aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel')
-rw-r--r--package/kernel/acx-mac80211/Makefile258
-rw-r--r--package/kernel/acx-mac80211/patches/001-make-compatible-with-recent-mac80211.patch30
-rw-r--r--package/kernel/acx-mac80211/patches/002-remove-usage-of__dev.patch85
-rw-r--r--package/kernel/acx-mac80211/patches/003-add-changes-for-3-10.patch27
-rw-r--r--package/kernel/acx-mac80211/patches/100-hw-queue-check-fix.patch42
-rw-r--r--package/kernel/acx-mac80211/patches/200-initial-macaddr.patch31
-rw-r--r--package/kernel/ar7-atm/Config.in22
-rw-r--r--package/kernel/ar7-atm/Makefile100
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/100-compile_fix.patch768
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/110-interrupt_fix.patch37
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/120-no_dumb_inline.patch11
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/130-powercutback.patch44
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/140-debug_mode.patch16
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/150-tasklet_mode.patch11
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/160-module-params.patch589
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/170-bus_id_removal.patch30
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/180-git_headers_include.patch54
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/190-2.6.32_proc_fixes.patch79
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/200-2.6.37_args.patch36
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/210-3.3-remove-smp_lock.h.patch33
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/100-compile_fix.patch808
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/110-interrupt_fix.patch37
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/120-no_dumb_inline.patch11
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/130-powercutback.patch44
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/140-debug_mode.patch16
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/150-tasklet_mode.patch11
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/160-module-params.patch675
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/170-bus_id_removal.patch30
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/180-git_headers_include.patch54
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/190-2.6.32_proc_fixes.patch79
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/200-2.6.37_args.patch36
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/210-3.3-remove-smp_lock.h.patch33
-rw-r--r--package/kernel/avila-wdt/Makefile40
-rw-r--r--package/kernel/avila-wdt/src/Makefile1
-rw-r--r--package/kernel/avila-wdt/src/avila-wdt.c231
-rw-r--r--package/kernel/brcm2708-gpu-fw/Makefile44
-rw-r--r--package/kernel/broadcom-diag/Makefile37
-rw-r--r--package/kernel/broadcom-diag/src/Makefile17
-rw-r--r--package/kernel/broadcom-diag/src/diag.c1807
-rw-r--r--package/kernel/broadcom-diag/src/diag.h135
-rw-r--r--package/kernel/broadcom-diag/src/gpio.h22
-rw-r--r--package/kernel/broadcom-wl/Makefile175
-rw-r--r--package/kernel/broadcom-wl/files/etc/hotplug.d/net/20-broadcom_wds61
-rwxr-xr-xpackage/kernel/broadcom-wl/files/etc/init.d/wlunbind29
-rw-r--r--package/kernel/broadcom-wl/files/lib/wifi/broadcom.sh395
-rw-r--r--package/kernel/broadcom-wl/patches/003-compat-2.6.35.patch39
-rw-r--r--package/kernel/broadcom-wl/patches/004-remove-pcmcia.patch22
-rw-r--r--package/kernel/broadcom-wl/patches/005-fix-mem-leak-on-unload.patch31
-rw-r--r--package/kernel/broadcom-wl/patches/006-generic-dma-api.patch88
-rw-r--r--package/kernel/broadcom-wl/patches/007-use-glue-driver.patch184
-rw-r--r--package/kernel/broadcom-wl/patches/008-fix_virtual_interfaces.patch11
-rw-r--r--package/kernel/broadcom-wl/patches/009-fix_compile_3_2.patch27
-rw-r--r--package/kernel/broadcom-wl/patches/010-remove_irqf_samble_random.patch11
-rw-r--r--package/kernel/broadcom-wl/patches/011-fix_compile_3_4.patch12
-rw-r--r--package/kernel/broadcom-wl/patches/100-fix_nvram_two_devices.patch32
-rw-r--r--package/kernel/broadcom-wl/patches/110-add_number_to_dev_name.patch11
-rw-r--r--package/kernel/broadcom-wl/patches/910-fallback-sprom.patch84
-rw-r--r--package/kernel/broadcom-wl/patches/912-pci-bus-nvram-hack.patch11
-rw-r--r--package/kernel/broadcom-wl/patches/913-avoid-dbe-on-ifs_ctl-readw-hack.patch12
-rw-r--r--package/kernel/broadcom-wl/src/glue/Makefile17
-rw-r--r--package/kernel/broadcom-wl/src/glue/wl_glue.c315
-rw-r--r--package/kernel/broadcom-wl/src/glue/wl_glue.h22
-rw-r--r--package/kernel/broadcom-wl/src/wlc.c1086
-rw-r--r--package/kernel/button-hotplug/Makefile53
-rw-r--r--package/kernel/button-hotplug/src/Kconfig2
-rw-r--r--package/kernel/button-hotplug/src/Makefile1
-rw-r--r--package/kernel/button-hotplug/src/button-hotplug.c349
-rw-r--r--package/kernel/ep80579-drivers/Makefile92
-rw-r--r--package/kernel/ep80579-drivers/patches/001-igbe_update.patch11755
-rw-r--r--package/kernel/ep80579-drivers/patches/002-cflags_cleanup.patch22
-rw-r--r--package/kernel/ep80579-drivers/patches/003-new_irqf_constants.patch53
-rw-r--r--package/kernel/ep80579-drivers/patches/100-iegbe_netdev_ops.patch56
-rw-r--r--package/kernel/ep80579-drivers/patches/101-iegbe_fix_napi_interface.patch41
-rw-r--r--package/kernel/ep80579-drivers/patches/102-iegbe_nuke_polling_netdev.patch103
-rw-r--r--package/kernel/ep80579-drivers/patches/103-iegbe_convert_unicast_addr_list.patch60
-rw-r--r--package/kernel/ep80579-drivers/patches/104-iegbe_group_address_list_and_its_count.patch20
-rw-r--r--package/kernel/ep80579-drivers/patches/105-iegbe_new_dma_masks.patch20
-rw-r--r--package/kernel/ep80579-drivers/patches/106-iegbe_new_irqf_constant.patch12
-rw-r--r--package/kernel/ep80579-drivers/patches/150-ocracoke_island.patch747
-rw-r--r--package/kernel/ep80579-drivers/patches/200-can_fix_ioctl_numbers.patch11
-rw-r--r--package/kernel/ep80579-drivers/patches/210-can_include_linux_fs_h.patch11
-rw-r--r--package/kernel/ep80579-drivers/patches/220-can_fix_irq_request.patch23
-rw-r--r--package/kernel/ep80579-drivers/patches/230-can_remove_driver_data_direct_access.patch40
-rw-r--r--package/kernel/ep80579-drivers/patches/300-wdt_compile_fix.patch59
-rw-r--r--package/kernel/ep80579-drivers/patches/400-edma_fix_irq_request_warning.patch22
-rw-r--r--package/kernel/ep80579-drivers/patches/500-1588_fix_irq_request_warning.patch22
-rw-r--r--package/kernel/ep80579-drivers/patches/600-2.6.27_includes.patch22
-rw-r--r--package/kernel/ep80579-drivers/patches/601-2.6.32_includes.patch30
-rw-r--r--package/kernel/ep80579-drivers/patches/700-iegbe_kcompat_2.6.30.patch31
-rw-r--r--package/kernel/ep80579-drivers/patches/701-iegbe_poll_dev.patch11
-rw-r--r--package/kernel/ep80579-drivers/patches/710-3.3-fix-generated-header-locations.patch91
-rw-r--r--package/kernel/ep80579-drivers/patches/711-3.3-gbe-fixes.patch392
-rw-r--r--package/kernel/ep80579-drivers/patches/712-3.3-can-fixes.patch41
-rw-r--r--package/kernel/ep80579-drivers/patches/713-3.3-gpio-fixes.patch33
-rw-r--r--package/kernel/ep80579-drivers/patches/714-3.3-wdt-fixes.patch31
-rw-r--r--package/kernel/ep80579-drivers/patches/715-3.3-1588-fixes.patch33
-rw-r--r--package/kernel/gpio-button-hotplug/Makefile44
-rw-r--r--package/kernel/gpio-button-hotplug/src/Makefile1
-rw-r--r--package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c564
-rw-r--r--package/kernel/hostap-driver/Makefile117
-rwxr-xr-xpackage/kernel/hostap-driver/files/lib/wifi/hostap.sh270
-rw-r--r--package/kernel/hostap-driver/patches/001-fix-txpower.patch175
-rw-r--r--package/kernel/i2c-gpio-custom/Makefile53
-rw-r--r--package/kernel/i2c-gpio-custom/src/Kconfig10
-rw-r--r--package/kernel/i2c-gpio-custom/src/Makefile1
-rw-r--r--package/kernel/i2c-gpio-custom/src/i2c-gpio-custom.c198
-rw-r--r--package/kernel/lantiq/ltq-adsl-app/Config.in9
-rw-r--r--package/kernel/lantiq/ltq-adsl-app/Makefile98
-rw-r--r--package/kernel/lantiq/ltq-adsl-app/files/dsl_control311
-rw-r--r--package/kernel/lantiq/ltq-adsl-app/files/dsl_notify.sh44
-rw-r--r--package/kernel/lantiq/ltq-adsl-fw/Makefile55
-rw-r--r--package/kernel/lantiq/ltq-adsl-mei/Makefile49
-rw-r--r--package/kernel/lantiq/ltq-adsl-mei/src/Makefile17
-rw-r--r--package/kernel/lantiq/ltq-adsl-mei/src/ifxmips_mei_interface.h702
-rw-r--r--package/kernel/lantiq/ltq-adsl-mei/src/lantiq_mei.c2805
-rw-r--r--package/kernel/lantiq/ltq-adsl/Config.in5
-rw-r--r--package/kernel/lantiq/ltq-adsl/Makefile96
-rw-r--r--package/kernel/lantiq/ltq-adsl/patches/100-dsl_compat.patch1065
-rw-r--r--package/kernel/lantiq/ltq-adsl/patches/110-fix_status_polling_loop.patch11
-rw-r--r--package/kernel/lantiq/ltq-adsl/patches/120-platform.patch72
-rw-r--r--package/kernel/lantiq/ltq-adsl/patches/130-linux3.8.patch143
-rw-r--r--package/kernel/lantiq/ltq-atm/Makefile51
-rw-r--r--package/kernel/lantiq/ltq-atm/src/Makefile23
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_amazon_se.c341
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ar9.c244
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_core.h245
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_danube.c231
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_amazon_se.h457
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_ar9.h439
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_ar9_retx.h611
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_danube.h442
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_danube_retx.h612
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_amazon_se.h57
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_ar9.h172
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_common.h549
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_danube.h51
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_vr9.h72
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_vr9.h427
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_amazon_se.h121
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_ar9.h188
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_common.h368
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_danube.h129
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_vr9.h192
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ifxmips_atm_vr9.c190
-rw-r--r--package/kernel/lantiq/ltq-atm/src/ltq_atm.c1913
-rw-r--r--package/kernel/lantiq/ltq-deu/Makefile49
-rw-r--r--package/kernel/lantiq/ltq-deu/src/Makefile26
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_aes.c904
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_arc4.c389
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_async_aes.c1137
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_async_des.c954
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_des.c768
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_deu.c210
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_deu.h232
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_deu_ar9.c135
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_deu_ar9.h299
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_deu_danube.c168
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_deu_danube.h250
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_deu_dma.c42
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_deu_dma.h69
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_deu_vr9.c144
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_deu_vr9.h324
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_md5.c310
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_md5_hmac.c386
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_sha1.c301
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_sha1_hmac.c378
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_tcrypt.h92
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ifxmips_testmgr.h9598
-rw-r--r--package/kernel/lantiq/ltq-deu/src/internal.h141
-rw-r--r--package/kernel/lantiq/ltq-deu/src/ltq_deu_testmgr.c3957
-rw-r--r--package/kernel/lantiq/ltq-hcd/Makefile53
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/Kconfig104
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/Makefile74
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxhcd.c2141
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxhcd.h758
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxhcd_es.c599
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxhcd_intr.c4844
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxhcd_queue.c485
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxusb_cif.c1686
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxusb_cif.h767
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxusb_cif_d.c535
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxusb_cif_h.c1599
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxusb_ctl.c3825
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxusb_driver.c1286
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxusb_host.kobin0 -> 181257 bytes
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxusb_plat.h1184
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxusb_regs.h1471
-rw-r--r--package/kernel/lantiq/ltq-hcd/src/ifxusb_version.h5
-rw-r--r--package/kernel/lantiq/ltq-ifxos/Makefile51
-rw-r--r--package/kernel/lantiq/ltq-ifxos/patches/100-compat.patch96
-rw-r--r--package/kernel/lantiq/ltq-ptm/Makefile52
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/Makefile23
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.c1551
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.h137
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_amazon_se.c322
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ar9.c376
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_common.h102
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_danube.c317
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_amazon_se.h493
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_ar9.h473
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_danube.h489
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_adsl.h284
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_amazon_se.h48
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_ar9.h48
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_danube.h48
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_vdsl.h278
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_vr9.h90
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_vr9.h380
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_amazon_se.h186
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_ar9.h213
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_common.h311
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_danube.h135
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_vr9.h205
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_test.c943
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.c1080
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.h126
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vr9.c295
-rw-r--r--package/kernel/lantiq/ltq-tapi/Config.in88
-rw-r--r--package/kernel/lantiq/ltq-tapi/Makefile70
-rw-r--r--package/kernel/lantiq/ltq-tapi/patches/000-portability.patch82
-rw-r--r--package/kernel/lantiq/ltq-tapi/patches/100-ifxmips.patch96
-rw-r--r--package/kernel/lantiq/ltq-tapi/patches/200-linux-37.patch108
-rw-r--r--package/kernel/lantiq/ltq-vdsl-app/Makefile75
-rw-r--r--package/kernel/lantiq/ltq-vdsl-app/files/dsl_control311
-rw-r--r--package/kernel/lantiq/ltq-vdsl-app/files/dsl_notify.sh44
-rw-r--r--package/kernel/lantiq/ltq-vdsl-app/patches/100-compat.patch26
-rw-r--r--package/kernel/lantiq/ltq-vdsl-fw/Makefile40
-rw-r--r--package/kernel/lantiq/ltq-vdsl-fw/src/LzmaDecode.c584
-rw-r--r--package/kernel/lantiq/ltq-vdsl-fw/src/LzmaDecode.h113
-rw-r--r--package/kernel/lantiq/ltq-vdsl-fw/src/LzmaTypes.h45
-rw-r--r--package/kernel/lantiq/ltq-vdsl-fw/src/LzmaWrapper.c206
-rw-r--r--package/kernel/lantiq/ltq-vdsl-fw/src/LzmaWrapper.h36
-rw-r--r--package/kernel/lantiq/ltq-vdsl-fw/src/Makefile13
-rwxr-xr-xpackage/kernel/lantiq/ltq-vdsl-fw/src/vdsl_fw_install.sh48
-rw-r--r--package/kernel/lantiq/ltq-vdsl-fw/src/w921v_fw_cutter.c164
-rw-r--r--package/kernel/lantiq/ltq-vdsl-mei/Makefile60
-rw-r--r--package/kernel/lantiq/ltq-vdsl-mei/patches/100-compat.patch298
-rw-r--r--package/kernel/lantiq/ltq-vdsl/Makefile69
-rw-r--r--package/kernel/lantiq/ltq-vdsl/patches/100-compat.patch148
-rw-r--r--package/kernel/lantiq/ltq-vmmc/Config.in95
-rw-r--r--package/kernel/lantiq/ltq-vmmc/Makefile166
-rw-r--r--package/kernel/lantiq/ltq-vmmc/files/vmmc.init19
-rw-r--r--package/kernel/lantiq/ltq-vmmc/patches/000-portability.patch287
-rw-r--r--package/kernel/lantiq/ltq-vmmc/patches/100-target.patch751
-rw-r--r--package/kernel/lantiq/ltq-vmmc/patches/400-falcon.patch968
-rw-r--r--package/kernel/linux/Makefile (renamed from package/kernel/Makefile)0
-rw-r--r--package/kernel/linux/modules/001-depends.mk (renamed from package/kernel/modules/001-depends.mk)0
-rw-r--r--package/kernel/linux/modules/block.mk (renamed from package/kernel/modules/block.mk)0
-rw-r--r--package/kernel/linux/modules/crypto.mk (renamed from package/kernel/modules/crypto.mk)0
-rw-r--r--package/kernel/linux/modules/firewire.mk (renamed from package/kernel/modules/firewire.mk)0
-rw-r--r--package/kernel/linux/modules/fs.mk (renamed from package/kernel/modules/fs.mk)0
-rw-r--r--package/kernel/linux/modules/hwmon.mk (renamed from package/kernel/modules/hwmon.mk)0
-rw-r--r--package/kernel/linux/modules/i2c.mk (renamed from package/kernel/modules/i2c.mk)0
-rw-r--r--package/kernel/linux/modules/input.mk (renamed from package/kernel/modules/input.mk)0
-rw-r--r--package/kernel/linux/modules/leds.mk (renamed from package/kernel/modules/leds.mk)0
-rw-r--r--package/kernel/linux/modules/lib.mk (renamed from package/kernel/modules/lib.mk)0
-rw-r--r--package/kernel/linux/modules/netdevices.mk (renamed from package/kernel/modules/netdevices.mk)0
-rw-r--r--package/kernel/linux/modules/netfilter.mk (renamed from package/kernel/modules/netfilter.mk)0
-rw-r--r--package/kernel/linux/modules/netsupport.mk (renamed from package/kernel/modules/netsupport.mk)0
-rw-r--r--package/kernel/linux/modules/nls.mk (renamed from package/kernel/modules/nls.mk)0
-rw-r--r--package/kernel/linux/modules/other.mk (renamed from package/kernel/modules/other.mk)0
-rw-r--r--package/kernel/linux/modules/pcmcia.mk (renamed from package/kernel/modules/pcmcia.mk)0
-rw-r--r--package/kernel/linux/modules/sound.mk (renamed from package/kernel/modules/sound.mk)0
-rw-r--r--package/kernel/linux/modules/spi.mk (renamed from package/kernel/modules/spi.mk)0
-rw-r--r--package/kernel/linux/modules/usb.mk (renamed from package/kernel/modules/usb.mk)0
-rw-r--r--package/kernel/linux/modules/video.mk (renamed from package/kernel/modules/video.mk)0
-rw-r--r--package/kernel/linux/modules/virtual.mk (renamed from package/kernel/modules/virtual.mk)0
-rw-r--r--package/kernel/linux/modules/w1.mk (renamed from package/kernel/modules/w1.mk)0
-rw-r--r--package/kernel/linux/modules/wireless.mk (renamed from package/kernel/modules/wireless.mk)0
-rw-r--r--package/kernel/mac80211/Makefile1630
-rw-r--r--package/kernel/mac80211/files/lib/wifi/mac80211.sh641
-rw-r--r--package/kernel/mac80211/files/regdb.txt697
-rw-r--r--package/kernel/mac80211/patches/000-fix_kconfig.patch16
-rw-r--r--package/kernel/mac80211/patches/001-fix_build.patch156
-rw-r--r--package/kernel/mac80211/patches/002-change_allconfig.patch44
-rw-r--r--package/kernel/mac80211/patches/010-disable_rfkill.patch13
-rw-r--r--package/kernel/mac80211/patches/020-disable_tty_set_termios.patch16
-rw-r--r--package/kernel/mac80211/patches/030-rt2x00_options.patch36
-rw-r--r--package/kernel/mac80211/patches/040-brcmutil_option.patch9
-rw-r--r--package/kernel/mac80211/patches/050-lib80211_option.patch30
-rw-r--r--package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch129
-rw-r--r--package/kernel/mac80211/patches/150-disable_addr_notifier.patch67
-rw-r--r--package/kernel/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch38
-rw-r--r--package/kernel/mac80211/patches/300-pending_work.patch313
-rw-r--r--package/kernel/mac80211/patches/310-ap_scan.patch11
-rw-r--r--package/kernel/mac80211/patches/400-ath_move_debug_code.patch28
-rw-r--r--package/kernel/mac80211/patches/401-ath9k_blink_default.patch11
-rw-r--r--package/kernel/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch29
-rw-r--r--package/kernel/mac80211/patches/403-ath_regd_optional.patch58
-rw-r--r--package/kernel/mac80211/patches/404-world_regd_fixup.patch84
-rw-r--r--package/kernel/mac80211/patches/405-regd_no_assoc_hints.patch19
-rw-r--r--package/kernel/mac80211/patches/406-ath_regd_us.patch26
-rw-r--r--package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch10
-rw-r--r--package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch46
-rw-r--r--package/kernel/mac80211/patches/420-ath5k_disable_fast_cc.patch18
-rw-r--r--package/kernel/mac80211/patches/430-add_ath5k_platform.patch33
-rw-r--r--package/kernel/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch56
-rw-r--r--package/kernel/mac80211/patches/432-ath5k_add_pciids.patch11
-rw-r--r--package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch113
-rw-r--r--package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch65
-rw-r--r--package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch102
-rw-r--r--package/kernel/mac80211/patches/502-ath9k_ahb_init.patch32
-rw-r--r--package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch13
-rw-r--r--package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch11
-rw-r--r--package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch128
-rw-r--r--package/kernel/mac80211/patches/520-mac80211_cur_txpower.patch33
-rw-r--r--package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch19
-rw-r--r--package/kernel/mac80211/patches/522-ath9k_per_chain_signal_strength.patch153
-rw-r--r--package/kernel/mac80211/patches/523-mac80211_configure_antenna_gain.patch162
-rw-r--r--package/kernel/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch34
-rw-r--r--package/kernel/mac80211/patches/530-ath9k_extra_leds.patch248
-rw-r--r--package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch71
-rw-r--r--package/kernel/mac80211/patches/541-ath9k_optimize_interrupt_mitigation.patch30
-rw-r--r--package/kernel/mac80211/patches/550-ath9k_reduce_ani_interval.patch11
-rw-r--r--package/kernel/mac80211/patches/552-ath9k_rx_dma_stop_check.patch28
-rw-r--r--package/kernel/mac80211/patches/553-ath9k_debugfs_diag.patch139
-rw-r--r--package/kernel/mac80211/patches/554-ath9k_ani_mrc_fix.patch13
-rw-r--r--package/kernel/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch70
-rw-r--r--package/kernel/mac80211/patches/556-ath9k_ani_revert.patch74
-rw-r--r--package/kernel/mac80211/patches/601-rt2x00-set_pci_mwi.patch13
-rw-r--r--package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch32
-rw-r--r--package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch289
-rw-r--r--package/kernel/mac80211/patches/605-rt2x00-pci-eeprom.patch46
-rw-r--r--package/kernel/mac80211/patches/606-rt2x00_no_realign.patch67
-rw-r--r--package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch47
-rw-r--r--package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch63
-rw-r--r--package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch214
-rw-r--r--package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch115
-rw-r--r--package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch34
-rw-r--r--package/kernel/mac80211/patches/614-rt2x00-of_load_eeprom_filename.patch28
-rw-r--r--package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch29
-rw-r--r--package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch285
-rw-r--r--package/kernel/mac80211/patches/617-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch102
-rw-r--r--package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch10
-rw-r--r--package/kernel/mac80211/patches/800-b43-gpio-mask-module-option.patch37
-rw-r--r--package/kernel/mac80211/patches/810-b43_no_pio.patch86
-rw-r--r--package/kernel/mac80211/patches/820-b43-add-antenna-control.patch131
-rw-r--r--package/kernel/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch134
-rw-r--r--package/kernel/mac80211/patches/841-b43-reduce-number-of-RX-slots.patch11
-rw-r--r--package/kernel/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch17
-rw-r--r--package/kernel/mac80211/patches/851-brcmsmac-remove-extra-regulation-restriction.patch31
-rw-r--r--package/kernel/mmc_over_gpio/Makefile77
-rw-r--r--package/kernel/mmc_over_gpio/files/mmc_over_gpio.config8
-rw-r--r--package/kernel/mmc_over_gpio/files/mmc_over_gpio.init83
-rw-r--r--package/kernel/om-watchdog/Makefile45
-rw-r--r--package/kernel/om-watchdog/files/om-watchdog15
-rw-r--r--package/kernel/om-watchdog/files/om-watchdog.init30
-rw-r--r--package/kernel/rotary-gpio-custom/Makefile53
-rw-r--r--package/kernel/rotary-gpio-custom/src/Kconfig9
-rw-r--r--package/kernel/rotary-gpio-custom/src/Makefile1
-rw-r--r--package/kernel/rotary-gpio-custom/src/rotary-gpio-custom.c188
-rw-r--r--package/kernel/rtc-rv5c386a/Makefile38
-rw-r--r--package/kernel/rtc-rv5c386a/src/Makefile18
-rw-r--r--package/kernel/rtc-rv5c386a/src/rtc.c613
-rw-r--r--package/kernel/spi-ks8995/Makefile54
-rw-r--r--package/kernel/spi-ks8995/src/Kconfig3
-rw-r--r--package/kernel/spi-ks8995/src/Makefile1
-rw-r--r--package/kernel/spi-ks8995/src/spi_ks8995.c419
-rw-r--r--package/kernel/switch/Makefile59
-rw-r--r--package/kernel/switch/files/switch.sh53
-rw-r--r--package/kernel/switch/src/Makefile18
-rw-r--r--package/kernel/switch/src/etc53xx.h624
-rw-r--r--package/kernel/switch/src/gpio.h25
-rw-r--r--package/kernel/switch/src/switch-adm.c596
-rw-r--r--package/kernel/switch/src/switch-core.c527
-rw-r--r--package/kernel/switch/src/switch-core.h55
-rw-r--r--package/kernel/switch/src/switch-robo.c892
-rw-r--r--package/kernel/trelay/Makefile50
-rw-r--r--package/kernel/trelay/files/trelay.config4
-rw-r--r--package/kernel/trelay/files/trelay.hotplug5
-rw-r--r--package/kernel/trelay/files/trelay.init32
-rw-r--r--package/kernel/trelay/src/Makefile1
-rw-r--r--package/kernel/trelay/src/trelay.c272
-rw-r--r--package/kernel/w1-gpio-custom/Makefile54
-rw-r--r--package/kernel/w1-gpio-custom/src/Kconfig4
-rw-r--r--package/kernel/w1-gpio-custom/src/Makefile1
-rw-r--r--package/kernel/w1-gpio-custom/src/w1-gpio-custom.c185
-rw-r--r--package/kernel/wrt55agv2-spidevs/Makefile53
-rw-r--r--package/kernel/wrt55agv2-spidevs/src/Kconfig3
-rw-r--r--package/kernel/wrt55agv2-spidevs/src/Makefile1
-rw-r--r--package/kernel/wrt55agv2-spidevs/src/wrt55agv2_spidevs.c114
381 files changed, 108244 insertions, 0 deletions
diff --git a/package/kernel/acx-mac80211/Makefile b/package/kernel/acx-mac80211/Makefile
new file mode 100644
index 0000000000..3e4984d59d
--- /dev/null
+++ b/package/kernel/acx-mac80211/Makefile
@@ -0,0 +1,258 @@
+#
+# Copyright (C) 2007-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=acx-mac80211
+PKG_REV:=v2012-09-23-WIP
+PKG_VERSION:=20121004
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=git://acx100.git.sourceforge.net/gitroot/acx100/acx-mac80211
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=$(PKG_REV)
+PKG_MIRROR_MD5SUM:=8d6bc84239059fd938ff4d989579f622
+PKG_BUILD_DEPENDS:=mac80211
+
+PKG_CONFIG_DEPENDS:= \
+ CONFIG_PACKAGE_MAC80211_DEBUGFS \
+ CONFIG_PACKAGE_MAC80211_MESH \
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/acx-mac80211
+ SUBMENU:=Wireless Drivers
+ TITLE:=ACX1xx mac80211 driver
+ DEPENDS:=@(PCI_SUPPORT||TARGET_ar7) @mipsel +kmod-mac80211
+ FILES:=$(PKG_BUILD_DIR)/acx-mac80211.ko
+ AUTOLOAD:=$(call AutoLoad,50,acx-mac80211)
+ MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+ MENU:=1
+endef
+
+define KernelPackage/acx-mac80211/config
+ menu "Configuration"
+ depends on PACKAGE_kmod-acx-mac80211
+
+ config ACX_ID_0D
+ bool "ACX1xx Radio ID 0D firmware"
+ help
+ Download and install firmware for:
+ ACX1xx cards with Radio ID 0D into /lib/firmware.
+
+ config ACX_ID_11
+ bool "ACX1xx Radio ID 11 firmware"
+ help
+ Download and install firmware for:
+ ACX1xx cards with Radio ID 11 into /lib/firmware.
+
+ config ACX_ID_15
+ bool "ACX1xx Radio ID 15 firmware"
+ help
+ Download and install firmware for:
+ ACX1xx cards with Radio ID 15 into /lib/firmware.
+
+ config ACX_ID_16
+ bool "ACX1xx Radio ID 16 firmware"
+ default y
+ help
+ Download and install firmware for:
+ ACX1xx cards with Radio ID 16 into /lib/firmware.
+
+ choice
+ prompt "ACX111 firmware version"
+ depends on ACX_ID_16
+ default ACX_DEFAULT if !TARGET_adm5120
+ default ACX_1_2_1_34 if TARGET_adm5120
+ help
+ This option allows you to select the version of the acx firmware.
+
+ config ACX_DEFAULT
+ bool "Default"
+ help
+ Default firmware for ACX111 devices.
+
+ If unsure, select this.
+
+ config ACX_1_2_1_34
+ bool "1.2.1_34"
+ help
+ 1.2.1_34 firmware for ACX111 devices. Works with Zyxel P-334WT.
+
+ If unsure, select the "default" firmware.
+
+ endchoice
+
+ config ACX_ID_17
+ bool "ACX1xx Radio ID 17 firmware"
+ help
+ Download and install firmware for:
+ ACX1xx cards with Radio ID 17 into /lib/firmware.
+
+ config ACX_ID_19
+ bool "ACX1xx Radio ID 19 firmware"
+ default y
+ help
+ Download and install firmware for:
+ ACX1xx cards with Radio ID 19 into /lib/firmware.
+
+ config ACX_ID_1B
+ bool "ACX1xx Radio ID 1B firmware"
+ help
+ Download and install firmware for:
+ ACX1xx cards with Radio ID 1b into /lib/firmware.
+
+ endmenu
+endef
+
+define KernelPackage/acx-mac80211/description
+ Driver for acx111 cards (mac80211 version)
+endef
+
+define Download/tiacx100
+ FILE:=tiacx100
+ URL:=http://acx100.erley.org/fw/acx100_1.9.8.b/
+ MD5SUM:=24a54fd30f7658fcbffc825b0dd7aa5b
+endef
+
+define Download/tiacx100r0d
+ FILE:=tiacx100r0D
+ URL:=http://acx100.erley.org/fw/acx100_1.9.8.b/
+ MD5SUM:=1c7413e7b0be4ef7d1e424a132e17fab
+endef
+
+define Download/tiacx100r11
+ FILE:=tiacx100r11
+ URL:=http://acx100.erley.org/fw/acx100_1.9.8.b/
+ MD5SUM:=a150750ad33c512edc4afee5270b37cb
+endef
+
+define Download/tiacx100r15
+ FILE:=tiacx100r15
+ URL:=http://acx100.erley.org/fw/acx100_1.9.8.b/
+ MD5SUM:=c99d01d4fcf0d6cc00441aff60690be4
+endef
+
+define Download/tiacx111c16
+ FILE:=tiacx111c16
+ URL:=http://acx100.erley.org/fw/acx111_2.3.1.31/
+ MD5SUM:=7026826460376f6b174f9225bd7781b9
+endef
+
+define Download/tiacx111c16_1
+ FILE:=tiacx111c16_1.2.1_34
+ URL:=http://sites.google.com/site/atorkhov/files/
+ MD5SUM:=fcd07de4b25e1d2aaf3b78b27c5b7ee9
+endef
+
+define Download/tiacx111c17
+ FILE:=tiacx111c17
+ URL:=http://acx100.erley.org/fw/acx111_2.3.1.31/
+ MD5SUM:=95552544ca6d2b4e8c6aeb80b8ae7fdf
+endef
+
+define Download/tiacx111c19
+ FILE:=tiacx111c19
+ URL:=http://acx100.erley.org/fw/acx111_2.3.1.31/
+ MD5SUM:=a1fa9681e297b4e36e257090fc12265a
+endef
+
+define Download/tiacx111usbc1b
+ FILE:=tiacx111usbc1B
+ URL:=http://acx100.erley.org/fw/acx111_2.4.0.70-USB/
+ MD5SUM:=c4edecd912b2417779d0b65e3a7dc86d
+endef
+
+PKG_EXTRA_KCONFIG:= \
+ CONFIG_ACX_MAC80211=m \
+ CONFIG_ACX_MAC80211_PCI=m \
+
+PKG_EXTRA_CFLAGS:= \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(PKG_EXTRA_KCONFIG)))) \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(PKG_EXTRA_KCONFIG)))) \
+ $(if $(CONFIG_LEDS_TRIGGERS), -DCONFIG_MAC80211_LEDS -DCONFIG_LEDS_TRIGGERS) \
+ $(if $(CONFIG_PACKAGE_MAC80211_DEBUGFS), -DCONFIG_CFG80211_DEBUGFS -DCONFIG_MAC80211_DEBUGFS) \
+ $(if $(CONFIG_PACKAGE_MAC80211_MESH), -DCONFIG_MAC80211_MESH) \
+ -DBACKPORTED_KERNEL_NAME=\\\"$(PKG_SOURCE)\\\" \
+ -DBACKPORTED_KERNEL_VERSION=\\\"$(PKG_SOURCE_VERSION)\\\" \
+ -DBACKPORTS_VERSION=\\\"unknown\\\" \
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ $(PKG_EXTRA_KCONFIG) \
+ EXTRA_CFLAGS="$(PKG_EXTRA_CFLAGS) -DCONFIG_ACX_MAC80211_VERSION=\"KERNEL_VERSION(3,10,0)\"" \
+ LINUXINCLUDE="-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi -I$(STAGING_DIR)/usr/include/mac80211-backport \
+ -I$(STAGING_DIR)/usr/include/mac80211/uapi -I$(STAGING_DIR)/usr/include/mac80211 \
+ -I$(LINUX_DIR)/include -I$(LINUX_DIR)/include/$(LINUX_UAPI_DIR) \
+ -I$(LINUX_DIR)/include/generated/uapi/ -Iarch/$(LINUX_KARCH)/include \
+ -Iarch/$(LINUX_KARCH)/include/$(LINUX_UAPI_DIR) \
+ -include generated/autoconf.h \
+ -include backport/backport.h " \
+ V="$(V)" \
+ modules
+endef
+
+define Build/Configure
+endef
+
+define KernelPackage/acx-mac80211/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+
+ifneq ($(CONFIG_ACX_ID_0D)$(CONFIG_ACX_ID_11)$(CONFIG_ACX_ID_15),)
+ $(INSTALL_DATA) $(DL_DIR)/tiacx100 $(1)/lib/firmware/
+endif
+
+ifneq ($(CONFIG_ACX_ID_0D),)
+ $(INSTALL_DATA) $(DL_DIR)/tiacx100r0D $(1)/lib/firmware/
+endif
+
+ifneq ($(CONFIG_ACX_ID_11),)
+ $(INSTALL_DATA) $(DL_DIR)/tiacx100r11 $(1)/lib/firmware/
+endif
+
+ifneq ($(CONFIG_ACX_ID_15),)
+ $(INSTALL_DATA) $(DL_DIR)/tiacx100r15 $(1)/lib/firmware/
+endif
+
+ifneq ($(CONFIG_ACX_DEFAULT),)
+ $(INSTALL_DATA) $(DL_DIR)/tiacx111c16 $(1)/lib/firmware/
+endif
+
+ifneq ($(CONFIG_ACX_1_2_1_34),)
+ $(INSTALL_DATA) $(DL_DIR)/tiacx111c16_1.2.1_34 $(1)/lib/firmware/tiacx111c16
+endif
+
+ifneq ($(CONFIG_ACX_ID_17),)
+ $(INSTALL_DATA) $(DL_DIR)/tiacx111c17 $(1)/lib/firmware/
+endif
+
+ifneq ($(CONFIG_ACX_ID_19),)
+ $(INSTALL_DATA) $(DL_DIR)/tiacx111c19 $(1)/lib/firmware/
+endif
+
+ifneq ($(CONFIG_ACX_ID_1B),)
+ $(INSTALL_DATA) $(DL_DIR)/tiacx111usbc1B $(1)/lib/firmware/
+endif
+
+endef
+
+$(eval $(call KernelPackage,acx-mac80211))
+$(eval $(call Download,tiacx100))
+$(eval $(call Download,tiacx100r0d))
+$(eval $(call Download,tiacx100r11))
+$(eval $(call Download,tiacx100r15))
+$(eval $(call Download,tiacx111c16))
+$(eval $(call Download,tiacx111c16_1))
+$(eval $(call Download,tiacx111c17))
+$(eval $(call Download,tiacx111c19))
+$(eval $(call Download,tiacx111usbc1b))
diff --git a/package/kernel/acx-mac80211/patches/001-make-compatible-with-recent-mac80211.patch b/package/kernel/acx-mac80211/patches/001-make-compatible-with-recent-mac80211.patch
new file mode 100644
index 0000000000..707ba8bb4b
--- /dev/null
+++ b/package/kernel/acx-mac80211/patches/001-make-compatible-with-recent-mac80211.patch
@@ -0,0 +1,30 @@
+--- a/main.h
++++ b/main.h
+@@ -44,8 +44,11 @@ int acx_e_op_get_tx_stats(struct ieee802
+
+ #if CONFIG_ACX_MAC80211_VERSION < KERNEL_VERSION(2, 6, 39)
+ int acx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+-#else
++#elif CONFIG_ACX_MAC80211_VERSION < KERNEL_VERSION(3, 7, 0)
+ void acx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
++#else
++void acx_op_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
++ struct sk_buff *skb);
+ #endif
+
+
+--- a/main.c
++++ b/main.c
+@@ -1024,7 +1024,12 @@ int acx_e_op_get_tx_stats(struct ieee802
+ * acx_compat, and hiding this #if/else. OTOH, inclusion doesnt care
+ * about old kernels
+ */
++#if CONFIG_ACX_MAC80211_VERSION < KERNEL_VERSION(3, 7, 0)
+ OP_TX_RET_TYPE acx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
++#else
++void acx_op_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
++ struct sk_buff *skb)
++#endif
+ {
+ acx_device_t *adev = ieee2adev(hw);
+
diff --git a/package/kernel/acx-mac80211/patches/002-remove-usage-of__dev.patch b/package/kernel/acx-mac80211/patches/002-remove-usage-of__dev.patch
new file mode 100644
index 0000000000..f16d3b68b1
--- /dev/null
+++ b/package/kernel/acx-mac80211/patches/002-remove-usage-of__dev.patch
@@ -0,0 +1,85 @@
+--- a/mem.c
++++ b/mem.c
+@@ -2002,7 +2002,7 @@ int acx100mem_ioctl_set_phy_amp_bias(str
+ * configuration
+ * id - ptr to the device id entry that matched this device
+ */
+-static int __devinit acxmem_probe(struct platform_device *pdev)
++static int acxmem_probe(struct platform_device *pdev)
+ {
+ acx_device_t *adev = NULL;
+ const char *chip_name;
+@@ -2268,7 +2268,7 @@ done:
+ * pdev - ptr to PCI device structure containing info about pci
+ * configuration
+ */
+-static int __devexit acxmem_remove(struct platform_device *pdev)
++static int acxmem_remove(struct platform_device *pdev)
+ {
+ struct ieee80211_hw *hw = (struct ieee80211_hw *)
+ platform_get_drvdata(pdev);
+@@ -2470,7 +2470,7 @@ static struct platform_driver acxmem_dri
+ .name = "acx-mem",
+ },
+ .probe = acxmem_probe,
+- .remove = __devexit_p(acxmem_remove),
++ .remove = acxmem_remove,
+
+ #ifdef CONFIG_PM
+ .suspend = acxmem_e_suspend,
+--- a/pci.c
++++ b/pci.c
+@@ -982,7 +982,7 @@ int acx100pci_ioctl_set_phy_amp_bias(str
+ * id - ptr to the device id entry that matched this device
+ */
+ #ifdef CONFIG_PCI
+-static int __devinit acxpci_probe(struct pci_dev *pdev,
++static int acxpci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+ {
+ acx111_ie_configoption_t co;
+@@ -1346,7 +1346,7 @@ done:
+ *
+ * pdev - ptr to PCI device structure containing info about pci configuration
+ */
+-static void __devexit acxpci_remove(struct pci_dev *pdev)
++static void acxpci_remove(struct pci_dev *pdev)
+ {
+ struct ieee80211_hw *hw
+ = (struct ieee80211_hw *) pci_get_drvdata(pdev);
+@@ -1537,7 +1537,7 @@ static int acxpci_e_resume(struct pci_de
+ */
+
+ #if 0 // use later ?
+-static struct acxpci_device_info acxpci_info_tbl[] __devinitdata = {
++static struct acxpci_device_info acxpci_info_tbl[] = {
+ [0] = {
+ .part_name = "acx111",
+ .helper_image = "tiacx1111r16", // probly wrong !!
+@@ -1564,7 +1564,7 @@ static struct pci_driver acxpci_driver =
+ .name = "acx_pci",
+ .id_table = acxpci_id_tbl,
+ .probe = acxpci_probe,
+- .remove = __devexit_p(acxpci_remove),
++ .remove = acxpci_remove,
+ #ifdef CONFIG_PM
+ .suspend = acxpci_e_suspend,
+ .resume = acxpci_e_resume
+@@ -1662,7 +1662,7 @@ static struct vlynq_device_id acx_vlynq_
+ };
+
+
+-static __devinit int vlynq_probe(struct vlynq_device *vdev,
++static int vlynq_probe(struct vlynq_device *vdev,
+ struct vlynq_device_id *id)
+ {
+ int result = -EIO, i;
+@@ -1971,7 +1971,7 @@ static struct vlynq_driver vlynq_acx = {
+ .name = "acx_vlynq",
+ .id_table = acx_vlynq_id,
+ .probe = vlynq_probe,
+- .remove = __devexit_p(vlynq_remove),
++ .remove = vlynq_remove,
+ };
+ #endif /* CONFIG_VLYNQ */
+
diff --git a/package/kernel/acx-mac80211/patches/003-add-changes-for-3-10.patch b/package/kernel/acx-mac80211/patches/003-add-changes-for-3-10.patch
new file mode 100644
index 0000000000..18d4f9e394
--- /dev/null
+++ b/package/kernel/acx-mac80211/patches/003-add-changes-for-3-10.patch
@@ -0,0 +1,27 @@
+--- a/main.c
++++ b/main.c
+@@ -681,6 +681,7 @@ int acx_op_config(struct ieee80211_hw *h
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ changed_not_done &= ~IEEE80211_CONF_CHANGE_CHANNEL;
+
++#if CONFIG_ACX_MAC80211_VERSION < KERNEL_VERSION(3, 10, 0)
+ logf1(L_DEBUG, "IEEE80211_CONF_CHANGE_CHANNEL, "
+ "channel->hw_value=%i\n", conf->channel->hw_value);
+
+@@ -689,6 +690,16 @@ int acx_op_config(struct ieee80211_hw *h
+
+ acx_selectchannel(adev, conf->channel->hw_value,
+ conf->channel->center_freq);
++#else
++ logf1(L_DEBUG, "IEEE80211_CONF_CHANGE_CHANNEL, "
++ "channel->hw_value=%i\n", conf->chandef.chan->hw_value);
++
++ if (conf->chandef.chan->hw_value == adev->channel)
++ goto change_channel_done;
++
++ acx_selectchannel(adev, conf->chandef.chan->hw_value,
++ conf->chandef.chan->center_freq);
++#endif
+ }
+ change_channel_done:
+ if (changed_not_done)
diff --git a/package/kernel/acx-mac80211/patches/100-hw-queue-check-fix.patch b/package/kernel/acx-mac80211/patches/100-hw-queue-check-fix.patch
new file mode 100644
index 0000000000..73366f3423
--- /dev/null
+++ b/package/kernel/acx-mac80211/patches/100-hw-queue-check-fix.patch
@@ -0,0 +1,42 @@
+--- a/mem.c
++++ b/mem.c
+@@ -2036,7 +2036,7 @@ static int acxmem_probe(struct platform_
+ */
+ ieee->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
+ | BIT(NL80211_IFTYPE_ADHOC);
+- ieee->queues = 1;
++ ieee->queues = 4;
+ /* OW TODO Check if RTS/CTS threshold can be included here */
+
+ /* TODO: although in the original driver the maximum value was
+--- a/pci.c
++++ b/pci.c
+@@ -1022,7 +1022,7 @@ static int acxpci_probe(struct pci_dev *
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_AP);
+- ieee->queues = 1;
++ ieee->queues = 4;
+ /* OW TODO Check if RTS/CTS threshold can be included here */
+
+ /* TODO: although in the original driver the maximum value was
+@@ -1691,7 +1691,7 @@ static int vlynq_probe(struct vlynq_devi
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_AP);
+- ieee->queues = 1;
++ ieee->queues = 4;
+
+ /* We base signal quality on winlevel approach of previous driver
+ * TODO OW 20100615 This should into a common init code
+--- a/usb.c
++++ b/usb.c
+@@ -1624,7 +1624,7 @@ acxusb_probe(struct usb_interface *intf,
+ */
+ ieee->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
+ | BIT(NL80211_IFTYPE_ADHOC);
+- ieee->queues = 1;
++ ieee->queues = 4;
+ // OW TODO Check if RTS/CTS threshold can be included here
+
+ // We base signal quality on winlevel approach of previous driver
diff --git a/package/kernel/acx-mac80211/patches/200-initial-macaddr.patch b/package/kernel/acx-mac80211/patches/200-initial-macaddr.patch
new file mode 100644
index 0000000000..cc82fecbb3
--- /dev/null
+++ b/package/kernel/acx-mac80211/patches/200-initial-macaddr.patch
@@ -0,0 +1,31 @@
+--- a/cardsetting.c
++++ b/cardsetting.c
+@@ -710,12 +710,27 @@ static int acx1xx_get_station_id(acx_dev
+ u8 stationID[4 + acx_ie_descs[ACX1xx_IE_DOT11_STATION_ID].len];
+ const u8 *paddr;
+ int i, res;
++ const char *prom_addr;
++ char *prom_getenv(const char *name);
+
+
+
+ res = acx_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
+ paddr = &stationID[4];
+- for (i = 0; i < ETH_ALEN; i++) {
++ prom_addr = NULL;
++#ifdef CONFIG_VLYNQ
++ prom_addr = prom_getenv("macwlan");
++ if (prom_addr == NULL)
++ prom_addr = prom_getenv("mac_ap");
++#endif
++ if (prom_addr)
++ sscanf(prom_addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", adev->dev_addr,
++ adev->dev_addr + 1,
++ adev->dev_addr + 2,
++ adev->dev_addr + 3,
++ adev->dev_addr + 4,
++ adev->dev_addr + 5);
++ else for (i = 0; i < ETH_ALEN; i++) {
+ /* we copy the MAC address (reversed in the card) to
+ * the netdevice's MAC address, and on ifup it will be
+ * copied into iwadev->dev_addr */
diff --git a/package/kernel/ar7-atm/Config.in b/package/kernel/ar7-atm/Config.in
new file mode 100644
index 0000000000..479b7ad072
--- /dev/null
+++ b/package/kernel/ar7-atm/Config.in
@@ -0,0 +1,22 @@
+menu "Configuration"
+ depends on (PACKAGE_kmod-sangam-atm-annex-a || PACKAGE_kmod-sangam-atm-annex-b)
+
+choice
+ prompt "Firmware version"
+ default AR7_ATM_FW_VERSION_704
+ help
+ This option allows you to switch between firmware/driver versions which
+ might improve the DSL line speed.
+
+config AR7_ATM_FW_VERSION_705
+ bool "D7.05.01.00"
+
+config AR7_ATM_FW_VERSION_704
+ bool "D7.04.03.00"
+
+config AR7_ATM_FW_VERSION_703
+ bool "D7.03.01.00"
+
+endchoice
+
+endmenu
diff --git a/package/kernel/ar7-atm/Makefile b/package/kernel/ar7-atm/Makefile
new file mode 100644
index 0000000000..59e9e79183
--- /dev/null
+++ b/package/kernel/ar7-atm/Makefile
@@ -0,0 +1,100 @@
+#
+# Copyright (C) 2006-2009 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=sangam_atm
+
+ifeq ($(CONFIG_AR7_ATM_FW_VERSION_705),y)
+PKG_VERSION:=D7.05.01.00
+PKG_MD5SUM:=42ee465be5cfbe9476fc25deb260d450
+PKG_RELEASE:=R1
+PATCH_DIR:=patches-$(PKG_VERSION)
+endif
+
+ifeq ($(CONFIG_AR7_ATM_FW_VERSION_704),y)
+PKG_VERSION:=D7.04.03.00
+PKG_MD5SUM:=3d76004e46f09e88931f91670cb420ad
+PKG_RELEASE:=R1
+PATCH_DIR:=patches-$(PKG_VERSION)
+endif
+
+ifeq ($(CONFIG_AR7_ATM_FW_VERSION_703),y)
+PKG_VERSION:=D7.03.01.00
+PKG_MD5SUM:=bc6e9c6adb1be25820c7ee661de8ca7d
+PKG_RELEASE:=R2
+PATCH_DIR:=patches-D7.04.03.00
+endif
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE).tar.bz2
+PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/sangam-atm/Default
+ SUBMENU:=Network Devices
+ DEPENDS:=@TARGET_ar7_generic +kmod-atm
+ TITLE:=AR7 ADSL driver
+ FILES:=$(PKG_BUILD_DIR)/tiatm.ko
+ AUTOLOAD:=$(call AutoLoad,50,tiatm)
+ MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+ MENU:=1
+endef
+
+define KernelPackage/sangam-atm/config
+ source "$(SOURCE)/Config.in"
+endef
+
+define KernelPackage/sangam-atm-annex-a
+$(call KernelPackage/sangam-atm/Default)
+ TITLE+= (Annex A, ADSL over POTS)
+endef
+
+define KernelPackage/sangam-atm-annex-a/description
+ The AR7 ADSL driver for Annex A (ADSL over POTS).
+endef
+
+define KernelPackage/sangam-atm-annex-a/config
+$(call KernelPackage/sangam-atm/config)
+endef
+
+define KernelPackage/sangam-atm-annex-b
+$(call KernelPackage/sangam-atm/Default)
+ TITLE+= (Annex B, ADSL over ISDN)
+endef
+
+define KernelPackage/sangam-atm-annex-b/description
+ The AR7 ADSL driver for Annex B (ADSL over ISDN).
+endef
+
+define KernelPackage/sangam-atm-annex-a/config
+$(call KernelPackage/sangam-atm/config)
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ ARCH="$(LINUX_KARCH)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ modules
+endef
+
+define KernelPackage/sangam-atm-annex-a/install
+ mkdir -p $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/ar0700mp.bin $(1)/lib/firmware/
+ ln -sf ar0700mp.bin $(1)/lib/firmware/ar0700xx.bin
+endef
+
+define KernelPackage/sangam-atm-annex-b/install
+ mkdir -p $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/ar0700db.bin $(1)/lib/firmware/
+ ln -sf ar0700db.bin $(1)/lib/firmware/ar0700xx.bin
+endef
+
+$(eval $(call KernelPackage,sangam-atm-annex-a))
+$(eval $(call KernelPackage,sangam-atm-annex-b))
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/100-compile_fix.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/100-compile_fix.patch
new file mode 100644
index 0000000000..df5fe53967
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/100-compile_fix.patch
@@ -0,0 +1,768 @@
+--- a/cppi_cpaal5.c
++++ b/cppi_cpaal5.c
+@@ -352,7 +352,7 @@ static int halRxReturn(HAL_RECEIVEINFO *
+ {
+ /* malloc failed, add this RCB to Needs Buffer List */
+ TempRcb->FragCount = 1; /*MJH+030417*/
+- (HAL_RCB *)TempRcb->Eop = TempRcb; /* GSG +030430 */
++ TempRcb->Eop = TempRcb; /* GSG +030430 */
+
+ if(HalDev->NeedsCount < MAX_NEEDS) /* +MJH 030410 */
+ { /* +MJH 030410 */
+--- a/dsl_hal_api.c
++++ b/dsl_hal_api.c
+@@ -254,15 +254,15 @@
+ * of phyEnableDisableWord & phyControlWord to avoid changing API struct
+ * which may cause change required to application data structure.
+ ******************************************************************************/
+-#include <dev_host_interface.h>
+-#include <dsl_hal_register.h>
+-#include <dsl_hal_support.h>
++#include "dev_host_interface.h"
++#include "dsl_hal_register.h"
++#include "dsl_hal_support.h"
+
+ #ifndef NO_ADV_STATS
+-#include <dsl_hal_logtable.h>
++#include "dsl_hal_logtable.h"
+ #endif
+
+-#include <dsl_hal_version.h>
++#include "dsl_hal_version.h"
+
+ // UR8_MERGE_START CQ11054 Jack Zhang
+ static unsigned int highprecision_selected = 0; //By default we use low precision for backward compt.
+--- a/dsl_hal_support.c
++++ b/dsl_hal_support.c
+@@ -140,9 +140,9 @@
+ * oamFeature are overriden
+ // UR8_MERGE_END CQ10774 Ram
+ *******************************************************************************/
+-#include <dev_host_interface.h>
+-#include <dsl_hal_register.h>
+-#include <dsl_hal_support.h>
++#include "dev_host_interface.h"
++#include "dsl_hal_register.h"
++#include "dsl_hal_support.h"
+
+ #define NUM_READ_RETRIES 3
+ static unsigned int dslhal_support_adsl2ByteSwap32(unsigned int in32Bits);
+--- a/dsl_hal_support.h
++++ b/dsl_hal_support.h
+@@ -49,7 +49,7 @@
+ * 04Nov05 0.11.00 CPH Fixed T1413 mode got Zero DS/US rate when DSL_BIT_TMODE is set.
+ *******************************************************************************/
+
+-#include <dsl_hal_api.h>
++#include "dsl_hal_api.h"
+
+ #define virtual2Physical(a) (((int)a)&~0xe0000000)
+ /* External Function Prototype Declarations */
+--- a/Makefile
++++ b/Makefile
+@@ -1,18 +1,9 @@
+-# File: drivers/atm/ti_evm3/Makefile
+ #
+-# Makefile for the Texas Instruments EVM3 ADSL/ATM driver.
++# Makefile for the TIATM device driver.
+ #
+-#
+-# Copyright (c) 2000 Texas Instruments Incorporated.
+-# Jeff Harrell (jharrell@telogy.com)
+-# Viren Balar (vbalar@ti.com)
+-# Victor Wells (vwells@telogy.com)
+-#
+-include $(TOPDIR)/Rules.make
+-
+-
+-
+-
+-
+-
+
++CONFIG_SANGAM_ATM=m
++#EXTRA_CFLAGS += -DEL -I. -DPOST_SILICON -DCOMMON_NSP -DCONFIG_LED_MODULE -DDEREGISTER_LED -DNO_ACT
++EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -DNO_ACT -D__NO__VOICE_PATCH__ -DEL
++obj-$(CONFIG_SANGAM_ATM) := tiatm.o
++tiatm-objs += cpsar.o aal5sar.o tn7sar.o tn7atm.o tn7dsl.o dsl_hal_api.o dsl_hal_support.o
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -61,7 +61,6 @@
+ * UR8_MERGE_END CQ11057*
+ *********************************************************************************************/
+
+-#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -69,11 +68,14 @@
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+ #include <linux/smp_lock.h>
+-#include <asm/io.h>
+-#include <asm/mips-boards/prom.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
++
++#include <asm/io.h>
++#include <asm/ar7/ar7.h>
++#include <asm/ar7/prom.h>
++
+ #include "dsl_hal_api.h"
+ #include "tn7atm.h"
+ #include "tn7api.h"
+@@ -82,6 +84,7 @@
+ #include "dsl_hal_register.h"
+
+ #ifdef MODULE
++MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION ("Tnetd73xx ATM Device Driver");
+ MODULE_AUTHOR ("Zhicheng Tang");
+ #endif
+@@ -100,9 +103,9 @@ MODULE_AUTHOR ("Zhicheng Tang");
+
+ /*end of externs */
+
+-#ifndef TI_STATIC_ALLOCATIONS
+-#define TI_STATIC_ALLOCATIONS
+-#endif
++//#ifndef TI_STATIC_ALLOCATIONS
++//#define TI_STATIC_ALLOCATIONS
++//#endif
+
+ #define tn7atm_kfree_skb(x) dev_kfree_skb(x)
+
+@@ -114,7 +117,7 @@ static int EnableQoS = FALSE;
+ /* prototypes */
+ static int tn7atm_set_can_support_adsl2 (int can);
+
+-static int tn7atm_open (struct atm_vcc *vcc, short vpi, int vci);
++static int tn7atm_open (struct atm_vcc *vcc);
+
+ static void tn7atm_close (struct atm_vcc *vcc);
+
+@@ -257,13 +260,12 @@ static const struct atmdev_ops tn7atm_op
+ getsockopt: NULL,
+ setsockopt: NULL,
+ send: tn7atm_send,
+- sg_send: NULL,
+ phy_put: NULL,
+ phy_get: NULL,
+ change_qos: tn7atm_change_qos,
+ };
+
+-const char drv_proc_root_folder[] = "avalanche/";
++const char drv_proc_root_folder[] = "avalanche";
+ static struct proc_dir_entry *root_proc_dir_entry = NULL;
+ #define DRV_PROC_MODE 0644
+ static int proc_root_already_exists = TRUE;
+@@ -559,56 +561,6 @@ static int turbodsl_check_priority_type(
+
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+- * Function: int tn7atm_walk_vccs(struct atm_dev *dev, short *vcc, int *vci)
+- *
+- * Description: retrieve VPI/VCI for connection
+- *
+- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+-static int tn7atm_walk_vccs (struct atm_vcc *vcc, short *vpi, int *vci)
+-{
+- struct atm_vcc *walk;
+-
+- /*
+- * find a free VPI
+- */
+- if (*vpi == ATM_VPI_ANY)
+- {
+-
+- for (*vpi = 0, walk = vcc->dev->vccs; walk; walk = walk->next)
+- {
+-
+- if ((walk->vci == *vci) && (walk->vpi == *vpi))
+- {
+- (*vpi)++;
+- walk = vcc->dev->vccs;
+- }
+- }
+- }
+-
+- /*
+- * find a free VCI
+- */
+- if (*vci == ATM_VCI_ANY)
+- {
+-
+- for (*vci = ATM_NOT_RSV_VCI, walk = vcc->dev->vccs; walk;
+- walk = walk->next)
+- {
+-
+- if ((walk->vpi = *vpi) && (walk->vci == *vci))
+- {
+- *vci = walk->vci + 1;
+- walk = vcc->dev->vccs;
+- }
+- }
+- }
+-
+- return 0;
+-}
+-
+-
+-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+- *
+ * Function: int tn7atm_sar_irq(void)
+ *
+ * Description: tnetd73xx SAR interrupt.
+@@ -693,7 +645,7 @@ static int __init tn7atm_irq_request (st
+ * Register SAR interrupt
+ */
+ priv->sar_irq = LNXINTNUM (ATM_SAR_INT); /* Interrupt line # */
+- if (request_irq (priv->sar_irq, tn7atm_sar_irq, SA_INTERRUPT, "SAR ", dev))
++ if (request_irq (priv->sar_irq, tn7atm_sar_irq, IRQF_DISABLED, "SAR ", dev))
+ printk ("Could not register tn7atm_sar_irq\n");
+
+ /*
+@@ -704,14 +656,14 @@ static int __init tn7atm_irq_request (st
+ {
+ def_sar_inter_pace = os_atoi (ptr);
+ }
+- avalanche_request_pacing (priv->sar_irq, ATM_SAR_INT_PACING_BLOCK_NUM,
+- def_sar_inter_pace);
++/* avalanche_request_pacing (priv->sar_irq, ATM_SAR_INT_PACING_BLOCK_NUM,
++ def_sar_inter_pace);*/
+
+ /*
+ * Reigster Receive interrupt A
+ */
+ priv->dsl_irq = LNXINTNUM (ATM_DSL_INT); /* Interrupt line # */
+- if (request_irq (priv->dsl_irq, tn7atm_dsl_irq, SA_INTERRUPT, "DSL ", dev))
++ if (request_irq (priv->dsl_irq, tn7atm_dsl_irq, IRQF_DISABLED, "DSL ", dev))
+ printk ("Could not register tn7atm_dsl_irq\n");
+
+ /***** VRB Tasklet Mode ****/
+@@ -875,11 +827,15 @@ static int __init tn7atm_get_ESI (struct
+ #define ATM_VBR_RT 5
+ #endif
+
+-int tn7atm_open (struct atm_vcc *vcc, short vpi, int vci)
++int tn7atm_open (struct atm_vcc *vcc)
+ {
+ tn7atm_activate_vc_parm_t tn7atm_activate_vc_parm;
+ int rc;
+ //int flags;
++ tn7atm_activate_vc_parm.pcr = 0x20000;
++ tn7atm_activate_vc_parm.scr = 0x20000;
++ tn7atm_activate_vc_parm.mbs = 0x20000;
++ tn7atm_activate_vc_parm.cdvt = 10000;
+
+ dgprintf(1, "tn7atm_open()\n");
+
+@@ -891,24 +847,18 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ return -1;
+ }
+
+- MOD_INC_USE_COUNT;
++// MOD_INC_USE_COUNT;
+
+- /* find a free VPI/VCI */
+- tn7atm_walk_vccs(vcc, &vpi, &vci);
+-
+- vcc->vpi = vpi;
+- vcc->vci = vci;
+-
+- if ((vci == ATM_VCI_UNSPEC) || (vpi == ATM_VCI_UNSPEC))
++ if ((vcc->vci == ATM_VCI_UNSPEC) || (vcc->vpi == ATM_VCI_UNSPEC))
+ {
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+ return -EBUSY;
+ }
+
+- tn7atm_activate_vc_parm.vpi = vpi;
+- tn7atm_activate_vc_parm.vci = vci;
++ tn7atm_activate_vc_parm.vpi = vcc->vpi;
++ tn7atm_activate_vc_parm.vci = vcc->vci;
+
+- if ((vpi == CLEAR_EOC_VPI) && (vci == CLEAR_EOC_VCI))
++ if ((vcc->vpi == CLEAR_EOC_VPI) && (vcc->vci == CLEAR_EOC_VCI))
+ {
+ /* always use (max_dma_chan+1) for clear eoc */
+ tn7atm_activate_vc_parm.chan = EOC_DMA_CHAN;
+@@ -916,7 +866,7 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ /* check to see whether clear eoc is opened or not */
+ if (tn7atm_activate_vc_parm.priv->lut[tn7atm_activate_vc_parm.chan].inuse)
+ {
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+ printk("tn7atm_open: Clear EOC channel (dmachan=%d) already in use.\n", tn7atm_activate_vc_parm.chan);
+ return -EBUSY;
+ }
+@@ -925,7 +875,7 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ if (rc)
+ {
+ printk("tn7atm_open: failed to setup clear_eoc\n");
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+ return -EBUSY;
+ }
+ tn7atm_set_lut(tn7atm_activate_vc_parm.priv,vcc, tn7atm_activate_vc_parm.chan);
+@@ -934,17 +884,17 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ }
+ else /* PVC channel setup */
+ {
+- if ((vpi==REMOTE_MGMT_VPI) && (vci==REMOTE_MGMT_VCI))
++ if ((vcc->vpi==REMOTE_MGMT_VPI) && (vcc->vci==REMOTE_MGMT_VCI))
+ {
+ tn7atm_activate_vc_parm.chan = 14; /* always use chan 14 for MII PVC-base romote mgmt */
+ }
+ else
+ {
+- rc = tn7atm_lut_find(vpi, vci);
++ rc = tn7atm_lut_find(vcc->vpi, vcc->vci);
+ /* check to see whether PVC is opened or not */
+ if(ATM_NO_DMA_CHAN != rc)
+ {
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+ printk("PVC already opened. dmachan = %d\n", rc);
+ return -EBUSY;
+ }
+@@ -976,6 +926,7 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ tn7atm_activate_vc_parm.priority = 2;
+ break;
+
++#if 0
+ case ATM_VBR: /* Variable Bit Rate-Non RealTime*/
+ tn7atm_activate_vc_parm.qos = 1;
+ tn7atm_activate_vc_parm.priority = 1;
+@@ -997,6 +948,7 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ tn7atm_activate_vc_parm.mbs = vcc->qos.txtp.max_pcr;
+ tn7atm_activate_vc_parm.cdvt = vcc->qos.txtp.max_cdv;
+ break;
++#endif
+
+ default:
+ tn7atm_activate_vc_parm.qos = 2;
+@@ -1024,7 +976,7 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ if (rc < 0)
+ {
+ printk("failed to activate hw channel\n");
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+ tn7atm_lut_clear(vcc, tn7atm_activate_vc_parm.chan);
+ //spin_unlock_irqrestore(&chan_init_lock, flags);
+ return -EBUSY;
+@@ -1114,7 +1066,7 @@ void tn7atm_close (struct atm_vcc *vcc)
+ tn7atm_lut_clear (vcc, dmachan);
+ //spin_unlock_irqrestore (&closeLock, closeFlag);
+
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+
+ dgprintf (1, "Leave tn7atm_close\n");
+ }
+@@ -1528,8 +1480,7 @@ int tn7atm_receive (void *os_dev, int ch
+ * firewall is on */
+
+ dgprintf (3, "pushing the skb...\n");
+-
+- skb->stamp = vcc->timestamp = xtime;
++ __net_timestamp(skb);
+
+ xdump ((unsigned char *) skb->data, skb->len, 5);
+
+@@ -1725,8 +1676,7 @@ static void tn7atm_exit (void)
+
+ kfree (dev->dev_data);
+
+- // atm_dev_deregister (dev);
+- shutdown_atm_dev (dev);
++ atm_dev_deregister (dev);
+
+ /*
+ * remove proc entries
+@@ -1885,9 +1835,6 @@ static int __init tn7atm_detect (void)
+ /*
+ * Set up proc entry for atm stats
+ */
+- if (tn7atm_xlate_proc_name
+- (drv_proc_root_folder, &root_proc_dir_entry, &residual))
+- {
+ printk ("Creating new root folder %s in the proc for the driver stats \n",
+ drv_proc_root_folder);
+ root_proc_dir_entry = proc_mkdir (drv_proc_root_folder, NULL);
+@@ -1897,7 +1844,6 @@ static int __init tn7atm_detect (void)
+ return -ENOMEM;
+ }
+ proc_root_already_exists = FALSE;
+- }
+
+ /*
+ * AV: Clean-up. Moved all the definitions to the data structure.
+@@ -2479,7 +2425,5 @@ static int tn7atm_proc_qos_write(struct
+ return count;
+ }
+
+-#ifdef MODULE
+ module_init (tn7atm_detect);
+ module_exit (tn7atm_exit);
+-#endif /* MODULE */
+--- a/tn7atm.h
++++ b/tn7atm.h
+@@ -19,7 +19,8 @@
+ //#include "mips_support.h"
+ #include <linux/list.h>
+
+-#include <linux/config.h>
++#define MIPS_EXCEPTION_OFFSET 8
++#define LNXINTNUM(x)((x) + MIPS_EXCEPTION_OFFSET)
+
+ #ifdef CONFIG_MODVERSIONS
+ #include <linux/modversions.h>
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -94,7 +94,6 @@
+ * 1/02/07 JZ CQ11054: Data Precision and Range Changes for TR-069 Conformance
+ * UR8_MERGE_END CQ11054*
+ *********************************************************************************************/
+-#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -102,8 +101,6 @@
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+ #include <linux/smp_lock.h>
+-#include <asm/io.h>
+-#include <asm/mips-boards/prom.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
+@@ -111,6 +108,12 @@
+ #include <linux/timer.h>
+ #include <linux/vmalloc.h>
+ #include <linux/file.h>
++#include <linux/firmware.h>
++
++#include <asm/io.h>
++#include <asm/ar7/ar7.h>
++#include <asm/ar7/prom.h>
++
+ /* Modules specific header files */
+ #include "tn7atm.h"
+ #include "tn7api.h"
+@@ -173,7 +176,7 @@ led_reg_t ledreg[2];
+ static struct led_funcs ledreg[2];
+ #endif
+
+-#define DEV_DSLMOD 1
++#define DEV_DSLMOD CTL_UNNUMBERED
+ #define MAX_STR_SIZE 256
+ #define DSL_MOD_SIZE 256
+
+@@ -299,7 +302,7 @@ static PITIDSLHW_T pIhw;
+ static volatile int bshutdown;
+ static char info[MAX_STR_SIZE];
+ /* Used for DSL Polling enable */
+-static DECLARE_MUTEX_LOCKED (adsl_sem_overlay);
++static struct semaphore adsl_sem_overlay;
+
+ //kthread_t overlay_thread;
+ /* end of module wide declars */
+@@ -323,6 +326,14 @@ static int tn7dsl_proc_snr_print (char *
+ #define gDot1(a) ((a>0)?(a%10):((-a)%10))
+ // UR8_MERGE_END CQ11054*
+
++int avalanche_request_intr_pacing(int irq_nr, unsigned int blk_num,
++ unsigned int pace_value)
++{
++ printk("avalanche_request_pacing(%d, %u, %u); // not implemented\n", irq_nr, blk_num, pace_value);
++ return 0;
++}
++
++
+ int os_atoi(const char *pStr)
+ {
+ int MulNeg = (*pStr == '-' ? -1 : 1);
+@@ -359,39 +370,6 @@ void dprintf (int uDbgLevel, char *szFmt
+ #endif
+ }
+
+-int strcmp(const char *s1, const char *s2)
+-{
+-
+- int size = strlen(s1);
+-
+- return(strncmp(s1, s2, size));
+-}
+-
+-int strncmp(const char *s1, const char *s2, size_t size)
+-{
+- int i = 0;
+- int max_size = (int)size;
+-
+- while((s1[i] != 0) && i < max_size)
+- {
+- if(s2[i] == 0)
+- {
+- return -1;
+- }
+- if(s1[i] != s2[i])
+- {
+- return 1;
+- }
+- i++;
+- }
+- if(s2[i] != 0)
+- {
+- return 1;
+- }
+-
+- return 0;
+-}
+-
+ // * UR8_MERGE_START CQ10640 Jack Zhang
+ int tn7dsl_dump_dsp_memory(char *input_str) //cph99
+ {
+@@ -441,101 +419,74 @@ unsigned int shim_osGetCpuFrequency(void
+ return CpuFrequency;
+ }
+
+-int shim_osLoadFWImage(unsigned char *ptr)
++static void avsar_release(struct device *dev)
+ {
+- unsigned int bytesRead;
+- mm_segment_t oldfs;
+- static struct file *filp;
+- unsigned int imageLength=0x5ffff;
+-
+-
+- dgprintf(4, "tn7dsl_read_dsp()\n");
+-
+- dgprintf(4,"open file %s\n", DSP_FIRMWARE_PATH);
+-
+- filp=filp_open(DSP_FIRMWARE_PATH,00,O_RDONLY);
+- if(filp ==NULL)
+- {
+- printk("Failed: Could not open DSP binary file\n");
+- return -1;
+- }
+-
+- if (filp->f_dentry != NULL)
+- {
+- if (filp->f_dentry->d_inode != NULL)
+- {
+- printk ("DSP binary filesize = %d bytes\n",
+- (int) filp->f_dentry->d_inode->i_size);
+- imageLength = (unsigned int)filp->f_dentry->d_inode->i_size + 0x200;
+- }
+- }
+-
+- if (filp->f_op->read==NULL)
+- return -1; /* File(system) doesn't allow reads */
+-
+- /*
+- * Disable parameter checking
+- */
+- oldfs = get_fs();
+- set_fs(KERNEL_DS);
+-
+- /*
+- * Now read bytes from postion "StartPos"
+- */
+- filp->f_pos = 0;
+-
+- bytesRead = filp->f_op->read(filp,ptr,imageLength,&filp->f_pos);
+-
+- dgprintf(4,"file length = %d\n", bytesRead);
+-
+- set_fs(oldfs);
+-
+- /*
+- * Close the file
+- */
+- fput(filp);
+-
+- return bytesRead;
++ printk(KERN_DEBUG "avsar firmware released\n");
+ }
+
++static struct device avsar = {
++ .bus_id = "vlynq",
++ .release = avsar_release,
++};
+
+-unsigned int shim_read_overlay_page (void *ptr, unsigned int secOffset,
+- unsigned int secLength)
++int shim_osLoadFWImage(unsigned char *ptr)
+ {
+- unsigned int bytesRead;
+- mm_segment_t oldfs;
+- struct file *filp;
+-
+- dgprintf(4,"shim_read_overlay_page\n");
+- //dgprintf(4,"sec offset=%d, sec length =%d\n", secOffset, secLength);
++ const struct firmware *fw_entry;
++ size_t size;
+
+- filp=filp_open(DSP_FIRMWARE_PATH,00,O_RDONLY);
+- if(filp ==NULL)
+- {
+- printk("Failed: Could not open DSP binary file\n");
+- return -1;
+- }
+-
+- if (filp->f_op->read==NULL)
+- return -1; /* File(system) doesn't allow reads */
+-
+- /*
+- * Now read bytes from postion "StartPos"
+- */
+-
+- if(filp->f_op->llseek)
+- filp->f_op->llseek(filp,secOffset, 0);
+- oldfs = get_fs();
+- set_fs(KERNEL_DS);
+- filp->f_pos = secOffset;
+- bytesRead = filp->f_op->read(filp,ptr,secLength,&filp->f_pos);
+-
+- set_fs(oldfs);
+- /*
+- * Close the file
+- */
+- fput(filp);
+- return bytesRead;
++ printk("requesting firmware image \"ar0700xx.bin\"\n");
++ if(device_register(&avsar) < 0) {
++ printk(KERN_ERR
++ "avsar: device_register fails\n");
++ return -1;
++ }
++
++ if(request_firmware(&fw_entry, "ar0700xx.bin", &avsar)) {
++ printk(KERN_ERR
++ "avsar: Firmware not available\n");
++ device_unregister(&avsar);
++ return -1;
++ }
++ size = fw_entry->size;
++ device_unregister(&avsar);
++ if(size > 0x5ffff) {
++ printk(KERN_ERR
++ "avsar: Firmware too big (%d bytes)\n", size);
++ release_firmware(fw_entry);
++ return -1;
++ }
++ memcpy(ptr, fw_entry->data, size);
++ release_firmware(fw_entry);
++ return size;
++}
++
++unsigned int shim_read_overlay_page(void *ptr, unsigned int secOffset, unsigned int secLength)
++{
++ const struct firmware *fw_entry;
++
++ printk("requesting firmware image \"ar0700xx.bin\"\n");
++ if(device_register(&avsar) < 0) {
++ printk(KERN_ERR
++ "avsar: device_register fails\n");
++ return -1;
++ }
++
++ if(request_firmware(&fw_entry, "ar0700xx.bin", &avsar)) {
++ printk(KERN_ERR
++ "avsar: Firmware not available\n");
++ device_unregister(&avsar);
++ return -1;
++ }
++ device_unregister(&avsar);
++ if(fw_entry->size > secLength) {
++ printk(KERN_ERR
++ "avsar: Firmware too big (%d bytes)\n", fw_entry->size);
++ release_firmware(fw_entry);
++ return -1;
++ }
++ memcpy(ptr + secOffset, fw_entry->data, secLength);
++ release_firmware(fw_entry);
++ return secLength;
+ }
+
+ int shim_osLoadDebugFWImage(unsigned char *ptr)
+@@ -3064,6 +3015,7 @@ int tn7dsl_init(void *priv)
+ int high_precision_selected = 0;
+ // UR8_MERGE_END CQ11054*
+
++ sema_init(&adsl_sem_overlay, 0);
+ /*
+ * start dsl
+ */
+@@ -3442,7 +3394,7 @@ static int dslmod_sysctl(ctl_table *ctl,
+ */
+ if(write)
+ {
+- ret = proc_dostring(ctl, write, filp, buffer, lenp);
++ ret = proc_dostring(ctl, write, filp, buffer, lenp, 0);
+
+ switch (ctl->ctl_name)
+ {
+@@ -3528,14 +3480,14 @@ static int dslmod_sysctl(ctl_table *ctl,
+ else
+ {
+ len += sprintf(info+len, mod_req);
+- ret = proc_dostring(ctl, write, filp, buffer, lenp);
++ ret = proc_dostring(ctl, write, filp, buffer, lenp, 0);
+ }
+ return ret;
+ }
+
+
+ ctl_table dslmod_table[] = {
+- {DEV_DSLMOD, "dslmod", info, DSL_MOD_SIZE, 0644, NULL, &dslmod_sysctl}
++ {DEV_DSLMOD, "dslmod", info, DSL_MOD_SIZE, 0644, NULL, NULL, &dslmod_sysctl, &sysctl_string}
+ ,
+ {0}
+ };
+@@ -3558,8 +3510,7 @@ void tn7dsl_dslmod_sysctl_register(void)
+ if (initialized == 1)
+ return;
+
+- dslmod_sysctl_header = register_sysctl_table(dslmod_root_table, 1);
+- dslmod_root_table->child->de->owner = THIS_MODULE;
++ dslmod_sysctl_header = register_sysctl_table(dslmod_root_table);
+
+ /*
+ * set the defaults
+@@ -4821,4 +4772,4 @@ int tn7dsl_proc_PMDus(char* buf, char **
+ }
+ #endif //NO_ADV_STATS
+ #endif //TR69_PMD_IN
+-// * UR8_MERGE_END CQ11057 *
+\ No newline at end of file
++// * UR8_MERGE_END CQ11057 *
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -42,7 +42,6 @@
+ * UR8_MERGE_END CQ10700
+ *******************************************************************************/
+
+-#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -50,12 +49,13 @@
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+ #include <linux/smp_lock.h>
+-#include <asm/io.h>
+-#include <asm/mips-boards/prom.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
+
++#include <asm/io.h>
++#include <asm/ar7/ar7.h>
++#include <asm/ar7/prom.h>
+
+ #define _CPHAL_AAL5
+ #define _CPHAL_SAR
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/110-interrupt_fix.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/110-interrupt_fix.patch
new file mode 100644
index 0000000000..9acb862e5d
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/110-interrupt_fix.patch
@@ -0,0 +1,37 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -566,7 +566,7 @@ static int turbodsl_check_priority_type(
+ * Description: tnetd73xx SAR interrupt.
+ *
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+-static void tn7atm_sar_irq (int irq, void *voiddev, struct pt_regs *regs)
++static irqreturn_t tn7atm_sar_irq (int irq, void *voiddev)
+ {
+ struct atm_dev *atmdev;
+ Tn7AtmPrivate *priv;
+@@ -593,6 +593,7 @@ static void tn7atm_sar_irq (int irq, voi
+ #ifdef TIATM_INST_SUPP
+ psp_trace_par (ATM_DRV_SAR_ISR_EXIT, retval);
+ #endif
++ return IRQ_HANDLED;
+ }
+
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+@@ -602,7 +603,7 @@ static void tn7atm_sar_irq (int irq, voi
+ * Description: tnetd73xx DSL interrupt.
+ *
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+-static void tn7atm_dsl_irq (int irq, void *voiddev, struct pt_regs *regs)
++static irqreturn_t tn7atm_dsl_irq (int irq, void *voiddev)
+ {
+ struct atm_dev *atmdev;
+ Tn7AtmPrivate *priv;
+@@ -624,6 +625,8 @@ static void tn7atm_dsl_irq (int irq, voi
+ #ifdef TIATM_INST_SUPP
+ psp_trace_par (ATM_DRV_DSL_ISR_EXIT, retval);
+ #endif
++
++ return IRQ_HANDLED;
+ }
+
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/120-no_dumb_inline.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/120-no_dumb_inline.patch
new file mode 100644
index 0000000000..2968fdc166
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/120-no_dumb_inline.patch
@@ -0,0 +1,11 @@
+--- a/tn7api.h
++++ b/tn7api.h
+@@ -107,7 +107,7 @@ int tn7dsl_proc_dbg_rmsgs4(char* buf, ch
+
+ int tn7dsl_proc_write_stats(struct file *fp, const char * buf, unsigned long count, void * data);
+ int tn7dsl_proc_modem(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-inline int tn7dsl_handle_interrupt(void);
++int tn7dsl_handle_interrupt(void);
+
+ void tn7dsl_dslmod_sysctl_register(void);
+ void tn7dsl_dslmod_sysctl_unregister(void);
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/130-powercutback.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/130-powercutback.patch
new file mode 100644
index 0000000000..ec00df97ab
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/130-powercutback.patch
@@ -0,0 +1,44 @@
+--- a/dsl_hal_advcfg.c
++++ b/dsl_hal_advcfg.c
+@@ -36,9 +36,9 @@
+ * 05Jul05 0.00.09 CPH CQ9775: Change dslhal_advcfg_configDsTones input parameters & support for ADSL2+
+ * 24Jul05 0.00.10 CPH Fixed comments in dslhal_advcfg_configDsTones function header
+ *******************************************************************************/
+-#include <dev_host_interface.h>
+-#include <dsl_hal_register.h>
+-#include <dsl_hal_support.h>
++#include "dev_host_interface.h"
++#include "dsl_hal_register.h"
++#include "dsl_hal_support.h"
+
+ /*****************************************************************************/
+ /* ACT API functions -- To be moved into their own independent module --RamP */
+--- a/Makefile
++++ b/Makefile
+@@ -4,6 +4,7 @@
+
+ CONFIG_SANGAM_ATM=m
+ #EXTRA_CFLAGS += -DEL -I. -DPOST_SILICON -DCOMMON_NSP -DCONFIG_LED_MODULE -DDEREGISTER_LED -DNO_ACT
+-EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -DNO_ACT -D__NO__VOICE_PATCH__ -DEL
++#EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -DNO_ACT -D__NO__VOICE_PATCH__ -DEL
++EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -D__NO__VOICE_PATCH__ -DEL
+ obj-$(CONFIG_SANGAM_ATM) := tiatm.o
+-tiatm-objs += cpsar.o aal5sar.o tn7sar.o tn7atm.o tn7dsl.o dsl_hal_api.o dsl_hal_support.o
++tiatm-objs += cpsar.o aal5sar.o tn7sar.o tn7atm.o tn7dsl.o dsl_hal_api.o dsl_hal_support.o dsl_hal_advcfg.o
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -2869,6 +2869,14 @@ static int tn7dsl_set_dsl(void)
+ dslhal_api_setRateAdaptFlag(pIhw, os_atoi(ptr));
+ }
+
++ // set powercutback
++ ptr = NULL;
++ ptr = prom_getenv("powercutback");
++ if(ptr)
++ {
++ dslhal_advcfg_onOffPcb(pIhw, os_atoi(ptr));
++ }
++
+ // trellis
+ ptr = NULL;
+ ptr = prom_getenv("trellis");
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/140-debug_mode.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/140-debug_mode.patch
new file mode 100644
index 0000000000..ce3697b10d
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/140-debug_mode.patch
@@ -0,0 +1,16 @@
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -103,10 +103,10 @@ enum
+
+ #define RESERVED_OAM_CHANNEL 15
+
+-#define AAL5_PARM "id=aal5, base = 0x03000000, offset = 0, int_line=15, ch0=[RxBufSize=1522; RxNumBuffers = 32; RxServiceMax = 50; TxServiceMax=50; TxNumBuffers=32; CpcsUU=0x5aa5; TxVc_CellRate=0x3000; TxVc_AtmHeader=0x00000640]"
+-#define SAR_PARM "id=sar,base = 0x03000000, reset_bit = 9, offset = 0; UniNni = 0, PdspEnable = 1"
++#define CH0_PARM "RxBufSize=1522, RxNumBuffers=32, RxServiceMax=50, TxServiceMax=50, TxNumBuffers=32, CpcsUU=0x5aa5, TxVc_CellRate=0x3000, TxVc_AtmHeader=0x00000640"
++#define AAL5_PARM "id=aal5, base=0x03000000, offset=0, int_line=15, ch0=[" CH0_PARM "]"
++#define SAR_PARM "id=sar, base=0x03000000, reset_bit=9, offset=0; UniNni=0, PdspEnable=1, Debug=0xFFFFFFFF"
+ #define RESET_PARM "id=ResetControl, base=0xA8611600"
+-#define CH0_PARM "RxBufSize=1522, RxNumBuffers = 32, RxServiceMax = 50, TxServiceMax=50, TxNumBuffers=32, CpcsUU=0x5aa5, TxVc_CellRate=0x3000, TxVc_AtmHeader=0x00000640"
+
+ #define MAX_PVC_TABLE_ENTRY 16
+
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/150-tasklet_mode.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/150-tasklet_mode.patch
new file mode 100644
index 0000000000..97b8cecdd9
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/150-tasklet_mode.patch
@@ -0,0 +1,11 @@
+--- a/Makefile
++++ b/Makefile
+@@ -5,6 +5,7 @@
+ CONFIG_SANGAM_ATM=m
+ #EXTRA_CFLAGS += -DEL -I. -DPOST_SILICON -DCOMMON_NSP -DCONFIG_LED_MODULE -DDEREGISTER_LED -DNO_ACT
+ #EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -DNO_ACT -D__NO__VOICE_PATCH__ -DEL
+-EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -D__NO__VOICE_PATCH__ -DEL
++#EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -D__NO__VOICE_PATCH__ -DEL
++EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -D__NO__VOICE_PATCH__ -DEL -DCPATM_TASKLET_MODE
+ obj-$(CONFIG_SANGAM_ATM) := tiatm.o
+ tiatm-objs += cpsar.o aal5sar.o tn7sar.o tn7atm.o tn7dsl.o dsl_hal_api.o dsl_hal_support.o dsl_hal_advcfg.o
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/160-module-params.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/160-module-params.patch
new file mode 100644
index 0000000000..67802ae1e9
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/160-module-params.patch
@@ -0,0 +1,589 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -87,6 +87,146 @@
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION ("Tnetd73xx ATM Device Driver");
+ MODULE_AUTHOR ("Zhicheng Tang");
++
++int mp_sar_ipacemax = -1;
++module_param_named(ipacemax, mp_sar_ipacemax, int, 0);
++MODULE_PARM_DESC(ipacemax, "Interrupt pacing");
++
++char *mp_macc = NULL;
++module_param_named(macc, mp_macc, charp, 0);
++MODULE_PARM_DESC(macc, "MAC address");
++
++int mp_dsp_noboost = -1;
++module_param_named(dsp_noboost, mp_dsp_noboost, int, 0);
++MODULE_PARM_DESC(dsp_noboost, "Suppress DSP frequency boost");
++
++int mp_dsp_freq = -1;
++module_param_named(dsp_freq, mp_dsp_freq, int, 0);
++MODULE_PARM_DESC(dsp_freq, "Frequency to boost the DSP to");
++
++char *mp_featctl0 = NULL;
++module_param_named(featctl0, mp_featctl0, charp, 0);
++MODULE_PARM_DESC(featctl0, "DSL feature control 0");
++
++char *mp_featctl1 = NULL;
++module_param_named(featctl1, mp_featctl1, charp, 0);
++MODULE_PARM_DESC(featctl1, "DSL feature control 1");
++
++char *mp_phyctl0 = NULL;
++module_param_named(phyctl0, mp_phyctl0, charp, 0);
++MODULE_PARM_DESC(phyctl0, "DSL PHY control 0");
++
++char *mp_phyctl1 = NULL;
++module_param_named(phyctl1, mp_phyctl1, charp, 0);
++MODULE_PARM_DESC(phyctl1, "DSL PHY control 1");
++
++int mp_turbodsl = -1;
++module_param_named(turbodsl, mp_turbodsl, int, 0);
++MODULE_PARM_DESC(turbodsl, "Enable TurboDSL");
++
++int mp_sar_rxbuf = -1;
++module_param_named(sar_rxbuf, mp_sar_rxbuf, int, 0);
++MODULE_PARM_DESC(sar_rxbuf, "SAR RxBuf size");
++
++int mp_sar_rxmax = -1;
++module_param_named(sar_rxmax, mp_sar_rxmax, int, 0);
++MODULE_PARM_DESC(sar_rxmax, "SAR RxMax size");
++
++int mp_sar_txbuf = -1;
++module_param_named(sar_txbuf, mp_sar_txbuf, int, 0);
++MODULE_PARM_DESC(sar_txbuf, "SAR TxBuf size");
++
++int mp_sar_txmax = -1;
++module_param_named(sar_txmax, mp_sar_txmax, int, 0);
++MODULE_PARM_DESC(sar_txmax, "SAR TxMax size");
++
++char *mp_modulation = NULL;
++module_param_named(modulation, mp_modulation, charp, 0);
++MODULE_PARM_DESC(modulation, "Modulation");
++
++int mp_fine_gain_control = -1;
++module_param_named(fine_gain_control, mp_fine_gain_control, int, 0);
++MODULE_PARM_DESC(fine_gain_control, "Fine gain control");
++
++int mp_fine_gain_value = -1;
++module_param_named(fine_gain_value, mp_fine_gain_value, int, 0);
++MODULE_PARM_DESC(fine_gain_value, "Fine gain value");
++
++int mp_enable_margin_retrain = -1;
++module_param_named(enable_margin_retrain, mp_enable_margin_retrain, int, 0);
++MODULE_PARM_DESC(enable_margin_retrain, "Enable margin retrain");
++
++int mp_margin_threshold = -1;
++module_param_named(margin_threshold, mp_margin_threshold, int, 0);
++MODULE_PARM_DESC(margin_threshold, "Margin retrain treshold");
++
++int mp_enable_rate_adapt = -1;
++module_param_named(enable_rate_adapt, mp_enable_rate_adapt, int, 0);
++MODULE_PARM_DESC(enable_rate_adapt, "Enable rate adaption");
++
++int mp_powercutback = -1;
++module_param_named(powercutback, mp_powercutback, int, 0);
++MODULE_PARM_DESC(powercutback, "Enable / disable powercutback");
++
++int mp_trellis = -1;
++module_param_named(trellis, mp_trellis, int, 0);
++MODULE_PARM_DESC(trellis, "Enable / disable trellis coding");
++
++int mp_bitswap = -1;
++module_param_named(bitswap, mp_bitswap, int, 0);
++MODULE_PARM_DESC(bitswap, "Enable / disable bitswap");
++
++int mp_maximum_bits_per_carrier = -1;
++module_param_named(maximum_bits_per_carrier, mp_maximum_bits_per_carrier, int, 0);
++MODULE_PARM_DESC(maximum_bits_per_carrier, "Maximum bits per carrier");
++
++int mp_maximum_interleave_depth = -1;
++module_param_named(maximum_interleave_depth, mp_maximum_interleave_depth, int, 0);
++MODULE_PARM_DESC(maximum_interleave_depth, "Maximum interleave depth");
++
++int mp_pair_selection = -1;
++module_param_named(pair_selection, mp_pair_selection, int, 0);
++MODULE_PARM_DESC(pair_selection, "Pair selection");
++
++int mp_dgas_polarity = -1;
++module_param_named(dgas_polarity, mp_dgas_polarity, int, 0);
++MODULE_PARM_DESC(dgas_polarity, "DGAS polarity");
++
++int mp_los_alarm = -1;
++module_param_named(los_alarm, mp_los_alarm, int, 0);
++MODULE_PARM_DESC(los_alarm, "LOS alarm");
++
++char *mp_eoc_vendor_id = NULL;
++module_param_named(eoc_vendor_id, mp_eoc_vendor_id, charp, 0);
++MODULE_PARM_DESC(eoc_vendor_id, "EOC vendor id");
++
++int mp_eoc_vendor_revision = -1;
++module_param_named(eoc_vendor_revision, mp_eoc_vendor_revision, int, 0);
++MODULE_PARM_DESC(eoc_vendor_revision, "EOC vendor revision");
++
++char *mp_eoc_vendor_serialnum = NULL;
++module_param_named(eoc_vendor_serialnum, mp_eoc_vendor_serialnum, charp, 0);
++MODULE_PARM_DESC(eoc_vendor_serialnum, "EOC vendor serial number");
++
++char *mp_invntry_vernum = NULL;
++module_param_named(invntry_vernum, mp_invntry_vernum, charp, 0);
++MODULE_PARM_DESC(invntry_vernum, "Inventory revision number");
++
++int mp_dsl_bit_tmode = -1;
++module_param_named(dsl_bit_tmode, mp_dsl_bit_tmode, int, 0);
++MODULE_PARM_DESC(dsl_bit_tmode, "DSL bit training mode");
++
++int mp_high_precision = -1;
++module_param_named(high_precision, mp_high_precision, int, 0);
++MODULE_PARM_DESC(high_precision, "High precision");
++
++int mp_autopvc_enable = -1;
++module_param_named(autopvc_enable, mp_autopvc_enable, int, 0);
++MODULE_PARM_DESC(autopvc_enable, "Enable / disable automatic PVC");
++
++int mp_oam_lb_timeout = -1;
++module_param_named(oam_lb_timeout, mp_oam_lb_timeout, int, 0);
++MODULE_PARM_DESC(oam_lb_timeout, "OAM LB timeout");
+ #endif
+
+ #ifndef TRUE
+@@ -655,9 +795,9 @@
+ * interrupt pacing
+ */
+ ptr = prom_getenv ("sar_ipacemax");
+- if (ptr)
++ if (ptr || mp_sar_ipacemax != -1)
+ {
+- def_sar_inter_pace = os_atoi (ptr);
++ def_sar_inter_pace = mp_sar_ipacemax == -1 ? os_atoi (ptr) : mp_sar_ipacemax;
+ }
+ /* avalanche_request_pacing (priv->sar_irq, ATM_SAR_INT_PACING_BLOCK_NUM,
+ def_sar_inter_pace);*/
+@@ -795,9 +935,18 @@
+ {
+ int i;
+ char esi_addr[ESI_LEN] = { 0x00, 0x00, 0x11, 0x22, 0x33, 0x44 };
+- char *esiaddr_str = NULL;
++ char *esiaddr_str = mp_macc;
+
+- esiaddr_str = prom_getenv ("maca");
++ if (esiaddr_str == NULL)
++ esiaddr_str = prom_getenv ("macdsl");
++ if (esiaddr_str == NULL)
++ esiaddr_str = prom_getenv ("macc");
++ if (esiaddr_str == NULL)
++ esiaddr_str = prom_getenv ("HWA_1");
++ if (esiaddr_str == NULL)
++ esiaddr_str = prom_getenv ("macb");
++ if (esiaddr_str == NULL)
++ esiaddr_str = prom_getenv ("maca");
+
+ if (!esiaddr_str)
+ {
+@@ -1930,15 +2079,15 @@
+ //UR8_MERGE_END CQ10450*
+
+ cp = prom_getenv ("dsp_noboost");
+- if (cp)
++ if (cp || mp_dsp_noboost != -1)
+ {
+- dsp_noboost = os_atoi (cp);
++ dsp_noboost = mp_dsp_noboost == -1 ? os_atoi (cp) : mp_dsp_noboost;
+ }
+
+ cp = (char *) prom_getenv ("dsp_freq");
+- if (cp)
++ if (cp || mp_dsp_freq != -1)
+ {
+- dspfreq = os_atoi (cp);
++ dspfreq = mp_dsp_freq == -1 ? os_atoi (cp) : mp_dsp_freq;
+ if (dspfreq == 250)
+ {
+ boostDsp = 1;
+@@ -2187,8 +2336,9 @@
+ // Inter-Op DSL phy Control
+ // Note the setting of _dsl_Feature_0 and _dsl_Feature_1 must before
+ // dslhal_api_dslStartup (in tn7dsl_init()).
+- if ((ptr = prom_getenv ("DSL_FEATURE_CNTL_0")) != NULL)
++ if ((ptr = prom_getenv ("DSL_FEATURE_CNTL_0")) != NULL || mp_featctl0 != NULL)
+ {
++ if (mp_featctl0 != NULL) ptr = mp_featctl0;
+ if ((ptr[0] == '0') && (ptr[1] == 'x')) // skip 0x before pass to
+ // os_atoh
+ ptr += 2;
+@@ -2196,8 +2346,9 @@
+ _dsl_Feature_0_defined = 1;
+ }
+
+- if ((ptr = prom_getenv ("DSL_FEATURE_CNTL_1")) != NULL)
++ if ((ptr = prom_getenv ("DSL_FEATURE_CNTL_1")) != NULL || mp_featctl1 != NULL)
+ {
++ if (mp_featctl1 != NULL) ptr = mp_featctl1;
+ if ((ptr[0] == '0') && (ptr[1] == 'x')) // skip 0x before pass to
+ // os_atoh
+ ptr += 2;
+@@ -2209,8 +2360,9 @@
+ // DSL phy Feature Control
+ // Note the setting of _dsl_PhyControl_0 and _dsl_PhyControl_1 must before
+ // dslhal_api_dslStartup (in tn7dsl_init()).
+- if ((ptr = prom_getenv ("DSL_PHY_CNTL_0")) != NULL)
++ if ((ptr = prom_getenv ("DSL_PHY_CNTL_0")) != NULL || mp_phyctl0 != NULL)
+ {
++ if (mp_phyctl0 != NULL) ptr = mp_phyctl0;
+ if ((ptr[0] == '0') && (ptr[1] == 'x')) // skip 0x before pass to
+ // os_atoh
+ ptr += 2;
+@@ -2218,8 +2370,9 @@
+ _dsl_PhyControl_0_defined = 1;
+ }
+
+- if ((ptr = prom_getenv ("DSL_PHY_CNTL_1")) != NULL)
++ if ((ptr = prom_getenv ("DSL_PHY_CNTL_1")) != NULL || mp_phyctl1 != NULL)
+ {
++ if (mp_phyctl1 != NULL) ptr = mp_phyctl1;
+ if ((ptr[0] == '0') && (ptr[1] == 'x')) // skip 0x before pass to
+ // os_atoh
+ ptr += 2;
+@@ -2247,9 +2400,9 @@
+ priv->bTurboDsl = 1;
+ // read config for turbo dsl
+ ptr = prom_getenv ("TurboDSL");
+- if (ptr)
++ if (ptr || mp_turbodsl != -1)
+ {
+- priv->bTurboDsl = os_atoi (ptr);
++ priv->bTurboDsl = mp_turbodsl == -1 ? os_atoi (ptr) : mp_turbodsl;
+ }
+
+ // @Added to make Rx buffer number & Service max configurable through
+@@ -2257,30 +2410,30 @@
+ priv->sarRxBuf = RX_BUFFER_NUM;
+ ptr = NULL;
+ ptr = prom_getenv ("SarRxBuf");
+- if (ptr)
++ if (ptr || mp_sar_rxbuf != -1)
+ {
+- priv->sarRxBuf = os_atoi (ptr);
++ priv->sarRxBuf = mp_sar_rxbuf == -1 ? os_atoi (ptr) : mp_sar_rxbuf;
+ }
+ priv->sarRxMax = RX_SERVICE_MAX;
+ ptr = NULL;
+ ptr = prom_getenv ("SarRxMax");
+- if (ptr)
++ if (ptr || mp_sar_rxmax != -1)
+ {
+- priv->sarRxMax = os_atoi (ptr);
++ priv->sarRxMax = mp_sar_rxmax == -1 ? os_atoi (ptr) : mp_sar_rxmax;
+ }
+ priv->sarTxBuf = TX_BUFFER_NUM;
+ ptr = NULL;
+ ptr = prom_getenv ("SarTxBuf");
+- if (ptr)
++ if (ptr || mp_sar_txbuf != -1)
+ {
+- priv->sarTxBuf = os_atoi (ptr);
++ priv->sarTxBuf = mp_sar_txbuf == -1 ? os_atoi (ptr) : mp_sar_txbuf;
+ }
+ priv->sarTxMax = TX_SERVICE_MAX;
+ ptr = NULL;
+ ptr = prom_getenv ("SarTxMax");
+- if (ptr)
++ if (ptr || mp_sar_txmax != -1)
+ {
+- priv->sarTxMax = os_atoi (ptr);
++ priv->sarTxMax = mp_sar_txmax == -1 ? os_atoi (ptr) : mp_sar_txmax;
+ }
+
+ return 0;
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -136,6 +136,27 @@
+ #define NEW_TRAINING_VAL_T1413 128
+ #define NEW_TRAINING_VAL_MMODE 255
+
++extern char *mp_modulation;
++extern int mp_fine_gain_control;
++extern int mp_fine_gain_value;
++extern int mp_enable_margin_retrain;
++extern int mp_margin_threshold;
++extern int mp_enable_rate_adapt;
++extern int mp_powercutback;
++extern int mp_trellis;
++extern int mp_bitswap;
++extern int mp_maximum_bits_per_carrier;
++extern int mp_maximum_interleave_depth;
++extern int mp_pair_selection;
++extern int mp_dgas_polarity;
++extern int mp_los_alarm;
++extern char *mp_eoc_vendor_id;
++extern int mp_eoc_vendor_revision;
++extern char *mp_eoc_vendor_serialnum;
++extern char *mp_invntry_vernum;
++extern int mp_dsl_bit_tmode;
++extern int mp_high_precision;
++
+ int testflag1 = 0;
+ extern int __guDbgLevel;
+ extern sar_stat_t sarStat;
+@@ -2818,84 +2839,80 @@ static int tn7dsl_set_dsl(void)
+
+ // modulation
+ ptr = prom_getenv("modulation");
+- if (ptr)
++ if (ptr || mp_modulation != NULL)
+ {
+- tn7dsl_set_modulation(ptr, FALSE);
++ tn7dsl_set_modulation(mp_modulation == NULL ? ptr : mp_modulation, FALSE);
+ }
+
+ // Fine Gains
+ ptr = prom_getenv("fine_gain_control");
+- if (ptr)
++ if (ptr || mp_fine_gain_control != -1)
+ {
+- value = os_atoi(ptr);
++ value = mp_fine_gain_control == -1 ? os_atoi(ptr) : mp_fine_gain_control;
+ tn7dsl_ctrl_fineGain(value);
+ }
+ ptr = NULL;
+ ptr = prom_getenv("fine_gain_value");
+- if(ptr)
+- tn7dsl_set_fineGainValue(os_atoh(ptr));
++ if(ptr || mp_fine_gain_value != -1)
++ tn7dsl_set_fineGainValue(mp_fine_gain_value == -1 ? os_atoh(ptr) : mp_fine_gain_value);
+
+ // margin retrain
+ ptr = NULL;
+ ptr = prom_getenv("enable_margin_retrain");
+- if(ptr)
++ value = mp_enable_margin_retrain == -1 ? (ptr ? os_atoi(ptr) : 0) : mp_enable_margin_retrain;
++
++ if (value == 1)
+ {
+- value = os_atoi(ptr);
+- if(value == 1)
++ dslhal_api_setMarginMonitorFlags(pIhw, 0, 1);
++ bMarginRetrainEnable = 1;
++ //printk("enable showtime margin monitor.\n");
++
++ ptr = NULL;
++ ptr = prom_getenv("margin_threshold");
++ value = mp_margin_threshold == -1 ? (ptr ? os_atoi(ptr) : 0) : mp_margin_threshold;
++
++ if(value >= 0)
+ {
+- dslhal_api_setMarginMonitorFlags(pIhw, 0, 1);
+- bMarginRetrainEnable = 1;
+- //printk("enable showtime margin monitor.\n");
+- ptr = NULL;
+- ptr = prom_getenv("margin_threshold");
+- if(ptr)
+- {
+- value = os_atoi(ptr);
+- //printk("Set margin threshold to %d x 0.5 db\n",value);
+- if(value >= 0)
+- {
+- dslhal_api_setMarginThreshold(pIhw, value);
+- bMarginThConfig=1;
+- }
+- }
++ dslhal_api_setMarginThreshold(pIhw, value);
++ bMarginThConfig=1;
+ }
+ }
+
+ // rate adapt
+ ptr = NULL;
+ ptr = prom_getenv("enable_rate_adapt");
+- if(ptr)
++ if(ptr || mp_enable_rate_adapt != -1)
+ {
+- dslhal_api_setRateAdaptFlag(pIhw, os_atoi(ptr));
++ dslhal_api_setRateAdaptFlag(pIhw, mp_enable_rate_adapt == -1 ? os_atoi(ptr) : mp_enable_rate_adapt);
+ }
+
+ // set powercutback
+ ptr = NULL;
+ ptr = prom_getenv("powercutback");
+- if(ptr)
++ if(ptr || mp_powercutback != -1)
+ {
+- dslhal_advcfg_onOffPcb(pIhw, os_atoi(ptr));
++ dslhal_advcfg_onOffPcb(pIhw, mp_powercutback == -1 ? os_atoi(ptr) : mp_powercutback);
+ }
+
+ // trellis
+ ptr = NULL;
+ ptr = prom_getenv("trellis");
+- if(ptr)
++ if(ptr || mp_trellis != -1)
+ {
+- dslhal_api_setTrellisFlag(pIhw, os_atoi(ptr));
+- trellis = os_atoi(ptr);
++ trellis = mp_trellis == -1 ? os_atoi(ptr) : mp_trellis;
++ dslhal_api_setTrellisFlag(pIhw, trellis);
+ //printk("trellis=%d\n");
+ }
+
+ // bitswap
+ ptr = NULL;
+ ptr = prom_getenv("bitswap");
+- if(ptr)
++ if(ptr || mp_bitswap != -1)
+ {
+ int offset[2] = {33, 0};
+ unsigned int bitswap;
+
+- bitswap = os_atoi(ptr);
++ bitswap = mp_bitswap == -1 ? os_atoi(ptr) : mp_bitswap;
+
+ tn7dsl_generic_read(2, offset);
+ dslReg &= dslhal_support_byteSwap32(0xFFFFFF00);
+@@ -2913,46 +2930,47 @@ static int tn7dsl_set_dsl(void)
+ // maximum bits per carrier
+ ptr = NULL;
+ ptr = prom_getenv("maximum_bits_per_carrier");
+- if(ptr)
++ if(ptr || mp_maximum_bits_per_carrier != -1)
+ {
+- dslhal_api_setMaxBitsPerCarrierUpstream(pIhw, os_atoi(ptr));
++ dslhal_api_setMaxBitsPerCarrierUpstream(pIhw, mp_maximum_bits_per_carrier == -1 ? os_atoi(ptr) : mp_maximum_bits_per_carrier);
+ }
+
+ // maximum interleave depth
+ ptr = NULL;
+ ptr = prom_getenv("maximum_interleave_depth");
+- if(ptr)
++ if(ptr || mp_maximum_interleave_depth != -1)
+ {
+- dslhal_api_setMaxInterleaverDepth(pIhw, os_atoi(ptr));
++ dslhal_api_setMaxInterleaverDepth(pIhw, mp_maximum_interleave_depth == -1 ? os_atoi(ptr) : mp_maximum_interleave_depth);
+ }
+
+ // inner and outer pairs
+ ptr = NULL;
+ ptr = prom_getenv("pair_selection");
+- if(ptr)
++ if(ptr || mp_pair_selection != -1)
+ {
+- dslhal_api_selectInnerOuterPair(pIhw, os_atoi(ptr));
++ dslhal_api_selectInnerOuterPair(pIhw, mp_pair_selection == -1 ? os_atoi(ptr) : mp_pair_selection);
+ }
+
+ ptr = NULL;
+ ptr = prom_getenv("dgas_polarity");
+- if(ptr)
++ if(ptr || mp_dgas_polarity != -1)
+ {
+ dslhal_api_configureDgaspLpr(pIhw, 1, 1);
+- dslhal_api_configureDgaspLpr(pIhw, 0, os_atoi(ptr));
++ dslhal_api_configureDgaspLpr(pIhw, 0, mp_dgas_polarity == -1 ? os_atoi(ptr) : mp_dgas_polarity);
+ }
+
+ ptr = NULL;
+ ptr = prom_getenv("los_alarm");
+- if(ptr)
++ if(ptr || mp_los_alarm != -1)
+ {
+- dslhal_api_disableLosAlarm(pIhw, os_atoi(ptr));
++ dslhal_api_disableLosAlarm(pIhw, mp_los_alarm == -1 ? os_atoi(ptr) : mp_los_alarm);
+ }
+
+ ptr = NULL;
+ ptr = prom_getenv("eoc_vendor_id");
+- if(ptr)
++ if(ptr || mp_eoc_vendor_id != NULL)
+ {
++ ptr = mp_eoc_vendor_id == NULL ? ptr : mp_eoc_vendor_id;
+ for(i=0;i<8;i++)
+ {
+ tmp[0]=ptr[i*2];
+@@ -2977,26 +2995,26 @@ static int tn7dsl_set_dsl(void)
+ }
+ ptr = NULL;
+ ptr = prom_getenv("eoc_vendor_revision");
+- if(ptr)
++ if(ptr || mp_eoc_vendor_revision != -1)
+ {
+- value = os_atoi(ptr);
++ value = mp_eoc_vendor_revision == -1 ? os_atoi(ptr) : mp_eoc_vendor_revision;
+ //printk("eoc rev=%d\n", os_atoi(ptr));
+ dslhal_api_setEocRevisionNumber(pIhw, (char *)&value);
+
+ }
+ ptr = NULL;
+ ptr = prom_getenv("eoc_vendor_serialnum");
+- if(ptr)
++ if(ptr || mp_eoc_vendor_serialnum != NULL)
+ {
+- dslhal_api_setEocSerialNumber(pIhw, ptr);
++ dslhal_api_setEocSerialNumber(pIhw, mp_eoc_vendor_serialnum == NULL ? ptr : mp_eoc_vendor_serialnum);
+ }
+
+ // CQ10037 Added invntry_vernum environment variable to be able to set version number in ADSL2, ADSL2+ modes.
+ ptr = NULL;
+ ptr = prom_getenv("invntry_vernum");
+- if(ptr)
++ if(ptr || mp_invntry_vernum != NULL)
+ {
+- dslhal_api_setEocRevisionNumber(pIhw, ptr);
++ dslhal_api_setEocRevisionNumber(pIhw, mp_invntry_vernum == NULL ? ptr : mp_invntry_vernum);
+ }
+
+ return 0;
+@@ -3041,7 +3059,7 @@ int tn7dsl_init(void *priv)
+ * backward compatibility.
+ */
+ cp = prom_getenv("DSL_BIT_TMODE");
+- if (cp)
++ if (cp || mp_dsl_bit_tmode != -1)
+ {
+ printk("%s : env var DSL_BIT_TMODE is set\n", __FUNCTION__);
+ /*
+@@ -3070,9 +3088,9 @@ int tn7dsl_init(void *priv)
+
+ // UR8_MERGE_START CQ11054 Jack Zhang
+ cp = prom_getenv("high_precision");
+- if (cp)
++ if (cp || mp_high_precision != -1)
+ {
+- high_precision_selected = os_atoi(cp);
++ high_precision_selected = mp_high_precision == -1 ? os_atoi(cp) : mp_high_precision;
+ }
+ if ( high_precision_selected)
+ {
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -74,6 +74,8 @@ typedef void OS_SETUP;
+ /* PDSP Firmware files */
+ #include "tnetd7300_sar_firm.h"
+
++extern int mp_oam_lb_timeout;
++extern int mp_autopvc_enable;
+
+ enum
+ {
+@@ -817,9 +819,9 @@ int tn7sar_setup_oam_channel(Tn7AtmPriva
+ pHalDev = (HAL_DEVICE *)priv->pSarHalDev;
+
+ pauto_pvc = prom_getenv("autopvc_enable");
+- if(pauto_pvc) //CQ10273
++ if(pauto_pvc || mp_autopvc_enable != -1) //CQ10273
+ {
+- auto_pvc =tn7sar_strtoul(pauto_pvc, NULL, 10);
++ auto_pvc = mp_autopvc_enable == -1 ? tn7sar_strtoul(pauto_pvc, NULL, 10) : mp_autopvc_enable;
+ }
+
+ memset(&chInfo, 0xff, sizeof(chInfo));
+@@ -985,9 +987,9 @@ int tn7sar_init(struct atm_dev *dev, Tn7
+
+ /* read in oam lb timeout value */
+ pLbTimeout = prom_getenv("oam_lb_timeout");
+- if(pLbTimeout)
++ if(pLbTimeout || mp_oam_lb_timeout != -1)
+ {
+- lbTimeout =tn7sar_strtoul(pLbTimeout, NULL, 10);
++ lbTimeout = mp_oam_lb_timeout == -1 ? tn7sar_strtoul(pLbTimeout, NULL, 10) : mp_oam_lb_timeout;
+ oamLbTimeout = lbTimeout;
+ pHalFunc->Control(pHalDev,"OamLbTimeout", "Set", &lbTimeout);
+ }
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/170-bus_id_removal.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/170-bus_id_removal.patch
new file mode 100644
index 0000000000..9f1f0fdae4
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/170-bus_id_removal.patch
@@ -0,0 +1,30 @@
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -109,6 +109,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/file.h>
+ #include <linux/firmware.h>
++#include <linux/version.h>
+
+ #include <asm/io.h>
+ #include <asm/ar7/ar7.h>
+@@ -446,7 +447,9 @@ static void avsar_release(struct device
+ }
+
+ static struct device avsar = {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
+ .bus_id = "vlynq",
++#endif
+ .release = avsar_release,
+ };
+
+@@ -455,6 +458,9 @@ int shim_osLoadFWImage(unsigned char *pt
+ const struct firmware *fw_entry;
+ size_t size;
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
++ dev_set_name(&avsar, "avsar");
++#endif
+ printk("requesting firmware image \"ar0700xx.bin\"\n");
+ if(device_register(&avsar) < 0) {
+ printk(KERN_ERR
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/180-git_headers_include.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/180-git_headers_include.patch
new file mode 100644
index 0000000000..6bd8f48760
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/180-git_headers_include.patch
@@ -0,0 +1,54 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -71,10 +71,16 @@
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
++#include <linux/version.h>
+
+ #include <asm/io.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
+ #include <asm/ar7/ar7.h>
+ #include <asm/ar7/prom.h>
++#else
++#include <asm/mach-ar7/ar7.h>
++#include <asm/mach-ar7/prom.h>
++#endif
+
+ #include "dsl_hal_api.h"
+ #include "tn7atm.h"
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -112,8 +112,13 @@
+ #include <linux/version.h>
+
+ #include <asm/io.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
+ #include <asm/ar7/ar7.h>
+ #include <asm/ar7/prom.h>
++#else
++#include <asm/mach-ar7/ar7.h>
++#include <asm/mach-ar7/prom.h>
++#endif
+
+ /* Modules specific header files */
+ #include "tn7atm.h"
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -52,10 +52,16 @@
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
++#include <linux/version.h>
+
+ #include <asm/io.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
+ #include <asm/ar7/ar7.h>
+ #include <asm/ar7/prom.h>
++#else
++#include <asm/mach-ar7/ar7.h>
++#include <asm/mach-ar7/prom.h>
++#endif
+
+ #define _CPHAL_AAL5
+ #define _CPHAL_SAR
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/190-2.6.32_proc_fixes.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/190-2.6.32_proc_fixes.patch
new file mode 100644
index 0000000000..11487bf7a6
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/190-2.6.32_proc_fixes.patch
@@ -0,0 +1,79 @@
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -203,7 +203,11 @@ led_reg_t ledreg[2];
+ static struct led_funcs ledreg[2];
+ #endif
+
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+ #define DEV_DSLMOD CTL_UNNUMBERED
++#else
++#define DEV_DSLMOD 0
++#endif
+ #define MAX_STR_SIZE 256
+ #define DSL_MOD_SIZE 256
+
+@@ -3431,9 +3435,16 @@ static int dslmod_sysctl(ctl_table *ctl,
+ */
+ if(write)
+ {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+ ret = proc_dostring(ctl, write, filp, buffer, lenp, 0);
+-
++#else
++ ret = proc_dostring(ctl, write, buffer, lenp, 0);
++#endif
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+ switch (ctl->ctl_name)
++#else
++ switch ((long)ctl->extra2)
++#endif
+ {
+ case DEV_DSLMOD:
+ ptr = strpbrk(info, " \t");
+@@ -3517,14 +3528,29 @@ static int dslmod_sysctl(ctl_table *ctl,
+ else
+ {
+ len += sprintf(info+len, mod_req);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+ ret = proc_dostring(ctl, write, filp, buffer, lenp, 0);
++#else
++ ret = proc_dostring(ctl, write, buffer, lenp, 0);
++#endif
+ }
+ return ret;
+ }
+
+
+ ctl_table dslmod_table[] = {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+ {DEV_DSLMOD, "dslmod", info, DSL_MOD_SIZE, 0644, NULL, NULL, &dslmod_sysctl, &sysctl_string}
++#else
++ {
++ .procname = "dslmod",
++ .data = info,
++ .maxlen = DSL_MOD_SIZE,
++ .mode = 0644,
++ .proc_handler = &dslmod_sysctl,
++ .extra2 = (void *)DEV_DSLMOD,
++ }
++#endif
+ ,
+ {0}
+ };
+@@ -3532,7 +3558,16 @@ ctl_table dslmod_table[] = {
+ /* Make sure that /proc/sys/dev is there */
+ ctl_table dslmod_root_table[] = {
+ #ifdef CONFIG_PROC_FS
++ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+ {CTL_DEV, "dev", NULL, 0, 0555, dslmod_table}
++ #else
++ {
++ .procname = "dev",
++ .maxlen = 0,
++ .mode = 0555,
++ .child = dslmod_table,
++ }
++ #endif
+ ,
+ #endif /* CONFIG_PROC_FS */
+ {0}
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/200-2.6.37_args.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/200-2.6.37_args.patch
new file mode 100644
index 0000000000..59c1d58d15
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/200-2.6.37_args.patch
@@ -0,0 +1,36 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -1867,7 +1867,11 @@ static int __init tn7atm_register (Tn7At
+
+ dgprintf (4, "device %s being registered\n", priv->name);
+
++ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
+ mydev = atm_dev_register (priv->proc_name, &tn7atm_ops, -1, NULL);
++ #else
++ mydev = atm_dev_register (priv->proc_name, NULL, &tn7atm_ops, -1, NULL);
++ #endif
+
+ if (mydev == NULL)
+ {
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -466,14 +466,17 @@ int shim_osLoadFWImage(unsigned char *pt
+ {
+ const struct firmware *fw_entry;
+ size_t size;
++ int ret;
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
+ dev_set_name(&avsar, "avsar");
+ #endif
+ printk("requesting firmware image \"ar0700xx.bin\"\n");
+- if(device_register(&avsar) < 0) {
++ dev_set_name(&avsar, "avsar");
++ ret = device_register(&avsar);
++ if (ret < 0) {
+ printk(KERN_ERR
+- "avsar: device_register fails\n");
++ "avsar: device_register fails, error%i\n", ret);
+ return -1;
+ }
+
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/210-3.3-remove-smp_lock.h.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/210-3.3-remove-smp_lock.h.patch
new file mode 100644
index 0000000000..525218c3b4
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/210-3.3-remove-smp_lock.h.patch
@@ -0,0 +1,33 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -67,7 +67,7 @@
+ #include <linux/atmdev.h>
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+-#include <linux/smp_lock.h>
++#include <linux/interrupt.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -48,7 +48,7 @@
+ #include <linux/atmdev.h>
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+-#include <linux/smp_lock.h>
++#include <linux/interrupt.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -100,7 +100,7 @@
+ #include <linux/atmdev.h>
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+-#include <linux/smp_lock.h>
++#include <linux/interrupt.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/100-compile_fix.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/100-compile_fix.patch
new file mode 100644
index 0000000000..7dee220256
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/100-compile_fix.patch
@@ -0,0 +1,808 @@
+--- a/cppi_cpaal5.c
++++ b/cppi_cpaal5.c
+@@ -360,7 +360,7 @@ static int halRxReturn(HAL_RECEIVEINFO *
+ {
+ /* malloc failed, add this RCB to Needs Buffer List */
+ TempRcb->FragCount = 1; /*MJH+030417*/
+- (HAL_RCB *)TempRcb->Eop = TempRcb; /* GSG +030430 */
++ TempRcb->Eop = TempRcb; /* GSG +030430 */
+
+ if(HalDev->NeedsCount < MAX_NEEDS) /* +MJH 030410 */
+ { /* +MJH 030410 */
+--- a/dsl_hal_api.c
++++ b/dsl_hal_api.c
+@@ -273,15 +273,15 @@
+ * 09/15/07 CPH CQ11466 Added EFM support
+ * 09/27/07 EYin CQ11929: Added NFEC/INP/Lp/Rp reporting for only ADSL2/2+ mode.
+ ******************************************************************************/
+-#include <dev_host_interface.h>
+-#include <dsl_hal_register.h>
+-#include <dsl_hal_support.h>
++#include "dev_host_interface.h"
++#include "dsl_hal_register.h"
++#include "dsl_hal_support.h"
+
+ #ifndef NO_ADV_STATS
+-#include <dsl_hal_logtable.h>
++#include "dsl_hal_logtable.h"
+ #endif
+
+-#include <dsl_hal_version.h>
++#include "dsl_hal_version.h"
+
+ // UR8_MERGE_START CQ11054 Jack Zhang
+ static unsigned int highprecision_selected = 0; //By default we use low precision for backward compt.
+--- a/dsl_hal_support.c
++++ b/dsl_hal_support.c
+@@ -142,9 +142,9 @@
+ * UR8_MERGE_START_END CQ11922 Tim
+ * 04Sep07 0.14.00 Tim CQ11922: Added support for new scratchram for INP NDR tables
+ *******************************************************************************/
+-#include <dev_host_interface.h>
+-#include <dsl_hal_register.h>
+-#include <dsl_hal_support.h>
++#include "dev_host_interface.h"
++#include "dsl_hal_register.h"
++#include "dsl_hal_support.h"
+
+ #define NUM_READ_RETRIES 3
+ static unsigned int dslhal_support_adsl2ByteSwap32(unsigned int in32Bits);
+--- a/dsl_hal_support.h
++++ b/dsl_hal_support.h
+@@ -49,7 +49,7 @@
+ * 04Nov05 0.11.00 CPH Fixed T1413 mode got Zero DS/US rate when DSL_BIT_TMODE is set.
+ *******************************************************************************/
+
+-#include <dsl_hal_api.h>
++#include "dsl_hal_api.h"
+
+ #define virtual2Physical(a) (((int)a)&~0xe0000000)
+ /* External Function Prototype Declarations */
+--- a/Makefile
++++ b/Makefile
+@@ -1,18 +1,9 @@
+-# File: drivers/atm/ti_evm3/Makefile
+ #
+-# Makefile for the Texas Instruments EVM3 ADSL/ATM driver.
++# Makefile for the TIATM device driver.
+ #
+-#
+-# Copyright (c) 2000 Texas Instruments Incorporated.
+-# Jeff Harrell (jharrell@telogy.com)
+-# Viren Balar (vbalar@ti.com)
+-# Victor Wells (vwells@telogy.com)
+-#
+-include $(TOPDIR)/Rules.make
+-
+-
+-
+-
+-
+-
+
++CONFIG_SANGAM_ATM=m
++#EXTRA_CFLAGS += -DEL -I. -DPOST_SILICON -DCOMMON_NSP -DCONFIG_LED_MODULE -DDEREGISTER_LED -DNO_ACT
++EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -DNO_ACT -D__NO__VOICE_PATCH__ -DEL
++obj-$(CONFIG_SANGAM_ATM) := tiatm.o
++tiatm-objs += cpsar.o aal5sar.o tn7sar.o tn7atm.o tn7dsl.o dsl_hal_api.o dsl_hal_support.o
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -66,7 +66,6 @@
+ * 09/18/07 CPH CQ11466 Added EFM Support
+ *********************************************************************************************/
+
+-#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -74,11 +73,14 @@
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+ #include <linux/smp_lock.h>
+-#include <asm/io.h>
+-#include <asm/mips-boards/prom.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
++
++#include <asm/io.h>
++#include <asm/ar7/ar7.h>
++#include <asm/ar7/prom.h>
++
+ #include "dsl_hal_api.h"
+ #ifdef AR7_EFM
+ #include "tn7efm.h"
+@@ -90,6 +92,7 @@
+ #include "dsl_hal_register.h"
+
+ #ifdef MODULE
++MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION ("Tnetd73xx ATM Device Driver");
+ MODULE_AUTHOR ("Zhicheng Tang");
+ #endif
+@@ -108,9 +111,9 @@ MODULE_AUTHOR ("Zhicheng Tang");
+
+ /*end of externs */
+
+-#ifndef TI_STATIC_ALLOCATIONS
+-#define TI_STATIC_ALLOCATIONS
+-#endif
++//#ifndef TI_STATIC_ALLOCATIONS
++//#define TI_STATIC_ALLOCATIONS
++//#endif
+
+ #define tn7atm_kfree_skb(x) dev_kfree_skb(x)
+
+@@ -135,7 +138,7 @@ static int EnableQoS = FALSE;
+ /* prototypes */
+ static int tn7atm_set_can_support_adsl2 (int can);
+
+-static int tn7atm_open (struct atm_vcc *vcc, short vpi, int vci);
++static int tn7atm_open (struct atm_vcc *vcc);
+
+ void tn7atm_close (struct atm_vcc *vcc);
+
+@@ -298,13 +301,12 @@ static const struct atmdev_ops tn7atm_op
+ getsockopt: NULL,
+ setsockopt: NULL,
+ send: tn7atm_send,
+- sg_send: NULL,
+ phy_put: NULL,
+ phy_get: NULL,
+ change_qos: tn7atm_change_qos,
+ };
+
+-const char drv_proc_root_folder[] = "avalanche/";
++const char drv_proc_root_folder[] = "avalanche";
+ static struct proc_dir_entry *root_proc_dir_entry = NULL;
+ #define DRV_PROC_MODE 0644
+ static int proc_root_already_exists = TRUE;
+@@ -626,56 +628,6 @@ static int turbodsl_check_priority_type(
+
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+- * Function: int tn7atm_walk_vccs(struct atm_dev *dev, short *vcc, int *vci)
+- *
+- * Description: retrieve VPI/VCI for connection
+- *
+- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+-static int tn7atm_walk_vccs (struct atm_vcc *vcc, short *vpi, int *vci)
+-{
+- struct atm_vcc *walk;
+-
+- /*
+- * find a free VPI
+- */
+- if (*vpi == ATM_VPI_ANY)
+- {
+-
+- for (*vpi = 0, walk = vcc->dev->vccs; walk; walk = walk->next)
+- {
+-
+- if ((walk->vci == *vci) && (walk->vpi == *vpi))
+- {
+- (*vpi)++;
+- walk = vcc->dev->vccs;
+- }
+- }
+- }
+-
+- /*
+- * find a free VCI
+- */
+- if (*vci == ATM_VCI_ANY)
+- {
+-
+- for (*vci = ATM_NOT_RSV_VCI, walk = vcc->dev->vccs; walk;
+- walk = walk->next)
+- {
+-
+- if ((walk->vpi = *vpi) && (walk->vci == *vci))
+- {
+- *vci = walk->vci + 1;
+- walk = vcc->dev->vccs;
+- }
+- }
+- }
+-
+- return 0;
+-}
+-
+-
+-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+- *
+ * Function: int tn7atm_sar_irq(void)
+ *
+ * Description: tnetd73xx SAR interrupt.
+@@ -766,7 +718,7 @@ static int __init tn7atm_irq_request (st
+
+ priv->sar_irq = LNXINTNUM (ATM_SAR_INT); /* Interrupt line # */
+
+- if (request_irq (priv->sar_irq, tn7atm_sar_irq, SA_INTERRUPT, "SAR ", dev))
++ if (request_irq (priv->sar_irq, tn7atm_sar_irq, IRQF_DISABLED, "SAR ", dev))
+ printk ("Could not register tn7atm_sar_irq\n");
+
+ /*
+@@ -777,8 +729,8 @@ static int __init tn7atm_irq_request (st
+ {
+ def_sar_inter_pace = os_atoi (ptr);
+ }
+- avalanche_request_pacing (priv->sar_irq, ATM_SAR_INT_PACING_BLOCK_NUM,
+- def_sar_inter_pace);
++ /* avalanche_request_pacing (priv->sar_irq, ATM_SAR_INT_PACING_BLOCK_NUM,
++ def_sar_inter_pace); */
+
+
+ #ifdef AR7_EFM
+@@ -790,7 +742,7 @@ static int __init tn7atm_irq_request (st
+ * Reigster Receive interrupt A
+ */
+ priv->dsl_irq = LNXINTNUM (ATM_DSL_INT); /* Interrupt line # */
+- if (request_irq (priv->dsl_irq, tn7atm_dsl_irq, SA_INTERRUPT, "DSL ", dev))
++ if (request_irq (priv->dsl_irq, tn7atm_dsl_irq, IRQF_DISABLED, "DSL ", dev))
+ printk ("Could not register tn7atm_dsl_irq\n");
+
+ /***** VRB Tasklet Mode ****/
+@@ -958,11 +910,15 @@ static int __init tn7atm_get_ESI (struct
+ #define ATM_VBR_RT 5
+ #endif
+
+-int tn7atm_open (struct atm_vcc *vcc, short vpi, int vci)
++int tn7atm_open (struct atm_vcc *vcc)
+ {
+ tn7atm_activate_vc_parm_t tn7atm_activate_vc_parm;
+ int rc;
+ //int flags;
++ tn7atm_activate_vc_parm.pcr = 0x20000;
++ tn7atm_activate_vc_parm.scr = 0x20000;
++ tn7atm_activate_vc_parm.mbs = 0x20000;
++ tn7atm_activate_vc_parm.cdvt = 10000;
+
+ dgprintf(1, "tn7atm_open()\n");
+
+@@ -974,24 +930,18 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ return -1;
+ }
+
+- MOD_INC_USE_COUNT;
++// MOD_INC_USE_COUNT;
+
+- /* find a free VPI/VCI */
+- tn7atm_walk_vccs(vcc, &vpi, &vci);
+-
+- vcc->vpi = vpi;
+- vcc->vci = vci;
+-
+- if ((vci == ATM_VCI_UNSPEC) || (vpi == ATM_VCI_UNSPEC))
++ if ((vcc->vci == ATM_VCI_UNSPEC) || (vcc->vpi == ATM_VCI_UNSPEC))
+ {
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+ return -EBUSY;
+ }
+
+- tn7atm_activate_vc_parm.vpi = vpi;
+- tn7atm_activate_vc_parm.vci = vci;
++ tn7atm_activate_vc_parm.vpi = vcc->vpi;
++ tn7atm_activate_vc_parm.vci = vcc->vci;
+
+- if ((vpi == CLEAR_EOC_VPI) && (vci == CLEAR_EOC_VCI))
++ if ((vcc->vpi == CLEAR_EOC_VPI) && (vcc->vci == CLEAR_EOC_VCI))
+ {
+ /* always use (max_dma_chan+1) for clear eoc */
+ tn7atm_activate_vc_parm.chan = EOC_DMA_CHAN;
+@@ -999,7 +949,7 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ /* check to see whether clear eoc is opened or not */
+ if (tn7atm_activate_vc_parm.priv->lut[tn7atm_activate_vc_parm.chan].inuse)
+ {
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+ printk("tn7atm_open: Clear EOC channel (dmachan=%d) already in use.\n", tn7atm_activate_vc_parm.chan);
+ return -EBUSY;
+ }
+@@ -1008,7 +958,7 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ if (rc)
+ {
+ printk("tn7atm_open: failed to setup clear_eoc\n");
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+ return -EBUSY;
+ }
+ tn7atm_set_lut(tn7atm_activate_vc_parm.priv,vcc, tn7atm_activate_vc_parm.chan);
+@@ -1017,17 +967,17 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ }
+ else /* PVC channel setup */
+ {
+- if ((vpi==REMOTE_MGMT_VPI) && (vci==REMOTE_MGMT_VCI))
++ if ((vcc->vpi==REMOTE_MGMT_VPI) && (vcc->vci==REMOTE_MGMT_VCI))
+ {
+ tn7atm_activate_vc_parm.chan = 14; /* always use chan 14 for MII PVC-base romote mgmt */
+ }
+ else
+ {
+- rc = tn7atm_lut_find(vpi, vci);
++ rc = tn7atm_lut_find(vcc->vpi, vcc->vci);
+ /* check to see whether PVC is opened or not */
+ if(ATM_NO_DMA_CHAN != rc)
+ {
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+ printk("PVC already opened. dmachan = %d\n", rc);
+ return -EBUSY;
+ }
+@@ -1059,6 +1009,7 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ tn7atm_activate_vc_parm.priority = 2;
+ break;
+
++#if 0
+ case ATM_VBR: /* Variable Bit Rate-Non RealTime*/
+ tn7atm_activate_vc_parm.qos = 1;
+ tn7atm_activate_vc_parm.priority = 1;
+@@ -1080,6 +1031,7 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ tn7atm_activate_vc_parm.mbs = vcc->qos.txtp.max_pcr;
+ tn7atm_activate_vc_parm.cdvt = vcc->qos.txtp.max_cdv;
+ break;
++#endif
+
+ default:
+ tn7atm_activate_vc_parm.qos = 2;
+@@ -1107,7 +1059,7 @@ int tn7atm_open (struct atm_vcc *vcc, sh
+ if (rc < 0)
+ {
+ printk("failed to activate hw channel\n");
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+ tn7atm_lut_clear(vcc, tn7atm_activate_vc_parm.chan);
+ //spin_unlock_irqrestore(&chan_init_lock, flags);
+ return -EBUSY;
+@@ -1197,7 +1149,7 @@ void tn7atm_close (struct atm_vcc *vcc)
+ tn7atm_lut_clear (vcc, dmachan);
+ //spin_unlock_irqrestore (&closeLock, closeFlag);
+
+- MOD_DEC_USE_COUNT;
++// MOD_DEC_USE_COUNT;
+
+ dgprintf (1, "Leave tn7atm_close\n");
+ }
+@@ -1630,8 +1582,7 @@ int tn7atm_receive (void *os_dev, int ch
+ * firewall is on */
+
+ dgprintf (3, "pushing the skb...\n");
+-
+- skb->stamp = vcc->timestamp = xtime;
++ __net_timestamp(skb);
+
+ xdump ((unsigned char *) skb->data, skb->len, 5);
+
+@@ -1854,8 +1805,7 @@ printk("!!!free atm irq: tn7atm_exit\n")
+
+ kfree (dev->dev_data);
+
+- // atm_dev_deregister (dev);
+- shutdown_atm_dev (dev);
++ atm_dev_deregister (dev);
+
+ /*
+ * remove proc entries
+@@ -2086,9 +2036,6 @@ static int __init tn7atm_detect (void)
+ * Set up proc entry for atm stats
+ */
+
+- if (tn7atm_xlate_proc_name
+- (drv_proc_root_folder, &root_proc_dir_entry, &residual))
+- {
+ printk ("Creating new root folder %s in the proc for the driver stats \n",
+ drv_proc_root_folder);
+ root_proc_dir_entry = proc_mkdir (drv_proc_root_folder, NULL);
+@@ -2098,7 +2045,6 @@ static int __init tn7atm_detect (void)
+ return -ENOMEM;
+ }
+ proc_root_already_exists = FALSE;
+- }
+
+
+ /*
+@@ -2731,7 +2677,5 @@ int tn7atm_proc_turbodsl_write(struct fi
+ return count;
+ }
+
+-#ifdef MODULE
+ module_init (tn7atm_detect);
+ module_exit (tn7atm_exit);
+-#endif /* MODULE */
+--- a/tn7atm.h
++++ b/tn7atm.h
+@@ -20,7 +20,8 @@
+ //#include "mips_support.h"
+ #include <linux/list.h>
+
+-#include <linux/config.h>
++#define MIPS_EXCEPTION_OFFSET 8
++#define LNXINTNUM(x)((x) + MIPS_EXCEPTION_OFFSET)
+
+ #ifdef CONFIG_MODVERSIONS
+ #include <linux/modversions.h>
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -102,7 +102,6 @@
+ * UR8_MERGE_END CQ11813
+ * 09/18/07 CPH CQ11466: Added EFM support.
+ *********************************************************************************************/
+-#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -110,8 +109,6 @@
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+ #include <linux/smp_lock.h>
+-#include <asm/io.h>
+-#include <asm/mips-boards/prom.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
+@@ -119,6 +116,12 @@
+ #include <linux/timer.h>
+ #include <linux/vmalloc.h>
+ #include <linux/file.h>
++#include <linux/firmware.h>
++
++#include <asm/io.h>
++#include <asm/ar7/ar7.h>
++#include <asm/ar7/prom.h>
++
+ /* Modules specific header files */
+ #ifdef AR7_EFM
+ #include "tn7efm.h"
+@@ -185,7 +188,7 @@ led_reg_t ledreg[2];
+ static struct led_funcs ledreg[2];
+ #endif
+
+-#define DEV_DSLMOD 1
++#define DEV_DSLMOD CTL_UNNUMBERED
+ #define MAX_STR_SIZE 256
+ #define DSL_MOD_SIZE 256
+
+@@ -316,7 +319,7 @@ static PITIDSLHW_T pIhw;
+ static volatile int bshutdown;
+ static char info[MAX_STR_SIZE];
+ /* Used for DSL Polling enable */
+-static DECLARE_MUTEX_LOCKED (adsl_sem_overlay);
++static struct semaphore adsl_sem_overlay;
+
+ //kthread_t overlay_thread;
+ /* end of module wide declars */
+@@ -369,6 +372,14 @@ int os_atoih (const char *pstr)
+ return val;
+ }
+
++int avalanche_request_intr_pacing(int irq_nr, unsigned int blk_num,
++ unsigned int pace_value)
++{
++ printk("avalanche_request_pacing(%d, %u, %u); // not implemented\n", irq_nr, blk_num, pace_value);
++ return 0;
++}
++
++
+ int os_atoi(const char *pStr)
+ {
+ int MulNeg = (*pStr == '-' ? -1 : 1);
+@@ -405,39 +416,6 @@ void dprintf (int uDbgLevel, char *szFmt
+ #endif
+ }
+
+-int strcmp(const char *s1, const char *s2)
+-{
+-
+- int size = strlen(s1);
+-
+- return(strncmp(s1, s2, size));
+-}
+-
+-int strncmp(const char *s1, const char *s2, size_t size)
+-{
+- int i = 0;
+- int max_size = (int)size;
+-
+- while((s1[i] != 0) && i < max_size)
+- {
+- if(s2[i] == 0)
+- {
+- return -1;
+- }
+- if(s1[i] != s2[i])
+- {
+- return 1;
+- }
+- i++;
+- }
+- if(s2[i] != 0)
+- {
+- return 1;
+- }
+-
+- return 0;
+-}
+-
+ // * UR8_MERGE_START CQ10640 Jack Zhang
+ int tn7dsl_dump_dsp_memory(char *input_str) //cph99
+ {
+@@ -487,144 +465,78 @@ unsigned int shim_osGetCpuFrequency(void
+ return CpuFrequency;
+ }
+
+-int shim_osLoadFWImage(unsigned char *ptr)
++static void avsar_release(struct device *dev)
+ {
+- unsigned int bytesRead;
+- mm_segment_t oldfs;
+- static struct file *filp;
+- unsigned int imageLength=0x5ffff;
+-
+-#ifdef AR7_EFM
+- int dp_alt=0;
+- char *ptr1=NULL;
+-#ifdef EFM_DEBUG
+- char *ptr2=NULL;
+- char *ptr3=NULL;
+-#endif
+-
+- if ((ptr1 = prom_getenv("DSL_DP_ALT")) != NULL)
+- {
+- dp_alt=os_atoi(ptr1);
+- if (dp_alt==1)
+- {
+- filp = filp_open(DSP_DEBUG_FIRMWARE_PATH,00,O_RDONLY);
+- if (!IS_ERR(filp))
+- {
+- strcpy (DSP_FIRMWARE_PATH, DSP_DEBUG_FIRMWARE_PATH);
+- }
+- }
+-#ifdef EFM_DEBUG
+- else if (dp_alt==2)
+- {
+- if ((ptr2 = prom_getenv("DSL_DP")) != NULL)
+- {
+- if (!strncmp(ptr2, "DSL_DP", 6))
+- { // indirect naming
+- if ((ptr3 = prom_getenv(ptr2)) != NULL)
+- filp = filp_open(ptr3,00,O_RDONLY);
+- ptr2 = ptr3; // redirect ptr2 to ptr3
+- }
+-
+- filp = filp_open(ptr2,00,O_RDONLY);
+- if (!IS_ERR(filp))
+- {
+- strcpy (DSP_FIRMWARE_PATH, ptr2);
+- }
+- }
+- }
+- printk("dp_path=%s\n", DSP_FIRMWARE_PATH);
+-#endif
+- }
+-#endif
+-
+- dgprintf(4, "tn7dsl_read_dsp()\n");
+-
+- dgprintf(4,"open file %s\n", DSP_FIRMWARE_PATH);
+-
+- filp=filp_open(DSP_FIRMWARE_PATH,00,O_RDONLY);
+- if(IS_ERR(filp))
+- {
+- printk("Failed: Could not open DSP binary file\n");
+- return -1;
+- }
+-
+- if (filp->f_dentry != NULL)
+- {
+- if (filp->f_dentry->d_inode != NULL)
+- {
+- printk ("DSP binary filesize = %d bytes\n",
+- (int) filp->f_dentry->d_inode->i_size);
+- imageLength = (unsigned int)filp->f_dentry->d_inode->i_size + 0x200;
+- }
+- }
+-
+- if (filp->f_op->read==NULL)
+- return -1; /* File(system) doesn't allow reads */
+-
+- /*
+- * Disable parameter checking
+- */
+- oldfs = get_fs();
+- set_fs(KERNEL_DS);
+-
+- /*
+- * Now read bytes from postion "StartPos"
+- */
+- filp->f_pos = 0;
+-
+- bytesRead = filp->f_op->read(filp,ptr,imageLength,&filp->f_pos);
+-
+- dgprintf(4,"file length = %d\n", bytesRead);
+-
+- set_fs(oldfs);
+-
+- /*
+- * Close the file
+- */
+- fput(filp);
+-
+- return bytesRead;
++ printk(KERN_DEBUG "avsar firmware released\n");
+ }
+
++static struct device avsar = {
++ .bus_id = "vlynq",
++ .release = avsar_release,
++};
+
+-unsigned int shim_read_overlay_page (void *ptr, unsigned int secOffset,
+- unsigned int secLength)
++int shim_osLoadFWImage(unsigned char *ptr)
+ {
+- unsigned int bytesRead;
+- mm_segment_t oldfs;
+- struct file *filp;
+-
+- dgprintf(4,"shim_read_overlay_page\n");
+- //dgprintf(4,"sec offset=%d, sec length =%d\n", secOffset, secLength);
++ const struct firmware *fw_entry;
++ size_t size;
+
+- filp=filp_open(DSP_FIRMWARE_PATH,00,O_RDONLY);
+- if(filp ==NULL)
+- {
+- printk("Failed: Could not open DSP binary file\n");
+- return -1;
+- }
+-
+- if (filp->f_op->read==NULL)
+- return -1; /* File(system) doesn't allow reads */
+-
+- /*
+- * Now read bytes from postion "StartPos"
+- */
++ printk("requesting firmware image \"ar0700xx.bin\"\n");
++ if(device_register(&avsar) < 0) {
++ printk(KERN_ERR
++ "avsar: device_register fails\n");
++ return -1;
++ }
++
++ if (request_firmware(&fw_entry, "ar0700xx.bin", &avsar)) {
++ printk(KERN_ERR
++ "avsar: Firmware not available\n");
++ device_unregister(&avsar);
++ return -1;
++ }
++ size = fw_entry->size;
++ device_unregister(&avsar);
++ if (size > 0x6ffff) {
++ printk(KERN_ERR
++ "avsar: Firmware too big (%d bytes)\n", size);
++ release_firmware(fw_entry);
++ return -1;
++ }
++ memcpy(ptr, fw_entry->data, size);
++ release_firmware(fw_entry);
++ return size;
++}
++
++unsigned int shim_read_overlay_page(void *ptr, unsigned int secOffset, unsigned int secLength)
++{
++ const struct firmware *fw_entry;
++
++ printk("requesting firmware image \"ar0700xx.bin\"\n");
++ if (device_register(&avsar) < 0) {
++ printk(KERN_ERR
++ "avsar: device_register fails\n");
++ return -1;
++ }
++
++ if (request_firmware(&fw_entry, "ar0700xx.bin", &avsar)) {
++ printk(KERN_ERR
++ "avsar: Firmware not available\n");
++ device_unregister(&avsar);
++ return -1;
++ }
++
++ device_unregister(&avsar);
++ if (fw_entry->size > secLength) {
++ printk(KERN_ERR
++ "avsar: Firmware too big (%d bytes)\n", fw_entry->size);
++ release_firmware(fw_entry);
++ return -1;
++ }
++ memcpy(ptr + secOffset, fw_entry->data, secLength);
++ release_firmware(fw_entry);
++ return secLength;
++}
+
+- if(filp->f_op->llseek)
+- filp->f_op->llseek(filp,secOffset, 0);
+- oldfs = get_fs();
+- set_fs(KERNEL_DS);
+- filp->f_pos = secOffset;
+- bytesRead = filp->f_op->read(filp,ptr,secLength,&filp->f_pos);
+
+- set_fs(oldfs);
+- /*
+- * Close the file
+- */
+- fput(filp);
+- return bytesRead;
+-}
+
+ int shim_osLoadDebugFWImage(unsigned char *ptr)
+ {
+@@ -3287,6 +3199,7 @@ int tn7dsl_init(void *priv)
+ int high_precision_selected = 0;
+ // UR8_MERGE_END CQ11054*
+
++ sema_init(&adsl_sem_overlay, 0);
+ /*
+ * start dsl
+ */
+@@ -3665,7 +3578,7 @@ static int dslmod_sysctl(ctl_table *ctl,
+ */
+ if(write)
+ {
+- ret = proc_dostring(ctl, write, filp, buffer, lenp);
++ ret = proc_dostring(ctl, write, filp, buffer, lenp, 0);
+
+ switch (ctl->ctl_name)
+ {
+@@ -3751,14 +3664,14 @@ static int dslmod_sysctl(ctl_table *ctl,
+ else
+ {
+ len += sprintf(info+len, mod_req);
+- ret = proc_dostring(ctl, write, filp, buffer, lenp);
++ ret = proc_dostring(ctl, write, filp, buffer, lenp, 0);
+ }
+ return ret;
+ }
+
+
+ ctl_table dslmod_table[] = {
+- {DEV_DSLMOD, "dslmod", info, DSL_MOD_SIZE, 0644, NULL, &dslmod_sysctl}
++ {DEV_DSLMOD, "dslmod", info, DSL_MOD_SIZE, 0644, NULL, NULL, &dslmod_sysctl, &sysctl_string}
+ ,
+ {0}
+ };
+@@ -3781,8 +3694,7 @@ void tn7dsl_dslmod_sysctl_register(void)
+ if (initialized == 1)
+ return;
+
+- dslmod_sysctl_header = register_sysctl_table(dslmod_root_table, 1);
+- dslmod_root_table->child->de->owner = THIS_MODULE;
++ dslmod_sysctl_header = register_sysctl_table(dslmod_root_table);
+
+ /*
+ * set the defaults
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -43,7 +43,6 @@
+ * 09/18/07 CPH CQ11466: Added EFM support.
+ *******************************************************************************/
+
+-#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -51,12 +50,13 @@
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+ #include <linux/smp_lock.h>
+-#include <asm/io.h>
+-#include <asm/mips-boards/prom.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
+
++#include <asm/io.h>
++#include <asm/ar7/ar7.h>
++#include <asm/ar7/prom.h>
+
+ #define _CPHAL_AAL5
+ #define _CPHAL_SAR
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/110-interrupt_fix.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/110-interrupt_fix.patch
new file mode 100644
index 0000000000..1122457691
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/110-interrupt_fix.patch
@@ -0,0 +1,37 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -633,7 +633,7 @@ static int turbodsl_check_priority_type(
+ * Description: tnetd73xx SAR interrupt.
+ *
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+-static void tn7atm_sar_irq (int irq, void *voiddev, struct pt_regs *regs)
++static irqreturn_t tn7atm_sar_irq (int irq, void *voiddev)
+ {
+ struct atm_dev *atmdev;
+ Tn7AtmPrivate *priv;
+@@ -660,6 +660,7 @@ static void tn7atm_sar_irq (int irq, voi
+ #ifdef TIATM_INST_SUPP
+ psp_trace_par (ATM_DRV_SAR_ISR_EXIT, retval);
+ #endif
++ return IRQ_HANDLED;
+ }
+
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+@@ -669,7 +670,7 @@ static void tn7atm_sar_irq (int irq, voi
+ * Description: tnetd73xx DSL interrupt.
+ *
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+-static void tn7atm_dsl_irq (int irq, void *voiddev, struct pt_regs *regs)
++static irqreturn_t tn7atm_dsl_irq (int irq, void *voiddev)
+ {
+ struct atm_dev *atmdev;
+ Tn7AtmPrivate *priv;
+@@ -691,6 +692,8 @@ static void tn7atm_dsl_irq (int irq, voi
+ #ifdef TIATM_INST_SUPP
+ psp_trace_par (ATM_DRV_DSL_ISR_EXIT, retval);
+ #endif
++
++ return IRQ_HANDLED;
+ }
+
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/120-no_dumb_inline.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/120-no_dumb_inline.patch
new file mode 100644
index 0000000000..e9d99dff42
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/120-no_dumb_inline.patch
@@ -0,0 +1,11 @@
+--- a/tn7api.h
++++ b/tn7api.h
+@@ -118,7 +118,7 @@ int tn7dsl_proc_dbgmsg_write(struct file
+ int tn7dsl_proc_dbgmsg_read(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+ #endif
+ //UR8_MERGE_END CQ11813
+-inline int tn7dsl_handle_interrupt(void);
++int tn7dsl_handle_interrupt(void);
+
+ void tn7dsl_dslmod_sysctl_register(void);
+ void tn7dsl_dslmod_sysctl_unregister(void);
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/130-powercutback.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/130-powercutback.patch
new file mode 100644
index 0000000000..415486482e
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/130-powercutback.patch
@@ -0,0 +1,44 @@
+--- a/dsl_hal_advcfg.c
++++ b/dsl_hal_advcfg.c
+@@ -36,9 +36,9 @@
+ * 05Jul05 0.00.09 CPH CQ9775: Change dslhal_advcfg_configDsTones input parameters & support for ADSL2+
+ * 24Jul05 0.00.10 CPH Fixed comments in dslhal_advcfg_configDsTones function header
+ *******************************************************************************/
+-#include <dev_host_interface.h>
+-#include <dsl_hal_register.h>
+-#include <dsl_hal_support.h>
++#include "dev_host_interface.h"
++#include "dsl_hal_register.h"
++#include "dsl_hal_support.h"
+
+ /*****************************************************************************/
+ /* ACT API functions -- To be moved into their own independent module --RamP */
+--- a/Makefile
++++ b/Makefile
+@@ -4,6 +4,7 @@
+
+ CONFIG_SANGAM_ATM=m
+ #EXTRA_CFLAGS += -DEL -I. -DPOST_SILICON -DCOMMON_NSP -DCONFIG_LED_MODULE -DDEREGISTER_LED -DNO_ACT
+-EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -DNO_ACT -D__NO__VOICE_PATCH__ -DEL
++#EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -DNO_ACT -D__NO__VOICE_PATCH__ -DEL
++EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -D__NO__VOICE_PATCH__ -DEL
+ obj-$(CONFIG_SANGAM_ATM) := tiatm.o
+-tiatm-objs += cpsar.o aal5sar.o tn7sar.o tn7atm.o tn7dsl.o dsl_hal_api.o dsl_hal_support.o
++tiatm-objs += cpsar.o aal5sar.o tn7sar.o tn7atm.o tn7dsl.o dsl_hal_api.o dsl_hal_support.o dsl_hal_advcfg.o
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -3053,6 +3053,14 @@ static int tn7dsl_set_dsl(void)
+ dslhal_api_setRateAdaptFlag(pIhw, os_atoi(ptr));
+ }
+
++ // set powercutback
++ ptr = NULL;
++ ptr = prom_getenv("powercutback");
++ if(ptr)
++ {
++ dslhal_advcfg_onOffPcb(pIhw, os_atoi(ptr));
++ }
++
+ // trellis
+ ptr = NULL;
+ ptr = prom_getenv("trellis");
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/140-debug_mode.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/140-debug_mode.patch
new file mode 100644
index 0000000000..3873827afc
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/140-debug_mode.patch
@@ -0,0 +1,16 @@
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -125,10 +125,10 @@ enum
+ //09/05/07: cph, move to tn7atm.h
+ // #define RESERVED_OAM_CHANNEL 15
+
+-#define AAL5_PARM "id=aal5, base = 0x03000000, offset = 0, int_line=15, ch0=[RxBufSize=1522; RxNumBuffers = 32; RxServiceMax = 50; TxServiceMax=50; TxNumBuffers=32; CpcsUU=0x5aa5; TxVc_CellRate=0x3000; TxVc_AtmHeader=0x00000640]"
+-#define SAR_PARM "id=sar,base = 0x03000000, reset_bit = 9, offset = 0; UniNni = 0, PdspEnable = 1"
++#define CH0_PARM "RxBufSize=1522, RxNumBuffers=32, RxServiceMax=50, TxServiceMax=50, TxNumBuffers=32, CpcsUU=0x5aa5, TxVc_CellRate=0x3000, TxVc_AtmHeader=0x00000640"
++#define AAL5_PARM "id=aal5, base=0x03000000, offset=0, int_line=15, ch0=[" CH0_PARM "]"
++#define SAR_PARM "id=sar, base=0x03000000, reset_bit=9, offset=0; UniNni=0, PdspEnable=1, Debug=0xFFFFFFFF"
+ #define RESET_PARM "id=ResetControl, base=0xA8611600"
+-#define CH0_PARM "RxBufSize=1522, RxNumBuffers = 32, RxServiceMax = 50, TxServiceMax=50, TxNumBuffers=32, CpcsUU=0x5aa5, TxVc_CellRate=0x3000, TxVc_AtmHeader=0x00000640"
+
+ #define MAX_PVC_TABLE_ENTRY 16
+
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/150-tasklet_mode.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/150-tasklet_mode.patch
new file mode 100644
index 0000000000..97b8cecdd9
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/150-tasklet_mode.patch
@@ -0,0 +1,11 @@
+--- a/Makefile
++++ b/Makefile
+@@ -5,6 +5,7 @@
+ CONFIG_SANGAM_ATM=m
+ #EXTRA_CFLAGS += -DEL -I. -DPOST_SILICON -DCOMMON_NSP -DCONFIG_LED_MODULE -DDEREGISTER_LED -DNO_ACT
+ #EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -DNO_ACT -D__NO__VOICE_PATCH__ -DEL
+-EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -D__NO__VOICE_PATCH__ -DEL
++#EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -D__NO__VOICE_PATCH__ -DEL
++EXTRA_CFLAGS += -DEL -I$(PWD) -DPOST_SILICON -DCOMMON_NSP -D__NO__VOICE_PATCH__ -DEL -DCPATM_TASKLET_MODE
+ obj-$(CONFIG_SANGAM_ATM) := tiatm.o
+ tiatm-objs += cpsar.o aal5sar.o tn7sar.o tn7atm.o tn7dsl.o dsl_hal_api.o dsl_hal_support.o dsl_hal_advcfg.o
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/160-module-params.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/160-module-params.patch
new file mode 100644
index 0000000000..75a41d1e36
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/160-module-params.patch
@@ -0,0 +1,675 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -95,6 +95,146 @@
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION ("Tnetd73xx ATM Device Driver");
+ MODULE_AUTHOR ("Zhicheng Tang");
++
++int mp_sar_ipacemax = -1;
++module_param_named(ipacemax, mp_sar_ipacemax, int, 0);
++MODULE_PARM_DESC(ipacemax, "Interrupt pacing");
++
++char *mp_macc = NULL;
++module_param_named(macc, mp_macc, charp, 0);
++MODULE_PARM_DESC(macc, "MAC address");
++
++int mp_dsp_noboost = -1;
++module_param_named(dsp_noboost, mp_dsp_noboost, int, 0);
++MODULE_PARM_DESC(dsp_noboost, "Suppress DSP frequency boost");
++
++int mp_dsp_freq = -1;
++module_param_named(dsp_freq, mp_dsp_freq, int, 0);
++MODULE_PARM_DESC(dsp_freq, "Frequency to boost the DSP to");
++
++char *mp_featctl0 = NULL;
++module_param_named(featctl0, mp_featctl0, charp, 0);
++MODULE_PARM_DESC(featctl0, "DSL feature control 0");
++
++char *mp_featctl1 = NULL;
++module_param_named(featctl1, mp_featctl1, charp, 0);
++MODULE_PARM_DESC(featctl1, "DSL feature control 1");
++
++char *mp_phyctl0 = NULL;
++module_param_named(phyctl0, mp_phyctl0, charp, 0);
++MODULE_PARM_DESC(phyctl0, "DSL PHY control 0");
++
++char *mp_phyctl1 = NULL;
++module_param_named(phyctl1, mp_phyctl1, charp, 0);
++MODULE_PARM_DESC(phyctl1, "DSL PHY control 1");
++
++int mp_turbodsl = -1;
++module_param_named(turbodsl, mp_turbodsl, int, 0);
++MODULE_PARM_DESC(turbodsl, "Enable TurboDSL");
++
++int mp_sar_rxbuf = -1;
++module_param_named(sar_rxbuf, mp_sar_rxbuf, int, 0);
++MODULE_PARM_DESC(sar_rxbuf, "SAR RxBuf size");
++
++int mp_sar_rxmax = -1;
++module_param_named(sar_rxmax, mp_sar_rxmax, int, 0);
++MODULE_PARM_DESC(sar_rxmax, "SAR RxMax size");
++
++int mp_sar_txbuf = -1;
++module_param_named(sar_txbuf, mp_sar_txbuf, int, 0);
++MODULE_PARM_DESC(sar_txbuf, "SAR TxBuf size");
++
++int mp_sar_txmax = -1;
++module_param_named(sar_txmax, mp_sar_txmax, int, 0);
++MODULE_PARM_DESC(sar_txmax, "SAR TxMax size");
++
++char *mp_modulation = NULL;
++module_param_named(modulation, mp_modulation, charp, 0);
++MODULE_PARM_DESC(modulation, "Modulation");
++
++int mp_fine_gain_control = -1;
++module_param_named(fine_gain_control, mp_fine_gain_control, int, 0);
++MODULE_PARM_DESC(fine_gain_control, "Fine gain control");
++
++int mp_fine_gain_value = -1;
++module_param_named(fine_gain_value, mp_fine_gain_value, int, 0);
++MODULE_PARM_DESC(fine_gain_value, "Fine gain value");
++
++int mp_enable_margin_retrain = -1;
++module_param_named(enable_margin_retrain, mp_enable_margin_retrain, int, 0);
++MODULE_PARM_DESC(enable_margin_retrain, "Enable margin retrain");
++
++int mp_margin_threshold = -1;
++module_param_named(margin_threshold, mp_margin_threshold, int, 0);
++MODULE_PARM_DESC(margin_threshold, "Margin retrain treshold");
++
++int mp_enable_rate_adapt = -1;
++module_param_named(enable_rate_adapt, mp_enable_rate_adapt, int, 0);
++MODULE_PARM_DESC(enable_rate_adapt, "Enable rate adaption");
++
++int mp_powercutback = -1;
++module_param_named(powercutback, mp_powercutback, int, 0);
++MODULE_PARM_DESC(powercutback, "Enable / disable powercutback");
++
++int mp_trellis = -1;
++module_param_named(trellis, mp_trellis, int, 0);
++MODULE_PARM_DESC(trellis, "Enable / disable trellis coding");
++
++int mp_bitswap = -1;
++module_param_named(bitswap, mp_bitswap, int, 0);
++MODULE_PARM_DESC(bitswap, "Enable / disable bitswap");
++
++int mp_maximum_bits_per_carrier = -1;
++module_param_named(maximum_bits_per_carrier, mp_maximum_bits_per_carrier, int, 0);
++MODULE_PARM_DESC(maximum_bits_per_carrier, "Maximum bits per carrier");
++
++int mp_maximum_interleave_depth = -1;
++module_param_named(maximum_interleave_depth, mp_maximum_interleave_depth, int, 0);
++MODULE_PARM_DESC(maximum_interleave_depth, "Maximum interleave depth");
++
++int mp_pair_selection = -1;
++module_param_named(pair_selection, mp_pair_selection, int, 0);
++MODULE_PARM_DESC(pair_selection, "Pair selection");
++
++int mp_dgas_polarity = -1;
++module_param_named(dgas_polarity, mp_dgas_polarity, int, 0);
++MODULE_PARM_DESC(dgas_polarity, "DGAS polarity");
++
++int mp_los_alarm = -1;
++module_param_named(los_alarm, mp_los_alarm, int, 0);
++MODULE_PARM_DESC(los_alarm, "LOS alarm");
++
++char *mp_eoc_vendor_id = NULL;
++module_param_named(eoc_vendor_id, mp_eoc_vendor_id, charp, 0);
++MODULE_PARM_DESC(eoc_vendor_id, "EOC vendor id");
++
++int mp_eoc_vendor_revision = -1;
++module_param_named(eoc_vendor_revision, mp_eoc_vendor_revision, int, 0);
++MODULE_PARM_DESC(eoc_vendor_revision, "EOC vendor revision");
++
++char *mp_eoc_vendor_serialnum = NULL;
++module_param_named(eoc_vendor_serialnum, mp_eoc_vendor_serialnum, charp, 0);
++MODULE_PARM_DESC(eoc_vendor_serialnum, "EOC vendor serial number");
++
++char *mp_invntry_vernum = NULL;
++module_param_named(invntry_vernum, mp_invntry_vernum, charp, 0);
++MODULE_PARM_DESC(invntry_vernum, "Inventory revision number");
++
++int mp_dsl_bit_tmode = -1;
++module_param_named(dsl_bit_tmode, mp_dsl_bit_tmode, int, 0);
++MODULE_PARM_DESC(dsl_bit_tmode, "DSL bit training mode");
++
++int mp_high_precision = -1;
++module_param_named(high_precision, mp_high_precision, int, 0);
++MODULE_PARM_DESC(high_precision, "High precision");
++
++int mp_autopvc_enable = -1;
++module_param_named(autopvc_enable, mp_autopvc_enable, int, 0);
++MODULE_PARM_DESC(autopvc_enable, "Enable / disable automatic PVC");
++
++int mp_oam_lb_timeout = -1;
++module_param_named(oam_lb_timeout, mp_oam_lb_timeout, int, 0);
++MODULE_PARM_DESC(oam_lb_timeout, "OAM LB timeout");
+ #endif
+
+ #ifndef TRUE
+@@ -728,9 +868,9 @@
+ * interrupt pacing
+ */
+ ptr = prom_getenv ("sar_ipacemax");
+- if (ptr)
++ if (ptr || mp_sar_ipacemax != -1)
+ {
+- def_sar_inter_pace = os_atoi (ptr);
++ def_sar_inter_pace = mp_sar_ipacemax == -1 ? os_atoi (ptr) : mp_sar_ipacemax;
+ }
+ /* avalanche_request_pacing (priv->sar_irq, ATM_SAR_INT_PACING_BLOCK_NUM,
+ def_sar_inter_pace); */
+@@ -878,9 +1018,18 @@
+ {
+ int i;
+ char esi_addr[ESI_LEN] = { 0x00, 0x00, 0x11, 0x22, 0x33, 0x44 };
+- char *esiaddr_str = NULL;
++ char *esiaddr_str = mp_macc;
+
+- esiaddr_str = prom_getenv ("macc");
++ if (esiaddr_str == NULL)
++ esiaddr_str = prom_getenv ("macdsl");
++ if (esiaddr_str == NULL)
++ esiaddr_str = prom_getenv ("macc");
++ if (esiaddr_str == NULL)
++ esiaddr_str = prom_getenv ("HWA_1");
++ if (esiaddr_str == NULL)
++ esiaddr_str = prom_getenv ("macb");
++ if (esiaddr_str == NULL)
++ esiaddr_str = prom_getenv ("maca");
+
+ if (!esiaddr_str)
+ {
+@@ -2139,15 +2288,15 @@
+ //UR8_MERGE_END CQ10450*
+
+ cp = prom_getenv ("dsp_noboost");
+- if (cp)
++ if (cp || mp_dsp_noboost != -1)
+ {
+- dsp_noboost = os_atoi (cp);
++ dsp_noboost = mp_dsp_noboost == -1 ? os_atoi (cp) : mp_dsp_noboost;
+ }
+
+ cp = (char *) prom_getenv ("dsp_freq");
+- if (cp)
++ if (cp || mp_dsp_freq != -1)
+ {
+- dspfreq = os_atoi (cp);
++ dspfreq = mp_dsp_freq == -1 ? os_atoi (cp) : mp_dsp_freq;
+ if (dspfreq == 250)
+ {
+ boostDsp = 1;
+@@ -2396,15 +2545,17 @@
+ // Inter-Op DSL phy Control
+ // Note the setting of _dsl_Feature_0 and _dsl_Feature_1 must before
+ // dslhal_api_dslStartup (in tn7dsl_init()).
+- if ((ptr = prom_getenv ("DSL_FEATURE_CNTL_0")) != NULL)
++ if ((ptr = prom_getenv ("DSL_FEATURE_CNTL_0")) != NULL || mp_featctl0 != NULL)
+ {
+- _dsl_Feature_0 = os_atoih (ptr);
++ if (mp_featctl0 != NULL) ptr = mp_featctl0;
++ _dsl_Feature_0 = os_atoh (ptr);
+ _dsl_Feature_0_defined = 1;
+ }
+
+- if ((ptr = prom_getenv ("DSL_FEATURE_CNTL_1")) != NULL)
++ if ((ptr = prom_getenv ("DSL_FEATURE_CNTL_1")) != NULL || mp_featctl1 != NULL)
+ {
+- _dsl_Feature_1 = os_atoih (ptr);
++ if (mp_featctl1 != NULL) ptr = mp_featctl1;
++ _dsl_Feature_1 = os_atoh (ptr);
+ _dsl_Feature_1_defined = 1;
+ }
+
+@@ -2412,15 +2563,17 @@
+ // DSL phy Feature Control
+ // Note the setting of _dsl_PhyControl_0 and _dsl_PhyControl_1 must before
+ // dslhal_api_dslStartup (in tn7dsl_init()).
+- if ((ptr = prom_getenv ("DSL_PHY_CNTL_0")) != NULL)
++ if ((ptr = prom_getenv ("DSL_PHY_CNTL_0")) != NULL || mp_phyctl0 != NULL)
+ {
+- _dsl_PhyControl_0 = os_atoih (ptr);
++ if (mp_phyctl0 != NULL) ptr = mp_phyctl0;
++ _dsl_PhyControl_0 = os_atoh (ptr);
+ _dsl_PhyControl_0_defined = 1;
+ }
+
+- if ((ptr = prom_getenv ("DSL_PHY_CNTL_1")) != NULL)
++ if ((ptr = prom_getenv ("DSL_PHY_CNTL_1")) != NULL || mp_phyctl1 != NULL)
+ {
+- _dsl_PhyControl_1 = os_atoih (ptr);
++ if (mp_phyctl1 != NULL) ptr = mp_phyctl1;
++ _dsl_PhyControl_1 = os_atoh (ptr);
+ _dsl_PhyControl_1_defined = 1;
+ }
+
+@@ -2440,12 +2593,12 @@
+ // read config for turbo dsl
+
+ ptr = prom_getenv ("TurboDSL");
+- if (ptr)
++ if (ptr || mp_turbodsl != -1)
+ {
+ #if 1 //[KT]
+ bTurboDsl = os_atoi (ptr);
+ #else
+- priv->bTurboDsl = os_atoi (ptr);
++ priv->bTurboDsl = mp_turbodsl == -1 ? os_atoi (ptr) : mp_turbodsl;
+ #endif
+ }
+ else
+@@ -2459,33 +2612,33 @@
+ priv->sarRxBuf = RX_BUFFER_NUM;
+ ptr = NULL;
+ ptr = prom_getenv ("SarRxBuf");
+- if (ptr)
++ if (ptr || mp_sar_rxbuf != -1)
+ {
+- priv->sarRxBuf = os_atoi (ptr);
++ priv->sarRxBuf = mp_sar_rxbuf == -1 ? os_atoi (ptr) : mp_sar_rxbuf;
+ }
+
+ priv->sarRxMax = RX_SERVICE_MAX;
+ ptr = NULL;
+ ptr = prom_getenv ("SarRxMax");
+- if (ptr)
++ if (ptr || mp_sar_rxmax != -1)
+ {
+- priv->sarRxMax = os_atoi (ptr);
++ priv->sarRxMax = mp_sar_rxmax == -1 ? os_atoi (ptr) : mp_sar_rxmax;
+ }
+
+ priv->sarTxBuf = TX_BUFFER_NUM;
+ ptr = NULL;
+ ptr = prom_getenv ("SarTxBuf");
+- if (ptr)
++ if (ptr || mp_sar_txbuf != -1)
+ {
+- priv->sarTxBuf = os_atoi (ptr);
++ priv->sarTxBuf = mp_sar_txbuf == -1 ? os_atoi (ptr) : mp_sar_txbuf;
+ }
+
+ priv->sarTxMax = TX_SERVICE_MAX;
+ ptr = NULL;
+ ptr = prom_getenv ("SarTxMax");
+- if (ptr)
++ if (ptr || mp_sar_txmax != -1)
+ {
+- priv->sarTxMax = os_atoi (ptr);
++ priv->sarTxMax = mp_sar_txmax == -1 ? os_atoi (ptr) : mp_sar_txmax;
+ }
+
+ #ifdef AR7_EFM
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -148,6 +148,27 @@
+ #define NEW_TRAINING_VAL_T1413 128
+ #define NEW_TRAINING_VAL_MMODE 255
+
++extern char *mp_modulation;
++extern int mp_fine_gain_control;
++extern int mp_fine_gain_value;
++extern int mp_enable_margin_retrain;
++extern int mp_margin_threshold;
++extern int mp_enable_rate_adapt;
++extern int mp_powercutback;
++extern int mp_trellis;
++extern int mp_bitswap;
++extern int mp_maximum_bits_per_carrier;
++extern int mp_maximum_interleave_depth;
++extern int mp_pair_selection;
++extern int mp_dgas_polarity;
++extern int mp_los_alarm;
++extern char *mp_eoc_vendor_id;
++extern int mp_eoc_vendor_revision;
++extern char *mp_eoc_vendor_serialnum;
++extern char *mp_invntry_vernum;
++extern int mp_dsl_bit_tmode;
++extern int mp_high_precision;
++
+ int testflag1 = 0;
+ extern int __guDbgLevel;
+ extern sar_stat_t sarStat;
+@@ -2933,24 +2954,24 @@ static int tn7dsl_set_dsl(void)
+ (unsigned char *) &oamFeature, 4);
+
+ ptr = prom_getenv("DSL_FEATURE_CNTL_0");
+- if(!ptr)
+- prom_setenv("DSL_FEATURE_CNTL_0", "0x00004000");
++ //if(!ptr)
++ //prom_setenv("DSL_FEATURE_CNTL_0", "0x00004000");
+
+ ptr = prom_getenv("DSL_FEATURE_CNTL_1");
+- if(!ptr)
+- prom_setenv("DSL_FEATURE_CNTL_1", "0x00000000");
++ //if(!ptr)
++ //prom_setenv("DSL_FEATURE_CNTL_1", "0x00000000");
+
+ ptr = prom_getenv("DSL_PHY_CNTL_0");
+- if(!ptr)
+- prom_setenv("DSL_PHY_CNTL_0", "0x00000400");
++ //if(!ptr)
++ //prom_setenv("DSL_PHY_CNTL_0", "0x00000400");
+
+ ptr = prom_getenv("enable_margin_retrain");
+- if(!ptr)
+- prom_setenv("enable_margin_retrain", "0");
++ //if(!ptr)
++ //prom_setenv("enable_margin_retrain", "0");
+
+ ptr = prom_getenv("modulation");
+- if(!ptr)
+- prom_setenv("modulation", "0xbf");
++ //if(!ptr)
++ //prom_setenv("modulation", "0xbf");
+
+ #define EOC_VENDOR_ID "4200534153000000"
+ #define EOC_VENDOR_REVISION "FW370090708b1_55"
+@@ -2959,25 +2980,25 @@ static int tn7dsl_set_dsl(void)
+ ptr = prom_getenv("eoc_vendor_id");
+ if(!ptr || strcmp(ptr,EOC_VENDOR_ID) != 0 || strlen(ptr) != strlen(EOC_VENDOR_ID))
+ {
+- if(ptr)
+- prom_unsetenv("eoc_vendor_id");
+- prom_setenv("eoc_vendor_id",EOC_VENDOR_ID);
++ //if(ptr)
++ //prom_unsetenv("eoc_vendor_id");
++ //prom_setenv("eoc_vendor_id",EOC_VENDOR_ID);
+ }
+
+ ptr = prom_getenv("eoc_vendor_revision");
+ if(!ptr || strcmp(ptr,EOC_VENDOR_REVISION) != 0 || strlen(ptr) != strlen(EOC_VENDOR_REVISION))
+ {
+- if(ptr)
+- prom_unsetenv("eoc_vendor_revision");
+- prom_setenv("eoc_vendor_revision",EOC_VENDOR_REVISION);
++ //if(ptr)
++ //prom_unsetenv("eoc_vendor_revision");
++ //prom_setenv("eoc_vendor_revision",EOC_VENDOR_REVISION);
+ }
+
+ ptr = prom_getenv("eoc_vendor_serialnum");
+ if(!ptr || strcmp(ptr,EOC_VENDOR_SERIALNUM) != 0 || strlen(ptr) != strlen(EOC_VENDOR_SERIALNUM))
+ {
+- if(ptr)
+- prom_unsetenv("eoc_vendor_serialnum");
+- prom_setenv("eoc_vendor_serialnum",EOC_VENDOR_SERIALNUM);
++ //if(ptr)
++ // prom_unsetenv("eoc_vendor_serialnum");
++ //prom_setenv("eoc_vendor_serialnum",EOC_VENDOR_SERIALNUM);
+ }
+
+ /* Do only if we are in the new Base PSP 7.4.*/
+@@ -2994,92 +3015,88 @@ static int tn7dsl_set_dsl(void)
+ we clear the modulation environment variable, as this could potentially
+ not have the same meaning in the new mode.
+ */
+- prom_unsetenv("modulation");
+- prom_setenv("DSL_UPG_DONE", "1");
++ //prom_unsetenv("modulation");
++ //prom_setenv("DSL_UPG_DONE", "1");
+ }
+ }
+ #endif
+
+ // modulation
+ ptr = prom_getenv("modulation");
+- if (ptr)
++ if (ptr || mp_modulation != NULL)
+ {
+- tn7dsl_set_modulation(ptr, FALSE);
++ tn7dsl_set_modulation(mp_modulation == NULL ? ptr : mp_modulation, FALSE);
+ }
+
+ // Fine Gains
+ ptr = prom_getenv("fine_gain_control");
+- if (ptr)
++ if (ptr || mp_fine_gain_control != -1)
+ {
+- value = os_atoi(ptr);
++ value = mp_fine_gain_control == -1 ? os_atoi(ptr) : mp_fine_gain_control;
+ tn7dsl_ctrl_fineGain(value);
+ }
+ ptr = NULL;
+ ptr = prom_getenv("fine_gain_value");
+- if(ptr)
+- tn7dsl_set_fineGainValue(os_atoh(ptr));
++ if(ptr || mp_fine_gain_value != -1)
++ tn7dsl_set_fineGainValue(mp_fine_gain_value == -1 ? os_atoh(ptr) : mp_fine_gain_value);
+
+ // margin retrain
+ ptr = NULL;
+ ptr = prom_getenv("enable_margin_retrain");
+- if(ptr)
++ value = mp_enable_margin_retrain == -1 ? (ptr ? os_atoi(ptr) : 0) : mp_enable_margin_retrain;
++
++ if (value == 1)
+ {
+- value = os_atoi(ptr);
+- if(value == 1)
++ dslhal_api_setMarginMonitorFlags(pIhw, 0, 1);
++ bMarginRetrainEnable = 1;
++ //printk("enable showtime margin monitor.\n");
++
++ ptr = NULL;
++ ptr = prom_getenv("margin_threshold");
++ value = mp_margin_threshold == -1 ? (ptr ? os_atoi(ptr) : 0) : mp_margin_threshold;
++
++ if(value >= 0)
+ {
+- dslhal_api_setMarginMonitorFlags(pIhw, 0, 1);
+- bMarginRetrainEnable = 1;
+- //printk("enable showtime margin monitor.\n");
+- ptr = NULL;
+- ptr = prom_getenv("margin_threshold");
+- if(ptr)
+- {
+- value = os_atoi(ptr);
+- //printk("Set margin threshold to %d x 0.5 db\n",value);
+- if(value >= 0)
+- {
+- dslhal_api_setMarginThreshold(pIhw, value);
+- bMarginThConfig=1;
+- }
+- }
++ dslhal_api_setMarginThreshold(pIhw, value);
++ bMarginThConfig=1;
+ }
+ }
+
+ // rate adapt
+ ptr = NULL;
+ ptr = prom_getenv("enable_rate_adapt");
+- if(ptr)
++ if(ptr || mp_enable_rate_adapt != -1)
+ {
+- dslhal_api_setRateAdaptFlag(pIhw, os_atoi(ptr));
++ dslhal_api_setRateAdaptFlag(pIhw, mp_enable_rate_adapt == -1 ? os_atoi(ptr) : mp_enable_rate_adapt);
+ }
+
+ // set powercutback
+ ptr = NULL;
+ ptr = prom_getenv("powercutback");
+- if(ptr)
++ if(ptr || mp_powercutback != -1)
+ {
+- dslhal_advcfg_onOffPcb(pIhw, os_atoi(ptr));
++ dslhal_advcfg_onOffPcb(pIhw, mp_powercutback == -1 ? os_atoi(ptr) : mp_powercutback);
+ }
+
+ // trellis
+ ptr = NULL;
+ ptr = prom_getenv("trellis");
+- if(ptr)
++ if(ptr || mp_trellis != -1)
+ {
+- dslhal_api_setTrellisFlag(pIhw, os_atoi(ptr));
+- trellis = os_atoi(ptr);
++ trellis = mp_trellis == -1 ? os_atoi(ptr) : mp_trellis;
++ dslhal_api_setTrellisFlag(pIhw, trellis);
+ //printk("trellis=%d\n");
+ }
+
+ // bitswap
+ ptr = NULL;
+ ptr = prom_getenv("bitswap");
+- if(ptr)
++ if(ptr || mp_bitswap != -1)
+ {
+ int offset[2] = {33, 0};
+ unsigned int bitswap;
+
+- bitswap = os_atoi(ptr);
++ bitswap = mp_bitswap == -1 ? os_atoi(ptr) : mp_bitswap;
+
+ tn7dsl_generic_read(2, offset);
+ dslReg &= dslhal_support_byteSwap32(0xFFFFFF00);
+@@ -3097,46 +3114,47 @@ static int tn7dsl_set_dsl(void)
+ // maximum bits per carrier
+ ptr = NULL;
+ ptr = prom_getenv("maximum_bits_per_carrier");
+- if(ptr)
++ if(ptr || mp_maximum_bits_per_carrier != -1)
+ {
+- dslhal_api_setMaxBitsPerCarrierUpstream(pIhw, os_atoi(ptr));
++ dslhal_api_setMaxBitsPerCarrierUpstream(pIhw, mp_maximum_bits_per_carrier == -1 ? os_atoi(ptr) : mp_maximum_bits_per_carrier);
+ }
+
+ // maximum interleave depth
+ ptr = NULL;
+ ptr = prom_getenv("maximum_interleave_depth");
+- if(ptr)
++ if(ptr || mp_maximum_interleave_depth != -1)
+ {
+- dslhal_api_setMaxInterleaverDepth(pIhw, os_atoi(ptr));
++ dslhal_api_setMaxInterleaverDepth(pIhw, mp_maximum_interleave_depth == -1 ? os_atoi(ptr) : mp_maximum_interleave_depth);
+ }
+
+ // inner and outer pairs
+ ptr = NULL;
+ ptr = prom_getenv("pair_selection");
+- if(ptr)
++ if(ptr || mp_pair_selection != -1)
+ {
+- dslhal_api_selectInnerOuterPair(pIhw, os_atoi(ptr));
++ dslhal_api_selectInnerOuterPair(pIhw, mp_pair_selection == -1 ? os_atoi(ptr) : mp_pair_selection);
+ }
+
+ ptr = NULL;
+ ptr = prom_getenv("dgas_polarity");
+- if(ptr)
++ if(ptr || mp_dgas_polarity != -1)
+ {
+ dslhal_api_configureDgaspLpr(pIhw, 1, 1);
+- dslhal_api_configureDgaspLpr(pIhw, 0, os_atoi(ptr));
++ dslhal_api_configureDgaspLpr(pIhw, 0, mp_dgas_polarity == -1 ? os_atoi(ptr) : mp_dgas_polarity);
+ }
+
+ ptr = NULL;
+ ptr = prom_getenv("los_alarm");
+- if(ptr)
++ if(ptr || mp_los_alarm != -1)
+ {
+- dslhal_api_disableLosAlarm(pIhw, os_atoi(ptr));
++ dslhal_api_disableLosAlarm(pIhw, mp_los_alarm == -1 ? os_atoi(ptr) : mp_los_alarm);
+ }
+
+ ptr = NULL;
+ ptr = prom_getenv("eoc_vendor_id");
+- if(ptr)
++ if(ptr || mp_eoc_vendor_id != NULL)
+ {
++ ptr = mp_eoc_vendor_id == NULL ? ptr : mp_eoc_vendor_id;
+ for(i=0;i<8;i++)
+ {
+ tmp[0]=ptr[i*2];
+@@ -3161,26 +3179,26 @@ static int tn7dsl_set_dsl(void)
+ }
+ ptr = NULL;
+ ptr = prom_getenv("eoc_vendor_revision");
+- if(ptr)
++ if(ptr || mp_eoc_vendor_revision != -1)
+ {
+- value = os_atoi(ptr);
++ value = mp_eoc_vendor_revision == -1 ? os_atoi(ptr) : mp_eoc_vendor_revision;
+ //printk("eoc rev=%d\n", os_atoi(ptr));
+ dslhal_api_setEocRevisionNumber(pIhw, (char *)&value);
+
+ }
+ ptr = NULL;
+ ptr = prom_getenv("eoc_vendor_serialnum");
+- if(ptr)
++ if(ptr || mp_eoc_vendor_serialnum != NULL)
+ {
+- dslhal_api_setEocSerialNumber(pIhw, ptr);
++ dslhal_api_setEocSerialNumber(pIhw, mp_eoc_vendor_serialnum == NULL ? ptr : mp_eoc_vendor_serialnum);
+ }
+
+ // CQ10037 Added invntry_vernum environment variable to be able to set version number in ADSL2, ADSL2+ modes.
+ ptr = NULL;
+ ptr = prom_getenv("invntry_vernum");
+- if(ptr)
++ if(ptr || mp_invntry_vernum != NULL)
+ {
+- dslhal_api_setEocRevisionNumber(pIhw, ptr);
++ dslhal_api_setEocRevisionNumber(pIhw, mp_invntry_vernum == NULL ? ptr : mp_invntry_vernum);
+ }
+
+ return 0;
+@@ -3225,7 +3243,7 @@ int tn7dsl_init(void *priv)
+ * backward compatibility.
+ */
+ cp = prom_getenv("DSL_BIT_TMODE");
+- if (cp)
++ if (cp || mp_dsl_bit_tmode != -1)
+ {
+ printk("%s : env var DSL_BIT_TMODE is set\n", __FUNCTION__);
+ /*
+@@ -3254,9 +3272,9 @@ int tn7dsl_init(void *priv)
+
+ // UR8_MERGE_START CQ11054 Jack Zhang
+ cp = prom_getenv("high_precision");
+- if (cp)
++ if (cp || mp_high_precision != -1)
+ {
+- high_precision_selected = os_atoi(cp);
++ high_precision_selected = mp_high_precision == -1 ? os_atoi(cp) : mp_high_precision;
+ }
+ if ( high_precision_selected)
+ {
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -76,6 +76,8 @@ typedef void OS_SETUP;
+ #include "tn7atm.h"
+ #include "tn7api.h"
+
++extern int mp_oam_lb_timeout;
++extern int mp_autopvc_enable;
+
+ /* PDSP Firmware files */
+ #include "tnetd7300_sar_firm.h"
+@@ -932,9 +934,9 @@ int tn7sar_setup_oam_channel(Tn7AtmPriva
+ pHalDev = (HAL_DEVICE *)priv->pSarHalDev;
+
+ pauto_pvc = prom_getenv("autopvc_enable");
+- if(pauto_pvc) //CQ10273
++ if(pauto_pvc || mp_autopvc_enable != -1) //CQ10273
+ {
+- auto_pvc =tn7sar_strtoul(pauto_pvc, NULL, 10);
++ auto_pvc = mp_autopvc_enable == -1 ? tn7sar_strtoul(pauto_pvc, NULL, 10) : mp_autopvc_enable;
+ }
+
+ memset(&chInfo, 0xff, sizeof(chInfo));
+@@ -1133,9 +1135,9 @@ int tn7sar_init(struct atm_dev *dev, Tn7
+
+ /* read in oam lb timeout value */
+ pLbTimeout = prom_getenv("oam_lb_timeout");
+- if(pLbTimeout)
++ if(pLbTimeout || mp_oam_lb_timeout != -1)
+ {
+- lbTimeout =tn7sar_strtoul(pLbTimeout, NULL, 10);
++ lbTimeout = mp_oam_lb_timeout == -1 ? tn7sar_strtoul(pLbTimeout, NULL, 10) : mp_oam_lb_timeout;
+ oamLbTimeout = lbTimeout;
+ pHalFunc->Control(pHalDev,"OamLbTimeout", "Set", &lbTimeout);
+ }
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/170-bus_id_removal.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/170-bus_id_removal.patch
new file mode 100644
index 0000000000..6692f40f6a
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/170-bus_id_removal.patch
@@ -0,0 +1,30 @@
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -117,6 +117,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/file.h>
+ #include <linux/firmware.h>
++#include <linux/version.h>
+
+ #include <asm/io.h>
+ #include <asm/ar7/ar7.h>
+@@ -492,7 +493,9 @@ static void avsar_release(struct device
+ }
+
+ static struct device avsar = {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
+ .bus_id = "vlynq",
++#endif
+ .release = avsar_release,
+ };
+
+@@ -501,6 +504,9 @@ int shim_osLoadFWImage(unsigned char *pt
+ const struct firmware *fw_entry;
+ size_t size;
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
++ dev_set_name(&avsar, "avsar");
++#endif
+ printk("requesting firmware image \"ar0700xx.bin\"\n");
+ if(device_register(&avsar) < 0) {
+ printk(KERN_ERR
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/180-git_headers_include.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/180-git_headers_include.patch
new file mode 100644
index 0000000000..feb6ea8605
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/180-git_headers_include.patch
@@ -0,0 +1,54 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -76,10 +76,16 @@
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
++#include <linux/version.h>
+
+ #include <asm/io.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
+ #include <asm/ar7/ar7.h>
+ #include <asm/ar7/prom.h>
++#else
++#include <asm/mach-ar7/ar7.h>
++#include <asm/mach-ar7/prom.h>
++#endif
+
+ #include "dsl_hal_api.h"
+ #ifdef AR7_EFM
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -120,8 +120,13 @@
+ #include <linux/version.h>
+
+ #include <asm/io.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
+ #include <asm/ar7/ar7.h>
+ #include <asm/ar7/prom.h>
++#else
++#include <asm/mach-ar7/ar7.h>
++#include <asm/mach-ar7/prom.h>
++#endif
+
+ /* Modules specific header files */
+ #ifdef AR7_EFM
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -53,10 +53,16 @@
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
++#include <linux/version.h>
+
+ #include <asm/io.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
+ #include <asm/ar7/ar7.h>
+ #include <asm/ar7/prom.h>
++#else
++#include <asm/mach-ar7/ar7.h>
++#include <asm/mach-ar7/prom.h>
++#endif
+
+ #define _CPHAL_AAL5
+ #define _CPHAL_SAR
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/190-2.6.32_proc_fixes.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/190-2.6.32_proc_fixes.patch
new file mode 100644
index 0000000000..52ebbc1529
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/190-2.6.32_proc_fixes.patch
@@ -0,0 +1,79 @@
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -215,7 +215,11 @@ led_reg_t ledreg[2];
+ static struct led_funcs ledreg[2];
+ #endif
+
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+ #define DEV_DSLMOD CTL_UNNUMBERED
++#else
++#define DEV_DSLMOD 0
++#endif
+ #define MAX_STR_SIZE 256
+ #define DSL_MOD_SIZE 256
+
+@@ -3615,9 +3619,16 @@ static int dslmod_sysctl(ctl_table *ctl,
+ */
+ if(write)
+ {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+ ret = proc_dostring(ctl, write, filp, buffer, lenp, 0);
+-
++#else
++ ret = proc_dostring(ctl, write, buffer, lenp, 0);
++#endif
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+ switch (ctl->ctl_name)
++#else
++ switch ((long)ctl->extra2)
++#endif
+ {
+ case DEV_DSLMOD:
+ ptr = strpbrk(info, " \t");
+@@ -3701,14 +3712,29 @@ static int dslmod_sysctl(ctl_table *ctl,
+ else
+ {
+ len += sprintf(info+len, mod_req);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+ ret = proc_dostring(ctl, write, filp, buffer, lenp, 0);
++#else
++ ret = proc_dostring(ctl, write, buffer, lenp, 0);
++#endif
+ }
+ return ret;
+ }
+
+
+ ctl_table dslmod_table[] = {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+ {DEV_DSLMOD, "dslmod", info, DSL_MOD_SIZE, 0644, NULL, NULL, &dslmod_sysctl, &sysctl_string}
++#else
++ {
++ .procname = "dslmod",
++ .data = info,
++ .maxlen = DSL_MOD_SIZE,
++ .mode = 0644,
++ .proc_handler = &dslmod_sysctl,
++ .extra2 = (void *)DEV_DSLMOD,
++ }
++#endif
+ ,
+ {0}
+ };
+@@ -3716,7 +3742,16 @@ ctl_table dslmod_table[] = {
+ /* Make sure that /proc/sys/dev is there */
+ ctl_table dslmod_root_table[] = {
+ #ifdef CONFIG_PROC_FS
++ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+ {CTL_DEV, "dev", NULL, 0, 0555, dslmod_table}
++ #else
++ {
++ .procname = "dev",
++ .maxlen = 0,
++ .mode = 0555,
++ .child = dslmod_table,
++ }
++ #endif
+ ,
+ #endif /* CONFIG_PROC_FS */
+ {0}
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/200-2.6.37_args.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/200-2.6.37_args.patch
new file mode 100644
index 0000000000..a3bff1b940
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/200-2.6.37_args.patch
@@ -0,0 +1,36 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -2000,7 +2000,11 @@ static int __init tn7atm_register (Tn7At
+
+ dgprintf (4, "device %s being registered\n", priv->name);
+
++ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
+ mydev = atm_dev_register (priv->proc_name, &tn7atm_ops, -1, NULL);
++ #else
++ mydev = atm_dev_register (priv->proc_name, NULL, &tn7atm_ops, -1, NULL);
++ #endif
+
+ if (mydev == NULL)
+ {
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -512,14 +512,17 @@ int shim_osLoadFWImage(unsigned char *pt
+ {
+ const struct firmware *fw_entry;
+ size_t size;
++ int ret;
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
+ dev_set_name(&avsar, "avsar");
+ #endif
+ printk("requesting firmware image \"ar0700xx.bin\"\n");
+- if(device_register(&avsar) < 0) {
++ dev_set_name(&avsar, "avsar");
++ ret = device_register(&avsar);
++ if (ret < 0) {
+ printk(KERN_ERR
+- "avsar: device_register fails\n");
++ "avsar: device_register fails, error%i\n", ret);
+ return -1;
+ }
+
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/210-3.3-remove-smp_lock.h.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/210-3.3-remove-smp_lock.h.patch
new file mode 100644
index 0000000000..975ebaf299
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/210-3.3-remove-smp_lock.h.patch
@@ -0,0 +1,33 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -72,7 +72,7 @@
+ #include <linux/atmdev.h>
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+-#include <linux/smp_lock.h>
++#include <linux/interrupt.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -49,7 +49,7 @@
+ #include <linux/atmdev.h>
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+-#include <linux/smp_lock.h>
++#include <linux/interrupt.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -108,7 +108,7 @@
+ #include <linux/atmdev.h>
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+-#include <linux/smp_lock.h>
++#include <linux/interrupt.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
diff --git a/package/kernel/avila-wdt/Makefile b/package/kernel/avila-wdt/Makefile
new file mode 100644
index 0000000000..5bf6bf4ad0
--- /dev/null
+++ b/package/kernel/avila-wdt/Makefile
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=avila-wdt
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/avila-wdt
+ SUBMENU:=Other modules
+ TITLE:=GPIO hardware watchdog driver for modified Avila boards
+ DEPENDS:=@GPIO_SUPPORT @TARGET_ixp4xx
+ FILES:=$(PKG_BUILD_DIR)/avila-wdt.ko
+ AUTOLOAD:=$(call AutoLoad,10,avila-wdt)
+endef
+
+MAKE_OPTS:= \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ SUBDIRS="$(PKG_BUILD_DIR)"
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ $(MAKE_OPTS) \
+ modules
+endef
+
+$(eval $(call KernelPackage,avila-wdt))
diff --git a/package/kernel/avila-wdt/src/Makefile b/package/kernel/avila-wdt/src/Makefile
new file mode 100644
index 0000000000..90d90657ed
--- /dev/null
+++ b/package/kernel/avila-wdt/src/Makefile
@@ -0,0 +1 @@
+obj-m := avila-wdt.o
diff --git a/package/kernel/avila-wdt/src/avila-wdt.c b/package/kernel/avila-wdt/src/avila-wdt.c
new file mode 100644
index 0000000000..981f3857ad
--- /dev/null
+++ b/package/kernel/avila-wdt/src/avila-wdt.c
@@ -0,0 +1,231 @@
+/*
+ * avila-wdt.c
+ * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+ *
+ * based on:
+ * drivers/char/watchdog/ixp4xx_wdt.c
+ *
+ * Watchdog driver for Intel IXP4xx network processors
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2004 (c) MontaVista, Software, Inc.
+ * Based on sa1100 driver, Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/uaccess.h>
+#include <mach/hardware.h>
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+static int heartbeat = 20; /* (secs) Default is 20 seconds */
+static unsigned long wdt_status;
+static atomic_t wdt_counter;
+struct timer_list wdt_timer;
+
+#define WDT_IN_USE 0
+#define WDT_OK_TO_CLOSE 1
+#define WDT_RUNNING 2
+
+static void wdt_refresh(unsigned long data)
+{
+ if (test_bit(WDT_RUNNING, &wdt_status)) {
+ if (atomic_dec_and_test(&wdt_counter)) {
+ printk(KERN_WARNING "Avila watchdog expired, expect a reboot soon!\n");
+ clear_bit(WDT_RUNNING, &wdt_status);
+ return;
+ }
+ }
+
+ /* strobe to the watchdog */
+ gpio_line_set(14, IXP4XX_GPIO_HIGH);
+ gpio_line_set(14, IXP4XX_GPIO_LOW);
+
+ mod_timer(&wdt_timer, jiffies + msecs_to_jiffies(500));
+}
+
+static void wdt_enable(void)
+{
+ atomic_set(&wdt_counter, heartbeat * 2);
+
+ /* Disable clock generator output on GPIO 14/15 */
+ *IXP4XX_GPIO_GPCLKR &= ~(1 << 8);
+
+ /* activate GPIO 14 out */
+ gpio_line_config(14, IXP4XX_GPIO_OUT);
+ gpio_line_set(14, IXP4XX_GPIO_LOW);
+
+ if (!test_bit(WDT_RUNNING, &wdt_status))
+ wdt_refresh(0);
+ set_bit(WDT_RUNNING, &wdt_status);
+}
+
+static void wdt_disable(void)
+{
+ /* Re-enable clock generator output on GPIO 14/15 */
+ *IXP4XX_GPIO_GPCLKR |= (1 << 8);
+}
+
+static int avila_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(WDT_IN_USE, &wdt_status))
+ return -EBUSY;
+
+ clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+ wdt_enable();
+ return nonseekable_open(inode, file);
+}
+
+static ssize_t
+avila_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+ for (i = 0; i != len; i++) {
+ char c;
+
+ if (get_user(c, data + i))
+ return -EFAULT;
+ if (c == 'V')
+ set_bit(WDT_OK_TO_CLOSE, &wdt_status);
+ }
+ }
+ wdt_enable();
+ }
+ return len;
+}
+
+static struct watchdog_info ident = {
+ .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
+ WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .identity = "Avila Watchdog",
+};
+
+
+static long avila_wdt_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = -ENOTTY;
+ int time;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ ret = copy_to_user((struct watchdog_info *)arg, &ident,
+ sizeof(ident)) ? -EFAULT : 0;
+ break;
+
+ case WDIOC_GETSTATUS:
+ ret = put_user(0, (int *)arg);
+ break;
+
+ case WDIOC_KEEPALIVE:
+ wdt_enable();
+ ret = 0;
+ break;
+
+ case WDIOC_SETTIMEOUT:
+ ret = get_user(time, (int *)arg);
+ if (ret)
+ break;
+
+ if (time <= 0 || time > 60) {
+ ret = -EINVAL;
+ break;
+ }
+
+ heartbeat = time;
+ wdt_enable();
+ /* Fall through */
+
+ case WDIOC_GETTIMEOUT:
+ ret = put_user(heartbeat, (int *)arg);
+ break;
+ }
+ return ret;
+}
+
+static int avila_wdt_release(struct inode *inode, struct file *file)
+{
+ if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
+ wdt_disable();
+ else
+ printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
+ "timer will not stop\n");
+ clear_bit(WDT_IN_USE, &wdt_status);
+ clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+ return 0;
+}
+
+
+static const struct file_operations avila_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = avila_wdt_write,
+ .unlocked_ioctl = avila_wdt_ioctl,
+ .open = avila_wdt_open,
+ .release = avila_wdt_release,
+};
+
+static struct miscdevice avila_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR + 1,
+ .name = "avila_watchdog",
+ .fops = &avila_wdt_fops,
+};
+
+static int __init avila_wdt_init(void)
+{
+ int ret;
+
+ init_timer(&wdt_timer);
+ wdt_timer.expires = 0;
+ wdt_timer.data = 0;
+ wdt_timer.function = wdt_refresh;
+ ret = misc_register(&avila_wdt_miscdev);
+ if (ret == 0)
+ printk(KERN_INFO "Avila Watchdog Timer: heartbeat %d sec\n",
+ heartbeat);
+ return ret;
+}
+
+static void __exit avila_wdt_exit(void)
+{
+ misc_deregister(&avila_wdt_miscdev);
+ del_timer(&wdt_timer);
+ wdt_disable();
+}
+
+
+module_init(avila_wdt_init);
+module_exit(avila_wdt_exit);
+
+MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>");
+MODULE_DESCRIPTION("Gateworks Avila Hardware Watchdog");
+
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 20s)");
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+
diff --git a/package/kernel/brcm2708-gpu-fw/Makefile b/package/kernel/brcm2708-gpu-fw/Makefile
new file mode 100644
index 0000000000..0b79cd15a9
--- /dev/null
+++ b/package/kernel/brcm2708-gpu-fw/Makefile
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=brcm2708-gpu-fw
+PKG_REV:=d5b05be2147bf5dc0137798837af24b0bbbe398d
+PKG_VERSION:=20130517
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_REV).tar.gz
+PKG_SOURCE_URL:=https://github.com/Hexxeh/rpi-firmware/archive/
+PKG_MD5SUM:=9b0ce0a530e237f4c6fe43a36ccf57c3
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/rpi-firmware-$(PKG_REV)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/brcm2708-gpu-fw
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_brcm2708
+ TITLE:=brcm2708-gpu-fw
+ DEFAULT:=y if (TARGET_brcm2708)
+endef
+
+define Package/brcm2708-gpu-fw/description
+ GPU and kernel boot firmware for brcm2708.
+endef
+
+define Build/Compile
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(BUILD_DIR)/brcm2708-gpu-fw-boot
+ $(CP) $(PKG_BUILD_DIR)/* $(BUILD_DIR)/brcm2708-gpu-fw-boot
+endef
+
+$(eval $(call BuildPackage,brcm2708-gpu-fw))
+
diff --git a/package/kernel/broadcom-diag/Makefile b/package/kernel/broadcom-diag/Makefile
new file mode 100644
index 0000000000..61b35290fc
--- /dev/null
+++ b/package/kernel/broadcom-diag/Makefile
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 2006-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=broadcom-diag
+PKG_RELEASE:=10
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/diag
+ SUBMENU:=Other modules
+ DEPENDS:=@TARGET_brcm47xx
+ TITLE:=Driver for router LEDs and Buttons
+ FILES:=$(PKG_BUILD_DIR)/diag.ko
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ ARCH="$(LINUX_KARCH)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="$(BUILDFLAGS)" \
+ modules
+endef
+
+$(eval $(call KernelPackage,diag))
diff --git a/package/kernel/broadcom-diag/src/Makefile b/package/kernel/broadcom-diag/src/Makefile
new file mode 100644
index 0000000000..44c80a8bff
--- /dev/null
+++ b/package/kernel/broadcom-diag/src/Makefile
@@ -0,0 +1,17 @@
+#
+# Makefile for diag driver
+#
+# Copyright (C) 2005 Felix Fietkau <nbd@openwrt.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.
+#
+
+obj-m := diag.o
+
+ifeq ($(MAKING_MODULES),1)
+
+-include $(TOPDIR)/Rules.make
+endif
diff --git a/package/kernel/broadcom-diag/src/diag.c b/package/kernel/broadcom-diag/src/diag.c
new file mode 100644
index 0000000000..ccbaee2d26
--- /dev/null
+++ b/package/kernel/broadcom-diag/src/diag.c
@@ -0,0 +1,1807 @@
+/*
+ * diag.c - GPIO interface driver for Broadcom boards
+ *
+ * Copyright (C) 2006 Mike Baker <mbm@openwrt.org>,
+ * Copyright (C) 2006-2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2008 Andy Boyett <agb@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/pci.h>
+#include <linux/kmod.h>
+#include <linux/proc_fs.h>
+#include <linux/timer.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+#include <linux/workqueue.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/kobject.h>
+#include <net/sock.h>
+#include <bcm47xx_board.h>
+extern u64 uevent_next_seqnum(void);
+
+#include "gpio.h"
+#include "diag.h"
+#define getvar(str) (nvram_get(str)?:"")
+
+static inline int startswith (char *source, char *cmp) { return !strncmp(source,cmp,strlen(cmp)); }
+static int fill_event(struct event_t *);
+static unsigned int gpiomask = 0;
+module_param(gpiomask, int, 0644);
+
+enum {
+ /* Linksys */
+ WAP54GV1,
+ WAP54GV2,
+ WAP54GV3,
+ WRT54GV1,
+ WRT54G,
+ WRTSL54GS,
+ WRT54G3G,
+ WRT54G3GV2_VF,
+ WRT150NV1,
+ WRT150NV11,
+ WRT160NV1,
+ WRT160NV3,
+ WRT300NV11,
+ WRT350N,
+ WRT600N,
+ WRT600NV11,
+ WRT610N,
+ WRT610NV2,
+ E1000V1,
+ E3000V1,
+ E3200V1,
+
+ /* ASUS */
+ WLHDD,
+ WL300G,
+ WL320GE,
+ WL330GE,
+ WL500G,
+ WL500GD,
+ WL500GP,
+ WL500GPV2,
+ WL500W,
+ WL520GC,
+ WL520GU,
+ ASUS_4702,
+ WL700GE,
+ RTN16,
+
+ /* Buffalo */
+ WBR2_G54,
+ WHR_G54S,
+ WHR_HP_G54,
+ WHR_G125,
+ WHR2_A54G54,
+ WLA2_G54L,
+ WZR_G300N,
+ WZR_RS_G54,
+ WZR_RS_G54HP,
+ BUFFALO_UNKNOWN,
+ BUFFALO_UNKNOWN_4710,
+
+ /* Siemens */
+ SE505V1,
+ SE505V2,
+
+ /* US Robotics */
+ USR5461,
+
+ /* Dell */
+ TM2300,
+ TM2300V2,
+
+ /* Motorola */
+ WE800G,
+ WR850GV1,
+ WR850GV2V3,
+ WR850GP,
+
+ /* Belkin */
+ BELKIN_UNKNOWN,
+ BELKIN_F7D4301,
+
+ /* Netgear */
+ WGT634U,
+ WNR834BV1,
+ WNR834BV2,
+ WNDR3400V1,
+ WNDR3700V3,
+
+ /* Trendware */
+ TEW411BRPP,
+
+ /* SimpleTech */
+ STI_NAS,
+
+ /* D-Link */
+ DIR130,
+ DIR320,
+ DIR330,
+ DWL3150,
+
+ /* Sitecom */
+ WL105B,
+
+ /* Western Digital */
+ WDNetCenter,
+
+ /* Askey */
+ RT210W,
+
+ /* OvisLink */
+ WL1600GL,
+
+ /* Microsoft */
+ MN700,
+
+ /* Edimax */
+ PS1208MFG,
+};
+
+static void __init bcm4780_init(void) {
+ int pin = 1 << 3;
+
+ /* Enables GPIO 3 that controls HDD and led power on ASUS WL-700gE */
+ printk(MODULE_NAME ": Spinning up HDD and enabling leds\n");
+ bcm47xx_gpio_outen(pin, pin);
+ bcm47xx_gpio_control(pin, 0);
+ bcm47xx_gpio_out(pin, pin);
+
+ /* Wait 5s, so the HDD can spin up */
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ * 5);
+}
+
+static void __init NetCenter_init(void) {
+ /* unset pin 6 (+12V) */
+ int pin = 1 << 6;
+ bcm47xx_gpio_outen(pin, pin);
+ bcm47xx_gpio_control(pin, 0);
+ bcm47xx_gpio_out(pin, pin);
+ /* unset pin 1 (turn off red led, blue will light alone if +5V comes up) */
+ pin = 1 << 1;
+ bcm47xx_gpio_outen(pin, pin);
+ bcm47xx_gpio_control(pin, 0);
+ bcm47xx_gpio_out(pin, pin);
+ /* unset pin 3 (+5V) and wait 5 seconds (harddisk spin up) */
+ bcm4780_init();
+}
+
+static void __init bcm57xx_init(void) {
+ int pin = 1 << 2;
+
+ /* FIXME: switch comes up, but port mappings/vlans not right */
+ bcm47xx_gpio_outen(pin, pin);
+ bcm47xx_gpio_control(pin, 0);
+ bcm47xx_gpio_out(pin, pin);
+}
+
+static struct platform_t __initdata platforms[] = {
+ /* Linksys */
+ [WAP54GV1] = {
+ .name = "Linksys WAP54G V1",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 0 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 3 },
+ { .name = "wlan", .gpio = 1 << 4 },
+ },
+ },
+ [WAP54GV2] = {
+ .name = "Linksys WAP54G V2",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 0 },
+ },
+ .leds = {
+ { .name = "wlan", .gpio = 1 << 5, .polarity = REVERSE },
+ /* GPIO 6 is b44 (eth0, LAN) PHY power */
+ },
+ },
+ [WAP54GV3] = {
+ .name = "Linksys WAP54G V3",
+ .buttons = {
+ /* FIXME: verify this */
+ { .name = "reset", .gpio = 1 << 7 },
+ { .name = "ses", .gpio = 1 << 0 },
+ },
+ .leds = {
+ /* FIXME: diag? */
+ { .name = "ses", .gpio = 1 << 1 },
+ },
+ },
+ [WRT54GV1] = {
+ .name = "Linksys WRT54G V1.x",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 0x13 | GPIO_TYPE_EXTIF, .polarity = NORMAL },
+ { .name = "dmz", .gpio = 0x12 | GPIO_TYPE_EXTIF, .polarity = NORMAL },
+ },
+ },
+ [WRT54G] = {
+ .name = "Linksys WRT54G/GS/GL",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "dmz", .gpio = 1 << 7, .polarity = REVERSE },
+ { .name = "ses_white", .gpio = 1 << 2, .polarity = REVERSE },
+ { .name = "ses_orange", .gpio = 1 << 3, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 0, .polarity = REVERSE },
+ },
+ },
+ [WRTSL54GS] = {
+ .name = "Linksys WRTSL54GS",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "dmz", .gpio = 1 << 0, .polarity = REVERSE },
+ { .name = "ses_white", .gpio = 1 << 5, .polarity = REVERSE },
+ { .name = "ses_orange", .gpio = 1 << 7, .polarity = REVERSE },
+ },
+ },
+ [WRT54G3G] = {
+ .name = "Linksys WRT54G3G",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "3g", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "dmz", .gpio = 1 << 7, .polarity = REVERSE },
+ { .name = "3g_green", .gpio = 1 << 2, .polarity = NORMAL },
+ { .name = "3g_blue", .gpio = 1 << 3, .polarity = NORMAL },
+ { .name = "3g_blink", .gpio = 1 << 5, .polarity = NORMAL },
+ },
+ },
+ [WRT54G3GV2_VF] = {
+ .name = "Linksys WRT54G3GV2-VF",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "3g", .gpio = 1 << 5 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "3g_green", .gpio = 1 << 2, .polarity = NORMAL },
+ { .name = "3g_blue", .gpio = 1 << 3, .polarity = NORMAL },
+ },
+ },
+ [WRT150NV1] = {
+ .name = "Linksys WRT150N V1",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "ses_green", .gpio = 1 << 5, .polarity = REVERSE },
+ { .name = "ses_amber", .gpio = 1 << 3, .polarity = REVERSE },
+ },
+ },
+ [WRT150NV11] = {
+ .name = "Linksys WRT150N V1.1",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "ses_green", .gpio = 1 << 5, .polarity = REVERSE },
+ { .name = "ses_amber", .gpio = 1 << 3, .polarity = REVERSE },
+ },
+ },
+ [WRT160NV1] = {
+ .name = "Linksys WRT160N v1.x",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "ses_blue", .gpio = 1 << 5, .polarity = REVERSE },
+ { .name = "ses_orange", .gpio = 1 << 3, .polarity = REVERSE },
+ },
+ },
+ [WRT160NV3] = {
+ .name = "Linksys WRT160N V3",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 5 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "ses_blue", .gpio = 1 << 4, .polarity = REVERSE },
+ { .name = "ses_orange", .gpio = 1 << 2, .polarity = REVERSE },
+ },
+ },
+ [WRT300NV11] = {
+ .name = "Linksys WRT300N V1.1",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 }, // "Reset" on back panel
+ { .name = "ses", .gpio = 1 << 4 }, // "Reserved" on top panel
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL }, // "Power"
+ { .name = "ses_amber", .gpio = 1 << 3, .polarity = REVERSE }, // "Security" Amber
+ { .name = "ses_green", .gpio = 1 << 5, .polarity = REVERSE }, // "Security" Green
+ },
+ .platform_init = bcm57xx_init,
+ },
+ [WRT350N] = {
+ .name = "Linksys WRT350N",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 8 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "ses_amber", .gpio = 1 << 3, .polarity = REVERSE },
+ { .name = "ses_green", .gpio = 1 << 9, .polarity = REVERSE },
+ { .name = "usb_blink", .gpio = 1 << 10, .polarity = REVERSE },
+ { .name = "usb", .gpio = 1 << 11, .polarity = REVERSE },
+ },
+ .platform_init = bcm57xx_init,
+ },
+ [WRT600N] = {
+ .name = "Linksys WRT600N",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 7 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 2, .polarity = REVERSE }, // Power LED
+ { .name = "usb", .gpio = 1 << 3, .polarity = REVERSE }, // USB LED
+ { .name = "wl0_ses_amber", .gpio = 1 << 8, .polarity = REVERSE }, // 2.4Ghz LED Amber
+ { .name = "wl0_ses_green", .gpio = 1 << 9, .polarity = REVERSE }, // 2.4Ghz LED Green
+ { .name = "wl1_ses_amber", .gpio = 1 << 10, .polarity = REVERSE }, // 5.6Ghz LED Amber
+ { .name = "wl1_ses_green", .gpio = 1 << 11, .polarity = REVERSE }, // 5.6Ghz LED Green
+ },
+ .platform_init = bcm57xx_init,
+ },
+ [WRT600NV11] = {
+ .name = "Linksys WRT600N V1.1",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 7 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 2, .polarity = REVERSE }, // Power LED
+ { .name = "usb", .gpio = 1 << 3, .polarity = REVERSE }, // USB LED
+ { .name = "wl0_ses_amber", .gpio = 1 << 8, .polarity = REVERSE }, // 2.4Ghz LED Amber
+ { .name = "wl0_ses_green", .gpio = 1 << 9, .polarity = REVERSE }, // 2.4Ghz LED Green
+ { .name = "wl1_ses_amber", .gpio = 1 << 10, .polarity = REVERSE }, // 5.6Ghz LED Amber
+ { .name = "wl1_ses_green", .gpio = 1 << 11, .polarity = REVERSE }, // 5.6Ghz LED Green
+ },
+ .platform_init = bcm57xx_init,
+ },
+ [WRT610N] = {
+ .name = "Linksys WRT610N",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 8 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL }, // Power LED
+ { .name = "usb", .gpio = 1 << 0, .polarity = REVERSE }, // USB LED
+ { .name = "ses_amber", .gpio = 1 << 3, .polarity = REVERSE }, // WiFi protected setup LED amber
+ { .name = "ses_blue", .gpio = 1 << 9, .polarity = REVERSE }, // WiFi protected setup LED blue
+ },
+ },
+ [WRT610NV2] = {
+ .name = "Linksys WRT610N V2",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 5, .polarity = NORMAL }, // Power LED
+ { .name = "usb", .gpio = 1 << 7, .polarity = NORMAL }, // USB LED
+ { .name = "ses_amber", .gpio = 1 << 0, .polarity = REVERSE }, // WiFi protected setup LED amber
+ { .name = "ses_blue", .gpio = 1 << 3, .polarity = REVERSE }, // WiFi protected setup LED blue
+ { .name = "wlan", .gpio = 1 << 1, .polarity = NORMAL }, // Wireless LED
+ },
+ },
+ /* same hardware as WRT160NV3 and Cisco Valet M10V1, but different board detection, combine? */
+ [E1000V1] = {
+ .name = "Linksys E1000 V1",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "wps", .gpio = 1 << 5 }, /* nvram get gpio5=wps_button */
+ },
+ .leds = {
+ /** turns on leds for all ethernet ports (wan too)
+ * this also disconnects some, or maybe all, ethernet ports
+ * 1: leds work normally
+ * 0: all lit all the time */
+ /* nvram get gpio3=robo_reset */
+ { .name = "wlan", .gpio = 1 << 0, .polarity = NORMAL },
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "ses_blue", .gpio = 1 << 4, .polarity = REVERSE }, /* nvram get gpio4=wps_led */
+ { .name = "ses_orange", .gpio = 1 << 2, .polarity = REVERSE }, /* nvram get gpio2=wps_status_led */
+ },
+ },
+ [E3000V1] = {
+ .name = "Linksys E3000 V1",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 5, .polarity = NORMAL }, // Power LED
+ { .name = "usb", .gpio = 1 << 7, .polarity = NORMAL }, // USB LED
+ { .name = "ses_amber", .gpio = 1 << 0, .polarity = REVERSE }, // WiFi protected setup LED amber
+ { .name = "ses_blue", .gpio = 1 << 3, .polarity = REVERSE }, // WiFi protected setup LED blue
+ { .name = "wlan", .gpio = 1 << 1, .polarity = NORMAL }, // Wireless LED
+ },
+ },
+ [E3200V1] = {
+ .name = "Linksys E3200 V1",
+ .buttons = {
+ /* { .name = "switch", .gpio = 1 << 4 },*/ /* nvram get gpio4=robo_reset */
+ { .name = "reset", .gpio = 1 << 5 }, /* nvram get reset_gpio=5 */
+ { .name = "wps", .gpio = 1 << 8 }, /* nvram get gpio8=wps_button */
+ /* { .name = "wombo", .gpio = 1 << 23 },*/ /* nvram get gpio23=wombo_reset - wireless on motherboard */
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 3, .polarity = REVERSE }, /* Power LED */
+ },
+ },
+ /* Asus */
+ [WLHDD] = {
+ .name = "ASUS WL-HDD",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 0, .polarity = REVERSE },
+ { .name = "usb", .gpio = 1 << 2, .polarity = REVERSE },
+ },
+ },
+ [WL300G] = {
+ .name = "ASUS WL-300g",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 0, .polarity = REVERSE },
+ },
+ },
+ [WL320GE] = {
+ .name = "ASUS WL-320gE/WL-320gP",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ },
+ .leds = {
+ { .name = "wlan", .gpio = 1 << 0, .polarity = REVERSE },
+ { .name = "power", .gpio = 1 << 2, .polarity = REVERSE },
+ { .name = "link", .gpio = 1 << 11, .polarity = REVERSE },
+ },
+ },
+ [WL330GE] = {
+ .name = "ASUS WL-330gE",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 2 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 0, .polarity = REVERSE },
+ },
+ },
+ [WL500G] = {
+ .name = "ASUS WL-500g",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 0, .polarity = REVERSE },
+ },
+ },
+ [WL500GD] = {
+ .name = "ASUS WL-500g Deluxe",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 0, .polarity = REVERSE },
+ },
+ },
+ [WL500GP] = {
+ .name = "ASUS WL-500g Premium",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 0 },
+ { .name = "ses", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = REVERSE },
+ },
+ },
+ [WL500GPV2] = {
+ .name = "ASUS WL-500g Premium V2",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 2 },
+ { .name = "ses", .gpio = 1 << 3 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 0, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 1, .polarity = REVERSE },
+ },
+ },
+ [WL500W] = {
+ .name = "ASUS WL-500W",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "ses", .gpio = 1 << 7 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 5, .polarity = REVERSE },
+ },
+ },
+ [WL520GC] = {
+ .name = "ASUS WL-520GC",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 2 },
+ { .name = "ses", .gpio = 1 << 3 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 0, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 1, .polarity = REVERSE },
+ },
+ },
+ [WL520GU] = {
+ .name = "ASUS WL-520gU",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 2 },
+ { .name = "ses", .gpio = 1 << 3 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 0, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 1, .polarity = REVERSE },
+ },
+ },
+ [ASUS_4702] = {
+ .name = "ASUS (unknown, BCM4702)",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 0, .polarity = REVERSE },
+ },
+ },
+ [WL700GE] = {
+ .name = "ASUS WL-700gE",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 7 }, // on back, hardwired, always resets device regardless OS state
+ { .name = "ses", .gpio = 1 << 4 }, // on back, actual name ezsetup
+ { .name = "power", .gpio = 1 << 0 }, // on front
+ { .name = "copy", .gpio = 1 << 6 }, // on front
+ },
+ .leds = {
+#if 0
+ // GPIO that controls power led also enables/disables some essential functions
+ // - power to HDD
+ // - switch leds
+ { .name = "power", .gpio = 1 << 3, .polarity = NORMAL }, // actual name power
+#endif
+ { .name = "diag", .gpio = 1 << 1, .polarity = REVERSE }, // actual name ready
+ },
+ .platform_init = bcm4780_init,
+ },
+ [RTN16] = {
+ .name = "ASUS RT-N16",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 8 },
+ { .name = "ses", .gpio = 1 << 5 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 7, .polarity = NORMAL },
+ },
+ },
+ /* Buffalo */
+ [WHR_G54S] = {
+ .name = "Buffalo WHR-G54S",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 4 },
+ { .name = "bridge", .gpio = 1 << 5 },
+ { .name = "ses", .gpio = 1 << 0 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 7, .polarity = REVERSE },
+ { .name = "internal", .gpio = 1 << 3, .polarity = REVERSE },
+ { .name = "ses", .gpio = 1 << 6, .polarity = REVERSE },
+ { .name = "bridge", .gpio = 1 << 1, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 2, .polarity = REVERSE },
+ },
+ },
+ [WBR2_G54] = {
+ .name = "Buffalo WBR2-G54",
+ /* FIXME: verify */
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 7 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 1, .polarity = REVERSE },
+ },
+ },
+ [WHR_HP_G54] = {
+ .name = "Buffalo WHR-HP-G54",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 4 },
+ { .name = "bridge", .gpio = 1 << 5 },
+ { .name = "ses", .gpio = 1 << 0 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 7, .polarity = REVERSE },
+ { .name = "internal", .gpio = 1 << 3, .polarity = REVERSE },
+ { .name = "bridge", .gpio = 1 << 1, .polarity = REVERSE },
+ { .name = "ses", .gpio = 1 << 6, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 2, .polarity = REVERSE },
+ },
+ },
+ [WHR_G125] = {
+ .name = "Buffalo WHR-G125",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 4 },
+ { .name = "bridge", .gpio = 1 << 5 },
+ { .name = "ses", .gpio = 1 << 0 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 7, .polarity = REVERSE },
+ { .name = "internal", .gpio = 1 << 3, .polarity = REVERSE },
+ { .name = "bridge", .gpio = 1 << 1, .polarity = REVERSE },
+ { .name = "ses", .gpio = 1 << 6, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 2, .polarity = REVERSE },
+ },
+ },
+ [WHR2_A54G54] = {
+ .name = "Buffalo WHR2-A54G54",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 7, .polarity = REVERSE },
+ },
+ },
+ [WLA2_G54L] = {
+ .name = "Buffalo WLA2-G54L",
+ /* FIXME: verify */
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 7 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 1, .polarity = REVERSE },
+ },
+ },
+ [WZR_G300N] = {
+ .name = "Buffalo WZR-G300N",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 7, .polarity = REVERSE },
+ { .name = "bridge", .gpio = 1 << 1, .polarity = REVERSE },
+ { .name = "ses", .gpio = 1 << 6, .polarity = REVERSE },
+ },
+ },
+ [WZR_RS_G54] = {
+ .name = "Buffalo WZR-RS-G54",
+ .buttons = {
+ { .name = "ses", .gpio = 1 << 0 },
+ { .name = "reset", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 7, .polarity = REVERSE },
+ { .name = "ses", .gpio = 1 << 6, .polarity = REVERSE },
+ { .name = "vpn", .gpio = 1 << 1, .polarity = REVERSE },
+ },
+ },
+ [WZR_RS_G54HP] = {
+ .name = "Buffalo WZR-RS-G54HP",
+ .buttons = {
+ { .name = "ses", .gpio = 1 << 0 },
+ { .name = "reset", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 7, .polarity = REVERSE },
+ { .name = "ses", .gpio = 1 << 6, .polarity = REVERSE },
+ { .name = "vpn", .gpio = 1 << 1, .polarity = REVERSE },
+ },
+ },
+ [BUFFALO_UNKNOWN] = {
+ .name = "Buffalo (unknown)",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 7 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 1, .polarity = REVERSE },
+ },
+ },
+ [BUFFALO_UNKNOWN_4710] = {
+ .name = "Buffalo (unknown, BCM4710)",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 1, .polarity = REVERSE },
+ },
+ },
+ /* Siemens */
+ [SE505V1] = {
+ .name = "Siemens SE505 V1",
+ .buttons = {
+ /* No usable buttons */
+ },
+ .leds = {
+// { .name = "power", .gpio = 1 << 0 .polarity = REVERSE }, // Usable when retrofitting D26 (?)
+ { .name = "dmz", .gpio = 1 << 4, .polarity = REVERSE }, // actual name WWW
+ { .name = "wlan", .gpio = 1 << 3, .polarity = REVERSE },
+ },
+ },
+ [SE505V2] = {
+ .name = "Siemens SE505 V2",
+ .buttons = {
+ /* No usable buttons */
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 5, .polarity = REVERSE },
+ { .name = "dmz", .gpio = 1 << 0, .polarity = REVERSE }, // actual name WWW
+ { .name = "wlan", .gpio = 1 << 3, .polarity = REVERSE },
+ },
+ },
+ /* US Robotics */
+ [USR5461] = {
+ .name = "U.S. Robotics USR5461",
+ .buttons = {
+ /* No usable buttons */
+ },
+ .leds = {
+ { .name = "wlan", .gpio = 1 << 0, .polarity = REVERSE },
+ { .name = "printer", .gpio = 1 << 1, .polarity = REVERSE },
+ },
+ },
+ /* Dell */
+ [TM2300] = {
+ .name = "Dell TrueMobile 2300",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 0 },
+ },
+ .leds = {
+ { .name = "wlan", .gpio = 1 << 6, .polarity = REVERSE },
+ { .name = "power", .gpio = 1 << 7, .polarity = REVERSE },
+ },
+ },
+ [TM2300V2] = {
+ .name = "Dell TrueMobile 2300 v2",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 0 },
+ },
+ .leds = {
+ { .name = "wlan", .gpio = 1 << 6, .polarity = REVERSE },
+ { .name = "power", .gpio = 1 << 7, .polarity = REVERSE },
+ },
+ },
+ /* Motorola */
+ [WE800G] = {
+ .name = "Motorola WE800G",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 0 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 4, .polarity = NORMAL },
+ { .name = "diag", .gpio = 1 << 2, .polarity = REVERSE },
+ { .name = "wlan_amber", .gpio = 1 << 1, .polarity = NORMAL },
+ },
+ },
+ [WR850GV1] = {
+ .name = "Motorola WR850G V1",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 0 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 4, .polarity = NORMAL },
+ { .name = "diag", .gpio = 1 << 3, .polarity = REVERSE },
+ { .name = "dmz", .gpio = 1 << 6, .polarity = NORMAL },
+ { .name = "wlan_red", .gpio = 1 << 5, .polarity = REVERSE },
+ { .name = "wlan_green", .gpio = 1 << 7, .polarity = REVERSE },
+ },
+ },
+ [WR850GV2V3] = {
+ .name = "Motorola WR850G V2/V3",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 5 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "wlan", .gpio = 1 << 0, .polarity = REVERSE },
+ { .name = "wan", .gpio = 1 << 6, .polarity = INPUT },
+ { .name = "diag", .gpio = 1 << 7, .polarity = REVERSE },
+ },
+ },
+ [WR850GP] = {
+ .name = "Motorola WR850GP",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 5 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "wlan", .gpio = 1 << 0, .polarity = REVERSE },
+ { .name = "dmz", .gpio = 1 << 6, .polarity = REVERSE },
+ { .name = "diag", .gpio = 1 << 7, .polarity = REVERSE },
+ },
+ },
+
+ /* Belkin */
+ [BELKIN_UNKNOWN] = {
+ .name = "Belkin (unknown)",
+ /* FIXME: verify & add detection */
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 7 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 5, .polarity = NORMAL },
+ { .name = "wlan", .gpio = 1 << 3, .polarity = NORMAL },
+ { .name = "connected", .gpio = 1 << 0, .polarity = NORMAL },
+ },
+ },
+ [BELKIN_F7D4301] = {
+ .name = "Belkin PlayMax F7D4301",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ { .name = "wps", .gpio = 1 << 8 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 11, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 13, .polarity = REVERSE },
+ { .name = "led0", .gpio = 1 << 14, .polarity = REVERSE },
+ { .name = "led1", .gpio = 1 << 15, .polarity = REVERSE },
+ },
+ },
+ /* Netgear */
+ [WGT634U] = {
+ .name = "Netgear WGT634U",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 2 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 3, .polarity = NORMAL },
+ },
+ },
+ /* Netgear */
+ [WNR834BV1] = {
+ .name = "Netgear WNR834B V1",
+ .buttons = { /* TODO: add reset button and confirm LEDs - GPIO from dd-wrt */ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 4, .polarity = REVERSE },
+ { .name = "diag", .gpio = 1 << 5, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 6, .polarity = REVERSE },
+ },
+ },
+ /* Netgear */
+ [WNR834BV2] = {
+ .name = "Netgear WNR834B V2",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 6 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 2, .polarity = NORMAL },
+ { .name = "diag", .gpio = 1 << 3, .polarity = NORMAL },
+ { .name = "connected", .gpio = 1 << 7, .polarity = NORMAL },
+ },
+ },
+ [WNDR3400V1] = {
+ .name = "Netgear WNDR3400 V1",
+ .buttons = {
+ /* nvram get gpio5=robo_reset */
+ { .name = "reset", .gpio = 1 << 4 },
+ { .name = "wps", .gpio = 1 << 6 },
+ { .name = "wlan", .gpio = 1 << 8 },
+ },
+ .leds = {
+ { .name = "wlan", .gpio = 0 << 0, .polarity = NORMAL },
+ { .name = "connected", .gpio = 1 << 0, .polarity = NORMAL },
+ { .name = "power", .gpio = 1 << 3, .polarity = NORMAL },
+ { .name = "diag", .gpio = 1 << 7, .polarity = NORMAL },
+ { .name = "usb", .gpio = 1 << 2, .polarity = REVERSE },
+ },
+ },
+ [WNDR3700V3] = {
+ .name = "Netgear WNDR3700 V3",
+ .buttons = {
+ /* { .name = "usb", .gpio = 1 << 1 }, */ /* this button doesn't seem to exist. */
+ { .name = "wlan", .gpio = 1 << 2 },
+ { .name = "reset", .gpio = 1 << 3 },
+ { .name = "wps", .gpio = 1 << 4 },
+ /* { .name = "switch", .gpio = 1 << 5 },*/ /* nvram get gpio5=robo_reset */
+ },
+ .leds = {
+ { .name = "power", .gpio = (1 << 0) | GPIO_TYPE_SHIFT, .polarity = REVERSE },
+ { .name = "diag", .gpio = (1 << 1) | GPIO_TYPE_SHIFT, .polarity = REVERSE },
+ /* WAN LED doesn't respond to GPIO control. The switch is probably driving it.
+ * { .name = "wan", .gpio = (1 << 2) | GPIO_TYPE_SHIFT, .polarity = REVERSE },
+ */
+ { .name = "wlan2g", .gpio = (1 << 3) | GPIO_TYPE_SHIFT, .polarity = REVERSE },
+ { .name = "wlan5g", .gpio = (1 << 4) | GPIO_TYPE_SHIFT, .polarity = REVERSE },
+ { .name = "usb", .gpio = (1 << 5) | GPIO_TYPE_SHIFT, .polarity = REVERSE },
+ { .name = "wps", .gpio = (1 << 6) | GPIO_TYPE_SHIFT, .polarity = REVERSE },
+ { .name = "wlan", .gpio = (1 << 7) | GPIO_TYPE_SHIFT, .polarity = REVERSE },
+ },
+ },
+ /* Trendware */
+ [TEW411BRPP] = {
+ .name = "Trendware TEW411BRP+",
+ .buttons = {
+ { /* No usable buttons */ },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 7, .polarity = NORMAL },
+ { .name = "wlan", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "bridge", .gpio = 1 << 6, .polarity = NORMAL },
+ },
+ },
+ /* SimpleTech */
+ [STI_NAS] = {
+ .name = "SimpleTech SimpleShare NAS",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 0 }, // Power button on back, named reset to enable failsafe.
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 1, .polarity = REVERSE }, // actual name ready
+ },
+ .platform_init = bcm4780_init,
+ },
+ /* D-Link */
+ [DIR130] = {
+ .name = "D-Link DIR-130",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 3},
+ { .name = "reserved", .gpio = 1 << 7},
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 0},
+ { .name = "blue", .gpio = 1 << 6},
+ },
+ },
+ [DIR320] = {
+ .name = "D-Link DIR-320",
+ .buttons = {
+ { .name = "reserved", .gpio = 1 << 6},
+ { .name = "reset", .gpio = 1 << 7},
+ },
+ .leds = {
+ { .name = "wlan", .gpio = 1 << 0, .polarity = NORMAL },
+ { .name = "diag", .gpio = 1 << 1, .polarity = NORMAL }, /* "status led */
+ { .name = "red", .gpio = 1 << 3, .polarity = REVERSE },
+ { .name = "blue", .gpio = 1 << 4, .polarity = REVERSE },
+ { .name = "usb", .gpio = 1 << 5, .polarity = NORMAL },
+ },
+ },
+ [DIR330] = {
+ .name = "D-Link DIR-330",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 3},
+ { .name = "reserved", .gpio = 1 << 7},
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 0},
+ { .name = "usb", .gpio = 1 << 4},
+ { .name = "blue", .gpio = 1 << 6},
+ },
+ },
+ [DWL3150] = {
+ .name = "D-Link DWL-3150",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 7},
+ },
+ .leds = {
+ { .name = "diag", .gpio = 1 << 2},
+ { .name = "status", .gpio = 1 << 1},
+ },
+ },
+ /* Double check */
+ [WL105B] = {
+ .name = "Sitecom WL-105b",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 10},
+ },
+ .leds = {
+ { .name = "wlan", .gpio = 1 << 4},
+ { .name = "power", .gpio = 1 << 3},
+ },
+ },
+ /* Western Digital Net Center */
+ [WDNetCenter] = {
+ .name = "Western Digital NetCenter",
+ .buttons = {
+ { .name = "power", .gpio = 1 << 0},
+ { .name = "reset", .gpio = 1 << 7},
+ },
+ .platform_init = NetCenter_init,
+ },
+ /* Askey (and clones) */
+ [RT210W] = {
+ .name = "Askey RT210W",
+ .buttons = {
+ /* Power button is hard-wired to hardware reset */
+ /* but is also connected to GPIO 7 (probably for bootloader recovery) */
+ { .name = "power", .gpio = 1 << 7},
+ },
+ .leds = {
+ /* These were verified and named based on Belkin F5D4230-4 v1112 */
+ { .name = "connected", .gpio = 1 << 0, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 3, .polarity = REVERSE },
+ { .name = "power", .gpio = 1 << 5, .polarity = REVERSE },
+ },
+ },
+ [WL1600GL] = {
+ .name = "OvisLink WL-1600GL",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 3 },
+ { .name = "ses", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 5, .polarity = REVERSE },
+ { .name = "wps", .gpio = 1 << 2, .polarity = REVERSE },
+ { .name = "wlan", .gpio = 1 << 1, .polarity = REVERSE },
+ { .name = "connected", .gpio = 1 << 0, .polarity = REVERSE },
+ },
+ },
+ /* Microsoft */
+ [MN700] = {
+ .name = "Microsoft MN-700",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 7 },
+ },
+ .leds = {
+ { .name = "power", .gpio = 1 << 6, .polarity = NORMAL },
+ },
+ },
+ /* Edimax */
+ [PS1208MFG] = {
+ .name = "Edimax PS-1208MFG",
+ .buttons = {
+ { .name = "reset", .gpio = 1 << 4 },
+ },
+ .leds = {
+ { .name = "status", .gpio = 1 << 1, .polarity = NORMAL },
+ { .name = "wlan", .gpio = 1 << 0, .polarity = NORMAL },
+ },
+ },
+};
+
+static struct platform_t __init *platform_detect_legacy(void)
+{
+ char *boardnum, *boardtype, *buf;
+
+ if (strcmp(getvar("nvram_type"), "cfe") == 0)
+ return &platforms[WGT634U];
+
+
+ /* no easy model number, attempt to guess */
+ boardnum = getvar("boardnum");
+ boardtype = getvar("boardtype");
+
+ if (!strcmp(boardnum, "20070615")) { /* Linksys WRT600N v1/V1.1 */
+ if (!strcmp(boardtype, "0x478") && !strcmp(getvar("cardbus"), "0") && !strcmp(getvar("switch_type"),"BCM5395"))
+ return &platforms[WRT600NV11];
+
+ if (!strcmp(boardtype, "0x478") && !strcmp(getvar("cardbus"), "0"))
+ return &platforms[WRT600N];
+ }
+
+ if (startswith(getvar("pmon_ver"), "CFE")) {
+ /* CFE based - newer hardware */
+ if (!strcmp(boardnum, "42")) { /* Linksys */
+ if (!strcmp(boardtype, "0x478") && !strcmp(getvar("cardbus"), "1"))
+ return &platforms[WRT350N];
+
+ if (!strcmp(boardtype, "0x0101") && !strcmp(getvar("boot_ver"), "v3.6"))
+ return &platforms[WRT54G3G];
+
+ if (!strcmp(getvar("et1phyaddr"),"5") && !strcmp(getvar("et1mdcport"), "1"))
+ return &platforms[WRTSL54GS];
+
+ /* default to WRT54G */
+ return &platforms[WRT54G];
+ }
+ if (!strcmp(boardnum, "1024") && !strcmp(boardtype, "0x0446"))
+ return &platforms[WAP54GV2];
+
+ if (!strcmp(boardnum, "8") && !strcmp(boardtype, "0x048e"))
+ return &platforms[WL1600GL];
+
+
+ if (!strcmp(boardnum, "44") || !strcmp(boardnum, "44\r")) {
+ if (!strcmp(boardtype,"0x0101") || !strcmp(boardtype, "0x0101\r"))
+ return &platforms[TM2300V2]; /* Dell TrueMobile 2300 v2 */
+ }
+
+ if (!strcmp(boardnum, "45")) { /* ASUS */
+ if (!strcmp(boardtype,"0x0472"))
+ return &platforms[WL500W];
+ else if (!strcmp(boardtype,"0x467"))
+ return &platforms[WL320GE];
+ else
+ return &platforms[WL500GD];
+ }
+
+ if (!strcmp(boardnum, "10496"))
+ return &platforms[USR5461];
+
+ if (!strcmp(getvar("boardtype"), "0x0101") && !strcmp(getvar("boardrev"), "0x10")) /* SE505V2 With Modified CFE */
+ return &platforms[SE505V2];
+
+ if (!strcmp(boardtype, "0x048e") && !strcmp(getvar("boardrev"),"0x35") &&
+ !strcmp(getvar("boardflags"), "0x750")) /* D-Link DIR-320 */
+ return &platforms[DIR320];
+
+ if (!strncmp(boardnum, "TH",2) && !strcmp(boardtype,"0x042f")) {
+ return &platforms[WDNetCenter];
+ }
+
+ if (!strcmp(boardtype,"0x0472") && !strcmp(getvar("cardbus"), "1")) { /* Netgear WNR834B V1 and V2*/
+ if (!strcmp(boardnum, "08") || !strcmp(boardnum, "8"))
+ return &platforms[WNR834BV1];
+ if (!strcmp(boardnum, "01") || !strcmp(boardnum, "1"))
+ return &platforms[WNR834BV2];
+ }
+
+ } else { /* PMON based - old stuff */
+ if ((simple_strtoul(getvar("GemtekPmonVer"), NULL, 0) == 9) &&
+ (simple_strtoul(getvar("et0phyaddr"), NULL, 0) == 30)) {
+ return &platforms[WR850GV1];
+ }
+ if (startswith(boardtype, "bcm94710dev")) {
+ if (!strcmp(boardnum, "42"))
+ return &platforms[WRT54GV1];
+ if (simple_strtoul(boardnum, NULL, 0) == 2)
+ return &platforms[WAP54GV1];
+ }
+ /* MN-700 has also hardware_version 'WL500-...', so use boardnum */
+ if (startswith(getvar("hardware_version"), "WL500-")) {
+ if (!strcmp(getvar("boardnum"), "mn700"))
+ return &platforms[MN700];
+ else
+ return &platforms[WL500G];
+ }
+ if (startswith(getvar("hardware_version"), "WL300-")) {
+ /* Either WL-300g or WL-HDD, do more extensive checks */
+ if ((simple_strtoul(getvar("et0phyaddr"), NULL, 0) == 0) &&
+ (simple_strtoul(getvar("et1phyaddr"), NULL, 0) == 1))
+ return &platforms[WLHDD];
+ if ((simple_strtoul(getvar("et0phyaddr"), NULL, 0) == 0) &&
+ (simple_strtoul(getvar("et1phyaddr"), NULL, 0) == 10))
+ return &platforms[WL300G];
+ }
+ /* Sitecom WL-105b */
+ if (startswith(boardnum, "2") && simple_strtoul(getvar("GemtekPmonVer"), NULL, 0) == 1)
+ return &platforms[WL105B];
+
+ /* unknown asus stuff, probably bcm4702 */
+ if (startswith(boardnum, "asusX"))
+ return &platforms[ASUS_4702];
+
+ /* bcm4702 based Askey RT210W clones, Including:
+ * Askey RT210W (duh?)
+ * Siemens SE505v1
+ * Belkin F5D7230-4 before version v1444 (MiniPCI slot, not integrated)
+ */
+ if (!strcmp(boardtype,"bcm94710r4")
+ && !strcmp(boardnum ,"100")
+ && !strcmp(getvar("pmon_ver"),"v1.03.12.bk")
+ ){
+ return &platforms[RT210W];
+ }
+ }
+
+ if (buf || !strcmp(boardnum, "00")) {/* probably buffalo */
+ if (startswith(boardtype, "bcm94710ap"))
+ return &platforms[BUFFALO_UNKNOWN_4710];
+ else
+ return &platforms[BUFFALO_UNKNOWN];
+ }
+
+ if (startswith(getvar("CFEver"), "MotoWRv2") ||
+ startswith(getvar("CFEver"), "MotoWRv3") ||
+ !strcmp(getvar("MOTO_BOARD_TYPE"), "WR_FEM1")) {
+
+ return &platforms[WR850GV2V3];
+ }
+
+ if (!strcmp(boardnum, "44") && !strcmp(getvar("boardflags"),"0x0388")) { /* Trendware TEW-411BRP+ */
+ return &platforms[TEW411BRPP];
+ }
+
+ if (startswith(boardnum, "04FN")) /* SimpleTech SimpleShare */
+ return &platforms[STI_NAS];
+
+ if (!strcmp(boardnum, "10") && !strcmp(getvar("boardrev"), "0x13")) /* D-Link DWL-3150 */
+ return &platforms[DWL3150];
+
+ if (!strcmp(boardnum, "01") && !strcmp(boardtype, "0x048e") && /* Edimax PS1208MFG */
+ !strcmp(getvar("status_gpio"), "1")) /* gpio based detection */
+ return &platforms[PS1208MFG];
+
+ /* not found */
+ return NULL;
+}
+
+static struct platform_t __init *platform_detect(void)
+{
+ enum bcm47xx_board board;
+ const char *board_name;
+
+
+ board = bcm47xx_board_get();
+ board_name = bcm47xx_board_get_name();
+ if (board != BCM47XX_BOARD_UNKNOWN && board != BCM47XX_BOARD_NON)
+ printk(MODULE_NAME ": kernel found a \"%s\"\n", board_name);
+
+ switch(board) {
+ case BCM47XX_BOARD_ASUS_RTN16:
+ return &platforms[RTN16];
+ case BCM47XX_BOARD_ASUS_WL330GE:
+ return &platforms[WL330GE];
+ case BCM47XX_BOARD_ASUS_WL500GPV1:
+ return &platforms[WL500GP];
+ case BCM47XX_BOARD_ASUS_WL500GPV2:
+ return &platforms[WL500GPV2];
+ case BCM47XX_BOARD_ASUS_WL520GC:
+ return &platforms[WL520GC];
+ case BCM47XX_BOARD_ASUS_WL520GU:
+ return &platforms[WL520GU];
+ case BCM47XX_BOARD_ASUS_WL700GE:
+ return &platforms[WL700GE];
+ case BCM47XX_BOARD_BELKIN_F7D4301:
+ return &platforms[BELKIN_F7D4301];
+ case BCM47XX_BOARD_BUFFALO_WBR2_G54:
+ return &platforms[WBR2_G54];
+ case BCM47XX_BOARD_BUFFALO_WHR2_A54G54:
+ return &platforms[WHR2_A54G54];
+ case BCM47XX_BOARD_BUFFALO_WHR_G125:
+ return &platforms[WHR_G125];
+ case BCM47XX_BOARD_BUFFALO_WHR_G54S:
+ return &platforms[WHR_G54S];
+ case BCM47XX_BOARD_BUFFALO_WHR_HP_G54:
+ return &platforms[WHR_HP_G54];
+ case BCM47XX_BOARD_BUFFALO_WLA2_G54L:
+ return &platforms[WLA2_G54L];
+ case BCM47XX_BOARD_BUFFALO_WZR_G300N:
+ return &platforms[WZR_G300N];
+ case BCM47XX_BOARD_BUFFALO_WZR_RS_G54:
+ return &platforms[WZR_RS_G54];
+ case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP:
+ return &platforms[WZR_RS_G54HP];
+ case BCM47XX_BOARD_DELL_TM2300:
+ return &platforms[TM2300];
+ case BCM47XX_BOARD_DLINK_DIR130:
+ return &platforms[DIR130];
+ case BCM47XX_BOARD_DLINK_DIR330:
+ return &platforms[DIR330];
+ case BCM47XX_BOARD_LINKSYS_E1000V1:
+ return &platforms[E1000V1];
+ case BCM47XX_BOARD_LINKSYS_E3000V1:
+ return &platforms[E3000V1];
+ case BCM47XX_BOARD_LINKSYS_E3200V1:
+ return &platforms[E3200V1];
+ case BCM47XX_BOARD_LINKSYS_WRT150NV1:
+ return &platforms[WRT150NV1];
+ case BCM47XX_BOARD_LINKSYS_WRT150NV11:
+ return &platforms[WRT150NV11];
+ case BCM47XX_BOARD_LINKSYS_WRT160NV1:
+ return &platforms[WRT160NV1];
+ case BCM47XX_BOARD_LINKSYS_WRT160NV3:
+ return &platforms[WRT160NV3];
+ case BCM47XX_BOARD_LINKSYS_WRT300NV11:
+ return &platforms[WRT300NV11];
+ case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
+ return &platforms[WRT54G3GV2_VF];
+ case BCM47XX_BOARD_LINKSYS_WRT610NV1:
+ return &platforms[WRT610N];
+ case BCM47XX_BOARD_LINKSYS_WRT610NV2:
+ return &platforms[WRT610NV2];
+ case BCM47XX_BOARD_MOTOROLA_WE800G:
+ return &platforms[WE800G];
+ case BCM47XX_BOARD_MOTOROLA_WR850GP:
+ return &platforms[WR850GP];
+ case BCM47XX_BOARD_MOTOROLA_WR850GV2V3:
+ return &platforms[WR850GV2V3];
+ case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
+ return &platforms[WNDR3400V1];
+ case BCM47XX_BOARD_NETGEAR_WNDR3700V3:
+ return &platforms[WNDR3700V3];
+ case BCM47XX_BOARD_UNKNOWN:
+ case BCM47XX_BOARD_NON:
+ printk(MODULE_NAME ": unknown board found, try legacy detect\n");
+ printk(MODULE_NAME ": please open a ticket at https://dev.openwrt.org and attach the complete nvram\n");
+ return platform_detect_legacy();
+ default:
+ printk(MODULE_NAME ": board was detected as \"%s\", but not gpio configuration available\n", board_name);
+ printk(MODULE_NAME ": now trying legacy detect\n");
+ return platform_detect_legacy();
+ }
+}
+
+static inline void ssb_maskset32(struct ssb_device *dev,
+ u16 offset, u32 mask, u32 set)
+{
+ ssb_write32(dev, offset, (ssb_read32(dev, offset) & mask) | set);
+}
+
+static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *))
+{
+ int irq;
+
+ irq = gpio_to_irq(0);
+ if (irq == -EINVAL) return;
+
+ if (enabled) {
+ if (request_irq(irq, handler, IRQF_SHARED, "gpio", handler))
+ return;
+ } else {
+ free_irq(irq, handler);
+ }
+
+ switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+ case BCM47XX_BUS_TYPE_SSB:
+ if (bcm47xx_bus.ssb.chipco.dev)
+ ssb_maskset32(bcm47xx_bus.ssb.chipco.dev, SSB_CHIPCO_IRQMASK, ~SSB_CHIPCO_IRQ_GPIO, (enabled ? SSB_CHIPCO_IRQ_GPIO : 0));
+ break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+ case BCM47XX_BUS_TYPE_BCMA:
+ if (bcm47xx_bus.bcma.bus.drv_cc.core)
+ bcma_maskset32(bcm47xx_bus.bcma.bus.drv_cc.core, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO, (enabled ? BCMA_CC_IRQ_GPIO : 0));
+ break;
+#endif
+ }
+}
+
+static void register_buttons(struct button_t *b)
+{
+ for (; b->name; b++)
+ platform.button_mask |= b->gpio;
+
+ platform.button_mask &= ~gpiomask;
+
+ bcm47xx_gpio_outen(platform.button_mask, 0);
+ bcm47xx_gpio_control(platform.button_mask, 0);
+ platform.button_polarity = bcm47xx_gpio_in(~0) & platform.button_mask;
+ bcm47xx_gpio_polarity(platform.button_mask, platform.button_polarity);
+ bcm47xx_gpio_intmask(platform.button_mask, platform.button_mask);
+
+ gpio_set_irqenable(1, button_handler);
+}
+
+static void unregister_buttons(struct button_t *b)
+{
+ bcm47xx_gpio_intmask(platform.button_mask, 0);
+
+ gpio_set_irqenable(0, button_handler);
+}
+
+
+static void add_msg(struct event_t *event, char *msg, int argv)
+{
+ char *s;
+
+ if (argv)
+ return;
+
+ s = skb_put(event->skb, strlen(msg) + 1);
+ strcpy(s, msg);
+}
+
+static void hotplug_button(struct work_struct *work)
+{
+ struct event_t *event = container_of(work, struct event_t, wq);
+ char *s;
+
+ event->skb = alloc_skb(2048, GFP_KERNEL);
+
+ s = skb_put(event->skb, strlen(event->action) + 2);
+ sprintf(s, "%s@", event->action);
+ fill_event(event);
+
+ NETLINK_CB(event->skb).dst_group = 1;
+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
+
+ kfree(event);
+}
+
+
+static int fill_event (struct event_t *event)
+{
+ static char buf[128];
+
+ add_msg(event, "HOME=/", 0);
+ add_msg(event, "PATH=/sbin:/bin:/usr/sbin:/usr/bin", 0);
+ add_msg(event, "SUBSYSTEM=button", 0);
+ snprintf(buf, 128, "ACTION=%s", event->action);
+ add_msg(event, buf, 0);
+ snprintf(buf, 128, "BUTTON=%s", event->name);
+ add_msg(event, buf, 0);
+ snprintf(buf, 128, "SEEN=%ld", event->seen);
+ add_msg(event, buf, 0);
+ snprintf(buf, 128, "SEQNUM=%llu", uevent_next_seqnum());
+ add_msg(event, buf, 0);
+
+ return 0;
+}
+
+
+static irqreturn_t button_handler(int irq, void *dev_id)
+{
+ struct button_t *b;
+ u32 in, changed;
+
+ in = bcm47xx_gpio_in(~0) & platform.button_mask;
+ bcm47xx_gpio_polarity(platform.button_mask, in);
+ changed = platform.button_polarity ^ in;
+ platform.button_polarity = in;
+
+ changed &= ~bcm47xx_gpio_outen(0, 0);
+
+ for (b = platform.buttons; b->name; b++) {
+ struct event_t *event;
+
+ if (!(b->gpio & changed)) continue;
+
+ b->pressed ^= 1;
+
+ if ((event = (struct event_t *)kzalloc (sizeof(struct event_t), GFP_ATOMIC))) {
+ event->seen = (jiffies - b->seen)/HZ;
+ event->name = b->name;
+ event->action = b->pressed ? "pressed" : "released";
+ INIT_WORK(&event->wq, (void *)(void *)hotplug_button);
+ schedule_work(&event->wq);
+ }
+
+ b->seen = jiffies;
+ }
+ return IRQ_HANDLED;
+}
+
+static void register_leds(struct led_t *l)
+{
+ struct proc_dir_entry *p;
+ u32 mask = 0;
+ u32 oe_mask = 0;
+ u32 val = 0;
+
+ leds = proc_mkdir("led", diag);
+ if (!leds)
+ return;
+
+ for(; l->name; l++) {
+ if (l->gpio & gpiomask)
+ continue;
+
+ switch (l->gpio & GPIO_TYPE_MASK) {
+ case GPIO_TYPE_EXTIF:
+ l->state = 0;
+ set_led_extif(l);
+ break;
+ case GPIO_TYPE_SHIFT:
+ mask |= (SHIFTREG_DATA | SHIFTREG_CLK);
+ oe_mask |= (SHIFTREG_DATA | SHIFTREG_CLK);
+ l->state = (l->polarity != NORMAL);
+ set_led_shift(l);
+ break;
+ case GPIO_TYPE_NORMAL:
+ default:
+ if (l->polarity != INPUT) oe_mask |= l->gpio;
+ mask |= l->gpio;
+ val |= (l->polarity == NORMAL)?0:l->gpio;
+ break;
+ }
+
+ if (l->polarity == INPUT) continue;
+
+ if ((p = create_proc_entry(l->name, S_IRUSR, leds))) {
+ l->proc.type = PROC_LED;
+ l->proc.ptr = l;
+ p->data = (void *) &l->proc;
+ p->proc_fops = &diag_proc_fops;
+ }
+ }
+
+ bcm47xx_gpio_outen(mask, oe_mask);
+ bcm47xx_gpio_control(mask, 0);
+ bcm47xx_gpio_out(mask, val);
+ bcm47xx_gpio_intmask(mask, 0);
+}
+
+static void unregister_leds(struct led_t *l)
+{
+ for(; l->name; l++)
+ remove_proc_entry(l->name, leds);
+
+ remove_proc_entry("led", diag);
+}
+
+static void set_led_extif(struct led_t *led)
+{
+ volatile u8 *addr = (volatile u8 *) KSEG1ADDR(EXTIF_UART) + (led->gpio & ~GPIO_TYPE_MASK);
+ if (led->state)
+ *addr = 0xFF;
+ else
+ *addr;
+}
+
+/*
+ * This should be extended to allow the platform to specify the pins and width
+ * of the shift register. They're hardcoded for now because only the WNDR3700v3
+ * uses it.
+ */
+static void shiftreg_output(unsigned int val)
+{
+ unsigned int mask;
+
+ bcm47xx_gpio_out(SHIFTREG_DATA, SHIFTREG_DATA); /* init off, pull high */
+ bcm47xx_gpio_out(SHIFTREG_CLK, 0); /* init reset */
+
+ /* shift 8 times */
+ for(mask = 1 << (SHIFTREG_MAX_BITS-1); mask; mask >>= 1)
+ {
+ bcm47xx_gpio_out(SHIFTREG_DATA, (val & mask) ? SHIFTREG_DATA : 0);
+ bcm47xx_gpio_out(SHIFTREG_CLK, SHIFTREG_CLK); /* pull high to trigger */
+ bcm47xx_gpio_out(SHIFTREG_CLK, 0); /* reset to low */
+ }
+}
+
+static void set_led_shift(struct led_t *led)
+{
+ static u32 shiftreg = 0;
+ u32 old = shiftreg;
+ u32 pin = (led->gpio & ~GPIO_TYPE_MASK);
+
+ if (led->state) {
+ shiftreg |= pin;
+ } else {
+ shiftreg &= ~pin;
+ }
+
+ /* Clock the bits out. */
+ if (shiftreg != old) {
+ shiftreg_output(shiftreg);
+ }
+}
+
+
+static void led_flash(unsigned long dummy) {
+ struct led_t *l;
+ u32 mask = 0;
+ u8 extif_blink = 0;
+
+ for (l = platform.leds; l->name; l++) {
+ if (!l->flash) continue;
+ switch (l->gpio & GPIO_TYPE_MASK) {
+ case GPIO_TYPE_EXTIF:
+ extif_blink = 1;
+ l->state = !l->state;
+ set_led_extif(l);
+ break;
+ case GPIO_TYPE_SHIFT:
+ extif_blink = 1;
+ l->state = !l->state;
+ set_led_shift(l);
+ break;
+ case GPIO_TYPE_NORMAL:
+ default:
+ mask |= l->gpio;
+ break;
+ }
+ }
+
+ mask &= ~gpiomask;
+ if (mask) {
+ u32 val = ~bcm47xx_gpio_in(~0);
+
+ bcm47xx_gpio_outen(mask, mask);
+ bcm47xx_gpio_control(mask, 0);
+ bcm47xx_gpio_out(mask, val);
+ }
+ if (mask || extif_blink) {
+ mod_timer(&led_timer, jiffies + FLASH_TIME);
+ }
+}
+
+static ssize_t diag_proc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+ struct proc_dir_entry *dent = PDE(file->f_dentry->d_inode);
+ char *page;
+ int len = 0;
+
+ if ((page = kmalloc(1024, GFP_KERNEL)) == NULL)
+ return -ENOBUFS;
+
+ if (dent->data != NULL) {
+ struct prochandler_t *handler = (struct prochandler_t *) dent->data;
+ switch (handler->type) {
+ case PROC_LED: {
+ struct led_t * led = (struct led_t *) handler->ptr;
+ u8 p = (led->polarity == NORMAL ? 0 : 1);
+ if (led->flash) {
+ len = sprintf(page, "f\n");
+ } else if ((led->gpio & GPIO_TYPE_MASK) != GPIO_TYPE_NORMAL) {
+ len = sprintf(page, "%d\n", ((led->state ^ p) ? 1 : 0));
+ } else {
+ u32 in = (bcm47xx_gpio_in(~0) & led->gpio ? 1 : 0);
+ len = sprintf(page, "%d\n", ((in ^ p) ? 1 : 0));
+ }
+ break;
+ }
+ case PROC_MODEL:
+ len = sprintf(page, "%s\n", platform.name);
+ break;
+ case PROC_GPIOMASK:
+ len = sprintf(page, "0x%04x\n", gpiomask);
+ break;
+ }
+ }
+ len += 1;
+
+ if (*ppos < len) {
+ len = min_t(int, len - *ppos, count);
+ if (copy_to_user(buf, (page + *ppos), len)) {
+ kfree(page);
+ return -EFAULT;
+ }
+ *ppos += len;
+ } else {
+ len = 0;
+ }
+
+ kfree(page);
+ return len;
+}
+
+
+static ssize_t diag_proc_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+ struct proc_dir_entry *dent = PDE(file->f_dentry->d_inode);
+ char *page;
+ int ret = -EINVAL;
+
+ if ((page = kmalloc(count + 1, GFP_KERNEL)) == NULL)
+ return -ENOBUFS;
+
+ if (copy_from_user(page, buf, count)) {
+ kfree(page);
+ return -EINVAL;
+ }
+ page[count] = 0;
+
+ if (dent->data != NULL) {
+ struct prochandler_t *handler = (struct prochandler_t *) dent->data;
+ switch (handler->type) {
+ case PROC_LED: {
+ struct led_t *led = (struct led_t *) handler->ptr;
+ int p = (led->polarity == NORMAL ? 0 : 1);
+
+ if (page[0] == 'f') {
+ led->flash = 1;
+ led_flash(0);
+ } else {
+ led->flash = 0;
+ if ((led->gpio & GPIO_TYPE_MASK) == GPIO_TYPE_EXTIF) {
+ led->state = p ^ ((page[0] == '1') ? 1 : 0);
+ set_led_extif(led);
+ } else if ((led->gpio & GPIO_TYPE_MASK) == GPIO_TYPE_SHIFT) {
+ led->state = p ^ ((page[0] == '1') ? 1 : 0);
+ set_led_shift(led);
+ } else {
+ bcm47xx_gpio_outen(led->gpio, led->gpio);
+ bcm47xx_gpio_control(led->gpio, 0);
+ bcm47xx_gpio_out(led->gpio, ((p ^ (page[0] == '1')) ? led->gpio : 0));
+ }
+ }
+ break;
+ }
+ case PROC_GPIOMASK:
+ gpiomask = simple_strtoul(page, NULL, 0);
+
+ if (platform.buttons) {
+ unregister_buttons(platform.buttons);
+ register_buttons(platform.buttons);
+ }
+
+ if (platform.leds) {
+ unregister_leds(platform.leds);
+ register_leds(platform.leds);
+ }
+ break;
+ }
+ ret = count;
+ }
+
+ kfree(page);
+ return ret;
+}
+
+static int __init diag_init(void)
+{
+ static struct proc_dir_entry *p;
+ static struct platform_t *detected;
+
+ detected = platform_detect();
+ if (!detected) {
+ printk(MODULE_NAME ": Router model not detected.\n");
+ return -ENODEV;
+ }
+ memcpy(&platform, detected, sizeof(struct platform_t));
+
+ printk(MODULE_NAME ": Detected '%s'\n", platform.name);
+ if (platform.platform_init != NULL) {
+ platform.platform_init();
+ }
+
+ if (!(diag = proc_mkdir("diag", NULL))) {
+ printk(MODULE_NAME ": proc_mkdir on /proc/diag failed\n");
+ return -EINVAL;
+ }
+
+ if ((p = create_proc_entry("model", S_IRUSR, diag))) {
+ p->data = (void *) &proc_model;
+ p->proc_fops = &diag_proc_fops;
+ }
+
+ if ((p = create_proc_entry("gpiomask", S_IRUSR | S_IWUSR, diag))) {
+ p->data = (void *) &proc_gpiomask;
+ p->proc_fops = &diag_proc_fops;
+ }
+
+ if (platform.buttons)
+ register_buttons(platform.buttons);
+
+ if (platform.leds)
+ register_leds(platform.leds);
+
+ return 0;
+}
+
+static void __exit diag_exit(void)
+{
+ del_timer(&led_timer);
+
+ if (platform.buttons)
+ unregister_buttons(platform.buttons);
+
+ if (platform.leds)
+ unregister_leds(platform.leds);
+
+ remove_proc_entry("model", diag);
+ remove_proc_entry("gpiomask", diag);
+ remove_proc_entry("diag", NULL);
+}
+
+module_init(diag_init);
+module_exit(diag_exit);
+
+MODULE_AUTHOR("Mike Baker, Felix Fietkau / OpenWrt.org");
+MODULE_LICENSE("GPL");
diff --git a/package/kernel/broadcom-diag/src/diag.h b/package/kernel/broadcom-diag/src/diag.h
new file mode 100644
index 0000000000..d9b5b006fe
--- /dev/null
+++ b/package/kernel/broadcom-diag/src/diag.h
@@ -0,0 +1,135 @@
+/*
+ * diag.h - GPIO interface driver for Broadcom boards
+ *
+ * Copyright (C) 2006 Mike Baker <mbm@openwrt.org>,
+ * Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/irq.h>
+#define MODULE_NAME "diag"
+
+#define MAX_GPIO 16
+#define FLASH_TIME HZ/6
+
+enum polarity_t {
+ REVERSE = 0,
+ NORMAL = 1,
+ INPUT = 2,
+};
+
+enum {
+ PROC_BUTTON,
+ PROC_LED,
+ PROC_MODEL,
+ PROC_GPIOMASK
+};
+
+struct prochandler_t {
+ int type;
+ void *ptr;
+};
+
+struct button_t {
+ struct prochandler_t proc;
+ char *name;
+ u32 gpio;
+ unsigned long seen;
+ u8 pressed;
+};
+
+struct led_t {
+ struct prochandler_t proc;
+ char *name;
+ u32 gpio;
+ u8 polarity;
+ u8 flash;
+ u8 state;
+};
+
+struct platform_t {
+ char *name;
+
+ struct button_t buttons[MAX_GPIO];
+ u32 button_mask;
+ u32 button_polarity;
+ void (*platform_init)(void);
+
+ struct led_t leds[MAX_GPIO];
+};
+
+struct event_t {
+ struct work_struct wq;
+ unsigned long seen;
+ char *name, *action;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+ struct sk_buff *skb;
+#else
+ char *scratch;
+ char *argv[4];
+ char *envp[7];
+ u8 enr, anr;
+#endif
+};
+
+extern char *nvram_get(char *str);
+
+static struct platform_t platform;
+
+/* buttons */
+
+static void register_buttons(struct button_t *b);
+static void unregister_buttons(struct button_t *b);
+
+static void hotplug_button(struct work_struct *work);
+static irqreturn_t button_handler(int irq, void *dev_id);
+
+/* leds */
+
+static void register_leds(struct led_t *l);
+static void unregister_leds(struct led_t *l);
+
+static void set_led_extif(struct led_t *led);
+static void set_led_shift(struct led_t *led);
+static void led_flash(unsigned long dummy);
+
+/* 2.4 compatibility */
+#ifndef TIMER_INITIALIZER
+#define TIMER_INITIALIZER(_function, _expires, _data) \
+ { \
+ /* _expires and _data currently unused */ \
+ function: _function \
+ }
+#endif
+
+static struct timer_list led_timer = TIMER_INITIALIZER(&led_flash, 0, 0);
+
+/* proc */
+
+static struct proc_dir_entry *diag, *leds;
+
+static ssize_t diag_proc_read(struct file *file, char *buf, size_t count, loff_t *ppos);
+static ssize_t diag_proc_write(struct file *file, const char *buf, size_t count, loff_t *ppos);
+
+static struct file_operations diag_proc_fops = {
+ read: diag_proc_read,
+ write: diag_proc_write
+};
+
+static struct prochandler_t proc_model = { .type = PROC_MODEL };
+static struct prochandler_t proc_gpiomask = { .type = PROC_GPIOMASK };
+
diff --git a/package/kernel/broadcom-diag/src/gpio.h b/package/kernel/broadcom-diag/src/gpio.h
new file mode 100644
index 0000000000..8bd3fe02f8
--- /dev/null
+++ b/package/kernel/broadcom-diag/src/gpio.h
@@ -0,0 +1,22 @@
+#ifndef __DIAG_GPIO_H
+#define __DIAG_GPIO_H
+
+#include <linux/interrupt.h>
+#include <linux/ssb/ssb_embedded.h>
+#include <linux/gpio.h>
+#include <bcm47xx.h>
+
+#define EXTIF_ADDR 0x1f000000
+#define EXTIF_UART (EXTIF_ADDR + 0x00800000)
+
+/* GPIO pins driving LEDs through a shift register */
+#define SHIFTREG_DATA (1 << 6)
+#define SHIFTREG_CLK (1 << 7)
+#define SHIFTREG_MAX_BITS 8
+
+#define GPIO_TYPE_NORMAL (0x0 << 24)
+#define GPIO_TYPE_EXTIF (0x1 << 24)
+#define GPIO_TYPE_SHIFT (0x2 << 24)
+#define GPIO_TYPE_MASK (0xf << 24)
+
+#endif /* __DIAG_GPIO_H */
diff --git a/package/kernel/broadcom-wl/Makefile b/package/kernel/broadcom-wl/Makefile
new file mode 100644
index 0000000000..1a7da0f89d
--- /dev/null
+++ b/package/kernel/broadcom-wl/Makefile
@@ -0,0 +1,175 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=broadcom-wl
+PKG_VERSION:=5.10.56.27.3
+PKG_RELEASE:=5
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(ARCH).tar.bz2
+PKG_SOURCE_URL:=http://downloads.openwrt.org/sources
+
+PKG_MD5SUM.mipsel:=3363e3a6b3d9d73c49dea870c7834eac
+PKG_MD5SUM.mips:=f8de63debc75333d6b4e28193eb051ff
+PKG_MD5SUM:=$(PKG_MD5SUM.$(ARCH))
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/broadcom-wl/Default
+ SECTION:=kernel
+ CATEGORY:=Kernel modules
+ DEPENDS:=@PACKAGE_kmod-brcm-wl||PACKAGE_kmod-brcm-wl-mini
+ SUBMENU:=Proprietary BCM43xx WiFi driver
+ SUBMENUDEP:=@TARGET_brcm47xx||TARGET_brcm63xx
+endef
+
+define KernelPackage/brcm-wl/Default
+ $(call Package/broadcom-wl/Default)
+ SECTION:=kernel
+ DEPENDS:=@TARGET_brcm47xx||TARGET_brcm63xx +wireless-tools
+ TITLE:=Kernel driver for BCM43xx chipsets
+ FILES:=$(PKG_BUILD_DIR)/driver$(1)/wl.ko $(PKG_BUILD_DIR)/glue/wl_glue.ko
+ AUTOLOAD:=$(call AutoLoad,30,wl_glue wl)
+endef
+
+define KernelPackage/brcm-wl/Default/description
+ This package contains the proprietary wireless driver for the Broadcom
+ BCM43xx chipset.
+endef
+
+define KernelPackage/brcm-wl
+$(call KernelPackage/brcm-wl/Default,)
+ TITLE+= (normal version)
+endef
+
+define KernelPackage/brcm-wl/description
+$(call KernelPackage/brcm-wl/Default/description)
+endef
+
+define KernelPackage/brcm-wl-mini
+$(call KernelPackage/brcm-wl/Default,-mini)
+ TITLE+= (Legacy version)
+endef
+
+define KernelPackage/brcm-wl-mini/description
+$(call KernelPackage/brcm-wl/Default/description)
+endef
+
+define Package/wlc
+$(call Package/broadcom-wl/Default)
+ TITLE:=wl driver setup utility
+endef
+
+define Package/wlc/description
+ This package contains an utility for initializing the proprietary Broadcom
+ wl driver.
+endef
+
+define Package/wl
+$(call Package/broadcom-wl/Default)
+ TITLE:=Proprietary Broadcom wl driver config utility
+endef
+
+define Package/wl/description
+ This package contains the proprietary utility (wl) for configuring the
+ proprietary Broadcom wl driver.
+endef
+
+define Package/nas
+$(call Package/broadcom-wl/Default)
+ TITLE:=Proprietary Broadcom WPA/WPA2 authenticator
+endef
+
+define Package/nas/description
+ This package contains the proprietary WPA/WPA2 authenticator (nas) for the
+ proprietary Broadcom wl driver.
+endef
+
+MAKE_KMOD := $(MAKE) -C "$(LINUX_DIR)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ ARCH="$(LINUX_KARCH)" \
+ PATH="$(TARGET_PATH)" \
+ SUBDIRS="$(PKG_BUILD_DIR)/kmod" \
+
+define Build/Prepare
+ $(call Build/Prepare/Default)
+ $(CP) $(PKG_BUILD_DIR)/driver $(PKG_BUILD_DIR)/driver-mini
+ $(CP) ./src/glue $(PKG_BUILD_DIR)/glue
+endef
+
+define Build/Compile
+ # Compile the kernel part
+ $(MAKE_KMOD) \
+ SUBDIRS="$(PKG_BUILD_DIR)/driver" \
+ MODFLAGS="-DMODULE -mlong-calls" \
+ modules
+
+ $(MAKE_KMOD) \
+ SUBDIRS="$(PKG_BUILD_DIR)/driver-mini" \
+ MODFLAGS="-DMODULE -mlong-calls" \
+ BUILD_TYPE="wl_apsta_mini" \
+ modules
+
+ # Compile glue driver
+ $(MAKE_KMOD) -C "$(LINUX_DIR)" \
+ SUBDIRS="$(PKG_BUILD_DIR)/glue" \
+ modules
+
+ # Compile libshared
+ $(MAKE) -C $(PKG_BUILD_DIR)/shared \
+ $(TARGET_CONFIGURE_OPTS) \
+ CFLAGS="$(TARGET_CFLAGS) -I. -I$(PKG_BUILD_DIR)/driver/include" \
+ all
+
+ $(TARGET_CC) -o $(PKG_BUILD_DIR)/wlc \
+ -I$(PKG_BUILD_DIR)/shared -I$(PKG_BUILD_DIR)/driver/include \
+ ./src/wlc.c $(PKG_BUILD_DIR)/shared/libshared.a
+
+ $(TARGET_CC) -o $(PKG_BUILD_DIR)/nas \
+ $(PKG_BUILD_DIR)/nas_exe.o \
+ $(PKG_BUILD_DIR)/shared/libshared.a
+
+ $(TARGET_CC) -o $(PKG_BUILD_DIR)/wl \
+ $(PKG_BUILD_DIR)/wl_exe.o \
+ $(PKG_BUILD_DIR)/shared/libshared.a
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/shared/libshared.a $(1)/usr/lib/
+endef
+
+define Package/wlc/install
+ $(CP) ./files/* $(1)/
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/wlc $(1)/sbin/
+endef
+
+define Package/wlc/postinst
+#!/bin/sh
+[ -n "$${IPKG_INSTROOT}" ] || /etc/init.d/wlunbind enable || true
+endef
+
+define Package/wl/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/wl $(1)/usr/sbin/
+endef
+
+define Package/nas/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/nas $(1)/usr/sbin/
+ ln -sf nas $(1)/usr/sbin/nas4not
+ ln -sf nas $(1)/usr/sbin/nas4wds
+endef
+
+$(eval $(call KernelPackage,brcm-wl))
+$(eval $(call KernelPackage,brcm-wl-mini))
+$(eval $(call BuildPackage,wlc))
+$(eval $(call BuildPackage,wl))
+$(eval $(call BuildPackage,nas))
diff --git a/package/kernel/broadcom-wl/files/etc/hotplug.d/net/20-broadcom_wds b/package/kernel/broadcom-wl/files/etc/hotplug.d/net/20-broadcom_wds
new file mode 100644
index 0000000000..0a563c2dbd
--- /dev/null
+++ b/package/kernel/broadcom-wl/files/etc/hotplug.d/net/20-broadcom_wds
@@ -0,0 +1,61 @@
+include /lib/wifi
+
+setup_broadcom_wds() {
+ local iface="$1"
+ local remote="$(wlc ifname "$iface" wdsmac)"
+
+ [ -z "$remote" ] && return
+
+ config_cb() {
+ [ -z "$CONFIG_SECTION" ] && return
+
+ config_get type "$CONFIG_SECTION" TYPE
+ [ "$type" = "wifi-iface" ] || return
+
+ config_get network "$CONFIG_SECTION" network
+ [ -z "$network" ] && return
+
+ config_get addr "$CONFIG_SECTION" bssid
+ addr=$(echo "$addr" | tr 'A-F' 'a-f')
+ [ "$addr" = "$remote" ] && {
+ local cfg="$CONFIG_SECTION"
+
+ include /lib/network
+ scan_interfaces
+
+ for network in $network; do
+ setup_interface "$iface" "$network"
+ done
+
+ config_get encryption "$cfg" encryption
+ config_get key "$cfg" key
+ config_get ssid "$cfg" ssid
+
+ [ "$encryption" != "none" ] && {
+ sleep 5
+ case "$encryption" in
+ psk|PSK)
+ nas4not "$network" "$iface" up auto tkip psk "$key" "$ssid"
+ ;;
+ psk2|PSK2)
+ nas4not "$network" "$iface" up auto aes psk "$key" "$ssid"
+ ;;
+ psk+psk2|psk2+psk|PSK+PSK2|PSK2+PSK)
+ nas4not "$network" "$iface" up auto aes+tkip psk "$key" "$ssid"
+ ;;
+ *)
+ nas4not lan "$iface" up auto aes "$encryption" "$key" "$ssid"
+ ;;
+ esac
+ }
+ }
+ }
+
+ config_load wireless
+}
+
+case "$ACTION" in
+ add|register)
+ [ "${INTERFACE%%0.*}" = wds ] && setup_broadcom_wds "$INTERFACE"
+ ;;
+esac
diff --git a/package/kernel/broadcom-wl/files/etc/init.d/wlunbind b/package/kernel/broadcom-wl/files/etc/init.d/wlunbind
new file mode 100755
index 0000000000..0a29db565f
--- /dev/null
+++ b/package/kernel/broadcom-wl/files/etc/init.d/wlunbind
@@ -0,0 +1,29 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2010-2011 OpenWrt.org
+
+START=09
+
+unbind_driver() {
+ local driver="$1"
+ local sysfs="/sys/bus/pci/drivers/$driver"
+ if [ -d "$sysfs" ]; then
+ local lnk
+ for lnk in $sysfs/*; do
+ [ -h "$lnk" ] || continue
+ case "${lnk##*/}" in
+ *:*:*.*)
+ logger "Unbinding WL PCI device ${lnk##*/} from $driver"
+ echo -n "${lnk##*/}" > "$sysfs/unbind"
+ ;;
+ esac
+ done
+ fi
+}
+
+boot() {
+ unbind_driver b43-pci-bridge
+ unbind_driver bcma-pci-bridge
+}
+
+start() { :; }
+stop() { :; }
diff --git a/package/kernel/broadcom-wl/files/lib/wifi/broadcom.sh b/package/kernel/broadcom-wl/files/lib/wifi/broadcom.sh
new file mode 100644
index 0000000000..72b85aaf88
--- /dev/null
+++ b/package/kernel/broadcom-wl/files/lib/wifi/broadcom.sh
@@ -0,0 +1,395 @@
+append DRIVERS "broadcom"
+
+scan_broadcom() {
+ local device="$1"
+ local wds
+ local adhoc sta apmode mon disabled
+ local adhoc_if sta_if ap_if mon_if
+ local _c=0
+
+ config_get vifs "$device" vifs
+ for vif in $vifs; do
+ config_get_bool disabled "$vif" disabled 0
+ [ $disabled -eq 0 ] || continue
+
+ config_get mode "$vif" mode
+ _c=$(($_c + 1))
+ case "$mode" in
+ adhoc)
+ adhoc=1
+ adhoc_if="$vif"
+ ;;
+ sta)
+ sta=1
+ sta_if="$vif"
+ ;;
+ ap)
+ apmode=1
+ ap_if="${ap_if:+$ap_if }$vif"
+ ;;
+ wds)
+ config_get addr "$vif" bssid
+ [ -z "$addr" ] || {
+ addr=$(echo "$addr" | tr 'A-F' 'a-f')
+ append wds "$addr"
+ }
+ ;;
+ monitor)
+ mon=1
+ mon_if="$vif"
+ ;;
+ *) echo "$device($vif): Invalid mode";;
+ esac
+ done
+ config_set "$device" wds "$wds"
+
+ local _c=
+ for vif in ${adhoc_if:-$sta_if $ap_if $mon_if}; do
+ config_set "$vif" ifname "${device}${_c:+.$_c}"
+ _c=$((${_c:-0} + 1))
+ done
+ config_set "$device" vifs "${adhoc_if:-$sta_if $ap_if $mon_if}"
+
+ ifdown="down"
+ for vif in 0 1 2 3; do
+ append ifdown "vif $vif" "$N"
+ append ifdown "enabled 0" "$N"
+ done
+
+ ap=1
+ infra=1
+ if [ "$_c" -gt 1 ]; then
+ mssid=1
+ else
+ mssid=
+ fi
+ apsta=0
+ radio=1
+ monitor=0
+ case "$adhoc:$sta:$apmode:$mon" in
+ 1*)
+ ap=0
+ mssid=
+ infra=0
+ ;;
+ :1:1:)
+ apsta=1
+ wet=1
+ ;;
+ :1::)
+ wet=1
+ ap=0
+ mssid=
+ ;;
+ :::1)
+ wet=1
+ ap=0
+ mssid=
+ monitor=1
+ ;;
+ ::)
+ radio=0
+ ;;
+ esac
+}
+
+disable_broadcom() {
+ local device="$1"
+ set_wifi_down "$device"
+ wlc ifname "$device" down
+ wlc ifname "$device" bssid `wlc ifname "$device" default_bssid`
+ (
+ include /lib/network
+
+ # make sure the interfaces are down and removed from all bridges
+ for dev in $device ${device}.1 ${device}.2 ${device}.3; do
+ ifconfig "$dev" down 2>/dev/null >/dev/null && {
+ unbridge "$dev"
+ }
+ done
+ )
+ true
+}
+
+enable_broadcom() {
+ local device="$1"
+ local _c
+ config_get channel "$device" channel
+ config_get country "$device" country
+ config_get maxassoc "$device" maxassoc
+ config_get wds "$device" wds
+ config_get vifs "$device" vifs
+ config_get distance "$device" distance
+ config_get slottime "$device" slottime
+ config_get rxantenna "$device" rxantenna
+ config_get txantenna "$device" txantenna
+ config_get_bool frameburst "$device" frameburst
+ config_get macfilter "$device" macfilter
+ config_get maclist "$device" maclist
+ config_get macaddr "$device" macaddr
+ config_get txpower "$device" txpower
+ config_get frag "$device" frag
+ config_get rts "$device" rts
+ config_get hwmode "$device" hwmode
+ local vif_pre_up vif_post_up vif_do_up vif_txpower
+ local doth=0
+ local wmm=1
+
+ _c=0
+ nas="$(which nas)"
+ nas_cmd=
+ if_up=
+
+ [ -z "$slottime" ] && {
+ [ -n "$distance" ] && {
+ # slottime = 9 + (distance / 150) + (distance % 150 ? 1 : 0)
+ slottime="$((9 + ($distance / 150) + 1 - (150 - ($distance % 150)) / 150 ))"
+ }
+ } || {
+ slottime="${slottime:--1}"
+ }
+
+ case "$macfilter" in
+ allow|2)
+ macfilter=2;
+ ;;
+ deny|1)
+ macfilter=1;
+ ;;
+ disable|none|0)
+ macfilter=0;
+ ;;
+ esac
+
+ case "$hwmode" in
+ *b) hwmode=0;;
+ *bg) hwmode=1;;
+ *g) hwmode=2;;
+ *gst) hwmode=4;;
+ *lrs) hwmode=5;;
+ *) hwmode=1;;
+ esac
+
+ for vif in $vifs; do
+ config_get vif_txpower "$vif" txpower
+
+ config_get mode "$vif" mode
+ append vif_pre_up "vif $_c" "$N"
+ append vif_post_up "vif $_c" "$N"
+ append vif_do_up "vif $_c" "$N"
+
+ config_get_bool wmm "$vif" wmm "$wmm"
+ config_get_bool doth "$vif" doth "$doth"
+
+ [ "$mode" = "sta" ] || {
+ config_get_bool hidden "$vif" hidden 0
+ append vif_pre_up "closed $hidden" "$N"
+ config_get_bool isolate "$vif" isolate 0
+ append vif_pre_up "ap_isolate $isolate" "$N"
+ }
+
+ wsec_r=0
+ eap_r=0
+ wsec=0
+ auth=0
+ nasopts=
+ config_get enc "$vif" encryption
+ case "$enc" in
+ *wep*)
+ wsec_r=1
+ wsec=1
+ defkey=1
+ config_get key "$vif" key
+ case "$enc" in
+ *shared*) append vif_do_up "wepauth 1" "$N";;
+ *) append vif_do_up "wepauth 0" "$N";;
+ esac
+ case "$key" in
+ [1234])
+ defkey="$key"
+ for knr in 1 2 3 4; do
+ config_get k "$vif" key$knr
+ [ -n "$k" ] || continue
+ [ "$defkey" = "$knr" ] && def="=" || def=""
+ append vif_do_up "wepkey $def$knr,$k" "$N"
+ done
+ ;;
+ "");;
+ *) append vif_do_up "wepkey =1,$key" "$N";;
+ esac
+ ;;
+ *psk*)
+ wsec_r=1
+ config_get key "$vif" key
+
+ # psk version + default cipher
+ case "$enc" in
+ *mixed*|*psk+psk2*) auth=132; wsec=6;;
+ *psk2*) auth=128; wsec=4;;
+ *) auth=4; wsec=2;;
+ esac
+
+ # cipher override
+ case "$enc" in
+ *tkip+aes*|*tkip+ccmp*|*aes+tkip*|*ccmp+tkip*) wsec=6;;
+ *aes*|*ccmp*) wsec=4;;
+ *tkip*) wsec=2;;
+ esac
+
+ # group rekey interval
+ config_get rekey "$vif" wpa_group_rekey
+
+ eval "${vif}_key=\"\$key\""
+ nasopts="-k \"\$${vif}_key\"${rekey:+ -g $rekey}"
+ ;;
+ *wpa*)
+ wsec_r=1
+ eap_r=1
+ config_get auth_server "$vif" auth_server
+ [ -z "$auth_server" ] && config_get auth_server "$vif" server
+ config_get auth_port "$vif" auth_port
+ [ -z "$auth_port" ] && config_get auth_port "$vif" port
+ config_get auth_secret "$vif" auth_secret
+ [ -z "$auth_secret" ] && config_get auth_secret "$vif" key
+
+ # wpa version + default cipher
+ case "$enc" in
+ *mixed*|*wpa+wpa2*) auth=66; wsec=6;;
+ *wpa2*) auth=64; wsec=4;;
+ *) auth=2; wsec=2;;
+ esac
+
+ # cipher override
+ case "$enc" in
+ *tkip+aes*|*tkip+ccmp*|*aes+tkip*|*ccmp+tkip*) wsec=6;;
+ *aes*|*ccmp*) wsec=4;;
+ *tkip*) wsec=2;;
+ esac
+
+ # group rekey interval
+ config_get rekey "$vif" wpa_group_rekey
+
+ eval "${vif}_key=\"\$auth_secret\""
+ nasopts="-r \"\$${vif}_key\" -h $auth_server -p ${auth_port:-1812}${rekey:+ -g $rekey}"
+ ;;
+ esac
+ append vif_do_up "wsec $wsec" "$N"
+ append vif_do_up "wpa_auth $auth" "$N"
+ append vif_do_up "wsec_restrict $wsec_r" "$N"
+ append vif_do_up "eap_restrict $eap_r" "$N"
+
+ config_get ssid "$vif" ssid
+ append vif_post_up "vlan_mode 0" "$N"
+ append vif_post_up "ssid $ssid" "$N"
+ append vif_do_up "ssid $ssid" "$N"
+
+ [ "$mode" = "monitor" ] && {
+ append vif_post_up "monitor $monitor" "$N"
+ }
+
+ [ "$mode" = "adhoc" ] && {
+ config_get bssid "$vif" bssid
+ [ -n "$bssid" ] && {
+ append vif_pre_up "bssid $bssid" "$N"
+ append vif_pre_up "ibss_merge 0" "$N"
+ } || {
+ append vif_pre_up "ibss_merge 1" "$N"
+ }
+ }
+
+ append vif_post_up "enabled 1" "$N"
+
+ config_get ifname "$vif" ifname
+ #append if_up "ifconfig $ifname up" ";$N"
+
+ local net_cfg
+ net_cfg="$(find_net_config "$vif")"
+ [ -z "$net_cfg" ] || {
+ append if_up "set_wifi_up '$vif' '$ifname'" ";$N"
+ append if_up "start_net '$ifname' '$net_cfg'" ";$N"
+ }
+ [ -z "$nasopts" ] || {
+ eval "${vif}_ssid=\"\$ssid\""
+ nas_mode="-A"
+ [ "$mode" = "sta" ] && nas_mode="-S"
+ [ -z "$nas" ] || {
+ nas_cmd="${nas_cmd:+$nas_cmd$N}start-stop-daemon -S -b -p /var/run/nas.$ifname.pid -x $nas -- -P /var/run/nas.$ifname.pid -H 34954 -i $ifname $nas_mode -m $auth -w $wsec -s \"\$${vif}_ssid\" -g 3600 -F $nasopts"
+ }
+ }
+ _c=$(($_c + 1))
+ done
+ killall -KILL nas >&- 2>&-
+ wlc ifname "$device" stdin <<EOF
+$ifdown
+
+gmode ${hwmode:-1}
+apsta $apsta
+ap $ap
+${mssid:+mssid $mssid}
+infra $infra
+${wet:+wet 1}
+802.11d 0
+802.11h ${doth:-0}
+wme ${wmm:-1}
+rxant ${rxantenna:-3}
+txant ${txantenna:-3}
+fragthresh ${frag:-2346}
+rtsthresh ${rts:-2347}
+monitor ${monitor:-0}
+
+radio ${radio:-1}
+macfilter ${macfilter:-0}
+maclist ${maclist:-none}
+wds none
+${wds:+wds $wds}
+country ${country:-US}
+${channel:+channel $channel}
+maxassoc ${maxassoc:-128}
+slottime ${slottime:--1}
+${frameburst:+frameburst $frameburst}
+
+$vif_pre_up
+up
+$vif_post_up
+EOF
+ eval "$if_up"
+ wlc ifname "$device" stdin <<EOF
+$vif_do_up
+EOF
+
+ # use vif_txpower (from last wifi-iface) instead of txpower (from
+ # wifi-device) if the latter does not exist
+ txpower=${txpower:-$vif_txpower}
+ [ -z "$txpower" ] || iwconfig $device txpower ${txpower}dBm
+
+ eval "$nas_cmd"
+}
+
+
+detect_broadcom() {
+ local i=-1
+
+ while grep -qs "^ *wl$((++i)):" /proc/net/dev; do
+ local channel
+
+ config_get type wl${i} type
+ [ "$type" = broadcom ] && continue
+ channel=`wlc ifname wl${i} channel`
+ cat <<EOF
+config wifi-device wl${i}
+ option type broadcom
+ option channel ${channel:-11}
+
+ # REMOVE THIS LINE TO ENABLE WIFI:
+ option disabled 1
+
+config wifi-iface
+ option device wl${i}
+ option network lan
+ option mode ap
+ option ssid OpenWrt${i#0}
+ option encryption none
+
+EOF
+ done
+}
diff --git a/package/kernel/broadcom-wl/patches/003-compat-2.6.35.patch b/package/kernel/broadcom-wl/patches/003-compat-2.6.35.patch
new file mode 100644
index 0000000000..89b665371d
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/003-compat-2.6.35.patch
@@ -0,0 +1,39 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -2082,7 +2082,11 @@ static void
+ _wl_set_multicast_list(struct net_device *dev)
+ {
+ wl_info_t *wl;
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
+ struct dev_mc_list *mclist;
++#else
++ struct netdev_hw_addr *ha;
++#endif
+ int i;
+
+ if (!dev)
+@@ -2098,14 +2102,24 @@ _wl_set_multicast_list(struct net_device
+ wl->pub->allmulti = (dev->flags & IFF_ALLMULTI)? TRUE: FALSE;
+
+ /* copy the list of multicasts into our private table */
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
+ for (i = 0, mclist = dev->mc_list; mclist && (i < dev->mc_count);
+ i++, mclist = mclist->next) {
++#else
++ i = 0;
++ netdev_for_each_mc_addr(ha, dev) {
++#endif
+ if (i >= MAXMULTILIST) {
+ wl->pub->allmulti = TRUE;
+ i = 0;
+ break;
+ }
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
+ wl->pub->multicast[i] = *((struct ether_addr*) mclist->dmi_addr);
++#else
++ wl->pub->multicast[i] = *((struct ether_addr*) ha->addr);
++ i++;
++#endif
+ }
+ wl->pub->nmulticast = i;
+ wlc_set(wl->wlc, WLC_SET_PROMISC, (dev->flags & IFF_PROMISC));
diff --git a/package/kernel/broadcom-wl/patches/004-remove-pcmcia.patch b/package/kernel/broadcom-wl/patches/004-remove-pcmcia.patch
new file mode 100644
index 0000000000..36dda47e10
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/004-remove-pcmcia.patch
@@ -0,0 +1,22 @@
+--- a/driver/include/linuxver.h
++++ b/driver/include/linuxver.h
+@@ -111,7 +111,7 @@ typedef irqreturn_t(*FN_ISR) (int irq, v
+ #endif /* not SANDGATE2G */
+ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) */
+
+-#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
++#if 0
+
+ #include <pcmcia/cs_types.h>
+ #include <pcmcia/cs.h>
+--- a/driver/linux_osl.c
++++ b/driver/linux_osl.c
+@@ -62,7 +62,7 @@ struct osl_info {
+ };
+
+ /* PCMCIA attribute space access macros */
+-#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
++#if 0
+ struct pcmcia_dev {
+ dev_link_t link; /* PCMCIA device pointer */
+ dev_node_t node; /* PCMCIA node structure */
diff --git a/package/kernel/broadcom-wl/patches/005-fix-mem-leak-on-unload.patch b/package/kernel/broadcom-wl/patches/005-fix-mem-leak-on-unload.patch
new file mode 100644
index 0000000000..41c246ff80
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/005-fix-mem-leak-on-unload.patch
@@ -0,0 +1,31 @@
+From: George Kashperko <george@znau.edu.ua>
+
+Release nvram variables buffer.
+Prevent block reserved by alloc_etherdev from being freed.
+Signed-off-by: George Kashperko <george@znau.edu.ua>
+---
+---
+--- a/driver/siutils.c
++++ b/driver/siutils.c
+@@ -647,7 +647,10 @@ si_detach(si_t *sih)
+ #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
+ if (sii != &ksii)
+ #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
+- MFREE(sii->osh, sii, sizeof(si_info_t));
++ do {
++ MFREE(sii->osh, sii, sizeof(si_info_t));
++ nvram_exit((void *)&(sii->pub));
++ } while (0);
+ }
+
+ void *
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -1477,7 +1477,6 @@ wl_free_if(wl_info_t *wl, wl_if_t *wlif)
+ free_netdev(wlif->dev);
+ #endif
+ }
+- MFREE(wl->osh, wlif, sizeof(wl_if_t));
+ }
+
+ #ifdef AP
diff --git a/package/kernel/broadcom-wl/patches/006-generic-dma-api.patch b/package/kernel/broadcom-wl/patches/006-generic-dma-api.patch
new file mode 100644
index 0000000000..a90bbe1f96
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/006-generic-dma-api.patch
@@ -0,0 +1,88 @@
+From: George Kashperko <george@znau.edu.ua>
+
+broadcom-wl driver bound to ssb device with ssb driver probe
+have osh handle struct pdev pointer value initialized with
+ssb_device pointer. Later on pdev is used with legacy pci
+dma api as pci_dev thus causing oops sometimes.
+
+The patch replaces legacy pci dma api and pass relevant
+device struct pointer to avoid crashes.
+Signed-off-by: George Kashperko <george@znau.edu.ua>
+---
+ driver/linux_osl.c | 28 +++++++++++++++++++++++-----
+ 1 file changed, 23 insertions(+), 5 deletions(-)
+--- a/driver/linux_osl.c
++++ b/driver/linux_osl.c
+@@ -25,6 +25,9 @@
+ #include <asm/paccess.h>
+ #endif /* mips */
+ #include <pcicfg.h>
++#ifdef CONFIG_SSB
++#include <linux/ssb/ssb.h>
++#endif
+
+ #define PCI_CFG_RETRY 10
+
+@@ -364,12 +367,27 @@ osl_dma_consistent_align(void)
+ return (PAGE_SIZE);
+ }
+
++static struct device *
++osl_get_dmadev(osl_t *osh)
++{
++#ifdef CONFIG_SSB
++ if (osh->bustype == SI_BUS) {
++ /* This can be SiliconBackplane emulated as pci with Broadcom or
++ * ssb device. Less harmful is to check for pci_bus_type and if
++ * no match then assume we got ssb */
++ if (((struct pci_dev *)osh->pdev)->dev.bus != &pci_bus_type)
++ return ((struct ssb_device *)osh->pdev)->dma_dev;
++ }
++#endif
++ return &((struct pci_dev *)osh->pdev)->dev;
++}
++
+ void*
+ osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap)
+ {
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+- return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap));
++ return (dma_alloc_coherent(osl_get_dmadev(osh), size, (dma_addr_t*)pap, GFP_ATOMIC));
+ }
+
+ void
+@@ -377,7 +395,7 @@ osl_dma_free_consistent(osl_t *osh, void
+ {
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+- pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa);
++ dma_free_coherent(osl_get_dmadev(osh), size, va, (dma_addr_t)pa);
+ }
+
+ uint BCMFASTPATH
+@@ -386,13 +404,13 @@ osl_dma_map(osl_t *osh, void *va, uint s
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+ if (direction == DMA_TX)
+- return (pci_map_single(osh->pdev, va, size, PCI_DMA_TODEVICE));
++ return (dma_map_single(osl_get_dmadev(osh), va, size, PCI_DMA_TODEVICE));
+ else {
+ #ifdef mips
+ dma_cache_inv((uint)va, size);
+ return (virt_to_phys(va));
+ #else /* mips */
+- return (pci_map_single(osh->pdev, va, size, PCI_DMA_FROMDEVICE));
++ return (dma_map_single(osl_get_dmadev(osh), va, size, PCI_DMA_FROMDEVICE));
+ #endif /* mips */
+ }
+ }
+@@ -404,7 +422,7 @@ osl_dma_unmap(osl_t *osh, uint pa, uint
+
+ 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);
++ dma_unmap_single(osl_get_dmadev(osh), (uint32)pa, size, dir);
+ }
+
+
diff --git a/package/kernel/broadcom-wl/patches/007-use-glue-driver.patch b/package/kernel/broadcom-wl/patches/007-use-glue-driver.patch
new file mode 100644
index 0000000000..2639abcf6a
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/007-use-glue-driver.patch
@@ -0,0 +1,184 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -85,10 +85,9 @@ typedef void wlc_hw_info_t;
+ #include <bcmjtag.h>
+ #endif /* BCMJTAG */
+
+-
+-#ifdef CONFIG_SSB
+-#include <linux/ssb/ssb.h>
+-#endif
++#if defined(CONFIG_SSB) || defined(CONFIG_BCMA)
++#include <wl_glue.h>
++#endif /* defined(CONFIG_SSB) || defined(CONFIG_BCMA) */
+
+ /* Linux wireless extension support */
+ #ifdef CONFIG_WIRELESS_EXT
+@@ -997,62 +996,32 @@ static struct pci_driver wl_pci_driver =
+ #endif /* CONFIG_PCI */
+ #endif
+
++#ifdef BCMJTAG
++static bcmjtag_driver_t wl_jtag_driver = {
++ wl_jtag_probe,
++ wl_jtag_detach,
++ wl_jtag_poll,
++ };
++#endif /* BCMJTAG */
+
+-static int wl_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)
++#if defined(CONFIG_SSB) || defined(CONFIG_BCMA)
++static void * glue_attach_cb(u16 vendor, u16 device,
++ ulong mmio, void *dev, u32 irq)
+ {
+- wl_info_t *wl;
+- void *mmio;
+-
+- if (dev->bus->bustype != SSB_BUSTYPE_SSB) {
+- printk("Attaching to SSB behind PCI is not supported. Please remove the b43 ssb bridge\n");
+- return -EINVAL;
+- }
+-
+- mmio = (void *) 0x18000000 + dev->core_index * 0x1000;
+- wl = wl_attach(id->vendor, id->coreid, (ulong) mmio, SI_BUS, dev, dev->irq);
+- if (!wl) {
+- printk("wl_attach failed\n");
+- return -ENODEV;
+- }
+-
+- ssb_set_drvdata(dev, wl);
+-
+- return 0;
++ return wl_attach(vendor, device, mmio, SI_BUS, dev, irq);
+ }
+
+-static void wl_ssb_remove(struct ssb_device *dev)
++static void glue_remove_cb(void *wldev)
+ {
+- wl_info_t *wl = (wl_info_t *) ssb_get_drvdata(dev);
++ wl_info_t *wl = (wl_info_t *)wldev;
+
+ WL_LOCK(wl);
+ WL_APSTA_UPDN(("wl%d (%s): wl_remove() -> wl_down()\n", wl->pub->unit, wl->dev->name));
+ wl_down(wl);
+ WL_UNLOCK(wl);
+ wl_free(wl);
+- ssb_set_drvdata(dev, NULL);
+ }
+-
+-static const struct ssb_device_id wl_ssb_tbl[] = {
+- SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, SSB_ANY_REV),
+- SSB_DEVTABLE_END
+-};
+-
+-#ifdef CONFIG_SSB
+-static struct ssb_driver wl_ssb_driver = {
+- .name = KBUILD_MODNAME,
+- .id_table = wl_ssb_tbl,
+- .probe = wl_ssb_probe,
+- .remove = wl_ssb_remove,
+-};
+-#endif
+-
+-#ifdef BCMJTAG
+-static bcmjtag_driver_t wl_jtag_driver = {
+- wl_jtag_probe,
+- wl_jtag_detach,
+- wl_jtag_poll,
+- };
+-#endif /* BCMJTAG */
++#endif/* defined(CONFIG_SSB) || defined(CONFIG_BCMA) */
+
+
+ /**
+@@ -1067,11 +1036,13 @@ wl_module_init(void)
+ {
+ int error = -ENODEV;
+
+-#ifdef CONFIG_SSB
+- error = ssb_driver_register(&wl_ssb_driver);
++#if defined(CONFIG_SSB) || defined(CONFIG_BCMA)
++ wl_glue_set_attach_callback(&glue_attach_cb);
++ wl_glue_set_remove_callback(&glue_remove_cb);
++ error = wl_glue_register();
+ if (error)
+ return error;
+-#endif /* CONFIG_SSB */
++#endif /* defined(CONFIG_SSB) || defined(CONFIG_BCMA) */
+
+ #ifdef CONFIG_PCI
+ error = pci_register_driver(&wl_pci_driver);
+@@ -1082,7 +1053,9 @@ wl_module_init(void)
+ return 0;
+
+ error_pci:
+- ssb_driver_unregister(&wl_ssb_driver);
++#if defined(CONFIG_SSB) || defined(CONFIG_BCMA)
++ wl_glue_unregister();
++#endif /* defined(CONFIG_SSB) || defined(CONFIG_BCMA) */
+ return error;
+ }
+
+@@ -1099,9 +1072,9 @@ wl_module_exit(void)
+ #ifdef CONFIG_PCI
+ pci_unregister_driver(&wl_pci_driver);
+ #endif /* CONFIG_PCI */
+-#ifdef CONFIG_SSB
+- ssb_driver_unregister(&wl_ssb_driver);
+-#endif /* CONFIG_SSB */
++#if defined(CONFIG_SSB) || defined(CONFIG_BCMA)
++ wl_glue_unregister();
++#endif /* defined(CONFIG_SSB) || defined(CONFIG_BCMA) */
+ }
+
+ module_init(wl_module_init);
+--- a/driver/linux_osl.c
++++ b/driver/linux_osl.c
+@@ -25,9 +25,9 @@
+ #include <asm/paccess.h>
+ #endif /* mips */
+ #include <pcicfg.h>
+-#ifdef CONFIG_SSB
+-#include <linux/ssb/ssb.h>
+-#endif
++#if defined(CONFIG_SSB) || defined(CONFIG_BCMA)
++#include <wl_glue.h>
++#endif /* defined(CONFIG_SSB) || defined(CONFIG_BCMA) */
+
+ #define PCI_CFG_RETRY 10
+
+@@ -370,15 +370,17 @@ osl_dma_consistent_align(void)
+ static struct device *
+ osl_get_dmadev(osl_t *osh)
+ {
+-#ifdef CONFIG_SSB
++#if defined(CONFIG_SSB) || defined(CONFIG_BCMA)
+ if (osh->bustype == SI_BUS) {
+- /* This can be SiliconBackplane emulated as pci with Broadcom or
+- * ssb device. Less harmful is to check for pci_bus_type and if
+- * no match then assume we got ssb */
++ /* This can be SiliconBackplane emulated as pci with Broadcom,
++ * ssb or bcma device. Less harmful is to check for pci_bus_type and if
++ * no match then assume we got either ssb or bcma */
+ if (((struct pci_dev *)osh->pdev)->dev.bus != &pci_bus_type)
+- return ((struct ssb_device *)osh->pdev)->dma_dev;
++ {
++ return wl_glue_get_dmadev(osh->pdev);
++ }
+ }
+-#endif
++#endif /* defined(CONFIG_SSB) || defined(CONFIG_BCMA) */
+ return &((struct pci_dev *)osh->pdev)->dev;
+ }
+
+--- a/driver/Makefile
++++ b/driver/Makefile
+@@ -1,7 +1,7 @@
+ BUILD_TYPE=wl_apsta
+ include $(src)/$(BUILD_TYPE)/buildflags.mk
+
+-EXTRA_CFLAGS += -I$(src)/include -I$(src) -DBCMDRIVER $(WLFLAGS)
++EXTRA_CFLAGS += -I$(src)/include -I$(src) -I$(realpath $(src)/../glue) -DBCMDRIVER $(WLFLAGS)
+
+ wl-objs := $(BUILD_TYPE)/wl_prebuilt.o wl_iw.o wl_linux.o linux_osl.o siutils.o aiutils.o hndpmu.o bcmutils.o sbutils.o nicpci.o hnddma.o bcmsrom.o nvram_stub.o
+
diff --git a/package/kernel/broadcom-wl/patches/008-fix_virtual_interfaces.patch b/package/kernel/broadcom-wl/patches/008-fix_virtual_interfaces.patch
new file mode 100644
index 0000000000..6cffa27810
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/008-fix_virtual_interfaces.patch
@@ -0,0 +1,11 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -1541,6 +1541,8 @@ wl_add_if(wl_info_t *wl, struct wlc_if*
+ return NULL;
+ }
+
++ wl_if_setup(wlif->dev);
++
+ sprintf(wlif->dev->name, "%s%d.%d", devname, wl->pub->unit, wlif->subunit);
+ if (remote)
+ bcopy(remote, &wlif->remote, ETHER_ADDR_LEN);
diff --git a/package/kernel/broadcom-wl/patches/009-fix_compile_3_2.patch b/package/kernel/broadcom-wl/patches/009-fix_compile_3_2.patch
new file mode 100644
index 0000000000..628f2fdf25
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/009-fix_compile_3_2.patch
@@ -0,0 +1,27 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -462,6 +462,16 @@ wl_schedule_fn(wl_info_t *wl, void (*fn)
+ }
+ #endif /* DSLCPE_DELAY */
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
++#define WL_DEFAULT_OPS \
++ .ndo_open = wl_open, \
++ .ndo_stop = wl_close, \
++ .ndo_start_xmit = wl_start, \
++ .ndo_get_stats = wl_get_stats, \
++ .ndo_set_mac_address = wl_set_mac_address, \
++ .ndo_set_rx_mode = wl_set_multicast_list, \
++ .ndo_do_ioctl = wl_ioctl
++#else
+ #define WL_DEFAULT_OPS \
+ .ndo_open = wl_open, \
+ .ndo_stop = wl_close, \
+@@ -470,6 +480,7 @@ wl_schedule_fn(wl_info_t *wl, void (*fn)
+ .ndo_set_mac_address = wl_set_mac_address, \
+ .ndo_set_multicast_list = wl_set_multicast_list, \
+ .ndo_do_ioctl = wl_ioctl
++#endif
+
+ static const struct net_device_ops wl_ops = {
+ WL_DEFAULT_OPS,
diff --git a/package/kernel/broadcom-wl/patches/010-remove_irqf_samble_random.patch b/package/kernel/broadcom-wl/patches/010-remove_irqf_samble_random.patch
new file mode 100644
index 0000000000..27b132d115
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/010-remove_irqf_samble_random.patch
@@ -0,0 +1,11 @@
+--- a/driver/wl_linux.c 2012-09-26 20:51:48.099454971 -0400
++++ b/driver/wl_linux.c 2012-09-26 20:53:24.115453441 -0400
+@@ -691,7 +691,7 @@
+ if (wl->bustype != JTAG_BUS)
+ #endif /* BCMJTAG */
+ {
+- if (request_irq(irq, wl_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM, dev->name, wl)) {
++ if (request_irq(irq, wl_isr, IRQF_SHARED, dev->name, wl)) {
+ WL_ERROR(("wl%d: request_irq() failed\n", unit));
+ goto fail;
+ }
diff --git a/package/kernel/broadcom-wl/patches/011-fix_compile_3_4.patch b/package/kernel/broadcom-wl/patches/011-fix_compile_3_4.patch
new file mode 100644
index 0000000000..585d53c7df
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/011-fix_compile_3_4.patch
@@ -0,0 +1,12 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -49,7 +49,9 @@
+ #include <linux/ieee80211.h>
+ #endif
+
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
+ #include <asm/system.h>
++#endif
+ #include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/pgtable.h>
diff --git a/package/kernel/broadcom-wl/patches/100-fix_nvram_two_devices.patch b/package/kernel/broadcom-wl/patches/100-fix_nvram_two_devices.patch
new file mode 100644
index 0000000000..5650862f83
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/100-fix_nvram_two_devices.patch
@@ -0,0 +1,32 @@
+--- a/driver/nvram_stub.c
++++ b/driver/nvram_stub.c
+@@ -22,6 +22,7 @@ typedef struct _vars {
+ #define VARS_T_OH sizeof(vars_t)
+
+ static vars_t *vars = NULL;
++static int nvram_init_done = 0;
+ extern char *nvram_buf[];
+
+ int
+@@ -33,6 +34,10 @@ BCMATTACHFN(nvram_init)(void *si)
+ uint nvs, bufsz;
+ vars_t *new;
+
++ nvram_init_done++;
++ if (nvram_init_done != 1)
++ return 0;
++
+ osh = si_osh(sih);
+
+ nvs = R_REG(osh, &nvh->len) - sizeof(struct nvram_header);
+@@ -79,6 +84,10 @@ BCMATTACHFN(nvram_exit)(void *si)
+ vars_t *this, *next;
+ si_t *sih;
+
++ nvram_init_done--;
++ if (nvram_init_done != 0)
++ return 0;
++
+ sih = (si_t *)si;
+ this = vars;
+ while (this) {
diff --git a/package/kernel/broadcom-wl/patches/110-add_number_to_dev_name.patch b/package/kernel/broadcom-wl/patches/110-add_number_to_dev_name.patch
new file mode 100644
index 0000000000..13ce72741e
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/110-add_number_to_dev_name.patch
@@ -0,0 +1,11 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -1412,7 +1412,7 @@ wl_alloc_if(wl_info_t *wl, int iftype, u
+ dev = alloc_etherdev(sizeof(wl_if_t));
+ wlif = netdev_priv(dev);
+ bzero(wlif, sizeof(wl_if_t));
+- strncpy(dev->name, name, IFNAMSIZ);
++ snprintf(dev->name, IFNAMSIZ, name, subunit);
+
+ wlif->type = iftype;
+ wlif->dev = dev;
diff --git a/package/kernel/broadcom-wl/patches/910-fallback-sprom.patch b/package/kernel/broadcom-wl/patches/910-fallback-sprom.patch
new file mode 100644
index 0000000000..749ecbf31f
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/910-fallback-sprom.patch
@@ -0,0 +1,84 @@
+--- a/driver/bcmsrom.c
++++ b/driver/bcmsrom.c
+@@ -39,6 +39,11 @@
+ #include <sbsdpcmdev.h>
+ #endif
+
++#if defined(CONFIG_SSB_PCIHOST) && defined(CONFIG_BOARD_BCM963XX)
++#include <linux/ssb/ssb.h>
++extern struct ssb_sprom bcm63xx_sprom;
++#endif
++
+ #ifdef WLTEST
+ #include <sbsprom.h>
+ #endif /* WLTEST */
+@@ -2058,6 +2063,10 @@ BCMATTACHFN(initvars_srom_pci)(si_t *sih
+ bool flash = FALSE;
+ int err = 0;
+
++#if defined(CONFIG_SSB_PCIHOST) && defined(CONFIG_BOARD_BCM963XX)
++ char eabuf[18];
++#endif
++
+ /*
+ * Apply CRC over SROM content regardless SROM is present or not,
+ * and use variable <devpath>sromrev's existance in flash to decide
+@@ -2120,6 +2129,58 @@ BCMATTACHFN(initvars_srom_pci)(si_t *sih
+ goto varscont;
+ }
+
++#if defined(CONFIG_SSB_PCIHOST) && defined(CONFIG_BOARD_BCM963XX)
++ base = vp = MALLOC(osh, MAXSZ_NVRAM_VARS);
++
++ if( base != NULL )
++ {
++ varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
++
++ printk("Got version %i SPROM from SSB\n", bcm63xx_sprom.revision);
++
++ varbuf_append(&b, vstr_sromrev, bcm63xx_sprom.revision);
++ varbuf_append(&b, vstr_boardrev, bcm63xx_sprom.board_rev);
++
++ /* ToDo: map bcm63xx_sprom.country_code */
++ varbuf_append(&b, vstr_noccode);
++
++ varbuf_append(&b, vstr_aa2g, bcm63xx_sprom.ant_available_bg);
++
++ varbuf_append(&b, vstr_pa0b[0], bcm63xx_sprom.pa0b0);
++ varbuf_append(&b, vstr_pa1b[0], bcm63xx_sprom.pa1b0);
++ varbuf_append(&b, vstr_pa0b[1], bcm63xx_sprom.pa0b1);
++ varbuf_append(&b, vstr_pa1b[1], bcm63xx_sprom.pa1b1);
++ varbuf_append(&b, vstr_pa0b[2], bcm63xx_sprom.pa0b2);
++ varbuf_append(&b, vstr_pa1b[2], bcm63xx_sprom.pa1b2);
++
++ varbuf_append(&b, vstr_pa0maxpwr, bcm63xx_sprom.maxpwr_bg);
++ varbuf_append(&b, vstr_pa0itssit, bcm63xx_sprom.itssi_bg);
++
++ varbuf_append(&b, vstr_boardflags, (bcm63xx_sprom.boardflags_hi << 16) | bcm63xx_sprom.boardflags_lo);
++ varbuf_append(&b, vstr_boardflags2, (bcm63xx_sprom.boardflags2_hi << 16) | bcm63xx_sprom.boardflags2_lo);
++
++ snprintf(eabuf, sizeof(eabuf), "%02x:%02x:%02x:%02x:%02x:%02x",
++ bcm63xx_sprom.il0mac[0], bcm63xx_sprom.il0mac[1], bcm63xx_sprom.il0mac[2],
++ bcm63xx_sprom.il0mac[3], bcm63xx_sprom.il0mac[4], bcm63xx_sprom.il0mac[5]
++ );
++
++ varbuf_append(&b, vstr_macaddr, eabuf);
++
++ /* final nullbyte terminator */
++ ASSERT(b.size >= 1);
++ vp = b.buf;
++ *vp++ = '\0';
++
++ ASSERT((vp - base) <= MAXSZ_NVRAM_VARS);
++ goto varsdone;
++ }
++ else
++ {
++ err = -2;
++ goto errout;
++ }
++#endif
++
+ BS_ERROR(("SROM CRC Error\n"));
+
+ #if defined(WLTEST)
diff --git a/package/kernel/broadcom-wl/patches/912-pci-bus-nvram-hack.patch b/package/kernel/broadcom-wl/patches/912-pci-bus-nvram-hack.patch
new file mode 100644
index 0000000000..65e8bd3958
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/912-pci-bus-nvram-hack.patch
@@ -0,0 +1,11 @@
+--- a/driver/siutils.c
++++ b/driver/siutils.c
+@@ -1859,7 +1859,7 @@ BCMINITFN(si_devpath)(si_t *sih, char *p
+ 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_BUS((SI_INFO(sih))->osh) + 1,
+ OSL_PCI_SLOT((SI_INFO(sih))->osh));
+ break;
+ case PCMCIA_BUS:
diff --git a/package/kernel/broadcom-wl/patches/913-avoid-dbe-on-ifs_ctl-readw-hack.patch b/package/kernel/broadcom-wl/patches/913-avoid-dbe-on-ifs_ctl-readw-hack.patch
new file mode 100644
index 0000000000..412bce92c8
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/913-avoid-dbe-on-ifs_ctl-readw-hack.patch
@@ -0,0 +1,12 @@
+--- a/driver/linux_osl.c
++++ b/driver/linux_osl.c
+@@ -723,6 +723,9 @@ osl_readl(volatile uint32 *r)
+ uint16
+ osl_readw(volatile uint16 *r)
+ {
++ uint32 addr = (uintptr)r & 0xffff3fff;
++ if (addr == 0xa8000688) /* ifs_ctl */
++ readl(r);
+ return (readw(r));
+ }
+
diff --git a/package/kernel/broadcom-wl/src/glue/Makefile b/package/kernel/broadcom-wl/src/glue/Makefile
new file mode 100644
index 0000000000..81f0c8acfd
--- /dev/null
+++ b/package/kernel/broadcom-wl/src/glue/Makefile
@@ -0,0 +1,17 @@
+#
+# Makefile for wl_glue driver
+#
+# Copyright (C) 2011 Jo-Philipp Wich <jow@openwrt.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.
+#
+
+obj-m := wl_glue.o
+
+ifeq ($(MAKING_MODULES),1)
+-include $(TOPDIR)/Rules.make
+endif
+
diff --git a/package/kernel/broadcom-wl/src/glue/wl_glue.c b/package/kernel/broadcom-wl/src/glue/wl_glue.c
new file mode 100644
index 0000000000..fc94ac0b25
--- /dev/null
+++ b/package/kernel/broadcom-wl/src/glue/wl_glue.c
@@ -0,0 +1,315 @@
+/*
+ * wl_glue.c: Broadcom WL support module providing a unified SSB/BCMA handling.
+ * Copyright (C) 2011 Jo-Philipp Wich <jow@openwrt.org>
+ */
+
+#include "wl_glue.h"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#ifdef CONFIG_BCM47XX
+#include <bcm47xx.h>
+#endif
+
+#ifdef CONFIG_SSB
+#include <linux/ssb/ssb.h>
+#endif
+
+#ifdef CONFIG_BCMA
+#include <linux/bcma/bcma.h>
+#endif
+
+MODULE_AUTHOR("Jo-Philipp Wich (jow@openwrt.org)");
+MODULE_DESCRIPTION("Broadcom WL SSB/BCMA compatibility layer");
+MODULE_LICENSE("GPL");
+
+static wl_glue_attach_cb_t attach_cb = NULL;
+static wl_glue_remove_cb_t remove_cb = NULL;
+static enum wl_glue_bus_type active_bus_type = WL_GLUE_BUS_TYPE_UNSPEC;
+static int wl_glue_attached = 0;
+
+
+#ifdef CONFIG_SSB
+static int wl_glue_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)
+{
+ void *mmio;
+ void *wldev;
+
+ if (!attach_cb)
+ {
+ pr_err("No attach callback registered\n");
+ return -ENOSYS;
+ }
+
+ if (dev->bus->bustype != SSB_BUSTYPE_SSB)
+ {
+ pr_err("Attaching to SSB behind PCI is not supported. Please remove the b43 ssb bridge\n");
+ return -EINVAL;
+ }
+
+ mmio = (void *) 0x18000000 + dev->core_index * 0x1000;
+ wldev = attach_cb(id->vendor, id->coreid, (ulong)mmio, dev, dev->irq);
+
+ if (!wldev)
+ {
+ pr_err("The attach callback failed, SSB probe aborted\n");
+ return -ENODEV;
+ }
+
+ ssb_set_drvdata(dev, wldev);
+ return 0;
+}
+
+static void wl_glue_ssb_remove(struct ssb_device *dev)
+{
+ void *wldev = ssb_get_drvdata(dev);
+
+ if (remove_cb)
+ remove_cb(wldev);
+
+ ssb_set_drvdata(dev, NULL);
+}
+
+static const struct ssb_device_id wl_glue_ssb_tbl[] = {
+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, SSB_ANY_REV),
+ SSB_DEVTABLE_END
+};
+
+static struct ssb_driver wl_glue_ssb_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = wl_glue_ssb_tbl,
+ .probe = wl_glue_ssb_probe,
+ .remove = wl_glue_ssb_remove,
+};
+#endif /* CONFIG_SSB */
+
+#ifdef CONFIG_BCMA
+static int wl_glue_bcma_probe(struct bcma_device *dev)
+{
+ void *wldev;
+
+ if (!attach_cb)
+ {
+ pr_err("No attach callback registered\n");
+ return -ENOSYS;
+ }
+
+ if (dev->bus->hosttype != BCMA_HOSTTYPE_SOC)
+ {
+ pr_err("Unsupported BCMA bus type %d\n", dev->bus->hosttype);
+ return -EINVAL;
+ }
+
+ /*
+ * NB:
+ * 0x18000000 = BCMA_ADDR_BASE
+ * 0x1000 = BCMA_CORE_SIZE
+ */
+
+ wldev = attach_cb(dev->id.manuf, dev->id.id, (ulong)dev->addr, dev, dev->irq);
+
+ if (!wldev)
+ {
+ pr_err("The attach callback failed, BCMA probe aborted\n");
+ return -ENODEV;
+ }
+
+ bcma_set_drvdata(dev, wldev);
+ return 0;
+}
+
+static void wl_glue_bcma_remove(struct bcma_device *dev)
+{
+ void *wldev = bcma_get_drvdata(dev);
+
+ if (remove_cb)
+ remove_cb(wldev);
+
+ bcma_set_drvdata(dev, NULL);
+}
+
+static const struct bcma_device_id wl_glue_bcma_tbl[] = {
+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, BCMA_ANY_REV, BCMA_ANY_CLASS),
+ BCMA_CORETABLE_END
+};
+
+static struct bcma_driver wl_glue_bcma_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = wl_glue_bcma_tbl,
+ .probe = wl_glue_bcma_probe,
+ .remove = wl_glue_bcma_remove,
+};
+#endif /* CONFIG_BCMA */
+
+
+void wl_glue_set_attach_callback(wl_glue_attach_cb_t cb)
+{
+ attach_cb = cb;
+}
+EXPORT_SYMBOL(wl_glue_set_attach_callback);
+
+void wl_glue_set_remove_callback(wl_glue_remove_cb_t cb)
+{
+ remove_cb = cb;
+}
+EXPORT_SYMBOL(wl_glue_set_remove_callback);
+
+int wl_glue_register(void)
+{
+ int err;
+
+ switch(active_bus_type)
+ {
+#ifdef CONFIG_SSB
+ case WL_GLUE_BUS_TYPE_SSB:
+ err = ssb_driver_register(&wl_glue_ssb_driver);
+ break;
+#endif /* CONFIG_SSB */
+
+#ifdef CONFIG_BCMA
+ case WL_GLUE_BUS_TYPE_BCMA:
+ err = bcma_driver_register(&wl_glue_bcma_driver);
+ break;
+#endif /* CONFIG_BCMA */
+
+ default:
+ pr_err("Not attaching through glue driver due to unsupported bus\n");
+ err = -ENOSYS;
+ break;
+ }
+
+ if (!err)
+ {
+ pr_info("SSB/BCMA glue driver successfully attached\n");
+ wl_glue_attached = 1;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(wl_glue_register);
+
+int wl_glue_unregister(void)
+{
+ int err;
+
+ if (!wl_glue_attached)
+ return -ENOSYS;
+
+ switch (active_bus_type)
+ {
+#ifdef CONFIG_SSB
+ case WL_GLUE_BUS_TYPE_SSB:
+ ssb_driver_unregister(&wl_glue_ssb_driver);
+ err = 0;
+ break;
+#endif /* CONFIG_SSB */
+
+#ifdef CONFIG_BCMA
+ case WL_GLUE_BUS_TYPE_BCMA:
+ bcma_driver_unregister(&wl_glue_bcma_driver);
+ err = 0;
+ break;
+#endif /* CONFIG_BCMA */
+
+ default:
+ pr_err("Not removing glue driver due to unsupported bus\n");
+ err = -ENOSYS;
+ break;
+ }
+
+ if (!err)
+ {
+ pr_info("SSB/BCMA glue driver successfully detached\n");
+ wl_glue_attached = 0;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(wl_glue_unregister);
+
+struct device * wl_glue_get_dmadev(void *dev)
+{
+ struct device *dma_dev;
+
+ switch (active_bus_type)
+ {
+#ifdef CONFIG_SSB
+ case WL_GLUE_BUS_TYPE_SSB:
+ dma_dev = ((struct ssb_device *)dev)->dma_dev;
+ break;
+#endif /* CONFIG_SSB */
+
+#ifdef CONFIG_BCMA
+ case WL_GLUE_BUS_TYPE_BCMA:
+ dma_dev = ((struct bcma_device *)dev)->dma_dev;
+ break;
+#endif /* CONFIG_BCMA */
+
+ default:
+ BUG();
+ dma_dev = NULL;
+ break;
+ }
+
+ return dma_dev;
+}
+EXPORT_SYMBOL(wl_glue_get_dmadev);
+
+
+static int __init wl_glue_init(void)
+{
+#ifdef CONFIG_BCM47XX
+ /*
+ * BCM47xx currently supports either SSB or BCMA bus,
+ * determine the used one from the info set by the
+ * platform setup code.
+ */
+ switch (bcm47xx_bus_type)
+ {
+#ifdef CONFIG_SSB
+ case BCM47XX_BUS_TYPE_SSB:
+ active_bus_type = WL_GLUE_BUS_TYPE_SSB;
+ break;
+#endif /* CONFIG_SSB */
+
+#ifdef CONFIG_BCMA
+ case BCM47XX_BUS_TYPE_BCMA:
+ active_bus_type = WL_GLUE_BUS_TYPE_BCMA;
+ break;
+#endif /* CONFIG_BCMA */
+ }
+#endif /* CONFIG_BCM47XX */
+
+#ifdef CONFIG_BCM63XX
+#ifdef CONFIG_SSB
+ /*
+ * BCM63xx currently only uses SSB, so assume that.
+ */
+ active_bus_type = WL_GLUE_BUS_TYPE_SSB;
+#endif /* CONFIG_SSB */
+#endif /* CONFIG_BCM63XX */
+
+ /* do not fail here, let wl_glue_register() return -ENOSYS later */
+ if (active_bus_type == WL_GLUE_BUS_TYPE_UNSPEC)
+ pr_err("Unable to determine used system bus type\n");
+
+ return 0;
+}
+
+static void __exit wl_glue_exit(void)
+{
+ if (wl_glue_attached)
+ {
+ if (wl_glue_unregister())
+ pr_err("Failed to unregister glue driver\n");
+
+ wl_glue_attached = 0;
+ }
+
+ return;
+}
+
+module_init(wl_glue_init);
+module_exit(wl_glue_exit);
diff --git a/package/kernel/broadcom-wl/src/glue/wl_glue.h b/package/kernel/broadcom-wl/src/glue/wl_glue.h
new file mode 100644
index 0000000000..b3c8aa3b6a
--- /dev/null
+++ b/package/kernel/broadcom-wl/src/glue/wl_glue.h
@@ -0,0 +1,22 @@
+/*
+ * wl_glue.h: Broadcom WL support module providing a unified SSB/BCMA handling.
+ * Copyright (C) 2011 Jo-Philipp Wich <jow@openwrt.org>
+ */
+
+#include <linux/types.h>
+
+typedef void * (*wl_glue_attach_cb_t)(u16, u16, ulong, void *, u32);
+typedef void (*wl_glue_remove_cb_t)(void *);
+
+enum wl_glue_bus_type {
+ WL_GLUE_BUS_TYPE_UNSPEC,
+ WL_GLUE_BUS_TYPE_SSB,
+ WL_GLUE_BUS_TYPE_BCMA
+};
+
+extern void wl_glue_set_attach_callback(wl_glue_attach_cb_t cb);
+extern void wl_glue_set_remove_callback(wl_glue_remove_cb_t cb);
+extern int wl_glue_register(void);
+extern int wl_glue_unregister(void);
+extern struct device * wl_glue_get_dmadev(void *);
+
diff --git a/package/kernel/broadcom-wl/src/wlc.c b/package/kernel/broadcom-wl/src/wlc.c
new file mode 100644
index 0000000000..253809c9a3
--- /dev/null
+++ b/package/kernel/broadcom-wl/src/wlc.c
@@ -0,0 +1,1086 @@
+/*
+ * wlc - Broadcom Wireless Driver Control Utility
+ *
+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <glob.h>
+#include <ctype.h>
+
+#include <typedefs.h>
+#include <wlutils.h>
+#include <proto/802.11.h>
+
+#define VERSION "0.1"
+#define BUFSIZE 8192
+#define PTABLE_MAGIC 0xbadc0ded
+#define PTABLE_SLT1 1
+#define PTABLE_SLT2 2
+#define PTABLE_ACKW 3
+#define PTABLE_ADHM 4
+#define PTABLE_END 0xffffffff
+
+/*
+ * Copy each token in wordlist delimited by space into word
+ * Taken from Broadcom shutils.h
+ */
+#define foreach(word, wordlist, next) \
+ for (next = &wordlist[strspn(wordlist, " ")], \
+ strncpy(word, next, sizeof(word)), \
+ word[strcspn(word, " ")] = '\0', \
+ word[sizeof(word) - 1] = '\0', \
+ next = strchr(next, ' '); \
+ strlen(word); \
+ next = next ? &next[strspn(next, " ")] : "", \
+ strncpy(word, next, sizeof(word)), \
+ word[strcspn(word, " ")] = '\0', \
+ word[sizeof(word) - 1] = '\0', \
+ next = strchr(next, ' '))
+
+static char wlbuf[8192];
+static char interface[16] = "wl0";
+static unsigned long kmem_offset = 0;
+static int vif = 0, debug = 1, fromstdin = 0;
+
+typedef enum {
+ NONE = 0x00,
+
+ /* types */
+ PARAM_TYPE = 0x00f,
+ INT = 0x001,
+ STRING = 0x002,
+ MAC = 0x003,
+
+ /* options */
+ PARAM_OPTIONS = 0x0f0,
+ NOARG = 0x010,
+
+ /* modes */
+ PARAM_MODE = 0xf00,
+ GET = 0x100,
+ SET = 0x200,
+} wlc_param;
+
+struct wlc_call {
+ const char *name;
+ wlc_param param;
+ int (*handler)(wlc_param param, void *data, void *value);
+ union {
+ int num;
+ char *str;
+ void *ptr;
+ } data;
+ const char *desc;
+};
+
+/* can't use the system include because of the stupid broadcom header files */
+extern struct ether_addr *ether_aton(const char *asc);
+static inline int my_ether_ntoa(unsigned char *ea, char *buf)
+{
+ return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
+ ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]);
+}
+
+static int wlc_ioctl(wlc_param param, void *data, void *value)
+{
+ unsigned int *var = ((unsigned int *) data);
+ unsigned int ioc = *var;
+
+ if (param & NOARG) {
+ return wl_ioctl(interface, ioc, NULL, 0);
+ }
+ switch(param & PARAM_TYPE) {
+ case MAC:
+ return wl_ioctl(interface, ((param & SET) ? (ioc) : (ioc >> 16)) & 0xffff, value, 6);
+ case INT:
+ return wl_ioctl(interface, ((param & SET) ? (ioc) : (ioc >> 16)) & 0xffff, value, sizeof(int));
+ case STRING:
+ return wl_ioctl(interface, ((param & SET) ? (ioc) : (ioc >> 16)) & 0xffff, value, BUFSIZE);
+ }
+ return 0;
+}
+
+static int wlc_iovar(wlc_param param, void *data, void *value)
+{
+ int *val = (int *) value;
+ char *iov = *((char **) data);
+ int ret = 0;
+
+ if (param & SET) {
+ switch(param & PARAM_TYPE) {
+ case INT:
+ ret = wl_iovar_setint(interface, iov, *val);
+ break;
+ case MAC:
+ ret = wl_iovar_set(interface, iov, value, 6);
+ break;
+ }
+ }
+ if (param & GET) {
+ switch(param & PARAM_TYPE) {
+ case INT:
+ ret = wl_iovar_get(interface, iov, val, sizeof(int));
+ break;
+ case MAC:
+ ret = wl_iovar_get(interface, iov, value, 6);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int wlc_bssiovar(wlc_param param, void *data, void *value)
+{
+ int *val = (int *) value;
+ char *iov = *((char **) data);
+ int ret = 0;
+
+ if (param & SET) {
+ switch(param & PARAM_TYPE) {
+ case INT:
+ ret = wl_bssiovar_setint(interface, iov, vif, *val);
+ }
+ }
+ if (param & GET) {
+ switch(param & PARAM_TYPE) {
+ case INT:
+ ret = wl_bssiovar_get(interface, iov, vif, val, sizeof(int));
+ }
+ }
+
+ return ret;
+}
+
+static int wlc_vif_enabled(wlc_param param, void *data, void *value)
+{
+ int *val = (int *) value;
+ int buf[3];
+ int ret = 0;
+
+ sprintf((char *) buf, "bss");
+ buf[1] = vif;
+ if (param & SET) {
+ buf[2] = (*val ? 1 : 0);
+ ret = wl_ioctl(interface, WLC_SET_VAR, buf, sizeof(buf));
+ } else if (param & GET) {
+ ret = wl_ioctl(interface, WLC_GET_VAR, buf, sizeof(buf));
+ *val = buf[0];
+ }
+
+ return ret;
+}
+
+static int wlc_ssid(wlc_param param, void *data, void *value)
+{
+ int ret = -1, ret2 = -1;
+ char *dest = (char *) value;
+ wlc_ssid_t ssid;
+
+ if ((param & PARAM_MODE) == GET) {
+ ret = wl_bssiovar_get(interface, "ssid", vif, &ssid, sizeof(ssid));
+
+ if (ret)
+ /* if we can't get the ssid through the bssiovar, try WLC_GET_SSID */
+ ret = wl_ioctl(interface, WLC_GET_SSID, &ssid, sizeof(ssid));
+
+ if (!ret) {
+ memcpy(dest, ssid.SSID, ssid.SSID_len);
+ dest[ssid.SSID_len] = 0;
+ }
+ } else if ((param & PARAM_MODE) == SET) {
+ strncpy(ssid.SSID, value, 32);
+ ssid.SSID_len = strlen(value);
+
+ if (ssid.SSID_len > 32)
+ ssid.SSID_len = 32;
+
+ if (vif == 0) {
+ /* for the main interface, also try the WLC_SET_SSID call */
+ ret2 = wl_ioctl(interface, WLC_SET_SSID, &ssid, sizeof(ssid));
+ }
+
+ ret = wl_bssiovar_set(interface, "ssid", vif, &ssid, sizeof(ssid));
+ ret = (!ret2 ? 0 : ret);
+ }
+
+ return ret;
+}
+
+static int wlc_int(wlc_param param, void *data, void *value)
+{
+ int *var = *((int **) data);
+ int *val = (int *) value;
+
+ if ((param & PARAM_MODE) == SET) {
+ *var = *val;
+ } else if ((param & PARAM_MODE) == GET) {
+ *val = *var;
+ }
+
+ return 0;
+}
+
+static int wlc_flag(wlc_param param, void *data, void *value)
+{
+ int *var = *((int **) data);
+
+ *var = 1;
+
+ return 0;
+}
+
+static int wlc_string(wlc_param param, void *data, void *value)
+{
+ char *var = *((char **) data);
+
+ if ((param & PARAM_MODE) == GET) {
+ strcpy(value, var);
+ }
+
+ return 0;
+}
+
+static int wlc_afterburner(wlc_param param, void *data, void *value)
+{
+ int *val = (int *) value;
+ int ret = 0;
+
+ if ((param & PARAM_MODE) == GET) {
+ ret = wl_iovar_get(interface, "afterburner", val, sizeof(int));
+ } else {
+ wl_iovar_setint(interface, "wlfeatureflag", (*val ? 3 : 0));
+ ret = wl_iovar_setint(interface, "afterburner", (*val ? 1 : 0));
+ wl_iovar_setint(interface, "afterburner_override", *val);
+ }
+
+ return ret;
+}
+
+static int wlc_maclist(wlc_param param, void *data, void *value)
+{
+ unsigned int *var = ((unsigned int *) data);
+ unsigned int ioc = *var;
+ int limit = (sizeof(wlbuf) - 4) / sizeof(struct ether_addr);
+ struct maclist *list = (struct maclist *) wlbuf;
+ char *str = (char *) value;
+ char astr[30], *p;
+ struct ether_addr *addr;
+ int isset = 0;
+ int ret;
+
+ if ((param & PARAM_MODE) == GET) {
+ list->count = limit;
+ ret = wl_ioctl(interface, (ioc >> 16) & 0xffff, wlbuf, sizeof(wlbuf));
+
+ if (!ret)
+ while (list->count) {
+ str += sprintf(str, "%s", ((((char *) value) == str) ? "" : " "));
+ str += my_ether_ntoa((unsigned char *) &list->ea[list->count-- - 1], str);
+ }
+
+ return ret;
+ } else {
+ while (*str && isspace(*str))
+ *str++;
+
+ if (*str == '+') {
+ str++;
+
+ list->count = limit;
+ if (wl_ioctl(interface, (ioc >> 16) & 0xffff, wlbuf, sizeof(wlbuf)) == 0)
+ isset = 1;
+
+ while (*str && isspace(*str))
+ str++;
+ }
+
+ if (!isset)
+ memset(wlbuf, 0, sizeof(wlbuf));
+
+ foreach(astr, str, p) {
+ if (list->count >= limit)
+ break;
+
+ if ((addr = ether_aton(astr)) != NULL)
+ memcpy(&list->ea[list->count++], addr, sizeof(struct ether_addr));
+ }
+
+ return wl_ioctl(interface, ioc & 0xffff, wlbuf, sizeof(wlbuf));
+ }
+}
+
+static int wlc_radio(wlc_param param, void *data, void *value)
+{
+ int *val = (int *) value;
+ int ret;
+
+ if ((param & PARAM_MODE) == GET) {
+ ret = wl_ioctl(interface, WLC_GET_RADIO, val, sizeof(int));
+ *val = ((*val & 1) ? 0 : 1);
+ } else {
+ *val = (1 << 16) | (*val ? 0 : 1);
+ ret = wl_ioctl(interface, WLC_SET_RADIO, val, sizeof(int));
+ }
+
+ return ret;
+}
+
+static int wlc_wsec_key(wlc_param param, void *null, void *value)
+{
+ wl_wsec_key_t wsec_key;
+ unsigned char *index = value;
+ unsigned char *key;
+ unsigned char *data;
+ unsigned char hex[3];
+
+ if ((param & PARAM_MODE) != SET)
+ return 0;
+
+ memset(&wsec_key, 0, sizeof(wsec_key));
+ if (index[0] == '=') {
+ wsec_key.flags = WL_PRIMARY_KEY;
+ index++;
+ }
+
+ if ((index[0] < '1') || (index[0] > '4') || (index[1] != ','))
+ return -1;
+
+ key = index + 2;
+ if (strncmp(key, "d:", 2) == 0) { /* delete key */
+ } else if (strncmp(key, "s:", 2) == 0) { /* ascii key */
+ key += 2;
+ wsec_key.len = strlen(key);
+
+ if ((wsec_key.len != 5) && (wsec_key.len != 13))
+ return -1;
+
+ strcpy(wsec_key.data, key);
+ } else { /* hex key */
+ wsec_key.len = strlen(key);
+ if ((wsec_key.len != 10) && (wsec_key.len != 26))
+ return -1;
+
+ wsec_key.len /= 2;
+ data = wsec_key.data;
+ hex[2] = 0;
+ do {
+ hex[0] = *(key++);
+ hex[1] = *(key++);
+ *(data++) = (unsigned char) strtoul(hex, NULL, 16);
+ } while (*key != 0);
+ }
+
+ return wl_bssiovar_set(interface, "wsec_key", vif, &wsec_key, sizeof(wsec_key));
+}
+
+static inline int cw2ecw(int cw)
+{
+ int i;
+ for (cw++, i = 0; cw; i++) cw >>=1;
+ return i - 1;
+}
+
+static int wlc_wme_ac(wlc_param param, void *data, void *value)
+{
+ char *type = *((char **) data);
+ char *settings = (char *) value;
+ char cmd[100], *p, *val;
+ edcf_acparam_t params[AC_COUNT];
+ int ret;
+ int intval;
+ int cur = -1;
+ char *buf = wlbuf;
+
+ if ((param & PARAM_MODE) != SET)
+ return -1;
+
+ memset(params, 0, sizeof(params));
+ ret = wl_iovar_get(interface, type, params, sizeof(params));
+ memset(buf, 0, BUFSIZE);
+ strcpy(buf, type);
+ buf += strlen(buf) + 1;
+
+ foreach(cmd, settings, p) {
+ val = strchr(cmd, '=');
+ if (val == NULL) {
+ if (strcmp(cmd, "be") == 0)
+ cur = AC_BE;
+ else if (strcmp(cmd, "bk") == 0)
+ cur = AC_BK;
+ else if (strcmp(cmd, "vi") == 0)
+ cur = AC_VI;
+ else if (strcmp(cmd, "vo") == 0)
+ cur = AC_VO;
+ else
+ return -1;
+
+ /* just in case */
+ params[cur].ACI = (params[cur].ACI & (0x3 << 5)) | (cur << 5);
+ } else {
+ *(val++) = 0;
+
+ intval = strtoul(val, NULL, 10);
+ if (strcmp(cmd, "cwmin") == 0)
+ params[cur].ECW = (params[cur].ECW & ~(0xf)) | cw2ecw(intval);
+ else if (strcmp(cmd, "ecwmin") == 0)
+ params[cur].ECW = (params[cur].ECW & ~(0xf)) | (intval & 0xf);
+ else if (strcmp(cmd, "cwmax") == 0)
+ params[cur].ECW = (params[cur].ECW & ~(0xf << 4)) | (cw2ecw(intval) << 4);
+ else if (strcmp(cmd, "ecwmax") == 0)
+ params[cur].ECW = (params[cur].ECW & ~(0xf << 4)) | ((intval & 0xf) << 4);
+ else if (strcmp(cmd, "aifsn") == 0)
+ params[cur].ACI = (params[cur].ACI & ~(0xf)) | (intval & 0xf);
+ else if (strcmp(cmd, "txop") == 0)
+ params[cur].TXOP = intval >> 5;
+ else if (strcmp(cmd, "force") == 0)
+ params[cur].ACI = (params[cur].ACI & ~(1 << 4)) | ((intval) ? (1 << 4) : 0);
+ else return -1;
+
+ memcpy(buf, &params[cur], sizeof(edcf_acparam_t));
+ wl_ioctl(interface, WLC_SET_VAR, wlbuf, BUFSIZE);
+ }
+ }
+ return ret;
+}
+
+static int wlc_ifname(wlc_param param, void *data, void *value)
+{
+ char *val = (char *) value;
+ int ret = 0;
+
+ if (param & SET) {
+ if (strlen(val) < 16)
+ strcpy(interface, val);
+ else ret = -1;
+ }
+ if (param & GET) {
+ strcpy(val, interface);
+ }
+
+ return ret;
+}
+
+static int wlc_wdsmac(wlc_param param, void *data, void *value)
+{
+ unsigned char mac[6];
+ int ret = 0;
+
+ ret = wl_ioctl(interface, WLC_WDS_GET_REMOTE_HWADDR, &mac, 6);
+ if (ret == 0)
+ my_ether_ntoa(mac, value);
+
+ return ret;
+}
+
+static int wlc_pmk(wlc_param param, void *data, void *value)
+{
+ int ret = -1;
+ char *str = (char *) value;
+ wsec_pmk_t pmk;
+
+ /* driver doesn't support GET */
+
+ if ((param & PARAM_MODE) == SET) {
+ strncpy(pmk.key, value, WSEC_MAX_PSK_LEN);
+ pmk.key_len = strlen(value);
+
+ if (pmk.key_len > WSEC_MAX_PSK_LEN)
+ pmk.key_len = WSEC_MAX_PSK_LEN;
+
+ pmk.flags = WSEC_PASSPHRASE;
+
+ ret = wl_ioctl(interface, WLC_SET_WSEC_PMK, &pmk, sizeof(pmk));
+ }
+
+ return ret;
+}
+
+static const struct wlc_call wlc_calls[] = {
+ {
+ .name = "version",
+ .param = STRING|NOARG,
+ .handler = wlc_string,
+ .data.str = VERSION,
+ .desc = "Version of this program"
+ },
+ {
+ .name = "debug",
+ .param = INT,
+ .handler = wlc_int,
+ .data.ptr = &debug,
+ .desc = "wlc debug level"
+ },
+ {
+ .name = "stdin",
+ .param = NOARG,
+ .handler = wlc_flag,
+ .data.ptr = &fromstdin,
+ .desc = "Accept input from stdin"
+ },
+ {
+ .name = "ifname",
+ .param = STRING,
+ .handler = wlc_ifname,
+ .desc = "interface to send commands to"
+ },
+ {
+ .name = "up",
+ .param = NOARG,
+ .handler = wlc_ioctl,
+ .data.num = WLC_UP,
+ .desc = "Bring the interface up"
+ },
+ {
+ .name = "down",
+ .param = NOARG,
+ .handler = wlc_ioctl,
+ .data.num = WLC_DOWN,
+ .desc = "Bring the interface down"
+ },
+ {
+ .name = "radio",
+ .param = INT,
+ .handler = wlc_radio,
+ .desc = "Radio enabled flag"
+ },
+ {
+ .name = "ap",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_AP << 16) | WLC_SET_AP),
+ .desc = "Access Point mode"
+ },
+ {
+ .name = "mssid",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "mbss",
+ .desc = "Multi-ssid mode"
+ },
+ {
+ .name = "apsta",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "apsta",
+ .desc = "AP+STA mode"
+ },
+ {
+ .name = "infra",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_INFRA << 16) | WLC_SET_INFRA),
+ .desc = "Infrastructure mode"
+ },
+ {
+ .name = "wet",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_WET << 16) | WLC_SET_WET),
+ .desc = "Wireless repeater mode",
+ },
+ {
+ .name = "statimeout",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "sta_retry_time",
+ .desc = "STA connection timeout"
+ },
+ {
+ .name = "country",
+ .param = STRING,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_COUNTRY << 16) | WLC_SET_COUNTRY),
+ .desc = "Country code"
+ },
+ {
+ .name = "channel",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_CHANNEL << 16) | WLC_SET_CHANNEL),
+ .desc = "Channel",
+ },
+ {
+ .name = "vlan_mode",
+ .param = INT,
+ .handler = wlc_bssiovar,
+ .data.str = "vlan_mode",
+ .desc = "Parse 802.1Q tags",
+ },
+ {
+ .name = "vif",
+ .param = INT,
+ .handler = wlc_int,
+ .data.ptr = &vif,
+ .desc = "Current vif index"
+ },
+ {
+ .name = "enabled",
+ .param = INT,
+ .handler = wlc_vif_enabled,
+ .desc = "vif enabled flag"
+ },
+ {
+ .name = "ssid",
+ .param = STRING,
+ .handler = wlc_ssid,
+ .desc = "Interface ESSID"
+ },
+ {
+ .name = "closed",
+ .param = INT,
+ .handler = wlc_bssiovar,
+ .data.str = "closednet",
+ .desc = "Hidden ESSID flag"
+ },
+ {
+ .name = "wsec",
+ .param = INT,
+ .handler = wlc_bssiovar,
+ .data.str = "wsec",
+ .desc = "Security mode flags"
+ },
+ {
+ .name = "wepkey",
+ .param = STRING,
+ .handler = wlc_wsec_key,
+ .desc = "Set/Remove WEP keys"
+ },
+ {
+ .name = "wepauth",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_AUTH << 16) | WLC_SET_AUTH),
+ .desc = "WEP authentication type. 0 = OpenSystem, 1 = SharedKey"
+ },
+ {
+ .name = "wsec_restrict",
+ .param = INT,
+ .handler = wlc_bssiovar,
+ .data.str = "wsec_restrict",
+ .desc = "Drop unencrypted traffic"
+ },
+ {
+ .name = "eap_restrict",
+ .param = INT,
+ .handler = wlc_bssiovar,
+ .data.str = "eap_restrict",
+ .desc = "Only allow 802.1X traffic until 802.1X authorized"
+ },
+ {
+ .name = "wpa_auth",
+ .param = INT,
+ .handler = wlc_bssiovar,
+ .data.str = "wpa_auth",
+ .desc = "WPA authentication modes"
+ },
+ {
+ .name = "ap_isolate",
+ .param = INT,
+ .handler = wlc_bssiovar,
+ .data.str = "ap_isolate",
+ .desc = "Isolate connected clients"
+ },
+ {
+ .name = "supplicant",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "sup_wpa",
+ .desc = "Built-in WPA supplicant"
+ },
+ {
+ .name = "passphrase",
+ .param = STRING,
+ .handler = wlc_pmk,
+ .desc = "Passphrase for built-in WPA supplicant",
+ },
+ {
+ .name = "maxassoc",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "maxassoc",
+ .desc = "Max. number of associated clients",
+ },
+ {
+ .name = "wme",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "wme",
+ .desc = "WME enabled"
+ },
+ {
+ .name = "wme_ac_ap",
+ .param = STRING,
+ .handler = wlc_wme_ac,
+ .data.str = "wme_ac_ap",
+ .desc = "Set WME AC options for AP mode",
+ },
+ {
+ .name = "wme_ac_sta",
+ .param = STRING,
+ .handler = wlc_wme_ac,
+ .data.str = "wme_ac_sta",
+ .desc = "Set WME AC options for STA mode",
+ },
+ {
+ .name = "wme_noack",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "wme_noack",
+ .desc = "WME ACK disable request",
+ },
+ {
+ .name = "802.11d",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_REGULATORY << 16) | WLC_SET_REGULATORY),
+ .desc = "Enable/disable 802.11d regulatory management",
+ },
+ {
+ .name = "802.11h",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_SPECT_MANAGMENT << 16) | WLC_SET_SPECT_MANAGMENT),
+ .desc = "Enable/disable 802.11h spectrum management",
+ },
+ {
+ .name = "fragthresh",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "fragthresh",
+ .desc = "Fragmentation threshold",
+ },
+ {
+ .name = "rtsthresh",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "rtsthresh",
+ .desc = "RTS threshold"
+ },
+ {
+ .name = "slottime",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "acktiming",
+ .desc = "Slot time"
+ },
+ {
+ .name = "rxant",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_ANTDIV << 16) | WLC_SET_ANTDIV),
+ .desc = "Rx antenna selection"
+ },
+ {
+ .name = "txant",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_TXANT << 16) | WLC_SET_TXANT),
+ .desc = "Tx antenna selection"
+ },
+ {
+ .name = "dtim",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_DTIMPRD << 16) | WLC_SET_DTIMPRD),
+ .desc = "DTIM period",
+ },
+ {
+ .name = "bcn",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_BCNPRD << 16) | WLC_SET_BCNPRD),
+ .desc = "Beacon interval"
+ },
+ {
+ .name = "frameburst",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_FAKEFRAG << 16) | WLC_SET_FAKEFRAG),
+ .desc = "Framebursting"
+ },
+ {
+ .name = "monitor",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_MONITOR << 16) | WLC_SET_MONITOR),
+ .desc = "Monitor mode"
+ },
+ {
+ .name = "passive_scan",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_PASSIVE_SCAN << 16) | WLC_SET_PASSIVE_SCAN),
+ .desc = "Passive scan mode"
+ },
+ {
+ .name = "macfilter",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_MACMODE << 16) | WLC_SET_MACMODE),
+ .desc = "MAC filter mode (0:disabled, 1:deny, 2:allow)"
+ },
+ {
+ .name = "maclist",
+ .param = STRING,
+ .data.num = ((WLC_GET_MACLIST << 16) | WLC_SET_MACLIST),
+ .handler = wlc_maclist,
+ .desc = "MAC filter list"
+ },
+ {
+ .name = "autowds",
+ .param = INT,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_LAZYWDS << 16) | WLC_SET_LAZYWDS),
+ .desc = "Automatic WDS"
+ },
+ {
+ .name = "wds",
+ .param = STRING,
+ .data.num = ((WLC_GET_WDSLIST << 16) | WLC_SET_WDSLIST),
+ .handler = wlc_maclist,
+ .desc = "WDS connection list"
+ },
+ {
+ .name = "wdstimeout",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "wdstimeout",
+ .desc = "WDS link detection timeout"
+ },
+ {
+ .name = "wdsmac",
+ .param = STRING|NOARG,
+ .handler = wlc_wdsmac,
+ .desc = "MAC of the remote WDS endpoint (only with wds0.* interfaces)"
+ },
+ {
+ .name = "afterburner",
+ .param = INT,
+ .handler = wlc_afterburner,
+ .desc = "Broadcom Afterburner"
+ },
+ {
+ .name = "ibss_merge",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "ibss_coalesce_allowed",
+ .desc = "Allow IBSS merges"
+ },
+ {
+ .name = "bssid",
+ .param = MAC,
+ .handler = wlc_ioctl,
+ .data.num = ((WLC_GET_BSSID << 16) | WLC_SET_BSSID),
+ .desc = "BSSID"
+ },
+ {
+ .name = "default_bssid",
+ .param = MAC,
+ .handler = wlc_iovar,
+ .data.str = "perm_etheraddr",
+ .desc = "Default BSSID (read-only)"
+ },
+ {
+ .name = "assoclist",
+ .param = STRING,
+ .data.num = (WLC_GET_ASSOCLIST << 16),
+ .handler = wlc_maclist,
+ .desc = "MACs of associated stations"
+ },
+ {
+ .name = "gmode",
+ .param = INT,
+ .data.num = ((WLC_GET_GMODE << 16) | WLC_SET_GMODE),
+ .handler = wlc_ioctl,
+ .desc = "G Mode"
+ },
+};
+#define wlc_calls_size (sizeof(wlc_calls) / sizeof(struct wlc_call))
+
+static void usage(char *cmd)
+{
+ int i;
+ fprintf(stderr, "Usage: %s <command> [<argument> ...]\n"
+ "\n"
+ "Available commands:\n", cmd);
+ for (i = 0; i < wlc_calls_size; i++) {
+ fprintf(stderr, "\t%-16s\t%s\n", wlc_calls[i].name ?: "", wlc_calls[i].desc ?: "");
+ }
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+static int do_command(const struct wlc_call *cmd, char *arg)
+{
+ static char buf[BUFSIZE];
+ int set;
+ int ret = 0;
+ char *format, *end;
+ int intval;
+ void *ptr = (void *) buf;
+
+ if (debug >= 10) {
+ fprintf(stderr, "do_command %-16s\t'%s'\n", cmd->name, arg);
+ }
+
+ if ((arg == NULL) && ((cmd->param & PARAM_TYPE) != NONE)) {
+ set = 0;
+ ret = cmd->handler(cmd->param | GET, (void *) &cmd->data, (void *) buf);
+ if (ret == 0) {
+ switch(cmd->param & PARAM_TYPE) {
+ case INT:
+ intval = *((int *) buf);
+
+ if (intval > 65535)
+ format = "0x%08x\n";
+ else if (intval > 255)
+ format = "0x%04x\n";
+ else
+ format = "%d\n";
+
+ fprintf(stdout, format, intval);
+ break;
+ case STRING:
+ fprintf(stdout, "%s\n", buf);
+ break;
+ case MAC:
+ my_ether_ntoa(buf, buf + 6);
+ fprintf(stdout, "%s\n", buf + 6);
+ break;
+ }
+ }
+ } else { /* SET */
+ set = 1;
+ switch(cmd->param & PARAM_TYPE) {
+ case INT:
+ intval = strtoul(arg, &end, 10);
+ if (end && !(*end)) {
+ memcpy(buf, &intval, sizeof(intval));
+ } else {
+ fprintf(stderr, "%s: Invalid argument\n", cmd->name);
+ return -1;
+ }
+ break;
+ case STRING:
+ strncpy(buf, arg, BUFSIZE);
+ buf[BUFSIZE - 1] = 0;
+ break;
+ case MAC:
+ ptr = ether_aton(arg);
+ if (!ptr) {
+ fprintf(stderr, "%s: Invalid mac address '%s'\n", cmd->name, arg);
+ return -1;
+ }
+ break;
+ }
+
+ ret = cmd->handler(cmd->param | SET, (void *) &cmd->data, ptr);
+ }
+
+ if ((debug > 0) && (ret != 0))
+ fprintf(stderr, "Command '%s %s' failed: %d\n", (set == 1 ? "set" : "get"), cmd->name, ret);
+
+ return ret;
+}
+
+static struct wlc_call *find_cmd(char *name)
+{
+ int found = 0, i = 0;
+
+ while (!found && (i < wlc_calls_size)) {
+ if (strcmp(name, wlc_calls[i].name) == 0)
+ found = 1;
+ else
+ i++;
+ }
+
+ return (struct wlc_call *) (found ? &wlc_calls[i] : NULL);
+}
+
+int main(int argc, char **argv)
+{
+ static char buf[BUFSIZE];
+ char *s, *s2;
+ char *cmd = argv[0];
+ struct wlc_call *call;
+ int ret = 0;
+
+ if (argc < 2)
+ usage(argv[0]);
+
+ for(interface[2] = '0'; (interface[2] < '3') && (wl_probe(interface) != 0); interface[2]++);
+ if (interface[2] == '3') {
+ fprintf(stderr, "No Broadcom wl interface found!\n");
+ return -1;
+ }
+
+ argv++;
+ argc--;
+ while ((argc > 0) && (argv[0] != NULL)) {
+ if ((call = find_cmd(argv[0])) == NULL) {
+ fprintf(stderr, "Invalid command: %s\n\n", argv[0]);
+ usage(cmd);
+ }
+ if ((argc > 1) && (!(call->param & NOARG))) {
+ ret = do_command(call, argv[1]);
+ argv += 2;
+ argc -= 2;
+ } else {
+ ret = do_command(call, NULL);
+ argv++;
+ argc--;
+ }
+ }
+
+ while (fromstdin && !feof(stdin)) {
+ *buf = 0;
+ fgets(buf, BUFSIZE - 1, stdin);
+
+ if (*buf == 0)
+ continue;
+
+ if ((s = strchr(buf, '\r')) != NULL)
+ *s = 0;
+ if ((s = strchr(buf, '\n')) != NULL)
+ *s = 0;
+
+ s = buf;
+ while (isspace(*s))
+ s++;
+
+ if (!*s)
+ continue;
+
+ if ((s2 = strchr(buf, ' ')) != NULL)
+ *(s2++) = 0;
+
+ while (s2 && isspace(*s2))
+ s2++;
+
+ if ((call = find_cmd(buf)) == NULL) {
+ fprintf(stderr, "Invalid command: %s\n", buf);
+ ret = -1;
+ } else
+ ret = do_command(call, ((call->param & NOARG) ? NULL : s2));
+ }
+
+ return ret;
+}
diff --git a/package/kernel/button-hotplug/Makefile b/package/kernel/button-hotplug/Makefile
new file mode 100644
index 0000000000..348ea13401
--- /dev/null
+++ b/package/kernel/button-hotplug/Makefile
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2008-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=button-hotplug
+PKG_RELEASE:=3
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/button-hotplug
+ SUBMENU:=Other modules
+ TITLE:=Button Hotplug driver
+ FILES:=$(PKG_BUILD_DIR)/button-hotplug.ko
+ AUTOLOAD:=$(call AutoLoad,30,button-hotplug,1)
+ KCONFIG:=
+endef
+
+define KernelPackage/button-hotplug/description
+ Kernel module to generate button hotplug events
+endef
+
+EXTRA_KCONFIG:= \
+ CONFIG_BUTTON_HOTPLUG=m
+
+EXTRA_CFLAGS:= \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \
+
+MAKE_OPTS:= \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
+ $(EXTRA_KCONFIG)
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ $(MAKE_OPTS) \
+ modules
+endef
+
+$(eval $(call KernelPackage,button-hotplug))
diff --git a/package/kernel/button-hotplug/src/Kconfig b/package/kernel/button-hotplug/src/Kconfig
new file mode 100644
index 0000000000..aa292e9c13
--- /dev/null
+++ b/package/kernel/button-hotplug/src/Kconfig
@@ -0,0 +1,2 @@
+config BUTTON_HOTPLUG
+ tristate "Button Hotplug driver"
diff --git a/package/kernel/button-hotplug/src/Makefile b/package/kernel/button-hotplug/src/Makefile
new file mode 100644
index 0000000000..230d604f8c
--- /dev/null
+++ b/package/kernel/button-hotplug/src/Makefile
@@ -0,0 +1 @@
+obj-${CONFIG_BUTTON_HOTPLUG} += button-hotplug.o \ No newline at end of file
diff --git a/package/kernel/button-hotplug/src/button-hotplug.c b/package/kernel/button-hotplug/src/button-hotplug.c
new file mode 100644
index 0000000000..4a8c4a88ed
--- /dev/null
+++ b/package/kernel/button-hotplug/src/button-hotplug.c
@@ -0,0 +1,349 @@
+/*
+ * Button Hotplug driver
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * Based on the diag.c - GPIO interface driver for Broadcom boards
+ * Copyright (C) 2006 Mike Baker <mbm@openwrt.org>,
+ * Copyright (C) 2006-2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2008 Andy Boyett <agb@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kmod.h>
+#include <linux/input.h>
+
+#include <linux/workqueue.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/kobject.h>
+
+#define DRV_NAME "button-hotplug"
+#define DRV_VERSION "0.4.1"
+#define DRV_DESC "Button Hotplug driver"
+
+#define BH_SKB_SIZE 2048
+
+#define PFX DRV_NAME ": "
+
+#undef BH_DEBUG
+
+#ifdef BH_DEBUG
+#define BH_DBG(fmt, args...) printk(KERN_DEBUG "%s: " fmt, DRV_NAME, ##args )
+#else
+#define BH_DBG(fmt, args...) do {} while (0)
+#endif
+
+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, DRV_NAME, ##args )
+
+#ifndef BIT_MASK
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#endif
+
+struct bh_priv {
+ unsigned long *seen;
+ struct input_handle handle;
+};
+
+struct bh_event {
+ const char *name;
+ char *action;
+ unsigned long seen;
+
+ struct sk_buff *skb;
+ struct work_struct work;
+};
+
+struct bh_map {
+ unsigned int code;
+ const char *name;
+};
+
+extern u64 uevent_next_seqnum(void);
+
+#define BH_MAP(_code, _name) \
+ { \
+ .code = (_code), \
+ .name = (_name), \
+ }
+
+static struct bh_map button_map[] = {
+ BH_MAP(BTN_0, "BTN_0"),
+ BH_MAP(BTN_1, "BTN_1"),
+ BH_MAP(BTN_2, "BTN_2"),
+ BH_MAP(BTN_3, "BTN_3"),
+ BH_MAP(BTN_4, "BTN_4"),
+ BH_MAP(BTN_5, "BTN_5"),
+ BH_MAP(BTN_6, "BTN_6"),
+ BH_MAP(BTN_7, "BTN_7"),
+ BH_MAP(BTN_8, "BTN_8"),
+ BH_MAP(BTN_9, "BTN_9"),
+ BH_MAP(KEY_RESTART, "reset"),
+#ifdef KEY_WPS_BUTTON
+ BH_MAP(KEY_WPS_BUTTON, "wps"),
+#endif /* KEY_WPS_BUTTON */
+};
+
+/* -------------------------------------------------------------------------*/
+
+static int bh_event_add_var(struct bh_event *event, int argv,
+ const char *format, ...)
+{
+ static char buf[128];
+ char *s;
+ va_list args;
+ int len;
+
+ if (argv)
+ return 0;
+
+ va_start(args, format);
+ len = vsnprintf(buf, sizeof(buf), format, args);
+ va_end(args);
+
+ if (len >= sizeof(buf)) {
+ BH_ERR("buffer size too small\n");
+ WARN_ON(1);
+ return -ENOMEM;
+ }
+
+ s = skb_put(event->skb, len + 1);
+ strcpy(s, buf);
+
+ BH_DBG("added variable '%s'\n", s);
+
+ return 0;
+}
+
+static int button_hotplug_fill_event(struct bh_event *event)
+{
+ int ret;
+
+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "PATH=%s",
+ "/sbin:/bin:/usr/sbin:/usr/bin");
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=%s", "button");
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "ACTION=%s", event->action);
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "BUTTON=%s", event->name);
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "SEEN=%ld", event->seen);
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
+
+ return ret;
+}
+
+static void button_hotplug_work(struct work_struct *work)
+{
+ struct bh_event *event = container_of(work, struct bh_event, work);
+ int ret = 0;
+
+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
+ if (!event->skb)
+ goto out_free_event;
+
+ ret = bh_event_add_var(event, 0, "%s@", event->action);
+ if (ret)
+ goto out_free_skb;
+
+ ret = button_hotplug_fill_event(event);
+ if (ret)
+ goto out_free_skb;
+
+ NETLINK_CB(event->skb).dst_group = 1;
+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
+
+ out_free_skb:
+ if (ret) {
+ BH_ERR("work error %d\n", ret);
+ kfree_skb(event->skb);
+ }
+ out_free_event:
+ kfree(event);
+}
+
+static int button_hotplug_create_event(const char *name, unsigned long seen,
+ int pressed)
+{
+ struct bh_event *event;
+
+ BH_DBG("create event, name=%s, seen=%lu, pressed=%d\n",
+ name, seen, pressed);
+
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
+ if (!event)
+ return -ENOMEM;
+
+ event->name = name;
+ event->seen = seen;
+ event->action = pressed ? "pressed" : "released";
+
+ INIT_WORK(&event->work, (void *)(void *)button_hotplug_work);
+ schedule_work(&event->work);
+
+ return 0;
+}
+
+/* -------------------------------------------------------------------------*/
+
+#ifdef CONFIG_HOTPLUG
+static int button_get_index(unsigned int code)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(button_map); i++)
+ if (button_map[i].code == code)
+ return i;
+
+ return -1;
+}
+static void button_hotplug_event(struct input_handle *handle,
+ unsigned int type, unsigned int code, int value)
+{
+ struct bh_priv *priv = handle->private;
+ unsigned long seen = jiffies;
+ int btn;
+
+ BH_DBG("event type=%u, code=%u, value=%d\n", type, code, value);
+
+ if (type != EV_KEY)
+ return;
+
+ btn = button_get_index(code);
+ if (btn < 0)
+ return;
+
+ button_hotplug_create_event(button_map[btn].name,
+ (seen - priv->seen[btn]) / HZ, value);
+ priv->seen[btn] = seen;
+}
+#else
+static void button_hotplug_event(struct input_handle *handle,
+ unsigned int type, unsigned int code, int value)
+{
+}
+#endif /* CONFIG_HOTPLUG */
+
+static int button_hotplug_connect(struct input_handler *handler,
+ struct input_dev *dev, const struct input_device_id *id)
+{
+ struct bh_priv *priv;
+ int ret;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(button_map); i++)
+ if (test_bit(button_map[i].code, dev->keybit))
+ break;
+
+ if (i == ARRAY_SIZE(button_map))
+ return -ENODEV;
+
+ priv = kzalloc(sizeof(*priv) +
+ (sizeof(unsigned long) * ARRAY_SIZE(button_map)),
+ GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->seen = (unsigned long *) &priv[1];
+ priv->handle.private = priv;
+ priv->handle.dev = dev;
+ priv->handle.handler = handler;
+ priv->handle.name = DRV_NAME;
+
+ ret = input_register_handle(&priv->handle);
+ if (ret)
+ goto err_free_priv;
+
+ ret = input_open_device(&priv->handle);
+ if (ret)
+ goto err_unregister_handle;
+
+ BH_DBG("connected to %s\n", dev->name);
+
+ return 0;
+
+ err_unregister_handle:
+ input_unregister_handle(&priv->handle);
+
+ err_free_priv:
+ kfree(priv);
+ return ret;
+}
+
+static void button_hotplug_disconnect(struct input_handle *handle)
+{
+ struct bh_priv *priv = handle->private;
+
+ input_close_device(handle);
+ input_unregister_handle(handle);
+
+ kfree(priv);
+}
+
+static const struct input_device_id button_hotplug_ids[] = {
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+ .evbit = { BIT_MASK(EV_KEY) },
+ },
+ {
+ /* Terminating entry */
+ },
+};
+
+MODULE_DEVICE_TABLE(input, button_hotplug_ids);
+
+static struct input_handler button_hotplug_handler = {
+ .event = button_hotplug_event,
+ .connect = button_hotplug_connect,
+ .disconnect = button_hotplug_disconnect,
+ .name = DRV_NAME,
+ .id_table = button_hotplug_ids,
+};
+
+/* -------------------------------------------------------------------------*/
+
+static int __init button_hotplug_init(void)
+{
+ int ret;
+
+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
+ ret = input_register_handler(&button_hotplug_handler);
+ if (ret)
+ BH_ERR("unable to register input handler\n");
+
+ return ret;
+}
+module_init(button_hotplug_init);
+
+static void __exit button_hotplug_exit(void)
+{
+ input_unregister_handler(&button_hotplug_handler);
+}
+module_exit(button_hotplug_exit);
+
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/package/kernel/ep80579-drivers/Makefile b/package/kernel/ep80579-drivers/Makefile
new file mode 100644
index 0000000000..61d3bc2a1f
--- /dev/null
+++ b/package/kernel/ep80579-drivers/Makefile
@@ -0,0 +1,92 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ep80579-drivers
+PKG_VERSION:=1.0.34
+PKG_RELEASE:=1
+
+PKG_SOURCE:=Embedded.L.1.0.34.ADI.R100.tar.gz
+PKG_SOURCE_URL:=ftp://ftp.adiengineering.com/Archive/OcracokeIsland/Drivers/Linux/1.0.34/
+PKG_MD5SUM:=61df9778f8c1f919257d2f48a0bcb000
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ep80579-drivers/Default
+ DEPENDS:=@TARGET_x86_ep80579
+endef
+
+define KernelPackage/ep80579-eth
+$(call KernelPackage/ep80579-drivers/Default)
+ SUBMENU:=Network Devices
+ TITLE:=Intel EP80579 ethernet driver
+ FILES:= \
+ $(PKG_BUILD_DIR)/Embedded/src/GbE/gcu.ko \
+ $(PKG_BUILD_DIR)/Embedded/src/GbE/iegbe.ko
+ AUTOLOAD:=$(call AutoLoad,40,gcu iegbe)
+endef
+
+define KernelPackage/ep80579-misc
+$(call KernelPackage/ep80579-drivers/Default)
+ SUBMENU:=Other modules
+ TITLE:=Misc. Intel EP80579 drivers (DMA,, gpio)
+ FILES:= \
+ $(PKG_BUILD_DIR)/Embedded/src/EDMA/dma.ko \
+ $(PKG_BUILD_DIR)/Embedded/src/GPIO/gpio.ko
+ AUTOLOAD:=$(call AutoLoad,40,gpio dma)
+endef
+
+define KernelPackage/ep80579-can
+$(call KernelPackage/ep80579-drivers/Default)
+ SUBMENU:=Other modules
+ TITLE:=Intel EP80579 CAN driver
+ FILES:= \
+ $(PKG_BUILD_DIR)/Embedded/src/1588/timesync.ko \
+ $(PKG_BUILD_DIR)/Embedded/src/CAN/can.ko
+ AUTOLOAD:=$(call AutoLoad,40,timesync can)
+endef
+
+define Build/Prepare
+ rm -rf $(PKG_BUILD_DIR)
+ mkdir -p $(PKG_BUILD_DIR)
+ tar xzvf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR)/
+ $(Build/Patch)
+endef
+
+define Build/Compile/Subdir
+ $(MAKE) -C "$(LINUX_DIR)" \
+ KSRC="$(LINUX_DIR)" \
+ KOBJ="$(LINUX_DIR)" \
+ ENV_DIR=$(PKG_BUILD_DIR)/Embedded \
+ SUBDIRS="$(PKG_BUILD_DIR)/Embedded/src/$(1)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ ARCHIVER="$(TARGET_CROSS)ar" \
+ COMPILER="$(TARGET_CC)" \
+ LINKER="$(TARGET_CROSS)ld" \
+ ARCH="$(LINUX_KARCH)"
+endef
+
+define Build/Compile
+ $(call Build/Compile/Subdir,GbE)
+ $(call Build/Compile/Subdir,CAN)
+ $(call Build/Compile/Subdir,EDMA)
+ $(call Build/Compile/Subdir,GPIO)
+ $(call Build/Compile/Subdir,WDT)
+ $(call Build/Compile/Subdir,1588)
+endef
+
+define KernelPackage/ep80579-eth/install
+endef
+
+$(eval $(call KernelPackage,ep80579-can))
+$(eval $(call KernelPackage,ep80579-eth))
+$(eval $(call KernelPackage,ep80579-misc))
+
diff --git a/package/kernel/ep80579-drivers/patches/001-igbe_update.patch b/package/kernel/ep80579-drivers/patches/001-igbe_update.patch
new file mode 100644
index 0000000000..d78d1a9b13
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/001-igbe_update.patch
@@ -0,0 +1,11755 @@
+--- a/Embedded/src/GbE/gcu.h
++++ b/Embedded/src/GbE/gcu.h
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+--- a/Embedded/src/GbE/gcu_if.c
++++ b/Embedded/src/GbE/gcu_if.c
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+@@ -330,10 +330,17 @@ gcu_write_verify(uint32_t phy_num, uint3
+ */
+ void gcu_iegbe_resume(struct pci_dev *pdev)
+ {
++#if ( ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,6) ) && \
++ ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) ) )
++ struct net_device *netdev = pci_get_drvdata(pdev);
++ struct gcu_adapter *adapter = netdev_priv(netdev);
++#endif
++
+ GCU_DBG("%s\n", __func__);
+
+ pci_restore_state(pdev);
+- pci_enable_device(pdev);
++ if(!pci_enable_device(pdev))
++ GCU_DBG("pci_enable_device failed!\n",);
+
+ return;
+ }
+@@ -348,6 +355,12 @@ EXPORT_SYMBOL(gcu_iegbe_resume);
+ */
+ int gcu_iegbe_suspend(struct pci_dev *pdev, uint32_t state)
+ {
++#if ( ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,6) ) && \
++ ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) ) )
++ struct net_device *netdev = pci_get_drvdata(pdev);
++ struct gcu_adapter *adapter = netdev_priv(netdev);
++#endif
++
+ GCU_DBG("%s\n", __func__);
+
+ pci_save_state(pdev);
+--- a/Embedded/src/GbE/gcu_if.h
++++ b/Embedded/src/GbE/gcu_if.h
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+--- a/Embedded/src/GbE/gcu_main.c
++++ b/Embedded/src/GbE/gcu_main.c
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+@@ -94,6 +94,7 @@ static struct pci_driver gcu_driver = {
+
+ static struct gcu_adapter *global_adapter = 0;
+ static spinlock_t global_adapter_spinlock = SPIN_LOCK_UNLOCKED;
++static unsigned long g_intflags = 0;
+
+ MODULE_AUTHOR("Intel(R) Corporation");
+ MODULE_DESCRIPTION("Global Configuration Unit Driver");
+@@ -124,7 +125,7 @@ gcu_init_module(void)
+
+ printk(KERN_INFO "%s\n", gcu_copyright);
+
+- ret = pci_module_init(&gcu_driver);
++ ret = pci_register_driver(&gcu_driver);
+ if(ret >= 0) {
+ register_reboot_notifier(&gcu_notifier_reboot);
+ }
+@@ -199,8 +200,6 @@ gcu_probe(struct pci_dev *pdev,
+ return -ENOMEM;
+ }
+
+- SET_MODULE_OWNER(adapter);
+-
+ pci_set_drvdata(pdev, adapter);
+
+ adapter->pdev = pdev;
+@@ -238,7 +237,6 @@ gcu_probe(struct pci_dev *pdev,
+ return 0;
+ }
+
+-
+ /**
+ * gcu_probe_err - gcu_probe error handler
+ * @err: gcu_err_type
+@@ -295,7 +293,7 @@ gcu_notify_reboot(struct notifier_block
+ case SYS_DOWN:
+ case SYS_HALT:
+ case SYS_POWER_OFF:
+- while((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
++ while((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
+ if(pci_dev_driver(pdev) == &gcu_driver){
+ gcu_suspend(pdev, 0x3);
+ }
+@@ -318,6 +316,11 @@ static int
+ gcu_suspend(struct pci_dev *pdev, uint32_t state)
+ {
+ /*struct gcu_adapter *adapter = pci_get_drvdata(pdev); */
++#if ( ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,6) ) && \
++ ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) ) )
++ struct net_device *netdev = pci_get_drvdata(pdev);
++ struct gcu_adapter *adapter = netdev_priv(netdev);
++#endif
+
+ GCU_DBG("%s\n", __func__);
+
+@@ -338,7 +341,6 @@ gcu_suspend(struct pci_dev *pdev, uint32
+ return state;
+ }
+
+-
+ /**
+ * alloc_gcu_adapter
+ *
+@@ -412,7 +414,7 @@ gcu_get_adapter(void)
+ return NULL;
+ }
+
+- spin_lock(&global_adapter_spinlock);
++ spin_lock_irqsave(&global_adapter_spinlock, g_intflags);
+
+ return global_adapter;
+ }
+@@ -437,7 +439,7 @@ gcu_release_adapter(const struct gcu_ada
+ *adapter = 0;
+ }
+
+- spin_unlock(&global_adapter_spinlock);
++ spin_unlock_irqrestore(&global_adapter_spinlock, g_intflags);
+
+ return;
+ }
+--- a/Embedded/src/GbE/gcu_reg.h
++++ b/Embedded/src/GbE/gcu_reg.h
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+--- a/Embedded/src/GbE/iegbe.7
++++ b/Embedded/src/GbE/iegbe.7
+@@ -1,7 +1,7 @@
+
+ .\" GPL LICENSE SUMMARY
+ .\"
+-.\" Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++.\" Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ .\"
+ .\" This program is free software; you can redistribute it and/or modify
+ .\" it under the terms of version 2 of the GNU General Public License as
+@@ -21,7 +21,7 @@
+ .\" Contact Information:
+ .\" Intel Corporation
+ .\"
+-.\" version: Embedded.L.1.0.34
++.\" version: Embedded.Release.Patch.L.1.0.7-5
+
+ .\" LICENSE
+ .\"
+--- a/Embedded/src/GbE/iegbe_ethtool.c
++++ b/Embedded/src/GbE/iegbe_ethtool.c
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+@@ -132,22 +132,6 @@ static const struct iegbe_stats iegbe_gs
+ { "cpp_master", E1000_STAT(icr_cpp_master) },
+ { "stat", E1000_STAT(icr_stat) },
+ #endif
+-#ifdef IEGBE_GBE_WORKAROUND
+- { "txqec", E1000_STAT(stats.txqec) },
+- { "tx_next_to_clean", E1000_STAT(stats.tx_next_to_clean) },
+- { "tx_next_to_use", E1000_STAT(stats.tx_next_to_use) },
+- { "num_tx_queues", E1000_STAT(stats.num_tx_queues) },
+-
+- { "num_rx_buf_alloc", E1000_STAT(stats.num_rx_buf_alloc) },
+- { "rx_next_to_clean", E1000_STAT(stats.rx_next_to_clean) },
+- { "rx_next_to_use", E1000_STAT(stats.rx_next_to_use) },
+- { "cc_gt_num_rx", E1000_STAT(stats.cc_gt_num_rx) },
+- { "tx_hnet", E1000_STAT(stats.tx_hnet) },
+- { "tx_hnentu", E1000_STAT(stats.tx_hnentu) },
+- { "RUC", E1000_STAT(stats.ruc) },
+- { "RFC", E1000_STAT(stats.rfc) },
+-
+-#endif
+ };
+ #define E1000_STATS_LEN \
+ sizeof(iegbe_gstrings_stats) / sizeof(struct iegbe_stats)
+@@ -158,7 +142,7 @@ static const char iegbe_gstrings_test[][
+ "Interrupt test (offline)", "Loopback test (offline)",
+ "Link test (on/offline)"
+ };
+-#define E1000_TEST_LEN (sizeof(iegbe_gstrings_test) / (ETH_GSTRING_LEN))
++#define E1000_TEST_LEN (sizeof(iegbe_gstrings_test) / ETH_GSTRING_LEN)
+ #endif /* ETHTOOL_TEST */
+
+ #define E1000_REGS_LEN 0x20
+@@ -176,9 +160,7 @@ iegbe_get_settings(struct net_device *ne
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+-#ifndef IEGBE_10_100_ONLY
+ SUPPORTED_1000baseT_Full|
+-#endif
+ SUPPORTED_Autoneg |
+ SUPPORTED_TP);
+
+@@ -259,21 +241,13 @@ iegbe_set_settings(struct net_device *ne
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+-#ifndef IEGBE_10_100_ONLY
+ ADVERTISED_1000baseT_Full|
+-#endif
+-
+ ADVERTISED_Autoneg |
+ ADVERTISED_TP;
+ ecmd->advertising = hw->autoneg_advertised;
+ }
+- } else {
+- uint16_t duplex;
+-
+- // ethtool uses DUPLEX_FULL/DUPLEX_HALF
+- // the driver needs FULL_DUPLEX/HALF_DUPLEX
+- duplex = (ecmd->duplex == DUPLEX_FULL) ? FULL_DUPLEX : HALF_DUPLEX;
+- if(iegbe_set_spd_dplx(adapter, ecmd->speed + duplex))
++ } else
++ if(iegbe_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)){
+ return -EINVAL;
+ }
+ /* reset the link */
+@@ -728,8 +702,8 @@ iegbe_set_ringparam(struct net_device *n
+ struct iegbe_rx_ring *rxdr, *rx_old, *rx_new;
+ int i, err, tx_ring_size, rx_ring_size;
+
+- tx_ring_size = sizeof(struct iegbe_tx_ring) * adapter->num_queues;
+- rx_ring_size = sizeof(struct iegbe_rx_ring) * adapter->num_queues;
++ tx_ring_size = sizeof(struct iegbe_tx_ring) * adapter->num_tx_queues;
++ rx_ring_size = sizeof(struct iegbe_rx_ring) * adapter->num_rx_queues;
+
+ if (netif_running(adapter->netdev)){
+ iegbe_down(adapter);
+@@ -768,10 +742,10 @@ iegbe_set_ringparam(struct net_device *n
+ E1000_MAX_TXD : E1000_MAX_82544_TXD));
+ E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE);
+
+- for (i = 0; i < adapter->num_queues; i++) {
+- txdr[i].count = txdr->count;
+- rxdr[i].count = rxdr->count;
+- }
++ for (i = 0; i < adapter->num_tx_queues; i++)
++ txdr[i].count = txdr->count;
++ for (i = 0; i < adapter->num_rx_queues; i++)
++ rxdr[i].count = rxdr->count;
+
+ if(netif_running(adapter->netdev)) {
+ /* Try to get new resources before deleting old */
+@@ -950,8 +924,7 @@ iegbe_eeprom_test(struct iegbe_adapter *
+
+ static irqreturn_t
+ iegbe_test_intr(int irq,
+- void *data,
+- struct pt_regs *regs)
++ void *data)
+ {
+ struct net_device *netdev = (struct net_device *) data;
+ struct iegbe_adapter *adapter = netdev_priv(netdev);
+@@ -973,7 +946,7 @@ iegbe_intr_test(struct iegbe_adapter *ad
+ /* Hook up test interrupt handler just for this test */
+ if(!request_irq(irq, &iegbe_test_intr, 0, netdev->name, netdev)) {
+ shared_int = FALSE;
+- } else if(request_irq(irq, &iegbe_test_intr, SA_SHIRQ,
++ } else if(request_irq(irq, &iegbe_test_intr, IRQF_SHARED,
+ netdev->name, netdev)){
+ *data = 1;
+ return -1;
+@@ -1393,7 +1366,7 @@ iegbe_set_phy_loopback(struct iegbe_adap
+ * attempt this 10 times.
+ */
+ while(iegbe_nonintegrated_phy_loopback(adapter) &&
+- count++ < 0xa) { };
++ count++ < 0xa);
+ if(count < 0xb) {
+ return 0;
+ }
+--- a/Embedded/src/GbE/iegbe.h
++++ b/Embedded/src/GbE/iegbe.h
+@@ -1,7 +1,7 @@
+ /*******************************************************************************
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -21,7 +21,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+@@ -127,9 +127,12 @@ struct iegbe_adapter;
+ #define E1000_MIN_RXD 80
+ #define E1000_MAX_82544_RXD 4096
+
++#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
+ /* Supported Rx Buffer Sizes */
+ #define E1000_RXBUFFER_128 128 /* Used for packet split */
+ #define E1000_RXBUFFER_256 256 /* Used for packet split */
++#define E1000_RXBUFFER_512 512
++#define E1000_RXBUFFER_1024 1024
+ #define E1000_RXBUFFER_2048 2048
+ #define E1000_RXBUFFER_4096 4096
+ #define E1000_RXBUFFER_8192 8192
+@@ -164,11 +167,9 @@ struct iegbe_adapter;
+ #define E1000_MASTER_SLAVE iegbe_ms_hw_default
+ #endif
+
+-#ifdef NETIF_F_HW_VLAN_TX
+-#define E1000_MNG_VLAN_NONE -1
+-#endif
++#define E1000_MNG_VLAN_NONE (-1)
+ /* Number of packet split data buffers (not including the header buffer) */
+-#define PS_PAGE_BUFFERS MAX_PS_BUFFERS-1
++#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
+
+ /* only works for sizes that are powers of 2 */
+ #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
+@@ -206,6 +207,7 @@ struct iegbe_tx_ring {
+ spinlock_t tx_lock;
+ uint16_t tdh;
+ uint16_t tdt;
++ boolean_t last_tx_tso;
+ uint64_t pkt;
+ };
+
+@@ -228,6 +230,9 @@ struct iegbe_rx_ring {
+ struct iegbe_ps_page *ps_page;
+ struct iegbe_ps_page_dma *ps_page_dma;
+
++ /* cpu for rx queue */
++ int cpu;
++
+ uint16_t rdh;
+ uint16_t rdt;
+ uint64_t pkt;
+@@ -252,10 +257,8 @@ struct iegbe_adapter {
+ struct timer_list tx_fifo_stall_timer;
+ struct timer_list watchdog_timer;
+ struct timer_list phy_info_timer;
+-#ifdef NETIF_F_HW_VLAN_TX
+ struct vlan_group *vlgrp;
+ uint16_t mng_vlan_id;
+-#endif
+ uint32_t bd_number;
+ uint32_t rx_buffer_len;
+ uint32_t part_num;
+@@ -265,8 +268,18 @@ struct iegbe_adapter {
+ uint16_t link_speed;
+ uint16_t link_duplex;
+ spinlock_t stats_lock;
+- atomic_t irq_sem;
+- struct work_struct tx_timeout_task;
++ spinlock_t tx_queue_lock;
++ unsigned int total_tx_bytes;
++ unsigned int total_tx_packets;
++ unsigned int total_rx_bytes;
++ unsigned int total_rx_packets;
++ /* Interrupt Throttle Rate */
++ uint32_t itr;
++ uint32_t itr_setting;
++ uint16_t tx_itr;
++ uint16_t rx_itr;
++
++ struct work_struct reset_task;
+ uint8_t fc_autoneg;
+
+ #ifdef ETHTOOL_PHYS_ID
+@@ -276,9 +289,8 @@ struct iegbe_adapter {
+
+ /* TX */
+ struct iegbe_tx_ring *tx_ring; /* One per active queue */
+-#ifdef CONFIG_E1000_MQ
+- struct iegbe_tx_ring **cpu_tx_ring; /* per-cpu */
+-#endif
++ unsigned int restart_queue;
++ unsigned long tx_queue_len;
+ uint32_t txd_cmd;
+ uint32_t tx_int_delay;
+ uint32_t tx_abs_int_delay;
+@@ -286,46 +298,33 @@ struct iegbe_adapter {
+ uint64_t gotcl_old;
+ uint64_t tpt_old;
+ uint64_t colc_old;
++ uint32_t tx_timeout_count;
+ uint32_t tx_fifo_head;
+ uint32_t tx_head_addr;
+ uint32_t tx_fifo_size;
++ uint8_t tx_timeout_factor;
+ atomic_t tx_fifo_stall;
+ boolean_t pcix_82544;
+ boolean_t detect_tx_hung;
+
+ /* RX */
+-#ifdef CONFIG_E1000_NAPI
+- boolean_t (*clean_rx) (struct iegbe_adapter *adapter,
++ bool (*clean_rx)(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring,
+ int *work_done, int work_to_do);
+-#else
+- boolean_t (*clean_rx) (struct iegbe_adapter *adapter,
+- struct iegbe_rx_ring *rx_ring);
+-#endif
+-
+-#ifdef IEGBE_GBE_WORKAROUND
+ void (*alloc_rx_buf) (struct iegbe_adapter *adapter,
+- struct iegbe_rx_ring *rx_ring,
+- int cleaned_count);
+-#else
+- void (*alloc_rx_buf) (struct iegbe_adapter *adapter,
+- struct iegbe_rx_ring *rx_ring);
+-#endif
+-
++ struct iegbe_rx_ring *rx_ring,
++ int cleaned_count);
+ struct iegbe_rx_ring *rx_ring; /* One per active queue */
+-#ifdef CONFIG_E1000_NAPI
++ struct napi_struct napi;
+ struct net_device *polling_netdev; /* One per active queue */
+-#endif
+-#ifdef CONFIG_E1000_MQ
+- struct net_device **cpu_netdev; /* per-cpu */
+- struct call_async_data_struct rx_sched_call_data;
+- int cpu_for_queue[4];
+-#endif
+- int num_queues;
++
++ int num_tx_queues;
++ int num_rx_queues;
+
+ uint64_t hw_csum_err;
+ uint64_t hw_csum_good;
+ uint64_t rx_hdr_split;
++ uint32_t alloc_rx_buff_failed;
+ uint32_t rx_int_delay;
+ uint32_t rx_abs_int_delay;
+ boolean_t rx_csum;
+@@ -334,8 +333,6 @@ struct iegbe_adapter {
+ uint64_t gorcl_old;
+ uint16_t rx_ps_bsize0;
+
+- /* Interrupt Throttle Rate */
+- uint32_t itr;
+
+ /* OS defined structs */
+ struct net_device *netdev;
+@@ -378,7 +375,21 @@ struct iegbe_adapter {
+ #ifdef CONFIG_PCI_MSI
+ boolean_t have_msi;
+ #endif
+-#define IEGBE_INTD_DISABLE 0x0400
++ /* to not mess up cache alignment, always add to the bottom */
++ boolean_t tso_force;
++ boolean_t smart_power_down; /* phy smart power down */
++ boolean_t quad_port_a;
++ unsigned long flags;
++ uint32_t eeprom_wol;
++ int bars;
++ int need_ioport;
+ };
++
++enum iegbe_state_t {
++ __E1000_TESTING,
++ __E1000_RESETTING,
++ __E1000_DOWN
++};
++#define IEGBE_INTD_DISABLE 0x0400
+ #endif /* _IEGBE_H_ */
+
+--- a/Embedded/src/GbE/iegbe_hw.c
++++ b/Embedded/src/GbE/iegbe_hw.c
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+@@ -2115,7 +2115,7 @@ iegbe_config_mac_to_phy(struct iegbe_hw
+
+ ret_val = iegbe_oem_set_trans_gasket(hw);
+ if(ret_val){
+- return ret_val;
++ return ret_val;
+ }
+ ret_val = iegbe_oem_phy_is_full_duplex(
+ hw, (int *) &is_FullDuplex);
+@@ -2164,7 +2164,7 @@ iegbe_config_mac_to_phy(struct iegbe_hw
+ }
+ /* Write the configured values back to the Device Control Reg. */
+ E1000_WRITE_REG(hw, CTRL, ctrl);
+- return E1000_SUCCESS;
++ return ret_val;
+ }
+
+ /*****************************************************************************
+@@ -2684,7 +2684,7 @@ iegbe_check_for_link(struct iegbe_hw *hw
+
+ if(hw->autoneg_failed == 0) {
+ hw->autoneg_failed = 1;
+- return 0;
++ return E1000_SUCCESS;
+ }
+ DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n");
+
+@@ -5875,7 +5875,7 @@ iegbe_get_cable_length(struct iegbe_hw *
+ max_agc = cur_agc;
+ }
+ }
+-
++
+ /* This is to fix a Klockwork defect, that the array index might
+ * be out of bounds. 113 is table size */
+ if (cur_agc < 0x71){
+--- a/Embedded/src/GbE/iegbe_hw.h
++++ b/Embedded/src/GbE/iegbe_hw.h
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+@@ -299,7 +299,7 @@ void iegbe_set_media_type(struct iegbe_h
+ /* Link Configuration */
+ int32_t iegbe_setup_link(struct iegbe_hw *hw);
+ int32_t iegbe_phy_setup_autoneg(struct iegbe_hw *hw);
+-void iegbe_config_collision_dist(struct iegbe_hw *hw);
++void iegbe_config_collision_dist(struct iegbe_hw *hw);
+ int32_t iegbe_config_fc_after_link_up(struct iegbe_hw *hw);
+ int32_t iegbe_check_for_link(struct iegbe_hw *hw);
+ int32_t iegbe_get_speed_and_duplex(struct iegbe_hw *hw, uint16_t * speed, uint16_t * duplex);
+@@ -588,14 +588,6 @@ uint8_t iegbe_arc_subsystem_valid(struct
+ * o LSC = Link Status Change
+ */
+
+-#ifdef IEGBE_GBE_WORKAROUND
+-#define IMS_ENABLE_MASK ( \
+- E1000_IMS_RXT0 | \
+- E1000_IMS_TXQE | \
+- E1000_IMS_RXDMT0 | \
+- E1000_IMS_RXSEQ | \
+- E1000_IMS_LSC)
+-#else
+ #define IMS_ENABLE_MASK ( \
+ E1000_IMS_RXT0 | \
+ E1000_IMS_TXDW | \
+@@ -606,8 +598,7 @@ uint8_t iegbe_arc_subsystem_valid(struct
+ E1000_ICR_PB | \
+ E1000_ICR_CPP_TARGET | \
+ E1000_ICR_CPP_MASTER | \
+- E1000_IMS_LSC)
+-#endif
++ E1000_ICR_LSC)
+
+ /* Number of high/low register pairs in the RAR. The RAR (Receive Address
+ * Registers) holds the directed and multicast addresses that we monitor. We
+@@ -923,10 +914,15 @@ struct iegbe_ffvt_entry {
+ #define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
+ #define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
+ #define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
+-// Register conflict, does not exist for ICP_xxxx hardware
+-// #define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
+ #define E1000_CTRL_AUX 0x000E0 /* Aux Control -RW */
++#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
+ #define E1000_RCTL 0x00100 /* RX Control - RW */
++#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */
++#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */
++#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */
++#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */
++#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */
++#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */
+ #define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
+ #define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
+ #define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
+@@ -1282,8 +1278,6 @@ struct iegbe_ffvt_entry {
+ #define E1000_82542_FFMT E1000_FFMT
+ #define E1000_82542_FFVT E1000_FFVT
+ #define E1000_82542_HOST_IF E1000_HOST_IF
+-// Register conflict with ICP_xxxx hardware, no IAM
+-// #define E1000_82542_IAM E1000_IAM
+ #define E1000_82542_EEMNGCTL E1000_EEMNGCTL
+ #define E1000_82542_PSRCTL E1000_PSRCTL
+ #define E1000_82542_RAID E1000_RAID
+@@ -1329,6 +1323,7 @@ struct iegbe_hw_stats {
+ uint64_t algnerrc;
+ uint64_t symerrs;
+ uint64_t rxerrc;
++ uint64_t txerrc;
+ uint64_t mpc;
+ uint64_t scc;
+ uint64_t ecol;
+@@ -1363,6 +1358,7 @@ struct iegbe_hw_stats {
+ uint64_t ruc;
+ uint64_t rfc;
+ uint64_t roc;
++ uint64_t rlerrc;
+ uint64_t rjc;
+ uint64_t mgprc;
+ uint64_t mgpdc;
+@@ -1392,19 +1388,6 @@ struct iegbe_hw_stats {
+ uint64_t ictxqmtc;
+ uint64_t icrxdmtc;
+ uint64_t icrxoc;
+-#ifdef IEGBE_GBE_WORKAROUND
+- u64 txqec;
+- u64 tx_next_to_clean;
+- u64 tx_next_to_use;
+- u64 cc_gt_num_rx;
+- u64 tx_hnet;
+- u64 tx_hnentu;
+- u64 num_tx_queues;
+-
+- u64 num_rx_buf_alloc;
+- u64 rx_next_to_clean;
+- u64 rx_next_to_use;
+-#endif
+ };
+
+ /* Structure containing variables used by the shared code (iegbe_hw.c) */
+@@ -1484,6 +1467,7 @@ struct iegbe_hw {
+ boolean_t ifs_params_forced;
+ boolean_t in_ifs_mode;
+ boolean_t mng_reg_access_disabled;
++ boolean_t rx_needs_kicking;
+ boolean_t icp_xxxx_is_link_up;
+ };
+
+@@ -2358,17 +2342,23 @@ struct iegbe_host_command_info {
+ #define E1000_EXTCNF_SIZE_EXT_PHY_LENGTH 0x000000FF
+ #define E1000_EXTCNF_SIZE_EXT_DOCK_LENGTH 0x0000FF00
+ #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH 0x00FF0000
++#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001
++#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020
+
+ /* PBA constants */
++#define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */
+ #define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */
+ #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
++#define E1000_PBA_20K 0x0014
+ #define E1000_PBA_22K 0x0016
+ #define E1000_PBA_24K 0x0018
+ #define E1000_PBA_30K 0x001E
+ #define E1000_PBA_32K 0x0020
++#define E1000_PBA_34K 0x0022
+ #define E1000_PBA_38K 0x0026
+ #define E1000_PBA_40K 0x0028
+ #define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */
++#define E1000_PBS_16K E1000_PBA_16K
+
+ /* Flow Control Constants */
+ #define FLOW_CONTROL_ADDRESS_LOW 0x00C28001
+@@ -2899,7 +2889,7 @@ struct iegbe_host_command_info {
+ #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
+ #define M88E1011_I_REV_4 0x04
+ #define M88E1111_I_PHY_ID 0x01410CC2
+-#define M88E1141_E_PHY_ID 0x01410CD4
++#define M88E1141_E_PHY_ID 0x01410CD0
+ #define L1LXT971A_PHY_ID 0x001378E0
+
+ /* Miscellaneous PHY bit definitions. */
+--- a/Embedded/src/GbE/iegbe_main.c
++++ b/Embedded/src/GbE/iegbe_main.c
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+@@ -42,103 +42,15 @@ GPL LICENSE SUMMARY
+
+ #include "iegbe.h"
+ #include "gcu_if.h"
+-
+-/* Change Log
+- * 6.0.58 4/20/05
+- * o iegbe_set_spd_dplx tests for compatible speed/duplex specification
+- * for fiber adapters
+- * 6.0.57 4/19/05
+- * o Added code to fix register test failure for devices >= 82571
+- *
+- * 6.0.52 3/15/05
+- * o Added stats_lock around iegbe_read_phy_reg commands to avoid concurrent
+- * calls, one from mii_ioctl and other from within update_stats while
+- * processing MIIREG ioctl.
+- *
+- * 6.1.2 4/13/05
+- * o Fixed ethtool diagnostics
+- * o Enabled flow control to take default eeprom settings
+- * o Added stats_lock around iegbe_read_phy_reg commands to avoid concurrent
+- * calls, one from mii_ioctl and other from within update_stats while processing
+- * MIIREG ioctl.
+- * 6.0.55 3/23/05
+- * o Support for MODULE_VERSION
+- * o Fix APM setting for 82544 based adapters
+- * 6.0.54 3/26/05
+- * o Added a timer to expire packets that were deferred for cleanup
+- * 6.0.52 3/15/05
+- * o Added stats_lock around iegbe_read_phy_reg commands to avoid concurrent
+- * calls, one from mii_ioctl and other from within update_stats while
+- * processing MIIREG ioctl.
+- * 6.0.47 3/2/05
+- * o Added enhanced functionality to the loopback diags to wrap the
+- * descriptor rings
+- * o Added manageability vlan filtering workaround.
+- *
+- * 6.0.44+ 2/15/05
+- * o Added code to handle raw packet based DHCP packets
+- * o Added code to fix the errata 10 buffer overflow issue
+- * o Sync up with WR01-05
+- * o applied Anton's patch to resolve tx hang in hardware
+- * o iegbe timeouts with early writeback patch
+- * o Removed Queensport IDs
+- * o fixed driver panic if MAC receives a bad large packets when packet
+- * split is enabled
+- * o Applied Andrew Mortons patch - iegbe stops working after resume
+- * 5.2.29 12/24/03
+- * o Bug fix: Endianess issue causing ethtool diags to fail on ppc.
+- * o Bug fix: Use pdev->irq instead of netdev->irq for MSI support.
+- * o Report driver message on user override of InterruptThrottleRate module
+- * parameter.
+- * o Bug fix: Change I/O address storage from uint32_t to unsigned long.
+- * o Feature: Added ethtool RINGPARAM support.
+- * o Feature: Added netpoll support.
+- * o Bug fix: Race between Tx queue and Tx clean fixed with a spin lock.
+- * o Bug fix: Allow 1000/Full setting for autoneg param for fiber connections.
+- * Jon D Mason [jonmason@us.ibm.com].
+- *
+- * 5.2.22 10/15/03
+- * o Bug fix: SERDES devices might be connected to a back-plane switch that
+- * doesn't support auto-neg, so add the capability to force 1000/Full.
+- * Also, since forcing 1000/Full, sample RxSynchronize bit to detect link
+- * state.
+- * o Bug fix: Flow control settings for hi/lo watermark didn't consider
+- * changes in the RX FIFO size, which could occur with Jumbo Frames or with
+- * the reduced FIFO in 82547.
+- * o Bug fix: Better propagation of error codes.
+- * [Janice Girouard (janiceg -a-t- us.ibm.com)]
+- * o Bug fix: hang under heavy Tx stress when running out of Tx descriptors;
+- * wasn't clearing context descriptor when backing out of send because of
+- * no-resource condition.
+- * o Bug fix: check netif_running in dev->poll so we don't have to hang in
+- * dev->close until all polls are finished. [Rober Olsson
+- * (robert.olsson@data.slu.se)].
+- * o Revert TxDescriptor ring size back to 256 since change to 1024 wasn't
+- * accepted into the kernel.
+- *
+- * 5.2.16 8/8/03
+- */
+-
+-#ifdef IEGBE_GBE_WORKAROUND
+-#define IEGBE_GBE_WORKAROUND_NUM_RX_DESCRIPTORS 1
+-#endif
++#include <linux/ipv6.h>
++#include <net/ip6_checksum.h>
+
+ char iegbe_driver_name[] = "iegbe";
+ char iegbe_driver_string[] = "Gigabit Ethernet Controller Driver";
+-#ifndef CONFIG_E1000_NAPI
+-#define DRIVERNAPI
+-#else
+-#define DRIVERNAPI "-NAPI"
+-#endif
+-#define DRV_VERSION "0.8.0"DRIVERNAPI
++#define DRV_VERSION "1.0.0-K28-NAPI"
+ char iegbe_driver_version[] = DRV_VERSION;
+-char iegbe_copyright[] = "Copyright (c) 1999-2007 Intel Corporation.";
++char iegbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
+
+-#define E1000_FIFO_HDR 0x10
+-#define E1000_82547_PAD_LEN 0x3E0
+-#define MINIMUM_DHCP_PACKET_SIZE 282
+-#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
+-#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
+
+ /* iegbe_pci_tbl - PCI Device ID Table
+ *
+@@ -148,95 +60,48 @@ char iegbe_copyright[] = "Copyright (c)
+ * {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
+ */
+ static struct pci_device_id iegbe_pci_tbl[] = {
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1000), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1001), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1004), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1008), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1009), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x100C), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x100D), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x100E), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x100F), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1010), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1011), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1012), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1013), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1014), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1015), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1016), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1017), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1018), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1019), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x101A), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x101D), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x101E), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1026), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1027), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1028), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x105E), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x105F), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1060), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1075), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1076), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1077), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1078), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x1079), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x107A), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x107B), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x107C), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x107D), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x107E), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x107F), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x108A), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x108B), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x108C), */
+-/* INTEL_E1000_ETHERNET_DEVICE(0x109A), */
+- INTEL_E1000_ETHERNET_DEVICE(0x5040),
+- INTEL_E1000_ETHERNET_DEVICE(0x5041),
+- INTEL_E1000_ETHERNET_DEVICE(0x5042),
+- INTEL_E1000_ETHERNET_DEVICE(0x5043),
+- INTEL_E1000_ETHERNET_DEVICE(0x5044),
+- INTEL_E1000_ETHERNET_DEVICE(0x5045),
+- INTEL_E1000_ETHERNET_DEVICE(0x5046),
+- INTEL_E1000_ETHERNET_DEVICE(0x5047),
+- INTEL_E1000_ETHERNET_DEVICE(0x5048),
+- INTEL_E1000_ETHERNET_DEVICE(0x5049),
+- INTEL_E1000_ETHERNET_DEVICE(0x504A),
+- INTEL_E1000_ETHERNET_DEVICE(0x504B),
+- /* required last entry */
++ INTEL_E1000_ETHERNET_DEVICE(0x5040),
++ INTEL_E1000_ETHERNET_DEVICE(0x5041),
++ INTEL_E1000_ETHERNET_DEVICE(0x5042),
++ INTEL_E1000_ETHERNET_DEVICE(0x5043),
++ INTEL_E1000_ETHERNET_DEVICE(0x5044),
++ INTEL_E1000_ETHERNET_DEVICE(0x5045),
++ INTEL_E1000_ETHERNET_DEVICE(0x5046),
++ INTEL_E1000_ETHERNET_DEVICE(0x5047),
++ INTEL_E1000_ETHERNET_DEVICE(0x5048),
++ INTEL_E1000_ETHERNET_DEVICE(0x5049),
++ INTEL_E1000_ETHERNET_DEVICE(0x504A),
++ INTEL_E1000_ETHERNET_DEVICE(0x504B),
++ /* required last entry */
+ {0,}
+ };
+
+ MODULE_DEVICE_TABLE(pci, iegbe_pci_tbl);
+
+-DEFINE_SPINLOCK(print_lock);
+
+ int iegbe_up(struct iegbe_adapter *adapter);
+ void iegbe_down(struct iegbe_adapter *adapter);
++void iegbe_reinit_locked(struct iegbe_adapter *adapter);
+ void iegbe_reset(struct iegbe_adapter *adapter);
+ int iegbe_set_spd_dplx(struct iegbe_adapter *adapter, uint16_t spddplx);
+ int iegbe_setup_all_tx_resources(struct iegbe_adapter *adapter);
+ int iegbe_setup_all_rx_resources(struct iegbe_adapter *adapter);
+ void iegbe_free_all_tx_resources(struct iegbe_adapter *adapter);
+ void iegbe_free_all_rx_resources(struct iegbe_adapter *adapter);
+-int iegbe_setup_tx_resources(struct iegbe_adapter *adapter,
++static int iegbe_setup_tx_resources(struct iegbe_adapter *adapter,
+ struct iegbe_tx_ring *txdr);
+-int iegbe_setup_rx_resources(struct iegbe_adapter *adapter,
++static int iegbe_setup_rx_resources(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rxdr);
+-void iegbe_free_tx_resources(struct iegbe_adapter *adapter,
++static void iegbe_free_tx_resources(struct iegbe_adapter *adapter,
+ struct iegbe_tx_ring *tx_ring);
+-void iegbe_free_rx_resources(struct iegbe_adapter *adapter,
++static void iegbe_free_rx_resources(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring);
+ void iegbe_update_stats(struct iegbe_adapter *adapter);
+-
+ static int iegbe_init_module(void);
+ static void iegbe_exit_module(void);
+ static int iegbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+ static void __devexit iegbe_remove(struct pci_dev *pdev);
+ static int iegbe_alloc_queues(struct iegbe_adapter *adapter);
+-#ifdef CONFIG_E1000_MQ
+-static void iegbe_setup_queue_mapping(struct iegbe_adapter *adapter);
+-#endif
+ static int iegbe_sw_init(struct iegbe_adapter *adapter);
+ static int iegbe_open(struct net_device *netdev);
+ static int iegbe_close(struct net_device *netdev);
+@@ -249,7 +114,8 @@ static void iegbe_clean_tx_ring(struct i
+ struct iegbe_tx_ring *tx_ring);
+ static void iegbe_clean_rx_ring(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring);
+-static void iegbe_set_multi(struct net_device *netdev);
++
++static void iegbe_set_rx_mode(struct net_device *netdev);
+ static void iegbe_update_phy_info(unsigned long data);
+ static void iegbe_watchdog(unsigned long data);
+ static void iegbe_82547_tx_fifo_stall(unsigned long data);
+@@ -257,66 +123,46 @@ static int iegbe_xmit_frame(struct sk_bu
+ static struct net_device_stats * iegbe_get_stats(struct net_device *netdev);
+ static int iegbe_change_mtu(struct net_device *netdev, int new_mtu);
+ static int iegbe_set_mac(struct net_device *netdev, void *p);
+-static irqreturn_t iegbe_intr(int irq, void *data, struct pt_regs *regs);
++static irqreturn_t iegbe_intr(int irq, void *data);
+
+-void iegbe_tasklet(unsigned long);
++static irqreturn_t iegbe_intr_msi(int irq, void *data);
+
+-#ifndef IEGBE_GBE_WORKAROUND
+-static boolean_t iegbe_clean_tx_irq(struct iegbe_adapter *adapter,
++static bool iegbe_clean_tx_irq(struct iegbe_adapter *adapter,
+ struct iegbe_tx_ring *tx_ring);
+-#endif
+-
+-#ifdef CONFIG_E1000_NAPI
+-static int iegbe_clean(struct net_device *poll_dev, int *budget);
+-static boolean_t iegbe_clean_rx_irq(struct iegbe_adapter *adapter,
++static int iegbe_clean(struct napi_struct *napi, int budget);
++static bool iegbe_clean_rx_irq(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring,
+ int *work_done, int work_to_do);
+-static boolean_t iegbe_clean_rx_irq_ps(struct iegbe_adapter *adapter,
++static bool iegbe_clean_rx_irq_ps(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring,
+ int *work_done, int work_to_do);
+-#else
+-static boolean_t iegbe_clean_rx_irq(struct iegbe_adapter *adapter,
+- struct iegbe_rx_ring *rx_ring);
+-static boolean_t iegbe_clean_rx_irq_ps(struct iegbe_adapter *adapter,
+- struct iegbe_rx_ring *rx_ring);
+-#endif
+
+-#ifdef IEGBE_GBE_WORKAROUND
++
+ static void iegbe_alloc_rx_buffers(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring,
+ int cleaned_count);
+ static void iegbe_alloc_rx_buffers_ps(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring,
+ int cleaned_count);
+-#else
+-static void iegbe_alloc_rx_buffers(struct iegbe_adapter *adapter,
+- struct iegbe_rx_ring *rx_ring);
+-static void iegbe_alloc_rx_buffers_ps(struct iegbe_adapter *adapter,
+- struct iegbe_rx_ring *rx_ring);
+-#endif
++
+
+ static int iegbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
+-#ifdef SIOCGMIIPHY
+ static int iegbe_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
+- int cmd);
+-#endif
++ int cmd);
+ void set_ethtool_ops(struct net_device *netdev);
+ extern int ethtool_ioctl(struct ifreq *ifr);
+ static void iegbe_enter_82542_rst(struct iegbe_adapter *adapter);
+ static void iegbe_leave_82542_rst(struct iegbe_adapter *adapter);
+ static void iegbe_tx_timeout(struct net_device *dev);
+-static void iegbe_tx_timeout_task(struct net_device *dev);
++static void iegbe_reset_task(struct work_struct *work);
+ static void iegbe_smartspeed(struct iegbe_adapter *adapter);
+ static inline int iegbe_82547_fifo_workaround(struct iegbe_adapter *adapter,
+- struct sk_buff *skb);
++ struct sk_buff *skb);
+
+-#ifdef NETIF_F_HW_VLAN_TX
+-static void iegbe_vlan_rx_register(struct net_device *netdev,
+- struct vlan_group *grp);
++static void iegbe_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
+ static void iegbe_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
+ static void iegbe_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
+ static void iegbe_restore_vlan(struct iegbe_adapter *adapter);
+-#endif
+
+ static int iegbe_notify_reboot(struct notifier_block *,
+ unsigned long event,
+@@ -331,15 +177,17 @@ static int iegbe_resume(struct pci_dev *
+ static void iegbe_netpoll (struct net_device *netdev);
+ #endif
+
+-#ifdef CONFIG_E1000_MQ
+-/* for multiple Rx queues */
++#define COPYBREAK_DEFAULT 256
++static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
++module_param(copybreak, uint, 0644);
++MODULE_PARM_DESC(copybreak,
++ "Maximum size of packet that is copied to a new buffer on receive");
+ void iegbe_rx_schedule(void *data);
+-#endif
+
+ struct notifier_block iegbe_notifier_reboot = {
+- .notifier_call = iegbe_notify_reboot,
+- .next = NULL,
+- .priority = 0
++ .notifier_call = iegbe_notify_reboot,
++ .next = NULL,
++ .priority = 0
+ };
+
+ /* Exported from other modules */
+@@ -347,14 +195,14 @@ struct notifier_block iegbe_notifier_reb
+ extern void iegbe_check_options(struct iegbe_adapter *adapter);
+
+ static struct pci_driver iegbe_driver = {
+- .name = iegbe_driver_name,
+- .id_table = iegbe_pci_tbl,
+- .probe = iegbe_probe,
+- .remove = __devexit_p(iegbe_remove),
+- /* Power Managment Hooks */
++ .name = iegbe_driver_name,
++ .id_table = iegbe_pci_tbl,
++ .probe = iegbe_probe,
++ .remove = __devexit_p(iegbe_remove),
++ /* Power Managment Hooks */
+ #ifdef CONFIG_PM
+- .suspend = iegbe_suspend,
+- .resume = iegbe_resume
++ .suspend = iegbe_suspend,
++ .resume = iegbe_resume
+ #endif
+ };
+
+@@ -364,46 +212,17 @@ MODULE_LICENSE("GPL");
+ MODULE_VERSION(DRV_VERSION);
+
+ static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
+-module_param(debug, int, 0);
++module_param(debug, int, 0x0);
+ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
+-static uint8_t gcu_suspend = 0;
+-static uint8_t gcu_resume = 0;
++static uint8_t gcu_suspend = 0x0;
++static uint8_t gcu_resume = 0x0;
+ struct pci_dev *gcu = NULL;
+
+-unsigned long tasklet_data;
+-DECLARE_TASKLET(iegbe_reset_tasklet, iegbe_tasklet, (unsigned long) &tasklet_data);
+
+ /**
+ * iegbe_iegbe_tasklet -*
+ **/
+-void iegbe_tasklet(unsigned long data)
+-{
+- char* err_msg = "TEST";
+- uint32_t *icr = (uint32_t*) data;
+- uint32_t gbe = *icr & 0x000000FF;
+- if( *icr & E1000_ICR_RX_DESC_FIFO_PAR) { /* 21 */
+- err_msg = "DMA Transmit Descriptor 2-bit ECC Error!";
+- }
+- if( *icr & E1000_ICR_TX_DESC_FIFO_PAR) { /* 20 */
+- err_msg = "DMA Receive Descriptor 2-bit ECC Error!";
+- }
+- if( *icr & E1000_ICR_PB) { /* 23 */
+- err_msg = "DMA Packet Buffer 2-bit ECC Error!";
+- }
+- if( *icr & E1000_ICR_CPP_TARGET) { /* 27 */
+- err_msg = "Statistic Register ECC Error!";
+- }
+- if( *icr & E1000_ICR_CPP_MASTER) {
+- err_msg = "CPP Error!";
+- }
+- spin_lock(&print_lock);
+- printk("IEGBE%d: System Reset due to: %s\n", gbe, err_msg);
+- dump_stack();
+- spin_unlock(&print_lock);
+- panic(err_msg);
+- return;
+-}
+ /**
+ * iegbe_init_module - Driver Registration Routine
+ *
+@@ -411,21 +230,24 @@ void iegbe_tasklet(unsigned long data)
+ * loaded. All it does is register with the PCI subsystem.
+ **/
+
+-static int __init
+-iegbe_init_module(void)
++static int __init iegbe_init_module(void)
+ {
+- int ret;
++ int ret;
+
+ printk(KERN_INFO "%s - version %s\n",
+- iegbe_driver_string, iegbe_driver_version);
++ iegbe_driver_string, iegbe_driver_version);
+
+- printk(KERN_INFO "%s\n", iegbe_copyright);
++ printk(KERN_INFO "%s\n", iegbe_copyright);
+
+- ret = pci_module_init(&iegbe_driver);
+- if(ret >= 0) {
+- register_reboot_notifier(&iegbe_notifier_reboot);
+- }
+- return ret;
++ ret = pci_register_driver(&iegbe_driver);
++ if (copybreak != COPYBREAK_DEFAULT) {
++ if (copybreak == 0)
++ printk(KERN_INFO "iegbe: copybreak disabled\n");
++ else
++ printk(KERN_INFO "iegbe: copybreak enabled for "
++ "packets <= %u bytes\n", copybreak);
++ }
++ return ret;
+ }
+
+ module_init(iegbe_init_module);
+@@ -437,29 +259,51 @@ module_init(iegbe_init_module);
+ * from memory.
+ **/
+
+-static void __exit
+-iegbe_exit_module(void)
++static void __exit iegbe_exit_module(void)
+ {
+-
+- unregister_reboot_notifier(&iegbe_notifier_reboot);
+- pci_unregister_driver(&iegbe_driver);
++ pci_unregister_driver(&iegbe_driver);
+ }
+
+ module_exit(iegbe_exit_module);
+
++static int iegbe_request_irq(struct iegbe_adapter *adapter)
++{
++ struct net_device *netdev = adapter->netdev;
++ irq_handler_t handler = iegbe_intr;
++ int irq_flags = IRQF_SHARED;
++ int err;
++ adapter->have_msi = !pci_enable_msi(adapter->pdev);
++ if (adapter->have_msi) {
++ handler = iegbe_intr_msi;
++ irq_flags = 0;
++ }
++ err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
++ netdev);
++ if (err) {
++ if (adapter->have_msi)
++ pci_disable_msi(adapter->pdev);
++ DPRINTK(PROBE, ERR,
++ "Unable to allocate interrupt Error: %d\n", err);
++ }
++ return err;
++}
++static void iegbe_free_irq(struct iegbe_adapter *adapter)
++{
++ struct net_device *netdev = adapter->netdev;
++ free_irq(adapter->pdev->irq, netdev);
++ if (adapter->have_msi)
++ pci_disable_msi(adapter->pdev);
++}
+ /**
+ * iegbe_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ **/
+
+-static inline void
+-iegbe_irq_disable(struct iegbe_adapter *adapter)
++static void iegbe_irq_disable(struct iegbe_adapter *adapter)
+ {
+-
+- atomic_inc(&adapter->irq_sem);
+- E1000_WRITE_REG(&adapter->hw, IMC, ~0);
+- E1000_WRITE_FLUSH(&adapter->hw);
+- synchronize_irq(adapter->pdev->irq);
++ E1000_WRITE_REG(&adapter->hw, IMC, ~0);
++ E1000_WRITE_FLUSH(&adapter->hw);
++ synchronize_irq(adapter->pdev->irq);
+ }
+
+ /**
+@@ -470,244 +314,414 @@ iegbe_irq_disable(struct iegbe_adapter *
+ static inline void
+ iegbe_irq_enable(struct iegbe_adapter *adapter)
+ {
+-
+- if(likely(atomic_dec_and_test(&adapter->irq_sem))) {
+- E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
+- E1000_WRITE_FLUSH(&adapter->hw);
+- }
++ E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
++ E1000_WRITE_FLUSH(&adapter->hw);
+ }
+-#ifdef NETIF_F_HW_VLAN_TX
+-void
+-iegbe_update_mng_vlan(struct iegbe_adapter *adapter)
+-{
+- struct net_device *netdev = adapter->netdev;
+- uint16_t vid = adapter->hw.mng_cookie.vlan_id;
+- uint16_t old_vid = adapter->mng_vlan_id;
+
+- if(adapter->vlgrp) {
+- if(!adapter->vlgrp->vlan_devices[vid]) {
+- if(adapter->hw.mng_cookie.status &
+- E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
+- iegbe_vlan_rx_add_vid(netdev, vid);
+- adapter->mng_vlan_id = vid;
+- } else {
+- adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
+- }
+- if((old_vid != (uint16_t)E1000_MNG_VLAN_NONE) &&
+- (vid != old_vid) &&
+- !adapter->vlgrp->vlan_devices[old_vid]) {
+- iegbe_vlan_rx_kill_vid(netdev, old_vid);
+- }
+- }
+-}
++static void iegbe_update_mng_vlan(struct iegbe_adapter *adapter)
++{
++ struct iegbe_hw *hw = &adapter->hw;
++ struct net_device *netdev = adapter->netdev;
++ u16 vid = hw->mng_cookie.vlan_id;
++ u16 old_vid = adapter->mng_vlan_id;
++ if (adapter->vlgrp) {
++ if (!vlan_group_get_device(adapter->vlgrp, vid)) {
++ if (hw->mng_cookie.status &
++ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
++ iegbe_vlan_rx_add_vid(netdev, vid);
++ adapter->mng_vlan_id = vid;
++ } else
++ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
++
++ if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
++ (vid != old_vid) &&
++ !vlan_group_get_device(adapter->vlgrp, old_vid))
++ iegbe_vlan_rx_kill_vid(netdev, old_vid);
++ } else
++ adapter->mng_vlan_id = vid;
++ }
+ }
+-#endif
+
+-int
+-iegbe_up(struct iegbe_adapter *adapter)
++/**
++ * iegbe_configure - configure the hardware for RX and TX
++ * @adapter = private board structure
++ **/
++static void iegbe_configure(struct iegbe_adapter *adapter)
+ {
+ struct net_device *netdev = adapter->netdev;
+- int i, err;
+- uint16_t pci_cmd;
+-
+- /* hardware has been reset, we need to reload some things */
+-
+- /* Reset the PHY if it was previously powered down */
+- if(adapter->hw.media_type == iegbe_media_type_copper
+- || (adapter->hw.media_type == iegbe_media_type_oem
+- && iegbe_oem_phy_is_copper(&adapter->hw))) {
+- uint16_t mii_reg;
+- iegbe_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
+- if(mii_reg & MII_CR_POWER_DOWN){
+- iegbe_phy_reset(&adapter->hw);
+- }
+- }
++ int i;
+
+- iegbe_set_multi(netdev);
++ iegbe_set_rx_mode(netdev);
+
+-#ifdef NETIF_F_HW_VLAN_TX
+ iegbe_restore_vlan(adapter);
+-#endif
+
+ iegbe_configure_tx(adapter);
+ iegbe_setup_rctl(adapter);
+ iegbe_configure_rx(adapter);
++ /* call E1000_DESC_UNUSED which always leaves
++ * at least 1 descriptor unused to make sure
++ * next_to_use != next_to_clean */
++ for (i = 0; i < adapter->num_rx_queues; i++) {
++ struct iegbe_rx_ring *ring = &adapter->rx_ring[i];
++ adapter->alloc_rx_buf(adapter, ring,
++ E1000_DESC_UNUSED(ring));
++ }
+
+-#ifdef IEGBE_GBE_WORKAROUND
+- for (i = 0; i < adapter->num_queues; i++)
+- adapter->alloc_rx_buf(adapter, &adapter->rx_ring[i],
+- IEGBE_GBE_WORKAROUND_NUM_RX_DESCRIPTORS + 1);
+-#else
+- for (i = 0; i < adapter->num_queues; i++)
+- adapter->alloc_rx_buf(adapter, &adapter->rx_ring[i]);
+-#endif
++ adapter->tx_queue_len = netdev->tx_queue_len;
++}
+
+-#ifdef CONFIG_PCI_MSI
+- if(adapter->hw.mac_type > iegbe_82547_rev_2
+- || adapter->hw.mac_type == iegbe_icp_xxxx) {
+- adapter->have_msi = TRUE;
+- if((err = pci_enable_msi(adapter->pdev))) {
+- DPRINTK(PROBE, ERR,
+- "Unable to allocate MSI interrupt Error: %d\n", err);
+- adapter->have_msi = FALSE;
+- }
+- }
+- pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
+- pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd | IEGBE_INTD_DISABLE);
++int iegbe_up(struct iegbe_adapter *adapter)
++{
++ /* hardware has been reset, we need to reload some things */
++ iegbe_configure(adapter);
+
+-#endif
+- if((err = request_irq(adapter->pdev->irq, &iegbe_intr,
+- SA_SHIRQ | SA_SAMPLE_RANDOM,
+- netdev->name, netdev))) {
+- DPRINTK(PROBE, ERR,
+- "Unable to allocate interrupt Error: %d\n", err);
+- return err;
+- }
++ clear_bit(__E1000_DOWN, &adapter->flags);
+
+- mod_timer(&adapter->watchdog_timer, jiffies);
++ napi_enable(&adapter->napi);
+
+-#ifdef CONFIG_E1000_NAPI
+- netif_poll_enable(netdev);
+-#endif
+ iegbe_irq_enable(adapter);
+
++ adapter->hw.get_link_status = 0x1;
+ return 0;
+ }
+
+-void
+-iegbe_down(struct iegbe_adapter *adapter)
+-{
+- struct net_device *netdev = adapter->netdev;
+-
+- iegbe_irq_disable(adapter);
+-#ifdef CONFIG_E1000_MQ
+- while (atomic_read(&adapter->rx_sched_call_data.count) != 0) { };
+-#endif
+- free_irq(adapter->pdev->irq, netdev);
+-#ifdef CONFIG_PCI_MSI
+- if((adapter->hw.mac_type > iegbe_82547_rev_2
+- || adapter->hw.mac_type == iegbe_icp_xxxx)
+- && adapter->have_msi == TRUE) {
+- pci_disable_msi(adapter->pdev);
+- }
+-#endif
+- del_timer_sync(&adapter->tx_fifo_stall_timer);
+- del_timer_sync(&adapter->watchdog_timer);
+- del_timer_sync(&adapter->phy_info_timer);
++/**
++ * iegbe_power_up_phy - restore link in case the phy was powered down
++ * @adapter: address of board private structure
++ *
++ * The phy may be powered down to save power and turn off link when the
++ * driver is unloaded and wake on lan is not enabled (among others)
++ * *** this routine MUST be followed by a call to iegbe_reset ***
++ *
++ **/
+
+-#ifdef CONFIG_E1000_NAPI
+- netif_poll_disable(netdev);
+-#endif
+- adapter->link_speed = 0;
+- adapter->link_duplex = 0;
+- netif_carrier_off(netdev);
+- netif_stop_queue(netdev);
++void iegbe_power_up_phy(struct iegbe_adapter *adapter)
++{
++ struct iegbe_hw *hw = &adapter->hw;
++ u16 mii_reg = 0;
+
+- iegbe_reset(adapter);
+- iegbe_clean_all_tx_rings(adapter);
+- iegbe_clean_all_rx_rings(adapter);
++ /* Just clear the power down bit to wake the phy back up */
++ if (hw->media_type == iegbe_media_type_copper) {
++ /* according to the manual, the phy will retain its
++ * settings across a power-down/up cycle */
++ iegbe_read_phy_reg(hw, PHY_CTRL, &mii_reg);
++ mii_reg &= ~MII_CR_POWER_DOWN;
++ iegbe_write_phy_reg(hw, PHY_CTRL, mii_reg);
++ }
++}
+
+- /* If WoL is not enabled and management mode is not IAMT
+- * or if WoL is not enabled and OEM PHY is copper based,
+- * power down the PHY so no link is implied when interface is down */
+- if(!adapter->wol
+- && ((adapter->hw.mac_type >= iegbe_82540
+- && adapter->hw.media_type == iegbe_media_type_copper
+- && !iegbe_check_mng_mode(&adapter->hw)
+- && !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN))
+- || (adapter->hw.media_type == iegbe_media_type_oem
+- && iegbe_oem_phy_is_copper(&adapter->hw)))){
++static void iegbe_power_down_phy(struct iegbe_adapter *adapter)
++{
++ struct iegbe_hw *hw = &adapter->hw;
+
+- uint16_t mii_reg;
+- iegbe_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
++ /* Power down the PHY so no link is implied when interface is down *
++ * The PHY cannot be powered down if any of the following is true *
++ * (a) WoL is enabled
++ * (b) AMT is active
++ * (c) SoL/IDER session is active */
++ if (!adapter->wol && hw->mac_type >= iegbe_82540 &&
++ hw->media_type == iegbe_media_type_copper) {
++ u16 mii_reg = 0;
++
++ switch (hw->mac_type) {
++ case iegbe_82540:
++ case iegbe_82545:
++ case iegbe_82545_rev_3:
++ case iegbe_82546:
++ case iegbe_82546_rev_3:
++ case iegbe_82541:
++ case iegbe_82541_rev_2:
++ case iegbe_82547:
++ case iegbe_82547_rev_2:
++ if (E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN)
++ goto out;
++ break;
++ case iegbe_82571:
++ case iegbe_82572:
++ case iegbe_82573:
++ if (iegbe_check_mng_mode(hw) ||
++ iegbe_check_phy_reset_block(hw))
++ goto out;
++ break;
++ default:
++ goto out;
++ }
++ iegbe_read_phy_reg(hw, PHY_CTRL, &mii_reg);
+ mii_reg |= MII_CR_POWER_DOWN;
+- iegbe_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
++ iegbe_write_phy_reg(hw, PHY_CTRL, mii_reg);
+ mdelay(1);
+ }
++out:
++ return;
+ }
+
+-void
+-iegbe_reset(struct iegbe_adapter *adapter)
++void iegbe_down(struct iegbe_adapter *adapter)
+ {
+- struct net_device *netdev = adapter->netdev;
+- uint32_t pba, manc;
+- uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
+- uint16_t fc_low_water_mark = E1000_FC_LOW_DIFF;
++ struct net_device *netdev = adapter->netdev;
+
++ /* signal that we're down so the interrupt handler does not
++ * reschedule our watchdog timer */
++ set_bit(__E1000_DOWN, &adapter->flags);
+
+- /* Repartition Pba for greater than 9k mtu
+- * To take effect CTRL.RST is required.
+- */
++ napi_disable(&adapter->napi);
+
+- switch (adapter->hw.mac_type) {
+- case iegbe_82547:
+- case iegbe_82547_rev_2:
+- pba = E1000_PBA_30K;
+- break;
+- case iegbe_82571:
+- case iegbe_82572:
+- pba = E1000_PBA_38K;
+- break;
+- case iegbe_82573:
+- pba = E1000_PBA_12K;
++ iegbe_irq_disable(adapter);
++
++ del_timer_sync(&adapter->tx_fifo_stall_timer);
++ del_timer_sync(&adapter->watchdog_timer);
++ del_timer_sync(&adapter->phy_info_timer);
++
++ netdev->tx_queue_len = adapter->tx_queue_len;
++ adapter->link_speed = 0;
++ adapter->link_duplex = 0;
++ netif_carrier_off(netdev);
++ netif_stop_queue(netdev);
++
++ iegbe_reset(adapter);
++ iegbe_clean_all_tx_rings(adapter);
++ iegbe_clean_all_rx_rings(adapter);
++}
++void iegbe_reinit_locked(struct iegbe_adapter *adapter)
++{
++ WARN_ON(in_interrupt());
++ while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
++ msleep(1);
++ iegbe_down(adapter);
++ iegbe_up(adapter);
++ clear_bit(__E1000_RESETTING, &adapter->flags);
++}
++
++void iegbe_reset(struct iegbe_adapter *adapter)
++{
++ struct iegbe_hw *hw = &adapter->hw;
++ u32 pba = 0, tx_space, min_tx_space, min_rx_space;
++ u16 fc_high_water_mark = E1000_FC_HIGH_DIFF;
++ bool legacy_pba_adjust = false;
++
++ /* Repartition Pba for greater than 9k mtu
++ * To take effect CTRL.RST is required.
++ */
++
++ switch (hw->mac_type) {
++ case iegbe_82542_rev2_0:
++ case iegbe_82542_rev2_1:
++ case iegbe_82543:
++ case iegbe_82544:
++ case iegbe_82540:
++ case iegbe_82541:
++ case iegbe_82541_rev_2:
++ case iegbe_icp_xxxx:
++ legacy_pba_adjust = true;
++ pba = E1000_PBA_48K;
+ break;
+- default:
++ case iegbe_82545:
++ case iegbe_82545_rev_3:
++ case iegbe_82546:
++ case iegbe_82546_rev_3:
+ pba = E1000_PBA_48K;
+ break;
+- }
++ case iegbe_82547:
++ case iegbe_82573:
++ case iegbe_82547_rev_2:
++ legacy_pba_adjust = true;
++ pba = E1000_PBA_30K;
++ break;
++ case iegbe_82571:
++ case iegbe_82572:
++ case iegbe_undefined:
++ case iegbe_num_macs:
++ break;
++ }
++
++ if (legacy_pba_adjust) {
++ if (adapter->netdev->mtu > E1000_RXBUFFER_8192)
++ pba -= 8; /* allocate more FIFO for Tx */
++ /* send an XOFF when there is enough space in the
++ * Rx FIFO to hold one extra full size Rx packet
++ */
+
+- if((adapter->hw.mac_type != iegbe_82573) &&
+- (adapter->rx_buffer_len > E1000_RXBUFFER_8192)) {
+- pba -= 0x8; /* allocate more FIFO for Tx */
+- /* send an XOFF when there is enough space in the
+- * Rx FIFO to hold one extra full size Rx packet
+- */
+- fc_high_water_mark = netdev->mtu + ENET_HEADER_SIZE +
+- ETHERNET_FCS_SIZE + 0x1;
+- fc_low_water_mark = fc_high_water_mark + 0x8;
+- }
+
++ if (hw->mac_type == iegbe_82547) {
++ adapter->tx_fifo_head = 0;
++ adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
++ adapter->tx_fifo_size =
++ (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
++ atomic_set(&adapter->tx_fifo_stall, 0);
++ }
++ } else if (hw->max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) {
++ E1000_WRITE_REG(&adapter->hw, PBA, pba);
++
++ /* To maintain wire speed transmits, the Tx FIFO should be
++ * large enough to accomodate two full transmit packets,
++ * rounded up to the next 1KB and expressed in KB. Likewise,
++ * the Rx FIFO should be large enough to accomodate at least
++ * one full receive packet and is similarly rounded up and
++ * expressed in KB. */
++ pba = E1000_READ_REG(&adapter->hw, PBA);
++ /* upper 16 bits has Tx packet buffer allocation size in KB */
++ tx_space = pba >> 16;
++ /* lower 16 bits has Rx packet buffer allocation size in KB */
++ pba &= 0xffff;
++ /* don't include ethernet FCS because hardware appends/strips */
++ min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE +
++ VLAN_TAG_SIZE;
++ min_tx_space = min_rx_space;
++ min_tx_space *= 2;
++ min_tx_space = ALIGN(min_tx_space, 1024);
++ min_tx_space >>= 10;
++ min_rx_space = ALIGN(min_rx_space, 1024);
++ min_rx_space >>= 10;
++
++ /* If current Tx allocation is less than the min Tx FIFO size,
++ * and the min Tx FIFO size is less than the current Rx FIFO
++ * allocation, take space away from current Rx allocation */
++ if (tx_space < min_tx_space &&
++ ((min_tx_space - tx_space) < pba)) {
++ pba = pba - (min_tx_space - tx_space);
++
++ /* PCI/PCIx hardware has PBA alignment constraints */
++ switch (hw->mac_type) {
++ case iegbe_82545 ... iegbe_82546_rev_3:
++ pba &= ~(E1000_PBA_8K - 1);
++ break;
++ default:
++ break;
++ }
+
+- if(adapter->hw.mac_type == iegbe_82547) {
+- adapter->tx_fifo_head = 0;
+- adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
+- adapter->tx_fifo_size =
+- (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
+- atomic_set(&adapter->tx_fifo_stall, 0);
++ /* if short on rx space, rx wins and must trump tx
++ * adjustment or use Early Receive if available */
++ if (pba < min_rx_space) {
++ switch (hw->mac_type) {
++ case iegbe_82573:
++ /* ERT enabled in iegbe_configure_rx */
++ break;
++ default:
++ pba = min_rx_space;
++ break;
++ }
++ }
++ }
+ }
+
+ E1000_WRITE_REG(&adapter->hw, PBA, pba);
+
+ /* flow control settings */
+- adapter->hw.fc_high_water = (pba << E1000_PBA_BYTES_SHIFT) -
+- fc_high_water_mark;
+- adapter->hw.fc_low_water = (pba << E1000_PBA_BYTES_SHIFT) -
+- fc_low_water_mark;
+- adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME;
+- adapter->hw.fc_send_xon = 1;
+- adapter->hw.fc = adapter->hw.original_fc;
++ /* Set the FC high water mark to 90% of the FIFO size.
++ * Required to clear last 3 LSB */
++ fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8;
++ /* We can't use 90% on small FIFOs because the remainder
++ * would be less than 1 full frame. In this case, we size
++ * it to allow at least a full frame above the high water
++ * mark. */
++ if (pba < E1000_PBA_16K)
++ fc_high_water_mark = (pba * 1024) - 1600;
++
++ hw->fc_high_water = fc_high_water_mark;
++ hw->fc_low_water = fc_high_water_mark - 8;
++ hw->fc_pause_time = E1000_FC_PAUSE_TIME;
++ hw->fc_send_xon = 1;
++ hw->fc = hw->original_fc;
+
+ /* Allow time for pending master requests to run */
+- iegbe_reset_hw(&adapter->hw);
+- if(adapter->hw.mac_type >= iegbe_82544){
++ iegbe_reset_hw(hw);
++ if (hw->mac_type >= iegbe_82544)
+ E1000_WRITE_REG(&adapter->hw, WUC, 0);
+- }
+- if(iegbe_init_hw(&adapter->hw)) {
++
++ if (iegbe_init_hw(hw))
+ DPRINTK(PROBE, ERR, "Hardware Error\n");
+- }
+-#ifdef NETIF_F_HW_VLAN_TX
+ iegbe_update_mng_vlan(adapter);
+-#endif
++
++ /* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
++ if (hw->mac_type >= iegbe_82544 &&
++ hw->mac_type <= iegbe_82547_rev_2 &&
++ hw->autoneg == 1 &&
++ hw->autoneg_advertised == ADVERTISE_1000_FULL) {
++ u32 ctrl = E1000_READ_REG(&adapter->hw, CTRL);
++ /* clear phy power management bit if we are in gig only mode,
++ * which if enabled will attempt negotiation to 100Mb, which
++ * can cause a loss of link at power off or driver unload */
++ ctrl &= ~E1000_CTRL_SWDPIN3;
++ E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
++ }
++
+ /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
+ E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE);
+
+- iegbe_reset_adaptive(&adapter->hw);
+- iegbe_phy_get_info(&adapter->hw, &adapter->phy_info);
+- if(adapter->en_mng_pt) {
+- manc = E1000_READ_REG(&adapter->hw, MANC);
+- manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
+- E1000_WRITE_REG(&adapter->hw, MANC, manc);
++ iegbe_reset_adaptive(hw);
++ iegbe_phy_get_info(hw, &adapter->phy_info);
++
++ if (!adapter->smart_power_down &&
++ (hw->mac_type == iegbe_82571 ||
++ hw->mac_type == iegbe_82572)) {
++ u16 phy_data = 0;
++ /* speed up time to link by disabling smart power down, ignore
++ * the return value of this function because there is nothing
++ * different we would do if it failed */
++ iegbe_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
++ &phy_data);
++ phy_data &= ~IGP02E1000_PM_SPD;
++ iegbe_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
++ phy_data);
++ }
++
++}
++
++/**
++ * Dump the eeprom for users having checksum issues
++ **/
++static void iegbe_dump_eeprom(struct iegbe_adapter *adapter)
++{
++ struct net_device *netdev = adapter->netdev;
++ struct ethtool_eeprom eeprom;
++ const struct ethtool_ops *ops = netdev->ethtool_ops;
++ u8 *data;
++ int i;
++ u16 csum_old, csum_new = 0;
++
++ eeprom.len = ops->get_eeprom_len(netdev);
++ eeprom.offset = 0;
++
++ data = kmalloc(eeprom.len, GFP_KERNEL);
++ if (!data) {
++ printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
++ " data\n");
++ return;
+ }
++
++ ops->get_eeprom(netdev, &eeprom, data);
++
++ csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
++ (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
++ for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
++ csum_new += data[i] + (data[i + 1] << 8);
++ csum_new = EEPROM_SUM - csum_new;
++
++ printk(KERN_ERR "/*********************/\n");
++ printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
++ printk(KERN_ERR "Calculated : 0x%04x\n", csum_new);
++
++ printk(KERN_ERR "Offset Values\n");
++ printk(KERN_ERR "======== ======\n");
++ print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
++
++ printk(KERN_ERR "Include this output when contacting your support "
++ "provider.\n");
++ printk(KERN_ERR "This is not a software error! Something bad "
++ "happened to your hardware or\n");
++ printk(KERN_ERR "EEPROM image. Ignoring this "
++ "problem could result in further problems,\n");
++ printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
++ printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
++ "which is invalid\n");
++ printk(KERN_ERR "and requires you to set the proper MAC "
++ "address manually before continuing\n");
++ printk(KERN_ERR "to enable this network device.\n");
++ printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
++ "to your hardware vendor\n");
++ printk(KERN_ERR "or Intel Customer Support.\n");
++ printk(KERN_ERR "/*********************/\n");
++
++ kfree(data);
+ }
+
+ /**
+@@ -721,184 +735,166 @@ iegbe_reset(struct iegbe_adapter *adapte
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ **/
+-
+-static int __devinit
+-iegbe_probe(struct pci_dev *pdev,
++static int __devinit iegbe_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+ {
+- struct net_device *netdev;
+- struct iegbe_adapter *adapter;
+- unsigned long mmio_start, mmio_len;
+- uint32_t ctrl_ext;
+- uint32_t swsm;
++ struct net_device *netdev;
++ struct iegbe_adapter *adapter;
++ struct iegbe_hw *hw;
+
+ static int cards_found = 0;
++ int i, err, pci_using_dac;
++ u16 eeprom_data = 0;
++ u16 eeprom_apme_mask = E1000_EEPROM_APME;
++ int bars;
++ DECLARE_MAC_BUF(mac);
+
+- int i, err, pci_using_dac;
+- uint16_t eeprom_data = 0;
+- uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
++ bars = pci_select_bars(pdev, IORESOURCE_MEM);
++ err = pci_enable_device(pdev);
+
++ if (err)
++ return err;
+
+- if((err = pci_enable_device(pdev))) {
+- return err;
+- }
+- if(!(err = pci_set_dma_mask(pdev, PCI_DMA_64BIT))) {
++ if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
++ !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
+ pci_using_dac = 1;
+- } else {
+- if((err = pci_set_dma_mask(pdev, PCI_DMA_32BIT))) {
+- E1000_ERR("No usable DMA configuration, aborting\n");
+- return err;
+- }
++ } else {
++ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
++ if (err) {
++ err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
++ if (err) {
++ E1000_ERR("No usable DMA configuration, "
++ "aborting\n");
++ goto err_dma;
++ }
++ }
+ pci_using_dac = 0;
+- }
+-
+- if((err = pci_request_regions(pdev, iegbe_driver_name))) {
+- return err;
+ }
+- pci_set_master(pdev);
+
+- netdev = alloc_etherdev(sizeof(struct iegbe_adapter));
+- if(!netdev) {
+- err = -ENOMEM;
+- goto err_alloc_etherdev;
+- }
++ err = pci_request_selected_regions(pdev, bars, iegbe_driver_name);
++ if (err)
++ goto err_pci_reg;
++
++ pci_set_master(pdev);
++
++ err = -ENOMEM;
++ netdev = alloc_etherdev(sizeof(struct iegbe_adapter));
++ if (!netdev)
++ goto err_alloc_etherdev;
+
+- SET_MODULE_OWNER(netdev);
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+
+- pci_set_drvdata(pdev, netdev);
+- adapter = netdev_priv(netdev);
+- adapter->netdev = netdev;
+- adapter->pdev = pdev;
+- adapter->hw.back = adapter;
+- adapter->msg_enable = (0x1 << debug) - 0x1;
+-
+- mmio_start = pci_resource_start(pdev, BAR_0);
+- mmio_len = pci_resource_len(pdev, BAR_0);
+-
+- adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
+- if(!adapter->hw.hw_addr) {
+- err = -EIO;
+- goto err_ioremap;
+- }
+-
+- for(i = BAR_1; i <= BAR_5; i++) {
+- if(pci_resource_len(pdev, i) == 0) {
+- continue;
+- }
+- if(pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+- adapter->hw.io_base = pci_resource_start(pdev, i);
+- break;
+- }
+- }
+-
+- netdev->open = &iegbe_open;
+- netdev->stop = &iegbe_close;
+- netdev->hard_start_xmit = &iegbe_xmit_frame;
+- netdev->get_stats = &iegbe_get_stats;
+- netdev->set_multicast_list = &iegbe_set_multi;
++ pci_set_drvdata(pdev, netdev);
++ adapter = netdev_priv(netdev);
++ adapter->netdev = netdev;
++ adapter->pdev = pdev;
++ adapter->msg_enable = (1 << debug) - 1;
++ adapter->bars = bars;
++
++ hw = &adapter->hw;
++ hw->back = adapter;
++
++ err = -EIO;
++ hw->hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
++ pci_resource_len(pdev, BAR_0));
++ if (!hw->hw_addr)
++ goto err_ioremap;
++
++ netdev->open = &iegbe_open;
++ netdev->stop = &iegbe_close;
++ netdev->hard_start_xmit = &iegbe_xmit_frame;
++ netdev->get_stats = &iegbe_get_stats;
++ netdev->set_rx_mode = &iegbe_set_rx_mode;
+ netdev->set_mac_address = &iegbe_set_mac;
+- netdev->change_mtu = &iegbe_change_mtu;
+- netdev->do_ioctl = &iegbe_ioctl;
++ netdev->change_mtu = &iegbe_change_mtu;
++ netdev->do_ioctl = &iegbe_ioctl;
+ set_ethtool_ops(netdev);
+-#ifdef HAVE_TX_TIMEOUT
+- netdev->tx_timeout = &iegbe_tx_timeout;
+- netdev->watchdog_timeo = 0x5 * HZ;
+-#endif
+-#ifdef CONFIG_E1000_NAPI
+- netdev->poll = &iegbe_clean;
+- netdev->weight = 0x40;
+-#endif
+-#ifdef NETIF_F_HW_VLAN_TX
+- netdev->vlan_rx_register = iegbe_vlan_rx_register;
+- netdev->vlan_rx_add_vid = iegbe_vlan_rx_add_vid;
+- netdev->vlan_rx_kill_vid = iegbe_vlan_rx_kill_vid;
+-#endif
++ netdev->tx_timeout = &iegbe_tx_timeout;
++ netdev->watchdog_timeo = 5 * HZ;
++ netif_napi_add(netdev, &adapter->napi, iegbe_clean, 64);
++ netdev->vlan_rx_register = iegbe_vlan_rx_register;
++ netdev->vlan_rx_add_vid = iegbe_vlan_rx_add_vid;
++ netdev->vlan_rx_kill_vid = iegbe_vlan_rx_kill_vid;
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+- netdev->poll_controller = iegbe_netpoll;
++ netdev->poll_controller = iegbe_netpoll;
+ #endif
+- strcpy(netdev->name, pci_name(pdev));
++ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
+
+- netdev->mem_start = mmio_start;
+- netdev->mem_end = mmio_start + mmio_len;
+- netdev->base_addr = adapter->hw.io_base;
+
+- adapter->bd_number = cards_found;
++ adapter->bd_number = cards_found;
+
+- /* setup the private structure */
++ /* setup the private structure */
+
+- if((err = iegbe_sw_init(adapter))) {
+- goto err_sw_init;
+- }
+- if((err = iegbe_check_phy_reset_block(&adapter->hw))) {
+- DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
+- }
+-#ifdef MAX_SKB_FRAGS
+- if(adapter->hw.mac_type >= iegbe_82543) {
+-#ifdef NETIF_F_HW_VLAN_TX
+- netdev->features = NETIF_F_SG |
+- NETIF_F_HW_CSUM |
+- NETIF_F_HW_VLAN_TX |
+- NETIF_F_HW_VLAN_RX |
+- NETIF_F_HW_VLAN_FILTER;
+-#else
+- netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM;
+-#endif
+- }
++ err = iegbe_sw_init(adapter);
++ if (err)
++ goto err_sw_init;
++ err = -EIO;
++ if (iegbe_check_phy_reset_block(hw))
++ DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
+
+-#ifdef NETIF_F_TSO
+- if((adapter->hw.mac_type >= iegbe_82544) &&
+- (adapter->hw.mac_type != iegbe_82547)) {
+- netdev->features |= NETIF_F_TSO;
+- }
+-#ifdef NETIF_F_TSO_IPV6
+- if(adapter->hw.mac_type > iegbe_82547_rev_2) {
+- netdev->features |= NETIF_F_TSO_IPV6;
+- }
+-#endif
+-#endif
+- if(pci_using_dac) {
+- netdev->features |= NETIF_F_HIGHDMA;
++ if (hw->mac_type >= iegbe_82543) {
++ netdev->features = NETIF_F_SG |
++ NETIF_F_HW_CSUM |
++ NETIF_F_HW_VLAN_TX |
++ NETIF_F_HW_VLAN_RX |
++ NETIF_F_HW_VLAN_FILTER;
+ }
+-#endif
+-#ifdef NETIF_F_LLTX
+- netdev->features |= NETIF_F_LLTX;
+-#endif
+
+- adapter->en_mng_pt = iegbe_enable_mng_pass_thru(&adapter->hw);
++ if ((hw->mac_type >= iegbe_82544) &&
++ (hw->mac_type != iegbe_82547))
++ netdev->features |= NETIF_F_TSO;
+
+- /* before reading the EEPROM, reset the controller to
+- * put the device in a known good starting state */
++ if (hw->mac_type > iegbe_82547_rev_2)
++ netdev->features |= NETIF_F_TSO6;
++ if (pci_using_dac)
++ netdev->features |= NETIF_F_HIGHDMA;
++
++ netdev->features |= NETIF_F_LLTX;
+
+- iegbe_reset_hw(&adapter->hw);
++ adapter->en_mng_pt = iegbe_enable_mng_pass_thru(hw);
+
+- /* make sure the EEPROM is good */
+- if(iegbe_validate_eeprom_checksum(&adapter->hw) < 0) {
+- DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
+- err = -EIO;
++ /* initialize eeprom parameters */
++
++ if (iegbe_init_eeprom_params(hw)) {
++ E1000_ERR("EEPROM initialization failed\n");
+ goto err_eeprom;
+ }
+
+- /* copy the MAC address out of the EEPROM */
++ /* before reading the EEPROM, reset the controller to
++ * put the device in a known good starting state */
+
+- if(iegbe_read_mac_addr(&adapter->hw)) {
+- DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
+- }
+- memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
++ iegbe_reset_hw(hw);
+
+- if(!is_valid_ether_addr(netdev->dev_addr)) {
+- DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
+- err = -EIO;
+- goto err_eeprom;
+- }
++ /* make sure the EEPROM is good */
++ if (iegbe_validate_eeprom_checksum(hw) < 0) {
++ DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
++ iegbe_dump_eeprom(adapter);
++ /*
++ * set MAC address to all zeroes to invalidate and temporary
++ * disable this device for the user. This blocks regular
++ * traffic while still permitting ethtool ioctls from reaching
++ * the hardware as well as allowing the user to run the
++ * interface after manually setting a hw addr using
++ * `ip set address`
++ */
++ memset(hw->mac_addr, 0, netdev->addr_len);
++ } else {
++ /* copy the MAC address out of the EEPROM */
++ if (iegbe_read_mac_addr(hw))
++ DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
++ }
++ /* don't block initalization here due to bad MAC address */
++ memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
++ memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
+
+- iegbe_read_part_num(&adapter->hw, &(adapter->part_num));
++ if (!is_valid_ether_addr(netdev->perm_addr))
++ DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
+
+- iegbe_get_bus_info(&adapter->hw);
++ iegbe_get_bus_info(hw);
+
+ init_timer(&adapter->tx_fifo_stall_timer);
+ adapter->tx_fifo_stall_timer.function = &iegbe_82547_tx_fifo_stall;
+- adapter->tx_fifo_stall_timer.data = (unsigned long) adapter;
++ adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
+
+ init_timer(&adapter->watchdog_timer);
+ adapter->watchdog_timer.function = &iegbe_watchdog;
+@@ -906,75 +902,50 @@ iegbe_probe(struct pci_dev *pdev,
+
+ init_timer(&adapter->phy_info_timer);
+ adapter->phy_info_timer.function = &iegbe_update_phy_info;
+- adapter->phy_info_timer.data = (unsigned long) adapter;
+-
+- INIT_WORK(&adapter->tx_timeout_task,
+- (void (*)(void *))iegbe_tx_timeout_task, netdev);
++ adapter->phy_info_timer.data = (unsigned long)adapter;
+
+- /* we're going to reset, so assume we have no link for now */
+-
+- netif_carrier_off(netdev);
+- netif_stop_queue(netdev);
++ INIT_WORK(&adapter->reset_task, iegbe_reset_task);
+
+- iegbe_check_options(adapter);
++ iegbe_check_options(adapter);
+
+- /* Initial Wake on LAN setting
+- * If APM wake is enabled in the EEPROM,
+- * enable the ACPI Magic Packet filter
+- */
++ /* Initial Wake on LAN setting
++ * If APM wake is enabled in the EEPROM,
++ * enable the ACPI Magic Packet filter
++ */
+
+- switch(adapter->hw.mac_type) {
+- case iegbe_82542_rev2_0:
+- case iegbe_82542_rev2_1:
+- case iegbe_82543:
+- break;
+- case iegbe_82544:
+- iegbe_read_eeprom(&adapter->hw,
+- EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
+- eeprom_apme_mask = E1000_EEPROM_82544_APM;
+- break;
++ switch(adapter->hw.mac_type) {
++ case iegbe_82542_rev2_0:
++ case iegbe_82542_rev2_1:
++ case iegbe_82543:
++ break;
++ case iegbe_82544:
++ iegbe_read_eeprom(&adapter->hw,
++ EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
++ eeprom_apme_mask = E1000_EEPROM_82544_APM;
++ break;
+ case iegbe_icp_xxxx:
+- iegbe_read_eeprom(&adapter->hw,
+- EEPROM_INIT_CONTROL3_ICP_xxxx(adapter->bd_number),
+- 1, &eeprom_data);
+- eeprom_apme_mask = EEPROM_CTRL3_APME_ICP_xxxx;
+- break;
+- case iegbe_82546:
+- case iegbe_82546_rev_3:
+- if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
+- && (adapter->hw.media_type == iegbe_media_type_copper)) {
+- iegbe_read_eeprom(&adapter->hw,
+- EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
+- break;
+- }
+- /* Fall Through */
+- default:
+- iegbe_read_eeprom(&adapter->hw,
+- EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+- break;
+- }
++ iegbe_read_eeprom(&adapter->hw,
++ EEPROM_INIT_CONTROL3_ICP_xxxx(adapter->bd_number),
++ 1, &eeprom_data);
++ eeprom_apme_mask = EEPROM_CTRL3_APME_ICP_xxxx;
++ break;
++ case iegbe_82546:
++ case iegbe_82546_rev_3:
++ if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
++ && (adapter->hw.media_type == iegbe_media_type_copper)) {
++ iegbe_read_eeprom(&adapter->hw,
++ EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
++ break;
++ }
++ /* Fall Through */
++ default:
++ iegbe_read_eeprom(&adapter->hw,
++ EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
++ break;
++ }
+ if(eeprom_data & eeprom_apme_mask) {
+- adapter->wol |= E1000_WUFC_MAG;
++ adapter->wol |= E1000_WUFC_MAG;
+ }
+- /* reset the hardware with the new settings */
+- iegbe_reset(adapter);
+-
+- /* Let firmware know the driver has taken over */
+- switch(adapter->hw.mac_type) {
+- case iegbe_82571:
+- case iegbe_82572:
+- ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+- E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+- ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+- break;
+- case iegbe_82573:
+- swsm = E1000_READ_REG(&adapter->hw, SWSM);
+- E1000_WRITE_REG(&adapter->hw, SWSM,
+- swsm | E1000_SWSM_DRV_LOAD);
+- break;
+- default:
+- break;
+- }
+
+ /* The ICP_xxxx device has multiple, duplicate interrupt
+ * registers, so disable all but the first one
+@@ -987,24 +958,40 @@ iegbe_probe(struct pci_dev *pdev,
+ E1000_WRITE_REG(&adapter->hw, IMC2, ~0UL);
+ }
+
+- strcpy(netdev->name, "eth%d");
+- if((err = register_netdev(netdev))) {
+- goto err_register;
+- }
++ iegbe_reset(adapter);
++ netif_carrier_off(netdev);
++ netif_stop_queue(netdev);
++ strcpy(netdev->name, "eth%d");
++ err = register_netdev(netdev);
++ if (err)
++ goto err_register;
++
+ DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
+
+- cards_found++;
+- return 0;
++ cards_found++;
++ return 0;
+
+ err_register:
+-err_sw_init:
+ err_eeprom:
+- iounmap(adapter->hw.hw_addr);
++ if (!iegbe_check_phy_reset_block(hw))
++ iegbe_phy_hw_reset(hw);
++ if (hw->flash_address)
++ iounmap(hw->flash_address);
++ for (i = 0; i < adapter->num_rx_queues; i++)
++ dev_put(&adapter->polling_netdev[i]);
++ kfree(adapter->tx_ring);
++ kfree(adapter->rx_ring);
++ kfree(adapter->polling_netdev);
++err_sw_init:
++ iounmap(hw->hw_addr);
+ err_ioremap:
+- free_netdev(netdev);
++ free_netdev(netdev);
+ err_alloc_etherdev:
+- pci_release_regions(pdev);
+- return err;
++ pci_release_selected_regions(pdev, bars);
++err_pci_reg:
++err_dma:
++ pci_disable_device(pdev);
++ return err;
+ }
+
+ /**
+@@ -1020,64 +1007,36 @@ err_alloc_etherdev:
+ static void __devexit
+ iegbe_remove(struct pci_dev *pdev)
+ {
+- struct net_device *netdev = pci_get_drvdata(pdev);
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+- uint32_t ctrl_ext;
+- uint32_t manc, swsm;
+-#ifdef CONFIG_E1000_NAPI
+- int i;
+-#endif
+-
+- if(adapter->hw.mac_type >= iegbe_82540
+- && adapter->hw.mac_type != iegbe_icp_xxxx
+- && adapter->hw.media_type == iegbe_media_type_copper) {
+- manc = E1000_READ_REG(&adapter->hw, MANC);
+- if(manc & E1000_MANC_SMBUS_EN) {
+- manc |= E1000_MANC_ARP_EN;
+- E1000_WRITE_REG(&adapter->hw, MANC, manc);
+- }
+- }
+-
+- switch(adapter->hw.mac_type) {
+- case iegbe_82571:
+- case iegbe_82572:
+- ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+- E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+- ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+- break;
+- case iegbe_82573:
+- swsm = E1000_READ_REG(&adapter->hw, SWSM);
+- E1000_WRITE_REG(&adapter->hw, SWSM,
+- swsm & ~E1000_SWSM_DRV_LOAD);
+- break;
+-
+- default:
+- break;
+- }
++ struct net_device *netdev = pci_get_drvdata(pdev);
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ uint32_t manc;
++ int i;
++
++ if(adapter->hw.mac_type >= iegbe_82540
++ && adapter->hw.mac_type != iegbe_icp_xxxx
++ && adapter->hw.media_type == iegbe_media_type_copper) {
++ manc = E1000_READ_REG(&adapter->hw, MANC);
++ if(manc & E1000_MANC_SMBUS_EN) {
++ manc |= E1000_MANC_ARP_EN;
++ E1000_WRITE_REG(&adapter->hw, MANC, manc);
++ }
++ }
+
+- unregister_netdev(netdev);
+-#ifdef CONFIG_E1000_NAPI
+- for (i = 0; i < adapter->num_queues; i++)
++ unregister_netdev(netdev);
++ for (i = 0x0; i < adapter->num_rx_queues; i++)
+ dev_put(&adapter->polling_netdev[i]);
+-#endif
+
+ if(!iegbe_check_phy_reset_block(&adapter->hw)) {
+- iegbe_phy_hw_reset(&adapter->hw);
++ iegbe_phy_hw_reset(&adapter->hw);
+ }
+- kfree(adapter->tx_ring);
+- kfree(adapter->rx_ring);
+-#ifdef CONFIG_E1000_NAPI
+- kfree(adapter->polling_netdev);
+-#endif
++ kfree(adapter->tx_ring);
++ kfree(adapter->rx_ring);
++ kfree(adapter->polling_netdev);
+
+- iounmap(adapter->hw.hw_addr);
+- pci_release_regions(pdev);
++ iounmap(adapter->hw.hw_addr);
++ pci_release_regions(pdev);
+
+-#ifdef CONFIG_E1000_MQ
+- free_percpu(adapter->cpu_netdev);
+- free_percpu(adapter->cpu_tx_ring);
+-#endif
+- free_netdev(netdev);
++ free_netdev(netdev);
+ }
+
+ /**
+@@ -1092,118 +1051,78 @@ iegbe_remove(struct pci_dev *pdev)
+ static int __devinit
+ iegbe_sw_init(struct iegbe_adapter *adapter)
+ {
+- struct iegbe_hw *hw = &adapter->hw;
+- struct net_device *netdev = adapter->netdev;
+- struct pci_dev *pdev = adapter->pdev;
+-#ifdef CONFIG_E1000_NAPI
+- int i;
+-#endif
++ struct iegbe_hw *hw = &adapter->hw;
++ struct net_device *netdev = adapter->netdev;
++ struct pci_dev *pdev = adapter->pdev;
++ int i;
+
+- /* PCI config space info */
++ /* 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->vendor_id = pdev->vendor;
++ hw->device_id = pdev->device;
++ hw->subsystem_vendor_id = pdev->subsystem_vendor;
++ hw->subsystem_id = pdev->subsystem_device;
+
+- pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
++ pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
+
+- pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
++ pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
+
+- adapter->rx_buffer_len = E1000_RXBUFFER_2048;
+- adapter->rx_ps_bsize0 = E1000_RXBUFFER_256;
+- hw->max_frame_size = netdev->mtu +
+- ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
+- hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
++ adapter->rx_buffer_len = E1000_RXBUFFER_2048;
++ adapter->rx_ps_bsize0 = E1000_RXBUFFER_256;
++ hw->max_frame_size = netdev->mtu +
++ ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
++ hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
+
+- /* identify the MAC */
++ /* identify the MAC */
+
+- if(iegbe_set_mac_type(hw)) {
++ if (iegbe_set_mac_type(hw)) {
+ DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
+ return -EIO;
+ }
+
+- /* initialize eeprom parameters */
+-
+- if(iegbe_init_eeprom_params(hw)) {
+- E1000_ERR("EEPROM initialization failed\n");
+- return -EIO;
+- }
+-
+- switch(hw->mac_type) {
+- default:
+- break;
+- case iegbe_82541:
+- case iegbe_82547:
+- case iegbe_82541_rev_2:
+- case iegbe_82547_rev_2:
+- hw->phy_init_script = 0x1;
+- break;
+- }
+-
+- iegbe_set_media_type(hw);
++ iegbe_set_media_type(hw);
+
+- hw->wait_autoneg_complete = FALSE;
+- hw->tbi_compatibility_en = TRUE;
+- hw->adaptive_ifs = TRUE;
++ hw->wait_autoneg_complete = FALSE;
++ hw->tbi_compatibility_en = TRUE;
++ hw->adaptive_ifs = TRUE;
+
+- /* Copper options */
++ /* Copper options */
+
+- if(hw->media_type == iegbe_media_type_copper
++ if(hw->media_type == iegbe_media_type_copper
+ || (hw->media_type == iegbe_media_type_oem
+ && iegbe_oem_phy_is_copper(&adapter->hw))) {
+- hw->mdix = AUTO_ALL_MODES;
+- hw->disable_polarity_correction = FALSE;
+- hw->master_slave = E1000_MASTER_SLAVE;
+- }
++ hw->mdix = AUTO_ALL_MODES;
++ hw->disable_polarity_correction = FALSE;
++ hw->master_slave = E1000_MASTER_SLAVE;
++ }
+
+-#ifdef CONFIG_E1000_MQ
+- /* Number of supported queues */
+- switch (hw->mac_type) {
+- case iegbe_82571:
+- case iegbe_82572:
+- adapter->num_queues = 0x2;
+- break;
+- default:
+- adapter->num_queues = 0x1;
+- break;
+- }
+- adapter->num_queues = min(adapter->num_queues, num_online_cpus());
+-#else
+- adapter->num_queues = 0x1;
+-#endif
++ adapter->num_tx_queues = 0x1;
++ adapter->num_rx_queues = 0x1;
+
+ if (iegbe_alloc_queues(adapter)) {
+ DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
+ return -ENOMEM;
+ }
+
+-#ifdef CONFIG_E1000_NAPI
+- for (i = 0; i < adapter->num_queues; i++) {
++ for (i = 0; i < adapter->num_rx_queues; i++) {
+ adapter->polling_netdev[i].priv = adapter;
+- adapter->polling_netdev[i].poll = &iegbe_clean;
+- adapter->polling_netdev[i].weight = 0x40;
+ dev_hold(&adapter->polling_netdev[i]);
+ set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
+ }
+-#endif
+-
+-#ifdef CONFIG_E1000_MQ
+- iegbe_setup_queue_mapping(adapter);
+-#endif
++ spin_lock_init(&adapter->tx_queue_lock);
+
+ /*
+- * for ICP_XXXX style controllers, it is necessary to keep
+- * track of the last known state of the link to determine if
+- * the link experienced a change in state when iegbe_watchdog
+- * fires
+- */
+- adapter->hw.icp_xxxx_is_link_up = FALSE;
++ * for ICP_XXXX style controllers, it is necessary to keep
++ * track of the last known state of the link to determine if
++ * the link experienced a change in state when iegbe_watchdog
++ * fires
++ */
++ adapter->hw.icp_xxxx_is_link_up = FALSE;
+
+- atomic_set(&adapter->irq_sem, 1);
+- spin_lock_init(&adapter->stats_lock);
++ spin_lock_init(&adapter->stats_lock);
+
+- return 0;
++ set_bit(__E1000_DOWN, &adapter->flags);
++ return 0x0;
+ }
+
+ /**
+@@ -1218,71 +1137,31 @@ iegbe_sw_init(struct iegbe_adapter *adap
+ static int __devinit
+ iegbe_alloc_queues(struct iegbe_adapter *adapter)
+ {
+- int size;
+
+- size = sizeof(struct iegbe_tx_ring) * adapter->num_queues;
+- adapter->tx_ring = kmalloc(size, GFP_KERNEL);
+- if (!adapter->tx_ring){
++
++ adapter->tx_ring = kcalloc(adapter->num_tx_queues,
++ sizeof(struct iegbe_tx_ring), GFP_KERNEL);
++ if (!adapter->tx_ring)
+ return -ENOMEM;
+- }
+- memset(adapter->tx_ring, 0, size);
+
+- size = sizeof(struct iegbe_rx_ring) * adapter->num_queues;
+- adapter->rx_ring = kmalloc(size, GFP_KERNEL);
++ adapter->rx_ring = kcalloc(adapter->num_rx_queues,
++ sizeof(struct iegbe_rx_ring), GFP_KERNEL);
+ if (!adapter->rx_ring) {
+ kfree(adapter->tx_ring);
+ return -ENOMEM;
+ }
+- memset(adapter->rx_ring, 0, size);
+
+-#ifdef CONFIG_E1000_NAPI
+- size = sizeof(struct net_device) * adapter->num_queues;
+- adapter->polling_netdev = kmalloc(size, GFP_KERNEL);
++ adapter->polling_netdev = kcalloc(adapter->num_rx_queues,
++ sizeof(struct net_device),
++ GFP_KERNEL);
+ if (!adapter->polling_netdev) {
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+ return -ENOMEM;
+ }
+- memset(adapter->polling_netdev, 0, size);
+-#endif
+-
+- return E1000_SUCCESS;
+-}
+
+-#ifdef CONFIG_E1000_MQ
+-static void __devinit
+-iegbe_setup_queue_mapping(struct iegbe_adapter *adapter)
+-{
+- int i, cpu;
+-
+- adapter->rx_sched_call_data.func = iegbe_rx_schedule;
+- adapter->rx_sched_call_data.info = adapter->netdev;
+- cpus_clear(adapter->rx_sched_call_data.cpumask);
+-
+- adapter->cpu_netdev = alloc_percpu(struct net_device *);
+- adapter->cpu_tx_ring = alloc_percpu(struct iegbe_tx_ring *);
+-
+- lock_cpu_hotplug();
+- i = 0;
+- for_each_online_cpu(cpu) {
+- *per_cpu_ptr(adapter->cpu_tx_ring, cpu) =
+- &adapter->tx_ring[i % adapter->num_queues];
+- /* This is incomplete because we'd like to assign separate
+- * physical cpus to these netdev polling structures and
+- * avoid saturating a subset of cpus.
+- */
+- if (i < adapter->num_queues) {
+- *per_cpu_ptr(adapter->cpu_netdev, cpu) =
+- &adapter->polling_netdev[i];
+- adapter->cpu_for_queue[i] = cpu;
+- } else {
+- *per_cpu_ptr(adapter->cpu_netdev, cpu) = NULL;
+- }
+- i++;
+- }
+- unlock_cpu_hotplug();
++ return E1000_SUCCESS;
+ }
+-#endif
+
+ /**
+ * iegbe_open - Called when a network interface is made active
+@@ -1300,40 +1179,62 @@ iegbe_setup_queue_mapping(struct iegbe_a
+ static int
+ iegbe_open(struct net_device *netdev)
+ {
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+- int err;
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct iegbe_hw *hw = &adapter->hw;
++ int err;
++
+
++ /* allocate receive descriptors */
++ if (test_bit(__E1000_TESTING, &adapter->flags))
++ return -EBUSY;
+
+- /* allocate receive descriptors */
++ /* allocate transmit descriptors */
++ err = iegbe_setup_all_tx_resources(adapter);
++ if (err)
++ goto err_setup_tx;
+
+- if ((err = iegbe_setup_all_rx_resources(adapter))) {
++ err = iegbe_setup_all_rx_resources(adapter);
++ if (err)
+ goto err_setup_rx;
+- }
+- /* allocate transmit descriptors */
+- if ((err = iegbe_setup_all_tx_resources(adapter))) {
+- goto err_setup_tx;
+- }
+- if ((err = iegbe_up(adapter))) {
+- goto err_up;
+- }
+-#ifdef NETIF_F_HW_VLAN_TX
+- adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
+- if ((adapter->hw.mng_cookie.status &
+- E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
+- iegbe_update_mng_vlan(adapter);
+- }
+-#endif
+
+- return E1000_SUCCESS;
++ iegbe_power_up_phy(adapter);
++ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
++ if ((hw->mng_cookie.status &
++ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
++ iegbe_update_mng_vlan(adapter);
++ }
++
++ /* before we allocate an interrupt, we must be ready to handle it.
++ * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
++ * as soon as we call pci_request_irq, so we have to setup our
++ * clean_rx handler before we do so. */
++ iegbe_configure(adapter);
++ err = iegbe_request_irq(adapter);
++ if (err)
++ goto err_req_irq;
+
+-err_up:
+- iegbe_free_all_tx_resources(adapter);
+-err_setup_tx:
+- iegbe_free_all_rx_resources(adapter);
++ /* From here on the code is the same as iegbe_up() */
++ clear_bit(__E1000_DOWN, &adapter->flags);
++
++ napi_enable(&adapter->napi);
++
++ iegbe_irq_enable(adapter);
++
++ netif_start_queue(netdev);
++
++ /* fire a link status change interrupt to start the watchdog */
++
++ return E1000_SUCCESS;
++
++err_req_irq:
++ iegbe_power_down_phy(adapter);
++ iegbe_free_all_rx_resources(adapter);
+ err_setup_rx:
+- iegbe_reset(adapter);
++ iegbe_free_all_tx_resources(adapter);
++err_setup_tx:
++ iegbe_reset(adapter);
+
+- return err;
++ return err;
+ }
+
+ /**
+@@ -1348,22 +1249,25 @@ err_setup_rx:
+ * hardware, and all transmit and receive resources are freed.
+ **/
+
+-static int
+-iegbe_close(struct net_device *netdev)
++static int iegbe_close(struct net_device *netdev)
+ {
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+-
+- iegbe_down(adapter);
+-
+- iegbe_free_all_tx_resources(adapter);
+- iegbe_free_all_rx_resources(adapter);
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct iegbe_hw *hw = &adapter->hw;
+
+-#ifdef NETIF_F_HW_VLAN_TX
+- if((adapter->hw.mng_cookie.status &
+- E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
++ WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
++ iegbe_down(adapter);
++ iegbe_power_down_phy(adapter);
++ iegbe_free_irq(adapter);
++
++ iegbe_free_all_tx_resources(adapter);
++ iegbe_free_all_rx_resources(adapter);
++
++ if ((hw->mng_cookie.status &
++ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
++ !(adapter->vlgrp &&
++ vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
+ iegbe_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
+ }
+-#endif
+ return 0;
+ }
+
+@@ -1375,19 +1279,19 @@ iegbe_close(struct net_device *netdev)
+ **/
+ static inline boolean_t
+ iegbe_check_64k_bound(struct iegbe_adapter *adapter,
+- void *start, unsigned long len)
++ void *start, unsigned long len)
+ {
+- unsigned long begin = (unsigned long) start;
+- unsigned long end = begin + len;
++ unsigned long begin = (unsigned long) start;
++ unsigned long end = begin + len;
+
+- /* First rev 82545 and 82546 need to not allow any memory
+- * write location to cross 64k boundary due to errata 23 */
+- if(adapter->hw.mac_type == iegbe_82545 ||
+- adapter->hw.mac_type == iegbe_82546) {
+- return ((begin ^ (end - 1)) >> 0x10) != 0 ? FALSE : TRUE;
+- }
++ /* First rev 82545 and 82546 need to not allow any memory
++ * write location to cross 64k boundary due to errata 23 */
++ if(adapter->hw.mac_type == iegbe_82545 ||
++ adapter->hw.mac_type == iegbe_82546) {
++ return ((begin ^ (end - 1)) >> 0x10) != 0x0 ? FALSE : TRUE;
++ }
+
+- return TRUE;
++ return TRUE;
+ }
+
+ /**
+@@ -1398,102 +1302,98 @@ iegbe_check_64k_bound(struct iegbe_adapt
+ * Return 0 on success, negative on failure
+ **/
+
+-int
+-iegbe_setup_tx_resources(struct iegbe_adapter *adapter,
++static int iegbe_setup_tx_resources(struct iegbe_adapter *adapter,
+ struct iegbe_tx_ring *txdr)
+ {
+- struct pci_dev *pdev = adapter->pdev;
+- int size;
++ struct pci_dev *pdev = adapter->pdev;
++ int size;
+
+- size = sizeof(struct iegbe_buffer) * txdr->count;
+- txdr->buffer_info = vmalloc(size);
+- if (!txdr->buffer_info) {
+- DPRINTK(PROBE, ERR,
+- "Unable to allocate memory for the transmit descriptor ring\n");
+- return -ENOMEM;
+- }
++ size = sizeof(struct iegbe_buffer) * txdr->count;
++ txdr->buffer_info = vmalloc(size);
++ if (!txdr->buffer_info) {
++ DPRINTK(PROBE, ERR,
++ "Unable to allocate memory for the transmit descriptor ring\n");
++ return -ENOMEM;
++ }
+ memset(txdr->buffer_info, 0, size);
+- memset(&txdr->previous_buffer_info, 0, sizeof(struct iegbe_buffer));
+
+- /* round up to nearest 4K */
++ /* round up to nearest 4K */
+
+- txdr->size = txdr->count * sizeof(struct iegbe_tx_desc);
+- E1000_ROUNDUP(txdr->size, 0x1000);
++ txdr->size = txdr->count * sizeof(struct iegbe_tx_desc);
++ txdr->size = ALIGN(txdr->size, 4096);
+
+- txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
+- if (!txdr->desc) {
++ txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
++ if (!txdr->desc) {
+ setup_tx_desc_die:
+- vfree(txdr->buffer_info);
+- DPRINTK(PROBE, ERR,
+- "Unable to allocate memory for the transmit descriptor ring\n");
+- return -ENOMEM;
+- }
+-
+- /* Fix for errata 23, can't cross 64kB boundary */
+- if (!iegbe_check_64k_bound(adapter, txdr->desc, txdr->size)) {
+- void *olddesc = txdr->desc;
+- dma_addr_t olddma = txdr->dma;
+- DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
+- "at %p\n", txdr->size, txdr->desc);
+- /* Try again, without freeing the previous */
+- txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
+- /* Failed allocation, critical failure */
+- if (!txdr->desc) {
+- pci_free_consistent(pdev, txdr->size, olddesc, olddma);
+- goto setup_tx_desc_die;
+- }
++ vfree(txdr->buffer_info);
++ DPRINTK(PROBE, ERR,
++ "Unable to allocate memory for the transmit descriptor ring\n");
++ return -ENOMEM;
++ }
++
++ /* Fix for errata 23, can't cross 64kB boundary */
++ if (!iegbe_check_64k_bound(adapter, txdr->desc, txdr->size)) {
++ void *olddesc = txdr->desc;
++ dma_addr_t olddma = txdr->dma;
++ DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
++ "at %p\n", txdr->size, txdr->desc);
++ /* Try again, without freeing the previous */
++ txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
++ /* Failed allocation, critical failure */
++ if (!txdr->desc) {
++ pci_free_consistent(pdev, txdr->size, olddesc, olddma);
++ goto setup_tx_desc_die;
++ }
+
+- if (!iegbe_check_64k_bound(adapter, txdr->desc, txdr->size)) {
+- /* give up */
+- pci_free_consistent(pdev, txdr->size, txdr->desc,
+- txdr->dma);
+- pci_free_consistent(pdev, txdr->size, olddesc, olddma);
+- DPRINTK(PROBE, ERR,
+- "Unable to allocate aligned memory "
+- "for the transmit descriptor ring\n");
+- vfree(txdr->buffer_info);
+- return -ENOMEM;
+- } else {
+- /* Free old allocation, new allocation was successful */
+- pci_free_consistent(pdev, txdr->size, olddesc, olddma);
+- }
+- }
++ if (!iegbe_check_64k_bound(adapter, txdr->desc, txdr->size)) {
++ /* give up */
++ pci_free_consistent(pdev, txdr->size, txdr->desc,
++ txdr->dma);
++ pci_free_consistent(pdev, txdr->size, olddesc, olddma);
++ DPRINTK(PROBE, ERR,
++ "Unable to allocate aligned memory "
++ "for the transmit descriptor ring\n");
++ vfree(txdr->buffer_info);
++ return -ENOMEM;
++ } else {
++ /* Free old allocation, new allocation was successful */
++ pci_free_consistent(pdev, txdr->size, olddesc, olddma);
++ }
++ }
+ memset(txdr->desc, 0, txdr->size);
+
+ txdr->next_to_use = 0;
+ txdr->next_to_clean = 0;
+- spin_lock_init(&txdr->tx_lock);
++ spin_lock_init(&txdr->tx_lock);
+
+ return 0;
+ }
+
+ /**
+ * iegbe_setup_all_tx_resources - wrapper to allocate Tx resources
+- * (Descriptors) for all queues
++ * (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+- * If this function returns with an error, then it's possible one or
+- * more of the rings is populated (while the rest are not). It is the
+- * callers duty to clean those orphaned rings.
+- *
+ * Return 0 on success, negative on failure
+ **/
+
+-int
+-iegbe_setup_all_tx_resources(struct iegbe_adapter *adapter)
++int iegbe_setup_all_tx_resources(struct iegbe_adapter *adapter)
+ {
+ int i, err = 0;
+
+- for (i = 0; i < adapter->num_queues; i++) {
++ for (i = 0; i < adapter->num_tx_queues; i++) {
+ err = iegbe_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+ if (err) {
+ DPRINTK(PROBE, ERR,
+ "Allocation for Tx Queue %u failed\n", i);
++ for (i-- ; i >= 0; i--)
++ iegbe_free_tx_resources(adapter,
++ &adapter->tx_ring[i]);
+ break;
+ }
+ }
+
+- return err;
++ return err;
+ }
+
+ /**
+@@ -1512,113 +1412,108 @@ iegbe_configure_tx(struct iegbe_adapter
+
+ /* Setup the HW Tx Head and Tail descriptor pointers */
+
+- switch (adapter->num_queues) {
++ switch (adapter->num_tx_queues) {
+ case 0x2:
+ tdba = adapter->tx_ring[0x1].dma;
+ tdlen = adapter->tx_ring[0x1].count *
+- sizeof(struct iegbe_tx_desc);
+- E1000_WRITE_REG(hw, TDBAL1, (tdba & 0x00000000ffffffffULL));
++ sizeof(struct iegbe_tx_desc);
++ E1000_WRITE_REG(hw, TDBAL1, (tdba & 0x00000000ffffffffULL));
+ E1000_WRITE_REG(hw, TDBAH1, (tdba >> 0x20));
+- E1000_WRITE_REG(hw, TDLEN1, tdlen);
+- E1000_WRITE_REG(hw, TDH1, 0);
+- E1000_WRITE_REG(hw, TDT1, 0);
++ E1000_WRITE_REG(hw, TDLEN1, tdlen);
++ E1000_WRITE_REG(hw, TDH1, 0x0);
++ E1000_WRITE_REG(hw, TDT1, 0x0);
+ adapter->tx_ring[0x1].tdh = E1000_TDH1;
+ adapter->tx_ring[0x1].tdt = E1000_TDT1;
+- /* Fall Through */
++ /* Fall Through */
+ case 0x1:
+- default:
+- tdba = adapter->tx_ring[0].dma;
+- tdlen = adapter->tx_ring[0].count *
+- sizeof(struct iegbe_tx_desc);
+- E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
++ default:
++ tdba = adapter->tx_ring[0x0].dma;
++ tdlen = adapter->tx_ring[0x0].count *
++ sizeof(struct iegbe_tx_desc);
++ E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
+ E1000_WRITE_REG(hw, TDBAH, (tdba >> 0x20));
+- E1000_WRITE_REG(hw, TDLEN, tdlen);
+- E1000_WRITE_REG(hw, TDH, 0);
+- E1000_WRITE_REG(hw, TDT, 0);
+- adapter->tx_ring[0].tdh = E1000_TDH;
+- adapter->tx_ring[0].tdt = E1000_TDT;
+- break;
+- }
+-
+- /* Set the default values for the Tx Inter Packet Gap timer */
+-
+- switch (hw->mac_type) {
+- case iegbe_82542_rev2_0:
+- case iegbe_82542_rev2_1:
+- tipg = DEFAULT_82542_TIPG_IPGT;
+- tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
+- tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+- break;
+- default:
+- switch(hw->media_type) {
+- case iegbe_media_type_fiber:
+- case iegbe_media_type_internal_serdes:
+- tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
+- break;
+- case iegbe_media_type_copper:
+- tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
+- break;
+- case iegbe_media_type_oem:
+- default:
++ E1000_WRITE_REG(hw, TDLEN, tdlen);
++ E1000_WRITE_REG(hw, TDH, 0x0);
++ E1000_WRITE_REG(hw, TDT, 0x0);
++ adapter->tx_ring[0x0].tdh = E1000_TDH;
++ adapter->tx_ring[0x0].tdt = E1000_TDT;
++ break;
++ }
++
++ /* Set the default values for the Tx Inter Packet Gap timer */
++
++ switch (hw->mac_type) {
++ case iegbe_82542_rev2_0:
++ case iegbe_82542_rev2_1:
++ tipg = DEFAULT_82542_TIPG_IPGT;
++ tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
++ tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
++ break;
++ default:
++ switch(hw->media_type) {
++ case iegbe_media_type_fiber:
++ case iegbe_media_type_internal_serdes:
++ tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
++ break;
++ case iegbe_media_type_copper:
++ tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
++ break;
++ case iegbe_media_type_oem:
++ default:
+ tipg = (0xFFFFFFFFUL >> (sizeof(tipg)*0x8 -
+ E1000_TIPG_IPGR1_SHIFT))
+- & iegbe_oem_get_tipg(&adapter->hw);
+- break;
+- }
+- tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
+- tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+- }
+- E1000_WRITE_REG(hw, TIPG, tipg);
++ & iegbe_oem_get_tipg(&adapter->hw);
++ break;
++ }
++ tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
++ tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
++ }
++ E1000_WRITE_REG(hw, TIPG, tipg);
+
+- /* Set the Tx Interrupt Delay register */
++ /* Set the Tx Interrupt Delay register */
+
+- E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
++ E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
+ if (hw->mac_type >= iegbe_82540) {
+- E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
++ E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
+ }
+- /* Program the Transmit Control Register */
++ /* Program the Transmit Control Register */
+
+- tctl = E1000_READ_REG(hw, TCTL);
++ tctl = E1000_READ_REG(hw, TCTL);
+
+- tctl &= ~E1000_TCTL_CT;
+- tctl |= E1000_TCTL_EN | E1000_TCTL_PSP | E1000_TCTL_RTLC |
+- (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
++ tctl &= ~E1000_TCTL_CT;
++ tctl |= E1000_TCTL_EN | E1000_TCTL_PSP | E1000_TCTL_RTLC |
++ (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
+
+- E1000_WRITE_REG(hw, TCTL, tctl);
++ E1000_WRITE_REG(hw, TCTL, tctl);
+
+- if (hw->mac_type == iegbe_82571 || hw->mac_type == iegbe_82572) {
+- tarc = E1000_READ_REG(hw, TARC0);
++ if (hw->mac_type == iegbe_82571 || hw->mac_type == iegbe_82572) {
++ tarc = E1000_READ_REG(hw, TARC0);
+ tarc |= ((0x1 << 0x19) | (0x1 << 0x15));
+- E1000_WRITE_REG(hw, TARC0, tarc);
+- tarc = E1000_READ_REG(hw, TARC1);
++ E1000_WRITE_REG(hw, TARC0, tarc);
++ tarc = E1000_READ_REG(hw, TARC1);
+ tarc |= (0x1 << 0x19);
+ if (tctl & E1000_TCTL_MULR) {
+ tarc &= ~(0x1 << 0x1c);
+ } else {
+ tarc |= (0x1 << 0x1c);
+ }
+- E1000_WRITE_REG(hw, TARC1, tarc);
+- }
++ E1000_WRITE_REG(hw, TARC1, tarc);
++ }
+
+- iegbe_config_collision_dist(hw);
++ iegbe_config_collision_dist(hw);
+
+- /* Setup Transmit Descriptor Settings for eop descriptor */
+- adapter->txd_cmd = E1000_TXD_CMD_IDE | E1000_TXD_CMD_EOP |
+- E1000_TXD_CMD_IFCS;
++ /* Setup Transmit Descriptor Settings for eop descriptor */
++ adapter->txd_cmd = E1000_TXD_CMD_IDE | E1000_TXD_CMD_EOP |
++ E1000_TXD_CMD_IFCS;
+
+ if (hw->mac_type < iegbe_82543) {
+- adapter->txd_cmd |= E1000_TXD_CMD_RPS;
++ adapter->txd_cmd |= E1000_TXD_CMD_RPS;
+ } else {
+-#ifdef IEGBE_GBE_WORKAROUND
+- /* Disable the RS bit in the Tx descriptor */
+- adapter->txd_cmd &= ~E1000_TXD_CMD_RS;
+-#else
+- adapter->txd_cmd |= E1000_TXD_CMD_RS;
+-#endif
++ adapter->txd_cmd |= E1000_TXD_CMD_RS;
+ }
+- /* Cache if we're 82544 running in PCI-X because we'll
+- * need this to apply a workaround later in the send path. */
+- if (hw->mac_type == iegbe_82544 &&
++ /* Cache if we're 82544 running in PCI-X because we'll
++ * need this to apply a workaround later in the send path. */
++ if (hw->mac_type == iegbe_82544 &&
+ hw->bus_type == iegbe_bus_type_pcix) {
+ adapter->pcix_82544 = 0x1;
+ }
+@@ -1632,96 +1527,95 @@ iegbe_configure_tx(struct iegbe_adapter
+ * Returns 0 on success, negative on failure
+ **/
+
+-int
+-iegbe_setup_rx_resources(struct iegbe_adapter *adapter,
++static int iegbe_setup_rx_resources(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rxdr)
+ {
+- struct pci_dev *pdev = adapter->pdev;
+- int size, desc_len;
+-
+- size = sizeof(struct iegbe_buffer) * rxdr->count;
+- rxdr->buffer_info = vmalloc(size);
+- if (!rxdr->buffer_info) {
+- DPRINTK(PROBE, ERR,
+- "Unable to allocate memory for the receive descriptor ring\n");
+- return -ENOMEM;
+- }
+- memset(rxdr->buffer_info, 0, size);
+-
+- size = sizeof(struct iegbe_ps_page) * rxdr->count;
+- rxdr->ps_page = kmalloc(size, GFP_KERNEL);
+- if (!rxdr->ps_page) {
+- vfree(rxdr->buffer_info);
+- DPRINTK(PROBE, ERR,
+- "Unable to allocate memory for the receive descriptor ring\n");
+- return -ENOMEM;
+- }
+- memset(rxdr->ps_page, 0, size);
+-
+- size = sizeof(struct iegbe_ps_page_dma) * rxdr->count;
+- rxdr->ps_page_dma = kmalloc(size, GFP_KERNEL);
+- if (!rxdr->ps_page_dma) {
+- vfree(rxdr->buffer_info);
+- kfree(rxdr->ps_page);
+- DPRINTK(PROBE, ERR,
+- "Unable to allocate memory for the receive descriptor ring\n");
+- return -ENOMEM;
+- }
+- memset(rxdr->ps_page_dma, 0, size);
++ struct iegbe_hw *hw = &adapter->hw;
++ struct pci_dev *pdev = adapter->pdev;
++ int size, desc_len;
+
+- if (adapter->hw.mac_type <= iegbe_82547_rev_2) {
+- desc_len = sizeof(struct iegbe_rx_desc);
+- } else {
+- desc_len = sizeof(union iegbe_rx_desc_packet_split);
++ size = sizeof(struct iegbe_buffer) * rxdr->count;
++ rxdr->buffer_info = vmalloc(size);
++ if (!rxdr->buffer_info) {
++ DPRINTK(PROBE, ERR,
++ "Unable to allocate memory for the receive descriptor ring\n");
++ return -ENOMEM;
+ }
+- /* Round up to nearest 4K */
+-
+- rxdr->size = rxdr->count * desc_len;
+- E1000_ROUNDUP(rxdr->size, 0x1000);
+-
+- rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
++ memset(rxdr->buffer_info, 0, size);
+
+- if (!rxdr->desc) {
+- DPRINTK(PROBE, ERR,
+- "Unable to allocate memory for the receive descriptor ring\n");
++ rxdr->ps_page = kcalloc(rxdr->count, sizeof(struct iegbe_ps_page),
++ GFP_KERNEL);
++ if (!rxdr->ps_page) {
++ vfree(rxdr->buffer_info);
++ DPRINTK(PROBE, ERR,
++ "Unable to allocate memory for the receive descriptor ring\n");
++ return -ENOMEM;
++ }
++
++ rxdr->ps_page_dma = kcalloc(rxdr->count,
++ sizeof(struct iegbe_ps_page_dma),
++ GFP_KERNEL);
++ if (!rxdr->ps_page_dma) {
++ vfree(rxdr->buffer_info);
++ kfree(rxdr->ps_page);
++ DPRINTK(PROBE, ERR,
++ "Unable to allocate memory for the receive descriptor ring\n");
++ return -ENOMEM;
++ }
++
++ if (hw->mac_type <= iegbe_82547_rev_2)
++ desc_len = sizeof(struct iegbe_rx_desc);
++ else
++ desc_len = sizeof(union iegbe_rx_desc_packet_split);
++
++ /* Round up to nearest 4K */
++
++ rxdr->size = rxdr->count * desc_len;
++ rxdr->size = ALIGN(rxdr->size, 4096);
++
++ rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
++
++ if (!rxdr->desc) {
++ DPRINTK(PROBE, ERR,
++ "Unable to allocate memory for the receive descriptor ring\n");
+ setup_rx_desc_die:
+- vfree(rxdr->buffer_info);
+- kfree(rxdr->ps_page);
+- kfree(rxdr->ps_page_dma);
+- return -ENOMEM;
+- }
+-
+- /* Fix for errata 23, can't cross 64kB boundary */
+- if (!iegbe_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
+- void *olddesc = rxdr->desc;
+- dma_addr_t olddma = rxdr->dma;
+- DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
+- "at %p\n", rxdr->size, rxdr->desc);
+- /* Try again, without freeing the previous */
+- rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
+- /* Failed allocation, critical failure */
+- if (!rxdr->desc) {
+- pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+- DPRINTK(PROBE, ERR,
+- "Unable to allocate memory "
+- "for the receive descriptor ring\n");
+- goto setup_rx_desc_die;
+- }
++ vfree(rxdr->buffer_info);
++ kfree(rxdr->ps_page);
++ kfree(rxdr->ps_page_dma);
++ return -ENOMEM;
++ }
++
++ /* Fix for errata 23, can't cross 64kB boundary */
++ if (!iegbe_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
++ void *olddesc = rxdr->desc;
++ dma_addr_t olddma = rxdr->dma;
++ DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
++ "at %p\n", rxdr->size, rxdr->desc);
++ /* Try again, without freeing the previous */
++ rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
++ /* Failed allocation, critical failure */
++ if (!rxdr->desc) {
++ pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
++ DPRINTK(PROBE, ERR,
++ "Unable to allocate memory "
++ "for the receive descriptor ring\n");
++ goto setup_rx_desc_die;
++ }
+
+- if (!iegbe_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
+- /* give up */
+- pci_free_consistent(pdev, rxdr->size, rxdr->desc,
+- rxdr->dma);
+- pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+- DPRINTK(PROBE, ERR,
+- "Unable to allocate aligned memory "
+- "for the receive descriptor ring\n");
+- goto setup_rx_desc_die;
+- } else {
+- /* Free old allocation, new allocation was successful */
+- pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+- }
+- }
++ if (!iegbe_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
++ /* give up */
++ pci_free_consistent(pdev, rxdr->size, rxdr->desc,
++ rxdr->dma);
++ pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
++ DPRINTK(PROBE, ERR,
++ "Unable to allocate aligned memory "
++ "for the receive descriptor ring\n");
++ goto setup_rx_desc_die;
++ } else {
++ /* Free old allocation, new allocation was successful */
++ pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
++ }
++ }
+ memset(rxdr->desc, 0, rxdr->size);
+
+ rxdr->next_to_clean = 0;
+@@ -1732,7 +1626,7 @@ setup_rx_desc_die:
+
+ /**
+ * iegbe_setup_all_rx_resources - wrapper to allocate Rx resources
+- * (Descriptors) for all queues
++ * (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+@@ -1742,21 +1636,23 @@ setup_rx_desc_die:
+ * Return 0 on success, negative on failure
+ **/
+
+-int
+-iegbe_setup_all_rx_resources(struct iegbe_adapter *adapter)
++int iegbe_setup_all_rx_resources(struct iegbe_adapter *adapter)
+ {
+ int i, err = 0;
+
+- for (i = 0; i < adapter->num_queues; i++) {
++ for (i = 0; i < adapter->num_rx_queues; i++) {
+ err = iegbe_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+ if (err) {
+ DPRINTK(PROBE, ERR,
+ "Allocation for Rx Queue %u failed\n", i);
++ for (i-- ; i >= 0; i--)
++ iegbe_free_rx_resources(adapter,
++ &adapter->rx_ring[i]);
+ break;
+ }
+ }
+
+- return err;
++ return err;
+ }
+
+ /**
+@@ -1765,105 +1661,104 @@ iegbe_setup_all_rx_resources(struct iegb
+ **/
+ #define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
+ (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
+-static void
+-iegbe_setup_rctl(struct iegbe_adapter *adapter)
++static void iegbe_setup_rctl(struct iegbe_adapter *adapter)
+ {
+- uint32_t rctl, rfctl;
+- uint32_t psrctl = 0;
+-#ifdef CONFIG_E1000_PACKET_SPLIT
+- uint32_t pages = 0;
+-#endif
+-
+- rctl = E1000_READ_REG(&adapter->hw, RCTL);
+-
+- rctl &= ~(0x3 << E1000_RCTL_MO_SHIFT);
+-
+- rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
+- E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
+- (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
+-
+- if(adapter->hw.tbi_compatibility_on == 0x1) {
+- rctl |= E1000_RCTL_SBP;
+- } else {
+- rctl &= ~E1000_RCTL_SBP;
+- }
+- if(adapter->netdev->mtu <= ETH_DATA_LEN) {
+- rctl &= ~E1000_RCTL_LPE;
+- } else {
+- rctl |= E1000_RCTL_LPE;
+- }
+- /* Setup buffer sizes */
+- if(adapter->hw.mac_type >= iegbe_82571) {
+- /* We can now specify buffers in 1K increments.
+- * BSIZE and BSEX are ignored in this case. */
+- rctl |= adapter->rx_buffer_len << 0x11;
+- } else {
+- rctl &= ~E1000_RCTL_SZ_4096;
+- rctl |= E1000_RCTL_BSEX;
+- switch (adapter->rx_buffer_len) {
+- case E1000_RXBUFFER_2048:
+- default:
+- rctl |= E1000_RCTL_SZ_2048;
++ struct iegbe_hw *hw = &adapter->hw;
++ u32 rctl, rfctl;
++ u32 psrctl = 0;
++#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
++ u32 pages = 0;
++#endif
++
++ rctl = E1000_READ_REG(&adapter->hw, RCTL);
++
++ rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
++
++ rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
++ E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
++ (hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
++
++ if (hw->tbi_compatibility_on == 1)
++ rctl |= E1000_RCTL_SBP;
++ else
++ rctl &= ~E1000_RCTL_SBP;
++
++ if (adapter->netdev->mtu <= ETH_DATA_LEN)
++ rctl &= ~E1000_RCTL_LPE;
++ else
++ rctl |= E1000_RCTL_LPE;
++
++ /* Setup buffer sizes */
++ /* We can now specify buffers in 1K increments.
++ * BSIZE and BSEX are ignored in this case. */
++ rctl &= ~E1000_RCTL_SZ_4096;
++ rctl |= E1000_RCTL_BSEX;
++ switch (adapter->rx_buffer_len) {
++ case E1000_RXBUFFER_256:
++ rctl |= E1000_RCTL_SZ_256;
+ rctl &= ~E1000_RCTL_BSEX;
+ break;
+- case E1000_RXBUFFER_4096:
+- rctl |= E1000_RCTL_SZ_4096;
+- break;
+- case E1000_RXBUFFER_8192:
+- rctl |= E1000_RCTL_SZ_8192;
+- break;
+- case E1000_RXBUFFER_16384:
+- rctl |= E1000_RCTL_SZ_16384;
+- break;
+- }
+- }
++ case E1000_RXBUFFER_2048:
++ default:
++ rctl |= E1000_RCTL_SZ_2048;
++ rctl &= ~E1000_RCTL_BSEX;
++ break;
++ case E1000_RXBUFFER_4096:
++ rctl |= E1000_RCTL_SZ_4096;
++ break;
++ case E1000_RXBUFFER_8192:
++ rctl |= E1000_RCTL_SZ_8192;
++ break;
++ case E1000_RXBUFFER_16384:
++ rctl |= E1000_RCTL_SZ_16384;
++ break;
++ }
+
+-#ifdef CONFIG_E1000_PACKET_SPLIT
+- /* 82571 and greater support packet-split where the protocol
+- * header is placed in skb->data and the packet data is
+- * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
+- * In the case of a non-split, skb->data is linearly filled,
+- * followed by the page buffers. Therefore, skb->data is
+- * sized to hold the largest protocol header.
+- */
+- pages = PAGE_USE_COUNT(adapter->netdev->mtu);
+- if ((adapter->hw.mac_type > iegbe_82547_rev_2) && (pages <= 0x3) &&
+- PAGE_SIZE <= 0x4000) {
+- adapter->rx_ps_pages = pages;
+- } else {
++#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
++ /* 82571 and greater support packet-split where the protocol
++ * header is placed in skb->data and the packet data is
++ * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
++ * In the case of a non-split, skb->data is linearly filled,
++ * followed by the page buffers. Therefore, skb->data is
++ * sized to hold the largest protocol header.
++ */
++ pages = PAGE_USE_COUNT(adapter->netdev->mtu);
++ if ((hw->mac_type >= iegbe_82571) && (pages <= 3) &&
++ PAGE_SIZE <= 16384 && (rctl & E1000_RCTL_LPE))
++ adapter->rx_ps_pages = pages;
++ else
+ adapter->rx_ps_pages = 0;
+- }
+ #endif
+- if (adapter->rx_ps_pages) {
+- /* Configure extra packet-split registers */
+- rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
+- rfctl |= E1000_RFCTL_EXTEN;
+- /* disable IPv6 packet split support */
+- rfctl |= E1000_RFCTL_IPV6_DIS;
+- E1000_WRITE_REG(&adapter->hw, RFCTL, rfctl);
+-
+- rctl |= E1000_RCTL_DTYP_PS | E1000_RCTL_SECRC;
+-
+- psrctl |= adapter->rx_ps_bsize0 >>
+- E1000_PSRCTL_BSIZE0_SHIFT;
+-
+- switch (adapter->rx_ps_pages) {
+- case 0x3:
+- psrctl |= PAGE_SIZE <<
+- E1000_PSRCTL_BSIZE3_SHIFT;
+- case 0x2:
+- psrctl |= PAGE_SIZE <<
+- E1000_PSRCTL_BSIZE2_SHIFT;
+- case 0x1:
+- psrctl |= PAGE_SIZE >>
+- E1000_PSRCTL_BSIZE1_SHIFT;
+- break;
+- }
++ if (adapter->rx_ps_pages) {
++ /* Configure extra packet-split registers */
++ rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
++ rfctl |= E1000_RFCTL_EXTEN;
++ /* disable IPv6 packet split support */
++ rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
++ E1000_RFCTL_NEW_IPV6_EXT_DIS);
++
++ rctl |= E1000_RCTL_DTYP_PS;
++
++ psrctl |= adapter->rx_ps_bsize0 >>
++ E1000_PSRCTL_BSIZE0_SHIFT;
++
++ switch (adapter->rx_ps_pages) {
++ case 3:
++ psrctl |= PAGE_SIZE <<
++ E1000_PSRCTL_BSIZE3_SHIFT;
++ case 2:
++ psrctl |= PAGE_SIZE <<
++ E1000_PSRCTL_BSIZE2_SHIFT;
++ case 1:
++ psrctl |= PAGE_SIZE >>
++ E1000_PSRCTL_BSIZE1_SHIFT;
++ break;
++ }
+
+- E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
+- }
++ E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
++ }
+
+- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
++ E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+ }
+
+ /**
+@@ -1873,145 +1768,87 @@ iegbe_setup_rctl(struct iegbe_adapter *a
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+
+-static void
+-iegbe_configure_rx(struct iegbe_adapter *adapter)
++static void iegbe_configure_rx(struct iegbe_adapter *adapter)
+ {
+- uint64_t rdba;
+- struct iegbe_hw *hw = &adapter->hw;
+- uint32_t rdlen, rctl, rxcsum, ctrl_ext;
+-#ifdef CONFIG_E1000_MQ
+- uint32_t reta, mrqc;
+- int i;
+-#endif
++ u64 rdba;
++ struct iegbe_hw *hw = &adapter->hw;
++ u32 rdlen, rctl, rxcsum, ctrl_ext;
+
+- if (adapter->rx_ps_pages) {
++ if (adapter->rx_ps_pages) {
+ rdlen = adapter->rx_ring[0].count *
+- sizeof(union iegbe_rx_desc_packet_split);
+- adapter->clean_rx = iegbe_clean_rx_irq_ps;
+- adapter->alloc_rx_buf = iegbe_alloc_rx_buffers_ps;
+- } else {
++ sizeof(union iegbe_rx_desc_packet_split);
++ adapter->clean_rx = iegbe_clean_rx_irq_ps;
++ adapter->alloc_rx_buf = iegbe_alloc_rx_buffers_ps;
++ } else {
+ rdlen = adapter->rx_ring[0].count *
+- sizeof(struct iegbe_rx_desc);
+- adapter->clean_rx = iegbe_clean_rx_irq;
+- adapter->alloc_rx_buf = iegbe_alloc_rx_buffers;
+- }
++ sizeof(struct iegbe_rx_desc);
++ adapter->clean_rx = iegbe_clean_rx_irq;
++ adapter->alloc_rx_buf = iegbe_alloc_rx_buffers;
++ }
+
+- /* disable receives while setting up the descriptors */
+- rctl = E1000_READ_REG(hw, RCTL);
+- E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
++ /* disable receives while setting up the descriptors */
++ rctl = E1000_READ_REG(hw, RCTL);
++ E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
+
+- /* set the Receive Delay Timer Register */
+- E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
++ /* set the Receive Delay Timer Register */
++ E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
+
+- if (hw->mac_type >= iegbe_82540) {
+- E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
+- if(adapter->itr > 0x1) {
+- E1000_WRITE_REG(hw, ITR,
+- 0x3b9aca00 / (adapter->itr * 0x100));
++ if (hw->mac_type >= iegbe_82540) {
++ E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
++ if (adapter->itr_setting != 0)
++ E1000_WRITE_REG(&adapter->hw, ITR, 1000000000 / (adapter->itr * 256));
+ }
+- }
+
+- if (hw->mac_type >= iegbe_82571) {
+- /* Reset delay timers after every interrupt */
+- ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+- ctrl_ext |= E1000_CTRL_EXT_CANC;
+- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+- E1000_WRITE_FLUSH(hw);
+- }
++ if (hw->mac_type >= iegbe_82571) {
++ /* Reset delay timers after every interrupt */
++ ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
++ ctrl_ext |= E1000_CTRL_EXT_CANC;
++ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
++ E1000_WRITE_FLUSH(hw);
++ }
+
+ /* Setup the HW Rx Head and Tail Descriptor Pointers and
+ * the Base and Length of the Rx Descriptor Ring */
+- switch (adapter->num_queues) {
+-#ifdef CONFIG_E1000_MQ
+- case 0x2:
+- rdba = adapter->rx_ring[0x1].dma;
+- E1000_WRITE_REG(hw, RDBAL1, (rdba & 0x00000000ffffffffULL));
+- E1000_WRITE_REG(hw, RDBAH1, (rdba >> 0x20));
+- E1000_WRITE_REG(hw, RDLEN1, rdlen);
+- E1000_WRITE_REG(hw, RDH1, 0);
+- E1000_WRITE_REG(hw, RDT1, 0);
+- adapter->rx_ring[1].rdh = E1000_RDH1;
+- adapter->rx_ring[1].rdt = E1000_RDT1;
+- /* Fall Through */
+-#endif
+- case 0x1:
+- default:
++ switch (adapter->num_rx_queues) {
++ case 1:
++ default:
+ rdba = adapter->rx_ring[0].dma;
+- E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
++ E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
+ E1000_WRITE_REG(hw, RDBAH, (rdba >> 0x20));
+- E1000_WRITE_REG(hw, RDLEN, rdlen);
+- E1000_WRITE_REG(hw, RDH, 0);
+- E1000_WRITE_REG(hw, RDT, 0);
+- adapter->rx_ring[0].rdh = E1000_RDH;
+- adapter->rx_ring[0].rdt = E1000_RDT;
+- break;
+- }
++ E1000_WRITE_REG(hw, RDLEN, rdlen);
++ adapter->rx_ring[0].rdh = ((hw->mac_type >= iegbe_82543) ? E1000_RDH : E1000_82542_RDH);
++ adapter->rx_ring[0].rdt = ((hw->mac_type >= iegbe_82543) ? E1000_RDT : E1000_82542_RDT);
++ break;
++ }
+
+-#ifdef CONFIG_E1000_MQ
+- if (adapter->num_queues > 0x1) {
+- uint32_t random[0xa];
+-
+- get_random_bytes(&random[0], FORTY);
+-
+- if (hw->mac_type <= iegbe_82572) {
+- E1000_WRITE_REG(hw, RSSIR, 0);
+- E1000_WRITE_REG(hw, RSSIM, 0);
+- }
+
+- switch (adapter->num_queues) {
+- case 0x2:
+- default:
+- reta = 0x00800080;
+- mrqc = E1000_MRQC_ENABLE_RSS_2Q;
+- break;
+- }
+-
+- /* Fill out redirection table */
+- for (i = 0; i < 0x20; i++)
+- E1000_WRITE_REG_ARRAY(hw, RETA, i, reta);
+- /* Fill out hash function seeds */
+- for (i = 0; i < 0xa; i++)
+- E1000_WRITE_REG_ARRAY(hw, RSSRK, i, random[i]);
+-
+- mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
+- E1000_MRQC_RSS_FIELD_IPV4_TCP);
+- E1000_WRITE_REG(hw, MRQC, mrqc);
+- }
+-
+- /* Multiqueue and packet checksumming are mutually exclusive. */
+- if (hw->mac_type >= iegbe_82571) {
+- rxcsum = E1000_READ_REG(hw, RXCSUM);
+- rxcsum |= E1000_RXCSUM_PCSD;
+- E1000_WRITE_REG(hw, RXCSUM, rxcsum);
+- }
+-
+-#else
++ /* Enable 82543 Receive Checksum Offload for TCP and UDP */
++ if (hw->mac_type >= iegbe_82543) {
++ rxcsum = E1000_READ_REG(hw, RXCSUM);
++ if(adapter->rx_csum == TRUE) {
++ rxcsum |= E1000_RXCSUM_TUOFL;
++
++ /* Enable 82571 IPv4 payload checksum for UDP fragments
++ * Must be used in conjunction with packet-split. */
++ if ((hw->mac_type >= iegbe_82571) &&
++ (adapter->rx_ps_pages)) {
++ rxcsum |= E1000_RXCSUM_IPPCSE;
++ }
++ } else {
++ rxcsum &= ~E1000_RXCSUM_TUOFL;
++ /* don't need to clear IPPCSE as it defaults to 0 */
++ }
++ E1000_WRITE_REG(hw, RXCSUM, rxcsum);
++ }
+
+- /* Enable 82543 Receive Checksum Offload for TCP and UDP */
+- if (hw->mac_type >= iegbe_82543) {
+- rxcsum = E1000_READ_REG(hw, RXCSUM);
+- if(adapter->rx_csum == TRUE) {
+- rxcsum |= E1000_RXCSUM_TUOFL;
+-
+- /* Enable 82571 IPv4 payload checksum for UDP fragments
+- * Must be used in conjunction with packet-split. */
+- if ((hw->mac_type >= iegbe_82571) &&
+- (adapter->rx_ps_pages)) {
+- rxcsum |= E1000_RXCSUM_IPPCSE;
+- }
+- } else {
+- rxcsum &= ~E1000_RXCSUM_TUOFL;
+- /* don't need to clear IPPCSE as it defaults to 0 */
+- }
+- E1000_WRITE_REG(hw, RXCSUM, rxcsum);
+- }
+-#endif /* CONFIG_E1000_MQ */
++ /* enable early receives on 82573, only takes effect if using > 2048
++ * byte total frame size. for example only for jumbo frames */
++#define E1000_ERT_2048 0x100
++ if (hw->mac_type == iegbe_82573)
++ E1000_WRITE_REG(&adapter->hw, ERT, E1000_ERT_2048);
+
+- if (hw->mac_type == iegbe_82573) {
+- E1000_WRITE_REG(hw, ERT, 0x0100);
+- }
+ /* Enable Receives */
+- E1000_WRITE_REG(hw, RCTL, rctl);
++ E1000_WRITE_REG(hw, RCTL, rctl);
+ }
+
+ /**
+@@ -2022,20 +1859,19 @@ iegbe_configure_rx(struct iegbe_adapter
+ * Free all transmit software resources
+ **/
+
+-void
+-iegbe_free_tx_resources(struct iegbe_adapter *adapter,
++static void iegbe_free_tx_resources(struct iegbe_adapter *adapter,
+ struct iegbe_tx_ring *tx_ring)
+ {
+- struct pci_dev *pdev = adapter->pdev;
++ struct pci_dev *pdev = adapter->pdev;
+
+- iegbe_clean_tx_ring(adapter, tx_ring);
++ iegbe_clean_tx_ring(adapter, tx_ring);
+
+- vfree(tx_ring->buffer_info);
+- tx_ring->buffer_info = NULL;
++ vfree(tx_ring->buffer_info);
++ tx_ring->buffer_info = NULL;
+
+- pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
++ pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+
+- tx_ring->desc = NULL;
++ tx_ring->desc = NULL;
+ }
+
+ /**
+@@ -2048,85 +1884,29 @@ iegbe_free_tx_resources(struct iegbe_ada
+ void
+ iegbe_free_all_tx_resources(struct iegbe_adapter *adapter)
+ {
+- int i;
++ int i;
+
+- for (i = 0; i < adapter->num_queues; i++)
++ for (i = 0x0; i < adapter->num_tx_queues; i++)
+ iegbe_free_tx_resources(adapter, &adapter->tx_ring[i]);
+ }
+
+ static inline void
+ iegbe_unmap_and_free_tx_resource(struct iegbe_adapter *adapter,
+- struct iegbe_buffer *buffer_info)
+-{
+- if(buffer_info->dma) {
+- pci_unmap_page(adapter->pdev,
+- buffer_info->dma,
+- buffer_info->length,
+- PCI_DMA_TODEVICE);
+- buffer_info->dma = 0;
+- }
+- if(buffer_info->skb) {
+- dev_kfree_skb_any(buffer_info->skb);
+- buffer_info->skb = NULL;
+- }
+-}
+-
+-#ifdef IEGBE_GBE_WORKAROUND
+-/**
+- * iegbe_clean_tx_ring_partial - Free Tx Buffers without using the DD
+- * bit in the descriptor
+- * @adapter: board private structure
+- * @tx_ring: ring to be cleaned
+- **/
+-static void iegbe_clean_tx_ring_partial(struct iegbe_adapter *adapter,
+- struct iegbe_tx_ring *tx_ring)
++ struct iegbe_buffer *buffer_info)
+ {
+- struct iegbe_buffer *buffer_info;
+- struct iegbe_tx_desc *tx_desc;
+- struct net_device *netdev = adapter->netdev;
+- unsigned int i;
+- unsigned tail;
+- unsigned head;
+- int cleaned = FALSE;
+-
+- tail = readl(adapter->hw.hw_addr + tx_ring->tdt);
+- head = readl(adapter->hw.hw_addr + tx_ring->tdh);
+-
+- if (head != tail) {
+- adapter->stats.tx_hnet++;
+- }
+- if (head != tx_ring->next_to_use) {
+- adapter->stats.tx_hnentu++;
+- }
+- /* Free all the Tx ring sk_buffs from next_to_clean up until
+- * the current head pointer
+- */
+- i = tx_ring->next_to_clean;
+- while(i != head) {
+- cleaned = TRUE;
+- tx_desc = E1000_TX_DESC(*tx_ring, i);
+-
+- buffer_info = &tx_ring->buffer_info[i];
+- iegbe_unmap_and_free_tx_resource(adapter, buffer_info);
+-
+- tx_desc->upper.data = 0;
+-
+- if (unlikely(++i == tx_ring->count)) { i = 0; }
+-
+- }
+- tx_ring->next_to_clean = head;
+-
+- spin_lock(&tx_ring->tx_lock);
+-
+- /* Wake up the queue if it's currently stopped */
+- if (unlikely(cleaned && netif_queue_stopped(netdev) &&
+- netif_carrier_ok(netdev))) {
+- netif_wake_queue(netdev);
++ if(buffer_info->dma) {
++ pci_unmap_page(adapter->pdev,
++ buffer_info->dma,
++ buffer_info->length,
++ PCI_DMA_TODEVICE);
++ buffer_info->dma = 0x0;
++ }
++ if(buffer_info->skb) {
++ dev_kfree_skb_any(buffer_info->skb);
++ buffer_info->skb = NULL;
+ }
+-
+- spin_unlock(&tx_ring->tx_lock);
+ }
+-#endif
++
+
+ /**
+ * iegbe_clean_tx_ring - Free Tx Buffers
+@@ -2134,38 +1914,34 @@ static void iegbe_clean_tx_ring_partial(
+ * @tx_ring: ring to be cleaned
+ **/
+
+-static void
+-iegbe_clean_tx_ring(struct iegbe_adapter *adapter,
++static void iegbe_clean_tx_ring(struct iegbe_adapter *adapter,
+ struct iegbe_tx_ring *tx_ring)
+ {
+- struct iegbe_buffer *buffer_info;
+- unsigned long size;
+- unsigned int i;
+-
+- /* Free all the Tx ring sk_buffs */
++ struct iegbe_hw *hw = &adapter->hw;
++ struct iegbe_buffer *buffer_info;
++ unsigned long size;
++ unsigned int i;
+
+- if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
+- iegbe_unmap_and_free_tx_resource(adapter,
+- &tx_ring->previous_buffer_info);
+- }
++ /* Free all the Tx ring sk_buffs */
+
+ for (i = 0; i < tx_ring->count; i++) {
+- buffer_info = &tx_ring->buffer_info[i];
+- iegbe_unmap_and_free_tx_resource(adapter, buffer_info);
+- }
++ buffer_info = &tx_ring->buffer_info[i];
++ iegbe_unmap_and_free_tx_resource(adapter, buffer_info);
++ }
+
+- size = sizeof(struct iegbe_buffer) * tx_ring->count;
++ size = sizeof(struct iegbe_buffer) * tx_ring->count;
+ memset(tx_ring->buffer_info, 0, size);
+
+- /* Zero out the descriptor ring */
++ /* Zero out the descriptor ring */
+
+ memset(tx_ring->desc, 0, tx_ring->size);
+
+ tx_ring->next_to_use = 0;
+ tx_ring->next_to_clean = 0;
++ tx_ring->last_tx_tso = 0;
+
+- writel(0, adapter->hw.hw_addr + tx_ring->tdh);
+- writel(0, adapter->hw.hw_addr + tx_ring->tdt);
++ writel(0, hw->hw_addr + tx_ring->tdh);
++ writel(0, hw->hw_addr + tx_ring->tdt);
+ }
+
+ /**
+@@ -2173,12 +1949,11 @@ iegbe_clean_tx_ring(struct iegbe_adapter
+ * @adapter: board private structure
+ **/
+
+-static void
+-iegbe_clean_all_tx_rings(struct iegbe_adapter *adapter)
++static void iegbe_clean_all_tx_rings(struct iegbe_adapter *adapter)
+ {
+- int i;
++ int i;
+
+- for (i = 0; i < adapter->num_queues; i++)
++ for (i = 0; i < adapter->num_tx_queues; i++)
+ iegbe_clean_tx_ring(adapter, &adapter->tx_ring[i]);
+ }
+
+@@ -2190,24 +1965,23 @@ iegbe_clean_all_tx_rings(struct iegbe_ad
+ * Free all receive software resources
+ **/
+
+-void
+-iegbe_free_rx_resources(struct iegbe_adapter *adapter,
++static void iegbe_free_rx_resources(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring)
+ {
+- struct pci_dev *pdev = adapter->pdev;
++ struct pci_dev *pdev = adapter->pdev;
+
+- iegbe_clean_rx_ring(adapter, rx_ring);
++ iegbe_clean_rx_ring(adapter, rx_ring);
+
+- vfree(rx_ring->buffer_info);
+- rx_ring->buffer_info = NULL;
+- kfree(rx_ring->ps_page);
+- rx_ring->ps_page = NULL;
+- kfree(rx_ring->ps_page_dma);
+- rx_ring->ps_page_dma = NULL;
++ vfree(rx_ring->buffer_info);
++ rx_ring->buffer_info = NULL;
++ kfree(rx_ring->ps_page);
++ rx_ring->ps_page = NULL;
++ kfree(rx_ring->ps_page_dma);
++ rx_ring->ps_page_dma = NULL;
+
+- pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
++ pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
+
+- rx_ring->desc = NULL;
++ rx_ring->desc = NULL;
+ }
+
+ /**
+@@ -2217,12 +1991,11 @@ iegbe_free_rx_resources(struct iegbe_ada
+ * Free all receive software resources
+ **/
+
+-void
+-iegbe_free_all_rx_resources(struct iegbe_adapter *adapter)
++void iegbe_free_all_rx_resources(struct iegbe_adapter *adapter)
+ {
+- int i;
++ int i;
+
+- for (i = 0; i < adapter->num_queues; i++)
++ for (i = 0; i < adapter->num_rx_queues; i++)
+ iegbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
+ }
+
+@@ -2232,60 +2005,59 @@ iegbe_free_all_rx_resources(struct iegbe
+ * @rx_ring: ring to free buffers from
+ **/
+
+-static void
+-iegbe_clean_rx_ring(struct iegbe_adapter *adapter,
++static void iegbe_clean_rx_ring(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring)
+ {
+- struct iegbe_buffer *buffer_info;
+- struct iegbe_ps_page *ps_page;
+- struct iegbe_ps_page_dma *ps_page_dma;
+- struct pci_dev *pdev = adapter->pdev;
+- unsigned long size;
+- unsigned int i, j;
+-
+- /* Free all the Rx ring sk_buffs */
++ struct iegbe_hw *hw = &adapter->hw;
++ struct iegbe_buffer *buffer_info;
++ struct iegbe_ps_page *ps_page;
++ struct iegbe_ps_page_dma *ps_page_dma;
++ struct pci_dev *pdev = adapter->pdev;
++ unsigned long size;
++ unsigned int i, j;
++
++ /* Free all the Rx ring sk_buffs */
++
++ for (i = 0; i < rx_ring->count; i++) {
++ buffer_info = &rx_ring->buffer_info[i];
++ if(buffer_info->skb) {
++ pci_unmap_single(pdev,
++ buffer_info->dma,
++ buffer_info->length,
++ PCI_DMA_FROMDEVICE);
+
+- for(i = 0; i < rx_ring->count; i++) {
+- buffer_info = &rx_ring->buffer_info[i];
+- if(buffer_info->skb) {
+- ps_page = &rx_ring->ps_page[i];
+- ps_page_dma = &rx_ring->ps_page_dma[i];
+- pci_unmap_single(pdev,
+- buffer_info->dma,
+- buffer_info->length,
+- PCI_DMA_FROMDEVICE);
+-
+- dev_kfree_skb(buffer_info->skb);
+- buffer_info->skb = NULL;
+-
+- for(j = 0; j < adapter->rx_ps_pages; j++) {
+- if(!ps_page->ps_page[j]) { break; }
+- pci_unmap_single(pdev,
+- ps_page_dma->ps_page_dma[j],
+- PAGE_SIZE, PCI_DMA_FROMDEVICE);
+- ps_page_dma->ps_page_dma[j] = 0;
+- put_page(ps_page->ps_page[j]);
+- ps_page->ps_page[j] = NULL;
+- }
++ dev_kfree_skb(buffer_info->skb);
++ buffer_info->skb = NULL;
+ }
+- }
++ ps_page = &rx_ring->ps_page[i];
++ ps_page_dma = &rx_ring->ps_page_dma[i];
++ for (j = 0; j < adapter->rx_ps_pages; j++) {
++ if (!ps_page->ps_page[j]) break;
++ pci_unmap_page(pdev,
++ ps_page_dma->ps_page_dma[j],
++ PAGE_SIZE, PCI_DMA_FROMDEVICE);
++ ps_page_dma->ps_page_dma[j] = 0;
++ put_page(ps_page->ps_page[j]);
++ ps_page->ps_page[j] = NULL;
++ }
++ }
+
+- size = sizeof(struct iegbe_buffer) * rx_ring->count;
++ size = sizeof(struct iegbe_buffer) * rx_ring->count;
+ memset(rx_ring->buffer_info, 0, size);
+- size = sizeof(struct iegbe_ps_page) * rx_ring->count;
++ size = sizeof(struct iegbe_ps_page) * rx_ring->count;
+ memset(rx_ring->ps_page, 0, size);
+- size = sizeof(struct iegbe_ps_page_dma) * rx_ring->count;
++ size = sizeof(struct iegbe_ps_page_dma) * rx_ring->count;
+ memset(rx_ring->ps_page_dma, 0, size);
+
+- /* Zero out the descriptor ring */
++ /* Zero out the descriptor ring */
+
+ memset(rx_ring->desc, 0, rx_ring->size);
+
+ rx_ring->next_to_clean = 0;
+ rx_ring->next_to_use = 0;
+
+- writel(0, adapter->hw.hw_addr + rx_ring->rdh);
+- writel(0, adapter->hw.hw_addr + rx_ring->rdt);
++ writel(0, hw->hw_addr + rx_ring->rdh);
++ writel(0, hw->hw_addr + rx_ring->rdt);
+ }
+
+ /**
+@@ -2293,60 +2065,54 @@ iegbe_clean_rx_ring(struct iegbe_adapter
+ * @adapter: board private structure
+ **/
+
+-static void
+-iegbe_clean_all_rx_rings(struct iegbe_adapter *adapter)
++static void iegbe_clean_all_rx_rings(struct iegbe_adapter *adapter)
+ {
+- int i;
++ int i;
+
+- for (i = 0; i < adapter->num_queues; i++)
++ for (i = 0; i < adapter->num_rx_queues; i++)
+ iegbe_clean_rx_ring(adapter, &adapter->rx_ring[i]);
+ }
+
+ /* The 82542 2.0 (revision 2) needs to have the receive unit in reset
+ * and memory write and invalidate disabled for certain operations
+ */
+-static void
+-iegbe_enter_82542_rst(struct iegbe_adapter *adapter)
++static void iegbe_enter_82542_rst(struct iegbe_adapter *adapter)
+ {
+- struct net_device *netdev = adapter->netdev;
+- uint32_t rctl;
++ struct net_device *netdev = adapter->netdev;
++ uint32_t rctl;
+
+- iegbe_pci_clear_mwi(&adapter->hw);
++ iegbe_pci_clear_mwi(&adapter->hw);
+
+- rctl = E1000_READ_REG(&adapter->hw, RCTL);
+- rctl |= E1000_RCTL_RST;
+- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+- E1000_WRITE_FLUSH(&adapter->hw);
++ rctl = E1000_READ_REG(&adapter->hw, RCTL);
++ rctl |= E1000_RCTL_RST;
++ E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
++ E1000_WRITE_FLUSH(&adapter->hw);
+ mdelay(0x5);
+
+ if(netif_running(netdev)) {
+- iegbe_clean_all_rx_rings(adapter);
+-}
++ iegbe_clean_all_rx_rings(adapter);
++ }
+ }
+
+ static void
+ iegbe_leave_82542_rst(struct iegbe_adapter *adapter)
+ {
+- struct net_device *netdev = adapter->netdev;
+- uint32_t rctl;
++ struct net_device *netdev = adapter->netdev;
++ uint32_t rctl;
+
+- rctl = E1000_READ_REG(&adapter->hw, RCTL);
+- rctl &= ~E1000_RCTL_RST;
+- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+- E1000_WRITE_FLUSH(&adapter->hw);
++ rctl = E1000_READ_REG(&adapter->hw, RCTL);
++ rctl &= ~E1000_RCTL_RST;
++ E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
++ E1000_WRITE_FLUSH(&adapter->hw);
+ mdelay(0x5);
+
+ if(adapter->hw.pci_cmd_word & PCI_COMMAND_INVALIDATE) {
+- iegbe_pci_set_mwi(&adapter->hw);
++ iegbe_pci_set_mwi(&adapter->hw);
+ }
+ if(netif_running(netdev)) {
++ struct iegbe_rx_ring *ring = &adapter->rx_ring[0x0];
+ iegbe_configure_rx(adapter);
+-#ifdef IEGBE_GBE_WORKAROUND
+- iegbe_alloc_rx_buffers(adapter, &adapter->rx_ring[0],
+- IEGBE_GBE_WORKAROUND_NUM_RX_DESCRIPTORS + 1);
+-#else
+- iegbe_alloc_rx_buffers(adapter, &adapter->rx_ring[0]);
+-#endif
++ adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
+ }
+ }
+
+@@ -2358,133 +2124,153 @@ iegbe_leave_82542_rst(struct iegbe_adapt
+ * Returns 0 on success, negative on failure
+ **/
+
+-static int
+-iegbe_set_mac(struct net_device *netdev, void *p)
++static int iegbe_set_mac(struct net_device *netdev, void *p)
+ {
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+- struct sockaddr *addr = p;
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct sockaddr *addr = p;
+
+ if(!is_valid_ether_addr(addr->sa_data)) {
+- return -EADDRNOTAVAIL;
++ return -EADDRNOTAVAIL;
+ }
+- /* 82542 2.0 needs to be in reset to write receive address registers */
++ /* 82542 2.0 needs to be in reset to write receive address registers */
+
+ if(adapter->hw.mac_type == iegbe_82542_rev2_0) {
+- iegbe_enter_82542_rst(adapter);
++ iegbe_enter_82542_rst(adapter);
+ }
+- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+- memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
++ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
++ memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+
+- iegbe_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
++ iegbe_rar_set(&adapter->hw, adapter->hw.mac_addr, 0x0);
+
+- /* With 82571 controllers, LAA may be overwritten (with the default)
+- * due to controller reset from the other port. */
+- if (adapter->hw.mac_type == iegbe_82571) {
+- /* activate the work around */
++ /* With 82571 controllers, LAA may be overwritten (with the default)
++ * due to controller reset from the other port. */
++ if (adapter->hw.mac_type == iegbe_82571) {
++ /* activate the work around */
+ adapter->hw.laa_is_present = 0x1;
+
+- /* Hold a copy of the LAA in RAR[14] This is done so that
+- * between the time RAR[0] gets clobbered and the time it
+- * gets fixed (in iegbe_watchdog), the actual LAA is in one
+- * of the RARs and no incoming packets directed to this port
+- * are dropped. Eventaully the LAA will be in RAR[0] and
+- * RAR[14] */
+- iegbe_rar_set(&adapter->hw, adapter->hw.mac_addr,
++ /* Hold a copy of the LAA in RAR[14] This is done so that
++ * between the time RAR[0] gets clobbered and the time it
++ * gets fixed (in iegbe_watchdog), the actual LAA is in one
++ * of the RARs and no incoming packets directed to this port
++ * are dropped. Eventaully the LAA will be in RAR[0] and
++ * RAR[14] */
++ iegbe_rar_set(&adapter->hw, adapter->hw.mac_addr,
+ E1000_RAR_ENTRIES - 0x1);
+- }
++ }
+
+ if(adapter->hw.mac_type == iegbe_82542_rev2_0) {
+- iegbe_leave_82542_rst(adapter);
++ iegbe_leave_82542_rst(adapter);
+ }
+- return 0;
++ return 0x0;
+ }
+
+ /**
+- * iegbe_set_multi - Multicast and Promiscuous mode set
++ * iegbe_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+- * The set_multi entry point is called whenever the multicast address
+- * list or the network interface flags are updated. This routine is
+- * responsible for configuring the hardware for proper multicast,
++ * The set_rx_mode entry point is called whenever the unicast or multicast
++ * address lists or the network interface flags are updated. This routine is
++ * responsible for configuring the hardware for proper unicast, multicast,
+ * promiscuous mode, and all-multi behavior.
+ **/
+
+-static void
+-iegbe_set_multi(struct net_device *netdev)
++static void iegbe_set_rx_mode(struct net_device *netdev)
+ {
+ struct iegbe_adapter *adapter = netdev_priv(netdev);
+ struct iegbe_hw *hw = &adapter->hw;
+- struct dev_mc_list *mc_ptr;
+- uint32_t rctl;
+- uint32_t hash_value;
++ struct dev_addr_list *uc_ptr;
++ struct dev_addr_list *mc_ptr;
++ u32 rctl;
++ u32 hash_value;
+ int i, rar_entries = E1000_RAR_ENTRIES;
++int mta_reg_count = E1000_NUM_MTA_REGISTERS;
+
+ /* reserve RAR[14] for LAA over-write work-around */
+- if (adapter->hw.mac_type == iegbe_82571) {
++ if (hw->mac_type == iegbe_82571)
+ rar_entries--;
+- }
++
+ /* Check for Promiscuous and All Multicast modes */
+
+- rctl = E1000_READ_REG(hw, RCTL);
++ rctl = E1000_READ_REG(&adapter->hw, RCTL);
+
+ if (netdev->flags & IFF_PROMISC) {
+ rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
+- } else if (netdev->flags & IFF_ALLMULTI) {
+- rctl |= E1000_RCTL_MPE;
+- rctl &= ~E1000_RCTL_UPE;
++ rctl &= ~E1000_RCTL_VFE;
+ } else {
+- rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
++ if (netdev->flags & IFF_ALLMULTI) {
++ rctl |= E1000_RCTL_MPE;
++ } else {
++ rctl &= ~E1000_RCTL_MPE;
++ }
++ }
++
++ uc_ptr = NULL;
++ if (netdev->uc_count > rar_entries - 1) {
++ rctl |= E1000_RCTL_UPE;
++ } else if (!(netdev->flags & IFF_PROMISC)) {
++ rctl &= ~E1000_RCTL_UPE;
++ uc_ptr = netdev->uc_list;
+ }
+
+- E1000_WRITE_REG(hw, RCTL, rctl);
++ E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+
+ /* 82542 2.0 needs to be in reset to write receive address registers */
+
+- if (hw->mac_type == iegbe_82542_rev2_0) {
++ if (hw->mac_type == iegbe_82542_rev2_0)
+ iegbe_enter_82542_rst(adapter);
+- }
+- /* load the first 14 multicast address into the exact filters 1-14
++
++ /* load the first 14 addresses into the exact filters 1-14. Unicast
++ * addresses take precedence to avoid disabling unicast filtering
++ * when possible.
++ *
+ * RAR 0 is used for the station MAC adddress
+ * if there are not 14 addresses, go ahead and clear the filters
+ * -- with 82571 controllers only 0-13 entries are filled here
+ */
+ mc_ptr = netdev->mc_list;
+
+- for (i = 0x1; i < rar_entries; i++) {
+- if (mc_ptr) {
+- iegbe_rar_set(hw, mc_ptr->dmi_addr, i);
++ for (i = 1; i < rar_entries; i++) {
++ if (uc_ptr) {
++ iegbe_rar_set(hw, uc_ptr->da_addr, i);
++ uc_ptr = uc_ptr->next;
++ } else if (mc_ptr) {
++ iegbe_rar_set(hw, mc_ptr->da_addr, i);
+ mc_ptr = mc_ptr->next;
+ } else {
+- E1000_WRITE_REG_ARRAY(hw, RA, i << 0x1, 0);
+- E1000_WRITE_REG_ARRAY(hw, RA, (i << 0x1) + 0x1, 0);
++ E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
++ E1000_WRITE_FLUSH(&adapter->hw);
++ E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
++ E1000_WRITE_FLUSH(&adapter->hw);
+ }
+ }
++ WARN_ON(uc_ptr != NULL);
+
+ /* clear the old settings from the multicast hash table */
+
+- for (i = 0; i < E1000_NUM_MTA_REGISTERS; i++)
++ for (i = 0; i < mta_reg_count; i++) {
+ E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
++ E1000_WRITE_FLUSH(&adapter->hw);
++ }
+
+ /* load any remaining addresses into the hash table */
+
+ for (; mc_ptr; mc_ptr = mc_ptr->next) {
+- hash_value = iegbe_hash_mc_addr(hw, mc_ptr->dmi_addr);
++ hash_value = iegbe_hash_mc_addr(hw, mc_ptr->da_addr);
+ iegbe_mta_set(hw, hash_value);
+ }
+
+- if (hw->mac_type == iegbe_82542_rev2_0) {
++ if (hw->mac_type == iegbe_82542_rev2_0)
+ iegbe_leave_82542_rst(adapter);
+ }
+-}
+
+ /* Need to wait a few seconds after link up to get diagnostic information from
+ * the phy */
+
+-static void
+-iegbe_update_phy_info(unsigned long data)
++static void iegbe_update_phy_info(unsigned long data)
+ {
+- struct iegbe_adapter *adapter = (struct iegbe_adapter *) data;
+- iegbe_phy_get_info(&adapter->hw, &adapter->phy_info);
++ struct iegbe_adapter *adapter = (struct iegbe_adapter *) data;
++ struct iegbe_hw *hw = &adapter->hw;
++ iegbe_phy_get_info(hw, &adapter->phy_info);
+ }
+
+ /**
+@@ -2492,54 +2278,54 @@ iegbe_update_phy_info(unsigned long data
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+
+-static void
+-iegbe_82547_tx_fifo_stall(unsigned long data)
++static void iegbe_82547_tx_fifo_stall(unsigned long data)
+ {
+- struct iegbe_adapter *adapter = (struct iegbe_adapter *) data;
+- struct net_device *netdev = adapter->netdev;
+- uint32_t tctl;
++ struct iegbe_adapter *adapter = (struct iegbe_adapter *) data;
++ struct net_device *netdev = adapter->netdev;
++ u32 tctl;
+
+- if(atomic_read(&adapter->tx_fifo_stall)) {
+- if((E1000_READ_REG(&adapter->hw, TDT) ==
+- E1000_READ_REG(&adapter->hw, TDH)) &&
+- (E1000_READ_REG(&adapter->hw, TDFT) ==
+- E1000_READ_REG(&adapter->hw, TDFH)) &&
+- (E1000_READ_REG(&adapter->hw, TDFTS) ==
+- E1000_READ_REG(&adapter->hw, TDFHS))) {
+- tctl = E1000_READ_REG(&adapter->hw, TCTL);
+- E1000_WRITE_REG(&adapter->hw, TCTL,
+- tctl & ~E1000_TCTL_EN);
+- E1000_WRITE_REG(&adapter->hw, TDFT,
+- adapter->tx_head_addr);
+- E1000_WRITE_REG(&adapter->hw, TDFH,
+- adapter->tx_head_addr);
+- E1000_WRITE_REG(&adapter->hw, TDFTS,
+- adapter->tx_head_addr);
+- E1000_WRITE_REG(&adapter->hw, TDFHS,
+- adapter->tx_head_addr);
+- E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
+- E1000_WRITE_FLUSH(&adapter->hw);
+-
+- adapter->tx_fifo_head = 0;
+- atomic_set(&adapter->tx_fifo_stall, 0);
+- netif_wake_queue(netdev);
+- } else {
++ if(atomic_read(&adapter->tx_fifo_stall)) {
++ if((E1000_READ_REG(&adapter->hw, TDT) ==
++ E1000_READ_REG(&adapter->hw, TDH)) &&
++ (E1000_READ_REG(&adapter->hw, TDFT) ==
++ E1000_READ_REG(&adapter->hw, TDFH)) &&
++ (E1000_READ_REG(&adapter->hw, TDFTS) ==
++ E1000_READ_REG(&adapter->hw, TDFHS))) {
++ tctl = E1000_READ_REG(&adapter->hw, TCTL);
++ E1000_WRITE_REG(&adapter->hw, TCTL,
++ tctl & ~E1000_TCTL_EN);
++ E1000_WRITE_REG(&adapter->hw, TDFT,
++ adapter->tx_head_addr);
++ E1000_WRITE_REG(&adapter->hw, TDFH,
++ adapter->tx_head_addr);
++ E1000_WRITE_REG(&adapter->hw, TDFTS,
++ adapter->tx_head_addr);
++ E1000_WRITE_REG(&adapter->hw, TDFHS,
++ adapter->tx_head_addr);
++ E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
++ E1000_WRITE_FLUSH(&adapter->hw);
++
++ adapter->tx_fifo_head = 0x0;
++ atomic_set(&adapter->tx_fifo_stall, 0x0);
++ netif_wake_queue(netdev);
++ } else {
+ mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 0x1);
+- }
+- }
++ }
++ }
+ }
+
++
+ /**
+ * iegbe_watchdog - Timer Call-back
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+-static void
+-iegbe_watchdog(unsigned long data)
++static void iegbe_watchdog(unsigned long data)
+ {
+- struct iegbe_adapter *adapter = (struct iegbe_adapter *) data;
+- struct net_device *netdev = adapter->netdev;
+- struct iegbe_tx_ring *txdr = &adapter->tx_ring[0];
+- uint32_t link;
++ struct iegbe_adapter *adapter = (struct iegbe_adapter *) data;
++ struct iegbe_hw *hw = &adapter->hw;
++ struct net_device *netdev = adapter->netdev;
++ struct iegbe_tx_ring *txdr = adapter->tx_ring;
++ u32 link, tctl;
+
+ /*
+ * Test the PHY for link status on icp_xxxx MACs.
+@@ -2547,123 +2333,305 @@ iegbe_watchdog(unsigned long data)
+ * in the adapter->hw structure, then set hw->get_link_status = 1
+ */
+ if(adapter->hw.mac_type == iegbe_icp_xxxx) {
+- int isUp = 0;
++ int isUp = 0x0;
+ int32_t ret_val;
+
+ ret_val = iegbe_oem_phy_is_link_up(&adapter->hw, &isUp);
+ if(ret_val != E1000_SUCCESS) {
+- isUp = 0;
+- }
++ isUp = 0x0;
++ }
+ if(isUp != adapter->hw.icp_xxxx_is_link_up) {
+ adapter->hw.get_link_status = 0x1;
+ }
+ }
+
+- iegbe_check_for_link(&adapter->hw);
+- if (adapter->hw.mac_type == iegbe_82573) {
+- iegbe_enable_tx_pkt_filtering(&adapter->hw);
++ iegbe_check_for_link(&adapter->hw);
++ if (adapter->hw.mac_type == iegbe_82573) {
++ iegbe_enable_tx_pkt_filtering(&adapter->hw);
+ #ifdef NETIF_F_HW_VLAN_TX
+ if (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id) {
+- iegbe_update_mng_vlan(adapter);
++ iegbe_update_mng_vlan(adapter);
+ }
+ #endif
+- }
++ }
+
+- if ((adapter->hw.media_type == iegbe_media_type_internal_serdes) &&
+- !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE)) {
+- link = !adapter->hw.serdes_link_down;
+- } else {
++ if ((adapter->hw.media_type == iegbe_media_type_internal_serdes) &&
++ !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE)) {
++ link = !adapter->hw.serdes_link_down;
++ } else {
+
+- if(adapter->hw.mac_type != iegbe_icp_xxxx) {
+- link = E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU;
+- } else {
+- int isUp = 0;
++ if(adapter->hw.mac_type != iegbe_icp_xxxx) {
++ link = E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU;
++ } else {
++ int isUp = 0x0;
+ if(iegbe_oem_phy_is_link_up(&adapter->hw, &isUp) != E1000_SUCCESS) {
+- isUp = 0;
++ isUp = 0x0;
+ }
+- link = isUp;
+- }
+- }
++ link = isUp;
++ }
++ }
+
+- if (link) {
+- if (!netif_carrier_ok(netdev)) {
+- iegbe_get_speed_and_duplex(&adapter->hw,
+- &adapter->link_speed,
+- &adapter->link_duplex);
+-
+- DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s\n",
+- adapter->link_speed,
+- adapter->link_duplex == FULL_DUPLEX ?
+- "Full Duplex" : "Half Duplex");
++ if (link) {
++ if (!netif_carrier_ok(netdev)) {
++ u32 ctrl;
++ bool txb2b = true;
++ iegbe_get_speed_and_duplex(hw,
++ &adapter->link_speed,
++ &adapter->link_duplex);
+
+- netif_carrier_on(netdev);
+- netif_wake_queue(netdev);
+- mod_timer(&adapter->phy_info_timer, jiffies + 0x2 * HZ);
++ ctrl = E1000_READ_REG(&adapter->hw, CTRL);
++ DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s, "
++ "Flow Control: %s\n",
++ adapter->link_speed,
++ adapter->link_duplex == FULL_DUPLEX ?
++ "Full Duplex" : "Half Duplex",
++ ((ctrl & E1000_CTRL_TFCE) && (ctrl &
++ E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
++ E1000_CTRL_RFCE) ? "RX" : ((ctrl &
++ E1000_CTRL_TFCE) ? "TX" : "None" )));
++
++ /* tweak tx_queue_len according to speed/duplex
++ * and adjust the timeout factor */
++ netdev->tx_queue_len = adapter->tx_queue_len;
++ adapter->tx_timeout_factor = 1;
++ switch (adapter->link_speed) {
++ case SPEED_10:
++ txb2b = false;
++ netdev->tx_queue_len = 10;
++ adapter->tx_timeout_factor = 8;
++ break;
++ case SPEED_100:
++ txb2b = false;
++ netdev->tx_queue_len = 100;
++ break;
++ }
++ if ((hw->mac_type == iegbe_82571 ||
++ hw->mac_type == iegbe_82572) &&
++ !txb2b) {
++ u32 tarc0;
++ tarc0 = E1000_READ_REG(&adapter->hw, TARC0);
++ tarc0 &= ~(1 << 21);
++ E1000_WRITE_REG(&adapter->hw, TARC0, tarc0);
++ }
++ /* disable TSO for pcie and 10/100 speeds, to avoid
++ * some hardware issues */
++ if (!adapter->tso_force &&
++ hw->bus_type == iegbe_bus_type_pci_express){
++ switch (adapter->link_speed) {
++ case SPEED_10:
++ case SPEED_100:
++ DPRINTK(PROBE,INFO,
++ "10/100 speed: disabling TSO\n");
++ netdev->features &= ~NETIF_F_TSO;
++ netdev->features &= ~NETIF_F_TSO6;
++ break;
++ case SPEED_1000:
++ netdev->features |= NETIF_F_TSO;
++ netdev->features |= NETIF_F_TSO6;
++ break;
++ default:
++ break;
++ }
++ }
++ tctl = E1000_READ_REG(&adapter->hw, TCTL);
++ tctl |= E1000_TCTL_EN;
++ E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
++ netif_carrier_on(netdev);
++ netif_wake_queue(netdev);
++ mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
+ adapter->smartspeed = 0;
++ } else {
++ if (hw->rx_needs_kicking) {
++ u32 rctl = E1000_READ_REG(&adapter->hw, RCTL);
++ E1000_WRITE_REG(&adapter->hw, RCTL, rctl | E1000_RCTL_EN);
++ }
+ }
+- } else {
+- if (netif_carrier_ok(netdev)) {
++ } else {
++ if (netif_carrier_ok(netdev)) {
+ adapter->link_speed = 0;
+ adapter->link_duplex = 0;
+- DPRINTK(LINK, INFO, "NIC Link is Down\n");
+- netif_carrier_off(netdev);
+- netif_stop_queue(netdev);
+- mod_timer(&adapter->phy_info_timer, jiffies + 0x2 * HZ);
+- }
++ DPRINTK(LINK, INFO, "NIC Link is Down\n");
++ netif_carrier_off(netdev);
++ netif_stop_queue(netdev);
++ mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
++ }
+
+- iegbe_smartspeed(adapter);
+- }
++ iegbe_smartspeed(adapter);
++ }
++
++ iegbe_update_stats(adapter);
++
++ hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
++ adapter->tpt_old = adapter->stats.tpt;
++ hw->collision_delta = adapter->stats.colc - adapter->colc_old;
++ adapter->colc_old = adapter->stats.colc;
++
++ adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
++ adapter->gorcl_old = adapter->stats.gorcl;
++ adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
++ adapter->gotcl_old = adapter->stats.gotcl;
++
++ iegbe_update_adaptive(hw);
++
++ if (!netif_carrier_ok(netdev)) {
++ if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
++ /* We've lost link, so the controller stops DMA,
++ * but we've got queued Tx work that's never going
++ * to get done, so reset controller to flush Tx.
++ * (Do the reset outside of interrupt context). */
++ adapter->tx_timeout_count++;
++ schedule_work(&adapter->reset_task);
++ }
++ }
++
++ /* Cause software interrupt to ensure rx ring is cleaned */
++ E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0);
++
++ /* Force detection of hung controller every watchdog period */
++ adapter->detect_tx_hung = TRUE;
++
++ /* With 82571 controllers, LAA may be overwritten due to controller
++ * reset from the other port. Set the appropriate LAA in RAR[0] */
++ if (adapter->hw.mac_type == iegbe_82571 && adapter->hw.laa_is_present) {
++ iegbe_rar_set(&adapter->hw, adapter->hw.mac_addr, 0x0);
++ }
++ /* Reset the timer */
++ mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
++}
++
++enum latency_range {
++ lowest_latency = 0,
++ low_latency = 1,
++ bulk_latency = 2,
++ latency_invalid = 255
++};
+
+- iegbe_update_stats(adapter);
++/**
++ * iegbe_update_itr - update the dynamic ITR value based on statistics
++ * Stores a new ITR value based on packets and byte
++ * counts during the last interrupt. The advantage of per interrupt
++ * computation is faster updates and more accurate ITR for the current
++ * traffic pattern. Constants in this function were computed
++ * based on theoretical maximum wire speed and thresholds were set based
++ * on testing data as well as attempting to minimize response time
++ * while increasing bulk throughput.
++ * this functionality is controlled by the InterruptThrottleRate module
++ * parameter (see iegbe_param.c)
++ * @adapter: pointer to adapter
++ * @itr_setting: current adapter->itr
++ * @packets: the number of packets during this measurement interval
++ * @bytes: the number of bytes during this measurement interval
++ **/
++static unsigned int iegbe_update_itr(struct iegbe_adapter *adapter,
++ u16 itr_setting, int packets, int bytes)
++{
++ unsigned int retval = itr_setting;
++ struct iegbe_hw *hw = &adapter->hw;
+
+- adapter->hw.tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
+- adapter->tpt_old = adapter->stats.tpt;
+- adapter->hw.collision_delta = adapter->stats.colc - adapter->colc_old;
+- adapter->colc_old = adapter->stats.colc;
+-
+- adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
+- adapter->gorcl_old = adapter->stats.gorcl;
+- adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
+- adapter->gotcl_old = adapter->stats.gotcl;
+-
+- iegbe_update_adaptive(&adapter->hw);
+-
+- if (adapter->num_queues == 0x1 && !netif_carrier_ok(netdev)) {
+- if (E1000_DESC_UNUSED(txdr) + 0x1 < txdr->count) {
+- /* We've lost link, so the controller stops DMA,
+- * but we've got queued Tx work that's never going
+- * to get done, so reset controller to flush Tx.
+- * (Do the reset outside of interrupt context). */
+- schedule_work(&adapter->tx_timeout_task);
++ if (unlikely(hw->mac_type < iegbe_82540))
++ goto update_itr_done;
++
++ if (packets == 0)
++ goto update_itr_done;
++
++ switch (itr_setting) {
++ case lowest_latency:
++ /* jumbo frames get bulk treatment*/
++ if (bytes/packets > 8000)
++ retval = bulk_latency;
++ else if ((packets < 5) && (bytes > 512))
++ retval = low_latency;
++ break;
++ case low_latency: /* 50 usec aka 20000 ints/s */
++ if (bytes > 10000) {
++ /* jumbo frames need bulk latency setting */
++ if (bytes/packets > 8000)
++ retval = bulk_latency;
++ else if ((packets < 10) || ((bytes/packets) > 1200))
++ retval = bulk_latency;
++ else if ((packets > 35))
++ retval = lowest_latency;
++ } else if (bytes/packets > 2000)
++ retval = bulk_latency;
++ else if (packets <= 2 && bytes < 512)
++ retval = lowest_latency;
++ break;
++ case bulk_latency: /* 250 usec aka 4000 ints/s */
++ if (bytes > 25000) {
++ if (packets > 35)
++ retval = low_latency;
++ } else if (bytes < 6000) {
++ retval = low_latency;
+ }
++ break;
+ }
+
+- /* Dynamic mode for Interrupt Throttle Rate (ITR) */
+- if (adapter->hw.mac_type >= iegbe_82540 && adapter->itr == 0x1) {
+- /* Symmetric Tx/Rx gets a reduced ITR=2000; Total
+- * asymmetrical Tx or Rx gets ITR=8000; everyone
+- * else is between 2000-8000. */
+- uint32_t goc = (adapter->gotcl + adapter->gorcl) / 0x2710;
+- uint32_t dif = (adapter->gotcl > adapter->gorcl ?
+- adapter->gotcl - adapter->gorcl :
+- adapter->gorcl - adapter->gotcl) / 0x2710;
+- uint32_t itr = goc > 0 ? (dif * 0x1770 / goc + 0x7d0) : 0x1f40;
+- E1000_WRITE_REG(&adapter->hw, ITR, 0x3b9aca00 / (itr * 0x100));
+- }
++update_itr_done:
++ return retval;
++}
+
+- /* Cause software interrupt to ensure rx ring is cleaned */
+- E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0);
++static void iegbe_set_itr(struct iegbe_adapter *adapter)
++{
++ struct iegbe_hw *hw = &adapter->hw;
++ u16 current_itr;
++ u32 new_itr = adapter->itr;
+
+- /* Force detection of hung controller every watchdog period */
+- adapter->detect_tx_hung = TRUE;
++ if (unlikely(hw->mac_type < iegbe_82540))
++ return;
+
+- /* With 82571 controllers, LAA may be overwritten due to controller
+- * reset from the other port. Set the appropriate LAA in RAR[0] */
+- if (adapter->hw.mac_type == iegbe_82571 && adapter->hw.laa_is_present) {
+- iegbe_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
+- }
+- /* Reset the timer */
+- mod_timer(&adapter->watchdog_timer, jiffies + 0x2 * HZ);
++ /* for non-gigabit speeds, just fix the interrupt rate at 4000 */
++ if (unlikely(adapter->link_speed != SPEED_1000)) {
++ current_itr = 0;
++ new_itr = 4000;
++ goto set_itr_now;
++ }
++
++ adapter->tx_itr = iegbe_update_itr(adapter,
++ adapter->tx_itr,
++ adapter->total_tx_packets,
++ adapter->total_tx_bytes);
++ /* conservative mode (itr 3) eliminates the lowest_latency setting */
++ if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
++ adapter->tx_itr = low_latency;
++
++ adapter->rx_itr = iegbe_update_itr(adapter,
++ adapter->rx_itr,
++ adapter->total_rx_packets,
++ adapter->total_rx_bytes);
++ /* conservative mode (itr 3) eliminates the lowest_latency setting */
++ if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
++ adapter->rx_itr = low_latency;
++
++ current_itr = max(adapter->rx_itr, adapter->tx_itr);
++
++ switch (current_itr) {
++ /* counts and packets in update_itr are dependent on these numbers */
++ case lowest_latency:
++ new_itr = 70000;
++ break;
++ case low_latency:
++ new_itr = 20000; /* aka hwitr = ~200 */
++ break;
++ case bulk_latency:
++ new_itr = 4000;
++ break;
++ default:
++ break;
++ }
++
++set_itr_now:
++ if (new_itr != adapter->itr) {
++ /* this attempts to bias the interrupt rate towards Bulk
++ * by adding intermediate steps when interrupt rate is
++ * increasing */
++ new_itr = new_itr > adapter->itr ?
++ min(adapter->itr + (new_itr >> 2), new_itr) :
++ new_itr;
++ adapter->itr = new_itr;
++ E1000_WRITE_REG(&adapter->hw, ITR, 1000000000 / (new_itr * 256));
++ }
++
++ return;
+ }
+
+ #define E1000_TX_FLAGS_CSUM 0x00000001
+@@ -2673,55 +2641,48 @@ iegbe_watchdog(unsigned long data)
+ #define E1000_TX_FLAGS_VLAN_MASK 0xffff0000
+ #define E1000_TX_FLAGS_VLAN_SHIFT 16
+
+-static inline int
+-iegbe_tso(struct iegbe_adapter *adapter, struct iegbe_tx_ring *tx_ring,
+- struct sk_buff *skb)
++static int iegbe_tso(struct iegbe_adapter *adapter,
++ struct iegbe_tx_ring *tx_ring, struct sk_buff *skb)
+ {
+-#ifdef NETIF_F_TSO
+ struct iegbe_context_desc *context_desc;
++ struct iegbe_buffer *buffer_info;
+ unsigned int i;
+- uint32_t cmd_length = 0;
+- uint16_t ipcse = 0, tucse, mss;
+- uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
++ u32 cmd_length = 0;
++ u16 ipcse = 0, tucse, mss;
++ u8 ipcss, ipcso, tucss, tucso, hdr_len;
+ int err;
+
+ if (skb_is_gso(skb)) {
+ if (skb_header_cloned(skb)) {
+ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+- if (err) {
++ if (err)
+ return err;
+ }
+- }
+
+- hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 0x2));
++ hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ mss = skb_shinfo(skb)->gso_size;
+ if (skb->protocol == htons(ETH_P_IP)) {
+- skb->nh.iph->tot_len = 0;
+- skb->nh.iph->check = 0;
+- skb->h.th->check =
+- ~csum_tcpudp_magic(skb->nh.iph->saddr,
+- skb->nh.iph->daddr,
+- 0,
+- IPPROTO_TCP,
+- 0);
++ struct iphdr *iph = ip_hdr(skb);
++ iph->tot_len = 0;
++ iph->check = 0;
++ tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
++ iph->daddr, 0,
++ IPPROTO_TCP,
++ 0);
+ cmd_length = E1000_TXD_CMD_IP;
+- ipcse = skb->h.raw - skb->data - 0x1;
+-#ifdef NETIF_F_TSO_IPV6
+- } else if (skb->protocol == ntohs(ETH_P_IPV6)) {
+- skb->nh.ipv6h->payload_len = 0;
+- skb->h.th->check =
+- ~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
+- &skb->nh.ipv6h->daddr,
+- 0,
+- IPPROTO_TCP,
+- 0);
++ ipcse = skb_transport_offset(skb) - 1;
++ } else if (skb->protocol == htons(ETH_P_IPV6)) {
++ 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);
+ ipcse = 0;
+-#endif
+ }
+- ipcss = skb->nh.raw - skb->data;
+- ipcso = (void *)&(skb->nh.iph->check) - (void *)skb->data;
+- tucss = skb->h.raw - skb->data;
+- tucso = (void *)&(skb->h.th->check) - (void *)skb->data;
++ ipcss = skb_network_offset(skb);
++ ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
++ tucss = skb_transport_offset(skb);
++ tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
+ tucse = 0;
+
+ cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
+@@ -2729,6 +2690,7 @@ iegbe_tso(struct iegbe_adapter *adapter,
+
+ i = tx_ring->next_to_use;
+ context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
++ buffer_info = &tx_ring->buffer_info[i];
+
+ context_desc->lower_setup.ip_fields.ipcss = ipcss;
+ context_desc->lower_setup.ip_fields.ipcso = ipcso;
+@@ -2740,205 +2702,218 @@ iegbe_tso(struct iegbe_adapter *adapter,
+ context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
+ context_desc->cmd_and_length = cpu_to_le32(cmd_length);
+
+- if (++i == tx_ring->count) { i = 0; }
++ buffer_info->time_stamp = jiffies;
++ buffer_info->next_to_watch = i;
++
++ if (++i == tx_ring->count) i = 0;
+ tx_ring->next_to_use = i;
+
+- return TRUE;
++ return true;
+ }
+-#endif
+-
+- return FALSE;
++ return false;
+ }
+
+-static inline boolean_t
+-iegbe_tx_csum(struct iegbe_adapter *adapter, struct iegbe_tx_ring *tx_ring,
+- struct sk_buff *skb)
++static bool iegbe_tx_csum(struct iegbe_adapter *adapter,
++ struct iegbe_tx_ring *tx_ring, struct sk_buff *skb)
+ {
+ struct iegbe_context_desc *context_desc;
++ struct iegbe_buffer *buffer_info;
+ unsigned int i;
+- uint8_t css;
++ u8 css;
+
+- if (likely(skb->ip_summed == CHECKSUM_HW)) {
+- css = skb->h.raw - skb->data;
++ if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
++ css = skb_transport_offset(skb);
+
+- i = tx_ring->next_to_use;
+- context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
++ i = tx_ring->next_to_use;
++ buffer_info = &tx_ring->buffer_info[i];
++ context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
+
++ context_desc->lower_setup.ip_config = 0;
+ context_desc->upper_setup.tcp_fields.tucss = css;
+- context_desc->upper_setup.tcp_fields.tucso = css + skb->csum;
++ context_desc->upper_setup.tcp_fields.tucso =
++ css + skb->csum_offset;
+ context_desc->upper_setup.tcp_fields.tucse = 0;
+ context_desc->tcp_seg_setup.data = 0;
+ context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
+
+- if (unlikely(++i == tx_ring->count)) { i = 0; }
++ buffer_info->time_stamp = jiffies;
++ buffer_info->next_to_watch = i;
++
++ if (unlikely(++i == tx_ring->count)) i = 0;
+ tx_ring->next_to_use = i;
+
+- return TRUE;
++ return true;
+ }
+
+- return FALSE;
++ return false;
+ }
+
+-#define E1000_MAX_TXD_PWR 12
+-#define E1000_MAX_DATA_PER_TXD (1<<E1000_MAX_TXD_PWR)
++#define E1000_MAX_TXD_PWR 12
++#define E1000_MAX_DATA_PER_TXD (1<<E1000_MAX_TXD_PWR)
+
+-static inline int
+-iegbe_tx_map(struct iegbe_adapter *adapter, struct iegbe_tx_ring *tx_ring,
+- struct sk_buff *skb, unsigned int first, unsigned int max_per_txd,
+- unsigned int nr_frags, unsigned int mss)
++static int iegbe_tx_map(struct iegbe_adapter *adapter,
++ struct iegbe_tx_ring *tx_ring,
++ struct sk_buff *skb, unsigned int first,
++ unsigned int max_per_txd, unsigned int nr_frags,
++ unsigned int mss)
+ {
+- struct iegbe_buffer *buffer_info;
+- unsigned int len = skb->len;
++ struct iegbe_hw *hw = &adapter->hw;
++ struct iegbe_buffer *buffer_info;
++ unsigned int len = skb->len;
+ unsigned int offset = 0, size, count = 0, i;
+-#ifdef MAX_SKB_FRAGS
+- unsigned int f;
+- len -= skb->data_len;
+-#endif
++ unsigned int f;
++ len -= skb->data_len;
+
+- i = tx_ring->next_to_use;
++ i = tx_ring->next_to_use;
++
++ while(len) {
++ buffer_info = &tx_ring->buffer_info[i];
++ size = min(len, max_per_txd);
++ /* Workaround for Controller erratum --
++ * descriptor for non-tso packet in a linear SKB that follows a
++ * tso gets written back prematurely before the data is fully
++ * DMA'd to the controller */
++ if (!skb->data_len && tx_ring->last_tx_tso &&
++ !skb_is_gso(skb)) {
++ tx_ring->last_tx_tso = 0;
++ size -= 4;
++ }
+
+- while(len) {
+- buffer_info = &tx_ring->buffer_info[i];
+- size = min(len, max_per_txd);
+-#ifdef NETIF_F_TSO
+ /* Workaround for premature desc write-backs
+ * in TSO mode. Append 4-byte sentinel desc */
+- if(unlikely(mss && !nr_frags && size == len && size > 0x8)) {
+- size -= 0x4;
++ if (unlikely(mss && !nr_frags && size == len && size > 8))
++ size -= 4;
++ /* work-around for errata 10 and it applies
++ * to all controllers in PCI-X mode
++ * The fix is to make sure that the first descriptor of a
++ * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
++ */
++ if (unlikely((hw->bus_type == iegbe_bus_type_pcix) &&
++ (size > 2015) && count == 0))
++ size = 2015;
++
++ /* Workaround for potential 82544 hang in PCI-X. Avoid
++ * terminating buffers within evenly-aligned dwords. */
++ if(unlikely(adapter->pcix_82544 &&
++ !((unsigned long)(skb->data + offset + size - 1) & 4) &&
++ size > 4))
++ size -= 4;
++
++ buffer_info->length = size;
++ buffer_info->dma =
++ pci_map_single(adapter->pdev,
++ skb->data + offset,
++ size,
++ PCI_DMA_TODEVICE);
++ buffer_info->time_stamp = jiffies;
++ buffer_info->next_to_watch = i;
++
++ len -= size;
++ offset += size;
++ count++;
++ if (unlikely(++i == tx_ring->count)) i = 0;
++ }
++
++ for (f = 0; f < nr_frags; f++) {
++ struct skb_frag_struct *frag;
++
++ frag = &skb_shinfo(skb)->frags[f];
++ len = frag->size;
++ offset = frag->page_offset;
++
++ while(len) {
++ buffer_info = &tx_ring->buffer_info[i];
++ size = min(len, max_per_txd);
++ /* Workaround for premature desc write-backs
++ * in TSO mode. Append 4-byte sentinel desc */
++ if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
++ size -= 4;
++ /* Workaround for potential 82544 hang in PCI-X.
++ * Avoid terminating buffers within evenly-aligned
++ * dwords. */
++ if(unlikely(adapter->pcix_82544 &&
++ !((unsigned long)(frag->page+offset+size-1) & 4) &&
++ size > 4))
++ size -= 4;
++
++ buffer_info->length = size;
++ buffer_info->dma =
++ pci_map_page(adapter->pdev,
++ frag->page,
++ offset,
++ size,
++ PCI_DMA_TODEVICE);
++ buffer_info->time_stamp = jiffies;
++ buffer_info->next_to_watch = i;
++
++ len -= size;
++ offset += size;
++ count++;
++ if (unlikely(++i == tx_ring->count)) i = 0;
+ }
+-#endif
+- /* work-around for errata 10 and it applies
+- * to all controllers in PCI-X mode
+- * The fix is to make sure that the first descriptor of a
+- * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
+- */
+- if(unlikely((adapter->hw.bus_type == iegbe_bus_type_pcix) &&
+- (size > 0x7df) && count == 0)) {
+- size = 0x7df;
+- }
+- /* Workaround for potential 82544 hang in PCI-X. Avoid
+- * terminating buffers within evenly-aligned dwords. */
+- if(unlikely(adapter->pcix_82544 &&
+- !((unsigned long)(skb->data + offset + size - 0x8) & 0x4) &&
+- size > 0x4)) {
+- size -= 0x4;
+- }
+- buffer_info->length = size;
+- buffer_info->dma =
+- pci_map_single(adapter->pdev,
+- skb->data + offset,
+- size,
+- PCI_DMA_TODEVICE);
+- buffer_info->time_stamp = jiffies;
+-
+- len -= size;
+- offset += size;
+- count++;
+- if(unlikely(++i == tx_ring->count)) { i = 0; }
+- }
+-
+-#ifdef MAX_SKB_FRAGS
+- for(f = 0; f < nr_frags; f++) {
+- struct skb_frag_struct *frag;
+-
+- frag = &skb_shinfo(skb)->frags[f];
+- len = frag->size;
+- offset = frag->page_offset;
+-
+- while(len) {
+- buffer_info = &tx_ring->buffer_info[i];
+- size = min(len, max_per_txd);
+-#ifdef NETIF_F_TSO
+- /* Workaround for premature desc write-backs
+- * in TSO mode. Append 4-byte sentinel desc */
+- if(unlikely(mss && f == (nr_frags-0x1) &&
+- size == len && size > 0x8)) {
+- size -= 0x4;
+- }
+-#endif
+- /* Workaround for potential 82544 hang in PCI-X.
+- * Avoid terminating buffers within evenly-aligned
+- * dwords. */
+- if(unlikely(adapter->pcix_82544 &&
+- !((unsigned long)(frag->page+offset+size-0x1) & 0x4) &&
+- size > 0x4)) {
+- size -= 0x4;
+- }
+- buffer_info->length = size;
+- buffer_info->dma =
+- pci_map_page(adapter->pdev,
+- frag->page,
+- offset,
+- size,
+- PCI_DMA_TODEVICE);
+- buffer_info->time_stamp = jiffies;
+-
+- len -= size;
+- offset += size;
+- count++;
+- if(unlikely(++i == tx_ring->count)) { i = 0; }
+- }
+- }
+-#endif
++ }
+
+- i = (i == 0) ? tx_ring->count - 0x1 : i - 0x1;
+- tx_ring->buffer_info[i].skb = skb;
+- tx_ring->buffer_info[first].next_to_watch = i;
++ i = (i == 0) ? tx_ring->count - 1 : i - 1;
++ tx_ring->buffer_info[i].skb = skb;
++ tx_ring->buffer_info[first].next_to_watch = i;
+
+- return count;
++ return count;
+ }
+
+-static inline void
+-iegbe_tx_queue(struct iegbe_adapter *adapter, struct iegbe_tx_ring *tx_ring,
+- int tx_flags, int count)
++static void iegbe_tx_queue(struct iegbe_adapter *adapter,
++ struct iegbe_tx_ring *tx_ring, int tx_flags,
++ int count)
+ {
++ struct iegbe_hw *hw = &adapter->hw;
+ struct iegbe_tx_desc *tx_desc = NULL;
+ struct iegbe_buffer *buffer_info;
+- uint32_t txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
++ u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
+ unsigned int i;
+
+- if(likely(tx_flags & E1000_TX_FLAGS_TSO)) {
++ if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
+ txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
+ E1000_TXD_CMD_TSE;
+- txd_upper |= E1000_TXD_POPTS_TXSM << 0x8;
++ txd_upper |= E1000_TXD_POPTS_TXSM << 8;
+
+- if(likely(tx_flags & E1000_TX_FLAGS_IPV4)) {
+- txd_upper |= E1000_TXD_POPTS_IXSM << 0x8;
+- }
++ if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
++ txd_upper |= E1000_TXD_POPTS_IXSM << 8;
+ }
+
+- if(likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
++ if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
+ txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
+- txd_upper |= E1000_TXD_POPTS_TXSM << 0x8;
+- }
+-
+- if(unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
+- txd_lower |= E1000_TXD_CMD_VLE;
+- txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
++ txd_upper |= E1000_TXD_POPTS_TXSM << 8;
+ }
+
+- i = tx_ring->next_to_use;
++ if(unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
++ txd_lower |= E1000_TXD_CMD_VLE;
++ txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
++ }
+
+- while(count--) {
+- buffer_info = &tx_ring->buffer_info[i];
+- tx_desc = E1000_TX_DESC(*tx_ring, i);
+- tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+- tx_desc->lower.data =
+- cpu_to_le32(txd_lower | buffer_info->length);
+- tx_desc->upper.data = cpu_to_le32(txd_upper);
+- if(unlikely(++i == tx_ring->count)) { i = 0; }
+- }
+- if(tx_desc != NULL) {
+- tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
+- }
+- /* Force memory writes to complete before letting h/w
+- * know there are new descriptors to fetch. (Only
+- * applicable for weak-ordered memory model archs,
+- * such as IA-64). */
+- wmb();
++ i = tx_ring->next_to_use;
+
+- tx_ring->next_to_use = i;
+- writel(i, adapter->hw.hw_addr + tx_ring->tdt);
++ while(count--) {
++ buffer_info = &tx_ring->buffer_info[i];
++ tx_desc = E1000_TX_DESC(*tx_ring, i);
++ tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
++ tx_desc->lower.data =
++ cpu_to_le32(txd_lower | buffer_info->length);
++ tx_desc->upper.data = cpu_to_le32(txd_upper);
++ if (unlikely(++i == tx_ring->count)) i = 0;
++ }
++
++ tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
++
++ /* Force memory writes to complete before letting h/w
++ * know there are new descriptors to fetch. (Only
++ * applicable for weak-ordered memory model archs,
++ * such as IA-64). */
++ wmb();
++
++ tx_ring->next_to_use = i;
++ writel(i, hw->hw_addr + tx_ring->tdt);
++ /* we need this if more than one processor can write to our tail
++ * at a time, it syncronizes IO on IA64/Altix systems */
++ mmiowb();
+ }
+
+ /**
+@@ -2950,113 +2925,132 @@ iegbe_tx_queue(struct iegbe_adapter *ada
+ * to the beginning of the Tx FIFO.
+ **/
+
+-static inline int
+-iegbe_82547_fifo_workaround(struct iegbe_adapter *adapter, struct sk_buff *skb)
++#define E1000_FIFO_HDR 0x10
++#define E1000_82547_PAD_LEN 0x3E0
++static int iegbe_82547_fifo_workaround(struct iegbe_adapter *adapter,
++ struct sk_buff *skb)
+ {
+- uint32_t fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
+- uint32_t skb_fifo_len = skb->len + E1000_FIFO_HDR;
++ u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
++ u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
+
+- E1000_ROUNDUP(skb_fifo_len, E1000_FIFO_HDR);
++ skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
+
+- if(adapter->link_duplex != HALF_DUPLEX) {
+- goto no_fifo_stall_required;
+- }
+- if(atomic_read(&adapter->tx_fifo_stall)) {
+- return 1;
++ if (adapter->link_duplex != HALF_DUPLEX)
++ goto no_fifo_stall_required;
++
++ if (atomic_read(&adapter->tx_fifo_stall))
++ return 1;
++
++ if(skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
++ atomic_set(&adapter->tx_fifo_stall, 1);
++ return 1;
+ }
+- if(skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
+- atomic_set(&adapter->tx_fifo_stall, 0x1);
+- return 1;
+- }
+
+ no_fifo_stall_required:
+- adapter->tx_fifo_head += skb_fifo_len;
+- if(adapter->tx_fifo_head >= adapter->tx_fifo_size) {
+- adapter->tx_fifo_head -= adapter->tx_fifo_size;
+- }
++ adapter->tx_fifo_head += skb_fifo_len;
++ if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
++ adapter->tx_fifo_head -= adapter->tx_fifo_size;
+ return 0;
+ }
+
+-static inline int
+-iegbe_transfer_dhcp_info(struct iegbe_adapter *adapter, struct sk_buff *skb)
++#define MINIMUM_DHCP_PACKET_SIZE 282
++static int iegbe_transfer_dhcp_info(struct iegbe_adapter *adapter,
++ struct sk_buff *skb)
+ {
+ struct iegbe_hw *hw = &adapter->hw;
+- uint16_t length, offset;
+-#ifdef NETIF_F_HW_VLAN_TX
+- if(vlan_tx_tag_present(skb)) {
+- if(!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
+- ( adapter->hw.mng_cookie.status &
+- E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) ) {
++ u16 length, offset;
++ if (vlan_tx_tag_present(skb)) {
++ if (!((vlan_tx_tag_get(skb) == hw->mng_cookie.vlan_id) &&
++ ( hw->mng_cookie.status &
++ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
+ return 0;
+ }
+- }
+-#endif
+- if(htons(ETH_P_IP) == skb->protocol) {
+- const struct iphdr *ip = skb->nh.iph;
+- if(IPPROTO_UDP == ip->protocol) {
+- struct udphdr *udp = (struct udphdr *)(skb->h.uh);
+- if(ntohs(udp->dest) == 0x43) { /* 0x43 = 67 */
+- offset = (uint8_t *)udp + 0x8 - skb->data;
+- length = skb->len - offset;
+-
+- return iegbe_mng_write_dhcp_info(hw,
+- (uint8_t *)udp + 0x8, length);
+- }
+- }
+- } else if((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) {
+- struct ethhdr *eth = (struct ethhdr *) skb->data;
+- if((htons(ETH_P_IP) == eth->h_proto)) {
++ if (skb->len > MINIMUM_DHCP_PACKET_SIZE) {
++ struct ethhdr *eth = (struct ethhdr *)skb->data;
++ if ((htons(ETH_P_IP) == eth->h_proto)) {
+ const struct iphdr *ip =
+- (struct iphdr *)((uint8_t *)skb->data+0xe);
+- if(IPPROTO_UDP == ip->protocol) {
++ (struct iphdr *)((u8 *)skb->data+14);
++ if (IPPROTO_UDP == ip->protocol) {
+ struct udphdr *udp =
+- (struct udphdr *)((uint8_t *)ip +
+- (ip->ihl << 0x2));
+- if(ntohs(udp->dest) == 0x43) {
+- offset = (uint8_t *)udp + 0x8 - skb->data;
++ (struct udphdr *)((u8 *)ip +
++ (ip->ihl << 2));
++ if (ntohs(udp->dest) == 67) {
++ offset = (u8 *)udp + 8 - skb->data;
+ length = skb->len - offset;
+
+ return iegbe_mng_write_dhcp_info(hw,
+- (uint8_t *)udp + 0x8,
++ (u8 *)udp + 8,
+ length);
+- }
++ }
+ }
+ }
+ }
+ return 0;
+ }
+
+-static int
+-iegbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
++static int __iegbe_maybe_stop_tx(struct net_device *netdev, int size)
++{
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct iegbe_tx_ring *tx_ring = adapter->tx_ring;
++
++ netif_stop_queue(netdev);
++ /* Herbert's original patch had:
++ * smp_mb__after_netif_stop_queue();
++ * but since that doesn't exist yet, just open code it. */
++ smp_mb();
++
++ /* We need to check again in a case another CPU has just
++ * made room available. */
++ if (likely(E1000_DESC_UNUSED(tx_ring) < size))
++ return -EBUSY;
++
++ /* A reprieve! */
++ netif_start_queue(netdev);
++ ++adapter->restart_queue;
++ return 0;
++}
++
++static int iegbe_maybe_stop_tx(struct net_device *netdev,
++ struct iegbe_tx_ring *tx_ring, int size)
++{
++ if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
++ return 0;
++ return __iegbe_maybe_stop_tx(netdev, size);
++}
++
++#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
++static int iegbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+ {
+ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct iegbe_hw *hw = &adapter->hw;
+ struct iegbe_tx_ring *tx_ring;
+ unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
+ unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
+ unsigned int tx_flags = 0;
+- unsigned int len = skb->len;
++ unsigned int len = skb->len - skb->data_len;
+ unsigned long flags = 0;
+- unsigned int nr_frags = 0;
+- unsigned int mss = 0;
++ unsigned int nr_frags;
++ unsigned int mss;
+ int count = 0;
+- int tso;
+-#ifdef MAX_SKB_FRAGS
++ int tso;
+ unsigned int f;
+- len -= skb->data_len;
+-#endif
+
+-#ifdef CONFIG_E1000_MQ
+- tx_ring = *per_cpu_ptr(adapter->cpu_tx_ring, smp_processor_id());
+-#else
++ /* This goes back to the question of how to logically map a tx queue
++ * to a flow. Right now, performance is impacted slightly negatively
++ * if using multiple tx queues. If the stack breaks away from a
++ * single qdisc implementation, we can look at this again. */
+ tx_ring = adapter->tx_ring;
+-#endif
+
+ if (unlikely(skb->len <= 0)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+-#ifdef NETIF_F_TSO
++ /* 82571 and newer doesn't need the workaround that limited descriptor
++ * length to 4kB */
++ if (hw->mac_type >= iegbe_82571)
++ max_per_txd = 8192;
++
+ mss = skb_shinfo(skb)->gso_size;
+ /* The controller does a simple calculation to
+ * make sure there is enough room in the FIFO before
+@@ -3064,164 +3058,150 @@ iegbe_xmit_frame(struct sk_buff *skb, st
+ * 4 = ceil(buffer len/mss). To make sure we don't
+ * overrun the FIFO, adjust the max buffer len if mss
+ * drops. */
+- if(mss) {
+- max_per_txd = min(mss << 0x2, max_per_txd);
+- max_txd_pwr = fls(max_per_txd) - 0x1;
++ if (mss) {
++ u8 hdr_len;
++ max_per_txd = min(mss << 2, max_per_txd);
++ max_txd_pwr = fls(max_per_txd) - 1;
++
++ /* TSO Workaround for 82571/2/3 Controllers -- if skb->data
++ * points to just header, pull a few bytes of payload from
++ * frags into skb->data */
++ hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
++ if (skb->data_len && hdr_len == len) {
++ switch (hw->mac_type) {
++ case iegbe_82544:
++ /* Make sure we have room to chop off 4 bytes,
++ * and that the end alignment will work out to
++ * this hardware's requirements
++ * NOTE: this is a TSO only workaround
++ * if end byte alignment not correct move us
++ * into the next dword */
++ break;
++ /* fall through */
++ case iegbe_82571:
++ case iegbe_82572:
++ case iegbe_82573:
++ break;
++ default:
++ /* do nothing */
++ break;
++ }
++ }
+ }
+
+- if((mss) || (skb->ip_summed == CHECKSUM_HW)) {
++ /* reserve a descriptor for the offload context */
++ if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
+ count++;
+- }
+ count++;
+-#else
+- if(skb->ip_summed == CHECKSUM_HW) {
++
++ /* Controller Erratum workaround */
++ if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
+ count++;
+- {
+-#endif
++
+ count += TXD_USE_COUNT(len, max_txd_pwr);
+
+- if(adapter->pcix_82544) {
++ if (adapter->pcix_82544)
+ count++;
+- }
++
+ /* work-around for errata 10 and it applies to all controllers
+ * in PCI-X mode, so add one more descriptor to the count
+ */
+- if(unlikely((adapter->hw.bus_type == iegbe_bus_type_pcix) &&
+- (len > 0x7df))) {
++ if (unlikely((hw->bus_type == iegbe_bus_type_pcix) &&
++ (len > 2015)))
+ count++;
+- }
+-#ifdef MAX_SKB_FRAGS
++
+ nr_frags = skb_shinfo(skb)->nr_frags;
+- for(f = 0; f < nr_frags; f++)
++ for (f = 0; f < nr_frags; f++)
+ count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
+ max_txd_pwr);
+- if(adapter->pcix_82544) {
++ if (adapter->pcix_82544)
+ count += nr_frags;
+- }
+-#ifdef NETIF_F_TSO
+- /* TSO Workaround for 82571/2 Controllers -- if skb->data
+- * points to just header, pull a few bytes of payload from
+- * frags into skb->data */
+- if (skb_is_gso(skb)) {
+- uint8_t hdr_len;
+- hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 0x2));
+- if (skb->data_len && (hdr_len < (skb->len - skb->data_len)) &&
+- (adapter->hw.mac_type == iegbe_82571 ||
+- adapter->hw.mac_type == iegbe_82572)) {
+- unsigned int pull_size;
+- pull_size = min((unsigned int)0x4, skb->data_len);
+- if (!__pskb_pull_tail(skb, pull_size)) {
+- printk(KERN_ERR "__pskb_pull_tail failed.\n");
+- dev_kfree_skb_any(skb);
+- return -EFAULT;
+- }
+- }
+- }
+-#endif
+-#endif
+
+- if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == iegbe_82573) ) {
++
++ if (hw->tx_pkt_filtering &&
++ (hw->mac_type == iegbe_82573))
+ iegbe_transfer_dhcp_info(adapter, skb);
+- }
+-#ifdef NETIF_F_LLTX
+- local_irq_save(flags);
+- if (!spin_trylock(&tx_ring->tx_lock)) {
++
++ if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
+ /* Collision - tell upper layer to requeue */
+- local_irq_restore(flags);
+ return NETDEV_TX_LOCKED;
+- }
+-#else
+- spin_lock_irqsave(&tx_ring->tx_lock, flags);
+-#endif
+
+ /* need: count + 2 desc gap to keep tail from touching
+ * head, otherwise try next time */
+- if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 0x2)) {
+- netif_stop_queue(netdev);
++ if (unlikely(iegbe_maybe_stop_tx(netdev, tx_ring, count + 2))) {
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+
+- if(unlikely(adapter->hw.mac_type == iegbe_82547)) {
+- if(unlikely(iegbe_82547_fifo_workaround(adapter, skb))) {
++ if (unlikely(hw->mac_type == iegbe_82547)) {
++ if (unlikely(iegbe_82547_fifo_workaround(adapter, skb))) {
+ netif_stop_queue(netdev);
+- mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
++ mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+ }
+
+-#ifndef NETIF_F_LLTX
+- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+-#endif
+-
+-#ifdef NETIF_F_HW_VLAN_TX
+- if(unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
++ if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+ tx_flags |= E1000_TX_FLAGS_VLAN;
+ tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
+ }
+-#endif
+
+ first = tx_ring->next_to_use;
+
+ tso = iegbe_tso(adapter, tx_ring, skb);
+ if (tso < 0) {
+ dev_kfree_skb_any(skb);
+-#ifdef NETIF_F_LLTX
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+-#endif
+ return NETDEV_TX_OK;
+ }
+
+- if (likely(tso)) {
++ if (likely(tso)) {
++ tx_ring->last_tx_tso = 1;
+ tx_flags |= E1000_TX_FLAGS_TSO;
+- } else if (likely(iegbe_tx_csum(adapter, tx_ring, skb))) {
++ } else if (likely(iegbe_tx_csum(adapter, tx_ring, skb)))
+ tx_flags |= E1000_TX_FLAGS_CSUM;
+- }
++
+ /* Old method was to assume IPv4 packet by default if TSO was enabled.
+ * 82571 hardware supports TSO capabilities for IPv6 as well...
+ * no longer assume, we must. */
+- if (likely(skb->protocol == ntohs(ETH_P_IP))) {
++ if (likely(skb->protocol == htons(ETH_P_IP)))
+ tx_flags |= E1000_TX_FLAGS_IPV4;
+- }
++
+ iegbe_tx_queue(adapter, tx_ring, tx_flags,
+ iegbe_tx_map(adapter, tx_ring, skb, first,
+ max_per_txd, nr_frags, mss));
+
+ netdev->trans_start = jiffies;
+
+-#ifdef NETIF_F_LLTX
+ /* Make sure there is space in the ring for the next send. */
+- if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 0x2)) {
+- netif_stop_queue(netdev);
+- }
+- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+-#endif
++ iegbe_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
+
++ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+ return NETDEV_TX_OK;
+ }
+
++
+ /**
+ * iegbe_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ **/
+
+-static void
+-iegbe_tx_timeout(struct net_device *netdev)
++static void iegbe_tx_timeout(struct net_device *netdev)
+ {
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
+
+- /* Do the reset outside of interrupt context */
+- schedule_work(&adapter->tx_timeout_task);
++ /* Do the reset outside of interrupt context */
++ adapter->tx_timeout_count++;
++ schedule_work(&adapter->reset_task);
+ }
+
+-static void
+-iegbe_tx_timeout_task(struct net_device *netdev)
++static void iegbe_reset_task(struct work_struct *work)
+ {
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct iegbe_adapter *adapter =
++ container_of(work, struct iegbe_adapter, reset_task);
+
+- iegbe_down(adapter);
+- iegbe_up(adapter);
++ iegbe_reinit_locked(adapter);
+ }
+
+ /**
+@@ -3232,13 +3212,12 @@ iegbe_tx_timeout_task(struct net_device
+ * The statistics are actually updated from the timer callback.
+ **/
+
+-static struct net_device_stats *
+-iegbe_get_stats(struct net_device *netdev)
++static struct net_device_stats *iegbe_get_stats(struct net_device *netdev)
+ {
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
+
+- iegbe_update_stats(adapter);
+- return &adapter->net_stats;
++ /* only return the current stats */
++ return &adapter->net_stats;
+ }
+
+ /**
+@@ -3249,67 +3228,55 @@ iegbe_get_stats(struct net_device *netde
+ * Returns 0 on success, negative on failure
+ **/
+
+-static int
+-iegbe_change_mtu(struct net_device *netdev, int new_mtu)
++static int iegbe_change_mtu(struct net_device *netdev, int new_mtu)
+ {
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+- int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct iegbe_hw *hw = &adapter->hw;
++ int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
+
+- if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
+- (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+- DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
+- return -EINVAL;
+- }
++ if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
++ (max_frame > MAX_JUMBO_FRAME_SIZE)) {
++ DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
++ return -EINVAL;
++ }
+
++ /* Adapter-specific max frame size limits. */
++ switch (hw->mac_type) {
++ case iegbe_undefined ... iegbe_82542_rev2_1:
++ if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
++ DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
++ return -EINVAL;
++ }
++ break;
++ case iegbe_82571:
++ case iegbe_82572:
+ #define MAX_STD_JUMBO_FRAME_SIZE 9234
+- /* might want this to be bigger enum check... */
+- /* 82571 controllers limit jumbo frame size to 10500 bytes */
+- if ((adapter->hw.mac_type == iegbe_82571 ||
+- adapter->hw.mac_type == iegbe_82572) &&
+- max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
+- DPRINTK(PROBE, ERR, "MTU > 9216 bytes not supported "
+- "on 82571 and 82572 controllers.\n");
+- return -EINVAL;
+- }
+-
+- if(adapter->hw.mac_type == iegbe_82573 &&
+- max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
+- DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
+- "on 82573\n");
+- return -EINVAL;
+- }
+-
+- if(adapter->hw.mac_type > iegbe_82547_rev_2) {
+- adapter->rx_buffer_len = max_frame;
+- E1000_ROUNDUP(adapter->rx_buffer_len, 0x1024);
+- } else {
+- if(unlikely((adapter->hw.mac_type < iegbe_82543) &&
+- (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) {
+- DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
+- "on 82542\n");
+- return -EINVAL;
+-
+- } else {
+- if(max_frame <= E1000_RXBUFFER_2048) {
+- adapter->rx_buffer_len = E1000_RXBUFFER_2048;
+- } else if(max_frame <= E1000_RXBUFFER_4096) {
+- adapter->rx_buffer_len = E1000_RXBUFFER_4096;
+- } else if(max_frame <= E1000_RXBUFFER_8192) {
+- adapter->rx_buffer_len = E1000_RXBUFFER_8192;
+- } else if(max_frame <= E1000_RXBUFFER_16384) {
+- adapter->rx_buffer_len = E1000_RXBUFFER_16384;
+- }
++ if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
++ DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n");
++ return -EINVAL;
+ }
++ break;
++ default:
++ break;
+ }
++ if (max_frame <= E1000_RXBUFFER_256)
++ adapter->rx_buffer_len = E1000_RXBUFFER_256;
++ else if (max_frame <= E1000_RXBUFFER_2048)
++ adapter->rx_buffer_len = E1000_RXBUFFER_2048;
++ else if (max_frame <= E1000_RXBUFFER_4096)
++ adapter->rx_buffer_len = E1000_RXBUFFER_4096;
++ else if (max_frame <= E1000_RXBUFFER_8192)
++ adapter->rx_buffer_len = E1000_RXBUFFER_8192;
++ else if (max_frame <= E1000_RXBUFFER_16384)
++ adapter->rx_buffer_len = E1000_RXBUFFER_16384;
+
+- netdev->mtu = new_mtu;
++ /* adjust allocation if LPE protects us, and we aren't using SBP */
+
+- if(netif_running(netdev)) {
+- iegbe_down(adapter);
+- iegbe_up(adapter);
+- }
++ netdev->mtu = new_mtu;
++ hw->max_frame_size = max_frame;
+
+- adapter->hw.max_frame_size = max_frame;
++ if (netif_running(netdev))
++ iegbe_reinit_locked(adapter);
+
+ return 0;
+ }
+@@ -3319,224 +3286,189 @@ iegbe_change_mtu(struct net_device *netd
+ * @adapter: board private structure
+ **/
+
+-void
+-iegbe_update_stats(struct iegbe_adapter *adapter)
++void iegbe_update_stats(struct iegbe_adapter *adapter)
+ {
+- struct iegbe_hw *hw = &adapter->hw;
+- unsigned long flags = 0;
+- uint16_t phy_tmp;
++ struct iegbe_hw *hw = &adapter->hw;
++ unsigned long flags = 0x0;
++ uint16_t phy_tmp;
+
+ #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
+
+- spin_lock_irqsave(&adapter->stats_lock, flags);
++ spin_lock_irqsave(&adapter->stats_lock, flags);
+
+- /* these counters are modified from iegbe_adjust_tbi_stats,
+- * called from the interrupt context, so they must only
+- * be written while holding adapter->stats_lock
+- */
++ /* these counters are modified from iegbe_adjust_tbi_stats,
++ * called from the interrupt context, so they must only
++ * be written while holding adapter->stats_lock
++ */
+
+- adapter->stats.crcerrs += E1000_READ_REG(hw, CRCERRS);
+- adapter->stats.gprc += E1000_READ_REG(hw, GPRC);
+- adapter->stats.gorcl += E1000_READ_REG(hw, GORCL);
+- adapter->stats.gorch += E1000_READ_REG(hw, GORCH);
+- adapter->stats.bprc += E1000_READ_REG(hw, BPRC);
+- adapter->stats.mprc += E1000_READ_REG(hw, MPRC);
+- adapter->stats.roc += E1000_READ_REG(hw, ROC);
+- adapter->stats.prc64 += E1000_READ_REG(hw, PRC64);
+- adapter->stats.prc127 += E1000_READ_REG(hw, PRC127);
+- adapter->stats.prc255 += E1000_READ_REG(hw, PRC255);
+- adapter->stats.prc511 += E1000_READ_REG(hw, PRC511);
+- adapter->stats.prc1023 += E1000_READ_REG(hw, PRC1023);
+- adapter->stats.prc1522 += E1000_READ_REG(hw, PRC1522);
+-
+- adapter->stats.symerrs += E1000_READ_REG(hw, SYMERRS);
+- adapter->stats.mpc += E1000_READ_REG(hw, MPC);
+- adapter->stats.scc += E1000_READ_REG(hw, SCC);
+- adapter->stats.ecol += E1000_READ_REG(hw, ECOL);
+- adapter->stats.mcc += E1000_READ_REG(hw, MCC);
+- adapter->stats.latecol += E1000_READ_REG(hw, LATECOL);
+- adapter->stats.dc += E1000_READ_REG(hw, DC);
+- adapter->stats.sec += E1000_READ_REG(hw, SEC);
+- adapter->stats.rlec += E1000_READ_REG(hw, RLEC);
+- adapter->stats.xonrxc += E1000_READ_REG(hw, XONRXC);
+- adapter->stats.xontxc += E1000_READ_REG(hw, XONTXC);
+- adapter->stats.xoffrxc += E1000_READ_REG(hw, XOFFRXC);
+- adapter->stats.xofftxc += E1000_READ_REG(hw, XOFFTXC);
+- adapter->stats.fcruc += E1000_READ_REG(hw, FCRUC);
+- adapter->stats.gptc += E1000_READ_REG(hw, GPTC);
+- adapter->stats.gotcl += E1000_READ_REG(hw, GOTCL);
+- adapter->stats.gotch += E1000_READ_REG(hw, GOTCH);
+- adapter->stats.rnbc += E1000_READ_REG(hw, RNBC);
+- adapter->stats.ruc += E1000_READ_REG(hw, RUC);
+- adapter->stats.rfc += E1000_READ_REG(hw, RFC);
+- adapter->stats.rjc += E1000_READ_REG(hw, RJC);
+- adapter->stats.torl += E1000_READ_REG(hw, TORL);
+- adapter->stats.torh += E1000_READ_REG(hw, TORH);
+- adapter->stats.totl += E1000_READ_REG(hw, TOTL);
+- adapter->stats.toth += E1000_READ_REG(hw, TOTH);
+- adapter->stats.tpr += E1000_READ_REG(hw, TPR);
+- adapter->stats.ptc64 += E1000_READ_REG(hw, PTC64);
+- adapter->stats.ptc127 += E1000_READ_REG(hw, PTC127);
+- adapter->stats.ptc255 += E1000_READ_REG(hw, PTC255);
+- adapter->stats.ptc511 += E1000_READ_REG(hw, PTC511);
+- adapter->stats.ptc1023 += E1000_READ_REG(hw, PTC1023);
+- adapter->stats.ptc1522 += E1000_READ_REG(hw, PTC1522);
+- adapter->stats.mptc += E1000_READ_REG(hw, MPTC);
+- adapter->stats.bptc += E1000_READ_REG(hw, BPTC);
+-
+- /* used for adaptive IFS */
+-
+- hw->tx_packet_delta = E1000_READ_REG(hw, TPT);
+- adapter->stats.tpt += hw->tx_packet_delta;
+- hw->collision_delta = E1000_READ_REG(hw, COLC);
+- adapter->stats.colc += hw->collision_delta;
+-
+- if(hw->mac_type >= iegbe_82543) {
+- adapter->stats.algnerrc += E1000_READ_REG(hw, ALGNERRC);
+- adapter->stats.rxerrc += E1000_READ_REG(hw, RXERRC);
+- adapter->stats.tncrs += E1000_READ_REG(hw, TNCRS);
+- adapter->stats.cexterr += E1000_READ_REG(hw, CEXTERR);
+- adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC);
+- adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC);
+- }
+- if(hw->mac_type > iegbe_82547_rev_2) {
+- adapter->stats.iac += E1000_READ_REG(hw, IAC);
+- adapter->stats.icrxoc += E1000_READ_REG(hw, ICRXOC);
+- adapter->stats.icrxptc += E1000_READ_REG(hw, ICRXPTC);
+- adapter->stats.icrxatc += E1000_READ_REG(hw, ICRXATC);
+- adapter->stats.ictxptc += E1000_READ_REG(hw, ICTXPTC);
+- adapter->stats.ictxatc += E1000_READ_REG(hw, ICTXATC);
+- adapter->stats.ictxqec += E1000_READ_REG(hw, ICTXQEC);
+- adapter->stats.ictxqmtc += E1000_READ_REG(hw, ICTXQMTC);
+- adapter->stats.icrxdmtc += E1000_READ_REG(hw, ICRXDMTC);
+- }
+-
+- /* Fill out the OS statistics structure */
+-
+- adapter->net_stats.rx_packets = adapter->stats.gprc;
+- adapter->net_stats.tx_packets = adapter->stats.gptc;
+- adapter->net_stats.rx_bytes = adapter->stats.gorcl;
+- adapter->net_stats.tx_bytes = adapter->stats.gotcl;
+- adapter->net_stats.multicast = adapter->stats.mprc;
+- adapter->net_stats.collisions = adapter->stats.colc;
+-
+- /* Rx Errors */
+-
+- adapter->net_stats.rx_errors = adapter->stats.rxerrc +
+- adapter->stats.crcerrs + adapter->stats.algnerrc +
+- adapter->stats.rlec + adapter->stats.mpc +
+- adapter->stats.cexterr;
+- adapter->net_stats.rx_dropped = adapter->stats.mpc;
+- adapter->net_stats.rx_length_errors = adapter->stats.rlec;
+- adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
+- adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
+- adapter->net_stats.rx_fifo_errors = adapter->stats.mpc;
+- adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
+-
+- /* Tx Errors */
+-
+- adapter->net_stats.tx_errors = adapter->stats.ecol +
+- adapter->stats.latecol;
+- adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
+- adapter->net_stats.tx_window_errors = adapter->stats.latecol;
+- adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
++ adapter->stats.crcerrs += E1000_READ_REG(hw, CRCERRS);
++ adapter->stats.gprc += E1000_READ_REG(hw, GPRC);
++ adapter->stats.gorcl += E1000_READ_REG(hw, GORCL);
++ adapter->stats.gorch += E1000_READ_REG(hw, GORCH);
++ adapter->stats.bprc += E1000_READ_REG(hw, BPRC);
++ adapter->stats.mprc += E1000_READ_REG(hw, MPRC);
++ adapter->stats.roc += E1000_READ_REG(hw, ROC);
++ adapter->stats.prc64 += E1000_READ_REG(hw, PRC64);
++ adapter->stats.prc127 += E1000_READ_REG(hw, PRC127);
++ adapter->stats.prc255 += E1000_READ_REG(hw, PRC255);
++ adapter->stats.prc511 += E1000_READ_REG(hw, PRC511);
++ adapter->stats.prc1023 += E1000_READ_REG(hw, PRC1023);
++ adapter->stats.prc1522 += E1000_READ_REG(hw, PRC1522);
++
++ adapter->stats.symerrs += E1000_READ_REG(hw, SYMERRS);
++ adapter->stats.mpc += E1000_READ_REG(hw, MPC);
++ adapter->stats.scc += E1000_READ_REG(hw, SCC);
++ adapter->stats.ecol += E1000_READ_REG(hw, ECOL);
++ adapter->stats.mcc += E1000_READ_REG(hw, MCC);
++ adapter->stats.latecol += E1000_READ_REG(hw, LATECOL);
++ adapter->stats.dc += E1000_READ_REG(hw, DC);
++ adapter->stats.sec += E1000_READ_REG(hw, SEC);
++ adapter->stats.rlec += E1000_READ_REG(hw, RLEC);
++ adapter->stats.xonrxc += E1000_READ_REG(hw, XONRXC);
++ adapter->stats.xontxc += E1000_READ_REG(hw, XONTXC);
++ adapter->stats.xoffrxc += E1000_READ_REG(hw, XOFFRXC);
++ adapter->stats.xofftxc += E1000_READ_REG(hw, XOFFTXC);
++ adapter->stats.fcruc += E1000_READ_REG(hw, FCRUC);
++ adapter->stats.gptc += E1000_READ_REG(hw, GPTC);
++ adapter->stats.gotcl += E1000_READ_REG(hw, GOTCL);
++ adapter->stats.gotch += E1000_READ_REG(hw, GOTCH);
++ adapter->stats.rnbc += E1000_READ_REG(hw, RNBC);
++ adapter->stats.ruc += E1000_READ_REG(hw, RUC);
++ adapter->stats.rfc += E1000_READ_REG(hw, RFC);
++ adapter->stats.rjc += E1000_READ_REG(hw, RJC);
++ adapter->stats.torl += E1000_READ_REG(hw, TORL);
++ adapter->stats.torh += E1000_READ_REG(hw, TORH);
++ adapter->stats.totl += E1000_READ_REG(hw, TOTL);
++ adapter->stats.toth += E1000_READ_REG(hw, TOTH);
++ adapter->stats.tpr += E1000_READ_REG(hw, TPR);
++ adapter->stats.ptc64 += E1000_READ_REG(hw, PTC64);
++ adapter->stats.ptc127 += E1000_READ_REG(hw, PTC127);
++ adapter->stats.ptc255 += E1000_READ_REG(hw, PTC255);
++ adapter->stats.ptc511 += E1000_READ_REG(hw, PTC511);
++ adapter->stats.ptc1023 += E1000_READ_REG(hw, PTC1023);
++ adapter->stats.ptc1522 += E1000_READ_REG(hw, PTC1522);
++ adapter->stats.mptc += E1000_READ_REG(hw, MPTC);
++ adapter->stats.bptc += E1000_READ_REG(hw, BPTC);
++
++ /* used for adaptive IFS */
++
++ hw->tx_packet_delta = E1000_READ_REG(hw, TPT);
++ adapter->stats.tpt += hw->tx_packet_delta;
++ hw->collision_delta = E1000_READ_REG(hw, COLC);
++ adapter->stats.colc += hw->collision_delta;
++
++ if(hw->mac_type >= iegbe_82543) {
++ adapter->stats.algnerrc += E1000_READ_REG(hw, ALGNERRC);
++ adapter->stats.rxerrc += E1000_READ_REG(hw, RXERRC);
++ adapter->stats.tncrs += E1000_READ_REG(hw, TNCRS);
++ adapter->stats.cexterr += E1000_READ_REG(hw, CEXTERR);
++ adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC);
++ adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC);
++ }
++ if(hw->mac_type > iegbe_82547_rev_2) {
++ adapter->stats.iac += E1000_READ_REG(hw, IAC);
++ adapter->stats.icrxoc += E1000_READ_REG(hw, ICRXOC);
++ adapter->stats.icrxptc += E1000_READ_REG(hw, ICRXPTC);
++ adapter->stats.icrxatc += E1000_READ_REG(hw, ICRXATC);
++ adapter->stats.ictxptc += E1000_READ_REG(hw, ICTXPTC);
++ adapter->stats.ictxatc += E1000_READ_REG(hw, ICTXATC);
++ adapter->stats.ictxqec += E1000_READ_REG(hw, ICTXQEC);
++ adapter->stats.ictxqmtc += E1000_READ_REG(hw, ICTXQMTC);
++ adapter->stats.icrxdmtc += E1000_READ_REG(hw, ICRXDMTC);
++ }
++
++ /* Fill out the OS statistics structure */
++
++ adapter->net_stats.rx_packets = adapter->stats.gprc;
++ adapter->net_stats.tx_packets = adapter->stats.gptc;
++ adapter->net_stats.rx_bytes = adapter->stats.gorcl;
++ adapter->net_stats.tx_bytes = adapter->stats.gotcl;
++ adapter->net_stats.multicast = adapter->stats.mprc;
++ adapter->net_stats.collisions = adapter->stats.colc;
++
++ /* Rx Errors */
++
++ adapter->net_stats.rx_errors = adapter->stats.rxerrc +
++ adapter->stats.crcerrs + adapter->stats.algnerrc +
++ adapter->stats.rlec + adapter->stats.mpc +
++ adapter->stats.cexterr;
++ adapter->net_stats.rx_dropped = adapter->stats.mpc;
++ adapter->net_stats.rx_length_errors = adapter->stats.rlec;
++ adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
++ adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
++ adapter->net_stats.rx_fifo_errors = adapter->stats.mpc;
++ adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
++
++ /* Tx Errors */
++
++ adapter->net_stats.tx_errors = adapter->stats.ecol +
++ adapter->stats.latecol;
++ adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
++ adapter->net_stats.tx_window_errors = adapter->stats.latecol;
++ adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
+
+- /* Tx Dropped needs to be maintained elsewhere */
++ /* Tx Dropped needs to be maintained elsewhere */
+
+- /* Phy Stats */
++ /* Phy Stats */
+
+- if(hw->media_type == iegbe_media_type_copper
++ if(hw->media_type == iegbe_media_type_copper
+ || (hw->media_type == iegbe_media_type_oem
+ && iegbe_oem_phy_is_copper(&adapter->hw))) {
+- if((adapter->link_speed == SPEED_1000) &&
+- (!iegbe_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
+- phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
+- adapter->phy_stats.idle_errors += phy_tmp;
+- }
++ if((adapter->link_speed == SPEED_1000) &&
++ (!iegbe_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
++ phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
++ adapter->phy_stats.idle_errors += phy_tmp;
++ }
+
+- if((hw->mac_type <= iegbe_82546) &&
+- (hw->phy_type == iegbe_phy_m88) &&
++ if((hw->mac_type <= iegbe_82546) &&
++ (hw->phy_type == iegbe_phy_m88) &&
+ !iegbe_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp)) {
+- adapter->phy_stats.receive_errors += phy_tmp;
+- }
++ adapter->phy_stats.receive_errors += phy_tmp;
++ }
+ }
+
+- spin_unlock_irqrestore(&adapter->stats_lock, flags);
++ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+ }
+
+-#ifdef CONFIG_E1000_MQ
+-void
+-iegbe_rx_schedule(void *data)
++/**
++ * iegbe_intr_msi - Interrupt Handler
++ * @irq: interrupt number
++ * @data: pointer to a network interface device structure
++ **/
++
++static irqreturn_t iegbe_intr_msi(int irq, void *data)
+ {
+- struct net_device *poll_dev, *netdev = data;
+- struct iegbe_adapter *adapter = netdev->priv;
+- int this_cpu = get_cpu();
+-
+- poll_dev = *per_cpu_ptr(adapter->cpu_netdev, this_cpu);
+- if (poll_dev == NULL) {
+- put_cpu();
+- return;
++ struct net_device *netdev = data;
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct iegbe_hw *hw = &adapter->hw;
++ u32 icr = E1000_READ_REG(&adapter->hw, ICR);
++ if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
++ hw->get_link_status = 1;
++ if (!test_bit(__E1000_DOWN, &adapter->flags))
++ mod_timer(&adapter->watchdog_timer, jiffies + 1);
+ }
+
+- if (likely(netif_rx_schedule_prep(poll_dev))) {
+- __netif_rx_schedule(poll_dev);
+- } else {
+- iegbe_irq_enable(adapter);
+- }
+- put_cpu();
+-}
+-#endif
+-
+-#ifdef IEGBE_GBE_WORKAROUND
+-/*
+- * Check for tx hang condition. This is the condition where a
+- * decsriptor is in the hardware and hasn't been processed for a
+- * while. This code is similar to the check in iegbe_clean_rx_irq()
+- */
+-static void
+-iegbe_tx_hang_check(struct iegbe_adapter *adapter,
+- struct iegbe_tx_ring *tx_ring)
+-{
+- struct net_device *netdev = adapter->netdev;
+- unsigned int i;
++ if(unlikely(icr & (E1000_ICR_RX_DESC_FIFO_PAR
++ | E1000_ICR_TX_DESC_FIFO_PAR
++ | E1000_ICR_PB
++ | E1000_ICR_CPP_TARGET
++ | E1000_ICR_CPP_MASTER ))) {
+
+- /* Check for a hang condition using the buffer currently at the Tx
+- head pointer */
+- i = readl(adapter->hw.hw_addr + tx_ring->tdh);
+-
+- if (adapter->detect_tx_hung) {
+- /* Detect a transmit hang in hardware, this serializes the
+- * check with the clearing of time_stamp and movement of i */
+- adapter->detect_tx_hung = FALSE;
+-
+- if (tx_ring->buffer_info[i].dma &&
+- time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ)
+- && !(E1000_READ_REG(&adapter->hw, STATUS) &
+- E1000_STATUS_TXOFF)) {
+-
+- /* detected Tx unit hang */
+- DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
+- " TDH <%x>\n"
+- " TDT <%x>\n"
+- " next_to_use <%x>\n"
+- " next_to_clean <%x>\n"
+- "buffer_info[tdh]\n"
+- " dma <%zx>\n"
+- " time_stamp <%lx>\n"
+- " jiffies <%lx>\n",
+- readl(adapter->hw.hw_addr + tx_ring->tdh),
+- readl(adapter->hw.hw_addr + tx_ring->tdt),
+- tx_ring->next_to_use,
+- tx_ring->next_to_clean,
+- (size_t)tx_ring->buffer_info[i].dma,
+- tx_ring->buffer_info[i].time_stamp,
+- jiffies);
+- netif_stop_queue(netdev);
+- }
++ iegbe_irq_disable(adapter);
++ printk("Critical error! ICR = 0x%x\n", icr);
++ return IRQ_HANDLED;
+ }
+-}
++ if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
++ adapter->total_tx_bytes = 0;
++ adapter->total_tx_packets = 0;
++ adapter->total_rx_bytes = 0;
++ adapter->total_rx_packets = 0;
++ __netif_rx_schedule(netdev, &adapter->napi);
++ } else
++ iegbe_irq_enable(adapter);
+
+-#endif
++ return IRQ_HANDLED;
++}
+
+ /**
+ * iegbe_intr - Interrupt Handler
+@@ -3546,364 +3478,208 @@ iegbe_tx_hang_check(struct iegbe_adapter
+ **/
+
+ static irqreturn_t
+-iegbe_intr(int irq, void *data, struct pt_regs *regs)
++iegbe_intr(int irq, void *data)
+ {
+- struct net_device *netdev = data;
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+- struct iegbe_hw *hw = &adapter->hw;
+- uint32_t rctl, tctl;
+- uint32_t icr = E1000_READ_REG(hw, ICR);
+-#ifndef CONFIG_E1000_NAPI
+- uint32_t i;
+-#ifdef IEGBE_GBE_WORKAROUND
+- int rx_cleaned;
+-#endif
+-#endif
++ struct net_device *netdev = data;
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct iegbe_hw *hw = &adapter->hw;
++ u32 icr = E1000_READ_REG(&adapter->hw, ICR);
+
+- if(unlikely(!icr)) {
++ if (unlikely(!icr))
+ return IRQ_NONE; /* Not our interrupt */
+- }
++
++ /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
++ * not set, then the adapter didn't send an interrupt */
++ if (unlikely(hw->mac_type >= iegbe_82571 &&
++ !(icr & E1000_ICR_INT_ASSERTED)))
++ return IRQ_NONE;
++
++
+ if(unlikely(icr & (E1000_ICR_RX_DESC_FIFO_PAR
+- | E1000_ICR_TX_DESC_FIFO_PAR
+- | E1000_ICR_PB
+- | E1000_ICR_CPP_TARGET
+- | E1000_ICR_CPP_MASTER ))) {
++ | E1000_ICR_TX_DESC_FIFO_PAR
++ | E1000_ICR_PB
++ | E1000_ICR_CPP_TARGET
++ | E1000_ICR_CPP_MASTER ))) {
+
+ iegbe_irq_disable(adapter);
+- tctl = E1000_READ_REG(&adapter->hw, TCTL);
+- rctl = E1000_READ_REG(&adapter->hw, RCTL);
+- E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_TCTL_EN);
+- E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN);
+-
+- tasklet_data = (unsigned long) (icr + adapter->bd_number);
+- tasklet_schedule(&iegbe_reset_tasklet);
+-
+- return IRQ_HANDLED;
+- }
+-
+-#ifdef CONFIG_E1000_NAPI
+- atomic_inc(&adapter->irq_sem);
+-#ifdef IEGBE_GBE_WORKAROUND
+- /* Ensure that the TXQE interrupt is enabled in NAPI mode */
+- E1000_WRITE_REG(hw, IMC, ~E1000_IMS_TXQE);
+-#else
+- E1000_WRITE_REG(hw, IMC, ~0);
+-#endif
+- E1000_WRITE_FLUSH(hw);
+-#ifdef CONFIG_E1000_MQ
+- if (atomic_read(&adapter->rx_sched_call_data.count) == 0) {
+- cpu_set(adapter->cpu_for_queue[0],
+- adapter->rx_sched_call_data.cpumask);
+- for (i = 1; i < adapter->num_queues; i++) {
+- cpu_set(adapter->cpu_for_queue[i],
+- adapter->rx_sched_call_data.cpumask);
+- atomic_inc(&adapter->irq_sem);
+- }
+- atomic_set(&adapter->rx_sched_call_data.count, i);
+- smp_call_async_mask(&adapter->rx_sched_call_data);
+- } else {
+- DEBUGOUT("call_data.count == %u\n",
+- atomic_read(&adapter->rx_sched_call_data.count));
++ printk("Critical error! ICR = 0x%x\n", icr);
++ return IRQ_HANDLED;
+ }
+-#else
+- if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0]))) {
+- __netif_rx_schedule(&adapter->polling_netdev[0]);
+- } else {
+- iegbe_irq_enable(adapter);
+- }
+-#endif
+-
+-#ifdef IEGBE_GBE_WORKAROUND
+- /* Clean the Tx ring */
+- for (i = 0; i < E1000_MAX_INTR; i++) {
+- adapter->stats.rx_next_to_clean = adapter->rx_ring->next_to_clean;
+- adapter->stats.rx_next_to_use = adapter->rx_ring->next_to_use;
+-
+- adapter->stats.tx_next_to_clean = adapter->tx_ring->next_to_clean;
+- adapter->stats.tx_next_to_use = adapter->tx_ring->next_to_use;
+-
+- /* Only clean Tx descriptors for a TXQE interrupt */
+- if(icr & E1000_ICR_TXQE) {
+- adapter->stats.txqec++;
+- iegbe_clean_tx_ring_partial(adapter, adapter->tx_ring);
+- }
+- else {
+- iegbe_tx_hang_check(adapter, adapter->tx_ring);
+- }
+- }
+
+-#endif /*IEGBE_GBE_WORKAROUND */
+-
+-#else
+- /* Writing IMC and IMS is needed for 82547.
+- * Due to Hub Link bus being occupied, an interrupt
+- * de-assertion message is not able to be sent.
+- * When an interrupt assertion message is generated later,
+- * two messages are re-ordered and sent out.
+- * That causes APIC to think 82547 is in de-assertion
+- * state, while 82547 is in assertion state, resulting
+- * in dead lock. Writing IMC forces 82547 into
+- * de-assertion state.
+- */
+- if (hw->mac_type == iegbe_82547 || hw->mac_type == iegbe_82547_rev_2) {
+- atomic_inc(&adapter->irq_sem);
+- E1000_WRITE_REG(hw, IMC, ~0);
+- }
+-
+-#ifdef IEGBE_GBE_WORKAROUND
+-
+- for (i = 0; i < E1000_MAX_INTR; i++) {
+- rx_cleaned = adapter->clean_rx(adapter, adapter->rx_ring);
+- adapter->stats.rx_next_to_clean = adapter->rx_ring->next_to_clean;
+- adapter->stats.rx_next_to_use = adapter->rx_ring->next_to_use;
+-
+- adapter->stats.tx_next_to_clean = adapter->tx_ring->next_to_clean;
+- adapter->stats.tx_next_to_use = adapter->tx_ring->next_to_use;
+-
+- /* Only clean Tx descriptors for a TXQE interrupt */
+- if(icr & E1000_ICR_TXQE) {
+- adapter->stats.txqec++;
+- iegbe_clean_tx_ring_partial(adapter, adapter->tx_ring);
+- }
+- else {
+- iegbe_tx_hang_check(adapter, adapter->tx_ring);
+- }
+- if(!rx_cleaned) {
+- break;
+- }
++ /* Interrupt Auto-Mask...upon reading ICR, interrupts are masked. No
++ * need for the IMC write */
++ if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
++ hw->get_link_status = 1;
++ /* guard against interrupt when we're going down */
++ if (!test_bit(__E1000_DOWN, &adapter->flags))
++ mod_timer(&adapter->watchdog_timer, jiffies + 1);
++
+ }
+
+-#else
+- for (i = 0; i < E1000_MAX_INTR; i++)
+- if(unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
+- !iegbe_clean_tx_irq(adapter, adapter->tx_ring))) {
+- break;
+- }
+-#endif
+-
+- if (hw->mac_type == iegbe_82547 || hw->mac_type == iegbe_82547_rev_2) {
+- iegbe_irq_enable(adapter);
+- }
+-#endif
+-#ifdef E1000_COUNT_ICR
+- adapter->icr_txdw += icr & 0x01UL;
+- icr >>= 0x1;
+- adapter->icr_txqe += icr & 0x01UL;
+- icr >>= 0x1;
+- adapter->icr_lsc += icr & 0x01UL;
+- icr >>= 0x1;
+- adapter->icr_rxseq += icr & 0x01UL;
+- icr >>= 0x1;
+- adapter->icr_rxdmt += icr & 0x01UL;
+- icr >>= 0x1;
+- adapter->icr_rxo += icr & 0x01UL;
+- icr >>= 0x1;
+- adapter->icr_rxt += icr & 0x01UL;
+- if(hw->mac_type != iegbe_icp_xxxx) {
+- icr >>= 0x2;
+- adapter->icr_mdac += icr & 0x01UL;
+- icr >>= 0x1;
+- adapter->icr_rxcfg += icr & 0x01UL;
+- icr >>= 0x1;
+- adapter->icr_gpi += icr & 0x01UL;
+- } else {
+- icr >>= 0x4;
+- }
+- if(hw->mac_type == iegbe_icp_xxxx) {
+- icr >>= 0xc;
+- adapter->icr_pb += icr & 0x01UL;
+- icr >>= 0x3;
+- adapter->icr_intmem_icp_xxxx += icr & 0x01UL;
+- icr >>= 0x1;
+- adapter->icr_cpp_target += icr & 0x01UL;
+- icr >>= 0x1;
+- adapter->icr_cpp_master += icr & 0x01UL;
+- icr >>= 0x1;
+- adapter->icr_stat += icr & 0x01UL;
++ if (unlikely(hw->mac_type < iegbe_82571)) {
++ E1000_WRITE_REG(&adapter->hw, IMC, ~0);
++ E1000_WRITE_FLUSH(&adapter->hw);
+ }
+-#endif
++ if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
++ adapter->total_tx_bytes = 0;
++ adapter->total_tx_packets = 0;
++ adapter->total_rx_bytes = 0;
++ adapter->total_rx_packets = 0;
++ __netif_rx_schedule(netdev, &adapter->napi);
++ } else
++ /* this really should not happen! if it does it is basically a
++ * bug, but not a hard error, so enable ints and continue */
++ iegbe_irq_enable(adapter);
+
+ return IRQ_HANDLED;
+ }
+
+-#ifdef CONFIG_E1000_NAPI
+ /**
+ * iegbe_clean - NAPI Rx polling callback
+ * @adapter: board private structure
+ **/
+-
+-static int
+-iegbe_clean(struct net_device *poll_dev, int *budget)
++static int iegbe_clean(struct napi_struct *napi, int budget)
+ {
+- struct iegbe_adapter *adapter;
+- int work_to_do = min(*budget, poll_dev->quota);
+- int tx_cleaned, i = 0, work_done = 0;
++ struct iegbe_adapter *adapter = container_of(napi, struct iegbe_adapter, napi);
++ struct net_device *poll_dev = adapter->netdev;
++ int tx_cleaned = 0, work_done = 0;
+
+ /* Must NOT use netdev_priv macro here. */
+ adapter = poll_dev->priv;
+
+- /* Keep link state information with original netdev */
+- if (!netif_carrier_ok(adapter->netdev)) {
+- goto quit_polling;
+- }
+- while (poll_dev != &adapter->polling_netdev[i]) {
+- i++;
+- if (unlikely(i == adapter->num_queues)) {
+- BUG();
+- }
+- }
+-
+-#ifdef IEGBE_GBE_WORKAROUND
+- /* Tx descriptors are cleaned in iegbe_intr(). No need to clean
+- them here */
+- tx_cleaned = FALSE;
+-#else
+- tx_cleaned = iegbe_clean_tx_irq(adapter, &adapter->tx_ring[i]);
+-#endif
+- adapter->clean_rx(adapter, &adapter->rx_ring[i],
+- &work_done, work_to_do);
+-
+- *budget -= work_done;
+- poll_dev->quota -= work_done;
+-
+- /* If no Tx and not enough Rx work done, exit the polling mode */
+- if((!tx_cleaned && (work_done == 0)) ||
+- !netif_running(adapter->netdev)) {
+-quit_polling:
+- netif_rx_complete(poll_dev);
++ /* iegbe_clean is called per-cpu. This lock protects
++ * tx_ring[0] from being cleaned by multiple cpus
++ * simultaneously. A failure obtaining the lock means
++ * tx_ring[0] is currently being cleaned anyway. */
++ if (spin_trylock(&adapter->tx_queue_lock)) {
++ tx_cleaned = iegbe_clean_tx_irq(adapter,
++ &adapter->tx_ring[0]);
++ spin_unlock(&adapter->tx_queue_lock);
++ }
++
++ adapter->clean_rx(adapter, &adapter->rx_ring[0],
++ &work_done, budget);
++
++ if (tx_cleaned)
++ work_done = budget;
++
++ /* If budget not fully consumed, exit the polling mode */
++ if (work_done < budget) {
++ if (likely(adapter->itr_setting & 3))
++ iegbe_set_itr(adapter);
++ netif_rx_complete(poll_dev, napi);
+ iegbe_irq_enable(adapter);
+- return 0;
+ }
+
+- return 1;
++ return work_done;
+ }
+
+-#endif
+-
+-
+-#ifndef IEGBE_GBE_WORKAROUND
+ /**
+ * iegbe_clean_tx_irq - Reclaim resources after transmit completes
+ * @adapter: board private structure
+ **/
+-
+-static boolean_t
+-iegbe_clean_tx_irq(struct iegbe_adapter *adapter,
++static bool iegbe_clean_tx_irq(struct iegbe_adapter *adapter,
+ struct iegbe_tx_ring *tx_ring)
+ {
+- struct net_device *netdev = adapter->netdev;
+- struct iegbe_tx_desc *tx_desc, *eop_desc;
+- struct iegbe_buffer *buffer_info;
+- unsigned int i, eop;
+- boolean_t cleaned = FALSE;
++ struct iegbe_hw *hw = &adapter->hw;
++ struct net_device *netdev = adapter->netdev;
++ struct iegbe_tx_desc *tx_desc, *eop_desc;
++ struct iegbe_buffer *buffer_info;
++ unsigned int i, eop;
++ unsigned int count = 0;
++ bool cleaned = false;
++ unsigned int total_tx_bytes=0, total_tx_packets=0;
+
+- i = tx_ring->next_to_clean;
+- eop = tx_ring->buffer_info[i].next_to_watch;
+- eop_desc = E1000_TX_DESC(*tx_ring, eop);
++ i = tx_ring->next_to_clean;
++ eop = tx_ring->buffer_info[i].next_to_watch;
++ eop_desc = E1000_TX_DESC(*tx_ring, eop);
+
+ while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
+- /* Premature writeback of Tx descriptors clear (free buffers
+- * and unmap pci_mapping) previous_buffer_info */
+- if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
+- iegbe_unmap_and_free_tx_resource(adapter,
+- &tx_ring->previous_buffer_info);
+- }
+-
+- for (cleaned = FALSE; !cleaned; ) {
+- tx_desc = E1000_TX_DESC(*tx_ring, i);
+- buffer_info = &tx_ring->buffer_info[i];
+- cleaned = (i == eop);
+-
+-#ifdef NETIF_F_TSO
+- if (!(netdev->features & NETIF_F_TSO)) {
+-#endif
+- iegbe_unmap_and_free_tx_resource(adapter,
+- buffer_info);
+-#ifdef NETIF_F_TSO
+- } else {
+- if (cleaned) {
+- memcpy(&tx_ring->previous_buffer_info,
+- buffer_info,
+- sizeof(struct iegbe_buffer));
+- memset(buffer_info, 0,
+- sizeof(struct iegbe_buffer));
+- } else {
+- iegbe_unmap_and_free_tx_resource(
+- adapter, buffer_info);
+- }
+- }
+-#endif
+-
+- tx_desc->buffer_addr = 0;
+- tx_desc->lower.data = 0;
++ for (cleaned = false; !cleaned; ) {
++ tx_desc = E1000_TX_DESC(*tx_ring, i);
++ buffer_info = &tx_ring->buffer_info[i];
++ cleaned = (i == eop);
++
++ if (cleaned) {
++ struct sk_buff *skb = buffer_info->skb;
++ unsigned int segs = 0, bytecount;
++ segs = skb_shinfo(skb)->gso_segs ?: 1;
++ bytecount = ((segs - 1) * skb_headlen(skb)) +
++ skb->len;
++ total_tx_packets += segs;
++ total_tx_bytes += bytecount;
++ }
++ iegbe_unmap_and_free_tx_resource(adapter, buffer_info);
+ tx_desc->upper.data = 0;
+
+- if (unlikely(++i == tx_ring->count)) { i = 0; }
+- }
+-
+- tx_ring->pkt++;
++ if (unlikely(++i == tx_ring->count)) i = 0;
++ }
+
+- eop = tx_ring->buffer_info[i].next_to_watch;
+- eop_desc = E1000_TX_DESC(*tx_ring, eop);
+- }
++ eop = tx_ring->buffer_info[i].next_to_watch;
++ eop_desc = E1000_TX_DESC(*tx_ring, eop);
++#define E1000_TX_WEIGHT 64
++ /* weight of a sort for tx, to avoid endless transmit cleanup */
++ if (count++ == E1000_TX_WEIGHT)
++ break;
++ }
+
+ tx_ring->next_to_clean = i;
+
+- spin_lock(&tx_ring->tx_lock);
++#define TX_WAKE_THRESHOLD 32
+
+- if (unlikely(cleaned && netif_queue_stopped(netdev) &&
+- netif_carrier_ok(netdev))) {
+- netif_wake_queue(netdev);
+- }
+- spin_unlock(&tx_ring->tx_lock);
+-
+- if (adapter->detect_tx_hung) {
+- /* Detect a transmit hang in hardware, this serializes the
+- * check with the clearing of time_stamp and movement of i */
+- adapter->detect_tx_hung = FALSE;
+-
+- if (tx_ring->buffer_info[i].dma &&
+- time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ)
+- && !(E1000_READ_REG(&adapter->hw, STATUS) &
+- E1000_STATUS_TXOFF)) {
+-
+- /* detected Tx unit hang */
+- i = tx_ring->next_to_clean;
+- eop = tx_ring->buffer_info[i].next_to_watch;
+- eop_desc = E1000_TX_DESC(*tx_ring, eop);
+- DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
+- " TDH <%x>\n"
+- " TDT <%x>\n"
+- " next_to_use <%x>\n"
+- " next_to_clean <%x>\n"
+- "buffer_info[next_to_clean]\n"
+- " dma <%zx>\n"
+- " time_stamp <%lx>\n"
+- " next_to_watch <%x>\n"
+- " jiffies <%lx>\n"
+- " next_to_watch.status <%x>\n",
+- readl(adapter->hw.hw_addr + tx_ring->tdh),
+- readl(adapter->hw.hw_addr + tx_ring->tdt),
+- tx_ring->next_to_use,
+- i,
+- (size_t)tx_ring->buffer_info[i].dma,
+- tx_ring->buffer_info[i].time_stamp,
+- eop,
+- jiffies,
+- eop_desc->upper.fields.status);
+- netif_stop_queue(netdev);
++ if (unlikely(cleaned && netif_carrier_ok(netdev) &&
++ E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
++ /* Make sure that anybody stopping the queue after this
++ * sees the new next_to_clean.
++ */
++ smp_mb();
++ if (netif_queue_stopped(netdev)) {
++ netif_wake_queue(netdev);
++ ++adapter->restart_queue;
+ }
+ }
+-#ifdef NETIF_F_TSO
+- if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+- time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ))) {
+- iegbe_unmap_and_free_tx_resource(
+- adapter, &tx_ring->previous_buffer_info);
++
++ if (adapter->detect_tx_hung) {
++ /* Detect a transmit hang in hardware, this serializes the
++ * check with the clearing of time_stamp and movement of i */
++ adapter->detect_tx_hung = false;
++
++ if (tx_ring->buffer_info[eop].dma &&
++ time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
++ (adapter->tx_timeout_factor * HZ))
++ && !(E1000_READ_REG(hw, STATUS) & E1000_STATUS_TXOFF)) {
++
++ /* detected Tx unit hang */
++ DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
++ " Tx Queue <%lu>\n"
++ " TDH <%x>\n"
++ " TDT <%x>\n"
++ " next_to_use <%x>\n"
++ " next_to_clean <%x>\n"
++ "buffer_info[next_to_clean]\n"
++ " time_stamp <%lx>\n"
++ " next_to_watch <%x>\n"
++ " jiffies <%lx>\n"
++ " next_to_watch.status <%x>\n",
++ (unsigned long)((tx_ring - adapter->tx_ring) /
++ sizeof(struct iegbe_tx_ring)),
++ readl(hw->hw_addr + tx_ring->tdh),
++ readl(hw->hw_addr + tx_ring->tdt),
++ tx_ring->next_to_use,
++ tx_ring->next_to_clean,
++ tx_ring->buffer_info[eop].time_stamp,
++ eop,
++ jiffies,
++ eop_desc->upper.fields.status);
++ netif_stop_queue(netdev);
++ }
+ }
+-#endif
+- return cleaned;
++ adapter->total_tx_bytes += total_tx_bytes;
++ adapter->total_tx_packets += total_tx_packets;
++ adapter->net_stats.tx_bytes += total_tx_bytes;
++ adapter->net_stats.tx_packets += total_tx_packets;
++ return cleaned;
+ }
+-#endif
+
+ /**
+ * iegbe_rx_checksum - Receive Checksum Offload for 82543
+@@ -3913,192 +3689,193 @@ iegbe_clean_tx_irq(struct iegbe_adapter
+ * @sk_buff: socket buffer with received data
+ **/
+
+-static inline void
+-iegbe_rx_checksum(struct iegbe_adapter *adapter,
+- uint32_t status_err, uint32_t csum,
+- struct sk_buff *skb)
++static void iegbe_rx_checksum(struct iegbe_adapter *adapter, u32 status_err,
++ u32 csum, struct sk_buff *skb)
+ {
+- uint16_t status = (uint16_t)status_err;
+- uint8_t errors = (uint8_t)(status_err >> 0x18);
++ struct iegbe_hw *hw = &adapter->hw;
++ u16 status = (u16)status_err;
++ u8 errors = (u8)(status_err >> 24);
+ skb->ip_summed = CHECKSUM_NONE;
+
+- /* 82543 or newer only */
+- if(unlikely(adapter->hw.mac_type < iegbe_82543)) { return; }
+- /* Ignore Checksum bit is set */
+- if(unlikely(status & E1000_RXD_STAT_IXSM)) { return; }
+- /* TCP/UDP checksum error bit is set */
+- if(unlikely(errors & E1000_RXD_ERR_TCPE)) {
+- /* let the stack verify checksum errors */
+- adapter->hw_csum_err++;
+- return;
+- }
+- /* TCP/UDP Checksum has not been calculated */
+- if(adapter->hw.mac_type <= iegbe_82547_rev_2) {
+- if(!(status & E1000_RXD_STAT_TCPCS)) {
+- return;
++ /* 82543 or newer only */
++ if (unlikely(hw->mac_type < iegbe_82543)) return;
++ /* Ignore Checksum bit is set */
++ if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
++ /* TCP/UDP checksum error bit is set */
++ if(unlikely(errors & E1000_RXD_ERR_TCPE)) {
++ /* let the stack verify checksum errors */
++ adapter->hw_csum_err++;
++ return;
++ }
++ /* TCP/UDP Checksum has not been calculated */
++ if (hw->mac_type <= iegbe_82547_rev_2) {
++ if (!(status & E1000_RXD_STAT_TCPCS))
++ return;
++ } else {
++ if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
++ return;
+ }
+- } else {
+- if(!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))) {
+- return;
+- }
++ /* It must be a TCP or UDP packet with a valid checksum */
++ if(likely(status & E1000_RXD_STAT_TCPCS)) {
++ /* TCP checksum is good */
++ skb->ip_summed = CHECKSUM_UNNECESSARY;
++ } else if (hw->mac_type > iegbe_82547_rev_2) {
++ /* IP fragment with UDP payload */
++ /* Hardware complements the payload checksum, so we undo it
++ * and then put the value in host order for further stack use.
++ */
++ __sum16 sum = (__force __sum16)htons(csum);
++ skb->csum = csum_unfold(~sum);
++ skb->ip_summed = CHECKSUM_COMPLETE;
+ }
+- /* It must be a TCP or UDP packet with a valid checksum */
+- if(likely(status & E1000_RXD_STAT_TCPCS)) {
+- /* TCP checksum is good */
+- skb->ip_summed = CHECKSUM_UNNECESSARY;
+- } else if(adapter->hw.mac_type > iegbe_82547_rev_2) {
+- /* IP fragment with UDP payload */
+- /* Hardware complements the payload checksum, so we undo it
+- * and then put the value in host order for further stack use.
+- */
+- csum = ntohl(csum ^ 0xFFFF);
+- skb->csum = csum;
+- skb->ip_summed = CHECKSUM_HW;
+- }
+- adapter->hw_csum_good++;
++ adapter->hw_csum_good++;
+ }
+
+ /**
+ * iegbe_clean_rx_irq - Send received data up the network stack; legacy
+ * @adapter: board private structure
+ **/
+-
+-static boolean_t
+-#ifdef CONFIG_E1000_NAPI
+-iegbe_clean_rx_irq(struct iegbe_adapter *adapter,
++static bool iegbe_clean_rx_irq(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring,
+ int *work_done, int work_to_do)
+-#else
+-iegbe_clean_rx_irq(struct iegbe_adapter *adapter,
+- struct iegbe_rx_ring *rx_ring)
+-#endif
+ {
+- struct net_device *netdev = adapter->netdev;
+- struct pci_dev *pdev = adapter->pdev;
+- struct iegbe_rx_desc *rx_desc;
+- struct iegbe_buffer *buffer_info;
+- struct sk_buff *skb;
+- unsigned long flags = 0;
+- uint32_t length;
+- uint8_t last_byte;
+- unsigned int i;
+- boolean_t cleaned = FALSE;
+-
+-#ifdef IEGBE_GBE_WORKAROUND
+- /* Need to keep track of the amount of Rx descriptors that we
+- cleaned to ensure that we don't supply too many back to the
+- hardware */
+- int cleaned_count = 0;
+-#endif
+-
+- i = rx_ring->next_to_clean;
+- rx_desc = E1000_RX_DESC(*rx_ring, i);
+-
+- while(rx_desc->status & E1000_RXD_STAT_DD) {
+- buffer_info = &rx_ring->buffer_info[i];
+-#ifdef CONFIG_E1000_NAPI
+- if(*work_done >= work_to_do) {
+- break;
+- }
+- (*work_done)++;
+-#endif
+- cleaned = TRUE;
++ struct iegbe_hw *hw = &adapter->hw;
++ struct net_device *netdev = adapter->netdev;
++ struct pci_dev *pdev = adapter->pdev;
++ struct iegbe_rx_desc *rx_desc, *next_rxd;
++ struct iegbe_buffer *buffer_info, *next_buffer;
++ unsigned long flags;
++ u32 length;
++ u8 last_byte;
++ unsigned int i;
++ int cleaned_count = 0;
++ bool cleaned = false;
++ unsigned int total_rx_bytes=0, total_rx_packets=0;
+
+-#ifdef IEGBE_GBE_WORKAROUND
+- cleaned_count++;
+-#endif
++ i = rx_ring->next_to_clean;
++ rx_desc = E1000_RX_DESC(*rx_ring, i);
++ buffer_info = &rx_ring->buffer_info[i];
+
+- pci_unmap_single(pdev,
+- buffer_info->dma,
+- buffer_info->length,
+- PCI_DMA_FROMDEVICE);
++ while(rx_desc->status & E1000_RXD_STAT_DD) {
++ struct sk_buff *skb;
++ u8 status;
++ if (*work_done >= work_to_do)
++ break;
++ (*work_done)++;
+
++ status = rx_desc->status;
+ skb = buffer_info->skb;
+- length = le16_to_cpu(rx_desc->length);
++ buffer_info->skb = NULL;
++ prefetch(skb->data - NET_IP_ALIGN);
++ if (++i == rx_ring->count) i = 0;
++ next_rxd = E1000_RX_DESC(*rx_ring, i);
++ prefetch(next_rxd);
++ next_buffer = &rx_ring->buffer_info[i];
++ cleaned = true;
++ cleaned_count++;
++ pci_unmap_single(pdev,
++ buffer_info->dma,
++ buffer_info->length,
++ PCI_DMA_FROMDEVICE);
++
++ length = le16_to_cpu(rx_desc->length);
++
++ if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
++ /* All receives must fit into a single buffer */
++ E1000_DBG("%s: Receive packet consumed multiple"
++ " buffers\n", netdev->name);
++ buffer_info->skb = skb;
++ goto next_desc;
++ }
+
+- if(unlikely(!(rx_desc->status & E1000_RXD_STAT_EOP))) {
+- /* All receives must fit into a single buffer */
+- E1000_DBG("%s: Receive packet consumed multiple"
+- " buffers\n", netdev->name);
+- dev_kfree_skb_irq(skb);
+- goto next_desc;
+- }
++ if(unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
++ last_byte = *(skb->data + length - 1);
++ if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
++ last_byte)) {
++ spin_lock_irqsave(&adapter->stats_lock, flags);
++ iegbe_tbi_adjust_stats(hw, &adapter->stats,
++ length, skb->data);
++ spin_unlock_irqrestore(&adapter->stats_lock,
++ flags);
++ length--;
++ } else {
++ buffer_info->skb = skb;
++ goto next_desc;
++ }
++ }
+
+- if(unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
+- last_byte = *(skb->data + length - 0x1);
+- if(TBI_ACCEPT(&adapter->hw, rx_desc->status,
+- rx_desc->errors, length, last_byte)) {
+- spin_lock_irqsave(&adapter->stats_lock, flags);
+- iegbe_tbi_adjust_stats(&adapter->hw,
+- &adapter->stats,
+- length, skb->data);
+- spin_unlock_irqrestore(&adapter->stats_lock,
+- flags);
+- length--;
+- } else {
+- dev_kfree_skb_irq(skb);
+- goto next_desc;
++ /* adjust length to remove Ethernet CRC, this must be
++ * done after the TBI_ACCEPT workaround above */
++ length -= 4;
++
++ /* probably a little skewed due to removing CRC */
++ total_rx_bytes += length;
++ total_rx_packets++;
++
++ /* code added for copybreak, this should improve
++ * performance for small packets with large amounts
++ * of reassembly being done in the stack */
++ if (length < copybreak) {
++ struct sk_buff *new_skb =
++ netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
++ if (new_skb) {
++ skb_reserve(new_skb, NET_IP_ALIGN);
++ skb_copy_to_linear_data_offset(new_skb,
++ -NET_IP_ALIGN,
++ (skb->data -
++ NET_IP_ALIGN),
++ (length +
++ NET_IP_ALIGN));
++ /* save the skb in buffer_info as good */
++ buffer_info->skb = skb;
++ skb = new_skb;
+ }
++ /* else just continue with the old one */
+ }
+-
+- /* Good Receive */
+- skb_put(skb, length - ETHERNET_FCS_SIZE);
++ /* Good Receive */
++ skb_put(skb, length);
+
+ /* Receive Checksum Offload */
+ iegbe_rx_checksum(adapter,
+- (uint32_t)(rx_desc->status) |
+- ((uint32_t)(rx_desc->errors) << 0x18),
+- rx_desc->csum, skb);
++ (u32)(status) |
++ ((u32)(rx_desc->errors) << 24),
++ le16_to_cpu(rx_desc->csum), skb);
++
+ skb->protocol = eth_type_trans(skb, netdev);
+-#ifdef CONFIG_E1000_NAPI
+-#ifdef NETIF_F_HW_VLAN_TX
+- if(unlikely(adapter->vlgrp &&
+- (rx_desc->status & E1000_RXD_STAT_VP))) {
++
++ if (unlikely(adapter->vlgrp &&
++ (status & E1000_RXD_STAT_VP))) {
+ vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+- le16_to_cpu(rx_desc->special) &
+- E1000_RXD_SPC_VLAN_MASK);
++ le16_to_cpu(rx_desc->special));
+ } else {
+ netif_receive_skb(skb);
+ }
+-#else
+- netif_receive_skb(skb);
+-#endif
+-#else /* CONFIG_E1000_NAPI */
+-#ifdef NETIF_F_HW_VLAN_TX
+- if(unlikely(adapter->vlgrp &&
+- (rx_desc->status & E1000_RXD_STAT_VP))) {
+- vlan_hwaccel_rx(skb, adapter->vlgrp,
+- le16_to_cpu(rx_desc->special) &
+- E1000_RXD_SPC_VLAN_MASK);
+- } else {
+- netif_rx(skb);
+- }
+-#else
+- netif_rx(skb);
+-#endif
+-#endif /* CONFIG_E1000_NAPI */
++
+ netdev->last_rx = jiffies;
+- rx_ring->pkt++;
+
+ next_desc:
+ rx_desc->status = 0;
+- buffer_info->skb = NULL;
+- if(unlikely(++i == rx_ring->count)) { i = 0; }
+
+- rx_desc = E1000_RX_DESC(*rx_ring, i);
++ /* return some buffers to hardware, one at a time is too slow */
++ if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
++ adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
++ cleaned_count = 0;
++ }
++
++ /* use prefetched values */
++ rx_desc = next_rxd;
++ buffer_info = next_buffer;
+ }
+ rx_ring->next_to_clean = i;
+
+-#ifdef IEGBE_GBE_WORKAROUND
+- /* Only allocate the number of buffers that we have actually
+- cleaned! */
+- if (cleaned_count) {
+- adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
+- }
+-#else
+- adapter->alloc_rx_buf(adapter, rx_ring);
+-#endif
+-
++ cleaned_count = E1000_DESC_UNUSED(rx_ring);
++ if (cleaned_count)
++ adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
++
++ adapter->total_rx_packets += total_rx_packets;
++ adapter->total_rx_bytes += total_rx_bytes;
++ adapter->net_stats.rx_bytes += total_rx_bytes;
++ adapter->net_stats.rx_packets += total_rx_packets;
+ return cleaned;
+ }
+
+@@ -4107,161 +3884,153 @@ next_desc:
+ * @adapter: board private structure
+ **/
+
+-static boolean_t
+-#ifdef CONFIG_E1000_NAPI
+-iegbe_clean_rx_irq_ps(struct iegbe_adapter *adapter,
++static bool iegbe_clean_rx_irq_ps(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring,
+ int *work_done, int work_to_do)
+-#else
+-iegbe_clean_rx_irq_ps(struct iegbe_adapter *adapter,
+- struct iegbe_rx_ring *rx_ring)
+-#endif
+ {
+- union iegbe_rx_desc_packet_split *rx_desc;
+- struct net_device *netdev = adapter->netdev;
+- struct pci_dev *pdev = adapter->pdev;
+- struct iegbe_buffer *buffer_info;
+- struct iegbe_ps_page *ps_page;
+- struct iegbe_ps_page_dma *ps_page_dma;
+- struct sk_buff *skb;
+- unsigned int i, j;
+- uint32_t length, staterr;
+- boolean_t cleaned = FALSE;
+-
+-#ifdef IEGBE_GBE_WORKAROUND
+- /* Need to keep track of the amount of Rx descriptors that we
+- cleaned to ensure that we don't supply too many back to the
+- hardware */
+- int cleaned_count = 0;
+-#endif
+-
+- i = rx_ring->next_to_clean;
+- rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
+- staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
+-
+- while(staterr & E1000_RXD_STAT_DD) {
+- buffer_info = &rx_ring->buffer_info[i];
+- ps_page = &rx_ring->ps_page[i];
+- ps_page_dma = &rx_ring->ps_page_dma[i];
+-#ifdef CONFIG_E1000_NAPI
+- if(unlikely(*work_done >= work_to_do)) {
+- break;
+- }
+- (*work_done)++;
+-#endif
+- cleaned = TRUE;
+-
+-#ifdef IEGBE_GBE_WORKAROUND
+- cleaned_count++;
+-#endif
++ union iegbe_rx_desc_packet_split *rx_desc, *next_rxd;
++ struct net_device *netdev = adapter->netdev;
++ struct pci_dev *pdev = adapter->pdev;
++ struct iegbe_buffer *buffer_info, *next_buffer;
++ struct iegbe_ps_page *ps_page;
++ struct iegbe_ps_page_dma *ps_page_dma;
++ struct sk_buff *skb;
++ unsigned int i, j;
++ u32 length, staterr;
++ int cleaned_count = 0;
++ bool cleaned = false;
++ unsigned int total_rx_bytes=0, total_rx_packets=0;
++
++ i = rx_ring->next_to_clean;
++ rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
++ staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
++ buffer_info = &rx_ring->buffer_info[i];
+
+- pci_unmap_single(pdev, buffer_info->dma,
+- buffer_info->length,
+- PCI_DMA_FROMDEVICE);
++ while(staterr & E1000_RXD_STAT_DD) {
++ ps_page = &rx_ring->ps_page[i];
++ ps_page_dma = &rx_ring->ps_page_dma[i];
++
++ if (unlikely(*work_done >= work_to_do))
++ break;
++ (*work_done)++;
+
+ skb = buffer_info->skb;
++ prefetch(skb->data - NET_IP_ALIGN);
++ if (++i == rx_ring->count) i = 0;
++ next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
++ prefetch(next_rxd);
++ next_buffer = &rx_ring->buffer_info[i];
++ cleaned = true;
++ cleaned_count++;
++ pci_unmap_single(pdev, buffer_info->dma,
++ buffer_info->length,
++ PCI_DMA_FROMDEVICE);
++
++ if(unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
++ E1000_DBG("%s: Packet Split buffers didn't pick up"
++ " the full packet\n", netdev->name);
++ dev_kfree_skb_irq(skb);
++ goto next_desc;
++ }
+
+- if(unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
+- E1000_DBG("%s: Packet Split buffers didn't pick up"
+- " the full packet\n", netdev->name);
+- dev_kfree_skb_irq(skb);
+- goto next_desc;
+- }
+-
+- if(unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
+- dev_kfree_skb_irq(skb);
+- goto next_desc;
+- }
+-
+- length = le16_to_cpu(rx_desc->wb.middle.length0);
++ if(unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
++ dev_kfree_skb_irq(skb);
++ goto next_desc;
++ }
+
+- if(unlikely(!length)) {
+- E1000_DBG("%s: Last part of the packet spanning"
+- " multiple descriptors\n", netdev->name);
+- dev_kfree_skb_irq(skb);
+- goto next_desc;
+- }
++ length = le16_to_cpu(rx_desc->wb.middle.length0);
+
+- /* Good Receive */
+- skb_put(skb, length);
+-
+- for(j = 0; j < adapter->rx_ps_pages; j++) {
+- if(!(length = le16_to_cpu(rx_desc->wb.upper.length[j]))) {
+- break;
+- }
+- pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
+- PAGE_SIZE, PCI_DMA_FROMDEVICE);
+- ps_page_dma->ps_page_dma[j] = 0;
+- skb_shinfo(skb)->frags[j].page =
+- ps_page->ps_page[j];
+- ps_page->ps_page[j] = NULL;
+- skb_shinfo(skb)->frags[j].page_offset = 0;
+- skb_shinfo(skb)->frags[j].size = length;
+- skb_shinfo(skb)->nr_frags++;
+- skb->len += length;
+- skb->data_len += length;
+- }
++ if(unlikely(!length)) {
++ E1000_DBG("%s: Last part of the packet spanning"
++ " multiple descriptors\n", netdev->name);
++ dev_kfree_skb_irq(skb);
++ goto next_desc;
++ }
+
+- iegbe_rx_checksum(adapter, staterr,
+- rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
+- skb->protocol = eth_type_trans(skb, netdev);
++ /* Good Receive */
++ skb_put(skb, length);
+
+- if(likely(rx_desc->wb.upper.header_status &
+- E1000_RXDPS_HDRSTAT_HDRSP)) {
+- adapter->rx_hdr_split++;
+-#ifdef HAVE_RX_ZERO_COPY
+- skb_shinfo(skb)->zero_copy = TRUE;
+-#endif
+- }
+-#ifdef CONFIG_E1000_NAPI
+-#ifdef NETIF_F_HW_VLAN_TX
+- if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
+- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+- le16_to_cpu(rx_desc->wb.middle.vlan) &
+- E1000_RXD_SPC_VLAN_MASK);
+- } else {
+- netif_receive_skb(skb);
+- }
+-#else
+- netif_receive_skb(skb);
+-#endif
+-#else /* CONFIG_E1000_NAPI */
+-#ifdef NETIF_F_HW_VLAN_TX
+- if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
+- vlan_hwaccel_rx(skb, adapter->vlgrp,
+- le16_to_cpu(rx_desc->wb.middle.vlan) &
+- E1000_RXD_SPC_VLAN_MASK);
+- } else {
+- netif_rx(skb);
+- }
+-#else
+- netif_rx(skb);
+-#endif
+-#endif /* CONFIG_E1000_NAPI */
+- netdev->last_rx = jiffies;
+- rx_ring->pkt++;
++ {
++ int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
++ if (l1 && (l1 <= copybreak) && ((length + l1) <= adapter->rx_ps_bsize0)) {
++ u8 *vaddr;
++ pci_dma_sync_single_for_cpu(pdev,
++ ps_page_dma->ps_page_dma[0],
++ PAGE_SIZE,
++ PCI_DMA_FROMDEVICE);
++ vaddr = kmap_atomic(ps_page->ps_page[0],
++ KM_SKB_DATA_SOFTIRQ);
++ memcpy(skb_tail_pointer(skb), vaddr, l1);
++ kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
++ pci_dma_sync_single_for_device(pdev,
++ ps_page_dma->ps_page_dma[0],
++ PAGE_SIZE, PCI_DMA_FROMDEVICE);
++ l1 -= 4;
++ skb_put(skb, l1);
++ goto copydone;
++ } /* if */
++ }
++ for (j = 0; j < adapter->rx_ps_pages; j++) {
++ length = le16_to_cpu(rx_desc->wb.upper.length[j]);
++ if (!length)
++ break;
++ pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
++ PAGE_SIZE, PCI_DMA_FROMDEVICE);
++ ps_page_dma->ps_page_dma[j] = 0;
++ skb_fill_page_desc(skb, j, ps_page->ps_page[j], 0,
++ length);
++ ps_page->ps_page[j] = NULL;
++ skb->len += length;
++ skb->data_len += length;
++ skb->truesize += length;
++ }
+
+-next_desc:
+- rx_desc->wb.middle.status_error &= ~0xFF;
+- buffer_info->skb = NULL;
+- if(unlikely(++i == rx_ring->count)) { i = 0; }
++ pskb_trim(skb, skb->len - 4);
++copydone:
++ total_rx_bytes += skb->len;
++ total_rx_packets++;
++ iegbe_rx_checksum(adapter, staterr,
++ le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
++ skb->protocol = eth_type_trans(skb, netdev);
++
++ if(likely(rx_desc->wb.upper.header_status &
++ cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)))
++ adapter->rx_hdr_split++;
++
++ if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
++ vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
++ le16_to_cpu(rx_desc->wb.middle.vlan));
++ } else {
++ netif_receive_skb(skb);
++ }
+
+- rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
+- staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
+- }
+- rx_ring->next_to_clean = i;
++ netdev->last_rx = jiffies;
+
+-#ifdef IEGBE_GBE_WORKAROUND
+- /* Only allocate the number of buffers that we have actually
+- cleaned! */
+- if (cleaned_count) {
+- adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
+- }
+-#else
+- adapter->alloc_rx_buf(adapter, rx_ring);
+-#endif
++next_desc:
++ rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
++ buffer_info->skb = NULL;
+
+- return cleaned;
++ if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
++ adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
++ cleaned_count = 0;
++ }
++
++ /* use prefetched values */
++ rx_desc = next_rxd;
++ buffer_info = next_buffer;
++ staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
++ }
++ rx_ring->next_to_clean = i;
++
++ cleaned_count = E1000_DESC_UNUSED(rx_ring);
++ if (cleaned_count)
++ adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
++
++ adapter->total_rx_packets += total_rx_packets;
++ adapter->total_rx_bytes += total_rx_bytes;
++ adapter->net_stats.rx_bytes += total_rx_bytes;
++ adapter->net_stats.rx_packets += total_rx_packets;
++ return cleaned;
+ }
+
+ /**
+@@ -4269,142 +4038,115 @@ next_desc:
+ * @adapter: address of board private structure
+ **/
+
+-#ifdef IEGBE_GBE_WORKAROUND
+-static void
+-iegbe_alloc_rx_buffers(struct iegbe_adapter *adapter,
++
++static void iegbe_alloc_rx_buffers(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring,
+ int cleaned_count)
+-#else
+-static void
+-iegbe_alloc_rx_buffers(struct iegbe_adapter *adapter,
+- struct iegbe_rx_ring *rx_ring)
+-#endif
+ {
+- struct net_device *netdev = adapter->netdev;
+- struct pci_dev *pdev = adapter->pdev;
+- struct iegbe_rx_desc *rx_desc;
+- struct iegbe_buffer *buffer_info;
+- struct sk_buff *skb;
+- unsigned int i;
+- unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
+-
+- i = rx_ring->next_to_use;
+- buffer_info = &rx_ring->buffer_info[i];
++ struct iegbe_hw *hw = &adapter->hw;
++ struct net_device *netdev = adapter->netdev;
++ struct pci_dev *pdev = adapter->pdev;
++ struct iegbe_rx_desc *rx_desc;
++ struct iegbe_buffer *buffer_info;
++ struct sk_buff *skb;
++ unsigned int i;
++ unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
+
+-#ifdef IEGBE_GBE_WORKAROUND
+- if (cleaned_count > IEGBE_GBE_WORKAROUND_NUM_RX_DESCRIPTORS) {
+- adapter->stats.cc_gt_num_rx++;
+- }
+- while(cleaned_count-- && !buffer_info->skb) {
+-#else
+- while(!buffer_info->skb) {
+-#endif
+- skb = dev_alloc_skb(bufsz);
++ i = rx_ring->next_to_use;
++ buffer_info = &rx_ring->buffer_info[i];
+
+- if(unlikely(!skb)) {
+- /* Better luck next round */
+- break;
+- }
++ while (cleaned_count--) {
++ skb = buffer_info->skb;
++ if (skb) {
++ skb_trim(skb, 0);
++ goto map_skb;
++ }
++ skb = netdev_alloc_skb(netdev, bufsz);
++
++ if(unlikely(!skb)) {
++ /* Better luck next round */
++ adapter->alloc_rx_buff_failed++;
++ break;
++ }
+
+- /* Fix for errata 23, can't cross 64kB boundary */
+- if(!iegbe_check_64k_bound(adapter, skb->data, bufsz)) {
+- struct sk_buff *oldskb = skb;
+- DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
+- "at %p\n", bufsz, skb->data);
+- /* Try again, without freeing the previous */
+- skb = dev_alloc_skb(bufsz);
+- /* Failed allocation, critical failure */
+- if(!skb) {
+- dev_kfree_skb(oldskb);
+- break;
+- }
++ /* Fix for errata 23, can't cross 64kB boundary */
++ if(!iegbe_check_64k_bound(adapter, skb->data, bufsz)) {
++ struct sk_buff *oldskb = skb;
++ DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
++ "at %p\n", bufsz, skb->data);
++ /* Try again, without freeing the previous */
++ skb = netdev_alloc_skb(netdev, bufsz);
++ /* Failed allocation, critical failure */
++ if(!skb) {
++ dev_kfree_skb(oldskb);
++ break;
++ }
+
+- if(!iegbe_check_64k_bound(adapter, skb->data, bufsz)) {
+- /* give up */
+- dev_kfree_skb(skb);
+- dev_kfree_skb(oldskb);
+- break; /* while !buffer_info->skb */
+- } else {
+- /* Use new allocation */
+- dev_kfree_skb(oldskb);
++ if(!iegbe_check_64k_bound(adapter, skb->data, bufsz)) {
++ /* give up */
++ dev_kfree_skb(skb);
++ dev_kfree_skb(oldskb);
++ break; /* while !buffer_info->skb */
+ }
+- }
+- /* Make buffer alignment 2 beyond a 16 byte boundary
+- * this will result in a 16 byte aligned IP header after
+- * the 14 byte MAC header is removed
+- */
+- skb_reserve(skb, NET_IP_ALIGN);
+-
+- skb->dev = netdev;
+-
+- buffer_info->skb = skb;
+- buffer_info->length = adapter->rx_buffer_len;
+- buffer_info->dma = pci_map_single(pdev,
+- skb->data,
+- adapter->rx_buffer_len,
+- PCI_DMA_FROMDEVICE);
+-
+- /* Fix for errata 23, can't cross 64kB boundary */
+- if(!iegbe_check_64k_bound(adapter,
+- (void *)(unsigned long)buffer_info->dma,
+- adapter->rx_buffer_len)) {
+- DPRINTK(RX_ERR, ERR,
+- "dma align check failed: %u bytes at %p\n",
+- adapter->rx_buffer_len,
+- (void *)(unsigned long)buffer_info->dma);
+- dev_kfree_skb(skb);
+- buffer_info->skb = NULL;
+-
+- pci_unmap_single(pdev, buffer_info->dma,
+- adapter->rx_buffer_len,
+- PCI_DMA_FROMDEVICE);
+-
+- break; /* while !buffer_info->skb */
+- }
+- rx_desc = E1000_RX_DESC(*rx_ring, i);
+- rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+-
+-#ifdef IEGBE_GBE_WORKAROUND_DISABLED
+- adapter->stats.num_rx_buf_alloc++;
++ /* Use new allocation */
++ dev_kfree_skb(oldskb);
++ }
++ /* Make buffer alignment 2 beyond a 16 byte boundary
++ * this will result in a 16 byte aligned IP header after
++ * the 14 byte MAC header is removed
++ */
++ skb_reserve(skb, NET_IP_ALIGN);
++
++
++ buffer_info->skb = skb;
++ buffer_info->length = adapter->rx_buffer_len;
++map_skb:
++ buffer_info->dma = pci_map_single(pdev,
++ skb->data,
++ adapter->rx_buffer_len,
++ PCI_DMA_FROMDEVICE);
++
++ /* Fix for errata 23, can't cross 64kB boundary */
++ if(!iegbe_check_64k_bound(adapter,
++ (void *)(unsigned long)buffer_info->dma,
++ adapter->rx_buffer_len)) {
++ DPRINTK(RX_ERR, ERR,
++ "dma align check failed: %u bytes at %p\n",
++ adapter->rx_buffer_len,
++ (void *)(unsigned long)buffer_info->dma);
++ dev_kfree_skb(skb);
++ buffer_info->skb = NULL;
++
++ pci_unmap_single(pdev, buffer_info->dma,
++ adapter->rx_buffer_len,
++ PCI_DMA_FROMDEVICE);
+
+- /* Force memory writes to complete before letting h/w
+- * know there are new descriptors to fetch. (Only
+- * applicable for weak-ordered memory model archs,
+- * such as IA-64). */
+- wmb();
+- writel(i, adapter->hw.hw_addr + rx_ring->rdt);
++ break; /* while !buffer_info->skb */
++ }
++ rx_desc = E1000_RX_DESC(*rx_ring, i);
++ rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+
+-#endif
+-#ifndef IEGBE_GBE_WORKAROUND
+- if(unlikely((i & ~(E1000_RX_BUFFER_WRITE - 0x1)) == i)) {
+- /* Force memory writes to complete before letting h/w
+- * know there are new descriptors to fetch. (Only
+- * applicable for weak-ordered memory model archs,
+- * such as IA-64). */
+- wmb();
+- writel(i, adapter->hw.hw_addr + rx_ring->rdt);
+- }
+-#endif
+- if(unlikely(++i == rx_ring->count)) { i = 0; }
+- buffer_info = &rx_ring->buffer_info[i];
+- }
++ /* Force memory writes to complete before letting h/w
++ * know there are new descriptors to fetch. (Only
++ * applicable for weak-ordered memory model archs,
++ * such as IA-64). */
++ if (unlikely(++i == rx_ring->count))
++ i = 0;
++ buffer_info = &rx_ring->buffer_info[i];
++ }
+
+-#ifdef IEGBE_GBE_WORKAROUND
+ if (likely(rx_ring->next_to_use != i)) {
+- rx_ring->next_to_use = i;
+- if (unlikely(i-- == 0)) {
+- i = (rx_ring->count - 0x1);
+- }
++ rx_ring->next_to_use = i;
++ if (unlikely(i-- == 0))
++ i = (rx_ring->count - 1);
++
+ /* Force memory writes to complete before letting h/w
+ * know there are new descriptors to fetch. (Only
+ * applicable for weak-ordered memory model archs,
+ * such as IA-64). */
+ wmb();
+- writel(i, adapter->hw.hw_addr + rx_ring->rdt);
++ writel(i, hw->hw_addr + rx_ring->rdt);
+ }
+-#else
+- rx_ring->next_to_use = i;
+-#endif
+ }
+
+ /**
+@@ -4412,49 +4154,41 @@ iegbe_alloc_rx_buffers(struct iegbe_adap
+ * @adapter: address of board private structure
+ **/
+
+-#ifdef IEGBE_GBE_WORKAROUND
+-static void
+-iegbe_alloc_rx_buffers_ps(struct iegbe_adapter *adapter,
++
++static void iegbe_alloc_rx_buffers_ps(struct iegbe_adapter *adapter,
+ struct iegbe_rx_ring *rx_ring,
+ int cleaned_count)
+-#else
+-static void
+-iegbe_alloc_rx_buffers_ps(struct iegbe_adapter *adapter,
+- struct iegbe_rx_ring *rx_ring)
+-#endif
+ {
+- struct net_device *netdev = adapter->netdev;
+- struct pci_dev *pdev = adapter->pdev;
+- union iegbe_rx_desc_packet_split *rx_desc;
+- struct iegbe_buffer *buffer_info;
+- struct iegbe_ps_page *ps_page;
+- struct iegbe_ps_page_dma *ps_page_dma;
+- struct sk_buff *skb;
+- unsigned int i, j;
+-
+- i = rx_ring->next_to_use;
+- buffer_info = &rx_ring->buffer_info[i];
+- ps_page = &rx_ring->ps_page[i];
+- ps_page_dma = &rx_ring->ps_page_dma[i];
++ struct iegbe_hw *hw = &adapter->hw;
++ struct net_device *netdev = adapter->netdev;
++ struct pci_dev *pdev = adapter->pdev;
++ union iegbe_rx_desc_packet_split *rx_desc;
++ struct iegbe_buffer *buffer_info;
++ struct iegbe_ps_page *ps_page;
++ struct iegbe_ps_page_dma *ps_page_dma;
++ struct sk_buff *skb;
++ unsigned int i, j;
++
++ i = rx_ring->next_to_use;
++ buffer_info = &rx_ring->buffer_info[i];
++ ps_page = &rx_ring->ps_page[i];
++ ps_page_dma = &rx_ring->ps_page_dma[i];
+
+-#ifdef IEGBE_GBE_WORKAROUND
+- while(cleaned_count-- && !buffer_info->skb) {
+-#else
+- while(!buffer_info->skb) {
+-#endif
+- rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
++ while (cleaned_count--) {
++ rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
+
+ for (j = 0; j < PS_PAGE_BUFFERS; j++) {
+- if (j < adapter->rx_ps_pages) {
+- if (likely(!ps_page->ps_page[j])) {
+- ps_page->ps_page[j] =
+- alloc_page(GFP_ATOMIC);
++ if (j < adapter->rx_ps_pages) {
++ if (likely(!ps_page->ps_page[j])) {
++ ps_page->ps_page[j] =
++ alloc_page(GFP_ATOMIC);
+ if (unlikely(!ps_page->ps_page[j])) {
+- goto no_buffers;
++ adapter->alloc_rx_buff_failed++;
++ goto no_buffers;
+ }
+- ps_page_dma->ps_page_dma[j] =
+- pci_map_page(pdev,
+- ps_page->ps_page[j],
++ ps_page_dma->ps_page_dma[j] =
++ pci_map_page(pdev,
++ ps_page->ps_page[j],
+ 0, PAGE_SIZE,
+ PCI_DMA_FROMDEVICE);
+ }
+@@ -4462,26 +4196,26 @@ iegbe_alloc_rx_buffers_ps(struct iegbe_a
+ * change because each write-back erases
+ * this info.
+ */
+- rx_desc->read.buffer_addr[j+0x1] =
++ rx_desc->read.buffer_addr[j+1] =
+ cpu_to_le64(ps_page_dma->ps_page_dma[j]);
+- } else {
+- rx_desc->read.buffer_addr[j+0x1] = ~0;
+- }
++ } else
++ rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
+ }
+
+- skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN);
++ skb = netdev_alloc_skb(netdev,
++ adapter->rx_ps_bsize0 + NET_IP_ALIGN);
+
+- if (unlikely(!skb)) {
++ if (unlikely(!skb)) {
++ adapter->alloc_rx_buff_failed++;
+ break;
+- }
++ }
++
+ /* Make buffer alignment 2 beyond a 16 byte boundary
+ * this will result in a 16 byte aligned IP header after
+ * the 14 byte MAC header is removed
+ */
+ skb_reserve(skb, NET_IP_ALIGN);
+
+- skb->dev = netdev;
+-
+ buffer_info->skb = skb;
+ buffer_info->length = adapter->rx_ps_bsize0;
+ buffer_info->dma = pci_map_single(pdev, skb->data,
+@@ -4490,27 +4224,28 @@ iegbe_alloc_rx_buffers_ps(struct iegbe_a
+
+ rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
+
+- if (unlikely((i & ~(E1000_RX_BUFFER_WRITE - 0x1)) == i)) {
+- /* Force memory writes to complete before letting h/w
+- * know there are new descriptors to fetch. (Only
+- * applicable for weak-ordered memory model archs,
+- * such as IA-64). */
+- wmb();
+- /* Hardware increments by 16 bytes, but packet split
+- * descriptors are 32 bytes...so we increment tail
+- * twice as much.
+- */
+- writel(i<<1, adapter->hw.hw_addr + rx_ring->rdt);
+- }
+-
+- if (unlikely(++i == rx_ring->count)) { i = 0; }
++ if (unlikely(++i == rx_ring->count)) i = 0;
+ buffer_info = &rx_ring->buffer_info[i];
+ ps_page = &rx_ring->ps_page[i];
+ ps_page_dma = &rx_ring->ps_page_dma[i];
+ }
+
+ no_buffers:
+- rx_ring->next_to_use = i;
++ if (likely(rx_ring->next_to_use != i)) {
++ rx_ring->next_to_use = i;
++ if (unlikely(i-- == 0)) i = (rx_ring->count - 1);
++
++ /* Force memory writes to complete before letting h/w
++ * know there are new descriptors to fetch. (Only
++ * applicable for weak-ordered memory model archs,
++ * such as IA-64). */
++ wmb();
++ /* Hardware increments by 16 bytes, but packet split
++ * descriptors are 32 bytes...so we increment tail
++ * twice as much.
++ */
++ writel(i<<1, hw->hw_addr + rx_ring->rdt);
++ }
+ }
+
+ /**
+@@ -4521,52 +4256,52 @@ no_buffers:
+ static void
+ iegbe_smartspeed(struct iegbe_adapter *adapter)
+ {
+- uint16_t phy_status;
+- uint16_t phy_ctrl;
++ uint16_t phy_status;
++ uint16_t phy_ctrl;
+
+- if((adapter->hw.phy_type != iegbe_phy_igp) || !adapter->hw.autoneg ||
++ if((adapter->hw.phy_type != iegbe_phy_igp) || !adapter->hw.autoneg ||
+ !(adapter->hw.autoneg_advertised & ADVERTISE_1000_FULL)) {
+- return;
++ return;
+ }
+- if(adapter->smartspeed == 0) {
+- /* If Master/Slave config fault is asserted twice,
+- * we assume back-to-back */
+- iegbe_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
++ if(adapter->smartspeed == 0x0) {
++ /* If Master/Slave config fault is asserted twice,
++ * we assume back-to-back */
++ iegbe_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
+ if(!(phy_status & SR_1000T_MS_CONFIG_FAULT)) { return; }
+- iegbe_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
++ iegbe_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
+ if(!(phy_status & SR_1000T_MS_CONFIG_FAULT)) { return; }
+- iegbe_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
+- if(phy_ctrl & CR_1000T_MS_ENABLE) {
+- phy_ctrl &= ~CR_1000T_MS_ENABLE;
+- iegbe_write_phy_reg(&adapter->hw, PHY_1000T_CTRL,
+- phy_ctrl);
+- adapter->smartspeed++;
+- if(!iegbe_phy_setup_autoneg(&adapter->hw) &&
+- !iegbe_read_phy_reg(&adapter->hw, PHY_CTRL,
+- &phy_ctrl)) {
+- phy_ctrl |= (MII_CR_AUTO_NEG_EN |
+- MII_CR_RESTART_AUTO_NEG);
+- iegbe_write_phy_reg(&adapter->hw, PHY_CTRL,
+- phy_ctrl);
+- }
+- }
+- return;
+- } else if(adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
+- /* If still no link, perhaps using 2/3 pair cable */
+- iegbe_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
+- phy_ctrl |= CR_1000T_MS_ENABLE;
+- iegbe_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_ctrl);
+- if(!iegbe_phy_setup_autoneg(&adapter->hw) &&
+- !iegbe_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_ctrl)) {
+- phy_ctrl |= (MII_CR_AUTO_NEG_EN |
+- MII_CR_RESTART_AUTO_NEG);
+- iegbe_write_phy_reg(&adapter->hw, PHY_CTRL, phy_ctrl);
+- }
+- }
+- /* Restart process after E1000_SMARTSPEED_MAX iterations */
++ iegbe_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
++ if(phy_ctrl & CR_1000T_MS_ENABLE) {
++ phy_ctrl &= ~CR_1000T_MS_ENABLE;
++ iegbe_write_phy_reg(&adapter->hw, PHY_1000T_CTRL,
++ phy_ctrl);
++ adapter->smartspeed++;
++ if(!iegbe_phy_setup_autoneg(&adapter->hw) &&
++ !iegbe_read_phy_reg(&adapter->hw, PHY_CTRL,
++ &phy_ctrl)) {
++ phy_ctrl |= (MII_CR_AUTO_NEG_EN |
++ MII_CR_RESTART_AUTO_NEG);
++ iegbe_write_phy_reg(&adapter->hw, PHY_CTRL,
++ phy_ctrl);
++ }
++ }
++ return;
++ } else if(adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
++ /* If still no link, perhaps using 2/3 pair cable */
++ iegbe_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
++ phy_ctrl |= CR_1000T_MS_ENABLE;
++ iegbe_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_ctrl);
++ if(!iegbe_phy_setup_autoneg(&adapter->hw) &&
++ !iegbe_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_ctrl)) {
++ phy_ctrl |= (MII_CR_AUTO_NEG_EN |
++ MII_CR_RESTART_AUTO_NEG);
++ iegbe_write_phy_reg(&adapter->hw, PHY_CTRL, phy_ctrl);
++ }
++ }
++ /* Restart process after E1000_SMARTSPEED_MAX iterations */
+ if(adapter->smartspeed++ == E1000_SMARTSPEED_MAX) {
+- adapter->smartspeed = 0;
+-}
++ adapter->smartspeed = 0x0;
++ }
+ }
+
+ /**
+@@ -4576,23 +4311,22 @@ iegbe_smartspeed(struct iegbe_adapter *a
+ * @cmd:
+ **/
+
+-static int
+-iegbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
++static int iegbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+ {
+- switch (cmd) {
++ switch (cmd) {
+ #ifdef SIOCGMIIPHY
+- case SIOCGMIIPHY:
+- case SIOCGMIIREG:
+- case SIOCSMIIREG:
+- return iegbe_mii_ioctl(netdev, ifr, cmd);
++ case SIOCGMIIPHY:
++ case SIOCGMIIREG:
++ case SIOCSMIIREG:
++ return iegbe_mii_ioctl(netdev, ifr, cmd);
+ #endif
+ #ifdef ETHTOOL_OPS_COMPAT
+- case SIOCETHTOOL:
+- return ethtool_ioctl(ifr);
++ case SIOCETHTOOL:
++ return ethtool_ioctl(ifr);
+ #endif
+- default:
+- return -EOPNOTSUPP;
+- }
++ default:
++ return -EOPNOTSUPP;
++ }
+ }
+
+ #ifdef SIOCGMIIPHY
+@@ -4603,534 +4337,510 @@ iegbe_ioctl(struct net_device *netdev, s
+ * @cmd:
+ **/
+
+-static int
+-iegbe_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
++static int iegbe_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
++ int cmd)
+ {
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+- struct mii_ioctl_data *data = if_mii(ifr);
+- int retval;
+- uint16_t mii_reg;
+- uint16_t spddplx;
+- unsigned long flags;
+-
+- if((adapter->hw.media_type == iegbe_media_type_oem &&
+- !iegbe_oem_phy_is_copper(&adapter->hw)) ||
+- adapter->hw.media_type == iegbe_media_type_fiber ||
+- adapter->hw.media_type == iegbe_media_type_internal_serdes ) {
+- return -EOPNOTSUPP;
+- }
+- switch (cmd) {
+- case SIOCGMIIPHY:
+- data->phy_id = adapter->hw.phy_addr;
+- break;
+- case SIOCGMIIREG:
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ struct mii_ioctl_data *data = if_mii(ifr);
++ int retval;
++ uint16_t mii_reg;
++ uint16_t spddplx;
++ unsigned long flags = 0;
++
++ if((adapter->hw.media_type == iegbe_media_type_oem
++ && !iegbe_oem_phy_is_copper(&adapter->hw))
++ ||adapter->hw.media_type != iegbe_media_type_copper) {
++ return -EOPNOTSUPP;
++ }
++ switch (cmd) {
++ case SIOCGMIIPHY:
++ data->phy_id = adapter->hw.phy_addr;
++ break;
++ case SIOCGMIIREG:
+ if(!capable(CAP_NET_ADMIN)) {
+- return -EPERM;
++ return -EPERM;
+ }
+- spin_lock_irqsave(&adapter->stats_lock, flags);
+- if(iegbe_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+- &data->val_out)) {
+- spin_unlock_irqrestore(&adapter->stats_lock, flags);
+- return -EIO;
+- }
+- spin_unlock_irqrestore(&adapter->stats_lock, flags);
+- break;
+- case SIOCSMIIREG:
++ spin_lock_irqsave(&adapter->stats_lock, flags);
++ if(iegbe_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
++ &data->val_out)) {
++ spin_unlock_irqrestore(&adapter->stats_lock, flags);
++ return -EIO;
++ }
++ spin_unlock_irqrestore(&adapter->stats_lock, flags);
++ break;
++ case SIOCSMIIREG:
+ if(!capable(CAP_NET_ADMIN)){
+- return -EPERM;
++ return -EPERM;
+ }
+ if(data->reg_num & ~(0x1F)) {
+- return -EFAULT;
++ return -EFAULT;
+ }
+- mii_reg = data->val_in;
+- spin_lock_irqsave(&adapter->stats_lock, flags);
+- if(iegbe_write_phy_reg(&adapter->hw, data->reg_num,
+- mii_reg)) {
+- spin_unlock_irqrestore(&adapter->stats_lock, flags);
+- return -EIO;
+- }
+- switch(adapter->hw.phy_type) {
+- case iegbe_phy_m88:
+- switch (data->reg_num) {
+- case PHY_CTRL:
++ mii_reg = data->val_in;
++ spin_lock_irqsave(&adapter->stats_lock, flags);
++ if(iegbe_write_phy_reg(&adapter->hw, data->reg_num,
++ mii_reg)) {
++ spin_unlock_irqrestore(&adapter->stats_lock, flags);
++ return -EIO;
++ }
++ switch(adapter->hw.phy_type) {
++ case iegbe_phy_m88:
++ switch (data->reg_num) {
++ case PHY_CTRL:
+ if(mii_reg & MII_CR_POWER_DOWN) {
+- break;
++ break;
+ }
+- if(mii_reg & MII_CR_AUTO_NEG_EN) {
+- adapter->hw.autoneg = 1;
+- adapter->hw.autoneg_advertised = 0x2F;
+- } else {
++ if(mii_reg & MII_CR_AUTO_NEG_EN) {
++ adapter->hw.autoneg = 1;
++ adapter->hw.autoneg_advertised = 0x2F;
++ } else {
+ if(mii_reg & 0x40){
+- spddplx = SPEED_1000;
++ spddplx = SPEED_1000;
+ } else if(mii_reg & 0x2000) {
+- spddplx = SPEED_100;
++ spddplx = SPEED_100;
+ } else {
+- spddplx = SPEED_10;
++ spddplx = SPEED_10;
+ }
+- spddplx += (mii_reg & 0x100)
+- ? FULL_DUPLEX :
+- HALF_DUPLEX;
+- retval = iegbe_set_spd_dplx(adapter,
+- spddplx);
+- if(retval) {
+- spin_unlock_irqrestore(
+- &adapter->stats_lock,
+- flags);
+- return retval;
+- }
+- }
+- if(netif_running(adapter->netdev)) {
+- iegbe_down(adapter);
+- iegbe_up(adapter);
++ spddplx += (mii_reg & 0x100)
++ ? FULL_DUPLEX :
++ HALF_DUPLEX;
++ retval = iegbe_set_spd_dplx(adapter,
++ spddplx);
++ if(retval) {
++ spin_unlock_irqrestore(
++ &adapter->stats_lock,
++ flags);
++ return retval;
++ }
++ }
++ if(netif_running(adapter->netdev)) {
++ iegbe_down(adapter);
++ iegbe_up(adapter);
+ } else {
+- iegbe_reset(adapter);
++ iegbe_reset(adapter);
+ }
+- break;
+- case M88E1000_PHY_SPEC_CTRL:
+- case M88E1000_EXT_PHY_SPEC_CTRL:
+- if(iegbe_phy_reset(&adapter->hw)) {
+- spin_unlock_irqrestore(
+- &adapter->stats_lock, flags);
+- return -EIO;
+- }
+- break;
+- }
+- break;
++ break;
++ case M88E1000_PHY_SPEC_CTRL:
++ case M88E1000_EXT_PHY_SPEC_CTRL:
++ if(iegbe_phy_reset(&adapter->hw)) {
++ spin_unlock_irqrestore(
++ &adapter->stats_lock, flags);
++ return -EIO;
++ }
++ break;
++ }
++ break;
+
+- case iegbe_phy_oem:
+- retval = iegbe_oem_mii_ioctl(adapter, flags, ifr, cmd);
+- if(retval) {
+- spin_unlock_irqrestore(
+- &adapter->stats_lock, flags);
+- return retval;
+- }
+- break;
++ case iegbe_phy_oem:
++ retval = iegbe_oem_mii_ioctl(adapter, flags, ifr, cmd);
++ if(retval) {
++ spin_unlock_irqrestore(
++ &adapter->stats_lock, flags);
++ return retval;
++ }
++ break;
+
+- default:
+- switch (data->reg_num) {
+- case PHY_CTRL:
++ default:
++ switch (data->reg_num) {
++ case PHY_CTRL:
+ if(mii_reg & MII_CR_POWER_DOWN) {
+- break;
++ break;
+ }
+- if(netif_running(adapter->netdev)) {
+- iegbe_down(adapter);
+- iegbe_up(adapter);
++ if(netif_running(adapter->netdev)) {
++ iegbe_down(adapter);
++ iegbe_up(adapter);
+ } else {
+- iegbe_reset(adapter);
++ iegbe_reset(adapter);
+ }
+- break;
+- }
+- }
+- spin_unlock_irqrestore(&adapter->stats_lock, flags);
+- break;
+- default:
+- return -EOPNOTSUPP;
+- }
+- return E1000_SUCCESS;
++ break;
++ }
++ }
++ spin_unlock_irqrestore(&adapter->stats_lock, flags);
++ break;
++ default:
++ return -EOPNOTSUPP;
++ }
++ return E1000_SUCCESS;
+ }
+ #endif
+
+-void
+-iegbe_pci_set_mwi(struct iegbe_hw *hw)
++void iegbe_pci_set_mwi(struct iegbe_hw *hw)
+ {
+- struct iegbe_adapter *adapter = hw->back;
+-#ifdef HAVE_PCI_SET_MWI
+- int ret_val = pci_set_mwi(adapter->pdev);
+-
+- if(ret_val) {
+- DPRINTK(PROBE, ERR, "Error in setting MWI\n");
+- }
+-#else
+- pci_write_config_word(adapter->pdev, PCI_COMMAND,
+- adapter->hw.pci_cmd_word |
+- PCI_COMMAND_INVALIDATE);
+-#endif
++ struct iegbe_adapter *adapter = hw->back;
++ int ret_val = pci_set_mwi(adapter->pdev);
++
++ if (ret_val)
++ DPRINTK(PROBE, ERR, "Error in setting MWI\n");
+ }
+
+-void
+-iegbe_pci_clear_mwi(struct iegbe_hw *hw)
++void iegbe_pci_clear_mwi(struct iegbe_hw *hw)
+ {
+- struct iegbe_adapter *adapter = hw->back;
++ struct iegbe_adapter *adapter = hw->back;
+
+-#ifdef HAVE_PCI_SET_MWI
+- pci_clear_mwi(adapter->pdev);
+-#else
+- pci_write_config_word(adapter->pdev, PCI_COMMAND,
+- adapter->hw.pci_cmd_word &
+- ~PCI_COMMAND_INVALIDATE);
+-#endif
++ pci_clear_mwi(adapter->pdev);
+ }
+
+ void
+ iegbe_read_pci_cfg(struct iegbe_hw *hw, uint32_t reg, uint16_t *value)
+ {
+- struct iegbe_adapter *adapter = hw->back;
++ struct iegbe_adapter *adapter = hw->back;
+
+- pci_read_config_word(adapter->pdev, reg, value);
++ pci_read_config_word(adapter->pdev, reg, value);
+ }
+
+ void
+ iegbe_write_pci_cfg(struct iegbe_hw *hw, uint32_t reg, uint16_t *value)
+ {
+- struct iegbe_adapter *adapter = hw->back;
++ struct iegbe_adapter *adapter = hw->back;
+
+- pci_write_config_word(adapter->pdev, reg, *value);
++ pci_write_config_word(adapter->pdev, reg, *value);
+ }
+
+ uint32_t
+ iegbe_io_read(struct iegbe_hw *hw, unsigned long port)
+ {
+- return inl(port);
++ return inl(port);
+ }
+
+ void
+ iegbe_io_write(struct iegbe_hw *hw, unsigned long port, uint32_t value)
+ {
+- outl(value, port);
++ outl(value, port);
+ }
+
+-#ifdef NETIF_F_HW_VLAN_TX
+-static void
+-iegbe_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
++static void iegbe_vlan_rx_register(struct net_device *netdev,
++ struct vlan_group *grp)
+ {
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+- uint32_t ctrl, rctl;
+-
+- iegbe_irq_disable(adapter);
+- adapter->vlgrp = grp;
+-
+- if(grp) {
+- /* enable VLAN tag insert/strip */
+- ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+- ctrl |= E1000_CTRL_VME;
+- E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+-
+- /* enable VLAN receive filtering */
+- rctl = E1000_READ_REG(&adapter->hw, RCTL);
+- rctl |= E1000_RCTL_VFE;
+- rctl &= ~E1000_RCTL_CFIEN;
+- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+- iegbe_update_mng_vlan(adapter);
+- } else {
+- /* disable VLAN tag insert/strip */
+- ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+- ctrl &= ~E1000_CTRL_VME;
+- E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ uint32_t ctrl, rctl;
+
+- /* disable VLAN filtering */
+- rctl = E1000_READ_REG(&adapter->hw, RCTL);
+- rctl &= ~E1000_RCTL_VFE;
+- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+- if(adapter->mng_vlan_id != (uint16_t)E1000_MNG_VLAN_NONE) {
+- iegbe_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
+- adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
+- }
+- }
++ if (!test_bit(__E1000_DOWN, &adapter->flags))
++ iegbe_irq_disable(adapter);
++ adapter->vlgrp = grp;
++
++ if(grp) {
++ /* enable VLAN tag insert/strip */
++ ctrl = E1000_READ_REG(&adapter->hw, CTRL);
++ ctrl |= E1000_CTRL_VME;
++ E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
++
++ /* enable VLAN receive filtering */
++ rctl = E1000_READ_REG(&adapter->hw, RCTL);
++ rctl |= E1000_RCTL_VFE;
++ rctl &= ~E1000_RCTL_CFIEN;
++ E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
++ iegbe_update_mng_vlan(adapter);
++ } else {
++ /* disable VLAN tag insert/strip */
++ ctrl = E1000_READ_REG(&adapter->hw, CTRL);
++ ctrl &= ~E1000_CTRL_VME;
++ E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
++
++ /* disable VLAN filtering */
++ rctl = E1000_READ_REG(&adapter->hw, RCTL);
++ rctl &= ~E1000_RCTL_VFE;
++ E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
++ if(adapter->mng_vlan_id != (uint16_t)E1000_MNG_VLAN_NONE) {
++ iegbe_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
++ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
++ }
++ }
+
+- iegbe_irq_enable(adapter);
++ if (!test_bit(__E1000_DOWN, &adapter->flags))
++ iegbe_irq_enable(adapter);
+ }
+
+-static void
+-iegbe_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
++static void iegbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+ {
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+- uint32_t vfta, index;
+- if((adapter->hw.mng_cookie.status &
+- E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ uint32_t vfta, index;
++ if((adapter->hw.mng_cookie.status &
++ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+ (vid == adapter->mng_vlan_id)) {
+- return;
++ return;
+ }
+- /* add VID to filter table */
++ /* add VID to filter table */
+ index = (vid >> 0x5) & 0x7F;
+- vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
++ vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
+ vfta |= (0x1 << (vid & 0x1F));
+- iegbe_write_vfta(&adapter->hw, index, vfta);
++ iegbe_write_vfta(&adapter->hw, index, vfta);
+ }
+
+-static void
+-iegbe_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
++static void iegbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+ {
+ struct iegbe_adapter *adapter = netdev_priv(netdev);
+- uint32_t vfta, index;
++ u32 vfta, index;
+
++ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ iegbe_irq_disable(adapter);
+-
+- if(adapter->vlgrp) {
+- adapter->vlgrp->vlan_devices[vid] = NULL;
+- }
++ vlan_group_set_device(adapter->vlgrp, vid, NULL);
++ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ iegbe_irq_enable(adapter);
+
+- if((adapter->hw.mng_cookie.status &
+- E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+- (vid == adapter->mng_vlan_id)) {
+- return;
+- }
+ /* remove VID from filter table */
+- index = (vid >> 0x5) & 0x7F;
++ index = (vid >> 0x5) & 0x7F;
+ vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
+- vfta &= ~(0x1 << (vid & 0x1F));
++ vfta &= ~(0x1 << (vid & 0x1F));
+ iegbe_write_vfta(&adapter->hw, index, vfta);
+ }
+
+-static void
+-iegbe_restore_vlan(struct iegbe_adapter *adapter)
++static void iegbe_restore_vlan(struct iegbe_adapter *adapter)
+ {
+ iegbe_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+
+- if(adapter->vlgrp) {
+- uint16_t vid;
+- for(vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+- if(!adapter->vlgrp->vlan_devices[vid]) {
++ if (adapter->vlgrp) {
++ u16 vid;
++ for (vid = 0x0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
++ if (!vlan_group_get_device(adapter->vlgrp, vid))
+ continue;
+- }
+ iegbe_vlan_rx_add_vid(adapter->netdev, vid);
+ }
+ }
+ }
+-#endif
+
+-int
+-iegbe_set_spd_dplx(struct iegbe_adapter *adapter, uint16_t spddplx)
++
++int iegbe_set_spd_dplx(struct iegbe_adapter *adapter, u16 spddplx)
+ {
+- adapter->hw.autoneg = 0;
++ adapter->hw.autoneg = 0x0;
+
+- /* Fiber NICs only allow 1000 gbps Full duplex */
+- if((adapter->hw.media_type == iegbe_media_type_fiber
++ /* Fiber NICs only allow 1000 gbps Full duplex */
++ if((adapter->hw.media_type == iegbe_media_type_fiber
+ || (adapter->hw.media_type == iegbe_media_type_oem
+ && !iegbe_oem_phy_is_copper(&adapter->hw)))
+- && spddplx != (SPEED_1000 + FULL_DUPLEX)) {
+- DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
+- return -EINVAL;
+- }
+-
+- switch(spddplx) {
+- case SPEED_10 + HALF_DUPLEX:
+- adapter->hw.forced_speed_duplex = iegbe_10_half;
+- break;
+- case SPEED_10 + FULL_DUPLEX:
+- adapter->hw.forced_speed_duplex = iegbe_10_full;
+- break;
+- case SPEED_100 + HALF_DUPLEX:
+- adapter->hw.forced_speed_duplex = iegbe_100_half;
+- break;
+- case SPEED_100 + FULL_DUPLEX:
+- adapter->hw.forced_speed_duplex = iegbe_100_full;
+- break;
+- case SPEED_1000 + FULL_DUPLEX:
++ && spddplx != (SPEED_1000 + DUPLEX_FULL)) {
++ DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
++ return -EINVAL;
++ }
++
++ switch(spddplx) {
++ case SPEED_10 + DUPLEX_HALF:
++ adapter->hw.forced_speed_duplex = iegbe_10_half;
++ break;
++ case SPEED_10 + DUPLEX_FULL:
++ adapter->hw.forced_speed_duplex = iegbe_10_full;
++ break;
++ case SPEED_100 + DUPLEX_HALF:
++ adapter->hw.forced_speed_duplex = iegbe_100_half;
++ break;
++ case SPEED_100 + DUPLEX_FULL:
++ adapter->hw.forced_speed_duplex = iegbe_100_full;
++ break;
++ case SPEED_1000 + DUPLEX_FULL:
+ adapter->hw.autoneg = 0x1;
+- adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
+- break;
+- case SPEED_1000 + HALF_DUPLEX: /* not supported */
+- default:
+- DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
+- return -EINVAL;
+- }
+- return 0;
++ adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
++ break;
++ case SPEED_1000 + DUPLEX_HALF: /* not supported */
++ default:
++ DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
++ return -EINVAL;
++ }
++ return 0x0;
+ }
+
+ static int
+ iegbe_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
+ {
+- struct pci_dev *pdev = NULL;
++ struct pci_dev *pdev = NULL;
+ pm_message_t state = {0x3};
+
+
+- switch(event) {
+- case SYS_DOWN:
+- case SYS_HALT:
+- case SYS_POWER_OFF:
+- while((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
++ switch(event) {
++ case SYS_DOWN:
++ case SYS_HALT:
++ case SYS_POWER_OFF:
++ while((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
+ if(pci_dev_driver(pdev) == &iegbe_driver) {
+- iegbe_suspend(pdev, state);
+- }
+- }
++ iegbe_suspend(pdev, state);
++ }
++ }
+ }
+- return NOTIFY_DONE;
++ return NOTIFY_DONE;
+ }
+
+ static int
+ iegbe_suspend(struct pci_dev *pdev, pm_message_t state)
+ {
+- struct net_device *netdev = pci_get_drvdata(pdev);
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+- uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm;
+- uint32_t wufc = adapter->wol;
+- uint16_t cmd_word;
++ struct net_device *netdev = pci_get_drvdata(pdev);
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm;
++ uint32_t wufc = adapter->wol;
++ uint16_t cmd_word;
+
+- netif_device_detach(netdev);
++ netif_device_detach(netdev);
+
+ if(netif_running(netdev)) {
+- iegbe_down(adapter);
++ WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
++ iegbe_down(adapter);
+ }
+- /*
+- * ICP_XXXX style MACs do not have a link up bit in
+- * the STATUS register, query the PHY directly
+- */
+- if(adapter->hw.mac_type != iegbe_icp_xxxx) {
+- status = E1000_READ_REG(&adapter->hw, STATUS);
++ /*
++ * ICP_XXXX style MACs do not have a link up bit in
++ * the STATUS register, query the PHY directly
++ */
++ if(adapter->hw.mac_type != iegbe_icp_xxxx) {
++ status = E1000_READ_REG(&adapter->hw, STATUS);
+ if(status & E1000_STATUS_LU) {
+- wufc &= ~E1000_WUFC_LNKC;
++ wufc &= ~E1000_WUFC_LNKC;
+ }
+- } else {
+- int isUp = 0;
++ } else {
++ int isUp = 0x0;
+ if(iegbe_oem_phy_is_link_up(&adapter->hw, &isUp) != E1000_SUCCESS) {
+- isUp = 0;
++ isUp = 0x0;
+ }
+ if(isUp) {
+- wufc &= ~E1000_WUFC_LNKC;
+- }
++ wufc &= ~E1000_WUFC_LNKC;
++ }
+ }
+
+- if(wufc) {
+- iegbe_setup_rctl(adapter);
+- iegbe_set_multi(netdev);
+-
+- /* turn on all-multi mode if wake on multicast is enabled */
+- if(adapter->wol & E1000_WUFC_MC) {
+- rctl = E1000_READ_REG(&adapter->hw, RCTL);
+- rctl |= E1000_RCTL_MPE;
+- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+- }
++ if(wufc) {
++ iegbe_setup_rctl(adapter);
++ iegbe_set_rx_mode(netdev);
++
++ /* turn on all-multi mode if wake on multicast is enabled */
++ if(adapter->wol & E1000_WUFC_MC) {
++ rctl = E1000_READ_REG(&adapter->hw, RCTL);
++ rctl |= E1000_RCTL_MPE;
++ E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
++ }
+
+- if(adapter->hw.mac_type >= iegbe_82540) {
+- ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+- /* advertise wake from D3Cold */
+- #define E1000_CTRL_ADVD3WUC 0x00100000
+- /* phy power management enable */
+- ctrl |= E1000_CTRL_ADVD3WUC |
+- (adapter->hw.mac_type != iegbe_icp_xxxx
+- ? E1000_CTRL_EN_PHY_PWR_MGMT : 0);
++ if(adapter->hw.mac_type >= iegbe_82540) {
++ ctrl = E1000_READ_REG(&adapter->hw, CTRL);
++ /* advertise wake from D3Cold */
++ #define E1000_CTRL_ADVD3WUC 0x00100000
++ /* phy power management enable */
++ #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
++ ctrl |= E1000_CTRL_ADVD3WUC |
++ (adapter->hw.mac_type != iegbe_icp_xxxx
++ ? E1000_CTRL_EN_PHY_PWR_MGMT : 0x0);
+
+- E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+- }
++ E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
++ }
+
+- if(adapter->hw.media_type == iegbe_media_type_fiber ||
+- adapter->hw.media_type == iegbe_media_type_internal_serdes) {
+- /* keep the laser running in D3 */
+- ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+- ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
+- E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext);
+- }
++ if(adapter->hw.media_type == iegbe_media_type_fiber ||
++ adapter->hw.media_type == iegbe_media_type_internal_serdes) {
++ /* keep the laser running in D3 */
++ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
++ ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
++ E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext);
++ }
+
+ /* Allow OEM PHYs (if any exist) to keep the laser
+ *running in D3 */
+ iegbe_oem_fiber_live_in_suspend(&adapter->hw);
+
+- /* Allow time for pending master requests to run */
+- iegbe_disable_pciex_master(&adapter->hw);
++ /* Allow time for pending master requests to run */
++ iegbe_disable_pciex_master(&adapter->hw);
+
+- E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
+- E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
++ E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
++ E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
+ pci_enable_wake(pdev, 0x3, 0x1);
+ pci_enable_wake(pdev, 0x4, 0x1); /* 4 == D3 cold */
+- } else {
+- E1000_WRITE_REG(&adapter->hw, WUC, 0);
+- E1000_WRITE_REG(&adapter->hw, WUFC, 0);
+- pci_enable_wake(pdev, 0x3, 0);
+- pci_enable_wake(pdev, 0x4, 0); /* 4 == D3 cold */
+- }
++ } else {
++ E1000_WRITE_REG(&adapter->hw, WUC, 0x0);
++ E1000_WRITE_REG(&adapter->hw, WUFC, 0x0);
++ pci_enable_wake(pdev, 0x3, 0x0);
++ pci_enable_wake(pdev, 0x4, 0x0); /* 4 == D3 cold */
++ }
+
+- pci_save_state(pdev);
+-
+- if(adapter->hw.mac_type >= iegbe_82540
+- && adapter->hw.mac_type != iegbe_icp_xxxx
+- && adapter->hw.media_type == iegbe_media_type_copper) {
+- manc = E1000_READ_REG(&adapter->hw, MANC);
+- if(manc & E1000_MANC_SMBUS_EN) {
+- manc |= E1000_MANC_ARP_EN;
+- E1000_WRITE_REG(&adapter->hw, MANC, manc);
++ pci_save_state(pdev);
++
++ if(adapter->hw.mac_type >= iegbe_82540
++ && adapter->hw.mac_type != iegbe_icp_xxxx
++ && adapter->hw.media_type == iegbe_media_type_copper) {
++ manc = E1000_READ_REG(&adapter->hw, MANC);
++ if(manc & E1000_MANC_SMBUS_EN) {
++ manc |= E1000_MANC_ARP_EN;
++ E1000_WRITE_REG(&adapter->hw, MANC, manc);
+ pci_enable_wake(pdev, 0x3, 0x1);
+ pci_enable_wake(pdev, 0x4, 0x1); /* 4 == D3 cold */
+- }
+- }
++ }
++ }
+
+- switch(adapter->hw.mac_type) {
+- case iegbe_82571:
+- case iegbe_82572:
+- ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+- E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+- ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+- break;
+- case iegbe_82573:
+- swsm = E1000_READ_REG(&adapter->hw, SWSM);
+- E1000_WRITE_REG(&adapter->hw, SWSM,
+- swsm & ~E1000_SWSM_DRV_LOAD);
+- break;
+- default:
+- break;
+- }
++ switch(adapter->hw.mac_type) {
++ case iegbe_82571:
++ case iegbe_82572:
++ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
++ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
++ ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
++ break;
++ case iegbe_82573:
++ swsm = E1000_READ_REG(&adapter->hw, SWSM);
++ E1000_WRITE_REG(&adapter->hw, SWSM,
++ swsm & ~E1000_SWSM_DRV_LOAD);
++ break;
++ default:
++ break;
++ }
+
+- pci_disable_device(pdev);
+- if(adapter->hw.mac_type == iegbe_icp_xxxx) {
+- /*
+- * ICP xxxx devices are not true PCI devices, in the context
+- * of power management, disabling the bus mastership is not
+- * sufficient to disable the device, it is also necessary to
+- * disable IO, Memory, and Interrupts if they are enabled.
+- */
+- pci_read_config_word(pdev, PCI_COMMAND, &cmd_word);
++ pci_disable_device(pdev);
++ if(adapter->hw.mac_type == iegbe_icp_xxxx) {
++ /*
++ * ICP xxxx devices are not true PCI devices, in the context
++ * of power management, disabling the bus mastership is not
++ * sufficient to disable the device, it is also necessary to
++ * disable IO, Memory, and Interrupts if they are enabled.
++ */
++ pci_read_config_word(pdev, PCI_COMMAND, &cmd_word);
+ if(cmd_word & PCI_COMMAND_IO) {
+- cmd_word &= ~PCI_COMMAND_IO;
++ cmd_word &= ~PCI_COMMAND_IO;
+ }
+ if(cmd_word & PCI_COMMAND_MEMORY) {
+- cmd_word &= ~PCI_COMMAND_MEMORY;
++ cmd_word &= ~PCI_COMMAND_MEMORY;
+ }
+ if(cmd_word & PCI_COMMAND_INTX_DISABLE) {
+- cmd_word &= ~PCI_COMMAND_INTX_DISABLE;
++ cmd_word &= ~PCI_COMMAND_INTX_DISABLE;
+ }
+- pci_write_config_word(pdev, PCI_COMMAND, cmd_word);
+- }
++ pci_write_config_word(pdev, PCI_COMMAND, cmd_word);
++ }
+
+- state.event = (state.event > 0) ? 0x3 : 0;
+- pci_set_power_state(pdev, state.event);
+- if(gcu_suspend == 0)
++ state.event = (state.event > 0x0) ? 0x3 : 0x0;
++ pci_set_power_state(pdev, state.event);
++ if(gcu_suspend == 0x0)
+ {
+ if(gcu == NULL) {
+- gcu = pci_find_device(PCI_VENDOR_ID_INTEL, GCU_DEVID, NULL);
+- }
++ gcu = pci_get_device(PCI_VENDOR_ID_INTEL, GCU_DEVID, NULL);
++ }
+ gcu_iegbe_suspend(gcu, 0x3);
+- gcu_suspend = 1;
+- gcu_resume = 0;
++ gcu_suspend = 0x1;
++ gcu_resume = 0x0;
+ }
+- return 0;
++ return 0x0;
+ }
+
+ #ifdef CONFIG_PM
+ static int
+ iegbe_resume(struct pci_dev *pdev)
+ {
+- struct net_device *netdev = pci_get_drvdata(pdev);
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+- uint32_t manc, ret_val, swsm;
+- uint32_t ctrl_ext;
++ struct net_device *netdev = pci_get_drvdata(pdev);
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ uint32_t manc, ret_val, swsm;
++ uint32_t ctrl_ext;
+ int offset;
+ uint32_t vdid;
+
+- if(gcu_resume == 0)
++ if(gcu_resume == 0x0)
+ {
+ if(gcu == NULL) {
+- gcu = pci_find_device(PCI_VENDOR_ID_INTEL, GCU_DEVID, NULL);
++ gcu = pci_get_device(PCI_VENDOR_ID_INTEL, GCU_DEVID, NULL);
+ pci_read_config_dword(gcu, 0x00, &vdid);
+- }
+-
++ }
++
+ if(gcu) {
+ gcu_iegbe_resume(gcu);
+- gcu_resume = 1;
+- gcu_suspend = 0;
++ gcu_resume = 0x1;
++ gcu_suspend = 0x0;
+ } else {
+ printk("Unable to resume GCU!\n");
+- }
++ }
+ }
+ pci_set_power_state(pdev, 0x0);
+- pci_restore_state(pdev);
+- ret_val = pci_enable_device(pdev);
+- pci_set_master(pdev);
++ pci_restore_state(pdev);
++ ret_val = pci_enable_device(pdev);
++ pci_set_master(pdev);
+
+ pci_enable_wake(pdev, 0x3, 0x0);
+ pci_enable_wake(pdev, 0x4, 0x0); /* 4 == D3 cold */
+
+- iegbe_reset(adapter);
+- E1000_WRITE_REG(&adapter->hw, WUS, ~0);
++ iegbe_reset(adapter);
++ E1000_WRITE_REG(&adapter->hw, WUS, ~0);
+ offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_ST)
+ + PCI_ST_SMIA_OFFSET;
+ pci_write_config_dword(adapter->pdev, offset, 0x00000006);
+@@ -5138,51 +4848,52 @@ iegbe_resume(struct pci_dev *pdev)
+ E1000_WRITE_REG(&adapter->hw, IMC2, ~0UL);
+
+ if(netif_running(netdev)) {
+- iegbe_up(adapter);
++ iegbe_up(adapter);
+ }
+- netif_device_attach(netdev);
+-
+- if(adapter->hw.mac_type >= iegbe_82540
+- && adapter->hw.mac_type != iegbe_icp_xxxx
+- && adapter->hw.media_type == iegbe_media_type_copper) {
+- manc = E1000_READ_REG(&adapter->hw, MANC);
+- manc &= ~(E1000_MANC_ARP_EN);
+- E1000_WRITE_REG(&adapter->hw, MANC, manc);
+- }
++ netif_device_attach(netdev);
+
+- switch(adapter->hw.mac_type) {
+- case iegbe_82571:
+- case iegbe_82572:
+- ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+- E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+- ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+- break;
+- case iegbe_82573:
+- swsm = E1000_READ_REG(&adapter->hw, SWSM);
+- E1000_WRITE_REG(&adapter->hw, SWSM,
+- swsm | E1000_SWSM_DRV_LOAD);
+- break;
+- default:
+- break;
+- }
++ if(adapter->hw.mac_type >= iegbe_82540
++ && adapter->hw.mac_type != iegbe_icp_xxxx
++ && adapter->hw.media_type == iegbe_media_type_copper) {
++ manc = E1000_READ_REG(&adapter->hw, MANC);
++ manc &= ~(E1000_MANC_ARP_EN);
++ E1000_WRITE_REG(&adapter->hw, MANC, manc);
++ }
++
++ switch(adapter->hw.mac_type) {
++ case iegbe_82571:
++ case iegbe_82572:
++ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
++ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
++ ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
++ break;
++ case iegbe_82573:
++ swsm = E1000_READ_REG(&adapter->hw, SWSM);
++ E1000_WRITE_REG(&adapter->hw, SWSM,
++ swsm | E1000_SWSM_DRV_LOAD);
++ break;
++ default:
++ break;
++ }
++#endif
+
+- return 0;
++ return 0x0;
+ }
+-#endif
++
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+ /*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+-static void
+-iegbe_netpoll(struct net_device *netdev)
++static void iegbe_netpoll(struct net_device *netdev)
+ {
+- struct iegbe_adapter *adapter = netdev_priv(netdev);
+- disable_irq(adapter->pdev->irq);
+- iegbe_intr(adapter->pdev->irq, netdev, NULL);
+- enable_irq(adapter->pdev->irq);
++ struct iegbe_adapter *adapter = netdev_priv(netdev);
++ disable_irq(adapter->pdev->irq);
++ iegbe_intr(adapter->pdev->irq, netdev);
++ enable_irq(adapter->pdev->irq);
+ }
+ #endif
+
++
+ /* iegbe_main.c */
+--- a/Embedded/src/GbE/iegbe_oem_phy.c
++++ b/Embedded/src/GbE/iegbe_oem_phy.c
+@@ -2,31 +2,31 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+- This program is free software; you can redistribute it and/or modify
++ 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
++ This program is distributed in the hope that it will be useful, but
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+- You should have received a copy of the GNU General Public License
+- along with this program; if not, write to the Free Software
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+- The full GNU General Public License is included in this distribution
++ The full GNU General Public License is included in this distribution
+ in the file called LICENSE.GPL.
+
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+- Intel Corporation, 5000 W Chandler Blvd, Chandler, AZ 85226
++ Intel Corporation, 5000 W Chandler Blvd, Chandler, AZ 85226
+
+ *****************************************************************************/
+ /**************************************************************************
+@@ -65,11 +65,6 @@ static int32_t iegbe_oem_link_m88_setup(
+ static int32_t iegbe_oem_set_phy_mode(struct iegbe_hw *hw);
+ static int32_t iegbe_oem_detect_phy(struct iegbe_hw *hw);
+
+-/* Define specific BCM functions */
+-static int32_t iegbe_oem_link_bcm5481_setup(struct iegbe_hw *hw);
+-static int32_t bcm5481_read_18sv (struct iegbe_hw *hw, int sv, uint16_t *data);
+-static int32_t oi_phy_setup (struct iegbe_hw *hw);
+-
+ /**
+ * iegbe_oem_setup_link
+ * @hw: iegbe_hw struct containing device specific information
+@@ -84,7 +79,7 @@ iegbe_oem_setup_link(struct iegbe_hw *hw
+ {
+ #ifdef EXTERNAL_MDIO
+
+- /*
++ /*
+ * see iegbe_setup_copper_link() as the primary example. Look at both
+ * the M88 and IGP functions that are called for ideas, possibly for
+ * power management.
+@@ -102,14 +97,14 @@ iegbe_oem_setup_link(struct iegbe_hw *hw
+ }
+ /* AFU: add test to exit out if improper phy type
+ */
+- /* relevent parts of iegbe_copper_link_preconfig */
+- ctrl = E1000_READ_REG(hw, CTRL);
+- ctrl |= E1000_CTRL_SLU;
+- ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
+- E1000_WRITE_REG(hw, CTRL, ctrl);
+-
++ /* relevent parts of iegbe_copper_link_preconfig */
++ ctrl = E1000_READ_REG(hw, CTRL);
++ ctrl |= E1000_CTRL_SLU;
++ ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
++ E1000_WRITE_REG(hw, CTRL, ctrl);
++
+ /* this is required for *hw init */
+- ret_val = iegbe_oem_detect_phy(hw);
++ ret_val = iegbe_oem_detect_phy(hw);
+ if(ret_val) {
+ return ret_val;
+ }
+@@ -119,23 +114,13 @@ iegbe_oem_setup_link(struct iegbe_hw *hw
+ }
+
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- return E1000_SUCCESS;
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ ret_val = iegbe_oem_link_m88_setup(hw);
+- if(ret_val) {
+- return ret_val;
+- }
+- break;
+- case BCM5481_PHY_ID:
+- ret_val = iegbe_oem_link_bcm5481_setup(hw);
+- if(ret_val) {
+- return ret_val;
++ if(ret_val) {
++ return ret_val;
+ }
+- break;
++ break;
+ default:
+ DEBUGOUT("Invalid PHY ID\n");
+ return -E1000_ERR_PHY_TYPE;
+@@ -143,16 +128,16 @@ iegbe_oem_setup_link(struct iegbe_hw *hw
+
+ if(hw->autoneg) {
+ ret_val = iegbe_copper_link_autoneg(hw);
+- if(ret_val) {
+- return ret_val;
+- }
++ if(ret_val) {
++ return ret_val;
+ }
++ }
+ else {
+ DEBUGOUT("Forcing speed and duplex\n");
+ ret_val = iegbe_phy_force_speed_duplex(hw);
+ }
+-
+- /*
++
++ /*
+ * Check link status. Wait up to 100 microseconds for link to become
+ * valid.
+ */
+@@ -194,51 +179,6 @@ iegbe_oem_setup_link(struct iegbe_hw *hw
+ #endif /* ifdef EXTERNAL_MDIO */
+ }
+
+-/**
+- * iegbe_oem_link_bcm5481_setup
+- * @hw: iegbe_hw struct containing device specific information
+- *
+- * Returns E1000_SUCCESS, negative E1000 error code on failure
+- *
+- * copied verbatim from iegbe_oem_link_m88_setup
+- **/
+-static int32_t
+-iegbe_oem_link_bcm5481_setup(struct iegbe_hw *hw)
+-{
+- int32_t ret_val;
+- uint16_t phy_data;
+-
+- //DEBUGFUNC(__func__);
+-
+- if(!hw)
+- return -1;
+-
+- /* phy_reset_disable is set in iegbe_oem_set_phy_mode */
+- if(hw->phy_reset_disable)
+- return E1000_SUCCESS;
+-
+- // Enable MDIX in extended control reg.
+- ret_val = iegbe_oem_read_phy_reg_ex(hw, BCM5481_ECTRL, &phy_data);
+- if(ret_val)
+- {
+- DEBUGOUT("Unable to read BCM5481_ECTRL register\n");
+- return ret_val;
+- }
+-
+- phy_data &= ~BCM5481_ECTRL_DISMDIX;
+- ret_val = iegbe_oem_write_phy_reg_ex(hw, BCM5481_ECTRL, phy_data);
+- if(ret_val)
+- {
+- DEBUGOUT("Unable to write BCM5481_ECTRL register\n");
+- return ret_val;
+- }
+-
+- ret_val = oi_phy_setup (hw);
+- if (ret_val)
+- return ret_val;
+-
+- return E1000_SUCCESS;
+-}
+
+ /**
+ * iegbe_oem_link_m88_setup
+@@ -253,7 +193,7 @@ static int32_t
+ iegbe_oem_link_m88_setup(struct iegbe_hw *hw)
+ {
+ int32_t ret_val;
+- uint16_t phy_data;
++ uint16_t phy_data = 0;
+
+ DEBUGFUNC1("%s",__func__);
+
+@@ -261,7 +201,7 @@ iegbe_oem_link_m88_setup(struct iegbe_hw
+ return -1;
+ }
+
+- ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_CTRL,
++ ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_CTRL,
+ &phy_data);
+ phy_data |= 0x00000008;
+ ret_val = iegbe_oem_write_phy_reg_ex(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+@@ -279,7 +219,7 @@ iegbe_oem_link_m88_setup(struct iegbe_hw
+
+ phy_data &= ~M88E1000_PSCR_ASSERT_CRS_ON_TX;
+
+- /*
++ /*
+ * Options:
+ * MDI/MDI-X = 0 (default)
+ * 0 - Auto for all speeds
+@@ -305,7 +245,7 @@ iegbe_oem_link_m88_setup(struct iegbe_hw
+ break;
+ }
+
+- /*
++ /*
+ * Options:
+ * disable_polarity_correction = 0 (default)
+ * Automatic Correction for Reversed Cable Polarity
+@@ -316,25 +256,25 @@ iegbe_oem_link_m88_setup(struct iegbe_hw
+
+ if(hw->disable_polarity_correction == 1) {
+ phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
+- }
++ }
+ ret_val = iegbe_oem_write_phy_reg_ex(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to write M88E1000_PHY_SPEC_CTRL register\n");
+ return ret_val;
+ }
+
+- /*
++ /*
+ * Force TX_CLK in the Extended PHY Specific Control Register
+ * to 25MHz clock.
+ */
+- ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_EXT_PHY_SPEC_CTRL,
++ ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+ &phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read M88E1000_EXT_PHY_SPEC_CTRL register\n");
+ return ret_val;
+ }
+
+- /*
++ /*
+ * For Truxton, it is necessary to add RGMII tx and rx
+ * timing delay though the EXT_PHY_SPEC_CTRL register
+ */
+@@ -350,13 +290,13 @@ iegbe_oem_link_m88_setup(struct iegbe_hw
+ phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
+ M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
+ }
+- ret_val = iegbe_oem_write_phy_reg_ex(hw, M88E1000_EXT_PHY_SPEC_CTRL,
++ ret_val = iegbe_oem_write_phy_reg_ex(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+ phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read M88E1000_EXT_PHY_SPEC_CTRL register\n");
+ return ret_val;
+ }
+-
++
+
+ /* SW Reset the PHY so all changes take effect */
+ ret_val = iegbe_phy_hw_reset(hw);
+@@ -371,7 +311,7 @@ iegbe_oem_link_m88_setup(struct iegbe_hw
+ /**
+ * iegbe_oem_force_mdi
+ * @hw: iegbe_hw struct containing device specific information
+- * @resetPhy: returns true if after calling this function the
++ * @resetPhy: returns true if after calling this function the
+ * PHY requires a reset
+ *
+ * Returns E1000_SUCCESS, negative E1000 error code on failure
+@@ -379,7 +319,7 @@ iegbe_oem_link_m88_setup(struct iegbe_hw
+ * This is called from iegbe_phy_force_speed_duplex, which is
+ * called from iegbe_oem_setup_link.
+ **/
+-int32_t
++int32_t
+ iegbe_oem_force_mdi(struct iegbe_hw *hw, int *resetPhy)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -393,35 +333,30 @@ iegbe_oem_force_mdi(struct iegbe_hw *hw,
+ return -1;
+ }
+
+- /*
++ /*
+ * a boolean to indicate if the phy needs to be reset
+- *
++ *
+ * Make note that the M88 phy is what'll be used on Truxton
+ * see iegbe_phy_force_speed_duplex, which does the following for M88
+ */
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- case BCM5481_PHY_ID:
+- DEBUGOUT("WARNING: An empty iegbe_oem_force_mdi() has been called!\n");
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- ret_val = iegbe_oem_read_phy_reg_ex(hw,
+- M88E1000_PHY_SPEC_CTRL,
++ ret_val = iegbe_oem_read_phy_reg_ex(hw,
++ M88E1000_PHY_SPEC_CTRL,
+ &phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read M88E1000_PHY_SPEC_CTRL register\n");
+ return ret_val;
+ }
+-
++
+ /*
+- * Clear Auto-Crossover to force MDI manually. M88E1000 requires
++ * Clear Auto-Crossover to force MDI manually. M88E1000 requires
+ * MDI forced whenever speed are duplex are forced.
+ */
+-
++
+ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+- ret_val = iegbe_oem_write_phy_reg_ex(hw, M88E1000_PHY_SPEC_CTRL,
++ ret_val = iegbe_oem_write_phy_reg_ex(hw, M88E1000_PHY_SPEC_CTRL,
+ phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to write M88E1000_PHY_SPEC_CTRL register\n");
+@@ -458,7 +393,7 @@ iegbe_oem_force_mdi(struct iegbe_hw *hw,
+ * This is called from iegbe_phy_force_speed_duplex, which is
+ * called from iegbe_oem_setup_link.
+ **/
+-int32_t
++int32_t
+ iegbe_oem_phy_reset_dsp(struct iegbe_hw *hw)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -478,10 +413,8 @@ iegbe_oem_phy_reset_dsp(struct iegbe_hw
+ * no-op.
+ */
+ switch (hw->phy_id) {
+- case M88E1000_I_PHY_ID:
+- case M88E1141_E_PHY_ID:
+- case BCM5481_PHY_ID:
+- case BCM5395S_PHY_ID:
++ case M88E1000_I_PHY_ID:
++ case M88E1141_E_PHY_ID:
+ DEBUGOUT("No DSP to reset on OEM PHY\n");
+ break;
+ default:
+@@ -508,7 +441,7 @@ iegbe_oem_phy_reset_dsp(struct iegbe_hw
+ * This is called from iegbe_phy_force_speed_duplex, which is
+ * called from iegbe_oem_setup_link.
+ **/
+-int32_t
++int32_t
+ iegbe_oem_cleanup_after_phy_reset(struct iegbe_hw *hw)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -520,29 +453,24 @@ iegbe_oem_cleanup_after_phy_reset(struct
+
+ if(!hw) {
+ return -1;
+- }
++ }
+
+- /*
++ /*
+ * Make note that the M88 phy is what'll be used on Truxton.
+ * see iegbe_phy_force_speed_duplex, which does the following for M88
+ */
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- case BCM5481_PHY_ID:
+- DEBUGOUT("WARNING: An empty iegbe_oem_cleanup_after_phy_reset() has been called!\n");
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ /*
+- * Because we reset the PHY above, we need to re-force
++ * Because we reset the PHY above, we need to re-force
+ * TX_CLK in the Extended PHY Specific Control Register to
+ * 25MHz clock. This value defaults back to a 2.5MHz clock
+ * when the PHY is reset.
+ */
+
+ ret_val = iegbe_oem_read_phy_reg_ex(hw,
+- M88E1000_EXT_PHY_SPEC_CTRL,
++ M88E1000_EXT_PHY_SPEC_CTRL,
+ &phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read M88E1000_EXT_SPEC_CTRL register\n");
+@@ -550,22 +478,23 @@ iegbe_oem_cleanup_after_phy_reset(struct
+ }
+
+ phy_data |= M88E1000_EPSCR_TX_CLK_25;
+- ret_val = iegbe_oem_write_phy_reg_ex(hw,
+- M88E1000_EXT_PHY_SPEC_CTRL,
++ ret_val = iegbe_oem_write_phy_reg_ex(hw,
++ M88E1000_EXT_PHY_SPEC_CTRL,
+ phy_data);
+ if(ret_val) {
+- DEBUGOUT("Unable to write M88E1000_EXT_PHY_SPEC_CTRL register\n");
++ DEBUGOUT("Unable to write M88E1000_EXT_PHY_SPEC_CTRL "
++ "register\n");
+ return ret_val;
+ }
+
+ /*
+ * In addition, because of the s/w reset above, we need to enable
+- * CRX on TX. This must be set for both full and half duplex
++ * CRX on TX. This must be set for both full and half duplex
+ * operation.
+ */
+
+- ret_val = iegbe_oem_read_phy_reg_ex(hw,
+- M88E1000_PHY_SPEC_CTRL,
++ ret_val = iegbe_oem_read_phy_reg_ex(hw,
++ M88E1000_PHY_SPEC_CTRL,
+ &phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read M88E1000_PHY_SPEC_CTRL register\n");
+@@ -573,12 +502,12 @@ iegbe_oem_cleanup_after_phy_reset(struct
+ }
+
+ phy_data &= ~M88E1000_PSCR_ASSERT_CRS_ON_TX;
+- ret_val = iegbe_oem_write_phy_reg_ex(hw, M88E1000_PHY_SPEC_CTRL,
++ ret_val = iegbe_oem_write_phy_reg_ex(hw, M88E1000_PHY_SPEC_CTRL,
+ phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to write M88E1000_PHY_SPEC_CTRL register\n");
+ return ret_val;
+- }
++ }
+ break;
+ default:
+ DEBUGOUT("Invalid PHY ID\n");
+@@ -604,12 +533,12 @@ iegbe_oem_cleanup_after_phy_reset(struct
+ * This is called from iegbe_oem_setup_link which is
+ * called from iegbe_setup_link.
+ **/
+-static int32_t
++static int32_t
+ iegbe_oem_set_phy_mode(struct iegbe_hw *hw)
+ {
+ /*
+ * it is unclear if it is necessary to set the phy mode. Right now only
+- * one MAC 82545 Rev 3 does it, but the other MACs like Tolapai do not.
++ * one MAC 82545 Rev 3 does it, but the other MACs like tola do not.
+ * Leave the functionality off for now until it is determined that Tolapai
+ * needs it as well.
+ */
+@@ -638,41 +567,37 @@ iegbe_oem_set_phy_mode(struct iegbe_hw *
+ #ifndef skip_set_mode
+ DEBUGOUT("No need to call oem_set_phy_mode on Truxton\n");
+ #else
+- /*
++ /*
+ * Make note that the M88 phy is what'll be used on Truxton.
+ *
+ * use iegbe_set_phy_mode as example
+ */
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- case BCM5481_PHY_ID:
+- DEBUGOUT("WARNING: An empty iegbe_oem_set_phy_mode() has been called!\n");
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- ret_val = iegbe_read_eeprom(hw,
+- EEPROM_PHY_CLASS_WORD,
+- 1,
++ ret_val = iegbe_read_eeprom(hw,
++ EEPROM_PHY_CLASS_WORD,
++ 1,
+ &eeprom_data);
+ if(ret_val) {
+ return ret_val;
+ }
+
+- if((eeprom_data != EEPROM_RESERVED_WORD) &&
+- (eeprom_data & EEPROM_PHY_CLASS_A))
++ if((eeprom_data != EEPROM_RESERVED_WORD) &&
++ (eeprom_data & EEPROM_PHY_CLASS_A))
+ {
+- ret_val = iegbe_oem_write_phy_reg_ex(hw,
+- M88E1000_PHY_PAGE_SELECT,
+- 0x000B);
++ ret_val = iegbe_oem_write_phy_reg_ex(hw,
++ M88E1000_PHY_PAGE_SELECT,
++ 0x000B);
+ if(ret_val) {
+- DEBUGOUT("Unable to write to M88E1000_PHY_PAGE_SELECT register on PHY\n");
++ DEBUGOUT("Unable to write to M88E1000_PHY_PAGE_SELECT "
++ "register on PHY\n");
+ return ret_val;
+ }
+
+- ret_val = iegbe_oem_write_phy_reg_ex(hw,
+- M88E1000_PHY_GEN_CONTROL,
+- 0x8104);
++ ret_val = iegbe_oem_write_phy_reg_ex(hw,
++ M88E1000_PHY_GEN_CONTROL,
++ 0x8104);
+ if(ret_val) {
+ DEBUGOUT("Unable to write to M88E1000_PHY_GEN_CONTROL"
+ "register on PHY\n");
+@@ -687,11 +612,12 @@ iegbe_oem_set_phy_mode(struct iegbe_hw *
+ return -E1000_ERR_PHY_TYPE;
+ }
+ #endif
+-
++
+ return E1000_SUCCESS;
+
+ }
+
++
+ /**
+ * iegbe_oem_detect_phy
+ * @hw: iegbe_hw struct containing device specific information
+@@ -702,7 +628,7 @@ iegbe_oem_set_phy_mode(struct iegbe_hw *
+ *
+ * This borrows heavily from iegbe_detect_gig_phy
+ **/
+-static int32_t
++static int32_t
+ iegbe_oem_detect_phy(struct iegbe_hw *hw)
+ {
+ int32_t ret_val;
+@@ -715,33 +641,20 @@ iegbe_oem_detect_phy(struct iegbe_hw *hw
+ }
+ hw->phy_type = iegbe_phy_oem;
+
+-{
+- // If MAC2 (BCM5395 switch), manually detect the phy
+- struct iegbe_adapter *adapter;
+- uint32_t device_number;
+- adapter = (struct iegbe_adapter *) hw->back;
+- device_number = PCI_SLOT(adapter->pdev->devfn);
+- if (device_number == ICP_XXXX_MAC_2) {
+- hw->phy_id = BCM5395S_PHY_ID;
+- hw->phy_revision = 0;
+- return E1000_SUCCESS;
+- }
+-}
+-
+-
+ ret_val = iegbe_oem_read_phy_reg_ex(hw, PHY_ID1, &phy_id_high);
+ if(ret_val) {
+ DEBUGOUT("Unable to read PHY register PHY_ID1\n");
+ return ret_val;
+ }
+-
++
+ usec_delay(0x14);
+ ret_val = iegbe_oem_read_phy_reg_ex(hw, PHY_ID2, &phy_id_low);
+ if(ret_val) {
+ DEBUGOUT("Unable to read PHY register PHY_ID2\n");
+ return ret_val;
+ }
+- hw->phy_id = (uint32_t) ((phy_id_high << 0x10) + phy_id_low);
++ hw->phy_id = (uint32_t) ((phy_id_high << 0x10) +
++ (phy_id_low & PHY_REVISION_MASK));
+ hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
+
+ return E1000_SUCCESS;
+@@ -753,15 +666,15 @@ iegbe_oem_detect_phy(struct iegbe_hw *hw
+ * @hw: iegbe_hw struct containing device specific information
+ *
+ * Returns the value of the Inter Packet Gap (IPG) Transmit Time (IPGT) in the
+- * Transmit IPG register appropriate for the given PHY. This field is only 10
++ * Transmit IPG register appropriate for the given PHY. This field is only 10
+ * bits wide.
+ *
+ * In the original iegbe code, only the IPGT field varied between media types.
+- * If the OEM phy requires setting IPG Receive Time 1 & 2 Registers, it would
++ * If the OEM phy requires setting IPG Receive Time 1 & 2 Registers, it would
+ * be required to modify the iegbe_config_tx() function to accomdate the change
+ *
+ **/
+-uint32_t
++uint32_t
+ iegbe_oem_get_tipg(struct iegbe_hw *hw)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -777,15 +690,13 @@ iegbe_oem_get_tipg(struct iegbe_hw *hw)
+ switch (hw->phy_id) {
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- case BCM5481_PHY_ID:
+- case BCM5395S_PHY_ID:
+ phy_num = DEFAULT_ICP_XXXX_TIPG_IPGT;
+ break;
+ default:
+ DEBUGOUT("Invalid PHY ID\n");
+ return DEFAULT_ICP_XXXX_TIPG_IPGT;
+ }
+-
++
+ return phy_num;
+
+ #else /* ifdef EXTERNAL_MDIO */
+@@ -803,15 +714,15 @@ iegbe_oem_get_tipg(struct iegbe_hw *hw)
+ * iegbe_oem_phy_is_copper
+ * @hw: iegbe_hw struct containing device specific information
+ *
+- * Test for media type within the iegbe driver is common, so this is a simple
+- * test for copper PHYs. The ICP_XXXX family of controllers initially only
+- * supported copper interconnects (no TBI (ten bit interface) for Fiber
+- * existed). If future revs support either Fiber or an internal SERDES, it
+- * may become necessary to evaluate where this function is used to go beyond
++ * Test for media type within the iegbe driver is common, so this is a simple
++ * test for copper PHYs. The ICP_XXXX family of controllers initially only
++ * supported copper interconnects (no TBI (ten bit interface) for Fiber
++ * existed). If future revs support either Fiber or an internal SERDES, it
++ * may become necessary to evaluate where this function is used to go beyond
+ * determining whether or not media type is just copper.
+ *
+ **/
+-int
++int
+ iegbe_oem_phy_is_copper(struct iegbe_hw *hw)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -827,23 +738,21 @@ iegbe_oem_phy_is_copper(struct iegbe_hw
+ switch (hw->phy_id) {
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- case BCM5481_PHY_ID:
+- case BCM5395S_PHY_ID:
+ isCopper = TRUE;
+ break;
+ default:
+ DEBUGOUT("Invalid PHY ID\n");
+ return -E1000_ERR_PHY_TYPE;
+ }
+-
++
+ return isCopper;
+
+ #else /* ifdef EXTERNAL_MDIO */
+
+- /*
++ /*
+ * caught between returning true or false. True allows it to
+ * be entered into && statements w/o ill effect, but false
+- * would make more sense
++ * would make more sense
+ */
+ DEBUGOUT("Invalid value for transceiver type, return FALSE\n");
+ return FALSE;
+@@ -856,19 +765,19 @@ iegbe_oem_phy_is_copper(struct iegbe_hw
+ * iegbe_oem_get_phy_dev_number
+ * @hw: iegbe_hw struct containing device specific information
+ *
+- * For ICP_XXXX family of devices, there are 3 MACs, each of which may
+- * have a different PHY (and indeed a different media interface). This
+- * function is used to indicate which of the MAC/PHY pairs we are interested
++ * For ICP_XXXX family of devices, there are 3 MACs, each of which may
++ * have a different PHY (and indeed a different media interface). This
++ * function is used to indicate which of the MAC/PHY pairs we are interested
+ * in.
+- *
++ *
+ **/
+-uint32_t
++uint32_t
+ iegbe_oem_get_phy_dev_number(struct iegbe_hw *hw)
+ {
+ #ifdef EXTERNAL_MDIO
+
+- /*
+- * for ICP_XXXX family of devices, the three network interfaces are
++ /*
++ * for ICP_XXXX family of devices, the three network interfaces are
+ * differentiated by their PCI device number, where the three share
+ * the same PCI bus
+ */
+@@ -886,15 +795,15 @@ iegbe_oem_get_phy_dev_number(struct iegb
+
+ switch(device_number)
+ {
+- case ICP_XXXX_MAC_0:
++ case ICP_XXXX_MAC_0:
++ hw->phy_addr = 0x00;
++ break;
++ case ICP_XXXX_MAC_1:
+ hw->phy_addr = 0x01;
+ break;
+- case ICP_XXXX_MAC_1:
++ case ICP_XXXX_MAC_2:
+ hw->phy_addr = 0x02;
+ break;
+- case ICP_XXXX_MAC_2:
+- hw->phy_addr = 0x00;
+- break;
+ default: hw->phy_addr = 0x00;
+ }
+ return hw->phy_addr;
+@@ -915,7 +824,7 @@ iegbe_oem_get_phy_dev_number(struct iegb
+ * @cmd: the original IOCTL command that instigated the call chain.
+ *
+ * This function abstracts out the code necessary to service the
+- * SIOCSMIIREG case within the iegbe_mii_ioctl() for oem PHYs.
++ * SIOCSMIIREG case within the iegbe_mii_ioctl() for oem PHYs.
+ * iegbe_mii_ioctl() was implemented for copper phy's only and this
+ * function will only be called if iegbe_oem_phy_is_copper() returns true for
+ * a given MAC. Note that iegbe_mii_ioctl() has a compile flag
+@@ -924,14 +833,14 @@ iegbe_oem_get_phy_dev_number(struct iegb
+ * NOTE: a spinlock is in effect for the duration of this call. It is
+ * imperative that a negative value be returned on any error, so
+ * the spinlock can be released properly.
+- *
++ *
+ **/
+ int
+ iegbe_oem_mii_ioctl(struct iegbe_adapter *adapter, unsigned long flags,
+ struct ifreq *ifr, int cmd)
+ {
+ #ifdef EXTERNAL_MDIO
+-
++
+ struct mii_ioctl_data *data = if_mii(ifr);
+ uint16_t mii_reg = data->val_in;
+ uint16_t spddplx;
+@@ -942,12 +851,6 @@ iegbe_oem_mii_ioctl(struct iegbe_adapter
+ if(!adapter || !ifr) {
+ return -1;
+ }
+-
+- // If MAC2 (BCM5395 switch) then leave now
+- if ((PCI_SLOT(adapter->pdev->devfn)) == ICP_XXXX_MAC_2) {
+- return -1;
+- }
+-
+ switch (data->reg_num) {
+ case PHY_CTRL:
+ if(mii_reg & MII_CR_POWER_DOWN) {
+@@ -956,7 +859,7 @@ iegbe_oem_mii_ioctl(struct iegbe_adapter
+ if(mii_reg & MII_CR_AUTO_NEG_EN) {
+ adapter->hw.autoneg = 1;
+ adapter->hw.autoneg_advertised = ICP_XXXX_AUTONEG_ADV_DEFAULT;
+- }
++ }
+ else {
+ if(mii_reg & 0x40) {
+ spddplx = SPEED_1000;
+@@ -976,7 +879,7 @@ iegbe_oem_mii_ioctl(struct iegbe_adapter
+ if(netif_running(adapter->netdev)) {
+ iegbe_down(adapter);
+ iegbe_up(adapter);
+- }
++ }
+ else {
+ iegbe_reset(adapter);
+ }
+@@ -1043,10 +946,10 @@ void iegbe_oem_fiber_live_in_suspend(str
+ * Note: The call to iegbe_get_regs() assumed an array of 24 elements
+ * where the last 11 are passed to this function. If the array
+ * that is passed to the calling function has its size or element
+- * defintions changed, this function becomes broken.
++ * defintions changed, this function becomes broken.
+ *
+ **/
+-void iegbe_oem_get_phy_regs(struct iegbe_adapter *adapter, uint32_t *data,
++void iegbe_oem_get_phy_regs(struct iegbe_adapter *adapter, uint32_t *data,
+ uint32_t data_len)
+ {
+ #define EXPECTED_ARRAY_LEN 11
+@@ -1062,13 +965,13 @@ void iegbe_oem_get_phy_regs(struct iegbe
+ * Use the corrected_length variable to make sure we don't exceed that
+ * length
+ */
+- corrected_len = data_len>EXPECTED_ARRAY_LEN
++ corrected_len = data_len>EXPECTED_ARRAY_LEN
+ ? EXPECTED_ARRAY_LEN : data_len;
+ memset(data, 0, corrected_len*sizeof(uint32_t));
+
+ #ifdef EXTERNAL_MDIO
+
+- /*
++ /*
+ * Fill data[] with...
+ *
+ * [0] = cable length
+@@ -1084,16 +987,11 @@ void iegbe_oem_get_phy_regs(struct iegbe
+ * [10] = mdix mode
+ */
+ switch (adapter->hw.phy_id) {
+- case BCM5395S_PHY_ID:
+- case BCM5481_PHY_ID:
+- DEBUGOUT("WARNING: An empty iegbe_oem_get_phy_regs() has been called!\n");
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ if(corrected_len > 0) {
+- iegbe_oem_read_phy_reg_ex(&adapter->hw,
+- M88E1000_PHY_SPEC_STATUS,
++ iegbe_oem_read_phy_reg_ex(&adapter->hw,
++ M88E1000_PHY_SPEC_STATUS,
+ (uint16_t *) &data[0]);
+ }
+ if(corrected_len > 0x1){
+@@ -1106,7 +1004,7 @@ void iegbe_oem_get_phy_regs(struct iegbe
+ data[0x3] = 0x0; /* Dummy (to align w/ IGP phy reg dump) */
+ }
+ if(corrected_len > 0x4) {
+- iegbe_oem_read_phy_reg_ex(&adapter->hw, M88E1000_PHY_SPEC_CTRL,
++ iegbe_oem_read_phy_reg_ex(&adapter->hw, M88E1000_PHY_SPEC_CTRL,
+ (uint16_t *) &data[0x4]);
+ }
+ if(corrected_len > 0x5) {
+@@ -1144,7 +1042,7 @@ void iegbe_oem_get_phy_regs(struct iegbe
+ * This is called from iegbe_set_phy_loopback in response from call from
+ * ethtool to place the PHY into loopback mode.
+ **/
+-int
++int
+ iegbe_oem_phy_loopback(struct iegbe_adapter *adapter)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -1165,23 +1063,18 @@ iegbe_oem_phy_loopback(struct iegbe_adap
+ * was that nonintegrated called iegbe_phy_reset_clk_and_crs(),
+ * hopefully this won't matter as CRS required for half-duplex
+ * operation and this is set to full duplex.
+- *
++ *
+ * Make note that the M88 phy is what'll be used on Truxton
+ * Loopback configuration is the same for each of the supported PHYs.
+ */
+ switch (adapter->hw.phy_id) {
+- case BCM5395S_PHY_ID:
+- DEBUGOUT("WARNING: An empty iegbe_oem_phy_loopback() has been called!\n");
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- case BCM5481_PHY_ID:
+
+ adapter->hw.autoneg = FALSE;
+
+ /* turn off Auto-MDI/MDIX */
+- /*ret_val = iegbe_oem_write_phy_reg_ex(&adapter->hw,
++ /*ret_val = iegbe_oem_write_phy_reg_ex(&adapter->hw,
+ M88E1000_PHY_SPEC_CTRL, 0x0808);
+ if(ret_val)
+ {
+@@ -1206,10 +1099,10 @@ iegbe_oem_phy_loopback(struct iegbe_adap
+ DEBUGOUT("Unable to write to register PHY_CTRL\n");
+ return ret_val;
+ }
+-
+-
++
++
+ /* force 1000, set loopback */
+- /*ret_val =
++ /*ret_val =
+ iegbe_oem_write_phy_reg_ex(&adapter->hw, PHY_CTRL, 0x4140); */
+ ret_val = iegbe_oem_write_phy_reg_ex(&adapter->hw, PHY_CTRL, 0x6100);
+ if(ret_val) {
+@@ -1228,21 +1121,21 @@ iegbe_oem_phy_loopback(struct iegbe_adap
+ E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg);
+
+ /*
+- * Write out to PHY registers 29 and 30 to disable the Receiver.
++ * Write out to PHY registers 29 and 30 to disable the Receiver.
+ * This directly lifted from iegbe_phy_disable_receiver().
+- *
++ *
+ * The code is currently commented out as for the M88 used in
+ * Truxton, registers 29 and 30 are unutilized. Leave in, just
+- * in case we are on the receiving end of an 'undocumented'
++ * in case we are on the receiving end of an 'undocumented'
+ * feature
+ */
+- /*
++ /*
+ * iegbe_oem_write_phy_reg_ex(&adapter->hw, 29, 0x001F);
+ * iegbe_oem_write_phy_reg_ex(&adapter->hw, 30, 0x8FFC);
+ * iegbe_oem_write_phy_reg_ex(&adapter->hw, 29, 0x001A);
+ * iegbe_oem_write_phy_reg_ex(&adapter->hw, 30, 0x8FF0);
+ */
+-
++
+ break;
+ default:
+ DEBUGOUT("Invalid PHY ID\n");
+@@ -1268,15 +1161,15 @@ iegbe_oem_phy_loopback(struct iegbe_adap
+ * ethtool to place the PHY out of loopback mode. This handles the OEM
+ * specific part of loopback cleanup.
+ **/
+-void
++void
+ iegbe_oem_loopback_cleanup(struct iegbe_adapter *adapter)
+ {
+ #ifdef EXTERNAL_MDIO
+
+- /*
+- * This borrows liberally from iegbe_loopback_cleanup().
++ /*
++ * This borrows liberally from iegbe_loopback_cleanup().
+ * making note that the M88 phy is what'll be used on Truxton
+- *
++ *
+ * Loopback cleanup is the same for all supported PHYs.
+ */
+ int32_t ret_val;
+@@ -1289,38 +1182,32 @@ iegbe_oem_loopback_cleanup(struct iegbe_
+ }
+
+ switch (adapter->hw.phy_id) {
+- case BCM5395S_PHY_ID:
+- DEBUGOUT("WARNING: An empty iegbe_oem_loopback_cleanup() has been called!\n");
+- return;
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- case BCM5481_PHY_ID:
+ default:
+ adapter->hw.autoneg = TRUE;
+-
+- ret_val = iegbe_oem_read_phy_reg_ex(&adapter->hw, PHY_CTRL,
++
++ ret_val = iegbe_oem_read_phy_reg_ex(&adapter->hw, PHY_CTRL,
+ &phy_reg);
+ if(ret_val) {
+ DEBUGOUT("Unable to read to register PHY_CTRL\n");
+ return;
+ }
+-
++
+ if(phy_reg & MII_CR_LOOPBACK) {
+ phy_reg &= ~MII_CR_LOOPBACK;
+-
+- ret_val = iegbe_oem_write_phy_reg_ex(&adapter->hw, PHY_CTRL,
++
++ ret_val = iegbe_oem_write_phy_reg_ex(&adapter->hw, PHY_CTRL,
+ phy_reg);
+ if(ret_val) {
+ DEBUGOUT("Unable to write to register PHY_CTRL\n");
+ return;
+ }
+-
++
+ iegbe_phy_reset(&adapter->hw);
+ }
+ }
+-
++
+ #endif /* ifdef EXTERNAL_MDIO */
+ return;
+
+@@ -1336,7 +1223,7 @@ iegbe_oem_loopback_cleanup(struct iegbe_
+ * Called by iegbe_check_downshift(), checks the PHY to see if it running
+ * at as speed slower than its maximum.
+ **/
+-uint32_t
++uint32_t
+ iegbe_oem_phy_speed_downgraded(struct iegbe_hw *hw, uint16_t *isDowngraded)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -1356,24 +1243,19 @@ iegbe_oem_phy_speed_downgraded(struct ie
+ */
+
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- case BCM5481_PHY_ID:
+- *isDowngraded = 0;
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
++ ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
+ &phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read register M88E1000_PHY_SPEC_STATUS\n");
+ return ret_val;
+ }
+-
+- *isDowngraded = (phy_data & M88E1000_PSSR_DOWNSHIFT)
++
++ *isDowngraded = (phy_data & M88E1000_PSSR_DOWNSHIFT)
+ >> M88E1000_PSSR_DOWNSHIFT_SHIFT;
+-
+- break;
++
++ break;
+ default:
+ DEBUGOUT("Invalid PHY ID\n");
+ return 1;
+@@ -1388,7 +1270,7 @@ iegbe_oem_phy_speed_downgraded(struct ie
+ }
+
+ *isDowngraded = 0;
+- return 0;
++ return 0;
+
+ #endif /* ifdef EXTERNAL_MDIO */
+ }
+@@ -1403,7 +1285,7 @@ iegbe_oem_phy_speed_downgraded(struct ie
+ * Called by iegbe_check_downshift(), checks the PHY to see if it running
+ * at as speed slower than its maximum.
+ **/
+-int32_t
++int32_t
+ iegbe_oem_check_polarity(struct iegbe_hw *hw, uint16_t *polarity)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -1417,33 +1299,27 @@ iegbe_oem_check_polarity(struct iegbe_hw
+ return -1;
+ }
+
+- /*
++ /*
+ * borrow liberally from iegbe_check_polarity.
+ * Make note that the M88 phy is what'll be used on Truxton
+ */
+
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- case BCM5481_PHY_ID:
+- *polarity = 0;
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ /* return the Polarity bit in the Status register. */
+- ret_val = iegbe_oem_read_phy_reg_ex(hw,
+- M88E1000_PHY_SPEC_STATUS,
++ ret_val = iegbe_oem_read_phy_reg_ex(hw,
++ M88E1000_PHY_SPEC_STATUS,
+ &phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read register M88E1000_PHY_SPEC_STATUS\n");
+ return ret_val;
+ }
+
+- *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY)
++ *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY)
+ >> M88E1000_PSSR_REV_POLARITY_SHIFT;
+-
+- break;
+-
++
++ break;
+ default:
+ DEBUGOUT("Invalid PHY ID\n");
+ return -E1000_ERR_PHY_TYPE;
+@@ -1472,7 +1348,7 @@ iegbe_oem_check_polarity(struct iegbe_hw
+ * the MAC with the PHY. It turns out on ICP_XXXX, this is not
+ * done automagically.
+ **/
+-int32_t
++int32_t
+ iegbe_oem_phy_is_full_duplex(struct iegbe_hw *hw, int *isFD)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -1485,40 +1361,22 @@ iegbe_oem_phy_is_full_duplex(struct iegb
+ if(!hw || !isFD) {
+ return -1;
+ }
+- /*
++ /*
+ * Make note that the M88 phy is what'll be used on Truxton
+ * see iegbe_config_mac_to_phy
+ */
+-
++
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- /* Always full duplex */
+- *isFD = 1;
+- break;
+-
+- case BCM5481_PHY_ID:
+- ret_val = iegbe_read_phy_reg(hw, BCM5481_ASTAT, &phy_data);
+- if(ret_val) return ret_val;
+-
+- switch (BCM5481_ASTAT_HCD(phy_data)) {
+- case BCM5481_ASTAT_1KBTFD:
+- case BCM5481_ASTAT_100BTXFD:
+- *isFD = 1;
+- break;
+- default:
+- *isFD = 0;
+- }
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
+- if(ret_val) {
+- DEBUGOUT("Unable to read register M88E1000_PHY_SPEC_STATUS\n");
+- return ret_val;
+- }
++ ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
++ &phy_data);
++ if(ret_val) {
++ DEBUGOUT("Unable to read register M88E1000_PHY_SPEC_STATUS\n");
++ return ret_val;
++ }
+ *isFD = (phy_data & M88E1000_PSSR_DPLX) != 0;
+-
++
+ break;
+ default:
+ DEBUGOUT("Invalid PHY ID\n");
+@@ -1546,7 +1404,7 @@ iegbe_oem_phy_is_full_duplex(struct iegb
+ * the MAC with the PHY. It turns out on ICP_XXXX, this is not
+ * done automagically.
+ **/
+-int32_t
++int32_t
+ iegbe_oem_phy_is_speed_1000(struct iegbe_hw *hw, int *is1000)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -1565,28 +1423,10 @@ iegbe_oem_phy_is_speed_1000(struct iegbe
+ */
+
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- /* Always 1000mb */
+- *is1000 = 1;
+- break;
+-
+- case BCM5481_PHY_ID:
+- ret_val = iegbe_read_phy_reg(hw, BCM5481_ASTAT, &phy_data);
+- if(ret_val) return ret_val;
+-
+- switch (BCM5481_ASTAT_HCD(phy_data)) {
+- case BCM5481_ASTAT_1KBTFD:
+- case BCM5481_ASTAT_1KBTHD:
+- *is1000 = 1;
+- break;
+- default:
+- *is1000 = 0;
+- }
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
++ ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
++ &phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read register M88E1000_PHY_SPEC_STATUS\n");
+ return ret_val;
+@@ -1638,28 +1478,9 @@ iegbe_oem_phy_is_speed_100(struct iegbe_
+ * see iegbe_config_mac_to_phy
+ */
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- /* Always 1000Mb, never 100mb */
+- *is100 = 0;
+- break;
+-
+- case BCM5481_PHY_ID:
+- ret_val = iegbe_read_phy_reg(hw, BCM5481_ASTAT, &phy_data);
+- if(ret_val) return ret_val;
+-
+- switch (BCM5481_ASTAT_HCD(phy_data)) {
+- case BCM5481_ASTAT_100BTXFD:
+- case BCM5481_ASTAT_100BTXHD:
+- *is100 = 1;
+- break;
+- default:
+- *is100 = 0;
+- }
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- ret_val = iegbe_oem_read_phy_reg_ex(hw,
++ ret_val = iegbe_oem_read_phy_reg_ex(hw,
+ M88E1000_PHY_SPEC_STATUS,
+ &phy_data);
+ if(ret_val) {
+@@ -1714,29 +1535,24 @@ iegbe_oem_phy_get_info(struct iegbe_hw *
+ * see iegbe_phy_m88_get_info
+ */
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- case BCM5481_PHY_ID:
+- DEBUGOUT("WARNING: An empty iegbe_oem_phy_get_info() has been called!\n");
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- /* The downshift status is checked only once, after link is
+- * established and it stored in the hw->speed_downgraded parameter.*/
++ /* The downshift status is checked only once, after link is
++ * established and it stored in the hw->speed_downgraded parameter.*/
+ phy_info->downshift = (iegbe_downshift)hw->speed_downgraded;
+-
+- ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_CTRL,
++
++ ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_CTRL,
+ &phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read register M88E1000_PHY_SPEC_CTRL\n");
+ return ret_val;
+ }
+
+- phy_info->extended_10bt_distance =
+- (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE)
++ phy_info->extended_10bt_distance =
++ (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE)
+ >> M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
+ phy_info->polarity_correction =
+- (phy_data & M88E1000_PSCR_POLARITY_REVERSAL)
++ (phy_data & M88E1000_PSCR_POLARITY_REVERSAL)
+ >> M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
+
+ /* Check polarity status */
+@@ -1747,11 +1563,11 @@ iegbe_oem_phy_get_info(struct iegbe_hw *
+
+ phy_info->cable_polarity = polarity;
+
+- ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
++ ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
+ &phy_data);
+ if(ret_val) {
+- DEBUGOUT("Unable to read register M88E1000_PHY_SPEC_STATUS\n");
+- return ret_val;
++ DEBUGOUT("Unable to read register M88E1000_PHY_SPEC_STATUS\n");
++ return ret_val;
+ }
+
+ phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX)
+@@ -1761,24 +1577,24 @@ iegbe_oem_phy_get_info(struct iegbe_hw *
+ /* Cable Length Estimation and Local/Remote Receiver Information
+ * are only valid at 1000 Mbps.
+ */
+- phy_info->cable_length =
++ phy_info->cable_length =
+ (phy_data & M88E1000_PSSR_CABLE_LENGTH)
+ >> M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+
+- ret_val = iegbe_oem_read_phy_reg_ex(hw, PHY_1000T_STATUS,
++ ret_val = iegbe_oem_read_phy_reg_ex(hw, PHY_1000T_STATUS,
+ &phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read register PHY_1000T_STATUS\n");
+ return ret_val;
+ }
+
+- phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
++ phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
+ >> SR_1000T_LOCAL_RX_STATUS_SHIFT;
+-
+- phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS)
++
++ phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS)
+ >> SR_1000T_REMOTE_RX_STATUS_SHIFT;
+ }
+-
++
+ break;
+ default:
+ DEBUGOUT("Invalid PHY ID\n");
+@@ -1801,7 +1617,7 @@ iegbe_oem_phy_get_info(struct iegbe_hw *
+ * This function will perform a software initiated reset of
+ * the PHY
+ **/
+-int32_t
++int32_t
+ iegbe_oem_phy_hw_reset(struct iegbe_hw *hw)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -1815,18 +1631,13 @@ iegbe_oem_phy_hw_reset(struct iegbe_hw *
+ return -1;
+ }
+ /*
+- * This code pretty much copies the default case from
++ * This code pretty much copies the default case from
+ * iegbe_phy_reset() as that is what is appropriate for
+- * the M88 used in truxton.
++ * the M88 used in truxton.
+ */
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- DEBUGOUT("WARNING: An empty iegbe_oem_phy_hw_reset() has been called!\n");
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- case BCM5481_PHY_ID:
+ ret_val = iegbe_oem_read_phy_reg_ex(hw, PHY_CTRL, &phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read register PHY_CTRL\n");
+@@ -1864,7 +1675,7 @@ iegbe_oem_phy_hw_reset(struct iegbe_hw *
+ * to perform and post reset initialiation. Not all PHYs require
+ * this, which is why it was split off as a seperate function.
+ **/
+-void
++void
+ iegbe_oem_phy_init_script(struct iegbe_hw *hw)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -1877,19 +1688,17 @@ iegbe_oem_phy_init_script(struct iegbe_h
+
+ /* call the GCU func that can do any phy specific init
+ * functions after a reset
+- *
++ *
+ * Make note that the M88 phy is what'll be used on Truxton
+ *
+- * The closest thing is in iegbe_phy_init_script, however this is
++ * The closest thing is in iegbe_phy_init_script, however this is
+ * for the IGP style of phy. This is probably a no-op for truxton
+ * but may be needed by OEM's later on
+- *
++ *
+ */
+ switch (hw->phy_id) {
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- case BCM5481_PHY_ID:
+- case BCM5395S_PHY_ID:
+ DEBUGOUT("Nothing to do for OEM PHY Init");
+ break;
+ default:
+@@ -1926,13 +1735,8 @@ iegbe_oem_read_phy_reg_ex(struct iegbe_h
+ return -1;
+ }
+
+- if (hw->phy_id == BCM5395S_PHY_ID) {
+- DEBUGOUT("WARNING: iegbe_oem_read_phy_reg_ex() has been unexpectedly called!\n");
+- return -1;
+- }
+-
+ /* call the GCU func that will read the phy
+- *
++ *
+ * Make note that the M88 phy is what'll be used on Truxton.
+ *
+ * The closest thing is in iegbe_read_phy_reg_ex.
+@@ -1940,7 +1744,7 @@ iegbe_oem_read_phy_reg_ex(struct iegbe_h
+ * NOTE: this is 1 (of 2) functions that is truly dependant on the
+ * gcu module
+ */
+-
++
+ ret_val = gcu_read_eth_phy(iegbe_oem_get_phy_dev_number(hw),
+ reg_addr, phy_data);
+ if(ret_val) {
+@@ -1962,10 +1766,10 @@ iegbe_oem_read_phy_reg_ex(struct iegbe_h
+ *
+ * Returns E1000_SUCCESS, negative E1000 error code on failure
+ *
+- * This is called from iegbe_config_mac_to_phy. Various supported
++ * This is called from iegbe_config_mac_to_phy. Various supported
+ * Phys may require the RGMII/RMII Translation gasket be set to RMII.
+ **/
+-int32_t
++int32_t
+ iegbe_oem_set_trans_gasket(struct iegbe_hw *hw)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -1978,17 +1782,12 @@ iegbe_oem_set_trans_gasket(struct iegbe_
+ }
+
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- case BCM5481_PHY_ID:
+- DEBUGOUT("WARNING: An empty iegbe_oem_set_trans_gasket() has been called!\n");
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ /* Gasket set correctly for Marvell Phys, so nothing to do */
+ break;
+ /* Add your PHY_ID here if your device requires an RMII interface
+- case YOUR_PHY_ID:
++ case YOUR_PHY_ID:
+ ctrl_aux_reg = E1000_READ_REG(hw, CTRL_AUX);
+ ctrl_aux_reg |= E1000_CTRL_AUX_ICP_xxxx_MII_TGS; // Set the RGMII_RMII bit
+ */
+@@ -2032,7 +1831,7 @@ iegbe_oem_write_phy_reg_ex(struct iegbe_
+ return -1;
+ }
+ /* call the GCU func that will write to the phy
+- *
++ *
+ * Make note that the M88 phy is what'll be used on Truxton.
+ *
+ * The closest thing is in iegbe_write_phy_reg_ex
+@@ -2062,11 +1861,11 @@ iegbe_oem_write_phy_reg_ex(struct iegbe_
+ * @hw struct iegbe_hw hardware specific data
+ *
+ * iegbe_reset_hw is called to reset the MAC. If, for
+- * some reason the PHY needs to be reset as well, this
++ * some reason the PHY needs to be reset as well, this
+ * should return TRUE and then iegbe_oem_phy_hw_reset()
+ * will be called.
+ **/
+-int
++int
+ iegbe_oem_phy_needs_reset_with_mac(struct iegbe_hw *hw)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -2079,16 +1878,14 @@ iegbe_oem_phy_needs_reset_with_mac(struc
+ return FALSE;
+ }
+
+- /*
++ /*
+ * From the original iegbe driver, the M88
+- * PHYs did not seem to need this reset,
++ * PHYs did not seem to need this reset,
+ * so returning FALSE.
+ */
+ switch (hw->phy_id) {
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- case BCM5481_PHY_ID:
+- case BCM5395S_PHY_ID:
+ ret_val = FALSE;
+ break;
+ default:
+@@ -2116,7 +1913,7 @@ iegbe_oem_phy_needs_reset_with_mac(struc
+ * tweaking of the PHY, for PHYs that support a DSP.
+ *
+ **/
+-int32_t
++int32_t
+ iegbe_oem_config_dsp_after_link_change(struct iegbe_hw *hw,
+ int link_up)
+ {
+@@ -2138,8 +1935,6 @@ iegbe_oem_config_dsp_after_link_change(s
+ switch (hw->phy_id) {
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- case BCM5481_PHY_ID:
+- case BCM5395S_PHY_ID:
+ DEBUGOUT("No DSP to configure on OEM PHY");
+ break;
+ default:
+@@ -2165,7 +1960,7 @@ iegbe_oem_config_dsp_after_link_change(s
+ *
+ *
+ **/
+-int32_t
++int32_t
+ iegbe_oem_get_cable_length(struct iegbe_hw *hw,
+ uint16_t *min_length,
+ uint16_t *max_length)
+@@ -2177,21 +1972,15 @@ iegbe_oem_get_cable_length(struct iegbe_
+ uint16_t phy_data;
+
+ DEBUGFUNC1("%s",__func__);
+-
++
+ if(!hw || !min_length || !max_length) {
+ return -1;
+ }
+
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- case BCM5481_PHY_ID:
+- *min_length = 0;
+- *max_length = iegbe_igp_cable_length_150;
+- break;
+-
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- ret_val = iegbe_oem_read_phy_reg_ex(hw,
++ ret_val = iegbe_oem_read_phy_reg_ex(hw,
+ M88E1000_PHY_SPEC_STATUS,
+ &phy_data);
+ if(ret_val) {
+@@ -2246,13 +2035,13 @@ iegbe_oem_get_cable_length(struct iegbe_
+ /**
+ * iegbe_oem_phy_is_link_up
+ * @hw iegbe_hw struct containing device specific information
+- * @isUp a boolean returning true if link is up
++ * @isUp a boolean returning true if link is up
+ *
+ * This is called as part of iegbe_config_mac_to_phy() to align
+ * the MAC with the PHY. It turns out on ICP_XXXX, this is not
+ * done automagically.
+ **/
+-int32_t
++int32_t
+ iegbe_oem_phy_is_link_up(struct iegbe_hw *hw, int *isUp)
+ {
+ #ifdef EXTERNAL_MDIO
+@@ -2266,35 +2055,19 @@ iegbe_oem_phy_is_link_up(struct iegbe_hw
+ if(!hw || !isUp) {
+ return -1;
+ }
+- /*
++ /*
+ * Make note that the M88 phy is what'll be used on Truxton
+ * see iegbe_config_mac_to_phy
+ */
+
+ switch (hw->phy_id) {
+- case BCM5395S_PHY_ID:
+- /* Link always up */
+- *isUp = TRUE;
+- return E1000_SUCCESS;
+- break;
+-
+- case BCM5481_PHY_ID:
+- iegbe_oem_read_phy_reg_ex(hw, BCM5481_ESTAT, &phy_data);
+- ret_val = iegbe_oem_read_phy_reg_ex(hw, BCM5481_ESTAT, &phy_data);
+- if(ret_val)
+- {
+- DEBUGOUT("Unable to read PHY register BCM5481_ESTAT\n");
+- return ret_val;
+- }
+- statusMask = BCM5481_ESTAT_LINK;
+- break;
+-
+- case M88E1000_I_PHY_ID:
++ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+- iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
+- ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
++ iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
++ ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
++ &phy_data);
+ statusMask = M88E1000_PSSR_LINK;
+- break;
++ break;
+ default:
+ DEBUGOUT("Invalid PHY ID\n");
+ return -E1000_ERR_PHY_TYPE;
+@@ -2319,213 +2092,3 @@ iegbe_oem_phy_is_link_up(struct iegbe_hw
+ #endif /* ifdef EXTERNAL_MDIO */
+ }
+
+-
+-
+-//-----
+-// Read BCM5481 expansion register
+-//
+-int32_t
+-bcm5481_read_ex (struct iegbe_hw *hw, uint16_t reg, uint16_t *data)
+-{
+- int ret;
+- uint16_t selector;
+- uint16_t reg_data;
+-
+- // Get the current value of bits 15:12
+- ret = iegbe_oem_read_phy_reg_ex (hw, 0x15, &selector);
+- if (ret)
+- return ret;
+-
+- // Select the expansion register
+- selector &= 0xf000;
+- selector |= (0xf << 8) | (reg);
+- iegbe_oem_write_phy_reg_ex (hw, 0x17, selector);
+-
+- // Read the expansion register
+- ret = iegbe_oem_read_phy_reg_ex (hw, 0x15, &reg_data);
+-
+- // De-select the expansion registers.
+- selector &= 0xf000;
+- iegbe_oem_write_phy_reg_ex (hw, 0x17, selector);
+-
+- if (ret)
+- return ret;
+-
+- *data = reg_data;
+- return ret;
+-}
+-
+-//-----
+-// Read reg 0x18 sub-register
+-//
+-static int32_t
+-bcm5481_read_18sv (struct iegbe_hw *hw, int sv, uint16_t *data)
+-{
+- int ret;
+- uint16_t tmp_data;
+-
+- // Select reg 0x18, sv
+- tmp_data = ((sv & BCM5481_R18H_SV_MASK) << 12) | BCM5481_R18H_SV_MCTRL;
+- ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R18H, tmp_data);
+- if(ret)
+- return ret;
+-
+- // Read reg 0x18, sv
+- ret = iegbe_oem_read_phy_reg_ex (hw, BCM5481_R18H, &tmp_data);
+- if(ret)
+- return ret;
+-
+- *data = tmp_data;
+- return ret;
+-}
+-
+-//-----
+-// Read reg 0x1C sub-register
+-//
+-int32_t
+-bcm5481_read_1csv (struct iegbe_hw *hw, int sv, uint16_t *data)
+-{
+- int ret;
+- uint16_t tmp_data;
+-
+- // Select reg 0x1c, sv
+- tmp_data = ((sv & BCM5481_R1CH_SV_MASK) << BCM5481_R1CH_SV_SHIFT);
+-
+- ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R1CH, tmp_data);
+- if(ret)
+- return ret;
+-
+- // Read reg 0x1c, sv
+- ret = iegbe_oem_read_phy_reg_ex (hw, BCM5481_R1CH, &tmp_data);
+- if(ret)
+- return ret;
+-
+- *data = tmp_data;
+- return ret;
+-}
+-
+-//-----
+-// Read-modify-write a 0x1C register.
+-//
+-// hw - hardware access info.
+-// reg - 0x1C register to modify.
+-// data - bits which should be set.
+-// mask - the '1' bits in this argument will be cleared in the data
+-// read from 'reg' then 'data' will be or'd in and the result
+-// will be written to 'reg'.
+-
+-int32_t
+-bcm5481_rmw_1csv (struct iegbe_hw *hw, uint16_t reg, uint16_t data, uint16_t mask)
+-{
+- int32_t ret;
+- uint16_t reg_data;
+-
+- ret = 0;
+-
+- ret = bcm5481_read_1csv (hw, reg, &reg_data);
+- if (ret)
+- {
+- DEBUGOUT("Unable to read BCM5481 1CH register\n");
+- printk (KERN_ERR "Unable to read BCM5481 1CH register [0x%x]\n", reg);
+- return ret;
+- }
+-
+- reg_data &= ~mask;
+- reg_data |= (BCM5481_R1CH_WE | data);
+-
+- ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R1CH, reg_data);
+- if(ret)
+- {
+- DEBUGOUT("Unable to write BCM5481 1CH register\n");
+- printk (KERN_ERR "Unable to write BCM5481 1CH register\n");
+- return ret;
+- }
+-
+- return ret;
+-}
+-
+-int32_t
+-oi_phy_setup (struct iegbe_hw *hw)
+-{
+- int ret;
+- uint16_t pmii_data;
+- uint16_t mctrl_data;
+- uint16_t cacr_data;
+- uint16_t sc1_data;
+- uint16_t lctl_data;
+-
+- ret = 0;
+-
+- // Set low power mode via reg 0x18, sv010, bit 6
+- // Do a read-modify-write on reg 0x18, sv010 register to preserve existing bits.
+- ret = bcm5481_read_18sv (hw, BCM5481_R18H_SV_PMII, &pmii_data);
+- if (ret)
+- {
+- DEBUGOUT("Unable to read BCM5481_R18H_SV_PMII register\n");
+- printk (KERN_ERR "Unable to read BCM5481_R18H_SV_PMII register\n");
+- return ret;
+- }
+-
+- // Set the LPM bit in the data just read and write back to sv010
+- // The shadow register select bits [2:0] are set by reading the sv010
+- // register.
+- pmii_data |= BCM5481_R18H_SV010_LPM;
+- ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R18H, pmii_data);
+- if(ret)
+- {
+- DEBUGOUT("Unable to write BCM5481_R18H register\n");
+- printk (KERN_ERR "Unable to write BCM5481_R18H register\n");
+- return ret;
+- }
+-
+-
+- // Set the RGMII RXD to RXC skew bit in reg 0x18, sv111
+-
+- if (bcm5481_read_18sv (hw, BCM5481_R18H_SV_MCTRL, &mctrl_data))
+- {
+- DEBUGOUT("Unable to read BCM5481_R18H_SV_MCTRL register\n");
+- printk (KERN_ERR "Unable to read BCM5481_R18H_SV_MCTRL register\n");
+- return ret;
+- }
+- mctrl_data |= (BCM5481_R18H_WE | BCM5481_R18H_SV111_SKEW);
+-
+- ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R18H, mctrl_data);
+- if(ret)
+- {
+- DEBUGOUT("Unable to write BCM5481_R18H register\n");
+- printk (KERN_ERR "Unable to write BCM5481_R18H register\n");
+- return ret;
+- }
+-
+-
+- // Enable RGMII transmit clock delay in reg 0x1c, sv00011
+- ret = bcm5481_read_1csv (hw, BCM5481_R1CH_CACR, &cacr_data);
+- if (ret)
+- {
+- DEBUGOUT("Unable to read BCM5481_R1CH_CACR register\n");
+- printk (KERN_ERR "Unable to read BCM5481_R1CH_CACR register\n");
+- return ret;
+- }
+-
+- cacr_data |= (BCM5481_R1CH_WE | BCM5481_R1CH_CACR_TCD);
+-
+- ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R1CH, cacr_data);
+- if(ret)
+- {
+- DEBUGOUT("Unable to write BCM5481_R1CH register\n");
+- printk (KERN_ERR "Unable to write BCM5481_R1CH register\n");
+- return ret;
+- }
+-
+- // Enable dual link speed indication (0x1c, sv 00010, bit 2)
+- ret = bcm5481_rmw_1csv (hw, BCM5481_R1CH_SC1, BCM5481_R1CH_SC1_LINK, BCM5481_R1CH_SC1_LINK);
+- if (ret)
+- return ret;
+-
+- // Enable link and activity on ACTIVITY LED (0x1c, sv 01001, bit 4=1, bit 3=0)
+- ret = bcm5481_rmw_1csv (hw, BCM5481_R1CH_LCTRL, BCM5481_R1CH_LCTRL_ALEN, BCM5481_R1CH_LCTRL_ALEN | BCM5481_R1CH_LCTRL_AEN);
+- if (ret)
+- return ret;
+-
+- return ret;
+-}
+--- a/Embedded/src/GbE/iegbe_oem_phy.h
++++ b/Embedded/src/GbE/iegbe_oem_phy.h
+@@ -2,31 +2,31 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+- This program is free software; you can redistribute it and/or modify
++ 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
++ This program is distributed in the hope that it will be useful, but
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+- You should have received a copy of the GNU General Public License
+- along with this program; if not, write to the Free Software
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+- The full GNU General Public License is included in this distribution
++ The full GNU General Public License is included in this distribution
+ in the file called LICENSE.GPL.
+
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+-
+- Intel Corporation, 5000 W Chandler Blvd, Chandler, AZ 85226
++
++ Intel Corporation, 5000 W Chandler Blvd, Chandler, AZ 85226
+
+ *******************************************************************************/
+ #ifndef _IEGBE_OEM_PHY_H_
+@@ -45,10 +45,10 @@ int32_t iegbe_oem_set_trans_gasket(struc
+ uint32_t iegbe_oem_get_tipg(struct iegbe_hw *hw);
+ int iegbe_oem_phy_is_copper(struct iegbe_hw *hw);
+ uint32_t iegbe_oem_get_phy_dev_number(struct iegbe_hw *hw);
+-int iegbe_oem_mii_ioctl(struct iegbe_adapter *adapter, unsigned long flags,
++int iegbe_oem_mii_ioctl(struct iegbe_adapter *adapter, unsigned long flags,
+ struct ifreq *ifr, int cmd);
+ void iegbe_oem_fiber_live_in_suspend(struct iegbe_hw *hw);
+-void iegbe_oem_get_phy_regs(struct iegbe_adapter *adapter, uint32_t *data,
++void iegbe_oem_get_phy_regs(struct iegbe_adapter *adapter, uint32_t *data,
+ uint32_t data_length);
+ int iegbe_oem_phy_loopback(struct iegbe_adapter *adapter);
+ void iegbe_oem_loopback_cleanup(struct iegbe_adapter *adapter);
+@@ -94,81 +94,14 @@ int32_t iegbe_oem_phy_is_link_up(struct
+ #define ICP_XXXX_MAC_2 2
+
+ #define DEFAULT_ICP_XXXX_TIPG_IPGT 8 /* Inter Packet Gap Transmit Time */
+-#define ICP_XXXX_TIPG_IPGT_MASK 0x000003FFUL
+-#define BCM5481_PHY_ID 0x0143BCA2
+-#define BCM5395S_PHY_ID 0x0143BCF0
++#define ICP_XXXX_TIPG_IPGT_MASK 0x000003FFUL
+
+ /* Miscellaneous defines */
+ #ifdef IEGBE_10_100_ONLY
+- #define ICP_XXXX_AUTONEG_ADV_DEFAULT 0x0F
++ #define ICP_XXXX_AUTONEG_ADV_DEFAULT 0x0F
+ #else
+ #define ICP_XXXX_AUTONEG_ADV_DEFAULT 0x2F
+ #endif
+
+-//-----
+-// BCM5481 specifics
+-
+-#define BCM5481_ECTRL (0x10)
+-#define BCM5481_ESTAT (0x11)
+-#define BCM5481_RXERR (0x12)
+-#define BCM5481_EXPRW (0x15)
+-#define BCM5481_EXPACC (0x17)
+-#define BCM5481_ASTAT (0x19)
+-#define BCM5481_R18H (0x18)
+-#define BCM5481_R1CH (0x1c)
+-
+-//-----
+-// indirect register access via register 18h
+-
+-#define BCM5481_R18H_SV_MASK (7) // Mask for SV bits.
+-#define BCM5481_R18H_SV_ACTRL (0) // SV000 Aux. control
+-#define BCM5481_R18H_SV_10BT (1) // SV001 10Base-T
+-#define BCM5481_R18H_SV_PMII (2) // SV010 Power/MII control
+-#define BCM5481_R18H_SV_MTEST (4) // SV100 Misc. test
+-#define BCM5481_R18H_SV_MCTRL (7) // SV111 Misc. control
+-
+-#define BCM5481_R18H_SV001_POL (1 << 13) // Polarity
+-#define BCM5481_R18H_SV010_LPM (1 << 6)
+-#define BCM5481_R18H_SV111_SKEW (1 << 8)
+-#define BCM5481_R18H_WE (1 << 15) // Write enable
+-
+-// 0x1c registers
+-#define BCM5481_R1CH_SV_SHIFT (10)
+-#define BCM5481_R1CH_SV_MASK (0x1f)
+-#define BCM5481_R1CH_SC1 (0x02) // sv00010 Spare control 1
+-#define BCM5481_R1CH_CACR (0x03) // sv00011 Clock alignment control
+-#define BCM5481_R1CH_LCTRL (0x09) // sv01001 LED control
+-#define BCM5481_R1CH_LEDS1 (0x0d) // sv01101 LED selector 1
+-
+-// 0x1c common
+-#define BCM5481_R1CH_WE (1 << 15) // Write enable
+-
+-// 0x1c, sv 00010
+-#define BCM5481_R1CH_SC1_LINK (1 << 2) // sv00010 Linkspeed
+-
+-// 0x1c, sv 00011
+-#define BCM5481_R1CH_CACR_TCD (1 << 9) // sv00011 RGMII tx clock delay
+-
+-// 0x1c, sv 01001
+-#define BCM5481_R1CH_LCTRL_ALEN (1 << 4) // Activity/Link enable on ACTIVITY LED
+-#define BCM5481_R1CH_LCTRL_AEN (1 << 3) // Activity enable on ACTIVITY LED
+-
+-
+-#define BCM5481_ECTRL_DISMDIX (1 <<14)
+-
+-#define BCM5481_MCTRL_AUTOMDIX (1 <<9)
+-
+-#define BCM5481_ESTAT_LINK (1 << 8)
+-
+-#define BCM5481_ASTAT_ANC (1 << 15)
+-#define BCM5481_ASTAT_ANHCD (7 << 8)
+-#define BCM5481_ASTAT_HCD(x) ((x >> 8) & 7)
+-#define BCM5481_ASTAT_1KBTFD (0x7)
+-#define BCM5481_ASTAT_1KBTHD (0x6)
+-#define BCM5481_ASTAT_100BTXFD (0x5)
+-#define BCM5481_ASTAT_100BTXHD (0x3)
+-
+-// end BCM5481 specifics
+-
+ #endif /* ifndef _IEGBE_OEM_PHY_H_ */
+-
++
+--- a/Embedded/src/GbE/iegbe_osdep.h
++++ b/Embedded/src/GbE/iegbe_osdep.h
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+--- a/Embedded/src/GbE/iegbe_param.c
++++ b/Embedded/src/GbE/iegbe_param.c
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+@@ -239,11 +239,7 @@ E1000_PARAM(InterruptThrottleRate, "Inte
+ #define MAX_TXABSDELAY 0xFFFF
+ #define MIN_TXABSDELAY 0
+
+-#ifdef IEGBE_GBE_WORKAROUND
+-#define DEFAULT_ITR 0
+-#else
+ #define DEFAULT_ITR 8000
+-#endif
+
+
+ #define MAX_ITR 100000
+@@ -373,7 +369,7 @@ iegbe_check_options(struct iegbe_adapter
+ tx_ring->count = opt.def;
+ }
+ #endif
+- for (i = 0; i < adapter->num_queues; i++)
++ for (i = 0; i < adapter->num_tx_queues; i++)
+ tx_ring[i].count = tx_ring->count;
+ }
+ { /* Receive Descriptor Count */
+@@ -403,7 +399,7 @@ iegbe_check_options(struct iegbe_adapter
+ rx_ring->count = opt.def;
+ }
+ #endif
+- for (i = 0; i < adapter->num_queues; i++)
++ for (i = 0; i < adapter->num_rx_queues; i++)
+ rx_ring[i].count = rx_ring->count;
+ }
+ { /* Checksum Offload Enable/Disable */
+--- a/Embedded/src/GbE/kcompat.c
++++ b/Embedded/src/GbE/kcompat.c
+@@ -1,8 +1,8 @@
+-/************************************************************
+-
++/************************************************************
++
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,183 +22,192 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
+-
+- Contact Information:
+-
+- Intel Corporation, 5000 W Chandler Blvd, Chandler, AZ 85226
+-
+-**************************************************************/
+-/**************************************************************************
+- * @ingroup KCOMPAT_GENERAL
+- *
+- * @file kcompat.c
+- *
+- * @description
+- *
+- *
+- **************************************************************************/
+-#include "kcompat.h"
+-
+-/*************************************************************/
+-/* 2.4.13 => 2.4.3 */
+-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(0x2,0x4,0xd) )
+-
+-/**************************************/
+-/* PCI DMA MAPPING */
+-
+-#if defined(CONFIG_HIGHMEM)
+-
+-#ifndef PCI_DRAM_OFFSET
+-#define PCI_DRAM_OFFSET 0
+-#endif
+-
+-u64 _kc_pci_map_page(struct pci_dev *dev,
+- struct page *page,
+- unsigned long offset,
+- size_t size,
+- int direction)
+-{
+- u64 ret_val;
+- ret_val = (((u64)(page - mem_map) << PAGE_SHIFT) + offset +
+- PCI_DRAM_OFFSET);
+- return ret_val;
+-}
+-
+-#else /* CONFIG_HIGHMEM */
+-
+-u64 _kc_pci_map_page(struct pci_dev *dev,
+- struct page *page,
+- unsigned long offset,
+- size_t size,
+- int direction)
+-{
+- return pci_map_single(dev, (void *)page_address(page) + offset,
+- size, direction);
+-}
+-
+-#endif /* CONFIG_HIGHMEM */
+-
+-void _kc_pci_unmap_page(struct pci_dev *dev,
+- u64 dma_addr,
+- size_t size,
+- int direction)
+-{
+- return pci_unmap_single(dev, dma_addr, size, direction);
+-}
+-
+-#endif /* 2.4.13 => 2.4.3 */
+-
+-
+-/*****************************************************************************/
+-/* 2.4.3 => 2.4.0 */
+-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(0x2,0x4,0x3) )
+-
+-/**************************************/
+-/* PCI DRIVER API */
+-
+-int _kc_pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask)
+-{
+- if(!pci_dma_supported(dev, mask)) {
+- return -EIO;
+- }
+- dev->dma_mask = mask;
+- return 0;
+-}
+-
+-int _kc_pci_request_regions(struct pci_dev *dev, char *res_name)
+-{
+- int i;
+-
+- for (i = 0; i < 0x6; i++) {
+- if (pci_resource_len(dev, i) == 0) {
+- continue;
+- }
+- if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
+- if (!request_region(pci_resource_start(dev, i),
+- pci_resource_len(dev, i), res_name)) {
+- pci_release_regions(dev);
+- return -EBUSY;
+- }
+- } else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) {
+- if (!request_mem_region(pci_resource_start(dev, i),
+- pci_resource_len(dev, i),
+- res_name)) {
+- pci_release_regions(dev);
+- return -EBUSY;
+- }
+- }
+- }
+- return 0;
+-}
+-
+-void _kc_pci_release_regions(struct pci_dev *dev)
+-{
+- int i;
+-
+- for (i = 0; i < 0x6; i++) {
+- if (pci_resource_len(dev, i) == 0) {
+- continue;
+- }
+- if (pci_resource_flags(dev, i) & IORESOURCE_IO){
+- release_region(pci_resource_start(dev, i),
+- pci_resource_len(dev, i));
+- } else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) {
+- release_mem_region(pci_resource_start(dev, i),
+- pci_resource_len(dev, i));
+- }
+- }
+-}
+-
+-/**************************************/
+-/* NETWORK DRIVER API */
+-
+-struct net_device * _kc_alloc_etherdev(int sizeof_priv)
+-{
+- struct net_device *dev;
+- int alloc_size;
+-
+- alloc_size = sizeof(*dev) + sizeof_priv + IFNAMSIZ + 0x1f;
+-
+- dev = kmalloc(alloc_size, GFP_KERNEL);
+-
+- if (!dev) { return NULL; }
+-
+- memset(dev, 0, alloc_size);
+-
+- if (sizeof_priv) {
+- dev->priv = (void *) (((unsigned long)(dev + 1) + 0x1f) & ~0x1f);
+- }
+- dev->name[0] = '\0';
+-
+- ether_setup(dev);
+-
+- return dev;
+-}
+-
+-int _kc_is_valid_ether_addr(u8 *addr)
+-{
+- const char zaddr[0x6] = {0,};
+-
+- return !(addr[0]&1) && memcmp( addr, zaddr, 0x6);
+-}
+-
+-#endif /* 2.4.3 => 2.4.0 */
+-
+-
+-/*****************************************************************/
+-/* 2.4.6 => 2.4.3 */
+-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(0x2,0x4,0x6) )
+-
+-int _kc_pci_set_power_state(struct pci_dev *dev, int state)
+-{ return 0; }
+-int _kc_pci_save_state(struct pci_dev *dev, u32 *buffer)
+-{ return 0; }
+-int _kc_pci_restore_state(struct pci_dev *pdev, u32 *buffer)
+-{ return 0; }
+-int _kc_pci_enable_wake(struct pci_dev *pdev, u32 state, int enable)
+-{ return 0; }
+-
+-#endif /* 2.4.6 => 2.4.3 */
+-
+-
++ version: Embedded.Release.Patch.L.1.0.7-5
++
++ Contact Information:
++
++ Intel Corporation, 5000 W Chandler Blvd, Chandler, AZ 85226
++
++**************************************************************/
++/**************************************************************************
++ * @ingroup KCOMPAT_GENERAL
++ *
++ * @file kcompat.c
++ *
++ * @description
++ *
++ *
++ **************************************************************************/
++#include "kcompat.h"
++
++/*************************************************************/
++/* 2.4.13 => 2.4.3 */
++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(0x2,0x4,0xd) )
++
++/**************************************/
++/* PCI DMA MAPPING */
++
++#if defined(CONFIG_HIGHMEM)
++
++#ifndef PCI_DRAM_OFFSET
++#define PCI_DRAM_OFFSET 0
++#endif
++
++u64 _kc_pci_map_page(struct pci_dev *dev,
++ struct page *page,
++ unsigned long offset,
++ size_t size,
++ int direction)
++{
++ u64 ret_val;
++ ret_val = (((u64)(page - mem_map) << PAGE_SHIFT) + offset +
++ PCI_DRAM_OFFSET);
++ return ret_val;
++}
++
++#else /* CONFIG_HIGHMEM */
++
++u64 _kc_pci_map_page(struct pci_dev *dev,
++ struct page *page,
++ unsigned long offset,
++ size_t size,
++ int direction)
++{
++ return pci_map_single(dev, (void *)page_address(page) + offset,
++ size, direction);
++}
++
++#endif /* CONFIG_HIGHMEM */
++
++void _kc_pci_unmap_page(struct pci_dev *dev,
++ u64 dma_addr,
++ size_t size,
++ int direction)
++{
++ return pci_unmap_single(dev, dma_addr, size, direction);
++}
++
++#endif /* 2.4.13 => 2.4.3 */
++
++
++/*****************************************************************************/
++/* 2.4.3 => 2.4.0 */
++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(0x2,0x4,0x3) )
++
++/**************************************/
++/* PCI DRIVER API */
++
++int _kc_pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask)
++{
++ if(!pci_dma_supported(dev, mask)) {
++ return -EIO;
++ }
++ dev->dma_mask = mask;
++ return 0;
++}
++
++int _kc_pci_request_regions(struct pci_dev *dev, char *res_name)
++{
++ int i;
++
++ for (i = 0; i < 0x6; i++) {
++ if (pci_resource_len(dev, i) == 0) {
++ continue;
++ }
++ if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
++ if (!request_region(pci_resource_start(dev, i),
++ pci_resource_len(dev, i), res_name)) {
++ pci_release_regions(dev);
++ return -EBUSY;
++ }
++ } else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) {
++ if (!request_mem_region(pci_resource_start(dev, i),
++ pci_resource_len(dev, i),
++ res_name)) {
++ pci_release_regions(dev);
++ return -EBUSY;
++ }
++ }
++ }
++ return 0;
++}
++
++void _kc_pci_release_regions(struct pci_dev *dev)
++{
++ int i;
++
++ for (i = 0; i < 0x6; i++) {
++ if (pci_resource_len(dev, i) == 0) {
++ continue;
++ }
++ if (pci_resource_flags(dev, i) & IORESOURCE_IO){
++ release_region(pci_resource_start(dev, i),
++ pci_resource_len(dev, i));
++ } else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) {
++ release_mem_region(pci_resource_start(dev, i),
++ pci_resource_len(dev, i));
++ }
++ }
++}
++
++/**************************************/
++/* NETWORK DRIVER API */
++
++struct net_device * _kc_alloc_etherdev(int sizeof_priv)
++{
++ struct net_device *dev;
++ int alloc_size;
++
++ alloc_size = sizeof(*dev) + sizeof_priv + IFNAMSIZ + 0x1f;
++
++ dev = kmalloc(alloc_size, GFP_KERNEL);
++
++ if (!dev) { return NULL; }
++
++ memset(dev, 0, alloc_size);
++
++ if (sizeof_priv) {
++ dev->priv = (void *) (((unsigned long)(dev + 1) + 0x1f) & ~0x1f);
++ }
++ dev->name[0] = '\0';
++
++ ether_setup(dev);
++
++ return dev;
++}
++
++int _kc_is_valid_ether_addr(u8 *addr)
++{
++ const char zaddr[0x6] = {0,};
++
++ return !(addr[0]&1) && memcmp( addr, zaddr, 0x6);
++}
++
++#endif /* 2.4.3 => 2.4.0 */
++
++
++/*****************************************************************/
++/* 2.4.6 => 2.4.3 */
++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(0x2,0x4,0x6) )
++
++int _kc_pci_set_power_state(struct pci_dev *dev, int state)
++{ return 0; }
++int _kc_pci_save_state(struct pci_dev *dev, u32 *buffer)
++{ return 0; }
++int _kc_pci_restore_state(struct pci_dev *pdev, u32 *buffer)
++{ return 0; }
++int _kc_pci_enable_wake(struct pci_dev *pdev, u32 state, int enable)
++{ return 0; }
++
++#endif /* 2.4.6 => 2.4.3 */
++
++
++
++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,24) )
++
++void dump_stack(void)
++{
++}
++
++#endif /* 2.4.24 */
++
+--- a/Embedded/src/GbE/kcompat_ethtool.c
++++ b/Embedded/src/GbE/kcompat_ethtool.c
+@@ -2,7 +2,7 @@
+ /*
+ * GPL LICENSE SUMMARY
+ *
+- * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@
+ * Contact Information:
+ * Intel Corporation
+ *
+- * version: Embedded.L.1.0.34
++ * version: Embedded.Release.Patch.L.1.0.7-5
+ */
+
+ /**************************************************************************
+@@ -779,6 +779,7 @@ static int ethtool_get_stats(struct net_
+ }
+
+ /* The main entry point in this file. Called from net/core/dev.c */
++
+ #define ETHTOOL_OPS_COMPAT
+ int ethtool_ioctl(struct ifreq *ifr)
+ {
+--- a/Embedded/src/GbE/kcompat.h
++++ b/Embedded/src/GbE/kcompat.h
+@@ -2,7 +2,7 @@
+
+ GPL LICENSE SUMMARY
+
+- Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+@@ -22,7 +22,7 @@ GPL LICENSE SUMMARY
+ Contact Information:
+ Intel Corporation
+
+- version: Embedded.L.1.0.34
++ version: Embedded.Release.Patch.L.1.0.7-5
+
+ Contact Information:
+
+@@ -69,15 +69,6 @@ GPL LICENSE SUMMARY
+ #define CONFIG_NET_POLL_CONTROLLER
+ #endif
+
+-#ifdef E1000_NAPI
+-#undef CONFIG_E1000_NAPI
+-#define CONFIG_E1000_NAPI
+-#endif
+-
+-#ifdef E1000_NO_NAPI
+-#undef CONFIG_E1000_NAPI
+-#endif
+-
+ #ifndef module_param
+ #define module_param(v,t,p) MODULE_PARM(v, "i");
+ #endif
+@@ -554,35 +545,14 @@ extern void _kc_pci_unmap_page(struct pc
+ #endif
+
+ /*****************************************************************************/
+-/* 2.4.23 => 2.4.22 */
+-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) )
+-#ifdef CONFIG_E1000_NAPI
+-#ifndef netif_poll_disable
+-#define netif_poll_disable(x) _kc_netif_poll_disable(x)
+-static inline void _kc_netif_poll_disable(struct net_device *netdev)
+-{
+- while (test_and_set_bit(__LINK_STATE_RX_SCHED, &netdev->state)) {
+- /* No hurry */
+- current->state = TASK_INTERRUPTIBLE;
+- schedule_timeout(1);
+- }
+-}
+-#endif
+-#ifndef netif_poll_enable
+-#define netif_poll_enable(x) _kc_netif_poll_enable(x)
+-static inline void _kc_netif_poll_enable(struct net_device *netdev)
+-{
+- clear_bit(__LINK_STATE_RX_SCHED, &netdev->state);
+-}
+-#endif
+-#endif
+-#endif
+-
+-/*****************************************************************************/
+ /* 2.5.28 => 2.4.23 */
+ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) )
+
++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) )
++static inline void _kc_synchronize_irq(void) { barrier(); }
++#else
+ static inline void _kc_synchronize_irq() { synchronize_irq(); }
++#endif /* 2.4.23 */
+ #undef synchronize_irq
+ #define synchronize_irq(X) _kc_synchronize_irq()
+
+@@ -747,6 +717,37 @@ static inline struct mii_ioctl_data *_kc
+ #define skb_header_cloned(x) 0
+ #endif /* SKB_DATAREF_SHIFT not defined */
+
++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) )
++
++#define ioread32(addr) readl(addr)
++#define iowrite32(val,addr) writel(val,addr)
++
++#endif /* 2.6.10 */
++
++#ifndef DEFINE_SPINLOCK
++#define DEFINE_SPINLOCK(s) spinlock_t s = SPIN_LOCK_UNLOCKED
++#endif /* DEFINE_SPINLOCK */
++
++#ifndef PCI_COMMAND_INTX_DISABLE
++#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
++#endif /* PCI_COMMAND_INTX_DISABLE */
++
++#ifndef ETH_GSTRING_LEN
++#define ETH_GSTRING_LEN 32
++#endif /* ETH_GSTRING_LEN */
++
++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,24) )
++
++extern void dump_stack(void);
++
++#undef register_reboot_notifier
++#define register_reboot_notifier(a)
++
++#undef unregister_reboot_notifier
++#define unregister_reboot_notifier(a)
++
++#endif /* 2.4.24 */
++
+ #endif /* _KCOMPAT_H_ */
+
+
+--- a/Embedded/src/GbE/Makefile
++++ b/Embedded/src/GbE/Makefile
+@@ -1,6 +1,6 @@
+ # GPL LICENSE SUMMARY
+ #
+-# Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ #
+ # This program is free software; you can redistribute it and/or modify
+ # it under the terms of version 2 of the GNU General Public License as
+@@ -20,7 +20,7 @@
+ # Contact Information:
+ # Intel Corporation
+ #
+-# version: Embedded.L.1.0.34
++# version: Embedded.Release.Patch.L.1.0.7-5
+
+ ###########################################################################
+ # Driver files
+@@ -35,6 +35,8 @@ MDIO_PHONY_CFILES = gcu.c
+ MDIO_CFILES = gcu_main.c gcu_if.c
+ MDIO_HFILES = gcu.h gcu_if.h gcu_reg.h kcompat.h
+
++KVER=$(shell uname -r)
++
+ #
+ # Variables:
+ # KSRC (path to kernel source to build against)
+@@ -50,45 +52,16 @@ MDIO_HFILES = gcu.h gcu_if.h gcu_reg.h k
+
+ # set KSRC, KOBJ, and EXTERNAL_MDIO to default values of not already set
+ #
+-KOBJ ?= /usr/src/kernels/linux
+-KSRC ?= /usr/src/kernels/linux
++#KOBJ=/usr/src/kernels/linux
++#KSRC=/usr/src/kernels/linux
++#KSRC=$(KOBJ)
+ EXTERNAL_MDIO ?= 1
+ GBE_NAME = iegbe
+ GCU_NAME = gcu
+
+-# By default the workaround for the IEGBE writeback issue is enabled
+-#
+-IEGBE_GBE_WORKAROUND ?= 0
+-
+-# If the platform only supports 10/100 this variable needs to be set
+-# so the default advertisement is set appropriately.
+-# By default, this variable will be disabled.
+-#
+-IEGBE_10_100_ONLY ?= 0
+-
+-# check for version.h and autoconf.h for running kernel in /boot (SUSE)
+-ifneq (,$(wildcard /boot/vmlinuz.version.h))
+- VERSION_FILE := /boot/vmlinuz.version.h
+- CONFIG_FILE := /boot/vmlinuz.autoconf.h
+- KVER := $(shell $(CC) $(CFLAGS) -E -dM $(VERSION_FILE) | \
+- grep UTS_RELEASE | awk '{ print $$3 }' | sed 's/\"//g')
+- ifeq ($(KVER),$(shell uname -r))
+- # set up include path to override headers from kernel source
+- x:=$(shell rm -rf include)
+- x:=$(shell mkdir -p include/linux)
+- x:=$(shell cp /boot/vmlinuz.version.h include/linux/version.h)
+- x:=$(shell cp /boot/vmlinuz.autoconf.h include/linux/autoconf.h)
+- CFLAGS += -I./include
+- else
+- VERSION_FILE := $(KOBJ)/include/linux/version.h
+- UTS_REL_FILE := $(KSRC)/include/linux/utsrelease.h
+- CONFIG_FILE := $(KOBJ)/include/linux/autoconf.h
+- endif
+-else
+- VERSION_FILE := $(KOBJ)/include/linux/version.h
+- UTS_REL_FILE := $(KSRC)/include/linux/utsrelease.h
+- CONFIG_FILE := $(KOBJ)/include/linux/autoconf.h
+-endif
++VERSION_FILE := $(KSRC)/include/linux/version.h
++UTS_REL_FILE := $(KSRC)/include/linux/utsrelease.h
++CONFIG_FILE := $(KSRC)/include/linux/autoconf.h
+
+ ifeq (,$(wildcard $(VERSION_FILE)))
+ $(error Linux kernel source not configured - missing version.h)
+@@ -98,83 +71,8 @@ ifeq (,$(wildcard $(CONFIG_FILE)))
+ $(error Linux kernel source not configured - missing autoconf.h)
+ endif
+
+-# as of 2.6.16, kernel define UTS_RELEASE has been moved to utsrelease.h
+-# so check that file for kernel version string instead of version.h
+-USE_UTS_REL := $(shell [ -f $(UTS_REL_FILE) ] && echo "1")
+-
+-# pick a compiler
+-ifneq (,$(findstring egcs-2.91.66, $(shell cat /proc/version)))
+- CC := kgcc gcc cc
+-else
+- CC := gcc cc
+-endif
+-test_cc = $(shell $(cc) --version > /dev/null 2>&1 && echo $(cc))
+-CC := $(foreach cc, $(CC), $(test_cc))
+-CC := $(firstword $(CC))
+-ifeq (,$(CC))
+- $(error Compiler not found)
+-endif
+-
+-# we need to know what platform the driver is being built on
+-# some additional features are only built on Intel platforms
+-ARCH := $(shell uname -m | sed 's/i.86/i386/')
+-ifeq ($(ARCH),alpha)
+- CFLAGS += -ffixed-8 -mno-fp-regs
+-endif
+-ifeq ($(ARCH),x86_64)
+- CFLAGS += -mcmodel=kernel -mno-red-zone
+-endif
+-ifeq ($(ARCH),ppc)
+- CFLAGS += -msoft-float
+-endif
+-ifeq ($(ARCH),ppc64)
+- CFLAGS += -m64 -msoft-float
+- LDFLAGS += -melf64ppc
+-endif
+-
+-# standard flags for module builds
+-CFLAGS += -DLINUX -D__KERNEL__ -DMODULE -O2 -pipe -Wall
+-CFLAGS += -I$(KSRC)/include -I.
+-CFLAGS += $(shell [ -f $(KSRC)/include/linux/modversions.h ] && \
+- echo "-DMODVERSIONS -DEXPORT_SYMTAB \
+- -include $(KSRC)/include/linux/modversions.h")
+-
+-ifeq ($(IEGBE_GBE_WORKAROUND), 1)
+-CFLAGS += -DIEGBE_GBE_WORKAROUND -DE1000_NO_NAPI
+-endif
+-
+-ifeq ($(IEGBE_10_100_ONLY), 1)
+-CFLAGS += -DIEGBE_10_100_ONLY
+-endif
+-
+-CFLAGS += $(CFLAGS_EXTRA)
+-#ifeq (,$(shell echo $(CFLAGS_EXTRA) | grep NAPI))
+-#CFLAGS += -DE1000_NO_NAPI
+-#CFLAGS_EXTRA += -DE1000_NO_NAPI
+-#endif
+-
+-RHC := $(KSRC)/include/linux/rhconfig.h
+-ifneq (,$(wildcard $(RHC)))
+- # 7.3 typo in rhconfig.h
+- ifneq (,$(shell $(CC) $(CFLAGS) -E -dM $(RHC) | grep __module__bigmem))
+- CFLAGS += -D__module_bigmem
+- endif
+-endif
+-
+-# get the kernel version - we use this to find the correct install path
+-ifeq ($(USE_UTS_REL), 1)
+- KVER := $(shell $(CC) $(CFLAGS) -E -dM $(UTS_REL_FILE) | grep UTS_RELEASE | \
+- awk '{ print $$3 }' | sed 's/\"//g')
+-else
+- KVER := $(shell $(CC) $(CFLAGS) -E -dM $(VERSION_FILE) | grep UTS_RELEASE | \
+- awk '{ print $$3 }' | sed 's/\"//g')
+-endif
+-
+-KKVER := $(shell echo $(KVER) | \
+- awk '{ if ($$0 ~ /2\.[6-9]\./) print "1"; else print "0"}')
+-ifeq ($(KKVER), 0)
+- $(error *** Aborting the build. \
+- *** This driver is not supported on kernel versions older than 2.6.18)
++ifeq (,$(wildcard $(UTS_REL_FILE)))
++ $(error Linux kernel source not configured - missing utsrelease.h)
+ endif
+
+ # set the install path
+@@ -202,11 +100,11 @@ ifneq ($(SMP),$(shell uname -a | grep SM
+ endif
+
+ ifeq ($(SMP),1)
+- CFLAGS += -D__SMP__
++ EXTRA_CFLAGS += -D__SMP__
+ endif
+
+ ifeq ($(EXTERNAL_MDIO), 1)
+- CFLAGS += -DEXTERNAL_MDIO
++ EXTRA_CFLAGS += -DEXTERNAL_MDIO
+ endif
+
+ ###########################################################################
+@@ -223,7 +121,6 @@ MANSECTION = 7
+ MANFILE = $(TARGET:.ko=.$(MANSECTION))
+
+ ifneq ($(PATCHLEVEL),)
+- EXTRA_CFLAGS += $(CFLAGS_EXTRA)
+ obj-m += $(TARGET:.ko=.o)
+ iegbe-objs := $(CFILES:.c=.o)
+ ifeq ($(EXTERNAL_MDIO),1)
+--- a/filelist
++++ b/filelist
+@@ -1,41 +1,3 @@
+-Embedded/Makefile
+-Embedded/environment.mk
+-Embedded/src/1588/1588.c
+-Embedded/src/1588/1588.h
+-Embedded/src/1588/IxTimeSyncAcc_p.h
+-Embedded/src/1588/Makefile
+-Embedded/src/1588/ixtimesyncacc.c
+-Embedded/src/1588/ixtimesyncacc.h
+-Embedded/src/1588/linux_ioctls.h
+-Embedded/src/CAN/Makefile
+-Embedded/src/CAN/can_fifo.c
+-Embedded/src/CAN/can_fifo.h
+-Embedded/src/CAN/can_ioctl.h
+-Embedded/src/CAN/can_main.c
+-Embedded/src/CAN/can_main.h
+-Embedded/src/CAN/can_port.h
+-Embedded/src/CAN/icp_can.c
+-Embedded/src/CAN/icp_can.h
+-Embedded/src/CAN/icp_can_regs.h
+-Embedded/src/CAN/icp_can_types.h
+-Embedded/src/CAN/icp_can_user.h
+-Embedded/src/EDMA/Makefile
+-Embedded/src/EDMA/dma.h
+-Embedded/src/EDMA/dma_api.h
+-Embedded/src/EDMA/dma_client_api.c
+-Embedded/src/EDMA/dma_common.c
+-Embedded/src/EDMA/dma_internals.h
+-Embedded/src/EDMA/dma_linux.c
+-Embedded/src/EDMA/os/os.c
+-Embedded/src/EDMA/os/os.h
+-Embedded/src/EDMA/os/os_list.c
+-Embedded/src/EDMA/os/os_list.h
+-Embedded/src/EDMA/os/os_types.h
+-Embedded/src/GPIO/Makefile
+-Embedded/src/GPIO/common.h
+-Embedded/src/GPIO/gpio.h
+-Embedded/src/GPIO/gpio_ref.c
+-Embedded/src/GPIO/linux_ioctls.h
+ Embedded/src/GbE/Makefile
+ Embedded/src/GbE/gcu.h
+ Embedded/src/GbE/gcu_if.c
+@@ -55,16 +17,6 @@ Embedded/src/GbE/iegbe_param.c
+ Embedded/src/GbE/kcompat.c
+ Embedded/src/GbE/kcompat.h
+ Embedded/src/GbE/kcompat_ethtool.c
+-Embedded/src/WDT/Makefile
+-Embedded/src/WDT/iwdt.c
+-Embedded/src/WDT/iwdt.h
+-Embedded/src/patches/Intel_EP80579_RHEL5.patch
+-Embedded/src/patches/pci.ids_RHEL5.patch
+ LICENSE.GPL
+-build_system/build_files/Core/ia.mk
+-build_system/build_files/OS/linux_2.6.mk
+-build_system/build_files/OS/linux_2.6_kernel_space_rules.mk
+-build_system/build_files/common.mk
+-build_system/build_files/rules.mk
+ filelist
+ versionfile
+--- a/versionfile
++++ b/versionfile
+@@ -1,4 +1,4 @@
+-PACKAGE_TYPE=Embedded
++PACKAGE_TYPE=Embedded.Release.Patch
+
+ PACKAGE_OS=L
+
+@@ -6,4 +6,6 @@ PACKAGE_VERSION_MAJOR_NUMBER=1
+
+ PACKAGE_VERSION_MINOR_NUMBER=0
+
+-PACKAGE_VERSION_PATCH_NUMBER=34
++PACKAGE_VERSION_PATCH_NUMBER=7
++
++PACKAGE_VERSION_BUILD_NUMBER=5
diff --git a/package/kernel/ep80579-drivers/patches/002-cflags_cleanup.patch b/package/kernel/ep80579-drivers/patches/002-cflags_cleanup.patch
new file mode 100644
index 0000000000..f897527956
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/002-cflags_cleanup.patch
@@ -0,0 +1,22 @@
+--- a/build_system/build_files/common.mk
++++ b/build_system/build_files/common.mk
+@@ -122,7 +122,7 @@ CC=$(COMPILER)
+ LD=$(LINKER)
+ AR=$(ARCHIVER)
+
+-CFLAGS+=-O2
++#CFLAGS+=-O2
+
+
+ PWD= $(shell pwd)
+--- a/build_system/build_files/OS/linux_2.6.mk
++++ b/build_system/build_files/OS/linux_2.6.mk
+@@ -80,7 +80,7 @@ endif
+
+
+ ifeq ($(OS_LEVEL), kernel_space)
+-CFLAGS+=
++#CFLAGS+=
+ endif
+
+
diff --git a/package/kernel/ep80579-drivers/patches/003-new_irqf_constants.patch b/package/kernel/ep80579-drivers/patches/003-new_irqf_constants.patch
new file mode 100644
index 0000000000..4f1c0829a5
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/003-new_irqf_constants.patch
@@ -0,0 +1,53 @@
+--- a/Embedded/src/1588/1588.c
++++ b/Embedded/src/1588/1588.c
+@@ -291,7 +291,7 @@ int pci_probe(struct pci_dev *dev, const
+
+ }
+
+- if ( request_irq(dev->irq, &timesync_isr, SA_SHIRQ, DRIVERNAME,
++ if ( request_irq(dev->irq, &timesync_isr, IRQF_SHARED, DRIVERNAME,
+ &g_drvr_data) )
+ {
+ printk("%s-pci_probe: irq\n", DRIVERNAME);
+--- a/Embedded/src/CAN/can_main.c
++++ b/Embedded/src/CAN/can_main.c
+@@ -424,7 +424,7 @@ int can_open(struct inode *inode, struct
+ err = request_irq(
+ can_os->irq,
+ can_irq_handler,
+- SA_SHIRQ,
++ IRQF_SHARED,
+ iminor(can_os->inode) ? CAN_PROC_1 : CAN_PROC_0,
+ &(g_can_os[iminor(can_os->inode)])
+ );
+--- a/Embedded/src/EDMA/dma_linux.c
++++ b/Embedded/src/EDMA/dma_linux.c
+@@ -367,7 +367,7 @@ int32_t edma_resume(struct pci_dev *dev)
+ return -ENODEV;
+ }
+
+- if (request_irq(dev->irq, &edma_irq_handler, SA_SHIRQ,
++ if (request_irq(dev->irq, &edma_irq_handler, IRQF_SHARED,
+ g_char_drvr_name, dev) )
+ {
+
+@@ -829,7 +829,7 @@ int32_t edma_probe(struct pci_dev * dev,
+ /*
+ * Obtain a (shared) Interrupt Request (IRQ) Line from the OS.
+ */
+- if (request_irq(dev->irq, &edma_irq_handler, SA_SHIRQ,
++ if (request_irq(dev->irq, &edma_irq_handler, IRQF_SHARED,
+ g_char_drvr_name, dev) )
+ {
+
+--- a/Embedded/src/WDT/iwdt.c
++++ b/Embedded/src/WDT/iwdt.c
+@@ -1461,7 +1461,7 @@ static int __init wdt_init_one(struct pc
+
+ /* Request irq only if wdt_irq is other than 0 */
+ if (wdt_irq) {
+- if (request_irq(wdt_irq, wdt_isr, SA_INTERRUPT | SA_SHIRQ,
++ if (request_irq(wdt_irq, wdt_isr, IRQF_DISABLED | IRQF_SHARED,
+ "iwdt", &wdt_miscdev)) {
+ printk("IRQ %d is not free.\n", wdt_irq);
+ return -EIO;
diff --git a/package/kernel/ep80579-drivers/patches/100-iegbe_netdev_ops.patch b/package/kernel/ep80579-drivers/patches/100-iegbe_netdev_ops.patch
new file mode 100644
index 0000000000..162449c69b
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/100-iegbe_netdev_ops.patch
@@ -0,0 +1,56 @@
+--- a/Embedded/src/GbE/iegbe_main.c
++++ b/Embedded/src/GbE/iegbe_main.c
+@@ -724,6 +724,26 @@ static void iegbe_dump_eeprom(struct ieg
+ kfree(data);
+ }
+
++static const struct net_device_ops iegbe_netdev_ops = {
++ .ndo_open = iegbe_open,
++ .ndo_stop = iegbe_close,
++ .ndo_start_xmit = iegbe_xmit_frame,
++ .ndo_get_stats = iegbe_get_stats,
++ .ndo_set_rx_mode = iegbe_set_rx_mode,
++ .ndo_set_mac_address = iegbe_set_mac,
++ .ndo_tx_timeout = iegbe_tx_timeout,
++ .ndo_change_mtu = iegbe_change_mtu,
++ .ndo_do_ioctl = iegbe_ioctl,
++ .ndo_validate_addr = eth_validate_addr,
++
++ .ndo_vlan_rx_register = iegbe_vlan_rx_register,
++ .ndo_vlan_rx_add_vid = iegbe_vlan_rx_add_vid,
++ .ndo_vlan_rx_kill_vid = iegbe_vlan_rx_kill_vid,
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ .ndo_poll_controller = iegbe_netpoll,
++#endif
++};
++
+ /**
+ * iegbe_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+@@ -800,24 +820,11 @@ static int __devinit iegbe_probe(struct
+ if (!hw->hw_addr)
+ goto err_ioremap;
+
+- netdev->open = &iegbe_open;
+- netdev->stop = &iegbe_close;
+- netdev->hard_start_xmit = &iegbe_xmit_frame;
+- netdev->get_stats = &iegbe_get_stats;
+- netdev->set_rx_mode = &iegbe_set_rx_mode;
+- netdev->set_mac_address = &iegbe_set_mac;
+- netdev->change_mtu = &iegbe_change_mtu;
+- netdev->do_ioctl = &iegbe_ioctl;
++ netdev->netdev_ops = &iegbe_netdev_ops;
+ set_ethtool_ops(netdev);
+- netdev->tx_timeout = &iegbe_tx_timeout;
+ netdev->watchdog_timeo = 5 * HZ;
+ netif_napi_add(netdev, &adapter->napi, iegbe_clean, 64);
+- netdev->vlan_rx_register = iegbe_vlan_rx_register;
+- netdev->vlan_rx_add_vid = iegbe_vlan_rx_add_vid;
+- netdev->vlan_rx_kill_vid = iegbe_vlan_rx_kill_vid;
+-#ifdef CONFIG_NET_POLL_CONTROLLER
+- netdev->poll_controller = iegbe_netpoll;
+-#endif
++
+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
+
+
diff --git a/package/kernel/ep80579-drivers/patches/101-iegbe_fix_napi_interface.patch b/package/kernel/ep80579-drivers/patches/101-iegbe_fix_napi_interface.patch
new file mode 100644
index 0000000000..921d464bad
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/101-iegbe_fix_napi_interface.patch
@@ -0,0 +1,41 @@
+--- a/Embedded/src/GbE/iegbe_main.c
++++ b/Embedded/src/GbE/iegbe_main.c
+@@ -3465,12 +3465,12 @@ static irqreturn_t iegbe_intr_msi(int ir
+ printk("Critical error! ICR = 0x%x\n", icr);
+ return IRQ_HANDLED;
+ }
+- if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
++ if (likely(napi_schedule_prep(&adapter->napi))) {
+ adapter->total_tx_bytes = 0;
+ adapter->total_tx_packets = 0;
+ adapter->total_rx_bytes = 0;
+ adapter->total_rx_packets = 0;
+- __netif_rx_schedule(netdev, &adapter->napi);
++ __napi_schedule(&adapter->napi);
+ } else
+ iegbe_irq_enable(adapter);
+
+@@ -3527,12 +3527,12 @@ iegbe_intr(int irq, void *data)
+ E1000_WRITE_REG(&adapter->hw, IMC, ~0);
+ E1000_WRITE_FLUSH(&adapter->hw);
+ }
+- if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
++ if (likely(napi_schedule_prep(&adapter->napi))) {
+ adapter->total_tx_bytes = 0;
+ adapter->total_tx_packets = 0;
+ adapter->total_rx_bytes = 0;
+ adapter->total_rx_packets = 0;
+- __netif_rx_schedule(netdev, &adapter->napi);
++ __napi_schedule(&adapter->napi);
+ } else
+ /* this really should not happen! if it does it is basically a
+ * bug, but not a hard error, so enable ints and continue */
+@@ -3574,7 +3574,7 @@ static int iegbe_clean(struct napi_struc
+ if (work_done < budget) {
+ if (likely(adapter->itr_setting & 3))
+ iegbe_set_itr(adapter);
+- netif_rx_complete(poll_dev, napi);
++ napi_complete(napi);
+ iegbe_irq_enable(adapter);
+ }
+
diff --git a/package/kernel/ep80579-drivers/patches/102-iegbe_nuke_polling_netdev.patch b/package/kernel/ep80579-drivers/patches/102-iegbe_nuke_polling_netdev.patch
new file mode 100644
index 0000000000..f7ca62709d
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/102-iegbe_nuke_polling_netdev.patch
@@ -0,0 +1,103 @@
+--- a/Embedded/src/GbE/iegbe.h
++++ b/Embedded/src/GbE/iegbe.h
+@@ -316,7 +316,6 @@ struct iegbe_adapter {
+ int cleaned_count);
+ struct iegbe_rx_ring *rx_ring; /* One per active queue */
+ struct napi_struct napi;
+- struct net_device *polling_netdev; /* One per active queue */
+
+ int num_tx_queues;
+ int num_rx_queues;
+--- a/Embedded/src/GbE/iegbe_main.c
++++ b/Embedded/src/GbE/iegbe_main.c
+@@ -763,7 +763,7 @@ static int __devinit iegbe_probe(struct
+ struct iegbe_hw *hw;
+
+ static int cards_found = 0;
+- int i, err, pci_using_dac;
++ int err, pci_using_dac;
+ u16 eeprom_data = 0;
+ u16 eeprom_apme_mask = E1000_EEPROM_APME;
+ int bars;
+@@ -984,11 +984,8 @@ err_eeprom:
+ iegbe_phy_hw_reset(hw);
+ if (hw->flash_address)
+ iounmap(hw->flash_address);
+- for (i = 0; i < adapter->num_rx_queues; i++)
+- dev_put(&adapter->polling_netdev[i]);
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+- kfree(adapter->polling_netdev);
+ err_sw_init:
+ iounmap(hw->hw_addr);
+ err_ioremap:
+@@ -1017,7 +1014,6 @@ iegbe_remove(struct pci_dev *pdev)
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct iegbe_adapter *adapter = netdev_priv(netdev);
+ uint32_t manc;
+- int i;
+
+ if(adapter->hw.mac_type >= iegbe_82540
+ && adapter->hw.mac_type != iegbe_icp_xxxx
+@@ -1030,15 +1026,11 @@ iegbe_remove(struct pci_dev *pdev)
+ }
+
+ unregister_netdev(netdev);
+- for (i = 0x0; i < adapter->num_rx_queues; i++)
+- dev_put(&adapter->polling_netdev[i]);
+-
+ if(!iegbe_check_phy_reset_block(&adapter->hw)) {
+ iegbe_phy_hw_reset(&adapter->hw);
+ }
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+- kfree(adapter->polling_netdev);
+
+ iounmap(adapter->hw.hw_addr);
+ pci_release_regions(pdev);
+@@ -1061,7 +1053,6 @@ iegbe_sw_init(struct iegbe_adapter *adap
+ struct iegbe_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+- int i;
+
+ /* PCI config space info */
+
+@@ -1111,11 +1102,6 @@ iegbe_sw_init(struct iegbe_adapter *adap
+ return -ENOMEM;
+ }
+
+- for (i = 0; i < adapter->num_rx_queues; i++) {
+- adapter->polling_netdev[i].priv = adapter;
+- dev_hold(&adapter->polling_netdev[i]);
+- set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
+- }
+ spin_lock_init(&adapter->tx_queue_lock);
+
+ /*
+@@ -1137,8 +1123,7 @@ iegbe_sw_init(struct iegbe_adapter *adap
+ * @adapter: board private structure to initialize
+ *
+ * We allocate one ring per queue at run-time since we don't know the
+- * number of queues at compile-time. The polling_netdev array is
+- * intended for Multiqueue, but should work fine with a single queue.
++ * number of queues at compile-time.
+ **/
+
+ static int __devinit
+@@ -1158,15 +1143,6 @@ iegbe_alloc_queues(struct iegbe_adapter
+ return -ENOMEM;
+ }
+
+- adapter->polling_netdev = kcalloc(adapter->num_rx_queues,
+- sizeof(struct net_device),
+- GFP_KERNEL);
+- if (!adapter->polling_netdev) {
+- kfree(adapter->tx_ring);
+- kfree(adapter->rx_ring);
+- return -ENOMEM;
+- }
+-
+ return E1000_SUCCESS;
+ }
+
diff --git a/package/kernel/ep80579-drivers/patches/103-iegbe_convert_unicast_addr_list.patch b/package/kernel/ep80579-drivers/patches/103-iegbe_convert_unicast_addr_list.patch
new file mode 100644
index 0000000000..71d2d54e6b
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/103-iegbe_convert_unicast_addr_list.patch
@@ -0,0 +1,60 @@
+--- a/Embedded/src/GbE/iegbe_main.c
++++ b/Embedded/src/GbE/iegbe_main.c
+@@ -2161,7 +2161,8 @@ static void iegbe_set_rx_mode(struct net
+ {
+ struct iegbe_adapter *adapter = netdev_priv(netdev);
+ struct iegbe_hw *hw = &adapter->hw;
+- struct dev_addr_list *uc_ptr;
++ struct netdev_hw_addr *ha;
++ bool use_uc = false;
+ struct dev_addr_list *mc_ptr;
+ u32 rctl;
+ u32 hash_value;
+@@ -2187,12 +2188,11 @@ int mta_reg_count = E1000_NUM_MTA_REGIST
+ }
+ }
+
+- uc_ptr = NULL;
+ if (netdev->uc_count > rar_entries - 1) {
+ rctl |= E1000_RCTL_UPE;
+ } else if (!(netdev->flags & IFF_PROMISC)) {
+ rctl &= ~E1000_RCTL_UPE;
+- uc_ptr = netdev->uc_list;
++ use_uc = true;
+ }
+
+ E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+@@ -2210,13 +2210,20 @@ int mta_reg_count = E1000_NUM_MTA_REGIST
+ * if there are not 14 addresses, go ahead and clear the filters
+ * -- with 82571 controllers only 0-13 entries are filled here
+ */
++ i = 1;
++ if (use_uc)
++ list_for_each_entry(ha, &netdev->uc_list, list) {
++ if (i == rar_entries)
++ break;
++ iegbe_rar_set(hw, ha->addr, i++);
++ }
++
++ WARN_ON(i == rar_entries);
++
+ mc_ptr = netdev->mc_list;
+
+- for (i = 1; i < rar_entries; i++) {
+- if (uc_ptr) {
+- iegbe_rar_set(hw, uc_ptr->da_addr, i);
+- uc_ptr = uc_ptr->next;
+- } else if (mc_ptr) {
++ for (; i < rar_entries; i++) {
++ if (mc_ptr) {
+ iegbe_rar_set(hw, mc_ptr->da_addr, i);
+ mc_ptr = mc_ptr->next;
+ } else {
+@@ -2226,7 +2233,6 @@ int mta_reg_count = E1000_NUM_MTA_REGIST
+ E1000_WRITE_FLUSH(&adapter->hw);
+ }
+ }
+- WARN_ON(uc_ptr != NULL);
+
+ /* clear the old settings from the multicast hash table */
+
diff --git a/package/kernel/ep80579-drivers/patches/104-iegbe_group_address_list_and_its_count.patch b/package/kernel/ep80579-drivers/patches/104-iegbe_group_address_list_and_its_count.patch
new file mode 100644
index 0000000000..c6eced6a5c
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/104-iegbe_group_address_list_and_its_count.patch
@@ -0,0 +1,20 @@
+--- a/Embedded/src/GbE/iegbe_main.c
++++ b/Embedded/src/GbE/iegbe_main.c
+@@ -2188,7 +2188,7 @@ int mta_reg_count = E1000_NUM_MTA_REGIST
+ }
+ }
+
+- if (netdev->uc_count > rar_entries - 1) {
++ if (netdev->uc.count > rar_entries - 1) {
+ rctl |= E1000_RCTL_UPE;
+ } else if (!(netdev->flags & IFF_PROMISC)) {
+ rctl &= ~E1000_RCTL_UPE;
+@@ -2212,7 +2212,7 @@ int mta_reg_count = E1000_NUM_MTA_REGIST
+ */
+ i = 1;
+ if (use_uc)
+- list_for_each_entry(ha, &netdev->uc_list, list) {
++ list_for_each_entry(ha, &netdev->uc.list, list) {
+ if (i == rar_entries)
+ break;
+ iegbe_rar_set(hw, ha->addr, i++);
diff --git a/package/kernel/ep80579-drivers/patches/105-iegbe_new_dma_masks.patch b/package/kernel/ep80579-drivers/patches/105-iegbe_new_dma_masks.patch
new file mode 100644
index 0000000000..d5fc46f796
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/105-iegbe_new_dma_masks.patch
@@ -0,0 +1,20 @@
+--- a/Embedded/src/GbE/iegbe_main.c
++++ b/Embedded/src/GbE/iegbe_main.c
+@@ -775,13 +775,13 @@ static int __devinit iegbe_probe(struct
+ if (err)
+ return err;
+
+- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
+- !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
++ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
++ !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ pci_using_dac = 1;
+ } else {
+- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
++ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (err) {
+- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
++ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (err) {
+ E1000_ERR("No usable DMA configuration, "
+ "aborting\n");
diff --git a/package/kernel/ep80579-drivers/patches/106-iegbe_new_irqf_constant.patch b/package/kernel/ep80579-drivers/patches/106-iegbe_new_irqf_constant.patch
new file mode 100644
index 0000000000..a08e8c7697
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/106-iegbe_new_irqf_constant.patch
@@ -0,0 +1,12 @@
+--- a/Embedded/src/GbE/iegbe_ethtool.c
++++ b/Embedded/src/GbE/iegbe_ethtool.c
+@@ -944,7 +944,8 @@ iegbe_intr_test(struct iegbe_adapter *ad
+ *data = 0;
+
+ /* Hook up test interrupt handler just for this test */
+- if(!request_irq(irq, &iegbe_test_intr, 0, netdev->name, netdev)) {
++ if(!request_irq(irq, &iegbe_test_intr, IRQF_PROBE_SHARED, netdev->name,
++ netdev)) {
+ shared_int = FALSE;
+ } else if(request_irq(irq, &iegbe_test_intr, IRQF_SHARED,
+ netdev->name, netdev)){
diff --git a/package/kernel/ep80579-drivers/patches/150-ocracoke_island.patch b/package/kernel/ep80579-drivers/patches/150-ocracoke_island.patch
new file mode 100644
index 0000000000..ae74e0c905
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/150-ocracoke_island.patch
@@ -0,0 +1,747 @@
+--- a/Embedded/src/GbE/iegbe_oem_phy.c
++++ b/Embedded/src/GbE/iegbe_oem_phy.c
+@@ -65,6 +65,10 @@ static int32_t iegbe_oem_link_m88_setup(
+ static int32_t iegbe_oem_set_phy_mode(struct iegbe_hw *hw);
+ static int32_t iegbe_oem_detect_phy(struct iegbe_hw *hw);
+
++static int32_t iegbe_oem_link_bcm5481_setup(struct iegbe_hw *hw);
++static int32_t bcm5481_read_18sv (struct iegbe_hw *hw, int sv, uint16_t *data);
++static int32_t oi_phy_setup (struct iegbe_hw *hw);
++
+ /**
+ * iegbe_oem_setup_link
+ * @hw: iegbe_hw struct containing device specific information
+@@ -114,6 +118,10 @@ iegbe_oem_setup_link(struct iegbe_hw *hw
+ }
+
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ return E1000_SUCCESS;
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ ret_val = iegbe_oem_link_m88_setup(hw);
+@@ -121,6 +129,12 @@ iegbe_oem_setup_link(struct iegbe_hw *hw
+ return ret_val;
+ }
+ break;
++ case BCM5481_PHY_ID:
++ ret_val = iegbe_oem_link_bcm5481_setup(hw);
++ if(ret_val) {
++ return ret_val;
++ }
++ break;
+ default:
+ DEBUGOUT("Invalid PHY ID\n");
+ return -E1000_ERR_PHY_TYPE;
+@@ -179,6 +193,51 @@ iegbe_oem_setup_link(struct iegbe_hw *hw
+ #endif /* ifdef EXTERNAL_MDIO */
+ }
+
++/**
++ * iegbe_oem_link_bcm5481_setup
++ * @hw: iegbe_hw struct containing device specific information
++ *
++ * Returns E1000_SUCCESS, negative E1000 error code on failure
++ *
++ * copied verbatim from iegbe_oem_link_m88_setup
++ **/
++static int32_t
++iegbe_oem_link_bcm5481_setup(struct iegbe_hw *hw)
++{
++ int32_t ret_val;
++ uint16_t phy_data;
++
++ //DEBUGFUNC(__func__);
++
++ if(!hw)
++ return -1;
++
++ /* phy_reset_disable is set in iegbe_oem_set_phy_mode */
++ if(hw->phy_reset_disable)
++ return E1000_SUCCESS;
++
++ // Enable MDIX in extended control reg.
++ ret_val = iegbe_oem_read_phy_reg_ex(hw, BCM5481_ECTRL, &phy_data);
++ if(ret_val)
++ {
++ DEBUGOUT("Unable to read BCM5481_ECTRL register\n");
++ return ret_val;
++ }
++
++ phy_data &= ~BCM5481_ECTRL_DISMDIX;
++ ret_val = iegbe_oem_write_phy_reg_ex(hw, BCM5481_ECTRL, phy_data);
++ if(ret_val)
++ {
++ DEBUGOUT("Unable to write BCM5481_ECTRL register\n");
++ return ret_val;
++ }
++
++ ret_val = oi_phy_setup (hw);
++ if (ret_val)
++ return ret_val;
++
++ return E1000_SUCCESS;
++}
+
+ /**
+ * iegbe_oem_link_m88_setup
+@@ -340,6 +399,11 @@ iegbe_oem_force_mdi(struct iegbe_hw *hw,
+ * see iegbe_phy_force_speed_duplex, which does the following for M88
+ */
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ case BCM5481_PHY_ID:
++ DEBUGOUT("WARNING: An empty iegbe_oem_force_mdi() has been called!\n");
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ ret_val = iegbe_oem_read_phy_reg_ex(hw,
+@@ -415,6 +479,8 @@ iegbe_oem_phy_reset_dsp(struct iegbe_hw
+ switch (hw->phy_id) {
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
++ case BCM5481_PHY_ID:
++ case BCM5395S_PHY_ID:
+ DEBUGOUT("No DSP to reset on OEM PHY\n");
+ break;
+ default:
+@@ -460,6 +526,11 @@ iegbe_oem_cleanup_after_phy_reset(struct
+ * see iegbe_phy_force_speed_duplex, which does the following for M88
+ */
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ case BCM5481_PHY_ID:
++ DEBUGOUT("WARNING: An empty iegbe_oem_cleanup_after_phy_reset() has been called!\n");
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ /*
+@@ -573,6 +644,11 @@ iegbe_oem_set_phy_mode(struct iegbe_hw *
+ * use iegbe_set_phy_mode as example
+ */
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ case BCM5481_PHY_ID:
++ DEBUGOUT("WARNING: An empty iegbe_oem_set_phy_mode() has been called!\n");
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ ret_val = iegbe_read_eeprom(hw,
+@@ -641,6 +717,19 @@ iegbe_oem_detect_phy(struct iegbe_hw *hw
+ }
+ hw->phy_type = iegbe_phy_oem;
+
++{
++ // If MAC2 (BCM5395 switch), manually detect the phy
++ struct iegbe_adapter *adapter;
++ uint32_t device_number;
++ adapter = (struct iegbe_adapter *) hw->back;
++ device_number = PCI_SLOT(adapter->pdev->devfn);
++ if (device_number == ICP_XXXX_MAC_2) {
++ hw->phy_id = BCM5395S_PHY_ID;
++ hw->phy_revision = 0;
++ return E1000_SUCCESS;
++ }
++}
++
+ ret_val = iegbe_oem_read_phy_reg_ex(hw, PHY_ID1, &phy_id_high);
+ if(ret_val) {
+ DEBUGOUT("Unable to read PHY register PHY_ID1\n");
+@@ -690,6 +779,8 @@ iegbe_oem_get_tipg(struct iegbe_hw *hw)
+ switch (hw->phy_id) {
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
++ case BCM5481_PHY_ID:
++ case BCM5395S_PHY_ID:
+ phy_num = DEFAULT_ICP_XXXX_TIPG_IPGT;
+ break;
+ default:
+@@ -738,6 +829,8 @@ iegbe_oem_phy_is_copper(struct iegbe_hw
+ switch (hw->phy_id) {
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
++ case BCM5481_PHY_ID:
++ case BCM5395S_PHY_ID:
+ isCopper = TRUE;
+ break;
+ default:
+@@ -796,13 +889,13 @@ iegbe_oem_get_phy_dev_number(struct iegb
+ switch(device_number)
+ {
+ case ICP_XXXX_MAC_0:
+- hw->phy_addr = 0x00;
++ hw->phy_addr = 0x01;
+ break;
+ case ICP_XXXX_MAC_1:
+- hw->phy_addr = 0x01;
++ hw->phy_addr = 0x02;
+ break;
+ case ICP_XXXX_MAC_2:
+- hw->phy_addr = 0x02;
++ hw->phy_addr = 0x00;
+ break;
+ default: hw->phy_addr = 0x00;
+ }
+@@ -851,6 +944,12 @@ iegbe_oem_mii_ioctl(struct iegbe_adapter
+ if(!adapter || !ifr) {
+ return -1;
+ }
++
++ // If MAC2 (BCM5395 switch) then leave now
++ if ((PCI_SLOT(adapter->pdev->devfn)) == ICP_XXXX_MAC_2) {
++ return -1;
++ }
++
+ switch (data->reg_num) {
+ case PHY_CTRL:
+ if(mii_reg & MII_CR_POWER_DOWN) {
+@@ -987,6 +1086,11 @@ void iegbe_oem_get_phy_regs(struct iegbe
+ * [10] = mdix mode
+ */
+ switch (adapter->hw.phy_id) {
++ case BCM5395S_PHY_ID:
++ case BCM5481_PHY_ID:
++ DEBUGOUT("WARNING: An empty iegbe_oem_get_phy_regs() has been called!\n");
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ if(corrected_len > 0) {
+@@ -1068,8 +1172,13 @@ iegbe_oem_phy_loopback(struct iegbe_adap
+ * Loopback configuration is the same for each of the supported PHYs.
+ */
+ switch (adapter->hw.phy_id) {
++ case BCM5395S_PHY_ID:
++ DEBUGOUT("WARNING: An empty iegbe_oem_phy_loopback() has been called!\n");
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
++ case BCM5481_PHY_ID:
+
+ adapter->hw.autoneg = FALSE;
+
+@@ -1182,8 +1291,14 @@ iegbe_oem_loopback_cleanup(struct iegbe_
+ }
+
+ switch (adapter->hw.phy_id) {
++ case BCM5395S_PHY_ID:
++ DEBUGOUT("WARNING: An empty iegbe_oem_loopback_cleanup() has been called!\n");
++ return;
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
++ case BCM5481_PHY_ID:
+ default:
+ adapter->hw.autoneg = TRUE;
+
+@@ -1243,6 +1358,11 @@ iegbe_oem_phy_speed_downgraded(struct ie
+ */
+
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ case BCM5481_PHY_ID:
++ *isDowngraded = 0;
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
+@@ -1305,6 +1425,11 @@ iegbe_oem_check_polarity(struct iegbe_hw
+ */
+
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ case BCM5481_PHY_ID:
++ *polarity = 0;
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ /* return the Polarity bit in the Status register. */
+@@ -1367,6 +1492,25 @@ iegbe_oem_phy_is_full_duplex(struct iegb
+ */
+
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ /* Always full duplex */
++ *isFD = 1;
++ break;
++
++ case BCM5481_PHY_ID:
++ ret_val = iegbe_read_phy_reg(hw, BCM5481_ASTAT, &phy_data);
++ if(ret_val) return ret_val;
++
++ switch (BCM5481_ASTAT_HCD(phy_data)) {
++ case BCM5481_ASTAT_1KBTFD:
++ case BCM5481_ASTAT_100BTXFD:
++ *isFD = 1;
++ break;
++ default:
++ *isFD = 0;
++ }
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
+@@ -1423,6 +1567,25 @@ iegbe_oem_phy_is_speed_1000(struct iegbe
+ */
+
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ /* Always 1000mb */
++ *is1000 = 1;
++ break;
++
++ case BCM5481_PHY_ID:
++ ret_val = iegbe_read_phy_reg(hw, BCM5481_ASTAT, &phy_data);
++ if(ret_val) return ret_val;
++
++ switch (BCM5481_ASTAT_HCD(phy_data)) {
++ case BCM5481_ASTAT_1KBTFD:
++ case BCM5481_ASTAT_1KBTHD:
++ *is1000 = 1;
++ break;
++ default:
++ *is1000 = 0;
++ }
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
+@@ -1478,6 +1641,25 @@ iegbe_oem_phy_is_speed_100(struct iegbe_
+ * see iegbe_config_mac_to_phy
+ */
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ /* Always 1000Mb, never 100mb */
++ *is100 = 0;
++ break;
++
++ case BCM5481_PHY_ID:
++ ret_val = iegbe_read_phy_reg(hw, BCM5481_ASTAT, &phy_data);
++ if(ret_val) return ret_val;
++
++ switch (BCM5481_ASTAT_HCD(phy_data)) {
++ case BCM5481_ASTAT_100BTXFD:
++ case BCM5481_ASTAT_100BTXHD:
++ *is100 = 1;
++ break;
++ default:
++ *is100 = 0;
++ }
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ ret_val = iegbe_oem_read_phy_reg_ex(hw,
+@@ -1535,6 +1717,11 @@ iegbe_oem_phy_get_info(struct iegbe_hw *
+ * see iegbe_phy_m88_get_info
+ */
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ case BCM5481_PHY_ID:
++ DEBUGOUT("WARNING: An empty iegbe_oem_phy_get_info() has been called!\n");
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ /* The downshift status is checked only once, after link is
+@@ -1636,8 +1823,13 @@ iegbe_oem_phy_hw_reset(struct iegbe_hw *
+ * the M88 used in truxton.
+ */
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ DEBUGOUT("WARNING: An empty iegbe_oem_phy_hw_reset() has been called!\n");
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
++ case BCM5481_PHY_ID:
+ ret_val = iegbe_oem_read_phy_reg_ex(hw, PHY_CTRL, &phy_data);
+ if(ret_val) {
+ DEBUGOUT("Unable to read register PHY_CTRL\n");
+@@ -1699,6 +1891,8 @@ iegbe_oem_phy_init_script(struct iegbe_h
+ switch (hw->phy_id) {
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
++ case BCM5481_PHY_ID:
++ case BCM5395S_PHY_ID:
+ DEBUGOUT("Nothing to do for OEM PHY Init");
+ break;
+ default:
+@@ -1735,6 +1929,11 @@ iegbe_oem_read_phy_reg_ex(struct iegbe_h
+ return -1;
+ }
+
++ if (hw->phy_id == BCM5395S_PHY_ID) {
++ DEBUGOUT("WARNING: iegbe_oem_read_phy_reg_ex() has been unexpectedly called!\n");
++ return -1;
++ }
++
+ /* call the GCU func that will read the phy
+ *
+ * Make note that the M88 phy is what'll be used on Truxton.
+@@ -1782,6 +1981,11 @@ iegbe_oem_set_trans_gasket(struct iegbe_
+ }
+
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ case BCM5481_PHY_ID:
++ DEBUGOUT("WARNING: An empty iegbe_oem_set_trans_gasket() has been called!\n");
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ /* Gasket set correctly for Marvell Phys, so nothing to do */
+@@ -1886,6 +2090,8 @@ iegbe_oem_phy_needs_reset_with_mac(struc
+ switch (hw->phy_id) {
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
++ case BCM5481_PHY_ID:
++ case BCM5395S_PHY_ID:
+ ret_val = FALSE;
+ break;
+ default:
+@@ -1935,6 +2141,8 @@ iegbe_oem_config_dsp_after_link_change(s
+ switch (hw->phy_id) {
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
++ case BCM5481_PHY_ID:
++ case BCM5395S_PHY_ID:
+ DEBUGOUT("No DSP to configure on OEM PHY");
+ break;
+ default:
+@@ -1978,6 +2186,12 @@ iegbe_oem_get_cable_length(struct iegbe_
+ }
+
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ case BCM5481_PHY_ID:
++ *min_length = 0;
++ *max_length = iegbe_igp_cable_length_150;
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ ret_val = iegbe_oem_read_phy_reg_ex(hw,
+@@ -2061,6 +2275,23 @@ iegbe_oem_phy_is_link_up(struct iegbe_hw
+ */
+
+ switch (hw->phy_id) {
++ case BCM5395S_PHY_ID:
++ /* Link always up */
++ *isUp = TRUE;
++ return E1000_SUCCESS;
++ break;
++
++ case BCM5481_PHY_ID:
++ iegbe_oem_read_phy_reg_ex(hw, BCM5481_ESTAT, &phy_data);
++ ret_val = iegbe_oem_read_phy_reg_ex(hw, BCM5481_ESTAT, &phy_data);
++ if(ret_val)
++ {
++ DEBUGOUT("Unable to read PHY register BCM5481_ESTAT\n");
++ return ret_val;
++ }
++ statusMask = BCM5481_ESTAT_LINK;
++ break;
++
+ case M88E1000_I_PHY_ID:
+ case M88E1141_E_PHY_ID:
+ iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
+@@ -2092,3 +2323,210 @@ iegbe_oem_phy_is_link_up(struct iegbe_hw
+ #endif /* ifdef EXTERNAL_MDIO */
+ }
+
++
++
++//-----
++// Read BCM5481 expansion register
++//
++int32_t
++bcm5481_read_ex (struct iegbe_hw *hw, uint16_t reg, uint16_t *data)
++{
++ int ret;
++ uint16_t selector;
++ uint16_t reg_data;
++
++ // Get the current value of bits 15:12
++ ret = iegbe_oem_read_phy_reg_ex (hw, 0x15, &selector);
++ if (ret)
++ return ret;
++
++ // Select the expansion register
++ selector &= 0xf000;
++ selector |= (0xf << 8) | (reg);
++ iegbe_oem_write_phy_reg_ex (hw, 0x17, selector);
++
++ // Read the expansion register
++ ret = iegbe_oem_read_phy_reg_ex (hw, 0x15, &reg_data);
++
++ // De-select the expansion registers.
++ selector &= 0xf000;
++ iegbe_oem_write_phy_reg_ex (hw, 0x17, selector);
++
++ if (ret)
++ return ret;
++
++ *data = reg_data;
++ return ret;
++}
++
++//-----
++// Read reg 0x18 sub-register
++//
++static int32_t
++bcm5481_read_18sv (struct iegbe_hw *hw, int sv, uint16_t *data)
++{
++ int ret;
++ uint16_t tmp_data;
++
++ // Select reg 0x18, sv
++ tmp_data = ((sv & BCM5481_R18H_SV_MASK) << 12) | BCM5481_R18H_SV_MCTRL;
++ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R18H, tmp_data);
++ if(ret)
++ return ret;
++
++ // Read reg 0x18, sv
++ ret = iegbe_oem_read_phy_reg_ex (hw, BCM5481_R18H, &tmp_data);
++ if(ret)
++ return ret;
++
++ *data = tmp_data;
++ return ret;
++}
++
++//-----
++// Read reg 0x1C sub-register
++//
++int32_t
++bcm5481_read_1csv (struct iegbe_hw *hw, int sv, uint16_t *data)
++{
++ int ret;
++ uint16_t tmp_data;
++
++ // Select reg 0x1c, sv
++ tmp_data = ((sv & BCM5481_R1CH_SV_MASK) << BCM5481_R1CH_SV_SHIFT);
++
++ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R1CH, tmp_data);
++ if(ret)
++ return ret;
++
++ // Read reg 0x1c, sv
++ ret = iegbe_oem_read_phy_reg_ex (hw, BCM5481_R1CH, &tmp_data);
++ if(ret)
++ return ret;
++
++ *data = tmp_data;
++ return ret;
++}
++
++//-----
++// Read-modify-write a 0x1C register.
++//
++// hw - hardware access info.
++// reg - 0x1C register to modify.
++// data - bits which should be set.
++// mask - the '1' bits in this argument will be cleared in the data
++// read from 'reg' then 'data' will be or'd in and the result
++// will be written to 'reg'.
++
++int32_t
++bcm5481_rmw_1csv (struct iegbe_hw *hw, uint16_t reg, uint16_t data, uint16_t mask)
++{
++ int32_t ret;
++ uint16_t reg_data;
++
++ ret = 0;
++
++ ret = bcm5481_read_1csv (hw, reg, &reg_data);
++ if (ret)
++ {
++ DEBUGOUT("Unable to read BCM5481 1CH register\n");
++ printk (KERN_ERR "Unable to read BCM5481 1CH register [0x%x]\n", reg);
++ return ret;
++ }
++
++ reg_data &= ~mask;
++ reg_data |= (BCM5481_R1CH_WE | data);
++
++ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R1CH, reg_data);
++ if(ret)
++ {
++ DEBUGOUT("Unable to write BCM5481 1CH register\n");
++ printk (KERN_ERR "Unable to write BCM5481 1CH register\n");
++ return ret;
++ }
++
++ return ret;
++}
++
++int32_t
++oi_phy_setup (struct iegbe_hw *hw)
++{
++ int ret;
++ uint16_t pmii_data;
++ uint16_t mctrl_data;
++ uint16_t cacr_data;
++
++ ret = 0;
++
++ // Set low power mode via reg 0x18, sv010, bit 6
++ // Do a read-modify-write on reg 0x18, sv010 register to preserve existing bits.
++ ret = bcm5481_read_18sv (hw, BCM5481_R18H_SV_PMII, &pmii_data);
++ if (ret)
++ {
++ DEBUGOUT("Unable to read BCM5481_R18H_SV_PMII register\n");
++ printk (KERN_ERR "Unable to read BCM5481_R18H_SV_PMII register\n");
++ return ret;
++ }
++
++ // Set the LPM bit in the data just read and write back to sv010
++ // The shadow register select bits [2:0] are set by reading the sv010
++ // register.
++ pmii_data |= BCM5481_R18H_SV010_LPM;
++ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R18H, pmii_data);
++ if(ret)
++ {
++ DEBUGOUT("Unable to write BCM5481_R18H register\n");
++ printk (KERN_ERR "Unable to write BCM5481_R18H register\n");
++ return ret;
++ }
++
++
++ // Set the RGMII RXD to RXC skew bit in reg 0x18, sv111
++
++ if (bcm5481_read_18sv (hw, BCM5481_R18H_SV_MCTRL, &mctrl_data))
++ {
++ DEBUGOUT("Unable to read BCM5481_R18H_SV_MCTRL register\n");
++ printk (KERN_ERR "Unable to read BCM5481_R18H_SV_MCTRL register\n");
++ return ret;
++ }
++ mctrl_data |= (BCM5481_R18H_WE | BCM5481_R18H_SV111_SKEW);
++
++ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R18H, mctrl_data);
++ if(ret)
++ {
++ DEBUGOUT("Unable to write BCM5481_R18H register\n");
++ printk (KERN_ERR "Unable to write BCM5481_R18H register\n");
++ return ret;
++ }
++
++ // Enable RGMII transmit clock delay in reg 0x1c, sv00011
++ ret = bcm5481_read_1csv (hw, BCM5481_R1CH_CACR, &cacr_data);
++ if (ret)
++ {
++ DEBUGOUT("Unable to read BCM5481_R1CH_CACR register\n");
++ printk (KERN_ERR "Unable to read BCM5481_R1CH_CACR register\n");
++ return ret;
++ }
++
++ cacr_data |= (BCM5481_R1CH_WE | BCM5481_R1CH_CACR_TCD);
++
++ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R1CH, cacr_data);
++ if(ret)
++ {
++ DEBUGOUT("Unable to write BCM5481_R1CH register\n");
++ printk (KERN_ERR "Unable to write BCM5481_R1CH register\n");
++ return ret;
++ }
++
++ // Enable dual link speed indication (0x1c, sv 00010, bit 2)
++ ret = bcm5481_rmw_1csv (hw, BCM5481_R1CH_SC1, BCM5481_R1CH_SC1_LINK, BCM5481_R1CH_SC1_LINK);
++ if (ret)
++ return ret;
++
++ // Enable link and activity on ACTIVITY LED (0x1c, sv 01001, bit 4=1, bit 3=0)
++ ret = bcm5481_rmw_1csv (hw, BCM5481_R1CH_LCTRL, BCM5481_R1CH_LCTRL_ALEN, BCM5481_R1CH_LCTRL_ALEN | BCM5481_R1CH_LCTRL_AEN);
++ if (ret)
++ return ret;
++
++ return ret;
++}
+--- a/Embedded/src/GbE/iegbe_oem_phy.h
++++ b/Embedded/src/GbE/iegbe_oem_phy.h
+@@ -95,6 +95,8 @@ int32_t iegbe_oem_phy_is_link_up(struct
+
+ #define DEFAULT_ICP_XXXX_TIPG_IPGT 8 /* Inter Packet Gap Transmit Time */
+ #define ICP_XXXX_TIPG_IPGT_MASK 0x000003FFUL
++#define BCM5481_PHY_ID 0x0143BCA0
++#define BCM5395S_PHY_ID 0x0143BCF0
+
+ /* Miscellaneous defines */
+ #ifdef IEGBE_10_100_ONLY
+@@ -103,5 +105,65 @@ int32_t iegbe_oem_phy_is_link_up(struct
+ #define ICP_XXXX_AUTONEG_ADV_DEFAULT 0x2F
+ #endif
+
++/* BCM5481 specifics */
++
++#define BCM5481_ECTRL (0x10)
++#define BCM5481_ESTAT (0x11)
++#define BCM5481_RXERR (0x12)
++#define BCM5481_EXPRW (0x15)
++#define BCM5481_EXPACC (0x17)
++#define BCM5481_ASTAT (0x19)
++#define BCM5481_R18H (0x18)
++#define BCM5481_R1CH (0x1c)
++
++/* indirect register access via register 18h */
++
++#define BCM5481_R18H_SV_MASK (7) // Mask for SV bits.
++#define BCM5481_R18H_SV_ACTRL (0) // SV000 Aux. control
++#define BCM5481_R18H_SV_10BT (1) // SV001 10Base-T
++#define BCM5481_R18H_SV_PMII (2) // SV010 Power/MII control
++#define BCM5481_R18H_SV_MTEST (4) // SV100 Misc. test
++#define BCM5481_R18H_SV_MCTRL (7) // SV111 Misc. control
++
++#define BCM5481_R18H_SV001_POL (1 << 13) // Polarity
++#define BCM5481_R18H_SV010_LPM (1 << 6)
++#define BCM5481_R18H_SV111_SKEW (1 << 8)
++#define BCM5481_R18H_WE (1 << 15) // Write enable
++
++// 0x1c registers
++#define BCM5481_R1CH_SV_SHIFT (10)
++#define BCM5481_R1CH_SV_MASK (0x1f)
++#define BCM5481_R1CH_SC1 (0x02) // sv00010 Spare control 1
++#define BCM5481_R1CH_CACR (0x03) // sv00011 Clock alignment control
++#define BCM5481_R1CH_LCTRL (0x09) // sv01001 LED control
++#define BCM5481_R1CH_LEDS1 (0x0d) // sv01101 LED selector 1
++
++// 0x1c common
++#define BCM5481_R1CH_WE (1 << 15) // Write enable
++
++// 0x1c, sv 00010
++#define BCM5481_R1CH_SC1_LINK (1 << 2) // sv00010 Linkspeed
++
++// 0x1c, sv 00011
++#define BCM5481_R1CH_CACR_TCD (1 << 9) // sv00011 RGMII tx clock delay
++
++// 0x1c, sv 01001
++#define BCM5481_R1CH_LCTRL_ALEN (1 << 4) // Activity/Link enable on ACTIVITY LED
++#define BCM5481_R1CH_LCTRL_AEN (1 << 3) // Activity enable on ACTIVITY LED
++
++#define BCM5481_ECTRL_DISMDIX (1 <<14)
++
++#define BCM5481_MCTRL_AUTOMDIX (1 <<9)
++
++#define BCM5481_ESTAT_LINK (1 << 8)
++
++#define BCM5481_ASTAT_ANC (1 << 15)
++#define BCM5481_ASTAT_ANHCD (7 << 8)
++#define BCM5481_ASTAT_HCD(x) ((x >> 8) & 7)
++#define BCM5481_ASTAT_1KBTFD (0x7)
++#define BCM5481_ASTAT_1KBTHD (0x6)
++#define BCM5481_ASTAT_100BTXFD (0x5)
++#define BCM5481_ASTAT_100BTXHD (0x3)
++
+ #endif /* ifndef _IEGBE_OEM_PHY_H_ */
+
diff --git a/package/kernel/ep80579-drivers/patches/200-can_fix_ioctl_numbers.patch b/package/kernel/ep80579-drivers/patches/200-can_fix_ioctl_numbers.patch
new file mode 100644
index 0000000000..2919466251
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/200-can_fix_ioctl_numbers.patch
@@ -0,0 +1,11 @@
+--- a/Embedded/src/CAN/icp_can_user.h
++++ b/Embedded/src/CAN/icp_can_user.h
+@@ -63,6 +63,8 @@
+ #ifndef __ICP_CAN_USER_H__
+ #define __ICP_CAN_USER_H__
+
++#include <linux/ioctl.h>
++
+ /*****************************************************************************
+ * Device IO control codes.
+ *****************************************************************************/
diff --git a/package/kernel/ep80579-drivers/patches/210-can_include_linux_fs_h.patch b/package/kernel/ep80579-drivers/patches/210-can_include_linux_fs_h.patch
new file mode 100644
index 0000000000..a560fa6d36
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/210-can_include_linux_fs_h.patch
@@ -0,0 +1,11 @@
+--- a/Embedded/src/CAN/can_main.c
++++ b/Embedded/src/CAN/can_main.c
+@@ -70,6 +70,8 @@
+
+ #include "can_main.h"
+ #include "can_ioctl.h"
++#include <linux/fs.h>
++
+
+ MODULE_AUTHOR("Intel(R) Corporation");
+ MODULE_DESCRIPTION("Controller Area Network Driver");
diff --git a/package/kernel/ep80579-drivers/patches/220-can_fix_irq_request.patch b/package/kernel/ep80579-drivers/patches/220-can_fix_irq_request.patch
new file mode 100644
index 0000000000..381841fee4
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/220-can_fix_irq_request.patch
@@ -0,0 +1,23 @@
+--- a/Embedded/src/CAN/can_main.c
++++ b/Embedded/src/CAN/can_main.c
+@@ -654,7 +654,7 @@ int can_dev_io(struct inode *inode, stru
+ /*****************************************************************************
+ * Interrupt handler.
+ *****************************************************************************/
+-irqreturn_t can_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t can_irq_handler(int irq, void *dev_id)
+ {
+ can_os_t *can_os = (can_os_t *) dev_id;
+ unsigned int int_status;
+--- a/Embedded/src/CAN/can_main.h
++++ b/Embedded/src/CAN/can_main.h
+@@ -165,8 +165,7 @@ int can_dev_io(
+
+ irqreturn_t can_irq_handler(
+ int irq,
+- void *dev_id,
+- struct pt_regs *regs);
++ void *dev_id);
+
+ void can_tasklet(
+ unsigned long arg
diff --git a/package/kernel/ep80579-drivers/patches/230-can_remove_driver_data_direct_access.patch b/package/kernel/ep80579-drivers/patches/230-can_remove_driver_data_direct_access.patch
new file mode 100644
index 0000000000..fcbb85c798
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/230-can_remove_driver_data_direct_access.patch
@@ -0,0 +1,40 @@
+--- a/Embedded/src/CAN/can_main.c
++++ b/Embedded/src/CAN/can_main.c
+@@ -214,8 +214,8 @@ int can_pci_probe(struct pci_dev *dev, c
+ spin_lock_init(&(g_can_os[can_num].int_spinlock));
+ spin_lock_init(&(g_can_os[can_num].open_spinlock));
+
+- dev->dev.driver_data = (void *) &(g_can_os[can_num]);
+- if (!dev->dev.driver_data)
++ dev_set_drvdata(&dev->dev, (void *) &(g_can_os[can_num]));
++ if (!dev_get_drvdata(&dev->dev))
+ {
+ printk("Couldn't create CAN device %d. Exiting.\n",
+ dev->device);
+@@ -237,7 +237,7 @@ int can_pci_probe(struct pci_dev *dev, c
+ *****************************************************************************/
+ void can_pci_remove(struct pci_dev *dev)
+ {
+- can_os_t *can_os = dev->dev.driver_data;
++ can_os_t *can_os = dev_get_drvdata(&dev->dev);
+
+ iounmap(can_os->pci_remap);
+ icp_can_destroy(can_os->can);
+@@ -251,7 +251,7 @@ int can_pci_suspend(struct pci_dev *dev,
+ {
+ unsigned int i;
+ unsigned int int_status;
+- can_os_t *can_os = dev->dev.driver_data;
++ can_os_t *can_os = dev_get_drvdata(&dev->dev);
+ int err;
+
+ /* Indicate that we are suspending */
+@@ -322,7 +322,7 @@ int can_pci_suspend(struct pci_dev *dev,
+ int can_pci_resume(struct pci_dev *dev)
+ {
+ unsigned int i;
+- can_os_t *can_os = dev->dev.driver_data;
++ can_os_t *can_os = dev_get_drvdata(&dev->dev);
+
+ /* Restore PCI CFG space */
+ pci_restore_state(dev);
diff --git a/package/kernel/ep80579-drivers/patches/300-wdt_compile_fix.patch b/package/kernel/ep80579-drivers/patches/300-wdt_compile_fix.patch
new file mode 100644
index 0000000000..59242b80b3
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/300-wdt_compile_fix.patch
@@ -0,0 +1,59 @@
+--- a/Embedded/src/WDT/iwdt.c
++++ b/Embedded/src/WDT/iwdt.c
+@@ -180,19 +180,19 @@ MODULE_PARM_DESC(wdt_scale, "Intel WDT s
+ module_param(wdt_intr_type, byte, WDT_INT_TYPE_IRQ);
+ MODULE_PARM_DESC(wdt_intr_type, "Intel WDT interrupt type (default SERIRQ).");
+
+-module_param(wdt_margin1, uint, TIMER_MARGIN);
++module_param(wdt_margin1, uint, 0);
+ MODULE_PARM_DESC(wdt_margin1, "First stage Intel WDT timeout in steps of 1 ms by default.");
+
+-module_param(wdt_margin2, uint, TIMER_MARGIN);
++module_param(wdt_margin2, uint, 0);
+ MODULE_PARM_DESC(wdt_margin2, "Second stage Intel WDT timeout in steps of 1 ms by default.");
+
+ module_param(nowayout, int, 0);
+ MODULE_PARM_DESC(nowayout, "Intel WDT can't be stopped once started (default=0)");
+
+-module_param(wdt_index_port, int, 0x4E);
++module_param(wdt_index_port, int, 0);
+ MODULE_PARM_DESC(wdt_index_port, "WDT Index Port (default 0x4e)");
+
+-module_param(wdt_data_port, int, 0x4E);
++module_param(wdt_data_port, int, 0);
+ MODULE_PARM_DESC(wdt_data_port, "WDT Data Port (default 0x4f)");
+
+ static int wdt_get_iobase(struct pci_dev *dev, u16 *iobase, int *irq);
+@@ -218,7 +218,7 @@ static ssize_t wdt_write(struct file *fi
+ size_t count, loff_t * pos);
+ static int wdt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg);
+-static irqreturn_t wdt_isr(int irq, void *dev_id, struct pt_regs *regs);
++static irqreturn_t wdt_isr(int irq, void *dev_id);
+ static void __exit wdt_cleanup(void);
+ static int __init wdt_init(void);
+ static int __init wdt_init_one(struct pci_dev *dev,
+@@ -255,7 +255,7 @@ static struct pci_driver wdt_driver = {
+ name: "iwdt",
+ id_table: lpc_pci_tbl,
+ probe: wdt_init_one,
+- remove: __devexit(wdt_remove_one),
++ remove: __devexit_p(wdt_remove_one),
+ suspend: wdt_pci_suspend,
+ resume: wdt_pci_resume,
+ };
+@@ -1393,12 +1393,12 @@ static int wdt_ioctl(struct inode *inode
+
+ /*
+ * Function Name: wdt_isr()
+- * Parameter: int irq - irq number, void *dev_id, struct pt_regs *regs
++ * Parameter: int irq - irq number, void *dev_id
+ * Return Value:: IRQ_NONE - if the interrupt is not for wdt.
+ * IRQ_HANDLED - if it is for wdt.
+ * Description: This is the interrupt service routine of the WDT.
+ */
+-static irqreturn_t wdt_isr(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t wdt_isr(int irq, void *dev_id)
+ {
+ u8 val;
+
diff --git a/package/kernel/ep80579-drivers/patches/400-edma_fix_irq_request_warning.patch b/package/kernel/ep80579-drivers/patches/400-edma_fix_irq_request_warning.patch
new file mode 100644
index 0000000000..d858aff1ff
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/400-edma_fix_irq_request_warning.patch
@@ -0,0 +1,22 @@
+--- a/Embedded/src/EDMA/dma_linux.c
++++ b/Embedded/src/EDMA/dma_linux.c
+@@ -149,8 +149,7 @@ int32_t edma_suspend (struct pci_dev *de
+ int32_t edma_resume(struct pci_dev *dev);
+ int32_t initialize_edma_device(struct edma_device *device);
+
+-static irqreturn_t edma_irq_handler(int32_t irq, void * dev_id,
+- struct pt_regs * regs);
++static irqreturn_t edma_irq_handler(int32_t irq, void * dev_id);
+
+ /* Prototypes - Misc. */
+
+@@ -429,8 +428,7 @@ int32_t edma_release(struct inode * inod
+ * Return Values: HANDLED = 1, NOT_HANDLED = 0
+ *****************************************************************************/
+
+-static irqreturn_t edma_irq_handler(int32_t irq, void * dev_id,
+- struct pt_regs * regs)
++static irqreturn_t edma_irq_handler(int32_t irq, void * dev_id)
+ {
+
+ uint32_t clear_bits;
diff --git a/package/kernel/ep80579-drivers/patches/500-1588_fix_irq_request_warning.patch b/package/kernel/ep80579-drivers/patches/500-1588_fix_irq_request_warning.patch
new file mode 100644
index 0000000000..cfffb9c95f
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/500-1588_fix_irq_request_warning.patch
@@ -0,0 +1,22 @@
+--- a/Embedded/src/1588/1588.c
++++ b/Embedded/src/1588/1588.c
+@@ -631,7 +631,7 @@ int restore_interrupts(void)
+ IRQ_NONE => this device did not interrupt
+
+ ******************************************************************************/
+-irqreturn_t timesync_isr(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t timesync_isr(int irq, void *dev_id)
+ {
+ if ( !ixTimeSyncAccEventAmmsFlagGet() && !ixTimeSyncAccEventAsmsFlagGet()&&
+ !ixTimeSyncAccEventAtmFlagGet() && !ixTimeSyncAccEventPpsmFlagGet()&&
+--- a/Embedded/src/1588/1588.h
++++ b/Embedded/src/1588/1588.h
+@@ -128,7 +128,7 @@ int pci_suspend(struct pci_dev *dev, pm_
+ int pci_resume(struct pci_dev *dev);
+ int pci_probe(struct pci_dev *dev, const struct pci_device_id *id);
+ void pci_remove(struct pci_dev *dev);
+-irqreturn_t timesync_isr(int irq, void *dev_id, struct pt_regs *regs);
++irqreturn_t timesync_isr(int irq, void *dev_id);
+
+ // private functions
+ int save_reg_state(void);
diff --git a/package/kernel/ep80579-drivers/patches/600-2.6.27_includes.patch b/package/kernel/ep80579-drivers/patches/600-2.6.27_includes.patch
new file mode 100644
index 0000000000..c11275ece6
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/600-2.6.27_includes.patch
@@ -0,0 +1,22 @@
+--- a/Embedded/src/CAN/can_main.h
++++ b/Embedded/src/CAN/can_main.h
+@@ -65,7 +65,7 @@
+
+ #include <linux/interrupt.h>
+ #include <linux/pci.h>
+-#include <asm/semaphore.h>
++#include <linux/semaphore.h>
+ #include <linux/spinlock.h>
+ #include <linux/cdev.h>
+ #include <asm/uaccess.h>
+--- a/Embedded/src/EDMA/dma_linux.c
++++ b/Embedded/src/EDMA/dma_linux.c
+@@ -87,7 +87,7 @@
+ #include <linux/fcntl.h> /* O_ACCMODE */
+ #include <asm/system.h> /* cli, *_flags */
+ #include <asm/uaccess.h> /* copy_to_user */
+-#include <asm/semaphore.h>
++#include <linux/semaphore.h>
+ #include <asm/io.h> /* inb(), outb() */
+ #include <linux/kmod.h>
+ #include <linux/ioport.h> /* request_region */
diff --git a/package/kernel/ep80579-drivers/patches/601-2.6.32_includes.patch b/package/kernel/ep80579-drivers/patches/601-2.6.32_includes.patch
new file mode 100644
index 0000000000..8981853774
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/601-2.6.32_includes.patch
@@ -0,0 +1,30 @@
+--- a/Embedded/src/1588/1588.c
++++ b/Embedded/src/1588/1588.c
+@@ -72,6 +72,7 @@
+ *
+ ****************************************************************************/
+
++#include <linux/sched.h>
+ #include "1588.h"
+
+ MODULE_AUTHOR("Intel(R) Corporation");
+--- a/Embedded/src/CAN/can_main.c
++++ b/Embedded/src/CAN/can_main.c
+@@ -68,6 +68,7 @@
+ *
+ **************************************************************************/
+
++#include <linux/sched.h>
+ #include "can_main.h"
+ #include "can_ioctl.h"
+ #include <linux/fs.h>
+--- a/Embedded/src/WDT/iwdt.c
++++ b/Embedded/src/WDT/iwdt.c
+@@ -137,6 +137,7 @@
+ #include <linux/watchdog.h>
+ #include <linux/miscdevice.h>
+ #include <linux/interrupt.h>
++#include <linux/sched.h>
+ #include "iwdt.h"
+
+ MODULE_AUTHOR("Intel(R) Corporation");
diff --git a/package/kernel/ep80579-drivers/patches/700-iegbe_kcompat_2.6.30.patch b/package/kernel/ep80579-drivers/patches/700-iegbe_kcompat_2.6.30.patch
new file mode 100644
index 0000000000..ca8c1bb9ea
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/700-iegbe_kcompat_2.6.30.patch
@@ -0,0 +1,31 @@
+--- a/Embedded/src/GbE/kcompat.h
++++ b/Embedded/src/GbE/kcompat.h
+@@ -46,12 +46,6 @@ GPL LICENSE SUMMARY
+ #include <linux/sched.h>
+ #include <asm/io.h>
+
+-#ifndef IRQ_HANDLED
+-#define irqreturn_t void
+-#define IRQ_HANDLED
+-#define IRQ_NONE
+-#endif
+-
+ #ifndef SET_NETDEV_DEV
+ #define SET_NETDEV_DEV(net, pdev)
+ #endif
+@@ -748,6 +742,15 @@ extern void dump_stack(void);
+
+ #endif /* 2.4.24 */
+
++/*****************************************************************************/
++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) )
++#ifndef IRQ_HANDLED
++#define irqreturn_t void
++#define IRQ_HANDLED
++#define IRQ_NONE
++#endif
++#endif /* < 2.6.30 */
++
+ #endif /* _KCOMPAT_H_ */
+
+
diff --git a/package/kernel/ep80579-drivers/patches/701-iegbe_poll_dev.patch b/package/kernel/ep80579-drivers/patches/701-iegbe_poll_dev.patch
new file mode 100644
index 0000000000..63a1326853
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/701-iegbe_poll_dev.patch
@@ -0,0 +1,11 @@
+--- a/Embedded/src/GbE/iegbe_main.c
++++ b/Embedded/src/GbE/iegbe_main.c
+@@ -3534,7 +3534,7 @@ static int iegbe_clean(struct napi_struc
+ int tx_cleaned = 0, work_done = 0;
+
+ /* Must NOT use netdev_priv macro here. */
+- adapter = poll_dev->priv;
++ adapter = netdev_priv(poll_dev);
+
+ /* iegbe_clean is called per-cpu. This lock protects
+ * tx_ring[0] from being cleaned by multiple cpus
diff --git a/package/kernel/ep80579-drivers/patches/710-3.3-fix-generated-header-locations.patch b/package/kernel/ep80579-drivers/patches/710-3.3-fix-generated-header-locations.patch
new file mode 100644
index 0000000000..793d08d39b
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/710-3.3-fix-generated-header-locations.patch
@@ -0,0 +1,91 @@
+--- a/Embedded/src/GbE/Makefile
++++ b/Embedded/src/GbE/Makefile
+@@ -60,19 +60,19 @@ GBE_NAME = iegbe
+ GCU_NAME = gcu
+
+ VERSION_FILE := $(KSRC)/include/linux/version.h
+-UTS_REL_FILE := $(KSRC)/include/linux/utsrelease.h
+-CONFIG_FILE := $(KSRC)/include/linux/autoconf.h
++UTS_REL_FILE := $(KSRC)/include/generated/utsrelease.h
++CONFIG_FILE := $(KSRC)/include/generated/autoconf.h
+
+ ifeq (,$(wildcard $(VERSION_FILE)))
+ $(error Linux kernel source not configured - missing version.h)
+ endif
+
+ ifeq (,$(wildcard $(CONFIG_FILE)))
+- $(error Linux kernel source not configured - missing autoconf.h)
++ $(error Linux kernel source not configured - missing autoconf.h)
+ endif
+
+ ifeq (,$(wildcard $(UTS_REL_FILE)))
+- $(error Linux kernel source not configured - missing utsrelease.h)
++ $(error Linux kernel source not configured - missing utsrelease.h)
+ endif
+
+ # set the install path
+--- a/Embedded/src/1588/Makefile
++++ b/Embedded/src/1588/Makefile
+@@ -97,8 +97,8 @@ OUTPUT_PATH ?= /
+ EXTRA_LDFLAGS += -whole-archive
+
+ VERSION_FILE := $(KOBJ)/include/linux/version.h
+-UTS_REL_FILE := $(KSRC)/include/linux/utsrelease.h
+-CONFIG_FILE := $(KOBJ)/include/linux/autoconf.h
++UTS_REL_FILE := $(KSRC)/include/generated/utsrelease.h
++CONFIG_FILE := $(KOBJ)/include/generated/autoconf.h
+
+
+ # as of 2.6.16, kernel define UTS_RELEASE has been moved to utsrelease.h
+--- a/Embedded/src/CAN/Makefile
++++ b/Embedded/src/CAN/Makefile
+@@ -100,8 +100,8 @@ OUTPUT_PATH ?= /
+ EXTRA_LDFLAGS += -whole-archive
+
+ VERSION_FILE := $(KOBJ)/include/linux/version.h
+-UTS_REL_FILE := $(KSRC)/include/linux/utsrelease.h
+-CONFIG_FILE := $(KOBJ)/include/linux/autoconf.h
++UTS_REL_FILE := $(KSRC)/include/generated/utsrelease.h
++CONFIG_FILE := $(KOBJ)/include/generated/autoconf.h
+
+
+ # as of 2.6.16, kernel define UTS_RELEASE has been moved to utsrelease.h
+--- a/Embedded/src/EDMA/Makefile
++++ b/Embedded/src/EDMA/Makefile
+@@ -114,8 +114,8 @@ OUTPUT_PATH ?= /
+ EXTRA_LDFLAGS += -whole-archive
+
+ VERSION_FILE := $(KOBJ)/include/linux/version.h
+-UTS_REL_FILE := $(KSRC)/include/linux/utsrelease.h
+-CONFIG_FILE := $(KOBJ)/include/linux/autoconf.h
++UTS_REL_FILE := $(KSRC)/include/generated/utsrelease.h
++CONFIG_FILE := $(KOBJ)/include/generated/autoconf.h
+
+
+ # as of 2.6.16, kernel define UTS_RELEASE has been moved to utsrelease.h
+--- a/Embedded/src/GPIO/Makefile
++++ b/Embedded/src/GPIO/Makefile
+@@ -97,8 +97,8 @@ OUTPUT_PATH ?= /
+ EXTRA_LDFLAGS += -whole-archive
+
+ VERSION_FILE := $(KOBJ)/include/linux/version.h
+-UTS_REL_FILE := $(KSRC)/include/linux/utsrelease.h
+-CONFIG_FILE := $(KOBJ)/include/linux/autoconf.h
++UTS_REL_FILE := $(KSRC)/include/generated/utsrelease.h
++CONFIG_FILE := $(KOBJ)/include/generated/autoconf.h
+
+
+ # as of 2.6.16, kernel define UTS_RELEASE has been moved to utsrelease.h
+--- a/Embedded/src/WDT/Makefile
++++ b/Embedded/src/WDT/Makefile
+@@ -99,8 +99,8 @@ OUTPUT_PATH ?= /
+ EXTRA_LDFLAGS += -whole-archive
+
+ VERSION_FILE := $(KOBJ)/include/linux/version.h
+-UTS_REL_FILE := $(KSRC)/include/linux/utsrelease.h
+-CONFIG_FILE := $(KOBJ)/include/linux/autoconf.h
++UTS_REL_FILE := $(KSRC)/include/generated/utsrelease.h
++CONFIG_FILE := $(KOBJ)/include/generated/autoconf.h
+
+
+ # as of 2.6.16, kernel define UTS_RELEASE has been moved to utsrelease.h
diff --git a/package/kernel/ep80579-drivers/patches/711-3.3-gbe-fixes.patch b/package/kernel/ep80579-drivers/patches/711-3.3-gbe-fixes.patch
new file mode 100644
index 0000000000..7b2df63984
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/711-3.3-gbe-fixes.patch
@@ -0,0 +1,392 @@
+--- a/Embedded/src/GbE/kcompat.h
++++ b/Embedded/src/GbE/kcompat.h
+@@ -590,6 +590,10 @@ static inline void _kc_synchronize_irq()
+ #define ETHTOOL_OPS_COMPAT
+ #endif
+
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
++#define HAVE_NETIF_MSG 1
++#endif
++
+ #ifndef HAVE_NETIF_MSG
+ #define HAVE_NETIF_MSG 1
+ enum {
+--- a/Embedded/src/GbE/iegbe_main.c
++++ b/Embedded/src/GbE/iegbe_main.c
+@@ -159,9 +159,9 @@ static void iegbe_smartspeed(struct iegb
+ static inline int iegbe_82547_fifo_workaround(struct iegbe_adapter *adapter,
+ struct sk_buff *skb);
+
+-static void iegbe_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
+-static void iegbe_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
+-static void iegbe_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
++static bool iegbe_vlan_used(struct iegbe_adapter *adapter);
++static int iegbe_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
++static int iegbe_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
+ static void iegbe_restore_vlan(struct iegbe_adapter *adapter);
+
+ static int iegbe_notify_reboot(struct notifier_block *,
+@@ -324,8 +324,8 @@ static void iegbe_update_mng_vlan(struct
+ struct net_device *netdev = adapter->netdev;
+ u16 vid = hw->mng_cookie.vlan_id;
+ u16 old_vid = adapter->mng_vlan_id;
+- if (adapter->vlgrp) {
+- if (!vlan_group_get_device(adapter->vlgrp, vid)) {
++ if (iegbe_vlan_used(adapter)) {
++ if (!test_bit(old_vid, adapter->active_vlans)) {
+ if (hw->mng_cookie.status &
+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
+ iegbe_vlan_rx_add_vid(netdev, vid);
+@@ -335,7 +335,7 @@ static void iegbe_update_mng_vlan(struct
+
+ if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
+ (vid != old_vid) &&
+- !vlan_group_get_device(adapter->vlgrp, old_vid))
++ !test_bit(old_vid, adapter->active_vlans))
+ iegbe_vlan_rx_kill_vid(netdev, old_vid);
+ } else
+ adapter->mng_vlan_id = vid;
+@@ -736,7 +736,6 @@ static const struct net_device_ops iegbe
+ .ndo_do_ioctl = iegbe_ioctl,
+ .ndo_validate_addr = eth_validate_addr,
+
+- .ndo_vlan_rx_register = iegbe_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = iegbe_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = iegbe_vlan_rx_kill_vid,
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+@@ -767,7 +766,6 @@ static int __devinit iegbe_probe(struct
+ u16 eeprom_data = 0;
+ u16 eeprom_apme_mask = E1000_EEPROM_APME;
+ int bars;
+- DECLARE_MAC_BUF(mac);
+
+ bars = pci_select_bars(pdev, IORESOURCE_MEM);
+ err = pci_enable_device(pdev);
+@@ -1247,8 +1245,7 @@ static int iegbe_close(struct net_device
+
+ if ((hw->mng_cookie.status &
+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+- !(adapter->vlgrp &&
+- vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
++ !test_bit(adapter->mng_vlan_id, adapter->active_vlans)) {
+ iegbe_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
+ }
+ return 0;
+@@ -2163,11 +2160,13 @@ static void iegbe_set_rx_mode(struct net
+ struct iegbe_hw *hw = &adapter->hw;
+ struct netdev_hw_addr *ha;
+ bool use_uc = false;
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0))
+ struct dev_addr_list *mc_ptr;
+- u32 rctl;
+ u32 hash_value;
+- int i, rar_entries = E1000_RAR_ENTRIES;
+ int mta_reg_count = E1000_NUM_MTA_REGISTERS;
++#endif
++ u32 rctl;
++ int i, rar_entries = E1000_RAR_ENTRIES;
+
+ /* reserve RAR[14] for LAA over-write work-around */
+ if (hw->mac_type == iegbe_82571)
+@@ -2220,6 +2219,7 @@ int mta_reg_count = E1000_NUM_MTA_REGIST
+
+ WARN_ON(i == rar_entries);
+
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0))
+ mc_ptr = netdev->mc_list;
+
+ for (; i < rar_entries; i++) {
+@@ -2247,6 +2247,7 @@ int mta_reg_count = E1000_NUM_MTA_REGIST
+ hash_value = iegbe_hash_mc_addr(hw, mc_ptr->da_addr);
+ iegbe_mta_set(hw, hash_value);
+ }
++#endif
+
+ if (hw->mac_type == iegbe_82542_rev2_0)
+ iegbe_leave_82542_rst(adapter);
+@@ -2821,14 +2822,14 @@ static int iegbe_tx_map(struct iegbe_ada
+ * Avoid terminating buffers within evenly-aligned
+ * dwords. */
+ if(unlikely(adapter->pcix_82544 &&
+- !((unsigned long)(frag->page+offset+size-1) & 4) &&
++ !((unsigned long)(frag->page.p+offset+size-1) & 4) &&
+ size > 4))
+ size -= 4;
+
+ buffer_info->length = size;
+ buffer_info->dma =
+ pci_map_page(adapter->pdev,
+- frag->page,
++ frag->page.p,
+ offset,
+ size,
+ PCI_DMA_TODEVICE);
+@@ -3131,7 +3132,7 @@ static int iegbe_xmit_frame(struct sk_bu
+ }
+ }
+
+- if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
++ if (unlikely(iegbe_vlan_used(adapter) && vlan_tx_tag_present(skb))) {
+ tx_flags |= E1000_TX_FLAGS_VLAN;
+ tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
+ }
+@@ -3832,10 +3833,12 @@ static bool iegbe_clean_rx_irq(struct ie
+
+ skb->protocol = eth_type_trans(skb, netdev);
+
+- if (unlikely(adapter->vlgrp &&
++ if (unlikely(iegbe_vlan_used(adapter) &&
+ (status & E1000_RXD_STAT_VP))) {
+- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+- le16_to_cpu(rx_desc->special));
++ u16 vid;
++
++ vid = le16_to_cpu(rx_desc->special);
++ __vlan_hwaccel_put_tag(skb, vid);
+ } else {
+ netif_receive_skb(skb);
+ }
+@@ -3986,9 +3989,10 @@ copydone:
+ cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)))
+ adapter->rx_hdr_split++;
+
+- if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
+- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+- le16_to_cpu(rx_desc->wb.middle.vlan));
++ if(unlikely(iegbe_vlan_used(adapter) && (staterr & E1000_RXD_STAT_VP))) {
++ u16 vid;
++ vid = le16_to_cpu(rx_desc->wb.middle.vlan);
++ __vlan_hwaccel_put_tag(skb, vid);
+ } else {
+ netif_receive_skb(skb);
+ }
+@@ -4496,17 +4500,25 @@ iegbe_io_write(struct iegbe_hw *hw, unsi
+ outl(value, port);
+ }
+
+-static void iegbe_vlan_rx_register(struct net_device *netdev,
+- struct vlan_group *grp)
++static bool iegbe_vlan_used(struct iegbe_adapter *adapter)
++{
++ u16 vid;
++
++ for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
++ return true;
++
++ return false;
++}
++
++static void iegbe_vlan_mode(struct net_device *netdev, bool vlan_on)
+ {
+ struct iegbe_adapter *adapter = netdev_priv(netdev);
+ uint32_t ctrl, rctl;
+
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ iegbe_irq_disable(adapter);
+- adapter->vlgrp = grp;
+
+- if(grp) {
++ if(vlan_on) {
+ /* enable VLAN tag insert/strip */
+ ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+ ctrl |= E1000_CTRL_VME;
+@@ -4538,30 +4550,37 @@ static void iegbe_vlan_rx_register(struc
+ iegbe_irq_enable(adapter);
+ }
+
+-static void iegbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
++static int iegbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+ {
+ struct iegbe_adapter *adapter = netdev_priv(netdev);
+ uint32_t vfta, index;
+ if((adapter->hw.mng_cookie.status &
+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+ (vid == adapter->mng_vlan_id)) {
+- return;
++ return 0;
+ }
++
++ if (!iegbe_vlan_used(adapter))
++ iegbe_vlan_mode(netdev, true);
++
+ /* add VID to filter table */
+ index = (vid >> 0x5) & 0x7F;
+ vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
+ vfta |= (0x1 << (vid & 0x1F));
+ iegbe_write_vfta(&adapter->hw, index, vfta);
++
++ set_bit(vid, adapter->active_vlans);
++
++ return 0;
+ }
+
+-static void iegbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
++static int iegbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+ {
+ struct iegbe_adapter *adapter = netdev_priv(netdev);
+ u32 vfta, index;
+
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ iegbe_irq_disable(adapter);
+- vlan_group_set_device(adapter->vlgrp, vid, NULL);
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ iegbe_irq_enable(adapter);
+
+@@ -4570,21 +4589,26 @@ static void iegbe_vlan_rx_kill_vid(struc
+ vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
+ vfta &= ~(0x1 << (vid & 0x1F));
+ iegbe_write_vfta(&adapter->hw, index, vfta);
++
++ clear_bit(vid, adapter->active_vlans);
++
++ if (!iegbe_vlan_used(adapter))
++ iegbe_vlan_mode(netdev, false);
++
++ return 0;
+ }
+
+ static void iegbe_restore_vlan(struct iegbe_adapter *adapter)
+ {
+- iegbe_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+-
+- if (adapter->vlgrp) {
+ u16 vid;
+- for (vid = 0x0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+- if (!vlan_group_get_device(adapter->vlgrp, vid))
+- continue;
++
++ if (!iegbe_vlan_used(adapter))
++ return;
++
++ iegbe_vlan_mode(adapter->netdev, true);
++ for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
+ iegbe_vlan_rx_add_vid(adapter->netdev, vid);
+ }
+- }
+-}
+
+
+ int iegbe_set_spd_dplx(struct iegbe_adapter *adapter, u16 spddplx)
+@@ -4864,10 +4888,11 @@ iegbe_resume(struct pci_dev *pdev)
+ default:
+ break;
+ }
+-#endif
+
+ return 0x0;
+ }
++#endif
++
+
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+ /*
+--- a/Embedded/src/GbE/iegbe_ethtool.c
++++ b/Embedded/src/GbE/iegbe_ethtool.c
+@@ -327,6 +327,7 @@ iegbe_set_pauseparam(struct net_device *
+ return 0;
+ }
+
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0))
+ static uint32_t
+ iegbe_get_rx_csum(struct net_device *netdev)
+ {
+@@ -392,6 +393,7 @@ iegbe_set_tso(struct net_device *netdev,
+ return 0;
+ }
+ #endif /* NETIF_F_TSO */
++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) */
+
+ static uint32_t
+ iegbe_get_msglevel(struct net_device *netdev)
+@@ -807,6 +809,7 @@ err_setup_rx:
+ E1000_82542_##R : E1000_##R; \
+ return 1; } }
+
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0))
+ static int
+ iegbe_reg_test(struct iegbe_adapter *adapter, uint64_t *data)
+ {
+@@ -1710,6 +1713,7 @@ iegbe_diag_test(struct net_device *netde
+ }
+ msleep_interruptible(0xfa0);
+ }
++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) */
+
+ static void
+ iegbe_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+@@ -1812,6 +1816,7 @@ iegbe_set_wol(struct net_device *netdev,
+ /* bit defines for adapter->led_status */
+ #define E1000_LED_ON 0
+
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0))
+ static void
+ iegbe_led_blink_callback(unsigned long data)
+ {
+@@ -1864,6 +1869,7 @@ iegbe_phys_id(struct net_device *netdev,
+
+ return 0;
+ }
++#endif
+
+ static int
+ iegbe_nway_reset(struct net_device *netdev)
+@@ -1876,11 +1882,13 @@ iegbe_nway_reset(struct net_device *netd
+ return 0;
+ }
+
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0))
+ static int
+ iegbe_get_stats_count(struct net_device *netdev)
+ {
+ return E1000_STATS_LEN;
+ }
++#endif
+
+ static void
+ iegbe_get_ethtool_stats(struct net_device *netdev,
+@@ -1936,6 +1944,8 @@ struct ethtool_ops iegbe_ethtool_ops = {
+ .set_ringparam = iegbe_set_ringparam,
+ .get_pauseparam = iegbe_get_pauseparam,
+ .set_pauseparam = iegbe_set_pauseparam,
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0))
+ .get_rx_csum = iegbe_get_rx_csum,
+ .set_rx_csum = iegbe_set_rx_csum,
+ .get_tx_csum = iegbe_get_tx_csum,
+@@ -1946,11 +1956,13 @@ struct ethtool_ops iegbe_ethtool_ops = {
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = iegbe_set_tso,
+ #endif
++
+ .self_test_count = iegbe_diag_test_count,
+ .self_test = iegbe_diag_test,
+- .get_strings = iegbe_get_strings,
+ .phys_id = iegbe_phys_id,
+ .get_stats_count = iegbe_get_stats_count,
++#endif
++ .get_strings = iegbe_get_strings,
+ .get_ethtool_stats = iegbe_get_ethtool_stats,
+ };
+
+--- a/Embedded/src/GbE/gcu_main.c
++++ b/Embedded/src/GbE/gcu_main.c
+@@ -93,7 +93,7 @@ static struct pci_driver gcu_driver = {
+ };
+
+ static struct gcu_adapter *global_adapter = 0;
+-static spinlock_t global_adapter_spinlock = SPIN_LOCK_UNLOCKED;
++static DEFINE_SPINLOCK(global_adapter_spinlock);
+ static unsigned long g_intflags = 0;
+
+ MODULE_AUTHOR("Intel(R) Corporation");
+--- a/Embedded/src/GbE/iegbe.h
++++ b/Embedded/src/GbE/iegbe.h
+@@ -257,7 +257,7 @@ struct iegbe_adapter {
+ struct timer_list tx_fifo_stall_timer;
+ struct timer_list watchdog_timer;
+ struct timer_list phy_info_timer;
+- struct vlan_group *vlgrp;
++ unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
+ uint16_t mng_vlan_id;
+ uint32_t bd_number;
+ uint32_t rx_buffer_len;
diff --git a/package/kernel/ep80579-drivers/patches/712-3.3-can-fixes.patch b/package/kernel/ep80579-drivers/patches/712-3.3-can-fixes.patch
new file mode 100644
index 0000000000..06a09e5139
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/712-3.3-can-fixes.patch
@@ -0,0 +1,41 @@
+--- a/Embedded/src/CAN/can_main.c
++++ b/Embedded/src/CAN/can_main.c
+@@ -72,6 +72,7 @@
+ #include "can_main.h"
+ #include "can_ioctl.h"
+ #include <linux/fs.h>
++#include <linux/module.h>
+
+
+ MODULE_AUTHOR("Intel(R) Corporation");
+@@ -110,7 +111,7 @@ struct file_operations file_ops = {
+ .owner = THIS_MODULE,
+ .read = can_read,
+ .write = can_write,
+- .ioctl = can_dev_io,
++ .unlocked_ioctl = can_dev_io,
+ .open = can_open,
+ .release = can_release
+ };
+@@ -594,8 +595,7 @@ int icp_can_reset(can_os_t *can_os)
+ /*****************************************************************************
+ * Device IO control function. Used by user apps to configure CAN device.
+ *****************************************************************************/
+-int can_dev_io(struct inode *inode, struct file *filp, unsigned int cmd,
+- unsigned long arg)
++long can_dev_io(struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+ can_os_t *can_os;
+ unsigned int err=0;
+--- a/Embedded/src/CAN/can_main.h
++++ b/Embedded/src/CAN/can_main.h
+@@ -157,8 +157,7 @@ ssize_t can_write(
+ int icp_can_reset(
+ can_os_t *can_os);
+
+-int can_dev_io(
+- struct inode *inode,
++long can_dev_io(
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long arg);
diff --git a/package/kernel/ep80579-drivers/patches/713-3.3-gpio-fixes.patch b/package/kernel/ep80579-drivers/patches/713-3.3-gpio-fixes.patch
new file mode 100644
index 0000000000..47fb920d0a
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/713-3.3-gpio-fixes.patch
@@ -0,0 +1,33 @@
+--- a/Embedded/src/GPIO/gpio.h
++++ b/Embedded/src/GPIO/gpio.h
+@@ -121,8 +121,7 @@ int gpio_init(void);
+ void gpio_close(void);
+ int gpio_open(struct inode *inode, struct file *filp);
+ int gpio_release(struct inode *inode, struct file *filp);
+-int gpio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+- unsigned long arg);
++long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+
+ // private driver functions
+ int gpio_getpininfo(int Signal, char *pBuff);
+@@ -134,7 +133,7 @@ struct file_operations file_ops =
+ .owner = THIS_MODULE,
+ .open = gpio_open,
+ .release = gpio_release,
+- .ioctl = gpio_ioctl,
++ .unlocked_ioctl = gpio_ioctl,
+ };
+
+ #endif
+--- a/Embedded/src/GPIO/gpio_ref.c
++++ b/Embedded/src/GPIO/gpio_ref.c
+@@ -251,8 +251,7 @@ int gpio_release(struct inode *inode, st
+ 0 => success
+ < 0 => error
+ ******************************************************************************/
+-int gpio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+- unsigned long arg)
++long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+ gpio_ioctl_t Info;
+ u_int bitstr = 0;
diff --git a/package/kernel/ep80579-drivers/patches/714-3.3-wdt-fixes.patch b/package/kernel/ep80579-drivers/patches/714-3.3-wdt-fixes.patch
new file mode 100644
index 0000000000..60cc4aeb73
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/714-3.3-wdt-fixes.patch
@@ -0,0 +1,31 @@
+--- a/Embedded/src/WDT/iwdt.c
++++ b/Embedded/src/WDT/iwdt.c
+@@ -217,8 +217,7 @@ static int wdt_open(struct inode *inode,
+ static int wdt_release(struct inode *inode, struct file *file);
+ static ssize_t wdt_write(struct file *file, const char *data,
+ size_t count, loff_t * pos);
+-static int wdt_ioctl(struct inode *inode, struct file *file,
+- unsigned int cmd, unsigned long arg);
++static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+ static irqreturn_t wdt_isr(int irq, void *dev_id);
+ static void __exit wdt_cleanup(void);
+ static int __init wdt_init(void);
+@@ -243,7 +242,7 @@ static struct pci_device_id lpc_pci_tbl[
+ static struct file_operations wdt_fops = {
+ owner: THIS_MODULE,
+ write: wdt_write,
+- ioctl: wdt_ioctl,
++ unlocked_ioctl: wdt_ioctl,
+ open: wdt_open,
+ release: wdt_release,
+ };
+@@ -1201,8 +1200,7 @@ char *wdt_get_ioctl_string(unsigned int
+ * Return Value: 0 - successful, negative value - failed.
+ * Description: This function is used to provide IO interface.
+ */
+-static int wdt_ioctl(struct inode *inode, struct file *file,
+- unsigned int cmd, unsigned long arg)
++static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ {
+ u8 mode=0, scale=0, int_type=0;
+ u32 u_margin=0, dcount=0;
diff --git a/package/kernel/ep80579-drivers/patches/715-3.3-1588-fixes.patch b/package/kernel/ep80579-drivers/patches/715-3.3-1588-fixes.patch
new file mode 100644
index 0000000000..efa19d959d
--- /dev/null
+++ b/package/kernel/ep80579-drivers/patches/715-3.3-1588-fixes.patch
@@ -0,0 +1,33 @@
+--- a/Embedded/src/1588/1588.c
++++ b/Embedded/src/1588/1588.c
+@@ -664,8 +664,7 @@ irqreturn_t timesync_isr(int irq, void *
+ 0 => success
+ < 0 => error
+ ******************************************************************************/
+-int timesync_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+- unsigned long arg)
++long timesync_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+ wait_queue_head_t *event = NULL;
+ unsigned int bytes_ret = 0;
+--- a/Embedded/src/1588/1588.h
++++ b/Embedded/src/1588/1588.h
+@@ -121,8 +121,7 @@ MODULE_DEVICE_TABLE(pci, pci_ids);
+ // Linux functions
+ int timesync_open(struct inode *inode, struct file *filp);
+ int timesync_release(struct inode *inode, struct file *filp);
+-int timesync_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+- unsigned long arg);
++long timesync_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+ void timesync_close(void);
+ int pci_suspend(struct pci_dev *dev, pm_message_t state);
+ int pci_resume(struct pci_dev *dev);
+@@ -142,7 +141,7 @@ struct file_operations file_ops =
+ .owner = THIS_MODULE,
+ .open = timesync_open,
+ .release = timesync_release,
+- .ioctl = timesync_ioctl,
++ .unlocked_ioctl = timesync_ioctl,
+ };
+
+ // Linux pci operations
diff --git a/package/kernel/gpio-button-hotplug/Makefile b/package/kernel/gpio-button-hotplug/Makefile
new file mode 100644
index 0000000000..1778aadf09
--- /dev/null
+++ b/package/kernel/gpio-button-hotplug/Makefile
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2008-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=gpio-button-hotplug
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/gpio-button-hotplug
+ SUBMENU:=Other modules
+ TITLE:=Simple GPIO Button Hotplug driver
+ FILES:=$(PKG_BUILD_DIR)/gpio-button-hotplug.ko
+ AUTOLOAD:=$(call AutoLoad,30,gpio-button-hotplug,1)
+ KCONFIG:=
+endef
+
+define KernelPackage/button-hotplug/description
+ Kernel module to generate GPIO button hotplug events
+endef
+
+MAKE_OPTS:= \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ SUBDIRS="$(PKG_BUILD_DIR)"
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ $(MAKE_OPTS) \
+ modules
+endef
+
+$(eval $(call KernelPackage,gpio-button-hotplug))
diff --git a/package/kernel/gpio-button-hotplug/src/Makefile b/package/kernel/gpio-button-hotplug/src/Makefile
new file mode 100644
index 0000000000..e968865631
--- /dev/null
+++ b/package/kernel/gpio-button-hotplug/src/Makefile
@@ -0,0 +1 @@
+obj-m += gpio-button-hotplug.o
diff --git a/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c
new file mode 100644
index 0000000000..9d91b57b56
--- /dev/null
+++ b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c
@@ -0,0 +1,564 @@
+/*
+ * GPIO Button Hotplug driver
+ *
+ * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * Based on the diag.c - GPIO interface driver for Broadcom boards
+ * Copyright (C) 2006 Mike Baker <mbm@openwrt.org>,
+ * Copyright (C) 2006-2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2008 Andy Boyett <agb@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kmod.h>
+
+#include <linux/workqueue.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/kobject.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio_keys.h>
+
+#define DRV_NAME "gpio-keys-polled"
+
+#define BH_SKB_SIZE 2048
+
+#define PFX DRV_NAME ": "
+
+#undef BH_DEBUG
+
+#ifdef BH_DEBUG
+#define BH_DBG(fmt, args...) printk(KERN_DEBUG "%s: " fmt, DRV_NAME, ##args )
+#else
+#define BH_DBG(fmt, args...) do {} while (0)
+#endif
+
+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, DRV_NAME, ##args )
+
+struct bh_priv {
+ unsigned long seen;
+};
+
+struct bh_event {
+ const char *name;
+ char *action;
+ unsigned long seen;
+
+ struct sk_buff *skb;
+ struct work_struct work;
+};
+
+struct bh_map {
+ unsigned int code;
+ const char *name;
+};
+
+struct gpio_keys_button_data {
+ struct delayed_work work;
+ struct bh_priv bh;
+ int last_state;
+ int count;
+ int threshold;
+ int can_sleep;
+};
+
+extern u64 uevent_next_seqnum(void);
+
+#define BH_MAP(_code, _name) \
+ { \
+ .code = (_code), \
+ .name = (_name), \
+ }
+
+static struct bh_map button_map[] = {
+ BH_MAP(BTN_0, "BTN_0"),
+ BH_MAP(BTN_1, "BTN_1"),
+ BH_MAP(BTN_2, "BTN_2"),
+ BH_MAP(BTN_3, "BTN_3"),
+ BH_MAP(BTN_4, "BTN_4"),
+ BH_MAP(BTN_5, "BTN_5"),
+ BH_MAP(BTN_6, "BTN_6"),
+ BH_MAP(BTN_7, "BTN_7"),
+ BH_MAP(BTN_8, "BTN_8"),
+ BH_MAP(BTN_9, "BTN_9"),
+ BH_MAP(KEY_RESTART, "reset"),
+ BH_MAP(KEY_RFKILL, "rfkill"),
+#ifdef KEY_WPS_BUTTON
+ BH_MAP(KEY_WPS_BUTTON, "wps"),
+#endif /* KEY_WPS_BUTTON */
+};
+
+/* -------------------------------------------------------------------------*/
+
+static int bh_event_add_var(struct bh_event *event, int argv,
+ const char *format, ...)
+{
+ static char buf[128];
+ char *s;
+ va_list args;
+ int len;
+
+ if (argv)
+ return 0;
+
+ va_start(args, format);
+ len = vsnprintf(buf, sizeof(buf), format, args);
+ va_end(args);
+
+ if (len >= sizeof(buf)) {
+ BH_ERR("buffer size too small\n");
+ WARN_ON(1);
+ return -ENOMEM;
+ }
+
+ s = skb_put(event->skb, len + 1);
+ strcpy(s, buf);
+
+ BH_DBG("added variable '%s'\n", s);
+
+ return 0;
+}
+
+static int button_hotplug_fill_event(struct bh_event *event)
+{
+ int ret;
+
+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "PATH=%s",
+ "/sbin:/bin:/usr/sbin:/usr/bin");
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=%s", "button");
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "ACTION=%s", event->action);
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "BUTTON=%s", event->name);
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "SEEN=%ld", event->seen);
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
+
+ return ret;
+}
+
+static void button_hotplug_work(struct work_struct *work)
+{
+ struct bh_event *event = container_of(work, struct bh_event, work);
+ int ret = 0;
+
+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
+ if (!event->skb)
+ goto out_free_event;
+
+ ret = bh_event_add_var(event, 0, "%s@", event->action);
+ if (ret)
+ goto out_free_skb;
+
+ ret = button_hotplug_fill_event(event);
+ if (ret)
+ goto out_free_skb;
+
+ NETLINK_CB(event->skb).dst_group = 1;
+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
+
+ out_free_skb:
+ if (ret) {
+ BH_ERR("work error %d\n", ret);
+ kfree_skb(event->skb);
+ }
+ out_free_event:
+ kfree(event);
+}
+
+static int button_hotplug_create_event(const char *name, unsigned long seen,
+ int pressed)
+{
+ struct bh_event *event;
+
+ BH_DBG("create event, name=%s, seen=%lu, pressed=%d\n",
+ name, seen, pressed);
+
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
+ if (!event)
+ return -ENOMEM;
+
+ event->name = name;
+ event->seen = seen;
+ event->action = pressed ? "pressed" : "released";
+
+ INIT_WORK(&event->work, (void *)(void *)button_hotplug_work);
+ schedule_work(&event->work);
+
+ return 0;
+}
+
+/* -------------------------------------------------------------------------*/
+
+#ifdef CONFIG_HOTPLUG
+static int button_get_index(unsigned int code)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(button_map); i++)
+ if (button_map[i].code == code)
+ return i;
+
+ return -1;
+}
+static void button_hotplug_event(struct gpio_keys_button_data *data,
+ unsigned int type, unsigned int code, int value)
+{
+ struct bh_priv *priv = &data->bh;
+ unsigned long seen = jiffies;
+ int btn;
+
+ BH_DBG("event type=%u, code=%u, value=%d\n", type, code, value);
+
+ if (type != EV_KEY)
+ return;
+
+ btn = button_get_index(code);
+ if (btn < 0)
+ return;
+
+ button_hotplug_create_event(button_map[btn].name,
+ (seen - priv->seen) / HZ, value);
+ priv->seen = seen;
+}
+#else
+static void button_hotplug_event(struct gpio_keys_button_data *data,
+ unsigned int type, unsigned int code, int value)
+{
+}
+#endif /* CONFIG_HOTPLUG */
+
+struct gpio_keys_polled_dev {
+ struct delayed_work work;
+
+ struct device *dev;
+ struct gpio_keys_platform_data *pdata;
+ struct gpio_keys_button_data data[0];
+};
+
+static void gpio_keys_polled_check_state(struct gpio_keys_button *button,
+ struct gpio_keys_button_data *bdata)
+{
+ int state;
+
+ if (bdata->can_sleep)
+ state = !!gpio_get_value_cansleep(button->gpio);
+ else
+ state = !!gpio_get_value(button->gpio);
+
+ state = !!(state ^ button->active_low);
+ if (state != bdata->last_state) {
+ unsigned int type = button->type ?: EV_KEY;
+
+ button_hotplug_event(bdata, type, button->code, state);
+ bdata->count = 0;
+ bdata->last_state = state;
+ }
+}
+
+static void gpio_keys_polled_queue_work(struct gpio_keys_polled_dev *bdev)
+{
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
+ unsigned long delay = msecs_to_jiffies(pdata->poll_interval);
+
+ if (delay >= HZ)
+ delay = round_jiffies_relative(delay);
+ schedule_delayed_work(&bdev->work, delay);
+}
+
+static void gpio_keys_polled_poll(struct work_struct *work)
+{
+ struct gpio_keys_polled_dev *bdev =
+ container_of(work, struct gpio_keys_polled_dev, work.work);
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
+ int i;
+
+ for (i = 0; i < bdev->pdata->nbuttons; i++) {
+ struct gpio_keys_button_data *bdata = &bdev->data[i];
+
+ if (bdata->count < bdata->threshold)
+ bdata->count++;
+ else
+ gpio_keys_polled_check_state(&pdata->buttons[i], bdata);
+ }
+ gpio_keys_polled_queue_work(bdev);
+}
+
+static void gpio_keys_polled_open(struct gpio_keys_polled_dev *bdev)
+{
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
+ int i;
+
+ if (pdata->enable)
+ pdata->enable(bdev->dev);
+
+ /* report initial state of the buttons */
+ for (i = 0; i < pdata->nbuttons; i++)
+ gpio_keys_polled_check_state(&pdata->buttons[i], &bdev->data[i]);
+
+ gpio_keys_polled_queue_work(bdev);
+}
+
+#ifdef CONFIG_OF
+static struct gpio_keys_platform_data *
+gpio_keys_polled_get_devtree_pdata(struct device *dev)
+{
+ struct device_node *node, *pp;
+ struct gpio_keys_platform_data *pdata;
+ struct gpio_keys_button *button;
+ int error;
+ int nbuttons;
+ int i;
+
+ node = dev->of_node;
+ if (!node)
+ return NULL;
+
+ nbuttons = of_get_child_count(node);
+ if (nbuttons == 0)
+ return NULL;
+
+ pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button),
+ GFP_KERNEL);
+ if (!pdata) {
+ error = -ENOMEM;
+ goto err_out;
+ }
+
+ pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
+ pdata->nbuttons = nbuttons;
+
+ pdata->rep = !!of_get_property(node, "autorepeat", NULL);
+ of_property_read_u32(node, "poll-interval", &pdata->poll_interval);
+
+ i = 0;
+ for_each_child_of_node(node, pp) {
+ enum of_gpio_flags flags;
+
+ if (!of_find_property(pp, "gpios", NULL)) {
+ pdata->nbuttons--;
+ dev_warn(dev, "Found button without gpios\n");
+ continue;
+ }
+
+ button = &pdata->buttons[i++];
+
+ button->gpio = of_get_gpio_flags(pp, 0, &flags);
+ button->active_low = flags & OF_GPIO_ACTIVE_LOW;
+
+ if (of_property_read_u32(pp, "linux,code", &button->code)) {
+ dev_err(dev, "Button without keycode: 0x%x\n",
+ button->gpio);
+ error = -EINVAL;
+ goto err_free_pdata;
+ }
+
+ button->desc = of_get_property(pp, "label", NULL);
+
+ if (of_property_read_u32(pp, "linux,input-type", &button->type))
+ button->type = EV_KEY;
+
+ button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
+
+ if (of_property_read_u32(pp, "debounce-interval",
+ &button->debounce_interval))
+ button->debounce_interval = 5;
+ }
+
+ if (pdata->nbuttons == 0) {
+ error = -EINVAL;
+ goto err_free_pdata;
+ }
+
+ return pdata;
+
+err_free_pdata:
+ kfree(pdata);
+err_out:
+ return ERR_PTR(error);
+}
+
+static struct of_device_id gpio_keys_polled_of_match[] = {
+ { .compatible = "gpio-keys-polled", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
+
+#else
+
+static inline struct gpio_keys_platform_data *
+gpio_keys_polled_get_devtree_pdata(struct device *dev)
+{
+ return NULL;
+}
+#endif
+
+static void gpio_keys_polled_close(struct gpio_keys_polled_dev *bdev)
+{
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
+
+ cancel_delayed_work_sync(&bdev->work);
+
+ if (pdata->disable)
+ pdata->disable(bdev->dev);
+}
+
+static int gpio_keys_polled_probe(struct platform_device *pdev)
+{
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+ struct device *dev = &pdev->dev;
+ struct gpio_keys_polled_dev *bdev;
+ int error;
+ int i;
+
+ if (!pdata) {
+ pdata = gpio_keys_polled_get_devtree_pdata(dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ if (!pdata) {
+ dev_err(dev, "missing platform data\n");
+ return -EINVAL;
+ }
+ }
+
+ if (!pdata->poll_interval) {
+ dev_err(dev, "missing poll_interval value\n");
+ error = -EINVAL;
+ goto err_free_pdata;
+ }
+
+ bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) +
+ pdata->nbuttons * sizeof(struct gpio_keys_button_data),
+ GFP_KERNEL);
+ if (!bdev) {
+ dev_err(dev, "no memory for private data\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < pdata->nbuttons; i++) {
+ struct gpio_keys_button *button = &pdata->buttons[i];
+ struct gpio_keys_button_data *bdata = &bdev->data[i];
+ unsigned int gpio = button->gpio;
+
+ if (button->wakeup) {
+ dev_err(dev, DRV_NAME " does not support wakeup\n");
+ error = -EINVAL;
+ goto err_free_gpio;
+ }
+
+ error = gpio_request(gpio,
+ button->desc ? button->desc : DRV_NAME);
+ if (error) {
+ dev_err(dev, "unable to claim gpio %u, err=%d\n",
+ gpio, error);
+ goto err_free_gpio;
+ }
+
+ error = gpio_direction_input(gpio);
+ if (error) {
+ dev_err(dev,
+ "unable to set direction on gpio %u, err=%d\n",
+ gpio, error);
+ goto err_free_gpio;
+ }
+
+ bdata->can_sleep = gpio_cansleep(gpio);
+ bdata->last_state = 0;
+ bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
+ pdata->poll_interval);
+ }
+
+ bdev->dev = &pdev->dev;
+ bdev->pdata = pdata;
+ platform_set_drvdata(pdev, bdev);
+
+ INIT_DELAYED_WORK(&bdev->work, gpio_keys_polled_poll);
+
+ gpio_keys_polled_open(bdev);
+
+ return 0;
+
+err_free_gpio:
+ while (--i >= 0)
+ gpio_free(pdata->buttons[i].gpio);
+
+ kfree(bdev);
+ platform_set_drvdata(pdev, NULL);
+
+err_free_pdata:
+ /* If we have no platform_data, we allocated pdata dynamically. */
+ if (!dev_get_platdata(&pdev->dev))
+ kfree(pdata);
+
+ return error;
+}
+
+static int gpio_keys_polled_remove(struct platform_device *pdev)
+{
+ struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev);
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
+ int i = pdata->nbuttons;
+
+ gpio_keys_polled_close(bdev);
+
+ while (--i >= 0)
+ gpio_free(pdata->buttons[i].gpio);
+
+ kfree(bdev);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver gpio_keys_polled_driver = {
+ .probe = gpio_keys_polled_probe,
+ .remove = gpio_keys_polled_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(gpio_keys_polled_of_match),
+ },
+};
+
+static int __init gpio_keys_polled_init(void)
+{
+ return platform_driver_register(&gpio_keys_polled_driver);
+}
+
+static void __exit gpio_keys_polled_exit(void)
+{
+ platform_driver_unregister(&gpio_keys_polled_driver);
+}
+
+module_init(gpio_keys_polled_init);
+module_exit(gpio_keys_polled_exit);
+
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>");
+MODULE_DESCRIPTION("Polled GPIO Buttons hotplug driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/package/kernel/hostap-driver/Makefile b/package/kernel/hostap-driver/Makefile
new file mode 100644
index 0000000000..d08fd9c0a5
--- /dev/null
+++ b/package/kernel/hostap-driver/Makefile
@@ -0,0 +1,117 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=hostap-driver
+PKG_VERSION:=0.4.9
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://hostap.epitest.fi/releases/
+PKG_MD5SUM:=c7534dc040ab90218257a78488ecd378
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/hostap/Default
+ VERSION:=$(LINUX_VERSION)-$(BOARD)-$(PKG_RELEASE)
+ SUBMENU:=Wireless Drivers
+ URL:=http://hostap.epitest.fi/
+endef
+
+define KernelPackage/hostap/Default/description
+ Host AP is a driver for 802.11b wireless cards based on Intersil
+ Prism2/2.5/3 chipset. It supports so called Host AP mode that allows the
+ card to act as an IEEE 802.11 access point.
+endef
+
+
+define KernelPackage/hostap
+$(call KernelPackage/hostap/Default)
+ TITLE:=Host AP support for Prism2/2.5/3
+ DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +kmod-lib80211 +wireless-tools
+ KCONFIG:=CONFIG_HOSTAP CONFIG_HOSTAP_FIRMWARE=y CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+ FILES:=$(LINUX_DIR)/drivers/net/wireless/hostap/hostap.ko
+ AUTOLOAD:=$(call AutoLoad,60,hostap)
+endef
+
+define KernelPackage/hostap/description
+$(call KernelPackage/hostap/Default/description)
+ This package contains the base Host AP driver code that is shared by
+ different hardware models. You will also need to enable support for
+ PLX/PCI/CS version of the driver to actually use the driver.
+endef
+
+
+define KernelPackage/hostap-cs
+$(call KernelPackage/hostap/Default)
+ TITLE:=Host AP driver for PCMCIA adaptors
+ DEPENDS:=@PCMCIA_SUPPORT +kmod-hostap +kmod-pcmcia-core
+ KCONFIG:=CONFIG_HOSTAP_CS
+ FILES:=$(LINUX_DIR)/drivers/net/wireless/hostap/hostap_cs.ko
+ AUTOLOAD:=$(call AutoLoad,60,hostap_cs)
+endef
+
+define KernelPackage/hostap-cs/description
+$(call KernelPackage/hostap/Default/description)
+ This package contains the Host AP driver for Prism2/2.5/3 PC cards.
+endef
+
+
+define KernelPackage/hostap-pci
+$(call KernelPackage/hostap/Default)
+ TITLE:=Host AP driver for PCI adaptors
+ DEPENDS:=@PCI_SUPPORT +kmod-hostap
+ KCONFIG:=CONFIG_HOSTAP_PCI
+ FILES:=$(LINUX_DIR)/drivers/net/wireless/hostap/hostap_pci.ko
+ AUTOLOAD:=$(call AutoLoad,60,hostap_pci)
+endef
+
+define KernelPackage/hostap-pci/description
+$(call KernelPackage/hostap/Default/description)
+ This package contains the Host AP driver for Prism2.5 PCI adaptors.
+endef
+
+
+define KernelPackage/hostap-plx
+$(call KernelPackage/hostap/Default)
+ TITLE:=Host AP driver for PLX9052 based PCI adaptors
+ DEPENDS:=@PCI_SUPPORT +kmod-hostap
+ KCONFIG:=CONFIG_HOSTAP_PLX
+ FILES:=$(LINUX_DIR)/drivers/net/wireless/hostap/hostap_plx.ko
+ AUTOLOAD:=$(call AutoLoad,60,hostap_plx)
+endef
+
+define KernelPackage/hostap-plx/description
+$(call KernelPackage/hostap/Default/description)
+ This package contains the Host AP driver for Prism2/2.5/3 in PLX9052
+ based PCI adaptors.
+endef
+
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+
+endef
+
+define Build/Compile
+
+endef
+
+define KernelPackage/hostap/install
+ $(INSTALL_DIR) $(1)/lib/wifi
+ $(INSTALL_DATA) ./files/lib/wifi/hostap.sh $(1)/lib/wifi
+endef
+
+$(eval $(call KernelPackage,hostap))
+$(eval $(call KernelPackage,hostap-cs))
+$(eval $(call KernelPackage,hostap-pci))
+$(eval $(call KernelPackage,hostap-plx))
diff --git a/package/kernel/hostap-driver/files/lib/wifi/hostap.sh b/package/kernel/hostap-driver/files/lib/wifi/hostap.sh
new file mode 100755
index 0000000000..62d2e7e472
--- /dev/null
+++ b/package/kernel/hostap-driver/files/lib/wifi/hostap.sh
@@ -0,0 +1,270 @@
+#!/bin/sh
+append DRIVERS "prism2"
+
+find_prism2_phy() {
+ local device="$1"
+
+ local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
+ config_get phy "$device" phy
+ [ -z "$phy" -a -n "$macaddr" ] && {
+ cd /proc/net/hostap
+ for phy in $(ls -d wlan* 2>&-); do
+ [ "$macaddr" = "$(cat /sys/class/net/${phy}/address)" ] || continue
+ config_set "$device" phy "$phy"
+ break
+ done
+ config_get phy "$device" phy
+ }
+ [ -n "$phy" -a -d "/proc/net/hostap/$phy" ] || {
+ echo "phy for wifi device $1 not found"
+ return 1
+ }
+ [ -z "$macaddr" ] && {
+ config_set "$device" macaddr "$(cat /sys/class/net/${phy}/address)"
+ }
+ return 0
+}
+
+scan_prism2() {
+ local device="$1"
+ local mainvif
+ local wds
+
+ [ ${device%[0-9]} = "wlan" ] && config_set "$device" phy "$device" || find_prism2_phy "$device" || {
+ config_unset "$device" vifs
+ return 0
+ }
+ config_get phy "$device" phy
+
+ config_get vifs "$device" vifs
+ local _c=0
+ for vif in $vifs; do
+ config_get_bool disabled "$vif" disabled 0
+ [ $disabled = 0 ] || continue
+
+ config_get mode "$vif" mode
+ case "$mode" in
+ adhoc|sta|ap|monitor)
+ # Only one vif is allowed on AP, station, Ad-hoc or monitor mode
+ [ -z "$mainvif" ] && {
+ mainvif="$vif"
+ config_set "$vif" ifname "$phy"
+ }
+ ;;
+ wds)
+ config_get ssid "$vif" ssid
+ [ -z "$ssid" ] && continue
+ config_set "$vif" ifname "${phy}wds${_c}"
+ _c=$(($_c + 1))
+ addr="$ssid"
+ ${addr:+append wds "$vif"}
+ ;;
+ *) echo "$device($vif): Invalid mode, ignored."; continue;;
+ esac
+ done
+ config_set "$device" vifs "${mainvif:+$mainvif }${wds:+$wds}"
+}
+
+disable_prism2() (
+ local device="$1"
+
+ find_prism2_phy "$device" || return 0
+ config_get phy "$device" phy
+
+ set_wifi_down "$device"
+
+ include /lib/network
+ while read line < /proc/net/hostap/${phy}/wds; do
+ set $line
+ [ -f "/var/run/wifi-${1}.pid" ] &&
+ kill "$(cat "/var/run/wifi-${1}.pid")"
+ ifconfig "$1" down
+ unbridge "$1"
+ iwpriv "$phy" wds_del "$2"
+ done
+ unbridge "$phy"
+ return 0
+)
+
+enable_prism2() {
+ local device="$1"
+
+ find_prism2_phy "$device" || return 0
+ config_get phy "$device" phy
+
+ config_get rxantenna "$device" rxantenna
+ config_get txantenna "$device" txantenna
+ config_get_bool diversity "$device" diversity
+ [ -n "$diversity" ] && {
+ rxantenna="1"
+ txantenna="1"
+ }
+ [ -n "$rxantenna" ] && iwpriv "$phy" antsel_rx "$rxantenna"
+ [ -n "$txantenna" ] && iwpriv "$phy" antsel_tx "$txantenna"
+
+ config_get channel "$device" channel
+ [ -n "$channel" ] && iwconfig "$phy" channel "$channel" >/dev/null 2>/dev/null
+
+ config_get txpower "$device" txpower
+ [ -n "$txpower" ] && iwconfig "$phy" txpower "${txpower%%.*}"
+
+ config_get vifs "$device" vifs
+ local first=1
+ for vif in $vifs; do
+ config_get ifname "$vif" ifname
+ config_get ssid "$vif" ssid
+ config_get mode "$vif" mode
+
+ [ "$mode" = "wds" ] || iwconfig "$phy" essid ${ssid:+-- }"${ssid:-any}"
+
+ case "$mode" in
+ sta)
+ iwconfig "$phy" mode managed
+ config_get addr "$device" bssid
+ [ -z "$addr" ] || {
+ iwconfig "$phy" ap "$addr"
+ }
+ ;;
+ ap) iwconfig "$phy" mode master;;
+ wds) iwpriv "$phy" wds_add "$ssid";;
+ adhoc) iwconfig "$phy" mode ad-hoc;;
+ *) iwconfig "$phy" mode "$mode";;
+ esac
+
+ [ "$first" = 1 ] && {
+ config_get rate "$vif" rate
+ [ -n "$rate" ] && iwconfig "$phy" rate "${rate%%.*}"
+
+ config_get_bool hidden "$vif" hidden 0
+ iwpriv "$phy" enh_sec "$hidden"
+
+ config_get frag "$vif" frag
+ [ -n "$frag" ] && iwconfig "$phy" frag "${frag%%.*}"
+
+ config_get rts "$vif" rts
+ [ -n "$rts" ] && iwconfig "$phy" rts "${rts%%.*}"
+
+ config_get maclist "$vif" maclist
+ [ -n "$maclist" ] && {
+ # flush MAC list
+ iwpriv "$phy" maccmd 3
+ for mac in $maclist; do
+ iwpriv "$phy" addmac "$mac"
+ done
+ }
+ config_get macpolicy "$vif" macpolicy
+ case "$macpolicy" in
+ allow)
+ iwpriv "$phy" maccmd 2
+ ;;
+ deny)
+ iwpriv "$phy" maccmd 1
+ ;;
+ *)
+ # default deny policy if mac list exists
+ [ -n "$maclist" ] && iwpriv "$phy" maccmd 1
+ ;;
+ esac
+ # kick all stations if we have policy explicitly set
+ [ -n "$macpolicy" ] && iwpriv "$phy" maccmd 4
+ }
+
+ config_get enc "$vif" encryption
+ case "$enc" in
+ WEP|wep)
+ for idx in 1 2 3 4; do
+ config_get key "$vif" "key${idx}"
+ iwconfig "$ifname" enc "[$idx]" "${key:-off}"
+ done
+ config_get key "$vif" key
+ key="${key:-1}"
+ case "$key" in
+ [1234]) iwconfig "$ifname" enc "[$key]";;
+ *) iwconfig "$ifname" enc "$key";;
+ esac
+ ;;
+ psk*|wpa*)
+ start_hostapd=1
+ config_get key "$vif" key
+ ;;
+ esac
+
+ local net_cfg bridge
+ net_cfg="$(find_net_config "$vif")"
+ [ -z "$net_cfg" ] || {
+ bridge="$(bridge_interface "$net_cfg")"
+ config_set "$vif" bridge "$bridge"
+ start_net "$ifname" "$net_cfg"
+ }
+ set_wifi_up "$vif" "$ifname"
+
+ case "$mode" in
+ ap)
+ if [ -n "$start_hostapd" ] && eval "type hostapd_setup_vif" 2>/dev/null >/dev/null; then
+ hostapd_setup_vif "$vif" hostap || {
+ echo "enable_prism2($device): Failed to set up hostapd for interface $ifname" >&2
+ # make sure this wifi interface won't accidentally stay open without encryption
+ ifconfig "$ifname" down
+ continue
+ }
+ fi
+ ;;
+ wds|sta)
+ if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
+ wpa_supplicant_setup_vif "$vif" wext || {
+ echo "enable_prism2($device): Failed to set up wpa_supplicant for interface $ifname" >&2
+ ifconfig "$ifname" down
+ continue
+ }
+ fi
+ ;;
+ esac
+ first=0
+ done
+
+}
+
+check_prism2_device() {
+ [ ${1%[0-9]} = "wlan" ] && config_set "$1" phy "$1"
+ config_get phy "$1" phy
+ [ -z "$phy" ] && {
+ find_prism2_phy "$1" >/dev/null || return 0
+ config_get phy "$1" phy
+ }
+ [ "$phy" = "$dev" ] && found=1
+}
+
+detect_prism2() {
+ devidx=0
+ config_load wireless
+ while :; do
+ config_get type "radio$devidx" type
+ [ -n "$type" ] || break
+ devidx=$(($devidx + 1))
+ done
+ cd /proc/net/hostap
+ [ -d wlan* ] || return
+ for dev in $(ls -d wlan* 2>&-); do
+ found=0
+ config_foreach check_prism2_device wifi-device
+ [ "$found" -gt 0 ] && continue
+ cat <<EOF
+config wifi-device radio$devidx
+ option type prism2
+ option channel 11
+ option macaddr $(cat /sys/class/net/${dev}/address)
+
+ # REMOVE THIS LINE TO ENABLE WIFI:
+ option disabled 1
+
+config wifi-iface
+ option device radio$devidx
+ option network lan
+ option mode ap
+ option ssid OpenWrt
+ option encryption none
+
+EOF
+ devidx=$(($devidx + 1))
+ done
+}
diff --git a/package/kernel/hostap-driver/patches/001-fix-txpower.patch b/package/kernel/hostap-driver/patches/001-fix-txpower.patch
new file mode 100644
index 0000000000..94ca344943
--- /dev/null
+++ b/package/kernel/hostap-driver/patches/001-fix-txpower.patch
@@ -0,0 +1,175 @@
+diff -Naur hostap-driver-0.3.7/driver/modules/hostap.c hostap-driver-0.3.7-patched/driver/modules/hostap.c
+--- hostap-driver-0.3.7/driver/modules/hostap.c 2004-08-28 06:26:46.000000000 +0300
++++ hostap-driver-0.3.7-patched/driver/modules/hostap.c 2005-04-20 17:20:56.000000000 +0300
+@@ -1164,6 +1164,36 @@
+ return ret;
+ }
+
++/* BUG FIX: Restore power setting value when lost due to F/W bug */
++
++int hostap_restore_power(struct net_device *dev)
++{
++ struct hostap_interface *iface = dev->priv;
++ local_info_t *local = iface->local;
++
++ u16 val;
++ int ret = 0;
++
++ if (local->txpower_type == PRISM2_TXPOWER_OFF) {
++ val = 0xff; /* use all standby and sleep modes */
++ ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
++ HFA386X_CR_A_D_TEST_MODES2,
++ &val, NULL);
++ }
++
++#ifdef RAW_TXPOWER_SETTING
++ if (local->txpower_type == PRISM2_TXPOWER_FIXED) {
++ val = HFA384X_TEST_CFG_BIT_ALC;
++ local->func->cmd(dev, HFA384X_CMDCODE_TEST |
++ (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL);
++ val = prism2_txpower_dBm_to_hfa386x(local->txpower);
++ ret = (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
++ HFA386X_CR_MANUAL_TX_POWER, &val, NULL));
++ }
++#endif /* RAW_TXPOWER_SETTING */
++ return (ret ? -EOPNOTSUPP : 0);
++}
++
+
+ struct proc_dir_entry *hostap_proc;
+
+@@ -1214,6 +1244,7 @@
+ EXPORT_SYMBOL(hostap_set_hostapd_sta);
+ EXPORT_SYMBOL(hostap_add_interface);
+ EXPORT_SYMBOL(hostap_remove_interface);
++EXPORT_SYMBOL(hostap_restore_power);
+ EXPORT_SYMBOL(prism2_update_comms_qual);
+
+ module_init(hostap_init);
+diff -Naur hostap-driver-0.3.7/driver/modules/hostap.h hostap-driver-0.3.7-patched/driver/modules/hostap.h
+--- hostap-driver-0.3.7/driver/modules/hostap.h 2003-11-30 04:14:26.000000000 +0200
++++ hostap-driver-0.3.7-patched/driver/modules/hostap.h 2005-04-20 17:21:23.000000000 +0300
+@@ -36,6 +36,7 @@
+ const char *prefix, const char *name);
+ void hostap_remove_interface(struct net_device *dev, int rtnl_locked,
+ int remove_from_list);
++int hostap_restore_power(struct net_device *dev);
+ int prism2_update_comms_qual(struct net_device *dev);
+ int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u8 stype,
+ u8 *body, size_t bodylen);
+diff -Naur hostap-driver-0.3.7/driver/modules/hostap_ap.c hostap-driver-0.3.7-patched/driver/modules/hostap_ap.c
+--- hostap-driver-0.3.7/driver/modules/hostap_ap.c 2005-01-24 04:52:00.000000000 +0200
++++ hostap-driver-0.3.7-patched/driver/modules/hostap_ap.c 2005-04-21 20:06:12.000000000 +0300
+@@ -2346,13 +2346,13 @@
+ addr[count].sa_family = ARPHRD_ETHER;
+ memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
+ if (sta->last_rx_silence == 0)
+- qual[count].qual = sta->last_rx_signal < 27 ?
+- 0 : (sta->last_rx_signal - 27) * 92 / 127;
++ qual[count].qual = (sta->last_rx_signal - 156) == 0 ?
++ 0 : (sta->last_rx_signal - 156) * 92 / 64;
+ else
+- qual[count].qual = sta->last_rx_signal -
+- sta->last_rx_silence - 35;
+- qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
+- qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
++ qual[count].qual = (sta->last_rx_signal -
++ sta->last_rx_silence) * 92 / 64;
++ qual[count].level = sta->last_rx_signal;
++ qual[count].noise = sta->last_rx_silence;
+ qual[count].updated = sta->last_rx_updated;
+
+ sta->last_rx_updated = 0;
+@@ -2413,13 +2413,13 @@
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVQUAL;
+ if (sta->last_rx_silence == 0)
+- iwe.u.qual.qual = sta->last_rx_signal < 27 ?
+- 0 : (sta->last_rx_signal - 27) * 92 / 127;
++ iwe.u.qual.qual = (sta->last_rx_signal -156) == 0 ?
++ 0 : (sta->last_rx_signal - 156) * 92 / 64;
+ else
+- iwe.u.qual.qual = sta->last_rx_signal -
+- sta->last_rx_silence - 35;
+- iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
+- iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
++ iwe.u.qual.qual = (sta->last_rx_signal -
++ sta->last_rx_silence) * 92 / 64;
++ iwe.u.qual.level = sta->last_rx_signal;
++ iwe.u.qual.noise = sta->last_rx_silence;
+ iwe.u.qual.updated = sta->last_rx_updated;
+ iwe.len = IW_EV_QUAL_LEN;
+ current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+diff -Naur hostap-driver-0.3.7/driver/modules/hostap_config.h hostap-driver-0.3.7-patched/driver/modules/hostap_config.h
+--- hostap-driver-0.3.7/driver/modules/hostap_config.h 2005-02-12 18:12:56.000000000 +0200
++++ hostap-driver-0.3.7-patched/driver/modules/hostap_config.h 2005-04-20 17:25:23.000000000 +0300
+@@ -94,6 +94,12 @@
+ */
+ /* #define PRISM2_NO_STATION_MODES */
+
++/* Enable TX power Setting functions
++ * (min att = -128 , max att = 127)
++ */
++
++#define RAW_TXPOWER_SETTING
++
+ /* Use Linux crypto API instead of own encryption implementation whenever
+ * possible. */
+ /* #define HOSTAP_USE_CRYPTO_API */
+diff -Naur hostap-driver-0.3.7/driver/modules/hostap_hw.c hostap-driver-0.3.7-patched/driver/modules/hostap_hw.c
+--- hostap-driver-0.3.7/driver/modules/hostap_hw.c 2005-02-05 09:20:09.000000000 +0200
++++ hostap-driver-0.3.7-patched/driver/modules/hostap_hw.c 2005-04-20 17:25:55.000000000 +0300
+@@ -1039,6 +1039,7 @@
+ dev->name, local->fragm_threshold);
+ }
+
++ hostap_restore_power(dev);
+ return res;
+ }
+
+diff -Naur hostap-driver-0.3.7/driver/modules/hostap_info.c hostap-driver-0.3.7-patched/driver/modules/hostap_info.c
+--- hostap-driver-0.3.7/driver/modules/hostap_info.c 2004-02-29 20:05:44.000000000 +0200
++++ hostap-driver-0.3.7-patched/driver/modules/hostap_info.c 2005-04-20 17:26:36.000000000 +0300
+@@ -418,6 +418,11 @@
+ }
+
+ /* Get BSSID if we have a valid AP address */
++
++ if ( val == HFA384X_LINKSTATUS_CONNECTED ||
++ val == HFA384X_LINKSTATUS_DISCONNECTED )
++ hostap_restore_power(local->dev);
++
+ if (connected) {
+ netif_carrier_on(local->dev);
+ netif_carrier_on(local->ddev);
+diff -Naur hostap-driver-0.3.7/driver/modules/hostap_ioctl.c hostap-driver-0.3.7-patched/driver/modules/hostap_ioctl.c
+--- hostap-driver-0.3.7/driver/modules/hostap_ioctl.c 2004-11-22 08:03:05.000000000 +0200
++++ hostap-driver-0.3.7-patched/driver/modules/hostap_ioctl.c 2005-04-20 17:42:41.000000000 +0300
+@@ -1453,23 +1453,20 @@
+ val = 255;
+
+ tmp = val;
+- tmp >>= 2;
+
+- return -12 - tmp;
++ return tmp;
+ }
+
+ static u16 prism2_txpower_dBm_to_hfa386x(int val)
+ {
+ signed char tmp;
+
+- if (val > 20)
+- return 128;
+- else if (val < -43)
++ if (val > 127)
+ return 127;
++ else if (val < -128)
++ return 128;
+
+ tmp = val;
+- tmp = -12 - tmp;
+- tmp <<= 2;
+
+ return (unsigned char) tmp;
+ }
diff --git a/package/kernel/i2c-gpio-custom/Makefile b/package/kernel/i2c-gpio-custom/Makefile
new file mode 100644
index 0000000000..8585a5ab57
--- /dev/null
+++ b/package/kernel/i2c-gpio-custom/Makefile
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=i2c-gpio-custom
+PKG_RELEASE:=2
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/i2c-gpio-custom
+ SUBMENU:=I2C support
+ TITLE:=Custom GPIO-based I2C device
+ DEPENDS:=@GPIO_SUPPORT +kmod-i2c-core +kmod-i2c-gpio
+ FILES:=$(PKG_BUILD_DIR)/i2c-gpio-custom.ko
+ KCONFIG:=
+endef
+
+define KernelPackage/i2c-gpio-custom/description
+ Kernel module for register a custom i2c-gpio platform device.
+endef
+
+EXTRA_KCONFIG:= \
+ CONFIG_I2C_GPIO_CUSTOM=m
+
+EXTRA_CFLAGS:= \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \
+
+MAKE_OPTS:= \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
+ $(EXTRA_KCONFIG)
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ $(MAKE_OPTS) \
+ modules
+endef
+
+$(eval $(call KernelPackage,i2c-gpio-custom))
diff --git a/package/kernel/i2c-gpio-custom/src/Kconfig b/package/kernel/i2c-gpio-custom/src/Kconfig
new file mode 100644
index 0000000000..e2e3a68d92
--- /dev/null
+++ b/package/kernel/i2c-gpio-custom/src/Kconfig
@@ -0,0 +1,10 @@
+config I2C_GPIO_CUSTOM
+ tristate "Custom GPIO-based I2C driver"
+ depends on GENERIC_GPIO
+ select I2C_GPIO
+ help
+ This is an I2C driver to register 1 to 4 custom I2C buses using
+ GPIO lines.
+
+ This support is also available as a module. If so, the module
+ will be called i2c-gpio-custom.
diff --git a/package/kernel/i2c-gpio-custom/src/Makefile b/package/kernel/i2c-gpio-custom/src/Makefile
new file mode 100644
index 0000000000..dcb2e2abe2
--- /dev/null
+++ b/package/kernel/i2c-gpio-custom/src/Makefile
@@ -0,0 +1 @@
+obj-${CONFIG_I2C_GPIO_CUSTOM} += i2c-gpio-custom.o \ No newline at end of file
diff --git a/package/kernel/i2c-gpio-custom/src/i2c-gpio-custom.c b/package/kernel/i2c-gpio-custom/src/i2c-gpio-custom.c
new file mode 100644
index 0000000000..76ab5f39cc
--- /dev/null
+++ b/package/kernel/i2c-gpio-custom/src/i2c-gpio-custom.c
@@ -0,0 +1,198 @@
+/*
+ * Custom GPIO-based I2C driver
+ *
+ * Copyright (C) 2007-2008 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * The behaviour of this driver can be altered by setting some parameters
+ * from the insmod command line.
+ *
+ * The following parameters are adjustable:
+ *
+ * bus0 These four arguments can be arrays of
+ * bus1 1-8 unsigned integers as follows:
+ * bus2
+ * bus3 <id>,<sda>,<scl>,<udelay>,<timeout>,<sda_od>,<scl_od>,<scl_oo>
+ *
+ * where:
+ *
+ * <id> ID to used as device_id for the corresponding bus (required)
+ * <sda> GPIO pin ID to used for SDA (required)
+ * <scl> GPIO pin ID to used for SCL (required)
+ * <udelay> signal toggle delay.
+ * <timeout> clock stretching timeout.
+ * <sda_od> SDA is configured as open drain.
+ * <scl_od> SCL is configured as open drain.
+ * <scl_oo> SCL output drivers cannot be turned off.
+ *
+ * See include/i2c-gpio.h for more information about the parameters.
+ *
+ * If this driver is built into the kernel, you can use the following kernel
+ * command line parameters, with the same values as the corresponding module
+ * parameters listed above:
+ *
+ * i2c-gpio-custom.bus0
+ * i2c-gpio-custom.bus1
+ * i2c-gpio-custom.bus2
+ * i2c-gpio-custom.bus3
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/i2c-gpio.h>
+
+#define DRV_NAME "i2c-gpio-custom"
+#define DRV_DESC "Custom GPIO-based I2C driver"
+#define DRV_VERSION "0.1.1"
+
+#define PFX DRV_NAME ": "
+
+#define BUS_PARAM_ID 0
+#define BUS_PARAM_SDA 1
+#define BUS_PARAM_SCL 2
+#define BUS_PARAM_UDELAY 3
+#define BUS_PARAM_TIMEOUT 4
+#define BUS_PARAM_SDA_OD 5
+#define BUS_PARAM_SCL_OD 6
+#define BUS_PARAM_SCL_OO 7
+
+#define BUS_PARAM_REQUIRED 3
+#define BUS_PARAM_COUNT 8
+#define BUS_COUNT_MAX 4
+
+static unsigned int bus0[BUS_PARAM_COUNT] __initdata;
+static unsigned int bus1[BUS_PARAM_COUNT] __initdata;
+static unsigned int bus2[BUS_PARAM_COUNT] __initdata;
+static unsigned int bus3[BUS_PARAM_COUNT] __initdata;
+
+static unsigned int bus_nump[BUS_COUNT_MAX] __initdata;
+
+#define BUS_PARM_DESC \
+ " config -> id,sda,scl[,udelay,timeout,sda_od,scl_od,scl_oo]"
+
+module_param_array(bus0, uint, &bus_nump[0], 0);
+MODULE_PARM_DESC(bus0, "bus0" BUS_PARM_DESC);
+module_param_array(bus1, uint, &bus_nump[1], 0);
+MODULE_PARM_DESC(bus1, "bus1" BUS_PARM_DESC);
+module_param_array(bus2, uint, &bus_nump[2], 0);
+MODULE_PARM_DESC(bus2, "bus2" BUS_PARM_DESC);
+module_param_array(bus3, uint, &bus_nump[3], 0);
+MODULE_PARM_DESC(bus3, "bus3" BUS_PARM_DESC);
+
+static struct platform_device *devices[BUS_COUNT_MAX];
+static unsigned int nr_devices;
+
+static void i2c_gpio_custom_cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < nr_devices; i++)
+ if (devices[i])
+ platform_device_put(devices[i]);
+}
+
+static int __init i2c_gpio_custom_add_one(unsigned int id, unsigned int *params)
+{
+ struct platform_device *pdev;
+ struct i2c_gpio_platform_data pdata;
+ int err;
+
+ if (!bus_nump[id])
+ return 0;
+
+ if (bus_nump[id] < BUS_PARAM_REQUIRED) {
+ printk(KERN_ERR PFX "not enough parameters for bus%d\n", id);
+ err = -EINVAL;
+ goto err;
+ }
+
+ pdev = platform_device_alloc("i2c-gpio", params[BUS_PARAM_ID]);
+ if (!pdev) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ pdata.sda_pin = params[BUS_PARAM_SDA];
+ pdata.scl_pin = params[BUS_PARAM_SCL];
+ pdata.udelay = params[BUS_PARAM_UDELAY];
+ pdata.timeout = params[BUS_PARAM_TIMEOUT];
+ pdata.sda_is_open_drain = params[BUS_PARAM_SDA_OD] != 0;
+ pdata.scl_is_open_drain = params[BUS_PARAM_SCL_OD] != 0;
+ pdata.scl_is_output_only = params[BUS_PARAM_SCL_OO] != 0;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto err_put;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_put;
+
+ devices[nr_devices++] = pdev;
+ return 0;
+
+err_put:
+ platform_device_put(pdev);
+err:
+ return err;
+}
+
+static int __init i2c_gpio_custom_probe(void)
+{
+ int err;
+
+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
+
+ err = i2c_gpio_custom_add_one(0, bus0);
+ if (err) goto err;
+
+ err = i2c_gpio_custom_add_one(1, bus1);
+ if (err) goto err;
+
+ err = i2c_gpio_custom_add_one(2, bus2);
+ if (err) goto err;
+
+ err = i2c_gpio_custom_add_one(3, bus3);
+ if (err) goto err;
+
+ if (!nr_devices) {
+ printk(KERN_ERR PFX "no bus parameter(s) specified\n");
+ err = -ENODEV;
+ goto err;
+ }
+
+ return 0;
+
+err:
+ i2c_gpio_custom_cleanup();
+ return err;
+}
+
+#ifdef MODULE
+static int __init i2c_gpio_custom_init(void)
+{
+ return i2c_gpio_custom_probe();
+}
+module_init(i2c_gpio_custom_init);
+
+static void __exit i2c_gpio_custom_exit(void)
+{
+ i2c_gpio_custom_cleanup();
+}
+module_exit(i2c_gpio_custom_exit);
+#else
+subsys_initcall(i2c_gpio_custom_probe);
+#endif /* MODULE*/
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org >");
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_VERSION(DRV_VERSION);
diff --git a/package/kernel/lantiq/ltq-adsl-app/Config.in b/package/kernel/lantiq/ltq-adsl-app/Config.in
new file mode 100644
index 0000000000..728fe65b31
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-app/Config.in
@@ -0,0 +1,9 @@
+config LTQ_DSL_ENABLE_SOAP
+ bool "Enable SOAP support"
+ depends on PACKAGE_ltq-dsl-app
+ default n
+
+config LTQ_DSL_ENABLE_DSL_EVENT_POLLING
+ bool "Include Event Polling support"
+ depends on PACKAGE_ltq-dsl-app
+ default n
diff --git a/package/kernel/lantiq/ltq-adsl-app/Makefile b/package/kernel/lantiq/ltq-adsl-app/Makefile
new file mode 100644
index 0000000000..92445e5580
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-app/Makefile
@@ -0,0 +1,98 @@
+#
+# Copyright (C) 2011-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=dsl_cpe_control_danube
+PKG_VERSION:=3.24.4.4
+PKG_RELEASE:=2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_BUILD_DIR:=$(BUILD_DIR)/dsl_cpe_control-$(PKG_VERSION)
+PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
+PKG_MD5SUM:=ee315306626b68794d3d3636dabfe161
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+PKG_FIXUP:=autoreconf
+
+PKG_CONFIG_DEPENDS:=\
+ CONFIG_LTQ_DSL_ENABLE_SOAP \
+ CONFIG_LTQ_DSL_ENABLE_DSL_EVENT_POLLING
+
+PKG_BUILD_DEPENDS:=TARGET_lantiq_xway:kmod-ltq-adsl-danube TARGET_lantiq_ase:kmod-ltq-adsl-ase
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ltq-adsl-app
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Lantiq DSL userland tool
+ URL:=http://www.lantiq.com/
+ DEPENDS:=@(TARGET_lantiq_xway||TARGET_lantiq_ase) +libpthread
+ MENU:=1
+endef
+
+define Package/ltq-adsl-app/description
+ Infineon DSL CPE API for Amazon SE, Danube and Vinax.
+endef
+
+define Package/ltq-adsl-app/config
+ source "$(SOURCE)/Config.in"
+endef
+
+LTQ_DSL_MAX_DEVICE=1
+LTQ_DSL_LINES_PER_DEVICE=1
+LTQ_DSL_CHANNELS_PER_LINE=1
+
+CONFIGURE_ARGS += \
+ --with-max-device="$(LTQ_DSL_MAX_DEVICE)" \
+ --with-lines-per-device="$(LTQ_DSL_LINES_PER_DEVICE)" \
+ --with-channels-per-line="$(LTQ_DSL_CHANNELS_PER_LINE)" \
+ --enable-danube \
+ --enable-driver-include="-I$(STAGING_DIR)/usr/include/adsl/" \
+ --enable-debug-prints \
+ --enable-add-appl-cflags="-DMAX_CLI_PIPES=2" \
+ --enable-cli-support \
+ --enable-cmv-scripts \
+ --enable-debug-tool-interface \
+ --enable-adsl-led \
+ --enable-dsl-ceoc \
+ --enable-script-notification \
+ --enable-dsl-pm \
+ --enable-dsl-pm-total \
+ --enable-dsl-pm-history \
+ --enable-dsl-pm-showtime \
+ --enable-dsl-pm-channel-counters \
+ --enable-dsl-pm-datapath-counters \
+ --enable-dsl-pm-line-counters \
+ --enable-dsl-pm-channel-thresholds \
+ --enable-dsl-pm-datapath-thresholds \
+ --enable-dsl-pm-line-thresholds \
+ --enable-dsl-pm-optional-parameters
+
+ifeq ($(CONFIG_LTQ_DSL_ENABLE_SOAP),y)
+CONFIGURE_ARGS += \
+ --enable-soap-support
+endif
+
+ifeq ($(CONFIG_LTQ_DSL_ENABLE_DSL_EVENT_POLLING),y)
+CONFIGURE_ARGS += \
+ --enable-dsl-event-polling
+endif
+
+TARGET_CFLAGS += -I$(LINUX_DIR)/include
+
+define Package/ltq-adsl-app/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/dsl_control $(1)/etc/init.d/
+
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dsl_cpe_control $(1)/sbin
+ $(INSTALL_BIN) ./files/dsl_notify.sh $(1)/sbin
+endef
+
+$(eval $(call BuildPackage,ltq-adsl-app))
diff --git a/package/kernel/lantiq/ltq-adsl-app/files/dsl_control b/package/kernel/lantiq/ltq-adsl-app/files/dsl_control
new file mode 100644
index 0000000000..e8a286f2bb
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-app/files/dsl_control
@@ -0,0 +1,311 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2012 OpenWrt.org
+
+START=99
+
+EXTRA_COMMANDS="status lucistat"
+EXTRA_HELP=" status Get DSL status information
+ lucistat Get status information if lua friendly format"
+
+SERVICE_DAEMONIZE=1
+SERVICE_WRITE_PID=1
+
+#
+# Basic functions to send CLI commands to the dsl_cpe_control daemon
+#
+dsl_cmd() {
+ killall -0 dsl_cpe_control && (
+ echo "$@" > /tmp/pipe/dsl_cpe0_cmd
+ cat /tmp/pipe/dsl_cpe0_ack
+ )
+}
+dsl_val() {
+ echo $(expr "$1" : '.*'$2'=\([-\.[:alnum:]]*\).*')
+}
+
+#
+# Simple divide by 10 routine to cope with one decimal place
+#
+dbt() {
+ local a=$(expr $1 / 10)
+ local b=$(expr $1 % 10)
+ echo "${a}.${b}"
+}
+#
+# Take a number and convert to k or meg
+#
+scale() {
+ local val=$1
+ local a
+ local b
+
+ if [ "$val" -gt 1000000 ]; then
+ a=$(expr $val / 1000)
+ b=$(expr $a % 1000)
+ a=$(expr $a / 1000)
+ printf "%d.%03d Mb" ${a} ${b}
+ elif [ "$val" -gt 1000 ]; then
+ a=$(expr $val / 1000)
+ printf "%d Kb" ${a}
+ else
+ echo "${val} b"
+ fi
+}
+
+#
+# Read the data rates for both directions
+#
+data_rates() {
+ local csg
+ local dru
+ local drd
+ local sdru
+ local sdrd
+
+ csg=$(dsl_cmd g997csg 0 1)
+ drd=$(dsl_val "$csg" ActualDataRate)
+
+ csg=$(dsl_cmd g997csg 0 0)
+ dru=$(dsl_val "$csg" ActualDataRate)
+
+ [ -z "$drd" ] && drd=0
+ [ -z "$dru" ] && dru=0
+
+ sdrd=$(scale $drd)
+ sdru=$(scale $dru)
+
+ if [ "$action" = "lucistat" ]; then
+ echo "dsl.data_rate_down=$drd"
+ echo "dsl.data_rate_up=$dru"
+ echo "dsl.data_rate_down_s=\"$sdrd\""
+ echo "dsl.data_rate_up_s=\"$sdru\""
+ else
+ echo "Data Rate: ${sdrd}/s / ${sdru}/s"
+ fi
+}
+
+#
+# Chipset
+#
+chipset() {
+ local vig
+ local cs
+ local csv
+
+ vig=$(dsl_cmd vig)
+ cs=$(dsl_val "$vig" DSL_ChipSetType)
+ csv=$(dsl_val "$vig" DSL_ChipSetHWVersion)
+
+ if [ "$action" = "lucistat" ]; then
+ echo "dsl.chipset=\"${cs} ${csv}\""
+ else
+ echo "Chipset: ${cs} ${csv}"
+ fi
+}
+
+#
+# Work out how long the line has been up
+#
+line_uptime() {
+ local ccsg
+ local et
+ local etr
+ local d
+ local h
+ local m
+ local s
+ local rc=""
+
+ ccsg=$(dsl_cmd pmccsg 0 0 0)
+ et=$(dsl_val "$ccsg" nElapsedTime)
+
+ [ -z "$et" ] && et=0
+
+ if [ "$action" = "lucistat" ]; then
+ echo "dsl.line_uptime=${et}"
+ return
+ fi
+
+ d=$(expr $et / 86400)
+ etr=$(expr $et % 86400)
+ h=$(expr $etr / 3600)
+ etr=$(expr $etr % 3600)
+ m=$(expr $etr / 60)
+ s=$(expr $etr % 60)
+
+
+ [ "${d}${h}${m}${s}" -ne 0 ] && rc="${s}s"
+ [ "${d}${h}${m}" -ne 0 ] && rc="${m}m ${rc}"
+ [ "${d}${h}" -ne 0 ] && rc="${h}h ${rc}"
+ [ "${d}" -ne 0 ] && rc="${d}d ${rc}"
+
+ [ -z "$rc" ] && rc="down"
+ echo "Line Uptime: ${rc}"
+}
+
+#
+# Get noise and attenuation figures
+#
+line_data() {
+ local lsg
+ local latnu
+ local latnd
+ local snru
+ local snrd
+
+ lsg=$(dsl_cmd g997lsg 1 1)
+ latnd=$(dsl_val "$lsg" LATN)
+ snrd=$(dsl_val "$lsg" SNR)
+
+ lsg=$(dsl_cmd g997lsg 0 1)
+ latnu=$(dsl_val "$lsg" LATN)
+ snru=$(dsl_val "$lsg" SNR)
+
+ [ -z "$latnd" ] && latnd=0
+ [ -z "$latnu" ] && latnu=0
+ [ -z "$snrd" ] && snrd=0
+ [ -z "$snru" ] && snru=0
+
+ latnd=$(dbt $latnd)
+ latnu=$(dbt $latnu)
+ snrd=$(dbt $snrd)
+ snru=$(dbt $snru)
+
+ if [ "$action" = "lucistat" ]; then
+ echo "dsl.line_attenuation_down=$latnd"
+ echo "dsl.line_attenuation_up=$latnu"
+ echo "dsl.noise_margin_down=$snrd"
+ echo "dsl.noise_margin_up=$snru"
+ else
+ echo "Line Attenuation: ${latnd}dB / ${latnu}dB"
+ echo "Noise Margin: ${snrd}dB / ${snru}dB"
+ fi
+}
+
+#
+# Is the line up? Or what state is it in?
+#
+line_state() {
+ local lsg=$(dsl_cmd lsg)
+ local ls=$(dsl_val "$lsg" nLineState);
+ local s;
+
+ case "$ls" in
+ "0x0") s="not initialized" ;;
+ "0x1") s="exception" ;;
+ "0x10") s="not updated" ;;
+ "0xff") s="idle request" ;;
+ "0x100") s="idle" ;;
+ "0x1ff") s="silent request" ;;
+ "0x200") s="silent" ;;
+ "0x300") s="handshake" ;;
+ "0x380") s="full_init" ;;
+ "0x400") s="discovery" ;;
+ "0x500") s="training" ;;
+ "0x600") s="analysis" ;;
+ "0x700") s="exchange" ;;
+ "0x800") s="showtime_no_sync" ;;
+ "0x801") s="showtime_tc_sync" ;;
+ "0x900") s="fastretrain" ;;
+ "0xa00") s="lowpower_l2" ;;
+ "0xb00") s="loopdiagnostic active" ;;
+ "0xb10") s="loopdiagnostic data exchange" ;;
+ "0xb20") s="loopdiagnostic data request" ;;
+ "0xc00") s="loopdiagnostic complete" ;;
+ "0x1000000") s="test" ;;
+ "0xd00") s="resync" ;;
+ "0x3c0") s="short init entry" ;;
+ "") s="not running daemon"; ls="0xfff" ;;
+ *) s="unknown" ;;
+ esac
+
+ if [ $action = "lucistat" ]; then
+ echo "dsl.line_state_num=$ls"
+ echo "dsl.line_state_detail=\"$s\""
+ if [ "$ls" = "0x801" ]; then
+ echo "dsl.line_state=\"UP\""
+ else
+ echo "dsl.line_state=\"DOWN\""
+ fi
+ else
+ if [ "$ls" = "0x801" ]; then
+ echo "Line State: UP [$ls: $s]"
+ else
+ echo "Line State: DOWN [$ls: $s]"
+ fi
+ fi
+}
+
+#
+# Main status routine
+#
+status() {
+ chipset
+ line_state
+ data_rates
+ line_data
+ line_uptime
+}
+
+#
+# Luci (lua) compatible version that's easy to parse
+#
+lucistat() {
+ echo "local dsl={}"
+ status
+ echo "return dsl"
+}
+
+
+annex_b=10_00_10_00_00_04_00_00
+annex_bdmt=10_00_00_00_00_00_00_00
+annex_b2=00_00_10_00_00_00_00_00
+annex_b2p=00_00_00_00_00_04_00_00
+annex_a=04_01_04_00_00_01_00_00
+annex_at1=01_00_00_00_00_00_00_00
+annex_alite=00_01_00_00_00_00_00_00
+annex_admt=04_00_00_00_00_00_00_00
+annex_a2=00_00_04_00_00_00_00_00
+annex_a2p=00_00_00_00_00_01_00_00
+annex_l=00_00_00_00_04_00_00_00
+annex_m=00_00_00_00_40_00_04_00
+annex_m2=00_00_00_00_40_00_00_00
+annex_m2p=00_00_00_00_00_00_04_00
+
+#
+# Simple start routine
+#
+start() {
+ local annex
+ local firmware
+ local xtu
+ config_load network
+ config_get annex wan annex
+ config_get firmware wan firmware
+
+ # get xtu
+ eval "xtu=\"\${annex_$annex}\""
+
+ # check for firmware
+ [ -z "${firmware}" ] &&
+ firmware=adsl.bin
+
+ # start CPE dsl daemon in the background
+ service_start /sbin/dsl_cpe_control -i${xtu} \
+ -n /sbin/dsl_notify.sh \
+ -f /lib/firmware/${firmware}
+}
+
+#
+# For stop we want to simulate the notification call for when
+# the line goes down, so that we can stop the ppp link before
+# we die.
+#
+stop() {
+ DSL_NOTIFICATION_TYPE="DSL_INTERFACE_STATUS" \
+ DSL_INTERFACE_STATUS="DOWN" \
+ /sbin/dsl_notify.sh
+
+ service_stop /sbin/dsl_cpe_control
+}
+
diff --git a/package/kernel/lantiq/ltq-adsl-app/files/dsl_notify.sh b/package/kernel/lantiq/ltq-adsl-app/files/dsl_notify.sh
new file mode 100644
index 0000000000..5e9f3964e8
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-app/files/dsl_notify.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# This script is called by dsl_cpe_control whenever there is a DSL event,
+# we only actually care about the DSL_INTERFACE_STATUS events as these
+# tell us the line has either come up or gone down.
+#
+# The rest of the code is basically the same at the atm hotplug code
+#
+
+[ "$DSL_NOTIFICATION_TYPE" = "DSL_INTERFACE_STATUS" ] || exit 0
+
+. /lib/functions.sh
+
+include /lib/network
+scan_interfaces
+
+local found=0
+local ifc
+for ifc in $interfaces; do
+ local up
+ config_get_bool up "$ifc" up 0
+
+ local auto
+ config_get_bool auto "$ifc" auto 1
+
+ local proto
+ config_get proto "$ifc" proto
+
+ if [ "$DSL_INTERFACE_STATUS" = "UP" ]; then
+ if [ "$proto" = "pppoa" ] && [ "$up" != 1 ] && [ "$auto" = 1 ]; then
+ found=1
+ ( sleep 1; ifup "$ifc" ) &
+ fi
+ else
+ if [ "$proto" = "pppoa" ] && [ "$up" = 1 ] && [ "$auto" = 1 ]; then
+ found=1
+ ( sleep 1; ifdown "$ifc" ) &
+ fi
+ fi
+done
+
+if [ "$found" != 1 ]; then
+ logger "Found no matching interface for DSL notification ($DSL_INTERFACE_STATUS)"
+fi
diff --git a/package/kernel/lantiq/ltq-adsl-fw/Makefile b/package/kernel/lantiq/ltq-adsl-fw/Makefile
new file mode 100644
index 0000000000..53d223b609
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-fw/Makefile
@@ -0,0 +1,55 @@
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ltq-adsl-fw
+PKG_VERSION:=0.1
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/ltq-dsl-fw-$(PKG_VERSION)
+PKG_SOURCE:=ltq-dsl-fw-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
+PKG_MD5SUM:=4700a36b66b955b4c5544227267356f4
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/kmod-ltq-adsl-fw-template
+ TITLE+=Firmware Annex-$(1) $(2)
+ SECTION:=sys
+ CATEGORY:=Kernel modules
+ SUBMENU:=Network Devices
+ VARIANT:= $(2)-fw-$(1)
+ SOC:=$(2)
+ ANNEX:=$(1)
+ URL:=http://www.lantiq.com/
+ DEPENDS:=@TARGET_lantiq_$(3) +kmod-ltq-adsl-$(2)
+endef
+
+Package/kmod-ltq-adsl-danube-fw-a=$(call Package/kmod-ltq-adsl-fw-template,a,danube,xway)
+Package/kmod-ltq-adsl-danube-fw-b=$(call Package/kmod-ltq-adsl-fw-template,b,danube,xway)
+Package/kmod-ltq-adsl-ar9-fw-a=$(call Package/kmod-ltq-adsl-fw-template,a,ar9,xway)
+Package/kmod-ltq-adsl-ar9-fw-b=$(call Package/kmod-ltq-adsl-fw-template,b,ar9,xway)
+Package/kmod-ltq-adsl-ase-fw-a=$(call Package/kmod-ltq-adsl-fw-template,a,ase,ase)
+Package/kmod-ltq-adsl-ase-fw-b=$(call Package/kmod-ltq-adsl-fw-template,b,ase,ase)
+
+define Build/Compile
+endef
+
+define Package/kmod-ltq-adsl-$(BUILD_VARIANT)/install
+ $(INSTALL_DIR) $(1)/lib/firmware/
+ $(CP) $(PKG_BUILD_DIR)/$(FW_NAME)/ltq-dsl-fw-$(ANNEX)-$(SOC).bin $(1)/lib/firmware/
+ ln -s /lib/firmware/$(FW_NAME)/ltq-dsl-fw-$(ANNEX)-$(SOC).bin $(1)/lib/firmware/adsl.bin
+endef
+
+$(eval $(call BuildPackage,kmod-ltq-adsl-danube-fw-a))
+$(eval $(call BuildPackage,kmod-ltq-adsl-danube-fw-b))
+$(eval $(call BuildPackage,kmod-ltq-adsl-ase-fw-a))
+$(eval $(call BuildPackage,kmod-ltq-adsl-ase-fw-b))
+$(eval $(call BuildPackage,kmod-ltq-adsl-ar9-fw-a))
+$(eval $(call BuildPackage,kmod-ltq-adsl-ar9-fw-b))
diff --git a/package/kernel/lantiq/ltq-adsl-mei/Makefile b/package/kernel/lantiq/ltq-adsl-mei/Makefile
new file mode 100644
index 0000000000..790b891d7a
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-mei/Makefile
@@ -0,0 +1,49 @@
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ltq-adsl-mei
+PKG_RELEASE:=1
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-adsl-mei-$(BUILD_VARIANT)/
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-adsl-mei-template
+ SECTION:=sys
+ CATEGORY:=Kernel modules
+ SUBMENU:=Network Devices
+ TITLE:=mei driver for $(1)
+ URL:=http://www.lantiq.com/
+ VARIANT:=$(1)
+ DEPENDS:=@TARGET_lantiq_$(2)
+ FILES:=$(PKG_BUILD_DIR)/ltq_mei_$(1).ko
+ AUTOLOAD:=$(call AutoLoad,50,ltq_mei_$(1))
+endef
+
+KernelPackage/ltq-adsl-danube-mei=$(call KernelPackage/ltq-adsl-mei-template,danube,xway)
+KernelPackage/ltq-adsl-ar9-mei=$(call KernelPackage/ltq-adsl-mei-template,ar9,xway)
+KernelPackage/ltq-adsl-ase-mei=$(call KernelPackage/ltq-adsl-mei-template,ase,ase)
+
+define Build/Prepare
+ $(INSTALL_DIR) $(PKG_BUILD_DIR)/
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ cd $(LINUX_DIR); \
+ ARCH=mips CROSS_COMPILE="$(KERNEL_CROSS)" \
+ $(MAKE) BUILD_VARIANT=$(BUILD_VARIANT) M=$(PKG_BUILD_DIR)/ V=1 modules
+endef
+
+$(eval $(call KernelPackage,ltq-adsl-danube-mei))
+$(eval $(call KernelPackage,ltq-adsl-ase-mei))
+$(eval $(call KernelPackage,ltq-adsl-ar9-mei))
diff --git a/package/kernel/lantiq/ltq-adsl-mei/src/Makefile b/package/kernel/lantiq/ltq-adsl-mei/src/Makefile
new file mode 100644
index 0000000000..2d8645f8f2
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-mei/src/Makefile
@@ -0,0 +1,17 @@
+ifeq ($(BUILD_VARIANT),danube)
+ CFLAGS_MODULE = -DCONFIG_DANUBE -DCONFIG_IFXMIPS_DSL_CPE_MEI
+ obj-m = ltq_mei_danube.o
+ ltq_mei_danube-objs = lantiq_mei.o
+endif
+
+ifeq ($(BUILD_VARIANT),ase)
+ CFLAGS_MODULE = -DCONFIG_AMAZON_SE -DCONFIG_IFXMIPS_DSL_CPE_MEI
+ obj-m = ltq_mei_ase.o
+ ltq_mei_ase-objs = lantiq_mei.o
+endif
+
+ifeq ($(BUILD_VARIANT),ar9)
+ CFLAGS_MODULE = -DCONFIG_AR9 -DCONFIG_IFXMIPS_DSL_CPE_MEI
+ obj-m = ltq_mei_ar9.o
+ ltq_mei_ar9-objs = lantiq_mei.o
+endif
diff --git a/package/kernel/lantiq/ltq-adsl-mei/src/ifxmips_mei_interface.h b/package/kernel/lantiq/ltq-adsl-mei/src/ifxmips_mei_interface.h
new file mode 100644
index 0000000000..4ddc4c6aed
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-mei/src/ifxmips_mei_interface.h
@@ -0,0 +1,702 @@
+/******************************************************************************
+
+ Copyright (c) 2009
+ Infineon Technologies AG
+ Am Campeon 1-12; 81726 Munich, Germany
+
+ For licensing information, see the file 'LICENSE' in the root folder of
+ this software module.
+
+******************************************************************************/
+
+#ifndef IFXMIPS_MEI_H
+#define IFXMIPS_MEI_H
+
+//#define CONFIG_AMAZON_SE 1
+//#define CONFIG_DANUBE 1
+//#define CONFIG_AR9 1
+
+#if !defined(CONFIG_DANUBE) && !defined(CONFIG_AMAZON_SE) && !defined(CONFIG_AR9) && !defined(CONFIG_VR9)
+#error Platform undefined!!!
+#endif
+
+#ifdef IFX_MEI_BSP
+/** This is the character datatype. */
+typedef char DSL_char_t;
+/** This is the unsigned 8-bit datatype. */
+typedef unsigned char DSL_uint8_t;
+/** This is the signed 8-bit datatype. */
+typedef signed char DSL_int8_t;
+/** This is the unsigned 16-bit datatype. */
+typedef unsigned short DSL_uint16_t;
+/** This is the signed 16-bit datatype. */
+typedef signed short DSL_int16_t;
+/** This is the unsigned 32-bit datatype. */
+typedef unsigned long DSL_uint32_t;
+/** This is the signed 32-bit datatype. */
+typedef signed long DSL_int32_t;
+/** This is the float datatype. */
+typedef float DSL_float_t;
+/** This is the void datatype. */
+typedef void DSL_void_t;
+/** integer type, width is depending on processor arch */
+typedef int DSL_int_t;
+/** unsigned integer type, width is depending on processor arch */
+typedef unsigned int DSL_uint_t;
+typedef struct file DSL_DRV_file_t;
+typedef struct inode DSL_DRV_inode_t;
+
+/**
+ * Defines all possible CMV groups
+ * */
+typedef enum {
+ DSL_CMV_GROUP_CNTL = 1,
+ DSL_CMV_GROUP_STAT = 2,
+ DSL_CMV_GROUP_INFO = 3,
+ DSL_CMV_GROUP_TEST = 4,
+ DSL_CMV_GROUP_OPTN = 5,
+ DSL_CMV_GROUP_RATE = 6,
+ DSL_CMV_GROUP_PLAM = 7,
+ DSL_CMV_GROUP_CNFG = 8
+} DSL_CmvGroup_t;
+/**
+ * Defines all opcode types
+ * */
+typedef enum {
+ H2D_CMV_READ = 0x00,
+ H2D_CMV_WRITE = 0x04,
+ H2D_CMV_INDICATE_REPLY = 0x10,
+ H2D_ERROR_OPCODE_UNKNOWN =0x20,
+ H2D_ERROR_CMV_UNKNOWN =0x30,
+
+ D2H_CMV_READ_REPLY =0x01,
+ D2H_CMV_WRITE_REPLY = 0x05,
+ D2H_CMV_INDICATE = 0x11,
+ D2H_ERROR_OPCODE_UNKNOWN = 0x21,
+ D2H_ERROR_CMV_UNKNOWN = 0x31,
+ D2H_ERROR_CMV_READ_NOT_AVAILABLE = 0x41,
+ D2H_ERROR_CMV_WRITE_ONLY = 0x51,
+ D2H_ERROR_CMV_READ_ONLY = 0x61,
+
+ H2D_DEBUG_READ_DM = 0x02,
+ H2D_DEBUG_READ_PM = 0x06,
+ H2D_DEBUG_WRITE_DM = 0x0a,
+ H2D_DEBUG_WRITE_PM = 0x0e,
+
+ D2H_DEBUG_READ_DM_REPLY = 0x03,
+ D2H_DEBUG_READ_FM_REPLY = 0x07,
+ D2H_DEBUG_WRITE_DM_REPLY = 0x0b,
+ D2H_DEBUG_WRITE_FM_REPLY = 0x0f,
+ D2H_ERROR_ADDR_UNKNOWN = 0x33,
+
+ D2H_AUTONOMOUS_MODEM_READY_MSG = 0xf1
+} DSL_CmvOpcode_t;
+
+/* mutex macros */
+#define MEI_MUTEX_INIT(id,flag) \
+ sema_init(&id,flag)
+#define MEI_MUTEX_LOCK(id) \
+ down_interruptible(&id)
+#define MEI_MUTEX_UNLOCK(id) \
+ up(&id)
+#define MEI_WAIT(ms) \
+ {\
+ set_current_state(TASK_INTERRUPTIBLE);\
+ schedule_timeout(ms);\
+ }
+#define MEI_INIT_WAKELIST(name,queue) \
+ init_waitqueue_head(&queue)
+
+/* wait for an event, timeout is measured in ms */
+#define MEI_WAIT_EVENT_TIMEOUT(ev,timeout)\
+ interruptible_sleep_on_timeout(&ev,timeout * HZ / 1000)
+#define MEI_WAKEUP_EVENT(ev)\
+ wake_up_interruptible(&ev)
+#endif /* IFX_MEI_BSP */
+
+/*** Register address offsets, relative to MEI_SPACE_ADDRESS ***/
+#define ME_DX_DATA (0x0000)
+#define ME_VERSION (0x0004)
+#define ME_ARC_GP_STAT (0x0008)
+#define ME_DX_STAT (0x000C)
+#define ME_DX_AD (0x0010)
+#define ME_DX_MWS (0x0014)
+#define ME_ME2ARC_INT (0x0018)
+#define ME_ARC2ME_STAT (0x001C)
+#define ME_ARC2ME_MASK (0x0020)
+#define ME_DBG_WR_AD (0x0024)
+#define ME_DBG_RD_AD (0x0028)
+#define ME_DBG_DATA (0x002C)
+#define ME_DBG_DECODE (0x0030)
+#define ME_CONFIG (0x0034)
+#define ME_RST_CTRL (0x0038)
+#define ME_DBG_MASTER (0x003C)
+#define ME_CLK_CTRL (0x0040)
+#define ME_BIST_CTRL (0x0044)
+#define ME_BIST_STAT (0x0048)
+#define ME_XDATA_BASE_SH (0x004c)
+#define ME_XDATA_BASE (0x0050)
+#define ME_XMEM_BAR_BASE (0x0054)
+#define ME_XMEM_BAR0 (0x0054)
+#define ME_XMEM_BAR1 (0x0058)
+#define ME_XMEM_BAR2 (0x005C)
+#define ME_XMEM_BAR3 (0x0060)
+#define ME_XMEM_BAR4 (0x0064)
+#define ME_XMEM_BAR5 (0x0068)
+#define ME_XMEM_BAR6 (0x006C)
+#define ME_XMEM_BAR7 (0x0070)
+#define ME_XMEM_BAR8 (0x0074)
+#define ME_XMEM_BAR9 (0x0078)
+#define ME_XMEM_BAR10 (0x007C)
+#define ME_XMEM_BAR11 (0x0080)
+#define ME_XMEM_BAR12 (0x0084)
+#define ME_XMEM_BAR13 (0x0088)
+#define ME_XMEM_BAR14 (0x008C)
+#define ME_XMEM_BAR15 (0x0090)
+#define ME_XMEM_BAR16 (0x0094)
+
+#define WHILE_DELAY 20000
+/*
+** Define where in ME Processor's memory map the Stratify chip lives
+*/
+
+#define MAXSWAPSIZE (8 * 1024) //8k *(32bits)
+
+// Mailboxes
+#define MSG_LENGTH 16 // x16 bits
+#define YES_REPLY 1
+#define NO_REPLY 0
+
+#define CMV_TIMEOUT 1000 //jiffies
+
+// Block size per BAR
+#define SDRAM_SEGMENT_SIZE (64*1024)
+// Number of Bar registers
+#define MAX_BAR_REGISTERS (17)
+
+#define XDATA_REGISTER (15)
+
+// ARC register addresss
+#define ARC_STATUS 0x0
+#define ARC_LP_START 0x2
+#define ARC_LP_END 0x3
+#define ARC_DEBUG 0x5
+#define ARC_INT_MASK 0x10A
+
+#define IRAM0_BASE (0x00000)
+#define IRAM1_BASE (0x04000)
+#if defined(CONFIG_DANUBE)
+#define BRAM_BASE (0x0A000)
+#elif defined(CONFIG_AMAZON_SE) || defined(CONFIG_AR9) || defined(CONFIG_VR9)
+#define BRAM_BASE (0x08000)
+#endif
+#define XRAM_BASE (0x18000)
+#define YRAM_BASE (0x1A000)
+#define EXT_MEM_BASE (0x80000)
+#define ARC_GPIO_CTRL (0xC030)
+#define ARC_GPIO_DATA (0xC034)
+
+#define IRAM0_SIZE (16*1024)
+#define IRAM1_SIZE (16*1024)
+#define BRAM_SIZE (12*1024)
+#define XRAM_SIZE (8*1024)
+#define YRAM_SIZE (8*1024)
+#define EXT_MEM_SIZE (1536*1024)
+
+#define ADSL_BASE (0x20000)
+#define CRI_BASE (ADSL_BASE + 0x11F00)
+#define CRI_CCR0 (CRI_BASE + 0x00)
+#define CRI_RST (CRI_BASE + 0x04*4)
+#define ADSL_DILV_BASE (ADSL_BASE+0x20000)
+
+//
+#define IRAM0_ADDR_BIT_MASK 0xFFF
+#define IRAM1_ADDR_BIT_MASK 0xFFF
+#define BRAM_ADDR_BIT_MASK 0xFFF
+#define RX_DILV_ADDR_BIT_MASK 0x1FFF
+
+/*** Bit definitions ***/
+#define ARC_AUX_HALT (1 << 25)
+#define ARC_DEBUG_HALT (1 << 1)
+#define FALSE 0
+#define TRUE 1
+#define BIT0 (1<<0)
+#define BIT1 (1<<1)
+#define BIT2 (1<<2)
+#define BIT3 (1<<3)
+#define BIT4 (1<<4)
+#define BIT5 (1<<5)
+#define BIT6 (1<<6)
+#define BIT7 (1<<7)
+#define BIT8 (1<<8)
+#define BIT9 (1<<9)
+#define BIT10 (1<<10)
+#define BIT11 (1<<11)
+#define BIT12 (1<<12)
+#define BIT13 (1<<13)
+#define BIT14 (1<<14)
+#define BIT15 (1<<15)
+#define BIT16 (1<<16)
+#define BIT17 (1<<17)
+#define BIT18 (1<<18)
+#define BIT19 (1<<19)
+#define BIT20 (1<<20)
+#define BIT21 (1<<21)
+#define BIT22 (1<<22)
+#define BIT23 (1<<23)
+#define BIT24 (1<<24)
+#define BIT25 (1<<25)
+#define BIT26 (1<<26)
+#define BIT27 (1<<27)
+#define BIT28 (1<<28)
+#define BIT29 (1<<29)
+#define BIT30 (1<<30)
+#define BIT31 (1<<31)
+
+// CRI_CCR0 Register definitions
+#define CLK_2M_MODE_ENABLE BIT6
+#define ACL_CLK_MODE_ENABLE BIT4
+#define FDF_CLK_MODE_ENABLE BIT2
+#define STM_CLK_MODE_ENABLE BIT0
+
+// CRI_RST Register definitions
+#define FDF_SRST BIT3
+#define MTE_SRST BIT2
+#define FCI_SRST BIT1
+#define AAI_SRST BIT0
+
+// MEI_TO_ARC_INTERRUPT Register definitions
+#define MEI_TO_ARC_INT1 BIT3
+#define MEI_TO_ARC_INT0 BIT2
+#define MEI_TO_ARC_CS_DONE BIT1 //need to check
+#define MEI_TO_ARC_MSGAV BIT0
+
+// ARC_TO_MEI_INTERRUPT Register definitions
+#define ARC_TO_MEI_INT1 BIT8
+#define ARC_TO_MEI_INT0 BIT7
+#define ARC_TO_MEI_CS_REQ BIT6
+#define ARC_TO_MEI_DBG_DONE BIT5
+#define ARC_TO_MEI_MSGACK BIT4
+#define ARC_TO_MEI_NO_ACCESS BIT3
+#define ARC_TO_MEI_CHECK_AAITX BIT2
+#define ARC_TO_MEI_CHECK_AAIRX BIT1
+#define ARC_TO_MEI_MSGAV BIT0
+
+// ARC_TO_MEI_INTERRUPT_MASK Register definitions
+#define GP_INT1_EN BIT8
+#define GP_INT0_EN BIT7
+#define CS_REQ_EN BIT6
+#define DBG_DONE_EN BIT5
+#define MSGACK_EN BIT4
+#define NO_ACC_EN BIT3
+#define AAITX_EN BIT2
+#define AAIRX_EN BIT1
+#define MSGAV_EN BIT0
+
+#define MEI_SOFT_RESET BIT0
+
+#define HOST_MSTR BIT0
+
+#define JTAG_MASTER_MODE 0x0
+#define MEI_MASTER_MODE HOST_MSTR
+
+// MEI_DEBUG_DECODE Register definitions
+#define MEI_DEBUG_DEC_MASK (0x3)
+#define MEI_DEBUG_DEC_AUX_MASK (0x0)
+#define ME_DBG_DECODE_DMP1_MASK (0x1)
+#define MEI_DEBUG_DEC_DMP2_MASK (0x2)
+#define MEI_DEBUG_DEC_CORE_MASK (0x3)
+
+#define AUX_STATUS (0x0)
+#define AUX_ARC_GPIO_CTRL (0x10C)
+#define AUX_ARC_GPIO_DATA (0x10D)
+// ARC_TO_MEI_MAILBOX[11] is a special location used to indicate
+// page swap requests.
+#if defined(CONFIG_DANUBE)
+#define OMBOX_BASE 0xDF80
+#define ARC_TO_MEI_MAILBOX 0xDFA0
+#define IMBOX_BASE 0xDFC0
+#define MEI_TO_ARC_MAILBOX 0xDFD0
+#elif defined(CONFIG_AMAZON_SE) || defined(CONFIG_AR9) || defined(CONFIG_VR9)
+#define OMBOX_BASE 0xAF80
+#define ARC_TO_MEI_MAILBOX 0xAFA0
+#define IMBOX_BASE 0xAFC0
+#define MEI_TO_ARC_MAILBOX 0xAFD0
+#endif
+
+#define MEI_TO_ARC_MAILBOXR (MEI_TO_ARC_MAILBOX + 0x2C)
+#define ARC_MEI_MAILBOXR (ARC_TO_MEI_MAILBOX + 0x2C)
+#define OMBOX1 (OMBOX_BASE+0x4)
+
+// Codeswap request messages are indicated by setting BIT31
+#define OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK (0x80000000)
+
+// Clear Eoc messages received are indicated by setting BIT17
+#define OMB_CLEAREOC_INTERRUPT_CODE (0x00020000)
+#define OMB_REBOOT_INTERRUPT_CODE (1 << 18)
+
+/*
+** Swap page header
+*/
+// Page must be loaded at boot time if size field has BIT31 set
+#define BOOT_FLAG (BIT31)
+#define BOOT_FLAG_MASK ~BOOT_FLAG
+
+#define FREE_RELOAD 1
+#define FREE_SHOWTIME 2
+#define FREE_ALL 3
+
+// marcos
+#define IFX_MEI_WRITE_REGISTER_L(data,addr) *((volatile u32*)(addr)) = (u32)(data)
+#define IFX_MEI_READ_REGISTER_L(addr) (*((volatile u32*)(addr)))
+#define SET_BIT(reg, mask) reg |= (mask)
+#define CLEAR_BIT(reg, mask) reg &= (~mask)
+#define CLEAR_BITS(reg, mask) CLEAR_BIT(reg, mask)
+//#define SET_BITS(reg, mask) SET_BIT(reg, mask)
+#define SET_BITFIELD(reg, mask, off, val) {reg &= (~mask); reg |= (val << off);}
+
+#define ALIGN_SIZE ( 1L<<10 ) //1K size align
+#define MEM_ALIGN(addr) (((addr) + ALIGN_SIZE - 1) & ~ (ALIGN_SIZE -1) )
+
+// swap marco
+#define MEI_HALF_WORD_SWAP(data) {data = ((data & 0xffff)<<16) + ((data & 0xffff0000)>>16);}
+#define MEI_BYTE_SWAP(data) {data = ((data & 0xff)<<24) + ((data & 0xff00)<<8)+ ((data & 0xff0000)>>8)+ ((data & 0xff000000)>>24);}
+
+
+#ifdef CONFIG_PROC_FS
+typedef struct reg_entry
+{
+ int *flag;
+ char name[30]; /* big enough to hold names */
+ char description[100]; /* big enough to hold description */
+ unsigned short low_ino;
+} reg_entry_t;
+#endif
+// Swap page header describes size in 32-bit words, load location, and image offset
+// for program and/or data segments
+typedef struct _arc_swp_page_hdr {
+ u32 p_offset; //Offset bytes of progseg from beginning of image
+ u32 p_dest; //Destination addr of progseg on processor
+ u32 p_size; //Size in 32-bitwords of program segment
+ u32 d_offset; //Offset bytes of dataseg from beginning of image
+ u32 d_dest; //Destination addr of dataseg on processor
+ u32 d_size; //Size in 32-bitwords of data segment
+} ARC_SWP_PAGE_HDR;
+
+/*
+** Swap image header
+*/
+#define GET_PROG 0 // Flag used for program mem segment
+#define GET_DATA 1 // Flag used for data mem segment
+
+// Image header contains size of image, checksum for image, and count of
+// page headers. Following that are 'count' page headers followed by
+// the code and/or data segments to be loaded
+typedef struct _arc_img_hdr {
+ u32 size; // Size of binary image in bytes
+ u32 checksum; // Checksum for image
+ u32 count; // Count of swp pages in image
+ ARC_SWP_PAGE_HDR page[1]; // Should be "count" pages - '1' to make compiler happy
+} ARC_IMG_HDR;
+
+typedef struct smmu_mem_info {
+ int type;
+ int boot;
+ unsigned long nCopy;
+ unsigned long size;
+ unsigned char *address;
+ unsigned char *org_address;
+} smmu_mem_info_t;
+
+#ifdef __KERNEL__
+typedef struct ifx_mei_device_private {
+ int modem_ready;
+ int arcmsgav;
+ int cmv_reply;
+ int cmv_waiting;
+ // Mei to ARC CMV count, reply count, ARC Indicator count
+ int modem_ready_cnt;
+ int cmv_count;
+ int reply_count;
+ unsigned long image_size;
+ int nBar;
+ u16 Recent_indicator[MSG_LENGTH];
+
+ u16 CMV_RxMsg[MSG_LENGTH] __attribute__ ((aligned (4)));
+
+ smmu_mem_info_t adsl_mem_info[MAX_BAR_REGISTERS];
+ ARC_IMG_HDR *img_hdr;
+ // to wait for arc cmv reply, sleep on wait_queue_arcmsgav;
+ wait_queue_head_t wait_queue_arcmsgav;
+ wait_queue_head_t wait_queue_modemready;
+ struct semaphore mei_cmv_sema;
+} ifx_mei_device_private_t;
+#endif
+typedef struct winhost_message {
+ union {
+ u16 RxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
+ u16 TxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
+ } msg;
+} DSL_DEV_WinHost_Message_t;
+/********************************************************************************************************
+ * DSL CPE API Driver Stack Interface Definitions
+ * *****************************************************************************************************/
+/** IOCTL codes for bsp driver */
+#define DSL_IOC_MEI_BSP_MAGIC 's'
+
+#define DSL_FIO_BSP_DSL_START _IO (DSL_IOC_MEI_BSP_MAGIC, 0)
+#define DSL_FIO_BSP_RUN _IO (DSL_IOC_MEI_BSP_MAGIC, 1)
+#define DSL_FIO_BSP_FREE_RESOURCE _IO (DSL_IOC_MEI_BSP_MAGIC, 2)
+#define DSL_FIO_BSP_RESET _IO (DSL_IOC_MEI_BSP_MAGIC, 3)
+#define DSL_FIO_BSP_REBOOT _IO (DSL_IOC_MEI_BSP_MAGIC, 4)
+#define DSL_FIO_BSP_HALT _IO (DSL_IOC_MEI_BSP_MAGIC, 5)
+#define DSL_FIO_BSP_BOOTDOWNLOAD _IO (DSL_IOC_MEI_BSP_MAGIC, 6)
+#define DSL_FIO_BSP_JTAG_ENABLE _IO (DSL_IOC_MEI_BSP_MAGIC, 7)
+#define DSL_FIO_FREE_RESOURCE _IO (DSL_IOC_MEI_BSP_MAGIC, 8)
+#define DSL_FIO_ARC_MUX_TEST _IO (DSL_IOC_MEI_BSP_MAGIC, 9)
+#define DSL_FIO_BSP_REMOTE _IOW (DSL_IOC_MEI_BSP_MAGIC, 10, u32)
+#define DSL_FIO_BSP_GET_BASE_ADDRESS _IOR (DSL_IOC_MEI_BSP_MAGIC, 11, u32)
+#define DSL_FIO_BSP_IS_MODEM_READY _IOR (DSL_IOC_MEI_BSP_MAGIC, 12, u32)
+#define DSL_FIO_BSP_GET_VERSION _IOR (DSL_IOC_MEI_BSP_MAGIC, 13, DSL_DEV_Version_t)
+#define DSL_FIO_BSP_CMV_WINHOST _IOWR(DSL_IOC_MEI_BSP_MAGIC, 14, DSL_DEV_WinHost_Message_t)
+#define DSL_FIO_BSP_CMV_READ _IOWR(DSL_IOC_MEI_BSP_MAGIC, 15, DSL_DEV_MeiReg_t)
+#define DSL_FIO_BSP_CMV_WRITE _IOW (DSL_IOC_MEI_BSP_MAGIC, 16, DSL_DEV_MeiReg_t)
+#define DSL_FIO_BSP_DEBUG_READ _IOWR(DSL_IOC_MEI_BSP_MAGIC, 17, DSL_DEV_MeiDebug_t)
+#define DSL_FIO_BSP_DEBUG_WRITE _IOWR(DSL_IOC_MEI_BSP_MAGIC, 18, DSL_DEV_MeiDebug_t)
+#define DSL_FIO_BSP_GET_CHIP_INFO _IOR (DSL_IOC_MEI_BSP_MAGIC, 19, DSL_DEV_HwVersion_t)
+
+#define DSL_DEV_MEIDEBUG_BUFFER_SIZES 512
+
+typedef struct DSL_DEV_MeiDebug
+{
+ DSL_uint32_t iAddress;
+ DSL_uint32_t iCount;
+ DSL_uint32_t buffer[DSL_DEV_MEIDEBUG_BUFFER_SIZES];
+} DSL_DEV_MeiDebug_t; /* meidebug */
+
+/**
+ * Structure is used for debug access only.
+ * Refer to configure option INCLUDE_ADSL_WINHOST_DEBUG */
+typedef struct struct_meireg
+{
+ /*
+ * Specifies that address for debug access */
+ unsigned long iAddress;
+ /*
+ * Specifies the pointer to the data that has to be written or returns a
+ * pointer to the data that has been read out*/
+ unsigned long iData;
+} DSL_DEV_MeiReg_t; /* meireg */
+
+typedef struct DSL_DEV_Device
+{
+ DSL_int_t nInUse; /* modem state, update by bsp driver, */
+ DSL_void_t *pPriv;
+ DSL_uint32_t base_address; /* mei base address */
+ DSL_int_t nIrq[2]; /* irq number */
+#define IFX_DFEIR 0
+#define IFX_DYING_GASP 1
+ DSL_DEV_MeiDebug_t lop_debugwr; /* dying gasp */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+ struct module *owner;
+#endif
+} DSL_DEV_Device_t; /* ifx_adsl_device_t */
+
+#define DSL_DEV_PRIVATE(dev) ((ifx_mei_device_private_t*)(dev->pPriv))
+
+typedef struct DSL_DEV_Version /* ifx_adsl_bsp_version */
+{
+ unsigned long major;
+ unsigned long minor;
+ unsigned long revision;
+} DSL_DEV_Version_t; /* ifx_adsl_bsp_version_t */
+
+typedef struct DSL_DEV_ChipInfo
+{
+ unsigned long major;
+ unsigned long minor;
+} DSL_DEV_HwVersion_t;
+
+typedef struct
+{
+ DSL_uint8_t dummy;
+} DSL_DEV_DeviceConfig_t;
+
+/** error code definitions */
+typedef enum DSL_DEV_MeiError
+{
+ DSL_DEV_MEI_ERR_SUCCESS = 0,
+ DSL_DEV_MEI_ERR_FAILURE = -1,
+ DSL_DEV_MEI_ERR_MAILBOX_FULL = -2,
+ DSL_DEV_MEI_ERR_MAILBOX_EMPTY = -3,
+ DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT = -4
+} DSL_DEV_MeiError_t; /* MEI_ERROR */
+
+typedef enum {
+ DSL_BSP_MEMORY_READ=0,
+ DSL_BSP_MEMORY_WRITE,
+} DSL_BSP_MemoryAccessType_t; /* ifx_adsl_memory_access_type_t */
+
+typedef enum
+{
+ DSL_LED_LINK_ID=0,
+ DSL_LED_DATA_ID
+} DSL_DEV_LedId_t; /* ifx_adsl_led_id_t */
+
+typedef enum
+{
+ DSL_LED_LINK_TYPE=0,
+ DSL_LED_DATA_TYPE
+} DSL_DEV_LedType_t; /* ifx_adsl_led_type_t */
+
+typedef enum
+{
+ DSL_LED_HD_CPU=0,
+ DSL_LED_HD_FW
+} DSL_DEV_LedHandler_t; /* ifx_adsl_led_handler_t */
+
+typedef enum {
+ DSL_LED_ON=0,
+ DSL_LED_OFF,
+ DSL_LED_FLASH,
+} DSL_DEV_LedMode_t; /* ifx_adsl_led_mode_t */
+
+typedef enum {
+ DSL_CPU_HALT=0,
+ DSL_CPU_RUN,
+ DSL_CPU_RESET,
+} DSL_DEV_CpuMode_t; /* ifx_adsl_cpu_mode_t */
+
+#if 0
+typedef enum {
+ DSL_BSP_EVENT_DYING_GASP = 0,
+ DSL_BSP_EVENT_CEOC_IRQ,
+} DSL_BSP_Event_id_t; /* ifx_adsl_event_id_t */
+
+typedef union DSL_BSP_CB_Param
+{
+ DSL_uint32_t nIrqMessage;
+} DSL_BSP_CB_Param_t; /* ifx_adsl_cbparam_t */
+
+typedef struct DSL_BSP_CB_Event
+{
+ DSL_BSP_Event_id_t nID;
+ DSL_DEV_Device_t *pDev;
+ DSL_BSP_CB_Param_t *pParam;
+} DSL_BSP_CB_Event_t; /* ifx_adsl_cb_event_t */
+#endif
+
+/* external functions (from the BSP Driver) */
+extern DSL_DEV_Device_t* DSL_BSP_DriverHandleGet(int, int);
+extern DSL_int_t DSL_BSP_DriverHandleDelete(DSL_DEV_Device_t *);
+extern DSL_DEV_MeiError_t DSL_BSP_FWDownload(DSL_DEV_Device_t *, const DSL_char_t *, DSL_uint32_t, DSL_int32_t *, DSL_int32_t *);
+extern int DSL_BSP_KernelIoctls(DSL_DEV_Device_t *, unsigned int, unsigned long);
+extern DSL_DEV_MeiError_t DSL_BSP_SendCMV(DSL_DEV_Device_t *, DSL_uint16_t *, DSL_int_t, DSL_uint16_t *);
+extern DSL_DEV_MeiError_t DSL_BSP_AdslLedInit(DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedType_t, DSL_DEV_LedHandler_t);
+extern DSL_DEV_MeiError_t DSL_BSP_Showtime(DSL_DEV_Device_t *, DSL_uint32_t, DSL_uint32_t);
+extern int DSL_BSP_ATMLedCBRegister( int (*ifx_adsl_ledcallback)(void));
+extern DSL_DEV_MeiError_t DSL_BSP_MemoryDebugAccess(DSL_DEV_Device_t *, DSL_BSP_MemoryAccessType_t, DSL_uint32_t, DSL_uint32_t *, DSL_uint32_t);
+extern volatile DSL_DEV_Device_t *adsl_dev;
+
+/**
+ * Dummy structure by now to show mechanism of extended data that will be
+ * provided within event callback itself.
+ * */
+typedef struct
+{
+ /**
+ * Dummy value */
+ DSL_uint32_t nDummy1;
+} DSL_BSP_CB_Event1DataDummy_t;
+
+/**
+ * Dummy structure by now to show mechanism of extended data that will be
+ * provided within event callback itself.
+ * */
+typedef struct
+{
+ /**
+ * Dummy value */
+ DSL_uint32_t nDummy2;
+} DSL_BSP_CB_Event2DataDummy_t;
+
+/**
+ * encapsulate all data structures that are necessary for status event
+ * callbacks.
+ * */
+typedef union
+{
+ DSL_BSP_CB_Event1DataDummy_t dataEvent1;
+ DSL_BSP_CB_Event2DataDummy_t dataEvent2;
+} DSL_BSP_CB_DATA_Union_t;
+
+
+typedef enum
+{
+ /**
+ * Informs the upper layer driver (DSL CPE API) about a reboot request from the
+ * firmware.
+ * \note This event does NOT include any additional data.
+ * More detailed information upon reboot reason has to be requested from
+ * upper layer software via CMV (INFO 109) if necessary. */
+ DSL_BSP_CB_FIRST = 0,
+ DSL_BSP_CB_DYING_GASP,
+ DSL_BSP_CB_CEOC_IRQ,
+ DSL_BSP_CB_FIRMWARE_REBOOT,
+ /**
+ * Delimiter only */
+ DSL_BSP_CB_LAST
+} DSL_BSP_CB_Type_t;
+
+/**
+ * Specifies the common event type that has to be used for registering and
+ * signalling of interrupts/autonomous status events from MEI BSP Driver.
+ *
+ * \param pDev
+ * Context pointer from MEI BSP Driver.
+ *
+ * \param IFX_ADSL_BSP_CallbackType_t
+ * Specifies the event callback type (reason of callback). Regrading to the
+ * setting of this value the data which is included in the following union
+ * might have different meanings.
+ * Please refer to the description of the union to get information about the
+ * meaning of the included data.
+ *
+ * \param pData
+ * Data according to \ref DSL_BSP_CB_DATA_Union_t.
+ * If this pointer is NULL there is no additional data available.
+ *
+ * \return depending on event
+ */
+typedef int (*DSL_BSP_EventCallback_t)
+(
+ DSL_DEV_Device_t *pDev,
+ DSL_BSP_CB_Type_t nCallbackType,
+ DSL_BSP_CB_DATA_Union_t *pData
+);
+
+typedef struct {
+ DSL_BSP_EventCallback_t function;
+ DSL_BSP_CB_Type_t event;
+ DSL_BSP_CB_DATA_Union_t *pData;
+} DSL_BSP_EventCallBack_t;
+
+extern int DSL_BSP_EventCBRegister(DSL_BSP_EventCallBack_t *);
+extern int DSL_BSP_EventCBUnregister(DSL_BSP_EventCallBack_t *);
+
+/** Modem states */
+#define DSL_DEV_STAT_InitState 0x0000
+#define DSL_DEV_STAT_ReadyState 0x0001
+#define DSL_DEV_STAT_FailState 0x0002
+#define DSL_DEV_STAT_IdleState 0x0003
+#define DSL_DEV_STAT_QuietState 0x0004
+#define DSL_DEV_STAT_GhsState 0x0005
+#define DSL_DEV_STAT_FullInitState 0x0006
+#define DSL_DEV_STAT_ShowTimeState 0x0007
+#define DSL_DEV_STAT_FastRetrainState 0x0008
+#define DSL_DEV_STAT_LoopDiagMode 0x0009
+#define DSL_DEV_STAT_ShortInit 0x000A /* Bis short initialization */
+
+#define DSL_DEV_STAT_CODESWAP_COMPLETE 0x0002
+
+#endif //IFXMIPS_MEI_H
diff --git a/package/kernel/lantiq/ltq-adsl-mei/src/lantiq_mei.c b/package/kernel/lantiq/ltq-adsl-mei/src/lantiq_mei.c
new file mode 100644
index 0000000000..443b9d90ac
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-mei/src/lantiq_mei.c
@@ -0,0 +1,2805 @@
+/******************************************************************************
+
+ Copyright (c) 2009
+ Infineon Technologies AG
+ Am Campeon 1-12; 81726 Munich, Germany
+
+ For licensing information, see the file 'LICENSE' in the root folder of
+ this software module.
+
+******************************************************************************/
+
+/*!
+ \defgroup AMAZON_S_MEI Amazon-S MEI Driver Module
+ \brief Amazon-S MEI driver module
+ */
+
+/*!
+ \defgroup Internal Compile Parametere
+ \ingroup AMAZON_S_MEI
+ \brief exported functions for other driver use
+ */
+
+/*!
+ \file amazon_s_mei_bsp.c
+ \ingroup AMAZON_S_MEI
+ \brief Amazon-S MEI driver file
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <generated/utsrelease.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/sched.h>
+#include <linux/platform_device.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+
+#include "lantiq_atm.h"
+#include <lantiq_soc.h>
+//#include "ifxmips_atm.h"
+#define IFX_MEI_BSP
+#include "ifxmips_mei_interface.h"
+
+/*#define LTQ_RCU_RST IFX_RCU_RST_REQ
+#define LTQ_RCU_RST_REQ_ARC_JTAG IFX_RCU_RST_REQ_ARC_JTAG
+#define LTQ_RCU_RST_REQ_DFE IFX_RCU_RST_REQ_DFE
+#define LTQ_RCU_RST_REQ_AFE IFX_RCU_RST_REQ_AFE
+#define IFXMIPS_FUSE_BASE_ADDR IFX_FUSE_BASE_ADDR
+#define IFXMIPS_ICU_IM0_IER IFX_ICU_IM0_IER
+#define IFXMIPS_ICU_IM2_IER IFX_ICU_IM2_IER
+#define LTQ_MEI_INT IFX_MEI_INT
+#define LTQ_MEI_DYING_GASP_INT IFX_MEI_DYING_GASP_INT
+#define LTQ_MEI_BASE_ADDR IFX_MEI_SPACE_ACCESS
+#define IFXMIPS_PMU_PWDCR IFX_PMU_PWDCR
+#define IFXMIPS_MPS_CHIPID IFX_MPS_CHIPID
+
+#define ifxmips_port_reserve_pin ifx_gpio_pin_reserve
+#define ifxmips_port_set_dir_in ifx_gpio_dir_in_set
+#define ifxmips_port_clear_altsel0 ifx_gpio_altsel0_set
+#define ifxmips_port_clear_altsel1 ifx_gpio_altsel1_clear
+#define ifxmips_port_set_open_drain ifx_gpio_open_drain_clear
+#define ifxmips_port_free_pin ifx_gpio_pin_free
+#define ifxmips_mask_and_ack_irq bsp_mask_and_ack_irq
+#define IFXMIPS_MPS_CHIPID_VERSION_GET IFX_MCD_CHIPID_VERSION_GET
+#define ltq_r32(reg) __raw_readl(reg)
+#define ltq_w32(val, reg) __raw_writel(val, reg)
+#define ltq_w32_mask(clear, set, reg) ltq_w32((ltq_r32(reg) & ~clear) | set, reg)
+*/
+
+#define LTQ_RCU_BASE_ADDR 0x1F203000
+#define LTQ_ICU_BASE_ADDR 0x1F880200
+#define LTQ_MEI_BASE_ADDR 0x1E116000
+#define LTQ_PMU_BASE_ADDR 0x1F102000
+#define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
+#define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
+#define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
+
+#define LTQ_RCU_RST_REQ_DFE (1 << 7)
+#define LTQ_RCU_RST_REQ_AFE (1 << 11)
+
+#define LTQ_PMU_BASE (KSEG1 + LTQ_PMU_BASE_ADDR)
+#define LTQ_RCU_BASE (KSEG1 + LTQ_RCU_BASE_ADDR)
+#define LTQ_ICU_BASE (KSEG1 + LTQ_ICU_BASE_ADDR)
+
+#define LTQ_PMU_PWDCR ((u32 *)(LTQ_PMU_BASE + 0x001C))
+#define LTQ_PMU_PWDSR ((u32 *)(LTQ_PMU_BASE + 0x0020))
+#define LTQ_RCU_RST ((u32 *)(LTQ_RCU_BASE + 0x0010))
+#define LTQ_RCU_RST_ALL 0x40000000
+
+#define LTQ_ICU_IM0_ISR ((u32 *)(LTQ_ICU_BASE + 0x0000))
+#define LTQ_ICU_IM0_IER ((u32 *)(LTQ_ICU_BASE + 0x0008))
+#define LTQ_ICU_IM0_IOSR ((u32 *)(LTQ_ICU_BASE + 0x0010))
+#define LTQ_ICU_IM0_IRSR ((u32 *)(LTQ_ICU_BASE + 0x0018))
+#define LTQ_ICU_IM0_IMR ((u32 *)(LTQ_ICU_BASE + 0x0020))
+
+
+#define LTQ_ICU_IM1_ISR ((u32 *)(LTQ_ICU_BASE + 0x0028))
+#define LTQ_ICU_IM2_ISR ((u32 *)(LTQ_ICU_BASE + 0x0050))
+#define LTQ_ICU_IM3_ISR ((u32 *)(LTQ_ICU_BASE + 0x0078))
+#define LTQ_ICU_IM4_ISR ((u32 *)(LTQ_ICU_BASE + 0x00A0))
+
+#define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
+#define LTQ_ICU_IM2_IER (LTQ_ICU_IM0_IER + LTQ_ICU_OFFSET)
+
+#define IFX_MEI_EMSG(fmt, args...) pr_err("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
+#define IFX_MEI_DMSG(fmt, args...) pr_debug("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
+
+#define LTQ_FUSE_BASE (KSEG1 + 0x1F107354)
+
+#ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
+//#define DFE_MEM_TEST
+//#define DFE_PING_TEST
+#define DFE_ATM_LOOPBACK
+
+
+#ifdef DFE_ATM_LOOPBACK
+#include <asm/ifxmips/ifxmips_mei_fw_loopback.h>
+#endif
+
+void dfe_loopback_irq_handler (DSL_DEV_Device_t *pDev);
+
+#endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
+
+DSL_DEV_Version_t bsp_mei_version = {
+ major: 5,
+ minor: 0,
+ revision:0
+};
+DSL_DEV_HwVersion_t bsp_chip_info;
+
+#define IFX_MEI_DEVNAME "ifx_mei"
+#define BSP_MAX_DEVICES 1
+#define MEI_DIRNAME "ifxmips_mei"
+
+DSL_DEV_MeiError_t DSL_BSP_FWDownload (DSL_DEV_Device_t *, const char *, unsigned long, long *, long *);
+DSL_DEV_MeiError_t DSL_BSP_Showtime (DSL_DEV_Device_t *, DSL_uint32_t, DSL_uint32_t);
+DSL_DEV_MeiError_t DSL_BSP_AdslLedInit (DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedType_t, DSL_DEV_LedHandler_t);
+//DSL_DEV_MeiError_t DSL_BSP_AdslLedSet (DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedMode_t);
+DSL_DEV_MeiError_t DSL_BSP_MemoryDebugAccess (DSL_DEV_Device_t *, DSL_BSP_MemoryAccessType_t, DSL_uint32_t, DSL_uint32_t*, DSL_uint32_t);
+DSL_DEV_MeiError_t DSL_BSP_SendCMV (DSL_DEV_Device_t *, u16 *, int, u16 *);
+
+int DSL_BSP_KernelIoctls (DSL_DEV_Device_t *, unsigned int, unsigned long);
+
+static DSL_DEV_MeiError_t IFX_MEI_RunAdslModem (DSL_DEV_Device_t *);
+static DSL_DEV_MeiError_t IFX_MEI_CpuModeSet (DSL_DEV_Device_t *, DSL_DEV_CpuMode_t);
+static DSL_DEV_MeiError_t IFX_MEI_DownloadBootCode (DSL_DEV_Device_t *);
+static DSL_DEV_MeiError_t IFX_MEI_ArcJtagEnable (DSL_DEV_Device_t *, int);
+static DSL_DEV_MeiError_t IFX_MEI_AdslMailboxIRQEnable (DSL_DEV_Device_t *, int);
+
+static int IFX_MEI_GetPage (DSL_DEV_Device_t *, u32, u32, u32, u32 *, u32 *);
+static int IFX_MEI_BarUpdate (DSL_DEV_Device_t *, int);
+
+static ssize_t IFX_MEI_Write (DSL_DRV_file_t *, const char *, size_t, loff_t *);
+static long IFX_MEI_UserIoctls (DSL_DRV_file_t *, unsigned int, unsigned long);
+static int IFX_MEI_Open (DSL_DRV_inode_t *, DSL_DRV_file_t *);
+static int IFX_MEI_Release (DSL_DRV_inode_t *, DSL_DRV_file_t *);
+
+void AMAZON_SE_MEI_ARC_MUX_Test(void);
+
+void IFX_MEI_ARC_MUX_Test(void);
+
+static int adsl_dummy_ledcallback(void);
+
+int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *) = NULL;
+EXPORT_SYMBOL(ifx_mei_atm_showtime_enter);
+
+int (*ifx_mei_atm_showtime_exit)(void) = NULL;
+EXPORT_SYMBOL(ifx_mei_atm_showtime_exit);
+
+static int (*g_adsl_ledcallback)(void) = adsl_dummy_ledcallback;
+
+static unsigned int g_tx_link_rate[2] = {0};
+
+static void *g_xdata_addr = NULL;
+
+static u32 *mei_arc_swap_buff = NULL; // holding swap pages
+
+extern void ltq_mask_and_ack_irq(struct irq_data *d);
+static void inline MEI_MASK_AND_ACK_IRQ(int x)
+{
+ struct irq_data d;
+ d.hwirq = x;
+ ltq_mask_and_ack_irq(&d);
+}
+#define MEI_MAJOR 105
+static int dev_major = MEI_MAJOR;
+
+static struct file_operations bsp_mei_operations = {
+ owner:THIS_MODULE,
+ open:IFX_MEI_Open,
+ release:IFX_MEI_Release,
+ write:IFX_MEI_Write,
+ unlocked_ioctl:IFX_MEI_UserIoctls,
+};
+
+static DSL_DEV_Device_t dsl_devices[BSP_MAX_DEVICES];
+
+static ifx_mei_device_private_t
+ sDanube_Mei_Private[BSP_MAX_DEVICES];
+
+static DSL_BSP_EventCallBack_t dsl_bsp_event_callback[DSL_BSP_CB_LAST + 1];
+
+/**
+ * Write a value to register
+ * This function writes a value to danube register
+ *
+ * \param ul_address The address to write
+ * \param ul_data The value to write
+ * \ingroup Internal
+ */
+static void
+IFX_MEI_LongWordWrite (u32 ul_address, u32 ul_data)
+{
+ IFX_MEI_WRITE_REGISTER_L (ul_data, ul_address);
+ wmb();
+ return;
+}
+
+/**
+ * Write a value to register
+ * This function writes a value to danube register
+ *
+ * \param pDev the device pointer
+ * \param ul_address The address to write
+ * \param ul_data The value to write
+ * \ingroup Internal
+ */
+static void
+IFX_MEI_LongWordWriteOffset (DSL_DEV_Device_t * pDev, u32 ul_address,
+ u32 ul_data)
+{
+ IFX_MEI_WRITE_REGISTER_L (ul_data, pDev->base_address + ul_address);
+ wmb();
+ return;
+}
+
+/**
+ * Read the danube register
+ * This function read the value from danube register
+ *
+ * \param ul_address The address to write
+ * \param pul_data Pointer to the data
+ * \ingroup Internal
+ */
+static void
+IFX_MEI_LongWordRead (u32 ul_address, u32 * pul_data)
+{
+ *pul_data = IFX_MEI_READ_REGISTER_L (ul_address);
+ rmb();
+ return;
+}
+
+/**
+ * Read the danube register
+ * This function read the value from danube register
+ *
+ * \param pDev the device pointer
+ * \param ul_address The address to write
+ * \param pul_data Pointer to the data
+ * \ingroup Internal
+ */
+static void
+IFX_MEI_LongWordReadOffset (DSL_DEV_Device_t * pDev, u32 ul_address,
+ u32 * pul_data)
+{
+ *pul_data = IFX_MEI_READ_REGISTER_L (pDev->base_address + ul_address);
+ rmb();
+ return;
+}
+
+/**
+ * Write several DWORD datas to ARC memory via ARC DMA interface
+ * This function writes several DWORD datas to ARC memory via DMA interface.
+ *
+ * \param pDev the device pointer
+ * \param destaddr The address to write
+ * \param databuff Pointer to the data buffer
+ * \param databuffsize Number of DWORDs to write
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_DMAWrite (DSL_DEV_Device_t * pDev, u32 destaddr,
+ u32 * databuff, u32 databuffsize)
+{
+ u32 *p = databuff;
+ u32 temp;
+
+ if (destaddr & 3)
+ return DSL_DEV_MEI_ERR_FAILURE;
+
+ // Set the write transfer address
+ IFX_MEI_LongWordWriteOffset (pDev, ME_DX_AD, destaddr);
+
+ // Write the data pushed across DMA
+ while (databuffsize--) {
+ temp = *p;
+ if (destaddr == MEI_TO_ARC_MAILBOX)
+ MEI_HALF_WORD_SWAP (temp);
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DX_DATA, temp);
+ p++;
+ }
+
+ return DSL_DEV_MEI_ERR_SUCCESS;
+
+}
+
+/**
+ * Read several DWORD datas from ARC memory via ARC DMA interface
+ * This function reads several DWORD datas from ARC memory via DMA interface.
+ *
+ * \param pDev the device pointer
+ * \param srcaddr The address to read
+ * \param databuff Pointer to the data buffer
+ * \param databuffsize Number of DWORDs to read
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_DMARead (DSL_DEV_Device_t * pDev, u32 srcaddr, u32 * databuff,
+ u32 databuffsize)
+{
+ u32 *p = databuff;
+ u32 temp;
+
+ if (srcaddr & 3)
+ return DSL_DEV_MEI_ERR_FAILURE;
+
+ // Set the read transfer address
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DX_AD, srcaddr);
+
+ // Read the data popped across DMA
+ while (databuffsize--) {
+ IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DX_DATA, &temp);
+ if (databuff == (u32 *) DSL_DEV_PRIVATE(pDev)->CMV_RxMsg) // swap half word
+ MEI_HALF_WORD_SWAP (temp);
+ *p = temp;
+ p++;
+ }
+
+ return DSL_DEV_MEI_ERR_SUCCESS;
+
+}
+
+/**
+ * Switch the ARC control mode
+ * This function switchs the ARC control mode to JTAG mode or MEI mode
+ *
+ * \param pDev the device pointer
+ * \param mode The mode want to switch: JTAG_MASTER_MODE or MEI_MASTER_MODE.
+ * \ingroup Internal
+ */
+static void
+IFX_MEI_ControlModeSet (DSL_DEV_Device_t * pDev, int mode)
+{
+ u32 temp = 0x0;
+
+ IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DBG_MASTER, &temp);
+ switch (mode) {
+ case JTAG_MASTER_MODE:
+ temp &= ~(HOST_MSTR);
+ break;
+ case MEI_MASTER_MODE:
+ temp |= (HOST_MSTR);
+ break;
+ default:
+ IFX_MEI_EMSG ("IFX_MEI_ControlModeSet: unkonwn mode [%d]\n", mode);
+ return;
+ }
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_MASTER, temp);
+}
+
+/**
+ * Disable ARC to MEI interrupt
+ *
+ * \param pDev the device pointer
+ * \ingroup Internal
+ */
+static void
+IFX_MEI_IRQDisable (DSL_DEV_Device_t * pDev)
+{
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_MASK, 0x0);
+}
+
+/**
+ * Eable ARC to MEI interrupt
+ *
+ * \param pDev the device pointer
+ * \ingroup Internal
+ */
+static void
+IFX_MEI_IRQEnable (DSL_DEV_Device_t * pDev)
+{
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_MASK, MSGAV_EN);
+}
+
+/**
+ * Poll for transaction complete signal
+ * This function polls and waits for transaction complete signal.
+ *
+ * \param pDev the device pointer
+ * \ingroup Internal
+ */
+static void
+meiPollForDbgDone (DSL_DEV_Device_t * pDev)
+{
+ u32 query = 0;
+ int i = 0;
+
+ while (i < WHILE_DELAY) {
+ IFX_MEI_LongWordReadOffset (pDev, (u32) ME_ARC2ME_STAT, &query);
+ query &= (ARC_TO_MEI_DBG_DONE);
+ if (query)
+ break;
+ i++;
+ if (i == WHILE_DELAY) {
+ IFX_MEI_EMSG ("PollforDbg fail!\n");
+ }
+ }
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_DBG_DONE); // to clear this interrupt
+}
+
+/**
+ * ARC Debug Memory Access for a single DWORD reading.
+ * This function used for direct, address-based access to ARC memory.
+ *
+ * \param pDev the device pointer
+ * \param DEC_mode ARC memory space to used
+ * \param address Address to read
+ * \param data Pointer to data
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+_IFX_MEI_DBGLongWordRead (DSL_DEV_Device_t * pDev, u32 DEC_mode,
+ u32 address, u32 * data)
+{
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DECODE, DEC_mode);
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_RD_AD, address);
+ meiPollForDbgDone (pDev);
+ IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DBG_DATA, data);
+ return DSL_DEV_MEI_ERR_SUCCESS;
+}
+
+/**
+ * ARC Debug Memory Access for a single DWORD writing.
+ * This function used for direct, address-based access to ARC memory.
+ *
+ * \param pDev the device pointer
+ * \param DEC_mode ARC memory space to used
+ * \param address The address to write
+ * \param data The data to write
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+_IFX_MEI_DBGLongWordWrite (DSL_DEV_Device_t * pDev, u32 DEC_mode,
+ u32 address, u32 data)
+{
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DECODE, DEC_mode);
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_WR_AD, address);
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DATA, data);
+ meiPollForDbgDone (pDev);
+ return DSL_DEV_MEI_ERR_SUCCESS;
+}
+
+/**
+ * ARC Debug Memory Access for writing.
+ * This function used for direct, address-based access to ARC memory.
+ *
+ * \param pDev the device pointer
+ * \param destaddr The address to read
+ * \param databuffer Pointer to data
+ * \param databuffsize The number of DWORDs to read
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+
+static DSL_DEV_MeiError_t
+IFX_MEI_DebugWrite (DSL_DEV_Device_t * pDev, u32 destaddr,
+ u32 * databuff, u32 databuffsize)
+{
+ u32 i;
+ u32 temp = 0x0;
+ u32 address = 0x0;
+ u32 *buffer = 0x0;
+
+ // Open the debug port before DMP memory write
+ IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
+
+ // For the requested length, write the address and write the data
+ address = destaddr;
+ buffer = databuff;
+ for (i = 0; i < databuffsize; i++) {
+ temp = *buffer;
+ _IFX_MEI_DBGLongWordWrite (pDev, ME_DBG_DECODE_DMP1_MASK, address, temp);
+ address += 4;
+ buffer++;
+ }
+
+ // Close the debug port after DMP memory write
+ IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
+
+ return DSL_DEV_MEI_ERR_SUCCESS;
+}
+
+/**
+ * ARC Debug Memory Access for reading.
+ * This function used for direct, address-based access to ARC memory.
+ *
+ * \param pDev the device pointer
+ * \param srcaddr The address to read
+ * \param databuffer Pointer to data
+ * \param databuffsize The number of DWORDs to read
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_DebugRead (DSL_DEV_Device_t * pDev, u32 srcaddr, u32 * databuff, u32 databuffsize)
+{
+ u32 i;
+ u32 temp = 0x0;
+ u32 address = 0x0;
+ u32 *buffer = 0x0;
+
+ // Open the debug port before DMP memory read
+ IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
+
+ // For the requested length, write the address and read the data
+ address = srcaddr;
+ buffer = databuff;
+ for (i = 0; i < databuffsize; i++) {
+ _IFX_MEI_DBGLongWordRead (pDev, ME_DBG_DECODE_DMP1_MASK, address, &temp);
+ *buffer = temp;
+ address += 4;
+ buffer++;
+ }
+
+ // Close the debug port after DMP memory read
+ IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
+
+ return DSL_DEV_MEI_ERR_SUCCESS;
+}
+
+/**
+ * Send a message to ARC MailBox.
+ * This function sends a message to ARC Mailbox via ARC DMA interface.
+ *
+ * \param pDev the device pointer
+ * \param msgsrcbuffer Pointer to message.
+ * \param msgsize The number of words to write.
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_MailboxWrite (DSL_DEV_Device_t * pDev, u16 * msgsrcbuffer,
+ u16 msgsize)
+{
+ int i;
+ u32 arc_mailbox_status = 0x0;
+ u32 temp = 0;
+ DSL_DEV_MeiError_t meiMailboxError = DSL_DEV_MEI_ERR_SUCCESS;
+
+ // Write to mailbox
+ meiMailboxError =
+ IFX_MEI_DMAWrite (pDev, MEI_TO_ARC_MAILBOX, (u32 *) msgsrcbuffer, msgsize / 2);
+ meiMailboxError =
+ IFX_MEI_DMAWrite (pDev, MEI_TO_ARC_MAILBOXR, (u32 *) (&temp), 1);
+
+ // Notify arc that mailbox write completed
+ DSL_DEV_PRIVATE(pDev)->cmv_waiting = 1;
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ME2ARC_INT, MEI_TO_ARC_MSGAV);
+
+ i = 0;
+ while (i < WHILE_DELAY) { // wait for ARC to clear the bit
+ IFX_MEI_LongWordReadOffset (pDev, (u32) ME_ME2ARC_INT, &arc_mailbox_status);
+ if ((arc_mailbox_status & MEI_TO_ARC_MSGAV) != MEI_TO_ARC_MSGAV)
+ break;
+ i++;
+ if (i == WHILE_DELAY) {
+ IFX_MEI_EMSG (">>> Timeout waiting for ARC to clear MEI_TO_ARC_MSGAV!!!"
+ " MEI_TO_ARC message size = %d DWORDs <<<\n", msgsize/2);
+ meiMailboxError = DSL_DEV_MEI_ERR_FAILURE;
+ }
+ }
+
+ return meiMailboxError;
+}
+
+/**
+ * Read a message from ARC MailBox.
+ * This function reads a message from ARC Mailbox via ARC DMA interface.
+ *
+ * \param pDev the device pointer
+ * \param msgsrcbuffer Pointer to message.
+ * \param msgsize The number of words to read
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_MailboxRead (DSL_DEV_Device_t * pDev, u16 * msgdestbuffer,
+ u16 msgsize)
+{
+ DSL_DEV_MeiError_t meiMailboxError = DSL_DEV_MEI_ERR_SUCCESS;
+ // Read from mailbox
+ meiMailboxError =
+ IFX_MEI_DMARead (pDev, ARC_TO_MEI_MAILBOX, (u32 *) msgdestbuffer, msgsize / 2);
+
+ // Notify arc that mailbox read completed
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
+
+ return meiMailboxError;
+}
+
+/**
+ * Download boot pages to ARC.
+ * This function downloads boot pages to ARC.
+ *
+ * \param pDev the device pointer
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_DownloadBootPages (DSL_DEV_Device_t * pDev)
+{
+ int boot_loop;
+ int page_size;
+ u32 dest_addr;
+
+ /*
+ ** DMA the boot code page(s)
+ */
+
+ for (boot_loop = 1;
+ boot_loop <
+ (DSL_DEV_PRIVATE(pDev)->img_hdr-> count); boot_loop++) {
+ if ((DSL_DEV_PRIVATE(pDev)-> img_hdr->page[boot_loop].p_size) & BOOT_FLAG) {
+ page_size = IFX_MEI_GetPage (pDev, boot_loop,
+ GET_PROG, MAXSWAPSIZE,
+ mei_arc_swap_buff,
+ &dest_addr);
+ if (page_size > 0) {
+ IFX_MEI_DMAWrite (pDev, dest_addr,
+ mei_arc_swap_buff,
+ page_size);
+ }
+ }
+ if ((DSL_DEV_PRIVATE(pDev)-> img_hdr->page[boot_loop].d_size) & BOOT_FLAG) {
+ page_size = IFX_MEI_GetPage (pDev, boot_loop,
+ GET_DATA, MAXSWAPSIZE,
+ mei_arc_swap_buff,
+ &dest_addr);
+ if (page_size > 0) {
+ IFX_MEI_DMAWrite (pDev, dest_addr,
+ mei_arc_swap_buff,
+ page_size);
+ }
+ }
+ }
+ return DSL_DEV_MEI_ERR_SUCCESS;
+}
+
+/**
+ * Initial efuse rar.
+ **/
+static void
+IFX_MEI_FuseInit (DSL_DEV_Device_t * pDev)
+{
+ u32 data = 0;
+ IFX_MEI_DMAWrite (pDev, IRAM0_BASE, &data, 1);
+ IFX_MEI_DMAWrite (pDev, IRAM0_BASE + 4, &data, 1);
+ IFX_MEI_DMAWrite (pDev, IRAM1_BASE, &data, 1);
+ IFX_MEI_DMAWrite (pDev, IRAM1_BASE + 4, &data, 1);
+ IFX_MEI_DMAWrite (pDev, BRAM_BASE, &data, 1);
+ IFX_MEI_DMAWrite (pDev, BRAM_BASE + 4, &data, 1);
+ IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE, &data, 1);
+ IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE + 4, &data, 1);
+}
+
+/**
+ * efuse rar program
+ **/
+static void
+IFX_MEI_FuseProg (DSL_DEV_Device_t * pDev)
+{
+ u32 reg_data, fuse_value;
+ int i = 0;
+
+ IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, &reg_data);
+ while ((reg_data & 0x10000000) == 0) {
+ IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, &reg_data);
+ i++;
+ /* 0x4000 translate to about 16 ms@111M, so should be enough */
+ if (i == 0x4000)
+ return;
+ }
+ // STEP a: Prepare memory for external accesses
+ // Write fuse_en bit24
+ IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, &reg_data);
+ IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST, reg_data | (1 << 24));
+
+ IFX_MEI_FuseInit (pDev);
+ for (i = 0; i < 4; i++) {
+ IFX_MEI_LongWordRead ((u32) (LTQ_FUSE_BASE) + i * 4, &fuse_value);
+ switch (fuse_value & 0xF0000) {
+ case 0x80000:
+ reg_data = ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
+ (RX_DILV_ADDR_BIT_MASK + 0x1));
+ IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE, &reg_data, 1);
+ break;
+ case 0x90000:
+ reg_data = ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
+ (RX_DILV_ADDR_BIT_MASK + 0x1));
+ IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE + 4, &reg_data, 1);
+ break;
+ case 0xA0000:
+ reg_data = ((fuse_value & IRAM0_ADDR_BIT_MASK) |
+ (IRAM0_ADDR_BIT_MASK + 0x1));
+ IFX_MEI_DMAWrite (pDev, IRAM0_BASE, &reg_data, 1);
+ break;
+ case 0xB0000:
+ reg_data = ((fuse_value & IRAM0_ADDR_BIT_MASK) |
+ (IRAM0_ADDR_BIT_MASK + 0x1));
+ IFX_MEI_DMAWrite (pDev, IRAM0_BASE + 4, &reg_data, 1);
+ break;
+ case 0xC0000:
+ reg_data = ((fuse_value & IRAM1_ADDR_BIT_MASK) |
+ (IRAM1_ADDR_BIT_MASK + 0x1));
+ IFX_MEI_DMAWrite (pDev, IRAM1_BASE, &reg_data, 1);
+ break;
+ case 0xD0000:
+ reg_data = ((fuse_value & IRAM1_ADDR_BIT_MASK) |
+ (IRAM1_ADDR_BIT_MASK + 0x1));
+ IFX_MEI_DMAWrite (pDev, IRAM1_BASE + 4, &reg_data, 1);
+ break;
+ case 0xE0000:
+ reg_data = ((fuse_value & BRAM_ADDR_BIT_MASK) |
+ (BRAM_ADDR_BIT_MASK + 0x1));
+ IFX_MEI_DMAWrite (pDev, BRAM_BASE, &reg_data, 1);
+ break;
+ case 0xF0000:
+ reg_data = ((fuse_value & BRAM_ADDR_BIT_MASK) |
+ (BRAM_ADDR_BIT_MASK + 0x1));
+ IFX_MEI_DMAWrite (pDev, BRAM_BASE + 4, &reg_data, 1);
+ break;
+ default: // PPE efuse
+ break;
+ }
+ }
+ IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, &reg_data);
+ IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST, reg_data & ~(1 << 24));
+ IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, &reg_data);
+}
+
+/**
+ * Enable DFE Clock
+ * This function enables DFE Clock
+ *
+ * \param pDev the device pointer
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_EnableCLK (DSL_DEV_Device_t * pDev)
+{
+ u32 arc_debug_data = 0;
+ IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
+ //enable ac_clk signal
+ _IFX_MEI_DBGLongWordRead (pDev, ME_DBG_DECODE_DMP1_MASK,
+ CRI_CCR0, &arc_debug_data);
+ arc_debug_data |= ACL_CLK_MODE_ENABLE;
+ _IFX_MEI_DBGLongWordWrite (pDev, ME_DBG_DECODE_DMP1_MASK,
+ CRI_CCR0, arc_debug_data);
+ IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
+ return DSL_DEV_MEI_ERR_SUCCESS;
+}
+
+/**
+ * Halt the ARC.
+ * This function halts the ARC.
+ *
+ * \param pDev the device pointer
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_HaltArc (DSL_DEV_Device_t * pDev)
+{
+ u32 arc_debug_data = 0x0;
+
+ // Switch arc control from JTAG mode to MEI mode
+ IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
+ _IFX_MEI_DBGLongWordRead (pDev, MEI_DEBUG_DEC_AUX_MASK,
+ ARC_DEBUG, &arc_debug_data);
+ arc_debug_data |= ARC_DEBUG_HALT;
+ _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
+ ARC_DEBUG, arc_debug_data);
+ // Switch arc control from MEI mode to JTAG mode
+ IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
+
+ MEI_WAIT (10);
+
+ return DSL_DEV_MEI_ERR_SUCCESS;
+}
+
+/**
+ * Run the ARC.
+ * This function runs the ARC.
+ *
+ * \param pDev the device pointer
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_RunArc (DSL_DEV_Device_t * pDev)
+{
+ u32 arc_debug_data = 0x0;
+
+ // Switch arc control from JTAG mode to MEI mode- write '1' to bit0
+ IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
+ _IFX_MEI_DBGLongWordRead (pDev, MEI_DEBUG_DEC_AUX_MASK,
+ AUX_STATUS, &arc_debug_data);
+
+ // Write debug data reg with content ANDd with 0xFDFFFFFF (halt bit cleared)
+ arc_debug_data &= ~ARC_AUX_HALT;
+ _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
+ AUX_STATUS, arc_debug_data);
+
+ // Switch arc control from MEI mode to JTAG mode- write '0' to bit0
+ IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
+ // Enable mask for arc codeswap interrupts
+ IFX_MEI_IRQEnable (pDev);
+
+ return DSL_DEV_MEI_ERR_SUCCESS;
+
+}
+
+/**
+ * Reset the ARC.
+ * This function resets the ARC.
+ *
+ * \param pDev the device pointer
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_ResetARC (DSL_DEV_Device_t * pDev)
+{
+ u32 arc_debug_data = 0;
+
+ IFX_MEI_HaltArc (pDev);
+
+ IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, &arc_debug_data);
+ IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST,
+ arc_debug_data | LTQ_RCU_RST_REQ_DFE | LTQ_RCU_RST_REQ_AFE);
+
+ // reset ARC
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_RST_CTRL, MEI_SOFT_RESET);
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_RST_CTRL, 0);
+
+ IFX_MEI_IRQDisable (pDev);
+
+ IFX_MEI_EnableCLK (pDev);
+
+#if 0
+ // reset part of PPE
+ *(unsigned long *) (BSP_PPE32_SRST) = 0xC30;
+ *(unsigned long *) (BSP_PPE32_SRST) = 0xFFF;
+#endif
+
+ DSL_DEV_PRIVATE(pDev)->modem_ready = 0;
+
+ return DSL_DEV_MEI_ERR_SUCCESS;
+}
+
+DSL_DEV_MeiError_t
+DSL_BSP_Showtime (DSL_DEV_Device_t * dev, DSL_uint32_t rate_fast, DSL_uint32_t rate_intl)
+{
+ struct port_cell_info port_cell = {0};
+
+ IFX_MEI_EMSG ("Datarate US intl = %d, fast = %d\n", (int)rate_intl,
+ (int)rate_fast);
+
+ if ( rate_fast )
+ g_tx_link_rate[0] = rate_fast / (53 * 8);
+ if ( rate_intl )
+ g_tx_link_rate[1] = rate_intl / (53 * 8);
+
+ if ( g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 ) {
+ IFX_MEI_EMSG ("Got rate fail.\n");
+ }
+
+ if ( ifx_mei_atm_showtime_enter )
+ {
+ port_cell.port_num = 2;
+ port_cell.tx_link_rate[0] = g_tx_link_rate[0];
+ port_cell.tx_link_rate[1] = g_tx_link_rate[1];
+ ifx_mei_atm_showtime_enter(&port_cell, g_xdata_addr);
+ }
+ else
+ {
+ IFX_MEI_EMSG("no hookup from ATM driver to set cell rate\n");
+ }
+
+ return DSL_DEV_MEI_ERR_SUCCESS;
+};
+
+/**
+ * Reset/halt/run the DFE.
+ * This function provide operations to reset/halt/run the DFE.
+ *
+ * \param pDev the device pointer
+ * \param mode which operation want to do
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_CpuModeSet (DSL_DEV_Device_t *pDev,
+ DSL_DEV_CpuMode_t mode)
+{
+ DSL_DEV_MeiError_t err_ret = DSL_DEV_MEI_ERR_FAILURE;
+ switch (mode) {
+ case DSL_CPU_HALT:
+ err_ret = IFX_MEI_HaltArc (pDev);
+ break;
+ case DSL_CPU_RUN:
+ err_ret = IFX_MEI_RunArc (pDev);
+ break;
+ case DSL_CPU_RESET:
+ err_ret = IFX_MEI_ResetARC (pDev);
+ break;
+ default:
+ break;
+ }
+ return err_ret;
+}
+
+/**
+ * Accress DFE memory.
+ * This function provide a way to access DFE memory;
+ *
+ * \param pDev the device pointer
+ * \param type read or write
+ * \param destaddr destination address
+ * \param databuff pointer to hold data
+ * \param databuffsize size want to read/write
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+DSL_DEV_MeiError_t
+DSL_BSP_MemoryDebugAccess (DSL_DEV_Device_t * pDev,
+ DSL_BSP_MemoryAccessType_t type,
+ DSL_uint32_t destaddr, DSL_uint32_t *databuff,
+ DSL_uint32_t databuffsize)
+{
+ DSL_DEV_MeiError_t meierr = DSL_DEV_MEI_ERR_SUCCESS;
+ switch (type) {
+ case DSL_BSP_MEMORY_READ:
+ meierr = IFX_MEI_DebugRead (pDev, (u32)destaddr, (u32*)databuff, (u32)databuffsize);
+ break;
+ case DSL_BSP_MEMORY_WRITE:
+ meierr = IFX_MEI_DebugWrite (pDev, (u32)destaddr, (u32*)databuff, (u32)databuffsize);
+ break;
+ }
+ return DSL_DEV_MEI_ERR_SUCCESS;
+};
+
+/**
+ * Download boot code to ARC.
+ * This function downloads boot code to ARC.
+ *
+ * \param pDev the device pointer
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_DownloadBootCode (DSL_DEV_Device_t *pDev)
+{
+ IFX_MEI_IRQDisable (pDev);
+
+ IFX_MEI_EnableCLK (pDev);
+
+ IFX_MEI_FuseProg (pDev); //program fuse rar
+
+ IFX_MEI_DownloadBootPages (pDev);
+
+ return DSL_DEV_MEI_ERR_SUCCESS;
+};
+
+/**
+ * Enable Jtag debugger interface
+ * This function setups mips gpio to enable jtag debugger
+ *
+ * \param pDev the device pointer
+ * \param enable enable or disable
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_ArcJtagEnable (DSL_DEV_Device_t *dev, int enable)
+{
+ /*
+ int meierr=0;
+ u32 reg_data;
+ switch (enable) {
+ case 1:
+ //reserve gpio 9, 10, 11, 14, 19 for ARC JTAG
+ ifxmips_port_reserve_pin (0, 9);
+ ifxmips_port_reserve_pin (0, 10);
+ ifxmips_port_reserve_pin (0, 11);
+ ifxmips_port_reserve_pin (0, 14);
+ ifxmips_port_reserve_pin (1, 3);
+
+ ifxmips_port_set_dir_in(0, 11);
+ ifxmips_port_clear_altsel0(0, 11);
+ ifxmips_port_clear_altsel1(0, 11);
+ ifxmips_port_set_open_drain(0, 11);
+ //enable ARC JTAG
+ IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, &reg_data);
+ IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST, reg_data | LTQ_RCU_RST_REQ_ARC_JTAG);
+ break;
+ case 0:
+ default:
+ break;
+ }
+jtag_end:
+ if (meierr)
+ return DSL_DEV_MEI_ERR_FAILURE;
+*/
+
+ return DSL_DEV_MEI_ERR_SUCCESS;
+};
+
+/**
+ * Enable DFE to MIPS interrupt
+ * This function enable DFE to MIPS interrupt
+ *
+ * \param pDev the device pointer
+ * \param enable enable or disable
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_AdslMailboxIRQEnable (DSL_DEV_Device_t *pDev, int enable)
+{
+ DSL_DEV_MeiError_t meierr;
+ switch (enable) {
+ case 0:
+ meierr = DSL_DEV_MEI_ERR_SUCCESS;
+ IFX_MEI_IRQDisable (pDev);
+ break;
+ case 1:
+ IFX_MEI_IRQEnable (pDev);
+ meierr = DSL_DEV_MEI_ERR_SUCCESS;
+ break;
+ default:
+ meierr = DSL_DEV_MEI_ERR_FAILURE;
+ break;
+
+ }
+ return meierr;
+}
+
+/**
+ * Get the modem status
+ * This function return the modem status
+ *
+ * \param pDev the device pointer
+ * \return 1: modem ready 0: not ready
+ * \ingroup Internal
+ */
+static int
+IFX_MEI_IsModemReady (DSL_DEV_Device_t * pDev)
+{
+ return DSL_DEV_PRIVATE(pDev)->modem_ready;
+}
+
+DSL_DEV_MeiError_t
+DSL_BSP_AdslLedInit (DSL_DEV_Device_t * dev,
+ DSL_DEV_LedId_t led_number,
+ DSL_DEV_LedType_t type,
+ DSL_DEV_LedHandler_t handler)
+{
+#if 0
+ struct led_config_param param;
+ if (led_number == DSL_LED_LINK_ID && type == DSL_LED_LINK_TYPE && handler == /*DSL_LED_HD_CPU*/DSL_LED_HD_FW) {
+ param.operation_mask = CONFIG_OPERATION_UPDATE_SOURCE;
+ param.led = 0x01;
+ param.source = 0x01;
+// bsp_led_config (&param);
+
+ } else if (led_number == DSL_LED_DATA_ID && type == DSL_LED_DATA_TYPE && (handler == DSL_LED_HD_FW)) {
+ param.operation_mask = CONFIG_OPERATION_UPDATE_SOURCE;
+ param.led = 0x02;
+ param.source = 0x02;
+// bsp_led_config (&param);
+ }
+#endif
+ return DSL_DEV_MEI_ERR_SUCCESS;
+};
+#if 0
+DSL_DEV_MeiError_t
+DSL_BSP_AdslLedSet (DSL_DEV_Device_t * dev, DSL_DEV_LedId_t led_number, DSL_DEV_LedMode_t mode)
+{
+ printk(KERN_INFO "[%s %d]: mode = %#x, led_number = %d\n", __func__, __LINE__, mode, led_number);
+ switch (mode) {
+ case DSL_LED_OFF:
+ switch (led_number) {
+ case DSL_LED_LINK_ID:
+#ifdef CONFIG_BSP_LED
+ bsp_led_set_blink (1, 0);
+ bsp_led_set_data (1, 0);
+#endif
+ break;
+ case DSL_LED_DATA_ID:
+#ifdef CONFIG_BSP_LED
+ bsp_led_set_blink (0, 0);
+ bsp_led_set_data (0, 0);
+#endif
+ break;
+ }
+ break;
+ case DSL_LED_FLASH:
+ switch (led_number) {
+ case DSL_LED_LINK_ID:
+#ifdef CONFIG_BSP_LED
+ bsp_led_set_blink (1, 1); // data
+#endif
+ break;
+ case DSL_LED_DATA_ID:
+#ifdef CONFIG_BSP_LED
+ bsp_led_set_blink (0, 1); // data
+#endif
+ break;
+ }
+ break;
+ case DSL_LED_ON:
+ switch (led_number) {
+ case DSL_LED_LINK_ID:
+#ifdef CONFIG_BSP_LED
+ bsp_led_set_blink (1, 0);
+ bsp_led_set_data (1, 1);
+#endif
+ break;
+ case DSL_LED_DATA_ID:
+#ifdef CONFIG_BSP_LED
+ bsp_led_set_blink (0, 0);
+ bsp_led_set_data (0, 1);
+#endif
+ break;
+ }
+ break;
+ }
+ return DSL_DEV_MEI_ERR_SUCCESS;
+};
+
+#endif
+
+/**
+* Compose a message.
+* This function compose a message from opcode, group, address, index, size, and data
+*
+* \param opcode The message opcode
+* \param group The message group number
+* \param address The message address.
+* \param index The message index.
+* \param size The number of words to read/write.
+* \param data The pointer to data.
+* \param CMVMSG The pointer to message buffer.
+* \ingroup Internal
+*/
+void
+makeCMV (u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data, u16 *CMVMSG)
+{
+ memset (CMVMSG, 0, MSG_LENGTH * 2);
+ CMVMSG[0] = (opcode << 4) + (size & 0xf);
+ CMVMSG[1] = (((index == 0) ? 0 : 1) << 7) + (group & 0x7f);
+ CMVMSG[2] = address;
+ CMVMSG[3] = index;
+ if (opcode == H2D_CMV_WRITE)
+ memcpy (CMVMSG + 4, data, size * 2);
+ return;
+}
+
+/**
+ * Send a message to ARC and read the response
+ * This function sends a message to arc, waits the response, and reads the responses.
+ *
+ * \param pDev the device pointer
+ * \param request Pointer to the request
+ * \param reply Wait reply or not.
+ * \param response Pointer to the response
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+DSL_DEV_MeiError_t
+DSL_BSP_SendCMV (DSL_DEV_Device_t * pDev, u16 * request, int reply, u16 * response) // write cmv to arc, if reply needed, wait for reply
+{
+ DSL_DEV_MeiError_t meierror;
+#if defined(BSP_PORT_RTEMS)
+ int delay_counter = 0;
+#endif
+
+ if (MEI_MUTEX_LOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema))
+ return -ERESTARTSYS;
+
+ DSL_DEV_PRIVATE(pDev)->cmv_reply = reply;
+ memset (DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, 0,
+ sizeof (DSL_DEV_PRIVATE(pDev)->
+ CMV_RxMsg));
+ DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
+
+ meierror = IFX_MEI_MailboxWrite (pDev, request, MSG_LENGTH);
+
+ if (meierror != DSL_DEV_MEI_ERR_SUCCESS) {
+ DSL_DEV_PRIVATE(pDev)->cmv_waiting = 0;
+ DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
+ IFX_MEI_EMSG ("MailboxWrite Fail!\n");
+ IFX_MEI_EMSG ("Resetting ARC...\n");
+ IFX_MEI_ResetARC(pDev);
+ MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
+ return meierror;
+ }
+ else {
+ DSL_DEV_PRIVATE(pDev)->cmv_count++;
+ }
+
+ if (DSL_DEV_PRIVATE(pDev)->cmv_reply ==
+ NO_REPLY) {
+ MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
+ return DSL_DEV_MEI_ERR_SUCCESS;
+ }
+
+#if !defined(BSP_PORT_RTEMS)
+ if (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0)
+ MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav, CMV_TIMEOUT);
+#else
+ while (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0 && delay_counter < CMV_TIMEOUT / 5) {
+ MEI_WAIT (5);
+ delay_counter++;
+ }
+#endif
+
+ DSL_DEV_PRIVATE(pDev)->cmv_waiting = 0;
+ if (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0) { //CMV_timeout
+ DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
+ IFX_MEI_EMSG ("\%s: DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT\n",
+ __FUNCTION__);
+ MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
+ return DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT;
+ }
+ else {
+ DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
+ DSL_DEV_PRIVATE(pDev)->
+ reply_count++;
+ memcpy (response, DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH * 2);
+ MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
+ return DSL_DEV_MEI_ERR_SUCCESS;
+ }
+ MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
+ return DSL_DEV_MEI_ERR_SUCCESS;
+}
+
+/**
+ * Reset the ARC, download boot codes, and run the ARC.
+ * This function resets the ARC, downloads boot codes to ARC, and runs the ARC.
+ *
+ * \param pDev the device pointer
+ * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
+ * \ingroup Internal
+ */
+static DSL_DEV_MeiError_t
+IFX_MEI_RunAdslModem (DSL_DEV_Device_t *pDev)
+{
+ int nSize = 0, idx = 0;
+ uint32_t im0_register, im2_register;
+// DSL_DEV_WinHost_Message_t m;
+
+ if (mei_arc_swap_buff == NULL) {
+ mei_arc_swap_buff =
+ (u32 *) kmalloc (MAXSWAPSIZE * 4, GFP_KERNEL);
+ if (mei_arc_swap_buff == NULL) {
+ IFX_MEI_EMSG (">>> malloc fail for codeswap buff!!! <<<\n");
+ return DSL_DEV_MEI_ERR_FAILURE;
+ }
+ IFX_MEI_DMSG("allocate %dKB swap buff memory at: 0x%p\n", ksize(mei_arc_swap_buff)/1024, mei_arc_swap_buff);
+ }
+
+ DSL_DEV_PRIVATE(pDev)->img_hdr =
+ (ARC_IMG_HDR *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[0].address;
+ if ((DSL_DEV_PRIVATE(pDev)->img_hdr->
+ count) * sizeof (ARC_SWP_PAGE_HDR) > SDRAM_SEGMENT_SIZE) {
+ IFX_MEI_EMSG ("firmware header size is bigger than 64K segment size\n");
+ return DSL_DEV_MEI_ERR_FAILURE;
+ }
+ // check image size
+ for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
+ nSize += DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].nCopy;
+ }
+ if (nSize !=
+ DSL_DEV_PRIVATE(pDev)->image_size) {
+ IFX_MEI_EMSG ("Firmware download is not completed. Please download firmware again!\n");
+ return DSL_DEV_MEI_ERR_FAILURE;
+ }
+ // TODO: check crc
+ ///
+
+ IFX_MEI_ResetARC (pDev);
+ IFX_MEI_HaltArc (pDev);
+ IFX_MEI_BarUpdate (pDev, DSL_DEV_PRIVATE(pDev)->nBar);
+
+ //IFX_MEI_DMSG("Starting to meiDownloadBootCode\n");
+
+ IFX_MEI_DownloadBootCode (pDev);
+
+ im0_register = (*LTQ_ICU_IM0_IER) & (1 << 20);
+ im2_register = (*LTQ_ICU_IM2_IER) & (1 << 20);
+ /* Turn off irq */
+ #ifdef CONFIG_SOC_AMAZON_SE
+#define IFXMIPS_USB_OC_INT0 (INT_NUM_IM4_IRL0 + 23)
+ disable_irq (IFXMIPS_USB_OC_INT0);
+// disable_irq (IFXMIPS_USB_OC_INT2);
+ #elif defined(CONFIG_SOC_AR9)
+#define IFXMIPS_USB_OC_INT0 (INT_NUM_IM4_IRL1 + 28)
+ disable_irq (IFXMIPS_USB_OC_INT0);
+// disable_irq (IFXMIPS_USB_OC_INT2);
+ #elif defined(CONFIG_SOC_XWAY)
+ disable_irq (LTQ_USB_OC_INT);
+ #else
+ #error unkonwn arch
+ #endif
+ disable_irq (pDev->nIrq[IFX_DYING_GASP]);
+
+ IFX_MEI_RunArc (pDev);
+
+ MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev)->wait_queue_modemready, 1000);
+
+ #ifdef CONFIG_SOC_AMAZON_SE
+ MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT0);
+// MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT2);
+ #elif defined(CONFIG_SOC_AR9)
+ MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT0);
+// MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT2);
+ #elif defined(CONFIG_SOC_XWAY)
+ MEI_MASK_AND_ACK_IRQ (LTQ_USB_OC_INT);
+ #else
+ #error unkonwn arch
+ #endif
+ MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DYING_GASP]);
+
+ /* Re-enable irq */
+ enable_irq(pDev->nIrq[IFX_DYING_GASP]);
+ *LTQ_ICU_IM0_IER |= im0_register;
+ *LTQ_ICU_IM2_IER |= im2_register;
+
+ if (DSL_DEV_PRIVATE(pDev)->modem_ready != 1) {
+ IFX_MEI_EMSG ("Modem failed to be ready!\n");
+ return DSL_DEV_MEI_ERR_FAILURE;
+ } else {
+ IFX_MEI_DMSG("Modem is ready.\n");
+ return DSL_DEV_MEI_ERR_SUCCESS;
+ }
+}
+
+/**
+ * Get the page's data pointer
+ * This function caculats the data address from the firmware header.
+ *
+ * \param pDev the device pointer
+ * \param Page The page number.
+ * \param data Data page or program page.
+ * \param MaxSize The maximum size to read.
+ * \param Buffer Pointer to data.
+ * \param Dest Pointer to the destination address.
+ * \return The number of bytes to read.
+ * \ingroup Internal
+ */
+static int
+IFX_MEI_GetPage (DSL_DEV_Device_t * pDev, u32 Page, u32 data,
+ u32 MaxSize, u32 * Buffer, u32 * Dest)
+{
+ u32 size;
+ u32 i;
+ u32 *p;
+ u32 idx, offset, nBar = 0;
+
+ if (Page > DSL_DEV_PRIVATE(pDev)->img_hdr->count)
+ return -2;
+ /*
+ ** Get program or data size, depending on "data" flag
+ */
+ size = (data == GET_DATA) ? (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].d_size) :
+ (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_size);
+ size &= BOOT_FLAG_MASK; // Clear boot bit!
+ if (size > MaxSize)
+ return -1;
+
+ if (size == 0)
+ return 0;
+ /*
+ ** Get program or data offset, depending on "data" flag
+ */
+ i = data ? (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].d_offset) :
+ (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_offset);
+
+ /*
+ ** Copy data/program to buffer
+ */
+
+ idx = i / SDRAM_SEGMENT_SIZE;
+ offset = i % SDRAM_SEGMENT_SIZE;
+ p = (u32 *) ((u8 *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address + offset);
+
+ for (i = 0; i < size; i++) {
+ if (offset + i * 4 - (nBar * SDRAM_SEGMENT_SIZE) >= SDRAM_SEGMENT_SIZE) {
+ idx++;
+ nBar++;
+ p = (u32 *) ((u8 *) KSEG1ADDR ((u32)DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address));
+ }
+ Buffer[i] = *p++;
+ }
+
+ /*
+ ** Pass back data/program destination address
+ */
+ *Dest = data ? (DSL_DEV_PRIVATE(pDev)-> img_hdr->page[Page].d_dest) :
+ (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_dest);
+
+ return size;
+}
+
+/**
+ * Free the memory for ARC firmware
+ *
+ * \param pDev the device pointer
+ * \param type Free all memory or free the unused memory after showtime
+ * \ingroup Internal
+ */
+const char *free_str[4] = {"Invalid", "Free_Reload", "Free_Showtime", "Free_All"};
+static int
+IFX_MEI_DFEMemoryFree (DSL_DEV_Device_t * pDev, int type)
+{
+ int idx = 0;
+ smmu_mem_info_t *adsl_mem_info =
+ DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
+
+ for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
+ if (type == FREE_ALL ||adsl_mem_info[idx].type == type) {
+ if (adsl_mem_info[idx].size > 0) {
+ IFX_MEI_DMSG ("Freeing memory %p (%s)\n", adsl_mem_info[idx].org_address, free_str[adsl_mem_info[idx].type]);
+ if ( idx == XDATA_REGISTER ) {
+ g_xdata_addr = NULL;
+ if ( ifx_mei_atm_showtime_exit )
+ ifx_mei_atm_showtime_exit();
+ }
+ kfree (adsl_mem_info[idx].org_address);
+ adsl_mem_info[idx].org_address = 0;
+ adsl_mem_info[idx].address = 0;
+ adsl_mem_info[idx].size = 0;
+ adsl_mem_info[idx].type = 0;
+ adsl_mem_info[idx].nCopy = 0;
+ }
+ }
+ }
+
+ if(mei_arc_swap_buff != NULL){
+ IFX_MEI_DMSG("free %dKB swap buff memory at: 0x%p\n", ksize(mei_arc_swap_buff)/1024, mei_arc_swap_buff);
+ kfree(mei_arc_swap_buff);
+ mei_arc_swap_buff=NULL;
+ }
+
+ return 0;
+}
+static int
+IFX_MEI_DFEMemoryAlloc (DSL_DEV_Device_t * pDev, long size)
+{
+ unsigned long mem_ptr;
+ char *org_mem_ptr = NULL;
+ int idx = 0;
+ long total_size = 0;
+ int err = 0;
+ smmu_mem_info_t *adsl_mem_info =
+ ((ifx_mei_device_private_t *) pDev->pPriv)->adsl_mem_info;
+// DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
+ int allocate_size = SDRAM_SEGMENT_SIZE;
+
+ IFX_MEI_DMSG("image_size = %ld\n", size);
+ // Alloc Swap Pages
+ for (idx = 0; size > 0 && idx < MAX_BAR_REGISTERS; idx++) {
+ // skip bar15 for XDATA usage.
+ if (idx == XDATA_REGISTER)
+ continue;
+#if 0
+ if (size < SDRAM_SEGMENT_SIZE) {
+ allocate_size = size;
+ if (allocate_size < 1024)
+ allocate_size = 1024;
+ }
+#endif
+ if (idx == (MAX_BAR_REGISTERS - 1))
+ allocate_size = size;
+ else
+ allocate_size = SDRAM_SEGMENT_SIZE;
+ org_mem_ptr = kmalloc (allocate_size + 1024, GFP_KERNEL);
+ if (org_mem_ptr == NULL) {
+ IFX_MEI_EMSG ("%d: kmalloc %d bytes memory fail!\n", idx, allocate_size);
+ err = -ENOMEM;
+ goto allocate_error;
+ }
+ mem_ptr = (unsigned long) (org_mem_ptr + 1023) & ~(1024 -1);
+ adsl_mem_info[idx].address = (char *) mem_ptr;
+ adsl_mem_info[idx].org_address = org_mem_ptr;
+ adsl_mem_info[idx].size = allocate_size;
+ size -= allocate_size;
+ total_size += allocate_size;
+ }
+ if (size > 0) {
+ IFX_MEI_EMSG ("Image size is too large!\n");
+ err = -EFBIG;
+ goto allocate_error;
+ }
+ err = idx;
+ return err;
+
+ allocate_error:
+ IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
+ return err;
+}
+
+/**
+ * Program the BAR registers
+ *
+ * \param pDev the device pointer
+ * \param nTotalBar The number of bar to program.
+ * \ingroup Internal
+ */
+static int
+IFX_MEI_BarUpdate (DSL_DEV_Device_t * pDev, int nTotalBar)
+{
+ int idx = 0;
+ smmu_mem_info_t *adsl_mem_info =
+ DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
+
+ for (idx = 0; idx < nTotalBar; idx++) {
+ //skip XDATA register
+ if (idx == XDATA_REGISTER)
+ continue;
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + idx * 4,
+ (((uint32_t) adsl_mem_info[idx].address) & 0x0FFFFFFF));
+ }
+ for (idx = nTotalBar; idx < MAX_BAR_REGISTERS; idx++) {
+ if (idx == XDATA_REGISTER)
+ continue;
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + idx * 4,
+ (((uint32_t)adsl_mem_info[nTotalBar - 1].address) & 0x0FFFFFFF));
+ /* These are for /proc/danube_mei/meminfo purpose */
+ adsl_mem_info[idx].address = adsl_mem_info[nTotalBar - 1].address;
+ adsl_mem_info[idx].org_address = adsl_mem_info[nTotalBar - 1].org_address;
+ adsl_mem_info[idx].size = 0; /* Prevent it from being freed */
+ }
+
+ g_xdata_addr = adsl_mem_info[XDATA_REGISTER].address;
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + XDATA_REGISTER * 4,
+ (((uint32_t) adsl_mem_info [XDATA_REGISTER].address) & 0x0FFFFFFF));
+ // update MEI_XDATA_BASE_SH
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XDATA_BASE_SH,
+ ((unsigned long)adsl_mem_info[XDATA_REGISTER].address) & 0x0FFFFFFF);
+
+ return DSL_DEV_MEI_ERR_SUCCESS;
+}
+
+/* This copies the firmware from secondary storage to 64k memory segment in SDRAM */
+DSL_DEV_MeiError_t
+DSL_BSP_FWDownload (DSL_DEV_Device_t * pDev, const char *buf,
+ unsigned long size, long *loff, long *current_offset)
+{
+ ARC_IMG_HDR img_hdr_tmp;
+ smmu_mem_info_t *adsl_mem_info = DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
+
+ size_t nRead = 0, nCopy = 0;
+ char *mem_ptr;
+ ssize_t retval = -ENOMEM;
+ int idx = 0;
+
+ IFX_MEI_DMSG("\n");
+
+ if (*loff == 0) {
+ if (size < sizeof (img_hdr_tmp)) {
+ IFX_MEI_EMSG ("Firmware size is too small!\n");
+ return retval;
+ }
+ copy_from_user ((char *) &img_hdr_tmp, buf, sizeof (img_hdr_tmp));
+ // header of image_size and crc are not included.
+ DSL_DEV_PRIVATE(pDev)->image_size = le32_to_cpu (img_hdr_tmp.size) + 8;
+
+ if (DSL_DEV_PRIVATE(pDev)->image_size > 1024 * 1024) {
+ IFX_MEI_EMSG ("Firmware size is too large!\n");
+ return retval;
+ }
+ // check if arc is halt
+ IFX_MEI_ResetARC (pDev);
+ IFX_MEI_HaltArc (pDev);
+
+ IFX_MEI_DFEMemoryFree (pDev, FREE_ALL); //free all
+
+ retval = IFX_MEI_DFEMemoryAlloc (pDev, DSL_DEV_PRIVATE(pDev)->image_size);
+ if (retval < 0) {
+ IFX_MEI_EMSG ("Error: No memory space left.\n");
+ goto error;
+ }
+ for (idx = 0; idx < retval; idx++) {
+ //skip XDATA register
+ if (idx == XDATA_REGISTER)
+ continue;
+ if (idx * SDRAM_SEGMENT_SIZE < le32_to_cpu (img_hdr_tmp.page[0].p_offset))
+ adsl_mem_info[idx].type = FREE_RELOAD;
+ else
+ adsl_mem_info[idx].type = FREE_SHOWTIME;
+ }
+ DSL_DEV_PRIVATE(pDev)->nBar = retval;
+
+ DSL_DEV_PRIVATE(pDev)->img_hdr =
+ (ARC_IMG_HDR *) adsl_mem_info[0].address;
+
+ adsl_mem_info[XDATA_REGISTER].org_address = kmalloc (SDRAM_SEGMENT_SIZE + 1024, GFP_KERNEL);
+ adsl_mem_info[XDATA_REGISTER].address =
+ (char *) ((unsigned long) (adsl_mem_info[XDATA_REGISTER].org_address + 1023) & 0xFFFFFC00);
+
+ adsl_mem_info[XDATA_REGISTER].size = SDRAM_SEGMENT_SIZE;
+
+ if (adsl_mem_info[XDATA_REGISTER].address == NULL) {
+ IFX_MEI_EMSG ("kmalloc memory fail!\n");
+ retval = -ENOMEM;
+ goto error;
+ }
+ adsl_mem_info[XDATA_REGISTER].type = FREE_RELOAD;
+ IFX_MEI_DMSG("-> IFX_MEI_BarUpdate()\n");
+ IFX_MEI_BarUpdate (pDev, (DSL_DEV_PRIVATE(pDev)->nBar));
+ }
+ else if (DSL_DEV_PRIVATE(pDev)-> image_size == 0) {
+ IFX_MEI_EMSG ("Error: Firmware size=0! \n");
+ goto error;
+ }
+
+ nRead = 0;
+ while (nRead < size) {
+ long offset = ((long) (*loff) + nRead) % SDRAM_SEGMENT_SIZE;
+ idx = (((long) (*loff)) + nRead) / SDRAM_SEGMENT_SIZE;
+ mem_ptr = (char *) KSEG1ADDR ((unsigned long) (adsl_mem_info[idx].address) + offset);
+ if ((size - nRead + offset) > SDRAM_SEGMENT_SIZE)
+ nCopy = SDRAM_SEGMENT_SIZE - offset;
+ else
+ nCopy = size - nRead;
+ copy_from_user (mem_ptr, buf + nRead, nCopy);
+ for (offset = 0; offset < (nCopy / 4); offset++) {
+ ((unsigned long *) mem_ptr)[offset] = le32_to_cpu (((unsigned long *) mem_ptr)[offset]);
+ }
+ nRead += nCopy;
+ adsl_mem_info[idx].nCopy += nCopy;
+ }
+
+ *loff += size;
+ *current_offset = size;
+ return DSL_DEV_MEI_ERR_SUCCESS;
+error:
+ IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
+ return DSL_DEV_MEI_ERR_FAILURE;
+}
+/*
+ * Register a callback event.
+ * Return:
+ * -1 if the event already has a callback function registered.
+ * 0 success
+ */
+int DSL_BSP_EventCBRegister(DSL_BSP_EventCallBack_t *p)
+{
+ if (!p) {
+ IFX_MEI_EMSG("Invalid parameter!\n");
+ return -EINVAL;
+ }
+ if (p->event > DSL_BSP_CB_LAST || p->event < DSL_BSP_CB_FIRST) {
+ IFX_MEI_EMSG("Invalid Event %d\n", p->event);
+ return -EINVAL;
+ }
+ if (dsl_bsp_event_callback[p->event].function) {
+ IFX_MEI_EMSG("Event %d already has a callback function registered!\n", p->event);
+ return -1;
+ } else {
+ dsl_bsp_event_callback[p->event].function = p->function;
+ dsl_bsp_event_callback[p->event].event = p->event;
+ dsl_bsp_event_callback[p->event].pData = p->pData;
+ }
+ return 0;
+}
+int DSL_BSP_EventCBUnregister(DSL_BSP_EventCallBack_t *p)
+{
+ if (!p) {
+ IFX_MEI_EMSG("Invalid parameter!\n");
+ return -EINVAL;
+ }
+ if (p->event > DSL_BSP_CB_LAST || p->event < DSL_BSP_CB_FIRST) {
+ IFX_MEI_EMSG("Invalid Event %d\n", p->event);
+ return -EINVAL;
+ }
+ if (dsl_bsp_event_callback[p->event].function) {
+ IFX_MEI_EMSG("Unregistering Event %d...\n", p->event);
+ dsl_bsp_event_callback[p->event].function = NULL;
+ dsl_bsp_event_callback[p->event].pData = NULL;
+ } else {
+ IFX_MEI_EMSG("Event %d is not registered!\n", p->event);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * MEI Dying Gasp interrupt handler
+ *
+ * \param int1
+ * \param void0
+ * \param regs Pointer to the structure of danube mips registers
+ * \ingroup Internal
+ */
+/*static irqreturn_t IFX_MEI_Dying_Gasp_IrqHandle (int int1, void *void0)
+{
+ DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
+ DSL_BSP_CB_Type_t event;
+
+ if (pDev == NULL)
+ IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
+
+#ifndef CONFIG_SMP
+ disable_irq (pDev->nIrq[IFX_DYING_GASP]);
+#else
+ disable_irq_nosync(pDev->nIrq[IFX_DYING_GASP]);
+#endif
+ event = DSL_BSP_CB_DYING_GASP;
+
+ if (dsl_bsp_event_callback[event].function)
+ (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
+
+#ifdef CONFIG_USE_EMULATOR
+ IFX_MEI_EMSG("Dying Gasp! Shutting Down... (Work around for Amazon-S Venus emulator)\n");
+#else
+ IFX_MEI_EMSG("Dying Gasp! Shutting Down...\n");
+// kill_proc (1, SIGINT, 1);
+#endif
+ return IRQ_HANDLED;
+}
+*/
+extern void ifx_usb_enable_afe_oc(void);
+
+/**
+ * MEI interrupt handler
+ *
+ * \param int1
+ * \param void0
+ * \param regs Pointer to the structure of danube mips registers
+ * \ingroup Internal
+ */
+static irqreturn_t IFX_MEI_IrqHandle (int int1, void *void0)
+{
+ u32 scratch;
+ DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
+#if defined(CONFIG_LTQ_MEI_FW_LOOPBACK) && defined(DFE_PING_TEST)
+ dfe_loopback_irq_handler (pDev);
+ return IRQ_HANDLED;
+#endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
+ DSL_BSP_CB_Type_t event;
+
+ if (pDev == NULL)
+ IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
+
+ IFX_MEI_DebugRead (pDev, ARC_MEI_MAILBOXR, &scratch, 1);
+ if (scratch & OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK) {
+ IFX_MEI_EMSG("Receive Code Swap Request interrupt!!!\n");
+ return IRQ_HANDLED;
+ }
+ else if (scratch & OMB_CLEAREOC_INTERRUPT_CODE) {
+ // clear eoc message interrupt
+ IFX_MEI_DMSG("OMB_CLEAREOC_INTERRUPT_CODE\n");
+ event = DSL_BSP_CB_CEOC_IRQ;
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
+ if (dsl_bsp_event_callback[event].function)
+ (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
+ } else if (scratch & OMB_REBOOT_INTERRUPT_CODE) {
+ // Reboot
+ IFX_MEI_DMSG("OMB_REBOOT_INTERRUPT_CODE\n");
+ event = DSL_BSP_CB_FIRMWARE_REBOOT;
+
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
+
+ if (dsl_bsp_event_callback[event].function)
+ (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
+ } else { // normal message
+ IFX_MEI_MailboxRead (pDev, DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH);
+ if (DSL_DEV_PRIVATE(pDev)-> cmv_waiting == 1) {
+ DSL_DEV_PRIVATE(pDev)-> arcmsgav = 1;
+ DSL_DEV_PRIVATE(pDev)-> cmv_waiting = 0;
+#if !defined(BSP_PORT_RTEMS)
+ MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav);
+#endif
+ }
+ else {
+ DSL_DEV_PRIVATE(pDev)-> modem_ready_cnt++;
+ memcpy ((char *) DSL_DEV_PRIVATE(pDev)->Recent_indicator,
+ (char *) DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH * 2);
+ if (((DSL_DEV_PRIVATE(pDev)->CMV_RxMsg[0] & 0xff0) >> 4) == D2H_AUTONOMOUS_MODEM_READY_MSG) {
+ //check ARC ready message
+ IFX_MEI_DMSG ("Got MODEM_READY_MSG\n");
+ DSL_DEV_PRIVATE(pDev)->modem_ready = 1;
+ MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev)->wait_queue_modemready);
+ }
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+int
+DSL_BSP_ATMLedCBRegister (int (*ifx_adsl_ledcallback) (void))
+{
+ g_adsl_ledcallback = ifx_adsl_ledcallback;
+ return 0;
+}
+
+int
+DSL_BSP_ATMLedCBUnregister (int (*ifx_adsl_ledcallback) (void))
+{
+ g_adsl_ledcallback = adsl_dummy_ledcallback;
+ return 0;
+}
+
+#if 0
+int
+DSL_BSP_EventCBRegister (int (*ifx_adsl_callback)
+ (DSL_BSP_CB_Event_t * param))
+{
+ int error = 0;
+
+ if (DSL_EventCB == NULL) {
+ DSL_EventCB = ifx_adsl_callback;
+ }
+ else {
+ error = -EIO;
+ }
+ return error;
+}
+
+int
+DSL_BSP_EventCBUnregister (int (*ifx_adsl_callback)
+ (DSL_BSP_CB_Event_t * param))
+{
+ int error = 0;
+
+ if (DSL_EventCB == ifx_adsl_callback) {
+ DSL_EventCB = NULL;
+ }
+ else {
+ error = -EIO;
+ }
+ return error;
+}
+
+static int
+DSL_BSP_GetEventCB (int (**ifx_adsl_callback)
+ (DSL_BSP_CB_Event_t * param))
+{
+ *ifx_adsl_callback = DSL_EventCB;
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
+#define mte_reg_base (0x4800*4+0x20000)
+
+/* Iridia Registers Address Constants */
+#define MTE_Reg(r) (int)(mte_reg_base + (r*4))
+
+#define IT_AMODE MTE_Reg(0x0004)
+
+#define TIMER_DELAY (1024)
+#define BC0_BYTES (32)
+#define BC1_BYTES (30)
+#define NUM_MB (12)
+#define TIMEOUT_VALUE 2000
+
+static void
+BFMWait (u32 cycle)
+{
+ u32 i;
+ for (i = 0; i < cycle; i++);
+}
+
+static void
+WriteRegLong (u32 addr, u32 data)
+{
+ //*((volatile u32 *)(addr)) = data;
+ IFX_MEI_WRITE_REGISTER_L (data, addr);
+}
+
+static u32
+ReadRegLong (u32 addr)
+{
+ // u32 rd_val;
+ //rd_val = *((volatile u32 *)(addr));
+ // return rd_val;
+ return IFX_MEI_READ_REGISTER_L (addr);
+}
+
+/* This routine writes the mailbox with the data in an input array */
+static void
+WriteMbox (u32 * mboxarray, u32 size)
+{
+ IFX_MEI_DebugWrite (&dsl_devices[0], IMBOX_BASE, mboxarray, size);
+ IFX_MEI_DMSG("write to %X\n", IMBOX_BASE);
+ IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ME2ARC_INT, MEI_TO_ARC_MSGAV);
+}
+
+/* This routine reads the output mailbox and places the results into an array */
+static void
+ReadMbox (u32 * mboxarray, u32 size)
+{
+ IFX_MEI_DebugRead (&dsl_devices[0], OMBOX_BASE, mboxarray, size);
+ IFX_MEI_DMSG("read from %X\n", OMBOX_BASE);
+}
+
+static void
+MEIWriteARCValue (u32 address, u32 value)
+{
+ u32 i, check = 0;
+
+ /* Write address register */
+ IFX_MEI_WRITE_REGISTER_L (address, ME_DBG_WR_AD + LTQ_MEI_BASE_ADDR);
+
+ /* Write data register */
+ IFX_MEI_WRITE_REGISTER_L (value, ME_DBG_DATA + LTQ_MEI_BASE_ADDR);
+
+ /* wait until complete - timeout at 40 */
+ for (i = 0; i < 40; i++) {
+ check = IFX_MEI_READ_REGISTER_L (ME_ARC2ME_STAT + LTQ_MEI_BASE_ADDR);
+
+ if ((check & ARC_TO_MEI_DBG_DONE))
+ break;
+ }
+ /* clear the flag */
+ IFX_MEI_WRITE_REGISTER_L (ARC_TO_MEI_DBG_DONE, ME_ARC2ME_STAT + LTQ_MEI_BASE_ADDR);
+}
+
+void
+arc_code_page_download (uint32_t arc_code_length, uint32_t * start_address)
+{
+ int count;
+
+ IFX_MEI_DMSG("try to download pages,size=%d\n", arc_code_length);
+ IFX_MEI_ControlModeSet (&dsl_devices[0], MEI_MASTER_MODE);
+ IFX_MEI_HaltArc (&dsl_devices[0]);
+ IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_DX_AD, 0);
+ for (count = 0; count < arc_code_length; count++) {
+ IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_DX_DATA,
+ *(start_address + count));
+ }
+ IFX_MEI_ControlModeSet (&dsl_devices[0], JTAG_MASTER_MODE);
+}
+static int
+load_jump_table (unsigned long addr)
+{
+ int i;
+ uint32_t addr_le, addr_be;
+ uint32_t jump_table[32];
+
+ for (i = 0; i < 16; i++) {
+ addr_le = i * 8 + addr;
+ addr_be = ((addr_le >> 16) & 0xffff);
+ addr_be |= ((addr_le & 0xffff) << 16);
+ jump_table[i * 2 + 0] = 0x0f802020;
+ jump_table[i * 2 + 1] = addr_be;
+ //printk("jt %X %08X %08X\n",i,jump_table[i*2+0],jump_table[i*2+1]);
+ }
+ arc_code_page_download (32, &jump_table[0]);
+return 0;
+}
+
+int got_int = 0;
+
+void
+dfe_loopback_irq_handler (DSL_DEV_Device_t *pDev)
+{
+ uint32_t rd_mbox[10];
+
+ memset (&rd_mbox[0], 0, 10 * 4);
+ ReadMbox (&rd_mbox[0], 6);
+ if (rd_mbox[0] == 0x0) {
+ FX_MEI_DMSG("Get ARC_ACK\n");
+ got_int = 1;
+ }
+ else if (rd_mbox[0] == 0x5) {
+ IFX_MEI_DMSG("Get ARC_BUSY\n");
+ got_int = 2;
+ }
+ else if (rd_mbox[0] == 0x3) {
+ IFX_MEI_DMSG("Get ARC_EDONE\n");
+ if (rd_mbox[1] == 0x0) {
+ got_int = 3;
+ IFX_MEI_DMSG("Get E_MEMTEST\n");
+ if (rd_mbox[2] != 0x1) {
+ got_int = 4;
+ IFX_MEI_DMSG("Get Result %X\n", rd_mbox[2]);
+ }
+ }
+ }
+ IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ARC2ME_STAT,
+ ARC_TO_MEI_DBG_DONE);
+ MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DFEIR]);
+ disable_irq (pDev->nIrq[IFX_DFEIR]);
+ //got_int = 1;
+ return;
+}
+
+static void
+wait_mem_test_result (void)
+{
+ uint32_t mbox[5];
+ mbox[0] = 0;
+
+ IFX_MEI_DMSG("Waiting Starting\n");
+ while (mbox[0] == 0) {
+ ReadMbox (&mbox[0], 5);
+ }
+ IFX_MEI_DMSG("Try to get mem test result.\n");
+ ReadMbox (&mbox[0], 5);
+ if (mbox[0] == 0xA) {
+ IFX_MEI_DMSG("Success.\n");
+ }
+ else if (mbox[0] == 0xA) {
+ IFX_MEI_EMSG("Fail,address %X,except data %X,receive data %X\n",
+ mbox[1], mbox[2], mbox[3]);
+ }
+ else {
+ IFX_MEI_EMSG("Fail\n");
+ }
+}
+
+static int
+arc_ping_testing (DSL_DEV_Device_t *pDev)
+{
+#define MEI_PING 0x00000001
+ uint32_t wr_mbox[10], rd_mbox[10];
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ wr_mbox[i] = 0;
+ rd_mbox[i] = 0;
+ }
+
+ FX_MEI_DMSG("send ping msg\n");
+ wr_mbox[0] = MEI_PING;
+ WriteMbox (&wr_mbox[0], 10);
+
+ while (got_int == 0) {
+ MEI_WAIT (100);
+ }
+
+ IFX_MEI_DMSG("send start event\n");
+ got_int = 0;
+
+ wr_mbox[0] = 0x4;
+ wr_mbox[1] = 0;
+ wr_mbox[2] = 0;
+ wr_mbox[3] = (uint32_t) 0xf5acc307e;
+ wr_mbox[4] = 5;
+ wr_mbox[5] = 2;
+ wr_mbox[6] = 0x1c000;
+ wr_mbox[7] = 64;
+ wr_mbox[8] = 0;
+ wr_mbox[9] = 0;
+ WriteMbox (&wr_mbox[0], 10);
+ DSL_ENABLE_IRQ (pDev->nIrq[IFX_DFEIR]);
+ //printk("IFX_MEI_MailboxWrite ret=%d\n",i);
+ IFX_MEI_LongWordWriteOffset (&dsl_devices[0],
+ (u32) ME_ME2ARC_INT,
+ MEI_TO_ARC_MSGAV);
+ IFX_MEI_DMSG("sleeping\n");
+ while (1) {
+ if (got_int > 0) {
+
+ if (got_int > 3)
+ IFX_MEI_DMSG("got_int >>>> 3\n");
+ else
+ IFX_MEI_DMSG("got int = %d\n", got_int);
+ got_int = 0;
+ //schedule();
+ DSL_ENABLE_IRQ (pDev->nIrq[IFX_DFEIR]);
+ }
+ //mbox_read(&rd_mbox[0],6);
+ MEI_WAIT (100);
+ }
+ return 0;
+}
+
+static DSL_DEV_MeiError_t
+DFE_Loopback_Test (void)
+{
+ int i = 0;
+ u32 arc_debug_data = 0, temp;
+ DSL_DEV_Device_t *pDev = &dsl_devices[0];
+ uint32_t wr_mbox[10];
+
+ IFX_MEI_ResetARC (pDev);
+ // start the clock
+ arc_debug_data = ACL_CLK_MODE_ENABLE;
+ IFX_MEI_DebugWrite (pDev, CRI_CCR0, &arc_debug_data, 1);
+
+#if defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
+ // WriteARCreg(AUX_XMEM_LTEST,0);
+ IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
+#define AUX_XMEM_LTEST 0x128
+ _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK, AUX_XMEM_LTEST, 0);
+ IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
+
+ // WriteARCreg(AUX_XDMA_GAP,0);
+ IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
+#define AUX_XDMA_GAP 0x114
+ _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK, AUX_XDMA_GAP, 0);
+ IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
+
+ IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
+ temp = 0;
+ _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
+ (u32) ME_XDATA_BASE_SH + LTQ_MEI_BASE_ADDR, temp);
+ IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
+
+ i = IFX_MEI_DFEMemoryAlloc (pDev, SDRAM_SEGMENT_SIZE * 16);
+ if (i >= 0) {
+ int idx;
+
+ for (idx = 0; idx < i; idx++) {
+ DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].type = FREE_RELOAD;
+ IFX_MEI_WRITE_REGISTER_L ((((uint32_t) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address) & 0x0fffffff),
+ LTQ_MEI_BASE_ADDR + ME_XMEM_BAR_BASE + idx * 4);
+ IFX_MEI_DMSG("bar%d(%X)=%X\n", idx,
+ LTQ_MEI_BASE_ADDR + ME_XMEM_BAR_BASE +
+ idx * 4, (((uint32_t)
+ ((ifx_mei_device_private_t *)
+ pDev->pPriv)->adsl_mem_info[idx].
+ address) & 0x0fffffff));
+ memset ((u8 *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address, 0, SDRAM_SEGMENT_SIZE);
+ }
+
+ IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XDATA_BASE_SH,
+ ((unsigned long) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[XDATA_REGISTER].address) & 0x0FFFFFFF);
+ }
+ else {
+ IFX_MEI_EMSG ("cannot load image: no memory\n");
+ return DSL_DEV_MEI_ERR_FAILURE;
+ }
+ //WriteARCreg(AUX_IC_CTRL,2);
+ IFX_MEI_DMSG("Setting MEI_MASTER_MODE..\n");
+ IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
+#define AUX_IC_CTRL 0x11
+ _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
+ AUX_IC_CTRL, 2);
+ IFX_MEI_DMSG("Setting JTAG_MASTER_MODE..\n");
+ IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
+
+ IFX_MEI_DMSG("Halting ARC...\n");
+ IFX_MEI_HaltArc (&dsl_devices[0]);
+
+#ifdef DFE_PING_TEST
+
+ IFX_MEI_DMSG("ping test image size=%d\n", sizeof (arc_ahb_access_code));
+ memcpy ((u8 *) (DSL_DEV_PRIVATE(pDev)->
+ adsl_mem_info[0].address + 0x1004),
+ &arc_ahb_access_code[0], sizeof (arc_ahb_access_code));
+ load_jump_table (0x80000 + 0x1004);
+
+#endif //DFE_PING_TEST
+
+ IFX_MEI_DMSG("ARC ping test code download complete\n");
+#endif //defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
+#ifdef DFE_MEM_TEST
+ IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ARC2ME_MASK, MSGAV_EN);
+
+ arc_code_page_download (1537, &code_array[0]);
+ IFX_MEI_DMSG("ARC mem test code download complete\n");
+#endif //DFE_MEM_TEST
+#ifdef DFE_ATM_LOOPBACK
+ arc_debug_data = 0xf;
+ arc_code_page_download (sizeof(code_array) / sizeof(*code_array), &code_array[0]);
+ wr_mbox[0] = 0; //TIMER_DELAY - org: 1024
+ wr_mbox[1] = 0; //TXFB_START0
+ wr_mbox[2] = 0x7f; //TXFB_END0 - org: 49
+ wr_mbox[3] = 0x80; //TXFB_START1 - org: 80
+ wr_mbox[4] = 0xff; //TXFB_END1 - org: 109
+ wr_mbox[5] = 0x100; //RXFB_START0 - org: 0
+ wr_mbox[6] = 0x17f; //RXFB_END0 - org: 49
+ wr_mbox[7] = 0x180; //RXFB_START1 - org: 256
+ wr_mbox[8] = 0x1ff; //RXFB_END1 - org: 315
+ WriteMbox (&wr_mbox[0], 9);
+ // Start Iridia IT_AMODE (in dmp access) why is it required?
+ IFX_MEI_DebugWrite (&dsl_devices[0], 0x32010, &arc_debug_data, 1);
+#endif //DFE_ATM_LOOPBACK
+ IFX_MEI_IRQEnable (pDev);
+ IFX_MEI_DMSG("run ARC...\n");
+ IFX_MEI_RunArc (&dsl_devices[0]);
+
+#ifdef DFE_PING_TEST
+ arc_ping_testing (pDev);
+#endif //DFE_PING_TEST
+#ifdef DFE_MEM_TEST
+ wait_mem_test_result ();
+#endif //DFE_MEM_TEST
+
+ IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
+ return DSL_DEV_MEI_ERR_SUCCESS;
+}
+
+#endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
+
+static int
+IFX_MEI_InitDevNode (int num)
+{
+ if (num == 0) {
+ if ((dev_major = register_chrdev (dev_major, IFX_MEI_DEVNAME, &bsp_mei_operations)) < 0) {
+ IFX_MEI_EMSG ("register_chrdev(%d %s) failed!\n", dev_major, IFX_MEI_DEVNAME);
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+static int
+IFX_MEI_CleanUpDevNode (int num)
+{
+ if (num == 0)
+ unregister_chrdev (dev_major, MEI_DIRNAME);
+ return 0;
+}
+
+static int
+IFX_MEI_InitDevice (int num)
+{
+ DSL_DEV_Device_t *pDev;
+ u32 temp;
+ pDev = &dsl_devices[num];
+ if (pDev == NULL)
+ return -ENOMEM;
+ pDev->pPriv = &sDanube_Mei_Private[num];
+ memset (pDev->pPriv, 0, sizeof (ifx_mei_device_private_t));
+
+ memset (&DSL_DEV_PRIVATE(pDev)->
+ adsl_mem_info[0], 0,
+ sizeof (smmu_mem_info_t) * MAX_BAR_REGISTERS);
+
+ if (num == 0) {
+ pDev->nIrq[IFX_DFEIR] = LTQ_MEI_INT;
+ pDev->nIrq[IFX_DYING_GASP] = LTQ_MEI_DYING_GASP_INT;
+ pDev->base_address = KSEG1 + LTQ_MEI_BASE_ADDR;
+
+ /* Power up MEI */
+#ifdef CONFIG_LANTIQ_AMAZON_SE
+ *LTQ_PMU_PWDCR &= ~(1 << 9); // enable dsl
+ *LTQ_PMU_PWDCR &= ~(1 << 15); // enable AHB base
+#else
+ temp = ltq_r32(LTQ_PMU_PWDCR);
+ temp &= 0xffff7dbe;
+ ltq_w32(temp, LTQ_PMU_PWDCR);
+#endif
+ }
+ pDev->nInUse = 0;
+ DSL_DEV_PRIVATE(pDev)->modem_ready = 0;
+ DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
+
+ MEI_INIT_WAKELIST ("arcq", DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav); // for ARCMSGAV
+ MEI_INIT_WAKELIST ("arcr", DSL_DEV_PRIVATE(pDev)->wait_queue_modemready); // for arc modem ready
+
+ MEI_MUTEX_INIT (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema, 1); // semaphore initialization, mutex
+#if 0
+ MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DFEIR]);
+ MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DYING_GASP]);
+#endif
+ if (request_irq (pDev->nIrq[IFX_DFEIR], IFX_MEI_IrqHandle, 0, "DFEIR", pDev) != 0) {
+ IFX_MEI_EMSG ("request_irq %d failed!\n", pDev->nIrq[IFX_DFEIR]);
+ return -1;
+ }
+ /*if (request_irq (pDev->nIrq[IFX_DYING_GASP], IFX_MEI_Dying_Gasp_IrqHandle, 0, "DYING_GASP", pDev) != 0) {
+ IFX_MEI_EMSG ("request_irq %d failed!\n", pDev->nIrq[IFX_DYING_GASP]);
+ return -1;
+ }*/
+// IFX_MEI_DMSG("Device %d initialized. IER %#x\n", num, bsp_get_irq_ier(pDev->nIrq[IFX_DYING_GASP]));
+ return 0;
+}
+
+static int
+IFX_MEI_ExitDevice (int num)
+{
+ DSL_DEV_Device_t *pDev;
+ pDev = &dsl_devices[num];
+
+ if (pDev == NULL)
+ return -EIO;
+
+ disable_irq (pDev->nIrq[IFX_DFEIR]);
+ disable_irq (pDev->nIrq[IFX_DYING_GASP]);
+
+ free_irq(pDev->nIrq[IFX_DFEIR], pDev);
+ free_irq(pDev->nIrq[IFX_DYING_GASP], pDev);
+
+ return 0;
+}
+
+static DSL_DEV_Device_t *
+IFX_BSP_HandleGet (int maj, int num)
+{
+ if (num > BSP_MAX_DEVICES)
+ return NULL;
+ return &dsl_devices[num];
+}
+
+DSL_DEV_Device_t *
+DSL_BSP_DriverHandleGet (int maj, int num)
+{
+ DSL_DEV_Device_t *pDev;
+
+ if (num > BSP_MAX_DEVICES)
+ return NULL;
+
+ pDev = &dsl_devices[num];
+ if (!try_module_get(pDev->owner))
+ return NULL;
+
+ pDev->nInUse++;
+ return pDev;
+}
+
+int
+DSL_BSP_DriverHandleDelete (DSL_DEV_Device_t * nHandle)
+{
+ DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) nHandle;
+ if (pDev->nInUse)
+ pDev->nInUse--;
+ module_put(pDev->owner);
+ return 0;
+}
+
+static int
+IFX_MEI_Open (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil)
+{
+ int maj = MAJOR (ino->i_rdev);
+ int num = MINOR (ino->i_rdev);
+
+ DSL_DEV_Device_t *pDev = NULL;
+ if ((pDev = DSL_BSP_DriverHandleGet (maj, num)) == NULL) {
+ IFX_MEI_EMSG("open(%d:%d) fail!\n", maj, num);
+ return -EIO;
+ }
+ fil->private_data = pDev;
+ return 0;
+}
+
+static int
+IFX_MEI_Release (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil)
+{
+ //int maj = MAJOR(ino->i_rdev);
+ int num = MINOR (ino->i_rdev);
+ DSL_DEV_Device_t *pDev;
+
+ pDev = &dsl_devices[num];
+ if (pDev == NULL)
+ return -EIO;
+ DSL_BSP_DriverHandleDelete (pDev);
+ return 0;
+}
+
+/**
+ * Callback function for linux userspace program writing
+ */
+static ssize_t
+IFX_MEI_Write (DSL_DRV_file_t * filp, const char *buf, size_t size, loff_t * loff)
+{
+ DSL_DEV_MeiError_t mei_error = DSL_DEV_MEI_ERR_FAILURE;
+ long offset = 0;
+ DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) filp->private_data;
+
+ if (pDev == NULL)
+ return -EIO;
+
+ mei_error =
+ DSL_BSP_FWDownload (pDev, buf, size, (long *) loff, &offset);
+
+ if (mei_error == DSL_DEV_MEI_ERR_FAILURE)
+ return -EIO;
+ return (ssize_t) offset;
+}
+
+/**
+ * Callback function for linux userspace program ioctling
+ */
+static int
+IFX_MEI_IoctlCopyFrom (int from_kernel, char *dest, char *from, int size)
+{
+ int ret = 0;
+
+ if (!from_kernel)
+ ret = copy_from_user ((char *) dest, (char *) from, size);
+ else
+ ret = (int)memcpy ((char *) dest, (char *) from, size);
+ return ret;
+}
+
+static int
+IFX_MEI_IoctlCopyTo (int from_kernel, char *dest, char *from, int size)
+{
+ int ret = 0;
+
+ if (!from_kernel)
+ ret = copy_to_user ((char *) dest, (char *) from, size);
+ else
+ ret = (int)memcpy ((char *) dest, (char *) from, size);
+ return ret;
+}
+
+int
+IFX_MEI_Ioctls (DSL_DEV_Device_t * pDev, int from_kernel, unsigned int command, unsigned long lon)
+{
+ int i = 0;
+ int meierr = DSL_DEV_MEI_ERR_SUCCESS;
+ u32 base_address = LTQ_MEI_BASE_ADDR;
+ DSL_DEV_WinHost_Message_t winhost_msg, m;
+// DSL_DEV_MeiDebug_t debugrdwr;
+ DSL_DEV_MeiReg_t regrdwr;
+
+ switch (command) {
+
+ case DSL_FIO_BSP_CMV_WINHOST:
+ IFX_MEI_IoctlCopyFrom (from_kernel, (char *) winhost_msg.msg.TxMessage,
+ (char *) lon, MSG_LENGTH * 2);
+
+ if ((meierr = DSL_BSP_SendCMV (pDev, winhost_msg.msg.TxMessage, YES_REPLY,
+ winhost_msg.msg.RxMessage)) != DSL_DEV_MEI_ERR_SUCCESS) {
+ IFX_MEI_EMSG ("WINHOST CMV fail :TxMessage:%X %X %X %X, RxMessage:%X %X %X %X %X\n",
+ winhost_msg.msg.TxMessage[0], winhost_msg.msg.TxMessage[1], winhost_msg.msg.TxMessage[2], winhost_msg.msg.TxMessage[3],
+ winhost_msg.msg.RxMessage[0], winhost_msg.msg.RxMessage[1], winhost_msg.msg.RxMessage[2], winhost_msg.msg.RxMessage[3],
+ winhost_msg.msg.RxMessage[4]);
+ meierr = DSL_DEV_MEI_ERR_FAILURE;
+ }
+ else {
+ IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
+ (char *) winhost_msg.msg.RxMessage,
+ MSG_LENGTH * 2);
+ }
+ break;
+
+ case DSL_FIO_BSP_CMV_READ:
+ IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (&regrdwr),
+ (char *) lon, sizeof (DSL_DEV_MeiReg_t));
+
+ IFX_MEI_LongWordRead ((u32) regrdwr.iAddress,
+ (u32 *) & (regrdwr.iData));
+
+ IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
+ (char *) (&regrdwr),
+ sizeof (DSL_DEV_MeiReg_t));
+
+ break;
+
+ case DSL_FIO_BSP_CMV_WRITE:
+ IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (&regrdwr),
+ (char *) lon, sizeof (DSL_DEV_MeiReg_t));
+
+ IFX_MEI_LongWordWrite ((u32) regrdwr.iAddress,
+ regrdwr.iData);
+ break;
+
+ case DSL_FIO_BSP_GET_BASE_ADDRESS:
+ IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
+ (char *) (&base_address),
+ sizeof (base_address));
+ break;
+
+ case DSL_FIO_BSP_IS_MODEM_READY:
+ i = IFX_MEI_IsModemReady (pDev);
+ IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
+ (char *) (&i), sizeof (int));
+ meierr = DSL_DEV_MEI_ERR_SUCCESS;
+ break;
+ case DSL_FIO_BSP_RESET:
+ case DSL_FIO_BSP_REBOOT:
+ meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_RESET);
+ meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_HALT);
+ break;
+
+ case DSL_FIO_BSP_HALT:
+ meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_HALT);
+ break;
+
+ case DSL_FIO_BSP_RUN:
+ meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_RUN);
+ break;
+ case DSL_FIO_BSP_BOOTDOWNLOAD:
+ meierr = IFX_MEI_DownloadBootCode (pDev);
+ break;
+ case DSL_FIO_BSP_JTAG_ENABLE:
+ meierr = IFX_MEI_ArcJtagEnable (pDev, 1);
+ break;
+
+ case DSL_FIO_BSP_REMOTE:
+ IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (&i),
+ (char *) lon, sizeof (int));
+
+ meierr = IFX_MEI_AdslMailboxIRQEnable (pDev, i);
+ break;
+
+ case DSL_FIO_BSP_DSL_START:
+ IFX_MEI_DMSG("DSL_FIO_BSP_DSL_START\n");
+ if ((meierr = IFX_MEI_RunAdslModem (pDev)) != DSL_DEV_MEI_ERR_SUCCESS) {
+ IFX_MEI_EMSG ("IFX_MEI_RunAdslModem() error...");
+ meierr = DSL_DEV_MEI_ERR_FAILURE;
+ }
+ break;
+
+/* case DSL_FIO_BSP_DEBUG_READ:
+ case DSL_FIO_BSP_DEBUG_WRITE:
+ IFX_MEI_IoctlCopyFrom (from_kernel,
+ (char *) (&debugrdwr),
+ (char *) lon,
+ sizeof (debugrdwr));
+
+ if (command == DSL_FIO_BSP_DEBUG_READ)
+ meierr = DSL_BSP_MemoryDebugAccess (pDev,
+ DSL_BSP_MEMORY_READ,
+ debugrdwr.
+ iAddress,
+ debugrdwr.
+ buffer,
+ debugrdwr.
+ iCount);
+ else
+ meierr = DSL_BSP_MemoryDebugAccess (pDev,
+ DSL_BSP_MEMORY_WRITE,
+ debugrdwr.
+ iAddress,
+ debugrdwr.
+ buffer,
+ debugrdwr.
+ iCount);
+
+ IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&debugrdwr), sizeof (debugrdwr));
+ break;*/
+ case DSL_FIO_BSP_GET_VERSION:
+ IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&bsp_mei_version), sizeof (DSL_DEV_Version_t));
+ break;
+
+#define LTQ_MPS_CHIPID_VERSION_GET(value) (((value) >> 28) & ((1 << 4) - 1))
+ case DSL_FIO_BSP_GET_CHIP_INFO:
+ bsp_chip_info.major = 1;
+ bsp_chip_info.minor = LTQ_MPS_CHIPID_VERSION_GET(*LTQ_MPS_CHIPID);
+ IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&bsp_chip_info), sizeof (DSL_DEV_HwVersion_t));
+ meierr = DSL_DEV_MEI_ERR_SUCCESS;
+ break;
+
+ case DSL_FIO_BSP_FREE_RESOURCE:
+ makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_STAT, 4, 0, 1, NULL, m.msg.TxMessage);
+ if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS) {
+ meierr = DSL_DEV_MEI_ERR_FAILURE;
+ return -EIO;
+ }
+ IFX_MEI_DMSG("RxMessage[4] = %#x\n", m.msg.RxMessage[4]);
+ if (!(m.msg.RxMessage[4] & DSL_DEV_STAT_CODESWAP_COMPLETE)) {
+ meierr = DSL_DEV_MEI_ERR_FAILURE;
+ return -EAGAIN;
+ }
+ IFX_MEI_DMSG("Freeing all memories marked FREE_SHOWTIME\n");
+ IFX_MEI_DFEMemoryFree (pDev, FREE_SHOWTIME);
+ meierr = DSL_DEV_MEI_ERR_SUCCESS;
+ break;
+#ifdef CONFIG_IFXMIPS_AMAZON_SE
+ case DSL_FIO_ARC_MUX_TEST:
+ AMAZON_SE_MEI_ARC_MUX_Test();
+ break;
+#endif
+ default:
+// IFX_MEI_EMSG("Invalid IOCTL command: %d\n");
+ break;
+ }
+ return meierr;
+}
+
+#ifdef CONFIG_IFXMIPS_AMAZON_SE
+void AMAZON_SE_MEI_ARC_MUX_Test(void)
+{
+ u32 *p, i;
+ *LTQ_RCU_RST |= LTQ_RCU_RST_REQ_MUX_ARC;
+
+ p = (u32*)(DFE_LDST_BASE_ADDR + IRAM0_BASE);
+ IFX_MEI_EMSG("Writing to IRAM0(%p)...\n", p);
+ for (i = 0; i < IRAM0_SIZE/sizeof(u32); i++, p++) {
+ *p = 0xdeadbeef;
+ if (*p != 0xdeadbeef)
+ IFX_MEI_EMSG("%p: %#x\n", p, *p);
+ }
+
+ p = (u32*)(DFE_LDST_BASE_ADDR + IRAM1_BASE);
+ IFX_MEI_EMSG("Writing to IRAM1(%p)...\n", p);
+ for (i = 0; i < IRAM1_SIZE/sizeof(u32); i++, p++) {
+ *p = 0xdeadbeef;
+ if (*p != 0xdeadbeef)
+ IFX_MEI_EMSG("%p: %#x\n", p, *p);
+ }
+
+ p = (u32*)(DFE_LDST_BASE_ADDR + BRAM_BASE);
+ IFX_MEI_EMSG("Writing to BRAM(%p)...\n", p);
+ for (i = 0; i < BRAM_SIZE/sizeof(u32); i++, p++) {
+ *p = 0xdeadbeef;
+ if (*p != 0xdeadbeef)
+ IFX_MEI_EMSG("%p: %#x\n", p, *p);
+ }
+
+ p = (u32*)(DFE_LDST_BASE_ADDR + XRAM_BASE);
+ IFX_MEI_EMSG("Writing to XRAM(%p)...\n", p);
+ for (i = 0; i < XRAM_SIZE/sizeof(u32); i++, p++) {
+ *p = 0xdeadbeef;
+ if (*p != 0xdeadbeef)
+ IFX_MEI_EMSG("%p: %#x\n", p, *p);
+ }
+
+ p = (u32*)(DFE_LDST_BASE_ADDR + YRAM_BASE);
+ IFX_MEI_EMSG("Writing to YRAM(%p)...\n", p);
+ for (i = 0; i < YRAM_SIZE/sizeof(u32); i++, p++) {
+ *p = 0xdeadbeef;
+ if (*p != 0xdeadbeef)
+ IFX_MEI_EMSG("%p: %#x\n", p, *p);
+ }
+
+ p = (u32*)(DFE_LDST_BASE_ADDR + EXT_MEM_BASE);
+ IFX_MEI_EMSG("Writing to EXT_MEM(%p)...\n", p);
+ for (i = 0; i < EXT_MEM_SIZE/sizeof(u32); i++, p++) {
+ *p = 0xdeadbeef;
+ if (*p != 0xdeadbeef)
+ IFX_MEI_EMSG("%p: %#x\n", p, *p);
+ }
+ *LTQ_RCU_RST &= ~LTQ_RCU_RST_REQ_MUX_ARC;
+}
+#endif
+int
+DSL_BSP_KernelIoctls (DSL_DEV_Device_t * pDev, unsigned int command,
+ unsigned long lon)
+{
+ int error = 0;
+
+ error = IFX_MEI_Ioctls (pDev, 1, command, lon);
+ return error;
+}
+
+static long
+IFX_MEI_UserIoctls (DSL_DRV_file_t * fil,
+ unsigned int command, unsigned long lon)
+{
+ int error = 0;
+ DSL_DEV_Device_t *pDev;
+
+ pDev = IFX_BSP_HandleGet (0, 0);
+ if (pDev == NULL)
+ return -EIO;
+
+ error = IFX_MEI_Ioctls (pDev, 0, command, lon);
+ return error;
+}
+
+static int adsl_dummy_ledcallback(void)
+{
+ return 0;
+}
+
+int ifx_mei_atm_led_blink(void)
+{
+ return g_adsl_ledcallback();
+}
+EXPORT_SYMBOL(ifx_mei_atm_led_blink);
+
+int ifx_mei_atm_showtime_check(int *is_showtime, struct port_cell_info *port_cell, void **xdata_addr)
+{
+ int i;
+
+ if ( is_showtime ) {
+ *is_showtime = g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 ? 0 : 1;
+ }
+
+ if ( port_cell ) {
+ for ( i = 0; i < port_cell->port_num && i < 2; i++ )
+ port_cell->tx_link_rate[i] = g_tx_link_rate[i];
+ }
+
+ if ( xdata_addr ) {
+ if ( g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 )
+ *xdata_addr = NULL;
+ else
+ *xdata_addr = g_xdata_addr;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(ifx_mei_atm_showtime_check);
+
+/*
+ * Writing function for linux proc filesystem
+ */
+static int ltq_mei_probe(struct platform_device *pdev)
+{
+ int i = 0;
+ static struct class *dsl_class;
+
+ pr_info("IFX MEI Version %ld.%02ld.%02ld\n", bsp_mei_version.major, bsp_mei_version.minor, bsp_mei_version.revision);
+
+ for (i = 0; i < BSP_MAX_DEVICES; i++) {
+ if (IFX_MEI_InitDevice (i) != 0) {
+ IFX_MEI_EMSG("Init device fail!\n");
+ return -EIO;
+ }
+ IFX_MEI_InitDevNode (i);
+ }
+ for (i = 0; i <= DSL_BSP_CB_LAST ; i++)
+ dsl_bsp_event_callback[i].function = NULL;
+
+#ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
+ IFX_MEI_DMSG("Start loopback test...\n");
+ DFE_Loopback_Test ();
+#endif
+ dsl_class = class_create(THIS_MODULE, "ifx_mei");
+ device_create(dsl_class, NULL, MKDEV(MEI_MAJOR, 0), NULL, "ifx_mei");
+ return 0;
+}
+
+static int ltq_mei_remove(struct platform_device *pdev)
+{
+ int i = 0;
+ int num;
+
+ for (num = 0; num < BSP_MAX_DEVICES; num++) {
+ IFX_MEI_CleanUpDevNode (num);
+ }
+
+ for (i = 0; i < BSP_MAX_DEVICES; i++) {
+ for (i = 0; i < BSP_MAX_DEVICES; i++) {
+ IFX_MEI_ExitDevice (i);
+ }
+ }
+ return 0;
+}
+
+static const struct of_device_id ltq_mei_match[] = {
+ { .compatible = "lantiq,mei-xway"},
+ {},
+};
+
+static struct platform_driver ltq_mei_driver = {
+ .probe = ltq_mei_probe,
+ .remove = ltq_mei_remove,
+ .driver = {
+ .name = "lantiq,mei-xway",
+ .owner = THIS_MODULE,
+ .of_match_table = ltq_mei_match,
+ },
+};
+
+module_platform_driver(ltq_mei_driver);
+
+/* export function for DSL Driver */
+
+/* The functions of MEI_DriverHandleGet and MEI_DriverHandleDelete are
+something like open/close in kernel space , where the open could be used
+to register a callback for autonomous messages and returns a mei driver context pointer (comparable to the file descriptor in user space)
+ The context will be required for the multi line chips future! */
+
+EXPORT_SYMBOL (DSL_BSP_DriverHandleGet);
+EXPORT_SYMBOL (DSL_BSP_DriverHandleDelete);
+
+EXPORT_SYMBOL (DSL_BSP_ATMLedCBRegister);
+EXPORT_SYMBOL (DSL_BSP_ATMLedCBUnregister);
+EXPORT_SYMBOL (DSL_BSP_KernelIoctls);
+EXPORT_SYMBOL (DSL_BSP_AdslLedInit);
+//EXPORT_SYMBOL (DSL_BSP_AdslLedSet);
+EXPORT_SYMBOL (DSL_BSP_FWDownload);
+EXPORT_SYMBOL (DSL_BSP_Showtime);
+
+EXPORT_SYMBOL (DSL_BSP_MemoryDebugAccess);
+EXPORT_SYMBOL (DSL_BSP_SendCMV);
+
+// provide a register/unregister function for DSL driver to register a event callback function
+EXPORT_SYMBOL (DSL_BSP_EventCBRegister);
+EXPORT_SYMBOL (DSL_BSP_EventCBUnregister);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/package/kernel/lantiq/ltq-adsl/Config.in b/package/kernel/lantiq/ltq-adsl/Config.in
new file mode 100644
index 0000000000..6d9caf4419
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl/Config.in
@@ -0,0 +1,5 @@
+config LANTIQ_DSL_DEBUG
+ bool "verbose debugging"
+ depends on PACKAGE_kmod-ltq-dsl
+ help
+ Say Y, if you need ltq-dsl to display debug messages.
diff --git a/package/kernel/lantiq/ltq-adsl/Makefile b/package/kernel/lantiq/ltq-adsl/Makefile
new file mode 100644
index 0000000000..6a0daa25c9
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl/Makefile
@@ -0,0 +1,96 @@
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ltq-adsl
+PKG_VERSION:=3.24.4.4
+PKG_RELEASE:=1
+PKG_SOURCE:=drv_dsl_cpe_api_danube-$(PKG_VERSION).tar.gz
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-dsl-$(BUILD_VARIANT)/drv_dsl_cpe_api-$(PKG_VERSION)
+PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
+PKG_MD5SUM:=c45bc531c1ed2ac80f68fb986b63bb87
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-adsl-template
+ SECTION:=sys
+ CATEGORY:=Kernel modules
+ SUBMENU:=Network Devices
+ TITLE:=adsl driver for $(1)
+ URL:=http://www.lantiq.com/
+ VARIANT:=$(1)
+ DEPENDS:=@TARGET_lantiq_$(2) +kmod-ltq-adsl-$(1)-mei
+ FILES:=$(PKG_BUILD_DIR)/src/drv_dsl_cpe_api.ko
+ AUTOLOAD:=$(call AutoLoad,51,drv_dsl_cpe_api)
+endef
+
+KernelPackage/ltq-adsl-danube=$(call KernelPackage/ltq-adsl-template,danube,xway)
+KernelPackage/ltq-adsl-ar9=$(call KernelPackage/ltq-adsl-template,ar9,xway)
+KernelPackage/ltq-adsl-ase=$(call KernelPackage/ltq-adsl-template,ase,ase)
+
+define KernelPackage/ltq-dsl/config
+ source "$(SOURCE)/Config.in"
+endef
+
+IFX_DSL_MAX_DEVICE=1
+IFX_DSL_LINES_PER_DEVICE=1
+IFX_DSL_CHANNELS_PER_LINE=1
+
+CONFIGURE_ARGS += --enable-kernel-include="$(LINUX_DIR)/include" \
+ --with-max-device="$(IFX_DSL_MAX_DEVICE)" \
+ --with-lines-per-device="$(IFX_DSL_LINES_PER_DEVICE)" \
+ --with-channels-per-line="$(IFX_DSL_CHANNELS_PER_LINE)" \
+ --disable-dsl-delt-static \
+ --disable-adsl-led \
+ --enable-dsl-ceoc \
+ --enable-dsl-pm \
+ --enable-dsl-pm-total \
+ --enable-dsl-pm-history \
+ --enable-dsl-pm-showtime \
+ --enable-dsl-pm-channel-counters \
+ --enable-dsl-pm-datapath-counters \
+ --enable-dsl-pm-line-counters \
+ --enable-dsl-pm-channel-thresholds \
+ --enable-dsl-pm-datapath-thresholds \
+ --enable-dsl-pm-line-thresholds \
+ --enable-dsl-pm-optional-parameters \
+ --enable-linux-26 \
+ --enable-kernelbuild="$(LINUX_DIR)" \
+ ARCH=$(LINUX_KARCH)
+
+CONFIG_TAG_danube:=DANUBE
+CONFIG_TAG_ase:=AMAZON_SE
+CONFIG_TAG_ar9:=AR9
+CONFIGURE_ARGS += --enable-add-drv-cflags="-DMODULE -DCONFIG_$(CONFIG_TAG_$(BUILD_VARIANT))"
+
+CONFIGURE_ARGS += --enable-danube
+
+ifeq ($(CONFIG_LANTIQ_DSL_DEBUG),y)
+CONFIGURE_ARGS += \
+ --enable-debug=yes \
+ --enable-debug-prints=yes
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+EXTRA_CFLAGS = -fno-pic -mno-abicalls -mlong-calls -G 0
+
+define Build/Configure
+ (cd $(PKG_BUILD_DIR); aclocal && autoconf && automake)
+ $(call Build/Configure/Default)
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include/adsl
+ $(CP) $(PKG_BUILD_DIR)/src/include/drv_dsl_cpe_*.h $(1)/usr/include/adsl/
+endef
+
+$(eval $(call KernelPackage,ltq-adsl-danube))
+$(eval $(call KernelPackage,ltq-adsl-ase))
+$(eval $(call KernelPackage,ltq-adsl-ar9))
diff --git a/package/kernel/lantiq/ltq-adsl/patches/100-dsl_compat.patch b/package/kernel/lantiq/ltq-adsl/patches/100-dsl_compat.patch
new file mode 100644
index 0000000000..f2ed230bd0
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl/patches/100-dsl_compat.patch
@@ -0,0 +1,1065 @@
+Index: drv_dsl_cpe_api-3.24.4.4/src/include/drv_dsl_cpe_device_danube.h
+===================================================================
+--- drv_dsl_cpe_api-3.24.4.4.orig/src/include/drv_dsl_cpe_device_danube.h 2009-05-12 20:02:16.000000000 +0200
++++ drv_dsl_cpe_api-3.24.4.4/src/include/drv_dsl_cpe_device_danube.h 2012-11-29 19:47:21.060210322 +0100
+@@ -24,7 +24,7 @@
+ #include "drv_dsl_cpe_simulator_danube.h"
+ #else
+ /* Include for the low level driver interface header file */
+-#include "asm/ifx/ifx_mei_bsp.h"
++#include "ifxmips_mei_interface.h"
+ #endif /* defined(DSL_CPE_SIMULATOR_DRIVER) && defined(WIN32)*/
+
+ #define DSL_MAX_LINE_NUMBER 1
+Index: drv_dsl_cpe_api-3.24.4.4/src/common/drv_dsl_cpe_os_linux.c
+===================================================================
+--- drv_dsl_cpe_api-3.24.4.4.orig/src/common/drv_dsl_cpe_os_linux.c 2009-07-13 11:33:43.000000000 +0200
++++ drv_dsl_cpe_api-3.24.4.4/src/common/drv_dsl_cpe_os_linux.c 2012-11-29 19:46:32.700209112 +0100
+@@ -11,6 +11,7 @@
+ #ifdef __LINUX__
+
+ #define DSL_INTERN
++#include <linux/device.h>
+
+ #include "drv_dsl_cpe_api.h"
+ #include "drv_dsl_cpe_api_ioctl.h"
+@@ -34,9 +35,13 @@
+ static DSL_ssize_t DSL_DRV_Write(DSL_DRV_file_t *pFile, const DSL_char_t * pBuf,
+ DSL_DRV_size_t nSize, DSL_DRV_offset_t * pLoff);
+
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
+ static DSL_int_t DSL_DRV_Ioctls(DSL_DRV_inode_t * pINode, DSL_DRV_file_t * pFile,
+ DSL_uint_t nCommand, unsigned long nArg);
+-
++#else
++static DSL_int_t DSL_DRV_Ioctls(DSL_DRV_file_t * pFile,
++ DSL_uint_t nCommand, unsigned long nArg);
++#endif
+ static int DSL_DRV_Open(DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil);
+
+ static int DSL_DRV_Release(DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil);
+@@ -72,7 +77,11 @@
+ open: DSL_DRV_Open,
+ release: DSL_DRV_Release,
+ write: DSL_DRV_Write,
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
+ ioctl: DSL_DRV_Ioctls,
++#else
++ unlocked_ioctl: DSL_DRV_Ioctls,
++#endif
+ poll: DSL_DRV_Poll
+ };
+ #else
+@@ -168,10 +177,17 @@
+ \return Success or failure.
+ \ingroup Internal
+ */
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
+ static DSL_int_t DSL_DRV_Ioctls(DSL_DRV_inode_t * pINode,
+ DSL_DRV_file_t * pFile,
+ DSL_uint_t nCommand,
+ unsigned long nArg)
++#else
++static DSL_int_t DSL_DRV_Ioctls(
++ DSL_DRV_file_t * pFile,
++ DSL_uint_t nCommand,
++ unsigned long nArg)
++#endif
+ {
+ DSL_int_t nErr=0;
+ DSL_boolean_t bIsInKernel;
+@@ -216,16 +232,7 @@
+ }
+ }
+ }
+-
+- if (pINode == DSL_NULL)
+- {
+- bIsInKernel = DSL_TRUE;
+- }
+- else
+- {
+- bIsInKernel = DSL_FALSE;
+- }
+-
++ bIsInKernel = DSL_FALSE;
+ if ( (_IOC_TYPE(nCommand) == DSL_IOC_MAGIC_CPE_API) ||
+ (_IOC_TYPE(nCommand) == DSL_IOC_MAGIC_CPE_API_G997) ||
+ (_IOC_TYPE(nCommand) == DSL_IOC_MAGIC_CPE_API_PM) ||
+@@ -1058,6 +1065,7 @@
+ /* Entry point of driver */
+ int __init DSL_ModuleInit(void)
+ {
++ struct class *dsl_class;
+ DSL_int_t i;
+
+ printk(DSL_DRV_CRLF DSL_DRV_CRLF "Infineon CPE API Driver version: %s" DSL_DRV_CRLF,
+@@ -1104,7 +1112,8 @@
+ }
+
+ DSL_DRV_DevNodeInit();
+-
++ dsl_class = class_create(THIS_MODULE, "dsl_cpe_api");
++ device_create(dsl_class, NULL, MKDEV(DRV_DSL_CPE_API_DEV_MAJOR, 0), NULL, "dsl_cpe_api");
+ return 0;
+ }
+
+Index: drv_dsl_cpe_api-3.24.4.4/src/include/drv_dsl_cpe_os_linux.h
+===================================================================
+--- drv_dsl_cpe_api-3.24.4.4.orig/src/include/drv_dsl_cpe_os_linux.h 2009-07-03 17:04:51.000000000 +0200
++++ drv_dsl_cpe_api-3.24.4.4/src/include/drv_dsl_cpe_os_linux.h 2012-11-29 19:47:23.092210377 +0100
+@@ -17,17 +17,17 @@
+ #endif
+
+ #include <asm/ioctl.h>
+-#include <linux/autoconf.h>
++#include <generated/autoconf.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/ctype.h>
+ #include <linux/version.h>
+ #include <linux/spinlock.h>
+-
++#include <linux/sched.h>
+
+ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+- #include <linux/utsrelease.h>
++ #include <generated/utsrelease.h>
+ #endif
+
+ #include <linux/types.h>
+Index: drv_dsl_cpe_api-3.24.4.4/src/ifxmips_mei_interface.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ drv_dsl_cpe_api-3.24.4.4/src/ifxmips_mei_interface.h 2012-11-29 19:47:54.972211177 +0100
+@@ -0,0 +1,702 @@
++/******************************************************************************
++
++ Copyright (c) 2009
++ Infineon Technologies AG
++ Am Campeon 1-12; 81726 Munich, Germany
++
++ For licensing information, see the file 'LICENSE' in the root folder of
++ this software module.
++
++******************************************************************************/
++
++#ifndef IFXMIPS_MEI_H
++#define IFXMIPS_MEI_H
++
++//#define CONFIG_AMAZON_SE 1
++//#define CONFIG_DANUBE 1
++//#define CONFIG_AR9 1
++
++#if !defined(CONFIG_DANUBE) && !defined(CONFIG_AMAZON_SE) && !defined(CONFIG_AR9) && !defined(CONFIG_VR9)
++#error Platform undefined!!!
++#endif
++
++#ifdef IFX_MEI_BSP
++/** This is the character datatype. */
++typedef char DSL_char_t;
++/** This is the unsigned 8-bit datatype. */
++typedef unsigned char DSL_uint8_t;
++/** This is the signed 8-bit datatype. */
++typedef signed char DSL_int8_t;
++/** This is the unsigned 16-bit datatype. */
++typedef unsigned short DSL_uint16_t;
++/** This is the signed 16-bit datatype. */
++typedef signed short DSL_int16_t;
++/** This is the unsigned 32-bit datatype. */
++typedef unsigned long DSL_uint32_t;
++/** This is the signed 32-bit datatype. */
++typedef signed long DSL_int32_t;
++/** This is the float datatype. */
++typedef float DSL_float_t;
++/** This is the void datatype. */
++typedef void DSL_void_t;
++/** integer type, width is depending on processor arch */
++typedef int DSL_int_t;
++/** unsigned integer type, width is depending on processor arch */
++typedef unsigned int DSL_uint_t;
++typedef struct file DSL_DRV_file_t;
++typedef struct inode DSL_DRV_inode_t;
++
++/**
++ * Defines all possible CMV groups
++ * */
++typedef enum {
++ DSL_CMV_GROUP_CNTL = 1,
++ DSL_CMV_GROUP_STAT = 2,
++ DSL_CMV_GROUP_INFO = 3,
++ DSL_CMV_GROUP_TEST = 4,
++ DSL_CMV_GROUP_OPTN = 5,
++ DSL_CMV_GROUP_RATE = 6,
++ DSL_CMV_GROUP_PLAM = 7,
++ DSL_CMV_GROUP_CNFG = 8
++} DSL_CmvGroup_t;
++/**
++ * Defines all opcode types
++ * */
++typedef enum {
++ H2D_CMV_READ = 0x00,
++ H2D_CMV_WRITE = 0x04,
++ H2D_CMV_INDICATE_REPLY = 0x10,
++ H2D_ERROR_OPCODE_UNKNOWN =0x20,
++ H2D_ERROR_CMV_UNKNOWN =0x30,
++
++ D2H_CMV_READ_REPLY =0x01,
++ D2H_CMV_WRITE_REPLY = 0x05,
++ D2H_CMV_INDICATE = 0x11,
++ D2H_ERROR_OPCODE_UNKNOWN = 0x21,
++ D2H_ERROR_CMV_UNKNOWN = 0x31,
++ D2H_ERROR_CMV_READ_NOT_AVAILABLE = 0x41,
++ D2H_ERROR_CMV_WRITE_ONLY = 0x51,
++ D2H_ERROR_CMV_READ_ONLY = 0x61,
++
++ H2D_DEBUG_READ_DM = 0x02,
++ H2D_DEBUG_READ_PM = 0x06,
++ H2D_DEBUG_WRITE_DM = 0x0a,
++ H2D_DEBUG_WRITE_PM = 0x0e,
++
++ D2H_DEBUG_READ_DM_REPLY = 0x03,
++ D2H_DEBUG_READ_FM_REPLY = 0x07,
++ D2H_DEBUG_WRITE_DM_REPLY = 0x0b,
++ D2H_DEBUG_WRITE_FM_REPLY = 0x0f,
++ D2H_ERROR_ADDR_UNKNOWN = 0x33,
++
++ D2H_AUTONOMOUS_MODEM_READY_MSG = 0xf1
++} DSL_CmvOpcode_t;
++
++/* mutex macros */
++#define MEI_MUTEX_INIT(id,flag) \
++ sema_init(&id,flag)
++#define MEI_MUTEX_LOCK(id) \
++ down_interruptible(&id)
++#define MEI_MUTEX_UNLOCK(id) \
++ up(&id)
++#define MEI_WAIT(ms) \
++ {\
++ set_current_state(TASK_INTERRUPTIBLE);\
++ schedule_timeout(ms);\
++ }
++#define MEI_INIT_WAKELIST(name,queue) \
++ init_waitqueue_head(&queue)
++
++/* wait for an event, timeout is measured in ms */
++#define MEI_WAIT_EVENT_TIMEOUT(ev,timeout)\
++ interruptible_sleep_on_timeout(&ev,timeout * HZ / 1000)
++#define MEI_WAKEUP_EVENT(ev)\
++ wake_up_interruptible(&ev)
++#endif /* IFX_MEI_BSP */
++
++/*** Register address offsets, relative to MEI_SPACE_ADDRESS ***/
++#define ME_DX_DATA (0x0000)
++#define ME_VERSION (0x0004)
++#define ME_ARC_GP_STAT (0x0008)
++#define ME_DX_STAT (0x000C)
++#define ME_DX_AD (0x0010)
++#define ME_DX_MWS (0x0014)
++#define ME_ME2ARC_INT (0x0018)
++#define ME_ARC2ME_STAT (0x001C)
++#define ME_ARC2ME_MASK (0x0020)
++#define ME_DBG_WR_AD (0x0024)
++#define ME_DBG_RD_AD (0x0028)
++#define ME_DBG_DATA (0x002C)
++#define ME_DBG_DECODE (0x0030)
++#define ME_CONFIG (0x0034)
++#define ME_RST_CTRL (0x0038)
++#define ME_DBG_MASTER (0x003C)
++#define ME_CLK_CTRL (0x0040)
++#define ME_BIST_CTRL (0x0044)
++#define ME_BIST_STAT (0x0048)
++#define ME_XDATA_BASE_SH (0x004c)
++#define ME_XDATA_BASE (0x0050)
++#define ME_XMEM_BAR_BASE (0x0054)
++#define ME_XMEM_BAR0 (0x0054)
++#define ME_XMEM_BAR1 (0x0058)
++#define ME_XMEM_BAR2 (0x005C)
++#define ME_XMEM_BAR3 (0x0060)
++#define ME_XMEM_BAR4 (0x0064)
++#define ME_XMEM_BAR5 (0x0068)
++#define ME_XMEM_BAR6 (0x006C)
++#define ME_XMEM_BAR7 (0x0070)
++#define ME_XMEM_BAR8 (0x0074)
++#define ME_XMEM_BAR9 (0x0078)
++#define ME_XMEM_BAR10 (0x007C)
++#define ME_XMEM_BAR11 (0x0080)
++#define ME_XMEM_BAR12 (0x0084)
++#define ME_XMEM_BAR13 (0x0088)
++#define ME_XMEM_BAR14 (0x008C)
++#define ME_XMEM_BAR15 (0x0090)
++#define ME_XMEM_BAR16 (0x0094)
++
++#define WHILE_DELAY 20000
++/*
++** Define where in ME Processor's memory map the Stratify chip lives
++*/
++
++#define MAXSWAPSIZE (8 * 1024) //8k *(32bits)
++
++// Mailboxes
++#define MSG_LENGTH 16 // x16 bits
++#define YES_REPLY 1
++#define NO_REPLY 0
++
++#define CMV_TIMEOUT 1000 //jiffies
++
++// Block size per BAR
++#define SDRAM_SEGMENT_SIZE (64*1024)
++// Number of Bar registers
++#define MAX_BAR_REGISTERS (17)
++
++#define XDATA_REGISTER (15)
++
++// ARC register addresss
++#define ARC_STATUS 0x0
++#define ARC_LP_START 0x2
++#define ARC_LP_END 0x3
++#define ARC_DEBUG 0x5
++#define ARC_INT_MASK 0x10A
++
++#define IRAM0_BASE (0x00000)
++#define IRAM1_BASE (0x04000)
++#if defined(CONFIG_DANUBE)
++#define BRAM_BASE (0x0A000)
++#elif defined(CONFIG_AMAZON_SE) || defined(CONFIG_AR9) || defined(CONFIG_VR9)
++#define BRAM_BASE (0x08000)
++#endif
++#define XRAM_BASE (0x18000)
++#define YRAM_BASE (0x1A000)
++#define EXT_MEM_BASE (0x80000)
++#define ARC_GPIO_CTRL (0xC030)
++#define ARC_GPIO_DATA (0xC034)
++
++#define IRAM0_SIZE (16*1024)
++#define IRAM1_SIZE (16*1024)
++#define BRAM_SIZE (12*1024)
++#define XRAM_SIZE (8*1024)
++#define YRAM_SIZE (8*1024)
++#define EXT_MEM_SIZE (1536*1024)
++
++#define ADSL_BASE (0x20000)
++#define CRI_BASE (ADSL_BASE + 0x11F00)
++#define CRI_CCR0 (CRI_BASE + 0x00)
++#define CRI_RST (CRI_BASE + 0x04*4)
++#define ADSL_DILV_BASE (ADSL_BASE+0x20000)
++
++//
++#define IRAM0_ADDR_BIT_MASK 0xFFF
++#define IRAM1_ADDR_BIT_MASK 0xFFF
++#define BRAM_ADDR_BIT_MASK 0xFFF
++#define RX_DILV_ADDR_BIT_MASK 0x1FFF
++
++/*** Bit definitions ***/
++#define ARC_AUX_HALT (1 << 25)
++#define ARC_DEBUG_HALT (1 << 1)
++#define FALSE 0
++#define TRUE 1
++#define BIT0 (1<<0)
++#define BIT1 (1<<1)
++#define BIT2 (1<<2)
++#define BIT3 (1<<3)
++#define BIT4 (1<<4)
++#define BIT5 (1<<5)
++#define BIT6 (1<<6)
++#define BIT7 (1<<7)
++#define BIT8 (1<<8)
++#define BIT9 (1<<9)
++#define BIT10 (1<<10)
++#define BIT11 (1<<11)
++#define BIT12 (1<<12)
++#define BIT13 (1<<13)
++#define BIT14 (1<<14)
++#define BIT15 (1<<15)
++#define BIT16 (1<<16)
++#define BIT17 (1<<17)
++#define BIT18 (1<<18)
++#define BIT19 (1<<19)
++#define BIT20 (1<<20)
++#define BIT21 (1<<21)
++#define BIT22 (1<<22)
++#define BIT23 (1<<23)
++#define BIT24 (1<<24)
++#define BIT25 (1<<25)
++#define BIT26 (1<<26)
++#define BIT27 (1<<27)
++#define BIT28 (1<<28)
++#define BIT29 (1<<29)
++#define BIT30 (1<<30)
++#define BIT31 (1<<31)
++
++// CRI_CCR0 Register definitions
++#define CLK_2M_MODE_ENABLE BIT6
++#define ACL_CLK_MODE_ENABLE BIT4
++#define FDF_CLK_MODE_ENABLE BIT2
++#define STM_CLK_MODE_ENABLE BIT0
++
++// CRI_RST Register definitions
++#define FDF_SRST BIT3
++#define MTE_SRST BIT2
++#define FCI_SRST BIT1
++#define AAI_SRST BIT0
++
++// MEI_TO_ARC_INTERRUPT Register definitions
++#define MEI_TO_ARC_INT1 BIT3
++#define MEI_TO_ARC_INT0 BIT2
++#define MEI_TO_ARC_CS_DONE BIT1 //need to check
++#define MEI_TO_ARC_MSGAV BIT0
++
++// ARC_TO_MEI_INTERRUPT Register definitions
++#define ARC_TO_MEI_INT1 BIT8
++#define ARC_TO_MEI_INT0 BIT7
++#define ARC_TO_MEI_CS_REQ BIT6
++#define ARC_TO_MEI_DBG_DONE BIT5
++#define ARC_TO_MEI_MSGACK BIT4
++#define ARC_TO_MEI_NO_ACCESS BIT3
++#define ARC_TO_MEI_CHECK_AAITX BIT2
++#define ARC_TO_MEI_CHECK_AAIRX BIT1
++#define ARC_TO_MEI_MSGAV BIT0
++
++// ARC_TO_MEI_INTERRUPT_MASK Register definitions
++#define GP_INT1_EN BIT8
++#define GP_INT0_EN BIT7
++#define CS_REQ_EN BIT6
++#define DBG_DONE_EN BIT5
++#define MSGACK_EN BIT4
++#define NO_ACC_EN BIT3
++#define AAITX_EN BIT2
++#define AAIRX_EN BIT1
++#define MSGAV_EN BIT0
++
++#define MEI_SOFT_RESET BIT0
++
++#define HOST_MSTR BIT0
++
++#define JTAG_MASTER_MODE 0x0
++#define MEI_MASTER_MODE HOST_MSTR
++
++// MEI_DEBUG_DECODE Register definitions
++#define MEI_DEBUG_DEC_MASK (0x3)
++#define MEI_DEBUG_DEC_AUX_MASK (0x0)
++#define ME_DBG_DECODE_DMP1_MASK (0x1)
++#define MEI_DEBUG_DEC_DMP2_MASK (0x2)
++#define MEI_DEBUG_DEC_CORE_MASK (0x3)
++
++#define AUX_STATUS (0x0)
++#define AUX_ARC_GPIO_CTRL (0x10C)
++#define AUX_ARC_GPIO_DATA (0x10D)
++// ARC_TO_MEI_MAILBOX[11] is a special location used to indicate
++// page swap requests.
++#if defined(CONFIG_DANUBE)
++#define OMBOX_BASE 0xDF80
++#define ARC_TO_MEI_MAILBOX 0xDFA0
++#define IMBOX_BASE 0xDFC0
++#define MEI_TO_ARC_MAILBOX 0xDFD0
++#elif defined(CONFIG_AMAZON_SE) || defined(CONFIG_AR9) || defined(CONFIG_VR9)
++#define OMBOX_BASE 0xAF80
++#define ARC_TO_MEI_MAILBOX 0xAFA0
++#define IMBOX_BASE 0xAFC0
++#define MEI_TO_ARC_MAILBOX 0xAFD0
++#endif
++
++#define MEI_TO_ARC_MAILBOXR (MEI_TO_ARC_MAILBOX + 0x2C)
++#define ARC_MEI_MAILBOXR (ARC_TO_MEI_MAILBOX + 0x2C)
++#define OMBOX1 (OMBOX_BASE+0x4)
++
++// Codeswap request messages are indicated by setting BIT31
++#define OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK (0x80000000)
++
++// Clear Eoc messages received are indicated by setting BIT17
++#define OMB_CLEAREOC_INTERRUPT_CODE (0x00020000)
++#define OMB_REBOOT_INTERRUPT_CODE (1 << 18)
++
++/*
++** Swap page header
++*/
++// Page must be loaded at boot time if size field has BIT31 set
++#define BOOT_FLAG (BIT31)
++#define BOOT_FLAG_MASK ~BOOT_FLAG
++
++#define FREE_RELOAD 1
++#define FREE_SHOWTIME 2
++#define FREE_ALL 3
++
++// marcos
++#define IFX_MEI_WRITE_REGISTER_L(data,addr) *((volatile u32*)(addr)) = (u32)(data)
++#define IFX_MEI_READ_REGISTER_L(addr) (*((volatile u32*)(addr)))
++#define SET_BIT(reg, mask) reg |= (mask)
++#define CLEAR_BIT(reg, mask) reg &= (~mask)
++#define CLEAR_BITS(reg, mask) CLEAR_BIT(reg, mask)
++//#define SET_BITS(reg, mask) SET_BIT(reg, mask)
++#define SET_BITFIELD(reg, mask, off, val) {reg &= (~mask); reg |= (val << off);}
++
++#define ALIGN_SIZE ( 1L<<10 ) //1K size align
++#define MEM_ALIGN(addr) (((addr) + ALIGN_SIZE - 1) & ~ (ALIGN_SIZE -1) )
++
++// swap marco
++#define MEI_HALF_WORD_SWAP(data) {data = ((data & 0xffff)<<16) + ((data & 0xffff0000)>>16);}
++#define MEI_BYTE_SWAP(data) {data = ((data & 0xff)<<24) + ((data & 0xff00)<<8)+ ((data & 0xff0000)>>8)+ ((data & 0xff000000)>>24);}
++
++
++#ifdef CONFIG_PROC_FS
++typedef struct reg_entry
++{
++ int *flag;
++ char name[30]; /* big enough to hold names */
++ char description[100]; /* big enough to hold description */
++ unsigned short low_ino;
++} reg_entry_t;
++#endif
++// Swap page header describes size in 32-bit words, load location, and image offset
++// for program and/or data segments
++typedef struct _arc_swp_page_hdr {
++ u32 p_offset; //Offset bytes of progseg from beginning of image
++ u32 p_dest; //Destination addr of progseg on processor
++ u32 p_size; //Size in 32-bitwords of program segment
++ u32 d_offset; //Offset bytes of dataseg from beginning of image
++ u32 d_dest; //Destination addr of dataseg on processor
++ u32 d_size; //Size in 32-bitwords of data segment
++} ARC_SWP_PAGE_HDR;
++
++/*
++** Swap image header
++*/
++#define GET_PROG 0 // Flag used for program mem segment
++#define GET_DATA 1 // Flag used for data mem segment
++
++// Image header contains size of image, checksum for image, and count of
++// page headers. Following that are 'count' page headers followed by
++// the code and/or data segments to be loaded
++typedef struct _arc_img_hdr {
++ u32 size; // Size of binary image in bytes
++ u32 checksum; // Checksum for image
++ u32 count; // Count of swp pages in image
++ ARC_SWP_PAGE_HDR page[1]; // Should be "count" pages - '1' to make compiler happy
++} ARC_IMG_HDR;
++
++typedef struct smmu_mem_info {
++ int type;
++ int boot;
++ unsigned long nCopy;
++ unsigned long size;
++ unsigned char *address;
++ unsigned char *org_address;
++} smmu_mem_info_t;
++
++#ifdef __KERNEL__
++typedef struct ifx_mei_device_private {
++ int modem_ready;
++ int arcmsgav;
++ int cmv_reply;
++ int cmv_waiting;
++ // Mei to ARC CMV count, reply count, ARC Indicator count
++ int modem_ready_cnt;
++ int cmv_count;
++ int reply_count;
++ unsigned long image_size;
++ int nBar;
++ u16 Recent_indicator[MSG_LENGTH];
++
++ u16 CMV_RxMsg[MSG_LENGTH] __attribute__ ((aligned (4)));
++
++ smmu_mem_info_t adsl_mem_info[MAX_BAR_REGISTERS];
++ ARC_IMG_HDR *img_hdr;
++ // to wait for arc cmv reply, sleep on wait_queue_arcmsgav;
++ wait_queue_head_t wait_queue_arcmsgav;
++ wait_queue_head_t wait_queue_modemready;
++ struct semaphore mei_cmv_sema;
++} ifx_mei_device_private_t;
++#endif
++typedef struct winhost_message {
++ union {
++ u16 RxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
++ u16 TxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
++ } msg;
++} DSL_DEV_WinHost_Message_t;
++/********************************************************************************************************
++ * DSL CPE API Driver Stack Interface Definitions
++ * *****************************************************************************************************/
++/** IOCTL codes for bsp driver */
++#define DSL_IOC_MEI_BSP_MAGIC 's'
++
++#define DSL_FIO_BSP_DSL_START _IO (DSL_IOC_MEI_BSP_MAGIC, 0)
++#define DSL_FIO_BSP_RUN _IO (DSL_IOC_MEI_BSP_MAGIC, 1)
++#define DSL_FIO_BSP_FREE_RESOURCE _IO (DSL_IOC_MEI_BSP_MAGIC, 2)
++#define DSL_FIO_BSP_RESET _IO (DSL_IOC_MEI_BSP_MAGIC, 3)
++#define DSL_FIO_BSP_REBOOT _IO (DSL_IOC_MEI_BSP_MAGIC, 4)
++#define DSL_FIO_BSP_HALT _IO (DSL_IOC_MEI_BSP_MAGIC, 5)
++#define DSL_FIO_BSP_BOOTDOWNLOAD _IO (DSL_IOC_MEI_BSP_MAGIC, 6)
++#define DSL_FIO_BSP_JTAG_ENABLE _IO (DSL_IOC_MEI_BSP_MAGIC, 7)
++#define DSL_FIO_FREE_RESOURCE _IO (DSL_IOC_MEI_BSP_MAGIC, 8)
++#define DSL_FIO_ARC_MUX_TEST _IO (DSL_IOC_MEI_BSP_MAGIC, 9)
++#define DSL_FIO_BSP_REMOTE _IOW (DSL_IOC_MEI_BSP_MAGIC, 10, u32)
++#define DSL_FIO_BSP_GET_BASE_ADDRESS _IOR (DSL_IOC_MEI_BSP_MAGIC, 11, u32)
++#define DSL_FIO_BSP_IS_MODEM_READY _IOR (DSL_IOC_MEI_BSP_MAGIC, 12, u32)
++#define DSL_FIO_BSP_GET_VERSION _IOR (DSL_IOC_MEI_BSP_MAGIC, 13, DSL_DEV_Version_t)
++#define DSL_FIO_BSP_CMV_WINHOST _IOWR(DSL_IOC_MEI_BSP_MAGIC, 14, DSL_DEV_WinHost_Message_t)
++#define DSL_FIO_BSP_CMV_READ _IOWR(DSL_IOC_MEI_BSP_MAGIC, 15, DSL_DEV_MeiReg_t)
++#define DSL_FIO_BSP_CMV_WRITE _IOW (DSL_IOC_MEI_BSP_MAGIC, 16, DSL_DEV_MeiReg_t)
++#define DSL_FIO_BSP_DEBUG_READ _IOWR(DSL_IOC_MEI_BSP_MAGIC, 17, DSL_DEV_MeiDebug_t)
++#define DSL_FIO_BSP_DEBUG_WRITE _IOWR(DSL_IOC_MEI_BSP_MAGIC, 18, DSL_DEV_MeiDebug_t)
++#define DSL_FIO_BSP_GET_CHIP_INFO _IOR (DSL_IOC_MEI_BSP_MAGIC, 19, DSL_DEV_HwVersion_t)
++
++#define DSL_DEV_MEIDEBUG_BUFFER_SIZES 512
++
++typedef struct DSL_DEV_MeiDebug
++{
++ DSL_uint32_t iAddress;
++ DSL_uint32_t iCount;
++ DSL_uint32_t buffer[DSL_DEV_MEIDEBUG_BUFFER_SIZES];
++} DSL_DEV_MeiDebug_t; /* meidebug */
++
++/**
++ * Structure is used for debug access only.
++ * Refer to configure option INCLUDE_ADSL_WINHOST_DEBUG */
++typedef struct struct_meireg
++{
++ /*
++ * Specifies that address for debug access */
++ unsigned long iAddress;
++ /*
++ * Specifies the pointer to the data that has to be written or returns a
++ * pointer to the data that has been read out*/
++ unsigned long iData;
++} DSL_DEV_MeiReg_t; /* meireg */
++
++typedef struct DSL_DEV_Device
++{
++ DSL_int_t nInUse; /* modem state, update by bsp driver, */
++ DSL_void_t *pPriv;
++ DSL_uint32_t base_address; /* mei base address */
++ DSL_int_t nIrq[2]; /* irq number */
++#define IFX_DFEIR 0
++#define IFX_DYING_GASP 1
++ DSL_DEV_MeiDebug_t lop_debugwr; /* dying gasp */
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
++ struct module *owner;
++#endif
++} DSL_DEV_Device_t; /* ifx_adsl_device_t */
++
++#define DSL_DEV_PRIVATE(dev) ((ifx_mei_device_private_t*)(dev->pPriv))
++
++typedef struct DSL_DEV_Version /* ifx_adsl_bsp_version */
++{
++ unsigned long major;
++ unsigned long minor;
++ unsigned long revision;
++} DSL_DEV_Version_t; /* ifx_adsl_bsp_version_t */
++
++typedef struct DSL_DEV_ChipInfo
++{
++ unsigned long major;
++ unsigned long minor;
++} DSL_DEV_HwVersion_t;
++
++typedef struct
++{
++ DSL_uint8_t dummy;
++} DSL_DEV_DeviceConfig_t;
++
++/** error code definitions */
++typedef enum DSL_DEV_MeiError
++{
++ DSL_DEV_MEI_ERR_SUCCESS = 0,
++ DSL_DEV_MEI_ERR_FAILURE = -1,
++ DSL_DEV_MEI_ERR_MAILBOX_FULL = -2,
++ DSL_DEV_MEI_ERR_MAILBOX_EMPTY = -3,
++ DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT = -4
++} DSL_DEV_MeiError_t; /* MEI_ERROR */
++
++typedef enum {
++ DSL_BSP_MEMORY_READ=0,
++ DSL_BSP_MEMORY_WRITE,
++} DSL_BSP_MemoryAccessType_t; /* ifx_adsl_memory_access_type_t */
++
++typedef enum
++{
++ DSL_LED_LINK_ID=0,
++ DSL_LED_DATA_ID
++} DSL_DEV_LedId_t; /* ifx_adsl_led_id_t */
++
++typedef enum
++{
++ DSL_LED_LINK_TYPE=0,
++ DSL_LED_DATA_TYPE
++} DSL_DEV_LedType_t; /* ifx_adsl_led_type_t */
++
++typedef enum
++{
++ DSL_LED_HD_CPU=0,
++ DSL_LED_HD_FW
++} DSL_DEV_LedHandler_t; /* ifx_adsl_led_handler_t */
++
++typedef enum {
++ DSL_LED_ON=0,
++ DSL_LED_OFF,
++ DSL_LED_FLASH,
++} DSL_DEV_LedMode_t; /* ifx_adsl_led_mode_t */
++
++typedef enum {
++ DSL_CPU_HALT=0,
++ DSL_CPU_RUN,
++ DSL_CPU_RESET,
++} DSL_DEV_CpuMode_t; /* ifx_adsl_cpu_mode_t */
++
++#if 0
++typedef enum {
++ DSL_BSP_EVENT_DYING_GASP = 0,
++ DSL_BSP_EVENT_CEOC_IRQ,
++} DSL_BSP_Event_id_t; /* ifx_adsl_event_id_t */
++
++typedef union DSL_BSP_CB_Param
++{
++ DSL_uint32_t nIrqMessage;
++} DSL_BSP_CB_Param_t; /* ifx_adsl_cbparam_t */
++
++typedef struct DSL_BSP_CB_Event
++{
++ DSL_BSP_Event_id_t nID;
++ DSL_DEV_Device_t *pDev;
++ DSL_BSP_CB_Param_t *pParam;
++} DSL_BSP_CB_Event_t; /* ifx_adsl_cb_event_t */
++#endif
++
++/* external functions (from the BSP Driver) */
++extern DSL_DEV_Device_t* DSL_BSP_DriverHandleGet(int, int);
++extern DSL_int_t DSL_BSP_DriverHandleDelete(DSL_DEV_Device_t *);
++extern DSL_DEV_MeiError_t DSL_BSP_FWDownload(DSL_DEV_Device_t *, const DSL_char_t *, DSL_uint32_t, DSL_int32_t *, DSL_int32_t *);
++extern int DSL_BSP_KernelIoctls(DSL_DEV_Device_t *, unsigned int, unsigned long);
++extern DSL_DEV_MeiError_t DSL_BSP_SendCMV(DSL_DEV_Device_t *, DSL_uint16_t *, DSL_int_t, DSL_uint16_t *);
++extern DSL_DEV_MeiError_t DSL_BSP_AdslLedInit(DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedType_t, DSL_DEV_LedHandler_t);
++extern DSL_DEV_MeiError_t DSL_BSP_Showtime(DSL_DEV_Device_t *, DSL_uint32_t, DSL_uint32_t);
++extern int DSL_BSP_ATMLedCBRegister( int (*ifx_adsl_ledcallback)(void));
++extern DSL_DEV_MeiError_t DSL_BSP_MemoryDebugAccess(DSL_DEV_Device_t *, DSL_BSP_MemoryAccessType_t, DSL_uint32_t, DSL_uint32_t *, DSL_uint32_t);
++extern volatile DSL_DEV_Device_t *adsl_dev;
++
++/**
++ * Dummy structure by now to show mechanism of extended data that will be
++ * provided within event callback itself.
++ * */
++typedef struct
++{
++ /**
++ * Dummy value */
++ DSL_uint32_t nDummy1;
++} DSL_BSP_CB_Event1DataDummy_t;
++
++/**
++ * Dummy structure by now to show mechanism of extended data that will be
++ * provided within event callback itself.
++ * */
++typedef struct
++{
++ /**
++ * Dummy value */
++ DSL_uint32_t nDummy2;
++} DSL_BSP_CB_Event2DataDummy_t;
++
++/**
++ * encapsulate all data structures that are necessary for status event
++ * callbacks.
++ * */
++typedef union
++{
++ DSL_BSP_CB_Event1DataDummy_t dataEvent1;
++ DSL_BSP_CB_Event2DataDummy_t dataEvent2;
++} DSL_BSP_CB_DATA_Union_t;
++
++
++typedef enum
++{
++ /**
++ * Informs the upper layer driver (DSL CPE API) about a reboot request from the
++ * firmware.
++ * \note This event does NOT include any additional data.
++ * More detailed information upon reboot reason has to be requested from
++ * upper layer software via CMV (INFO 109) if necessary. */
++ DSL_BSP_CB_FIRST = 0,
++ DSL_BSP_CB_DYING_GASP,
++ DSL_BSP_CB_CEOC_IRQ,
++ DSL_BSP_CB_FIRMWARE_REBOOT,
++ /**
++ * Delimiter only */
++ DSL_BSP_CB_LAST
++} DSL_BSP_CB_Type_t;
++
++/**
++ * Specifies the common event type that has to be used for registering and
++ * signalling of interrupts/autonomous status events from MEI BSP Driver.
++ *
++ * \param pDev
++ * Context pointer from MEI BSP Driver.
++ *
++ * \param IFX_ADSL_BSP_CallbackType_t
++ * Specifies the event callback type (reason of callback). Regrading to the
++ * setting of this value the data which is included in the following union
++ * might have different meanings.
++ * Please refer to the description of the union to get information about the
++ * meaning of the included data.
++ *
++ * \param pData
++ * Data according to \ref DSL_BSP_CB_DATA_Union_t.
++ * If this pointer is NULL there is no additional data available.
++ *
++ * \return depending on event
++ */
++typedef int (*DSL_BSP_EventCallback_t)
++(
++ DSL_DEV_Device_t *pDev,
++ DSL_BSP_CB_Type_t nCallbackType,
++ DSL_BSP_CB_DATA_Union_t *pData
++);
++
++typedef struct {
++ DSL_BSP_EventCallback_t function;
++ DSL_BSP_CB_Type_t event;
++ DSL_BSP_CB_DATA_Union_t *pData;
++} DSL_BSP_EventCallBack_t;
++
++extern int DSL_BSP_EventCBRegister(DSL_BSP_EventCallBack_t *);
++extern int DSL_BSP_EventCBUnregister(DSL_BSP_EventCallBack_t *);
++
++/** Modem states */
++#define DSL_DEV_STAT_InitState 0x0000
++#define DSL_DEV_STAT_ReadyState 0x0001
++#define DSL_DEV_STAT_FailState 0x0002
++#define DSL_DEV_STAT_IdleState 0x0003
++#define DSL_DEV_STAT_QuietState 0x0004
++#define DSL_DEV_STAT_GhsState 0x0005
++#define DSL_DEV_STAT_FullInitState 0x0006
++#define DSL_DEV_STAT_ShowTimeState 0x0007
++#define DSL_DEV_STAT_FastRetrainState 0x0008
++#define DSL_DEV_STAT_LoopDiagMode 0x0009
++#define DSL_DEV_STAT_ShortInit 0x000A /* Bis short initialization */
++
++#define DSL_DEV_STAT_CODESWAP_COMPLETE 0x0002
++
++#endif //IFXMIPS_MEI_H
+--- a/configure.in
++++ b/configure.in
+@@ -310,7 +310,7 @@
+ AC_ARG_ENABLE(kernelbuild,
+ AC_HELP_STRING(--enable-kernel-build=x,Set the target kernel build path),
+ [
+- if test -e $enableval/include/linux/autoconf.h; then
++ if test -e $enableval/include/linux/autoconf.h -o -e $enableval/include/generated/autoconf.h; then
+ AC_SUBST([KERNEL_BUILD_PATH],[$enableval])
+ else
+ AC_MSG_ERROR([The kernel build directory is not valid or not configured!])
+@@ -333,12 +333,12 @@
+ echo Set the lib_ifxos include path $enableval
+ AC_SUBST([IFXOS_INCLUDE_PATH],[$enableval])
+ else
+- echo -e Set the default lib_ifxos include path $DEFAULT_IFXOS_INCLUDE_PATH
++ echo Set the default lib_ifxos include path $DEFAULT_IFXOS_INCLUDE_PATH
+ AC_SUBST([IFXOS_INCLUDE_PATH],[$DEFAULT_IFXOS_INCLUDE_PATH])
+ fi
+ ],
+ [
+- echo -e Set the default lib_ifxos include path $DEFAULT_IFXOS_INCLUDE_PATH
++ echo Set the default lib_ifxos include path $DEFAULT_IFXOS_INCLUDE_PATH
+ AC_SUBST([IFXOS_INCLUDE_PATH],[$DEFAULT_IFXOS_INCLUDE_PATH])
+ ]
+ )
+@@ -1702,73 +1702,73 @@
+ AC_SUBST([DISTCHECK_CONFIGURE_PARAMS],[$CONFIGURE_OPTIONS])
+
+ AC_CONFIG_COMMANDS_PRE([
+-echo -e "------------------------------------------------------------------------"
+-echo -e " Configuration for drv_dsl_cpe_api:"
+-echo -e " Configure model type: $DSL_CONFIG_MODEL_TYPE"
+-echo -e " Source code location: $srcdir"
+-echo -e " Compiler: $CC"
+-echo -e " Compiler c-flags: $CFLAGS"
+-echo -e " Extra compiler c-flags: $EXTRA_DRV_CFLAGS"
+-echo -e " Host System Type: $host"
+-echo -e " Install path: $prefix"
+-echo -e " Linux kernel include path: $KERNEL_INCL_PATH"
+-echo -e " Linux kernel build path: $KERNEL_BUILD_PATH"
+-echo -e " Linux kernel architecture: $KERNEL_ARCH"
+-echo -e " Include IFXOS: $INCLUDE_DSL_CPE_API_IFXOS_SUPPORT"
+-echo -e " IFXOS include path: $IFXOS_INCLUDE_PATH"
+-echo -e " Driver Include Path $DSL_DRIVER_INCL_PATH"
+-echo -e " DSL device: $DSL_DEVICE_NAME"
+-echo -e " Max device number: $DSL_DRV_MAX_DEVICE_NUMBER"
+-echo -e " Channels per line: $DSL_CHANNELS_PER_LINE"
+-echo -e " Build lib (only for kernel 2.6) $DSL_CPE_API_LIBRARY_BUILD_2_6"
+-echo -e " DSL data led flash frequency: $DSL_DATA_LED_FLASH_FREQUENCY Hz"
+-echo -e " Disable debug prints: $DSL_DEBUG_DISABLE"
+-echo -e " Preselection of max. debug level: $DSL_DBG_MAX_LEVEL_SET"
+-echo -e " Preselected max. debug level: $DSL_DBG_MAX_LEVEL_PRE"
+-echo -e " Include deprecated functions: $INCLUDE_DEPRECATED"
+-echo -e " Include Device Exception Codes: $INCLUDE_DEVICE_EXCEPTION_CODES"
+-echo -e " Include FW request support: $INCLUDE_FW_REQUEST_SUPPORT"
+-echo -e " Include ADSL trace buffer: $INCLUDE_DSL_CPE_TRACE_BUFFER"
+-echo -e " Include ADSL MIB: $INCLUDE_DSL_ADSL_MIB"
+-echo -e " Include ADSL LED: $INCLUDE_ADSL_LED"
+-echo -e " Include CEOC: $INCLUDE_DSL_CEOC"
+-echo -e " Include config get support: $INCLUDE_DSL_CONFIG_GET"
+-echo -e " Include System i/f configuration: $INCLUDE_DSL_SYSTEM_INTERFACE"
+-echo -e " Include Resource Statistics: $INCLUDE_DSL_RESOURCE_STATISTICS"
+-echo -e " Include Framing Parameters: $INCLUDE_DSL_FRAMING_PARAMETERS"
+-echo -e " Include G997 Line Inventory: $INCLUDE_DSL_G997_LINE_INVENTORY"
+-echo -e " Include G997 Framing Parameters: $INCLUDE_DSL_G997_FRAMING_PARAMETERS"
+-echo -e " Include G997 per tone data: $INCLUDE_DSL_G997_PER_TONE"
+-echo -e " Include G997 status: $INCLUDE_DSL_G997_STATUS"
+-echo -e " Include G997 alarm: $INCLUDE_DSL_G997_ALARM"
+-echo -e " Include DSL Bonding: $INCLUDE_DSL_BONDING"
+-echo -e " Include Misc Line Status $INCLUDE_DSL_CPE_MISC_LINE_STATUS"
+-echo -e " Include DELT: $INCLUDE_DSL_DELT"
+-echo -e " Include DELT data static storage: $DSL_CPE_STATIC_DELT_DATA"
+-echo -e " Include PM: $INCLUDE_DSL_PM"
+-echo -e " Include PM config: $INCLUDE_DSL_CPE_PM_CONFIG"
+-echo -e " Include PM total: $INCLUDE_DSL_CPE_PM_TOTAL_COUNTERS"
+-echo -e " Include PM history: $INCLUDE_DSL_CPE_PM_HISTORY"
+-echo -e " Include PM showtime: $INCLUDE_DSL_CPE_PM_SHOWTIME_COUNTERS"
+-echo -e " Include PM optional: $INCLUDE_DSL_CPE_PM_OPTIONAL_PARAMETERS"
+-echo -e " Include PM line: $INCLUDE_DSL_CPE_PM_LINE_COUNTERS"
+-echo -e " Include PM line event showtime: $INCLUDE_DSL_CPE_PM_LINE_EVENT_SHOWTIME_COUNTERS"
+-echo -e " Include PM channel: $INCLUDE_DSL_CPE_PM_CHANNEL_COUNTERS"
+-echo -e " Include PM channel extended: $INCLUDE_DSL_CPE_PM_CHANNEL_EXT_COUNTERS"
+-echo -e " Include PM data path: $INCLUDE_DSL_CPE_PM_DATA_PATH_COUNTERS"
+-echo -e " Include PM data path failure: $INCLUDE_DSL_CPE_PM_DATA_PATH_FAILURE_COUNTERS"
+-echo -e " Include PM ReTx: $INCLUDE_DSL_CPE_PM_RETX_COUNTERS"
+-echo -e " Include PM line threshold: $INCLUDE_DSL_CPE_PM_LINE_THRESHOLDS"
+-echo -e " Include PM channel threshold: $INCLUDE_DSL_CPE_PM_CHANNEL_THRESHOLDS"
+-echo -e " Include PM data path threshold: $INCLUDE_DSL_CPE_PM_DATA_PATH_THRESHOLDS"
+-echo -e " Include PM ReTx threshold: $INCLUDE_DSL_CPE_PM_RETX_THRESHOLDS"
+-echo -e " Include FW memory free support: $INCLUDE_DSL_FIRMWARE_MEMORY_FREE"
+-echo -e "----------------------- deprectated ! ----------------------------------"
+-echo -e " Include PM line failure: $INCLUDE_DSL_CPE_PM_LINE_FAILURE_COUNTERS"
+-echo -e ""
+-echo -e " Settings:"
+-echo -e " Configure options: $CONFIGURE_OPTIONS"
+-echo -e "------------------------------------------------------------------------"
++echo "------------------------------------------------------------------------"
++echo " Configuration for drv_dsl_cpe_api:"
++echo " Configure model type: $DSL_CONFIG_MODEL_TYPE"
++echo " Source code location: $srcdir"
++echo " Compiler: $CC"
++echo " Compiler c-flags: $CFLAGS"
++echo " Extra compiler c-flags: $EXTRA_DRV_CFLAGS"
++echo " Host System Type: $host"
++echo " Install path: $prefix"
++echo " Linux kernel include path: $KERNEL_INCL_PATH"
++echo " Linux kernel build path: $KERNEL_BUILD_PATH"
++echo " Linux kernel architecture: $KERNEL_ARCH"
++echo " Include IFXOS: $INCLUDE_DSL_CPE_API_IFXOS_SUPPORT"
++echo " IFXOS include path: $IFXOS_INCLUDE_PATH"
++echo " Driver Include Path $DSL_DRIVER_INCL_PATH"
++echo " DSL device: $DSL_DEVICE_NAME"
++echo " Max device number: $DSL_DRV_MAX_DEVICE_NUMBER"
++echo " Channels per line: $DSL_CHANNELS_PER_LINE"
++echo " Build lib (only for kernel 2.6) $DSL_CPE_API_LIBRARY_BUILD_2_6"
++echo " DSL data led flash frequency: $DSL_DATA_LED_FLASH_FREQUENCY Hz"
++echo " Disable debug prints: $DSL_DEBUG_DISABLE"
++echo " Preselection of max. debug level: $DSL_DBG_MAX_LEVEL_SET"
++echo " Preselected max. debug level: $DSL_DBG_MAX_LEVEL_PRE"
++echo " Include deprecated functions: $INCLUDE_DEPRECATED"
++echo " Include Device Exception Codes: $INCLUDE_DEVICE_EXCEPTION_CODES"
++echo " Include FW request support: $INCLUDE_FW_REQUEST_SUPPORT"
++echo " Include ADSL trace buffer: $INCLUDE_DSL_CPE_TRACE_BUFFER"
++echo " Include ADSL MIB: $INCLUDE_DSL_ADSL_MIB"
++echo " Include ADSL LED: $INCLUDE_ADSL_LED"
++echo " Include CEOC: $INCLUDE_DSL_CEOC"
++echo " Include config get support: $INCLUDE_DSL_CONFIG_GET"
++echo " Include System i/f configuration: $INCLUDE_DSL_SYSTEM_INTERFACE"
++echo " Include Resource Statistics: $INCLUDE_DSL_RESOURCE_STATISTICS"
++echo " Include Framing Parameters: $INCLUDE_DSL_FRAMING_PARAMETERS"
++echo " Include G997 Line Inventory: $INCLUDE_DSL_G997_LINE_INVENTORY"
++echo " Include G997 Framing Parameters: $INCLUDE_DSL_G997_FRAMING_PARAMETERS"
++echo " Include G997 per tone data: $INCLUDE_DSL_G997_PER_TONE"
++echo " Include G997 status: $INCLUDE_DSL_G997_STATUS"
++echo " Include G997 alarm: $INCLUDE_DSL_G997_ALARM"
++echo " Include DSL Bonding: $INCLUDE_DSL_BONDING"
++echo " Include Misc Line Status $INCLUDE_DSL_CPE_MISC_LINE_STATUS"
++echo " Include DELT: $INCLUDE_DSL_DELT"
++echo " Include DELT data static storage: $DSL_CPE_STATIC_DELT_DATA"
++echo " Include PM: $INCLUDE_DSL_PM"
++echo " Include PM config: $INCLUDE_DSL_CPE_PM_CONFIG"
++echo " Include PM total: $INCLUDE_DSL_CPE_PM_TOTAL_COUNTERS"
++echo " Include PM history: $INCLUDE_DSL_CPE_PM_HISTORY"
++echo " Include PM showtime: $INCLUDE_DSL_CPE_PM_SHOWTIME_COUNTERS"
++echo " Include PM optional: $INCLUDE_DSL_CPE_PM_OPTIONAL_PARAMETERS"
++echo " Include PM line: $INCLUDE_DSL_CPE_PM_LINE_COUNTERS"
++echo " Include PM line event showtime: $INCLUDE_DSL_CPE_PM_LINE_EVENT_SHOWTIME_COUNTERS"
++echo " Include PM channel: $INCLUDE_DSL_CPE_PM_CHANNEL_COUNTERS"
++echo " Include PM channel extended: $INCLUDE_DSL_CPE_PM_CHANNEL_EXT_COUNTERS"
++echo " Include PM data path: $INCLUDE_DSL_CPE_PM_DATA_PATH_COUNTERS"
++echo " Include PM data path failure: $INCLUDE_DSL_CPE_PM_DATA_PATH_FAILURE_COUNTERS"
++echo " Include PM ReTx: $INCLUDE_DSL_CPE_PM_RETX_COUNTERS"
++echo " Include PM line threshold: $INCLUDE_DSL_CPE_PM_LINE_THRESHOLDS"
++echo " Include PM channel threshold: $INCLUDE_DSL_CPE_PM_CHANNEL_THRESHOLDS"
++echo " Include PM data path threshold: $INCLUDE_DSL_CPE_PM_DATA_PATH_THRESHOLDS"
++echo " Include PM ReTx threshold: $INCLUDE_DSL_CPE_PM_RETX_THRESHOLDS"
++echo " Include FW memory free support: $INCLUDE_DSL_FIRMWARE_MEMORY_FREE"
++echo "----------------------- deprectated ! ----------------------------------"
++echo " Include PM line failure: $INCLUDE_DSL_CPE_PM_LINE_FAILURE_COUNTERS"
++echo ""
++echo " Settings:"
++echo " Configure options: $CONFIGURE_OPTIONS"
++echo "------------------------------------------------------------------------"
+ ])
+
+ AC_CONFIG_FILES([Makefile src/Makefile])
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -303,7 +303,7 @@
+ drv_dsl_cpe_api_OBJS = "$(subst .c,.o,$(filter %.c,$(drv_dsl_cpe_api_SOURCES)))"
+
+ drv_dsl_cpe_api.ko: $(drv_dsl_cpe_api_SOURCES)
+- @echo -e "drv_dsl_cpe_api: Making Linux 2.6.x kernel object"
++ @echo "drv_dsl_cpe_api: Making Linux 2.6.x kernel object"
+ if test ! -e common/drv_dsl_cpe_api.c ; then \
+ echo "copy source files (as links only!)"; \
+ for f in $(filter %.c,$(drv_dsl_cpe_api_SOURCES)); do \
+@@ -311,10 +311,10 @@
+ cp -s $(addprefix @abs_srcdir@/,$$f) $(PWD)/`dirname $$f`/ ; \
+ done \
+ fi
+- @echo -e "# drv_dsl_cpe_api: Generated to build Linux 2.6.x kernel object" > $(PWD)/Kbuild
+- @echo -e "obj-m := $(subst .ko,.o,$@)" >> $(PWD)/Kbuild
+- @echo -e "$(subst .ko,,$@)-y := $(drv_dsl_cpe_api_OBJS)" >> $(PWD)/Kbuild
+- @echo -e "EXTRA_CFLAGS := $(CFLAGS) -DHAVE_CONFIG_H $(drv_dsl_cpe_api_CFLAGS) $(DSL_DRIVER_INCL_PATH) $(IFXOS_INCLUDE_PATH) -I@abs_srcdir@/include -I$(PWD)/include" >> $(PWD)/Kbuild
++ @echo "# drv_dsl_cpe_api: Generated to build Linux 2.6.x kernel object" > $(PWD)/Kbuild
++ @echo "obj-m := $(subst .ko,.o,$@)" >> $(PWD)/Kbuild
++ @echo "$(subst .ko,,$@)-y := $(drv_dsl_cpe_api_OBJS)" >> $(PWD)/Kbuild
++ @echo "EXTRA_CFLAGS := $(CFLAGS) -DHAVE_CONFIG_H $(drv_dsl_cpe_api_CFLAGS) $(DSL_DRIVER_INCL_PATH) $(IFXOS_INCLUDE_PATH) -I@abs_srcdir@/include -I$(PWD)/include" >> $(PWD)/Kbuild
+ $(MAKE) ARCH=@KERNEL_ARCH@ -C @KERNEL_BUILD_PATH@ O=@KERNEL_BUILD_PATH@ M=$(PWD) modules
+
+ clean-generic:
+--- a/src/include/drv_dsl_cpe_os_linux.h
++++ b/src/include/drv_dsl_cpe_os_linux.h
+@@ -16,8 +16,6 @@
+ extern "C" {
+ #endif
+
+-#include <asm/ioctl.h>
+-#include <generated/autoconf.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+@@ -26,8 +24,10 @@
+ #include <linux/spinlock.h>
+ #include <linux/sched.h>
+
+-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+- #include <generated/utsrelease.h>
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
++#include <linux/utsrelease.h>
++#else
++#include <generated/utsrelease.h>
+ #endif
+
+ #include <linux/types.h>
+@@ -39,7 +39,8 @@
+ #include <linux/delay.h>
+ #include <linux/poll.h>
+ #include <asm/uaccess.h>
+-#include <linux/smp_lock.h>
++//#include <linux/smp_lock.h>
++#include <asm/ioctl.h>
+
+ #ifdef INCLUDE_DSL_CPE_API_IFXOS_SUPPORT
+ /** IFXOS includes*/
diff --git a/package/kernel/lantiq/ltq-adsl/patches/110-fix_status_polling_loop.patch b/package/kernel/lantiq/ltq-adsl/patches/110-fix_status_polling_loop.patch
new file mode 100644
index 0000000000..870943d950
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl/patches/110-fix_status_polling_loop.patch
@@ -0,0 +1,11 @@
+--- a/src/device/drv_dsl_cpe_device_danube.c
++++ b/src/device/drv_dsl_cpe_device_danube.c
+@@ -4069,7 +4069,7 @@ static DSL_Error_t DSL_DRV_DANUBE_XTUSys
+
+ DSL_CTX_WRITE(pContext, nErrCode, xtseCurr, xtseCurr);
+
+- for (nRetry = 0; nRetry < 20; nRetry++)
++ for (nRetry = 0; nRetry < 20 && bStatusUpdated == DSL_FALSE; nRetry++)
+ {
+ /* Get STAT1 info*/
+ nErrCode = DSL_DRV_DANUBE_CmvRead(pContext, DSL_CMV_GROUP_STAT,
diff --git a/package/kernel/lantiq/ltq-adsl/patches/120-platform.patch b/package/kernel/lantiq/ltq-adsl/patches/120-platform.patch
new file mode 100644
index 0000000000..48c7581e4f
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl/patches/120-platform.patch
@@ -0,0 +1,72 @@
+Index: drv_dsl_cpe_api-3.24.4.4/src/common/drv_dsl_cpe_os_linux.c
+===================================================================
+--- drv_dsl_cpe_api-3.24.4.4.orig/src/common/drv_dsl_cpe_os_linux.c 2012-12-07 21:22:58.020256076 +0100
++++ drv_dsl_cpe_api-3.24.4.4/src/common/drv_dsl_cpe_os_linux.c 2012-12-07 21:31:13.156268489 +0100
+@@ -12,6 +12,7 @@
+
+ #define DSL_INTERN
+ #include <linux/device.h>
++#include <linux/platform_device.h>
+
+ #include "drv_dsl_cpe_api.h"
+ #include "drv_dsl_cpe_api_ioctl.h"
+@@ -1063,7 +1064,7 @@
+ #endif
+
+ /* Entry point of driver */
+-int __init DSL_ModuleInit(void)
++static int __devinit ltq_adsl_probe(struct platform_device *pdev)
+ {
+ struct class *dsl_class;
+ DSL_int_t i;
+@@ -1117,7 +1118,7 @@
+ return 0;
+ }
+
+-void __exit DSL_ModuleCleanup(void)
++static int __devexit ltq_adsl_remove(struct platform_device *pdev)
+ {
+ printk("Module will be unloaded"DSL_DRV_CRLF);
+
+@@ -1132,7 +1133,7 @@
+ (DSL_uint8_t**)&g_BndFpgaBase);
+ #endif /* defined(INCLUDE_DSL_CPE_API_VINAX) && defined(INCLUDE_DSL_BONDING)*/
+
+- return;
++ return 0;
+ }
+
+ #ifndef _lint
+@@ -1148,8 +1149,30 @@
+ MODULE_PARM_DESC(debug_level, "set to get more (1) or fewer (4) debug outputs");
+ #endif /* #ifndef DSL_DEBUG_DISABLE*/
+
+-module_init(DSL_ModuleInit);
+-module_exit(DSL_ModuleCleanup);
++static const struct of_device_id ltq_adsl_match[] = {
++#ifdef CONFIG_DANUBE
++ { .compatible = "lantiq,adsl-danube"},
++#elif defined CONFIG_AMAZON_SE
++ { .compatible = "lantiq,adsl-ase"},
++#elif defined CONFIG_AR9
++ { .compatible = "lantiq,adsl-arx100"},
++#endif
++ {},
++};
++MODULE_DEVICE_TABLE(of, ltq_adsl_match);
++
++static struct platform_driver ltq_adsl_driver = {
++ .probe = ltq_adsl_probe,
++ .remove = __devexit_p(ltq_adsl_remove),
++ .driver = {
++ .name = "adsl",
++ .owner = THIS_MODULE,
++ .of_match_table = ltq_adsl_match,
++ },
++};
++
++module_platform_driver(ltq_adsl_driver);
++
+ #endif /* #ifndef _lint*/
+
+ //EXPORT_SYMBOL(DSL_ModuleInit);
diff --git a/package/kernel/lantiq/ltq-adsl/patches/130-linux3.8.patch b/package/kernel/lantiq/ltq-adsl/patches/130-linux3.8.patch
new file mode 100644
index 0000000000..bf758e0a90
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl/patches/130-linux3.8.patch
@@ -0,0 +1,143 @@
+Index: drv_dsl_cpe_api-3.24.4.4/src/common/drv_dsl_cpe_os_linux.c
+===================================================================
+--- drv_dsl_cpe_api-3.24.4.4.orig/src/common/drv_dsl_cpe_os_linux.c 2013-03-14 11:44:50.318326078 +0100
++++ drv_dsl_cpe_api-3.24.4.4/src/common/drv_dsl_cpe_os_linux.c 2013-03-14 11:46:08.562329425 +0100
+@@ -11,6 +11,7 @@
+ #ifdef __LINUX__
+
+ #define DSL_INTERN
++#include <linux/kthread.h>
+ #include <linux/device.h>
+ #include <linux/platform_device.h>
+
+@@ -40,7 +41,7 @@
+ static DSL_int_t DSL_DRV_Ioctls(DSL_DRV_inode_t * pINode, DSL_DRV_file_t * pFile,
+ DSL_uint_t nCommand, unsigned long nArg);
+ #else
+-static DSL_int_t DSL_DRV_Ioctls(DSL_DRV_file_t * pFile,
++static long DSL_DRV_Ioctls(DSL_DRV_file_t * pFile,
+ DSL_uint_t nCommand, unsigned long nArg);
+ #endif
+ static int DSL_DRV_Open(DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil);
+@@ -184,7 +185,7 @@
+ DSL_uint_t nCommand,
+ unsigned long nArg)
+ #else
+-static DSL_int_t DSL_DRV_Ioctls(
++static long DSL_DRV_Ioctls(
+ DSL_DRV_file_t * pFile,
+ DSL_uint_t nCommand,
+ unsigned long nArg)
+@@ -521,9 +522,9 @@
+ - IFX_SUCCESS on success
+ - IFX_ERROR on error
+ */
+-DSL_DRV_STATIC DSL_int32_t DSL_DRV_KernelThreadStartup(
+- DSL_DRV_ThreadCtrl_t *pThrCntrl)
++static int DSL_DRV_KernelThreadStartup(void *data)
+ {
++ DSL_DRV_ThreadCtrl_t *pThrCntrl = (DSL_DRV_ThreadCtrl_t*) data;
+ DSL_int32_t retVal = -1;
+ #ifndef _lint
+
+@@ -546,30 +547,6 @@
+ (DSL_NULL, "ENTER - Kernel Thread Startup <%s>" DSL_DRV_CRLF,
+ pThrCntrl->thrParams.pName));
+
+- /* do LINUX specific setup */
+-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+- daemonize();
+- reparent_to_init();
+-
+- /* lock the kernel. A new kernel thread starts without
+- the big kernel lock, regardless of the lock state
+- of the creator (the lock level is *not* inheritated)
+- */
+- lock_kernel();
+-
+- /* Don't care about any signals. */
+- siginitsetinv(&current->blocked, 0);
+-
+- /* set name of this process */
+- strcpy(kthread->comm, pThrCntrl->thrParams.pName);
+-
+- /* let others run */
+- unlock_kernel();
+-#else
+- daemonize(pThrCntrl->thrParams.pName);
+-
+-#endif
+-
+ /*DSL_DRV_ThreadPriorityModify(pThrCntrl->nPriority);*/
+
+ pThrCntrl->thrParams.bRunning = 1;
+@@ -639,9 +616,7 @@
+ init_completion(&pThrCntrl->thrCompletion);
+
+ /* start kernel thread via the wrapper function */
+- pThrCntrl->pid = kernel_thread( (DSL_DRV_KERNEL_THREAD_StartRoutine)DSL_DRV_KernelThreadStartup,
+- (void *)pThrCntrl,
+- DSL_DRV_DRV_THREAD_OPTIONS);
++ pThrCntrl->pid = kthread_run(DSL_DRV_KernelThreadStartup, (void *)pThrCntrl, pThrCntrl->thrParams.pName);
+
+ pThrCntrl->bValid = DSL_TRUE;
+
+@@ -1064,12 +1039,12 @@
+ #endif
+
+ /* Entry point of driver */
+-static int __devinit ltq_adsl_probe(struct platform_device *pdev)
++static int ltq_adsl_probe(struct platform_device *pdev)
+ {
+ struct class *dsl_class;
+ DSL_int_t i;
+
+- printk(DSL_DRV_CRLF DSL_DRV_CRLF "Infineon CPE API Driver version: %s" DSL_DRV_CRLF,
++ printk("Infineon CPE API Driver version: %s" DSL_DRV_CRLF,
+ &(dsl_cpe_api_version[4]));
+
+ DSL_DRV_MemSet( ifxDevices, 0, sizeof(DSL_devCtx_t) * DSL_DRV_MAX_DEVICE_NUMBER );
+@@ -1118,7 +1093,7 @@
+ return 0;
+ }
+
+-static int __devexit ltq_adsl_remove(struct platform_device *pdev)
++static int ltq_adsl_remove(struct platform_device *pdev)
+ {
+ printk("Module will be unloaded"DSL_DRV_CRLF);
+
+@@ -1163,7 +1138,7 @@
+
+ static struct platform_driver ltq_adsl_driver = {
+ .probe = ltq_adsl_probe,
+- .remove = __devexit_p(ltq_adsl_remove),
++ .remove = ltq_adsl_remove,
+ .driver = {
+ .name = "adsl",
+ .owner = THIS_MODULE,
+Index: drv_dsl_cpe_api-3.24.4.4/src/include/drv_dsl_cpe_os_lint_map.h
+===================================================================
+--- drv_dsl_cpe_api-3.24.4.4.orig/src/include/drv_dsl_cpe_os_lint_map.h 2009-02-24 21:44:54.000000000 +0100
++++ drv_dsl_cpe_api-3.24.4.4/src/include/drv_dsl_cpe_os_lint_map.h 2013-03-14 11:44:50.330326079 +0100
+@@ -247,7 +247,7 @@
+ DSL_DRV_ThreadFunction_t pThrFct;
+
+ /** Kernel thread process ID */
+- DSL_int32_t pid;
++ struct task_struct *pid;
+
+ /** requested kernel thread priority */
+ DSL_int32_t nPriority;
+Index: drv_dsl_cpe_api-3.24.4.4/src/include/drv_dsl_cpe_os_linux.h
+===================================================================
+--- drv_dsl_cpe_api-3.24.4.4.orig/src/include/drv_dsl_cpe_os_linux.h 2013-03-14 11:44:50.298326077 +0100
++++ drv_dsl_cpe_api-3.24.4.4/src/include/drv_dsl_cpe_os_linux.h 2013-03-14 11:44:50.330326079 +0100
+@@ -288,7 +288,7 @@
+ DSL_DRV_ThreadFunction_t pThrFct;
+
+ /** Kernel thread process ID */
+- DSL_int32_t pid;
++ struct task_struct *pid;
+
+ /** requested kernel thread priority */
+ DSL_int32_t nPriority;
diff --git a/package/kernel/lantiq/ltq-atm/Makefile b/package/kernel/lantiq/ltq-atm/Makefile
new file mode 100644
index 0000000000..e6e005933c
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/Makefile
@@ -0,0 +1,51 @@
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ltq-atm
+PKG_RELEASE:=1
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-atm-$(BUILD_VARIANT)
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-atm-template
+ SECTION:=sys
+ CATEGORY:=Kernel modules
+ SUBMENU:=Network Devices
+ TITLE:=atm driver for $(1)
+ URL:=http://www.lantiq.com/
+ VARIANT:=$(1)
+ DEPENDS:=@TARGET_lantiq_$(2) +kmod-atm +br2684ctl
+ FILES:=$(PKG_BUILD_DIR)/ltq_atm_$(1).ko
+ AUTOLOAD:=$(call AutoLoad,52,ltq_atm_$(1))
+endef
+
+KernelPackage/ltq-atm-danube=$(call KernelPackage/ltq-atm-template,danube,xway)
+KernelPackage/ltq-atm-ar9=$(call KernelPackage/ltq-atm-template,ar9,xway)
+KernelPackage/ltq-atm-ase=$(call KernelPackage/ltq-atm-template,ase,ase)
+KernelPackage/ltq-atm-vr9=$(call KernelPackage/ltq-atm-template,vr9,xway)
+
+define Build/Prepare
+ $(INSTALL_DIR) $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ cd $(LINUX_DIR); \
+ ARCH=mips CROSS_COMPILE="$(KERNEL_CROSS)" \
+ $(MAKE) BUILD_VARIANT=$(BUILD_VARIANT) M=$(PKG_BUILD_DIR) V=1 modules
+endef
+
+$(eval $(call KernelPackage,ltq-atm-danube))
+$(eval $(call KernelPackage,ltq-atm-ase))
+$(eval $(call KernelPackage,ltq-atm-ar9))
+$(eval $(call KernelPackage,ltq-atm-vr9))
diff --git a/package/kernel/lantiq/ltq-atm/src/Makefile b/package/kernel/lantiq/ltq-atm/src/Makefile
new file mode 100644
index 0000000000..3d68c8f6de
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/Makefile
@@ -0,0 +1,23 @@
+ifeq ($(BUILD_VARIANT),danube)
+ CFLAGS_MODULE = -DCONFIG_DANUBE
+ obj-m = ltq_atm_danube.o
+ ltq_atm_danube-objs = ltq_atm.o ifxmips_atm_danube.o
+endif
+
+ifeq ($(BUILD_VARIANT),ase)
+ CFLAGS_MODULE = -DCONFIG_AMAZON_SE
+ obj-m = ltq_atm_ase.o
+ ltq_atm_ase-objs = ltq_atm.o ifxmips_atm_amazon_se.o
+endif
+
+ifeq ($(BUILD_VARIANT),ar9)
+ CFLAGS_MODULE = -DCONFIG_AR9
+ obj-m = ltq_atm_ar9.o
+ ltq_atm_ar9-objs = ltq_atm.o ifxmips_atm_ar9.o
+endif
+
+ifeq ($(BUILD_VARIANT),vr9)
+ CFLAGS_MODULE = -DCONFIG_VR9
+ obj-m = ltq_atm_vr9.o
+ ltq_atm_vr9-objs = ltq_atm.o ifxmips_atm_vr9.o
+endif
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_amazon_se.c b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_amazon_se.c
new file mode 100644
index 0000000000..6e8975bac0
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_amazon_se.c
@@ -0,0 +1,341 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_amazon_se.c
+** PROJECT : UEIP
+** MODULES : ATM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM driver common source file (core functions)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+/*
+ * ####################################
+ * Head File
+ * ####################################
+ */
+
+/*
+ * Common Head File
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <asm/delay.h>
+
+/*
+ * Chip Specific Head File
+ */
+#include "ifxmips_atm_core.h"
+#include "ifxmips_atm_fw_amazon_se.h"
+
+#include <lantiq_soc.h>
+
+#define EMA_CMD_BUF_LEN 0x0040
+#define EMA_CMD_BASE_ADDR (0x00001580 << 2)
+#define EMA_DATA_BUF_LEN 0x0100
+#define EMA_DATA_BASE_ADDR (0x00001900 << 2)
+#define EMA_WRITE_BURST 0x2
+#define EMA_READ_BURST 0x2
+
+
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+/*
+ * EMA Settings
+ */
+#define EMA_CMD_BUF_LEN 0x0040
+#define EMA_CMD_BASE_ADDR (0x00001580 << 2)
+#define EMA_DATA_BUF_LEN 0x0100
+#define EMA_DATA_BASE_ADDR (0x00000B00 << 2)
+#define EMA_WRITE_BURST 0x2
+#define EMA_READ_BURST 0x2
+
+
+
+/*
+ * ####################################
+ * Declaration
+ * ####################################
+ */
+
+/*
+ * Hardware Init/Uninit Functions
+ */
+static inline void init_pmu(void);
+static inline void uninit_pmu(void);
+static inline void reset_ppe(void);
+static inline void init_ema(void);
+static inline void init_mailbox(void);
+static inline void init_atm_tc(void);
+static inline void clear_share_buffer(void);
+
+
+
+/*
+ * ####################################
+ * Local Variable
+ * ####################################
+ */
+
+
+
+/*
+ * ####################################
+ * Local Function
+ * ####################################
+ */
+#define IFX_PMU_MODULE_PPE_SLL01 BIT(19)
+#define IFX_PMU_MODULE_PPE_TC BIT(21)
+#define IFX_PMU_MODULE_PPE_EMA BIT(22)
+#define IFX_PMU_MODULE_PPE_QSB BIT(18)
+#define IFX_PMU_MODULE_TPE BIT(13)
+#define IFX_PMU_MODULE_DSL_DFE BIT(9)
+
+static inline void init_pmu(void)
+{
+ //*(unsigned long *)0xBF10201C &= ~((1 << 15) | (1 << 13) | (1 << 9));
+ //PPE_TOP_PMU_SETUP(IFX_PMU_ENABLE);
+/* PPE_SLL01_PMU_SETUP(IFX_PMU_ENABLE);
+ PPE_TC_PMU_SETUP(IFX_PMU_ENABLE);
+ PPE_EMA_PMU_SETUP(IFX_PMU_ENABLE);
+ //PPE_QSB_PMU_SETUP(IFX_PMU_ENABLE);
+ PPE_TPE_PMU_SETUP(IFX_PMU_ENABLE);
+ DSL_DFE_PMU_SETUP(IFX_PMU_ENABLE);*/
+ ltq_pmu_enable(IFX_PMU_MODULE_PPE_SLL01 |
+ IFX_PMU_MODULE_PPE_TC |
+ IFX_PMU_MODULE_PPE_EMA |
+ IFX_PMU_MODULE_TPE |
+ IFX_PMU_MODULE_DSL_DFE);
+}
+
+static inline void uninit_pmu(void)
+{
+ /*PPE_SLL01_PMU_SETUP(IFX_PMU_DISABLE);
+ PPE_TC_PMU_SETUP(IFX_PMU_DISABLE);
+ PPE_EMA_PMU_SETUP(IFX_PMU_DISABLE);
+ //PPE_QSB_PMU_SETUP(IFX_PMU_DISABLE);
+ PPE_TPE_PMU_SETUP(IFX_PMU_DISABLE);
+ DSL_DFE_PMU_SETUP(IFX_PMU_DISABLE);
+ //PPE_TOP_PMU_SETUP(IFX_PMU_DISABLE);*/
+}
+
+static inline void reset_ppe(void)
+{
+#if 0 //MODULE
+ unsigned int etop_cfg;
+ unsigned int etop_mdio_cfg;
+ unsigned int etop_ig_plen_ctrl;
+ unsigned int enet_mac_cfg;
+
+ etop_cfg = *IFX_PP32_ETOP_CFG;
+ etop_mdio_cfg = *IFX_PP32_ETOP_MDIO_CFG;
+ etop_ig_plen_ctrl = *IFX_PP32_ETOP_IG_PLEN_CTRL;
+ enet_mac_cfg = *IFX_PP32_ENET_MAC_CFG;
+
+ *IFX_PP32_ETOP_CFG = (*IFX_PP32_ETOP_CFG & ~0x03C0) | 0x0001;
+
+ // reset PPE
+ ifx_rcu_rst(IFX_RCU_DOMAIN_PPE, IFX_RCU_MODULE_ATM);
+
+ *IFX_PP32_ETOP_MDIO_CFG = etop_mdio_cfg;
+ *IFX_PP32_ETOP_IG_PLEN_CTRL = etop_ig_plen_ctrl;
+ *IFX_PP32_ENET_MAC_CFG = enet_mac_cfg;
+ *IFX_PP32_ETOP_CFG = etop_cfg;
+#endif
+}
+
+static inline void init_ema(void)
+{
+ IFX_REG_W32((EMA_CMD_BUF_LEN << 16) | (EMA_CMD_BASE_ADDR >> 2), EMA_CMDCFG);
+ IFX_REG_W32((EMA_DATA_BUF_LEN << 16) | (EMA_DATA_BASE_ADDR >> 2), EMA_DATACFG);
+ IFX_REG_W32(0x000000FF, EMA_IER);
+ IFX_REG_W32(EMA_READ_BURST | (EMA_WRITE_BURST << 2), EMA_CFG);
+}
+
+static inline void init_mailbox(void)
+{
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU1_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU1_IER);
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU3_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU3_IER);
+}
+
+static inline void init_atm_tc(void)
+{
+ IFX_REG_W32(0x0000, DREG_AT_CTRL);
+ IFX_REG_W32(0x0000, DREG_AR_CTRL);
+ IFX_REG_W32(0x0, DREG_AT_IDLE0);
+ IFX_REG_W32(0x0, DREG_AT_IDLE1);
+ IFX_REG_W32(0x0, DREG_AR_IDLE0);
+ IFX_REG_W32(0x0, DREG_AR_IDLE1);
+ IFX_REG_W32(0x40, RFBI_CFG);
+ IFX_REG_W32(0x0700, SFSM_DBA0);
+ IFX_REG_W32(0x0818, SFSM_DBA1);
+ IFX_REG_W32(0x0930, SFSM_CBA0);
+ IFX_REG_W32(0x0944, SFSM_CBA1);
+ IFX_REG_W32(0x14014, SFSM_CFG0);
+ IFX_REG_W32(0x14014, SFSM_CFG1);
+ IFX_REG_W32(0x0958, FFSM_DBA0);
+ IFX_REG_W32(0x09AC, FFSM_DBA1);
+ IFX_REG_W32(0x10006, FFSM_CFG0);
+ IFX_REG_W32(0x10006, FFSM_CFG1);
+ IFX_REG_W32(0x00000001, FFSM_IDLE_HEAD_BC0);
+ IFX_REG_W32(0x00000001, FFSM_IDLE_HEAD_BC1);
+}
+
+static inline void clear_share_buffer(void)
+{
+ volatile u32 *p = SB_RAM0_ADDR(0);
+ unsigned int i;
+
+ for ( i = 0; i < SB_RAM0_DWLEN + SB_RAM1_DWLEN; i++ )
+ IFX_REG_W32(0, p++);
+}
+
+/*
+ * Description:
+ * Download PPE firmware binary code.
+ * Input:
+ * src --- u32 *, binary code buffer
+ * dword_len --- unsigned int, binary code length in DWORD (32-bit)
+ * Output:
+ * int --- 0: Success
+ * else: Error Code
+ */
+static inline int pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
+{
+ volatile u32 *dest;
+
+ if ( code_src == 0 || ((unsigned long)code_src & 0x03) != 0
+ || data_src == 0 || ((unsigned long)data_src & 0x03) != 0 )
+ return -1;
+
+ if ( code_dword_len <= CDM_CODE_MEMORYn_DWLEN(0) )
+ IFX_REG_W32(0x00, CDM_CFG);
+ else
+ IFX_REG_W32(0x04, CDM_CFG);
+
+ /* copy code */
+ dest = CDM_CODE_MEMORY(0, 0);
+ while ( code_dword_len-- > 0 )
+ IFX_REG_W32(*code_src++, dest++);
+
+ /* copy data */
+ dest = CDM_DATA_MEMORY(0, 0);
+ while ( data_dword_len-- > 0 )
+ IFX_REG_W32(*data_src++, dest++);
+
+ return 0;
+}
+
+
+
+/*
+ * ####################################
+ * Global Function
+ * ####################################
+ */
+
+extern void ase_fw_ver(unsigned int *major, unsigned int *minor)
+{
+ ASSERT(major != NULL, "pointer is NULL");
+ ASSERT(minor != NULL, "pointer is NULL");
+
+ *major = FW_VER_ID->major;
+ *minor = FW_VER_ID->minor;
+}
+
+void ase_init(void)
+{
+ init_pmu();
+
+ reset_ppe();
+
+ init_ema();
+
+ init_mailbox();
+
+ init_atm_tc();
+
+ clear_share_buffer();
+}
+
+void ase_shutdown(void)
+{
+ uninit_pmu();
+}
+
+/*
+ * Description:
+ * Initialize and start up PP32.
+ * Input:
+ * none
+ * Output:
+ * int --- 0: Success
+ * else: Error Code
+ */
+int ase_start(int pp32)
+{
+ int ret;
+
+ /* download firmware */
+ ret = pp32_download_code(firmware_binary_code, sizeof(firmware_binary_code) / sizeof(*firmware_binary_code), firmware_binary_data, sizeof(firmware_binary_data) / sizeof(*firmware_binary_data));
+ if ( ret != 0 )
+ return ret;
+
+ /* run PP32 */
+ IFX_REG_W32(DBG_CTRL_RESTART, PP32_DBG_CTRL);
+
+ /* idle for a while to let PP32 init itself */
+ udelay(10);
+
+ return 0;
+}
+
+/*
+ * Description:
+ * Halt PP32.
+ * Input:
+ * none
+ * Output:
+ * none
+ */
+void ase_stop(int pp32)
+{
+ /* halt PP32 */
+ IFX_REG_W32(DBG_CTRL_STOP, PP32_DBG_CTRL);
+}
+
+struct ltq_atm_ops ase_ops = {
+ .init = ase_init,
+ .shutdown = ase_shutdown,
+ .start = ase_start,
+ .stop = ase_stop,
+ .fw_ver = ase_fw_ver,
+};
+
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ar9.c b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ar9.c
new file mode 100644
index 0000000000..b68848b22d
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ar9.c
@@ -0,0 +1,244 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_ar9.c
+** PROJECT : UEIP
+** MODULES : ATM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM driver common source file (core functions)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+/*
+ * ####################################
+ * Head File
+ * ####################################
+ */
+
+/*
+ * Common Head File
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <asm/delay.h>
+
+/*
+ * Chip Specific Head File
+ */
+#include "ifxmips_atm_core.h"
+
+#include "ifxmips_atm_fw_ar9.h"
+#include "ifxmips_atm_fw_regs_ar9.h"
+
+#include <lantiq_soc.h>
+
+
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+/*
+ * EMA Settings
+ */
+#define EMA_CMD_BUF_LEN 0x0040
+#define EMA_CMD_BASE_ADDR (0x00003B80 << 2)
+#define EMA_DATA_BUF_LEN 0x0100
+#define EMA_DATA_BASE_ADDR (0x00003C00 << 2)
+#define EMA_WRITE_BURST 0x2
+#define EMA_READ_BURST 0x2
+
+
+
+/*
+ * ####################################
+ * Declaration
+ * ####################################
+ */
+
+/*
+ * Hardware Init/Uninit Functions
+ */
+static inline void init_pmu(void);
+static inline void uninit_pmu(void);
+static inline void reset_ppe(void);
+static inline void init_ema(void);
+static inline void init_mailbox(void);
+static inline void clear_share_buffer(void);
+
+
+
+/*
+ * ####################################
+ * Local Variable
+ * ####################################
+ */
+
+
+
+/*
+ * ####################################
+ * Local Function
+ * ####################################
+ */
+
+#define IFX_PMU_MODULE_PPE_SLL01 BIT(19)
+#define IFX_PMU_MODULE_PPE_TC BIT(21)
+#define IFX_PMU_MODULE_PPE_EMA BIT(22)
+#define IFX_PMU_MODULE_PPE_QSB BIT(18)
+#define IFX_PMU_MODULE_TPE BIT(13)
+#define IFX_PMU_MODULE_DSL_DFE BIT(9)
+
+static inline void init_pmu(void)
+{
+ ltq_pmu_enable(IFX_PMU_MODULE_PPE_SLL01 |
+ IFX_PMU_MODULE_PPE_TC |
+ IFX_PMU_MODULE_PPE_EMA |
+ IFX_PMU_MODULE_PPE_QSB |
+ IFX_PMU_MODULE_TPE |
+ IFX_PMU_MODULE_DSL_DFE);
+}
+
+static inline void uninit_pmu(void)
+{
+}
+
+static inline void reset_ppe(void)
+{
+#ifdef MODULE
+ // reset PPE
+// ifx_rcu_rst(IFX_RCU_DOMAIN_PPE, IFX_RCU_MODULE_ATM);
+#endif
+}
+
+static inline void init_ema(void)
+{
+ IFX_REG_W32((EMA_CMD_BUF_LEN << 16) | (EMA_CMD_BASE_ADDR >> 2), EMA_CMDCFG);
+ IFX_REG_W32((EMA_DATA_BUF_LEN << 16) | (EMA_DATA_BASE_ADDR >> 2), EMA_DATACFG);
+ IFX_REG_W32(0x000000FF, EMA_IER);
+ IFX_REG_W32(EMA_READ_BURST | (EMA_WRITE_BURST << 2), EMA_CFG);
+}
+
+static inline void init_mailbox(void)
+{
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU1_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU1_IER);
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU3_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU3_IER);
+}
+
+static inline void clear_share_buffer(void)
+{
+ volatile u32 *p = SB_RAM0_ADDR(0);
+ unsigned int i;
+
+ for ( i = 0; i < SB_RAM0_DWLEN + SB_RAM1_DWLEN + SB_RAM2_DWLEN + SB_RAM3_DWLEN + SB_RAM4_DWLEN; i++ )
+ IFX_REG_W32(0, p++);
+}
+
+static inline int pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
+{
+ volatile u32 *dest;
+
+ if ( code_src == 0 || ((unsigned long)code_src & 0x03) != 0
+ || data_src == 0 || ((unsigned long)data_src & 0x03) != 0 )
+ return -1;
+
+ if ( code_dword_len <= CDM_CODE_MEMORYn_DWLEN(0) )
+ IFX_REG_W32(0x00, CDM_CFG);
+ else
+ IFX_REG_W32(0x04, CDM_CFG);
+
+ /* copy code */
+ dest = CDM_CODE_MEMORY(0, 0);
+ while ( code_dword_len-- > 0 )
+ IFX_REG_W32(*code_src++, dest++);
+
+ /* copy data */
+ dest = CDM_DATA_MEMORY(0, 0);
+ while ( data_dword_len-- > 0 )
+ IFX_REG_W32(*data_src++, dest++);
+
+ return 0;
+}
+
+void ar9_fw_ver(unsigned int *major, unsigned int *minor)
+{
+ ASSERT(major != NULL, "pointer is NULL");
+ ASSERT(minor != NULL, "pointer is NULL");
+
+ *major = FW_VER_ID->major;
+ *minor = FW_VER_ID->minor;
+}
+
+void ar9_init(void)
+{
+ init_pmu();
+ reset_ppe();
+ init_ema();
+ init_mailbox();
+ clear_share_buffer();
+}
+
+void ar9_shutdown(void)
+{
+ ltq_pmu_disable(IFX_PMU_MODULE_PPE_SLL01 |
+ IFX_PMU_MODULE_PPE_TC |
+ IFX_PMU_MODULE_PPE_EMA |
+ IFX_PMU_MODULE_PPE_QSB |
+ IFX_PMU_MODULE_TPE |
+ IFX_PMU_MODULE_DSL_DFE);
+}
+
+int ar9_start(int pp32)
+{
+ int ret;
+
+ ret = pp32_download_code(ar9_fw_bin, sizeof(ar9_fw_bin) / sizeof(*ar9_fw_bin),
+ ar9_fw_data, sizeof(ar9_fw_data) / sizeof(*ar9_fw_data));
+ if ( ret != 0 )
+ return ret;
+
+ IFX_REG_W32(DBG_CTRL_RESTART, PP32_DBG_CTRL(0));
+
+ udelay(10);
+
+ return 0;
+}
+
+void ar9_stop(int pp32)
+{
+ IFX_REG_W32(DBG_CTRL_STOP, PP32_DBG_CTRL(0));
+}
+
+struct ltq_atm_ops ar9_ops = {
+ .init = ar9_init,
+ .shutdown = ar9_shutdown,
+ .start = ar9_start,
+ .stop = ar9_stop,
+ .fw_ver = ar9_fw_ver,
+};
+
+
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_core.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_core.h
new file mode 100644
index 0000000000..2f754c982b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_core.h
@@ -0,0 +1,245 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_core.h
+** PROJECT : UEIP
+** MODULES : ATM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM driver header file (core functions)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 17 JUN 2009 Xu Liang Init Version
+*******************************************************************************/
+
+#ifndef IFXMIPS_ATM_CORE_H
+#define IFXMIPS_ATM_CORE_H
+
+
+#define INT_NUM_IM2_IRL24 (INT_NUM_IM2_IRL0 + 24)
+#define INT_NUM_IM2_IRL13 (INT_NUM_IM2_IRL0 + 13)
+#define CONFIG_IFXMIPS_DSL_CPE_MEI
+#define IFX_REG_W32(_v, _r) __raw_writel((_v), (volatile unsigned int *)(_r))
+#define IFX_REG_R32(_r) __raw_readl((volatile unsigned int *)(_r))
+#define IFX_REG_W32_MASK(_clr, _set, _r) IFX_REG_W32((IFX_REG_R32((_r)) & ~(_clr)) | (_set), (_r))
+#define SET_BITS(x, msb, lsb, value) (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))
+
+struct ltq_atm_ops {
+ void (*init)(void);
+ void (*shutdown)(void);
+
+ int (*start)(int pp32);
+ void (*stop)(int pp32);
+
+ void (*fw_ver)(unsigned int *major, unsigned int *minor);
+};
+
+#include <lantiq_atm.h>
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+/*
+ * Compile Options
+ */
+
+#define ENABLE_DEBUG 1
+
+#define ENABLE_ASSERT 1
+
+#define INLINE
+
+#define DEBUG_DUMP_SKB 1
+
+#define DEBUG_QOS 1
+
+#define DISABLE_QOS_WORKAROUND 0
+
+#define ENABLE_DBG_PROC 1
+
+#define ENABLE_FW_PROC 1
+
+#ifdef CONFIG_IFX_ATM_TASKLET
+ #define ENABLE_TASKLET 1
+#endif
+
+#ifdef CONFIG_IFX_ATM_RETX
+ #define ENABLE_ATM_RETX 1
+#endif
+
+#if defined(CONFIG_DSL_MEI_CPE_DRV) && !defined(CONFIG_IFXMIPS_DSL_CPE_MEI)
+ #define CONFIG_IFXMIPS_DSL_CPE_MEI 1
+#endif
+
+/*
+ * Debug/Assert/Error Message
+ */
+
+#define ifx_atm_dbg_enable 1
+
+#define DBG_ENABLE_MASK_ERR (1 << 0)
+#define DBG_ENABLE_MASK_DEBUG_PRINT (1 << 1)
+#define DBG_ENABLE_MASK_ASSERT (1 << 2)
+#define DBG_ENABLE_MASK_DUMP_SKB_RX (1 << 8)
+#define DBG_ENABLE_MASK_DUMP_SKB_TX (1 << 9)
+#define DBG_ENABLE_MASK_DUMP_QOS (1 << 10)
+#define DBG_ENABLE_MASK_DUMP_INIT (1 << 11)
+#define DBG_ENABLE_MASK_MAC_SWAP (1 << 12)
+#define DBG_ENABLE_MASK_ALL (DBG_ENABLE_MASK_ERR | DBG_ENABLE_MASK_DEBUG_PRINT | DBG_ENABLE_MASK_ASSERT | DBG_ENABLE_MASK_DUMP_SKB_RX | DBG_ENABLE_MASK_DUMP_SKB_TX | DBG_ENABLE_MASK_DUMP_QOS | DBG_ENABLE_MASK_DUMP_INIT | DBG_ENABLE_MASK_MAC_SWAP)
+
+#if defined(ENABLE_ASSERT) && ENABLE_ASSERT
+ #define ASSERT(cond, format, arg...) do { if ( (ifx_atm_dbg_enable & DBG_ENABLE_MASK_ASSERT) && !(cond) ) printk(KERN_ERR __FILE__ ":%d:%s: " format "\n", __LINE__, __FUNCTION__, ##arg); } while ( 0 )
+#else
+ #define ASSERT(cond, format, arg...)
+#endif
+
+
+/*
+ * Constants
+ */
+#define DEFAULT_TX_LINK_RATE 3200 // in cells
+
+/*
+ * ATM Port, QSB Queue, DMA RX/TX Channel Parameters
+ */
+#define ATM_PORT_NUMBER 2
+#define MAX_QUEUE_NUMBER 16
+#define OAM_RX_QUEUE 15
+#define QSB_RESERVE_TX_QUEUE 0
+#define FIRST_QSB_QID 1
+#define MAX_PVC_NUMBER (MAX_QUEUE_NUMBER - FIRST_QSB_QID)
+#define MAX_RX_DMA_CHANNEL_NUMBER 8
+#define MAX_TX_DMA_CHANNEL_NUMBER 16
+#define DATA_BUFFER_ALIGNMENT EMA_ALIGNMENT
+#define DESC_ALIGNMENT 8
+#define DEFAULT_RX_HUNT_BITTH 4
+
+/*
+ * RX DMA Channel Allocation
+ */
+#define RX_DMA_CH_OAM 0
+#define RX_DMA_CH_AAL 1
+#define RX_DMA_CH_TOTAL 2
+#define RX_DMA_CH_OAM_DESC_LEN 32
+#define RX_DMA_CH_OAM_BUF_SIZE ((CELL_SIZE + 14) & ~15)
+#define RX_DMA_CH_AAL_BUF_SIZE (2048 - 48)
+
+/*
+ * OAM Constants
+ */
+#define OAM_HTU_ENTRY_NUMBER 3
+#define OAM_F4_SEG_HTU_ENTRY 0
+#define OAM_F4_TOT_HTU_ENTRY 1
+#define OAM_F5_HTU_ENTRY 2
+#define OAM_F4_CELL_ID 0
+#define OAM_F5_CELL_ID 15
+#if defined(ENABLE_ATM_RETX) && ENABLE_ATM_RETX
+ #undef OAM_HTU_ENTRY_NUMBER
+ #define OAM_HTU_ENTRY_NUMBER 4
+ #define OAM_ARQ_HTU_ENTRY 3
+#endif
+
+/*
+ * RX Frame Definitions
+ */
+#define MAX_RX_PACKET_ALIGN_BYTES 3
+#define MAX_RX_PACKET_PADDING_BYTES 3
+#define RX_INBAND_TRAILER_LENGTH 8
+#define MAX_RX_FRAME_EXTRA_BYTES (RX_INBAND_TRAILER_LENGTH + MAX_RX_PACKET_ALIGN_BYTES + MAX_RX_PACKET_PADDING_BYTES)
+
+/*
+ * TX Frame Definitions
+ */
+#define MAX_TX_HEADER_ALIGN_BYTES 12
+#define MAX_TX_PACKET_ALIGN_BYTES 3
+#define MAX_TX_PACKET_PADDING_BYTES 3
+#define TX_INBAND_HEADER_LENGTH 8
+#define MAX_TX_FRAME_EXTRA_BYTES (TX_INBAND_HEADER_LENGTH + MAX_TX_HEADER_ALIGN_BYTES + MAX_TX_PACKET_ALIGN_BYTES + MAX_TX_PACKET_PADDING_BYTES)
+
+#define CELL_SIZE ATM_AAL0_SDU
+
+#if defined(ENABLE_ATM_RETX) && ENABLE_ATM_RETX
+ #define RETX_PLAYOUT_BUFFER_ORDER 6
+ #define RETX_PLAYOUT_BUFFER_SIZE (PAGE_SIZE * (1 << RETX_PLAYOUT_BUFFER_ORDER))
+ #define RETX_PLAYOUT_FW_BUFF_SIZE (RETX_PLAYOUT_BUFFER_SIZE / (32 * 56 /* cell size */))
+ #define RETX_POLLING_INTERVAL (HZ / 100 > 0 ? HZ / 100 : 1)
+#endif
+
+typedef struct {
+ unsigned int h;
+ unsigned int l;
+} ppe_u64_t;
+
+struct port {
+ unsigned int tx_max_cell_rate;
+ unsigned int tx_current_cell_rate;
+
+ struct atm_dev *dev;
+};
+
+struct connection {
+ struct atm_vcc *vcc;
+
+ volatile struct tx_descriptor *tx_desc;
+ unsigned int tx_desc_pos;
+ struct sk_buff **tx_skb;
+
+ unsigned int aal5_vcc_crc_err; /* number of packets with CRC error */
+ unsigned int aal5_vcc_oversize_sdu; /* number of packets with oversize error */
+
+ unsigned int port;
+};
+
+struct atm_priv_data {
+ unsigned long conn_table;
+ struct connection conn[MAX_PVC_NUMBER];
+
+ volatile struct rx_descriptor *aal_desc;
+ unsigned int aal_desc_pos;
+
+ volatile struct rx_descriptor *oam_desc;
+ unsigned char *oam_buf;
+ unsigned int oam_desc_pos;
+
+ struct port port[ATM_PORT_NUMBER];
+
+ unsigned int wrx_pdu; /* successfully received AAL5 packet */
+ unsigned int wrx_drop_pdu; /* AAL5 packet dropped by driver on RX */
+ unsigned int wtx_pdu; /* successfully transmitted AAL5 packet */
+ unsigned int wtx_err_pdu; /* error AAL5 packet */
+ unsigned int wtx_drop_pdu; /* AAL5 packet dropped by driver on TX */
+
+ unsigned int wrx_oam; /* successfully received OAM cell */
+ unsigned int wrx_drop_oam; /* OAM cell dropped by driver on RX */
+ unsigned int wtx_oam; /* successfully transmitted OAM cell */
+ unsigned int wtx_err_oam; /* error during transmiting OAM cell */
+ unsigned int wtx_drop_oam; /* OAM cell dropped by driver on TX */
+
+ ppe_u64_t wrx_total_byte;
+ ppe_u64_t wtx_total_byte;
+ unsigned int prev_wrx_total_byte;
+ unsigned int prev_wtx_total_byte;
+
+ void *aal_desc_base;
+ void *oam_desc_base;
+ void *oam_buf_base;
+ void *tx_desc_base;
+ void *tx_skb_base;
+};
+
+#include "ifxmips_atm_ppe_common.h"
+#include "ifxmips_atm_fw_regs_common.h"
+
+#endif
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_danube.c b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_danube.c
new file mode 100644
index 0000000000..9bab5b4a98
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_danube.c
@@ -0,0 +1,231 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_danube.c
+** PROJECT : UEIP
+** MODULES : ATM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM driver common source file (core functions)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+/*
+ * ####################################
+ * Head File
+ * ####################################
+ */
+
+/*
+ * Common Head File
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+
+/*
+ * Chip Specific Head File
+ */
+#include "ifxmips_atm_core.h"
+
+#ifdef CONFIG_DANUBE
+
+#include "ifxmips_atm_fw_danube.h"
+#include "ifxmips_atm_fw_regs_danube.h"
+
+#include <lantiq_soc.h>
+
+#define EMA_CMD_BUF_LEN 0x0040
+#define EMA_CMD_BASE_ADDR (0x00001580 << 2)
+#define EMA_DATA_BUF_LEN 0x0100
+#define EMA_DATA_BASE_ADDR (0x00001900 << 2)
+#define EMA_WRITE_BURST 0x2
+#define EMA_READ_BURST 0x2
+
+static inline void reset_ppe(void);
+
+#define IFX_PMU_MODULE_PPE_SLL01 BIT(19)
+#define IFX_PMU_MODULE_PPE_TC BIT(21)
+#define IFX_PMU_MODULE_PPE_EMA BIT(22)
+#define IFX_PMU_MODULE_PPE_QSB BIT(18)
+#define IFX_PMU_MODULE_TPE BIT(13)
+#define IFX_PMU_MODULE_DSL_DFE BIT(9)
+
+static inline void reset_ppe(void)
+{
+/*#ifdef MODULE
+ unsigned int etop_cfg;
+ unsigned int etop_mdio_cfg;
+ unsigned int etop_ig_plen_ctrl;
+ unsigned int enet_mac_cfg;
+
+ etop_cfg = *IFX_PP32_ETOP_CFG;
+ etop_mdio_cfg = *IFX_PP32_ETOP_MDIO_CFG;
+ etop_ig_plen_ctrl = *IFX_PP32_ETOP_IG_PLEN_CTRL;
+ enet_mac_cfg = *IFX_PP32_ENET_MAC_CFG;
+
+ *IFX_PP32_ETOP_CFG &= ~0x03C0;
+
+ // reset PPE
+ ifx_rcu_rst(IFX_RCU_DOMAIN_PPE, IFX_RCU_MODULE_ATM);
+
+ *IFX_PP32_ETOP_MDIO_CFG = etop_mdio_cfg;
+ *IFX_PP32_ETOP_IG_PLEN_CTRL = etop_ig_plen_ctrl;
+ *IFX_PP32_ENET_MAC_CFG = enet_mac_cfg;
+ *IFX_PP32_ETOP_CFG = etop_cfg;
+#endif*/
+}
+
+/*
+ * Description:
+ * Download PPE firmware binary code.
+ * Input:
+ * src --- u32 *, binary code buffer
+ * dword_len --- unsigned int, binary code length in DWORD (32-bit)
+ * Output:
+ * int --- 0: Success
+ * else: Error Code
+ */
+static inline int danube_pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
+{
+ volatile u32 *dest;
+
+ if ( code_src == 0 || ((unsigned long)code_src & 0x03) != 0
+ || data_src == 0 || ((unsigned long)data_src & 0x03) != 0 )
+ return -1;
+
+ if ( code_dword_len <= CDM_CODE_MEMORYn_DWLEN(0) )
+ IFX_REG_W32(0x00, CDM_CFG);
+ else
+ IFX_REG_W32(0x04, CDM_CFG);
+
+ /* copy code */
+ dest = CDM_CODE_MEMORY(0, 0);
+ while ( code_dword_len-- > 0 )
+ IFX_REG_W32(*code_src++, dest++);
+
+ /* copy data */
+ dest = CDM_DATA_MEMORY(0, 0);
+ while ( data_dword_len-- > 0 )
+ IFX_REG_W32(*data_src++, dest++);
+
+ return 0;
+}
+
+static void danube_fw_ver(unsigned int *major, unsigned int *minor)
+{
+ ASSERT(major != NULL, "pointer is NULL");
+ ASSERT(minor != NULL, "pointer is NULL");
+
+ *major = FW_VER_ID->major;
+ *minor = FW_VER_ID->minor;
+}
+
+static void danube_init(void)
+{
+ volatile u32 *p = SB_RAM0_ADDR(0);
+ unsigned int i;
+
+ ltq_pmu_enable(IFX_PMU_MODULE_PPE_SLL01 |
+ IFX_PMU_MODULE_PPE_TC |
+ IFX_PMU_MODULE_PPE_EMA |
+ IFX_PMU_MODULE_PPE_QSB |
+ IFX_PMU_MODULE_TPE |
+ IFX_PMU_MODULE_DSL_DFE);
+
+ reset_ppe();
+
+ /* init ema */
+ IFX_REG_W32((EMA_CMD_BUF_LEN << 16) | (EMA_CMD_BASE_ADDR >> 2), EMA_CMDCFG);
+ IFX_REG_W32((EMA_DATA_BUF_LEN << 16) | (EMA_DATA_BASE_ADDR >> 2), EMA_DATACFG);
+ IFX_REG_W32(0x000000FF, EMA_IER);
+ IFX_REG_W32(EMA_READ_BURST | (EMA_WRITE_BURST << 2), EMA_CFG);
+
+ /* init mailbox */
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU1_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU1_IER);
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU3_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU3_IER);
+
+ /* init atm tc */
+ IFX_REG_W32(0x0000, DREG_AT_CTRL);
+ IFX_REG_W32(0x0000, DREG_AR_CTRL);
+ IFX_REG_W32(0x0, DREG_AT_IDLE0);
+ IFX_REG_W32(0x0, DREG_AT_IDLE1);
+ IFX_REG_W32(0x0, DREG_AR_IDLE0);
+ IFX_REG_W32(0x0, DREG_AR_IDLE1);
+ IFX_REG_W32(0x40, RFBI_CFG);
+ IFX_REG_W32(0x1600, SFSM_DBA0);
+ IFX_REG_W32(0x1718, SFSM_DBA1);
+ IFX_REG_W32(0x1830, SFSM_CBA0);
+ IFX_REG_W32(0x1844, SFSM_CBA1);
+ IFX_REG_W32(0x14014, SFSM_CFG0);
+ IFX_REG_W32(0x14014, SFSM_CFG1);
+ IFX_REG_W32(0x1858, FFSM_DBA0);
+ IFX_REG_W32(0x18AC, FFSM_DBA1);
+ IFX_REG_W32(0x10006, FFSM_CFG0);
+ IFX_REG_W32(0x10006, FFSM_CFG1);
+ IFX_REG_W32(0x00000001, FFSM_IDLE_HEAD_BC0);
+ IFX_REG_W32(0x00000001, FFSM_IDLE_HEAD_BC1);
+
+ for ( i = 0; i < SB_RAM0_DWLEN + SB_RAM1_DWLEN + SB_RAM2_DWLEN + SB_RAM3_DWLEN; i++ )
+ IFX_REG_W32(0, p++);
+}
+
+static void danube_shutdown(void)
+{
+}
+
+int danube_start(int pp32)
+{
+ int ret;
+
+ /* download firmware */
+ ret = danube_pp32_download_code(
+ danube_fw_bin, sizeof(danube_fw_bin) / sizeof(*danube_fw_bin),
+ danube_fw_data, sizeof(danube_fw_data) / sizeof(*danube_fw_data));
+ if ( ret != 0 )
+ return ret;
+
+ /* run PP32 */
+ IFX_REG_W32(DBG_CTRL_START_SET(1), PP32_DBG_CTRL);
+
+ /* idle for a while to let PP32 init itself */
+ udelay(10);
+
+ return 0;
+}
+
+void danube_stop(int pp32)
+{
+ IFX_REG_W32(DBG_CTRL_STOP_SET(1), PP32_DBG_CTRL);
+}
+
+struct ltq_atm_ops danube_ops = {
+ .init = danube_init,
+ .shutdown = danube_shutdown,
+ .start = danube_start,
+ .stop = danube_stop,
+ .fw_ver = danube_fw_ver,
+};
+
+#endif
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_amazon_se.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_amazon_se.h
new file mode 100644
index 0000000000..b0a9c91bc4
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_amazon_se.h
@@ -0,0 +1,457 @@
+#ifndef IFXMIPS_ATM_FW_AMAZON_SE_H
+#define IFXMIPS_ATM_FW_AMAZON_SE_H
+
+
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_fw_amazon_se.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (PP32 Firmware)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+#define VER_IN_FIRMWARE 1
+
+#define ATM_FW_VER_MAJOR 0
+#define ATM_FW_VER_MINOR 16
+
+
+static unsigned int firmware_binary_code[] = {
+ 0x800004b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000ffe0, 0x00000000, 0x00000000, 0x00000000,
+ 0xc1000002, 0xd90c00f8, 0xc2000002, 0xda0800f9, 0x80004cc8, 0xc2000000, 0xda0800f9, 0x80004330,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x800042e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x800055a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x800041e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc0400000, 0xc0004840, 0xc88400f8, 0x80004988, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc0400002, 0xc0004840, 0xc88400f8, 0x80004908, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc3c00004, 0xdbc800f9, 0xc10c0002, 0xd90c00f8, 0x8000fee0, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc10e0002, 0xd90c00f8, 0xc0004808, 0xc84000f8, 0x80004938, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc3e1fffe, 0x597dfffe, 0x593dfe14, 0x900004d9, 0x00000000, 0x00000000, 0x00000000, 0x90cc0481,
+ 0x00000000, 0x00000000, 0x00000000, 0xc3c00000, 0xdbc800f9, 0xc1400008, 0xc1900000, 0x71588000,
+ 0x14100100, 0xc140000a, 0xc1900002, 0x71588000, 0x14100100, 0xc140000c, 0xc1900004, 0x71588000,
+ 0x14100100, 0xc1400004, 0xc1900006, 0x71588000, 0x14100100, 0xc1400006, 0xc1900008, 0x71588000,
+ 0x14100100, 0xc140000e, 0xc190000a, 0x71588000, 0x14100100, 0xc1400000, 0xc190000c, 0x71588000,
+ 0x14100100, 0xc1400002, 0xc190000e, 0x71588000, 0x14100100, 0xc0400000, 0xc11c0000, 0xc000082c,
+ 0xcd05ce00, 0xc11c0002, 0xc000082c, 0xcd05ce00, 0xc0400002, 0xc11c0000, 0xc000082c, 0xcd05ce00,
+ 0xc11c0002, 0xc000082c, 0xcd05ce00, 0xc0000824, 0x00000000, 0xcbc000f9, 0xcb8000f9, 0xcb4000f9,
+ 0xcb0000f8, 0xc0004878, 0x5bfc4000, 0xcfc000f9, 0x5bb84000, 0xcf8000f9, 0x5b744000, 0xcf4000f9,
+ 0x5b304000, 0xcf0000f8, 0xc0000a10, 0x00000000, 0xcbc000f9, 0xcb8000f8, 0xc0004874, 0x5bfc4000,
+ 0xcfc000f9, 0x5bb84000, 0xcf8000f8, 0xc30001fe, 0xc000140a, 0xcf0000f8, 0xc3000000, 0x7f018000,
+ 0xc000042e, 0xcf0000f8, 0xc000040e, 0xcf0000f8, 0xc3c1fffe, 0xc000490e, 0xcfc00078, 0xc000492c,
+ 0xcfc00078, 0xc0004924, 0xcfc00038, 0xc0004912, 0xcfc00038, 0xc0004966, 0xcfc00038, 0xc0004968,
+ 0xcfc00078, 0xc000496a, 0xcfc00078, 0xc3c1fffe, 0xc00049a0, 0xcfc000f8, 0xc3c00000, 0xc2800020,
+ 0xc3000000, 0x7f018000, 0x6ff88000, 0x6fd44000, 0x4395c000, 0x5bb84a00, 0x5838000a, 0xcf0000f8,
+ 0x5bfc0002, 0xb7e8ffc8, 0x00000000, 0xc3c00000, 0xc2800010, 0x6ff86000, 0x47bdc000, 0x5bb84c80,
+ 0xc3400000, 0x58380004, 0xcb420078, 0x00000000, 0x58380008, 0xcf400078, 0x5bfc0002, 0xb7e8ffb0,
+ 0x00000000, 0xc3c00000, 0xc2800020, 0xc348001e, 0xc3000000, 0x7f018000, 0x6ff8a000, 0x6fd44000,
+ 0x4795c000, 0x47bdc000, 0x5bb85e00, 0x58380008, 0xcf408418, 0x5838000a, 0xcf0000f8, 0x5bfc0002,
+ 0xb7e8ffb0, 0x00000000, 0x00000000, 0xc3e06242, 0x5bfc0020, 0xc0004802, 0xcfc000f8, 0xc161fffe,
+ 0x5955fffe, 0x14140000, 0x00000000, 0xc1000000, 0xd91c00f8, 0xc3e01002, 0x5bfd88c0, 0xc3a00f88,
+ 0x5bb839a2, 0x99005fa8, 0xdbd800f8, 0xdb9800f9, 0x00000000, 0xc3c00000, 0xdf7f0038, 0xa7ccfff0,
+ 0xc3800000, 0xc00048c0, 0xcb818078, 0xc0001408, 0xcfc000f8, 0xc10e0002, 0xd90c00f8, 0x5d3802a6,
+ 0xc1000002, 0xd91c1f02, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0xa9fe0270, 0xc3c00000,
+ 0xddfc00f0, 0x5d3c0000, 0x84000100, 0xc0000c04, 0xcb8000f8, 0xc11c0002, 0x00000000, 0x7391c000,
+ 0xcf8000f8, 0xc3800000, 0xc3400080, 0xdf780038, 0xb7b4ffea, 0xc3203002, 0x5b3188c4, 0xc2e00f88,
+ 0x5aec100e, 0x99005fa8, 0xdb1800f8, 0xdad800f9, 0x00000000, 0xc3800000, 0xc3400080, 0xdf780038,
+ 0xb7b4ffea, 0xc3205002, 0x5b3188c8, 0xc2e00f90, 0x5aec180c, 0x99005fa8, 0xdb1800f8, 0xdad800f9,
+ 0x00000000, 0x80000128, 0xc00048cc, 0xca8000f8, 0x00000000, 0xc1000006, 0x76914000, 0x840000fa,
+ 0x00000000, 0xa6800070, 0xc3800000, 0xc3400080, 0xdf780038, 0xb7b4ffea, 0xc3202002, 0x5b31c8c6,
+ 0xc2e00f88, 0x5aec100e, 0x99005fa8, 0xdb1800f8, 0xdad800f9, 0x00000000, 0xa6820068, 0xc3800000,
+ 0xc3400080, 0xdf780038, 0xb7b4ffea, 0xc3204002, 0x5b31c8ca, 0xc2e00f90, 0x5aec180c, 0x99005fa8,
+ 0xdb1800f8, 0xdad800f9, 0x00000000, 0xc00048cc, 0xc2800000, 0xce8000f8, 0xc3a00140, 0x5bfc0002,
+ 0x47bc8000, 0xc1000000, 0xc53c00fe, 0xdbdc00f0, 0x80000530, 0x00000000, 0x80002130, 0x00000000,
+ 0x8000fd70, 0xc0004958, 0xc84000f8, 0x00000000, 0xc3c00002, 0x787c2000, 0xcc4000f8, 0xc0004848,
+ 0xcb8400f8, 0xc000495c, 0xcac400f8, 0xc0004844, 0xc88400f8, 0x47ad0000, 0x8400ff82, 0xc000487c,
+ 0xc80400f8, 0x00000000, 0x00000000, 0x40080000, 0xca0000f8, 0xc0001624, 0xcb0400f8, 0xa63c007a,
+ 0x00000000, 0x00000000, 0xa71eff22, 0x00000000, 0xc0000824, 0xca8400f8, 0x6ca08000, 0x6ca42000,
+ 0x46250000, 0x42290000, 0xc35e0002, 0xc6340060, 0xc0001624, 0xcf440078, 0xc2000000, 0xc161fffe,
+ 0x5955fffe, 0x14140000, 0x00000000, 0xc0004844, 0xc88400f8, 0xc000082c, 0xca040038, 0x00000000,
+ 0x00000000, 0x58880002, 0xb6080018, 0x00000000, 0xc0800000, 0xc0004844, 0xcc840038, 0x5aec0002,
+ 0xc000495c, 0xcec400f8, 0x5e6c0006, 0x84000060, 0xc0004848, 0xcb8400f8, 0xc0000838, 0xc2500002,
+ 0xce450800, 0x5fb80002, 0xc0004848, 0xcf8400f8, 0x5eec0002, 0xc000495c, 0xcec400f8, 0x00000000,
+ 0xc121fffe, 0x5911fe14, 0x14100000, 0x8000fd98, 0xc000495a, 0xc84000f8, 0x00000000, 0xc3c00002,
+ 0x787c2000, 0xcc4000f8, 0xc0004960, 0xcac400f8, 0x00000000, 0x00000000, 0x5eec0000, 0x8400010a,
+ 0x00000000, 0xb6fc0050, 0xc0001600, 0xca0400f8, 0x00000000, 0x00000000, 0xa61e00d2, 0x6fe90000,
+ 0xc0000a28, 0xce850800, 0xc2c00000, 0xc2800004, 0xb6e800a0, 0xc0001604, 0xca8400f8, 0xc0004960,
+ 0xcec400f8, 0xa69efcc2, 0x00000000, 0x6fe90000, 0xc0000a28, 0xce850800, 0xc2c00002, 0xc0001600,
+ 0xca0400f8, 0x00000000, 0x00000000, 0xa61e002a, 0x6fe90000, 0xc0000a28, 0xce850800, 0xc2c00000,
+ 0xc0001604, 0xca8400f8, 0xc0004960, 0xcec400f8, 0xa69efc2a, 0xc2400000, 0xc0000a14, 0xca440028,
+ 0x00000000, 0x00000000, 0x466d2000, 0xa4400020, 0xc2800000, 0xdfeb0029, 0x80000010, 0xdfea0029,
+ 0xb668f932, 0x00000000, 0xc00048a0, 0xcb0400f8, 0xc0000a10, 0xca8400f8, 0x6f208000, 0x6f242000,
+ 0x46250000, 0x42a10000, 0xc2400000, 0xc0000a14, 0xca440028, 0xc35e0002, 0xc6340060, 0xc0001604,
+ 0xcf440078, 0x5b300002, 0xb6700018, 0x5aec0002, 0xc3000000, 0xc00048a0, 0xcf0400f8, 0xc0004960,
+ 0xcec400f8, 0x8000f868, 0xc0004918, 0xd28000f8, 0xc2000000, 0xdf600038, 0x5e600080, 0x84000272,
+ 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc000480a, 0xca0000f8, 0xc0004912,
+ 0xca4000f8, 0xc0004924, 0xca8000f8, 0xc0004966, 0xcac000f8, 0x00000000, 0xc121fffe, 0x5911fe14,
+ 0x14100000, 0x76250000, 0x76290000, 0x762d0000, 0x840001ca, 0xc0004918, 0xca4000f8, 0xc28001fe,
+ 0x76290000, 0x5a640002, 0x6a254010, 0x5ee80000, 0x8400001a, 0x6aa54000, 0x80000010, 0xc62800f8,
+ 0x62818008, 0xc0004918, 0xcf0000f8, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc0004966,
+ 0xca4000f8, 0xc2000002, 0x6a310000, 0x7e010000, 0x76612000, 0xce4000f8, 0x00000000, 0xc121fffe,
+ 0x5911fe14, 0x14100000, 0x6f346000, 0x4771a000, 0x5b744c80, 0xc2800000, 0x58340006, 0xca800078,
+ 0xc2c00000, 0x58340000, 0xcac000d8, 0xc2400000, 0x5834000a, 0xca420078, 0x6ea82000, 0x42e9e000,
+ 0x6f2ca000, 0x42e56000, 0x5aec1400, 0xc3990040, 0xc7381c18, 0xc6f80060, 0x99005fa8, 0xdb9800f8,
+ 0xdbd800f9, 0x00000000, 0xdea000f8, 0x46310000, 0x8400fd80, 0xc0004958, 0xc84000f8, 0x00000000,
+ 0xc3c00002, 0x787c2000, 0xcc4000f8, 0xc0004848, 0xcb8400f8, 0xc0004844, 0xc88400f8, 0x5fb80000,
+ 0x8400f7f2, 0xc0001a1c, 0xca0000f8, 0xc2400002, 0x6a452000, 0x76250000, 0x8400f7c2, 0xc000487c,
+ 0xc80400f8, 0x00000000, 0x00000000, 0x40080000, 0xca0000f8, 0xc42400f8, 0x00000000, 0xa63c17da,
+ 0x00000000, 0xc0004878, 0xc80400f8, 0x6c908000, 0x45088000, 0x45088000, 0x40100000, 0xca0000f8,
+ 0xc42400f8, 0x00000000, 0xc0004934, 0xce0000f8, 0xc2800002, 0xc4681c08, 0xc62821d0, 0xc2600010,
+ 0x5a652440, 0xc0004800, 0xcb4000f8, 0xc2200400, 0x5a202400, 0xc7601040, 0xc0001220, 0xce8000f8,
+ 0xc0001200, 0xce4000f8, 0xc0001202, 0xce0000f8, 0xc0001240, 0xcb4000f8, 0x00000000, 0x00000000,
+ 0xa754ffe0, 0xc2000000, 0xc7600040, 0xa7520042, 0x00000000, 0x00000000, 0x99006720, 0xc0004822,
+ 0xc94000f8, 0xc1800002, 0x80001680, 0x58206480, 0xc2000000, 0xca000018, 0xc2400000, 0xca414000,
+ 0xc2800000, 0xca812000, 0xc2c00000, 0xcac20018, 0xc0004938, 0xce0000f8, 0xc0004920, 0xce4000f8,
+ 0xc0004916, 0xce8000f8, 0xc0004922, 0xcec000f8, 0xa6400540, 0x00000000, 0xc0004938, 0xcbc000f8,
+ 0x00000000, 0xc3800000, 0x6ff48000, 0x6fd44000, 0x4355a000, 0x5b744a00, 0x58340000, 0xcb802010,
+ 0x00000000, 0xc2000000, 0x6fb46000, 0x4779a000, 0x5b744c80, 0x5834000c, 0xca000020, 0xc000491a,
+ 0xcf8000f8, 0x5e200000, 0x8400046a, 0xc2000000, 0xdf610048, 0x5e6001e8, 0x8800ffe8, 0xc2000002,
+ 0xc2400466, 0xc2a00000, 0x5aa80000, 0xc0001006, 0xce0000f8, 0xc0001008, 0xce4000f8, 0xc000100a,
+ 0xce8000f8, 0x990059e8, 0xc1a0fffe, 0xc0000824, 0xc9840060, 0xc0004934, 0xca4000f8, 0xc2000000,
+ 0xc2800002, 0x99005a28, 0xda9800f8, 0xc61400f8, 0xc65800f8, 0xc161fffe, 0x5955fffe, 0x14140000,
+ 0x00000000, 0x99005b10, 0xc000491a, 0xc94000f8, 0x00000000, 0x00000000, 0xc121fffe, 0x5911fe14,
+ 0x14100000, 0xc0004922, 0xca001118, 0xc3c00000, 0xc3800000, 0xc0004930, 0xce023118, 0xc0004932,
+ 0xcbc000d8, 0xc2800000, 0xc000491e, 0xcfc000f8, 0xc0004862, 0xca800060, 0xc3a0001a, 0x5bb94000,
+ 0xc6b80060, 0xc000491c, 0xcf8000f8, 0x99005d80, 0xc000491c, 0xc1400000, 0xc9420048, 0x00000000,
+ 0x00000000, 0x00000000, 0xa8e2ffe8, 0xc2000000, 0xc1220002, 0xd90c00f8, 0xdf600038, 0x5e600080,
+ 0x8400fff2, 0xc000491c, 0xca0000f8, 0xc000491e, 0xca4000f8, 0x00000000, 0x00000000, 0x99005fa8,
+ 0xda1800f8, 0xda5800f9, 0x00000000, 0xc2000000, 0xdf610048, 0x5e6001fe, 0x8800ffe8, 0xc0004916,
+ 0xca8000f8, 0xc2c00000, 0xdfec0048, 0xc2400000, 0x466d2000, 0x8400004a, 0x5ea80000, 0x8400003a,
+ 0xc2600002, 0x99006720, 0xc000482e, 0xc94000f8, 0xc1800002, 0x80000030, 0xc2600000, 0x99006720,
+ 0xc000482c, 0xc94000f8, 0xc1800002, 0xc2000068, 0xc6240078, 0xc0004930, 0xce400080, 0xc000491a,
+ 0xc98000f8, 0xc0004862, 0xc94000f8, 0x6d9c6000, 0x45d8e000, 0x59dc4c80, 0x99005e08, 0xd95800f8,
+ 0xd99800f9, 0xd9d400f8, 0x99005d80, 0xc000491c, 0xc1400000, 0xc9420048, 0xc2000000, 0xdf600038,
+ 0x5e600080, 0x8400ffea, 0x00000000, 0xc000491c, 0xca0000f8, 0xc000491e, 0xca4000f8, 0x00000000,
+ 0x00000000, 0x99005fa8, 0xda1800f8, 0xda5800f9, 0x00000000, 0x800010e8, 0x00000000, 0x99006720,
+ 0xc000482a, 0xc94000f8, 0xc1800002, 0x800010b8, 0xc0004938, 0xcbc000f8, 0x00000000, 0x00000000,
+ 0x6ff88000, 0x6fd44000, 0x4395c000, 0x5bb84a00, 0x58380008, 0xca0000f8, 0x00000000, 0x00000000,
+ 0xa6000382, 0x00000000, 0xc0004938, 0xcbc000f8, 0xc3000000, 0x00000000, 0x6ff88000, 0x6fd44000,
+ 0x4395c000, 0x5bb84a00, 0x58380000, 0xcb002010, 0xc2000000, 0x58380008, 0xca020078, 0x5838000c,
+ 0xcac000f8, 0x5838000e, 0xca4000f8, 0xc000491a, 0xcf0000f8, 0xc0004930, 0xcec000f8, 0xc000493c,
+ 0xce0000f8, 0xc0004932, 0xce4000f8, 0x5e200000, 0x84000120, 0xc2800000, 0xa6fe00ba, 0x6f206000,
+ 0x46310000, 0x5a204c80, 0x5820000c, 0xca800020, 0x00000000, 0x00000000, 0x5ea80000, 0x840001f2,
+ 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x99005b10, 0xc000491a, 0xc94000f8,
+ 0x00000000, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0xc0004930, 0xcac000f8, 0xc0004932,
+ 0xca4000f8, 0xc7ec1118, 0xc0004930, 0xcec000f8, 0x5838000c, 0xcec000f8, 0x58000002, 0xce4000f8,
+ 0xc0004934, 0xca0000f8, 0xc2400002, 0x6e642000, 0x6e642000, 0x76612000, 0x8400002a, 0xc2400002,
+ 0x6e684000, 0x58380008, 0xce804200, 0xa6000020, 0x6e682000, 0x58380008, 0xce802100, 0xc2400002,
+ 0x6e642000, 0x76612000, 0x840000ea, 0x58380008, 0xca0000f8, 0xc2800000, 0xc2400000, 0xa60200c0,
+ 0xdba800f8, 0x6f386000, 0x47b1c000, 0x5bb84c80, 0x58380004, 0xca400078, 0x58380002, 0xca800078,
+ 0x00000000, 0xdeb800f8, 0x46a54000, 0x88000060, 0x00000000, 0xc0004824, 0xca0000f8, 0xc2400002,
+ 0x6e640000, 0x5a200002, 0xce0000f8, 0x58380008, 0xce400000, 0x80000018, 0x00000000, 0x80000048,
+ 0xc0004934, 0xca0000f8, 0x00000000, 0x00000000, 0xa6020c6a, 0x00000000, 0x00000000, 0x80000c98,
+ 0xc2800000, 0xc2000200, 0xc240001a, 0xdf690048, 0x46294000, 0x46a54000, 0x8800ffd2, 0xc2000006,
+ 0xc2600982, 0x5a643b6e, 0x5838000a, 0xca8000f8, 0xc0001006, 0xce0000f8, 0xc0001008, 0xce4000f8,
+ 0xc000100a, 0xce8000f8, 0x990059e8, 0xc1a0fffe, 0xc0000824, 0xc9840060, 0xc2000000, 0xc0004930,
+ 0xca02e008, 0x58380026, 0xca4000f8, 0x00000000, 0xc2800000, 0x99005a28, 0xda9800f8, 0xc61400f8,
+ 0xc65800f8, 0xc0004934, 0xca0000f8, 0x00000000, 0x00000000, 0xa6020022, 0x00000000, 0x00000000,
+ 0x80000318, 0xc0004938, 0xcbc000f8, 0xc0004878, 0xc80400f8, 0x6c908000, 0x45088000, 0x45088000,
+ 0x40100000, 0xca0000f8, 0xc42400f8, 0x00000000, 0x58240018, 0xca0000f8, 0x6ff88000, 0x6fd44000,
+ 0x4395c000, 0x5bb84a00, 0xc3000000, 0xc3400002, 0xc2c00000, 0xc62c0078, 0xc6270038, 0xc0004940,
+ 0xce400038, 0xc6260038, 0xc0004942, 0xce400038, 0xc000493c, 0xca0000f8, 0x5eec0000, 0x8400018a,
+ 0x5a6c0010, 0x46254000, 0x88000190, 0x5a600052, 0x46e54000, 0x88000178, 0x58380006, 0xca8000f8,
+ 0xc0004940, 0xca0000f8, 0xc2400000, 0xc6a70038, 0x7e412000, 0x76612000, 0xc2000000, 0xc6a10038,
+ 0x46250000, 0x84000138, 0xc0004942, 0xca0000f8, 0xc2400000, 0xc6a60038, 0x7e412000, 0x76612000,
+ 0xc2000000, 0xc6a00038, 0x58380002, 0xca8000f8, 0x46250000, 0x840000e8, 0xc2400000, 0xc6a60078,
+ 0x466d0000, 0x880000da, 0xc2400000, 0xc6a40078, 0x58380008, 0xca8000f8, 0x46e50000, 0x880000ba,
+ 0x00000000, 0xa6820018, 0x00000000, 0xc7700b00, 0xa6840098, 0x00000000, 0xc7700a00, 0x80000080,
+ 0xc7700200, 0xc000493c, 0xcac000f8, 0x80000060, 0xc7700300, 0xc000493c, 0xcac000f8, 0x80000040,
+ 0xc7700900, 0x80000030, 0xc7700800, 0x80000020, 0xc7700700, 0x80000010, 0xc7700500, 0xc0004944,
+ 0xcf0000f8, 0xc000493e, 0xcec000f8, 0xc0004938, 0xca4000f8, 0xc000493c, 0xcb8000f8, 0xc000493e,
+ 0xcb4000f8, 0xc3000000, 0x6e608000, 0x6e544000, 0x42150000, 0x5a204a00, 0x5aa00008, 0x58200004,
+ 0xcb000078, 0xc0004934, 0xca0000f8, 0xc2400000, 0xc0004930, 0xca42e008, 0xc3c00018, 0xa6020098,
+ 0x00000000, 0x43656000, 0x47ad0000, 0x88000050, 0x46f96000, 0x6ee04010, 0x5be00004, 0xc2000000,
+ 0xc6e00008, 0x5e200000, 0x84000042, 0x5bfc0002, 0x80000030, 0xc3c00004, 0x5a2c0008, 0x47a10000,
+ 0x88000012, 0x5fb80008, 0x6fe04000, 0x42390000, 0x47212000, 0x88000068, 0xc2400000, 0xc0004930,
+ 0xca42e008, 0xc2060002, 0xc68000f8, 0xce006300, 0x6fe04000, 0x4721c000, 0x5f700010, 0x4765a000,
+ 0xc2000000, 0xc6340008, 0xc25a000a, 0xc000491a, 0xca401c18, 0xc2800000, 0xc0004932, 0xca8000d8,
+ 0xc0004862, 0xca400060, 0x6fa04010, 0x42290000, 0xc000491e, 0xce0000f8, 0xc7e41048, 0xc000491c,
+ 0xce4000f8, 0x6fe04000, 0x43a1c000, 0xc000493c, 0xcf8000f8, 0xc000493e, 0xcf4000f8, 0xc000493a,
+ 0xcfc000f8, 0x80000008, 0x00000000, 0x00000000, 0x00000000, 0xc2000000, 0xdce000f8, 0xa622ffd8,
+ 0xc1220002, 0xd90c00f8, 0xc0004938, 0xcbc000f8, 0xc0004944, 0xcb4000f8, 0xc0004862, 0xcb0000f8,
+ 0xc0004934, 0xca0000f8, 0x6ff88000, 0x6fd44000, 0x4395c000, 0x5bb84a00, 0xa6020268, 0xc2400000,
+ 0x58380008, 0xca406000, 0xdfe800f8, 0xc2218e08, 0x5a21baf6, 0x46a14000, 0x84000022, 0xc2080002,
+ 0x7361a000, 0x80000058, 0x5e640000, 0x84000022, 0xc20c0002, 0x7361a000, 0x80000030, 0xc2000000,
+ 0xc760e710, 0xc7604218, 0x5e200000, 0x84000272, 0xc2200002, 0xc0004930, 0xce021000, 0x99006720,
+ 0xc0004828, 0xc94000f8, 0xc1800002, 0x58380000, 0xca0000f8, 0x00000000, 0x00000000, 0xa6000132,
+ 0xc0004940, 0xca8000f8, 0xc0004942, 0xca4000f8, 0xc7600078, 0xc6a01838, 0xc6601038, 0xc000493a,
+ 0xca4000f8, 0xc0004934, 0xca8000f8, 0xc0005600, 0x40300000, 0x40240000, 0x5c000004, 0x5ec05800,
+ 0x88000012, 0x5c000200, 0xce0000f8, 0x58000002, 0x5ec05800, 0x88000012, 0x5c000200, 0xce8000f8,
+ 0xc000493e, 0xca0000f8, 0xc2400000, 0x5838000c, 0xce4000f8, 0x99006720, 0xc0004830, 0xc94000f8,
+ 0xc61800f8, 0xc0004930, 0xc6100078, 0xcd000078, 0x800000a8, 0xc2400002, 0x58380008, 0xce400000,
+ 0xc0004944, 0xcf4000f8, 0x80000278, 0xc000493c, 0xca4000f8, 0xdfe800f8, 0x5a300018, 0xc0005600,
+ 0x40200000, 0xca0000f8, 0x58380008, 0xc6501078, 0xcd021078, 0x5838000a, 0xce8000f8, 0x58380026,
+ 0xce0000f8, 0xc0004944, 0xcf4000f8, 0x99005d80, 0xc000491c, 0xc1400000, 0xc9420048, 0x80000038,
+ 0x00000000, 0x99006720, 0xc0004826, 0xc94000f8, 0xc1800002, 0x8000fdd8, 0xc2000000, 0xc2400080,
+ 0xdf600038, 0xb624ffea, 0xc000491c, 0xca4000f8, 0xc000491e, 0xca8000f8, 0x99005fa8, 0xda5800f8,
+ 0xda9800f9, 0x00000000, 0xc0004934, 0xca0000f8, 0x00000000, 0xc2800000, 0xa6020160, 0xc2400004,
+ 0xc2000200, 0xdf690048, 0x46294000, 0x46a54000, 0x8800ffda, 0x00000000, 0xc000491a, 0xc98000f8,
+ 0xc0004862, 0xc94000f8, 0x6d9c6000, 0x45d8e000, 0x59dc4c80, 0x99005e08, 0xd95800f8, 0xd99800f9,
+ 0xd9d400f8, 0x99005d80, 0xc000491c, 0xc1400000, 0xc9420048, 0xc2000000, 0xc2400080, 0xdf600038,
+ 0xb624ffea, 0xc000491c, 0xca4000f8, 0xc000491e, 0xca8000f8, 0x99005fa8, 0xda5800f8, 0xda9800f9,
+ 0x00000000, 0x58380008, 0xca4000f8, 0xc2000000, 0xce000018, 0xc2a1fffe, 0x5aa9fffe, 0xce021078,
+ 0x5838000a, 0xce8000f8, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc0000838, 0xc2500002,
+ 0xce450800, 0xc0004848, 0xcb8400f8, 0xc2000000, 0xc000082c, 0xca040028, 0x5fb80002, 0xc0004848,
+ 0xcf8400f8, 0x58880002, 0xb6080018, 0x00000000, 0xc0800000, 0xc0004844, 0xcc8400f8, 0x00000000,
+ 0xc121fffe, 0x5911fe14, 0x14100000, 0x8000ded8, 0xc2000000, 0xdf600038, 0x5e200080, 0x8400026a,
+ 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc000480c, 0xca0000f8, 0xc0004910,
+ 0xca4000f8, 0xc000492c, 0xca8000f8, 0xc0004968, 0xcac000f8, 0x00000000, 0xc121fffe, 0x5911fe14,
+ 0x14100000, 0x76250000, 0x76290000, 0x76e16000, 0x840001c2, 0xc0004926, 0xca4000f8, 0xc201fffe,
+ 0x76e16000, 0x5a640002, 0x6ae50010, 0x5f200000, 0x8400001a, 0x6a250000, 0x80000010, 0xc6e000f8,
+ 0x62014008, 0xc0004926, 0xce8000f8, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc0004968,
+ 0xca4000f8, 0xc2000002, 0x6a290000, 0x7e010000, 0x76612000, 0xce4000f8, 0x00000000, 0xc121fffe,
+ 0x5911fe14, 0x14100000, 0x6eb4a000, 0x6e944000, 0x4755a000, 0x4769a000, 0x5b745e00, 0x58340002,
+ 0xc2000000, 0xca0000d8, 0x5834002e, 0xc2400000, 0xca400078, 0x6eb0a000, 0x6ebc4000, 0x473d8000,
+ 0x47298000, 0x5b301e2e, 0x5b300004, 0x6e642000, 0x4225e000, 0xc39a8024, 0xc7380060, 0xc6b81c18,
+ 0x99005fa8, 0xdb9800f8, 0xdbd800f9, 0x00000000, 0xc2000000, 0xdf600038, 0x5e200080, 0x84000352,
+ 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc000490e, 0xca0000f8, 0xc00049a0,
+ 0xca8000f8, 0xc000492a, 0xca4000f8, 0xc000496a, 0xcb0000f8, 0xc0004956, 0xcac000f8, 0x00000000,
+ 0xc121fffe, 0x5911fe14, 0x14100000, 0x77218000, 0x77258000, 0x77298000, 0x8400029a, 0xc201fffe,
+ 0x77218000, 0x5aec0002, 0x6b2d0010, 0x5ea00000, 0x8400001a, 0x6a2d0000, 0x80000010, 0xc72000f8,
+ 0x62016008, 0xc0004956, 0xcec000f8, 0x6ef4a000, 0x6ed44000, 0x4755a000, 0x476da000, 0x5b745e00,
+ 0x58340000, 0xc9c000f8, 0xc00049a0, 0xca0000f8, 0xc3000000, 0xc5f04018, 0xc2400000, 0xc5e50038,
+ 0x7e412000, 0x76250000, 0xce0000f8, 0xc0004980, 0x40300000, 0xcec000f8, 0xc161fffe, 0x5955fffe,
+ 0x14140000, 0x00000000, 0xc000496a, 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x7e010000, 0x76612000,
+ 0xce4000f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0x6ef4a000, 0x6ed44000, 0x4755a000,
+ 0x476da000, 0x5b745e00, 0x5834000e, 0xc2000000, 0xca0000d8, 0x58340008, 0xc2400000, 0xca420078,
+ 0x5834000c, 0xc2800000, 0xca832010, 0x6e644010, 0x42250000, 0x4229e000, 0xc39a8008, 0x58340008,
+ 0xcb809018, 0x58340008, 0xc2800000, 0xca810010, 0x6ee0a000, 0x6ee44000, 0x46250000, 0x462d0000,
+ 0x5a200008, 0x5a201e08, 0x42290000, 0xc6380060, 0xc6f81c18, 0x99005fa8, 0xdb9800f8, 0xdbd800f9,
+ 0x00000000, 0xc000495a, 0xc84000f8, 0x00000000, 0xc3c00002, 0x787c2000, 0xcc4000f8, 0xc0001a1c,
+ 0xca0000f8, 0xc2400008, 0x6a452000, 0x76250000, 0x84000ec2, 0xc0000a28, 0xc3800000, 0xcb840028,
+ 0xc0000a14, 0xc3400000, 0xcb440028, 0xc0004880, 0xcb0400f8, 0xb7b40072, 0x58041802, 0xcac000f8,
+ 0xa7000078, 0x00000000, 0x00000000, 0xa6c8d598, 0xc1000000, 0xc6d00018, 0xc0004980, 0x40100000,
+ 0xca8000f8, 0x80000070, 0x00000000, 0x00000000, 0x00000000, 0x8000d548, 0x00000000, 0xc2800000,
+ 0xc7282018, 0xc000490e, 0xca4000f8, 0x6be9e000, 0x00000000, 0x767d2000, 0x8400d500, 0x6ea0a000,
+ 0x6e944000, 0x46150000, 0x46290000, 0x5a205e00, 0x5820000c, 0xca0000f8, 0xc0004946, 0xce8000f8,
+ 0xa62203a8, 0x00000000, 0xc2200060, 0xc0004948, 0xce000008, 0xce021038, 0xc240000a, 0xc000494a,
+ 0xce4000f8, 0xc2b60002, 0xc0004964, 0xce837b00, 0x99006278, 0xc00048a0, 0xc88400f8, 0x00000000,
+ 0xc0004946, 0xcbc000f8, 0x00000000, 0x00000000, 0x6ff8a000, 0x6fd44000, 0x4795c000, 0x47bdc000,
+ 0x5bb85e00, 0x99006038, 0xdbd800f8, 0xdb9800f9, 0x00000000, 0x99005d80, 0xc000491c, 0xc1400000,
+ 0xc9420048, 0xc000491c, 0x99006230, 0xc94000f9, 0xc98000f8, 0x00000000, 0x99005fa8, 0xd95800f8,
+ 0xd99800f9, 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x99005c70, 0xdbd800f8,
+ 0xdb9800f9, 0xc7d800f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0x6ff8a000, 0x6fd44000,
+ 0x4795c000, 0x47bdc000, 0x5bb85e00, 0x58380010, 0xca0000f8, 0xc0004874, 0xc80400f8, 0x6c908000,
+ 0x45088000, 0x45088000, 0x40100000, 0xca4000f8, 0xc43400f8, 0x00000000, 0xc74000f8, 0xce0000f8,
+ 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc000490e, 0xca4000f8, 0xc2800002, 0x6abd4000,
+ 0x72692000, 0xce4000f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0x99006720, 0xc0004836,
+ 0xc94000f8, 0xc1800002, 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffe8, 0x00000000, 0x58380000,
+ 0xc90000f8, 0xc00049a0, 0xca0000f8, 0xc2800000, 0xc5290038, 0x72290000, 0xce0000f8, 0xc1220002,
+ 0xd90c00f8, 0xc2000000, 0xc0000a14, 0xca040028, 0xc0000a28, 0xc2500002, 0xce450800, 0x58880002,
+ 0xb6080018, 0xc00048a0, 0xc0800000, 0xcc8400f8, 0x8000d110, 0xc0004946, 0xcbc000f8, 0xc161fffe,
+ 0x5955fffe, 0x14140000, 0x00000000, 0xc000490e, 0xca4000f8, 0xc2800002, 0x6abd4000, 0x72692000,
+ 0xce4000f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0x6ff8a000, 0x6fd44000, 0x4795c000,
+ 0x47bdc000, 0x5bb85e00, 0x58380008, 0xca0000f8, 0x5838000c, 0xca4000f8, 0xc3400000, 0xc6340000,
+ 0xc000494e, 0xcf4000f8, 0xc2800000, 0xc62a0078, 0xc3000000, 0xc6308018, 0x6f304000, 0x43298000,
+ 0xc000493c, 0xcf0000f8, 0xc2c00000, 0xc66c0078, 0xc0004950, 0xcec000f8, 0xc2800000, 0xc66ae020,
+ 0xc0004954, 0xce8000f8, 0x5f740000, 0x840001a0, 0x5e300028, 0x46e12000, 0x8400016a, 0x46e12000,
+ 0x88000132, 0x5e300018, 0x46e12000, 0x8800002a, 0x46e12000, 0x84000042, 0x00000000, 0x800000c0,
+ 0x00000000, 0x990063b8, 0xdbd800f8, 0xdb9800f9, 0xc78000f8, 0xc3400002, 0xc000494e, 0xcf4000f8,
+ 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc000490e, 0xca4000f8, 0xc2800002, 0x6abd4000,
+ 0x7e814000, 0x76692000, 0xce4000f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0xc2200060,
+ 0xc0004948, 0xce021038, 0xc2000000, 0xc000494c, 0xce0000f8, 0x80000080, 0x00000000, 0x990063b8,
+ 0xdbd800f8, 0xdb9800f9, 0xc78000f8, 0x990065b8, 0xdbd800f8, 0xdb9800f9, 0xc78000f8, 0xc2200058,
+ 0xc0004948, 0xce021038, 0xc2000002, 0xc000494c, 0xce0000f8, 0xc2000006, 0xc0001006, 0xce0000f8,
+ 0x5838000a, 0xca4000f8, 0xc2200982, 0x5a203b6e, 0xc0001008, 0xce0000f8, 0xc000100a, 0xce4000f8,
+ 0xc0004954, 0xca8000f8, 0xc200000c, 0xc000494a, 0xce0000f8, 0xc0004948, 0xce800008, 0xc2b60000,
+ 0xc0004964, 0xce8000f8, 0x99006278, 0xc00048a0, 0xc88400f8, 0x00000000, 0xc0004946, 0xcbc000f8,
+ 0xc000494c, 0xca0000f8, 0x6ff8a000, 0x6fd44000, 0x4795c000, 0x47bdc000, 0x5bb85e00, 0x5e200000,
+ 0x840000fa, 0x00000000, 0x99006038, 0xdbd800f8, 0xdb9800f9, 0x00000000, 0x99005d80, 0xc000491c,
+ 0xc1400000, 0xc9420048, 0xc000491c, 0x99006230, 0xc94000f9, 0xc98000f8, 0x00000000, 0x99005fa8,
+ 0xd95800f8, 0xd99800f9, 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x99005c70,
+ 0xdbd800f8, 0xdb9800f9, 0xc7d800f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0xc000493c,
+ 0xca8000f8, 0xc000494e, 0xcac000f8, 0xc3000018, 0xc3400006, 0x5e200000, 0x8400002a, 0xc2800000,
+ 0xc2c00000, 0xc300001e, 0xc3400000, 0xc6ac1078, 0xc72c0418, 0xc76c0810, 0x58380010, 0xca8000f8,
+ 0x58380008, 0xcec000f8, 0xc6280100, 0xc0004874, 0xc80400f8, 0x6c908000, 0x45088000, 0x45088000,
+ 0x40100000, 0xcb0000f8, 0xc43400f8, 0x00000000, 0xc74000f8, 0xce8000f8, 0xc0004952, 0xce8000f8,
+ 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc000494c, 0xca0000f8, 0xc0004950,
+ 0xcac000f8, 0x5e200000, 0x8400006a, 0xdfe800f8, 0x7e814000, 0x5834001a, 0xce8000f8, 0x99006720,
+ 0xc0004834, 0xc94000f8, 0xc1800002, 0x99006720, 0xc0004838, 0xc94000f8, 0xc6d800f8, 0xc1220002,
+ 0xd90c00f8, 0x5e200000, 0x84000040, 0x5838002c, 0xcb0000f8, 0xdfe800f8, 0x00000000, 0x58380014,
+ 0xcf0000f8, 0x80000058, 0xc2a1fffe, 0x5aa9fffe, 0x58380000, 0xc90000f8, 0xc00049a0, 0xcb0000f8,
+ 0xc2c00000, 0xc52d0038, 0x732d8000, 0xcf0000f8, 0x5838000a, 0xce8000f8, 0xc3000000, 0xc0000a14,
+ 0xcb040028, 0xc2d00002, 0xc0000a28, 0xcec50800, 0xc000494e, 0xca8000f8, 0x58880002, 0xb4b00018,
+ 0xc00048a0, 0xc0800000, 0xcc8400f8, 0x5ea80000, 0x8400017a, 0x5e200000, 0x84000168, 0xc000493c,
+ 0xca8000f8, 0x00000000, 0x00000000, 0x5aa80060, 0xce8000f8, 0x990063b8, 0xdbd800f8, 0xdb9800f9,
+ 0xc78000f8, 0x990065b8, 0xdbd800f8, 0xdb9800f9, 0xc78000f8, 0x58380000, 0xcac000f8, 0x00000000,
+ 0xc2000000, 0xc6e04018, 0xc0004952, 0xcac000f8, 0x58380000, 0xca8000f8, 0xc30c0002, 0xc6300018,
+ 0xa6800098, 0x00000000, 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc0001800,
+ 0xca0000f8, 0x00000000, 0x00000000, 0xa60cffea, 0xc6f00500, 0xc6b0c400, 0xcf0000f8, 0x00000000,
+ 0xc121fffe, 0x5911fe14, 0x14100000, 0x8000c758, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x8000c6f0, 0xdcbc00f9, 0x5ffc0000, 0x84000052, 0xc3800002, 0xdb8800f9, 0x5ffc0004, 0x8400bf4a,
+ 0xc3800000, 0xdb8800f9, 0xc3ce0002, 0xc0000800, 0xcfc0e700, 0xc3e1fffe, 0x597dfffe, 0x593dfe14,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0xc000487c, 0xc80400f8, 0x00000000, 0x00000000,
+ 0x40080000, 0xcbc000f8, 0xc43800f8, 0x00000000, 0xc000480e, 0xca0000f8, 0xc0004858, 0xcb4400f8,
+ 0x00000000, 0x00000000, 0x47610000, 0x880000b0, 0x00000000, 0xa7c00048, 0xc0004854, 0xc1000002,
+ 0xcd0400f8, 0xc11c0000, 0xc000082c, 0xcd05ce00, 0x800000d8, 0x00000000, 0xa7d20138, 0x00000000,
+ 0xc7e14040, 0xc2400000, 0xc6246028, 0xc200006a, 0x46250000, 0xc6240030, 0xc0000810, 0xce440030,
+ 0x8000ff70, 0xc2000000, 0xc0000808, 0xca040010, 0xc11c0000, 0xc000082c, 0xcd05ce00, 0x5a200002,
+ 0x5e600010, 0x84000010, 0xc2000000, 0xc0000808, 0xce040010, 0xc3400000, 0x80000028, 0xc1200002,
+ 0xc0000818, 0xcd061000, 0x5b740002, 0xc0004858, 0xcf4400f8, 0x990059c0, 0xc0004848, 0xc94400f8,
+ 0xc1800000, 0xc11c0002, 0xc000082c, 0xcd05ce00, 0x80000600, 0x5b740002, 0xc0004858, 0xcf4400f8,
+ 0xc78000f8, 0xc13c0002, 0xcd03de00, 0xc0004848, 0xc94400f8, 0xc1800000, 0xc000082c, 0xc9840028,
+ 0x59540002, 0xc0004848, 0xcd4400f8, 0x58880002, 0xb4980580, 0x00000000, 0xc0800000, 0x80000568,
+ 0xc000487c, 0xc80400f8, 0x00000000, 0x00000000, 0x40080000, 0xcbc000f8, 0xc42800f8, 0x00000000,
+ 0xa7c00130, 0xc000484c, 0xca0400f8, 0xc2400000, 0xc0001aec, 0xca440018, 0x5a200002, 0xc000484c,
+ 0xce0400f8, 0xb624008a, 0xc68000f8, 0xc13c0002, 0xcd03de00, 0xc0004848, 0xc94400f8, 0xc1800000,
+ 0xc000082c, 0xc9840028, 0x59540002, 0xc0004848, 0xcd4400f8, 0x58880002, 0xb4980470, 0x00000000,
+ 0xc0800000, 0x80000458, 0xc0004854, 0xc1000004, 0xcd0400f8, 0xc0000820, 0xc2000002, 0xce0400f8,
+ 0xc2000000, 0xc000484c, 0xce0400f8, 0xc0004858, 0xce0400f8, 0x8000ff28, 0xc0004854, 0xc1000000,
+ 0xcd0400f8, 0xc11c0000, 0xc000082c, 0xcd05ce00, 0x990059c0, 0xc0004848, 0xc94400f8, 0xc1800000,
+ 0xc1200000, 0xc0000818, 0xcd061000, 0xc11c0002, 0xc000082c, 0xcd05ce00, 0xc2000000, 0xc000484c,
+ 0xce0400f8, 0x80000358, 0xc0001ac0, 0xcb8400f8, 0xc000487c, 0xc80400f8, 0x00000000, 0x00000000,
+ 0x40080000, 0xcbc000f8, 0xc42800f8, 0x00000000, 0x00000000, 0xc68000f8, 0xc13c0000, 0xcd03de00,
+ 0xa780024a, 0x00000000, 0x00000000, 0xa7c0020a, 0x00000000, 0xc0001b00, 0xc2060006, 0xce046308,
+ 0xa7e801c2, 0x00000000, 0xc0004850, 0xca0400f8, 0xc2400000, 0xc0001aec, 0xca448018, 0x5a200002,
+ 0xc0004850, 0xce0400f8, 0xb62400aa, 0x00000000, 0xc68000f8, 0xc13c0002, 0xcd03de00, 0xc0001acc,
+ 0xc2000002, 0xce040000, 0xc0004848, 0xc94400f8, 0xc1800000, 0xc000082c, 0xc9840028, 0x59540002,
+ 0xc0004848, 0xcd4400f8, 0x58880002, 0xb49801c8, 0x00000000, 0xc0800000, 0x800001b0, 0xc0004854,
+ 0xc1000000, 0xcd0400f8, 0xc11c0000, 0xc000082c, 0xcd05ce00, 0x990059c0, 0xc0004848, 0xc94400f8,
+ 0xc1800000, 0xc2000000, 0xc0000820, 0xce0400f8, 0xc1200000, 0xc0000818, 0xcd061000, 0xc11c0002,
+ 0xc000082c, 0xcd05ce00, 0xc0004850, 0xce0400f8, 0xc2000002, 0xc0001acc, 0xce040008, 0x800000e8,
+ 0xc2000002, 0xc0004850, 0xce0400f8, 0x8000fe88, 0xc2000000, 0xc0004850, 0xce0400f8, 0xa7e60032,
+ 0x00000000, 0xc2000002, 0xc0001b00, 0xce040000, 0x8000fe70, 0x00000000, 0xa7860052, 0x00000000,
+ 0xc68000f8, 0xc13c0002, 0xcd03de00, 0xc2020002, 0xc7e2a540, 0xc0001b00, 0xce0400f8, 0x8000fe18,
+ 0xc2040002, 0xc0001b00, 0xce044200, 0x8000fdf8, 0xc2c80002, 0x6ac56000, 0xdacc00f8, 0xc0004854,
+ 0xcb4400f8, 0xc0004848, 0xcb8400f8, 0xc0000838, 0xc3c00000, 0xcbc40028, 0x5ef40004, 0x84000022,
+ 0xc3000000, 0xc0001acc, 0xcf042100, 0x47f98000, 0x8400002a, 0x47f98000, 0x88000030, 0xc1006e8c,
+ 0x8000b380, 0xc0004840, 0xcc8400f8, 0x8000f6b0, 0xc0001ac0, 0xcac400f8, 0xc0004854, 0xcb4400f8,
+ 0xa6c0fbd2, 0x00000000, 0x5ef40000, 0x8400f70a, 0x5ef40002, 0x8400f99a, 0x5ef40004, 0x8400fb9a,
+ 0xc1006ce8, 0x8000b2f8, 0x00000000, 0xc0800000, 0xdf4b0038, 0xc0004900, 0xcb8000f8, 0xc2000000,
+ 0xc000490a, 0xa78000d0, 0xcbc000f8, 0xc1000000, 0xd90000f9, 0xc1000002, 0xd90c00f8, 0x6ff46000,
+ 0x477da000, 0x5b744c80, 0xc2400000, 0x58340004, 0xca400078, 0xc0004900, 0xce000000, 0x5a640002,
+ 0x58340004, 0xc6500078, 0xcd000078, 0xc0004914, 0xca4000f8, 0xc2000002, 0x6a3d0000, 0x72612000,
+ 0xce4000f8, 0xc0000408, 0xce0000f8, 0xa78200d8, 0xc0004908, 0xcbc000f8, 0xc1000000, 0xd90000f9,
+ 0xc1000002, 0xd90c00f8, 0x6ff4a000, 0x6fd44000, 0x4755a000, 0x477da000, 0x5b745e00, 0xc2800000,
+ 0x58340006, 0xca800078, 0xc2000000, 0xc0004900, 0xce002100, 0x5ea80002, 0x58340006, 0xc6900078,
+ 0xcd000078, 0x5a7c0020, 0xc2000002, 0x6a250000, 0xc0000408, 0xce0000f8, 0xdca800f9, 0x5ea80000,
+ 0x8400b168, 0x00000000, 0xa4800230, 0x00000000, 0xc3c00000, 0xc000140e, 0xcbc00018, 0xc3400000,
+ 0xc2400000, 0x6ff86000, 0x47bdc000, 0x5bb84c80, 0x58380008, 0xcb400078, 0x58380006, 0xca400078,
+ 0x5f740002, 0x58380008, 0xc7500078, 0xcd000078, 0xc2000000, 0x58380004, 0xca020078, 0xc3000000,
+ 0x5838000c, 0xcb000020, 0x5a640002, 0x46610000, 0x84000010, 0xc2400000, 0x58380006, 0xc6500078,
+ 0xcd000078, 0xc2000000, 0x5838000a, 0xca020078, 0x5b300002, 0x5838000c, 0xc7100020, 0xcd000020,
+ 0xc2420020, 0x5a200004, 0x46252000, 0x84000010, 0xc2000000, 0x5838000a, 0xc6101078, 0xcd021078,
+ 0xc0004966, 0xca4000f8, 0xc2000002, 0x6a3d0000, 0x72612000, 0xce4000f8, 0x5f740000, 0x84000040,
+ 0xc0004912, 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x7ec16000, 0x762d0000, 0xce0000f8, 0x5f300020,
+ 0x84000040, 0xc0004924, 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x7ec16000, 0x762d0000, 0xce0000f8,
+ 0xa4820070, 0xc2400000, 0xc000140e, 0xca408018, 0xc2000002, 0xc0004900, 0xce000000, 0xc000490a,
+ 0xce4000f8, 0xc1000000, 0xd90000f9, 0xd8400078, 0xc1000004, 0xd90000f9, 0xa4840270, 0x00000000,
+ 0xc3c00000, 0xc000140e, 0xcbc10018, 0xc2800000, 0xc2000000, 0x6ff8a000, 0x6fd44000, 0x4795c000,
+ 0x47bdc000, 0x5bb85e00, 0x5838002e, 0xca800078, 0x58380006, 0xca020078, 0xc3400000, 0x5838002e,
+ 0xcb420078, 0x5aa80002, 0x46a10000, 0x84000010, 0xc2800000, 0x5838002e, 0xc6900078, 0xcd000078,
+ 0x5f740002, 0x5838002e, 0xc7501078, 0xcd021078, 0xc0004968, 0xca4000f8, 0xc2000002, 0x6a3d0000,
+ 0x72612000, 0xce4000f8, 0xc000492a, 0xca8000f8, 0x5e740000, 0x84000040, 0xc0004910, 0xca0000f8,
+ 0xc2c00002, 0x6afd6000, 0x7ec16000, 0x762d0000, 0xce0000f8, 0x6abd4010, 0xa68000ba, 0x00000000,
+ 0x58380032, 0xca0000f8, 0x58000002, 0xca4000f8, 0x5838000c, 0x00000000, 0xce0000f9, 0xce4000f8,
+ 0xc000492a, 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x722d0000, 0xce0000f8, 0xc000492c, 0xca0000f8,
+ 0xc2c00002, 0x6afd6000, 0x722d0000, 0xce0000f8, 0x80000040, 0xc000492c, 0xca0000f8, 0xc2c00002,
+ 0x6afd6000, 0x7ec16000, 0x762d0000, 0xce0000f8, 0xa4880148, 0xc2c00000, 0xc000140e, 0xcac20018,
+ 0xc000490e, 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x7e010000, 0x76612000, 0xce4000f8, 0xc000496a,
+ 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x72612000, 0xce4000f8, 0x6ef0a000, 0x6ed44000, 0x47158000,
+ 0x472d8000, 0x5b305e00, 0x58300000, 0xca0000f8, 0x00000000, 0xc2400002, 0x76612000, 0x84000072,
+ 0x58300000, 0xca4000f8, 0xc2800000, 0x00000000, 0xc6684018, 0xc24c0002, 0xc6a40018, 0xc624c400,
+ 0x58300010, 0xca400500, 0x00000000, 0xc0001800, 0xce4000f8, 0xa4860070, 0xc2400000, 0xc000140e,
+ 0xca418018, 0xc2020002, 0xc0004900, 0xce002100, 0xc0004908, 0xce4000f8, 0xc1000000, 0xd90000f9,
+ 0xd8400078, 0xc1000004, 0xd90000f9, 0xa48c00e8, 0xc2400000, 0xc000140e, 0xca430018, 0x00000000,
+ 0x00000000, 0x5d240002, 0x84000058, 0xc00048c4, 0xca0000f8, 0xc00048c6, 0xc1040002, 0x72110000,
+ 0xce0000f8, 0xc1000002, 0xc00048cc, 0xcd000000, 0x80000060, 0x5d240004, 0x84000050, 0xc00048c8,
+ 0xca0000f8, 0xc00048ca, 0xc1160002, 0x72110000, 0xce0000f8, 0xc1020002, 0xc00048cc, 0xcd002100,
+ 0xc0001408, 0xcc8000f8, 0xc10e0002, 0xd90c00f8, 0x8000ecc8, 0xdfbc00f9, 0xc000496e, 0x990066c8,
+ 0xc94000f8, 0xc7d800f8, 0x00000000, 0xc57000f8, 0x5ef00020, 0x88000148, 0x6f346000, 0x4771a000,
+ 0x5b744c80, 0x58340008, 0xc2400000, 0xca400078, 0x00000000, 0xc2000000, 0x5a640002, 0xce400078,
+ 0x58340004, 0xca000078, 0x00000000, 0x00000000, 0x5e200002, 0xce000078, 0xc0004912, 0xca8000f8,
+ 0xc2400002, 0x6a712000, 0x72a54000, 0xce8000f8, 0x5e200000, 0x84000052, 0xc000480a, 0xca0000f8,
+ 0xc0000408, 0xca8000f8, 0x76250000, 0x00000000, 0x72a14000, 0xce8000f8, 0x80000038, 0xc0004914,
+ 0xca0000f8, 0x7e412000, 0x00000000, 0x76250000, 0xce0000f8, 0x800000d0, 0x6ef4a000, 0x6ed44000,
+ 0x4755a000, 0x476da000, 0x5b745e00, 0x5834002e, 0xc2400000, 0xca420078, 0x00000000, 0xc2000000,
+ 0x5a640002, 0xc6501078, 0xcd021078, 0x58340006, 0xca000078, 0x00000000, 0x00000000, 0x5a200002,
+ 0xce000078, 0xc0004910, 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x72612000, 0xce4000f8, 0xc2000002,
+ 0x6a310000, 0xc000042a, 0xce0000f8, 0xc1040002, 0xd90c00f8, 0x00000000, 0x8000ea38, 0x00000000,
+ 0xc4980928, 0x9d000000, 0xc5580028, 0xc0000838, 0xcd8400f8, 0xc1440200, 0xc1c01600, 0xc55c1070,
+ 0xc000100e, 0x9d000000, 0xcd8000f8, 0xc000100c, 0xcdc000f8, 0xc0004862, 0xc9c000f8, 0x00000000,
+ 0x00000000, 0xd9d800f9, 0xc0005600, 0x401c0000, 0x5dc05800, 0x88000012, 0x5c000200, 0xcd8000f8,
+ 0xc1f0000a, 0x715ca000, 0xdd9800f8, 0xdd9c00f9, 0x41d8e000, 0xc5d40260, 0xc0001010, 0xcd4000f8,
+ 0x6c9c8000, 0x45c8e000, 0x45c8e000, 0x59dc0004, 0xc1601260, 0xc5d40260, 0x9d000000, 0xc0001012,
+ 0xcd4000f8, 0x00000000, 0x00000000, 0xd95800f8, 0x6d586000, 0x4594c000, 0x59984c80, 0xd99800f9,
+ 0x5818000a, 0xc1800000, 0xc9800078, 0xc0005400, 0x6d5ca000, 0x401c0000, 0x40180000, 0xc94000f8,
+ 0x58000002, 0x00000000, 0xc9c000f8, 0xc0004930, 0xcd4000f8, 0xc0004932, 0xcdc000f8, 0x59980004,
+ 0xc1c20020, 0xb59c0018, 0x00000000, 0xc1800000, 0xdd9c00f9, 0x581c000a, 0xcd800078, 0x581c000c,
+ 0xc1800000, 0xc9800020, 0xc1c00002, 0xdd9400f8, 0x69d4e000, 0x5d980002, 0xcd800020, 0xc0004924,
+ 0xc98000f8, 0x00000000, 0x9d000000, 0x00000000, 0x719cc000, 0xcd8000f8, 0xc000492a, 0xc94000f8,
+ 0xc1c00002, 0x69d8e000, 0x7dc0c000, 0x7558a000, 0xcd4000f8, 0xc000492c, 0xc94000f8, 0xdd8000f9,
+ 0x58000032, 0x755ca000, 0x84000090, 0xc94000f9, 0xc98000f8, 0xdd8000f9, 0x5800000c, 0x00000000,
+ 0xcd4000f9, 0xcd8000f8, 0xc000492c, 0xc94000f8, 0xc000492a, 0xc98000f8, 0x715ca000, 0xc000492c,
+ 0xcd4000f8, 0x719cc000, 0xc000492a, 0xcd8000f8, 0x9d000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc0004862, 0xc98000f8, 0x00000000, 0xc1c00200, 0x4194c000, 0x459ce000, 0x88000012, 0xc5d800f8,
+ 0xc0004862, 0xcd8000f8, 0xc0001406, 0xc98000f8, 0xc1c00002, 0x9d000000, 0xc5d80a00, 0xc5581048,
+ 0xcd8000f8, 0xc0004930, 0xc98000f8, 0xc0004932, 0xc9c000f8, 0xc140000e, 0xc5581c18, 0xdd9400f8,
+ 0xc0005600, 0x40140000, 0x5d405800, 0x88000012, 0x5c000200, 0xcd8000f8, 0x58000002, 0x5d405800,
+ 0x88000012, 0x5c000200, 0xcdc000f8, 0xdd5400f8, 0xc1c00000, 0x58140006, 0xc9c20078, 0xc1800000,
+ 0x58140000, 0xc98000d8, 0x6ddc2000, 0xc000491e, 0x41d8e000, 0xcdc000f8, 0xdd9800f8, 0xc1c00022,
+ 0xc5d80d70, 0xdd9400f9, 0xc5581c18, 0xc000491c, 0xcd8000f8, 0xdd5400f8, 0xc1c00000, 0x58140006,
+ 0xc9c20078, 0xc1800000, 0x58140004, 0xc9820078, 0x00000000, 0x59dc0002, 0x45d8c000, 0x84000010,
+ 0xc1c00000, 0x9d000000, 0x58140006, 0xc5d81078, 0xcd821078, 0xc0004860, 0xc94000f8, 0xc1820080,
+ 0xc1d00002, 0x58146b00, 0xd58000f8, 0x58000002, 0xd58000f9, 0x59540004, 0xb5580018, 0xc0004860,
+ 0xc1400000, 0xcd4000f8, 0xdd9800f9, 0x9d000000, 0xdd9400f8, 0xc0001404, 0xcdc10800, 0xc1c00000,
+ 0xc1800200, 0x5d980004, 0xdf5d0048, 0x459ca000, 0x8800fff2, 0xdd8000f9, 0x5800000c, 0x00000000,
+ 0xc94000f9, 0xc98000f8, 0xc1c00002, 0xc5d43f00, 0xc5d81e00, 0xc0004862, 0xc9c000f8, 0x00000000,
+ 0x00000000, 0x581c5600, 0x5dc05800, 0x88000012, 0x5c000200, 0xcd4000f8, 0x58000002, 0x5dc05800,
+ 0x88000012, 0x5c000200, 0xcd8000f8, 0xc0004862, 0xc9c000f8, 0x00000000, 0xc15004c0, 0xc5d40060,
+ 0xdd9c00f8, 0xc5d41c18, 0xc1c00000, 0xdd8000f9, 0x58000030, 0xc9c00078, 0xdd8000f9, 0x58000002,
+ 0xc98000f8, 0x6ddc2000, 0xc000491c, 0x41d8e000, 0xcd4000f9, 0xcdc000f8, 0xdd9400f9, 0xc1c00000,
+ 0x58140030, 0xc9c00078, 0xc1800000, 0x58140006, 0xc9820078, 0x00000000, 0x59dc0002, 0x45d8c000,
+ 0x84000010, 0xc1c00000, 0x9d000000, 0x58140030, 0xc5d80078, 0xcd800078, 0xc1c00000, 0xdf5c0038,
+ 0x5ddc0080, 0x8400ffea, 0x00000000, 0x9d000000, 0x00000000, 0x00000000, 0x00000000, 0xc160fffe,
+ 0xc0000a10, 0xc9440060, 0xc1a0fffe, 0x59981e08, 0xc000100c, 0xcd4000f8, 0xc000100e, 0xcd8000f8,
+ 0xc0004964, 0xc98000f8, 0x00000000, 0xc170000a, 0x7158a000, 0x6c988000, 0x4588c000, 0x4588c000,
+ 0x59980004, 0xc5940270, 0xc0001010, 0xcd4000f8, 0xc0004946, 0xc94000f8, 0x00000000, 0x00000000,
+ 0x6d58a000, 0x6d5c4000, 0x459cc000, 0x4594c000, 0xc000494a, 0xc94000f8, 0xc0004948, 0xc9c000f8,
+ 0x4194c000, 0xc1400012, 0xc55c1818, 0x9d000000, 0xc59c0268, 0xc0001012, 0xcdc000f8, 0xc1400000,
+ 0x58000012, 0xc9410038, 0xc0004950, 0xc9c000f8, 0xc55800f8, 0xc5940838, 0xc5581078, 0xd99400f8,
+ 0xc000493c, 0xc94000f8, 0xc0004954, 0xc98000f8, 0x59dc00a8, 0x45d4e000, 0x41d8e000, 0x5d5c0030,
+ 0x88000010, 0xc1c00030, 0xc1800000, 0xc5d84028, 0xc1400000, 0xc5d40008, 0x5dd40002, 0x84000072,
+ 0x5dd40004, 0x8400009a, 0x5dd40006, 0x840000c2, 0x5dd80026, 0x840000ea, 0xdd5400f8, 0xdd8000f9,
+ 0x58000008, 0x40180000, 0xcd4000f8, 0x59980002, 0x8000ffc0, 0xdd5400f8, 0xdd8000f9, 0x58000008,
+ 0x40180000, 0xcd4000b8, 0x59980002, 0x8000ff88, 0xdd5400f8, 0xdd8000f9, 0x58000008, 0x40180000,
+ 0xcd400078, 0x59980002, 0x8000ff50, 0xdd5400f8, 0xdd8000f9, 0x58000008, 0x40180000, 0xcd400038,
+ 0x59980002, 0x8000ff18, 0x00000000, 0x9d000000, 0x00000000, 0x00000000, 0x00000000, 0x58000012,
+ 0xc94000f8, 0xc0004954, 0xc9c000f8, 0xc0004950, 0xc9400078, 0xdd8000f9, 0x58000028, 0x5d9c0000,
+ 0x84000052, 0x5d9c0002, 0x84000052, 0x5d9c0004, 0x8400006a, 0xc55b0038, 0xc55c08b8, 0xcd800039,
+ 0xcdc108b8, 0x80000060, 0xcd4000f8, 0x80000050, 0xc55900b8, 0xc55c1838, 0xcd8000b9, 0xcdc31838,
+ 0x80000028, 0xc55a0078, 0xc55c1078, 0xcd800079, 0xcdc21078, 0x9d000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x59540002, 0x6994e018, 0x61c0c008, 0x4194a000, 0x5d940040, 0x88000012, 0xc59400f8,
+ 0x9d000000, 0xcd4000f8, 0x00000000, 0x00000000, 0x9d000000, 0x4158a000, 0xcd4000f8, 0x00000000,
+};
+
+static unsigned int firmware_binary_data[] = {
+};
+
+
+#endif // IFXMIPS_ATM_FW_AMAZON_SE_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_ar9.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_ar9.h
new file mode 100644
index 0000000000..5ee6d23bb1
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_ar9.h
@@ -0,0 +1,439 @@
+#ifndef IFXMIPS_ATM_FW_AR9_H
+#define IFXMIPS_ATM_FW_AR9_H
+
+
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_fw_ar9.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 22 OCT 2007
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (PP32 Firmware)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 22 OCT 2007 Xu Liang Initiate Version, v00.01
+*******************************************************************************/
+
+
+#define VER_IN_FIRMWARE 1
+
+#define ATM_FW_VER_MAJOR 0
+#define ATM_FW_VER_MINOR 16
+
+
+static unsigned int ar9_fw_bin[] = {
+ 0x800004b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000ffe0, 0x00000000, 0x00000000, 0x00000000,
+ 0xc1000002, 0xd90c00f8, 0xc2000002, 0xda0800f9, 0x80004980, 0xc2000000, 0xda0800f9, 0x80003fe8,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80003fa0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80005178, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80003ea0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc0400000, 0xc0004840, 0xc88400f8, 0x80004640, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc0400002, 0xc0004840, 0xc88400f8, 0x800045c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc3c00004, 0xdbc800f9, 0xc10c0002, 0xd90c00f8, 0x8000fee0, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc10e0002, 0xd90c00f8, 0xc0004808, 0xc84000f8, 0x800045f0, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc3e1fffe, 0x597dfffe, 0x593dfe14, 0x900004d9, 0x00000000, 0x00000000, 0x00000000, 0x90cc0481,
+ 0x00000000, 0x00000000, 0x00000000, 0xc3c00000, 0xdbc800f9, 0xc1400008, 0xc1900000, 0x71588000,
+ 0x14100100, 0xc140000a, 0xc1900002, 0x71588000, 0x14100100, 0xc140000c, 0xc1900004, 0x71588000,
+ 0x14100100, 0xc1400004, 0xc1900006, 0x71588000, 0x14100100, 0xc1400006, 0xc1900008, 0x71588000,
+ 0x14100100, 0xc140000e, 0xc190000a, 0x71588000, 0x14100100, 0xc1400000, 0xc190000c, 0x71588000,
+ 0x14100100, 0xc1400002, 0xc190000e, 0x71588000, 0x14100100, 0xc0400000, 0xc11c0000, 0xc000082c,
+ 0xcd05ce00, 0xc11c0002, 0xc000082c, 0xcd05ce00, 0xc0400002, 0xc11c0000, 0xc000082c, 0xcd05ce00,
+ 0xc11c0002, 0xc000082c, 0xcd05ce00, 0xc0000824, 0x00000000, 0xcbc000f9, 0xcb8000f9, 0xcb4000f9,
+ 0xcb0000f8, 0xc0004878, 0x5bfc4000, 0xcfc000f9, 0x5bb84000, 0xcf8000f9, 0x5b744000, 0xcf4000f9,
+ 0x5b304000, 0xcf0000f8, 0xc0000a10, 0x00000000, 0xcbc000f9, 0xcb8000f8, 0xc0004874, 0x5bfc4000,
+ 0xcfc000f9, 0x5bb84000, 0xcf8000f8, 0xc30001fe, 0xc000140a, 0xcf0000f8, 0xc3000000, 0x7f018000,
+ 0xc000042e, 0xcf0000f8, 0xc000040e, 0xcf0000f8, 0xc3c1fffe, 0xc000490e, 0xcfc00078, 0xc000492c,
+ 0xcfc00078, 0xc0004924, 0xcfc00038, 0xc0004912, 0xcfc00038, 0xc0004966, 0xcfc00038, 0xc0004968,
+ 0xcfc00078, 0xc000496a, 0xcfc00078, 0xc3c1fffe, 0xc00049a0, 0xcfc000f8, 0xc3c00000, 0xc2800020,
+ 0xc3000000, 0x7f018000, 0x6ff88000, 0x6fd44000, 0x4395c000, 0x5bb84a00, 0x5838000a, 0xcf0000f8,
+ 0x5bfc0002, 0xb7e8ffc8, 0x00000000, 0xc3c00000, 0xc2800010, 0x6ff86000, 0x47bdc000, 0x5bb84c80,
+ 0xc3400000, 0x58380004, 0xcb420078, 0x00000000, 0x58380008, 0xcf400078, 0x5bfc0002, 0xb7e8ffb0,
+ 0x00000000, 0xc3c00000, 0xc2800020, 0xc348001e, 0xc3000000, 0x7f018000, 0x6ff8a000, 0x6fd44000,
+ 0x4795c000, 0x47bdc000, 0x5bb87000, 0x58380008, 0xcf408418, 0x5838000a, 0xcf0000f8, 0x5bfc0002,
+ 0xb7e8ffb0, 0x00000000, 0x00000000, 0xc3e0a242, 0x5bfc0020, 0xc0004002, 0xcfc000f8, 0x00000000,
+ 0xc121fffe, 0x5911fe14, 0x14100000, 0x80000530, 0x00000000, 0x80002130, 0x00000000, 0x8000ffe0,
+ 0xc0004958, 0xc84000f8, 0x00000000, 0xc3c00002, 0x787c2000, 0xcc4000f8, 0xc0004848, 0xcb8400f8,
+ 0xc000495c, 0xcac400f8, 0xc0004844, 0xc88400f8, 0x47ad0000, 0x8400ff82, 0xc000487c, 0xc80400f8,
+ 0x00000000, 0x00000000, 0x40080000, 0xca0000f8, 0xc0001624, 0xcb0400f8, 0xa63c007a, 0x00000000,
+ 0x00000000, 0xa71eff22, 0x00000000, 0xc0000824, 0xca8400f8, 0x6ca08000, 0x6ca42000, 0x46250000,
+ 0x42290000, 0xc35e0002, 0xc6340060, 0xc0001624, 0xcf440078, 0xc2000000, 0xc161fffe, 0x5955fffe,
+ 0x14140000, 0x00000000, 0xc0004844, 0xc88400f8, 0xc000082c, 0xca040038, 0x00000000, 0x00000000,
+ 0x58880002, 0xb6080018, 0x00000000, 0xc0800000, 0xc0004844, 0xcc840038, 0x5aec0002, 0xc000495c,
+ 0xcec400f8, 0x5e6c0006, 0x84000060, 0xc0004848, 0xcb8400f8, 0xc0000838, 0xc2500002, 0xce450800,
+ 0x5fb80002, 0xc0004848, 0xcf8400f8, 0x5eec0002, 0xc000495c, 0xcec400f8, 0x00000000, 0xc121fffe,
+ 0x5911fe14, 0x14100000, 0x8000fd98, 0xc000495a, 0xc84000f8, 0x00000000, 0xc3c00002, 0x787c2000,
+ 0xcc4000f8, 0xc0004960, 0xcac400f8, 0x00000000, 0x00000000, 0x5eec0000, 0x8400010a, 0x00000000,
+ 0xb6fc0050, 0xc0001600, 0xca0400f8, 0x00000000, 0x00000000, 0xa61e00d2, 0x6fe90000, 0xc0000a28,
+ 0xce850800, 0xc2c00000, 0xc2800004, 0xb6e800a0, 0xc0001604, 0xca8400f8, 0xc0004960, 0xcec400f8,
+ 0xa69efcc2, 0x00000000, 0x6fe90000, 0xc0000a28, 0xce850800, 0xc2c00002, 0xc0001600, 0xca0400f8,
+ 0x00000000, 0x00000000, 0xa61e002a, 0x6fe90000, 0xc0000a28, 0xce850800, 0xc2c00000, 0xc0001604,
+ 0xca8400f8, 0xc0004960, 0xcec400f8, 0xa69efc2a, 0xc2400000, 0xc0000a14, 0xca440028, 0x00000000,
+ 0x00000000, 0x466d2000, 0xa4400020, 0xc2800000, 0xdfeb0029, 0x80000010, 0xdfea0029, 0xb668fba2,
+ 0x00000000, 0xc00048a0, 0xcb0400f8, 0xc0000a10, 0xca8400f8, 0x6f208000, 0x6f242000, 0x46250000,
+ 0x42a10000, 0xc2400000, 0xc0000a14, 0xca440028, 0xc35e0002, 0xc6340060, 0xc0001604, 0xcf440078,
+ 0x5b300002, 0xb6700018, 0x5aec0002, 0xc3000000, 0xc00048a0, 0xcf0400f8, 0xc0004960, 0xcec400f8,
+ 0x8000fad8, 0xc0004918, 0xd28000f8, 0xc2000000, 0xdf600038, 0x5e600080, 0x84000272, 0x00000000,
+ 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc000480a, 0xca0000f8, 0xc0004912, 0xca4000f8,
+ 0xc0004924, 0xca8000f8, 0xc0004966, 0xcac000f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000,
+ 0x76250000, 0x76290000, 0x762d0000, 0x840001ca, 0xc0004918, 0xca4000f8, 0xc28001fe, 0x76290000,
+ 0x5a640002, 0x6a254010, 0x5ee80000, 0x8400001a, 0x6aa54000, 0x80000010, 0xc62800f8, 0x62818008,
+ 0xc0004918, 0xcf0000f8, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc0004966, 0xca4000f8,
+ 0xc2000002, 0x6a310000, 0x7e010000, 0x76612000, 0xce4000f8, 0x00000000, 0xc121fffe, 0x5911fe14,
+ 0x14100000, 0x6f346000, 0x4771a000, 0x5b744c80, 0xc2800000, 0x58340006, 0xca800078, 0xc2c00000,
+ 0x58340000, 0xcac000d8, 0xc2400000, 0x5834000a, 0xca420078, 0x6ea82000, 0x42e9e000, 0x6f2ca000,
+ 0x42e56000, 0x5aec2e00, 0xc3990040, 0xc7381c18, 0xc6f80060, 0x99005b78, 0xdb9800f8, 0xdbd800f9,
+ 0x00000000, 0xdea000f8, 0x46310000, 0x8400fd80, 0xc0004958, 0xc84000f8, 0x00000000, 0xc3c00002,
+ 0x787c2000, 0xcc4000f8, 0xc0004848, 0xcb8400f8, 0xc0004844, 0xc88400f8, 0x5fb80000, 0x8400f7f2,
+ 0xc0001a1c, 0xca0000f8, 0xc2400002, 0x6a452000, 0x76250000, 0x8400f7c2, 0xc000487c, 0xc80400f8,
+ 0x00000000, 0x00000000, 0x40080000, 0xca0000f8, 0xc42400f8, 0x00000000, 0xa63c17da, 0x00000000,
+ 0xc0004878, 0xc80400f8, 0x6c908000, 0x45088000, 0x45088000, 0x40100000, 0xca0000f8, 0xc42400f8,
+ 0x00000000, 0xc0004934, 0xce0000f8, 0xc2800002, 0xc4681c08, 0xc62821d0, 0xc2600010, 0x5a650060,
+ 0xc0004800, 0xcb4000f8, 0xc2200400, 0x5a200020, 0xc7601040, 0xc0001220, 0xce8000f8, 0xc0001200,
+ 0xce4000f8, 0xc0001202, 0xce0000f8, 0xc0001240, 0xcb4000f8, 0x00000000, 0x00000000, 0xa754ffe0,
+ 0xc2000000, 0xc7600040, 0xa7520042, 0x00000000, 0x00000000, 0x990062f0, 0xc0004822, 0xc94000f8,
+ 0xc1800002, 0x80001680, 0x582040a0, 0xc2000000, 0xca000018, 0xc2400000, 0xca414000, 0xc2800000,
+ 0xca812000, 0xc2c00000, 0xcac20018, 0xc0004938, 0xce0000f8, 0xc0004920, 0xce4000f8, 0xc0004916,
+ 0xce8000f8, 0xc0004922, 0xcec000f8, 0xa6400540, 0x00000000, 0xc0004938, 0xcbc000f8, 0x00000000,
+ 0xc3800000, 0x6ff48000, 0x6fd44000, 0x4355a000, 0x5b744a00, 0x58340000, 0xcb802010, 0x00000000,
+ 0xc2000000, 0x6fb46000, 0x4779a000, 0x5b744c80, 0x5834000c, 0xca000020, 0xc000491a, 0xcf8000f8,
+ 0x5e200000, 0x8400046a, 0xc2000000, 0xdf610048, 0x5e6001e8, 0x8800ffe8, 0xc2000002, 0xc2400466,
+ 0xc2a00000, 0x5aa80000, 0xc0001006, 0xce0000f8, 0xc0001008, 0xce4000f8, 0xc000100a, 0xce8000f8,
+ 0x990055b8, 0xc1a0fffe, 0xc0000824, 0xc9840060, 0xc0004934, 0xca4000f8, 0xc2000000, 0xc2800002,
+ 0x990055f8, 0xda9800f8, 0xc61400f8, 0xc65800f8, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000,
+ 0x990056e0, 0xc000491a, 0xc94000f8, 0x00000000, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000,
+ 0xc0004922, 0xca001118, 0xc3c00000, 0xc3800000, 0xc0004930, 0xce023118, 0xc0004932, 0xcbc000d8,
+ 0xc2800000, 0xc000491e, 0xcfc000f8, 0xc0004862, 0xca800060, 0xc3a0001a, 0x5bb94000, 0xc6b80060,
+ 0xc000491c, 0xcf8000f8, 0x99005950, 0xc000491c, 0xc1400000, 0xc9420048, 0x00000000, 0x00000000,
+ 0x00000000, 0xa8e2ffe8, 0xc2000000, 0xc1220002, 0xd90c00f8, 0xdf600038, 0x5e600080, 0x8400fff2,
+ 0xc000491c, 0xca0000f8, 0xc000491e, 0xca4000f8, 0x00000000, 0x00000000, 0x99005b78, 0xda1800f8,
+ 0xda5800f9, 0x00000000, 0xc2000000, 0xdf610048, 0x5e6001fe, 0x8800ffe8, 0xc0004916, 0xca8000f8,
+ 0xc2c00000, 0xdfec0048, 0xc2400000, 0x466d2000, 0x8400004a, 0x5ea80000, 0x8400003a, 0xc2600002,
+ 0x990062f0, 0xc000482e, 0xc94000f8, 0xc1800002, 0x80000030, 0xc2600000, 0x990062f0, 0xc000482c,
+ 0xc94000f8, 0xc1800002, 0xc2000068, 0xc6240078, 0xc0004930, 0xce400080, 0xc000491a, 0xc98000f8,
+ 0xc0004862, 0xc94000f8, 0x6d9c6000, 0x45d8e000, 0x59dc4c80, 0x990059d8, 0xd95800f8, 0xd99800f9,
+ 0xd9d400f8, 0x99005950, 0xc000491c, 0xc1400000, 0xc9420048, 0xc2000000, 0xdf600038, 0x5e600080,
+ 0x8400ffea, 0x00000000, 0xc000491c, 0xca0000f8, 0xc000491e, 0xca4000f8, 0x00000000, 0x00000000,
+ 0x99005b78, 0xda1800f8, 0xda5800f9, 0x00000000, 0x800010e8, 0x00000000, 0x990062f0, 0xc000482a,
+ 0xc94000f8, 0xc1800002, 0x800010b8, 0xc0004938, 0xcbc000f8, 0x00000000, 0x00000000, 0x6ff88000,
+ 0x6fd44000, 0x4395c000, 0x5bb84a00, 0x58380008, 0xca0000f8, 0x00000000, 0x00000000, 0xa6000382,
+ 0x00000000, 0xc0004938, 0xcbc000f8, 0xc3000000, 0x00000000, 0x6ff88000, 0x6fd44000, 0x4395c000,
+ 0x5bb84a00, 0x58380000, 0xcb002010, 0xc2000000, 0x58380008, 0xca020078, 0x5838000c, 0xcac000f8,
+ 0x5838000e, 0xca4000f8, 0xc000491a, 0xcf0000f8, 0xc0004930, 0xcec000f8, 0xc000493c, 0xce0000f8,
+ 0xc0004932, 0xce4000f8, 0x5e200000, 0x84000120, 0xc2800000, 0xa6fe00ba, 0x6f206000, 0x46310000,
+ 0x5a204c80, 0x5820000c, 0xca800020, 0x00000000, 0x00000000, 0x5ea80000, 0x840001f2, 0x00000000,
+ 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x990056e0, 0xc000491a, 0xc94000f8, 0x00000000,
+ 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0xc0004930, 0xcac000f8, 0xc0004932, 0xca4000f8,
+ 0xc7ec1118, 0xc0004930, 0xcec000f8, 0x5838000c, 0xcec000f8, 0x58000002, 0xce4000f8, 0xc0004934,
+ 0xca0000f8, 0xc2400002, 0x6e642000, 0x6e642000, 0x76612000, 0x8400002a, 0xc2400002, 0x6e684000,
+ 0x58380008, 0xce804200, 0xa6000020, 0x6e682000, 0x58380008, 0xce802100, 0xc2400002, 0x6e642000,
+ 0x76612000, 0x840000ea, 0x58380008, 0xca0000f8, 0xc2800000, 0xc2400000, 0xa60200c0, 0xdba800f8,
+ 0x6f386000, 0x47b1c000, 0x5bb84c80, 0x58380004, 0xca400078, 0x58380002, 0xca800078, 0x00000000,
+ 0xdeb800f8, 0x46a54000, 0x88000060, 0x00000000, 0xc0004824, 0xca0000f8, 0xc2400002, 0x6e640000,
+ 0x5a200002, 0xce0000f8, 0x58380008, 0xce400000, 0x80000018, 0x00000000, 0x80000048, 0xc0004934,
+ 0xca0000f8, 0x00000000, 0x00000000, 0xa6020c6a, 0x00000000, 0x00000000, 0x80000c98, 0xc2800000,
+ 0xc2000200, 0xc240001a, 0xdf690048, 0x46294000, 0x46a54000, 0x8800ffd2, 0xc2000006, 0xc2600982,
+ 0x5a643b6e, 0x5838000a, 0xca8000f8, 0xc0001006, 0xce0000f8, 0xc0001008, 0xce4000f8, 0xc000100a,
+ 0xce8000f8, 0x990055b8, 0xc1a0fffe, 0xc0000824, 0xc9840060, 0xc2000000, 0xc0004930, 0xca02e008,
+ 0x58380026, 0xca4000f8, 0x00000000, 0xc2800000, 0x990055f8, 0xda9800f8, 0xc61400f8, 0xc65800f8,
+ 0xc0004934, 0xca0000f8, 0x00000000, 0x00000000, 0xa6020022, 0x00000000, 0x00000000, 0x80000318,
+ 0xc0004938, 0xcbc000f8, 0xc0004878, 0xc80400f8, 0x6c908000, 0x45088000, 0x45088000, 0x40100000,
+ 0xca0000f8, 0xc42400f8, 0x00000000, 0x58240018, 0xca0000f8, 0x6ff88000, 0x6fd44000, 0x4395c000,
+ 0x5bb84a00, 0xc3000000, 0xc3400002, 0xc2c00000, 0xc62c0078, 0xc6270038, 0xc0004940, 0xce400038,
+ 0xc6260038, 0xc0004942, 0xce400038, 0xc000493c, 0xca0000f8, 0x5eec0000, 0x8400018a, 0x5a6c0010,
+ 0x46254000, 0x88000190, 0x5a600052, 0x46e54000, 0x88000178, 0x58380006, 0xca8000f8, 0xc0004940,
+ 0xca0000f8, 0xc2400000, 0xc6a70038, 0x7e412000, 0x76612000, 0xc2000000, 0xc6a10038, 0x46250000,
+ 0x84000138, 0xc0004942, 0xca0000f8, 0xc2400000, 0xc6a60038, 0x7e412000, 0x76612000, 0xc2000000,
+ 0xc6a00038, 0x58380002, 0xca8000f8, 0x46250000, 0x840000e8, 0xc2400000, 0xc6a60078, 0x466d0000,
+ 0x880000da, 0xc2400000, 0xc6a40078, 0x58380008, 0xca8000f8, 0x46e50000, 0x880000ba, 0x00000000,
+ 0xa6820018, 0x00000000, 0xc7700b00, 0xa6840098, 0x00000000, 0xc7700a00, 0x80000080, 0xc7700200,
+ 0xc000493c, 0xcac000f8, 0x80000060, 0xc7700300, 0xc000493c, 0xcac000f8, 0x80000040, 0xc7700900,
+ 0x80000030, 0xc7700800, 0x80000020, 0xc7700700, 0x80000010, 0xc7700500, 0xc0004944, 0xcf0000f8,
+ 0xc000493e, 0xcec000f8, 0xc0004938, 0xca4000f8, 0xc000493c, 0xcb8000f8, 0xc000493e, 0xcb4000f8,
+ 0xc3000000, 0x6e608000, 0x6e544000, 0x42150000, 0x5a204a00, 0x5aa00008, 0x58200004, 0xcb000078,
+ 0xc0004934, 0xca0000f8, 0xc2400000, 0xc0004930, 0xca42e008, 0xc3c00018, 0xa6020098, 0x00000000,
+ 0x43656000, 0x47ad0000, 0x88000050, 0x46f96000, 0x6ee04010, 0x5be00004, 0xc2000000, 0xc6e00008,
+ 0x5e200000, 0x84000042, 0x5bfc0002, 0x80000030, 0xc3c00004, 0x5a2c0008, 0x47a10000, 0x88000012,
+ 0x5fb80008, 0x6fe04000, 0x42390000, 0x47212000, 0x88000068, 0xc2400000, 0xc0004930, 0xca42e008,
+ 0xc2060002, 0xc68000f8, 0xce006300, 0x6fe04000, 0x4721c000, 0x5f700010, 0x4765a000, 0xc2000000,
+ 0xc6340008, 0xc25a000a, 0xc000491a, 0xca401c18, 0xc2800000, 0xc0004932, 0xca8000d8, 0xc0004862,
+ 0xca400060, 0x6fa04010, 0x42290000, 0xc000491e, 0xce0000f8, 0xc7e41048, 0xc000491c, 0xce4000f8,
+ 0x6fe04000, 0x43a1c000, 0xc000493c, 0xcf8000f8, 0xc000493e, 0xcf4000f8, 0xc000493a, 0xcfc000f8,
+ 0x80000008, 0x00000000, 0x00000000, 0x00000000, 0xc2000000, 0xdce000f8, 0xa622ffd8, 0xc1220002,
+ 0xd90c00f8, 0xc0004938, 0xcbc000f8, 0xc0004944, 0xcb4000f8, 0xc0004862, 0xcb0000f8, 0xc0004934,
+ 0xca0000f8, 0x6ff88000, 0x6fd44000, 0x4395c000, 0x5bb84a00, 0xa6020268, 0xc2400000, 0x58380008,
+ 0xca406000, 0xdfe800f8, 0xc2218e08, 0x5a21baf6, 0x46a14000, 0x84000022, 0xc2080002, 0x7361a000,
+ 0x80000058, 0x5e640000, 0x84000022, 0xc20c0002, 0x7361a000, 0x80000030, 0xc2000000, 0xc760e710,
+ 0xc7604218, 0x5e200000, 0x84000272, 0xc2200002, 0xc0004930, 0xce021000, 0x990062f0, 0xc0004828,
+ 0xc94000f8, 0xc1800002, 0x58380000, 0xca0000f8, 0x00000000, 0x00000000, 0xa6000132, 0xc0004940,
+ 0xca8000f8, 0xc0004942, 0xca4000f8, 0xc7600078, 0xc6a01838, 0xc6601038, 0xc000493a, 0xca4000f8,
+ 0xc0004934, 0xca8000f8, 0xc0007800, 0x40300000, 0x40240000, 0x5c000004, 0x5ec07a00, 0x88000012,
+ 0x5c000200, 0xce0000f8, 0x58000002, 0x5ec07a00, 0x88000012, 0x5c000200, 0xce8000f8, 0xc000493e,
+ 0xca0000f8, 0xc2400000, 0x5838000c, 0xce4000f8, 0x990062f0, 0xc0004830, 0xc94000f8, 0xc61800f8,
+ 0xc0004930, 0xc6100078, 0xcd000078, 0x800000a8, 0xc2400002, 0x58380008, 0xce400000, 0xc0004944,
+ 0xcf4000f8, 0x80000278, 0xc000493c, 0xca4000f8, 0xdfe800f8, 0x5a300018, 0xc0007800, 0x40200000,
+ 0xca0000f8, 0x58380008, 0xc6501078, 0xcd021078, 0x5838000a, 0xce8000f8, 0x58380026, 0xce0000f8,
+ 0xc0004944, 0xcf4000f8, 0x99005950, 0xc000491c, 0xc1400000, 0xc9420048, 0x80000038, 0x00000000,
+ 0x990062f0, 0xc0004826, 0xc94000f8, 0xc1800002, 0x8000fdd8, 0xc2000000, 0xc2400080, 0xdf600038,
+ 0xb624ffea, 0xc000491c, 0xca4000f8, 0xc000491e, 0xca8000f8, 0x99005b78, 0xda5800f8, 0xda9800f9,
+ 0x00000000, 0xc0004934, 0xca0000f8, 0x00000000, 0xc2800000, 0xa6020160, 0xc2400004, 0xc2000200,
+ 0xdf690048, 0x46294000, 0x46a54000, 0x8800ffda, 0x00000000, 0xc000491a, 0xc98000f8, 0xc0004862,
+ 0xc94000f8, 0x6d9c6000, 0x45d8e000, 0x59dc4c80, 0x990059d8, 0xd95800f8, 0xd99800f9, 0xd9d400f8,
+ 0x99005950, 0xc000491c, 0xc1400000, 0xc9420048, 0xc2000000, 0xc2400080, 0xdf600038, 0xb624ffea,
+ 0xc000491c, 0xca4000f8, 0xc000491e, 0xca8000f8, 0x99005b78, 0xda5800f8, 0xda9800f9, 0x00000000,
+ 0x58380008, 0xca4000f8, 0xc2000000, 0xce000018, 0xc2a1fffe, 0x5aa9fffe, 0xce021078, 0x5838000a,
+ 0xce8000f8, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc0000838, 0xc2500002, 0xce450800,
+ 0xc0004848, 0xcb8400f8, 0xc2000000, 0xc000082c, 0xca040028, 0x5fb80002, 0xc0004848, 0xcf8400f8,
+ 0x58880002, 0xb6080018, 0x00000000, 0xc0800000, 0xc0004844, 0xcc8400f8, 0x00000000, 0xc121fffe,
+ 0x5911fe14, 0x14100000, 0x8000ded8, 0xc2000000, 0xdf600038, 0x5e200080, 0x8400026a, 0x00000000,
+ 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc000480c, 0xca0000f8, 0xc0004910, 0xca4000f8,
+ 0xc000492c, 0xca8000f8, 0xc0004968, 0xcac000f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000,
+ 0x76250000, 0x76290000, 0x76e16000, 0x840001c2, 0xc0004926, 0xca4000f8, 0xc201fffe, 0x76e16000,
+ 0x5a640002, 0x6ae50010, 0x5f200000, 0x8400001a, 0x6a250000, 0x80000010, 0xc6e000f8, 0x62014008,
+ 0xc0004926, 0xce8000f8, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc0004968, 0xca4000f8,
+ 0xc2000002, 0x6a290000, 0x7e010000, 0x76612000, 0xce4000f8, 0x00000000, 0xc121fffe, 0x5911fe14,
+ 0x14100000, 0x6eb4a000, 0x6e944000, 0x4755a000, 0x4769a000, 0x5b747000, 0x58340002, 0xc2000000,
+ 0xca0000d8, 0x5834002e, 0xc2400000, 0xca400078, 0x6eb0a000, 0x6ebc4000, 0x473d8000, 0x47298000,
+ 0x5b30302e, 0x5b300004, 0x6e642000, 0x4225e000, 0xc39a8024, 0xc7380060, 0xc6b81c18, 0x99005b78,
+ 0xdb9800f8, 0xdbd800f9, 0x00000000, 0xc2000000, 0xdf600038, 0x5e200080, 0x84000352, 0x00000000,
+ 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc000490e, 0xca0000f8, 0xc00049a0, 0xca8000f8,
+ 0xc000492a, 0xca4000f8, 0xc000496a, 0xcb0000f8, 0xc0004956, 0xcac000f8, 0x00000000, 0xc121fffe,
+ 0x5911fe14, 0x14100000, 0x77218000, 0x77258000, 0x77298000, 0x8400029a, 0xc201fffe, 0x77218000,
+ 0x5aec0002, 0x6b2d0010, 0x5ea00000, 0x8400001a, 0x6a2d0000, 0x80000010, 0xc72000f8, 0x62016008,
+ 0xc0004956, 0xcec000f8, 0x6ef4a000, 0x6ed44000, 0x4755a000, 0x476da000, 0x5b747000, 0x58340000,
+ 0xc9c000f8, 0xc00049a0, 0xca0000f8, 0xc3000000, 0xc5f04018, 0xc2400000, 0xc5e50038, 0x7e412000,
+ 0x76250000, 0xce0000f8, 0xc0004980, 0x40300000, 0xcec000f8, 0xc161fffe, 0x5955fffe, 0x14140000,
+ 0x00000000, 0xc000496a, 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x7e010000, 0x76612000, 0xce4000f8,
+ 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0x6ef4a000, 0x6ed44000, 0x4755a000, 0x476da000,
+ 0x5b747000, 0x5834000e, 0xc2000000, 0xca0000d8, 0x58340008, 0xc2400000, 0xca420078, 0x5834000c,
+ 0xc2800000, 0xca832010, 0x6e644010, 0x42250000, 0x4229e000, 0xc39a8008, 0x58340008, 0xcb809018,
+ 0x58340008, 0xc2800000, 0xca810010, 0x6ee0a000, 0x6ee44000, 0x46250000, 0x462d0000, 0x5a200008,
+ 0x5a203008, 0x42290000, 0xc6380060, 0xc6f81c18, 0x99005b78, 0xdb9800f8, 0xdbd800f9, 0x00000000,
+ 0xc000495a, 0xc84000f8, 0x00000000, 0xc3c00002, 0x787c2000, 0xcc4000f8, 0xc0001a1c, 0xca0000f8,
+ 0xc2400008, 0x6a452000, 0x76250000, 0x84000ec2, 0xc0000a28, 0xc3800000, 0xcb840028, 0xc0000a14,
+ 0xc3400000, 0xcb440028, 0xc0004880, 0xcb0400f8, 0xb7b40072, 0x58041802, 0xcac000f8, 0xa7000078,
+ 0x00000000, 0x00000000, 0xa6c8d808, 0xc1000000, 0xc6d00018, 0xc0004980, 0x40100000, 0xca8000f8,
+ 0x80000070, 0x00000000, 0x00000000, 0x00000000, 0x8000d7b8, 0x00000000, 0xc2800000, 0xc7282018,
+ 0xc000490e, 0xca4000f8, 0x6be9e000, 0x00000000, 0x767d2000, 0x8400d770, 0x6ea0a000, 0x6e944000,
+ 0x46150000, 0x46290000, 0x5a207000, 0x5820000c, 0xca0000f8, 0xc0004946, 0xce8000f8, 0xa62203a8,
+ 0x00000000, 0xc2200060, 0xc0004948, 0xce000008, 0xce021038, 0xc240000a, 0xc000494a, 0xce4000f8,
+ 0xc2b60002, 0xc0004964, 0xce837b00, 0x99005e48, 0xc00048a0, 0xc88400f8, 0x00000000, 0xc0004946,
+ 0xcbc000f8, 0x00000000, 0x00000000, 0x6ff8a000, 0x6fd44000, 0x4795c000, 0x47bdc000, 0x5bb87000,
+ 0x99005c08, 0xdbd800f8, 0xdb9800f9, 0x00000000, 0x99005950, 0xc000491c, 0xc1400000, 0xc9420048,
+ 0xc000491c, 0x99005e00, 0xc94000f9, 0xc98000f8, 0x00000000, 0x99005b78, 0xd95800f8, 0xd99800f9,
+ 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x99005840, 0xdbd800f8, 0xdb9800f9,
+ 0xc7d800f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0x6ff8a000, 0x6fd44000, 0x4795c000,
+ 0x47bdc000, 0x5bb87000, 0x58380010, 0xca0000f8, 0xc0004874, 0xc80400f8, 0x6c908000, 0x45088000,
+ 0x45088000, 0x40100000, 0xca4000f8, 0xc43400f8, 0x00000000, 0xc74000f8, 0xce0000f8, 0xc161fffe,
+ 0x5955fffe, 0x14140000, 0x00000000, 0xc000490e, 0xca4000f8, 0xc2800002, 0x6abd4000, 0x72692000,
+ 0xce4000f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0x990062f0, 0xc0004836, 0xc94000f8,
+ 0xc1800002, 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffe8, 0x00000000, 0x58380000, 0xc90000f8,
+ 0xc00049a0, 0xca0000f8, 0xc2800000, 0xc5290038, 0x72290000, 0xce0000f8, 0xc1220002, 0xd90c00f8,
+ 0xc2000000, 0xc0000a14, 0xca040028, 0xc0000a28, 0xc2500002, 0xce450800, 0x58880002, 0xb6080018,
+ 0xc00048a0, 0xc0800000, 0xcc8400f8, 0x8000d380, 0xc0004946, 0xcbc000f8, 0xc161fffe, 0x5955fffe,
+ 0x14140000, 0x00000000, 0xc000490e, 0xca4000f8, 0xc2800002, 0x6abd4000, 0x72692000, 0xce4000f8,
+ 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0x6ff8a000, 0x6fd44000, 0x4795c000, 0x47bdc000,
+ 0x5bb87000, 0x58380008, 0xca0000f8, 0x5838000c, 0xca4000f8, 0xc3400000, 0xc6340000, 0xc000494e,
+ 0xcf4000f8, 0xc2800000, 0xc62a0078, 0xc3000000, 0xc6308018, 0x6f304000, 0x43298000, 0xc000493c,
+ 0xcf0000f8, 0xc2c00000, 0xc66c0078, 0xc0004950, 0xcec000f8, 0xc2800000, 0xc66ae020, 0xc0004954,
+ 0xce8000f8, 0x5f740000, 0x840001a0, 0x5e300028, 0x46e12000, 0x8400016a, 0x46e12000, 0x88000132,
+ 0x5e300018, 0x46e12000, 0x8800002a, 0x46e12000, 0x84000042, 0x00000000, 0x800000c0, 0x00000000,
+ 0x99005f88, 0xdbd800f8, 0xdb9800f9, 0xc78000f8, 0xc3400002, 0xc000494e, 0xcf4000f8, 0xc161fffe,
+ 0x5955fffe, 0x14140000, 0x00000000, 0xc000490e, 0xca4000f8, 0xc2800002, 0x6abd4000, 0x7e814000,
+ 0x76692000, 0xce4000f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0xc2200060, 0xc0004948,
+ 0xce021038, 0xc2000000, 0xc000494c, 0xce0000f8, 0x80000080, 0x00000000, 0x99005f88, 0xdbd800f8,
+ 0xdb9800f9, 0xc78000f8, 0x99006188, 0xdbd800f8, 0xdb9800f9, 0xc78000f8, 0xc2200058, 0xc0004948,
+ 0xce021038, 0xc2000002, 0xc000494c, 0xce0000f8, 0xc2000006, 0xc0001006, 0xce0000f8, 0x5838000a,
+ 0xca4000f8, 0xc2200982, 0x5a203b6e, 0xc0001008, 0xce0000f8, 0xc000100a, 0xce4000f8, 0xc0004954,
+ 0xca8000f8, 0xc200000c, 0xc000494a, 0xce0000f8, 0xc0004948, 0xce800008, 0xc2b60000, 0xc0004964,
+ 0xce8000f8, 0x99005e48, 0xc00048a0, 0xc88400f8, 0x00000000, 0xc0004946, 0xcbc000f8, 0xc000494c,
+ 0xca0000f8, 0x6ff8a000, 0x6fd44000, 0x4795c000, 0x47bdc000, 0x5bb87000, 0x5e200000, 0x840000fa,
+ 0x00000000, 0x99005c08, 0xdbd800f8, 0xdb9800f9, 0x00000000, 0x99005950, 0xc000491c, 0xc1400000,
+ 0xc9420048, 0xc000491c, 0x99005e00, 0xc94000f9, 0xc98000f8, 0x00000000, 0x99005b78, 0xd95800f8,
+ 0xd99800f9, 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x99005840, 0xdbd800f8,
+ 0xdb9800f9, 0xc7d800f8, 0x00000000, 0xc121fffe, 0x5911fe14, 0x14100000, 0xc000493c, 0xca8000f8,
+ 0xc000494e, 0xcac000f8, 0xc3000018, 0xc3400006, 0x5e200000, 0x8400002a, 0xc2800000, 0xc2c00000,
+ 0xc300001e, 0xc3400000, 0xc6ac1078, 0xc72c0418, 0xc76c0810, 0x58380010, 0xca8000f8, 0x58380008,
+ 0xcec000f8, 0xc6280100, 0xc0004874, 0xc80400f8, 0x6c908000, 0x45088000, 0x45088000, 0x40100000,
+ 0xcb0000f8, 0xc43400f8, 0x00000000, 0xc74000f8, 0xce8000f8, 0xc0004952, 0xce8000f8, 0x00000000,
+ 0x00000000, 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc000494c, 0xca0000f8, 0xc0004950, 0xcac000f8,
+ 0x5e200000, 0x8400006a, 0xdfe800f8, 0x7e814000, 0x5834001a, 0xce8000f8, 0x990062f0, 0xc0004834,
+ 0xc94000f8, 0xc1800002, 0x990062f0, 0xc0004838, 0xc94000f8, 0xc6d800f8, 0xc1220002, 0xd90c00f8,
+ 0x5e200000, 0x84000040, 0x5838002c, 0xcb0000f8, 0xdfe800f8, 0x00000000, 0x58380014, 0xcf0000f8,
+ 0x80000058, 0xc2a1fffe, 0x5aa9fffe, 0x58380000, 0xc90000f8, 0xc00049a0, 0xcb0000f8, 0xc2c00000,
+ 0xc52d0038, 0x732d8000, 0xcf0000f8, 0x5838000a, 0xce8000f8, 0xc3000000, 0xc0000a14, 0xcb040028,
+ 0xc2d00002, 0xc0000a28, 0xcec50800, 0xc000494e, 0xca8000f8, 0x58880002, 0xb4b00018, 0xc00048a0,
+ 0xc0800000, 0xcc8400f8, 0x5ea80000, 0x8400017a, 0x5e200000, 0x84000168, 0xc000493c, 0xca8000f8,
+ 0x00000000, 0x00000000, 0x5aa80060, 0xce8000f8, 0x99005f88, 0xdbd800f8, 0xdb9800f9, 0xc78000f8,
+ 0x99006188, 0xdbd800f8, 0xdb9800f9, 0xc78000f8, 0x58380000, 0xcac000f8, 0x00000000, 0xc2000000,
+ 0xc6e04018, 0xc0004952, 0xcac000f8, 0x58380000, 0xca8000f8, 0xc30c0002, 0xc6300018, 0xa6800098,
+ 0x00000000, 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0xc0001800, 0xca0000f8,
+ 0x00000000, 0x00000000, 0xa60cffea, 0xc6f00500, 0xc6b0c400, 0xcf0000f8, 0x00000000, 0xc121fffe,
+ 0x5911fe14, 0x14100000, 0x8000c9c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000c960,
+ 0xdcbc00f9, 0x5ffc0000, 0x84000052, 0xc3800002, 0xdb8800f9, 0x5ffc0004, 0x8400c292, 0xc3800000,
+ 0xdb8800f9, 0xc3ce0002, 0xc0000800, 0xcfc0e700, 0xc3e1fffe, 0x597dfffe, 0x593dfe14, 0x94000001,
+ 0x00000000, 0x00000000, 0x00000000, 0xc000487c, 0xc80400f8, 0x00000000, 0x00000000, 0x40080000,
+ 0xcbc000f8, 0xc43800f8, 0x00000000, 0xc000480e, 0xca0000f8, 0xc0004858, 0xcb4400f8, 0x00000000,
+ 0x00000000, 0x47610000, 0x880000b0, 0x00000000, 0xa7c00048, 0xc0004854, 0xc1000002, 0xcd0400f8,
+ 0xc11c0000, 0xc000082c, 0xcd05ce00, 0x800000d8, 0x00000000, 0xa7d20138, 0x00000000, 0xc7e14040,
+ 0xc2400000, 0xc6246028, 0xc200006a, 0x46250000, 0xc6240030, 0xc0000810, 0xce440030, 0x8000ff70,
+ 0xc2000000, 0xc0000808, 0xca040010, 0xc11c0000, 0xc000082c, 0xcd05ce00, 0x5a200002, 0x5e600010,
+ 0x84000010, 0xc2000000, 0xc0000808, 0xce040010, 0xc3400000, 0x80000028, 0xc1200002, 0xc0000818,
+ 0xcd061000, 0x5b740002, 0xc0004858, 0xcf4400f8, 0x99005590, 0xc0004848, 0xc94400f8, 0xc1800000,
+ 0xc11c0002, 0xc000082c, 0xcd05ce00, 0x80000600, 0x5b740002, 0xc0004858, 0xcf4400f8, 0xc78000f8,
+ 0xc13c0002, 0xcd03de00, 0xc0004848, 0xc94400f8, 0xc1800000, 0xc000082c, 0xc9840028, 0x59540002,
+ 0xc0004848, 0xcd4400f8, 0x58880002, 0xb4980580, 0x00000000, 0xc0800000, 0x80000568, 0xc000487c,
+ 0xc80400f8, 0x00000000, 0x00000000, 0x40080000, 0xcbc000f8, 0xc42800f8, 0x00000000, 0xa7c00130,
+ 0xc000484c, 0xca0400f8, 0xc2400000, 0xc0001aec, 0xca440018, 0x5a200002, 0xc000484c, 0xce0400f8,
+ 0xb624008a, 0xc68000f8, 0xc13c0002, 0xcd03de00, 0xc0004848, 0xc94400f8, 0xc1800000, 0xc000082c,
+ 0xc9840028, 0x59540002, 0xc0004848, 0xcd4400f8, 0x58880002, 0xb4980470, 0x00000000, 0xc0800000,
+ 0x80000458, 0xc0004854, 0xc1000004, 0xcd0400f8, 0xc0000820, 0xc2000002, 0xce0400f8, 0xc2000000,
+ 0xc000484c, 0xce0400f8, 0xc0004858, 0xce0400f8, 0x8000ff28, 0xc0004854, 0xc1000000, 0xcd0400f8,
+ 0xc11c0000, 0xc000082c, 0xcd05ce00, 0x99005590, 0xc0004848, 0xc94400f8, 0xc1800000, 0xc1200000,
+ 0xc0000818, 0xcd061000, 0xc11c0002, 0xc000082c, 0xcd05ce00, 0xc2000000, 0xc000484c, 0xce0400f8,
+ 0x80000358, 0xc0001ac0, 0xcb8400f8, 0xc000487c, 0xc80400f8, 0x00000000, 0x00000000, 0x40080000,
+ 0xcbc000f8, 0xc42800f8, 0x00000000, 0x00000000, 0xc68000f8, 0xc13c0000, 0xcd03de00, 0xa780024a,
+ 0x00000000, 0x00000000, 0xa7c0020a, 0x00000000, 0xc0001b00, 0xc2060006, 0xce046308, 0xa7e801c2,
+ 0x00000000, 0xc0004850, 0xca0400f8, 0xc2400000, 0xc0001aec, 0xca448018, 0x5a200002, 0xc0004850,
+ 0xce0400f8, 0xb62400aa, 0x00000000, 0xc68000f8, 0xc13c0002, 0xcd03de00, 0xc0001acc, 0xc2000002,
+ 0xce040000, 0xc0004848, 0xc94400f8, 0xc1800000, 0xc000082c, 0xc9840028, 0x59540002, 0xc0004848,
+ 0xcd4400f8, 0x58880002, 0xb49801c8, 0x00000000, 0xc0800000, 0x800001b0, 0xc0004854, 0xc1000000,
+ 0xcd0400f8, 0xc11c0000, 0xc000082c, 0xcd05ce00, 0x99005590, 0xc0004848, 0xc94400f8, 0xc1800000,
+ 0xc2000000, 0xc0000820, 0xce0400f8, 0xc1200000, 0xc0000818, 0xcd061000, 0xc11c0002, 0xc000082c,
+ 0xcd05ce00, 0xc0004850, 0xce0400f8, 0xc2000002, 0xc0001acc, 0xce040008, 0x800000e8, 0xc2000002,
+ 0xc0004850, 0xce0400f8, 0x8000fe88, 0xc2000000, 0xc0004850, 0xce0400f8, 0xa7e60032, 0x00000000,
+ 0xc2000002, 0xc0001b00, 0xce040000, 0x8000fe70, 0x00000000, 0xa7860052, 0x00000000, 0xc68000f8,
+ 0xc13c0002, 0xcd03de00, 0xc2020002, 0xc7e2a540, 0xc0001b00, 0xce0400f8, 0x8000fe18, 0xc2040002,
+ 0xc0001b00, 0xce044200, 0x8000fdf8, 0xc2c80002, 0x6ac56000, 0xdacc00f8, 0xc0004854, 0xcb4400f8,
+ 0xc0004848, 0xcb8400f8, 0xc0000838, 0xc3c00000, 0xcbc40028, 0x5ef40004, 0x84000022, 0xc3000000,
+ 0xc0001acc, 0xcf042100, 0x47f98000, 0x8400002a, 0x47f98000, 0x88000030, 0xc1006e8c, 0x8000b6c8,
+ 0xc0004840, 0xcc8400f8, 0x8000f6b0, 0xc0001ac0, 0xcac400f8, 0xc0004854, 0xcb4400f8, 0xa6c0fbd2,
+ 0x00000000, 0x5ef40000, 0x8400f70a, 0x5ef40002, 0x8400f99a, 0x5ef40004, 0x8400fb9a, 0xc1006ce8,
+ 0x8000b640, 0x00000000, 0xc0800000, 0xdf4b0038, 0xc0004900, 0xcb8000f8, 0xc2000000, 0xc000490a,
+ 0xa78000d0, 0xcbc000f8, 0xc1000000, 0xd90000f9, 0xc1000002, 0xd90c00f8, 0x6ff46000, 0x477da000,
+ 0x5b744c80, 0xc2400000, 0x58340004, 0xca400078, 0xc0004900, 0xce000000, 0x5a640002, 0x58340004,
+ 0xc6500078, 0xcd000078, 0xc0004914, 0xca4000f8, 0xc2000002, 0x6a3d0000, 0x72612000, 0xce4000f8,
+ 0xc0000408, 0xce0000f8, 0xa78200d8, 0xc0004908, 0xcbc000f8, 0xc1000000, 0xd90000f9, 0xc1000002,
+ 0xd90c00f8, 0x6ff4a000, 0x6fd44000, 0x4755a000, 0x477da000, 0x5b747000, 0xc2800000, 0x58340006,
+ 0xca800078, 0xc2000000, 0xc0004900, 0xce002100, 0x5ea80002, 0x58340006, 0xc6900078, 0xcd000078,
+ 0x5a7c0020, 0xc2000002, 0x6a250000, 0xc0000408, 0xce0000f8, 0xdca800f9, 0x5ea80000, 0x8400b4b0,
+ 0x00000000, 0xa4800230, 0x00000000, 0xc3c00000, 0xc000140e, 0xcbc00018, 0xc3400000, 0xc2400000,
+ 0x6ff86000, 0x47bdc000, 0x5bb84c80, 0x58380008, 0xcb400078, 0x58380006, 0xca400078, 0x5f740002,
+ 0x58380008, 0xc7500078, 0xcd000078, 0xc2000000, 0x58380004, 0xca020078, 0xc3000000, 0x5838000c,
+ 0xcb000020, 0x5a640002, 0x46610000, 0x84000010, 0xc2400000, 0x58380006, 0xc6500078, 0xcd000078,
+ 0xc2000000, 0x5838000a, 0xca020078, 0x5b300002, 0x5838000c, 0xc7100020, 0xcd000020, 0xc2420020,
+ 0x5a200004, 0x46252000, 0x84000010, 0xc2000000, 0x5838000a, 0xc6101078, 0xcd021078, 0xc0004966,
+ 0xca4000f8, 0xc2000002, 0x6a3d0000, 0x72612000, 0xce4000f8, 0x5f740000, 0x84000040, 0xc0004912,
+ 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x7ec16000, 0x762d0000, 0xce0000f8, 0x5f300020, 0x84000040,
+ 0xc0004924, 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x7ec16000, 0x762d0000, 0xce0000f8, 0xa4820070,
+ 0xc2400000, 0xc000140e, 0xca408018, 0xc2000002, 0xc0004900, 0xce000000, 0xc000490a, 0xce4000f8,
+ 0xc1000000, 0xd90000f9, 0xd8400078, 0xc1000004, 0xd90000f9, 0xa4840270, 0x00000000, 0xc3c00000,
+ 0xc000140e, 0xcbc10018, 0xc2800000, 0xc2000000, 0x6ff8a000, 0x6fd44000, 0x4795c000, 0x47bdc000,
+ 0x5bb87000, 0x5838002e, 0xca800078, 0x58380006, 0xca020078, 0xc3400000, 0x5838002e, 0xcb420078,
+ 0x5aa80002, 0x46a10000, 0x84000010, 0xc2800000, 0x5838002e, 0xc6900078, 0xcd000078, 0x5f740002,
+ 0x5838002e, 0xc7501078, 0xcd021078, 0xc0004968, 0xca4000f8, 0xc2000002, 0x6a3d0000, 0x72612000,
+ 0xce4000f8, 0xc000492a, 0xca8000f8, 0x5e740000, 0x84000040, 0xc0004910, 0xca0000f8, 0xc2c00002,
+ 0x6afd6000, 0x7ec16000, 0x762d0000, 0xce0000f8, 0x6abd4010, 0xa68000ba, 0x00000000, 0x58380032,
+ 0xca0000f8, 0x58000002, 0xca4000f8, 0x5838000c, 0x00000000, 0xce0000f9, 0xce4000f8, 0xc000492a,
+ 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x722d0000, 0xce0000f8, 0xc000492c, 0xca0000f8, 0xc2c00002,
+ 0x6afd6000, 0x722d0000, 0xce0000f8, 0x80000040, 0xc000492c, 0xca0000f8, 0xc2c00002, 0x6afd6000,
+ 0x7ec16000, 0x762d0000, 0xce0000f8, 0xa4880148, 0xc2c00000, 0xc000140e, 0xcac20018, 0xc000490e,
+ 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x7e010000, 0x76612000, 0xce4000f8, 0xc000496a, 0xca4000f8,
+ 0xc2000002, 0x6a2d0000, 0x72612000, 0xce4000f8, 0x6ef0a000, 0x6ed44000, 0x47158000, 0x472d8000,
+ 0x5b307000, 0x58300000, 0xca0000f8, 0x00000000, 0xc2400002, 0x76612000, 0x84000072, 0x58300000,
+ 0xca4000f8, 0xc2800000, 0x00000000, 0xc6684018, 0xc24c0002, 0xc6a40018, 0xc624c400, 0x58300010,
+ 0xca400500, 0x00000000, 0xc0001800, 0xce4000f8, 0xa4860070, 0xc2400000, 0xc000140e, 0xca418018,
+ 0xc2020002, 0xc0004900, 0xce002100, 0xc0004908, 0xce4000f8, 0xc1000000, 0xd90000f9, 0xd8400078,
+ 0xc1000004, 0xd90000f9, 0xc0001408, 0xcc8000f8, 0xc10e0002, 0xd90c00f8, 0x8000edb0, 0xdfbc00f9,
+ 0xc000496e, 0x99006298, 0xc94000f8, 0xc7d800f8, 0x00000000, 0xc57000f8, 0x5ef00020, 0x88000148,
+ 0x6f346000, 0x4771a000, 0x5b744c80, 0x58340008, 0xc2400000, 0xca400078, 0x00000000, 0xc2000000,
+ 0x5a640002, 0xce400078, 0x58340004, 0xca000078, 0x00000000, 0x00000000, 0x5e200002, 0xce000078,
+ 0xc0004912, 0xca8000f8, 0xc2400002, 0x6a712000, 0x72a54000, 0xce8000f8, 0x5e200000, 0x84000052,
+ 0xc000480a, 0xca0000f8, 0xc0000408, 0xca8000f8, 0x76250000, 0x00000000, 0x72a14000, 0xce8000f8,
+ 0x80000038, 0xc0004914, 0xca0000f8, 0x7e412000, 0x00000000, 0x76250000, 0xce0000f8, 0x800000d0,
+ 0x6ef4a000, 0x6ed44000, 0x4755a000, 0x476da000, 0x5b747000, 0x5834002e, 0xc2400000, 0xca420078,
+ 0x00000000, 0xc2000000, 0x5a640002, 0xc6501078, 0xcd021078, 0x58340006, 0xca000078, 0x00000000,
+ 0x00000000, 0x5a200002, 0xce000078, 0xc0004910, 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x72612000,
+ 0xce4000f8, 0xc2000002, 0x6a310000, 0xc000042a, 0xce0000f8, 0xc1040002, 0xd90c00f8, 0x00000000,
+ 0x8000eb20, 0x00000000, 0xc4980928, 0x9d000000, 0xc5580028, 0xc0000838, 0xcd8400f8, 0xc1440200,
+ 0xc1c03800, 0xc55c1070, 0xc000100e, 0x9d000000, 0xcd8000f8, 0xc000100c, 0xcdc000f8, 0xc0004862,
+ 0xc9c000f8, 0x00000000, 0x00000000, 0xd9d800f9, 0xc0007800, 0x401c0000, 0x5dc07a00, 0x88000012,
+ 0x5c000200, 0xcd8000f8, 0xc1f0000a, 0x715ca000, 0xdd9800f8, 0xdd9c00f9, 0x41d8e000, 0xc5d40260,
+ 0xc0001010, 0xcd4000f8, 0x6c9c8000, 0x45c8e000, 0x45c8e000, 0x59dc0004, 0xc1601260, 0xc5d40260,
+ 0x9d000000, 0xc0001012, 0xcd4000f8, 0x00000000, 0x00000000, 0xd95800f8, 0x6d586000, 0x4594c000,
+ 0x59984c80, 0xd99800f9, 0x5818000a, 0xc1800000, 0xc9800078, 0xc0006e00, 0x6d5ca000, 0x401c0000,
+ 0x40180000, 0xc94000f8, 0x58000002, 0x00000000, 0xc9c000f8, 0xc0004930, 0xcd4000f8, 0xc0004932,
+ 0xcdc000f8, 0x59980004, 0xc1c20020, 0xb59c0018, 0x00000000, 0xc1800000, 0xdd9c00f9, 0x581c000a,
+ 0xcd800078, 0x581c000c, 0xc1800000, 0xc9800020, 0xc1c00002, 0xdd9400f8, 0x69d4e000, 0x5d980002,
+ 0xcd800020, 0xc0004924, 0xc98000f8, 0x00000000, 0x9d000000, 0x00000000, 0x719cc000, 0xcd8000f8,
+ 0xc000492a, 0xc94000f8, 0xc1c00002, 0x69d8e000, 0x7dc0c000, 0x7558a000, 0xcd4000f8, 0xc000492c,
+ 0xc94000f8, 0xdd8000f9, 0x58000032, 0x755ca000, 0x84000090, 0xc94000f9, 0xc98000f8, 0xdd8000f9,
+ 0x5800000c, 0x00000000, 0xcd4000f9, 0xcd8000f8, 0xc000492c, 0xc94000f8, 0xc000492a, 0xc98000f8,
+ 0x715ca000, 0xc000492c, 0xcd4000f8, 0x719cc000, 0xc000492a, 0xcd8000f8, 0x9d000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xc0004862, 0xc98000f8, 0x00000000, 0xc1c00200, 0x4194c000, 0x459ce000,
+ 0x88000012, 0xc5d800f8, 0xc0004862, 0xcd8000f8, 0xc0001406, 0xc98000f8, 0xc1c00002, 0x9d000000,
+ 0xc5d80a00, 0xc5581048, 0xcd8000f8, 0xc0004930, 0xc98000f8, 0xc0004932, 0xc9c000f8, 0xc140000e,
+ 0xc5581c18, 0xdd9400f8, 0xc0007800, 0x40140000, 0x5d407a00, 0x88000012, 0x5c000200, 0xcd8000f8,
+ 0x58000002, 0x5d407a00, 0x88000012, 0x5c000200, 0xcdc000f8, 0xdd5400f8, 0xc1c00000, 0x58140006,
+ 0xc9c20078, 0xc1800000, 0x58140000, 0xc98000d8, 0x6ddc2000, 0xc000491e, 0x41d8e000, 0xcdc000f8,
+ 0xdd9800f8, 0xc1c00022, 0xc5d80d70, 0xdd9400f9, 0xc5581c18, 0xc000491c, 0xcd8000f8, 0xdd5400f8,
+ 0xc1c00000, 0x58140006, 0xc9c20078, 0xc1800000, 0x58140004, 0xc9820078, 0x00000000, 0x59dc0002,
+ 0x45d8c000, 0x84000010, 0xc1c00000, 0x9d000000, 0x58140006, 0xc5d81078, 0xcd821078, 0xc0004860,
+ 0xc94000f8, 0xc1820080, 0xc1d00002, 0x58147700, 0xd58000f8, 0x58000002, 0xd58000f9, 0x59540004,
+ 0xb5580018, 0xc0004860, 0xc1400000, 0xcd4000f8, 0xdd9800f9, 0x9d000000, 0xdd9400f8, 0xc0001404,
+ 0xcdc10800, 0xc1c00000, 0xc1800200, 0x5d980004, 0xdf5d0048, 0x459ca000, 0x8800fff2, 0xdd8000f9,
+ 0x5800000c, 0x00000000, 0xc94000f9, 0xc98000f8, 0xc1c00002, 0xc5d43f00, 0xc5d81e00, 0xc0004862,
+ 0xc9c000f8, 0x00000000, 0x00000000, 0x581c7800, 0x5dc07a00, 0x88000012, 0x5c000200, 0xcd4000f8,
+ 0x58000002, 0x5dc07a00, 0x88000012, 0x5c000200, 0xcd8000f8, 0xc0004862, 0xc9c000f8, 0x00000000,
+ 0xc15004c0, 0xc5d40060, 0xdd9c00f8, 0xc5d41c18, 0xc1c00000, 0xdd8000f9, 0x58000030, 0xc9c00078,
+ 0xdd8000f9, 0x58000002, 0xc98000f8, 0x6ddc2000, 0xc000491c, 0x41d8e000, 0xcd4000f9, 0xcdc000f8,
+ 0xdd9400f9, 0xc1c00000, 0x58140030, 0xc9c00078, 0xc1800000, 0x58140006, 0xc9820078, 0x00000000,
+ 0x59dc0002, 0x45d8c000, 0x84000010, 0xc1c00000, 0x9d000000, 0x58140030, 0xc5d80078, 0xcd800078,
+ 0xc1c00000, 0xdf5c0038, 0x5ddc0080, 0x8400ffea, 0x00000000, 0x9d000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xc160fffe, 0xc0000a10, 0xc9440060, 0xc1a0fffe, 0x59983008, 0xc000100c, 0xcd4000f8,
+ 0xc000100e, 0xcd8000f8, 0xc0004964, 0xc98000f8, 0x00000000, 0xc170000a, 0x7158a000, 0x6c988000,
+ 0x4588c000, 0x4588c000, 0x59980004, 0xc5940270, 0xc0001010, 0xcd4000f8, 0xc0004946, 0xc94000f8,
+ 0x00000000, 0x00000000, 0x6d58a000, 0x6d5c4000, 0x459cc000, 0x4594c000, 0xc000494a, 0xc94000f8,
+ 0xc0004948, 0xc9c000f8, 0x4194c000, 0xc1400012, 0xc55c1818, 0x9d000000, 0xc59c0268, 0xc0001012,
+ 0xcdc000f8, 0xc1400000, 0x58000012, 0xc9410038, 0xc0004950, 0xc9c000f8, 0xc55800f8, 0xc5940838,
+ 0xc5581078, 0xd99400f8, 0xc000493c, 0xc94000f8, 0xc0004954, 0xc98000f8, 0x59dc00a8, 0x45d4e000,
+ 0x41d8e000, 0x5d5c0030, 0x88000010, 0xc1c00030, 0xc1800000, 0xc5d84028, 0xc1400000, 0xc5d40008,
+ 0x5dd40002, 0x84000072, 0x5dd40004, 0x8400009a, 0x5dd40006, 0x840000c2, 0x5dd80026, 0x840000ea,
+ 0xdd5400f8, 0xdd8000f9, 0x58000008, 0x40180000, 0xcd4000f8, 0x59980002, 0x8000ffc0, 0xdd5400f8,
+ 0xdd8000f9, 0x58000008, 0x40180000, 0xcd4000b8, 0x59980002, 0x8000ff88, 0xdd5400f8, 0xdd8000f9,
+ 0x58000008, 0x40180000, 0xcd400078, 0x59980002, 0x8000ff50, 0xdd5400f8, 0xdd8000f9, 0x58000008,
+ 0x40180000, 0xcd400038, 0x59980002, 0x8000ff18, 0x00000000, 0x9d000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x58000012, 0xc94000f8, 0xc0004954, 0xc9c000f8, 0xc0004950, 0xc9400078, 0xdd8000f9,
+ 0x58000028, 0x5d9c0000, 0x84000052, 0x5d9c0002, 0x84000052, 0x5d9c0004, 0x8400006a, 0xc55b0038,
+ 0xc55c08b8, 0xcd800039, 0xcdc108b8, 0x80000060, 0xcd4000f8, 0x80000050, 0xc55900b8, 0xc55c1838,
+ 0xcd8000b9, 0xcdc31838, 0x80000028, 0xc55a0078, 0xc55c1078, 0xcd800079, 0xcdc21078, 0x9d000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x59540002, 0x6994e018, 0x61c0c008, 0x4194a000, 0x5d940040,
+ 0x88000012, 0xc59400f8, 0x9d000000, 0xcd4000f8, 0x00000000, 0x00000000, 0x9d000000, 0x4158a000,
+ 0xcd4000f8, 0x00000000,
+};
+
+static unsigned int ar9_fw_data[] = {
+};
+
+
+#endif // IFXMIPS_ATM_FW_AR9_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_ar9_retx.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_ar9_retx.h
new file mode 100644
index 0000000000..51e4f9c6c9
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_ar9_retx.h
@@ -0,0 +1,611 @@
+#ifndef IFXMIPS_ATM_FW_AR9_H
+#define IFXMIPS_ATM_FW_AR9_H
+
+
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_fw_ar9.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 22 OCT 2007
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (PP32 Firmware)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 22 OCT 2007 Xu Liang Initiate Version, v00.01
+*******************************************************************************/
+
+
+#define VER_IN_FIRMWARE 1
+
+#define ATM_FW_VER_MAJOR 0
+#define ATM_FW_VER_MINOR 15
+
+
+static unsigned int firmware_binary_code[] = {
+ 0x800004B8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000FFE0, 0x00000000, 0x00000000, 0x00000000,
+ 0xC1000002, 0xD90C00F8, 0xC2000002, 0xDA0800F9, 0xC0001B50, 0x8C100000, 0x00000000, 0x00000000,
+ 0x00000000, 0xC2000000, 0xDA0800F9, 0x80006030, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80006008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC1001DA6, 0x8D3C0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80005F08, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0400000, 0xC0004840, 0xC88400F8, 0xC2001AEE, 0x8E100000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0400002, 0xC0004840, 0xC88400F8, 0xC2001AEE, 0x8E100000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC3C00004, 0xDBC800F9, 0xC10C0002, 0xD90C00F8, 0x8000FEE0, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC10E0002, 0xD90C00F8, 0xC0004808, 0xC84000F8, 0xC2001B4C, 0x8E100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC3E1FFFE, 0x597DFFFE, 0x593DFE14, 0x900004D9, 0x00000000, 0x00000000, 0x00000000, 0x90CC0481,
+ 0x00000000, 0x00000000, 0x00000000, 0xC3E0A252, 0x5BFC001E, 0xC0004002, 0xCFC000F8, 0xC3C00000,
+ 0xDBC800F9, 0xC1400008, 0xC1900000, 0x71588000, 0x14100100, 0xC140000A, 0xC1900002, 0x71588000,
+ 0x14100100, 0xC140000C, 0xC1900004, 0x71588000, 0x14100100, 0xC1400004, 0xC1900006, 0x71588000,
+ 0x14100100, 0xC1400006, 0xC1900008, 0x71588000, 0x14100100, 0xC140000E, 0xC190000A, 0x71588000,
+ 0x14100100, 0xC1400000, 0xC190000C, 0x71588000, 0x14100100, 0xC1400002, 0xC190000E, 0x71588000,
+ 0x14100100, 0xC0400000, 0xC11C0000, 0xC000082C, 0xCD05CE00, 0xC11C0002, 0xC000082C, 0xCD05CE00,
+ 0xC0400002, 0xC11C0000, 0xC000082C, 0xCD05CE00, 0xC0000824, 0x00000000, 0xCBC000F9, 0xCB8000F9,
+ 0xCB4000F9, 0xCB0000F8, 0xC0004878, 0x5BFC4000, 0xCFC000F9, 0x5BB84000, 0xCF8000F9, 0x5B744000,
+ 0xCF4000F9, 0x5B304000, 0xCF0000F8, 0xC0000A10, 0x00000000, 0xCBC000F9, 0xCB8000F8, 0xC0004874,
+ 0x5BFC4000, 0xCFC000F9, 0x5BB84000, 0xCF8000F8, 0xC30001FE, 0xC000140A, 0xCF0000F8, 0xC3000000,
+ 0x7F018000, 0xC000042E, 0xCF0000F8, 0xC000040E, 0xCF0000F8, 0xC3C1FFFE, 0xC000490E, 0xCFC00078,
+ 0xC000492C, 0xCFC00078, 0xC0004924, 0xCFC00038, 0xC0004912, 0xCFC00038, 0xC0004966, 0xCFC00038,
+ 0xC0004968, 0xCFC00078, 0xC000496A, 0xCFC00078, 0xC3C00000, 0xC2800020, 0xC3000000, 0x7F018000,
+ 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB84A00, 0x5838000A, 0xCF0000F8, 0x5BFC0002, 0xB7E8FFC8,
+ 0x00000000, 0xC3C00000, 0xC2800010, 0x6FF86000, 0x47BDC000, 0x5BB84C80, 0xC3400000, 0x58380004,
+ 0xCB420078, 0x00000000, 0x58380008, 0xCF400078, 0x5BFC0002, 0xB7E8FFB0, 0x00000000, 0xC3C00000,
+ 0xC2800020, 0xC348001E, 0xC3000000, 0x7F018000, 0x6FF8A000, 0x6FD44000, 0x4795C000, 0x47BDC000,
+ 0x5BB87000, 0x58380008, 0xCF408418, 0x5838000A, 0xCF0000F8, 0x5BFC0002, 0xB7E8FFB0, 0x00000000,
+ 0x00000000, 0xC0004816, 0xC3C00000, 0xCBC00078, 0x00000000, 0x00000000, 0xC1000000, 0xD90400F9,
+ 0xDBC40078, 0xC1000006, 0xD90400F9, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000, 0xC3C00000,
+ 0xDCFC2000, 0x5FFC0002, 0x00000000, 0x98C08D62, 0xC0004730, 0xC94000F8, 0xC0004732, 0xC0001AF2,
+ 0xCBC000F8, 0x00000000, 0x00000000, 0xA7C20470, 0xC000474A, 0xCA8000F8, 0x00000000, 0x00000000,
+ 0x5D280000, 0x8400FFE0, 0x00000000, 0xC121FFFE, 0x5911FEF4, 0x14100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC2802000, 0x6EA8E010, 0xC0004200, 0xC2400000, 0x7E410000, 0xC1000000, 0xCE4000F9, 0xCE4000F9,
+ 0xCE4000F9, 0xCE4000F9, 0x5EA80002, 0x8400FFD8, 0xC0004300, 0xC2800200, 0x6EA84010, 0xCE4000F9,
+ 0xCE0000F9, 0xCE4000F9, 0xCE0000F9, 0xCE4000F9, 0xCE0000F9, 0xCE4000F9, 0xCE0000F9, 0x5EA80002,
+ 0x8400FFB8, 0xC0004700, 0xC2800200, 0x6EA8E010, 0xCE4000F9, 0xCE4000F9, 0xCE4000F9, 0xCE4000F9,
+ 0x5EA80002, 0x8400FFD8, 0xC0004740, 0xCE4000F8, 0xC0004742, 0xC1000200, 0x5D100002, 0xCD0000F8,
+ 0xC0004744, 0xCE4000F8, 0xC0004746, 0xCE4000F8, 0xC0004748, 0xCE4000F8, 0xC000474A, 0xCE4000F8,
+ 0xC000474C, 0xC1000002, 0xCD0000F8, 0xC000474E, 0xCE4000F8, 0xC0004750, 0xCE4000F8, 0xC0004752,
+ 0xCE4000F8, 0xC0004754, 0xCE4000F8, 0xC0400000, 0xC11C0000, 0xC000082C, 0xCD05CE00, 0xC0000838,
+ 0xCE4000F8, 0xC0000818, 0xCE4000F8, 0xC0000820, 0xCE4000F8, 0xC2804840, 0xC240485A, 0x98C086B0,
+ 0xC68000F8, 0xC65400F8, 0xC1800000, 0xC11C0002, 0xC000082C, 0xCD05CE00, 0x00000000, 0xC121FFFE,
+ 0x5911FE54, 0x14100000, 0xC0000A10, 0xCB8000F8, 0xC0000A12, 0xCB4000F8, 0xC0000A14, 0xCB0000F8,
+ 0xC0000A16, 0xCAC000F8, 0xC0000040, 0xC2800000, 0xCE800000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC2800002,
+ 0xCE800000, 0xC0000A10, 0xCF8000F8, 0xC0000A12, 0xCF4000F8, 0xC0000A14, 0xCF0000F8, 0xC0000A16,
+ 0xCEC000F8, 0xC1000000, 0xC00048A0, 0xCD0000F8, 0xC00048A2, 0xCD0000F8, 0xC0001AF2, 0xC1000000,
+ 0xCD002100, 0x80001038, 0x00000000, 0xC3C00000, 0xDCFC2000, 0x5FFC0002, 0x00000000, 0x98C08D62,
+ 0xC0004730, 0xC94000F8, 0xC0004732, 0x800033D8, 0x00000000, 0xC3C00000, 0xDCFC2000, 0x5FFC0002,
+ 0x00000000, 0x98C08D62, 0xC0004730, 0xC94000F8, 0xC0004732, 0xC0004810, 0xC90000F8, 0xC000474A,
+ 0xC94000F8, 0xA50007E8, 0x00000000, 0x5D140002, 0x840007D2, 0xC1000000, 0xC000484A, 0xC90000F8,
+ 0xC0004740, 0xC84000F8, 0x5D100000, 0x84000798, 0x00000000, 0x00000000, 0xC121FFFE, 0x5911FEF4,
+ 0x14100000, 0xC0004744, 0xC88000F8, 0xC0001AF0, 0xC3000000, 0x58000002, 0xCB010038, 0x6C7C2000,
+ 0x5BFC4300, 0x98C08A88, 0xC1400000, 0xC4540020, 0x6C40A010, 0x5D240002, 0x8400021A, 0x00000000,
+ 0xC0004742, 0xCA8000F8, 0x00000000, 0x00000000, 0x59280002, 0x6D130000, 0x6D130010, 0x45048000,
+ 0x84000692, 0x00000000, 0x98C08870, 0xC45400F8, 0xC69800F8, 0xC241FFFE, 0xC67400F8, 0x5D35FFFE,
+ 0x84000652, 0x47448000, 0x84000642, 0xC1000000, 0x6F502000, 0xC0004300, 0x40100000, 0xC1400000,
+ 0x58000000, 0xC9410038, 0xC1800000, 0xC0004814, 0xC9820038, 0x4714A000, 0xC10001FE, 0x4150A004,
+ 0x45588000, 0x880005CA, 0x4744C000, 0xC1000200, 0x4190C004, 0xC000473E, 0xC90000F8, 0x00000000,
+ 0x00000000, 0x41188000, 0xCD0000F8, 0xC000471C, 0xC90000F8, 0x00000000, 0x00000000, 0x41188000,
+ 0xCD0000F8, 0x98C087E8, 0xC45400F8, 0x6C58A010, 0xC0004700, 0x58440002, 0x6C470000, 0x6C470010,
+ 0x44748000, 0x8400FFC0, 0xC74400F8, 0xC0004740, 0xCC4000F8, 0xC0800000, 0xC0004744, 0xCC8000F8,
+ 0x800004D0, 0xC1000000, 0x583C0000, 0xC9000038, 0x00000000, 0x00000000, 0x44908000, 0x88000280,
+ 0xC1400000, 0x583C0000, 0xC9410038, 0xC1800000, 0xC0004814, 0xC9800038, 0x4714A000, 0xC10001FE,
+ 0x4150A004, 0x45588000, 0x88000442, 0xC3800000, 0x583C0002, 0xCB820078, 0xC1000000, 0x583C0002,
+ 0xC9000078, 0x00000000, 0x00000000, 0x47908000, 0x8400024A, 0xC0400002, 0xC0800000, 0xC3C00000,
+ 0xC000481A, 0xC80000F8, 0x6F908000, 0x45388000, 0x45388000, 0x4011E000, 0xC000491E, 0xCFC000F8,
+ 0xC3400000, 0xC0004878, 0xC80400F8, 0x6C908000, 0x45088000, 0x45088000, 0x40100000, 0xCAC000F8,
+ 0xC43000F8, 0x00000000, 0xC7340060, 0xC1000002, 0xC5341B00, 0xC100001C, 0xC5341048, 0xC100000C,
+ 0xC5340D10, 0xC000491C, 0xCF4000F8, 0xC3000000, 0xDF700038, 0x5D300080, 0x8800FFE8, 0xC000474A,
+ 0xC1000002, 0xCD0000F8, 0xC000491C, 0xCB4000F8, 0xC000491E, 0xCBC000F8, 0x99007F18, 0xDB5800F8,
+ 0xDBD800F9, 0x00000000, 0xC1400000, 0xC794A030, 0xC1800000, 0xC7980020, 0x58144200, 0xC9C000F8,
+ 0xC1210000, 0x69188010, 0x7D008000, 0x75D0E000, 0xCDC000F8, 0x80000228, 0x00000000, 0xC1000000,
+ 0x583C0000, 0xC903E000, 0x00000000, 0x00000000, 0x5D100000, 0x84000042, 0xC0004734, 0xC90000F8,
+ 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0x800000C0, 0xC1400000, 0x583C0000, 0xC9410038,
+ 0xC1800000, 0xC0004814, 0xC9820038, 0x4714A000, 0xC10001FE, 0x4150A004, 0x45588000, 0x8800015A,
+ 0xC000473E, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0xC000471C, 0xC90000F8,
+ 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0xC3800000, 0x583C0002, 0xCB820078, 0x00000000,
+ 0x00000000, 0x5D39FFFE, 0x84000062, 0xC1400000, 0xC794A030, 0xC1800000, 0xC7980020, 0x58144200,
+ 0xC9C000F8, 0xC1210000, 0x69188010, 0x7D008000, 0x75D0E000, 0xCDC000F8, 0x98C087E8, 0xC45400F8,
+ 0x6C58A010, 0xC0004700, 0x58440002, 0x6C470000, 0x6C470010, 0xC0004740, 0xCC4000F8, 0xC0800000,
+ 0xC0004744, 0xCC8000F8, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000, 0x8000F288, 0x00000000,
+ 0x00000000, 0x98C086F0, 0xC0004748, 0xC98000F8, 0xC2000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xC1400000, 0xC7D4A030, 0xC1800000, 0xC7D80020, 0x58144200,
+ 0xC9C000F8, 0xC1210000, 0x69188010, 0x7D008000, 0x75D0E000, 0xCDC000F8, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x98C087E8, 0xC7D400F8, 0x6FD8A010, 0xC0004700, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x98C08870, 0xC7D400F8, 0xC79800F8, 0xC241FFFE, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x98C08A88, 0xC1400000, 0xC7D40020, 0x6FC0A010,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x98C08AB8, 0xC1400000, 0xC7D40020, 0x6FC0A010,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x98C08AF0, 0xC7D400F8, 0xC0004740, 0xC9C000F8,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x98C08BE0, 0xC7D400F8, 0xC0004742, 0xC98000F8,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC0004958, 0xC84000F8, 0x00000000, 0xC3C00002,
+ 0x787C2000, 0xCC4000F8, 0xC0004848, 0xCB8400F8, 0xC000495C, 0xCAC400F8, 0xC0004844, 0xC88400F8,
+ 0x47AD0000, 0x8400F492, 0xC000487C, 0xC80400F8, 0x00000000, 0x00000000, 0x40080000, 0xCA0000F8,
+ 0xC0001624, 0xCB0400F8, 0xA63C007A, 0x00000000, 0x00000000, 0xA71EF432, 0x00000000, 0xC0000824,
+ 0xCA8400F8, 0x6CA08000, 0x6CA42000, 0x46250000, 0x42290000, 0xC35E0002, 0xC6340060, 0xC0001624,
+ 0xCF440078, 0xC2000000, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xC0004844, 0xC88400F8, 0xC000082C, 0xCA040038, 0x00000000, 0x00000000, 0x58880002,
+ 0xB6080018, 0x00000000, 0xC0800000, 0xC0004844, 0xCC840038, 0x5AEC0002, 0xC000495C, 0xCEC400F8,
+ 0x5E6C0006, 0x84000060, 0xC0004848, 0xCB8400F8, 0xC0000838, 0xC2500002, 0xCE450800, 0x5FB80002,
+ 0xC0004848, 0xCF8400F8, 0x5EEC0002, 0xC000495C, 0xCEC400F8, 0x00000000, 0xC121FFFE, 0x5911FE54,
+ 0x14100000, 0x8000F290, 0xC000495A, 0xC84000F8, 0x00000000, 0xC3C00002, 0x787C2000, 0xCC4000F8,
+ 0xC0004960, 0xCAC400F8, 0x00000000, 0x00000000, 0x5EEC0000, 0x8400010A, 0x00000000, 0xB6FC0050,
+ 0xC0001600, 0xCA0400F8, 0x00000000, 0x00000000, 0xA61E00D2, 0x6FE90000, 0xC0000A28, 0xCE850800,
+ 0xC2C00000, 0xC2800004, 0xB6E800A0, 0xC0001604, 0xCA8400F8, 0xC0004960, 0xCEC400F8, 0xA69EFCAA,
+ 0x00000000, 0x6FE90000, 0xC0000A28, 0xCE850800, 0xC2C00002, 0xC0001600, 0xCA0400F8, 0x00000000,
+ 0x00000000, 0xA61E002A, 0x6FE90000, 0xC0000A28, 0xCE850800, 0xC2C00000, 0xC0001604, 0xCA8400F8,
+ 0xC0004960, 0xCEC400F8, 0xA69EFC12, 0xC2400000, 0xC0000A14, 0xCA440028, 0x00000000, 0x00000000,
+ 0x466D2000, 0xA4400020, 0xC2800000, 0xDFEB0029, 0x80000010, 0xDFEA0029, 0xB668EC0A, 0x00000000,
+ 0xC00048A0, 0xCB0400F8, 0xC0000A10, 0xCA8400F8, 0x6F208000, 0x6F242000, 0x46250000, 0x42A10000,
+ 0xC2400000, 0xC0000A14, 0xCA440028, 0xC35E0002, 0xC6340060, 0xC0001604, 0xCF440078, 0x5B300002,
+ 0xB6700018, 0x5AEC0002, 0xC3000000, 0xC00048A0, 0xCF0400F8, 0xC0004960, 0xCEC400F8, 0x8000F030,
+ 0xC0004918, 0xD28000F8, 0xC2000000, 0xDF600038, 0x5E600080, 0x840002A2, 0x00000000, 0xC161FFFE,
+ 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC000480A, 0xCA0000F8,
+ 0xC0004912, 0xCA4000F8, 0xC0004924, 0xCA8000F8, 0xC0004966, 0xCAC000F8, 0x00000000, 0xC121FFFE,
+ 0x5911FE54, 0x14100000, 0x76250000, 0x76290000, 0x762D0000, 0x840001E2, 0xC0004918, 0xCA4000F8,
+ 0xC28001FE, 0x76290000, 0x5A640002, 0x6A254010, 0x5EE80000, 0x8400001A, 0x6AA54000, 0x80000010,
+ 0xC62800F8, 0x62818008, 0xC0004918, 0xCF0000F8, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xC0004966, 0xCA4000F8, 0xC2000002, 0x6A310000, 0x7E010000,
+ 0x76612000, 0xCE4000F8, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000, 0x6F346000, 0x4771A000,
+ 0x5B744C80, 0xC2800000, 0x58340006, 0xCA800078, 0xC2C00000, 0x58340000, 0xCAC000D8, 0xC2400000,
+ 0x5834000A, 0xCA420078, 0x6EA82000, 0x42E9E000, 0x6F2CA000, 0x42E56000, 0x5AEC2E00, 0xC3990040,
+ 0xC7381C18, 0xC6F80060, 0x99007F18, 0xDB9800F8, 0xDBD800F9, 0x00000000, 0xDEA000F8, 0x46310000,
+ 0x8400FD50, 0xC0004958, 0xC84000F8, 0x00000000, 0xC1000002, 0x78502000, 0xCC4000F8, 0xC0004848,
+ 0xCBC400F8, 0xC0004844, 0xC88400F8, 0x5FFC0000, 0x8400ECBA, 0xC0004740, 0xCB0000F8, 0xC0004744,
+ 0xCAC000F8, 0x6F282000, 0x5AA84300, 0xC000487C, 0xC80400F8, 0x00000000, 0x00000000, 0x40080000,
+ 0xCA4000F8, 0xC40000F8, 0x00000000, 0xC0004878, 0xC80400F8, 0x6C908000, 0x45088000, 0x45088000,
+ 0x40100000, 0xC90000F8, 0xC43400F8, 0x00000000, 0x5C440000, 0x840000A2, 0x00000000, 0xC00047D2,
+ 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0x58340002, 0xC9000078, 0x00000000,
+ 0x00000000, 0x58280002, 0x6D120000, 0xCD021078, 0x5AEC0002, 0xC0004744, 0xCEC000F8, 0x80000630,
+ 0x00000000, 0xC00047C0, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0xA67C0048,
+ 0xC00047C2, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0x80001E18, 0x00000000,
+ 0xA6600042, 0xC00047C4, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0x80000570,
+ 0xC00047C6, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0xC3C00000, 0xC67D0038,
+ 0xC3800000, 0xC6780038, 0x47F08000, 0x840000A8, 0x47AC8000, 0x84000098, 0xC1000000, 0xC0004814,
+ 0xC9000038, 0x00000000, 0x00000000, 0x5D100000, 0x840000F0, 0x5AEC0002, 0xC0004744, 0xCEC000F8,
+ 0xC00047CA, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0x80000478, 0x00000000,
+ 0x98C08AF0, 0xC7D400F8, 0xC0004740, 0xC9C000F8, 0x5D240000, 0x8400006A, 0x00000000, 0x98C087E8,
+ 0xC7D400F8, 0x6FD8A010, 0xC0004700, 0xC00047C8, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002,
+ 0xCD0000F8, 0x80001C40, 0xC00047CC, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8,
+ 0x6FE82000, 0x5AA84300, 0x5D380000, 0x840000A0, 0x00000000, 0x98C086F0, 0xC0004748, 0xC98000F8,
+ 0xC2000000, 0x58280002, 0x6E520000, 0xCD021078, 0x58280002, 0xCE400078, 0x5D25FFFE, 0x84000040,
+ 0xC00047D0, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0x800002D0, 0xC3000000,
+ 0x58280002, 0xCB000078, 0x00000000, 0x00000000, 0x5D31FFFE, 0x84000048, 0xC00047D0, 0xC90000F8,
+ 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0x80000260, 0x00000000, 0x98C086F0, 0xC0004748,
+ 0xC98000F8, 0xC2000000, 0x58340002, 0xC6500078, 0xC7D01038, 0xC7901838, 0xCD0000F8, 0x58280002,
+ 0xCE400078, 0xC3C00200, 0x5FFC001C, 0xC3800000, 0xDF790048, 0x00000000, 0x00000000, 0x47F88000,
+ 0x8800FFDA, 0xC0004862, 0xCBC000F8, 0xC0000000, 0xC76C00F8, 0x5BBC7800, 0xC280001C, 0xCA6C00F9,
+ 0x00000000, 0x00000000, 0xCE7800F9, 0xC1007A00, 0x45388000, 0xC1007800, 0xC53800FE, 0x5EA80002,
+ 0x8400FFB8, 0xC3800000, 0xC000481A, 0xC80000F8, 0x6F108000, 0x45308000, 0x45308000, 0x4011C000,
+ 0xC000491E, 0xCF8000F8, 0xC2C00000, 0xC7EC0060, 0xC100001C, 0xC52C1048, 0xC100000A, 0xC52C0D10,
+ 0xC000491C, 0xCEC000F8, 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420048, 0xC2800000, 0xDF680038,
+ 0x5D280080, 0x8800FFE8, 0xC000491C, 0xCAC000F8, 0xC000491E, 0xCB8000F8, 0x99007F18, 0xDAD800F8,
+ 0xDB9800F9, 0x00000000, 0xC00047CE, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8,
+ 0x00000000, 0x80001880, 0x00000000, 0x00000000, 0x00000000, 0xC0004878, 0xC80400F8, 0x6C908000,
+ 0x45088000, 0x45088000, 0x40100000, 0xCA0000F8, 0xC42400F8, 0x00000000, 0xC0004934, 0xCE0000F8,
+ 0xC2800002, 0xC4681C08, 0xC62821D0, 0xC6281E00, 0xC2600010, 0x5A650060, 0xC0004800, 0xCB4000F8,
+ 0xC2200400, 0x5A200020, 0xC7601040, 0xC0001220, 0xCE8000F8, 0xC0001200, 0xCE4000F8, 0xC0001202,
+ 0xCE0000F8, 0xC0001240, 0xCB4000F8, 0x00000000, 0x00000000, 0xA754FFE0, 0xC2000000, 0xC7600040,
+ 0xA7520042, 0x00000000, 0x00000000, 0x99008690, 0xC0004822, 0xC94000F8, 0xC1800002, 0x80001710,
+ 0x582040A0, 0xC2000000, 0xCA000018, 0xC2400000, 0xCA414000, 0xC2800000, 0xCA812000, 0xC2C00000,
+ 0xCAC20018, 0xC0004938, 0xCE0000F8, 0xC0004920, 0xCE4000F8, 0xC0004916, 0xCE8000F8, 0xC0004922,
+ 0xCEC000F8, 0xA6400558, 0x00000000, 0xC0004938, 0xCBC000F8, 0x00000000, 0xC3800000, 0x6FF48000,
+ 0x6FD44000, 0x4355A000, 0x5B744A00, 0x58340000, 0xCB802010, 0x00000000, 0xC2000000, 0x6FB46000,
+ 0x4779A000, 0x5B744C80, 0x5834000C, 0xCA000020, 0xC000491A, 0xCF8000F8, 0x5E200000, 0x84000482,
+ 0xC2000000, 0xDF610048, 0x5E6001E8, 0x8800FFE8, 0xC2000002, 0xC2400466, 0xC2A00000, 0x5AA80000,
+ 0xC0001006, 0xCE0000F8, 0xC0001008, 0xCE4000F8, 0xC000100A, 0xCE8000F8, 0x99007958, 0xC1A0FFFE,
+ 0xC0000824, 0xC9840060, 0xC0004934, 0xCA4000F8, 0xC2000000, 0xC2800002, 0x99007998, 0xDA9800F8,
+ 0xC61400F8, 0xC65800F8, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x99007A80, 0xC000491A, 0xC94000F8, 0x00000000, 0x00000000, 0xC121FFFE, 0x5911FE54,
+ 0x14100000, 0xC0004922, 0xCA001118, 0xC3C00000, 0xC3800000, 0xC0004930, 0xCE023118, 0xC0004932,
+ 0xCBC000D8, 0xC2800000, 0xC000491E, 0xCFC000F8, 0xC0004862, 0xCA800060, 0xC3A0001A, 0x5BB94000,
+ 0xC6B80060, 0xC000491C, 0xCF8000F8, 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420048, 0x00000000,
+ 0x00000000, 0x00000000, 0xA8E2FFE8, 0xC2000000, 0xC1220002, 0xD90C00F8, 0xDF600038, 0x5E600080,
+ 0x8400FFF2, 0xC000491C, 0xCA0000F8, 0xC000491E, 0xCA4000F8, 0x00000000, 0x00000000, 0x99007F18,
+ 0xDA1800F8, 0xDA5800F9, 0x00000000, 0xC2000000, 0xDF610048, 0x5E6001FE, 0x8800FFE8, 0xC0004916,
+ 0xCA8000F8, 0xC2C00000, 0xDFEC0048, 0xC2400000, 0x466D2000, 0x8400004A, 0x5EA80000, 0x8400003A,
+ 0xC2600002, 0x99008690, 0xC000482E, 0xC94000F8, 0xC1800002, 0x80000030, 0xC2600000, 0x99008690,
+ 0xC000482C, 0xC94000F8, 0xC1800002, 0xC2000068, 0xC6240078, 0xC0004930, 0xCE400080, 0xC000491A,
+ 0xC98000F8, 0xC0004862, 0xC94000F8, 0x6D9C6000, 0x45D8E000, 0x59DC4C80, 0x99007D78, 0xD95800F8,
+ 0xD99800F9, 0xD9D400F8, 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420048, 0xC2000000, 0xDF600038,
+ 0x5E600080, 0x8400FFEA, 0x00000000, 0xC000491C, 0xCA0000F8, 0xC000491E, 0xCA4000F8, 0x00000000,
+ 0x00000000, 0x99007F18, 0xDA1800F8, 0xDA5800F9, 0x00000000, 0x80001160, 0x00000000, 0x99008690,
+ 0xC000482A, 0xC94000F8, 0xC1800002, 0x80001130, 0xC0004938, 0xCBC000F8, 0x00000000, 0x00000000,
+ 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB84A00, 0x58380008, 0xCA0000F8, 0x00000000, 0x00000000,
+ 0xA600039A, 0x00000000, 0xC0004938, 0xCBC000F8, 0xC3000000, 0x00000000, 0x6FF88000, 0x6FD44000,
+ 0x4395C000, 0x5BB84A00, 0x58380000, 0xCB002010, 0xC2000000, 0x58380008, 0xCA020078, 0x5838000C,
+ 0xCAC000F8, 0x5838000E, 0xCA4000F8, 0xC000491A, 0xCF0000F8, 0xC0004930, 0xCEC000F8, 0xC000493C,
+ 0xCE0000F8, 0xC0004932, 0xCE4000F8, 0x5E200000, 0x84000138, 0xC2800000, 0xA6FE00D2, 0x6F206000,
+ 0x46310000, 0x5A204C80, 0x5820000C, 0xCA800020, 0x00000000, 0x00000000, 0x5EA80000, 0x8400020A,
+ 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x99007A80, 0xC000491A, 0xC94000F8, 0x00000000, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000,
+ 0xC0004930, 0xCAC000F8, 0xC0004932, 0xCA4000F8, 0xC7EC1118, 0xC0004930, 0xCEC000F8, 0x5838000C,
+ 0xCEC000F8, 0x58000002, 0xCE4000F8, 0xC0004934, 0xCA0000F8, 0xC2400002, 0x6E642000, 0x6E642000,
+ 0x76612000, 0x8400002A, 0xC2400002, 0x6E684000, 0x58380008, 0xCE804200, 0xA6000020, 0x6E682000,
+ 0x58380008, 0xCE802100, 0xC2400002, 0x6E642000, 0x76612000, 0x840000EA, 0x58380008, 0xCA0000F8,
+ 0xC2800000, 0xC2400000, 0xA60200C0, 0xDBA800F8, 0x6F386000, 0x47B1C000, 0x5BB84C80, 0x58380004,
+ 0xCA400078, 0x58380002, 0xCA800078, 0x00000000, 0xDEB800F8, 0x46A54000, 0x88000060, 0x00000000,
+ 0xC0004824, 0xCA0000F8, 0xC2400002, 0x6E640000, 0x5A200002, 0xCE0000F8, 0x58380008, 0xCE400000,
+ 0x80000018, 0x00000000, 0x80000048, 0xC0004934, 0xCA0000F8, 0x00000000, 0x00000000, 0xA6020CCA,
+ 0x00000000, 0x00000000, 0x80000CF8, 0xC2800000, 0xC2000200, 0xC240001A, 0xDF690048, 0x46294000,
+ 0x46A54000, 0x8800FFD2, 0xC2000006, 0xC2600982, 0x5A643B6E, 0x5838000A, 0xCA8000F8, 0xC0001006,
+ 0xCE0000F8, 0xC0001008, 0xCE4000F8, 0xC000100A, 0xCE8000F8, 0x99007958, 0xC1A0FFFE, 0xC0000824,
+ 0xC9840060, 0xC2000000, 0xC0004930, 0xCA02E008, 0x58380026, 0xCA4000F8, 0x00000000, 0xC2800000,
+ 0x99007998, 0xDA9800F8, 0xC61400F8, 0xC65800F8, 0xC0004934, 0xCA0000F8, 0x00000000, 0x00000000,
+ 0xA6020022, 0x00000000, 0x00000000, 0x80000318, 0xC0004938, 0xCBC000F8, 0xC0004878, 0xC80400F8,
+ 0x6C908000, 0x45088000, 0x45088000, 0x40100000, 0xCA0000F8, 0xC42400F8, 0x00000000, 0x58240018,
+ 0xCA0000F8, 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB84A00, 0xC3000000, 0xC3400002, 0xC2C00000,
+ 0xC62C0078, 0xC6270038, 0xC0004940, 0xCE400038, 0xC6260038, 0xC0004942, 0xCE400038, 0xC000493C,
+ 0xCA0000F8, 0x5EEC0000, 0x8400018A, 0x5A6C0010, 0x46254000, 0x88000190, 0x5A600052, 0x46E54000,
+ 0x88000178, 0x58380006, 0xCA8000F8, 0xC0004940, 0xCA0000F8, 0xC2400000, 0xC6A70038, 0x7E412000,
+ 0x76612000, 0xC2000000, 0xC6A10038, 0x46250000, 0x84000138, 0xC0004942, 0xCA0000F8, 0xC2400000,
+ 0xC6A60038, 0x7E412000, 0x76612000, 0xC2000000, 0xC6A00038, 0x58380002, 0xCA8000F8, 0x46250000,
+ 0x840000E8, 0xC2400000, 0xC6A60078, 0x466D0000, 0x880000DA, 0xC2400000, 0xC6A40078, 0x58380008,
+ 0xCA8000F8, 0x46E50000, 0x880000BA, 0x00000000, 0xA6820018, 0x00000000, 0xC7700B00, 0xA6840098,
+ 0x00000000, 0xC7700A00, 0x80000080, 0xC7700200, 0xC000493C, 0xCAC000F8, 0x80000060, 0xC7700300,
+ 0xC000493C, 0xCAC000F8, 0x80000040, 0xC7700900, 0x80000030, 0xC7700800, 0x80000020, 0xC7700700,
+ 0x80000010, 0xC7700500, 0xC0004944, 0xCF0000F8, 0xC000493E, 0xCEC000F8, 0xC0004938, 0xCA4000F8,
+ 0xC000493C, 0xCB8000F8, 0xC000493E, 0xCB4000F8, 0xC3000000, 0x6E608000, 0x6E544000, 0x42150000,
+ 0x5A204A00, 0x5AA00008, 0x58200004, 0xCB000078, 0xC0004934, 0xCA0000F8, 0xC2400000, 0xC0004930,
+ 0xCA42E008, 0xC3C00018, 0xA6020098, 0x00000000, 0x43656000, 0x47AD0000, 0x88000050, 0x46F96000,
+ 0x6EE04010, 0x5BE00004, 0xC2000000, 0xC6E00008, 0x5E200000, 0x84000042, 0x5BFC0002, 0x80000030,
+ 0xC3C00004, 0x5A2C0008, 0x47A10000, 0x88000012, 0x5FB80008, 0x6FE04000, 0x42390000, 0x47212000,
+ 0x88000068, 0xC2400000, 0xC0004930, 0xCA42E008, 0xC2060002, 0xC68000F8, 0xCE006300, 0x6FE04000,
+ 0x4721C000, 0x5F700010, 0x4765A000, 0xC2000000, 0xC6340008, 0xC25A000A, 0xC000491A, 0xCA401C18,
+ 0xC2800000, 0xC0004932, 0xCA8000D8, 0xC0004862, 0xCA400060, 0x6FA04010, 0x42290000, 0xC000491E,
+ 0xCE0000F8, 0xC7E41048, 0xC000491C, 0xCE4000F8, 0x6FE04000, 0x43A1C000, 0xC000493C, 0xCF8000F8,
+ 0xC000493E, 0xCF4000F8, 0xC000493A, 0xCFC000F8, 0x80000008, 0x00000000, 0x00000000, 0x00000000,
+ 0xC2000000, 0xDCE000F8, 0xA622FFD8, 0xC1220002, 0xD90C00F8, 0xC0004938, 0xCBC000F8, 0xC0004944,
+ 0xCB4000F8, 0xC0004862, 0xCB0000F8, 0xC0004934, 0xCA0000F8, 0x6FF88000, 0x6FD44000, 0x4395C000,
+ 0x5BB84A00, 0xA6020298, 0xC2400000, 0x58380008, 0xCA406000, 0xDFE800F8, 0xC2218E08, 0x5A21BAF6,
+ 0x46A14000, 0x84000022, 0xC2080002, 0x7361A000, 0x80000058, 0x5E640000, 0x84000022, 0xC20C0002,
+ 0x7361A000, 0x80000030, 0xC2000000, 0xC760E710, 0xC7604218, 0x5E200000, 0x840002A2, 0xC2200002,
+ 0xC0004930, 0xCE021000, 0x99008690, 0xC0004828, 0xC94000F8, 0xC1800002, 0xC0004780, 0xC93C00F8,
+ 0x00000000, 0x00000000, 0x59100002, 0xCD3C00F8, 0x58380000, 0xCA0000F8, 0x00000000, 0x00000000,
+ 0xA6000132, 0xC0004940, 0xCA8000F8, 0xC0004942, 0xCA4000F8, 0xC7600078, 0xC6A01838, 0xC6601038,
+ 0xC000493A, 0xCA4000F8, 0xC0004934, 0xCA8000F8, 0xC0007800, 0x40300000, 0x40240000, 0x5C000004,
+ 0x5EC07A00, 0x88000012, 0x5C000200, 0xCE0000F8, 0x58000002, 0x5EC07A00, 0x88000012, 0x5C000200,
+ 0xCE8000F8, 0xC000493E, 0xCA0000F8, 0xC2400000, 0x5838000C, 0xCE4000F8, 0x99008690, 0xC0004830,
+ 0xC94000F8, 0xC61800F8, 0xC0004930, 0xC6100078, 0xCD000078, 0x800000A8, 0xC2400002, 0x58380008,
+ 0xCE400000, 0xC0004944, 0xCF4000F8, 0x800002A8, 0xC000493C, 0xCA4000F8, 0xDFE800F8, 0x5A300018,
+ 0xC0007800, 0x40200000, 0xCA0000F8, 0x58380008, 0xC6501078, 0xCD021078, 0x5838000A, 0xCE8000F8,
+ 0x58380026, 0xCE0000F8, 0xC0004944, 0xCF4000F8, 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420048,
+ 0x80000068, 0x00000000, 0x99008690, 0xC0004826, 0xC94000F8, 0xC1800002, 0xC0004760, 0xC93C00F8,
+ 0x00000000, 0x00000000, 0x59100002, 0xCD3C00F8, 0x8000FDA8, 0xC2000000, 0xC2400080, 0xDF600038,
+ 0xB624FFEA, 0xC000491C, 0xCA4000F8, 0xC000491E, 0xCA8000F8, 0x99007F18, 0xDA5800F8, 0xDA9800F9,
+ 0x00000000, 0xC0004934, 0xCA0000F8, 0x00000000, 0xC2800000, 0xA6020160, 0xC2400004, 0xC2000200,
+ 0xDF690048, 0x46294000, 0x46A54000, 0x8800FFDA, 0x00000000, 0xC000491A, 0xC98000F8, 0xC0004862,
+ 0xC94000F8, 0x6D9C6000, 0x45D8E000, 0x59DC4C80, 0x99007D78, 0xD95800F8, 0xD99800F9, 0xD9D400F8,
+ 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420048, 0xC2000000, 0xC2400080, 0xDF600038, 0xB624FFEA,
+ 0xC000491C, 0xCA4000F8, 0xC000491E, 0xCA8000F8, 0x99007F18, 0xDA5800F8, 0xDA9800F9, 0x00000000,
+ 0x58380008, 0xCA4000F8, 0xC2000000, 0xCE000018, 0xC2A1FFFE, 0x5AA9FFFE, 0xCE021078, 0x5838000A,
+ 0xCE8000F8, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0000838, 0xC2500002, 0xCE450800, 0xC0004848, 0xCBC400F8, 0xC3800000, 0xC000082C, 0xCB840028,
+ 0x5FFC0002, 0xC0004848, 0xCFC400F8, 0x58880002, 0x47888000, 0xC1000000, 0xC50800FE, 0xC0004844,
+ 0xCC8400F8, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000, 0x8000CBF0, 0xC2000000, 0xDF600038,
+ 0x5E200080, 0x8400029A, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xC000480C, 0xCA0000F8, 0xC0004910, 0xCA4000F8, 0xC000492C, 0xCA8000F8,
+ 0xC0004968, 0xCAC000F8, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000, 0x76250000, 0x76290000,
+ 0x76E16000, 0x840001DA, 0xC0004926, 0xCA4000F8, 0xC201FFFE, 0x76E16000, 0x5A640002, 0x6AE50010,
+ 0x5F200000, 0x8400001A, 0x6A250000, 0x80000010, 0xC6E000F8, 0x62014008, 0xC0004926, 0xCE8000F8,
+ 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC0004968,
+ 0xCA4000F8, 0xC2000002, 0x6A290000, 0x7E010000, 0x76612000, 0xCE4000F8, 0x00000000, 0xC121FFFE,
+ 0x5911FE54, 0x14100000, 0x6EB4A000, 0x6E944000, 0x4755A000, 0x4769A000, 0x5B747000, 0x58340002,
+ 0xC2000000, 0xCA0000D8, 0x5834002E, 0xC2400000, 0xCA400078, 0x6EB0A000, 0x6EBC4000, 0x473D8000,
+ 0x47298000, 0x5B30302E, 0x5B300004, 0x6E642000, 0x4225E000, 0xC39A8024, 0xC7380060, 0xC6B81C18,
+ 0x99007F18, 0xDB9800F8, 0xDBD800F9, 0x00000000, 0xC2000000, 0xDF600038, 0x5E200080, 0x840002D2,
+ 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC000490E, 0xCA0000F8, 0xC000492A, 0xCA4000F8, 0xC000496A, 0xCB0000F8, 0xC0004956, 0xCAC000F8,
+ 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000, 0x77218000, 0x77258000, 0x8400021A, 0xC201FFFE,
+ 0x77218000, 0x5AEC0002, 0x6B2D0010, 0x5EA00000, 0x8400001A, 0x6A2D0000, 0x80000010, 0xC72000F8,
+ 0x62016008, 0xC0004956, 0xCEC000F8, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xC000496A, 0xCA4000F8, 0xC2000002, 0x6A2D0000, 0x7E010000, 0x76612000,
+ 0xCE4000F8, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000, 0x6EF4A000, 0x6ED44000, 0x4755A000,
+ 0x476DA000, 0x5B747000, 0x5834000E, 0xC2000000, 0xCA0000D8, 0x58340008, 0xC2400000, 0xCA420078,
+ 0x5834000C, 0xC2800000, 0xCA832010, 0x6E644010, 0x42250000, 0x4229E000, 0xC39A8008, 0x58340008,
+ 0xCB809018, 0x58340008, 0xC2800000, 0xCA810010, 0x6EE0A000, 0x6EE44000, 0x46250000, 0x462D0000,
+ 0x5A200008, 0x5A203008, 0x42290000, 0xC6380060, 0xC6F81C18, 0x99007F18, 0xDB9800F8, 0xDBD800F9,
+ 0x00000000, 0xC000495A, 0xC84000F8, 0x00000000, 0xC3C00002, 0x787C2000, 0xCC4000F8, 0xC0001A1C,
+ 0xCA0000F8, 0xC2400008, 0x6A452000, 0x76250000, 0x84000E9A, 0xC0000A28, 0xC3800000, 0xCB840028,
+ 0xC0000A14, 0xC3400000, 0xCB440028, 0xC0004880, 0xCB0400F8, 0x47B48000, 0x88000E48, 0x58041802,
+ 0xCAC000F8, 0xA7000060, 0x00000000, 0x00000000, 0xA6C8C5C8, 0xC2800000, 0xC6E80018, 0x80000070,
+ 0x00000000, 0x00000000, 0x00000000, 0x8000C590, 0x00000000, 0xC2800000, 0xC7282018, 0xC000490E,
+ 0xCA4000F8, 0x6BE9E000, 0x00000000, 0x767D2000, 0x8400C548, 0x6EA0A000, 0x6E944000, 0x46150000,
+ 0x46290000, 0x5A207000, 0x5820000C, 0xCA0000F8, 0xC0004946, 0xCE8000F8, 0xA6220398, 0x00000000,
+ 0xC2200060, 0xC0004948, 0xCE000008, 0xCE021038, 0xC240000A, 0xC000494A, 0xCE4000F8, 0xC2B60002,
+ 0xC0004964, 0xCE837B00, 0x990081E8, 0xC00048A0, 0xC88400F8, 0x00000000, 0xC0004946, 0xCBC000F8,
+ 0x00000000, 0x00000000, 0x6FF8A000, 0x6FD44000, 0x4795C000, 0x47BDC000, 0x5BB87000, 0x99007FA8,
+ 0xDBD800F8, 0xDB9800F9, 0x00000000, 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420048, 0xC000491C,
+ 0x990081A0, 0xC94000F9, 0xC98000F8, 0x00000000, 0x99007F18, 0xD95800F8, 0xD99800F9, 0x00000000,
+ 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x99007BE0,
+ 0xDBD800F8, 0xDB9800F9, 0xC7D800F8, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000, 0x6FF8A000,
+ 0x6FD44000, 0x4795C000, 0x47BDC000, 0x5BB87000, 0x58380010, 0xCA0000F8, 0xC0004874, 0xC80400F8,
+ 0x6C908000, 0x45088000, 0x45088000, 0x40100000, 0xCA4000F8, 0xC43400F8, 0x00000000, 0xC74000F8,
+ 0xCE0000F8, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC000490E, 0xCA4000F8, 0xC2800002, 0x6ABD4000, 0x72692000, 0xCE4000F8, 0x00000000, 0xC121FFFE,
+ 0x5911FE54, 0x14100000, 0x99008690, 0xC0004836, 0xC94000F8, 0xC1800002, 0x00000000, 0x00000000,
+ 0x00000000, 0xA8E2FFE8, 0x00000000, 0xC1220002, 0xD90C00F8, 0xC2000000, 0xC0000A14, 0xCA040028,
+ 0xC0000A28, 0xC2500002, 0xCE450800, 0x58880002, 0xB6080018, 0xC00048A0, 0xC0800000, 0xCC8400F8,
+ 0x8000C168, 0xC0004946, 0xCBC000F8, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xC000490E, 0xCA4000F8, 0xC2800002, 0x6ABD4000, 0x72692000, 0xCE4000F8,
+ 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000, 0x6FF8A000, 0x6FD44000, 0x4795C000, 0x47BDC000,
+ 0x5BB87000, 0x58380008, 0xCA0000F8, 0x5838000C, 0xCA4000F8, 0xC3400000, 0xC6340000, 0xC000494E,
+ 0xCF4000F8, 0xC2800000, 0xC62A0078, 0xC3000000, 0xC6308018, 0x6F304000, 0x43298000, 0xC000493C,
+ 0xCF0000F8, 0xC2C00000, 0xC66C0078, 0xC0004950, 0xCEC000F8, 0xC2800000, 0xC66AE020, 0xC0004954,
+ 0xCE8000F8, 0x5F740000, 0x840001B8, 0x5E300028, 0x46E12000, 0x84000182, 0x46E12000, 0x8800014A,
+ 0x5E300018, 0x46E12000, 0x8800002A, 0x46E12000, 0x84000042, 0x00000000, 0x800000D8, 0x00000000,
+ 0x99008328, 0xDBD800F8, 0xDB9800F9, 0xC78000F8, 0xC3400002, 0xC000494E, 0xCF4000F8, 0xC161FFFE,
+ 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC000490E, 0xCA4000F8,
+ 0xC2800002, 0x6ABD4000, 0x7E814000, 0x76692000, 0xCE4000F8, 0x00000000, 0xC121FFFE, 0x5911FE54,
+ 0x14100000, 0xC2200060, 0xC0004948, 0xCE021038, 0xC2000000, 0xC000494C, 0xCE0000F8, 0x80000080,
+ 0x00000000, 0x99008328, 0xDBD800F8, 0xDB9800F9, 0xC78000F8, 0x99008528, 0xDBD800F8, 0xDB9800F9,
+ 0xC78000F8, 0xC2200058, 0xC0004948, 0xCE021038, 0xC2000002, 0xC000494C, 0xCE0000F8, 0xC2000006,
+ 0xC0001006, 0xCE0000F8, 0x5838000A, 0xCA4000F8, 0xC2200982, 0x5A203B6E, 0xC0001008, 0xCE0000F8,
+ 0xC000100A, 0xCE4000F8, 0xC0004954, 0xCA8000F8, 0xC200000C, 0xC000494A, 0xCE0000F8, 0xC0004948,
+ 0xCE800008, 0xC2B60000, 0xC0004964, 0xCE8000F8, 0x990081E8, 0xC00048A0, 0xC88400F8, 0x00000000,
+ 0xC0004946, 0xCBC000F8, 0xC000494C, 0xCA0000F8, 0x6FF8A000, 0x6FD44000, 0x4795C000, 0x47BDC000,
+ 0x5BB87000, 0x5E200000, 0x84000112, 0x00000000, 0x99007FA8, 0xDBD800F8, 0xDB9800F9, 0x00000000,
+ 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420048, 0xC000491C, 0x990081A0, 0xC94000F9, 0xC98000F8,
+ 0x00000000, 0x99007F18, 0xD95800F8, 0xD99800F9, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x14140000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x99007BE0, 0xDBD800F8, 0xDB9800F9, 0xC7D800F8,
+ 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000, 0xC000493C, 0xCA8000F8, 0xC000494E, 0xCAC000F8,
+ 0xC3000018, 0xC3400006, 0x5E200000, 0x8400002A, 0xC2800000, 0xC2C00000, 0xC300001E, 0xC3400000,
+ 0xC6AC1078, 0xC72C0418, 0xC76C0810, 0x58380010, 0xCA8000F8, 0x58380008, 0xCEC000F8, 0xC6280100,
+ 0xC0004874, 0xC80400F8, 0x6C908000, 0x45088000, 0x45088000, 0x40100000, 0xCB0000F8, 0xC43400F8,
+ 0x00000000, 0xC74000F8, 0xCE8000F8, 0xC0004952, 0xCE8000F8, 0x00000000, 0x00000000, 0x00000000,
+ 0xA8E2FFE8, 0x00000000, 0xC000494C, 0xCA0000F8, 0xC0004950, 0xCAC000F8, 0x5E200000, 0x8400006A,
+ 0xDFE800F8, 0x7E814000, 0x5834001A, 0xCE8000F8, 0x99008690, 0xC0004834, 0xC94000F8, 0xC1800002,
+ 0x99008690, 0xC0004838, 0xC94000F8, 0xC6D800F8, 0xC1220002, 0xD90C00F8, 0x5E200000, 0x84000040,
+ 0x5838002C, 0xCB0000F8, 0xDFE800F8, 0x00000000, 0x58380014, 0xCF0000F8, 0x80000018, 0xC2A1FFFE,
+ 0x5AA9FFFE, 0x5838000A, 0xCE8000F8, 0xC3000000, 0xC0000A14, 0xCB040028, 0xC2D00002, 0xC0000A28,
+ 0xCEC50800, 0xC000494E, 0xCA8000F8, 0x58880002, 0xB4B00018, 0xC00048A0, 0xC0800000, 0xCC8400F8,
+ 0x5EA80000, 0x8400016A, 0x5E200000, 0x84000158, 0xC000493C, 0xCA8000F8, 0x00000000, 0x00000000,
+ 0x5AA80060, 0xCE8000F8, 0x99008328, 0xDBD800F8, 0xDB9800F9, 0xC78000F8, 0x99008528, 0xDBD800F8,
+ 0xDB9800F9, 0xC78000F8, 0xC0004952, 0xCAC000F8, 0x58380000, 0xCA8000F8, 0xC30C0002, 0xC7F00018,
+ 0xA68000B0, 0x00000000, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xC0001800, 0xCA0000F8, 0x00000000, 0x00000000, 0xA60CFFEA, 0xC6F00500,
+ 0xC6B0C400, 0xCF0000F8, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x14100000, 0x8000B7B8, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x8000B750, 0xDCBC00F9, 0x5FFC0000, 0x8400095A, 0xC3800002,
+ 0xDB8800F9, 0xC3800000, 0xDB8800F9, 0xC0004728, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002,
+ 0xCD0000F8, 0xC0004730, 0xC98000F8, 0xC000472E, 0xC94000F8, 0xC00047DC, 0xC90000F8, 0xC00047DE,
+ 0xC9C000F8, 0xC000472E, 0xCD8000F8, 0x6D110000, 0xC5D30038, 0xC00047DC, 0xCD0000F8, 0x4594A000,
+ 0x6DDD0000, 0xC55C0038, 0xC00047DE, 0xCDC000F8, 0xC0001AC4, 0xC94000F8, 0xC0001AC8, 0xC98000F8,
+ 0xC000472C, 0xC9C000F8, 0x45948000, 0xC1000002, 0x41D0E004, 0xCDC000F8, 0xC5501078, 0xC5900078,
+ 0xC000472A, 0xCD0000F8, 0xC0001AF0, 0xCBC000F8, 0x58000002, 0xCB8000F8, 0xC3400000, 0xC7F50038,
+ 0x6F702000, 0x5B304300, 0xC000474C, 0xCAC000F8, 0xC0004720, 0xC94000F8, 0x00000000, 0x00000000,
+ 0x5D940002, 0x6D9B8000, 0x6D9B8010, 0x581847E0, 0xC98000F8, 0x581447E0, 0xC9C000F8, 0x5D2C0000,
+ 0x8400007A, 0xC7901078, 0xC7D00078, 0xCD0000F8, 0xC1000000, 0xC5910038, 0x45348000, 0x84000090,
+ 0xC0004722, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0x80000058, 0xC1000000,
+ 0xC5D10038, 0x45348000, 0x8400003A, 0xC0004724, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002,
+ 0xCD0000F8, 0xA7840080, 0x59540002, 0x6D578000, 0x6D578010, 0xC0004720, 0xCD4000F8, 0xC1000000,
+ 0xC5910038, 0x45348000, 0x84000038, 0xC0004726, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002,
+ 0xCD0000F8, 0xA78000B8, 0xC2800002, 0xC000474E, 0xCE8000F8, 0xC2C00000, 0xC000474C, 0xCEC000F8,
+ 0xC0004758, 0xCFC000F8, 0x58000002, 0xCF8000F8, 0xC000475C, 0xC90000F8, 0x00000000, 0x00000000,
+ 0xA53E003A, 0x00000000, 0xC13E0002, 0xCFC000F8, 0xCD03DE08, 0x58000002, 0xCF8000F8, 0x800001A0,
+ 0xC000475C, 0xC13C0002, 0xCD03DE08, 0x5D2C0000, 0x8400017A, 0xC2C00000, 0xC000474C, 0xCEC000F8,
+ 0x98C08AF0, 0xC75400F8, 0xC0004740, 0xC9C000F8, 0x5D240000, 0x84000042, 0xC1000002, 0xC0004750,
+ 0xCD0000F8, 0xC0004752, 0xCD0000F8, 0x80000100, 0x00000000, 0x98C08BE0, 0xC75400F8, 0xC0004742,
+ 0xC98000F8, 0x5D240000, 0x8400002A, 0xC1000002, 0xC0004752, 0xCD0000F8, 0x80000060, 0xC0004742,
+ 0xC94000F8, 0xC0004754, 0xC1000002, 0xCD0000F8, 0x98C08CF0, 0xC55400F8, 0xC75800F8, 0x00000000,
+ 0xC0004742, 0xCF4000F8, 0x98C08AB8, 0xC1400000, 0xC7540020, 0x6F40A010, 0xC1000000, 0xC7D00038,
+ 0x58300000, 0x6D110000, 0xCD010838, 0xA7840398, 0xC000474C, 0xCAC000F8, 0xC000474E, 0xCA8000F8,
+ 0xC0004750, 0xCBC000F8, 0xC0004752, 0xCB8000F8, 0xC0004710, 0xC90000F8, 0x00000000, 0x00000000,
+ 0x59100002, 0xCD0000F8, 0x5D280002, 0x840000B8, 0xC000473C, 0xC90000F8, 0x00000000, 0x00000000,
+ 0x59100002, 0xCD0000F8, 0xC0004712, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8,
+ 0xC0004754, 0xC90000F8, 0x00000000, 0x00000000, 0x5D100000, 0x8400021A, 0x58300000, 0xC13C0002,
+ 0xCD03DE00, 0x800001F8, 0xC0004714, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8,
+ 0x5D380000, 0x8400003A, 0xC0004736, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8,
+ 0x5D3C0000, 0x84000042, 0xC0004718, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8,
+ 0x80000140, 0xC1000000, 0x58300000, 0xC903E000, 0x00000000, 0x00000000, 0x5D100000, 0x84000042,
+ 0xC000471A, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0x800000D0, 0x58300000,
+ 0xC13E0002, 0xCD03FF00, 0xC1000000, 0x58300000, 0xC903C000, 0x00000000, 0x00000000, 0x5D100000,
+ 0x84000082, 0xC0004716, 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0xC000473A,
+ 0xC90000F8, 0x00000000, 0x00000000, 0x59100002, 0xCD0000F8, 0x58300000, 0xC13C0000, 0xCD03DE00,
+ 0xC1000000, 0xC0004746, 0xCD0000F8, 0xC0004750, 0xCD0000F8, 0xC0004752, 0xCD0000F8, 0xC000474E,
+ 0xCD0000F8, 0xC2C00002, 0xC000474C, 0xCEC000F8, 0xC0004754, 0xCD0000F8, 0xC3CE0002, 0xC0000800,
+ 0xCFC0E700, 0xC3E1FFFE, 0x597DFFFE, 0x593DFE14, 0x94000001, 0x00000000, 0x00000000, 0x00000000,
+ 0xC000487C, 0xC80400F8, 0x00000000, 0x00000000, 0x40080000, 0xCBC000F8, 0xC43800F8, 0x00000000,
+ 0xC000480E, 0xCA0000F8, 0xC0004858, 0xCB4400F8, 0x00000000, 0x00000000, 0x47610000, 0x880000B0,
+ 0x00000000, 0xA7C00048, 0xC0004854, 0xC1000002, 0xCD0400F8, 0xC11C0000, 0xC000082C, 0xCD05CE00,
+ 0x800000D8, 0x00000000, 0xA7D20138, 0x00000000, 0xC7E14040, 0xC2400000, 0xC6246028, 0xC200006A,
+ 0x46250000, 0xC6240030, 0xC0000810, 0xCE440030, 0x8000FF70, 0xC2000000, 0xC0000808, 0xCA040010,
+ 0xC11C0000, 0xC000082C, 0xCD05CE00, 0x5A200002, 0x5E600010, 0x84000010, 0xC2000000, 0xC0000808,
+ 0xCE040010, 0xC3400000, 0x80000028, 0xC1200002, 0xC0000818, 0xCD061000, 0x5B740002, 0xC0004858,
+ 0xCF4400F8, 0x99007930, 0xC0004848, 0xC94400F8, 0xC1800000, 0xC11C0002, 0xC000082C, 0xCD05CE00,
+ 0x80000878, 0x5B740002, 0xC0004858, 0xCF4400F8, 0xC78000F8, 0xC13C0002, 0xCD03DE00, 0xC0004848,
+ 0xC94400F8, 0xC1800000, 0xC000082C, 0xC9840028, 0x59540002, 0xC0004848, 0xCD4400F8, 0x58880002,
+ 0xB49807F8, 0x00000000, 0xC0800000, 0x800007E0, 0xC000487C, 0xC80400F8, 0x00000000, 0x00000000,
+ 0x40080000, 0xCBC000F8, 0xC42800F8, 0x00000000, 0xA7C00130, 0xC000484C, 0xCA0400F8, 0xC2400000,
+ 0xC0001AEC, 0xCA440018, 0x5A200002, 0xC000484C, 0xCE0400F8, 0xB624008A, 0xC68000F8, 0xC13C0002,
+ 0xCD03DE00, 0xC0004848, 0xC94400F8, 0xC1800000, 0xC000082C, 0xC9840028, 0x59540002, 0xC0004848,
+ 0xCD4400F8, 0x58880002, 0xB49806E8, 0x00000000, 0xC0800000, 0x800006D0, 0xC0004854, 0xC1000004,
+ 0xCD0400F8, 0xC0000820, 0xC2000002, 0xCE0400F8, 0xC2000000, 0xC000484C, 0xCE0400F8, 0xC0004858,
+ 0xCE0400F8, 0x8000FF28, 0xC0004854, 0xC1000000, 0xCD0400F8, 0xC11C0000, 0xC000082C, 0xCD05CE00,
+ 0x99007930, 0xC0004848, 0xC94400F8, 0xC1800000, 0xC1200000, 0xC0000818, 0xCD061000, 0xC11C0002,
+ 0xC000082C, 0xCD05CE00, 0xC2000000, 0xC000484C, 0xCE0400F8, 0x800005D0, 0xC0001AC0, 0xCB8400F8,
+ 0xC000487C, 0xC80400F8, 0x00000000, 0x00000000, 0x40080000, 0xCBC000F8, 0xC42800F8, 0x00000000,
+ 0xA78004E2, 0x00000000, 0x00000000, 0xA7C004A2, 0x00000000, 0xC0001B00, 0xC2060006, 0xCE046308,
+ 0xA7E8045A, 0x00000000, 0xC0004850, 0xCA0400F8, 0xC2400000, 0xC0004812, 0xCA420078, 0x5A200002,
+ 0xC0004850, 0xCE0400F8, 0x5E640000, 0x8400001A, 0x46250000, 0x880002F8, 0xC68000F8, 0xC13C0002,
+ 0xCD03DE00, 0xC0001ACC, 0xC2000002, 0xCE040000, 0x5C440000, 0x84000250, 0xC0004810, 0xC94000F8,
+ 0xC68000F8, 0xCBC000F8, 0x00000000, 0xC1000000, 0xA5400208, 0xC53C1000, 0x00000000, 0xA7FC01F2,
+ 0xC0001AF0, 0xC1000000, 0x58000002, 0xC9000000, 0xC000474E, 0xC98000F8, 0x5D100000, 0x84000022,
+ 0xC1000002, 0xC53C1E00, 0x80000198, 0x5D180000, 0x84000022, 0xC1000002, 0xC53C1E00, 0x80000170,
+ 0xC0004878, 0xC80400F8, 0x6C908000, 0x45088000, 0x45088000, 0x40100000, 0xC98000F8, 0xC43800F8,
+ 0x00000000, 0xC000481E, 0xC9C000F8, 0xC000481C, 0xCA0000F8, 0x00000000, 0x759CC000, 0x45A08000,
+ 0x840000E8, 0xC0001AF0, 0xC3400000, 0x58000000, 0xCB410038, 0xC0004746, 0xC94000F8, 0x6F702000,
+ 0x5B304300, 0xC2C00000, 0x58300000, 0xCAC00038, 0x00000000, 0x00000000, 0x456C8000, 0x88000020,
+ 0xC1000002, 0xC53C1E00, 0x80000040, 0x5AEC0002, 0x58300000, 0xCEC00038, 0xC1000002, 0xC53C1000,
+ 0xC77C0838, 0xC57C0038, 0x59540002, 0xC0004746, 0xCD4000F8, 0xC68000F8, 0xCFC000F8, 0xC0004848,
+ 0xC94400F8, 0xC1800000, 0xC000082C, 0xC9840028, 0x59540002, 0xC0004848, 0xCD4400F8, 0x58880002,
+ 0xB49801F8, 0x00000000, 0xC0800000, 0x800001E0, 0xC000471E, 0xC90000F8, 0x00000000, 0x00000000,
+ 0x59100002, 0xCD0000F8, 0xC0004854, 0xC1000000, 0xCD0400F8, 0xC11C0000, 0xC000082C, 0xCD05CE00,
+ 0x99007930, 0xC0004848, 0xC94400F8, 0xC1800000, 0xC2000000, 0xC0000820, 0xCE0400F8, 0xC1200000,
+ 0xC0000818, 0xCD061000, 0xC11C0002, 0xC000082C, 0xCD05CE00, 0xC0004850, 0xCE0400F8, 0xC2000002,
+ 0xC0001ACC, 0xCE040008, 0x800000E8, 0xC2000002, 0xC0004850, 0xCE0400F8, 0x8000FC00, 0xC2000000,
+ 0xC0004850, 0xCE0400F8, 0xA7E60032, 0x00000000, 0xC2000002, 0xC0001B00, 0xCE040000, 0x8000FBE8,
+ 0x00000000, 0xA7860052, 0x00000000, 0xC68000F8, 0xC13C0002, 0xCD03DE00, 0xC2020002, 0xC7E2A540,
+ 0xC0001B00, 0xCE0400F8, 0x8000FB90, 0xC2040002, 0xC0001B00, 0xCE044200, 0x8000FB70, 0xC2C80002,
+ 0x6AC56000, 0xDACC00F8, 0xC0004854, 0xCB4400F8, 0xC0004848, 0xCB8400F8, 0xC0000838, 0xC3C00000,
+ 0xCBC40028, 0x5EF40004, 0x84000022, 0xC3000000, 0xC0001ACC, 0xCF042100, 0x47F98000, 0x8400004A,
+ 0x47F98000, 0x88000050, 0xC1006E8C, 0xC1400010, 0x8D580000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0004840, 0xCC8400F8, 0x8000EB10, 0xC0001AC0, 0xCAC400F8, 0xC0004854, 0xCB4400F8, 0xA6C0F93A,
+ 0x00000000, 0x5EF40000, 0x8400F472, 0x5EF40002, 0x8400F702, 0x5EF40004, 0x8400F902, 0xC1006CE8,
+ 0xC1400010, 0x8D580000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC0800000, 0xDF4B0038,
+ 0xC0004900, 0xCB8000F8, 0xC2000000, 0xC000490A, 0xA78000D0, 0xCBC000F8, 0xC1000000, 0xD90000F9,
+ 0xC1000002, 0xD90C00F8, 0x6FF46000, 0x477DA000, 0x5B744C80, 0xC2400000, 0x58340004, 0xCA400078,
+ 0xC0004900, 0xCE000000, 0x5A640002, 0x58340004, 0xC6500078, 0xCD000078, 0xC0004914, 0xCA4000F8,
+ 0xC2000002, 0x6A3D0000, 0x72612000, 0xCE4000F8, 0xC0000408, 0xCE0000F8, 0xA78200D8, 0xC0004908,
+ 0xCBC000F8, 0xC1000000, 0xD90000F9, 0xC1000002, 0xD90C00F8, 0x6FF4A000, 0x6FD44000, 0x4755A000,
+ 0x477DA000, 0x5B747000, 0xC2800000, 0x58340006, 0xCA800078, 0xC2000000, 0xC0004900, 0xCE002100,
+ 0x5EA80002, 0x58340006, 0xC6900078, 0xCD000078, 0x5A7C0020, 0xC2000002, 0x6A250000, 0xC0000408,
+ 0xCE0000F8, 0xC0000032, 0xDCA800F9, 0xC1000002, 0x45294000, 0x00000000, 0x8C100006, 0x00000000,
+ 0x00000000, 0x00000000, 0xA4800230, 0x00000000, 0xC3C00000, 0xC000140E, 0xCBC00018, 0xC3400000,
+ 0xC2400000, 0x6FF86000, 0x47BDC000, 0x5BB84C80, 0x58380008, 0xCB400078, 0x58380006, 0xCA400078,
+ 0x5F740002, 0x58380008, 0xC7500078, 0xCD000078, 0xC2000000, 0x58380004, 0xCA020078, 0xC3000000,
+ 0x5838000C, 0xCB000020, 0x5A640002, 0x46610000, 0x84000010, 0xC2400000, 0x58380006, 0xC6500078,
+ 0xCD000078, 0xC2000000, 0x5838000A, 0xCA020078, 0x5B300002, 0x5838000C, 0xC7100020, 0xCD000020,
+ 0xC2420020, 0x5A200004, 0x46252000, 0x84000010, 0xC2000000, 0x5838000A, 0xC6101078, 0xCD021078,
+ 0xC0004966, 0xCA4000F8, 0xC2000002, 0x6A3D0000, 0x72612000, 0xCE4000F8, 0x5F740000, 0x84000040,
+ 0xC0004912, 0xCA0000F8, 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x762D0000, 0xCE0000F8, 0x5F300020,
+ 0x84000040, 0xC0004924, 0xCA0000F8, 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x762D0000, 0xCE0000F8,
+ 0xA4820070, 0xC2400000, 0xC000140E, 0xCA408018, 0xC2000002, 0xC0004900, 0xCE000000, 0xC000490A,
+ 0xCE4000F8, 0xC1000000, 0xD90000F9, 0xD8400078, 0xC1000004, 0xD90000F9, 0xA48402A8, 0x00000000,
+ 0xC3C00000, 0xC000140E, 0xCBC10018, 0xC2800000, 0xC2000000, 0x6FF8A000, 0x6FD44000, 0x4795C000,
+ 0x47BDC000, 0x5BB87000, 0x5838002E, 0xCA800078, 0x58380006, 0xCA020078, 0xC3400000, 0x5838002E,
+ 0xCB420078, 0x5AA80002, 0x46A10000, 0x84000010, 0xC2800000, 0x5838002E, 0xC6900078, 0xCD000078,
+ 0x5F740002, 0x5838002E, 0xC7501078, 0xCD021078, 0xC0004968, 0xCA4000F8, 0xC2000002, 0x6A3D0000,
+ 0x72612000, 0xCE4000F8, 0xC000492A, 0xCA8000F8, 0x5E740000, 0x84000040, 0xC0004910, 0xCA0000F8,
+ 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x762D0000, 0xCE0000F8, 0x6ABD4010, 0xA68000F2, 0x00000000,
+ 0xC0004910, 0xCA0000F8, 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x762D0000, 0xCE0000F8, 0x58380032,
+ 0xCA0000F8, 0x58000002, 0xCA4000F8, 0x5838000C, 0x00000000, 0xCE0000F9, 0xCE4000F8, 0xC000492A,
+ 0xCA0000F8, 0xC2C00002, 0x6AFD6000, 0x722D0000, 0xCE0000F8, 0xC000492C, 0xCA0000F8, 0xC2C00002,
+ 0x6AFD6000, 0x722D0000, 0xCE0000F8, 0x80000040, 0xC000492C, 0xCA0000F8, 0xC2C00002, 0x6AFD6000,
+ 0x7EC16000, 0x762D0000, 0xCE0000F8, 0xA4880120, 0xC2C00000, 0xC000140E, 0xCAC20018, 0xC000490E,
+ 0xCA4000F8, 0xC2000002, 0x6A2D0000, 0x7E010000, 0x76612000, 0xCE4000F8, 0xC000496A, 0xCA4000F8,
+ 0xC2000002, 0x6A2D0000, 0x72612000, 0xCE4000F8, 0x6EF0A000, 0x6ED44000, 0x47158000, 0x472D8000,
+ 0x5B307000, 0x58300000, 0xCA0000F8, 0x00000000, 0xC2400002, 0x76612000, 0x8400004A, 0xC24C0002,
+ 0xC6E40018, 0xC624C400, 0x58300010, 0xCA400500, 0x00000000, 0xC0001800, 0xCE4000F8, 0xA4860070,
+ 0xC2400000, 0xC000140E, 0xCA418018, 0xC2020002, 0xC0004900, 0xCE002100, 0xC0004908, 0xCE4000F8,
+ 0xC1000000, 0xD90000F9, 0xD8400078, 0xC1000004, 0xD90000F9, 0xA48C0048, 0xC2800002, 0xC000484A,
+ 0xCE8000F8, 0xC2800000, 0xC000474A, 0xCE8000F8, 0xC0004846, 0xCE8000F8, 0xC0001408, 0xCC8000F8,
+ 0xC10E0002, 0xD90C00F8, 0x8000EA78, 0xDFBC00F9, 0xC000496E, 0x99008638, 0xC94000F8, 0xC7D800F8,
+ 0x00000000, 0xC57000F8, 0x5EF00020, 0x88000148, 0x6F346000, 0x4771A000, 0x5B744C80, 0x58340008,
+ 0xC2400000, 0xCA400078, 0x00000000, 0xC2000000, 0x5A640002, 0xCE400078, 0x58340004, 0xCA000078,
+ 0x00000000, 0x00000000, 0x5E200002, 0xCE000078, 0xC0004912, 0xCA8000F8, 0xC2400002, 0x6A712000,
+ 0x72A54000, 0xCE8000F8, 0x5E200000, 0x84000052, 0xC000480A, 0xCA0000F8, 0xC0000408, 0xCA8000F8,
+ 0x76250000, 0x00000000, 0x72A14000, 0xCE8000F8, 0x80000038, 0xC0004914, 0xCA0000F8, 0x7E412000,
+ 0x00000000, 0x76250000, 0xCE0000F8, 0x800000D0, 0x6EF4A000, 0x6ED44000, 0x4755A000, 0x476DA000,
+ 0x5B747000, 0x5834002E, 0xC2400000, 0xCA420078, 0x00000000, 0xC2000000, 0x5A640002, 0xC6501078,
+ 0xCD021078, 0x58340006, 0xCA000078, 0x00000000, 0x00000000, 0x5A200002, 0xCE000078, 0xC0004910,
+ 0xCA4000F8, 0xC2000002, 0x6A2D0000, 0x72612000, 0xCE4000F8, 0xC2000002, 0x6A310000, 0xC000042A,
+ 0xCE0000F8, 0xC1040002, 0xD90C00F8, 0x00000000, 0x8000E7E8, 0x00000000, 0xC4980928, 0x9D000000,
+ 0xC5580028, 0xC0000838, 0xCD8400F8, 0xC1440200, 0xC1C03800, 0xC55C1070, 0xC000100E, 0x9D000000,
+ 0xCD8000F8, 0xC000100C, 0xCDC000F8, 0xC0004862, 0xC9C000F8, 0x00000000, 0x00000000, 0xD9D800F9,
+ 0xC0007800, 0x401C0000, 0x5DC07A00, 0x88000012, 0x5C000200, 0xCD8000F8, 0xC1F0000A, 0x715CA000,
+ 0xDD9800F8, 0xDD9C00F9, 0x41D8E000, 0xC5D40260, 0xC0001010, 0xCD4000F8, 0x6C9C8000, 0x45C8E000,
+ 0x45C8E000, 0x59DC0004, 0xC1601260, 0xC5D40260, 0x9D000000, 0xC0001012, 0xCD4000F8, 0x00000000,
+ 0x00000000, 0xD95800F8, 0x6D586000, 0x4594C000, 0x59984C80, 0xD99800F9, 0x5818000A, 0xC1800000,
+ 0xC9800078, 0xC0006E00, 0x6D5CA000, 0x401C0000, 0x40180000, 0xC94000F8, 0x58000002, 0x00000000,
+ 0xC9C000F8, 0xC0004930, 0xCD4000F8, 0xC0004932, 0xCDC000F8, 0x59980004, 0xC1C20020, 0xB59C0018,
+ 0x00000000, 0xC1800000, 0xDD9C00F9, 0x581C000A, 0xCD800078, 0x581C000C, 0xC1800000, 0xC9800020,
+ 0xC1C00002, 0xDD9400F8, 0x69D4E000, 0x5D980002, 0xCD800020, 0xC0004924, 0xC98000F8, 0x00000000,
+ 0x9D000000, 0x00000000, 0x719CC000, 0xCD8000F8, 0xC000492A, 0xC94000F8, 0xC1C00002, 0x69D8E000,
+ 0x7DC0C000, 0x7558A000, 0xCD4000F8, 0xC000492C, 0xC94000F8, 0xDD8000F9, 0x58000032, 0x755CA000,
+ 0x84000090, 0xC94000F9, 0xC98000F8, 0xDD8000F9, 0x5800000C, 0x00000000, 0xCD4000F9, 0xCD8000F8,
+ 0xC000492C, 0xC94000F8, 0xC000492A, 0xC98000F8, 0x715CA000, 0xC000492C, 0xCD4000F8, 0x719CC000,
+ 0xC000492A, 0xCD8000F8, 0x9D000000, 0x00000000, 0x00000000, 0x00000000, 0xC0004862, 0xC98000F8,
+ 0x00000000, 0xC1C00200, 0x4194C000, 0x459CE000, 0x88000012, 0xC5D800F8, 0xC0004862, 0xCD8000F8,
+ 0xC0001406, 0xC98000F8, 0xC1C00002, 0x9D000000, 0xC5D80A00, 0xC5581048, 0xCD8000F8, 0xC0004930,
+ 0xC98000F8, 0xC0004932, 0xC9C000F8, 0xC140000E, 0xC5581C18, 0xDD9400F8, 0xC0007800, 0x40140000,
+ 0x5D407A00, 0x88000012, 0x5C000200, 0xCD8000F8, 0x58000002, 0x5D407A00, 0x88000012, 0x5C000200,
+ 0xCDC000F8, 0xDD5400F8, 0xC1C00000, 0x58140006, 0xC9C20078, 0xC1800000, 0x58140000, 0xC98000D8,
+ 0x6DDC2000, 0xC000491E, 0x41D8E000, 0xCDC000F8, 0xDD9800F8, 0xC1C00022, 0xC5D80D70, 0xDD9400F9,
+ 0xC5581C18, 0xC000491C, 0xCD8000F8, 0xDD5400F8, 0xC1C00000, 0x58140006, 0xC9C20078, 0xC1800000,
+ 0x58140004, 0xC9820078, 0x00000000, 0x59DC0002, 0x45D8C000, 0x84000010, 0xC1C00000, 0x9D000000,
+ 0x58140006, 0xC5D81078, 0xCD821078, 0xC0004860, 0xC94000F8, 0xC1820080, 0xC1D00002, 0x58147700,
+ 0xD58000F8, 0x58000002, 0xD58000F9, 0x59540004, 0xB5580018, 0xC0004860, 0xC1400000, 0xCD4000F8,
+ 0xDD9800F9, 0x9D000000, 0xDD9400F8, 0xC0001404, 0xCDC10800, 0xC1C00000, 0xC1800200, 0x5D980004,
+ 0xDF5D0048, 0x459CA000, 0x8800FFF2, 0xDD8000F9, 0x5800000C, 0x00000000, 0xC94000F9, 0xC98000F8,
+ 0xC1C00002, 0xC5D43F00, 0xC5D81E00, 0xC0004862, 0xC9C000F8, 0x00000000, 0x00000000, 0x581C7800,
+ 0x5DC07A00, 0x88000012, 0x5C000200, 0xCD4000F8, 0x58000002, 0x5DC07A00, 0x88000012, 0x5C000200,
+ 0xCD8000F8, 0xC0004862, 0xC9C000F8, 0x00000000, 0xC15004C0, 0xC5D40060, 0xDD9C00F8, 0xC5D41C18,
+ 0xC1C00000, 0xDD8000F9, 0x58000030, 0xC9C00078, 0xDD8000F9, 0x58000002, 0xC98000F8, 0x6DDC2000,
+ 0xC000491C, 0x41D8E000, 0xCD4000F9, 0xCDC000F8, 0xDD9400F9, 0xC1C00000, 0x58140030, 0xC9C00078,
+ 0xC1800000, 0x58140006, 0xC9820078, 0x00000000, 0x59DC0002, 0x45D8C000, 0x84000010, 0xC1C00000,
+ 0x9D000000, 0x58140030, 0xC5D80078, 0xCD800078, 0xC1C00000, 0xDF5C0038, 0x5DDC0080, 0x8400FFEA,
+ 0x00000000, 0x9D000000, 0x00000000, 0x00000000, 0x00000000, 0xC160FFFE, 0xC0000A10, 0xC9440060,
+ 0xC1A0FFFE, 0x59983008, 0xC000100C, 0xCD4000F8, 0xC000100E, 0xCD8000F8, 0xC0004964, 0xC98000F8,
+ 0x00000000, 0xC170000A, 0x7158A000, 0x6C988000, 0x4588C000, 0x4588C000, 0x59980004, 0xC5940270,
+ 0xC0001010, 0xCD4000F8, 0xC0004946, 0xC94000F8, 0x00000000, 0x00000000, 0x6D58A000, 0x6D5C4000,
+ 0x459CC000, 0x4594C000, 0xC000494A, 0xC94000F8, 0xC0004948, 0xC9C000F8, 0x4194C000, 0xC1400012,
+ 0xC55C1818, 0x9D000000, 0xC59C0268, 0xC0001012, 0xCDC000F8, 0xC1400000, 0x58000012, 0xC9410038,
+ 0xC0004950, 0xC9C000F8, 0xC55800F8, 0xC5940838, 0xC5581078, 0xD99400F8, 0xC000493C, 0xC94000F8,
+ 0xC0004954, 0xC98000F8, 0x59DC00A8, 0x45D4E000, 0x41D8E000, 0x5D5C0030, 0x88000010, 0xC1C00030,
+ 0xC1800000, 0xC5D84028, 0xC1400000, 0xC5D40008, 0x5DD40002, 0x84000072, 0x5DD40004, 0x8400009A,
+ 0x5DD40006, 0x840000C2, 0x5DD80026, 0x840000EA, 0xDD5400F8, 0xDD8000F9, 0x58000008, 0x40180000,
+ 0xCD4000F8, 0x59980002, 0x8000FFC0, 0xDD5400F8, 0xDD8000F9, 0x58000008, 0x40180000, 0xCD4000B8,
+ 0x59980002, 0x8000FF88, 0xDD5400F8, 0xDD8000F9, 0x58000008, 0x40180000, 0xCD400078, 0x59980002,
+ 0x8000FF50, 0xDD5400F8, 0xDD8000F9, 0x58000008, 0x40180000, 0xCD400038, 0x59980002, 0x8000FF18,
+ 0x00000000, 0x9D000000, 0x00000000, 0x00000000, 0x00000000, 0x58000012, 0xC94000F8, 0xC0004954,
+ 0xC9C000F8, 0xC0004950, 0xC9400078, 0xDD8000F9, 0x58000028, 0x5D9C0000, 0x84000052, 0x5D9C0002,
+ 0x84000052, 0x5D9C0004, 0x8400006A, 0xC55B0038, 0xC55C08B8, 0xCD800039, 0xCDC108B8, 0x80000060,
+ 0xCD4000F8, 0x80000050, 0xC55900B8, 0xC55C1838, 0xCD8000B9, 0xCDC31838, 0x80000028, 0xC55A0078,
+ 0xC55C1078, 0xCD800079, 0xCDC21078, 0x9D000000, 0x00000000, 0x00000000, 0x00000000, 0x59540002,
+ 0x6994E018, 0x61C0C008, 0x4194A000, 0x5D940040, 0x88000012, 0xC59400F8, 0x9D000000, 0xCD4000F8,
+ 0x00000000, 0x00000000, 0x9D000000, 0x4158A000, 0xCD4000F8, 0x00000000, 0xCD8000F9, 0x45408000,
+ 0x8800FFF0, 0x00000000, 0x9CC00000, 0x00000000, 0x00000000, 0x00000000, 0xC0004810, 0xCA010038,
+ 0xC241FFFE, 0xC1400000, 0x46148000, 0x00000000, 0x9CC00006, 0xC0004200, 0x40180000, 0xC9C000F8,
+ 0x00000000, 0x00000000, 0x61C08010, 0x8400005A, 0xC2400002, 0x6A512000, 0x71E4E000, 0xCDC000F8,
+ 0xC0004748, 0xCD8000F8, 0x9CC00000, 0x6D98A000, 0x5998003E, 0x45912000, 0x59540002, 0x59980002,
+ 0x46188000, 0xC1000000, 0xC51800FE, 0x8000FF38, 0x00000000, 0x40180000, 0xC9C000F8, 0xC2000000,
+ 0xC5600020, 0xC1210000, 0x69208010, 0x7D008000, 0x75D0E000, 0xCDC000F8, 0x6D542000, 0x58144300,
+ 0xC1000000, 0xCD0000F9, 0x9CC00000, 0xC121FFFE, 0x5911FFFE, 0xCD0000F9, 0x79588000, 0x6D10A010,
+ 0x5D100000, 0x840000C0, 0x45948000, 0x880000B0, 0x6D536000, 0x6D136010, 0x6D54A010, 0xC0004700,
+ 0x40140000, 0xCA0000F8, 0x00000000, 0x00000000, 0x6A110000, 0x6A110010, 0x62008018, 0x84000032,
+ 0x00000000, 0x9CC00000, 0x6D54A000, 0x5954003E, 0x45512000, 0x59540002, 0x6D57A000, 0x6D57A010,
+ 0x6D54A000, 0x6D936000, 0x6D136010, 0xC1E10000, 0x69D0E010, 0x5DDC0002, 0x7DC0E000, 0x6D98A010,
+ 0x6D536000, 0x6D136010, 0x6D54A010, 0xC0004700, 0x40140000, 0xCA0000F8, 0x00000000, 0x00000000,
+ 0x6A110000, 0x6A110010, 0x45588000, 0x00000000, 0x761D0002, 0x62008018, 0x84000032, 0x00000000,
+ 0x9CC00000, 0x6D54A000, 0x5954003E, 0x45512000, 0x45588000, 0x00000000, 0x9CC00002, 0x59540002,
+ 0x6D57A000, 0x6D57A010, 0xC0004700, 0x40140000, 0xCA0000F8, 0x8000FF68, 0x00000000, 0x00000000,
+ 0x00000000, 0x58004700, 0xC98000F8, 0x9CC00000, 0x00000000, 0x6994C000, 0x6DA7E010, 0x58004700,
+ 0xC98000F8, 0xC1210000, 0x9CC00000, 0x69148010, 0x7190C000, 0xCD8000F8, 0xC1000000, 0xC0004810,
+ 0xC9020038, 0x00000000, 0x00000000, 0x45D0C000, 0x88000062, 0xC2400002, 0x45588000, 0xC1000000,
+ 0xC52400FC, 0x45D48000, 0xC1000000, 0xC52400FE, 0x9CC00000, 0x00000000, 0x00000000, 0x00000000,
+ 0x59980200, 0xC2400000, 0x455C8000, 0xC1000002, 0xC52400FC, 0x45948000, 0xC1000002, 0xC52400FE,
+ 0x9CC00000, 0x00000000, 0x00000000, 0x00000000, 0xC0004740, 0xC9C000F8, 0x59180002, 0x6D130000,
+ 0x6D130010, 0x451C8000, 0xC2400000, 0x9CC00002, 0x00000000, 0x00000000, 0x459C8000, 0x88000062,
+ 0xC2400002, 0x455C8000, 0xC1000000, 0xC52400FC, 0x45948000, 0xC1000000, 0xC52400FC, 0x9CC00000,
+ 0x00000000, 0x00000000, 0x00000000, 0xC2400000, 0x45588000, 0xC1000002, 0xC52400FE, 0x45D48000,
+ 0xC1000002, 0xC52400FE, 0x9CC00000, 0x00000000, 0x00000000, 0x00000000, 0x59540002, 0x6D570000,
+ 0x6D570010, 0x45588000, 0x6D402000, 0x9CC00002, 0x58004300, 0x58000000, 0xC13C0002, 0xCD03DE00,
+ 0x8000FFB0, 0x00000000, 0x00000000, 0x00000000, 0xC1020002, 0xD90C00F8, 0xC98000F8, 0x59540002,
+ 0xC0004730, 0xCD4000F8, 0x5D980002, 0x00000000, 0x80000036, 0x00000000, 0x9CC00000, 0xC0004732,
+ 0xCD8000F8, 0x00000000, 0xC0004734, 0xC9C000F8, 0xC1800000, 0xC0004816, 0xC9820078, 0xC0004738,
+ 0xCDC000F8, 0xC1C00000, 0xC0004734, 0x9CC00000, 0xCDC000F8, 0xC0004732, 0xCD8000F8,
+};
+
+static unsigned int firmware_binary_data[] = {
+};
+
+
+#endif // IFXMIPS_ATM_FW_AR9_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_danube.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_danube.h
new file mode 100644
index 0000000000..57b7586bd0
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_danube.h
@@ -0,0 +1,442 @@
+#ifndef IFXMIPS_ATM_FW_DANUBE_H
+#define IFXMIPS_ATM_FW_DANUBE_H
+
+
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_fw_danube.h
+** PROJECT : Danube
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (PP32 Firmware)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+*******************************************************************************/
+
+
+#define VER_IN_FIRMWARE 1
+
+#define ATM_FW_VER_MAJOR 0
+#define ATM_FW_VER_MINOR 17
+// fix 1 upstream packet stuck in TX queue issue
+// add multiple queue per PVC feature
+
+
+static unsigned int danube_fw_bin[] = {
+ 0x800004A0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000FFC8, 0x00000000, 0x00000000, 0x00000000,
+ 0xC1000002, 0xD90C0000, 0xC2000002, 0xDA080001, 0x80004968, 0xC2000000, 0xDA080001, 0x80003FD0,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80003F88, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80005160, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80003E88, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0400000, 0xC0004840, 0xC8840000, 0x80004628, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0400002, 0xC0004840, 0xC8840000, 0x800045A8, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC3C00004, 0xDBC80001, 0xC10C0002, 0xD90C0000, 0x8000FEC8, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC10E0002, 0xD90C0000, 0xC0004808, 0xC8400000, 0x800045D8, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC3E1FFFE, 0x597DFFFE, 0x593DFE14, 0x900004D9, 0x00000000, 0x00000000, 0x00000000, 0x90CC0481,
+ 0x00000000, 0x00000000, 0x00000000, 0xC3C00000, 0xDBC80001, 0xC1400008, 0xC1900000, 0x71948000,
+ 0x15000100, 0xC140000A, 0xC1900002, 0x71948000, 0x15000100, 0xC140000C, 0xC1900004, 0x71948000,
+ 0x15000100, 0xC1400004, 0xC1900006, 0x71948000, 0x15000100, 0xC1400006, 0xC1900008, 0x71948000,
+ 0x15000100, 0xC140000E, 0xC190000A, 0x71948000, 0x15000100, 0xC1400000, 0xC190000C, 0x71948000,
+ 0x15000100, 0xC1400002, 0xC190000E, 0x71948000, 0x15000100, 0xC0400000, 0xC11C0000, 0xC000082C,
+ 0xCD040E08, 0xC11C0002, 0xC000082C, 0xCD040E08, 0xC0400002, 0xC11C0000, 0xC000082C, 0xCD040E08,
+ 0xC11C0002, 0xC000082C, 0xCD040E08, 0xC0000824, 0x00000000, 0xCBC00001, 0xCB800001, 0xCB400001,
+ 0xCB000000, 0xC0004878, 0x5BFC4000, 0xCFC00001, 0x5BB84000, 0xCF800001, 0x5B744000, 0xCF400001,
+ 0x5B304000, 0xCF000000, 0xC0000A10, 0x00000000, 0xCBC00001, 0xCB800000, 0xC0004874, 0x5BFC4000,
+ 0xCFC00001, 0x5BB84000, 0xCF800000, 0xC30001FE, 0xC000140A, 0xCF000000, 0xC3000000, 0x7F018000,
+ 0xC000042E, 0xCF000000, 0xC000040E, 0xCF000000, 0xC3C1FFFE, 0xC000490E, 0xCFC00080, 0xC000492C,
+ 0xCFC00080, 0xC0004924, 0xCFC00040, 0xC0004912, 0xCFC00040, 0xC0004966, 0xCFC00040, 0xC0004968,
+ 0xCFC00080, 0xC000496A, 0xCFC00080, 0xC3C1FFFE, 0xC00049A0, 0xCFC00000, 0xC3C00000, 0xC2800020,
+ 0xC3000000, 0x7F018000, 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB84A00, 0x5838000A, 0xCF000000,
+ 0x5BFC0002, 0xB7E8FFA8, 0x00000000, 0xC3C00000, 0xC2800010, 0x6FF86000, 0x47F9C000, 0x5BB84C80,
+ 0xC3400000, 0x58380004, 0xCB420080, 0x00000000, 0x58380008, 0xCF400080, 0x5BFC0002, 0xB7E8FF90,
+ 0x00000000, 0xC3C00000, 0xC2800020, 0xC348001E, 0xC3000000, 0x7F018000, 0x6FF8A000, 0x6FD44000,
+ 0x4579C000, 0x47F9C000, 0x5BB84E20, 0x58380008, 0xCF400420, 0x5838000A, 0xCF000000, 0x5BFC0002,
+ 0xB7E8FF90, 0x00000000, 0x00000000, 0xC3E02242, 0x5BFC0022, 0xC0004002, 0xCFC00000, 0x00000000,
+ 0xC121FFFE, 0x5911FE14, 0x15000000, 0x80000518, 0x00000000, 0x80002118, 0x00000000, 0x8000FFC8,
+ 0xC0004958, 0xC8400000, 0x00000000, 0xC3C00002, 0x7BC42000, 0xCC400000, 0xC0004848, 0xCB840000,
+ 0xC000495C, 0xCAC40000, 0xC0004844, 0xC8840000, 0x46F90000, 0x8400FF6A, 0xC000487C, 0xC8040000,
+ 0x00000000, 0x00000000, 0x40080000, 0xCA000000, 0xC0001624, 0xCB040000, 0xA63C005A, 0x00000000,
+ 0x00000000, 0xA71EFF02, 0x00000000, 0xC0000824, 0xCA840000, 0x6CA08000, 0x6CA42000, 0x46610000,
+ 0x42290000, 0xC35E0002, 0xC6340068, 0xC0001624, 0xCF440080, 0xC2000000, 0xC161FFFE, 0x5955FFFE,
+ 0x15400000, 0x00000000, 0xC0004844, 0xC8840000, 0xC000082C, 0xCA040040, 0x00000000, 0x00000000,
+ 0x58880002, 0xB608FFF8, 0x00000000, 0xC0800000, 0xC0004844, 0xCC840040, 0x5AEC0002, 0xC000495C,
+ 0xCEC40000, 0x5E6C0006, 0x84000048, 0xC0004848, 0xCB840000, 0xC0000838, 0xC2500002, 0xCE440808,
+ 0x5FB80002, 0xC0004848, 0xCF840000, 0x5EEC0002, 0xC000495C, 0xCEC40000, 0x00000000, 0xC121FFFE,
+ 0x5911FE14, 0x15000000, 0x8000FD80, 0xC000495A, 0xC8400000, 0x00000000, 0xC3C00002, 0x7BC42000,
+ 0xCC400000, 0xC0004960, 0xCAC40000, 0x00000000, 0x00000000, 0x5EEC0000, 0x840000F2, 0x00000000,
+ 0xB6FC0030, 0xC0001600, 0xCA040000, 0x00000000, 0x00000000, 0xA61E00B2, 0x6FE90000, 0xC0000A28,
+ 0xCE840808, 0xC2C00000, 0xC2800004, 0xB6E80080, 0xC0001604, 0xCA840000, 0xC0004960, 0xCEC40000,
+ 0xA69EFCA2, 0x00000000, 0x6FE90000, 0xC0000A28, 0xCE840808, 0xC2C00002, 0xC0001600, 0xCA040000,
+ 0x00000000, 0x00000000, 0xA61E000A, 0x6FE90000, 0xC0000A28, 0xCE840808, 0xC2C00000, 0xC0001604,
+ 0xCA840000, 0xC0004960, 0xCEC40000, 0xA69EFC0A, 0xC2400000, 0xC0000A14, 0xCA440030, 0x00000000,
+ 0x00000000, 0x46E52000, 0xA4400000, 0xC2800000, 0xDFEB0031, 0x8000FFF8, 0xDFEA0031, 0xB668FB82,
+ 0x00000000, 0xC00048A0, 0xCB040000, 0xC0000A10, 0xCA840000, 0x6F208000, 0x6F242000, 0x46610000,
+ 0x42A10000, 0xC2400000, 0xC0000A14, 0xCA440030, 0xC35E0002, 0xC6340068, 0xC0001604, 0xCF440080,
+ 0x5B300002, 0xB670FFF8, 0x5AEC0002, 0xC3000000, 0xC00048A0, 0xCF040000, 0xC0004960, 0xCEC40000,
+ 0x8000FAC0, 0xC0004918, 0xD2800000, 0xC2000000, 0xDF600040, 0x5E600080, 0x8400025A, 0x00000000,
+ 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0xC000480A, 0xCA000000, 0xC0004912, 0xCA400000,
+ 0xC0004924, 0xCA800000, 0xC0004966, 0xCAC00000, 0x00000000, 0xC121FFFE, 0x5911FE14, 0x15000000,
+ 0x76610000, 0x76A10000, 0x76E10000, 0x840001B2, 0xC0004918, 0xCA400000, 0xC28001FE, 0x76A10000,
+ 0x5A640002, 0x6A254010, 0x5EE80000, 0x84000002, 0x6AA54000, 0x8000FFF8, 0xC6280000, 0x62818008,
+ 0xC0004918, 0xCF000000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0xC0004966, 0xCA400000,
+ 0xC2000002, 0x6A310000, 0x7E010000, 0x76252000, 0xCE400000, 0x00000000, 0xC121FFFE, 0x5911FE14,
+ 0x15000000, 0x6F346000, 0x4735A000, 0x5B744C80, 0xC2800000, 0x58340006, 0xCA800080, 0xC2C00000,
+ 0x58340000, 0xCAC000E0, 0xC2400000, 0x5834000A, 0xCA420080, 0x6EA82000, 0x42E9E000, 0x6F2CA000,
+ 0x42E56000, 0x5AEC1400, 0xC3990040, 0xC7381C20, 0xC6F80068, 0x99005B78, 0xDB980000, 0xDBD80001,
+ 0x00000000, 0xDEA00000, 0x47210000, 0x8400FD68, 0xC0004958, 0xC8400000, 0x00000000, 0xC3C00002,
+ 0x7BC42000, 0xCC400000, 0xC0004848, 0xCB840000, 0xC0004844, 0xC8840000, 0x5FB80000, 0x8400F7DA,
+ 0xC0001A1C, 0xCA000000, 0xC2400002, 0x6A452000, 0x76610000, 0x8400F7AA, 0xC000487C, 0xC8040000,
+ 0x00000000, 0x00000000, 0x40080000, 0xCA000000, 0xC4240000, 0x00000000, 0xA63C17BA, 0x00000000,
+ 0xC0004878, 0xC8040000, 0x6C908000, 0x44908000, 0x44908000, 0x40100000, 0xCA000000, 0xC4240000,
+ 0x00000000, 0xC0004934, 0xCE000000, 0xC2800002, 0xC4681C10, 0xC62821D8, 0xC2600010, 0x5A650040,
+ 0xC0004800, 0xCB400000, 0xC2200400, 0x5A200000, 0xC7601048, 0xC0001220, 0xCE800000, 0xC0001200,
+ 0xCE400000, 0xC0001202, 0xCE000000, 0xC0001240, 0xCB400000, 0x00000000, 0x00000000, 0xA754FFC0,
+ 0xC2000000, 0xC7600048, 0xA7520022, 0x00000000, 0x00000000, 0x990062F0, 0xC0004822, 0xC9400000,
+ 0xC1800002, 0x80001668, 0x58204080, 0xC2000000, 0xCA000020, 0xC2400000, 0xCA414008, 0xC2800000,
+ 0xCA812008, 0xC2C00000, 0xCAC20020, 0xC0004938, 0xCE000000, 0xC0004920, 0xCE400000, 0xC0004916,
+ 0xCE800000, 0xC0004922, 0xCEC00000, 0xA6400520, 0x00000000, 0xC0004938, 0xCBC00000, 0x00000000,
+ 0xC3800000, 0x6FF48000, 0x6FD44000, 0x4355A000, 0x5B744A00, 0x58340000, 0xCB802018, 0x00000000,
+ 0xC2000000, 0x6FB46000, 0x47B5A000, 0x5B744C80, 0x5834000C, 0xCA000028, 0xC000491A, 0xCF800000,
+ 0x5E200000, 0x84000452, 0xC2000000, 0xDF610050, 0x5E6001E8, 0x8800FFD0, 0xC2000002, 0xC2400466,
+ 0xC2A00000, 0x5AA80000, 0xC0001006, 0xCE000000, 0xC0001008, 0xCE400000, 0xC000100A, 0xCE800000,
+ 0x990055B8, 0xC1A0FFFE, 0xC0000824, 0xC9840068, 0xC0004934, 0xCA400000, 0xC2000000, 0xC2800002,
+ 0x990055F8, 0xDA980000, 0xC6140000, 0xC6580000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000,
+ 0x990056E0, 0xC000491A, 0xC9400000, 0x00000000, 0x00000000, 0xC121FFFE, 0x5911FE14, 0x15000000,
+ 0xC0004922, 0xCA001120, 0xC3C00000, 0xC3800000, 0xC0004930, 0xCE001120, 0xC0004932, 0xCBC000E0,
+ 0xC2800000, 0xC000491E, 0xCFC00000, 0xC0004862, 0xCA800068, 0xC3A0001A, 0x5BB94000, 0xC6B80068,
+ 0xC000491C, 0xCF800000, 0x99005950, 0xC000491C, 0xC1400000, 0xC9420050, 0x00000000, 0x00000000,
+ 0x00000000, 0xA8E2FFC8, 0xC2000000, 0xC1220002, 0xD90C0000, 0xDF600040, 0x5E600080, 0x8400FFDA,
+ 0xC000491C, 0xCA000000, 0xC000491E, 0xCA400000, 0x00000000, 0x00000000, 0x99005B78, 0xDA180000,
+ 0xDA580001, 0x00000000, 0xC2000000, 0xDF610050, 0x5E6001FE, 0x8800FFD0, 0xC0004916, 0xCA800000,
+ 0xC2C00000, 0xDFEC0050, 0xC2400000, 0x46E52000, 0x84000032, 0x5EA80000, 0x84000022, 0xC2600002,
+ 0x990062F0, 0xC000482E, 0xC9400000, 0xC1800002, 0x80000018, 0xC2600000, 0x990062F0, 0xC000482C,
+ 0xC9400000, 0xC1800002, 0xC2000068, 0xC6240080, 0xC0004930, 0xCE400088, 0xC000491A, 0xC9800000,
+ 0xC0004862, 0xC9400000, 0x6D9C6000, 0x459CE000, 0x59DC4C80, 0x990059D8, 0xD9580000, 0xD9980001,
+ 0xD9D40000, 0x99005950, 0xC000491C, 0xC1400000, 0xC9420050, 0xC2000000, 0xDF600040, 0x5E600080,
+ 0x8400FFD2, 0x00000000, 0xC000491C, 0xCA000000, 0xC000491E, 0xCA400000, 0x00000000, 0x00000000,
+ 0x99005B78, 0xDA180000, 0xDA580001, 0x00000000, 0x800010D0, 0x00000000, 0x990062F0, 0xC000482A,
+ 0xC9400000, 0xC1800002, 0x800010A0, 0xC0004938, 0xCBC00000, 0x00000000, 0x00000000, 0x6FF88000,
+ 0x6FD44000, 0x4395C000, 0x5BB84A00, 0x58380008, 0xCA000000, 0x00000000, 0x00000000, 0xA6000362,
+ 0x00000000, 0xC0004938, 0xCBC00000, 0xC3000000, 0x00000000, 0x6FF88000, 0x6FD44000, 0x4395C000,
+ 0x5BB84A00, 0x58380000, 0xCB002018, 0xC2000000, 0x58380008, 0xCA020080, 0x5838000C, 0xCAC00000,
+ 0x5838000E, 0xCA400000, 0xC000491A, 0xCF000000, 0xC0004930, 0xCEC00000, 0xC000493C, 0xCE000000,
+ 0xC0004932, 0xCE400000, 0x5E200000, 0x84000108, 0xC2800000, 0xA6FE009A, 0x6F206000, 0x47210000,
+ 0x5A204C80, 0x5820000C, 0xCA800028, 0x00000000, 0x00000000, 0x5EA80000, 0x840001DA, 0x00000000,
+ 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x990056E0, 0xC000491A, 0xC9400000, 0x00000000,
+ 0x00000000, 0xC121FFFE, 0x5911FE14, 0x15000000, 0xC0004930, 0xCAC00000, 0xC0004932, 0xCA400000,
+ 0xC7EC1120, 0xC0004930, 0xCEC00000, 0x5838000C, 0xCEC00000, 0x58000002, 0xCE400000, 0xC0004934,
+ 0xCA000000, 0xC2400002, 0x6E642000, 0x6E642000, 0x76252000, 0x84000012, 0xC2400002, 0x6E684000,
+ 0x58380008, 0xCE800208, 0xA6000000, 0x6E682000, 0x58380008, 0xCE800108, 0xC2400002, 0x6E642000,
+ 0x76252000, 0x840000D2, 0x58380008, 0xCA000000, 0xC2800000, 0xC2400000, 0xA60200A0, 0xDBA80000,
+ 0x6F386000, 0x4739C000, 0x5BB84C80, 0x58380004, 0xCA400080, 0x58380002, 0xCA800080, 0x00000000,
+ 0xDEB80000, 0x46694000, 0x88000048, 0x00000000, 0xC0004824, 0xCA000000, 0xC2400002, 0x6E640000,
+ 0x5A200002, 0xCE000000, 0x58380008, 0xCE400008, 0x80000000, 0x00000000, 0x80000030, 0xC0004934,
+ 0xCA000000, 0x00000000, 0x00000000, 0xA6020C4A, 0x00000000, 0x00000000, 0x80000C80, 0xC2800000,
+ 0xC2000200, 0xC240001A, 0xDF690050, 0x46A14000, 0x46694000, 0x8800FFBA, 0xC2000006, 0xC2600982,
+ 0x5A643B6E, 0x5838000A, 0xCA800000, 0xC0001006, 0xCE000000, 0xC0001008, 0xCE400000, 0xC000100A,
+ 0xCE800000, 0x990055B8, 0xC1A0FFFE, 0xC0000824, 0xC9840068, 0xC2000000, 0xC0004930, 0xCA02E010,
+ 0x58380026, 0xCA400000, 0x00000000, 0xC2800000, 0x990055F8, 0xDA980000, 0xC6140000, 0xC6580000,
+ 0xC0004934, 0xCA000000, 0x00000000, 0x00000000, 0xA6020002, 0x00000000, 0x00000000, 0x80000300,
+ 0xC0004938, 0xCBC00000, 0xC0004878, 0xC8040000, 0x6C908000, 0x44908000, 0x44908000, 0x40100000,
+ 0xCA000000, 0xC4240000, 0x00000000, 0x58240018, 0xCA000000, 0x6FF88000, 0x6FD44000, 0x4395C000,
+ 0x5BB84A00, 0xC3000000, 0xC3400002, 0xC2C00000, 0xC62C0080, 0xC6270040, 0xC0004940, 0xCE400040,
+ 0xC6260040, 0xC0004942, 0xCE400040, 0xC000493C, 0xCA000000, 0x5EEC0000, 0x84000172, 0x5A6C0010,
+ 0x46614000, 0x88000178, 0x5A600052, 0x466D4000, 0x88000160, 0x58380006, 0xCA800000, 0xC0004940,
+ 0xCA000000, 0xC2400000, 0xC6A70040, 0x7E412000, 0x76252000, 0xC2000000, 0xC6A10040, 0x46610000,
+ 0x84000120, 0xC0004942, 0xCA000000, 0xC2400000, 0xC6A60040, 0x7E412000, 0x76252000, 0xC2000000,
+ 0xC6A00040, 0x58380002, 0xCA800000, 0x46610000, 0x840000D0, 0xC2400000, 0xC6A60080, 0x46E50000,
+ 0x880000C2, 0xC2400000, 0xC6A40080, 0x58380008, 0xCA800000, 0x466D0000, 0x880000A2, 0x00000000,
+ 0xA682FFF8, 0x00000000, 0xC7700B08, 0xA6840078, 0x00000000, 0xC7700A08, 0x80000068, 0xC7700208,
+ 0xC000493C, 0xCAC00000, 0x80000048, 0xC7700308, 0xC000493C, 0xCAC00000, 0x80000028, 0xC7700908,
+ 0x80000018, 0xC7700808, 0x80000008, 0xC7700708, 0x8000FFF8, 0xC7700508, 0xC0004944, 0xCF000000,
+ 0xC000493E, 0xCEC00000, 0xC0004938, 0xCA400000, 0xC000493C, 0xCB800000, 0xC000493E, 0xCB400000,
+ 0xC3000000, 0x6E608000, 0x6E544000, 0x42150000, 0x5A204A00, 0x5AA00008, 0x58200004, 0xCB000080,
+ 0xC0004934, 0xCA000000, 0xC2400000, 0xC0004930, 0xCA42E010, 0xC3C00018, 0xA6020078, 0x00000000,
+ 0x43656000, 0x46F90000, 0x88000038, 0x47AD6000, 0x6EE04010, 0x5BE00004, 0xC2000000, 0xC6E00010,
+ 0x5E200000, 0x8400002A, 0x5BFC0002, 0x80000018, 0xC3C00004, 0x5A2C0008, 0x46390000, 0x8800FFFA,
+ 0x5FB80008, 0x6FE04000, 0x42390000, 0x46312000, 0x88000050, 0xC2400000, 0xC0004930, 0xCA42E010,
+ 0xC2060002, 0xC6800000, 0xCE000308, 0x6FE04000, 0x4631C000, 0x5F700010, 0x4675A000, 0xC2000000,
+ 0xC6340010, 0xC25A000A, 0xC000491A, 0xCA401C20, 0xC2800000, 0xC0004932, 0xCA8000E0, 0xC0004862,
+ 0xCA400068, 0x6FA04010, 0x42290000, 0xC000491E, 0xCE000000, 0xC7E41050, 0xC000491C, 0xCE400000,
+ 0x6FE04000, 0x43A1C000, 0xC000493C, 0xCF800000, 0xC000493E, 0xCF400000, 0xC000493A, 0xCFC00000,
+ 0x8000FFF0, 0x00000000, 0x00000000, 0x00000000, 0xC2000000, 0xDCE00000, 0xA622FFB8, 0xC1220002,
+ 0xD90C0000, 0xC0004938, 0xCBC00000, 0xC0004944, 0xCB400000, 0xC0004862, 0xCB000000, 0xC0004934,
+ 0xCA000000, 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB84A00, 0xA6020248, 0xC2400000, 0x58380008,
+ 0xCA406008, 0xDFE80000, 0xC2218E08, 0x5A21BAF6, 0x46294000, 0x8400000A, 0xC2080002, 0x7235A000,
+ 0x80000040, 0x5E640000, 0x8400000A, 0xC20C0002, 0x7235A000, 0x80000018, 0xC2000000, 0xC760E718,
+ 0xC7604220, 0x5E200000, 0x8400025A, 0xC2200002, 0xC0004930, 0xCE001008, 0x990062F0, 0xC0004828,
+ 0xC9400000, 0xC1800002, 0x58380000, 0xCA000000, 0x00000000, 0x00000000, 0xA6000112, 0xC0004940,
+ 0xCA800000, 0xC0004942, 0xCA400000, 0xC7600080, 0xC6A01840, 0xC6601040, 0xC000493A, 0xCA400000,
+ 0xC0004934, 0xCA800000, 0xC0007200, 0x40300000, 0x40240000, 0x5C000004, 0x5EC07400, 0x8800FFFA,
+ 0x5C000200, 0xCE000000, 0x58000002, 0x5EC07400, 0x8800FFFA, 0x5C000200, 0xCE800000, 0xC000493E,
+ 0xCA000000, 0xC2400000, 0x5838000C, 0xCE400000, 0x990062F0, 0xC0004830, 0xC9400000, 0xC6180000,
+ 0xC0004930, 0xC6100080, 0xCD000080, 0x80000090, 0xC2400002, 0x58380008, 0xCE400008, 0xC0004944,
+ 0xCF400000, 0x80000260, 0xC000493C, 0xCA400000, 0xDFE80000, 0x5A300018, 0xC0007200, 0x40200000,
+ 0xCA000000, 0x58380008, 0xC6501080, 0xCD001080, 0x5838000A, 0xCE800000, 0x58380026, 0xCE000000,
+ 0xC0004944, 0xCF400000, 0x99005950, 0xC000491C, 0xC1400000, 0xC9420050, 0x80000020, 0x00000000,
+ 0x990062F0, 0xC0004826, 0xC9400000, 0xC1800002, 0x8000FDC0, 0xC2000000, 0xC2400080, 0xDF600040,
+ 0xB624FFCA, 0xC000491C, 0xCA400000, 0xC000491E, 0xCA800000, 0x99005B78, 0xDA580000, 0xDA980001,
+ 0x00000000, 0xC0004934, 0xCA000000, 0x00000000, 0xC2800000, 0xA6020140, 0xC2400004, 0xC2000200,
+ 0xDF690050, 0x46A14000, 0x46694000, 0x8800FFC2, 0x00000000, 0xC000491A, 0xC9800000, 0xC0004862,
+ 0xC9400000, 0x6D9C6000, 0x459CE000, 0x59DC4C80, 0x990059D8, 0xD9580000, 0xD9980001, 0xD9D40000,
+ 0x99005950, 0xC000491C, 0xC1400000, 0xC9420050, 0xC2000000, 0xC2400080, 0xDF600040, 0xB624FFCA,
+ 0xC000491C, 0xCA400000, 0xC000491E, 0xCA800000, 0x99005B78, 0xDA580000, 0xDA980001, 0x00000000,
+ 0x58380008, 0xCA400000, 0xC2000000, 0xCE000020, 0xC2A1FFFE, 0x5AA9FFFE, 0xCE001080, 0x5838000A,
+ 0xCE800000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0xC0000838, 0xC2500002, 0xCE440808,
+ 0xC0004848, 0xCB840000, 0xC2000000, 0xC000082C, 0xCA040030, 0x5FB80002, 0xC0004848, 0xCF840000,
+ 0x58880002, 0xB608FFF8, 0x00000000, 0xC0800000, 0xC0004844, 0xCC840000, 0x00000000, 0xC121FFFE,
+ 0x5911FE14, 0x15000000, 0x8000DEC0, 0xC2000000, 0xDF600040, 0x5E200080, 0x84000252, 0x00000000,
+ 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0xC000480C, 0xCA000000, 0xC0004910, 0xCA400000,
+ 0xC000492C, 0xCA800000, 0xC0004968, 0xCAC00000, 0x00000000, 0xC121FFFE, 0x5911FE14, 0x15000000,
+ 0x76610000, 0x76A10000, 0x762D6000, 0x840001AA, 0xC0004926, 0xCA400000, 0xC201FFFE, 0x762D6000,
+ 0x5A640002, 0x6AE50010, 0x5F200000, 0x84000002, 0x6A250000, 0x8000FFF8, 0xC6E00000, 0x62014008,
+ 0xC0004926, 0xCE800000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0xC0004968, 0xCA400000,
+ 0xC2000002, 0x6A290000, 0x7E010000, 0x76252000, 0xCE400000, 0x00000000, 0xC121FFFE, 0x5911FE14,
+ 0x15000000, 0x6EB4A000, 0x6E944000, 0x4575A000, 0x46B5A000, 0x5B744E20, 0x58340002, 0xC2000000,
+ 0xCA0000E0, 0x5834002E, 0xC2400000, 0xCA400080, 0x6EB0A000, 0x6EBC4000, 0x47F18000, 0x46B18000,
+ 0x5B300E4E, 0x5B300004, 0x6E642000, 0x4225E000, 0xC39A8024, 0xC7380068, 0xC6B81C20, 0x99005B78,
+ 0xDB980000, 0xDBD80001, 0x00000000, 0xC2000000, 0xDF600040, 0x5E200080, 0x8400033A, 0x00000000,
+ 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0xC000490E, 0xCA000000, 0xC00049A0, 0xCA800000,
+ 0xC000492A, 0xCA400000, 0xC000496A, 0xCB000000, 0xC0004956, 0xCAC00000, 0x00000000, 0xC121FFFE,
+ 0x5911FE14, 0x15000000, 0x76318000, 0x76718000, 0x76B18000, 0x84000282, 0xC201FFFE, 0x76318000,
+ 0x5AEC0002, 0x6B2D0010, 0x5EA00000, 0x84000002, 0x6A2D0000, 0x8000FFF8, 0xC7200000, 0x62016008,
+ 0xC0004956, 0xCEC00000, 0x6EF4A000, 0x6ED44000, 0x4575A000, 0x46F5A000, 0x5B744E20, 0x58340000,
+ 0xC9C00000, 0xC00049A0, 0xCA000000, 0xC3000000, 0xC5F04020, 0xC2400000, 0xC5E50040, 0x7E412000,
+ 0x76610000, 0xCE000000, 0xC0004980, 0x40300000, 0xCEC00000, 0xC161FFFE, 0x5955FFFE, 0x15400000,
+ 0x00000000, 0xC000496A, 0xCA400000, 0xC2000002, 0x6A2D0000, 0x7E010000, 0x76252000, 0xCE400000,
+ 0x00000000, 0xC121FFFE, 0x5911FE14, 0x15000000, 0x6EF4A000, 0x6ED44000, 0x4575A000, 0x46F5A000,
+ 0x5B744E20, 0x5834000E, 0xC2000000, 0xCA0000E0, 0x58340008, 0xC2400000, 0xCA420080, 0x5834000C,
+ 0xC2800000, 0xCA832018, 0x6E644010, 0x42250000, 0x4229E000, 0xC39A8008, 0x58340008, 0xCB809020,
+ 0x58340008, 0xC2800000, 0xCA810018, 0x6EE0A000, 0x6EE44000, 0x46610000, 0x46E10000, 0x5A200008,
+ 0x5A200E28, 0x42290000, 0xC6380068, 0xC6F81C20, 0x99005B78, 0xDB980000, 0xDBD80001, 0x00000000,
+ 0xC000495A, 0xC8400000, 0x00000000, 0xC3C00002, 0x7BC42000, 0xCC400000, 0xC0001A1C, 0xCA000000,
+ 0xC2400008, 0x6A452000, 0x76610000, 0x84000EAA, 0xC0000A28, 0xC3800000, 0xCB840030, 0xC0000A14,
+ 0xC3400000, 0xCB440030, 0xC0004880, 0xCB040000, 0xB7B40052, 0x58041802, 0xCAC00000, 0xA7000058,
+ 0x00000000, 0x00000000, 0xA6C8D7E8, 0xC1000000, 0xC6D00020, 0xC0004980, 0x40100000, 0xCA800000,
+ 0x80000058, 0x00000000, 0x00000000, 0x00000000, 0x8000D7A0, 0x00000000, 0xC2800000, 0xC7282020,
+ 0xC000490E, 0xCA400000, 0x6BE9E000, 0x00000000, 0x77E52000, 0x8400D758, 0x6EA0A000, 0x6E944000,
+ 0x45610000, 0x46A10000, 0x5A204E20, 0x5820000C, 0xCA000000, 0xC0004946, 0xCE800000, 0xA6220388,
+ 0x00000000, 0xC2200060, 0xC0004948, 0xCE000010, 0xCE001040, 0xC240000A, 0xC000494A, 0xCE400000,
+ 0xC2B60002, 0xC0004964, 0xCE801B08, 0x99005E48, 0xC00048A0, 0xC8840000, 0x00000000, 0xC0004946,
+ 0xCBC00000, 0x00000000, 0x00000000, 0x6FF8A000, 0x6FD44000, 0x4579C000, 0x47F9C000, 0x5BB84E20,
+ 0x99005C08, 0xDBD80000, 0xDB980001, 0x00000000, 0x99005950, 0xC000491C, 0xC1400000, 0xC9420050,
+ 0xC000491C, 0x99005E00, 0xC9400001, 0xC9800000, 0x00000000, 0x99005B78, 0xD9580000, 0xD9980001,
+ 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x99005840, 0xDBD80000, 0xDB980001,
+ 0xC7D80000, 0x00000000, 0xC121FFFE, 0x5911FE14, 0x15000000, 0x6FF8A000, 0x6FD44000, 0x4579C000,
+ 0x47F9C000, 0x5BB84E20, 0x58380010, 0xCA000000, 0xC0004874, 0xC8040000, 0x6C908000, 0x44908000,
+ 0x44908000, 0x40100000, 0xCA400000, 0xC4340000, 0x00000000, 0xC7400000, 0xCE000000, 0xC161FFFE,
+ 0x5955FFFE, 0x15400000, 0x00000000, 0xC000490E, 0xCA400000, 0xC2800002, 0x6ABD4000, 0x72A52000,
+ 0xCE400000, 0x00000000, 0xC121FFFE, 0x5911FE14, 0x15000000, 0x990062F0, 0xC0004836, 0xC9400000,
+ 0xC1800002, 0x00000000, 0x00000000, 0x00000000, 0xA8E2FFC8, 0x00000000, 0x58380000, 0xC9000000,
+ 0xC00049A0, 0xCA000000, 0xC2800000, 0xC5290040, 0x72A10000, 0xCE000000, 0xC1220002, 0xD90C0000,
+ 0xC2000000, 0xC0000A14, 0xCA040030, 0xC0000A28, 0xC2500002, 0xCE440808, 0x58880002, 0xB608FFF8,
+ 0xC00048A0, 0xC0800000, 0xCC840000, 0x8000D368, 0xC0004946, 0xCBC00000, 0xC161FFFE, 0x5955FFFE,
+ 0x15400000, 0x00000000, 0xC000490E, 0xCA400000, 0xC2800002, 0x6ABD4000, 0x72A52000, 0xCE400000,
+ 0x00000000, 0xC121FFFE, 0x5911FE14, 0x15000000, 0x6FF8A000, 0x6FD44000, 0x4579C000, 0x47F9C000,
+ 0x5BB84E20, 0x58380008, 0xCA000000, 0x5838000C, 0xCA400000, 0xC3400000, 0xC6340008, 0xC000494E,
+ 0xCF400000, 0xC2800000, 0xC62A0080, 0xC3000000, 0xC6308020, 0x6F304000, 0x43298000, 0xC000493C,
+ 0xCF000000, 0xC2C00000, 0xC66C0080, 0xC0004950, 0xCEC00000, 0xC2800000, 0xC66AE028, 0xC0004954,
+ 0xCE800000, 0x5F740000, 0x84000188, 0x5E300028, 0x462D2000, 0x84000152, 0x462D2000, 0x8800011A,
+ 0x5E300018, 0x462D2000, 0x88000012, 0x462D2000, 0x8400002A, 0x00000000, 0x800000A8, 0x00000000,
+ 0x99005F88, 0xDBD80000, 0xDB980001, 0xC7800000, 0xC3400002, 0xC000494E, 0xCF400000, 0xC161FFFE,
+ 0x5955FFFE, 0x15400000, 0x00000000, 0xC000490E, 0xCA400000, 0xC2800002, 0x6ABD4000, 0x7E814000,
+ 0x76A52000, 0xCE400000, 0x00000000, 0xC121FFFE, 0x5911FE14, 0x15000000, 0xC2200060, 0xC0004948,
+ 0xCE001040, 0xC2000000, 0xC000494C, 0xCE000000, 0x80000068, 0x00000000, 0x99005F88, 0xDBD80000,
+ 0xDB980001, 0xC7800000, 0x99006188, 0xDBD80000, 0xDB980001, 0xC7800000, 0xC2200058, 0xC0004948,
+ 0xCE001040, 0xC2000002, 0xC000494C, 0xCE000000, 0xC2000006, 0xC0001006, 0xCE000000, 0x5838000A,
+ 0xCA400000, 0xC2200982, 0x5A203B6E, 0xC0001008, 0xCE000000, 0xC000100A, 0xCE400000, 0xC0004954,
+ 0xCA800000, 0xC200000C, 0xC000494A, 0xCE000000, 0xC0004948, 0xCE800010, 0xC2B60000, 0xC0004964,
+ 0xCE800000, 0x99005E48, 0xC00048A0, 0xC8840000, 0x00000000, 0xC0004946, 0xCBC00000, 0xC000494C,
+ 0xCA000000, 0x6FF8A000, 0x6FD44000, 0x4579C000, 0x47F9C000, 0x5BB84E20, 0x5E200000, 0x840000E2,
+ 0x00000000, 0x99005C08, 0xDBD80000, 0xDB980001, 0x00000000, 0x99005950, 0xC000491C, 0xC1400000,
+ 0xC9420050, 0xC000491C, 0x99005E00, 0xC9400001, 0xC9800000, 0x00000000, 0x99005B78, 0xD9580000,
+ 0xD9980001, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x99005840, 0xDBD80000,
+ 0xDB980001, 0xC7D80000, 0x00000000, 0xC121FFFE, 0x5911FE14, 0x15000000, 0xC000493C, 0xCA800000,
+ 0xC000494E, 0xCAC00000, 0xC3000018, 0xC3400006, 0x5E200000, 0x84000012, 0xC2800000, 0xC2C00000,
+ 0xC300001E, 0xC3400000, 0xC6AC1080, 0xC72C0420, 0xC76C0818, 0x58380010, 0xCA800000, 0x58380008,
+ 0xCEC00000, 0xC6280108, 0xC0004874, 0xC8040000, 0x6C908000, 0x44908000, 0x44908000, 0x40100000,
+ 0xCB000000, 0xC4340000, 0x00000000, 0xC7400000, 0xCE800000, 0xC0004952, 0xCE800000, 0x00000000,
+ 0x00000000, 0x00000000, 0xA8E2FFC8, 0x00000000, 0xC000494C, 0xCA000000, 0xC0004950, 0xCAC00000,
+ 0x5E200000, 0x84000052, 0xDFE80000, 0x7E814000, 0x5834001A, 0xCE800000, 0x990062F0, 0xC0004834,
+ 0xC9400000, 0xC1800002, 0x990062F0, 0xC0004838, 0xC9400000, 0xC6D80000, 0xC1220002, 0xD90C0000,
+ 0x5E200000, 0x84000028, 0x5838002C, 0xCB000000, 0xDFE80000, 0x00000000, 0x58380014, 0xCF000000,
+ 0x80000040, 0xC2A1FFFE, 0x5AA9FFFE, 0x58380000, 0xC9000000, 0xC00049A0, 0xCB000000, 0xC2C00000,
+ 0xC52D0040, 0x72F18000, 0xCF000000, 0x5838000A, 0xCE800000, 0xC3000000, 0xC0000A14, 0xCB040030,
+ 0xC2D00002, 0xC0000A28, 0xCEC40808, 0xC000494E, 0xCA800000, 0x58880002, 0xB4B0FFF8, 0xC00048A0,
+ 0xC0800000, 0xCC840000, 0x5EA80000, 0x84000162, 0x5E200000, 0x84000150, 0xC000493C, 0xCA800000,
+ 0x00000000, 0x00000000, 0x5AA80060, 0xCE800000, 0x99005F88, 0xDBD80000, 0xDB980001, 0xC7800000,
+ 0x99006188, 0xDBD80000, 0xDB980001, 0xC7800000, 0x58380000, 0xCAC00000, 0x00000000, 0xC2000000,
+ 0xC6E04020, 0xC0004952, 0xCAC00000, 0x58380000, 0xCA800000, 0xC30C0002, 0xC6300020, 0xA6800078,
+ 0x00000000, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0xC0001800, 0xCA000000,
+ 0x00000000, 0x00000000, 0xA60CFFCA, 0xC6F00508, 0xC6B0C408, 0xCF000000, 0x00000000, 0xC121FFFE,
+ 0x5911FE14, 0x15000000, 0x8000C9B0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000C948,
+ 0xDCBC0001, 0x5FFC0000, 0x8400003A, 0xC3800002, 0xDB880001, 0x5FFC0004, 0x8400C27A, 0xC3800000,
+ 0xDB880001, 0xC3CE0002, 0xC0000800, 0xCFC00708, 0xC3E1FFFE, 0x597DFFFE, 0x593DFE14, 0x94000001,
+ 0x00000000, 0x00000000, 0x00000000, 0xC000487C, 0xC8040000, 0x00000000, 0x00000000, 0x40080000,
+ 0xCBC00000, 0xC4380000, 0x00000000, 0xC000480E, 0xCA000000, 0xC0004858, 0xCB440000, 0x00000000,
+ 0x00000000, 0x46350000, 0x88000098, 0x00000000, 0xA7C00028, 0xC0004854, 0xC1000002, 0xCD040000,
+ 0xC11C0000, 0xC000082C, 0xCD040E08, 0x800000C0, 0x00000000, 0xA7D20118, 0x00000000, 0xC7E14048,
+ 0xC2400000, 0xC6246030, 0xC200006A, 0x46610000, 0xC6240038, 0xC0000810, 0xCE440038, 0x8000FF58,
+ 0xC2000000, 0xC0000808, 0xCA040018, 0xC11C0000, 0xC000082C, 0xCD040E08, 0x5A200002, 0x5E600010,
+ 0x8400FFF8, 0xC2000000, 0xC0000808, 0xCE040018, 0xC3400000, 0x80000010, 0xC1200002, 0xC0000818,
+ 0xCD041008, 0x5B740002, 0xC0004858, 0xCF440000, 0x99005590, 0xC0004848, 0xC9440000, 0xC1800000,
+ 0xC11C0002, 0xC000082C, 0xCD040E08, 0x800005E8, 0x5B740002, 0xC0004858, 0xCF440000, 0xC7800000,
+ 0xC13C0002, 0xCD001E08, 0xC0004848, 0xC9440000, 0xC1800000, 0xC000082C, 0xC9840030, 0x59540002,
+ 0xC0004848, 0xCD440000, 0x58880002, 0xB4980560, 0x00000000, 0xC0800000, 0x80000550, 0xC000487C,
+ 0xC8040000, 0x00000000, 0x00000000, 0x40080000, 0xCBC00000, 0xC4280000, 0x00000000, 0xA7C00110,
+ 0xC000484C, 0xCA040000, 0xC2400000, 0xC0001AEC, 0xCA440020, 0x5A200002, 0xC000484C, 0xCE040000,
+ 0xB624006A, 0xC6800000, 0xC13C0002, 0xCD001E08, 0xC0004848, 0xC9440000, 0xC1800000, 0xC000082C,
+ 0xC9840030, 0x59540002, 0xC0004848, 0xCD440000, 0x58880002, 0xB4980450, 0x00000000, 0xC0800000,
+ 0x80000440, 0xC0004854, 0xC1000004, 0xCD040000, 0xC0000820, 0xC2000002, 0xCE040000, 0xC2000000,
+ 0xC000484C, 0xCE040000, 0xC0004858, 0xCE040000, 0x8000FF10, 0xC0004854, 0xC1000000, 0xCD040000,
+ 0xC11C0000, 0xC000082C, 0xCD040E08, 0x99005590, 0xC0004848, 0xC9440000, 0xC1800000, 0xC1200000,
+ 0xC0000818, 0xCD041008, 0xC11C0002, 0xC000082C, 0xCD040E08, 0xC2000000, 0xC000484C, 0xCE040000,
+ 0x80000340, 0xC0001AC0, 0xCB840000, 0xC000487C, 0xC8040000, 0x00000000, 0x00000000, 0x40080000,
+ 0xCBC00000, 0xC4280000, 0x00000000, 0x00000000, 0xC6800000, 0xC13C0000, 0xCD001E08, 0xA780022A,
+ 0x00000000, 0x00000000, 0xA7C001EA, 0x00000000, 0xC0001B00, 0xC2060006, 0xCE040310, 0xA7E801A2,
+ 0x00000000, 0xC0004850, 0xCA040000, 0xC2400000, 0xC0001AEC, 0xCA448020, 0x5A200002, 0xC0004850,
+ 0xCE040000, 0xB624008A, 0x00000000, 0xC6800000, 0xC13C0002, 0xCD001E08, 0xC0001ACC, 0xC2000002,
+ 0xCE040008, 0xC0004848, 0xC9440000, 0xC1800000, 0xC000082C, 0xC9840030, 0x59540002, 0xC0004848,
+ 0xCD440000, 0x58880002, 0xB49801A8, 0x00000000, 0xC0800000, 0x80000198, 0xC0004854, 0xC1000000,
+ 0xCD040000, 0xC11C0000, 0xC000082C, 0xCD040E08, 0x99005590, 0xC0004848, 0xC9440000, 0xC1800000,
+ 0xC2000000, 0xC0000820, 0xCE040000, 0xC1200000, 0xC0000818, 0xCD041008, 0xC11C0002, 0xC000082C,
+ 0xCD040E08, 0xC0004850, 0xCE040000, 0xC2000002, 0xC0001ACC, 0xCE040010, 0x800000D0, 0xC2000002,
+ 0xC0004850, 0xCE040000, 0x8000FE70, 0xC2000000, 0xC0004850, 0xCE040000, 0xA7E60012, 0x00000000,
+ 0xC2000002, 0xC0001B00, 0xCE040008, 0x8000FE58, 0x00000000, 0xA7860032, 0x00000000, 0xC6800000,
+ 0xC13C0002, 0xCD001E08, 0xC2020002, 0xC7E2A548, 0xC0001B00, 0xCE040000, 0x8000FE00, 0xC2040002,
+ 0xC0001B00, 0xCE040208, 0x8000FDE0, 0xC2C80002, 0x6AC56000, 0xDACC0000, 0xC0004854, 0xCB440000,
+ 0xC0004848, 0xCB840000, 0xC0000838, 0xC3C00000, 0xCBC40030, 0x5EF40004, 0x8400000A, 0xC3000000,
+ 0xC0001ACC, 0xCF040108, 0x47BD8000, 0x84000012, 0x47BD8000, 0x88000018, 0xC1006E8C, 0x8000B6B0,
+ 0xC0004840, 0xCC840000, 0x8000F698, 0xC0001AC0, 0xCAC40000, 0xC0004854, 0xCB440000, 0xA6C0FBB2,
+ 0x00000000, 0x5EF40000, 0x8400F6F2, 0x5EF40002, 0x8400F982, 0x5EF40004, 0x8400FB82, 0xC1006CE8,
+ 0x8000B628, 0x00000000, 0xC0800000, 0xDF4B0040, 0xC0004900, 0xCB800000, 0xC2000000, 0xC000490A,
+ 0xA78000B0, 0xCBC00000, 0xC1000000, 0xD9000001, 0xC1000002, 0xD90C0000, 0x6FF46000, 0x47F5A000,
+ 0x5B744C80, 0xC2400000, 0x58340004, 0xCA400080, 0xC0004900, 0xCE000008, 0x5A640002, 0x58340004,
+ 0xC6500080, 0xCD000080, 0xC0004914, 0xCA400000, 0xC2000002, 0x6A3D0000, 0x72252000, 0xCE400000,
+ 0xC0000408, 0xCE000000, 0xA78200B8, 0xC0004908, 0xCBC00000, 0xC1000000, 0xD9000001, 0xC1000002,
+ 0xD90C0000, 0x6FF4A000, 0x6FD44000, 0x4575A000, 0x47F5A000, 0x5B744E20, 0xC2800000, 0x58340006,
+ 0xCA800080, 0xC2000000, 0xC0004900, 0xCE000108, 0x5EA80002, 0x58340006, 0xC6900080, 0xCD000080,
+ 0x5A7C0020, 0xC2000002, 0x6A250000, 0xC0000408, 0xCE000000, 0xDCA80001, 0x5EA80000, 0x8400B498,
+ 0x00000000, 0xA4800210, 0x00000000, 0xC3C00000, 0xC000140E, 0xCBC00020, 0xC3400000, 0xC2400000,
+ 0x6FF86000, 0x47F9C000, 0x5BB84C80, 0x58380008, 0xCB400080, 0x58380006, 0xCA400080, 0x5F740002,
+ 0x58380008, 0xC7500080, 0xCD000080, 0xC2000000, 0x58380004, 0xCA020080, 0xC3000000, 0x5838000C,
+ 0xCB000028, 0x5A640002, 0x46250000, 0x8400FFF8, 0xC2400000, 0x58380006, 0xC6500080, 0xCD000080,
+ 0xC2000000, 0x5838000A, 0xCA020080, 0x5B300002, 0x5838000C, 0xC7100028, 0xCD000028, 0xC2420020,
+ 0x5A200004, 0x46612000, 0x8400FFF8, 0xC2000000, 0x5838000A, 0xC6101080, 0xCD001080, 0xC0004966,
+ 0xCA400000, 0xC2000002, 0x6A3D0000, 0x72252000, 0xCE400000, 0x5F740000, 0x84000028, 0xC0004912,
+ 0xCA000000, 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x76E10000, 0xCE000000, 0x5F300020, 0x84000028,
+ 0xC0004924, 0xCA000000, 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x76E10000, 0xCE000000, 0xA4820050,
+ 0xC2400000, 0xC000140E, 0xCA408020, 0xC2000002, 0xC0004900, 0xCE000008, 0xC000490A, 0xCE400000,
+ 0xC1000000, 0xD9000001, 0xD8400080, 0xC1000004, 0xD9000001, 0xA4840250, 0x00000000, 0xC3C00000,
+ 0xC000140E, 0xCBC10020, 0xC2800000, 0xC2000000, 0x6FF8A000, 0x6FD44000, 0x4579C000, 0x47F9C000,
+ 0x5BB84E20, 0x5838002E, 0xCA800080, 0x58380006, 0xCA020080, 0xC3400000, 0x5838002E, 0xCB420080,
+ 0x5AA80002, 0x46290000, 0x8400FFF8, 0xC2800000, 0x5838002E, 0xC6900080, 0xCD000080, 0x5F740002,
+ 0x5838002E, 0xC7501080, 0xCD001080, 0xC0004968, 0xCA400000, 0xC2000002, 0x6A3D0000, 0x72252000,
+ 0xCE400000, 0xC000492A, 0xCA800000, 0x5E740000, 0x84000028, 0xC0004910, 0xCA000000, 0xC2C00002,
+ 0x6AFD6000, 0x7EC16000, 0x76E10000, 0xCE000000, 0x6ABD4010, 0xA680009A, 0x00000000, 0x58380032,
+ 0xCA000000, 0x58000002, 0xCA400000, 0x5838000C, 0x00000000, 0xCE000001, 0xCE400000, 0xC000492A,
+ 0xCA000000, 0xC2C00002, 0x6AFD6000, 0x72E10000, 0xCE000000, 0xC000492C, 0xCA000000, 0xC2C00002,
+ 0x6AFD6000, 0x72E10000, 0xCE000000, 0x80000028, 0xC000492C, 0xCA000000, 0xC2C00002, 0x6AFD6000,
+ 0x7EC16000, 0x76E10000, 0xCE000000, 0xA4880128, 0xC2C00000, 0xC000140E, 0xCAC20020, 0xC000490E,
+ 0xCA400000, 0xC2000002, 0x6A2D0000, 0x7E010000, 0x76252000, 0xCE400000, 0xC000496A, 0xCA400000,
+ 0xC2000002, 0x6A2D0000, 0x72252000, 0xCE400000, 0x6EF0A000, 0x6ED44000, 0x45718000, 0x46F18000,
+ 0x5B304E20, 0x58300000, 0xCA000000, 0x00000000, 0xC2400002, 0x76252000, 0x8400005A, 0x58300000,
+ 0xCA400000, 0xC2800000, 0x00000000, 0xC6684020, 0xC24C0002, 0xC6A40020, 0xC624C408, 0x58300010,
+ 0xCA400508, 0x00000000, 0xC0001800, 0xCE400000, 0xA4860050, 0xC2400000, 0xC000140E, 0xCA418020,
+ 0xC2020002, 0xC0004900, 0xCE000108, 0xC0004908, 0xCE400000, 0xC1000000, 0xD9000001, 0xD8400080,
+ 0xC1000004, 0xD9000001, 0xC0001408, 0xCC800000, 0xC10E0002, 0xD90C0000, 0x8000ED98, 0xDFBC0001,
+ 0xC000496E, 0x99006298, 0xC9400000, 0xC7D80000, 0x00000000, 0xC5700000, 0x5EF00020, 0x88000130,
+ 0x6F346000, 0x4735A000, 0x5B744C80, 0x58340008, 0xC2400000, 0xCA400080, 0x00000000, 0xC2000000,
+ 0x5A640002, 0xCE400080, 0x58340004, 0xCA000080, 0x00000000, 0x00000000, 0x5E200002, 0xCE000080,
+ 0xC0004912, 0xCA800000, 0xC2400002, 0x6A712000, 0x72694000, 0xCE800000, 0x5E200000, 0x8400003A,
+ 0xC000480A, 0xCA000000, 0xC0000408, 0xCA800000, 0x76610000, 0x00000000, 0x72294000, 0xCE800000,
+ 0x80000020, 0xC0004914, 0xCA000000, 0x7E412000, 0x00000000, 0x76610000, 0xCE000000, 0x800000B8,
+ 0x6EF4A000, 0x6ED44000, 0x4575A000, 0x46F5A000, 0x5B744E20, 0x5834002E, 0xC2400000, 0xCA420080,
+ 0x00000000, 0xC2000000, 0x5A640002, 0xC6501080, 0xCD001080, 0x58340006, 0xCA000080, 0x00000000,
+ 0x00000000, 0x5A200002, 0xCE000080, 0xC0004910, 0xCA400000, 0xC2000002, 0x6A2D0000, 0x72252000,
+ 0xCE400000, 0xC2000002, 0x6A310000, 0xC000042A, 0xCE000000, 0xC1040002, 0xD90C0000, 0x00000000,
+ 0x8000EB08, 0x00000000, 0xC4980930, 0x9D000000, 0xC5580030, 0xC0000838, 0xCD840000, 0xC1440200,
+ 0xC1C03200, 0xC55C1078, 0xC000100E, 0x9D000000, 0xCD800000, 0xC000100C, 0xCDC00000, 0xC0004862,
+ 0xC9C00000, 0x00000000, 0x00000000, 0xD9D80001, 0xC0007200, 0x401C0000, 0x5DC07400, 0x8800FFFA,
+ 0x5C000200, 0xCD800000, 0xC1F0000A, 0x71D4A000, 0xDD980000, 0xDD9C0001, 0x41D8E000, 0xC5D40268,
+ 0xC0001010, 0xCD400000, 0x6C9C8000, 0x449CE000, 0x449CE000, 0x59DC0004, 0xC1601260, 0xC5D40268,
+ 0x9D000000, 0xC0001012, 0xCD400000, 0x00000000, 0x00000000, 0xD9580000, 0x6D586000, 0x4558C000,
+ 0x59984C80, 0xD9980001, 0x5818000A, 0xC1800000, 0xC9800080, 0xC0005400, 0x6D5CA000, 0x401C0000,
+ 0x40180000, 0xC9400000, 0x58000002, 0x00000000, 0xC9C00000, 0xC0004930, 0xCD400000, 0xC0004932,
+ 0xCDC00000, 0x59980004, 0xC1C20020, 0xB59CFFF8, 0x00000000, 0xC1800000, 0xDD9C0001, 0x581C000A,
+ 0xCD800080, 0x581C000C, 0xC1800000, 0xC9800028, 0xC1C00002, 0xDD940000, 0x69D4E000, 0x5D980002,
+ 0xCD800028, 0xC0004924, 0xC9800000, 0x00000000, 0x9D000000, 0x00000000, 0x71D8C000, 0xCD800000,
+ 0xC000492A, 0xC9400000, 0xC1C00002, 0x69D8E000, 0x7DC0C000, 0x7594A000, 0xCD400000, 0xC000492C,
+ 0xC9400000, 0xDD800001, 0x58000032, 0x75D4A000, 0x84000078, 0xC9400001, 0xC9800000, 0xDD800001,
+ 0x5800000C, 0x00000000, 0xCD400001, 0xCD800000, 0xC000492C, 0xC9400000, 0xC000492A, 0xC9800000,
+ 0x71D4A000, 0xC000492C, 0xCD400000, 0x71D8C000, 0xC000492A, 0xCD800000, 0x9D000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xC0004862, 0xC9800000, 0x00000000, 0xC1C00200, 0x4194C000, 0x45D8E000,
+ 0x8800FFFA, 0xC5D80000, 0xC0004862, 0xCD800000, 0xC0001406, 0xC9800000, 0xC1C00002, 0x9D000000,
+ 0xC5D80A08, 0xC5581050, 0xCD800000, 0xC0004930, 0xC9800000, 0xC0004932, 0xC9C00000, 0xC140000E,
+ 0xC5581C20, 0xDD940000, 0xC0007200, 0x40140000, 0x5D407400, 0x8800FFFA, 0x5C000200, 0xCD800000,
+ 0x58000002, 0x5D407400, 0x8800FFFA, 0x5C000200, 0xCDC00000, 0xDD540000, 0xC1C00000, 0x58140006,
+ 0xC9C20080, 0xC1800000, 0x58140000, 0xC98000E0, 0x6DDC2000, 0xC000491E, 0x41D8E000, 0xCDC00000,
+ 0xDD980000, 0xC1C00022, 0xC5D80D78, 0xDD940001, 0xC5581C20, 0xC000491C, 0xCD800000, 0xDD540000,
+ 0xC1C00000, 0x58140006, 0xC9C20080, 0xC1800000, 0x58140004, 0xC9820080, 0x00000000, 0x59DC0002,
+ 0x459CC000, 0x8400FFF8, 0xC1C00000, 0x9D000000, 0x58140006, 0xC5D81080, 0xCD801080, 0xC0004860,
+ 0xC9400000, 0xC1820080, 0xC1D00002, 0x58146B00, 0xD5800000, 0x58000002, 0xD5800001, 0x59540004,
+ 0xB558FFF8, 0xC0004860, 0xC1400000, 0xCD400000, 0xDD980001, 0x9D000000, 0xDD940000, 0xC0001404,
+ 0xCDC00808, 0xC1C00000, 0xC1800200, 0x5D980004, 0xDF5D0050, 0x45D8A000, 0x8800FFDA, 0xDD800001,
+ 0x5800000C, 0x00000000, 0xC9400001, 0xC9800000, 0xC1C00002, 0xC5D43F08, 0xC5D81E08, 0xC0004862,
+ 0xC9C00000, 0x00000000, 0x00000000, 0x581C7200, 0x5DC07400, 0x8800FFFA, 0x5C000200, 0xCD400000,
+ 0x58000002, 0x5DC07400, 0x8800FFFA, 0x5C000200, 0xCD800000, 0xC0004862, 0xC9C00000, 0x00000000,
+ 0xC15004C0, 0xC5D40068, 0xDD9C0000, 0xC5D41C20, 0xC1C00000, 0xDD800001, 0x58000030, 0xC9C00080,
+ 0xDD800001, 0x58000002, 0xC9800000, 0x6DDC2000, 0xC000491C, 0x41D8E000, 0xCD400001, 0xCDC00000,
+ 0xDD940001, 0xC1C00000, 0x58140030, 0xC9C00080, 0xC1800000, 0x58140006, 0xC9820080, 0x00000000,
+ 0x59DC0002, 0x459CC000, 0x8400FFF8, 0xC1C00000, 0x9D000000, 0x58140030, 0xC5D80080, 0xCD800080,
+ 0xC1C00000, 0xDF5C0040, 0x5DDC0080, 0x8400FFD2, 0x00000000, 0x9D000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xC160FFFE, 0xC0000A10, 0xC9440068, 0xC1A0FFFE, 0x59980E28, 0xC000100C, 0xCD400000,
+ 0xC000100E, 0xCD800000, 0xC0004964, 0xC9800000, 0x00000000, 0xC170000A, 0x7194A000, 0x6C988000,
+ 0x4498C000, 0x4498C000, 0x59980004, 0xC5940278, 0xC0001010, 0xCD400000, 0xC0004946, 0xC9400000,
+ 0x00000000, 0x00000000, 0x6D58A000, 0x6D5C4000, 0x45D8C000, 0x4558C000, 0xC000494A, 0xC9400000,
+ 0xC0004948, 0xC9C00000, 0x4194C000, 0xC1400012, 0xC55C1820, 0x9D000000, 0xC59C0270, 0xC0001012,
+ 0xCDC00000, 0xC1400000, 0x58000012, 0xC9410040, 0xC0004950, 0xC9C00000, 0xC5580000, 0xC5940840,
+ 0xC5581080, 0xD9940000, 0xC000493C, 0xC9400000, 0xC0004954, 0xC9800000, 0x59DC00A8, 0x455CE000,
+ 0x41D8E000, 0x5D5C0030, 0x8800FFF8, 0xC1C00030, 0xC1800000, 0xC5D84030, 0xC1400000, 0xC5D40010,
+ 0x5DD40002, 0x8400005A, 0x5DD40004, 0x84000082, 0x5DD40006, 0x840000AA, 0x5DD80026, 0x840000D2,
+ 0xDD540000, 0xDD800001, 0x58000008, 0x40180000, 0xCD400000, 0x59980002, 0x8000FFA8, 0xDD540000,
+ 0xDD800001, 0x58000008, 0x40180000, 0xCD4000C0, 0x59980002, 0x8000FF70, 0xDD540000, 0xDD800001,
+ 0x58000008, 0x40180000, 0xCD400080, 0x59980002, 0x8000FF38, 0xDD540000, 0xDD800001, 0x58000008,
+ 0x40180000, 0xCD400040, 0x59980002, 0x8000FF00, 0x00000000, 0x9D000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x58000012, 0xC9400000, 0xC0004954, 0xC9C00000, 0xC0004950, 0xC9400080, 0xDD800001,
+ 0x58000028, 0x5D9C0000, 0x8400003A, 0x5D9C0002, 0x8400003A, 0x5D9C0004, 0x84000052, 0xC55B0040,
+ 0xC55C08C0, 0xCD800041, 0xCDC008C0, 0x80000048, 0xCD400000, 0x80000038, 0xC55900C0, 0xC55C1840,
+ 0xCD8000C1, 0xCDC01840, 0x80000010, 0xC55A0080, 0xC55C1080, 0xCD800081, 0xCDC01080, 0x9D000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x59540002, 0x6994E018, 0x61C0C008, 0x4194A000, 0x5D940040,
+ 0x8800FFFA, 0xC5940000, 0x9D000000, 0xCD400000, 0x00000000, 0x00000000, 0x9D000000, 0x4158A000,
+ 0xCD400000, 0x00000000,
+};
+
+static unsigned int danube_fw_data[] = {
+};
+
+
+#endif // IFXMIPS_ATM_FW_DANUBE_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_danube_retx.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_danube_retx.h
new file mode 100644
index 0000000000..1c915dbba1
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_danube_retx.h
@@ -0,0 +1,612 @@
+#ifndef IFXMIPS_ATM_FW_DANUBE_H
+#define IFXMIPS_ATM_FW_DANUBE_H
+
+
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_fw_danube.h
+** PROJECT : Danube
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (PP32 Firmware)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+*******************************************************************************/
+
+
+#define VER_IN_FIRMWARE 1
+
+#define ATM_FW_VER_MAJOR 0
+#define ATM_FW_VER_MINOR 15
+
+
+static unsigned int firmware_binary_code[] = {
+ 0x800004A0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000FFC8, 0x00000000, 0x00000000, 0x00000000,
+ 0xC1000002, 0xD90C0000, 0xC2000002, 0xDA080001, 0xC0001B50, 0x8C100000, 0x00000000, 0x00000000,
+ 0x00000000, 0xC2000000, 0xDA080001, 0x80006018, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80005FF0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC1001DA6, 0x8D3C0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80005EF0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0400000, 0xC0004840, 0xC8840000, 0xC2001AEE, 0x8E100000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0400002, 0xC0004840, 0xC8840000, 0xC2001AEE, 0x8E100000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC3C00004, 0xDBC80001, 0xC10C0002, 0xD90C0000, 0x8000FEC8, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC10E0002, 0xD90C0000, 0xC0004808, 0xC8400000, 0xC2001B4C, 0x8E100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC3E1FFFE, 0x597DFFFE, 0x593DFE14, 0x900004D9, 0x00000000, 0x00000000, 0x00000000, 0x90CC0481,
+ 0x00000000, 0x00000000, 0x00000000, 0xC3E02252, 0x5BFC001E, 0xC0004002, 0xCFC00000, 0xC3C00000,
+ 0xDBC80001, 0xC1400008, 0xC1900000, 0x71948000, 0x15000100, 0xC140000A, 0xC1900002, 0x71948000,
+ 0x15000100, 0xC140000C, 0xC1900004, 0x71948000, 0x15000100, 0xC1400004, 0xC1900006, 0x71948000,
+ 0x15000100, 0xC1400006, 0xC1900008, 0x71948000, 0x15000100, 0xC140000E, 0xC190000A, 0x71948000,
+ 0x15000100, 0xC1400000, 0xC190000C, 0x71948000, 0x15000100, 0xC1400002, 0xC190000E, 0x71948000,
+ 0x15000100, 0xC0400000, 0xC11C0000, 0xC000082C, 0xCD040E08, 0xC11C0002, 0xC000082C, 0xCD040E08,
+ 0xC0400002, 0xC11C0000, 0xC000082C, 0xCD040E08, 0xC0000824, 0x00000000, 0xCBC00001, 0xCB800001,
+ 0xCB400001, 0xCB000000, 0xC0004878, 0x5BFC4000, 0xCFC00001, 0x5BB84000, 0xCF800001, 0x5B744000,
+ 0xCF400001, 0x5B304000, 0xCF000000, 0xC0000A10, 0x00000000, 0xCBC00001, 0xCB800000, 0xC0004874,
+ 0x5BFC4000, 0xCFC00001, 0x5BB84000, 0xCF800000, 0xC30001FE, 0xC000140A, 0xCF000000, 0xC3000000,
+ 0x7F018000, 0xC000042E, 0xCF000000, 0xC000040E, 0xCF000000, 0xC3C1FFFE, 0xC000490E, 0xCFC00080,
+ 0xC000492C, 0xCFC00080, 0xC0004924, 0xCFC00040, 0xC0004912, 0xCFC00040, 0xC0004966, 0xCFC00040,
+ 0xC0004968, 0xCFC00080, 0xC000496A, 0xCFC00080, 0xC3C00000, 0xC2800020, 0xC3000000, 0x7F018000,
+ 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB84A00, 0x5838000A, 0xCF000000, 0x5BFC0002, 0xB7E8FFA8,
+ 0x00000000, 0xC3C00000, 0xC2800010, 0x6FF86000, 0x47F9C000, 0x5BB84C80, 0xC3400000, 0x58380004,
+ 0xCB420080, 0x00000000, 0x58380008, 0xCF400080, 0x5BFC0002, 0xB7E8FF90, 0x00000000, 0xC3C00000,
+ 0xC2800020, 0xC348001E, 0xC3000000, 0x7F018000, 0x6FF8A000, 0x6FD44000, 0x4579C000, 0x47F9C000,
+ 0x5BB84E20, 0x58380008, 0xCF400420, 0x5838000A, 0xCF000000, 0x5BFC0002, 0xB7E8FF90, 0x00000000,
+ 0x00000000, 0xC0004816, 0xC3C00000, 0xCBC00080, 0x00000000, 0x00000000, 0xC1000000, 0xD9040001,
+ 0xDBC40080, 0xC1000006, 0xD9040001, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000, 0xC3C00000,
+ 0xDCFC2008, 0x5FFC0002, 0x00000000, 0x98C08D62, 0xC0004730, 0xC9400000, 0xC0004732, 0xC0001AF2,
+ 0xCBC00000, 0x00000000, 0x00000000, 0xA7C20450, 0xC000474A, 0xCA800000, 0x00000000, 0x00000000,
+ 0x5D280000, 0x8400FFC8, 0x00000000, 0xC121FFFE, 0x5911FEF4, 0x15000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC2802000, 0x6EA8E010, 0xC0004200, 0xC2400000, 0x7E410000, 0xC1000000, 0xCE400001, 0xCE400001,
+ 0xCE400001, 0xCE400001, 0x5EA80002, 0x8400FFC0, 0xC0004300, 0xC2800200, 0x6EA84010, 0xCE400001,
+ 0xCE000001, 0xCE400001, 0xCE000001, 0xCE400001, 0xCE000001, 0xCE400001, 0xCE000001, 0x5EA80002,
+ 0x8400FFA0, 0xC0004700, 0xC2800200, 0x6EA8E010, 0xCE400001, 0xCE400001, 0xCE400001, 0xCE400001,
+ 0x5EA80002, 0x8400FFC0, 0xC0004740, 0xCE400000, 0xC0004742, 0xC1000200, 0x5D100002, 0xCD000000,
+ 0xC0004744, 0xCE400000, 0xC0004746, 0xCE400000, 0xC0004748, 0xCE400000, 0xC000474A, 0xCE400000,
+ 0xC000474C, 0xC1000002, 0xCD000000, 0xC000474E, 0xCE400000, 0xC0004750, 0xCE400000, 0xC0004752,
+ 0xCE400000, 0xC0004754, 0xCE400000, 0xC0400000, 0xC11C0000, 0xC000082C, 0xCD040E08, 0xC0000838,
+ 0xCE400000, 0xC0000818, 0xCE400000, 0xC0000820, 0xCE400000, 0xC2804840, 0xC240485A, 0x98C086B0,
+ 0xC6800000, 0xC6540000, 0xC1800000, 0xC11C0002, 0xC000082C, 0xCD040E08, 0x00000000, 0xC121FFFE,
+ 0x5911FE54, 0x15000000, 0xC0000A10, 0xCB800000, 0xC0000A12, 0xCB400000, 0xC0000A14, 0xCB000000,
+ 0xC0000A16, 0xCAC00000, 0xC0000040, 0xC2800000, 0xCE800008, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC2800002,
+ 0xCE800008, 0xC0000A10, 0xCF800000, 0xC0000A12, 0xCF400000, 0xC0000A14, 0xCF000000, 0xC0000A16,
+ 0xCEC00000, 0xC1000000, 0xC00048A0, 0xCD000000, 0xC00048A2, 0xCD000000, 0xC0001AF2, 0xC1000000,
+ 0xCD000108, 0x80001020, 0x00000000, 0xC3C00000, 0xDCFC2008, 0x5FFC0002, 0x00000000, 0x98C08D62,
+ 0xC0004730, 0xC9400000, 0xC0004732, 0x800033C0, 0x00000000, 0xC3C00000, 0xDCFC2008, 0x5FFC0002,
+ 0x00000000, 0x98C08D62, 0xC0004730, 0xC9400000, 0xC0004732, 0xC0004810, 0xC9000000, 0xC000474A,
+ 0xC9400000, 0xA50007C8, 0x00000000, 0x5D140002, 0x840007BA, 0xC1000000, 0xC000484A, 0xC9000000,
+ 0xC0004740, 0xC8400000, 0x5D100000, 0x84000780, 0x00000000, 0x00000000, 0xC121FFFE, 0x5911FEF4,
+ 0x15000000, 0xC0004744, 0xC8800000, 0xC0001AF0, 0xC3000000, 0x58000002, 0xCB010040, 0x6C7C2000,
+ 0x5BFC4300, 0x98C08A88, 0xC1400000, 0xC4540028, 0x6C40A010, 0x5D240002, 0x84000202, 0x00000000,
+ 0xC0004742, 0xCA800000, 0x00000000, 0x00000000, 0x59280002, 0x6D130000, 0x6D130010, 0x44508000,
+ 0x8400067A, 0x00000000, 0x98C08870, 0xC4540000, 0xC6980000, 0xC241FFFE, 0xC6740000, 0x5D35FFFE,
+ 0x8400063A, 0x44748000, 0x8400062A, 0xC1000000, 0x6F502000, 0xC0004300, 0x40100000, 0xC1400000,
+ 0x58000000, 0xC9410040, 0xC1800000, 0xC0004814, 0xC9820040, 0x4570A000, 0xC10001FE, 0x4150A004,
+ 0x45948000, 0x880005B2, 0x4474C000, 0xC1000200, 0x4190C004, 0xC000473E, 0xC9000000, 0x00000000,
+ 0x00000000, 0x41188000, 0xCD000000, 0xC000471C, 0xC9000000, 0x00000000, 0x00000000, 0x41188000,
+ 0xCD000000, 0x98C087E8, 0xC4540000, 0x6C58A010, 0xC0004700, 0x58440002, 0x6C470000, 0x6C470010,
+ 0x47448000, 0x8400FFA8, 0xC7440000, 0xC0004740, 0xCC400000, 0xC0800000, 0xC0004744, 0xCC800000,
+ 0x800004B8, 0xC1000000, 0x583C0000, 0xC9000040, 0x00000000, 0x00000000, 0x45088000, 0x88000268,
+ 0xC1400000, 0x583C0000, 0xC9410040, 0xC1800000, 0xC0004814, 0xC9800040, 0x4570A000, 0xC10001FE,
+ 0x4150A004, 0x45948000, 0x8800042A, 0xC3800000, 0x583C0002, 0xCB820080, 0xC1000000, 0x583C0002,
+ 0xC9000080, 0x00000000, 0x00000000, 0x45388000, 0x84000232, 0xC0400002, 0xC0800000, 0xC3C00000,
+ 0xC000481A, 0xC8000000, 0x6F908000, 0x47908000, 0x47908000, 0x4011E000, 0xC000491E, 0xCFC00000,
+ 0xC3400000, 0xC0004878, 0xC8040000, 0x6C908000, 0x44908000, 0x44908000, 0x40100000, 0xCAC00000,
+ 0xC4300000, 0x00000000, 0xC7340068, 0xC1000002, 0xC5341B08, 0xC100001C, 0xC5341050, 0xC100000C,
+ 0xC5340D18, 0xC000491C, 0xCF400000, 0xC3000000, 0xDF700040, 0x5D300080, 0x8800FFD0, 0xC000474A,
+ 0xC1000002, 0xCD000000, 0xC000491C, 0xCB400000, 0xC000491E, 0xCBC00000, 0x99007F18, 0xDB580000,
+ 0xDBD80001, 0x00000000, 0xC1400000, 0xC794A038, 0xC1800000, 0xC7980028, 0x58144200, 0xC9C00000,
+ 0xC1210000, 0x69188010, 0x7D008000, 0x751CE000, 0xCDC00000, 0x80000210, 0x00000000, 0xC1000000,
+ 0x583C0000, 0xC903E008, 0x00000000, 0x00000000, 0x5D100000, 0x8400002A, 0xC0004734, 0xC9000000,
+ 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0x800000A8, 0xC1400000, 0x583C0000, 0xC9410040,
+ 0xC1800000, 0xC0004814, 0xC9820040, 0x4570A000, 0xC10001FE, 0x4150A004, 0x45948000, 0x88000142,
+ 0xC000473E, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0xC000471C, 0xC9000000,
+ 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0xC3800000, 0x583C0002, 0xCB820080, 0x00000000,
+ 0x00000000, 0x5D39FFFE, 0x8400004A, 0xC1400000, 0xC794A038, 0xC1800000, 0xC7980028, 0x58144200,
+ 0xC9C00000, 0xC1210000, 0x69188010, 0x7D008000, 0x751CE000, 0xCDC00000, 0x98C087E8, 0xC4540000,
+ 0x6C58A010, 0xC0004700, 0x58440002, 0x6C470000, 0x6C470010, 0xC0004740, 0xCC400000, 0xC0800000,
+ 0xC0004744, 0xCC800000, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000, 0x8000F270, 0x00000000,
+ 0x00000000, 0x98C086F0, 0xC0004748, 0xC9800000, 0xC2000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xC1400000, 0xC7D4A038, 0xC1800000, 0xC7D80028, 0x58144200,
+ 0xC9C00000, 0xC1210000, 0x69188010, 0x7D008000, 0x751CE000, 0xCDC00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x98C087E8, 0xC7D40000, 0x6FD8A010, 0xC0004700, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x98C08870, 0xC7D40000, 0xC7980000, 0xC241FFFE, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x98C08A88, 0xC1400000, 0xC7D40028, 0x6FC0A010,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x98C08AB8, 0xC1400000, 0xC7D40028, 0x6FC0A010,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x98C08AF0, 0xC7D40000, 0xC0004740, 0xC9C00000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x98C08BE0, 0xC7D40000, 0xC0004742, 0xC9800000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC0004958, 0xC8400000, 0x00000000, 0xC3C00002,
+ 0x7BC42000, 0xCC400000, 0xC0004848, 0xCB840000, 0xC000495C, 0xCAC40000, 0xC0004844, 0xC8840000,
+ 0x46F90000, 0x8400F47A, 0xC000487C, 0xC8040000, 0x00000000, 0x00000000, 0x40080000, 0xCA000000,
+ 0xC0001624, 0xCB040000, 0xA63C005A, 0x00000000, 0x00000000, 0xA71EF412, 0x00000000, 0xC0000824,
+ 0xCA840000, 0x6CA08000, 0x6CA42000, 0x46610000, 0x42290000, 0xC35E0002, 0xC6340068, 0xC0001624,
+ 0xCF440080, 0xC2000000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xC0004844, 0xC8840000, 0xC000082C, 0xCA040040, 0x00000000, 0x00000000, 0x58880002,
+ 0xB608FFF8, 0x00000000, 0xC0800000, 0xC0004844, 0xCC840040, 0x5AEC0002, 0xC000495C, 0xCEC40000,
+ 0x5E6C0006, 0x84000048, 0xC0004848, 0xCB840000, 0xC0000838, 0xC2500002, 0xCE440808, 0x5FB80002,
+ 0xC0004848, 0xCF840000, 0x5EEC0002, 0xC000495C, 0xCEC40000, 0x00000000, 0xC121FFFE, 0x5911FE54,
+ 0x15000000, 0x8000F278, 0xC000495A, 0xC8400000, 0x00000000, 0xC3C00002, 0x7BC42000, 0xCC400000,
+ 0xC0004960, 0xCAC40000, 0x00000000, 0x00000000, 0x5EEC0000, 0x840000F2, 0x00000000, 0xB6FC0030,
+ 0xC0001600, 0xCA040000, 0x00000000, 0x00000000, 0xA61E00B2, 0x6FE90000, 0xC0000A28, 0xCE840808,
+ 0xC2C00000, 0xC2800004, 0xB6E80080, 0xC0001604, 0xCA840000, 0xC0004960, 0xCEC40000, 0xA69EFC8A,
+ 0x00000000, 0x6FE90000, 0xC0000A28, 0xCE840808, 0xC2C00002, 0xC0001600, 0xCA040000, 0x00000000,
+ 0x00000000, 0xA61E000A, 0x6FE90000, 0xC0000A28, 0xCE840808, 0xC2C00000, 0xC0001604, 0xCA840000,
+ 0xC0004960, 0xCEC40000, 0xA69EFBF2, 0xC2400000, 0xC0000A14, 0xCA440030, 0x00000000, 0x00000000,
+ 0x46E52000, 0xA4400000, 0xC2800000, 0xDFEB0031, 0x8000FFF8, 0xDFEA0031, 0xB668EBEA, 0x00000000,
+ 0xC00048A0, 0xCB040000, 0xC0000A10, 0xCA840000, 0x6F208000, 0x6F242000, 0x46610000, 0x42A10000,
+ 0xC2400000, 0xC0000A14, 0xCA440030, 0xC35E0002, 0xC6340068, 0xC0001604, 0xCF440080, 0x5B300002,
+ 0xB670FFF8, 0x5AEC0002, 0xC3000000, 0xC00048A0, 0xCF040000, 0xC0004960, 0xCEC40000, 0x8000F018,
+ 0xC0004918, 0xD2800000, 0xC2000000, 0xDF600040, 0x5E600080, 0x8400028A, 0x00000000, 0xC161FFFE,
+ 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC000480A, 0xCA000000,
+ 0xC0004912, 0xCA400000, 0xC0004924, 0xCA800000, 0xC0004966, 0xCAC00000, 0x00000000, 0xC121FFFE,
+ 0x5911FE54, 0x15000000, 0x76610000, 0x76A10000, 0x76E10000, 0x840001CA, 0xC0004918, 0xCA400000,
+ 0xC28001FE, 0x76A10000, 0x5A640002, 0x6A254010, 0x5EE80000, 0x84000002, 0x6AA54000, 0x8000FFF8,
+ 0xC6280000, 0x62818008, 0xC0004918, 0xCF000000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xC0004966, 0xCA400000, 0xC2000002, 0x6A310000, 0x7E010000,
+ 0x76252000, 0xCE400000, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000, 0x6F346000, 0x4735A000,
+ 0x5B744C80, 0xC2800000, 0x58340006, 0xCA800080, 0xC2C00000, 0x58340000, 0xCAC000E0, 0xC2400000,
+ 0x5834000A, 0xCA420080, 0x6EA82000, 0x42E9E000, 0x6F2CA000, 0x42E56000, 0x5AEC1400, 0xC3990040,
+ 0xC7381C20, 0xC6F80068, 0x99007F18, 0xDB980000, 0xDBD80001, 0x00000000, 0xDEA00000, 0x47210000,
+ 0x8400FD38, 0xC0004958, 0xC8400000, 0x00000000, 0xC1000002, 0x79042000, 0xCC400000, 0xC0004848,
+ 0xCBC40000, 0xC0004844, 0xC8840000, 0x5FFC0000, 0x8400ECA2, 0xC0004740, 0xCB000000, 0xC0004744,
+ 0xCAC00000, 0x6F282000, 0x5AA84300, 0xC000487C, 0xC8040000, 0x00000000, 0x00000000, 0x40080000,
+ 0xCA400000, 0xC4000000, 0x00000000, 0xC0004878, 0xC8040000, 0x6C908000, 0x44908000, 0x44908000,
+ 0x40100000, 0xC9000000, 0xC4340000, 0x00000000, 0x5C440000, 0x8400008A, 0x00000000, 0xC00047D2,
+ 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0x58340002, 0xC9000080, 0x00000000,
+ 0x00000000, 0x58280002, 0x6D120000, 0xCD001080, 0x5AEC0002, 0xC0004744, 0xCEC00000, 0x80000618,
+ 0x00000000, 0xC00047C0, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0xA67C0028,
+ 0xC00047C2, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0x80001E00, 0x00000000,
+ 0xA6600022, 0xC00047C4, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0x80000558,
+ 0xC00047C6, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0xC3C00000, 0xC67D0040,
+ 0xC3800000, 0xC6780040, 0x473C8000, 0x84000090, 0x46F88000, 0x84000080, 0xC1000000, 0xC0004814,
+ 0xC9000040, 0x00000000, 0x00000000, 0x5D100000, 0x840000D8, 0x5AEC0002, 0xC0004744, 0xCEC00000,
+ 0xC00047CA, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0x80000460, 0x00000000,
+ 0x98C08AF0, 0xC7D40000, 0xC0004740, 0xC9C00000, 0x5D240000, 0x84000052, 0x00000000, 0x98C087E8,
+ 0xC7D40000, 0x6FD8A010, 0xC0004700, 0xC00047C8, 0xC9000000, 0x00000000, 0x00000000, 0x59100002,
+ 0xCD000000, 0x80001C28, 0xC00047CC, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000,
+ 0x6FE82000, 0x5AA84300, 0x5D380000, 0x84000088, 0x00000000, 0x98C086F0, 0xC0004748, 0xC9800000,
+ 0xC2000000, 0x58280002, 0x6E520000, 0xCD001080, 0x58280002, 0xCE400080, 0x5D25FFFE, 0x84000028,
+ 0xC00047D0, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0x800002B8, 0xC3000000,
+ 0x58280002, 0xCB000080, 0x00000000, 0x00000000, 0x5D31FFFE, 0x84000030, 0xC00047D0, 0xC9000000,
+ 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0x80000248, 0x00000000, 0x98C086F0, 0xC0004748,
+ 0xC9800000, 0xC2000000, 0x58340002, 0xC6500080, 0xC7D01040, 0xC7901840, 0xCD000000, 0x58280002,
+ 0xCE400080, 0xC3C00200, 0x5FFC001C, 0xC3800000, 0xDF790050, 0x00000000, 0x00000000, 0x47BC8000,
+ 0x8800FFC2, 0xC0004862, 0xCBC00000, 0xC0000000, 0xC76C0000, 0x5BBC7200, 0xC280001C, 0xCA6C0001,
+ 0x00000000, 0x00000000, 0xCE780001, 0xC1007400, 0x47908000, 0xC1007200, 0xC5380006, 0x5EA80002,
+ 0x8400FFA0, 0xC3800000, 0xC000481A, 0xC8000000, 0x6F108000, 0x47108000, 0x47108000, 0x4011C000,
+ 0xC000491E, 0xCF800000, 0xC2C00000, 0xC7EC0068, 0xC100001C, 0xC52C1050, 0xC100000A, 0xC52C0D18,
+ 0xC000491C, 0xCEC00000, 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420050, 0xC2800000, 0xDF680040,
+ 0x5D280080, 0x8800FFD0, 0xC000491C, 0xCAC00000, 0xC000491E, 0xCB800000, 0x99007F18, 0xDAD80000,
+ 0xDB980001, 0x00000000, 0xC00047CE, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000,
+ 0x00000000, 0x80001868, 0x00000000, 0x00000000, 0x00000000, 0xC0004878, 0xC8040000, 0x6C908000,
+ 0x44908000, 0x44908000, 0x40100000, 0xCA000000, 0xC4240000, 0x00000000, 0xC0004934, 0xCE000000,
+ 0xC2800002, 0xC4681C10, 0xC62821D8, 0xC6281E08, 0xC2600010, 0x5A650080, 0xC0004800, 0xCB400000,
+ 0xC2200400, 0x5A200040, 0xC7601048, 0xC0001220, 0xCE800000, 0xC0001200, 0xCE400000, 0xC0001202,
+ 0xCE000000, 0xC0001240, 0xCB400000, 0x00000000, 0x00000000, 0xA754FFC0, 0xC2000000, 0xC7600048,
+ 0xA7520022, 0x00000000, 0x00000000, 0x99008690, 0xC0004822, 0xC9400000, 0xC1800002, 0x800016F8,
+ 0x582040C0, 0xC2000000, 0xCA000020, 0xC2400000, 0xCA414008, 0xC2800000, 0xCA812008, 0xC2C00000,
+ 0xCAC20020, 0xC0004938, 0xCE000000, 0xC0004920, 0xCE400000, 0xC0004916, 0xCE800000, 0xC0004922,
+ 0xCEC00000, 0xA6400538, 0x00000000, 0xC0004938, 0xCBC00000, 0x00000000, 0xC3800000, 0x6FF48000,
+ 0x6FD44000, 0x4355A000, 0x5B744A00, 0x58340000, 0xCB802018, 0x00000000, 0xC2000000, 0x6FB46000,
+ 0x47B5A000, 0x5B744C80, 0x5834000C, 0xCA000028, 0xC000491A, 0xCF800000, 0x5E200000, 0x8400046A,
+ 0xC2000000, 0xDF610050, 0x5E6001E8, 0x8800FFD0, 0xC2000002, 0xC2400466, 0xC2A00000, 0x5AA80000,
+ 0xC0001006, 0xCE000000, 0xC0001008, 0xCE400000, 0xC000100A, 0xCE800000, 0x99007958, 0xC1A0FFFE,
+ 0xC0000824, 0xC9840068, 0xC0004934, 0xCA400000, 0xC2000000, 0xC2800002, 0x99007998, 0xDA980000,
+ 0xC6140000, 0xC6580000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x99007A80, 0xC000491A, 0xC9400000, 0x00000000, 0x00000000, 0xC121FFFE, 0x5911FE54,
+ 0x15000000, 0xC0004922, 0xCA001120, 0xC3C00000, 0xC3800000, 0xC0004930, 0xCE001120, 0xC0004932,
+ 0xCBC000E0, 0xC2800000, 0xC000491E, 0xCFC00000, 0xC0004862, 0xCA800068, 0xC3A0001A, 0x5BB94000,
+ 0xC6B80068, 0xC000491C, 0xCF800000, 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420050, 0x00000000,
+ 0x00000000, 0x00000000, 0xA8E2FFC8, 0xC2000000, 0xC1220002, 0xD90C0000, 0xDF600040, 0x5E600080,
+ 0x8400FFDA, 0xC000491C, 0xCA000000, 0xC000491E, 0xCA400000, 0x00000000, 0x00000000, 0x99007F18,
+ 0xDA180000, 0xDA580001, 0x00000000, 0xC2000000, 0xDF610050, 0x5E6001FE, 0x8800FFD0, 0xC0004916,
+ 0xCA800000, 0xC2C00000, 0xDFEC0050, 0xC2400000, 0x46E52000, 0x84000032, 0x5EA80000, 0x84000022,
+ 0xC2600002, 0x99008690, 0xC000482E, 0xC9400000, 0xC1800002, 0x80000018, 0xC2600000, 0x99008690,
+ 0xC000482C, 0xC9400000, 0xC1800002, 0xC2000068, 0xC6240080, 0xC0004930, 0xCE400088, 0xC000491A,
+ 0xC9800000, 0xC0004862, 0xC9400000, 0x6D9C6000, 0x459CE000, 0x59DC4C80, 0x99007D78, 0xD9580000,
+ 0xD9980001, 0xD9D40000, 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420050, 0xC2000000, 0xDF600040,
+ 0x5E600080, 0x8400FFD2, 0x00000000, 0xC000491C, 0xCA000000, 0xC000491E, 0xCA400000, 0x00000000,
+ 0x00000000, 0x99007F18, 0xDA180000, 0xDA580001, 0x00000000, 0x80001148, 0x00000000, 0x99008690,
+ 0xC000482A, 0xC9400000, 0xC1800002, 0x80001118, 0xC0004938, 0xCBC00000, 0x00000000, 0x00000000,
+ 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB84A00, 0x58380008, 0xCA000000, 0x00000000, 0x00000000,
+ 0xA600037A, 0x00000000, 0xC0004938, 0xCBC00000, 0xC3000000, 0x00000000, 0x6FF88000, 0x6FD44000,
+ 0x4395C000, 0x5BB84A00, 0x58380000, 0xCB002018, 0xC2000000, 0x58380008, 0xCA020080, 0x5838000C,
+ 0xCAC00000, 0x5838000E, 0xCA400000, 0xC000491A, 0xCF000000, 0xC0004930, 0xCEC00000, 0xC000493C,
+ 0xCE000000, 0xC0004932, 0xCE400000, 0x5E200000, 0x84000120, 0xC2800000, 0xA6FE00B2, 0x6F206000,
+ 0x47210000, 0x5A204C80, 0x5820000C, 0xCA800028, 0x00000000, 0x00000000, 0x5EA80000, 0x840001F2,
+ 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x99007A80, 0xC000491A, 0xC9400000, 0x00000000, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000,
+ 0xC0004930, 0xCAC00000, 0xC0004932, 0xCA400000, 0xC7EC1120, 0xC0004930, 0xCEC00000, 0x5838000C,
+ 0xCEC00000, 0x58000002, 0xCE400000, 0xC0004934, 0xCA000000, 0xC2400002, 0x6E642000, 0x6E642000,
+ 0x76252000, 0x84000012, 0xC2400002, 0x6E684000, 0x58380008, 0xCE800208, 0xA6000000, 0x6E682000,
+ 0x58380008, 0xCE800108, 0xC2400002, 0x6E642000, 0x76252000, 0x840000D2, 0x58380008, 0xCA000000,
+ 0xC2800000, 0xC2400000, 0xA60200A0, 0xDBA80000, 0x6F386000, 0x4739C000, 0x5BB84C80, 0x58380004,
+ 0xCA400080, 0x58380002, 0xCA800080, 0x00000000, 0xDEB80000, 0x46694000, 0x88000048, 0x00000000,
+ 0xC0004824, 0xCA000000, 0xC2400002, 0x6E640000, 0x5A200002, 0xCE000000, 0x58380008, 0xCE400008,
+ 0x80000000, 0x00000000, 0x80000030, 0xC0004934, 0xCA000000, 0x00000000, 0x00000000, 0xA6020CAA,
+ 0x00000000, 0x00000000, 0x80000CE0, 0xC2800000, 0xC2000200, 0xC240001A, 0xDF690050, 0x46A14000,
+ 0x46694000, 0x8800FFBA, 0xC2000006, 0xC2600982, 0x5A643B6E, 0x5838000A, 0xCA800000, 0xC0001006,
+ 0xCE000000, 0xC0001008, 0xCE400000, 0xC000100A, 0xCE800000, 0x99007958, 0xC1A0FFFE, 0xC0000824,
+ 0xC9840068, 0xC2000000, 0xC0004930, 0xCA02E010, 0x58380026, 0xCA400000, 0x00000000, 0xC2800000,
+ 0x99007998, 0xDA980000, 0xC6140000, 0xC6580000, 0xC0004934, 0xCA000000, 0x00000000, 0x00000000,
+ 0xA6020002, 0x00000000, 0x00000000, 0x80000300, 0xC0004938, 0xCBC00000, 0xC0004878, 0xC8040000,
+ 0x6C908000, 0x44908000, 0x44908000, 0x40100000, 0xCA000000, 0xC4240000, 0x00000000, 0x58240018,
+ 0xCA000000, 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB84A00, 0xC3000000, 0xC3400002, 0xC2C00000,
+ 0xC62C0080, 0xC6270040, 0xC0004940, 0xCE400040, 0xC6260040, 0xC0004942, 0xCE400040, 0xC000493C,
+ 0xCA000000, 0x5EEC0000, 0x84000172, 0x5A6C0010, 0x46614000, 0x88000178, 0x5A600052, 0x466D4000,
+ 0x88000160, 0x58380006, 0xCA800000, 0xC0004940, 0xCA000000, 0xC2400000, 0xC6A70040, 0x7E412000,
+ 0x76252000, 0xC2000000, 0xC6A10040, 0x46610000, 0x84000120, 0xC0004942, 0xCA000000, 0xC2400000,
+ 0xC6A60040, 0x7E412000, 0x76252000, 0xC2000000, 0xC6A00040, 0x58380002, 0xCA800000, 0x46610000,
+ 0x840000D0, 0xC2400000, 0xC6A60080, 0x46E50000, 0x880000C2, 0xC2400000, 0xC6A40080, 0x58380008,
+ 0xCA800000, 0x466D0000, 0x880000A2, 0x00000000, 0xA682FFF8, 0x00000000, 0xC7700B08, 0xA6840078,
+ 0x00000000, 0xC7700A08, 0x80000068, 0xC7700208, 0xC000493C, 0xCAC00000, 0x80000048, 0xC7700308,
+ 0xC000493C, 0xCAC00000, 0x80000028, 0xC7700908, 0x80000018, 0xC7700808, 0x80000008, 0xC7700708,
+ 0x8000FFF8, 0xC7700508, 0xC0004944, 0xCF000000, 0xC000493E, 0xCEC00000, 0xC0004938, 0xCA400000,
+ 0xC000493C, 0xCB800000, 0xC000493E, 0xCB400000, 0xC3000000, 0x6E608000, 0x6E544000, 0x42150000,
+ 0x5A204A00, 0x5AA00008, 0x58200004, 0xCB000080, 0xC0004934, 0xCA000000, 0xC2400000, 0xC0004930,
+ 0xCA42E010, 0xC3C00018, 0xA6020078, 0x00000000, 0x43656000, 0x46F90000, 0x88000038, 0x47AD6000,
+ 0x6EE04010, 0x5BE00004, 0xC2000000, 0xC6E00010, 0x5E200000, 0x8400002A, 0x5BFC0002, 0x80000018,
+ 0xC3C00004, 0x5A2C0008, 0x46390000, 0x8800FFFA, 0x5FB80008, 0x6FE04000, 0x42390000, 0x46312000,
+ 0x88000050, 0xC2400000, 0xC0004930, 0xCA42E010, 0xC2060002, 0xC6800000, 0xCE000308, 0x6FE04000,
+ 0x4631C000, 0x5F700010, 0x4675A000, 0xC2000000, 0xC6340010, 0xC25A000A, 0xC000491A, 0xCA401C20,
+ 0xC2800000, 0xC0004932, 0xCA8000E0, 0xC0004862, 0xCA400068, 0x6FA04010, 0x42290000, 0xC000491E,
+ 0xCE000000, 0xC7E41050, 0xC000491C, 0xCE400000, 0x6FE04000, 0x43A1C000, 0xC000493C, 0xCF800000,
+ 0xC000493E, 0xCF400000, 0xC000493A, 0xCFC00000, 0x8000FFF0, 0x00000000, 0x00000000, 0x00000000,
+ 0xC2000000, 0xDCE00000, 0xA622FFB8, 0xC1220002, 0xD90C0000, 0xC0004938, 0xCBC00000, 0xC0004944,
+ 0xCB400000, 0xC0004862, 0xCB000000, 0xC0004934, 0xCA000000, 0x6FF88000, 0x6FD44000, 0x4395C000,
+ 0x5BB84A00, 0xA6020278, 0xC2400000, 0x58380008, 0xCA406008, 0xDFE80000, 0xC2218E08, 0x5A21BAF6,
+ 0x46294000, 0x8400000A, 0xC2080002, 0x7235A000, 0x80000040, 0x5E640000, 0x8400000A, 0xC20C0002,
+ 0x7235A000, 0x80000018, 0xC2000000, 0xC760E718, 0xC7604220, 0x5E200000, 0x8400028A, 0xC2200002,
+ 0xC0004930, 0xCE001008, 0x99008690, 0xC0004828, 0xC9400000, 0xC1800002, 0xC0004780, 0xC93C0000,
+ 0x00000000, 0x00000000, 0x59100002, 0xCD3C0000, 0x58380000, 0xCA000000, 0x00000000, 0x00000000,
+ 0xA6000112, 0xC0004940, 0xCA800000, 0xC0004942, 0xCA400000, 0xC7600080, 0xC6A01840, 0xC6601040,
+ 0xC000493A, 0xCA400000, 0xC0004934, 0xCA800000, 0xC0007200, 0x40300000, 0x40240000, 0x5C000004,
+ 0x5EC07400, 0x8800FFFA, 0x5C000200, 0xCE000000, 0x58000002, 0x5EC07400, 0x8800FFFA, 0x5C000200,
+ 0xCE800000, 0xC000493E, 0xCA000000, 0xC2400000, 0x5838000C, 0xCE400000, 0x99008690, 0xC0004830,
+ 0xC9400000, 0xC6180000, 0xC0004930, 0xC6100080, 0xCD000080, 0x80000090, 0xC2400002, 0x58380008,
+ 0xCE400008, 0xC0004944, 0xCF400000, 0x80000290, 0xC000493C, 0xCA400000, 0xDFE80000, 0x5A300018,
+ 0xC0007200, 0x40200000, 0xCA000000, 0x58380008, 0xC6501080, 0xCD001080, 0x5838000A, 0xCE800000,
+ 0x58380026, 0xCE000000, 0xC0004944, 0xCF400000, 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420050,
+ 0x80000050, 0x00000000, 0x99008690, 0xC0004826, 0xC9400000, 0xC1800002, 0xC0004760, 0xC93C0000,
+ 0x00000000, 0x00000000, 0x59100002, 0xCD3C0000, 0x8000FD90, 0xC2000000, 0xC2400080, 0xDF600040,
+ 0xB624FFCA, 0xC000491C, 0xCA400000, 0xC000491E, 0xCA800000, 0x99007F18, 0xDA580000, 0xDA980001,
+ 0x00000000, 0xC0004934, 0xCA000000, 0x00000000, 0xC2800000, 0xA6020140, 0xC2400004, 0xC2000200,
+ 0xDF690050, 0x46A14000, 0x46694000, 0x8800FFC2, 0x00000000, 0xC000491A, 0xC9800000, 0xC0004862,
+ 0xC9400000, 0x6D9C6000, 0x459CE000, 0x59DC4C80, 0x99007D78, 0xD9580000, 0xD9980001, 0xD9D40000,
+ 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420050, 0xC2000000, 0xC2400080, 0xDF600040, 0xB624FFCA,
+ 0xC000491C, 0xCA400000, 0xC000491E, 0xCA800000, 0x99007F18, 0xDA580000, 0xDA980001, 0x00000000,
+ 0x58380008, 0xCA400000, 0xC2000000, 0xCE000020, 0xC2A1FFFE, 0x5AA9FFFE, 0xCE001080, 0x5838000A,
+ 0xCE800000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0000838, 0xC2500002, 0xCE440808, 0xC0004848, 0xCBC40000, 0xC3800000, 0xC000082C, 0xCB840030,
+ 0x5FFC0002, 0xC0004848, 0xCFC40000, 0x58880002, 0x44B88000, 0xC1000000, 0xC5080006, 0xC0004844,
+ 0xCC840000, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000, 0x8000CBD8, 0xC2000000, 0xDF600040,
+ 0x5E200080, 0x84000282, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xC000480C, 0xCA000000, 0xC0004910, 0xCA400000, 0xC000492C, 0xCA800000,
+ 0xC0004968, 0xCAC00000, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000, 0x76610000, 0x76A10000,
+ 0x762D6000, 0x840001C2, 0xC0004926, 0xCA400000, 0xC201FFFE, 0x762D6000, 0x5A640002, 0x6AE50010,
+ 0x5F200000, 0x84000002, 0x6A250000, 0x8000FFF8, 0xC6E00000, 0x62014008, 0xC0004926, 0xCE800000,
+ 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC0004968,
+ 0xCA400000, 0xC2000002, 0x6A290000, 0x7E010000, 0x76252000, 0xCE400000, 0x00000000, 0xC121FFFE,
+ 0x5911FE54, 0x15000000, 0x6EB4A000, 0x6E944000, 0x4575A000, 0x46B5A000, 0x5B744E20, 0x58340002,
+ 0xC2000000, 0xCA0000E0, 0x5834002E, 0xC2400000, 0xCA400080, 0x6EB0A000, 0x6EBC4000, 0x47F18000,
+ 0x46B18000, 0x5B300E4E, 0x5B300004, 0x6E642000, 0x4225E000, 0xC39A8024, 0xC7380068, 0xC6B81C20,
+ 0x99007F18, 0xDB980000, 0xDBD80001, 0x00000000, 0xC2000000, 0xDF600040, 0x5E200080, 0x840002BA,
+ 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC000490E, 0xCA000000, 0xC000492A, 0xCA400000, 0xC000496A, 0xCB000000, 0xC0004956, 0xCAC00000,
+ 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000, 0x76318000, 0x76718000, 0x84000202, 0xC201FFFE,
+ 0x76318000, 0x5AEC0002, 0x6B2D0010, 0x5EA00000, 0x84000002, 0x6A2D0000, 0x8000FFF8, 0xC7200000,
+ 0x62016008, 0xC0004956, 0xCEC00000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xC000496A, 0xCA400000, 0xC2000002, 0x6A2D0000, 0x7E010000, 0x76252000,
+ 0xCE400000, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000, 0x6EF4A000, 0x6ED44000, 0x4575A000,
+ 0x46F5A000, 0x5B744E20, 0x5834000E, 0xC2000000, 0xCA0000E0, 0x58340008, 0xC2400000, 0xCA420080,
+ 0x5834000C, 0xC2800000, 0xCA832018, 0x6E644010, 0x42250000, 0x4229E000, 0xC39A8008, 0x58340008,
+ 0xCB809020, 0x58340008, 0xC2800000, 0xCA810018, 0x6EE0A000, 0x6EE44000, 0x46610000, 0x46E10000,
+ 0x5A200008, 0x5A200E28, 0x42290000, 0xC6380068, 0xC6F81C20, 0x99007F18, 0xDB980000, 0xDBD80001,
+ 0x00000000, 0xC000495A, 0xC8400000, 0x00000000, 0xC3C00002, 0x7BC42000, 0xCC400000, 0xC0001A1C,
+ 0xCA000000, 0xC2400008, 0x6A452000, 0x76610000, 0x84000E82, 0xC0000A28, 0xC3800000, 0xCB840030,
+ 0xC0000A14, 0xC3400000, 0xCB440030, 0xC0004880, 0xCB040000, 0x47788000, 0x88000E30, 0x58041802,
+ 0xCAC00000, 0xA7000040, 0x00000000, 0x00000000, 0xA6C8C5A8, 0xC2800000, 0xC6E80020, 0x80000058,
+ 0x00000000, 0x00000000, 0x00000000, 0x8000C578, 0x00000000, 0xC2800000, 0xC7282020, 0xC000490E,
+ 0xCA400000, 0x6BE9E000, 0x00000000, 0x77E52000, 0x8400C530, 0x6EA0A000, 0x6E944000, 0x45610000,
+ 0x46A10000, 0x5A204E20, 0x5820000C, 0xCA000000, 0xC0004946, 0xCE800000, 0xA6220378, 0x00000000,
+ 0xC2200060, 0xC0004948, 0xCE000010, 0xCE001040, 0xC240000A, 0xC000494A, 0xCE400000, 0xC2B60002,
+ 0xC0004964, 0xCE801B08, 0x990081E8, 0xC00048A0, 0xC8840000, 0x00000000, 0xC0004946, 0xCBC00000,
+ 0x00000000, 0x00000000, 0x6FF8A000, 0x6FD44000, 0x4579C000, 0x47F9C000, 0x5BB84E20, 0x99007FA8,
+ 0xDBD80000, 0xDB980001, 0x00000000, 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420050, 0xC000491C,
+ 0x990081A0, 0xC9400001, 0xC9800000, 0x00000000, 0x99007F18, 0xD9580000, 0xD9980001, 0x00000000,
+ 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x99007BE0,
+ 0xDBD80000, 0xDB980001, 0xC7D80000, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000, 0x6FF8A000,
+ 0x6FD44000, 0x4579C000, 0x47F9C000, 0x5BB84E20, 0x58380010, 0xCA000000, 0xC0004874, 0xC8040000,
+ 0x6C908000, 0x44908000, 0x44908000, 0x40100000, 0xCA400000, 0xC4340000, 0x00000000, 0xC7400000,
+ 0xCE000000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC000490E, 0xCA400000, 0xC2800002, 0x6ABD4000, 0x72A52000, 0xCE400000, 0x00000000, 0xC121FFFE,
+ 0x5911FE54, 0x15000000, 0x99008690, 0xC0004836, 0xC9400000, 0xC1800002, 0x00000000, 0x00000000,
+ 0x00000000, 0xA8E2FFC8, 0x00000000, 0xC1220002, 0xD90C0000, 0xC2000000, 0xC0000A14, 0xCA040030,
+ 0xC0000A28, 0xC2500002, 0xCE440808, 0x58880002, 0xB608FFF8, 0xC00048A0, 0xC0800000, 0xCC840000,
+ 0x8000C150, 0xC0004946, 0xCBC00000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xC000490E, 0xCA400000, 0xC2800002, 0x6ABD4000, 0x72A52000, 0xCE400000,
+ 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000, 0x6FF8A000, 0x6FD44000, 0x4579C000, 0x47F9C000,
+ 0x5BB84E20, 0x58380008, 0xCA000000, 0x5838000C, 0xCA400000, 0xC3400000, 0xC6340008, 0xC000494E,
+ 0xCF400000, 0xC2800000, 0xC62A0080, 0xC3000000, 0xC6308020, 0x6F304000, 0x43298000, 0xC000493C,
+ 0xCF000000, 0xC2C00000, 0xC66C0080, 0xC0004950, 0xCEC00000, 0xC2800000, 0xC66AE028, 0xC0004954,
+ 0xCE800000, 0x5F740000, 0x840001A0, 0x5E300028, 0x462D2000, 0x8400016A, 0x462D2000, 0x88000132,
+ 0x5E300018, 0x462D2000, 0x88000012, 0x462D2000, 0x8400002A, 0x00000000, 0x800000C0, 0x00000000,
+ 0x99008328, 0xDBD80000, 0xDB980001, 0xC7800000, 0xC3400002, 0xC000494E, 0xCF400000, 0xC161FFFE,
+ 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC000490E, 0xCA400000,
+ 0xC2800002, 0x6ABD4000, 0x7E814000, 0x76A52000, 0xCE400000, 0x00000000, 0xC121FFFE, 0x5911FE54,
+ 0x15000000, 0xC2200060, 0xC0004948, 0xCE001040, 0xC2000000, 0xC000494C, 0xCE000000, 0x80000068,
+ 0x00000000, 0x99008328, 0xDBD80000, 0xDB980001, 0xC7800000, 0x99008528, 0xDBD80000, 0xDB980001,
+ 0xC7800000, 0xC2200058, 0xC0004948, 0xCE001040, 0xC2000002, 0xC000494C, 0xCE000000, 0xC2000006,
+ 0xC0001006, 0xCE000000, 0x5838000A, 0xCA400000, 0xC2200982, 0x5A203B6E, 0xC0001008, 0xCE000000,
+ 0xC000100A, 0xCE400000, 0xC0004954, 0xCA800000, 0xC200000C, 0xC000494A, 0xCE000000, 0xC0004948,
+ 0xCE800010, 0xC2B60000, 0xC0004964, 0xCE800000, 0x990081E8, 0xC00048A0, 0xC8840000, 0x00000000,
+ 0xC0004946, 0xCBC00000, 0xC000494C, 0xCA000000, 0x6FF8A000, 0x6FD44000, 0x4579C000, 0x47F9C000,
+ 0x5BB84E20, 0x5E200000, 0x840000FA, 0x00000000, 0x99007FA8, 0xDBD80000, 0xDB980001, 0x00000000,
+ 0x99007CF0, 0xC000491C, 0xC1400000, 0xC9420050, 0xC000491C, 0x990081A0, 0xC9400001, 0xC9800000,
+ 0x00000000, 0x99007F18, 0xD9580000, 0xD9980001, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x15400000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x99007BE0, 0xDBD80000, 0xDB980001, 0xC7D80000,
+ 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000, 0xC000493C, 0xCA800000, 0xC000494E, 0xCAC00000,
+ 0xC3000018, 0xC3400006, 0x5E200000, 0x84000012, 0xC2800000, 0xC2C00000, 0xC300001E, 0xC3400000,
+ 0xC6AC1080, 0xC72C0420, 0xC76C0818, 0x58380010, 0xCA800000, 0x58380008, 0xCEC00000, 0xC6280108,
+ 0xC0004874, 0xC8040000, 0x6C908000, 0x44908000, 0x44908000, 0x40100000, 0xCB000000, 0xC4340000,
+ 0x00000000, 0xC7400000, 0xCE800000, 0xC0004952, 0xCE800000, 0x00000000, 0x00000000, 0x00000000,
+ 0xA8E2FFC8, 0x00000000, 0xC000494C, 0xCA000000, 0xC0004950, 0xCAC00000, 0x5E200000, 0x84000052,
+ 0xDFE80000, 0x7E814000, 0x5834001A, 0xCE800000, 0x99008690, 0xC0004834, 0xC9400000, 0xC1800002,
+ 0x99008690, 0xC0004838, 0xC9400000, 0xC6D80000, 0xC1220002, 0xD90C0000, 0x5E200000, 0x84000028,
+ 0x5838002C, 0xCB000000, 0xDFE80000, 0x00000000, 0x58380014, 0xCF000000, 0x80000000, 0xC2A1FFFE,
+ 0x5AA9FFFE, 0x5838000A, 0xCE800000, 0xC3000000, 0xC0000A14, 0xCB040030, 0xC2D00002, 0xC0000A28,
+ 0xCEC40808, 0xC000494E, 0xCA800000, 0x58880002, 0xB4B0FFF8, 0xC00048A0, 0xC0800000, 0xCC840000,
+ 0x5EA80000, 0x84000152, 0x5E200000, 0x84000140, 0xC000493C, 0xCA800000, 0x00000000, 0x00000000,
+ 0x5AA80060, 0xCE800000, 0x99008328, 0xDBD80000, 0xDB980001, 0xC7800000, 0x99008528, 0xDBD80000,
+ 0xDB980001, 0xC7800000, 0xC0004952, 0xCAC00000, 0x58380000, 0xCA800000, 0xC30C0002, 0xC7F00020,
+ 0xA6800090, 0x00000000, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x15400000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xC0001800, 0xCA000000, 0x00000000, 0x00000000, 0xA60CFFCA, 0xC6F00508,
+ 0xC6B0C408, 0xCF000000, 0x00000000, 0xC121FFFE, 0x5911FE54, 0x15000000, 0x8000B7A0, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x8000B738, 0xDCBC0001, 0x5FFC0000, 0x84000942, 0xC3800002,
+ 0xDB880001, 0xC3800000, 0xDB880001, 0xC0004728, 0xC9000000, 0x00000000, 0x00000000, 0x59100002,
+ 0xCD000000, 0xC0004730, 0xC9800000, 0xC000472E, 0xC9400000, 0xC00047DC, 0xC9000000, 0xC00047DE,
+ 0xC9C00000, 0xC000472E, 0xCD800000, 0x6D110000, 0xC5D30040, 0xC00047DC, 0xCD000000, 0x4558A000,
+ 0x6DDD0000, 0xC55C0040, 0xC00047DE, 0xCDC00000, 0xC0001AC4, 0xC9400000, 0xC0001AC8, 0xC9800000,
+ 0xC000472C, 0xC9C00000, 0x45588000, 0xC1000002, 0x41D0E004, 0xCDC00000, 0xC5501080, 0xC5900080,
+ 0xC000472A, 0xCD000000, 0xC0001AF0, 0xCBC00000, 0x58000002, 0xCB800000, 0xC3400000, 0xC7F50040,
+ 0x6F702000, 0x5B304300, 0xC000474C, 0xCAC00000, 0xC0004720, 0xC9400000, 0x00000000, 0x00000000,
+ 0x5D940002, 0x6D9B8000, 0x6D9B8010, 0x581847E0, 0xC9800000, 0x581447E0, 0xC9C00000, 0x5D2C0000,
+ 0x84000062, 0xC7901080, 0xC7D00080, 0xCD000000, 0xC1000000, 0xC5910040, 0x47508000, 0x84000078,
+ 0xC0004722, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0x80000040, 0xC1000000,
+ 0xC5D10040, 0x47508000, 0x84000022, 0xC0004724, 0xC9000000, 0x00000000, 0x00000000, 0x59100002,
+ 0xCD000000, 0xA7840060, 0x59540002, 0x6D578000, 0x6D578010, 0xC0004720, 0xCD400000, 0xC1000000,
+ 0xC5910040, 0x47508000, 0x84000020, 0xC0004726, 0xC9000000, 0x00000000, 0x00000000, 0x59100002,
+ 0xCD000000, 0xA7800098, 0xC2800002, 0xC000474E, 0xCE800000, 0xC2C00000, 0xC000474C, 0xCEC00000,
+ 0xC0004758, 0xCFC00000, 0x58000002, 0xCF800000, 0xC000475C, 0xC9000000, 0x00000000, 0x00000000,
+ 0xA53E001A, 0x00000000, 0xC13E0002, 0xCFC00000, 0xCD001E10, 0x58000002, 0xCF800000, 0x80000188,
+ 0xC000475C, 0xC13C0002, 0xCD001E10, 0x5D2C0000, 0x84000162, 0xC2C00000, 0xC000474C, 0xCEC00000,
+ 0x98C08AF0, 0xC7540000, 0xC0004740, 0xC9C00000, 0x5D240000, 0x8400002A, 0xC1000002, 0xC0004750,
+ 0xCD000000, 0xC0004752, 0xCD000000, 0x800000E8, 0x00000000, 0x98C08BE0, 0xC7540000, 0xC0004742,
+ 0xC9800000, 0x5D240000, 0x84000012, 0xC1000002, 0xC0004752, 0xCD000000, 0x80000048, 0xC0004742,
+ 0xC9400000, 0xC0004754, 0xC1000002, 0xCD000000, 0x98C08CF0, 0xC5540000, 0xC7580000, 0x00000000,
+ 0xC0004742, 0xCF400000, 0x98C08AB8, 0xC1400000, 0xC7540028, 0x6F40A010, 0xC1000000, 0xC7D00040,
+ 0x58300000, 0x6D110000, 0xCD000840, 0xA7840378, 0xC000474C, 0xCAC00000, 0xC000474E, 0xCA800000,
+ 0xC0004750, 0xCBC00000, 0xC0004752, 0xCB800000, 0xC0004710, 0xC9000000, 0x00000000, 0x00000000,
+ 0x59100002, 0xCD000000, 0x5D280002, 0x840000A0, 0xC000473C, 0xC9000000, 0x00000000, 0x00000000,
+ 0x59100002, 0xCD000000, 0xC0004712, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000,
+ 0xC0004754, 0xC9000000, 0x00000000, 0x00000000, 0x5D100000, 0x84000202, 0x58300000, 0xC13C0002,
+ 0xCD001E08, 0x800001E0, 0xC0004714, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000,
+ 0x5D380000, 0x84000022, 0xC0004736, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000,
+ 0x5D3C0000, 0x8400002A, 0xC0004718, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000,
+ 0x80000128, 0xC1000000, 0x58300000, 0xC903E008, 0x00000000, 0x00000000, 0x5D100000, 0x8400002A,
+ 0xC000471A, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0x800000B8, 0x58300000,
+ 0xC13E0002, 0xCD001F08, 0xC1000000, 0x58300000, 0xC903C008, 0x00000000, 0x00000000, 0x5D100000,
+ 0x8400006A, 0xC0004716, 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0xC000473A,
+ 0xC9000000, 0x00000000, 0x00000000, 0x59100002, 0xCD000000, 0x58300000, 0xC13C0000, 0xCD001E08,
+ 0xC1000000, 0xC0004746, 0xCD000000, 0xC0004750, 0xCD000000, 0xC0004752, 0xCD000000, 0xC000474E,
+ 0xCD000000, 0xC2C00002, 0xC000474C, 0xCEC00000, 0xC0004754, 0xCD000000, 0xC3CE0002, 0xC0000800,
+ 0xCFC00708, 0xC3E1FFFE, 0x597DFFFE, 0x593DFE14, 0x94000001, 0x00000000, 0x00000000, 0x00000000,
+ 0xC000487C, 0xC8040000, 0x00000000, 0x00000000, 0x40080000, 0xCBC00000, 0xC4380000, 0x00000000,
+ 0xC000480E, 0xCA000000, 0xC0004858, 0xCB440000, 0x00000000, 0x00000000, 0x46350000, 0x88000098,
+ 0x00000000, 0xA7C00028, 0xC0004854, 0xC1000002, 0xCD040000, 0xC11C0000, 0xC000082C, 0xCD040E08,
+ 0x800000C0, 0x00000000, 0xA7D20118, 0x00000000, 0xC7E14048, 0xC2400000, 0xC6246030, 0xC200006A,
+ 0x46610000, 0xC6240038, 0xC0000810, 0xCE440038, 0x8000FF58, 0xC2000000, 0xC0000808, 0xCA040018,
+ 0xC11C0000, 0xC000082C, 0xCD040E08, 0x5A200002, 0x5E600010, 0x8400FFF8, 0xC2000000, 0xC0000808,
+ 0xCE040018, 0xC3400000, 0x80000010, 0xC1200002, 0xC0000818, 0xCD041008, 0x5B740002, 0xC0004858,
+ 0xCF440000, 0x99007930, 0xC0004848, 0xC9440000, 0xC1800000, 0xC11C0002, 0xC000082C, 0xCD040E08,
+ 0x80000860, 0x5B740002, 0xC0004858, 0xCF440000, 0xC7800000, 0xC13C0002, 0xCD001E08, 0xC0004848,
+ 0xC9440000, 0xC1800000, 0xC000082C, 0xC9840030, 0x59540002, 0xC0004848, 0xCD440000, 0x58880002,
+ 0xB49807D8, 0x00000000, 0xC0800000, 0x800007C8, 0xC000487C, 0xC8040000, 0x00000000, 0x00000000,
+ 0x40080000, 0xCBC00000, 0xC4280000, 0x00000000, 0xA7C00110, 0xC000484C, 0xCA040000, 0xC2400000,
+ 0xC0001AEC, 0xCA440020, 0x5A200002, 0xC000484C, 0xCE040000, 0xB624006A, 0xC6800000, 0xC13C0002,
+ 0xCD001E08, 0xC0004848, 0xC9440000, 0xC1800000, 0xC000082C, 0xC9840030, 0x59540002, 0xC0004848,
+ 0xCD440000, 0x58880002, 0xB49806C8, 0x00000000, 0xC0800000, 0x800006B8, 0xC0004854, 0xC1000004,
+ 0xCD040000, 0xC0000820, 0xC2000002, 0xCE040000, 0xC2000000, 0xC000484C, 0xCE040000, 0xC0004858,
+ 0xCE040000, 0x8000FF10, 0xC0004854, 0xC1000000, 0xCD040000, 0xC11C0000, 0xC000082C, 0xCD040E08,
+ 0x99007930, 0xC0004848, 0xC9440000, 0xC1800000, 0xC1200000, 0xC0000818, 0xCD041008, 0xC11C0002,
+ 0xC000082C, 0xCD040E08, 0xC2000000, 0xC000484C, 0xCE040000, 0x800005B8, 0xC0001AC0, 0xCB840000,
+ 0xC000487C, 0xC8040000, 0x00000000, 0x00000000, 0x40080000, 0xCBC00000, 0xC4280000, 0x00000000,
+ 0xA78004C2, 0x00000000, 0x00000000, 0xA7C00482, 0x00000000, 0xC0001B00, 0xC2060006, 0xCE040310,
+ 0xA7E8043A, 0x00000000, 0xC0004850, 0xCA040000, 0xC2400000, 0xC0004812, 0xCA420080, 0x5A200002,
+ 0xC0004850, 0xCE040000, 0x5E640000, 0x84000002, 0x46610000, 0x880002E0, 0xC6800000, 0xC13C0002,
+ 0xCD001E08, 0xC0001ACC, 0xC2000002, 0xCE040008, 0x5C440000, 0x84000238, 0xC0004810, 0xC9400000,
+ 0xC6800000, 0xCBC00000, 0x00000000, 0xC1000000, 0xA54001E8, 0xC53C1008, 0x00000000, 0xA7FC01D2,
+ 0xC0001AF0, 0xC1000000, 0x58000002, 0xC9000008, 0xC000474E, 0xC9800000, 0x5D100000, 0x8400000A,
+ 0xC1000002, 0xC53C1E08, 0x80000180, 0x5D180000, 0x8400000A, 0xC1000002, 0xC53C1E08, 0x80000158,
+ 0xC0004878, 0xC8040000, 0x6C908000, 0x44908000, 0x44908000, 0x40100000, 0xC9800000, 0xC4380000,
+ 0x00000000, 0xC000481E, 0xC9C00000, 0xC000481C, 0xCA000000, 0x00000000, 0x75D8C000, 0x46188000,
+ 0x840000D0, 0xC0001AF0, 0xC3400000, 0x58000000, 0xCB410040, 0xC0004746, 0xC9400000, 0x6F702000,
+ 0x5B304300, 0xC2C00000, 0x58300000, 0xCAC00040, 0x00000000, 0x00000000, 0x46D48000, 0x88000008,
+ 0xC1000002, 0xC53C1E08, 0x80000028, 0x5AEC0002, 0x58300000, 0xCEC00040, 0xC1000002, 0xC53C1008,
+ 0xC77C0840, 0xC57C0040, 0x59540002, 0xC0004746, 0xCD400000, 0xC6800000, 0xCFC00000, 0xC0004848,
+ 0xC9440000, 0xC1800000, 0xC000082C, 0xC9840030, 0x59540002, 0xC0004848, 0xCD440000, 0x58880002,
+ 0xB49801D8, 0x00000000, 0xC0800000, 0x800001C8, 0xC000471E, 0xC9000000, 0x00000000, 0x00000000,
+ 0x59100002, 0xCD000000, 0xC0004854, 0xC1000000, 0xCD040000, 0xC11C0000, 0xC000082C, 0xCD040E08,
+ 0x99007930, 0xC0004848, 0xC9440000, 0xC1800000, 0xC2000000, 0xC0000820, 0xCE040000, 0xC1200000,
+ 0xC0000818, 0xCD041008, 0xC11C0002, 0xC000082C, 0xCD040E08, 0xC0004850, 0xCE040000, 0xC2000002,
+ 0xC0001ACC, 0xCE040010, 0x800000D0, 0xC2000002, 0xC0004850, 0xCE040000, 0x8000FBE8, 0xC2000000,
+ 0xC0004850, 0xCE040000, 0xA7E60012, 0x00000000, 0xC2000002, 0xC0001B00, 0xCE040008, 0x8000FBD0,
+ 0x00000000, 0xA7860032, 0x00000000, 0xC6800000, 0xC13C0002, 0xCD001E08, 0xC2020002, 0xC7E2A548,
+ 0xC0001B00, 0xCE040000, 0x8000FB78, 0xC2040002, 0xC0001B00, 0xCE040208, 0x8000FB58, 0xC2C80002,
+ 0x6AC56000, 0xDACC0000, 0xC0004854, 0xCB440000, 0xC0004848, 0xCB840000, 0xC0000838, 0xC3C00000,
+ 0xCBC40030, 0x5EF40004, 0x8400000A, 0xC3000000, 0xC0001ACC, 0xCF040108, 0x47BD8000, 0x84000032,
+ 0x47BD8000, 0x88000038, 0xC1006E8C, 0xC1400010, 0x8D580000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0004840, 0xCC840000, 0x8000EAF8, 0xC0001AC0, 0xCAC40000, 0xC0004854, 0xCB440000, 0xA6C0F91A,
+ 0x00000000, 0x5EF40000, 0x8400F45A, 0x5EF40002, 0x8400F6EA, 0x5EF40004, 0x8400F8EA, 0xC1006CE8,
+ 0xC1400010, 0x8D580000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xC0800000, 0xDF4B0040,
+ 0xC0004900, 0xCB800000, 0xC2000000, 0xC000490A, 0xA78000B0, 0xCBC00000, 0xC1000000, 0xD9000001,
+ 0xC1000002, 0xD90C0000, 0x6FF46000, 0x47F5A000, 0x5B744C80, 0xC2400000, 0x58340004, 0xCA400080,
+ 0xC0004900, 0xCE000008, 0x5A640002, 0x58340004, 0xC6500080, 0xCD000080, 0xC0004914, 0xCA400000,
+ 0xC2000002, 0x6A3D0000, 0x72252000, 0xCE400000, 0xC0000408, 0xCE000000, 0xA78200B8, 0xC0004908,
+ 0xCBC00000, 0xC1000000, 0xD9000001, 0xC1000002, 0xD90C0000, 0x6FF4A000, 0x6FD44000, 0x4575A000,
+ 0x47F5A000, 0x5B744E20, 0xC2800000, 0x58340006, 0xCA800080, 0xC2000000, 0xC0004900, 0xCE000108,
+ 0x5EA80002, 0x58340006, 0xC6900080, 0xCD000080, 0x5A7C0020, 0xC2000002, 0x6A250000, 0xC0000408,
+ 0xCE000000, 0xC0000032, 0xDCA80001, 0xC1000002, 0x46914000, 0x00000000, 0x8C100006, 0x00000000,
+ 0x00000000, 0x00000000, 0xA4800210, 0x00000000, 0xC3C00000, 0xC000140E, 0xCBC00020, 0xC3400000,
+ 0xC2400000, 0x6FF86000, 0x47F9C000, 0x5BB84C80, 0x58380008, 0xCB400080, 0x58380006, 0xCA400080,
+ 0x5F740002, 0x58380008, 0xC7500080, 0xCD000080, 0xC2000000, 0x58380004, 0xCA020080, 0xC3000000,
+ 0x5838000C, 0xCB000028, 0x5A640002, 0x46250000, 0x8400FFF8, 0xC2400000, 0x58380006, 0xC6500080,
+ 0xCD000080, 0xC2000000, 0x5838000A, 0xCA020080, 0x5B300002, 0x5838000C, 0xC7100028, 0xCD000028,
+ 0xC2420020, 0x5A200004, 0x46612000, 0x8400FFF8, 0xC2000000, 0x5838000A, 0xC6101080, 0xCD001080,
+ 0xC0004966, 0xCA400000, 0xC2000002, 0x6A3D0000, 0x72252000, 0xCE400000, 0x5F740000, 0x84000028,
+ 0xC0004912, 0xCA000000, 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x76E10000, 0xCE000000, 0x5F300020,
+ 0x84000028, 0xC0004924, 0xCA000000, 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x76E10000, 0xCE000000,
+ 0xA4820050, 0xC2400000, 0xC000140E, 0xCA408020, 0xC2000002, 0xC0004900, 0xCE000008, 0xC000490A,
+ 0xCE400000, 0xC1000000, 0xD9000001, 0xD8400080, 0xC1000004, 0xD9000001, 0xA4840288, 0x00000000,
+ 0xC3C00000, 0xC000140E, 0xCBC10020, 0xC2800000, 0xC2000000, 0x6FF8A000, 0x6FD44000, 0x4579C000,
+ 0x47F9C000, 0x5BB84E20, 0x5838002E, 0xCA800080, 0x58380006, 0xCA020080, 0xC3400000, 0x5838002E,
+ 0xCB420080, 0x5AA80002, 0x46290000, 0x8400FFF8, 0xC2800000, 0x5838002E, 0xC6900080, 0xCD000080,
+ 0x5F740002, 0x5838002E, 0xC7501080, 0xCD001080, 0xC0004968, 0xCA400000, 0xC2000002, 0x6A3D0000,
+ 0x72252000, 0xCE400000, 0xC000492A, 0xCA800000, 0x5E740000, 0x84000028, 0xC0004910, 0xCA000000,
+ 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x76E10000, 0xCE000000, 0x6ABD4010, 0xA68000D2, 0x00000000,
+ 0xC0004910, 0xCA000000, 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x76E10000, 0xCE000000, 0x58380032,
+ 0xCA000000, 0x58000002, 0xCA400000, 0x5838000C, 0x00000000, 0xCE000001, 0xCE400000, 0xC000492A,
+ 0xCA000000, 0xC2C00002, 0x6AFD6000, 0x72E10000, 0xCE000000, 0xC000492C, 0xCA000000, 0xC2C00002,
+ 0x6AFD6000, 0x72E10000, 0xCE000000, 0x80000028, 0xC000492C, 0xCA000000, 0xC2C00002, 0x6AFD6000,
+ 0x7EC16000, 0x76E10000, 0xCE000000, 0xA4880100, 0xC2C00000, 0xC000140E, 0xCAC20020, 0xC000490E,
+ 0xCA400000, 0xC2000002, 0x6A2D0000, 0x7E010000, 0x76252000, 0xCE400000, 0xC000496A, 0xCA400000,
+ 0xC2000002, 0x6A2D0000, 0x72252000, 0xCE400000, 0x6EF0A000, 0x6ED44000, 0x45718000, 0x46F18000,
+ 0x5B304E20, 0x58300000, 0xCA000000, 0x00000000, 0xC2400002, 0x76252000, 0x84000032, 0xC24C0002,
+ 0xC6E40020, 0xC624C408, 0x58300010, 0xCA400508, 0x00000000, 0xC0001800, 0xCE400000, 0xA4860050,
+ 0xC2400000, 0xC000140E, 0xCA418020, 0xC2020002, 0xC0004900, 0xCE000108, 0xC0004908, 0xCE400000,
+ 0xC1000000, 0xD9000001, 0xD8400080, 0xC1000004, 0xD9000001, 0xA48C0028, 0xC2800002, 0xC000484A,
+ 0xCE800000, 0xC2800000, 0xC000474A, 0xCE800000, 0xC0004846, 0xCE800000, 0xC0001408, 0xCC800000,
+ 0xC10E0002, 0xD90C0000, 0x8000EA60, 0xDFBC0001, 0xC000496E, 0x99008638, 0xC9400000, 0xC7D80000,
+ 0x00000000, 0xC5700000, 0x5EF00020, 0x88000130, 0x6F346000, 0x4735A000, 0x5B744C80, 0x58340008,
+ 0xC2400000, 0xCA400080, 0x00000000, 0xC2000000, 0x5A640002, 0xCE400080, 0x58340004, 0xCA000080,
+ 0x00000000, 0x00000000, 0x5E200002, 0xCE000080, 0xC0004912, 0xCA800000, 0xC2400002, 0x6A712000,
+ 0x72694000, 0xCE800000, 0x5E200000, 0x8400003A, 0xC000480A, 0xCA000000, 0xC0000408, 0xCA800000,
+ 0x76610000, 0x00000000, 0x72294000, 0xCE800000, 0x80000020, 0xC0004914, 0xCA000000, 0x7E412000,
+ 0x00000000, 0x76610000, 0xCE000000, 0x800000B8, 0x6EF4A000, 0x6ED44000, 0x4575A000, 0x46F5A000,
+ 0x5B744E20, 0x5834002E, 0xC2400000, 0xCA420080, 0x00000000, 0xC2000000, 0x5A640002, 0xC6501080,
+ 0xCD001080, 0x58340006, 0xCA000080, 0x00000000, 0x00000000, 0x5A200002, 0xCE000080, 0xC0004910,
+ 0xCA400000, 0xC2000002, 0x6A2D0000, 0x72252000, 0xCE400000, 0xC2000002, 0x6A310000, 0xC000042A,
+ 0xCE000000, 0xC1040002, 0xD90C0000, 0x00000000, 0x8000E7D0, 0x00000000, 0xC4980930, 0x9D000000,
+ 0xC5580030, 0xC0000838, 0xCD840000, 0xC1440200, 0xC1C03200, 0xC55C1078, 0xC000100E, 0x9D000000,
+ 0xCD800000, 0xC000100C, 0xCDC00000, 0xC0004862, 0xC9C00000, 0x00000000, 0x00000000, 0xD9D80001,
+ 0xC0007200, 0x401C0000, 0x5DC07400, 0x8800FFFA, 0x5C000200, 0xCD800000, 0xC1F0000A, 0x71D4A000,
+ 0xDD980000, 0xDD9C0001, 0x41D8E000, 0xC5D40268, 0xC0001010, 0xCD400000, 0x6C9C8000, 0x449CE000,
+ 0x449CE000, 0x59DC0004, 0xC1601260, 0xC5D40268, 0x9D000000, 0xC0001012, 0xCD400000, 0x00000000,
+ 0x00000000, 0xD9580000, 0x6D586000, 0x4558C000, 0x59984C80, 0xD9980001, 0x5818000A, 0xC1800000,
+ 0xC9800080, 0xC0005400, 0x6D5CA000, 0x401C0000, 0x40180000, 0xC9400000, 0x58000002, 0x00000000,
+ 0xC9C00000, 0xC0004930, 0xCD400000, 0xC0004932, 0xCDC00000, 0x59980004, 0xC1C20020, 0xB59CFFF8,
+ 0x00000000, 0xC1800000, 0xDD9C0001, 0x581C000A, 0xCD800080, 0x581C000C, 0xC1800000, 0xC9800028,
+ 0xC1C00002, 0xDD940000, 0x69D4E000, 0x5D980002, 0xCD800028, 0xC0004924, 0xC9800000, 0x00000000,
+ 0x9D000000, 0x00000000, 0x71D8C000, 0xCD800000, 0xC000492A, 0xC9400000, 0xC1C00002, 0x69D8E000,
+ 0x7DC0C000, 0x7594A000, 0xCD400000, 0xC000492C, 0xC9400000, 0xDD800001, 0x58000032, 0x75D4A000,
+ 0x84000078, 0xC9400001, 0xC9800000, 0xDD800001, 0x5800000C, 0x00000000, 0xCD400001, 0xCD800000,
+ 0xC000492C, 0xC9400000, 0xC000492A, 0xC9800000, 0x71D4A000, 0xC000492C, 0xCD400000, 0x71D8C000,
+ 0xC000492A, 0xCD800000, 0x9D000000, 0x00000000, 0x00000000, 0x00000000, 0xC0004862, 0xC9800000,
+ 0x00000000, 0xC1C00200, 0x4194C000, 0x45D8E000, 0x8800FFFA, 0xC5D80000, 0xC0004862, 0xCD800000,
+ 0xC0001406, 0xC9800000, 0xC1C00002, 0x9D000000, 0xC5D80A08, 0xC5581050, 0xCD800000, 0xC0004930,
+ 0xC9800000, 0xC0004932, 0xC9C00000, 0xC140000E, 0xC5581C20, 0xDD940000, 0xC0007200, 0x40140000,
+ 0x5D407400, 0x8800FFFA, 0x5C000200, 0xCD800000, 0x58000002, 0x5D407400, 0x8800FFFA, 0x5C000200,
+ 0xCDC00000, 0xDD540000, 0xC1C00000, 0x58140006, 0xC9C20080, 0xC1800000, 0x58140000, 0xC98000E0,
+ 0x6DDC2000, 0xC000491E, 0x41D8E000, 0xCDC00000, 0xDD980000, 0xC1C00022, 0xC5D80D78, 0xDD940001,
+ 0xC5581C20, 0xC000491C, 0xCD800000, 0xDD540000, 0xC1C00000, 0x58140006, 0xC9C20080, 0xC1800000,
+ 0x58140004, 0xC9820080, 0x00000000, 0x59DC0002, 0x459CC000, 0x8400FFF8, 0xC1C00000, 0x9D000000,
+ 0x58140006, 0xC5D81080, 0xCD801080, 0xC0004860, 0xC9400000, 0xC1820080, 0xC1D00002, 0x58146B00,
+ 0xD5800000, 0x58000002, 0xD5800001, 0x59540004, 0xB558FFF8, 0xC0004860, 0xC1400000, 0xCD400000,
+ 0xDD980001, 0x9D000000, 0xDD940000, 0xC0001404, 0xCDC00808, 0xC1C00000, 0xC1800200, 0x5D980004,
+ 0xDF5D0050, 0x45D8A000, 0x8800FFDA, 0xDD800001, 0x5800000C, 0x00000000, 0xC9400001, 0xC9800000,
+ 0xC1C00002, 0xC5D43F08, 0xC5D81E08, 0xC0004862, 0xC9C00000, 0x00000000, 0x00000000, 0x581C7200,
+ 0x5DC07400, 0x8800FFFA, 0x5C000200, 0xCD400000, 0x58000002, 0x5DC07400, 0x8800FFFA, 0x5C000200,
+ 0xCD800000, 0xC0004862, 0xC9C00000, 0x00000000, 0xC15004C0, 0xC5D40068, 0xDD9C0000, 0xC5D41C20,
+ 0xC1C00000, 0xDD800001, 0x58000030, 0xC9C00080, 0xDD800001, 0x58000002, 0xC9800000, 0x6DDC2000,
+ 0xC000491C, 0x41D8E000, 0xCD400001, 0xCDC00000, 0xDD940001, 0xC1C00000, 0x58140030, 0xC9C00080,
+ 0xC1800000, 0x58140006, 0xC9820080, 0x00000000, 0x59DC0002, 0x459CC000, 0x8400FFF8, 0xC1C00000,
+ 0x9D000000, 0x58140030, 0xC5D80080, 0xCD800080, 0xC1C00000, 0xDF5C0040, 0x5DDC0080, 0x8400FFD2,
+ 0x00000000, 0x9D000000, 0x00000000, 0x00000000, 0x00000000, 0xC160FFFE, 0xC0000A10, 0xC9440068,
+ 0xC1A0FFFE, 0x59980E28, 0xC000100C, 0xCD400000, 0xC000100E, 0xCD800000, 0xC0004964, 0xC9800000,
+ 0x00000000, 0xC170000A, 0x7194A000, 0x6C988000, 0x4498C000, 0x4498C000, 0x59980004, 0xC5940278,
+ 0xC0001010, 0xCD400000, 0xC0004946, 0xC9400000, 0x00000000, 0x00000000, 0x6D58A000, 0x6D5C4000,
+ 0x45D8C000, 0x4558C000, 0xC000494A, 0xC9400000, 0xC0004948, 0xC9C00000, 0x4194C000, 0xC1400012,
+ 0xC55C1820, 0x9D000000, 0xC59C0270, 0xC0001012, 0xCDC00000, 0xC1400000, 0x58000012, 0xC9410040,
+ 0xC0004950, 0xC9C00000, 0xC5580000, 0xC5940840, 0xC5581080, 0xD9940000, 0xC000493C, 0xC9400000,
+ 0xC0004954, 0xC9800000, 0x59DC00A8, 0x455CE000, 0x41D8E000, 0x5D5C0030, 0x8800FFF8, 0xC1C00030,
+ 0xC1800000, 0xC5D84030, 0xC1400000, 0xC5D40010, 0x5DD40002, 0x8400005A, 0x5DD40004, 0x84000082,
+ 0x5DD40006, 0x840000AA, 0x5DD80026, 0x840000D2, 0xDD540000, 0xDD800001, 0x58000008, 0x40180000,
+ 0xCD400000, 0x59980002, 0x8000FFA8, 0xDD540000, 0xDD800001, 0x58000008, 0x40180000, 0xCD4000C0,
+ 0x59980002, 0x8000FF70, 0xDD540000, 0xDD800001, 0x58000008, 0x40180000, 0xCD400080, 0x59980002,
+ 0x8000FF38, 0xDD540000, 0xDD800001, 0x58000008, 0x40180000, 0xCD400040, 0x59980002, 0x8000FF00,
+ 0x00000000, 0x9D000000, 0x00000000, 0x00000000, 0x00000000, 0x58000012, 0xC9400000, 0xC0004954,
+ 0xC9C00000, 0xC0004950, 0xC9400080, 0xDD800001, 0x58000028, 0x5D9C0000, 0x8400003A, 0x5D9C0002,
+ 0x8400003A, 0x5D9C0004, 0x84000052, 0xC55B0040, 0xC55C08C0, 0xCD800041, 0xCDC008C0, 0x80000048,
+ 0xCD400000, 0x80000038, 0xC55900C0, 0xC55C1840, 0xCD8000C1, 0xCDC01840, 0x80000010, 0xC55A0080,
+ 0xC55C1080, 0xCD800081, 0xCDC01080, 0x9D000000, 0x00000000, 0x00000000, 0x00000000, 0x59540002,
+ 0x6994E018, 0x61C0C008, 0x4194A000, 0x5D940040, 0x8800FFFA, 0xC5940000, 0x9D000000, 0xCD400000,
+ 0x00000000, 0x00000000, 0x9D000000, 0x4158A000, 0xCD400000, 0x00000000, 0xCD800001, 0x44148000,
+ 0x8800FFD8, 0x00000000, 0x9CC00000, 0x00000000, 0x00000000, 0x00000000, 0xC0004810, 0xCA010040,
+ 0xC241FFFE, 0xC1400000, 0x45608000, 0x00000000, 0x9CC00006, 0xC0004200, 0x40180000, 0xC9C00000,
+ 0x00000000, 0x00000000, 0x61C08010, 0x84000042, 0xC2400002, 0x6A512000, 0x725CE000, 0xCDC00000,
+ 0xC0004748, 0xCD800000, 0x9CC00000, 0x6D98A000, 0x5998003E, 0x45192000, 0x59540002, 0x59980002,
+ 0x45A08000, 0xC1000000, 0xC5180006, 0x8000FF20, 0x00000000, 0x40180000, 0xC9C00000, 0xC2000000,
+ 0xC5600028, 0xC1210000, 0x69208010, 0x7D008000, 0x751CE000, 0xCDC00000, 0x6D542000, 0x58144300,
+ 0xC1000000, 0xCD000001, 0x9CC00000, 0xC121FFFE, 0x5911FFFE, 0xCD000001, 0x79948000, 0x6D10A010,
+ 0x5D100000, 0x840000A8, 0x45588000, 0x88000098, 0x6D536000, 0x6D136010, 0x6D54A010, 0xC0004700,
+ 0x40140000, 0xCA000000, 0x00000000, 0x00000000, 0x6A110000, 0x6A110010, 0x62008018, 0x8400001A,
+ 0x00000000, 0x9CC00000, 0x6D54A000, 0x5954003E, 0x45152000, 0x59540002, 0x6D57A000, 0x6D57A010,
+ 0x6D54A000, 0x6D936000, 0x6D136010, 0xC1E10000, 0x69D0E010, 0x5DDC0002, 0x7DC0E000, 0x6D98A010,
+ 0x6D536000, 0x6D136010, 0x6D54A010, 0xC0004700, 0x40140000, 0xCA000000, 0x00000000, 0x00000000,
+ 0x6A110000, 0x6A110010, 0x45948000, 0x00000000, 0x75E10002, 0x62008018, 0x8400001A, 0x00000000,
+ 0x9CC00000, 0x6D54A000, 0x5954003E, 0x45152000, 0x45948000, 0x00000000, 0x9CC00002, 0x59540002,
+ 0x6D57A000, 0x6D57A010, 0xC0004700, 0x40140000, 0xCA000000, 0x8000FF50, 0x00000000, 0x00000000,
+ 0x00000000, 0x58004700, 0xC9800000, 0x9CC00000, 0x00000000, 0x6994C000, 0x6DA7E010, 0x58004700,
+ 0xC9800000, 0xC1210000, 0x9CC00000, 0x69148010, 0x7118C000, 0xCD800000, 0xC1000000, 0xC0004810,
+ 0xC9020040, 0x00000000, 0x00000000, 0x451CC000, 0x8800004A, 0xC2400002, 0x45948000, 0xC1000000,
+ 0xC5240004, 0x455C8000, 0xC1000000, 0xC5240006, 0x9CC00000, 0x00000000, 0x00000000, 0x00000000,
+ 0x59980200, 0xC2400000, 0x45D48000, 0xC1000002, 0xC5240004, 0x45588000, 0xC1000002, 0xC5240006,
+ 0x9CC00000, 0x00000000, 0x00000000, 0x00000000, 0xC0004740, 0xC9C00000, 0x59180002, 0x6D130000,
+ 0x6D130010, 0x45D08000, 0xC2400000, 0x9CC00002, 0x00000000, 0x00000000, 0x45D88000, 0x8800004A,
+ 0xC2400002, 0x45D48000, 0xC1000000, 0xC5240004, 0x45588000, 0xC1000000, 0xC5240004, 0x9CC00000,
+ 0x00000000, 0x00000000, 0x00000000, 0xC2400000, 0x45948000, 0xC1000002, 0xC5240006, 0x455C8000,
+ 0xC1000002, 0xC5240006, 0x9CC00000, 0x00000000, 0x00000000, 0x00000000, 0x59540002, 0x6D570000,
+ 0x6D570010, 0x45948000, 0x6D402000, 0x9CC00002, 0x58004300, 0x58000000, 0xC13C0002, 0xCD001E08,
+ 0x8000FF98, 0x00000000, 0x00000000, 0x00000000, 0xC1020002, 0xD90C0000, 0xC9800000, 0x59540002,
+ 0xC0004730, 0xCD400000, 0x5D980002, 0x00000000, 0x8000001E, 0x00000000, 0x9CC00000, 0xC0004732,
+ 0xCD800000, 0x00000000, 0xC0004734, 0xC9C00000, 0xC1800000, 0xC0004816, 0xC9820080, 0xC0004738,
+ 0xCDC00000, 0xC1C00000, 0xC0004734, 0x9CC00000, 0xCDC00000, 0xC0004732, 0xCD800000,
+};
+
+static unsigned int firmware_binary_data[] = {
+};
+
+
+#endif // IFXMIPS_ATM_FW_DANUBE_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_amazon_se.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_amazon_se.h
new file mode 100644
index 0000000000..87cbe5dbe7
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_amazon_se.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_fw_regs_amazon_se.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (Firmware Registers)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_ATM_FW_REGS_AMAZON_SE_H
+#define IFXMIPS_ATM_FW_REGS_AMAZON_SE_H
+
+
+
+/*
+ * Host-PPE Communication Data Address Mapping
+ */
+#define FW_VER_ID ((volatile struct fw_ver_id *) SB_BUFFER(0x2401)) /* Firmware Version ID */
+#define CFG_WRX_HTUTS SB_BUFFER(0x2400) /* WAN RX HTU Table Size, must be configured before enable PPE firmware. */
+//#define CFG_WRX_QNUM SB_BUFFER(0x2401) /* WAN RX Queue Number */
+#define CFG_WRX_DCHNUM SB_BUFFER(0x2402) /* WAN RX DMA Channel Number, no more than 8, must be configured before enable PPE firmware. */
+#define CFG_WTX_DCHNUM SB_BUFFER(0x2403) /* WAN TX DMA Channel Number, no more than 16, must be configured before enable PPE firmware. */
+#define CFG_WRDES_DELAY SB_BUFFER(0x2404) /* WAN Descriptor Write Delay, must be configured before enable PPE firmware. */
+#define WRX_DMACH_ON SB_BUFFER(0x2405) /* WAN RX DMA Channel Enable, must be configured before enable PPE firmware. */
+#define WTX_DMACH_ON SB_BUFFER(0x2406) /* WAN TX DMA Channel Enable, must be configured before enable PPE firmware. */
+#define WRX_HUNT_BITTH SB_BUFFER(0x2407) /* WAN RX HUNT Threshold, must be between 2 to 8. */
+#define WRX_QUEUE_CONFIG(i) ((struct wrx_queue_config*) SB_BUFFER(0x2500 + (i) * 20))
+#define WRX_DMA_CHANNEL_CONFIG(i) ((struct wrx_dma_channel_config*) SB_BUFFER(0x2640 + (i) * 7))
+#define WTX_PORT_CONFIG(i) ((struct wtx_port_config*) SB_BUFFER(0x2440 + (i)))
+#define WTX_QUEUE_CONFIG(i) ((struct wtx_queue_config*) SB_BUFFER(0x2F00 + (i) * 27))
+#define WTX_DMA_CHANNEL_CONFIG(i) ((struct wtx_dma_channel_config*) SB_BUFFER(0x2F01 + (i) * 27))
+#define WAN_MIB_TABLE ((struct wan_mib_table*) SB_BUFFER(0x2410))
+#define HTU_ENTRY(i) ((struct htu_entry*) SB_BUFFER(0x3200 + (i)))
+#define HTU_MASK(i) ((struct htu_mask*) SB_BUFFER(0x3220 + (i)))
+#define HTU_RESULT(i) ((struct htu_result*) SB_BUFFER(0x3240 + (i)))
+
+
+
+#endif // IFXMIPS_ATM_FW_REGS_AMAZON_SE_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_ar9.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_ar9.h
new file mode 100644
index 0000000000..dd010f54f9
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_ar9.h
@@ -0,0 +1,172 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_fw_regs_ar9.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (Firmware Registers)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_ATM_FW_REGS_AR9_H
+#define IFXMIPS_ATM_FW_REGS_AR9_H
+
+
+
+/*
+ * Host-PPE Communication Data Address Mapping
+ */
+#define FW_VER_ID ((volatile struct fw_ver_id *) SB_BUFFER(0x2001))
+#define CFG_WRX_HTUTS SB_BUFFER(0x2400) /* WAN RX HTU Table Size, must be configured before enable PPE firmware. */
+#define CFG_WRX_QNUM SB_BUFFER(0x2401) /* WAN RX Queue Number */
+#define CFG_WRX_DCHNUM SB_BUFFER(0x2402) /* WAN RX DMA Channel Number, no more than 8, must be configured before enable PPE firmware. */
+#define CFG_WTX_DCHNUM SB_BUFFER(0x2403) /* WAN TX DMA Channel Number, no more than 16, must be configured before enable PPE firmware. */
+#define CFG_WRDES_DELAY SB_BUFFER(0x2404) /* WAN Descriptor Write Delay, must be configured before enable PPE firmware. */
+#define WRX_DMACH_ON SB_BUFFER(0x2405) /* WAN RX DMA Channel Enable, must be configured before enable PPE firmware. */
+#define WTX_DMACH_ON SB_BUFFER(0x2406) /* WAN TX DMA Channel Enable, must be configured before enable PPE firmware. */
+#define WRX_HUNT_BITTH SB_BUFFER(0x2407) /* WAN RX HUNT Threshold, must be between 2 to 8. */
+#define WRX_QUEUE_CONFIG(i) ((struct wrx_queue_config*) SB_BUFFER(0x2500 + (i) * 20))
+#define WRX_QUEUE_CONTEXT(i) ((struct wrx_queue_context*) SB_BUFFER(0x2504 + (i) * 20))
+#define WRX_DMA_CHANNEL_CONFIG(i) ((struct wrx_dma_channel_config*) SB_BUFFER(0x2640 + (i) * 7))
+#define WRX_DESC_CONTEXT(i) ((struct wrx_desc_context*) SB_BUFFER(0x2643 + (i) * 7))
+#define WTX_PORT_CONFIG(i) ((struct wtx_port_config*) SB_BUFFER(0x2440 + (i)))
+#define WTX_QUEUE_CONFIG(i) ((struct wtx_queue_config*) SB_BUFFER(0x3800 + (i) * 27))
+#define WTX_DMA_CHANNEL_CONFIG(i) ((struct wtx_dma_channel_config*) SB_BUFFER(0x3801 + (i) * 27))
+#define WAN_MIB_TABLE ((struct wan_mib_table*) SB_BUFFER(0x2410))
+#define HTU_ENTRY(i) ((struct htu_entry*) SB_BUFFER(0x2010 + (i)))
+#define HTU_MASK(i) ((struct htu_mask*) SB_BUFFER(0x2030 + (i)))
+#define HTU_RESULT(i) ((struct htu_result*) SB_BUFFER(0x2050 + (i)))
+
+#if defined(ENABLE_ATM_RETX) && ENABLE_ATM_RETX
+
+ #define RETX_MODE_CFG ((volatile struct Retx_mode_cfg *) SB_BUFFER(0x2408))
+ #define RETX_TSYNC_CFG ((volatile struct Retx_Tsync_cfg *) SB_BUFFER(0x2409))
+ #define RETX_TD_CFG ((volatile struct Retx_Td_cfg *) SB_BUFFER(0x240A))
+ #define RETX_MIB_TIMER_CFG ((volatile struct Retx_MIB_Timer_cfg *) SB_BUFFER(0x240B))
+ #define RETX_PLAYOUT_BUFFER_BASE SB_BUFFER(0x240D)
+ #define RETX_SERVICE_HEADER_CFG SB_BUFFER(0x240E)
+ #define RETX_MASK_HEADER_CFG SB_BUFFER(0x240F)
+
+ #define RETX_ADSL_PPE_INTF ((volatile struct Retx_adsl_ppe_intf *) PPE_REG_ADDR(0x0D78))
+ #define BAD_REC_RETX_ADSL_PPE_INTF ((volatile struct Retx_adsl_ppe_intf *) SB_BUFFER(0x23AC))
+ #define FIRST_BAD_REC_RETX_ADSL_PPE_INTF ((volatile struct Retx_adsl_ppe_intf *) SB_BUFFER(0x23AE))
+
+ #define PB_BUFFER_USAGE SB_BUFFER(0x2100)
+ #define DTU_STAT_INFO ((volatile struct DTU_stat_info *) SB_BUFFER(0x2180))
+ #define DTU_VLD_STAT SB_BUFFER(0x2380)
+
+
+ //=====================================================================
+ // retx firmware mib, for debug purpose
+ // address : 0x2388 - 0x238F
+ // size : 8
+ //=====================================================================
+ #define URETX_RX_TOTAL_DTU SB_BUFFER(0x2388)
+ #define URETX_RX_BAD_DTU SB_BUFFER(0x2389)
+ #define URETX_RX_GOOD_DTU SB_BUFFER(0x238A)
+ #define URETX_RX_CORRECTED_DTU SB_BUFFER(0x238B)
+ #define URETX_RX_OUTOFDATE_DTU SB_BUFFER(0x238C)
+ #define URETX_RX_DUPLICATE_DTU SB_BUFFER(0x238D)
+ #define URETX_RX_TIMEOUT_DTU SB_BUFFER(0x238E)
+
+ #define URETX_ALPHA_SWITCH_TO_HUNT_TIMES SB_BUFFER(0x238F)
+
+ // cell counter for debug purpose
+ #define WRX_BC0_CELL_NUM SB_BUFFER(0x23E0)
+ #define WRX_BC0_DROP_CELL_NUM SB_BUFFER(0x23E1)
+ #define WRX_BC0_NONRETX_CELL_NUM SB_BUFFER(0x23E2)
+ #define WRX_BC0_RETX_CELL_NUM SB_BUFFER(0x23E3)
+ #define WRX_BC0_OUTOFDATE_CELL_NUM SB_BUFFER(0x23E4)
+ #define WRX_BC0_DIRECTUP_NUM SB_BUFFER(0x23E5)
+ #define WRX_BC0_PBW_TOTAL_NUM SB_BUFFER(0x23E6)
+ #define WRX_BC0_PBW_SUCC_NUM SB_BUFFER(0x23E7)
+ #define WRX_BC0_PBW_FAIL_NUM SB_BUFFER(0x23E8)
+ #define WRX_BC1_CELL_NUM SB_BUFFER(0x23E9)
+
+ // debug info (interface)
+
+ #define DBG_DTU_INTF_WRPTR SB_BUFFER(0x2390)
+ #define DBG_INTF_FCW_DUP_CNT SB_BUFFER(0x2391)
+ #define DBG_INTF_SID_CHANGE_IN_DTU_CNT SB_BUFFER(0x2392)
+ #define DBG_INTF_LCW_DUP_CNT SB_BUFFER(0x2393)
+
+ #define DBG_RFBI_DONE_INT_CNT SB_BUFFER(0x2394)
+ #define DBG_DREG_BEG_END SB_BUFFER(0x2395)
+ #define DBG_RFBI_BC0_INVALID_CNT SB_BUFFER(0x2396)
+ #define DBG_RFBI_LAST_T SB_BUFFER(0x2397)
+
+ #define DBG_RFBI_INTV0 SB_BUFFER(0x23EE)
+ #define DBG_RFBI_INTV1 SB_BUFFER(0x23EF)
+
+ #define DBG_INTF_INFO(i) ((volatile struct Retx_adsl_ppe_intf_rec *) SB_BUFFER(0x23F0 + i))
+
+ // Internal status
+ #define URetx_curr_time SB_BUFFER(0x2398)
+ #define URetx_sec_counter SB_BUFFER(0x2399)
+ #define RxCURR_EFB SB_BUFFER(0x239A)
+ #define RxDTURetransmittedCNT SB_BUFFER(0x239B)
+
+ //=====================================================================
+ // standardized MIB counter
+ // address : 0x239C - 0x239F
+ // size : 4
+ //=====================================================================
+ #define RxLastEFBCNT SB_BUFFER(0x239C)
+ #define RxDTUCorrectedCNT SB_BUFFER(0x239D)
+ #define RxDTUCorruptedCNT SB_BUFFER(0x239E)
+ #define RxRetxDTUUncorrectedCNT SB_BUFFER(0x239F)
+
+
+ //=====================================================================
+ // General URetx Context
+ // address : 0x23A0 - 0x23AF
+ // size : 16
+ //=====================================================================
+ #define NEXT_DTU_SID_OUT SB_BUFFER(0x23A0)
+ #define LAST_DTU_SID_IN SB_BUFFER(0x23A1)
+ #define NEXT_CELL_SID_OUT SB_BUFFER(0x23A2)
+ #define ISR_CELL_ID SB_BUFFER(0x23A3)
+ #define PB_CELL_SEARCH_IDX SB_BUFFER(0x23A4)
+ #define PB_READ_PEND_FLAG SB_BUFFER(0x23A5)
+ #define RFBI_FIRST_CW SB_BUFFER(0x23A6)
+ #define RFBI_BAD_CW SB_BUFFER(0x23A7)
+ #define RFBI_INVALID_CW SB_BUFFER(0x23A8)
+ #define RFBI_RETX_CW SB_BUFFER(0x23A9)
+ #define RFBI_CHK_DTU_STATUS SB_BUFFER(0x23AA)
+
+ //=====================================================================
+ // per PVC counter for RX error_pdu and correct_pdu
+ // address : 0x23B0 - 0x23CF
+ // size : 32
+ //=====================================================================
+ #define WRX_PER_PVC_CORRECT_PDU_BASE SB_BUFFER(0x23B0)
+ #define WRX_PER_PVC_ERROR_PDU_BASE SB_BUFFER(0x23C0)
+
+ #define __WRXCTXT_L2_RdPtr(i) SB_BUFFER(0x2422 + (i))
+ #define __WRXCTXT_L2Pages(i) SB_BUFFER(0x2424 + (i))
+
+ #define __WTXCTXT_TC_WRPTR(i) SB_BUFFER(0x2450 + (i))
+ #define __WRXCTXT_PortState(i) SB_BUFFER(0x242A + (i))
+
+#endif
+
+
+
+#endif // IFXMIPS_ATM_FW_REGS_AR9_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_common.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_common.h
new file mode 100644
index 0000000000..49be99e12a
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_common.h
@@ -0,0 +1,549 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_fw_regs_common.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (Firmware Register Structures)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_ATM_FW_REGS_COMMON_H
+#define IFXMIPS_ATM_FW_REGS_COMMON_H
+
+
+#if defined(CONFIG_DANUBE)
+ #include "ifxmips_atm_fw_regs_danube.h"
+#elif defined(CONFIG_AMAZON_SE)
+ #include "ifxmips_atm_fw_regs_amazon_se.h"
+#elif defined(CONFIG_AR9)
+ #include "ifxmips_atm_fw_regs_ar9.h"
+#elif defined(CONFIG_VR9)
+ #include "ifxmips_atm_fw_regs_vr9.h"
+#else
+ #error Platform is not specified!
+#endif
+
+
+
+/*
+ * PPE ATM Cell Header
+ */
+#if defined(__BIG_ENDIAN)
+ struct uni_cell_header {
+ unsigned int gfc :4;
+ unsigned int vpi :8;
+ unsigned int vci :16;
+ unsigned int pti :3;
+ unsigned int clp :1;
+ };
+#else
+ struct uni_cell_header {
+ unsigned int clp :1;
+ unsigned int pti :3;
+ unsigned int vci :16;
+ unsigned int vpi :8;
+ unsigned int gfc :4;
+ };
+#endif // defined(__BIG_ENDIAN)
+
+/*
+ * Inband Header and Trailer
+ */
+#if defined(__BIG_ENDIAN)
+ struct rx_inband_trailer {
+ /* 0 - 3h */
+ unsigned int uu :8;
+ unsigned int cpi :8;
+ unsigned int stw_res1:4;
+ unsigned int stw_clp :1;
+ unsigned int stw_ec :1;
+ unsigned int stw_uu :1;
+ unsigned int stw_cpi :1;
+ unsigned int stw_ovz :1;
+ unsigned int stw_mfl :1;
+ unsigned int stw_usz :1;
+ unsigned int stw_crc :1;
+ unsigned int stw_il :1;
+ unsigned int stw_ra :1;
+ unsigned int stw_res2:2;
+ /* 4 - 7h */
+ unsigned int gfc :4;
+ unsigned int vpi :8;
+ unsigned int vci :16;
+ unsigned int pti :3;
+ unsigned int clp :1;
+ };
+
+ struct tx_inband_header {
+ /* 0 - 3h */
+ unsigned int gfc :4;
+ unsigned int vpi :8;
+ unsigned int vci :16;
+ unsigned int pti :3;
+ unsigned int clp :1;
+ /* 4 - 7h */
+ unsigned int uu :8;
+ unsigned int cpi :8;
+ unsigned int pad :8;
+ unsigned int res1 :8;
+ };
+#else
+ struct rx_inband_trailer {
+ /* 0 - 3h */
+ unsigned int stw_res2:2;
+ unsigned int stw_ra :1;
+ unsigned int stw_il :1;
+ unsigned int stw_crc :1;
+ unsigned int stw_usz :1;
+ unsigned int stw_mfl :1;
+ unsigned int stw_ovz :1;
+ unsigned int stw_cpi :1;
+ unsigned int stw_uu :1;
+ unsigned int stw_ec :1;
+ unsigned int stw_clp :1;
+ unsigned int stw_res1:4;
+ unsigned int cpi :8;
+ unsigned int uu :8;
+ /* 4 - 7h */
+ unsigned int clp :1;
+ unsigned int pti :3;
+ unsigned int vci :16;
+ unsigned int vpi :8;
+ unsigned int gfc :4;
+ };
+
+ struct tx_inband_header {
+ /* 0 - 3h */
+ unsigned int clp :1;
+ unsigned int pti :3;
+ unsigned int vci :16;
+ unsigned int vpi :8;
+ unsigned int gfc :4;
+ /* 4 - 7h */
+ unsigned int res1 :8;
+ unsigned int pad :8;
+ unsigned int cpi :8;
+ unsigned int uu :8;
+ };
+#endif // defined(__BIG_ENDIAN)
+
+/*
+ * MIB Table Maintained by Firmware
+ */
+struct wan_mib_table {
+ u32 res1;
+ u32 wrx_drophtu_cell;
+ u32 wrx_dropdes_pdu;
+ u32 wrx_correct_pdu;
+ u32 wrx_err_pdu;
+ u32 wrx_dropdes_cell;
+ u32 wrx_correct_cell;
+ u32 wrx_err_cell;
+ u32 wrx_total_byte;
+ u32 res2;
+ u32 wtx_total_pdu;
+ u32 wtx_total_cell;
+ u32 wtx_total_byte;
+};
+
+/*
+ * Host-PPE Communication Data Structure
+ */
+
+#if defined(__BIG_ENDIAN)
+ struct fw_ver_id {
+ unsigned int family :4;
+ unsigned int fwtype :4;
+ unsigned int interface :4;
+ unsigned int fwmode :4;
+ unsigned int major :8;
+ unsigned int minor :8;
+ };
+
+ struct wrx_queue_config {
+ /* 0h */
+ unsigned int res2 :27;
+ unsigned int dmach :4;
+ unsigned int errdp :1;
+ /* 1h */
+ unsigned int oversize :16;
+ unsigned int undersize :16;
+ /* 2h */
+ unsigned int res1 :16;
+ unsigned int mfs :16;
+ /* 3h */
+ unsigned int uumask :8;
+ unsigned int cpimask :8;
+ unsigned int uuexp :8;
+ unsigned int cpiexp :8;
+ };
+
+ struct wrx_queue_context {
+ /* 0h */
+ unsigned int curr_len :16;
+ unsigned int res0 :12;
+ unsigned int mfs :1;
+ unsigned int ec :1;
+ unsigned int clp1 :1;
+ unsigned int aal5dp :1;
+
+ /* 1h */
+ unsigned int intcrc;
+
+ /* 2h, 3h */
+ unsigned int curr_des0;
+ unsigned int curr_des1;
+
+ /* 4h - 0xE */
+ unsigned int res1[11];
+
+ unsigned int last_dword;
+ };
+
+ struct wtx_port_config {
+ unsigned int res1 :27;
+ unsigned int qid :4;
+ unsigned int qsben :1;
+ };
+
+ struct wtx_queue_config {
+ unsigned int res1 :16;
+ unsigned int same_vc_qmap:8;
+ unsigned int res2 :1;
+ unsigned int sbid :1;
+ unsigned int qsb_vcid :4; // Which QSB queue (VCID) does this TX queue map to.
+ unsigned int res3 :1;
+ unsigned int qsben :1;
+ };
+
+ struct wrx_desc_context {
+ unsigned int dmach_wrptr : 16;
+ unsigned int dmach_rdptr : 16;
+
+ unsigned int res0 : 16;
+ unsigned int dmach_fcnt : 16;
+
+ unsigned int res1 : 11;
+ unsigned int desbuf_wrptr : 5;
+ unsigned int res2 : 11;
+ unsigned int desbuf_rdptr : 5;
+
+ unsigned int res3 : 27;
+ unsigned int desbuf_vcnt : 5;
+ };
+
+ struct wrx_dma_channel_config {
+ /* 0h */
+ unsigned int res1 :1;
+ unsigned int mode :2;
+ unsigned int rlcfg :1;
+ unsigned int desba :28;
+ /* 1h */
+ unsigned int chrl :16;
+ unsigned int clp1th :16;
+ /* 2h */
+ unsigned int deslen :16;
+ unsigned int vlddes :16;
+ };
+
+ struct wtx_dma_channel_config {
+ /* 0h */
+ unsigned int res2 :1;
+ unsigned int mode :2;
+ unsigned int res3 :1;
+ unsigned int desba :28;
+ /* 1h */
+ unsigned int res1 :32;
+ /* 2h */
+ unsigned int deslen :16;
+ unsigned int vlddes :16;
+ };
+
+ struct htu_entry {
+ unsigned int res1 :1;
+ unsigned int clp :1;
+ unsigned int pid :2;
+ unsigned int vpi :8;
+ unsigned int vci :16;
+ unsigned int pti :3;
+ unsigned int vld :1;
+ };
+
+ struct htu_mask {
+ unsigned int set :1;
+ unsigned int clp :1;
+ unsigned int pid_mask :2;
+ unsigned int vpi_mask :8;
+ unsigned int vci_mask :16;
+ unsigned int pti_mask :3;
+ unsigned int clear :1;
+ };
+
+ struct htu_result {
+ unsigned int res1 :12;
+ unsigned int cellid :4;
+ unsigned int res2 :5;
+ unsigned int type :1;
+ unsigned int ven :1;
+ unsigned int res3 :5;
+ unsigned int qid :4;
+ };
+
+ struct rx_descriptor {
+ /* 0 - 3h */
+ unsigned int own :1;
+ unsigned int c :1;
+ unsigned int sop :1;
+ unsigned int eop :1;
+ unsigned int res1 :3;
+ unsigned int byteoff :2;
+ unsigned int res2 :2;
+ unsigned int id :4;
+ unsigned int err :1;
+ unsigned int datalen :16;
+ /* 4 - 7h */
+ unsigned int res3 :4;
+ unsigned int dataptr :28;
+ };
+
+ struct tx_descriptor {
+ /* 0 - 3h */
+ unsigned int own :1;
+ unsigned int c :1;
+ unsigned int sop :1;
+ unsigned int eop :1;
+ unsigned int byteoff :5;
+ unsigned int res1 :5;
+ unsigned int iscell :1;
+ unsigned int clp :1;
+ unsigned int datalen :16;
+ /* 4 - 7h */
+ unsigned int res2 :4;
+ unsigned int dataptr :28;
+ };
+#else
+ struct wrx_queue_config {
+ /* 0h */
+ unsigned int errdp :1;
+ unsigned int dmach :4;
+ unsigned int res2 :27;
+ /* 1h */
+ unsigned int undersize :16;
+ unsigned int oversize :16;
+ /* 2h */
+ unsigned int mfs :16;
+ unsigned int res1 :16;
+ /* 3h */
+ unsigned int cpiexp :8;
+ unsigned int uuexp :8;
+ unsigned int cpimask :8;
+ unsigned int uumask :8;
+ };
+
+ struct wtx_port_config {
+ unsigned int qsben :1;
+ unsigned int qid :4;
+ unsigned int res1 :27;
+ };
+
+ struct wtx_queue_config {
+ unsigned int qsben :1;
+ unsigned int res3 :1;
+ unsigned int qsb_vcid :4; // Which QSB queue (VCID) does this TX queue map to.
+ unsigned int sbid :1;
+ unsigned int res2 :1;
+ unsigned int same_vc_qmap:8;
+ unsigned int res1 :16;
+ };
+
+ struct wrx_dma_channel_config
+ {
+ /* 0h */
+ unsigned int desba :28;
+ unsigned int rlcfg :1;
+ unsigned int mode :2;
+ unsigned int res1 :1;
+ /* 1h */
+ unsigned int clp1th :16;
+ unsigned int chrl :16;
+ /* 2h */
+ unsigned int vlddes :16;
+ unsigned int deslen :16;
+ };
+
+ struct wtx_dma_channel_config {
+ /* 0h */
+ unsigned int desba :28;
+ unsigned int res3 :1;
+ unsigned int mode :2;
+ unsigned int res2 :1;
+ /* 1h */
+ unsigned int res1 :32;
+ /* 2h */
+ unsigned int vlddes :16;
+ unsigned int deslen :16;
+ };
+
+ struct rx_descriptor {
+ /* 4 - 7h */
+ unsigned int dataptr :28;
+ unsigned int res3 :4;
+ /* 0 - 3h */
+ unsigned int datalen :16;
+ unsigned int err :1;
+ unsigned int id :4;
+ unsigned int res2 :2;
+ unsigned int byteoff :2;
+ unsigned int res1 :3;
+ unsigned int eop :1;
+ unsigned int sop :1;
+ unsigned int c :1;
+ unsigned int own :1;
+ };
+
+ struct tx_descriptor {
+ /* 4 - 7h */
+ unsigned int dataptr :28;
+ unsigned int res2 :4;
+ /* 0 - 3h */
+ unsigned int datalen :16;
+ unsigned int clp :1;
+ unsigned int iscell :1;
+ unsigned int res1 :5;
+ unsigned int byteoff :5;
+ unsigned int eop :1;
+ unsigned int sop :1;
+ unsigned int c :1;
+ unsigned int own :1;
+ };
+#endif // defined(__BIG_ENDIAN)
+
+#if defined(ENABLE_ATM_RETX) && ENABLE_ATM_RETX
+ #if defined(__BIG_ENDIAN)
+
+ struct Retx_adsl_ppe_intf {
+ unsigned int res0_0 : 16;
+ unsigned int dtu_sid : 8;
+ unsigned int dtu_timestamp : 8;
+
+ unsigned int res1_0 : 16;
+ unsigned int local_time : 8;
+ unsigned int res1_1 : 5;
+ unsigned int is_last_cw : 1;
+ unsigned int reinit_flag : 1;
+ unsigned int is_bad_cw : 1;
+ };
+
+ struct Retx_adsl_ppe_intf_rec {
+
+ unsigned int local_time : 8;
+ unsigned int res1_1 : 5;
+ unsigned int is_last_cw : 1;
+ unsigned int reinit_flag : 1;
+ unsigned int is_bad_cw : 1;
+
+ unsigned int dtu_sid : 8;
+ unsigned int dtu_timestamp : 8;
+
+ };
+
+ struct Retx_mode_cfg {
+ unsigned int res0 :8;
+ unsigned int invld_range :8; // used for rejecting the too late arrival of the retransmitted DTU
+ unsigned int buff_size :8; // the total number of cells in playout buffer is 32 * buff_size
+ unsigned int res1 :7;
+ unsigned int retx_en :1;
+ };
+
+ struct Retx_Tsync_cfg {
+ unsigned int fw_alpha :16; // number of consecutive HEC error cell causes that the cell delineation state machine transit from SYNC to HUNT (0 means never)
+ unsigned int sync_inp :16; // reserved
+ };
+
+ struct Retx_Td_cfg {
+ unsigned int res0 :8;
+ unsigned int td_max :8; // maximum delay between the time a DTU is first created at transmitter and the time the DTU is sent out of ReTX layer at receiver
+ unsigned int res1 :8;
+ unsigned int td_min :8; // minimum delay between the time a DTU is first created at transmitter and the time the DTU is sent out of ReTX layer at receiver
+ };
+
+ struct Retx_MIB_Timer_cfg {
+ unsigned int ticks_per_sec : 16;
+ unsigned int tick_cycle : 16;
+ };
+
+ struct DTU_stat_info {
+ unsigned int complete : 1;
+ unsigned int bad : 1;
+ unsigned int res0_0 : 14;
+ unsigned int time_stamp : 8;
+ unsigned int cell_cnt : 8;
+
+ unsigned int dtu_rd_ptr : 16;
+ unsigned int dtu_wr_ptr : 16;
+ };
+
+ struct Retx_ctrl_field {
+ unsigned int res0 : 1;
+
+ unsigned int l2_drop : 1;
+ unsigned int res1 : 13;
+ unsigned int retx : 1;
+
+ unsigned int dtu_sid : 8;
+ unsigned int cell_sid : 8;
+ };
+
+ #else
+ #error Little Endian is not supported yet.
+ #endif
+
+ struct dsl_param {
+ unsigned int update_flag; // 00
+ unsigned int res0; // 04
+ unsigned int MinDelayrt; // 08
+ unsigned int MaxDelayrt; // 0C
+ unsigned int res1; // 10
+ unsigned int res2; // 14
+ unsigned int RetxEnable; // 18
+ unsigned int ServiceSpecificReTx; // 1C
+ unsigned int res3; // 20
+ unsigned int ReTxPVC; // 24
+ unsigned int res4; // 28
+ unsigned int res5; // 2C
+ unsigned int res6; // 30
+ unsigned int res7; // 34
+ unsigned int res8; // 38
+ unsigned int res9; // 3C
+ unsigned int res10; // 40
+ unsigned int res11; // 44
+ unsigned int res12; // 48
+ unsigned int res13; // 4C
+ unsigned int RxDtuCorruptedCNT; // 50
+ unsigned int RxRetxDtuUnCorrectedCNT;// 54
+ unsigned int RxLastEFB; // 58
+ unsigned int RxDtuCorrectedCNT; // 5C
+ };
+#endif
+
+
+
+#endif // IFXMIPS_ATM_FW_REGS_COMMON_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_danube.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_danube.h
new file mode 100644
index 0000000000..9bdefdb17c
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_danube.h
@@ -0,0 +1,51 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_fw_regs_danube.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (Firmware Registers)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_ATM_FW_REGS_DANUBE_H
+#define IFXMIPS_ATM_FW_REGS_DANUBE_H
+
+#define FW_VER_ID ((volatile struct fw_ver_id *) SB_BUFFER(0x2001))
+#define CFG_WRX_HTUTS SB_BUFFER(0x2400) /* WAN RX HTU Table Size, must be configured before enable PPE firmware. */
+#define CFG_WRX_QNUM SB_BUFFER(0x2401) /* WAN RX Queue Number */
+#define CFG_WRX_DCHNUM SB_BUFFER(0x2402) /* WAN RX DMA Channel Number, no more than 8, must be configured before enable PPE firmware. */
+#define CFG_WTX_DCHNUM SB_BUFFER(0x2403) /* WAN TX DMA Channel Number, no more than 16, must be configured before enable PPE firmware. */
+#define CFG_WRDES_DELAY SB_BUFFER(0x2404) /* WAN Descriptor Write Delay, must be configured before enable PPE firmware. */
+#define WRX_DMACH_ON SB_BUFFER(0x2405) /* WAN RX DMA Channel Enable, must be configured before enable PPE firmware. */
+#define WTX_DMACH_ON SB_BUFFER(0x2406) /* WAN TX DMA Channel Enable, must be configured before enable PPE firmware. */
+#define WRX_HUNT_BITTH SB_BUFFER(0x2407) /* WAN RX HUNT Threshold, must be between 2 to 8. */
+
+#define WRX_QUEUE_CONFIG(i) ((struct wrx_queue_config*) SB_BUFFER(0x2500 + (i) * 20))
+#define WRX_DMA_CHANNEL_CONFIG(i) ((struct wrx_dma_channel_config*) SB_BUFFER(0x2640 + (i) * 7))
+#define WTX_PORT_CONFIG(i) ((struct wtx_port_config*) SB_BUFFER(0x2440 + (i)))
+#define WTX_QUEUE_CONFIG(i) ((struct wtx_queue_config*) SB_BUFFER(0x2710 + (i) * 27))
+#define WTX_DMA_CHANNEL_CONFIG(i) ((struct wtx_dma_channel_config*) SB_BUFFER(0x2711 + (i) * 27))
+#define WAN_MIB_TABLE ((struct wan_mib_table*) SB_BUFFER(0x2410))
+#define HTU_ENTRY(i) ((struct htu_entry*) SB_BUFFER(0x2000 + (i)))
+#define HTU_MASK(i) ((struct htu_mask*) SB_BUFFER(0x2020 + (i)))
+#define HTU_RESULT(i) ((struct htu_result*) SB_BUFFER(0x2040 + (i)))
+
+#endif
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_vr9.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_vr9.h
new file mode 100644
index 0000000000..708d337629
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_regs_vr9.h
@@ -0,0 +1,72 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_fw_regs_vr9.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (Firmware Registers)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_ATM_FW_REGS_VR9_H
+#define IFXMIPS_ATM_FW_REGS_VR9_H
+
+#define FW_VER_ID ((volatile struct fw_ver_id *) SB_BUFFER(0x2001))
+
+/* WAN RX HTU Table Size, must be configured before enable PPE firmware. */
+#define CFG_WRX_HTUTS SB_BUFFER(0x2010)
+/* WAN RX Queue Number */
+#define CFG_WRX_QNUM SB_BUFFER(0x2011)
+/* WAN RX DMA Channel Number, no more than 8, must be configured before enable PPE firmware. */
+#define CFG_WRX_DCHNUM SB_BUFFER(0x2012)
+/* WAN TX DMA Channel Number, no more than 16, must be configured before enable PPE firmware. */
+#define CFG_WTX_DCHNUM SB_BUFFER(0x2013)
+/* WAN Descriptor Write Delay, must be configured before enable PPE firmware. */
+#define CFG_WRDES_DELAY SB_BUFFER(0x2014)
+/* WAN RX DMA Channel Enable, must be configured before enable PPE firmware. */
+#define WRX_DMACH_ON SB_BUFFER(0x2015)
+/* WAN TX DMA Channel Enable, must be configured before enable PPE firmware. */
+#define WTX_DMACH_ON SB_BUFFER(0x2016)
+/* WAN RX HUNT Threshold, must be between 2 to 8. */
+#define WRX_HUNT_BITTH SB_BUFFER(0x2017)
+/* i < 16 */
+#define WRX_QUEUE_CONFIG(i) ((struct wrx_queue_config *) SB_BUFFER(0x4C00 + (i) * 20))
+/* i < 8 */
+#define WRX_DMA_CHANNEL_CONFIG(i) ((struct wrx_dma_channel_config *) SB_BUFFER(0x4F80 + (i) * 7))
+/* i < 2 */
+#define WTX_PORT_CONFIG(i) ((struct wtx_port_config *) SB_BUFFER(0x4FB8 + (i)))
+/* i < 16 */
+#define WTX_QUEUE_CONFIG(i) ((struct wtx_queue_config *) SB_BUFFER(0x3A00 + (i) * 27))
+/* i < 16 */
+#define WTX_DMA_CHANNEL_CONFIG(i) ((struct wtx_dma_channel_config *) SB_BUFFER(0x3A01 + (i) * 27))
+
+#define WAN_MIB_TABLE ((struct wan_mib_table *) SB_BUFFER(0x4EF0))
+/* i < 32 */
+#define HTU_ENTRY(i) ((struct htu_entry *) SB_BUFFER(0x26A0 + (i)))
+/* i < 32 */
+#define HTU_MASK(i) ((struct htu_mask *) SB_BUFFER(0x26C0 + (i)))
+/* i < 32 */
+#define HTU_RESULT(i) ((struct htu_result *) SB_BUFFER(0x26E0 + (i)))
+/* bit 0~3 - 0x0F: in showtime, 0x00: not in showtime */
+#define UTP_CFG SB_BUFFER(0x2018)
+
+
+
+#endif // IFXMIPS_ATM_FW_REGS_VR9_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_vr9.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_vr9.h
new file mode 100644
index 0000000000..42a26ec539
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_fw_vr9.h
@@ -0,0 +1,427 @@
+#ifndef IFXMIPS_ATM_FW_VR9_H
+#define IFXMIPS_ATM_FW_VR9_H
+
+
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_fw_vr9.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 22 OCT 2007
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (PP32 Firmware)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 22 OCT 2007 Xu Liang Initial Version, v00.01
+*******************************************************************************/
+
+
+#define VER_IN_FIRMWARE 1
+
+#define ATM_FW_VER_MAJOR 0
+#define ATM_FW_VER_MINOR 24
+
+
+static u32 vr9_fw_bin[] = {
+ 0x800004B8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000FFE0, 0x00000000, 0x00000000, 0x00000000,
+ 0xC1000002, 0xD90C00F8, 0xC2000002, 0xDA0800F9, 0x80004390, 0xC2000000, 0xDA0800F9, 0x80003A10,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x800039C8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80004B60, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x800038C8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0400000, 0xC000ABC0, 0xC88400F8, 0x80004050, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0400002, 0xC000ABC0, 0xC88400F8, 0x80003FD0, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC3C00004, 0xDBC800F9, 0xC10C0002, 0xD90C00F8, 0x8000FEE0, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC10E0002, 0xD90C00F8, 0xC0004028, 0xC84000F8, 0x80004000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC3E1FFFE, 0x597DFFFE, 0x593DFE14, 0x900004D9, 0x00000000, 0x00000000, 0x00000000, 0x90CC0481,
+ 0x00000000, 0x00000000, 0x00000000, 0xC3C00000, 0xDBC800F9, 0xC1400008, 0xC1900000, 0x71588000,
+ 0x14100100, 0xC140000A, 0xC1900002, 0x71588000, 0x14100100, 0xC140000C, 0xC1900004, 0x71588000,
+ 0x14100100, 0xC1400004, 0xC1900006, 0x71588000, 0x14100100, 0xC1400006, 0xC1900008, 0x71588000,
+ 0x14100100, 0xC140000E, 0xC190000A, 0x71588000, 0x14100100, 0xC1400000, 0xC190000C, 0x71588000,
+ 0x14100100, 0xC1400002, 0xC190000E, 0x71588000, 0x14100100, 0xC0400000, 0xC11C0000, 0xC000E82C,
+ 0xCD05CE00, 0xC11C0002, 0xC000E82C, 0xCD05CE00, 0xC0400002, 0xC11C0000, 0xC000E82C, 0xCD05CE00,
+ 0xC11C0002, 0xC000E82C, 0xCD05CE00, 0xC000E824, 0x00000000, 0xCBC000F9, 0xCB8000F9, 0xCB4000F9,
+ 0xCB0000F8, 0xC000ABE4, 0x5BFC4000, 0xCFC000F9, 0x5BB84000, 0xCF8000F9, 0x5B744000, 0xCF4000F9,
+ 0x5B304000, 0xCF0000F8, 0xC000EA10, 0x00000000, 0xCBC000F9, 0xCB8000F8, 0xC000ABE0, 0x5BFC4000,
+ 0xCFC000F9, 0x5BB84000, 0xCF8000F8, 0xC30001FE, 0xC000F416, 0xCF0000F8, 0xC3000000, 0x7F018000,
+ 0xC000E42E, 0xCF0000F8, 0xC000E40E, 0xCF0000F8, 0xC3C1FFFE, 0xC000690E, 0xCFC00078, 0xC000692C,
+ 0xCFC00078, 0xC0006924, 0xCFC00038, 0xC0006912, 0xCFC00038, 0xC0006966, 0xCFC00038, 0xC0006968,
+ 0xCFC00078, 0xC000696A, 0xCFC00078, 0xC3C00000, 0xC2800020, 0xC3000000, 0x7F018000, 0x6FF88000,
+ 0x6FD44000, 0x4395C000, 0x5BB89800, 0x5838000A, 0xCF0000F8, 0x5BFC0002, 0xB7E8FFC8, 0x00000000,
+ 0xC3C00000, 0xC2800010, 0x6FF86000, 0x47BDC000, 0x5BB89F00, 0xC3400000, 0x58380004, 0xCB420078,
+ 0x00000000, 0x58380008, 0xCF400078, 0x5BFC0002, 0xB7E8FFB0, 0x00000000, 0xC3C00000, 0xC2800020,
+ 0xC348001E, 0xC3000000, 0x7F018000, 0x6FF8A000, 0x6FD44000, 0x4795C000, 0x47BDC000, 0x5BB87400,
+ 0x58380008, 0xCF408418, 0x5838000A, 0xCF0000F8, 0x5BFC0002, 0xB7E8FFB0, 0x00000000, 0x00000000,
+ 0xC3E0E282, 0x5BFC0030, 0xC0004002, 0xCFC000F8, 0xC000E82C, 0xC11E0002, 0xCD01EF00, 0xC000E82E,
+ 0xCD01EF00, 0x00000000, 0xC121FFFE, 0x5911FE94, 0x14100000, 0x80000028, 0x00000000, 0x80001CB8,
+ 0x00000000, 0x8000FFE0, 0xC0006918, 0xD28000F8, 0xC2000000, 0xDF600038, 0x5E600020, 0x84000272,
+ 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0xC000402A, 0xCA0000F8, 0xC0006912,
+ 0xCA4000F8, 0xC0006924, 0xCA8000F8, 0xC0006966, 0xCAC000F8, 0x00000000, 0xC121FFFE, 0x5911FE94,
+ 0x14100000, 0x76250000, 0x76290000, 0x762D0000, 0x840001CA, 0xC0006918, 0xCA4000F8, 0xC28001FE,
+ 0x76290000, 0x5A640002, 0x6A254010, 0x5EE80000, 0x8400001A, 0x6AA54000, 0x80000010, 0xC62800F8,
+ 0x62818008, 0xC0006918, 0xCF0000F8, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0xC0006966,
+ 0xCA4000F8, 0xC2000002, 0x6A310000, 0x7E010000, 0x76612000, 0xCE4000F8, 0x00000000, 0xC121FFFE,
+ 0x5911FE94, 0x14100000, 0x6F346000, 0x4771A000, 0x5B749F00, 0xC2800000, 0x58340006, 0xCA800078,
+ 0xC2C00000, 0x58340000, 0xCAC000D8, 0xC2400000, 0x5834000A, 0xCA420078, 0x6EA82000, 0x42E9E000,
+ 0x6F2CA000, 0x42E56000, 0x5AEC3200, 0xC3990040, 0xC7381C18, 0xC6F80060, 0x99005560, 0xDB9800F8,
+ 0xDBD800F9, 0x00000000, 0xDEA000F8, 0x46310000, 0x8400FD80, 0xC0006958, 0xC84000F8, 0x00000000,
+ 0xC3C00002, 0x787C2000, 0xCC4000F8, 0xC000ABC8, 0xCB8400F8, 0xC000ABC4, 0xC88400F8, 0x5FB80000,
+ 0x8400FCFA, 0xC000FAC0, 0xCA0400F8, 0x00000000, 0x00000000, 0xA6040070, 0xC000ABE4, 0xC80400F8,
+ 0x6C908000, 0x45088000, 0x45088000, 0x40100000, 0xCA0000F8, 0xC42400F8, 0x00000000, 0x98C05CD8,
+ 0xC000697C, 0xCA0000F8, 0x59640004, 0xC0004030, 0xCA0000F8, 0xC2400002, 0x6A452000, 0x76250000,
+ 0x8400FC3A, 0xC000ABE8, 0xC80400F8, 0x00000000, 0x00000000, 0x40080000, 0xCA0000F8, 0xC42400F8,
+ 0x00000000, 0xA63C17DA, 0x00000000, 0xC000ABE4, 0xC80400F8, 0x6C908000, 0x45088000, 0x45088000,
+ 0x40100000, 0xCA0000F8, 0xC42400F8, 0x00000000, 0xC0006934, 0xCE0000F8, 0xC2800002, 0xC4681C08,
+ 0xC62821D0, 0xC2600010, 0x5A650D80, 0xC0004020, 0xCB4000F8, 0xC2200400, 0x5A200D40, 0xC7601040,
+ 0xC000F220, 0xCE8000F8, 0xC000F200, 0xCE4000F8, 0xC000F202, 0xCE0000F8, 0xC000F240, 0xCB4000F8,
+ 0x00000000, 0x00000000, 0xA754FFE0, 0xC2000000, 0xC7600040, 0xA7520042, 0x00000000, 0x00000000,
+ 0x99005FD8, 0xC0009DE2, 0xC94000F8, 0xC1800002, 0x80001680, 0x58204DC0, 0xC2000000, 0xCA000018,
+ 0xC2400000, 0xCA414000, 0xC2800000, 0xCA812000, 0xC2C00000, 0xCAC20018, 0xC0006938, 0xCE0000F8,
+ 0xC0006920, 0xCE4000F8, 0xC0006916, 0xCE8000F8, 0xC0006922, 0xCEC000F8, 0xA6400540, 0x00000000,
+ 0xC0006938, 0xCBC000F8, 0x00000000, 0xC3800000, 0x6FF48000, 0x6FD44000, 0x4355A000, 0x5B749800,
+ 0x58340000, 0xCB802010, 0x00000000, 0xC2000000, 0x6FB46000, 0x4779A000, 0x5B749F00, 0x5834000C,
+ 0xCA000020, 0xC000691A, 0xCF8000F8, 0x5E200000, 0x8400046A, 0xC2000000, 0xDF610048, 0x5E6001E8,
+ 0x8800FFE8, 0xC2000002, 0xC2400466, 0xC2A00000, 0x5AA80000, 0xC000F006, 0xCE0000F8, 0xC000F008,
+ 0xCE4000F8, 0xC000F00A, 0xCE8000F8, 0x99004FA0, 0xC1A0FFFE, 0xC000E824, 0xC9840070, 0xC0006934,
+ 0xCA4000F8, 0xC2000000, 0xC2800002, 0x99004FE0, 0xDA9800F8, 0xC61400F8, 0xC65800F8, 0xC161FFFE,
+ 0x5955FFFE, 0x14140000, 0x00000000, 0x990050C8, 0xC000691A, 0xC94000F8, 0x00000000, 0x00000000,
+ 0xC121FFFE, 0x5911FE94, 0x14100000, 0xC0006922, 0xCA001118, 0xC3C00000, 0xC3800000, 0xC0006930,
+ 0xCE023118, 0xC0006932, 0xCBC000D8, 0xC2800000, 0xC000691E, 0xCFC000F8, 0xC000ABDE, 0xCA800060,
+ 0xC3A0001A, 0x5BB94000, 0xC6B80060, 0xC000691C, 0xCF8000F8, 0x99005338, 0xC000691C, 0xC1400000,
+ 0xC9420048, 0x00000000, 0x00000000, 0x00000000, 0xA8E2FFE8, 0xC2000000, 0xC1220002, 0xD90C00F8,
+ 0xDF600038, 0x5E600020, 0x8400FFF2, 0xC000691C, 0xCA0000F8, 0xC000691E, 0xCA4000F8, 0x00000000,
+ 0x00000000, 0x99005560, 0xDA1800F8, 0xDA5800F9, 0x00000000, 0xC2000000, 0xDF610048, 0x5E6001FE,
+ 0x8800FFE8, 0xC0006916, 0xCA8000F8, 0xC2C00000, 0xDFEC0048, 0xC2400000, 0x466D2000, 0x8400004A,
+ 0x5EA80000, 0x8400003A, 0xC2600002, 0x99005FD8, 0xC0009DEE, 0xC94000F8, 0xC1800002, 0x80000030,
+ 0xC2600000, 0x99005FD8, 0xC0009DEC, 0xC94000F8, 0xC1800002, 0xC2000068, 0xC6240078, 0xC0006930,
+ 0xCE400080, 0xC000691A, 0xC98000F8, 0xC000ABDE, 0xC94000F8, 0x6D9C6000, 0x45D8E000, 0x59DC9F00,
+ 0x990053C0, 0xD95800F8, 0xD99800F9, 0xD9D400F8, 0x99005338, 0xC000691C, 0xC1400000, 0xC9420048,
+ 0xC2000000, 0xDF600038, 0x5E600020, 0x8400FFEA, 0x00000000, 0xC000691C, 0xCA0000F8, 0xC000691E,
+ 0xCA4000F8, 0x00000000, 0x00000000, 0x99005560, 0xDA1800F8, 0xDA5800F9, 0x00000000, 0x800010E8,
+ 0x00000000, 0x99005FD8, 0xC0009DEA, 0xC94000F8, 0xC1800002, 0x800010B8, 0xC0006938, 0xCBC000F8,
+ 0x00000000, 0x00000000, 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB89800, 0x58380008, 0xCA0000F8,
+ 0x00000000, 0x00000000, 0xA6000382, 0x00000000, 0xC0006938, 0xCBC000F8, 0xC3000000, 0x00000000,
+ 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB89800, 0x58380000, 0xCB002010, 0xC2000000, 0x58380008,
+ 0xCA020078, 0x5838000C, 0xCAC000F8, 0x5838000E, 0xCA4000F8, 0xC000691A, 0xCF0000F8, 0xC0006930,
+ 0xCEC000F8, 0xC000693C, 0xCE0000F8, 0xC0006932, 0xCE4000F8, 0x5E200000, 0x84000120, 0xC2800000,
+ 0xA6FE00BA, 0x6F206000, 0x46310000, 0x5A209F00, 0x5820000C, 0xCA800020, 0x00000000, 0x00000000,
+ 0x5EA80000, 0x840001F2, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x990050C8,
+ 0xC000691A, 0xC94000F8, 0x00000000, 0x00000000, 0xC121FFFE, 0x5911FE94, 0x14100000, 0xC0006930,
+ 0xCAC000F8, 0xC0006932, 0xCA4000F8, 0xC7EC1118, 0xC0006930, 0xCEC000F8, 0x5838000C, 0xCEC000F8,
+ 0x58000002, 0xCE4000F8, 0xC0006934, 0xCA0000F8, 0xC2400002, 0x6E642000, 0x6E642000, 0x76612000,
+ 0x8400002A, 0xC2400002, 0x6E684000, 0x58380008, 0xCE804200, 0xA6000020, 0x6E682000, 0x58380008,
+ 0xCE802100, 0xC2400002, 0x6E642000, 0x76612000, 0x840000EA, 0x58380008, 0xCA0000F8, 0xC2800000,
+ 0xC2400000, 0xA60200C0, 0xDBA800F8, 0x6F386000, 0x47B1C000, 0x5BB89F00, 0x58380004, 0xCA400078,
+ 0x58380002, 0xCA800078, 0x00000000, 0xDEB800F8, 0x46A54000, 0x88000060, 0x00000000, 0xC0009DE4,
+ 0xCA0000F8, 0xC2400002, 0x6E640000, 0x5A200002, 0xCE0000F8, 0x58380008, 0xCE400000, 0x80000018,
+ 0x00000000, 0x80000048, 0xC0006934, 0xCA0000F8, 0x00000000, 0x00000000, 0xA6020C6A, 0x00000000,
+ 0x00000000, 0x80000C98, 0xC2800000, 0xC2000080, 0xC240001A, 0xDF690048, 0x46294000, 0x46A54000,
+ 0x8800FFD2, 0xC2000006, 0xC2600982, 0x5A643B6E, 0x5838000A, 0xCA8000F8, 0xC000F006, 0xCE0000F8,
+ 0xC000F008, 0xCE4000F8, 0xC000F00A, 0xCE8000F8, 0x99004FA0, 0xC1A0FFFE, 0xC000E824, 0xC9840070,
+ 0xC2000000, 0xC0006930, 0xCA02E008, 0x58380026, 0xCA4000F8, 0x00000000, 0xC2800000, 0x99004FE0,
+ 0xDA9800F8, 0xC61400F8, 0xC65800F8, 0xC0006934, 0xCA0000F8, 0x00000000, 0x00000000, 0xA6020022,
+ 0x00000000, 0x00000000, 0x80000318, 0xC0006938, 0xCBC000F8, 0xC000ABE4, 0xC80400F8, 0x6C908000,
+ 0x45088000, 0x45088000, 0x40100000, 0xCA0000F8, 0xC42400F8, 0x00000000, 0x58240018, 0xCA0000F8,
+ 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB89800, 0xC3000000, 0xC3400002, 0xC2C00000, 0xC62C0078,
+ 0xC6270038, 0xC0006940, 0xCE400038, 0xC6260038, 0xC0006942, 0xCE400038, 0xC000693C, 0xCA0000F8,
+ 0x5EEC0000, 0x8400018A, 0x5A6C0010, 0x46254000, 0x88000190, 0x5A600052, 0x46E54000, 0x88000178,
+ 0x58380006, 0xCA8000F8, 0xC0006940, 0xCA0000F8, 0xC2400000, 0xC6A70038, 0x7E412000, 0x76612000,
+ 0xC2000000, 0xC6A10038, 0x46250000, 0x84000138, 0xC0006942, 0xCA0000F8, 0xC2400000, 0xC6A60038,
+ 0x7E412000, 0x76612000, 0xC2000000, 0xC6A00038, 0x58380002, 0xCA8000F8, 0x46250000, 0x840000E8,
+ 0xC2400000, 0xC6A60078, 0x466D0000, 0x880000DA, 0xC2400000, 0xC6A40078, 0x58380008, 0xCA8000F8,
+ 0x46E50000, 0x880000BA, 0x00000000, 0xA6820018, 0x00000000, 0xC7700B00, 0xA6840098, 0x00000000,
+ 0xC7700A00, 0x80000080, 0xC7700200, 0xC000693C, 0xCAC000F8, 0x80000060, 0xC7700300, 0xC000693C,
+ 0xCAC000F8, 0x80000040, 0xC7700900, 0x80000030, 0xC7700800, 0x80000020, 0xC7700700, 0x80000010,
+ 0xC7700500, 0xC0006944, 0xCF0000F8, 0xC000693E, 0xCEC000F8, 0xC0006938, 0xCA4000F8, 0xC000693C,
+ 0xCB8000F8, 0xC000693E, 0xCB4000F8, 0xC3000000, 0x6E608000, 0x6E544000, 0x42150000, 0x5A209800,
+ 0x5AA00008, 0x58200004, 0xCB000078, 0xC0006934, 0xCA0000F8, 0xC2400000, 0xC0006930, 0xCA42E008,
+ 0xC3C00018, 0xA6020098, 0x00000000, 0x43656000, 0x47AD0000, 0x88000050, 0x46F96000, 0x6EE04010,
+ 0x5BE00004, 0xC2000000, 0xC6E00008, 0x5E200000, 0x84000042, 0x5BFC0002, 0x80000030, 0xC3C00004,
+ 0x5A2C0008, 0x47A10000, 0x88000012, 0x5FB80008, 0x6FE04000, 0x42390000, 0x47212000, 0x88000068,
+ 0xC2400000, 0xC0006930, 0xCA42E008, 0xC2060002, 0xC68000F8, 0xCE006300, 0x6FE04000, 0x4721C000,
+ 0x5F700010, 0x4765A000, 0xC2000000, 0xC6340008, 0xC25A000A, 0xC000691A, 0xCA401C18, 0xC2800000,
+ 0xC0006932, 0xCA8000D8, 0xC000ABDE, 0xCA400060, 0x6FA04010, 0x42290000, 0xC000691E, 0xCE0000F8,
+ 0xC7E41048, 0xC000691C, 0xCE4000F8, 0x6FE04000, 0x43A1C000, 0xC000693C, 0xCF8000F8, 0xC000693E,
+ 0xCF4000F8, 0xC000693A, 0xCFC000F8, 0x80000008, 0x00000000, 0x00000000, 0x00000000, 0xC2000000,
+ 0xDCE000F8, 0xA622FFD8, 0xC1220002, 0xD90C00F8, 0xC0006938, 0xCBC000F8, 0xC0006944, 0xCB4000F8,
+ 0xC000ABDE, 0xCB0000F8, 0xC0006934, 0xCA0000F8, 0x6FF88000, 0x6FD44000, 0x4395C000, 0x5BB89800,
+ 0xA6020268, 0xC2400000, 0x58380008, 0xCA406000, 0xDFE800F8, 0xC2218E08, 0x5A21BAF6, 0x46A14000,
+ 0x84000022, 0xC2080002, 0x7361A000, 0x80000058, 0x5E640000, 0x84000022, 0xC20C0002, 0x7361A000,
+ 0x80000030, 0xC2000000, 0xC760E710, 0xC7604218, 0x5E200000, 0x84000272, 0xC2200002, 0xC0006930,
+ 0xCE021000, 0x99005FD8, 0xC0009DE8, 0xC94000F8, 0xC1800002, 0x58380000, 0xCA0000F8, 0x00000000,
+ 0x00000000, 0xA6000132, 0xC0006940, 0xCA8000F8, 0xC0006942, 0xCA4000F8, 0xC7600078, 0xC6A01838,
+ 0xC6601038, 0xC000693A, 0xCA4000F8, 0xC0006934, 0xCA8000F8, 0xC000AB40, 0x40300000, 0x40240000,
+ 0x5C000004, 0x5EC0ABC0, 0x88000012, 0x5C000080, 0xCE0000F8, 0x58000002, 0x5EC0ABC0, 0x88000012,
+ 0x5C000080, 0xCE8000F8, 0xC000693E, 0xCA0000F8, 0xC2400000, 0x5838000C, 0xCE4000F8, 0x99005FD8,
+ 0xC0009DF0, 0xC94000F8, 0xC61800F8, 0xC0006930, 0xC6100078, 0xCD000078, 0x800000A8, 0xC2400002,
+ 0x58380008, 0xCE400000, 0xC0006944, 0xCF4000F8, 0x80000278, 0xC000693C, 0xCA4000F8, 0xDFE800F8,
+ 0x5A300018, 0xC000AB40, 0x40200000, 0xCA0000F8, 0x58380008, 0xC6501078, 0xCD021078, 0x5838000A,
+ 0xCE8000F8, 0x58380026, 0xCE0000F8, 0xC0006944, 0xCF4000F8, 0x99005338, 0xC000691C, 0xC1400000,
+ 0xC9420048, 0x80000038, 0x00000000, 0x99005FD8, 0xC0009DE6, 0xC94000F8, 0xC1800002, 0x8000FDD8,
+ 0xC2000000, 0xC2400020, 0xDF600038, 0xB624FFEA, 0xC000691C, 0xCA4000F8, 0xC000691E, 0xCA8000F8,
+ 0x99005560, 0xDA5800F8, 0xDA9800F9, 0x00000000, 0xC0006934, 0xCA0000F8, 0x00000000, 0xC2800000,
+ 0xA6020160, 0xC2400004, 0xC2000080, 0xDF690048, 0x46294000, 0x46A54000, 0x8800FFDA, 0x00000000,
+ 0xC000691A, 0xC98000F8, 0xC000ABDE, 0xC94000F8, 0x6D9C6000, 0x45D8E000, 0x59DC9F00, 0x990053C0,
+ 0xD95800F8, 0xD99800F9, 0xD9D400F8, 0x99005338, 0xC000691C, 0xC1400000, 0xC9420048, 0xC2000000,
+ 0xC2400020, 0xDF600038, 0xB624FFEA, 0xC000691C, 0xCA4000F8, 0xC000691E, 0xCA8000F8, 0x99005560,
+ 0xDA5800F8, 0xDA9800F9, 0x00000000, 0x58380008, 0xCA4000F8, 0xC2000000, 0xCE000018, 0xC2A1FFFE,
+ 0x5AA9FFFE, 0xCE021078, 0x5838000A, 0xCE8000F8, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000,
+ 0xC000E838, 0xC2500002, 0xCE450800, 0xC000ABC8, 0xCB8400F8, 0xC2000000, 0xC000E82C, 0xCA040038,
+ 0x5FB80002, 0xC000ABC8, 0xCF8400F8, 0x58880002, 0xB6080018, 0x00000000, 0xC0800000, 0xC000ABC4,
+ 0xCC8400F8, 0x00000000, 0xC121FFFE, 0x5911FE94, 0x14100000, 0x8000E350, 0xC2000000, 0xDF600038,
+ 0x5E200020, 0x8400026A, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0xC000402C,
+ 0xCA0000F8, 0xC0006910, 0xCA4000F8, 0xC000692C, 0xCA8000F8, 0xC0006968, 0xCAC000F8, 0x00000000,
+ 0xC121FFFE, 0x5911FE94, 0x14100000, 0x76250000, 0x76290000, 0x76E16000, 0x840001C2, 0xC0006926,
+ 0xCA4000F8, 0xC201FFFE, 0x76E16000, 0x5A640002, 0x6AE50010, 0x5F200000, 0x8400001A, 0x6A250000,
+ 0x80000010, 0xC6E000F8, 0x62014008, 0xC0006926, 0xCE8000F8, 0xC161FFFE, 0x5955FFFE, 0x14140000,
+ 0x00000000, 0xC0006968, 0xCA4000F8, 0xC2000002, 0x6A290000, 0x7E010000, 0x76612000, 0xCE4000F8,
+ 0x00000000, 0xC121FFFE, 0x5911FE94, 0x14100000, 0x6EB4A000, 0x6E944000, 0x4755A000, 0x4769A000,
+ 0x5B747400, 0x58340002, 0xC2000000, 0xCA0000D8, 0x5834002E, 0xC2400000, 0xCA400078, 0x6EB0A000,
+ 0x6EBC4000, 0x473D8000, 0x47298000, 0x5B30342E, 0x5B300004, 0x6E642000, 0x4225E000, 0xC39A8024,
+ 0xC7380060, 0xC6B81C18, 0x99005560, 0xDB9800F8, 0xDBD800F9, 0x00000000, 0xC2000000, 0xDF600038,
+ 0x5E200020, 0x840002A2, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0xC000690E,
+ 0xCA0000F8, 0xC000692A, 0xCA4000F8, 0xC000696A, 0xCB0000F8, 0xC0006956, 0xCAC000F8, 0x00000000,
+ 0xC121FFFE, 0x5911FE94, 0x14100000, 0x77218000, 0x77258000, 0x84000202, 0xC201FFFE, 0x77218000,
+ 0x5AEC0002, 0x6B2D0010, 0x5EA00000, 0x8400001A, 0x6A2D0000, 0x80000010, 0xC72000F8, 0x62016008,
+ 0xC0006956, 0xCEC000F8, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0xC000696A, 0xCA4000F8,
+ 0xC2000002, 0x6A2D0000, 0x7E010000, 0x76612000, 0xCE4000F8, 0x00000000, 0xC121FFFE, 0x5911FE94,
+ 0x14100000, 0x6EF4A000, 0x6ED44000, 0x4755A000, 0x476DA000, 0x5B747400, 0x5834000E, 0xC2000000,
+ 0xCA0000D8, 0x58340008, 0xC2400000, 0xCA420078, 0x5834000C, 0xC2800000, 0xCA832010, 0x6E644010,
+ 0x42250000, 0x4229E000, 0xC39A8008, 0x58340008, 0xCB809018, 0x58340008, 0xC2800000, 0xCA810010,
+ 0x6EE0A000, 0x6EE44000, 0x46250000, 0x462D0000, 0x5A200008, 0x5A203408, 0x42290000, 0xC6380060,
+ 0xC6F81C18, 0x99005560, 0xDB9800F8, 0xDBD800F9, 0x00000000, 0xC000695A, 0xC84000F8, 0x00000000,
+ 0xC3C00002, 0x787C2000, 0xCC4000F8, 0xC0004030, 0xCA0000F8, 0xC2400008, 0x6A452000, 0x76250000,
+ 0x84000E02, 0xC000EA28, 0xC3800000, 0xCB840038, 0xC000EA14, 0xC3400000, 0xCB440038, 0xC0009F70,
+ 0xCB0400F8, 0xB7B4005A, 0x5804F802, 0xCAC000F8, 0xA7000060, 0x00000000, 0x00000000, 0xA6C8DD30,
+ 0xC2800000, 0xC6E80018, 0x80000070, 0x00000000, 0x00000000, 0x00000000, 0x8000DCF8, 0x00000000,
+ 0xC2800000, 0xC7282018, 0xC000690E, 0xCA4000F8, 0x6BE9E000, 0x00000000, 0x767D2000, 0x8400DCB0,
+ 0x6EA0A000, 0x6E944000, 0x46150000, 0x46290000, 0x5A207400, 0x5820000C, 0xCA0000F8, 0xC0006946,
+ 0xCE8000F8, 0xA6220368, 0x00000000, 0xC2200060, 0xC0006948, 0xCE000008, 0xCE021038, 0xC240000A,
+ 0xC000694A, 0xCE4000F8, 0xC2B60002, 0xC0006964, 0xCE837B00, 0x99005830, 0xC0009F74, 0xC88400F8,
+ 0x00000000, 0xC0006946, 0xCBC000F8, 0x00000000, 0x00000000, 0x6FF8A000, 0x6FD44000, 0x4795C000,
+ 0x47BDC000, 0x5BB87400, 0x990055F0, 0xDBD800F8, 0xDB9800F9, 0x00000000, 0x99005338, 0xC000691C,
+ 0xC1400000, 0xC9420048, 0xC000691C, 0x990057E8, 0xC94000F9, 0xC98000F8, 0x00000000, 0x99005560,
+ 0xD95800F8, 0xD99800F9, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0x99005228,
+ 0xDBD800F8, 0xDB9800F9, 0xC7D800F8, 0x00000000, 0xC121FFFE, 0x5911FE94, 0x14100000, 0x6FF8A000,
+ 0x6FD44000, 0x4795C000, 0x47BDC000, 0x5BB87400, 0x58380010, 0xCA0000F8, 0xC000ABE0, 0xC80400F8,
+ 0x6C908000, 0x45088000, 0x45088000, 0x40100000, 0xCA4000F8, 0xC43400F8, 0x00000000, 0xC74000F8,
+ 0xCE0000F8, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0xC000690E, 0xCA4000F8, 0xC2800002,
+ 0x6ABD4000, 0x72692000, 0xCE4000F8, 0x00000000, 0xC121FFFE, 0x5911FE94, 0x14100000, 0x99005FD8,
+ 0xC0009DF6, 0xC94000F8, 0xC1800002, 0x00000000, 0x00000000, 0x00000000, 0xA8E2FFE8, 0x00000000,
+ 0xC1220002, 0xD90C00F8, 0xC2000000, 0xC000EA14, 0xCA040038, 0xC000EA28, 0xC2500002, 0xCE450800,
+ 0x58880002, 0xB6080018, 0xC0009F74, 0xC0800000, 0xCC8400F8, 0x8000D900, 0xC0006946, 0xCBC000F8,
+ 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0xC000690E, 0xCA4000F8, 0xC2800002, 0x6ABD4000,
+ 0x72692000, 0xCE4000F8, 0x00000000, 0xC121FFFE, 0x5911FE94, 0x14100000, 0x6FF8A000, 0x6FD44000,
+ 0x4795C000, 0x47BDC000, 0x5BB87400, 0x58380008, 0xCA0000F8, 0x5838000C, 0xCA4000F8, 0xC3400000,
+ 0xC6340000, 0xC000694E, 0xCF4000F8, 0xC2800000, 0xC62A0078, 0xC3000000, 0xC6308018, 0x6F304000,
+ 0x43298000, 0xC000693C, 0xCF0000F8, 0xC2C00000, 0xC66C0078, 0xC0006950, 0xCEC000F8, 0xC2800000,
+ 0xC66AE020, 0xC0006954, 0xCE8000F8, 0x5F740000, 0x840001A0, 0x5E300028, 0x46E12000, 0x8400016A,
+ 0x46E12000, 0x88000132, 0x5E300018, 0x46E12000, 0x8800002A, 0x46E12000, 0x84000042, 0x00000000,
+ 0x800000C0, 0x00000000, 0x99005970, 0xDBD800F8, 0xDB9800F9, 0xC78000F8, 0xC3400002, 0xC000694E,
+ 0xCF4000F8, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000, 0xC000690E, 0xCA4000F8, 0xC2800002,
+ 0x6ABD4000, 0x7E814000, 0x76692000, 0xCE4000F8, 0x00000000, 0xC121FFFE, 0x5911FE94, 0x14100000,
+ 0xC2200060, 0xC0006948, 0xCE021038, 0xC2000000, 0xC000694C, 0xCE0000F8, 0x80000080, 0x00000000,
+ 0x99005970, 0xDBD800F8, 0xDB9800F9, 0xC78000F8, 0x99005B70, 0xDBD800F8, 0xDB9800F9, 0xC78000F8,
+ 0xC2200058, 0xC0006948, 0xCE021038, 0xC2000002, 0xC000694C, 0xCE0000F8, 0xC2000006, 0xC000F006,
+ 0xCE0000F8, 0x5838000A, 0xCA4000F8, 0xC2200982, 0x5A203B6E, 0xC000F008, 0xCE0000F8, 0xC000F00A,
+ 0xCE4000F8, 0xC0006954, 0xCA8000F8, 0xC200000C, 0xC000694A, 0xCE0000F8, 0xC0006948, 0xCE800008,
+ 0xC2B60000, 0xC0006964, 0xCE8000F8, 0x99005830, 0xC0009F74, 0xC88400F8, 0x00000000, 0xC0006946,
+ 0xCBC000F8, 0xC000694C, 0xCA0000F8, 0x6FF8A000, 0x6FD44000, 0x4795C000, 0x47BDC000, 0x5BB87400,
+ 0x5E200000, 0x840000FA, 0x00000000, 0x990055F0, 0xDBD800F8, 0xDB9800F9, 0x00000000, 0x99005338,
+ 0xC000691C, 0xC1400000, 0xC9420048, 0xC000691C, 0x990057E8, 0xC94000F9, 0xC98000F8, 0x00000000,
+ 0x99005560, 0xD95800F8, 0xD99800F9, 0x00000000, 0xC161FFFE, 0x5955FFFE, 0x14140000, 0x00000000,
+ 0x99005228, 0xDBD800F8, 0xDB9800F9, 0xC7D800F8, 0x00000000, 0xC121FFFE, 0x5911FE94, 0x14100000,
+ 0xC000693C, 0xCA8000F8, 0xC000694E, 0xCAC000F8, 0xC3000018, 0xC3400006, 0x5E200000, 0x8400002A,
+ 0xC2800000, 0xC2C00000, 0xC300001E, 0xC3400000, 0xC6AC1078, 0xC72C0418, 0xC76C0810, 0x58380010,
+ 0xCA8000F8, 0x58380008, 0xCEC000F8, 0xC6280100, 0xC000ABE0, 0xC80400F8, 0x6C908000, 0x45088000,
+ 0x45088000, 0x40100000, 0xCB0000F8, 0xC43400F8, 0x00000000, 0xC74000F8, 0xCE8000F8, 0xC0006952,
+ 0xCE8000F8, 0x00000000, 0x00000000, 0x00000000, 0xA8E2FFE8, 0x00000000, 0xC000694C, 0xCA0000F8,
+ 0xC0006950, 0xCAC000F8, 0x5E200000, 0x8400006A, 0xDFE800F8, 0x7E814000, 0x5834001A, 0xCE8000F8,
+ 0x99005FD8, 0xC0009DF4, 0xC94000F8, 0xC1800002, 0x99005FD8, 0xC0009DF8, 0xC94000F8, 0xC6D800F8,
+ 0xC1220002, 0xD90C00F8, 0x5E200000, 0x84000040, 0x5838002C, 0xCB0000F8, 0xDFE800F8, 0x00000000,
+ 0x58380014, 0xCF0000F8, 0x80000018, 0xC2A1FFFE, 0x5AA9FFFE, 0x5838000A, 0xCE8000F8, 0xC3000000,
+ 0xC000EA14, 0xCB040038, 0xC2D00002, 0xC000EA28, 0xCEC50800, 0xC000694E, 0xCA8000F8, 0x58880002,
+ 0xB4B00018, 0xC0009F74, 0xC0800000, 0xCC8400F8, 0x5EA80000, 0x84000152, 0x5E200000, 0x84000140,
+ 0xC000693C, 0xCA8000F8, 0x00000000, 0x00000000, 0x5AA80060, 0xCE8000F8, 0x99005970, 0xDBD800F8,
+ 0xDB9800F9, 0xC78000F8, 0x99005B70, 0xDBD800F8, 0xDB9800F9, 0xC78000F8, 0xC0006952, 0xCAC000F8,
+ 0x58380000, 0xCA8000F8, 0xC30C0002, 0xC7F00018, 0xA6800098, 0x00000000, 0x00000000, 0xC161FFFE,
+ 0x5955FFFE, 0x14140000, 0x00000000, 0xC000F800, 0xCA0000F8, 0x00000000, 0x00000000, 0xA60CFFEA,
+ 0xC6F00500, 0xC6B0C400, 0xCF0000F8, 0x00000000, 0xC121FFFE, 0x5911FE94, 0x14100000, 0x8000CFB0,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000CF48, 0xDCBC00F9, 0x5FFC0000, 0x84000052,
+ 0xC3800002, 0xDB8800F9, 0x5FFC0004, 0x8400C86A, 0xC3800000, 0xDB8800F9, 0xC3CE0002, 0xC000E800,
+ 0xCFC0E700, 0xC3E1FFFE, 0x597DFFFE, 0x593DFE14, 0x94000001, 0x00000000, 0x00000000, 0x00000000,
+ 0xC000ABE8, 0xC80400F8, 0x00000000, 0x00000000, 0x40080000, 0xCBC000F8, 0xC43800F8, 0x00000000,
+ 0xC000402E, 0xCA0000F8, 0xC000ABD8, 0xCB4400F8, 0x00000000, 0x00000000, 0x47610000, 0x880000B0,
+ 0x00000000, 0xA7C00048, 0xC000ABD4, 0xC1000002, 0xCD0400F8, 0xC11C0000, 0xC000E82C, 0xCD05CE00,
+ 0x800000D8, 0x00000000, 0xA7D20120, 0x00000000, 0xC7E14040, 0xC2400000, 0xC6246028, 0xC200006A,
+ 0x46250000, 0xC6240030, 0xC000E810, 0xCE440030, 0x8000FF70, 0xC2000000, 0xC000E808, 0xCA040010,
+ 0xC11C0000, 0xC000E82C, 0xCD05CE00, 0x5A200002, 0x5E600010, 0x84000010, 0xC2000000, 0xC000E808,
+ 0xCE040010, 0xC3400000, 0x80000010, 0x5B740002, 0xC000ABD8, 0xCF4400F8, 0x99004F78, 0xC000ABC8,
+ 0xC94400F8, 0xC1800000, 0xC11C0002, 0xC000E82C, 0xCD05CE00, 0x80000600, 0x5B740002, 0xC000ABD8,
+ 0xCF4400F8, 0xC78000F8, 0xC13C0002, 0xCD03DE00, 0xC000ABC8, 0xC94400F8, 0xC1800000, 0xC000E82C,
+ 0xC9840038, 0x59540002, 0xC000ABC8, 0xCD4400F8, 0x58880002, 0xB4980580, 0x00000000, 0xC0800000,
+ 0x80000568, 0xC000ABE8, 0xC80400F8, 0x00000000, 0x00000000, 0x40080000, 0xCBC000F8, 0xC42800F8,
+ 0x00000000, 0xA7C00130, 0xC000ABCC, 0xCA0400F8, 0xC2400000, 0xC000FAEC, 0xCA440018, 0x5A200002,
+ 0xC000ABCC, 0xCE0400F8, 0xB624008A, 0xC68000F8, 0xC13C0002, 0xCD03DE00, 0xC000ABC8, 0xC94400F8,
+ 0xC1800000, 0xC000E82C, 0xC9840038, 0x59540002, 0xC000ABC8, 0xCD4400F8, 0x58880002, 0xB4980470,
+ 0x00000000, 0xC0800000, 0x80000458, 0xC000ABD4, 0xC1000004, 0xCD0400F8, 0xC000E820, 0xC2000002,
+ 0xCE0400F8, 0xC2000000, 0xC000ABCC, 0xCE0400F8, 0xC000ABD8, 0xCE0400F8, 0x8000FF28, 0xC000ABD4,
+ 0xC1000000, 0xCD0400F8, 0xC11C0000, 0xC000E82C, 0xCD05CE00, 0x99004F78, 0xC000ABC8, 0xC94400F8,
+ 0xC1800000, 0xC1200000, 0xC000E818, 0xCD061000, 0xC11C0002, 0xC000E82C, 0xCD05CE00, 0xC2000000,
+ 0xC000ABCC, 0xCE0400F8, 0x80000358, 0xC000FAC0, 0xCB8400F8, 0xC000ABE8, 0xC80400F8, 0x00000000,
+ 0x00000000, 0x40080000, 0xCBC000F8, 0xC42800F8, 0x00000000, 0x00000000, 0xC68000F8, 0xC13C0000,
+ 0xCD03DE00, 0xA780024A, 0x00000000, 0x00000000, 0xA7C0020A, 0x00000000, 0xC000FB60, 0xC2060006,
+ 0xCE046308, 0xA7E801C2, 0x00000000, 0xC000ABD0, 0xCA0400F8, 0xC2400000, 0xC000FAEC, 0xCA448018,
+ 0x5A200002, 0xC000ABD0, 0xCE0400F8, 0xB62400AA, 0x00000000, 0xC68000F8, 0xC13C0002, 0xCD03DE00,
+ 0xC000FACC, 0xC2000002, 0xCE040000, 0xC000ABC8, 0xC94400F8, 0xC1800000, 0xC000E82C, 0xC9840038,
+ 0x59540002, 0xC000ABC8, 0xCD4400F8, 0x58880002, 0xB49801C8, 0x00000000, 0xC0800000, 0x800001B0,
+ 0xC000ABD4, 0xC1000000, 0xCD0400F8, 0xC11C0000, 0xC000E82C, 0xCD05CE00, 0x99004F78, 0xC000ABC8,
+ 0xC94400F8, 0xC1800000, 0xC2000000, 0xC000E820, 0xCE0400F8, 0xC1200000, 0xC000E818, 0xCD061000,
+ 0xC11C0002, 0xC000E82C, 0xCD05CE00, 0xC000ABD0, 0xCE0400F8, 0xC2000002, 0xC000FACC, 0xCE040008,
+ 0x800000E8, 0xC2000002, 0xC000ABD0, 0xCE0400F8, 0x8000FE88, 0xC2000000, 0xC000ABD0, 0xCE0400F8,
+ 0xA7E60032, 0x00000000, 0xC2000002, 0xC000FB60, 0xCE040000, 0x8000FE70, 0x00000000, 0xA7860052,
+ 0x00000000, 0xC68000F8, 0xC13C0002, 0xCD03DE00, 0xC2020002, 0xC7E2A540, 0xC000FB60, 0xCE0400F8,
+ 0x8000FE18, 0xC2040002, 0xC000FB60, 0xCE044200, 0x8000FDF8, 0xC2C80002, 0x6AC56000, 0xDACC00F8,
+ 0xC000ABD4, 0xCB4400F8, 0xC000ABC8, 0xCB8400F8, 0xC000E838, 0xC3C00000, 0xCBC40038, 0x5EF40004,
+ 0x84000022, 0xC3000000, 0xC000FACC, 0xCF042100, 0x47F98000, 0x8400002A, 0x47F98000, 0x88000030,
+ 0xC1006E8C, 0x8000BCB8, 0xC000ABC0, 0xCC8400F8, 0x8000F6C8, 0xC000FAC0, 0xCAC400F8, 0xC000ABD4,
+ 0xCB4400F8, 0xA6C0FBD2, 0x00000000, 0x5EF40000, 0x8400F722, 0x5EF40002, 0x8400F99A, 0x5EF40004,
+ 0x8400FB9A, 0xC1006CE8, 0x8000BC30, 0x00000000, 0xC0800000, 0xDF4B0038, 0xC0006900, 0xCB8000F8,
+ 0xC2000000, 0xC000690A, 0xA78000D0, 0xCBC000F8, 0xC1000000, 0xD90000F9, 0xC1000002, 0xD90C00F8,
+ 0x6FF46000, 0x477DA000, 0x5B749F00, 0xC2400000, 0x58340004, 0xCA400078, 0xC0006900, 0xCE000000,
+ 0x5A640002, 0x58340004, 0xC6500078, 0xCD000078, 0xC0006914, 0xCA4000F8, 0xC2000002, 0x6A3D0000,
+ 0x72612000, 0xCE4000F8, 0xC000E408, 0xCE0000F8, 0xA78200D8, 0xC0006908, 0xCBC000F8, 0xC1000000,
+ 0xD90000F9, 0xC1000002, 0xD90C00F8, 0x6FF4A000, 0x6FD44000, 0x4755A000, 0x477DA000, 0x5B747400,
+ 0xC2800000, 0x58340006, 0xCA800078, 0xC2000000, 0xC0006900, 0xCE002100, 0x5EA80002, 0x58340006,
+ 0xC6900078, 0xCD000078, 0x5A7C0020, 0xC2000002, 0x6A250000, 0xC000E408, 0xCE0000F8, 0xDCA800F9,
+ 0x5EA80000, 0x8400BAA0, 0x00000000, 0xA4800230, 0x00000000, 0xC3C00000, 0xC000F418, 0xCBC00018,
+ 0xC3400000, 0xC2400000, 0x6FF86000, 0x47BDC000, 0x5BB89F00, 0x58380008, 0xCB400078, 0x58380006,
+ 0xCA400078, 0x5F740002, 0x58380008, 0xC7500078, 0xCD000078, 0xC2000000, 0x58380004, 0xCA020078,
+ 0xC3000000, 0x5838000C, 0xCB000020, 0x5A640002, 0x46610000, 0x84000010, 0xC2400000, 0x58380006,
+ 0xC6500078, 0xCD000078, 0xC2000000, 0x5838000A, 0xCA020078, 0x5B300002, 0x5838000C, 0xC7100020,
+ 0xCD000020, 0xC2420020, 0x5A200004, 0x46252000, 0x84000010, 0xC2000000, 0x5838000A, 0xC6101078,
+ 0xCD021078, 0xC0006966, 0xCA4000F8, 0xC2000002, 0x6A3D0000, 0x72612000, 0xCE4000F8, 0x5F740000,
+ 0x84000040, 0xC0006912, 0xCA0000F8, 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x762D0000, 0xCE0000F8,
+ 0x5F300020, 0x84000040, 0xC0006924, 0xCA0000F8, 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x762D0000,
+ 0xCE0000F8, 0xA4820070, 0xC2400000, 0xC000F418, 0xCA408018, 0xC2000002, 0xC0006900, 0xCE000000,
+ 0xC000690A, 0xCE4000F8, 0xC1000000, 0xD90000F9, 0xD8400078, 0xC1000004, 0xD90000F9, 0xA4840270,
+ 0x00000000, 0xC3C00000, 0xC000F418, 0xCBC10018, 0xC2800000, 0xC2000000, 0x6FF8A000, 0x6FD44000,
+ 0x4795C000, 0x47BDC000, 0x5BB87400, 0x5838002E, 0xCA800078, 0x58380006, 0xCA020078, 0xC3400000,
+ 0x5838002E, 0xCB420078, 0x5AA80002, 0x46A10000, 0x84000010, 0xC2800000, 0x5838002E, 0xC6900078,
+ 0xCD000078, 0x5F740002, 0x5838002E, 0xC7501078, 0xCD021078, 0xC0006968, 0xCA4000F8, 0xC2000002,
+ 0x6A3D0000, 0x72612000, 0xCE4000F8, 0xC000692A, 0xCA8000F8, 0x5E740000, 0x84000040, 0xC0006910,
+ 0xCA0000F8, 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x762D0000, 0xCE0000F8, 0x6ABD4010, 0xA68000BA,
+ 0x00000000, 0x58380032, 0xCA0000F8, 0x58000002, 0xCA4000F8, 0x5838000C, 0x00000000, 0xCE0000F9,
+ 0xCE4000F8, 0xC000692A, 0xCA0000F8, 0xC2C00002, 0x6AFD6000, 0x722D0000, 0xCE0000F8, 0xC000692C,
+ 0xCA0000F8, 0xC2C00002, 0x6AFD6000, 0x722D0000, 0xCE0000F8, 0x80000040, 0xC000692C, 0xCA0000F8,
+ 0xC2C00002, 0x6AFD6000, 0x7EC16000, 0x762D0000, 0xCE0000F8, 0xA4880120, 0xC2C00000, 0xC000F418,
+ 0xCAC20018, 0xC000690E, 0xCA4000F8, 0xC2000002, 0x6A2D0000, 0x7E010000, 0x76612000, 0xCE4000F8,
+ 0xC000696A, 0xCA4000F8, 0xC2000002, 0x6A2D0000, 0x72612000, 0xCE4000F8, 0x6EF0A000, 0x6ED44000,
+ 0x47158000, 0x472D8000, 0x5B307400, 0x58300000, 0xCA0000F8, 0x00000000, 0xC2400002, 0x76612000,
+ 0x8400004A, 0xC24C0002, 0xC6E40018, 0xC624C400, 0x58300010, 0xCA400500, 0x00000000, 0xC000F800,
+ 0xCE4000F8, 0xA4860070, 0xC2400000, 0xC000F418, 0xCA418018, 0xC2020002, 0xC0006900, 0xCE002100,
+ 0xC0006908, 0xCE4000F8, 0xC1000000, 0xD90000F9, 0xD8400078, 0xC1000004, 0xD90000F9, 0xC000F414,
+ 0xCC8000F8, 0xC10E0002, 0xD90C00F8, 0x8000EDF0, 0xDFBC00F9, 0xC000696E, 0x99005C80, 0xC94000F8,
+ 0xC7D800F8, 0x00000000, 0xC57000F8, 0x5EF00020, 0x88000148, 0x6F346000, 0x4771A000, 0x5B749F00,
+ 0x58340008, 0xC2400000, 0xCA400078, 0x00000000, 0xC2000000, 0x5A640002, 0xCE400078, 0x58340004,
+ 0xCA000078, 0x00000000, 0x00000000, 0x5E200002, 0xCE000078, 0xC0006912, 0xCA8000F8, 0xC2400002,
+ 0x6A712000, 0x72A54000, 0xCE8000F8, 0x5E200000, 0x84000052, 0xC000402A, 0xCA0000F8, 0xC000E408,
+ 0xCA8000F8, 0x76250000, 0x00000000, 0x72A14000, 0xCE8000F8, 0x80000038, 0xC0006914, 0xCA0000F8,
+ 0x7E412000, 0x00000000, 0x76250000, 0xCE0000F8, 0x800000D0, 0x6EF4A000, 0x6ED44000, 0x4755A000,
+ 0x476DA000, 0x5B747400, 0x5834002E, 0xC2400000, 0xCA420078, 0x00000000, 0xC2000000, 0x5A640002,
+ 0xC6501078, 0xCD021078, 0x58340006, 0xCA000078, 0x00000000, 0x00000000, 0x5A200002, 0xCE000078,
+ 0xC0006910, 0xCA4000F8, 0xC2000002, 0x6A2D0000, 0x72612000, 0xCE4000F8, 0xC2000002, 0x6A310000,
+ 0xC000E42A, 0xCE0000F8, 0xC1040002, 0xD90C00F8, 0x00000000, 0x8000EB60, 0x00000000, 0xC4980928,
+ 0x9D000000, 0xC5580038, 0xC000E838, 0xCD8400F8, 0xC1440080, 0xC1C06B40, 0xC55C0F80, 0xC000F00E,
+ 0x9D000000, 0xCD8000F8, 0xC000F00C, 0xCDC000F8, 0xC000ABDE, 0xC9C000F8, 0x00000000, 0x00000000,
+ 0xD9D800F9, 0xC000AB40, 0x401C0000, 0x5DC0ABC0, 0x88000012, 0x5C000080, 0xCD8000F8, 0xC1F0000A,
+ 0x715CA000, 0xDD9800F8, 0xDD9C00F9, 0x41D8E000, 0xC5D40260, 0xC000F010, 0xCD4000F8, 0x6C9C8000,
+ 0x45C8E000, 0x45C8E000, 0x59DC0004, 0xC1601260, 0xC5D40260, 0x9D000000, 0xC000F012, 0xCD4000F8,
+ 0x00000000, 0x00000000, 0xD95800F8, 0x6D586000, 0x4594C000, 0x59989F00, 0xD99800F9, 0x5818000A,
+ 0xC1800000, 0xC9800078, 0xC0007200, 0x6D5CA000, 0x401C0000, 0x40180000, 0xC94000F8, 0x58000002,
+ 0x00000000, 0xC9C000F8, 0xC0006930, 0xCD4000F8, 0xC0006932, 0xCDC000F8, 0x59980004, 0xC1C20020,
+ 0xB59C0018, 0x00000000, 0xC1800000, 0xDD9C00F9, 0x581C000A, 0xCD800078, 0x581C000C, 0xC1800000,
+ 0xC9800020, 0xC1C00002, 0xDD9400F8, 0x69D4E000, 0x5D980002, 0xCD800020, 0xC0006924, 0xC98000F8,
+ 0x00000000, 0x9D000000, 0x00000000, 0x719CC000, 0xCD8000F8, 0xC000692A, 0xC94000F8, 0xC1C00002,
+ 0x69D8E000, 0x7DC0C000, 0x7558A000, 0xCD4000F8, 0xC000692C, 0xC94000F8, 0xDD8000F9, 0x58000032,
+ 0x755CA000, 0x84000090, 0xC94000F9, 0xC98000F8, 0xDD8000F9, 0x5800000C, 0x00000000, 0xCD4000F9,
+ 0xCD8000F8, 0xC000692C, 0xC94000F8, 0xC000692A, 0xC98000F8, 0x715CA000, 0xC000692C, 0xCD4000F8,
+ 0x719CC000, 0xC000692A, 0xCD8000F8, 0x9D000000, 0x00000000, 0x00000000, 0x00000000, 0xC000ABDE,
+ 0xC98000F8, 0x00000000, 0xC1C00080, 0x4194C000, 0x459CE000, 0x88000012, 0xC5D800F8, 0xC000ABDE,
+ 0xCD8000F8, 0xC000F406, 0xC98000F8, 0xC1C00002, 0x9D000000, 0xC5D80A00, 0xC5581048, 0xCD8000F8,
+ 0xC0006930, 0xC98000F8, 0xC0006932, 0xC9C000F8, 0xC140000E, 0xC5581C18, 0xDD9400F8, 0xC000AB40,
+ 0x40140000, 0x5D40ABC0, 0x88000012, 0x5C000080, 0xCD8000F8, 0x58000002, 0x5D40ABC0, 0x88000012,
+ 0x5C000080, 0xCDC000F8, 0xDD5400F8, 0xC1C00000, 0x58140006, 0xC9C20078, 0xC1800000, 0x58140000,
+ 0xC98000D8, 0x6DDC2000, 0xC000691E, 0x41D8E000, 0xCDC000F8, 0xDD9800F8, 0xC1C00022, 0xC5D80D70,
+ 0xDD9400F9, 0xC5581C18, 0xC000691C, 0xCD8000F8, 0xDD5400F8, 0xC1C00000, 0x58140006, 0xC9C20078,
+ 0xC1800000, 0x58140004, 0xC9820078, 0x00000000, 0x59DC0002, 0x45D8C000, 0x84000010, 0xC1C00000,
+ 0x9D000000, 0x58140006, 0xC5D81078, 0xCD821078, 0xC000ABDC, 0xC94000F8, 0xC1820020, 0xC1D00002,
+ 0x5814AB00, 0xD58000F8, 0x58000002, 0xD58000F9, 0x59540004, 0xB5580018, 0xC000ABDC, 0xC1400000,
+ 0xCD4000F8, 0xDD9800F9, 0x9D000000, 0xDD9400F8, 0xC000F402, 0xCDC10800, 0xC1C00000, 0xC1800080,
+ 0x5D980004, 0xDF5D0048, 0x459CA000, 0x8800FFF2, 0xDD8000F9, 0x5800000C, 0x00000000, 0xC94000F9,
+ 0xC98000F8, 0xC1C00002, 0xC5D43F00, 0xC5D81E00, 0xC000ABDE, 0xC9C000F8, 0x00000000, 0x00000000,
+ 0x581CAB40, 0x5DC0ABC0, 0x88000012, 0x5C000080, 0xCD4000F8, 0x58000002, 0x5DC0ABC0, 0x88000012,
+ 0x5C000080, 0xCD8000F8, 0xC000ABDE, 0xC9C000F8, 0x00000000, 0xC15004C0, 0xC5D40060, 0xDD9C00F8,
+ 0xC5D41C18, 0xC1C00000, 0xDD8000F9, 0x58000030, 0xC9C00078, 0xDD8000F9, 0x58000002, 0xC98000F8,
+ 0x6DDC2000, 0xC000691C, 0x41D8E000, 0xCD4000F9, 0xCDC000F8, 0xDD9400F9, 0xC1C00000, 0x58140030,
+ 0xC9C00078, 0xC1800000, 0x58140006, 0xC9820078, 0x00000000, 0x59DC0002, 0x45D8C000, 0x84000010,
+ 0xC1C00000, 0x9D000000, 0x58140030, 0xC5D80078, 0xCD800078, 0xC1C00000, 0xDF5C0038, 0x5DDC0020,
+ 0x8400FFEA, 0x00000000, 0x9D000000, 0x00000000, 0x00000000, 0x00000000, 0xC160FFFE, 0xC000EA10,
+ 0xC9440070, 0xC1A0FFFE, 0x59983408, 0xC000F00C, 0xCD4000F8, 0xC000F00E, 0xCD8000F8, 0xC0006964,
+ 0xC98000F8, 0x00000000, 0xC170000A, 0x7158A000, 0x6C988000, 0x4588C000, 0x4588C000, 0x59980004,
+ 0xC5940270, 0xC000F010, 0xCD4000F8, 0xC0006946, 0xC94000F8, 0x00000000, 0x00000000, 0x6D58A000,
+ 0x6D5C4000, 0x459CC000, 0x4594C000, 0xC000694A, 0xC94000F8, 0xC0006948, 0xC9C000F8, 0x4194C000,
+ 0xC1400012, 0xC55C1818, 0x9D000000, 0xC59C0268, 0xC000F012, 0xCDC000F8, 0xC1400000, 0x58000012,
+ 0xC9410038, 0xC0006950, 0xC9C000F8, 0xC55800F8, 0xC5940838, 0xC5581078, 0xD99400F8, 0xC000693C,
+ 0xC94000F8, 0xC0006954, 0xC98000F8, 0x59DC00A8, 0x45D4E000, 0x41D8E000, 0x5D5C0030, 0x88000010,
+ 0xC1C00030, 0xC1800000, 0xC5D84028, 0xC1400000, 0xC5D40008, 0x5DD40002, 0x84000072, 0x5DD40004,
+ 0x8400009A, 0x5DD40006, 0x840000C2, 0x5DD80026, 0x840000EA, 0xDD5400F8, 0xDD8000F9, 0x58000008,
+ 0x40180000, 0xCD4000F8, 0x59980002, 0x8000FFC0, 0xDD5400F8, 0xDD8000F9, 0x58000008, 0x40180000,
+ 0xCD4000B8, 0x59980002, 0x8000FF88, 0xDD5400F8, 0xDD8000F9, 0x58000008, 0x40180000, 0xCD400078,
+ 0x59980002, 0x8000FF50, 0xDD5400F8, 0xDD8000F9, 0x58000008, 0x40180000, 0xCD400038, 0x59980002,
+ 0x8000FF18, 0x00000000, 0x9D000000, 0x00000000, 0x00000000, 0x00000000, 0x58000012, 0xC94000F8,
+ 0xC0006954, 0xC9C000F8, 0xC0006950, 0xC9400078, 0xDD8000F9, 0x58000028, 0x5D9C0000, 0x84000052,
+ 0x5D9C0002, 0x84000052, 0x5D9C0004, 0x8400006A, 0xC55B0038, 0xC55C08B8, 0xCD800039, 0xCDC108B8,
+ 0x80000060, 0xCD4000F8, 0x80000050, 0xC55900B8, 0xC55C1838, 0xCD8000B9, 0xCDC31838, 0x80000028,
+ 0xC55A0078, 0xC55C1078, 0xCD800079, 0xCDC21078, 0x9D000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x59540002, 0x6994E018, 0x61C0C008, 0x4194A000, 0x5D940040, 0x88000012, 0xC59400F8, 0x9D000000,
+ 0xCD4000F8, 0x00000000, 0x00000000, 0xC000697E, 0xCA4000F8, 0xC0000000, 0xC55800F8, 0xC9D400F9,
+ 0x00000000, 0x00000000, 0x79E08000, 0xCD1800F9, 0xC5D000F8, 0xC9D400F9, 0xC66000F8, 0xC52160A0,
+ 0xC5241550, 0x79E08000, 0xCD1800F9, 0xC5D000F8, 0xC9D400F9, 0xC66000F8, 0xC52160A0, 0xC5241550,
+ 0x79E08000, 0xCD1800F9, 0xC5D000F8, 0xC9D400F9, 0xC66000F8, 0xC52160A0, 0xC5241550, 0x79E08000,
+ 0xCD1800F9, 0xC5D000F8, 0xC9D400F9, 0xC66000F8, 0xC52160A0, 0xC5241550, 0x79E08000, 0xCD1800F9,
+ 0xC5D000F8, 0xC9D400F9, 0xC66000F8, 0xC52160A0, 0xC5241550, 0x79E08000, 0xCD1800F9, 0xC5D000F8,
+ 0xC9D400F9, 0xC66000F8, 0xC52160A0, 0xC5241550, 0x79E08000, 0xCD1800F9, 0xC5D000F8, 0xC9D400F9,
+ 0xC66000F8, 0xC52160A0, 0xC5241550, 0x79E08000, 0xCD1800F9, 0xC5D000F8, 0xC9D400F9, 0xC66000F8,
+ 0xC52160A0, 0xC5241550, 0x79E08000, 0xCD1800F9, 0xC5D000F8, 0xC9D400F9, 0xC66000F8, 0xC52160A0,
+ 0xC5241550, 0x79E08000, 0xCD1800F9, 0xC5D000F8, 0xC9D400F9, 0xC66000F8, 0xC52160A0, 0xC5241550,
+ 0x79E08000, 0xCD1800F9, 0xC5D000F8, 0xC9D400F9, 0xC66000F8, 0xC52160A0, 0xC5241550, 0x79E08000,
+ 0xCD1800F9, 0xC5D000F8, 0xC9D400F9, 0xC66000F8, 0xC52160A0, 0xC5241550, 0xC000697C, 0x9CC00000,
+ 0xCE0000F8, 0xC000697E, 0xCE4000F8, 0x9D000000, 0x4158A000, 0xCD4000F8, 0x00000000,
+};
+
+static u32 vr9_fw_data[] = {
+};
+
+
+#endif // IFXMIPS_ATM_FW_VR9_H
+
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_amazon_se.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_amazon_se.h
new file mode 100644
index 0000000000..412f605b2b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_amazon_se.h
@@ -0,0 +1,121 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_ppe_amazon_se.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (PPE Registers)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_ATM_PPE_AMAZON_SE_H
+#define IFXMIPS_ATM_PPE_AMAZON_SE_H
+
+
+
+/*
+ * FPI Configuration Bus Register and Memory Address Mapping
+ */
+#define IFX_PPE (KSEG1 | 0x1E180000)
+#define PP32_DEBUG_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0000) << 2)))
+#define PPM_INT_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0030) << 2)))
+#define PP32_INTERNAL_RES_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0040) << 2)))
+#define CDM_CODE_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x1000) << 2)))
+#define PPE_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x4000) << 2)))
+#define CDM_DATA_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x5000) << 2)))
+#define PPM_INT_UNIT_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6000) << 2)))
+#define PPM_TIMER0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6100) << 2)))
+#define PPM_TASK_IND_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6200) << 2)))
+#define PPS_BRK_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6300) << 2)))
+#define PPM_TIMER1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6400) << 2)))
+#define SB_RAM0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8200) << 2)))
+#define SB_RAM1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8C00) << 2)))
+#define QSB_CONF_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0xC000) << 2)))
+
+/*
+ * DWORD-Length of Memory Blocks
+ */
+#define PP32_DEBUG_REG_DWLEN 0x0030
+#define PPM_INT_REG_DWLEN 0x0010
+#define PP32_INTERNAL_RES_DWLEN 0x00C0
+#define CDM_CODE_MEMORYn_DWLEN(n) ((n) == 0 ? 0x1000 : 0x0800)
+#define PPE_REG_DWLEN 0x1000
+#define CDM_DATA_MEMORY_DWLEN CDM_CODE_MEMORYn_DWLEN(1)
+#define PPM_INT_UNIT_DWLEN 0x0100
+#define PPM_TIMER0_DWLEN 0x0100
+#define PPM_TASK_IND_REG_DWLEN 0x0100
+#define PPS_BRK_DWLEN 0x0100
+#define PPM_TIMER1_DWLEN 0x0100
+#define SB_RAM0_DWLEN 0x0A00
+#define SB_RAM1_DWLEN 0x0A00
+#define QSB_CONF_REG_DWLEN 0x0100
+
+/*
+ * PP32 to FPI Address Mapping
+ */
+#define SB_BUFFER(__sb_addr) ((volatile unsigned int *)((((__sb_addr) >= 0x2200) && ((__sb_addr) <= 0x2BFF)) ? SB_RAM0_ADDR((__sb_addr) - 0x2200) : \
+ (((__sb_addr) >= 0x2C00) && ((__sb_addr) <= 0x35FF)) ? SB_RAM1_ADDR((__sb_addr) - 0x2C00) : \
+ 0))
+
+/*
+ * PP32 Debug Control Register
+ */
+#define PP32_DBG_CTRL PP32_DEBUG_REG_ADDR(0, 0x0000)
+
+#define DBG_CTRL_RESTART 0
+#define DBG_CTRL_STOP 1
+
+#define PP32_HALT_STAT PP32_DEBUG_REG_ADDR(0, 0x0D00)
+#define PP32_BREAKPOINT_REASONS PP32_DEBUG_REG_ADDR(0, 0x0A00)
+
+#define PP32_BRK_SRC PP32_DEBUG_REG_ADDR(0, 0x0F00)
+
+#define PP32_DBG_CUR_PC PP32_DEBUG_REG_ADDR(0, 0x0F80)
+
+#define PP32_DBG_TASK_NO PP32_DEBUG_REG_ADDR(0, 0x0F81)
+
+/*
+ * Share Buffer
+ */
+#define SB_MST_PRI0 PPE_REG_ADDR(0x0300)
+#define SB_MST_PRI1 PPE_REG_ADDR(0x0301)
+
+/*
+ * EMA Registers
+ */
+#define EMA_CMDCFG PPE_REG_ADDR(0x0A00)
+#define EMA_DATACFG PPE_REG_ADDR(0x0A01)
+#define EMA_CMDCNT PPE_REG_ADDR(0x0A02)
+#define EMA_DATACNT PPE_REG_ADDR(0x0A03)
+#define EMA_ISR PPE_REG_ADDR(0x0A04)
+#define EMA_IER PPE_REG_ADDR(0x0A05)
+#define EMA_CFG PPE_REG_ADDR(0x0A06)
+#define EMA_SUBID PPE_REG_ADDR(0x0A07)
+
+#define EMA_ALIGNMENT 4
+
+/*
+ * Mailbox IGU1 Interrupt
+ */
+#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL13
+
+
+
+#endif // IFXMIPS_ATM_PPE_AMAZON_SE_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_ar9.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_ar9.h
new file mode 100644
index 0000000000..fae0252c31
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_ar9.h
@@ -0,0 +1,188 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_ppe_ar9.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (PPE Registers)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_ATM_PPE_AR9_H
+#define IFXMIPS_ATM_PPE_AR9_H
+
+
+
+/*
+ * FPI Configuration Bus Register and Memory Address Mapping
+ */
+#define IFX_PPE (KSEG1 | 0x1E180000)
+#define PP32_DEBUG_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0000) << 2)))
+#define PPM_INT_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0030) << 2)))
+#define PP32_INTERNAL_RES_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0040) << 2)))
+#define CDM_CODE_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x1000) << 2)))
+#define PPE_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x4000) << 2)))
+#define CDM_DATA_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x5000) << 2)))
+#define PPM_INT_UNIT_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6000) << 2)))
+#define PPM_TIMER0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6100) << 2)))
+#define PPM_TASK_IND_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6200) << 2)))
+#define PPS_BRK_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6300) << 2)))
+#define PPM_TIMER1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6400) << 2)))
+#define SB_RAM0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8000) << 2)))
+#define SB_RAM1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8800) << 2)))
+#define SB_RAM2_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x9000) << 2)))
+#define SB_RAM3_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x9800) << 2)))
+#define SB_RAM4_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0xA000) << 2)))
+#define QSB_CONF_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0xC000) << 2)))
+
+/*
+ * DWORD-Length of Memory Blocks
+ */
+#define PP32_DEBUG_REG_DWLEN 0x0030
+#define PPM_INT_REG_DWLEN 0x0010
+#define PP32_INTERNAL_RES_DWLEN 0x00C0
+#define CDM_CODE_MEMORYn_DWLEN(n) 0x1000
+#define PPE_REG_DWLEN 0x1000
+#define CDM_DATA_MEMORY_DWLEN CDM_CODE_MEMORYn_DWLEN(1)
+#define PPM_INT_UNIT_DWLEN 0x0100
+#define PPM_TIMER0_DWLEN 0x0100
+#define PPM_TASK_IND_REG_DWLEN 0x0100
+#define PPS_BRK_DWLEN 0x0100
+#define PPM_TIMER1_DWLEN 0x0100
+#define SB_RAM0_DWLEN 0x0800
+#define SB_RAM1_DWLEN 0x0800
+#define SB_RAM2_DWLEN 0x0800
+#define SB_RAM3_DWLEN 0x0800
+#define SB_RAM4_DWLEN 0x0C00
+#define QSB_CONF_REG_DWLEN 0x0100
+
+/*
+ * PP32 to FPI Address Mapping
+ */
+#define SB_BUFFER(__sb_addr) ((volatile unsigned int *)((((__sb_addr) >= 0x0000) && ((__sb_addr) <= 0x0FFF)) ? PPE_REG_ADDR((__sb_addr)): \
+ (((__sb_addr) >= 0x2000) && ((__sb_addr) <= 0x27FF)) ? SB_RAM0_ADDR((__sb_addr) - 0x2000) : \
+ (((__sb_addr) >= 0x2800) && ((__sb_addr) <= 0x2FFF)) ? SB_RAM1_ADDR((__sb_addr) - 0x2800) : \
+ (((__sb_addr) >= 0x3000) && ((__sb_addr) <= 0x37FF)) ? SB_RAM2_ADDR((__sb_addr) - 0x3000) : \
+ (((__sb_addr) >= 0x3800) && ((__sb_addr) <= 0x3FFF)) ? SB_RAM3_ADDR((__sb_addr) - 0x3800) : \
+ (((__sb_addr) >= 0x4000) && ((__sb_addr) <= 0x4BFF)) ? SB_RAM4_ADDR((__sb_addr) - 0x4000) : \
+ 0))
+
+/*
+ * PP32 Debug Control Register
+ */
+#define NUM_OF_PP32 1
+
+#define PP32_DBG_CTRL(n) PP32_DEBUG_REG_ADDR(n, 0x0000)
+
+#define DBG_CTRL_RESTART 0
+#define DBG_CTRL_STOP 1
+
+#define PP32_CTRL_CMD(n) PP32_DEBUG_REG_ADDR(n, 0x0B00)
+ #define PP32_CTRL_CMD_RESTART (1 << 0)
+ #define PP32_CTRL_CMD_STOP (1 << 1)
+ #define PP32_CTRL_CMD_STEP (1 << 2)
+ #define PP32_CTRL_CMD_BREAKOUT (1 << 3)
+
+#define PP32_CTRL_OPT(n) PP32_DEBUG_REG_ADDR(n, 0x0C00)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP_ON (3 << 0)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP_OFF (2 << 0)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN_ON (3 << 2)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN_OFF (2 << 2)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN_ON (3 << 4)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN_OFF (2 << 4)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT_ON (3 << 6)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT_OFF (2 << 6)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP(n) (*PP32_CTRL_OPT(n) & (1 << 0))
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN(n) (*PP32_CTRL_OPT(n) & (1 << 2))
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN(n) (*PP32_CTRL_OPT(n) & (1 << 4))
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT(n) (*PP32_CTRL_OPT(n) & (1 << 6))
+
+#define PP32_BRK_PC(n, i) PP32_DEBUG_REG_ADDR(n, 0x0900 + (i) * 2)
+#define PP32_BRK_PC_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0901 + (i) * 2)
+#define PP32_BRK_DATA_ADDR(n, i) PP32_DEBUG_REG_ADDR(n, 0x0904 + (i) * 2)
+#define PP32_BRK_DATA_ADDR_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0905 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_RD(n, i) PP32_DEBUG_REG_ADDR(n, 0x0908 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_RD_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0909 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_WR(n, i) PP32_DEBUG_REG_ADDR(n, 0x090C + (i) * 2)
+#define PP32_BRK_DATA_VALUE_WR_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x090D + (i) * 2)
+ #define PP32_BRK_CONTEXT_MASK(i) (1 << (i))
+ #define PP32_BRK_CONTEXT_MASK_EN (1 << 4)
+ #define PP32_BRK_COMPARE_GREATER_EQUAL (1 << 5) // valid for break data value rd/wr only
+ #define PP32_BRK_COMPARE_LOWER_EQUAL (1 << 6)
+ #define PP32_BRK_COMPARE_EN (1 << 7)
+
+#define PP32_BRK_TRIG(n) PP32_DEBUG_REG_ADDR(n, 0x0F00)
+ #define PP32_BRK_GRPi_PCn_ON(i, n) ((3 << ((n) * 2)) << ((i) * 16))
+ #define PP32_BRK_GRPi_PCn_OFF(i, n) ((2 << ((n) * 2)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_ADDRn_ON(i, n) ((3 << ((n) * 2 + 4)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_ADDRn_OFF(i, n) ((2 << ((n) * 2 + 4)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn_ON(i, n) ((3 << ((n) * 2 + 8)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn_OFF(i, n)((2 << ((n) * 2 + 8)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn_ON(i, n) ((3 << ((n) * 2 + 12)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn_OFF(i, n)((2 << ((n) * 2 + 12)) << ((i) * 16))
+ #define PP32_BRK_GRPi_PCn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n))) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_ADDRn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 2)) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 4)) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 6)) << ((i) * 8)))
+
+#define PP32_CPU_STATUS(n) PP32_DEBUG_REG_ADDR(n, 0x0D00)
+#define PP32_HALT_STAT(n) PP32_CPU_STATUS(n)
+#define PP32_DBG_CUR_PC(n) PP32_CPU_STATUS(n)
+ #define PP32_CPU_USER_STOPPED(n) (*PP32_CPU_STATUS(n) & (1 << 0))
+ #define PP32_CPU_USER_BREAKIN_RCV(n) (*PP32_CPU_STATUS(n) & (1 << 1))
+ #define PP32_CPU_USER_BREAKPOINT_MET(n) (*PP32_CPU_STATUS(n) & (1 << 2))
+ #define PP32_CPU_CUR_PC(n) (*PP32_CPU_STATUS(n) >> 16)
+
+#define PP32_BREAKPOINT_REASONS(n) PP32_DEBUG_REG_ADDR(n, 0x0A00)
+ #define PP32_BRK_PC_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << (i)))
+ #define PP32_BRK_DATA_ADDR_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 2)))
+ #define PP32_BRK_DATA_VALUE_RD_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 4)))
+ #define PP32_BRK_DATA_VALUE_WR_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 6)))
+ #define PP32_BRK_DATA_VALUE_RD_LO_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 8)))
+ #define PP32_BRK_DATA_VALUE_RD_GT_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 9)))
+ #define PP32_BRK_DATA_VALUE_WR_LO_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 12)))
+ #define PP32_BRK_DATA_VALUE_WR_GT_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 13)))
+ #define PP32_BRK_CUR_CONTEXT(n) ((*PP32_BREAKPOINT_REASONS(n) >> 16) & 0x03)
+
+#define PP32_GP_REG_BASE(n) PP32_DEBUG_REG_ADDR(n, 0x0E00)
+#define PP32_GP_CONTEXTi_REGn(n, i, j) PP32_DEBUG_REG_ADDR(n, 0x0E00 + (i) * 16 + (j))
+
+/*
+ * EMA Registers
+ */
+#define EMA_CMDCFG PPE_REG_ADDR(0x0A00)
+#define EMA_DATACFG PPE_REG_ADDR(0x0A01)
+#define EMA_CMDCNT PPE_REG_ADDR(0x0A02)
+#define EMA_DATACNT PPE_REG_ADDR(0x0A03)
+#define EMA_ISR PPE_REG_ADDR(0x0A04)
+#define EMA_IER PPE_REG_ADDR(0x0A05)
+#define EMA_CFG PPE_REG_ADDR(0x0A06)
+#define EMA_SUBID PPE_REG_ADDR(0x0A07)
+
+#define EMA_ALIGNMENT 4
+
+/*
+ * Mailbox IGU1 Interrupt
+ */
+#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
+
+
+
+#endif // IFXMIPS_ATM_PPE_AR9_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_common.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_common.h
new file mode 100644
index 0000000000..ee55fd7a0f
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_common.h
@@ -0,0 +1,368 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_ppe_common.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (PPE Registers)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_ATM_PPE_COMMON_H
+#define IFXMIPS_ATM_PPE_COMMON_H
+
+
+
+#if defined(CONFIG_DANUBE)
+ #include "ifxmips_atm_ppe_danube.h"
+#elif defined(CONFIG_AMAZON_SE)
+ #include "ifxmips_atm_ppe_amazon_se.h"
+#elif defined(CONFIG_AR9)
+ #include "ifxmips_atm_ppe_ar9.h"
+#elif defined(CONFIG_VR9)
+ #include "ifxmips_atm_ppe_vr9.h"
+#else
+ #error Platform is not specified!
+#endif
+
+
+
+/*
+ * Code/Data Memory (CDM) Interface Configuration Register
+ */
+#define CDM_CFG PPE_REG_ADDR(0x0100)
+
+#define CDM_CFG_RAM1 GET_BITS(*CDM_CFG, 3, 2)
+#define CDM_CFG_RAM0 (*CDM_CFG & (1 << 1))
+
+#define CDM_CFG_RAM1_SET(value) SET_BITS(0, 3, 2, value)
+#define CDM_CFG_RAM0_SET(value) ((value) ? (1 << 1) : 0)
+
+/*
+ * QSB Internal Cell Delay Variation Register
+ */
+#define QSB_ICDV QSB_CONF_REG_ADDR(0x0007)
+
+#define QSB_ICDV_TAU GET_BITS(*QSB_ICDV, 5, 0)
+
+#define QSB_ICDV_TAU_SET(value) SET_BITS(0, 5, 0, value)
+
+/*
+ * QSB Scheduler Burst Limit Register
+ */
+#define QSB_SBL QSB_CONF_REG_ADDR(0x0009)
+
+#define QSB_SBL_SBL GET_BITS(*QSB_SBL, 3, 0)
+
+#define QSB_SBL_SBL_SET(value) SET_BITS(0, 3, 0, value)
+
+/*
+ * QSB Configuration Register
+ */
+#define QSB_CFG QSB_CONF_REG_ADDR(0x000A)
+
+#define QSB_CFG_TSTEPC GET_BITS(*QSB_CFG, 1, 0)
+
+#define QSB_CFG_TSTEPC_SET(value) SET_BITS(0, 1, 0, value)
+
+/*
+ * QSB RAM Transfer Table Register
+ */
+#define QSB_RTM QSB_CONF_REG_ADDR(0x000B)
+
+#define QSB_RTM_DM (*QSB_RTM)
+
+#define QSB_RTM_DM_SET(value) ((value) & 0xFFFFFFFF)
+
+/*
+ * QSB RAM Transfer Data Register
+ */
+#define QSB_RTD QSB_CONF_REG_ADDR(0x000C)
+
+#define QSB_RTD_TTV (*QSB_RTD)
+
+#define QSB_RTD_TTV_SET(value) ((value) & 0xFFFFFFFF)
+
+/*
+ * QSB RAM Access Register
+ */
+#define QSB_RAMAC QSB_CONF_REG_ADDR(0x000D)
+
+#define QSB_RAMAC_RW (*QSB_RAMAC & (1 << 31))
+#define QSB_RAMAC_TSEL GET_BITS(*QSB_RAMAC, 27, 24)
+#define QSB_RAMAC_LH (*QSB_RAMAC & (1 << 16))
+#define QSB_RAMAC_TESEL GET_BITS(*QSB_RAMAC, 9, 0)
+
+#define QSB_RAMAC_RW_SET(value) ((value) ? (1 << 31) : 0)
+#define QSB_RAMAC_TSEL_SET(value) SET_BITS(0, 27, 24, value)
+#define QSB_RAMAC_LH_SET(value) ((value) ? (1 << 16) : 0)
+#define QSB_RAMAC_TESEL_SET(value) SET_BITS(0, 9, 0, value)
+
+/*
+ * QSB Queue Scheduling and Shaping Definitions
+ */
+#define QSB_WFQ_NONUBR_MAX 0x3f00
+#define QSB_WFQ_UBR_BYPASS 0x3fff
+#define QSB_TP_TS_MAX 65472
+#define QSB_TAUS_MAX 64512
+#define QSB_GCR_MIN 18
+
+/*
+ * QSB Constant
+ */
+#define QSB_RAMAC_RW_READ 0
+#define QSB_RAMAC_RW_WRITE 1
+
+#define QSB_RAMAC_TSEL_QPT 0x01
+#define QSB_RAMAC_TSEL_SCT 0x02
+#define QSB_RAMAC_TSEL_SPT 0x03
+#define QSB_RAMAC_TSEL_VBR 0x08
+
+#define QSB_RAMAC_LH_LOW 0
+#define QSB_RAMAC_LH_HIGH 1
+
+#define QSB_QPT_SET_MASK 0x0
+#define QSB_QVPT_SET_MASK 0x0
+#define QSB_SET_SCT_MASK 0x0
+#define QSB_SET_SPT_MASK 0x0
+#define QSB_SET_SPT_SBVALID_MASK 0x7FFFFFFF
+
+#define QSB_SPT_SBV_VALID (1 << 31)
+#define QSB_SPT_PN_SET(value) (((value) & 0x01) ? (1 << 16) : 0)
+#define QSB_SPT_INTRATE_SET(value) SET_BITS(0, 13, 0, value)
+
+/*
+ * QSB Queue Parameter Table Entry and Queue VBR Parameter Table Entry
+ */
+#if defined(__BIG_ENDIAN)
+ union qsb_queue_parameter_table {
+ struct {
+ unsigned int res1 :1;
+ unsigned int vbr :1;
+ unsigned int wfqf :14;
+ unsigned int tp :16;
+ } bit;
+ u32 dword;
+ };
+
+ union qsb_queue_vbr_parameter_table {
+ struct {
+ unsigned int taus :16;
+ unsigned int ts :16;
+ } bit;
+ u32 dword;
+ };
+#else
+ union qsb_queue_parameter_table {
+ struct {
+ unsigned int tp :16;
+ unsigned int wfqf :14;
+ unsigned int vbr :1;
+ unsigned int res1 :1;
+ } bit;
+ u32 dword;
+ };
+
+ union qsb_queue_vbr_parameter_table {
+ struct {
+ unsigned int ts :16;
+ unsigned int taus :16;
+ } bit;
+ u32 dword;
+ };
+#endif // defined(__BIG_ENDIAN)
+
+/*
+ * Mailbox IGU0 Registers
+ */
+#define MBOX_IGU0_ISRS PPE_REG_ADDR(0x0200)
+#define MBOX_IGU0_ISRC PPE_REG_ADDR(0x0201)
+#define MBOX_IGU0_ISR PPE_REG_ADDR(0x0202)
+#define MBOX_IGU0_IER PPE_REG_ADDR(0x0203)
+
+#define MBOX_IGU0_ISRS_SET(n) (1 << (n))
+#define MBOX_IGU0_ISRC_CLEAR(n) (1 << (n))
+#define MBOX_IGU0_ISR_ISR(n) (*MBOX_IGU0_ISR & (1 << (n)))
+#define MBOX_IGU0_IER_EN(n) (*MBOX_IGU0_IER & (1 << (n)))
+#define MBOX_IGU0_IER_EN_SET(n) (1 << (n))
+
+/*
+ * Mailbox IGU1 Registers
+ */
+#define MBOX_IGU1_ISRS PPE_REG_ADDR(0x0204)
+#define MBOX_IGU1_ISRC PPE_REG_ADDR(0x0205)
+#define MBOX_IGU1_ISR PPE_REG_ADDR(0x0206)
+#define MBOX_IGU1_IER PPE_REG_ADDR(0x0207)
+
+#define MBOX_IGU1_ISRS_SET(n) (1 << (n))
+#define MBOX_IGU1_ISRC_CLEAR(n) (1 << (n))
+#define MBOX_IGU1_ISR_ISR(n) (*MBOX_IGU1_ISR & (1 << (n)))
+#define MBOX_IGU1_IER_EN(n) (*MBOX_IGU1_IER & (1 << (n)))
+#define MBOX_IGU1_IER_EN_SET(n) (1 << (n))
+
+/*
+ * Mailbox IGU3 Registers
+ */
+#define MBOX_IGU3_ISRS PPE_REG_ADDR(0x0214)
+#define MBOX_IGU3_ISRC PPE_REG_ADDR(0x0215)
+#define MBOX_IGU3_ISR PPE_REG_ADDR(0x0216)
+#define MBOX_IGU3_IER PPE_REG_ADDR(0x0217)
+
+#define MBOX_IGU3_ISRS_SET(n) (1 << (n))
+#define MBOX_IGU3_ISRC_CLEAR(n) (1 << (n))
+#define MBOX_IGU3_ISR_ISR(n) (*MBOX_IGU3_ISR & (1 << (n)))
+#define MBOX_IGU3_IER_EN(n) (*MBOX_IGU3_IER & (1 << (n)))
+#define MBOX_IGU3_IER_EN_SET(n) (1 << (n))
+
+/*
+ * RTHA/TTHA Registers
+ */
+#define RFBI_CFG PPE_REG_ADDR(0x0400)
+#define RBA_CFG0 PPE_REG_ADDR(0x0404)
+#define RBA_CFG1 PPE_REG_ADDR(0x0405)
+#define RCA_CFG0 PPE_REG_ADDR(0x0408)
+#define RCA_CFG1 PPE_REG_ADDR(0x0409)
+#define RDES_CFG0 PPE_REG_ADDR(0x040C)
+#define RDES_CFG1 PPE_REG_ADDR(0x040D)
+#define SFSM_STATE0 PPE_REG_ADDR(0x0410)
+#define SFSM_STATE1 PPE_REG_ADDR(0x0411)
+#define SFSM_DBA0 PPE_REG_ADDR(0x0412)
+#define SFSM_DBA1 PPE_REG_ADDR(0x0413)
+#define SFSM_CBA0 PPE_REG_ADDR(0x0414)
+#define SFSM_CBA1 PPE_REG_ADDR(0x0415)
+#define SFSM_CFG0 PPE_REG_ADDR(0x0416)
+#define SFSM_CFG1 PPE_REG_ADDR(0x0417)
+#define SFSM_PGCNT0 PPE_REG_ADDR(0x041C)
+#define SFSM_PGCNT1 PPE_REG_ADDR(0x041D)
+#define FFSM_DBA0 PPE_REG_ADDR(0x0508)
+#define FFSM_DBA1 PPE_REG_ADDR(0x0509)
+#define FFSM_CFG0 PPE_REG_ADDR(0x050A)
+#define FFSM_CFG1 PPE_REG_ADDR(0x050B)
+#define FFSM_IDLE_HEAD_BC0 PPE_REG_ADDR(0x050E)
+#define FFSM_IDLE_HEAD_BC1 PPE_REG_ADDR(0x050F)
+#define FFSM_PGCNT0 PPE_REG_ADDR(0x0514)
+#define FFSM_PGCNT1 PPE_REG_ADDR(0x0515)
+
+/*
+ * PPE TC Logic Registers (partial)
+ */
+#define DREG_A_VERSION PPE_REG_ADDR(0x0D00)
+#define DREG_A_CFG PPE_REG_ADDR(0x0D01)
+#define DREG_AT_CTRL PPE_REG_ADDR(0x0D02)
+#define DREG_AT_CB_CFG0 PPE_REG_ADDR(0x0D03)
+#define DREG_AT_CB_CFG1 PPE_REG_ADDR(0x0D04)
+#define DREG_AR_CTRL PPE_REG_ADDR(0x0D08)
+#define DREG_AR_CB_CFG0 PPE_REG_ADDR(0x0D09)
+#define DREG_AR_CB_CFG1 PPE_REG_ADDR(0x0D0A)
+#define DREG_A_UTPCFG PPE_REG_ADDR(0x0D0E)
+#define DREG_A_STATUS PPE_REG_ADDR(0x0D0F)
+#define DREG_AT_CFG0 PPE_REG_ADDR(0x0D20)
+#define DREG_AT_CFG1 PPE_REG_ADDR(0x0D21)
+#define DREG_AT_FB_SIZE0 PPE_REG_ADDR(0x0D22)
+#define DREG_AT_FB_SIZE1 PPE_REG_ADDR(0x0D23)
+#define DREG_AT_CELL0 PPE_REG_ADDR(0x0D24)
+#define DREG_AT_CELL1 PPE_REG_ADDR(0x0D25)
+#define DREG_AT_IDLE_CNT0 PPE_REG_ADDR(0x0D26)
+#define DREG_AT_IDLE_CNT1 PPE_REG_ADDR(0x0D27)
+#define DREG_AT_IDLE0 PPE_REG_ADDR(0x0D28)
+#define DREG_AT_IDLE1 PPE_REG_ADDR(0x0D29)
+#define DREG_AR_CFG0 PPE_REG_ADDR(0x0D60)
+#define DREG_AR_CFG1 PPE_REG_ADDR(0x0D61)
+#define DREG_AR_CELL0 PPE_REG_ADDR(0x0D68)
+#define DREG_AR_CELL1 PPE_REG_ADDR(0x0D69)
+#define DREG_AR_IDLE_CNT0 PPE_REG_ADDR(0x0D6A)
+#define DREG_AR_IDLE_CNT1 PPE_REG_ADDR(0x0D6B)
+#define DREG_AR_AIIDLE_CNT0 PPE_REG_ADDR(0x0D6C)
+#define DREG_AR_AIIDLE_CNT1 PPE_REG_ADDR(0x0D6D)
+#define DREG_AR_BE_CNT0 PPE_REG_ADDR(0x0D6E)
+#define DREG_AR_BE_CNT1 PPE_REG_ADDR(0x0D6F)
+#define DREG_AR_HEC_CNT0 PPE_REG_ADDR(0x0D70)
+#define DREG_AR_HEC_CNT1 PPE_REG_ADDR(0x0D71)
+#define DREG_AR_IDLE0 PPE_REG_ADDR(0x0D74)
+#define DREG_AR_IDLE1 PPE_REG_ADDR(0x0D75)
+#define DREG_AR_CVN_CNT0 PPE_REG_ADDR(0x0DA4)
+#define DREG_AR_CVN_CNT1 PPE_REG_ADDR(0x0DA5)
+#define DREG_AR_CVNP_CNT0 PPE_REG_ADDR(0x0DA6)
+#define DREG_AR_CVNP_CNT1 PPE_REG_ADDR(0x0DA7)
+#define DREG_B0_LADR PPE_REG_ADDR(0x0DA8)
+#define DREG_B1_LADR PPE_REG_ADDR(0x0DA9)
+
+#define SFSM_DBA(i) ( (SFSM_dba * ) PPE_REG_ADDR(0x0412 + (i)))
+#define SFSM_CBA(i) ( (SFSM_cba * ) PPE_REG_ADDR(0x0414 + (i)))
+#define SFSM_CFG(i) ( (SFSM_cfg * ) PPE_REG_ADDR(0x0416 + (i)))
+#define SFSM_PGCNT(i) ( (SFSM_pgcnt * ) PPE_REG_ADDR(0x041C + (i)))
+
+#define FFSM_DBA(i) ( (FFSM_dba * ) PPE_REG_ADDR(0x0508 + (i)))
+#define FFSM_CFG(i) ( (FFSM_cfg * ) PPE_REG_ADDR(0x050A + (i)))
+#define FFSM_PGCNT(i) ( (FFSM_pgcnt * ) PPE_REG_ADDR(0x0514 + (i)))
+
+typedef struct {
+ unsigned int res : 19;
+ unsigned int dbase : 13;
+} SFSM_dba;
+
+typedef struct {
+ unsigned int res : 19;
+ unsigned int cbase : 13;
+} SFSM_cba;
+
+typedef struct {
+ unsigned int res : 15;
+ unsigned int endian : 1;
+ unsigned int idlekeep: 1;
+ unsigned int sen : 1;
+ unsigned int res1 : 8;
+ unsigned int pnum : 6;
+} SFSM_cfg;
+
+typedef struct {
+ unsigned int res : 17;
+ unsigned int pptr : 6;
+ unsigned int dcmd : 1;
+ unsigned int res1 : 2;
+ unsigned int upage : 6;
+} SFSM_pgcnt;
+
+typedef struct {
+ unsigned int res : 19;
+ unsigned int dbase : 13;
+} FFSM_dba;
+
+typedef struct {
+ unsigned int res : 12;
+ unsigned int rstptr : 1;
+ unsigned int clvpage : 1;
+ unsigned int fidle : 1;
+ unsigned int endian : 1;
+ unsigned int res1 : 10;
+ unsigned int pnum : 6;
+} FFSM_cfg;
+
+typedef struct {
+ unsigned int res : 17;
+ unsigned int ival : 6;
+ unsigned int icmd : 1;
+ unsigned int res1 : 2;
+ unsigned int vpage : 6;
+} FFSM_pgcnt;
+
+
+
+#endif // IFXMIPS_ATM_PPE_COMMON_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_danube.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_danube.h
new file mode 100644
index 0000000000..7aaaa8db1e
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_danube.h
@@ -0,0 +1,129 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_ppe_danube.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (PPE Registers)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_ATM_PPE_DANUBE_H
+#define IFXMIPS_ATM_PPE_DANUBE_H
+
+
+
+/*
+ * FPI Configuration Bus Register and Memory Address Mapping
+ */
+#define IFX_PPE (KSEG1 | 0x1E180000)
+#define PP32_DEBUG_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0000) << 2)))
+#define PPM_INT_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0030) << 2)))
+#define PP32_INTERNAL_RES_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0040) << 2)))
+#define CDM_CODE_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x1000) << 2)))
+#define PPE_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x4000) << 2)))
+#define CDM_DATA_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x5000) << 2)))
+#define PPM_INT_UNIT_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6000) << 2)))
+#define PPM_TIMER0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6100) << 2)))
+#define PPM_TASK_IND_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6200) << 2)))
+#define PPS_BRK_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6300) << 2)))
+#define PPM_TIMER1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6400) << 2)))
+#define SB_RAM0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8000) << 2)))
+#define SB_RAM1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8400) << 2)))
+#define SB_RAM2_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8C00) << 2)))
+#define SB_RAM3_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x9600) << 2)))
+#define QSB_CONF_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0xC000) << 2)))
+
+/*
+ * DWORD-Length of Memory Blocks
+ */
+#define PP32_DEBUG_REG_DWLEN 0x0030
+#define PPM_INT_REG_DWLEN 0x0010
+#define PP32_INTERNAL_RES_DWLEN 0x00C0
+#define CDM_CODE_MEMORYn_DWLEN(n) ((n) == 0 ? 0x1000 : 0x0800)
+#define PPE_REG_DWLEN 0x1000
+#define CDM_DATA_MEMORY_DWLEN CDM_CODE_MEMORYn_DWLEN(1)
+#define PPM_INT_UNIT_DWLEN 0x0100
+#define PPM_TIMER0_DWLEN 0x0100
+#define PPM_TASK_IND_REG_DWLEN 0x0100
+#define PPS_BRK_DWLEN 0x0100
+#define PPM_TIMER1_DWLEN 0x0100
+#define SB_RAM0_DWLEN 0x0400
+#define SB_RAM1_DWLEN 0x0800
+#define SB_RAM2_DWLEN 0x0A00
+#define SB_RAM3_DWLEN 0x0400
+#define QSB_CONF_REG_DWLEN 0x0100
+
+/*
+ * PP32 to FPI Address Mapping
+ */
+#define SB_BUFFER(__sb_addr) ((volatile unsigned int *)((((__sb_addr) >= 0x2000) && ((__sb_addr) <= 0x23FF)) ? SB_RAM0_ADDR((__sb_addr) - 0x2000) : \
+ (((__sb_addr) >= 0x2400) && ((__sb_addr) <= 0x2BFF)) ? SB_RAM1_ADDR((__sb_addr) - 0x2400) : \
+ (((__sb_addr) >= 0x2C00) && ((__sb_addr) <= 0x35FF)) ? SB_RAM2_ADDR((__sb_addr) - 0x2C00) : \
+ (((__sb_addr) >= 0x3600) && ((__sb_addr) <= 0x39FF)) ? SB_RAM3_ADDR((__sb_addr) - 0x3600) : \
+ 0))
+
+/*
+ * PP32 Debug Control Register
+ */
+#define PP32_DBG_CTRL PP32_DEBUG_REG_ADDR(0, 0x0000)
+
+#define DBG_CTRL_START_SET(value) ((value) ? (1 << 0) : 0)
+#define DBG_CTRL_STOP_SET(value) ((value) ? (1 << 1) : 0)
+#define DBG_CTRL_STEP_SET(value) ((value) ? (1 << 2) : 0)
+
+#define PP32_HALT_STAT PP32_DEBUG_REG_ADDR(0, 0x0001)
+
+#define PP32_BRK_SRC PP32_DEBUG_REG_ADDR(0, 0x0002)
+
+#define PP32_DBG_PC_MIN(i) PP32_DEBUG_REG_ADDR(0, 0x0010 + (i))
+#define PP32_DBG_PC_MAX(i) PP32_DEBUG_REG_ADDR(0, 0x0014 + (i))
+#define PP32_DBG_DATA_MIN(i) PP32_DEBUG_REG_ADDR(0, 0x0018 + (i))
+#define PP32_DBG_DATA_MAX(i) PP32_DEBUG_REG_ADDR(0, 0x001A + (i))
+#define PP32_DBG_DATA_VAL(i) PP32_DEBUG_REG_ADDR(0, 0x001C + (i))
+
+#define PP32_DBG_CUR_PC PP32_DEBUG_REG_ADDR(0, 0x0080)
+
+#define PP32_DBG_TASK_NO PP32_DEBUG_REG_ADDR(0, 0x0081)
+
+#define PP32_DBG_REG_BASE(tsk, i) PP32_DEBUG_REG_ADDR(0, 0x0100 + (tsk) * 16 + (i))
+
+/*
+ * EMA Registers
+ */
+#define EMA_CMDCFG PPE_REG_ADDR(0x0A00)
+#define EMA_DATACFG PPE_REG_ADDR(0x0A01)
+#define EMA_CMDCNT PPE_REG_ADDR(0x0A02)
+#define EMA_DATACNT PPE_REG_ADDR(0x0A03)
+#define EMA_ISR PPE_REG_ADDR(0x0A04)
+#define EMA_IER PPE_REG_ADDR(0x0A05)
+#define EMA_CFG PPE_REG_ADDR(0x0A06)
+#define EMA_SUBID PPE_REG_ADDR(0x0A07)
+
+#define EMA_ALIGNMENT 4
+
+/*
+ * Mailbox IGU1 Interrupt
+ */
+#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
+
+
+
+#endif // IFXMIPS_ATM_PPE_DANUBE_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_vr9.h b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_vr9.h
new file mode 100644
index 0000000000..144c39656c
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_ppe_vr9.h
@@ -0,0 +1,192 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_ppe_vr9.h
+** PROJECT : UEIP
+** MODULES : ATM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM Driver (PPE Registers)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_ATM_PPE_VR9_H
+#define IFXMIPS_ATM_PPE_VR9_H
+
+
+
+/*
+ * FPI Configuration Bus Register and Memory Address Mapping
+ */
+#define IFX_PPE (KSEG1 | 0x1E200000)
+#define PP32_DEBUG_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x000000 + (i) * 0x00010000) << 2)))
+#define CDM_CODE_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x001000 + (i) * 0x00010000) << 2)))
+#define CDM_DATA_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x004000 + (i) * 0x00010000) << 2)))
+#define SB_RAM0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x008000) << 2)))
+#define SB_RAM1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x009000) << 2)))
+#define SB_RAM2_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x00A000) << 2)))
+#define SB_RAM3_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x00B000) << 2)))
+#define PPE_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x00D000) << 2)))
+#define QSB_CONF_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x00E000) << 2)))
+#define SB_RAM6_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x018000) << 2)))
+
+/*
+ * DWORD-Length of Memory Blocks
+ */
+#define PP32_DEBUG_REG_DWLEN 0x0030
+#define CDM_CODE_MEMORYn_DWLEN(n) ((n) == 0 ? 0x1000 : 0x0800)
+#define CDM_DATA_MEMORY_DWLEN CDM_CODE_MEMORYn_DWLEN(1)
+#define SB_RAM0_DWLEN 0x1000
+#define SB_RAM1_DWLEN 0x1000
+#define SB_RAM2_DWLEN 0x1000
+#define SB_RAM3_DWLEN 0x1000
+#define SB_RAM6_DWLEN 0x8000
+#define QSB_CONF_REG_DWLEN 0x0100
+
+/*
+ * PP32 to FPI Address Mapping
+ */
+#define SB_BUFFER(__sb_addr) ((volatile unsigned int *)((((__sb_addr) >= 0x0000) && ((__sb_addr) <= 0x1FFF)) ? PPE_REG_ADDR((__sb_addr)) : \
+ (((__sb_addr) >= 0x2000) && ((__sb_addr) <= 0x2FFF)) ? SB_RAM0_ADDR((__sb_addr) - 0x2000) : \
+ (((__sb_addr) >= 0x3000) && ((__sb_addr) <= 0x3FFF)) ? SB_RAM1_ADDR((__sb_addr) - 0x3000) : \
+ (((__sb_addr) >= 0x4000) && ((__sb_addr) <= 0x4FFF)) ? SB_RAM2_ADDR((__sb_addr) - 0x4000) : \
+ (((__sb_addr) >= 0x5000) && ((__sb_addr) <= 0x5FFF)) ? SB_RAM3_ADDR((__sb_addr) - 0x5000) : \
+ (((__sb_addr) >= 0x7000) && ((__sb_addr) <= 0x7FFF)) ? PPE_REG_ADDR((__sb_addr) - 0x7000) : \
+ (((__sb_addr) >= 0x8000) && ((__sb_addr) <= 0xFFFF)) ? SB_RAM6_ADDR((__sb_addr) - 0x8000) : \
+ 0))
+
+/*
+ * PP32 Debug Control Register
+ */
+#define NUM_OF_PP32 2
+
+#define PP32_FREEZE PPE_REG_ADDR(0x0000)
+#define PP32_SRST PPE_REG_ADDR(0x0020)
+
+#define PP32_DBG_CTRL(n) PP32_DEBUG_REG_ADDR(n, 0x0000)
+
+#define DBG_CTRL_RESTART 0
+#define DBG_CTRL_STOP 1
+
+#define PP32_CTRL_CMD(n) PP32_DEBUG_REG_ADDR(n, 0x0B00)
+ #define PP32_CTRL_CMD_RESTART (1 << 0)
+ #define PP32_CTRL_CMD_STOP (1 << 1)
+ #define PP32_CTRL_CMD_STEP (1 << 2)
+ #define PP32_CTRL_CMD_BREAKOUT (1 << 3)
+
+#define PP32_CTRL_OPT(n) PP32_DEBUG_REG_ADDR(n, 0x0C00)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP_ON (3 << 0)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP_OFF (2 << 0)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN_ON (3 << 2)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN_OFF (2 << 2)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN_ON (3 << 4)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN_OFF (2 << 4)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT_ON (3 << 6)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT_OFF (2 << 6)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP(n) (*PP32_CTRL_OPT(n) & (1 << 0))
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN(n) (*PP32_CTRL_OPT(n) & (1 << 2))
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN(n) (*PP32_CTRL_OPT(n) & (1 << 4))
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT(n) (*PP32_CTRL_OPT(n) & (1 << 6))
+
+#define PP32_BRK_PC(n, i) PP32_DEBUG_REG_ADDR(n, 0x0900 + (i) * 2)
+#define PP32_BRK_PC_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0901 + (i) * 2)
+#define PP32_BRK_DATA_ADDR(n, i) PP32_DEBUG_REG_ADDR(n, 0x0904 + (i) * 2)
+#define PP32_BRK_DATA_ADDR_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0905 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_RD(n, i) PP32_DEBUG_REG_ADDR(n, 0x0908 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_RD_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0909 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_WR(n, i) PP32_DEBUG_REG_ADDR(n, 0x090C + (i) * 2)
+#define PP32_BRK_DATA_VALUE_WR_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x090D + (i) * 2)
+ #define PP32_BRK_CONTEXT_MASK(i) (1 << (i))
+ #define PP32_BRK_CONTEXT_MASK_EN (1 << 4)
+ #define PP32_BRK_COMPARE_GREATER_EQUAL (1 << 5) // valid for break data value rd/wr only
+ #define PP32_BRK_COMPARE_LOWER_EQUAL (1 << 6)
+ #define PP32_BRK_COMPARE_EN (1 << 7)
+
+#define PP32_BRK_TRIG(n) PP32_DEBUG_REG_ADDR(n, 0x0F00)
+ #define PP32_BRK_GRPi_PCn_ON(i, n) ((3 << ((n) * 2)) << ((i) * 16))
+ #define PP32_BRK_GRPi_PCn_OFF(i, n) ((2 << ((n) * 2)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_ADDRn_ON(i, n) ((3 << ((n) * 2 + 4)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_ADDRn_OFF(i, n) ((2 << ((n) * 2 + 4)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn_ON(i, n) ((3 << ((n) * 2 + 8)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn_OFF(i, n)((2 << ((n) * 2 + 8)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn_ON(i, n) ((3 << ((n) * 2 + 12)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn_OFF(i, n)((2 << ((n) * 2 + 12)) << ((i) * 16))
+ #define PP32_BRK_GRPi_PCn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n))) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_ADDRn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 2)) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 4)) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 6)) << ((i) * 8)))
+
+#define PP32_CPU_STATUS(n) PP32_DEBUG_REG_ADDR(n, 0x0D00)
+#define PP32_HALT_STAT(n) PP32_CPU_STATUS(n)
+#define PP32_DBG_CUR_PC(n) PP32_CPU_STATUS(n)
+ #define PP32_CPU_USER_STOPPED(n) (*PP32_CPU_STATUS(n) & (1 << 0))
+ #define PP32_CPU_USER_BREAKIN_RCV(n) (*PP32_CPU_STATUS(n) & (1 << 1))
+ #define PP32_CPU_USER_BREAKPOINT_MET(n) (*PP32_CPU_STATUS(n) & (1 << 2))
+ #define PP32_CPU_CUR_PC(n) (*PP32_CPU_STATUS(n) >> 16)
+
+#define PP32_BREAKPOINT_REASONS(n) PP32_DEBUG_REG_ADDR(n, 0x0A00)
+ #define PP32_BRK_PC_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << (i)))
+ #define PP32_BRK_DATA_ADDR_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 2)))
+ #define PP32_BRK_DATA_VALUE_RD_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 4)))
+ #define PP32_BRK_DATA_VALUE_WR_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 6)))
+ #define PP32_BRK_DATA_VALUE_RD_LO_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 8)))
+ #define PP32_BRK_DATA_VALUE_RD_GT_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 9)))
+ #define PP32_BRK_DATA_VALUE_WR_LO_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 12)))
+ #define PP32_BRK_DATA_VALUE_WR_GT_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 13)))
+ #define PP32_BRK_CUR_CONTEXT(n) ((*PP32_BREAKPOINT_REASONS(n) >> 16) & 0x03)
+
+#define PP32_GP_REG_BASE(n) PP32_DEBUG_REG_ADDR(n, 0x0E00)
+#define PP32_GP_CONTEXTi_REGn(n, i, j) PP32_DEBUG_REG_ADDR(n, 0x0E00 + (i) * 16 + (j))
+
+/*
+ * PDMA/EMA Registers
+ */
+#define PDMA_CFG PPE_REG_ADDR(0x0A00)
+#define PDMA_RX_CMDCNT PPE_REG_ADDR(0x0A01)
+#define PDMA_TX_CMDCNT PPE_REG_ADDR(0x0A02)
+#define PDMA_RX_FWDATACNT PPE_REG_ADDR(0x0A03)
+#define PDMA_TX_FWDATACNT PPE_REG_ADDR(0x0A04)
+#define PDMA_RX_CTX_CFG PPE_REG_ADDR(0x0A05)
+#define PDMA_TX_CTX_CFG PPE_REG_ADDR(0x0A06)
+#define PDMA_RX_MAX_LEN_REG PPE_REG_ADDR(0x0A07)
+#define PDMA_RX_DELAY_CFG PPE_REG_ADDR(0x0A08)
+#define PDMA_INT_FIFO_RD PPE_REG_ADDR(0x0A09)
+#define PDMA_ISR PPE_REG_ADDR(0x0A0A)
+#define PDMA_IER PPE_REG_ADDR(0x0A0B)
+#define PDMA_SUBID PPE_REG_ADDR(0x0A0C)
+#define PDMA_BAR0 PPE_REG_ADDR(0x0A0D)
+#define PDMA_BAR1 PPE_REG_ADDR(0x0A0E)
+
+#define SAR_PDMA_RX_CMDBUF_CFG PPE_REG_ADDR(0x0F00)
+#define SAR_PDMA_TX_CMDBUF_CFG PPE_REG_ADDR(0x0F01)
+#define SAR_PDMA_RX_FW_CMDBUF_CFG PPE_REG_ADDR(0x0F02)
+#define SAR_PDMA_TX_FW_CMDBUF_CFG PPE_REG_ADDR(0x0F03)
+#define SAR_PDMA_RX_CMDBUF_STATUS PPE_REG_ADDR(0x0F04)
+#define SAR_PDMA_TX_CMDBUF_STATUS PPE_REG_ADDR(0x0F05)
+
+#define PDMA_ALIGNMENT 4
+#define EMA_ALIGNMENT PDMA_ALIGNMENT
+
+/*
+ * Mailbox IGU1 Interrupt
+ */
+#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
+
+
+
+#endif // IFXMIPS_ATM_PPE_VR9_H
diff --git a/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_vr9.c b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_vr9.c
new file mode 100644
index 0000000000..89c71e37e6
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ifxmips_atm_vr9.c
@@ -0,0 +1,190 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_vr9.c
+** PROJECT : UEIP
+** MODULES : ATM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM driver common source file (core functions)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+/*
+ * ####################################
+ * Head File
+ * ####################################
+ */
+
+/*
+ * Common Head File
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <asm/delay.h>
+
+#include "ifxmips_atm_core.h"
+#include "ifxmips_atm_fw_vr9.h"
+
+#ifdef CONFIG_VR9
+
+#include <lantiq_soc.h>
+
+#define IFX_PMU_MODULE_PPE_SLL01 BIT(19)
+#define IFX_PMU_MODULE_PPE_TC BIT(21)
+#define IFX_PMU_MODULE_PPE_EMA BIT(22)
+#define IFX_PMU_MODULE_PPE_QSB BIT(18)
+#define IFX_PMU_MODULE_AHBS BIT(13)
+#define IFX_PMU_MODULE_DSL_DFE BIT(9)
+
+static inline void vr9_reset_ppe(void)
+{
+/*#ifdef MODULE
+ // reset PPE
+ ifx_rcu_rst(IFX_RCU_DOMAIN_DSLDFE, IFX_RCU_MODULE_ATM);
+ udelay(1000);
+ ifx_rcu_rst(IFX_RCU_DOMAIN_DSLTC, IFX_RCU_MODULE_ATM);
+ udelay(1000);
+ ifx_rcu_rst(IFX_RCU_DOMAIN_PPE, IFX_RCU_MODULE_ATM);
+ udelay(1000);
+ *PP32_SRST &= ~0x000303CF;
+ udelay(1000);
+ *PP32_SRST |= 0x000303CF;
+ udelay(1000);
+#endif*/
+}
+
+static inline int vr9_pp32_download_code(int pp32, u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
+{
+ unsigned int clr, set;
+ volatile u32 *dest;
+
+ if ( code_src == 0 || ((unsigned long)code_src & 0x03) != 0
+ || data_src == 0 || ((unsigned long)data_src & 0x03) != 0 )
+ return -1;
+
+ clr = pp32 ? 0xF0 : 0x0F;
+ if ( code_dword_len <= CDM_CODE_MEMORYn_DWLEN(0) )
+ set = pp32 ? (3 << 6): (2 << 2);
+ else
+ set = 0x00;
+ IFX_REG_W32_MASK(clr, set, CDM_CFG);
+
+ dest = CDM_CODE_MEMORY(pp32, 0);
+ while ( code_dword_len-- > 0 )
+ IFX_REG_W32(*code_src++, dest++);
+
+ dest = CDM_DATA_MEMORY(pp32, 0);
+ while ( data_dword_len-- > 0 )
+ IFX_REG_W32(*data_src++, dest++);
+
+ return 0;
+}
+
+static void vr9_fw_ver(unsigned int *major, unsigned int *minor)
+{
+
+ *major = FW_VER_ID->major;
+ *minor = FW_VER_ID->minor;
+}
+
+static void vr9_init(void)
+{
+ volatile u32 *p;
+ unsigned int i;
+
+ /* setup pmu */
+ ltq_pmu_enable(IFX_PMU_MODULE_PPE_SLL01 |
+ IFX_PMU_MODULE_PPE_TC |
+ IFX_PMU_MODULE_PPE_EMA |
+ IFX_PMU_MODULE_PPE_QSB |
+ IFX_PMU_MODULE_AHBS |
+ IFX_PMU_MODULE_DSL_DFE);
+
+ vr9_reset_ppe();
+
+ /* pdma init */
+ IFX_REG_W32(0x08, PDMA_CFG);
+ IFX_REG_W32(0x00203580, SAR_PDMA_RX_CMDBUF_CFG);
+ IFX_REG_W32(0x004035A0, SAR_PDMA_RX_FW_CMDBUF_CFG);
+
+ /* mailbox init */
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU1_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU1_IER);
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU3_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU3_IER);
+
+ /* tc init - clear sync state */
+ *SFSM_STATE0 = 0;
+ *SFSM_STATE1 = 0;
+
+ /* init shared buffer */
+ p = SB_RAM0_ADDR(0);
+ for ( i = 0; i < SB_RAM0_DWLEN + SB_RAM1_DWLEN + SB_RAM2_DWLEN + SB_RAM3_DWLEN; i++ )
+ IFX_REG_W32(0, p++);
+
+ p = SB_RAM6_ADDR(0);
+ for ( i = 0; i < SB_RAM6_DWLEN; i++ )
+ IFX_REG_W32(0, p++);
+}
+
+static void vr9_shutdown(void)
+{
+}
+
+static int vr9_start(int pp32)
+{
+ unsigned int mask = 1 << (pp32 << 4);
+ int ret;
+
+ /* download firmware */
+ ret = vr9_pp32_download_code(pp32,
+ vr9_fw_bin, sizeof(vr9_fw_bin) / sizeof(*vr9_fw_bin),
+ vr9_fw_data, sizeof(vr9_fw_data) / sizeof(*vr9_fw_data));
+ if ( ret != 0 )
+ return ret;
+
+ /* run PP32 */
+ IFX_REG_W32_MASK(mask, 0, PP32_FREEZE);
+
+ /* idle for a while to let PP32 init itself */
+ udelay(10);
+
+ return 0;
+}
+
+static void vr9_stop(int pp32)
+{
+ unsigned int mask = 1 << (pp32 << 4);
+
+ IFX_REG_W32_MASK(0, mask, PP32_FREEZE);
+}
+
+struct ltq_atm_ops vr9_ops = {
+ .init = vr9_init,
+ .shutdown = vr9_shutdown,
+ .start = vr9_start,
+ .stop = vr9_stop,
+ .fw_ver = vr9_fw_ver,
+};
+
+#endif
diff --git a/package/kernel/lantiq/ltq-atm/src/ltq_atm.c b/package/kernel/lantiq/ltq-atm/src/ltq_atm.c
new file mode 100644
index 0000000000..8466510c6b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ltq_atm.c
@@ -0,0 +1,1913 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_atm_core.c
+** PROJECT : UEIP
+** MODULES : ATM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : ATM driver common source file (core functions)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+#define IFX_ATM_VER_MAJOR 1
+#define IFX_ATM_VER_MID 0
+#define IFX_ATM_VER_MINOR 26
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/atmdev.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/atm.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#ifdef CONFIG_XFRM
+ #include <net/xfrm.h>
+#endif
+
+#include <lantiq_soc.h>
+
+#include "ifxmips_atm_core.h"
+
+#define MODULE_PARM_ARRAY(a, b) module_param_array(a, int, NULL, 0)
+#define MODULE_PARM(a, b) module_param(a, int, 0)
+
+/*!
+ \brief QSB cell delay variation due to concurrency
+ */
+static int qsb_tau = 1; /* QSB cell delay variation due to concurrency */
+/*!
+ \brief QSB scheduler burst length
+ */
+static int qsb_srvm = 0x0F; /* QSB scheduler burst length */
+/*!
+ \brief QSB time step, all legal values are 1, 2, 4
+ */
+static int qsb_tstep = 4 ; /* QSB time step, all legal values are 1, 2, 4 */
+
+/*!
+ \brief Write descriptor delay
+ */
+static int write_descriptor_delay = 0x20; /* Write descriptor delay */
+
+/*!
+ \brief AAL5 padding byte ('~')
+ */
+static int aal5_fill_pattern = 0x007E; /* AAL5 padding byte ('~') */
+/*!
+ \brief Max frame size for RX
+ */
+static int aal5r_max_packet_size = 0x0700; /* Max frame size for RX */
+/*!
+ \brief Min frame size for RX
+ */
+static int aal5r_min_packet_size = 0x0000; /* Min frame size for RX */
+/*!
+ \brief Max frame size for TX
+ */
+static int aal5s_max_packet_size = 0x0700; /* Max frame size for TX */
+/*!
+ \brief Min frame size for TX
+ */
+static int aal5s_min_packet_size = 0x0000; /* Min frame size for TX */
+/*!
+ \brief Drop error packet in RX path
+ */
+static int aal5r_drop_error_packet = 1; /* Drop error packet in RX path */
+
+/*!
+ \brief Number of descriptors per DMA RX channel
+ */
+static int dma_rx_descriptor_length = 128; /* Number of descriptors per DMA RX channel */
+/*!
+ \brief Number of descriptors per DMA TX channel
+ */
+static int dma_tx_descriptor_length = 64; /* Number of descriptors per DMA TX channel */
+/*!
+ \brief PPE core clock cycles between descriptor write and effectiveness in external RAM
+ */
+static int dma_rx_clp1_descriptor_threshold = 38;
+/*@}*/
+
+MODULE_PARM(qsb_tau, "i");
+MODULE_PARM_DESC(qsb_tau, "Cell delay variation. Value must be > 0");
+MODULE_PARM(qsb_srvm, "i");
+MODULE_PARM_DESC(qsb_srvm, "Maximum burst size");
+MODULE_PARM(qsb_tstep, "i");
+MODULE_PARM_DESC(qsb_tstep, "n*32 cycles per sbs cycles n=1,2,4");
+
+MODULE_PARM(write_descriptor_delay, "i");
+MODULE_PARM_DESC(write_descriptor_delay, "PPE core clock cycles between descriptor write and effectiveness in external RAM");
+
+MODULE_PARM(aal5_fill_pattern, "i");
+MODULE_PARM_DESC(aal5_fill_pattern, "Filling pattern (PAD) for AAL5 frames");
+MODULE_PARM(aal5r_max_packet_size, "i");
+MODULE_PARM_DESC(aal5r_max_packet_size, "Max packet size in byte for downstream AAL5 frames");
+MODULE_PARM(aal5r_min_packet_size, "i");
+MODULE_PARM_DESC(aal5r_min_packet_size, "Min packet size in byte for downstream AAL5 frames");
+MODULE_PARM(aal5s_max_packet_size, "i");
+MODULE_PARM_DESC(aal5s_max_packet_size, "Max packet size in byte for upstream AAL5 frames");
+MODULE_PARM(aal5s_min_packet_size, "i");
+MODULE_PARM_DESC(aal5s_min_packet_size, "Min packet size in byte for upstream AAL5 frames");
+MODULE_PARM(aal5r_drop_error_packet, "i");
+MODULE_PARM_DESC(aal5r_drop_error_packet, "Non-zero value to drop error packet for downstream");
+
+MODULE_PARM(dma_rx_descriptor_length, "i");
+MODULE_PARM_DESC(dma_rx_descriptor_length, "Number of descriptor assigned to DMA RX channel (>16)");
+MODULE_PARM(dma_tx_descriptor_length, "i");
+MODULE_PARM_DESC(dma_tx_descriptor_length, "Number of descriptor assigned to DMA TX channel (>16)");
+MODULE_PARM(dma_rx_clp1_descriptor_threshold, "i");
+MODULE_PARM_DESC(dma_rx_clp1_descriptor_threshold, "Descriptor threshold for cells with cell loss priority 1");
+
+
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+#ifdef CONFIG_AMAZON_SE
+ #define ENABLE_LESS_CACHE_INV 1
+ #define LESS_CACHE_INV_LEN 96
+#endif
+
+#define DUMP_SKB_LEN ~0
+
+
+
+/*
+ * ####################################
+ * Declaration
+ * ####################################
+ */
+
+/*
+ * Network Operations
+ */
+static int ppe_ioctl(struct atm_dev *, unsigned int, void *);
+static int ppe_open(struct atm_vcc *);
+static void ppe_close(struct atm_vcc *);
+static int ppe_send(struct atm_vcc *, struct sk_buff *);
+static int ppe_send_oam(struct atm_vcc *, void *, int);
+static int ppe_change_qos(struct atm_vcc *, struct atm_qos *, int);
+
+/*
+ * ADSL LED
+ */
+static inline void adsl_led_flash(void);
+
+/*
+ * 64-bit operation used by MIB calculation
+ */
+static inline void u64_add_u32(ppe_u64_t, unsigned int, ppe_u64_t *);
+
+/*
+ * buffer manage functions
+ */
+static inline struct sk_buff* alloc_skb_rx(void);
+static inline struct sk_buff* alloc_skb_tx(unsigned int);
+struct sk_buff* atm_alloc_tx(struct atm_vcc *, unsigned int);
+static inline void atm_free_tx_skb_vcc(struct sk_buff *, struct atm_vcc *);
+static inline struct sk_buff *get_skb_rx_pointer(unsigned int);
+static inline int get_tx_desc(unsigned int);
+static struct sk_buff* skb_duplicate(struct sk_buff *);
+static struct sk_buff* skb_break_away_from_protocol(struct sk_buff *);
+
+/*
+ * mailbox handler and signal function
+ */
+static inline void mailbox_oam_rx_handler(void);
+static inline void mailbox_aal_rx_handler(void);
+static irqreturn_t mailbox_irq_handler(int, void *);
+static inline void mailbox_signal(unsigned int, int);
+static void do_ppe_tasklet(unsigned long);
+DECLARE_TASKLET(g_dma_tasklet, do_ppe_tasklet, 0);
+
+/*
+ * QSB & HTU setting functions
+ */
+static void set_qsb(struct atm_vcc *, struct atm_qos *, unsigned int);
+static void qsb_global_set(void);
+static inline void set_htu_entry(unsigned int, unsigned int, unsigned int, int, int);
+static inline void clear_htu_entry(unsigned int);
+static void validate_oam_htu_entry(void);
+static void invalidate_oam_htu_entry(void);
+
+/*
+ * look up for connection ID
+ */
+static inline int find_vpi(unsigned int);
+static inline int find_vpivci(unsigned int, unsigned int);
+static inline int find_vcc(struct atm_vcc *);
+
+static inline int ifx_atm_version(const struct ltq_atm_ops *ops, char *);
+
+/*
+ * Init & clean-up functions
+ */
+static inline void check_parameters(void);
+static inline int init_priv_data(void);
+static inline void clear_priv_data(void);
+static inline void init_rx_tables(void);
+static inline void init_tx_tables(void);
+
+/*
+ * Exteranl Function
+ */
+#if defined(CONFIG_IFX_OAM) || defined(CONFIG_IFX_OAM_MODULE)
+extern void ifx_push_oam(unsigned char *);
+#else
+static inline void ifx_push_oam(unsigned char *dummy) {}
+#endif
+
+#if defined(CONFIG_IFXMIPS_DSL_CPE_MEI) || defined(CONFIG_IFXMIPS_DSL_CPE_MEI_MODULE)
+extern int ifx_mei_atm_showtime_check(int *is_showtime, struct port_cell_info *port_cell, void **xdata_addr);
+extern int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *);
+
+extern int (*ifx_mei_atm_showtime_exit)(void);
+extern int ifx_mei_atm_led_blink(void);
+#else
+static inline int ifx_mei_atm_led_blink(void) { return 0; }
+static inline int ifx_mei_atm_showtime_check(int *is_showtime, struct port_cell_info *port_cell, void **xdata_addr)
+{
+ if ( is_showtime != NULL )
+ *is_showtime = 0;
+ return 0;
+}
+int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *) = NULL;
+EXPORT_SYMBOL(ifx_mei_atm_showtime_enter);
+
+int (*ifx_mei_atm_showtime_exit)(void) = NULL;
+EXPORT_SYMBOL(ifx_mei_atm_showtime_exit);
+
+#endif
+
+static struct sk_buff* (*ifx_atm_alloc_tx)(struct atm_vcc *, unsigned int) = NULL;
+
+static struct atm_priv_data g_atm_priv_data;
+
+static struct atmdev_ops g_ifx_atm_ops = {
+ .open = ppe_open,
+ .close = ppe_close,
+ .ioctl = ppe_ioctl,
+ .send = ppe_send,
+ .send_oam = ppe_send_oam,
+ .change_qos = ppe_change_qos,
+ .owner = THIS_MODULE,
+};
+
+static int g_showtime = 0;
+static void *g_xdata_addr = NULL;
+
+static int ppe_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)
+{
+ int ret = 0;
+ atm_cell_ifEntry_t mib_cell;
+ atm_aal5_ifEntry_t mib_aal5;
+ atm_aal5_vcc_x_t mib_vcc;
+ unsigned int value;
+ int conn;
+
+ if ( _IOC_TYPE(cmd) != PPE_ATM_IOC_MAGIC
+ || _IOC_NR(cmd) >= PPE_ATM_IOC_MAXNR )
+ return -ENOTTY;
+
+ if ( _IOC_DIR(cmd) & _IOC_READ )
+ ret = !access_ok(VERIFY_WRITE, arg, _IOC_SIZE(cmd));
+ else if ( _IOC_DIR(cmd) & _IOC_WRITE )
+ ret = !access_ok(VERIFY_READ, arg, _IOC_SIZE(cmd));
+ if ( ret )
+ return -EFAULT;
+
+ switch (cmd) {
+ case PPE_ATM_MIB_CELL: /* cell level MIB */
+ /* These MIB should be read at ARC side, now put zero only. */
+ mib_cell.ifHCInOctets_h = 0;
+ mib_cell.ifHCInOctets_l = 0;
+ mib_cell.ifHCOutOctets_h = 0;
+ mib_cell.ifHCOutOctets_l = 0;
+ mib_cell.ifInErrors = 0;
+ mib_cell.ifInUnknownProtos = WAN_MIB_TABLE->wrx_drophtu_cell;
+ mib_cell.ifOutErrors = 0;
+
+ ret = sizeof(mib_cell) - copy_to_user(arg, &mib_cell, sizeof(mib_cell));
+ break;
+
+ case PPE_ATM_MIB_AAL5: /* AAL5 MIB */
+ value = WAN_MIB_TABLE->wrx_total_byte;
+ u64_add_u32(g_atm_priv_data.wrx_total_byte, value - g_atm_priv_data.prev_wrx_total_byte, &g_atm_priv_data.wrx_total_byte);
+ g_atm_priv_data.prev_wrx_total_byte = value;
+ mib_aal5.ifHCInOctets_h = g_atm_priv_data.wrx_total_byte.h;
+ mib_aal5.ifHCInOctets_l = g_atm_priv_data.wrx_total_byte.l;
+
+ value = WAN_MIB_TABLE->wtx_total_byte;
+ u64_add_u32(g_atm_priv_data.wtx_total_byte, value - g_atm_priv_data.prev_wtx_total_byte, &g_atm_priv_data.wtx_total_byte);
+ g_atm_priv_data.prev_wtx_total_byte = value;
+ mib_aal5.ifHCOutOctets_h = g_atm_priv_data.wtx_total_byte.h;
+ mib_aal5.ifHCOutOctets_l = g_atm_priv_data.wtx_total_byte.l;
+
+ mib_aal5.ifInUcastPkts = g_atm_priv_data.wrx_pdu;
+ mib_aal5.ifOutUcastPkts = WAN_MIB_TABLE->wtx_total_pdu;
+ mib_aal5.ifInErrors = WAN_MIB_TABLE->wrx_err_pdu;
+ mib_aal5.ifInDiscards = WAN_MIB_TABLE->wrx_dropdes_pdu + g_atm_priv_data.wrx_drop_pdu;
+ mib_aal5.ifOutErros = g_atm_priv_data.wtx_err_pdu;
+ mib_aal5.ifOutDiscards = g_atm_priv_data.wtx_drop_pdu;
+
+ ret = sizeof(mib_aal5) - copy_to_user(arg, &mib_aal5, sizeof(mib_aal5));
+ break;
+
+ case PPE_ATM_MIB_VCC: /* VCC related MIB */
+ copy_from_user(&mib_vcc, arg, sizeof(mib_vcc));
+ conn = find_vpivci(mib_vcc.vpi, mib_vcc.vci);
+ if (conn >= 0) {
+ mib_vcc.mib_vcc.aal5VccCrcErrors = g_atm_priv_data.conn[conn].aal5_vcc_crc_err;
+ mib_vcc.mib_vcc.aal5VccOverSizedSDUs = g_atm_priv_data.conn[conn].aal5_vcc_oversize_sdu;
+ mib_vcc.mib_vcc.aal5VccSarTimeOuts = 0; /* no timer support */
+ ret = sizeof(mib_vcc) - copy_to_user(arg, &mib_vcc, sizeof(mib_vcc));
+ } else
+ ret = -EINVAL;
+ break;
+
+ default:
+ ret = -ENOIOCTLCMD;
+ }
+
+ return ret;
+}
+
+static int ppe_open(struct atm_vcc *vcc)
+{
+ int ret;
+ short vpi = vcc->vpi;
+ int vci = vcc->vci;
+ struct port *port = &g_atm_priv_data.port[(int)vcc->dev->dev_data];
+ int conn;
+ int f_enable_irq = 0;
+
+ if ( vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0 )
+ return -EPROTONOSUPPORT;
+
+#if !defined(DISABLE_QOS_WORKAROUND) || !DISABLE_QOS_WORKAROUND
+ /* check bandwidth */
+ if ( (vcc->qos.txtp.traffic_class == ATM_CBR && vcc->qos.txtp.max_pcr > (port->tx_max_cell_rate - port->tx_current_cell_rate))
+ || (vcc->qos.txtp.traffic_class == ATM_VBR_RT && vcc->qos.txtp.max_pcr > (port->tx_max_cell_rate - port->tx_current_cell_rate))
+ || (vcc->qos.txtp.traffic_class == ATM_VBR_NRT && vcc->qos.txtp.scr > (port->tx_max_cell_rate - port->tx_current_cell_rate))
+ || (vcc->qos.txtp.traffic_class == ATM_UBR_PLUS && vcc->qos.txtp.min_pcr > (port->tx_max_cell_rate - port->tx_current_cell_rate)) )
+ {
+ ret = -EINVAL;
+ goto PPE_OPEN_EXIT;
+ }
+#endif
+
+ /* check existing vpi,vci */
+ conn = find_vpivci(vpi, vci);
+ if ( conn >= 0 ) {
+ ret = -EADDRINUSE;
+ goto PPE_OPEN_EXIT;
+ }
+
+ /* check whether it need to enable irq */
+ if ( g_atm_priv_data.conn_table == 0 )
+ f_enable_irq = 1;
+
+ /* allocate connection */
+ for ( conn = 0; conn < MAX_PVC_NUMBER; conn++ ) {
+ if ( test_and_set_bit(conn, &g_atm_priv_data.conn_table) == 0 ) {
+ g_atm_priv_data.conn[conn].vcc = vcc;
+ break;
+ }
+ }
+ if ( conn == MAX_PVC_NUMBER ) {
+ ret = -EINVAL;
+ goto PPE_OPEN_EXIT;
+ }
+
+ /* reserve bandwidth */
+ switch ( vcc->qos.txtp.traffic_class ) {
+ case ATM_CBR:
+ case ATM_VBR_RT:
+ port->tx_current_cell_rate += vcc->qos.txtp.max_pcr;
+ break;
+ case ATM_VBR_NRT:
+ port->tx_current_cell_rate += vcc->qos.txtp.scr;
+ break;
+ case ATM_UBR_PLUS:
+ port->tx_current_cell_rate += vcc->qos.txtp.min_pcr;
+ break;
+ }
+
+ /* set qsb */
+ set_qsb(vcc, &vcc->qos, conn);
+
+ /* update atm_vcc structure */
+ vcc->itf = (int)vcc->dev->dev_data;
+ vcc->vpi = vpi;
+ vcc->vci = vci;
+ set_bit(ATM_VF_READY, &vcc->flags);
+
+ /* enable irq */
+ if ( f_enable_irq ) {
+ ifx_atm_alloc_tx = atm_alloc_tx;
+
+ *MBOX_IGU1_ISRC = (1 << RX_DMA_CH_AAL) | (1 << RX_DMA_CH_OAM);
+ *MBOX_IGU1_IER = (1 << RX_DMA_CH_AAL) | (1 << RX_DMA_CH_OAM);
+
+ enable_irq(PPE_MAILBOX_IGU1_INT);
+ }
+
+ /* set port */
+ WTX_QUEUE_CONFIG(conn + FIRST_QSB_QID)->sbid = (int)vcc->dev->dev_data;
+
+ /* set htu entry */
+ set_htu_entry(vpi, vci, conn, vcc->qos.aal == ATM_AAL5 ? 1 : 0, 0);
+
+ ret = 0;
+
+PPE_OPEN_EXIT:
+ return ret;
+}
+
+static void ppe_close(struct atm_vcc *vcc)
+{
+ int conn;
+ struct port *port;
+ struct connection *connection;
+ if ( vcc == NULL )
+ return;
+
+ /* get connection id */
+ conn = find_vcc(vcc);
+ if ( conn < 0 ) {
+ pr_err("can't find vcc\n");
+ goto PPE_CLOSE_EXIT;
+ }
+ connection = &g_atm_priv_data.conn[conn];
+ port = &g_atm_priv_data.port[connection->port];
+
+ /* clear htu */
+ clear_htu_entry(conn);
+
+ /* release connection */
+ connection->vcc = NULL;
+ connection->aal5_vcc_crc_err = 0;
+ connection->aal5_vcc_oversize_sdu = 0;
+ clear_bit(conn, &g_atm_priv_data.conn_table);
+
+ /* disable irq */
+ if ( g_atm_priv_data.conn_table == 0 ) {
+ disable_irq(PPE_MAILBOX_IGU1_INT);
+ ifx_atm_alloc_tx = NULL;
+ }
+
+ /* release bandwidth */
+ switch ( vcc->qos.txtp.traffic_class )
+ {
+ case ATM_CBR:
+ case ATM_VBR_RT:
+ port->tx_current_cell_rate -= vcc->qos.txtp.max_pcr;
+ break;
+ case ATM_VBR_NRT:
+ port->tx_current_cell_rate -= vcc->qos.txtp.scr;
+ break;
+ case ATM_UBR_PLUS:
+ port->tx_current_cell_rate -= vcc->qos.txtp.min_pcr;
+ break;
+ }
+
+ /* wait for incoming packets to be processed by upper layers */
+ tasklet_unlock_wait(&g_dma_tasklet);
+
+PPE_CLOSE_EXIT:
+ return;
+}
+
+static int ppe_send(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+ int ret;
+ int conn;
+ int desc_base;
+ struct tx_descriptor reg_desc = {0};
+ struct sk_buff *new_skb;
+
+ if ( vcc == NULL || skb == NULL )
+ return -EINVAL;
+
+ skb_get(skb);
+ atm_free_tx_skb_vcc(skb, vcc);
+
+ conn = find_vcc(vcc);
+ if ( conn < 0 ) {
+ ret = -EINVAL;
+ goto FIND_VCC_FAIL;
+ }
+
+ if ( !g_showtime ) {
+ pr_debug("not in showtime\n");
+ ret = -EIO;
+ goto PPE_SEND_FAIL;
+ }
+
+ if ( vcc->qos.aal == ATM_AAL5 ) {
+ int byteoff;
+ int datalen;
+ struct tx_inband_header *header;
+
+ byteoff = (unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1);
+ if ( skb_headroom(skb) < byteoff + TX_INBAND_HEADER_LENGTH )
+ new_skb = skb_duplicate(skb);
+ else
+ new_skb = skb_break_away_from_protocol(skb);
+ if ( new_skb == NULL ) {
+ pr_err("either skb_duplicate or skb_break_away_from_protocol fail\n");
+ ret = -ENOMEM;
+ goto PPE_SEND_FAIL;
+ }
+ dev_kfree_skb_any(skb);
+ skb = new_skb;
+
+ datalen = skb->len;
+ byteoff = (unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1);
+
+ skb_push(skb, byteoff + TX_INBAND_HEADER_LENGTH);
+
+ header = (struct tx_inband_header *)skb->data;
+
+ /* setup inband trailer */
+ header->uu = 0;
+ header->cpi = 0;
+ header->pad = aal5_fill_pattern;
+ header->res1 = 0;
+
+ /* setup cell header */
+ header->clp = (vcc->atm_options & ATM_ATMOPT_CLP) ? 1 : 0;
+ header->pti = ATM_PTI_US0;
+ header->vci = vcc->vci;
+ header->vpi = vcc->vpi;
+ header->gfc = 0;
+
+ /* setup descriptor */
+ reg_desc.dataptr = (unsigned int)skb->data >> 2;
+ reg_desc.datalen = datalen;
+ reg_desc.byteoff = byteoff;
+ reg_desc.iscell = 0;
+ } else {
+ /* if data pointer is not aligned, allocate new sk_buff */
+ if ( ((unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1)) != 0 ) {
+ pr_err("skb->data not aligned\n");
+ new_skb = skb_duplicate(skb);
+ } else
+ new_skb = skb_break_away_from_protocol(skb);
+ if ( new_skb == NULL ) {
+ pr_err("either skb_duplicate or skb_break_away_from_protocol fail\n");
+ ret = -ENOMEM;
+ goto PPE_SEND_FAIL;
+ }
+ dev_kfree_skb_any(skb);
+ skb = new_skb;
+
+ reg_desc.dataptr = (unsigned int)skb->data >> 2;
+ reg_desc.datalen = skb->len;
+ reg_desc.byteoff = 0;
+ reg_desc.iscell = 1;
+ }
+
+ reg_desc.own = 1;
+ reg_desc.c = 1;
+ reg_desc.sop = reg_desc.eop = 1;
+
+ desc_base = get_tx_desc(conn);
+ if ( desc_base < 0 ) {
+ pr_debug("ALLOC_TX_CONNECTION_FAIL\n");
+ ret = -EIO;
+ goto PPE_SEND_FAIL;
+ }
+
+ if ( vcc->stats )
+ atomic_inc(&vcc->stats->tx);
+ if ( vcc->qos.aal == ATM_AAL5 )
+ g_atm_priv_data.wtx_pdu++;
+
+ /* update descriptor send pointer */
+ if ( g_atm_priv_data.conn[conn].tx_skb[desc_base] != NULL )
+ dev_kfree_skb_any(g_atm_priv_data.conn[conn].tx_skb[desc_base]);
+ g_atm_priv_data.conn[conn].tx_skb[desc_base] = skb;
+
+ /* write discriptor to memory and write back cache */
+ g_atm_priv_data.conn[conn].tx_desc[desc_base] = reg_desc;
+ dma_cache_wback((unsigned long)skb->data, skb->len);
+
+ mailbox_signal(conn, 1);
+
+ adsl_led_flash();
+
+ return 0;
+
+FIND_VCC_FAIL:
+ pr_err("FIND_VCC_FAIL\n");
+ g_atm_priv_data.wtx_err_pdu++;
+ dev_kfree_skb_any(skb);
+ return ret;
+
+PPE_SEND_FAIL:
+ if ( vcc->qos.aal == ATM_AAL5 )
+ g_atm_priv_data.wtx_drop_pdu++;
+ if ( vcc->stats )
+ atomic_inc(&vcc->stats->tx_err);
+ dev_kfree_skb_any(skb);
+ return ret;
+}
+
+/* operation and maintainance */
+static int ppe_send_oam(struct atm_vcc *vcc, void *cell, int flags)
+{
+ int conn;
+ struct uni_cell_header *uni_cell_header = (struct uni_cell_header *)cell;
+ int desc_base;
+ struct sk_buff *skb;
+ struct tx_descriptor reg_desc = {0};
+
+ if ( ((uni_cell_header->pti == ATM_PTI_SEGF5 || uni_cell_header->pti == ATM_PTI_E2EF5)
+ && find_vpivci(uni_cell_header->vpi, uni_cell_header->vci) < 0)
+ || ((uni_cell_header->vci == 0x03 || uni_cell_header->vci == 0x04)
+ && find_vpi(uni_cell_header->vpi) < 0) )
+ {
+ g_atm_priv_data.wtx_err_oam++;
+ return -EINVAL;
+ }
+
+ if ( !g_showtime ) {
+ pr_err("not in showtime\n");
+ g_atm_priv_data.wtx_drop_oam++;
+ return -EIO;
+ }
+
+ conn = find_vcc(vcc);
+ if ( conn < 0 ) {
+ pr_err("FIND_VCC_FAIL\n");
+ g_atm_priv_data.wtx_drop_oam++;
+ return -EINVAL;
+ }
+
+ skb = alloc_skb_tx(CELL_SIZE);
+ if ( skb == NULL ) {
+ pr_err("ALLOC_SKB_TX_FAIL\n");
+ g_atm_priv_data.wtx_drop_oam++;
+ return -ENOMEM;
+ }
+ skb_put(skb, CELL_SIZE);
+ memcpy(skb->data, cell, CELL_SIZE);
+
+ reg_desc.dataptr = (unsigned int)skb->data >> 2;
+ reg_desc.datalen = CELL_SIZE;
+ reg_desc.byteoff = 0;
+ reg_desc.iscell = 1;
+
+ reg_desc.own = 1;
+ reg_desc.c = 1;
+ reg_desc.sop = reg_desc.eop = 1;
+
+ desc_base = get_tx_desc(conn);
+ if ( desc_base < 0 ) {
+ dev_kfree_skb_any(skb);
+ pr_err("ALLOC_TX_CONNECTION_FAIL\n");
+ g_atm_priv_data.wtx_drop_oam++;
+ return -EIO;
+ }
+
+ if ( vcc->stats )
+ atomic_inc(&vcc->stats->tx);
+
+ /* update descriptor send pointer */
+ if ( g_atm_priv_data.conn[conn].tx_skb[desc_base] != NULL )
+ dev_kfree_skb_any(g_atm_priv_data.conn[conn].tx_skb[desc_base]);
+ g_atm_priv_data.conn[conn].tx_skb[desc_base] = skb;
+
+ /* write discriptor to memory and write back cache */
+ g_atm_priv_data.conn[conn].tx_desc[desc_base] = reg_desc;
+ dma_cache_wback((unsigned long)skb->data, CELL_SIZE);
+
+ mailbox_signal(conn, 1);
+
+ g_atm_priv_data.wtx_oam++;
+ adsl_led_flash();
+
+ return 0;
+}
+
+static int ppe_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)
+{
+ int conn;
+
+ if ( vcc == NULL || qos == NULL )
+ return -EINVAL;
+
+ conn = find_vcc(vcc);
+ if ( conn < 0 )
+ return -EINVAL;
+
+ set_qsb(vcc, qos, conn);
+
+ return 0;
+}
+
+static inline void adsl_led_flash(void)
+{
+ ifx_mei_atm_led_blink();
+}
+
+/*
+* Description:
+* Add a 32-bit value to 64-bit value, and put result in a 64-bit variable.
+* Input:
+* opt1 --- ppe_u64_t, first operand, a 64-bit unsigned integer value
+* opt2 --- unsigned int, second operand, a 32-bit unsigned integer value
+* ret --- ppe_u64_t, pointer to a variable to hold result
+* Output:
+* none
+*/
+static inline void u64_add_u32(ppe_u64_t opt1, unsigned int opt2, ppe_u64_t *ret)
+{
+ ret->l = opt1.l + opt2;
+ if ( ret->l < opt1.l || ret->l < opt2 )
+ ret->h++;
+}
+
+static inline struct sk_buff* alloc_skb_rx(void)
+{
+ struct sk_buff *skb;
+
+ skb = dev_alloc_skb(RX_DMA_CH_AAL_BUF_SIZE + DATA_BUFFER_ALIGNMENT);
+ if ( skb != NULL ) {
+ /* must be burst length alignment */
+ if ( ((unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1)) != 0 )
+ skb_reserve(skb, ~((unsigned int)skb->data + (DATA_BUFFER_ALIGNMENT - 1)) & (DATA_BUFFER_ALIGNMENT - 1));
+ /* pub skb in reserved area "skb->data - 4" */
+ *((struct sk_buff **)skb->data - 1) = skb;
+ /* write back and invalidate cache */
+ dma_cache_wback_inv((unsigned long)skb->data - sizeof(skb), sizeof(skb));
+ /* invalidate cache */
+#if defined(ENABLE_LESS_CACHE_INV) && ENABLE_LESS_CACHE_INV
+ dma_cache_inv((unsigned long)skb->data, LESS_CACHE_INV_LEN);
+#else
+ dma_cache_inv((unsigned long)skb->data, RX_DMA_CH_AAL_BUF_SIZE);
+#endif
+ }
+ return skb;
+}
+
+static inline struct sk_buff* alloc_skb_tx(unsigned int size)
+{
+ struct sk_buff *skb;
+
+ /* allocate memory including header and padding */
+ size += TX_INBAND_HEADER_LENGTH + MAX_TX_PACKET_ALIGN_BYTES + MAX_TX_PACKET_PADDING_BYTES;
+ size &= ~(DATA_BUFFER_ALIGNMENT - 1);
+ skb = dev_alloc_skb(size + DATA_BUFFER_ALIGNMENT);
+ /* must be burst length alignment */
+ if ( skb != NULL )
+ skb_reserve(skb, (~((unsigned int)skb->data + (DATA_BUFFER_ALIGNMENT - 1)) & (DATA_BUFFER_ALIGNMENT - 1)) + TX_INBAND_HEADER_LENGTH);
+ return skb;
+}
+
+struct sk_buff* atm_alloc_tx(struct atm_vcc *vcc, unsigned int size)
+{
+ int conn;
+ struct sk_buff *skb;
+
+ /* oversize packet */
+ if ( size > aal5s_max_packet_size ) {
+ pr_err("atm_alloc_tx: oversize packet\n");
+ return NULL;
+ }
+ /* send buffer overflow */
+ if ( sk_wmem_alloc_get(sk_atm(vcc)) && !atm_may_send(vcc, size) ) {
+ pr_err("atm_alloc_tx: send buffer overflow\n");
+ return NULL;
+ }
+ conn = find_vcc(vcc);
+ if ( conn < 0 ) {
+ pr_err("atm_alloc_tx: unknown VCC\n");
+ return NULL;
+ }
+
+ skb = dev_alloc_skb(size);
+ if ( skb == NULL ) {
+ pr_err("atm_alloc_tx: sk buffer is used up\n");
+ return NULL;
+ }
+
+ atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
+
+ return skb;
+}
+
+static inline void atm_free_tx_skb_vcc(struct sk_buff *skb, struct atm_vcc *vcc)
+{
+ if ( vcc->pop != NULL )
+ vcc->pop(vcc, skb);
+ else
+ dev_kfree_skb_any(skb);
+}
+
+static inline struct sk_buff *get_skb_rx_pointer(unsigned int dataptr)
+{
+ unsigned int skb_dataptr;
+ struct sk_buff *skb;
+
+ skb_dataptr = ((dataptr - 1) << 2) | KSEG1;
+ skb = *(struct sk_buff **)skb_dataptr;
+
+ ASSERT((unsigned int)skb >= KSEG0, "invalid skb - skb = %#08x, dataptr = %#08x", (unsigned int)skb, dataptr);
+ ASSERT(((unsigned int)skb->data | KSEG1) == ((dataptr << 2) | KSEG1), "invalid skb - skb = %#08x, skb->data = %#08x, dataptr = %#08x", (unsigned int)skb, (unsigned int)skb->data, dataptr);
+
+ return skb;
+}
+
+static inline int get_tx_desc(unsigned int conn)
+{
+ int desc_base = -1;
+ struct connection *p_conn = &g_atm_priv_data.conn[conn];
+
+ if ( p_conn->tx_desc[p_conn->tx_desc_pos].own == 0 ) {
+ desc_base = p_conn->tx_desc_pos;
+ if ( ++(p_conn->tx_desc_pos) == dma_tx_descriptor_length )
+ p_conn->tx_desc_pos = 0;
+ }
+
+ return desc_base;
+}
+
+static struct sk_buff* skb_duplicate(struct sk_buff *skb)
+{
+ struct sk_buff *new_skb;
+
+ new_skb = alloc_skb_tx(skb->len);
+ if ( new_skb == NULL )
+ return NULL;
+
+ skb_put(new_skb, skb->len);
+ memcpy(new_skb->data, skb->data, skb->len);
+
+ return new_skb;
+}
+
+static struct sk_buff* skb_break_away_from_protocol(struct sk_buff *skb)
+{
+ struct sk_buff *new_skb;
+
+ if ( skb_shared(skb) ) {
+ new_skb = skb_clone(skb, GFP_ATOMIC);
+ if ( new_skb == NULL )
+ return NULL;
+ } else
+ new_skb = skb_get(skb);
+
+ skb_dst_drop(new_skb);
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ nf_conntrack_put(new_skb->nfct);
+ new_skb->nfct = NULL;
+ nf_conntrack_put_reasm(new_skb->nfct_reasm);
+ new_skb->nfct_reasm = NULL;
+ #ifdef CONFIG_BRIDGE_NETFILTER
+ nf_bridge_put(new_skb->nf_bridge);
+ new_skb->nf_bridge = NULL;
+ #endif
+#endif
+
+ return new_skb;
+}
+
+static inline void mailbox_oam_rx_handler(void)
+{
+ unsigned int vlddes = WRX_DMA_CHANNEL_CONFIG(RX_DMA_CH_OAM)->vlddes;
+ struct rx_descriptor reg_desc;
+ struct uni_cell_header *header;
+ int conn;
+ struct atm_vcc *vcc;
+ unsigned int i;
+
+ for ( i = 0; i < vlddes; i++ ) {
+ unsigned int loop_count = 0;
+
+ do {
+ reg_desc = g_atm_priv_data.oam_desc[g_atm_priv_data.oam_desc_pos];
+ if ( ++loop_count == 1000 )
+ break;
+ } while ( reg_desc.own || !reg_desc.c ); // keep test OWN and C bit until data is ready
+ ASSERT(loop_count == 1, "loop_count = %u, own = %d, c = %d, oam_desc_pos = %u", loop_count, (int)reg_desc.own, (int)reg_desc.c, g_atm_priv_data.oam_desc_pos);
+
+ header = (struct uni_cell_header *)&g_atm_priv_data.oam_buf[g_atm_priv_data.oam_desc_pos * RX_DMA_CH_OAM_BUF_SIZE];
+
+ if ( header->pti == ATM_PTI_SEGF5 || header->pti == ATM_PTI_E2EF5 )
+ conn = find_vpivci(header->vpi, header->vci);
+ else if ( header->vci == 0x03 || header->vci == 0x04 )
+ conn = find_vpi(header->vpi);
+ else
+ conn = -1;
+
+ if ( conn >= 0 && g_atm_priv_data.conn[conn].vcc != NULL ) {
+ vcc = g_atm_priv_data.conn[conn].vcc;
+
+ if ( vcc->push_oam != NULL )
+ vcc->push_oam(vcc, header);
+ else
+ ifx_push_oam((unsigned char *)header);
+
+ g_atm_priv_data.wrx_oam++;
+
+ adsl_led_flash();
+ } else
+ g_atm_priv_data.wrx_drop_oam++;
+
+ reg_desc.byteoff = 0;
+ reg_desc.datalen = RX_DMA_CH_OAM_BUF_SIZE;
+ reg_desc.own = 1;
+ reg_desc.c = 0;
+
+ g_atm_priv_data.oam_desc[g_atm_priv_data.oam_desc_pos] = reg_desc;
+ if ( ++g_atm_priv_data.oam_desc_pos == RX_DMA_CH_OAM_DESC_LEN )
+ g_atm_priv_data.oam_desc_pos = 0;
+
+ dma_cache_inv((unsigned long)header, CELL_SIZE);
+ mailbox_signal(RX_DMA_CH_OAM, 0);
+ }
+}
+
+static inline void mailbox_aal_rx_handler(void)
+{
+ unsigned int vlddes = WRX_DMA_CHANNEL_CONFIG(RX_DMA_CH_AAL)->vlddes;
+ struct rx_descriptor reg_desc;
+ int conn;
+ struct atm_vcc *vcc;
+ struct sk_buff *skb, *new_skb;
+ struct rx_inband_trailer *trailer;
+ unsigned int i;
+
+ for ( i = 0; i < vlddes; i++ ) {
+ unsigned int loop_count = 0;
+
+ do {
+ reg_desc = g_atm_priv_data.aal_desc[g_atm_priv_data.aal_desc_pos];
+ if ( ++loop_count == 1000 )
+ break;
+ } while ( reg_desc.own || !reg_desc.c ); // keep test OWN and C bit until data is ready
+ ASSERT(loop_count == 1, "loop_count = %u, own = %d, c = %d, aal_desc_pos = %u", loop_count, (int)reg_desc.own, (int)reg_desc.c, g_atm_priv_data.aal_desc_pos);
+
+ conn = reg_desc.id;
+
+ if ( g_atm_priv_data.conn[conn].vcc != NULL ) {
+ vcc = g_atm_priv_data.conn[conn].vcc;
+
+ skb = get_skb_rx_pointer(reg_desc.dataptr);
+
+ if ( reg_desc.err ) {
+ if ( vcc->qos.aal == ATM_AAL5 ) {
+ trailer = (struct rx_inband_trailer *)((unsigned int)skb->data + ((reg_desc.byteoff + reg_desc.datalen + MAX_RX_PACKET_PADDING_BYTES) & ~MAX_RX_PACKET_PADDING_BYTES));
+ if ( trailer->stw_crc )
+ g_atm_priv_data.conn[conn].aal5_vcc_crc_err++;
+ if ( trailer->stw_ovz )
+ g_atm_priv_data.conn[conn].aal5_vcc_oversize_sdu++;
+ g_atm_priv_data.wrx_drop_pdu++;
+ }
+ if ( vcc->stats ) {
+ atomic_inc(&vcc->stats->rx_drop);
+ atomic_inc(&vcc->stats->rx_err);
+ }
+ reg_desc.err = 0;
+ } else if ( atm_charge(vcc, skb->truesize) ) {
+ new_skb = alloc_skb_rx();
+ if ( new_skb != NULL ) {
+#if defined(ENABLE_LESS_CACHE_INV) && ENABLE_LESS_CACHE_INV
+ if ( reg_desc.byteoff + reg_desc.datalen > LESS_CACHE_INV_LEN )
+ dma_cache_inv((unsigned long)skb->data + LESS_CACHE_INV_LEN, reg_desc.byteoff + reg_desc.datalen - LESS_CACHE_INV_LEN);
+#endif
+
+ skb_reserve(skb, reg_desc.byteoff);
+ skb_put(skb, reg_desc.datalen);
+ ATM_SKB(skb)->vcc = vcc;
+
+ vcc->push(vcc, skb);
+
+ if ( vcc->qos.aal == ATM_AAL5 )
+ g_atm_priv_data.wrx_pdu++;
+ if ( vcc->stats )
+ atomic_inc(&vcc->stats->rx);
+ adsl_led_flash();
+
+ reg_desc.dataptr = (unsigned int)new_skb->data >> 2;
+ } else {
+ atm_return(vcc, skb->truesize);
+ if ( vcc->qos.aal == ATM_AAL5 )
+ g_atm_priv_data.wrx_drop_pdu++;
+ if ( vcc->stats )
+ atomic_inc(&vcc->stats->rx_drop);
+ }
+ } else {
+ if ( vcc->qos.aal == ATM_AAL5 )
+ g_atm_priv_data.wrx_drop_pdu++;
+ if ( vcc->stats )
+ atomic_inc(&vcc->stats->rx_drop);
+ }
+ } else {
+ g_atm_priv_data.wrx_drop_pdu++;
+ }
+
+ reg_desc.byteoff = 0;
+ reg_desc.datalen = RX_DMA_CH_AAL_BUF_SIZE;
+ reg_desc.own = 1;
+ reg_desc.c = 0;
+
+ g_atm_priv_data.aal_desc[g_atm_priv_data.aal_desc_pos] = reg_desc;
+ if ( ++g_atm_priv_data.aal_desc_pos == dma_rx_descriptor_length )
+ g_atm_priv_data.aal_desc_pos = 0;
+
+ mailbox_signal(RX_DMA_CH_AAL, 0);
+ }
+}
+
+static void do_ppe_tasklet(unsigned long data)
+{
+ *MBOX_IGU1_ISRC = *MBOX_IGU1_ISR;
+ mailbox_oam_rx_handler();
+ mailbox_aal_rx_handler();
+
+ if ((*MBOX_IGU1_ISR & ((1 << RX_DMA_CH_AAL) | (1 << RX_DMA_CH_OAM))) != 0)
+ tasklet_schedule(&g_dma_tasklet);
+ else
+ enable_irq(PPE_MAILBOX_IGU1_INT);
+}
+
+static irqreturn_t mailbox_irq_handler(int irq, void *dev_id)
+{
+ if ( !*MBOX_IGU1_ISR )
+ return IRQ_HANDLED;
+
+ disable_irq_nosync(PPE_MAILBOX_IGU1_INT);
+ tasklet_schedule(&g_dma_tasklet);
+
+ return IRQ_HANDLED;
+}
+
+static inline void mailbox_signal(unsigned int queue, int is_tx)
+{
+ int count = 1000;
+
+ if ( is_tx ) {
+ while ( MBOX_IGU3_ISR_ISR(queue + FIRST_QSB_QID + 16) && count > 0 )
+ count--;
+ *MBOX_IGU3_ISRS = MBOX_IGU3_ISRS_SET(queue + FIRST_QSB_QID + 16);
+ } else {
+ while ( MBOX_IGU3_ISR_ISR(queue) && count > 0 )
+ count--;
+ *MBOX_IGU3_ISRS = MBOX_IGU3_ISRS_SET(queue);
+ }
+
+ ASSERT(count > 0, "queue = %u, is_tx = %d, MBOX_IGU3_ISR = 0x%08x", queue, is_tx, IFX_REG_R32(MBOX_IGU3_ISR));
+}
+
+static void set_qsb(struct atm_vcc *vcc, struct atm_qos *qos, unsigned int queue)
+{
+ struct clk *fpi_clk = clk_get_fpi();
+ unsigned int qsb_clk = clk_get_rate(fpi_clk);
+ unsigned int qsb_qid = queue + FIRST_QSB_QID;
+ union qsb_queue_parameter_table qsb_queue_parameter_table = {{0}};
+ union qsb_queue_vbr_parameter_table qsb_queue_vbr_parameter_table = {{0}};
+ unsigned int tmp;
+
+
+ /*
+ * Peak Cell Rate (PCR) Limiter
+ */
+ if ( qos->txtp.max_pcr == 0 )
+ qsb_queue_parameter_table.bit.tp = 0; /* disable PCR limiter */
+ else {
+ /* peak cell rate would be slightly lower than requested [maximum_rate / pcr = (qsb_clock / 8) * (time_step / 4) / pcr] */
+ tmp = ((qsb_clk * qsb_tstep) >> 5) / qos->txtp.max_pcr + 1;
+ /* check if overflow takes place */
+ qsb_queue_parameter_table.bit.tp = tmp > QSB_TP_TS_MAX ? QSB_TP_TS_MAX : tmp;
+ }
+
+#if !defined(DISABLE_QOS_WORKAROUND) || !DISABLE_QOS_WORKAROUND
+ // A funny issue. Create two PVCs, one UBR and one UBR with max_pcr.
+ // Send packets to these two PVCs at same time, it trigger strange behavior.
+ // In A1, RAM from 0x80000000 to 0x0x8007FFFF was corrupted with fixed pattern 0x00000000 0x40000000.
+ // In A4, PPE firmware keep emiting unknown cell and do not respond to driver.
+ // To work around, create UBR always with max_pcr.
+ // If user want to create UBR without max_pcr, we give a default one larger than line-rate.
+ if ( qos->txtp.traffic_class == ATM_UBR && qsb_queue_parameter_table.bit.tp == 0 ) {
+ int port = g_atm_priv_data.conn[queue].port;
+ unsigned int max_pcr = g_atm_priv_data.port[port].tx_max_cell_rate + 1000;
+
+ tmp = ((qsb_clk * qsb_tstep) >> 5) / max_pcr + 1;
+ if ( tmp > QSB_TP_TS_MAX )
+ tmp = QSB_TP_TS_MAX;
+ else if ( tmp < 1 )
+ tmp = 1;
+ qsb_queue_parameter_table.bit.tp = tmp;
+ }
+#endif
+
+ /*
+ * Weighted Fair Queueing Factor (WFQF)
+ */
+ switch ( qos->txtp.traffic_class ) {
+ case ATM_CBR:
+ case ATM_VBR_RT:
+ /* real time queue gets weighted fair queueing bypass */
+ qsb_queue_parameter_table.bit.wfqf = 0;
+ break;
+ case ATM_VBR_NRT:
+ case ATM_UBR_PLUS:
+ /* WFQF calculation here is based on virtual cell rates, to reduce granularity for high rates */
+ /* WFQF is maximum cell rate / garenteed cell rate */
+ /* wfqf = qsb_minimum_cell_rate * QSB_WFQ_NONUBR_MAX / requested_minimum_peak_cell_rate */
+ if ( qos->txtp.min_pcr == 0 )
+ qsb_queue_parameter_table.bit.wfqf = QSB_WFQ_NONUBR_MAX;
+ else {
+ tmp = QSB_GCR_MIN * QSB_WFQ_NONUBR_MAX / qos->txtp.min_pcr;
+ if ( tmp == 0 )
+ qsb_queue_parameter_table.bit.wfqf = 1;
+ else if ( tmp > QSB_WFQ_NONUBR_MAX )
+ qsb_queue_parameter_table.bit.wfqf = QSB_WFQ_NONUBR_MAX;
+ else
+ qsb_queue_parameter_table.bit.wfqf = tmp;
+ }
+ break;
+ default:
+ case ATM_UBR:
+ qsb_queue_parameter_table.bit.wfqf = QSB_WFQ_UBR_BYPASS;
+ }
+
+ /*
+ * Sustained Cell Rate (SCR) Leaky Bucket Shaper VBR.0/VBR.1
+ */
+ if ( qos->txtp.traffic_class == ATM_VBR_RT || qos->txtp.traffic_class == ATM_VBR_NRT ) {
+ if ( qos->txtp.scr == 0 ) {
+ /* disable shaper */
+ qsb_queue_vbr_parameter_table.bit.taus = 0;
+ qsb_queue_vbr_parameter_table.bit.ts = 0;
+ } else {
+ /* Cell Loss Priority (CLP) */
+ if ( (vcc->atm_options & ATM_ATMOPT_CLP) )
+ /* CLP1 */
+ qsb_queue_parameter_table.bit.vbr = 1;
+ else
+ /* CLP0 */
+ qsb_queue_parameter_table.bit.vbr = 0;
+ /* Rate Shaper Parameter (TS) and Burst Tolerance Parameter for SCR (tauS) */
+ tmp = ((qsb_clk * qsb_tstep) >> 5) / qos->txtp.scr + 1;
+ qsb_queue_vbr_parameter_table.bit.ts = tmp > QSB_TP_TS_MAX ? QSB_TP_TS_MAX : tmp;
+ tmp = (qos->txtp.mbs - 1) * (qsb_queue_vbr_parameter_table.bit.ts - qsb_queue_parameter_table.bit.tp) / 64;
+ if ( tmp == 0 )
+ qsb_queue_vbr_parameter_table.bit.taus = 1;
+ else if ( tmp > QSB_TAUS_MAX )
+ qsb_queue_vbr_parameter_table.bit.taus = QSB_TAUS_MAX;
+ else
+ qsb_queue_vbr_parameter_table.bit.taus = tmp;
+ }
+ } else {
+ qsb_queue_vbr_parameter_table.bit.taus = 0;
+ qsb_queue_vbr_parameter_table.bit.ts = 0;
+ }
+
+ /* Queue Parameter Table (QPT) */
+ *QSB_RTM = QSB_RTM_DM_SET(QSB_QPT_SET_MASK);
+ *QSB_RTD = QSB_RTD_TTV_SET(qsb_queue_parameter_table.dword);
+ *QSB_RAMAC = QSB_RAMAC_RW_SET(QSB_RAMAC_RW_WRITE) | QSB_RAMAC_TSEL_SET(QSB_RAMAC_TSEL_QPT) | QSB_RAMAC_LH_SET(QSB_RAMAC_LH_LOW) | QSB_RAMAC_TESEL_SET(qsb_qid);
+ /* Queue VBR Paramter Table (QVPT) */
+ *QSB_RTM = QSB_RTM_DM_SET(QSB_QVPT_SET_MASK);
+ *QSB_RTD = QSB_RTD_TTV_SET(qsb_queue_vbr_parameter_table.dword);
+ *QSB_RAMAC = QSB_RAMAC_RW_SET(QSB_RAMAC_RW_WRITE) | QSB_RAMAC_TSEL_SET(QSB_RAMAC_TSEL_VBR) | QSB_RAMAC_LH_SET(QSB_RAMAC_LH_LOW) | QSB_RAMAC_TESEL_SET(qsb_qid);
+
+}
+
+static void qsb_global_set(void)
+{
+ struct clk *fpi_clk = clk_get_fpi();
+ unsigned int qsb_clk = clk_get_rate(fpi_clk);
+ int i;
+ unsigned int tmp1, tmp2, tmp3;
+
+ *QSB_ICDV = QSB_ICDV_TAU_SET(qsb_tau);
+ *QSB_SBL = QSB_SBL_SBL_SET(qsb_srvm);
+ *QSB_CFG = QSB_CFG_TSTEPC_SET(qsb_tstep >> 1);
+
+ /*
+ * set SCT and SPT per port
+ */
+ for ( i = 0; i < ATM_PORT_NUMBER; i++ ) {
+ if ( g_atm_priv_data.port[i].tx_max_cell_rate != 0 ) {
+ tmp1 = ((qsb_clk * qsb_tstep) >> 1) / g_atm_priv_data.port[i].tx_max_cell_rate;
+ tmp2 = tmp1 >> 6; /* integer value of Tsb */
+ tmp3 = (tmp1 & ((1 << 6) - 1)) + 1; /* fractional part of Tsb */
+ /* carry over to integer part (?) */
+ if ( tmp3 == (1 << 6) ) {
+ tmp3 = 0;
+ tmp2++;
+ }
+ if ( tmp2 == 0 )
+ tmp2 = tmp3 = 1;
+ /* 1. set mask */
+ /* 2. write value to data transfer register */
+ /* 3. start the tranfer */
+ /* SCT (FracRate) */
+ *QSB_RTM = QSB_RTM_DM_SET(QSB_SET_SCT_MASK);
+ *QSB_RTD = QSB_RTD_TTV_SET(tmp3);
+ *QSB_RAMAC = QSB_RAMAC_RW_SET(QSB_RAMAC_RW_WRITE) |
+ QSB_RAMAC_TSEL_SET(QSB_RAMAC_TSEL_SCT) |
+ QSB_RAMAC_LH_SET(QSB_RAMAC_LH_LOW) |
+ QSB_RAMAC_TESEL_SET(i & 0x01);
+ /* SPT (SBV + PN + IntRage) */
+ *QSB_RTM = QSB_RTM_DM_SET(QSB_SET_SPT_MASK);
+ *QSB_RTD = QSB_RTD_TTV_SET(QSB_SPT_SBV_VALID | QSB_SPT_PN_SET(i & 0x01) | QSB_SPT_INTRATE_SET(tmp2));
+ *QSB_RAMAC = QSB_RAMAC_RW_SET(QSB_RAMAC_RW_WRITE) |
+ QSB_RAMAC_TSEL_SET(QSB_RAMAC_TSEL_SPT) |
+ QSB_RAMAC_LH_SET(QSB_RAMAC_LH_LOW) |
+ QSB_RAMAC_TESEL_SET(i & 0x01);
+ }
+ }
+}
+
+static inline void set_htu_entry(unsigned int vpi, unsigned int vci, unsigned int queue, int aal5, int is_retx)
+{
+ struct htu_entry htu_entry = {
+ res1: 0x00,
+ clp: is_retx ? 0x01 : 0x00,
+ pid: g_atm_priv_data.conn[queue].port & 0x01,
+ vpi: vpi,
+ vci: vci,
+ pti: 0x00,
+ vld: 0x01};
+
+ struct htu_mask htu_mask = {
+ set: 0x01,
+ clp: 0x01,
+ pid_mask: 0x02,
+ vpi_mask: 0x00,
+ vci_mask: 0x0000,
+ pti_mask: 0x03, // 0xx, user data
+ clear: 0x00};
+
+ struct htu_result htu_result = {
+ res1: 0x00,
+ cellid: queue,
+ res2: 0x00,
+ type: aal5 ? 0x00 : 0x01,
+ ven: 0x01,
+ res3: 0x00,
+ qid: queue};
+
+ *HTU_RESULT(queue + OAM_HTU_ENTRY_NUMBER) = htu_result;
+ *HTU_MASK(queue + OAM_HTU_ENTRY_NUMBER) = htu_mask;
+ *HTU_ENTRY(queue + OAM_HTU_ENTRY_NUMBER) = htu_entry;
+}
+
+static inline void clear_htu_entry(unsigned int queue)
+{
+ HTU_ENTRY(queue + OAM_HTU_ENTRY_NUMBER)->vld = 0;
+}
+
+static void validate_oam_htu_entry(void)
+{
+ HTU_ENTRY(OAM_F4_SEG_HTU_ENTRY)->vld = 1;
+ HTU_ENTRY(OAM_F4_TOT_HTU_ENTRY)->vld = 1;
+ HTU_ENTRY(OAM_F5_HTU_ENTRY)->vld = 1;
+}
+
+static void invalidate_oam_htu_entry(void)
+{
+ HTU_ENTRY(OAM_F4_SEG_HTU_ENTRY)->vld = 0;
+ HTU_ENTRY(OAM_F4_TOT_HTU_ENTRY)->vld = 0;
+ HTU_ENTRY(OAM_F5_HTU_ENTRY)->vld = 0;
+}
+
+static inline int find_vpi(unsigned int vpi)
+{
+ int i;
+ unsigned int bit;
+
+ for ( i = 0, bit = 1; i < MAX_PVC_NUMBER; i++, bit <<= 1 ) {
+ if ( (g_atm_priv_data.conn_table & bit) != 0
+ && g_atm_priv_data.conn[i].vcc != NULL
+ && vpi == g_atm_priv_data.conn[i].vcc->vpi )
+ return i;
+ }
+
+ return -1;
+}
+
+static inline int find_vpivci(unsigned int vpi, unsigned int vci)
+{
+ int i;
+ unsigned int bit;
+
+ for ( i = 0, bit = 1; i < MAX_PVC_NUMBER; i++, bit <<= 1 ) {
+ if ( (g_atm_priv_data.conn_table & bit) != 0
+ && g_atm_priv_data.conn[i].vcc != NULL
+ && vpi == g_atm_priv_data.conn[i].vcc->vpi
+ && vci == g_atm_priv_data.conn[i].vcc->vci )
+ return i;
+ }
+
+ return -1;
+}
+
+static inline int find_vcc(struct atm_vcc *vcc)
+{
+ int i;
+ unsigned int bit;
+
+ for ( i = 0, bit = 1; i < MAX_PVC_NUMBER; i++, bit <<= 1 ) {
+ if ( (g_atm_priv_data.conn_table & bit) != 0
+ && g_atm_priv_data.conn[i].vcc == vcc )
+ return i;
+ }
+
+ return -1;
+}
+
+static inline int ifx_atm_version(const struct ltq_atm_ops *ops, char *buf)
+{
+ int len = 0;
+ unsigned int major, minor;
+
+ ops->fw_ver(&major, &minor);
+
+ len += sprintf(buf + len, "ATM%d.%d.%d", IFX_ATM_VER_MAJOR, IFX_ATM_VER_MID, IFX_ATM_VER_MINOR);
+ len += sprintf(buf + len, " ATM (A1) firmware version %d.%d\n", major, minor);
+
+ return len;
+}
+
+static inline void check_parameters(void)
+{
+ /* Please refer to Amazon spec 15.4 for setting these values. */
+ if ( qsb_tau < 1 )
+ qsb_tau = 1;
+ if ( qsb_tstep < 1 )
+ qsb_tstep = 1;
+ else if ( qsb_tstep > 4 )
+ qsb_tstep = 4;
+ else if ( qsb_tstep == 3 )
+ qsb_tstep = 2;
+
+ /* There is a delay between PPE write descriptor and descriptor is */
+ /* really stored in memory. Host also has this delay when writing */
+ /* descriptor. So PPE will use this value to determine if the write */
+ /* operation makes effect. */
+ if ( write_descriptor_delay < 0 )
+ write_descriptor_delay = 0;
+
+ if ( aal5_fill_pattern < 0 )
+ aal5_fill_pattern = 0;
+ else
+ aal5_fill_pattern &= 0xFF;
+
+ /* Because of the limitation of length field in descriptors, the packet */
+ /* size could not be larger than 64K minus overhead size. */
+ if ( aal5r_max_packet_size < 0 )
+ aal5r_max_packet_size = 0;
+ else if ( aal5r_max_packet_size >= 65535 - MAX_RX_FRAME_EXTRA_BYTES )
+ aal5r_max_packet_size = 65535 - MAX_RX_FRAME_EXTRA_BYTES;
+ if ( aal5r_min_packet_size < 0 )
+ aal5r_min_packet_size = 0;
+ else if ( aal5r_min_packet_size > aal5r_max_packet_size )
+ aal5r_min_packet_size = aal5r_max_packet_size;
+ if ( aal5s_max_packet_size < 0 )
+ aal5s_max_packet_size = 0;
+ else if ( aal5s_max_packet_size >= 65535 - MAX_TX_FRAME_EXTRA_BYTES )
+ aal5s_max_packet_size = 65535 - MAX_TX_FRAME_EXTRA_BYTES;
+ if ( aal5s_min_packet_size < 0 )
+ aal5s_min_packet_size = 0;
+ else if ( aal5s_min_packet_size > aal5s_max_packet_size )
+ aal5s_min_packet_size = aal5s_max_packet_size;
+
+ if ( dma_rx_descriptor_length < 2 )
+ dma_rx_descriptor_length = 2;
+ if ( dma_tx_descriptor_length < 2 )
+ dma_tx_descriptor_length = 2;
+ if ( dma_rx_clp1_descriptor_threshold < 0 )
+ dma_rx_clp1_descriptor_threshold = 0;
+ else if ( dma_rx_clp1_descriptor_threshold > dma_rx_descriptor_length )
+ dma_rx_clp1_descriptor_threshold = dma_rx_descriptor_length;
+
+ if ( dma_tx_descriptor_length < 2 )
+ dma_tx_descriptor_length = 2;
+}
+
+static inline int init_priv_data(void)
+{
+ void *p;
+ int i;
+ struct rx_descriptor rx_desc = {0};
+ struct sk_buff *skb;
+ volatile struct tx_descriptor *p_tx_desc;
+ struct sk_buff **ppskb;
+
+ // clear atm private data structure
+ memset(&g_atm_priv_data, 0, sizeof(g_atm_priv_data));
+
+ // allocate memory for RX (AAL) descriptors
+ p = kzalloc(dma_rx_descriptor_length * sizeof(struct rx_descriptor) + DESC_ALIGNMENT, GFP_KERNEL);
+ if ( p == NULL )
+ return -1;
+ dma_cache_wback_inv((unsigned long)p, dma_rx_descriptor_length * sizeof(struct rx_descriptor) + DESC_ALIGNMENT);
+ g_atm_priv_data.aal_desc_base = p;
+ p = (void *)((((unsigned int)p + DESC_ALIGNMENT - 1) & ~(DESC_ALIGNMENT - 1)) | KSEG1);
+ g_atm_priv_data.aal_desc = (volatile struct rx_descriptor *)p;
+
+ // allocate memory for RX (OAM) descriptors
+ p = kzalloc(RX_DMA_CH_OAM_DESC_LEN * sizeof(struct rx_descriptor) + DESC_ALIGNMENT, GFP_KERNEL);
+ if ( p == NULL )
+ return -1;
+ dma_cache_wback_inv((unsigned long)p, RX_DMA_CH_OAM_DESC_LEN * sizeof(struct rx_descriptor) + DESC_ALIGNMENT);
+ g_atm_priv_data.oam_desc_base = p;
+ p = (void *)((((unsigned int)p + DESC_ALIGNMENT - 1) & ~(DESC_ALIGNMENT - 1)) | KSEG1);
+ g_atm_priv_data.oam_desc = (volatile struct rx_descriptor *)p;
+
+ // allocate memory for RX (OAM) buffer
+ p = kzalloc(RX_DMA_CH_OAM_DESC_LEN * RX_DMA_CH_OAM_BUF_SIZE + DATA_BUFFER_ALIGNMENT, GFP_KERNEL);
+ if ( p == NULL )
+ return -1;
+ dma_cache_wback_inv((unsigned long)p, RX_DMA_CH_OAM_DESC_LEN * RX_DMA_CH_OAM_BUF_SIZE + DATA_BUFFER_ALIGNMENT);
+ g_atm_priv_data.oam_buf_base = p;
+ p = (void *)(((unsigned int)p + DATA_BUFFER_ALIGNMENT - 1) & ~(DATA_BUFFER_ALIGNMENT - 1));
+ g_atm_priv_data.oam_buf = p;
+
+ // allocate memory for TX descriptors
+ p = kzalloc(MAX_PVC_NUMBER * dma_tx_descriptor_length * sizeof(struct tx_descriptor) + DESC_ALIGNMENT, GFP_KERNEL);
+ if ( p == NULL )
+ return -1;
+ dma_cache_wback_inv((unsigned long)p, MAX_PVC_NUMBER * dma_tx_descriptor_length * sizeof(struct tx_descriptor) + DESC_ALIGNMENT);
+ g_atm_priv_data.tx_desc_base = p;
+
+ // allocate memory for TX skb pointers
+ p = kzalloc(MAX_PVC_NUMBER * dma_tx_descriptor_length * sizeof(struct sk_buff *) + 4, GFP_KERNEL);
+ if ( p == NULL )
+ return -1;
+ dma_cache_wback_inv((unsigned long)p, MAX_PVC_NUMBER * dma_tx_descriptor_length * sizeof(struct sk_buff *) + 4);
+ g_atm_priv_data.tx_skb_base = p;
+
+ // setup RX (AAL) descriptors
+ rx_desc.own = 1;
+ rx_desc.c = 0;
+ rx_desc.sop = 1;
+ rx_desc.eop = 1;
+ rx_desc.byteoff = 0;
+ rx_desc.id = 0;
+ rx_desc.err = 0;
+ rx_desc.datalen = RX_DMA_CH_AAL_BUF_SIZE;
+ for ( i = 0; i < dma_rx_descriptor_length; i++ ) {
+ skb = alloc_skb_rx();
+ if ( skb == NULL )
+ return -1;
+ rx_desc.dataptr = ((unsigned int)skb->data >> 2) & 0x0FFFFFFF;
+ g_atm_priv_data.aal_desc[i] = rx_desc;
+ }
+
+ // setup RX (OAM) descriptors
+ p = (void *)((unsigned int)g_atm_priv_data.oam_buf | KSEG1);
+ rx_desc.own = 1;
+ rx_desc.c = 0;
+ rx_desc.sop = 1;
+ rx_desc.eop = 1;
+ rx_desc.byteoff = 0;
+ rx_desc.id = 0;
+ rx_desc.err = 0;
+ rx_desc.datalen = RX_DMA_CH_OAM_BUF_SIZE;
+ for ( i = 0; i < RX_DMA_CH_OAM_DESC_LEN; i++ ) {
+ rx_desc.dataptr = ((unsigned int)p >> 2) & 0x0FFFFFFF;
+ g_atm_priv_data.oam_desc[i] = rx_desc;
+ p = (void *)((unsigned int)p + RX_DMA_CH_OAM_BUF_SIZE);
+ }
+
+ // setup TX descriptors and skb pointers
+ p_tx_desc = (volatile struct tx_descriptor *)((((unsigned int)g_atm_priv_data.tx_desc_base + DESC_ALIGNMENT - 1) & ~(DESC_ALIGNMENT - 1)) | KSEG1);
+ ppskb = (struct sk_buff **)(((unsigned int)g_atm_priv_data.tx_skb_base + 3) & ~3);
+ for ( i = 0; i < MAX_PVC_NUMBER; i++ ) {
+ g_atm_priv_data.conn[i].tx_desc = &p_tx_desc[i * dma_tx_descriptor_length];
+ g_atm_priv_data.conn[i].tx_skb = &ppskb[i * dma_tx_descriptor_length];
+ }
+
+ for ( i = 0; i < ATM_PORT_NUMBER; i++ )
+ g_atm_priv_data.port[i].tx_max_cell_rate = DEFAULT_TX_LINK_RATE;
+
+ return 0;
+}
+
+static inline void clear_priv_data(void)
+{
+ int i, j;
+ struct sk_buff *skb;
+
+ for ( i = 0; i < MAX_PVC_NUMBER; i++ ) {
+ if ( g_atm_priv_data.conn[i].tx_skb != NULL ) {
+ for ( j = 0; j < dma_tx_descriptor_length; j++ )
+ if ( g_atm_priv_data.conn[i].tx_skb[j] != NULL )
+ dev_kfree_skb_any(g_atm_priv_data.conn[i].tx_skb[j]);
+ }
+ }
+
+ if ( g_atm_priv_data.tx_skb_base != NULL )
+ kfree(g_atm_priv_data.tx_skb_base);
+
+ if ( g_atm_priv_data.tx_desc_base != NULL )
+ kfree(g_atm_priv_data.tx_desc_base);
+
+ if ( g_atm_priv_data.oam_buf_base != NULL )
+ kfree(g_atm_priv_data.oam_buf_base);
+
+ if ( g_atm_priv_data.oam_desc_base != NULL )
+ kfree(g_atm_priv_data.oam_desc_base);
+
+ if ( g_atm_priv_data.aal_desc_base != NULL ) {
+ for ( i = 0; i < dma_rx_descriptor_length; i++ ) {
+ if ( g_atm_priv_data.aal_desc[i].sop || g_atm_priv_data.aal_desc[i].eop ) { // descriptor initialized
+ skb = get_skb_rx_pointer(g_atm_priv_data.aal_desc[i].dataptr);
+ dev_kfree_skb_any(skb);
+ }
+ }
+ kfree(g_atm_priv_data.aal_desc_base);
+ }
+}
+
+static inline void init_rx_tables(void)
+{
+ int i;
+ struct wrx_queue_config wrx_queue_config = {0};
+ struct wrx_dma_channel_config wrx_dma_channel_config = {0};
+ struct htu_entry htu_entry = {0};
+ struct htu_result htu_result = {0};
+ struct htu_mask htu_mask = {
+ set: 0x01,
+ clp: 0x01,
+ pid_mask: 0x00,
+ vpi_mask: 0x00,
+ vci_mask: 0x00,
+ pti_mask: 0x00,
+ clear: 0x00
+ };
+
+ /*
+ * General Registers
+ */
+ *CFG_WRX_HTUTS = MAX_PVC_NUMBER + OAM_HTU_ENTRY_NUMBER;
+#ifndef CONFIG_AMAZON_SE
+ *CFG_WRX_QNUM = MAX_QUEUE_NUMBER;
+#endif
+ *CFG_WRX_DCHNUM = RX_DMA_CH_TOTAL;
+ *WRX_DMACH_ON = (1 << RX_DMA_CH_TOTAL) - 1;
+ *WRX_HUNT_BITTH = DEFAULT_RX_HUNT_BITTH;
+
+ /*
+ * WRX Queue Configuration Table
+ */
+ wrx_queue_config.uumask = 0xFF;
+ wrx_queue_config.cpimask = 0xFF;
+ wrx_queue_config.uuexp = 0;
+ wrx_queue_config.cpiexp = 0;
+ wrx_queue_config.mfs = aal5r_max_packet_size;
+ wrx_queue_config.oversize = aal5r_max_packet_size;
+ wrx_queue_config.undersize = aal5r_min_packet_size;
+ wrx_queue_config.errdp = aal5r_drop_error_packet;
+ wrx_queue_config.dmach = RX_DMA_CH_AAL;
+ for ( i = 0; i < MAX_QUEUE_NUMBER; i++ )
+ *WRX_QUEUE_CONFIG(i) = wrx_queue_config;
+ WRX_QUEUE_CONFIG(OAM_RX_QUEUE)->dmach = RX_DMA_CH_OAM;
+
+ /*
+ * WRX DMA Channel Configuration Table
+ */
+ wrx_dma_channel_config.chrl = 0;
+ wrx_dma_channel_config.clp1th = dma_rx_clp1_descriptor_threshold;
+ wrx_dma_channel_config.mode = 0;
+ wrx_dma_channel_config.rlcfg = 0;
+
+ wrx_dma_channel_config.deslen = RX_DMA_CH_OAM_DESC_LEN;
+ wrx_dma_channel_config.desba = ((unsigned int)g_atm_priv_data.oam_desc >> 2) & 0x0FFFFFFF;
+ *WRX_DMA_CHANNEL_CONFIG(RX_DMA_CH_OAM) = wrx_dma_channel_config;
+
+ wrx_dma_channel_config.deslen = dma_rx_descriptor_length;
+ wrx_dma_channel_config.desba = ((unsigned int)g_atm_priv_data.aal_desc >> 2) & 0x0FFFFFFF;
+ *WRX_DMA_CHANNEL_CONFIG(RX_DMA_CH_AAL) = wrx_dma_channel_config;
+
+ /*
+ * HTU Tables
+ */
+ for (i = 0; i < MAX_PVC_NUMBER; i++) {
+ htu_result.qid = (unsigned int)i;
+
+ *HTU_ENTRY(i + OAM_HTU_ENTRY_NUMBER) = htu_entry;
+ *HTU_MASK(i + OAM_HTU_ENTRY_NUMBER) = htu_mask;
+ *HTU_RESULT(i + OAM_HTU_ENTRY_NUMBER) = htu_result;
+ }
+
+ /* OAM HTU Entry */
+ htu_entry.vci = 0x03;
+ htu_mask.pid_mask = 0x03;
+ htu_mask.vpi_mask = 0xFF;
+ htu_mask.vci_mask = 0x0000;
+ htu_mask.pti_mask = 0x07;
+ htu_result.cellid = OAM_RX_QUEUE;
+ htu_result.type = 1;
+ htu_result.ven = 1;
+ htu_result.qid = OAM_RX_QUEUE;
+ *HTU_RESULT(OAM_F4_SEG_HTU_ENTRY) = htu_result;
+ *HTU_MASK(OAM_F4_SEG_HTU_ENTRY) = htu_mask;
+ *HTU_ENTRY(OAM_F4_SEG_HTU_ENTRY) = htu_entry;
+ htu_entry.vci = 0x04;
+ htu_result.cellid = OAM_RX_QUEUE;
+ htu_result.type = 1;
+ htu_result.ven = 1;
+ htu_result.qid = OAM_RX_QUEUE;
+ *HTU_RESULT(OAM_F4_TOT_HTU_ENTRY) = htu_result;
+ *HTU_MASK(OAM_F4_TOT_HTU_ENTRY) = htu_mask;
+ *HTU_ENTRY(OAM_F4_TOT_HTU_ENTRY) = htu_entry;
+ htu_entry.vci = 0x00;
+ htu_entry.pti = 0x04;
+ htu_mask.vci_mask = 0xFFFF;
+ htu_mask.pti_mask = 0x01;
+ htu_result.cellid = OAM_RX_QUEUE;
+ htu_result.type = 1;
+ htu_result.ven = 1;
+ htu_result.qid = OAM_RX_QUEUE;
+ *HTU_RESULT(OAM_F5_HTU_ENTRY) = htu_result;
+ *HTU_MASK(OAM_F5_HTU_ENTRY) = htu_mask;
+ *HTU_ENTRY(OAM_F5_HTU_ENTRY) = htu_entry;
+}
+
+static inline void init_tx_tables(void)
+{
+ int i;
+ struct wtx_queue_config wtx_queue_config = {0};
+ struct wtx_dma_channel_config wtx_dma_channel_config = {0};
+ struct wtx_port_config wtx_port_config = {
+ res1: 0,
+ qid: 0,
+ qsben: 1
+ };
+
+ /*
+ * General Registers
+ */
+ *CFG_WTX_DCHNUM = MAX_TX_DMA_CHANNEL_NUMBER;
+ *WTX_DMACH_ON = ((1 << MAX_TX_DMA_CHANNEL_NUMBER) - 1) ^ ((1 << FIRST_QSB_QID) - 1);
+ *CFG_WRDES_DELAY = write_descriptor_delay;
+
+ /*
+ * WTX Port Configuration Table
+ */
+ for ( i = 0; i < ATM_PORT_NUMBER; i++ )
+ *WTX_PORT_CONFIG(i) = wtx_port_config;
+
+ /*
+ * WTX Queue Configuration Table
+ */
+ wtx_queue_config.qsben = 1;
+ wtx_queue_config.sbid = 0;
+ for ( i = 0; i < MAX_TX_DMA_CHANNEL_NUMBER; i++ ) {
+ wtx_queue_config.qsb_vcid = i;
+ *WTX_QUEUE_CONFIG(i) = wtx_queue_config;
+ }
+
+ /*
+ * WTX DMA Channel Configuration Table
+ */
+ wtx_dma_channel_config.mode = 0;
+ wtx_dma_channel_config.deslen = 0;
+ wtx_dma_channel_config.desba = 0;
+ for ( i = 0; i < FIRST_QSB_QID; i++ )
+ *WTX_DMA_CHANNEL_CONFIG(i) = wtx_dma_channel_config;
+ /* normal connection */
+ wtx_dma_channel_config.deslen = dma_tx_descriptor_length;
+ for ( ; i < MAX_TX_DMA_CHANNEL_NUMBER ; i++ ) {
+ wtx_dma_channel_config.desba = ((unsigned int)g_atm_priv_data.conn[i - FIRST_QSB_QID].tx_desc >> 2) & 0x0FFFFFFF;
+ *WTX_DMA_CHANNEL_CONFIG(i) = wtx_dma_channel_config;
+ }
+}
+
+static int atm_showtime_enter(struct port_cell_info *port_cell, void *xdata_addr)
+{
+ int i, j;
+
+ ASSERT(port_cell != NULL, "port_cell is NULL");
+ ASSERT(xdata_addr != NULL, "xdata_addr is NULL");
+
+ for ( j = 0; j < ATM_PORT_NUMBER && j < port_cell->port_num; j++ )
+ if ( port_cell->tx_link_rate[j] > 0 )
+ break;
+ for ( i = 0; i < ATM_PORT_NUMBER && i < port_cell->port_num; i++ )
+ g_atm_priv_data.port[i].tx_max_cell_rate =
+ port_cell->tx_link_rate[i] > 0 ? port_cell->tx_link_rate[i] : port_cell->tx_link_rate[j];
+
+ qsb_global_set();
+
+ for ( i = 0; i < MAX_PVC_NUMBER; i++ )
+ if ( g_atm_priv_data.conn[i].vcc != NULL )
+ set_qsb(g_atm_priv_data.conn[i].vcc, &g_atm_priv_data.conn[i].vcc->qos, i);
+
+ // TODO: ReTX set xdata_addr
+ g_xdata_addr = xdata_addr;
+
+ g_showtime = 1;
+
+#if defined(CONFIG_VR9)
+ IFX_REG_W32(0x0F, UTP_CFG);
+#endif
+
+ printk("enter showtime, cell rate: 0 - %d, 1 - %d, xdata addr: 0x%08x\n",
+ g_atm_priv_data.port[0].tx_max_cell_rate,
+ g_atm_priv_data.port[1].tx_max_cell_rate,
+ (unsigned int)g_xdata_addr);
+
+ return 0;
+}
+
+static int atm_showtime_exit(void)
+{
+ if ( !g_showtime )
+ return -1;
+
+#if defined(CONFIG_VR9)
+ IFX_REG_W32(0x00, UTP_CFG);
+#endif
+ g_showtime = 0;
+ g_xdata_addr = NULL;
+ printk("leave showtime\n");
+ return 0;
+}
+
+extern struct ltq_atm_ops ar9_ops;
+extern struct ltq_atm_ops vr9_ops;
+extern struct ltq_atm_ops danube_ops;
+extern struct ltq_atm_ops ase_ops;
+
+static const struct of_device_id ltq_atm_match[] = {
+#ifdef CONFIG_DANUBE
+ { .compatible = "lantiq,ppe-danube", .data = &danube_ops },
+#elif defined CONFIG_AMAZON_SE
+ { .compatible = "lantiq,ppe-ase", .data = &ase_ops },
+#elif defined CONFIG_AR9
+ { .compatible = "lantiq,ppe-arx100", .data = &ar9_ops },
+#elif defined CONFIG_VR9
+ { .compatible = "lantiq,ppe-xrx200", .data = &vr9_ops },
+#endif
+ {},
+};
+MODULE_DEVICE_TABLE(of, ltq_atm_match);
+
+static int ltq_atm_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct ltq_atm_ops *ops = NULL;
+ int ret;
+ int port_num;
+ struct port_cell_info port_cell = {0};
+ int i, j;
+ char ver_str[256];
+
+ match = of_match_device(ltq_atm_match, &pdev->dev);
+ if (!match) {
+ dev_err(&pdev->dev, "failed to find matching device\n");
+ return -ENOENT;
+ }
+ ops = (struct ltq_atm_ops *) match->data;
+
+ check_parameters();
+
+ ret = init_priv_data();
+ if ( ret != 0 ) {
+ pr_err("INIT_PRIV_DATA_FAIL\n");
+ goto INIT_PRIV_DATA_FAIL;
+ }
+
+ ops->init();
+ init_rx_tables();
+ init_tx_tables();
+
+ /* create devices */
+ for ( port_num = 0; port_num < ATM_PORT_NUMBER; port_num++ ) {
+ g_atm_priv_data.port[port_num].dev = atm_dev_register("ifxmips_atm", NULL, &g_ifx_atm_ops, -1, NULL);
+ if ( !g_atm_priv_data.port[port_num].dev ) {
+ pr_err("failed to register atm device %d!\n", port_num);
+ ret = -EIO;
+ goto ATM_DEV_REGISTER_FAIL;
+ } else {
+ g_atm_priv_data.port[port_num].dev->ci_range.vpi_bits = 8;
+ g_atm_priv_data.port[port_num].dev->ci_range.vci_bits = 16;
+ g_atm_priv_data.port[port_num].dev->link_rate = g_atm_priv_data.port[port_num].tx_max_cell_rate;
+ g_atm_priv_data.port[port_num].dev->dev_data = (void*)port_num;
+ }
+ }
+
+ /* register interrupt handler */
+ ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, IRQF_DISABLED, "atm_mailbox_isr", &g_atm_priv_data);
+ if ( ret ) {
+ if ( ret == -EBUSY ) {
+ pr_err("IRQ may be occupied by other driver, please reconfig to disable it.\n");
+ } else {
+ pr_err("request_irq fail irq:%d\n", PPE_MAILBOX_IGU1_INT);
+ }
+ goto REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL;
+ }
+ disable_irq(PPE_MAILBOX_IGU1_INT);
+
+
+ ret = ops->start(0);
+ if ( ret ) {
+ pr_err("ifx_pp32_start fail!\n");
+ goto PP32_START_FAIL;
+ }
+
+ port_cell.port_num = ATM_PORT_NUMBER;
+ ifx_mei_atm_showtime_check(&g_showtime, &port_cell, &g_xdata_addr);
+ if ( g_showtime ) {
+ for ( i = 0; i < ATM_PORT_NUMBER; i++ )
+ if ( port_cell.tx_link_rate[i] != 0 )
+ break;
+ for ( j = 0; j < ATM_PORT_NUMBER; j++ )
+ g_atm_priv_data.port[j].tx_max_cell_rate =
+ port_cell.tx_link_rate[j] != 0 ? port_cell.tx_link_rate[j] : port_cell.tx_link_rate[i];
+ }
+
+ qsb_global_set();
+ validate_oam_htu_entry();
+
+ ifx_mei_atm_showtime_enter = atm_showtime_enter;
+ ifx_mei_atm_showtime_exit = atm_showtime_exit;
+
+ ifx_atm_version(ops, ver_str);
+ printk(KERN_INFO "%s", ver_str);
+ platform_set_drvdata(pdev, ops);
+ printk("ifxmips_atm: ATM init succeed\n");
+
+ return 0;
+
+PP32_START_FAIL:
+ free_irq(PPE_MAILBOX_IGU1_INT, &g_atm_priv_data);
+REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL:
+ATM_DEV_REGISTER_FAIL:
+ while ( port_num-- > 0 )
+ atm_dev_deregister(g_atm_priv_data.port[port_num].dev);
+INIT_PRIV_DATA_FAIL:
+ clear_priv_data();
+ printk("ifxmips_atm: ATM init failed\n");
+ return ret;
+}
+
+static int ltq_atm_remove(struct platform_device *pdev)
+{
+ int port_num;
+ struct ltq_atm_ops *ops = platform_get_drvdata(pdev);
+
+ ifx_mei_atm_showtime_enter = NULL;
+ ifx_mei_atm_showtime_exit = NULL;
+
+ invalidate_oam_htu_entry();
+
+ ops->stop(0);
+
+ free_irq(PPE_MAILBOX_IGU1_INT, &g_atm_priv_data);
+
+ for ( port_num = 0; port_num < ATM_PORT_NUMBER; port_num++ )
+ atm_dev_deregister(g_atm_priv_data.port[port_num].dev);
+
+ ops->shutdown();
+
+ clear_priv_data();
+
+ return 0;
+}
+
+static struct platform_driver ltq_atm_driver = {
+ .probe = ltq_atm_probe,
+ .remove = ltq_atm_remove,
+ .driver = {
+ .name = "atm",
+ .owner = THIS_MODULE,
+ .of_match_table = ltq_atm_match,
+ },
+};
+
+module_platform_driver(ltq_atm_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/package/kernel/lantiq/ltq-deu/Makefile b/package/kernel/lantiq/ltq-deu/Makefile
new file mode 100644
index 0000000000..4e0d9551ce
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/Makefile
@@ -0,0 +1,49 @@
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ltq-deu
+PKG_RELEASE:=1
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-deu-$(BUILD_VARIANT)
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-deu-template
+ SECTION:=sys
+ CATEGORY:=Kernel modules
+ SUBMENU:=Cryptographic API modules
+ TITLE:=deu driver for $(1)
+ URL:=http://www.lantiq.com/
+ VARIANT:=$(1)
+ DEPENDS:=@TARGET_lantiq_xway
+ FILES:=$(PKG_BUILD_DIR)/ltq_deu_$(1).ko $(PKG_BUILD_DIR)/ltq_deu_testmgr.ko
+ AUTOLOAD:=$(call AutoLoad,52,ltq_deu_$(1))
+endef
+
+KernelPackage/ltq-deu-danube=$(call KernelPackage/ltq-deu-template,danube)
+KernelPackage/ltq-deu-ar9=$(call KernelPackage/ltq-deu-template,ar9)
+KernelPackage/ltq-deu-vr9=$(call KernelPackage/ltq-deu-template,vr9)
+
+define Build/Prepare
+ $(INSTALL_DIR) $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ cd $(LINUX_DIR); \
+ ARCH=mips CROSS_COMPILE="$(KERNEL_CROSS)" \
+ $(MAKE) BUILD_VARIANT=$(BUILD_VARIANT) M=$(PKG_BUILD_DIR) V=1 modules
+endef
+
+$(eval $(call KernelPackage,ltq-deu-danube))
+$(eval $(call KernelPackage,ltq-deu-ar9))
+$(eval $(call KernelPackage,ltq-deu-vr9))
diff --git a/package/kernel/lantiq/ltq-deu/src/Makefile b/package/kernel/lantiq/ltq-deu/src/Makefile
new file mode 100644
index 0000000000..9714e83786
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/Makefile
@@ -0,0 +1,26 @@
+ifeq ($(BUILD_VARIANT),danube)
+ CFLAGS_MODULE =-DCONFIG_DANUBE -DCONFIG_CRYPTO_DEV_DEU -DCONFIG_CRYPTO_DEV_SPEED_TEST -DCONFIG_CRYPTO_DEV_DES \
+ -DCONFIG_CRYPTO_DEV_AES -DCONFIG_CRYPTO_DEV_SHA1 -DCONFIG_CRYPTO_DEV_MD5
+ obj-m = ltq_deu_danube.o
+ ltq_deu_danube-objs = ifxmips_deu.o ifxmips_deu_danube.o ifxmips_des.o ifxmips_aes.o ifxmips_sha1.o ifxmips_md5.o
+endif
+
+ifeq ($(BUILD_VARIANT),ar9)
+ CFLAGS_MODULE = -DCONFIG_AR9 -DCONFIG_CRYPTO_DEV_DEU -DCONFIG_CRYPTO_DEV_SPEED_TEST -DCONFIG_CRYPTO_DEV_DES \
+ -DCONFIG_CRYPTO_DEV_AES -DCONFIG_CRYPTO_DEV_SHA1 -DCONFIG_CRYPTO_DEV_MD5 -DCONFIG_CRYPTO_DEV_ARC4 \
+ -DCONFIG_CRYPTO_DEV_SHA1_HMAC -DCONFIG_CRYPTO_DEV_MD5_HMAC
+ obj-m = ltq_deu_ar9.o
+ ltq_deu_ar9-objs = ifxmips_deu.o ifxmips_deu_ar9.o ifxmips_des.o ifxmips_aes.o ifxmips_arc4.o \
+ ifxmips_sha1.o ifxmips_md5.o ifxmips_sha1_hmac.o ifxmips_md5_hmac.o
+endif
+
+ifeq ($(BUILD_VARIANT),vr9)
+ CFLAGS_MODULE = -DCONFIG_VR9 -DCONFIG_CRYPTO_DEV_DEU -DCONFIG_CRYPTO_DEV_SPEED_TEST -DCONFIG_CRYPTO_DEV_DES \
+ -DCONFIG_CRYPTO_DEV_AES -DCONFIG_CRYPTO_DEV_SHA1 -DCONFIG_CRYPTO_DEV_MD5 -DCONFIG_CRYPTO_DEV_ARC4 \
+ -DCONFIG_CRYPTO_DEV_SHA1_HMAC -DCONFIG_CRYPTO_DEV_MD5_HMAC
+ obj-m = ltq_deu_vr9.o
+ ltq_deu_vr9-objs = ifxmips_deu.o ifxmips_deu_vr9.o ifxmips_des.o ifxmips_aes.o ifxmips_arc4.o \
+ ifxmips_sha1.o ifxmips_md5.o ifxmips_sha1_hmac.o ifxmips_md5_hmac.o
+endif
+
+obj-m += ltq_deu_testmgr.o
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_aes.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_aes.c
new file mode 100644
index 0000000000..bf77537940
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_aes.c
@@ -0,0 +1,904 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_aes.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver for AES Algorithm
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx DEU driver module
+*/
+
+/*!
+ \file ifxmips_aes.c
+ \ingroup IFX_DEU
+ \brief AES Encryption Driver main file
+*/
+
+/*!
+ \defgroup IFX_AES_FUNCTIONS IFX_AES_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief IFX AES driver Functions
+*/
+
+
+/* Project Header Files */
+#if defined(CONFIG_MODVERSIONS)
+#define MODVERSIONS
+#include <linux/modeversions>
+#endif
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <crypto/algapi.h>
+
+#include "ifxmips_deu.h"
+
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+extern int ifx_danube_pre_1_4;
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Unkown platform"
+#endif
+
+/* DMA related header and variables */
+
+spinlock_t aes_lock;
+#define CRTCL_SECT_INIT spin_lock_init(&aes_lock)
+#define CRTCL_SECT_START spin_lock_irqsave(&aes_lock, flag)
+#define CRTCL_SECT_END spin_unlock_irqrestore(&aes_lock, flag)
+
+/* Definition of constants */
+#define AES_START IFX_AES_CON
+#define AES_MIN_KEY_SIZE 16
+#define AES_MAX_KEY_SIZE 32
+#define AES_BLOCK_SIZE 16
+#define CTR_RFC3686_NONCE_SIZE 4
+#define CTR_RFC3686_IV_SIZE 8
+#define CTR_RFC3686_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE)
+
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif /* CRYPTO_DEBUG */
+
+/* Function decleration */
+int aes_chip_init(void);
+u32 endian_swap(u32 input);
+u32 input_swap(u32 input);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+int aes_memory_allocate(int value);
+int des_memory_allocate(int value);
+void memory_release(u32 *addr);
+
+
+extern void ifx_deu_aes (void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg,
+ uint8_t *iv_arg, size_t nbytes, int encdec, int mode);
+/* End of function decleration */
+
+struct aes_ctx {
+ int key_length;
+ u32 buf[AES_MAX_KEY_SIZE];
+ u8 nonce[CTR_RFC3686_NONCE_SIZE];
+};
+
+extern int disable_deudma;
+extern int disable_multiblock;
+
+/*! \fn int aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief sets the AES keys
+ * \param tfm linux crypto algo transform
+ * \param in_key input key
+ * \param key_len key lengths of 16, 24 and 32 bytes supported
+ * \return -EINVAL - bad key length, 0 - SUCCESS
+*/
+int aes_set_key (struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len)
+{
+ struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+ unsigned long *flags = (unsigned long *) &tfm->crt_flags;
+
+ //printk("set_key in %s\n", __FILE__);
+
+ //aes_chip_init();
+
+ if (key_len != 16 && key_len != 24 && key_len != 32) {
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+
+ ctx->key_length = key_len;
+ DPRINTF(0, "ctx @%p, key_len %d, ctx->key_length %d\n", ctx, key_len, ctx->key_length);
+ memcpy ((u8 *) (ctx->buf), in_key, key_len);
+
+ return 0;
+}
+
+
+/*! \fn void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, size_t nbytes, int encdec, int mode)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief main interface to AES hardware
+ * \param ctx_arg crypto algo context
+ * \param out_arg output bytestream
+ * \param in_arg input bytestream
+ * \param iv_arg initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param mode operation mode such as ebc, cbc, ctr
+ *
+*/
+void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+ u8 *iv_arg, size_t nbytes, int encdec, int mode)
+
+{
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+ volatile struct aes_t *aes = (volatile struct aes_t *) AES_START;
+ struct aes_ctx *ctx = (struct aes_ctx *)ctx_arg;
+ u32 *in_key = ctx->buf;
+ unsigned long flag;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+ int key_len = ctx->key_length;
+
+ int i = 0;
+ int byte_cnt = nbytes;
+
+
+ CRTCL_SECT_START;
+ /* 128, 192 or 256 bit key length */
+ aes->controlr.K = key_len / 8 - 2;
+ if (key_len == 128 / 8) {
+ aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+ aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+ aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+ aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+ }
+ else if (key_len == 192 / 8) {
+ aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+ aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+ aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+ aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+ aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
+ aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
+ }
+ else if (key_len == 256 / 8) {
+ aes->K7R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+ aes->K6R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+ aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+ aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+ aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
+ aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
+ aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 6));
+ aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 7));
+ }
+ else {
+ printk (KERN_ERR "[%s %s %d]: Invalid key_len : %d\n", __FILE__, __func__, __LINE__, key_len);
+ CRTCL_SECT_END;
+ return;// -EINVAL;
+ }
+
+ /* let HW pre-process DEcryption key in any case (even if
+ ENcryption is used). Key Valid (KV) bit is then only
+ checked in decryption routine! */
+ aes->controlr.PNK = 1;
+
+
+ aes->controlr.E_D = !encdec; //encryption
+ aes->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
+
+ //aes->controlr.F = 128; //default; only for CFB and OFB modes; change only for customer-specific apps
+ if (mode > 0) {
+ aes->IV3R = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
+ aes->IV2R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
+ aes->IV1R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));
+ aes->IV0R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));
+ };
+
+
+ i = 0;
+ while (byte_cnt >= 16) {
+
+ aes->ID3R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 0));
+ aes->ID2R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 1));
+ aes->ID1R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 2));
+ aes->ID0R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 3)); /* start crypto */
+
+ while (aes->controlr.BUS) {
+ // this will not take long
+ }
+
+ *((volatile u32 *) out_arg + (i * 4) + 0) = aes->OD3R;
+ *((volatile u32 *) out_arg + (i * 4) + 1) = aes->OD2R;
+ *((volatile u32 *) out_arg + (i * 4) + 2) = aes->OD1R;
+ *((volatile u32 *) out_arg + (i * 4) + 3) = aes->OD0R;
+
+ i++;
+ byte_cnt -= 16;
+ }
+
+
+ //tc.chen : copy iv_arg back
+ if (mode > 0) {
+ *((u32 *) iv_arg) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg));
+ *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
+ *((u32 *) iv_arg + 2) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));
+ *((u32 *) iv_arg + 3) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));
+ }
+
+ CRTCL_SECT_END;
+}
+
+/*!
+ * \fn int ctr_rfc3686_aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief sets RFC3686 key
+ * \param tfm linux crypto algo transform
+ * \param in_key input key
+ * \param key_len key lengths of 20, 28 and 36 bytes supported; last 4 bytes is nonce
+ * \return 0 - SUCCESS
+ * -EINVAL - bad key length
+*/
+int ctr_rfc3686_aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
+{
+ struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+ unsigned long *flags = (unsigned long *)&tfm->crt_flags;
+
+ //printk("ctr_rfc3686_aes_set_key in %s\n", __FILE__);
+
+ memcpy(ctx->nonce, in_key + (key_len - CTR_RFC3686_NONCE_SIZE),
+ CTR_RFC3686_NONCE_SIZE);
+
+ key_len -= CTR_RFC3686_NONCE_SIZE; // remove 4 bytes of nonce
+
+ if (key_len != 16 && key_len != 24 && key_len != 32) {
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+
+ ctx->key_length = key_len;
+
+ memcpy ((u8 *) (ctx->buf), in_key, key_len);
+
+ return 0;
+}
+
+/*! \fn void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief main interface with deu hardware in DMA mode
+ * \param ctx_arg crypto algo context
+ * \param out_arg output bytestream
+ * \param in_arg input bytestream
+ * \param iv_arg initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param mode operation mode such as ebc, cbc, ctr
+*/
+
+
+//definitions from linux/include/crypto.h:
+//#define CRYPTO_TFM_MODE_ECB 0x00000001
+//#define CRYPTO_TFM_MODE_CBC 0x00000002
+//#define CRYPTO_TFM_MODE_CFB 0x00000004
+//#define CRYPTO_TFM_MODE_CTR 0x00000008
+//#define CRYPTO_TFM_MODE_OFB 0x00000010 // not even defined
+//but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
+
+/*! \fn void ifx_deu_aes_ecb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief sets AES hardware to ECB mode
+ * \param ctx crypto algo context
+ * \param dst output bytestream
+ * \param src input bytestream
+ * \param iv initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param inplace not used
+*/
+void ifx_deu_aes_ecb (void *ctx, uint8_t *dst, const uint8_t *src,
+ uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+ ifx_deu_aes (ctx, dst, src, NULL, nbytes, encdec, 0);
+}
+
+/*! \fn void ifx_deu_aes_cbc (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief sets AES hardware to CBC mode
+ * \param ctx crypto algo context
+ * \param dst output bytestream
+ * \param src input bytestream
+ * \param iv initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param inplace not used
+*/
+void ifx_deu_aes_cbc (void *ctx, uint8_t *dst, const uint8_t *src,
+ uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+ ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 1);
+}
+
+/*! \fn void ifx_deu_aes_ofb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief sets AES hardware to OFB mode
+ * \param ctx crypto algo context
+ * \param dst output bytestream
+ * \param src input bytestream
+ * \param iv initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param inplace not used
+*/
+void ifx_deu_aes_ofb (void *ctx, uint8_t *dst, const uint8_t *src,
+ uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+ ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 2);
+}
+
+/*! \fn void ifx_deu_aes_cfb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief sets AES hardware to CFB mode
+ * \param ctx crypto algo context
+ * \param dst output bytestream
+ * \param src input bytestream
+ * \param iv initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param inplace not used
+*/
+void ifx_deu_aes_cfb (void *ctx, uint8_t *dst, const uint8_t *src,
+ uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+ ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 3);
+}
+
+/*! \fn void ifx_deu_aes_ctr (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief sets AES hardware to CTR mode
+ * \param ctx crypto algo context
+ * \param dst output bytestream
+ * \param src input bytestream
+ * \param iv initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param inplace not used
+*/
+void ifx_deu_aes_ctr (void *ctx, uint8_t *dst, const uint8_t *src,
+ uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+ ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 4);
+}
+
+/*! \fn void aes_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief encrypt AES_BLOCK_SIZE of data
+ * \param tfm linux crypto algo transform
+ * \param out output bytestream
+ * \param in input bytestream
+*/
+void aes_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+{
+ struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+ ifx_deu_aes (ctx, out, in, NULL, AES_BLOCK_SIZE,
+ CRYPTO_DIR_ENCRYPT, 0);
+}
+
+/*! \fn void aes_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief decrypt AES_BLOCK_SIZE of data
+ * \param tfm linux crypto algo transform
+ * \param out output bytestream
+ * \param in input bytestream
+*/
+void aes_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+{
+ struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+ ifx_deu_aes (ctx, out, in, NULL, AES_BLOCK_SIZE,
+ CRYPTO_DIR_DECRYPT, 0);
+}
+
+/*
+ * \brief AES function mappings
+*/
+struct crypto_alg ifxdeu_aes_alg = {
+ .cra_name = "aes",
+ .cra_driver_name = "ifxdeu-aes",
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_aes_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = AES_MIN_KEY_SIZE,
+ .cia_max_keysize = AES_MAX_KEY_SIZE,
+ .cia_setkey = aes_set_key,
+ .cia_encrypt = aes_encrypt,
+ .cia_decrypt = aes_decrypt,
+ }
+ }
+};
+
+/*! \fn int ecb_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief ECB AES encrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+ * \return err
+*/
+int ecb_aes_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ nbytes -= (nbytes % AES_BLOCK_SIZE);
+ ifx_deu_aes_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*! \fn int ecb_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief ECB AES decrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+ * \return err
+*/
+int ecb_aes_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ nbytes -= (nbytes % AES_BLOCK_SIZE);
+ ifx_deu_aes_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*
+ * \brief AES function mappings
+*/
+struct crypto_alg ifxdeu_ecb_aes_alg = {
+ .cra_name = "ecb(aes)",
+ .cra_driver_name = "ifxdeu-ecb(aes)",
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_ecb_aes_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .setkey = aes_set_key,
+ .encrypt = ecb_aes_encrypt,
+ .decrypt = ecb_aes_decrypt,
+ }
+ }
+};
+
+
+/*! \fn int cbc_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief CBC AES encrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+ * \return err
+*/
+int cbc_aes_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ u8 *iv = walk.iv;
+ nbytes -= (nbytes % AES_BLOCK_SIZE);
+ ifx_deu_aes_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*! \fn int cbc_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief CBC AES decrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+ * \return err
+*/
+int cbc_aes_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ u8 *iv = walk.iv;
+ nbytes -= (nbytes % AES_BLOCK_SIZE);
+ ifx_deu_aes_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*
+ * \brief AES function mappings
+*/
+struct crypto_alg ifxdeu_cbc_aes_alg = {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "ifxdeu-cbc(aes)",
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_cbc_aes_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = aes_set_key,
+ .encrypt = cbc_aes_encrypt,
+ .decrypt = cbc_aes_decrypt,
+ }
+ }
+};
+
+
+/*! \fn int ctr_basic_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Counter mode AES encrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+ * \return err
+*/
+int ctr_basic_aes_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ u8 *iv = walk.iv;
+ nbytes -= (nbytes % AES_BLOCK_SIZE);
+ ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*! \fn int ctr_basic_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Counter mode AES decrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+ * \return err
+*/
+int ctr_basic_aes_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ u8 *iv = walk.iv;
+ nbytes -= (nbytes % AES_BLOCK_SIZE);
+ ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*
+ * \brief AES function mappings
+*/
+struct crypto_alg ifxdeu_ctr_basic_aes_alg = {
+ .cra_name = "ctr(aes)",
+ .cra_driver_name = "ifxdeu-ctr(aes)",
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_ctr_basic_aes_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = aes_set_key,
+ .encrypt = ctr_basic_aes_encrypt,
+ .decrypt = ctr_basic_aes_decrypt,
+ }
+ }
+};
+
+
+/*! \fn int ctr_rfc3686_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Counter mode AES (rfc3686) encrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+ * \return err
+*/
+int ctr_rfc3686_aes_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+ u8 rfc3686_iv[16];
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ /* set up counter block */
+ memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
+ memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, walk.iv, CTR_RFC3686_IV_SIZE);
+
+ /* initialize counter portion of counter block */
+ *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
+ cpu_to_be32(1);
+
+ while ((nbytes = walk.nbytes)) {
+ nbytes -= (nbytes % AES_BLOCK_SIZE);
+ ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ rfc3686_iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*! \fn int ctr_rfc3686_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Counter mode AES (rfc3686) decrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+ * \return err
+*/
+int ctr_rfc3686_aes_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+ u8 rfc3686_iv[16];
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ /* set up counter block */
+ memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
+ memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, walk.iv, CTR_RFC3686_IV_SIZE);
+
+ /* initialize counter portion of counter block */
+ *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
+ cpu_to_be32(1);
+
+ while ((nbytes = walk.nbytes)) {
+ nbytes -= (nbytes % AES_BLOCK_SIZE);
+ ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ rfc3686_iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*
+ * \brief AES function mappings
+*/
+struct crypto_alg ifxdeu_ctr_rfc3686_aes_alg = {
+ .cra_name = "rfc3686(ctr(aes))",
+ .cra_driver_name = "ifxdeu-ctr-rfc3686(aes)",
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_ctr_rfc3686_aes_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = CTR_RFC3686_MAX_KEY_SIZE,
+ .ivsize = CTR_RFC3686_IV_SIZE,
+ .setkey = ctr_rfc3686_aes_set_key,
+ .encrypt = ctr_rfc3686_aes_encrypt,
+ .decrypt = ctr_rfc3686_aes_decrypt,
+ }
+ }
+};
+
+
+/*! \fn int __init ifxdeu_init_aes (void)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief function to initialize AES driver
+ * \return ret
+*/
+int __init ifxdeu_init_aes (void)
+{
+ int ret = -ENOSYS;
+
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+ if (!disable_multiblock) {
+ ifxdeu_aes_alg.cra_u.cipher.cia_max_nbytes = AES_BLOCK_SIZE; //(size_t)-1;
+ ifxdeu_aes_alg.cra_u.cipher.cia_req_align = 16;
+ ifxdeu_aes_alg.cra_u.cipher.cia_ecb = ifx_deu_aes_ecb;
+ ifxdeu_aes_alg.cra_u.cipher.cia_cbc = ifx_deu_aes_cbc;
+ ifxdeu_aes_alg.cra_u.cipher.cia_cfb = ifx_deu_aes_cfb;
+ ifxdeu_aes_alg.cra_u.cipher.cia_ofb = ifx_deu_aes_ofb;
+ }
+#endif
+
+ if ((ret = crypto_register_alg(&ifxdeu_aes_alg)))
+ goto aes_err;
+
+ if ((ret = crypto_register_alg(&ifxdeu_ecb_aes_alg)))
+ goto ecb_aes_err;
+
+ if ((ret = crypto_register_alg(&ifxdeu_cbc_aes_alg)))
+ goto cbc_aes_err;
+
+ if ((ret = crypto_register_alg(&ifxdeu_ctr_basic_aes_alg)))
+ goto ctr_basic_aes_err;
+
+ if ((ret = crypto_register_alg(&ifxdeu_ctr_rfc3686_aes_alg)))
+ goto ctr_rfc3686_aes_err;
+
+ aes_chip_init ();
+
+ CRTCL_SECT_INIT;
+
+
+ printk (KERN_NOTICE "IFX DEU AES initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
+ return ret;
+
+ctr_rfc3686_aes_err:
+ crypto_unregister_alg(&ifxdeu_ctr_rfc3686_aes_alg);
+ printk (KERN_ERR "IFX ctr_rfc3686_aes initialization failed!\n");
+ return ret;
+ctr_basic_aes_err:
+ crypto_unregister_alg(&ifxdeu_ctr_basic_aes_alg);
+ printk (KERN_ERR "IFX ctr_basic_aes initialization failed!\n");
+ return ret;
+cbc_aes_err:
+ crypto_unregister_alg(&ifxdeu_cbc_aes_alg);
+ printk (KERN_ERR "IFX cbc_aes initialization failed!\n");
+ return ret;
+ecb_aes_err:
+ crypto_unregister_alg(&ifxdeu_ecb_aes_alg);
+ printk (KERN_ERR "IFX aes initialization failed!\n");
+ return ret;
+aes_err:
+ printk(KERN_ERR "IFX DEU AES initialization failed!\n");
+
+ return ret;
+}
+
+/*! \fn void __exit ifxdeu_fini_aes (void)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief unregister aes driver
+*/
+void __exit ifxdeu_fini_aes (void)
+{
+ crypto_unregister_alg (&ifxdeu_aes_alg);
+ crypto_unregister_alg (&ifxdeu_ecb_aes_alg);
+ crypto_unregister_alg (&ifxdeu_cbc_aes_alg);
+ crypto_unregister_alg (&ifxdeu_ctr_basic_aes_alg);
+ crypto_unregister_alg (&ifxdeu_ctr_rfc3686_aes_alg);
+
+}
+
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_arc4.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_arc4.c
new file mode 100644
index 0000000000..ee56187eee
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_arc4.c
@@ -0,0 +1,389 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_arc4.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver for ARC4 Algorithm
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08 Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx deu driver module
+*/
+
+/*!
+ \file ifxmips_arc4.c
+ \ingroup IFX_DEU
+ \brief ARC4 encryption DEU driver file
+*/
+
+/*!
+ \defgroup IFX_ARC4_FUNCTIONS IFX_ARC4_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief IFX deu driver functions
+*/
+
+/* Project header */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <crypto/algapi.h>
+#include <linux/interrupt.h>
+#include <asm/byteorder.h>
+#include <linux/delay.h>
+
+/* Board specific header files */
+#ifdef CONFIG_AR9
+#include "ifxmips_deu_ar9.h"
+#endif
+#ifdef CONFIG_VR9
+#include "ifxmips_deu_vr9.h"
+#endif
+
+static spinlock_t lock;
+#define CRTCL_SECT_INIT spin_lock_init(&lock)
+#define CRTCL_SECT_START spin_lock_irqsave(&lock, flag)
+#define CRTCL_SECT_END spin_unlock_irqrestore(&lock, flag)
+
+/* Preprocessor declerations */
+#define ARC4_MIN_KEY_SIZE 1
+//#define ARC4_MAX_KEY_SIZE 256
+#define ARC4_MAX_KEY_SIZE 16
+#define ARC4_BLOCK_SIZE 1
+#define ARC4_START IFX_ARC4_CON
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+
+/*
+ * \brief arc4 private structure
+*/
+struct arc4_ctx {
+ int key_length;
+ u8 buf[120];
+};
+
+extern int disable_deudma;
+extern int disable_multiblock;
+
+
+/*! \fn static void _deu_arc4 (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
+ \ingroup IFX_ARC4_FUNCTIONS
+ \brief main interface to ARC4 hardware
+ \param ctx_arg crypto algo context
+ \param out_arg output bytestream
+ \param in_arg input bytestream
+ \param iv_arg initialization vector
+ \param nbytes length of bytestream
+ \param encdec 1 for encrypt; 0 for decrypt
+ \param mode operation mode such as ebc, cbc, ctr
+*/
+static void _deu_arc4 (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+ u8 *iv_arg, u32 nbytes, int encdec, int mode)
+{
+ volatile struct arc4_t *arc4 = (struct arc4_t *) ARC4_START;
+
+ int i = 0;
+ unsigned long flag;
+
+#if 1 // need to handle nbytes not multiple of 16
+ volatile u32 tmp_array32[4];
+ volatile u8 *tmp_ptr8;
+ int remaining_bytes, j;
+#endif
+
+ CRTCL_SECT_START;
+
+ arc4->IDLEN = nbytes;
+
+#if 1
+ while (i < nbytes) {
+ arc4->ID3R = *((u32 *) in_arg + (i>>2) + 0);
+ arc4->ID2R = *((u32 *) in_arg + (i>>2) + 1);
+ arc4->ID1R = *((u32 *) in_arg + (i>>2) + 2);
+ arc4->ID0R = *((u32 *) in_arg + (i>>2) + 3);
+
+ arc4->controlr.GO = 1;
+
+ while (arc4->controlr.BUS) {
+ // this will not take long
+ }
+
+#if 1
+ // need to handle nbytes not multiple of 16
+ tmp_array32[0] = arc4->OD3R;
+ tmp_array32[1] = arc4->OD2R;
+ tmp_array32[2] = arc4->OD1R;
+ tmp_array32[3] = arc4->OD0R;
+
+ remaining_bytes = nbytes - i;
+ if (remaining_bytes > 16)
+ remaining_bytes = 16;
+
+ tmp_ptr8 = (u8 *)&tmp_array32[0];
+ for (j = 0; j < remaining_bytes; j++)
+ *out_arg++ = *tmp_ptr8++;
+#else
+ *((u32 *) out_arg + (i>>2) + 0) = arc4->OD3R;
+ *((u32 *) out_arg + (i>>2) + 1) = arc4->OD2R;
+ *((u32 *) out_arg + (i>>2) + 2) = arc4->OD1R;
+ *((u32 *) out_arg + (i>>2) + 3) = arc4->OD0R;
+#endif
+
+ i += 16;
+ }
+#else // dma
+
+#endif // dma
+
+ CRTCL_SECT_END;
+}
+
+/*! \fn arc4_chip_init (void)
+ \ingroup IFX_ARC4_FUNCTIONS
+ \brief initialize arc4 hardware
+*/
+static void arc4_chip_init (void)
+{
+ //do nothing
+}
+
+/*! \fn static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len)
+ \ingroup IFX_ARC4_FUNCTIONS
+ \brief sets ARC4 key
+ \param tfm linux crypto algo transform
+ \param in_key input key
+ \param key_len key lengths less than or equal to 16 bytes supported
+*/
+static int arc4_set_key(struct crypto_tfm *tfm, const u8 *inkey,
+ unsigned int key_len)
+{
+ //struct arc4_ctx *ctx = crypto_tfm_ctx(tfm);
+ volatile struct arc4_t *arc4 = (struct arc4_t *) ARC4_START;
+ u32 *in_key = (u32 *)inkey;
+
+ // must program all bits at one go?!!!
+//#if 1
+ *IFX_ARC4_CON = ( (1<<31) | ((key_len - 1)<<27) | (1<<26) | (3<<16) );
+ //NDC=1,ENDI=1,GO=0,KSAE=1,SM=0
+
+ arc4->K3R = *((u32 *) in_key + 0);
+ arc4->K2R = *((u32 *) in_key + 1);
+ arc4->K1R = *((u32 *) in_key + 2);
+ arc4->K0R = *((u32 *) in_key + 3);
+
+#if 0 // arc4 is a ugly state machine, KSAE can only be set once per session
+ ctx->key_length = key_len;
+
+ memcpy ((u8 *) (ctx->buf), in_key, key_len);
+#endif
+
+ return 0;
+}
+
+/*! \fn static void _deu_arc4_ecb(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ \ingroup IFX_ARC4_FUNCTIONS
+ \brief sets ARC4 hardware to ECB mode
+ \param ctx crypto algo context
+ \param dst output bytestream
+ \param src input bytestream
+ \param iv initialization vector
+ \param nbytes length of bytestream
+ \param encdec 1 for encrypt; 0 for decrypt
+ \param inplace not used
+*/
+static void _deu_arc4_ecb(void *ctx, uint8_t *dst, const uint8_t *src,
+ uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+ _deu_arc4 (ctx, dst, src, NULL, nbytes, encdec, 0);
+}
+
+/*! \fn static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+ \ingroup IFX_ARC4_FUNCTIONS
+ \brief encrypt/decrypt ARC4_BLOCK_SIZE of data
+ \param tfm linux crypto algo transform
+ \param out output bytestream
+ \param in input bytestream
+*/
+static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+{
+ struct arc4_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ _deu_arc4 (ctx, out, in, NULL, ARC4_BLOCK_SIZE,
+ CRYPTO_DIR_DECRYPT, 0);
+
+}
+
+/*
+ * \brief ARC4 function mappings
+*/
+static struct crypto_alg ifxdeu_arc4_alg = {
+ .cra_name = "arc4",
+ .cra_driver_name = "ifxdeu-arc4",
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = ARC4_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct arc4_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_arc4_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = ARC4_MIN_KEY_SIZE,
+ .cia_max_keysize = ARC4_MAX_KEY_SIZE,
+ .cia_setkey = arc4_set_key,
+ .cia_encrypt = arc4_crypt,
+ .cia_decrypt = arc4_crypt,
+ }
+ }
+};
+
+/*! \fn static int ecb_arc4_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ \ingroup IFX_ARC4_FUNCTIONS
+ \brief ECB ARC4 encrypt using linux crypto blkcipher
+ \param desc blkcipher descriptor
+ \param dst output scatterlist
+ \param src input scatterlist
+ \param nbytes data size in bytes
+*/
+static int ecb_arc4_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct arc4_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ DPRINTF(1, "\n");
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ _deu_arc4_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
+ nbytes &= ARC4_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*! \fn static int ecb_arc4_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ \ingroup IFX_ARC4_FUNCTIONS
+ \brief ECB ARC4 decrypt using linux crypto blkcipher
+ \param desc blkcipher descriptor
+ \param dst output scatterlist
+ \param src input scatterlist
+ \param nbytes data size in bytes
+*/
+static int ecb_arc4_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct arc4_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ DPRINTF(1, "\n");
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ _deu_arc4_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
+ nbytes &= ARC4_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*
+ * \brief ARC4 function mappings
+*/
+static struct crypto_alg ifxdeu_ecb_arc4_alg = {
+ .cra_name = "ecb(arc4)",
+ .cra_driver_name = "ifxdeu-ecb(arc4)",
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = ARC4_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct arc4_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_ecb_arc4_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = ARC4_MIN_KEY_SIZE,
+ .max_keysize = ARC4_MAX_KEY_SIZE,
+ .setkey = arc4_set_key,
+ .encrypt = ecb_arc4_encrypt,
+ .decrypt = ecb_arc4_decrypt,
+ }
+ }
+};
+
+/*! \fn int __init ifxdeu_init_arc4(void)
+ \ingroup IFX_ARC4_FUNCTIONS
+ \brief initialize arc4 driver
+*/
+int __init ifxdeu_init_arc4(void)
+{
+ int ret = -ENOSYS;
+
+
+ if ((ret = crypto_register_alg(&ifxdeu_arc4_alg)))
+ goto arc4_err;
+
+ if ((ret = crypto_register_alg(&ifxdeu_ecb_arc4_alg)))
+ goto ecb_arc4_err;
+
+ arc4_chip_init ();
+
+ CRTCL_SECT_INIT;
+
+ printk (KERN_NOTICE "IFX DEU ARC4 initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
+ return ret;
+
+arc4_err:
+ crypto_unregister_alg(&ifxdeu_arc4_alg);
+ printk(KERN_ERR "IFX arc4 initialization failed!\n");
+ return ret;
+ecb_arc4_err:
+ crypto_unregister_alg(&ifxdeu_ecb_arc4_alg);
+ printk (KERN_ERR "IFX ecb_arc4 initialization failed!\n");
+ return ret;
+
+}
+
+/*! \fn void __exit ifxdeu_fini_arc4(void)
+ \ingroup IFX_ARC4_FUNCTIONS
+ \brief unregister arc4 driver
+*/
+void __exit ifxdeu_fini_arc4(void)
+{
+ crypto_unregister_alg (&ifxdeu_arc4_alg);
+ crypto_unregister_alg (&ifxdeu_ecb_arc4_alg);
+
+
+}
+
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_async_aes.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_async_aes.c
new file mode 100644
index 0000000000..64536daa99
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_async_aes.c
@@ -0,0 +1,1137 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_async_aes.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module
+**
+** DATE : October 11, 2010
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver for AES Algorithm
+** COPYRIGHT : Copyright (c) 2010
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+** 11, Oct 2010 Mohammad Firdaus Kernel Port incl. Async. Ablkcipher mode
+** 21,March 2011 Mohammad Firdaus Changes for Kernel 2.6.32 and IPSec integration
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx DEU driver module
+*/
+
+/*!
+ \file ifxmips_async_aes.c
+ \ingroup IFX_DEU
+ \brief AES Encryption Driver main file
+*/
+
+/*!
+ \defgroup IFX_AES_FUNCTIONS IFX_AES_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief IFX AES driver Functions
+*/
+
+
+
+#include <linux/wait.h>
+#include <linux/crypto.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <crypto/ctr.h>
+#include <crypto/aes.h>
+#include <crypto/algapi.h>
+#include <crypto/scatterwalk.h>
+
+#include <asm/ifx/ifx_regs.h>
+#include <asm/ifx/ifx_types.h>
+#include <asm/ifx/common_routines.h>
+#include <asm/ifx/irq.h>
+#include <asm/ifx/ifx_pmu.h>
+#include <asm/ifx/ifx_gpio.h>
+#include <asm/kmap_types.h>
+
+#include "ifxmips_deu.h"
+
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+extern int ifx_danube_pre_1_4;
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Unkown platform"
+#endif
+
+/* DMA related header and variables */
+
+spinlock_t aes_lock;
+#define CRTCL_SECT_INIT spin_lock_init(&aes_lock)
+#define CRTCL_SECT_START spin_lock_irqsave(&aes_lock, flag)
+#define CRTCL_SECT_END spin_unlock_irqrestore(&aes_lock, flag)
+
+/* Definition of constants */
+//#define AES_START IFX_AES_CON
+#define AES_MIN_KEY_SIZE 16
+#define AES_MAX_KEY_SIZE 32
+#define AES_BLOCK_SIZE 16
+#define CTR_RFC3686_NONCE_SIZE 4
+#define CTR_RFC3686_IV_SIZE 8
+#define CTR_RFC3686_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE)
+
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif /* CRYPTO_DEBUG */
+
+
+static int disable_multiblock = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+module_param(disable_multiblock, int, 0);
+#else
+MODULE_PARM_DESC(disable_multiblock, "Disable encryption of whole multiblock buffers");
+#endif
+
+static int disable_deudma = 1;
+
+/* Function decleration */
+int aes_chip_init(void);
+u32 endian_swap(u32 input);
+u32 input_swap(u32 input);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+int aes_memory_allocate(int value);
+int des_memory_allocate(int value);
+void memory_release(u32 *addr);
+
+
+struct aes_ctx {
+ int key_length;
+ u32 buf[AES_MAX_KEY_SIZE];
+ u8 nonce[CTR_RFC3686_NONCE_SIZE];
+
+};
+
+struct aes_container {
+ u8 *iv;
+ u8 *src_buf;
+ u8 *dst_buf;
+
+ int mode;
+ int encdec;
+ int complete;
+ int flag;
+
+ u32 bytes_processed;
+ u32 nbytes;
+
+ struct ablkcipher_request arequest;
+
+};
+
+aes_priv_t *aes_queue;
+extern deu_drv_priv_t deu_dma_priv;
+
+void hexdump(unsigned char *buf, unsigned int len)
+{
+ print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
+ 16, 1,
+ buf, len, false);
+}
+
+/*! \fn void lq_deu_aes_core (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg,
+ size_t nbytes, int encdec, int mode)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief main interface to AES hardware
+ * \param ctx_arg crypto algo context
+ * \param out_arg output bytestream
+ * \param in_arg input bytestream
+ * \param iv_arg initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param mode operation mode such as ebc, cbc, ctr
+ *
+*/
+
+static int lq_deu_aes_core (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+ u8 *iv_arg, size_t nbytes, int encdec, int mode)
+{
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+ volatile struct aes_t *aes = (volatile struct aes_t *) AES_START;
+ struct aes_ctx *ctx = (struct aes_ctx *)ctx_arg;
+ u32 *in_key = ctx->buf;
+ unsigned long flag;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+ int key_len = ctx->key_length;
+
+ volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON;
+ struct dma_device_info *dma_device = ifx_deu[0].dma_device;
+ deu_drv_priv_t *deu_priv = (deu_drv_priv_t *)dma_device->priv;
+ int wlen = 0;
+ //u32 *outcopy = NULL;
+ u32 *dword_mem_aligned_in = NULL;
+
+ CRTCL_SECT_START;
+
+ /* 128, 192 or 256 bit key length */
+ aes->controlr.K = key_len / 8 - 2;
+ if (key_len == 128 / 8) {
+ aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+ aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+ aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+ aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+ }
+ else if (key_len == 192 / 8) {
+ aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+ aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+ aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+ aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+ aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
+ aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
+ }
+ else if (key_len == 256 / 8) {
+ aes->K7R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
+ aes->K6R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
+ aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
+ aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
+ aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
+ aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
+ aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 6));
+ aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 7));
+ }
+ else {
+ printk (KERN_ERR "[%s %s %d]: Invalid key_len : %d\n", __FILE__, __func__, __LINE__, key_len);
+ CRTCL_SECT_END;
+ return -EINVAL;
+ }
+
+ /* let HW pre-process DEcryption key in any case (even if
+ ENcryption is used). Key Valid (KV) bit is then only
+ checked in decryption routine! */
+ aes->controlr.PNK = 1;
+
+ while (aes->controlr.BUS) {
+ // this will not take long
+ }
+ AES_DMA_MISC_CONFIG();
+
+ aes->controlr.E_D = !encdec; //encryption
+ aes->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
+
+ //aes->controlr.F = 128; //default; only for CFB and OFB modes; change only for customer-specific apps
+ if (mode > 0) {
+ aes->IV3R = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
+ aes->IV2R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
+ aes->IV1R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));
+ aes->IV0R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));
+ };
+
+
+ /* Prepare Rx buf length used in dma psuedo interrupt */
+ deu_priv->deu_rx_buf = (u32 *)out_arg;
+ deu_priv->deu_rx_len = nbytes;
+
+ /* memory alignment issue */
+ dword_mem_aligned_in = (u32 *) DEU_DWORD_REORDERING(in_arg, aes_buff_in, BUFFER_IN, nbytes);
+
+ dma->controlr.ALGO = 1; //AES
+ dma->controlr.BS = 0;
+ aes->controlr.DAU = 0;
+ dma->controlr.EN = 1;
+
+ while (aes->controlr.BUS) {
+ // wait for AES to be ready
+ };
+
+ deu_priv->outcopy = (u32 *) DEU_DWORD_REORDERING(out_arg, aes_buff_out, BUFFER_OUT, nbytes);
+ deu_priv->event_src = AES_ASYNC_EVENT;
+
+ wlen = dma_device_write (dma_device, (u8 *)dword_mem_aligned_in, nbytes, NULL);
+ if (wlen != nbytes) {
+ dma->controlr.EN = 0;
+ CRTCL_SECT_END;
+ printk (KERN_ERR "[%s %s %d]: dma_device_write fail!\n", __FILE__, __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ // WAIT_AES_DMA_READY();
+
+ CRTCL_SECT_END;
+
+ if (mode > 0) {
+ *((u32 *) iv_arg) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg));
+ *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
+ *((u32 *) iv_arg + 2) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));
+ *((u32 *) iv_arg + 3) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));
+ }
+
+ return -EINPROGRESS;
+}
+
+/* \fn static int count_sgs(struct scatterlist *sl, unsigned int total_bytes)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Counts and return the number of scatterlists
+ * \param *sl Function pointer to the scatterlist
+ * \param total_bytes The total number of bytes that needs to be encrypted/decrypted
+ * \return The number of scatterlists
+*/
+
+static int count_sgs(struct scatterlist *sl, unsigned int total_bytes)
+{
+ int i = 0;
+
+ do {
+ total_bytes -= sl[i].length;
+ i++;
+
+ } while (total_bytes > 0);
+
+ return i;
+}
+
+/* \fn void lq_sg_init(struct scatterlist *src,
+ * struct scatterlist *dst)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Maps the scatterlists into a source/destination page.
+ * \param *src Pointer to the source scatterlist
+ * \param *dst Pointer to the destination scatterlist
+*/
+
+static void lq_sg_init(struct aes_container *aes_con,struct scatterlist *src,
+ struct scatterlist *dst)
+{
+
+ struct page *dst_page, *src_page;
+
+ src_page = sg_virt(src);
+ aes_con->src_buf = (char *) src_page;
+
+ dst_page = sg_virt(dst);
+ aes_con->dst_buf = (char *) dst_page;
+
+}
+
+
+/* \fn static void lq_sg_complete(struct aes_container *aes_con)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Free the used up memory after encryt/decrypt.
+*/
+
+static void lq_sg_complete(struct aes_container *aes_con)
+{
+ unsigned long queue_flag;
+
+ spin_lock_irqsave(&aes_queue->lock, queue_flag);
+ kfree(aes_con);
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+}
+
+/* \fn static inline struct aes_container *aes_container_cast (
+ * struct scatterlist *dst)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Locate the structure aes_container in memory.
+ * \param *areq Pointer to memory location where ablkcipher_request is located
+ * \return *aes_cointainer The function pointer to aes_container
+*/
+static inline struct aes_container *aes_container_cast (
+ struct ablkcipher_request *areq)
+{
+ return container_of(areq, struct aes_container, arequest);
+}
+
+
+/* \fn static int process_next_packet(struct aes_container *aes_con, struct ablkcipher_request *areq,
+ * \ int state)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Process next packet to be encrypt/decrypt
+ * \param *aes_con AES container structure
+ * \param *areq Pointer to memory location where ablkcipher_request is located
+ * \param state The state of the current packet (part of scatterlist or new packet)
+ * \return -EINVAL: error, -EINPROGRESS: Crypto still running, 1: no more scatterlist
+*/
+
+static int process_next_packet(struct aes_container *aes_con, struct ablkcipher_request *areq,
+ int state)
+{
+ u8 *iv;
+ int mode, dir, err = -EINVAL;
+ unsigned long queue_flag;
+ u32 inc, nbytes, remain, chunk_size;
+ struct scatterlist *src = NULL;
+ struct scatterlist *dst = NULL;
+ struct crypto_ablkcipher *cipher;
+ struct aes_ctx *ctx;
+
+ spin_lock_irqsave(&aes_queue->lock, queue_flag);
+
+ dir = aes_con->encdec;
+ mode = aes_con->mode;
+ iv = aes_con->iv;
+
+ if (state & PROCESS_SCATTER) {
+ src = scatterwalk_sg_next(areq->src);
+ dst = scatterwalk_sg_next(areq->dst);
+
+ if (!src || !dst) {
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+ return 1;
+ }
+ }
+ else if (state & PROCESS_NEW_PACKET) {
+ src = areq->src;
+ dst = areq->dst;
+ }
+
+ remain = aes_con->bytes_processed;
+ chunk_size = src->length;
+
+ if (remain > DEU_MAX_PACKET_SIZE)
+ inc = DEU_MAX_PACKET_SIZE;
+ else if (remain > chunk_size)
+ inc = chunk_size;
+ else
+ inc = remain;
+
+ remain -= inc;
+ aes_con->nbytes = inc;
+
+ if (state & PROCESS_SCATTER) {
+ aes_con->src_buf += aes_con->nbytes;
+ aes_con->dst_buf += aes_con->nbytes;
+ }
+
+ lq_sg_init(aes_con, src, dst);
+
+ nbytes = aes_con->nbytes;
+
+ //printk("debug - Line: %d, func: %s, reqsize: %d, scattersize: %d\n",
+ // __LINE__, __func__, nbytes, chunk_size);
+
+ cipher = crypto_ablkcipher_reqtfm(areq);
+ ctx = crypto_ablkcipher_ctx(cipher);
+
+
+ if (aes_queue->hw_status == AES_IDLE)
+ aes_queue->hw_status = AES_STARTED;
+
+ aes_con->bytes_processed -= aes_con->nbytes;
+ err = ablkcipher_enqueue_request(&aes_queue->list, &aes_con->arequest);
+ if (err == -EBUSY) {
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+ printk("Failed to enqueue request, ln: %d, err: %d\n",
+ __LINE__, err);
+ return -EINVAL;
+ }
+
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+
+ err = lq_deu_aes_core(ctx, aes_con->dst_buf, aes_con->src_buf, iv, nbytes, dir, mode);
+ return err;
+
+}
+
+/* \fn static void process_queue (unsigned long data)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief tasklet to signal the dequeuing of the next packet to be processed
+ * \param unsigned long data Not used
+ * \return void
+*/
+
+static void process_queue(unsigned long data)
+{
+
+ DEU_WAKEUP_EVENT(deu_dma_priv.deu_thread_wait, AES_ASYNC_EVENT,
+ deu_dma_priv.aes_event_flags);
+}
+
+
+/* \fn static int aes_crypto_thread (void *data)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief AES thread that handles crypto requests from upper layer & DMA
+ * \param *data Not used
+ * \return -EINVAL: DEU failure, -EBUSY: DEU HW busy, 0: exit thread
+*/
+static int aes_crypto_thread (void *data)
+{
+ struct aes_container *aes_con = NULL;
+ struct ablkcipher_request *areq = NULL;
+ int err;
+ unsigned long queue_flag;
+
+ daemonize("lq_aes_thread");
+ printk("AES Queue Manager Starting\n");
+
+ while (1)
+ {
+ DEU_WAIT_EVENT(deu_dma_priv.deu_thread_wait, AES_ASYNC_EVENT,
+ deu_dma_priv.aes_event_flags);
+
+ spin_lock_irqsave(&aes_queue->lock, queue_flag);
+
+ /* wait to prevent starting a crypto session before
+ * exiting the dma interrupt thread.
+ */
+ if (aes_queue->hw_status == AES_STARTED) {
+ areq = ablkcipher_dequeue_request(&aes_queue->list);
+ aes_con = aes_container_cast(areq);
+ aes_queue->hw_status = AES_BUSY;
+ }
+ else if (aes_queue->hw_status == AES_IDLE) {
+ areq = ablkcipher_dequeue_request(&aes_queue->list);
+ aes_con = aes_container_cast(areq);
+ aes_queue->hw_status = AES_STARTED;
+ }
+ else if (aes_queue->hw_status == AES_BUSY) {
+ areq = ablkcipher_dequeue_request(&aes_queue->list);
+ aes_con = aes_container_cast(areq);
+ }
+ else if (aes_queue->hw_status == AES_COMPLETED) {
+ lq_sg_complete(aes_con);
+ aes_queue->hw_status = AES_IDLE;
+ areq->base.complete(&areq->base, 0);
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+ return 0;
+ }
+ //printk("debug ln: %d, bytes proc: %d\n", __LINE__, aes_con->bytes_processed);
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+
+ if (!aes_con) {
+ printk("AES_CON return null\n");
+ goto aes_done;
+ }
+
+ if (aes_con->bytes_processed == 0) {
+ goto aes_done;
+ }
+
+ /* Process new packet or the next packet in a scatterlist */
+ if (aes_con->flag & PROCESS_NEW_PACKET) {
+ aes_con->flag = PROCESS_SCATTER;
+ err = process_next_packet(aes_con, areq, PROCESS_NEW_PACKET);
+ }
+ else
+ err = process_next_packet(aes_con, areq, PROCESS_SCATTER);
+
+ if (err == -EINVAL) {
+ areq->base.complete(&areq->base, err);
+ lq_sg_complete(aes_con);
+ printk("src/dst returned -EINVAL in func: %s\n", __func__);
+ }
+ else if (err > 0) {
+ printk("src/dst returned zero in func: %s\n", __func__);
+ goto aes_done;
+ }
+
+ continue;
+
+aes_done:
+ //printk("debug line - %d, func: %s, qlen: %d\n", __LINE__, __func__, aes_queue->list.qlen);
+ areq->base.complete(&areq->base, 0);
+ lq_sg_complete(aes_con);
+
+ spin_lock_irqsave(&aes_queue->lock, queue_flag);
+ if (aes_queue->list.qlen > 0) {
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+ tasklet_schedule(&aes_queue->aes_task);
+ }
+ else {
+ aes_queue->hw_status = AES_IDLE;
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+ }
+ } //while(1)
+
+ return 0;
+}
+
+/* \fn static int lq_aes_queue_mgr(struct aes_ctx *ctx, struct ablkcipher_request *areq,
+ u8 *iv, int dir, int mode)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief starts the process of queuing DEU requests
+ * \param *ctx crypto algo contax
+ * \param *areq Pointer to the balkcipher requests
+ * \param *iv Pointer to intput vector location
+ * \param dir Encrypt/Decrypt
+ * \mode The mode AES algo is running
+ * \return 0 if success
+*/
+
+static int lq_aes_queue_mgr(struct aes_ctx *ctx, struct ablkcipher_request *areq,
+ u8 *iv, int dir, int mode)
+{
+ int err = -EINVAL;
+ unsigned long queue_flag;
+ struct scatterlist *src = areq->src;
+ struct scatterlist *dst = areq->dst;
+ struct aes_container *aes_con = NULL;
+ u32 remain, inc, nbytes = areq->nbytes;
+ u32 chunk_bytes = src->length;
+
+
+ aes_con = (struct aes_container *)kmalloc(sizeof(struct aes_container),
+ GFP_KERNEL);
+
+ if (!(aes_con)) {
+ printk("Cannot allocate memory for AES container, fn %s, ln %d\n",
+ __func__, __LINE__);
+ return -ENOMEM;
+ }
+
+ /* AES encrypt/decrypt mode */
+ if (mode == 5) {
+ nbytes = AES_BLOCK_SIZE;
+ chunk_bytes = AES_BLOCK_SIZE;
+ mode = 0;
+ }
+
+ aes_con->bytes_processed = nbytes;
+ aes_con->arequest = *(areq);
+ remain = nbytes;
+
+ //printk("debug - Line: %d, func: %s, reqsize: %d, scattersize: %d\n",
+ // __LINE__, __func__, nbytes, chunk_bytes);
+
+ if (remain > DEU_MAX_PACKET_SIZE)
+ inc = DEU_MAX_PACKET_SIZE;
+ else if (remain > chunk_bytes)
+ inc = chunk_bytes;
+ else
+ inc = remain;
+
+ remain -= inc;
+ lq_sg_init(aes_con, src, dst);
+
+ if (remain <= 0)
+ aes_con->complete = 1;
+ else
+ aes_con->complete = 0;
+
+ aes_con->nbytes = inc;
+ aes_con->iv = iv;
+ aes_con->mode = mode;
+ aes_con->encdec = dir;
+
+ spin_lock_irqsave(&aes_queue->lock, queue_flag);
+
+ if (aes_queue->hw_status == AES_STARTED || aes_queue->hw_status == AES_BUSY ||
+ aes_queue->list.qlen > 0) {
+
+ aes_con->flag = PROCESS_NEW_PACKET;
+ err = ablkcipher_enqueue_request(&aes_queue->list, &aes_con->arequest);
+
+ /* max queue length reached */
+ if (err == -EBUSY) {
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+ printk("Unable to enqueue request ln: %d, err: %d\n", __LINE__, err);
+ return err;
+ }
+
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+ return -EINPROGRESS;
+ }
+ else if (aes_queue->hw_status == AES_IDLE)
+ aes_queue->hw_status = AES_STARTED;
+
+ aes_con->flag = PROCESS_SCATTER;
+ aes_con->bytes_processed -= aes_con->nbytes;
+ /* or enqueue the whole structure so as to get back the info
+ * at the moment that it's queued. nbytes might be different */
+ err = ablkcipher_enqueue_request(&aes_queue->list, &aes_con->arequest);
+
+ if (err == -EBUSY) {
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+ printk("Unable to enqueue request ln: %d, err: %d\n", __LINE__, err);
+ return err;
+ }
+
+ spin_unlock_irqrestore(&aes_queue->lock, queue_flag);
+ return lq_deu_aes_core(ctx, aes_con->dst_buf, aes_con->src_buf, iv, inc, dir, mode);
+
+}
+
+/* \fn static int aes_setkey(struct crypto_ablkcipher *tfm, const u8 *in_key,
+ * unsigned int keylen)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Sets AES key
+ * \param *tfm Pointer to the ablkcipher transform
+ * \param *in_key Pointer to input keys
+ * \param key_len Length of the AES keys
+ * \return 0 is success, -EINVAL if bad key length
+*/
+
+static int aes_setkey(struct crypto_ablkcipher *tfm, const u8 *in_key,
+ unsigned int keylen)
+{
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+ unsigned long *flags = (unsigned long *) &tfm->base.crt_flags;
+
+ DPRINTF(2, "set_key in %s\n", __FILE__);
+
+ if (keylen != 16 && keylen != 24 && keylen != 32) {
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+
+ ctx->key_length = keylen;
+ DPRINTF(0, "ctx @%p, keylen %d, ctx->key_length %d\n", ctx, keylen, ctx->key_length);
+ memcpy ((u8 *) (ctx->buf), in_key, keylen);
+
+ return 0;
+
+}
+
+/* \fn static int aes_generic_setkey(struct crypto_ablkcipher *tfm, const u8 *in_key,
+ * unsigned int keylen)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Sets AES key
+ * \param *tfm Pointer to the ablkcipher transform
+ * \param *key Pointer to input keys
+ * \param keylen Length of AES keys
+ * \return 0 is success, -EINVAL if bad key length
+*/
+
+static int aes_generic_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ return aes_setkey(tfm, key, keylen);
+}
+
+/* \fn static int rfc3686_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *in_key,
+ * unsigned int keylen)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Sets AES key
+ * \param *tfm Pointer to the ablkcipher transform
+ * \param *in_key Pointer to input keys
+ * \param key_len Length of the AES keys
+ * \return 0 is success, -EINVAL if bad key length
+*/
+
+static int rfc3686_aes_setkey(struct crypto_ablkcipher *tfm,
+ const u8 *in_key, unsigned int keylen)
+{
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+ unsigned long *flags = (unsigned long *)&tfm->base.crt_flags;
+
+ DPRINTF(2, "ctr_rfc3686_aes_set_key in %s\n", __FILE__);
+
+ memcpy(ctx->nonce, in_key + (keylen - CTR_RFC3686_NONCE_SIZE),
+ CTR_RFC3686_NONCE_SIZE);
+
+ keylen -= CTR_RFC3686_NONCE_SIZE; // remove 4 bytes of nonce
+
+ if (keylen != 16 && keylen != 24 && keylen != 32) {
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+
+ ctx->key_length = keylen;
+
+ memcpy ((u8 *) (ctx->buf), in_key, keylen);
+
+ return 0;
+}
+
+/* \fn static int aes_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Encrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int aes_encrypt (struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, NULL, CRYPTO_DIR_ENCRYPT, 5);
+
+}
+
+/* \fn static int aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Decrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+static int aes_decrypt (struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, NULL, CRYPTO_DIR_DECRYPT, 5);
+}
+
+/* \fn static int ecb_aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Encrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int ecb_aes_encrypt (struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 0);
+
+}
+/* \fn static int ecb_aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Decrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+static int ecb_aes_decrypt(struct ablkcipher_request *areq)
+
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 0);
+}
+
+/* \fn static int cbc_aes_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Encrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int cbc_aes_encrypt (struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 1);
+
+}
+
+/* \fn static int cbc_aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Decrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int cbc_aes_decrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 1);
+}
+#if 0
+static int ofb_aes_encrypt (struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 2);
+
+}
+
+static int ofb_aes_decrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 2);
+}
+
+static int cfb_aes_encrypt (struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 3);
+
+}
+
+static int cfb_aes_decrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 3);
+}
+#endif
+
+/* \fn static int ctr_aes_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Encrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int ctr_aes_encrypt (struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 4);
+
+}
+
+/* \fn static int ctr_aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Decrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int ctr_aes_decrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 4);
+}
+
+/* \fn static int rfc3686_aes_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Encrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int rfc3686_aes_encrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ int ret;
+ u8 *info = areq->info;
+ u8 rfc3686_iv[16];
+
+ memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
+ memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, info, CTR_RFC3686_IV_SIZE);
+
+ /* initialize counter portion of counter block */
+ *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
+ cpu_to_be32(1);
+
+ areq->info = rfc3686_iv;
+ ret = lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 4);
+ areq->info = info;
+ return ret;
+}
+
+/* \fn static int rfc3686_aes_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Decrypt function for AES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int rfc3686_aes_decrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct aes_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ int ret;
+ u8 *info = areq->info;
+ u8 rfc3686_iv[16];
+
+ /* set up counter block */
+ memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
+ memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, info, CTR_RFC3686_IV_SIZE);
+
+ /* initialize counter portion of counter block */
+ *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
+ cpu_to_be32(1);
+
+ areq->info = rfc3686_iv;
+ ret = lq_aes_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 4);
+ areq->info = info;
+ return ret;
+}
+
+struct lq_aes_alg {
+ struct crypto_alg alg;
+};
+
+/* AES supported algo array */
+static struct lq_aes_alg aes_drivers_alg[] = {
+ {
+ .alg = {
+ .cra_name = "aes",
+ .cra_driver_name = "ifxdeu-aes",
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_priority = 300,
+ .cra_module = THIS_MODULE,
+ .cra_ablkcipher = {
+ .setkey = aes_setkey,
+ .encrypt = aes_encrypt,
+ .decrypt = aes_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ }
+ }
+ },{
+ .alg = {
+ .cra_name = "ecb(aes)",
+ .cra_driver_name = "ifxdeu-ecb(aes)",
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_priority = 300,
+ .cra_module = THIS_MODULE,
+ .cra_ablkcipher = {
+ .setkey = aes_generic_setkey,
+ .encrypt = ecb_aes_encrypt,
+ .decrypt = ecb_aes_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ }
+ }
+ },{
+ .alg = {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "ifxdeu-cbc(aes)",
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_priority = 300,
+ .cra_module = THIS_MODULE,
+ .cra_ablkcipher = {
+ .setkey = aes_generic_setkey,
+ .encrypt = cbc_aes_encrypt,
+ .decrypt = cbc_aes_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ }
+ }
+ },{
+ .alg = {
+ .cra_name = "ctr(aes)",
+ .cra_driver_name = "ifxdeu-ctr(aes)",
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_priority = 300,
+ .cra_module = THIS_MODULE,
+ .cra_ablkcipher = {
+ .setkey = aes_generic_setkey,
+ .encrypt = ctr_aes_encrypt,
+ .decrypt = ctr_aes_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ }
+ }
+ },{
+ .alg = {
+ .cra_name = "rfc3686(ctr(aes))",
+ .cra_driver_name = "ifxdeu-rfc3686(ctr(aes))",
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_priority = 300,
+ .cra_module = THIS_MODULE,
+ .cra_ablkcipher = {
+ .setkey = rfc3686_aes_setkey,
+ .encrypt = rfc3686_aes_encrypt,
+ .decrypt = rfc3686_aes_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = CTR_RFC3686_MAX_KEY_SIZE,
+ //.max_keysize = AES_MAX_KEY_SIZE,
+ //.ivsize = CTR_RFC3686_IV_SIZE,
+ .ivsize = AES_BLOCK_SIZE, // else cannot reg
+ }
+ }
+ }
+};
+
+/* \fn int __init lqdeu_async_aes_init (void)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief Initializes the Async. AES driver
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+int __init lqdeu_async_aes_init (void)
+{
+ int i, j, ret = -EINVAL;
+
+#define IFX_DEU_DRV_VERSION "2.0.0"
+ printk(KERN_INFO "Lantiq Technologies DEU Driver version %s\n", IFX_DEU_DRV_VERSION);
+
+ for (i = 0; i < ARRAY_SIZE(aes_drivers_alg); i++) {
+ ret = crypto_register_alg(&aes_drivers_alg[i].alg);
+ printk("driver: %s\n", aes_drivers_alg[i].alg.cra_name);
+ if (ret)
+ goto aes_err;
+ }
+
+ aes_chip_init();
+
+ CRTCL_SECT_INIT;
+
+
+ printk (KERN_NOTICE "Lantiq DEU AES initialized %s %s.\n",
+ disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
+
+ return ret;
+
+aes_err:
+
+ for (j = 0; j < i; j++)
+ crypto_unregister_alg(&aes_drivers_alg[j].alg);
+
+ printk(KERN_ERR "Lantiq %s driver initialization failed!\n", (char *)&aes_drivers_alg[i].alg.cra_driver_name);
+ return ret;
+
+ctr_rfc3686_aes_err:
+ for (i = 0; i < ARRAY_SIZE(aes_drivers_alg); i++) {
+ if (!strcmp((char *)&aes_drivers_alg[i].alg.cra_name, "rfc3686(ctr(aes))"))
+ crypto_unregister_alg(&aes_drivers_alg[j].alg);
+ }
+ printk (KERN_ERR "Lantiq ctr_rfc3686_aes initialization failed!\n");
+ return ret;
+}
+
+/*! \fn void __exit ifxdeu_fini_aes (void)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief unregister aes driver
+*/
+void __exit lqdeu_fini_async_aes (void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(aes_drivers_alg); i++)
+ crypto_unregister_alg(&aes_drivers_alg[i].alg);
+
+ aes_queue->hw_status = AES_COMPLETED;
+
+ DEU_WAKEUP_EVENT(deu_dma_priv.deu_thread_wait, AES_ASYNC_EVENT,
+ deu_dma_priv.aes_event_flags);
+
+ kfree(aes_queue);
+
+}
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_async_des.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_async_des.c
new file mode 100644
index 0000000000..9c593aeb49
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_async_des.c
@@ -0,0 +1,954 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_async_des.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module
+**
+** DATE : October 11, 2010
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver for DES Algorithm
+** COPYRIGHT : Copyright (c) 2010
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+** 11, Oct 2010 Mohammad Firdaus Kernel Port incl. Async. Ablkcipher mode
+** 21,March 2011 Mohammad Firdaus Changes for Kernel 2.6.32 and IPSec integration
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx DEU driver module
+*/
+
+/*!
+ \file ifxmips_async_des.c
+ \ingroup IFX_DEU
+ \brief DES Encryption Driver main file
+*/
+
+/*!
+ \defgroup IFX_DES_FUNCTIONS IFX_DES_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief IFX DES driver Functions
+*/
+
+#include <linux/wait.h>
+#include <linux/crypto.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <crypto/ctr.h>
+#include <crypto/aes.h>
+#include <crypto/algapi.h>
+#include <crypto/scatterwalk.h>
+
+#include <asm/ifx/ifx_regs.h>
+#include <asm/ifx/ifx_types.h>
+#include <asm/ifx/common_routines.h>
+#include <asm/ifx/irq.h>
+#include <asm/ifx/ifx_pmu.h>
+#include <asm/ifx/ifx_gpio.h>
+#include <asm/kmap_types.h>
+
+#include "ifxmips_deu.h"
+
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+extern int ifx_danube_pre_1_4;
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Unkown platform"
+#endif
+
+/* DMA specific header and variables */
+
+spinlock_t des_lock;
+#define CRTCL_SECT_INIT spin_lock_init(&des_lock)
+#define CRTCL_SECT_START spin_lock_irqsave(&des_lock, flag)
+#define CRTCL_SECT_END spin_unlock_irqrestore(&des_lock, flag)
+
+/* Preprocessor declerations */
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+//#define DES_3DES_START IFX_DES_CON
+#define DES_KEY_SIZE 8
+#define DES_EXPKEY_WORDS 32
+#define DES_BLOCK_SIZE 8
+#define DES3_EDE_KEY_SIZE (3 * DES_KEY_SIZE)
+#define DES3_EDE_EXPKEY_WORDS (3 * DES_EXPKEY_WORDS)
+#define DES3_EDE_BLOCK_SIZE DES_BLOCK_SIZE
+
+/* Function Declaration to prevent warning messages */
+void des_chip_init (void);
+u32 endian_swap(u32 input);
+u32 input_swap(u32 input);
+int aes_memory_allocate(int value);
+int des_memory_allocate(int value);
+void memory_release(u32 *buffer);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+
+static int lq_deu_des_core (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+ u8 *iv_arg, u32 nbytes, int encdec, int mode);
+
+struct des_ctx {
+ int controlr_M;
+ int key_length;
+ u8 iv[DES_BLOCK_SIZE];
+ u32 expkey[DES3_EDE_EXPKEY_WORDS];
+};
+
+
+static int disable_multiblock = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+module_param(disable_multiblock, int, 0);
+#else
+MODULE_PARM_DESC(disable_multiblock, "Disable encryption of whole multiblock buffers");
+#endif
+
+static int disable_deudma = 1;
+
+struct des_container {
+ u8 *iv;
+ u8 *dst_buf;
+ u8 *src_buf;
+ int mode;
+ int encdec;
+ int complete;
+ int flag;
+
+ u32 bytes_processed;
+ u32 nbytes;
+
+ struct ablkcipher_request arequest;
+};
+
+des_priv_t *des_queue;
+extern deu_drv_priv_t deu_dma_priv;
+
+void hexdump1(unsigned char *buf, unsigned int len)
+{
+ print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
+ 16, 1,
+ buf, len, false);
+}
+
+
+/*! \fn int lq_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief sets DES key
+ * \param tfm linux crypto algo transform
+ * \param key input key
+ * \param keylen key length
+*/
+static int lq_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct des_ctx *dctx = crypto_ablkcipher_ctx(tfm);
+
+ //printk("setkey in %s\n", __FILE__);
+
+ dctx->controlr_M = 0; // des
+ dctx->key_length = keylen;
+
+ memcpy ((u8 *) (dctx->expkey), key, keylen);
+
+ return 0;
+}
+
+/*! \fn int lq_des3_ede_setkey(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief sets DES key
+ * \param tfm linux crypto algo transform
+ * \param key input key
+ * \param keylen key length
+*/
+
+static int lq_des3_ede_setkey(struct crypto_ablkcipher *tfm, const u8 *in_key,
+ unsigned int keylen)
+{
+ struct des_ctx *dctx = crypto_ablkcipher_ctx(tfm);
+
+ //printk("setkey in %s\n", __FILE__);
+
+ dctx->controlr_M = keylen/8 + 1; // des
+ dctx->key_length = keylen;
+
+ memcpy ((u8 *) (dctx->expkey), in_key, keylen);
+
+ return 0;
+}
+
+/*! \fn void ifx_deu_des_core(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief main interface to DES hardware
+ * \param ctx_arg crypto algo context
+ * \param out_arg output bytestream
+ * \param in_arg input bytestream
+ * \param iv_arg initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param mode operation mode such as ebc, cbc
+*/
+
+static int lq_deu_des_core (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+ u8 *iv_arg, u32 nbytes, int encdec, int mode)
+{
+ volatile struct des_t *des = (struct des_t *) DES_3DES_START;
+ struct des_ctx *dctx = ctx_arg;
+ u32 *key = dctx->expkey;
+ unsigned long flag;
+
+ int i = 0;
+ int nblocks = 0;
+
+ CRTCL_SECT_START;
+
+ des->controlr.M = dctx->controlr_M;
+ if (dctx->controlr_M == 0) // des
+ {
+ des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
+ des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
+
+ }
+ else {
+ /* Hardware Section */
+ switch (dctx->key_length) {
+ case 24:
+ des->K3HR = DEU_ENDIAN_SWAP(*((u32 *) key + 4));
+ des->K3LR = DEU_ENDIAN_SWAP(*((u32 *) key + 5));
+ /* no break; */
+
+ case 16:
+ des->K2HR = DEU_ENDIAN_SWAP(*((u32 *) key + 2));
+ des->K2LR = DEU_ENDIAN_SWAP(*((u32 *) key + 3));
+
+ /* no break; */
+ case 8:
+ des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
+ des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
+ break;
+
+ default:
+ CRTCL_SECT_END;
+ return -EINVAL;
+ }
+ }
+
+ des->controlr.E_D = !encdec; //encryption
+ des->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR hexdump(prin,sizeof(*des));
+
+ if (mode > 0) {
+ des->IVHR = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
+ des->IVLR = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
+ };
+
+ /* memory alignment issue */
+ dword_mem_aligned_in = (u32 *) DEU_DWORD_REORDERING(in_arg, des_buff_in, BUFFER_IN, nbytes);
+
+ deu_priv->deu_rx_buf = (u32 *) out_arg;
+ deu_priv->deu_rx_len = nbytes;
+
+ dma->controlr.ALGO = 0; //DES
+ des->controlr.DAU = 0;
+ dma->controlr.BS = 0;
+ dma->controlr.EN = 1;
+
+ while (des->controlr.BUS) {
+ };
+
+ wlen = dma_device_write (dma_device, (u8 *) dword_mem_aligned_in, nbytes, NULL);
+ if (wlen != nbytes) {
+ dma->controlr.EN = 0;
+ CRTCL_SECT_END;
+ printk (KERN_ERR "[%s %s %d]: dma_device_write fail!\n", __FILE__, __func__, __LINE__);
+ return -EINVAL;
+ }
+
+
+ /* Prepare Rx buf length used in dma psuedo interrupt */
+ outcopy = (u32 *) DEU_DWORD_REORDERING(out_arg, des_buff_out, BUFFER_OUT, nbytes);
+ deu_priv->outcopy = outcopy;
+ deu_priv->event_src = DES_ASYNC_EVENT;
+
+ if (mode > 0) {
+ *(u32 *) iv_arg = DEU_ENDIAN_SWAP(des->IVHR);
+ *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(des->IVLR);
+ };
+
+ CRTCL_SECT_END;
+
+ return -EINPROGRESS;
+
+}
+
+static int count_sgs(struct scatterlist *sl, unsigned int total_bytes)
+{
+ int i = 0;
+
+ do {
+ total_bytes -= sl[i].length;
+ i++;
+
+ } while (total_bytes > 0);
+
+ return i;
+}
+
+/* \fn static inline struct des_container *des_container_cast (
+ * struct scatterlist *dst)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Locate the structure des_container in memory.
+ * \param *areq Pointer to memory location where ablkcipher_request is located
+ * \return *des_cointainer The function pointer to des_container
+*/
+
+static inline struct des_container *des_container_cast(
+ struct ablkcipher_request *areq)
+{
+ return container_of(areq, struct des_container, arequest);
+}
+
+/* \fn static void lq_sg_complete(struct des_container *des_con)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Free the used up memory after encryt/decrypt.
+*/
+
+static void lq_sg_complete(struct des_container *des_con)
+{
+ unsigned long queue_flag;
+
+ spin_lock_irqsave(&des_queue->lock, queue_flag);
+ kfree(des_con);
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+}
+
+/* \fn void lq_sg_init(struct scatterlist *src,
+ * struct scatterlist *dst)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Maps the scatterlists into a source/destination page.
+ * \param *src Pointer to the source scatterlist
+ * \param *dst Pointer to the destination scatterlist
+*/
+
+static void lq_sg_init(struct des_container *des_con, struct scatterlist *src,
+ struct scatterlist *dst)
+{
+ struct page *dst_page, *src_page;
+
+ src_page = sg_virt(src);
+ des_con->src_buf = (char *) src_page;
+
+ dst_page = sg_virt(dst);
+ des_con->dst_buf = (char *) dst_page;
+}
+
+/* \fn static int process_next_packet(struct des_container *des_con, struct ablkcipher_request *areq,
+ * int state)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Process the next packet after dequeuing the packet from crypto queue
+ * \param *des_con Pointer to DES container structure
+ * \param *areq Pointer to ablkcipher_request container
+ * \param state State of the packet (scattered packet or new packet to be processed)
+ * \return -EINVAL: DEU failure, -EINPROGRESS: DEU encrypt/decrypt in progress, 1: no scatterlist left
+*/
+
+static int process_next_packet(struct des_container *des_con, struct ablkcipher_request *areq,
+ int state)
+{
+ u8 *iv;
+ int mode, encdec, err = -EINVAL;
+ u32 remain, inc, chunk_size, nbytes;
+ struct scatterlist *src = NULL;
+ struct scatterlist *dst = NULL;
+ struct crypto_ablkcipher *cipher;
+ struct des_ctx *ctx;
+ unsigned long queue_flag;
+
+ spin_lock_irqsave(&des_queue->lock, queue_flag);
+
+ mode = des_con->mode;
+ encdec = des_con->encdec;
+ iv = des_con->iv;
+
+ if (state & PROCESS_SCATTER) {
+ src = scatterwalk_sg_next(areq->src);
+ dst = scatterwalk_sg_next(areq->dst);
+
+ if (!src || !dst) {
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+ return 1;
+ }
+ }
+ else if (state & PROCESS_NEW_PACKET) {
+ src = areq->src;
+ dst = areq->dst;
+ }
+
+ remain = des_con->bytes_processed;
+ chunk_size = src->length;
+
+ //printk("debug ln: %d, func: %s, reqsize: %d, scattersize: %d\n",
+// __LINE__, __func__, areq->nbytes, chunk_size);
+
+ if (remain > DEU_MAX_PACKET_SIZE)
+ inc = DEU_MAX_PACKET_SIZE;
+ else if(remain > chunk_size)
+ inc = chunk_size;
+ else
+ inc = remain;
+
+ remain -= inc;
+ des_con->nbytes = inc;
+
+ if (state & PROCESS_SCATTER) {
+ des_con->src_buf += des_con->nbytes;
+ des_con->dst_buf += des_con->nbytes;
+ }
+
+ lq_sg_init(des_con, src, dst);
+
+ nbytes = des_con->nbytes;
+
+ cipher = crypto_ablkcipher_reqtfm(areq);
+ ctx = crypto_ablkcipher_ctx(cipher);
+
+ if (des_queue->hw_status == DES_IDLE) {
+ des_queue->hw_status = DES_STARTED;
+ }
+
+ des_con->bytes_processed -= des_con->nbytes;
+ err = ablkcipher_enqueue_request(&des_queue->list, &des_con->arequest);
+ if (err == -EBUSY) {
+ printk("Failed to enqueue request, ln: %d, err: %d\n",
+ __LINE__, err);
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+ return -EINVAL;
+ }
+
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+ err = lq_deu_des_core(ctx, des_con->dst_buf, des_con->src_buf, iv, nbytes, encdec, mode);
+
+ return err;
+}
+
+/* \fn static void process_queue(unsigned long data)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Process next packet in queue
+ * \param data not used
+ * \return
+*/
+
+static void process_queue(unsigned long data)
+{
+ DEU_WAKEUP_EVENT(deu_dma_priv.deu_thread_wait, DES_ASYNC_EVENT,
+ deu_dma_priv.des_event_flags);
+
+}
+
+/* \fn static int des_crypto_thread (void *data)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief DES thread that handles crypto requests from upper layer & DMA
+ * \param *data Not used
+ * \return -EINVAL: DEU failure, -EBUSY: DEU HW busy, 0: exit thread
+*/
+
+static int des_crypto_thread(void *data)
+{
+ struct des_container *des_con = NULL;
+ struct ablkcipher_request *areq = NULL;
+ int err;
+ unsigned long queue_flag;
+
+ daemonize("lq_des_thread");
+
+ while (1)
+ {
+ DEU_WAIT_EVENT(deu_dma_priv.deu_thread_wait, DES_ASYNC_EVENT,
+ deu_dma_priv.des_event_flags);
+ spin_lock_irqsave(&des_queue->lock, queue_flag);
+
+ /* wait to prevent starting a crypto session before
+ * exiting the dma interrupt thread.
+ */
+
+ if (des_queue->hw_status == DES_STARTED) {
+ areq = ablkcipher_dequeue_request(&des_queue->list);
+ des_con = des_container_cast(areq);
+ des_queue->hw_status = DES_BUSY;
+ }
+ else if (des_queue->hw_status == DES_IDLE) {
+ areq = ablkcipher_dequeue_request(&des_queue->list);
+ des_con = des_container_cast(areq);
+ des_queue->hw_status = DES_STARTED;
+ }
+ else if (des_queue->hw_status == DES_BUSY) {
+ areq = ablkcipher_dequeue_request(&des_queue->list);
+ des_con = des_container_cast(areq);
+ }
+ else if (des_queue->hw_status == DES_COMPLETED) {
+ areq->base.complete(&areq->base, 0);
+ lq_sg_complete(des_con);
+ des_queue->hw_status = DES_IDLE;
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+ return 0;
+ }
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+
+ if ((des_con->bytes_processed == 0)) {
+ goto des_done;
+ }
+
+ if (!des_con) {
+ goto des_done;
+ }
+
+ if (des_con->flag & PROCESS_NEW_PACKET) {
+ des_con->flag = PROCESS_SCATTER;
+ err = process_next_packet(des_con, areq, PROCESS_NEW_PACKET);
+ }
+ else
+ err = process_next_packet(des_con, areq, PROCESS_SCATTER);
+
+ if (err == -EINVAL) {
+ areq->base.complete(&areq->base, err);
+ lq_sg_complete(des_con);
+ printk("src/dst returned -EINVAL in func: %s\n", __func__);
+ }
+ else if (err > 0) {
+ printk("src/dst returned zero in func: %s\n", __func__);
+ goto des_done;
+ }
+
+ continue;
+
+des_done:
+ //printk("debug line - %d, func: %s, qlen: %d\n", __LINE__, __func__, des_queue->list.qlen);
+ areq->base.complete(&areq->base, 0);
+ lq_sg_complete(des_con);
+
+ spin_lock_irqsave(&des_queue->lock, queue_flag);
+ if (des_queue->list.qlen > 0) {
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+ tasklet_schedule(&des_queue->des_task);
+ }
+ else {
+ des_queue->hw_status = DES_IDLE;
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+ }
+ } // while(1)
+
+ return 0;
+
+}
+
+/* \fn static int lq_des_queue_mgr(struct des_ctx *ctx, struct ablkcipher_request *areq,
+ u8 *iv, int encdec, int mode)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief starts the process of queuing DEU requests
+ * \param *ctx crypto algo contax
+ * \param *areq Pointer to the balkcipher requests
+ * \param *iv Pointer to intput vector location
+ * \param dir Encrypt/Decrypt
+ * \mode The mode DES algo is running
+ * \return 0 if success
+*/
+
+static int lq_queue_mgr(struct des_ctx *ctx, struct ablkcipher_request *areq,
+ u8 *iv, int encdec, int mode)
+{
+ int err = -EINVAL;
+ unsigned long queue_flag;
+ struct scatterlist *src = areq->src;
+ struct scatterlist *dst = areq->dst;
+ struct des_container *des_con = NULL;
+ u32 remain, inc, nbytes = areq->nbytes;
+ u32 chunk_bytes = src->length;
+
+ des_con = (struct des_container *)kmalloc(sizeof(struct des_container),
+ GFP_KERNEL);
+
+ if (!(des_con)) {
+ printk("Cannot allocate memory for AES container, fn %s, ln %d\n",
+ __func__, __LINE__);
+ return -ENOMEM;
+ }
+
+ /* DES encrypt/decrypt mode */
+ if (mode == 5) {
+ nbytes = DES_BLOCK_SIZE;
+ chunk_bytes = DES_BLOCK_SIZE;
+ mode = 0;
+ }
+
+ des_con->bytes_processed = nbytes;
+ des_con->arequest = (*areq);
+ remain = nbytes;
+
+ //printk("debug - Line: %d, func: %s, reqsize: %d, scattersize: %d\n",
+ // __LINE__, __func__, nbytes, chunk_bytes);
+
+ if (remain > DEU_MAX_PACKET_SIZE)
+ inc = DEU_MAX_PACKET_SIZE;
+ else if(remain > chunk_bytes)
+ inc = chunk_bytes;
+ else
+ inc = remain;
+
+ remain -= inc;
+ lq_sg_init(des_con, src, dst);
+
+ if (remain <= 0 ) {
+ des_con->complete = 1;
+ }
+ else
+ des_con->complete = 0;
+
+ des_con->nbytes = inc;
+ des_con->iv = iv;
+ des_con->mode = mode;
+ des_con->encdec = encdec;
+
+ spin_lock_irqsave(&des_queue->lock, queue_flag);
+
+ if (des_queue->hw_status == DES_STARTED || des_queue->hw_status == DES_BUSY ||
+ des_queue->list.qlen > 0) {
+
+ des_con->flag = PROCESS_NEW_PACKET;
+ err = ablkcipher_enqueue_request(&des_queue->list, &des_con->arequest);
+ if (err == -EBUSY) {
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+ printk("Fail to enqueue ablkcipher request ln: %d, err: %d\n",
+ __LINE__, err);
+ return err;
+ }
+
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+ return -EINPROGRESS;
+
+ }
+ else if (des_queue->hw_status == DES_IDLE) {
+ des_queue->hw_status = DES_STARTED;
+ }
+
+ des_con->flag = PROCESS_SCATTER;
+ des_con->bytes_processed -= des_con->nbytes;
+
+ err = ablkcipher_enqueue_request(&des_queue->list, &des_con->arequest);
+ if (err == -EBUSY) {
+ printk("Fail to enqueue ablkcipher request ln: %d, err: %d\n",
+ __LINE__, err);
+
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+ return err;
+ }
+
+ spin_unlock_irqrestore(&des_queue->lock, queue_flag);
+ return lq_deu_des_core(ctx, des_con->dst_buf, des_con->src_buf, iv, inc, encdec, mode);
+
+}
+
+/* \fn static int lq_des_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int lq_des_encrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_queue_mgr(ctx, areq, NULL, CRYPTO_DIR_ENCRYPT, 5);
+
+}
+
+/* \fn static int lq_des_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int lq_des_decrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_queue_mgr(ctx, areq, NULL, CRYPTO_DIR_DECRYPT, 5);
+}
+
+/* \fn static int lq_ecb_des_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int lq_ecb_des_encrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 0);
+}
+
+/* \fn static int lq_ecb_des_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+static int lq_ecb_des_decrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 0);
+
+}
+
+/* \fn static int lq_cbc_ecb_des_encrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int lq_cbc_des_encrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_ENCRYPT, 1);
+}
+/* \fn static int lq_cbc_des_decrypt(struct ablkcipher_request *areq)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief Decrypt function for DES algo
+ * \param *areq Pointer to ablkcipher request in memory
+ * \return 0 is success, -EINPROGRESS if encryting, EINVAL if failure
+*/
+
+static int lq_cbc_des_decrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct des_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return lq_queue_mgr(ctx, areq, areq->info, CRYPTO_DIR_DECRYPT, 1);
+}
+
+struct lq_des_alg {
+ struct crypto_alg alg;
+};
+
+/* DES Supported algo array */
+static struct lq_des_alg des_drivers_alg [] = {
+ {
+ .alg = {
+ .cra_name = "des",
+ .cra_driver_name = "lqdeu-des",
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_priority = 300,
+ .cra_module = THIS_MODULE,
+ .cra_ablkcipher = {
+ .setkey = lq_des_setkey,
+ .encrypt = lq_des_encrypt,
+ .decrypt = lq_des_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = DES_KEY_SIZE,
+ .max_keysize = DES_KEY_SIZE,
+ .ivsize = DES_BLOCK_SIZE,
+ }
+ }
+
+ },{
+ .alg = {
+ .cra_name = "ecb(des)",
+ .cra_driver_name = "lqdeu-ecb(des)",
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_priority = 300,
+ .cra_module = THIS_MODULE,
+ .cra_ablkcipher = {
+ .setkey = lq_des_setkey,
+ .encrypt = lq_ecb_des_encrypt,
+ .decrypt = lq_ecb_des_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = DES_KEY_SIZE,
+ .max_keysize = DES_KEY_SIZE,
+ .ivsize = DES_BLOCK_SIZE,
+ }
+ }
+ },{
+ .alg = {
+ .cra_name = "cbc(des)",
+ .cra_driver_name = "lqdeu-cbc(des)",
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_priority = 300,
+ .cra_module = THIS_MODULE,
+ .cra_ablkcipher = {
+ .setkey = lq_des_setkey,
+ .encrypt = lq_cbc_des_encrypt,
+ .decrypt = lq_cbc_des_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = DES3_EDE_KEY_SIZE,
+ .max_keysize = DES3_EDE_KEY_SIZE,
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ }
+ }
+ },{
+ .alg = {
+ .cra_name = "des3_ede",
+ .cra_driver_name = "lqdeu-des3_ede",
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_priority = 300,
+ .cra_module = THIS_MODULE,
+ .cra_ablkcipher = {
+ .setkey = lq_des3_ede_setkey,
+ .encrypt = lq_des_encrypt,
+ .decrypt = lq_des_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = DES_KEY_SIZE,
+ .max_keysize = DES_KEY_SIZE,
+ .ivsize = DES_BLOCK_SIZE,
+ }
+ }
+ },{
+ .alg = {
+ .cra_name = "ecb(des3_ede)",
+ .cra_driver_name = "lqdeu-ecb(des3_ede)",
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_priority = 300,
+ .cra_module = THIS_MODULE,
+ .cra_ablkcipher = {
+ .setkey = lq_des3_ede_setkey,
+ .encrypt = lq_ecb_des_encrypt,
+ .decrypt = lq_ecb_des_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = DES3_EDE_KEY_SIZE,
+ .max_keysize = DES3_EDE_KEY_SIZE,
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ }
+ }
+ },{
+ .alg = {
+ .cra_name = "cbc(des3_ede)",
+ .cra_driver_name = "lqdeu-cbc(des3_ede)",
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_priority = 300,
+ .cra_module = THIS_MODULE,
+ .cra_ablkcipher = {
+ .setkey = lq_des3_ede_setkey,
+ .encrypt = lq_cbc_des_encrypt,
+ .decrypt = lq_cbc_des_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = DES3_EDE_KEY_SIZE,
+ .max_keysize = DES3_EDE_KEY_SIZE,
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ }
+ }
+ }
+};
+
+/*! \fn int __init lqdeu_async_des_init (void)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief initialize des driver
+*/
+int __init lqdeu_async_des_init (void)
+{
+ int i, j, ret = -EINVAL;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+ if (!disable_multiblock) {
+ ifxdeu_des_alg.cra_u.cipher.cia_max_nbytes = DES_BLOCK_SIZE; //(size_t)-1;
+ ifxdeu_des_alg.cra_u.cipher.cia_req_align = 16;
+ ifxdeu_des_alg.cra_u.cipher.cia_ecb = ifx_deu_des_ecb;
+ ifxdeu_des_alg.cra_u.cipher.cia_cbc = ifx_deu_des_cbc;
+ ifxdeu_des_alg.cra_u.cipher.cia_cfb = ifx_deu_des_cfb;
+ ifxdeu_des_alg.cra_u.cipher.cia_ofb = ifx_deu_des_ofb;
+ }
+#endif
+ for (i = 0; i < ARRAY_SIZE(des_drivers_alg); i++) {
+ ret = crypto_register_alg(&des_drivers_alg[i].alg);
+ //printk("driver: %s\n", des_drivers_alg[i].alg.cra_name);
+ if (ret)
+ goto des_err;
+ }
+
+ des_chip_init();
+ CRTCL_SECT_INIT;
+
+
+ printk (KERN_NOTICE "IFX DEU DES initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
+ return ret;
+
+des_err:
+ for (j = 0; j < i; j++)
+ crypto_unregister_alg(&des_drivers_alg[i].alg);
+
+ printk(KERN_ERR "Lantiq %s driver initialization failed!\n", (char *)&des_drivers_alg[i].alg.cra_driver_name);
+ return ret;
+
+cbc_des3_ede_err:
+ for (i = 0; i < ARRAY_SIZE(des_drivers_alg); i++) {
+ if (!strcmp((char *)&des_drivers_alg[i].alg.cra_name, "cbc(des3_ede)"))
+ crypto_unregister_alg(&des_drivers_alg[i].alg);
+ }
+
+ printk(KERN_ERR "Lantiq %s driver initialization failed!\n", (char *)&des_drivers_alg[i].alg.cra_driver_name);
+ return ret;
+}
+
+/*! \fn void __exit lqdeu_fini_async_des (void)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief unregister des driver
+*/
+void __exit lqdeu_fini_async_des (void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(des_drivers_alg); i++)
+ crypto_unregister_alg(&des_drivers_alg[i].alg);
+
+ des_queue->hw_status = DES_COMPLETED;
+ DEU_WAKEUP_EVENT(deu_dma_priv.deu_thread_wait, DES_ASYNC_EVENT,
+ deu_dma_priv.des_event_flags);
+
+ kfree(des_queue);
+}
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_des.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_des.c
new file mode 100644
index 0000000000..dcf6c18a98
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_des.c
@@ -0,0 +1,768 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_des.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver for DES Algorithm
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08 Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx deu driver
+*/
+
+/*!
+ \file ifxmips_des.c
+ \ingroup IFX_DEU
+ \brief DES encryption DEU driver file
+*/
+
+/*!
+ \defgroup IFX_DES_FUNCTIONS IFX_DES_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief IFX DES Encryption functions
+*/
+
+/* Project Header Files */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <crypto/algapi.h>
+#include "ifxmips_deu.h"
+
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+extern int ifx_danube_pre_1_4;
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Unkown platform"
+#endif
+
+/* DMA specific header and variables */
+
+#if 0
+ #define CRTCL_SECT_INIT
+ #define CRTCL_SECT_START
+ #define CRTCL_SECT_END
+#else
+spinlock_t des_lock;
+#define CRTCL_SECT_INIT spin_lock_init(&des_lock)
+#define CRTCL_SECT_START spin_lock_irqsave(&des_lock, flag)
+#define CRTCL_SECT_END spin_unlock_irqrestore(&des_lock, flag)
+#endif
+
+/* Preprocessor declerations */
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+#define DES_3DES_START IFX_DES_CON
+#define DES_KEY_SIZE 8
+#define DES_EXPKEY_WORDS 32
+#define DES_BLOCK_SIZE 8
+#define DES3_EDE_KEY_SIZE (3 * DES_KEY_SIZE)
+#define DES3_EDE_EXPKEY_WORDS (3 * DES_EXPKEY_WORDS)
+#define DES3_EDE_BLOCK_SIZE DES_BLOCK_SIZE
+
+/* Function Declaration to prevent warning messages */
+void des_chip_init (void);
+u32 endian_swap(u32 input);
+u32 input_swap(u32 input);
+int aes_memory_allocate(int value);
+int des_memory_allocate(int value);
+void memory_release(u32 *buffer);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+
+void ifx_deu_des (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+ u8 *iv_arg, u32 nbytes, int encdec, int mode);
+
+struct des_ctx {
+ int controlr_M;
+ int key_length;
+ u8 iv[DES_BLOCK_SIZE];
+ u32 expkey[DES3_EDE_EXPKEY_WORDS];
+};
+
+extern int disable_multiblock;
+extern int disable_deudma;
+
+
+/*! \fn int des_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief sets DES key
+ * \param tfm linux crypto algo transform
+ * \param key input key
+ * \param keylen key length
+*/
+int des_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct des_ctx *dctx = crypto_tfm_ctx(tfm);
+
+ //printk("setkey in %s\n", __FILE__);
+
+ dctx->controlr_M = 0; // des
+ dctx->key_length = keylen;
+
+ memcpy ((u8 *) (dctx->expkey), key, keylen);
+
+ return 0;
+}
+
+
+/*! \fn void ifx_deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief main interface to DES hardware
+ * \param ctx_arg crypto algo context
+ * \param out_arg output bytestream
+ * \param in_arg input bytestream
+ * \param iv_arg initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param mode operation mode such as ebc, cbc
+*/
+
+void ifx_deu_des (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
+ u8 *iv_arg, u32 nbytes, int encdec, int mode)
+{
+ volatile struct des_t *des = (struct des_t *) DES_3DES_START;
+ struct des_ctx *dctx = ctx_arg;
+ u32 *key = dctx->expkey;
+ unsigned long flag;
+
+ int i = 0;
+ int nblocks = 0;
+
+ CRTCL_SECT_START;
+
+ des->controlr.M = dctx->controlr_M;
+ if (dctx->controlr_M == 0) // des
+ {
+ des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
+ des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
+
+ }
+ else {
+ /* Hardware Section */
+ switch (dctx->key_length) {
+ case 24:
+ des->K3HR = DEU_ENDIAN_SWAP(*((u32 *) key + 4));
+ des->K3LR = DEU_ENDIAN_SWAP(*((u32 *) key + 5));
+ /* no break; */
+
+ case 16:
+ des->K2HR = DEU_ENDIAN_SWAP(*((u32 *) key + 2));
+ des->K2LR = DEU_ENDIAN_SWAP(*((u32 *) key + 3));
+
+ /* no break; */
+ case 8:
+ des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
+ des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
+ break;
+
+ default:
+ CRTCL_SECT_END;
+ return;
+ }
+ }
+
+ des->controlr.E_D = !encdec; //encryption
+ des->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR hexdump(prin,sizeof(*des));
+
+ if (mode > 0) {
+ des->IVHR = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
+ des->IVLR = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
+ };
+
+ nblocks = nbytes / 4;
+
+ for (i = 0; i < nblocks; i += 2) {
+ /* wait for busy bit to clear */
+
+ /*--- Workaround ----------------------------------------------------
+ do a dummy read to the busy flag because it is not raised early
+ enough in CFB/OFB 3DES modes */
+#ifdef CRYPTO_DEBUG
+ printk ("ihr: %x\n", (*((u32 *) in_arg + i)));
+ printk ("ilr: %x\n", (*((u32 *) in_arg + 1 + i)));
+#endif
+ des->IHR = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + i));
+ des->ILR = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + 1 + i)); /* start crypto */
+
+ while (des->controlr.BUS) {
+ // this will not take long
+ }
+
+ *((u32 *) out_arg + 0 + i) = des->OHR;
+ *((u32 *) out_arg + 1 + i) = des->OLR;
+
+ }
+
+
+
+ if (mode > 0) {
+ *(u32 *) iv_arg = DEU_ENDIAN_SWAP(des->IVHR);
+ *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(des->IVLR);
+ };
+
+ CRTCL_SECT_END;
+}
+
+//definitions from linux/include/crypto.h:
+//#define CRYPTO_TFM_MODE_ECB 0x00000001
+//#define CRYPTO_TFM_MODE_CBC 0x00000002
+//#define CRYPTO_TFM_MODE_CFB 0x00000004
+//#define CRYPTO_TFM_MODE_CTR 0x00000008
+//#define CRYPTO_TFM_MODE_OFB 0x00000010 // not even defined
+//but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
+
+/*! \fn void ifx_deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief main interface to DES hardware
+ * \param ctx_arg crypto algo context
+ * \param out_arg output bytestream
+ * \param in_arg input bytestream
+ * \param iv_arg initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param mode operation mode such as ebc, cbc
+*/
+
+
+
+/*! \fn void ifx_deu_des_ecb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief sets DES hardware to ECB mode
+ * \param ctx crypto algo context
+ * \param dst output bytestream
+ * \param src input bytestream
+ * \param iv initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param inplace not used
+*/
+
+void ifx_deu_des_ecb (void *ctx, uint8_t *dst, const uint8_t *src,
+ uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+ ifx_deu_des (ctx, dst, src, NULL, nbytes, encdec, 0);
+}
+
+/*! \fn void ifx_deu_des_cbc (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief sets DES hardware to CBC mode
+ * \param ctx crypto algo context
+ * \param dst output bytestream
+ * \param src input bytestream
+ * \param iv initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param inplace not used
+*/
+void ifx_deu_des_cbc (void *ctx, uint8_t *dst, const uint8_t *src,
+ uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+ ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 1);
+}
+
+/*! \fn void ifx_deu_des_ofb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief sets DES hardware to OFB mode
+ * \param ctx crypto algo context
+ * \param dst output bytestream
+ * \param src input bytestream
+ * \param iv initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param inplace not used
+*/
+void ifx_deu_des_ofb (void *ctx, uint8_t *dst, const uint8_t *src,
+ uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+ ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 2);
+}
+
+/*! \fn void ifx_deu_des_cfb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ \ingroup IFX_DES_FUNCTIONS
+ \brief sets DES hardware to CFB mode
+ \param ctx crypto algo context
+ \param dst output bytestream
+ \param src input bytestream
+ \param iv initialization vector
+ \param nbytes length of bytestream
+ \param encdec 1 for encrypt; 0 for decrypt
+ \param inplace not used
+*/
+void ifx_deu_des_cfb (void *ctx, uint8_t *dst, const uint8_t *src,
+ uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+ ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 3);
+}
+
+/*! \fn void ifx_deu_des_ctr (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief sets DES hardware to CTR mode
+ * \param ctx crypto algo context
+ * \param dst output bytestream
+ * \param src input bytestream
+ * \param iv initialization vector
+ * \param nbytes length of bytestream
+ * \param encdec 1 for encrypt; 0 for decrypt
+ * \param inplace not used
+*/
+void ifx_deu_des_ctr (void *ctx, uint8_t *dst, const uint8_t *src,
+ uint8_t *iv, size_t nbytes, int encdec, int inplace)
+{
+ ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 4);
+}
+
+/*! \fn void des_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief encrypt DES_BLOCK_SIZE of data
+ * \param tfm linux crypto algo transform
+ * \param out output bytestream
+ * \param in input bytestream
+*/
+void des_encrypt (struct crypto_tfm *tfm, uint8_t * out, const uint8_t * in)
+{
+ struct des_ctx *ctx = crypto_tfm_ctx(tfm);
+ ifx_deu_des (ctx, out, in, NULL, DES_BLOCK_SIZE,
+ CRYPTO_DIR_ENCRYPT, 0);
+
+}
+
+/*! \fn void des_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief encrypt DES_BLOCK_SIZE of data
+ * \param tfm linux crypto algo transform
+ * \param out output bytestream
+ * \param in input bytestream
+*/
+void des_decrypt (struct crypto_tfm *tfm, uint8_t * out, const uint8_t * in)
+{
+ struct des_ctx *ctx = crypto_tfm_ctx(tfm);
+ ifx_deu_des (ctx, out, in, NULL, DES_BLOCK_SIZE,
+ CRYPTO_DIR_DECRYPT, 0);
+}
+
+/*
+ * \brief RFC2451:
+ *
+ * For DES-EDE3, there is no known need to reject weak or
+ * complementation keys. Any weakness is obviated by the use of
+ * multiple keys.
+ *
+ * However, if the first two or last two independent 64-bit keys are
+ * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
+ * same as DES. Implementers MUST reject keys that exhibit this
+ * property.
+ *
+ */
+
+/*! \fn int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief sets 3DES key
+ * \param tfm linux crypto algo transform
+ * \param key input key
+ * \param keylen key length
+*/
+int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct des_ctx *dctx = crypto_tfm_ctx(tfm);
+
+ //printk("setkey in %s\n", __FILE__);
+
+ dctx->controlr_M = keylen / 8 + 1; // 3DES EDE1 / EDE2 / EDE3 Mode
+ dctx->key_length = keylen;
+
+ memcpy ((u8 *) (dctx->expkey), key, keylen);
+
+ return 0;
+}
+
+/*
+ * \brief DES function mappings
+*/
+struct crypto_alg ifxdeu_des_alg = {
+ .cra_name = "des",
+ .cra_driver_name = "ifxdeu-des",
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_alignmask = 3,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_des_alg.cra_list),
+ .cra_u = { .cipher = {
+ .cia_min_keysize = DES_KEY_SIZE,
+ .cia_max_keysize = DES_KEY_SIZE,
+ .cia_setkey = des_setkey,
+ .cia_encrypt = des_encrypt,
+ .cia_decrypt = des_decrypt } }
+};
+
+/*
+ * \brief DES function mappings
+*/
+struct crypto_alg ifxdeu_des3_ede_alg = {
+ .cra_name = "des3_ede",
+ .cra_driver_name = "ifxdeu-des3_ede",
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_alignmask = 3,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_des3_ede_alg.cra_list),
+ .cra_u = { .cipher = {
+ .cia_min_keysize = DES_KEY_SIZE,
+ .cia_max_keysize = DES_KEY_SIZE,
+ .cia_setkey = des3_ede_setkey,
+ .cia_encrypt = des_encrypt,
+ .cia_decrypt = des_decrypt } }
+};
+
+/*! \fn int ecb_des_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief ECB DES encrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+*/
+int ecb_des_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ nbytes -= (nbytes % DES_BLOCK_SIZE);
+ ifx_deu_des_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
+ nbytes &= DES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*! \fn int ecb_des_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief ECB DES decrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+ * \return err
+*/
+int ecb_des_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ DPRINTF(1, "\n");
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ nbytes -= (nbytes % DES_BLOCK_SIZE);
+ ifx_deu_des_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
+ nbytes &= DES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*
+ * \brief DES function mappings
+*/
+struct crypto_alg ifxdeu_ecb_des_alg = {
+ .cra_name = "ecb(des)",
+ .cra_driver_name = "ifxdeu-ecb(des)",
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_ecb_des_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = DES_KEY_SIZE,
+ .max_keysize = DES_KEY_SIZE,
+ .setkey = des_setkey,
+ .encrypt = ecb_des_encrypt,
+ .decrypt = ecb_des_decrypt,
+ }
+ }
+};
+
+/*
+ * \brief DES function mappings
+*/
+struct crypto_alg ifxdeu_ecb_des3_ede_alg = {
+ .cra_name = "ecb(des3_ede)",
+ .cra_driver_name = "ifxdeu-ecb(des3_ede)",
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_ecb_des3_ede_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = DES3_EDE_KEY_SIZE,
+ .max_keysize = DES3_EDE_KEY_SIZE,
+ .setkey = des3_ede_setkey,
+ .encrypt = ecb_des_encrypt,
+ .decrypt = ecb_des_decrypt,
+ }
+ }
+};
+
+/*! \fn int cbc_des_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief CBC DES encrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+ * \return err
+*/
+int cbc_des_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ DPRINTF(1, "\n");
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ u8 *iv = walk.iv;
+ nbytes -= (nbytes % DES_BLOCK_SIZE);
+ ifx_deu_des_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
+ nbytes &= DES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*! \fn int cbc_des_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief CBC DES decrypt using linux crypto blkcipher
+ * \param desc blkcipher descriptor
+ * \param dst output scatterlist
+ * \param src input scatterlist
+ * \param nbytes data size in bytes
+ * \return err
+*/
+int cbc_des_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+ int err;
+
+ DPRINTF(1, "\n");
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ u8 *iv = walk.iv;
+ nbytes -= (nbytes % DES_BLOCK_SIZE);
+ ifx_deu_des_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
+ nbytes &= DES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+/*
+ * \brief DES function mappings
+*/
+struct crypto_alg ifxdeu_cbc_des_alg = {
+ .cra_name = "cbc(des)",
+ .cra_driver_name = "ifxdeu-cbc(des)",
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_cbc_des_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = DES_KEY_SIZE,
+ .max_keysize = DES_KEY_SIZE,
+ .ivsize = DES_BLOCK_SIZE,
+ .setkey = des_setkey,
+ .encrypt = cbc_des_encrypt,
+ .decrypt = cbc_des_decrypt,
+ }
+ }
+};
+
+/*
+ * \brief DES function mappings
+*/
+struct crypto_alg ifxdeu_cbc_des3_ede_alg = {
+ .cra_name = "cbc(des3_ede)",
+ .cra_driver_name = "ifxdeu-cbc(des3_ede)",
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ifxdeu_cbc_des3_ede_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = DES3_EDE_KEY_SIZE,
+ .max_keysize = DES3_EDE_KEY_SIZE,
+ .ivsize = DES_BLOCK_SIZE,
+ .setkey = des3_ede_setkey,
+ .encrypt = cbc_des_encrypt,
+ .decrypt = cbc_des_decrypt,
+ }
+ }
+};
+
+/*! \fn int __init ifxdeu_init_des (void)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief initialize des driver
+*/
+int __init ifxdeu_init_des (void)
+{
+ int ret = -ENOSYS;
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+ if (!disable_multiblock) {
+ ifxdeu_des_alg.cra_u.cipher.cia_max_nbytes = DES_BLOCK_SIZE; //(size_t)-1;
+ ifxdeu_des_alg.cra_u.cipher.cia_req_align = 16;
+ ifxdeu_des_alg.cra_u.cipher.cia_ecb = ifx_deu_des_ecb;
+ ifxdeu_des_alg.cra_u.cipher.cia_cbc = ifx_deu_des_cbc;
+ ifxdeu_des_alg.cra_u.cipher.cia_cfb = ifx_deu_des_cfb;
+ ifxdeu_des_alg.cra_u.cipher.cia_ofb = ifx_deu_des_ofb;
+ }
+#endif
+
+ ret = crypto_register_alg(&ifxdeu_des_alg);
+ if (ret < 0)
+ goto des_err;
+
+ ret = crypto_register_alg(&ifxdeu_ecb_des_alg);
+ if (ret < 0)
+ goto ecb_des_err;
+
+ ret = crypto_register_alg(&ifxdeu_cbc_des_alg);
+ if (ret < 0)
+ goto cbc_des_err;
+
+ ret = crypto_register_alg(&ifxdeu_des3_ede_alg);
+ if (ret < 0)
+ goto des3_ede_err;
+
+ ret = crypto_register_alg(&ifxdeu_ecb_des3_ede_alg);
+ if (ret < 0)
+ goto ecb_des3_ede_err;
+
+ ret = crypto_register_alg(&ifxdeu_cbc_des3_ede_alg);
+ if (ret < 0)
+ goto cbc_des3_ede_err;
+
+ des_chip_init();
+ CRTCL_SECT_INIT;
+
+
+
+ printk (KERN_NOTICE "IFX DEU DES initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
+ return ret;
+
+des_err:
+ crypto_unregister_alg(&ifxdeu_des_alg);
+ printk(KERN_ERR "IFX des initialization failed!\n");
+ return ret;
+ecb_des_err:
+ crypto_unregister_alg(&ifxdeu_ecb_des_alg);
+ printk (KERN_ERR "IFX ecb_des initialization failed!\n");
+ return ret;
+cbc_des_err:
+ crypto_unregister_alg(&ifxdeu_cbc_des_alg);
+ printk (KERN_ERR "IFX cbc_des initialization failed!\n");
+ return ret;
+des3_ede_err:
+ crypto_unregister_alg(&ifxdeu_des3_ede_alg);
+ printk(KERN_ERR "IFX des3_ede initialization failed!\n");
+ return ret;
+ecb_des3_ede_err:
+ crypto_unregister_alg(&ifxdeu_ecb_des3_ede_alg);
+ printk (KERN_ERR "IFX ecb_des3_ede initialization failed!\n");
+ return ret;
+cbc_des3_ede_err:
+ crypto_unregister_alg(&ifxdeu_cbc_des3_ede_alg);
+ printk (KERN_ERR "IFX cbc_des3_ede initialization failed!\n");
+ return ret;
+
+}
+
+/*! \fn void __exit ifxdeu_fini_des (void)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief unregister des driver
+*/
+void __exit ifxdeu_fini_des (void)
+{
+ crypto_unregister_alg (&ifxdeu_des_alg);
+ crypto_unregister_alg (&ifxdeu_ecb_des_alg);
+ crypto_unregister_alg (&ifxdeu_cbc_des_alg);
+ crypto_unregister_alg (&ifxdeu_des3_ede_alg);
+ crypto_unregister_alg (&ifxdeu_ecb_des3_ede_alg);
+ crypto_unregister_alg (&ifxdeu_cbc_des3_ede_alg);
+
+}
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu.c
new file mode 100644
index 0000000000..05f168160b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu.c
@@ -0,0 +1,210 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_deu.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for Danube
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx deu driver module
+*/
+
+/*!
+ \file ifxmips_deu.c
+ \ingroup IFX_DEU
+ \brief main deu driver file
+*/
+
+/*!
+ \defgroup IFX_DEU_FUNCTIONS IFX_DEU_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief IFX DEU functions
+*/
+
+/* Project header */
+#include <linux/version.h>
+#if defined(CONFIG_MODVERSIONS)
+#define MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/proc_fs.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h> /* Stuff about file systems that we need */
+#include <asm/byteorder.h>
+#include "ifxmips_deu.h"
+
+#include <lantiq_soc.h>
+
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Platform unknown!"
+#endif /* CONFIG_xxxx */
+
+int disable_deudma = 1;
+
+void chip_version(void);
+
+/*! \fn static int __init deu_init (void)
+ * \ingroup IFX_DEU_FUNCTIONS
+ * \brief link all modules that have been selected in kernel config for ifx hw crypto support
+ * \return ret
+*/
+
+static int ltq_deu_probe(struct platform_device *pdev)
+{
+ int ret = -ENOSYS;
+
+
+ START_DEU_POWER;
+
+#define IFX_DEU_DRV_VERSION "2.0.0"
+ printk(KERN_INFO "Infineon Technologies DEU driver version %s \n", IFX_DEU_DRV_VERSION);
+
+ FIND_DEU_CHIP_VERSION;
+
+#if defined(CONFIG_CRYPTO_DEV_DES)
+ if ((ret = ifxdeu_init_des ())) {
+ printk (KERN_ERR "IFX DES initialization failed!\n");
+ }
+#endif
+#if defined(CONFIG_CRYPTO_DEV_AES)
+ if ((ret = ifxdeu_init_aes ())) {
+ printk (KERN_ERR "IFX AES initialization failed!\n");
+ }
+
+#endif
+#if defined(CONFIG_CRYPTO_DEV_ARC4)
+ if ((ret = ifxdeu_init_arc4 ())) {
+ printk (KERN_ERR "IFX ARC4 initialization failed!\n");
+ }
+
+#endif
+#if defined(CONFIG_CRYPTO_DEV_SHA1)
+ if ((ret = ifxdeu_init_sha1 ())) {
+ printk (KERN_ERR "IFX SHA1 initialization failed!\n");
+ }
+#endif
+#if defined(CONFIG_CRYPTO_DEV_MD5)
+ if ((ret = ifxdeu_init_md5 ())) {
+ printk (KERN_ERR "IFX MD5 initialization failed!\n");
+ }
+
+#endif
+#if defined(CONFIG_CRYPTO_DEV_SHA1_HMAC)
+ if ((ret = ifxdeu_init_sha1_hmac ())) {
+ printk (KERN_ERR "IFX SHA1_HMAC initialization failed!\n");
+ }
+#endif
+#if defined(CONFIG_CRYPTO_DEV_MD5_HMAC)
+ if ((ret = ifxdeu_init_md5_hmac ())) {
+ printk (KERN_ERR "IFX MD5_HMAC initialization failed!\n");
+ }
+#endif
+
+
+
+ return ret;
+
+}
+
+/*! \fn static void __exit deu_fini (void)
+ * \ingroup IFX_DEU_FUNCTIONS
+ * \brief remove the loaded crypto algorithms
+*/
+static int ltq_deu_remove(struct platform_device *pdev)
+{
+//#ifdef CONFIG_CRYPTO_DEV_PWR_SAVE_MODE
+ #if defined(CONFIG_CRYPTO_DEV_DES)
+ ifxdeu_fini_des ();
+ #endif
+ #if defined(CONFIG_CRYPTO_DEV_AES)
+ ifxdeu_fini_aes ();
+ #endif
+ #if defined(CONFIG_CRYPTO_DEV_ARC4)
+ ifxdeu_fini_arc4 ();
+ #endif
+ #if defined(CONFIG_CRYPTO_DEV_SHA1)
+ ifxdeu_fini_sha1 ();
+ #endif
+ #if defined(CONFIG_CRYPTO_DEV_MD5)
+ ifxdeu_fini_md5 ();
+ #endif
+ #if defined(CONFIG_CRYPTO_DEV_SHA1_HMAC)
+ ifxdeu_fini_sha1_hmac ();
+ #endif
+ #if defined(CONFIG_CRYPTO_DEV_MD5_HMAC)
+ ifxdeu_fini_md5_hmac ();
+ #endif
+ printk("DEU has exited successfully\n");
+
+ return 0;
+}
+
+
+int disable_multiblock = 0;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+module_param(disable_multiblock,int,0);
+
+#else
+//MODULE_PARM (disable_multiblock, "i");
+MODULE_PARM_DESC (disable_multiblock,
+ "Disable encryption of whole multiblock buffers.");
+#endif
+
+static const struct of_device_id ltq_deu_match[] = {
+#ifdef CONFIG_DANUBE
+ { .compatible = "lantiq,deu-danube"},
+#elif defined CONFIG_AR9
+ { .compatible = "lantiq,deu-arx100"},
+#elif defined CONFIG_VR9
+ { .compatible = "lantiq,deu-xrx200"},
+#endif
+ {},
+};
+MODULE_DEVICE_TABLE(of, ltq_deu_match);
+
+
+static struct platform_driver ltq_deu_driver = {
+ .probe = ltq_deu_probe,
+ .remove = ltq_deu_remove,
+ .driver = {
+ .name = "deu",
+ .owner = THIS_MODULE,
+ .of_match_table = ltq_deu_match,
+ },
+};
+
+module_platform_driver(ltq_deu_driver);
+
+MODULE_DESCRIPTION ("Infineon DEU crypto engine support.");
+MODULE_LICENSE ("GPL");
+MODULE_AUTHOR ("Mohammad Firdaus");
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu.h b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu.h
new file mode 100644
index 0000000000..c842d64c1b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu.h
@@ -0,0 +1,232 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_deu.h
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx deu driver module
+*/
+
+/*!
+ \file ifxmips_deu.h
+ \brief main deu driver header file
+*/
+
+/*!
+ \defgroup IFX_DEU_DEFINITIONS IFX_DEU_DEFINITIONS
+ \ingroup IFX_DEU
+ \brief ifx deu definitions
+*/
+
+
+#ifndef IFXMIPS_DEU_H
+#define IFXMIPS_DEU_H
+
+#include <crypto/algapi.h>
+#include <linux/interrupt.h>
+
+#define IFXDEU_ALIGNMENT 16
+
+#define IFX_DEU_BASE_ADDR (KSEG1 | 0x1E103100)
+#define IFX_DEU_CLK ((volatile u32 *)(IFX_DEU_BASE_ADDR + 0x0000))
+#define IFX_DES_CON ((volatile u32 *)(IFX_DEU_BASE_ADDR + 0x0010))
+#define IFX_AES_CON ((volatile u32 *)(IFX_DEU_BASE_ADDR + 0x0050))
+#define IFX_HASH_CON ((volatile u32 *)(IFX_DEU_BASE_ADDR + 0x00B0))
+#define IFX_ARC4_CON ((volatile u32 *)(IFX_DEU_BASE_ADDR + 0x0100))
+
+#define PFX "ifxdeu: "
+#define CLC_START IFX_DEU_CLK
+#define IFXDEU_CRA_PRIORITY 300
+#define IFXDEU_COMPOSITE_PRIORITY 400
+//#define KSEG1 0xA0000000
+#define IFX_PMU_ENABLE 1
+#define IFX_PMU_DISABLE 0
+
+#define CRYPTO_DIR_ENCRYPT 1
+#define CRYPTO_DIR_DECRYPT 0
+
+#define AES_IDLE 0
+#define AES_BUSY 1
+#define AES_STARTED 2
+#define AES_COMPLETED 3
+#define DES_IDLE 0
+#define DES_BUSY 1
+#define DES_STARTED 2
+#define DES_COMPLETED 3
+
+#define PROCESS_SCATTER 1
+#define PROCESS_NEW_PACKET 2
+
+#define PMU_DEU BIT(20)
+#define START_DEU_POWER \
+ do { \
+ volatile struct clc_controlr_t *clc = (struct clc_controlr_t *) CLC_START; \
+ ltq_pmu_enable(PMU_DEU); \
+ clc->FSOE = 0; \
+ clc->SBWE = 0; \
+ clc->SPEN = 0; \
+ clc->SBWE = 0; \
+ clc->DISS = 0; \
+ clc->DISR = 0; \
+ } while(0)
+
+#define STOP_DEU_POWER \
+ do { \
+ volatile struct clc_controlr_t *clc = (struct clc_controlr_t *) CLC_START; \
+ ltq_pmu_disable(PMU_DEU); \
+ clc->FSOE = 1; \
+ clc->SBWE = 1; \
+ clc->SPEN = 1; \
+ clc->SBWE = 1; \
+ clc->DISS = 1; \
+ clc->DISR = 1; \
+ } while (0)
+
+/*
+ * Not used anymore in UEIP (use IFX_DES_CON, IFX_AES_CON, etc instead)
+ * #define DEU_BASE (KSEG1+0x1E103100)
+ * #define DES_CON (DEU_BASE+0x10)
+ * #define AES_CON (DEU_BASE+0x50)
+ * #define HASH_CON (DEU_BASE+0xB0)
+ * #define DMA_CON (DEU_BASE+0xEC)
+ * #define INT_CON (DEU_BASE+0xF4)
+ * #define ARC4_CON (DEU_BASE+0x100)
+ */
+
+
+int __init ifxdeu_init_des (void);
+int __init ifxdeu_init_aes (void);
+int __init ifxdeu_init_arc4 (void);
+int __init ifxdeu_init_sha1 (void);
+int __init ifxdeu_init_md5 (void);
+int __init ifxdeu_init_sha1_hmac (void);
+int __init ifxdeu_init_md5_hmac (void);
+int __init lqdeu_async_aes_init(void);
+int __init lqdeu_async_des_init(void);
+
+void __exit ifxdeu_fini_des (void);
+void __exit ifxdeu_fini_aes (void);
+void __exit ifxdeu_fini_arc4 (void);
+void __exit ifxdeu_fini_sha1 (void);
+void __exit ifxdeu_fini_md5 (void);
+void __exit ifxdeu_fini_sha1_hmac (void);
+void __exit ifxdeu_fini_md5_hmac (void);
+void __exit ifxdeu_fini_dma(void);
+void __exit lqdeu_fini_async_aes(void);
+void __exit lqdeu_fini_async_des(void);
+void __exit deu_fini (void);
+int deu_dma_init (void);
+
+
+
+#define DEU_WAKELIST_INIT(queue) \
+ init_waitqueue_head(&queue)
+
+#define DEU_WAIT_EVENT_TIMEOUT(queue, event, flags, timeout) \
+ do { \
+ wait_event_interruptible_timeout((queue), \
+ test_bit((event), &(flags)), (timeout)); \
+ clear_bit((event), &(flags)); \
+ }while (0)
+
+
+#define DEU_WAKEUP_EVENT(queue, event, flags) \
+ do { \
+ set_bit((event), &(flags)); \
+ wake_up_interruptible(&(queue)); \
+ }while (0)
+
+#define DEU_WAIT_EVENT(queue, event, flags) \
+ do { \
+ wait_event_interruptible(queue, \
+ test_bit((event), &(flags))); \
+ clear_bit((event), &(flags)); \
+ }while (0)
+
+typedef struct deu_drv_priv {
+ wait_queue_head_t deu_thread_wait;
+#define DEU_EVENT 1
+#define DES_ASYNC_EVENT 2
+#define AES_ASYNC_EVENT 3
+ volatile long des_event_flags;
+ volatile long aes_event_flags;
+ volatile long deu_event_flags;
+ int event_src;
+ u32 *deu_rx_buf;
+ u32 *outcopy;
+ u32 deu_rx_len;
+
+ struct aes_priv *aes_dataptr;
+ struct des_priv *des_dataptr;
+}deu_drv_priv_t;
+
+
+/**
+ * struct aes_priv_t - ASYNC AES
+ * @lock: spinlock lock
+ * @lock_flag: flag for spinlock activities
+ * @list: crypto queue API list
+ * @hw_status: DEU hw status flag
+ * @aes_wait_flag: flag for sleep queue
+ * @aes_wait_queue: queue attributes for aes
+ * @bytes_processed: number of bytes to process by DEU
+ * @aes_pid: pid number for AES thread
+ * @aes_sync: atomic wait sync for AES
+ *
+*/
+
+typedef struct {
+ spinlock_t lock;
+ struct crypto_queue list;
+ unsigned int hw_status;
+ volatile long aes_wait_flag;
+ wait_queue_head_t aes_wait_queue;
+
+ pid_t aes_pid;
+
+ struct tasklet_struct aes_task;
+
+} aes_priv_t;
+
+/**
+ * struct des_priv_t - ASYNC DES
+ * @lock: spinlock lock
+ * @list: crypto queue API list
+ * @hw_status: DEU hw status flag
+ * @des_wait_flag: flag for sleep queue
+ * @des_wait_queue: queue attributes for des
+ * @des_pid: pid number for DES thread
+ * @des_sync: atomic wait sync for DES
+ *
+*/
+
+typedef struct {
+ spinlock_t lock;
+ struct crypto_queue list;
+ unsigned int hw_status;
+ volatile long des_wait_flag;
+ wait_queue_head_t des_wait_queue;
+
+ pid_t des_pid;
+
+ struct tasklet_struct des_task;
+
+} des_priv_t;
+
+#endif /* IFXMIPS_DEU_H */
+
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_ar9.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_ar9.c
new file mode 100644
index 0000000000..9dc3e30427
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_ar9.c
@@ -0,0 +1,135 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_deu_ar9.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for AR9
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx deu driver module
+*/
+
+/*!
+ \file ifxmips_deu_ar9.c
+ \brief ifx deu board specific driver file for ar9
+*/
+
+/*!
+ \defgroup BOARD_SPECIFIC_FUNCTIONS IFX_BOARD_SPECIFIC_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief board specific functions
+*/
+
+/* Project header files */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/io.h> //dma_cache_inv
+
+#include "ifxmips_deu_dma.h"
+#include "ifxmips_deu_ar9.h"
+
+/* Function decleration */
+void aes_chip_init (void);
+void des_chip_init (void);
+int deu_dma_init (void);
+u32 endian_swap(u32 input);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void deu_dma_priv_init(void);
+void __exit ifxdeu_fini_dma(void);
+
+#define DES_3DES_START IFX_DES_CON
+#define AES_START IFX_AES_CON
+#define CLC_START IFX_DEU_CLK
+
+/* Variables */
+
+u8 *g_dma_page_ptr = NULL;
+u8 *g_dma_block = NULL;
+u8 *g_dma_block2 = NULL;
+
+deu_drv_priv_t deu_dma_priv;
+
+
+/*! \fn u32 endian_swap(u32 input)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief Swap data given to the function
+ * \param input Data input to be swapped
+ * \return either the swapped data or the input data depending on whether it is in DMA mode or FPI mode
+*/
+u32 endian_swap(u32 input)
+{
+ return input;
+}
+
+/*! \fn u32 input_swap(u32 input)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief Not used
+ * \return input
+*/
+
+u32 input_swap(u32 input)
+{
+ return input;
+}
+
+/*! \fn void aes_chip_init (void)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief initialize AES hardware
+*/
+
+void aes_chip_init (void)
+{
+ volatile struct aes_t *aes = (struct aes_t *) AES_START;
+
+ aes->controlr.SM = 1;
+ aes->controlr.ARS = 1;
+
+}
+
+/*! \fn void des_chip_init (void)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief initialize DES hardware
+*/
+
+void des_chip_init (void)
+{
+ volatile struct des_t *des = (struct des_t *) DES_3DES_START;
+
+ // start crypto engine with write to ILR
+ des->controlr.SM = 1;
+ asm("sync");
+ des->controlr.ARS = 1;
+
+}
+
+/*! \fn void chip_version(void)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief not used!
+*/
+
+void chip_version(void)
+{
+ return;
+}
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_ar9.h b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_ar9.h
new file mode 100644
index 0000000000..1d84da3a5a
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_ar9.h
@@ -0,0 +1,299 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_deu_ar9.h
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for AR9
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief deu driver module
+*/
+
+/*!
+ \defgroup IFX_DEU_DEFINITIONS IFX_DEU_DEFINITIONS
+ \ingroup IFX_DEU
+ \brief ifx deu definitions
+*/
+
+/*!
+ \file ifxmips_deu_ar9.h
+ \brief deu driver header file
+*/
+
+
+#ifndef IFXMIPS_DEU_AR9_H
+#define IFXMIPS_DEU_AR9_H
+
+/* Project Header Files */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <crypto/algapi.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include "ifxmips_deu.h"
+
+
+/* SHA CONSTANTS */
+#define HASH_CON_VALUE 0x0700002C
+
+#define INPUT_ENDIAN_SWAP(input) input_swap(input)
+#define DEU_ENDIAN_SWAP(input) endian_swap(input)
+#define DELAY_PERIOD 10
+#define FIND_DEU_CHIP_VERSION chip_version()
+#define CLC_START IFX_DEU_CLK
+
+#define AES_INIT 0
+#define DES_INIT 1
+#define ARC4_INIT 2
+#define SHA1_INIT 3
+#define MD5_INIT 4
+#define SHA1_HMAC_INIT 5
+#define MD5_HMAC_INIT 6
+
+#define AES_START IFX_AES_CON
+#define DES_3DES_START IFX_DES_CON
+
+#define WAIT_AES_DMA_READY() \
+ do { \
+ int i; \
+ volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+ volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; \
+ for (i = 0; i < 10; i++) \
+ udelay(DELAY_PERIOD); \
+ while (dma->controlr.BSY) {}; \
+ while (aes->controlr.BUS) {}; \
+ } while (0)
+
+#define WAIT_DES_DMA_READY() \
+ do { \
+ int i; \
+ volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+ volatile struct des_t *des = (struct des_t *) DES_3DES_START; \
+ for (i = 0; i < 10; i++) \
+ udelay(DELAY_PERIOD); \
+ while (dma->controlr.BSY) {}; \
+ while (des->controlr.BUS) {}; \
+ } while (0)
+
+#define AES_DMA_MISC_CONFIG() \
+ do { \
+ volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; \
+ aes->controlr.KRE = 1; \
+ aes->controlr.GO = 1; \
+ } while(0)
+
+#define SHA_HASH_INIT \
+ do { \
+ volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START; \
+ hash->controlr.SM = 1; \
+ hash->controlr.ALGO = 0; \
+ hash->controlr.INIT = 1; \
+ } while(0)
+
+/* DEU Common Structures for AR9*/
+
+struct clc_controlr_t {
+ u32 Res:26;
+ u32 FSOE:1;
+ u32 SBWE:1;
+ u32 EDIS:1;
+ u32 SPEN:1;
+ u32 DISS:1;
+ u32 DISR:1;
+
+};
+
+struct des_t {
+ struct des_controlr { //10h
+ u32 KRE:1;
+ u32 reserved1:5;
+ u32 GO:1;
+ u32 STP:1;
+ u32 Res2:6;
+ u32 NDC:1;
+ u32 ENDI:1;
+ u32 Res3:2;
+ u32 F:3;
+ u32 O:3;
+ u32 BUS:1;
+ u32 DAU:1;
+ u32 ARS:1;
+ u32 SM:1;
+ u32 E_D:1;
+ u32 M:3;
+
+ } controlr;
+ u32 IHR; //14h
+ u32 ILR; //18h
+ u32 K1HR; //1c
+ u32 K1LR; //
+ u32 K2HR;
+ u32 K2LR;
+ u32 K3HR;
+ u32 K3LR; //30h
+ u32 IVHR; //34h
+ u32 IVLR; //38
+ u32 OHR; //3c
+ u32 OLR; //40
+};
+
+struct aes_t {
+ struct aes_controlr {
+
+ u32 KRE:1;
+ u32 reserved1:4;
+ u32 PNK:1;
+ u32 GO:1;
+ u32 STP:1;
+ u32 reserved2:6;
+ u32 NDC:1;
+ u32 ENDI:1;
+ u32 reserved3:2;
+ u32 F:3; //fbs
+ u32 O:3; //om
+ u32 BUS:1; //bsy
+ u32 DAU:1;
+ u32 ARS:1;
+ u32 SM:1;
+ u32 E_D:1;
+ u32 KV:1;
+ u32 K:2; //KL
+
+ } controlr;
+ u32 ID3R; //80h
+ u32 ID2R; //84h
+ u32 ID1R; //88h
+ u32 ID0R; //8Ch
+ u32 K7R; //90h
+ u32 K6R; //94h
+ u32 K5R; //98h
+ u32 K4R; //9Ch
+ u32 K3R; //A0h
+ u32 K2R; //A4h
+ u32 K1R; //A8h
+ u32 K0R; //ACh
+ u32 IV3R; //B0h
+ u32 IV2R; //B4h
+ u32 IV1R; //B8h
+ u32 IV0R; //BCh
+ u32 OD3R; //D4h
+ u32 OD2R; //D8h
+ u32 OD1R; //DCh
+ u32 OD0R; //E0h
+};
+
+struct arc4_t {
+ struct arc4_controlr {
+
+ u32 KRE:1;
+ u32 KLEN:4;
+ u32 KSAE:1;
+ u32 GO:1;
+ u32 STP:1;
+ u32 reserved1:6;
+ u32 NDC:1;
+ u32 ENDI:1;
+ u32 reserved2:8;
+ u32 BUS:1; //bsy
+ u32 reserved3:1;
+ u32 ARS:1;
+ u32 SM:1;
+ u32 reserved4:4;
+
+ } controlr;
+ u32 K3R; //104h
+ u32 K2R; //108h
+ u32 K1R; //10Ch
+ u32 K0R; //110h
+
+ u32 IDLEN; //114h
+
+ u32 ID3R; //118h
+ u32 ID2R; //11Ch
+ u32 ID1R; //120h
+ u32 ID0R; //124h
+
+ u32 OD3R; //128h
+ u32 OD2R; //12Ch
+ u32 OD1R; //130h
+ u32 OD0R; //134h
+};
+
+struct deu_hash_t {
+ struct hash_controlr {
+ u32 reserved1:5;
+ u32 KHS:1;
+ u32 GO:1;
+ u32 INIT:1;
+ u32 reserved2:6;
+ u32 NDC:1;
+ u32 ENDI:1;
+ u32 reserved3:7;
+ u32 DGRY:1;
+ u32 BSY:1;
+ u32 reserved4:1;
+ u32 IRCL:1;
+ u32 SM:1;
+ u32 KYUE:1;
+ u32 HMEN:1;
+ u32 SSEN:1;
+ u32 ALGO:1;
+
+ } controlr;
+ u32 MR; //B4h
+ u32 D1R; //B8h
+ u32 D2R; //BCh
+ u32 D3R; //C0h
+ u32 D4R; //C4h
+ u32 D5R; //C8h
+
+ u32 dummy; //CCh
+
+ u32 KIDX; //D0h
+ u32 KEY; //D4h
+ u32 DBN; //D8h
+};
+
+
+struct deu_dma_t {
+ struct dma_controlr {
+ u32 reserved1:22;
+ u32 BS:2;
+ u32 BSY:1;
+ u32 reserved2:1;
+ u32 ALGO:2;
+ u32 RXCLS:2;
+ u32 reserved3:1;
+ u32 EN:1;
+
+ } controlr;
+};
+
+#endif /* IFXMIPS_DEU_AR9_H */
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_danube.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_danube.c
new file mode 100644
index 0000000000..492391d414
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_danube.c
@@ -0,0 +1,168 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_deu_danube.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for Danube
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief deu driver module
+*/
+
+/*!
+ \file ifxmips_deu_danube.c
+ \ingroup IFX_DEU
+ \brief board specific deu driver file for danube
+*/
+
+/*!
+ \defgroup BOARD_SPECIFIC_FUNCTIONS IFX_BOARD_SPECIFIC_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief board specific deu functions
+*/
+
+/* Project header files */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/io.h> //dma_cache_inv
+
+#include "ifxmips_deu_dma.h"
+#include "ifxmips_deu_danube.h"
+
+
+/* Function Declerations */
+int aes_memory_allocate(int value);
+int des_memory_allocate(int value);
+void memory_release(u32 *addr);
+int aes_chip_init (void);
+void des_chip_init (void);
+int deu_dma_init (void);
+u32 endian_swap(u32 input);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void chip_version(void);
+void deu_dma_priv_init(void);
+void __exit ifxdeu_fini_dma(void);
+
+#define DES_3DES_START IFX_DES_CON
+#define AES_START IFX_AES_CON
+#define CLC_START IFX_DEU_CLK
+
+/* Variables definition */
+int ifx_danube_pre_1_4;
+u8 *g_dma_page_ptr = NULL;
+u8 *g_dma_block = NULL;
+u8 *g_dma_block2 = NULL;
+
+deu_drv_priv_t deu_dma_priv;
+
+
+/*! \fn u32 endian_swap(u32 input)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief function is not used
+ * \param input Data input to be swapped
+ * \return input
+*/
+
+u32 endian_swap(u32 input)
+{
+ return input;
+}
+
+/*! \fn u32 input_swap(u32 input)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief Swap the input data if the current chip is Danube version
+ * 1.4 and do nothing to the data if the current chip is
+ * Danube version 1.3
+ * \param input data that needs to be swapped
+ * \return input or swapped input
+*/
+
+u32 input_swap(u32 input)
+{
+ if (!ifx_danube_pre_1_4) {
+ u8 *ptr = (u8 *)&input;
+ return ((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
+ }
+ else
+ return input;
+}
+
+
+
+/*! \fn void aes_chip_init (void)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief initialize AES hardware
+*/
+
+int aes_chip_init (void)
+{
+ volatile struct aes_t *aes = (struct aes_t *) AES_START;
+
+ //start crypto engine with write to ILR
+ aes->controlr.SM = 1;
+ aes->controlr.ARS = 1;
+ return 0;
+}
+
+/*! \fn void des_chip_init (void)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief initialize DES hardware
+*/
+
+void des_chip_init (void)
+{
+ volatile struct des_t *des = (struct des_t *) DES_3DES_START;
+
+ // start crypto engine with write to ILR
+ des->controlr.SM = 1;
+ des->controlr.ARS = 1;
+}
+
+/*! \fn void chip_version (void)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief To find the version of the chip by looking at the chip ID
+ * \param ifx_danube_pre_1_4 (sets to 1 if Chip is Danube less than v1.4)
+*/
+#define IFX_MPS (KSEG1 | 0x1F107000)
+#define IFX_MPS_CHIPID ((volatile u32*)(IFX_MPS + 0x0344))
+
+void chip_version(void)
+{
+
+ /* DANUBE PRE 1.4 SOFTWARE FIX */
+ int chip_id = 0;
+ chip_id = *IFX_MPS_CHIPID;
+ chip_id >>= 28;
+
+ if (chip_id >= 4) {
+ ifx_danube_pre_1_4 = 0;
+ printk("Danube Chip ver. 1.4 detected. \n");
+ }
+ else {
+ ifx_danube_pre_1_4 = 1;
+ printk("Danube Chip ver. 1.3 or below detected. \n");
+ }
+
+ return;
+}
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_danube.h b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_danube.h
new file mode 100644
index 0000000000..62ad96d987
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_danube.h
@@ -0,0 +1,250 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_deu_danube.h
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for Danube
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief deu driver module
+*/
+
+/*!
+ \file ifxmips_deu_danube.h
+ \brief board specific driver header file for danube
+*/
+
+/*!
+ \defgroup BOARD_SPECIFIC_FUNCTIONS IFX_BOARD_SPECIFIC_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief board specific deu header files
+*/
+
+#ifndef IFXMIPS_DEU_DANUBE_H
+#define IFXMIPS_DEU_DANUBE_H
+
+/* Project Header Files */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <crypto/algapi.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include "ifxmips_deu.h"
+
+
+
+#define INPUT_ENDIAN_SWAP(input) input_swap(input)
+#define DEU_ENDIAN_SWAP(input) endian_swap(input)
+#define FIND_DEU_CHIP_VERSION chip_version()
+#define AES_DMA_MISC_CONFIG()
+#define CLC_START IFX_DEU_CLK
+
+#define AES_START IFX_AES_CON
+#define DES_3DES_START IFX_DES_CON
+
+#define AES_INIT 0
+#define DES_INIT 1
+#define SHA1_INIT 2
+#define MD5_INIT 3
+
+#define WAIT_AES_DMA_READY() \
+ do { \
+ int i; \
+ volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+ volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; \
+ for (i = 0; i < 10; i++) \
+ udelay(DELAY_PERIOD); \
+ while (dma->controlr.BSY) {}; \
+ while (aes->controlr.BUS) {}; \
+ } while (0)
+
+#define WAIT_DES_DMA_READY() \
+ do { \
+ int i; \
+ volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+ volatile struct des_t *des = (struct des_t *) DES_3DES_START; \
+ for (i = 0; i < 10; i++) \
+ udelay(DELAY_PERIOD); \
+ while (dma->controlr.BSY) {}; \
+ while (des->controlr.BUS) {}; \
+ } while (0)
+
+#define SHA_HASH_INIT \
+ do { \
+ volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START; \
+ hash->controlr.SM = 1; \
+ hash->controlr.ALGO = 0; \
+ hash->controlr.INIT = 1; \
+ } while(0)
+
+/* DEU STRUCTURES */
+
+struct clc_controlr_t {
+ u32 Res:26;
+ u32 FSOE:1;
+ u32 SBWE:1;
+ u32 EDIS:1;
+ u32 SPEN:1;
+ u32 DISS:1;
+ u32 DISR:1;
+
+};
+
+struct des_t {
+ struct des_controlr { //10h
+ u32 KRE:1;
+ u32 reserved1:5;
+ u32 GO:1;
+ u32 STP:1;
+ u32 Res2:6;
+ u32 NDC:1;
+ u32 ENDI:1;
+ u32 Res3:2;
+ u32 F:3;
+ u32 O:3;
+ u32 BUS:1;
+ u32 DAU:1;
+ u32 ARS:1;
+ u32 SM:1;
+ u32 E_D:1;
+ u32 M:3;
+
+ } controlr;
+ u32 IHR; //14h
+ u32 ILR; //18h
+ u32 K1HR; //1c
+ u32 K1LR; //
+ u32 K2HR;
+ u32 K2LR;
+ u32 K3HR;
+ u32 K3LR; //30h
+ u32 IVHR; //34h
+ u32 IVLR; //38
+ u32 OHR; //3c
+ u32 OLR; //40
+};
+
+struct aes_t {
+ struct aes_controlr {
+
+ u32 KRE:1;
+ u32 reserved1:4;
+ u32 PNK:1;
+ u32 GO:1;
+ u32 STP:1;
+
+ u32 reserved2:6;
+ u32 NDC:1;
+ u32 ENDI:1;
+ u32 reserved3:2;
+
+ u32 F:3; //fbs
+ u32 O:3; //om
+ u32 BUS:1; //bsy
+ u32 DAU:1;
+ u32 ARS:1;
+ u32 SM:1;
+ u32 E_D:1;
+ u32 KV:1;
+ u32 K:2; //KL
+
+ } controlr;
+ u32 ID3R; //80h
+ u32 ID2R; //84h
+ u32 ID1R; //88h
+ u32 ID0R; //8Ch
+ u32 K7R; //90h
+ u32 K6R; //94h
+ u32 K5R; //98h
+ u32 K4R; //9Ch
+ u32 K3R; //A0h
+ u32 K2R; //A4h
+ u32 K1R; //A8h
+ u32 K0R; //ACh
+ u32 IV3R; //B0h
+ u32 IV2R; //B4h
+ u32 IV1R; //B8h
+ u32 IV0R; //BCh
+ u32 OD3R; //D4h
+ u32 OD2R; //D8h
+ u32 OD1R; //DCh
+ u32 OD0R; //E0h
+};
+
+struct deu_hash_t {
+ struct hash_controlr {
+ u32 reserved1:5;
+ u32 KHS:1;
+ u32 GO:1;
+ u32 INIT:1;
+ u32 reserved2:6;
+ u32 NDC:1;
+ u32 ENDI:1;
+ u32 reserved3:7;
+ u32 DGRY:1;
+ u32 BSY:1;
+ u32 reserved4:1;
+ u32 IRCL:1;
+ u32 SM:1;
+ u32 KYUE:1;
+ u32 HMEN:1;
+ u32 SSEN:1;
+ u32 ALGO:1;
+
+ } controlr;
+ u32 MR; //B4h
+ u32 D1R; //B8h
+ u32 D2R; //BCh
+ u32 D3R; //C0h
+ u32 D4R; //C4h
+ u32 D5R; //C8h
+
+ u32 dummy; //CCh
+
+ u32 KIDX; //D0h
+ u32 KEY; //D4h
+ u32 DBN; //D8h
+};
+
+struct deu_dma_t {
+ struct dma_controlr {
+ u32 reserved1:22;
+ u32 BS:2;
+ u32 BSY:1;
+ u32 reserved2:1;
+ u32 ALGO:2;
+ u32 RXCLS:2;
+ u32 reserved3:1;
+ u32 EN:1;
+
+ } controlr;
+};
+
+#endif /* IFXMIPS_DEU_DANUBE_H */
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_dma.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_dma.c
new file mode 100644
index 0000000000..13dc921f7d
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_dma.c
@@ -0,0 +1,42 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_deu_dma.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for Danube
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08 Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup IFX_API
+ \brief ifx deu driver module
+*/
+
+/*!
+ \file ifxmips_deu_dma.c
+ \ingroup IFX_DEU
+ \brief DMA deu driver file
+*/
+
+/*!
+ \defgroup IFX_DMA_FUNCTIONS IFX_DMA_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief deu-dma driver functions
+*/
+
+/* Project header files */
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_dma.h b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_dma.h
new file mode 100644
index 0000000000..5198a4a11f
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_dma.h
@@ -0,0 +1,69 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_deu_dma.h
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+
+/*!
+ \addtogroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx deu driver module
+*/
+
+/*!
+ \file ifxmips_deu_dma.h
+ \ingroup IFX_DEU
+ \brief DMA deu driver header file
+*/
+
+#ifndef IFXMIPS_DEU_DMA_H
+#define IFXMIPS_DEU_DMA_H
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/crypto.h>
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+
+// must match the size of memory block allocated for g_dma_block and g_dma_block2
+#define DEU_MAX_PACKET_SIZE (PAGE_SIZE >> 1)
+
+typedef struct ifx_deu_device {
+ struct dma_device_info *dma_device;
+ u8 *dst;
+ u8 *src;
+ int len;
+ int dst_count;
+ int src_count;
+ int recv_count;
+ int packet_size;
+ int packet_num;
+ wait_queue_t wait;
+} _ifx_deu_device;
+
+extern _ifx_deu_device ifx_deu[1];
+
+extern int deu_dma_intr_handler (struct dma_device_info *, int);
+extern u8 *deu_dma_buffer_alloc (int, int *, void **);
+extern int deu_dma_buffer_free (u8 *, void *);
+extern void deu_dma_inactivate_poll(struct dma_device_info* dma_dev);
+extern void deu_dma_activate_poll (struct dma_device_info* dma_dev);
+extern struct dma_device_info* deu_dma_reserve(struct dma_device_info** dma_device);
+extern int deu_dma_release(struct dma_device_info** dma_device);
+
+#endif /* IFMIPS_DEU_DMA_H */
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_vr9.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_vr9.c
new file mode 100644
index 0000000000..aaa7bce237
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_vr9.c
@@ -0,0 +1,144 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_deu_vr9.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for VR9
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief deu driver module
+*/
+
+/*!
+ \file ifxmips_deu_vr9.c
+ \ingroup IFX_DEU
+ \brief board specific deu driver file for vr9
+*/
+
+/*!
+ \defgroup BOARD_SPECIFIC_FUNCTIONS IFX_BOARD_SPECIFIC_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief board specific deu driver functions
+*/
+
+/* Project header files */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/io.h> //dma_cache_inv
+
+#include "ifxmips_deu_dma.h"
+#include "ifxmips_deu_vr9.h"
+
+/* Function decleration */
+void aes_chip_init (void);
+void des_chip_init (void);
+int deu_dma_init (void);
+void deu_dma_priv_init(void);
+u32 endian_swap(u32 input);
+u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
+void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
+void __exit ifxdeu_fini_dma(void);
+
+#define DES_3DES_START IFX_DES_CON
+#define AES_START IFX_AES_CON
+
+/* Variables */
+
+u8 *g_dma_page_ptr = NULL;
+u8 *g_dma_block = NULL;
+u8 *g_dma_block2 = NULL;
+
+deu_drv_priv_t deu_dma_priv;
+
+
+/*! \fn u32 endian_swap(u32 input)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief Swap data given to the function
+ * \param input Data input to be swapped
+ * \return either the swapped data or the input data depending on whether it is in DMA mode or FPI mode
+*/
+
+
+u32 endian_swap(u32 input)
+{
+ return input;
+}
+
+/*! \fn u32 input_swap(u32 input)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief Not used
+ * \return input
+*/
+
+u32 input_swap(u32 input)
+{
+ return input;
+}
+
+/*! \fn void aes_chip_init (void)
+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
+ * \brief initialize AES hardware
+*/
+
+void aes_chip_init (void)
+{
+ volatile struct aes_t *aes = (struct aes_t *) AES_START;
+
+ // start crypto engine with write to ILR
+ aes->controlr.SM = 1;
+ aes->controlr.NDC = 0;
+ asm("sync");
+ aes->controlr.ENDI = 1;
+ asm("sync");
+ aes->controlr.ARS = 0;
+
+}
+
+/*! \fn void des_chip_init (void)
+ * \ingroup IFX_AES_FUNCTIONS
+ * \brief initialize DES hardware
+*/
+
+void des_chip_init (void)
+{
+ volatile struct des_t *des = (struct des_t *) DES_3DES_START;
+
+ // start crypto engine with write to ILR
+ des->controlr.SM = 1;
+ des->controlr.NDC = 1;
+ asm("sync");
+ des->controlr.ENDI = 1;
+ asm("sync");
+ des->controlr.ARS = 0;
+
+}
+/*! \fn void chip_version(void)
+ * \ingroup IFX_DES_FUNCTIONS
+ * \brief function not used in VR9
+*/
+void chip_version(void)
+{
+ return;
+}
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_vr9.h b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_vr9.h
new file mode 100644
index 0000000000..d2cfd11702
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu_vr9.h
@@ -0,0 +1,324 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_deu_vr9.h
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for VR9
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief deu driver module
+*/
+
+/*!
+ \file ifxmips_deu_vr9.h
+ \ingroup IFX_DEU
+ \brief board specific deu driver header file for vr9
+*/
+
+/*!
+ \defgroup IFX_DEU_DEFINITIONS IFX_DEU_DEFINITIONS
+ \brief deu driver header file
+*/
+
+
+#ifndef IFXMIPS_DEU_VR9_H
+#define IFXMIPS_DEU_VR9_H
+
+/* Project Header Files */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <crypto/algapi.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include "ifxmips_deu.h"
+
+
+#define AES_INIT 1
+#define DES_INIT 2
+#define ARC4_INIT 3
+#define SHA1_INIT 4
+#define MD5_INIT 5
+#define SHA1_HMAC_INIT 6
+#define MD5_HMAC_INIT 7
+
+#define AES_START IFX_AES_CON
+#define DES_3DES_START IFX_DES_CON
+
+#if 0
+#define AES_IDLE 0
+#define AES_BUSY 1
+#define AES_STARTED 2
+#define AES_COMPLETED 3
+#define DES_IDLE 0
+#define DES_BUSY 1
+#define DES_STARTED 2
+#define DES_COMPLETED 3
+#endif
+
+/* SHA1 CONSTANT */
+#define HASH_CON_VALUE 0x0701002C
+
+#define INPUT_ENDIAN_SWAP(input) input_swap(input)
+#define DEU_ENDIAN_SWAP(input) endian_swap(input)
+#define FIND_DEU_CHIP_VERSION chip_version()
+
+#if defined (CONFIG_AR10)
+#define DELAY_PERIOD 30
+#else
+#define DELAY_PERIOD 10
+#endif
+
+#define WAIT_AES_DMA_READY() \
+ do { \
+ int i; \
+ volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+ volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; \
+ for (i = 0; i < 10; i++) \
+ udelay(DELAY_PERIOD); \
+ while (dma->controlr.BSY) {}; \
+ while (aes->controlr.BUS) {}; \
+ } while (0)
+
+#define WAIT_DES_DMA_READY() \
+ do { \
+ int i; \
+ volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON; \
+ volatile struct des_t *des = (struct des_t *) DES_3DES_START; \
+ for (i = 0; i < 10; i++) \
+ udelay(DELAY_PERIOD); \
+ while (dma->controlr.BSY) {}; \
+ while (des->controlr.BUS) {}; \
+ } while (0)
+
+#define AES_DMA_MISC_CONFIG() \
+ do { \
+ volatile struct aes_t *aes = (volatile struct aes_t *) AES_START; \
+ aes->controlr.KRE = 1; \
+ aes->controlr.GO = 1; \
+ } while(0)
+
+#define SHA_HASH_INIT \
+ do { \
+ volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START; \
+ hash->controlr.ENDI = 1; \
+ hash->controlr.SM = 1; \
+ hash->controlr.ALGO = 0; \
+ hash->controlr.INIT = 1; \
+ } while(0)
+
+#define MD5_HASH_INIT \
+ do { \
+ volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START; \
+ hash->controlr.ENDI = 1; \
+ hash->controlr.SM = 1; \
+ hash->controlr.ALGO = 1; \
+ hash->controlr.INIT = 1; \
+ } while(0)
+
+/* DEU Common Structures for AR9*/
+
+struct clc_controlr_t {
+ u32 Res:26;
+ u32 FSOE:1;
+ u32 SBWE:1;
+ u32 EDIS:1;
+ u32 SPEN:1;
+ u32 DISS:1;
+ u32 DISR:1;
+
+};
+
+struct des_t {
+ struct des_controlr { //10h
+ u32 KRE:1;
+ u32 reserved1:5;
+ u32 GO:1;
+ u32 STP:1;
+ u32 Res2:6;
+ u32 NDC:1;
+ u32 ENDI:1;
+ u32 Res3:2;
+ u32 F:3;
+ u32 O:3;
+ u32 BUS:1;
+ u32 DAU:1;
+ u32 ARS:1;
+ u32 SM:1;
+ u32 E_D:1;
+ u32 M:3;
+
+ } controlr;
+ u32 IHR; //14h
+ u32 ILR; //18h
+ u32 K1HR; //1c
+ u32 K1LR; //
+ u32 K2HR;
+ u32 K2LR;
+ u32 K3HR;
+ u32 K3LR; //30h
+ u32 IVHR; //34h
+ u32 IVLR; //38
+ u32 OHR; //3c
+ u32 OLR; //40
+};
+
+struct aes_t {
+ struct aes_controlr {
+
+ u32 KRE:1;
+ u32 reserved1:4;
+ u32 PNK:1;
+ u32 GO:1;
+ u32 STP:1;
+ u32 reserved2:6;
+ u32 NDC:1;
+ u32 ENDI:1;
+ u32 reserved3:2;
+ u32 F:3; //fbs
+ u32 O:3; //om
+ u32 BUS:1; //bsy
+ u32 DAU:1;
+ u32 ARS:1;
+ u32 SM:1;
+ u32 E_D:1;
+ u32 KV:1;
+ u32 K:2; //KL
+
+ } controlr;
+ u32 ID3R; //80h
+ u32 ID2R; //84h
+ u32 ID1R; //88h
+ u32 ID0R; //8Ch
+ u32 K7R; //90h
+ u32 K6R; //94h
+ u32 K5R; //98h
+ u32 K4R; //9Ch
+ u32 K3R; //A0h
+ u32 K2R; //A4h
+ u32 K1R; //A8h
+ u32 K0R; //ACh
+ u32 IV3R; //B0h
+ u32 IV2R; //B4h
+ u32 IV1R; //B8h
+ u32 IV0R; //BCh
+ u32 OD3R; //D4h
+ u32 OD2R; //D8h
+ u32 OD1R; //DCh
+ u32 OD0R; //E0h
+};
+
+struct arc4_t {
+ struct arc4_controlr {
+
+ u32 KRE:1;
+ u32 KLEN:4;
+ u32 KSAE:1;
+ u32 GO:1;
+ u32 STP:1;
+ u32 reserved1:6;
+ u32 NDC:1;
+ u32 ENDI:1;
+ u32 reserved2:8;
+ u32 BUS:1; //bsy
+ u32 reserved3:1;
+ u32 ARS:1;
+ u32 SM:1;
+ u32 reserved4:4;
+
+ } controlr;
+ u32 K3R; //104h
+ u32 K2R; //108h
+ u32 K1R; //10Ch
+ u32 K0R; //110h
+
+ u32 IDLEN; //114h
+
+ u32 ID3R; //118h
+ u32 ID2R; //11Ch
+ u32 ID1R; //120h
+ u32 ID0R; //124h
+
+ u32 OD3R; //128h
+ u32 OD2R; //12Ch
+ u32 OD1R; //130h
+ u32 OD0R; //134h
+};
+
+struct deu_hash_t {
+ struct hash_controlr {
+ u32 reserved1:5;
+ u32 KHS:1;
+ u32 GO:1;
+ u32 INIT:1;
+ u32 reserved2:6;
+ u32 NDC:1;
+ u32 ENDI:1;
+ u32 reserved3:7;
+ u32 DGRY:1;
+ u32 BSY:1;
+ u32 reserved4:1;
+ u32 IRCL:1;
+ u32 SM:1;
+ u32 KYUE:1;
+ u32 HMEN:1;
+ u32 SSEN:1;
+ u32 ALGO:1;
+
+ } controlr;
+ u32 MR; //B4h
+ u32 D1R; //B8h
+ u32 D2R; //BCh
+ u32 D3R; //C0h
+ u32 D4R; //C4h
+ u32 D5R; //C8h
+
+ u32 dummy; //CCh
+
+ u32 KIDX; //D0h
+ u32 KEY; //D4h
+ u32 DBN; //D8h
+};
+
+
+struct deu_dma_t {
+ struct dma_controlr {
+ u32 reserved1:22;
+ u32 BS:2;
+ u32 BSY:1;
+ u32 reserved2:1;
+ u32 ALGO:2;
+ u32 RXCLS:2;
+ u32 reserved3:1;
+ u32 EN:1;
+
+ } controlr;
+};
+
+#endif /* IFXMIPS_DEU_VR9_H */
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_md5.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_md5.c
new file mode 100644
index 0000000000..591389fd56
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_md5.c
@@ -0,0 +1,310 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_md5.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for UEIP
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx deu driver module
+*/
+
+/*!
+ \file ifxmips_md5.c
+ \ingroup IFX_DEU
+ \brief MD5 encryption deu driver file
+*/
+
+/*!
+ \defgroup IFX_MD5_FUNCTIONS IFX_MD5_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief ifx deu MD5 functions
+*/
+
+/*Project header files */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/types.h>
+#include <crypto/internal/hash.h>
+#include <asm/byteorder.h>
+
+/* Project header */
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Plaform Unknwon!"
+#endif
+
+#define MD5_DIGEST_SIZE 16
+#define MD5_HMAC_BLOCK_SIZE 64
+#define MD5_BLOCK_WORDS 16
+#define MD5_HASH_WORDS 4
+#define HASH_START IFX_HASH_CON
+
+static spinlock_t lock;
+#define CRTCL_SECT_INIT spin_lock_init(&lock)
+#define CRTCL_SECT_START spin_lock_irqsave(&lock, flag)
+#define CRTCL_SECT_END spin_unlock_irqrestore(&lock, flag)
+
+//#define CRYPTO_DEBUG
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+
+struct md5_ctx {
+ int started;
+ u32 hash[MD5_HASH_WORDS];
+ u32 block[MD5_BLOCK_WORDS];
+ u64 byte_count;
+};
+
+extern int disable_deudma;
+
+/*! \fn static u32 endian_swap(u32 input)
+ * \ingroup IFX_MD5_FUNCTIONS
+ * \brief perform dword level endian swap
+ * \param input value of dword that requires to be swapped
+*/
+static u32 endian_swap(u32 input)
+{
+ u8 *ptr = (u8 *)&input;
+
+ return ((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
+}
+
+/*! \fn static void md5_transform(u32 *hash, u32 const *in)
+ * \ingroup IFX_MD5_FUNCTIONS
+ * \brief main interface to md5 hardware
+ * \param hash current hash value
+ * \param in 64-byte block of input
+*/
+static void md5_transform(struct md5_ctx *mctx, u32 *hash, u32 const *in)
+{
+ int i;
+ volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+ unsigned long flag;
+
+ CRTCL_SECT_START;
+
+ if (mctx->started) {
+ hashs->D1R = endian_swap(*((u32 *) hash + 0));
+ hashs->D2R = endian_swap(*((u32 *) hash + 1));
+ hashs->D3R = endian_swap(*((u32 *) hash + 2));
+ hashs->D4R = endian_swap(*((u32 *) hash + 3));
+ }
+
+ for (i = 0; i < 16; i++) {
+ hashs->MR = endian_swap(in[i]);
+// printk("in[%d]: %08x\n", i, endian_swap(in[i]));
+ };
+
+ //wait for processing
+ while (hashs->controlr.BSY) {
+ // this will not take long
+ }
+
+ *((u32 *) hash + 0) = endian_swap (hashs->D1R);
+ *((u32 *) hash + 1) = endian_swap (hashs->D2R);
+ *((u32 *) hash + 2) = endian_swap (hashs->D3R);
+ *((u32 *) hash + 3) = endian_swap (hashs->D4R);
+
+ mctx->started = 1;
+
+ CRTCL_SECT_END;
+}
+
+/*! \fn static inline void md5_transform_helper(struct md5_ctx *ctx)
+ * \ingroup IFX_MD5_FUNCTIONS
+ * \brief interfacing function for md5_transform()
+ * \param ctx crypto context
+*/
+static inline void md5_transform_helper(struct md5_ctx *ctx)
+{
+ //le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
+ md5_transform(ctx, ctx->hash, ctx->block);
+}
+
+/*! \fn static void md5_init(struct crypto_tfm *tfm)
+ * \ingroup IFX_MD5_FUNCTIONS
+ * \brief initialize md5 hardware
+ * \param tfm linux crypto algo transform
+*/
+static int md5_init(struct shash_desc *desc)
+{
+ struct md5_ctx *mctx = shash_desc_ctx(desc);
+ volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START;
+
+ hash->controlr.ENDI = 0;
+ hash->controlr.SM = 1;
+ hash->controlr.ALGO = 1; // 1 = md5 0 = sha1
+ hash->controlr.INIT = 1; // Initialize the hash operation by writing a '1' to the INIT bit.
+
+ mctx->byte_count = 0;
+ mctx->started = 0;
+ return 0;
+}
+
+/*! \fn static void md5_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
+ * \ingroup IFX_MD5_FUNCTIONS
+ * \brief on-the-fly md5 computation
+ * \param tfm linux crypto algo transform
+ * \param data input data
+ * \param len size of input data
+*/
+static int md5_update(struct shash_desc *desc, const u8 *data, unsigned int len)
+{
+ struct md5_ctx *mctx = shash_desc_ctx(desc);
+ const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
+
+ mctx->byte_count += len;
+
+ if (avail > len) {
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, len);
+ return 0;
+ }
+
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, avail);
+
+ md5_transform_helper(mctx);
+ data += avail;
+ len -= avail;
+
+ while (len >= sizeof(mctx->block)) {
+ memcpy(mctx->block, data, sizeof(mctx->block));
+ md5_transform_helper(mctx);
+ data += sizeof(mctx->block);
+ len -= sizeof(mctx->block);
+ }
+
+ memcpy(mctx->block, data, len);
+ return 0;
+}
+
+/*! \fn static void md5_final(struct crypto_tfm *tfm, u8 *out)
+ * \ingroup IFX_MD5_FUNCTIONS
+ * \brief compute final md5 value
+ * \param tfm linux crypto algo transform
+ * \param out final md5 output value
+*/
+static int md5_final(struct shash_desc *desc, u8 *out)
+{
+ struct md5_ctx *mctx = shash_desc_ctx(desc);
+ const unsigned int offset = mctx->byte_count & 0x3f;
+ char *p = (char *)mctx->block + offset;
+ int padding = 56 - (offset + 1);
+ volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+ unsigned long flag;
+
+ *p++ = 0x80;
+ if (padding < 0) {
+ memset(p, 0x00, padding + sizeof (u64));
+ md5_transform_helper(mctx);
+ p = (char *)mctx->block;
+ padding = 56;
+ }
+
+ memset(p, 0, padding);
+ mctx->block[14] = endian_swap(mctx->byte_count << 3);
+ mctx->block[15] = endian_swap(mctx->byte_count >> 29);
+
+#if 0
+ le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
+ sizeof(u64)) / sizeof(u32));
+#endif
+
+ md5_transform(mctx, mctx->hash, mctx->block);
+
+ CRTCL_SECT_START;
+
+ *((u32 *) out + 0) = endian_swap (hashs->D1R);
+ *((u32 *) out + 1) = endian_swap (hashs->D2R);
+ *((u32 *) out + 2) = endian_swap (hashs->D3R);
+ *((u32 *) out + 3) = endian_swap (hashs->D4R);
+
+ CRTCL_SECT_END;
+
+ // Wipe context
+ memset(mctx, 0, sizeof(*mctx));
+
+ return 0;
+}
+
+/*
+ * \brief MD5 function mappings
+*/
+static struct shash_alg ifxdeu_md5_alg = {
+ .digestsize = MD5_DIGEST_SIZE,
+ .init = md5_init,
+ .update = md5_update,
+ .final = md5_final,
+ .descsize = sizeof(struct md5_ctx),
+ .base = {
+ .cra_name = "md5",
+ .cra_driver_name= "ifxdeu-md5",
+ .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
+ .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+/*! \fn int __init ifxdeu_init_md5 (void)
+ * \ingroup IFX_MD5_FUNCTIONS
+ * \brief initialize md5 driver
+*/
+int __init ifxdeu_init_md5 (void)
+{
+ int ret = -ENOSYS;
+
+
+ if ((ret = crypto_register_shash(&ifxdeu_md5_alg)))
+ goto md5_err;
+
+ CRTCL_SECT_INIT;
+
+ printk (KERN_NOTICE "IFX DEU MD5 initialized%s.\n", disable_deudma ? "" : " (DMA)");
+ return ret;
+
+md5_err:
+ printk(KERN_ERR "IFX DEU MD5 initialization failed!\n");
+ return ret;
+}
+
+/*! \fn void __exit ifxdeu_fini_md5 (void)
+ * \ingroup IFX_MD5_FUNCTIONS
+ * \brief unregister md5 driver
+*/
+
+void __exit ifxdeu_fini_md5 (void)
+{
+ crypto_unregister_shash(&ifxdeu_md5_alg);
+
+}
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_md5_hmac.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_md5_hmac.c
new file mode 100644
index 0000000000..fc6f52ea7d
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_md5_hmac.c
@@ -0,0 +1,386 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_md5_hmac.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for UEIP
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+** 21,March 2011 Mohammad Firdaus Changes for Kernel 2.6.32 and IPSec integration
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx deu driver module
+*/
+
+/*!
+ \file ifxmips_md5_hmac.c
+ \ingroup IFX_DEU
+ \brief MD5-HMAC encryption deu driver file
+*/
+
+/*!
+ \defgroup IFX_MD5_HMAC_FUNCTIONS IFX_MD5_HMAC_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief ifx md5-hmac driver functions
+*/
+
+/* Project Header files */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/types.h>
+#include <crypto/internal/hash.h>
+#include <asm/byteorder.h>
+
+#if defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Plaform Unknwon!"
+#endif
+
+#define MD5_DIGEST_SIZE 16
+#define MD5_HMAC_BLOCK_SIZE 64
+#define MD5_BLOCK_WORDS 16
+#define MD5_HASH_WORDS 4
+#define MD5_HMAC_DBN_TEMP_SIZE 1024 // size in dword, needed for dbn workaround
+#define HASH_START IFX_HASH_CON
+
+static spinlock_t lock;
+#define CRTCL_SECT_INIT spin_lock_init(&lock)
+#define CRTCL_SECT_START spin_lock_irqsave(&lock, flag)
+#define CRTCL_SECT_END spin_unlock_irqrestore(&lock, flag)
+
+//#define CRYPTO_DEBUG
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+
+#define MAX_HASH_KEYLEN 64
+
+struct md5_hmac_ctx {
+ u8 key[MAX_HASH_KEYLEN];
+ u32 hash[MD5_HASH_WORDS];
+ u32 block[MD5_BLOCK_WORDS];
+ u64 byte_count;
+ u32 dbn;
+ unsigned int keylen;
+};
+
+static u32 temp[MD5_HMAC_DBN_TEMP_SIZE];
+
+extern int disable_deudma;
+
+/*! \fn static u32 endian_swap(u32 input)
+ * \ingroup IFX_MD5_HMAC_FUNCTIONS
+ * \brief perform dword level endian swap
+ * \param input value of dword that requires to be swapped
+*/
+static u32 endian_swap(u32 input)
+{
+ u8 *ptr = (u8 *)&input;
+
+ return ((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
+}
+
+/*! \fn static void md5_hmac_transform(struct crypto_tfm *tfm, u32 const *in)
+ * \ingroup IFX_MD5_HMAC_FUNCTIONS
+ * \brief save input block to context
+ * \param tfm linux crypto algo transform
+ * \param in 64-byte block of input
+*/
+static void md5_hmac_transform(struct shash_desc *desc, u32 const *in)
+{
+ struct md5_hmac_ctx *mctx = crypto_shash_ctx(desc->tfm);
+
+ memcpy(&temp[mctx->dbn<<4], in, 64); //dbn workaround
+ mctx->dbn += 1;
+
+ if ( (mctx->dbn<<4) > MD5_HMAC_DBN_TEMP_SIZE )
+ {
+ printk("MD5_HMAC_DBN_TEMP_SIZE exceeded\n");
+ }
+
+}
+
+/*! \fn int md5_hmac_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+ * \ingroup IFX_MD5_HMAC_FUNCTIONS
+ * \brief sets md5 hmac key
+ * \param tfm linux crypto algo transform
+ * \param key input key
+ * \param keylen key length greater than 64 bytes IS NOT SUPPORTED
+*/
+static int md5_hmac_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen)
+{
+ struct md5_hmac_ctx *mctx = crypto_shash_ctx(tfm);
+ volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START;
+ //printk("copying keys to context with length %d\n", keylen);
+
+ if (keylen > MAX_HASH_KEYLEN) {
+ printk("Key length more than what DEU hash can handle\n");
+ return -EINVAL;
+ }
+
+
+ hash->KIDX |= 0x80000000; // reset all 16 words of the key to '0'
+ memcpy(&mctx->key, key, keylen);
+ mctx->keylen = keylen;
+
+ return 0;
+
+}
+
+
+/*! \fn int md5_hmac_setkey_hw(const u8 *key, unsigned int keylen)
+ * \ingroup IFX_MD5_HMAC_FUNCTIONS
+ * \brief sets md5 hmac key into the hardware registers
+ * \param key input key
+ * \param keylen key length greater than 64 bytes IS NOT SUPPORTED
+*/
+
+static int md5_hmac_setkey_hw(const u8 *key, unsigned int keylen)
+{
+ volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START;
+ unsigned long flag;
+ int i, j;
+ u32 *in_key = (u32 *)key;
+
+ //printk("\nsetkey keylen: %d\n key: ", keylen);
+
+ CRTCL_SECT_START;
+ j = 0;
+ for (i = 0; i < keylen; i+=4)
+ {
+ hash->KIDX = j;
+ asm("sync");
+ hash->KEY = *((u32 *) in_key + j);
+ asm("sync");
+ j++;
+ }
+ CRTCL_SECT_END;
+
+ return 0;
+}
+
+/*! \fn void md5_hmac_init(struct crypto_tfm *tfm)
+ * \ingroup IFX_MD5_HMAC_FUNCTIONS
+ * \brief initialize md5 hmac context
+ * \param tfm linux crypto algo transform
+*/
+static int md5_hmac_init(struct shash_desc *desc)
+{
+
+ struct md5_hmac_ctx *mctx = crypto_shash_ctx(desc->tfm);
+
+
+ mctx->dbn = 0; //dbn workaround
+ md5_hmac_setkey_hw(mctx->key, mctx->keylen);
+
+ return 0;
+}
+EXPORT_SYMBOL(md5_hmac_init);
+
+/*! \fn void md5_hmac_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
+ * \ingroup IFX_MD5_HMAC_FUNCTIONS
+ * \brief on-the-fly md5 hmac computation
+ * \param tfm linux crypto algo transform
+ * \param data input data
+ * \param len size of input data
+*/
+static int md5_hmac_update(struct shash_desc *desc, const u8 *data, unsigned int len)
+{
+ struct md5_hmac_ctx *mctx = crypto_shash_ctx(desc->tfm);
+ const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
+
+ mctx->byte_count += len;
+
+ if (avail > len) {
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, len);
+ return 0;
+ }
+
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, avail);
+
+ md5_hmac_transform(desc, mctx->block);
+ data += avail;
+ len -= avail;
+
+ while (len >= sizeof(mctx->block)) {
+ memcpy(mctx->block, data, sizeof(mctx->block));
+ md5_hmac_transform(desc, mctx->block);
+ data += sizeof(mctx->block);
+ len -= sizeof(mctx->block);
+ }
+
+ memcpy(mctx->block, data, len);
+ return 0;
+}
+EXPORT_SYMBOL(md5_hmac_update);
+
+/*! \fn void md5_hmac_final(struct crypto_tfm *tfm, u8 *out)
+ * \ingroup IFX_MD5_HMAC_FUNCTIONS
+ * \brief compute final md5 hmac value
+ * \param tfm linux crypto algo transform
+ * \param out final md5 hmac output value
+*/
+static int md5_hmac_final(struct shash_desc *desc, u8 *out)
+{
+ struct md5_hmac_ctx *mctx = crypto_shash_ctx(desc->tfm);
+ const unsigned int offset = mctx->byte_count & 0x3f;
+ char *p = (char *)mctx->block + offset;
+ int padding = 56 - (offset + 1);
+ volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+ unsigned long flag;
+ int i = 0;
+ int dbn;
+ u32 *in = &temp[0];
+
+
+ *p++ = 0x80;
+ if (padding < 0) {
+ memset(p, 0x00, padding + sizeof (u64));
+ md5_hmac_transform(desc, mctx->block);
+ p = (char *)mctx->block;
+ padding = 56;
+ }
+
+ memset(p, 0, padding);
+ mctx->block[14] = endian_swap((mctx->byte_count + 64) << 3); // need to add 512 bit of the IPAD operation
+ mctx->block[15] = 0x00000000;
+
+ md5_hmac_transform(desc, mctx->block);
+
+ CRTCL_SECT_START;
+
+ //printk("\ndbn = %d\n", mctx->dbn);
+ hashs->DBN = mctx->dbn;
+ asm("sync");
+
+ *IFX_HASH_CON = 0x0703002D; //khs, go, init, ndc, endi, kyue, hmen, md5
+
+ //wait for processing
+ while (hashs->controlr.BSY) {
+ // this will not take long
+ }
+
+ for (dbn = 0; dbn < mctx->dbn; dbn++)
+ {
+ for (i = 0; i < 16; i++) {
+ hashs->MR = in[i];
+ };
+
+ hashs->controlr.GO = 1;
+ asm("sync");
+
+ //wait for processing
+ while (hashs->controlr.BSY) {
+ // this will not take long
+ }
+
+ in += 16;
+}
+
+
+#if 1
+ //wait for digest ready
+ while (! hashs->controlr.DGRY) {
+ // this will not take long
+ }
+#endif
+
+ *((u32 *) out + 0) = hashs->D1R;
+ *((u32 *) out + 1) = hashs->D2R;
+ *((u32 *) out + 2) = hashs->D3R;
+ *((u32 *) out + 3) = hashs->D4R;
+ *((u32 *) out + 4) = hashs->D5R;
+
+ /* reset the context after we finish with the hash */
+ mctx->byte_count = 0;
+ memset(&mctx->hash[0], 0, sizeof(MD5_HASH_WORDS));
+ memset(&mctx->block[0], 0, sizeof(MD5_BLOCK_WORDS));
+ memset(&temp[0], 0, MD5_HMAC_DBN_TEMP_SIZE);
+
+ CRTCL_SECT_END;
+
+
+ return 0;
+}
+
+EXPORT_SYMBOL(md5_hmac_final);
+
+/*
+ * \brief MD5_HMAC function mappings
+*/
+
+static struct shash_alg ifxdeu_md5_hmac_alg = {
+ .digestsize = MD5_DIGEST_SIZE,
+ .init = md5_hmac_init,
+ .update = md5_hmac_update,
+ .final = md5_hmac_final,
+ .setkey = md5_hmac_setkey,
+ .descsize = sizeof(struct md5_hmac_ctx),
+ .base = {
+ .cra_name = "hmac(md5)",
+ .cra_driver_name= "ifxdeu-md5_hmac",
+ .cra_ctxsize = sizeof(struct md5_hmac_ctx),
+ .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
+ .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+/*! \fn int __init ifxdeu_init_md5_hmac (void)
+ * \ingroup IFX_MD5_HMAC_FUNCTIONS
+ * \brief initialize md5 hmac driver
+*/
+int __init ifxdeu_init_md5_hmac (void)
+{
+
+ int ret = -ENOSYS;
+
+
+ if ((ret = crypto_register_shash(&ifxdeu_md5_hmac_alg)))
+ goto md5_hmac_err;
+
+ CRTCL_SECT_INIT;
+
+ printk (KERN_NOTICE "IFX DEU MD5_HMAC initialized%s.\n", disable_deudma ? "" : " (DMA)");
+ return ret;
+
+md5_hmac_err:
+ printk(KERN_ERR "IFX DEU MD5_HMAC initialization failed!\n");
+ return ret;
+}
+
+/** \fn void __exit ifxdeu_fini_md5_hmac (void)
+ * \ingroup IFX_MD5_HMAC_FUNCTIONS
+ * \brief unregister md5 hmac driver
+*/
+void __exit ifxdeu_fini_md5_hmac (void)
+{
+ crypto_unregister_shash(&ifxdeu_md5_hmac_alg);
+}
+
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_sha1.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_sha1.c
new file mode 100644
index 0000000000..a5f5f90a79
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_sha1.c
@@ -0,0 +1,301 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_sha1.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for Danube
+**
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx deu driver module
+*/
+
+/*!
+ \file ifxmips_sha1.c
+ \ingroup IFX_DEU
+ \brief SHA1 encryption deu driver file
+*/
+
+/*!
+ \defgroup IFX_SHA1_FUNCTIONS IFX_SHA1_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief ifx deu sha1 functions
+*/
+
+
+/* Project header */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/crypto.h>
+#include <linux/cryptohash.h>
+#include <crypto/sha.h>
+#include <crypto/internal/hash.h>
+#include <linux/types.h>
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+
+#if defined(CONFIG_DANUBE)
+#include "ifxmips_deu_danube.h"
+#elif defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Plaform Unknwon!"
+#endif
+
+#define SHA1_DIGEST_SIZE 20
+#define SHA1_HMAC_BLOCK_SIZE 64
+#define HASH_START IFX_HASH_CON
+
+static spinlock_t lock;
+#define CRTCL_SECT_INIT spin_lock_init(&lock)
+#define CRTCL_SECT_START spin_lock_irqsave(&lock, flag)
+#define CRTCL_SECT_END spin_unlock_irqrestore(&lock, flag)
+
+//#define CRYPTO_DEBUG
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+
+/*
+ * \brief SHA1 private structure
+*/
+struct sha1_ctx {
+ int started;
+ u64 count;
+ u32 hash[5];
+ u32 state[5];
+ u8 buffer[64];
+};
+
+extern int disable_deudma;
+
+
+/*! \fn static void sha1_transform (u32 *state, const u32 *in)
+ * \ingroup IFX_SHA1_FUNCTIONS
+ * \brief main interface to sha1 hardware
+ * \param state current state
+ * \param in 64-byte block of input
+*/
+static void sha1_transform (struct sha1_ctx *sctx, u32 *state, const u32 *in)
+{
+ int i = 0;
+ volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+ unsigned long flag;
+
+ CRTCL_SECT_START;
+
+ /* For context switching purposes, the previous hash output
+ * is loaded back into the output register
+ */
+ if (sctx->started) {
+ hashs->D1R = *((u32 *) sctx->hash + 0);
+ hashs->D2R = *((u32 *) sctx->hash + 1);
+ hashs->D3R = *((u32 *) sctx->hash + 2);
+ hashs->D4R = *((u32 *) sctx->hash + 3);
+ hashs->D5R = *((u32 *) sctx->hash + 4);
+ }
+
+ for (i = 0; i < 16; i++) {
+ hashs->MR = in[i];
+ };
+
+ //wait for processing
+ while (hashs->controlr.BSY) {
+ // this will not take long
+ }
+
+ /* For context switching purposes, the output is saved into a
+ * context struct which can be used later on
+ */
+ *((u32 *) sctx->hash + 0) = hashs->D1R;
+ *((u32 *) sctx->hash + 1) = hashs->D2R;
+ *((u32 *) sctx->hash + 2) = hashs->D3R;
+ *((u32 *) sctx->hash + 3) = hashs->D4R;
+ *((u32 *) sctx->hash + 4) = hashs->D5R;
+
+ sctx->started = 1;
+
+ CRTCL_SECT_END;
+}
+
+/*! \fn static void sha1_init(struct crypto_tfm *tfm)
+ * \ingroup IFX_SHA1_FUNCTIONS
+ * \brief initialize sha1 hardware
+ * \param tfm linux crypto algo transform
+*/
+static int sha1_init(struct shash_desc *desc)
+{
+ struct sha1_ctx *sctx = shash_desc_ctx(desc);
+
+ SHA_HASH_INIT;
+
+ sctx->started = 0;
+ sctx->count = 0;
+ return 0;
+}
+
+/*! \fn static void sha1_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
+ * \ingroup IFX_SHA1_FUNCTIONS
+ * \brief on-the-fly sha1 computation
+ * \param tfm linux crypto algo transform
+ * \param data input data
+ * \param len size of input data
+*/
+static int sha1_update(struct shash_desc * desc, const u8 *data,
+ unsigned int len)
+{
+ struct sha1_ctx *sctx = shash_desc_ctx(desc);
+ unsigned int i, j;
+
+ j = (sctx->count >> 3) & 0x3f;
+ sctx->count += len << 3;
+
+ if ((j + len) > 63) {
+ memcpy (&sctx->buffer[j], data, (i = 64 - j));
+ sha1_transform (sctx, sctx->state, (const u32 *)sctx->buffer);
+ for (; i + 63 < len; i += 64) {
+ sha1_transform (sctx, sctx->state, (const u32 *)&data[i]);
+ }
+
+ j = 0;
+ }
+ else
+ i = 0;
+
+ memcpy (&sctx->buffer[j], &data[i], len - i);
+ return 0;
+}
+
+/*! \fn static void sha1_final(struct crypto_tfm *tfm, u8 *out)
+ * \ingroup IFX_SHA1_FUNCTIONS
+ * \brief compute final sha1 value
+ * \param tfm linux crypto algo transform
+ * \param out final md5 output value
+*/
+static int sha1_final(struct shash_desc *desc, u8 *out)
+{
+ struct sha1_ctx *sctx = shash_desc_ctx(desc);
+ u32 index, padlen;
+ u64 t;
+ u8 bits[8] = { 0, };
+ static const u8 padding[64] = { 0x80, };
+ volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+ unsigned long flag;
+
+ t = sctx->count;
+ bits[7] = 0xff & t;
+ t >>= 8;
+ bits[6] = 0xff & t;
+ t >>= 8;
+ bits[5] = 0xff & t;
+ t >>= 8;
+ bits[4] = 0xff & t;
+ t >>= 8;
+ bits[3] = 0xff & t;
+ t >>= 8;
+ bits[2] = 0xff & t;
+ t >>= 8;
+ bits[1] = 0xff & t;
+ t >>= 8;
+ bits[0] = 0xff & t;
+
+ /* Pad out to 56 mod 64 */
+ index = (sctx->count >> 3) & 0x3f;
+ padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
+ sha1_update (desc, padding, padlen);
+
+ /* Append length */
+ sha1_update (desc, bits, sizeof bits);
+
+ CRTCL_SECT_START;
+
+ *((u32 *) out + 0) = hashs->D1R;
+ *((u32 *) out + 1) = hashs->D2R;
+ *((u32 *) out + 2) = hashs->D3R;
+ *((u32 *) out + 3) = hashs->D4R;
+ *((u32 *) out + 4) = hashs->D5R;
+
+ CRTCL_SECT_END;
+
+ // Wipe context
+ memset (sctx, 0, sizeof *sctx);
+
+ return 0;
+}
+
+/*
+ * \brief SHA1 function mappings
+*/
+static struct shash_alg ifxdeu_sha1_alg = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = sha1_init,
+ .update = sha1_update,
+ .final = sha1_final,
+ .descsize = sizeof(struct sha1_ctx),
+ .statesize = sizeof(struct sha1_state),
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name= "ifxdeu-sha1",
+ .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
+ .cra_blocksize = SHA1_HMAC_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+
+/*! \fn int __init ifxdeu_init_sha1 (void)
+ * \ingroup IFX_SHA1_FUNCTIONS
+ * \brief initialize sha1 driver
+*/
+int __init ifxdeu_init_sha1 (void)
+{
+ int ret = -ENOSYS;
+
+
+ if ((ret = crypto_register_shash(&ifxdeu_sha1_alg)))
+ goto sha1_err;
+
+ CRTCL_SECT_INIT;
+
+ printk (KERN_NOTICE "IFX DEU SHA1 initialized%s.\n", disable_deudma ? "" : " (DMA)");
+ return ret;
+
+sha1_err:
+ printk(KERN_ERR "IFX DEU SHA1 initialization failed!\n");
+ return ret;
+}
+
+/*! \fn void __exit ifxdeu_fini_sha1 (void)
+ * \ingroup IFX_SHA1_FUNCTIONS
+ * \brief unregister sha1 driver
+*/
+void __exit ifxdeu_fini_sha1 (void)
+{
+ crypto_unregister_shash(&ifxdeu_sha1_alg);
+
+
+}
+
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_sha1_hmac.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_sha1_hmac.c
new file mode 100644
index 0000000000..a5a6c39154
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_sha1_hmac.c
@@ -0,0 +1,378 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_sha1_hmac.c
+** PROJECT : IFX UEIP
+** MODULES : DEU Module for UEIP
+** DATE : September 8, 2009
+** AUTHOR : Mohammad Firdaus
+** DESCRIPTION : Data Encryption Unit Driver
+** COPYRIGHT : Copyright (c) 2009
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
+** 21,March 2011 Mohammad Firdaus Changes for Kernel 2.6.32 and IPSec integration
+*******************************************************************************/
+/*!
+ \defgroup IFX_DEU IFX_DEU_DRIVERS
+ \ingroup API
+ \brief ifx deu driver module
+*/
+
+/*!
+ \file ifxmips_sha1_hmac.c
+ \ingroup IFX_DEU
+ \brief SHA1-HMAC deu driver file
+*/
+
+/*!
+ \defgroup IFX_SHA1_HMAC_FUNCTIONS IFX_SHA1_HMAC_FUNCTIONS
+ \ingroup IFX_DEU
+ \brief ifx sha1 hmac functions
+*/
+
+
+/* Project header */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/crypto.h>
+#include <linux/cryptohash.h>
+#include <crypto/internal/hash.h>
+#include <linux/types.h>
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+#include <linux/delay.h>
+
+#if defined(CONFIG_AR9)
+#include "ifxmips_deu_ar9.h"
+#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
+#include "ifxmips_deu_vr9.h"
+#else
+#error "Plaform Unknwon!"
+#endif
+
+#define SHA1_DIGEST_SIZE 20
+#define SHA1_HMAC_BLOCK_SIZE 64
+#define SHA1_HMAC_DBN_TEMP_SIZE 1024 // size in dword, needed for dbn workaround
+#define HASH_START IFX_HASH_CON
+
+#define SHA1_HMAC_MAX_KEYLEN 64
+
+static spinlock_t lock;
+#define CRTCL_SECT_INIT spin_lock_init(&lock)
+#define CRTCL_SECT_START spin_lock_irqsave(&lock, flag)
+#define CRTCL_SECT_END spin_unlock_irqrestore(&lock, flag)
+
+#ifdef CRYPTO_DEBUG
+extern char debug_level;
+#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
+#else
+#define DPRINTF(level, format, args...)
+#endif
+
+struct sha1_hmac_ctx {
+ int keylen;
+
+ u8 buffer[SHA1_HMAC_BLOCK_SIZE];
+ u8 key[SHA1_HMAC_MAX_KEYLEN];
+ u32 state[5];
+ u32 dbn;
+ u64 count;
+
+};
+
+static u32 temp[SHA1_HMAC_DBN_TEMP_SIZE];
+
+extern int disable_deudma;
+
+/*! \fn static void sha1_hmac_transform(struct crypto_tfm *tfm, u32 const *in)
+ * \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ * \brief save input block to context
+ * \param tfm linux crypto algo transform
+ * \param in 64-byte block of input
+*/
+static int sha1_hmac_transform(struct shash_desc *desc, u32 const *in)
+{
+ struct sha1_hmac_ctx *sctx = crypto_shash_ctx(desc->tfm);
+
+ memcpy(&temp[sctx->dbn<<4], in, 64); //dbn workaround
+ sctx->dbn += 1;
+
+ if ( (sctx->dbn<<4) > SHA1_HMAC_DBN_TEMP_SIZE )
+ {
+ printk("SHA1_HMAC_DBN_TEMP_SIZE exceeded\n");
+ }
+
+ return 0;
+}
+
+/*! \fn int sha1_hmac_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+ * \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ * \brief sets sha1 hmac key
+ * \param tfm linux crypto algo transform
+ * \param key input key
+ * \param keylen key length greater than 64 bytes IS NOT SUPPORTED
+*/
+static int sha1_hmac_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen)
+{
+ struct sha1_hmac_ctx *sctx = crypto_shash_ctx(tfm);
+ volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+
+ if (keylen > SHA1_HMAC_MAX_KEYLEN) {
+ printk("Key length exceeds maximum key length\n");
+ return -EINVAL;
+ }
+
+ //printk("Setting keys of len: %d\n", keylen);
+
+ hashs->KIDX |= 0x80000000; //reset keys back to 0
+ memcpy(&sctx->key, key, keylen);
+ sctx->keylen = keylen;
+
+ return 0;
+
+}
+
+
+/*! \fn int sha1_hmac_setkey_hw(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+ * \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ * \brief sets sha1 hmac key into hw registers
+ * \param tfm linux crypto algo transform
+ * \param key input key
+ * \param keylen key length greater than 64 bytes IS NOT SUPPORTED
+*/
+static int sha1_hmac_setkey_hw(const u8 *key, unsigned int keylen)
+{
+ volatile struct deu_hash_t *hash = (struct deu_hash_t *) HASH_START;
+ int i, j;
+ unsigned long flag;
+ u32 *in_key = (u32 *)key;
+
+ j = 0;
+
+ CRTCL_SECT_START;
+ for (i = 0; i < keylen; i+=4)
+ {
+ hash->KIDX = j;
+ asm("sync");
+ hash->KEY = *((u32 *) in_key + j);
+ j++;
+ }
+
+ CRTCL_SECT_END;
+ return 0;
+}
+
+/*! \fn void sha1_hmac_init(struct crypto_tfm *tfm)
+ * \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ * \brief initialize sha1 hmac context
+ * \param tfm linux crypto algo transform
+*/
+static int sha1_hmac_init(struct shash_desc *desc)
+{
+ struct sha1_hmac_ctx *sctx = crypto_shash_ctx(desc->tfm);
+
+ //printk("debug ln: %d, fn: %s\n", __LINE__, __func__);
+ sctx->dbn = 0; //dbn workaround
+ sha1_hmac_setkey_hw(sctx->key, sctx->keylen);
+
+ return 0;
+}
+
+/*! \fn static void sha1_hmac_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
+ * \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ * \brief on-the-fly sha1 hmac computation
+ * \param tfm linux crypto algo transform
+ * \param data input data
+ * \param len size of input data
+*/
+static int sha1_hmac_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ struct sha1_hmac_ctx *sctx = crypto_shash_ctx(desc->tfm);
+ unsigned int i, j;
+
+ j = (sctx->count >> 3) & 0x3f;
+ sctx->count += len << 3;
+ // printk("sctx->count = %d\n", sctx->count);
+
+ if ((j + len) > 63) {
+ memcpy (&sctx->buffer[j], data, (i = 64 - j));
+ sha1_hmac_transform (desc, (const u32 *)sctx->buffer);
+ for (; i + 63 < len; i += 64) {
+ sha1_hmac_transform (desc, (const u32 *)&data[i]);
+ }
+
+ j = 0;
+ }
+ else
+ i = 0;
+
+ memcpy (&sctx->buffer[j], &data[i], len - i);
+ return 0;
+}
+
+/*! \fn static void sha1_hmac_final(struct crypto_tfm *tfm, u8 *out)
+ * \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ * \brief ompute final sha1 hmac value
+ * \param tfm linux crypto algo transform
+ * \param out final sha1 hmac output value
+*/
+static int sha1_hmac_final(struct shash_desc *desc, u8 *out)
+{
+ //struct sha1_hmac_ctx *sctx = shash_desc_ctx(desc);
+ struct sha1_hmac_ctx *sctx = crypto_shash_ctx(desc->tfm);
+ u32 index, padlen;
+ u64 t;
+ u8 bits[8] = { 0, };
+ static const u8 padding[64] = { 0x80, };
+ volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
+ unsigned long flag;
+ int i = 0;
+ int dbn;
+ u32 *in = &temp[0];
+
+ t = sctx->count + 512; // need to add 512 bit of the IPAD operation
+ bits[7] = 0xff & t;
+ t >>= 8;
+ bits[6] = 0xff & t;
+ t >>= 8;
+ bits[5] = 0xff & t;
+ t >>= 8;
+ bits[4] = 0xff & t;
+ t >>= 8;
+ bits[3] = 0xff & t;
+ t >>= 8;
+ bits[2] = 0xff & t;
+ t >>= 8;
+ bits[1] = 0xff & t;
+ t >>= 8;
+ bits[0] = 0xff & t;
+
+ /* Pad out to 56 mod 64 */
+ index = (sctx->count >> 3) & 0x3f;
+ padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
+ sha1_hmac_update (desc, padding, padlen);
+
+ /* Append length */
+ sha1_hmac_update (desc, bits, sizeof bits);
+
+ CRTCL_SECT_START;
+
+ hashs->DBN = sctx->dbn;
+
+ //for vr9 change, ENDI = 1
+ *IFX_HASH_CON = HASH_CON_VALUE;
+
+ //wait for processing
+ while (hashs->controlr.BSY) {
+ // this will not take long
+ }
+
+ for (dbn = 0; dbn < sctx->dbn; dbn++)
+ {
+ for (i = 0; i < 16; i++) {
+ hashs->MR = in[i];
+ };
+
+ hashs->controlr.GO = 1;
+ asm("sync");
+
+ //wait for processing
+ while (hashs->controlr.BSY) {
+ // this will not take long
+ }
+
+ in += 16;
+}
+
+
+#if 1
+ //wait for digest ready
+ while (! hashs->controlr.DGRY) {
+ // this will not take long
+ }
+#endif
+
+ *((u32 *) out + 0) = hashs->D1R;
+ *((u32 *) out + 1) = hashs->D2R;
+ *((u32 *) out + 2) = hashs->D3R;
+ *((u32 *) out + 3) = hashs->D4R;
+ *((u32 *) out + 4) = hashs->D5R;
+
+ memset(&sctx->buffer[0], 0, SHA1_HMAC_BLOCK_SIZE);
+ sctx->count = 0;
+
+ //printk("debug ln: %d, fn: %s\n", __LINE__, __func__);
+ CRTCL_SECT_END;
+
+
+ return 0;
+
+}
+
+/*
+ * \brief SHA1-HMAC function mappings
+*/
+static struct shash_alg ifxdeu_sha1_hmac_alg = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = sha1_hmac_init,
+ .update = sha1_hmac_update,
+ .final = sha1_hmac_final,
+ .setkey = sha1_hmac_setkey,
+ .descsize = sizeof(struct sha1_hmac_ctx),
+ .base = {
+ .cra_name = "hmac(sha1)",
+ .cra_driver_name= "ifxdeu-sha1_hmac",
+ .cra_ctxsize = sizeof(struct sha1_hmac_ctx),
+ .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
+ .cra_blocksize = SHA1_HMAC_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+
+};
+
+
+/*! \fn int __init ifxdeu_init_sha1_hmac (void)
+ * \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ * \brief initialize sha1 hmac driver
+*/
+int __init ifxdeu_init_sha1_hmac (void)
+{
+ int ret = -ENOSYS;
+
+
+
+ if ((ret = crypto_register_shash(&ifxdeu_sha1_hmac_alg)))
+ goto sha1_err;
+
+ CRTCL_SECT_INIT;
+
+ printk (KERN_NOTICE "IFX DEU SHA1_HMAC initialized%s.\n", disable_deudma ? "" : " (DMA)");
+ return ret;
+
+sha1_err:
+ printk(KERN_ERR "IFX DEU SHA1_HMAC initialization failed!\n");
+ return ret;
+}
+
+/*! \fn void __exit ifxdeu_fini_sha1_hmac (void)
+ * \ingroup IFX_SHA1_HMAC_FUNCTIONS
+ * \brief unregister sha1 hmac driver
+*/
+void __exit ifxdeu_fini_sha1_hmac (void)
+{
+
+ crypto_unregister_shash(&ifxdeu_sha1_hmac_alg);
+
+
+}
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_tcrypt.h b/package/kernel/lantiq/ltq-deu/src/ifxmips_tcrypt.h
new file mode 100644
index 0000000000..1e7047b593
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_tcrypt.h
@@ -0,0 +1,92 @@
+/*
+ * Quick & dirty crypto testing module.
+ *
+ * This will only exist until we have a better testing mechanism
+ * (e.g. a char device).
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) 2007 Nokia Siemens Networks
+ *
+ * This program is free software; 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 _IFXMIPS_CRYPTO_TCRYPT_H
+#define _IFXMIPS_CRYPTO_TCRYPT_H
+
+struct cipher_speed_template {
+ const char *key;
+ unsigned int klen;
+};
+
+struct hash_speed {
+ unsigned int blen; /* buffer length */
+ unsigned int plen; /* per-update length */
+};
+
+/*
+ * DES test vectors.
+ */
+#define DES3_SPEED_VECTORS 1
+#define CRYPTO_ALG_TYPE_SPEED_TEST 0xB
+
+static int alg_speed_test(const char *alg, const char *driver,
+ unsigned int sec,
+ struct cipher_speed_template *t,
+ unsigned int tcount, u8 *keysize);
+
+static struct cipher_speed_template des3_speed_template[] = {
+ {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\x55\x55\x55\x55\x55\x55\x55\x55"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .klen = 24,
+ }
+};
+
+/*
+ * Cipher speed tests
+ */
+static u8 speed_template_8[] = {8, 0};
+static u8 speed_template_24[] = {24, 0};
+static u8 speed_template_8_32[] = {8, 32, 0};
+static u8 speed_template_16_32[] = {16, 32, 0};
+static u8 speed_template_16_24_32[] = {16, 24, 32, 0};
+static u8 speed_template_32_40_48[] = {32, 40, 48, 0};
+static u8 speed_template_32_48_64[] = {32, 48, 64, 0};
+
+/*
+ * Digest speed tests
+ */
+static struct hash_speed generic_hash_speed_template[] = {
+ { .blen = 16, .plen = 16, },
+ { .blen = 64, .plen = 16, },
+ { .blen = 64, .plen = 64, },
+ { .blen = 256, .plen = 16, },
+ { .blen = 256, .plen = 64, },
+ { .blen = 256, .plen = 256, },
+ { .blen = 1024, .plen = 16, },
+ { .blen = 1024, .plen = 256, },
+ { .blen = 1024, .plen = 1024, },
+ { .blen = 2048, .plen = 16, },
+ { .blen = 2048, .plen = 256, },
+ { .blen = 2048, .plen = 1024, },
+ { .blen = 2048, .plen = 2048, },
+ { .blen = 4096, .plen = 16, },
+ { .blen = 4096, .plen = 256, },
+ { .blen = 4096, .plen = 1024, },
+ { .blen = 4096, .plen = 4096, },
+ { .blen = 8192, .plen = 16, },
+ { .blen = 8192, .plen = 256, },
+ { .blen = 8192, .plen = 1024, },
+ { .blen = 8192, .plen = 4096, },
+ { .blen = 8192, .plen = 8192, },
+
+ /* End marker */
+ { .blen = 0, .plen = 0, }
+};
+
+#endif /* _CRYPTO_TCRYPT_H */
diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_testmgr.h b/package/kernel/lantiq/ltq-deu/src/ifxmips_testmgr.h
new file mode 100644
index 0000000000..27fe9a9f62
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_testmgr.h
@@ -0,0 +1,9598 @@
+/*
+ * Algorithm testing framework and tests.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) 2007 Nokia Siemens Networks
+ * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program is free software; 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 _IFXMIPS_CRYPTO_TESTMGR_H
+#define _IFXMIPS_CRYPTO_TESTMGR_H
+
+#include <linux/netlink.h>
+#include <linux/zlib.h>
+
+#include <crypto/compress.h>
+
+#define MAX_DIGEST_SIZE 64
+#define MAX_TAP 8
+
+#define MAX_KEYLEN 56
+#define MAX_IVLEN 32
+
+struct hash_testvec {
+ /* only used with keyed hash algorithms */
+ char *key;
+ char *plaintext;
+ char *digest;
+ unsigned char tap[MAX_TAP];
+ unsigned char psize;
+ unsigned char np;
+ unsigned char ksize;
+};
+
+struct cipher_testvec {
+ char *key;
+ char *iv;
+ char *input;
+ char *result;
+ unsigned short tap[MAX_TAP];
+ int np;
+ unsigned char fail;
+ unsigned char wk; /* weak key flag */
+ unsigned char klen;
+ unsigned short ilen;
+ unsigned short rlen;
+};
+
+struct aead_testvec {
+ char *key;
+ char *iv;
+ char *input;
+ char *assoc;
+ char *result;
+ unsigned char tap[MAX_TAP];
+ unsigned char atap[MAX_TAP];
+ int np;
+ int anp;
+ unsigned char fail;
+ unsigned char novrfy; /* ccm dec verification failure expected */
+ unsigned char wk; /* weak key flag */
+ unsigned char klen;
+ unsigned short ilen;
+ unsigned short alen;
+ unsigned short rlen;
+};
+
+struct cprng_testvec {
+ char *key;
+ char *dt;
+ char *v;
+ char *result;
+ unsigned char klen;
+ unsigned short dtlen;
+ unsigned short vlen;
+ unsigned short rlen;
+ unsigned short loops;
+};
+
+static char zeroed_string[48];
+
+/*
+ * MD4 test vectors from RFC1320
+ */
+#define MD4_TEST_VECTORS 7
+
+static struct hash_testvec md4_tv_template [] = {
+ {
+ .plaintext = "",
+ .digest = "\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31"
+ "\xb7\x3c\x59\xd7\xe0\xc0\x89\xc0",
+ }, {
+ .plaintext = "a",
+ .psize = 1,
+ .digest = "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46"
+ "\x24\x5e\x05\xfb\xdb\xd6\xfb\x24",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\xa4\x48\x01\x7a\xaf\x21\xd8\x52"
+ "\x5f\xc1\x0a\xe8\x7a\xa6\x72\x9d",
+ }, {
+ .plaintext = "message digest",
+ .psize = 14,
+ .digest = "\xd9\x13\x0a\x81\x64\x54\x9f\xe8"
+ "\x18\x87\x48\x06\xe1\xc7\x01\x4b",
+ }, {
+ .plaintext = "abcdefghijklmnopqrstuvwxyz",
+ .psize = 26,
+ .digest = "\xd7\x9e\x1c\x30\x8a\xa5\xbb\xcd"
+ "\xee\xa8\xed\x63\xdf\x41\x2d\xa9",
+ .np = 2,
+ .tap = { 13, 13 },
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ .psize = 62,
+ .digest = "\x04\x3f\x85\x82\xf2\x41\xdb\x35"
+ "\x1c\xe6\x27\xe1\x53\xe7\xf0\xe4",
+ }, {
+ .plaintext = "123456789012345678901234567890123456789012345678901234567890123"
+ "45678901234567890",
+ .psize = 80,
+ .digest = "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19"
+ "\x9c\x3e\x7b\x16\x4f\xcc\x05\x36",
+ },
+};
+
+/*
+ * MD5 test vectors from RFC1321
+ */
+#define MD5_TEST_VECTORS 7
+
+static struct hash_testvec md5_tv_template[] = {
+ {
+ .digest = "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04"
+ "\xe9\x80\x09\x98\xec\xf8\x42\x7e",
+ }, {
+ .plaintext = "a",
+ .psize = 1,
+ .digest = "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8"
+ "\x31\xc3\x99\xe2\x69\x77\x26\x61",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\x90\x01\x50\x98\x3c\xd2\x4f\xb0"
+ "\xd6\x96\x3f\x7d\x28\xe1\x7f\x72",
+ }, {
+ .plaintext = "message digest",
+ .psize = 14,
+ .digest = "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d"
+ "\x52\x5a\x2f\x31\xaa\xf1\x61\xd0",
+ }, {
+ .plaintext = "abcdefghijklmnopqrstuvwxyz",
+ .psize = 26,
+ .digest = "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00"
+ "\x7d\xfb\x49\x6c\xca\x67\xe1\x3b",
+ .np = 2,
+ .tap = {13, 13}
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ .psize = 62,
+ .digest = "\xd1\x74\xab\x98\xd2\x77\xd9\xf5"
+ "\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f",
+ }, {
+ .plaintext = "12345678901234567890123456789012345678901234567890123456789012"
+ "345678901234567890",
+ .psize = 80,
+ .digest = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55"
+ "\xac\x49\xda\x2e\x21\x07\xb6\x7a",
+ }
+
+};
+
+/*
+ * RIPEMD-128 test vectors from ISO/IEC 10118-3:2004(E)
+ */
+#define RMD128_TEST_VECTORS 10
+
+static struct hash_testvec rmd128_tv_template[] = {
+ {
+ .digest = "\xcd\xf2\x62\x13\xa1\x50\xdc\x3e"
+ "\xcb\x61\x0f\x18\xf6\xb3\x8b\x46",
+ }, {
+ .plaintext = "a",
+ .psize = 1,
+ .digest = "\x86\xbe\x7a\xfa\x33\x9d\x0f\xc7"
+ "\xcf\xc7\x85\xe7\x2f\x57\x8d\x33",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\xc1\x4a\x12\x19\x9c\x66\xe4\xba"
+ "\x84\x63\x6b\x0f\x69\x14\x4c\x77",
+ }, {
+ .plaintext = "message digest",
+ .psize = 14,
+ .digest = "\x9e\x32\x7b\x3d\x6e\x52\x30\x62"
+ "\xaf\xc1\x13\x2d\x7d\xf9\xd1\xb8",
+ }, {
+ .plaintext = "abcdefghijklmnopqrstuvwxyz",
+ .psize = 26,
+ .digest = "\xfd\x2a\xa6\x07\xf7\x1d\xc8\xf5"
+ "\x10\x71\x49\x22\xb3\x71\x83\x4e",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+ "fghijklmnopqrstuvwxyz0123456789",
+ .psize = 62,
+ .digest = "\xd1\xe9\x59\xeb\x17\x9c\x91\x1f"
+ "\xae\xa4\x62\x4c\x60\xc5\xc7\x02",
+ }, {
+ .plaintext = "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890",
+ .psize = 80,
+ .digest = "\x3f\x45\xef\x19\x47\x32\xc2\xdb"
+ "\xb2\xc4\xa2\xc7\x69\x79\x5f\xa3",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighij"
+ "hijkijkljklmklmnlmnomnopnopq",
+ .psize = 56,
+ .digest = "\xa1\xaa\x06\x89\xd0\xfa\xfa\x2d"
+ "\xdc\x22\xe8\x8b\x49\x13\x3a\x06",
+ .np = 2,
+ .tap = { 28, 28 },
+ }, {
+ .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
+ "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqr"
+ "lmnopqrsmnopqrstnopqrstu",
+ .psize = 112,
+ .digest = "\xd4\xec\xc9\x13\xe1\xdf\x77\x6b"
+ "\xf4\x8d\xe9\xd5\x5b\x1f\x25\x46",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+ .psize = 32,
+ .digest = "\x13\xfc\x13\xe8\xef\xff\x34\x7d"
+ "\xe1\x93\xff\x46\xdb\xac\xcf\xd4",
+ }
+};
+
+/*
+ * RIPEMD-160 test vectors from ISO/IEC 10118-3:2004(E)
+ */
+#define RMD160_TEST_VECTORS 10
+
+static struct hash_testvec rmd160_tv_template[] = {
+ {
+ .digest = "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28"
+ "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31",
+ }, {
+ .plaintext = "a",
+ .psize = 1,
+ .digest = "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae"
+ "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04"
+ "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc",
+ }, {
+ .plaintext = "message digest",
+ .psize = 14,
+ .digest = "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8"
+ "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36",
+ }, {
+ .plaintext = "abcdefghijklmnopqrstuvwxyz",
+ .psize = 26,
+ .digest = "\xf7\x1c\x27\x10\x9c\x69\x2c\x1b\x56\xbb"
+ "\xdc\xeb\x5b\x9d\x28\x65\xb3\x70\x8d\xbc",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+ "fghijklmnopqrstuvwxyz0123456789",
+ .psize = 62,
+ .digest = "\xb0\xe2\x0b\x6e\x31\x16\x64\x02\x86\xed"
+ "\x3a\x87\xa5\x71\x30\x79\xb2\x1f\x51\x89",
+ }, {
+ .plaintext = "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890",
+ .psize = 80,
+ .digest = "\x9b\x75\x2e\x45\x57\x3d\x4b\x39\xf4\xdb"
+ "\xd3\x32\x3c\xab\x82\xbf\x63\x32\x6b\xfb",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighij"
+ "hijkijkljklmklmnlmnomnopnopq",
+ .psize = 56,
+ .digest = "\x12\xa0\x53\x38\x4a\x9c\x0c\x88\xe4\x05"
+ "\xa0\x6c\x27\xdc\xf4\x9a\xda\x62\xeb\x2b",
+ .np = 2,
+ .tap = { 28, 28 },
+ }, {
+ .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
+ "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqr"
+ "lmnopqrsmnopqrstnopqrstu",
+ .psize = 112,
+ .digest = "\x6f\x3f\xa3\x9b\x6b\x50\x3c\x38\x4f\x91"
+ "\x9a\x49\xa7\xaa\x5c\x2c\x08\xbd\xfb\x45",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+ .psize = 32,
+ .digest = "\x94\xc2\x64\x11\x54\x04\xe6\x33\x79\x0d"
+ "\xfc\xc8\x7b\x58\x7d\x36\x77\x06\x7d\x9f",
+ }
+};
+
+/*
+ * RIPEMD-256 test vectors
+ */
+#define RMD256_TEST_VECTORS 8
+
+static struct hash_testvec rmd256_tv_template[] = {
+ {
+ .digest = "\x02\xba\x4c\x4e\x5f\x8e\xcd\x18"
+ "\x77\xfc\x52\xd6\x4d\x30\xe3\x7a"
+ "\x2d\x97\x74\xfb\x1e\x5d\x02\x63"
+ "\x80\xae\x01\x68\xe3\xc5\x52\x2d",
+ }, {
+ .plaintext = "a",
+ .psize = 1,
+ .digest = "\xf9\x33\x3e\x45\xd8\x57\xf5\xd9"
+ "\x0a\x91\xba\xb7\x0a\x1e\xba\x0c"
+ "\xfb\x1b\xe4\xb0\x78\x3c\x9a\xcf"
+ "\xcd\x88\x3a\x91\x34\x69\x29\x25",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\xaf\xbd\x6e\x22\x8b\x9d\x8c\xbb"
+ "\xce\xf5\xca\x2d\x03\xe6\xdb\xa1"
+ "\x0a\xc0\xbc\x7d\xcb\xe4\x68\x0e"
+ "\x1e\x42\xd2\xe9\x75\x45\x9b\x65",
+ }, {
+ .plaintext = "message digest",
+ .psize = 14,
+ .digest = "\x87\xe9\x71\x75\x9a\x1c\xe4\x7a"
+ "\x51\x4d\x5c\x91\x4c\x39\x2c\x90"
+ "\x18\xc7\xc4\x6b\xc1\x44\x65\x55"
+ "\x4a\xfc\xdf\x54\xa5\x07\x0c\x0e",
+ }, {
+ .plaintext = "abcdefghijklmnopqrstuvwxyz",
+ .psize = 26,
+ .digest = "\x64\x9d\x30\x34\x75\x1e\xa2\x16"
+ "\x77\x6b\xf9\xa1\x8a\xcc\x81\xbc"
+ "\x78\x96\x11\x8a\x51\x97\x96\x87"
+ "\x82\xdd\x1f\xd9\x7d\x8d\x51\x33",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+ "fghijklmnopqrstuvwxyz0123456789",
+ .psize = 62,
+ .digest = "\x57\x40\xa4\x08\xac\x16\xb7\x20"
+ "\xb8\x44\x24\xae\x93\x1c\xbb\x1f"
+ "\xe3\x63\xd1\xd0\xbf\x40\x17\xf1"
+ "\xa8\x9f\x7e\xa6\xde\x77\xa0\xb8",
+ }, {
+ .plaintext = "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890",
+ .psize = 80,
+ .digest = "\x06\xfd\xcc\x7a\x40\x95\x48\xaa"
+ "\xf9\x13\x68\xc0\x6a\x62\x75\xb5"
+ "\x53\xe3\xf0\x99\xbf\x0e\xa4\xed"
+ "\xfd\x67\x78\xdf\x89\xa8\x90\xdd",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighij"
+ "hijkijkljklmklmnlmnomnopnopq",
+ .psize = 56,
+ .digest = "\x38\x43\x04\x55\x83\xaa\xc6\xc8"
+ "\xc8\xd9\x12\x85\x73\xe7\xa9\x80"
+ "\x9a\xfb\x2a\x0f\x34\xcc\xc3\x6e"
+ "\xa9\xe7\x2f\x16\xf6\x36\x8e\x3f",
+ .np = 2,
+ .tap = { 28, 28 },
+ }
+};
+
+/*
+ * RIPEMD-320 test vectors
+ */
+#define RMD320_TEST_VECTORS 8
+
+static struct hash_testvec rmd320_tv_template[] = {
+ {
+ .digest = "\x22\xd6\x5d\x56\x61\x53\x6c\xdc\x75\xc1"
+ "\xfd\xf5\xc6\xde\x7b\x41\xb9\xf2\x73\x25"
+ "\xeb\xc6\x1e\x85\x57\x17\x7d\x70\x5a\x0e"
+ "\xc8\x80\x15\x1c\x3a\x32\xa0\x08\x99\xb8",
+ }, {
+ .plaintext = "a",
+ .psize = 1,
+ .digest = "\xce\x78\x85\x06\x38\xf9\x26\x58\xa5\xa5"
+ "\x85\x09\x75\x79\x92\x6d\xda\x66\x7a\x57"
+ "\x16\x56\x2c\xfc\xf6\xfb\xe7\x7f\x63\x54"
+ "\x2f\x99\xb0\x47\x05\xd6\x97\x0d\xff\x5d",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\xde\x4c\x01\xb3\x05\x4f\x89\x30\xa7\x9d"
+ "\x09\xae\x73\x8e\x92\x30\x1e\x5a\x17\x08"
+ "\x5b\xef\xfd\xc1\xb8\xd1\x16\x71\x3e\x74"
+ "\xf8\x2f\xa9\x42\xd6\x4c\xdb\xc4\x68\x2d",
+ }, {
+ .plaintext = "message digest",
+ .psize = 14,
+ .digest = "\x3a\x8e\x28\x50\x2e\xd4\x5d\x42\x2f\x68"
+ "\x84\x4f\x9d\xd3\x16\xe7\xb9\x85\x33\xfa"
+ "\x3f\x2a\x91\xd2\x9f\x84\xd4\x25\xc8\x8d"
+ "\x6b\x4e\xff\x72\x7d\xf6\x6a\x7c\x01\x97",
+ }, {
+ .plaintext = "abcdefghijklmnopqrstuvwxyz",
+ .psize = 26,
+ .digest = "\xca\xbd\xb1\x81\x0b\x92\x47\x0a\x20\x93"
+ "\xaa\x6b\xce\x05\x95\x2c\x28\x34\x8c\xf4"
+ "\x3f\xf6\x08\x41\x97\x51\x66\xbb\x40\xed"
+ "\x23\x40\x04\xb8\x82\x44\x63\xe6\xb0\x09",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+ "fghijklmnopqrstuvwxyz0123456789",
+ .psize = 62,
+ .digest = "\xed\x54\x49\x40\xc8\x6d\x67\xf2\x50\xd2"
+ "\x32\xc3\x0b\x7b\x3e\x57\x70\xe0\xc6\x0c"
+ "\x8c\xb9\xa4\xca\xfe\x3b\x11\x38\x8a\xf9"
+ "\x92\x0e\x1b\x99\x23\x0b\x84\x3c\x86\xa4",
+ }, {
+ .plaintext = "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890",
+ .psize = 80,
+ .digest = "\x55\x78\x88\xaf\x5f\x6d\x8e\xd6\x2a\xb6"
+ "\x69\x45\xc6\xd2\xa0\xa4\x7e\xcd\x53\x41"
+ "\xe9\x15\xeb\x8f\xea\x1d\x05\x24\x95\x5f"
+ "\x82\x5d\xc7\x17\xe4\xa0\x08\xab\x2d\x42",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighij"
+ "hijkijkljklmklmnlmnomnopnopq",
+ .psize = 56,
+ .digest = "\xd0\x34\xa7\x95\x0c\xf7\x22\x02\x1b\xa4"
+ "\xb8\x4d\xf7\x69\xa5\xde\x20\x60\xe2\x59"
+ "\xdf\x4c\x9b\xb4\xa4\x26\x8c\x0e\x93\x5b"
+ "\xbc\x74\x70\xa9\x69\xc9\xd0\x72\xa1\xac",
+ .np = 2,
+ .tap = { 28, 28 },
+ }
+};
+
+/*
+ * SHA1 test vectors from from FIPS PUB 180-1
+ */
+#define SHA1_TEST_VECTORS 2
+
+static struct hash_testvec sha1_tv_template[] = {
+ {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e"
+ "\x25\x71\x78\x50\xc2\x6c\x9c\xd0\xd8\x9d",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .psize = 56,
+ .digest = "\x84\x98\x3e\x44\x1c\x3b\xd2\x6e\xba\xae"
+ "\x4a\xa1\xf9\x51\x29\xe5\xe5\x46\x70\xf1",
+ .np = 2,
+ .tap = { 28, 28 }
+ }
+};
+
+
+/*
+ * SHA224 test vectors from from FIPS PUB 180-2
+ */
+#define SHA224_TEST_VECTORS 2
+
+static struct hash_testvec sha224_tv_template[] = {
+ {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\x23\x09\x7D\x22\x34\x05\xD8\x22"
+ "\x86\x42\xA4\x77\xBD\xA2\x55\xB3"
+ "\x2A\xAD\xBC\xE4\xBD\xA0\xB3\xF7"
+ "\xE3\x6C\x9D\xA7",
+ }, {
+ .plaintext =
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .psize = 56,
+ .digest = "\x75\x38\x8B\x16\x51\x27\x76\xCC"
+ "\x5D\xBA\x5D\xA1\xFD\x89\x01\x50"
+ "\xB0\xC6\x45\x5C\xB4\xF5\x8B\x19"
+ "\x52\x52\x25\x25",
+ .np = 2,
+ .tap = { 28, 28 }
+ }
+};
+
+/*
+ * SHA256 test vectors from from NIST
+ */
+#define SHA256_TEST_VECTORS 2
+
+static struct hash_testvec sha256_tv_template[] = {
+ {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\xba\x78\x16\xbf\x8f\x01\xcf\xea"
+ "\x41\x41\x40\xde\x5d\xae\x22\x23"
+ "\xb0\x03\x61\xa3\x96\x17\x7a\x9c"
+ "\xb4\x10\xff\x61\xf2\x00\x15\xad",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .psize = 56,
+ .digest = "\x24\x8d\x6a\x61\xd2\x06\x38\xb8"
+ "\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
+ "\xa3\x3c\xe4\x59\x64\xff\x21\x67"
+ "\xf6\xec\xed\xd4\x19\xdb\x06\xc1",
+ .np = 2,
+ .tap = { 28, 28 }
+ },
+};
+
+/*
+ * SHA384 test vectors from from NIST and kerneli
+ */
+#define SHA384_TEST_VECTORS 4
+
+static struct hash_testvec sha384_tv_template[] = {
+ {
+ .plaintext= "abc",
+ .psize = 3,
+ .digest = "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b"
+ "\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
+ "\x27\x2c\x32\xab\x0e\xde\xd1\x63"
+ "\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
+ "\x80\x86\x07\x2b\xa1\xe7\xcc\x23"
+ "\x58\xba\xec\xa1\x34\xc8\x25\xa7",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .psize = 56,
+ .digest = "\x33\x91\xfd\xdd\xfc\x8d\xc7\x39"
+ "\x37\x07\xa6\x5b\x1b\x47\x09\x39"
+ "\x7c\xf8\xb1\xd1\x62\xaf\x05\xab"
+ "\xfe\x8f\x45\x0d\xe5\xf3\x6b\xc6"
+ "\xb0\x45\x5a\x85\x20\xbc\x4e\x6f"
+ "\x5f\xe9\x5b\x1f\xe3\xc8\x45\x2b",
+ }, {
+ .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ .psize = 112,
+ .digest = "\x09\x33\x0c\x33\xf7\x11\x47\xe8"
+ "\x3d\x19\x2f\xc7\x82\xcd\x1b\x47"
+ "\x53\x11\x1b\x17\x3b\x3b\x05\xd2"
+ "\x2f\xa0\x80\x86\xe3\xb0\xf7\x12"
+ "\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9"
+ "\x66\xc3\xe9\xfa\x91\x74\x60\x39",
+ }, {
+ .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+ "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+ .psize = 104,
+ .digest = "\x3d\x20\x89\x73\xab\x35\x08\xdb"
+ "\xbd\x7e\x2c\x28\x62\xba\x29\x0a"
+ "\xd3\x01\x0e\x49\x78\xc1\x98\xdc"
+ "\x4d\x8f\xd0\x14\xe5\x82\x82\x3a"
+ "\x89\xe1\x6f\x9b\x2a\x7b\xbc\x1a"
+ "\xc9\x38\xe2\xd1\x99\xe8\xbe\xa4",
+ .np = 4,
+ .tap = { 26, 26, 26, 26 }
+ },
+};
+
+/*
+ * SHA512 test vectors from from NIST and kerneli
+ */
+#define SHA512_TEST_VECTORS 4
+
+static struct hash_testvec sha512_tv_template[] = {
+ {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\xdd\xaf\x35\xa1\x93\x61\x7a\xba"
+ "\xcc\x41\x73\x49\xae\x20\x41\x31"
+ "\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2"
+ "\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a"
+ "\x21\x92\x99\x2a\x27\x4f\xc1\xa8"
+ "\x36\xba\x3c\x23\xa3\xfe\xeb\xbd"
+ "\x45\x4d\x44\x23\x64\x3c\xe8\x0e"
+ "\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .psize = 56,
+ .digest = "\x20\x4a\x8f\xc6\xdd\xa8\x2f\x0a"
+ "\x0c\xed\x7b\xeb\x8e\x08\xa4\x16"
+ "\x57\xc1\x6e\xf4\x68\xb2\x28\xa8"
+ "\x27\x9b\xe3\x31\xa7\x03\xc3\x35"
+ "\x96\xfd\x15\xc1\x3b\x1b\x07\xf9"
+ "\xaa\x1d\x3b\xea\x57\x78\x9c\xa0"
+ "\x31\xad\x85\xc7\xa7\x1d\xd7\x03"
+ "\x54\xec\x63\x12\x38\xca\x34\x45",
+ }, {
+ .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ .psize = 112,
+ .digest = "\x8e\x95\x9b\x75\xda\xe3\x13\xda"
+ "\x8c\xf4\xf7\x28\x14\xfc\x14\x3f"
+ "\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1"
+ "\x72\x99\xae\xad\xb6\x88\x90\x18"
+ "\x50\x1d\x28\x9e\x49\x00\xf7\xe4"
+ "\x33\x1b\x99\xde\xc4\xb5\x43\x3a"
+ "\xc7\xd3\x29\xee\xb6\xdd\x26\x54"
+ "\x5e\x96\xe5\x5b\x87\x4b\xe9\x09",
+ }, {
+ .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+ "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+ .psize = 104,
+ .digest = "\x93\x0d\x0c\xef\xcb\x30\xff\x11"
+ "\x33\xb6\x89\x81\x21\xf1\xcf\x3d"
+ "\x27\x57\x8a\xfc\xaf\xe8\x67\x7c"
+ "\x52\x57\xcf\x06\x99\x11\xf7\x5d"
+ "\x8f\x58\x31\xb5\x6e\xbf\xda\x67"
+ "\xb2\x78\xe6\x6d\xff\x8b\x84\xfe"
+ "\x2b\x28\x70\xf7\x42\xa5\x80\xd8"
+ "\xed\xb4\x19\x87\x23\x28\x50\xc9",
+ .np = 4,
+ .tap = { 26, 26, 26, 26 }
+ },
+};
+
+
+/*
+ * WHIRLPOOL test vectors from Whirlpool package
+ * by Vincent Rijmen and Paulo S. L. M. Barreto as part of the NESSIE
+ * submission
+ */
+#define WP512_TEST_VECTORS 8
+
+static struct hash_testvec wp512_tv_template[] = {
+ {
+ .plaintext = "",
+ .psize = 0,
+ .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
+ "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
+ "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
+ "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7"
+ "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB"
+ "\xCF\x88\xE3\xE0\x3C\x4F\x07\x57"
+ "\xEA\x89\x64\xE5\x9B\x63\xD9\x37"
+ "\x08\xB1\x38\xCC\x42\xA6\x6E\xB3",
+
+
+ }, {
+ .plaintext = "a",
+ .psize = 1,
+ .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
+ "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
+ "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
+ "\x73\xC4\x50\x01\xD0\x08\x7B\x42"
+ "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6"
+ "\x3A\x42\x39\x1A\x39\x14\x5A\x59"
+ "\x1A\x92\x20\x0D\x56\x01\x95\xE5"
+ "\x3B\x47\x85\x84\xFD\xAE\x23\x1A",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
+ "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
+ "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
+ "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C"
+ "\x71\x81\xEE\xBD\xB6\xC5\x7E\x27"
+ "\x7D\x0E\x34\x95\x71\x14\xCB\xD6"
+ "\xC7\x97\xFC\x9D\x95\xD8\xB5\x82"
+ "\xD2\x25\x29\x20\x76\xD4\xEE\xF5",
+ }, {
+ .plaintext = "message digest",
+ .psize = 14,
+ .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
+ "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
+ "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
+ "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B"
+ "\x84\x21\x55\x76\x59\xEF\x55\xC1"
+ "\x06\xB4\xB5\x2A\xC5\xA4\xAA\xA6"
+ "\x92\xED\x92\x00\x52\x83\x8F\x33"
+ "\x62\xE8\x6D\xBD\x37\xA8\x90\x3E",
+ }, {
+ .plaintext = "abcdefghijklmnopqrstuvwxyz",
+ .psize = 26,
+ .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
+ "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
+ "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
+ "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B"
+ "\x08\xBF\x2A\x92\x51\xC3\x0B\x6A"
+ "\x0B\x8A\xAE\x86\x17\x7A\xB4\xA6"
+ "\xF6\x8F\x67\x3E\x72\x07\x86\x5D"
+ "\x5D\x98\x19\xA3\xDB\xA4\xEB\x3B",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz0123456789",
+ .psize = 62,
+ .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
+ "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
+ "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
+ "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E"
+ "\x08\xEB\xA2\x66\x29\x12\x9D\x8F"
+ "\xB7\xCB\x57\x21\x1B\x92\x81\xA6"
+ "\x55\x17\xCC\x87\x9D\x7B\x96\x21"
+ "\x42\xC6\x5F\x5A\x7A\xF0\x14\x67",
+ }, {
+ .plaintext = "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890",
+ .psize = 80,
+ .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
+ "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
+ "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
+ "\x54\x9C\x4A\xFA\xDB\x60\x14\x29"
+ "\x4D\x5B\xD8\xDF\x2A\x6C\x44\xE5"
+ "\x38\xCD\x04\x7B\x26\x81\xA5\x1A"
+ "\x2C\x60\x48\x1E\x88\xC5\xA2\x0B"
+ "\x2C\x2A\x80\xCF\x3A\x9A\x08\x3B",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+ .psize = 32,
+ .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
+ "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
+ "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
+ "\x07\xC5\x62\xF9\x88\xE9\x5C\x69"
+ "\x16\xBD\xC8\x03\x1B\xC5\xBE\x1B"
+ "\x7B\x94\x76\x39\xFE\x05\x0B\x56"
+ "\x93\x9B\xAA\xA0\xAD\xFF\x9A\xE6"
+ "\x74\x5B\x7B\x18\x1C\x3B\xE3\xFD",
+ },
+};
+
+#define WP384_TEST_VECTORS 8
+
+static struct hash_testvec wp384_tv_template[] = {
+ {
+ .plaintext = "",
+ .psize = 0,
+ .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
+ "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
+ "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
+ "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7"
+ "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB"
+ "\xCF\x88\xE3\xE0\x3C\x4F\x07\x57",
+
+
+ }, {
+ .plaintext = "a",
+ .psize = 1,
+ .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
+ "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
+ "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
+ "\x73\xC4\x50\x01\xD0\x08\x7B\x42"
+ "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6"
+ "\x3A\x42\x39\x1A\x39\x14\x5A\x59",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
+ "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
+ "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
+ "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C"
+ "\x71\x81\xEE\xBD\xB6\xC5\x7E\x27"
+ "\x7D\x0E\x34\x95\x71\x14\xCB\xD6",
+ }, {
+ .plaintext = "message digest",
+ .psize = 14,
+ .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
+ "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
+ "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
+ "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B"
+ "\x84\x21\x55\x76\x59\xEF\x55\xC1"
+ "\x06\xB4\xB5\x2A\xC5\xA4\xAA\xA6",
+ }, {
+ .plaintext = "abcdefghijklmnopqrstuvwxyz",
+ .psize = 26,
+ .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
+ "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
+ "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
+ "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B"
+ "\x08\xBF\x2A\x92\x51\xC3\x0B\x6A"
+ "\x0B\x8A\xAE\x86\x17\x7A\xB4\xA6",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz0123456789",
+ .psize = 62,
+ .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
+ "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
+ "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
+ "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E"
+ "\x08\xEB\xA2\x66\x29\x12\x9D\x8F"
+ "\xB7\xCB\x57\x21\x1B\x92\x81\xA6",
+ }, {
+ .plaintext = "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890",
+ .psize = 80,
+ .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
+ "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
+ "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
+ "\x54\x9C\x4A\xFA\xDB\x60\x14\x29"
+ "\x4D\x5B\xD8\xDF\x2A\x6C\x44\xE5"
+ "\x38\xCD\x04\x7B\x26\x81\xA5\x1A",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+ .psize = 32,
+ .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
+ "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
+ "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
+ "\x07\xC5\x62\xF9\x88\xE9\x5C\x69"
+ "\x16\xBD\xC8\x03\x1B\xC5\xBE\x1B"
+ "\x7B\x94\x76\x39\xFE\x05\x0B\x56",
+ },
+};
+
+#define WP256_TEST_VECTORS 8
+
+static struct hash_testvec wp256_tv_template[] = {
+ {
+ .plaintext = "",
+ .psize = 0,
+ .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
+ "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
+ "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
+ "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7",
+
+
+ }, {
+ .plaintext = "a",
+ .psize = 1,
+ .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
+ "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
+ "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
+ "\x73\xC4\x50\x01\xD0\x08\x7B\x42",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
+ "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
+ "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
+ "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C",
+ }, {
+ .plaintext = "message digest",
+ .psize = 14,
+ .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
+ "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
+ "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
+ "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B",
+ }, {
+ .plaintext = "abcdefghijklmnopqrstuvwxyz",
+ .psize = 26,
+ .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
+ "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
+ "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
+ "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz0123456789",
+ .psize = 62,
+ .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
+ "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
+ "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
+ "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E",
+ }, {
+ .plaintext = "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890",
+ .psize = 80,
+ .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
+ "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
+ "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
+ "\x54\x9C\x4A\xFA\xDB\x60\x14\x29",
+ }, {
+ .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+ .psize = 32,
+ .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
+ "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
+ "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
+ "\x07\xC5\x62\xF9\x88\xE9\x5C\x69",
+ },
+};
+
+/*
+ * TIGER test vectors from Tiger website
+ */
+#define TGR192_TEST_VECTORS 6
+
+static struct hash_testvec tgr192_tv_template[] = {
+ {
+ .plaintext = "",
+ .psize = 0,
+ .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
+ "\x16\x16\x6e\x76\xb1\xbb\x92\x5f"
+ "\xf3\x73\xde\x2d\x49\x58\x4e\x7a",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
+ "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf"
+ "\x93\x5f\x7b\x95\x1c\x13\x29\x51",
+ }, {
+ .plaintext = "Tiger",
+ .psize = 5,
+ .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
+ "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec"
+ "\x37\x79\x0c\x11\x6f\x9d\x2b\xdf",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
+ .psize = 64,
+ .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
+ "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e"
+ "\xb5\x86\x44\x50\x34\xa5\xa3\x86",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
+ .psize = 64,
+ .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
+ "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9"
+ "\x57\x89\x65\x65\x97\x5f\x91\x97",
+ }, {
+ .plaintext = "Tiger - A Fast New Hash Function, "
+ "by Ross Anderson and Eli Biham, "
+ "proceedings of Fast Software Encryption 3, "
+ "Cambridge, 1996.",
+ .psize = 125,
+ .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
+ "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24"
+ "\xdd\x68\x15\x1d\x50\x39\x74\xfc",
+ },
+};
+
+#define TGR160_TEST_VECTORS 6
+
+static struct hash_testvec tgr160_tv_template[] = {
+ {
+ .plaintext = "",
+ .psize = 0,
+ .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
+ "\x16\x16\x6e\x76\xb1\xbb\x92\x5f"
+ "\xf3\x73\xde\x2d",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
+ "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf"
+ "\x93\x5f\x7b\x95",
+ }, {
+ .plaintext = "Tiger",
+ .psize = 5,
+ .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
+ "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec"
+ "\x37\x79\x0c\x11",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
+ .psize = 64,
+ .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
+ "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e"
+ "\xb5\x86\x44\x50",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
+ .psize = 64,
+ .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
+ "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9"
+ "\x57\x89\x65\x65",
+ }, {
+ .plaintext = "Tiger - A Fast New Hash Function, "
+ "by Ross Anderson and Eli Biham, "
+ "proceedings of Fast Software Encryption 3, "
+ "Cambridge, 1996.",
+ .psize = 125,
+ .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
+ "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24"
+ "\xdd\x68\x15\x1d",
+ },
+};
+
+#define TGR128_TEST_VECTORS 6
+
+static struct hash_testvec tgr128_tv_template[] = {
+ {
+ .plaintext = "",
+ .psize = 0,
+ .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
+ "\x16\x16\x6e\x76\xb1\xbb\x92\x5f",
+ }, {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
+ "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf",
+ }, {
+ .plaintext = "Tiger",
+ .psize = 5,
+ .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
+ "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
+ .psize = 64,
+ .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
+ "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e",
+ }, {
+ .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
+ .psize = 64,
+ .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
+ "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9",
+ }, {
+ .plaintext = "Tiger - A Fast New Hash Function, "
+ "by Ross Anderson and Eli Biham, "
+ "proceedings of Fast Software Encryption 3, "
+ "Cambridge, 1996.",
+ .psize = 125,
+ .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
+ "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24",
+ },
+};
+
+/*
+ * HMAC-MD5 test vectors from RFC2202
+ * (These need to be fixed to not use strlen).
+ */
+#ifndef CONFIG_CRYPTO_DEV_MD5_HMAC
+#define HMAC_MD5_TEST_VECTORS 7
+#else
+#define HMAC_MD5_TEST_VECTORS 5
+#endif
+
+static struct hash_testvec hmac_md5_tv_template[] =
+{
+ {
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .ksize = 16,
+ .plaintext = "Hi There",
+ .psize = 8,
+ .digest = "\x92\x94\x72\x7a\x36\x38\xbb\x1c"
+ "\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d",
+ }, {
+ .key = "Jefe",
+ .ksize = 4,
+ .plaintext = "what do ya want for nothing?",
+ .psize = 28,
+ .digest = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03"
+ "\xea\xa8\x6e\x31\x0a\x5d\xb7\x38",
+ .np = 2,
+ .tap = {14, 14}
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .ksize = 16,
+ .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+ .psize = 50,
+ .digest = "\x56\xbe\x34\x52\x1d\x14\x4c\x88"
+ "\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6",
+ }, {
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ .ksize = 25,
+ .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+ .psize = 50,
+ .digest = "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea"
+ "\x3a\x75\x16\x47\x46\xff\xaa\x79",
+ }, {
+ .key = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+ .ksize = 16,
+ .plaintext = "Test With Truncation",
+ .psize = 20,
+ .digest = "\x56\x46\x1e\xf2\x34\x2e\xdc\x00"
+ "\xf9\xba\xb9\x95\x69\x0e\xfd\x4c",
+#ifndef CONFIG_CRYPTO_DEV_MD5_HMAC
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa",
+ .ksize = 80,
+ .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .psize = 54,
+ .digest = "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f"
+ "\x0b\x62\xe6\xce\x61\xb9\xd0\xcd",
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa",
+ .ksize = 80,
+ .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+ "Block-Size Data",
+ .psize = 73,
+ .digest = "\x6f\x63\x0f\xad\x67\xcd\xa0\xee"
+ "\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e",
+#endif /* CONFIG_CRYPTO_DEV_MD5_HMAC */
+ },
+};
+
+/*
+ * HMAC-RIPEMD128 test vectors from RFC2286
+ */
+#define HMAC_RMD128_TEST_VECTORS 7
+
+static struct hash_testvec hmac_rmd128_tv_template[] = {
+ {
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .ksize = 16,
+ .plaintext = "Hi There",
+ .psize = 8,
+ .digest = "\xfb\xf6\x1f\x94\x92\xaa\x4b\xbf"
+ "\x81\xc1\x72\xe8\x4e\x07\x34\xdb",
+ }, {
+ .key = "Jefe",
+ .ksize = 4,
+ .plaintext = "what do ya want for nothing?",
+ .psize = 28,
+ .digest = "\x87\x5f\x82\x88\x62\xb6\xb3\x34"
+ "\xb4\x27\xc5\x5f\x9f\x7f\xf0\x9b",
+ .np = 2,
+ .tap = { 14, 14 },
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .ksize = 16,
+ .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+ .psize = 50,
+ .digest = "\x09\xf0\xb2\x84\x6d\x2f\x54\x3d"
+ "\xa3\x63\xcb\xec\x8d\x62\xa3\x8d",
+ }, {
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ .ksize = 25,
+ .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+ .psize = 50,
+ .digest = "\xbd\xbb\xd7\xcf\x03\xe4\x4b\x5a"
+ "\xa6\x0a\xf8\x15\xbe\x4d\x22\x94",
+ }, {
+ .key = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+ .ksize = 16,
+ .plaintext = "Test With Truncation",
+ .psize = 20,
+ .digest = "\xe7\x98\x08\xf2\x4b\x25\xfd\x03"
+ "\x1c\x15\x5f\x0d\x55\x1d\x9a\x3a",
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa",
+ .ksize = 80,
+ .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .psize = 54,
+ .digest = "\xdc\x73\x29\x28\xde\x98\x10\x4a"
+ "\x1f\x59\xd3\x73\xc1\x50\xac\xbb",
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa",
+ .ksize = 80,
+ .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+ "Block-Size Data",
+ .psize = 73,
+ .digest = "\x5c\x6b\xec\x96\x79\x3e\x16\xd4"
+ "\x06\x90\xc2\x37\x63\x5f\x30\xc5",
+ },
+};
+
+/*
+ * HMAC-RIPEMD160 test vectors from RFC2286
+ */
+#define HMAC_RMD160_TEST_VECTORS 7
+
+static struct hash_testvec hmac_rmd160_tv_template[] = {
+ {
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .ksize = 20,
+ .plaintext = "Hi There",
+ .psize = 8,
+ .digest = "\x24\xcb\x4b\xd6\x7d\x20\xfc\x1a\x5d\x2e"
+ "\xd7\x73\x2d\xcc\x39\x37\x7f\x0a\x56\x68",
+ }, {
+ .key = "Jefe",
+ .ksize = 4,
+ .plaintext = "what do ya want for nothing?",
+ .psize = 28,
+ .digest = "\xdd\xa6\xc0\x21\x3a\x48\x5a\x9e\x24\xf4"
+ "\x74\x20\x64\xa7\xf0\x33\xb4\x3c\x40\x69",
+ .np = 2,
+ .tap = { 14, 14 },
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .ksize = 20,
+ .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+ .psize = 50,
+ .digest = "\xb0\xb1\x05\x36\x0d\xe7\x59\x96\x0a\xb4"
+ "\xf3\x52\x98\xe1\x16\xe2\x95\xd8\xe7\xc1",
+ }, {
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ .ksize = 25,
+ .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+ .psize = 50,
+ .digest = "\xd5\xca\x86\x2f\x4d\x21\xd5\xe6\x10\xe1"
+ "\x8b\x4c\xf1\xbe\xb9\x7a\x43\x65\xec\xf4",
+ }, {
+ .key = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+ .ksize = 20,
+ .plaintext = "Test With Truncation",
+ .psize = 20,
+ .digest = "\x76\x19\x69\x39\x78\xf9\x1d\x90\x53\x9a"
+ "\xe7\x86\x50\x0f\xf3\xd8\xe0\x51\x8e\x39",
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa",
+ .ksize = 80,
+ .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .psize = 54,
+ .digest = "\x64\x66\xca\x07\xac\x5e\xac\x29\xe1\xbd"
+ "\x52\x3e\x5a\xda\x76\x05\xb7\x91\xfd\x8b",
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa",
+ .ksize = 80,
+ .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+ "Block-Size Data",
+ .psize = 73,
+ .digest = "\x69\xea\x60\x79\x8d\x71\x61\x6c\xce\x5f"
+ "\xd0\x87\x1e\x23\x75\x4c\xd7\x5d\x5a\x0a",
+ },
+};
+
+/*
+ * HMAC-SHA1 test vectors from RFC2202
+ */
+#ifndef CONFIG_CRYPTO_DEV_SHA1_HMAC
+#define HMAC_SHA1_TEST_VECTORS 7
+#else
+#define HMAC_SHA1_TEST_VECTORS 5
+#endif
+
+static struct hash_testvec hmac_sha1_tv_template[] = {
+ {
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .ksize = 20,
+ .plaintext = "Hi There",
+ .psize = 8,
+ .digest = "\xb6\x17\x31\x86\x55\x05\x72\x64"
+ "\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1"
+ "\x46\xbe",
+ }, {
+ .key = "Jefe",
+ .ksize = 4,
+ .plaintext = "what do ya want for nothing?",
+ .psize = 28,
+ .digest = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74"
+ "\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79",
+ .np = 2,
+ .tap = { 14, 14 }
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .ksize = 20,
+ .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+ .psize = 50,
+ .digest = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3"
+ "\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3",
+ }, {
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ .ksize = 25,
+ .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+ .psize = 50,
+ .digest = "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84"
+ "\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda",
+ }, {
+ .key = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+ .ksize = 20,
+ .plaintext = "Test With Truncation",
+ .psize = 20,
+ .digest = "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2"
+ "\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04",
+
+#ifndef CONFIG_CRYPTO_DEV_SHA1_HMAC
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa",
+ .ksize = 80,
+ .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .psize = 54,
+ .digest = "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70"
+ "\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12",
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa",
+ .ksize = 80,
+ .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+ "Block-Size Data",
+ .psize = 73,
+ .digest = "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b"
+ "\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91",
+#endif
+ },
+};
+
+
+/*
+ * SHA224 HMAC test vectors from RFC4231
+ */
+#define HMAC_SHA224_TEST_VECTORS 4
+
+static struct hash_testvec hmac_sha224_tv_template[] = {
+ {
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ .ksize = 20,
+ /* ("Hi There") */
+ .plaintext = "\x48\x69\x20\x54\x68\x65\x72\x65",
+ .psize = 8,
+ .digest = "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19"
+ "\x68\x32\x10\x7c\xd4\x9d\xf3\x3f"
+ "\x47\xb4\xb1\x16\x99\x12\xba\x4f"
+ "\x53\x68\x4b\x22",
+ }, {
+ .key = "Jefe",
+ .ksize = 4,
+ /* ("what do ya want for nothing?") */
+ .plaintext = "\x77\x68\x61\x74\x20\x64\x6f\x20"
+ "\x79\x61\x20\x77\x61\x6e\x74\x20"
+ "\x66\x6f\x72\x20\x6e\x6f\x74\x68"
+ "\x69\x6e\x67\x3f",
+ .psize = 28,
+ .digest = "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf"
+ "\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f"
+ "\x8b\xbe\xa2\xa3\x9e\x61\x48\x00"
+ "\x8f\xd0\x5e\x44",
+ .np = 4,
+ .tap = { 7, 7, 7, 7 }
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .ksize = 131,
+ /* ("Test Using Larger Than Block-Size Key - Hash Key First") */
+ .plaintext = "\x54\x65\x73\x74\x20\x55\x73\x69"
+ "\x6e\x67\x20\x4c\x61\x72\x67\x65"
+ "\x72\x20\x54\x68\x61\x6e\x20\x42"
+ "\x6c\x6f\x63\x6b\x2d\x53\x69\x7a"
+ "\x65\x20\x4b\x65\x79\x20\x2d\x20"
+ "\x48\x61\x73\x68\x20\x4b\x65\x79"
+ "\x20\x46\x69\x72\x73\x74",
+ .psize = 54,
+ .digest = "\x95\xe9\xa0\xdb\x96\x20\x95\xad"
+ "\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2"
+ "\xd4\x99\xf1\x12\xf2\xd2\xb7\x27"
+ "\x3f\xa6\x87\x0e",
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .ksize = 131,
+ /* ("This is a test using a larger than block-size key and a")
+ (" larger than block-size data. The key needs to be")
+ (" hashed before being used by the HMAC algorithm.") */
+ .plaintext = "\x54\x68\x69\x73\x20\x69\x73\x20"
+ "\x61\x20\x74\x65\x73\x74\x20\x75"
+ "\x73\x69\x6e\x67\x20\x61\x20\x6c"
+ "\x61\x72\x67\x65\x72\x20\x74\x68"
+ "\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
+ "\x2d\x73\x69\x7a\x65\x20\x6b\x65"
+ "\x79\x20\x61\x6e\x64\x20\x61\x20"
+ "\x6c\x61\x72\x67\x65\x72\x20\x74"
+ "\x68\x61\x6e\x20\x62\x6c\x6f\x63"
+ "\x6b\x2d\x73\x69\x7a\x65\x20\x64"
+ "\x61\x74\x61\x2e\x20\x54\x68\x65"
+ "\x20\x6b\x65\x79\x20\x6e\x65\x65"
+ "\x64\x73\x20\x74\x6f\x20\x62\x65"
+ "\x20\x68\x61\x73\x68\x65\x64\x20"
+ "\x62\x65\x66\x6f\x72\x65\x20\x62"
+ "\x65\x69\x6e\x67\x20\x75\x73\x65"
+ "\x64\x20\x62\x79\x20\x74\x68\x65"
+ "\x20\x48\x4d\x41\x43\x20\x61\x6c"
+ "\x67\x6f\x72\x69\x74\x68\x6d\x2e",
+ .psize = 152,
+ .digest = "\x3a\x85\x41\x66\xac\x5d\x9f\x02"
+ "\x3f\x54\xd5\x17\xd0\xb3\x9d\xbd"
+ "\x94\x67\x70\xdb\x9c\x2b\x95\xc9"
+ "\xf6\xf5\x65\xd1",
+ },
+};
+
+/*
+ * HMAC-SHA256 test vectors from
+ * draft-ietf-ipsec-ciph-sha-256-01.txt
+ */
+#define HMAC_SHA256_TEST_VECTORS 10
+
+static struct hash_testvec hmac_sha256_tv_template[] = {
+ {
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18"
+ "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
+ .ksize = 32,
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = "\xa2\x1b\x1f\x5d\x4c\xf4\xf7\x3a"
+ "\x4d\xd9\x39\x75\x0f\x7a\x06\x6a"
+ "\x7f\x98\xcc\x13\x1c\xb1\x6a\x66"
+ "\x92\x75\x90\x21\xcf\xab\x81\x81",
+ }, {
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18"
+ "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
+ .ksize = 32,
+ .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .psize = 56,
+ .digest = "\x10\x4f\xdc\x12\x57\x32\x8f\x08"
+ "\x18\x4b\xa7\x31\x31\xc5\x3c\xae"
+ "\xe6\x98\xe3\x61\x19\x42\x11\x49"
+ "\xea\x8c\x71\x24\x56\x69\x7d\x30",
+ }, {
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18"
+ "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
+ .ksize = 32,
+ .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .psize = 112,
+ .digest = "\x47\x03\x05\xfc\x7e\x40\xfe\x34"
+ "\xd3\xee\xb3\xe7\x73\xd9\x5a\xab"
+ "\x73\xac\xf0\xfd\x06\x04\x47\xa5"
+ "\xeb\x45\x95\xbf\x33\xa9\xd1\xa3",
+ }, {
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b",
+ .ksize = 32,
+ .plaintext = "Hi There",
+ .psize = 8,
+ .digest = "\x19\x8a\x60\x7e\xb4\x4b\xfb\xc6"
+ "\x99\x03\xa0\xf1\xcf\x2b\xbd\xc5"
+ "\xba\x0a\xa3\xf3\xd9\xae\x3c\x1c"
+ "\x7a\x3b\x16\x96\xa0\xb6\x8c\xf7",
+ }, {
+ .key = "Jefe",
+ .ksize = 4,
+ .plaintext = "what do ya want for nothing?",
+ .psize = 28,
+ .digest = "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e"
+ "\x6a\x04\x24\x26\x08\x95\x75\xc7"
+ "\x5a\x00\x3f\x08\x9d\x27\x39\x83"
+ "\x9d\xec\x58\xb9\x64\xec\x38\x43",
+ .np = 2,
+ .tap = { 14, 14 }
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .ksize = 32,
+ .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+ .psize = 50,
+ .digest = "\xcd\xcb\x12\x20\xd1\xec\xcc\xea"
+ "\x91\xe5\x3a\xba\x30\x92\xf9\x62"
+ "\xe5\x49\xfe\x6c\xe9\xed\x7f\xdc"
+ "\x43\x19\x1f\xbd\xe4\x5c\x30\xb0",
+ }, {
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18"
+ "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+ "\x21\x22\x23\x24\x25",
+ .ksize = 37,
+ .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+ .psize = 50,
+ .digest = "\xd4\x63\x3c\x17\xf6\xfb\x8d\x74"
+ "\x4c\x66\xde\xe0\xf8\xf0\x74\x55"
+ "\x6e\xc4\xaf\x55\xef\x07\x99\x85"
+ "\x41\x46\x8e\xb4\x9b\xd2\xe9\x17",
+ }, {
+ .key = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c",
+ .ksize = 32,
+ .plaintext = "Test With Truncation",
+ .psize = 20,
+ .digest = "\x75\x46\xaf\x01\x84\x1f\xc0\x9b"
+ "\x1a\xb9\xc3\x74\x9a\x5f\x1c\x17"
+ "\xd4\xf5\x89\x66\x8a\x58\x7b\x27"
+ "\x00\xa9\xc9\x7c\x11\x93\xcf\x42",
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa",
+ .ksize = 80,
+ .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .psize = 54,
+ .digest = "\x69\x53\x02\x5e\xd9\x6f\x0c\x09"
+ "\xf8\x0a\x96\xf7\x8e\x65\x38\xdb"
+ "\xe2\xe7\xb8\x20\xe3\xdd\x97\x0e"
+ "\x7d\xdd\x39\x09\x1b\x32\x35\x2f",
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa",
+ .ksize = 80,
+ .plaintext = "Test Using Larger Than Block-Size Key and Larger Than "
+ "One Block-Size Data",
+ .psize = 73,
+ .digest = "\x63\x55\xac\x22\xe8\x90\xd0\xa3"
+ "\xc8\x48\x1a\x5c\xa4\x82\x5b\xc8"
+ "\x84\xd3\xe7\xa1\xff\x98\xa2\xfc"
+ "\x2a\xc7\xd8\xe0\x64\xc3\xb2\xe6",
+ },
+};
+
+#define XCBC_AES_TEST_VECTORS 6
+
+static struct hash_testvec aes_xcbc128_tv_template[] = {
+ {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .plaintext = zeroed_string,
+ .digest = "\x75\xf0\x25\x1d\x52\x8a\xc0\x1c"
+ "\x45\x73\xdf\xd5\x84\xd7\x9f\x29",
+ .psize = 0,
+ .ksize = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .plaintext = "\x00\x01\x02",
+ .digest = "\x5b\x37\x65\x80\xae\x2f\x19\xaf"
+ "\xe7\x21\x9c\xee\xf1\x72\x75\x6f",
+ .psize = 3,
+ .ksize = 16,
+ } , {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .digest = "\xd2\xa2\x46\xfa\x34\x9b\x68\xa7"
+ "\x99\x98\xa4\x39\x4f\xf7\xa2\x63",
+ .psize = 16,
+ .ksize = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13",
+ .digest = "\x47\xf5\x1b\x45\x64\x96\x62\x15"
+ "\xb8\x98\x5c\x63\x05\x5e\xd3\x08",
+ .tap = { 10, 10 },
+ .psize = 20,
+ .np = 2,
+ .ksize = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .digest = "\xf5\x4f\x0e\xc8\xd2\xb9\xf3\xd3"
+ "\x68\x07\x73\x4b\xd5\x28\x3f\xd4",
+ .psize = 32,
+ .ksize = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21",
+ .digest = "\xbe\xcb\xb3\xbc\xcd\xb5\x18\xa3"
+ "\x06\x77\xd5\x48\x1f\xb6\xb4\xd8",
+ .tap = { 17, 17 },
+ .psize = 34,
+ .np = 2,
+ .ksize = 16,
+ }
+};
+
+#define VMAC_AES_TEST_VECTORS 1
+static char vmac_string[128] = {'\x01', '\x01', '\x01', '\x01',
+ '\x02', '\x03', '\x02', '\x02',
+ '\x02', '\x04', '\x01', '\x07',
+ '\x04', '\x01', '\x04', '\x03',};
+static struct hash_testvec aes_vmac128_tv_template[] = {
+ {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .plaintext = vmac_string,
+ .digest = "\xcb\xd7\x8a\xfd\xb7\x33\x79\xe7",
+ .psize = 128,
+ .ksize = 16,
+ },
+};
+
+/*
+ * SHA384 HMAC test vectors from RFC4231
+ */
+
+#define HMAC_SHA384_TEST_VECTORS 4
+
+static struct hash_testvec hmac_sha384_tv_template[] = {
+ {
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ .ksize = 20,
+ .plaintext = "Hi There",
+ .psize = 8,
+ .digest = "\xaf\xd0\x39\x44\xd8\x48\x95\x62"
+ "\x6b\x08\x25\xf4\xab\x46\x90\x7f"
+ "\x15\xf9\xda\xdb\xe4\x10\x1e\xc6"
+ "\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c"
+ "\xfa\xea\x9e\xa9\x07\x6e\xde\x7f"
+ "\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6",
+ }, {
+ .key = "Jefe",
+ .ksize = 4,
+ .plaintext = "what do ya want for nothing?",
+ .psize = 28,
+ .digest = "\xaf\x45\xd2\xe3\x76\x48\x40\x31"
+ "\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b"
+ "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47"
+ "\xe4\x2e\xc3\x73\x63\x22\x44\x5e"
+ "\x8e\x22\x40\xca\x5e\x69\xe2\xc7"
+ "\x8b\x32\x39\xec\xfa\xb2\x16\x49",
+ .np = 4,
+ .tap = { 7, 7, 7, 7 }
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .ksize = 131,
+ .plaintext = "Test Using Larger Than Block-Siz"
+ "e Key - Hash Key First",
+ .psize = 54,
+ .digest = "\x4e\xce\x08\x44\x85\x81\x3e\x90"
+ "\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4"
+ "\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f"
+ "\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6"
+ "\x0c\x2e\xf6\xab\x40\x30\xfe\x82"
+ "\x96\x24\x8d\xf1\x63\xf4\x49\x52",
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .ksize = 131,
+ .plaintext = "This is a test u"
+ "sing a larger th"
+ "an block-size ke"
+ "y and a larger t"
+ "han block-size d"
+ "ata. The key nee"
+ "ds to be hashed "
+ "before being use"
+ "d by the HMAC al"
+ "gorithm.",
+ .psize = 152,
+ .digest = "\x66\x17\x17\x8e\x94\x1f\x02\x0d"
+ "\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c"
+ "\x60\x24\x20\xfe\xb0\xb8\xfb\x9a"
+ "\xdc\xce\xbb\x82\x46\x1e\x99\xc5"
+ "\xa6\x78\xcc\x31\xe7\x99\x17\x6d"
+ "\x38\x60\xe6\x11\x0c\x46\x52\x3e",
+ },
+};
+
+/*
+ * SHA512 HMAC test vectors from RFC4231
+ */
+
+#define HMAC_SHA512_TEST_VECTORS 4
+
+static struct hash_testvec hmac_sha512_tv_template[] = {
+ {
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ .ksize = 20,
+ .plaintext = "Hi There",
+ .psize = 8,
+ .digest = "\x87\xaa\x7c\xde\xa5\xef\x61\x9d"
+ "\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0"
+ "\x23\x79\xf4\xe2\xce\x4e\xc2\x78"
+ "\x7a\xd0\xb3\x05\x45\xe1\x7c\xde"
+ "\xda\xa8\x33\xb7\xd6\xb8\xa7\x02"
+ "\x03\x8b\x27\x4e\xae\xa3\xf4\xe4"
+ "\xbe\x9d\x91\x4e\xeb\x61\xf1\x70"
+ "\x2e\x69\x6c\x20\x3a\x12\x68\x54",
+ }, {
+ .key = "Jefe",
+ .ksize = 4,
+ .plaintext = "what do ya want for nothing?",
+ .psize = 28,
+ .digest = "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2"
+ "\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3"
+ "\x87\xbd\x64\x22\x2e\x83\x1f\xd6"
+ "\x10\x27\x0c\xd7\xea\x25\x05\x54"
+ "\x97\x58\xbf\x75\xc0\x5a\x99\x4a"
+ "\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd"
+ "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b"
+ "\x63\x6e\x07\x0a\x38\xbc\xe7\x37",
+ .np = 4,
+ .tap = { 7, 7, 7, 7 }
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .ksize = 131,
+ .plaintext = "Test Using Large"
+ "r Than Block-Siz"
+ "e Key - Hash Key"
+ " First",
+ .psize = 54,
+ .digest = "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb"
+ "\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4"
+ "\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1"
+ "\x12\x1b\x01\x37\x83\xf8\xf3\x52"
+ "\x6b\x56\xd0\x37\xe0\x5f\x25\x98"
+ "\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52"
+ "\x95\xe6\x4f\x73\xf6\x3f\x0a\xec"
+ "\x8b\x91\x5a\x98\x5d\x78\x65\x98",
+ }, {
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .ksize = 131,
+ .plaintext =
+ "This is a test u"
+ "sing a larger th"
+ "an block-size ke"
+ "y and a larger t"
+ "han block-size d"
+ "ata. The key nee"
+ "ds to be hashed "
+ "before being use"
+ "d by the HMAC al"
+ "gorithm.",
+ .psize = 152,
+ .digest = "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba"
+ "\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd"
+ "\xde\xbd\x71\xf8\x86\x72\x89\x86"
+ "\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44"
+ "\xb6\x02\x2c\xac\x3c\x49\x82\xb1"
+ "\x0d\x5e\xeb\x55\xc3\xe4\xde\x15"
+ "\x13\x46\x76\xfb\x6d\xe0\x44\x60"
+ "\x65\xc9\x74\x40\xfa\x8c\x6a\x58",
+ },
+};
+
+/*
+ * DES test vectors.
+ */
+#if defined(CONFIG_CRYPTO_DEV_DES) || defined (CONFIG_CRYPTO_ASYNC_DES)
+#define DES_ENC_TEST_VECTORS 5
+#define DES_DEC_TEST_VECTORS 3
+#define DES_CBC_ENC_TEST_VECTORS 4
+#define DES_CBC_DEC_TEST_VECTORS 3
+#define DES3_EDE_ENC_TEST_VECTORS 3
+#define DES3_EDE_DEC_TEST_VECTORS 3
+#define DES3_EDE_CBC_ENC_TEST_VECTORS 1
+#define DES3_EDE_CBC_DEC_TEST_VECTORS 1
+#else
+#define DES_ENC_TEST_VECTORS 10
+#define DES_DEC_TEST_VECTORS 4
+#define DES_CBC_ENC_TEST_VECTORS 5
+#define DES_CBC_DEC_TEST_VECTORS 4
+#define DES3_EDE_ENC_TEST_VECTORS 3
+#define DES3_EDE_DEC_TEST_VECTORS 3
+#define DES3_EDE_CBC_ENC_TEST_VECTORS 1
+#define DES3_EDE_CBC_DEC_TEST_VECTORS 1
+#endif /*CONFIG_CRYPTO_DEV_DES*/
+
+static struct cipher_testvec des_enc_tv_template[] = {
+ { /* From Applied Cryptography */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+ .ilen = 8,
+ .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+ .rlen = 8,
+ }, { /* Same key, different plaintext block */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x22\x33\x44\x55\x66\x77\x88\x99",
+ .ilen = 8,
+ .result = "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+ .rlen = 8,
+ }, { /* Sbox test from NBS */
+ .key = "\x7c\xa1\x10\x45\x4a\x1a\x6e\x57",
+ .klen = 8,
+ .input = "\x01\xa1\xd6\xd0\x39\x77\x67\x42",
+ .ilen = 8,
+ .result = "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+ .rlen = 8,
+ }, { /* Three blocks */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+ "\x22\x33\x44\x55\x66\x77\x88\x99"
+ "\xca\xfe\xba\xbe\xfe\xed\xbe\xef",
+ .ilen = 24,
+ .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+ "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
+ "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90",
+ .rlen = 24,
+//#if !defined(CONFIG_CRYPTO_DEV_DES) && !defined(CONFIG_CRYPTO_ASYNC_DES)
+#if 0
+ }, { /* Weak key */
+ .fail = 1,
+ .wk = 1,
+ .key = "\x01\x01\x01\x01\x01\x01\x01\x01",
+ .klen = 8,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+ .ilen = 8,
+ .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+ .rlen = 8,
+#endif
+ }, { /* Two blocks -- for testing encryption across pages */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+ "\x22\x33\x44\x55\x66\x77\x88\x99",
+ .ilen = 16,
+ .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+ "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+ .rlen = 16,
+ .np = 2,
+ .tap = { 8, 8 }
+//#if !defined(CONFIG_CRYPTO_DEV_DES) && !defined(CONFIG_CRYPTO_ASYNC_DES)
+#if 0
+ }, { /* Four blocks -- for testing encryption with chunking */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+ "\x22\x33\x44\x55\x66\x77\x88\x99"
+ "\xca\xfe\xba\xbe\xfe\xed\xbe\xef"
+ "\x22\x33\x44\x55\x66\x77\x88\x99",
+ .ilen = 32,
+ .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+ "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
+ "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90"
+ "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+ .rlen = 32,
+ .np = 3,
+ .tap = { 14, 10, 8 }
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+ "\x22\x33\x44\x55\x66\x77\x88\x99"
+ "\xca\xfe\xba\xbe\xfe\xed\xbe\xef",
+ .ilen = 24,
+ .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+ "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
+ "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90",
+ .rlen = 24,
+ .np = 4,
+ .tap = { 2, 1, 3, 18 }
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+ "\x22\x33\x44\x55\x66\x77\x88\x99",
+ .ilen = 16,
+ .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+ "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+ .rlen = 16,
+ .np = 5,
+ .tap = { 2, 2, 2, 2, 8 }
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+ .ilen = 8,
+ .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+ .rlen = 8,
+ .np = 8,
+ .tap = { 1, 1, 1, 1, 1, 1, 1, 1 }
+#endif
+ },
+};
+
+static struct cipher_testvec des_dec_tv_template[] = {
+ { /* From Applied Cryptography */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+ .ilen = 8,
+ .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+ .rlen = 8,
+ }, { /* Sbox test from NBS */
+ .key = "\x7c\xa1\x10\x45\x4a\x1a\x6e\x57",
+ .klen = 8,
+ .input = "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+ .ilen = 8,
+ .result = "\x01\xa1\xd6\xd0\x39\x77\x67\x42",
+ .rlen = 8,
+ }, { /* Two blocks, for chunking test */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+ "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+ .ilen = 16,
+ .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+ "\xa3\x99\x7b\xca\xaf\x69\xa0\xf5",
+ .rlen = 16,
+ .np = 2,
+ .tap = { 8, 8 }
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+ "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+ .ilen = 16,
+ .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+ "\xa3\x99\x7b\xca\xaf\x69\xa0\xf5",
+ .rlen = 16,
+ .np = 3,
+ .tap = { 3, 12, 1 }
+ },
+};
+
+static struct cipher_testvec des_cbc_enc_tv_template[] = {
+ { /* From OpenSSL */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .iv = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .input = "\x37\x36\x35\x34\x33\x32\x31\x20"
+ "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+ "\x68\x65\x20\x74\x69\x6d\x65\x20",
+ .ilen = 24,
+ .result = "\xcc\xd1\x73\xff\xab\x20\x39\xf4"
+ "\xac\xd8\xae\xfd\xdf\xd8\xa1\xeb"
+ "\x46\x8e\x91\x15\x78\x88\xba\x68",
+ .rlen = 24,
+ }, { /* FIPS Pub 81 */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .iv = "\x12\x34\x56\x78\x90\xab\xcd\xef",
+ .input = "\x4e\x6f\x77\x20\x69\x73\x20\x74",
+ .ilen = 8,
+ .result = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+ .rlen = 8,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .iv = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+ .input = "\x68\x65\x20\x74\x69\x6d\x65\x20",
+ .ilen = 8,
+ .result = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+ .rlen = 8,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .iv = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+ .input = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
+ .ilen = 8,
+ .result = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
+ .rlen = 8,
+#if 0
+ }, { /* Copy of openssl vector for chunk testing */
+ /* From OpenSSL */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .iv = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .input = "\x37\x36\x35\x34\x33\x32\x31\x20"
+ "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+ "\x68\x65\x20\x74\x69\x6d\x65\x20",
+ .ilen = 24,
+ .result = "\xcc\xd1\x73\xff\xab\x20\x39\xf4"
+ "\xac\xd8\xae\xfd\xdf\xd8\xa1\xeb"
+ "\x46\x8e\x91\x15\x78\x88\xba\x68",
+ .rlen = 24,
+ .np = 2,
+ .tap = { 13, 11 }
+#endif
+ },
+};
+
+static struct cipher_testvec des_cbc_dec_tv_template[] = {
+ { /* FIPS Pub 81 */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .iv = "\x12\x34\x56\x78\x90\xab\xcd\xef",
+ .input = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+ .ilen = 8,
+ .result = "\x4e\x6f\x77\x20\x69\x73\x20\x74",
+ .rlen = 8,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .iv = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+ .input = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+ .ilen = 8,
+ .result = "\x68\x65\x20\x74\x69\x6d\x65\x20",
+ .rlen = 8,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .iv = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+ .input = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
+ .ilen = 8,
+ .result = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
+ .rlen = 8,
+ }, { /* Copy of above, for chunk testing */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .iv = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+ .input = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
+ .ilen = 8,
+ .result = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
+ .rlen = 8,
+ .np = 2,
+ .tap = { 4, 4 }
+ },
+};
+
+static struct cipher_testvec des3_ede_enc_tv_template[] = {
+ { /* These are from openssl */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\x55\x55\x55\x55\x55\x55\x55\x55"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .klen = 24,
+ .input = "\x73\x6f\x6d\x65\x64\x61\x74\x61",
+ .ilen = 8,
+ .result = "\x18\xd7\x48\xe5\x63\x62\x05\x72",
+ .rlen = 8,
+ }, {
+ .key = "\x03\x52\x02\x07\x67\x20\x82\x17"
+ "\x86\x02\x87\x66\x59\x08\x21\x98"
+ "\x64\x05\x6a\xbd\xfe\xa9\x34\x57",
+ .klen = 24,
+ .input = "\x73\x71\x75\x69\x67\x67\x6c\x65",
+ .ilen = 8,
+ .result = "\xc0\x7d\x2a\x0f\xa5\x66\xfa\x30",
+ .rlen = 8,
+ }, {
+ .key = "\x10\x46\x10\x34\x89\x98\x80\x20"
+ "\x91\x07\xd0\x15\x89\x19\x01\x01"
+ "\x19\x07\x92\x10\x98\x1a\x01\x01",
+ .klen = 24,
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 8,
+ .result = "\xe1\xef\x62\xc3\x32\xfe\x82\x5b",
+ .rlen = 8,
+ },
+};
+
+static struct cipher_testvec des3_ede_dec_tv_template[] = {
+ { /* These are from openssl */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\x55\x55\x55\x55\x55\x55\x55\x55"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .klen = 24,
+ .input = "\x18\xd7\x48\xe5\x63\x62\x05\x72",
+ .ilen = 8,
+ .result = "\x73\x6f\x6d\x65\x64\x61\x74\x61",
+ .rlen = 8,
+ }, {
+ .key = "\x03\x52\x02\x07\x67\x20\x82\x17"
+ "\x86\x02\x87\x66\x59\x08\x21\x98"
+ "\x64\x05\x6a\xbd\xfe\xa9\x34\x57",
+ .klen = 24,
+ .input = "\xc0\x7d\x2a\x0f\xa5\x66\xfa\x30",
+ .ilen = 8,
+ .result = "\x73\x71\x75\x69\x67\x67\x6c\x65",
+ .rlen = 8,
+ }, {
+ .key = "\x10\x46\x10\x34\x89\x98\x80\x20"
+ "\x91\x07\xd0\x15\x89\x19\x01\x01"
+ "\x19\x07\x92\x10\x98\x1a\x01\x01",
+ .klen = 24,
+ .input = "\xe1\xef\x62\xc3\x32\xfe\x82\x5b",
+ .ilen = 8,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .rlen = 8,
+ },
+};
+
+static struct cipher_testvec des3_ede_cbc_enc_tv_template[] = {
+ { /* Generated from openssl */
+ .key = "\xE9\xC0\xFF\x2E\x76\x0B\x64\x24"
+ "\x44\x4D\x99\x5A\x12\xD6\x40\xC0"
+ "\xEA\xC2\x84\xE8\x14\x95\xDB\xE8",
+ .klen = 24,
+ .iv = "\x7D\x33\x88\x93\x0F\x93\xB2\x42",
+ .input = "\x6f\x54\x20\x6f\x61\x4d\x79\x6e"
+ "\x53\x20\x63\x65\x65\x72\x73\x74"
+ "\x54\x20\x6f\x6f\x4d\x20\x6e\x61"
+ "\x20\x79\x65\x53\x72\x63\x74\x65"
+ "\x20\x73\x6f\x54\x20\x6f\x61\x4d"
+ "\x79\x6e\x53\x20\x63\x65\x65\x72"
+ "\x73\x74\x54\x20\x6f\x6f\x4d\x20"
+ "\x6e\x61\x20\x79\x65\x53\x72\x63"
+ "\x74\x65\x20\x73\x6f\x54\x20\x6f"
+ "\x61\x4d\x79\x6e\x53\x20\x63\x65"
+ "\x65\x72\x73\x74\x54\x20\x6f\x6f"
+ "\x4d\x20\x6e\x61\x20\x79\x65\x53"
+ "\x72\x63\x74\x65\x20\x73\x6f\x54"
+ "\x20\x6f\x61\x4d\x79\x6e\x53\x20"
+ "\x63\x65\x65\x72\x73\x74\x54\x20"
+ "\x6f\x6f\x4d\x20\x6e\x61\x0a\x79",
+ .ilen = 128,
+ .result = "\x0e\x2d\xb6\x97\x3c\x56\x33\xf4"
+ "\x67\x17\x21\xc7\x6e\x8a\xd5\x49"
+ "\x74\xb3\x49\x05\xc5\x1c\xd0\xed"
+ "\x12\x56\x5c\x53\x96\xb6\x00\x7d"
+ "\x90\x48\xfc\xf5\x8d\x29\x39\xcc"
+ "\x8a\xd5\x35\x18\x36\x23\x4e\xd7"
+ "\x76\xd1\xda\x0c\x94\x67\xbb\x04"
+ "\x8b\xf2\x03\x6c\xa8\xcf\xb6\xea"
+ "\x22\x64\x47\xaa\x8f\x75\x13\xbf"
+ "\x9f\xc2\xc3\xf0\xc9\x56\xc5\x7a"
+ "\x71\x63\x2e\x89\x7b\x1e\x12\xca"
+ "\xe2\x5f\xaf\xd8\xa4\xf8\xc9\x7a"
+ "\xd6\xf9\x21\x31\x62\x44\x45\xa6"
+ "\xd6\xbc\x5a\xd3\x2d\x54\x43\xcc"
+ "\x9d\xde\xa5\x70\xe9\x42\x45\x8a"
+ "\x6b\xfa\xb1\x91\x13\xb0\xd9\x19",
+ .rlen = 128,
+ },
+};
+
+static struct cipher_testvec des3_ede_cbc_dec_tv_template[] = {
+ { /* Generated from openssl */
+ .key = "\xE9\xC0\xFF\x2E\x76\x0B\x64\x24"
+ "\x44\x4D\x99\x5A\x12\xD6\x40\xC0"
+ "\xEA\xC2\x84\xE8\x14\x95\xDB\xE8",
+ .klen = 24,
+ .iv = "\x7D\x33\x88\x93\x0F\x93\xB2\x42",
+ .input = "\x0e\x2d\xb6\x97\x3c\x56\x33\xf4"
+ "\x67\x17\x21\xc7\x6e\x8a\xd5\x49"
+ "\x74\xb3\x49\x05\xc5\x1c\xd0\xed"
+ "\x12\x56\x5c\x53\x96\xb6\x00\x7d"
+ "\x90\x48\xfc\xf5\x8d\x29\x39\xcc"
+ "\x8a\xd5\x35\x18\x36\x23\x4e\xd7"
+ "\x76\xd1\xda\x0c\x94\x67\xbb\x04"
+ "\x8b\xf2\x03\x6c\xa8\xcf\xb6\xea"
+ "\x22\x64\x47\xaa\x8f\x75\x13\xbf"
+ "\x9f\xc2\xc3\xf0\xc9\x56\xc5\x7a"
+ "\x71\x63\x2e\x89\x7b\x1e\x12\xca"
+ "\xe2\x5f\xaf\xd8\xa4\xf8\xc9\x7a"
+ "\xd6\xf9\x21\x31\x62\x44\x45\xa6"
+ "\xd6\xbc\x5a\xd3\x2d\x54\x43\xcc"
+ "\x9d\xde\xa5\x70\xe9\x42\x45\x8a"
+ "\x6b\xfa\xb1\x91\x13\xb0\xd9\x19",
+ .ilen = 128,
+ .result = "\x6f\x54\x20\x6f\x61\x4d\x79\x6e"
+ "\x53\x20\x63\x65\x65\x72\x73\x74"
+ "\x54\x20\x6f\x6f\x4d\x20\x6e\x61"
+ "\x20\x79\x65\x53\x72\x63\x74\x65"
+ "\x20\x73\x6f\x54\x20\x6f\x61\x4d"
+ "\x79\x6e\x53\x20\x63\x65\x65\x72"
+ "\x73\x74\x54\x20\x6f\x6f\x4d\x20"
+ "\x6e\x61\x20\x79\x65\x53\x72\x63"
+ "\x74\x65\x20\x73\x6f\x54\x20\x6f"
+ "\x61\x4d\x79\x6e\x53\x20\x63\x65"
+ "\x65\x72\x73\x74\x54\x20\x6f\x6f"
+ "\x4d\x20\x6e\x61\x20\x79\x65\x53"
+ "\x72\x63\x74\x65\x20\x73\x6f\x54"
+ "\x20\x6f\x61\x4d\x79\x6e\x53\x20"
+ "\x63\x65\x65\x72\x73\x74\x54\x20"
+ "\x6f\x6f\x4d\x20\x6e\x61\x0a\x79",
+ .rlen = 128,
+ },
+};
+
+/*
+ * Blowfish test vectors.
+ */
+#define BF_ENC_TEST_VECTORS 6
+#define BF_DEC_TEST_VECTORS 6
+#define BF_CBC_ENC_TEST_VECTORS 1
+#define BF_CBC_DEC_TEST_VECTORS 1
+
+static struct cipher_testvec bf_enc_tv_template[] = {
+ { /* DES test vectors from OpenSSL */
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 8,
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 8,
+ .result = "\x4e\xf9\x97\x45\x61\x98\xdd\x78",
+ .rlen = 8,
+ }, {
+ .key = "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e",
+ .klen = 8,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .ilen = 8,
+ .result = "\xa7\x90\x79\x51\x08\xea\x3c\xae",
+ .rlen = 8,
+ }, {
+ .key = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+ .klen = 8,
+ .input = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .ilen = 8,
+ .result = "\xe8\x7a\x24\x4e\x2c\xc8\x5e\x82",
+ .rlen = 8,
+ }, { /* Vary the keylength... */
+ .key = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+ "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f",
+ .klen = 16,
+ .input = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .ilen = 8,
+ .result = "\x93\x14\x28\x87\xee\x3b\xe1\x5c",
+ .rlen = 8,
+ }, {
+ .key = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+ "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+ "\x00\x11\x22\x33\x44",
+ .klen = 21,
+ .input = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .ilen = 8,
+ .result = "\xe6\xf5\x1e\xd7\x9b\x9d\xb2\x1f",
+ .rlen = 8,
+ }, { /* Generated with bf488 */
+ .key = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+ "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+ "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x04\x68\x91\x04\xc2\xfd\x3b\x2f"
+ "\x58\x40\x23\x64\x1a\xba\x61\x76"
+ "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e"
+ "\xff\xff\xff\xff\xff\xff\xff\xff",
+ .klen = 56,
+ .input = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .ilen = 8,
+ .result = "\xc0\x45\x04\x01\x2e\x4e\x1f\x53",
+ .rlen = 8,
+ },
+};
+
+static struct cipher_testvec bf_dec_tv_template[] = {
+ { /* DES test vectors from OpenSSL */
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 8,
+ .input = "\x4e\xf9\x97\x45\x61\x98\xdd\x78",
+ .ilen = 8,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .rlen = 8,
+ }, {
+ .key = "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e",
+ .klen = 8,
+ .input = "\xa7\x90\x79\x51\x08\xea\x3c\xae",
+ .ilen = 8,
+ .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .rlen = 8,
+ }, {
+ .key = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+ .klen = 8,
+ .input = "\xe8\x7a\x24\x4e\x2c\xc8\x5e\x82",
+ .ilen = 8,
+ .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .rlen = 8,
+ }, { /* Vary the keylength... */
+ .key = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+ "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f",
+ .klen = 16,
+ .input = "\x93\x14\x28\x87\xee\x3b\xe1\x5c",
+ .ilen = 8,
+ .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .rlen = 8,
+ }, {
+ .key = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+ "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+ "\x00\x11\x22\x33\x44",
+ .klen = 21,
+ .input = "\xe6\xf5\x1e\xd7\x9b\x9d\xb2\x1f",
+ .ilen = 8,
+ .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .rlen = 8,
+ }, { /* Generated with bf488, using OpenSSL, Libgcrypt and Nettle */
+ .key = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+ "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+ "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x04\x68\x91\x04\xc2\xfd\x3b\x2f"
+ "\x58\x40\x23\x64\x1a\xba\x61\x76"
+ "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e"
+ "\xff\xff\xff\xff\xff\xff\xff\xff",
+ .klen = 56,
+ .input = "\xc0\x45\x04\x01\x2e\x4e\x1f\x53",
+ .ilen = 8,
+ .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .rlen = 8,
+ },
+};
+
+static struct cipher_testvec bf_cbc_enc_tv_template[] = {
+ { /* From OpenSSL */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+ .klen = 16,
+ .iv = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .input = "\x37\x36\x35\x34\x33\x32\x31\x20"
+ "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+ "\x68\x65\x20\x74\x69\x6d\x65\x20"
+ "\x66\x6f\x72\x20\x00\x00\x00\x00",
+ .ilen = 32,
+ .result = "\x6b\x77\xb4\xd6\x30\x06\xde\xe6"
+ "\x05\xb1\x56\xe2\x74\x03\x97\x93"
+ "\x58\xde\xb9\xe7\x15\x46\x16\xd9"
+ "\x59\xf1\x65\x2b\xd5\xff\x92\xcc",
+ .rlen = 32,
+ },
+};
+
+static struct cipher_testvec bf_cbc_dec_tv_template[] = {
+ { /* From OpenSSL */
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+ .klen = 16,
+ .iv = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .input = "\x6b\x77\xb4\xd6\x30\x06\xde\xe6"
+ "\x05\xb1\x56\xe2\x74\x03\x97\x93"
+ "\x58\xde\xb9\xe7\x15\x46\x16\xd9"
+ "\x59\xf1\x65\x2b\xd5\xff\x92\xcc",
+ .ilen = 32,
+ .result = "\x37\x36\x35\x34\x33\x32\x31\x20"
+ "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+ "\x68\x65\x20\x74\x69\x6d\x65\x20"
+ "\x66\x6f\x72\x20\x00\x00\x00\x00",
+ .rlen = 32,
+ },
+};
+
+/*
+ * Twofish test vectors.
+ */
+#define TF_ENC_TEST_VECTORS 3
+#define TF_DEC_TEST_VECTORS 3
+#define TF_CBC_ENC_TEST_VECTORS 4
+#define TF_CBC_DEC_TEST_VECTORS 4
+
+static struct cipher_testvec tf_enc_tv_template[] = {
+ {
+ .key = zeroed_string,
+ .klen = 16,
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+ "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+ .rlen = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+ "\x00\x11\x22\x33\x44\x55\x66\x77",
+ .klen = 24,
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\xcf\xd1\xd2\xe5\xa9\xbe\x9c\xdf"
+ "\x50\x1f\x13\xb8\x92\xbd\x22\x48",
+ .rlen = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+ "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .klen = 32,
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\x37\x52\x7b\xe0\x05\x23\x34\xb8"
+ "\x9f\x0c\xfc\xca\xe8\x7c\xfa\x20",
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec tf_dec_tv_template[] = {
+ {
+ .key = zeroed_string,
+ .klen = 16,
+ .input = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+ "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+ "\x00\x11\x22\x33\x44\x55\x66\x77",
+ .klen = 24,
+ .input = "\xcf\xd1\xd2\xe5\xa9\xbe\x9c\xdf"
+ "\x50\x1f\x13\xb8\x92\xbd\x22\x48",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+ "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .klen = 32,
+ .input = "\x37\x52\x7b\xe0\x05\x23\x34\xb8"
+ "\x9f\x0c\xfc\xca\xe8\x7c\xfa\x20",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec tf_cbc_enc_tv_template[] = {
+ { /* Generated with Nettle */
+ .key = zeroed_string,
+ .klen = 16,
+ .iv = zeroed_string,
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+ "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+ .rlen = 16,
+ }, {
+ .key = zeroed_string,
+ .klen = 16,
+ .iv = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+ "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+ "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+ .rlen = 16,
+ }, {
+ .key = zeroed_string,
+ .klen = 16,
+ .iv = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+ "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+ "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+ .rlen = 16,
+ }, {
+ .key = zeroed_string,
+ .klen = 16,
+ .iv = zeroed_string,
+ .input = zeroed_string,
+ .ilen = 48,
+ .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+ "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a"
+ "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+ "\x86\xcb\x08\x6b\x78\x9f\x54\x19"
+ "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+ "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+ .rlen = 48,
+ },
+};
+
+static struct cipher_testvec tf_cbc_dec_tv_template[] = {
+ { /* Reverse of the first four above */
+ .key = zeroed_string,
+ .klen = 16,
+ .iv = zeroed_string,
+ .input = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+ "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ }, {
+ .key = zeroed_string,
+ .klen = 16,
+ .iv = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+ "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+ .input = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+ "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ }, {
+ .key = zeroed_string,
+ .klen = 16,
+ .iv = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+ "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+ .input = "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+ "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ }, {
+ .key = zeroed_string,
+ .klen = 16,
+ .iv = zeroed_string,
+ .input = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+ "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a"
+ "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+ "\x86\xcb\x08\x6b\x78\x9f\x54\x19"
+ "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+ "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+ .ilen = 48,
+ .result = zeroed_string,
+ .rlen = 48,
+ },
+};
+
+/*
+ * Serpent test vectors. These are backwards because Serpent writes
+ * octet sequences in right-to-left mode.
+ */
+#define SERPENT_ENC_TEST_VECTORS 4
+#define SERPENT_DEC_TEST_VECTORS 4
+
+#define TNEPRES_ENC_TEST_VECTORS 4
+#define TNEPRES_DEC_TEST_VECTORS 4
+
+static struct cipher_testvec serpent_enc_tv_template[] = {
+ {
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .ilen = 16,
+ .result = "\x12\x07\xfc\xce\x9b\xd0\xd6\x47"
+ "\x6a\xe9\x8f\xbe\xd1\x43\xa0\xe2",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .klen = 16,
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .ilen = 16,
+ .result = "\x4c\x7d\x8a\x32\x80\x72\xa2\x2c"
+ "\x82\x3e\x4a\x1f\x3a\xcd\xa1\x6d",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .klen = 32,
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .ilen = 16,
+ .result = "\xde\x26\x9f\xf8\x33\xe4\x32\xb8"
+ "\x5b\x2e\x88\xd2\x70\x1c\xe7\x5c",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
+ .klen = 16,
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\xdd\xd2\x6b\x98\xa5\xff\xd8\x2c"
+ "\x05\x34\x5a\x9d\xad\xbf\xaf\x49",
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec tnepres_enc_tv_template[] = {
+ { /* KeySize=128, PT=0, I=1 */
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .key = "\x80\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 16,
+ .ilen = 16,
+ .result = "\x49\xaf\xbf\xad\x9d\x5a\x34\x05"
+ "\x2c\xd8\xff\xa5\x98\x6b\xd2\xdd",
+ .rlen = 16,
+ }, { /* KeySize=192, PT=0, I=1 */
+ .key = "\x80\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 24,
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 16,
+ .result = "\xe7\x8e\x54\x02\xc7\x19\x55\x68"
+ "\xac\x36\x78\xf7\xa3\xf6\x0c\x66",
+ .rlen = 16,
+ }, { /* KeySize=256, PT=0, I=1 */
+ .key = "\x80\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 32,
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 16,
+ .result = "\xab\xed\x96\xe7\x66\xbf\x28\xcb"
+ "\xc0\xeb\xd2\x1a\x82\xef\x08\x19",
+ .rlen = 16,
+ }, { /* KeySize=256, I=257 */
+ .key = "\x1f\x1e\x1d\x1c\x1b\x1a\x19\x18"
+ "\x17\x16\x15\x14\x13\x12\x11\x10"
+ "\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08"
+ "\x07\x06\x05\x04\x03\x02\x01\x00",
+ .klen = 32,
+ .input = "\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08"
+ "\x07\x06\x05\x04\x03\x02\x01\x00",
+ .ilen = 16,
+ .result = "\x5c\xe7\x1c\x70\xd2\x88\x2e\x5b"
+ "\xb8\x32\xe4\x33\xf8\x9f\x26\xde",
+ .rlen = 16,
+ },
+};
+
+
+static struct cipher_testvec serpent_dec_tv_template[] = {
+ {
+ .input = "\x12\x07\xfc\xce\x9b\xd0\xd6\x47"
+ "\x6a\xe9\x8f\xbe\xd1\x43\xa0\xe2",
+ .ilen = 16,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .klen = 16,
+ .input = "\x4c\x7d\x8a\x32\x80\x72\xa2\x2c"
+ "\x82\x3e\x4a\x1f\x3a\xcd\xa1\x6d",
+ .ilen = 16,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .klen = 32,
+ .input = "\xde\x26\x9f\xf8\x33\xe4\x32\xb8"
+ "\x5b\x2e\x88\xd2\x70\x1c\xe7\x5c",
+ .ilen = 16,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
+ .klen = 16,
+ .input = "\xdd\xd2\x6b\x98\xa5\xff\xd8\x2c"
+ "\x05\x34\x5a\x9d\xad\xbf\xaf\x49",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec tnepres_dec_tv_template[] = {
+ {
+ .input = "\x41\xcc\x6b\x31\x59\x31\x45\x97"
+ "\x6d\x6f\xbb\x38\x4b\x37\x21\x28",
+ .ilen = 16,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .klen = 16,
+ .input = "\xea\xf4\xd7\xfc\xd8\x01\x34\x47"
+ "\x81\x45\x0b\xfa\x0c\xd6\xad\x6e",
+ .ilen = 16,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .klen = 32,
+ .input = "\x64\xa9\x1a\x37\xed\x9f\xe7\x49"
+ "\xa8\x4e\x76\xd6\xf5\x0d\x78\xee",
+ .ilen = 16,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .rlen = 16,
+ }, { /* KeySize=128, I=121 */
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
+ .klen = 16,
+ .input = "\x3d\xda\xbf\xc0\x06\xda\xab\x06"
+ "\x46\x2a\xf4\xef\x81\x54\x4e\x26",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ },
+};
+
+
+/* Cast6 test vectors from RFC 2612 */
+#define CAST6_ENC_TEST_VECTORS 3
+#define CAST6_DEC_TEST_VECTORS 3
+
+static struct cipher_testvec cast6_enc_tv_template[] = {
+ {
+ .key = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+ "\x0a\xf7\x56\x47\xf2\x9f\x61\x5d",
+ .klen = 16,
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\xc8\x42\xa0\x89\x72\xb4\x3d\x20"
+ "\x83\x6c\x91\xd1\xb7\x53\x0f\x6b",
+ .rlen = 16,
+ }, {
+ .key = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+ "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+ "\xba\xc7\x7a\x77\x17\x94\x28\x63",
+ .klen = 24,
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\x1b\x38\x6c\x02\x10\xdc\xad\xcb"
+ "\xdd\x0e\x41\xaa\x08\xa7\xa7\xe8",
+ .rlen = 16,
+ }, {
+ .key = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+ "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+ "\x8d\x7c\x47\xce\x26\x49\x08\x46"
+ "\x1c\xc1\xb5\x13\x7a\xe6\xb6\x04",
+ .klen = 32,
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\x4f\x6a\x20\x38\x28\x68\x97\xb9"
+ "\xc9\x87\x01\x36\x55\x33\x17\xfa",
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec cast6_dec_tv_template[] = {
+ {
+ .key = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+ "\x0a\xf7\x56\x47\xf2\x9f\x61\x5d",
+ .klen = 16,
+ .input = "\xc8\x42\xa0\x89\x72\xb4\x3d\x20"
+ "\x83\x6c\x91\xd1\xb7\x53\x0f\x6b",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ }, {
+ .key = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+ "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+ "\xba\xc7\x7a\x77\x17\x94\x28\x63",
+ .klen = 24,
+ .input = "\x1b\x38\x6c\x02\x10\xdc\xad\xcb"
+ "\xdd\x0e\x41\xaa\x08\xa7\xa7\xe8",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ }, {
+ .key = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+ "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+ "\x8d\x7c\x47\xce\x26\x49\x08\x46"
+ "\x1c\xc1\xb5\x13\x7a\xe6\xb6\x04",
+ .klen = 32,
+ .input = "\x4f\x6a\x20\x38\x28\x68\x97\xb9"
+ "\xc9\x87\x01\x36\x55\x33\x17\xfa",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ },
+};
+
+
+/*
+ * AES test vectors.
+ */
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+#define AES_ENC_TEST_VECTORS 3
+#define AES_DEC_TEST_VECTORS 3
+#define AES_CBC_ENC_TEST_VECTORS 4
+#define AES_CBC_DEC_TEST_VECTORS 4
+#define AES_LRW_ENC_TEST_VECTORS 8
+#define AES_LRW_DEC_TEST_VECTORS 8
+#define AES_XTS_ENC_TEST_VECTORS 4
+#define AES_XTS_DEC_TEST_VECTORS 4
+#define AES_CTR_ENC_TEST_VECTORS 3
+#define AES_CTR_DEC_TEST_VECTORS 3
+#define AES_CTR_3686_ENC_TEST_VECTORS 7
+#define AES_CTR_3686_DEC_TEST_VECTORS 6
+#define AES_GCM_ENC_TEST_VECTORS 9
+#define AES_GCM_DEC_TEST_VECTORS 8
+#define AES_CCM_ENC_TEST_VECTORS 7
+#define AES_CCM_DEC_TEST_VECTORS 7
+#define AES_CCM_4309_ENC_TEST_VECTORS 7
+#define AES_CCM_4309_DEC_TEST_VECTORS 10
+#else
+#define AES_ENC_TEST_VECTORS 3
+#define AES_DEC_TEST_VECTORS 3
+#define AES_CBC_ENC_TEST_VECTORS 3
+#define AES_CBC_DEC_TEST_VECTORS 3
+#define AES_CTR_ENC_TEST_VECTORS 3
+#define AES_CTR_DEC_TEST_VECTORS 3
+#define AES_GCM_ENC_TEST_VECTORS 9
+#define AES_GCM_DEC_TEST_VECTORS 8
+#define AES_CCM_ENC_TEST_VECTORS 7
+#define AES_CCM_DEC_TEST_VECTORS 7
+#define AES_CCM_4309_ENC_TEST_VECTORS 7
+#define AES_CCM_4309_DEC_TEST_VECTORS 10
+#define AES_CTR_3686_ENC_TEST_VECTORS 6
+#define AES_CTR_3686_DEC_TEST_VECTORS 6
+#endif /* CONFIG_CRYPTO_DEV_AES */
+
+static struct cipher_testvec aes_enc_tv_template[] = {
+ { /* From FIPS-197 */
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .klen = 16,
+ .input = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .ilen = 16,
+ .result = "\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
+ "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17",
+ .klen = 24,
+ .input = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .ilen = 16,
+ .result = "\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
+ "\x6e\xaf\x70\xa0\xec\x0d\x71\x91",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .klen = 32,
+ .input = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .ilen = 16,
+ .result = "\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
+ "\xea\xfc\x49\x90\x4b\x49\x60\x89",
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec aes_dec_tv_template[] = {
+ { /* From FIPS-197 */
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .klen = 16,
+ .input = "\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
+ "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a",
+ .ilen = 16,
+ .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17",
+ .klen = 24,
+ .input = "\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
+ "\x6e\xaf\x70\xa0\xec\x0d\x71\x91",
+ .ilen = 16,
+ .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .klen = 32,
+ .input = "\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
+ "\xea\xfc\x49\x90\x4b\x49\x60\x89",
+ .ilen = 16,
+ .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec aes_cbc_enc_tv_template[] = {
+ { /* From RFC 3602 */
+ .key = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+ "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+ .klen = 16,
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+ .input = "Single block msg",
+ .ilen = 16,
+ .result = "\xe3\x53\x77\x9c\x10\x79\xae\xb8"
+ "\x27\x08\x94\x2d\xbe\x77\x18\x1a",
+ .rlen = 16,
+ }, {
+ .key = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+ "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+ .klen = 16,
+ .iv = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+ "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .ilen = 32,
+ .result = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a"
+ "\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
+ "\x75\x86\x60\x2d\x25\x3c\xff\xf9"
+ "\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
+ .rlen = 32,
+ }, { /* From NIST SP800-38A */
+ .key = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+ "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ .klen = 24,
+ .iv = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .input = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .ilen = 64,
+ .result = "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d"
+ "\x71\x78\x18\x3a\x9f\xa0\x71\xe8"
+ "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4"
+ "\xe5\xe7\x38\x76\x3f\x69\x14\x5a"
+ "\x57\x1b\x24\x20\x12\xfb\x7a\xe0"
+ "\x7f\xa9\xba\xac\x3d\xf1\x02\xe0"
+ "\x08\xb0\xe2\x79\x88\x59\x88\x81"
+ "\xd9\x20\xa9\xe6\x4f\x56\x15\xcd",
+ .rlen = 64,
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+ }, {
+ .key = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+ "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+ "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ .klen = 32,
+ .iv = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .input = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .ilen = 64,
+ .result = "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba"
+ "\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6"
+ "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d"
+ "\x67\x9f\x77\x7b\xc6\x70\x2c\x7d"
+ "\x39\xf2\x33\x69\xa9\xd9\xba\xcf"
+ "\xa5\x30\xe2\x63\x04\x23\x14\x61"
+ "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc"
+ "\xda\x6c\x19\x07\x8c\x6a\x9d\x1b",
+ .rlen = 64,
+#endif
+ },
+};
+
+static struct cipher_testvec aes_cbc_dec_tv_template[] = {
+ { /* From RFC 3602 */
+ .key = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+ "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+ .klen = 16,
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+ .input = "\xe3\x53\x77\x9c\x10\x79\xae\xb8"
+ "\x27\x08\x94\x2d\xbe\x77\x18\x1a",
+ .ilen = 16,
+ .result = "Single block msg",
+ .rlen = 16,
+ }, {
+ .key = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+ "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+ .klen = 16,
+ .iv = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+ "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+ .input = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a"
+ "\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
+ "\x75\x86\x60\x2d\x25\x3c\xff\xf9"
+ "\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
+ .ilen = 32,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .rlen = 32,
+ }, { /* From NIST SP800-38A */
+ .key = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+ "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ .klen = 24,
+ .iv = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .input = "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d"
+ "\x71\x78\x18\x3a\x9f\xa0\x71\xe8"
+ "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4"
+ "\xe5\xe7\x38\x76\x3f\x69\x14\x5a"
+ "\x57\x1b\x24\x20\x12\xfb\x7a\xe0"
+ "\x7f\xa9\xba\xac\x3d\xf1\x02\xe0"
+ "\x08\xb0\xe2\x79\x88\x59\x88\x81"
+ "\xd9\x20\xa9\xe6\x4f\x56\x15\xcd",
+ .ilen = 64,
+ .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .rlen = 64,
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+ }, {
+ .key = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+ "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+ "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ .klen = 32,
+ .iv = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .input = "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba"
+ "\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6"
+ "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d"
+ "\x67\x9f\x77\x7b\xc6\x70\x2c\x7d"
+ "\x39\xf2\x33\x69\xa9\xd9\xba\xcf"
+ "\xa5\x30\xe2\x63\x04\x23\x14\x61"
+ "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc"
+ "\xda\x6c\x19\x07\x8c\x6a\x9d\x1b",
+ .ilen = 64,
+ .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .rlen = 64,
+#endif
+ },
+};
+
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+
+static struct cipher_testvec aes_lrw_enc_tv_template[] = {
+ /* from http://grouper.ieee.org/groups/1619/email/pdf00017.pdf */
+ { /* LRW-32-AES 1 */
+ .key = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
+ "\x4c\x26\x84\x14\xb5\x68\x01\x85"
+ "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
+ "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\xf1\xb2\x73\xcd\x65\xa3\xdf\x5f"
+ "\xe9\x5d\x48\x92\x54\x63\x4e\xb8",
+ .rlen = 16,
+ }, { /* LRW-32-AES 2 */
+ .key = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
+ "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
+ "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
+ "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x02",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x00\xc8\x2b\xae\x95\xbb\xcd\xe5"
+ "\x27\x4f\x07\x69\xb2\x60\xe1\x36",
+ .rlen = 16,
+ }, { /* LRW-32-AES 3 */
+ .key = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
+ "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
+ "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
+ "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x76\x32\x21\x83\xed\x8f\xf1\x82"
+ "\xf9\x59\x62\x03\x69\x0e\x5e\x01",
+ .rlen = 16,
+ }, { /* LRW-32-AES 4 */
+ .key = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
+ "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
+ "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
+ "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
+ "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x9c\x0f\x15\x2f\x55\xa2\xd8\xf0"
+ "\xd6\x7b\x8f\x9e\x28\x22\xbc\x41",
+ .rlen = 16,
+ }, { /* LRW-32-AES 5 */
+ .key = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
+ "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
+ "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
+ "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
+ "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\xd4\x27\x6a\x7f\x14\x91\x3d\x65"
+ "\xc8\x60\x48\x02\x87\xe3\x34\x06",
+ .rlen = 16,
+ }, { /* LRW-32-AES 6 */
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\xbd\x06\xb8\xe1\xdb\x98\x89\x9e"
+ "\xc4\x98\xe4\x91\xcf\x1c\x70\x2b",
+ .rlen = 16,
+ }, { /* LRW-32-AES 7 */
+ .key = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
+ "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
+ "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
+ "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
+ "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
+ "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x5b\x90\x8e\xc1\xab\xdd\x67\x5f"
+ "\x3d\x69\x8a\x95\x53\xc8\x9c\xe5",
+ .rlen = 16,
+ }, {
+/* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html */
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+ "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+ "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+ "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+ "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+ "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+ "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+ "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+ "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+ "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+ "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+ "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+ "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+ "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+ "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+ "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+ "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+ "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+ "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+ "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+ "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+ "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+ "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+ "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+ "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+ "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+ "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+ "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+ "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+ "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+ "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+ "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+ "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+ "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+ "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+ "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+ "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+ "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+ "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+ "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+ "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+ "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+ "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+ "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+ "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+ "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+ "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+ "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+ "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+ "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+ "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+ "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+ "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+ "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+ "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+ "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+ "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+ "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+ "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+ "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+ "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+ "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+ "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+ "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+ .ilen = 512,
+ .result = "\x1a\x1d\xa9\x30\xad\xf9\x2f\x9b"
+ "\xb6\x1d\xae\xef\xf0\x2f\xf8\x5a"
+ "\x39\x3c\xbf\x2a\xb2\x45\xb2\x23"
+ "\x1b\x63\x3c\xcf\xaa\xbe\xcf\x4e"
+ "\xfa\xe8\x29\xc2\x20\x68\x2b\x3c"
+ "\x2e\x8b\xf7\x6e\x25\xbd\xe3\x3d"
+ "\x66\x27\xd6\xaf\xd6\x64\x3e\xe3"
+ "\xe8\x58\x46\x97\x39\x51\x07\xde"
+ "\xcb\x37\xbc\xa9\xc0\x5f\x75\xc3"
+ "\x0e\x84\x23\x1d\x16\xd4\x1c\x59"
+ "\x9c\x1a\x02\x55\xab\x3a\x97\x1d"
+ "\xdf\xdd\xc7\x06\x51\xd7\x70\xae"
+ "\x23\xc6\x8c\xf5\x1e\xa0\xe5\x82"
+ "\xb8\xb2\xbf\x04\xa0\x32\x8e\x68"
+ "\xeb\xaf\x6e\x2d\x94\x22\x2f\xce"
+ "\x4c\xb5\x59\xe2\xa2\x2f\xa0\x98"
+ "\x1a\x97\xc6\xd4\xb5\x00\x59\xf2"
+ "\x84\x14\x72\xb1\x9a\x6e\xa3\x7f"
+ "\xea\x20\xe7\xcb\x65\x77\x3a\xdf"
+ "\xc8\x97\x67\x15\xc2\x2a\x27\xcc"
+ "\x18\x55\xa1\x24\x0b\x24\x24\xaf"
+ "\x5b\xec\x68\xb8\xc8\xf5\xba\x63"
+ "\xff\xed\x89\xce\xd5\x3d\x88\xf3"
+ "\x25\xef\x05\x7c\x3a\xef\xeb\xd8"
+ "\x7a\x32\x0d\xd1\x1e\x58\x59\x99"
+ "\x90\x25\xb5\x26\xb0\xe3\x2b\x6c"
+ "\x4c\xa9\x8b\x84\x4f\x5e\x01\x50"
+ "\x41\x30\x58\xc5\x62\x74\x52\x1d"
+ "\x45\x24\x6a\x42\x64\x4f\x97\x1c"
+ "\xa8\x66\xb5\x6d\x79\xd4\x0d\x48"
+ "\xc5\x5f\xf3\x90\x32\xdd\xdd\xe1"
+ "\xe4\xa9\x9f\xfc\xc3\x52\x5a\x46"
+ "\xe4\x81\x84\x95\x36\x59\x7a\x6b"
+ "\xaa\xb3\x60\xad\xce\x9f\x9f\x28"
+ "\xe0\x01\x75\x22\xc4\x4e\xa9\x62"
+ "\x5c\x62\x0d\x00\xcb\x13\xe8\x43"
+ "\x72\xd4\x2d\x53\x46\xb5\xd1\x16"
+ "\x22\x18\xdf\x34\x33\xf5\xd6\x1c"
+ "\xb8\x79\x78\x97\x94\xff\x72\x13"
+ "\x4c\x27\xfc\xcb\xbf\x01\x53\xa6"
+ "\xb4\x50\x6e\xde\xdf\xb5\x43\xa4"
+ "\x59\xdf\x52\xf9\x7c\xe0\x11\x6f"
+ "\x2d\x14\x8e\x24\x61\x2c\xe1\x17"
+ "\xcc\xce\x51\x0c\x19\x8a\x82\x30"
+ "\x94\xd5\x3d\x6a\x53\x06\x5e\xbd"
+ "\xb7\xeb\xfa\xfd\x27\x51\xde\x85"
+ "\x1e\x86\x53\x11\x53\x94\x00\xee"
+ "\x2b\x8c\x08\x2a\xbf\xdd\xae\x11"
+ "\xcb\x1e\xa2\x07\x9a\x80\xcf\x62"
+ "\x9b\x09\xdc\x95\x3c\x96\x8e\xb1"
+ "\x09\xbd\xe4\xeb\xdb\xca\x70\x7a"
+ "\x9e\xfa\x31\x18\x45\x3c\x21\x33"
+ "\xb0\xb3\x2b\xea\xf3\x71\x2d\xe1"
+ "\x03\xad\x1b\x48\xd4\x67\x27\xf0"
+ "\x62\xe4\x3d\xfb\x9b\x08\x76\xe7"
+ "\xdd\x2b\x01\x39\x04\x5a\x58\x7a"
+ "\xf7\x11\x90\xec\xbd\x51\x5c\x32"
+ "\x6b\xd7\x35\x39\x02\x6b\xf2\xa6"
+ "\xd0\x0d\x07\xe1\x06\xc4\x5b\x7d"
+ "\xe4\x6a\xd7\xee\x15\x1f\x83\xb4"
+ "\xa3\xa7\x5e\xc3\x90\xb7\xef\xd3"
+ "\xb7\x4f\xf8\x92\x4c\xb7\x3c\x29"
+ "\xcd\x7e\x2b\x5d\x43\xea\x42\xe7"
+ "\x74\x3f\x7d\x58\x88\x75\xde\x3e",
+ .rlen = 512,
+ }
+};
+
+static struct cipher_testvec aes_lrw_dec_tv_template[] = {
+ /* from http://grouper.ieee.org/groups/1619/email/pdf00017.pdf */
+ /* same as enc vectors with input and result reversed */
+ { /* LRW-32-AES 1 */
+ .key = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
+ "\x4c\x26\x84\x14\xb5\x68\x01\x85"
+ "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
+ "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\xf1\xb2\x73\xcd\x65\xa3\xdf\x5f"
+ "\xe9\x5d\x48\x92\x54\x63\x4e\xb8",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, { /* LRW-32-AES 2 */
+ .key = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
+ "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
+ "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
+ "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x02",
+ .input = "\x00\xc8\x2b\xae\x95\xbb\xcd\xe5"
+ "\x27\x4f\x07\x69\xb2\x60\xe1\x36",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, { /* LRW-32-AES 3 */
+ .key = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
+ "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
+ "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
+ "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x76\x32\x21\x83\xed\x8f\xf1\x82"
+ "\xf9\x59\x62\x03\x69\x0e\x5e\x01",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, { /* LRW-32-AES 4 */
+ .key = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
+ "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
+ "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
+ "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
+ "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x9c\x0f\x15\x2f\x55\xa2\xd8\xf0"
+ "\xd6\x7b\x8f\x9e\x28\x22\xbc\x41",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, { /* LRW-32-AES 5 */
+ .key = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
+ "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
+ "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
+ "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
+ "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\xd4\x27\x6a\x7f\x14\x91\x3d\x65"
+ "\xc8\x60\x48\x02\x87\xe3\x34\x06",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, { /* LRW-32-AES 6 */
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\xbd\x06\xb8\xe1\xdb\x98\x89\x9e"
+ "\xc4\x98\xe4\x91\xcf\x1c\x70\x2b",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, { /* LRW-32-AES 7 */
+ .key = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
+ "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
+ "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
+ "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
+ "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
+ "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x5b\x90\x8e\xc1\xab\xdd\x67\x5f"
+ "\x3d\x69\x8a\x95\x53\xc8\x9c\xe5",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+/* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html */
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x1a\x1d\xa9\x30\xad\xf9\x2f\x9b"
+ "\xb6\x1d\xae\xef\xf0\x2f\xf8\x5a"
+ "\x39\x3c\xbf\x2a\xb2\x45\xb2\x23"
+ "\x1b\x63\x3c\xcf\xaa\xbe\xcf\x4e"
+ "\xfa\xe8\x29\xc2\x20\x68\x2b\x3c"
+ "\x2e\x8b\xf7\x6e\x25\xbd\xe3\x3d"
+ "\x66\x27\xd6\xaf\xd6\x64\x3e\xe3"
+ "\xe8\x58\x46\x97\x39\x51\x07\xde"
+ "\xcb\x37\xbc\xa9\xc0\x5f\x75\xc3"
+ "\x0e\x84\x23\x1d\x16\xd4\x1c\x59"
+ "\x9c\x1a\x02\x55\xab\x3a\x97\x1d"
+ "\xdf\xdd\xc7\x06\x51\xd7\x70\xae"
+ "\x23\xc6\x8c\xf5\x1e\xa0\xe5\x82"
+ "\xb8\xb2\xbf\x04\xa0\x32\x8e\x68"
+ "\xeb\xaf\x6e\x2d\x94\x22\x2f\xce"
+ "\x4c\xb5\x59\xe2\xa2\x2f\xa0\x98"
+ "\x1a\x97\xc6\xd4\xb5\x00\x59\xf2"
+ "\x84\x14\x72\xb1\x9a\x6e\xa3\x7f"
+ "\xea\x20\xe7\xcb\x65\x77\x3a\xdf"
+ "\xc8\x97\x67\x15\xc2\x2a\x27\xcc"
+ "\x18\x55\xa1\x24\x0b\x24\x24\xaf"
+ "\x5b\xec\x68\xb8\xc8\xf5\xba\x63"
+ "\xff\xed\x89\xce\xd5\x3d\x88\xf3"
+ "\x25\xef\x05\x7c\x3a\xef\xeb\xd8"
+ "\x7a\x32\x0d\xd1\x1e\x58\x59\x99"
+ "\x90\x25\xb5\x26\xb0\xe3\x2b\x6c"
+ "\x4c\xa9\x8b\x84\x4f\x5e\x01\x50"
+ "\x41\x30\x58\xc5\x62\x74\x52\x1d"
+ "\x45\x24\x6a\x42\x64\x4f\x97\x1c"
+ "\xa8\x66\xb5\x6d\x79\xd4\x0d\x48"
+ "\xc5\x5f\xf3\x90\x32\xdd\xdd\xe1"
+ "\xe4\xa9\x9f\xfc\xc3\x52\x5a\x46"
+ "\xe4\x81\x84\x95\x36\x59\x7a\x6b"
+ "\xaa\xb3\x60\xad\xce\x9f\x9f\x28"
+ "\xe0\x01\x75\x22\xc4\x4e\xa9\x62"
+ "\x5c\x62\x0d\x00\xcb\x13\xe8\x43"
+ "\x72\xd4\x2d\x53\x46\xb5\xd1\x16"
+ "\x22\x18\xdf\x34\x33\xf5\xd6\x1c"
+ "\xb8\x79\x78\x97\x94\xff\x72\x13"
+ "\x4c\x27\xfc\xcb\xbf\x01\x53\xa6"
+ "\xb4\x50\x6e\xde\xdf\xb5\x43\xa4"
+ "\x59\xdf\x52\xf9\x7c\xe0\x11\x6f"
+ "\x2d\x14\x8e\x24\x61\x2c\xe1\x17"
+ "\xcc\xce\x51\x0c\x19\x8a\x82\x30"
+ "\x94\xd5\x3d\x6a\x53\x06\x5e\xbd"
+ "\xb7\xeb\xfa\xfd\x27\x51\xde\x85"
+ "\x1e\x86\x53\x11\x53\x94\x00\xee"
+ "\x2b\x8c\x08\x2a\xbf\xdd\xae\x11"
+ "\xcb\x1e\xa2\x07\x9a\x80\xcf\x62"
+ "\x9b\x09\xdc\x95\x3c\x96\x8e\xb1"
+ "\x09\xbd\xe4\xeb\xdb\xca\x70\x7a"
+ "\x9e\xfa\x31\x18\x45\x3c\x21\x33"
+ "\xb0\xb3\x2b\xea\xf3\x71\x2d\xe1"
+ "\x03\xad\x1b\x48\xd4\x67\x27\xf0"
+ "\x62\xe4\x3d\xfb\x9b\x08\x76\xe7"
+ "\xdd\x2b\x01\x39\x04\x5a\x58\x7a"
+ "\xf7\x11\x90\xec\xbd\x51\x5c\x32"
+ "\x6b\xd7\x35\x39\x02\x6b\xf2\xa6"
+ "\xd0\x0d\x07\xe1\x06\xc4\x5b\x7d"
+ "\xe4\x6a\xd7\xee\x15\x1f\x83\xb4"
+ "\xa3\xa7\x5e\xc3\x90\xb7\xef\xd3"
+ "\xb7\x4f\xf8\x92\x4c\xb7\x3c\x29"
+ "\xcd\x7e\x2b\x5d\x43\xea\x42\xe7"
+ "\x74\x3f\x7d\x58\x88\x75\xde\x3e",
+ .ilen = 512,
+ .result = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+ "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+ "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+ "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+ "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+ "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+ "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+ "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+ "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+ "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+ "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+ "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+ "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+ "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+ "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+ "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+ "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+ "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+ "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+ "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+ "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+ "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+ "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+ "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+ "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+ "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+ "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+ "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+ "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+ "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+ "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+ "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+ "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+ "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+ "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+ "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+ "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+ "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+ "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+ "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+ "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+ "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+ "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+ "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+ "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+ "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+ "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+ "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+ "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+ "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+ "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+ "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+ "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+ "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+ "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+ "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+ "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+ "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+ "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+ "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+ "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+ "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+ "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+ "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+ .rlen = 512,
+ }
+};
+
+static struct cipher_testvec aes_xts_enc_tv_template[] = {
+ /* http://grouper.ieee.org/groups/1619/email/pdf00086.pdf */
+ { /* XTS-AES 1 */
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 32,
+ .result = "\x91\x7c\xf6\x9e\xbd\x68\xb2\xec"
+ "\x9b\x9f\xe9\xa3\xea\xdd\xa6\x92"
+ "\xcd\x43\xd2\xf5\x95\x98\xed\x85"
+ "\x8c\x02\xc2\x65\x2f\xbf\x92\x2e",
+ .rlen = 32,
+ }, { /* XTS-AES 2 */
+ .key = "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .ilen = 32,
+ .result = "\xc4\x54\x18\x5e\x6a\x16\x93\x6e"
+ "\x39\x33\x40\x38\xac\xef\x83\x8b"
+ "\xfb\x18\x6f\xff\x74\x80\xad\xc4"
+ "\x28\x93\x82\xec\xd6\xd3\x94\xf0",
+ .rlen = 32,
+ }, { /* XTS-AES 3 */
+ .key = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
+ "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .ilen = 32,
+ .result = "\xaf\x85\x33\x6b\x59\x7a\xfc\x1a"
+ "\x90\x0b\x2e\xb2\x1e\xc9\x49\xd2"
+ "\x92\xdf\x4c\x04\x7e\x0b\x21\x53"
+ "\x21\x86\xa5\x97\x1a\x22\x7a\x89",
+ .rlen = 32,
+ }, { /* XTS-AES 4 */
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .ilen = 512,
+ .result = "\x27\xa7\x47\x9b\xef\xa1\xd4\x76"
+ "\x48\x9f\x30\x8c\xd4\xcf\xa6\xe2"
+ "\xa9\x6e\x4b\xbe\x32\x08\xff\x25"
+ "\x28\x7d\xd3\x81\x96\x16\xe8\x9c"
+ "\xc7\x8c\xf7\xf5\xe5\x43\x44\x5f"
+ "\x83\x33\xd8\xfa\x7f\x56\x00\x00"
+ "\x05\x27\x9f\xa5\xd8\xb5\xe4\xad"
+ "\x40\xe7\x36\xdd\xb4\xd3\x54\x12"
+ "\x32\x80\x63\xfd\x2a\xab\x53\xe5"
+ "\xea\x1e\x0a\x9f\x33\x25\x00\xa5"
+ "\xdf\x94\x87\xd0\x7a\x5c\x92\xcc"
+ "\x51\x2c\x88\x66\xc7\xe8\x60\xce"
+ "\x93\xfd\xf1\x66\xa2\x49\x12\xb4"
+ "\x22\x97\x61\x46\xae\x20\xce\x84"
+ "\x6b\xb7\xdc\x9b\xa9\x4a\x76\x7a"
+ "\xae\xf2\x0c\x0d\x61\xad\x02\x65"
+ "\x5e\xa9\x2d\xc4\xc4\xe4\x1a\x89"
+ "\x52\xc6\x51\xd3\x31\x74\xbe\x51"
+ "\xa1\x0c\x42\x11\x10\xe6\xd8\x15"
+ "\x88\xed\xe8\x21\x03\xa2\x52\xd8"
+ "\xa7\x50\xe8\x76\x8d\xef\xff\xed"
+ "\x91\x22\x81\x0a\xae\xb9\x9f\x91"
+ "\x72\xaf\x82\xb6\x04\xdc\x4b\x8e"
+ "\x51\xbc\xb0\x82\x35\xa6\xf4\x34"
+ "\x13\x32\xe4\xca\x60\x48\x2a\x4b"
+ "\xa1\xa0\x3b\x3e\x65\x00\x8f\xc5"
+ "\xda\x76\xb7\x0b\xf1\x69\x0d\xb4"
+ "\xea\xe2\x9c\x5f\x1b\xad\xd0\x3c"
+ "\x5c\xcf\x2a\x55\xd7\x05\xdd\xcd"
+ "\x86\xd4\x49\x51\x1c\xeb\x7e\xc3"
+ "\x0b\xf1\x2b\x1f\xa3\x5b\x91\x3f"
+ "\x9f\x74\x7a\x8a\xfd\x1b\x13\x0e"
+ "\x94\xbf\xf9\x4e\xff\xd0\x1a\x91"
+ "\x73\x5c\xa1\x72\x6a\xcd\x0b\x19"
+ "\x7c\x4e\x5b\x03\x39\x36\x97\xe1"
+ "\x26\x82\x6f\xb6\xbb\xde\x8e\xcc"
+ "\x1e\x08\x29\x85\x16\xe2\xc9\xed"
+ "\x03\xff\x3c\x1b\x78\x60\xf6\xde"
+ "\x76\xd4\xce\xcd\x94\xc8\x11\x98"
+ "\x55\xef\x52\x97\xca\x67\xe9\xf3"
+ "\xe7\xff\x72\xb1\xe9\x97\x85\xca"
+ "\x0a\x7e\x77\x20\xc5\xb3\x6d\xc6"
+ "\xd7\x2c\xac\x95\x74\xc8\xcb\xbc"
+ "\x2f\x80\x1e\x23\xe5\x6f\xd3\x44"
+ "\xb0\x7f\x22\x15\x4b\xeb\xa0\xf0"
+ "\x8c\xe8\x89\x1e\x64\x3e\xd9\x95"
+ "\xc9\x4d\x9a\x69\xc9\xf1\xb5\xf4"
+ "\x99\x02\x7a\x78\x57\x2a\xee\xbd"
+ "\x74\xd2\x0c\xc3\x98\x81\xc2\x13"
+ "\xee\x77\x0b\x10\x10\xe4\xbe\xa7"
+ "\x18\x84\x69\x77\xae\x11\x9f\x7a"
+ "\x02\x3a\xb5\x8c\xca\x0a\xd7\x52"
+ "\xaf\xe6\x56\xbb\x3c\x17\x25\x6a"
+ "\x9f\x6e\x9b\xf1\x9f\xdd\x5a\x38"
+ "\xfc\x82\xbb\xe8\x72\xc5\x53\x9e"
+ "\xdb\x60\x9e\xf4\xf7\x9c\x20\x3e"
+ "\xbb\x14\x0f\x2e\x58\x3c\xb2\xad"
+ "\x15\xb4\xaa\x5b\x65\x50\x16\xa8"
+ "\x44\x92\x77\xdb\xd4\x77\xef\x2c"
+ "\x8d\x6c\x01\x7d\xb7\x38\xb1\x8d"
+ "\xeb\x4a\x42\x7d\x19\x23\xce\x3f"
+ "\xf2\x62\x73\x57\x79\xa4\x18\xf2"
+ "\x0a\x28\x2d\xf9\x20\x14\x7b\xea"
+ "\xbe\x42\x1e\xe5\x31\x9d\x05\x68",
+ .rlen = 512,
+ }
+};
+
+static struct cipher_testvec aes_xts_dec_tv_template[] = {
+ /* http://grouper.ieee.org/groups/1619/email/pdf00086.pdf */
+ { /* XTS-AES 1 */
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x91\x7c\xf6\x9e\xbd\x68\xb2\xec"
+ "\x9b\x9f\xe9\xa3\xea\xdd\xa6\x92"
+ "\xcd\x43\xd2\xf5\x95\x98\xed\x85"
+ "\x8c\x02\xc2\x65\x2f\xbf\x92\x2e",
+ .ilen = 32,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .rlen = 32,
+ }, { /* XTS-AES 2 */
+ .key = "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\xc4\x54\x18\x5e\x6a\x16\x93\x6e"
+ "\x39\x33\x40\x38\xac\xef\x83\x8b"
+ "\xfb\x18\x6f\xff\x74\x80\xad\xc4"
+ "\x28\x93\x82\xec\xd6\xd3\x94\xf0",
+ .ilen = 32,
+ .result = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .rlen = 32,
+ }, { /* XTS-AES 3 */
+ .key = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
+ "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\xaf\x85\x33\x6b\x59\x7a\xfc\x1a"
+ "\x90\x0b\x2e\xb2\x1e\xc9\x49\xd2"
+ "\x92\xdf\x4c\x04\x7e\x0b\x21\x53"
+ "\x21\x86\xa5\x97\x1a\x22\x7a\x89",
+ .ilen = 32,
+ .result = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .rlen = 32,
+ }, { /* XTS-AES 4 */
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x27\xa7\x47\x9b\xef\xa1\xd4\x76"
+ "\x48\x9f\x30\x8c\xd4\xcf\xa6\xe2"
+ "\xa9\x6e\x4b\xbe\x32\x08\xff\x25"
+ "\x28\x7d\xd3\x81\x96\x16\xe8\x9c"
+ "\xc7\x8c\xf7\xf5\xe5\x43\x44\x5f"
+ "\x83\x33\xd8\xfa\x7f\x56\x00\x00"
+ "\x05\x27\x9f\xa5\xd8\xb5\xe4\xad"
+ "\x40\xe7\x36\xdd\xb4\xd3\x54\x12"
+ "\x32\x80\x63\xfd\x2a\xab\x53\xe5"
+ "\xea\x1e\x0a\x9f\x33\x25\x00\xa5"
+ "\xdf\x94\x87\xd0\x7a\x5c\x92\xcc"
+ "\x51\x2c\x88\x66\xc7\xe8\x60\xce"
+ "\x93\xfd\xf1\x66\xa2\x49\x12\xb4"
+ "\x22\x97\x61\x46\xae\x20\xce\x84"
+ "\x6b\xb7\xdc\x9b\xa9\x4a\x76\x7a"
+ "\xae\xf2\x0c\x0d\x61\xad\x02\x65"
+ "\x5e\xa9\x2d\xc4\xc4\xe4\x1a\x89"
+ "\x52\xc6\x51\xd3\x31\x74\xbe\x51"
+ "\xa1\x0c\x42\x11\x10\xe6\xd8\x15"
+ "\x88\xed\xe8\x21\x03\xa2\x52\xd8"
+ "\xa7\x50\xe8\x76\x8d\xef\xff\xed"
+ "\x91\x22\x81\x0a\xae\xb9\x9f\x91"
+ "\x72\xaf\x82\xb6\x04\xdc\x4b\x8e"
+ "\x51\xbc\xb0\x82\x35\xa6\xf4\x34"
+ "\x13\x32\xe4\xca\x60\x48\x2a\x4b"
+ "\xa1\xa0\x3b\x3e\x65\x00\x8f\xc5"
+ "\xda\x76\xb7\x0b\xf1\x69\x0d\xb4"
+ "\xea\xe2\x9c\x5f\x1b\xad\xd0\x3c"
+ "\x5c\xcf\x2a\x55\xd7\x05\xdd\xcd"
+ "\x86\xd4\x49\x51\x1c\xeb\x7e\xc3"
+ "\x0b\xf1\x2b\x1f\xa3\x5b\x91\x3f"
+ "\x9f\x74\x7a\x8a\xfd\x1b\x13\x0e"
+ "\x94\xbf\xf9\x4e\xff\xd0\x1a\x91"
+ "\x73\x5c\xa1\x72\x6a\xcd\x0b\x19"
+ "\x7c\x4e\x5b\x03\x39\x36\x97\xe1"
+ "\x26\x82\x6f\xb6\xbb\xde\x8e\xcc"
+ "\x1e\x08\x29\x85\x16\xe2\xc9\xed"
+ "\x03\xff\x3c\x1b\x78\x60\xf6\xde"
+ "\x76\xd4\xce\xcd\x94\xc8\x11\x98"
+ "\x55\xef\x52\x97\xca\x67\xe9\xf3"
+ "\xe7\xff\x72\xb1\xe9\x97\x85\xca"
+ "\x0a\x7e\x77\x20\xc5\xb3\x6d\xc6"
+ "\xd7\x2c\xac\x95\x74\xc8\xcb\xbc"
+ "\x2f\x80\x1e\x23\xe5\x6f\xd3\x44"
+ "\xb0\x7f\x22\x15\x4b\xeb\xa0\xf0"
+ "\x8c\xe8\x89\x1e\x64\x3e\xd9\x95"
+ "\xc9\x4d\x9a\x69\xc9\xf1\xb5\xf4"
+ "\x99\x02\x7a\x78\x57\x2a\xee\xbd"
+ "\x74\xd2\x0c\xc3\x98\x81\xc2\x13"
+ "\xee\x77\x0b\x10\x10\xe4\xbe\xa7"
+ "\x18\x84\x69\x77\xae\x11\x9f\x7a"
+ "\x02\x3a\xb5\x8c\xca\x0a\xd7\x52"
+ "\xaf\xe6\x56\xbb\x3c\x17\x25\x6a"
+ "\x9f\x6e\x9b\xf1\x9f\xdd\x5a\x38"
+ "\xfc\x82\xbb\xe8\x72\xc5\x53\x9e"
+ "\xdb\x60\x9e\xf4\xf7\x9c\x20\x3e"
+ "\xbb\x14\x0f\x2e\x58\x3c\xb2\xad"
+ "\x15\xb4\xaa\x5b\x65\x50\x16\xa8"
+ "\x44\x92\x77\xdb\xd4\x77\xef\x2c"
+ "\x8d\x6c\x01\x7d\xb7\x38\xb1\x8d"
+ "\xeb\x4a\x42\x7d\x19\x23\xce\x3f"
+ "\xf2\x62\x73\x57\x79\xa4\x18\xf2"
+ "\x0a\x28\x2d\xf9\x20\x14\x7b\xea"
+ "\xbe\x42\x1e\xe5\x31\x9d\x05\x68",
+ .ilen = 512,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .rlen = 512,
+ }
+};
+
+#endif
+
+static struct cipher_testvec aes_ctr_enc_tv_template[] = {
+ { /* From NIST Special Publication 800-38A, Appendix F.5 */
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
+ "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .klen = 16,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .ilen = 64,
+ .result = "\x87\x4d\x61\x91\xb6\x20\xe3\x26"
+ "\x1b\xef\x68\x64\x99\x0d\xb6\xce"
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff"
+ "\x86\x17\x18\x7b\xb9\xff\xfd\xff"
+ "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e"
+ "\x5b\x4f\x09\x02\x0d\xb0\x3e\xab"
+ "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1"
+ "\x79\x21\x70\xa0\xf3\x00\x9c\xee",
+ .rlen = 64,
+ }, {
+ .key = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+ "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ .klen = 24,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .ilen = 64,
+ .result = "\x1a\xbc\x93\x24\x17\x52\x1c\xa2"
+ "\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b"
+ "\x09\x03\x39\xec\x0a\xa6\xfa\xef"
+ "\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94"
+ "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70"
+ "\xd1\xbd\x1d\x66\x56\x20\xab\xf7"
+ "\x4f\x78\xa7\xf6\xd2\x98\x09\x58"
+ "\x5a\x97\xda\xec\x58\xc6\xb0\x50",
+ .rlen = 64,
+ }, {
+ .key = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+ "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+ "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ .klen = 32,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .ilen = 64,
+ .result = "\x60\x1e\xc3\x13\x77\x57\x89\xa5"
+ "\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28"
+ "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a"
+ "\xca\x84\xe9\x90\xca\xca\xf5\xc5"
+ "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c"
+ "\xe8\x70\x17\xba\x2d\x84\x98\x8d"
+ "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6"
+ "\x13\xc2\xdd\x08\x45\x79\x41\xa6",
+ .rlen = 64,
+ }
+};
+
+static struct cipher_testvec aes_ctr_dec_tv_template[] = {
+ { /* From NIST Special Publication 800-38A, Appendix F.5 */
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
+ "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .klen = 16,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x87\x4d\x61\x91\xb6\x20\xe3\x26"
+ "\x1b\xef\x68\x64\x99\x0d\xb6\xce"
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff"
+ "\x86\x17\x18\x7b\xb9\xff\xfd\xff"
+ "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e"
+ "\x5b\x4f\x09\x02\x0d\xb0\x3e\xab"
+ "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1"
+ "\x79\x21\x70\xa0\xf3\x00\x9c\xee",
+ .ilen = 64,
+ .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .rlen = 64,
+ }, {
+ .key = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+ "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ .klen = 24,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x1a\xbc\x93\x24\x17\x52\x1c\xa2"
+ "\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b"
+ "\x09\x03\x39\xec\x0a\xa6\xfa\xef"
+ "\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94"
+ "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70"
+ "\xd1\xbd\x1d\x66\x56\x20\xab\xf7"
+ "\x4f\x78\xa7\xf6\xd2\x98\x09\x58"
+ "\x5a\x97\xda\xec\x58\xc6\xb0\x50",
+ .ilen = 64,
+ .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .rlen = 64,
+ }, {
+ .key = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+ "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+ "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ .klen = 32,
+ .iv = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .input = "\x60\x1e\xc3\x13\x77\x57\x89\xa5"
+ "\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28"
+ "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a"
+ "\xca\x84\xe9\x90\xca\xca\xf5\xc5"
+ "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c"
+ "\xe8\x70\x17\xba\x2d\x84\x98\x8d"
+ "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6"
+ "\x13\xc2\xdd\x08\x45\x79\x41\xa6",
+ .ilen = 64,
+ .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .rlen = 64,
+ }
+};
+
+static struct cipher_testvec aes_ctr_rfc3686_enc_tv_template[] = {
+ { /* From RFC 3686 */
+ .key = "\xae\x68\x52\xf8\x12\x10\x67\xcc"
+ "\x4b\xf7\xa5\x76\x55\x77\xf3\x9e"
+ "\x00\x00\x00\x30",
+ .klen = 20,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "Single block msg",
+ .ilen = 16,
+ .result = "\xe4\x09\x5d\x4f\xb7\xa7\xb3\x79"
+ "\x2d\x61\x75\xa3\x26\x13\x11\xb8",
+ .rlen = 16,
+ }, {
+ .key = "\x7e\x24\x06\x78\x17\xfa\xe0\xd7"
+ "\x43\xd6\xce\x1f\x32\x53\x91\x63"
+ "\x00\x6c\xb6\xdb",
+ .klen = 20,
+ .iv = "\xc0\x54\x3b\x59\xda\x48\xd9\x0b",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .ilen = 32,
+ .result = "\x51\x04\xa1\x06\x16\x8a\x72\xd9"
+ "\x79\x0d\x41\xee\x8e\xda\xd3\x88"
+ "\xeb\x2e\x1e\xfc\x46\xda\x57\xc8"
+ "\xfc\xe6\x30\xdf\x91\x41\xbe\x28",
+ .rlen = 32,
+ }, {
+ .key = "\x16\xaf\x5b\x14\x5f\xc9\xf5\x79"
+ "\xc1\x75\xf9\x3e\x3b\xfb\x0e\xed"
+ "\x86\x3d\x06\xcc\xfd\xb7\x85\x15"
+ "\x00\x00\x00\x48",
+ .klen = 28,
+ .iv = "\x36\x73\x3c\x14\x7d\x6d\x93\xcb",
+ .input = "Single block msg",
+ .ilen = 16,
+ .result = "\x4b\x55\x38\x4f\xe2\x59\xc9\xc8"
+ "\x4e\x79\x35\xa0\x03\xcb\xe9\x28",
+ .rlen = 16,
+ }, {
+ .key = "\x7c\x5c\xb2\x40\x1b\x3d\xc3\x3c"
+ "\x19\xe7\x34\x08\x19\xe0\xf6\x9c"
+ "\x67\x8c\x3d\xb8\xe6\xf6\xa9\x1a"
+ "\x00\x96\xb0\x3b",
+ .klen = 28,
+ .iv = "\x02\x0c\x6e\xad\xc2\xcb\x50\x0d",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .ilen = 32,
+ .result = "\x45\x32\x43\xfc\x60\x9b\x23\x32"
+ "\x7e\xdf\xaa\xfa\x71\x31\xcd\x9f"
+ "\x84\x90\x70\x1c\x5a\xd4\xa7\x9c"
+ "\xfc\x1f\xe0\xff\x42\xf4\xfb\x00",
+ .rlen = 32,
+ }, {
+ .key = "\x77\x6b\xef\xf2\x85\x1d\xb0\x6f"
+ "\x4c\x8a\x05\x42\xc8\x69\x6f\x6c"
+ "\x6a\x81\xaf\x1e\xec\x96\xb4\xd3"
+ "\x7f\xc1\xd6\x89\xe6\xc1\xc1\x04"
+ "\x00\x00\x00\x60",
+ .klen = 36,
+ .iv = "\xdb\x56\x72\xc9\x7a\xa8\xf0\xb2",
+ .input = "Single block msg",
+ .ilen = 16,
+ .result = "\x14\x5a\xd0\x1d\xbf\x82\x4e\xc7"
+ "\x56\x08\x63\xdc\x71\xe3\xe0\xc0",
+ .rlen = 16,
+ }, {
+ .key = "\xf6\xd6\x6d\x6b\xd5\x2d\x59\xbb"
+ "\x07\x96\x36\x58\x79\xef\xf8\x86"
+ "\xc6\x6d\xd5\x1a\x5b\x6a\x99\x74"
+ "\x4b\x50\x59\x0c\x87\xa2\x38\x84"
+ "\x00\xfa\xac\x24",
+ .klen = 36,
+ .iv = "\xc1\x58\x5e\xf1\x5a\x43\xd8\x75",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .ilen = 32,
+ .result = "\xf0\x5e\x23\x1b\x38\x94\x61\x2c"
+ "\x49\xee\x00\x0b\x80\x4e\xb2\xa9"
+ "\xb8\x30\x6b\x50\x8f\x83\x9d\x6a"
+ "\x55\x30\x83\x1d\x93\x44\xaf\x1c",
+ .rlen = 32,
+ }, {
+#if 0
+ // generated using Crypto++
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x00\x00\x00\x00",
+ .klen = 32 + 4,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input =
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x03\x06\x09\x0c\x0f\x12\x15"
+ "\x18\x1b\x1e\x21\x24\x27\x2a\x2d"
+ "\x30\x33\x36\x39\x3c\x3f\x42\x45"
+ "\x48\x4b\x4e\x51\x54\x57\x5a\x5d"
+ "\x60\x63\x66\x69\x6c\x6f\x72\x75"
+ "\x78\x7b\x7e\x81\x84\x87\x8a\x8d"
+ "\x90\x93\x96\x99\x9c\x9f\xa2\xa5"
+ "\xa8\xab\xae\xb1\xb4\xb7\xba\xbd"
+ "\xc0\xc3\xc6\xc9\xcc\xcf\xd2\xd5"
+ "\xd8\xdb\xde\xe1\xe4\xe7\xea\xed"
+ "\xf0\xf3\xf6\xf9\xfc\xff\x02\x05"
+ "\x08\x0b\x0e\x11\x14\x17\x1a\x1d"
+ "\x20\x23\x26\x29\x2c\x2f\x32\x35"
+ "\x38\x3b\x3e\x41\x44\x47\x4a\x4d"
+ "\x50\x53\x56\x59\x5c\x5f\x62\x65"
+ "\x68\x6b\x6e\x71\x74\x77\x7a\x7d"
+ "\x80\x83\x86\x89\x8c\x8f\x92\x95"
+ "\x98\x9b\x9e\xa1\xa4\xa7\xaa\xad"
+ "\xb0\xb3\xb6\xb9\xbc\xbf\xc2\xc5"
+ "\xc8\xcb\xce\xd1\xd4\xd7\xda\xdd"
+ "\xe0\xe3\xe6\xe9\xec\xef\xf2\xf5"
+ "\xf8\xfb\xfe\x01\x04\x07\x0a\x0d"
+ "\x10\x13\x16\x19\x1c\x1f\x22\x25"
+ "\x28\x2b\x2e\x31\x34\x37\x3a\x3d"
+ "\x40\x43\x46\x49\x4c\x4f\x52\x55"
+ "\x58\x5b\x5e\x61\x64\x67\x6a\x6d"
+ "\x70\x73\x76\x79\x7c\x7f\x82\x85"
+ "\x88\x8b\x8e\x91\x94\x97\x9a\x9d"
+ "\xa0\xa3\xa6\xa9\xac\xaf\xb2\xb5"
+ "\xb8\xbb\xbe\xc1\xc4\xc7\xca\xcd"
+ "\xd0\xd3\xd6\xd9\xdc\xdf\xe2\xe5"
+ "\xe8\xeb\xee\xf1\xf4\xf7\xfa\xfd"
+ "\x00\x05\x0a\x0f\x14\x19\x1e\x23"
+ "\x28\x2d\x32\x37\x3c\x41\x46\x4b"
+ "\x50\x55\x5a\x5f\x64\x69\x6e\x73"
+ "\x78\x7d\x82\x87\x8c\x91\x96\x9b"
+ "\xa0\xa5\xaa\xaf\xb4\xb9\xbe\xc3"
+ "\xc8\xcd\xd2\xd7\xdc\xe1\xe6\xeb"
+ "\xf0\xf5\xfa\xff\x04\x09\x0e\x13"
+ "\x18\x1d\x22\x27\x2c\x31\x36\x3b"
+ "\x40\x45\x4a\x4f\x54\x59\x5e\x63"
+ "\x68\x6d\x72\x77\x7c\x81\x86\x8b"
+ "\x90\x95\x9a\x9f\xa4\xa9\xae\xb3"
+ "\xb8\xbd\xc2\xc7\xcc\xd1\xd6\xdb"
+ "\xe0\xe5\xea\xef\xf4\xf9\xfe\x03"
+ "\x08\x0d\x12\x17\x1c\x21\x26\x2b"
+ "\x30\x35\x3a\x3f\x44\x49\x4e\x53"
+ "\x58\x5d\x62\x67\x6c\x71\x76\x7b"
+ "\x80\x85\x8a\x8f\x94\x99\x9e\xa3"
+ "\xa8\xad\xb2\xb7\xbc\xc1\xc6\xcb"
+ "\xd0\xd5\xda\xdf\xe4\xe9\xee\xf3"
+ "\xf8\xfd\x02\x07\x0c\x11\x16\x1b"
+ "\x20\x25\x2a\x2f\x34\x39\x3e\x43"
+ "\x48\x4d\x52\x57\x5c\x61\x66\x6b"
+ "\x70\x75\x7a\x7f\x84\x89\x8e\x93"
+ "\x98\x9d\xa2\xa7\xac\xb1\xb6\xbb"
+ "\xc0\xc5\xca\xcf\xd4\xd9\xde\xe3"
+ "\xe8\xed\xf2\xf7\xfc\x01\x06\x0b"
+ "\x10\x15\x1a\x1f\x24\x29\x2e\x33"
+ "\x38\x3d\x42\x47\x4c\x51\x56\x5b"
+ "\x60\x65\x6a\x6f\x74\x79\x7e\x83"
+ "\x88\x8d\x92\x97\x9c\xa1\xa6\xab"
+ "\xb0\xb5\xba\xbf\xc4\xc9\xce\xd3"
+ "\xd8\xdd\xe2\xe7\xec\xf1\xf6\xfb"
+ "\x00\x07\x0e\x15\x1c\x23\x2a\x31"
+ "\x38\x3f\x46\x4d\x54\x5b\x62\x69"
+ "\x70\x77\x7e\x85\x8c\x93\x9a\xa1"
+ "\xa8\xaf\xb6\xbd\xc4\xcb\xd2\xd9"
+ "\xe0\xe7\xee\xf5\xfc\x03\x0a\x11"
+ "\x18\x1f\x26\x2d\x34\x3b\x42\x49"
+ "\x50\x57\x5e\x65\x6c\x73\x7a\x81"
+ "\x88\x8f\x96\x9d\xa4\xab\xb2\xb9"
+ "\xc0\xc7\xce\xd5\xdc\xe3\xea\xf1"
+ "\xf8\xff\x06\x0d\x14\x1b\x22\x29"
+ "\x30\x37\x3e\x45\x4c\x53\x5a\x61"
+ "\x68\x6f\x76\x7d\x84\x8b\x92\x99"
+ "\xa0\xa7\xae\xb5\xbc\xc3\xca\xd1"
+ "\xd8\xdf\xe6\xed\xf4\xfb\x02\x09"
+ "\x10\x17\x1e\x25\x2c\x33\x3a\x41"
+ "\x48\x4f\x56\x5d\x64\x6b\x72\x79"
+ "\x80\x87\x8e\x95\x9c\xa3\xaa\xb1"
+ "\xb8\xbf\xc6\xcd\xd4\xdb\xe2\xe9"
+ "\xf0\xf7\xfe\x05\x0c\x13\x1a\x21"
+ "\x28\x2f\x36\x3d\x44\x4b\x52\x59"
+ "\x60\x67\x6e\x75\x7c\x83\x8a\x91"
+ "\x98\x9f\xa6\xad\xb4\xbb\xc2\xc9"
+ "\xd0\xd7\xde\xe5\xec\xf3\xfa\x01"
+ "\x08\x0f\x16\x1d\x24\x2b\x32\x39"
+ "\x40\x47\x4e\x55\x5c\x63\x6a\x71"
+ "\x78\x7f\x86\x8d\x94\x9b\xa2\xa9"
+ "\xb0\xb7\xbe\xc5\xcc\xd3\xda\xe1"
+ "\xe8\xef\xf6\xfd\x04\x0b\x12\x19"
+ "\x20\x27\x2e\x35\x3c\x43\x4a\x51"
+ "\x58\x5f\x66\x6d\x74\x7b\x82\x89"
+ "\x90\x97\x9e\xa5\xac\xb3\xba\xc1"
+ "\xc8\xcf\xd6\xdd\xe4\xeb\xf2\xf9"
+ "\x00\x09\x12\x1b\x24\x2d\x36\x3f"
+ "\x48\x51\x5a\x63\x6c\x75\x7e\x87"
+ "\x90\x99\xa2\xab\xb4\xbd\xc6\xcf"
+ "\xd8\xe1\xea\xf3\xfc\x05\x0e\x17"
+ "\x20\x29\x32\x3b\x44\x4d\x56\x5f"
+ "\x68\x71\x7a\x83\x8c\x95\x9e\xa7"
+ "\xb0\xb9\xc2\xcb\xd4\xdd\xe6\xef"
+ "\xf8\x01\x0a\x13\x1c\x25\x2e\x37"
+ "\x40\x49\x52\x5b\x64\x6d\x76\x7f"
+ "\x88\x91\x9a\xa3\xac\xb5\xbe\xc7"
+ "\xd0\xd9\xe2\xeb\xf4\xfd\x06\x0f"
+ "\x18\x21\x2a\x33\x3c\x45\x4e\x57"
+ "\x60\x69\x72\x7b\x84\x8d\x96\x9f"
+ "\xa8\xb1\xba\xc3\xcc\xd5\xde\xe7"
+ "\xf0\xf9\x02\x0b\x14\x1d\x26\x2f"
+ "\x38\x41\x4a\x53\x5c\x65\x6e\x77"
+ "\x80\x89\x92\x9b\xa4\xad\xb6\xbf"
+ "\xc8\xd1\xda\xe3\xec\xf5\xfe\x07"
+ "\x10\x19\x22\x2b\x34\x3d\x46\x4f"
+ "\x58\x61\x6a\x73\x7c\x85\x8e\x97"
+ "\xa0\xa9\xb2\xbb\xc4\xcd\xd6\xdf"
+ "\xe8\xf1\xfa\x03\x0c\x15\x1e\x27"
+ "\x30\x39\x42\x4b\x54\x5d\x66\x6f"
+ "\x78\x81\x8a\x93\x9c\xa5\xae\xb7"
+ "\xc0\xc9\xd2\xdb\xe4\xed\xf6\xff"
+ "\x08\x11\x1a\x23\x2c\x35\x3e\x47"
+ "\x50\x59\x62\x6b\x74\x7d\x86\x8f"
+ "\x98\xa1\xaa\xb3\xbc\xc5\xce\xd7"
+ "\xe0\xe9\xf2\xfb\x04\x0d\x16\x1f"
+ "\x28\x31\x3a\x43\x4c\x55\x5e\x67"
+ "\x70\x79\x82\x8b\x94\x9d\xa6\xaf"
+ "\xb8\xc1\xca\xd3\xdc\xe5\xee\xf7"
+ "\x00\x0b\x16\x21\x2c\x37\x42\x4d"
+ "\x58\x63\x6e\x79\x84\x8f\x9a\xa5"
+ "\xb0\xbb\xc6\xd1\xdc\xe7\xf2\xfd"
+ "\x08\x13\x1e\x29\x34\x3f\x4a\x55"
+ "\x60\x6b\x76\x81\x8c\x97\xa2\xad"
+ "\xb8\xc3\xce\xd9\xe4\xef\xfa\x05"
+ "\x10\x1b\x26\x31\x3c\x47\x52\x5d"
+ "\x68\x73\x7e\x89\x94\x9f\xaa\xb5"
+ "\xc0\xcb\xd6\xe1\xec\xf7\x02\x0d"
+ "\x18\x23\x2e\x39\x44\x4f\x5a\x65"
+ "\x70\x7b\x86\x91\x9c\xa7\xb2\xbd"
+ "\xc8\xd3\xde\xe9\xf4\xff\x0a\x15"
+ "\x20\x2b\x36\x41\x4c\x57\x62\x6d"
+ "\x78\x83\x8e\x99\xa4\xaf\xba\xc5"
+ "\xd0\xdb\xe6\xf1\xfc\x07\x12\x1d"
+ "\x28\x33\x3e\x49\x54\x5f\x6a\x75"
+ "\x80\x8b\x96\xa1\xac\xb7\xc2\xcd"
+ "\xd8\xe3\xee\xf9\x04\x0f\x1a\x25"
+ "\x30\x3b\x46\x51\x5c\x67\x72\x7d"
+ "\x88\x93\x9e\xa9\xb4\xbf\xca\xd5"
+ "\xe0\xeb\xf6\x01\x0c\x17\x22\x2d"
+ "\x38\x43\x4e\x59\x64\x6f\x7a\x85"
+ "\x90\x9b\xa6\xb1\xbc\xc7\xd2\xdd"
+ "\xe8\xf3\xfe\x09\x14\x1f\x2a\x35"
+ "\x40\x4b\x56\x61\x6c\x77\x82\x8d"
+ "\x98\xa3\xae\xb9\xc4\xcf\xda\xe5"
+ "\xf0\xfb\x06\x11\x1c\x27\x32\x3d"
+ "\x48\x53\x5e\x69\x74\x7f\x8a\x95"
+ "\xa0\xab\xb6\xc1\xcc\xd7\xe2\xed"
+ "\xf8\x03\x0e\x19\x24\x2f\x3a\x45"
+ "\x50\x5b\x66\x71\x7c\x87\x92\x9d"
+ "\xa8\xb3\xbe\xc9\xd4\xdf\xea\xf5"
+ "\x00\x0d\x1a\x27\x34\x41\x4e\x5b"
+ "\x68\x75\x82\x8f\x9c\xa9\xb6\xc3"
+ "\xd0\xdd\xea\xf7\x04\x11\x1e\x2b"
+ "\x38\x45\x52\x5f\x6c\x79\x86\x93"
+ "\xa0\xad\xba\xc7\xd4\xe1\xee\xfb"
+ "\x08\x15\x22\x2f\x3c\x49\x56\x63"
+ "\x70\x7d\x8a\x97\xa4\xb1\xbe\xcb"
+ "\xd8\xe5\xf2\xff\x0c\x19\x26\x33"
+ "\x40\x4d\x5a\x67\x74\x81\x8e\x9b"
+ "\xa8\xb5\xc2\xcf\xdc\xe9\xf6\x03"
+ "\x10\x1d\x2a\x37\x44\x51\x5e\x6b"
+ "\x78\x85\x92\x9f\xac\xb9\xc6\xd3"
+ "\xe0\xed\xfa\x07\x14\x21\x2e\x3b"
+ "\x48\x55\x62\x6f\x7c\x89\x96\xa3"
+ "\xb0\xbd\xca\xd7\xe4\xf1\xfe\x0b"
+ "\x18\x25\x32\x3f\x4c\x59\x66\x73"
+ "\x80\x8d\x9a\xa7\xb4\xc1\xce\xdb"
+ "\xe8\xf5\x02\x0f\x1c\x29\x36\x43"
+ "\x50\x5d\x6a\x77\x84\x91\x9e\xab"
+ "\xb8\xc5\xd2\xdf\xec\xf9\x06\x13"
+ "\x20\x2d\x3a\x47\x54\x61\x6e\x7b"
+ "\x88\x95\xa2\xaf\xbc\xc9\xd6\xe3"
+ "\xf0\xfd\x0a\x17\x24\x31\x3e\x4b"
+ "\x58\x65\x72\x7f\x8c\x99\xa6\xb3"
+ "\xc0\xcd\xda\xe7\xf4\x01\x0e\x1b"
+ "\x28\x35\x42\x4f\x5c\x69\x76\x83"
+ "\x90\x9d\xaa\xb7\xc4\xd1\xde\xeb"
+ "\xf8\x05\x12\x1f\x2c\x39\x46\x53"
+ "\x60\x6d\x7a\x87\x94\xa1\xae\xbb"
+ "\xc8\xd5\xe2\xef\xfc\x09\x16\x23"
+ "\x30\x3d\x4a\x57\x64\x71\x7e\x8b"
+ "\x98\xa5\xb2\xbf\xcc\xd9\xe6\xf3"
+ "\x00\x0f\x1e\x2d\x3c\x4b\x5a\x69"
+ "\x78\x87\x96\xa5\xb4\xc3\xd2\xe1"
+ "\xf0\xff\x0e\x1d\x2c\x3b\x4a\x59"
+ "\x68\x77\x86\x95\xa4\xb3\xc2\xd1"
+ "\xe0\xef\xfe\x0d\x1c\x2b\x3a\x49"
+ "\x58\x67\x76\x85\x94\xa3\xb2\xc1"
+ "\xd0\xdf\xee\xfd\x0c\x1b\x2a\x39"
+ "\x48\x57\x66\x75\x84\x93\xa2\xb1"
+ "\xc0\xcf\xde\xed\xfc\x0b\x1a\x29"
+ "\x38\x47\x56\x65\x74\x83\x92\xa1"
+ "\xb0\xbf\xce\xdd\xec\xfb\x0a\x19"
+ "\x28\x37\x46\x55\x64\x73\x82\x91"
+ "\xa0\xaf\xbe\xcd\xdc\xeb\xfa\x09"
+ "\x18\x27\x36\x45\x54\x63\x72\x81"
+ "\x90\x9f\xae\xbd\xcc\xdb\xea\xf9"
+ "\x08\x17\x26\x35\x44\x53\x62\x71"
+ "\x80\x8f\x9e\xad\xbc\xcb\xda\xe9"
+ "\xf8\x07\x16\x25\x34\x43\x52\x61"
+ "\x70\x7f\x8e\x9d\xac\xbb\xca\xd9"
+ "\xe8\xf7\x06\x15\x24\x33\x42\x51"
+ "\x60\x6f\x7e\x8d\x9c\xab\xba\xc9"
+ "\xd8\xe7\xf6\x05\x14\x23\x32\x41"
+ "\x50\x5f\x6e\x7d\x8c\x9b\xaa\xb9"
+ "\xc8\xd7\xe6\xf5\x04\x13\x22\x31"
+ "\x40\x4f\x5e\x6d\x7c\x8b\x9a\xa9"
+ "\xb8\xc7\xd6\xe5\xf4\x03\x12\x21"
+ "\x30\x3f\x4e\x5d\x6c\x7b\x8a\x99"
+ "\xa8\xb7\xc6\xd5\xe4\xf3\x02\x11"
+ "\x20\x2f\x3e\x4d\x5c\x6b\x7a\x89"
+ "\x98\xa7\xb6\xc5\xd4\xe3\xf2\x01"
+ "\x10\x1f\x2e\x3d\x4c\x5b\x6a\x79"
+ "\x88\x97\xa6\xb5\xc4\xd3\xe2\xf1"
+ "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
+ "\x10\x21\x32\x43\x54\x65\x76\x87"
+ "\x98\xa9\xba\xcb\xdc\xed\xfe\x0f"
+ "\x20\x31\x42\x53\x64\x75\x86\x97"
+ "\xa8\xb9\xca\xdb\xec\xfd\x0e\x1f"
+ "\x30\x41\x52\x63\x74\x85\x96\xa7"
+ "\xb8\xc9\xda\xeb\xfc\x0d\x1e\x2f"
+ "\x40\x51\x62\x73\x84\x95\xa6\xb7"
+ "\xc8\xd9\xea\xfb\x0c\x1d\x2e\x3f"
+ "\x50\x61\x72\x83\x94\xa5\xb6\xc7"
+ "\xd8\xe9\xfa\x0b\x1c\x2d\x3e\x4f"
+ "\x60\x71\x82\x93\xa4\xb5\xc6\xd7"
+ "\xe8\xf9\x0a\x1b\x2c\x3d\x4e\x5f"
+ "\x70\x81\x92\xa3\xb4\xc5\xd6\xe7"
+ "\xf8\x09\x1a\x2b\x3c\x4d\x5e\x6f"
+ "\x80\x91\xa2\xb3\xc4\xd5\xe6\xf7"
+ "\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f"
+ "\x90\xa1\xb2\xc3\xd4\xe5\xf6\x07"
+ "\x18\x29\x3a\x4b\x5c\x6d\x7e\x8f"
+ "\xa0\xb1\xc2\xd3\xe4\xf5\x06\x17"
+ "\x28\x39\x4a\x5b\x6c\x7d\x8e\x9f"
+ "\xb0\xc1\xd2\xe3\xf4\x05\x16\x27"
+ "\x38\x49\x5a\x6b\x7c\x8d\x9e\xaf"
+ "\xc0\xd1\xe2\xf3\x04\x15\x26\x37"
+ "\x48\x59\x6a\x7b\x8c\x9d\xae\xbf"
+ "\xd0\xe1\xf2\x03\x14\x25\x36\x47"
+ "\x58\x69\x7a\x8b\x9c\xad\xbe\xcf"
+ "\xe0\xf1\x02\x13\x24\x35\x46\x57"
+ "\x68\x79\x8a\x9b\xac\xbd\xce\xdf"
+ "\xf0\x01\x12\x23\x34\x45\x56\x67"
+ "\x78\x89\x9a\xab\xbc\xcd\xde\xef"
+ "\x00\x13\x26\x39\x4c\x5f\x72\x85"
+ "\x98\xab\xbe\xd1\xe4\xf7\x0a\x1d"
+ "\x30\x43\x56\x69\x7c\x8f\xa2\xb5"
+ "\xc8\xdb\xee\x01\x14\x27\x3a\x4d"
+ "\x60\x73\x86\x99\xac\xbf\xd2\xe5"
+ "\xf8\x0b\x1e\x31\x44\x57\x6a\x7d"
+ "\x90\xa3\xb6\xc9\xdc\xef\x02\x15"
+ "\x28\x3b\x4e\x61\x74\x87\x9a\xad"
+ "\xc0\xd3\xe6\xf9\x0c\x1f\x32\x45"
+ "\x58\x6b\x7e\x91\xa4\xb7\xca\xdd"
+ "\xf0\x03\x16\x29\x3c\x4f\x62\x75"
+ "\x88\x9b\xae\xc1\xd4\xe7\xfa\x0d"
+ "\x20\x33\x46\x59\x6c\x7f\x92\xa5"
+ "\xb8\xcb\xde\xf1\x04\x17\x2a\x3d"
+ "\x50\x63\x76\x89\x9c\xaf\xc2\xd5"
+ "\xe8\xfb\x0e\x21\x34\x47\x5a\x6d"
+ "\x80\x93\xa6\xb9\xcc\xdf\xf2\x05"
+ "\x18\x2b\x3e\x51\x64\x77\x8a\x9d"
+ "\xb0\xc3\xd6\xe9\xfc\x0f\x22\x35"
+ "\x48\x5b\x6e\x81\x94\xa7\xba\xcd"
+ "\xe0\xf3\x06\x19\x2c\x3f\x52\x65"
+ "\x78\x8b\x9e\xb1\xc4\xd7\xea\xfd"
+ "\x10\x23\x36\x49\x5c\x6f\x82\x95"
+ "\xa8\xbb\xce\xe1\xf4\x07\x1a\x2d"
+ "\x40\x53\x66\x79\x8c\x9f\xb2\xc5"
+ "\xd8\xeb\xfe\x11\x24\x37\x4a\x5d"
+ "\x70\x83\x96\xa9\xbc\xcf\xe2\xf5"
+ "\x08\x1b\x2e\x41\x54\x67\x7a\x8d"
+ "\xa0\xb3\xc6\xd9\xec\xff\x12\x25"
+ "\x38\x4b\x5e\x71\x84\x97\xaa\xbd"
+ "\xd0\xe3\xf6\x09\x1c\x2f\x42\x55"
+ "\x68\x7b\x8e\xa1\xb4\xc7\xda\xed"
+ "\x00\x15\x2a\x3f\x54\x69\x7e\x93"
+ "\xa8\xbd\xd2\xe7\xfc\x11\x26\x3b"
+ "\x50\x65\x7a\x8f\xa4\xb9\xce\xe3"
+ "\xf8\x0d\x22\x37\x4c\x61\x76\x8b"
+ "\xa0\xb5\xca\xdf\xf4\x09\x1e\x33"
+ "\x48\x5d\x72\x87\x9c\xb1\xc6\xdb"
+ "\xf0\x05\x1a\x2f\x44\x59\x6e\x83"
+ "\x98\xad\xc2\xd7\xec\x01\x16\x2b"
+ "\x40\x55\x6a\x7f\x94\xa9\xbe\xd3"
+ "\xe8\xfd\x12\x27\x3c\x51\x66\x7b"
+ "\x90\xa5\xba\xcf\xe4\xf9\x0e\x23"
+ "\x38\x4d\x62\x77\x8c\xa1\xb6\xcb"
+ "\xe0\xf5\x0a\x1f\x34\x49\x5e\x73"
+ "\x88\x9d\xb2\xc7\xdc\xf1\x06\x1b"
+ "\x30\x45\x5a\x6f\x84\x99\xae\xc3"
+ "\xd8\xed\x02\x17\x2c\x41\x56\x6b"
+ "\x80\x95\xaa\xbf\xd4\xe9\xfe\x13"
+ "\x28\x3d\x52\x67\x7c\x91\xa6\xbb"
+ "\xd0\xe5\xfa\x0f\x24\x39\x4e\x63"
+ "\x78\x8d\xa2\xb7\xcc\xe1\xf6\x0b"
+ "\x20\x35\x4a\x5f\x74\x89\x9e\xb3"
+ "\xc8\xdd\xf2\x07\x1c\x31\x46\x5b"
+ "\x70\x85\x9a\xaf\xc4\xd9\xee\x03"
+ "\x18\x2d\x42\x57\x6c\x81\x96\xab"
+ "\xc0\xd5\xea\xff\x14\x29\x3e\x53"
+ "\x68\x7d\x92\xa7\xbc\xd1\xe6\xfb"
+ "\x10\x25\x3a\x4f\x64\x79\x8e\xa3"
+ "\xb8\xcd\xe2\xf7\x0c\x21\x36\x4b"
+ "\x60\x75\x8a\x9f\xb4\xc9\xde\xf3"
+ "\x08\x1d\x32\x47\x5c\x71\x86\x9b"
+ "\xb0\xc5\xda\xef\x04\x19\x2e\x43"
+ "\x58\x6d\x82\x97\xac\xc1\xd6\xeb"
+ "\x00\x17\x2e\x45\x5c\x73\x8a\xa1"
+ "\xb8\xcf\xe6\xfd\x14\x2b\x42\x59"
+ "\x70\x87\x9e\xb5\xcc\xe3\xfa\x11"
+ "\x28\x3f\x56\x6d\x84\x9b\xb2\xc9"
+ "\xe0\xf7\x0e\x25\x3c\x53\x6a\x81"
+ "\x98\xaf\xc6\xdd\xf4\x0b\x22\x39"
+ "\x50\x67\x7e\x95\xac\xc3\xda\xf1"
+ "\x08\x1f\x36\x4d\x64\x7b\x92\xa9"
+ "\xc0\xd7\xee\x05\x1c\x33\x4a\x61"
+ "\x78\x8f\xa6\xbd\xd4\xeb\x02\x19"
+ "\x30\x47\x5e\x75\x8c\xa3\xba\xd1"
+ "\xe8\xff\x16\x2d\x44\x5b\x72\x89"
+ "\xa0\xb7\xce\xe5\xfc\x13\x2a\x41"
+ "\x58\x6f\x86\x9d\xb4\xcb\xe2\xf9"
+ "\x10\x27\x3e\x55\x6c\x83\x9a\xb1"
+ "\xc8\xdf\xf6\x0d\x24\x3b\x52\x69"
+ "\x80\x97\xae\xc5\xdc\xf3\x0a\x21"
+ "\x38\x4f\x66\x7d\x94\xab\xc2\xd9"
+ "\xf0\x07\x1e\x35\x4c\x63\x7a\x91"
+ "\xa8\xbf\xd6\xed\x04\x1b\x32\x49"
+ "\x60\x77\x8e\xa5\xbc\xd3\xea\x01"
+ "\x18\x2f\x46\x5d\x74\x8b\xa2\xb9"
+ "\xd0\xe7\xfe\x15\x2c\x43\x5a\x71"
+ "\x88\x9f\xb6\xcd\xe4\xfb\x12\x29"
+ "\x40\x57\x6e\x85\x9c\xb3\xca\xe1"
+ "\xf8\x0f\x26\x3d\x54\x6b\x82\x99"
+ "\xb0\xc7\xde\xf5\x0c\x23\x3a\x51"
+ "\x68\x7f\x96\xad\xc4\xdb\xf2\x09"
+ "\x20\x37\x4e\x65\x7c\x93\xaa\xc1"
+ "\xd8\xef\x06\x1d\x34\x4b\x62\x79"
+ "\x90\xa7\xbe\xd5\xec\x03\x1a\x31"
+ "\x48\x5f\x76\x8d\xa4\xbb\xd2\xe9"
+ "\x00\x19\x32\x4b\x64\x7d\x96\xaf"
+ "\xc8\xe1\xfa\x13\x2c\x45\x5e\x77"
+ "\x90\xa9\xc2\xdb\xf4\x0d\x26\x3f"
+ "\x58\x71\x8a\xa3\xbc\xd5\xee\x07"
+ "\x20\x39\x52\x6b\x84\x9d\xb6\xcf"
+ "\xe8\x01\x1a\x33\x4c\x65\x7e\x97"
+ "\xb0\xc9\xe2\xfb\x14\x2d\x46\x5f"
+ "\x78\x91\xaa\xc3\xdc\xf5\x0e\x27"
+ "\x40\x59\x72\x8b\xa4\xbd\xd6\xef"
+ "\x08\x21\x3a\x53\x6c\x85\x9e\xb7"
+ "\xd0\xe9\x02\x1b\x34\x4d\x66\x7f"
+ "\x98\xb1\xca\xe3\xfc\x15\x2e\x47"
+ "\x60\x79\x92\xab\xc4\xdd\xf6\x0f"
+ "\x28\x41\x5a\x73\x8c\xa5\xbe\xd7"
+ "\xf0\x09\x22\x3b\x54\x6d\x86\x9f"
+ "\xb8\xd1\xea\x03\x1c\x35\x4e\x67"
+ "\x80\x99\xb2\xcb\xe4\xfd\x16\x2f"
+ "\x48\x61\x7a\x93\xac\xc5\xde\xf7"
+ "\x10\x29\x42\x5b\x74\x8d\xa6\xbf"
+ "\xd8\xf1\x0a\x23\x3c\x55\x6e\x87"
+ "\xa0\xb9\xd2\xeb\x04\x1d\x36\x4f"
+ "\x68\x81\x9a\xb3\xcc\xe5\xfe\x17"
+ "\x30\x49\x62\x7b\x94\xad\xc6\xdf"
+ "\xf8\x11\x2a\x43\x5c\x75\x8e\xa7"
+ "\xc0\xd9\xf2\x0b\x24\x3d\x56\x6f"
+ "\x88\xa1\xba\xd3\xec\x05\x1e\x37"
+ "\x50\x69\x82\x9b\xb4\xcd\xe6\xff"
+ "\x18\x31\x4a\x63\x7c\x95\xae\xc7"
+ "\xe0\xf9\x12\x2b\x44\x5d\x76\x8f"
+ "\xa8\xc1\xda\xf3\x0c\x25\x3e\x57"
+ "\x70\x89\xa2\xbb\xd4\xed\x06\x1f"
+ "\x38\x51\x6a\x83\x9c\xb5\xce\xe7"
+ "\x00\x1b\x36\x51\x6c\x87\xa2\xbd"
+ "\xd8\xf3\x0e\x29\x44\x5f\x7a\x95"
+ "\xb0\xcb\xe6\x01\x1c\x37\x52\x6d"
+ "\x88\xa3\xbe\xd9\xf4\x0f\x2a\x45"
+ "\x60\x7b\x96\xb1\xcc\xe7\x02\x1d"
+ "\x38\x53\x6e\x89\xa4\xbf\xda\xf5"
+ "\x10\x2b\x46\x61\x7c\x97\xb2\xcd"
+ "\xe8\x03\x1e\x39\x54\x6f\x8a\xa5"
+ "\xc0\xdb\xf6\x11\x2c\x47\x62\x7d"
+ "\x98\xb3\xce\xe9\x04\x1f\x3a\x55"
+ "\x70\x8b\xa6\xc1\xdc\xf7\x12\x2d"
+ "\x48\x63\x7e\x99\xb4\xcf\xea\x05"
+ "\x20\x3b\x56\x71\x8c\xa7\xc2\xdd"
+ "\xf8\x13\x2e\x49\x64\x7f\x9a\xb5"
+ "\xd0\xeb\x06\x21\x3c\x57\x72\x8d"
+ "\xa8\xc3\xde\xf9\x14\x2f\x4a\x65"
+ "\x80\x9b\xb6\xd1\xec\x07\x22\x3d"
+ "\x58\x73\x8e\xa9\xc4\xdf\xfa\x15"
+ "\x30\x4b\x66\x81\x9c\xb7\xd2\xed"
+ "\x08\x23\x3e\x59\x74\x8f\xaa\xc5"
+ "\xe0\xfb\x16\x31\x4c\x67\x82\x9d"
+ "\xb8\xd3\xee\x09\x24\x3f\x5a\x75"
+ "\x90\xab\xc6\xe1\xfc\x17\x32\x4d"
+ "\x68\x83\x9e\xb9\xd4\xef\x0a\x25"
+ "\x40\x5b\x76\x91\xac\xc7\xe2\xfd"
+ "\x18\x33\x4e\x69\x84\x9f\xba\xd5"
+ "\xf0\x0b\x26\x41\x5c\x77\x92\xad"
+ "\xc8\xe3\xfe\x19\x34\x4f\x6a\x85"
+ "\xa0\xbb\xd6\xf1\x0c\x27\x42\x5d"
+ "\x78\x93\xae\xc9\xe4\xff\x1a\x35"
+ "\x50\x6b\x86\xa1\xbc\xd7\xf2\x0d"
+ "\x28\x43\x5e\x79\x94\xaf\xca\xe5"
+ "\x00\x1d\x3a\x57\x74\x91\xae\xcb"
+ "\xe8\x05\x22\x3f\x5c\x79\x96\xb3"
+ "\xd0\xed\x0a\x27\x44\x61\x7e\x9b"
+ "\xb8\xd5\xf2\x0f\x2c\x49\x66\x83"
+ "\xa0\xbd\xda\xf7\x14\x31\x4e\x6b"
+ "\x88\xa5\xc2\xdf\xfc\x19\x36\x53"
+ "\x70\x8d\xaa\xc7\xe4\x01\x1e\x3b"
+ "\x58\x75\x92\xaf\xcc\xe9\x06\x23"
+ "\x40\x5d\x7a\x97\xb4\xd1\xee\x0b"
+ "\x28\x45\x62\x7f\x9c\xb9\xd6\xf3"
+ "\x10\x2d\x4a\x67\x84\xa1\xbe\xdb"
+ "\xf8\x15\x32\x4f\x6c\x89\xa6\xc3"
+ "\xe0\xfd\x1a\x37\x54\x71\x8e\xab"
+ "\xc8\xe5\x02\x1f\x3c\x59\x76\x93"
+ "\xb0\xcd\xea\x07\x24\x41\x5e\x7b"
+ "\x98\xb5\xd2\xef\x0c\x29\x46\x63"
+ "\x80\x9d\xba\xd7\xf4\x11\x2e\x4b"
+ "\x68\x85\xa2\xbf\xdc\xf9\x16\x33"
+ "\x50\x6d\x8a\xa7\xc4\xe1\xfe\x1b"
+ "\x38\x55\x72\x8f\xac\xc9\xe6\x03"
+ "\x20\x3d\x5a\x77\x94\xb1\xce\xeb"
+ "\x08\x25\x42\x5f\x7c\x99\xb6\xd3"
+ "\xf0\x0d\x2a\x47\x64\x81\x9e\xbb"
+ "\xd8\xf5\x12\x2f\x4c\x69\x86\xa3"
+ "\xc0\xdd\xfa\x17\x34\x51\x6e\x8b"
+ "\xa8\xc5\xe2\xff\x1c\x39\x56\x73"
+ "\x90\xad\xca\xe7\x04\x21\x3e\x5b"
+ "\x78\x95\xb2\xcf\xec\x09\x26\x43"
+ "\x60\x7d\x9a\xb7\xd4\xf1\x0e\x2b"
+ "\x48\x65\x82\x9f\xbc\xd9\xf6\x13"
+ "\x30\x4d\x6a\x87\xa4\xc1\xde\xfb"
+ "\x18\x35\x52\x6f\x8c\xa9\xc6\xe3"
+ "\x00\x1f\x3e\x5d\x7c\x9b\xba\xd9"
+ "\xf8\x17\x36\x55\x74\x93\xb2\xd1"
+ "\xf0\x0f\x2e\x4d\x6c\x8b\xaa\xc9"
+ "\xe8\x07\x26\x45\x64\x83\xa2\xc1"
+ "\xe0\xff\x1e\x3d\x5c\x7b\x9a\xb9"
+ "\xd8\xf7\x16\x35\x54\x73\x92\xb1"
+ "\xd0\xef\x0e\x2d\x4c\x6b\x8a\xa9"
+ "\xc8\xe7\x06\x25\x44\x63\x82\xa1"
+ "\xc0\xdf\xfe\x1d\x3c\x5b\x7a\x99"
+ "\xb8\xd7\xf6\x15\x34\x53\x72\x91"
+ "\xb0\xcf\xee\x0d\x2c\x4b\x6a\x89"
+ "\xa8\xc7\xe6\x05\x24\x43\x62\x81"
+ "\xa0\xbf\xde\xfd\x1c\x3b\x5a\x79"
+ "\x98\xb7\xd6\xf5\x14\x33\x52\x71"
+ "\x90\xaf\xce\xed\x0c\x2b\x4a\x69"
+ "\x88\xa7\xc6\xe5\x04\x23\x42\x61"
+ "\x80\x9f\xbe\xdd\xfc\x1b\x3a\x59"
+ "\x78\x97\xb6\xd5\xf4\x13\x32\x51"
+ "\x70\x8f\xae\xcd\xec\x0b\x2a\x49"
+ "\x68\x87\xa6\xc5\xe4\x03\x22\x41"
+ "\x60\x7f\x9e\xbd\xdc\xfb\x1a\x39"
+ "\x58\x77\x96\xb5\xd4\xf3\x12\x31"
+ "\x50\x6f\x8e\xad\xcc\xeb\x0a\x29"
+ "\x48\x67\x86\xa5\xc4\xe3\x02\x21"
+ "\x40\x5f\x7e\x9d\xbc\xdb\xfa\x19"
+ "\x38\x57\x76\x95\xb4\xd3\xf2\x11"
+ "\x30\x4f\x6e\x8d\xac\xcb\xea\x09"
+ "\x28\x47\x66\x85\xa4\xc3\xe2\x01"
+ "\x20\x3f\x5e\x7d\x9c\xbb\xda\xf9"
+ "\x18\x37\x56\x75\x94\xb3\xd2\xf1"
+ "\x10\x2f\x4e\x6d\x8c\xab\xca\xe9"
+ "\x08\x27\x46\x65\x84\xa3\xc2\xe1"
+ "\x00\x21\x42\x63",
+ .ilen = 4100,
+ .result =
+ "\xf0\x5c\x74\xad\x4e\xbc\x99\xe2"
+ "\xae\xff\x91\x3a\x44\xcf\x38\x32"
+ "\x1e\xad\xa7\xcd\xa1\x39\x95\xaa"
+ "\x10\xb1\xb3\x2e\x04\x31\x8f\x86"
+ "\xf2\x62\x74\x70\x0c\xa4\x46\x08"
+ "\xa8\xb7\x99\xa8\xe9\xd2\x73\x79"
+ "\x7e\x6e\xd4\x8f\x1e\xc7\x8e\x31"
+ "\x0b\xfa\x4b\xce\xfd\xf3\x57\x71"
+ "\xe9\x46\x03\xa5\x3d\x34\x00\xe2"
+ "\x18\xff\x75\x6d\x06\x2d\x00\xab"
+ "\xb9\x3e\x6c\x59\xc5\x84\x06\xb5"
+ "\x8b\xd0\x89\x9c\x4a\x79\x16\xc6"
+ "\x3d\x74\x54\xfa\x44\xcd\x23\x26"
+ "\x5c\xcf\x7e\x28\x92\x32\xbf\xdf"
+ "\xa7\x20\x3c\x74\x58\x2a\x9a\xde"
+ "\x61\x00\x1c\x4f\xff\x59\xc4\x22"
+ "\xac\x3c\xd0\xe8\x6c\xf9\x97\x1b"
+ "\x58\x9b\xad\x71\xe8\xa9\xb5\x0d"
+ "\xee\x2f\x04\x1f\x7f\xbc\x99\xee"
+ "\x84\xff\x42\x60\xdc\x3a\x18\xa5"
+ "\x81\xf9\xef\xdc\x7a\x0f\x65\x41"
+ "\x2f\xa3\xd3\xf9\xc2\xcb\xc0\x4d"
+ "\x8f\xd3\x76\x96\xad\x49\x6d\x38"
+ "\x3d\x39\x0b\x6c\x80\xb7\x54\x69"
+ "\xf0\x2c\x90\x02\x29\x0d\x1c\x12"
+ "\xad\x55\xc3\x8b\x68\xd9\xcc\xb3"
+ "\xb2\x64\x33\x90\x5e\xca\x4b\xe2"
+ "\xfb\x75\xdc\x63\xf7\x9f\x82\x74"
+ "\xf0\xc9\xaa\x7f\xe9\x2a\x9b\x33"
+ "\xbc\x88\x00\x7f\xca\xb2\x1f\x14"
+ "\xdb\xc5\x8e\x7b\x11\x3c\x3e\x08"
+ "\xf3\x83\xe8\xe0\x94\x86\x2e\x92"
+ "\x78\x6b\x01\xc9\xc7\x83\xba\x21"
+ "\x6a\x25\x15\x33\x4e\x45\x08\xec"
+ "\x35\xdb\xe0\x6e\x31\x51\x79\xa9"
+ "\x42\x44\x65\xc1\xa0\xf1\xf9\x2a"
+ "\x70\xd5\xb6\xc6\xc1\x8c\x39\xfc"
+ "\x25\xa6\x55\xd9\xdd\x2d\x4c\xec"
+ "\x49\xc6\xeb\x0e\xa8\x25\x2a\x16"
+ "\x1b\x66\x84\xda\xe2\x92\xe5\xc0"
+ "\xc8\x53\x07\xaf\x80\x84\xec\xfd"
+ "\xcd\xd1\x6e\xcd\x6f\x6a\xf5\x36"
+ "\xc5\x15\xe5\x25\x7d\x77\xd1\x1a"
+ "\x93\x36\xa9\xcf\x7c\xa4\x54\x4a"
+ "\x06\x51\x48\x4e\xf6\x59\x87\xd2"
+ "\x04\x02\xef\xd3\x44\xde\x76\x31"
+ "\xb3\x34\x17\x1b\x9d\x66\x11\x9f"
+ "\x1e\xcc\x17\xe9\xc7\x3c\x1b\xe7"
+ "\xcb\x50\x08\xfc\xdc\x2b\x24\xdb"
+ "\x65\x83\xd0\x3b\xe3\x30\xea\x94"
+ "\x6c\xe7\xe8\x35\x32\xc7\xdb\x64"
+ "\xb4\x01\xab\x36\x2c\x77\x13\xaf"
+ "\xf8\x2b\x88\x3f\x54\x39\xc4\x44"
+ "\xfe\xef\x6f\x68\x34\xbe\x0f\x05"
+ "\x16\x6d\xf6\x0a\x30\xe7\xe3\xed"
+ "\xc4\xde\x3c\x1b\x13\xd8\xdb\xfe"
+ "\x41\x62\xe5\x28\xd4\x8d\xa3\xc7"
+ "\x93\x97\xc6\x48\x45\x1d\x9f\x83"
+ "\xdf\x4b\x40\x3e\x42\x25\x87\x80"
+ "\x4c\x7d\xa8\xd4\x98\x23\x95\x75"
+ "\x41\x8c\xda\x41\x9b\xd4\xa7\x06"
+ "\xb5\xf1\x71\x09\x53\xbe\xca\xbf"
+ "\x32\x03\xed\xf0\x50\x1c\x56\x39"
+ "\x5b\xa4\x75\x18\xf7\x9b\x58\xef"
+ "\x53\xfc\x2a\x38\x23\x15\x75\xcd"
+ "\x45\xe5\x5a\x82\x55\xba\x21\xfa"
+ "\xd4\xbd\xc6\x94\x7c\xc5\x80\x12"
+ "\xf7\x4b\x32\xc4\x9a\x82\xd8\x28"
+ "\x8f\xd9\xc2\x0f\x60\x03\xbe\x5e"
+ "\x21\xd6\x5f\x58\xbf\x5c\xb1\x32"
+ "\x82\x8d\xa9\xe5\xf2\x66\x1a\xc0"
+ "\xa0\xbc\x58\x2f\x71\xf5\x2f\xed"
+ "\xd1\x26\xb9\xd8\x49\x5a\x07\x19"
+ "\x01\x7c\x59\xb0\xf8\xa4\xb7\xd3"
+ "\x7b\x1a\x8c\x38\xf4\x50\xa4\x59"
+ "\xb0\xcc\x41\x0b\x88\x7f\xe5\x31"
+ "\xb3\x42\xba\xa2\x7e\xd4\x32\x71"
+ "\x45\x87\x48\xa9\xc2\xf2\x89\xb3"
+ "\xe4\xa7\x7e\x52\x15\x61\xfa\xfe"
+ "\xc9\xdd\x81\xeb\x13\xab\xab\xc3"
+ "\x98\x59\xd8\x16\x3d\x14\x7a\x1c"
+ "\x3c\x41\x9a\x16\x16\x9b\xd2\xd2"
+ "\x69\x3a\x29\x23\xac\x86\x32\xa5"
+ "\x48\x9c\x9e\xf3\x47\x77\x81\x70"
+ "\x24\xe8\x85\xd2\xf5\xb5\xfa\xff"
+ "\x59\x6a\xd3\x50\x59\x43\x59\xde"
+ "\xd9\xf1\x55\xa5\x0c\xc3\x1a\x1a"
+ "\x18\x34\x0d\x1a\x63\x33\xed\x10"
+ "\xe0\x1d\x2a\x18\xd2\xc0\x54\xa8"
+ "\xca\xb5\x9a\xd3\xdd\xca\x45\x84"
+ "\x50\xe7\x0f\xfe\xa4\x99\x5a\xbe"
+ "\x43\x2d\x9a\xcb\x92\x3f\x5a\x1d"
+ "\x85\xd8\xc9\xdf\x68\xc9\x12\x80"
+ "\x56\x0c\xdc\x00\xdc\x3a\x7d\x9d"
+ "\xa3\xa2\xe8\x4d\xbf\xf9\x70\xa0"
+ "\xa4\x13\x4f\x6b\xaf\x0a\x89\x7f"
+ "\xda\xf0\xbf\x9b\xc8\x1d\xe5\xf8"
+ "\x2e\x8b\x07\xb5\x73\x1b\xcc\xa2"
+ "\xa6\xad\x30\xbc\x78\x3c\x5b\x10"
+ "\xfa\x5e\x62\x2d\x9e\x64\xb3\x33"
+ "\xce\xf9\x1f\x86\xe7\x8b\xa2\xb8"
+ "\xe8\x99\x57\x8c\x11\xed\x66\xd9"
+ "\x3c\x72\xb9\xc3\xe6\x4e\x17\x3a"
+ "\x6a\xcb\x42\x24\x06\xed\x3e\x4e"
+ "\xa3\xe8\x6a\x94\xda\x0d\x4e\xd5"
+ "\x14\x19\xcf\xb6\x26\xd8\x2e\xcc"
+ "\x64\x76\x38\x49\x4d\xfe\x30\x6d"
+ "\xe4\xc8\x8c\x7b\xc4\xe0\x35\xba"
+ "\x22\x6e\x76\xe1\x1a\xf2\x53\xc3"
+ "\x28\xa2\x82\x1f\x61\x69\xad\xc1"
+ "\x7b\x28\x4b\x1e\x6c\x85\x95\x9b"
+ "\x51\xb5\x17\x7f\x12\x69\x8c\x24"
+ "\xd5\xc7\x5a\x5a\x11\x54\xff\x5a"
+ "\xf7\x16\xc3\x91\xa6\xf0\xdc\x0a"
+ "\xb6\xa7\x4a\x0d\x7a\x58\xfe\xa5"
+ "\xf5\xcb\x8f\x7b\x0e\xea\x57\xe7"
+ "\xbd\x79\xd6\x1c\x88\x23\x6c\xf2"
+ "\x4d\x29\x77\x53\x35\x6a\x00\x8d"
+ "\xcd\xa3\x58\xbe\x77\x99\x18\xf8"
+ "\xe6\xe1\x8f\xe9\x37\x8f\xe3\xe2"
+ "\x5a\x8a\x93\x25\xaf\xf3\x78\x80"
+ "\xbe\xa6\x1b\xc6\xac\x8b\x1c\x91"
+ "\x58\xe1\x9f\x89\x35\x9d\x1d\x21"
+ "\x29\x9f\xf4\x99\x02\x27\x0f\xa8"
+ "\x4f\x79\x94\x2b\x33\x2c\xda\xa2"
+ "\x26\x39\x83\x94\xef\x27\xd8\x53"
+ "\x8f\x66\x0d\xe4\x41\x7d\x34\xcd"
+ "\x43\x7c\x95\x0a\x53\xef\x66\xda"
+ "\x7e\x9b\xf3\x93\xaf\xd0\x73\x71"
+ "\xba\x40\x9b\x74\xf8\xd7\xd7\x41"
+ "\x6d\xaf\x72\x9c\x8d\x21\x87\x3c"
+ "\xfd\x0a\x90\xa9\x47\x96\x9e\xd3"
+ "\x88\xee\x73\xcf\x66\x2f\x52\x56"
+ "\x6d\xa9\x80\x4c\xe2\x6f\x62\x88"
+ "\x3f\x0e\x54\x17\x48\x80\x5d\xd3"
+ "\xc3\xda\x25\x3d\xa1\xc8\xcb\x9f"
+ "\x9b\x70\xb3\xa1\xeb\x04\x52\xa1"
+ "\xf2\x22\x0f\xfc\xc8\x18\xfa\xf9"
+ "\x85\x9c\xf1\xac\xeb\x0c\x02\x46"
+ "\x75\xd2\xf5\x2c\xe3\xd2\x59\x94"
+ "\x12\xf3\x3c\xfc\xd7\x92\xfa\x36"
+ "\xba\x61\x34\x38\x7c\xda\x48\x3e"
+ "\x08\xc9\x39\x23\x5e\x02\x2c\x1a"
+ "\x18\x7e\xb4\xd9\xfd\x9e\x40\x02"
+ "\xb1\x33\x37\x32\xe7\xde\xd6\xd0"
+ "\x7c\x58\x65\x4b\xf8\x34\x27\x9c"
+ "\x44\xb4\xbd\xe9\xe9\x4c\x78\x7d"
+ "\x4b\x9f\xce\xb1\xcd\x47\xa5\x37"
+ "\xe5\x6d\xbd\xb9\x43\x94\x0a\xd4"
+ "\xd6\xf9\x04\x5f\xb5\x66\x6c\x1a"
+ "\x35\x12\xe3\x36\x28\x27\x36\x58"
+ "\x01\x2b\x79\xe4\xba\x6d\x10\x7d"
+ "\x65\xdf\x84\x95\xf4\xd5\xb6\x8f"
+ "\x2b\x9f\x96\x00\x86\x60\xf0\x21"
+ "\x76\xa8\x6a\x8c\x28\x1c\xb3\x6b"
+ "\x97\xd7\xb6\x53\x2a\xcc\xab\x40"
+ "\x9d\x62\x79\x58\x52\xe6\x65\xb7"
+ "\xab\x55\x67\x9c\x89\x7c\x03\xb0"
+ "\x73\x59\xc5\x81\xf5\x18\x17\x5c"
+ "\x89\xf3\x78\x35\x44\x62\x78\x72"
+ "\xd0\x96\xeb\x31\xe7\x87\x77\x14"
+ "\x99\x51\xf2\x59\x26\x9e\xb5\xa6"
+ "\x45\xfe\x6e\xbd\x07\x4c\x94\x5a"
+ "\xa5\x7d\xfc\xf1\x2b\x77\xe2\xfe"
+ "\x17\xd4\x84\xa0\xac\xb5\xc7\xda"
+ "\xa9\x1a\xb6\xf3\x74\x11\xb4\x9d"
+ "\xfb\x79\x2e\x04\x2d\x50\x28\x83"
+ "\xbf\xc6\x52\xd3\x34\xd6\xe8\x7a"
+ "\xb6\xea\xe7\xa8\x6c\x15\x1e\x2c"
+ "\x57\xbc\x48\x4e\x5f\x5c\xb6\x92"
+ "\xd2\x49\x77\x81\x6d\x90\x70\xae"
+ "\x98\xa1\x03\x0d\x6b\xb9\x77\x14"
+ "\xf1\x4e\x23\xd3\xf8\x68\xbd\xc2"
+ "\xfe\x04\xb7\x5c\xc5\x17\x60\x8f"
+ "\x65\x54\xa4\x7a\x42\xdc\x18\x0d"
+ "\xb5\xcf\x0f\xd3\xc7\x91\x66\x1b"
+ "\x45\x42\x27\x75\x50\xe5\xee\xb8"
+ "\x7f\x33\x2c\xba\x4a\x92\x4d\x2c"
+ "\x3c\xe3\x0d\x80\x01\xba\x0d\x29"
+ "\xd8\x3c\xe9\x13\x16\x57\xe6\xea"
+ "\x94\x52\xe7\x00\x4d\x30\xb0\x0f"
+ "\x35\xb8\xb8\xa7\xb1\xb5\x3b\x44"
+ "\xe1\x2f\xfd\x88\xed\x43\xe7\x52"
+ "\x10\x93\xb3\x8a\x30\x6b\x0a\xf7"
+ "\x23\xc6\x50\x9d\x4a\xb0\xde\xc3"
+ "\xdc\x9b\x2f\x01\x56\x36\x09\xc5"
+ "\x2f\x6b\xfe\xf1\xd8\x27\x45\x03"
+ "\x30\x5e\x5c\x5b\xb4\x62\x0e\x1a"
+ "\xa9\x21\x2b\x92\x94\x87\x62\x57"
+ "\x4c\x10\x74\x1a\xf1\x0a\xc5\x84"
+ "\x3b\x9e\x72\x02\xd7\xcc\x09\x56"
+ "\xbd\x54\xc1\xf0\xc3\xe3\xb3\xf8"
+ "\xd2\x0d\x61\xcb\xef\xce\x0d\x05"
+ "\xb0\x98\xd9\x8e\x4f\xf9\xbc\x93"
+ "\xa6\xea\xc8\xcf\x10\x53\x4b\xf1"
+ "\xec\xfc\x89\xf9\x64\xb0\x22\xbf"
+ "\x9e\x55\x46\x9f\x7c\x50\x8e\x84"
+ "\x54\x20\x98\xd7\x6c\x40\x1e\xdb"
+ "\x69\x34\x78\x61\x24\x21\x9c\x8a"
+ "\xb3\x62\x31\x8b\x6e\xf5\x2a\x35"
+ "\x86\x13\xb1\x6c\x64\x2e\x41\xa5"
+ "\x05\xf2\x42\xba\xd2\x3a\x0d\x8e"
+ "\x8a\x59\x94\x3c\xcf\x36\x27\x82"
+ "\xc2\x45\xee\x58\xcd\x88\xb4\xec"
+ "\xde\xb2\x96\x0a\xaf\x38\x6f\x88"
+ "\xd7\xd8\xe1\xdf\xb9\x96\xa9\x0a"
+ "\xb1\x95\x28\x86\x20\xe9\x17\x49"
+ "\xa2\x29\x38\xaa\xa5\xe9\x6e\xf1"
+ "\x19\x27\xc0\xd5\x2a\x22\xc3\x0b"
+ "\xdb\x7c\x73\x10\xb9\xba\x89\x76"
+ "\x54\xae\x7d\x71\xb3\x93\xf6\x32"
+ "\xe6\x47\x43\x55\xac\xa0\x0d\xc2"
+ "\x93\x27\x4a\x8e\x0e\x74\x15\xc7"
+ "\x0b\x85\xd9\x0c\xa9\x30\x7a\x3e"
+ "\xea\x8f\x85\x6d\x3a\x12\x4f\x72"
+ "\x69\x58\x7a\x80\xbb\xb5\x97\xf3"
+ "\xcf\x70\xd2\x5d\xdd\x4d\x21\x79"
+ "\x54\x4d\xe4\x05\xe8\xbd\xc2\x62"
+ "\xb1\x3b\x77\x1c\xd6\x5c\xf3\xa0"
+ "\x79\x00\xa8\x6c\x29\xd9\x18\x24"
+ "\x36\xa2\x46\xc0\x96\x65\x7f\xbd"
+ "\x2a\xed\x36\x16\x0c\xaa\x9f\xf4"
+ "\xc5\xb4\xe2\x12\xed\x69\xed\x4f"
+ "\x26\x2c\x39\x52\x89\x98\xe7\x2c"
+ "\x99\xa4\x9e\xa3\x9b\x99\x46\x7a"
+ "\x3a\xdc\xa8\x59\xa3\xdb\xc3\x3b"
+ "\x95\x0d\x3b\x09\x6e\xee\x83\x5d"
+ "\x32\x4d\xed\xab\xfa\x98\x14\x4e"
+ "\xc3\x15\x45\x53\x61\xc4\x93\xbd"
+ "\x90\xf4\x99\x95\x4c\xe6\x76\x92"
+ "\x29\x90\x46\x30\x92\x69\x7d\x13"
+ "\xf2\xa5\xcd\x69\x49\x44\xb2\x0f"
+ "\x63\x40\x36\x5f\x09\xe2\x78\xf8"
+ "\x91\xe3\xe2\xfa\x10\xf7\xc8\x24"
+ "\xa8\x89\x32\x5c\x37\x25\x1d\xb2"
+ "\xea\x17\x8a\x0a\xa9\x64\xc3\x7c"
+ "\x3c\x7c\xbd\xc6\x79\x34\xe7\xe2"
+ "\x85\x8e\xbf\xf8\xde\x92\xa0\xae"
+ "\x20\xc4\xf6\xbb\x1f\x38\x19\x0e"
+ "\xe8\x79\x9c\xa1\x23\xe9\x54\x7e"
+ "\x37\x2f\xe2\x94\x32\xaf\xa0\x23"
+ "\x49\xe4\xc0\xb3\xac\x00\x8f\x36"
+ "\x05\xc4\xa6\x96\xec\x05\x98\x4f"
+ "\x96\x67\x57\x1f\x20\x86\x1b\x2d"
+ "\x69\xe4\x29\x93\x66\x5f\xaf\x6b"
+ "\x88\x26\x2c\x67\x02\x4b\x52\xd0"
+ "\x83\x7a\x43\x1f\xc0\x71\x15\x25"
+ "\x77\x65\x08\x60\x11\x76\x4c\x8d"
+ "\xed\xa9\x27\xc6\xb1\x2a\x2c\x6a"
+ "\x4a\x97\xf5\xc6\xb7\x70\x42\xd3"
+ "\x03\xd1\x24\x95\xec\x6d\xab\x38"
+ "\x72\xce\xe2\x8b\x33\xd7\x51\x09"
+ "\xdc\x45\xe0\x09\x96\x32\xf3\xc4"
+ "\x84\xdc\x73\x73\x2d\x1b\x11\x98"
+ "\xc5\x0e\x69\x28\x94\xc7\xb5\x4d"
+ "\xc8\x8a\xd0\xaa\x13\x2e\x18\x74"
+ "\xdd\xd1\x1e\xf3\x90\xe8\xfc\x9a"
+ "\x72\x4a\x0e\xd1\xe4\xfb\x0d\x96"
+ "\xd1\x0c\x79\x85\x1b\x1c\xfe\xe1"
+ "\x62\x8f\x7a\x73\x32\xab\xc8\x18"
+ "\x69\xe3\x34\x30\xdf\x13\xa6\xe5"
+ "\xe8\x0e\x67\x7f\x81\x11\xb4\x60"
+ "\xc7\xbd\x79\x65\x50\xdc\xc4\x5b"
+ "\xde\x39\xa4\x01\x72\x63\xf3\xd1"
+ "\x64\x4e\xdf\xfc\x27\x92\x37\x0d"
+ "\x57\xcd\x11\x4f\x11\x04\x8e\x1d"
+ "\x16\xf7\xcd\x92\x9a\x99\x30\x14"
+ "\xf1\x7c\x67\x1b\x1f\x41\x0b\xe8"
+ "\x32\xe8\xb8\xc1\x4f\x54\x86\x4f"
+ "\xe5\x79\x81\x73\xcd\x43\x59\x68"
+ "\x73\x02\x3b\x78\x21\x72\x43\x00"
+ "\x49\x17\xf7\x00\xaf\x68\x24\x53"
+ "\x05\x0a\xc3\x33\xe0\x33\x3f\x69"
+ "\xd2\x84\x2f\x0b\xed\xde\x04\xf4"
+ "\x11\x94\x13\x69\x51\x09\x28\xde"
+ "\x57\x5c\xef\xdc\x9a\x49\x1c\x17"
+ "\x97\xf3\x96\xc1\x7f\x5d\x2e\x7d"
+ "\x55\xb8\xb3\x02\x09\xb3\x1f\xe7"
+ "\xc9\x8d\xa3\x36\x34\x8a\x77\x13"
+ "\x30\x63\x4c\xa5\xcd\xc3\xe0\x7e"
+ "\x05\xa1\x7b\x0c\xcb\x74\x47\x31"
+ "\x62\x03\x43\xf1\x87\xb4\xb0\x85"
+ "\x87\x8e\x4b\x25\xc7\xcf\xae\x4b"
+ "\x36\x46\x3e\x62\xbc\x6f\xeb\x5f"
+ "\x73\xac\xe6\x07\xee\xc1\xa1\xd6"
+ "\xc4\xab\xc9\xd6\x89\x45\xe1\xf1"
+ "\x04\x4e\x1a\x6f\xbb\x4f\x3a\xa3"
+ "\xa0\xcb\xa3\x0a\xd8\x71\x35\x55"
+ "\xe4\xbc\x2e\x04\x06\xe6\xff\x5b"
+ "\x1c\xc0\x11\x7c\xc5\x17\xf3\x38"
+ "\xcf\xe9\xba\x0f\x0e\xef\x02\xc2"
+ "\x8d\xc6\xbc\x4b\x67\x20\x95\xd7"
+ "\x2c\x45\x5b\x86\x44\x8c\x6f\x2e"
+ "\x7e\x9f\x1c\x77\xba\x6b\x0e\xa3"
+ "\x69\xdc\xab\x24\x57\x60\x47\xc1"
+ "\xd1\xa5\x9d\x23\xe6\xb1\x37\xfe"
+ "\x93\xd2\x4c\x46\xf9\x0c\xc6\xfb"
+ "\xd6\x9d\x99\x69\xab\x7a\x07\x0c"
+ "\x65\xe7\xc4\x08\x96\xe2\xa5\x01"
+ "\x3f\x46\x07\x05\x7e\xe8\x9a\x90"
+ "\x50\xdc\xe9\x7a\xea\xa1\x39\x6e"
+ "\x66\xe4\x6f\xa5\x5f\xb2\xd9\x5b"
+ "\xf5\xdb\x2a\x32\xf0\x11\x6f\x7c"
+ "\x26\x10\x8f\x3d\x80\xe9\x58\xf7"
+ "\xe0\xa8\x57\xf8\xdb\x0e\xce\x99"
+ "\x63\x19\x3d\xd5\xec\x1b\x77\x69"
+ "\x98\xf6\xe4\x5f\x67\x17\x4b\x09"
+ "\x85\x62\x82\x70\x18\xe2\x9a\x78"
+ "\xe2\x62\xbd\xb4\xf1\x42\xc6\xfb"
+ "\x08\xd0\xbd\xeb\x4e\x09\xf2\xc8"
+ "\x1e\xdc\x3d\x32\x21\x56\x9c\x4f"
+ "\x35\xf3\x61\x06\x72\x84\xc4\x32"
+ "\xf2\xf1\xfa\x0b\x2f\xc3\xdb\x02"
+ "\x04\xc2\xde\x57\x64\x60\x8d\xcf"
+ "\xcb\x86\x5d\x97\x3e\xb1\x9c\x01"
+ "\xd6\x28\x8f\x99\xbc\x46\xeb\x05"
+ "\xaf\x7e\xb8\x21\x2a\x56\x85\x1c"
+ "\xb3\x71\xa0\xde\xca\x96\xf1\x78"
+ "\x49\xa2\x99\x81\x80\x5c\x01\xf5"
+ "\xa0\xa2\x56\x63\xe2\x70\x07\xa5"
+ "\x95\xd6\x85\xeb\x36\x9e\xa9\x51"
+ "\x66\x56\x5f\x1d\x02\x19\xe2\xf6"
+ "\x4f\x73\x38\x09\x75\x64\x48\xe0"
+ "\xf1\x7e\x0e\xe8\x9d\xf9\xed\x94"
+ "\xfe\x16\x26\x62\x49\x74\xf4\xb0"
+ "\xd4\xa9\x6c\xb0\xfd\x53\xe9\x81"
+ "\xe0\x7a\xbf\xcf\xb5\xc4\x01\x81"
+ "\x79\x99\x77\x01\x3b\xe9\xa2\xb6"
+ "\xe6\x6a\x8a\x9e\x56\x1c\x8d\x1e"
+ "\x8f\x06\x55\x2c\x6c\xdc\x92\x87"
+ "\x64\x3b\x4b\x19\xa1\x13\x64\x1d"
+ "\x4a\xe9\xc0\x00\xb8\x95\xef\x6b"
+ "\x1a\x86\x6d\x37\x52\x02\xc2\xe0"
+ "\xc8\xbb\x42\x0c\x02\x21\x4a\xc9"
+ "\xef\xa0\x54\xe4\x5e\x16\x53\x81"
+ "\x70\x62\x10\xaf\xde\xb8\xb5\xd3"
+ "\xe8\x5e\x6c\xc3\x8a\x3e\x18\x07"
+ "\xf2\x2f\x7d\xa7\xe1\x3d\x4e\xb4"
+ "\x26\xa7\xa3\x93\x86\xb2\x04\x1e"
+ "\x53\x5d\x86\xd6\xde\x65\xca\xe3"
+ "\x4e\xc1\xcf\xef\xc8\x70\x1b\x83"
+ "\x13\xdd\x18\x8b\x0d\x76\xd2\xf6"
+ "\x37\x7a\x93\x7a\x50\x11\x9f\x96"
+ "\x86\x25\xfd\xac\xdc\xbe\x18\x93"
+ "\x19\x6b\xec\x58\x4f\xb9\x75\xa7"
+ "\xdd\x3f\x2f\xec\xc8\x5a\x84\xab"
+ "\xd5\xe4\x8a\x07\xf6\x4d\x23\xd6"
+ "\x03\xfb\x03\x6a\xea\x66\xbf\xd4"
+ "\xb1\x34\xfb\x78\xe9\x55\xdc\x7c"
+ "\x3d\x9c\xe5\x9a\xac\xc3\x7a\x80"
+ "\x24\x6d\xa0\xef\x25\x7c\xb7\xea"
+ "\xce\x4d\x5f\x18\x60\xce\x87\x22"
+ "\x66\x2f\xd5\xdd\xdd\x02\x21\x75"
+ "\x82\xa0\x1f\x58\xc6\xd3\x62\xf7"
+ "\x32\xd8\xaf\x1e\x07\x77\x51\x96"
+ "\xd5\x6b\x1e\x7e\x80\x02\xe8\x67"
+ "\xea\x17\x0b\x10\xd2\x3f\x28\x25"
+ "\x4f\x05\x77\x02\x14\x69\xf0\x2c"
+ "\xbe\x0c\xf1\x74\x30\xd1\xb9\x9b"
+ "\xfc\x8c\xbb\x04\x16\xd9\xba\xc3"
+ "\xbc\x91\x8a\xc4\x30\xa4\xb0\x12"
+ "\x4c\x21\x87\xcb\xc9\x1d\x16\x96"
+ "\x07\x6f\x23\x54\xb9\x6f\x79\xe5"
+ "\x64\xc0\x64\xda\xb1\xae\xdd\x60"
+ "\x6c\x1a\x9d\xd3\x04\x8e\x45\xb0"
+ "\x92\x61\xd0\x48\x81\xed\x5e\x1d"
+ "\xa0\xc9\xa4\x33\xc7\x13\x51\x5d"
+ "\x7f\x83\x73\xb6\x70\x18\x65\x3e"
+ "\x2f\x0e\x7a\x12\x39\x98\xab\xd8"
+ "\x7e\x6f\xa3\xd1\xba\x56\xad\xbd"
+ "\xf0\x03\x01\x1c\x85\x35\x9f\xeb"
+ "\x19\x63\xa1\xaf\xfe\x2d\x35\x50"
+ "\x39\xa0\x65\x7c\x95\x7e\x6b\xfe"
+ "\xc1\xac\x07\x7c\x98\x4f\xbe\x57"
+ "\xa7\x22\xec\xe2\x7e\x29\x09\x53"
+ "\xe8\xbf\xb4\x7e\x3f\x8f\xfc\x14"
+ "\xce\x54\xf9\x18\x58\xb5\xff\x44"
+ "\x05\x9d\xce\x1b\xb6\x82\x23\xc8"
+ "\x2e\xbc\x69\xbb\x4a\x29\x0f\x65"
+ "\x94\xf0\x63\x06\x0e\xef\x8c\xbd"
+ "\xff\xfd\xb0\x21\x6e\x57\x05\x75"
+ "\xda\xd5\xc4\xeb\x8d\x32\xf7\x50"
+ "\xd3\x6f\x22\xed\x5f\x8e\xa2\x5b"
+ "\x80\x8c\xc8\x78\x40\x24\x4b\x89"
+ "\x30\xce\x7a\x97\x0e\xc4\xaf\xef"
+ "\x9b\xb4\xcd\x66\x74\x14\x04\x2b"
+ "\xf7\xce\x0b\x1c\x6e\xc2\x78\x8c"
+ "\xca\xc5\xd0\x1c\x95\x4a\x91\x2d"
+ "\xa7\x20\xeb\x86\x52\xb7\x67\xd8"
+ "\x0c\xd6\x04\x14\xde\x51\x74\x75"
+ "\xe7\x11\xb4\x87\xa3\x3d\x2d\xad"
+ "\x4f\xef\xa0\x0f\x70\x00\x6d\x13"
+ "\x19\x1d\x41\x50\xe9\xd8\xf0\x32"
+ "\x71\xbc\xd3\x11\xf2\xac\xbe\xaf"
+ "\x75\x46\x65\x4e\x07\x34\x37\xa3"
+ "\x89\xfe\x75\xd4\x70\x4c\xc6\x3f"
+ "\x69\x24\x0e\x38\x67\x43\x8c\xde"
+ "\x06\xb5\xb8\xe7\xc4\xf0\x41\x8f"
+ "\xf0\xbd\x2f\x0b\xb9\x18\xf8\xde"
+ "\x64\xb1\xdb\xee\x00\x50\x77\xe1"
+ "\xc7\xff\xa6\xfa\xdd\x70\xf4\xe3"
+ "\x93\xe9\x77\x35\x3d\x4b\x2f\x2b"
+ "\x6d\x55\xf0\xfc\x88\x54\x4e\x89"
+ "\xc1\x8a\x23\x31\x2d\x14\x2a\xb8"
+ "\x1b\x15\xdd\x9e\x6e\x7b\xda\x05"
+ "\x91\x7d\x62\x64\x96\x72\xde\xfc"
+ "\xc1\xec\xf0\x23\x51\x6f\xdb\x5b"
+ "\x1d\x08\x57\xce\x09\xb8\xf6\xcd"
+ "\x8d\x95\xf2\x20\xbf\x0f\x20\x57"
+ "\x98\x81\x84\x4f\x15\x5c\x76\xe7"
+ "\x3e\x0a\x3a\x6c\xc4\x8a\xbe\x78"
+ "\x74\x77\xc3\x09\x4b\x5d\x48\xe4"
+ "\xc8\xcb\x0b\xea\x17\x28\xcf\xcf"
+ "\x31\x32\x44\xa4\xe5\x0e\x1a\x98"
+ "\x94\xc4\xf0\xff\xae\x3e\x44\xe8"
+ "\xa5\xb3\xb5\x37\x2f\xe8\xaf\x6f"
+ "\x28\xc1\x37\x5f\x31\xd2\xb9\x33"
+ "\xb1\xb2\x52\x94\x75\x2c\x29\x59"
+ "\x06\xc2\x25\xe8\x71\x65\x4e\xed"
+ "\xc0\x9c\xb1\xbb\x25\xdc\x6c\xe7"
+ "\x4b\xa5\x7a\x54\x7a\x60\xff\x7a"
+ "\xe0\x50\x40\x96\x35\x63\xe4\x0b"
+ "\x76\xbd\xa4\x65\x00\x1b\x57\x88"
+ "\xae\xed\x39\x88\x42\x11\x3c\xed"
+ "\x85\x67\x7d\xb9\x68\x82\xe9\x43"
+ "\x3c\x47\x53\xfa\xe8\xf8\x9f\x1f"
+ "\x9f\xef\x0f\xf7\x30\xd9\x30\x0e"
+ "\xb9\x9f\x69\x18\x2f\x7e\xf8\xf8"
+ "\xf8\x8c\x0f\xd4\x02\x4d\xea\xcd"
+ "\x0a\x9c\x6f\x71\x6d\x5a\x4c\x60"
+ "\xce\x20\x56\x32\xc6\xc5\x99\x1f"
+ "\x09\xe6\x4e\x18\x1a\x15\x13\xa8"
+ "\x7d\xb1\x6b\xc0\xb2\x6d\xf8\x26"
+ "\x66\xf8\x3d\x18\x74\x70\x66\x7a"
+ "\x34\x17\xde\xba\x47\xf1\x06\x18"
+ "\xcb\xaf\xeb\x4a\x1e\x8f\xa7\x77"
+ "\xe0\x3b\x78\x62\x66\xc9\x10\xea"
+ "\x1f\xb7\x29\x0a\x45\xa1\x1d\x1e"
+ "\x1d\xe2\x65\x61\x50\x9c\xd7\x05"
+ "\xf2\x0b\x5b\x12\x61\x02\xc8\xe5"
+ "\x63\x4f\x20\x0c\x07\x17\x33\x5e"
+ "\x03\x9a\x53\x0f\x2e\x55\xfe\x50"
+ "\x43\x7d\xd0\xb6\x7e\x5a\xda\xae"
+ "\x58\xef\x15\xa9\x83\xd9\x46\xb1"
+ "\x42\xaa\xf5\x02\x6c\xce\x92\x06"
+ "\x1b\xdb\x66\x45\x91\x79\xc2\x2d"
+ "\xe6\x53\xd3\x14\xfd\xbb\x44\x63"
+ "\xc6\xd7\x3d\x7a\x0c\x75\x78\x9d"
+ "\x5c\xa6\x39\xb3\xe5\x63\xca\x8b"
+ "\xfe\xd3\xef\x60\x83\xf6\x8e\x70"
+ "\xb6\x67\xc7\x77\xed\x23\xef\x4c"
+ "\xf0\xed\x2d\x07\x59\x6f\xc1\x01"
+ "\x34\x37\x08\xab\xd9\x1f\x09\xb1"
+ "\xce\x5b\x17\xff\x74\xf8\x9c\xd5"
+ "\x2c\x56\x39\x79\x0f\x69\x44\x75"
+ "\x58\x27\x01\xc4\xbf\xa7\xa1\x1d"
+ "\x90\x17\x77\x86\x5a\x3f\xd9\xd1"
+ "\x0e\xa0\x10\xf8\xec\x1e\xa5\x7f"
+ "\x5e\x36\xd1\xe3\x04\x2c\x70\xf7"
+ "\x8e\xc0\x98\x2f\x6c\x94\x2b\x41"
+ "\xb7\x60\x00\xb7\x2e\xb8\x02\x8d"
+ "\xb8\xb0\xd3\x86\xba\x1d\xd7\x90"
+ "\xd6\xb6\xe1\xfc\xd7\xd8\x28\x06"
+ "\x63\x9b\xce\x61\x24\x79\xc0\x70"
+ "\x52\xd0\xb6\xd4\x28\x95\x24\x87"
+ "\x03\x1f\xb7\x9a\xda\xa3\xfb\x52"
+ "\x5b\x68\xe7\x4c\x8c\x24\xe1\x42"
+ "\xf7\xd5\xfd\xad\x06\x32\x9f\xba"
+ "\xc1\xfc\xdd\xc6\xfc\xfc\xb3\x38"
+ "\x74\x56\x58\x40\x02\x37\x52\x2c"
+ "\x55\xcc\xb3\x9e\x7a\xe9\xd4\x38"
+ "\x41\x5e\x0c\x35\xe2\x11\xd1\x13"
+ "\xf8\xb7\x8d\x72\x6b\x22\x2a\xb0"
+ "\xdb\x08\xba\x35\xb9\x3f\xc8\xd3"
+ "\x24\x90\xec\x58\xd2\x09\xc7\x2d"
+ "\xed\x38\x80\x36\x72\x43\x27\x49"
+ "\x4a\x80\x8a\xa2\xe8\xd3\xda\x30"
+ "\x7d\xb6\x82\x37\x86\x92\x86\x3e"
+ "\x08\xb2\x28\x5a\x55\x44\x24\x7d"
+ "\x40\x48\x8a\xb6\x89\x58\x08\xa0"
+ "\xd6\x6d\x3a\x17\xbf\xf6\x54\xa2"
+ "\xf5\xd3\x8c\x0f\x78\x12\x57\x8b"
+ "\xd5\xc2\xfd\x58\x5b\x7f\x38\xe3"
+ "\xcc\xb7\x7c\x48\xb3\x20\xe8\x81"
+ "\x14\x32\x45\x05\xe0\xdb\x9f\x75"
+ "\x85\xb4\x6a\xfc\x95\xe3\x54\x22"
+ "\x12\xee\x30\xfe\xd8\x30\xef\x34"
+ "\x50\xab\x46\x30\x98\x2f\xb7\xc0"
+ "\x15\xa2\x83\xb6\xf2\x06\x21\xa2"
+ "\xc3\x26\x37\x14\xd1\x4d\xb5\x10"
+ "\x52\x76\x4d\x6a\xee\xb5\x2b\x15"
+ "\xb7\xf9\x51\xe8\x2a\xaf\xc7\xfa"
+ "\x77\xaf\xb0\x05\x4d\xd1\x68\x8e"
+ "\x74\x05\x9f\x9d\x93\xa5\x3e\x7f"
+ "\x4e\x5f\x9d\xcb\x09\xc7\x83\xe3"
+ "\x02\x9d\x27\x1f\xef\x85\x05\x8d"
+ "\xec\x55\x88\x0f\x0d\x7c\x4c\xe8"
+ "\xa1\x75\xa0\xd8\x06\x47\x14\xef"
+ "\xaa\x61\xcf\x26\x15\xad\xd8\xa3"
+ "\xaa\x75\xf2\x78\x4a\x5a\x61\xdf"
+ "\x8b\xc7\x04\xbc\xb2\x32\xd2\x7e"
+ "\x42\xee\xb4\x2f\x51\xff\x7b\x2e"
+ "\xd3\x02\xe8\xdc\x5d\x0d\x50\xdc"
+ "\xae\xb7\x46\xf9\xa8\xe6\xd0\x16"
+ "\xcc\xe6\x2c\x81\xc7\xad\xe9\xf0"
+ "\x05\x72\x6d\x3d\x0a\x7a\xa9\x02"
+ "\xac\x82\x93\x6e\xb6\x1c\x28\xfc"
+ "\x44\x12\xfb\x73\x77\xd4\x13\x39"
+ "\x29\x88\x8a\xf3\x5c\xa6\x36\xa0"
+ "\x2a\xed\x7e\xb1\x1d\xd6\x4c\x6b"
+ "\x41\x01\x18\x5d\x5d\x07\x97\xa6"
+ "\x4b\xef\x31\x18\xea\xac\xb1\x84"
+ "\x21\xed\xda\x86",
+ .rlen = 4100,
+ .np = 2,
+ .tap = { 4064, 36 },
+#endif
+ },
+};
+
+static struct cipher_testvec aes_ctr_rfc3686_dec_tv_template[] = {
+ { /* From RFC 3686 */
+ .key = "\xae\x68\x52\xf8\x12\x10\x67\xcc"
+ "\x4b\xf7\xa5\x76\x55\x77\xf3\x9e"
+ "\x00\x00\x00\x30",
+ .klen = 20,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\xe4\x09\x5d\x4f\xb7\xa7\xb3\x79"
+ "\x2d\x61\x75\xa3\x26\x13\x11\xb8",
+ .ilen = 16,
+ .result = "Single block msg",
+ .rlen = 16,
+ }, {
+ .key = "\x7e\x24\x06\x78\x17\xfa\xe0\xd7"
+ "\x43\xd6\xce\x1f\x32\x53\x91\x63"
+ "\x00\x6c\xb6\xdb",
+ .klen = 20,
+ .iv = "\xc0\x54\x3b\x59\xda\x48\xd9\x0b",
+ .input = "\x51\x04\xa1\x06\x16\x8a\x72\xd9"
+ "\x79\x0d\x41\xee\x8e\xda\xd3\x88"
+ "\xeb\x2e\x1e\xfc\x46\xda\x57\xc8"
+ "\xfc\xe6\x30\xdf\x91\x41\xbe\x28",
+ .ilen = 32,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .rlen = 32,
+ }, {
+ .key = "\x16\xaf\x5b\x14\x5f\xc9\xf5\x79"
+ "\xc1\x75\xf9\x3e\x3b\xfb\x0e\xed"
+ "\x86\x3d\x06\xcc\xfd\xb7\x85\x15"
+ "\x00\x00\x00\x48",
+ .klen = 28,
+ .iv = "\x36\x73\x3c\x14\x7d\x6d\x93\xcb",
+ .input = "\x4b\x55\x38\x4f\xe2\x59\xc9\xc8"
+ "\x4e\x79\x35\xa0\x03\xcb\xe9\x28",
+ .ilen = 16,
+ .result = "Single block msg",
+ .rlen = 16,
+ }, {
+ .key = "\x7c\x5c\xb2\x40\x1b\x3d\xc3\x3c"
+ "\x19\xe7\x34\x08\x19\xe0\xf6\x9c"
+ "\x67\x8c\x3d\xb8\xe6\xf6\xa9\x1a"
+ "\x00\x96\xb0\x3b",
+ .klen = 28,
+ .iv = "\x02\x0c\x6e\xad\xc2\xcb\x50\x0d",
+ .input = "\x45\x32\x43\xfc\x60\x9b\x23\x32"
+ "\x7e\xdf\xaa\xfa\x71\x31\xcd\x9f"
+ "\x84\x90\x70\x1c\x5a\xd4\xa7\x9c"
+ "\xfc\x1f\xe0\xff\x42\xf4\xfb\x00",
+ .ilen = 32,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .rlen = 32,
+ }, {
+ .key = "\x77\x6b\xef\xf2\x85\x1d\xb0\x6f"
+ "\x4c\x8a\x05\x42\xc8\x69\x6f\x6c"
+ "\x6a\x81\xaf\x1e\xec\x96\xb4\xd3"
+ "\x7f\xc1\xd6\x89\xe6\xc1\xc1\x04"
+ "\x00\x00\x00\x60",
+ .klen = 36,
+ .iv = "\xdb\x56\x72\xc9\x7a\xa8\xf0\xb2",
+ .input = "\x14\x5a\xd0\x1d\xbf\x82\x4e\xc7"
+ "\x56\x08\x63\xdc\x71\xe3\xe0\xc0",
+ .ilen = 16,
+ .result = "Single block msg",
+ .rlen = 16,
+ }, {
+ .key = "\xf6\xd6\x6d\x6b\xd5\x2d\x59\xbb"
+ "\x07\x96\x36\x58\x79\xef\xf8\x86"
+ "\xc6\x6d\xd5\x1a\x5b\x6a\x99\x74"
+ "\x4b\x50\x59\x0c\x87\xa2\x38\x84"
+ "\x00\xfa\xac\x24",
+ .klen = 36,
+ .iv = "\xc1\x58\x5e\xf1\x5a\x43\xd8\x75",
+ .input = "\xf0\x5e\x23\x1b\x38\x94\x61\x2c"
+ "\x49\xee\x00\x0b\x80\x4e\xb2\xa9"
+ "\xb8\x30\x6b\x50\x8f\x83\x9d\x6a"
+ "\x55\x30\x83\x1d\x93\x44\xaf\x1c",
+ .ilen = 32,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .rlen = 32,
+ },
+};
+
+static struct aead_testvec aes_gcm_enc_tv_template[] = {
+ { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */
+ .key = zeroed_string,
+ .klen = 16,
+ .result = "\x58\xe2\xfc\xce\xfa\x7e\x30\x61"
+ "\x36\x7f\x1d\x57\xa4\xe7\x45\x5a",
+ .rlen = 16,
+ }, {
+ .key = zeroed_string,
+ .klen = 16,
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\x03\x88\xda\xce\x60\xb6\xa3\x92"
+ "\xf3\x28\xc2\xb9\x71\xb2\xfe\x78"
+ "\xab\x6e\x47\xd4\x2c\xec\x13\xbd"
+ "\xf5\x3a\x67\xb2\x12\x57\xbd\xdf",
+ .rlen = 32,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+ .klen = 16,
+ .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+ "\xde\xca\xf8\x88",
+ .input = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+ "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+ "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+ "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+ "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+ .ilen = 64,
+ .result = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+ "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+ "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+ "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+ "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+ "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+ "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+ "\x3d\x58\xe0\x91\x47\x3f\x59\x85"
+ "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6"
+ "\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4",
+ .rlen = 80,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+ .klen = 16,
+ .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+ "\xde\xca\xf8\x88",
+ .input = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+ "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+ "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+ "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+ "\xba\x63\x7b\x39",
+ .ilen = 60,
+ .assoc = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xab\xad\xda\xd2",
+ .alen = 20,
+ .result = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+ "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+ "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+ "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+ "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+ "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+ "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+ "\x3d\x58\xe0\x91"
+ "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb"
+ "\x94\xfa\xe9\x5a\xe7\x12\x1a\x47",
+ .rlen = 76,
+ }, {
+ .key = zeroed_string,
+ .klen = 24,
+ .result = "\xcd\x33\xb2\x8a\xc7\x73\xf7\x4b"
+ "\xa0\x0e\xd1\xf3\x12\x57\x24\x35",
+ .rlen = 16,
+ }, {
+ .key = zeroed_string,
+ .klen = 24,
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\x98\xe7\x24\x7c\x07\xf0\xfe\x41"
+ "\x1c\x26\x7e\x43\x84\xb0\xf6\x00"
+ "\x2f\xf5\x8d\x80\x03\x39\x27\xab"
+ "\x8e\xf4\xd4\x58\x75\x14\xf0\xfb",
+ .rlen = 32,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+ .klen = 24,
+ .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+ "\xde\xca\xf8\x88",
+ .input = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+ "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+ "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+ "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+ "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+ .ilen = 64,
+ .result = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+ "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+ "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+ "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+ "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+ "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+ "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+ "\xcc\xda\x27\x10\xac\xad\xe2\x56"
+ "\x99\x24\xa7\xc8\x58\x73\x36\xbf"
+ "\xb1\x18\x02\x4d\xb8\x67\x4a\x14",
+ .rlen = 80,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+ .klen = 24,
+ .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+ "\xde\xca\xf8\x88",
+ .input = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+ "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+ "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+ "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+ "\xba\x63\x7b\x39",
+ .ilen = 60,
+ .assoc = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xab\xad\xda\xd2",
+ .alen = 20,
+ .result = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+ "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+ "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+ "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+ "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+ "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+ "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+ "\xcc\xda\x27\x10"
+ "\x25\x19\x49\x8e\x80\xf1\x47\x8f"
+ "\x37\xba\x55\xbd\x6d\x27\x61\x8c",
+ .rlen = 76,
+ .np = 2,
+ .tap = { 32, 28 },
+ .anp = 2,
+ .atap = { 8, 12 }
+ }, {
+ .key = zeroed_string,
+ .klen = 32,
+ .result = "\x53\x0f\x8a\xfb\xc7\x45\x36\xb9"
+ "\xa9\x63\xb4\xf1\xc4\xcb\x73\x8b",
+ .rlen = 16,
+ }
+};
+
+static struct aead_testvec aes_gcm_dec_tv_template[] = {
+ { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */
+ .key = zeroed_string,
+ .klen = 32,
+ .input = "\xce\xa7\x40\x3d\x4d\x60\x6b\x6e"
+ "\x07\x4e\xc5\xd3\xba\xf3\x9d\x18"
+ "\xd0\xd1\xc8\xa7\x99\x99\x6b\xf0"
+ "\x26\x5b\x98\xb5\xd4\x8a\xb9\x19",
+ .ilen = 32,
+ .result = zeroed_string,
+ .rlen = 16,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+ .klen = 32,
+ .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+ "\xde\xca\xf8\x88",
+ .input = "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
+ "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
+ "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
+ "\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
+ "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
+ "\xa7\xb0\x8b\x10\x56\x82\x88\x38"
+ "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
+ "\xbc\xc9\xf6\x62\x89\x80\x15\xad"
+ "\xb0\x94\xda\xc5\xd9\x34\x71\xbd"
+ "\xec\x1a\x50\x22\x70\xe3\xcc\x6c",
+ .ilen = 80,
+ .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+ "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+ "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+ "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+ "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+ .rlen = 64,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+ .klen = 32,
+ .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+ "\xde\xca\xf8\x88",
+ .input = "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
+ "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
+ "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
+ "\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
+ "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
+ "\xa7\xb0\x8b\x10\x56\x82\x88\x38"
+ "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
+ "\xbc\xc9\xf6\x62"
+ "\x76\xfc\x6e\xce\x0f\x4e\x17\x68"
+ "\xcd\xdf\x88\x53\xbb\x2d\x55\x1b",
+ .ilen = 76,
+ .assoc = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xab\xad\xda\xd2",
+ .alen = 20,
+ .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+ "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+ "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+ "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+ "\xba\x63\x7b\x39",
+ .rlen = 60,
+ .np = 2,
+ .tap = { 48, 28 },
+ .anp = 3,
+ .atap = { 8, 8, 4 }
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+ .klen = 16,
+ .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+ "\xde\xca\xf8\x88",
+ .input = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+ "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+ "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+ "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+ "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+ "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+ "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+ "\x3d\x58\xe0\x91\x47\x3f\x59\x85"
+ "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6"
+ "\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4",
+ .ilen = 80,
+ .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+ "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+ "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+ "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+ "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+ .rlen = 64,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+ .klen = 16,
+ .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+ "\xde\xca\xf8\x88",
+ .input = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+ "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+ "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+ "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+ "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+ "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+ "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+ "\x3d\x58\xe0\x91"
+ "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb"
+ "\x94\xfa\xe9\x5a\xe7\x12\x1a\x47",
+ .ilen = 76,
+ .assoc = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xab\xad\xda\xd2",
+ .alen = 20,
+ .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+ "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+ "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+ "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+ "\xba\x63\x7b\x39",
+ .rlen = 60,
+ }, {
+ .key = zeroed_string,
+ .klen = 24,
+ .input = "\x98\xe7\x24\x7c\x07\xf0\xfe\x41"
+ "\x1c\x26\x7e\x43\x84\xb0\xf6\x00"
+ "\x2f\xf5\x8d\x80\x03\x39\x27\xab"
+ "\x8e\xf4\xd4\x58\x75\x14\xf0\xfb",
+ .ilen = 32,
+ .result = zeroed_string,
+ .rlen = 16,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+ .klen = 24,
+ .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+ "\xde\xca\xf8\x88",
+ .input = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+ "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+ "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+ "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+ "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+ "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+ "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+ "\xcc\xda\x27\x10\xac\xad\xe2\x56"
+ "\x99\x24\xa7\xc8\x58\x73\x36\xbf"
+ "\xb1\x18\x02\x4d\xb8\x67\x4a\x14",
+ .ilen = 80,
+ .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+ "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+ "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+ "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+ "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+ .rlen = 64,
+ }, {
+ .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+ "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+ .klen = 24,
+ .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+ "\xde\xca\xf8\x88",
+ .input = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+ "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+ "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+ "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+ "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+ "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+ "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+ "\xcc\xda\x27\x10"
+ "\x25\x19\x49\x8e\x80\xf1\x47\x8f"
+ "\x37\xba\x55\xbd\x6d\x27\x61\x8c",
+ .ilen = 76,
+ .assoc = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xab\xad\xda\xd2",
+ .alen = 20,
+ .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+ "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+ "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+ "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+ "\xba\x63\x7b\x39",
+ .rlen = 60,
+ }
+};
+
+static struct aead_testvec aes_ccm_enc_tv_template[] = {
+ { /* From RFC 3610 */
+ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+ .klen = 16,
+ .iv = "\x01\x00\x00\x00\x03\x02\x01\x00"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07",
+ .alen = 8,
+ .input = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e",
+ .ilen = 23,
+ .result = "\x58\x8c\x97\x9a\x61\xc6\x63\xd2"
+ "\xf0\x66\xd0\xc2\xc0\xf9\x89\x80"
+ "\x6d\x5f\x6b\x61\xda\xc3\x84\x17"
+ "\xe8\xd1\x2c\xfd\xf9\x26\xe0",
+ .rlen = 31,
+ }, {
+ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+ .klen = 16,
+ .iv = "\x01\x00\x00\x00\x07\x06\x05\x04"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b",
+ .alen = 12,
+ .input = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+ "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+ "\x1c\x1d\x1e\x1f",
+ .ilen = 20,
+ .result = "\xdc\xf1\xfb\x7b\x5d\x9e\x23\xfb"
+ "\x9d\x4e\x13\x12\x53\x65\x8a\xd8"
+ "\x6e\xbd\xca\x3e\x51\xe8\x3f\x07"
+ "\x7d\x9c\x2d\x93",
+ .rlen = 28,
+ }, {
+ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+ .klen = 16,
+ .iv = "\x01\x00\x00\x00\x0b\x0a\x09\x08"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07",
+ .alen = 8,
+ .input = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20",
+ .ilen = 25,
+ .result = "\x82\x53\x1a\x60\xcc\x24\x94\x5a"
+ "\x4b\x82\x79\x18\x1a\xb5\xc8\x4d"
+ "\xf2\x1c\xe7\xf9\xb7\x3f\x42\xe1"
+ "\x97\xea\x9c\x07\xe5\x6b\x5e\xb1"
+ "\x7e\x5f\x4e",
+ .rlen = 35,
+ }, {
+ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+ .klen = 16,
+ .iv = "\x01\x00\x00\x00\x0c\x0b\x0a\x09"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b",
+ .alen = 12,
+ .input = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+ "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+ "\x1c\x1d\x1e",
+ .ilen = 19,
+ .result = "\x07\x34\x25\x94\x15\x77\x85\x15"
+ "\x2b\x07\x40\x98\x33\x0a\xbb\x14"
+ "\x1b\x94\x7b\x56\x6a\xa9\x40\x6b"
+ "\x4d\x99\x99\x88\xdd",
+ .rlen = 29,
+ }, {
+ .key = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+ "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+ .klen = 16,
+ .iv = "\x01\x00\x33\x56\x8e\xf7\xb2\x63"
+ "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+ .assoc = "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb",
+ .alen = 8,
+ .input = "\x90\x20\xea\x6f\x91\xbd\xd8\x5a"
+ "\xfa\x00\x39\xba\x4b\xaf\xf9\xbf"
+ "\xb7\x9c\x70\x28\x94\x9c\xd0\xec",
+ .ilen = 24,
+ .result = "\x4c\xcb\x1e\x7c\xa9\x81\xbe\xfa"
+ "\xa0\x72\x6c\x55\xd3\x78\x06\x12"
+ "\x98\xc8\x5c\x92\x81\x4a\xbc\x33"
+ "\xc5\x2e\xe8\x1d\x7d\x77\xc0\x8a",
+ .rlen = 32,
+ }, {
+ .key = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+ "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+ .klen = 16,
+ .iv = "\x01\x00\xd5\x60\x91\x2d\x3f\x70"
+ "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+ .assoc = "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81"
+ "\x20\xea\x60\xc0",
+ .alen = 12,
+ .input = "\x64\x35\xac\xba\xfb\x11\xa8\x2e"
+ "\x2f\x07\x1d\x7c\xa4\xa5\xeb\xd9"
+ "\x3a\x80\x3b\xa8\x7f",
+ .ilen = 21,
+ .result = "\x00\x97\x69\xec\xab\xdf\x48\x62"
+ "\x55\x94\xc5\x92\x51\xe6\x03\x57"
+ "\x22\x67\x5e\x04\xc8\x47\x09\x9e"
+ "\x5a\xe0\x70\x45\x51",
+ .rlen = 29,
+ }, {
+ .key = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+ "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+ .klen = 16,
+ .iv = "\x01\x00\x42\xff\xf8\xf1\x95\x1c"
+ "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+ .assoc = "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8",
+ .alen = 8,
+ .input = "\x8a\x19\xb9\x50\xbc\xf7\x1a\x01"
+ "\x8e\x5e\x67\x01\xc9\x17\x87\x65"
+ "\x98\x09\xd6\x7d\xbe\xdd\x18",
+ .ilen = 23,
+ .result = "\xbc\x21\x8d\xaa\x94\x74\x27\xb6"
+ "\xdb\x38\x6a\x99\xac\x1a\xef\x23"
+ "\xad\xe0\xb5\x29\x39\xcb\x6a\x63"
+ "\x7c\xf9\xbe\xc2\x40\x88\x97\xc6"
+ "\xba",
+ .rlen = 33,
+ },
+};
+
+static struct aead_testvec aes_ccm_dec_tv_template[] = {
+ { /* From RFC 3610 */
+ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+ .klen = 16,
+ .iv = "\x01\x00\x00\x00\x03\x02\x01\x00"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07",
+ .alen = 8,
+ .input = "\x58\x8c\x97\x9a\x61\xc6\x63\xd2"
+ "\xf0\x66\xd0\xc2\xc0\xf9\x89\x80"
+ "\x6d\x5f\x6b\x61\xda\xc3\x84\x17"
+ "\xe8\xd1\x2c\xfd\xf9\x26\xe0",
+ .ilen = 31,
+ .result = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e",
+ .rlen = 23,
+ }, {
+ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+ .klen = 16,
+ .iv = "\x01\x00\x00\x00\x07\x06\x05\x04"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b",
+ .alen = 12,
+ .input = "\xdc\xf1\xfb\x7b\x5d\x9e\x23\xfb"
+ "\x9d\x4e\x13\x12\x53\x65\x8a\xd8"
+ "\x6e\xbd\xca\x3e\x51\xe8\x3f\x07"
+ "\x7d\x9c\x2d\x93",
+ .ilen = 28,
+ .result = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+ "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+ "\x1c\x1d\x1e\x1f",
+ .rlen = 20,
+ }, {
+ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+ .klen = 16,
+ .iv = "\x01\x00\x00\x00\x0b\x0a\x09\x08"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07",
+ .alen = 8,
+ .input = "\x82\x53\x1a\x60\xcc\x24\x94\x5a"
+ "\x4b\x82\x79\x18\x1a\xb5\xc8\x4d"
+ "\xf2\x1c\xe7\xf9\xb7\x3f\x42\xe1"
+ "\x97\xea\x9c\x07\xe5\x6b\x5e\xb1"
+ "\x7e\x5f\x4e",
+ .ilen = 35,
+ .result = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20",
+ .rlen = 25,
+ }, {
+ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+ .klen = 16,
+ .iv = "\x01\x00\x00\x00\x0c\x0b\x0a\x09"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b",
+ .alen = 12,
+ .input = "\x07\x34\x25\x94\x15\x77\x85\x15"
+ "\x2b\x07\x40\x98\x33\x0a\xbb\x14"
+ "\x1b\x94\x7b\x56\x6a\xa9\x40\x6b"
+ "\x4d\x99\x99\x88\xdd",
+ .ilen = 29,
+ .result = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+ "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+ "\x1c\x1d\x1e",
+ .rlen = 19,
+ }, {
+ .key = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+ "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+ .klen = 16,
+ .iv = "\x01\x00\x33\x56\x8e\xf7\xb2\x63"
+ "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+ .assoc = "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb",
+ .alen = 8,
+ .input = "\x4c\xcb\x1e\x7c\xa9\x81\xbe\xfa"
+ "\xa0\x72\x6c\x55\xd3\x78\x06\x12"
+ "\x98\xc8\x5c\x92\x81\x4a\xbc\x33"
+ "\xc5\x2e\xe8\x1d\x7d\x77\xc0\x8a",
+ .ilen = 32,
+ .result = "\x90\x20\xea\x6f\x91\xbd\xd8\x5a"
+ "\xfa\x00\x39\xba\x4b\xaf\xf9\xbf"
+ "\xb7\x9c\x70\x28\x94\x9c\xd0\xec",
+ .rlen = 24,
+ }, {
+ .key = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+ "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+ .klen = 16,
+ .iv = "\x01\x00\xd5\x60\x91\x2d\x3f\x70"
+ "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+ .assoc = "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81"
+ "\x20\xea\x60\xc0",
+ .alen = 12,
+ .input = "\x00\x97\x69\xec\xab\xdf\x48\x62"
+ "\x55\x94\xc5\x92\x51\xe6\x03\x57"
+ "\x22\x67\x5e\x04\xc8\x47\x09\x9e"
+ "\x5a\xe0\x70\x45\x51",
+ .ilen = 29,
+ .result = "\x64\x35\xac\xba\xfb\x11\xa8\x2e"
+ "\x2f\x07\x1d\x7c\xa4\xa5\xeb\xd9"
+ "\x3a\x80\x3b\xa8\x7f",
+ .rlen = 21,
+ }, {
+ .key = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+ "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+ .klen = 16,
+ .iv = "\x01\x00\x42\xff\xf8\xf1\x95\x1c"
+ "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+ .assoc = "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8",
+ .alen = 8,
+ .input = "\xbc\x21\x8d\xaa\x94\x74\x27\xb6"
+ "\xdb\x38\x6a\x99\xac\x1a\xef\x23"
+ "\xad\xe0\xb5\x29\x39\xcb\x6a\x63"
+ "\x7c\xf9\xbe\xc2\x40\x88\x97\xc6"
+ "\xba",
+ .ilen = 33,
+ .result = "\x8a\x19\xb9\x50\xbc\xf7\x1a\x01"
+ "\x8e\x5e\x67\x01\xc9\x17\x87\x65"
+ "\x98\x09\xd6\x7d\xbe\xdd\x18",
+ .rlen = 23,
+ },
+};
+
+/*
+ * rfc4309 refers to section 8 of rfc3610 for test vectors, but they all
+ * use a 13-byte nonce, we only support an 11-byte nonce. Similarly, all of
+ * Special Publication 800-38C's test vectors also use nonce lengths our
+ * implementation doesn't support. The following are taken from fips cavs
+ * fax files on hand at Red Hat.
+ *
+ * nb: actual key lengths are (klen - 3), the last 3 bytes are actually
+ * part of the nonce which combine w/the iv, but need to be input this way.
+ */
+static struct aead_testvec aes_ccm_rfc4309_enc_tv_template[] = {
+ {
+ .key = "\x83\xac\x54\x66\xc2\xeb\xe5\x05"
+ "\x2e\x01\xd1\xfc\x5d\x82\x66\x2e"
+ "\x96\xac\x59",
+ .klen = 19,
+ .iv = "\x30\x07\xa1\xe2\xa2\xc7\x55\x24",
+ .alen = 0,
+ .input = "\x19\xc8\x81\xf6\xe9\x86\xff\x93"
+ "\x0b\x78\x67\xe5\xbb\xb7\xfc\x6e"
+ "\x83\x77\xb3\xa6\x0c\x8c\x9f\x9c"
+ "\x35\x2e\xad\xe0\x62\xf9\x91\xa1",
+ .ilen = 32,
+ .result = "\xab\x6f\xe1\x69\x1d\x19\x99\xa8"
+ "\x92\xa0\xc4\x6f\x7e\xe2\x8b\xb1"
+ "\x70\xbb\x8c\xa6\x4c\x6e\x97\x8a"
+ "\x57\x2b\xbe\x5d\x98\xa6\xb1\x32"
+ "\xda\x24\xea\xd9\xa1\x39\x98\xfd"
+ "\xa4\xbe\xd9\xf2\x1a\x6d\x22\xa8",
+ .rlen = 48,
+ }, {
+ .key = "\x1e\x2c\x7e\x01\x41\x9a\xef\xc0"
+ "\x0d\x58\x96\x6e\x5c\xa2\x4b\xd3"
+ "\x4f\xa3\x19",
+ .klen = 19,
+ .iv = "\xd3\x01\x5a\xd8\x30\x60\x15\x56",
+ .assoc = "\xda\xe6\x28\x9c\x45\x2d\xfd\x63"
+ "\x5e\xda\x4c\xb6\xe6\xfc\xf9\xb7"
+ "\x0c\x56\xcb\xe4\xe0\x05\x7a\xe1"
+ "\x0a\x63\x09\x78\xbc\x2c\x55\xde",
+ .alen = 32,
+ .input = "\x87\xa3\x36\xfd\x96\xb3\x93\x78"
+ "\xa9\x28\x63\xba\x12\xa3\x14\x85"
+ "\x57\x1e\x06\xc9\x7b\x21\xef\x76"
+ "\x7f\x38\x7e\x8e\x29\xa4\x3e\x7e",
+ .ilen = 32,
+ .result = "\x8a\x1e\x11\xf0\x02\x6b\xe2\x19"
+ "\xfc\x70\xc4\x6d\x8e\xb7\x99\xab"
+ "\xc5\x4b\xa2\xac\xd3\xf3\x48\xff"
+ "\x3b\xb5\xce\x53\xef\xde\xbb\x02"
+ "\xa9\x86\x15\x6c\x13\xfe\xda\x0a"
+ "\x22\xb8\x29\x3d\xd8\x39\x9a\x23",
+ .rlen = 48,
+ }, {
+ .key = "\xf4\x6b\xc2\x75\x62\xfe\xb4\xe1"
+ "\xa3\xf0\xff\xdd\x4e\x4b\x12\x75"
+ "\x53\x14\x73\x66\x8d\x88\xf6\x80"
+ "\xa0\x20\x35",
+ .klen = 27,
+ .iv = "\x26\xf2\x21\x8d\x50\x20\xda\xe2",
+ .assoc = "\x5b\x9e\x13\x67\x02\x5e\xef\xc1"
+ "\x6c\xf9\xd7\x1e\x52\x8f\x7a\x47"
+ "\xe9\xd4\xcf\x20\x14\x6e\xf0\x2d"
+ "\xd8\x9e\x2b\x56\x10\x23\x56\xe7",
+ .alen = 32,
+ .ilen = 0,
+ .result = "\x36\xea\x7a\x70\x08\xdc\x6a\xbc"
+ "\xad\x0c\x7a\x63\xf6\x61\xfd\x9b",
+ .rlen = 16,
+ }, {
+ .key = "\x56\xdf\x5c\x8f\x26\x3f\x0e\x42"
+ "\xef\x7a\xd3\xce\xfc\x84\x60\x62"
+ "\xca\xb4\x40\xaf\x5f\xc9\xc9\x01"
+ "\xd6\x3c\x8c",
+ .klen = 27,
+ .iv = "\x86\x84\xb6\xcd\xef\x09\x2e\x94",
+ .assoc = "\x02\x65\x78\x3c\xe9\x21\x30\x91"
+ "\xb1\xb9\xda\x76\x9a\x78\x6d\x95"
+ "\xf2\x88\x32\xa3\xf2\x50\xcb\x4c"
+ "\xe3\x00\x73\x69\x84\x69\x87\x79",
+ .alen = 32,
+ .input = "\x9f\xd2\x02\x4b\x52\x49\x31\x3c"
+ "\x43\x69\x3a\x2d\x8e\x70\xad\x7e"
+ "\xe0\xe5\x46\x09\x80\x89\x13\xb2"
+ "\x8c\x8b\xd9\x3f\x86\xfb\xb5\x6b",
+ .ilen = 32,
+ .result = "\x39\xdf\x7c\x3c\x5a\x29\xb9\x62"
+ "\x5d\x51\xc2\x16\xd8\xbd\x06\x9f"
+ "\x9b\x6a\x09\x70\xc1\x51\x83\xc2"
+ "\x66\x88\x1d\x4f\x9a\xda\xe0\x1e"
+ "\xc7\x79\x11\x58\xe5\x6b\x20\x40"
+ "\x7a\xea\x46\x42\x8b\xe4\x6f\xe1",
+ .rlen = 48,
+ }, {
+ .key = "\xe0\x8d\x99\x71\x60\xd7\x97\x1a"
+ "\xbd\x01\x99\xd5\x8a\xdf\x71\x3a"
+ "\xd3\xdf\x24\x4b\x5e\x3d\x4b\x4e"
+ "\x30\x7a\xb9\xd8\x53\x0a\x5e\x2b"
+ "\x1e\x29\x91",
+ .klen = 35,
+ .iv = "\xad\x8e\xc1\x53\x0a\xcf\x2d\xbe",
+ .assoc = "\x19\xb6\x1f\x57\xc4\xf3\xf0\x8b"
+ "\x78\x2b\x94\x02\x29\x0f\x42\x27"
+ "\x6b\x75\xcb\x98\x34\x08\x7e\x79"
+ "\xe4\x3e\x49\x0d\x84\x8b\x22\x87",
+ .alen = 32,
+ .input = "\xe1\xd9\xd8\x13\xeb\x3a\x75\x3f"
+ "\x9d\xbd\x5f\x66\xbe\xdc\xbb\x66"
+ "\xbf\x17\x99\x62\x4a\x39\x27\x1f"
+ "\x1d\xdc\x24\xae\x19\x2f\x98\x4c",
+ .ilen = 32,
+ .result = "\x19\xb8\x61\x33\x45\x2b\x43\x96"
+ "\x6f\x51\xd0\x20\x30\x7d\x9b\xc6"
+ "\x26\x3d\xf8\xc9\x65\x16\xa8\x9f"
+ "\xf0\x62\x17\x34\xf2\x1e\x8d\x75"
+ "\x4e\x13\xcc\xc0\xc3\x2a\x54\x2d",
+ .rlen = 40,
+ }, {
+ .key = "\x7c\xc8\x18\x3b\x8d\x99\xe0\x7c"
+ "\x45\x41\xb8\xbd\x5c\xa7\xc2\x32"
+ "\x8a\xb8\x02\x59\xa4\xfe\xa9\x2c"
+ "\x09\x75\x9a\x9b\x3c\x9b\x27\x39"
+ "\xf9\xd9\x4e",
+ .klen = 35,
+ .iv = "\x63\xb5\x3d\x9d\x43\xf6\x1e\x50",
+ .assoc = "\x57\xf5\x6b\x8b\x57\x5c\x3d\x3b"
+ "\x13\x02\x01\x0c\x83\x4c\x96\x35"
+ "\x8e\xd6\x39\xcf\x7d\x14\x9b\x94"
+ "\xb0\x39\x36\xe6\x8f\x57\xe0\x13",
+ .alen = 32,
+ .input = "\x3b\x6c\x29\x36\xb6\xef\x07\xa6"
+ "\x83\x72\x07\x4f\xcf\xfa\x66\x89"
+ "\x5f\xca\xb1\xba\xd5\x8f\x2c\x27"
+ "\x30\xdb\x75\x09\x93\xd4\x65\xe4",
+ .ilen = 32,
+ .result = "\xb0\x88\x5a\x33\xaa\xe5\xc7\x1d"
+ "\x85\x23\xc7\xc6\x2f\xf4\x1e\x3d"
+ "\xcc\x63\x44\x25\x07\x78\x4f\x9e"
+ "\x96\xb8\x88\xeb\xbc\x48\x1f\x06"
+ "\x39\xaf\x39\xac\xd8\x4a\x80\x39"
+ "\x7b\x72\x8a\xf7",
+ .rlen = 44,
+ }, {
+ .key = "\xab\xd0\xe9\x33\x07\x26\xe5\x83"
+ "\x8c\x76\x95\xd4\xb6\xdc\xf3\x46"
+ "\xf9\x8f\xad\xe3\x02\x13\x83\x77"
+ "\x3f\xb0\xf1\xa1\xa1\x22\x0f\x2b"
+ "\x24\xa7\x8b",
+ .klen = 35,
+ .iv = "\x07\xcb\xcc\x0e\xe6\x33\xbf\xf5",
+ .assoc = "\xd4\xdb\x30\x1d\x03\xfe\xfd\x5f"
+ "\x87\xd4\x8c\xb6\xb6\xf1\x7a\x5d"
+ "\xab\x90\x65\x8d\x8e\xca\x4d\x4f"
+ "\x16\x0c\x40\x90\x4b\xc7\x36\x73",
+ .alen = 32,
+ .input = "\xf5\xc6\x7d\x48\xc1\xb7\xe6\x92"
+ "\x97\x5a\xca\xc4\xa9\x6d\xf9\x3d"
+ "\x6c\xde\xbc\xf1\x90\xea\x6a\xb2"
+ "\x35\x86\x36\xaf\x5c\xfe\x4b\x3a",
+ .ilen = 32,
+ .result = "\x83\x6f\x40\x87\x72\xcf\xc1\x13"
+ "\xef\xbb\x80\x21\x04\x6c\x58\x09"
+ "\x07\x1b\xfc\xdf\xc0\x3f\x5b\xc7"
+ "\xe0\x79\xa8\x6e\x71\x7c\x3f\xcf"
+ "\x5c\xda\xb2\x33\xe5\x13\xe2\x0d"
+ "\x74\xd1\xef\xb5\x0f\x3a\xb5\xf8",
+ .rlen = 48,
+ },
+};
+
+static struct aead_testvec aes_ccm_rfc4309_dec_tv_template[] = {
+ {
+ .key = "\xab\x2f\x8a\x74\xb7\x1c\xd2\xb1"
+ "\xff\x80\x2e\x48\x7d\x82\xf8\xb9"
+ "\xc6\xfb\x7d",
+ .klen = 19,
+ .iv = "\x80\x0d\x13\xab\xd8\xa6\xb2\xd8",
+ .alen = 0,
+ .input = "\xd5\xe8\x93\x9f\xc7\x89\x2e\x2b",
+ .ilen = 8,
+ .result = "\x00",
+ .rlen = 0,
+ .novrfy = 1,
+ }, {
+ .key = "\xab\x2f\x8a\x74\xb7\x1c\xd2\xb1"
+ "\xff\x80\x2e\x48\x7d\x82\xf8\xb9"
+ "\xaf\x94\x87",
+ .klen = 19,
+ .iv = "\x78\x35\x82\x81\x7f\x88\x94\x68",
+ .alen = 0,
+ .input = "\x41\x3c\xb8\x87\x73\xcb\xf3\xf3",
+ .ilen = 8,
+ .result = "\x00",
+ .rlen = 0,
+ }, {
+ .key = "\x61\x0e\x8c\xae\xe3\x23\xb6\x38"
+ "\x76\x1c\xf6\x3a\x67\xa3\x9c\xd8"
+ "\xc6\xfb\x7d",
+ .klen = 19,
+ .iv = "\x80\x0d\x13\xab\xd8\xa6\xb2\xd8",
+ .assoc = "\xf3\x94\x87\x78\x35\x82\x81\x7f"
+ "\x88\x94\x68\xb1\x78\x6b\x2b\xd6"
+ "\x04\x1f\x4e\xed\x78\xd5\x33\x66"
+ "\xd8\x94\x99\x91\x81\x54\x62\x57",
+ .alen = 32,
+ .input = "\xf0\x7c\x29\x02\xae\x1c\x2f\x55"
+ "\xd0\xd1\x3d\x1a\xa3\x6d\xe4\x0a"
+ "\x86\xb0\x87\x6b\x62\x33\x8c\x34"
+ "\xce\xab\x57\xcc\x79\x0b\xe0\x6f"
+ "\x5c\x3e\x48\x1f\x6c\x46\xf7\x51"
+ "\x8b\x84\x83\x2a\xc1\x05\xb8\xc5",
+ .ilen = 48,
+ .result = "\x50\x82\x3e\x07\xe2\x1e\xb6\xfb"
+ "\x33\xe4\x73\xce\xd2\xfb\x95\x79"
+ "\xe8\xb4\xb5\x77\x11\x10\x62\x6f"
+ "\x6a\x82\xd1\x13\xec\xf5\xd0\x48",
+ .rlen = 32,
+ .novrfy = 1,
+ }, {
+ .key = "\x61\x0e\x8c\xae\xe3\x23\xb6\x38"
+ "\x76\x1c\xf6\x3a\x67\xa3\x9c\xd8"
+ "\x05\xe0\xc9",
+ .klen = 19,
+ .iv = "\x0f\xed\x34\xea\x97\xd4\x3b\xdf",
+ .assoc = "\x49\x5c\x50\x1f\x1d\x94\xcc\x81"
+ "\xba\xb7\xb6\x03\xaf\xa5\xc1\xa1"
+ "\xd8\x5c\x42\x68\xe0\x6c\xda\x89"
+ "\x05\xac\x56\xac\x1b\x2a\xd3\x86",
+ .alen = 32,
+ .input = "\x39\xbe\x7d\x15\x62\x77\xf3\x3c"
+ "\xad\x83\x52\x6d\x71\x03\x25\x1c"
+ "\xed\x81\x3a\x9a\x16\x7d\x19\x80"
+ "\x72\x04\x72\xd0\xf6\xff\x05\x0f"
+ "\xb7\x14\x30\x00\x32\x9e\xa0\xa6"
+ "\x9e\x5a\x18\xa1\xb8\xfe\xdb\xd3",
+ .ilen = 48,
+ .result = "\x75\x05\xbe\xc2\xd9\x1e\xde\x60"
+ "\x47\x3d\x8c\x7d\xbd\xb5\xd9\xb7"
+ "\xf2\xae\x61\x05\x8f\x82\x24\x3f"
+ "\x9c\x67\x91\xe1\x38\x4f\xe4\x0c",
+ .rlen = 32,
+ }, {
+ .key = "\x39\xbb\xa7\xbe\x59\x97\x9e\x73"
+ "\xa2\xbc\x6b\x98\xd7\x75\x7f\xe3"
+ "\xa4\x48\x93\x39\x26\x71\x4a\xc6"
+ "\xee\x49\x83",
+ .klen = 27,
+ .iv = "\xe9\xa9\xff\xe9\x57\xba\xfd\x9e",
+ .assoc = "\x44\xa6\x2c\x05\xe9\xe1\x43\xb1"
+ "\x58\x7c\xf2\x5c\x6d\x39\x0a\x64"
+ "\xa4\xf0\x13\x05\xd1\x77\x99\x67"
+ "\x11\xc4\xc6\xdb\x00\x56\x36\x61",
+ .alen = 32,
+ .input = "\x71\x99\xfa\xf4\x44\x12\x68\x9b",
+ .ilen = 8,
+ .result = "\x00",
+ .rlen = 0,
+ }, {
+ .key = "\x58\x5d\xa0\x96\x65\x1a\x04\xd7"
+ "\x96\xe5\xc5\x68\xaa\x95\x35\xe0"
+ "\x29\xa0\xba\x9e\x48\x78\xd1\xba"
+ "\xee\x49\x83",
+ .klen = 27,
+ .iv = "\xe9\xa9\xff\xe9\x57\xba\xfd\x9e",
+ .assoc = "\x44\xa6\x2c\x05\xe9\xe1\x43\xb1"
+ "\x58\x7c\xf2\x5c\x6d\x39\x0a\x64"
+ "\xa4\xf0\x13\x05\xd1\x77\x99\x67"
+ "\x11\xc4\xc6\xdb\x00\x56\x36\x61",
+ .alen = 32,
+ .input = "\xfb\xe5\x5d\x34\xbe\xe5\xe8\xe7"
+ "\x5a\xef\x2f\xbf\x1f\x7f\xd4\xb2"
+ "\x66\xca\x61\x1e\x96\x7a\x61\xb3"
+ "\x1c\x16\x45\x52\xba\x04\x9c\x9f"
+ "\xb1\xd2\x40\xbc\x52\x7c\x6f\xb1",
+ .ilen = 40,
+ .result = "\x85\x34\x66\x42\xc8\x92\x0f\x36"
+ "\x58\xe0\x6b\x91\x3c\x98\x5c\xbb"
+ "\x0a\x85\xcc\x02\xad\x7a\x96\xe9"
+ "\x65\x43\xa4\xc3\x0f\xdc\x55\x81",
+ .rlen = 32,
+ }, {
+ .key = "\x58\x5d\xa0\x96\x65\x1a\x04\xd7"
+ "\x96\xe5\xc5\x68\xaa\x95\x35\xe0"
+ "\x29\xa0\xba\x9e\x48\x78\xd1\xba"
+ "\xd1\xfc\x57",
+ .klen = 27,
+ .iv = "\x9c\xfe\xb8\x9c\xad\x71\xaa\x1f",
+ .assoc = "\x86\x67\xa5\xa9\x14\x5f\x0d\xc6"
+ "\xff\x14\xc7\x44\xbf\x6c\x3a\xc3"
+ "\xff\xb6\x81\xbd\xe2\xd5\x06\xc7"
+ "\x3c\xa1\x52\x13\x03\x8a\x23\x3a",
+ .alen = 32,
+ .input = "\x3f\x66\xb0\x9d\xe5\x4b\x38\x00"
+ "\xc6\x0e\x6e\xe5\xd6\x98\xa6\x37"
+ "\x8c\x26\x33\xc6\xb2\xa2\x17\xfa"
+ "\x64\x19\xc0\x30\xd7\xfc\x14\x6b"
+ "\xe3\x33\xc2\x04\xb0\x37\xbe\x3f"
+ "\xa9\xb4\x2d\x68\x03\xa3\x44\xef",
+ .ilen = 48,
+ .result = "\x02\x87\x4d\x28\x80\x6e\xb2\xed"
+ "\x99\x2a\xa8\xca\x04\x25\x45\x90"
+ "\x1d\xdd\x5a\xd9\xe4\xdb\x9c\x9c"
+ "\x49\xe9\x01\xfe\xa7\x80\x6d\x6b",
+ .rlen = 32,
+ .novrfy = 1,
+ }, {
+ .key = "\xa4\x4b\x54\x29\x0a\xb8\x6d\x01"
+ "\x5b\x80\x2a\xcf\x25\xc4\xb7\x5c"
+ "\x20\x2c\xad\x30\xc2\x2b\x41\xfb"
+ "\x0e\x85\xbc\x33\xad\x0f\x2b\xff"
+ "\xee\x49\x83",
+ .klen = 35,
+ .iv = "\xe9\xa9\xff\xe9\x57\xba\xfd\x9e",
+ .alen = 0,
+ .input = "\x1f\xb8\x8f\xa3\xdd\x54\x00\xf2",
+ .ilen = 8,
+ .result = "\x00",
+ .rlen = 0,
+ }, {
+ .key = "\x39\xbb\xa7\xbe\x59\x97\x9e\x73"
+ "\xa2\xbc\x6b\x98\xd7\x75\x7f\xe3"
+ "\xa4\x48\x93\x39\x26\x71\x4a\xc6"
+ "\xae\x8f\x11\x4c\xc2\x9c\x4a\xbb"
+ "\x85\x34\x66",
+ .klen = 35,
+ .iv = "\x42\xc8\x92\x0f\x36\x58\xe0\x6b",
+ .alen = 0,
+ .input = "\x48\x01\x5e\x02\x24\x04\x66\x47"
+ "\xa1\xea\x6f\xaf\xe8\xfc\xfb\xdd"
+ "\xa5\xa9\x87\x8d\x84\xee\x2e\x77"
+ "\xbb\x86\xb9\xf5\x5c\x6c\xff\xf6"
+ "\x72\xc3\x8e\xf7\x70\xb1\xb2\x07"
+ "\xbc\xa8\xa3\xbd\x83\x7c\x1d\x2a",
+ .ilen = 48,
+ .result = "\xdc\x56\xf2\x71\xb0\xb1\xa0\x6c"
+ "\xf0\x97\x3a\xfb\x6d\xe7\x32\x99"
+ "\x3e\xaf\x70\x5e\xb2\x4d\xea\x39"
+ "\x89\xd4\x75\x7a\x63\xb1\xda\x93",
+ .rlen = 32,
+ .novrfy = 1,
+ }, {
+ .key = "\x58\x5d\xa0\x96\x65\x1a\x04\xd7"
+ "\x96\xe5\xc5\x68\xaa\x95\x35\xe0"
+ "\x29\xa0\xba\x9e\x48\x78\xd1\xba"
+ "\x0d\x1a\x53\x3b\xb5\xe3\xf8\x8b"
+ "\xcf\x76\x3f",
+ .klen = 35,
+ .iv = "\xd9\x95\x75\x8f\x44\x89\x40\x7b",
+ .assoc = "\x8f\x86\x6c\x4d\x1d\xc5\x39\x88"
+ "\xc8\xf3\x5c\x52\x10\x63\x6f\x2b"
+ "\x8a\x2a\xc5\x6f\x30\x23\x58\x7b"
+ "\xfb\x36\x03\x11\xb4\xd9\xf2\xfe",
+ .alen = 32,
+ .input = "\x48\x58\xd6\xf3\xad\x63\x58\xbf"
+ "\xae\xc7\x5e\xae\x83\x8f\x7b\xe4"
+ "\x78\x5c\x4c\x67\x71\x89\x94\xbf"
+ "\x47\xf1\x63\x7e\x1c\x59\xbd\xc5"
+ "\x7f\x44\x0a\x0c\x01\x18\x07\x92"
+ "\xe1\xd3\x51\xce\x32\x6d\x0c\x5b",
+ .ilen = 48,
+ .result = "\xc2\x54\xc8\xde\x78\x87\x77\x40"
+ "\x49\x71\xe4\xb7\xe7\xcb\x76\x61"
+ "\x0a\x41\xb9\xe9\xc0\x76\x54\xab"
+ "\x04\x49\x3b\x19\x93\x57\x25\x5d",
+ .rlen = 32,
+ },
+};
+
+/*
+ * ANSI X9.31 Continuous Pseudo-Random Number Generator (
+ * test vectors, taken from Appendix B.2.9 and B.2.10:
+ * http://csrc.nist.gov/groups/STM/cavp/documents/rng/RNGVS.pdf
+ * Only AES-128 is supported at this time.
+ */
+#define ANSI_CPRNG_AES_TEST_VECTORS 6
+
+static struct cprng_testvec ansi_cprng_aes_tv_template[] = {
+ {
+ .key = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+ "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+ .klen = 16,
+ .dt = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+ "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xf9",
+ .dtlen = 16,
+ .v = "\x80\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .vlen = 16,
+ .result = "\x59\x53\x1e\xd1\x3b\xb0\xc0\x55"
+ "\x84\x79\x66\x85\xc1\x2f\x76\x41",
+ .rlen = 16,
+ .loops = 1,
+ }, {
+ .key = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+ "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+ .klen = 16,
+ .dt = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+ "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfa",
+ .dtlen = 16,
+ .v = "\xc0\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .vlen = 16,
+ .result = "\x7c\x22\x2c\xf4\xca\x8f\xa2\x4c"
+ "\x1c\x9c\xb6\x41\xa9\xf3\x22\x0d",
+ .rlen = 16,
+ .loops = 1,
+ }, {
+ .key = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+ "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+ .klen = 16,
+ .dt = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+ "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfb",
+ .dtlen = 16,
+ .v = "\xe0\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .vlen = 16,
+ .result = "\x8a\xaa\x00\x39\x66\x67\x5b\xe5"
+ "\x29\x14\x28\x81\xa9\x4d\x4e\xc7",
+ .rlen = 16,
+ .loops = 1,
+ }, {
+ .key = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+ "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+ .klen = 16,
+ .dt = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+ "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfc",
+ .dtlen = 16,
+ .v = "\xf0\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .vlen = 16,
+ .result = "\x88\xdd\xa4\x56\x30\x24\x23\xe5"
+ "\xf6\x9d\xa5\x7e\x7b\x95\xc7\x3a",
+ .rlen = 16,
+ .loops = 1,
+ }, {
+ .key = "\xf3\xb1\x66\x6d\x13\x60\x72\x42"
+ "\xed\x06\x1c\xab\xb8\xd4\x62\x02",
+ .klen = 16,
+ .dt = "\xe6\xb3\xbe\x78\x2a\x23\xfa\x62"
+ "\xd7\x1d\x4a\xfb\xb0\xe9\x22\xfd",
+ .dtlen = 16,
+ .v = "\xf8\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .vlen = 16,
+ .result = "\x05\x25\x92\x46\x61\x79\xd2\xcb"
+ "\x78\xc4\x0b\x14\x0a\x5a\x9a\xc8",
+ .rlen = 16,
+ .loops = 1,
+ }, { /* Monte Carlo Test */
+ .key = "\x9f\x5b\x51\x20\x0b\xf3\x34\xb5"
+ "\xd8\x2b\xe8\xc3\x72\x55\xc8\x48",
+ .klen = 16,
+ .dt = "\x63\x76\xbb\xe5\x29\x02\xba\x3b"
+ "\x67\xc9\x25\xfa\x70\x1f\x11\xac",
+ .dtlen = 16,
+ .v = "\x57\x2c\x8e\x76\x87\x26\x47\x97"
+ "\x7e\x74\xfb\xdd\xc4\x95\x01\xd1",
+ .vlen = 16,
+ .result = "\x48\xe9\xbd\x0d\x06\xee\x18\xfb"
+ "\xe4\x57\x90\xd5\xc3\xfc\x9b\x73",
+ .rlen = 16,
+ .loops = 10000,
+ },
+};
+
+/* Cast5 test vectors from RFC 2144 */
+#define CAST5_ENC_TEST_VECTORS 3
+#define CAST5_DEC_TEST_VECTORS 3
+
+static struct cipher_testvec cast5_enc_tv_template[] = {
+ {
+ .key = "\x01\x23\x45\x67\x12\x34\x56\x78"
+ "\x23\x45\x67\x89\x34\x56\x78\x9a",
+ .klen = 16,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .ilen = 8,
+ .result = "\x23\x8b\x4f\xe5\x84\x7e\x44\xb2",
+ .rlen = 8,
+ }, {
+ .key = "\x01\x23\x45\x67\x12\x34\x56\x78"
+ "\x23\x45",
+ .klen = 10,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .ilen = 8,
+ .result = "\xeb\x6a\x71\x1a\x2c\x02\x27\x1b",
+ .rlen = 8,
+ }, {
+ .key = "\x01\x23\x45\x67\x12",
+ .klen = 5,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .ilen = 8,
+ .result = "\x7a\xc8\x16\xd1\x6e\x9b\x30\x2e",
+ .rlen = 8,
+ },
+};
+
+static struct cipher_testvec cast5_dec_tv_template[] = {
+ {
+ .key = "\x01\x23\x45\x67\x12\x34\x56\x78"
+ "\x23\x45\x67\x89\x34\x56\x78\x9a",
+ .klen = 16,
+ .input = "\x23\x8b\x4f\xe5\x84\x7e\x44\xb2",
+ .ilen = 8,
+ .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .rlen = 8,
+ }, {
+ .key = "\x01\x23\x45\x67\x12\x34\x56\x78"
+ "\x23\x45",
+ .klen = 10,
+ .input = "\xeb\x6a\x71\x1a\x2c\x02\x27\x1b",
+ .ilen = 8,
+ .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .rlen = 8,
+ }, {
+ .key = "\x01\x23\x45\x67\x12",
+ .klen = 5,
+ .input = "\x7a\xc8\x16\xd1\x6e\x9b\x30\x2e",
+ .ilen = 8,
+ .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .rlen = 8,
+ },
+};
+
+/*
+ * ARC4 test vectors from OpenSSL
+ */
+#define ARC4_ENC_TEST_VECTORS 7
+#define ARC4_DEC_TEST_VECTORS 7
+
+static struct cipher_testvec arc4_enc_tv_template[] = {
+ {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .ilen = 8,
+ .result = "\x75\xb7\x87\x80\x99\xe0\xc5\x96",
+ .rlen = 8,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 8,
+ .result = "\x74\x94\xc2\xe7\x10\x4b\x08\x79",
+ .rlen = 8,
+ }, {
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 8,
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 8,
+ .result = "\xde\x18\x89\x41\xa3\x37\x5d\x3a",
+ .rlen = 8,
+ }, {
+ .key = "\xef\x01\x23\x45",
+ .klen = 4,
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00",
+ .ilen = 20,
+ .result = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+ "\xbd\x61\x5a\x11\x62\xe1\xc7\xba"
+ "\x36\xb6\x78\x58",
+ .rlen = 20,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+ "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+ "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+ "\x12\x34\x56\x78",
+ .ilen = 28,
+ .result = "\x66\xa0\x94\x9f\x8a\xf7\xd6\x89"
+ "\x1f\x7f\x83\x2b\xa8\x33\xc0\x0c"
+ "\x89\x2e\xbe\x30\x14\x3c\xe2\x87"
+ "\x40\x01\x1e\xcf",
+ .rlen = 28,
+ }, {
+ .key = "\xef\x01\x23\x45",
+ .klen = 4,
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00",
+ .ilen = 10,
+ .result = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+ "\xbd\x61",
+ .rlen = 10,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 16,
+ .input = "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
+ .ilen = 8,
+ .result = "\x69\x72\x36\x59\x1B\x52\x42\xB1",
+ .rlen = 8,
+ },
+};
+
+static struct cipher_testvec arc4_dec_tv_template[] = {
+ {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x75\xb7\x87\x80\x99\xe0\xc5\x96",
+ .ilen = 8,
+ .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .rlen = 8,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x74\x94\xc2\xe7\x10\x4b\x08\x79",
+ .ilen = 8,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .rlen = 8,
+ }, {
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 8,
+ .input = "\xde\x18\x89\x41\xa3\x37\x5d\x3a",
+ .ilen = 8,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .rlen = 8,
+ }, {
+ .key = "\xef\x01\x23\x45",
+ .klen = 4,
+ .input = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+ "\xbd\x61\x5a\x11\x62\xe1\xc7\xba"
+ "\x36\xb6\x78\x58",
+ .ilen = 20,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00",
+ .rlen = 20,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+ .klen = 8,
+ .input = "\x66\xa0\x94\x9f\x8a\xf7\xd6\x89"
+ "\x1f\x7f\x83\x2b\xa8\x33\xc0\x0c"
+ "\x89\x2e\xbe\x30\x14\x3c\xe2\x87"
+ "\x40\x01\x1e\xcf",
+ .ilen = 28,
+ .result = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+ "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+ "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+ "\x12\x34\x56\x78",
+ .rlen = 28,
+ }, {
+ .key = "\xef\x01\x23\x45",
+ .klen = 4,
+ .input = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+ "\xbd\x61",
+ .ilen = 10,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00",
+ .rlen = 10,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 16,
+ .input = "\x69\x72\x36\x59\x1B\x52\x42\xB1",
+ .ilen = 8,
+ .result = "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
+ .rlen = 8,
+ },
+};
+
+/*
+ * TEA test vectors
+ */
+#define TEA_ENC_TEST_VECTORS 4
+#define TEA_DEC_TEST_VECTORS 4
+
+static struct cipher_testvec tea_enc_tv_template[] = {
+ {
+ .key = zeroed_string,
+ .klen = 16,
+ .input = zeroed_string,
+ .ilen = 8,
+ .result = "\x0a\x3a\xea\x41\x40\xa9\xba\x94",
+ .rlen = 8,
+ }, {
+ .key = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+ "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+ .klen = 16,
+ .input = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+ .ilen = 8,
+ .result = "\x77\x5d\x2a\x6a\xf6\xce\x92\x09",
+ .rlen = 8,
+ }, {
+ .key = "\x09\x65\x43\x11\x66\x44\x39\x25"
+ "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+ .klen = 16,
+ .input = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+ "\x65\x73\x74\x5f\x76\x65\x63\x74",
+ .ilen = 16,
+ .result = "\xbe\x7a\xbb\x81\x95\x2d\x1f\x1e"
+ "\xdd\x89\xa1\x25\x04\x21\xdf\x95",
+ .rlen = 16,
+ }, {
+ .key = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+ "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+ .klen = 16,
+ .input = "\x54\x65\x61\x20\x69\x73\x20\x67"
+ "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+ "\x79\x6f\x75\x21\x21\x21\x20\x72"
+ "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+ .ilen = 32,
+ .result = "\xe0\x4d\x5d\x3c\xb7\x8c\x36\x47"
+ "\x94\x18\x95\x91\xa9\xfc\x49\xf8"
+ "\x44\xd1\x2d\xc2\x99\xb8\x08\x2a"
+ "\x07\x89\x73\xc2\x45\x92\xc6\x90",
+ .rlen = 32,
+ }
+};
+
+static struct cipher_testvec tea_dec_tv_template[] = {
+ {
+ .key = zeroed_string,
+ .klen = 16,
+ .input = "\x0a\x3a\xea\x41\x40\xa9\xba\x94",
+ .ilen = 8,
+ .result = zeroed_string,
+ .rlen = 8,
+ }, {
+ .key = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+ "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+ .klen = 16,
+ .input = "\x77\x5d\x2a\x6a\xf6\xce\x92\x09",
+ .ilen = 8,
+ .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+ .rlen = 8,
+ }, {
+ .key = "\x09\x65\x43\x11\x66\x44\x39\x25"
+ "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+ .klen = 16,
+ .input = "\xbe\x7a\xbb\x81\x95\x2d\x1f\x1e"
+ "\xdd\x89\xa1\x25\x04\x21\xdf\x95",
+ .ilen = 16,
+ .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+ "\x65\x73\x74\x5f\x76\x65\x63\x74",
+ .rlen = 16,
+ }, {
+ .key = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+ "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+ .klen = 16,
+ .input = "\xe0\x4d\x5d\x3c\xb7\x8c\x36\x47"
+ "\x94\x18\x95\x91\xa9\xfc\x49\xf8"
+ "\x44\xd1\x2d\xc2\x99\xb8\x08\x2a"
+ "\x07\x89\x73\xc2\x45\x92\xc6\x90",
+ .ilen = 32,
+ .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
+ "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+ "\x79\x6f\x75\x21\x21\x21\x20\x72"
+ "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+ .rlen = 32,
+ }
+};
+
+/*
+ * XTEA test vectors
+ */
+#define XTEA_ENC_TEST_VECTORS 4
+#define XTEA_DEC_TEST_VECTORS 4
+
+static struct cipher_testvec xtea_enc_tv_template[] = {
+ {
+ .key = zeroed_string,
+ .klen = 16,
+ .input = zeroed_string,
+ .ilen = 8,
+ .result = "\xd8\xd4\xe9\xde\xd9\x1e\x13\xf7",
+ .rlen = 8,
+ }, {
+ .key = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+ "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+ .klen = 16,
+ .input = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+ .ilen = 8,
+ .result = "\x94\xeb\xc8\x96\x84\x6a\x49\xa8",
+ .rlen = 8,
+ }, {
+ .key = "\x09\x65\x43\x11\x66\x44\x39\x25"
+ "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+ .klen = 16,
+ .input = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+ "\x65\x73\x74\x5f\x76\x65\x63\x74",
+ .ilen = 16,
+ .result = "\x3e\xce\xae\x22\x60\x56\xa8\x9d"
+ "\x77\x4d\xd4\xb4\x87\x24\xe3\x9a",
+ .rlen = 16,
+ }, {
+ .key = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+ "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+ .klen = 16,
+ .input = "\x54\x65\x61\x20\x69\x73\x20\x67"
+ "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+ "\x79\x6f\x75\x21\x21\x21\x20\x72"
+ "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+ .ilen = 32,
+ .result = "\x99\x81\x9f\x5d\x6f\x4b\x31\x3a"
+ "\x86\xff\x6f\xd0\xe3\x87\x70\x07"
+ "\x4d\xb8\xcf\xf3\x99\x50\xb3\xd4"
+ "\x73\xa2\xfa\xc9\x16\x59\x5d\x81",
+ .rlen = 32,
+ }
+};
+
+static struct cipher_testvec xtea_dec_tv_template[] = {
+ {
+ .key = zeroed_string,
+ .klen = 16,
+ .input = "\xd8\xd4\xe9\xde\xd9\x1e\x13\xf7",
+ .ilen = 8,
+ .result = zeroed_string,
+ .rlen = 8,
+ }, {
+ .key = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+ "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+ .klen = 16,
+ .input = "\x94\xeb\xc8\x96\x84\x6a\x49\xa8",
+ .ilen = 8,
+ .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+ .rlen = 8,
+ }, {
+ .key = "\x09\x65\x43\x11\x66\x44\x39\x25"
+ "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+ .klen = 16,
+ .input = "\x3e\xce\xae\x22\x60\x56\xa8\x9d"
+ "\x77\x4d\xd4\xb4\x87\x24\xe3\x9a",
+ .ilen = 16,
+ .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+ "\x65\x73\x74\x5f\x76\x65\x63\x74",
+ .rlen = 16,
+ }, {
+ .key = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+ "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+ .klen = 16,
+ .input = "\x99\x81\x9f\x5d\x6f\x4b\x31\x3a"
+ "\x86\xff\x6f\xd0\xe3\x87\x70\x07"
+ "\x4d\xb8\xcf\xf3\x99\x50\xb3\xd4"
+ "\x73\xa2\xfa\xc9\x16\x59\x5d\x81",
+ .ilen = 32,
+ .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
+ "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+ "\x79\x6f\x75\x21\x21\x21\x20\x72"
+ "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+ .rlen = 32,
+ }
+};
+
+/*
+ * KHAZAD test vectors.
+ */
+#define KHAZAD_ENC_TEST_VECTORS 5
+#define KHAZAD_DEC_TEST_VECTORS 5
+
+static struct cipher_testvec khazad_enc_tv_template[] = {
+ {
+ .key = "\x80\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 16,
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 8,
+ .result = "\x49\xa4\xce\x32\xac\x19\x0e\x3f",
+ .rlen = 8,
+ }, {
+ .key = "\x38\x38\x38\x38\x38\x38\x38\x38"
+ "\x38\x38\x38\x38\x38\x38\x38\x38",
+ .klen = 16,
+ .input = "\x38\x38\x38\x38\x38\x38\x38\x38",
+ .ilen = 8,
+ .result = "\x7e\x82\x12\xa1\xd9\x5b\xe4\xf9",
+ .rlen = 8,
+ }, {
+ .key = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2"
+ "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+ .klen = 16,
+ .input = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+ .ilen = 8,
+ .result = "\xaa\xbe\xc1\x95\xc5\x94\x1a\x9c",
+ .rlen = 8,
+ }, {
+ .key = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+ "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+ .klen = 16,
+ .input = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+ .ilen = 8,
+ .result = "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+ .rlen = 8,
+ }, {
+ .key = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+ "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+ .klen = 16,
+ .input = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+ "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+ .ilen = 16,
+ .result = "\x04\x74\xf5\x70\x50\x16\xd3\xb8"
+ "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec khazad_dec_tv_template[] = {
+ {
+ .key = "\x80\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 16,
+ .input = "\x49\xa4\xce\x32\xac\x19\x0e\x3f",
+ .ilen = 8,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .rlen = 8,
+ }, {
+ .key = "\x38\x38\x38\x38\x38\x38\x38\x38"
+ "\x38\x38\x38\x38\x38\x38\x38\x38",
+ .klen = 16,
+ .input = "\x7e\x82\x12\xa1\xd9\x5b\xe4\xf9",
+ .ilen = 8,
+ .result = "\x38\x38\x38\x38\x38\x38\x38\x38",
+ .rlen = 8,
+ }, {
+ .key = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2"
+ "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+ .klen = 16,
+ .input = "\xaa\xbe\xc1\x95\xc5\x94\x1a\x9c",
+ .ilen = 8,
+ .result = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+ .rlen = 8,
+ }, {
+ .key = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+ "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+ .klen = 16,
+ .input = "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+ .ilen = 8,
+ .result = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+ .rlen = 8,
+ }, {
+ .key = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+ "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+ .klen = 16,
+ .input = "\x04\x74\xf5\x70\x50\x16\xd3\xb8"
+ "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+ .ilen = 16,
+ .result = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+ "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+ .rlen = 16,
+ },
+};
+
+/*
+ * Anubis test vectors.
+ */
+
+#define ANUBIS_ENC_TEST_VECTORS 5
+#define ANUBIS_DEC_TEST_VECTORS 5
+#define ANUBIS_CBC_ENC_TEST_VECTORS 2
+#define ANUBIS_CBC_DEC_TEST_VECTORS 2
+
+static struct cipher_testvec anubis_enc_tv_template[] = {
+ {
+ .key = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+ .klen = 16,
+ .input = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+ .ilen = 16,
+ .result = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+ "\x08\xb7\x52\x8e\x6e\x6e\x86\x90",
+ .rlen = 16,
+ }, {
+
+ .key = "\x03\x03\x03\x03\x03\x03\x03\x03"
+ "\x03\x03\x03\x03\x03\x03\x03\x03"
+ "\x03\x03\x03\x03",
+ .klen = 20,
+ .input = "\x03\x03\x03\x03\x03\x03\x03\x03"
+ "\x03\x03\x03\x03\x03\x03\x03\x03",
+ .ilen = 16,
+ .result = "\xdb\xf1\x42\xf4\xd1\x8a\xc7\x49"
+ "\x87\x41\x6f\x82\x0a\x98\x64\xae",
+ .rlen = 16,
+ }, {
+ .key = "\x24\x24\x24\x24\x24\x24\x24\x24"
+ "\x24\x24\x24\x24\x24\x24\x24\x24"
+ "\x24\x24\x24\x24\x24\x24\x24\x24"
+ "\x24\x24\x24\x24",
+ .klen = 28,
+ .input = "\x24\x24\x24\x24\x24\x24\x24\x24"
+ "\x24\x24\x24\x24\x24\x24\x24\x24",
+ .ilen = 16,
+ .result = "\xfd\x1b\x4a\xe3\xbf\xf0\xad\x3d"
+ "\x06\xd3\x61\x27\xfd\x13\x9e\xde",
+ .rlen = 16,
+ }, {
+ .key = "\x25\x25\x25\x25\x25\x25\x25\x25"
+ "\x25\x25\x25\x25\x25\x25\x25\x25"
+ "\x25\x25\x25\x25\x25\x25\x25\x25"
+ "\x25\x25\x25\x25\x25\x25\x25\x25",
+ .klen = 32,
+ .input = "\x25\x25\x25\x25\x25\x25\x25\x25"
+ "\x25\x25\x25\x25\x25\x25\x25\x25",
+ .ilen = 16,
+ .result = "\x1a\x91\xfb\x2b\xb7\x78\x6b\xc4"
+ "\x17\xd9\xff\x40\x3b\x0e\xe5\xfe",
+ .rlen = 16,
+ }, {
+ .key = "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35",
+ .klen = 40,
+ .input = "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35",
+ .ilen = 16,
+ .result = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+ "\x9e\xc6\x84\x0f\x17\x21\x07\xee",
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec anubis_dec_tv_template[] = {
+ {
+ .key = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+ .klen = 16,
+ .input = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+ "\x08\xb7\x52\x8e\x6e\x6e\x86\x90",
+ .ilen = 16,
+ .result = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+ .rlen = 16,
+ }, {
+
+ .key = "\x03\x03\x03\x03\x03\x03\x03\x03"
+ "\x03\x03\x03\x03\x03\x03\x03\x03"
+ "\x03\x03\x03\x03",
+ .klen = 20,
+ .input = "\xdb\xf1\x42\xf4\xd1\x8a\xc7\x49"
+ "\x87\x41\x6f\x82\x0a\x98\x64\xae",
+ .ilen = 16,
+ .result = "\x03\x03\x03\x03\x03\x03\x03\x03"
+ "\x03\x03\x03\x03\x03\x03\x03\x03",
+ .rlen = 16,
+ }, {
+ .key = "\x24\x24\x24\x24\x24\x24\x24\x24"
+ "\x24\x24\x24\x24\x24\x24\x24\x24"
+ "\x24\x24\x24\x24\x24\x24\x24\x24"
+ "\x24\x24\x24\x24",
+ .klen = 28,
+ .input = "\xfd\x1b\x4a\xe3\xbf\xf0\xad\x3d"
+ "\x06\xd3\x61\x27\xfd\x13\x9e\xde",
+ .ilen = 16,
+ .result = "\x24\x24\x24\x24\x24\x24\x24\x24"
+ "\x24\x24\x24\x24\x24\x24\x24\x24",
+ .rlen = 16,
+ }, {
+ .key = "\x25\x25\x25\x25\x25\x25\x25\x25"
+ "\x25\x25\x25\x25\x25\x25\x25\x25"
+ "\x25\x25\x25\x25\x25\x25\x25\x25"
+ "\x25\x25\x25\x25\x25\x25\x25\x25",
+ .klen = 32,
+ .input = "\x1a\x91\xfb\x2b\xb7\x78\x6b\xc4"
+ "\x17\xd9\xff\x40\x3b\x0e\xe5\xfe",
+ .ilen = 16,
+ .result = "\x25\x25\x25\x25\x25\x25\x25\x25"
+ "\x25\x25\x25\x25\x25\x25\x25\x25",
+ .rlen = 16,
+ }, {
+ .key = "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35",
+ .input = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+ "\x9e\xc6\x84\x0f\x17\x21\x07\xee",
+ .klen = 40,
+ .ilen = 16,
+ .result = "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35",
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec anubis_cbc_enc_tv_template[] = {
+ {
+ .key = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+ .klen = 16,
+ .input = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+ .ilen = 32,
+ .result = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+ "\x08\xb7\x52\x8e\x6e\x6e\x86\x90"
+ "\x86\xd8\xb5\x6f\x98\x5e\x8a\x66"
+ "\x4f\x1f\x78\xa1\xbb\x37\xf1\xbe",
+ .rlen = 32,
+ }, {
+ .key = "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35",
+ .klen = 40,
+ .input = "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35",
+ .ilen = 32,
+ .result = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+ "\x9e\xc6\x84\x0f\x17\x21\x07\xee"
+ "\xa2\xbc\x06\x98\xc6\x4b\xda\x75"
+ "\x2e\xaa\xbe\x58\xce\x01\x5b\xc7",
+ .rlen = 32,
+ },
+};
+
+static struct cipher_testvec anubis_cbc_dec_tv_template[] = {
+ {
+ .key = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+ .klen = 16,
+ .input = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+ "\x08\xb7\x52\x8e\x6e\x6e\x86\x90"
+ "\x86\xd8\xb5\x6f\x98\x5e\x8a\x66"
+ "\x4f\x1f\x78\xa1\xbb\x37\xf1\xbe",
+ .ilen = 32,
+ .result = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+ .rlen = 32,
+ }, {
+ .key = "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35",
+ .klen = 40,
+ .input = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+ "\x9e\xc6\x84\x0f\x17\x21\x07\xee"
+ "\xa2\xbc\x06\x98\xc6\x4b\xda\x75"
+ "\x2e\xaa\xbe\x58\xce\x01\x5b\xc7",
+ .ilen = 32,
+ .result = "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35"
+ "\x35\x35\x35\x35\x35\x35\x35\x35",
+ .rlen = 32,
+ },
+};
+
+/*
+ * XETA test vectors
+ */
+#define XETA_ENC_TEST_VECTORS 4
+#define XETA_DEC_TEST_VECTORS 4
+
+static struct cipher_testvec xeta_enc_tv_template[] = {
+ {
+ .key = zeroed_string,
+ .klen = 16,
+ .input = zeroed_string,
+ .ilen = 8,
+ .result = "\xaa\x22\x96\xe5\x6c\x61\xf3\x45",
+ .rlen = 8,
+ }, {
+ .key = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+ "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+ .klen = 16,
+ .input = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+ .ilen = 8,
+ .result = "\x82\x3e\xeb\x35\xdc\xdd\xd9\xc3",
+ .rlen = 8,
+ }, {
+ .key = "\x09\x65\x43\x11\x66\x44\x39\x25"
+ "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+ .klen = 16,
+ .input = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+ "\x65\x73\x74\x5f\x76\x65\x63\x74",
+ .ilen = 16,
+ .result = "\xe2\x04\xdb\xf2\x89\x85\x9e\xea"
+ "\x61\x35\xaa\xed\xb5\xcb\x71\x2c",
+ .rlen = 16,
+ }, {
+ .key = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+ "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+ .klen = 16,
+ .input = "\x54\x65\x61\x20\x69\x73\x20\x67"
+ "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+ "\x79\x6f\x75\x21\x21\x21\x20\x72"
+ "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+ .ilen = 32,
+ .result = "\x0b\x03\xcd\x8a\xbe\x95\xfd\xb1"
+ "\xc1\x44\x91\x0b\xa5\xc9\x1b\xb4"
+ "\xa9\xda\x1e\x9e\xb1\x3e\x2a\x8f"
+ "\xea\xa5\x6a\x85\xd1\xf4\xa8\xa5",
+ .rlen = 32,
+ }
+};
+
+static struct cipher_testvec xeta_dec_tv_template[] = {
+ {
+ .key = zeroed_string,
+ .klen = 16,
+ .input = "\xaa\x22\x96\xe5\x6c\x61\xf3\x45",
+ .ilen = 8,
+ .result = zeroed_string,
+ .rlen = 8,
+ }, {
+ .key = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+ "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+ .klen = 16,
+ .input = "\x82\x3e\xeb\x35\xdc\xdd\xd9\xc3",
+ .ilen = 8,
+ .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+ .rlen = 8,
+ }, {
+ .key = "\x09\x65\x43\x11\x66\x44\x39\x25"
+ "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+ .klen = 16,
+ .input = "\xe2\x04\xdb\xf2\x89\x85\x9e\xea"
+ "\x61\x35\xaa\xed\xb5\xcb\x71\x2c",
+ .ilen = 16,
+ .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+ "\x65\x73\x74\x5f\x76\x65\x63\x74",
+ .rlen = 16,
+ }, {
+ .key = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+ "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+ .klen = 16,
+ .input = "\x0b\x03\xcd\x8a\xbe\x95\xfd\xb1"
+ "\xc1\x44\x91\x0b\xa5\xc9\x1b\xb4"
+ "\xa9\xda\x1e\x9e\xb1\x3e\x2a\x8f"
+ "\xea\xa5\x6a\x85\xd1\xf4\xa8\xa5",
+ .ilen = 32,
+ .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
+ "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+ "\x79\x6f\x75\x21\x21\x21\x20\x72"
+ "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+ .rlen = 32,
+ }
+};
+
+/*
+ * FCrypt test vectors
+ */
+#define FCRYPT_ENC_TEST_VECTORS ARRAY_SIZE(fcrypt_pcbc_enc_tv_template)
+#define FCRYPT_DEC_TEST_VECTORS ARRAY_SIZE(fcrypt_pcbc_dec_tv_template)
+
+static struct cipher_testvec fcrypt_pcbc_enc_tv_template[] = {
+ { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 8,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 8,
+ .result = "\x0E\x09\x00\xC7\x3E\xF7\xED\x41",
+ .rlen = 8,
+ }, {
+ .key = "\x11\x44\x77\xAA\xDD\x00\x33\x66",
+ .klen = 8,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
+ .ilen = 8,
+ .result = "\xD8\xED\x78\x74\x77\xEC\x06\x80",
+ .rlen = 8,
+ }, { /* From Arla */
+ .key = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+ .klen = 8,
+ .iv = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .input = "The quick brown fox jumps over the lazy dogs.\0\0",
+ .ilen = 48,
+ .result = "\x00\xf0\x0e\x11\x75\xe6\x23\x82"
+ "\xee\xac\x98\x62\x44\x51\xe4\x84"
+ "\xc3\x59\xd8\xaa\x64\x60\xae\xf7"
+ "\xd2\xd9\x13\x79\x72\xa3\x45\x03"
+ "\x23\xb5\x62\xd7\x0c\xf5\x27\xd1"
+ "\xf8\x91\x3c\xac\x44\x22\x92\xef",
+ .rlen = 48,
+ }, {
+ .key = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .klen = 8,
+ .iv = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+ .input = "The quick brown fox jumps over the lazy dogs.\0\0",
+ .ilen = 48,
+ .result = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+ "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+ "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+ "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+ "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+ "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+ .rlen = 48,
+ }, { /* split-page version */
+ .key = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .klen = 8,
+ .iv = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+ .input = "The quick brown fox jumps over the lazy dogs.\0\0",
+ .ilen = 48,
+ .result = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+ "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+ "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+ "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+ "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+ "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+ .rlen = 48,
+ .np = 2,
+ .tap = { 20, 28 },
+ }
+};
+
+static struct cipher_testvec fcrypt_pcbc_dec_tv_template[] = {
+ { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 8,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x0E\x09\x00\xC7\x3E\xF7\xED\x41",
+ .ilen = 8,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .rlen = 8,
+ }, {
+ .key = "\x11\x44\x77\xAA\xDD\x00\x33\x66",
+ .klen = 8,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\xD8\xED\x78\x74\x77\xEC\x06\x80",
+ .ilen = 8,
+ .result = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
+ .rlen = 8,
+ }, { /* From Arla */
+ .key = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+ .klen = 8,
+ .iv = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .input = "\x00\xf0\x0e\x11\x75\xe6\x23\x82"
+ "\xee\xac\x98\x62\x44\x51\xe4\x84"
+ "\xc3\x59\xd8\xaa\x64\x60\xae\xf7"
+ "\xd2\xd9\x13\x79\x72\xa3\x45\x03"
+ "\x23\xb5\x62\xd7\x0c\xf5\x27\xd1"
+ "\xf8\x91\x3c\xac\x44\x22\x92\xef",
+ .ilen = 48,
+ .result = "The quick brown fox jumps over the lazy dogs.\0\0",
+ .rlen = 48,
+ }, {
+ .key = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .klen = 8,
+ .iv = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+ .input = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+ "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+ "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+ "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+ "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+ "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+ .ilen = 48,
+ .result = "The quick brown fox jumps over the lazy dogs.\0\0",
+ .rlen = 48,
+ }, { /* split-page version */
+ .key = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .klen = 8,
+ .iv = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+ .input = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+ "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+ "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+ "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+ "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+ "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+ .ilen = 48,
+ .result = "The quick brown fox jumps over the lazy dogs.\0\0",
+ .rlen = 48,
+ .np = 2,
+ .tap = { 20, 28 },
+ }
+};
+
+/*
+ * CAMELLIA test vectors.
+ */
+#define CAMELLIA_ENC_TEST_VECTORS 3
+#define CAMELLIA_DEC_TEST_VECTORS 3
+#define CAMELLIA_CBC_ENC_TEST_VECTORS 2
+#define CAMELLIA_CBC_DEC_TEST_VECTORS 2
+
+static struct cipher_testvec camellia_enc_tv_template[] = {
+ {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .klen = 16,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .ilen = 16,
+ .result = "\x67\x67\x31\x38\x54\x96\x69\x73"
+ "\x08\x57\x06\x56\x48\xea\xbe\x43",
+ .rlen = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+ "\x00\x11\x22\x33\x44\x55\x66\x77",
+ .klen = 24,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .ilen = 16,
+ .result = "\xb4\x99\x34\x01\xb3\xe9\x96\xf8"
+ "\x4e\xe5\xce\xe7\xd7\x9b\x09\xb9",
+ .rlen = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+ "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .klen = 32,
+ .input = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .ilen = 16,
+ .result = "\x9a\xcc\x23\x7d\xff\x16\xd7\x6c"
+ "\x20\xef\x7c\x91\x9e\x3a\x75\x09",
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec camellia_dec_tv_template[] = {
+ {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .klen = 16,
+ .input = "\x67\x67\x31\x38\x54\x96\x69\x73"
+ "\x08\x57\x06\x56\x48\xea\xbe\x43",
+ .ilen = 16,
+ .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .rlen = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+ "\x00\x11\x22\x33\x44\x55\x66\x77",
+ .klen = 24,
+ .input = "\xb4\x99\x34\x01\xb3\xe9\x96\xf8"
+ "\x4e\xe5\xce\xe7\xd7\x9b\x09\xb9",
+ .ilen = 16,
+ .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .rlen = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+ "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .klen = 32,
+ .input = "\x9a\xcc\x23\x7d\xff\x16\xd7\x6c"
+ "\x20\xef\x7c\x91\x9e\x3a\x75\x09",
+ .ilen = 16,
+ .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .rlen = 16,
+ },
+};
+
+static struct cipher_testvec camellia_cbc_enc_tv_template[] = {
+ {
+ .key = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+ "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+ .klen = 16,
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+ .input = "Single block msg",
+ .ilen = 16,
+ .result = "\xea\x32\x12\x76\x3b\x50\x10\xe7"
+ "\x18\xf6\xfd\x5d\xf6\x8f\x13\x51",
+ .rlen = 16,
+ }, {
+ .key = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+ "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+ .klen = 16,
+ .iv = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+ "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .ilen = 32,
+ .result = "\xa5\xdf\x6e\x50\xda\x70\x6c\x01"
+ "\x4a\xab\xf3\xf2\xd6\xfc\x6c\xfd"
+ "\x19\xb4\x3e\x57\x1c\x02\x5e\xa0"
+ "\x15\x78\xe0\x5e\xf2\xcb\x87\x16",
+ .rlen = 32,
+ },
+};
+
+static struct cipher_testvec camellia_cbc_dec_tv_template[] = {
+ {
+ .key = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+ "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+ .klen = 16,
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+ .input = "\xea\x32\x12\x76\x3b\x50\x10\xe7"
+ "\x18\xf6\xfd\x5d\xf6\x8f\x13\x51",
+ .ilen = 16,
+ .result = "Single block msg",
+ .rlen = 16,
+ }, {
+ .key = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+ "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+ .klen = 16,
+ .iv = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+ "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+ .input = "\xa5\xdf\x6e\x50\xda\x70\x6c\x01"
+ "\x4a\xab\xf3\xf2\xd6\xfc\x6c\xfd"
+ "\x19\xb4\x3e\x57\x1c\x02\x5e\xa0"
+ "\x15\x78\xe0\x5e\xf2\xcb\x87\x16",
+ .ilen = 32,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .rlen = 32,
+ },
+};
+
+/*
+ * SEED test vectors
+ */
+#define SEED_ENC_TEST_VECTORS 4
+#define SEED_DEC_TEST_VECTORS 4
+
+static struct cipher_testvec seed_enc_tv_template[] = {
+ {
+ .key = zeroed_string,
+ .klen = 16,
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .ilen = 16,
+ .result = "\x5e\xba\xc6\xe0\x05\x4e\x16\x68"
+ "\x19\xaf\xf1\xcc\x6d\x34\x6c\xdb",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .klen = 16,
+ .input = zeroed_string,
+ .ilen = 16,
+ .result = "\xc1\x1f\x22\xf2\x01\x40\x50\x50"
+ "\x84\x48\x35\x97\xe4\x37\x0f\x43",
+ .rlen = 16,
+ }, {
+ .key = "\x47\x06\x48\x08\x51\xe6\x1b\xe8"
+ "\x5d\x74\xbf\xb3\xfd\x95\x61\x85",
+ .klen = 16,
+ .input = "\x83\xa2\xf8\xa2\x88\x64\x1f\xb9"
+ "\xa4\xe9\xa5\xcc\x2f\x13\x1c\x7d",
+ .ilen = 16,
+ .result = "\xee\x54\xd1\x3e\xbc\xae\x70\x6d"
+ "\x22\x6b\xc3\x14\x2c\xd4\x0d\x4a",
+ .rlen = 16,
+ }, {
+ .key = "\x28\xdb\xc3\xbc\x49\xff\xd8\x7d"
+ "\xcf\xa5\x09\xb1\x1d\x42\x2b\xe7",
+ .klen = 16,
+ .input = "\xb4\x1e\x6b\xe2\xeb\xa8\x4a\x14"
+ "\x8e\x2e\xed\x84\x59\x3c\x5e\xc7",
+ .ilen = 16,
+ .result = "\x9b\x9b\x7b\xfc\xd1\x81\x3c\xb9"
+ "\x5d\x0b\x36\x18\xf4\x0f\x51\x22",
+ .rlen = 16,
+ }
+};
+
+static struct cipher_testvec seed_dec_tv_template[] = {
+ {
+ .key = zeroed_string,
+ .klen = 16,
+ .input = "\x5e\xba\xc6\xe0\x05\x4e\x16\x68"
+ "\x19\xaf\xf1\xcc\x6d\x34\x6c\xdb",
+ .ilen = 16,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .rlen = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .klen = 16,
+ .input = "\xc1\x1f\x22\xf2\x01\x40\x50\x50"
+ "\x84\x48\x35\x97\xe4\x37\x0f\x43",
+ .ilen = 16,
+ .result = zeroed_string,
+ .rlen = 16,
+ }, {
+ .key = "\x47\x06\x48\x08\x51\xe6\x1b\xe8"
+ "\x5d\x74\xbf\xb3\xfd\x95\x61\x85",
+ .klen = 16,
+ .input = "\xee\x54\xd1\x3e\xbc\xae\x70\x6d"
+ "\x22\x6b\xc3\x14\x2c\xd4\x0d\x4a",
+ .ilen = 16,
+ .result = "\x83\xa2\xf8\xa2\x88\x64\x1f\xb9"
+ "\xa4\xe9\xa5\xcc\x2f\x13\x1c\x7d",
+ .rlen = 16,
+ }, {
+ .key = "\x28\xdb\xc3\xbc\x49\xff\xd8\x7d"
+ "\xcf\xa5\x09\xb1\x1d\x42\x2b\xe7",
+ .klen = 16,
+ .input = "\x9b\x9b\x7b\xfc\xd1\x81\x3c\xb9"
+ "\x5d\x0b\x36\x18\xf4\x0f\x51\x22",
+ .ilen = 16,
+ .result = "\xb4\x1e\x6b\xe2\xeb\xa8\x4a\x14"
+ "\x8e\x2e\xed\x84\x59\x3c\x5e\xc7",
+ .rlen = 16,
+ }
+};
+
+#define SALSA20_STREAM_ENC_TEST_VECTORS 5
+static struct cipher_testvec salsa20_stream_enc_tv_template[] = {
+ /*
+ * Testvectors from verified.test-vectors submitted to ECRYPT.
+ * They are truncated to size 39, 64, 111, 129 to test a variety
+ * of input length.
+ */
+ { /* Set 3, vector 0 */
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .klen = 16,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 39,
+ .result = "\x2D\xD5\xC3\xF7\xBA\x2B\x20\xF7"
+ "\x68\x02\x41\x0C\x68\x86\x88\x89"
+ "\x5A\xD8\xC1\xBD\x4E\xA6\xC9\xB1"
+ "\x40\xFB\x9B\x90\xE2\x10\x49\xBF"
+ "\x58\x3F\x52\x79\x70\xEB\xC1",
+ .rlen = 39,
+ }, { /* Set 5, vector 0 */
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 16,
+ .iv = "\x80\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 64,
+ .result = "\xB6\x6C\x1E\x44\x46\xDD\x95\x57"
+ "\xE5\x78\xE2\x23\xB0\xB7\x68\x01"
+ "\x7B\x23\xB2\x67\xBB\x02\x34\xAE"
+ "\x46\x26\xBF\x44\x3F\x21\x97\x76"
+ "\x43\x6F\xB1\x9F\xD0\xE8\x86\x6F"
+ "\xCD\x0D\xE9\xA9\x53\x8F\x4A\x09"
+ "\xCA\x9A\xC0\x73\x2E\x30\xBC\xF9"
+ "\x8E\x4F\x13\xE4\xB9\xE2\x01\xD9",
+ .rlen = 64,
+ }, { /* Set 3, vector 27 */
+ .key = "\x1B\x1C\x1D\x1E\x1F\x20\x21\x22"
+ "\x23\x24\x25\x26\x27\x28\x29\x2A"
+ "\x2B\x2C\x2D\x2E\x2F\x30\x31\x32"
+ "\x33\x34\x35\x36\x37\x38\x39\x3A",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 111,
+ .result = "\xAE\x39\x50\x8E\xAC\x9A\xEC\xE7"
+ "\xBF\x97\xBB\x20\xB9\xDE\xE4\x1F"
+ "\x87\xD9\x47\xF8\x28\x91\x35\x98"
+ "\xDB\x72\xCC\x23\x29\x48\x56\x5E"
+ "\x83\x7E\x0B\xF3\x7D\x5D\x38\x7B"
+ "\x2D\x71\x02\xB4\x3B\xB5\xD8\x23"
+ "\xB0\x4A\xDF\x3C\xEC\xB6\xD9\x3B"
+ "\x9B\xA7\x52\xBE\xC5\xD4\x50\x59"
+ "\x15\x14\xB4\x0E\x40\xE6\x53\xD1"
+ "\x83\x9C\x5B\xA0\x92\x29\x6B\x5E"
+ "\x96\x5B\x1E\x2F\xD3\xAC\xC1\x92"
+ "\xB1\x41\x3F\x19\x2F\xC4\x3B\xC6"
+ "\x95\x46\x45\x54\xE9\x75\x03\x08"
+ "\x44\xAF\xE5\x8A\x81\x12\x09",
+ .rlen = 111,
+ }, { /* Set 5, vector 27 */
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x10\x00\x00\x00\x00",
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00",
+ .ilen = 129,
+ .result = "\xD2\xDB\x1A\x5C\xF1\xC1\xAC\xDB"
+ "\xE8\x1A\x7A\x43\x40\xEF\x53\x43"
+ "\x5E\x7F\x4B\x1A\x50\x52\x3F\x8D"
+ "\x28\x3D\xCF\x85\x1D\x69\x6E\x60"
+ "\xF2\xDE\x74\x56\x18\x1B\x84\x10"
+ "\xD4\x62\xBA\x60\x50\xF0\x61\xF2"
+ "\x1C\x78\x7F\xC1\x24\x34\xAF\x58"
+ "\xBF\x2C\x59\xCA\x90\x77\xF3\xB0"
+ "\x5B\x4A\xDF\x89\xCE\x2C\x2F\xFC"
+ "\x67\xF0\xE3\x45\xE8\xB3\xB3\x75"
+ "\xA0\x95\x71\xA1\x29\x39\x94\xCA"
+ "\x45\x2F\xBD\xCB\x10\xB6\xBE\x9F"
+ "\x8E\xF9\xB2\x01\x0A\x5A\x0A\xB7"
+ "\x6B\x9D\x70\x8E\x4B\xD6\x2F\xCD"
+ "\x2E\x40\x48\x75\xE9\xE2\x21\x45"
+ "\x0B\xC9\xB6\xB5\x66\xBC\x9A\x59"
+ "\x5A",
+ .rlen = 129,
+ }, { /* large test vector generated using Crypto++ */
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input =
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x03\x06\x09\x0c\x0f\x12\x15"
+ "\x18\x1b\x1e\x21\x24\x27\x2a\x2d"
+ "\x30\x33\x36\x39\x3c\x3f\x42\x45"
+ "\x48\x4b\x4e\x51\x54\x57\x5a\x5d"
+ "\x60\x63\x66\x69\x6c\x6f\x72\x75"
+ "\x78\x7b\x7e\x81\x84\x87\x8a\x8d"
+ "\x90\x93\x96\x99\x9c\x9f\xa2\xa5"
+ "\xa8\xab\xae\xb1\xb4\xb7\xba\xbd"
+ "\xc0\xc3\xc6\xc9\xcc\xcf\xd2\xd5"
+ "\xd8\xdb\xde\xe1\xe4\xe7\xea\xed"
+ "\xf0\xf3\xf6\xf9\xfc\xff\x02\x05"
+ "\x08\x0b\x0e\x11\x14\x17\x1a\x1d"
+ "\x20\x23\x26\x29\x2c\x2f\x32\x35"
+ "\x38\x3b\x3e\x41\x44\x47\x4a\x4d"
+ "\x50\x53\x56\x59\x5c\x5f\x62\x65"
+ "\x68\x6b\x6e\x71\x74\x77\x7a\x7d"
+ "\x80\x83\x86\x89\x8c\x8f\x92\x95"
+ "\x98\x9b\x9e\xa1\xa4\xa7\xaa\xad"
+ "\xb0\xb3\xb6\xb9\xbc\xbf\xc2\xc5"
+ "\xc8\xcb\xce\xd1\xd4\xd7\xda\xdd"
+ "\xe0\xe3\xe6\xe9\xec\xef\xf2\xf5"
+ "\xf8\xfb\xfe\x01\x04\x07\x0a\x0d"
+ "\x10\x13\x16\x19\x1c\x1f\x22\x25"
+ "\x28\x2b\x2e\x31\x34\x37\x3a\x3d"
+ "\x40\x43\x46\x49\x4c\x4f\x52\x55"
+ "\x58\x5b\x5e\x61\x64\x67\x6a\x6d"
+ "\x70\x73\x76\x79\x7c\x7f\x82\x85"
+ "\x88\x8b\x8e\x91\x94\x97\x9a\x9d"
+ "\xa0\xa3\xa6\xa9\xac\xaf\xb2\xb5"
+ "\xb8\xbb\xbe\xc1\xc4\xc7\xca\xcd"
+ "\xd0\xd3\xd6\xd9\xdc\xdf\xe2\xe5"
+ "\xe8\xeb\xee\xf1\xf4\xf7\xfa\xfd"
+ "\x00\x05\x0a\x0f\x14\x19\x1e\x23"
+ "\x28\x2d\x32\x37\x3c\x41\x46\x4b"
+ "\x50\x55\x5a\x5f\x64\x69\x6e\x73"
+ "\x78\x7d\x82\x87\x8c\x91\x96\x9b"
+ "\xa0\xa5\xaa\xaf\xb4\xb9\xbe\xc3"
+ "\xc8\xcd\xd2\xd7\xdc\xe1\xe6\xeb"
+ "\xf0\xf5\xfa\xff\x04\x09\x0e\x13"
+ "\x18\x1d\x22\x27\x2c\x31\x36\x3b"
+ "\x40\x45\x4a\x4f\x54\x59\x5e\x63"
+ "\x68\x6d\x72\x77\x7c\x81\x86\x8b"
+ "\x90\x95\x9a\x9f\xa4\xa9\xae\xb3"
+ "\xb8\xbd\xc2\xc7\xcc\xd1\xd6\xdb"
+ "\xe0\xe5\xea\xef\xf4\xf9\xfe\x03"
+ "\x08\x0d\x12\x17\x1c\x21\x26\x2b"
+ "\x30\x35\x3a\x3f\x44\x49\x4e\x53"
+ "\x58\x5d\x62\x67\x6c\x71\x76\x7b"
+ "\x80\x85\x8a\x8f\x94\x99\x9e\xa3"
+ "\xa8\xad\xb2\xb7\xbc\xc1\xc6\xcb"
+ "\xd0\xd5\xda\xdf\xe4\xe9\xee\xf3"
+ "\xf8\xfd\x02\x07\x0c\x11\x16\x1b"
+ "\x20\x25\x2a\x2f\x34\x39\x3e\x43"
+ "\x48\x4d\x52\x57\x5c\x61\x66\x6b"
+ "\x70\x75\x7a\x7f\x84\x89\x8e\x93"
+ "\x98\x9d\xa2\xa7\xac\xb1\xb6\xbb"
+ "\xc0\xc5\xca\xcf\xd4\xd9\xde\xe3"
+ "\xe8\xed\xf2\xf7\xfc\x01\x06\x0b"
+ "\x10\x15\x1a\x1f\x24\x29\x2e\x33"
+ "\x38\x3d\x42\x47\x4c\x51\x56\x5b"
+ "\x60\x65\x6a\x6f\x74\x79\x7e\x83"
+ "\x88\x8d\x92\x97\x9c\xa1\xa6\xab"
+ "\xb0\xb5\xba\xbf\xc4\xc9\xce\xd3"
+ "\xd8\xdd\xe2\xe7\xec\xf1\xf6\xfb"
+ "\x00\x07\x0e\x15\x1c\x23\x2a\x31"
+ "\x38\x3f\x46\x4d\x54\x5b\x62\x69"
+ "\x70\x77\x7e\x85\x8c\x93\x9a\xa1"
+ "\xa8\xaf\xb6\xbd\xc4\xcb\xd2\xd9"
+ "\xe0\xe7\xee\xf5\xfc\x03\x0a\x11"
+ "\x18\x1f\x26\x2d\x34\x3b\x42\x49"
+ "\x50\x57\x5e\x65\x6c\x73\x7a\x81"
+ "\x88\x8f\x96\x9d\xa4\xab\xb2\xb9"
+ "\xc0\xc7\xce\xd5\xdc\xe3\xea\xf1"
+ "\xf8\xff\x06\x0d\x14\x1b\x22\x29"
+ "\x30\x37\x3e\x45\x4c\x53\x5a\x61"
+ "\x68\x6f\x76\x7d\x84\x8b\x92\x99"
+ "\xa0\xa7\xae\xb5\xbc\xc3\xca\xd1"
+ "\xd8\xdf\xe6\xed\xf4\xfb\x02\x09"
+ "\x10\x17\x1e\x25\x2c\x33\x3a\x41"
+ "\x48\x4f\x56\x5d\x64\x6b\x72\x79"
+ "\x80\x87\x8e\x95\x9c\xa3\xaa\xb1"
+ "\xb8\xbf\xc6\xcd\xd4\xdb\xe2\xe9"
+ "\xf0\xf7\xfe\x05\x0c\x13\x1a\x21"
+ "\x28\x2f\x36\x3d\x44\x4b\x52\x59"
+ "\x60\x67\x6e\x75\x7c\x83\x8a\x91"
+ "\x98\x9f\xa6\xad\xb4\xbb\xc2\xc9"
+ "\xd0\xd7\xde\xe5\xec\xf3\xfa\x01"
+ "\x08\x0f\x16\x1d\x24\x2b\x32\x39"
+ "\x40\x47\x4e\x55\x5c\x63\x6a\x71"
+ "\x78\x7f\x86\x8d\x94\x9b\xa2\xa9"
+ "\xb0\xb7\xbe\xc5\xcc\xd3\xda\xe1"
+ "\xe8\xef\xf6\xfd\x04\x0b\x12\x19"
+ "\x20\x27\x2e\x35\x3c\x43\x4a\x51"
+ "\x58\x5f\x66\x6d\x74\x7b\x82\x89"
+ "\x90\x97\x9e\xa5\xac\xb3\xba\xc1"
+ "\xc8\xcf\xd6\xdd\xe4\xeb\xf2\xf9"
+ "\x00\x09\x12\x1b\x24\x2d\x36\x3f"
+ "\x48\x51\x5a\x63\x6c\x75\x7e\x87"
+ "\x90\x99\xa2\xab\xb4\xbd\xc6\xcf"
+ "\xd8\xe1\xea\xf3\xfc\x05\x0e\x17"
+ "\x20\x29\x32\x3b\x44\x4d\x56\x5f"
+ "\x68\x71\x7a\x83\x8c\x95\x9e\xa7"
+ "\xb0\xb9\xc2\xcb\xd4\xdd\xe6\xef"
+ "\xf8\x01\x0a\x13\x1c\x25\x2e\x37"
+ "\x40\x49\x52\x5b\x64\x6d\x76\x7f"
+ "\x88\x91\x9a\xa3\xac\xb5\xbe\xc7"
+ "\xd0\xd9\xe2\xeb\xf4\xfd\x06\x0f"
+ "\x18\x21\x2a\x33\x3c\x45\x4e\x57"
+ "\x60\x69\x72\x7b\x84\x8d\x96\x9f"
+ "\xa8\xb1\xba\xc3\xcc\xd5\xde\xe7"
+ "\xf0\xf9\x02\x0b\x14\x1d\x26\x2f"
+ "\x38\x41\x4a\x53\x5c\x65\x6e\x77"
+ "\x80\x89\x92\x9b\xa4\xad\xb6\xbf"
+ "\xc8\xd1\xda\xe3\xec\xf5\xfe\x07"
+ "\x10\x19\x22\x2b\x34\x3d\x46\x4f"
+ "\x58\x61\x6a\x73\x7c\x85\x8e\x97"
+ "\xa0\xa9\xb2\xbb\xc4\xcd\xd6\xdf"
+ "\xe8\xf1\xfa\x03\x0c\x15\x1e\x27"
+ "\x30\x39\x42\x4b\x54\x5d\x66\x6f"
+ "\x78\x81\x8a\x93\x9c\xa5\xae\xb7"
+ "\xc0\xc9\xd2\xdb\xe4\xed\xf6\xff"
+ "\x08\x11\x1a\x23\x2c\x35\x3e\x47"
+ "\x50\x59\x62\x6b\x74\x7d\x86\x8f"
+ "\x98\xa1\xaa\xb3\xbc\xc5\xce\xd7"
+ "\xe0\xe9\xf2\xfb\x04\x0d\x16\x1f"
+ "\x28\x31\x3a\x43\x4c\x55\x5e\x67"
+ "\x70\x79\x82\x8b\x94\x9d\xa6\xaf"
+ "\xb8\xc1\xca\xd3\xdc\xe5\xee\xf7"
+ "\x00\x0b\x16\x21\x2c\x37\x42\x4d"
+ "\x58\x63\x6e\x79\x84\x8f\x9a\xa5"
+ "\xb0\xbb\xc6\xd1\xdc\xe7\xf2\xfd"
+ "\x08\x13\x1e\x29\x34\x3f\x4a\x55"
+ "\x60\x6b\x76\x81\x8c\x97\xa2\xad"
+ "\xb8\xc3\xce\xd9\xe4\xef\xfa\x05"
+ "\x10\x1b\x26\x31\x3c\x47\x52\x5d"
+ "\x68\x73\x7e\x89\x94\x9f\xaa\xb5"
+ "\xc0\xcb\xd6\xe1\xec\xf7\x02\x0d"
+ "\x18\x23\x2e\x39\x44\x4f\x5a\x65"
+ "\x70\x7b\x86\x91\x9c\xa7\xb2\xbd"
+ "\xc8\xd3\xde\xe9\xf4\xff\x0a\x15"
+ "\x20\x2b\x36\x41\x4c\x57\x62\x6d"
+ "\x78\x83\x8e\x99\xa4\xaf\xba\xc5"
+ "\xd0\xdb\xe6\xf1\xfc\x07\x12\x1d"
+ "\x28\x33\x3e\x49\x54\x5f\x6a\x75"
+ "\x80\x8b\x96\xa1\xac\xb7\xc2\xcd"
+ "\xd8\xe3\xee\xf9\x04\x0f\x1a\x25"
+ "\x30\x3b\x46\x51\x5c\x67\x72\x7d"
+ "\x88\x93\x9e\xa9\xb4\xbf\xca\xd5"
+ "\xe0\xeb\xf6\x01\x0c\x17\x22\x2d"
+ "\x38\x43\x4e\x59\x64\x6f\x7a\x85"
+ "\x90\x9b\xa6\xb1\xbc\xc7\xd2\xdd"
+ "\xe8\xf3\xfe\x09\x14\x1f\x2a\x35"
+ "\x40\x4b\x56\x61\x6c\x77\x82\x8d"
+ "\x98\xa3\xae\xb9\xc4\xcf\xda\xe5"
+ "\xf0\xfb\x06\x11\x1c\x27\x32\x3d"
+ "\x48\x53\x5e\x69\x74\x7f\x8a\x95"
+ "\xa0\xab\xb6\xc1\xcc\xd7\xe2\xed"
+ "\xf8\x03\x0e\x19\x24\x2f\x3a\x45"
+ "\x50\x5b\x66\x71\x7c\x87\x92\x9d"
+ "\xa8\xb3\xbe\xc9\xd4\xdf\xea\xf5"
+ "\x00\x0d\x1a\x27\x34\x41\x4e\x5b"
+ "\x68\x75\x82\x8f\x9c\xa9\xb6\xc3"
+ "\xd0\xdd\xea\xf7\x04\x11\x1e\x2b"
+ "\x38\x45\x52\x5f\x6c\x79\x86\x93"
+ "\xa0\xad\xba\xc7\xd4\xe1\xee\xfb"
+ "\x08\x15\x22\x2f\x3c\x49\x56\x63"
+ "\x70\x7d\x8a\x97\xa4\xb1\xbe\xcb"
+ "\xd8\xe5\xf2\xff\x0c\x19\x26\x33"
+ "\x40\x4d\x5a\x67\x74\x81\x8e\x9b"
+ "\xa8\xb5\xc2\xcf\xdc\xe9\xf6\x03"
+ "\x10\x1d\x2a\x37\x44\x51\x5e\x6b"
+ "\x78\x85\x92\x9f\xac\xb9\xc6\xd3"
+ "\xe0\xed\xfa\x07\x14\x21\x2e\x3b"
+ "\x48\x55\x62\x6f\x7c\x89\x96\xa3"
+ "\xb0\xbd\xca\xd7\xe4\xf1\xfe\x0b"
+ "\x18\x25\x32\x3f\x4c\x59\x66\x73"
+ "\x80\x8d\x9a\xa7\xb4\xc1\xce\xdb"
+ "\xe8\xf5\x02\x0f\x1c\x29\x36\x43"
+ "\x50\x5d\x6a\x77\x84\x91\x9e\xab"
+ "\xb8\xc5\xd2\xdf\xec\xf9\x06\x13"
+ "\x20\x2d\x3a\x47\x54\x61\x6e\x7b"
+ "\x88\x95\xa2\xaf\xbc\xc9\xd6\xe3"
+ "\xf0\xfd\x0a\x17\x24\x31\x3e\x4b"
+ "\x58\x65\x72\x7f\x8c\x99\xa6\xb3"
+ "\xc0\xcd\xda\xe7\xf4\x01\x0e\x1b"
+ "\x28\x35\x42\x4f\x5c\x69\x76\x83"
+ "\x90\x9d\xaa\xb7\xc4\xd1\xde\xeb"
+ "\xf8\x05\x12\x1f\x2c\x39\x46\x53"
+ "\x60\x6d\x7a\x87\x94\xa1\xae\xbb"
+ "\xc8\xd5\xe2\xef\xfc\x09\x16\x23"
+ "\x30\x3d\x4a\x57\x64\x71\x7e\x8b"
+ "\x98\xa5\xb2\xbf\xcc\xd9\xe6\xf3"
+ "\x00\x0f\x1e\x2d\x3c\x4b\x5a\x69"
+ "\x78\x87\x96\xa5\xb4\xc3\xd2\xe1"
+ "\xf0\xff\x0e\x1d\x2c\x3b\x4a\x59"
+ "\x68\x77\x86\x95\xa4\xb3\xc2\xd1"
+ "\xe0\xef\xfe\x0d\x1c\x2b\x3a\x49"
+ "\x58\x67\x76\x85\x94\xa3\xb2\xc1"
+ "\xd0\xdf\xee\xfd\x0c\x1b\x2a\x39"
+ "\x48\x57\x66\x75\x84\x93\xa2\xb1"
+ "\xc0\xcf\xde\xed\xfc\x0b\x1a\x29"
+ "\x38\x47\x56\x65\x74\x83\x92\xa1"
+ "\xb0\xbf\xce\xdd\xec\xfb\x0a\x19"
+ "\x28\x37\x46\x55\x64\x73\x82\x91"
+ "\xa0\xaf\xbe\xcd\xdc\xeb\xfa\x09"
+ "\x18\x27\x36\x45\x54\x63\x72\x81"
+ "\x90\x9f\xae\xbd\xcc\xdb\xea\xf9"
+ "\x08\x17\x26\x35\x44\x53\x62\x71"
+ "\x80\x8f\x9e\xad\xbc\xcb\xda\xe9"
+ "\xf8\x07\x16\x25\x34\x43\x52\x61"
+ "\x70\x7f\x8e\x9d\xac\xbb\xca\xd9"
+ "\xe8\xf7\x06\x15\x24\x33\x42\x51"
+ "\x60\x6f\x7e\x8d\x9c\xab\xba\xc9"
+ "\xd8\xe7\xf6\x05\x14\x23\x32\x41"
+ "\x50\x5f\x6e\x7d\x8c\x9b\xaa\xb9"
+ "\xc8\xd7\xe6\xf5\x04\x13\x22\x31"
+ "\x40\x4f\x5e\x6d\x7c\x8b\x9a\xa9"
+ "\xb8\xc7\xd6\xe5\xf4\x03\x12\x21"
+ "\x30\x3f\x4e\x5d\x6c\x7b\x8a\x99"
+ "\xa8\xb7\xc6\xd5\xe4\xf3\x02\x11"
+ "\x20\x2f\x3e\x4d\x5c\x6b\x7a\x89"
+ "\x98\xa7\xb6\xc5\xd4\xe3\xf2\x01"
+ "\x10\x1f\x2e\x3d\x4c\x5b\x6a\x79"
+ "\x88\x97\xa6\xb5\xc4\xd3\xe2\xf1"
+ "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
+ "\x10\x21\x32\x43\x54\x65\x76\x87"
+ "\x98\xa9\xba\xcb\xdc\xed\xfe\x0f"
+ "\x20\x31\x42\x53\x64\x75\x86\x97"
+ "\xa8\xb9\xca\xdb\xec\xfd\x0e\x1f"
+ "\x30\x41\x52\x63\x74\x85\x96\xa7"
+ "\xb8\xc9\xda\xeb\xfc\x0d\x1e\x2f"
+ "\x40\x51\x62\x73\x84\x95\xa6\xb7"
+ "\xc8\xd9\xea\xfb\x0c\x1d\x2e\x3f"
+ "\x50\x61\x72\x83\x94\xa5\xb6\xc7"
+ "\xd8\xe9\xfa\x0b\x1c\x2d\x3e\x4f"
+ "\x60\x71\x82\x93\xa4\xb5\xc6\xd7"
+ "\xe8\xf9\x0a\x1b\x2c\x3d\x4e\x5f"
+ "\x70\x81\x92\xa3\xb4\xc5\xd6\xe7"
+ "\xf8\x09\x1a\x2b\x3c\x4d\x5e\x6f"
+ "\x80\x91\xa2\xb3\xc4\xd5\xe6\xf7"
+ "\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f"
+ "\x90\xa1\xb2\xc3\xd4\xe5\xf6\x07"
+ "\x18\x29\x3a\x4b\x5c\x6d\x7e\x8f"
+ "\xa0\xb1\xc2\xd3\xe4\xf5\x06\x17"
+ "\x28\x39\x4a\x5b\x6c\x7d\x8e\x9f"
+ "\xb0\xc1\xd2\xe3\xf4\x05\x16\x27"
+ "\x38\x49\x5a\x6b\x7c\x8d\x9e\xaf"
+ "\xc0\xd1\xe2\xf3\x04\x15\x26\x37"
+ "\x48\x59\x6a\x7b\x8c\x9d\xae\xbf"
+ "\xd0\xe1\xf2\x03\x14\x25\x36\x47"
+ "\x58\x69\x7a\x8b\x9c\xad\xbe\xcf"
+ "\xe0\xf1\x02\x13\x24\x35\x46\x57"
+ "\x68\x79\x8a\x9b\xac\xbd\xce\xdf"
+ "\xf0\x01\x12\x23\x34\x45\x56\x67"
+ "\x78\x89\x9a\xab\xbc\xcd\xde\xef"
+ "\x00\x13\x26\x39\x4c\x5f\x72\x85"
+ "\x98\xab\xbe\xd1\xe4\xf7\x0a\x1d"
+ "\x30\x43\x56\x69\x7c\x8f\xa2\xb5"
+ "\xc8\xdb\xee\x01\x14\x27\x3a\x4d"
+ "\x60\x73\x86\x99\xac\xbf\xd2\xe5"
+ "\xf8\x0b\x1e\x31\x44\x57\x6a\x7d"
+ "\x90\xa3\xb6\xc9\xdc\xef\x02\x15"
+ "\x28\x3b\x4e\x61\x74\x87\x9a\xad"
+ "\xc0\xd3\xe6\xf9\x0c\x1f\x32\x45"
+ "\x58\x6b\x7e\x91\xa4\xb7\xca\xdd"
+ "\xf0\x03\x16\x29\x3c\x4f\x62\x75"
+ "\x88\x9b\xae\xc1\xd4\xe7\xfa\x0d"
+ "\x20\x33\x46\x59\x6c\x7f\x92\xa5"
+ "\xb8\xcb\xde\xf1\x04\x17\x2a\x3d"
+ "\x50\x63\x76\x89\x9c\xaf\xc2\xd5"
+ "\xe8\xfb\x0e\x21\x34\x47\x5a\x6d"
+ "\x80\x93\xa6\xb9\xcc\xdf\xf2\x05"
+ "\x18\x2b\x3e\x51\x64\x77\x8a\x9d"
+ "\xb0\xc3\xd6\xe9\xfc\x0f\x22\x35"
+ "\x48\x5b\x6e\x81\x94\xa7\xba\xcd"
+ "\xe0\xf3\x06\x19\x2c\x3f\x52\x65"
+ "\x78\x8b\x9e\xb1\xc4\xd7\xea\xfd"
+ "\x10\x23\x36\x49\x5c\x6f\x82\x95"
+ "\xa8\xbb\xce\xe1\xf4\x07\x1a\x2d"
+ "\x40\x53\x66\x79\x8c\x9f\xb2\xc5"
+ "\xd8\xeb\xfe\x11\x24\x37\x4a\x5d"
+ "\x70\x83\x96\xa9\xbc\xcf\xe2\xf5"
+ "\x08\x1b\x2e\x41\x54\x67\x7a\x8d"
+ "\xa0\xb3\xc6\xd9\xec\xff\x12\x25"
+ "\x38\x4b\x5e\x71\x84\x97\xaa\xbd"
+ "\xd0\xe3\xf6\x09\x1c\x2f\x42\x55"
+ "\x68\x7b\x8e\xa1\xb4\xc7\xda\xed"
+ "\x00\x15\x2a\x3f\x54\x69\x7e\x93"
+ "\xa8\xbd\xd2\xe7\xfc\x11\x26\x3b"
+ "\x50\x65\x7a\x8f\xa4\xb9\xce\xe3"
+ "\xf8\x0d\x22\x37\x4c\x61\x76\x8b"
+ "\xa0\xb5\xca\xdf\xf4\x09\x1e\x33"
+ "\x48\x5d\x72\x87\x9c\xb1\xc6\xdb"
+ "\xf0\x05\x1a\x2f\x44\x59\x6e\x83"
+ "\x98\xad\xc2\xd7\xec\x01\x16\x2b"
+ "\x40\x55\x6a\x7f\x94\xa9\xbe\xd3"
+ "\xe8\xfd\x12\x27\x3c\x51\x66\x7b"
+ "\x90\xa5\xba\xcf\xe4\xf9\x0e\x23"
+ "\x38\x4d\x62\x77\x8c\xa1\xb6\xcb"
+ "\xe0\xf5\x0a\x1f\x34\x49\x5e\x73"
+ "\x88\x9d\xb2\xc7\xdc\xf1\x06\x1b"
+ "\x30\x45\x5a\x6f\x84\x99\xae\xc3"
+ "\xd8\xed\x02\x17\x2c\x41\x56\x6b"
+ "\x80\x95\xaa\xbf\xd4\xe9\xfe\x13"
+ "\x28\x3d\x52\x67\x7c\x91\xa6\xbb"
+ "\xd0\xe5\xfa\x0f\x24\x39\x4e\x63"
+ "\x78\x8d\xa2\xb7\xcc\xe1\xf6\x0b"
+ "\x20\x35\x4a\x5f\x74\x89\x9e\xb3"
+ "\xc8\xdd\xf2\x07\x1c\x31\x46\x5b"
+ "\x70\x85\x9a\xaf\xc4\xd9\xee\x03"
+ "\x18\x2d\x42\x57\x6c\x81\x96\xab"
+ "\xc0\xd5\xea\xff\x14\x29\x3e\x53"
+ "\x68\x7d\x92\xa7\xbc\xd1\xe6\xfb"
+ "\x10\x25\x3a\x4f\x64\x79\x8e\xa3"
+ "\xb8\xcd\xe2\xf7\x0c\x21\x36\x4b"
+ "\x60\x75\x8a\x9f\xb4\xc9\xde\xf3"
+ "\x08\x1d\x32\x47\x5c\x71\x86\x9b"
+ "\xb0\xc5\xda\xef\x04\x19\x2e\x43"
+ "\x58\x6d\x82\x97\xac\xc1\xd6\xeb"
+ "\x00\x17\x2e\x45\x5c\x73\x8a\xa1"
+ "\xb8\xcf\xe6\xfd\x14\x2b\x42\x59"
+ "\x70\x87\x9e\xb5\xcc\xe3\xfa\x11"
+ "\x28\x3f\x56\x6d\x84\x9b\xb2\xc9"
+ "\xe0\xf7\x0e\x25\x3c\x53\x6a\x81"
+ "\x98\xaf\xc6\xdd\xf4\x0b\x22\x39"
+ "\x50\x67\x7e\x95\xac\xc3\xda\xf1"
+ "\x08\x1f\x36\x4d\x64\x7b\x92\xa9"
+ "\xc0\xd7\xee\x05\x1c\x33\x4a\x61"
+ "\x78\x8f\xa6\xbd\xd4\xeb\x02\x19"
+ "\x30\x47\x5e\x75\x8c\xa3\xba\xd1"
+ "\xe8\xff\x16\x2d\x44\x5b\x72\x89"
+ "\xa0\xb7\xce\xe5\xfc\x13\x2a\x41"
+ "\x58\x6f\x86\x9d\xb4\xcb\xe2\xf9"
+ "\x10\x27\x3e\x55\x6c\x83\x9a\xb1"
+ "\xc8\xdf\xf6\x0d\x24\x3b\x52\x69"
+ "\x80\x97\xae\xc5\xdc\xf3\x0a\x21"
+ "\x38\x4f\x66\x7d\x94\xab\xc2\xd9"
+ "\xf0\x07\x1e\x35\x4c\x63\x7a\x91"
+ "\xa8\xbf\xd6\xed\x04\x1b\x32\x49"
+ "\x60\x77\x8e\xa5\xbc\xd3\xea\x01"
+ "\x18\x2f\x46\x5d\x74\x8b\xa2\xb9"
+ "\xd0\xe7\xfe\x15\x2c\x43\x5a\x71"
+ "\x88\x9f\xb6\xcd\xe4\xfb\x12\x29"
+ "\x40\x57\x6e\x85\x9c\xb3\xca\xe1"
+ "\xf8\x0f\x26\x3d\x54\x6b\x82\x99"
+ "\xb0\xc7\xde\xf5\x0c\x23\x3a\x51"
+ "\x68\x7f\x96\xad\xc4\xdb\xf2\x09"
+ "\x20\x37\x4e\x65\x7c\x93\xaa\xc1"
+ "\xd8\xef\x06\x1d\x34\x4b\x62\x79"
+ "\x90\xa7\xbe\xd5\xec\x03\x1a\x31"
+ "\x48\x5f\x76\x8d\xa4\xbb\xd2\xe9"
+ "\x00\x19\x32\x4b\x64\x7d\x96\xaf"
+ "\xc8\xe1\xfa\x13\x2c\x45\x5e\x77"
+ "\x90\xa9\xc2\xdb\xf4\x0d\x26\x3f"
+ "\x58\x71\x8a\xa3\xbc\xd5\xee\x07"
+ "\x20\x39\x52\x6b\x84\x9d\xb6\xcf"
+ "\xe8\x01\x1a\x33\x4c\x65\x7e\x97"
+ "\xb0\xc9\xe2\xfb\x14\x2d\x46\x5f"
+ "\x78\x91\xaa\xc3\xdc\xf5\x0e\x27"
+ "\x40\x59\x72\x8b\xa4\xbd\xd6\xef"
+ "\x08\x21\x3a\x53\x6c\x85\x9e\xb7"
+ "\xd0\xe9\x02\x1b\x34\x4d\x66\x7f"
+ "\x98\xb1\xca\xe3\xfc\x15\x2e\x47"
+ "\x60\x79\x92\xab\xc4\xdd\xf6\x0f"
+ "\x28\x41\x5a\x73\x8c\xa5\xbe\xd7"
+ "\xf0\x09\x22\x3b\x54\x6d\x86\x9f"
+ "\xb8\xd1\xea\x03\x1c\x35\x4e\x67"
+ "\x80\x99\xb2\xcb\xe4\xfd\x16\x2f"
+ "\x48\x61\x7a\x93\xac\xc5\xde\xf7"
+ "\x10\x29\x42\x5b\x74\x8d\xa6\xbf"
+ "\xd8\xf1\x0a\x23\x3c\x55\x6e\x87"
+ "\xa0\xb9\xd2\xeb\x04\x1d\x36\x4f"
+ "\x68\x81\x9a\xb3\xcc\xe5\xfe\x17"
+ "\x30\x49\x62\x7b\x94\xad\xc6\xdf"
+ "\xf8\x11\x2a\x43\x5c\x75\x8e\xa7"
+ "\xc0\xd9\xf2\x0b\x24\x3d\x56\x6f"
+ "\x88\xa1\xba\xd3\xec\x05\x1e\x37"
+ "\x50\x69\x82\x9b\xb4\xcd\xe6\xff"
+ "\x18\x31\x4a\x63\x7c\x95\xae\xc7"
+ "\xe0\xf9\x12\x2b\x44\x5d\x76\x8f"
+ "\xa8\xc1\xda\xf3\x0c\x25\x3e\x57"
+ "\x70\x89\xa2\xbb\xd4\xed\x06\x1f"
+ "\x38\x51\x6a\x83\x9c\xb5\xce\xe7"
+ "\x00\x1b\x36\x51\x6c\x87\xa2\xbd"
+ "\xd8\xf3\x0e\x29\x44\x5f\x7a\x95"
+ "\xb0\xcb\xe6\x01\x1c\x37\x52\x6d"
+ "\x88\xa3\xbe\xd9\xf4\x0f\x2a\x45"
+ "\x60\x7b\x96\xb1\xcc\xe7\x02\x1d"
+ "\x38\x53\x6e\x89\xa4\xbf\xda\xf5"
+ "\x10\x2b\x46\x61\x7c\x97\xb2\xcd"
+ "\xe8\x03\x1e\x39\x54\x6f\x8a\xa5"
+ "\xc0\xdb\xf6\x11\x2c\x47\x62\x7d"
+ "\x98\xb3\xce\xe9\x04\x1f\x3a\x55"
+ "\x70\x8b\xa6\xc1\xdc\xf7\x12\x2d"
+ "\x48\x63\x7e\x99\xb4\xcf\xea\x05"
+ "\x20\x3b\x56\x71\x8c\xa7\xc2\xdd"
+ "\xf8\x13\x2e\x49\x64\x7f\x9a\xb5"
+ "\xd0\xeb\x06\x21\x3c\x57\x72\x8d"
+ "\xa8\xc3\xde\xf9\x14\x2f\x4a\x65"
+ "\x80\x9b\xb6\xd1\xec\x07\x22\x3d"
+ "\x58\x73\x8e\xa9\xc4\xdf\xfa\x15"
+ "\x30\x4b\x66\x81\x9c\xb7\xd2\xed"
+ "\x08\x23\x3e\x59\x74\x8f\xaa\xc5"
+ "\xe0\xfb\x16\x31\x4c\x67\x82\x9d"
+ "\xb8\xd3\xee\x09\x24\x3f\x5a\x75"
+ "\x90\xab\xc6\xe1\xfc\x17\x32\x4d"
+ "\x68\x83\x9e\xb9\xd4\xef\x0a\x25"
+ "\x40\x5b\x76\x91\xac\xc7\xe2\xfd"
+ "\x18\x33\x4e\x69\x84\x9f\xba\xd5"
+ "\xf0\x0b\x26\x41\x5c\x77\x92\xad"
+ "\xc8\xe3\xfe\x19\x34\x4f\x6a\x85"
+ "\xa0\xbb\xd6\xf1\x0c\x27\x42\x5d"
+ "\x78\x93\xae\xc9\xe4\xff\x1a\x35"
+ "\x50\x6b\x86\xa1\xbc\xd7\xf2\x0d"
+ "\x28\x43\x5e\x79\x94\xaf\xca\xe5"
+ "\x00\x1d\x3a\x57\x74\x91\xae\xcb"
+ "\xe8\x05\x22\x3f\x5c\x79\x96\xb3"
+ "\xd0\xed\x0a\x27\x44\x61\x7e\x9b"
+ "\xb8\xd5\xf2\x0f\x2c\x49\x66\x83"
+ "\xa0\xbd\xda\xf7\x14\x31\x4e\x6b"
+ "\x88\xa5\xc2\xdf\xfc\x19\x36\x53"
+ "\x70\x8d\xaa\xc7\xe4\x01\x1e\x3b"
+ "\x58\x75\x92\xaf\xcc\xe9\x06\x23"
+ "\x40\x5d\x7a\x97\xb4\xd1\xee\x0b"
+ "\x28\x45\x62\x7f\x9c\xb9\xd6\xf3"
+ "\x10\x2d\x4a\x67\x84\xa1\xbe\xdb"
+ "\xf8\x15\x32\x4f\x6c\x89\xa6\xc3"
+ "\xe0\xfd\x1a\x37\x54\x71\x8e\xab"
+ "\xc8\xe5\x02\x1f\x3c\x59\x76\x93"
+ "\xb0\xcd\xea\x07\x24\x41\x5e\x7b"
+ "\x98\xb5\xd2\xef\x0c\x29\x46\x63"
+ "\x80\x9d\xba\xd7\xf4\x11\x2e\x4b"
+ "\x68\x85\xa2\xbf\xdc\xf9\x16\x33"
+ "\x50\x6d\x8a\xa7\xc4\xe1\xfe\x1b"
+ "\x38\x55\x72\x8f\xac\xc9\xe6\x03"
+ "\x20\x3d\x5a\x77\x94\xb1\xce\xeb"
+ "\x08\x25\x42\x5f\x7c\x99\xb6\xd3"
+ "\xf0\x0d\x2a\x47\x64\x81\x9e\xbb"
+ "\xd8\xf5\x12\x2f\x4c\x69\x86\xa3"
+ "\xc0\xdd\xfa\x17\x34\x51\x6e\x8b"
+ "\xa8\xc5\xe2\xff\x1c\x39\x56\x73"
+ "\x90\xad\xca\xe7\x04\x21\x3e\x5b"
+ "\x78\x95\xb2\xcf\xec\x09\x26\x43"
+ "\x60\x7d\x9a\xb7\xd4\xf1\x0e\x2b"
+ "\x48\x65\x82\x9f\xbc\xd9\xf6\x13"
+ "\x30\x4d\x6a\x87\xa4\xc1\xde\xfb"
+ "\x18\x35\x52\x6f\x8c\xa9\xc6\xe3"
+ "\x00\x1f\x3e\x5d\x7c\x9b\xba\xd9"
+ "\xf8\x17\x36\x55\x74\x93\xb2\xd1"
+ "\xf0\x0f\x2e\x4d\x6c\x8b\xaa\xc9"
+ "\xe8\x07\x26\x45\x64\x83\xa2\xc1"
+ "\xe0\xff\x1e\x3d\x5c\x7b\x9a\xb9"
+ "\xd8\xf7\x16\x35\x54\x73\x92\xb1"
+ "\xd0\xef\x0e\x2d\x4c\x6b\x8a\xa9"
+ "\xc8\xe7\x06\x25\x44\x63\x82\xa1"
+ "\xc0\xdf\xfe\x1d\x3c\x5b\x7a\x99"
+ "\xb8\xd7\xf6\x15\x34\x53\x72\x91"
+ "\xb0\xcf\xee\x0d\x2c\x4b\x6a\x89"
+ "\xa8\xc7\xe6\x05\x24\x43\x62\x81"
+ "\xa0\xbf\xde\xfd\x1c\x3b\x5a\x79"
+ "\x98\xb7\xd6\xf5\x14\x33\x52\x71"
+ "\x90\xaf\xce\xed\x0c\x2b\x4a\x69"
+ "\x88\xa7\xc6\xe5\x04\x23\x42\x61"
+ "\x80\x9f\xbe\xdd\xfc\x1b\x3a\x59"
+ "\x78\x97\xb6\xd5\xf4\x13\x32\x51"
+ "\x70\x8f\xae\xcd\xec\x0b\x2a\x49"
+ "\x68\x87\xa6\xc5\xe4\x03\x22\x41"
+ "\x60\x7f\x9e\xbd\xdc\xfb\x1a\x39"
+ "\x58\x77\x96\xb5\xd4\xf3\x12\x31"
+ "\x50\x6f\x8e\xad\xcc\xeb\x0a\x29"
+ "\x48\x67\x86\xa5\xc4\xe3\x02\x21"
+ "\x40\x5f\x7e\x9d\xbc\xdb\xfa\x19"
+ "\x38\x57\x76\x95\xb4\xd3\xf2\x11"
+ "\x30\x4f\x6e\x8d\xac\xcb\xea\x09"
+ "\x28\x47\x66\x85\xa4\xc3\xe2\x01"
+ "\x20\x3f\x5e\x7d\x9c\xbb\xda\xf9"
+ "\x18\x37\x56\x75\x94\xb3\xd2\xf1"
+ "\x10\x2f\x4e\x6d\x8c\xab\xca\xe9"
+ "\x08\x27\x46\x65\x84\xa3\xc2\xe1"
+ "\x00\x21\x42\x63",
+ .ilen = 4100,
+ .result =
+ "\xb5\x81\xf5\x64\x18\x73\xe3\xf0"
+ "\x4c\x13\xf2\x77\x18\x60\x65\x5e"
+ "\x29\x01\xce\x98\x55\x53\xf9\x0c"
+ "\x2a\x08\xd5\x09\xb3\x57\x55\x56"
+ "\xc5\xe9\x56\x90\xcb\x6a\xa3\xc0"
+ "\xff\xc4\x79\xb4\xd2\x97\x5d\xc4"
+ "\x43\xd1\xfe\x94\x7b\x88\x06\x5a"
+ "\xb2\x9e\x2c\xfc\x44\x03\xb7\x90"
+ "\xa0\xc1\xba\x6a\x33\xb8\xc7\xb2"
+ "\x9d\xe1\x12\x4f\xc0\x64\xd4\x01"
+ "\xfe\x8c\x7a\x66\xf7\xe6\x5a\x91"
+ "\xbb\xde\x56\x86\xab\x65\x21\x30"
+ "\x00\x84\x65\x24\xa5\x7d\x85\xb4"
+ "\xe3\x17\xed\x3a\xb7\x6f\xb4\x0b"
+ "\x0b\xaf\x15\xae\x5a\x8f\xf2\x0c"
+ "\x2f\x27\xf4\x09\xd8\xd2\x96\xb7"
+ "\x71\xf2\xc5\x99\x4d\x7e\x7f\x75"
+ "\x77\x89\x30\x8b\x59\xdb\xa2\xb2"
+ "\xa0\xf3\x19\x39\x2b\xc5\x7e\x3f"
+ "\x4f\xd9\xd3\x56\x28\x97\x44\xdc"
+ "\xc0\x8b\x77\x24\xd9\x52\xe7\xc5"
+ "\xaf\xf6\x7d\x59\xb2\x44\x05\x1d"
+ "\xb1\xb0\x11\xa5\x0f\xec\x33\xe1"
+ "\x6d\x1b\x4e\x1f\xff\x57\x91\xb4"
+ "\x5b\x9a\x96\xc5\x53\xbc\xae\x20"
+ "\x3c\xbb\x14\xe2\xe8\x22\x33\xc1"
+ "\x5e\x76\x9e\x46\x99\xf6\x2a\x15"
+ "\xc6\x97\x02\xa0\x66\x43\xd1\xa6"
+ "\x31\xa6\x9f\xfb\xf4\xd3\x69\xe5"
+ "\xcd\x76\x95\xb8\x7a\x82\x7f\x21"
+ "\x45\xff\x3f\xce\x55\xf6\x95\x10"
+ "\x08\x77\x10\x43\xc6\xf3\x09\xe5"
+ "\x68\xe7\x3c\xad\x00\x52\x45\x0d"
+ "\xfe\x2d\xc6\xc2\x94\x8c\x12\x1d"
+ "\xe6\x25\xae\x98\x12\x8e\x19\x9c"
+ "\x81\x68\xb1\x11\xf6\x69\xda\xe3"
+ "\x62\x08\x18\x7a\x25\x49\x28\xac"
+ "\xba\x71\x12\x0b\xe4\xa2\xe5\xc7"
+ "\x5d\x8e\xec\x49\x40\x21\xbf\x5a"
+ "\x98\xf3\x02\x68\x55\x03\x7f\x8a"
+ "\xe5\x94\x0c\x32\x5c\x07\x82\x63"
+ "\xaf\x6f\x91\x40\x84\x8e\x52\x25"
+ "\xd0\xb0\x29\x53\x05\xe2\x50\x7a"
+ "\x34\xeb\xc9\x46\x20\xa8\x3d\xde"
+ "\x7f\x16\x5f\x36\xc5\x2e\xdc\xd1"
+ "\x15\x47\xc7\x50\x40\x6d\x91\xc5"
+ "\xe7\x93\x95\x1a\xd3\x57\xbc\x52"
+ "\x33\xee\x14\x19\x22\x52\x89\xa7"
+ "\x4a\x25\x56\x77\x4b\xca\xcf\x0a"
+ "\xe1\xf5\x35\x85\x30\x7e\x59\x4a"
+ "\xbd\x14\x5b\xdf\xe3\x46\xcb\xac"
+ "\x1f\x6c\x96\x0e\xf4\x81\xd1\x99"
+ "\xca\x88\x63\x3d\x02\x58\x6b\xa9"
+ "\xe5\x9f\xb3\x00\xb2\x54\xc6\x74"
+ "\x1c\xbf\x46\xab\x97\xcc\xf8\x54"
+ "\x04\x07\x08\x52\xe6\xc0\xda\x93"
+ "\x74\x7d\x93\x99\x5d\x78\x68\xa6"
+ "\x2e\x6b\xd3\x6a\x69\xcc\x12\x6b"
+ "\xd4\xc7\xa5\xc6\xe7\xf6\x03\x04"
+ "\x5d\xcd\x61\x5e\x17\x40\xdc\xd1"
+ "\x5c\xf5\x08\xdf\x5c\x90\x85\xa4"
+ "\xaf\xf6\x78\xbb\x0d\xf1\xf4\xa4"
+ "\x54\x26\x72\x9e\x61\xfa\x86\xcf"
+ "\xe8\x9e\xa1\xe0\xc7\x48\x23\xae"
+ "\x5a\x90\xae\x75\x0a\x74\x18\x89"
+ "\x05\xb1\x92\xb2\x7f\xd0\x1b\xa6"
+ "\x62\x07\x25\x01\xc7\xc2\x4f\xf9"
+ "\xe8\xfe\x63\x95\x80\x07\xb4\x26"
+ "\xcc\xd1\x26\xb6\xc4\x3f\x9e\xcb"
+ "\x8e\x3b\x2e\x44\x16\xd3\x10\x9a"
+ "\x95\x08\xeb\xc8\xcb\xeb\xbf\x6f"
+ "\x0b\xcd\x1f\xc8\xca\x86\xaa\xec"
+ "\x33\xe6\x69\xf4\x45\x25\x86\x3a"
+ "\x22\x94\x4f\x00\x23\x6a\x44\xc2"
+ "\x49\x97\x33\xab\x36\x14\x0a\x70"
+ "\x24\xc3\xbe\x04\x3b\x79\xa0\xf9"
+ "\xb8\xe7\x76\x29\x22\x83\xd7\xf2"
+ "\x94\xf4\x41\x49\xba\x5f\x7b\x07"
+ "\xb5\xfb\xdb\x03\x1a\x9f\xb6\x4c"
+ "\xc2\x2e\x37\x40\x49\xc3\x38\x16"
+ "\xe2\x4f\x77\x82\xb0\x68\x4c\x71"
+ "\x1d\x57\x61\x9c\xd9\x4e\x54\x99"
+ "\x47\x13\x28\x73\x3c\xbb\x00\x90"
+ "\xf3\x4d\xc9\x0e\xfd\xe7\xb1\x71"
+ "\xd3\x15\x79\xbf\xcc\x26\x2f\xbd"
+ "\xad\x6c\x50\x69\x6c\x3e\x6d\x80"
+ "\x9a\xea\x78\xaf\x19\xb2\x0d\x4d"
+ "\xad\x04\x07\xae\x22\x90\x4a\x93"
+ "\x32\x0e\x36\x9b\x1b\x46\xba\x3b"
+ "\xb4\xac\xc6\xd1\xa2\x31\x53\x3b"
+ "\x2a\x3d\x45\xfe\x03\x61\x10\x85"
+ "\x17\x69\xa6\x78\xcc\x6c\x87\x49"
+ "\x53\xf9\x80\x10\xde\x80\xa2\x41"
+ "\x6a\xc3\x32\x02\xad\x6d\x3c\x56"
+ "\x00\x71\x51\x06\xa7\xbd\xfb\xef"
+ "\x3c\xb5\x9f\xfc\x48\x7d\x53\x7c"
+ "\x66\xb0\x49\x23\xc4\x47\x10\x0e"
+ "\xe5\x6c\x74\x13\xe6\xc5\x3f\xaa"
+ "\xde\xff\x07\x44\xdd\x56\x1b\xad"
+ "\x09\x77\xfb\x5b\x12\xb8\x0d\x38"
+ "\x17\x37\x35\x7b\x9b\xbc\xfe\xd4"
+ "\x7e\x8b\xda\x7e\x5b\x04\xa7\x22"
+ "\xa7\x31\xa1\x20\x86\xc7\x1b\x99"
+ "\xdb\xd1\x89\xf4\x94\xa3\x53\x69"
+ "\x8d\xe7\xe8\x74\x11\x8d\x74\xd6"
+ "\x07\x37\x91\x9f\xfd\x67\x50\x3a"
+ "\xc9\xe1\xf4\x36\xd5\xa0\x47\xd1"
+ "\xf9\xe5\x39\xa3\x31\xac\x07\x36"
+ "\x23\xf8\x66\x18\x14\x28\x34\x0f"
+ "\xb8\xd0\xe7\x29\xb3\x04\x4b\x55"
+ "\x01\x41\xb2\x75\x8d\xcb\x96\x85"
+ "\x3a\xfb\xab\x2b\x9e\xfa\x58\x20"
+ "\x44\x1f\xc0\x14\x22\x75\x61\xe8"
+ "\xaa\x19\xcf\xf1\x82\x56\xf4\xd7"
+ "\x78\x7b\x3d\x5f\xb3\x9e\x0b\x8a"
+ "\x57\x50\xdb\x17\x41\x65\x4d\xa3"
+ "\x02\xc9\x9c\x9c\x53\xfb\x39\x39"
+ "\x9b\x1d\x72\x24\xda\xb7\x39\xbe"
+ "\x13\x3b\xfa\x29\xda\x9e\x54\x64"
+ "\x6e\xba\xd8\xa1\xcb\xb3\x36\xfa"
+ "\xcb\x47\x85\xe9\x61\x38\xbc\xbe"
+ "\xc5\x00\x38\x2a\x54\xf7\xc4\xb9"
+ "\xb3\xd3\x7b\xa0\xa0\xf8\x72\x7f"
+ "\x8c\x8e\x82\x0e\xc6\x1c\x75\x9d"
+ "\xca\x8e\x61\x87\xde\xad\x80\xd2"
+ "\xf5\xf9\x80\xef\x15\x75\xaf\xf5"
+ "\x80\xfb\xff\x6d\x1e\x25\xb7\x40"
+ "\x61\x6a\x39\x5a\x6a\xb5\x31\xab"
+ "\x97\x8a\x19\x89\x44\x40\xc0\xa6"
+ "\xb4\x4e\x30\x32\x7b\x13\xe7\x67"
+ "\xa9\x8b\x57\x04\xc2\x01\xa6\xf4"
+ "\x28\x99\xad\x2c\x76\xa3\x78\xc2"
+ "\x4a\xe6\xca\x5c\x50\x6a\xc1\xb0"
+ "\x62\x4b\x10\x8e\x7c\x17\x43\xb3"
+ "\x17\x66\x1c\x3e\x8d\x69\xf0\x5a"
+ "\x71\xf5\x97\xdc\xd1\x45\xdd\x28"
+ "\xf3\x5d\xdf\x53\x7b\x11\xe5\xbc"
+ "\x4c\xdb\x1b\x51\x6b\xe9\xfb\x3d"
+ "\xc1\xc3\x2c\xb9\x71\xf5\xb6\xb2"
+ "\x13\x36\x79\x80\x53\xe8\xd3\xa6"
+ "\x0a\xaf\xfd\x56\x97\xf7\x40\x8e"
+ "\x45\xce\xf8\xb0\x9e\x5c\x33\x82"
+ "\xb0\x44\x56\xfc\x05\x09\xe9\x2a"
+ "\xac\x26\x80\x14\x1d\xc8\x3a\x35"
+ "\x4c\x82\x97\xfd\x76\xb7\xa9\x0a"
+ "\x35\x58\x79\x8e\x0f\x66\xea\xaf"
+ "\x51\x6c\x09\xa9\x6e\x9b\xcb\x9a"
+ "\x31\x47\xa0\x2f\x7c\x71\xb4\x4a"
+ "\x11\xaa\x8c\x66\xc5\x64\xe6\x3a"
+ "\x54\xda\x24\x6a\xc4\x41\x65\x46"
+ "\x82\xa0\x0a\x0f\x5f\xfb\x25\xd0"
+ "\x2c\x91\xa7\xee\xc4\x81\x07\x86"
+ "\x75\x5e\x33\x69\x97\xe4\x2c\xa8"
+ "\x9d\x9f\x0b\x6a\xbe\xad\x98\xda"
+ "\x6d\x94\x41\xda\x2c\x1e\x89\xc4"
+ "\xc2\xaf\x1e\x00\x05\x0b\x83\x60"
+ "\xbd\x43\xea\x15\x23\x7f\xb9\xac"
+ "\xee\x4f\x2c\xaf\x2a\xf3\xdf\xd0"
+ "\xf3\x19\x31\xbb\x4a\x74\x84\x17"
+ "\x52\x32\x2c\x7d\x61\xe4\xcb\xeb"
+ "\x80\x38\x15\x52\xcb\x6f\xea\xe5"
+ "\x73\x9c\xd9\x24\x69\xc6\x95\x32"
+ "\x21\xc8\x11\xe4\xdc\x36\xd7\x93"
+ "\x38\x66\xfb\xb2\x7f\x3a\xb9\xaf"
+ "\x31\xdd\x93\x75\x78\x8a\x2c\x94"
+ "\x87\x1a\x58\xec\x9e\x7d\x4d\xba"
+ "\xe1\xe5\x4d\xfc\xbc\xa4\x2a\x14"
+ "\xef\xcc\xa7\xec\xab\x43\x09\x18"
+ "\xd3\xab\x68\xd1\x07\x99\x44\x47"
+ "\xd6\x83\x85\x3b\x30\xea\xa9\x6b"
+ "\x63\xea\xc4\x07\xfb\x43\x2f\xa4"
+ "\xaa\xb0\xab\x03\x89\xce\x3f\x8c"
+ "\x02\x7c\x86\x54\xbc\x88\xaf\x75"
+ "\xd2\xdc\x63\x17\xd3\x26\xf6\x96"
+ "\xa9\x3c\xf1\x61\x8c\x11\x18\xcc"
+ "\xd6\xea\x5b\xe2\xcd\xf0\xf1\xb2"
+ "\xe5\x35\x90\x1f\x85\x4c\x76\x5b"
+ "\x66\xce\x44\xa4\x32\x9f\xe6\x7b"
+ "\x71\x6e\x9f\x58\x15\x67\x72\x87"
+ "\x64\x8e\x3a\x44\x45\xd4\x76\xfa"
+ "\xc2\xf6\xef\x85\x05\x18\x7a\x9b"
+ "\xba\x41\x54\xac\xf0\xfc\x59\x12"
+ "\x3f\xdf\xa0\xe5\x8a\x65\xfd\x3a"
+ "\x62\x8d\x83\x2c\x03\xbe\x05\x76"
+ "\x2e\x53\x49\x97\x94\x33\xae\x40"
+ "\x81\x15\xdb\x6e\xad\xaa\xf5\x4b"
+ "\xe3\x98\x70\xdf\xe0\x7c\xcd\xdb"
+ "\x02\xd4\x7d\x2f\xc1\xe6\xb4\xf3"
+ "\xd7\x0d\x7a\xd9\x23\x9e\x87\x2d"
+ "\xce\x87\xad\xcc\x72\x05\x00\x29"
+ "\xdc\x73\x7f\x64\xc1\x15\x0e\xc2"
+ "\xdf\xa7\x5f\xeb\x41\xa1\xcd\xef"
+ "\x5c\x50\x79\x2a\x56\x56\x71\x8c"
+ "\xac\xc0\x79\x50\x69\xca\x59\x32"
+ "\x65\xf2\x54\xe4\x52\x38\x76\xd1"
+ "\x5e\xde\x26\x9e\xfb\x75\x2e\x11"
+ "\xb5\x10\xf4\x17\x73\xf5\x89\xc7"
+ "\x4f\x43\x5c\x8e\x7c\xb9\x05\x52"
+ "\x24\x40\x99\xfe\x9b\x85\x0b\x6c"
+ "\x22\x3e\x8b\xae\x86\xa1\xd2\x79"
+ "\x05\x68\x6b\xab\xe3\x41\x49\xed"
+ "\x15\xa1\x8d\x40\x2d\x61\xdf\x1a"
+ "\x59\xc9\x26\x8b\xef\x30\x4c\x88"
+ "\x4b\x10\xf8\x8d\xa6\x92\x9f\x4b"
+ "\xf3\xc4\x53\x0b\x89\x5d\x28\x92"
+ "\xcf\x78\xb2\xc0\x5d\xed\x7e\xfc"
+ "\xc0\x12\x23\x5f\x5a\x78\x86\x43"
+ "\x6e\x27\xf7\x5a\xa7\x6a\xed\x19"
+ "\x04\xf0\xb3\x12\xd1\xbd\x0e\x89"
+ "\x6e\xbc\x96\xa8\xd8\x49\x39\x9f"
+ "\x7e\x67\xf0\x2e\x3e\x01\xa9\xba"
+ "\xec\x8b\x62\x8e\xcb\x4a\x70\x43"
+ "\xc7\xc2\xc4\xca\x82\x03\x73\xe9"
+ "\x11\xdf\xcf\x54\xea\xc9\xb0\x95"
+ "\x51\xc0\x13\x3d\x92\x05\xfa\xf4"
+ "\xa9\x34\xc8\xce\x6c\x3d\x54\xcc"
+ "\xc4\xaf\xf1\xdc\x11\x44\x26\xa2"
+ "\xaf\xf1\x85\x75\x7d\x03\x61\x68"
+ "\x4e\x78\xc6\x92\x7d\x86\x7d\x77"
+ "\xdc\x71\x72\xdb\xc6\xae\xa1\xcb"
+ "\x70\x9a\x0b\x19\xbe\x4a\x6c\x2a"
+ "\xe2\xba\x6c\x64\x9a\x13\x28\xdf"
+ "\x85\x75\xe6\x43\xf6\x87\x08\x68"
+ "\x6e\xba\x6e\x79\x9f\x04\xbc\x23"
+ "\x50\xf6\x33\x5c\x1f\x24\x25\xbe"
+ "\x33\x47\x80\x45\x56\xa3\xa7\xd7"
+ "\x7a\xb1\x34\x0b\x90\x3c\x9c\xad"
+ "\x44\x5f\x9e\x0e\x9d\xd4\xbd\x93"
+ "\x5e\xfa\x3c\xe0\xb0\xd9\xed\xf3"
+ "\xd6\x2e\xff\x24\xd8\x71\x6c\xed"
+ "\xaf\x55\xeb\x22\xac\x93\x68\x32"
+ "\x05\x5b\x47\xdd\xc6\x4a\xcb\xc7"
+ "\x10\xe1\x3c\x92\x1a\xf3\x23\x78"
+ "\x2b\xa1\xd2\x80\xf4\x12\xb1\x20"
+ "\x8f\xff\x26\x35\xdd\xfb\xc7\x4e"
+ "\x78\xf1\x2d\x50\x12\x77\xa8\x60"
+ "\x7c\x0f\xf5\x16\x2f\x63\x70\x2a"
+ "\xc0\x96\x80\x4e\x0a\xb4\x93\x35"
+ "\x5d\x1d\x3f\x56\xf7\x2f\xbb\x90"
+ "\x11\x16\x8f\xa2\xec\x47\xbe\xac"
+ "\x56\x01\x26\x56\xb1\x8c\xb2\x10"
+ "\xf9\x1a\xca\xf5\xd1\xb7\x39\x20"
+ "\x63\xf1\x69\x20\x4f\x13\x12\x1f"
+ "\x5b\x65\xfc\x98\xf7\xc4\x7a\xbe"
+ "\xf7\x26\x4d\x2b\x84\x7b\x42\xad"
+ "\xd8\x7a\x0a\xb4\xd8\x74\xbf\xc1"
+ "\xf0\x6e\xb4\x29\xa3\xbb\xca\x46"
+ "\x67\x70\x6a\x2d\xce\x0e\xa2\x8a"
+ "\xa9\x87\xbf\x05\xc4\xc1\x04\xa3"
+ "\xab\xd4\x45\x43\x8c\xb6\x02\xb0"
+ "\x41\xc8\xfc\x44\x3d\x59\xaa\x2e"
+ "\x44\x21\x2a\x8d\x88\x9d\x57\xf4"
+ "\xa0\x02\x77\xb8\xa6\xa0\xe6\x75"
+ "\x5c\x82\x65\x3e\x03\x5c\x29\x8f"
+ "\x38\x55\xab\x33\x26\xef\x9f\x43"
+ "\x52\xfd\x68\xaf\x36\xb4\xbb\x9a"
+ "\x58\x09\x09\x1b\xc3\x65\x46\x46"
+ "\x1d\xa7\x94\x18\x23\x50\x2c\xca"
+ "\x2c\x55\x19\x97\x01\x9d\x93\x3b"
+ "\x63\x86\xf2\x03\x67\x45\xd2\x72"
+ "\x28\x52\x6c\xf4\xe3\x1c\xb5\x11"
+ "\x13\xf1\xeb\x21\xc7\xd9\x56\x82"
+ "\x2b\x82\x39\xbd\x69\x54\xed\x62"
+ "\xc3\xe2\xde\x73\xd4\x6a\x12\xae"
+ "\x13\x21\x7f\x4b\x5b\xfc\xbf\xe8"
+ "\x2b\xbe\x56\xba\x68\x8b\x9a\xb1"
+ "\x6e\xfa\xbf\x7e\x5a\x4b\xf1\xac"
+ "\x98\x65\x85\xd1\x93\x53\xd3\x7b"
+ "\x09\xdd\x4b\x10\x6d\x84\xb0\x13"
+ "\x65\xbd\xcf\x52\x09\xc4\x85\xe2"
+ "\x84\x74\x15\x65\xb7\xf7\x51\xaf"
+ "\x55\xad\xa4\xd1\x22\x54\x70\x94"
+ "\xa0\x1c\x90\x41\xfd\x99\xd7\x5a"
+ "\x31\xef\xaa\x25\xd0\x7f\x4f\xea"
+ "\x1d\x55\x42\xe5\x49\xb0\xd0\x46"
+ "\x62\x36\x43\xb2\x82\x15\x75\x50"
+ "\xa4\x72\xeb\x54\x27\x1f\x8a\xe4"
+ "\x7d\xe9\x66\xc5\xf1\x53\xa4\xd1"
+ "\x0c\xeb\xb8\xf8\xbc\xd4\xe2\xe7"
+ "\xe1\xf8\x4b\xcb\xa9\xa1\xaf\x15"
+ "\x83\xcb\x72\xd0\x33\x79\x00\x2d"
+ "\x9f\xd7\xf1\x2e\x1e\x10\xe4\x45"
+ "\xc0\x75\x3a\x39\xea\x68\xf7\x5d"
+ "\x1b\x73\x8f\xe9\x8e\x0f\x72\x47"
+ "\xae\x35\x0a\x31\x7a\x14\x4d\x4a"
+ "\x6f\x47\xf7\x7e\x91\x6e\x74\x8b"
+ "\x26\x47\xf9\xc3\xf9\xde\x70\xf5"
+ "\x61\xab\xa9\x27\x9f\x82\xe4\x9c"
+ "\x89\x91\x3f\x2e\x6a\xfd\xb5\x49"
+ "\xe9\xfd\x59\x14\x36\x49\x40\x6d"
+ "\x32\xd8\x85\x42\xf3\xa5\xdf\x0c"
+ "\xa8\x27\xd7\x54\xe2\x63\x2f\xf2"
+ "\x7e\x8b\x8b\xe7\xf1\x9a\x95\x35"
+ "\x43\xdc\x3a\xe4\xb6\xf4\xd0\xdf"
+ "\x9c\xcb\x94\xf3\x21\xa0\x77\x50"
+ "\xe2\xc6\xc4\xc6\x5f\x09\x64\x5b"
+ "\x92\x90\xd8\xe1\xd1\xed\x4b\x42"
+ "\xd7\x37\xaf\x65\x3d\x11\x39\xb6"
+ "\x24\x8a\x60\xae\xd6\x1e\xbf\x0e"
+ "\x0d\xd7\xdc\x96\x0e\x65\x75\x4e"
+ "\x29\x06\x9d\xa4\x51\x3a\x10\x63"
+ "\x8f\x17\x07\xd5\x8e\x3c\xf4\x28"
+ "\x00\x5a\x5b\x05\x19\xd8\xc0\x6c"
+ "\xe5\x15\xe4\x9c\x9d\x71\x9d\x5e"
+ "\x94\x29\x1a\xa7\x80\xfa\x0e\x33"
+ "\x03\xdd\xb7\x3e\x9a\xa9\x26\x18"
+ "\x37\xa9\x64\x08\x4d\x94\x5a\x88"
+ "\xca\x35\xce\x81\x02\xe3\x1f\x1b"
+ "\x89\x1a\x77\x85\xe3\x41\x6d\x32"
+ "\x42\x19\x23\x7d\xc8\x73\xee\x25"
+ "\x85\x0d\xf8\x31\x25\x79\x1b\x6f"
+ "\x79\x25\xd2\xd8\xd4\x23\xfd\xf7"
+ "\x82\x36\x6a\x0c\x46\x22\x15\xe9"
+ "\xff\x72\x41\x91\x91\x7d\x3a\xb7"
+ "\xdd\x65\x99\x70\xf6\x8d\x84\xf8"
+ "\x67\x15\x20\x11\xd6\xb2\x55\x7b"
+ "\xdb\x87\xee\xef\x55\x89\x2a\x59"
+ "\x2b\x07\x8f\x43\x8a\x59\x3c\x01"
+ "\x8b\x65\x54\xa1\x66\xd5\x38\xbd"
+ "\xc6\x30\xa9\xcc\x49\xb6\xa8\x1b"
+ "\xb8\xc0\x0e\xe3\x45\x28\xe2\xff"
+ "\x41\x9f\x7e\x7c\xd1\xae\x9e\x25"
+ "\x3f\x4c\x7c\x7c\xf4\xa8\x26\x4d"
+ "\x5c\xfd\x4b\x27\x18\xf9\x61\x76"
+ "\x48\xba\x0c\x6b\xa9\x4d\xfc\xf5"
+ "\x3b\x35\x7e\x2f\x4a\xa9\xc2\x9a"
+ "\xae\xab\x86\x09\x89\xc9\xc2\x40"
+ "\x39\x2c\x81\xb3\xb8\x17\x67\xc2"
+ "\x0d\x32\x4a\x3a\x67\x81\xd7\x1a"
+ "\x34\x52\xc5\xdb\x0a\xf5\x63\x39"
+ "\xea\x1f\xe1\x7c\xa1\x9e\xc1\x35"
+ "\xe3\xb1\x18\x45\x67\xf9\x22\x38"
+ "\x95\xd9\x34\x34\x86\xc6\x41\x94"
+ "\x15\xf9\x5b\x41\xa6\x87\x8b\xf8"
+ "\xd5\xe1\x1b\xe2\x5b\xf3\x86\x10"
+ "\xff\xe6\xae\x69\x76\xbc\x0d\xb4"
+ "\x09\x90\x0c\xa2\x65\x0c\xad\x74"
+ "\xf5\xd7\xff\xda\xc1\xce\x85\xbe"
+ "\x00\xa7\xff\x4d\x2f\x65\xd3\x8c"
+ "\x86\x2d\x05\xe8\xed\x3e\x6b\x8b"
+ "\x0f\x3d\x83\x8c\xf1\x1d\x5b\x96"
+ "\x2e\xb1\x9c\xc2\x98\xe1\x70\xb9"
+ "\xba\x5c\x8a\x43\xd6\x34\xa7\x2d"
+ "\xc9\x92\xae\xf2\xa5\x7b\x05\x49"
+ "\xa7\x33\x34\x86\xca\xe4\x96\x23"
+ "\x76\x5b\xf2\xc6\xf1\x51\x28\x42"
+ "\x7b\xcc\x76\x8f\xfa\xa2\xad\x31"
+ "\xd4\xd6\x7a\x6d\x25\x25\x54\xe4"
+ "\x3f\x50\x59\xe1\x5c\x05\xb7\x27"
+ "\x48\xbf\x07\xec\x1b\x13\xbe\x2b"
+ "\xa1\x57\x2b\xd5\xab\xd7\xd0\x4c"
+ "\x1e\xcb\x71\x9b\xc5\x90\x85\xd3"
+ "\xde\x59\xec\x71\xeb\x89\xbb\xd0"
+ "\x09\x50\xe1\x16\x3f\xfd\x1c\x34"
+ "\xc3\x1c\xa1\x10\x77\x53\x98\xef"
+ "\xf2\xfd\xa5\x01\x59\xc2\x9b\x26"
+ "\xc7\x42\xd9\x49\xda\x58\x2b\x6e"
+ "\x9f\x53\x19\x76\x7e\xd9\xc9\x0e"
+ "\x68\xc8\x7f\x51\x22\x42\xef\x49"
+ "\xa4\x55\xb6\x36\xac\x09\xc7\x31"
+ "\x88\x15\x4b\x2e\x8f\x3a\x08\xf7"
+ "\xd8\xf7\xa8\xc5\xa9\x33\xa6\x45"
+ "\xe4\xc4\x94\x76\xf3\x0d\x8f\x7e"
+ "\xc8\xf6\xbc\x23\x0a\xb6\x4c\xd3"
+ "\x6a\xcd\x36\xc2\x90\x5c\x5c\x3c"
+ "\x65\x7b\xc2\xd6\xcc\xe6\x0d\x87"
+ "\x73\x2e\x71\x79\x16\x06\x63\x28"
+ "\x09\x15\xd8\x89\x38\x38\x3d\xb5"
+ "\x42\x1c\x08\x24\xf7\x2a\xd2\x9d"
+ "\xc8\xca\xef\xf9\x27\xd8\x07\x86"
+ "\xf7\x43\x0b\x55\x15\x3f\x9f\x83"
+ "\xef\xdc\x49\x9d\x2a\xc1\x54\x62"
+ "\xbd\x9b\x66\x55\x9f\xb7\x12\xf3"
+ "\x1b\x4d\x9d\x2a\x5c\xed\x87\x75"
+ "\x87\x26\xec\x61\x2c\xb4\x0f\x89"
+ "\xb0\xfb\x2e\x68\x5d\x15\xc7\x8d"
+ "\x2e\xc0\xd9\xec\xaf\x4f\xd2\x25"
+ "\x29\xe8\xd2\x26\x2b\x67\xe9\xfc"
+ "\x2b\xa8\x67\x96\x12\x1f\x5b\x96"
+ "\xc6\x14\x53\xaf\x44\xea\xd6\xe2"
+ "\x94\x98\xe4\x12\x93\x4c\x92\xe0"
+ "\x18\xa5\x8d\x2d\xe4\x71\x3c\x47"
+ "\x4c\xf7\xe6\x47\x9e\xc0\x68\xdf"
+ "\xd4\xf5\x5a\x74\xb1\x2b\x29\x03"
+ "\x19\x07\xaf\x90\x62\x5c\x68\x98"
+ "\x48\x16\x11\x02\x9d\xee\xb4\x9b"
+ "\xe5\x42\x7f\x08\xfd\x16\x32\x0b"
+ "\xd0\xb3\xfa\x2b\xb7\x99\xf9\x29"
+ "\xcd\x20\x45\x9f\xb3\x1a\x5d\xa2"
+ "\xaf\x4d\xe0\xbd\x42\x0d\xbc\x74"
+ "\x99\x9c\x8e\x53\x1a\xb4\x3e\xbd"
+ "\xa2\x9a\x2d\xf7\xf8\x39\x0f\x67"
+ "\x63\xfc\x6b\xc0\xaf\xb3\x4b\x4f"
+ "\x55\xc4\xcf\xa7\xc8\x04\x11\x3e"
+ "\x14\x32\xbb\x1b\x38\x77\xd6\x7f"
+ "\x54\x4c\xdf\x75\xf3\x07\x2d\x33"
+ "\x9b\xa8\x20\xe1\x7b\x12\xb5\xf3"
+ "\xef\x2f\xce\x72\xe5\x24\x60\xc1"
+ "\x30\xe2\xab\xa1\x8e\x11\x09\xa8"
+ "\x21\x33\x44\xfe\x7f\x35\x32\x93"
+ "\x39\xa7\xad\x8b\x79\x06\xb2\xcb"
+ "\x4e\xa9\x5f\xc7\xba\x74\x29\xec"
+ "\x93\xa0\x4e\x54\x93\xc0\xbc\x55"
+ "\x64\xf0\x48\xe5\x57\x99\xee\x75"
+ "\xd6\x79\x0f\x66\xb7\xc6\x57\x76"
+ "\xf7\xb7\xf3\x9c\xc5\x60\xe8\x7f"
+ "\x83\x76\xd6\x0e\xaa\xe6\x90\x39"
+ "\x1d\xa6\x32\x6a\x34\xe3\x55\xf8"
+ "\x58\xa0\x58\x7d\x33\xe0\x22\x39"
+ "\x44\x64\x87\x86\x5a\x2f\xa7\x7e"
+ "\x0f\x38\xea\xb0\x30\xcc\x61\xa5"
+ "\x6a\x32\xae\x1e\xf7\xe9\xd0\xa9"
+ "\x0c\x32\x4b\xb5\x49\x28\xab\x85"
+ "\x2f\x8e\x01\x36\x38\x52\xd0\xba"
+ "\xd6\x02\x78\xf8\x0e\x3e\x9c\x8b"
+ "\x6b\x45\x99\x3f\x5c\xfe\x58\xf1"
+ "\x5c\x94\x04\xe1\xf5\x18\x6d\x51"
+ "\xb2\x5d\x18\x20\xb6\xc2\x9a\x42"
+ "\x1d\xb3\xab\x3c\xb6\x3a\x13\x03"
+ "\xb2\x46\x82\x4f\xfc\x64\xbc\x4f"
+ "\xca\xfa\x9c\xc0\xd5\xa7\xbd\x11"
+ "\xb7\xe4\x5a\xf6\x6f\x4d\x4d\x54"
+ "\xea\xa4\x98\x66\xd4\x22\x3b\xd3"
+ "\x8f\x34\x47\xd9\x7c\xf4\x72\x3b"
+ "\x4d\x02\x77\xf6\xd6\xdd\x08\x0a"
+ "\x81\xe1\x86\x89\x3e\x56\x10\x3c"
+ "\xba\xd7\x81\x8c\x08\xbc\x8b\xe2"
+ "\x53\xec\xa7\x89\xee\xc8\x56\xb5"
+ "\x36\x2c\xb2\x03\xba\x99\xdd\x7c"
+ "\x48\xa0\xb0\xbc\x91\x33\xe9\xa8"
+ "\xcb\xcd\xcf\x59\x5f\x1f\x15\xe2"
+ "\x56\xf5\x4e\x01\x35\x27\x45\x77"
+ "\x47\xc8\xbc\xcb\x7e\x39\xc1\x97"
+ "\x28\xd3\x84\xfc\x2c\x3e\xc8\xad"
+ "\x9c\xf8\x8a\x61\x9c\x28\xaa\xc5"
+ "\x99\x20\x43\x85\x9d\xa5\xe2\x8b"
+ "\xb8\xae\xeb\xd0\x32\x0d\x52\x78"
+ "\x09\x56\x3f\xc7\xd8\x7e\x26\xfc"
+ "\x37\xfb\x6f\x04\xfc\xfa\x92\x10"
+ "\xac\xf8\x3e\x21\xdc\x8c\x21\x16"
+ "\x7d\x67\x6e\xf6\xcd\xda\xb6\x98"
+ "\x23\xab\x23\x3c\xb2\x10\xa0\x53"
+ "\x5a\x56\x9f\xc5\xd0\xff\xbb\xe4"
+ "\x98\x3c\x69\x1e\xdb\x38\x8f\x7e"
+ "\x0f\xd2\x98\x88\x81\x8b\x45\x67"
+ "\xea\x33\xf1\xeb\xe9\x97\x55\x2e"
+ "\xd9\xaa\xeb\x5a\xec\xda\xe1\x68"
+ "\xa8\x9d\x3c\x84\x7c\x05\x3d\x62"
+ "\x87\x8f\x03\x21\x28\x95\x0c\x89"
+ "\x25\x22\x4a\xb0\x93\xa9\x50\xa2"
+ "\x2f\x57\x6e\x18\x42\x19\x54\x0c"
+ "\x55\x67\xc6\x11\x49\xf4\x5c\xd2"
+ "\xe9\x3d\xdd\x8b\x48\x71\x21\x00"
+ "\xc3\x9a\x6c\x85\x74\x28\x83\x4a"
+ "\x1b\x31\x05\xe1\x06\x92\xe7\xda"
+ "\x85\x73\x78\x45\x20\x7f\xae\x13"
+ "\x7c\x33\x06\x22\xf4\x83\xf9\x35"
+ "\x3f\x6c\x71\xa8\x4e\x48\xbe\x9b"
+ "\xce\x8a\xba\xda\xbe\x28\x08\xf7"
+ "\xe2\x14\x8c\x71\xea\x72\xf9\x33"
+ "\xf2\x88\x3f\xd7\xbb\x69\x6c\x29"
+ "\x19\xdc\x84\xce\x1f\x12\x4f\xc8"
+ "\xaf\xa5\x04\xba\x5a\xab\xb0\xd9"
+ "\x14\x1f\x6c\x68\x98\x39\x89\x7a"
+ "\xd9\xd8\x2f\xdf\xa8\x47\x4a\x25"
+ "\xe2\xfb\x33\xf4\x59\x78\xe1\x68"
+ "\x85\xcf\xfe\x59\x20\xd4\x05\x1d"
+ "\x80\x99\xae\xbc\xca\xae\x0f\x2f"
+ "\x65\x43\x34\x8e\x7e\xac\xd3\x93"
+ "\x2f\xac\x6d\x14\x3d\x02\x07\x70"
+ "\x9d\xa4\xf3\x1b\x5c\x36\xfc\x01"
+ "\x73\x34\x85\x0c\x6c\xd6\xf1\xbd"
+ "\x3f\xdf\xee\xf5\xd9\xba\x56\xef"
+ "\xf4\x9b\x6b\xee\x9f\x5a\x78\x6d"
+ "\x32\x19\xf4\xf7\xf8\x4c\x69\x0b"
+ "\x4b\xbc\xbb\xb7\xf2\x85\xaf\x70"
+ "\x75\x24\x6c\x54\xa7\x0e\x4d\x1d"
+ "\x01\xbf\x08\xac\xcf\x7f\x2c\xe3"
+ "\x14\x89\x5e\x70\x5a\x99\x92\xcd"
+ "\x01\x84\xc8\xd2\xab\xe5\x4f\x58"
+ "\xe7\x0f\x2f\x0e\xff\x68\xea\xfd"
+ "\x15\xb3\x17\xe6\xb0\xe7\x85\xd8"
+ "\x23\x2e\x05\xc7\xc9\xc4\x46\x1f"
+ "\xe1\x9e\x49\x20\x23\x24\x4d\x7e"
+ "\x29\x65\xff\xf4\xb6\xfd\x1a\x85"
+ "\xc4\x16\xec\xfc\xea\x7b\xd6\x2c"
+ "\x43\xf8\xb7\xbf\x79\xc0\x85\xcd"
+ "\xef\xe1\x98\xd3\xa5\xf7\x90\x8c"
+ "\xe9\x7f\x80\x6b\xd2\xac\x4c\x30"
+ "\xa7\xc6\x61\x6c\xd2\xf9\x2c\xff"
+ "\x30\xbc\x22\x81\x7d\x93\x12\xe4"
+ "\x0a\xcd\xaf\xdd\xe8\xab\x0a\x1e"
+ "\x13\xa4\x27\xc3\x5f\xf7\x4b\xbb"
+ "\x37\x09\x4b\x91\x6f\x92\x4f\xaf"
+ "\x52\xee\xdf\xef\x09\x6f\xf7\x5c"
+ "\x6e\x12\x17\x72\x63\x57\xc7\xba"
+ "\x3b\x6b\x38\x32\x73\x1b\x9c\x80"
+ "\xc1\x7a\xc6\xcf\xcd\x35\xc0\x6b"
+ "\x31\x1a\x6b\xe9\xd8\x2c\x29\x3f"
+ "\x96\xfb\xb6\xcd\x13\x91\x3b\xc2"
+ "\xd2\xa3\x31\x8d\xa4\xcd\x57\xcd"
+ "\x13\x3d\x64\xfd\x06\xce\xe6\xdc"
+ "\x0c\x24\x43\x31\x40\x57\xf1\x72"
+ "\x17\xe3\x3a\x63\x6d\x35\xcf\x5d"
+ "\x97\x40\x59\xdd\xf7\x3c\x02\xf7"
+ "\x1c\x7e\x05\xbb\xa9\x0d\x01\xb1"
+ "\x8e\xc0\x30\xa9\x53\x24\xc9\x89"
+ "\x84\x6d\xaa\xd0\xcd\x91\xc2\x4d"
+ "\x91\xb0\x89\xe2\xbf\x83\x44\xaa"
+ "\x28\x72\x23\xa0\xc2\xad\xad\x1c"
+ "\xfc\x3f\x09\x7a\x0b\xdc\xc5\x1b"
+ "\x87\x13\xc6\x5b\x59\x8d\xf2\xc8"
+ "\xaf\xdf\x11\x95",
+ .rlen = 4100,
+ .np = 2,
+ .tap = { 4064, 36 },
+ },
+};
+
+/*
+ * CTS (Cipher Text Stealing) mode tests
+ */
+#define CTS_MODE_ENC_TEST_VECTORS 6
+#define CTS_MODE_DEC_TEST_VECTORS 6
+static struct cipher_testvec cts_mode_enc_tv_template[] = {
+ { /* from rfc3962 */
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .ilen = 17,
+ .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20",
+ .rlen = 17,
+ .result = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4"
+ "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
+ "\x97",
+ }, {
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .ilen = 31,
+ .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+ "\x20\x47\x61\x75\x27\x73\x20",
+ .rlen = 31,
+ .result = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1"
+ "\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
+ "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+ "\xc0\x7b\x25\xe2\x5e\xcf\xe5",
+ }, {
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .ilen = 32,
+ .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+ "\x20\x47\x61\x75\x27\x73\x20\x43",
+ .rlen = 32,
+ .result = "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+ "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+ "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+ "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
+ }, {
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .ilen = 47,
+ .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+ "\x20\x47\x61\x75\x27\x73\x20\x43"
+ "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+ "\x70\x6c\x65\x61\x73\x65\x2c",
+ .rlen = 47,
+ .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+ "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c"
+ "\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+ "\xbe\x7f\xcb\xcc\x98\xeb\xf5",
+ }, {
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .ilen = 48,
+ .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+ "\x20\x47\x61\x75\x27\x73\x20\x43"
+ "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+ "\x70\x6c\x65\x61\x73\x65\x2c\x20",
+ .rlen = 48,
+ .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+ "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+ "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+ "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
+ }, {
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .ilen = 64,
+ .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+ "\x20\x47\x61\x75\x27\x73\x20\x43"
+ "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+ "\x70\x6c\x65\x61\x73\x65\x2c\x20"
+ "\x61\x6e\x64\x20\x77\x6f\x6e\x74"
+ "\x6f\x6e\x20\x73\x6f\x75\x70\x2e",
+ .rlen = 64,
+ .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+ "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+ "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+ "\x48\x07\xef\xe8\x36\xee\x89\xa5"
+ "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
+ "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+ "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
+ }
+};
+
+static struct cipher_testvec cts_mode_dec_tv_template[] = {
+ { /* from rfc3962 */
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .rlen = 17,
+ .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20",
+ .ilen = 17,
+ .input = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4"
+ "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
+ "\x97",
+ }, {
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .rlen = 31,
+ .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+ "\x20\x47\x61\x75\x27\x73\x20",
+ .ilen = 31,
+ .input = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1"
+ "\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
+ "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+ "\xc0\x7b\x25\xe2\x5e\xcf\xe5",
+ }, {
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .rlen = 32,
+ .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+ "\x20\x47\x61\x75\x27\x73\x20\x43",
+ .ilen = 32,
+ .input = "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+ "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+ "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+ "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
+ }, {
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .rlen = 47,
+ .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+ "\x20\x47\x61\x75\x27\x73\x20\x43"
+ "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+ "\x70\x6c\x65\x61\x73\x65\x2c",
+ .ilen = 47,
+ .input = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+ "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c"
+ "\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+ "\xbe\x7f\xcb\xcc\x98\xeb\xf5",
+ }, {
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .rlen = 48,
+ .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+ "\x20\x47\x61\x75\x27\x73\x20\x43"
+ "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+ "\x70\x6c\x65\x61\x73\x65\x2c\x20",
+ .ilen = 48,
+ .input = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+ "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+ "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+ "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
+ }, {
+ .klen = 16,
+ .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+ "\x74\x65\x72\x69\x79\x61\x6b\x69",
+ .rlen = 64,
+ .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+ "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+ "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+ "\x20\x47\x61\x75\x27\x73\x20\x43"
+ "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+ "\x70\x6c\x65\x61\x73\x65\x2c\x20"
+ "\x61\x6e\x64\x20\x77\x6f\x6e\x74"
+ "\x6f\x6e\x20\x73\x6f\x75\x70\x2e",
+ .ilen = 64,
+ .input = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+ "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+ "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+ "\x48\x07\xef\xe8\x36\xee\x89\xa5"
+ "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
+ "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+ "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
+ }
+};
+
+/*
+ * Compression stuff.
+ */
+#define COMP_BUF_SIZE 512
+
+struct comp_testvec {
+ int inlen, outlen;
+ char input[COMP_BUF_SIZE];
+ char output[COMP_BUF_SIZE];
+};
+
+struct pcomp_testvec {
+ void *params;
+ unsigned int paramsize;
+ int inlen, outlen;
+ char input[COMP_BUF_SIZE];
+ char output[COMP_BUF_SIZE];
+};
+
+/*
+ * Deflate test vectors (null-terminated strings).
+ * Params: winbits=-11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL.
+ */
+
+#define DEFLATE_COMP_TEST_VECTORS 2
+#define DEFLATE_DECOMP_TEST_VECTORS 2
+
+static struct comp_testvec deflate_comp_tv_template[] = {
+ {
+ .inlen = 70,
+ .outlen = 38,
+ .input = "Join us now and share the software "
+ "Join us now and share the software ",
+ .output = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+ "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+ "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+ "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+ "\x71\xbc\x08\x2b\x01\x00",
+ }, {
+ .inlen = 191,
+ .outlen = 122,
+ .input = "This document describes a compression method based on the DEFLATE"
+ "compression algorithm. This document defines the application of "
+ "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+ .output = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+ "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+ "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+ "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+ "\x68\x12\x51\xae\x76\x67\xd6\x27"
+ "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+ "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+ "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+ "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+ "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+ "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+ "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+ "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+ "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+ "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+ "\xfa\x02",
+ },
+};
+
+static struct comp_testvec deflate_decomp_tv_template[] = {
+ {
+ .inlen = 122,
+ .outlen = 191,
+ .input = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+ "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+ "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+ "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+ "\x68\x12\x51\xae\x76\x67\xd6\x27"
+ "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+ "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+ "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+ "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+ "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+ "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+ "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+ "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+ "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+ "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+ "\xfa\x02",
+ .output = "This document describes a compression method based on the DEFLATE"
+ "compression algorithm. This document defines the application of "
+ "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+ }, {
+ .inlen = 38,
+ .outlen = 70,
+ .input = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+ "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+ "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+ "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+ "\x71\xbc\x08\x2b\x01\x00",
+ .output = "Join us now and share the software "
+ "Join us now and share the software ",
+ },
+};
+
+#define ZLIB_COMP_TEST_VECTORS 2
+#define ZLIB_DECOMP_TEST_VECTORS 2
+
+static const struct {
+ struct nlattr nla;
+ int val;
+} deflate_comp_params[] = {
+ {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_COMP_LEVEL,
+ },
+ .val = Z_DEFAULT_COMPRESSION,
+ }, {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_COMP_METHOD,
+ },
+ .val = Z_DEFLATED,
+ }, {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_COMP_WINDOWBITS,
+ },
+ .val = -11,
+ }, {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_COMP_MEMLEVEL,
+ },
+ .val = MAX_MEM_LEVEL,
+ }, {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_COMP_STRATEGY,
+ },
+ .val = Z_DEFAULT_STRATEGY,
+ }
+};
+
+static const struct {
+ struct nlattr nla;
+ int val;
+} deflate_decomp_params[] = {
+ {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_DECOMP_WINDOWBITS,
+ },
+ .val = -11,
+ }
+};
+
+static struct pcomp_testvec zlib_comp_tv_template[] = {
+ {
+ .params = &deflate_comp_params,
+ .paramsize = sizeof(deflate_comp_params),
+ .inlen = 70,
+ .outlen = 38,
+ .input = "Join us now and share the software "
+ "Join us now and share the software ",
+ .output = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+ "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+ "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+ "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+ "\x71\xbc\x08\x2b\x01\x00",
+ }, {
+ .params = &deflate_comp_params,
+ .paramsize = sizeof(deflate_comp_params),
+ .inlen = 191,
+ .outlen = 122,
+ .input = "This document describes a compression method based on the DEFLATE"
+ "compression algorithm. This document defines the application of "
+ "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+ .output = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+ "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+ "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+ "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+ "\x68\x12\x51\xae\x76\x67\xd6\x27"
+ "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+ "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+ "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+ "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+ "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+ "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+ "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+ "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+ "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+ "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+ "\xfa\x02",
+ },
+};
+
+static struct pcomp_testvec zlib_decomp_tv_template[] = {
+ {
+ .params = &deflate_decomp_params,
+ .paramsize = sizeof(deflate_decomp_params),
+ .inlen = 122,
+ .outlen = 191,
+ .input = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+ "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+ "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+ "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+ "\x68\x12\x51\xae\x76\x67\xd6\x27"
+ "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+ "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+ "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+ "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+ "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+ "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+ "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+ "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+ "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+ "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+ "\xfa\x02",
+ .output = "This document describes a compression method based on the DEFLATE"
+ "compression algorithm. This document defines the application of "
+ "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+ }, {
+ .params = &deflate_decomp_params,
+ .paramsize = sizeof(deflate_decomp_params),
+ .inlen = 38,
+ .outlen = 70,
+ .input = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+ "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+ "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+ "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+ "\x71\xbc\x08\x2b\x01\x00",
+ .output = "Join us now and share the software "
+ "Join us now and share the software ",
+ },
+};
+
+/*
+ * LZO test vectors (null-terminated strings).
+ */
+#define LZO_COMP_TEST_VECTORS 2
+#define LZO_DECOMP_TEST_VECTORS 2
+
+static struct comp_testvec lzo_comp_tv_template[] = {
+ {
+ .inlen = 70,
+ .outlen = 46,
+ .input = "Join us now and share the software "
+ "Join us now and share the software ",
+ .output = "\x00\x0d\x4a\x6f\x69\x6e\x20\x75"
+ "\x73\x20\x6e\x6f\x77\x20\x61\x6e"
+ "\x64\x20\x73\x68\x61\x72\x65\x20"
+ "\x74\x68\x65\x20\x73\x6f\x66\x74"
+ "\x77\x70\x01\x01\x4a\x6f\x69\x6e"
+ "\x3d\x88\x00\x11\x00\x00",
+ }, {
+ .inlen = 159,
+ .outlen = 133,
+ .input = "This document describes a compression method based on the LZO "
+ "compression algorithm. This document defines the application of "
+ "the LZO algorithm used in UBIFS.",
+ .output = "\x00\x2b\x54\x68\x69\x73\x20\x64"
+ "\x6f\x63\x75\x6d\x65\x6e\x74\x20"
+ "\x64\x65\x73\x63\x72\x69\x62\x65"
+ "\x73\x20\x61\x20\x63\x6f\x6d\x70"
+ "\x72\x65\x73\x73\x69\x6f\x6e\x20"
+ "\x6d\x65\x74\x68\x6f\x64\x20\x62"
+ "\x61\x73\x65\x64\x20\x6f\x6e\x20"
+ "\x74\x68\x65\x20\x4c\x5a\x4f\x2b"
+ "\x8c\x00\x0d\x61\x6c\x67\x6f\x72"
+ "\x69\x74\x68\x6d\x2e\x20\x20\x54"
+ "\x68\x69\x73\x2a\x54\x01\x02\x66"
+ "\x69\x6e\x65\x73\x94\x06\x05\x61"
+ "\x70\x70\x6c\x69\x63\x61\x74\x76"
+ "\x0a\x6f\x66\x88\x02\x60\x09\x27"
+ "\xf0\x00\x0c\x20\x75\x73\x65\x64"
+ "\x20\x69\x6e\x20\x55\x42\x49\x46"
+ "\x53\x2e\x11\x00\x00",
+ },
+};
+
+static struct comp_testvec lzo_decomp_tv_template[] = {
+ {
+ .inlen = 133,
+ .outlen = 159,
+ .input = "\x00\x2b\x54\x68\x69\x73\x20\x64"
+ "\x6f\x63\x75\x6d\x65\x6e\x74\x20"
+ "\x64\x65\x73\x63\x72\x69\x62\x65"
+ "\x73\x20\x61\x20\x63\x6f\x6d\x70"
+ "\x72\x65\x73\x73\x69\x6f\x6e\x20"
+ "\x6d\x65\x74\x68\x6f\x64\x20\x62"
+ "\x61\x73\x65\x64\x20\x6f\x6e\x20"
+ "\x74\x68\x65\x20\x4c\x5a\x4f\x2b"
+ "\x8c\x00\x0d\x61\x6c\x67\x6f\x72"
+ "\x69\x74\x68\x6d\x2e\x20\x20\x54"
+ "\x68\x69\x73\x2a\x54\x01\x02\x66"
+ "\x69\x6e\x65\x73\x94\x06\x05\x61"
+ "\x70\x70\x6c\x69\x63\x61\x74\x76"
+ "\x0a\x6f\x66\x88\x02\x60\x09\x27"
+ "\xf0\x00\x0c\x20\x75\x73\x65\x64"
+ "\x20\x69\x6e\x20\x55\x42\x49\x46"
+ "\x53\x2e\x11\x00\x00",
+ .output = "This document describes a compression method based on the LZO "
+ "compression algorithm. This document defines the application of "
+ "the LZO algorithm used in UBIFS.",
+ }, {
+ .inlen = 46,
+ .outlen = 70,
+ .input = "\x00\x0d\x4a\x6f\x69\x6e\x20\x75"
+ "\x73\x20\x6e\x6f\x77\x20\x61\x6e"
+ "\x64\x20\x73\x68\x61\x72\x65\x20"
+ "\x74\x68\x65\x20\x73\x6f\x66\x74"
+ "\x77\x70\x01\x01\x4a\x6f\x69\x6e"
+ "\x3d\x88\x00\x11\x00\x00",
+ .output = "Join us now and share the software "
+ "Join us now and share the software ",
+ },
+};
+
+/*
+ * Michael MIC test vectors from IEEE 802.11i
+ */
+#define MICHAEL_MIC_TEST_VECTORS 6
+
+static struct hash_testvec michael_mic_tv_template[] = {
+ {
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ksize = 8,
+ .plaintext = zeroed_string,
+ .psize = 0,
+ .digest = "\x82\x92\x5c\x1c\xa1\xd1\x30\xb8",
+ },
+ {
+ .key = "\x82\x92\x5c\x1c\xa1\xd1\x30\xb8",
+ .ksize = 8,
+ .plaintext = "M",
+ .psize = 1,
+ .digest = "\x43\x47\x21\xca\x40\x63\x9b\x3f",
+ },
+ {
+ .key = "\x43\x47\x21\xca\x40\x63\x9b\x3f",
+ .ksize = 8,
+ .plaintext = "Mi",
+ .psize = 2,
+ .digest = "\xe8\xf9\xbe\xca\xe9\x7e\x5d\x29",
+ },
+ {
+ .key = "\xe8\xf9\xbe\xca\xe9\x7e\x5d\x29",
+ .ksize = 8,
+ .plaintext = "Mic",
+ .psize = 3,
+ .digest = "\x90\x03\x8f\xc6\xcf\x13\xc1\xdb",
+ },
+ {
+ .key = "\x90\x03\x8f\xc6\xcf\x13\xc1\xdb",
+ .ksize = 8,
+ .plaintext = "Mich",
+ .psize = 4,
+ .digest = "\xd5\x5e\x10\x05\x10\x12\x89\x86",
+ },
+ {
+ .key = "\xd5\x5e\x10\x05\x10\x12\x89\x86",
+ .ksize = 8,
+ .plaintext = "Michael",
+ .psize = 7,
+ .digest = "\x0a\x94\x2b\x12\x4e\xca\xa5\x46",
+ }
+};
+
+/*
+ * CRC32C test vectors
+ */
+#define CRC32C_TEST_VECTORS 14
+
+static struct hash_testvec crc32c_tv_template[] = {
+ {
+ .psize = 0,
+ .digest = "\x00\x00\x00\x00",
+ },
+ {
+ .key = "\x87\xa9\xcb\xed",
+ .ksize = 4,
+ .psize = 0,
+ .digest = "\x78\x56\x34\x12",
+ },
+ {
+ .key = "\xff\xff\xff\xff",
+ .ksize = 4,
+ .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18"
+ "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+ "\x21\x22\x23\x24\x25\x26\x27\x28",
+ .psize = 40,
+ .digest = "\x7f\x15\x2c\x0e",
+ },
+ {
+ .key = "\xff\xff\xff\xff",
+ .ksize = 4,
+ .plaintext = "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+ "\x31\x32\x33\x34\x35\x36\x37\x38"
+ "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+ "\x41\x42\x43\x44\x45\x46\x47\x48"
+ "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50",
+ .psize = 40,
+ .digest = "\xf6\xeb\x80\xe9",
+ },
+ {
+ .key = "\xff\xff\xff\xff",
+ .ksize = 4,
+ .plaintext = "\x51\x52\x53\x54\x55\x56\x57\x58"
+ "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+ "\x61\x62\x63\x64\x65\x66\x67\x68"
+ "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74\x75\x76\x77\x78",
+ .psize = 40,
+ .digest = "\xed\xbd\x74\xde",
+ },
+ {
+ .key = "\xff\xff\xff\xff",
+ .ksize = 4,
+ .plaintext = "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+ "\x81\x82\x83\x84\x85\x86\x87\x88"
+ "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+ "\x91\x92\x93\x94\x95\x96\x97\x98"
+ "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0",
+ .psize = 40,
+ .digest = "\x62\xc8\x79\xd5",
+ },
+ {
+ .key = "\xff\xff\xff\xff",
+ .ksize = 4,
+ .plaintext = "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+ "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+ "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+ "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+ "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8",
+ .psize = 40,
+ .digest = "\xd0\x9a\x97\xba",
+ },
+ {
+ .key = "\xff\xff\xff\xff",
+ .ksize = 4,
+ .plaintext = "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+ "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+ "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+ "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+ "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+ .psize = 40,
+ .digest = "\x13\xd9\x29\x2b",
+ },
+ {
+ .key = "\x80\xea\xd3\xf1",
+ .ksize = 4,
+ .plaintext = "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+ "\x31\x32\x33\x34\x35\x36\x37\x38"
+ "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+ "\x41\x42\x43\x44\x45\x46\x47\x48"
+ "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50",
+ .psize = 40,
+ .digest = "\x0c\xb5\xe2\xa2",
+ },
+ {
+ .key = "\xf3\x4a\x1d\x5d",
+ .ksize = 4,
+ .plaintext = "\x51\x52\x53\x54\x55\x56\x57\x58"
+ "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+ "\x61\x62\x63\x64\x65\x66\x67\x68"
+ "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74\x75\x76\x77\x78",
+ .psize = 40,
+ .digest = "\xd1\x7f\xfb\xa6",
+ },
+ {
+ .key = "\x2e\x80\x04\x59",
+ .ksize = 4,
+ .plaintext = "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+ "\x81\x82\x83\x84\x85\x86\x87\x88"
+ "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+ "\x91\x92\x93\x94\x95\x96\x97\x98"
+ "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0",
+ .psize = 40,
+ .digest = "\x59\x33\xe6\x7a",
+ },
+ {
+ .key = "\xa6\xcc\x19\x85",
+ .ksize = 4,
+ .plaintext = "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+ "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+ "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+ "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+ "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8",
+ .psize = 40,
+ .digest = "\xbe\x03\x01\xd2",
+ },
+ {
+ .key = "\x41\xfc\xfe\x2d",
+ .ksize = 4,
+ .plaintext = "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+ "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+ "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+ "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+ "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+ .psize = 40,
+ .digest = "\x75\xd3\xc5\x24",
+ },
+ {
+ .key = "\xff\xff\xff\xff",
+ .ksize = 4,
+ .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18"
+ "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+ "\x21\x22\x23\x24\x25\x26\x27\x28"
+ "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+ "\x31\x32\x33\x34\x35\x36\x37\x38"
+ "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+ "\x41\x42\x43\x44\x45\x46\x47\x48"
+ "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
+ "\x51\x52\x53\x54\x55\x56\x57\x58"
+ "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+ "\x61\x62\x63\x64\x65\x66\x67\x68"
+ "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74\x75\x76\x77\x78"
+ "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+ "\x81\x82\x83\x84\x85\x86\x87\x88"
+ "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+ "\x91\x92\x93\x94\x95\x96\x97\x98"
+ "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
+ "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+ "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+ "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+ "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+ "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8"
+ "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+ "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+ "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+ "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+ "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+ .psize = 240,
+ .digest = "\x75\xd3\xc5\x24",
+ .np = 2,
+ .tap = { 31, 209 }
+ },
+};
+
+#endif /* _IFXMIPS_CRYPTO_TESTMGR_H */
diff --git a/package/kernel/lantiq/ltq-deu/src/internal.h b/package/kernel/lantiq/ltq-deu/src/internal.h
new file mode 100644
index 0000000000..2d226362e5
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/internal.h
@@ -0,0 +1,141 @@
+/*
+ * Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program is free software; 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 _CRYPTO_INTERNAL_H
+#define _CRYPTO_INTERNAL_H
+
+#include <crypto/algapi.h>
+#include <linux/completion.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+#include <linux/fips.h>
+
+/* Crypto notification events. */
+enum {
+ CRYPTO_MSG_ALG_REQUEST,
+ CRYPTO_MSG_ALG_REGISTER,
+ CRYPTO_MSG_ALG_UNREGISTER,
+ CRYPTO_MSG_TMPL_REGISTER,
+ CRYPTO_MSG_TMPL_UNREGISTER,
+};
+
+struct crypto_instance;
+struct crypto_template;
+
+struct crypto_larval {
+ struct crypto_alg alg;
+ struct crypto_alg *adult;
+ struct completion completion;
+ u32 mask;
+};
+
+extern struct list_head crypto_alg_list;
+extern struct rw_semaphore crypto_alg_sem;
+extern struct blocking_notifier_head crypto_chain;
+
+#ifdef CONFIG_PROC_FS
+void __init crypto_init_proc(void);
+void __exit crypto_exit_proc(void);
+#else
+static inline void crypto_init_proc(void)
+{ }
+static inline void crypto_exit_proc(void)
+{ }
+#endif
+
+static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg)
+{
+ return alg->cra_ctxsize;
+}
+
+static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg)
+{
+ return alg->cra_ctxsize;
+}
+
+struct crypto_alg *crypto_mod_get(struct crypto_alg *alg);
+struct crypto_alg *crypto_alg_lookup(const char *name, u32 type, u32 mask);
+struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);
+
+int crypto_init_cipher_ops(struct crypto_tfm *tfm);
+int crypto_init_compress_ops(struct crypto_tfm *tfm);
+
+void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
+void crypto_exit_compress_ops(struct crypto_tfm *tfm);
+
+struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask);
+void crypto_larval_kill(struct crypto_alg *alg);
+struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask);
+void crypto_larval_error(const char *name, u32 type, u32 mask);
+void crypto_alg_tested(const char *name, int err);
+
+void crypto_shoot_alg(struct crypto_alg *alg);
+struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
+ u32 mask);
+void *crypto_create_tfm(struct crypto_alg *alg,
+ const struct crypto_type *frontend);
+struct crypto_alg *crypto_find_alg(const char *alg_name,
+ const struct crypto_type *frontend,
+ u32 type, u32 mask);
+void *crypto_alloc_tfm(const char *alg_name,
+ const struct crypto_type *frontend, u32 type, u32 mask);
+
+int crypto_register_notifier(struct notifier_block *nb);
+int crypto_unregister_notifier(struct notifier_block *nb);
+int crypto_probing_notify(unsigned long val, void *v);
+
+static inline void crypto_alg_put(struct crypto_alg *alg)
+{
+ if (atomic_dec_and_test(&alg->cra_refcnt) && alg->cra_destroy)
+ alg->cra_destroy(alg);
+}
+
+static inline int crypto_tmpl_get(struct crypto_template *tmpl)
+{
+ return try_module_get(tmpl->module);
+}
+
+static inline void crypto_tmpl_put(struct crypto_template *tmpl)
+{
+ module_put(tmpl->module);
+}
+
+static inline int crypto_is_larval(struct crypto_alg *alg)
+{
+ return alg->cra_flags & CRYPTO_ALG_LARVAL;
+}
+
+static inline int crypto_is_dead(struct crypto_alg *alg)
+{
+ return alg->cra_flags & CRYPTO_ALG_DEAD;
+}
+
+static inline int crypto_is_moribund(struct crypto_alg *alg)
+{
+ return alg->cra_flags & (CRYPTO_ALG_DEAD | CRYPTO_ALG_DYING);
+}
+
+static inline void crypto_notify(unsigned long val, void *v)
+{
+ blocking_notifier_call_chain(&crypto_chain, val, v);
+}
+
+#endif /* _CRYPTO_INTERNAL_H */
+
diff --git a/package/kernel/lantiq/ltq-deu/src/ltq_deu_testmgr.c b/package/kernel/lantiq/ltq-deu/src/ltq_deu_testmgr.c
new file mode 100644
index 0000000000..f1b57525d0
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ltq_deu_testmgr.c
@@ -0,0 +1,3957 @@
+/*
+ * Algorithm testing framework and tests.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) 2007 Nokia Siemens Networks
+ * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program is free software; 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 <crypto/hash.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <crypto/rng.h>
+#include <linux/jiffies.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+
+#include "internal.h"
+#include "ifxmips_testmgr.h"
+#include "ifxmips_tcrypt.h"
+#include "ifxmips_deu.h"
+
+/* changes for LQ ablkcipher speedtest */
+#include <linux/timex.h>
+#include <linux/interrupt.h>
+#include <asm/mipsregs.h>
+
+/*
+ * Need slab memory for testing (size in number of pages).
+ */
+#define XBUFSIZE 8
+
+/*
+ * Indexes into the xbuf to simulate cross-page access.
+ */
+#define IDX1 32
+#define IDX2 32400
+#define IDX3 1
+#define IDX4 8193
+#define IDX5 22222
+#define IDX6 17101
+#define IDX7 27333
+#define IDX8 3000
+
+/*
+* Used by test_cipher()
+*/
+#define ENCRYPT 1
+#define DECRYPT 0
+
+/*
+ * Need slab memory for testing (size in number of pages).
+ */
+#define TVMEMSIZE 4
+
+/*
+* Used by test_cipher_speed()
+*/
+#define ENCRYPT 1
+#define DECRYPT 0
+
+/*
+ * Used by test_cipher_speed()
+ */
+
+
+static unsigned int sec;
+
+static char *alg = NULL;
+static u32 type;
+static u32 mask;
+static int mode;
+static char *tvmem[TVMEMSIZE];
+
+static char *check[] = {
+ "des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256",
+ "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes",
+ "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
+ "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt",
+ "camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320",
+ "lzo", "cts", "zlib", NULL
+};
+struct tcrypt_result {
+ struct completion completion;
+ int err;
+};
+
+struct aead_test_suite {
+ struct {
+ struct aead_testvec *vecs;
+ unsigned int count;
+ } enc, dec;
+};
+
+struct cipher_test_suite {
+ struct {
+ struct cipher_testvec *vecs;
+ unsigned int count;
+ } enc, dec;
+};
+
+struct comp_test_suite {
+ struct {
+ struct comp_testvec *vecs;
+ unsigned int count;
+ } comp, decomp;
+};
+
+struct pcomp_test_suite {
+ struct {
+ struct pcomp_testvec *vecs;
+ unsigned int count;
+ } comp, decomp;
+};
+
+struct hash_test_suite {
+ struct hash_testvec *vecs;
+ unsigned int count;
+};
+
+struct cprng_test_suite {
+ struct cprng_testvec *vecs;
+ unsigned int count;
+};
+
+struct alg_test_desc {
+ const char *alg;
+ int (*test)(const struct alg_test_desc *desc, const char *driver,
+ u32 type, u32 mask);
+ int fips_allowed; /* set if alg is allowed in fips mode */
+
+ union {
+ struct aead_test_suite aead;
+ struct cipher_test_suite cipher;
+ struct comp_test_suite comp;
+ struct pcomp_test_suite pcomp;
+ struct hash_test_suite hash;
+ struct cprng_test_suite cprng;
+ } suite;
+};
+
+static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
+
+static void hexdump(unsigned char *buf, unsigned int len)
+{
+ print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
+ 16, 1,
+ buf, len, false);
+}
+
+static void tcrypt_complete(struct crypto_async_request *req, int err)
+{
+ struct tcrypt_result *res = req->data;
+
+ //printk("Signal done test\n");
+
+ if (err == -EINPROGRESS) {
+ printk("********************* Completion didnt go too well **************************** \n");
+ return;
+ }
+
+ res->err = err;
+ complete_all(&res->completion);
+}
+
+static int testmgr_alloc_buf(char *buf[XBUFSIZE])
+{
+ int i;
+
+ for (i = 0; i < XBUFSIZE; i++) {
+ buf[i] = (void *)__get_free_page(GFP_KERNEL);
+ if (!buf[i])
+ goto err_free_buf;
+ }
+
+ return 0;
+
+err_free_buf:
+ while (i-- > 0)
+ free_page((unsigned long)buf[i]);
+
+ return -ENOMEM;
+}
+
+static void testmgr_free_buf(char *buf[XBUFSIZE])
+{
+ int i;
+
+ for (i = 0; i < XBUFSIZE; i++)
+ free_page((unsigned long)buf[i]);
+}
+
+static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
+ unsigned int tcount)
+{
+ const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
+ unsigned int i, j, k, temp;
+ struct scatterlist sg[8];
+ char result[64];
+ struct ahash_request *req;
+ struct tcrypt_result tresult;
+ void *hash_buff;
+ char *xbuf[XBUFSIZE];
+ int ret = -ENOMEM;
+
+ if (testmgr_alloc_buf(xbuf))
+ goto out_nobuf;
+
+ init_completion(&tresult.completion);
+
+ req = ahash_request_alloc(tfm, GFP_KERNEL);
+ if (!req) {
+ printk(KERN_ERR "alg: hash: Failed to allocate request for "
+ "%s\n", algo);
+ goto out_noreq;
+ }
+ ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, &tresult);
+
+ j = 0;
+ for (i = 0; i < tcount; i++) {
+ if (template[i].np)
+ continue;
+
+ j++;
+ memset(result, 0, 64);
+
+ hash_buff = xbuf[0];
+
+ memcpy(hash_buff, template[i].plaintext, template[i].psize);
+ sg_init_one(&sg[0], hash_buff, template[i].psize);
+
+ if (template[i].ksize) {
+ crypto_ahash_clear_flags(tfm, ~0);
+ ret = crypto_ahash_setkey(tfm, template[i].key,
+ template[i].ksize);
+ if (ret) {
+ printk(KERN_ERR "alg: hash: setkey failed on "
+ "test %d for %s: ret=%d\n", j, algo,
+ -ret);
+ goto out;
+ }
+ }
+
+ ahash_request_set_crypt(req, sg, result, template[i].psize);
+ ret = crypto_ahash_digest(req);
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &tresult.completion);
+ if (!ret && !(ret = tresult.err)) {
+ INIT_COMPLETION(tresult.completion);
+ break;
+ }
+ /* fall through */
+ default:
+ printk(KERN_ERR "alg: hash: digest failed on test %d "
+ "for %s: ret=%d\n", j, algo, -ret);
+ goto out;
+ }
+
+ if (memcmp(result, template[i].digest,
+ crypto_ahash_digestsize(tfm))) {
+ printk(KERN_ERR "alg: hash: Test %d failed for %s\n",
+ j, algo);
+ hexdump(result, crypto_ahash_digestsize(tfm));
+ ret = -EINVAL;
+ goto out;
+ }
+ else {
+ printk(KERN_ERR "alg: hash: Test %d passed for %s\n",
+ j, algo);
+ hexdump(result, crypto_ahash_digestsize(tfm));
+ }
+ }
+
+ j = 0;
+ for (i = 0; i < tcount; i++) {
+ if (template[i].np) {
+ j++;
+ memset(result, 0, 64);
+
+ temp = 0;
+ sg_init_table(sg, template[i].np);
+ ret = -EINVAL;
+ for (k = 0; k < template[i].np; k++) {
+ if (WARN_ON(offset_in_page(IDX[k]) +
+ template[i].tap[k] > PAGE_SIZE))
+ goto out;
+ sg_set_buf(&sg[k],
+ memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]),
+ template[i].plaintext + temp,
+ template[i].tap[k]),
+ template[i].tap[k]);
+ temp += template[i].tap[k];
+ }
+
+ if (template[i].ksize) {
+ crypto_ahash_clear_flags(tfm, ~0);
+ ret = crypto_ahash_setkey(tfm, template[i].key,
+ template[i].ksize);
+
+ if (ret) {
+ printk(KERN_ERR "alg: hash: setkey "
+ "failed on chunking test %d "
+ "for %s: ret=%d\n", j, algo,
+ -ret);
+ goto out;
+ }
+ }
+
+ ahash_request_set_crypt(req, sg, result,
+ template[i].psize);
+ ret = crypto_ahash_digest(req);
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &tresult.completion);
+ if (!ret && !(ret = tresult.err)) {
+ INIT_COMPLETION(tresult.completion);
+ break;
+ }
+ /* fall through */
+ default:
+ printk(KERN_ERR "alg: hash: digest failed "
+ "on chunking test %d for %s: "
+ "ret=%d\n", j, algo, -ret);
+ goto out;
+ }
+
+ if (memcmp(result, template[i].digest,
+ crypto_ahash_digestsize(tfm))) {
+ printk(KERN_ERR "alg: hash: Chunking test %d "
+ "failed for %s\n", j, algo);
+ hexdump(result, crypto_ahash_digestsize(tfm));
+ ret = -EINVAL;
+ goto out;
+ }
+ else {
+ printk(KERN_ERR "alg: hash: Chunking test %d "
+ "passed for %s\n", j, algo);
+ hexdump(result, crypto_ahash_digestsize(tfm));
+ }
+ }
+ }
+
+ ret = 0;
+
+out:
+ ahash_request_free(req);
+out_noreq:
+ testmgr_free_buf(xbuf);
+out_nobuf:
+ return ret;
+}
+
+static int test_aead(struct crypto_aead *tfm, int enc,
+ struct aead_testvec *template, unsigned int tcount)
+{
+ const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
+ unsigned int i, j, k, n, temp;
+ int ret = -ENOMEM;
+ char *q;
+ char *key;
+ struct aead_request *req;
+ struct scatterlist sg[8];
+ struct scatterlist asg[8];
+ const char *e;
+ struct tcrypt_result result;
+ unsigned int authsize;
+ void *input;
+ void *assoc;
+ char iv[MAX_IVLEN];
+ char *xbuf[XBUFSIZE];
+ char *axbuf[XBUFSIZE];
+
+ if (testmgr_alloc_buf(xbuf))
+ goto out_noxbuf;
+ if (testmgr_alloc_buf(axbuf))
+ goto out_noaxbuf;
+
+ if (enc == ENCRYPT)
+ e = "encryption";
+ else
+ e = "decryption";
+
+ init_completion(&result.completion);
+
+ req = aead_request_alloc(tfm, GFP_KERNEL);
+ if (!req) {
+ printk(KERN_ERR "alg: aead: Failed to allocate request for "
+ "%s\n", algo);
+ goto out;
+ }
+
+ aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, &result);
+
+ for (i = 0, j = 0; i < tcount; i++) {
+ if (!template[i].np) {
+ j++;
+
+ /* some tepmplates have no input data but they will
+ * touch input
+ */
+ input = xbuf[0];
+ assoc = axbuf[0];
+
+ ret = -EINVAL;
+ if (WARN_ON(template[i].ilen > PAGE_SIZE ||
+ template[i].alen > PAGE_SIZE))
+ goto out;
+
+ memcpy(input, template[i].input, template[i].ilen);
+ memcpy(assoc, template[i].assoc, template[i].alen);
+ if (template[i].iv)
+ memcpy(iv, template[i].iv, MAX_IVLEN);
+ else
+ memset(iv, 0, MAX_IVLEN);
+
+ crypto_aead_clear_flags(tfm, ~0);
+ if (template[i].wk)
+ crypto_aead_set_flags(
+ tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+ key = template[i].key;
+
+ ret = crypto_aead_setkey(tfm, key,
+ template[i].klen);
+ if (!ret == template[i].fail) {
+ printk(KERN_ERR "alg: aead: setkey failed on "
+ "test %d for %s: flags=%x\n", j, algo,
+ crypto_aead_get_flags(tfm));
+ goto out;
+ } else if (ret)
+ continue;
+
+ authsize = abs(template[i].rlen - template[i].ilen);
+ ret = crypto_aead_setauthsize(tfm, authsize);
+ if (ret) {
+ printk(KERN_ERR "alg: aead: Failed to set "
+ "authsize to %u on test %d for %s\n",
+ authsize, j, algo);
+ goto out;
+ }
+
+ sg_init_one(&sg[0], input,
+ template[i].ilen + (enc ? authsize : 0));
+
+ sg_init_one(&asg[0], assoc, template[i].alen);
+
+ aead_request_set_crypt(req, sg, sg,
+ template[i].ilen, iv);
+
+ aead_request_set_assoc(req, asg, template[i].alen);
+
+ ret = enc ?
+ crypto_aead_encrypt(req) :
+ crypto_aead_decrypt(req);
+
+ switch (ret) {
+ case 0:
+ if (template[i].novrfy) {
+ /* verification was supposed to fail */
+ printk(KERN_ERR "alg: aead: %s failed "
+ "on test %d for %s: ret was 0, "
+ "expected -EBADMSG\n",
+ e, j, algo);
+ /* so really, we got a bad message */
+ ret = -EBADMSG;
+ goto out;
+ }
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &result.completion);
+ if (!ret && !(ret = result.err)) {
+ INIT_COMPLETION(result.completion);
+ break;
+ }
+ case -EBADMSG:
+ if (template[i].novrfy)
+ /* verification failure was expected */
+ continue;
+ /* fall through */
+ default:
+ printk(KERN_ERR "alg: aead: %s failed on test "
+ "%d for %s: ret=%d\n", e, j, algo, -ret);
+ goto out;
+ }
+
+ q = input;
+ if (memcmp(q, template[i].result, template[i].rlen)) {
+ printk(KERN_ERR "alg: aead: Test %d failed on "
+ "%s for %s\n", j, e, algo);
+ hexdump(q, template[i].rlen);
+ ret = -EINVAL;
+ goto out;
+ }
+ else {
+ printk(KERN_ERR "alg: aead: Test %d passed on "
+ "%s for %s\n", j, e, algo);
+ hexdump(q, template[i].rlen);
+ }
+ }
+ }
+
+ for (i = 0, j = 0; i < tcount; i++) {
+ if (template[i].np) {
+ j++;
+
+ if (template[i].iv)
+ memcpy(iv, template[i].iv, MAX_IVLEN);
+ else
+ memset(iv, 0, MAX_IVLEN);
+
+ crypto_aead_clear_flags(tfm, ~0);
+ if (template[i].wk)
+ crypto_aead_set_flags(
+ tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+ key = template[i].key;
+
+ ret = crypto_aead_setkey(tfm, key, template[i].klen);
+ if (!ret == template[i].fail) {
+ printk(KERN_ERR "alg: aead: setkey failed on "
+ "chunk test %d for %s: flags=%x\n", j,
+ algo, crypto_aead_get_flags(tfm));
+ goto out;
+ } else if (ret)
+ continue;
+
+ authsize = abs(template[i].rlen - template[i].ilen);
+
+ ret = -EINVAL;
+ sg_init_table(sg, template[i].np);
+ for (k = 0, temp = 0; k < template[i].np; k++) {
+ if (WARN_ON(offset_in_page(IDX[k]) +
+ template[i].tap[k] > PAGE_SIZE))
+ goto out;
+
+ q = xbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]);
+
+ memcpy(q, template[i].input + temp,
+ template[i].tap[k]);
+
+ n = template[i].tap[k];
+ if (k == template[i].np - 1 && enc)
+ n += authsize;
+ if (offset_in_page(q) + n < PAGE_SIZE)
+ q[n] = 0;
+
+ sg_set_buf(&sg[k], q, template[i].tap[k]);
+ temp += template[i].tap[k];
+ }
+
+ ret = crypto_aead_setauthsize(tfm, authsize);
+ if (ret) {
+ printk(KERN_ERR "alg: aead: Failed to set "
+ "authsize to %u on chunk test %d for "
+ "%s\n", authsize, j, algo);
+ goto out;
+ }
+
+ if (enc) {
+ if (WARN_ON(sg[k - 1].offset +
+ sg[k - 1].length + authsize >
+ PAGE_SIZE)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ sg[k - 1].length += authsize;
+ }
+
+ sg_init_table(asg, template[i].anp);
+ ret = -EINVAL;
+ for (k = 0, temp = 0; k < template[i].anp; k++) {
+ if (WARN_ON(offset_in_page(IDX[k]) +
+ template[i].atap[k] > PAGE_SIZE))
+ goto out;
+ sg_set_buf(&asg[k],
+ memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]),
+ template[i].assoc + temp,
+ template[i].atap[k]),
+ template[i].atap[k]);
+ temp += template[i].atap[k];
+ }
+
+ aead_request_set_crypt(req, sg, sg,
+ template[i].ilen,
+ iv);
+
+ aead_request_set_assoc(req, asg, template[i].alen);
+
+ ret = enc ?
+ crypto_aead_encrypt(req) :
+ crypto_aead_decrypt(req);
+
+ switch (ret) {
+ case 0:
+ if (template[i].novrfy) {
+ /* verification was supposed to fail */
+ printk(KERN_ERR "alg: aead: %s failed "
+ "on chunk test %d for %s: ret "
+ "was 0, expected -EBADMSG\n",
+ e, j, algo);
+ /* so really, we got a bad message */
+ ret = -EBADMSG;
+ goto out;
+ }
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &result.completion);
+ if (!ret && !(ret = result.err)) {
+ INIT_COMPLETION(result.completion);
+ break;
+ }
+ case -EBADMSG:
+ if (template[i].novrfy)
+ /* verification failure was expected */
+ continue;
+ /* fall through */
+ default:
+ printk(KERN_ERR "alg: aead: %s failed on "
+ "chunk test %d for %s: ret=%d\n", e, j,
+ algo, -ret);
+ goto out;
+ }
+
+ ret = -EINVAL;
+ for (k = 0, temp = 0; k < template[i].np; k++) {
+ q = xbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]);
+
+ n = template[i].tap[k];
+ if (k == template[i].np - 1)
+ n += enc ? authsize : -authsize;
+
+ if (memcmp(q, template[i].result + temp, n)) {
+ printk(KERN_ERR "alg: aead: Chunk "
+ "test %d failed on %s at page "
+ "%u for %s\n", j, e, k, algo);
+ hexdump(q, n);
+ goto out;
+ }
+ else {
+ printk(KERN_ERR "alg: aead: Chunk "
+ "test %d passed on %s at page "
+ "%u for %s\n", j, e, k, algo);
+ hexdump(q, n);
+ }
+
+ q += n;
+ if (k == template[i].np - 1 && !enc) {
+ if (memcmp(q, template[i].input +
+ temp + n, authsize))
+ n = authsize;
+ else
+ n = 0;
+ } else {
+ for (n = 0; offset_in_page(q + n) &&
+ q[n]; n++)
+ ;
+ }
+ if (n) {
+ printk(KERN_ERR "alg: aead: Result "
+ "buffer corruption in chunk "
+ "test %d on %s at page %u for "
+ "%s: %u bytes:\n", j, e, k,
+ algo, n);
+ hexdump(q, n);
+ goto out;
+ }
+ temp += template[i].tap[k];
+ }
+ }
+ }
+
+ ret = 0;
+
+out:
+ aead_request_free(req);
+ testmgr_free_buf(axbuf);
+out_noaxbuf:
+ testmgr_free_buf(xbuf);
+out_noxbuf:
+ return ret;
+}
+
+static int test_cipher(struct crypto_cipher *tfm, int enc,
+ struct cipher_testvec *template, unsigned int tcount)
+{
+ const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
+ unsigned int i, j, k;
+ char *q;
+ const char *e;
+ void *data;
+ char *xbuf[XBUFSIZE];
+ int ret = -ENOMEM;
+
+ if (testmgr_alloc_buf(xbuf))
+ goto out_nobuf;
+
+ if (enc == ENCRYPT)
+ e = "encryption";
+ else
+ e = "decryption";
+
+ j = 0;
+ for (i = 0; i < tcount; i++) {
+ if (template[i].np)
+ continue;
+
+ j++;
+
+ ret = -EINVAL;
+ if (WARN_ON(template[i].ilen > PAGE_SIZE))
+ goto out;
+
+ data = xbuf[0];
+ memcpy(data, template[i].input, template[i].ilen);
+
+ crypto_cipher_clear_flags(tfm, ~0);
+ if (template[i].wk)
+ crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+ ret = crypto_cipher_setkey(tfm, template[i].key,
+ template[i].klen);
+ if (!ret == template[i].fail) {
+ printk(KERN_ERR "alg: cipher: setkey failed "
+ "on test %d for %s: flags=%x\n", j,
+ algo, crypto_cipher_get_flags(tfm));
+ goto out;
+ } else if (ret)
+ continue;
+
+ for (k = 0; k < template[i].ilen;
+ k += crypto_cipher_blocksize(tfm)) {
+ if (enc)
+ crypto_cipher_encrypt_one(tfm, data + k,
+ data + k);
+ else
+ crypto_cipher_decrypt_one(tfm, data + k,
+ data + k);
+ }
+
+ q = data;
+ if (memcmp(q, template[i].result, template[i].rlen)) {
+ printk(KERN_ERR "alg: cipher: Test %d failed "
+ "on %s for %s\n", j, e, algo);
+ hexdump(q, template[i].rlen);
+ ret = -EINVAL;
+ goto out;
+ }
+ else {
+ printk(KERN_ERR "alg: cipher: Test %d passed "
+ "on %s for %s\n", j, e, algo);
+ hexdump(q, template[i].rlen);
+ }
+ }
+
+ ret = 0;
+
+out:
+ testmgr_free_buf(xbuf);
+out_nobuf:
+ return ret;
+}
+
+static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
+ struct cipher_testvec *template, unsigned int tcount)
+{
+ const char *algo =
+ crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
+ unsigned int i, j, k, n, temp;
+ char *q;
+ struct ablkcipher_request *req;
+ struct scatterlist sg[8];
+ const char *e;
+ struct tcrypt_result result;
+ void *data;
+ char iv[MAX_IVLEN];
+ char *xbuf[XBUFSIZE];
+ int ret = -ENOMEM;
+
+ if (testmgr_alloc_buf(xbuf))
+ goto out_nobuf;
+
+ if (enc == ENCRYPT)
+ e = "encryption";
+ else
+ e = "decryption";
+
+ init_completion(&result.completion);
+
+ req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
+ if (!req) {
+ printk(KERN_ERR "alg: skcipher: Failed to allocate request "
+ "for %s\n", algo);
+ goto out;
+ }
+
+ //printk("tcount: %u\n", tcount);
+
+ ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, &result);
+
+ j = 0;
+ for (i = 0; i < tcount; i++) {
+ if (template[i].iv)
+ memcpy(iv, template[i].iv, MAX_IVLEN);
+ else
+ memset(iv, 0, MAX_IVLEN);
+
+ if (!(template[i].np)) {
+ //printk("np: %d, i: %d, j: %d\n", template[i].np, i, j);
+ j++;
+
+ ret = -EINVAL;
+ if (WARN_ON(template[i].ilen > PAGE_SIZE))
+ goto out;
+
+ data = xbuf[0];
+ memcpy(data, template[i].input, template[i].ilen);
+
+ crypto_ablkcipher_clear_flags(tfm, ~0);
+ if (template[i].wk)
+ crypto_ablkcipher_set_flags(
+ tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+ ret = crypto_ablkcipher_setkey(tfm, template[i].key,
+ template[i].klen);
+ if (!ret == template[i].fail) {
+ printk(KERN_ERR "alg: skcipher: setkey failed "
+ "on test %d for %s: flags=%x\n", j,
+ algo, crypto_ablkcipher_get_flags(tfm));
+ printk("ERROR\n");
+ goto out;
+ } else if (ret)
+ continue;
+
+ sg_init_one(&sg[0], data, template[i].ilen);
+
+ ablkcipher_request_set_crypt(req, sg, sg,
+ template[i].ilen, iv);
+ ret = enc ?
+ crypto_ablkcipher_encrypt(req) :
+ crypto_ablkcipher_decrypt(req);
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &result.completion);
+ if (!ret && !((ret = result.err))) {
+ INIT_COMPLETION(result.completion);
+ break;
+ }
+ /* fall through */
+ default:
+ printk(KERN_ERR "alg: skcipher: %s failed on "
+ "test %d for %s: ret=%d\n", e, j, algo,
+ -ret);
+ printk("ERROR\n");
+ goto out;
+ }
+ q = data;
+ if (memcmp(q, template[i].result, template[i].rlen)) {
+ printk(KERN_ERR "alg: skcipher: Test %d "
+ "failed on %s for %s\n", j, e, algo);
+ hexdump(q, template[i].rlen);
+ printk("ERROR\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ else {
+ printk(KERN_ERR "alg: skcipher: Test %d "
+ "*PASSED* on %s for %s\n", j, e, algo);
+ hexdump(q, template[i].rlen);
+ printk("DONE\n");
+ }
+ }
+ }
+ printk("Testing %s chunking across pages.\n", algo);
+ j = 0;
+ for (i = 0; i < tcount; i++) {
+ if (template[i].iv)
+ memcpy(iv, template[i].iv, MAX_IVLEN);
+ else
+ memset(iv, 0, MAX_IVLEN);
+
+ if (template[i].np) {
+ j++;
+
+ crypto_ablkcipher_clear_flags(tfm, ~0);
+ if (template[i].wk)
+ crypto_ablkcipher_set_flags(
+ tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+ ret = crypto_ablkcipher_setkey(tfm, template[i].key,
+ template[i].klen);
+ if (!ret == template[i].fail) {
+ printk(KERN_ERR "alg: skcipher: setkey failed "
+ "on chunk test %d for %s: flags=%x\n",
+ j, algo,
+ crypto_ablkcipher_get_flags(tfm));
+ printk("ERROR\n");
+ goto out;
+ } else if (ret)
+ continue;
+
+ temp = 0;
+ ret = -EINVAL;
+ sg_init_table(sg, template[i].np);
+ for (k = 0; k < template[i].np; k++) {
+ if (WARN_ON(offset_in_page(IDX[k]) +
+ template[i].tap[k] > PAGE_SIZE))
+ goto out;
+
+ q = xbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]);
+
+ memcpy(q, template[i].input + temp,
+ template[i].tap[k]);
+
+ if (offset_in_page(q) + template[i].tap[k] <
+ PAGE_SIZE)
+ q[template[i].tap[k]] = 0;
+
+ sg_set_buf(&sg[k], q, template[i].tap[k]);
+
+ temp += template[i].tap[k];
+ }
+
+ ablkcipher_request_set_crypt(req, sg, sg,
+ template[i].ilen, iv);
+
+ ret = enc ?
+ crypto_ablkcipher_encrypt(req) :
+ crypto_ablkcipher_decrypt(req);
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &result.completion);
+ if (!ret && !((ret = result.err))) {
+ INIT_COMPLETION(result.completion);
+ break;
+ }
+ /* fall through */
+ default:
+ printk(KERN_ERR "alg: skcipher: %s failed on "
+ "chunk test %d for %s: ret=%d\n", e, j,
+ algo, -ret);
+ printk("ERROR\n");
+ goto out;
+ }
+
+ temp = 0;
+ ret = -EINVAL;
+ for (k = 0; k < template[i].np; k++) {
+ q = xbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]);
+
+ if (memcmp(q, template[i].result + temp,
+ template[i].tap[k])) {
+ printk(KERN_ERR "alg: skcipher: Chunk "
+ "test %d failed on %s at page "
+ "%u for %s\n", j, e, k, algo);
+ hexdump(q, template[i].tap[k]);
+ printk("ERROR\n");
+ goto out;
+ }
+ else {
+ printk(KERN_ERR "alg: skcipher: Chunk "
+ "test %d *PASSED* on %s at page "
+ "%u for %s\n", j, e, k, algo);
+ hexdump(q, template[i].tap[k]);
+ printk("DONE\n");
+ }
+
+ q += template[i].tap[k];
+ for (n = 0; offset_in_page(q + n) && q[n]; n++)
+ ;
+#if 1
+ if (n) {
+ printk(KERN_ERR "alg: skcipher: "
+ "Result buffer corruption in "
+ "chunk test %d on %s at page "
+ "%u for %s: %u bytes:\n", j, e,
+ k, algo, n);
+ hexdump(q, n);
+ printk("ERROR\n");
+ goto out;
+ }
+ else {
+ printk(KERN_ERR "alg: skcipher: "
+ "Result buffer clean in "
+ "chunk test %d on %s at page "
+ "%u for %s: %u bytes:\n", j, e,
+ k, algo, n);
+ hexdump(q, n);
+ printk("Chunk Buffer clean\n");
+ }
+#endif
+ temp += template[i].tap[k];
+ }
+ }
+ }
+
+ ret = 0;
+out:
+ ablkcipher_request_free(req);
+ testmgr_free_buf(xbuf);
+out_nobuf:
+ return ret;
+}
+
+static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
+ struct comp_testvec *dtemplate, int ctcount, int dtcount)
+{
+ const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm));
+ unsigned int i;
+ char result[COMP_BUF_SIZE];
+ int ret;
+
+ for (i = 0; i < ctcount; i++) {
+ int ilen;
+ unsigned int dlen = COMP_BUF_SIZE;
+
+ memset(result, 0, sizeof (result));
+
+ ilen = ctemplate[i].inlen;
+ ret = crypto_comp_compress(tfm, ctemplate[i].input,
+ ilen, result, &dlen);
+ if (ret) {
+ printk(KERN_ERR "alg: comp: compression failed "
+ "on test %d for %s: ret=%d\n", i + 1, algo,
+ -ret);
+ goto out;
+ }
+
+ if (dlen != ctemplate[i].outlen) {
+ printk(KERN_ERR "alg: comp: Compression test %d "
+ "failed for %s: output len = %d\n", i + 1, algo,
+ dlen);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (memcmp(result, ctemplate[i].output, dlen)) {
+ printk(KERN_ERR "alg: comp: Compression test %d "
+ "failed for %s\n", i + 1, algo);
+ hexdump(result, dlen);
+ ret = -EINVAL;
+ goto out;
+ }
+ else {
+ printk(KERN_ERR "alg: comp: Compression test %d "
+ "passed for %s\n", i + 1, algo);
+ hexdump(result, dlen);
+ }
+ }
+
+ for (i = 0; i < dtcount; i++) {
+ int ilen;
+ unsigned int dlen = COMP_BUF_SIZE;
+
+ memset(result, 0, sizeof (result));
+
+ ilen = dtemplate[i].inlen;
+ ret = crypto_comp_decompress(tfm, dtemplate[i].input,
+ ilen, result, &dlen);
+ if (ret) {
+ printk(KERN_ERR "alg: comp: decompression failed "
+ "on test %d for %s: ret=%d\n", i + 1, algo,
+ -ret);
+ goto out;
+ }
+
+ if (dlen != dtemplate[i].outlen) {
+ printk(KERN_ERR "alg: comp: Decompression test %d "
+ "failed for %s: output len = %d\n", i + 1, algo,
+ dlen);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (memcmp(result, dtemplate[i].output, dlen)) {
+ printk(KERN_ERR "alg: comp: Decompression test %d "
+ "failed for %s\n", i + 1, algo);
+ hexdump(result, dlen);
+ ret = -EINVAL;
+ goto out;
+ }
+ else {
+ printk(KERN_ERR "alg: comp: Decompression test %d "
+ "passed for %s\n", i + 1, algo);
+ hexdump(result, dlen);
+ }
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int test_pcomp(struct crypto_pcomp *tfm,
+ struct pcomp_testvec *ctemplate,
+ struct pcomp_testvec *dtemplate, int ctcount,
+ int dtcount)
+{
+ const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
+ unsigned int i;
+ char result[COMP_BUF_SIZE];
+ int res;
+
+ for (i = 0; i < ctcount; i++) {
+ struct comp_request req;
+ unsigned int produced = 0;
+
+ res = crypto_compress_setup(tfm, ctemplate[i].params,
+ ctemplate[i].paramsize);
+ if (res) {
+ pr_err("alg: pcomp: compression setup failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, res);
+ return res;
+ }
+
+ res = crypto_compress_init(tfm);
+ if (res) {
+ pr_err("alg: pcomp: compression init failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, res);
+ return res;
+ }
+
+ memset(result, 0, sizeof(result));
+
+ req.next_in = ctemplate[i].input;
+ req.avail_in = ctemplate[i].inlen / 2;
+ req.next_out = result;
+ req.avail_out = ctemplate[i].outlen / 2;
+
+ res = crypto_compress_update(tfm, &req);
+ if (res < 0 && (res != -EAGAIN || req.avail_in)) {
+ pr_err("alg: pcomp: compression update failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, res);
+ return res;
+ }
+ if (res > 0)
+ produced += res;
+
+ /* Add remaining input data */
+ req.avail_in += (ctemplate[i].inlen + 1) / 2;
+
+ res = crypto_compress_update(tfm, &req);
+ if (res < 0 && (res != -EAGAIN || req.avail_in)) {
+ pr_err("alg: pcomp: compression update failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, res);
+ return res;
+ }
+ if (res > 0)
+ produced += res;
+
+ /* Provide remaining output space */
+ req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
+
+ res = crypto_compress_final(tfm, &req);
+ if (res < 0) {
+ pr_err("alg: pcomp: compression final failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, res);
+ return res;
+ }
+ produced += res;
+
+ if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
+ pr_err("alg: comp: Compression test %d failed for %s: "
+ "output len = %d (expected %d)\n", i + 1, algo,
+ COMP_BUF_SIZE - req.avail_out,
+ ctemplate[i].outlen);
+ return -EINVAL;
+ }
+
+ if (produced != ctemplate[i].outlen) {
+ pr_err("alg: comp: Compression test %d failed for %s: "
+ "returned len = %u (expected %d)\n", i + 1,
+ algo, produced, ctemplate[i].outlen);
+ return -EINVAL;
+ }
+
+ if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
+ pr_err("alg: pcomp: Compression test %d failed for "
+ "%s\n", i + 1, algo);
+ hexdump(result, ctemplate[i].outlen);
+ return -EINVAL;
+ }
+ }
+
+ for (i = 0; i < dtcount; i++) {
+ struct comp_request req;
+ unsigned int produced = 0;
+
+ res = crypto_decompress_setup(tfm, dtemplate[i].params,
+ dtemplate[i].paramsize);
+ if (res) {
+ pr_err("alg: pcomp: decompression setup failed on "
+ "test %d for %s: error=%d\n", i + 1, algo, res);
+ return res;
+ }
+
+ res = crypto_decompress_init(tfm);
+ if (res) {
+ pr_err("alg: pcomp: decompression init failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, res);
+ return res;
+ }
+
+ memset(result, 0, sizeof(result));
+
+ req.next_in = dtemplate[i].input;
+ req.avail_in = dtemplate[i].inlen / 2;
+ req.next_out = result;
+ req.avail_out = dtemplate[i].outlen / 2;
+
+ res = crypto_decompress_update(tfm, &req);
+ if (res < 0 && (res != -EAGAIN || req.avail_in)) {
+ pr_err("alg: pcomp: decompression update failed on "
+ "test %d for %s: error=%d\n", i + 1, algo, res);
+ return res;
+ }
+ if (res > 0)
+ produced += res;
+
+ /* Add remaining input data */
+ req.avail_in += (dtemplate[i].inlen + 1) / 2;
+
+ res = crypto_decompress_update(tfm, &req);
+ if (res < 0 && (res != -EAGAIN || req.avail_in)) {
+ pr_err("alg: pcomp: decompression update failed on "
+ "test %d for %s: error=%d\n", i + 1, algo, res);
+ return res;
+ }
+ if (res > 0)
+ produced += res;
+
+ /* Provide remaining output space */
+ req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
+
+ res = crypto_decompress_final(tfm, &req);
+ if (res < 0 && (res != -EAGAIN || req.avail_in)) {
+ pr_err("alg: pcomp: decompression final failed on "
+ "test %d for %s: error=%d\n", i + 1, algo, res);
+ return res;
+ }
+ if (res > 0)
+ produced += res;
+
+ if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
+ pr_err("alg: comp: Decompression test %d failed for "
+ "%s: output len = %d (expected %d)\n", i + 1,
+ algo, COMP_BUF_SIZE - req.avail_out,
+ dtemplate[i].outlen);
+ return -EINVAL;
+ }
+
+ if (produced != dtemplate[i].outlen) {
+ pr_err("alg: comp: Decompression test %d failed for "
+ "%s: returned len = %u (expected %d)\n", i + 1,
+ algo, produced, dtemplate[i].outlen);
+ return -EINVAL;
+ }
+
+ if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
+ pr_err("alg: pcomp: Decompression test %d failed for "
+ "%s\n", i + 1, algo);
+ hexdump(result, dtemplate[i].outlen);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int test_ablkcipher_jiffies(struct ablkcipher_request *req, int enc,
+ int sec, struct tcrypt_result *result,
+ int blen)
+{
+ unsigned long start, end;
+ int bcount;
+ int ret;
+
+ for (start = jiffies, end = start + sec * HZ, bcount = 0;
+ time_before(jiffies, end); bcount++) {
+
+ if (enc)
+ ret = crypto_ablkcipher_encrypt(req);
+ else
+ ret = crypto_ablkcipher_decrypt(req);
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &result->completion);
+ if (!ret && !((ret = result->err))) {
+ INIT_COMPLETION(result->completion);
+ break;
+ }
+ default:
+ printk("ERROR\n");
+ return ret;
+ }
+ }
+
+ printk("%d operations in %d seconds (%ld bytes)\n",
+ bcount, sec, (long)bcount * blen);
+
+ return 0;
+}
+
+static int test_ablkcipher_cycles(struct ablkcipher_request *req, int enc,
+ int sec, struct tcrypt_result *result,
+ int blen)
+{
+ unsigned long cycles = 0;
+ int ret = 0;
+ int i;
+ unsigned long start, end = 0;
+ //local_bh_disable();
+ //local_irq_disable();
+ /* Warm-up run. */
+ for (i = 0; i < 4; i++) {
+ if (enc)
+ ret = crypto_ablkcipher_encrypt(req);
+ else
+ ret = crypto_ablkcipher_decrypt(req);
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+#if 0
+ ret = wait_for_completion_interruptible(
+ &result->completion);
+ if (!ret && !((ret = result->err))) {
+ INIT_COMPLETION(result->completion);
+ break;
+ }
+#else
+
+ wait_for_completion(&result->completion);
+ INIT_COMPLETION(result->completion);
+ break;
+#endif
+ default:
+ printk("ERROR\n");
+ return ret;
+ }
+
+ if (signal_pending(current)) {
+ printk("Signal caught\n");
+ break;
+ }
+
+ }
+
+ //printk("Debug ln: (%d), fn: %s\n", __LINE__, __func__);
+ /* The real thing. */
+ for (i = 0; i < 8; i++) {
+ end = 0;
+ start = 0;
+ start = read_c0_count();
+ if (enc)
+ ret = crypto_ablkcipher_encrypt(req);
+ else
+ ret = crypto_ablkcipher_decrypt(req);
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+#if 0
+ ret = wait_for_completion_interruptible(
+ &result->completion);
+ end = get_cycles();
+ if (!ret && !((ret = result->err))) {
+ INIT_COMPLETION(result->completion);
+ break;
+ }
+#else
+ wait_for_completion(&result->completion);
+ end = read_c0_count();
+ INIT_COMPLETION(result->completion);
+ break;
+#endif
+ default:
+ printk("ERROR\n");
+ return ret;
+ }
+
+ if (signal_pending(current)) {
+ printk("Signal caught\n");
+ break;
+ }
+
+ cycles += end - start;
+ }
+
+ // local_irq_enable();
+ // local_bh_enable();
+
+ printk("1 operation in %lu cycles (%d bytes)\n",
+ (cycles + 4) / 8, blen);
+
+ return 0;
+
+}
+
+static u32 b_size[] = {16, 64, 256, 1024, 8192, 0};
+
+static int test_skcipher_speed(struct crypto_ablkcipher *tfm, int enc,
+ struct cipher_speed_template *template,
+ unsigned int tcount, unsigned int sec,
+ u8* keysize)
+{
+ const char *algo =
+ crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
+
+ unsigned int i = 0, j, iv_len;
+ struct ablkcipher_request *req;
+ //struct scatterlist sg[8];
+ const char *e;
+ struct tcrypt_result result;
+ char iv[MAX_IVLEN];
+ static char *xbuf[XBUFSIZE];
+ int ret = -ENOMEM;
+ u32 *block_size;
+ static char *tvmem_buf[4];
+ const char *key;
+
+ if (testmgr_alloc_buf(xbuf))
+ goto out_nobuf;
+
+ if (enc == ENCRYPT)
+ e = "encryption";
+ else
+ e = "decryption";
+
+ init_completion(&result.completion);
+
+ printk("Start ablkcipher speed test\n");
+
+ req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
+ if (!req) {
+ printk(KERN_ERR "alg: skcipher: Failed to allocate request "
+ "for %s\n", algo);
+ goto out;
+ }
+
+// ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ ablkcipher_request_set_callback(req, 0,
+ tcrypt_complete, &result);
+
+ do {
+
+ block_size = b_size;
+
+ do {
+ struct scatterlist sg[4];
+ if ((*keysize + *block_size) > 4 * PAGE_SIZE) {
+ printk("template (%u) too big for "
+ "tvmem_buf (%lu)\n", *keysize + *block_size,
+ 4 * PAGE_SIZE);
+ goto out;
+ }
+ crypto_ablkcipher_clear_flags(tfm, ~0);
+
+ printk("test %u (%d bit key, %d byte blocks): ", i,
+ *keysize * 8, *block_size);
+
+ memset(tvmem_buf[0], 0xff, PAGE_SIZE);
+ key = tvmem_buf[0];
+
+ for (j = 0; j < tcount; j++) {
+ if (template[j].klen == *keysize) {
+ key = template[j].key;
+ break;
+ }
+ }
+ ret = crypto_ablkcipher_setkey(tfm, key, *keysize);
+ if (ret) {
+ printk("Error setting of keys\n");
+ goto out;
+ }
+
+ sg_init_table(sg, 4);
+
+ for (j = 0; j < 4; j++) {
+ tvmem_buf[j] = xbuf[j];
+ memset(tvmem_buf[j], 0xff, PAGE_SIZE);
+ sg_set_buf(sg + j, tvmem_buf[j], PAGE_SIZE);
+ }
+
+ iv_len = crypto_ablkcipher_ivsize(tfm);
+ if (iv_len) {
+ memset(&iv, 0xff, iv_len);
+ }
+
+ ablkcipher_request_set_crypt(req, sg, sg,
+ *block_size, iv);
+
+ //printk("Debug ln: %d, %s\n", __LINE__, __func__);
+ if (sec)
+ ret = test_ablkcipher_jiffies(req, enc, sec,
+ &result, *block_size);
+ else
+ ret = test_ablkcipher_cycles(req, enc, sec,
+ &result, *block_size);
+
+
+ if (ret) {
+ printk(KERN_ERR "alg: skcipher: %s failed on "
+ "test %d for %s: ret=%d\n", e, j, algo,
+ -ret);
+ goto out;
+ }
+
+ block_size++;
+ i++;
+ } while (*block_size);
+ keysize++;
+ } while (*keysize);
+
+ ret = 0;
+out:
+ printk("End ablkcipher speed test\n");
+ ablkcipher_request_free(req);
+ testmgr_free_buf(xbuf);
+#if 0
+ if (!completion_done(&result->completion)) {
+ printk("There are threads waiting for completion, completing all\n");
+ complete_all(&result->completion);
+ }
+#endif
+
+ //testmgr_free_buf(tvbuf);
+out_nobuf:
+ return ret;
+
+}
+
+static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template,
+ unsigned int tcount)
+{
+ const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
+ int err = 0, i, j, seedsize;
+ u8 *seed;
+ char result[32];
+
+ seedsize = crypto_rng_seedsize(tfm);
+
+ seed = kmalloc(seedsize, GFP_KERNEL);
+ if (!seed) {
+ printk(KERN_ERR "alg: cprng: Failed to allocate seed space "
+ "for %s\n", algo);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < tcount; i++) {
+ memset(result, 0, 32);
+
+ memcpy(seed, template[i].v, template[i].vlen);
+ memcpy(seed + template[i].vlen, template[i].key,
+ template[i].klen);
+ memcpy(seed + template[i].vlen + template[i].klen,
+ template[i].dt, template[i].dtlen);
+
+ err = crypto_rng_reset(tfm, seed, seedsize);
+ if (err) {
+ printk(KERN_ERR "alg: cprng: Failed to reset rng "
+ "for %s\n", algo);
+ goto out;
+ }
+
+ for (j = 0; j < template[i].loops; j++) {
+ err = crypto_rng_get_bytes(tfm, result,
+ template[i].rlen);
+ if (err != template[i].rlen) {
+ printk(KERN_ERR "alg: cprng: Failed to obtain "
+ "the correct amount of random data for "
+ "%s (requested %d, got %d)\n", algo,
+ template[i].rlen, err);
+ goto out;
+ }
+ }
+
+ err = memcmp(result, template[i].result,
+ template[i].rlen);
+ if (err) {
+ printk(KERN_ERR "alg: cprng: Test %d failed for %s\n",
+ i, algo);
+ hexdump(result, template[i].rlen);
+ err = -EINVAL;
+ goto out;
+ }
+ }
+
+out:
+ kfree(seed);
+ return err;
+}
+
+static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
+ u32 type, u32 mask)
+{
+ struct crypto_aead *tfm;
+ int err = 0;
+
+ tfm = crypto_alloc_aead(driver, type, mask);
+ if (IS_ERR(tfm)) {
+ printk(KERN_ERR "alg: aead: Failed to load transform for %s: "
+ "%ld\n", driver, PTR_ERR(tfm));
+ return PTR_ERR(tfm);
+ }
+
+ if (desc->suite.aead.enc.vecs) {
+ err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs,
+ desc->suite.aead.enc.count);
+ if (err)
+ goto out;
+ }
+
+ if (!err && desc->suite.aead.dec.vecs)
+ err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs,
+ desc->suite.aead.dec.count);
+
+out:
+ crypto_free_aead(tfm);
+ return err;
+}
+
+static int alg_test_cipher(const struct alg_test_desc *desc,
+ const char *driver, u32 type, u32 mask)
+{
+ struct crypto_cipher *tfm;
+ int err = 0;
+
+ tfm = crypto_alloc_cipher(driver, type, mask);
+ if (IS_ERR(tfm)) {
+ printk(KERN_ERR "alg: cipher: Failed to load transform for "
+ "%s: %ld\n", driver, PTR_ERR(tfm));
+ return PTR_ERR(tfm);
+ }
+
+ if (desc->suite.cipher.enc.vecs) {
+ err = test_cipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
+ desc->suite.cipher.enc.count);
+ if (err)
+ goto out;
+ }
+
+ if (desc->suite.cipher.dec.vecs)
+ err = test_cipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
+ desc->suite.cipher.dec.count);
+
+out:
+ crypto_free_cipher(tfm);
+ return err;
+}
+
+static int alg_test_skcipher(const struct alg_test_desc *desc,
+ const char *driver, u32 type, u32 mask)
+{
+ struct crypto_ablkcipher *tfm;
+ int err = 0;
+
+ tfm = crypto_alloc_ablkcipher(driver, type, mask);
+ if (IS_ERR(tfm)) {
+ printk(KERN_ERR "alg: skcipher: Failed to load transform for "
+ "%s: %ld\n", driver, PTR_ERR(tfm));
+ return PTR_ERR(tfm);
+ }
+
+ if (desc->suite.cipher.enc.vecs) {
+ err = test_skcipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
+ desc->suite.cipher.enc.count);
+ if (err)
+ goto out;
+ }
+
+ if (desc->suite.cipher.dec.vecs)
+ err = test_skcipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
+ desc->suite.cipher.dec.count);
+
+out:
+ crypto_free_ablkcipher(tfm);
+ return err;
+}
+
+static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
+ u32 type, u32 mask)
+{
+ struct crypto_comp *tfm;
+ int err;
+
+ tfm = crypto_alloc_comp(driver, type, mask);
+ if (IS_ERR(tfm)) {
+ printk(KERN_ERR "alg: comp: Failed to load transform for %s: "
+ "%ld\n", driver, PTR_ERR(tfm));
+ return PTR_ERR(tfm);
+ }
+
+ err = test_comp(tfm, desc->suite.comp.comp.vecs,
+ desc->suite.comp.decomp.vecs,
+ desc->suite.comp.comp.count,
+ desc->suite.comp.decomp.count);
+
+ crypto_free_comp(tfm);
+ return err;
+}
+
+static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver,
+ u32 type, u32 mask)
+{
+ struct crypto_pcomp *tfm;
+ int err;
+
+ tfm = crypto_alloc_pcomp(driver, type, mask);
+ if (IS_ERR(tfm)) {
+ pr_err("alg: pcomp: Failed to load transform for %s: %ld\n",
+ driver, PTR_ERR(tfm));
+ return PTR_ERR(tfm);
+ }
+
+ err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs,
+ desc->suite.pcomp.decomp.vecs,
+ desc->suite.pcomp.comp.count,
+ desc->suite.pcomp.decomp.count);
+
+ crypto_free_pcomp(tfm);
+ return err;
+}
+
+static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
+ u32 type, u32 mask)
+{
+ struct crypto_ahash *tfm;
+ int err;
+
+ tfm = crypto_alloc_ahash(driver, type, mask);
+ if (IS_ERR(tfm)) {
+ printk(KERN_ERR "alg: hash: Failed to load transform for %s: "
+ "%ld\n", driver, PTR_ERR(tfm));
+ return PTR_ERR(tfm);
+ }
+
+ err = test_hash(tfm, desc->suite.hash.vecs, desc->suite.hash.count);
+
+ crypto_free_ahash(tfm);
+ return err;
+}
+
+static int alg_test_crc32c(const struct alg_test_desc *desc,
+ const char *driver, u32 type, u32 mask)
+{
+ struct crypto_shash *tfm;
+ u32 val;
+ int err;
+
+ err = alg_test_hash(desc, driver, type, mask);
+ if (err)
+ goto out;
+
+ tfm = crypto_alloc_shash(driver, type, mask);
+ if (IS_ERR(tfm)) {
+ printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: "
+ "%ld\n", driver, PTR_ERR(tfm));
+ err = PTR_ERR(tfm);
+ goto out;
+ }
+
+ do {
+ struct {
+ struct shash_desc shash;
+ char ctx[crypto_shash_descsize(tfm)];
+ } sdesc;
+
+ sdesc.shash.tfm = tfm;
+ sdesc.shash.flags = 0;
+
+ *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
+ err = crypto_shash_final(&sdesc.shash, (u8 *)&val);
+ if (err) {
+ printk(KERN_ERR "alg: crc32c: Operation failed for "
+ "%s: %d\n", driver, err);
+ break;
+ }
+
+ if (val != ~420553207) {
+ printk(KERN_ERR "alg: crc32c: Test failed for %s: "
+ "%d\n", driver, val);
+ err = -EINVAL;
+ }
+ } while (0);
+
+ crypto_free_shash(tfm);
+
+out:
+ return err;
+}
+
+static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
+ u32 type, u32 mask)
+{
+ struct crypto_rng *rng;
+ int err = 0;
+
+ rng = crypto_alloc_rng(driver, type, mask);
+ if (IS_ERR(rng)) {
+ printk(KERN_ERR "alg: cprng: Failed to load transform for %s: "
+ "%ld\n", driver, PTR_ERR(rng));
+ return PTR_ERR(rng);
+ }
+
+ err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count);
+
+ crypto_free_rng(rng);
+
+ return err;
+}
+
+/* Please keep this list sorted by algorithm name. */
+static const struct alg_test_desc alg_test_descs[] = {
+ {
+ .alg = "ansi_cprng",
+ .test = alg_test_cprng,
+ .fips_allowed = 1,
+ .suite = {
+ .cprng = {
+ .vecs = ansi_cprng_aes_tv_template,
+ .count = ANSI_CPRNG_AES_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "cbc(aes)",
+ .test = alg_test_skcipher,
+ .fips_allowed = 1,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = aes_cbc_enc_tv_template,
+ .count = AES_CBC_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_cbc_dec_tv_template,
+ .count = AES_CBC_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "cbc(anubis)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = anubis_cbc_enc_tv_template,
+ .count = ANUBIS_CBC_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = anubis_cbc_dec_tv_template,
+ .count = ANUBIS_CBC_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "cbc(blowfish)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = bf_cbc_enc_tv_template,
+ .count = BF_CBC_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = bf_cbc_dec_tv_template,
+ .count = BF_CBC_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "cbc(camellia)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = camellia_cbc_enc_tv_template,
+ .count = CAMELLIA_CBC_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = camellia_cbc_dec_tv_template,
+ .count = CAMELLIA_CBC_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "cbc(des)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = des_cbc_enc_tv_template,
+ .count = DES_CBC_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = des_cbc_dec_tv_template,
+ .count = DES_CBC_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "cbc(des3_ede)",
+ .test = alg_test_skcipher,
+ .fips_allowed = 1,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = des3_ede_cbc_enc_tv_template,
+ .count = DES3_EDE_CBC_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = des3_ede_cbc_dec_tv_template,
+ .count = DES3_EDE_CBC_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "cbc(twofish)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = tf_cbc_enc_tv_template,
+ .count = TF_CBC_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = tf_cbc_dec_tv_template,
+ .count = TF_CBC_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ccm(aes)",
+ .test = alg_test_aead,
+ .fips_allowed = 1,
+ .suite = {
+ .aead = {
+ .enc = {
+ .vecs = aes_ccm_enc_tv_template,
+ .count = AES_CCM_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_ccm_dec_tv_template,
+ .count = AES_CCM_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "crc32c",
+ .test = alg_test_crc32c,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = crc32c_tv_template,
+ .count = CRC32C_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "ctr(aes)",
+ .test = alg_test_skcipher,
+ .fips_allowed = 1,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = aes_ctr_enc_tv_template,
+ .count = AES_CTR_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_ctr_dec_tv_template,
+ .count = AES_CTR_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "cts(cbc(aes))",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = cts_mode_enc_tv_template,
+ .count = CTS_MODE_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = cts_mode_dec_tv_template,
+ .count = CTS_MODE_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "deflate",
+ .test = alg_test_comp,
+ .suite = {
+ .comp = {
+ .comp = {
+ .vecs = deflate_comp_tv_template,
+ .count = DEFLATE_COMP_TEST_VECTORS
+ },
+ .decomp = {
+ .vecs = deflate_decomp_tv_template,
+ .count = DEFLATE_DECOMP_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(aes)",
+ .test = alg_test_skcipher,
+ .fips_allowed = 1,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = aes_enc_tv_template,
+ .count = AES_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_dec_tv_template,
+ .count = AES_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(anubis)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = anubis_enc_tv_template,
+ .count = ANUBIS_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = anubis_dec_tv_template,
+ .count = ANUBIS_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(arc4)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = arc4_enc_tv_template,
+ .count = ARC4_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = arc4_dec_tv_template,
+ .count = ARC4_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(blowfish)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = bf_enc_tv_template,
+ .count = BF_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = bf_dec_tv_template,
+ .count = BF_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(camellia)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = camellia_enc_tv_template,
+ .count = CAMELLIA_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = camellia_dec_tv_template,
+ .count = CAMELLIA_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(cast5)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = cast5_enc_tv_template,
+ .count = CAST5_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = cast5_dec_tv_template,
+ .count = CAST5_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(cast6)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = cast6_enc_tv_template,
+ .count = CAST6_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = cast6_dec_tv_template,
+ .count = CAST6_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(des)",
+ .test = alg_test_skcipher,
+ .fips_allowed = 1,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = des_enc_tv_template,
+ .count = DES_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = des_dec_tv_template,
+ .count = DES_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(des3_ede)",
+ .test = alg_test_skcipher,
+ .fips_allowed = 1,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = des3_ede_enc_tv_template,
+ .count = DES3_EDE_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = des3_ede_dec_tv_template,
+ .count = DES3_EDE_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(khazad)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = khazad_enc_tv_template,
+ .count = KHAZAD_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = khazad_dec_tv_template,
+ .count = KHAZAD_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(seed)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = seed_enc_tv_template,
+ .count = SEED_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = seed_dec_tv_template,
+ .count = SEED_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(serpent)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = serpent_enc_tv_template,
+ .count = SERPENT_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = serpent_dec_tv_template,
+ .count = SERPENT_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(tea)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = tea_enc_tv_template,
+ .count = TEA_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = tea_dec_tv_template,
+ .count = TEA_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(tnepres)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = tnepres_enc_tv_template,
+ .count = TNEPRES_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = tnepres_dec_tv_template,
+ .count = TNEPRES_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(twofish)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = tf_enc_tv_template,
+ .count = TF_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = tf_dec_tv_template,
+ .count = TF_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(xeta)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = xeta_enc_tv_template,
+ .count = XETA_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = xeta_dec_tv_template,
+ .count = XETA_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ecb(xtea)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = xtea_enc_tv_template,
+ .count = XTEA_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = xtea_dec_tv_template,
+ .count = XTEA_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "gcm(aes)",
+ .test = alg_test_aead,
+ .fips_allowed = 1,
+ .suite = {
+ .aead = {
+ .enc = {
+ .vecs = aes_gcm_enc_tv_template,
+ .count = AES_GCM_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_gcm_dec_tv_template,
+ .count = AES_GCM_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "hmac(md5)",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = hmac_md5_tv_template,
+ .count = HMAC_MD5_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "hmac(rmd128)",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = hmac_rmd128_tv_template,
+ .count = HMAC_RMD128_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "hmac(rmd160)",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = hmac_rmd160_tv_template,
+ .count = HMAC_RMD160_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "hmac(sha1)",
+ .test = alg_test_hash,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = hmac_sha1_tv_template,
+ .count = HMAC_SHA1_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "hmac(sha224)",
+ .test = alg_test_hash,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = hmac_sha224_tv_template,
+ .count = HMAC_SHA224_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "hmac(sha256)",
+ .test = alg_test_hash,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = hmac_sha256_tv_template,
+ .count = HMAC_SHA256_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "hmac(sha384)",
+ .test = alg_test_hash,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = hmac_sha384_tv_template,
+ .count = HMAC_SHA384_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "hmac(sha512)",
+ .test = alg_test_hash,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = hmac_sha512_tv_template,
+ .count = HMAC_SHA512_TEST_VECTORS
+ }
+ }
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+ }, {
+ .alg = "lrw(aes)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = aes_lrw_enc_tv_template,
+ .count = AES_LRW_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_lrw_dec_tv_template,
+ .count = AES_LRW_DEC_TEST_VECTORS
+ }
+ }
+ }
+#endif
+ }, {
+ .alg = "lzo",
+ .test = alg_test_comp,
+ .suite = {
+ .comp = {
+ .comp = {
+ .vecs = lzo_comp_tv_template,
+ .count = LZO_COMP_TEST_VECTORS
+ },
+ .decomp = {
+ .vecs = lzo_decomp_tv_template,
+ .count = LZO_DECOMP_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "md4",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = md4_tv_template,
+ .count = MD4_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "md5",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = md5_tv_template,
+ .count = MD5_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "michael_mic",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = michael_mic_tv_template,
+ .count = MICHAEL_MIC_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "pcbc(fcrypt)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = fcrypt_pcbc_enc_tv_template,
+ .count = FCRYPT_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = fcrypt_pcbc_dec_tv_template,
+ .count = FCRYPT_DEC_TEST_VECTORS
+ }
+ }
+ }
+
+ }, {
+ .alg = "rfc3686(ctr(aes))",
+ .test = alg_test_skcipher,
+ .fips_allowed = 1,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = aes_ctr_rfc3686_enc_tv_template,
+ .count = AES_CTR_3686_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_ctr_rfc3686_dec_tv_template,
+ .count = AES_CTR_3686_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "rfc4309(ccm(aes))",
+ .test = alg_test_aead,
+ .fips_allowed = 1,
+ .suite = {
+ .aead = {
+ .enc = {
+ .vecs = aes_ccm_rfc4309_enc_tv_template,
+ .count = AES_CCM_4309_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_ccm_rfc4309_dec_tv_template,
+ .count = AES_CCM_4309_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "rmd128",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = rmd128_tv_template,
+ .count = RMD128_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "rmd160",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = rmd160_tv_template,
+ .count = RMD160_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "rmd256",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = rmd256_tv_template,
+ .count = RMD256_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "rmd320",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = rmd320_tv_template,
+ .count = RMD320_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "salsa20",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = salsa20_stream_enc_tv_template,
+ .count = SALSA20_STREAM_ENC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "sha1",
+ .test = alg_test_hash,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = sha1_tv_template,
+ .count = SHA1_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "sha224",
+ .test = alg_test_hash,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = sha224_tv_template,
+ .count = SHA224_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "sha256",
+ .test = alg_test_hash,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = sha256_tv_template,
+ .count = SHA256_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "sha384",
+ .test = alg_test_hash,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = sha384_tv_template,
+ .count = SHA384_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "sha512",
+ .test = alg_test_hash,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = sha512_tv_template,
+ .count = SHA512_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "tgr128",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = tgr128_tv_template,
+ .count = TGR128_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "tgr160",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = tgr160_tv_template,
+ .count = TGR160_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "tgr192",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = tgr192_tv_template,
+ .count = TGR192_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "vmac(aes)",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = aes_vmac128_tv_template,
+ .count = VMAC_AES_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "wp256",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = wp256_tv_template,
+ .count = WP256_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "wp384",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = wp384_tv_template,
+ .count = WP384_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "wp512",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = wp512_tv_template,
+ .count = WP512_TEST_VECTORS
+ }
+ }
+ }, {
+ .alg = "xcbc(aes)",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = {
+ .vecs = aes_xcbc128_tv_template,
+ .count = XCBC_AES_TEST_VECTORS
+ }
+ }
+#if 0
+ }, {
+ .alg = "xts(aes)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = aes_xts_enc_tv_template,
+ .count = AES_XTS_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_xts_dec_tv_template,
+ .count = AES_XTS_DEC_TEST_VECTORS
+ }
+ }
+ }
+#endif
+ }, {
+ .alg = "zlib",
+ .test = alg_test_pcomp,
+ .suite = {
+ .pcomp = {
+ .comp = {
+ .vecs = zlib_comp_tv_template,
+ .count = ZLIB_COMP_TEST_VECTORS
+ },
+ .decomp = {
+ .vecs = zlib_decomp_tv_template,
+ .count = ZLIB_DECOMP_TEST_VECTORS
+ }
+ }
+ }
+ }
+};
+
+static int alg_find_test(const char *alg)
+{
+ int start = 0;
+ int end = ARRAY_SIZE(alg_test_descs);
+
+ while (start < end) {
+ int i = (start + end) / 2;
+ int diff = strcmp(alg_test_descs[i].alg, alg);
+
+ if (diff > 0) {
+ end = i;
+ continue;
+ }
+
+ if (diff < 0) {
+ start = i + 1;
+ continue;
+ }
+
+ return i;
+ }
+
+ return -1;
+}
+
+static int ifx_alg_test(const char *driver, const char *alg, u32 type, u32 mask)
+{
+ int i;
+ int j;
+ int rc;
+
+ if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
+ char nalg[CRYPTO_MAX_ALG_NAME];
+
+ if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
+ sizeof(nalg))
+ return -ENAMETOOLONG;
+
+ i = alg_find_test(nalg);
+ if (i < 0)
+ goto notest;
+
+ if (fips_enabled && !alg_test_descs[i].fips_allowed)
+ goto non_fips_alg;
+
+ rc = alg_test_cipher(alg_test_descs + i, driver, type, mask);
+ goto test_done;
+ }
+
+ i = alg_find_test(alg);
+ j = alg_find_test(driver);
+ if (i < 0 && j < 0)
+ goto notest;
+
+ if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
+ (j >= 0 && !alg_test_descs[j].fips_allowed)))
+ goto non_fips_alg;
+
+ rc = 0;
+ if (i >= 0)
+ rc |= alg_test_descs[i].test(alg_test_descs + i, driver,
+ type, mask);
+ if (j >= 0)
+ rc |= alg_test_descs[j].test(alg_test_descs + j, driver,
+ type, mask);
+
+test_done:
+ if (fips_enabled && rc)
+ panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
+
+ if (fips_enabled && !rc)
+ printk(KERN_INFO "alg: self-tests for %s (%s) passed\n",
+ driver, alg);
+
+ return rc;
+
+notest:
+ printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
+ return 0;
+non_fips_alg:
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(ifx_alg_test);
+
+/* Modified speed test for async block cipher mode*/
+
+static int ifx_alg_speed_test(const char *driver, const char *alg,
+ unsigned int sec,
+ struct cipher_speed_template *template,
+ unsigned int tcount, u8 *keysize)
+{
+ int i;
+ int j;
+ int err;
+ int type = 0, mask = 0;
+ struct crypto_ablkcipher *tfm;
+
+ i = alg_find_test(alg);
+ j = alg_find_test(driver);
+
+ if (i < 0 && j < 0)
+ goto notest;
+
+ if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
+ (j >= 0 && !alg_test_descs[j].fips_allowed)))
+ goto non_fips_alg;
+
+ tfm = crypto_alloc_ablkcipher(driver, type, mask);
+
+ if (IS_ERR(tfm)) {
+ printk(KERN_ERR "alg: skcipher: Failed to load transform for "
+ "%s: %ld\n", driver, PTR_ERR(tfm));
+ return PTR_ERR(tfm);
+ }
+ err = test_skcipher_speed(tfm, ENCRYPT, template,
+ tcount, sec, keysize);
+ if (err)
+ goto test_done;
+
+ err = test_skcipher_speed(tfm, DECRYPT, template,
+ tcount, sec, keysize);
+ if (!err)
+ goto test_done;
+
+notest:
+ return 0;
+non_fips_alg:
+ return -EINVAL;
+
+test_done:
+ if (fips_enabled && err)
+ panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
+
+ if (fips_enabled && !err)
+ printk(KERN_INFO "alg: self-tests for %s (%s) passed\n",
+ driver, alg);
+
+ crypto_free_ablkcipher(tfm);
+ return err;
+}
+EXPORT_SYMBOL_GPL(ifx_alg_speed_test);
+
+
+static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc,
+ struct scatterlist *sg, int blen, int sec)
+{
+ unsigned long start, end;
+ int bcount;
+ int ret;
+
+ for (start = jiffies, end = start + sec * HZ, bcount = 0;
+ time_before(jiffies, end); bcount++) {
+ if (enc)
+ ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
+ else
+ ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
+
+ if (ret)
+ return ret;
+ }
+
+ printk("%d operations in %d seconds (%ld bytes)\n",
+ bcount, sec, (long)bcount * blen);
+ return 0;
+}
+
+static int test_cipher_cycles(struct blkcipher_desc *desc, int enc,
+ struct scatterlist *sg, int blen)
+{
+ unsigned long cycles = 0;
+ unsigned long start, end;
+ int ret = 0;
+ int i;
+
+ local_bh_disable();
+ local_irq_disable();
+
+ /* Warm-up run. */
+ for (i = 0; i < 4; i++) {
+ if (enc)
+ ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
+ else
+ ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
+
+ if (ret)
+ goto out;
+ }
+
+ /* The real thing. */
+ for (i = 0; i < 8; i++) {
+ /* Original code to get cycles, does not work with MIPS
+ * cycles_t start, end;
+ * start = get_cycles();
+ */
+
+ start = read_c0_count(); // LQ modified tcrypt
+
+ if (enc)
+ ret = crypto_blkcipher_encrypt(desc, sg, sg, blen);
+ else
+ ret = crypto_blkcipher_decrypt(desc, sg, sg, blen);
+
+ /* Original code to get cycles, does not work with MIPS
+ * end = get_cycles();
+ */
+
+ end = read_c0_count(); //LQ modified tcrypt
+
+ if (ret)
+ goto out;
+
+ cycles += end - start;
+ }
+
+out:
+ local_irq_enable();
+ local_bh_enable();
+
+ if (ret == 0)
+ printk("1 operation in %lu cycles (%d bytes)\n",
+ (cycles + 4) / 8, blen);
+
+ return ret;
+}
+
+static u32 block_sizes[] = { 16, 64, 256, 1024, 8192, 0 };
+
+static void test_cipher_speed(const char *algo, int enc, unsigned int sec,
+ struct cipher_speed_template *template,
+ unsigned int tcount, u8 *keysize)
+{
+ unsigned int ret, i, j, iv_len;
+ const char *key, iv[128];
+ struct crypto_blkcipher *tfm;
+ struct blkcipher_desc desc;
+ const char *e;
+ u32 *b_size;
+
+ if (enc == ENCRYPT)
+ e = "encryption";
+ else
+ e = "decryption";
+
+ printk("\n ******* testing speed of %s %s ******* \n", algo, e);
+
+ tfm = crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
+
+ if (IS_ERR(tfm)) {
+ printk("failed to load transform for %s: %ld\n", algo,
+ PTR_ERR(tfm));
+ return;
+ }
+ desc.tfm = tfm;
+ desc.flags = 0;
+
+ i = 0;
+ do {
+
+ b_size = block_sizes;
+ do {
+ struct scatterlist sg[TVMEMSIZE];
+
+ if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) {
+ printk("template (%u) too big for "
+ "tvmem (%lu)\n", *keysize + *b_size,
+ TVMEMSIZE * PAGE_SIZE);
+ goto out;
+ }
+
+ printk("test %u (%d bit key, %d byte blocks): ", i,
+ *keysize * 8, *b_size);
+
+ memset(tvmem[0], 0xff, PAGE_SIZE);
+
+ /* set key, plain text and IV */
+ key = tvmem[0];
+ for (j = 0; j < tcount; j++) {
+ if (template[j].klen == *keysize) {
+ key = template[j].key;
+ break;
+ }
+ }
+
+ ret = crypto_blkcipher_setkey(tfm, key, *keysize);
+ if (ret) {
+ printk("setkey() failed flags=%x\n",
+ crypto_blkcipher_get_flags(tfm));
+ goto out;
+ }
+
+ sg_init_table(sg, TVMEMSIZE);
+ sg_set_buf(sg, tvmem[0] + *keysize,
+ PAGE_SIZE - *keysize);
+ for (j = 1; j < TVMEMSIZE; j++) {
+ sg_set_buf(sg + j, tvmem[j], PAGE_SIZE);
+ memset (tvmem[j], 0xff, PAGE_SIZE);
+ }
+
+ iv_len = crypto_blkcipher_ivsize(tfm);
+ if (iv_len) {
+ memset(&iv, 0xff, iv_len);
+ crypto_blkcipher_set_iv(tfm, iv, iv_len);
+ }
+
+ if (sec)
+ ret = test_cipher_jiffies(&desc, enc, sg,
+ *b_size, sec);
+ else
+ ret = test_cipher_cycles(&desc, enc, sg,
+ *b_size);
+
+ if (ret) {
+ printk("%s() failed flags=%x\n", e, desc.flags);
+ break;
+ }
+ b_size++;
+ i++;
+ } while (*b_size);
+ keysize++;
+ } while (*keysize);
+
+out:
+ crypto_free_blkcipher(tfm);
+}
+
+static int test_hash_jiffies_digest(struct hash_desc *desc,
+ struct scatterlist *sg, int blen,
+ char *out, int sec)
+{
+ unsigned long start, end;
+ int bcount;
+ int ret;
+
+ for (start = jiffies, end = start + sec * HZ, bcount = 0;
+ time_before(jiffies, end); bcount++) {
+ ret = crypto_hash_digest(desc, sg, blen, out);
+ if (ret)
+ return ret;
+ }
+
+ printk("%6u opers/sec, %9lu bytes/sec\n",
+ bcount / sec, ((long)bcount * blen) / sec);
+
+ return 0;
+}
+
+static int test_hash_jiffies(struct hash_desc *desc, struct scatterlist *sg,
+ int blen, int plen, char *out, int sec)
+{
+ unsigned long start, end;
+ int bcount, pcount;
+ int ret;
+
+ if (plen == blen)
+ return test_hash_jiffies_digest(desc, sg, blen, out, sec);
+
+ for (start = jiffies, end = start + sec * HZ, bcount = 0;
+ time_before(jiffies, end); bcount++) {
+ ret = crypto_hash_init(desc);
+ if (ret)
+ return ret;
+ for (pcount = 0; pcount < blen; pcount += plen) {
+ ret = crypto_hash_update(desc, sg, plen);
+ if (ret)
+ return ret;
+ }
+ /* we assume there is enough space in 'out' for the result */
+ ret = crypto_hash_final(desc, out);
+ if (ret)
+ return ret;
+ }
+
+ printk("%6u opers/sec, %9lu bytes/sec\n",
+ bcount / sec, ((long)bcount * blen) / sec);
+
+ return 0;
+}
+
+static int test_hash_cycles_digest(struct hash_desc *desc,
+ struct scatterlist *sg, int blen, char *out)
+{
+ unsigned long cycles = 0;
+ unsigned long start, end;
+ int i;
+ int ret;
+
+ local_bh_disable();
+ local_irq_disable();
+
+ /* Warm-up run. */
+ for (i = 0; i < 4; i++) {
+ ret = crypto_hash_digest(desc, sg, blen, out);
+ if (ret)
+ goto out;
+ }
+
+ /* The real thing. */
+ for (i = 0; i < 8; i++) {
+
+ /* Original code to get cycles, does not work with MIPS
+ * cycles_t start, end;
+ * start = get_cycles();
+ */
+
+ start = read_c0_count(); // LQ modified tcrypt
+
+ ret = crypto_hash_digest(desc, sg, blen, out);
+ if (ret)
+ goto out;
+
+ /* Original code to get cycles, does not work with MIPS
+ * end = get_cycles();
+ */
+
+ end = read_c0_count(); // LQ modified tcrypt
+
+ cycles += end - start;
+ }
+
+out:
+ local_irq_enable();
+ local_bh_enable();
+
+ if (ret)
+ return ret;
+
+ printk("%6lu cycles/operation, %4lu cycles/byte\n",
+ cycles / 8, cycles / (8 * blen));
+
+ return 0;
+}
+
+static int test_hash_cycles(struct hash_desc *desc, struct scatterlist *sg,
+ int blen, int plen, char *out)
+{
+ unsigned long cycles = 0;
+ unsigned long start, end;
+ int i, pcount;
+ int ret;
+
+ if (plen == blen)
+ return test_hash_cycles_digest(desc, sg, blen, out);
+
+ local_bh_disable();
+ local_irq_disable();
+
+ /* Warm-up run. */
+ for (i = 0; i < 4; i++) {
+ ret = crypto_hash_init(desc);
+ if (ret)
+ goto out;
+ for (pcount = 0; pcount < blen; pcount += plen) {
+ ret = crypto_hash_update(desc, sg, plen);
+ if (ret)
+ goto out;
+ }
+ ret = crypto_hash_final(desc, out);
+ if (ret)
+ goto out;
+ }
+
+ /* The real thing. */
+ for (i = 0; i < 8; i++) {
+
+ /* Original code for getting cycles, not working for MIPS
+ * cycle_t start, end;
+ * end = get_cycles();
+ */
+
+ start = read_c0_count(); // LQ modified tcrypt
+
+ ret = crypto_hash_init(desc);
+ if (ret)
+ goto out;
+ for (pcount = 0; pcount < blen; pcount += plen) {
+ ret = crypto_hash_update(desc, sg, plen);
+ if (ret)
+ goto out;
+ }
+ ret = crypto_hash_final(desc, out);
+ if (ret)
+ goto out;
+
+ /* Original code for getting cycles, not working for MIPS
+ * end = get_cycles();
+ */
+
+ end = read_c0_count(); // LQ modified tcrypt
+
+ cycles += end - start;
+ }
+
+out:
+ local_irq_enable();
+ local_bh_enable();
+
+ if (ret)
+ return ret;
+
+ printk("%6lu cycles/operation, %4lu cycles/byte\n",
+ cycles / 8, cycles / (8 * blen));
+
+ return 0;
+}
+
+static void test_hash_speed(const char *algo, unsigned int sec,
+ struct hash_speed *speed)
+{
+ struct scatterlist sg[TVMEMSIZE];
+ struct crypto_hash *tfm;
+ struct hash_desc desc;
+ static char output[1024];
+ int i;
+ int ret;
+
+ printk(KERN_INFO "\ntesting speed of %s\n", algo);
+
+ tfm = crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC);
+
+ if (IS_ERR(tfm)) {
+ printk(KERN_ERR "failed to load transform for %s: %ld\n", algo,
+ PTR_ERR(tfm));
+ return;
+ }
+
+ desc.tfm = tfm;
+ desc.flags = 0;
+
+ if (crypto_hash_digestsize(tfm) > sizeof(output)) {
+ printk(KERN_ERR "digestsize(%u) > outputbuffer(%zu)\n",
+ crypto_hash_digestsize(tfm), sizeof(output));
+ goto out;
+ }
+
+ sg_init_table(sg, TVMEMSIZE);
+ for (i = 0; i < TVMEMSIZE; i++) {
+ sg_set_buf(sg + i, tvmem[i], PAGE_SIZE);
+ memset(tvmem[i], 0xff, PAGE_SIZE);
+ }
+
+ for (i = 0; speed[i].blen != 0; i++) {
+ if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) {
+ printk(KERN_ERR
+ "template (%u) too big for tvmem (%lu)\n",
+ speed[i].blen, TVMEMSIZE * PAGE_SIZE);
+ goto out;
+ }
+
+ printk(KERN_INFO "test%3u "
+ "(%5u byte blocks,%5u bytes per update,%4u updates): ",
+ i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
+
+ if (sec)
+ ret = test_hash_jiffies(&desc, sg, speed[i].blen,
+ speed[i].plen, output, sec);
+ else
+ ret = test_hash_cycles(&desc, sg, speed[i].blen,
+ speed[i].plen, output);
+
+ if (ret) {
+ printk(KERN_ERR "hashing failed ret=%d\n", ret);
+ break;
+ }
+ }
+
+out:
+ crypto_free_hash(tfm);
+}
+
+
+static void test_available(void)
+{
+ char **name = check;
+
+ while (*name) {
+ printk("alg %s ", *name);
+ printk(crypto_has_alg(*name, 0, 0) ?
+ "found\n" : "not found\n");
+ name++;
+ }
+}
+
+static inline int tcrypt_test(const char *alg)
+{
+ int ret;
+
+ printk("Running test %s\n", alg);
+ ret = ifx_alg_test(alg, alg, 0, 0);
+ /* non-fips algs return -EINVAL in fips mode */
+ if (fips_enabled && ret == -EINVAL)
+ ret = 0;
+ return ret;
+}
+
+static inline int tcrypt_speedtest(const char *alg,
+ struct cipher_speed_template *template,
+ unsigned int tcount, u8 *keysize)
+{
+ int ret;
+
+ printk("[****** Running speedtest %s *******]\n", alg);
+ ret = ifx_alg_speed_test(alg, alg, sec, template, tcount, keysize);
+ if (fips_enabled && ret == -EINVAL)
+ ret = 0;
+ return ret;
+}
+
+
+static int do_test(int m)
+{
+ int i;
+ int ret = 0;
+
+ switch (m) {
+ case 0:
+ for (i = 1; i < 200; i++)
+ ret += do_test(i);
+ break;
+
+ case 1:
+ ret += tcrypt_test("md5");
+ break;
+
+ case 2:
+ ret += tcrypt_test("sha1");
+ break;
+
+ case 3:
+ ret += tcrypt_test("ecb(des)");
+ ret += tcrypt_test("cbc(des)");
+ break;
+
+ case 4:
+ ret += tcrypt_test("ecb(des3_ede)");
+ ret += tcrypt_test("cbc(des3_ede)");
+ break;
+
+ case 5:
+ ret += tcrypt_test("md4");
+ break;
+
+ case 6:
+ ret += tcrypt_test("sha256");
+ break;
+
+ case 7:
+ ret += tcrypt_test("ecb(blowfish)");
+ ret += tcrypt_test("cbc(blowfish)");
+ break;
+
+ case 8:
+ ret += tcrypt_test("ecb(twofish)");
+ ret += tcrypt_test("cbc(twofish)");
+ break;
+
+ case 9:
+ ret += tcrypt_test("ecb(serpent)");
+ break;
+
+ case 10:
+ ret += tcrypt_test("ecb(aes)");
+ ret += tcrypt_test("cbc(aes)");
+ // ret += tcrypt_test("lrw(aes)");
+ // ret += tcrypt_test("xts(aes)");
+ ret += tcrypt_test("ctr(aes)");
+ ret += tcrypt_test("rfc3686(ctr(aes))");
+ break;
+
+ case 11:
+ ret += tcrypt_test("sha384");
+ break;
+
+ case 12:
+ ret += tcrypt_test("sha512");
+ break;
+
+ case 13:
+ ret += tcrypt_test("deflate");
+ break;
+
+ case 14:
+ ret += tcrypt_test("ecb(cast5)");
+ break;
+
+ case 15:
+ ret += tcrypt_test("ecb(cast6)");
+ break;
+
+ case 16:
+ ret += tcrypt_test("ecb(arc4)");
+ break;
+
+ case 17:
+ ret += tcrypt_test("michael_mic");
+ break;
+
+ case 18:
+ ret += tcrypt_test("crc32c");
+ break;
+
+ case 19:
+ ret += tcrypt_test("ecb(tea)");
+ break;
+
+ case 20:
+ ret += tcrypt_test("ecb(xtea)");
+ break;
+
+ case 21:
+ ret += tcrypt_test("ecb(khazad)");
+ break;
+
+ case 22:
+ ret += tcrypt_test("wp512");
+ break;
+
+ case 23:
+ ret += tcrypt_test("wp384");
+ break;
+
+ case 24:
+ ret += tcrypt_test("wp256");
+ break;
+
+ case 25:
+ ret += tcrypt_test("ecb(tnepres)");
+ break;
+
+ case 26:
+ ret += tcrypt_test("ecb(anubis)");
+ ret += tcrypt_test("cbc(anubis)");
+ break;
+
+ case 27:
+ ret += tcrypt_test("tgr192");
+ break;
+
+ case 28:
+
+ ret += tcrypt_test("tgr160");
+ break;
+
+ case 29:
+ ret += tcrypt_test("tgr128");
+ break;
+
+ case 30:
+ ret += tcrypt_test("ecb(xeta)");
+ break;
+
+ case 31:
+ ret += tcrypt_test("pcbc(fcrypt)");
+ break;
+
+ case 32:
+ ret += tcrypt_test("ecb(camellia)");
+ ret += tcrypt_test("cbc(camellia)");
+ break;
+ case 33:
+ ret += tcrypt_test("sha224");
+ break;
+
+ case 34:
+ ret += tcrypt_test("salsa20");
+ break;
+
+ case 35:
+ ret += tcrypt_test("gcm(aes)");
+ break;
+
+ case 36:
+ ret += tcrypt_test("lzo");
+ break;
+
+ case 37:
+ ret += tcrypt_test("ccm(aes)");
+ break;
+
+ case 38:
+ ret += tcrypt_test("cts(cbc(aes))");
+ break;
+
+ case 39:
+ ret += tcrypt_test("rmd128");
+ break;
+
+ case 40:
+ ret += tcrypt_test("rmd160");
+ break;
+
+ case 41:
+ ret += tcrypt_test("rmd256");
+ break;
+
+ case 42:
+ ret += tcrypt_test("rmd320");
+ break;
+
+ case 43:
+ ret += tcrypt_test("ecb(seed)");
+ break;
+
+ case 44:
+ ret += tcrypt_test("zlib");
+ break;
+
+ case 45:
+ ret += tcrypt_test("rfc4309(ccm(aes))");
+ break;
+
+ case 100:
+ ret += tcrypt_test("hmac(md5)");
+ break;
+
+ case 101:
+ ret += tcrypt_test("hmac(sha1)");
+ break;
+
+ case 102:
+ ret += tcrypt_test("hmac(sha256)");
+ break;
+
+ case 103:
+ ret += tcrypt_test("hmac(sha384)");
+ break;
+
+ case 104:
+ ret += tcrypt_test("hmac(sha512)");
+ break;
+
+ case 105:
+ ret += tcrypt_test("hmac(sha224)");
+ break;
+
+ case 106:
+ ret += tcrypt_test("xcbc(aes)");
+ break;
+
+ case 107:
+ ret += tcrypt_test("hmac(rmd128)");
+ break;
+
+ case 108:
+ ret += tcrypt_test("hmac(rmd160)");
+ break;
+
+ case 109:
+ ret += tcrypt_test("vmac(aes)");
+ break;
+
+ case 150:
+ ret += tcrypt_test("ansi_cprng");
+ break;
+
+ case 200:
+ test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("ecb(aes)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("cbc(aes)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("cbc(aes)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+#if !defined(CONFIG_CRYPTO_DEV_AES) && !defined(CONFIG_CRYPTO_ASYNC_AES)
+ test_cipher_speed("lrw(aes)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_40_48);
+ test_cipher_speed("lrw(aes)", DECRYPT, sec, NULL, 0,
+ speed_template_32_40_48);
+ test_cipher_speed("xts(aes)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_48_64);
+ test_cipher_speed("xts(aes)", DECRYPT, sec, NULL, 0,
+ speed_template_32_48_64);
+#endif
+ break;
+
+ case 201:
+ test_cipher_speed("ecb(des3_ede)", ENCRYPT, sec,
+ des3_speed_template, DES3_SPEED_VECTORS,
+ speed_template_24);
+ test_cipher_speed("ecb(des3_ede)", DECRYPT, sec,
+ des3_speed_template, DES3_SPEED_VECTORS,
+ speed_template_24);
+ test_cipher_speed("cbc(des3_ede)", ENCRYPT, sec,
+ des3_speed_template, DES3_SPEED_VECTORS,
+ speed_template_24);
+ test_cipher_speed("cbc(des3_ede)", DECRYPT, sec,
+ des3_speed_template, DES3_SPEED_VECTORS,
+ speed_template_24);
+ break;
+
+ case 202:
+ test_cipher_speed("ecb(twofish)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("ecb(twofish)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("cbc(twofish)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("cbc(twofish)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ break;
+
+ case 203:
+ test_cipher_speed("ecb(blowfish)", ENCRYPT, sec, NULL, 0,
+ speed_template_8_32);
+ test_cipher_speed("ecb(blowfish)", DECRYPT, sec, NULL, 0,
+ speed_template_8_32);
+ test_cipher_speed("cbc(blowfish)", ENCRYPT, sec, NULL, 0,
+ speed_template_8_32);
+ test_cipher_speed("cbc(blowfish)", DECRYPT, sec, NULL, 0,
+ speed_template_8_32);
+ break;
+
+ case 204:
+ test_cipher_speed("ecb(des)", ENCRYPT, sec, NULL, 0,
+ speed_template_8);
+ test_cipher_speed("ecb(des)", DECRYPT, sec, NULL, 0,
+ speed_template_8);
+ test_cipher_speed("cbc(des)", ENCRYPT, sec, NULL, 0,
+ speed_template_8);
+ test_cipher_speed("cbc(des)", DECRYPT, sec, NULL, 0,
+ speed_template_8);
+ break;
+
+ case 205:
+ test_cipher_speed("ecb(camellia)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("ecb(camellia)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("cbc(camellia)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("cbc(camellia)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ break;
+
+ case 206:
+ test_cipher_speed("salsa20", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ break;
+
+ case 300:
+ /* fall through */
+
+ case 301:
+ test_hash_speed("md4", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 302:
+ test_hash_speed("md5", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 303:
+ test_hash_speed("sha1", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 304:
+ test_hash_speed("sha256", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 305:
+ test_hash_speed("sha384", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 306:
+ test_hash_speed("sha512", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 307:
+ test_hash_speed("wp256", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 308:
+ test_hash_speed("wp384", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 309:
+ test_hash_speed("wp512", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 310:
+ test_hash_speed("tgr128", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 311:
+ test_hash_speed("tgr160", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 312:
+ test_hash_speed("tgr192", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 313:
+ test_hash_speed("sha224", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 314:
+ test_hash_speed("rmd128", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 315:
+ test_hash_speed("rmd160", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 316:
+ test_hash_speed("rmd256", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 317:
+ test_hash_speed("rmd320", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
+ case 399:
+ break;
+
+ /* Modified speed test for async block cipher mode */
+ case 400:
+ tcrypt_speedtest("ecb(aes)", NULL, 0,
+ speed_template_16_24_32);
+ tcrypt_speedtest("cbc(aes)", NULL, 0,
+ speed_template_16_24_32);
+ break;
+
+ case 401:
+ tcrypt_speedtest("ecb(des3_ede)", des3_speed_template,
+ DES3_SPEED_VECTORS,speed_template_24);
+ tcrypt_speedtest("cbc(des3_ede)", des3_speed_template,
+ DES3_SPEED_VECTORS,speed_template_24);
+ break;
+
+ case 404:
+ tcrypt_speedtest("ecb(des)", NULL, 0,
+ speed_template_8);
+ tcrypt_speedtest("cbc(des)", NULL, 0,
+ speed_template_8);
+ break;
+
+ case 1000:
+ test_available();
+ break;
+ }
+
+ return ret;
+}
+#if !defined(CONFIG_CRYPTO_DEV_DEU)
+static int do_alg_test(const char *alg, u32 type, u32 mask)
+{
+ return crypto_has_alg(alg, type, mask ?: CRYPTO_ALG_TYPE_MASK) ?
+ 0 : -ENOENT;
+}
+#endif
+
+static int __init tcrypt_mod_init(void)
+{
+ int err = -ENOMEM;
+ int i;
+
+ printk("Starting Lantiq DEU Crypto TESTS . . . . . . .\n");
+
+ for (i = 0; i < TVMEMSIZE; i++) {
+ tvmem[i] = (void *)__get_free_page(GFP_KERNEL);
+ if (!tvmem[i])
+ goto err_free_tv;
+ }
+
+#if defined(CONFIG_CRYPTO_DEV_DEU)
+#if defined(CONFIG_CRYPTO_DEV_MD5)
+ mode = 1; // test md5 only
+ err = do_test(mode);
+ if (err)
+ goto md5_err;
+
+md5_err:
+ if (err) {
+ printk(KERN_ERR "md5: one or more tests failed!\n");
+ goto err_free_tv;
+ }
+#endif
+#if defined(CONFIG_CRYPTO_DEV_SHA1)
+ mode = 2; // test sha1 only
+ err = do_test(mode);
+ if (err)
+ goto sha1_err;
+
+sha1_err:
+ if (err) {
+ printk(KERN_ERR "sha1: one or more tests failed!\n");
+ goto err_free_tv;
+ }
+#endif
+#if defined (CONFIG_CRYPTO_DEV_DES) || defined (CONFIG_CRYPTO_ASYNC_DES)
+ mode = 3; // test des only
+ err = do_test(mode);
+ if (err)
+ goto des_err;
+
+ mode = 4; // test des3 only
+ err = do_test(mode);
+ if (err)
+ goto des_err;
+
+des_err:
+ if (err) {
+ printk(KERN_ERR "des3: one or more tests failed!\n");
+ goto err_free_tv;
+ }
+#endif
+#if defined (CONFIG_CRYPTO_ASYNC_AES) || defined (CONFIG_CRYPTO_DEV_AES)
+ mode = 10; // test aes only
+ err = do_test(mode);
+ if (err)
+ goto aes_err;
+
+aes_err:
+ if (err) {
+ printk(KERN_ERR "aes: one or more tests failed!\n");
+ goto err_free_tv;
+ }
+#endif
+#if defined(CONFIG_CRYPTO_DEV_ARC4)
+ mode = 16;
+ err = do_test(mode);
+
+ if (err) {
+ printk(KERN_ERR "arc4: one or more tests failed!\n");
+ goto err_free_tv;
+ }
+#endif
+#if defined (CONFIG_CRYPTO_DEV_MD5_HMAC)
+ mode = 100;
+ err = do_test(mode);
+
+ if (err) {
+ printk(KERN_ERR "tcrypt: one or more tests failed!\n");
+ goto err_free_tv;
+ }
+#endif
+#if defined (CONFIG_CRYPTO_DEV_SHA1_HMAC)
+ mode = 101;
+ err = do_test(mode);
+
+ if (err) {
+ printk(KERN_ERR "tcrypt: one or more tests failed!\n");
+ goto err_free_tv;
+ }
+#endif
+
+/* Start Speed tests test modes */
+#if defined(CONFIG_CRYPTO_DEV_SPEED_TEST)
+#if defined(CONFIG_CRYPTO_DEV_AES)
+ mode = 200;
+ err = do_test(mode);
+ if (err)
+ goto speed_err;
+#endif
+#if defined (CONFIG_CRYPTO_DEV_DES)
+ mode = 201;
+ err = do_test(mode);
+ if (err)
+ goto speed_err;
+
+ mode = 204;
+ err = do_test(mode);
+ if (err)
+ goto speed_err;
+#endif
+#if defined (CONFIG_CRYPTO_DEV_MD5)
+ mode = 302;
+ err = do_test(mode);
+ if (err)
+ goto speed_err;
+#endif
+#if defined (CONFIG_CRYPTO_DEV_SHA1)
+ mode = 303;
+ err = do_test(mode);
+ if (err)
+ goto speed_err;
+#endif
+ printk("Speed tests finished successfully\n");
+ goto fips_check;
+
+speed_err:
+ printk(KERN_ERR "tcrypt: one or more tests failed!\n");
+ goto err_free_tv;
+#endif /* CONFIG_CRYPTO_DEV_SPEED_TEST */
+
+#else
+ if (alg)
+ err = do_alg_test(alg, type, mask);
+ else
+ err = do_test(mode);
+
+ if (err) {
+ printk(KERN_ERR "tcrypt: one or more tests failed!\n");
+ goto err_free_tv;
+ }
+#endif /* CONFIG_CRYPTO_DEV_DEU */
+
+fips_check:
+ /* We intentionaly return -EAGAIN to prevent keeping the module,
+ * unless we're running in fips mode. It does all its work from
+ * init() and doesn't offer any runtime functionality, but in
+ * the fips case, checking for a successful load is helpful.
+ * => we don't need it in the memory, do we?
+ * -- mludvig
+ */
+ if (!fips_enabled)
+ err = -EAGAIN;
+
+err_free_tv:
+ for (i = 0; i < TVMEMSIZE && tvmem[i]; i++ ){
+ printk("Freeing page: %d\n", i);
+ free_page((unsigned long)tvmem[i]);
+ }
+
+ printk("Finished DEU testing . . . . . .\n");
+ return err;
+}
+
+/*
+ * If an init function is provided, an exit function must also be provided
+ * to allow module unload.
+ */
+static void __exit tcrypt_mod_fini(void) {}
+
+
+module_init(tcrypt_mod_init);
+module_exit(tcrypt_mod_fini);
+
+module_param(alg, charp, 0);
+module_param(type, uint, 0);
+module_param(mask, uint, 0);
+module_param(mode, int, 0);
+module_param(sec, uint, 0);
+MODULE_PARM_DESC(sec, "Length in seconds of speed tests "
+ "(defaults to zero which uses CPU cycles instead)");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Quick & dirty crypto testing module");
+MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
+
diff --git a/package/kernel/lantiq/ltq-hcd/Makefile b/package/kernel/lantiq/ltq-hcd/Makefile
new file mode 100644
index 0000000000..74218c887b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/Makefile
@@ -0,0 +1,53 @@
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ltq-hcd
+PKG_RELEASE:=1
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-hcd-$(BUILD_VARIANT)
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-hcd-template
+ SECTION:=sys
+ CATEGORY:=Kernel modules
+ SUBMENU:=USB Support
+ TITLE:=USB driver for $(1)
+ URL:=http://www.lantiq.com/
+ VARIANT:=$(1)
+ DEPENDS:=@TARGET_lantiq_$(2) +kmod-usb-core
+ FILES:=$(PKG_BUILD_DIR)/ltq_hcd_$(1).ko
+ AUTOLOAD:=$(call AutoLoad,50,ltq_hcd_$(1),1)
+endef
+
+KernelPackage/ltq-hcd-ase=$(call KernelPackage/ltq-hcd-template,ase,ase)
+KernelPackage/ltq-hcd-danube=$(call KernelPackage/ltq-hcd-template,danube,xway)
+KernelPackage/ltq-hcd-ar9=$(call KernelPackage/ltq-hcd-template,ar9,xway)
+KernelPackage/ltq-hcd-vr9=$(call KernelPackage/ltq-hcd-template,vr9,xway)
+KernelPackage/ltq-hcd-ar10=$(call KernelPackage/ltq-hcd-template,ar10,xway)
+
+define Build/Prepare
+ $(INSTALL_DIR) $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ cd $(LINUX_DIR); \
+ ARCH=mips CROSS_COMPILE="$(KERNEL_CROSS)" \
+ $(MAKE) BUILD_VARIANT=$(BUILD_VARIANT) M=$(PKG_BUILD_DIR) V=1 modules
+endef
+
+$(eval $(call KernelPackage,ltq-hcd-ase))
+$(eval $(call KernelPackage,ltq-hcd-danube))
+$(eval $(call KernelPackage,ltq-hcd-ar9))
+$(eval $(call KernelPackage,ltq-hcd-vr9))
+$(eval $(call KernelPackage,ltq-hcd-ar10))
diff --git a/package/kernel/lantiq/ltq-hcd/src/Kconfig b/package/kernel/lantiq/ltq-hcd/src/Kconfig
new file mode 100644
index 0000000000..2a3a38d3f8
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/Kconfig
@@ -0,0 +1,104 @@
+
+config USB_HOST_IFX
+ tristate "Infineon USB Host Controller Driver"
+ depends on USB
+ default n
+ help
+ Infineon USB Host Controller
+
+choice
+ prompt "Infineon USB Host Controller Driver Operation mode"
+ depends on USB_HOST_IFX && ( AMAZON_S || AR9 || VR9 || AR10 || MIPS_AMAZON_S || MIPS_AR9 || MIPS_VR9 || MIPS_AR10 )
+ help
+ The IFX USB core can be configured as dual-host and single host.
+ The unused core can be set as Device-mode.
+
+config USB_HOST_IFX_B
+ boolean "USB host mode on core 1 and 2"
+ help
+ Both cores run as host
+
+config USB_HOST_IFX_1
+ boolean "USB host mode on core 1 only"
+ help
+ Core #1 runs as host
+
+config USB_HOST_IFX_2
+ boolean "USB host mode on core 2 only"
+ help
+ Core #2 runs as host
+
+endchoice
+
+config USB_HOST_IFX_FORCE_USB11
+ boolean "Forced USB1.1"
+ depends on USB_HOST_IFX
+ default n
+ help
+ force to be USB 1.1
+
+config USB_HOST_IFX_WITH_HS_ELECT_TST
+ boolean "With HS_Electrical Test"
+ depends on USB_HOST_IFX
+ default n
+ help
+ With USBIF HSET routines
+
+config USB_HOST_IFX_WITH_ISO
+ boolean "With ISO transfer"
+ depends on USB_HOST_IFX
+ default n
+ help
+ With USBIF ISO transfer
+
+config USB_HOST_IFX_COC
+ boolean "CoC in USB Host"
+ depends on USB_HOST_IFX
+ default n
+ help
+ With CoC on Host
+
+choice
+ prompt "IFX unaligned buffer policy"
+ depends on USB_HOST_IFX
+ help
+ IFX unaligned buffer policy
+
+config USB_HOST_IFX_UNALIGNED_ADJ
+ boolean "Adjust"
+ help
+ USB_HOST_IFX_UNALIGNED_ADJ
+
+config USB_HOST_IFX_UNALIGNED_CHK
+ boolean "Check-only"
+ help
+ USB_HOST_IFX_UNALIGNED_CHK
+
+config USB_HOST_IFX_UNALIGNED_NONE
+ boolean "No process"
+ help
+ USB_HOST_IFX_UNALIGNED_NONE
+
+endchoice
+
+
+config USB_HOST_IFX_XHCI
+ tristate "xHCI HCD (USB 3.0) support (EXPERIMENTAL)"
+ depends on USB && PCI && ( VR9 || MIPS_VR9 || AR10 || MIPS_AR10 )
+ ---help---
+ The eXtensible Host Controller Interface (xHCI) is standard for USB 3.0
+ "SuperSpeed" host controller hardware.
+
+ To compile this driver as a module, choose M here: the
+ module will be called xhci-hcd.
+
+config USB_HOST_IFX_XHCI_DEBUGGING
+ bool "Debugging for the xHCI host controller"
+ depends on USB_HOST_IFX_XHCI
+ ---help---
+ Say 'Y' to turn on debugging for the xHCI host controller driver.
+ This will spew debugging output, even in interrupt context.
+ This should only be used for debugging xHCI driver bugs.
+
+ If unsure, say N.
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/Makefile b/package/kernel/lantiq/ltq-hcd/src/Makefile
new file mode 100644
index 0000000000..153fd42dc4
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/Makefile
@@ -0,0 +1,74 @@
+ltq_hcd_$(BUILD_VARIANT)-objs := ifxusb_driver.o ifxusb_ctl.o ifxusb_cif.o \
+ ifxusb_cif_h.o ifxhcd.o ifxhcd_es.o \
+ ifxhcd_intr.o ifxhcd_queue.o
+obj-m = ltq_hcd_$(BUILD_VARIANT).o
+
+ifeq ($(BUILD_VARIANT),danube)
+ EXTRA_CFLAGS += -D__IS_DANUBE__
+endif
+
+ifeq ($(BUILD_VARIANT),ase)
+ EXTRA_CFLAGS += -D__IS_AMAZON_SE__
+endif
+
+ifeq ($(BUILD_VARIANT),ar9)
+ EXTRA_CFLAGS += -D__IS_AR9__
+ EXTRA_CFLAGS += -D__IS_DUAL__
+endif
+
+ifeq ($(BUILD_VARIANT),vr9)
+ EXTRA_CFLAGS += -D__IS_VR9__
+ EXTRA_CFLAGS += -D__PHY_LONG_PREEMP__
+ EXTRA_CFLAGS += -D__PINGSTOP_CTRL__
+ EXTRA_CFLAGS += -D__PINGSTOP_BULK__
+ EXTRA_CFLAGS += -D__IS_DUAL__
+endif
+
+ifeq ($(BUILD_VARIANT),ar10)
+ EXTRA_CFLAGS += -D__IS_AR10__
+ EXTRA_CFLAGS += -D__PHY_LONG_PREEMP__
+ EXTRA_CFLAGS += -D__PINGSTOP_CTRL__
+ EXTRA_CFLAGS += -D__PINGSTOP_BULK__
+endif
+
+ifeq ($(CONFIG_USB_HOST_IFX_FORCE_USB11),y)
+ EXTRA_CFLAGS += -D__FORCE_USB11__
+endif
+ifeq ($(CONFIG_USB_HOST_IFX_WITH_HS_ELECT_TST),y)
+ EXTRA_CFLAGS += -D__WITH_HS_ELECT_TST__
+endif
+ifeq ($(CONFIG_USB_HOST_IFX_WITH_ISO),y)
+ EXTRA_CFLAGS += -D__EN_ISOC__
+endif
+#ifeq ($(CONFIG_USB_HOST_IFX_UNALIGNED_ADJ),y)
+ EXTRA_CFLAGS += -D__UNALIGNED_BUF_ADJ__
+#endif
+ifeq ($(CONFIG_USB_HOST_IFX_UNALIGNED_CHK),y)
+ EXTRA_CFLAGS += -D__UNALIGNED_BUF_CHK__
+endif
+ifeq ($(CONFIG_USB_HOST_IFX_COC),y)
+ EXTRA_CFLAGS += -D__HOST_COC__
+endif
+
+# EXTRA_CFLAGS += -D__IS_FIRST__
+# EXTRA_CFLAGS += -D__IS_SECOND__
+
+# EXTRA_CFLAGS += -D__EN_ISOC__
+# EXTRA_CFLAGS += -D__EN_ISOC_SPLIT__
+# EXTRA_CFLAGS += -D__EPQD_DESTROY_TIMEOUT__
+# EXTRA_CFLAGS += -D__INNAKSTOP_CTRL__
+
+EXTRA_CFLAGS += -Dlinux -D__LINUX__
+EXTRA_CFLAGS += -D__IS_HOST__
+EXTRA_CFLAGS += -D__KERNEL__
+#EXTRA_CFLAGS += -D__DEBUG__
+#EXTRA_CFLAGS += -D__ENABLE_DUMP__
+
+EXTRA_CFLAGS += -D__DYN_SOF_INTR__
+EXTRA_CFLAGS += -D__UEIP__
+EXTRA_CFLAGS += -D__DO_OC_INT__
+EXTRA_CFLAGS += -D__INNAKSTOP_BULK__
+
+EXTRA_CFLAGS += -D__INTRNAKRETRY__
+EXTRA_CFLAGS += -D__INTRINCRETRY__
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxhcd.c b/package/kernel/lantiq/ltq-hcd/src/ifxhcd.c
new file mode 100644
index 0000000000..be0a91d262
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxhcd.c
@@ -0,0 +1,2141 @@
+/*****************************************************************************
+ ** FILE NAME : ifxhcd.c
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** AUTHOR : Chen, Howard
+ ** DESCRIPTION : This file contains the structures, constants, and
+ ** interfaces for the Host Contoller Driver (HCD).
+ **
+ ** The Host Controller Driver (HCD) is responsible for
+ ** translating requests from the USB Driver into the
+ ** appropriate actions on the IFXUSB controller.
+ ** It isolates the USBD from the specifics of the
+ ** controller by providing an API to the USBD.
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*!
+ \file ifxhcd.c
+ \ingroup IFXUSB_DRIVER_V3
+ \brief This file contains the implementation of the HCD. In Linux,
+ the HCD implements the hc_driver API.
+*/
+
+#include <linux/version.h>
+#include "ifxusb_version.h"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+
+#include <linux/device.h>
+
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+
+#include <linux/dma-mapping.h>
+
+
+#include "ifxusb_plat.h"
+#include "ifxusb_regs.h"
+#include "ifxusb_cif.h"
+#include "ifxhcd.h"
+
+#include <asm/irq.h>
+
+#ifdef __DEBUG__
+ static void dump_urb_info(struct urb *_urb, char* _fn_name);
+#if 0
+ static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_epqh_t *_epqh);
+#endif
+#endif
+
+static void ifxhcd_complete_urb_sub(ifxhcd_urbd_t *_urbd)
+{
+ ifxhcd_hcd_t *ifxhcd;
+ struct urb *urb=NULL;
+
+ if (!list_empty(&_urbd->ql))
+ {
+ list_del_init(&_urbd->ql);
+ _urbd->epqh->urbd_count--;
+ }
+ else
+ IFX_ERROR("%s: urb(%p) not connect to any epqh\n",
+ __func__,_urbd);
+
+ ifxhcd=_urbd->epqh->ifxhcd;
+ urb =_urbd->urb;
+ if(!urb)
+ IFX_ERROR("%s: invalid urb\n",__func__);
+ else if(urb->hcpriv)
+ {
+ if(urb->hcpriv != _urbd)
+ IFX_ERROR("%s: invalid"
+ " urb(%p)->hcpriv(%p) != _urbd(%p)\n",
+ __func__,
+ urb,
+ urb->hcpriv,
+ _urbd);
+ #if defined(__UNALIGNED_BUF_ADJ__)
+ if(_urbd->is_in &&
+// _urbd->using_aligned_buf &&
+ _urbd->aligned_buf)
+ memcpy(_urbd->xfer_buff,
+ _urbd->aligned_buf,
+ _urbd->xfer_len);
+ if(_urbd->aligned_buf)
+ ifxusb_free_buf_h(_urbd->aligned_buf);
+ #endif
+ urb->hcpriv = NULL;
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+ urb->status=_urbd->status;
+ usb_hcd_giveback_urb(ifxhcd_to_syshcd(ifxhcd), urb);
+ #else
+ usb_hcd_giveback_urb(ifxhcd_to_syshcd(ifxhcd), urb,
+ _urbd->status);
+ #endif
+ }
+ kfree(_urbd);
+}
+
+#ifdef __STRICT_ORDER__
+ static void ifxhcd_complete_urb_func(unsigned long data)
+ {
+ unsigned long flags;
+ ifxhcd_urbd_t *urbd;
+ ifxhcd_epqh_t *epqh;
+ struct list_head *item;
+
+ int count=10;
+
+ epqh=((ifxhcd_epqh_t *)data);
+
+ while (!list_empty(&epqh->release_list) && count)
+ {
+ item = epqh->release_list.next;
+ urbd = list_entry(item, ifxhcd_urbd_t, ql);
+ if (!urbd)
+ IFX_ERROR("%s: invalid urbd\n",__func__);
+ else if (!urbd->epqh)
+ IFX_ERROR("%s: invalid epqd\n",__func__);
+ else
+ {
+ ifxhcd_epqh_t *epqh2;
+ epqh2=urbd->epqh;
+ local_irq_save(flags);
+ LOCK_URBD_LIST(epqh2);
+ ifxhcd_complete_urb_sub(urbd);
+ UNLOCK_URBD_LIST(epqh2);
+ local_irq_restore (flags);
+ }
+ count--;
+ }
+ if(!list_empty(&epqh->release_list))
+ tasklet_schedule(&epqh->complete_urb_sub);
+ }
+
+ /*!
+ \brief Sets the final status of an URB and returns it to the device
+ driver. Any required cleanup of the URB is performed.
+ */
+ void ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_urbd_t *_urbd,
+ int _status)
+ {
+ unsigned long flags;
+
+ if(!_urbd)
+ {
+ IFX_ERROR("%s: invalid urbd\n",__func__);
+ return;
+ }
+ if (!_urbd->epqh)
+ {
+ IFX_ERROR("%s: invalid epqh\n",__func__);
+ return;
+ }
+
+ local_irq_save(flags);
+ LOCK_URBD_LIST(_urbd->epqh);
+ #ifdef __DEBUG__
+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
+ {
+ IFX_PRINT("%s: ehqh %p _urbd %p, urb %p,"
+ " device %d, ep %d %s/%s, status=%d\n",
+ __func__,_urbd->epqh,
+ _urbd,_urbd->urb,
+ (_urbd->urb)?usb_pipedevice(_urbd->urb->pipe):-1,
+ (_urbd->urb)?usb_pipeendpoint(_urbd->urb->pipe):-1,
+ (_urbd->urb)?(usb_pipein(_urbd->urb->pipe) ? "IN" : "OUT"):"--",
+ (_urbd->is_in) ? "IN" : "OUT",
+ _status);
+ if ((_urbd->urb)&& _urbd->epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
+ {
+ int i;
+ for (i = 0; i < _urbd->urb->number_of_packets; i++)
+ IFX_PRINT(" ISO Desc %d status: %d\n", i, _urbd->urb->iso_frame_desc[i].status);
+ }
+ }
+ #endif
+ _urbd->status = _status;
+
+ if(_urbd->phase!=URBD_FINISHING)
+ {
+ if(_urbd->phase!=URBD_DEQUEUEING && _urbd->phase!=URBD_COMPLETING)
+ printk(KERN_INFO "Warning: %s() Strange URBD PHASE %d\n",__func__,_urbd->phase);
+ if(_urbd->urb)
+ {
+ if( _urbd->status == 0
+ && _urbd->phase==URBD_COMPLETING
+ && in_irq())
+ {
+ list_move_tail(&_urbd->ql,&_urbd->epqh->release_list);
+ if(!_urbd->epqh->complete_urb_sub.func)
+ {
+ _urbd->epqh->complete_urb_sub.next = NULL;
+ _urbd->epqh->complete_urb_sub.state = 0;
+ atomic_set( &_urbd->epqh->complete_urb_sub.count, 0);
+ _urbd->epqh->complete_urb_sub.func = ifxhcd_complete_urb_func;
+ _urbd->epqh->complete_urb_sub.data = (unsigned long)_urbd->epqh;
+ }
+ tasklet_schedule(&_urbd->epqh->complete_urb_sub);
+ }
+ else
+ {
+ _urbd->phase=URBD_FINISHING;
+ ifxhcd_complete_urb_sub(_urbd);
+ }
+ UNLOCK_URBD_LIST(_urbd->epqh);
+ }
+ else
+ {
+ UNLOCK_URBD_LIST(_urbd->epqh);
+ kfree(_urbd);
+ }
+ }
+ else
+ {
+ printk(KERN_INFO "Warning: %s() Double Completing \n",__func__);
+ UNLOCK_URBD_LIST(_urbd->epqh);
+ }
+
+ local_irq_restore (flags);
+ }
+#else
+ static void ifxhcd_complete_urb_func(unsigned long data)
+ {
+ unsigned long flags;
+ ifxhcd_urbd_t *urbd;
+
+ urbd=((ifxhcd_urbd_t *)data);
+
+ // local_irq_save(flags);
+ if (!urbd)
+ IFX_ERROR("%s: invalid urbd\n",__func__);
+ else if (!urbd->epqh)
+ IFX_ERROR("%s: invalid epqd\n",__func__);
+ else
+ {
+ local_irq_save(flags);
+ LOCK_URBD_LIST(urbd->epqh);
+ ifxhcd_complete_urb_sub(urbd);
+ UNLOCK_URBD_LIST(urbd->epqh);
+ local_irq_restore (flags);
+ }
+ // local_irq_restore (flags);
+ }
+
+
+ /*!
+ \brief Sets the final status of an URB and returns it to the device driver. Any
+ required cleanup of the URB is performed.
+ */
+ void ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status)
+ {
+ unsigned long flags;
+
+ if(!_urbd)
+ {
+ IFX_ERROR("%s: invalid urbd\n",__func__);
+ return;
+ }
+ if (!_urbd->epqh)
+ {
+ IFX_ERROR("%s: invalid epqh\n",__func__);
+ return;
+ }
+
+ local_irq_save(flags);
+ LOCK_URBD_LIST(_urbd->epqh);
+ #ifdef __DEBUG__
+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
+ {
+ IFX_PRINT("%s: ehqh %p _urbd %p, urb %p, device %d, ep %d %s/%s, status=%d\n",
+ __func__,_urbd->epqh, _urbd,_urbd->urb,
+ (_urbd->urb)?usb_pipedevice(_urbd->urb->pipe):-1,
+ (_urbd->urb)?usb_pipeendpoint(_urbd->urb->pipe):-1,
+ (_urbd->urb)?(usb_pipein(_urbd->urb->pipe) ? "IN" : "OUT"):"--",
+ (_urbd->is_in) ? "IN" : "OUT",
+ _status);
+ if ((_urbd->urb)&& _urbd->epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
+ {
+ int i;
+ for (i = 0; i < _urbd->urb->number_of_packets; i++)
+ IFX_PRINT(" ISO Desc %d status: %d\n", i, _urbd->urb->iso_frame_desc[i].status);
+ }
+ }
+ #endif
+ _urbd->status = _status;
+
+ if(_urbd->phase!=URBD_FINISHING)
+ {
+ if(_urbd->phase!=URBD_DEQUEUEING && _urbd->phase!=URBD_COMPLETING)
+ printk(KERN_INFO "Warning: %s() Strange URBD PHASE %d\n",__func__,_urbd->phase);
+ if(_urbd->urb)
+ {
+ if( _urbd->status == 0
+ && _urbd->phase==URBD_COMPLETING
+ && in_irq())
+ {
+ if(_urbd->complete_urb_sub.func)
+ printk(KERN_INFO "Warning: %s() URBD Tasklet is on already\n",__func__);
+ _urbd->phase=URBD_FINISHING;
+ _urbd->complete_urb_sub.next = NULL;
+ _urbd->complete_urb_sub.state = 0;
+ atomic_set( &_urbd->complete_urb_sub.count, 0);
+ _urbd->complete_urb_sub.func = ifxhcd_complete_urb_func;
+ _urbd->complete_urb_sub.data = (unsigned long)_urbd;
+ tasklet_schedule(&_urbd->complete_urb_sub);
+ }
+ else
+ {
+ _urbd->phase=URBD_FINISHING;
+ ifxhcd_complete_urb_sub(_urbd);
+ }
+ }
+ else
+ kfree(_urbd);
+ }
+ else
+ printk(KERN_INFO "Warning: %s() Double Completing \n",__func__);
+ UNLOCK_URBD_LIST(_urbd->epqh);
+ local_irq_restore (flags);
+ }
+#endif
+
+/*!
+ \brief Processes all the URBs in a single EPQHs. Completes them with
+ status and frees the URBD.
+ */
+static
+void kill_all_urbs_in_epqh(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh, int _status)
+{
+ struct list_head *item;
+ struct list_head *next;
+ ifxhcd_urbd_t *urbd;
+
+ if(!_epqh)
+ return;
+
+ IFX_DEBUGPL(DBG_HCDV, "%s %p\n",__func__,_epqh);
+ LOCK_URBD_LIST(_epqh);
+ list_for_each(item, &_epqh->urbd_list)
+ {
+ urbd = list_entry(item, ifxhcd_urbd_t, ql);
+ if( urbd->phase==URBD_IDLE
+ || urbd->phase==URBD_ACTIVE
+// || urbd->phase==URBD_STARTING
+ )
+ urbd->phase=URBD_DEQUEUEING;
+ }
+ list_for_each_safe(item, next, &_epqh->urbd_list)
+ {
+ urbd = list_entry(item, ifxhcd_urbd_t, ql);
+ if(urbd->phase==URBD_DEQUEUEING)
+ {
+ urbd->urb->status = _status;
+ urbd->phase = URBD_FINISHING;
+ ifxhcd_complete_urb_sub(urbd);
+ }
+ else if( urbd->phase==URBD_STARTED
+ || urbd->phase==URBD_STARTING
+// || urbd->phase==URBD_ACTIVE
+ )
+ {
+ if(ifxhcd_hc_halt(&_ifxhcd->core_if, _epqh->hc, HC_XFER_URB_DEQUEUE))
+ {
+ urbd->urb->status = _status;
+ urbd->phase=URBD_FINISHING;
+ ifxhcd_complete_urb_sub(urbd);
+ }
+ }
+ else
+ IFX_ERROR("%s: invalid urb phase:%d \n",__func__,urbd->phase);
+ }
+ UNLOCK_URBD_LIST(_epqh);
+ IFX_DEBUGPL(DBG_HCDV, "%s %p finish\n",__func__,_epqh);
+}
+
+
+/*!
+ \brief Free all EPS in one Processes all the URBs in a single list of EPQHs. Completes them with
+ -ETIMEDOUT and frees the URBD.
+ */
+static
+void epqh_list_free_1(ifxhcd_hcd_t *_ifxhcd, struct list_head *_epqh_list)
+{
+ ifxhcd_epqh_t *epqh;
+ struct list_head *item;
+ if (!_ifxhcd)
+ return;
+ if (!_epqh_list)
+ return;
+
+ IFX_DEBUGPL(DBG_HCDV, "%s %p\n",__func__,_epqh_list);
+
+ item = _epqh_list->next;
+ while(item != _epqh_list && item != item->next)
+ {
+ epqh = list_entry(item, ifxhcd_epqh_t, ql);
+ epqh->phase=EPQH_DISABLING;
+ item = item->next;
+ kill_all_urbs_in_epqh(_ifxhcd, epqh, -ETIMEDOUT);
+ #ifdef __STRICT_ORDER__
+ if(list_empty(&epqh->urbd_list) && list_empty(&epqh->release_list))
+ #else
+ if(list_empty(&epqh->urbd_list))
+ #endif
+ ifxhcd_epqh_free(epqh);
+ }
+ IFX_DEBUGPL(DBG_HCDV, "%s %p finish\n",__func__,_epqh_list);
+ /* Ensure there are no URBDs or URBs left. */
+}
+
+static
+void epqh_list_free_2(ifxhcd_hcd_t *_ifxhcd, struct list_head *_epqh_list)
+{
+ ifxhcd_epqh_t *epqh;
+ struct list_head *item;
+ struct list_head *next;
+ if (!_ifxhcd)
+ return;
+ if (!_epqh_list)
+ return;
+
+ IFX_DEBUGPL(DBG_HCDV, "%s %p\n",__func__,_epqh_list);
+ list_for_each_safe(item, next, _epqh_list)
+ {
+ epqh = list_entry(item, ifxhcd_epqh_t, ql);
+ if(item == item->next)
+ {
+ ifxhcd_epqh_free(epqh);
+ }
+ else
+ {
+ uint32_t count=0x80000;
+ #ifdef __STRICT_ORDER__
+ for(;(!list_empty(&epqh->urbd_list) || !list_empty(&epqh->release_list))&& count> 0; count--) udelay(1);
+ #else
+ for(;!list_empty(&epqh->urbd_list) && count> 0; count--) udelay(1);
+ #endif
+ if(!count)
+ IFX_ERROR("%s: unable to clear urbd in epqh \n",__func__);
+ ifxhcd_epqh_free(epqh);
+ }
+ }
+ IFX_DEBUGPL(DBG_HCDV, "%s %p finish\n",__func__,_epqh_list);
+ /* Ensure there are no URBDs or URBs left. */
+}
+
+static
+void epqh_list_free_all_sub(unsigned long data)
+{
+ ifxhcd_hcd_t *ifxhcd;
+
+ ifxhcd=(ifxhcd_hcd_t *)data;
+ epqh_list_free_1(ifxhcd, &ifxhcd->epqh_list_np );
+ epqh_list_free_1(ifxhcd, &ifxhcd->epqh_list_intr);
+ #ifdef __EN_ISOC__
+ epqh_list_free_1(ifxhcd, &ifxhcd->epqh_list_isoc);
+ #endif
+
+ epqh_list_free_2(ifxhcd, &ifxhcd->epqh_list_np );
+ epqh_list_free_2(ifxhcd, &ifxhcd->epqh_list_intr);
+ #ifdef __EN_ISOC__
+ epqh_list_free_2(ifxhcd, &ifxhcd->epqh_list_isoc);
+ #endif
+}
+
+static
+void epqh_list_free_all(ifxhcd_hcd_t *_ifxhcd)
+{
+ _ifxhcd->tasklet_free_epqh_list.next = NULL;
+ _ifxhcd->tasklet_free_epqh_list.state = 0;
+ atomic_set( &_ifxhcd->tasklet_free_epqh_list.count, 0);
+ _ifxhcd->tasklet_free_epqh_list.func=epqh_list_free_all_sub;
+ _ifxhcd->tasklet_free_epqh_list.data = (unsigned long)_ifxhcd;
+ tasklet_schedule(&_ifxhcd->tasklet_free_epqh_list);
+}
+
+
+/*!
+ \brief This function is called to handle the disconnection of host port.
+ */
+int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd)
+{
+ IFX_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _ifxhcd);
+
+ _ifxhcd->disconnecting=1;
+ /* Set status flags for the hub driver. */
+ _ifxhcd->flags.b.port_connect_status_change = 1;
+ _ifxhcd->flags.b.port_connect_status = 0;
+
+ /*
+ * Shutdown any transfers in process by clearing the Tx FIFO Empty
+ * interrupt mask and status bits and disabling subsequent host
+ * channel interrupts.
+ */
+ {
+ gint_data_t intr = { .d32 = 0 };
+ intr.b.nptxfempty = 1;
+ intr.b.ptxfempty = 1;
+ intr.b.hcintr = 1;
+ ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gintmsk, intr.d32, 0);
+ ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gintsts, intr.d32, 0);
+ }
+
+ /* Respond with an error status to all URBs in the schedule. */
+ epqh_list_free_all(_ifxhcd);
+
+ /* Clean up any host channels that were in use. */
+ {
+ int num_channels;
+ ifxhcd_hc_t *channel;
+ ifxusb_hc_regs_t *hc_regs;
+ hcchar_data_t hcchar;
+ int i;
+
+ num_channels = _ifxhcd->core_if.params.host_channels;
+
+ for (i = 0; i < num_channels; i++)
+ {
+ channel = &_ifxhcd->ifxhc[i];
+ hc_regs = _ifxhcd->core_if.hc_regs[i];
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ if (hcchar.b.chen)
+ printk(KERN_INFO "Warning: %s() HC still enabled\n",__func__);
+ ifxhcd_hc_cleanup(&_ifxhcd->core_if, channel);
+ }
+ }
+ IFX_DEBUGPL(DBG_HCDV, "%s(%p) finish\n", __func__, _ifxhcd);
+ return 1;
+}
+
+
+/*!
+ \brief Frees secondary storage associated with the ifxhcd_hcd structure contained
+ in the struct usb_hcd field.
+ */
+static void ifxhcd_freeextra(struct usb_hcd *_syshcd)
+{
+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
+
+ IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD FREE\n");
+
+ /* Free memory for EPQH/URBD lists */
+ epqh_list_free_all(ifxhcd);
+
+ /* Free memory for the host channels. */
+ ifxusb_free_buf_h(ifxhcd->status_buf);
+ return;
+}
+
+/*!
+ \brief Initializes the HCD. This function allocates memory for and initializes the
+ static parts of the usb_hcd and ifxhcd_hcd structures. It also registers the
+ USB bus with the core and calls the hc_driver->start() function. It returns
+ a negative error on failure.
+ */
+int ifxhcd_init(ifxhcd_hcd_t *_ifxhcd)
+{
+ int retval = 0;
+ struct usb_hcd *syshcd = NULL;
+
+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD INIT\n");
+
+ INIT_EPQH_LIST_ALL(_ifxhcd);
+ INIT_EPQH_LIST(_ifxhcd);
+
+ init_timer(&_ifxhcd->autoprobe_timer);
+ init_timer(&_ifxhcd->host_probe_timer);
+ _ifxhcd->probe_sec = 5;
+ _ifxhcd->autoprobe_sec = 30;
+
+ _ifxhcd->hc_driver.description = _ifxhcd->core_if.core_name;
+ _ifxhcd->hc_driver.product_desc = "IFX USB Controller";
+ //_ifxhcd->hc_driver.hcd_priv_size = sizeof(ifxhcd_hcd_t);
+ _ifxhcd->hc_driver.hcd_priv_size = sizeof(unsigned long);
+ _ifxhcd->hc_driver.irq = ifxhcd_irq;
+ _ifxhcd->hc_driver.flags = HCD_MEMORY | HCD_USB2;
+ _ifxhcd->hc_driver.start = ifxhcd_start;
+ _ifxhcd->hc_driver.stop = ifxhcd_stop;
+ //_ifxhcd->hc_driver.reset =
+ //_ifxhcd->hc_driver.suspend =
+ //_ifxhcd->hc_driver.resume =
+ _ifxhcd->hc_driver.urb_enqueue = ifxhcd_urb_enqueue;
+ _ifxhcd->hc_driver.urb_dequeue = ifxhcd_urb_dequeue;
+ _ifxhcd->hc_driver.endpoint_disable = ifxhcd_endpoint_disable;
+ _ifxhcd->hc_driver.get_frame_number = ifxhcd_get_frame_number;
+ _ifxhcd->hc_driver.hub_status_data = ifxhcd_hub_status_data;
+ _ifxhcd->hc_driver.hub_control = ifxhcd_hub_control;
+ //_ifxhcd->hc_driver.hub_suspend =
+ //_ifxhcd->hc_driver.hub_resume =
+ _ifxhcd->pkt_remaining_reload_hs=PKT_REMAINING_RELOAD_HS;
+ _ifxhcd->pkt_remaining_reload_fs=PKT_REMAINING_RELOAD_FS;
+ _ifxhcd->pkt_remaining_reload_ls=PKT_REMAINING_RELOAD_LS;
+ _ifxhcd->pkt_count_limit_bo =8;
+ _ifxhcd->pkt_count_limit_bi =8;
+
+ /* Allocate memory for and initialize the base HCD and */
+ //syshcd = usb_create_hcd(&_ifxhcd->hc_driver, _ifxhcd->dev, _ifxhcd->dev->bus_id);
+ syshcd = usb_create_hcd(&_ifxhcd->hc_driver, _ifxhcd->dev, _ifxhcd->core_if.core_name);
+
+ if (syshcd == NULL)
+ {
+ retval = -ENOMEM;
+ goto error1;
+ }
+
+ syshcd->rsrc_start = (unsigned long)_ifxhcd->core_if.core_global_regs;
+ syshcd->regs = (void *)_ifxhcd->core_if.core_global_regs;
+ syshcd->self.otg_port = 0;
+
+ //*((unsigned long *)(&(syshcd->hcd_priv)))=(unsigned long)_ifxhcd;
+ //*((unsigned long *)(&(syshcd->hcd_priv[0])))=(unsigned long)_ifxhcd;
+ syshcd->hcd_priv[0]=(unsigned long)_ifxhcd;
+ _ifxhcd->syshcd=syshcd;
+ INIT_LIST_HEAD(&_ifxhcd->epqh_list_all );
+ INIT_LIST_HEAD(&_ifxhcd->epqh_list_np );
+ INIT_LIST_HEAD(&_ifxhcd->epqh_list_intr );
+ #ifdef __EN_ISOC__
+ INIT_LIST_HEAD(&_ifxhcd->epqh_list_isoc);
+ #endif
+
+ /*
+ * Create a host channel descriptor for each host channel implemented
+ * in the controller. Initialize the channel descriptor array.
+ */
+ {
+ int num_channels = _ifxhcd->core_if.params.host_channels;
+ int i;
+ for (i = 0; i < num_channels; i++)
+ {
+ _ifxhcd->ifxhc[i].hc_num = i;
+ IFX_DEBUGPL(DBG_HCDV, "HCD Added channel #%d\n", i);
+ }
+ }
+
+ /* Set device flags indicating whether the HCD supports DMA. */
+ if(_ifxhcd->dev->dma_mask)
+ *(_ifxhcd->dev->dma_mask) = ~0;
+ _ifxhcd->dev->coherent_dma_mask = ~0;
+
+ /*
+ * Finish generic HCD initialization and start the HCD. This function
+ * allocates the DMA buffer pool, registers the USB bus, requests the
+ * IRQ line, and calls ifxusb_hcd_start method.
+ */
+ retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, 0
+ |IRQF_DISABLED
+ |IRQF_SHARED
+ );
+ if (retval < 0)
+ goto error2;
+
+ /*
+ * Allocate space for storing data on status transactions. Normally no
+ * data is sent, but this space acts as a bit bucket. This must be
+ * done after usb_add_hcd since that function allocates the DMA buffer
+ * pool.
+ */
+ _ifxhcd->status_buf = ifxusb_alloc_buf_h(IFXHCD_STATUS_BUF_SIZE, 1);
+
+ if (_ifxhcd->status_buf)
+ {
+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Initialized, bus=%s, usbbus=%d\n", _ifxhcd->core_if.core_name, syshcd->self.busnum);
+ return 0;
+ }
+ IFX_ERROR("%s: status_buf allocation failed\n", __func__);
+
+ /* Error conditions */
+ usb_remove_hcd(syshcd);
+error2:
+ ifxhcd_freeextra(syshcd);
+ usb_put_hcd(syshcd);
+error1:
+ return retval;
+}
+
+/*!
+ \brief Removes the HCD.
+ Frees memory and resources associated with the HCD and deregisters the bus.
+ */
+void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd)
+{
+ struct usb_hcd *syshcd = ifxhcd_to_syshcd(_ifxhcd);
+
+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD REMOVE\n");
+
+ /* Turn off all interrupts */
+ ifxusb_wreg (&_ifxhcd->core_if.core_global_regs->gintmsk, 0);
+ ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gahbcfg, 1, 0);
+
+ usb_remove_hcd(syshcd);
+ ifxhcd_freeextra(syshcd);
+ usb_put_hcd(syshcd);
+
+ return;
+}
+
+
+/* =========================================================================
+ * Linux HC Driver Functions
+ * ========================================================================= */
+
+/*!
+ \brief Initializes the IFXUSB controller and its root hub and prepares it for host
+ mode operation. Activates the root port. Returns 0 on success and a negative
+ error code on failure.
+ Called by USB stack.
+ */
+int ifxhcd_start(struct usb_hcd *_syshcd)
+{
+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
+ ifxusb_core_if_t *core_if = &ifxhcd->core_if;
+ struct usb_bus *bus;
+
+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD START\n");
+
+ bus = hcd_to_bus(_syshcd);
+
+ /* Initialize the bus state. */
+ _syshcd->state = HC_STATE_RUNNING;
+
+ /* Initialize and connect root hub if one is not already attached */
+ if (bus->root_hub)
+ {
+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Has Root Hub\n");
+ /* Inform the HUB driver to resume. */
+ usb_hcd_resume_root_hub(_syshcd);
+ }
+
+ ifxhcd->flags.d32 = 0;
+
+ /* Put all channels in the free channel list and clean up channel states.*/
+ {
+ int num_channels = ifxhcd->core_if.params.host_channels;
+ int i;
+ for (i = 0; i < num_channels; i++)
+ {
+ ifxhcd_hc_t *channel;
+ channel = &ifxhcd->ifxhc[i];
+ ifxhcd_hc_cleanup(&ifxhcd->core_if, channel);
+ }
+ }
+ /* Initialize the USB core for host mode operation. */
+
+ ifxusb_host_enable_interrupts(core_if);
+ ifxusb_enable_global_interrupts_h(core_if);
+ ifxusb_phy_power_on_h (core_if);
+
+ ifxusb_vbus_init(core_if);
+
+ /* Turn on the vbus power. */
+ {
+ hprt0_data_t hprt0;
+ hprt0.d32 = ifxusb_read_hprt0(core_if);
+
+ IFX_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);
+ if (hprt0.b.prtpwr == 0 )
+ {
+ hprt0.b.prtpwr = 1;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ ifxusb_vbus_on(core_if);
+ }
+ }
+ return 0;
+}
+
+/*!
+ \brief Halts the IFXUSB host mode operations in a clean manner. USB transfers are
+ stopped.
+ */
+ #if defined(__IS_AR10__)
+void ifxusb_oc_int_free(int port);
+ #else
+void ifxusb_oc_int_free(void);
+ #endif
+
+void ifxhcd_stop(struct usb_hcd *_syshcd)
+{
+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
+ hprt0_data_t hprt0 = { .d32=0 };
+
+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD STOP\n");
+
+ /* Turn off all interrupts. */
+ ifxusb_disable_global_interrupts_h(&ifxhcd->core_if );
+ ifxusb_host_disable_interrupts(&ifxhcd->core_if );
+
+ /*
+ * The root hub should be disconnected before this function is called.
+ * The disconnect will clear the URBD lists (via ..._hcd_urb_dequeue)
+ * and the EPQH lists (via ..._hcd_endpoint_disable).
+ */
+
+ /* Turn off the vbus power */
+ IFX_PRINT("PortPower off\n");
+
+ ifxusb_vbus_off(&ifxhcd->core_if );
+
+
+ #if defined(__IS_AR10__)
+ ifxusb_oc_int_free(ifxhcd->core_if.core_no);
+ #else
+ ifxusb_oc_int_free();
+ #endif
+
+
+ ifxusb_vbus_free(&ifxhcd->core_if );
+ hprt0.b.prtpwr = 0;
+ ifxusb_wreg(ifxhcd->core_if.hprt0, hprt0.d32);
+ return;
+}
+
+/*!
+ \brief Returns the current frame number
+ */
+int ifxhcd_get_frame_number(struct usb_hcd *_syshcd)
+{
+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
+ hfnum_data_t hfnum;
+
+ hfnum.d32 = ifxusb_rreg(&ifxhcd->core_if.host_global_regs->hfnum);
+
+ return hfnum.b.frnum;
+}
+
+/*!
+ \brief Starts processing a USB transfer request specified by a USB Request Block
+ (URB). mem_flags indicates the type of memory allocation to use while
+ processing this URB.
+ */
+int ifxhcd_urb_enqueue( struct usb_hcd *_syshcd,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+ struct usb_host_endpoint *_sysep,
+#endif
+ struct urb *_urb,
+ gfp_t _mem_flags)
+{
+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
+ ifxhcd_epqh_t *epqh = NULL;
+
+ #ifdef __DEBUG__
+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
+ dump_urb_info(_urb, "ifxusb_hcd_urb_enqueue");
+ #endif //__DEBUG__
+
+ if (!ifxhcd->flags.b.port_connect_status) /* No longer connected. */
+ return -ENODEV;
+
+ #if !defined(__EN_ISOC__)
+ if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
+ {
+ IFX_ERROR("ISOC transfer not supported!!!\n");
+ return -ENODEV;
+ }
+ #endif
+
+ if(_urb->hcpriv)
+ {
+ IFX_WARN("%s() Previous urb->hcpriv exist %p\n",__func__,_urb->hcpriv);
+ #if 1
+ return -ENOSPC;
+ #endif
+ }
+
+ epqh=ifxhcd_urbd_create (ifxhcd,_urb);
+ if (!epqh)
+ {
+ IFX_ERROR("IFXUSB HCD URB Enqueue failed creating URBD\n");
+ return -ENOSPC;
+ }
+ if(epqh->phase==EPQH_DISABLING )
+ {
+ IFX_ERROR("Enqueue to a DISABLING EP!!!\n");
+ return -ENODEV;
+ }
+
+ #ifdef __DYN_SOF_INTR__
+ ifxhcd->dyn_sof_count = DYN_SOF_COUNT_DEF;
+ #endif
+ //enable_sof(ifxhcd);
+ {
+ gint_data_t gintsts;
+ gintsts.d32=0;
+ gintsts.b.sofintr = 1;
+ ifxusb_mreg(&ifxhcd->core_if.core_global_regs->gintmsk, 0,gintsts.d32);
+ }
+
+ if(epqh->phase==EPQH_IDLE || epqh->phase==EPQH_STDBY )
+ {
+ epqh->phase=EPQH_READY;
+ #ifdef __EPQD_DESTROY_TIMEOUT__
+ del_timer(&epqh->destroy_timer);
+ #endif
+ }
+ select_eps(ifxhcd);
+ return 0;
+}
+
+/*!
+ \brief Aborts/cancels a USB transfer request. Always returns 0 to indicate
+ success.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb)
+#else
+int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb, int status)
+#endif
+{
+ ifxhcd_hcd_t *ifxhcd;
+ struct usb_host_endpoint *sysep;
+ ifxhcd_urbd_t *urbd;
+ ifxhcd_epqh_t *epqh;
+
+ IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD URB Dequeue\n");
+ #if !defined(__EN_ISOC__)
+ if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
+ return 0;
+ #endif
+
+ ifxhcd = syshcd_to_ifxhcd(_syshcd);
+
+ urbd = (ifxhcd_urbd_t *) _urb->hcpriv;
+ if(!urbd)
+ {
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+ _urb->status=-ETIMEDOUT;
+ usb_hcd_giveback_urb(_syshcd, _urb);
+ #else
+// usb_hcd_giveback_urb(_syshcd, _urb,-ETIMEDOUT);
+ usb_hcd_giveback_urb(_syshcd, _urb,status);
+ #endif
+ return 0;
+ }
+
+ sysep = ifxhcd_urb_to_endpoint(_urb);
+ if(sysep)
+ {
+ LOCK_EPQH_LIST_ALL(ifxhcd);
+ epqh = sysep_to_epqh(ifxhcd,sysep);
+ UNLOCK_EPQH_LIST_ALL(ifxhcd);
+ if(epqh!=urbd->epqh)
+ IFX_ERROR("%s inconsistant epqh %p %p\n",__func__,epqh,urbd->epqh);
+ }
+ else
+ epqh = (ifxhcd_epqh_t *) urbd->epqh;
+ if(!ifxhcd->flags.b.port_connect_status || !epqh)
+ {
+ urbd->phase=URBD_DEQUEUEING;
+ ifxhcd_complete_urb(ifxhcd, urbd, -ENODEV);
+ }
+ else
+ {
+ LOCK_URBD_LIST(epqh);
+ if( urbd->phase==URBD_IDLE
+ || urbd->phase==URBD_ACTIVE
+// || urbd->phase==URBD_STARTING
+ )
+ {
+ urbd->phase=URBD_DEQUEUEING;
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+ ifxhcd_complete_urb(ifxhcd, urbd, -ETIMEDOUT);
+ #else
+ ifxhcd_complete_urb(ifxhcd, urbd, status);
+ #endif
+ }
+ else if( urbd->phase==URBD_STARTED
+ || urbd->phase==URBD_STARTING
+// || urbd->phase==URBD_ACTIVE
+ )
+ {
+ if(ifxhcd_hc_halt(&ifxhcd->core_if, epqh->hc, HC_XFER_URB_DEQUEUE))
+ {
+ urbd->phase=URBD_DEQUEUEING;
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+ ifxhcd_complete_urb(ifxhcd, urbd, -ETIMEDOUT);
+ #else
+ ifxhcd_complete_urb(ifxhcd, urbd, status);
+ #endif
+ ifxhcd_epqh_idle(epqh);
+ }
+ }
+ UNLOCK_URBD_LIST(epqh);
+ }
+ return 0;
+}
+
+
+/*!
+ \brief Frees resources in the IFXUSB controller related to a given endpoint. Also
+ clears state in the HCD related to the endpoint. Any URBs for the endpoint
+ must already be dequeued.
+ */
+void ifxhcd_endpoint_disable( struct usb_hcd *_syshcd,
+ struct usb_host_endpoint *_sysep)
+{
+ ifxhcd_hcd_t *ifxhcd;
+ ifxhcd_epqh_t *epqh;
+
+ IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD EP DISABLE: _bEndpointAddress=0x%02x, "
+ "endpoint=%d\n", _sysep->desc.bEndpointAddress,
+ ifxhcd_ep_addr_to_endpoint(_sysep->desc.bEndpointAddress));
+
+ ifxhcd = syshcd_to_ifxhcd(_syshcd);
+
+ LOCK_EPQH_LIST_ALL(ifxhcd);
+ epqh = sysep_to_epqh(ifxhcd,_sysep);
+ UNLOCK_EPQH_LIST_ALL(ifxhcd);
+
+ if (!epqh)
+ {
+ return;
+ }
+ else
+ {
+ if (epqh->sysep!=_sysep)
+ {
+ IFX_ERROR("%s inconsistant sysep %p %p %p\n",__func__,epqh,epqh->sysep,_sysep);
+ return;
+ }
+
+ epqh->phase=EPQH_DISABLING;
+ kill_all_urbs_in_epqh(ifxhcd, epqh, -ETIMEDOUT);
+ {
+ uint32_t count=0x80000;
+ for(;!list_empty(&epqh->urbd_list) && count> 0; count--) udelay(1);
+ if(!count)
+ IFX_ERROR("%s: unable to clear urbd in epqh \n",__func__);
+ }
+ ifxhcd_epqh_free(epqh);
+ }
+ IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD EP DISABLE: done\n");
+}
+
+
+/*!
+ \brief Handles host mode interrupts for the IFXUSB controller. Returns IRQ_NONE if
+ there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
+ interrupt.
+
+ This function is called by the USB core when an interrupt occurs
+ */
+irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd)
+{
+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
+ int32_t retval=0;
+
+ //mask_and_ack_ifx_irq (ifxhcd->core_if.irq);
+ retval = ifxhcd_handle_intr(ifxhcd);
+ return IRQ_RETVAL(retval);
+}
+
+
+
+/*!
+ \brief Creates Status Change bitmap for the root hub and root port. The bitmap is
+ returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
+ is the status change indicator for the single root port. Returns 1 if either
+ change indicator is 1, otherwise returns 0.
+ */
+int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf)
+{
+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
+
+ _buf[0] = 0;
+ _buf[0] |= (ifxhcd->flags.b.port_connect_status_change ||
+ ifxhcd->flags.b.port_reset_change ||
+ ifxhcd->flags.b.port_enable_change ||
+ ifxhcd->flags.b.port_suspend_change ||
+ ifxhcd->flags.b.port_over_current_change) << 1;
+
+ #ifdef __DEBUG__
+ if (_buf[0])
+ {
+ IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD HUB STATUS DATA:"
+ " Root port status changed\n");
+ IFX_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n",
+ ifxhcd->flags.b.port_connect_status_change);
+ IFX_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n",
+ ifxhcd->flags.b.port_reset_change);
+ IFX_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n",
+ ifxhcd->flags.b.port_enable_change);
+ IFX_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n",
+ ifxhcd->flags.b.port_suspend_change);
+ IFX_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n",
+ ifxhcd->flags.b.port_over_current_change);
+ {
+ hprt0_data_t hprt0;
+ hprt0.d32 = ifxusb_rreg(ifxhcd->core_if.hprt0);
+ IFX_DEBUGPL(DBG_HCDV, " port reg :%08X\n",hprt0.d32);
+ IFX_DEBUGPL(DBG_HCDV, " port reg :connect: %d/%d\n",hprt0.b.prtconnsts,hprt0.b.prtconndet);
+ IFX_DEBUGPL(DBG_HCDV, " port reg :enable: %d/%d\n",hprt0.b.prtena,hprt0.b.prtenchng);
+ IFX_DEBUGPL(DBG_HCDV, " port reg :OC: %d/%d\n",hprt0.b.prtovrcurract,hprt0.b.prtovrcurrchng);
+ IFX_DEBUGPL(DBG_HCDV, " port reg :rsume/suspend/reset: %d/%d/%d\n",hprt0.b.prtres,hprt0.b.prtsusp,hprt0.b.prtrst);
+ IFX_DEBUGPL(DBG_HCDV, " port reg :port power: %d/\n",hprt0.b.prtpwr);
+ IFX_DEBUGPL(DBG_HCDV, " port reg :speed: %d/\n",hprt0.b.prtspd);
+ }
+ }
+ #endif //__DEBUG__
+ return (_buf[0] != 0);
+}
+
+#ifdef __WITH_HS_ELECT_TST__
+ extern void do_setup(ifxusb_core_if_t *_core_if) ;
+ extern void do_in_ack(ifxusb_core_if_t *_core_if);
+#endif //__WITH_HS_ELECT_TST__
+
+/*!
+ \brief Handles hub class-specific requests.
+ */
+int ifxhcd_hub_control( struct usb_hcd *_syshcd,
+ u16 _typeReq,
+ u16 _wValue,
+ u16 _wIndex,
+ char *_buf,
+ u16 _wLength)
+{
+ int retval = 0;
+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
+ ifxusb_core_if_t *core_if = &ifxhcd->core_if;
+ struct usb_hub_descriptor *desc;
+ hprt0_data_t hprt0 = {.d32 = 0};
+
+ uint32_t port_status;
+
+ switch (_typeReq)
+ {
+ case ClearHubFeature:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "ClearHubFeature 0x%x\n", _wValue);
+ switch (_wValue)
+ {
+ case C_HUB_LOCAL_POWER:
+ case C_HUB_OVER_CURRENT:
+ /* Nothing required here */
+ break;
+ default:
+ retval = -EINVAL;
+ IFX_ERROR ("IFXUSB HCD - "
+ "ClearHubFeature request %xh unknown\n", _wValue);
+ }
+ break;
+ case ClearPortFeature:
+ if (!_wIndex || _wIndex > 1)
+ goto error;
+
+ switch (_wValue)
+ {
+ case USB_PORT_FEAT_ENABLE:
+ IFX_DEBUGPL (DBG_ANY, "IFXUSB HCD HUB CONTROL - "
+ "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
+ hprt0.d32 = ifxusb_read_hprt0 (core_if);
+ hprt0.b.prtena = 1;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ break;
+ case USB_PORT_FEAT_SUSPEND:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
+ hprt0.d32 = ifxusb_read_hprt0 (core_if);
+ hprt0.b.prtres = 1;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ /* Clear Resume bit */
+ mdelay (100);
+ hprt0.b.prtres = 0;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ break;
+ case USB_PORT_FEAT_POWER:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "ClearPortFeature USB_PORT_FEAT_POWER\n");
+ #ifdef __IS_DUAL__
+ ifxusb_vbus_off(core_if);
+ #else
+ ifxusb_vbus_off(core_if);
+ #endif
+ hprt0.d32 = ifxusb_read_hprt0 (core_if);
+ hprt0.b.prtpwr = 0;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ break;
+ case USB_PORT_FEAT_INDICATOR:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
+ /* Port inidicator not supported */
+ break;
+ case USB_PORT_FEAT_C_CONNECTION:
+ /* Clears drivers internal connect status change
+ * flag */
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
+ ifxhcd->flags.b.port_connect_status_change = 0;
+ break;
+ case USB_PORT_FEAT_C_RESET:
+ /* Clears the driver's internal Port Reset Change
+ * flag */
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
+ ifxhcd->flags.b.port_reset_change = 0;
+ break;
+ case USB_PORT_FEAT_C_ENABLE:
+ /* Clears the driver's internal Port
+ * Enable/Disable Change flag */
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
+ ifxhcd->flags.b.port_enable_change = 0;
+ break;
+ case USB_PORT_FEAT_C_SUSPEND:
+ /* Clears the driver's internal Port Suspend
+ * Change flag, which is set when resume signaling on
+ * the host port is complete */
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
+ ifxhcd->flags.b.port_suspend_change = 0;
+ break;
+ case USB_PORT_FEAT_C_OVER_CURRENT:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
+ ifxhcd->flags.b.port_over_current_change = 0;
+ break;
+ default:
+ retval = -EINVAL;
+ IFX_ERROR ("IFXUSB HCD - "
+ "ClearPortFeature request %xh "
+ "unknown or unsupported\n", _wValue);
+ }
+ break;
+ case GetHubDescriptor:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "GetHubDescriptor\n");
+ desc = (struct usb_hub_descriptor *)_buf;
+ desc->bDescLength = 9;
+ desc->bDescriptorType = 0x29;
+ desc->bNbrPorts = 1;
+ desc->wHubCharacteristics = 0x08;
+ desc->bPwrOn2PwrGood = 1;
+ desc->bHubContrCurrent = 0;
+
+ desc->u.hs.DeviceRemovable[0] = 0;
+ desc->u.hs.DeviceRemovable[1] = 1;
+ /*desc->bitmap[0] = 0;
+ desc->bitmap[1] = 0xff;*/
+ break;
+ case GetHubStatus:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "GetHubStatus\n");
+ memset (_buf, 0, 4);
+ break;
+ case GetPortStatus:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "GetPortStatus\n");
+ if (!_wIndex || _wIndex > 1)
+ goto error;
+ port_status = 0;
+ if (ifxhcd->flags.b.port_connect_status_change)
+ port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
+ if (ifxhcd->flags.b.port_enable_change)
+ port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
+ if (ifxhcd->flags.b.port_suspend_change)
+ port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
+ if (ifxhcd->flags.b.port_reset_change)
+ port_status |= (1 << USB_PORT_FEAT_C_RESET);
+ if (ifxhcd->flags.b.port_over_current_change)
+ {
+ IFX_ERROR("Device Not Supported\n");
+ port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
+ }
+ if (!ifxhcd->flags.b.port_connect_status)
+ {
+ /*
+ * The port is disconnected, which means the core is
+ * either in device mode or it soon will be. Just
+ * return 0's for the remainder of the port status
+ * since the port register can't be read if the core
+ * is in device mode.
+ */
+ *((u32 *) _buf) = cpu_to_le32(port_status);
+ break;
+ }
+
+ hprt0.d32 = ifxusb_rreg(core_if->hprt0);
+ IFX_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
+ if (hprt0.b.prtconnsts)
+ port_status |= (1 << USB_PORT_FEAT_CONNECTION);
+ if (hprt0.b.prtena)
+ {
+ ifxhcd->disconnecting=0;
+ port_status |= (1 << USB_PORT_FEAT_ENABLE);
+ }
+ if (hprt0.b.prtsusp)
+ port_status |= (1 << USB_PORT_FEAT_SUSPEND);
+ if (hprt0.b.prtovrcurract)
+ port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
+ if (hprt0.b.prtrst)
+ port_status |= (1 << USB_PORT_FEAT_RESET);
+ if (hprt0.b.prtpwr)
+ port_status |= (1 << USB_PORT_FEAT_POWER);
+ if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
+ port_status |= USB_PORT_STAT_HIGH_SPEED;
+ else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
+ port_status |= USB_PORT_STAT_LOW_SPEED;
+ if (hprt0.b.prttstctl)
+ port_status |= (1 << USB_PORT_FEAT_TEST);
+ /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
+ *((u32 *) _buf) = cpu_to_le32(port_status);
+ break;
+ case SetHubFeature:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "SetHubFeature\n");
+ /* No HUB features supported */
+ break;
+ case SetPortFeature:
+ if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1))
+ goto error;
+ /*
+ * The port is disconnected, which means the core is
+ * either in device mode or it soon will be. Just
+ * return without doing anything since the port
+ * register can't be written if the core is in device
+ * mode.
+ */
+ if (!ifxhcd->flags.b.port_connect_status)
+ break;
+ switch (_wValue)
+ {
+ case USB_PORT_FEAT_SUSPEND:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
+ hprt0.d32 = ifxusb_read_hprt0 (core_if);
+ hprt0.b.prtsusp = 1;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ //IFX_PRINT( "SUSPEND: HPRT0=%0x\n", hprt0.d32);
+ /* Suspend the Phy Clock */
+ {
+ pcgcctl_data_t pcgcctl = {.d32=0};
+ pcgcctl.b.stoppclk = 1;
+ ifxusb_wreg(core_if->pcgcctl, pcgcctl.d32);
+ }
+ break;
+ case USB_PORT_FEAT_POWER:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "SetPortFeature - USB_PORT_FEAT_POWER\n");
+ ifxusb_vbus_on (core_if);
+ hprt0.d32 = ifxusb_read_hprt0 (core_if);
+ hprt0.b.prtpwr = 1;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ break;
+ case USB_PORT_FEAT_RESET:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "SetPortFeature - USB_PORT_FEAT_RESET\n");
+ hprt0.d32 = ifxusb_read_hprt0 (core_if);
+ hprt0.b.prtrst = 1;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
+ MDELAY (60);
+ hprt0.b.prtrst = 0;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ break;
+ #ifdef __WITH_HS_ELECT_TST__
+ case USB_PORT_FEAT_TEST:
+ {
+ uint32_t t;
+ gint_data_t gintmsk;
+ t = (_wIndex >> 8); /* MSB wIndex USB */
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
+ warn("USB_PORT_FEAT_TEST %d\n", t);
+ if (t < 6)
+ {
+ hprt0.d32 = ifxusb_read_hprt0 (core_if);
+ hprt0.b.prttstctl = t;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ }
+ else if (t == 6) /* HS_HOST_PORT_SUSPEND_RESUME */
+ {
+ /* Save current interrupt mask */
+ gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
+
+ /* Disable all interrupts while we muck with
+ * the hardware directly
+ */
+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
+
+ /* 15 second delay per the test spec */
+ mdelay(15000);
+
+ /* Drive suspend on the root port */
+ hprt0.d32 = ifxusb_read_hprt0 (core_if);
+ hprt0.b.prtsusp = 1;
+ hprt0.b.prtres = 0;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+
+ /* 15 second delay per the test spec */
+ mdelay(15000);
+
+ /* Drive resume on the root port */
+ hprt0.d32 = ifxusb_read_hprt0 (core_if);
+ hprt0.b.prtsusp = 0;
+ hprt0.b.prtres = 1;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ mdelay(100);
+
+ /* Clear the resume bit */
+ hprt0.b.prtres = 0;
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+
+ /* Restore interrupts */
+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
+ }
+ else if (t == 7) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
+ {
+ /* Save current interrupt mask */
+ gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
+
+ /* Disable all interrupts while we muck with
+ * the hardware directly
+ */
+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
+
+ /* 15 second delay per the test spec */
+ mdelay(15000);
+
+ /* Send the Setup packet */
+ do_setup(core_if);
+
+ /* 15 second delay so nothing else happens for awhile */
+ mdelay(15000);
+
+ /* Restore interrupts */
+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
+ }
+
+ else if (t == 8) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
+ {
+ /* Save current interrupt mask */
+ gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
+
+ /* Disable all interrupts while we muck with
+ * the hardware directly
+ */
+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
+
+ /* Send the Setup packet */
+ do_setup(core_if);
+
+ /* 15 second delay so nothing else happens for awhile */
+ mdelay(15000);
+
+ /* Send the In and Ack packets */
+ do_in_ack(core_if);
+
+ /* 15 second delay so nothing else happens for awhile */
+ mdelay(15000);
+
+ /* Restore interrupts */
+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
+ }
+ }
+ break;
+ #endif //__WITH_HS_ELECT_TST__
+ case USB_PORT_FEAT_INDICATOR:
+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
+ "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
+ /* Not supported */
+ break;
+ default:
+ retval = -EINVAL;
+ IFX_ERROR ("IFXUSB HCD - "
+ "SetPortFeature request %xh "
+ "unknown or unsupported\n", _wValue);
+ }
+ break;
+ default:
+ error:
+ retval = -EINVAL;
+ IFX_WARN ("IFXUSB HCD - "
+ "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
+ _typeReq, _wIndex, _wValue);
+ }
+ return retval;
+}
+
+
+
+
+/*!
+ \brief This function trigger a data transfer for a host channel and
+ starts the transfer.
+
+ For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
+ register along with a packet count of 1 and the channel is enabled. This
+ causes a single PING transaction to occur. Other fields in HCTSIZ are
+ simply set to 0 since no data transfer occurs in this case.
+
+ For a PING transfer in DMA mode, the HCTSIZ register is initialized with
+ all the information required to perform the subsequent data transfer. In
+ addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
+ controller performs the entire PING protocol, then starts the data
+ transfer.
+ \param _core_if Pointer of core_if structure
+ \param _ifxhc Information needed to initialize the host channel. The xfer_len
+ value may be reduced to accommodate the max widths of the XferSize and
+ PktCnt fields in the HCTSIZn register. The multi_count value may be changed
+ to reflect the final xfer_len value.
+ */
+void ifxhcd_hc_start(ifxhcd_hcd_t *_ifxhcd, ifxhcd_hc_t *_ifxhc)
+{
+ ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
+ uint32_t max_hc_xfer_size = core_if->params.max_transfer_size;
+ uint16_t max_hc_pkt_count = core_if->params.max_packet_count;
+ ifxusb_hc_regs_t *hc_regs = core_if->hc_regs[_ifxhc->hc_num];
+ hfnum_data_t hfnum;
+
+ hprt0_data_t hprt0;
+
+ if(_ifxhc->epqh->urbd->phase==URBD_DEQUEUEING)
+ return;
+
+ hprt0.d32 = ifxusb_read_hprt0(core_if);
+
+ if(_ifxhcd->pkt_remaining==0)
+ return;
+
+#if 0
+ if(_ifxhc->phase!=HC_WAITING)
+ printk(KERN_INFO "%s() line %d: _ifxhc->phase!=HC_WAITING :%d\n",__func__,__LINE__,_ifxhc->phase);
+ if(_ifxhc->epqh->urbd->phase==URBD_IDLE ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_IDLE\n",__func__,__LINE__);
+// if(_ifxhc->epqh->urbd->phase==URBD_ACTIVE ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_ACTIVE\n",__func__,__LINE__);
+ if(_ifxhc->epqh->urbd->phase==URBD_STARTING ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_STARTING\n",__func__,__LINE__);
+ if(_ifxhc->epqh->urbd->phase==URBD_STARTED ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_STARTED\n",__func__,__LINE__);
+ if(_ifxhc->epqh->urbd->phase==URBD_COMPLETING) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_COMPLETING\n",__func__,__LINE__);
+ if(_ifxhc->epqh->urbd->phase==URBD_DEQUEUEING) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_DEQUEUEING\n",__func__,__LINE__);
+ if(_ifxhc->epqh->urbd->phase==URBD_FINISHING ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_FINISHING\n",__func__,__LINE__);
+#endif
+
+ if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
+ {
+ if (_ifxhc->split)
+ {
+ if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
+ max_hc_pkt_count = _ifxhcd->pkt_remaining;
+ }
+ else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
+ {
+ if( _ifxhc->is_in && _ifxhcd->pkt_count_limit_bi && max_hc_pkt_count > _ifxhcd->pkt_count_limit_bi)
+ max_hc_pkt_count = _ifxhcd->pkt_count_limit_bi;
+ if(!_ifxhc->is_in && _ifxhcd->pkt_count_limit_bo && max_hc_pkt_count > _ifxhcd->pkt_count_limit_bo)
+ max_hc_pkt_count = _ifxhcd->pkt_count_limit_bo;
+ if(max_hc_pkt_count*8 > _ifxhcd->pkt_remaining)
+ max_hc_pkt_count = _ifxhcd->pkt_remaining/8;
+ }
+ else
+ {
+ if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
+ max_hc_pkt_count = _ifxhcd->pkt_remaining;
+ }
+ }
+ else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
+ {
+ if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
+ max_hc_pkt_count = _ifxhcd->pkt_remaining;
+ }
+ else
+ {
+ if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
+ max_hc_pkt_count = _ifxhcd->pkt_remaining;
+ }
+
+ if(max_hc_pkt_count==0)
+ return;
+
+ if(max_hc_pkt_count * _ifxhc->mps < max_hc_xfer_size)
+ max_hc_xfer_size = max_hc_pkt_count * _ifxhc->mps;
+
+ _ifxhc->epqh->urbd->phase=URBD_STARTING;
+
+ if(_ifxhc->is_in || _ifxhc->speed != IFXUSB_EP_SPEED_HIGH || _ifxhc->xfer_len==0)
+ _ifxhc->epqh->do_ping=0;
+ if(_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
+ _ifxhc->epqh->do_ping=0;
+ if(_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL && _ifxhc->control_phase != IFXHCD_CONTROL_DATA )
+ _ifxhc->epqh->do_ping=0;
+
+ if (_ifxhc->split > 0)
+ {
+ _ifxhc->start_pkt_count = 1;
+ if(!_ifxhc->is_in && _ifxhc->split>1) // OUT CSPLIT
+ _ifxhc->xfer_len = 0;
+ if (_ifxhc->xfer_len > _ifxhc->mps)
+ _ifxhc->xfer_len = _ifxhc->mps;
+ if (_ifxhc->xfer_len > 188)
+ _ifxhc->xfer_len = 188;
+ }
+ else if(_ifxhc->is_in)
+ {
+ _ifxhc->short_rw = 0;
+ if (_ifxhc->xfer_len > 0)
+ {
+ if (_ifxhc->xfer_len > max_hc_xfer_size)
+ _ifxhc->xfer_len = max_hc_xfer_size - _ifxhc->mps + 1;
+ _ifxhc->start_pkt_count = (_ifxhc->xfer_len + _ifxhc->mps - 1) / _ifxhc->mps;
+ if (_ifxhc->start_pkt_count > max_hc_pkt_count)
+ _ifxhc->start_pkt_count = max_hc_pkt_count;
+ }
+ else /* Need 1 packet for transfer length of 0. */
+ _ifxhc->start_pkt_count = 1;
+ _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps;
+ }
+ else //non-split out
+ {
+ if (_ifxhc->xfer_len == 0)
+ {
+ if(_ifxhc->short_rw==0)
+ printk(KERN_INFO "Info: %s() line %d: ZLP write without short_rw set! xfer_count:%d/%d \n",__func__,__LINE__,
+ _ifxhc->xfer_count,
+ _ifxhc->epqh->urbd->xfer_len);
+ _ifxhc->start_pkt_count = 1;
+ }
+ else
+ {
+ if (_ifxhc->xfer_len > max_hc_xfer_size)
+ {
+ _ifxhc->start_pkt_count = (max_hc_xfer_size / _ifxhc->mps);
+ _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps;
+ }
+ else
+ {
+ _ifxhc->start_pkt_count = (_ifxhc->xfer_len+_ifxhc->mps-1) / _ifxhc->mps;
+// if(_ifxhc->start_pkt_count * _ifxhc->mps == _ifxhc->xfer_len )
+// _ifxhc->start_pkt_count += _ifxhc->short_rw;
+ }
+ }
+ }
+
+ if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
+ {
+ if (_ifxhc->split)
+ {
+ if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
+ _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
+ else
+ _ifxhcd->pkt_remaining = 0;
+ }
+ else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
+ {
+ if( _ifxhcd->pkt_remaining*8 > _ifxhc->start_pkt_count)
+ _ifxhcd->pkt_remaining -= (_ifxhc->start_pkt_count*8);
+ else
+ _ifxhcd->pkt_remaining = 0;
+ }
+ else
+ {
+ if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
+ _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
+ else
+ _ifxhcd->pkt_remaining = 0;
+ }
+ }
+ else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
+ {
+ if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
+ _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
+ else
+ _ifxhcd->pkt_remaining = 0;
+ }
+ else
+ {
+ if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
+ _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
+ else
+ _ifxhcd->pkt_remaining = 0;
+ }
+
+ #ifdef __EN_ISOC__
+ if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
+ {
+ /* Set up the initial PID for the transfer. */
+ #if 1
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
+ #else
+ if (_ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ {
+ if (_ifxhc->is_in)
+ {
+ if (_ifxhc->multi_count == 1)
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
+ else if (_ifxhc->multi_count == 2)
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
+ else
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA2;
+ }
+ else
+ {
+ if (_ifxhc->multi_count == 1)
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
+ else
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_MDATA;
+ }
+ }
+ else
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
+ #endif
+ }
+ #endif
+
+ IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _ifxhc->hc_num);
+ {
+ hctsiz_data_t hctsiz= { .d32=0 };
+
+ hctsiz.b.dopng = _ifxhc->epqh->do_ping;
+ _ifxhc->epqh->do_ping=0;
+
+ if(_ifxhc->is_in || _ifxhc->speed != IFXUSB_EP_SPEED_HIGH || _ifxhc->xfer_len==0)
+ hctsiz.b.dopng = 0;
+ if(_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
+ hctsiz.b.dopng = 0;
+ if(_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL && _ifxhc->control_phase != IFXHCD_CONTROL_DATA )
+ hctsiz.b.dopng = 0;
+
+ hctsiz.b.xfersize = _ifxhc->xfer_len;
+ hctsiz.b.pktcnt = _ifxhc->start_pkt_count;
+ hctsiz.b.pid = _ifxhc->data_pid_start;
+ ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
+
+ IFX_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
+ IFX_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n" , hctsiz.b.pktcnt);
+ IFX_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
+ }
+ IFX_DEBUGPL(DBG_HCDV, " DMA: 0x%08x\n", (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count )));
+ ifxusb_wreg(&hc_regs->hcdma, (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count )));
+
+ /* Start the split */
+ if (_ifxhc->split>0)
+ {
+ hcsplt_data_t hcsplt;
+ hcsplt.d32 = ifxusb_rreg (&hc_regs->hcsplt);
+ hcsplt.b.spltena = 1;
+ if (_ifxhc->split>1)
+ hcsplt.b.compsplt = 1;
+ else
+ hcsplt.b.compsplt = 0;
+
+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
+ if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
+ hcsplt.b.xactpos = _ifxhc->isoc_xact_pos;
+ else
+ #endif
+ hcsplt.b.xactpos = IFXUSB_HCSPLIT_XACTPOS_ALL;// if not ISO
+ ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32);
+ IFX_DEBUGPL(DBG_HCDV, " SPLIT: XACT_POS:0x%08x\n", hcsplt.d32);
+ }
+
+ {
+ hcchar_data_t hcchar;
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+// hcchar.b.multicnt = _ifxhc->multi_count;
+ hcchar.b.multicnt = 1;
+
+ if (_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
+ {
+ hfnum.d32 = ifxusb_rreg(&core_if->host_global_regs->hfnum);
+ /* 1 if _next_ frame is odd, 0 if it's even */
+ hcchar.b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
+ }
+
+ #ifdef __DEBUG__
+ _ifxhc->start_hcchar_val = hcchar.d32;
+ if (hcchar.b.chdis)
+ IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
+ __func__, _ifxhc->hc_num, hcchar.d32);
+ #endif
+
+ /* Set host channel enable after all other setup is complete. */
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 0;
+ hcchar.b.epdir = _ifxhc->is_in;
+ _ifxhc->hcchar=hcchar.d32;
+ }
+
+ IFX_DEBUGPL(DBG_HCDV, " HCCHART: 0x%08x\n", _ifxhc->hcchar);
+
+ _ifxhc->phase=HC_STARTING;
+}
+
+/*!
+ \brief Attempts to halt a host channel. This function should only be called
+ to abort a transfer in DMA mode. Under normal circumstances in DMA mode, the
+ controller halts the channel when the transfer is complete or a condition
+ occurs that requires application intervention.
+
+ In DMA mode, always sets the Channel Enable and Channel Disable bits of the
+ HCCHARn register. The controller ensures there is space in the request
+ queue before submitting the halt request.
+
+ Some time may elapse before the core flushes any posted requests for this
+ host channel and halts. The Channel Halted interrupt handler completes the
+ deactivation of the host channel.
+ */
+int ifxhcd_hc_halt(ifxusb_core_if_t *_core_if,
+ ifxhcd_hc_t *_ifxhc,
+ ifxhcd_halt_status_e _halt_status)
+{
+ hcchar_data_t hcchar;
+ ifxusb_hc_regs_t *hc_regs;
+ hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
+
+ WARN_ON(_halt_status == HC_XFER_NO_HALT_STATUS);
+
+ {
+ hprt0_data_t hprt0;
+ hprt0.d32 = ifxusb_rreg(_core_if->hprt0);
+ if(hprt0.b.prtena == 0)
+ return -1;
+ }
+
+ if (_halt_status == HC_XFER_URB_DEQUEUE ||
+ _halt_status == HC_XFER_AHB_ERR)
+ {
+ /*
+ * Disable all channel interrupts except Ch Halted. The URBD
+ * and EPQH state associated with this transfer has been cleared
+ * (in the case of URB_DEQUEUE), so the channel needs to be
+ * shut down carefully to prevent crashes.
+ */
+ hcint_data_t hcintmsk;
+ hcintmsk.d32 = 0;
+ hcintmsk.b.chhltd = 1;
+ ifxusb_wreg(&hc_regs->hcintmsk, hcintmsk.d32);
+
+ /*
+ * Make sure no other interrupts besides halt are currently
+ * pending. Handling another interrupt could cause a crash due
+ * to the URBD and EPQH state.
+ */
+ ifxusb_wreg(&hc_regs->hcint, ~hcintmsk.d32);
+
+ /*
+ * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
+ * even if the channel was already halted for some other
+ * reason.
+ */
+ _ifxhc->halt_status = _halt_status;
+ }
+
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ if (hcchar.b.chen == 0)
+ {
+ /*
+ * The channel is either already halted or it hasn't
+ * started yet. In DMA mode, the transfer may halt if
+ * it finishes normally or a condition occurs that
+ * requires driver intervention. Don't want to halt
+ * the channel again. In either Slave or DMA mode,
+ * it's possible that the transfer has been assigned
+ * to a channel, but not started yet when an URB is
+ * dequeued. Don't want to halt a channel that hasn't
+ * started yet.
+ */
+ _ifxhc->phase=HC_IDLE;
+ return -1;
+ }
+
+ if (_ifxhc->phase==HC_STOPPING)
+ {
+ /*
+ * A halt has already been issued for this channel. This might
+ * happen when a transfer is aborted by a higher level in
+ * the stack.
+ */
+ #ifdef __DEBUG__
+ IFX_PRINT("*** %s: Channel %d, double halt a channel***\n",
+ __func__, _ifxhc->hc_num);
+ #endif
+ return 0;
+ }
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 1;
+
+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
+
+ _ifxhc->halt_status = _halt_status;
+ _ifxhc->phase=HC_STOPPING;
+
+ IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n" , __func__, _ifxhc->hc_num);
+ IFX_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n" , hcchar.d32);
+ IFX_DEBUGPL(DBG_HCDV, " halt_status: %d\n" , _ifxhc->halt_status);
+
+ return 0;
+}
+
+/*!
+ \brief Clears a host channel.
+ */
+void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc)
+{
+ ifxusb_hc_regs_t *hc_regs;
+
+ _ifxhc->phase=HC_IDLE;
+ _ifxhc->epqh=0;
+
+ /*
+ * Clear channel interrupt enables and any unhandled channel interrupt
+ * conditions.
+ */
+ hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
+ ifxusb_wreg(&hc_regs->hcintmsk, 0);
+ ifxusb_wreg(&hc_regs->hcint, 0xFFFFFFFF);
+
+ #ifdef __DEBUG__
+ {
+ hcchar_data_t hcchar;
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ if (hcchar.b.chdis)
+ IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", __func__, _ifxhc->hc_num, hcchar.d32);
+ }
+ #endif
+}
+
+
+
+
+
+#ifdef __DEBUG__
+ static void dump_urb_info(struct urb *_urb, char* _fn_name)
+ {
+ IFX_PRINT("%s, urb %p\n" , _fn_name, _urb);
+ IFX_PRINT(" Device address: %d\n", usb_pipedevice(_urb->pipe));
+ IFX_PRINT(" Endpoint: %d, %s\n" , usb_pipeendpoint(_urb->pipe),
+ (usb_pipein(_urb->pipe) ? "IN" : "OUT"));
+ IFX_PRINT(" Endpoint type: %s\n",
+ ({ char *pipetype;
+ switch (usb_pipetype(_urb->pipe)) {
+ case PIPE_CONTROL: pipetype = "CONTROL"; break;
+ case PIPE_BULK: pipetype = "BULK"; break;
+ case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
+ case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
+ default: pipetype = "UNKNOWN"; break;
+ };
+ pipetype;
+ }));
+ IFX_PRINT(" Speed: %s\n",
+ ({ char *speed;
+ switch (_urb->dev->speed) {
+ case USB_SPEED_HIGH: speed = "HIGH"; break;
+ case USB_SPEED_FULL: speed = "FULL"; break;
+ case USB_SPEED_LOW: speed = "LOW"; break;
+ default: speed = "UNKNOWN"; break;
+ };
+ speed;
+ }));
+ IFX_PRINT(" Max packet size: %d\n",
+ usb_maxpacket(_urb->dev, _urb->pipe, usb_pipeout(_urb->pipe)));
+ IFX_PRINT(" Data buffer length: %d\n", _urb->transfer_buffer_length);
+ IFX_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n",
+ _urb->transfer_buffer, (void *)_urb->transfer_dma);
+ IFX_PRINT(" Setup buffer: %p, Setup DMA: %p\n",
+ _urb->setup_packet, (void *)_urb->setup_dma);
+ IFX_PRINT(" Interval: %d\n", _urb->interval);
+ if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
+ {
+ int i;
+ for (i = 0; i < _urb->number_of_packets; i++)
+ {
+ IFX_PRINT(" ISO Desc %d:\n", i);
+ IFX_PRINT(" offset: %d, length %d\n",
+ _urb->iso_frame_desc[i].offset,
+ _urb->iso_frame_desc[i].length);
+ }
+ }
+ }
+
+#if 0
+ static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
+ {
+ if (_epqh->hc != NULL)
+ {
+ ifxhcd_hc_t *hc = _epqh->hc;
+ struct list_head *item;
+ ifxhcd_epqh_t *epqh_item;
+
+ ifxusb_hc_regs_t *hc_regs;
+
+ hcchar_data_t hcchar;
+ hcsplt_data_t hcsplt;
+ hctsiz_data_t hctsiz;
+ uint32_t hcdma;
+
+ hc_regs = _ifxhcd->core_if.hc_regs[hc->hc_num];
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ hcsplt.d32 = ifxusb_rreg(&hc_regs->hcsplt);
+ hctsiz.d32 = ifxusb_rreg(&hc_regs->hctsiz);
+ hcdma = ifxusb_rreg(&hc_regs->hcdma);
+
+ IFX_PRINT(" Assigned to channel %d:\n" , hc->hc_num);
+ IFX_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
+ IFX_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n" , hctsiz.d32, hcdma);
+ IFX_PRINT(" dev_addr: %d, ep_num: %d, is_in: %d\n",
+ hc->dev_addr, hc->ep_num, hc->is_in);
+ IFX_PRINT(" ep_type: %d\n" , hc->ep_type);
+ IFX_PRINT(" max_packet_size: %d\n", hc->mps);
+ IFX_PRINT(" data_pid_start: %d\n" , hc->data_pid_start);
+ IFX_PRINT(" halt_status: %d\n" , hc->halt_status);
+ IFX_PRINT(" xfer_buff: %p\n" , hc->xfer_buff);
+ IFX_PRINT(" xfer_len: %d\n" , hc->xfer_len);
+ IFX_PRINT(" epqh: %p\n" , hc->epqh);
+ IFX_PRINT(" NP :\n");
+ list_for_each(item, &_ifxhcd->epqh_list_np)
+ {
+ epqh_item = list_entry(item, ifxhcd_epqh_t, ql);
+ IFX_PRINT(" %p\n", epqh_item);
+ }
+ IFX_PRINT(" INTR :\n");
+ list_for_each(item, &_ifxhcd->epqh_list_intr)
+ {
+ epqh_item = list_entry(item, ifxhcd_epqh_t, ql);
+ IFX_PRINT(" %p\n", epqh_item);
+ }
+ #ifdef __EN_ISOC__
+ IFX_PRINT(" ISOC:\n");
+ list_for_each(item, &_ifxhcd->epqh_list_isoc)
+ {
+ epqh_item = list_entry(item, ifxhcd_epqh_t, ql);
+ IFX_PRINT(" %p\n", epqh_item);
+ }
+ #endif
+ }
+ }
+#endif
+#endif //__DEBUG__
+
+
+/*!
+ \brief This function writes a packet into the Tx FIFO associated with the Host
+ Channel. For a channel associated with a non-periodic EP, the non-periodic
+ Tx FIFO is written. For a channel associated with a periodic EP, the
+ periodic Tx FIFO is written. This function should only be called in Slave
+ mode.
+
+ Upon return the xfer_buff and xfer_count fields in _hc are incremented by
+ then number of bytes written to the Tx FIFO.
+ */
+
+#ifdef __ENABLE_DUMP__
+ void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd)
+ {
+ int num_channels;
+ int i;
+ num_channels = _ifxhcd->core_if.params.host_channels;
+ IFX_PRINT("\n");
+ IFX_PRINT("************************************************************\n");
+ IFX_PRINT("HCD State:\n");
+ IFX_PRINT(" Num channels: %d\n", num_channels);
+ for (i = 0; i < num_channels; i++) {
+ ifxhcd_hc_t *hc = &_ifxhcd->ifxhc[i];
+ IFX_PRINT(" Channel %d:\n", hc->hc_num);
+ IFX_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
+ hc->dev_addr, hc->ep_num, hc->is_in);
+ IFX_PRINT(" speed: %d\n" , hc->speed);
+ IFX_PRINT(" ep_type: %d\n" , hc->ep_type);
+ IFX_PRINT(" mps: %d\n", hc->mps);
+ IFX_PRINT(" data_pid_start: %d\n" , hc->data_pid_start);
+ IFX_PRINT(" xfer_buff: %p\n" , hc->xfer_buff);
+ IFX_PRINT(" xfer_len: %d\n" , hc->xfer_len);
+ IFX_PRINT(" xfer_count: %d\n" , hc->xfer_count);
+ IFX_PRINT(" halt_status: %d\n" , hc->halt_status);
+ IFX_PRINT(" split: %d\n" , hc->split);
+ IFX_PRINT(" hub_addr: %d\n" , hc->hub_addr);
+ IFX_PRINT(" port_addr: %d\n" , hc->port_addr);
+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
+ IFX_PRINT(" isoc_xact_pos: %d\n" , hc->isoc_xact_pos);
+ #endif
+
+ IFX_PRINT(" epqh: %p\n" , hc->epqh);
+ IFX_PRINT(" short_rw: %d\n" , hc->short_rw);
+ IFX_PRINT(" control_phase: %d\n" , hc->control_phase);
+ if(hc->epqh)
+ {
+ IFX_PRINT(" do_ping: %d\n" , hc->epqh->do_ping);
+ }
+ IFX_PRINT(" start_pkt_count: %d\n" , hc->start_pkt_count);
+ }
+ IFX_PRINT("************************************************************\n");
+ IFX_PRINT("\n");
+ }
+#endif //__ENABLE_DUMP__
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxhcd.h b/package/kernel/lantiq/ltq-hcd/src/ifxhcd.h
new file mode 100644
index 0000000000..243c5f57e3
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxhcd.h
@@ -0,0 +1,758 @@
+/*****************************************************************************
+ ** FILE NAME : ifxhcd.h
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** AUTHOR : Chen, Howard
+ ** DESCRIPTION : This file contains the structures, constants, and interfaces for
+ ** the Host Contoller Driver (HCD).
+ **
+ ** The Host Controller Driver (HCD) is responsible for translating requests
+ ** from the USB Driver into the appropriate actions on the IFXUSB controller.
+ ** It isolates the USBD from the specifics of the controller by providing an
+ ** API to the USBD.
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*!
+ \defgroup IFXUSB_HCD HCD Interface
+ \ingroup IFXUSB_DRIVER_V3
+ \brief The Host Controller Driver (HCD) is responsible for translating requests
+ from the USB Driver into the appropriate actions on the IFXUSB controller.
+ It isolates the USBD from the specifics of the controller by providing an
+ API to the USBD.
+ */
+
+
+/*!
+ \file ifxhcd.h
+ \ingroup IFXUSB_DRIVER_V3
+ \brief This file contains the structures, constants, and interfaces for
+ the Host Contoller Driver (HCD).
+ */
+
+#if !defined(__IFXHCD_H__)
+#define __IFXHCD_H__
+
+
+#define __STRICT_ORDER__
+
+
+#include <linux/list.h>
+#include <linux/usb.h>
+
+#include <linux/usb/hcd.h>
+
+#include "ifxusb_cif.h"
+#include "ifxusb_plat.h"
+
+
+#undef __INNAKSTOP__
+#if !defined(__INNAKSTOP__) && defined(__INNAKSTOP_CTRL__)
+ #define __INNAKSTOP__ 1
+#endif
+#if !defined(__INNAKSTOP__) && defined(__INNAKSTOP_BULK__)
+ #define __INNAKSTOP__ 1
+#endif
+
+#undef __PINGSTOP__
+#if !defined(__PINGSTOP__) && defined(__PINGSTOP_CTRL__)
+ #define __PINGSTOP__ 1
+#endif
+#if !defined(__PINGSTOP__) && defined(__PINGSTOP_BULK__)
+ #define __PINGSTOP__ 1
+#endif
+
+#undef __NAKSTOP__
+#if defined(__INNAKSTOP__) || defined(__PINGSTOP__)
+ #define __NAKSTOP__ 1
+#endif
+
+
+/* Phases for control transfers.*/
+typedef enum ifxhcd_epqh_phase {
+ EPQH_IDLE=0,
+ EPQH_DISABLING,
+// EPQH_COMPLETING,
+ EPQH_STDBY,
+ EPQH_READY,
+ EPQH_ACTIVE
+} ifxhcd_epqh_phase_e;
+
+/* Phases for control transfers.*/
+typedef enum ifxhcd_urbd_phase {
+ URBD_IDLE=0,
+ URBD_ACTIVE,
+ URBD_STARTING,
+ URBD_STARTED,
+ URBD_FINISHING, //URB_Complete already scheduled
+ URBD_COMPLETING, //To URB_Complete, it's normal finish
+ URBD_DEQUEUEING, //To URB_Complete, it's abnormal finish
+} ifxhcd_urbd_phase_e;
+
+/* Phases for control transfers.*/
+typedef enum ifxhcd_hc_phase {
+ HC_IDLE=0,
+ HC_ASSIGNED,
+ HC_WAITING,
+ HC_STARTING,
+ HC_STARTED,
+ HC_STOPPING,
+ HC_STOPPED,
+} ifxhcd_hc_phase_e;
+
+/*!
+ \addtogroup IFXUSB_HCD
+ */
+/*@{*/
+
+/*! \typedef ifxhcd_control_phase_e
+ \brief Phases for control transfers.
+*/
+
+typedef enum ifxhcd_control_phase {
+ IFXHCD_CONTROL_SETUP,
+ IFXHCD_CONTROL_DATA,
+ IFXHCD_CONTROL_STATUS
+} ifxhcd_control_phase_e;
+
+/*! \typedef ifxhcd_halt_status_e
+ \brief Reasons for halting a host channel.
+*/
+typedef enum ifxhcd_halt_status
+{
+ HC_XFER_NO_HALT_STATUS, // Initial
+ HC_XFER_COMPLETE, // Xact complete without error, upward
+ HC_XFER_URB_COMPLETE, // Xfer complete without error, short upward
+ HC_XFER_STALL, // HC stopped abnormally, upward/downward
+ HC_XFER_XACT_ERR, // HC stopped abnormally, upward
+ HC_XFER_FRAME_OVERRUN, // HC stopped abnormally, upward
+ HC_XFER_BABBLE_ERR, // HC stopped abnormally, upward
+ HC_XFER_AHB_ERR, // HC stopped abnormally, upward
+ HC_XFER_DATA_TOGGLE_ERR,
+ HC_XFER_URB_DEQUEUE, // HC stopper manually, downward
+ HC_XFER_NO_URB, // HC stopper manually, downward
+ HC_XFER_NO_EPQH, // HC stopper manually, downward
+ #ifdef __NAKSTOP__
+ HC_XFER_NAK, // HC stopped by nak monitor, downward
+ #endif
+ #if defined(__INTRNAKRETRY__) || defined(__INTRINCRETRY__)
+ HC_XFER_INTR_NAK_RETRY, // HC stopped by nak monitor, downward
+ #endif
+} ifxhcd_halt_status_e;
+
+struct ifxhcd_urbd;
+struct ifxhcd_hc ;
+struct ifxhcd_epqh ;
+struct ifxhcd_hcd;
+
+/*! typedef ifxhcd_urbd_t
+ \brief A URB Descriptor (URBD) holds the state of a bulk, control,
+ interrupt, or isochronous transfer. A single URBD is created for each URB
+ (of one of these types) submitted to the HCD. The transfer associated with
+ a URBD may require one or multiple transactions.
+
+ A URBD is linked to a EP Queue Head, which is entered in either the
+ isoc, intr or non-periodic schedule for execution. When a URBD is chosen for
+ execution, some or all of its transactions may be executed. After
+ execution, the state of the URBD is updated. The URBD may be retired if all
+ its transactions are complete or if an error occurred. Otherwise, it
+ remains in the schedule so more transactions can be executed later.
+ */
+typedef struct ifxhcd_urbd {
+ ifxhcd_urbd_phase_e phase;
+ struct list_head ql; // Hook for EPQH->urbd_list
+ struct urb *urb; /*!< URB for this transfer */
+ //struct urb {
+ // struct list_head urb_list;
+ // struct list_head anchor_list;
+ // struct usb_anchor * anchor;
+ // struct usb_device * dev;
+ // struct usb_host_endpoint * ep;
+ // unsigned int pipe;
+ // int status;
+ // unsigned int transfer_flags;
+ // void * transfer_buffer;
+ // dma_addr_t transfer_dma;
+ // u32 transfer_buffer_length;
+ // u32 actual_length;
+ // unsigned char * setup_packet;
+ // dma_addr_t setup_dma;
+ // int start_frame;
+ // int number_of_packets;
+ // int interval;
+ // int error_count;
+ // void * context;
+ // usb_complete_t complete;
+ // struct usb_iso_packet_descriptor iso_frame_desc[0];
+ //};
+ //urb_list For use by current owner of the URB.
+ //anchor_list membership in the list of an anchor
+ //anchor to anchor URBs to a common mooring
+ //dev Identifies the USB device to perform the request.
+ //ep Points to the endpoint's data structure. Will
+ // eventually replace pipe.
+ //pipe Holds endpoint number, direction, type, and more.
+ // Create these values with the eight macros available; u
+ // sb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is
+ // "ctrl", "bulk", "int" or "iso". For example
+ // usb_sndbulkpipe or usb_rcvintpipe. Endpoint numbers
+ // range from zero to fifteen. Note that "in" endpoint two
+ // is a different endpoint (and pipe) from "out" endpoint
+ // two. The current configuration controls the existence,
+ // type, and maximum packet size of any given endpoint.
+ //status This is read in non-iso completion functions to get
+ // the status of the particular request. ISO requests
+ // only use it to tell whether the URB was unlinked;
+ // detailed status for each frame is in the fields of
+ // the iso_frame-desc.
+ //transfer_flags A variety of flags may be used to affect how URB
+ // submission, unlinking, or operation are handled.
+ // Different kinds of URB can use different flags.
+ // URB_SHORT_NOT_OK
+ // URB_ISO_ASAP
+ // URB_NO_TRANSFER_DMA_MAP
+ // URB_NO_SETUP_DMA_MAP
+ // URB_NO_FSBR
+ // URB_ZERO_PACKET
+ // URB_NO_INTERRUPT
+ //transfer_buffer This identifies the buffer to (or from) which the I/O
+ // request will be performed (unless URB_NO_TRANSFER_DMA_MAP
+ // is set). This buffer must be suitable for DMA; allocate it
+ // with kmalloc or equivalent. For transfers to "in"
+ // endpoints, contents of this buffer will be modified. This
+ // buffer is used for the data stage of control transfers.
+ //transfer_dma When transfer_flags includes URB_NO_TRANSFER_DMA_MAP, the
+ // device driver is saying that it provided this DMA address,
+ // which the host controller driver should use in preference
+ // to the transfer_buffer.
+ //transfer_buffer_length How big is transfer_buffer. The transfer may be broken
+ // up into chunks according to the current maximum packet size
+ // for the endpoint, which is a function of the configuration
+ // and is encoded in the pipe. When the length is zero, neither
+ // transfer_buffer nor transfer_dma is used.
+ //actual_length This is read in non-iso completion functions, and it tells
+ // how many bytes (out of transfer_buffer_length) were transferred.
+ // It will normally be the same as requested, unless either an error
+ // was reported or a short read was performed. The URB_SHORT_NOT_OK
+ // transfer flag may be used to make such short reads be reported
+ // as errors.
+ //setup_packet Only used for control transfers, this points to eight bytes of
+ // setup data. Control transfers always start by sending this data
+ // to the device. Then transfer_buffer is read or written, if needed.
+ //setup_dma For control transfers with URB_NO_SETUP_DMA_MAP set, the device
+ // driver has provided this DMA address for the setup packet. The
+ // host controller driver should use this in preference to setup_packet.
+ //start_frame Returns the initial frame for isochronous transfers.
+ //number_of_packets Lists the number of ISO transfer buffers.
+ //interval Specifies the polling interval for interrupt or isochronous transfers.
+ // The units are frames (milliseconds) for for full and low speed devices,
+ // and microframes (1/8 millisecond) for highspeed ones.
+ //error_count Returns the number of ISO transfers that reported errors.
+ //context For use in completion functions. This normally points to request-specific
+ // driver context.
+ //complete Completion handler. This URB is passed as the parameter to the completion
+ // function. The completion function may then do what it likes with the URB,
+ // including resubmitting or freeing it.
+ //iso_frame_desc[0] Used to provide arrays of ISO transfer buffers and to collect the transfer
+ // status for each buffer.
+
+ struct ifxhcd_epqh *epqh;
+ // Actual data portion, not SETUP or STATUS in case of CTRL XFER
+ // DMA adjusted
+ uint8_t *setup_buff; /*!< Pointer to the entire transfer buffer. (CPU accessable)*/
+ uint8_t *xfer_buff; /*!< Pointer to the entire transfer buffer. (CPU accessable)*/
+ uint32_t xfer_len; /*!< Total number of bytes to transfer in this xfer. */
+
+ #if defined(__UNALIGNED_BUF_ADJ__)
+// uint8_t using_aligned_setup;
+ uint8_t *aligned_setup;
+// uint8_t using_aligned_buf;
+ uint8_t *aligned_buf;
+ unsigned aligned_buf_len : 19;
+ #endif
+ #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
+ unsigned aligned_checked : 1;
+ #endif
+ unsigned is_in :1;
+ #ifndef __STRICT_ORDER__
+ struct tasklet_struct complete_urb_sub;
+ #endif
+
+ // For ALL XFER
+ uint8_t error_count; /*!< Holds the number of bus errors that have occurred for a transaction
+ within this transfer.
+ */
+ // For ISOC XFER only
+ #ifdef __EN_ISOC__
+ int isoc_frame_index; /*!< Index of the next frame descriptor for an isochronous transfer. A
+ frame descriptor describes the buffer position and length of the
+ data to be transferred in the next scheduled (micro)frame of an
+ isochronous transfer. It also holds status for that transaction.
+ The frame index starts at 0.
+ */
+ #endif
+ int status;
+} ifxhcd_urbd_t;
+
+/*! typedef ifxhcd_epqh_t
+ \brief A EP Queue Head (EPQH) holds the static characteristics of an endpoint and
+ maintains a list of transfers (URBDs) for that endpoint. A EPQH structure may
+ be entered in either the isoc, intr or non-periodic schedule.
+ */
+
+typedef struct ifxhcd_epqh {
+ struct ifxhcd_hcd *ifxhcd;
+ struct usb_host_endpoint *sysep;
+ uint8_t devno;
+
+ ifxhcd_epqh_phase_e phase;
+ struct list_head ql_all;
+ struct list_head ql; // Hook for EP Queues
+ struct list_head urbd_list; /*!< List of URBDs for this EPQH. */
+ #ifdef __STRICT_ORDER__
+ struct list_head release_list;
+ struct tasklet_struct complete_urb_sub;
+ #endif
+ struct ifxhcd_hc *hc; /*!< Host channel currently processing transfers for this EPQH. */
+ struct ifxhcd_urbd *urbd; /*!< URBD currently assigned to a host channel for this EPQH. */
+ uint8_t ep_type; /*!< Endpoint type. One of the following values:
+ - IFXUSB_EP_TYPE_CTRL
+ - IFXUSB_EP_TYPE_ISOC
+ - IFXUSB_EP_TYPE_BULK
+ - IFXUSB_EP_TYPE_INTR
+ */
+ uint16_t mps; /*!< wMaxPacketSize Field of Endpoint Descriptor. */
+ #ifdef __EPQD_DESTROY_TIMEOUT__
+ struct timer_list destroy_timer;
+ #endif
+
+ unsigned need_split : 1 ;
+ unsigned do_ping : 1 ; /*!< Set to 1 to indicate that a PING request should be issued on this
+ channel. If 0, process normally.
+ */
+ unsigned pause : 1;
+ unsigned period_do : 1;
+ uint16_t interval; /*!< Interval between transfers in (micro)frames. (for INTR)*/
+ uint16_t period_counter; /*!< Interval between transfers in (micro)frames. */
+
+ #ifdef __EN_ISOC__
+ struct tasklet_struct tasklet_next_isoc;
+ uint8_t isoc_now;
+ uint32_t isoc_start_frame;
+ // For SPLITed ISOC XFER only
+ #ifdef __EN_ISOC_SPLIT__
+ uint8_t isoc_split_pos; /*!< Position of the ISOC split on full/low speed */
+ uint16_t isoc_split_offset;/*!< Position of the ISOC split in the buffer for the current frame */
+ #endif
+ #endif
+ spinlock_t urbd_list_lock;
+ int urbd_count;
+} ifxhcd_epqh_t;
+
+
+/*! typedef ifxhcd_hc_t
+ \brief Host channel descriptor. This structure represents the state of a single
+ host channel when acting in host mode. It contains the data items needed to
+ transfer packets to an endpoint via a host channel.
+ */
+typedef struct ifxhcd_hc
+{
+ struct ifxhcd_epqh *epqh ; /*!< EP Queue Head for the transfer being processed by this channel. */
+ uint8_t hc_num ; /*!< Host channel number used for register address lookup */
+ uint8_t *xfer_buff ; /*!< Pointer to the entire transfer buffer. */
+ uint32_t xfer_count ; /*!< Number of bytes transferred so far. The offset of the begin of the buf */
+ uint32_t xfer_len ; /*!< Total number of bytes to transfer in this xfer. */
+ uint16_t start_pkt_count ; /*!< Packet count at start of transfer. Used to calculate the actual xfer size*/
+ ifxhcd_halt_status_e halt_status; /*!< Reason for halting the host channel. */
+ ifxhcd_hc_phase_e phase;
+
+ unsigned dev_addr : 7; /*!< Device to access */
+ unsigned ep_num : 4; /*!< EP to access */
+ unsigned is_in : 1; /*!< EP direction. 0: OUT, 1: IN */
+ unsigned speed : 2; /*!< EP speed. */
+ unsigned ep_type : 2; /*!< Endpoint type. */
+ unsigned mps :11; /*!< Max packet size in bytes */
+ unsigned data_pid_start : 2; /*!< PID for initial transaction. */
+ unsigned short_rw : 1; /*!< When Tx, means termination needed.
+ When Rx, indicate Short Read */
+ /* Split settings for the host channel */
+ unsigned split : 2; /*!< Split: 0-Non Split, 1-SSPLIT, 2&3 CSPLIT */
+
+ unsigned sof_delay :16;
+ unsigned erron : 1;
+
+ #ifdef __NAKSTOP__
+ unsigned stop_on : 1;
+// unsigned wait_for_sof_quick : 1;
+ #endif
+
+ ifxhcd_control_phase_e control_phase; /*!< Current phase for control transfers (Setup, Data, or Status). */
+ uint32_t ssplit_out_xfer_count; /*!< How many bytes transferred during SSPLIT OUT */
+ #ifdef __DEBUG__
+ uint32_t start_hcchar_val;
+ #endif
+ uint32_t hcchar;
+
+ /* Split settings for the host channel */
+ uint8_t hub_addr; /*!< Address of high speed hub */
+ uint8_t port_addr; /*!< Port of the low/full speed device */
+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
+ uint8_t isoc_xact_pos; /*!< Split transaction position */
+ #endif
+} ifxhcd_hc_t;
+
+
+/*! typedef ifxhcd_hcd_t
+ \brief This structure holds the state of the HCD, including the non-periodic and
+ periodic schedules.
+ */
+typedef struct ifxhcd_hcd
+{
+ struct device *dev;
+ struct hc_driver hc_driver;
+ ifxusb_core_if_t core_if; /*!< Pointer to the core interface structure. */
+ struct usb_hcd *syshcd;
+
+ volatile union
+ {
+ uint32_t d32;
+ struct
+ {
+ unsigned port_connect_status_change : 1;
+ unsigned port_connect_status : 1;
+ unsigned port_reset_change : 1;
+ unsigned port_enable_change : 1;
+ unsigned port_suspend_change : 1;
+ unsigned port_over_current_change : 1;
+ unsigned reserved : 27;
+ } b;
+ } flags; /*!< Internal HCD Flags */
+
+ struct ifxhcd_hc ifxhc[MAX_EPS_CHANNELS]; /*!< Array of pointers to the host channel descriptors. Allows accessing
+ a host channel descriptor given the host channel number. This is
+ useful in interrupt handlers.
+ */
+ uint8_t *status_buf; /*!< Buffer to use for any data received during the status phase of a
+ control transfer. Normally no data is transferred during the status
+ phase. This buffer is used as a bit bucket.
+ */
+ #define IFXHCD_STATUS_BUF_SIZE 64 /*!< buffer size of status phase in CTRL xfer */
+
+ struct list_head epqh_list_all;
+ struct list_head epqh_list_np;
+ struct list_head epqh_list_intr;
+ #ifdef __EN_ISOC__
+ struct list_head epqh_list_isoc;
+ #endif
+
+ uint32_t lastframe;
+
+ uint16_t pkt_remaining;
+ uint16_t pkt_remaining_reload;
+ uint16_t pkt_remaining_reload_hs;
+ uint16_t pkt_remaining_reload_fs;
+ uint16_t pkt_remaining_reload_ls;
+ #define PKT_REMAINING_RELOAD_HS 88
+ #define PKT_REMAINING_RELOAD_FS 10
+ #define PKT_REMAINING_RELOAD_LS 20
+ #ifdef __EN_ISOC__
+ uint8_t isoc_ep_count;
+ #endif
+
+ spinlock_t epqh_list_lock;
+ spinlock_t epqh_list_all_lock;
+
+ struct timer_list host_probe_timer;
+ struct timer_list autoprobe_timer;
+
+ unsigned power_status;
+ int probe_sec;
+ int autoprobe_sec;
+ #ifdef __DYN_SOF_INTR__
+ uint32_t dyn_sof_count;
+ #define DYN_SOF_COUNT_DEF 40000
+ #endif
+ struct tasklet_struct tasklet_select_eps; /*!< Tasket to do a reset */
+ struct tasklet_struct tasklet_free_epqh_list ; /*!< Tasket to do a reset */
+ unsigned disconnecting : 1 ;
+
+ uint8_t pkt_count_limit_bo;
+ uint8_t pkt_count_limit_bi;
+} ifxhcd_hcd_t;
+
+/* Gets the ifxhcd_hcd from a struct usb_hcd */
+static inline ifxhcd_hcd_t *syshcd_to_ifxhcd(struct usb_hcd *syshcd)
+{
+ return (ifxhcd_hcd_t *)(syshcd->hcd_priv[0]);
+}
+
+/* Gets the struct usb_hcd that contains a ifxhcd_hcd_t. */
+static inline struct usb_hcd *ifxhcd_to_syshcd(ifxhcd_hcd_t *ifxhcd)
+{
+ return (struct usb_hcd *)(ifxhcd->syshcd);
+}
+
+
+extern ifxhcd_epqh_t * sysep_to_epqh(ifxhcd_hcd_t *_ifxhcd, struct usb_host_endpoint *_sysep);
+
+/* HCD Create/Destroy Functions */
+ extern int ifxhcd_init (ifxhcd_hcd_t *_ifxhcd);
+ extern void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd);
+
+/*Linux HC Driver API Functions */
+
+extern int ifxhcd_start(struct usb_hcd *hcd);
+extern void ifxhcd_stop (struct usb_hcd *hcd);
+extern int ifxhcd_get_frame_number(struct usb_hcd *hcd);
+
+
+/*!
+ \brief This function does the setup for a data transfer for a host channel and
+ starts the transfer. May be called in either Slave mode or DMA mode. In
+ Slave mode, the caller must ensure that there is sufficient space in the
+ request queue and Tx Data FIFO.
+
+ For an OUT transfer in Slave mode, it loads a data packet into the
+ appropriate FIFO. If necessary, additional data packets will be loaded in
+ the Host ISR.
+
+ For an IN transfer in Slave mode, a data packet is requested. The data
+ packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
+ additional data packets are requested in the Host ISR.
+
+ For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
+ register along with a packet count of 1 and the channel is enabled. This
+ causes a single PING transaction to occur. Other fields in HCTSIZ are
+ simply set to 0 since no data transfer occurs in this case.
+
+ For a PING transfer in DMA mode, the HCTSIZ register is initialized with
+ all the information required to perform the subsequent data transfer. In
+ addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
+ controller performs the entire PING protocol, then starts the data
+ transfer.
+
+ @param _ifxhc Information needed to initialize the host channel. The xfer_len
+ value may be reduced to accommodate the max widths of the XferSize and
+ PktCnt fields in the HCTSIZn register. The multi_count value may be changed
+ to reflect the final xfer_len value.
+ */
+extern void ifxhcd_hc_start(ifxhcd_hcd_t *_ifxhcd, ifxhcd_hc_t *_ifxhc);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+extern int ifxhcd_urb_enqueue(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep, struct urb *_urb, gfp_t mem_flags);
+extern int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb);
+#else
+extern int ifxhcd_urb_enqueue(struct usb_hcd *_syshcd, struct urb *_urb, gfp_t mem_flags);
+extern int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb, int status);
+#endif
+extern irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd);
+
+extern void ifxhcd_endpoint_disable(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep);
+
+extern int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf);
+extern int ifxhcd_hub_control( struct usb_hcd *_syshcd,
+ u16 _typeReq,
+ u16 _wValue,
+ u16 _wIndex,
+ char *_buf,
+ u16 _wLength);
+
+/*@}*/
+
+/*! \brief Transaction Execution Functions */
+/*@{*/
+extern void ifxhcd_complete_urb (ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status);
+
+/*!
+ \brief Clears the transfer state for a host channel. This function is normally
+ called after a transfer is done and the host channel is being released.
+ */
+extern void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc);
+
+/*!
+ \brief Attempts to halt a host channel. This function should only be called in
+ Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
+ normal circumstances in DMA mode, the controller halts the channel when the
+ transfer is complete or a condition occurs that requires application
+ intervention.
+
+ In DMA mode, always sets the Channel Enable and Channel Disable bits of the
+ HCCHARn register. The controller ensures there is space in the request
+ queue before submitting the halt request.
+
+ Some time may elapse before the core flushes any posted requests for this
+ host channel and halts. The Channel Halted interrupt handler completes the
+ deactivation of the host channel.
+ */
+extern int ifxhcd_hc_halt(ifxusb_core_if_t *_core_if,
+ ifxhcd_hc_t *_ifxhc,
+ ifxhcd_halt_status_e _halt_status);
+
+/*!
+ \brief Prepares a host channel for transferring packets to/from a specific
+ endpoint. The HCCHARn register is set up with the characteristics specified
+ in _ifxhc. Host channel interrupts that may need to be serviced while this
+ transfer is in progress are enabled.
+ */
+extern void ifxhcd_hc_init(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc);
+
+/*!
+ \brief This function is called to handle the disconnection of host port.
+ */
+int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd);
+/*@}*/
+
+/*! \brief Interrupt Handler Functions */
+/*@{*/
+extern irqreturn_t ifxhcd_oc_irq(int _irq, void *_dev);
+
+extern int32_t ifxhcd_handle_oc_intr(ifxhcd_hcd_t *_ifxhcd);
+extern int32_t ifxhcd_handle_intr (ifxhcd_hcd_t *_ifxhcd);
+/*@}*/
+
+
+/*! \brief Schedule Queue Functions */
+/*@{*/
+extern void ifxhcd_epqh_free (ifxhcd_epqh_t *_epqh);
+extern void select_eps (ifxhcd_hcd_t *_ifxhcd);
+extern void ifxhcd_epqh_idle(ifxhcd_epqh_t *_epqh);
+extern void ifxhcd_epqh_idle_periodic(ifxhcd_epqh_t *_epqh);
+extern ifxhcd_epqh_t *ifxhcd_urbd_create (ifxhcd_hcd_t *_ifxhcd,struct urb *_urb);
+/*@}*/
+
+/*! \brief Gets the usb_host_endpoint associated with an URB. */
+static inline struct usb_host_endpoint *ifxhcd_urb_to_endpoint(struct urb *_urb)
+{
+ struct usb_device *dev = _urb->dev;
+ int ep_num = usb_pipeendpoint(_urb->pipe);
+
+ return (usb_pipein(_urb->pipe))?(dev->ep_in[ep_num]):(dev->ep_out[ep_num]);
+}
+
+/*!
+ * \brief Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
+ * qualified with its direction (possible 32 endpoints per device).
+ */
+#define ifxhcd_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
+ ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
+
+
+
+/*! Internal debug function */
+void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd);
+
+/*@}*//*IFXUSB_HCD*/
+
+extern struct usb_device *usb_alloc_dev (struct usb_device *parent, struct usb_bus *, unsigned port);
+extern int usb_add_hcd (struct usb_hcd *syshcd, unsigned int irqnum, unsigned long irqflags);
+extern void usb_remove_hcd (struct usb_hcd *syshcd);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, struct device *dev, char *bus_name);
+#else
+extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, struct device *dev, const char *bus_name);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+extern void usb_hcd_giveback_urb (struct usb_hcd *syshcd, struct urb *urb);
+#else
+extern void usb_hcd_giveback_urb (struct usb_hcd *syshcd, struct urb *urb,int status);
+#endif
+
+extern void usb_put_hcd (struct usb_hcd *syshcd);
+extern long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount);
+extern char *syserr(int errno);
+
+
+
+static inline void INIT_EPQH_LIST_ALL(ifxhcd_hcd_t *_ifxhcd)
+{
+ spin_lock_init(&_ifxhcd->epqh_list_all_lock);
+}
+static inline void LOCK_EPQH_LIST_ALL(ifxhcd_hcd_t *_ifxhcd)
+{
+ spin_lock(&_ifxhcd->epqh_list_all_lock);
+}
+static inline void UNLOCK_EPQH_LIST_ALL(ifxhcd_hcd_t *_ifxhcd)
+{
+ spin_unlock(&_ifxhcd->epqh_list_all_lock);
+}
+
+static inline void INIT_EPQH_LIST(ifxhcd_hcd_t *_ifxhcd)
+{
+ spin_lock_init(&_ifxhcd->epqh_list_lock);
+}
+static inline void LOCK_EPQH_LIST(ifxhcd_hcd_t *_ifxhcd)
+{
+ spin_lock(&_ifxhcd->epqh_list_lock);
+}
+static inline void UNLOCK_EPQH_LIST(ifxhcd_hcd_t *_ifxhcd)
+{
+ spin_unlock(&_ifxhcd->epqh_list_lock);
+}
+
+static inline void INIT_URBD_LIST(ifxhcd_epqh_t *_epqh)
+{
+ spin_lock_init(&_epqh->urbd_list_lock);
+}
+static inline void LOCK_URBD_LIST(ifxhcd_epqh_t *_epqh)
+{
+ spin_lock(&_epqh->urbd_list_lock);
+}
+static inline void UNLOCK_URBD_LIST(ifxhcd_epqh_t *_epqh)
+{
+ spin_unlock(&_epqh->urbd_list_lock);
+}
+
+#endif // __IFXHCD_H__
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxhcd_es.c b/package/kernel/lantiq/ltq-hcd/src/ifxhcd_es.c
new file mode 100644
index 0000000000..a7d18dd7fe
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxhcd_es.c
@@ -0,0 +1,599 @@
+/*****************************************************************************
+ ** FILE NAME : ifxhcd_es.c
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 1.0
+ ** DATE : 1/Jan/2009
+ ** AUTHOR : Chen, Howard
+ ** DESCRIPTION : The file contain function to enable host mode USB-IF Electrical Test function.
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*!
+ \file ifxhcd_es.c
+ \ingroup IFXUSB_DRIVER_V3
+ \brief The file contain function to enable host mode USB-IF Electrical Test function.
+*/
+
+#include <linux/version.h>
+#include "ifxusb_version.h"
+
+#include <linux/kernel.h>
+
+#include <linux/errno.h>
+
+#include <linux/dma-mapping.h>
+
+#include "ifxusb_plat.h"
+#include "ifxusb_regs.h"
+#include "ifxusb_cif.h"
+#include "ifxhcd.h"
+
+
+#ifdef __WITH_HS_ELECT_TST__
+ /*
+ * Quick and dirty hack to implement the HS Electrical Test
+ * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
+ *
+ * This code was copied from our userspace app "hset". It sends a
+ * Get Device Descriptor control sequence in two parts, first the
+ * Setup packet by itself, followed some time later by the In and
+ * Ack packets. Rather than trying to figure out how to add this
+ * functionality to the normal driver code, we just hijack the
+ * hardware, using these two function to drive the hardware
+ * directly.
+ */
+
+
+ void do_setup(ifxusb_core_if_t *_core_if)
+ {
+
+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
+ ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
+ ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0];
+ uint32_t *data_fifo = _core_if->data_fifo[0];
+
+ gint_data_t gintsts;
+ hctsiz_data_t hctsiz;
+ hcchar_data_t hcchar;
+ haint_data_t haint;
+ hcint_data_t hcint;
+
+
+ /* Enable HAINTs */
+ ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
+
+ /* Enable HCINTs */
+ ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
+
+ /* Read GINTSTS */
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
+
+ /* Read HAINT */
+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
+
+ /* Read HCINT */
+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
+
+ /* Read HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
+
+ /* Clear HCINT */
+ ifxusb_wreg(&hc_regs->hcint, hcint.d32);
+
+ /* Clear HAINT */
+ ifxusb_wreg(&hc_global_regs->haint, haint.d32);
+
+ /* Clear GINTSTS */
+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
+
+ /* Read GINTSTS */
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
+
+ /*
+ * Send Setup packet (Get Device Descriptor)
+ */
+
+ /* Make sure channel is disabled */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ if (hcchar.b.chen) {
+ //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
+ hcchar.b.chdis = 1;
+ // hcchar.b.chen = 1;
+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
+ //sleep(1);
+ mdelay(1000);
+
+ /* Read GINTSTS */
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
+
+ /* Read HAINT */
+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
+
+ /* Read HCINT */
+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
+
+ /* Read HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
+
+ /* Clear HCINT */
+ ifxusb_wreg(&hc_regs->hcint, hcint.d32);
+
+ /* Clear HAINT */
+ ifxusb_wreg(&hc_global_regs->haint, haint.d32);
+
+ /* Clear GINTSTS */
+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
+
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //if (hcchar.b.chen) {
+ // fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
+ //}
+ }
+
+ /* Set HCTSIZ */
+ hctsiz.d32 = 0;
+ hctsiz.b.xfersize = 8;
+ hctsiz.b.pktcnt = 1;
+ hctsiz.b.pid = IFXUSB_HC_PID_SETUP;
+ ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
+
+ /* Set HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
+ hcchar.b.epdir = 0;
+ hcchar.b.epnum = 0;
+ hcchar.b.mps = 8;
+ hcchar.b.chen = 1;
+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
+
+ /* Fill FIFO with Setup data for Get Device Descriptor */
+ ifxusb_wreg(data_fifo++, 0x01000680);
+ ifxusb_wreg(data_fifo++, 0x00080000);
+
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
+
+ /* Wait for host channel interrupt */
+ do {
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ } while (gintsts.b.hcintr == 0);
+
+ //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
+
+ /* Disable HCINTs */
+ ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
+
+ /* Disable HAINTs */
+ ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
+
+ /* Read HAINT */
+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
+
+ /* Read HCINT */
+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
+
+ /* Read HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
+
+ /* Clear HCINT */
+ ifxusb_wreg(&hc_regs->hcint, hcint.d32);
+
+ /* Clear HAINT */
+ ifxusb_wreg(&hc_global_regs->haint, haint.d32);
+
+ /* Clear GINTSTS */
+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
+
+ /* Read GINTSTS */
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
+ }
+
+ void do_in_ack(ifxusb_core_if_t *_core_if)
+ {
+
+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
+ ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
+ ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0];
+ uint32_t *data_fifo = _core_if->data_fifo[0];
+
+ gint_data_t gintsts;
+ hctsiz_data_t hctsiz;
+ hcchar_data_t hcchar;
+ haint_data_t haint;
+ hcint_data_t hcint;
+ grxsts_data_t grxsts;
+
+ /* Enable HAINTs */
+ ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
+
+ /* Enable HCINTs */
+ ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
+
+ /* Read GINTSTS */
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
+
+ /* Read HAINT */
+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
+
+ /* Read HCINT */
+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
+
+ /* Read HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
+
+ /* Clear HCINT */
+ ifxusb_wreg(&hc_regs->hcint, hcint.d32);
+
+ /* Clear HAINT */
+ ifxusb_wreg(&hc_global_regs->haint, haint.d32);
+
+ /* Clear GINTSTS */
+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
+
+ /* Read GINTSTS */
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
+
+ /*
+ * Receive Control In packet
+ */
+
+ /* Make sure channel is disabled */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ if (hcchar.b.chen) {
+ //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
+ hcchar.b.chdis = 1;
+ hcchar.b.chen = 1;
+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
+ //sleep(1);
+ mdelay(1000);
+
+ /* Read GINTSTS */
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
+
+ /* Read HAINT */
+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
+
+ /* Read HCINT */
+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
+
+ /* Read HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
+
+ /* Clear HCINT */
+ ifxusb_wreg(&hc_regs->hcint, hcint.d32);
+
+ /* Clear HAINT */
+ ifxusb_wreg(&hc_global_regs->haint, haint.d32);
+
+ /* Clear GINTSTS */
+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
+
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //if (hcchar.b.chen) {
+ // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
+ //}
+ }
+
+ /* Set HCTSIZ */
+ hctsiz.d32 = 0;
+ hctsiz.b.xfersize = 8;
+ hctsiz.b.pktcnt = 1;
+ hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
+ ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
+
+ /* Set HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
+ hcchar.b.epdir = 1;
+ hcchar.b.epnum = 0;
+ hcchar.b.mps = 8;
+ hcchar.b.chen = 1;
+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
+
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
+
+ /* Wait for receive status queue interrupt */
+ do {
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ } while (gintsts.b.rxstsqlvl == 0);
+
+ //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
+
+ /* Read RXSTS */
+ grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
+ //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
+
+ /* Clear RXSTSQLVL in GINTSTS */
+ gintsts.d32 = 0;
+ gintsts.b.rxstsqlvl = 1;
+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
+
+ switch (grxsts.hb.pktsts) {
+ case IFXUSB_HSTS_DATA_UPDT:
+ /* Read the data into the host buffer */
+ if (grxsts.hb.bcnt > 0) {
+ int i;
+ int word_count = (grxsts.hb.bcnt + 3) / 4;
+
+ for (i = 0; i < word_count; i++) {
+ (void)ifxusb_rreg(data_fifo++);
+ }
+ }
+
+ //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.hb.bcnt);
+ break;
+
+ default:
+ //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
+ break;
+ }
+
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
+
+ /* Wait for receive status queue interrupt */
+ do {
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ } while (gintsts.b.rxstsqlvl == 0);
+
+ //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
+
+ /* Read RXSTS */
+ grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
+ //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
+
+ /* Clear RXSTSQLVL in GINTSTS */
+ gintsts.d32 = 0;
+ gintsts.b.rxstsqlvl = 1;
+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
+
+ switch (grxsts.hb.pktsts) {
+ case IFXUSB_HSTS_XFER_COMP:
+ break;
+
+ default:
+ //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
+ break;
+ }
+
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
+
+ /* Wait for host channel interrupt */
+ do {
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ } while (gintsts.b.hcintr == 0);
+
+ //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
+
+ /* Read HAINT */
+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
+
+ /* Read HCINT */
+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
+
+ /* Read HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
+
+ /* Clear HCINT */
+ ifxusb_wreg(&hc_regs->hcint, hcint.d32);
+
+ /* Clear HAINT */
+ ifxusb_wreg(&hc_global_regs->haint, haint.d32);
+
+ /* Clear GINTSTS */
+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
+
+ /* Read GINTSTS */
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
+
+ // usleep(100000);
+ // mdelay(100);
+ mdelay(1);
+
+ /*
+ * Send handshake packet
+ */
+
+ /* Read HAINT */
+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
+
+ /* Read HCINT */
+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
+
+ /* Read HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
+
+ /* Clear HCINT */
+ ifxusb_wreg(&hc_regs->hcint, hcint.d32);
+
+ /* Clear HAINT */
+ ifxusb_wreg(&hc_global_regs->haint, haint.d32);
+
+ /* Clear GINTSTS */
+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
+
+ /* Read GINTSTS */
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
+
+ /* Make sure channel is disabled */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ if (hcchar.b.chen) {
+ //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
+ hcchar.b.chdis = 1;
+ hcchar.b.chen = 1;
+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
+ //sleep(1);
+ mdelay(1000);
+
+ /* Read GINTSTS */
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
+
+ /* Read HAINT */
+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
+
+ /* Read HCINT */
+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
+
+ /* Read HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
+
+ /* Clear HCINT */
+ ifxusb_wreg(&hc_regs->hcint, hcint.d32);
+
+ /* Clear HAINT */
+ ifxusb_wreg(&hc_global_regs->haint, haint.d32);
+
+ /* Clear GINTSTS */
+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
+
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //if (hcchar.b.chen) {
+ // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
+ //}
+ }
+
+ /* Set HCTSIZ */
+ hctsiz.d32 = 0;
+ hctsiz.b.xfersize = 0;
+ hctsiz.b.pktcnt = 1;
+ hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
+ ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
+
+ /* Set HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
+ hcchar.b.epdir = 0;
+ hcchar.b.epnum = 0;
+ hcchar.b.mps = 8;
+ hcchar.b.chen = 1;
+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
+
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
+
+ /* Wait for host channel interrupt */
+ do {
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ } while (gintsts.b.hcintr == 0);
+
+ //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
+
+ /* Disable HCINTs */
+ ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
+
+ /* Disable HAINTs */
+ ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
+
+ /* Read HAINT */
+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
+
+ /* Read HCINT */
+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
+
+ /* Read HCCHAR */
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
+
+ /* Clear HCINT */
+ ifxusb_wreg(&hc_regs->hcint, hcint.d32);
+
+ /* Clear HAINT */
+ ifxusb_wreg(&hc_global_regs->haint, haint.d32);
+
+ /* Clear GINTSTS */
+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
+
+ /* Read GINTSTS */
+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
+ }
+#endif //__WITH_HS_ELECT_TST__
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxhcd_intr.c b/package/kernel/lantiq/ltq-hcd/src/ifxhcd_intr.c
new file mode 100644
index 0000000000..27885bb860
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxhcd_intr.c
@@ -0,0 +1,4844 @@
+/*****************************************************************************
+ ** FILE NAME : ifxhcd_intr.c
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** AUTHOR : Chen, Howard
+ ** DESCRIPTION : This file contains the implementation of the HCD Interrupt handlers.
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*!
+ \file ifxhcd_intr.c
+ \ingroup IFXUSB_DRIVER_V3
+ \brief This file contains the implementation of the HCD Interrupt handlers.
+*/
+
+
+#include <linux/version.h>
+#include "ifxusb_version.h"
+
+#include "ifxusb_plat.h"
+#include "ifxusb_regs.h"
+#include "ifxusb_cif.h"
+
+#include "ifxhcd.h"
+
+/* Macro used to clear one channel interrupt */
+#define clear_hc_int(_hc_regs_,_intr_) \
+ do { \
+ hcint_data_t hcint_clear = {.d32 = 0}; \
+ hcint_clear.b._intr_ = 1; \
+ ifxusb_wreg(&((_hc_regs_)->hcint), hcint_clear.d32); \
+ } while (0)
+
+/*
+ * Macro used to disable one channel interrupt. Channel interrupts are
+ * disabled when the channel is halted or released by the interrupt handler.
+ * There is no need to handle further interrupts of that type until the
+ * channel is re-assigned. In fact, subsequent handling may cause crashes
+ * because the channel structures are cleaned up when the channel is released.
+ */
+#define disable_hc_int(_hc_regs_,_intr_) \
+ do { \
+ hcint_data_t hcintmsk = {.d32 = 0}; \
+ hcintmsk.b._intr_ = 1; \
+ ifxusb_mreg(&((_hc_regs_)->hcintmsk), hcintmsk.d32, 0); \
+ } while (0)
+
+#define enable_hc_int(_hc_regs_,_intr_) \
+ do { \
+ hcint_data_t hcintmsk = {.d32 = 0}; \
+ hcintmsk.b._intr_ = 1; \
+ ifxusb_mreg(&((_hc_regs_)->hcintmsk),0, hcintmsk.d32); \
+ } while (0)
+
+/*
+ * Save the starting data toggle for the next transfer. The data toggle is
+ * saved in the QH for non-control transfers and it's saved in the QTD for
+ * control transfers.
+ */
+uint8_t read_data_toggle(ifxusb_hc_regs_t *_hc_regs)
+{
+ hctsiz_data_t hctsiz;
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ return(hctsiz.b.pid);
+}
+
+
+static void release_channel_dump(ifxhcd_hc_t *ifxhc,
+ struct urb *urb,
+ ifxhcd_epqh_t *epqh,
+ ifxhcd_urbd_t *urbd,
+ ifxhcd_halt_status_e halt_status)
+{
+ #ifdef __DEBUG__
+ printk(KERN_INFO);
+ switch (halt_status)
+ {
+ case HC_XFER_NO_HALT_STATUS:
+ printk("HC_XFER_NO_HALT_STATUS");break;
+ case HC_XFER_URB_COMPLETE:
+ printk("HC_XFER_URB_COMPLETE");break;
+ case HC_XFER_AHB_ERR:
+ printk("HC_XFER_AHB_ERR");break;
+ case HC_XFER_STALL:
+ printk("HC_XFER_STALL");break;
+ case HC_XFER_BABBLE_ERR:
+ printk("HC_XFER_BABBLE_ERR");break;
+ case HC_XFER_XACT_ERR:
+ printk("HC_XFER_XACT_ERR");break;
+ case HC_XFER_URB_DEQUEUE:
+ printk("HC_XFER_URB_DEQUEUE");break;
+ case HC_XFER_FRAME_OVERRUN:
+ printk("HC_XFER_FRAME_OVERRUN");break;
+ case HC_XFER_DATA_TOGGLE_ERR:
+ printk("HC_XFER_DATA_TOGGLE_ERR");break;
+ #ifdef __NAKSTOP__
+ case HC_XFER_NAK:
+ printk("HC_XFER_NAK");break;
+ #endif
+ case HC_XFER_COMPLETE:
+ printk("HC_XFER_COMPLETE");break;
+ default:
+ printk("KNOWN");break;
+ }
+ if(ifxhc)
+ printk("Ch %d %s%s S%d " , ifxhc->hc_num
+ ,(ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL)?"CTRL-":
+ ((ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)?"BULK-":
+ ((ifxhc->ep_type == IFXUSB_EP_TYPE_INTR)?"INTR-":
+ ((ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)?"ISOC-":"????"
+ )
+ )
+ )
+ ,(ifxhc->is_in)?"IN":"OUT"
+ ,(ifxhc->split)
+ );
+ else
+ printk(" [NULL HC] ");
+ printk("urb=%p epqh=%p urbd=%p\n",urb,epqh,urbd);
+
+ if(urb)
+ {
+ printk(KERN_INFO " Device address: %d\n", usb_pipedevice(urb->pipe));
+ printk(KERN_INFO " Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
+ (usb_pipein(urb->pipe) ? "IN" : "OUT"));
+ printk(KERN_INFO " Endpoint type: %s\n",
+ ({char *pipetype;
+ switch (usb_pipetype(urb->pipe)) {
+ case PIPE_CONTROL: pipetype = "CTRL"; break;
+ case PIPE_BULK: pipetype = "BULK"; break;
+ case PIPE_INTERRUPT: pipetype = "INTR"; break;
+ case PIPE_ISOCHRONOUS: pipetype = "ISOC"; break;
+ default: pipetype = "????"; break;
+ }; pipetype;}));
+ printk(KERN_INFO " Speed: %s\n",
+ ({char *speed;
+ switch (urb->dev->speed) {
+ case USB_SPEED_HIGH: speed = "HS"; break;
+ case USB_SPEED_FULL: speed = "FS"; break;
+ case USB_SPEED_LOW: speed = "LS"; break;
+ default: speed = "????"; break;
+ }; speed;}));
+ printk(KERN_INFO " Max packet size: %d\n",
+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
+ printk(KERN_INFO " Data buffer length: %d/%d\n",urb->actual_length, urb->transfer_buffer_length);
+ printk(KERN_INFO " Transfer buffer: %p, Transfer DMA: %p\n",
+ urb->transfer_buffer, (void *)urb->transfer_dma);
+ printk(KERN_INFO " Setup buffer: %p, Setup DMA: %p\n",
+ urb->setup_packet, (void *)urb->setup_dma);
+ printk(KERN_INFO " Interval: %d\n", urb->interval);
+ }
+ if(urbd)
+ {
+ switch (urbd->status)
+ {
+ case HC_XFER_NO_HALT_STATUS:
+ printk(KERN_INFO " STATUS:HC_XFER_NO_HALT_STATUS\n");break;
+ case HC_XFER_URB_COMPLETE:
+ printk(KERN_INFO " STATUS:HC_XFER_URB_COMPLETE\n");break;
+ case HC_XFER_AHB_ERR:
+ printk(KERN_INFO " STATUS:HC_XFER_AHB_ERR\n");break;
+ case HC_XFER_STALL:
+ printk(KERN_INFO " STATUS:HC_XFER_STALL\n");break;
+ case HC_XFER_BABBLE_ERR:
+ printk(KERN_INFO " STATUS:HC_XFER_BABBLE_ERR\n");break;
+ case HC_XFER_XACT_ERR:
+ printk(KERN_INFO " STATUS:HC_XFER_XACT_ERR\n");break;
+ case HC_XFER_URB_DEQUEUE:
+ printk(KERN_INFO " STATUS:HC_XFER_URB_DEQUEUE\n");break;
+ case HC_XFER_FRAME_OVERRUN:
+ printk(KERN_INFO " STATUS:HC_XFER_FRAME_OVERRUN\n");break;
+ case HC_XFER_DATA_TOGGLE_ERR:
+ printk(KERN_INFO " STATUS:HC_XFER_DATA_TOGGLE_ERR\n");break;
+ case HC_XFER_COMPLETE:
+ printk(KERN_INFO " STATUS:HC_XFER_COMPLETE\n");break;
+ default:
+ printk(KERN_INFO " STATUS:UNKKNOWN %d\n",urbd->status);break;
+ }
+ }
+ #endif
+}
+
+/*!
+ \fn static void release_channel(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxhcd_halt_status_e _halt_status)
+ \brief Release the halted channel.
+ \param _ifxhcd Pointer to the sate of HCD structure
+ \param _ifxhc Pointer to host channel descriptor
+ \param _halt_status Halt satus
+ \return None
+ \ingroup IFXUSB_HCD
+ */
+
+static void release_channel(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxhcd_halt_status_e _halt_status)
+{
+ ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[_ifxhc->hc_num];
+ struct urb *urb = NULL;
+ ifxhcd_epqh_t *epqh = NULL;
+ ifxhcd_urbd_t *urbd = NULL;
+
+ IFX_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n",
+ __func__, _ifxhc->hc_num, _halt_status);
+
+ epqh=_ifxhc->epqh;
+
+ if(!epqh)
+ {
+ if(_halt_status!=HC_XFER_NO_EPQH)
+ IFX_ERROR("%s epqh=null\n",__func__);
+ }
+ else
+ {
+ urbd=epqh->urbd;
+ if(!urbd)
+ IFX_ERROR("%s urbd=null\n",__func__);
+ else
+ {
+ urb=urbd->urb;
+ if(!urb)
+ {
+ if(_halt_status!=HC_XFER_NO_URB)
+ IFX_ERROR("%s urb =null\n",__func__);
+ }
+ else
+ {
+ if (read_data_toggle(hc_regs) == IFXUSB_HCTSIZ_DATA0)
+ usb_settoggle (urb->dev,usb_pipeendpoint (urb->pipe), (_ifxhc->is_in)?0:1,0);
+ else if (read_data_toggle(hc_regs) == IFXUSB_HCTSIZ_DATA1)
+ usb_settoggle (urb->dev,usb_pipeendpoint (urb->pipe), (_ifxhc->is_in)?0:1,1);
+ }
+ }
+ }
+
+ switch (_halt_status)
+ {
+ case HC_XFER_NO_HALT_STATUS:
+ IFX_ERROR("%s: No halt_status, channel %d\n", __func__, _ifxhc->hc_num);
+// return;
+ break;
+ case HC_XFER_COMPLETE:
+ IFX_ERROR("%s: Inavalid halt_status HC_XFER_COMPLETE, channel %d\n", __func__, _ifxhc->hc_num);
+// return;
+ break;
+ case HC_XFER_NO_URB:
+ break;
+ case HC_XFER_NO_EPQH:
+ break;
+ case HC_XFER_URB_DEQUEUE:
+ case HC_XFER_AHB_ERR:
+ case HC_XFER_XACT_ERR:
+ case HC_XFER_FRAME_OVERRUN:
+ if(urbd && urb)
+ {
+ urbd->phase=URBD_DEQUEUEING;
+ ifxhcd_complete_urb(_ifxhcd, urbd, urbd->status);
+ }
+ else
+ {
+ IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
+ }
+ break;
+ case HC_XFER_URB_COMPLETE:
+ if(urbd && urb)
+ {
+ urbd->phase=URBD_COMPLETING;
+ ifxhcd_complete_urb(_ifxhcd, urbd, urbd->status);
+ }
+ else
+ {
+ IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
+ }
+ break;
+ case HC_XFER_STALL:
+ if(urbd)
+ {
+ urbd->phase=URBD_DEQUEUEING;
+ ifxhcd_complete_urb(_ifxhcd, urbd, -EPIPE);
+ }
+ else
+ {
+ IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
+ }
+ if(epqh && urb && urb->dev && urb->pipe)
+ usb_settoggle(urb->dev, usb_pipeendpoint (urb->pipe), !usb_pipein(urb->pipe), IFXUSB_HC_PID_DATA0);
+ break;
+ case HC_XFER_BABBLE_ERR:
+ case HC_XFER_DATA_TOGGLE_ERR:
+ if(urbd)
+ {
+ urbd->phase=URBD_DEQUEUEING;
+ ifxhcd_complete_urb(_ifxhcd, urbd, -EOVERFLOW);
+ }
+ else
+ {
+ IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
+ }
+ break;
+ #ifdef __NAKSTOP__
+ case HC_XFER_NAK:
+ if (_ifxhc->is_in)
+ {
+ if(urbd && urb)
+ {
+ urbd->phase=URBD_COMPLETING;
+ ifxhcd_complete_urb(_ifxhcd, urbd, 0);
+ }
+ else
+ {
+ IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
+ }
+ }
+ else
+ {
+ IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
+ }
+ break;
+ #endif
+ #if defined(__INTRNAKRETRY__) || defined(__INTRINCRETRY__)
+ case HC_XFER_INTR_NAK_RETRY:
+ epqh->phase=EPQH_READY;
+ urbd->phase=URBD_IDLE;
+ ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
+ select_eps(_ifxhcd);
+ return;
+ break;
+
+ #endif
+ }
+ if(epqh)
+ {
+ ifxhcd_epqh_idle(epqh);
+ }
+ else if(_halt_status!=HC_XFER_NO_EPQH)
+ {
+ IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh);
+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
+ }
+ ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
+ select_eps(_ifxhcd);
+}
+
+/*
+ * Updates the state of the URB after a Transfer Complete interrupt on the
+ * host channel. Updates the actual_length field of the URB based on the
+ * number of bytes transferred via the host channel. Sets the URB status
+ * if the data transfer is finished.
+ *
+ * @return 1 if the data transfer specified by the URB is completely finished,
+ * 0 otherwise.
+ */
+static int update_urb_state_xfer_comp(ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ struct urb *_urb,
+ ifxhcd_urbd_t *_urbd)
+{
+ int xfer_done = 0;
+
+ #ifdef __EN_ISOC__
+ if(_urbd->epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
+ {
+ struct usb_iso_packet_descriptor *frame_desc;
+ frame_desc = &_urb->iso_frame_desc[_urbd->isoc_frame_index];
+ if (_ifxhc->is_in)
+ {
+ hctsiz_data_t hctsiz;
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ frame_desc->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ if ((hctsiz.b.xfersize != 0) || (frame_desc->actual_length >= _urbd->xfer_len))
+ {
+ xfer_done = 1;
+ frame_desc->status = 0;
+ #if 0
+ if (frame_desc->actual_length < frame_desc->length && _urb->transfer_flags & URB_SHORT_NOT_OK)
+ frame_desc->status = -EREMOTEIO;
+ #endif
+ }
+ }
+ else
+ {
+ if (_ifxhc->split)
+ frame_desc->actual_length += _ifxhc->ssplit_out_xfer_count;
+ else
+ frame_desc->actual_length += _ifxhc->xfer_len;
+ if (frame_desc->actual_length >= _urbd->xfer_len)
+ {
+ xfer_done = 1;
+ frame_desc->status = 0;
+ }
+ }
+ }
+ else
+ #endif
+ if (_ifxhc->is_in)
+ {
+ hctsiz_data_t hctsiz;
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ _urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+#ifdef __INTRINCRETRY__
+ if(_urbd->epqh->ep_type==IFXUSB_EP_TYPE_INTR)
+ {
+ if(_ifxhc->xfer_len != hctsiz.b.xfersize)
+ {
+ xfer_done = 1;
+ _urbd->status = 0;
+ }
+ }
+ else
+#endif
+ if ((hctsiz.b.xfersize != 0) || (_urb->actual_length >= _urb->transfer_buffer_length))
+ {
+ xfer_done = 1;
+ _urbd->status = 0;
+ if(_urb->transfer_flags & URB_SHORT_NOT_OK)
+ {
+ if (_urb->actual_length < _urb->transfer_buffer_length)
+ _urbd->status = -EREMOTEIO;
+ }
+ }
+ }
+ else if(_urb->transfer_buffer_length%_ifxhc->mps) // OUT without ZLP
+ {
+ if (_ifxhc->split)
+ _urb->actual_length += _ifxhc->ssplit_out_xfer_count;
+ else
+ _urb->actual_length += _ifxhc->xfer_len;
+ if (_urb->actual_length >= _urb->transfer_buffer_length)
+ {
+ xfer_done = 1;
+ _urbd->status = 0;
+ }
+ }
+ else if (_urb->actual_length >= _urb->transfer_buffer_length) //OUT with ZLP
+ {
+ xfer_done = 1;
+ _urbd->status = 0;
+ }
+ else //OUT without ZLP, unfinished
+ {
+ if (_ifxhc->split)
+ _urb->actual_length += _ifxhc->ssplit_out_xfer_count;
+ else
+ _urb->actual_length += _ifxhc->xfer_len;
+ if (!_ifxhc->short_rw && _urb->actual_length >= _urb->transfer_buffer_length)
+ {
+ xfer_done = 1;
+ _urbd->status = 0;
+ }
+ }
+
+ #ifdef __DEBUG__
+ {
+ hctsiz_data_t hctsiz;
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB: %s: %s, channel %d\n",
+ __func__, (_ifxhc->is_in ? "IN" : "OUT"), _ifxhc->hc_num);
+ IFX_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", _ifxhc->xfer_len);
+ IFX_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n", hctsiz.b.xfersize);
+ #ifdef __EN_ISOC__
+ if(_urbd->epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
+ {
+ IFX_DEBUGPL(DBG_HCDV, " descritor # %d\n", _urbd->isoc_frame_index);
+ IFX_DEBUGPL(DBG_HCDV, " buffer_length %d\n",
+ _urb->iso_frame_desc[_urbd->isoc_frame_index].length);
+ IFX_DEBUGPL(DBG_HCDV, " actual_length %d\n", _urb->iso_frame_desc[_urbd->isoc_frame_index].actual_length);
+ }
+ else
+ #endif
+ {
+ IFX_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
+ _urb->transfer_buffer_length);
+ IFX_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", _urb->actual_length);
+ }
+ }
+ #endif
+ return xfer_done;
+}
+
+#ifdef __EN_ISOC__
+ static void next_isoc_sub(unsigned long data)
+ {
+ ifxhcd_urbd_t *urbd;
+ ifxhcd_hcd_t *ifxhcd;
+
+ urbd=((ifxhcd_urbd_t *)data);
+ ifxhcd=urbd->epqh->ifxhcd;
+
+ if (!urbd->epqh)
+ IFX_ERROR("%s: invalid epqd\n",__func__);
+ #if defined(__UNALIGNED_BUF_ADJ__)
+ else
+ {
+ if( urbd->aligned_checked &&
+// urbd->using_aligned_buf &&
+ urbd->xfer_buff &&
+ urbd->is_in)
+ {
+ uint8_t *buf;
+
+ buf=urbd->xfer_buff;
+ buf+=urbd->urb->iso_frame_desc[urbd->isoc_frame_index].offset;
+ memcpy(buf,urbd->aligned_buf,urbd->urb->iso_frame_desc[urbd->isoc_frame_index].length);
+ }
+// urbd->using_aligned_buf=0;
+// urbd->using_aligned_setup=0;
+ }
+ #endif
+
+ urbd->isoc_frame_index++;
+ if(urbd->isoc_frame_index>=urbd->urb->number_of_packets)
+ release_channel(ifxhcd,urbd->epqh->hc,HC_XFER_URB_COMPLETE);
+ else
+ init_hc(urbd->epqh);
+ }
+#endif
+
+/*!
+ \fn static void complete_channel(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxhcd_urbd_t *_urbd)
+ \brief Complete the transaction on the channel.
+ \param _ifxhcd Pointer to the sate of HCD structure
+ \param _ifxhc Pointer to host channel descriptor
+ \param _urbd Pointer to URB descriptor
+ \return None
+ \ingroup IFXUSB_HCD
+ */
+static void complete_channel(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxhcd_urbd_t *_urbd)
+{
+ ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[_ifxhc->hc_num];
+ struct urb *urb = NULL;
+ ifxhcd_epqh_t *epqh = NULL;
+ int urb_xfer_done;
+
+ IFX_DEBUGPL(DBG_HCD, "--Complete Channel %d : \n", _ifxhc->hc_num);
+
+ if(!_urbd)
+ {
+ IFX_ERROR("ERROR %s():%d urbd=%p\n",__func__,__LINE__,_urbd);
+ return;
+ }
+
+ urb = _urbd->urb;
+ epqh = _urbd->epqh;
+
+ if(!epqh)
+ {
+ release_channel(_ifxhcd,_ifxhc,HC_XFER_NO_EPQH);
+ return;
+ }
+ if(!urb || (unsigned long)urb->hcpriv!=(unsigned long)_urbd)
+ {
+ release_channel(_ifxhcd,_ifxhc,HC_XFER_NO_URB);
+ return;
+ }
+
+ if (_ifxhc->split)
+ _ifxhc->split = 1;
+
+ switch (epqh->ep_type)
+ {
+ case IFXUSB_EP_TYPE_CTRL:
+ switch (_ifxhc->control_phase)
+ {
+ case IFXHCD_CONTROL_SETUP:
+ if (_urbd->xfer_len > 0)
+ {
+ _ifxhc->control_phase = IFXHCD_CONTROL_DATA;
+ IFX_DEBUGPL(DBG_HCDV, " Control setup transaction done Data Stage now\n");
+ _ifxhc->is_in = _urbd->is_in;
+ _ifxhc->xfer_len = _urbd->xfer_len;
+ #if defined(__UNALIGNED_BUF_ADJ__)
+ if(_urbd->aligned_buf)
+ _ifxhc->xfer_buff = _urbd->aligned_buf;
+ else
+ #endif
+ _ifxhc->xfer_buff = _urbd->xfer_buff;
+ #ifdef __NAKSTOP__
+ if(!_ifxhc->split)
+ {
+ #ifdef __INNAKSTOP_CTRL__
+ if(_ifxhc->is_in)
+ _ifxhc->stop_on=1;
+ #endif
+ #ifdef __PINGSTOP_CTRL__
+ if(!_ifxhc->is_in)
+ _ifxhc->stop_on=1;
+ #endif
+ }
+ #endif
+ }
+ else
+ {
+ IFX_DEBUGPL(DBG_HCDV, " Control setup transaction done Status Stage now\n");
+ _ifxhc->control_phase = IFXHCD_CONTROL_STATUS;
+ _ifxhc->is_in = 1;
+ _ifxhc->xfer_len = 0;
+ _ifxhc->xfer_buff = _ifxhcd->status_buf;
+ #ifdef __NAKSTOP__
+ _ifxhc->stop_on=0;
+ #endif
+ }
+ if(_ifxhc->is_in)
+ _ifxhc->short_rw =0;
+ else
+ _ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
+ _ifxhc->xfer_count = 0;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ break;
+ case IFXHCD_CONTROL_DATA:
+ urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
+ if (urb_xfer_done)
+ {
+ _ifxhc->control_phase = IFXHCD_CONTROL_STATUS;
+ IFX_DEBUGPL(DBG_HCDV, " Control data transaction done Status Stage now\n");
+ _ifxhc->is_in = (_urbd->is_in)?0:1;
+ _ifxhc->xfer_len = 0;
+ _ifxhc->xfer_count = 0;
+ _ifxhc->xfer_buff = _ifxhcd->status_buf;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
+ if(_ifxhc->is_in)
+ _ifxhc->short_rw =0;
+ else
+ _ifxhc->short_rw =1;
+ #ifdef __NAKSTOP__
+ _ifxhc->stop_on=0;
+ #endif
+ }
+ else // continue
+ {
+ IFX_DEBUGPL(DBG_HCDV, " Control data transaction continue\n");
+ _ifxhc->xfer_len = _urbd->xfer_len - urb->actual_length;
+ _ifxhc->xfer_count = urb->actual_length;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->data_pid_start = read_data_toggle(hc_regs);
+ }
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ break;
+ case IFXHCD_CONTROL_STATUS:
+ IFX_DEBUGPL(DBG_HCDV, " Control status transaction done\n");
+ if (_urbd->status == -EINPROGRESS)
+ _urbd->status = 0;
+ release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
+ break;
+ }
+ break;
+ case IFXUSB_EP_TYPE_BULK:
+ IFX_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n");
+ urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
+ if (urb_xfer_done)
+ release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
+ else
+ {
+ _ifxhc->xfer_len = _urbd->xfer_len - urb->actual_length;
+ _ifxhc->xfer_count = urb->actual_length;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->data_pid_start = read_data_toggle(hc_regs);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ break;
+ case IFXUSB_EP_TYPE_INTR:
+ urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
+
+ #ifdef __INTRINCRETRY__
+ if(!urb_xfer_done)
+ release_channel(_ifxhcd,_ifxhc,HC_XFER_INTR_NAK_RETRY);
+ else
+ #endif
+ release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
+ break;
+ case IFXUSB_EP_TYPE_ISOC:
+ #ifdef __EN_ISOC__
+ urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
+ if (urb_xfer_done)
+ {
+ #if defined(__UNALIGNED_BUF_ADJ__)
+ if(in_irq())
+ {
+ if(!epqh->tasklet_next_isoc.func)
+ {
+ epqh->tasklet_next_isoc.next = NULL;
+ epqh->tasklet_next_isoc.state = 0;
+ atomic_set( &epqh->tasklet_next_isoc.count, 0);
+ epqh->tasklet_next_isoc.func = next_isoc_sub;
+ epqh->tasklet_next_isoc.data = (unsigned long)_urbd;
+ }
+ tasklet_schedule(&epqh->tasklet_next_isoc);
+ }
+ else
+ #endif
+ {
+ next_isoc_sub((unsigned long)_urbd);
+ }
+ }
+ else
+ {
+ struct usb_iso_packet_descriptor *frame_desc;
+ frame_desc = &urb->iso_frame_desc[_urbd->isoc_frame_index];
+ _ifxhc->xfer_len = _urbd->xfer_len - frame_desc->actual_length;
+ _ifxhc->xfer_count = frame_desc->actual_length;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->data_pid_start = read_data_toggle(hc_regs);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ #endif
+ break;
+ }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_ctrl_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ #ifdef __INNAKSTOP_CTRL__
+ if (_ifxhc->halt_status == HC_XFER_NAK)
+ {
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ u32 actual_length;
+ actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
+
+ if(_urbd->xfer_len && actual_length >= _urbd->xfer_len)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _ifxhc->xfer_count =
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ }
+ else
+ {
+ printk(KERN_INFO "Warning: %s() %d Invalid CTRL Phase:%d\n",__func__,__LINE__,_ifxhc->control_phase);
+ release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
+ }
+ return 1;
+ }
+ #endif
+
+ if (hcint.b.xfercomp || hcint.d32 == 0x02)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if (hcint.b.stall)
+ {
+ _urbd->error_count =0;
+ // ZLP shortcut
+ #if 0
+ if(hctsiz.b.pktcnt==0)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ #endif
+ #if 0
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_STATUS)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ #endif
+ {
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ }
+ return 1;
+ }
+ else if (hcint.b.bblerr)
+ {
+ _urbd->error_count =0;
+
+ // ZLP shortcut
+ #if 0
+ if(hctsiz.b.pktcnt==0)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ #endif
+ #if 0
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_STATUS)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ #endif
+ {
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ }
+ return 1;
+ }
+ else if (hcint.b.xacterr)
+ {
+ // ZLP shortcut
+ #if 1
+ if(hctsiz.b.pktcnt==0)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ #endif
+ #if 1
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_STATUS)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ #endif
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ #if 1
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ #else
+ u32 actual_length;
+ actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ if(actual_length >= _urbd->xfer_len)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _urbd->error_count++;
+ _ifxhc->xfer_count =
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ if (_urbd->error_count >= 3)
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->erron=1;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ }
+ #endif
+ }
+ else
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ #if 0
+ #if 1
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ #else
+ u32 actual_length;
+ actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ if(actual_length>=_urbd->xfer_len)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ }
+ #endif
+ #else
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ #endif
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else
+ {
+ _urbd->error_count =0;
+ IFX_ERROR("ERROR %s():%d invalid chhlt condition %08X/%08X %d\n",__func__,__LINE__,hcint.d32,hcintmsk.d32,_ifxhc->halt_status);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ return 1;
+ }
+
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_ctrl_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ #ifdef __PINGSTOP_CTRL__
+ if (_ifxhc->halt_status == HC_XFER_NAK)
+ {
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ u32 actual_length;
+ actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+
+ if(_urbd->xfer_len && actual_length >= _urbd->xfer_len)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _ifxhc->xfer_count =
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ }
+ else
+ {
+ printk(KERN_INFO "Warning: %s() %d Invalid CTRL Phase:%d\n",__func__,__LINE__,_ifxhc->control_phase);
+ release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
+ }
+ return 1;
+ }
+ #endif
+
+
+ if (hcint.b.xfercomp || hcint.d32 == 0x02)
+ {
+ _urbd->error_count =0;
+ if(_ifxhc->xfer_len==0 && !hcint.b.ack && hcint.b.nak)
+ {
+ // Walkaround: When sending ZLP and receive NAK but also issue CMPT intr
+ // Solution: NoSplit: Resend at next SOF
+ // Split : Resend at next SOF with SSPLIT
+ if(hcint.b.nyet)
+ _ifxhc->epqh->do_ping=1;
+
+ _ifxhc->xfer_len = 0;
+ _ifxhc->xfer_count = 0;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ else
+ {
+ if(hcint.b.nyet)
+ _ifxhc->epqh->do_ping=1;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ return 1;
+ }
+ else if (hcint.b.stall)
+ {
+ _urbd->error_count =0;
+
+ // ZLP shortcut
+ #if 1
+ if(hctsiz.b.pktcnt==0)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ #endif
+ {
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ }
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ }
+ return 1;
+ }
+ else if (hcint.b.xacterr)
+ {
+ // ZLP shortcut
+ #if 1
+ if(hctsiz.b.pktcnt==0)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ #endif
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_STATUS)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else if(_ifxhc->control_phase == IFXHCD_CONTROL_SETUP)
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ #if 0
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ #else
+ u32 actual_length;
+ actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+ if(actual_length>=_urbd->xfer_len)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _urbd->error_count++;
+ _ifxhc->xfer_count =
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ if (_urbd->error_count >= 3)
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->erron=1;
+ _ifxhc->phase=HC_WAITING;
+ _ifxhc->epqh->do_ping=1;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ }
+ #endif
+ }
+ else
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ }
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.nak || hcint.b.nyet)
+ {
+ #ifdef __PINGSTOP_CTRL__
+ _urbd->error_count =0;
+ IFX_ERROR("ERROR %s():%d invalid chhlt condition\n",__func__,__LINE__);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ #else
+ // ZLP shortcut
+ #if 1
+ if(hctsiz.b.pktcnt==0)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ #endif
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_STATUS)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else if(_ifxhc->control_phase == IFXHCD_CONTROL_SETUP)
+ {
+ _urbd->error_count =0;
+ IFX_ERROR("ERROR %s():%d invalid chhlt condition\n",__func__,__LINE__);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ #if 0
+ _ifxhc->epqh->do_ping=1;
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ #else
+ u32 actual_length;
+ _ifxhc->epqh->do_ping=1;
+ actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+ if(actual_length>=_urbd->xfer_len)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _ifxhc->xfer_count =
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _ifxhc->erron=1;
+ _ifxhc->epqh->do_ping=1;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ #endif
+ }
+ #endif
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ }
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ }
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else
+ {
+ _urbd->error_count =0;
+ IFX_ERROR("ERROR %s():%d invalid chhlt condition %08X/%08X %d\n",__func__,__LINE__,hcint.d32,hcintmsk.d32,_ifxhc->halt_status);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_bulk_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ #ifdef __INNAKSTOP_BULK__
+ if(_ifxhc->halt_status == HC_XFER_NAK)
+ {
+ u32 actual_length;
+ actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
+
+ if(
+ (_urbd->xfer_len && actual_length>=_urbd->xfer_len)
+ || hctsiz.b.pktcnt==0
+ || (hctsiz.b.xfersize % _ifxhc->mps)>0
+ )
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ #endif
+
+ if (hcint.b.xfercomp || hcint.d32 == 0x02)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if (hcint.b.stall)
+ {
+ _urbd->error_count =0;
+ // ZLP shortcut
+ #if 0
+ if(hctsiz.b.pktcnt==0)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ #endif
+ {
+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ }
+ return 1;
+ }
+ else if (hcint.b.bblerr)
+ {
+ _urbd->error_count =0;
+
+ // ZLP shortcut
+ #if 0
+ if(hctsiz.b.pktcnt==0)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ #endif
+ {
+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ }
+ return 1;
+ }
+ else if (hcint.b.xacterr)
+ {
+ // ZLP shortcut
+ #if 1
+ if(hctsiz.b.pktcnt==0)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ #endif
+ {
+ #if 0
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ #else
+ u32 actual_length;
+ actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ if(actual_length >= _urbd->xfer_len)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _urbd->error_count++;
+ _ifxhc->xfer_count =
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ if (_urbd->error_count >= 3)
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->erron=1;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ }
+ #endif
+ }
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ #if 0
+ #if 1
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ #else
+ u32 actual_length;
+ actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ if(actual_length >= _urbd->xfer_len)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ }
+ #endif
+ #else
+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ #endif
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else
+ {
+ _urbd->error_count =0;
+ IFX_ERROR("ERROR %s():%d invalid chhlt condition %08X/%08X %d sz:%d/%d/%d/%d\n",__func__,__LINE__,hcint.d32,hcintmsk.d32,_ifxhc->halt_status , hctsiz.b.xfersize, _ifxhc->xfer_len-_ifxhc->xfer_len,_ifxhc->xfer_len,_urbd->xfer_len);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_bulk_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+ int out_nak_enh = 0;
+
+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ out_nak_enh = 1;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ #ifdef __PINGSTOP_BULK__
+ if (_ifxhc->halt_status == HC_XFER_NAK)
+ {
+ u32 actual_length;
+ actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+
+ if(_urbd->xfer_len && actual_length >= _urbd->xfer_len)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _ifxhc->xfer_count =
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ #endif
+
+ if (hcint.b.xfercomp || hcint.d32 == 0x02)
+ {
+ _urbd->error_count =0;
+ if(_ifxhc->xfer_len==0 && !hcint.b.ack && hcint.b.nak)
+ {
+ // Walkaround: When sending ZLP and receive NAK but also issue CMPT intr
+ // Solution: NoSplit: Resend at next SOF
+ // Split : Resend at next SOF with SSPLIT
+ if(hcint.b.nyet)
+ _ifxhc->epqh->do_ping=1;
+
+ _ifxhc->xfer_len = 0;
+ _ifxhc->xfer_count = 0;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ else
+ {
+ if(hcint.b.nyet)
+ _ifxhc->epqh->do_ping=1;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ return 1;
+ }
+ else if (hcint.b.stall)
+ {
+ _urbd->error_count =0;
+
+ // ZLP shortcut
+ #if 1
+ if(hctsiz.b.pktcnt==0)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ #endif
+ {
+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+ if(_urbd->urb->actual_length>_urbd->xfer_len) _urbd->urb->actual_length=_urbd->xfer_len;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ }
+ return 1;
+ }
+ else if (hcint.b.xacterr)
+ {
+ // ZLP shortcut
+ #if 1
+ if(hctsiz.b.pktcnt==0)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ #endif
+ {
+ #if 0
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ #else
+ u32 actual_length;
+ actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+ if(actual_length >= _urbd->xfer_len)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _urbd->error_count++;
+ _ifxhc->xfer_count =
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ if (_urbd->error_count >= 3)
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->erron=1;
+ _ifxhc->phase=HC_WAITING;
+ _ifxhc->epqh->do_ping=1;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ }
+ #endif
+ }
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+ if(_urbd->urb->actual_length>_urbd->xfer_len) _urbd->urb->actual_length=_urbd->xfer_len;
+ IFX_ERROR("ERROR %s():%d invalid packet babble\n",__func__,__LINE__);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.nak || hcint.b.nyet)
+ {
+ #ifdef __PINGSTOP_BULK__
+ _urbd->error_count =0;
+ IFX_ERROR("ERROR %s():%d invalid chhlt condition\n",__func__,__LINE__);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ #else
+ // ZLP shortcut
+ #if 1
+ if(hctsiz.b.pktcnt==0)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ #endif
+ {
+ #if 0
+ _ifxhc->epqh->do_ping=1;
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ #else
+ u32 actual_length;
+ _ifxhc->epqh->do_ping=1;
+ actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+ if(actual_length>=_urbd->xfer_len)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _ifxhc->xfer_count =
+ _urbd->urb->actual_length = actual_length;
+ _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _ifxhc->erron=1;
+ _ifxhc->epqh->do_ping=1;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ #endif
+ }
+ #endif
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else
+ {
+ _urbd->error_count =0;
+ IFX_ERROR("ERROR %s():%d invalid chhlt condition %08X/%08X %d\n",__func__,__LINE__,hcint.d32,hcintmsk.d32,_ifxhc->halt_status);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_intr_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if (hcint.b.xfercomp || hcint.d32 == 0x02)
+ {
+ _urbd->error_count =0;
+ //restart INTR immediately
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if (hcint.b.stall)
+ {
+ _urbd->error_count =0;
+
+ // Don't care shortcut
+ #if 0
+ if(hctsiz.b.pktcnt==0)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ #endif
+ {
+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ }
+ return 1;
+ }
+ else if (hcint.b.bblerr)
+ {
+ _urbd->error_count =0;
+
+ // Don't care shortcut
+ #if 0
+ if(hctsiz.b.pktcnt==0)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ #endif
+ {
+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ }
+ return 1;
+ }
+ else if (hcint.b.datatglerr || hcint.b.frmovrun)
+ {
+ _urbd->error_count =0;
+ //restart INTR immediately
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if (hcint.b.xacterr)
+ {
+ // ZLP shortcut
+ #if 1
+ if(hctsiz.b.pktcnt==0)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ #endif
+ {
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ }
+ return 1;
+ }
+ else if(hcint.b.nyet )
+ {
+ return 1;
+ }
+ else if (hcint.b.nak)
+ {
+
+ #ifdef __INTRNAKRETRY__
+ if(hctsiz.b.pktcnt)
+ {
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_INTR_NAK_RETRY);
+ return 1;
+ }
+ #endif
+ _urbd->error_count =0;
+ //restart INTR immediately
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else
+ {
+ _urbd->error_count =0;
+ //restart INTR immediately
+ #if 0
+ if(hctsiz.b.pktcnt>0)
+ {
+ // TODO Re-initialize Channel (in next b_interval - 1 uF/F)
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ else
+ #endif
+ {
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ return 1;
+ }
+
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_intr_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+ int out_nak_enh = 0;
+
+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ out_nak_enh = 1;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+
+ if (hcint.b.xfercomp || hcint.d32 == 0x02)
+ {
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+ _urbd->error_count =0;
+ //restart INTR immediately
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if (hcint.b.stall)
+ {
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nyet);
+ disable_hc_int(_hc_regs,nak);
+ _urbd->error_count =0;
+
+ // Don't care shortcut
+ #if 0
+ if(hctsiz.b.pktcnt==0)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ #endif
+ {
+ if(_ifxhc->xfer_len!=0)// !_ifxhc->is_in
+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ }
+ return 1;
+ }
+ else if(hcint.b.nak || hcint.b.frmovrun )
+ {
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nyet);
+ disable_hc_int(_hc_regs,nak);
+ _urbd->error_count =0;
+ //restart INTR immediately
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if(hcint.b.xacterr )
+ {
+ // ZLP shortcut
+ #if 1
+ if(hctsiz.b.pktcnt==0)
+ {
+ _urbd->error_count =0;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ #endif
+ {
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ }
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_isoc_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ #ifdef __EN_ISOC__
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+
+ if (hcint.b.xfercomp || hcint.b.frmovrun || hcint.d32 == 0x02)
+ {
+ _urbd->error_count=0;
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+ if (hcint.b.xfercomp)
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ else
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ }
+ else if (hcint.b.xacterr || hcint.b.bblerr)
+ {
+ #ifndef VR9Skip
+ if(hctsiz.b.pktcnt==0)
+ {
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ if (hcint.b.bblerr)
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ else if (hcint.b.xacterr)
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ enable_hc_int(_hc_regs,ack);
+ enable_hc_int(_hc_regs,nak);
+ enable_hc_int(_hc_regs,nyet);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ }
+ #endif
+ }
+ else if(hcint.b.datatglerr )
+ {
+ return 1;
+ }
+ else if(hcint.b.stall )
+ {
+ return 1;
+ }
+ #endif
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_isoc_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ #ifdef __EN_ISOC__
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+ int out_nak_enh = 0;
+
+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ out_nak_enh = 1;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+
+ if (hcint.b.xfercomp || hcint.d32 == 0x02)
+ {
+ _urbd->error_count=0;
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if (hcint.b.frmovrun)
+ {
+ #ifndef VR9Skip
+ _urbd->error_count=0;
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ #endif
+ }
+ else if(hcint.b.datatglerr )
+ {
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ #ifndef VR9Skip
+ if(hctsiz.b.pktcnt==0)
+ {
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ else
+ {
+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ }
+ else
+ {
+ enable_hc_int(_hc_regs,ack);
+ enable_hc_int(_hc_regs,nak);
+ enable_hc_int(_hc_regs,nyet);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ }
+ #endif
+ }
+ else if(hcint.b.xacterr )
+ {
+ if(hctsiz.b.pktcnt==0)
+ {
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.stall )
+ {
+ return 1;
+ }
+ #endif
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_ctrl_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if (hcint.b.ack)
+ {
+ _urbd->error_count=0;
+ _ifxhc->split=2;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if (hcint.b.nak)
+ {
+ _urbd->error_count = 0;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if (hcint.b.xacterr)
+ {
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.stall )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else if(hcint.b.nyet )
+ {
+ }
+ else if(hcint.b.xfercomp )
+ {
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_ctrl_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+ int out_nak_enh = 0;
+
+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ out_nak_enh = 1;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if (hcint.b.ack )
+ {
+ _urbd->error_count=0;
+ if (_ifxhc->control_phase != IFXHCD_CONTROL_SETUP)
+ _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
+ _ifxhc->split=2;
+ _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nyet)
+ {
+ _urbd->error_count=0;
+ if (_ifxhc->control_phase != IFXHCD_CONTROL_SETUP)
+ _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
+ _ifxhc->split=2;
+ _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nak )
+ {
+ _urbd->error_count =0;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.xacterr )
+ {
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.stall )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else if(hcint.b.xfercomp )
+ {
+ printk(KERN_INFO "Warning: %s() %d CTRL OUT SPLIT1 COMPLETE\n",__func__,__LINE__);
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_bulk_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if (hcint.b.ack)
+ {
+ _urbd->error_count=0;
+ _ifxhc->split=2;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if (hcint.b.nak)
+ {
+ _urbd->error_count = 0;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if (hcint.b.xacterr)
+ {
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.stall )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else if(hcint.b.nyet )
+ {
+ }
+ else if(hcint.b.xfercomp )
+ {
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_bulk_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+ int out_nak_enh = 0;
+
+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ out_nak_enh = 1;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if (hcint.b.ack )
+ {
+ _urbd->error_count=0;
+ _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
+ _ifxhc->split=2;
+ _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nyet)
+ {
+ _urbd->error_count=0;
+ _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
+ _ifxhc->split=2;
+ _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nak )
+ {
+ _urbd->error_count =0;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.xacterr )
+ {
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.stall )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else if(hcint.b.xfercomp )
+ {
+ printk(KERN_INFO "Warning: %s() %d BULK OUT SPLIT1 COMPLETE\n",__func__,__LINE__);
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_intr_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if (hcint.b.ack)
+ {
+ _urbd->error_count=0;
+ _ifxhc->split=2;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nak)
+ {
+ _urbd->error_count=0;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.xacterr)
+ {
+ hcchar_data_t hcchar;
+ hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
+ _urbd->error_count=hcchar.b.multicnt;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.stall )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.xfercomp )
+ {
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_intr_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+ int out_nak_enh = 0;
+
+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ out_nak_enh = 1;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if (hcint.b.ack )
+ {
+ _urbd->error_count=0;
+ _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
+ _ifxhc->split=2;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nyet)
+ {
+ _urbd->error_count=0;
+ _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
+ _ifxhc->split=2;
+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nak )
+ {
+ _urbd->error_count =0;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ _urbd->error_count =0;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.xacterr )
+ {
+ hcchar_data_t hcchar;
+ hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
+ _urbd->error_count=hcchar.b.multicnt;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ enable_hc_int(_hc_regs,ack);
+ enable_hc_int(_hc_regs,nak);
+ enable_hc_int(_hc_regs,nyet);
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.stall )
+ {
+ _urbd->error_count =0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ return 1;
+ }
+ else if(hcint.b.xfercomp )
+ {
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_isoc_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ if (hcint.b.ack )
+ {
+ Do Complete Split
+ }
+ else if(hcint.b.frmovrun )
+ {
+ Rewind Buffer Pointers
+ Retry Start Split (in next b_interval ¡V 1 uF)
+ }
+ else if(hcint.b.datatglerr )
+ {
+ //warning
+ }
+ else if(hcint.b.bblerr )
+ {
+ //warning
+ }
+ else if(hcint.b.xacterr )
+ {
+ //warning
+ }
+ else if(hcint.b.stall )
+ {
+ //warning
+ }
+ else if(hcint.b.nak )
+ {
+ //warning
+ }
+ else if(hcint.b.xfercomp )
+ {
+ //warning
+ }
+ else if(hcint.b.nyet)
+ {
+ //warning
+ }
+ #endif
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_isoc_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+ int out_nak_enh = 0;
+
+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ out_nak_enh = 1;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ if (hcint.b.ack )
+ {
+ //Do Next Start Split (in next b_interval ¡V 1 uF)
+ }
+ else if(hcint.b.frmovrun )
+ {
+ //Do Next Transaction in next frame.
+ }
+ else if(hcint.b.datatglerr )
+ {
+ //warning
+ }
+ else if(hcint.b.bblerr )
+ {
+ //warning
+ }
+ else if(hcint.b.xacterr )
+ {
+ //warning
+ }
+ else if(hcint.b.stall )
+ {
+ //warning
+ }
+ else if(hcint.b.nak )
+ {
+ //warning
+ }
+ else if(hcint.b.xfercomp )
+ {
+ //warning
+ }
+ else if(hcint.b.nyet)
+ {
+ //warning
+ }
+ #endif
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_ctrl_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if (hcint.b.xfercomp)
+ {
+ _urbd->error_count =0;
+ _ifxhc->split=1;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if (hcint.b.nak)
+ {
+ _ifxhc->split = 1;
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ }
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nyet)
+ {
+ _urbd->error_count=0;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.stall || hcint.b.bblerr )
+ {
+ _urbd->error_count=0;
+ if (hcint.b.stall)
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ else if(hcint.b.bblerr )
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.xacterr )
+ {
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->split=1;
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ }
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
+ else
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
+ _ifxhc->split=1;
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ }
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_ctrl_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+ int out_nak_enh = 0;
+
+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ out_nak_enh = 1;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if(hcint.b.xfercomp )
+ {
+ _urbd->error_count=0;
+ _ifxhc->split=1;
+ #if 0
+ if(_ifxhc->xfer_len==0 && !hcint.b.ack && (hcint.b.nak || hcint.b.nyet))
+ {
+ // Walkaround: When sending ZLP and receive NYEY or NAK but also issue CMPT intr
+ // Solution: NoSplit: Resend at next SOF
+ // Split : Resend at next SOF with SSPLIT
+ _ifxhc->xfer_len = 0;
+ _ifxhc->xfer_count = 0;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ else
+ #endif
+ {
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ return 1;
+ }
+ else if(hcint.b.nak )
+ {
+ _ifxhc->split = 1;
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ }
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nyet)
+ {
+ //Retry Complete Split
+ // Issue Retry instantly on next SOF, without gothrough process_channels
+ _urbd->error_count=0;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.stall )
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ return 1;
+ }
+ else if(hcint.b.xacterr )
+ {
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->split=1;
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ }
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
+ else
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
+ _ifxhc->split=1;
+ if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
+ {
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ }
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_bulk_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if (hcint.b.xfercomp)
+ {
+ _urbd->error_count =0;
+ _ifxhc->split=1;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if (hcint.b.nak)
+ {
+ _ifxhc->split = 1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nyet)
+ {
+ _urbd->error_count=0;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.stall || hcint.b.bblerr )
+ {
+ _urbd->error_count=0;
+ if (hcint.b.stall)
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ else if(hcint.b.bblerr )
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ else if(hcint.b.xacterr )
+ {
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->split=1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
+ else
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
+ _ifxhc->split=1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_bulk_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+ int out_nak_enh = 0;
+
+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ out_nak_enh = 1;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if(hcint.b.xfercomp )
+ {
+ _urbd->error_count=0;
+ _ifxhc->split=1;
+ #if 0
+ if(_ifxhc->xfer_len==0 && !hcint.b.ack && (hcint.b.nak || hcint.b.nyet))
+ {
+ // Walkaround: When sending ZLP and receive NYEY or NAK but also issue CMPT intr
+ // Solution: NoSplit: Resend at next SOF
+ // Split : Resend at next SOF with SSPLIT
+ _ifxhc->xfer_len = 0;
+ _ifxhc->xfer_count = 0;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ else
+ #endif
+ {
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ }
+ return 1;
+ }
+ else if(hcint.b.nak )
+ {
+ _ifxhc->split = 1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nyet)
+ {
+ //Retry Complete Split
+ // Issue Retry instantly on next SOF, without gothrough process_channels
+ _urbd->error_count=0;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.stall )
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ return 1;
+ }
+ else if(hcint.b.xacterr )
+ {
+ _urbd->error_count++;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->split=1;
+ _ifxhc->epqh->do_ping=1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
+ else
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
+ _ifxhc->split=1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.frmovrun )
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_intr_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if (hcint.b.xfercomp )
+ {
+ _urbd->error_count=0;
+ _ifxhc->split=1;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if(hcint.b.nak )
+ {
+ _ifxhc->split = 1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nyet)
+ {
+ _urbd->error_count=0;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.frmovrun || hcint.b.bblerr || hcint.b.stall )
+ {
+ _urbd->error_count=0;
+ if (hcint.b.stall)
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ else if(hcint.b.bblerr )
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ else if(hcint.b.frmovrun )
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else if(hcint.b.xacterr )
+ {
+ hcchar_data_t hcchar;
+ hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
+ _urbd->error_count=hcchar.b.multicnt;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->split=1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
+ else
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
+ _ifxhc->split=1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_intr_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+ int out_nak_enh = 0;
+
+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ out_nak_enh = 1;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+
+ if(hcint.b.xfercomp )
+ {
+ _urbd->error_count=0;
+ _ifxhc->split=1;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if(hcint.b.nak )
+ {
+ _ifxhc->split = 1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.nyet)
+ {
+ _urbd->error_count=0;
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.stall || hcint.b.frmovrun)
+ {
+ _urbd->error_count=0;
+ if (hcint.b.stall)
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ else if(hcint.b.frmovrun )
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
+ return 1;
+ }
+ else if(hcint.b.xacterr )
+ {
+ hcchar_data_t hcchar;
+ hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
+ _urbd->error_count=hcchar.b.multicnt;
+ if(_urbd->error_count>=3)
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
+ }
+ else
+ {
+ _ifxhc->split=1;
+ _ifxhc->epqh->do_ping=1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ }
+ return 1;
+ }
+ else if(hcint.b.datatglerr )
+ {
+ if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
+ else
+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
+ _ifxhc->split=1;
+ _ifxhc->epqh->do_ping=1;
+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
+ _ifxhc->xfer_count = _urbd->urb->actual_length;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.bblerr )
+ {
+ _urbd->error_count=0;
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_isoc_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ if(hcint.b.xfercomp )
+ {
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ disable_hc_int(_hc_regs,nyet);
+ _urbd->error_count=0;
+ _ifxhc->split=1;
+ complete_channel(_ifxhcd, _ifxhc, _urbd);
+ return 1;
+ }
+ else if(hcint.b.nak )
+ {
+ Retry Start Split (in next b_interval ¡V 1 uF)
+ }
+ else if(hcint.b.nyet)
+ {
+ //Do Next Complete Split
+ // Issue Retry instantly on next SOF, without gothrough process_channels
+ _urbd->error_count=0;
+ //disable_hc_int(_hc_regs,ack);
+ //disable_hc_int(_hc_regs,nak);
+ //disable_hc_int(_hc_regs,datatglerr);
+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ _ifxhc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, _ifxhc);
+ return 1;
+ }
+ else if(hcint.b.frmovrun || hcint.b.stall || hcint.b.bblerr)
+ {
+ _urbd->error_count=0;
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nyet);
+ disable_hc_int(_hc_regs,nak);
+ _ifxhc->wait_for_sof = 0;
+
+ //if(hctsiz.b.pktcnt==0)
+ //{
+ // complete_channel(_ifxhcd, _ifxhc, _urbd);
+ // return 1;
+ //}
+ //else
+ // _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
+ if (hcint.b.stall)
+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
+ else if(hcint.b.frmovrun )
+ else if(hcint.b.bblerr )
+ return 1;
+ }
+ else if(hcint.b.xacterr )
+ {
+ Rewind Buffer Pointers
+ if (HCCHARn.EC = = 3) // ERR response received
+ {
+ Record ERR error
+ Do Next Start Split (in next frame)
+ }
+ else
+ {
+ De-allocate Channel
+ }
+ }
+ else if(hcint.b.datatglerr )
+ {
+ warning
+ }
+ else if(hcint.b.ack )
+ {
+ warning
+ }
+ #endif
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int32_t chhltd_isoc_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
+ hcint_data_t hcint;
+ hcint_data_t hcintmsk;
+ hctsiz_data_t hctsiz;
+ int out_nak_enh = 0;
+
+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
+ out_nak_enh = 1;
+
+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ warning
+ #endif
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*!
+ \fn static int32_t handle_hc_chhltd_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+ \brief This function handles halted interrupts of host channels.
+ \param _ifxhcd Pointer to the sate of HCD structure
+ \param _ifxhc Pointer to host channel descriptor
+ \param _hc_regs Pointer to host channel registers
+ \param _urbd Pointer to URB descriptor
+ \return 0 OK
+ \ingroup IFXUSB_HCD
+ */
+static
+int32_t handle_hc_chhltd_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ IFX_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: Channel Halted--\n", _ifxhc->hc_num);
+
+ _ifxhc->phase = HC_STOPPED;
+ if(_ifxhc->epqh)
+ if(_ifxhc->epqh->urbd)
+ _ifxhc->epqh->urbd->phase=URBD_ACTIVE;
+
+ if (_ifxhc->halt_status == HC_XFER_URB_DEQUEUE ||
+ _ifxhc->halt_status == HC_XFER_AHB_ERR) {
+ /*
+ * Just release the channel. A dequeue can happen on a
+ * transfer timeout. In the case of an AHB Error, the channel
+ * was forced to halt because there's no way to gracefully
+ * recover.
+ */
+ if(_ifxhc->epqh)
+ if(_ifxhc->epqh->urbd)
+ _ifxhc->epqh->urbd->phase=URBD_DEQUEUEING;
+ release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
+ return 1;
+ }
+
+ if (_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL)
+ {
+ if (_ifxhc->split==0)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_ctrl_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_ctrl_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ else if(_ifxhc->split==1)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_ctrl_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_ctrl_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ else if(_ifxhc->split==2)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_ctrl_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_ctrl_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ }
+ else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
+ {
+ if (_ifxhc->split==0)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_bulk_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_bulk_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ else if(_ifxhc->split==1)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_bulk_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_bulk_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ else if(_ifxhc->split==2)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_bulk_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_bulk_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ }
+ else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR)
+ {
+ if (_ifxhc->split==0)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_intr_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_intr_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ else if(_ifxhc->split==1)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_intr_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_intr_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ else if(_ifxhc->split==2)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_intr_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_intr_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ }
+ else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
+ {
+ if (_ifxhc->split==0)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_isoc_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_isoc_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ else if(_ifxhc->split==1)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_isoc_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_isoc_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ else if(_ifxhc->split==2)
+ {
+ if(_ifxhc->is_in)
+ return (chhltd_isoc_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ else
+ return (chhltd_isoc_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
+ }
+ }
+ return 0;
+}
+
+/*
+ * Handles a host channel AHB error interrupt. This handler is only called in
+ * DMA mode.
+ */
+static void hc_other_intr_dump(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ #ifdef __DEBUG__
+ hcchar_data_t hcchar;
+ hcsplt_data_t hcsplt;
+ hctsiz_data_t hctsiz;
+ uint32_t hcdma;
+ struct urb *urb = _urbd->urb;
+ hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
+ hcsplt.d32 = ifxusb_rreg(&_hc_regs->hcsplt);
+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
+ hcdma = ifxusb_rreg(&_hc_regs->hcdma);
+
+ IFX_ERROR("Channel %d\n", _ifxhc->hc_num);
+ IFX_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
+ IFX_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
+ IFX_ERROR(" Device address: %d\n", usb_pipedevice(urb->pipe));
+ IFX_ERROR(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
+ (usb_pipein(urb->pipe) ? "IN" : "OUT"));
+ IFX_ERROR(" Endpoint type: %s\n",
+ ({char *pipetype;
+ switch (usb_pipetype(urb->pipe)) {
+ case PIPE_CONTROL: pipetype = "CTRL"; break;
+ case PIPE_BULK: pipetype = "BULK"; break;
+ case PIPE_INTERRUPT: pipetype = "INTR"; break;
+ case PIPE_ISOCHRONOUS: pipetype = "ISOC"; break;
+ default: pipetype = "????"; break;
+ }; pipetype;}));
+ IFX_ERROR(" Speed: %s\n",
+ ({char *speed;
+ switch (urb->dev->speed) {
+ case USB_SPEED_HIGH: speed = "HS"; break;
+ case USB_SPEED_FULL: speed = "FS"; break;
+ case USB_SPEED_LOW: speed = "LS"; break;
+ default: speed = "????"; break;
+ }; speed;}));
+ IFX_ERROR(" Max packet size: %d\n",
+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
+ IFX_ERROR(" Data buffer length: %d\n", urb->transfer_buffer_length);
+ IFX_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n",
+ urb->transfer_buffer, (void *)urb->transfer_dma);
+ IFX_ERROR(" Setup buffer: %p, Setup DMA: %p\n",
+ urb->setup_packet, (void *)urb->setup_dma);
+ IFX_ERROR(" Interval: %d\n", urb->interval);
+ #endif //__DEBUG__
+}
+
+/*
+ * Handles a host channel ACK interrupt. This interrupt is enabled when
+ * errors occur, and during Start Split transactions.
+ */
+static
+int32_t handle_hc_ack_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ _urbd->error_count=0;
+ _ifxhc->erron = 0;
+
+ disable_hc_int(_hc_regs,nyet);
+
+ #ifdef __NAKSTOP__
+ if(!_ifxhc->stop_on)
+ {
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ }
+ #else
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ #endif
+ return 1;
+}
+
+/*
+ * Handles a host channel ACK interrupt. This interrupt is enabled when
+ * errors occur, and during Start Split transactions.
+ */
+static
+int32_t handle_hc_nak_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ _urbd->error_count=0;
+ _ifxhc->erron=0;
+ disable_hc_int(_hc_regs,nyet);
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ #ifdef __NAKSTOP__
+ if(_ifxhc->stop_on)
+ {
+ hcchar_data_t hcchar;
+ hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
+ if(hcchar.b.chen)
+ {
+ hcchar.b.chdis = 1;
+ _ifxhc->halt_status = HC_XFER_NAK;
+ ifxusb_wreg(&_hc_regs->hcchar, hcchar.d32);
+ }
+ }
+ #endif
+ return 1;
+}
+
+static
+int32_t handle_hc_nyet_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ _urbd->error_count=0;
+ _ifxhc->erron = 0;
+
+ disable_hc_int(_hc_regs,nyet);
+ #ifdef __NAKSTOP__
+ if(!_ifxhc->stop_on)
+ {
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ }
+ #else
+ disable_hc_int(_hc_regs,ack);
+ disable_hc_int(_hc_regs,nak);
+ #endif
+ return 1;
+}
+
+/*
+ * Handles a host channel AHB error interrupt. This handler is only called in
+ * DMA mode.
+ */
+static int32_t handle_hc_ahberr_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ IFX_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
+ "AHB Error--\n", _ifxhc->hc_num);
+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
+
+ ifxhcd_hc_halt(&_ifxhcd->core_if, _ifxhc, HC_XFER_AHB_ERR);
+ return 1;
+}
+
+/*
+ * Datatoggle
+ */
+static int32_t handle_hc_datatglerr_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ IFX_ERROR( "--Host Channel %d Interrupt: "
+ "DATATOGGLE Error--\n", _ifxhc->hc_num);
+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
+ disable_hc_int(_hc_regs,datatglerr);
+ return 1;
+}
+
+
+/*
+ * Interrupts which should not been triggered
+ */
+static int32_t handle_hc_frmovrun_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ IFX_ERROR( "--Host Channel %d Interrupt: "
+ "FrameOverRun Error--\n", _ifxhc->hc_num);
+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
+ disable_hc_int(_hc_regs,frmovrun);
+ return 1;
+}
+
+static int32_t handle_hc_bblerr_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ IFX_ERROR( "--Host Channel %d Interrupt: "
+ "BBL Error--\n", _ifxhc->hc_num);
+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
+ disable_hc_int(_hc_regs,bblerr);
+ return 1;
+}
+
+static int32_t handle_hc_xacterr_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ IFX_ERROR( "--Host Channel %d Interrupt: "
+ "XACT Error--\n", _ifxhc->hc_num);
+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
+ disable_hc_int(_hc_regs,xacterr);
+ return 1;
+}
+
+
+static int32_t handle_hc_stall_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ IFX_ERROR( "--Host Channel %d Interrupt: "
+ "STALL--\n", _ifxhc->hc_num);
+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
+ disable_hc_int(_hc_regs,stall);
+ return 1;
+}
+
+static int32_t handle_hc_xfercomp_intr(ifxhcd_hcd_t *_ifxhcd,
+ ifxhcd_hc_t *_ifxhc,
+ ifxusb_hc_regs_t *_hc_regs,
+ ifxhcd_urbd_t *_urbd)
+{
+ IFX_ERROR( "--Host Channel %d Interrupt: "
+ "XFERCOMP--\n", _ifxhc->hc_num);
+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
+ disable_hc_int(_hc_regs,xfercomp);
+ return 1;
+}
+
+/* This interrupt indicates that the specified host channels has a pending
+ * interrupt. There are multiple conditions that can cause each host channel
+ * interrupt. This function determines which conditions have occurred for this
+ * host channel interrupt and handles them appropriately. */
+static int32_t handle_hc_n_intr (ifxhcd_hcd_t *_ifxhcd, uint32_t _num)
+{
+ uint32_t hcintval,hcintmsk;
+ hcint_data_t hcint;
+ ifxhcd_hc_t *ifxhc;
+ ifxusb_hc_regs_t *hc_regs;
+ ifxhcd_urbd_t *urbd;
+
+ int retval = 0;
+
+ IFX_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", _num);
+
+ ifxhc = &_ifxhcd->ifxhc[_num];
+ hc_regs = _ifxhcd->core_if.hc_regs[_num];
+
+ hcintval = ifxusb_rreg(&hc_regs->hcint);
+ hcintmsk = ifxusb_rreg(&hc_regs->hcintmsk);
+ hcint.d32 = hcintval & hcintmsk;
+ IFX_DEBUGPL(DBG_HCDV, " 0x%08x & 0x%08x = 0x%08x\n",
+ hcintval, hcintmsk, hcint.d32);
+
+ urbd = ifxhc->epqh->urbd;
+
+ if (hcint.b.ahberr)
+ retval |= handle_hc_ahberr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
+ else if (hcint.b.chhltd)
+ retval |= handle_hc_chhltd_intr(_ifxhcd, ifxhc, hc_regs, urbd);
+ else
+ {
+ if (hcint.b.datatglerr)
+ retval |= handle_hc_datatglerr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
+ if (hcint.b.frmovrun)
+ retval |= handle_hc_frmovrun_intr(_ifxhcd, ifxhc, hc_regs, urbd);
+ if (hcint.b.bblerr)
+ retval |= handle_hc_bblerr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
+ if (hcint.b.xacterr)
+ retval |= handle_hc_xacterr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
+ if (hcint.b.nyet)
+ retval |= handle_hc_nyet_intr(_ifxhcd, ifxhc, hc_regs, urbd);
+ if (hcint.b.ack)
+ retval |= handle_hc_ack_intr(_ifxhcd, ifxhc, hc_regs, urbd);
+ if (hcint.b.nak)
+ retval |= handle_hc_nak_intr(_ifxhcd, ifxhc, hc_regs, urbd);
+ if (hcint.b.stall)
+ retval |= handle_hc_stall_intr(_ifxhcd, ifxhc, hc_regs, urbd);
+ if (hcint.b.xfercomp)
+ retval |= handle_hc_xfercomp_intr(_ifxhcd, ifxhc, hc_regs, urbd);
+ }
+
+ ifxusb_wreg(&hc_regs->hcint,hcintval);
+
+ return retval;
+}
+
+
+static uint8_t update_interval_counter(ifxhcd_epqh_t *_epqh,uint32_t _diff)
+{
+ if(_diff>=_epqh->period_counter)
+ {
+ _epqh->period_do=1;
+ if(_diff>_epqh->interval)
+ _epqh->period_counter=1;
+ else
+ _epqh->period_counter=_epqh->period_counter+_epqh->interval-_diff;
+ return 1;
+ }
+ _epqh->period_counter=_epqh->period_counter-_diff;
+ return 0;
+}
+
+static
+void process_unaligned( ifxhcd_epqh_t *_epqh, ifxusb_core_if_t *_core_if)
+{
+ ifxhcd_urbd_t *urbd;
+ urbd =_epqh->urbd;
+
+ #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
+ if(!urbd->aligned_checked)
+ {
+ #if defined(__UNALIGNED_BUF_ADJ__)
+ uint32_t xfer_len;
+ xfer_len=urbd->xfer_len;
+ if(urbd->is_in && xfer_len<_epqh->mps)
+ xfer_len = _epqh->mps;
+// urbd->using_aligned_buf=0;
+
+ if(xfer_len > 0 && ((unsigned long)urbd->xfer_buff) & _core_if->unaligned_mask)
+ {
+ if( urbd->aligned_buf
+ && urbd->aligned_buf_len > 0
+ && urbd->aligned_buf_len < xfer_len
+ )
+ {
+ ifxusb_free_buf_h(urbd->aligned_buf);
+ urbd->aligned_buf=NULL;
+ urbd->aligned_buf_len=0;
+ }
+ if(! urbd->aligned_buf || ! urbd->aligned_buf_len)
+ {
+ urbd->aligned_buf = ifxusb_alloc_buf_h(xfer_len, urbd->is_in);
+ if(urbd->aligned_buf)
+ urbd->aligned_buf_len = xfer_len;
+ }
+ if(urbd->aligned_buf)
+ {
+ if(!urbd->is_in)
+ memcpy(urbd->aligned_buf, urbd->xfer_buff, xfer_len);
+// urbd->using_aligned_buf=1;
+ _epqh->hc->xfer_buff = urbd->aligned_buf;
+ }
+ else
+ IFX_WARN("%s():%d\n",__func__,__LINE__);
+ }
+ if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
+ {
+// urbd->using_aligned_setup=0;
+ if(((unsigned long)urbd->setup_buff) & _core_if->unaligned_mask)
+ {
+ if(! urbd->aligned_setup)
+ urbd->aligned_setup = ifxusb_alloc_buf_h(8,0);
+ if(urbd->aligned_setup)
+ {
+ memcpy(urbd->aligned_setup, urbd->setup_buff, 8);
+// urbd->using_aligned_setup=1;
+ }
+ else
+ IFX_WARN("%s():%d\n",__func__,__LINE__);
+ _epqh->hc->xfer_buff = urbd->aligned_setup;
+ }
+ }
+ #elif defined(__UNALIGNED_BUF_CHK__)
+ if(_epqh->urbd->is_in)
+ {
+ if(_epqh->urbd->xfer_len==0)
+ IFX_WARN("%s():%d IN xfer while length is zero \n",__func__,__LINE__);
+ else{
+ if(_epqh->urbd->xfer_len < _epqh->mps)
+ IFX_WARN("%s():%d IN xfer while length < mps \n",__func__,__LINE__);
+ if(((unsigned long)_epqh->urbd->xfer_buff) & _core_if->unaligned_mask)
+ IFX_WARN("%s():%d IN xfer Buffer UNALIGNED\n",__func__,__LINE__);
+ }
+ }
+ else
+ {
+ if(_epqh->urbd->xfer_len > 0 && (((unsigned long)_epqh->urbd->xfer_buff) & _core_if->unaligned_mask))
+ IFX_WARN("%s():%d OUT xfer Buffer UNALIGNED\n",__func__,__LINE__);
+ }
+ if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
+ {
+ if(((unsigned long)_epqh->urbd->setup_buff) & _core_if->unaligned_mask)
+ IFX_WARN("%s():%d SETUP xfer Buffer UNALIGNED\n",__func__,__LINE__);
+ }
+ #endif
+ }
+ urbd->aligned_checked=1;
+ #endif
+}
+
+/*!
+ \brief Assigns transactions from a URBD to a free host channel and initializes the
+ host channel to perform the transactions. The host channel is removed from
+ the free list.
+ \param _ifxhcd The HCD state structure.
+ \param _epqh Transactions from the first URBD for this EPQH are selected and assigned to a free host channel.
+ */
+static
+int assign_hc(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh,ifxhcd_urbd_t *_urbd)
+{
+ ifxhcd_hc_t *ifxhc;
+ struct urb *urb;
+
+ IFX_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, _ifxhcd, _epqh);
+
+ if(_ifxhcd->disconnecting)
+ {
+ printk(KERN_INFO "Warning: %s() Port is in discoonection\n",__func__);
+ return 0;
+ }
+
+ if(!_epqh) return 0;
+ if(!_urbd) return 0;
+ if(!_urbd->urb) return 0;
+
+ {
+ int i;
+ int num_channels = _ifxhcd->core_if.params.host_channels;
+ for(i=0;i<num_channels ; i++)
+ {
+ hcchar_data_t hcchar;
+ ifxusb_hc_regs_t *hc_regs;
+ hc_regs = _ifxhcd->core_if.hc_regs[i];
+ if(_ifxhcd->ifxhc[i].phase!=HC_IDLE)
+ {
+ continue;
+ }
+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
+ if(hcchar.b.chen || hcchar.b.chdis)
+ {
+ continue;
+ }
+ break;
+ }
+
+ if(i<num_channels)
+ {
+ ifxhc=&_ifxhcd->ifxhc[i];
+ ifxhc->phase=HC_ASSIGNED;
+ }
+ else
+ return 0;
+ }
+
+ urb = _urbd->urb;
+ _epqh->hc = ifxhc;
+ _epqh->urbd = _urbd;
+ ifxhc->epqh = _epqh;
+ /*
+ * Use usb_pipedevice to determine device address. This address is
+ * 0 before the SET_ADDRESS command and the correct address afterward.
+ */
+ ifxhc->dev_addr = usb_pipedevice(urb->pipe);
+ ifxhc->ep_num = usb_pipeendpoint(urb->pipe);
+
+ if (urb->dev->speed == USB_SPEED_LOW) ifxhc->speed = IFXUSB_EP_SPEED_LOW;
+ else if (urb->dev->speed == USB_SPEED_FULL) ifxhc->speed = IFXUSB_EP_SPEED_FULL;
+ else ifxhc->speed = IFXUSB_EP_SPEED_HIGH;
+
+ ifxhc->mps = _epqh->mps;
+ ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+ ifxhc->ep_type = _epqh->ep_type;
+
+ ifxhc->split = 0;
+ if (_epqh->need_split)
+ {
+ ifxhc->split = 1;
+ ifxhc->hub_addr = urb->dev->tt->hub->devnum;
+ ifxhc->port_addr = urb->dev->ttport;
+ }
+ return 1;
+}
+
+/*!
+ \brief Assigns transactions from a URBD to a free host channel and initializes the
+ host channel to perform the transactions. The host channel is removed from
+ the free list.
+ \param _ifxhcd The HCD state structure.
+ \param _epqh Transactions from the first URBD for this EPQH are selected and assigned to a free host channel.
+ */
+static
+void init_hc(ifxhcd_epqh_t *_epqh)
+{
+ ifxhcd_hc_t *ifxhc;
+ ifxhcd_urbd_t *urbd;
+ struct urb *urb;
+ ifxhcd_hcd_t *ifxhcd;
+
+ IFX_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _epqh);
+
+ ifxhc =_epqh->hc;
+ urbd =_epqh->urbd;
+ ifxhcd=_epqh->ifxhcd;
+ urb = urbd->urb;
+ #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
+ urbd->aligned_checked=0;
+ #endif
+
+ ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
+
+ if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
+ {
+ ifxhc->control_phase =IFXHCD_CONTROL_SETUP;
+ ifxhc->is_in = 0;
+ ifxhc->data_pid_start = IFXUSB_HC_PID_SETUP;
+ ifxhc->xfer_buff = urbd->setup_buff;
+ ifxhc->xfer_len = 8;
+ ifxhc->xfer_count = 0;
+ ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
+ ifxhc->sof_delay = 0;
+ _epqh->do_ping=0;
+ if(!ifxhc->is_in && ifxhc->split==0)
+ _epqh->do_ping=1;
+ }
+ else if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
+ {
+ #ifdef __EN_ISOC__
+ struct usb_iso_packet_descriptor *frame_desc;
+ ifxhc->is_in = urbd->is_in;
+ frame_desc = &urb->iso_frame_desc[urbd->isoc_frame_index];
+ urbd->xfer_len = ifxhc->xfer_len = frame_desc->length;
+ ifxhc->xfer_buff = urbd->xfer_buff;
+ ifxhc->xfer_buff += frame_desc->offset;
+ ifxhc->xfer_count = 0;
+ ifxhc->sof_delay = 0;
+ if(usb_gettoggle (urb->dev,usb_pipeendpoint (urb->pipe), (ifxhc->is_in)?0:1))
+ ifxhc->data_pid_start = IFXUSB_HCTSIZ_DATA1;
+ else
+ ifxhc->data_pid_start = IFXUSB_HCTSIZ_DATA0;
+
+ if(ifxhc->is_in)
+ ifxhc->short_rw =0;
+ else
+ ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
+ #ifdef __EN_ISOC_SPLIT__
+ ifxhc->isoc_xact_pos = IFXUSB_HCSPLIT_XACTPOS_ALL;
+ #endif
+
+ _epqh->isoc_frame_index=0;
+ _epqh->isoc_now=0;
+ _epqh->isoc_start_frame=0;
+ if(_urb->transfer_flags && URB_ISO_ASAP)
+ _epqh->isoc_now=1;
+ else
+ _epqh->isoc_start_frame=_urb->start_frame;
+ #ifdef __EN_ISOC_SPLIT__
+ _epqh->isoc_split_pos =0;
+ _epqh->isoc_split_offset=0;
+ #endif
+ _epqh->do_ping=0;
+ #endif
+ }
+ else
+ {
+ ifxhc->is_in = urbd->is_in;
+ ifxhc->xfer_buff = urbd->xfer_buff;
+ ifxhc->xfer_len = urbd->xfer_len;
+ ifxhc->xfer_count = 0;
+ ifxhc->sof_delay = 0;
+// if(ifxhc->xfer_len==13 && ifxhc->is_in && _epqh->ep_type==IFXUSB_EP_TYPE_BULK && ifxhc->split==0)
+// ifxhc->sof_delay = 8;
+ if(usb_gettoggle (urb->dev,usb_pipeendpoint (urb->pipe), (ifxhc->is_in)?0:1))
+ ifxhc->data_pid_start = IFXUSB_HCTSIZ_DATA1;
+ else
+ ifxhc->data_pid_start = IFXUSB_HCTSIZ_DATA0;
+ if(ifxhc->is_in)
+ ifxhc->short_rw =0;
+ else
+ ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
+ _epqh->do_ping=0;
+ if(!ifxhc->is_in && ifxhc->split==0)
+ {
+ if(_epqh->ep_type==IFXUSB_EP_TYPE_BULK) _epqh->do_ping=1;
+ }
+ }
+
+ {
+ hcint_data_t hc_intr_mask;
+ uint8_t hc_num = ifxhc->hc_num;
+ ifxusb_hc_regs_t *hc_regs = ifxhcd->core_if.hc_regs[hc_num];
+
+ /* Clear old interrupt conditions for this host channel. */
+ hc_intr_mask.d32 = 0xFFFFFFFF;
+ hc_intr_mask.b.reserved = 0;
+ ifxusb_wreg(&hc_regs->hcint, hc_intr_mask.d32);
+
+ /* Enable channel interrupts required for this transfer. */
+ hc_intr_mask.d32 = 0;
+ hc_intr_mask.b.chhltd = 1;
+ hc_intr_mask.b.ahberr = 1;
+
+ ifxusb_wreg(&hc_regs->hcintmsk, hc_intr_mask.d32);
+
+ /* Enable the top level host channel interrupt. */
+ {
+ uint32_t intr_enable;
+ intr_enable = (1 << hc_num);
+ ifxusb_mreg(&ifxhcd->core_if.host_global_regs->haintmsk, 0, intr_enable);
+ }
+
+ /* Make sure host channel interrupts are enabled. */
+ {
+ gint_data_t gintmsk ={.d32 = 0};
+ gintmsk.b.hcintr = 1;
+ ifxusb_mreg(&ifxhcd->core_if.core_global_regs->gintmsk, 0, gintmsk.d32);
+ }
+
+ /*
+ * Program the HCCHARn register with the endpoint characteristics for
+ * the current transfer.
+ */
+ {
+ hcchar_data_t hcchar;
+
+ hcchar.d32 = 0;
+ hcchar.b.devaddr = ifxhc->dev_addr;
+ hcchar.b.epnum = ifxhc->ep_num;
+ hcchar.b.lspddev = (ifxhc->speed == IFXUSB_EP_SPEED_LOW);
+ hcchar.b.eptype = ifxhc->ep_type;
+ hcchar.b.mps = ifxhc->mps;
+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
+
+ IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, ifxhc->hc_num);
+ IFX_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n" , hcchar.b.devaddr);
+ IFX_DEBUGPL(DBG_HCDV, " Ep Num: %d\n" , hcchar.b.epnum);
+ IFX_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
+ IFX_DEBUGPL(DBG_HCDV, " Ep Type: %d\n" , hcchar.b.eptype);
+ IFX_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n" , hcchar.b.mps);
+ IFX_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n" , hcchar.b.multicnt);
+ }
+ /* Program the HCSPLIT register for SPLITs */
+ {
+ hcsplt_data_t hcsplt;
+
+ hcsplt.d32 = 0;
+ if (ifxhc->split)
+ {
+ IFX_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n", ifxhc->hc_num,
+ (ifxhc->split==2) ? "CSPLIT" : "SSPLIT");
+ hcsplt.b.spltena = 1;
+ hcsplt.b.compsplt = (ifxhc->split==2);
+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
+ if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
+ hcsplt.b.xactpos = ifxhc->isoc_xact_pos;
+ else
+ #endif
+ hcsplt.b.xactpos = IFXUSB_HCSPLIT_XACTPOS_ALL;
+ hcsplt.b.hubaddr = ifxhc->hub_addr;
+ hcsplt.b.prtaddr = ifxhc->port_addr;
+ IFX_DEBUGPL(DBG_HCDV, " comp split %d\n" , hcsplt.b.compsplt);
+ IFX_DEBUGPL(DBG_HCDV, " xact pos %d\n" , hcsplt.b.xactpos);
+ IFX_DEBUGPL(DBG_HCDV, " hub addr %d\n" , hcsplt.b.hubaddr);
+ IFX_DEBUGPL(DBG_HCDV, " port addr %d\n" , hcsplt.b.prtaddr);
+ IFX_DEBUGPL(DBG_HCDV, " is_in %d\n" , ifxhc->is_in);
+ IFX_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n" , ifxhc->mps);
+ IFX_DEBUGPL(DBG_HCDV, " xferlen: %d\n" , ifxhc->xfer_len);
+ }
+ ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32);
+ }
+ }
+ process_unaligned(_epqh,&ifxhcd->core_if);
+
+
+ #ifdef __NAKSTOP__
+ ifxhc->stop_on=0;
+ if (!ifxhc->split && ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
+ {
+ #ifdef __INNAKSTOP_BULK__
+ if(ifxhc->is_in)
+ ifxhc->stop_on=1;
+ #endif
+ #ifdef __PINGSTOP_BULK__
+ if(!ifxhc->is_in)
+ ifxhc->stop_on=1;
+ #endif
+ }
+ #endif
+}
+
+
+static
+void select_eps_sub(ifxhcd_hcd_t *_ifxhcd)
+{
+ struct list_head *epqh_ptr;
+ ifxhcd_epqh_t *epqh;
+ struct list_head *urbd_ptr;
+ unsigned long flags;
+ ifxhcd_urbd_t *urbd;
+
+ hfnum_data_t hfnum;
+ uint32_t fndiff;
+
+ if(_ifxhcd->disconnecting)
+ {
+// printk(KERN_INFO "Warning: %s() Port is in discoonection\n",__func__);
+ return ;
+ }
+
+ local_irq_save(flags);
+ LOCK_EPQH_LIST(_ifxhcd);
+
+ hfnum.d32 = ifxusb_rreg(&_ifxhcd->core_if.host_global_regs->hfnum);
+ fndiff = hfnum.b.frnum;
+ fndiff+= 0x00004000;
+ fndiff-= _ifxhcd->lastframe ;
+ fndiff&= 0x00003FFF;
+ if(!fndiff) fndiff =1;
+
+ #ifdef __EN_ISOC__
+ epqh_ptr = _ifxhcd->epqh_list_isoc.next;
+ while (epqh_ptr != &_ifxhcd->epqh_list_isoc)
+ {
+ epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, ql);
+ epqh_ptr = epqh_ptr->next;
+
+ #ifdef __DYN_SOF_INTR__
+ if (!list_empty(&epqh->urbd_list))
+ _ifxhcd->dyn_sof_count = DYN_SOF_COUNT_DEF;
+ #endif
+
+ if(epqh->pause)
+ continue;
+ if(epqh->phase==EPQH_READY)
+ {
+ if(update_interval_counter(epqh,fndiff) || epqh->isoc_now)
+ {
+ LOCK_URBD_LIST(epqh);
+ urbd_ptr = epqh->urbd_list.next;
+ while (urbd_ptr != &epqh->urbd_list)
+ {
+ urbd = list_entry(urbd_ptr, ifxhcd_urbd_t, ql);
+ urbd_ptr=urbd_ptr->next;
+ if(urbd->phase==URBD_IDLE)
+ {
+ if(assign_hc(_ifxhcd, epqh,urbd))
+ {
+ IFX_DEBUGPL(DBG_HCD, " select_eps ISOC\n");
+ #ifdef __EPQD_DESTROY_TIMEOUT__
+ del_timer(&epqh->destroy_timer);
+ #endif
+ epqh->isoc_now=0;
+ list_del_init (&epqh->ql);
+ list_add_tail(&epqh->ql, &_ifxhcd->epqh_list_isoc);
+ init_hc(epqh);
+ epqh->phase=EPQH_ACTIVE;
+ urbd->phase==URBD_ACTIVE;
+ epqh->hc.phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, epqh->hc);
+ }
+ break;
+ }
+ }
+ UNLOCK_URBD_LIST(epqh);
+ }
+ }
+ }
+ #endif //__EN_ISOC__
+
+ epqh_ptr = _ifxhcd->epqh_list_intr.next;
+ while (epqh_ptr != &_ifxhcd->epqh_list_intr)
+ {
+ epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, ql);
+ epqh_ptr = epqh_ptr->next;
+ #ifdef __DYN_SOF_INTR__
+ if (!list_empty(&epqh->urbd_list))
+ _ifxhcd->dyn_sof_count = DYN_SOF_COUNT_DEF;
+ #endif
+ if(epqh->pause)
+ continue;
+ if(epqh->phase==EPQH_READY)
+ {
+ if(update_interval_counter(epqh,fndiff))
+ {
+ LOCK_URBD_LIST(epqh);
+ urbd_ptr = epqh->urbd_list.next;
+ while (urbd_ptr != &epqh->urbd_list)
+ {
+ urbd = list_entry(urbd_ptr, ifxhcd_urbd_t, ql);
+ urbd_ptr=urbd_ptr->next;
+ if(urbd->phase==URBD_IDLE)
+ {
+ if(assign_hc(_ifxhcd, epqh,urbd))
+ {
+ IFX_DEBUGPL(DBG_HCD, " select_eps INTR\n");
+ #ifdef __EPQD_DESTROY_TIMEOUT__
+ del_timer(&epqh->destroy_timer);
+ #endif
+ list_del_init (&epqh->ql);
+ list_add_tail(&epqh->ql, &_ifxhcd->epqh_list_intr);
+ init_hc(epqh);
+ epqh->phase=EPQH_ACTIVE;
+ urbd->phase=URBD_ACTIVE;
+ epqh->hc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, epqh->hc);
+ }
+ break;
+ }
+ }
+ UNLOCK_URBD_LIST(epqh);
+ }
+ }
+ else if(epqh->phase==EPQH_STDBY)
+ {
+ if(epqh->period_counter > 0 )
+ epqh->period_counter --;
+ if(epqh->period_counter == 0)
+ ifxhcd_epqh_idle_periodic(epqh);
+ update_interval_counter(epqh,fndiff);
+ }
+ else
+ update_interval_counter(epqh,fndiff);
+ }
+
+ epqh_ptr = _ifxhcd->epqh_list_np.next;
+ while (epqh_ptr != &_ifxhcd->epqh_list_np) // may need to preserve at lease one for period
+ {
+ epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, ql);
+ epqh_ptr = epqh_ptr->next;
+ #ifdef __DYN_SOF_INTR__
+ if (!list_empty(&epqh->urbd_list))
+ _ifxhcd->dyn_sof_count = DYN_SOF_COUNT_DEF;
+ #endif
+ if(epqh->pause)
+ continue;
+ if(epqh->phase==EPQH_READY)
+ {
+ LOCK_URBD_LIST(epqh);
+ urbd_ptr = epqh->urbd_list.next;
+ while (urbd_ptr != &epqh->urbd_list)
+ {
+ urbd = list_entry(urbd_ptr, ifxhcd_urbd_t, ql);
+ urbd_ptr=urbd_ptr->next;
+ if(urbd->phase==URBD_IDLE)
+ {
+ if(assign_hc(_ifxhcd, epqh,urbd))
+ {
+ IFX_DEBUGPL(DBG_HCD, " select_eps Non-Period\n");
+ #ifdef __EPQD_DESTROY_TIMEOUT__
+ del_timer(&epqh->destroy_timer);
+ #endif
+ list_del_init (&epqh->ql);
+ list_add_tail(&epqh->ql, &_ifxhcd->epqh_list_np);
+ init_hc(epqh);
+ epqh->phase=EPQH_ACTIVE;
+ urbd->phase=URBD_ACTIVE;
+ epqh->hc->phase=HC_WAITING;
+ ifxhcd_hc_start(_ifxhcd, epqh->hc);
+ }
+ break;
+ }
+ }
+ UNLOCK_URBD_LIST(epqh);
+ }
+ }
+
+ _ifxhcd->lastframe=hfnum.b.frnum;
+
+ UNLOCK_EPQH_LIST(_ifxhcd);
+ local_irq_restore(flags);
+}
+
+static
+void select_eps_func(unsigned long data)
+{
+ ifxhcd_hcd_t *ifxhcd;
+ ifxhcd=((ifxhcd_hcd_t *)data);
+
+ select_eps_sub(ifxhcd);
+}
+
+/*!
+ \fn void select_eps(ifxhcd_hcd_t *_ifxhcd)
+ \brief This function selects transactions from the HCD transfer schedule and assigns them to available host channels.
+ \param _ifxhcd Pointer to the sate of HCD structure
+ \ingroup IFXUSB_HCD
+ */
+void select_eps(ifxhcd_hcd_t *_ifxhcd)
+{
+ if(in_irq())
+ {
+ if(!_ifxhcd->tasklet_select_eps.func)
+ {
+ _ifxhcd->tasklet_select_eps.next = NULL;
+ _ifxhcd->tasklet_select_eps.state = 0;
+ atomic_set( &_ifxhcd->tasklet_select_eps.count, 0);
+ _ifxhcd->tasklet_select_eps.func = select_eps_func;
+ _ifxhcd->tasklet_select_eps.data = (unsigned long)_ifxhcd;
+ }
+ tasklet_schedule(&_ifxhcd->tasklet_select_eps);
+ }
+ else
+ {
+ select_eps_sub(_ifxhcd);
+ }
+}
+
+static
+void ifxhcd_hc_kickstart(ifxhcd_hcd_t *_ifxhcd)
+{
+ int num_channels;
+ ifxusb_hc_regs_t *hc_regs;
+ int i;
+ ifxhcd_hc_t *ifxhc;
+ num_channels = _ifxhcd->core_if.params.host_channels;
+
+ for (i = 0; i < num_channels; i++)
+ {
+ ifxhc=&_ifxhcd->ifxhc[i];
+ if(ifxhc->phase==HC_STARTING)
+ {
+ if(ifxhc->sof_delay) ifxhc->sof_delay--;
+ if(!ifxhc->sof_delay)
+ {
+ hcint_data_t hcint;
+// ifxhc->erron=0;
+ hc_regs = _ifxhcd->core_if.hc_regs[i];
+ hcint.d32 =0xFFFFFFFF;
+ ifxusb_wreg(&hc_regs->hcint, hcint.d32);
+ hcint.d32 =ifxusb_rreg(&hc_regs->hcintmsk);
+ hcint.b.nak =0;
+ hcint.b.ack =0;
+ hcint.b.nyet=0;
+ if(ifxhc->erron)
+ {
+ hcint.b.ack =1;
+ hcint.b.nak =1;
+ hcint.b.nyet =1;
+ }
+ #ifdef __NAKSTOP__
+ if(ifxhc->stop_on)
+ {
+ hcint.b.ack =1;
+ hcint.b.nak =1;
+ }
+ #endif
+ ifxusb_wreg(&hc_regs->hcintmsk, hcint.d32);
+ ifxusb_wreg(&hc_regs->hcchar, ifxhc->hcchar);
+ ifxhc->phase=HC_STARTED;
+ }
+ }
+ }
+
+ for (i = 0; i < num_channels; i++)
+ {
+ ifxhc=&_ifxhcd->ifxhc[i];
+ if(ifxhc->phase==HC_WAITING &&
+ (ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
+ )
+ {
+ ifxhcd_hc_start(_ifxhcd, ifxhc);
+ }
+ }
+
+ for (i = 0; i < num_channels; i++)
+ {
+ ifxhc=&_ifxhcd->ifxhc[i];
+ if(ifxhc->phase==HC_WAITING)
+ {
+ ifxhcd_hc_start(_ifxhcd, ifxhc);
+ }
+ }
+}
+
+/*
+ * Handles the start-of-frame interrupt in host mode. Non-periodic
+ * transactions may be queued to the DWC_otg controller for the current
+ * (micro)frame. Periodic transactions may be queued to the controller for the
+ * next (micro)frame.
+ */
+static
+int32_t handle_sof_intr (ifxhcd_hcd_t *_ifxhcd)
+{
+ _ifxhcd->pkt_remaining=_ifxhcd->pkt_remaining_reload;
+ ifxhcd_hc_kickstart(_ifxhcd);
+
+ select_eps(_ifxhcd);
+
+ /* Clear interrupt */
+ {
+ gint_data_t gintsts;
+ gintsts.d32=0;
+ gintsts.b.sofintr = 1;
+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
+
+ #ifdef __DYN_SOF_INTR__
+ if(_ifxhcd->dyn_sof_count)
+ _ifxhcd->dyn_sof_count--;
+ if(!_ifxhcd->dyn_sof_count)
+ ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, gintsts.d32,0);
+ #endif
+ }
+ return 1;
+}
+
+
+
+/* There are multiple conditions that can cause a port interrupt. This function
+ * determines which interrupt conditions have occurred and handles them
+ * appropriately. */
+static int32_t handle_port_intr (ifxhcd_hcd_t *_ifxhcd)
+{
+ int retval = 0;
+ hprt0_data_t hprt0;
+ hprt0_data_t hprt0_modify;
+
+ hprt0.d32 =
+ hprt0_modify.d32 = ifxusb_rreg(_ifxhcd->core_if.hprt0);
+
+ /* Clear appropriate bits in HPRT0 to clear the interrupt bit in
+ * GINTSTS */
+
+ hprt0_modify.b.prtena = 0;
+ hprt0_modify.b.prtconndet = 0;
+ hprt0_modify.b.prtenchng = 0;
+ hprt0_modify.b.prtovrcurrchng = 0;
+
+ /* Port Connect Detected
+ * Set flag and clear if detected */
+ if (hprt0.b.prtconndet) {
+ IFX_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x "
+ "Port Connect Detected--\n", hprt0.d32);
+ _ifxhcd->flags.b.port_connect_status_change = 1;
+ _ifxhcd->flags.b.port_connect_status = 1;
+ hprt0_modify.b.prtconndet = 1;
+
+ /* The Hub driver asserts a reset when it sees port connect
+ * status change flag */
+ retval |= 1;
+ }
+
+ /* Port Enable Changed
+ * Clear if detected - Set internal flag if disabled */
+ if (hprt0.b.prtenchng) {
+ IFX_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
+ "Port Enable Changed--\n", hprt0.d32);
+ hprt0_modify.b.prtenchng = 1;
+ if (hprt0.b.prtena == 1)
+ {
+ /* Port has been enabled set the reset change flag */
+ _ifxhcd->flags.b.port_reset_change = 1;
+ if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
+ _ifxhcd->pkt_remaining_reload=_ifxhcd->pkt_remaining_reload_hs;
+ else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
+ _ifxhcd->pkt_remaining_reload=_ifxhcd->pkt_remaining_reload_ls;
+ else
+ _ifxhcd->pkt_remaining_reload=_ifxhcd->pkt_remaining_reload_fs;
+ }
+ else
+ _ifxhcd->flags.b.port_enable_change = 1;
+ retval |= 1;
+ }
+
+ /* Overcurrent Change Interrupt */
+
+ if (hprt0.b.prtovrcurrchng) {
+ IFX_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
+ "Port Overcurrent Changed--\n", hprt0.d32);
+ _ifxhcd->flags.b.port_over_current_change = 1;
+ hprt0_modify.b.prtovrcurrchng = 1;
+ retval |= 1;
+ }
+
+ /* Clear Port Interrupts */
+ ifxusb_wreg(_ifxhcd->core_if.hprt0, hprt0_modify.d32);
+ return retval;
+}
+
+/*
+ * This interrupt indicates that SUSPEND state has been detected on
+ * the USB.
+ * No Functioning in Host Mode
+ */
+static int32_t handle_usb_suspend_intr(ifxhcd_hcd_t *_ifxhcd)
+{
+ gint_data_t gintsts;
+ IFX_DEBUGP("USB SUSPEND RECEIVED!\n");
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.usbsuspend = 1;
+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
+ return 1;
+}
+
+/*
+ * This interrupt indicates that the IFXUSB controller has detected a
+ * resume or remote wakeup sequence. If the IFXUSB controller is in
+ * low power mode, the handler must brings the controller out of low
+ * power mode. The controller automatically begins resume
+ * signaling. The handler schedules a time to stop resume signaling.
+ */
+static int32_t handle_wakeup_detected_intr(ifxhcd_hcd_t *_ifxhcd)
+{
+ gint_data_t gintsts;
+ hprt0_data_t hprt0 = {.d32=0};
+ pcgcctl_data_t pcgcctl = {.d32=0};
+ ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
+
+ IFX_DEBUGPL(DBG_ANY, "++Resume and Remote Wakeup Detected Interrupt++\n");
+
+ /*
+ * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
+ * so that OPT tests pass with all PHYs).
+ */
+ /* Restart the Phy Clock */
+ pcgcctl.b.stoppclk = 1;
+ ifxusb_mreg(core_if->pcgcctl, pcgcctl.d32, 0);
+ UDELAY(10);
+
+ /* Now wait for 70 ms. */
+ hprt0.d32 = ifxusb_read_hprt0( core_if );
+ IFX_DEBUGPL(DBG_ANY,"Resume: HPRT0=%0x\n", hprt0.d32);
+ MDELAY(70);
+ hprt0.b.prtres = 0; /* Resume */
+ ifxusb_wreg(core_if->hprt0, hprt0.d32);
+ IFX_DEBUGPL(DBG_ANY,"Clear Resume: HPRT0=%0x\n", ifxusb_rreg(core_if->hprt0));
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.wkupintr = 1;
+ ifxusb_wreg(&core_if->core_global_regs->gintsts, gintsts.d32);
+ return 1;
+}
+
+/*
+ * This interrupt indicates that a device is initiating the Session
+ * Request Protocol to request the host to turn on bus power so a new
+ * session can begin. The handler responds by turning on bus power. If
+ * the DWC_otg controller is in low power mode, the handler brings the
+ * controller out of low power mode before turning on bus power.
+ */
+static int32_t handle_session_req_intr(ifxhcd_hcd_t *_ifxhcd)
+{
+ /* Clear interrupt */
+ gint_data_t gintsts = { .d32 = 0 };
+ gintsts.b.sessreqintr = 1;
+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
+ return 1;
+}
+
+/*
+ * This interrupt indicates that a device has been disconnected from
+ * the root port.
+ */
+static int32_t handle_disconnect_intr(ifxhcd_hcd_t *_ifxhcd)
+{
+ gint_data_t gintsts;
+
+ ifxhcd_disconnect(_ifxhcd);
+
+ gintsts.d32 = 0;
+ gintsts.b.disconnect = 1;
+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
+ return 1;
+}
+
+/*
+ * This function handles the Connector ID Status Change Interrupt. It
+ * reads the OTG Interrupt Register (GOTCTL) to determine whether this
+ * is a Device to Host Mode transition or a Host Mode to Device
+ * Transition.
+ * This only occurs when the cable is connected/removed from the PHY
+ * connector.
+ */
+static int32_t handle_conn_id_status_change_intr(ifxhcd_hcd_t *_ifxhcd)
+{
+ gint_data_t gintsts;
+
+ IFX_WARN("ID Status Change Interrupt: currently in %s mode\n",
+ ifxusb_mode(&_ifxhcd->core_if) ? "Host" : "Device");
+
+ gintsts.d32 = 0;
+ gintsts.b.conidstschng = 1;
+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
+ return 1;
+}
+
+static int32_t handle_otg_intr(ifxhcd_hcd_t *_ifxhcd)
+{
+ ifxusb_core_global_regs_t *global_regs = _ifxhcd->core_if.core_global_regs;
+ gotgint_data_t gotgint;
+ gotgint.d32 = ifxusb_rreg( &global_regs->gotgint);
+ /* Clear GOTGINT */
+ ifxusb_wreg (&global_regs->gotgint, gotgint.d32);
+ return 1;
+}
+
+/** This function will log a debug message */
+static int32_t handle_mode_mismatch_intr(ifxhcd_hcd_t *_ifxhcd)
+{
+ gint_data_t gintsts;
+
+ IFX_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
+ ifxusb_mode(&_ifxhcd->core_if) ? "Host" : "Device");
+ gintsts.d32 = 0;
+ gintsts.b.modemismatch = 1;
+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
+ return 1;
+}
+
+/** This function handles interrupts for the HCD. */
+int32_t ifxhcd_handle_intr (ifxhcd_hcd_t *_ifxhcd)
+{
+ int retval = 0;
+
+ ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
+ gint_data_t gintsts,gintsts2;
+
+ /* Check if HOST Mode */
+ if (ifxusb_is_device_mode(core_if))
+ {
+ IFX_ERROR("%s() CRITICAL! IN DEVICE MODE\n", __func__);
+ return 0;
+ }
+
+ gintsts.d32 = ifxusb_read_core_intr(core_if);
+ gintsts2.d32 = 0;
+
+ if (!gintsts.d32)
+ return 0;
+
+ //Common INT
+ if (gintsts.b.modemismatch)
+ {
+ retval |= handle_mode_mismatch_intr(_ifxhcd);
+ gintsts.b.modemismatch=0;
+ gintsts2.b.modemismatch=1;
+ }
+ if (gintsts.b.otgintr)
+ {
+ retval |= handle_otg_intr(_ifxhcd);
+ gintsts.b.otgintr=0;
+ gintsts2.b.otgintr=1;
+ }
+ if (gintsts.b.conidstschng)
+ {
+ retval |= handle_conn_id_status_change_intr(_ifxhcd);
+ gintsts.b.conidstschng=0;
+ gintsts2.b.conidstschng=1;
+ }
+ if (gintsts.b.disconnect)
+ {
+ retval |= handle_disconnect_intr(_ifxhcd);
+ gintsts.b.disconnect=0;
+ gintsts2.b.disconnect=1;
+ }
+ if (gintsts.b.sessreqintr)
+ {
+ retval |= handle_session_req_intr(_ifxhcd);
+ gintsts.b.sessreqintr=0;
+ gintsts2.b.sessreqintr=1;
+ }
+ if (gintsts.b.wkupintr)
+ {
+ retval |= handle_wakeup_detected_intr(_ifxhcd);
+ gintsts.b.wkupintr=0;
+ gintsts2.b.wkupintr=1;
+ }
+ if (gintsts.b.usbsuspend)
+ {
+ retval |= handle_usb_suspend_intr(_ifxhcd);
+ gintsts.b.usbsuspend=0;
+ gintsts2.b.usbsuspend=1;
+ }
+
+ //Host Int
+ if (gintsts.b.sofintr)
+ {
+ retval |= handle_sof_intr (_ifxhcd);
+ gintsts.b.sofintr=0;
+ gintsts2.b.sofintr=1;
+ }
+ if (gintsts.b.portintr)
+ {
+ retval |= handle_port_intr (_ifxhcd);
+ gintsts.b.portintr=0;
+ gintsts2.b.portintr=1;
+ }
+ if (gintsts.b.hcintr)
+ {
+ int i;
+ haint_data_t haint;
+ haint.d32 = ifxusb_read_host_all_channels_intr(core_if);
+ for (i=0; i<MAX_EPS_CHANNELS && i< core_if->params.host_channels; i++)
+ if (haint.b2.chint & (1 << i))
+ retval |= handle_hc_n_intr (_ifxhcd, i);
+ gintsts.b.hcintr=0;
+ gintsts2.b.hcintr=1;
+ }
+ return retval;
+}
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxhcd_queue.c b/package/kernel/lantiq/ltq-hcd/src/ifxhcd_queue.c
new file mode 100644
index 0000000000..a30fcd05e9
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxhcd_queue.c
@@ -0,0 +1,485 @@
+/*****************************************************************************
+ ** FILE NAME : ifxhcd_queue.c
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** AUTHOR : Chen, Howard
+ ** DESCRIPTION : This file contains the functions to manage Queue Heads and Queue
+ ** Transfer Descriptors.
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*!
+ \file ifxhcd_queue.c
+ \ingroup IFXUSB_DRIVER_V3
+ \brief This file contains the functions to manage Queue Heads and Queue
+ Transfer Descriptors.
+*/
+#include <linux/version.h>
+#include "ifxusb_version.h"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+
+#include "ifxusb_plat.h"
+#include "ifxusb_regs.h"
+#include "ifxusb_cif.h"
+#include "ifxhcd.h"
+
+#ifdef __EPQD_DESTROY_TIMEOUT__
+ #define epqh_self_destroy_timeout 300
+ static void eqph_destroy_func(unsigned long _ptr)
+ {
+ ifxhcd_epqh_t *epqh=(ifxhcd_epqh_t *)_ptr;
+ if(epqh)
+ {
+ if(epqh->sysep)
+ {
+ epqh->sysep->hcpriv=NULL;
+ }
+ ifxhcd_epqh_free (epqh);
+ }
+ }
+#endif
+
+/*!
+ \brief This function allocates and initializes a EPQH.
+
+ \param _ifxhcd The HCD state structure for the USB Host controller.
+ \param[in] _urb Holds the information about the device/endpoint that we need
+ to initialize the EPQH.
+
+ \return Returns pointer to the newly allocated EPQH, or NULL on error.
+ */
+static ifxhcd_epqh_t *ifxhcd_epqh_create (ifxhcd_hcd_t *_ifxhcd, struct urb *_urb)
+{
+ ifxhcd_epqh_t *epqh;
+
+ hprt0_data_t hprt0;
+ struct usb_host_endpoint *sysep = ifxhcd_urb_to_endpoint(_urb);
+
+ /* Allocate memory */
+// epqh=(ifxhcd_epqh_t *) kmalloc (sizeof(ifxhcd_epqh_t), GFP_KERNEL);
+ epqh=(ifxhcd_epqh_t *) kmalloc (sizeof(ifxhcd_epqh_t), GFP_ATOMIC);
+
+ if(epqh == NULL)
+ return NULL;
+
+ memset (epqh, 0, sizeof (ifxhcd_epqh_t));
+
+ epqh->sysep=sysep;
+
+ epqh->devno=_urb->dev->devnum;
+
+ epqh->ifxhcd=_ifxhcd;
+ epqh->phase=EPQH_IDLE;
+
+ /* Initialize EPQH */
+ switch (usb_pipetype(_urb->pipe))
+ {
+ case PIPE_CONTROL : epqh->ep_type = IFXUSB_EP_TYPE_CTRL; break;
+ case PIPE_BULK : epqh->ep_type = IFXUSB_EP_TYPE_BULK; break;
+ case PIPE_ISOCHRONOUS: epqh->ep_type = IFXUSB_EP_TYPE_ISOC; break;
+ case PIPE_INTERRUPT : epqh->ep_type = IFXUSB_EP_TYPE_INTR; break;
+ }
+
+ usb_settoggle(_urb->dev, usb_pipeendpoint (_urb->pipe), !usb_pipein(_urb->pipe), IFXUSB_HC_PID_DATA0);
+ epqh->mps = usb_maxpacket(_urb->dev, _urb->pipe, !(usb_pipein(_urb->pipe)));
+
+ INIT_LIST_HEAD(&epqh->urbd_list);
+ #ifdef __STRICT_ORDER__
+ INIT_LIST_HEAD(&epqh->release_list);
+ #endif
+ INIT_LIST_HEAD(&epqh->ql);
+ INIT_LIST_HEAD(&epqh->ql_all);
+ INIT_URBD_LIST(epqh);
+
+ epqh->hc = NULL;
+
+ /* FS/LS Enpoint on HS Hub
+ * NOT virtual root hub */
+ epqh->need_split = 0;
+ hprt0.d32 = ifxusb_read_hprt0 (&_ifxhcd->core_if);
+ if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED &&
+ ((_urb->dev->speed == USB_SPEED_LOW) ||
+ (_urb->dev->speed == USB_SPEED_FULL)) &&
+ (_urb->dev->tt) && (_urb->dev->tt->hub) && (_urb->dev->tt->hub->devnum != 1))
+ {
+ IFX_DEBUGPL(DBG_HCD, "QH init: EP %d: TT found at hub addr %d, for port %d\n",
+ usb_pipeendpoint(_urb->pipe), _urb->dev->tt->hub->devnum,
+ _urb->dev->ttport);
+ epqh->need_split = 1;
+ }
+
+ if (epqh->ep_type == IFXUSB_EP_TYPE_INTR ||
+ epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
+ {
+ /* Compute scheduling parameters once and save them. */
+ epqh->interval = _urb->interval;
+ if(epqh->need_split)
+ epqh->interval *= 8;
+ }
+
+ #ifdef __EN_ISOC__
+ if (epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
+ _ifxhcd->isoc_ep_count++;
+ #endif
+
+ epqh->period_counter=0;
+
+ #ifdef __EPQD_DESTROY_TIMEOUT__
+ /* Start a timer for this transfer. */
+ init_timer(&epqh->destroy_timer);
+ epqh->destroy_timer.function = eqph_destroy_func;
+ epqh->destroy_timer.data = (unsigned long)(epqh);
+ #endif
+
+ #ifdef __DEBUG__
+ IFX_DEBUGPL(DBG_HCD , "IFXUSB HCD EPQH Initialized\n");
+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - epqh = %p\n", epqh);
+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - Device Address = %d EP %d, %s\n",
+ _urb->dev->devnum,
+ usb_pipeendpoint(_urb->pipe),
+ usb_pipein(_urb->pipe) == USB_DIR_IN ? "IN" : "OUT");
+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - Speed = %s\n",
+ ({ char *speed; switch (_urb->dev->speed) {
+ case USB_SPEED_LOW: speed = "low" ; break;
+ case USB_SPEED_FULL: speed = "full"; break;
+ case USB_SPEED_HIGH: speed = "high"; break;
+ default: speed = "?"; break;
+ }; speed;}));
+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - Type = %s\n",
+ ({
+ char *type; switch (epqh->ep_type)
+ {
+ case IFXUSB_EP_TYPE_ISOC: type = "isochronous"; break;
+ case IFXUSB_EP_TYPE_INTR: type = "interrupt" ; break;
+ case IFXUSB_EP_TYPE_CTRL: type = "control" ; break;
+ case IFXUSB_EP_TYPE_BULK: type = "bulk" ; break;
+ default: type = "?"; break;
+ };
+ type;
+ }));
+ if (epqh->ep_type == IFXUSB_EP_TYPE_INTR)
+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - interval = %d\n", epqh->interval);
+ #endif
+
+ LOCK_EPQH_LIST_ALL(_ifxhcd);
+ list_add_tail(&epqh->ql_all, &_ifxhcd->epqh_list_all);
+ UNLOCK_EPQH_LIST_ALL(_ifxhcd);
+
+ LOCK_EPQH_LIST(_ifxhcd);
+ switch (epqh->ep_type)
+ {
+ case IFXUSB_EP_TYPE_CTRL:
+ case IFXUSB_EP_TYPE_BULK:
+
+ list_add_tail(&epqh->ql, &_ifxhcd->epqh_list_np);
+ break;
+ case IFXUSB_EP_TYPE_INTR:
+ list_add_tail(&epqh->ql, &_ifxhcd->epqh_list_intr);
+ break;
+ #ifdef __EN_ISOC__
+ case IFXUSB_EP_TYPE_ISOC:
+ list_add_tail(&epqh->ql, &_ifxhcd->epqh_list_isoc);
+
+ break;
+ #endif
+ }
+ UNLOCK_EPQH_LIST(_ifxhcd);
+ return epqh;
+}
+
+
+
+
+
+
+/*!
+ \brief Free the EPQH. EPQH should already be removed from a list.
+ URBD list should already be empty if called from URB Dequeue.
+
+ \param[in] _epqh The EPQH to free.
+ */
+void ifxhcd_epqh_free (ifxhcd_epqh_t *_epqh)
+{
+ unsigned long flags;
+ if(!_epqh)
+ return;
+
+ if(_epqh->sysep) _epqh->sysep->hcpriv=NULL;
+ _epqh->sysep=NULL;
+
+ local_irq_save (flags);
+ if (!list_empty(&_epqh->urbd_list))
+ IFX_WARN("%s() invalid epqh state\n",__func__);
+ else
+ {
+ LOCK_EPQH_LIST_ALL(_epqh->ifxhcd);
+ if (!list_empty(&_epqh->ql_all))
+ list_del_init (&_epqh->ql_all);
+ UNLOCK_EPQH_LIST_ALL(_epqh->ifxhcd);
+
+ LOCK_EPQH_LIST(_epqh->ifxhcd);
+ if (!list_empty(&_epqh->ql))
+ list_del_init (&_epqh->ql);
+ UNLOCK_EPQH_LIST(_epqh->ifxhcd);
+
+ #ifdef __EPQD_DESTROY_TIMEOUT__
+ del_timer(&_epqh->destroy_timer);
+ #endif
+ kfree (_epqh);
+ }
+ local_irq_restore (flags);
+}
+
+
+void ifxhcd_epqh_idle(ifxhcd_epqh_t *_epqh)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ LOCK_URBD_LIST(_epqh);
+ if (list_empty(&_epqh->urbd_list))
+ {
+ if(_epqh->ep_type == IFXUSB_EP_TYPE_ISOC || _epqh->ep_type == IFXUSB_EP_TYPE_INTR)
+ _epqh->phase=EPQH_STDBY;
+ else
+ {
+ _epqh->phase=EPQH_IDLE;
+ #ifdef __EPQD_DESTROY_TIMEOUT__
+ del_timer(&_epqh->destroy_timer);
+ _epqh->destroy_timer.expires = jiffies + (HZ*epqh_self_destroy_timeout);
+ add_timer(&_epqh->destroy_timer );
+ #endif
+ }
+ }
+ else
+ {
+ _epqh->phase=EPQH_READY;
+ #ifdef __EPQD_DESTROY_TIMEOUT__
+ del_timer(&_epqh->destroy_timer);
+ #endif
+ }
+ UNLOCK_URBD_LIST(_epqh);
+ local_irq_restore(flags);
+}
+
+
+void ifxhcd_epqh_idle_periodic(ifxhcd_epqh_t *_epqh)
+{
+ unsigned long flags;
+ if(_epqh->ep_type != IFXUSB_EP_TYPE_ISOC && _epqh->ep_type != IFXUSB_EP_TYPE_INTR && _epqh->phase!=EPQH_STDBY)
+ return;
+
+ local_irq_save(flags);
+ LOCK_URBD_LIST(_epqh);
+ if (!list_empty(&_epqh->urbd_list))
+ IFX_WARN("%s() invalid epqh state(not empty)\n",__func__);
+
+ _epqh->phase=EPQH_IDLE;
+
+ #ifdef __EPQD_DESTROY_TIMEOUT__
+ del_timer(&_epqh->destroy_timer);
+ _epqh->destroy_timer.expires = jiffies + (HZ*epqh_self_destroy_timeout);
+ add_timer(&_epqh->destroy_timer );
+ #endif
+
+ #ifdef __EN_ISOC__
+ if (_epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
+ _epqh->ifxhcd->isoc_ep_count--;
+ #endif
+ UNLOCK_URBD_LIST(_epqh);
+ local_irq_restore(flags);
+}
+
+
+ifxhcd_epqh_t *ifxhcd_urbd_create (ifxhcd_hcd_t *_ifxhcd,struct urb *_urb)
+{
+ ifxhcd_urbd_t *urbd;
+ struct usb_host_endpoint *sysep;
+ ifxhcd_epqh_t *epqh=NULL;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ sysep = ifxhcd_urb_to_endpoint(_urb);
+
+ LOCK_EPQH_LIST_ALL(_ifxhcd);
+ epqh = sysep_to_epqh(_ifxhcd, sysep);
+
+ if (!epqh)
+ {
+ sysep->hcpriv = NULL;
+ epqh = ifxhcd_epqh_create (_ifxhcd, _urb);
+ }
+ UNLOCK_EPQH_LIST_ALL(_ifxhcd);
+
+ if (!epqh)
+ {
+ IFX_ERROR("EPQH Error alloc\n");
+ local_irq_restore (flags);
+ return (ifxhcd_epqh_t *)NULL;
+ }
+ if(epqh->phase==EPQH_DISABLING)
+ {
+ IFX_ERROR("EPQH Error alloc while disabling\n");
+ local_irq_restore (flags);
+ return (ifxhcd_epqh_t *)NULL;
+ }
+ sysep->hcpriv = epqh;
+
+ if(_urb->hcpriv)
+ {
+ IFX_WARN("%s() Previous urb->hcpriv exist %p\n",__func__,_urb->hcpriv);
+ #if 1
+ local_irq_restore (flags);
+ return (ifxhcd_epqh_t *)NULL;
+ #else
+ urbd = _urb->hcpriv;
+ if(urbd->epqh!=epqh)
+ IFX_WARN("%s() Previous urb->hcpriv exist %p and epqh not the same %p %p\n",__func__,_urb->hcpriv,urbd->epqh,epqh);
+ #endif
+ }
+ else
+ {
+ urbd = (ifxhcd_urbd_t *) kmalloc (sizeof(ifxhcd_urbd_t), GFP_ATOMIC);
+ if (!urbd)
+ {
+ local_irq_restore (flags);
+ return (ifxhcd_epqh_t *)NULL;
+ }
+ memset (urbd, 0, sizeof (ifxhcd_urbd_t));
+ INIT_LIST_HEAD(&urbd->ql);
+ }
+
+ _urb->hcpriv = urbd;
+ urbd->urb = _urb;
+ urbd->epqh = epqh;
+ urbd->status= -EINPROGRESS;
+
+ urbd->is_in=usb_pipein(_urb->pipe) ? 1 : 0;
+#define URB_NO_SETUP_DMA_MAP 0
+ #ifdef __EN_ISOC__
+ if(epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
+ {
+ if(_urb->transfer_flags && URB_NO_TRANSFER_DMA_MAP)
+ urbd->xfer_buff = (uint8_t *) (KSEG1ADDR((uint32_t *)_urb->transfer_dma));
+ else
+ urbd->xfer_buff = (uint8_t *) _urb->transfer_buffer;
+ }
+ else
+ #endif
+ {
+ urbd->xfer_len=_urb->transfer_buffer_length;
+ if(urbd->xfer_len>0)
+ {
+ if(_urb->transfer_flags && URB_NO_TRANSFER_DMA_MAP)
+ urbd->xfer_buff = (uint8_t *) (KSEG1ADDR((uint32_t *)_urb->transfer_dma));
+ else
+ urbd->xfer_buff = (uint8_t *) _urb->transfer_buffer;
+ }
+ }
+
+ #if 1 // cache write-back, so DMA engine can get correct content. Precaution
+ if(urbd->xfer_len)
+ dma_cache_wback_inv((unsigned long)urbd->xfer_buff, urbd->xfer_len);
+ #endif
+
+ if(epqh->ep_type == IFXUSB_EP_TYPE_CTRL)
+ {
+ if(_urb->transfer_flags && URB_NO_SETUP_DMA_MAP)
+ urbd->setup_buff = (uint8_t *) (KSEG1ADDR((uint32_t *)_urb->setup_dma));
+ else
+ urbd->setup_buff = (uint8_t *) _urb->setup_packet;
+ #if 1 // cache write-back, so DMA engine can get correct content. Precaution
+ dma_cache_wback_inv((unsigned long)urbd->setup_buff, 16);
+ #endif
+ }
+
+ LOCK_URBD_LIST(epqh);
+ if (!list_empty(&urbd->ql))
+ list_del_init(&urbd->ql);
+ list_add_tail(&urbd->ql, &epqh->urbd_list);
+ epqh->urbd_count++;
+ UNLOCK_URBD_LIST(epqh);
+
+ local_irq_restore (flags);
+ return epqh;
+}
+
+
+
+ifxhcd_epqh_t * sysep_to_epqh(ifxhcd_hcd_t *_ifxhcd, struct usb_host_endpoint *_sysep)
+{
+ ifxhcd_epqh_t *epqh;
+
+ LOCK_EPQH_LIST_ALL(_ifxhcd);
+ list_for_each_entry( epqh, &_ifxhcd->epqh_list_all, ql_all)
+ {
+ if(epqh->sysep==_sysep)
+ {
+ UNLOCK_EPQH_LIST_ALL(_ifxhcd);
+ return epqh;
+ }
+ }
+ UNLOCK_EPQH_LIST_ALL(_ifxhcd);
+ return NULL;
+}
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif.c b/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif.c
new file mode 100644
index 0000000000..9f0262578e
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif.c
@@ -0,0 +1,1686 @@
+/*****************************************************************************
+ ** FILE NAME : ifxusb_cif.c
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 1.0
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** DESCRIPTION : The Core Interface provides basic services for accessing and
+ ** managing the IFX USB hardware. These services are used by both the
+ ** Host Controller Driver and the Peripheral Controller Driver.
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*!
+ \file ifxusb_cif.c
+ \ingroup IFXUSB_DRIVER_V3
+ \brief This file contains the interface to the IFX USB Core.
+*/
+
+#include <linux/version.h>
+#include "ifxusb_version.h"
+
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
+
+#ifdef __DEBUG__
+ #include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#endif
+
+
+#include "ifxusb_plat.h"
+#include "ifxusb_regs.h"
+#include "ifxusb_cif.h"
+
+
+#ifdef __IS_DEVICE__
+ #include "ifxpcd.h"
+#endif
+
+#ifdef __IS_HOST__
+ #include "ifxhcd.h"
+#endif
+
+#include <linux/mm.h>
+
+#include <linux/gfp.h>
+
+#include <lantiq_soc.h>
+
+#if defined(__UEIP__)
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
+ #ifndef USB_CTRL_PMU_SETUP
+ #define USB_CTRL_PMU_SETUP(__x) USB0_CTRL_PMU_SETUP(__x)
+ #endif
+ #ifndef USB_PHY_PMU_SETUP
+ #define USB_PHY_PMU_SETUP(__x) USB0_PHY_PMU_SETUP(__x)
+ #endif
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
+#endif // defined(__UEIP__)
+
+/*!
+ \brief This function is called to allocate buffer of specified size.
+ The allocated buffer is mapped into DMA accessable address.
+ \param size Size in BYTE to be allocated
+ \param clear 0: don't do clear after buffer allocated, other: do clear to zero
+ \return 0/NULL: Fail; uncached pointer of allocated buffer
+ */
+#ifdef __IS_HOST__
+void *ifxusb_alloc_buf_h(size_t size, int clear)
+#else
+void *ifxusb_alloc_buf_d(size_t size, int clear)
+#endif
+{
+ uint32_t *cached,*uncached;
+ uint32_t totalsize,page;
+
+ if(!size)
+ return 0;
+
+ size=(size+3)&0xFFFFFFFC;
+ totalsize=size + 12;
+ page=get_order(totalsize);
+
+ cached = (void *) __get_free_pages(( GFP_ATOMIC | GFP_DMA), page);
+
+ if(!cached)
+ {
+ IFX_PRINT("%s Allocation Failed size:%d\n",__func__,size);
+ return NULL;
+ }
+
+ uncached = (uint32_t *)(KSEG1ADDR(cached));
+ if(clear)
+ memset(uncached, 0, totalsize);
+
+ *(uncached+0)=totalsize;
+ *(uncached+1)=page;
+ *(uncached+2)=(uint32_t)cached;
+ return (void *)(uncached+3);
+}
+
+
+/*!
+ \brief This function is called to free allocated buffer.
+ \param vaddr the uncached pointer of the buffer
+ */
+#ifdef __IS_HOST__
+void ifxusb_free_buf_h(void *vaddr)
+#else
+void ifxusb_free_buf_d(void *vaddr)
+#endif
+{
+ uint32_t totalsize,page;
+ uint32_t *cached,*uncached;
+
+ if(vaddr != NULL)
+ {
+ uncached=vaddr;
+ uncached-=3;
+ totalsize=*(uncached+0);
+ page=*(uncached+1);
+ cached=(uint32_t *)(*(uncached+2));
+ if(totalsize && page==get_order(totalsize) && cached==(uint32_t *)(KSEG0ADDR(uncached)))
+ {
+ free_pages((unsigned long)cached, page);
+ return;
+ }
+ // the memory is not allocated by ifxusb_alloc_buf. Allowed but must be careful.
+ return;
+ }
+}
+
+
+
+/*!
+ \brief This function is called to initialize the IFXUSB CSR data
+ structures. The register addresses in the device and host
+ structures are initialized from the base address supplied by the
+ caller. The calling function must make the OS calls to get the
+ base address of the IFXUSB controller registers.
+
+ \param _core_if Pointer of core_if structure
+ \param _irq irq number
+ \param _reg_base_addr Base address of IFXUSB core registers
+ \param _fifo_base_addr Fifo base address
+ \param _fifo_dbg_addr Fifo debug address
+ \return 0: success;
+ */
+#ifdef __IS_HOST__
+int ifxusb_core_if_init_h(ifxusb_core_if_t *_core_if,
+#else
+int ifxusb_core_if_init_d(ifxusb_core_if_t *_core_if,
+#endif
+ int _irq,
+ uint32_t _reg_base_addr,
+ uint32_t _fifo_base_addr,
+ uint32_t _fifo_dbg_addr)
+{
+ int retval = 0;
+ uint32_t *reg_base =NULL;
+ uint32_t *fifo_base =NULL;
+ uint32_t *fifo_dbg =NULL;
+
+ int i;
+
+ IFX_DEBUGPL(DBG_CILV, "%s(%p,%d,0x%08X,0x%08X,0x%08X)\n", __func__,
+ _core_if,
+ _irq,
+ _reg_base_addr,
+ _fifo_base_addr,
+ _fifo_dbg_addr);
+
+ if( _core_if == NULL)
+ {
+ IFX_ERROR("%s() invalid _core_if\n", __func__);
+ retval = -ENOMEM;
+ goto fail;
+ }
+
+ //memset(_core_if, 0, sizeof(ifxusb_core_if_t));
+
+ _core_if->irq=_irq;
+
+ reg_base =ioremap_nocache(_reg_base_addr , IFXUSB_IOMEM_SIZE );
+ fifo_base =ioremap_nocache(_fifo_base_addr, IFXUSB_FIFOMEM_SIZE);
+ fifo_dbg =ioremap_nocache(_fifo_dbg_addr , IFXUSB_FIFODBG_SIZE);
+ if( reg_base == NULL || fifo_base == NULL || fifo_dbg == NULL)
+ {
+ IFX_ERROR("%s() usb ioremap() failed\n", __func__);
+ retval = -ENOMEM;
+ goto fail;
+ }
+
+ _core_if->core_global_regs = (ifxusb_core_global_regs_t *)reg_base;
+
+ /*
+ * Attempt to ensure this device is really a IFXUSB Controller.
+ * Read and verify the SNPSID register contents. The value should be
+ * 0x45F42XXX
+ */
+ {
+ int32_t snpsid;
+ snpsid = ifxusb_rreg(&_core_if->core_global_regs->gsnpsid);
+ if ((snpsid & 0xFFFFF000) != 0x4F542000)
+ {
+ IFX_ERROR("%s() snpsid error(0x%08x) failed\n", __func__,snpsid);
+ retval = -EINVAL;
+ goto fail;
+ }
+ _core_if->snpsid=snpsid;
+ }
+
+ #ifdef __IS_HOST__
+ _core_if->host_global_regs = (ifxusb_host_global_regs_t *)
+ ((uint32_t)reg_base + IFXUSB_HOST_GLOBAL_REG_OFFSET);
+ _core_if->hprt0 = (uint32_t*)((uint32_t)reg_base + IFXUSB_HOST_PORT_REGS_OFFSET);
+
+ for (i=0; i<MAX_EPS_CHANNELS; i++)
+ {
+ _core_if->hc_regs[i] = (ifxusb_hc_regs_t *)
+ ((uint32_t)reg_base + IFXUSB_HOST_CHAN_REGS_OFFSET +
+ (i * IFXUSB_CHAN_REGS_OFFSET));
+ IFX_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
+ i, &_core_if->hc_regs[i]->hcchar);
+ }
+ #endif //__IS_HOST__
+
+ #ifdef __IS_DEVICE__
+ _core_if->dev_global_regs =
+ (ifxusb_device_global_regs_t *)((uint32_t)reg_base + IFXUSB_DEV_GLOBAL_REG_OFFSET);
+
+ for (i=0; i<MAX_EPS_CHANNELS; i++)
+ {
+ _core_if->in_ep_regs[i] = (ifxusb_dev_in_ep_regs_t *)
+ ((uint32_t)reg_base + IFXUSB_DEV_IN_EP_REG_OFFSET +
+ (i * IFXUSB_EP_REG_OFFSET));
+ _core_if->out_ep_regs[i] = (ifxusb_dev_out_ep_regs_t *)
+ ((uint32_t)reg_base + IFXUSB_DEV_OUT_EP_REG_OFFSET +
+ (i * IFXUSB_EP_REG_OFFSET));
+ IFX_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p/%p %p/0x%08X/0x%08X\n",
+ i, &_core_if->in_ep_regs[i]->diepctl, _core_if->in_ep_regs[i],
+ reg_base,IFXUSB_DEV_IN_EP_REG_OFFSET,(i * IFXUSB_EP_REG_OFFSET)
+ );
+ IFX_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p/%p %p/0x%08X/0x%08X\n",
+ i, &_core_if->out_ep_regs[i]->doepctl, _core_if->out_ep_regs[i],
+ reg_base,IFXUSB_DEV_OUT_EP_REG_OFFSET,(i * IFXUSB_EP_REG_OFFSET)
+ );
+ }
+ #endif //__IS_DEVICE__
+
+ /* Setting the FIFO and other Address. */
+ for (i=0; i<MAX_EPS_CHANNELS; i++)
+ {
+ _core_if->data_fifo[i] = fifo_base + (i * IFXUSB_DATA_FIFO_SIZE);
+ IFX_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08x\n",
+ i, (unsigned)_core_if->data_fifo[i]);
+ }
+
+ _core_if->data_fifo_dbg = fifo_dbg;
+ _core_if->pcgcctl = (uint32_t*)(((uint32_t)reg_base) + IFXUSB_PCGCCTL_OFFSET);
+
+ /*
+ * Store the contents of the hardware configuration registers here for
+ * easy access later.
+ */
+ _core_if->hwcfg1.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg1);
+ _core_if->hwcfg2.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg2);
+ _core_if->hwcfg3.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg3);
+ _core_if->hwcfg4.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg4);
+
+ IFX_DEBUGPL(DBG_CILV,"hwcfg1=%08x\n",_core_if->hwcfg1.d32);
+ IFX_DEBUGPL(DBG_CILV,"hwcfg2=%08x\n",_core_if->hwcfg2.d32);
+ IFX_DEBUGPL(DBG_CILV,"hwcfg3=%08x\n",_core_if->hwcfg3.d32);
+ IFX_DEBUGPL(DBG_CILV,"hwcfg4=%08x\n",_core_if->hwcfg4.d32);
+
+
+ #ifdef __DED_FIFO__
+ {
+ unsigned int countdown=0xFFFF;
+ IFX_PRINT("Waiting for PHY Clock Lock!\n");
+ while(--countdown && !( ifxusb_rreg(&_core_if->core_global_regs->grxfsiz) & (1<<9)))
+ {
+ UDELAY(1);
+ }
+ if(countdown)
+ IFX_PRINT("PHY Clock Locked!\n");
+ else
+ IFX_PRINT("PHY Clock Not Locked! %08X\n",ifxusb_rreg(&_core_if->core_global_regs->grxfsiz));
+ }
+ #endif
+
+ /* Create new workqueue and init works */
+#if 0
+ _core_if->wq_usb = create_singlethread_workqueue(_core_if->core_name);
+
+ if(_core_if->wq_usb == 0)
+ {
+ IFX_DEBUGPL(DBG_CIL, "Creation of wq_usb failed\n");
+ retval = -EINVAL;
+ goto fail;
+ }
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+ INIT_WORK(&core_if->w_conn_id, w_conn_id_status_change, core_if);
+ INIT_WORK(&core_if->w_wkp, w_wakeup_detected, core_if);
+ #else
+ INIT_WORK(&core_if->w_conn_id, w_conn_id_status_change);
+ INIT_DELAYED_WORK(&core_if->w_wkp, w_wakeup_detected);
+ #endif
+#endif
+ return 0;
+
+fail:
+ if( reg_base != NULL) iounmap(reg_base );
+ if( fifo_base != NULL) iounmap(fifo_base);
+ if( fifo_dbg != NULL) iounmap(fifo_dbg );
+ return retval;
+}
+
+/*!
+ \brief This function free the mapped address in the IFXUSB CSR data structures.
+ \param _core_if Pointer of core_if structure
+ */
+#ifdef __IS_HOST__
+void ifxusb_core_if_remove_h(ifxusb_core_if_t *_core_if)
+#else
+void ifxusb_core_if_remove_d(ifxusb_core_if_t *_core_if)
+#endif
+{
+ /* Disable all interrupts */
+ if( _core_if->core_global_regs != NULL)
+ {
+ gusbcfg_data_t usbcfg ={.d32 = 0};
+ usbcfg.d32 = ifxusb_rreg( &_core_if->core_global_regs->gusbcfg);
+ usbcfg.b.ForceDevMode=0;
+ usbcfg.b.ForceHstMode=0;
+ ifxusb_wreg( &_core_if->core_global_regs->gusbcfg,usbcfg.d32);
+ ifxusb_mreg( &_core_if->core_global_regs->gahbcfg, 1, 0);
+ ifxusb_wreg( &_core_if->core_global_regs->gintmsk, 0);
+ }
+
+ if( _core_if->core_global_regs != NULL) iounmap(_core_if->core_global_regs );
+ if( _core_if->data_fifo[0] != NULL) iounmap(_core_if->data_fifo[0] );
+ if( _core_if->data_fifo_dbg != NULL) iounmap(_core_if->data_fifo_dbg );
+
+#if 0
+ if (_core_if->wq_usb)
+ destroy_workqueue(_core_if->wq_usb);
+#endif
+ memset(_core_if, 0, sizeof(ifxusb_core_if_t));
+}
+
+
+
+
+/*!
+ \brief This function enbles the controller's Global Interrupt in the AHB Config register.
+ \param _core_if Pointer of core_if structure
+ */
+#ifdef __IS_HOST__
+void ifxusb_enable_global_interrupts_h( ifxusb_core_if_t *_core_if )
+#else
+void ifxusb_enable_global_interrupts_d( ifxusb_core_if_t *_core_if )
+#endif
+{
+ gahbcfg_data_t ahbcfg ={ .d32 = 0};
+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
+ ifxusb_mreg(&_core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
+}
+
+/*!
+ \brief This function disables the controller's Global Interrupt in the AHB Config register.
+ \param _core_if Pointer of core_if structure
+ */
+#ifdef __IS_HOST__
+void ifxusb_disable_global_interrupts_h( ifxusb_core_if_t *_core_if )
+#else
+void ifxusb_disable_global_interrupts_d( ifxusb_core_if_t *_core_if )
+#endif
+{
+ gahbcfg_data_t ahbcfg ={ .d32 = 0};
+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
+ ifxusb_mreg(&_core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
+}
+
+
+
+
+/*!
+ \brief Flush Tx and Rx FIFO.
+ \param _core_if Pointer of core_if structure
+ */
+#ifdef __IS_HOST__
+void ifxusb_flush_both_fifo_h( ifxusb_core_if_t *_core_if )
+#else
+void ifxusb_flush_both_fifo_d( ifxusb_core_if_t *_core_if )
+#endif
+{
+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
+ volatile grstctl_t greset ={ .d32 = 0};
+ int count = 0;
+
+ IFX_DEBUGPL((DBG_CIL|DBG_PCDV), "%s\n", __func__);
+ greset.b.rxfflsh = 1;
+ greset.b.txfflsh = 1;
+ greset.b.txfnum = 0x10;
+ greset.b.intknqflsh=1;
+ greset.b.hstfrm=1;
+ ifxusb_wreg( &global_regs->grstctl, greset.d32 );
+
+ do
+ {
+ greset.d32 = ifxusb_rreg( &global_regs->grstctl);
+ if (++count > 10000)
+ {
+ IFX_WARN("%s() HANG! GRSTCTL=%0x\n", __func__, greset.d32);
+ break;
+ }
+ } while (greset.b.rxfflsh == 1 || greset.b.txfflsh == 1);
+ /* Wait for 3 PHY Clocks*/
+ UDELAY(1);
+}
+
+/*!
+ \brief Flush a Tx FIFO.
+ \param _core_if Pointer of core_if structure
+ \param _num Tx FIFO to flush. ( 0x10 for ALL TX FIFO )
+ */
+#ifdef __IS_HOST__
+void ifxusb_flush_tx_fifo_h( ifxusb_core_if_t *_core_if, const int _num )
+#else
+void ifxusb_flush_tx_fifo_d( ifxusb_core_if_t *_core_if, const int _num )
+#endif
+{
+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
+ volatile grstctl_t greset ={ .d32 = 0};
+ int count = 0;
+
+ IFX_DEBUGPL((DBG_CIL|DBG_PCDV), "Flush Tx FIFO %d\n", _num);
+
+ greset.b.intknqflsh=1;
+ greset.b.txfflsh = 1;
+ greset.b.txfnum = _num;
+ ifxusb_wreg( &global_regs->grstctl, greset.d32 );
+
+ do
+ {
+ greset.d32 = ifxusb_rreg( &global_regs->grstctl);
+ if (++count > 10000&&(_num==0 ||_num==0x10))
+ {
+ IFX_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
+ __func__, greset.d32,
+ ifxusb_rreg( &global_regs->gnptxsts));
+ break;
+ }
+ } while (greset.b.txfflsh == 1);
+ /* Wait for 3 PHY Clocks*/
+ UDELAY(1);
+}
+
+
+/*!
+ \brief Flush Rx FIFO.
+ \param _core_if Pointer of core_if structure
+ */
+#ifdef __IS_HOST__
+void ifxusb_flush_rx_fifo_h( ifxusb_core_if_t *_core_if )
+#else
+void ifxusb_flush_rx_fifo_d( ifxusb_core_if_t *_core_if )
+#endif
+{
+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
+ volatile grstctl_t greset ={ .d32 = 0};
+ int count = 0;
+
+ IFX_DEBUGPL((DBG_CIL|DBG_PCDV), "%s\n", __func__);
+ greset.b.rxfflsh = 1;
+ ifxusb_wreg( &global_regs->grstctl, greset.d32 );
+
+ do
+ {
+ greset.d32 = ifxusb_rreg( &global_regs->grstctl);
+ if (++count > 10000)
+ {
+ IFX_WARN("%s() HANG! GRSTCTL=%0x\n", __func__, greset.d32);
+ break;
+ }
+ } while (greset.b.rxfflsh == 1);
+ /* Wait for 3 PHY Clocks*/
+ UDELAY(1);
+}
+
+
+#define SOFT_RESET_DELAY 100 /*!< Delay in msec of detection after soft-reset of usb core */
+
+/*!
+ \brief Do a soft reset of the core. Be careful with this because it
+ resets all the internal state machines of the core.
+ \param _core_if Pointer of core_if structure
+ */
+#ifdef __IS_HOST__
+int ifxusb_core_soft_reset_h(ifxusb_core_if_t *_core_if)
+#else
+int ifxusb_core_soft_reset_d(ifxusb_core_if_t *_core_if)
+#endif
+{
+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
+ volatile grstctl_t greset ={ .d32 = 0};
+ int count = 0;
+
+ IFX_DEBUGPL(DBG_CILV, "%s\n", __func__);
+ /* Wait for AHB master IDLE state. */
+ do
+ {
+ UDELAY(10);
+ greset.d32 = ifxusb_rreg( &global_regs->grstctl);
+ if (++count > 100000)
+ {
+ IFX_WARN("%s() HANG! AHB Idle GRSTCTL=%0x %x\n", __func__,
+ greset.d32, greset.b.ahbidle);
+ break;
+ }
+ } while (greset.b.ahbidle == 0);
+
+ UDELAY(1);
+
+ /* Core Soft Reset */
+ count = 0;
+ greset.b.csftrst = 1;
+ ifxusb_wreg( &global_regs->grstctl, greset.d32 );
+
+ #ifdef SOFT_RESET_DELAY
+ MDELAY(SOFT_RESET_DELAY);
+ #endif
+
+ do
+ {
+ UDELAY(10);
+ greset.d32 = ifxusb_rreg( &global_regs->grstctl);
+ if (++count > 100000)
+ {
+ IFX_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n", __func__, greset.d32);
+ return -1;
+ }
+ } while (greset.b.csftrst == 1);
+
+ #ifdef SOFT_RESET_DELAY
+ MDELAY(SOFT_RESET_DELAY);
+ #endif
+
+ // This is to reset the PHY of VR9
+ #if defined(__IS_VR9__)
+ if(_core_if->core_no==0)
+ {
+ set_bit (4, VR9_RCU_USBRESET2);
+ MDELAY(50);
+ clear_bit (4, VR9_RCU_USBRESET2);
+ }
+ else
+ {
+ set_bit (5, VR9_RCU_USBRESET2);
+ MDELAY(50);
+ clear_bit (5, VR9_RCU_USBRESET2);
+ }
+ MDELAY(50);
+ #endif //defined(__IS_VR9__)
+
+ IFX_PRINT("USB core #%d soft-reset\n",_core_if->core_no);
+
+ return 0;
+}
+
+/*!
+ \brief Turn on the USB Core Power
+ \param _core_if Pointer of core_if structure
+*/
+#ifdef __IS_HOST__
+void ifxusb_power_on_h (ifxusb_core_if_t *_core_if)
+#else
+void ifxusb_power_on_d (ifxusb_core_if_t *_core_if)
+#endif
+{
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ #if defined(__UEIP__)
+
+ // set clock gating
+ #if defined(__IS_TWINPASS) || defined(__IS_DANUBE__)
+ set_bit (4, (volatile unsigned long *)DANUBE_CGU_IFCCR);
+ set_bit (5, (volatile unsigned long *)DANUBE_CGU_IFCCR);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ // clear_bit (4, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR);
+ clear_bit (5, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ set_bit (0, (volatile unsigned long *)AR9_CGU_IFCCR);
+ set_bit (1, (volatile unsigned long *)AR9_CGU_IFCCR);
+ #endif //defined(__IS_AR9__)
+ #if defined(__IS_VR9__)
+// set_bit (0, (volatile unsigned long *)VR9_CGU_IFCCR);
+// set_bit (1, (volatile unsigned long *)VR9_CGU_IFCCR);
+ #endif //defined(__IS_VR9__)
+ #if defined(__IS_AR10__)
+// set_bit (0, (volatile unsigned long *)VR9_CGU_IFCCR);
+// set_bit (1, (volatile unsigned long *)VR9_CGU_IFCCR);
+ #endif //defined(__IS_AR10__)
+
+ MDELAY(50);
+#define PMU_AHBM BIT(15)
+#define PMU_USB0 BIT(6)
+#define PMU_USB1 BIT(27)
+#define PMU_USB0_P BIT(0)
+#define PMU_USB1_P BIT(26)
+ // set power
+ ltq_pmu_enable(PMU_AHBM);
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
+ ltq_pmu_enable(PMU_USB0);
+ //#if defined(__IS_TWINPASS__)
+ // ifxusb_enable_afe_oc();
+ //#endif
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__) || defined(__IS_VR9__)
+ if(_core_if->core_no==0)
+ ltq_pmu_enable(PMU_USB0);
+ else
+ ltq_pmu_enable(PMU_USB1);
+ #endif //defined(__IS_AR9__) || defined(__IS_VR9__)
+ #if defined(__IS_AR10__)
+ //if(_core_if->core_no==0)
+ // USB0_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
+ //else
+ // USB1_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
+ #endif //defined(__IS_AR10__)
+
+ MDELAY(50);
+
+ if(_core_if->pcgcctl)
+ {
+ pcgcctl_data_t pcgcctl = {.d32=0};
+ pcgcctl.b.gatehclk = 1;
+ ifxusb_mreg(_core_if->pcgcctl, pcgcctl.d32, 0);
+ }
+
+
+ if(_core_if->core_global_regs)
+ {
+ // PHY configurations.
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AR9__)
+ #if defined(__IS_VR9__)
+ //ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_VR9__)
+ #if defined(__IS_AR10__)
+ //ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AR10__)
+ }
+ #else //defined(__UEIP__)
+ // set clock gating
+ #if defined(__IS_TWINPASS) || defined(__IS_DANUBE__)
+ set_bit (4, (volatile unsigned long *)DANUBE_CGU_IFCCR);
+ set_bit (5, (volatile unsigned long *)DANUBE_CGU_IFCCR);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ // clear_bit (4, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR);
+ clear_bit (5, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ set_bit (0, (volatile unsigned long *)AMAZON_S_CGU_IFCCR);
+ set_bit (1, (volatile unsigned long *)AMAZON_S_CGU_IFCCR);
+ #endif //defined(__IS_AR9__)
+
+ MDELAY(50);
+
+ // set power
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ clear_bit (6, (volatile unsigned long *)DANUBE_PMU_PWDCR);//USB
+ clear_bit (9, (volatile unsigned long *)DANUBE_PMU_PWDCR);//DSL
+ clear_bit (15, (volatile unsigned long *)DANUBE_PMU_PWDCR);//AHB
+ #if defined(__IS_TWINPASS__)
+ ifxusb_enable_afe_oc();
+ #endif
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ clear_bit (6, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);
+ clear_bit (9, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);
+ clear_bit (15, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ clear_bit (6, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB
+ else
+ clear_bit (27, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB
+ clear_bit (9, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//DSL
+ clear_bit (15, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//AHB
+ #endif //defined(__IS_AR9__)
+
+ if(_core_if->core_global_regs)
+ {
+ // PHY configurations.
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AR9__)
+ }
+
+ #endif //defined(__UEIP__)
+}
+
+/*!
+ \brief Turn off the USB Core Power
+ \param _core_if Pointer of core_if structure
+*/
+#ifdef __IS_HOST__
+void ifxusb_power_off_h (ifxusb_core_if_t *_core_if)
+#else
+void ifxusb_power_off_d (ifxusb_core_if_t *_core_if)
+#endif
+
+{
+ #ifdef __IS_HOST__
+ ifxusb_phy_power_off_h (_core_if);
+ #else
+ ifxusb_phy_power_off_d (_core_if);
+ #endif
+
+ #if defined(__UEIP__)
+ //AHBM_PMU_SETUP(IFX_PMU_DISABLE);
+ // set power
+ if(_core_if->pcgcctl)
+ {
+ pcgcctl_data_t pcgcctl = {.d32=0};
+ pcgcctl.b.gatehclk = 1;
+ pcgcctl.b.stoppclk = 1;
+ ifxusb_mreg(_core_if->pcgcctl, 0, pcgcctl.d32);
+ }
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
+ //USB_CTRL_PMU_SETUP(IFX_PMU_DISABLE);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__) || defined(__IS_VR9__)
+ /* if(_core_if->core_no==0)
+ USB0_CTRL_PMU_SETUP(IFX_PMU_DISABLE);
+ else
+ USB1_CTRL_PMU_SETUP(IFX_PMU_DISABLE);*/
+ #endif //defined(__IS_AR9__) || defined(__IS_VR9__)
+ #if defined(__IS_AR10__)
+ //if(_core_if->core_no==0)
+ // USB0_CTRL_PMU_SETUP(IFX_PMU_DISABLE);
+ //else
+ // USB1_CTRL_PMU_SETUP(IFX_PMU_DISABLE);
+ #endif //defined(__IS_AR10__)
+ #else //defined(__UEIP__)
+ // set power
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ set_bit (6, (volatile unsigned long *)DANUBE_PMU_PWDCR);//USB
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ set_bit (6, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);//USB
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ set_bit (6, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB
+ else
+ set_bit (27, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB
+ #endif //defined(__IS_AR9__)
+ #endif //defined(__UEIP__)
+}
+
+/*!
+ \brief Turn on the USB PHY Power
+ \param _core_if Pointer of core_if structure
+*/
+#ifdef __IS_HOST__
+void ifxusb_phy_power_on_h (ifxusb_core_if_t *_core_if)
+#else
+void ifxusb_phy_power_on_d (ifxusb_core_if_t *_core_if)
+#endif
+{
+ #if defined(__UEIP__)
+ if(_core_if->core_global_regs)
+ {
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AR9__)
+ #if ( defined(__IS_VR9__) || defined(__IS_AR10__)) && defined(__PHY_LONG_PREEMP__)
+ if(_core_if->core_no==0)
+ set_bit (0, VR9_RCU_USB_ANA_CFG1A);
+ else
+ set_bit (0, VR9_RCU_USB_ANA_CFG1B);
+ #endif //( defined(__IS_VR9__) || defined(__IS_AR10__)) && defined(__PHY_LONG_PREEMP__)
+
+ if(_core_if->pcgcctl)
+ {
+ pcgcctl_data_t pcgcctl = {.d32=0};
+ pcgcctl.b.stoppclk = 1;
+ ifxusb_mreg(_core_if->pcgcctl, pcgcctl.d32, 0);
+ }
+ }
+
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
+ ltq_pmu_enable(PMU_USB0_P);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__) || defined(__IS_VR9__) || defined(__IS_AR10__)
+ if(_core_if->core_no==0)
+ ltq_pmu_enable(PMU_USB0_P);
+ else
+ ltq_pmu_enable(PMU_USB1_P);
+ #endif //defined(__IS_AR9__) || defined(__IS_VR9__)
+
+ // PHY configurations.
+ if(_core_if->core_global_regs)
+ {
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AR9__)
+ #if ( defined(__IS_VR9__) || defined(__IS_AR10__)) && defined(__PHY_LONG_PREEMP__)
+ if(_core_if->core_no==0)
+ set_bit (0, VR9_RCU_USB_ANA_CFG1A);
+ else
+ set_bit (0, VR9_RCU_USB_ANA_CFG1B);
+ #endif //( defined(__IS_VR9__) || defined(__IS_AR10__)) && defined(__PHY_LONG_PREEMP__)
+ }
+ #else //defined(__UEIP__)
+ // PHY configurations.
+ if(_core_if->core_global_regs)
+ {
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AR9__)
+ }
+
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ clear_bit (0, (volatile unsigned long *)DANUBE_PMU_PWDCR);//PHY
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ clear_bit (0, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ clear_bit (0, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY
+ else
+ clear_bit (26, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY
+ #endif //defined(__IS_AR9__)
+
+ // PHY configurations.
+ if(_core_if->core_global_regs)
+ {
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AR9__)
+ }
+ #endif //defined(__UEIP__)
+}
+
+
+/*!
+ \brief Turn off the USB PHY Power
+ \param _core_if Pointer of core_if structure
+*/
+#ifdef __IS_HOST__
+void ifxusb_phy_power_off_h (ifxusb_core_if_t *_core_if)
+#else
+void ifxusb_phy_power_off_d (ifxusb_core_if_t *_core_if)
+#endif
+{
+ #if defined(__UEIP__)
+ if(_core_if->pcgcctl)
+ {
+ pcgcctl_data_t pcgcctl = {.d32=0};
+ pcgcctl.b.stoppclk = 1;
+ ifxusb_mreg(_core_if->pcgcctl, 0, pcgcctl.d32);
+ }
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
+ //USB_PHY_PMU_SETUP(IFX_PMU_DISABLE);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__) || defined(__IS_VR9__) || defined(__IS_AR10__)
+/* if(_core_if->core_no==0)
+ USB0_PHY_PMU_SETUP(IFX_PMU_DISABLE);
+ else
+ USB1_PHY_PMU_SETUP(IFX_PMU_DISABLE);*/
+ #endif // defined(__IS_AR9__) || defined(__IS_VR9__)
+ #else //defined(__UEIP__)
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ set_bit (0, (volatile unsigned long *)DANUBE_PMU_PWDCR);//PHY
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ set_bit (0, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);//PHY
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ set_bit (0, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY
+ else
+ set_bit (26, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY
+ #endif //defined(__IS_AR9__)
+ #endif //defined(__UEIP__)
+}
+
+
+/*!
+ \brief Reset on the USB Core RCU
+ \param _core_if Pointer of core_if structure
+ */
+#if defined(__IS_VR9__) || defined(__IS_AR10__)
+static int CheckAlready(void)
+{
+ gusbcfg_data_t usbcfg ={.d32 = 0};
+ usbcfg.d32 = ifxusb_rreg((volatile uint32_t *)0xBE10100C);
+ if(usbcfg.b.ForceDevMode)
+ return 1;
+ if(usbcfg.b.ForceHstMode)
+ return 1;
+ usbcfg.d32 = ifxusb_rreg((volatile uint32_t *)0xBE10600C);
+ if(usbcfg.b.ForceDevMode)
+ return 1;
+ if(usbcfg.b.ForceHstMode)
+ return 1;
+ return 0;
+}
+#endif
+
+#ifdef __IS_HOST__
+ void ifxusb_hard_reset_h(ifxusb_core_if_t *_core_if)
+#else
+ void ifxusb_hard_reset_d(ifxusb_core_if_t *_core_if)
+#endif
+{
+ #if defined(__UEIP__)
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined (__IS_HOST__)
+ clear_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
+ #elif defined (__IS_DEVICE__)
+ set_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
+ #endif
+ #endif //defined(__IS_AMAZON_SE__)
+
+ #if defined(__IS_AMAZON_SE__)
+ #if defined (__IS_HOST__)
+ clear_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
+ #elif defined (__IS_DEVICE__)
+ set_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
+ #endif
+ #endif //defined(__IS_AMAZON_SE__)
+
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ {
+ #if defined (__IS_HOST__)
+ clear_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG);
+ #elif defined (__IS_DEVICE__)
+ set_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG);
+ #endif
+ }
+ else
+ {
+ #if defined (__IS_HOST__)
+ clear_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG);
+ #elif defined (__IS_DEVICE__)
+ set_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG);
+ #endif
+ }
+ #endif //defined(__IS_AR9__)
+
+ #if defined(__IS_VR9__)
+ if(!CheckAlready())
+ {
+ #if defined (__IS_HOST__)
+ #if defined (__IS_DUAL__)
+ clear_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG);
+ clear_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG);
+ #elif defined (__IS_FIRST__)
+ clear_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG);
+ set_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG);
+ #elif defined (__IS_SECOND__)
+ set_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG);
+ clear_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG);
+ #endif
+ #endif
+ #if defined (__IS_DEVICE__)
+ #if defined (__IS_FIRST__)
+ set_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG);
+ clear_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG);
+ #elif defined (__IS_SECOND__)
+ clear_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG);
+ set_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG);
+ #endif
+ #endif
+ }
+ #endif //defined(__IS_VR9__)
+
+ #if defined(__IS_AR10__)
+ if(!CheckAlready())
+ {
+ #if defined (__IS_HOST__)
+ #if defined (__IS_DUAL__)
+ clear_bit (AR10_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR10_RCU_USB1CFG);
+ clear_bit (AR10_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR10_RCU_USB2CFG);
+ #elif defined (__IS_FIRST__)
+ clear_bit (AR10_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR10_RCU_USB1CFG);
+ set_bit (AR10_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR10_RCU_USB2CFG);
+ #elif defined (__IS_SECOND__)
+ set_bit (AR10_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR10_RCU_USB1CFG);
+ clear_bit (AR10_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR10_RCU_USB2CFG);
+ #endif
+ #endif
+ #if defined (__IS_DEVICE__)
+ #if defined (__IS_FIRST__)
+ set_bit (AR10_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR10_RCU_USB1CFG);
+ clear_bit (AR10_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR10_RCU_USB2CFG);
+ #elif defined (__IS_SECOND__)
+ clear_bit (AR10_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR10_RCU_USB1CFG);
+ set_bit (AR10_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR10_RCU_USB2CFG);
+ #endif
+ #endif
+ }
+ #endif //defined(__IS_AR10__)
+
+ // set the HC's byte-order to big-endian
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ set_bit (DANUBE_USBCFG_HOST_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
+ clear_bit (DANUBE_USBCFG_SLV_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ set_bit (AMAZON_SE_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
+ clear_bit (AMAZON_SE_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ {
+ set_bit (AR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG);
+ clear_bit (AR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG);
+ }
+ else
+ {
+ set_bit (AR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG);
+ clear_bit (AR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG);
+ }
+ #endif //defined(__IS_AR9__)
+ #if defined(__IS_VR9__)
+ if(_core_if->core_no==0)
+ {
+ set_bit (VR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG);
+ clear_bit (VR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG);
+ }
+ else
+ {
+ set_bit (VR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG);
+ clear_bit (VR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG);
+ }
+ #endif //defined(__IS_VR9__)
+ #if defined(__IS_AR10__)
+ if(_core_if->core_no==0)
+ {
+ set_bit (AR10_USBCFG_HOST_END_BIT, (volatile unsigned long *)AR10_RCU_USB1CFG);
+ clear_bit (AR10_USBCFG_SLV_END_BIT, (volatile unsigned long *)AR10_RCU_USB1CFG);
+ }
+ else
+ {
+ set_bit (AR10_USBCFG_HOST_END_BIT, (volatile unsigned long *)AR10_RCU_USB2CFG);
+ clear_bit (AR10_USBCFG_SLV_END_BIT, (volatile unsigned long *)AR10_RCU_USB2CFG);
+ }
+ #endif //defined(__IS_AR10__)
+
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ set_bit (4, DANUBE_RCU_RESET);
+ MDELAY(50);
+ clear_bit (4, DANUBE_RCU_RESET);
+ MDELAY(50);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+
+ #if defined(__IS_AMAZON_SE__)
+ set_bit (4, AMAZON_SE_RCU_RESET);
+ MDELAY(50);
+ clear_bit (4, AMAZON_SE_RCU_RESET);
+ MDELAY(50);
+ #endif //defined(__IS_AMAZON_SE__)
+
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ {
+ set_bit (4, AR9_RCU_USBRESET);
+ MDELAY(50);
+ clear_bit (4, AR9_RCU_USBRESET);
+ }
+ else
+ {
+ set_bit (28, AR9_RCU_USBRESET);
+ MDELAY(50);
+ clear_bit (28, AR9_RCU_USBRESET);
+ }
+ MDELAY(50);
+ #endif //defined(__IS_AR9__)
+ #if defined(__IS_VR9__)
+ if(!CheckAlready())
+ {
+ set_bit (4, VR9_RCU_USBRESET);
+ MDELAY(50);
+ clear_bit (4, VR9_RCU_USBRESET);
+ MDELAY(50);
+ }
+ #endif //defined(__IS_VR9__)
+ #if defined(__IS_AR10__)
+ if(!CheckAlready())
+ {
+ set_bit (4, AR10_RCU_USBRESET);
+ MDELAY(50);
+ clear_bit (4, AR10_RCU_USBRESET);
+ MDELAY(50);
+ }
+ #endif //defined(__IS_AR10__)
+
+ #if defined(__IS_TWINPASS__)
+ ifxusb_enable_afe_oc();
+ #endif
+
+ if(_core_if->core_global_regs)
+ {
+ // PHY configurations.
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AR9__)
+ #if defined(__IS_VR9__)
+ // ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_VR9__)
+ #if defined(__IS_AR10__)
+ // ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AR10__)
+ }
+ #else //defined(__UEIP__)
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined (__IS_HOST__)
+ clear_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
+ #elif defined (__IS_DEVICE__)
+ set_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
+ #endif
+ #endif //defined(__IS_AMAZON_SE__)
+
+ #if defined(__IS_AMAZON_SE__)
+ #if defined (__IS_HOST__)
+ clear_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
+ #elif defined (__IS_DEVICE__)
+ set_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
+ #endif
+ #endif //defined(__IS_AMAZON_SE__)
+
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ {
+ #if defined (__IS_HOST__)
+ clear_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG);
+ #elif defined (__IS_DEVICE__)
+ set_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG);
+ #endif
+ }
+ else
+ {
+ #if defined (__IS_HOST__)
+ clear_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG);
+ #elif defined (__IS_DEVICE__)
+ set_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG);
+ #endif
+ }
+ #endif //defined(__IS_AR9__)
+
+ // set the HC's byte-order to big-endian
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ set_bit (DANUBE_USBCFG_HOST_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
+ clear_bit (DANUBE_USBCFG_SLV_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ set_bit (AMAZON_SE_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
+ clear_bit (AMAZON_SE_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ {
+ set_bit (AMAZON_S_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG);
+ clear_bit (AMAZON_S_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG);
+ }
+ else
+ {
+ set_bit (AMAZON_S_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG);
+ clear_bit (AMAZON_S_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG);
+ }
+ #endif //defined(__IS_AR9__)
+
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ set_bit (4, DANUBE_RCU_RESET);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ set_bit (4, AMAZON_SE_RCU_RESET);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ {
+ set_bit (4, AMAZON_S_RCU_USBRESET);
+ }
+ else
+ {
+ set_bit (28, AMAZON_S_RCU_USBRESET);
+ }
+ #endif //defined(__IS_AR9__)
+
+ MDELAY(50);
+
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ clear_bit (4, DANUBE_RCU_RESET);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ clear_bit (4, AMAZON_SE_RCU_RESET);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ {
+ clear_bit (4, AMAZON_S_RCU_USBRESET);
+ }
+ else
+ {
+ clear_bit (28, AMAZON_S_RCU_USBRESET);
+ }
+ #endif //defined(__IS_AR9__)
+
+ MDELAY(50);
+
+ #if defined(__IS_TWINPASS__)
+ ifxusb_enable_afe_oc();
+ #endif
+
+ if(_core_if->core_global_regs)
+ {
+ // PHY configurations.
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014);
+ #endif //defined(__IS_AR9__)
+ }
+ #endif //defined(__UEIP__)
+}
+
+#if defined(__GADGET_LED__) || defined(__HOST_LED__)
+ #if defined(__UEIP__)
+ static void *g_usb_led_trigger = NULL;
+ #endif
+
+ void ifxusb_led_init(ifxusb_core_if_t *_core_if)
+ {
+ #if defined(__UEIP__)
+ #if defined(IFX_LEDGPIO_USB_LED) || defined(IFX_LEDLED_USB_LED)
+ if ( !g_usb_led_trigger )
+ {
+ ifx_led_trigger_register("usb_link", &g_usb_led_trigger);
+ if ( g_usb_led_trigger != NULL )
+ {
+ struct ifx_led_trigger_attrib attrib = {0};
+ attrib.delay_on = 250;
+ attrib.delay_off = 250;
+ attrib.timeout = 2000;
+ attrib.def_value = 1;
+ attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE;
+ IFX_DEBUGP("Reg USB LED!!\n");
+ ifx_led_trigger_set_attrib(g_usb_led_trigger, &attrib);
+ }
+ }
+ #endif
+ #endif //defined(__UEIP__)
+ }
+
+ void ifxusb_led_free(ifxusb_core_if_t *_core_if)
+ {
+ #if defined(__UEIP__)
+ if ( g_usb_led_trigger )
+ {
+ ifx_led_trigger_deregister(g_usb_led_trigger);
+ g_usb_led_trigger = NULL;
+ }
+ #endif //defined(__UEIP__)
+ }
+
+ /*!
+ \brief Turn off the USB 5V VBus Power
+ \param _core_if Pointer of core_if structure
+ */
+ void ifxusb_led(ifxusb_core_if_t *_core_if)
+ {
+ #if defined(__UEIP__)
+ if(g_usb_led_trigger)
+ ifx_led_trigger_activate(g_usb_led_trigger);
+ #else
+ #endif //defined(__UEIP__)
+ }
+#endif // defined(__GADGET_LED__) || defined(__HOST_LED__)
+
+
+
+/*!
+ \brief internal routines for debugging
+ */
+#ifdef __IS_HOST__
+void ifxusb_dump_msg_h(const u8 *buf, unsigned int length)
+#else
+void ifxusb_dump_msg_d(const u8 *buf, unsigned int length)
+#endif
+{
+#ifdef __DEBUG__
+ unsigned int start, num, i;
+ char line[52], *p;
+
+ if (length >= 512)
+ return;
+ start = 0;
+ while (length > 0)
+ {
+ num = min(length, 16u);
+ p = line;
+ for (i = 0; i < num; ++i)
+ {
+ if (i == 8)
+ *p++ = ' ';
+ sprintf(p, " %02x", buf[i]);
+ p += 3;
+ }
+ *p = 0;
+ IFX_PRINT( "%6x: %s\n", start, line);
+ buf += num;
+ start += num;
+ length -= num;
+ }
+#endif
+}
+
+/*!
+ \brief internal routines for debugging, reads the SPRAM and prints its content
+ */
+#ifdef __IS_HOST__
+void ifxusb_dump_spram_h(ifxusb_core_if_t *_core_if)
+#else
+void ifxusb_dump_spram_d(ifxusb_core_if_t *_core_if)
+#endif
+{
+#ifdef __ENABLE_DUMP__
+ volatile uint8_t *addr, *start_addr, *end_addr;
+ uint32_t size;
+ IFX_PRINT("SPRAM Data:\n");
+ start_addr = (void*)_core_if->core_global_regs;
+ IFX_PRINT("Base Address: 0x%8X\n", (uint32_t)start_addr);
+
+ start_addr = (void*)_core_if->data_fifo_dbg;
+ IFX_PRINT("Starting Address: 0x%8X\n", (uint32_t)start_addr);
+
+ size=_core_if->hwcfg3.b.dfifo_depth;
+ size<<=2;
+ size+=0x200;
+ size&=0x0003FFFC;
+
+ end_addr = (void*)_core_if->data_fifo_dbg;
+ end_addr += size;
+
+ for(addr = start_addr; addr < end_addr; addr+=16)
+ {
+ IFX_PRINT("0x%8X: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X \n", (uint32_t)addr,
+ 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]
+ );
+ }
+ return;
+#endif //__ENABLE_DUMP__
+}
+
+/*!
+ \brief internal routines for debugging, reads the core global registers and prints them
+ */
+#ifdef __IS_HOST__
+void ifxusb_dump_registers_h(ifxusb_core_if_t *_core_if)
+#else
+void ifxusb_dump_registers_d(ifxusb_core_if_t *_core_if)
+#endif
+{
+#ifdef __ENABLE_DUMP__
+ int i;
+ volatile uint32_t *addr;
+ #ifdef __IS_DEVICE__
+ volatile uint32_t *addri,*addro;
+ #endif
+
+ IFX_PRINT("Core #%d\n",_core_if->core_no);
+ IFX_PRINT("========================================\n");
+ IFX_PRINT("Core Global Registers\n");
+ addr=&_core_if->core_global_regs->gotgctl;
+ IFX_PRINT(" GOTGCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->gotgint;
+ IFX_PRINT(" GOTGINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->gahbcfg;
+ IFX_PRINT(" GAHBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->gusbcfg;
+ IFX_PRINT(" GUSBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->grstctl;
+ IFX_PRINT(" GRSTCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->gintsts;
+ IFX_PRINT(" GINTSTS @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->gintmsk;
+ IFX_PRINT(" GINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->gi2cctl;
+ IFX_PRINT(" GI2CCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->gpvndctl;
+ IFX_PRINT(" GPVNDCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->ggpio;
+ IFX_PRINT(" GGPIO @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->guid;
+ IFX_PRINT(" GUID @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->gsnpsid;
+ IFX_PRINT(" GSNPSID @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->ghwcfg1;
+ IFX_PRINT(" GHWCFG1 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->ghwcfg2;
+ IFX_PRINT(" GHWCFG2 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->ghwcfg3;
+ IFX_PRINT(" GHWCFG3 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->ghwcfg4;
+ IFX_PRINT(" GHWCFG4 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+
+ addr=_core_if->pcgcctl;
+ IFX_PRINT(" PCGCCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+
+ addr=&_core_if->core_global_regs->grxfsiz;
+ IFX_PRINT(" GRXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+
+ #ifdef __IS_HOST__
+ addr=&_core_if->core_global_regs->gnptxfsiz;
+ IFX_PRINT(" GNPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->core_global_regs->hptxfsiz;
+ IFX_PRINT(" HPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ #endif //__IS_HOST__
+
+ #ifdef __IS_DEVICE__
+ #ifdef __DED_FIFO__
+ addr=&_core_if->core_global_regs->gnptxfsiz;
+ IFX_PRINT(" GNPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ for (i=0; i<= _core_if->hwcfg4.b.num_in_eps; i++)
+ {
+ addr=&_core_if->core_global_regs->dptxfsiz_dieptxf[i];
+ IFX_PRINT(" DPTXFSIZ[%d] @0x%08X : 0x%08X\n",i,(uint32_t)addr,ifxusb_rreg(addr));
+ }
+ #else
+ addr=&_core_if->core_global_regs->gnptxfsiz;
+ IFX_PRINT(" TXFSIZ[00] @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ for (i=0; i< _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
+ {
+ addr=&_core_if->core_global_regs->dptxfsiz_dieptxf[i];
+ IFX_PRINT(" TXFSIZ[%02d] @0x%08X : 0x%08X\n",i+1,(uint32_t)addr,ifxusb_rreg(addr));
+ }
+ #endif
+ #endif //__IS_DEVICE__
+
+ #ifdef __IS_HOST__
+ IFX_PRINT(" Host Global Registers\n");
+ addr=&_core_if->host_global_regs->hcfg;
+ IFX_PRINT(" HCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->host_global_regs->hfir;
+ IFX_PRINT(" HFIR @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->host_global_regs->hfnum;
+ IFX_PRINT(" HFNUM @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->host_global_regs->hptxsts;
+ IFX_PRINT(" HPTXSTS @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->host_global_regs->haint;
+ IFX_PRINT(" HAINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->host_global_regs->haintmsk;
+ IFX_PRINT(" HAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr= _core_if->hprt0;
+ IFX_PRINT(" HPRT0 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+
+ for (i=0; i<MAX_EPS_CHANNELS; i++)
+ {
+ addr=&_core_if->hc_regs[i]->hcchar;
+ IFX_PRINT(" Host Channel %d Specific Registers\n", i);
+ IFX_PRINT(" HCCHAR @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->hc_regs[i]->hcsplt;
+ IFX_PRINT(" HCSPLT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->hc_regs[i]->hcint;
+ IFX_PRINT(" HCINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->hc_regs[i]->hcintmsk;
+ IFX_PRINT(" HCINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->hc_regs[i]->hctsiz;
+ IFX_PRINT(" HCTSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->hc_regs[i]->hcdma;
+ IFX_PRINT(" HCDMA @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ }
+ #endif //__IS_HOST__
+
+ #ifdef __IS_DEVICE__
+ IFX_PRINT(" Device Global Registers\n");
+ addr=&_core_if->dev_global_regs->dcfg;
+ IFX_PRINT(" DCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->dev_global_regs->dctl;
+ IFX_PRINT(" DCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->dev_global_regs->dsts;
+ IFX_PRINT(" DSTS @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->dev_global_regs->diepmsk;
+ IFX_PRINT(" DIEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->dev_global_regs->doepmsk;
+ IFX_PRINT(" DOEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->dev_global_regs->daintmsk;
+ IFX_PRINT(" DAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->dev_global_regs->daint;
+ IFX_PRINT(" DAINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->dev_global_regs->dvbusdis;
+ IFX_PRINT(" DVBUSID @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ addr=&_core_if->dev_global_regs->dvbuspulse;
+ IFX_PRINT(" DVBUSPULS @0x%08X : 0x%08X\n", (uint32_t)addr,ifxusb_rreg(addr));
+
+ addr=&_core_if->dev_global_regs->dtknqr1;
+ IFX_PRINT(" DTKNQR1 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr));
+ if (_core_if->hwcfg2.b.dev_token_q_depth > 6) {
+ addr=&_core_if->dev_global_regs->dtknqr2;
+ IFX_PRINT(" DTKNQR2 @0x%08X : 0x%08X\n", (uint32_t)addr,ifxusb_rreg(addr));
+ }
+
+ if (_core_if->hwcfg2.b.dev_token_q_depth > 14)
+ {
+ addr=&_core_if->dev_global_regs->dtknqr3_dthrctl;
+ IFX_PRINT(" DTKNQR3_DTHRCTL @0x%08X : 0x%08X\n", (uint32_t)addr, ifxusb_rreg(addr));
+ }
+
+ if (_core_if->hwcfg2.b.dev_token_q_depth > 22)
+ {
+ addr=&_core_if->dev_global_regs->dtknqr4_fifoemptymsk;
+ IFX_PRINT(" DTKNQR4 @0x%08X : 0x%08X\n", (uint32_t)addr, ifxusb_rreg(addr));
+ }
+
+ //for (i=0; i<= MAX_EPS_CHANNELS; i++)
+ //for (i=0; i<= 10; i++)
+ for (i=0; i<= 3; i++)
+ {
+ IFX_PRINT(" Device EP %d Registers\n", i);
+ addri=&_core_if->in_ep_regs[i]->diepctl;addro=&_core_if->out_ep_regs[i]->doepctl;
+ IFX_PRINT(" DEPCTL I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro));
+ addro=&_core_if->out_ep_regs[i]->doepfn;
+ IFX_PRINT(" DEPFN I: O: 0x%08X\n",ifxusb_rreg(addro));
+ addri=&_core_if->in_ep_regs[i]->diepint;addro=&_core_if->out_ep_regs[i]->doepint;
+ IFX_PRINT(" DEPINT I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro));
+ addri=&_core_if->in_ep_regs[i]->dieptsiz;addro=&_core_if->out_ep_regs[i]->doeptsiz;
+ IFX_PRINT(" DETSIZ I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro));
+ addri=&_core_if->in_ep_regs[i]->diepdma;addro=&_core_if->out_ep_regs[i]->doepdma;
+ IFX_PRINT(" DEPDMA I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro));
+ addri=&_core_if->in_ep_regs[i]->dtxfsts;
+ IFX_PRINT(" DTXFSTS I: 0x%08X\n",ifxusb_rreg(addri) );
+ addri=&_core_if->in_ep_regs[i]->diepdmab;addro=&_core_if->out_ep_regs[i]->doepdmab;
+ IFX_PRINT(" DEPDMAB I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro));
+ }
+ #endif //__IS_DEVICE__
+#endif //__ENABLE_DUMP__
+}
+
+#ifdef __IS_HOST__
+void do_suspend_h(ifxusb_core_if_t *core_if)
+{
+ ifxusb_vbus_off(core_if);
+ mdelay(100);
+ ifxusb_power_off_h(core_if);
+}
+void do_resume_h(ifxusb_core_if_t *core_if)
+{
+ ifxusb_vbus_on(core_if);
+ mdelay(100);
+ ifxusb_power_on_h(core_if);
+ ifxusb_phy_power_on_h(core_if);
+}
+#endif
+#ifdef __IS_DEVICE__
+void do_suspend_d(ifxusb_core_if_t *core_if)
+{
+ ifxusb_power_off_d(core_if);
+}
+void do_resume_d(ifxusb_core_if_t *core_if)
+{
+ dctl_data_t dctl = {.d32=0};
+
+ ifxusb_power_on_d(core_if);
+ ifxusb_phy_power_on_d(core_if);
+ dctl.d32=ifxusb_rreg(&core_if->dev_global_regs->dctl);
+ dctl.b.sftdiscon=1;
+ ifxusb_wreg(&core_if->dev_global_regs->dctl,dctl.d32);
+ mdelay(50);
+ dctl.b.sftdiscon=0;
+ ifxusb_wreg(&core_if->dev_global_regs->dctl,dctl.d32);
+}
+#endif
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif.h b/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif.h
new file mode 100644
index 0000000000..5af988f91f
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif.h
@@ -0,0 +1,767 @@
+/*****************************************************************************
+ ** FILE NAME : ifxusb_cif.h
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** AUTHOR : Chen, Howard
+ ** DESCRIPTION : The Core Interface provides basic services for accessing and
+ ** managing the IFX USB hardware. These services are used by both the
+ ** Host Controller Driver and the Peripheral Controller Driver.
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*!
+ \defgroup IFXUSB_DRIVER_V3 IFX USB SS Project
+ \brief IFX USB subsystem V3.x
+ */
+
+/*!
+ \defgroup IFXUSB_CIF Core Interface APIs
+ \ingroup IFXUSB_DRIVER_V3
+ \brief The Core Interface provides basic services for accessing and
+ managing the IFXUSB hardware. These services are used by both the
+ Host Controller Driver and the Peripheral Controller Driver.
+ */
+
+
+/*!
+ \file ifxusb_cif.h
+ \ingroup IFXUSB_DRIVER_V3
+ \brief This file contains the interface to the IFX USB Core.
+ */
+
+#if !defined(__IFXUSB_CIF_H__)
+#define __IFXUSB_CIF_H__
+
+#include <linux/workqueue.h>
+
+#include <linux/version.h>
+#include <asm/param.h>
+
+#include "ifxusb_plat.h"
+#include "ifxusb_regs.h"
+
+#ifdef __DEBUG__
+ #include "linux/timer.h"
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define IFXUSB_PARAM_SPEED_HIGH 0 /*!< Build stage parameter: High Speed */
+#define IFXUSB_PARAM_SPEED_FULL 1 /*!< Build stage parameter: Full Speed */
+
+#define IFXUSB_EP_SPEED_LOW 0 /*!< Run-Time Status: High Speed */
+#define IFXUSB_EP_SPEED_FULL 1 /*!< Run-Time Status: Full Speed */
+#define IFXUSB_EP_SPEED_HIGH 2 /*!< Run-Time Status: Low Speed */
+
+#define IFXUSB_EP_TYPE_CTRL 0 /*!< Run-Time Status: CTRL */
+#define IFXUSB_EP_TYPE_ISOC 1 /*!< Run-Time Status: ISOC */
+#define IFXUSB_EP_TYPE_BULK 2 /*!< Run-Time Status: BULK */
+#define IFXUSB_EP_TYPE_INTR 3 /*!< Run-Time Status: INTR */
+
+#define IFXUSB_HC_PID_DATA0 0 /*!< Run-Time Data Toggle: Data 0 */
+#define IFXUSB_HC_PID_DATA2 1 /*!< Run-Time Data Toggle: Data 2 */
+#define IFXUSB_HC_PID_DATA1 2 /*!< Run-Time Data Toggle: Data 1 */
+#define IFXUSB_HC_PID_MDATA 3 /*!< Run-Time Data Toggle: MData */
+#define IFXUSB_HC_PID_SETUP 3 /*!< Run-Time Data Toggle: Setup */
+
+
+/*!
+ \addtogroup IFXUSB_CIF
+ */
+/*@{*/
+
+/*! typedef ifxusb_params_t
+ \brief IFXUSB Parameters structure.
+ This structure is used for both importing from insmod stage and run-time storage.
+ These parameters define how the IFXUSB controller should be configured.
+ */
+typedef struct ifxusb_params
+{
+ int32_t dma_burst_size; /*!< The DMA Burst size (applicable only for Internal DMA
+ Mode). 0(for single), 1(incr), 4(incr4), 8(incr8) 16(incr16)
+ */
+ /* Translate this to GAHBCFG values */
+ int32_t speed; /*!< Specifies the maximum speed of operation in host and device mode.
+ The actual speed depends on the speed of the attached device and
+ the value of phy_type. The actual speed depends on the speed of the
+ attached device.
+ 0 - High Speed (default)
+ 1 - Full Speed
+ */
+
+ int32_t data_fifo_size; /*!< Total number of dwords in the data FIFO memory. This
+ memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic
+ Tx FIFOs.
+ 32 to 32768
+ */
+ #ifdef __IS_DEVICE__
+ int32_t rx_fifo_size; /*!< Number of dwords in the Rx FIFO in device mode.
+ 16 to 32768
+ */
+
+
+ int32_t tx_fifo_size[MAX_EPS_CHANNELS]; /*!< Number of dwords in each of the Tx FIFOs in device mode.
+ 4 to 768
+ */
+ #ifdef __DED_FIFO__
+ int32_t thr_ctl; /*!< Threshold control on/off */
+ int32_t tx_thr_length; /*!< Threshold length for Tx */
+ int32_t rx_thr_length; /*!< Threshold length for Rx*/
+ #endif
+ #else //__IS_HOST__
+ int32_t host_channels; /*!< The number of host channel registers to use.
+ 1 to 16
+ */
+
+ int32_t rx_fifo_size; /*!< Number of dwords in the Rx FIFO in host mode.
+ 16 to 32768
+ */
+
+ int32_t nperio_tx_fifo_size;/*!< Number of dwords in the non-periodic Tx FIFO in host mode.
+ 16 to 32768
+ */
+
+ int32_t perio_tx_fifo_size; /*!< Number of dwords in the host periodic Tx FIFO.
+ 16 to 32768
+ */
+ #endif //__IS_HOST__
+
+ int32_t max_transfer_size; /*!< The maximum transfer size supported in bytes.
+ 2047 to 65,535
+ */
+
+ int32_t max_packet_count; /*!< The maximum number of packets in a transfer.
+ 15 to 511 (default 511)
+ */
+ int32_t phy_utmi_width; /*!< Specifies the UTMI+ Data Width.
+ 8 or 16 bits (default 16)
+ */
+
+ int32_t turn_around_time_hs; /*!< Specifies the Turn-Around time at HS*/
+ int32_t turn_around_time_fs; /*!< Specifies the Turn-Around time at FS*/
+
+ int32_t timeout_cal_hs; /*!< Specifies the Timeout_Calibration at HS*/
+ int32_t timeout_cal_fs; /*!< Specifies the Timeout_Calibration at FS*/
+} ifxusb_params_t;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*! typedef ifxusb_core_if_t
+ \brief The ifx_core_if structure contains information needed to manage
+ the IFX USB controller acting in either host or device mode. It
+ represents the programming view of the controller as a whole.
+ */
+typedef struct ifxusb_core_if
+{
+ ifxusb_params_t params; /*!< Run-time Parameters */
+
+ uint8_t core_no; /*!< core number (used as id when multi-core case */
+ char *core_name; /*!< core name used for registration and informative purpose*/
+ int irq; /*!< irq number this core is hooked */
+
+ /*****************************************************************
+ * Structures and pointers to physical register interface.
+ *****************************************************************/
+ /** Core Global registers starting at offset 000h. */
+ ifxusb_core_global_regs_t *core_global_regs; /*!< pointer to Core Global Registers, offset at 000h */
+
+ /** Host-specific registers */
+ #ifdef __IS_HOST__
+ /** Host Global Registers starting at offset 400h.*/
+ ifxusb_host_global_regs_t *host_global_regs; /*!< pointer to Host Global Registers, offset at 400h */
+ #define IFXUSB_HOST_GLOBAL_REG_OFFSET 0x400
+ /** Host Port 0 Control and Status Register */
+ volatile uint32_t *hprt0; /*!< pointer to HPRT0 Registers, offset at 440h */
+ #define IFXUSB_HOST_PORT_REGS_OFFSET 0x440
+ /** Host Channel Specific Registers at offsets 500h-5FCh. */
+ ifxusb_hc_regs_t *hc_regs[MAX_EPS_CHANNELS]; /*!< pointer to Host-Channel n Registers, offset at 500h */
+ #define IFXUSB_HOST_CHAN_REGS_OFFSET 0x500
+ #define IFXUSB_CHAN_REGS_OFFSET 0x20
+ #endif
+
+ /** Device-specific registers */
+ #ifdef __IS_DEVICE__
+ /** Device Global Registers starting at offset 800h */
+ ifxusb_device_global_regs_t *dev_global_regs; /*!< pointer to Device Global Registers, offset at 800h */
+ #define IFXUSB_DEV_GLOBAL_REG_OFFSET 0x800
+
+ /** Device Logical IN Endpoint-Specific Registers 900h-AFCh */
+ ifxusb_dev_in_ep_regs_t *in_ep_regs[MAX_EPS_CHANNELS]; /*!< pointer to Device IN-EP Registers, offset at 900h */
+ #define IFXUSB_DEV_IN_EP_REG_OFFSET 0x900
+ #define IFXUSB_EP_REG_OFFSET 0x20
+ /** Device Logical OUT Endpoint-Specific Registers B00h-CFCh */
+ ifxusb_dev_out_ep_regs_t *out_ep_regs[MAX_EPS_CHANNELS];/*!< pointer to Device OUT-EP Registers, offset at 900h */
+ #define IFXUSB_DEV_OUT_EP_REG_OFFSET 0xB00
+ #endif
+
+ /** Power and Clock Gating Control Register */
+ volatile uint32_t *pcgcctl; /*!< pointer to Power and Clock Gating Control Registers, offset at E00h */
+ #define IFXUSB_PCGCCTL_OFFSET 0xE00
+
+ /** Push/pop addresses for endpoints or host channels.*/
+ uint32_t *data_fifo[MAX_EPS_CHANNELS]; /*!< pointer to FIFO access windows, offset at 1000h */
+ #define IFXUSB_DATA_FIFO_OFFSET 0x1000
+ #define IFXUSB_DATA_FIFO_SIZE 0x1000
+
+ uint32_t *data_fifo_dbg; /*!< pointer to FIFO debug windows, offset at 1000h */
+
+ /** Hardware Configuration -- stored here for convenience.*/
+ hwcfg1_data_t hwcfg1; /*!< preserved Hardware Configuration 1 */
+ hwcfg2_data_t hwcfg2; /*!< preserved Hardware Configuration 2 */
+ hwcfg3_data_t hwcfg3; /*!< preserved Hardware Configuration 3 */
+ hwcfg4_data_t hwcfg4; /*!< preserved Hardware Configuration 3 */
+ uint32_t snpsid; /*!< preserved SNPSID */
+
+ /*****************************************************************
+ * Run-time informations.
+ *****************************************************************/
+ /* Set to 1 if the core PHY interface bits in USBCFG have been initialized. */
+ uint8_t phy_init_done; /*!< indicated PHY is initialized. */
+
+ #ifdef __IS_HOST__
+ uint8_t queuing_high_bandwidth; /*!< Host mode, Queueing High Bandwidth. */
+ #endif
+
+ #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
+ uint32_t unaligned_mask;
+ #endif
+} ifxusb_core_if_t;
+
+/*@}*//*IFXUSB_CIF*/
+
+
+/*!
+ \fn void *ifxusb_alloc_buf(size_t size, int clear)
+ \brief This function is called to allocate buffer of specified size.
+ The allocated buffer is mapped into DMA accessable address.
+ \param size Size in BYTE to be allocated
+ \param clear 0: don't do clear after buffer allocated, other: do clear to zero
+ \return 0/NULL: Fail; uncached pointer of allocated buffer
+ \ingroup IFXUSB_CIF
+ */
+#ifdef __IS_HOST__
+extern void *ifxusb_alloc_buf_h(size_t size, int clear);
+#else
+extern void *ifxusb_alloc_buf_d(size_t size, int clear);
+#endif
+
+
+/*!
+ \fn void ifxusb_free_buf(void *vaddr)
+ \brief This function is called to free allocated buffer.
+ \param vaddr the uncached pointer of the buffer
+ \ingroup IFXUSB_CIF
+ */
+#ifdef __IS_HOST__
+extern void ifxusb_free_buf_h(void *vaddr);
+#else
+extern void ifxusb_free_buf_d(void *vaddr);
+#endif
+
+/*!
+ \fn int ifxusb_core_if_init(ifxusb_core_if_t *_core_if,
+ int _irq,
+ uint32_t _reg_base_addr,
+ uint32_t _fifo_base_addr,
+ uint32_t _fifo_dbg_addr)
+ \brief This function is called to initialize the IFXUSB CSR data
+ structures. The register addresses in the device and host
+ structures are initialized from the base address supplied by the
+ caller. The calling function must make the OS calls to get the
+ base address of the IFXUSB controller registers.
+ \param _core_if Pointer of core_if structure
+ \param _irq irq number
+ \param _reg_base_addr Base address of IFXUSB core registers
+ \param _fifo_base_addr Fifo base address
+ \param _fifo_dbg_addr Fifo debug address
+ \return 0: success;
+ \ingroup IFXUSB_CIF
+ */
+#ifdef __IS_HOST__
+extern int ifxusb_core_if_init_h(ifxusb_core_if_t *_core_if,
+#else
+extern int ifxusb_core_if_init_d(ifxusb_core_if_t *_core_if,
+#endif
+ int _irq,
+ uint32_t _reg_base_addr,
+ uint32_t _fifo_base_addr,
+ uint32_t _fifo_dbg_addr);
+
+
+/*!
+ \fn void ifxusb_core_if_remove(ifxusb_core_if_t *_core_if)
+ \brief This function free the mapped address in the IFXUSB CSR data structures.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+#ifdef __IS_HOST__
+extern void ifxusb_core_if_remove_h(ifxusb_core_if_t *_core_if);
+#else
+extern void ifxusb_core_if_remove_d(ifxusb_core_if_t *_core_if);
+#endif
+
+/*!
+ \fn void ifxusb_enable_global_interrupts( ifxusb_core_if_t *_core_if )
+ \brief This function enbles the controller's Global Interrupt in the AHB Config register.
+ \param _core_if Pointer of core_if structure
+ */
+#ifdef __IS_HOST__
+extern void ifxusb_enable_global_interrupts_h( ifxusb_core_if_t *_core_if );
+#else
+extern void ifxusb_enable_global_interrupts_d( ifxusb_core_if_t *_core_if );
+#endif
+
+/*!
+ \fn void ifxusb_disable_global_interrupts( ifxusb_core_if_t *_core_if )
+ \brief This function disables the controller's Global Interrupt in the AHB Config register.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+#ifdef __IS_HOST__
+extern void ifxusb_disable_global_interrupts_h( ifxusb_core_if_t *_core_if );
+#else
+extern void ifxusb_disable_global_interrupts_d( ifxusb_core_if_t *_core_if );
+#endif
+
+/*!
+ \fn void ifxusb_flush_tx_fifo( ifxusb_core_if_t *_core_if, const int _num )
+ \brief Flush a Tx FIFO.
+ \param _core_if Pointer of core_if structure
+ \param _num Tx FIFO to flush. ( 0x10 for ALL TX FIFO )
+ \ingroup IFXUSB_CIF
+ */
+#ifdef __IS_HOST__
+extern void ifxusb_flush_tx_fifo_h( ifxusb_core_if_t *_core_if, const int _num );
+#else
+extern void ifxusb_flush_tx_fifo_d( ifxusb_core_if_t *_core_if, const int _num );
+#endif
+
+/*!
+ \fn void ifxusb_flush_rx_fifo( ifxusb_core_if_t *_core_if )
+ \brief Flush Rx FIFO.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+#ifdef __IS_HOST__
+extern void ifxusb_flush_rx_fifo_h( ifxusb_core_if_t *_core_if );
+#else
+extern void ifxusb_flush_rx_fifo_d( ifxusb_core_if_t *_core_if );
+#endif
+
+/*!
+ \fn void ifxusb_flush_both_fifo( ifxusb_core_if_t *_core_if )
+ \brief Flush ALL Rx and Tx FIFO.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+#ifdef __IS_HOST__
+extern void ifxusb_flush_both_fifo_h( ifxusb_core_if_t *_core_if );
+#else
+extern void ifxusb_flush_both_fifo_d( ifxusb_core_if_t *_core_if );
+#endif
+
+
+/*!
+ \fn int ifxusb_core_soft_reset(ifxusb_core_if_t *_core_if)
+ \brief Do core a soft reset of the core. Be careful with this because it
+ resets all the internal state machines of the core.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+#ifdef __IS_HOST__
+extern int ifxusb_core_soft_reset_h(ifxusb_core_if_t *_core_if);
+#else
+extern int ifxusb_core_soft_reset_d(ifxusb_core_if_t *_core_if);
+#endif
+
+
+/*!
+ \brief Turn on the USB Core Power
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+*/
+#ifdef __IS_HOST__
+ extern void ifxusb_power_on_h (ifxusb_core_if_t *_core_if);
+#else
+ extern void ifxusb_power_on_d (ifxusb_core_if_t *_core_if);
+#endif
+
+/*!
+ \fn void ifxusb_power_off (ifxusb_core_if_t *_core_if)
+ \brief Turn off the USB Core Power
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+*/
+#ifdef __IS_HOST__
+ extern void ifxusb_power_off_h (ifxusb_core_if_t *_core_if);
+#else
+ extern void ifxusb_power_off_d (ifxusb_core_if_t *_core_if);
+#endif
+
+/*!
+ \fn void ifxusb_phy_power_on (ifxusb_core_if_t *_core_if)
+ \brief Turn on the USB PHY Power
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+*/
+#ifdef __IS_HOST__
+ extern void ifxusb_phy_power_on_h (ifxusb_core_if_t *_core_if);
+#else
+ extern void ifxusb_phy_power_on_d (ifxusb_core_if_t *_core_if);
+#endif
+
+
+/*!
+ \fn void ifxusb_phy_power_off (ifxusb_core_if_t *_core_if)
+ \brief Turn off the USB PHY Power
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+*/
+#ifdef __IS_HOST__
+ extern void ifxusb_phy_power_off_h (ifxusb_core_if_t *_core_if);
+#else
+ extern void ifxusb_phy_power_off_d (ifxusb_core_if_t *_core_if);
+#endif
+
+/*!
+ \fn void ifxusb_hard_reset(ifxusb_core_if_t *_core_if)
+ \brief Reset on the USB Core RCU
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+#ifdef __IS_HOST__
+ extern void ifxusb_hard_reset_h(ifxusb_core_if_t *_core_if);
+#else
+ extern void ifxusb_hard_reset_d(ifxusb_core_if_t *_core_if);
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __IS_HOST__
+ /*!
+ \fn void ifxusb_host_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params)
+ \brief This function initializes the IFXUSB controller registers for Host mode.
+ This function flushes the Tx and Rx FIFOs and it flushes any entries in the
+ request queues.
+ \param _core_if Pointer of core_if structure
+ \param _params parameters to be set
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_host_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params);
+
+ /*!
+ \fn void ifxusb_host_enable_interrupts(ifxusb_core_if_t *_core_if)
+ \brief This function enables the Host mode interrupts.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_host_enable_interrupts(ifxusb_core_if_t *_core_if);
+
+ /*!
+ \fn void ifxusb_host_disable_interrupts(ifxusb_core_if_t *_core_if)
+ \brief This function disables the Host mode interrupts.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_host_disable_interrupts(ifxusb_core_if_t *_core_if);
+
+ #if defined(__IS_TWINPASS__)
+ extern void ifxusb_enable_afe_oc(void);
+ #endif
+
+ /*!
+ \fn void ifxusb_vbus_init(ifxusb_core_if_t *_core_if)
+ \brief This function init the VBUS control.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_vbus_init(ifxusb_core_if_t *_core_if);
+
+ /*!
+ \fn void ifxusb_vbus_free(ifxusb_core_if_t *_core_if)
+ \brief This function free the VBUS control.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_vbus_free(ifxusb_core_if_t *_core_if);
+
+ /*!
+ \fn void ifxusb_vbus_on(ifxusb_core_if_t *_core_if)
+ \brief Turn on the USB 5V VBus Power
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_vbus_on(ifxusb_core_if_t *_core_if);
+
+ /*!
+ \fn void ifxusb_vbus_off(ifxusb_core_if_t *_core_if)
+ \brief Turn off the USB 5V VBus Power
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_vbus_off(ifxusb_core_if_t *_core_if);
+
+ /*!
+ \fn int ifxusb_vbus(ifxusb_core_if_t *_core_if)
+ \brief Read Current VBus status
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern int ifxusb_vbus(ifxusb_core_if_t *_core_if);
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __IS_DEVICE__
+ /*!
+ \fn void ifxusb_dev_enable_interrupts(ifxusb_core_if_t *_core_if)
+ \brief This function enables the Device mode interrupts.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_dev_enable_interrupts(ifxusb_core_if_t *_core_if);
+
+ /*!
+ \fn uint32_t ifxusb_dev_get_frame_number(ifxusb_core_if_t *_core_if)
+ \brief Gets the current USB frame number. This is the frame number from the last SOF packet.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern uint32_t ifxusb_dev_get_frame_number(ifxusb_core_if_t *_core_if);
+
+ /*!
+ \fn void ifxusb_dev_ep_set_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _is_in)
+ \brief Set the EP STALL.
+ \param _core_if Pointer of core_if structure
+ \param _epno EP number
+ \param _is_in 1: is IN transfer
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_dev_ep_set_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _is_in);
+
+ /*!
+ \fn void ifxusb_dev_ep_clear_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _ep_type, uint8_t _is_in)
+ \brief Set the EP STALL.
+ \param _core_if Pointer of core_if structure
+ \param _epno EP number
+ \param _ep_type EP Type
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_dev_ep_clear_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _ep_type, uint8_t _is_in);
+
+ /*!
+ \fn void ifxusb_dev_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params)
+ \brief This function initializes the IFXUSB controller registers for Device mode.
+ This function flushes the Tx and Rx FIFOs and it flushes any entries in the
+ request queues.
+ This function validate the imported parameters and store the result in the CIF structure.
+ After
+ \param _core_if Pointer of core_if structure
+ \param _params structure of inported parameters
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_dev_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params);
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if defined(__GADGET_LED__) || defined(__HOST_LED__)
+ /*!
+ \fn void ifxusb_led_init(ifxusb_core_if_t *_core_if)
+ \brief This function init the LED control.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_led_init(ifxusb_core_if_t *_core_if);
+
+ /*!
+ \fn void ifxusb_led_free(ifxusb_core_if_t *_core_if)
+ \brief This function free the LED control.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_led_free(ifxusb_core_if_t *_core_if);
+
+ /*!
+ \fn void ifxusb_led(ifxusb_core_if_t *_core_if)
+ \brief This function trigger the LED access.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+ extern void ifxusb_led(ifxusb_core_if_t *_core_if);
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/* internal routines for debugging */
+#ifdef __IS_HOST__
+ extern void ifxusb_dump_msg_h(const u8 *buf, unsigned int length);
+ extern void ifxusb_dump_spram_h(ifxusb_core_if_t *_core_if);
+ extern void ifxusb_dump_registers_h(ifxusb_core_if_t *_core_if);
+#else
+ extern void ifxusb_dump_msg_d(const u8 *buf, unsigned int length);
+ extern void ifxusb_dump_spram_d(ifxusb_core_if_t *_core_if);
+ extern void ifxusb_dump_registers_d(ifxusb_core_if_t *_core_if);
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static inline uint32_t ifxusb_read_core_intr(ifxusb_core_if_t *_core_if)
+{
+ return (ifxusb_rreg(&_core_if->core_global_regs->gintsts) &
+ ifxusb_rreg(&_core_if->core_global_regs->gintmsk));
+}
+
+static inline uint32_t ifxusb_read_otg_intr (ifxusb_core_if_t *_core_if)
+{
+ return (ifxusb_rreg (&_core_if->core_global_regs->gotgint));
+}
+
+static inline uint32_t ifxusb_mode(ifxusb_core_if_t *_core_if)
+{
+ return (ifxusb_rreg( &_core_if->core_global_regs->gintsts ) & 0x1);
+}
+static inline uint8_t ifxusb_is_device_mode(ifxusb_core_if_t *_core_if)
+{
+ return (ifxusb_mode(_core_if) != 1);
+}
+static inline uint8_t ifxusb_is_host_mode(ifxusb_core_if_t *_core_if)
+{
+ return (ifxusb_mode(_core_if) == 1);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __IS_HOST__
+ static inline uint32_t ifxusb_read_hprt0(ifxusb_core_if_t *_core_if)
+ {
+ hprt0_data_t hprt0;
+ hprt0.d32 = ifxusb_rreg(_core_if->hprt0);
+ hprt0.b.prtena = 0;
+ hprt0.b.prtconndet = 0;
+ hprt0.b.prtenchng = 0;
+ hprt0.b.prtovrcurrchng = 0;
+ return hprt0.d32;
+ }
+
+ static inline uint32_t ifxusb_read_host_all_channels_intr (ifxusb_core_if_t *_core_if)
+ {
+ return (ifxusb_rreg (&_core_if->host_global_regs->haint));
+ }
+
+ static inline uint32_t ifxusb_read_host_channel_intr (ifxusb_core_if_t *_core_if, int hc_num)
+ {
+ return (ifxusb_rreg (&_core_if->hc_regs[hc_num]->hcint));
+ }
+#endif
+
+#ifdef __IS_DEVICE__
+ static inline uint32_t ifxusb_read_dev_all_in_ep_intr(ifxusb_core_if_t *_core_if)
+ {
+ uint32_t v;
+ v = ifxusb_rreg(&_core_if->dev_global_regs->daint) &
+ ifxusb_rreg(&_core_if->dev_global_regs->daintmsk);
+ return (v & 0xffff);
+ }
+
+ static inline uint32_t ifxusb_read_dev_all_out_ep_intr(ifxusb_core_if_t *_core_if)
+ {
+ uint32_t v;
+ v = ifxusb_rreg(&_core_if->dev_global_regs->daint) &
+ ifxusb_rreg(&_core_if->dev_global_regs->daintmsk);
+ return ((v & 0xffff0000) >> 16);
+ }
+
+ static inline uint32_t ifxusb_read_dev_in_ep_intr(ifxusb_core_if_t *_core_if, int _ep_num)
+ {
+ uint32_t v;
+ v = ifxusb_rreg(&_core_if->in_ep_regs[_ep_num]->diepint) &
+ ifxusb_rreg(&_core_if->dev_global_regs->diepmsk);
+ return v;
+ }
+
+ static inline uint32_t ifxusb_read_dev_out_ep_intr(ifxusb_core_if_t *_core_if, int _ep_num)
+ {
+ uint32_t v;
+ v = ifxusb_rreg(&_core_if->out_ep_regs[_ep_num]->doepint) &
+ ifxusb_rreg(&_core_if->dev_global_regs->doepmsk);
+ return v;
+ }
+
+#endif
+
+#ifdef __IS_HOST__
+extern void ifxusb_attr_create_h (void *_dev);
+extern void ifxusb_attr_remove_h (void *_dev);
+#else
+extern void ifxusb_attr_create_d (void *_dev);
+extern void ifxusb_attr_remove_d (void *_dev);
+#endif
+
+#ifdef __IS_HOST__
+extern void do_suspend_h(ifxusb_core_if_t *core_if);
+extern void do_resume_h(ifxusb_core_if_t *_core_if);
+#else
+extern void do_suspend_d(ifxusb_core_if_t *core_if);
+extern void do_resume_d(ifxusb_core_if_t *_core_if);
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#endif // !defined(__IFXUSB_CIF_H__)
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif_d.c b/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif_d.c
new file mode 100644
index 0000000000..19f7650410
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif_d.c
@@ -0,0 +1,535 @@
+/*****************************************************************************
+ ** FILE NAME : ifxusb_cif_d.c
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** AUTHOR : Chen, Howard
+ ** DESCRIPTION : The Core Interface provides basic services for accessing and
+ ** managing the IFX USB hardware. These services are used by the
+ ** Peripheral Controller Driver only.
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*!
+ \file ifxusb_cif_d.c
+ \ingroup IFXUSB_DRIVER_V3
+ \brief This file contains the interface to the IFX USB Core.
+*/
+
+#include <linux/version.h>
+#include "ifxusb_version.h"
+
+
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
+
+#ifdef __DEBUG__
+ #include <linux/jiffies.h>
+#endif
+
+#include "ifxusb_plat.h"
+#include "ifxusb_regs.h"
+#include "ifxusb_cif.h"
+
+#include "ifxpcd.h"
+
+
+
+/*!
+ \brief Initializes the DevSpd field of the DCFG register depending on the PHY type
+ and the enumeration speed of the device.
+ \param _core_if Pointer of core_if structure
+ */
+void ifxusb_dev_init_spd(ifxusb_core_if_t *_core_if)
+{
+ uint32_t val;
+ dcfg_data_t dcfg;
+
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ if (_core_if->params.speed == IFXUSB_PARAM_SPEED_FULL)
+ /* High speed PHY running at full speed */
+ val = 0x1;
+ else
+ /* High speed PHY running at high speed and full speed*/
+ val = 0x0;
+
+ IFX_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
+ dcfg.d32 = ifxusb_rreg(&_core_if->dev_global_regs->dcfg);
+ dcfg.b.devspd = val;
+ ifxusb_wreg(&_core_if->dev_global_regs->dcfg, dcfg.d32);
+}
+
+
+/*!
+ \brief This function enables the Device mode interrupts.
+ \param _core_if Pointer of core_if structure
+ */
+void ifxusb_dev_enable_interrupts(ifxusb_core_if_t *_core_if)
+{
+ gint_data_t intr_mask ={ .d32 = 0};
+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
+
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ IFX_DEBUGPL(DBG_CIL, "%s()\n", __func__);
+
+ /* Clear any pending OTG Interrupts */
+ ifxusb_wreg( &global_regs->gotgint, 0xFFFFFFFF);
+
+ /* Clear any pending interrupts */
+ ifxusb_wreg( &global_regs->gintsts, 0xFFFFFFFF);
+
+ /* Enable the interrupts in the GINTMSK.*/
+ intr_mask.b.modemismatch = 1;
+ intr_mask.b.conidstschng = 1;
+ intr_mask.b.wkupintr = 1;
+ intr_mask.b.disconnect = 1;
+ intr_mask.b.usbsuspend = 1;
+
+ intr_mask.b.usbreset = 1;
+ intr_mask.b.enumdone = 1;
+ intr_mask.b.inepintr = 1;
+ intr_mask.b.outepintr = 1;
+ intr_mask.b.erlysuspend = 1;
+ #ifndef __DED_FIFO__
+ #ifndef __DED_INTR__
+ intr_mask.b.epmismatch = 1;
+ #endif
+ #endif
+
+ ifxusb_mreg( &global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
+ IFX_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__, ifxusb_rreg( &global_regs->gintmsk));
+}
+
+/*!
+ \brief Gets the current USB frame number. This is the frame number from the last SOF packet.
+ \param _core_if Pointer of core_if structure
+ */
+uint32_t ifxusb_dev_get_frame_number(ifxusb_core_if_t *_core_if)
+{
+ dsts_data_t dsts;
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ dsts.d32 = ifxusb_rreg(&_core_if->dev_global_regs->dsts);
+ /* read current frame/microfreme number from DSTS register */
+ return dsts.b.soffn;
+}
+
+
+/*!
+ \brief Set the EP STALL.
+ */
+void ifxusb_dev_ep_set_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _is_in)
+{
+ depctl_data_t depctl;
+ volatile uint32_t *depctl_addr;
+
+ IFX_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _epno, (_is_in?"IN":"OUT"));
+
+ depctl_addr = (_is_in)? (&(_core_if->in_ep_regs [_epno]->diepctl)):
+ (&(_core_if->out_ep_regs[_epno]->doepctl));
+ depctl.d32 = ifxusb_rreg(depctl_addr);
+ depctl.b.stall = 1;
+
+ if (_is_in && depctl.b.epena)
+ depctl.b.epdis = 1;
+
+ ifxusb_wreg(depctl_addr, depctl.d32);
+ IFX_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",ifxusb_rreg(depctl_addr));
+ return;
+}
+
+/*!
+\brief Clear the EP STALL.
+ */
+void ifxusb_dev_ep_clear_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _ep_type, uint8_t _is_in)
+{
+ depctl_data_t depctl;
+ volatile uint32_t *depctl_addr;
+
+ IFX_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _epno, (_is_in?"IN":"OUT"));
+
+ depctl_addr = (_is_in)? (&(_core_if->in_ep_regs [_epno]->diepctl)):
+ (&(_core_if->out_ep_regs[_epno]->doepctl));
+
+ depctl.d32 = ifxusb_rreg(depctl_addr);
+ /* clear the stall bits */
+ depctl.b.stall = 0;
+
+ /*
+ * USB Spec 9.4.5: For endpoints using data toggle, regardless
+ * of whether an endpoint has the Halt feature set, a
+ * ClearFeature(ENDPOINT_HALT) request always results in the
+ * data toggle being reinitialized to DATA0.
+ */
+ if (_ep_type == IFXUSB_EP_TYPE_INTR || _ep_type == IFXUSB_EP_TYPE_BULK)
+ depctl.b.setd0pid = 1; /* DATA0 */
+
+ ifxusb_wreg(depctl_addr, depctl.d32);
+ IFX_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",ifxusb_rreg(depctl_addr));
+ return;
+}
+
+/*!
+ \brief This function initializes the IFXUSB controller registers for Device mode.
+ This function flushes the Tx and Rx FIFOs and it flushes any entries in the
+ request queues.
+ \param _core_if Pointer of core_if structure
+ \param _params parameters to be set
+ */
+void ifxusb_dev_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params)
+{
+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
+
+ gusbcfg_data_t usbcfg ={.d32 = 0};
+ gahbcfg_data_t ahbcfg ={.d32 = 0};
+ dcfg_data_t dcfg ={.d32 = 0};
+ grstctl_t resetctl ={.d32 = 0};
+ gotgctl_data_t gotgctl ={.d32 = 0};
+
+ uint32_t dir;
+ int i;
+
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ IFX_DEBUGPL(DBG_CILV, "%s(%p)\n",__func__,_core_if);
+
+ /* Copy Params */
+ _core_if->params.dma_burst_size = _params->dma_burst_size;
+ _core_if->params.speed = _params->speed;
+ if(_params->max_transfer_size < 2048 || _params->max_transfer_size > ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1) )
+ _core_if->params.max_transfer_size = ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1);
+ else
+ _core_if->params.max_transfer_size = _params->max_transfer_size;
+
+ if(_params->max_packet_count < 16 || _params->max_packet_count > ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1) )
+ _core_if->params.max_packet_count= ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
+ else
+ _core_if->params.max_packet_count= _params->max_packet_count;
+ _core_if->params.phy_utmi_width = _params->phy_utmi_width;
+ _core_if->params.turn_around_time_hs = _params->turn_around_time_hs;
+ _core_if->params.turn_around_time_fs = _params->turn_around_time_fs;
+ _core_if->params.timeout_cal_hs = _params->timeout_cal_hs;
+ _core_if->params.timeout_cal_fs = _params->timeout_cal_fs;
+
+ #ifdef __DED_FIFO__
+ _core_if->params.thr_ctl = _params->thr_ctl;
+ _core_if->params.tx_thr_length = _params->tx_thr_length;
+ _core_if->params.rx_thr_length = _params->rx_thr_length;
+ #endif
+
+ /* Reset the Controller */
+ do
+ {
+ while(ifxusb_core_soft_reset_d( _core_if ))
+ ifxusb_hard_reset_d(_core_if);
+ } while (ifxusb_is_host_mode(_core_if));
+
+ usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg);
+
+ usbcfg.b.ForceDevMode = 1;
+ usbcfg.b.ForceHstMode = 0;
+
+ usbcfg.b.term_sel_dl_pulse = 0;
+ ifxusb_wreg (&global_regs->gusbcfg, usbcfg.d32);
+
+ /* This programming sequence needs to happen in FS mode before any other
+ * programming occurs */
+ /* High speed PHY. */
+ if (!_core_if->phy_init_done)
+ {
+ _core_if->phy_init_done = 1;
+ /* HS PHY parameters. These parameters are preserved
+ * during soft reset so only program the first time. Do
+ * a soft reset immediately after setting phyif. */
+ usbcfg.b.ulpi_utmi_sel = 0; //UTMI+
+ usbcfg.b.phyif = ( _core_if->params.phy_utmi_width == 16)?1:0;
+ ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32);
+ /* Reset after setting the PHY parameters */
+ ifxusb_core_soft_reset_d( _core_if );
+ }
+
+ /* Program the GAHBCFG Register.*/
+ switch (_core_if->params.dma_burst_size)
+ {
+ case 0 :
+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_SINGLE;
+ break;
+ case 1 :
+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR;
+ break;
+ case 4 :
+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR4;
+ break;
+ case 8 :
+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR8;
+ break;
+ case 16:
+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR16;
+ break;
+ }
+ #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
+ _core_if->unaligned_mask=3;
+ #if defined(__UNALIGNED_BUF_BURST__)
+ switch (_core_if->params.dma_burst_size)
+ {
+ case 4 :
+ _core_if->unaligned_mask=15;
+ break;
+ case 8 :
+ _core_if->unaligned_mask=31;
+ break;
+ case 16:
+ _core_if->unaligned_mask=63;
+ break;
+ case 0 :
+ case 1 :
+ break;
+ }
+ #endif //defined(__UNALIGNED_BUF_BURST__)
+ #endif //defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
+ ahbcfg.b.dmaenable = 1;
+ ifxusb_wreg(&global_regs->gahbcfg, ahbcfg.d32);
+
+ /* Program the GUSBCFG register. */
+ usbcfg.d32 = ifxusb_rreg( &global_regs->gusbcfg );
+ usbcfg.b.hnpcap = 0;
+ usbcfg.b.srpcap = 0;
+ ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32);
+
+ {
+ dctl_data_t dctl = {.d32=0};
+ dctl.d32=ifxusb_rreg(&_core_if->dev_global_regs->dctl);
+ dctl.b.sftdiscon=1;
+ ifxusb_wreg(&_core_if->dev_global_regs->dctl,dctl.d32);
+ }
+
+ /* Restart the Phy Clock */
+ ifxusb_wreg(_core_if->pcgcctl, 0);
+
+ /* Device configuration register */
+ ifxusb_dev_init_spd(_core_if);
+ dcfg.d32 = ifxusb_rreg( &_core_if->dev_global_regs->dcfg);
+ dcfg.b.perfrint = IFXUSB_DCFG_FRAME_INTERVAL_80;
+ #if defined(__DED_FIFO__)
+ #if defined(__DESC_DMA__)
+ dcfg.b.descdma = 1;
+ #else
+ dcfg.b.descdma = 0;
+ #endif
+ #endif
+
+ ifxusb_wreg( &_core_if->dev_global_regs->dcfg, dcfg.d32 );
+
+ /* Configure data FIFO sizes */
+ _core_if->params.data_fifo_size = _core_if->hwcfg3.b.dfifo_depth;
+ _core_if->params.rx_fifo_size = ifxusb_rreg(&global_regs->grxfsiz);
+ IFX_DEBUGPL(DBG_CIL, "Initial: FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size);
+ IFX_DEBUGPL(DBG_CIL, " Rx FIFO Size=0x%06X\n", _core_if->params.rx_fifo_size);
+
+ _core_if->params.tx_fifo_size[0]= ifxusb_rreg(&global_regs->gnptxfsiz) >> 16;
+
+ #ifdef __DED_FIFO__
+ for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++)
+ _core_if->params.tx_fifo_size[i] =
+ ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i-1]) >> 16;
+ #else
+ for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
+ _core_if->params.tx_fifo_size[i+1] =
+ ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
+ #endif
+
+ #ifdef __DEBUG__
+ #ifdef __DED_FIFO__
+ for (i=0; i <= _core_if->hwcfg4.b.num_in_eps; i++)
+ IFX_DEBUGPL(DBG_CIL, " Tx[%02d] FIFO Size=0x%06X\n",i, _core_if->params.tx_fifo_size[i]);
+ #else
+ IFX_DEBUGPL(DBG_CIL, " NPTx FIFO Size=0x%06X\n", _core_if->params.tx_fifo_size[0]);
+ for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
+ IFX_DEBUGPL(DBG_CIL, " PTx[%02d] FIFO Size=0x%06X\n",i, _core_if->params.tx_fifo_size[i+1]);
+ #endif
+ #endif
+
+ {
+ fifosize_data_t txfifosize;
+ if(_params->data_fifo_size >=0 && _params->data_fifo_size < _core_if->params.data_fifo_size)
+ _core_if->params.data_fifo_size = _params->data_fifo_size;
+
+
+ if(_params->rx_fifo_size >=0 && _params->rx_fifo_size < _core_if->params.rx_fifo_size)
+ _core_if->params.rx_fifo_size = _params->rx_fifo_size;
+ if(_core_if->params.data_fifo_size < _core_if->params.rx_fifo_size)
+ _core_if->params.rx_fifo_size = _core_if->params.data_fifo_size;
+ ifxusb_wreg( &global_regs->grxfsiz, _core_if->params.rx_fifo_size);
+
+ for (i=0; i < MAX_EPS_CHANNELS; i++)
+ if(_params->tx_fifo_size[i] >=0 && _params->tx_fifo_size[i] < _core_if->params.tx_fifo_size[i])
+ _core_if->params.tx_fifo_size[i] = _params->tx_fifo_size[i];
+
+ txfifosize.b.startaddr = _core_if->params.rx_fifo_size;
+ #ifdef __DED_FIFO__
+ if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[0] > _core_if->params.data_fifo_size)
+ _core_if->params.tx_fifo_size[0]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
+ txfifosize.b.depth=_core_if->params.tx_fifo_size[0];
+ ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32);
+ txfifosize.b.startaddr += _core_if->params.tx_fifo_size[0];
+ for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++)
+ {
+ if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[i] > _core_if->params.data_fifo_size)
+ _core_if->params.tx_fifo_size[i]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
+ txfifosize.b.depth=_core_if->params.tx_fifo_size[i];
+ ifxusb_wreg( &global_regs->dptxfsiz_dieptxf[i-1], txfifosize.d32);
+ txfifosize.b.startaddr += _core_if->params.tx_fifo_size[i];
+ }
+ #else
+ if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[0] > _core_if->params.data_fifo_size)
+ _core_if->params.tx_fifo_size[0]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
+ txfifosize.b.depth=_core_if->params.tx_fifo_size[0];
+ ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32);
+ txfifosize.b.startaddr += _core_if->params.tx_fifo_size[0];
+ for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
+ {
+ if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[i+1] > _core_if->params.data_fifo_size)
+ _core_if->params.tx_fifo_size[i+1]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
+ //txfifosize.b.depth=_core_if->params.tx_fifo_size[i+1];
+ ifxusb_wreg( &global_regs->dptxfsiz_dieptxf[i], txfifosize.d32);
+ txfifosize.b.startaddr += _core_if->params.tx_fifo_size[i+1];
+ }
+ #endif
+ }
+
+ #ifdef __DEBUG__
+ {
+ fifosize_data_t fifosize;
+ IFX_DEBUGPL(DBG_CIL, "Result : FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size);
+
+ IFX_DEBUGPL(DBG_CIL, " Rx FIFO =0x%06X Sz=0x%06X\n", 0,ifxusb_rreg(&global_regs->grxfsiz));
+ #ifdef __DED_FIFO__
+ fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz);
+ IFX_DEBUGPL(DBG_CIL, " Tx[00] FIFO =0x%06X Sz=0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
+ for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++)
+ {
+ fifosize.d32=ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i-1]);
+ IFX_DEBUGPL(DBG_CIL, " Tx[%02d] FIFO 0x%06X Sz=0x%06X\n",i, fifosize.b.startaddr,fifosize.b.depth);
+ }
+ #else
+ fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz);
+ IFX_DEBUGPL(DBG_CIL, " NPTx FIFO =0x%06X Sz=0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
+ for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
+ {
+ fifosize.d32=ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i]);
+ IFX_DEBUGPL(DBG_CIL, " PTx[%02d] FIFO 0x%06X Sz=0x%06X\n",i, fifosize.b.startaddr,fifosize.b.depth);
+ }
+ #endif
+ }
+ #endif
+
+ /* Clear Host Set HNP Enable in the OTG Control Register */
+ gotgctl.b.hstsethnpen = 1;
+ ifxusb_mreg( &global_regs->gotgctl, gotgctl.d32, 0);
+
+ /* Flush the FIFOs */
+ ifxusb_flush_tx_fifo_d(_core_if, 0x10); /* all Tx FIFOs */
+ ifxusb_flush_rx_fifo_d(_core_if);
+
+ /* Flush the Learning Queue. */
+ resetctl.b.intknqflsh = 1;
+ ifxusb_wreg( &global_regs->grstctl, resetctl.d32);
+
+ /* Clear all pending Device Interrupts */
+ ifxusb_wreg( &_core_if->dev_global_regs->diepmsk , 0 );
+ ifxusb_wreg( &_core_if->dev_global_regs->doepmsk , 0 );
+ ifxusb_wreg( &_core_if->dev_global_regs->daint , 0xFFFFFFFF );
+ ifxusb_wreg( &_core_if->dev_global_regs->daintmsk, 0 );
+
+ dir=_core_if->hwcfg1.d32;
+ for (i=0; i <= _core_if->hwcfg2.b.num_dev_ep ; i++,dir>>=2)
+ {
+ depctl_data_t depctl;
+ if((dir&0x03)==0 || (dir&0x03) ==1)
+ {
+ depctl.d32 = ifxusb_rreg(&_core_if->in_ep_regs[i]->diepctl);
+ if (depctl.b.epena)
+ {
+ depctl.d32 = 0;
+ depctl.b.epdis = 1;
+ depctl.b.snak = 1;
+ }
+ else
+ depctl.d32 = 0;
+ ifxusb_wreg( &_core_if->in_ep_regs[i]->diepctl, depctl.d32);
+ #ifndef __DESC_DMA__
+ ifxusb_wreg( &_core_if->in_ep_regs[i]->dieptsiz, 0);
+ #endif
+ ifxusb_wreg( &_core_if->in_ep_regs[i]->diepdma, 0);
+ ifxusb_wreg( &_core_if->in_ep_regs[i]->diepint, 0xFF);
+ }
+
+ if((dir&0x03)==0 || (dir&0x03) ==2)
+ {
+ depctl.d32 = ifxusb_rreg(&_core_if->out_ep_regs[i]->doepctl);
+ if (depctl.b.epena)
+ {
+ depctl.d32 = 0;
+ depctl.b.epdis = 1;
+ depctl.b.snak = 1;
+ }
+ else
+ depctl.d32 = 0;
+ ifxusb_wreg( &_core_if->out_ep_regs[i]->doepctl, depctl.d32);
+ #ifndef __DESC_DMA__
+ ifxusb_wreg( &_core_if->out_ep_regs[i]->doeptsiz, 0);
+ #endif
+ ifxusb_wreg( &_core_if->out_ep_regs[i]->doepdma, 0);
+ ifxusb_wreg( &_core_if->out_ep_regs[i]->doepint, 0xFF);
+ }
+ }
+}
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif_h.c b/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif_h.c
new file mode 100644
index 0000000000..e9e67bf43c
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif_h.c
@@ -0,0 +1,1599 @@
+/*****************************************************************************
+ ** FILE NAME : ifxusb_cif_h.c
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** AUTHOR : Chen, Howard
+ ** DESCRIPTION : The Core Interface provides basic services for accessing and
+ ** managing the IFX USB hardware. These services are used by the
+ ** Host Controller Driver only.
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*!
+ \file ifxusb_cif_h.c
+ \ingroup IFXUSB_DRIVER_V3
+ \brief This file contains the interface to the IFX USB Core.
+*/
+#include <linux/version.h>
+#include "ifxusb_version.h"
+
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
+
+#ifdef __DEBUG__
+ #include <linux/jiffies.h>
+#endif
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+
+#include "ifxusb_plat.h"
+#include "ifxusb_regs.h"
+#include "ifxusb_cif.h"
+
+#include "ifxhcd.h"
+
+#if !defined(__UEIP__)
+ #undef __USING_LED_AS_GPIO__
+#endif
+
+
+/*!
+ \brief This function enables the Host mode interrupts.
+ \param _core_if Pointer of core_if structure
+ */
+void ifxusb_host_enable_interrupts(ifxusb_core_if_t *_core_if)
+{
+ gint_data_t intr_mask ={ .d32 = 0};
+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
+
+ IFX_DEBUGPL(DBG_CIL, "%s()\n", __func__);
+
+ /* Clear any pending OTG Interrupts */
+ ifxusb_wreg( &global_regs->gotgint, 0xFFFFFFFF);
+
+ /* Clear any pending interrupts */
+ ifxusb_wreg( &global_regs->gintsts, 0xFFFFFFFF);
+
+ /* Enable the interrupts in the GINTMSK.*/
+
+ /* Common interrupts */
+ intr_mask.b.modemismatch = 1;
+ intr_mask.b.conidstschng = 1;
+ intr_mask.b.wkupintr = 1;
+ intr_mask.b.disconnect = 1;
+ intr_mask.b.usbsuspend = 1;
+
+ /* Host interrupts */
+ intr_mask.b.sofintr = 1;
+ intr_mask.b.portintr = 1;
+ intr_mask.b.hcintr = 1;
+
+ ifxusb_mreg( &global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
+ IFX_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__, ifxusb_rreg( &global_regs->gintmsk));
+}
+
+/*!
+ \brief This function disables the Host mode interrupts.
+ \param _core_if Pointer of core_if structure
+ */
+void ifxusb_host_disable_interrupts(ifxusb_core_if_t *_core_if)
+{
+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
+
+ IFX_DEBUGPL(DBG_CILV, "%s()\n", __func__);
+
+ #if 1
+ ifxusb_wreg( &global_regs->gintmsk, 0);
+ #else
+ /* Common interrupts */
+ {
+ gint_data_t intr_mask ={.d32 = 0};
+ intr_mask.b.modemismatch = 1;
+ intr_mask.b.rxstsqlvl = 1;
+ intr_mask.b.conidstschng = 1;
+ intr_mask.b.wkupintr = 1;
+ intr_mask.b.disconnect = 1;
+ intr_mask.b.usbsuspend = 1;
+
+ /* Host interrupts */
+ intr_mask.b.sofintr = 1;
+ intr_mask.b.portintr = 1;
+ intr_mask.b.hcintr = 1;
+ intr_mask.b.ptxfempty = 1;
+ intr_mask.b.nptxfempty = 1;
+ ifxusb_mreg(&global_regs->gintmsk, intr_mask.d32, 0);
+ }
+ #endif
+}
+
+/*!
+ \brief This function initializes the IFXUSB controller registers for Host mode.
+ This function flushes the Tx and Rx FIFOs and it flushes any entries in the
+ request queues.
+ \param _core_if Pointer of core_if structure
+ \param _params parameters to be set
+ */
+void ifxusb_host_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params)
+{
+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
+
+ gusbcfg_data_t usbcfg ={.d32 = 0};
+ gahbcfg_data_t ahbcfg ={.d32 = 0};
+ gotgctl_data_t gotgctl ={.d32 = 0};
+
+ int i;
+
+ IFX_DEBUGPL(DBG_CILV, "%s(%p)\n",__func__,_core_if);
+
+ /* Copy Params */
+
+ _core_if->params.dma_burst_size = _params->dma_burst_size;
+ _core_if->params.speed = _params->speed;
+ if(_params->max_transfer_size < 2048 || _params->max_transfer_size > ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1) )
+ _core_if->params.max_transfer_size = ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1);
+ else
+ _core_if->params.max_transfer_size = _params->max_transfer_size;
+
+ if(_params->max_packet_count < 16 || _params->max_packet_count > ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1) )
+ _core_if->params.max_packet_count= ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
+ else
+ _core_if->params.max_packet_count= _params->max_packet_count;
+ _core_if->params.phy_utmi_width = _params->phy_utmi_width;
+ _core_if->params.turn_around_time_hs = _params->turn_around_time_hs;
+ _core_if->params.turn_around_time_fs = _params->turn_around_time_fs;
+ _core_if->params.timeout_cal_hs = _params->timeout_cal_hs;
+ _core_if->params.timeout_cal_fs = _params->timeout_cal_fs;
+ usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg);
+// usbcfg.b.ulpi_ext_vbus_drv = 1;
+ usbcfg.b.term_sel_dl_pulse = 0;
+ usbcfg.b.ForceDevMode = 0;
+ usbcfg.b.ForceHstMode = 1;
+ ifxusb_wreg (&global_regs->gusbcfg, usbcfg.d32);
+ /* Reset the Controller */
+ do
+ {
+ while(ifxusb_core_soft_reset_h( _core_if ))
+ ifxusb_hard_reset_h(_core_if);
+ } while (ifxusb_is_device_mode(_core_if));
+
+ usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg);
+// usbcfg.b.ulpi_ext_vbus_drv = 1;
+ usbcfg.b.term_sel_dl_pulse = 0;
+ ifxusb_wreg (&global_regs->gusbcfg, usbcfg.d32);
+
+ /* This programming sequence needs to happen in FS mode before any other
+ * programming occurs */
+ /* High speed PHY. */
+ if (!_core_if->phy_init_done)
+ {
+ _core_if->phy_init_done = 1;
+ /* HS PHY parameters. These parameters are preserved
+ * during soft reset so only program the first time. Do
+ * a soft reset immediately after setting phyif. */
+ usbcfg.b.ulpi_utmi_sel = 0; //UTMI+
+ usbcfg.b.phyif = ( _core_if->params.phy_utmi_width == 16)?1:0;
+ ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32);
+ /* Reset after setting the PHY parameters */
+ ifxusb_core_soft_reset_h( _core_if );
+ }
+
+ usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg);
+// usbcfg.b.ulpi_fsls = 0;
+// usbcfg.b.ulpi_clk_sus_m = 0;
+ usbcfg.b.term_sel_dl_pulse = 0;
+ usbcfg.b.ForceDevMode = 0;
+ usbcfg.b.ForceHstMode = 1;
+ ifxusb_wreg(&global_regs->gusbcfg, usbcfg.d32);
+
+ /* Program the GAHBCFG Register.*/
+ switch (_core_if->params.dma_burst_size)
+ {
+ case 0 :
+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_SINGLE;
+ break;
+ case 1 :
+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR;
+ break;
+ case 4 :
+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR4;
+ break;
+ case 8 :
+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR8;
+ break;
+ case 16:
+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR16;
+ break;
+ }
+ #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
+ _core_if->unaligned_mask=3;
+ #if defined(__UNALIGNED_BUF_BURST__)
+ switch(_core_if->params.dma_burst_size)
+ {
+ case 4 :
+ _core_if->unaligned_mask=15;
+ break;
+ case 8 :
+ _core_if->unaligned_mask=31;
+ break;
+ case 16:
+ _core_if->unaligned_mask=63;
+ break;
+ case 0 :
+ case 1 :
+ break;
+ default:
+ break;
+ }
+ #endif //defined(__UNALIGNED_BUF_BURST__)
+ #endif //defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
+ ahbcfg.b.dmaenable = 1;
+ ifxusb_wreg(&global_regs->gahbcfg, ahbcfg.d32);
+
+ /* Program the GUSBCFG register. */
+ usbcfg.d32 = ifxusb_rreg( &global_regs->gusbcfg );
+ usbcfg.b.hnpcap = 0;
+ usbcfg.b.srpcap = 0;
+ ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32);
+
+ /* Restart the Phy Clock */
+ ifxusb_wreg(_core_if->pcgcctl, 0);
+
+ /* Initialize Host Configuration Register */
+ {
+ hcfg_data_t hcfg;
+ hcfg.d32 = ifxusb_rreg(&_core_if->host_global_regs->hcfg);
+ hcfg.b.fslspclksel = IFXUSB_HCFG_30_60_MHZ;
+ if (_params->speed == IFXUSB_PARAM_SPEED_FULL)
+ hcfg.b.fslssupp = 1;
+ ifxusb_wreg(&_core_if->host_global_regs->hcfg, hcfg.d32);
+ }
+
+ _core_if->params.host_channels=(_core_if->hwcfg2.b.num_host_chan + 1);
+
+ if(_params->host_channels>0 && _params->host_channels < _core_if->params.host_channels)
+ _core_if->params.host_channels = _params->host_channels;
+
+ /* Configure data FIFO sizes */
+ _core_if->params.data_fifo_size = _core_if->hwcfg3.b.dfifo_depth;
+ _core_if->params.rx_fifo_size = ifxusb_rreg(&global_regs->grxfsiz);
+ _core_if->params.nperio_tx_fifo_size= ifxusb_rreg(&global_regs->gnptxfsiz) >> 16;
+ _core_if->params.perio_tx_fifo_size = ifxusb_rreg(&global_regs->hptxfsiz) >> 16;
+ IFX_DEBUGPL(DBG_CIL, "Initial: FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size);
+ IFX_DEBUGPL(DBG_CIL, " Rx FIFO Size=0x%06X\n", _core_if->params.rx_fifo_size);
+ IFX_DEBUGPL(DBG_CIL, " NPTx FIFO Size=0x%06X\n", _core_if->params.nperio_tx_fifo_size);
+ IFX_DEBUGPL(DBG_CIL, " PTx FIFO Size=0x%06X\n", _core_if->params.perio_tx_fifo_size);
+
+ {
+ fifosize_data_t txfifosize;
+ if(_params->data_fifo_size >=0 && _params->data_fifo_size < _core_if->params.data_fifo_size)
+ _core_if->params.data_fifo_size = _params->data_fifo_size;
+
+ if( _params->rx_fifo_size >= 0 && _params->rx_fifo_size < _core_if->params.rx_fifo_size)
+ _core_if->params.rx_fifo_size = _params->rx_fifo_size;
+ if( _params->nperio_tx_fifo_size >=0 && _params->nperio_tx_fifo_size < _core_if->params.nperio_tx_fifo_size)
+ _core_if->params.nperio_tx_fifo_size = _params->nperio_tx_fifo_size;
+ if( _params->perio_tx_fifo_size >=0 && _params->perio_tx_fifo_size < _core_if->params.perio_tx_fifo_size)
+ _core_if->params.perio_tx_fifo_size = _params->perio_tx_fifo_size;
+
+ if(_core_if->params.data_fifo_size < _core_if->params.rx_fifo_size)
+ _core_if->params.rx_fifo_size = _core_if->params.data_fifo_size;
+ ifxusb_wreg( &global_regs->grxfsiz, _core_if->params.rx_fifo_size);
+ txfifosize.b.startaddr = _core_if->params.rx_fifo_size;
+
+ if(txfifosize.b.startaddr + _core_if->params.nperio_tx_fifo_size > _core_if->params.data_fifo_size)
+ _core_if->params.nperio_tx_fifo_size = _core_if->params.data_fifo_size - txfifosize.b.startaddr;
+ txfifosize.b.depth=_core_if->params.nperio_tx_fifo_size;
+ ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32);
+ txfifosize.b.startaddr += _core_if->params.nperio_tx_fifo_size;
+
+ if(txfifosize.b.startaddr + _core_if->params.perio_tx_fifo_size > _core_if->params.data_fifo_size)
+ _core_if->params.perio_tx_fifo_size = _core_if->params.data_fifo_size - txfifosize.b.startaddr;
+ txfifosize.b.depth=_core_if->params.perio_tx_fifo_size;
+ ifxusb_wreg( &global_regs->hptxfsiz, txfifosize.d32);
+ txfifosize.b.startaddr += _core_if->params.perio_tx_fifo_size;
+ }
+
+ #ifdef __DEBUG__
+ {
+ fifosize_data_t fifosize;
+ IFX_DEBUGPL(DBG_CIL, "Result : FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size);
+
+ fifosize.d32=ifxusb_rreg(&global_regs->grxfsiz);
+ IFX_DEBUGPL(DBG_CIL, " Rx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
+ fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz);
+ IFX_DEBUGPL(DBG_CIL, " NPTx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
+ fifosize.d32=ifxusb_rreg(&global_regs->hptxfsiz);
+ IFX_DEBUGPL(DBG_CIL, " PTx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
+ }
+ #endif
+
+ /* Clear Host Set HNP Enable in the OTG Control Register */
+ gotgctl.b.hstsethnpen = 1;
+ ifxusb_mreg( &global_regs->gotgctl, gotgctl.d32, 0);
+
+ /* Flush the FIFOs */
+ ifxusb_flush_tx_fifo_h(_core_if, 0x10); /* all Tx FIFOs */
+ ifxusb_flush_rx_fifo_h(_core_if);
+
+ for (i = 0; i < _core_if->hwcfg2.b.num_host_chan + 1; i++)
+ {
+ hcchar_data_t hcchar;
+ hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar);
+ hcchar.b.chen = 0;
+ hcchar.b.chdis = 1;
+ hcchar.b.epdir = 0;
+ ifxusb_wreg(&_core_if->hc_regs[i]->hcchar, hcchar.d32);
+ }
+ /* Halt all channels to put them into a known state. */
+ for (i = 0; i < _core_if->hwcfg2.b.num_host_chan + 1; i++)
+ {
+ hcchar_data_t hcchar;
+ int count = 0;
+
+ hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar);
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 1;
+ hcchar.b.epdir = 0;
+ ifxusb_wreg(&_core_if->hc_regs[i]->hcchar, hcchar.d32);
+
+ IFX_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
+ do{
+ hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar);
+ if (++count > 1000)
+ {
+ IFX_ERROR("%s: Unable to clear halt on channel %d\n", __func__, i);
+ break;
+ }
+ } while (hcchar.b.chen);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if defined(__UEIP__)
+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
+ int ifxusb_vbus_status =-1;
+ #endif
+
+ #if defined(IFX_GPIO_USB_VBUS1) || defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
+ int ifxusb_vbus1_status =-1;
+ #endif
+
+ #if defined(IFX_GPIO_USB_VBUS2) || defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
+ int ifxusb_vbus2_status =-1;
+ #endif
+
+ #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
+ static void *g_usb_vbus_trigger = NULL;
+ #endif
+ #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
+ static void *g_usb_vbus1_trigger = NULL;
+ #endif
+ #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
+ static void *g_usb_vbus2_trigger = NULL;
+ #endif
+
+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
+ int ifxusb_vbus_gpio_inited=0;
+ #endif
+
+#else //defined(__UEIP__)
+ int ifxusb_vbus_status =-1;
+ int ifxusb_vbus1_status =-1;
+ int ifxusb_vbus2_status =-1;
+ int ifxusb_vbus_gpio_inited=0;
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*!
+ \fn void ifxusb_vbus_init(ifxusb_core_if_t *_core_if)
+ \brief This function init the VBUS control.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+void ifxusb_vbus_init(ifxusb_core_if_t *_core_if)
+{
+ #if defined(__UEIP__)
+ #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
+ if ( !g_usb_vbus_trigger )
+ {
+ ifx_led_trigger_register("USB_VBUS", &g_usb_vbus_trigger);
+ if ( g_usb_vbus_trigger != NULL )
+ {
+ struct ifx_led_trigger_attrib attrib = {0};
+ attrib.delay_on = 0;
+ attrib.delay_off = 0;
+ attrib.timeout = 0;
+ attrib.def_value = 0;
+ attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE;
+ IFX_DEBUGP("Reg USB power!!\n");
+ ifx_led_trigger_set_attrib(g_usb_vbus_trigger, &attrib);
+ ifxusb_vbus_status =0;
+ }
+ }
+ #endif
+ #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
+ if(_core_if->core_no==0 && !g_usb_vbus1_trigger )
+ {
+ ifx_led_trigger_register("USB_VBUS1", &g_usb_vbus1_trigger);
+ if ( g_usb_vbus1_trigger != NULL )
+ {
+ struct ifx_led_trigger_attrib attrib = {0};
+ attrib.delay_on = 0;
+ attrib.delay_off = 0;
+ attrib.timeout = 0;
+ attrib.def_value = 0;
+ attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE;
+ IFX_DEBUGP("Reg USB1 power!!\n");
+ ifx_led_trigger_set_attrib(g_usb_vbus1_trigger, &attrib);
+ ifxusb_vbus1_status =0;
+ }
+ }
+ #endif
+ #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
+ if(_core_if->core_no==1 && !g_usb_vbus2_trigger )
+ {
+ ifx_led_trigger_register("USB_VBUS2", &g_usb_vbus2_trigger);
+ if ( g_usb_vbus2_trigger != NULL )
+ {
+ struct ifx_led_trigger_attrib attrib = {0};
+ attrib.delay_on = 0;
+ attrib.delay_off = 0;
+ attrib.timeout = 0;
+ attrib.def_value = 0;
+ attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE;
+ IFX_DEBUGP("Reg USB2 power!!\n");
+ ifx_led_trigger_set_attrib(g_usb_vbus2_trigger, &attrib);
+ ifxusb_vbus2_status =0;
+ }
+ }
+ #endif
+
+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
+ if(!ifxusb_vbus_gpio_inited)
+ {
+ if(!ifx_gpio_register(IFX_GPIO_MODULE_USB))
+ {
+ IFX_DEBUGP("Register USB VBus through GPIO OK!!\n");
+ #ifdef IFX_GPIO_USB_VBUS
+ ifxusb_vbus_status =0;
+ #endif //IFX_GPIO_USB_VBUS
+ #ifdef IFX_GPIO_USB_VBUS1
+ ifxusb_vbus1_status=0;
+ #endif //IFX_GPIO_USB_VBUS1
+ #ifdef IFX_GPIO_USB_VBUS2
+ ifxusb_vbus2_status=0;
+ #endif //IFX_GPIO_USB_VBUS2
+ }
+ else
+ IFX_PRINT("Register USB VBus Failed!!\n");
+ ifxusb_vbus_gpio_inited=1;
+ }
+ #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
+ #endif //defined(__UEIP__)
+}
+
+/*!
+ \fn void ifxusb_vbus_free(ifxusb_core_if_t *_core_if)
+ \brief This function free the VBUS control.
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+void ifxusb_vbus_free(ifxusb_core_if_t *_core_if)
+{
+ #if defined(__UEIP__)
+ #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
+ if ( g_usb_vbus_trigger )
+ {
+ ifx_led_trigger_deregister(g_usb_vbus_trigger);
+ g_usb_vbus_trigger = NULL;
+ ifxusb_vbus_status =-1;
+ }
+ #endif
+ #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
+ if(_core_if->core_no==0 && g_usb_vbus1_trigger )
+ {
+ ifx_led_trigger_deregister(g_usb_vbus1_trigger);
+ g_usb_vbus1_trigger = NULL;
+ ifxusb_vbus1_status =-1;
+ }
+ #endif
+ #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
+ if(_core_if->core_no==1 && g_usb_vbus2_trigger )
+ {
+ ifx_led_trigger_deregister(g_usb_vbus2_trigger);
+ g_usb_vbus2_trigger = NULL;
+ ifxusb_vbus2_status =-1;
+ }
+ #endif
+
+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
+ if(ifxusb_vbus_gpio_inited)
+ {
+ ifx_gpio_deregister(IFX_GPIO_MODULE_USB);
+ #ifdef IFX_GPIO_USB_VBUS
+ ifxusb_vbus_status =-1;
+ #endif //IFX_GPIO_USB_VBUS
+ #ifdef IFX_GPIO_USB_VBUS1
+ ifxusb_vbus1_status=-1;
+ #endif //IFX_GPIO_USB_VBUS1
+ #ifdef IFX_GPIO_USB_VBUS2
+ ifxusb_vbus2_status=-1;
+ #endif //IFX_GPIO_USB_VBUS2
+ ifxusb_vbus_gpio_inited=0;
+ }
+ #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
+ #endif //defined(__UEIP__)
+}
+
+
+#if defined(__DO_OC_INT__)
+
+#define OC_Timer_Stable 3
+#define OC_Timer_Sleep 200
+#define OC_Timer_Max 3
+
+
+ #if defined(__IS_AR10__)
+ #if defined(__IS_DUAL__)
+ unsigned int oc1_int_installed=0;
+ unsigned int oc2_int_installed=0;
+ unsigned int oc1_int_count=0;
+ unsigned int oc2_int_count=0;
+ extern ifxhcd_hcd_t *oc1_int_id;
+ extern ifxhcd_hcd_t *oc2_int_id;
+
+ /*!
+ \brief Handles host mode Over Current Interrupt
+ */
+ struct timer_list oc1_retry_timer;
+ struct timer_list oc2_retry_timer;
+
+ void oc_retry_timer_func(unsigned long arg)
+ {
+ if(arg==1)
+ {
+ if(oc1_int_installed==0) //not installed
+ {
+ }
+ else if(oc1_int_installed==1) //disabled
+ {
+ }
+ else if(oc1_int_installed==2) //stablizing
+ {
+ oc1_int_installed=4;
+ oc1_int_count=0;
+ }
+ else if(oc1_int_installed==3) // sleeping
+ {
+ mod_timer(&oc1_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ oc1_int_installed=2;
+ enable_irq(IFXUSB1_OC_IRQ);
+ }
+ else if(oc1_int_installed==4) //
+ {
+ oc1_int_count=0;
+ }
+ else if(oc1_int_installed==5) // Stable sleeping
+ {
+ mod_timer(&oc1_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ oc1_int_installed=4;
+ enable_irq(IFXUSB1_OC_IRQ);
+ }
+ else
+ {
+ }
+ }
+ else
+ {
+ if(oc2_int_installed==0) //not installed
+ {
+ }
+ else if(oc2_int_installed==1) //disabled
+ {
+ }
+ else if(oc2_int_installed==2) //stablizing
+ {
+ oc2_int_installed=4;
+ oc2_int_count=0;
+ }
+ else if(oc2_int_installed==3) // sleeping
+ {
+ mod_timer(&oc2_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ oc2_int_installed=2;
+ enable_irq(IFXUSB2_OC_IRQ);
+ }
+ else if(oc2_int_installed==4) //
+ {
+ oc2_int_count=0;
+ }
+ else if(oc2_int_installed==5) // Stable sleeping
+ {
+ mod_timer(&oc2_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ oc2_int_installed=4;
+ enable_irq(IFXUSB2_OC_IRQ);
+ }
+ else
+ {
+ }
+ }
+ }
+
+ irqreturn_t ifxhcd_oc_irq(int _irq , void *_dev)
+ {
+ //ifxhcd_hcd_t *ifxhcd= _dev;
+ int32_t retval=1;
+ if(_irq==IFXUSB1_OC_IRQ)
+ {
+ if(oc1_int_installed==0) //not installed
+ {
+ }
+ else if(oc1_int_installed==1) //disabled
+ {
+ }
+ else if(oc1_int_installed==2) //stablizing
+ {
+ disable_irq_nosync(IFXUSB1_OC_IRQ);
+ mod_timer(&oc1_retry_timer,jiffies + HZ/OC_Timer_Sleep);
+ oc1_int_installed=3;
+ }
+ else if(oc1_int_installed==3) // sleeping
+ {
+ }
+ else if(oc1_int_installed==4) //
+ {
+ oc1_int_count++;
+ if(oc1_int_count>=OC_Timer_Max)
+ {
+ IFX_DEBUGP("OC INTERRUPT port #1\n");
+ oc1_int_id->flags.b.port_over_current_change = 1;
+ ifxusb_vbus_off(&oc1_int_id->core_if);
+ IFX_DEBUGP("Turning off port #1\n");
+ }
+ else
+ {
+ disable_irq_nosync(IFXUSB1_OC_IRQ);
+ mod_timer(&oc1_retry_timer,jiffies + HZ/OC_Timer_Sleep);
+ oc1_int_installed=5;
+ }
+ }
+ else if(oc1_int_installed==5) // Stable sleeping
+ {
+ }
+ }
+ else
+ {
+ if(oc2_int_installed==0) //not installed
+ {
+ }
+ else if(oc2_int_installed==1) //disabled
+ {
+ }
+ else if(oc2_int_installed==2) //stablizing
+ {
+ disable_irq_nosync(IFXUSB2_OC_IRQ);
+ mod_timer(&oc2_retry_timer,jiffies + HZ/OC_Timer_Sleep);
+ oc2_int_installed=3;
+ }
+ else if(oc2_int_installed==3) // sleeping
+ {
+ }
+ else if(oc2_int_installed==4) //
+ {
+ oc2_int_count++;
+ if(oc2_int_count>=OC_Timer_Max)
+ {
+ IFX_DEBUGP("OC INTERRUPT port #2\n");
+ oc2_int_id->flags.b.port_over_current_change = 1;
+ ifxusb_vbus_off(&oc2_int_id->core_if);
+ IFX_DEBUGP("Turning off port #2\n");
+ }
+ else
+ {
+ disable_irq_nosync(IFXUSB2_OC_IRQ);
+ mod_timer(&oc2_retry_timer,jiffies + HZ/OC_Timer_Sleep);
+ oc2_int_installed=5;
+ }
+ }
+ else if(oc2_int_installed==5) // Stable sleeping
+ {
+ }
+ }
+ return IRQ_RETVAL(retval);
+ }
+
+ void ifxusb_oc_int_on(int port)
+ {
+ if(port==1)
+ IFX_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for port #1 irq%d\n", IFXUSB1_OC_IRQ);
+ else
+ IFX_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for port #2 irq%d\n", IFXUSB2_OC_IRQ);
+ if((port==1&&oc1_int_id) || (port==2&&oc2_int_id)
+ {
+ if((port==1&&oc1_int_installed==0)||(port==2&&oc2_int_installed==0))
+ {
+ if(port==1)
+ {
+ oc1_int_installed=2;
+ init_timer(&oc1_retry_timer);
+ oc1_retry_timer.function = oc_retry_timer_func;
+ oc1_retry_timer.data=1;
+ if(request_irq((unsigned int)IFXUSB1_OC_IRQ, &ifxhcd_oc_irq,
+ IRQF_TRIGGER_NONE
+ // | IRQF_TRIGGER_RISING
+ // | IRQF_TRIGGER_FALLING
+ // | IRQF_TRIGGER_HIGH
+ // | IRQF_TRIGGER_LOW
+ // | IRQF_TRIGGER_PROBE
+ | IRQF_DISABLED
+ // | IRQF_SAMPLE_RANDOM
+ // | IRQF_SHARED
+ | IRQF_PROBE_SHARED
+ // | IRQF_TIMER
+ // | IRQF_PERCPU
+ // | IRQF_NOBALANCING
+ // | IRQF_IRQPOLL
+ // | IRQF_ONESHOT
+ ,
+ "ifxusb1_oc", (void *)oc1_int_id))
+ oc1_int_installed=0;
+ else
+ mod_timer(&oc1_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ }
+ else
+ {
+ oc2_int_installed=2;
+ init_timer(&oc2_retry_timer);
+ oc2_retry_timer.function = oc_retry_timer_func;
+ oc2_retry_timer.data=2;
+ if(request_irq((unsigned int)IFXUSB2_OC_IRQ, &ifxhcd_oc_irq,
+ IRQF_TRIGGER_NONE
+ // | IRQF_TRIGGER_RISING
+ // | IRQF_TRIGGER_FALLING
+ // | IRQF_TRIGGER_HIGH
+ // | IRQF_TRIGGER_LOW
+ // | IRQF_TRIGGER_PROBE
+ | IRQF_DISABLED
+ // | IRQF_SAMPLE_RANDOM
+ // | IRQF_SHARED
+ | IRQF_PROBE_SHARED
+ // | IRQF_TIMER
+ // | IRQF_PERCPU
+ // | IRQF_NOBALANCING
+ // | IRQF_IRQPOLL
+ // | IRQF_ONESHOT
+ ,
+ "ifxusb2_oc", (void *)oc2_int_id))
+ oc2_int_installed=0;
+ else
+ mod_timer(&oc2_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ }
+ /* Poll the event ring */
+ }
+ else if(port==1 && oc1_int_installed!=2 && oc1_int_installed!=4 )
+ {
+ oc1_int_installed=2;
+ enable_irq(IFXUSB1_OC_IRQ);
+ mod_timer(&oc1_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ }
+ else if(port==2 && oc2_int_installed!=2 && oc2_int_installed!=4 )
+ {
+ oc2_int_installed=2;
+ enable_irq(IFXUSB2_OC_IRQ);
+ mod_timer(&oc2_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ }
+ }
+ }
+
+ void ifxusb_oc_int_off(int port)
+ {
+ if(port==1)
+ {
+ disable_irq_nosync(IFXUSB1_OC_IRQ);
+ if(oc1_int_installed)
+ oc1_int_installed=1;
+ }
+ else
+ {
+ disable_irq_nosync(IFXUSB2_OC_IRQ);
+ if(oc2_int_installed)
+ oc2_int_installed=1;
+ }
+ }
+
+
+ void ifxusb_oc_int_free(int port)
+ {
+ if(port==1)
+ {
+ del_timer(&oc1_retry_timer);
+ disable_irq_nosync(IFXUSB1_OC_IRQ);
+ free_irq(IFXUSB1_OC_IRQ, (void *)oc1_int_id);
+ oc1_int_installed=0;
+ }
+ else
+ {
+ del_timer(&oc1_retry_timer);
+ disable_irq_nosync(IFXUSB1_OC_IRQ);
+ free_irq(IFXUSB2_OC_IRQ, (void *)oc2_int_id);
+ oc2_int_installed=0;
+ }
+ }
+
+ #elif defined(__IS_FIRST__) || defined(__IS_SECOND__)
+ unsigned int oc_int_installed=0;
+ unsigned int oc_int_count=0;
+ extern ifxhcd_hcd_t *oc_int_id;
+
+ /*!
+ \brief Handles host mode Over Current Interrupt
+ */
+ struct timer_list oc_retry_timer;
+
+ void oc_retry_timer_func(void)
+ {
+ if(oc_int_installed==0) //not installed
+ {
+ }
+ else if(oc_int_installed==1) //disabled
+ {
+ }
+ else if(oc_int_installed==2) //stablizing
+ {
+ oc_int_installed=4;
+ oc_int_count=0;
+ }
+ else if(oc_int_installed==3) // sleeping
+ {
+ mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ oc_int_installed=2;
+ #if defined(__IS_FIRST__)
+ enable_irq(IFXUSB1_OC_IRQ);
+ #else
+ enable_irq(IFXUSB2_OC_IRQ);
+ #endif
+ }
+ else if(oc_int_installed==4) //
+ {
+ oc_int_count=0;
+ }
+ else if(oc_int_installed==5) // Stable sleeping
+ {
+ mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ oc_int_installed=4;
+ #if defined(__IS_FIRST__)
+ enable_irq(IFXUSB1_OC_IRQ);
+ #else
+ enable_irq(IFXUSB2_OC_IRQ);
+ #endif
+ }
+ else
+ {
+ }
+ }
+
+ irqreturn_t ifxhcd_oc_irq(int _irq , void *_dev)
+ {
+ //ifxhcd_hcd_t *ifxhcd= _dev;
+ int32_t retval=1;
+ if(oc_int_installed==0) //not installed
+ {
+ }
+ else if(oc_int_installed==1) //disabled
+ {
+ }
+ else if(oc_int_installed==2) //stablizing
+ {
+ #if defined(__IS_FIRST__)
+ disable_irq_nosync(IFXUSB1_OC_IRQ);
+ #else
+ disable_irq_nosync(IFXUSB2_OC_IRQ);
+ #endif
+ mod_timer(&oc_retry_timer,jiffies + HZ/OC_Timer_Sleep);
+ oc_int_installed=3;
+ }
+ else if(oc_int_installed==3) // sleeping
+ {
+ }
+ else if(oc_int_installed==4) //
+ {
+ oc_int_count++;
+ if(oc_int_count>=OC_Timer_Max)
+ {
+ #if defined(__IS_FIRST__)
+ IFX_DEBUGP("OC INTERRUPT port #1\n");
+ #else
+ IFX_DEBUGP("OC INTERRUPT port #2\n");
+ #endif
+ oc_int_id->flags.b.port_over_current_change = 1;
+ ifxusb_vbus_off(&oc_int_id->core_if);
+ #if defined(__IS_FIRST__)
+ IFX_DEBUGP("Turning off port #1\n");
+ #else
+ IFX_DEBUGP("Turning off port #2\n");
+ #endif
+ }
+ else
+ {
+ #if defined(__IS_FIRST__)
+ disable_irq_nosync(IFXUSB1_OC_IRQ);
+ #else
+ disable_irq_nosync(IFXUSB2_OC_IRQ);
+ #endif
+ mod_timer(&oc_retry_timer,jiffies + HZ/OC_Timer_Sleep);
+ oc_int_installed=5;
+ }
+ }
+ else if(oc_int_installed==5) // Stable sleeping
+ {
+ }
+ return IRQ_RETVAL(retval);
+ }
+
+ void ifxusb_oc_int_on(void)
+ {
+ #if defined(__IS_FIRST__)
+ IFX_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for port #1 irq%d\n", IFXUSB1_OC_IRQ);
+ #else
+ IFX_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for port #2 irq%d\n", IFXUSB2_OC_IRQ);
+ #endif
+ if(oc_int_id)
+ {
+ if(oc_int_installed==0)
+ {
+ oc_int_installed=2;
+ init_timer(&oc_retry_timer);
+ oc_retry_timer.function = oc_retry_timer_func;
+ oc_retry_timer.data=1;
+ #if defined(__IS_FIRST__)
+ if(request_irq((unsigned int)IFXUSB1_OC_IRQ, &ifxhcd_oc_irq,
+ #else
+ if(request_irq((unsigned int)IFXUSB2_OC_IRQ, &ifxhcd_oc_irq,
+ #endif
+ IRQF_TRIGGER_NONE
+ // | IRQF_TRIGGER_RISING
+ // | IRQF_TRIGGER_FALLING
+ // | IRQF_TRIGGER_HIGH
+ // | IRQF_TRIGGER_LOW
+ // | IRQF_TRIGGER_PROBE
+ | IRQF_DISABLED
+ // | IRQF_SAMPLE_RANDOM
+ // | IRQF_SHARED
+ | IRQF_PROBE_SHARED
+ // | IRQF_TIMER
+ // | IRQF_PERCPU
+ // | IRQF_NOBALANCING
+ // | IRQF_IRQPOLL
+ // | IRQF_ONESHOT
+ ,
+ "ifxusb_oc", (void *)oc_int_id))
+ oc_int_installed=0;
+ else
+ mod_timer(&oc1_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ }
+ else if(oc_int_installed!=2 && oc_int_installed!=4 )
+ {
+ oc_int_installed=2;
+ #if defined(__IS_FIRST__)
+ enable_irq(IFXUSB1_OC_IRQ);
+ #else
+ enable_irq(IFXUSB2_OC_IRQ);
+ #endif
+ mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ }
+ }
+ }
+
+ void ifxusb_oc_int_off(int port)
+ {
+ #if defined(__IS_FIRST__)
+ disable_irq_nosync(IFXUSB1_OC_IRQ);
+ #else
+ disable_irq_nosync(IFXUSB2_OC_IRQ);
+ #endif
+ }
+ void ifxusb_oc_int_free(int port)
+ {
+ #if defined(__IS_FIRST__)
+ free_irq(IFXUSB1_OC_IRQ, (void *)oc_int_id);
+ #else
+ free_irq(IFXUSB2_OC_IRQ, (void *)oc_int_id);
+ #endif
+ }
+ #endif
+ #else //!defined(__IS_AR10__)
+ unsigned int oc_int_installed=0;
+ unsigned int oc_int_count=0;
+ extern ifxhcd_hcd_t *oc_int_id;
+ #ifdef __IS_DUAL__
+ extern ifxhcd_hcd_t *oc_int_id_1;
+ extern ifxhcd_hcd_t *oc_int_id_2;
+ #endif
+
+ /*!
+ \brief Handles host mode Over Current Interrupt
+ */
+ struct timer_list oc_retry_timer;
+
+ void oc_retry_timer_func(unsigned long arg)
+ {
+ if(oc_int_installed==0) //not installed
+ {
+ }
+ else if(oc_int_installed==1) //disabled
+ {
+ }
+ else if(oc_int_installed==2) //stablizing
+ {
+ oc_int_installed=4;
+ oc_int_count=0;
+ }
+ else if(oc_int_installed==3) // sleeping
+ {
+ mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ oc_int_installed=2;
+ enable_irq(IFXUSB_OC_IRQ);
+ }
+ else if(oc_int_installed==4) //
+ {
+ oc_int_count=0;
+ }
+ else if(oc_int_installed==5) // Stable sleeping
+ {
+ mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ oc_int_installed=4;
+ enable_irq(IFXUSB_OC_IRQ);
+ }
+ else
+ {
+ }
+ }
+
+ irqreturn_t ifxhcd_oc_irq(int _irq , void *_dev)
+ {
+ //ifxhcd_hcd_t *ifxhcd= _dev;
+ int32_t retval=1;
+
+ if(oc_int_installed==0) //not installed
+ {
+ }
+ else if(oc_int_installed==1) //disabled
+ {
+ }
+ else if(oc_int_installed==2) //stablizing
+ {
+ disable_irq_nosync(IFXUSB_OC_IRQ);
+ mod_timer(&oc_retry_timer,jiffies + HZ/OC_Timer_Sleep);
+ oc_int_installed=3;
+ }
+ else if(oc_int_installed==3) // sleeping
+ {
+ }
+ else if(oc_int_installed==4) //
+ {
+ oc_int_count++;
+ if(oc_int_count>=OC_Timer_Max)
+ {
+ IFX_DEBUGP("OC INTERRUPT port #%d\n",oc_int_id->core_if.core_no);
+ #ifdef __IS_DUAL__
+ oc_int_id_1->flags.b.port_over_current_change = 1;
+ oc_int_id_2->flags.b.port_over_current_change = 1;
+ ifxusb_vbus_off(&oc_int_id_1->core_if);
+ IFX_DEBUGP("Turning off port #%d\n",oc_int_id_1->core_if.core_no);
+ ifxusb_vbus_off(&oc_int_id_2->core_if);
+ IFX_DEBUGP("Turning off port #%d\n",oc_int_id_2->core_if.core_no);
+ #else
+ oc_int_id->flags.b.port_over_current_change = 1;
+ ifxusb_vbus_off(&oc_int_id->core_if);
+ IFX_DEBUGP("Turning off port #%d\n",oc_int_id->core_if.core_no);
+ #endif
+ }
+ else
+ {
+ disable_irq_nosync(IFXUSB_OC_IRQ);
+ mod_timer(&oc_retry_timer,jiffies + HZ/OC_Timer_Sleep);
+ oc_int_installed=5;
+ }
+ }
+ else if(oc_int_installed==5) // Stable sleeping
+ {
+ }
+
+ return IRQ_RETVAL(retval);
+ }
+
+ void ifxusb_oc_int_on(void)
+ {
+ IFX_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for irq%d\n", IFXUSB_OC_IRQ);
+ if(oc_int_id)
+ {
+ if(oc_int_installed==0)
+ {
+ oc_int_installed=2;
+ init_timer(&oc_retry_timer);
+ oc_retry_timer.function = oc_retry_timer_func;
+ /* Poll the event ring */
+
+ if(request_irq((unsigned int)IFXUSB_OC_IRQ, &ifxhcd_oc_irq,
+ IRQF_TRIGGER_NONE
+ // | IRQF_TRIGGER_RISING
+ // | IRQF_TRIGGER_FALLING
+ // | IRQF_TRIGGER_HIGH
+ // | IRQF_TRIGGER_LOW
+ // | IRQF_TRIGGER_PROBE
+ | IRQF_DISABLED
+ // | IRQF_SAMPLE_RANDOM
+ // | IRQF_SHARED
+ // | IRQF_PROBE_SHARED
+ // | IRQF_TIMER
+ // | IRQF_PERCPU
+ // | IRQF_NOBALANCING
+ // | IRQF_IRQPOLL
+ // | IRQF_ONESHOT
+ ,
+ "ifxusb_oc", (void *)oc_int_id))
+ oc_int_installed=0;
+ else
+ mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ }
+ else if(oc_int_installed!=2 && oc_int_installed!=4 )
+ {
+ oc_int_installed=2;
+ enable_irq(IFXUSB_OC_IRQ);
+ mod_timer(&oc_retry_timer,jiffies + HZ*OC_Timer_Stable);
+ }
+ }
+ }
+
+ void ifxusb_oc_int_off(void)
+ {
+ disable_irq_nosync(IFXUSB_OC_IRQ);
+ if(oc_int_installed)
+ oc_int_installed=1;
+ }
+
+ void ifxusb_oc_int_free(void)
+ {
+ del_timer(&oc_retry_timer);
+ disable_irq_nosync(IFXUSB_OC_IRQ);
+ if(oc_int_installed)
+ free_irq(IFXUSB_OC_IRQ, (void *)oc_int_id);
+ oc_int_installed=0;
+ }
+ #endif
+#endif
+
+
+/*!
+ \fn void ifxusb_vbus_on(ifxusb_core_if_t *_core_if)
+ \brief Turn on the USB 5V VBus Power
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+void ifxusb_vbus_on(ifxusb_core_if_t *_core_if)
+{
+ IFX_DEBUGP("SENDING VBus POWER UP\n");
+ #if defined(__UEIP__)
+ #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
+ if ( g_usb_vbus_trigger && ifxusb_vbus_status==0)
+ {
+ ifx_led_trigger_activate(g_usb_vbus_trigger);
+ IFX_DEBUGP("Enable USB power!!\n");
+ ifxusb_vbus_status=1;
+ }
+ #endif
+ #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
+ if(_core_if->core_no==0 && g_usb_vbus1_trigger && ifxusb_vbus1_status==0)
+ {
+ ifx_led_trigger_activate(g_usb_vbus1_trigger);
+ IFX_DEBUGP("Enable USB1 power!!\n");
+ ifxusb_vbus1_status=1;
+ }
+ #endif
+ #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
+ if(_core_if->core_no==1 && g_usb_vbus2_trigger && ifxusb_vbus2_status==0)
+ {
+ ifx_led_trigger_activate(g_usb_vbus2_trigger);
+ IFX_DEBUGP("Enable USB2 power!!\n");
+ ifxusb_vbus2_status=1;
+ }
+ #endif
+
+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
+ if(ifxusb_vbus_gpio_inited)
+ {
+ #if defined(IFX_GPIO_USB_VBUS)
+ if(ifxusb_vbus_status==0)
+ {
+ ifx_gpio_output_set(IFX_GPIO_USB_VBUS,IFX_GPIO_MODULE_USB);
+ ifxusb_vbus_status=1;
+ }
+ #endif
+ #if defined(IFX_GPIO_USB_VBUS1)
+ if(_core_if->core_no==0 && ifxusb_vbus1_status==0)
+ {
+ ifx_gpio_output_set(IFX_GPIO_USB_VBUS1,IFX_GPIO_MODULE_USB);
+ ifxusb_vbus1_status=1;
+ }
+ #endif
+ #if defined(IFX_GPIO_USB_VBUS2)
+ if(_core_if->core_no==1 && ifxusb_vbus2_status==0)
+ {
+ ifx_gpio_output_set(IFX_GPIO_USB_VBUS2,IFX_GPIO_MODULE_USB);
+ ifxusb_vbus2_status=1;
+ }
+ #endif
+ }
+ #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
+ #else
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ ifxusb_vbus_status=1;
+ //usb_set_vbus_on();
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ set_bit (4, (volatile unsigned long *)AMAZON_SE_GPIO_P0_OUT);
+ ifxusb_vbus_status=1;
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ {
+ if (bsp_port_reserve_pin(1, 13, PORT_MODULE_USB) != 0)
+ {
+ IFX_PRINT("Can't enable USB1 5.5V power!!\n");
+ return;
+ }
+ bsp_port_clear_altsel0(1, 13, PORT_MODULE_USB);
+ bsp_port_clear_altsel1(1, 13, PORT_MODULE_USB);
+ bsp_port_set_dir_out(1, 13, PORT_MODULE_USB);
+ bsp_port_set_pudsel(1, 13, PORT_MODULE_USB);
+ bsp_port_set_puden(1, 13, PORT_MODULE_USB);
+ bsp_port_set_output(1, 13, PORT_MODULE_USB);
+ IFX_DEBUGP("Enable USB1 power!!\n");
+ ifxusb_vbus1_status=1;
+ }
+ else
+ {
+ if (bsp_port_reserve_pin(3, 4, PORT_MODULE_USB) != 0)
+ {
+ IFX_PRINT("Can't enable USB2 5.5V power!!\n");
+ return;
+ }
+ bsp_port_clear_altsel0(3, 4, PORT_MODULE_USB);
+ bsp_port_clear_altsel1(3, 4, PORT_MODULE_USB);
+ bsp_port_set_dir_out(3, 4, PORT_MODULE_USB);
+ bsp_port_set_pudsel(3, 4, PORT_MODULE_USB);
+ bsp_port_set_puden(3, 4, PORT_MODULE_USB);
+ bsp_port_set_output(3, 4, PORT_MODULE_USB);
+ IFX_DEBUGP("Enable USB2 power!!\n");
+ ifxusb_vbus2_status=1;
+ }
+ #endif //defined(__IS_AR9__)
+ #if defined(__IS_VR9__)
+ if(_core_if->core_no==0)
+ {
+ ifxusb_vbus1_status=1;
+ }
+ else
+ {
+ ifxusb_vbus2_status=1;
+ }
+ #endif //defined(__IS_VR9__)
+ #endif //defined(__UEIP__)
+
+ #if defined(__DO_OC_INT__)
+ #if defined(__IS_AR10__) && defined(__IS_DUAL__)
+ if(_core_if->core_no==0)
+ ifxusb_oc_int_on(1);
+ else
+ ifxusb_oc_int_on(2);
+ #else
+ ifxusb_oc_int_on();
+ #endif
+ #endif
+
+}
+
+
+/*!
+ \fn void ifxusb_vbus_off(ifxusb_core_if_t *_core_if)
+ \brief Turn off the USB 5V VBus Power
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+void ifxusb_vbus_off(ifxusb_core_if_t *_core_if)
+{
+ IFX_DEBUGP("SENDING VBus POWER OFF\n");
+
+ #if defined(__UEIP__)
+ #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
+ if ( g_usb_vbus_trigger && ifxusb_vbus_status==1)
+ {
+ ifx_led_trigger_deactivate(g_usb_vbus_trigger);
+ IFX_DEBUGP("Disable USB power!!\n");
+ ifxusb_vbus_status=0;
+ }
+ #endif
+ #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
+ if(_core_if->core_no==0 && g_usb_vbus1_trigger && ifxusb_vbus1_status==1)
+ {
+ ifx_led_trigger_deactivate(g_usb_vbus1_trigger);
+ IFX_DEBUGP("Disable USB1 power!!\n");
+ ifxusb_vbus1_status=0;
+ }
+ #endif
+ #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
+ if(_core_if->core_no==1 && g_usb_vbus2_trigger && ifxusb_vbus2_status==1)
+ {
+ ifx_led_trigger_deactivate(g_usb_vbus2_trigger);
+ IFX_DEBUGP("Disable USB2 power!!\n");
+ ifxusb_vbus2_status=0;
+ }
+ #endif
+
+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
+ if(ifxusb_vbus_gpio_inited)
+ {
+ #if defined(IFX_GPIO_USB_VBUS)
+ if(ifxusb_vbus_status==1)
+ {
+ ifx_gpio_output_clear(IFX_GPIO_USB_VBUS,IFX_GPIO_MODULE_USB);
+ ifxusb_vbus_status=0;
+ }
+ #endif
+ #if defined(IFX_GPIO_USB_VBUS1)
+ if(_core_if->core_no==0 && ifxusb_vbus1_status==1)
+ {
+ ifx_gpio_output_clear(IFX_GPIO_USB_VBUS1,IFX_GPIO_MODULE_USB);
+ ifxusb_vbus1_status=0;
+ }
+ #endif
+ #if defined(IFX_GPIO_USB_VBUS2)
+ if(_core_if->core_no==1 && ifxusb_vbus2_status==1)
+ {
+ ifx_gpio_output_clear(IFX_GPIO_USB_VBUS2,IFX_GPIO_MODULE_USB);
+ ifxusb_vbus2_status=0;
+ }
+ #endif
+ }
+ #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2)
+ #else
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ ifxusb_vbus_status=0;
+ //usb_set_vbus_on();
+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #if defined(__IS_AMAZON_SE__)
+ clear_bit (4, (volatile unsigned long *)AMAZON_SE_GPIO_P0_OUT);
+ ifxusb_vbus_status=0;
+ #endif //defined(__IS_AMAZON_SE__)
+ #if defined(__IS_AR9__)
+ if(_core_if->core_no==0)
+ {
+ if (bsp_port_reserve_pin(1, 13, PORT_MODULE_USB) != 0) {
+ IFX_PRINT("Can't Disable USB1 5.5V power!!\n");
+ return;
+ }
+ bsp_port_clear_altsel0(1, 13, PORT_MODULE_USB);
+ bsp_port_clear_altsel1(1, 13, PORT_MODULE_USB);
+ bsp_port_set_dir_out(1, 13, PORT_MODULE_USB);
+ bsp_port_set_pudsel(1, 13, PORT_MODULE_USB);
+ bsp_port_set_puden(1, 13, PORT_MODULE_USB);
+ bsp_port_clear_output(1, 13, PORT_MODULE_USB);
+ IFX_DEBUGP("Disable USB1 power!!\n");
+ ifxusb_vbus1_status=0;
+ }
+ else
+ {
+ if (bsp_port_reserve_pin(3, 4, PORT_MODULE_USB) != 0) {
+ IFX_PRINT("Can't Disable USB2 5.5V power!!\n");
+ return;
+ }
+ bsp_port_clear_altsel0(3, 4, PORT_MODULE_USB);
+ bsp_port_clear_altsel1(3, 4, PORT_MODULE_USB);
+ bsp_port_set_dir_out(3, 4, PORT_MODULE_USB);
+ bsp_port_set_pudsel(3, 4, PORT_MODULE_USB);
+ bsp_port_set_puden(3, 4, PORT_MODULE_USB);
+ bsp_port_clear_output(3, 4, PORT_MODULE_USB);
+ IFX_DEBUGP("Disable USB2 power!!\n");
+
+ ifxusb_vbus2_status=0;
+ }
+ #endif //defined(__IS_AR9__)
+ #if defined(__IS_VR9__)
+ if(_core_if->core_no==0)
+ {
+ ifxusb_vbus1_status=0;
+ }
+ else
+ {
+ ifxusb_vbus2_status=0;
+ }
+ #endif //defined(__IS_VR9__)
+ #endif //defined(__UEIP__)
+ #if defined(__DO_OC_INT__)
+ #if defined(__IS_AR10__) && defined(__IS_DUAL__)
+ if(_core_if->core_no==0)
+ ifxusb_oc_int_off(1);
+ else
+ ifxusb_oc_int_off(2);
+ #else
+ ifxusb_oc_int_off();
+ #endif
+ #endif
+}
+
+
+/*!
+ \fn int ifxusb_vbus(ifxusb_core_if_t *_core_if)
+ \brief Read Current VBus status
+ \param _core_if Pointer of core_if structure
+ \ingroup IFXUSB_CIF
+ */
+int ifxusb_vbus(ifxusb_core_if_t *_core_if)
+{
+#if defined(__UEIP__)
+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS)
+ return (ifxusb_vbus_status);
+ #endif
+
+ #if defined(IFX_GPIO_USB_VBUS1) || defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1)
+ if(_core_if->core_no==0)
+ return (ifxusb_vbus1_status);
+ #endif
+
+ #if defined(IFX_GPIO_USB_VBUS2) || defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2)
+ if(_core_if->core_no==1)
+ return (ifxusb_vbus2_status);
+ #endif
+#else //defined(__UEIP__)
+#endif
+ return -1;
+}
+
+#if defined(__UEIP__)
+#else
+ #if defined(__IS_TWINPASS__)
+ #define ADSL_BASE 0x20000
+ #define CRI_BASE 0x31F00
+ #define CRI_CCR0 CRI_BASE + 0x00
+ #define CRI_CCR1 CRI_BASE + 0x01*4
+ #define CRI_CDC0 CRI_BASE + 0x02*4
+ #define CRI_CDC1 CRI_BASE + 0x03*4
+ #define CRI_RST CRI_BASE + 0x04*4
+ #define CRI_MASK0 CRI_BASE + 0x05*4
+ #define CRI_MASK1 CRI_BASE + 0x06*4
+ #define CRI_MASK2 CRI_BASE + 0x07*4
+ #define CRI_STATUS0 CRI_BASE + 0x08*4
+ #define CRI_STATUS1 CRI_BASE + 0x09*4
+ #define CRI_STATUS2 CRI_BASE + 0x0A*4
+ #define CRI_AMASK0 CRI_BASE + 0x0B*4
+ #define CRI_AMASK1 CRI_BASE + 0x0C*4
+ #define CRI_UPDCTL CRI_BASE + 0x0D*4
+ #define CRI_MADST CRI_BASE + 0x0E*4
+ // 0x0f is missing
+ #define CRI_EVENT0 CRI_BASE + 0x10*4
+ #define CRI_EVENT1 CRI_BASE + 0x11*4
+ #define CRI_EVENT2 CRI_BASE + 0x12*4
+
+ #define IRI_I_ENABLE 0x32000
+ #define STY_SMODE 0x3c004
+ #define AFE_TCR_0 0x3c0dc
+ #define AFE_ADDR_ADDR 0x3c0e8
+ #define AFE_RDATA_ADDR 0x3c0ec
+ #define AFE_WDATA_ADDR 0x3c0f0
+ #define AFE_CONFIG 0x3c0f4
+ #define AFE_SERIAL_CFG 0x3c0fc
+
+ #define DFE_BASE_ADDR 0xBE116000
+ //#define DFE_BASE_ADDR 0x9E116000
+
+ #define MEI_FR_ARCINT_C (DFE_BASE_ADDR + 0x0000001C)
+ #define MEI_DBG_WADDR_C (DFE_BASE_ADDR + 0x00000024)
+ #define MEI_DBG_RADDR_C (DFE_BASE_ADDR + 0x00000028)
+ #define MEI_DBG_DATA_C (DFE_BASE_ADDR + 0x0000002C)
+ #define MEI_DBG_DECO_C (DFE_BASE_ADDR + 0x00000030)
+ #define MEI_DBG_MASTER_C (DFE_BASE_ADDR + 0x0000003C)
+
+ static void WriteARCmem(uint32_t addr, uint32_t data)
+ {
+ writel(1 ,(volatile uint32_t *)MEI_DBG_MASTER_C);
+ writel(1 ,(volatile uint32_t *)MEI_DBG_DECO_C );
+ writel(addr ,(volatile uint32_t *)MEI_DBG_WADDR_C );
+ writel(data ,(volatile uint32_t *)MEI_DBG_DATA_C );
+ while( (ifxusb_rreg((volatile uint32_t *)MEI_FR_ARCINT_C) & 0x20) != 0x20 ){};
+ writel(0 ,(volatile uint32_t *)MEI_DBG_MASTER_C);
+ IFX_DEBUGP("WriteARCmem %08x %08x\n",addr,data);
+ };
+
+ static uint32_t ReadARCmem(uint32_t addr)
+ {
+ u32 data;
+ writel(1 ,(volatile uint32_t *)MEI_DBG_MASTER_C);
+ writel(1 ,(volatile uint32_t *)MEI_DBG_DECO_C );
+ writel(addr ,(volatile uint32_t *)MEI_DBG_RADDR_C );
+ while( (ifxusb_rreg((volatile uint32_t *)MEI_FR_ARCINT_C) & 0x20) != 0x20 ){};
+ data = ifxusb_rreg((volatile uint32_t *)MEI_DBG_DATA_C );
+ writel(0 ,(volatile uint32_t *)MEI_DBG_MASTER_C);
+ IFX_DEBUGP("ReadARCmem %08x %08x\n",addr,data);
+ return data;
+ };
+
+ void ifxusb_enable_afe_oc(void)
+ {
+ /* Start the clock */
+ WriteARCmem(CRI_UPDCTL ,0x00000008);
+ WriteARCmem(CRI_CCR0 ,0x00000014);
+ WriteARCmem(CRI_CCR1 ,0x00000500);
+ WriteARCmem(AFE_CONFIG ,0x000001c8);
+ WriteARCmem(AFE_SERIAL_CFG,0x00000016); // (DANUBE_PCI_CFG_BASE+(1<<addrline))AFE serial interface clock & data latch edge
+ WriteARCmem(AFE_TCR_0 ,0x00000002);
+ //Take afe out of reset
+ WriteARCmem(AFE_CONFIG ,0x000000c0);
+ WriteARCmem(IRI_I_ENABLE ,0x00000101);
+ WriteARCmem(STY_SMODE ,0x00001980);
+
+ ReadARCmem(CRI_UPDCTL );
+ ReadARCmem(CRI_CCR0 );
+ ReadARCmem(CRI_CCR1 );
+ ReadARCmem(AFE_CONFIG );
+ ReadARCmem(AFE_SERIAL_CFG); // (DANUBE_PCI_CFG_BASE+(1<<addrline))AFE serial interface clock & data latch edge
+ ReadARCmem(AFE_TCR_0 );
+ ReadARCmem(AFE_CONFIG );
+ ReadARCmem(IRI_I_ENABLE );
+ ReadARCmem(STY_SMODE );
+ }
+ #endif //defined(__IS_TWINPASS__)
+#endif //defined(__UEIP__)
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxusb_ctl.c b/package/kernel/lantiq/ltq-hcd/src/ifxusb_ctl.c
new file mode 100644
index 0000000000..32878e3d90
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxusb_ctl.c
@@ -0,0 +1,3825 @@
+/*****************************************************************************
+ ** FILE NAME : ifxusb_ctl.c
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 1.0
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** DESCRIPTION : Implementing the procfs and sysfs for IFX USB driver
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*! \file ifxusb_ctl.c
+ \ingroup IFXUSB_DRIVER_V3
+ \brief Implementing the procfs and sysfs for IFX USB driver
+*/
+
+#include <linux/version.h>
+#include "ifxusb_version.h"
+
+
+#include <linux/proc_fs.h>
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
+#include <asm/uaccess.h>
+
+#include "ifxusb_plat.h"
+#include "ifxusb_regs.h"
+#include "ifxusb_cif.h"
+
+#ifdef __IS_DEVICE__
+ #include "ifxpcd.h"
+ #ifdef __GADGET_COC__
+ #include <asm/ifx/ifx_types.h>
+ #include <asm/ifx/ifx_pmcu.h>
+ IFX_PMCU_REGISTER_t pmcuRegisterUSBGadget;
+ #endif
+#endif
+
+#ifdef __IS_HOST__
+ #include "ifxhcd.h"
+ #ifdef __HOST_COC__
+ #include <asm/ifx/ifx_types.h>
+ #include <asm/ifx/ifx_pmcu.h>
+ #ifdef __IS_DUAL__
+ IFX_PMCU_REGISTER_t pmcuRegisterUSBHost_1;
+ IFX_PMCU_REGISTER_t pmcuRegisterUSBHost_2;
+ #else
+ IFX_PMCU_REGISTER_t pmcuRegisterUSBHost;
+ #endif
+ #endif
+#endif
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/gfp.h>
+
+#ifdef __IS_HOST__
+ extern char ifxusb_hcd_driver_name[];
+
+ #ifdef __IS_DUAL__
+ extern ifxhcd_hcd_t ifxusb_hcd_1;
+ extern ifxhcd_hcd_t ifxusb_hcd_2;
+ extern char ifxusb_hcd_name_1[];
+ extern char ifxusb_hcd_name_2[];
+ #else
+ extern ifxhcd_hcd_t ifxusb_hcd;
+ extern char ifxusb_hcd_name[];
+ #endif
+
+#endif
+
+#ifdef __IS_DEVICE__
+ extern char ifxusb_pcd_driver_name[];
+
+ extern ifxpcd_pcd_t ifxusb_pcd;
+ extern char ifxusb_pcd_name[];
+#endif
+
+
+//Attributes for sysfs (for 2.6 only)
+
+#ifdef __IS_HOST__
+extern struct device_attribute dev_attr_version_h;
+#else
+extern struct device_attribute dev_attr_version_d;
+#endif
+#ifdef __IS_HOST__
+extern struct device_attribute dev_attr_dbglevel_h;
+#else
+extern struct device_attribute dev_attr_dbglevel_d;
+#endif
+#ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ extern struct device_attribute dev_attr_suspend_host_1;
+ extern struct device_attribute dev_attr_suspend_host_2;
+ extern struct device_attribute dev_attr_probe_host_1;
+ extern struct device_attribute dev_attr_probe_host_2;
+ extern struct device_attribute dev_attr_probe_timer1_val_h;
+ extern struct device_attribute dev_attr_probe_timer2_val_h;
+ extern struct device_attribute dev_attr_autoprobe_timer1_val_h;
+ extern struct device_attribute dev_attr_autoprobe_timer2_val_h;
+ #else
+ extern struct device_attribute dev_attr_suspend_host;
+ extern struct device_attribute dev_attr_probe_host;
+ extern struct device_attribute dev_attr_probe_timer_val_h;
+ extern struct device_attribute dev_attr_autoprobe_timer_val_h;
+ #endif
+#endif
+
+#ifdef __IS_DEVICE__
+ extern struct device_attribute dev_attr_suspend_device;
+ extern struct device_attribute dev_attr_probe_device;
+ extern struct device_attribute dev_attr_probe_timer_val_d;
+ extern struct device_attribute dev_attr_autoprobe_timer_val_d;
+#endif
+
+#ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ extern struct device_attribute dev_attr_dump_params_h_1;
+ extern struct device_attribute dev_attr_dump_params_h_2;
+ extern struct device_attribute dev_attr_mode_h_1;
+ extern struct device_attribute dev_attr_mode_h_2;
+ #else
+ extern struct device_attribute dev_attr_dump_params_h;
+ extern struct device_attribute dev_attr_mode_h;
+ #endif
+#else
+ extern struct device_attribute dev_attr_dump_params_d;
+ extern struct device_attribute dev_attr_mode_d;
+#endif
+
+#ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ extern struct device_attribute dev_attr_pkt_count_limit_bi_1;
+ extern struct device_attribute dev_attr_pkt_count_limit_bo_1;
+ extern struct device_attribute dev_attr_pkt_count_limit_bi_2;
+ extern struct device_attribute dev_attr_pkt_count_limit_bo_2;
+ extern struct device_attribute dev_attr_bandwidth_fs_1;
+ extern struct device_attribute dev_attr_bandwidth_ls_1;
+ extern struct device_attribute dev_attr_bandwidth_hs_2;
+ extern struct device_attribute dev_attr_bandwidth_fs_2;
+ extern struct device_attribute dev_attr_bandwidth_ls_2;
+ extern struct device_attribute dev_attr_buspower_1;
+ extern struct device_attribute dev_attr_buspower_2;
+ extern struct device_attribute dev_attr_bussuspend_1;
+ extern struct device_attribute dev_attr_bussuspend_2;
+ extern struct device_attribute dev_attr_busconnected_1;
+ extern struct device_attribute dev_attr_busconnected_2;
+ extern struct device_attribute dev_attr_connectspeed_1;
+ extern struct device_attribute dev_attr_connectspeed_1;
+ #else
+ extern struct device_attribute dev_attr_pkt_count_limit_bi;
+ extern struct device_attribute dev_attr_pkt_count_limit_bo;
+ extern struct device_attribute dev_attr_bandwidth_hs;
+ extern struct device_attribute dev_attr_bandwidth_fs;
+ extern struct device_attribute dev_attr_bandwidth_ls;
+ extern struct device_attribute dev_attr_buspower;
+ extern struct device_attribute dev_attr_bussuspend;
+ extern struct device_attribute dev_attr_busconnected;
+ extern struct device_attribute dev_attr_connectspeed;
+ #endif
+#endif //__IS_HOST__
+
+#ifdef __IS_DEVICE__
+ extern struct device_attribute dev_attr_devspeed;
+ extern struct device_attribute dev_attr_enumspeed;
+#endif //__IS_DEVICE__
+
+#ifdef __ENABLE_DUMP__
+ #ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ extern struct device_attribute dev_attr_dump_reg_h_1;
+ extern struct device_attribute dev_attr_dump_reg_h_2;
+ extern struct device_attribute dev_attr_dump_spram_h_1;
+ extern struct device_attribute dev_attr_dump_spram_h_2;
+ extern struct device_attribute dev_attr_dump_host_state_1;
+ extern struct device_attribute dev_attr_dump_host_state_2;
+ #else
+ extern struct device_attribute dev_attr_dump_reg_h;
+ extern struct device_attribute dev_attr_dump_spram_h;
+ extern struct device_attribute dev_attr_dump_host_state;
+ #endif
+ #else
+ extern struct device_attribute dev_attr_dump_reg_d;
+ extern struct device_attribute dev_attr_dump_spram_d;
+ #endif
+#endif //__ENABLE_DUMP__
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static ssize_t procfs_version_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+{
+ return sprintf( buf, "%s\n",IFXUSB_VERSION );
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_version_show( struct device *_dev, struct device_attribute *attr,char *buf)
+#else
+ static ssize_t sysfs_version_show( struct device *_dev, char *buf)
+#endif
+{
+ return sprintf( buf, "%s\n",IFXUSB_VERSION );
+}
+
+#ifdef __IS_HOST__
+DEVICE_ATTR(version_h, S_IRUGO|S_IWUSR, sysfs_version_show, NULL);
+#else
+DEVICE_ATTR(version_d, S_IRUGO|S_IWUSR, sysfs_version_show, NULL);
+#endif
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static ssize_t procfs_dbglevel_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+{
+ #ifdef __IS_HOST__
+ return sprintf( buf, "%08X\n",h_dbg_lvl );
+ #else
+ return sprintf( buf, "%08X\n",d_dbg_lvl );
+ #endif
+}
+
+static ssize_t procfs_dbglevel_store(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 16);
+ #ifdef __IS_HOST__
+ h_dbg_lvl =value;
+ #else
+ d_dbg_lvl =value;
+ #endif
+ //turn on and off power
+ return count;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dbglevel_show( struct device *_dev, struct device_attribute *attr,char *buf)
+#else
+ static ssize_t sysfs_dbglevel_show( struct device *_dev, char *buf)
+#endif
+{
+ #ifdef __IS_HOST__
+ return sprintf( buf, "%08X\n",h_dbg_lvl );
+ #else
+ return sprintf( buf, "%08X\n",d_dbg_lvl );
+ #endif
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dbglevel_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+#else
+ static ssize_t sysfs_dbglevel_store( struct device *_dev, const char *buffer, size_t count )
+#endif
+{
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 16);
+ #ifdef __IS_HOST__
+ h_dbg_lvl =value;
+ #else
+ d_dbg_lvl =value;
+ #endif
+ //turn on and off power
+ return count;
+}
+
+#ifdef __IS_HOST__
+DEVICE_ATTR(dbglevel_h, S_IRUGO|S_IWUSR, sysfs_dbglevel_show, sysfs_dbglevel_store);
+#else
+DEVICE_ATTR(dbglevel_d, S_IRUGO|S_IWUSR, sysfs_dbglevel_show, sysfs_dbglevel_store);
+#endif
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void ifxusb_dump_params(ifxusb_core_if_t *_core_if);
+
+#ifdef __IS_DUAL__
+ static void dump_params_1(void)
+ {
+ ifxusb_dump_params(&ifxusb_hcd_1.core_if);
+ }
+ static void dump_params_2(void)
+ {
+ ifxusb_dump_params(&ifxusb_hcd_2.core_if);
+ }
+
+ static ssize_t procfs_dump_params_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ dump_params_1();
+ return 0;
+ }
+ static ssize_t procfs_dump_params_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ dump_params_2();
+ return 0;
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_params_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_params_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ dump_params_1();
+ return 0;
+ }
+ DEVICE_ATTR(dump_params_h_1, S_IRUGO|S_IWUSR, sysfs_dump_params_show_1, NULL);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_params_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_params_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ dump_params_2();
+ return 0;
+ }
+
+ DEVICE_ATTR(dump_params_h_2, S_IRUGO|S_IWUSR, sysfs_dump_params_show_2, NULL);
+#else
+ static void dump_params(void)
+ {
+ #ifdef __IS_HOST__
+ ifxusb_dump_params(&ifxusb_hcd.core_if);
+ #else
+ ifxusb_dump_params(&ifxusb_pcd.core_if);
+ #endif
+ }
+
+ static ssize_t procfs_dump_params_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ dump_params();
+ return 0;
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_params_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_params_show( struct device *_dev,char *buf)
+ #endif
+ {
+ dump_params();
+ return 0;
+ }
+
+ #ifdef __IS_HOST__
+ DEVICE_ATTR(dump_params_h, S_IRUGO|S_IWUSR, sysfs_dump_params_show, NULL);
+ #else
+ DEVICE_ATTR(dump_params_d, S_IRUGO|S_IWUSR, sysfs_dump_params_show, NULL);
+ #endif
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __IS_DUAL__
+ static ssize_t mode_show_1(char *buf)
+ {
+ if((ifxusb_rreg(&ifxusb_hcd_1.core_if.core_global_regs->gintsts ) & 0x1) == 1)
+ return sprintf( buf, "HOST\n" );
+ else
+ return sprintf( buf, "DEVICE(INCORRECT!)\n" );
+ }
+
+ static ssize_t mode_show_2(char *buf)
+ {
+ if((ifxusb_rreg(&ifxusb_hcd_2.core_if.core_global_regs->gintsts ) & 0x1) == 1)
+ return sprintf( buf, "HOST\n" );
+ else
+ return sprintf( buf, "DEVICE(INCORRECT!)\n" );
+ }
+
+ static ssize_t procfs_mode_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return mode_show_1(buf);
+ }
+ static ssize_t procfs_mode_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return mode_show_2(buf);
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_mode_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_mode_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ return mode_show_1(buf);
+ }
+
+ DEVICE_ATTR(mode_h_1, S_IRUGO|S_IWUSR, sysfs_mode_show_1, 0);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_mode_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_mode_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ return mode_show_2(buf);
+ }
+ DEVICE_ATTR(mode_h_2, S_IRUGO|S_IWUSR, sysfs_mode_show_2, NULL);
+#else
+ static ssize_t mode_show(char *buf)
+ {
+ #ifdef __IS_HOST__
+ if((ifxusb_rreg(&ifxusb_hcd.core_if.core_global_regs->gintsts ) & 0x1) == 1)
+ return sprintf( buf, "HOST\n" );
+ else
+ return sprintf( buf, "DEVICE(INCORRECT!)\n" );
+ #else
+ if((ifxusb_rreg(&ifxusb_pcd.core_if.core_global_regs->gintsts ) & 0x1) != 1)
+ return sprintf( buf, "DEVICE\n" );
+ else
+ return sprintf( buf, "HOST(INCORRECT!)\n" );
+ #endif
+ }
+ static ssize_t procfs_mode_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return mode_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_mode_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_mode_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return mode_show(buf);
+ }
+ #ifdef __IS_HOST__
+ DEVICE_ATTR(mode_h, S_IRUGO|S_IWUSR, sysfs_mode_show, NULL);
+ #else
+ DEVICE_ATTR(mode_d, S_IRUGO|S_IWUSR, sysfs_mode_show, NULL);
+ #endif
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __IS_HOST__
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+ #ifdef __IS_DUAL__
+ static ssize_t bandwidth_hs_show_1(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd_1.pkt_remaining_reload_hs );
+ }
+ static ssize_t bandwidth_fs_show_1(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd_1.pkt_remaining_reload_fs );
+ }
+ static ssize_t bandwidth_ls_show_1(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd_1.pkt_remaining_reload_ls );
+ }
+ static void bandwidth_hs_store_1(uint32_t value)
+ {
+ if(value>16 && value<120)
+ {
+ hprt0_data_t hprt0;
+ ifxusb_hcd_1.pkt_remaining_reload_hs = value;
+ hprt0.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0);
+ if(hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
+ ifxusb_hcd_1.pkt_remaining_reload=value;
+ }
+ }
+ static void bandwidth_fs_store_1(uint32_t value)
+ {
+ if (value>2 && value<30)
+ {
+ hprt0_data_t hprt0;
+ ifxusb_hcd_1.pkt_remaining_reload_fs = value;
+ hprt0.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0);
+ if(hprt0.b.prtspd != IFXUSB_HPRT0_PRTSPD_LOW_SPEED && hprt0.b.prtspd != IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
+ ifxusb_hcd_1.pkt_remaining_reload=value;
+ }
+ }
+ static void bandwidth_ls_store_1(uint32_t value)
+ {
+ if (value>2 && value<30)
+ {
+ hprt0_data_t hprt0;
+ ifxusb_hcd_1.pkt_remaining_reload_ls = value;
+ hprt0.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0);
+ if(hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
+ ifxusb_hcd_1.pkt_remaining_reload=value;
+ }
+ }
+ static ssize_t bandwidth_hs_show_2(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd_2.pkt_remaining_reload_hs );
+ }
+ static ssize_t bandwidth_fs_show_2(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd_2.pkt_remaining_reload_fs );
+ }
+ static ssize_t bandwidth_ls_show_2(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd_2.pkt_remaining_reload_ls );
+ }
+ static void bandwidth_hs_store_2(uint32_t value)
+ {
+ if(value>16 && value<120)
+ {
+ hprt0_data_t hprt0;
+ ifxusb_hcd_2.pkt_remaining_reload_hs = value;
+ hprt0.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0);
+ if(hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
+ ifxusb_hcd_2.pkt_remaining_reload=value;
+ }
+ }
+ static void bandwidth_fs_store_2(uint32_t value)
+ {
+ if (value>2 && value<30)
+ {
+ hprt0_data_t hprt0;
+ ifxusb_hcd_2.pkt_remaining_reload_fs = value;
+ hprt0.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0);
+ if(hprt0.b.prtspd != IFXUSB_HPRT0_PRTSPD_LOW_SPEED && hprt0.b.prtspd != IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
+ ifxusb_hcd_2.pkt_remaining_reload=value;
+ }
+ }
+ static void bandwidth_ls_store_2(uint32_t value)
+ {
+ if (value>2 && value<30)
+ {
+ hprt0_data_t hprt0;
+ ifxusb_hcd_2.pkt_remaining_reload_ls = value;
+ hprt0.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0);
+ if(hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
+ ifxusb_hcd_2.pkt_remaining_reload=value;
+ }
+ }
+ static ssize_t procfs_bandwidth_hs_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bandwidth_hs_show_1(buf);
+ }
+ static ssize_t procfs_bandwidth_fs_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bandwidth_fs_show_1(buf);
+ }
+ static ssize_t procfs_bandwidth_ls_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bandwidth_ls_show_1(buf);
+ }
+ static ssize_t procfs_bandwidth_hs_store_1(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_hs_store_1(value);
+ return count;
+ }
+ static ssize_t procfs_bandwidth_fs_store_1(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_fs_store_1(value);
+ return count;
+ }
+ static ssize_t procfs_bandwidth_ls_store_1(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_ls_store_1(value);
+ return count;
+ }
+ static ssize_t procfs_bandwidth_hs_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bandwidth_hs_show_2(buf);
+ }
+ static ssize_t procfs_bandwidth_fs_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bandwidth_fs_show_2(buf);
+ }
+ static ssize_t procfs_bandwidth_ls_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bandwidth_ls_show_2(buf);
+ }
+ static ssize_t procfs_bandwidth_hs_store_2(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_hs_store_2(value);
+ return count;
+ }
+ static ssize_t procfs_bandwidth_fs_store_2(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_fs_store_2(value);
+ return count;
+ }
+ static ssize_t procfs_bandwidth_ls_store_2(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_ls_store_2(value);
+ return count;
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_hs_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bandwidth_hs_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ return bandwidth_hs_show_1(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_hs_store_1( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_bandwidth_hs_store_1( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_hs_store_1(value);
+ return count;
+ }
+ DEVICE_ATTR(bandwidth_hs_1, S_IRUGO|S_IWUSR, sysfs_bandwidth_hs_show_1, sysfs_bandwidth_hs_store_1);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_fs_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bandwidth_fs_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ return bandwidth_fs_show_1(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_fs_store_1( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_bandwidth_fs_store_1( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_fs_store_1(value);
+ return count;
+ }
+ DEVICE_ATTR(bandwidth_fs_1, S_IRUGO|S_IWUSR, sysfs_bandwidth_fs_show_1, sysfs_bandwidth_fs_store_1);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_ls_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bandwidth_ls_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ return bandwidth_ls_show_1(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_ls_store_1( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_bandwidth_ls_store_1( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_ls_store_1(value);
+ return count;
+ }
+ DEVICE_ATTR(bandwidth_ls_1, S_IRUGO|S_IWUSR, sysfs_bandwidth_ls_show_1, sysfs_bandwidth_ls_store_1);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_hs_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bandwidth_hs_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ return bandwidth_hs_show_2(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_hs_store_2( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_bandwidth_hs_store_2( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_hs_store_2(value);
+ return count;
+ }
+ DEVICE_ATTR(bandwidth_hs_2, S_IRUGO|S_IWUSR, sysfs_bandwidth_hs_show_2, sysfs_bandwidth_hs_store_2);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_fs_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bandwidth_fs_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ return bandwidth_fs_show_2(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_fs_store_2( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_bandwidth_fs_store_2( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_fs_store_2(value);
+ return count;
+ }
+ DEVICE_ATTR(bandwidth_fs_2, S_IRUGO|S_IWUSR, sysfs_bandwidth_fs_show_2, sysfs_bandwidth_fs_store_2);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_ls_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bandwidth_ls_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ return bandwidth_ls_show_2(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_ls_store_2( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_bandwidth_ls_store_2( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_ls_store_2(value);
+ return count;
+ }
+ DEVICE_ATTR(bandwidth_ls_2, S_IRUGO|S_IWUSR, sysfs_bandwidth_ls_show_2, sysfs_bandwidth_ls_store_2);
+ #else
+ static ssize_t bandwidth_hs_show(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd.pkt_remaining_reload_hs );
+ }
+ static ssize_t bandwidth_fs_show(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd.pkt_remaining_reload_fs );
+ }
+ static ssize_t bandwidth_ls_show(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd.pkt_remaining_reload_ls );
+ }
+ static void bandwidth_hs_store(uint32_t value)
+ {
+ if (value>16 && value<120)
+ {
+ hprt0_data_t hprt0;
+ ifxusb_hcd.pkt_remaining_reload_hs = value;
+ hprt0.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0);
+ if(hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
+ ifxusb_hcd.pkt_remaining_reload=value;
+ }
+ }
+ static void bandwidth_fs_store(uint32_t value)
+ {
+ if (value>2 && value<30)
+ {
+ hprt0_data_t hprt0;
+ ifxusb_hcd.pkt_remaining_reload_fs = value;
+ hprt0.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0);
+ if(hprt0.b.prtspd != IFXUSB_HPRT0_PRTSPD_LOW_SPEED && hprt0.b.prtspd != IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
+ ifxusb_hcd.pkt_remaining_reload=value;
+ }
+ }
+ static void bandwidth_ls_store(uint32_t value)
+ {
+ if (value>2 && value<30)
+ {
+ hprt0_data_t hprt0;
+ ifxusb_hcd.pkt_remaining_reload_hs = value;
+ hprt0.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0);
+ if(hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
+ ifxusb_hcd.pkt_remaining_reload=value;
+ }
+ }
+ static ssize_t procfs_bandwidth_hs_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bandwidth_hs_show(buf);
+ }
+ static ssize_t procfs_bandwidth_fs_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bandwidth_fs_show(buf);
+ }
+ static ssize_t procfs_bandwidth_ls_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bandwidth_ls_show(buf);
+ }
+ static ssize_t procfs_bandwidth_hs_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_hs_store(value);
+ return count;
+ }
+ static ssize_t procfs_bandwidth_fs_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_fs_store(value);
+ return count;
+ }
+ static ssize_t procfs_bandwidth_ls_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_ls_store(value);
+ return count;
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_hs_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bandwidth_hs_show( struct device *_dev,char *buf)
+ #endif
+ {
+ return bandwidth_hs_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_hs_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_bandwidth_hs_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_hs_store(value);
+ return count;
+ }
+ DEVICE_ATTR(bandwidth_hs, S_IRUGO|S_IWUSR, sysfs_bandwidth_hs_show, sysfs_bandwidth_hs_store);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_fs_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bandwidth_fs_show( struct device *_dev,char *buf)
+ #endif
+ {
+ return bandwidth_fs_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_fs_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_bandwidth_fs_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_fs_store(value);
+ return count;
+ }
+ DEVICE_ATTR(bandwidth_fs, S_IRUGO|S_IWUSR, sysfs_bandwidth_fs_show, sysfs_bandwidth_fs_store);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_ls_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bandwidth_ls_show( struct device *_dev,char *buf)
+ #endif
+ {
+ return bandwidth_ls_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bandwidth_ls_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_bandwidth_ls_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ bandwidth_ls_store(value);
+ return count;
+ }
+ DEVICE_ATTR(bandwidth_ls, S_IRUGO|S_IWUSR, sysfs_bandwidth_ls_show, sysfs_bandwidth_ls_store);
+ #endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+ #ifdef __IS_DUAL__
+ static ssize_t pkt_count_limit_bi_show_1(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd_1.pkt_count_limit_bi );
+ }
+ static ssize_t pkt_count_limit_bo_show_1(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd_1.pkt_count_limit_bo );
+ }
+ static void pkt_count_limit_bi_store_1(uint32_t value)
+ {
+ if(value<=13)
+ ifxusb_hcd_1.pkt_count_limit_bi = value;
+ }
+ static void pkt_count_limit_bo_store_1(uint32_t value)
+ {
+ if (value<=13)
+ ifxusb_hcd_1.pkt_count_limit_bo = value;
+ }
+ static ssize_t pkt_count_limit_bi_show_2(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd_2.pkt_count_limit_bi );
+ }
+ static ssize_t pkt_count_limit_bo_show_2(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd_2.pkt_count_limit_bo );
+ }
+ static void pkt_count_limit_bi_store_2(uint32_t value)
+ {
+ if(value<=13)
+ ifxusb_hcd_2.pkt_count_limit_bi = value;
+ }
+ static void pkt_count_limit_bo_store_2(uint32_t value)
+ {
+ if(value<=13)
+ ifxusb_hcd_2.pkt_count_limit_bo = value;
+ }
+ static ssize_t procfs_pkt_count_limit_bi_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return pkt_count_limit_bi_show_1(buf);
+ }
+ static ssize_t procfs_pkt_count_limit_bo_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return pkt_count_limit_bo_show_1(buf);
+ }
+ static ssize_t procfs_pkt_count_limit_bi_store_1(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bi_store_1(value);
+ return count;
+ }
+ static ssize_t procfs_pkt_count_limit_bo_store_1(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bo_store_1(value);
+ return count;
+ }
+ static ssize_t procfs_pkt_count_limit_bi_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return pkt_count_limit_bi_show_2(buf);
+ }
+ static ssize_t procfs_pkt_count_limit_bo_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return pkt_count_limit_bo_show_2(buf);
+ }
+ static ssize_t procfs_pkt_count_limit_bi_store_2(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bi_store_2(value);
+ return count;
+ }
+ static ssize_t procfs_pkt_count_limit_bo_store_2(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bo_store_2(value);
+ return count;
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bi_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_pkt_count_limit_bi_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ return pkt_count_limit_bi_show_1(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bi_store_1( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_pkt_count_limit_bi_store_1( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bi_store_1(value);
+ return count;
+ }
+ DEVICE_ATTR(pkt_count_limit_bi_1, S_IRUGO|S_IWUSR, sysfs_pkt_count_limit_bi_show_1, sysfs_pkt_count_limit_bi_store_1);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bo_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_pkt_count_limit_bo_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ return pkt_count_limit_bo_show_1(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bo_store_1( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_pkt_count_limit_bo_store_1( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bo_store_1(value);
+ return count;
+ }
+ DEVICE_ATTR(pkt_count_limit_bo_1, S_IRUGO|S_IWUSR, sysfs_pkt_count_limit_bo_show_1, sysfs_pkt_count_limit_bo_store_1);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bi_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_pkt_count_limit_bi_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ return pkt_count_limit_bi_show_2(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bi_store_2( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_pkt_count_limit_bi_2( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bi_store_2(value);
+ return count;
+ }
+ DEVICE_ATTR(pkt_count_limit_bi_2, S_IRUGO|S_IWUSR, sysfs_pkt_count_limit_bi_show_2, sysfs_pkt_count_limit_bi_store_2);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bo_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_pkt_count_limit_bo_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ return pkt_count_limit_bo_show_2(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bo_store_2( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_pkt_count_limit_bo_store_2( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bo_store_2(value);
+ return count;
+ }
+ DEVICE_ATTR(pkt_count_limit_bo_2, S_IRUGO|S_IWUSR, sysfs_pkt_count_limit_bo_show_2, sysfs_pkt_count_limit_bo_store_2);
+ #else
+ static ssize_t pkt_count_limit_bi_show(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd.pkt_count_limit_bi );
+ }
+ static ssize_t pkt_count_limit_bo_show(char *buf)
+ {
+ return sprintf( buf, "%d\n",ifxusb_hcd.pkt_count_limit_bo );
+ }
+ static void pkt_count_limit_bi_store(uint32_t value)
+ {
+ if (value<=13)
+ ifxusb_hcd.pkt_count_limit_bi = value;
+ }
+ static void pkt_count_limit_bo_store(uint32_t value)
+ {
+ if (value<=13)
+ ifxusb_hcd.pkt_count_limit_bo = value;
+ }
+ static ssize_t procfs_pkt_count_limit_bi_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return pkt_count_limit_bi_show(buf);
+ }
+ static ssize_t procfs_pkt_count_limit_bo_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return pkt_count_limit_bo_show(buf);
+ }
+ static ssize_t procfs_pkt_count_limit_bi_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bi_store(value);
+ return count;
+ }
+ static ssize_t procfs_pkt_count_limit_bo_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bo_store(value);
+ return count;
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bi_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_pkt_count_limit_bi_show( struct device *_dev,char *buf)
+ #endif
+ {
+ return pkt_count_limit_bi_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bi_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_pkt_count_limit_bi_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bi_store(value);
+ return count;
+ }
+ DEVICE_ATTR(pkt_count_limit_bi, S_IRUGO|S_IWUSR, sysfs_pkt_count_limit_bi_show, sysfs_pkt_count_limit_bi_store);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bo_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_pkt_count_limit_bo_show( struct device *_dev,char *buf)
+ #endif
+ {
+ return pkt_count_limit_bo_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_pkt_count_limit_bo_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_pkt_count_limit_bo_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ pkt_count_limit_bo_store(value);
+ return count;
+ }
+ DEVICE_ATTR(pkt_count_limit_bo, S_IRUGO|S_IWUSR, sysfs_pkt_count_limit_bo_show, sysfs_pkt_count_limit_bo_store);
+ #endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #ifdef __IS_DUAL__
+ static ssize_t buspower_show_1(char *buf)
+ {
+ if(ifxusb_vbus (&ifxusb_hcd_1.core_if)==1) return sprintf( buf, "1\n" );
+ if(ifxusb_vbus (&ifxusb_hcd_1.core_if)==0) return sprintf( buf, "0\n" );
+ return sprintf( buf, "UNKNOWN\n" );
+ }
+ static void buspower_store_1(uint32_t value)
+ {
+ if (value==1) ifxusb_vbus_on (&ifxusb_hcd_1.core_if);
+ else if(value==0) ifxusb_vbus_off(&ifxusb_hcd_1.core_if);
+ }
+ static ssize_t buspower_show_2(char *buf)
+ {
+ if(ifxusb_vbus (&ifxusb_hcd_2.core_if)==1) return sprintf( buf, "1\n" );
+ if(ifxusb_vbus (&ifxusb_hcd_2.core_if)==0) return sprintf( buf, "0\n" );
+ return sprintf( buf, "UNKNOWN\n" );
+ }
+ static void buspower_store_2(uint32_t value)
+ {
+ if (value==1) ifxusb_vbus_on (&ifxusb_hcd_2.core_if);
+ else if(value==0) ifxusb_vbus_off(&ifxusb_hcd_2.core_if);
+ }
+ static ssize_t procfs_buspower_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return buspower_show_1(buf);
+ }
+ static ssize_t procfs_buspower_store_1(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ buspower_store_1(value);
+ return count;
+ }
+ static ssize_t procfs_buspower_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return buspower_show_2(buf);
+ }
+ static ssize_t procfs_buspower_store_2(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ buspower_store_2(value);
+ return count;
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_buspower_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_buspower_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ return buspower_show_1(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_buspower_store_1( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_buspower_store_1( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ buspower_store_1(value);
+ return count;
+ }
+ DEVICE_ATTR(buspower_1, S_IRUGO|S_IWUSR, sysfs_buspower_show_1, sysfs_buspower_store_1);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_buspower_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_buspower_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ return buspower_show_2(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_buspower_store_2( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_buspower_store_2( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ buspower_store_2(value);
+ return count;
+ }
+ DEVICE_ATTR(buspower_2, S_IRUGO|S_IWUSR, sysfs_buspower_show_2, sysfs_buspower_store_2);
+ #else
+ static ssize_t buspower_show(char *buf)
+ {
+ if(ifxusb_vbus (&ifxusb_hcd.core_if)==1) return sprintf( buf, "1\n" );
+ if(ifxusb_vbus (&ifxusb_hcd.core_if)==0) return sprintf( buf, "0\n" );
+ return sprintf( buf, "UNKNOWN\n" );
+ }
+ static void buspower_store(uint32_t value)
+ {
+ if (value==1) ifxusb_vbus_on (&ifxusb_hcd.core_if);
+ else if(value==0) ifxusb_vbus_off(&ifxusb_hcd.core_if);
+ }
+ static ssize_t procfs_buspower_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return buspower_show(buf);
+ }
+ static ssize_t procfs_buspower_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ buspower_store(value);
+ return count;
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_buspower_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_buspower_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return buspower_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_buspower_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_buspower_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ buspower_store(value);
+ return count;
+ }
+ DEVICE_ATTR(buspower, S_IRUGO|S_IWUSR, sysfs_buspower_show, sysfs_buspower_store);
+ #endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+ #ifdef __IS_DUAL__
+ static ssize_t bussuspend_show_1(char *buf)
+ {
+ hprt0_data_t val;
+ val.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0);
+ return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
+ }
+ static ssize_t bussuspend_show_2(char *buf)
+ {
+ hprt0_data_t val;
+ val.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0);
+ return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
+ }
+
+ static ssize_t procfs_bussuspend_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bussuspend_show_1(buf);
+ }
+ static ssize_t procfs_bussuspend_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bussuspend_show_2(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bussuspend_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bussuspend_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ return bussuspend_show_1(buf);
+ }
+ DEVICE_ATTR(bussuspend_1, S_IRUGO|S_IWUSR, sysfs_bussuspend_show_1, 0);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bussuspend_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bussuspend_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ return bussuspend_show_2(buf);
+ }
+ DEVICE_ATTR(bussuspend_2, S_IRUGO|S_IWUSR, sysfs_bussuspend_show_2, 0);
+ #else
+ static ssize_t bussuspend_show(char *buf)
+ {
+ hprt0_data_t val;
+ val.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0);
+ return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
+ }
+ static ssize_t procfs_bussuspend_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return bussuspend_show(buf);
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_bussuspend_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_bussuspend_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return bussuspend_show(buf);
+ }
+ DEVICE_ATTR(bussuspend, S_IRUGO|S_IWUSR, sysfs_bussuspend_show, 0);
+ #endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #ifdef __IS_DUAL__
+ static ssize_t busconnected_show_1(char *buf)
+ {
+ hprt0_data_t val;
+ val.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0);
+ return sprintf (buf, "Bus Connected = 0x%x\n", val.b.prtconnsts);
+ }
+ static ssize_t busconnected_show_2(char *buf)
+ {
+ hprt0_data_t val;
+ val.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0);
+ return sprintf (buf, "Bus Connected = 0x%x\n", val.b.prtconnsts);
+ }
+
+ static ssize_t procfs_busconnected_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return busconnected_show_1(buf);
+ }
+ static ssize_t procfs_busconnected_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return busconnected_show_2(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_busconnected_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_busconnected_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ return busconnected_show_1(buf);
+ }
+ DEVICE_ATTR(busconnected_1, S_IRUGO|S_IWUSR, sysfs_busconnected_show_1, 0);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_busconnected_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_busconnected_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ return busconnected_show_2(buf);
+ }
+ DEVICE_ATTR(busconnected_2, S_IRUGO|S_IWUSR, sysfs_busconnected_show_2, 0);
+ #else
+ static ssize_t busconnected_show(char *buf)
+ {
+ hprt0_data_t val;
+ val.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0);
+ return sprintf (buf, "Bus Connected = 0x%x\n", val.b.prtconnsts);
+ }
+ static ssize_t procfs_busconnected_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return busconnected_show(buf);
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_busconnected_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_busconnected_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return busconnected_show(buf);
+ }
+ DEVICE_ATTR(busconnected, S_IRUGO|S_IWUSR, sysfs_busconnected_show, 0);
+ #endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #ifdef __IS_DUAL__
+ static ssize_t connectspeed_show_1(char *buf)
+ {
+ hprt0_data_t val;
+ val.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0);
+ if( val.b.prtspd ==0) return sprintf (buf, "Bus Speed = High (%d)\n", val.b.prtspd);
+ if( val.b.prtspd ==1) return sprintf (buf, "Bus Speed = Full (%d)\n", val.b.prtspd);
+ if( val.b.prtspd ==2) return sprintf (buf, "Bus Speed = Low (%d)\n", val.b.prtspd);
+ return sprintf (buf, "Bus Speed = Unknown (%d)\n", val.b.prtspd);
+ }
+ static ssize_t connectspeed_show_2(char *buf)
+ {
+ hprt0_data_t val;
+ val.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0);
+ if( val.b.prtspd ==0) return sprintf (buf, "Bus Speed = High (%d)\n", val.b.prtspd);
+ if( val.b.prtspd ==1) return sprintf (buf, "Bus Speed = Full (%d)\n", val.b.prtspd);
+ if( val.b.prtspd ==2) return sprintf (buf, "Bus Speed = Low (%d)\n", val.b.prtspd);
+ return sprintf (buf, "Bus Speed = Unknown (%d)\n", val.b.prtspd);
+ }
+
+ static ssize_t procfs_connectspeed_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return connectspeed_show_1(buf);
+ }
+ static ssize_t procfs_connectspeed_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return connectspeed_show_2(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_connectspeed_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_connectspeed_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ return connectspeed_show_1(buf);
+ }
+ DEVICE_ATTR(connectspeed_1, S_IRUGO|S_IWUSR, sysfs_connectspeed_show_1, 0);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_connectspeed_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_connectspeed_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ return connectspeed_show_2(buf);
+ }
+ DEVICE_ATTR(connectspeed_2, S_IRUGO|S_IWUSR, sysfs_connectspeed_show_2, 0);
+ #else
+ static ssize_t connectspeed_show(char *buf)
+ {
+ hprt0_data_t val;
+ val.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0);
+ if( val.b.prtspd ==0) return sprintf (buf, "Bus Speed = High (%d)\n", val.b.prtspd);
+ if( val.b.prtspd ==1) return sprintf (buf, "Bus Speed = Full (%d)\n", val.b.prtspd);
+ if( val.b.prtspd ==2) return sprintf (buf, "Bus Speed = Low (%d)\n", val.b.prtspd);
+ return sprintf (buf, "Bus Speed = Unknown (%d)\n", val.b.prtspd);
+ }
+
+ static ssize_t procfs_connectspeed_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return connectspeed_show(buf);
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_connectspeed_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_connectspeed_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return connectspeed_show(buf);
+ }
+ DEVICE_ATTR(connectspeed, S_IRUGO|S_IWUSR, sysfs_connectspeed_show, 0);
+ #endif
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#endif
+
+
+#ifdef __IS_DEVICE__
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+ static ssize_t devspeed_show(char *buf)
+ {
+ dcfg_data_t val;
+ val.d32 = ifxusb_rreg(&ifxusb_pcd.core_if.dev_global_regs->dcfg);
+ if( val.b.devspd ==0) return sprintf (buf, "Dev Speed = High (%d)\n", val.b.devspd);
+ if( val.b.devspd ==1) return sprintf (buf, "Dev Speed = Full (%d)\n", val.b.devspd);
+ if( val.b.devspd ==3) return sprintf (buf, "Dev Speed = Full (%d)\n", val.b.devspd);
+ return sprintf (buf, "Dev Speed = Unknown (%d)\n", val.b.devspd);
+ }
+
+ static ssize_t procfs_devspeed_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return devspeed_show(buf);
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_devspeed_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_devspeed_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return devspeed_show(buf);
+ }
+ DEVICE_ATTR(devspeed, S_IRUGO|S_IWUSR, sysfs_devspeed_show, 0);
+
+ static ssize_t enumspeed_show(char *buf)
+ {
+ dsts_data_t val;
+ val.d32 = ifxusb_rreg(&ifxusb_pcd.core_if.dev_global_regs->dsts);
+ if( val.b.enumspd ==0) return sprintf (buf, "Enum Speed = High (%d)\n", val.b.enumspd);
+ if( val.b.enumspd ==1) return sprintf (buf, "Enum Speed = Full (%d)\n", val.b.enumspd);
+ if( val.b.enumspd ==2) return sprintf (buf, "Enum Speed = Low (%d)\n", val.b.enumspd);
+ return sprintf (buf, "Enum Speed = invalid(%d)\n", val.b.enumspd);
+ }
+
+ static ssize_t procfs_enumspeed_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return enumspeed_show(buf);
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_enumspeed_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_enumspeed_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return enumspeed_show(buf);
+ }
+ DEVICE_ATTR(enumspeed, S_IRUGO|S_IWUSR, sysfs_enumspeed_show, 0);
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#endif
+
+
+//////////////////////////////////////////////////////////////////////////////////
+#ifdef __ENABLE_DUMP__
+
+ #ifdef __IS_DUAL__
+ static void dump_reg_1(void)
+ {
+ ifxusb_dump_registers_h(&ifxusb_hcd_1.core_if);
+ }
+ static void dump_reg_2(void)
+ {
+ ifxusb_dump_registers_h(&ifxusb_hcd_2.core_if);
+ }
+
+ static ssize_t procfs_dump_reg_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ dump_reg_1();
+ return 0;
+ }
+ static ssize_t procfs_dump_reg_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ dump_reg_2();
+ return 0;
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_reg_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_reg_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ dump_reg_1();
+ return 0;
+ }
+ DEVICE_ATTR(dump_reg_h_1, S_IRUGO|S_IWUSR, sysfs_dump_reg_show_1, 0);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_reg_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_reg_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ dump_reg_2();
+ return 0;
+ }
+ DEVICE_ATTR(dump_reg_h_2, S_IRUGO|S_IWUSR, sysfs_dump_reg_show_2, 0);
+ #else
+ static void dump_reg(void)
+ {
+ #ifdef __IS_HOST__
+ ifxusb_dump_registers_h(&ifxusb_hcd.core_if);
+ #endif
+ #ifdef __IS_DEVICE__
+ ifxusb_dump_registers_d(&ifxusb_pcd.core_if);
+ #endif
+ }
+ static ssize_t procfs_dump_reg_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ dump_reg();
+ return 0;
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_reg_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_reg_show( struct device *_dev,char *buf)
+ #endif
+ {
+ dump_reg();
+ return 0;
+ }
+ #ifdef __IS_HOST__
+ DEVICE_ATTR(dump_reg_h, S_IRUGO|S_IWUSR, sysfs_dump_reg_show, 0);
+ #else
+ DEVICE_ATTR(dump_reg_d, S_IRUGO|S_IWUSR, sysfs_dump_reg_show, 0);
+ #endif
+ #endif
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #ifdef __IS_DUAL__
+ static void dump_spram_1(void)
+ {
+ ifxusb_dump_spram_h(&ifxusb_hcd_1.core_if);
+ }
+ static void dump_spram_2(void)
+ {
+ ifxusb_dump_spram_h(&ifxusb_hcd_2.core_if);
+ }
+
+ static ssize_t procfs_dump_spram_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ dump_spram_1();
+ return 0;
+ }
+ static ssize_t procfs_dump_spram_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ dump_spram_2();
+ return 0;
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_spram_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_spram_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ dump_spram_1();
+ return 0;
+ }
+ DEVICE_ATTR(dump_spram_h_1, S_IRUGO|S_IWUSR, sysfs_dump_spram_show_1, 0);
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_spram_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_spram_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ dump_spram_2();
+ return 0;
+ }
+ DEVICE_ATTR(dump_spram_h_2, S_IRUGO|S_IWUSR, sysfs_dump_spram_show_2, 0);
+ #else
+ static void dump_spram(void)
+ {
+ #ifdef __IS_HOST__
+ ifxusb_dump_spram_h(&ifxusb_hcd.core_if);
+ #endif
+ #ifdef __IS_DEVICE__
+ ifxusb_dump_spram_d(&ifxusb_pcd.core_if);
+ #endif
+ }
+ static ssize_t procfs_dump_spram_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ dump_spram();
+ return 0;
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_spram_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_spram_show( struct device *_dev,char *buf)
+ #endif
+ {
+ dump_spram();
+ return 0;
+ }
+ #ifdef __IS_HOST__
+ DEVICE_ATTR(dump_spram_h, S_IRUGO|S_IWUSR, sysfs_dump_spram_show, 0);
+ #else
+ DEVICE_ATTR(dump_spram_d, S_IRUGO|S_IWUSR, sysfs_dump_spram_show, 0);
+ #endif
+
+ #endif
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ static ssize_t procfs_dump_host_state_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ ifxhcd_dump_state(&ifxusb_hcd_1);
+ return 0;
+ }
+ static ssize_t procfs_dump_host_state_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ ifxhcd_dump_state(&ifxusb_hcd_2);
+ return 0;
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_host_state_show_1( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_host_state_show_1( struct device *_dev,char *buf)
+ #endif
+ {
+ ifxhcd_dump_state(&ifxusb_hcd_1);
+ return 0;
+ }
+ DEVICE_ATTR(dump_host_state_1, S_IRUGO|S_IWUSR, sysfs_dump_host_state_show_1, 0);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_host_state_show_2( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_host_state_show_2( struct device *_dev,char *buf)
+ #endif
+ {
+ ifxhcd_dump_state(&ifxusb_hcd_2);
+ return 0;
+ }
+ DEVICE_ATTR(dump_host_state_2, S_IRUGO|S_IWUSR, sysfs_dump_host_state_show_2, 0);
+ #else
+ static ssize_t procfs_dump_host_state_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ ifxhcd_dump_state(&ifxusb_hcd);
+ return 0;
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_dump_host_state_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_dump_host_state_show( struct device *_dev,char *buf)
+ #endif
+ {
+ ifxhcd_dump_state(&ifxusb_hcd);
+ return 0;
+ }
+ DEVICE_ATTR(dump_host_state, S_IRUGO|S_IWUSR, sysfs_dump_host_state_show, 0);
+ #endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #endif //IS_HOST_
+
+#endif //__ENABLE_DUMP__
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef __IS_HOST__
+ static void host_probe(unsigned long _ptr)
+ {
+ ifxhcd_hcd_t *ifxhcd = (ifxhcd_hcd_t *)_ptr;
+
+ if(ifxhcd->flags.b.port_connect_status)
+ {
+ del_timer(&ifxhcd->host_probe_timer);
+ del_timer(&ifxhcd->autoprobe_timer);
+ ifxhcd->power_status = 0;
+ }
+ else
+ {
+ del_timer(&ifxhcd->autoprobe_timer);
+ ifxhcd->autoprobe_timer.expires = jiffies + (HZ*ifxhcd->autoprobe_sec);
+ add_timer(&ifxhcd->autoprobe_timer);
+ ifxhcd->power_status = 2;
+ del_timer(&ifxhcd->host_probe_timer);
+ do_suspend_h(&ifxhcd->core_if);
+ }
+ }
+
+ static void host_autoprobe(unsigned long _ptr)
+ {
+ ifxhcd_hcd_t *ifxhcd = (ifxhcd_hcd_t *)_ptr;
+ del_timer(&ifxhcd->host_probe_timer);
+ ifxhcd->host_probe_timer.function = host_probe;
+ ifxhcd->host_probe_timer.expires = jiffies + (HZ*ifxhcd->probe_sec);
+ ifxhcd->host_probe_timer.data = (unsigned long)ifxhcd;
+ add_timer(&ifxhcd->host_probe_timer);
+ do_resume_h(&ifxhcd->core_if);
+ }
+
+ static void suspend_host_store(ifxhcd_hcd_t *ifxhcd , uint32_t value)
+ {
+ if(value==2)
+ {
+ del_timer(&ifxhcd->autoprobe_timer);
+ ifxhcd->autoprobe_timer.function = host_autoprobe;
+ ifxhcd->autoprobe_timer.expires = jiffies + (HZ*ifxhcd->autoprobe_sec);
+ ifxhcd->autoprobe_timer.data = (unsigned long)ifxhcd;
+ add_timer(&ifxhcd->autoprobe_timer);
+ ifxhcd->power_status = 2;
+ }
+ else if(value==1)
+ {
+ do_suspend_h(&ifxhcd->core_if);
+ ifxhcd->power_status = 1;
+ del_timer(&ifxhcd->host_probe_timer);
+ del_timer(&ifxhcd->autoprobe_timer);
+ }
+ else if(value==0)
+ {
+ do_resume_h(&ifxhcd->core_if);
+ ifxhcd->power_status = 0;
+ del_timer(&ifxhcd->host_probe_timer);
+ del_timer(&ifxhcd->autoprobe_timer);
+ }
+ }
+ #ifdef __IS_DUAL__
+ static ssize_t procfs_suspend_host_2_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ suspend_host_store(&ifxusb_hcd_2,value);
+ return count;
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_suspend_host_2_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_suspend_host_2_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ suspend_host_store(&ifxusb_hcd_2,value);
+ return count;
+ }
+
+ static ssize_t procfs_suspend_host_1_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ suspend_host_store(&ifxusb_hcd_1,value);
+ return count;
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_suspend_host_1_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_suspend_host_1_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ suspend_host_store(&ifxusb_hcd_1,value);
+ return count;
+ }
+ DEVICE_ATTR(suspend_host_2, S_IWUSR,NULL, sysfs_suspend_host_2_store);
+ DEVICE_ATTR(suspend_host_1, S_IWUSR,NULL, sysfs_suspend_host_1_store);
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+ #else
+ static ssize_t procfs_suspend_host_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ suspend_host_store(&ifxusb_hcd,value);
+ return count;
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_suspend_host_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_suspend_host_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ suspend_host_store(&ifxusb_hcd,value);
+ return count;
+ }
+ DEVICE_ATTR(suspend_host, S_IWUSR,NULL, sysfs_suspend_host_store);
+ #endif
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef __IS_HOST__
+ static void probe_host_store(ifxhcd_hcd_t *ifxhcd, uint32_t value)
+ {
+ if(ifxhcd->power_status == 1)
+ {
+ del_timer(&ifxhcd->host_probe_timer);
+ ifxhcd->host_probe_timer.function = host_probe;
+ ifxhcd->host_probe_timer.expires = jiffies + (HZ*ifxhcd->probe_sec);
+ ifxhcd->host_probe_timer.data = (unsigned long) ifxhcd;
+ add_timer(&ifxhcd->host_probe_timer);
+ do_resume_h(&ifxhcd->core_if);
+ }
+ }
+ #ifdef __IS_DUAL__
+ static ssize_t probe_host_2_show(char *buf)
+ {
+ if(ifxusb_hcd_2.power_status == 0)
+ return sprintf (buf,"Host 2 power status is ON\n");
+ else if(ifxusb_hcd_2.power_status == 1)
+ return sprintf (buf,"Host 2 power status is Suspend\n");
+ else
+ return sprintf (buf,"Host 2 power status is Auto-probing\n");
+ }
+ static ssize_t probe_host_1_show(char *buf)
+ {
+ if(ifxusb_hcd_1.power_status == 0)
+ return sprintf (buf,"Host 1 power status is ON\n");
+ else if(ifxusb_hcd_1.power_status == 1)
+ return sprintf (buf,"Host 1 power status is Suspend\n");
+ else
+ return sprintf (buf,"Host 1 power status is Auto-probing\n");
+ }
+ static ssize_t procfs_probe_host_2_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ probe_host_store(&ifxusb_hcd_2,value);
+ return count;
+ }
+ static ssize_t procfs_probe_host_2_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return probe_host_2_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_host_2_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_probe_host_2_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return probe_host_2_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_host_2_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_probe_host_2_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ probe_host_store(&ifxusb_hcd_2,value);
+ return count;
+ }
+
+ static ssize_t procfs_probe_host_1_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ probe_host_store(&ifxusb_hcd_1,value);
+ return count;
+ }
+ static ssize_t procfs_probe_host_1_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return probe_host_1_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_host_1_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_probe_host_1_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return probe_host_1_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_host_1_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_probe_host_1_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ probe_host_store(&ifxusb_hcd_1,value);
+ return count;
+ }
+ DEVICE_ATTR(probe_host_2, S_IRUGO|S_IWUSR, sysfs_probe_host_2_show, sysfs_probe_host_2_store);
+ DEVICE_ATTR(probe_host_1, S_IRUGO|S_IWUSR, sysfs_probe_host_1_show, sysfs_probe_host_1_store);
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+ #else
+ static ssize_t probe_host_show(char *buf)
+ {
+ if(ifxusb_hcd.power_status == 0)
+ return sprintf (buf,"Host power status is ON\n");
+ else if(ifxusb_hcd.power_status == 1)
+ return sprintf (buf,"Host power status is Suspend\n");
+ else
+ return sprintf (buf,"Host power status is Auto-probing\n");
+ }
+ static ssize_t procfs_probe_host_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ probe_host_store(&ifxusb_hcd,value);
+ return count;
+ }
+ static ssize_t procfs_probe_host_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return probe_host_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_host_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_probe_host_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return probe_host_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_host_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_probe_host_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ probe_host_store(&ifxusb_hcd,value);
+ return count;
+ }
+ DEVICE_ATTR(probe_host, S_IRUGO|S_IWUSR, sysfs_probe_host_show, sysfs_probe_host_store);
+ #endif
+#endif
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef __IS_DEVICE__
+ static void device_probe(unsigned long _ptr)
+ {
+ if(ifxusb_pcd.power_status == 2)
+ {
+ del_timer(&ifxusb_pcd.device_autoprobe_timer);
+ ifxusb_pcd.device_autoprobe_timer.expires = jiffies + (HZ*ifxusb_pcd.autoprobe_sec);
+ add_timer(&ifxusb_pcd.device_autoprobe_timer);
+ ifxusb_pcd.power_status = 2;
+ do_suspend_d(&ifxusb_pcd.core_if);
+ }
+ else if(ifxusb_pcd.power_status == 1)
+ {
+ do_suspend_d(&ifxusb_pcd.core_if);
+ ifxusb_pcd.power_status = 1;
+ }
+ }
+ static void device_autoprobe(unsigned long _ptr)
+ {
+ init_timer(&ifxusb_pcd.device_probe_timer);
+ ifxusb_pcd.device_probe_timer.function = device_probe;
+ ifxusb_pcd.device_probe_timer.expires = jiffies + (HZ*ifxusb_pcd.probe_sec);
+ add_timer(&ifxusb_pcd.device_probe_timer);
+ do_resume_d(&ifxusb_pcd.core_if);
+ }
+ static void suspend_device_store(uint32_t value)
+ {
+ if(value==2)
+ {
+ del_timer(&ifxusb_pcd.device_autoprobe_timer);
+ ifxusb_pcd.device_autoprobe_timer.function = device_autoprobe;
+ ifxusb_pcd.device_autoprobe_timer.expires = jiffies + (HZ*ifxusb_pcd.autoprobe_sec);
+ add_timer(&ifxusb_pcd.device_autoprobe_timer);
+ ifxusb_pcd.power_status = 2;
+ }
+ else if(value==1)
+ {
+ do_suspend_d(&ifxusb_pcd.core_if);
+ ifxusb_pcd.power_status = 1;
+ del_timer(&ifxusb_pcd.device_autoprobe_timer);
+ del_timer(&ifxusb_pcd.device_probe_timer);
+ }
+ else if(value==0)
+ {
+ do_resume_d(&ifxusb_pcd.core_if);
+ ifxusb_pcd.power_status = 0;
+ del_timer(&ifxusb_pcd.device_autoprobe_timer);
+ del_timer(&ifxusb_pcd.device_probe_timer);
+ }
+ }
+ static ssize_t procfs_suspend_device_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ suspend_device_store(value);
+ return count;
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_suspend_device_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_suspend_device_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ suspend_device_store(value);
+ return count;
+ }
+ DEVICE_ATTR(suspend_device, S_IWUSR,NULL,sysfs_suspend_device_store);
+#endif
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef __IS_DEVICE__
+ static ssize_t probe_device_show(char *buf)
+ {
+ if(ifxusb_pcd.power_status == 0)
+ return sprintf (buf,"Device power status is ON\n");
+ else if(ifxusb_pcd.power_status == 1)
+ return sprintf (buf,"Device power status is Suspend\n");
+ else
+ return printk(buf,"Device power status is Auto-probing\n");
+ }
+ static void probe_device_store(uint32_t value)
+ {
+
+ if(ifxusb_pcd.power_status == 1)
+ {
+ del_timer(&ifxusb_pcd.device_probe_timer);
+ ifxusb_pcd.device_probe_timer.function = device_probe;
+ ifxusb_pcd.device_probe_timer.expires = jiffies + (HZ*ifxusb_pcd.probe_sec);
+ add_timer(&ifxusb_pcd.device_probe_timer);
+ do_resume_d(&ifxusb_pcd.core_if);
+ }
+ }
+ static ssize_t procfs_probe_device_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ probe_device_store(value);
+ return count;
+ }
+ static ssize_t procfs_probe_device_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return probe_device_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_device_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_probe_device_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return probe_device_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_device_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_probe_device_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ probe_device_store(value);
+ return count;
+ }
+ DEVICE_ATTR(probe_device, S_IRUGO|S_IWUSR, sysfs_probe_device_show, sysfs_probe_device_store);
+#endif
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ static ssize_t autoprobe_timer2_val_show(char *buf)
+ {
+ return sprintf (buf,"Host 2 auto-probe timer is %d second\n",ifxusb_hcd_2.autoprobe_sec);
+ }
+ static ssize_t procfs_autoprobe_timer2_val_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 300))
+ ifxusb_hcd_2.autoprobe_sec = value;
+ return count;
+ }
+ static ssize_t procfs_autoprobe_timer2_val_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return autoprobe_timer2_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_autoprobe_timer2_val_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_autoprobe_timer2_val_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return autoprobe_timer2_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_autoprobe_timer2_val_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_autoprobe_timer2_val_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 300))
+ ifxusb_hcd_2.autoprobe_sec = value;
+ return count;
+ }
+
+ static ssize_t autoprobe_timer1_val_show(char *buf)
+ {
+ return sprintf (buf,"Host 1 auto-probe timer is %d second\n",ifxusb_hcd_1.autoprobe_sec);
+ }
+ static ssize_t procfs_autoprobe_timer1_val_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 300))
+ ifxusb_hcd_1.autoprobe_sec = value;
+ return count;
+ }
+ static ssize_t procfs_autoprobe_timer1_val_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return autoprobe_timer1_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_autoprobe_timer1_val_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_autoprobe_timer1_val_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return autoprobe_timer1_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_autoprobe_timer1_val_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_autoautoprobe_timer1_val_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 300))
+ ifxusb_hcd_1.autoprobe_sec = value;
+ return count;
+ }
+
+ static ssize_t probe_timer2_val_show(char *buf)
+ {
+ return sprintf (buf,"Host 2 probe timer is %d second\n",ifxusb_hcd_2.probe_sec);
+ }
+ static ssize_t procfs_probe_timer2_val_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 10))
+ ifxusb_hcd_2.probe_sec = value;
+ return count;
+ }
+ static ssize_t procfs_probe_timer2_val_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return probe_timer2_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_timer2_val_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_probe_timer2_val_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return probe_timer2_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_timer2_val_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_probe_timer2_val_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 10))
+ ifxusb_hcd_2.probe_sec = value;
+ return count;
+ }
+
+ static ssize_t probe_timer1_val_show(char *buf)
+ {
+ return sprintf (buf,"Host 1 probe timer is %d second\n",ifxusb_hcd_1.probe_sec);
+ }
+ static ssize_t procfs_probe_timer1_val_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 10))
+ ifxusb_hcd_1.probe_sec = value;
+ return count;
+ }
+ static ssize_t procfs_probe_timer1_val_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return probe_timer1_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_timer1_val_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_probe_timer1_val_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return probe_timer1_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_timer1_val_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_probe_timer1_val_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 10))
+ ifxusb_hcd_1.probe_sec = value;
+ return count;
+ }
+ DEVICE_ATTR(probe_timer1_val_h, S_IRUGO|S_IWUSR, sysfs_probe_timer1_val_show, sysfs_probe_timer1_val_store);
+ DEVICE_ATTR(probe_timer2_val_h, S_IRUGO|S_IWUSR, sysfs_probe_timer2_val_show, sysfs_probe_timer2_val_store);
+ DEVICE_ATTR(autoprobe_timer1_val_h, S_IRUGO|S_IWUSR, sysfs_autoprobe_timer1_val_show, sysfs_autoprobe_timer1_val_store);
+ DEVICE_ATTR(autoprobe_timer2_val_h, S_IRUGO|S_IWUSR, sysfs_autoprobe_timer2_val_show, sysfs_autoprobe_timer2_val_store);
+ #else
+ static ssize_t autoprobe_timer_val_show(char *buf)
+ {
+ return sprintf (buf,"Host auto-probe timer is %d second\n",ifxusb_hcd.autoprobe_sec);
+ }
+ static ssize_t procfs_autoprobe_timer_val_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 300))
+ ifxusb_hcd.autoprobe_sec = value;
+ return count;
+ }
+ static ssize_t procfs_autoprobe_timer_val_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return autoprobe_timer_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_autoprobe_timer_val_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_autoprobe_timer_val_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return autoprobe_timer_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_autoprobe_timer_val_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_autoautoprobe_timer_val_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 300))
+ ifxusb_hcd.autoprobe_sec = value;
+ return count;
+ }
+ static ssize_t probe_timer_val_show(char *buf)
+ {
+ return sprintf (buf,"Host probe timer is %d second\n",ifxusb_hcd.probe_sec);
+ }
+ static ssize_t procfs_probe_timer_val_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 10))
+ ifxusb_hcd.probe_sec = value;
+ return count;
+ }
+ static ssize_t procfs_probe_timer_val_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return probe_timer_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_timer_val_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_probe_timer_val_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return probe_timer_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_timer_val_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_probe_timer_val_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 10))
+ ifxusb_hcd.probe_sec = value;
+ return count;
+ }
+ DEVICE_ATTR(probe_timer_val_h, S_IRUGO|S_IWUSR, sysfs_probe_timer_val_show, sysfs_probe_timer_val_store);
+ DEVICE_ATTR(autoprobe_timer_val_h, S_IRUGO|S_IWUSR, sysfs_autoprobe_timer_val_show, sysfs_autoprobe_timer_val_store);
+ #endif
+#endif
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef __IS_DEVICE__
+ static ssize_t autoprobe_timer_val_show(char *buf)
+ {
+ return sprintf (buf,"Device auto-probe timer is %d second\n",ifxusb_pcd.autoprobe_sec);
+ }
+ static ssize_t procfs_autoprobe_timer_val_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 300))
+ ifxusb_pcd.autoprobe_sec = value;
+ return count;
+ }
+ static ssize_t procfs_autoprobe_timer_val_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return autoprobe_timer_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_autoprobe_timer_val_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_autoprobe_timer_val_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return autoprobe_timer_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_autoprobe_timer_val_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_autoautoprobe_timer_val_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 300))
+ ifxusb_pcd.autoprobe_sec = value;
+ return count;
+ }
+ static ssize_t probe_timer_val_show(char *buf)
+ {
+ return sprintf (buf,"Device probe timer is %d second\n",ifxusb_pcd.probe_sec);
+ }
+ static ssize_t procfs_probe_timer_val_store(struct file *file, const char *buffer, unsigned long count, void *data)
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 10))
+ ifxusb_pcd.probe_sec = value;
+ return count;
+ }
+ static ssize_t procfs_probe_timer_val_show(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+ {
+ return probe_timer_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_timer_val_show( struct device *_dev, struct device_attribute *attr,char *buf)
+ #else
+ static ssize_t sysfs_probe_timer_val_show( struct device *_dev, char *buf)
+ #endif
+ {
+ return probe_timer_val_show(buf);
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ static ssize_t sysfs_probe_timer_val_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count )
+ #else
+ static ssize_t sysfs_probe_timer_val_store( struct device *_dev, const char *buffer, size_t count )
+ #endif
+ {
+ char buf[10];
+ int i = 0;
+ uint32_t value;
+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1))
+ return -EFAULT;
+ value = simple_strtoul(buf, NULL, 10);
+ if((value > 0)&&(value < 10))
+ ifxusb_pcd.probe_sec = value;
+ return count;
+ }
+ DEVICE_ATTR(probe_timer_val_d, S_IRUGO|S_IWUSR, sysfs_probe_timer_val_show, sysfs_probe_timer_val_store);
+ DEVICE_ATTR(autoprobe_timer_val_d, S_IRUGO|S_IWUSR, sysfs_autoprobe_timer_val_show, sysfs_autoprobe_timer_val_store);
+#endif
+//////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+
+static int ifx_proc_addproc(char *funcname, read_proc_t *hookfuncr, write_proc_t *hookfuncw);
+static void ifx_proc_delproc(char *funcname);
+
+//////////////////////////////////////////////////////////////////////////////////
+
+#if defined(__IS_HOST__) && defined(__HOST_COC__)
+ #ifdef __IS_DUAL__
+ static IFX_PMCU_MODULE_DEP_t depListUSBHost_1=
+ {
+ 1,
+ {
+ {IFX_PMCU_MODULE_CPU, IFX_PMCU_STATE_D0, IFX_PMCU_STATE_D0D3, IFX_PMCU_STATE_D0D3, IFX_PMCU_STATE_D0D3}
+ }
+ };
+ static IFX_PMCU_MODULE_DEP_t depListUSBHost_2=
+ {
+ 1,
+ {
+ {IFX_PMCU_MODULE_CPU, IFX_PMCU_STATE_D0, IFX_PMCU_STATE_D0D3, IFX_PMCU_STATE_D0D3, IFX_PMCU_STATE_D0D3}
+ }
+ };
+ // This functions returns the current power state of the module
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_stateGet_1(IFX_PMCU_STATE_t *pmcuModState) {
+ printk(KERN_DEBUG "ifx_usbhost_stateGet_1 is called\n");
+ if(ifxusb_hcd_1.power_status == 0){
+ printk(KERN_DEBUG "current power state of USB Host #1 is D0\n");
+ *pmcuModState = IFX_PMCU_STATE_D0; // set here the right value
+ }
+ else if(ifxusb_hcd_1.power_status == 1){
+ printk(KERN_DEBUG "current power state of USB Host #1 is D3 (Suspend)\n");
+ *pmcuModState = IFX_PMCU_STATE_D3; // set here the right value
+ }
+ else if(ifxusb_hcd_1.power_status == 2){
+ printk(KERN_DEBUG "current power state of USB Host #1 is D3 (Auto-Probing)\n");
+ *pmcuModState = IFX_PMCU_STATE_D3; // set here the right value
+ }
+ else{
+ printk(KERN_DEBUG "current power state of USB Host #1 is unknown (%d)\n",ifxusb_hcd_1.power_status);
+ *pmcuModState = IFX_PMCU_STATE_INVALID; // must be set to INVALID
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_stateGet_2(IFX_PMCU_STATE_t *pmcuModState) {
+ printk(KERN_DEBUG "ifx_usbhost_stateGet_2 is called\n");
+ if(ifxusb_hcd_2.power_status == 0){
+ printk(KERN_DEBUG "current power state of USB Host #2 is D0\n");
+ *pmcuModState = IFX_PMCU_STATE_D0; // set here the right value
+ }
+ else if(ifxusb_hcd_2.power_status == 1){
+ printk(KERN_DEBUG "current power state of USB Host #2 is D3 (Suspend)\n");
+ *pmcuModState = IFX_PMCU_STATE_D3; // set here the right value
+ }
+ else if(ifxusb_hcd_2.power_status == 2){
+ printk(KERN_DEBUG "current power state of USB Host #2 is D3 (Auto-Probing)\n");
+ *pmcuModState = IFX_PMCU_STATE_D3; // set here the right value
+ }
+ else{
+ printk(KERN_DEBUG "current power state of USB Host #2 is unknown (%d)\n",ifxusb_hcd_2.power_status);
+ *pmcuModState = IFX_PMCU_STATE_INVALID; // must be set to INVALID
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+
+
+ // The function should be used to enable/disable the module specific power saving methods
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_pwrFeatureSwitch_1(IFX_PMCU_PWR_STATE_ENA_t pmcuPwrStateEna)
+ {
+ if (pmcuPwrStateEna == IFX_PMCU_PWR_STATE_ON) {
+ suspend_host_store(&ifxusb_hcd_1, 0);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (pmcuPwrStateEna == IFX_PMCU_PWR_STATE_OFF) {
+ suspend_host_store(&ifxusb_hcd_1, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_pwrFeatureSwitch_2(IFX_PMCU_PWR_STATE_ENA_t pmcuPwrStateEna)
+ {
+ if (pmcuPwrStateEna == IFX_PMCU_PWR_STATE_ON) {
+ suspend_host_store(&ifxusb_hcd_2, 0);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (pmcuPwrStateEna == IFX_PMCU_PWR_STATE_OFF) {
+ suspend_host_store(&ifxusb_hcd_2, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+
+ // This function should be used to do all the necessary clean-up's before a the real
+ // power state change is initiated; e.g. flush all serial buffers inside the UART before
+ // the frequency will be changed.
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_preChange_1(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
+ {
+ printk(KERN_DEBUG "ifx_usbhost_preChange_1 is called\n");
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_preChange_2(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
+ {
+ printk(KERN_DEBUG "ifx_usbhost_preChange_2 is called\n");
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+
+
+ // This function initiate the real power state change. The module should do all the necessary
+ // adpations to the new state.
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_stateChange_1(IFX_PMCU_STATE_t newState)
+ {
+ printk(KERN_DEBUG "ifx_usbhost_stateChange_1 is called\n");
+ if (newState == IFX_PMCU_STATE_D0) {
+ suspend_host_store(&ifxusb_hcd_1, 0);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D1) {
+ suspend_host_store(&ifxusb_hcd_1, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D2) {
+ suspend_host_store(&ifxusb_hcd_1, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D3) {
+ suspend_host_store(&ifxusb_hcd_1, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_stateChange_2(IFX_PMCU_STATE_t newState)
+ {
+ printk(KERN_DEBUG "ifx_usbhost_stateChange_2 is called\n");
+ if (newState == IFX_PMCU_STATE_D0) {
+ suspend_host_store(&ifxusb_hcd_2, 0);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D1) {
+ suspend_host_store(&ifxusb_hcd_2, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D2) {
+ suspend_host_store(&ifxusb_hcd_2, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D3) {
+ suspend_host_store(&ifxusb_hcd_2, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+
+ // This function should be used to do all the necessary post processing after a the real
+ // power state change was initiated.
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_postChange_1(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
+ {
+ printk(KERN_DEBUG "ifx_usbhost_postChange_1 is called\n");
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_postChange_2(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
+ {
+ printk(KERN_DEBUG "ifx_usbhost_postChange_2 is called\n");
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ #else
+ static IFX_PMCU_MODULE_DEP_t depListUSBHost=
+ {
+ 1,
+ {
+ {IFX_PMCU_MODULE_CPU, IFX_PMCU_STATE_D0, IFX_PMCU_STATE_D0D3, IFX_PMCU_STATE_D0D3, IFX_PMCU_STATE_D0D3}
+ }
+ };
+ // This functions returns the current power state of the module
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_stateGet(IFX_PMCU_STATE_t *pmcuModState) {
+ printk(KERN_DEBUG "ifx_usbhost_stateGet is called\n");
+ if(ifxusb_hcd.power_status == 0){
+ printk(KERN_DEBUG "current power state of USB Host is D0\n");
+ *pmcuModState = IFX_PMCU_STATE_D0; // set here the right value
+ }
+ else if(ifxusb_hcd.power_status == 1){
+ printk(KERN_DEBUG "current power state of USB Host is D3 (Suspend)\n");
+ *pmcuModState = IFX_PMCU_STATE_D3; // set here the right value
+ }
+ else if(ifxusb_hcd.power_status == 2){
+ printk(KERN_DEBUG "current power state of USB Host is D3 (Auto-Probing)\n");
+ *pmcuModState = IFX_PMCU_STATE_D3; // set here the right value
+ }
+ else{
+ printk(KERN_DEBUG "current power state of USB Host is unknown (%d)\n",ifxusb_hcd.power_status);
+ *pmcuModState = IFX_PMCU_STATE_INVALID; // must be set to INVALID
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ // The function should be used to enable/disable the module specific power saving methods
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_pwrFeatureSwitch(IFX_PMCU_PWR_STATE_ENA_t pmcuPwrStateEna)
+ {
+ if (pmcuPwrStateEna == IFX_PMCU_PWR_STATE_ON) {
+ suspend_host_store(&ifxusb_hcd, 0);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (pmcuPwrStateEna == IFX_PMCU_PWR_STATE_OFF) {
+ suspend_host_store(&ifxusb_hcd, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+
+ // This function should be used to do all the necessary clean-up's before a the real
+ // power state change is initiated; e.g. flush all serial buffers inside the UART before
+ // the frequency will be changed.
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_preChange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
+ {
+ printk(KERN_DEBUG "ifx_usbhost_preChange is called\n");
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+
+
+ // This function initiate the real power state change. The module should do all the necessary
+ // adpations to the new state.
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_stateChange(IFX_PMCU_STATE_t newState)
+ {
+ printk(KERN_DEBUG "ifx_usbhost_stateChange is called\n");
+ if (newState == IFX_PMCU_STATE_D0) {
+ suspend_host_store(&ifxusb_hcd, 0);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D1) {
+ suspend_host_store(&ifxusb_hcd, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D2) {
+ suspend_host_store(&ifxusb_hcd, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D3) {
+ suspend_host_store(&ifxusb_hcd, 1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+
+ // This function should be used to do all the necessary post processing after a the real
+ // power state change was initiated.
+ static IFX_PMCU_RETURN_t
+ ifx_usbhost_postChange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
+ {
+ printk(KERN_DEBUG "ifx_usbhost_postChange is called\n");
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ #endif
+#endif
+#if defined(__IS_DEVICE__) && defined(__GADGET_COC__)
+ static IFX_PMCU_MODULE_DEP_t depListUSBGadget=
+ {
+ 1,
+ {
+ {IFX_PMCU_MODULE_CPU, IFX_PMCU_STATE_D0, IFX_PMCU_STATE_D0D3, IFX_PMCU_STATE_D0D3, IFX_PMCU_STATE_D0D3}
+ }
+ };
+ // This functions returns the current power state of the module
+ static IFX_PMCU_RETURN_t
+ ifx_usbgadget_stateGet(IFX_PMCU_STATE_t *pmcuModState) {
+ printk(KERN_DEBUG "ifx_usbgadget_stateGet is called\n");
+ if(ifxusb_pcd.power_status == 0){
+ printk(KERN_DEBUG "current power state of USB Gadget is D0\n");
+ *pmcuModState = IFX_PMCU_STATE_D0; // set here the right value
+ }
+ else if(ifxusb_pcd.power_status == 1){
+ printk(KERN_DEBUG "current power state of USB Gadget is D3 (Suspend)\n");
+ *pmcuModState = IFX_PMCU_STATE_D3; // set here the right value
+ }
+ else if(ifxusb_pcd.power_status == 2){
+ printk(KERN_DEBUG "current power state of USB Gadget is D3 (Auto-Probing)\n");
+ *pmcuModState = IFX_PMCU_STATE_D3; // set here the right value
+ }
+ else{
+ printk(KERN_DEBUG "current power state of USB Gadget is unknown (%d)\n",ifxusb_pcd.power_status);
+ *pmcuModState = IFX_PMCU_STATE_INVALID; // must be set to INVALID
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ // The function should be used to enable/disable the module specific power saving methods
+ static IFX_PMCU_RETURN_t
+ ifx_usbgadget_pwrFeatureSwitch(IFX_PMCU_PWR_STATE_ENA_t pmcuPwrStateEna)
+ {
+ if (pmcuPwrStateEna == IFX_PMCU_PWR_STATE_ON) {
+ suspend_device_store(0);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (pmcuPwrStateEna == IFX_PMCU_PWR_STATE_OFF) {
+ suspend_device_store(1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+
+ // This function should be used to do all the necessary clean-up's before a the real
+ // power state change is initiated; e.g. flush all serial buffers inside the UART before
+ // the frequency will be changed.
+ static IFX_PMCU_RETURN_t
+ ifx_usbgadget_preChange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
+ {
+ printk(KERN_DEBUG "ifx_usbgadget_preChange is called\n");
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+
+
+ // This function initiate the real power state change. The module should do all the necessary
+ // adpations to the new state.
+ static IFX_PMCU_RETURN_t
+ ifx_usbgadget_stateChange(IFX_PMCU_STATE_t newState)
+ {
+ printk(KERN_DEBUG "ifx_usbgadget_stateChange is called\n");
+ if (newState == IFX_PMCU_STATE_D0) {
+ suspend_device_store(0);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D1) {
+ suspend_device_store(1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D2) {
+ suspend_device_store(1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ if (newState == IFX_PMCU_STATE_D3) {
+ suspend_device_store(1);
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+
+ // This function should be used to do all the necessary post processing after a the real
+ // power state change was initiated.
+ static IFX_PMCU_RETURN_t
+ ifx_usbgadget_postChange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
+ {
+ printk(KERN_DEBUG "ifx_usbgadget_postChange is called\n");
+ return IFX_PMCU_RETURN_SUCCESS;
+ }
+#endif
+
+
+/*!
+ \brief This function create the sysfs and procfs entries
+ \param[in] _dev Pointer of device structure, if applied
+ */
+#ifdef __IS_HOST__
+void ifxusb_attr_create_h (void *_dev)
+#else
+void ifxusb_attr_create_d (void *_dev)
+#endif
+{
+ int error;
+
+ struct device *dev = (struct device *) _dev;
+
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+
+ error = ifx_proc_addproc("dbglevel", procfs_dbglevel_show, procfs_dbglevel_store);
+ #ifdef __IS_HOST__
+ error = device_create_file(dev, &dev_attr_dbglevel_h);
+ #else
+ error = device_create_file(dev, &dev_attr_dbglevel_d);
+ #endif
+
+ #ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ error = ifx_proc_addproc("dump_params_1", procfs_dump_params_show_1, NULL);
+ error = ifx_proc_addproc("dump_params_2", procfs_dump_params_show_2, NULL);
+ error = device_create_file(dev, &dev_attr_dump_params_h_1);
+ error = device_create_file(dev, &dev_attr_dump_params_h_2);
+
+ error = ifx_proc_addproc("mode_1", procfs_mode_show_1, NULL);
+ error = ifx_proc_addproc("mode_2", procfs_mode_show_2, NULL);
+ error = device_create_file(dev, &dev_attr_mode_h_1);
+ error = device_create_file(dev, &dev_attr_mode_h_2);
+ #else
+ error = ifx_proc_addproc("dump_params", procfs_dump_params_show, NULL);
+ error = device_create_file(dev, &dev_attr_dump_params_h);
+ error = ifx_proc_addproc("mode", procfs_mode_show, NULL);
+ error = device_create_file(dev, &dev_attr_mode_h);
+ #endif
+ #else
+ error = ifx_proc_addproc("dump_params", procfs_dump_params_show, NULL);
+ error = device_create_file(dev, &dev_attr_dump_params_d);
+
+ error = ifx_proc_addproc("mode", procfs_mode_show, NULL);
+ error = device_create_file(dev, &dev_attr_mode_d);
+ #endif
+
+ #ifdef __IS_HOST__
+ error = ifx_proc_addproc("version", procfs_version_show, NULL);
+ error = device_create_file(dev, &dev_attr_version_h);
+ #else
+ error = ifx_proc_addproc("version", procfs_version_show, NULL);
+ error = device_create_file(dev, &dev_attr_version_d);
+ #endif
+
+
+ #ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ error = ifx_proc_addproc("pkt_count_limit_bi_1", procfs_pkt_count_limit_bi_show_1, procfs_pkt_count_limit_bi_store_1);
+ error = ifx_proc_addproc("pkt_count_limit_bo_1", procfs_pkt_count_limit_bo_show_1, procfs_pkt_count_limit_bo_store_1);
+ error = ifx_proc_addproc("pkt_count_limit_bi_2", procfs_pkt_count_limit_bi_show_2, procfs_pkt_count_limit_bi_store_2);
+ error = ifx_proc_addproc("pkt_count_limit_bo_2", procfs_pkt_count_limit_bo_show_2, procfs_pkt_count_limit_bo_store_2);
+ error = ifx_proc_addproc("bandwidth_hs_1", procfs_bandwidth_hs_show_1, procfs_bandwidth_hs_store_1);
+ error = ifx_proc_addproc("bandwidth_fs_1", procfs_bandwidth_fs_show_1, procfs_bandwidth_fs_store_1);
+ error = ifx_proc_addproc("bandwidth_ls_1", procfs_bandwidth_ls_show_1, procfs_bandwidth_ls_store_1);
+ error = ifx_proc_addproc("bandwidth_hs_2", procfs_bandwidth_hs_show_2, procfs_bandwidth_hs_store_2);
+ error = ifx_proc_addproc("bandwidth_fs_2", procfs_bandwidth_fs_show_2, procfs_bandwidth_fs_store_2);
+ error = ifx_proc_addproc("bandwidth_ls_2", procfs_bandwidth_ls_show_2, procfs_bandwidth_ls_store_2);
+ error = device_create_file(dev, &dev_attr_pkt_count_limit_bi_1);
+ error = device_create_file(dev, &dev_attr_pkt_count_limit_bo_1);
+ error = device_create_file(dev, &dev_attr_pkt_count_limit_bi_2);
+ error = device_create_file(dev, &dev_attr_pkt_count_limit_bo_2);
+ error = device_create_file(dev, &dev_attr_bandwidth_hs_1);
+ error = device_create_file(dev, &dev_attr_bandwidth_fs_1);
+ error = device_create_file(dev, &dev_attr_bandwidth_ls_1);
+ error = device_create_file(dev, &dev_attr_bandwidth_hs_2);
+ error = device_create_file(dev, &dev_attr_bandwidth_fs_2);
+ error = device_create_file(dev, &dev_attr_bandwidth_ls_2);
+ #else
+ error = ifx_proc_addproc("pkt_count_limit_bi", procfs_pkt_count_limit_bi_show, procfs_pkt_count_limit_bi_store);
+ error = ifx_proc_addproc("pkt_count_limit_bo", procfs_pkt_count_limit_bo_show, procfs_pkt_count_limit_bo_store);
+ error = ifx_proc_addproc("bandwidth_hs", procfs_bandwidth_hs_show, procfs_bandwidth_hs_store);
+ error = ifx_proc_addproc("bandwidth_fs", procfs_bandwidth_fs_show, procfs_bandwidth_fs_store);
+ error = ifx_proc_addproc("bandwidth_ls", procfs_bandwidth_ls_show, procfs_bandwidth_ls_store);
+ error = device_create_file(dev, &dev_attr_pkt_count_limit_bi);
+ error = device_create_file(dev, &dev_attr_pkt_count_limit_bo);
+ error = device_create_file(dev, &dev_attr_bandwidth_hs);
+ error = device_create_file(dev, &dev_attr_bandwidth_fs);
+ error = device_create_file(dev, &dev_attr_bandwidth_ls);
+ #endif
+
+ #ifdef __IS_DUAL__
+ error = ifx_proc_addproc("buspower_1", procfs_buspower_show_1, procfs_buspower_store_1);
+ error = ifx_proc_addproc("buspower_2", procfs_buspower_show_2, procfs_buspower_store_2);
+ error = device_create_file(dev, &dev_attr_buspower_1);
+ error = device_create_file(dev, &dev_attr_buspower_2);
+ #else
+ error = ifx_proc_addproc("buspower", procfs_buspower_show, procfs_buspower_store);
+ error = device_create_file(dev, &dev_attr_buspower);
+ #endif
+
+ #ifdef __IS_DUAL__
+ error = ifx_proc_addproc("bussuspend_1", procfs_bussuspend_show_1, NULL);
+ error = ifx_proc_addproc("bussuspend_2", procfs_bussuspend_show_2, NULL);
+ error = device_create_file(dev, &dev_attr_bussuspend_1);
+ error = device_create_file(dev, &dev_attr_bussuspend_2);
+ #else
+ error = ifx_proc_addproc("bussuspend", procfs_bussuspend_show, NULL);
+ error = device_create_file(dev, &dev_attr_bussuspend);
+ #endif
+
+ #ifdef __IS_DUAL__
+ error = ifx_proc_addproc("busconnected_1", procfs_busconnected_show_1, NULL);
+ error = ifx_proc_addproc("busconnected_2", procfs_busconnected_show_2, NULL);
+ error = device_create_file(dev, &dev_attr_busconnected_1);
+ error = device_create_file(dev, &dev_attr_busconnected_2);
+ #else
+ error = ifx_proc_addproc("busconnected", procfs_busconnected_show, NULL);
+ error = device_create_file(dev, &dev_attr_busconnected);
+ #endif
+
+ #ifdef __IS_DUAL__
+ error = ifx_proc_addproc("connectspeed_1", procfs_connectspeed_show_1, NULL);
+ error = ifx_proc_addproc("connectspeed_2", procfs_connectspeed_show_2, NULL);
+ error = device_create_file(dev, &dev_attr_connectspeed_1);
+ error = device_create_file(dev, &dev_attr_connectspeed_2);
+ #else
+ error = ifx_proc_addproc("connectspeed", procfs_connectspeed_show, NULL);
+ error = device_create_file(dev, &dev_attr_connectspeed);
+ #endif
+ #endif
+
+ #ifdef __IS_DEVICE__
+ error = ifx_proc_addproc("devspeed", procfs_devspeed_show, NULL);
+ error = device_create_file(dev, &dev_attr_devspeed);
+ error = ifx_proc_addproc("enumspeed", procfs_enumspeed_show, NULL);
+ error = device_create_file(dev, &dev_attr_enumspeed);
+ #endif
+
+ //////////////////////////////////////////////////////
+ #ifdef __ENABLE_DUMP__
+
+ #ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ error = ifx_proc_addproc("dump_reg_1", procfs_dump_reg_show_1, NULL);
+ error = ifx_proc_addproc("dump_reg_2", procfs_dump_reg_show_2, NULL);
+ error = device_create_file(dev, &dev_attr_dump_reg_h_1);
+ error = device_create_file(dev, &dev_attr_dump_reg_h_2);
+ #else
+ error = ifx_proc_addproc("dump_reg", procfs_dump_reg_show, NULL);
+ error = device_create_file(dev, &dev_attr_dump_reg_h);
+ #endif
+
+ #ifdef __IS_DUAL__
+ error = ifx_proc_addproc("dump_spram_1", procfs_dump_spram_show_1, NULL);
+ error = ifx_proc_addproc("dump_spram_2", procfs_dump_spram_show_2, NULL);
+ error = device_create_file(dev, &dev_attr_dump_spram_h_1);
+ error = device_create_file(dev, &dev_attr_dump_spram_h_2);
+ #else
+ error = ifx_proc_addproc("dump_spram", procfs_dump_spram_show, NULL);
+ error = device_create_file(dev, &dev_attr_dump_spram_h);
+ #endif
+
+ #ifdef __IS_DUAL__
+ error = ifx_proc_addproc("dump_host_state_1", procfs_dump_host_state_show_1, NULL);
+ error = ifx_proc_addproc("dump_host_state_2", procfs_dump_host_state_show_2, NULL);
+ error = device_create_file(dev, &dev_attr_dump_host_state_1);
+ error = device_create_file(dev, &dev_attr_dump_host_state_2);
+ #else
+ error = ifx_proc_addproc("dump_host_state", procfs_dump_host_state_show, NULL);
+ error = device_create_file(dev, &dev_attr_dump_host_state);
+ #endif
+ #else
+ error = ifx_proc_addproc("dump_reg", procfs_dump_reg_show, NULL);
+ error = device_create_file(dev, &dev_attr_dump_reg_d);
+ error = ifx_proc_addproc("dump_spram", procfs_dump_spram_show, NULL);
+ error = device_create_file(dev, &dev_attr_dump_spram_d);
+ #endif
+ #endif //__ENABLE_DUMP__
+ //////////////////////////////////////////////////////
+#ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ error = ifx_proc_addproc("suspend_host_1",NULL, procfs_suspend_host_1_store);
+ error = device_create_file(dev, &dev_attr_suspend_host_1);
+
+ error = ifx_proc_addproc("probe_host_1", procfs_probe_host_1_show, procfs_probe_host_1_store);
+ error = device_create_file(dev, &dev_attr_probe_host_1);
+
+ error = ifx_proc_addproc("suspend_host_2",NULL, procfs_suspend_host_2_store);
+ error = device_create_file(dev, &dev_attr_suspend_host_2);
+
+ error = ifx_proc_addproc("probe_host_2", procfs_probe_host_2_show, procfs_probe_host_2_store);
+ error = device_create_file(dev, &dev_attr_probe_host_2);
+
+ error = ifx_proc_addproc("probe_timer1", procfs_probe_timer1_val_show, procfs_probe_timer1_val_store);
+ error = device_create_file(dev, &dev_attr_probe_timer1_val_h);
+
+ error = ifx_proc_addproc("probe_timer2", procfs_probe_timer2_val_show, procfs_probe_timer2_val_store);
+ error = device_create_file(dev, &dev_attr_probe_timer2_val_h);
+
+ error = ifx_proc_addproc("autoprobe_timer1", procfs_autoprobe_timer1_val_show, procfs_autoprobe_timer1_val_store);
+ error = device_create_file(dev, &dev_attr_autoprobe_timer1_val_h);
+
+ error = ifx_proc_addproc("autoprobe_timer2", procfs_autoprobe_timer2_val_show, procfs_autoprobe_timer2_val_store);
+ error = device_create_file(dev, &dev_attr_autoprobe_timer2_val_h);
+ #else
+ error = ifx_proc_addproc("suspend_host",NULL, procfs_suspend_host_store);
+ error = device_create_file(dev, &dev_attr_suspend_host);
+
+ error = ifx_proc_addproc("probe_host", procfs_probe_host_show, procfs_probe_host_store);
+ error = device_create_file(dev, &dev_attr_probe_host);
+
+ error = ifx_proc_addproc("probe_timer", procfs_probe_timer_val_show, procfs_probe_timer_val_store);
+ error = device_create_file(dev, &dev_attr_probe_timer_val_h);
+
+ error = ifx_proc_addproc("autoprobe_timer", procfs_autoprobe_timer_val_show, procfs_autoprobe_timer_val_store);
+ error = device_create_file(dev, &dev_attr_autoprobe_timer_val_h);
+ #endif
+#endif
+
+#ifdef __IS_DEVICE__
+ error = ifx_proc_addproc("suspend_device",NULL, procfs_suspend_device_store);
+ error = device_create_file(dev, &dev_attr_suspend_device);
+
+ error = ifx_proc_addproc("probe_device", procfs_probe_device_show, procfs_probe_device_store);
+ error = device_create_file(dev, &dev_attr_probe_device);
+
+ error = ifx_proc_addproc("probe_timer", procfs_probe_timer_val_show, procfs_probe_timer_val_store);
+ error = device_create_file(dev, &dev_attr_probe_timer_val_d);
+
+ error = ifx_proc_addproc("autoprobe_timer", procfs_autoprobe_timer_val_show, procfs_autoprobe_timer_val_store);
+ error = device_create_file(dev, &dev_attr_autoprobe_timer_val_d);
+#endif
+#if defined(__IS_HOST__) && defined(__HOST_COC__)
+ #ifdef __IS_DUAL__
+ memset (&pmcuRegisterUSBHost_1, 0, sizeof(pmcuRegisterUSBHost_1));
+ memset (&pmcuRegisterUSBHost_2, 0, sizeof(pmcuRegisterUSBHost_2));
+ pmcuRegisterUSBHost_1.pmcuModule=
+ pmcuRegisterUSBHost_2.pmcuModule=IFX_PMCU_MODULE_USB;
+ pmcuRegisterUSBHost_1.pmcuModuleNr=1;
+ pmcuRegisterUSBHost_2.pmcuModuleNr=2;
+ pmcuRegisterUSBHost_1.pmcuModuleDep = &depListUSBHost_1;
+ pmcuRegisterUSBHost_2.pmcuModuleDep = &depListUSBHost_2;
+ pmcuRegisterUSBHost_1.pre = ifx_usbhost_preChange_1;
+ pmcuRegisterUSBHost_2.pre = ifx_usbhost_preChange_2;
+ pmcuRegisterUSBHost_1.post = ifx_usbhost_postChange_1;
+ pmcuRegisterUSBHost_2.post = ifx_usbhost_postChange_2;
+ pmcuRegisterUSBHost_1.ifx_pmcu_state_change = ifx_usbhost_stateChange_1;
+ pmcuRegisterUSBHost_2.ifx_pmcu_state_change = ifx_usbhost_stateChange_2;
+ pmcuRegisterUSBHost_1.ifx_pmcu_state_get = ifx_usbhost_stateGet_1;
+ pmcuRegisterUSBHost_2.ifx_pmcu_state_get = ifx_usbhost_stateGet_2;
+ pmcuRegisterUSBHost_1.ifx_pmcu_pwr_feature_switch = ifx_usbhost_pwrFeatureSwitch_1;
+ pmcuRegisterUSBHost_2.ifx_pmcu_pwr_feature_switch = ifx_usbhost_pwrFeatureSwitch_2;
+ ifx_pmcu_register ( &pmcuRegisterUSBHost_1 );
+ ifx_pmcu_register ( &pmcuRegisterUSBHost_2 );
+ #else
+ memset (&pmcuRegisterUSBHost, 0, sizeof(pmcuRegisterUSBHost));
+ pmcuRegisterUSBHost.pmcuModule=IFX_PMCU_MODULE_USB;
+ pmcuRegisterUSBHost.pmcuModuleNr=1;
+ pmcuRegisterUSBHost.pmcuModuleDep = &depListUSBHost;
+ pmcuRegisterUSBHost.pre = ifx_usbhost_preChange;
+ pmcuRegisterUSBHost.post = ifx_usbhost_postChange;
+ pmcuRegisterUSBHost.ifx_pmcu_state_change = ifx_usbhost_stateChange;
+ pmcuRegisterUSBHost.ifx_pmcu_state_get = ifx_usbhost_stateGet;
+ pmcuRegisterUSBHost.ifx_pmcu_pwr_feature_switch = ifx_usbhost_pwrFeatureSwitch;
+ ifx_pmcu_register ( &pmcuRegisterUSBHost );
+ #endif
+#endif
+#if defined(__IS_DEVICE__) && defined(__GADGET_COC__)
+ memset (&pmcuRegisterUSBGadget, 0, sizeof(pmcuRegisterUSBGadget));
+ pmcuRegisterUSBGadget.pmcuModule=IFX_PMCU_MODULE_USB;
+ pmcuRegisterUSBGadget.pmcuModuleNr=0;
+ pmcuRegisterUSBGadget.pmcuModuleDep = &depListUSBGadget;
+ pmcuRegisterUSBGadget.pre = ifx_usbgadget_preChange;
+ pmcuRegisterUSBGadget.post = ifx_usbgadget_postChange;
+ pmcuRegisterUSBGadget.ifx_pmcu_state_change = ifx_usbgadget_stateChange;
+ pmcuRegisterUSBGadget.ifx_pmcu_state_get = ifx_usbgadget_stateGet;
+ pmcuRegisterUSBGadget.ifx_pmcu_pwr_feature_switch = ifx_usbgadget_pwrFeatureSwitch;
+ ifx_pmcu_register ( &pmcuRegisterUSBGadget );
+#endif
+}
+
+
+/*!
+ \brief This function remove the sysfs and procfs entries
+ \param[in] _dev Pointer of device structure, if applied
+ */
+#ifdef __IS_HOST__
+void ifxusb_attr_remove_h (void *_dev)
+#else
+void ifxusb_attr_remove_d (void *_dev)
+#endif
+{
+ struct device *dev = (struct device *) _dev;
+
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ ifx_proc_delproc("dbglevel");
+ #ifdef __IS_HOST__
+ device_remove_file(dev, &dev_attr_dbglevel_h);
+ #else
+ device_remove_file(dev, &dev_attr_dbglevel_d);
+ #endif
+
+ #ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ ifx_proc_delproc("dump_params_1");
+ ifx_proc_delproc("dump_params_2");
+ device_remove_file(dev, &dev_attr_dump_params_h_1);
+ device_remove_file(dev, &dev_attr_dump_params_h_2);
+ #else
+ ifx_proc_delproc("dump_params");
+ device_remove_file(dev, &dev_attr_dump_params_h);
+ #endif
+
+ #ifdef __IS_DUAL__
+ ifx_proc_delproc("mode_1");
+ ifx_proc_delproc("mode_2");
+ device_remove_file(dev, &dev_attr_mode_h_1);
+ device_remove_file(dev, &dev_attr_mode_h_2);
+ #else
+ ifx_proc_delproc("mode");
+ device_remove_file(dev, &dev_attr_mode_h);
+ #endif
+ #else
+ ifx_proc_delproc("dump_params");
+ device_remove_file(dev, &dev_attr_dump_params_d);
+ ifx_proc_delproc("mode");
+ device_remove_file(dev, &dev_attr_mode_d);
+ #endif
+
+ #ifdef __IS_HOST__
+ ifx_proc_delproc("version");
+ device_remove_file(dev, &dev_attr_version_h);
+ #else
+ ifx_proc_delproc("version");
+ device_remove_file(dev, &dev_attr_version_d);
+ #endif
+
+
+ #ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ ifx_proc_delproc("pkt_count_limit_bi_1");
+ ifx_proc_delproc("pkt_count_limit_bo_1");
+ ifx_proc_delproc("pkt_count_limit_bi_2");
+ ifx_proc_delproc("pkt_count_limit_bo_2");
+ ifx_proc_delproc("bandwidth_hs_1");
+ ifx_proc_delproc("bandwidth_fs_1");
+ ifx_proc_delproc("bandwidth_ls_1");
+ ifx_proc_delproc("bandwidth_hs_2");
+ ifx_proc_delproc("bandwidth_fs_2");
+ ifx_proc_delproc("bandwidth_ls_2");
+ device_remove_file(dev, &dev_attr_pkt_count_limit_bi_1);
+ device_remove_file(dev, &dev_attr_pkt_count_limit_bo_1);
+ device_remove_file(dev, &dev_attr_pkt_count_limit_bi_2);
+ device_remove_file(dev, &dev_attr_pkt_count_limit_bo_2);
+ device_remove_file(dev, &dev_attr_bandwidth_hs_1);
+ device_remove_file(dev, &dev_attr_bandwidth_fs_1);
+ device_remove_file(dev, &dev_attr_bandwidth_ls_1);
+ device_remove_file(dev, &dev_attr_bandwidth_hs_2);
+ device_remove_file(dev, &dev_attr_bandwidth_fs_2);
+ device_remove_file(dev, &dev_attr_bandwidth_ls_2);
+ #else
+ ifx_proc_delproc("pkt_count_limit_bi");
+ ifx_proc_delproc("pkt_count_limit_bo");
+ ifx_proc_delproc("bandwidth_hs");
+ ifx_proc_delproc("bandwidth_fs");
+ ifx_proc_delproc("bandwidth_ls");
+ device_remove_file(dev, &dev_attr_pkt_count_limit_bi);
+ device_remove_file(dev, &dev_attr_pkt_count_limit_bo);
+ device_remove_file(dev, &dev_attr_bandwidth_hs);
+ device_remove_file(dev, &dev_attr_bandwidth_fs);
+ device_remove_file(dev, &dev_attr_bandwidth_ls);
+ #endif
+ #endif
+
+ #ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ ifx_proc_delproc("buspower_1");
+ ifx_proc_delproc("buspower_2");
+ device_remove_file(dev, &dev_attr_buspower_1);
+ device_remove_file(dev, &dev_attr_buspower_2);
+ #else
+ ifx_proc_delproc("buspower");
+ device_remove_file(dev, &dev_attr_buspower);
+ #endif
+
+ #ifdef __IS_DUAL__
+ ifx_proc_delproc("bussuspend_1");
+ ifx_proc_delproc("bussuspend_2");
+ device_remove_file(dev, &dev_attr_bussuspend_1);
+ device_remove_file(dev, &dev_attr_bussuspend_2);
+ #else
+ ifx_proc_delproc("bussuspend");
+ device_remove_file(dev, &dev_attr_bussuspend);
+ #endif
+
+ #ifdef __IS_DUAL__
+ ifx_proc_delproc("busconnected_1");
+ ifx_proc_delproc("busconnected_2");
+ device_remove_file(dev, &dev_attr_busconnected_1);
+ device_remove_file(dev, &dev_attr_busconnected_2);
+ #else
+ ifx_proc_delproc("busconnected");
+ device_remove_file(dev, &dev_attr_busconnected);
+ #endif
+
+ #ifdef __IS_DUAL__
+ ifx_proc_delproc("connectspeed_1");
+ ifx_proc_delproc("connectspeed_2");
+ device_remove_file(dev, &dev_attr_connectspeed_1);
+ device_remove_file(dev, &dev_attr_connectspeed_2);
+ #else
+ ifx_proc_delproc("connectspeed");
+ device_remove_file(dev, &dev_attr_connectspeed);
+ #endif
+ #endif
+
+ #ifdef __IS_DEVICE__
+ ifx_proc_delproc("devspeed");
+ device_remove_file(dev, &dev_attr_devspeed);
+ ifx_proc_delproc("enumspeed");
+ device_remove_file(dev, &dev_attr_enumspeed);
+ #endif
+
+ #ifdef __ENABLE_DUMP__
+ #ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ ifx_proc_delproc("dump_reg_1");
+ ifx_proc_delproc("dump_reg_2");
+ device_remove_file(dev, &dev_attr_dump_reg_h_1);
+ device_remove_file(dev, &dev_attr_dump_reg_h_2);
+ #else
+ ifx_proc_delproc("dump_reg");
+ device_remove_file(dev, &dev_attr_dump_reg_h);
+ #endif
+
+ #ifdef __IS_DUAL__
+ ifx_proc_delproc("dump_spram_1");
+ ifx_proc_delproc("dump_spram_2");
+ device_remove_file(dev, &dev_attr_dump_spram_h_1);
+ device_remove_file(dev, &dev_attr_dump_spram_h_2);
+ #else
+ ifx_proc_delproc("dump_spram");
+ device_remove_file(dev, &dev_attr_dump_spram_h);
+ #endif
+
+ #ifdef __IS_DUAL__
+ ifx_proc_delproc("dump_host_state_1");
+ ifx_proc_delproc("dump_host_state_2");
+ device_remove_file(dev, &dev_attr_dump_host_state_1);
+ device_remove_file(dev, &dev_attr_dump_host_state_2);
+ #else
+ ifx_proc_delproc("dump_host_state");
+ device_remove_file(dev, &dev_attr_dump_host_state);
+ #endif
+ #else
+ ifx_proc_delproc("dump_reg");
+ device_remove_file(dev, &dev_attr_dump_reg_d);
+ ifx_proc_delproc("dump_spram");
+ device_remove_file(dev, &dev_attr_dump_spram_d);
+ #endif
+
+ #ifdef __IS_HOST__
+ #endif
+ #endif //__ENABLE_DUMP__
+#ifdef __IS_HOST__
+ #ifdef __IS_DUAL__
+ ifx_proc_delproc("suspend_host_1");
+ ifx_proc_delproc("probe_host_1");
+ device_remove_file(dev, &dev_attr_suspend_host_1);
+ device_remove_file(dev, &dev_attr_probe_host_1);
+ ifx_proc_delproc("suspend_host_2");
+ ifx_proc_delproc("probe_host_2");
+ device_remove_file(dev, &dev_attr_suspend_host_2);
+ device_remove_file(dev, &dev_attr_probe_host_2);
+ ifx_proc_delproc("probe_timer1");
+ ifx_proc_delproc("autoprobe_timer1");
+ device_remove_file(dev, &dev_attr_probe_timer1_val_h);
+ device_remove_file(dev, &dev_attr_autoprobe_timer1_val_h);
+ ifx_proc_delproc("probe_timer2");
+ ifx_proc_delproc("autoprobe_timer2");
+ device_remove_file(dev, &dev_attr_probe_timer2_val_h);
+ device_remove_file(dev, &dev_attr_autoprobe_timer2_val_h);
+ #else
+ ifx_proc_delproc("suspend_host");
+ ifx_proc_delproc("probe_host");
+ device_remove_file(dev, &dev_attr_suspend_host);
+ device_remove_file(dev, &dev_attr_probe_host);
+ ifx_proc_delproc("probe_timer");
+ ifx_proc_delproc("autoprobe_timer");
+ device_remove_file(dev, &dev_attr_probe_timer_val_h);
+ device_remove_file(dev, &dev_attr_autoprobe_timer_val_h);
+ #endif
+ remove_proc_entry(ifxusb_hcd_driver_name, (void *)0);
+#endif
+
+#ifdef __IS_DEVICE__
+ ifx_proc_delproc("suspend_device");
+ ifx_proc_delproc("probe_device");
+ device_remove_file(dev, &dev_attr_suspend_device);
+ device_remove_file(dev, &dev_attr_probe_device);
+ ifx_proc_delproc("probe_timer");
+ ifx_proc_delproc("autoprobe_timer");
+ device_remove_file(dev, &dev_attr_probe_timer_val_d);
+ device_remove_file(dev, &dev_attr_autoprobe_timer_val_d);
+ remove_proc_entry(ifxusb_pcd_driver_name, (void *)0);
+#endif
+#if defined(__IS_HOST__) && defined(__HOST_COC__)
+ #ifdef __IS_DUAL__
+ ifx_pmcu_unregister ( &pmcuRegisterUSBHost_1 );
+ ifx_pmcu_unregister ( &pmcuRegisterUSBHost_2 );
+ #else
+ ifx_pmcu_unregister ( &pmcuRegisterUSBHost );
+ #endif
+#endif
+#if defined(__IS_DEVICE__) && defined(__GADGET_COC__)
+ ifx_pmcu_unregister ( &pmcuRegisterUSBGadget );
+#endif
+
+}
+
+static struct proc_dir_entry * proc_ifx_root = NULL;
+
+/* initialize the proc file system and make a dir named /proc/[name] */
+static void ifx_proc_init(void)
+{
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+#ifdef __IS_HOST__
+ proc_ifx_root = proc_mkdir(ifxusb_hcd_driver_name, (void *)0);
+ if (!proc_ifx_root){
+ IFX_PRINT("%s proc initialization failed! \n", ifxusb_hcd_driver_name);
+ return;
+ }
+#else
+ proc_ifx_root = proc_mkdir(ifxusb_pcd_driver_name, (void *)0);
+ if (!proc_ifx_root){
+ IFX_PRINT("%s proc initialization failed! \n", ifxusb_pcd_driver_name);
+ return;
+ }
+#endif
+}
+
+/* proc file system add function for debugging. */
+static int ifx_proc_addproc(char *funcname, read_proc_t *hookfuncr, write_proc_t *hookfuncw)
+{
+ struct proc_dir_entry *pe;
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ if (!proc_ifx_root)
+ ifx_proc_init();
+
+ if (hookfuncw == NULL)
+ {
+ pe = create_proc_read_entry(funcname, S_IRUGO, proc_ifx_root, hookfuncr, NULL);
+ if (!pe)
+ {
+ IFX_PRINT("ERROR in creating read proc entry (%s)! \n", funcname);
+ return -1;
+ }
+ }
+ else
+ {
+ pe = create_proc_entry(funcname, S_IRUGO | S_IWUGO, proc_ifx_root);
+ if (pe)
+ {
+ pe->read_proc = hookfuncr;
+ pe->write_proc = hookfuncw;
+ }
+ else
+ {
+ IFX_PRINT("ERROR in creating proc entry (%s)! \n", funcname);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+/* proc file system del function for removing module. */
+static void ifx_proc_delproc(char *funcname)
+{
+ char pname[30];
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ sprintf(pname, "%s", funcname);
+
+ remove_proc_entry(pname, proc_ifx_root);
+
+}
+
+static void ifxusb_dump_params(ifxusb_core_if_t *_core_if)
+{
+ ifxusb_params_t *params=&_core_if->params;
+
+ #ifdef __IS_HOST__
+ IFX_PRINT("IFXUSB Dump Parameters ( Host Mode) \n");
+ #endif //__IS_HOST__
+ #ifdef __IS_DEVICE__
+ IFX_PRINT("IFXUSB Dump Parameters ( Device Mode) \n");
+ #endif //__IS_DEVICE__
+
+ #ifdef __DESC_DMA__
+ IFX_PRINT("DMA: Hermes DMA\n");
+ #else
+ IFX_PRINT("DMA: Non-Desc DMA\n");
+ #endif
+ IFX_PRINT(" Burst size: %d\n",params->dma_burst_size);
+
+ if (params->speed==1)
+ IFX_PRINT("Full Speed only\n");
+ else if(params->speed==0)
+ IFX_PRINT("Full/Hign Speed\n");
+ else
+ IFX_PRINT("Unkonwn setting (%d) for Speed\n",params->speed);
+
+ IFX_PRINT("Total Data FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",
+ params->data_fifo_size,params->data_fifo_size,
+ params->data_fifo_size*4, params->data_fifo_size*4
+ );
+
+ #ifdef __IS_DEVICE__
+ IFX_PRINT("Rx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",
+ params->rx_fifo_size,params->rx_fifo_size,
+ params->rx_fifo_size*4, params->rx_fifo_size*4
+ );
+ {
+ int i;
+ for(i=0;i<MAX_EPS_CHANNELS;i++)
+ {
+ IFX_PRINT("Tx FIFO #%d size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",i,
+ params->tx_fifo_size[i],params->tx_fifo_size[i],
+ params->tx_fifo_size[i]*4, params->tx_fifo_size[i]*4
+ );
+ }
+ }
+ #ifdef __DED_FIFO__
+ IFX_PRINT("Treshold : %s Rx:%d Tx:%d \n",
+ (params->thr_ctl)?"On":"Off",params->tx_thr_length,params->rx_thr_length);
+ #endif
+ #else //__IS_HOST__
+ IFX_PRINT("Host Channels: %d\n",params->host_channels);
+
+ IFX_PRINT("Rx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",
+ params->data_fifo_size,params->data_fifo_size,
+ params->data_fifo_size*4, params->data_fifo_size*4
+ );
+
+ IFX_PRINT("NP Tx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",
+ params->nperio_tx_fifo_size,params->nperio_tx_fifo_size,
+ params->nperio_tx_fifo_size*4, params->nperio_tx_fifo_size*4
+ );
+
+ IFX_PRINT(" P Tx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",
+ params->perio_tx_fifo_size,params->perio_tx_fifo_size,
+ params->perio_tx_fifo_size*4, params->perio_tx_fifo_size*4
+ );
+ #endif //__IS_HOST__
+
+ IFX_PRINT("Max Transfer size: %d(0x%06X) Bytes\n",
+ params->max_transfer_size,params->max_transfer_size
+ );
+ IFX_PRINT("Max Packet Count: %d(0x%06X)\n",
+ params->max_packet_count,params->max_packet_count
+ );
+
+ IFX_PRINT("PHY UTMI Width: %d\n",params->phy_utmi_width);
+
+ IFX_PRINT("Turn Around Time: HS:%d FS:%d\n",params->turn_around_time_hs,params->turn_around_time_fs);
+ IFX_PRINT("Timeout Calibration: HS:%d FS:%d\n",params->timeout_cal_hs,params->timeout_cal_fs);
+
+
+ IFX_PRINT("==================================================\n");
+ IFX_PRINT("End of Parameters Dump\n");
+ IFX_PRINT("==================================================\n");
+}
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxusb_driver.c b/package/kernel/lantiq/ltq-hcd/src/ifxusb_driver.c
new file mode 100644
index 0000000000..04346b972f
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxusb_driver.c
@@ -0,0 +1,1286 @@
+/*****************************************************************************
+ ** FILE NAME : ifxusb_driver.c
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** AUTHOR : Chen, Howard
+ ** DESCRIPTION : The provides the initialization and cleanup entry
+ ** points for the IFX USB driver. This module can be
+ ** dynamically loaded with insmod command or built-in
+ ** with kernel. When loaded or executed the ifxusb_driver_init
+ ** function is called. When the module is removed (using rmmod),
+ ** the ifxusb_driver_cleanup function is called.
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*!
+ \file ifxusb_driver.c
+ \brief This file contains the loading/unloading interface to the Linux driver.
+*/
+
+#include <linux/version.h>
+#include "ifxusb_version.h"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+
+#include <linux/device.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/stat.h> /* permission constants */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ #include <linux/irq.h>
+#endif
+
+#include <asm/io.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+ #include <asm/irq.h>
+#endif
+
+#include "ifxusb_plat.h"
+
+#include "ifxusb_cif.h"
+
+#ifdef __IS_HOST__
+ #include "ifxhcd.h"
+
+ #define USB_DRIVER_DESC "IFX USB HCD driver"
+ const char ifxusb_hcd_driver_name[] = "ifxusb_hcd";
+ #ifdef __IS_DUAL__
+ ifxhcd_hcd_t ifxusb_hcd_1;
+ ifxhcd_hcd_t ifxusb_hcd_2;
+ const char ifxusb_hcd_name_1[] = "ifxusb_hcd_1";
+ const char ifxusb_hcd_name_2[] = "ifxusb_hcd_2";
+ #else
+ ifxhcd_hcd_t ifxusb_hcd;
+ const char ifxusb_hcd_name[] = "ifxusb_hcd";
+ #endif
+
+ #if defined(__DO_OC_INT__)
+ ifxhcd_hcd_t *oc_int_id=NULL;
+ #ifdef __IS_DUAL__
+ ifxhcd_hcd_t *oc_int_id_1=NULL;
+ ifxhcd_hcd_t *oc_int_id_2=NULL;
+ #endif
+ #endif
+#endif
+
+#ifdef __IS_DEVICE__
+ #include "ifxpcd.h"
+
+ #define USB_DRIVER_DESC "IFX USB PCD driver"
+ const char ifxusb_pcd_driver_name[] = "ifxusb_pcd";
+ ifxpcd_pcd_t ifxusb_pcd;
+ const char ifxusb_pcd_name[] = "ifxusb_pcd";
+#endif
+
+/* Global Debug Level Mask. */
+#ifdef __IS_HOST__
+ uint32_t h_dbg_lvl = 0xff;
+#endif
+
+#ifdef __IS_DEVICE__
+ uint32_t d_dbg_lvl = 0x00;
+#endif
+
+#ifdef __IS_HOST__
+ifxusb_params_t ifxusb_module_params_h;
+#else
+ifxusb_params_t ifxusb_module_params_d;
+#endif
+
+static void parse_parms(void);
+
+
+#if defined(__IS_TWINPASS__)
+#warning "Compiled as TWINPASS"
+#elif defined(__IS_DANUBE__)
+#warning "Compiled as DANUBE"
+#elif defined(__IS_AMAZON_SE__)
+#warning "Compiled as AMAZON_SE"
+#elif defined(__IS_AR9__)
+#warning "Compiled as AR9"
+#elif defined(__IS_VR9__)
+#warning "Compiled as VR9"
+#elif defined(__IS_AR10__)
+#warning "Compiled as AR10"
+#else
+#error "No Platform defined"
+#endif
+
+
+/* Function to setup the structures to control one usb core running as host*/
+#ifdef __IS_HOST__
+/*!
+ \brief inlined by ifxusb_driver_probe(), handling host mode probing. Run at each host core.
+*/
+ static inline int ifxusb_driver_probe_h(ifxhcd_hcd_t *_hcd,
+ int _irq,
+ uint32_t _iobase,
+ uint32_t _fifomem,
+ uint32_t _fifodbg
+ )
+ {
+ int retval = 0;
+
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+
+ ifxusb_power_on_h (&_hcd->core_if);
+ mdelay(50);
+ ifxusb_phy_power_on_h (&_hcd->core_if); // Test
+ mdelay(50);
+ ifxusb_hard_reset_h(&_hcd->core_if);
+ retval =ifxusb_core_if_init_h(&_hcd->core_if,
+ _irq,
+ _iobase,
+ _fifomem,
+ _fifodbg);
+ if(retval)
+ return retval;
+
+ ifxusb_host_core_init(&_hcd->core_if,&ifxusb_module_params_h);
+
+ ifxusb_disable_global_interrupts_h( &_hcd->core_if);
+
+ /* The driver is now initialized and need to be registered into Linux USB sub-system */
+
+ retval = ifxhcd_init(_hcd); // hook the hcd into usb ss
+
+ if (retval != 0)
+ {
+ IFX_ERROR("_hcd_init failed\n");
+ return retval;
+ }
+
+ //ifxusb_enable_global_interrupts_h( _hcd->core_if ); // this should be done at hcd_start , including hcd_interrupt
+ return 0;
+ }
+#endif //__IS_HOST__
+
+#ifdef __IS_DEVICE__
+/*!
+ \brief inlined by ifxusb_driver_probe(), handling device mode probing.
+*/
+ static inline int ifxusb_driver_probe_d(ifxpcd_pcd_t *_pcd,
+ int _irq,
+ uint32_t _iobase,
+ uint32_t _fifomem,
+ uint32_t _fifodbg
+ )
+ {
+ int retval = 0;
+
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ ifxusb_power_on_d (&_pcd->core_if);
+ mdelay(50);
+ ifxusb_phy_power_on_d (&_pcd->core_if); // Test
+ mdelay(50);
+ ifxusb_hard_reset_d(&_pcd->core_if);
+ retval =ifxusb_core_if_init_d(&_pcd->core_if,
+ _irq,
+ _iobase,
+ _fifomem,
+ _fifodbg);
+ if(retval)
+ return retval;
+
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ ifxusb_dev_core_init(&_pcd->core_if,&ifxusb_module_params_d);
+
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ ifxusb_disable_global_interrupts_d( &_pcd->core_if);
+
+ /* The driver is now initialized and need to be registered into
+ Linux USB Gadget sub-system
+ */
+ retval = ifxpcd_init();
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+
+ if (retval != 0)
+ {
+ IFX_ERROR("_pcd_init failed\n");
+ return retval;
+ }
+ //ifxusb_enable_global_interrupts_d( _pcd->core_if ); // this should be done at gadget bind or start
+ return 0;
+ }
+#endif //__IS_DEVICE__
+
+/*!
+ \brief This function is called when a driver is unregistered. This happens when
+ the rmmod command is executed. The device may or may not be electrically
+ present. If it is present, the driver stops device processing. Any resources
+ used on behalf of this device are freed.
+*/
+static int ifxusb_driver_remove(struct platform_device *_pdev)
+{
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ #ifdef __IS_HOST__
+ #if defined(__IS_DUAL__)
+ ifxhcd_remove(&ifxusb_hcd_1);
+ ifxusb_core_if_remove_h(&ifxusb_hcd_1.core_if );
+ ifxhcd_remove(&ifxusb_hcd_2);
+ ifxusb_core_if_remove_h(&ifxusb_hcd_2.core_if );
+ #else
+ ifxhcd_remove(&ifxusb_hcd);
+ ifxusb_core_if_remove_h(&ifxusb_hcd.core_if );
+ #endif
+ #endif
+ #ifdef __IS_DEVICE__
+ ifxpcd_remove();
+ ifxusb_core_if_remove_d(&ifxusb_pcd.core_if );
+ #endif
+ /* Remove the device attributes */
+ #ifdef __IS_HOST__
+ ifxusb_attr_remove_h(&_pdev->dev);
+ #else
+ ifxusb_attr_remove_d(&_pdev->dev);
+ #endif
+ return 0;
+}
+
+/*!
+ \brief This function is called by module management in 2.6 kernel or by ifxusb_driver_init with 2.4 kernel
+ It is to probe and setup IFXUSB core(s).
+*/
+static int ifxusb_driver_probe(struct platform_device *_pdev)
+{
+ int retval = 0;
+ struct device_node *np;
+ int gpio_count;
+ u32 port_mask = 0x1;
+
+#ifdef __IS_DANUBE__
+ np = of_find_compatible_node(NULL, NULL, "lantiq,ifxhcd-danube");
+#elif defined __IS_AMAZON_SE__
+ np = of_find_compatible_node(NULL, NULL, "lantiq,ifxhcd-ase");
+#elif defined __IS_AR9__
+ np = of_find_compatible_node(NULL, NULL, "lantiq,ifxhcd-arx100");
+#elif defined __IS_VR9__
+ np = of_find_compatible_node(NULL, NULL, "lantiq,ifxhcd-xrx200");
+#elif defined __IS_AR10__
+ np = of_find_compatible_node(NULL, NULL, "lantiq,ifxhcd-arx300");
+#endif
+ if (!np) {
+ dev_err(&_pdev->dev, "failed to find hcd device node\n");
+ return -ENODEV;
+ }
+ of_property_read_u32(np, "lantiq,portmask", &port_mask);
+ // Parsing and store the parameters
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ parse_parms();
+
+ #ifdef __IS_HOST__
+ #if defined(__DO_OC_INT__)
+ if(!oc_int_id)
+ {
+ #if defined(__IS_DUAL__)
+ oc_int_id=&ifxusb_hcd_1;
+ oc_int_id_1=&ifxusb_hcd_1;
+ oc_int_id_2=&ifxusb_hcd_2;
+ #else
+ oc_int_id=&ifxusb_hcd;
+ #endif
+ }
+ #endif
+
+ #if defined(__IS_DUAL__)
+ memset(&ifxusb_hcd_1, 0, sizeof(ifxhcd_hcd_t));
+ memset(&ifxusb_hcd_2, 0, sizeof(ifxhcd_hcd_t));
+
+ ifxusb_hcd_1.core_if.core_no=0;
+ ifxusb_hcd_2.core_if.core_no=1;
+ ifxusb_hcd_1.core_if.core_name=(char *)ifxusb_hcd_name_1;
+ ifxusb_hcd_2.core_if.core_name=(char *)ifxusb_hcd_name_2;
+
+ ifxusb_hcd_1.dev=&_pdev->dev;
+ ifxusb_hcd_2.dev=&_pdev->dev;
+
+ if (port_mask & 0x1) {
+ retval = ifxusb_driver_probe_h(&ifxusb_hcd_1,
+ IFXUSB1_IRQ,
+ IFXUSB1_IOMEM_BASE,
+ IFXUSB1_FIFOMEM_BASE,
+ IFXUSB1_FIFODBG_BASE
+ );
+ if(retval)
+ goto ifxusb_driver_probe_fail;
+ }
+
+ if (port_mask & 0x2) {
+ retval = ifxusb_driver_probe_h(&ifxusb_hcd_2,
+ IFXUSB2_IRQ,
+ IFXUSB2_IOMEM_BASE,
+ IFXUSB2_FIFOMEM_BASE,
+ IFXUSB2_FIFODBG_BASE
+ );
+ if(retval)
+ goto ifxusb_driver_probe_fail;
+ }
+ #elif defined(__IS_FIRST__)
+ memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t));
+
+ ifxusb_hcd.core_if.core_no=0;
+ ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name;
+
+ ifxusb_hcd.dev=&_pdev->dev;
+
+ retval = ifxusb_driver_probe_h(&ifxusb_hcd,
+ IFXUSB1_IRQ,
+ IFXUSB1_IOMEM_BASE,
+ IFXUSB1_FIFOMEM_BASE,
+ IFXUSB1_FIFODBG_BASE
+ );
+ if(retval)
+ goto ifxusb_driver_probe_fail;
+
+ #elif defined(__IS_SECOND__)
+ memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t));
+
+ ifxusb_hcd.core_if.core_no=1;
+ ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name;
+
+ ifxusb_hcd.dev=&_pdev->dev;
+
+ retval = ifxusb_driver_probe_h(&ifxusb_hcd,
+ IFXUSB2_IRQ,
+ IFXUSB2_IOMEM_BASE,
+ IFXUSB2_FIFOMEM_BASE,
+ IFXUSB2_FIFODBG_BASE
+ );
+ if(retval)
+ goto ifxusb_driver_probe_fail;
+
+ #else
+ memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t));
+
+ ifxusb_hcd.core_if.core_no=0;
+ ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name;
+
+ ifxusb_hcd.dev=&_pdev->dev;
+
+ retval = ifxusb_driver_probe_h(&ifxusb_hcd,
+ IFXUSB_IRQ,
+ IFXUSB_IOMEM_BASE,
+ IFXUSB_FIFOMEM_BASE,
+ IFXUSB_FIFODBG_BASE
+ );
+ if(retval)
+ goto ifxusb_driver_probe_fail;
+ #endif
+ #endif
+
+ #ifdef __IS_DEVICE__
+ memset(&ifxusb_pcd, 0, sizeof(ifxpcd_pcd_t));
+ ifxusb_pcd.core_if.core_name=(char *)&ifxusb_pcd_name[0];
+
+ ifxusb_pcd.dev=&_pdev->dev;
+
+ #if defined(__IS_FIRST__)
+ ifxusb_pcd.core_if.core_no=0;
+ retval = ifxusb_driver_probe_d(&ifxusb_pcd,
+ IFXUSB1_IRQ,
+ IFXUSB1_IOMEM_BASE,
+ IFXUSB1_FIFOMEM_BASE,
+ IFXUSB1_FIFODBG_BASE
+ );
+ #elif defined(__IS_SECOND__)
+ ifxusb_pcd.core_if.core_no=1;
+ retval = ifxusb_driver_probe_d(&ifxusb_pcd,
+ IFXUSB2_IRQ,
+ IFXUSB2_IOMEM_BASE,
+ IFXUSB2_FIFOMEM_BASE,
+ IFXUSB2_FIFODBG_BASE
+ );
+ #else
+ ifxusb_pcd.core_if.core_no=0;
+ retval = ifxusb_driver_probe_d(&ifxusb_pcd,
+ IFXUSB_IRQ,
+ IFXUSB_IOMEM_BASE,
+ IFXUSB_FIFOMEM_BASE,
+ IFXUSB_FIFODBG_BASE
+ );
+ #endif
+ if(retval)
+ goto ifxusb_driver_probe_fail;
+ #endif
+
+ #ifdef __IS_HOST__
+ ifxusb_attr_create_h(&_pdev->dev);
+ #else
+ ifxusb_attr_create_d(&_pdev->dev);
+ #endif
+
+ gpio_count = of_gpio_count(np);
+ while (gpio_count) {
+ enum of_gpio_flags flags;
+ int gpio = of_get_gpio_flags(np, --gpio_count, &flags);
+ if (gpio_request(gpio, "usb"))
+ continue;
+ dev_info(&_pdev->dev, "requested GPIO %d\n", gpio);
+ gpio_direction_output(gpio, (flags & OF_GPIO_ACTIVE_LOW) ? (0) : (1));
+ }
+
+
+ return 0;
+
+ifxusb_driver_probe_fail:
+ ifxusb_driver_remove(_pdev);
+ return retval;
+}
+
+static struct resource ifxusb_device_resources[] =
+{
+ #if defined(__IS_DUAL__)
+ [0] = { .start = IFXUSB1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = { .start = IFXUSB1_IOMEM_BASE,
+ .end = IFXUSB1_IOMEM_BASE + IFXUSB_IOMEM_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = { .start = IFXUSB2_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = { .start = IFXUSB2_IOMEM_BASE,
+ .end = IFXUSB2_IOMEM_BASE + IFXUSB_IOMEM_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [4] = { .start = IFXUSB1_FIFOMEM_BASE,
+ .end = IFXUSB1_FIFOMEM_BASE + IFXUSB_FIFOMEM_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [5] = { .start = IFXUSB2_FIFOMEM_BASE,
+ .end = IFXUSB2_FIFOMEM_BASE + IFXUSB_FIFOMEM_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [6] = { .start = IFXUSB1_FIFODBG_BASE,
+ .end = IFXUSB1_FIFODBG_BASE + IFXUSB_FIFODBG_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [7] = { .start = IFXUSB2_FIFODBG_BASE,
+ .end = IFXUSB2_FIFODBG_BASE + IFXUSB_FIFODBG_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ #elif defined(__IS_FIRST__)
+ [0] = { .start = IFXUSB1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = { .start = IFXUSB1_IOMEM_BASE,
+ .end = IFXUSB1_IOMEM_BASE + IFXUSB_IOMEM_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = { .start = IFXUSB1_FIFOMEM_BASE,
+ .end = IFXUSB1_FIFOMEM_BASE + IFXUSB_FIFOMEM_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = { .start = IFXUSB1_FIFODBG_BASE,
+ .end = IFXUSB1_FIFODBG_BASE + IFXUSB_FIFODBG_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ #elif defined(__IS_SECOND__)
+ [0] = { .start = IFXUSB2_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = { .start = IFXUSB2_IOMEM_BASE,
+ .end = IFXUSB2_IOMEM_BASE + IFXUSB_IOMEM_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = { .start = IFXUSB2_FIFOMEM_BASE,
+ .end = IFXUSB2_FIFOMEM_BASE + IFXUSB_FIFOMEM_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = { .start = IFXUSB2_FIFODBG_BASE,
+ .end = IFXUSB2_FIFODBG_BASE + IFXUSB_FIFODBG_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ #else
+ [0] = { .start = IFXUSB_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = { .start = IFXUSB_IOMEM_BASE,
+ .end = IFXUSB_IOMEM_BASE + IFXUSB_IOMEM_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = { .start = IFXUSB_FIFOMEM_BASE,
+ .end = IFXUSB_FIFOMEM_BASE+IFXUSB_FIFOMEM_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = { .start = IFXUSB_FIFODBG_BASE,
+ .end = IFXUSB_FIFODBG_BASE+IFXUSB_FIFODBG_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+ #endif //__IS_DUAL__
+};
+
+static u64 ifxusb_dmamask = (u32)0x1fffffff;
+
+static void ifxusb_device_release(struct device * dev)
+{
+ IFX_PRINT("IFX USB platform_dev release\n");
+ dev->parent = NULL;
+}
+
+static struct platform_device ifxusb_device =
+{
+ .id = -1,
+ .dev =
+ {
+ .release = ifxusb_device_release,
+ .dma_mask = &ifxusb_dmamask,
+ },
+ .resource = ifxusb_device_resources,
+ .num_resources = ARRAY_SIZE(ifxusb_device_resources),
+};
+
+
+/*!
+ \brief This function is called when the ifxusb_driver is installed with the insmod command.
+*/
+static struct platform_driver ifxusb_driver = {
+ .probe = ifxusb_driver_probe,
+ .remove = ifxusb_driver_remove,
+ .driver ={
+ .owner = THIS_MODULE,
+ #ifdef __IS_HOST__
+ .name = ifxusb_hcd_driver_name,
+ #else
+ .name = ifxusb_pcd_driver_name,
+ #endif
+ },
+};
+
+#ifdef __IS_HOST__
+ int __init ifxusb_hcd_driver_init(void)
+#else
+ int __init ifxusb_pcd_driver_init(void)
+#endif
+{
+ int retval = 0;
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ #if defined(__IS_HOST__)
+ IFX_PRINT("%s: version %s\n", ifxusb_hcd_driver_name, IFXUSB_VERSION);
+ #else
+ IFX_PRINT("%s: version %s\n", ifxusb_pcd_driver_name, IFXUSB_VERSION);
+ #endif
+
+ #if 0
+ #if defined(__IS_TWINPASS__)
+ IFX_PRINT(" OPTION: __IS_TWINPASS__\n");
+ #elif defined(__IS_DANUBE__)
+ IFX_PRINT(" OPTION: __IS_DANUBE__\n");
+ #elif defined(__IS_AMAZON_SE__)
+ IFX_PRINT(" OPTION: __IS_AMAZON_SE__\n");
+ #elif defined(__IS_AR9__)
+ IFX_PRINT(" OPTION: __IS_AR9__\n");
+ #elif defined(__IS_VR9__)
+ IFX_PRINT(" OPTION: __IS_VR9__\n");
+ #elif defined(__IS_AR10__)
+ IFX_PRINT(" OPTION: __IS_AR10__\n");
+ #else
+ IFX_PRINT(" OPTION: NO PLATFORM DEFINED\n");
+ #endif
+
+ #ifdef __UEIP__
+ IFX_PRINT(" OPTION: __UEIP__\n");
+ #endif
+
+ #ifdef __PHY_LONG_PREEMP__
+ IFX_PRINT(" OPTION: __PHY_LONG_PREEMP__\n");
+ #endif
+ #ifdef __FORCE_USB11__
+ IFX_PRINT(" OPTION: __FORCE_USB11__\n");
+ #endif
+ #ifdef __UNALIGNED_BUF_ADJ__
+ IFX_PRINT(" OPTION: __UNALIGNED_BUF_ADJ__\n");
+ #endif
+ #ifdef __UNALIGNED_BUF_CHK__
+ IFX_PRINT(" OPTION: __UNALIGNED_BUF_CHK__\n");
+ #endif
+ #ifdef __UNALIGNED_BUF_BURST__
+ IFX_PRINT(" OPTION: __UNALIGNED_BUF_BURST__\n");
+ #endif
+ #ifdef __DEBUG__
+ IFX_PRINT(" OPTION: __DEBUG__\n");
+ #endif
+ #ifdef __ENABLE_DUMP__
+ IFX_PRINT(" OPTION: __ENABLE_DUMP__\n");
+ #endif
+
+ #ifdef __IS_HOST__
+ IFX_PRINT(" OPTION: __IS_HOST__\n");
+ #ifdef __IS_DUAL__
+ IFX_PRINT(" __IS_DUAL__\n");
+ #endif
+ #ifdef __IS_FIRST__
+ IFX_PRINT(" __IS_FIRST__\n");
+ #endif
+ #ifdef __IS_SECOND__
+ IFX_PRINT(" __IS_SECOND__\n");
+ #endif
+ #ifdef __WITH_HS_ELECT_TST__
+ IFX_PRINT(" __WITH_HS_ELECT_TST__\n");
+ #endif
+ #ifdef __EN_ISOC__
+ IFX_PRINT(" __EN_ISOC__\n");
+ #endif
+ #ifdef __EN_ISOC_SPLIT__
+ IFX_PRINT(" __EN_ISOC_SPLIT__\n");
+ #endif
+ #ifdef __EPQD_DESTROY_TIMEOUT__
+ IFX_PRINT(" __EPQD_DESTROY_TIMEOUT__\n");
+ #endif
+ #ifdef __DYN_SOF_INTR__
+ IFX_PRINT(" __DYN_SOF_INTR__\n");
+ #endif
+ #else
+ IFX_PRINT(" OPTION: __IS_DEVICE__\n");
+ #ifdef __DED_INTR__
+ IFX_PRINT(" __DED_INTR__\n");
+ #endif
+ #ifdef __DED_FIFO__
+ IFX_PRINT(" __DED_FIFO__\n");
+ #endif
+ #ifdef __DESC_DMA__
+ IFX_PRINT(" __DESC_DMA__\n");
+ #endif
+ #ifdef __IS_FIRST__
+ IFX_PRINT(" __IS_FIRST__\n");
+ #endif
+ #ifdef __IS_SECOND__
+ IFX_PRINT(" __IS_SECOND__\n");
+ #endif
+ #ifdef __GADGET_TASKLET_TX__
+ IFX_PRINT(" __GADGET_TASKLET_TX__\n");
+ #endif
+ #ifdef __GADGET_TASKLET_RX__
+ IFX_PRINT(" __GADGET_TASKLET_RX__\n");
+ #endif
+ #ifdef __GADGET_TASKLET_HIGH__
+ IFX_PRINT(" __GADGET_TASKLET_HIGH__\n");
+ #endif
+ #ifdef __DO_PCD_UNLOCK__
+ IFX_PRINT(" __DO_PCD_UNLOCK__\n");
+ #endif
+ #ifdef __GADGET_LED__
+ IFX_PRINT(" __GADGET_LED__\n");
+ #endif
+
+ #ifdef __ECM_NO_INTR__
+ IFX_PRINT(" __ECM_NO_INTR__\n");
+ #endif
+ #ifdef __NOSWAPINCTRL__
+ IFX_PRINT(" __NOSWAPINCTRL__\n");
+ #endif
+ #ifdef __MAC_ECM_FIX__
+ IFX_PRINT(" __MAC_ECM_FIX__\n");
+ #endif
+ #ifdef __RETAIN_BUF_TX__
+ IFX_PRINT(" __RETAIN_BUF_TX__\n");
+ #endif
+ #ifdef __RETAIN_BUF_RX__
+ IFX_PRINT(" __RETAIN_BUF_RX__\n");
+ #endif
+ #ifdef __QUICKNAK__
+ IFX_PRINT(" __QUICKNAK__\n");
+ #endif
+ #endif
+ #endif
+
+ retval = platform_driver_register(&ifxusb_driver);
+
+ if (retval < 0) {
+ IFX_ERROR("%s retval=%d\n", __func__, retval);
+ return retval;
+ }
+
+ #ifdef __IS_HOST__
+ ifxusb_device.name = ifxusb_hcd_driver_name;
+ #else
+ ifxusb_device.name = ifxusb_pcd_driver_name;
+ #endif
+
+ if (ifxusb_device.dev.parent)
+ retval = -EBUSY;
+ else
+ retval = platform_device_register(&ifxusb_device);
+
+ if (retval < 0)
+ {
+ IFX_ERROR("%s retval=%d\n", __func__, retval);
+ platform_driver_unregister(&ifxusb_driver);
+ return retval;
+ }
+ return retval;
+}
+
+#ifdef __IS_HOST__
+ module_init(ifxusb_hcd_driver_init);
+#else
+ module_init(ifxusb_pcd_driver_init);
+#endif
+
+/*!
+ \brief This function is called when the driver is removed from the kernel
+ with the rmmod command. The driver unregisters itself with its bus
+ driver.
+*/
+#ifdef __IS_HOST__
+ void __exit ifxusb_hcd_driver_cleanup(void)
+ {
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ platform_device_unregister(&ifxusb_device);
+ platform_driver_unregister(&ifxusb_driver);
+ IFX_PRINT("%s module removed\n", ifxusb_hcd_driver_name);
+ }
+ module_exit(ifxusb_hcd_driver_cleanup);
+#else
+ void __exit ifxusb_pcd_driver_cleanup(void)
+ {
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ platform_device_unregister(&ifxusb_device);
+ platform_driver_unregister(&ifxusb_driver);
+ IFX_PRINT("%s module removed\n", ifxusb_pcd_driver_name);
+ }
+ module_exit(ifxusb_pcd_driver_cleanup);
+#endif
+MODULE_DESCRIPTION(USB_DRIVER_DESC);
+MODULE_AUTHOR("Lantiq");
+MODULE_LICENSE("GPL");
+
+
+
+// Parameters set when loaded
+//static long dbg_lvl =0xFFFFFFFF;
+static long dbg_lvl =0;
+static short dma_burst_size =-1;
+static short speed =-1;
+static long data_fifo_size =-1;
+#ifdef __IS_DEVICE__
+ static long rx_fifo_size =-1;
+ #ifdef __DED_FIFO__
+ static long tx_fifo_size_00 =-1;
+ static long tx_fifo_size_01 =-1;
+ static long tx_fifo_size_02 =-1;
+ static long tx_fifo_size_03 =-1;
+ static long tx_fifo_size_04 =-1;
+ static long tx_fifo_size_05 =-1;
+ static long tx_fifo_size_06 =-1;
+ static long tx_fifo_size_07 =-1;
+ static long tx_fifo_size_08 =-1;
+ static long tx_fifo_size_09 =-1;
+ static long tx_fifo_size_10 =-1;
+ static long tx_fifo_size_11 =-1;
+ static long tx_fifo_size_12 =-1;
+ static long tx_fifo_size_13 =-1;
+ static long tx_fifo_size_14 =-1;
+ static long tx_fifo_size_15 =-1;
+ static short thr_ctl=-1;
+ static long tx_thr_length =-1;
+ static long rx_thr_length =-1;
+ #else
+ static long nperio_tx_fifo_size =-1;
+ static long perio_tx_fifo_size_01 =-1;
+ static long perio_tx_fifo_size_02 =-1;
+ static long perio_tx_fifo_size_03 =-1;
+ static long perio_tx_fifo_size_04 =-1;
+ static long perio_tx_fifo_size_05 =-1;
+ static long perio_tx_fifo_size_06 =-1;
+ static long perio_tx_fifo_size_07 =-1;
+ static long perio_tx_fifo_size_08 =-1;
+ static long perio_tx_fifo_size_09 =-1;
+ static long perio_tx_fifo_size_10 =-1;
+ static long perio_tx_fifo_size_11 =-1;
+ static long perio_tx_fifo_size_12 =-1;
+ static long perio_tx_fifo_size_13 =-1;
+ static long perio_tx_fifo_size_14 =-1;
+ static long perio_tx_fifo_size_15 =-1;
+ #endif
+ static short dev_endpoints =-1;
+#endif
+
+#ifdef __IS_HOST__
+ static long rx_fifo_size =-1;
+ static long nperio_tx_fifo_size =-1;
+ static long perio_tx_fifo_size =-1;
+ static short host_channels =-1;
+#endif
+
+static long max_transfer_size =-1;
+static long max_packet_count =-1;
+static long phy_utmi_width =-1;
+static long turn_around_time_hs =-1;
+static long turn_around_time_fs =-1;
+static long timeout_cal_hs =-1;
+static long timeout_cal_fs =-1;
+
+/*!
+ \brief Parsing the parameters taken when module load
+*/
+static void parse_parms(void)
+{
+
+ ifxusb_params_t *params;
+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
+ #ifdef __IS_HOST__
+ h_dbg_lvl=dbg_lvl;
+ params=&ifxusb_module_params_h;
+ #endif
+ #ifdef __IS_DEVICE__
+ d_dbg_lvl=dbg_lvl;
+ params=&ifxusb_module_params_d;
+ #endif
+
+ switch(dma_burst_size)
+ {
+ case 0:
+ case 1:
+ case 4:
+ case 8:
+ case 16:
+ params->dma_burst_size=dma_burst_size;
+ break;
+ default:
+ #if defined(__IS_VR9__)
+ {
+ unsigned int chipid;
+ unsigned int partnum;
+ chipid=*((volatile uint32_t *)IFX_MPS_CHIPID);
+ partnum=(chipid&0x0FFFF000)>>12;
+ switch(partnum)
+ {
+ case 0x000B: //VRX288_A2x
+ case 0x000E: //VRX282_A2x
+ case 0x000C: //VRX268_A2x
+ case 0x000D: //GRX288_A2x
+ params->dma_burst_size=default_param_dma_burst_size_n;
+ break;
+ default:
+ params->dma_burst_size=default_param_dma_burst_size;
+ }
+ printk(KERN_INFO "Chip Version :%04x BurstSize=%d\n",partnum,params->dma_burst_size);
+ }
+ #else
+ params->dma_burst_size=default_param_dma_burst_size;
+ #endif
+ }
+
+ if(speed==0 || speed==1)
+ params->speed=speed;
+ else
+ params->speed=default_param_speed;
+
+ if(max_transfer_size>=2048 && max_transfer_size<=65535)
+ params->max_transfer_size=max_transfer_size;
+ else
+ params->max_transfer_size=default_param_max_transfer_size;
+
+ if(max_packet_count>=15 && max_packet_count<=511)
+ params->max_packet_count=max_packet_count;
+ else
+ params->max_packet_count=default_param_max_packet_count;
+
+ switch(phy_utmi_width)
+ {
+ case 8:
+ case 16:
+ params->phy_utmi_width=phy_utmi_width;
+ break;
+ default:
+ params->phy_utmi_width=default_param_phy_utmi_width;
+ }
+
+ if(turn_around_time_hs>=0 && turn_around_time_hs<=7)
+ params->turn_around_time_hs=turn_around_time_hs;
+ else
+ params->turn_around_time_hs=default_param_turn_around_time_hs;
+
+ if(turn_around_time_fs>=0 && turn_around_time_fs<=7)
+ params->turn_around_time_fs=turn_around_time_fs;
+ else
+ params->turn_around_time_fs=default_param_turn_around_time_fs;
+
+ if(timeout_cal_hs>=0 && timeout_cal_hs<=7)
+ params->timeout_cal_hs=timeout_cal_hs;
+ else
+ params->timeout_cal_hs=default_param_timeout_cal_hs;
+
+ if(timeout_cal_fs>=0 && timeout_cal_fs<=7)
+ params->timeout_cal_fs=timeout_cal_fs;
+ else
+ params->timeout_cal_fs=default_param_timeout_cal_fs;
+
+ if(data_fifo_size>=32 && data_fifo_size<=32768)
+ params->data_fifo_size=data_fifo_size;
+ else
+ params->data_fifo_size=default_param_data_fifo_size;
+
+ #ifdef __IS_HOST__
+ if(host_channels>=1 && host_channels<=16)
+ params->host_channels=host_channels;
+ else
+ params->host_channels=default_param_host_channels;
+
+ if(rx_fifo_size>=16 && rx_fifo_size<=32768)
+ params->rx_fifo_size=rx_fifo_size;
+ else
+ params->rx_fifo_size=default_param_rx_fifo_size;
+
+ if(nperio_tx_fifo_size>=16 && nperio_tx_fifo_size<=32768)
+ params->nperio_tx_fifo_size=nperio_tx_fifo_size;
+ else
+ params->nperio_tx_fifo_size=default_param_nperio_tx_fifo_size;
+
+ if(perio_tx_fifo_size>=16 && perio_tx_fifo_size<=32768)
+ params->perio_tx_fifo_size=perio_tx_fifo_size;
+ else
+ params->perio_tx_fifo_size=default_param_perio_tx_fifo_size;
+ #endif //__IS_HOST__
+
+ #ifdef __IS_DEVICE__
+ if(rx_fifo_size>=16 && rx_fifo_size<=32768)
+ params->rx_fifo_size=rx_fifo_size;
+ else
+ params->rx_fifo_size=default_param_rx_fifo_size;
+ #ifdef __DED_FIFO__
+ if(tx_fifo_size_00>=16 && tx_fifo_size_00<=32768)
+ params->tx_fifo_size[ 0]=tx_fifo_size_00;
+ else
+ params->tx_fifo_size[ 0]=default_param_tx_fifo_size_00;
+ if(tx_fifo_size_01>=0 && tx_fifo_size_01<=32768)
+ params->tx_fifo_size[ 1]=tx_fifo_size_01;
+ else
+ params->tx_fifo_size[ 1]=default_param_tx_fifo_size_01;
+ if(tx_fifo_size_02>=0 && tx_fifo_size_02<=32768)
+ params->tx_fifo_size[ 2]=tx_fifo_size_02;
+ else
+ params->tx_fifo_size[ 2]=default_param_tx_fifo_size_02;
+ if(tx_fifo_size_03>=0 && tx_fifo_size_03<=32768)
+ params->tx_fifo_size[ 3]=tx_fifo_size_03;
+ else
+ params->tx_fifo_size[ 3]=default_param_tx_fifo_size_03;
+ if(tx_fifo_size_04>=0 && tx_fifo_size_04<=32768)
+ params->tx_fifo_size[ 4]=tx_fifo_size_04;
+ else
+ params->tx_fifo_size[ 4]=default_param_tx_fifo_size_04;
+ if(tx_fifo_size_05>=0 && tx_fifo_size_05<=32768)
+ params->tx_fifo_size[ 5]=tx_fifo_size_05;
+ else
+ params->tx_fifo_size[ 5]=default_param_tx_fifo_size_05;
+ if(tx_fifo_size_06>=0 && tx_fifo_size_06<=32768)
+ params->tx_fifo_size[ 6]=tx_fifo_size_06;
+ else
+ params->tx_fifo_size[ 6]=default_param_tx_fifo_size_06;
+ if(tx_fifo_size_07>=0 && tx_fifo_size_07<=32768)
+ params->tx_fifo_size[ 7]=tx_fifo_size_07;
+ else
+ params->tx_fifo_size[ 7]=default_param_tx_fifo_size_07;
+ if(tx_fifo_size_08>=0 && tx_fifo_size_08<=32768)
+ params->tx_fifo_size[ 8]=tx_fifo_size_08;
+ else
+ params->tx_fifo_size[ 8]=default_param_tx_fifo_size_08;
+ if(tx_fifo_size_09>=0 && tx_fifo_size_09<=32768)
+ params->tx_fifo_size[ 9]=tx_fifo_size_09;
+ else
+ params->tx_fifo_size[ 9]=default_param_tx_fifo_size_09;
+ if(tx_fifo_size_10>=0 && tx_fifo_size_10<=32768)
+ params->tx_fifo_size[10]=tx_fifo_size_10;
+ else
+ params->tx_fifo_size[10]=default_param_tx_fifo_size_10;
+ if(tx_fifo_size_11>=0 && tx_fifo_size_11<=32768)
+ params->tx_fifo_size[11]=tx_fifo_size_11;
+ else
+ params->tx_fifo_size[11]=default_param_tx_fifo_size_11;
+ if(tx_fifo_size_12>=0 && tx_fifo_size_12<=32768)
+ params->tx_fifo_size[12]=tx_fifo_size_12;
+ else
+ params->tx_fifo_size[12]=default_param_tx_fifo_size_12;
+ if(tx_fifo_size_13>=0 && tx_fifo_size_13<=32768)
+ params->tx_fifo_size[13]=tx_fifo_size_13;
+ else
+ params->tx_fifo_size[13]=default_param_tx_fifo_size_13;
+ if(tx_fifo_size_14>=0 && tx_fifo_size_14<=32768)
+ params->tx_fifo_size[14]=tx_fifo_size_14;
+ else
+ params->tx_fifo_size[14]=default_param_tx_fifo_size_14;
+ if(tx_fifo_size_15>=0 && tx_fifo_size_15<=32768)
+ params->tx_fifo_size[15]=tx_fifo_size_15;
+ else
+ params->tx_fifo_size[15]=default_param_tx_fifo_size_15;
+ if(thr_ctl==0 || thr_ctl==1)
+ params->thr_ctl=thr_ctl;
+ else
+ params->thr_ctl=default_param_thr_ctl;
+ if(tx_thr_length>=16 && tx_thr_length<=511)
+ params->tx_thr_length=tx_thr_length;
+ else
+ params->tx_thr_length=default_param_tx_thr_length;
+ if(rx_thr_length>=16 && rx_thr_length<=511)
+ params->rx_thr_length=rx_thr_length;
+ else
+ params->rx_thr_length=default_param_rx_thr_length;
+ #else //__DED_FIFO__
+ if(nperio_tx_fifo_size>=16 && nperio_tx_fifo_size<=32768)
+ params->tx_fifo_size[ 0]=nperio_tx_fifo_size;
+ else
+ params->tx_fifo_size[ 0]=default_param_nperio_tx_fifo_size;
+ if(perio_tx_fifo_size_01>=0 && perio_tx_fifo_size_01<=32768)
+ params->tx_fifo_size[ 1]=perio_tx_fifo_size_01;
+ else
+ params->tx_fifo_size[ 1]=default_param_perio_tx_fifo_size_01;
+ if(perio_tx_fifo_size_02>=0 && perio_tx_fifo_size_02<=32768)
+ params->tx_fifo_size[ 2]=perio_tx_fifo_size_02;
+ else
+ params->tx_fifo_size[ 2]=default_param_perio_tx_fifo_size_02;
+ if(perio_tx_fifo_size_03>=0 && perio_tx_fifo_size_03<=32768)
+ params->tx_fifo_size[ 3]=perio_tx_fifo_size_03;
+ else
+ params->tx_fifo_size[ 3]=default_param_perio_tx_fifo_size_03;
+ if(perio_tx_fifo_size_04>=0 && perio_tx_fifo_size_04<=32768)
+ params->tx_fifo_size[ 4]=perio_tx_fifo_size_04;
+ else
+ params->tx_fifo_size[ 4]=default_param_perio_tx_fifo_size_04;
+ if(perio_tx_fifo_size_05>=0 && perio_tx_fifo_size_05<=32768)
+ params->tx_fifo_size[ 5]=perio_tx_fifo_size_05;
+ else
+ params->tx_fifo_size[ 5]=default_param_perio_tx_fifo_size_05;
+ if(perio_tx_fifo_size_06>=0 && perio_tx_fifo_size_06<=32768)
+ params->tx_fifo_size[ 6]=perio_tx_fifo_size_06;
+ else
+ params->tx_fifo_size[ 6]=default_param_perio_tx_fifo_size_06;
+ if(perio_tx_fifo_size_07>=0 && perio_tx_fifo_size_07<=32768)
+ params->tx_fifo_size[ 7]=perio_tx_fifo_size_07;
+ else
+ params->tx_fifo_size[ 7]=default_param_perio_tx_fifo_size_07;
+ if(perio_tx_fifo_size_08>=0 && perio_tx_fifo_size_08<=32768)
+ params->tx_fifo_size[ 8]=perio_tx_fifo_size_08;
+ else
+ params->tx_fifo_size[ 8]=default_param_perio_tx_fifo_size_08;
+ if(perio_tx_fifo_size_09>=0 && perio_tx_fifo_size_09<=32768)
+ params->tx_fifo_size[ 9]=perio_tx_fifo_size_09;
+ else
+ params->tx_fifo_size[ 9]=default_param_perio_tx_fifo_size_09;
+ if(perio_tx_fifo_size_10>=0 && perio_tx_fifo_size_10<=32768)
+ params->tx_fifo_size[10]=perio_tx_fifo_size_10;
+ else
+ params->tx_fifo_size[10]=default_param_perio_tx_fifo_size_10;
+ if(perio_tx_fifo_size_11>=0 && perio_tx_fifo_size_11<=32768)
+ params->tx_fifo_size[11]=perio_tx_fifo_size_11;
+ else
+ params->tx_fifo_size[11]=default_param_perio_tx_fifo_size_11;
+ if(perio_tx_fifo_size_12>=0 && perio_tx_fifo_size_12<=32768)
+ params->tx_fifo_size[12]=perio_tx_fifo_size_12;
+ else
+ params->tx_fifo_size[12]=default_param_perio_tx_fifo_size_12;
+ if(perio_tx_fifo_size_13>=0 && perio_tx_fifo_size_13<=32768)
+ params->tx_fifo_size[13]=perio_tx_fifo_size_13;
+ else
+ params->tx_fifo_size[13]=default_param_perio_tx_fifo_size_13;
+ if(perio_tx_fifo_size_14>=0 && perio_tx_fifo_size_14<=32768)
+ params->tx_fifo_size[14]=perio_tx_fifo_size_14;
+ else
+ params->tx_fifo_size[14]=default_param_perio_tx_fifo_size_14;
+ if(perio_tx_fifo_size_15>=0 && perio_tx_fifo_size_15<=32768)
+ params->tx_fifo_size[15]=perio_tx_fifo_size_15;
+ else
+ params->tx_fifo_size[15]=default_param_perio_tx_fifo_size_15;
+ #endif //__DED_FIFO__
+ #endif //__IS_DEVICE__
+}
+
+
+
+
+
+
+
+module_param(dbg_lvl, long, 0444);
+MODULE_PARM_DESC(dbg_lvl, "Debug level.");
+
+module_param(dma_burst_size, short, 0444);
+MODULE_PARM_DESC(dma_burst_size, "DMA Burst Size 0, 1, 4, 8, 16");
+
+module_param(speed, short, 0444);
+MODULE_PARM_DESC(speed, "Speed 0=High Speed 1=Full Speed");
+
+module_param(data_fifo_size, long, 0444);
+MODULE_PARM_DESC(data_fifo_size, "Total number of words in the data FIFO memory 32-32768");
+
+#ifdef __IS_DEVICE__
+ module_param(rx_fifo_size, long, 0444);
+ MODULE_PARM_DESC(rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
+
+ #ifdef __DED_FIFO__
+ module_param(tx_fifo_size_00, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_00, "Number of words in the Tx FIFO #00 16-32768");
+ module_param(tx_fifo_size_01, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_01, "Number of words in the Tx FIFO #01 0-32768");
+ module_param(tx_fifo_size_02, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_02, "Number of words in the Tx FIFO #02 0-32768");
+ module_param(tx_fifo_size_03, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_03, "Number of words in the Tx FIFO #03 0-32768");
+ module_param(tx_fifo_size_04, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_04, "Number of words in the Tx FIFO #04 0-32768");
+ module_param(tx_fifo_size_05, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_05, "Number of words in the Tx FIFO #05 0-32768");
+ module_param(tx_fifo_size_06, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_06, "Number of words in the Tx FIFO #06 0-32768");
+ module_param(tx_fifo_size_07, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_07, "Number of words in the Tx FIFO #07 0-32768");
+ module_param(tx_fifo_size_08, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_08, "Number of words in the Tx FIFO #08 0-32768");
+ module_param(tx_fifo_size_09, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_09, "Number of words in the Tx FIFO #09 0-32768");
+ module_param(tx_fifo_size_10, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_10, "Number of words in the Tx FIFO #10 0-32768");
+ module_param(tx_fifo_size_11, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_11, "Number of words in the Tx FIFO #11 0-32768");
+ module_param(tx_fifo_size_12, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_12, "Number of words in the Tx FIFO #12 0-32768");
+ module_param(tx_fifo_size_13, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_13, "Number of words in the Tx FIFO #13 0-32768");
+ module_param(tx_fifo_size_14, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_14, "Number of words in the Tx FIFO #14 0-32768");
+ module_param(tx_fifo_size_15, long, 0444);
+ MODULE_PARM_DESC(tx_fifo_size_15, "Number of words in the Tx FIFO #15 0-32768");
+
+ module_param(thr_ctl, short, 0444);
+ MODULE_PARM_DESC(thr_ctl, "0=Without 1=With Theshold Ctrl");
+
+ module_param(tx_thr_length, long, 0444);
+ MODULE_PARM_DESC(tx_thr_length, "TX Threshold length");
+
+ module_param(rx_thr_length, long, 0444);
+ MODULE_PARM_DESC(rx_thr_length, "RX Threshold length");
+
+ #else
+ module_param(nperio_tx_fifo_size, long, 0444);
+ MODULE_PARM_DESC(nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
+
+ module_param(perio_tx_fifo_size_01, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_01, "Number of words in the periodic Tx FIFO #01 0-32768");
+ module_param(perio_tx_fifo_size_02, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_02, "Number of words in the periodic Tx FIFO #02 0-32768");
+ module_param(perio_tx_fifo_size_03, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_03, "Number of words in the periodic Tx FIFO #03 0-32768");
+ module_param(perio_tx_fifo_size_04, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_04, "Number of words in the periodic Tx FIFO #04 0-32768");
+ module_param(perio_tx_fifo_size_05, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_05, "Number of words in the periodic Tx FIFO #05 0-32768");
+ module_param(perio_tx_fifo_size_06, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_06, "Number of words in the periodic Tx FIFO #06 0-32768");
+ module_param(perio_tx_fifo_size_07, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_07, "Number of words in the periodic Tx FIFO #07 0-32768");
+ module_param(perio_tx_fifo_size_08, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_08, "Number of words in the periodic Tx FIFO #08 0-32768");
+ module_param(perio_tx_fifo_size_09, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_09, "Number of words in the periodic Tx FIFO #09 0-32768");
+ module_param(perio_tx_fifo_size_10, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_10, "Number of words in the periodic Tx FIFO #10 0-32768");
+ module_param(perio_tx_fifo_size_11, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_11, "Number of words in the periodic Tx FIFO #11 0-32768");
+ module_param(perio_tx_fifo_size_12, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_12, "Number of words in the periodic Tx FIFO #12 0-32768");
+ module_param(perio_tx_fifo_size_13, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_13, "Number of words in the periodic Tx FIFO #13 0-32768");
+ module_param(perio_tx_fifo_size_14, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_14, "Number of words in the periodic Tx FIFO #14 0-32768");
+ module_param(perio_tx_fifo_size_15, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size_15, "Number of words in the periodic Tx FIFO #15 0-32768");
+ #endif//__DED_FIFO__
+ module_param(dev_endpoints, short, 0444);
+ MODULE_PARM_DESC(dev_endpoints, "The number of endpoints in addition to EP0 available for device mode 1-15");
+#endif
+
+#ifdef __IS_HOST__
+ module_param(rx_fifo_size, long, 0444);
+ MODULE_PARM_DESC(rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
+
+ module_param(nperio_tx_fifo_size, long, 0444);
+ MODULE_PARM_DESC(nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
+
+ module_param(perio_tx_fifo_size, long, 0444);
+ MODULE_PARM_DESC(perio_tx_fifo_size, "Number of words in the host periodic Tx FIFO 16-32768");
+
+ module_param(host_channels, short, 0444);
+ MODULE_PARM_DESC(host_channels, "The number of host channel registers to use 1-16");
+#endif
+
+module_param(max_transfer_size, long, 0444);
+MODULE_PARM_DESC(max_transfer_size, "The maximum transfer size supported in bytes 2047-65535");
+
+module_param(max_packet_count, long, 0444);
+MODULE_PARM_DESC(max_packet_count, "The maximum number of packets in a transfer 15-511");
+
+module_param(phy_utmi_width, long, 0444);
+MODULE_PARM_DESC(phy_utmi_width, "Specifies the UTMI+ Data Width 8 or 16 bits");
+
+module_param(turn_around_time_hs, long, 0444);
+MODULE_PARM_DESC(turn_around_time_hs, "Turn-Around time for HS");
+
+module_param(turn_around_time_fs, long, 0444);
+MODULE_PARM_DESC(turn_around_time_fs, "Turn-Around time for FS");
+
+module_param(timeout_cal_hs, long, 0444);
+MODULE_PARM_DESC(timeout_cal_hs, "Timeout Cal for HS");
+
+module_param(timeout_cal_fs, long, 0444);
+MODULE_PARM_DESC(timeout_cal_fs, "Timeout Cal for FS");
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxusb_host.ko b/package/kernel/lantiq/ltq-hcd/src/ifxusb_host.ko
new file mode 100644
index 0000000000..1dd25ca0d6
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxusb_host.ko
Binary files differ
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxusb_plat.h b/package/kernel/lantiq/ltq-hcd/src/ifxusb_plat.h
new file mode 100644
index 0000000000..df959cfa19
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxusb_plat.h
@@ -0,0 +1,1184 @@
+/*****************************************************************************
+ ** FILE NAME : ifxusb_plat.h
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** AUTHOR : Chen, Howard
+ ** DESCRIPTION : This file contains the Platform Specific constants, interfaces
+ ** (functions and macros).
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+
+/*!
+ \defgroup IFXUSB_PLATEFORM_DEFINITION Platform Specific constants, interfaces (functions and macros).
+ \ingroup IFXUSB_DRIVER_V3
+ \brief Maintain plateform specific definitions and macros in this file.
+ Each plateform has its own definition zone.
+ */
+
+/*!
+ \defgroup IFXUSB_PLATEFORM_MEM_ADDR Definition of memory address and size and default parameters
+ \ingroup IFXUSB_PLATEFORM_DEFINITION
+ */
+
+/*!
+ \defgroup IFXUSB_DBG_ROUTINE Routines for debug message
+ \ingroup IFXUSB_PLATEFORM_DEFINITION
+ */
+
+
+/*! \file ifxusb_plat.h
+ \ingroup IFXUSB_DRIVER_V3
+ \brief This file contains the Platform Specific constants, interfaces (functions and macros).
+*/
+
+#if !defined(__IFXUSB_PLAT_H__)
+#define __IFXUSB_PLAT_H__
+
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+
+#define IFXUSB_IOMEM_SIZE 0x00001000
+#define IFXUSB_FIFOMEM_SIZE 0x00010000
+#define IFXUSB_FIFODBG_SIZE 0x00020000
+
+
+
+/*!
+ \addtogroup IFXUSB_PLATEFORM_MEM_ADDR
+ */
+/*@{*/
+#if defined(__UEIP__)
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #define IFXUSB_IRQ 62
+ #define IFXUSB_IOMEM_BASE 0x1e101000
+ #define IFXUSB_FIFOMEM_BASE 0x1e120000
+ #define IFXUSB_FIFODBG_BASE 0x1e140000
+ #define IFXUSB_OC_IRQ 159
+
+ #ifndef DANUBE_RCU_BASE_ADDR
+ #define DANUBE_RCU_BASE_ADDR (0xBF203000)
+ #endif
+
+ #ifndef DANUBE_CGU
+ #define DANUBE_CGU (0xBF103000)
+ #endif
+ #ifndef DANUBE_CGU_IFCCR
+ #define DANUBE_CGU_IFCCR ((volatile unsigned long *)(DANUBE_CGU+ 0x0018))
+ #endif
+ #ifndef DANUBE_PMU
+ #define DANUBE_PMU (KSEG1+0x1F102000)
+ #endif
+ #ifndef DANUBE_PMU_PWDCR
+ #define DANUBE_PMU_PWDCR ((volatile unsigned long *)(DANUBE_PMU+0x001C))
+ #endif
+
+ #ifndef DANUBE_GPIO_P0_OUT
+ #define DANUBE_GPIO_P0_OUT (0xBF103000+0x10)
+ #define DANUBE_GPIO_P0_DIR (0xBF103000+0x18)
+ #define DANUBE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
+ #define DANUBE_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
+ #define DANUBE_GPIO_P0_OD (0xBF103000+0x24)
+ #define DANUBE_GPIO_P0_PUDSEL (0xBF103000+0x2C)
+ #define DANUBE_GPIO_P0_PUDEN (0xBF103000+0x30)
+ #define DANUBE_GPIO_P1_OUT (0xBF103000+0x40)
+ #define DANUBE_GPIO_P1_DIR (0xBF103000+0x48)
+ #define DANUBE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
+ #define DANUBE_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
+ #define DANUBE_GPIO_P1_OD (0xBF103000+0x54)
+ #define DANUBE_GPIO_P1_PUDSEL (0xBF103000+0x5C)
+ #define DANUBE_GPIO_P1_PUDEN (0xBF103000+0x60)
+ #endif
+
+ #define DANUBE_RCU_USBCFG ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x18))
+ #define DANUBE_RCU_RESET ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x10))
+ #define DANUBE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
+ #define DANUBE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
+ #define DANUBE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
+
+ #define default_param_dma_burst_size 4
+
+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
+
+ #define default_param_max_transfer_size -1 //(Max, hwcfg)
+ #define default_param_max_packet_count -1 //(Max, hwcfg)
+ #define default_param_phy_utmi_width 16
+
+ #define default_param_turn_around_time_hs 4
+ #define default_param_turn_around_time_fs 4
+ #define default_param_timeout_cal_hs -1 //(NoChange)
+ #define default_param_timeout_cal_fs -1 //(NoChange)
+
+ #define default_param_data_fifo_size -1 //(Max, hwcfg)
+
+ #ifdef __IS_HOST__
+ #define default_param_host_channels -1 //(Max, hwcfg)
+ #define default_param_rx_fifo_size 640
+ #define default_param_nperio_tx_fifo_size 640
+ #define default_param_perio_tx_fifo_size 768
+ #endif //__IS_HOST__
+
+ #ifdef __IS_DEVICE__
+ #ifdef __DED_INTR__
+// #define default_param_rx_fifo_size 1024
+// #define default_param_nperio_tx_fifo_size 1016
+// #define default_param_perio_tx_fifo_size_01 8
+ #define default_param_rx_fifo_size 1008
+ #define default_param_nperio_tx_fifo_size 1008
+ #define default_param_perio_tx_fifo_size_01 32
+ #else
+ #define default_param_rx_fifo_size 1024
+ #define default_param_nperio_tx_fifo_size 1024
+ #define default_param_perio_tx_fifo_size_01 0
+ #endif
+ #define default_param_perio_tx_fifo_size_02 0
+ #define default_param_perio_tx_fifo_size_03 0
+ #define default_param_perio_tx_fifo_size_04 0
+ #define default_param_perio_tx_fifo_size_05 0
+ #define default_param_perio_tx_fifo_size_06 0
+ #define default_param_perio_tx_fifo_size_07 0
+ #define default_param_perio_tx_fifo_size_08 0
+ #define default_param_perio_tx_fifo_size_09 0
+ #define default_param_perio_tx_fifo_size_10 0
+ #define default_param_perio_tx_fifo_size_11 0
+ #define default_param_perio_tx_fifo_size_12 0
+ #define default_param_perio_tx_fifo_size_13 0
+ #define default_param_perio_tx_fifo_size_14 0
+ #define default_param_perio_tx_fifo_size_15 0
+ #endif //__IS_DEVICE__
+
+ #elif defined(__IS_AMAZON_SE__)
+ //#include <asm/amazon_se/amazon_se.h>
+ //#include <asm/amazon_se/irq.h>
+
+ #define IFXUSB_IRQ 39
+ #define IFXUSB_IOMEM_BASE 0x1e101000
+ #define IFXUSB_FIFOMEM_BASE 0x1e120000
+ #define IFXUSB_FIFODBG_BASE 0x1e140000
+ #define IFXUSB_OC_IRQ 20
+
+ #ifndef AMAZON_SE_RCU_BASE_ADDR
+ #define AMAZON_SE_RCU_BASE_ADDR (0xBF203000)
+ #endif
+ #define AMAZON_SE_RCU_USBCFG ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x18))
+ #define AMAZON_SE_RCU_RESET ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x10))
+ #define AMAZON_SE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
+ #define AMAZON_SE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
+ #define AMAZON_SE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
+
+ #ifndef AMAZON_SE_GPIO_P0_OUT
+ #define AMAZON_SE_GPIO_P0_OUT (0xBF103000+0x10)
+ #define AMAZON_SE_GPIO_P0_DIR (0xBF103000+0x18)
+ #define AMAZON_SE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
+ #define AMAZON_SE_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
+ #define AMAZON_SE_GPIO_P0_OD (0xBF103000+0x24)
+ #define AMAZON_SE_GPIO_P0_PUDSEL (0xBF103000+0x2C)
+ #define AMAZON_SE_GPIO_P0_PUDEN (0xBF103000+0x30)
+ #define AMAZON_SE_GPIO_P1_OUT (0xBF103000+0x40)
+ #define AMAZON_SE_GPIO_P1_DIR (0xBF103000+0x48)
+ #define AMAZON_SE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
+ #define AMAZON_SE_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
+ #define AMAZON_SE_GPIO_P1_OD (0xBF103000+0x54)
+ #define AMAZON_SE_GPIO_P1_PUDSEL (0xBF103000+0x5C)
+ #define AMAZON_SE_GPIO_P1_PUDEN (0xBF103000+0x60)
+ #endif
+
+ #ifndef AMAZON_SE_CGU
+ #define AMAZON_SE_CGU (0xBF103000)
+ #endif
+ #ifndef AMAZON_SE_CGU_IFCCR
+ #define AMAZON_SE_CGU_IFCCR ((volatile unsigned long *)(AMAZON_SE_CGU+ 0x0018))
+ #endif
+ #ifndef AMAZON_SE_PMU
+ #define AMAZON_SE_PMU (KSEG1+0x1F102000)
+ #endif
+ #ifndef AMAZON_SE_PMU_PWDCR
+ #define AMAZON_SE_PMU_PWDCR ((volatile unsigned long *)(AMAZON_SE_PMU+0x001C))
+ #endif
+
+ #define default_param_dma_burst_size 4
+
+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
+
+ #define default_param_max_transfer_size -1 //(Max, hwcfg)
+ #define default_param_max_packet_count -1 //(Max, hwcfg)
+ #define default_param_phy_utmi_width 16
+
+ #define default_param_turn_around_time_hs 4 //(NoChange)
+ #define default_param_turn_around_time_fs 4 //(NoChange)
+ #define default_param_timeout_cal_hs -1 //(NoChange)
+ #define default_param_timeout_cal_fs -1 //(NoChange)
+
+ #define default_param_data_fifo_size -1 //(Max, hwcfg)
+
+ #ifdef __IS_HOST__
+ #define default_param_host_channels -1 //(Max, hwcfg)
+ #define default_param_rx_fifo_size 240
+ #define default_param_nperio_tx_fifo_size 240
+ #define default_param_perio_tx_fifo_size 32
+ #endif //__IS_HOST__
+ #ifdef __IS_DEVICE__
+ #ifdef __DED_INTR__
+// #define default_param_rx_fifo_size 256
+// #define default_param_nperio_tx_fifo_size 248
+// #define default_param_perio_tx_fifo_size_01 8
+ #define default_param_rx_fifo_size 240
+ #define default_param_nperio_tx_fifo_size 240
+ #define default_param_perio_tx_fifo_size_01 32
+ #else
+ #define default_param_rx_fifo_size 256
+ #define default_param_nperio_tx_fifo_size 256
+ #define default_param_perio_tx_fifo_size_01 0
+ #endif
+ #define default_param_perio_tx_fifo_size_02 0
+ #define default_param_perio_tx_fifo_size_03 0
+ #define default_param_perio_tx_fifo_size_04 0
+ #define default_param_perio_tx_fifo_size_05 0
+ #define default_param_perio_tx_fifo_size_06 0
+ #define default_param_perio_tx_fifo_size_07 0
+ #define default_param_perio_tx_fifo_size_08 0
+ #define default_param_perio_tx_fifo_size_09 0
+ #define default_param_perio_tx_fifo_size_10 0
+ #define default_param_perio_tx_fifo_size_11 0
+ #define default_param_perio_tx_fifo_size_12 0
+ #define default_param_perio_tx_fifo_size_13 0
+ #define default_param_perio_tx_fifo_size_14 0
+ #define default_param_perio_tx_fifo_size_15 0
+ #endif //__IS_DEVICE__
+
+ #elif defined(__IS_AR9__)
+ #define IFXUSB1_IRQ 62
+ #define IFXUSB1_IOMEM_BASE 0x1E101000
+ #define IFXUSB1_FIFOMEM_BASE 0x1E120000
+ #define IFXUSB1_FIFODBG_BASE 0x1E140000
+
+ #define IFXUSB2_IRQ 91
+ #define IFXUSB2_IOMEM_BASE 0x1E106000
+ #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000
+ #define IFXUSB2_FIFODBG_BASE 0x1E1C0000
+
+ #define IFXUSB_OC_IRQ 68
+
+ #ifndef AR9_RCU_BASE_ADDR
+ #define AR9_RCU_BASE_ADDR (0xBF203000)
+ #endif
+
+ #ifndef AR9_CGU
+ #define AR9_CGU (0xBF103000)
+ #endif
+ #ifndef AR9_CGU_IFCCR
+ #define AR9_CGU_IFCCR ((volatile unsigned long *)(AR9_CGU+ 0x0018))
+ #endif
+
+ #ifndef AR9_PMU
+ #define AR9_PMU (KSEG1+0x1F102000)
+ #endif
+ #ifndef AR9_PMU_PWDCR
+ #define AR9_PMU_PWDCR ((volatile unsigned long *)(AR9_PMU+0x001C))
+ #endif
+
+ #ifndef AR9_GPIO_P0_OUT
+ #define AR9_GPIO_P0_OUT (0xBF103000+0x10)
+ #define AR9_GPIO_P0_DIR (0xBF103000+0x18)
+ #define AR9_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
+ #define AR9_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
+ #define AR9_GPIO_P0_OD (0xBF103000+0x24)
+ #define AR9_GPIO_P0_PUDSEL (0xBF103000+0x2C)
+ #define AR9_GPIO_P0_PUDEN (0xBF103000+0x30)
+ #define AR9_GPIO_P1_OUT (0xBF103000+0x40)
+ #define AR9_GPIO_P1_DIR (0xBF103000+0x48)
+ #define AR9_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
+ #define AR9_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
+ #define AR9_GPIO_P1_OD (0xBF103000+0x54)
+ #define AR9_GPIO_P1_PUDSEL (0xBF103000+0x5C)
+ #define AR9_GPIO_P1_PUDEN (0xBF103000+0x60)
+ #endif
+
+ #define AR9_RCU_USB1CFG ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x18))
+ #define AR9_RCU_USB2CFG ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x34))
+ #define AR9_RCU_USBRESET ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x10))
+ #define AR9_USBCFG_ARB 7 //
+ #define AR9_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
+ #define AR9_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
+ #define AR9_USBCFG_SLV_END_BIT 17 // 0:little_end, 1:big_end
+
+ #define default_param_dma_burst_size 4
+
+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
+
+ #define default_param_max_transfer_size -1 //(Max, hwcfg)
+ #define default_param_max_packet_count -1 //(Max, hwcfg)
+ #define default_param_phy_utmi_width 16
+
+ #define default_param_turn_around_time_hs 4 //(NoChange)
+ #define default_param_turn_around_time_fs 4 //(NoChange)
+ #define default_param_timeout_cal_hs -1 //(NoChange)
+ #define default_param_timeout_cal_fs -1 //(NoChange)
+
+ #define default_param_data_fifo_size -1 //(Max, hwcfg)
+
+ #ifdef __IS_HOST__
+ #define default_param_host_channels -1 //(Max, hwcfg)
+ #define default_param_rx_fifo_size 240
+ #define default_param_nperio_tx_fifo_size 240
+ #define default_param_perio_tx_fifo_size 32
+ #endif //__IS_HOST__
+ #ifdef __IS_DEVICE__
+ #ifdef __DED_INTR__
+// #define default_param_rx_fifo_size 256
+// #define default_param_nperio_tx_fifo_size 248
+// #define default_param_perio_tx_fifo_size_01 8
+ #define default_param_rx_fifo_size 240
+ #define default_param_nperio_tx_fifo_size 240
+ #define default_param_perio_tx_fifo_size_01 32
+ #else
+ #define default_param_rx_fifo_size 256
+ #define default_param_nperio_tx_fifo_size 256
+ #define default_param_perio_tx_fifo_size_01 0
+ #endif
+ #define default_param_perio_tx_fifo_size_02 0
+ #define default_param_perio_tx_fifo_size_03 0
+ #define default_param_perio_tx_fifo_size_04 0
+ #define default_param_perio_tx_fifo_size_05 0
+ #define default_param_perio_tx_fifo_size_06 0
+ #define default_param_perio_tx_fifo_size_07 0
+ #define default_param_perio_tx_fifo_size_08 0
+ #define default_param_perio_tx_fifo_size_09 0
+ #define default_param_perio_tx_fifo_size_10 0
+ #define default_param_perio_tx_fifo_size_11 0
+ #define default_param_perio_tx_fifo_size_12 0
+ #define default_param_perio_tx_fifo_size_13 0
+ #define default_param_perio_tx_fifo_size_14 0
+ #define default_param_perio_tx_fifo_size_15 0
+ #endif //__IS_DEVICE__
+
+ #elif defined(__IS_VR9__)
+ #define IFXUSB1_IRQ 62
+ #define IFXUSB1_IOMEM_BASE 0x1E101000
+ #define IFXUSB1_FIFOMEM_BASE 0x1E120000
+ #define IFXUSB1_FIFODBG_BASE 0x1E140000
+
+ #define IFXUSB2_IRQ 91
+ #define IFXUSB2_IOMEM_BASE 0x1E106000
+ #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000
+ #define IFXUSB2_FIFODBG_BASE 0x1E1C0000
+ #define IFXUSB_OC_IRQ 60
+
+ #ifndef IFX_MPS
+ #define IFX_MPS (KSEG1+0x1F107000)
+ #endif
+ #ifndef IFX_MPS_CHIPID
+ #define IFX_MPS_CHIPID ((volatile unsigned long *)(IFX_MPS + 0x0344))
+ #endif
+
+ #ifndef VR9_RCU_BASE_ADDR
+ #define VR9_RCU_BASE_ADDR (0xBF203000)
+ #endif
+
+ #ifndef VR9_CGU
+ #define VR9_CGU (0xBF103000)
+ #endif
+ #ifndef VR9_CGU_IFCCR
+ #define VR9_CGU_IFCCR ((volatile unsigned long *)(VR9_CGU+ 0x0018))
+ #endif
+
+ #ifndef VR9_PMU
+ #define VR9_PMU (KSEG1+0x1F102000)
+ #endif
+ #ifndef VR9_PMU_PWDCR
+ #define VR9_PMU_PWDCR ((volatile unsigned long *)(VR9_PMU+0x001C))
+ #endif
+
+ #ifndef VR9_GPIO_P0_OUT
+ #define VR9_GPIO_P0_OUT (0xBF103000+0x10)
+ #define VR9_GPIO_P0_DIR (0xBF103000+0x18)
+ #define VR9_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
+ #define VR9_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
+ #define VR9_GPIO_P0_OD (0xBF103000+0x24)
+ #define VR9_GPIO_P0_PUDSEL (0xBF103000+0x2C)
+ #define VR9_GPIO_P0_PUDEN (0xBF103000+0x30)
+ #define VR9_GPIO_P1_OUT (0xBF103000+0x40)
+ #define VR9_GPIO_P1_DIR (0xBF103000+0x48)
+ #define VR9_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
+ #define VR9_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
+ #define VR9_GPIO_P1_OD (0xBF103000+0x54)
+ #define VR9_GPIO_P1_PUDSEL (0xBF103000+0x5C)
+ #define VR9_GPIO_P1_PUDEN (0xBF103000+0x60)
+ #endif
+
+ #define VR9_RCU_USB1CFG ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x18))
+ #define VR9_RCU_USB2CFG ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x34))
+ #define VR9_RCU_USB_ANA_CFG1A ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x38))
+ #define VR9_RCU_USB_ANA_CFG1B ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x3C))
+ #define VR9_RCU_USBRESET ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x10))
+ #define VR9_RCU_USBRESET2 ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x48))
+ #define VR9_USBCFG_ARB 7 //
+ #define VR9_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
+ #define VR9_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
+ #define VR9_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
+
+// #define default_param_dma_burst_size 4 //(ALL)
+ //WA for AHB
+ #define default_param_dma_burst_size 0 //(ALL)
+ #define default_param_dma_burst_size_n 4 //(ALL)
+
+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
+
+ #define default_param_max_transfer_size -1 //(Max, hwcfg)
+ #define default_param_max_packet_count -1 //(Max, hwcfg)
+ #define default_param_phy_utmi_width 16
+
+ #define default_param_turn_around_time_hs 6 //(NoChange) snpsid >= 0x4f54260a
+ #define default_param_turn_around_time_fs 6 //(NoChange) snpsid >= 0x4f54260a
+ #define default_param_timeout_cal_hs -1 //(NoChange)
+ #define default_param_timeout_cal_fs -1 //(NoChange)
+
+ #define default_param_data_fifo_size -1 //(Max, hwcfg)
+
+ #ifdef __IS_HOST__
+ #define default_param_host_channels -1 //(Max, hwcfg)
+ #define default_param_rx_fifo_size 240
+ #define default_param_nperio_tx_fifo_size 240
+ #define default_param_perio_tx_fifo_size 32
+ #endif //__IS_HOST__
+ #ifdef __IS_DEVICE__
+#if 0
+ #define default_param_rx_fifo_size 256
+ #define default_param_tx_fifo_size_00 -1
+ #define default_param_tx_fifo_size_01 -1
+ #define default_param_tx_fifo_size_02 -1
+#else
+ #define default_param_rx_fifo_size 256
+ #define default_param_tx_fifo_size_00 32
+ #define default_param_tx_fifo_size_01 200
+ #define default_param_tx_fifo_size_02 8
+#endif
+ #define default_param_tx_fifo_size_03 -1
+ #define default_param_tx_fifo_size_04 -1
+ #define default_param_tx_fifo_size_05 -1
+ #define default_param_tx_fifo_size_06 -1
+ #define default_param_tx_fifo_size_07 -1
+ #define default_param_tx_fifo_size_08 -1
+ #define default_param_tx_fifo_size_09 -1
+ #define default_param_tx_fifo_size_10 -1
+ #define default_param_tx_fifo_size_11 -1
+ #define default_param_tx_fifo_size_12 -1
+ #define default_param_tx_fifo_size_13 -1
+ #define default_param_tx_fifo_size_14 -1
+ #define default_param_tx_fifo_size_15 -1
+ #define default_param_dma_unalgned_tx -1
+ #define default_param_dma_unalgned_rx -1
+ #define default_param_thr_ctl -1
+ #define default_param_tx_thr_length -1
+ #define default_param_rx_thr_length -1
+ #endif //__IS_DEVICE__
+
+ #elif defined(__IS_AR10__)
+ #define IFXUSB1_IRQ 54
+ #define IFXUSB1_IOMEM_BASE 0x1E101000
+ #define IFXUSB1_FIFOMEM_BASE 0x1E120000
+ #define IFXUSB1_FIFODBG_BASE 0x1E140000
+ #define IFXUSB1_OC_IRQ 60
+
+ #define IFXUSB2_IRQ 83
+ #define IFXUSB2_IOMEM_BASE 0x1E106000
+ #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000
+ #define IFXUSB2_FIFODBG_BASE 0x1E1C0000
+ #define IFXUSB2_OC_IRQ 56
+
+ #ifndef AR10_RCU_BASE_ADDR
+ #define AR10_RCU_BASE_ADDR (0xBF203000)
+ #endif
+ #ifndef AR10_CGU
+ #define AR10_CGU (0xBF103000)
+ #endif
+
+ #ifndef AR10_CGU_IFCCR
+ #define AR10_CGU_IFCCR ((volatile unsigned long *)(AR10_CGU+ 0x0018))
+ #endif
+ #ifndef AR10_PMU
+ #define AR10_PMU (KSEG1+0x1F102000)
+ #endif
+ #ifndef AR10_PMU_PWDCR
+ #define AR10_PMU_PWDCR ((volatile unsigned long *)(AR10_PMU+0x0044))
+ #endif
+
+ #ifndef AR10_GPIO_P0_OUT
+ #define AR10_GPIO_P0_OUT (0xBF103000+0x10)
+ #define AR10_GPIO_P0_DIR (0xBF103000+0x18)
+ #define AR10_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
+ #define AR10_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
+ #define AR10_GPIO_P0_OD (0xBF103000+0x24)
+ #define AR10_GPIO_P0_PUDSEL (0xBF103000+0x2C)
+ #define AR10_GPIO_P0_PUDEN (0xBF103000+0x30)
+ #define AR10_GPIO_P1_OUT (0xBF103000+0x40)
+ #define AR10_GPIO_P1_DIR (0xBF103000+0x48)
+ #define AR10_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
+ #define AR10_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
+ #define AR10_GPIO_P1_OD (0xBF103000+0x54)
+ #define AR10_GPIO_P1_PUDSEL (0xBF103000+0x5C)
+ #define AR10_GPIO_P1_PUDEN (0xBF103000+0x60)
+ #endif
+
+ #define AR10_RCU_USB1CFG ((volatile unsigned long *)(AR10_RCU_BASE_ADDR + 0x18))
+ #define AR10_RCU_USB2CFG ((volatile unsigned long *)(AR10_RCU_BASE_ADDR + 0x34))
+ #define AR10_RCU_USB_ANA_CFG1A ((volatile unsigned long *)(AR10_RCU_BASE_ADDR + 0x38))
+ #define AR10_RCU_USB_ANA_CFG1B ((volatile unsigned long *)(AR10_RCU_BASE_ADDR + 0x3C))
+
+ #define AR10_RCU_USBRESET ((volatile unsigned long *)(AR10_RCU_BASE_ADDR + 0x10))
+
+ #define AR10_USBCFG_ARB 7 //
+ #define AR10_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
+ #define AR10_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
+ #define AR10_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
+
+// #define default_param_dma_burst_size 4 //(ALL)
+ //WA for AHB
+ #define default_param_dma_burst_size 0 //(ALL)
+
+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
+
+ #define default_param_max_transfer_size -1 //(Max, hwcfg)
+ #define default_param_max_packet_count -1 //(Max, hwcfg)
+ #define default_param_phy_utmi_width 16
+
+ #define default_param_turn_around_time_hs 6 //(NoChange) snpsid >= 0x4f54260a
+ #define default_param_turn_around_time_fs 6 //(NoChange) snpsid >= 0x4f54260a
+ #define default_param_timeout_cal_hs -1 //(NoChange)
+ #define default_param_timeout_cal_fs -1 //(NoChange)
+
+ #define default_param_data_fifo_size -1 //(Max, hwcfg)
+
+ #ifdef __IS_HOST__
+ #define default_param_host_channels -1 //(Max, hwcfg)
+ #define default_param_rx_fifo_size 240
+ #define default_param_nperio_tx_fifo_size 240
+ #define default_param_perio_tx_fifo_size 32
+ #endif //__IS_HOST__
+ #ifdef __IS_DEVICE__
+#if 0
+ #define default_param_rx_fifo_size 256
+ #define default_param_tx_fifo_size_00 -1
+ #define default_param_tx_fifo_size_01 -1
+ #define default_param_tx_fifo_size_02 -1
+#else
+ #define default_param_rx_fifo_size 256
+ #define default_param_tx_fifo_size_00 32
+ #define default_param_tx_fifo_size_01 200
+ #define default_param_tx_fifo_size_02 8
+#endif
+ #define default_param_tx_fifo_size_03 -1
+ #define default_param_tx_fifo_size_04 -1
+ #define default_param_tx_fifo_size_05 -1
+ #define default_param_tx_fifo_size_06 -1
+ #define default_param_tx_fifo_size_07 -1
+ #define default_param_tx_fifo_size_08 -1
+ #define default_param_tx_fifo_size_09 -1
+ #define default_param_tx_fifo_size_10 -1
+ #define default_param_tx_fifo_size_11 -1
+ #define default_param_tx_fifo_size_12 -1
+ #define default_param_tx_fifo_size_13 -1
+ #define default_param_tx_fifo_size_14 -1
+ #define default_param_tx_fifo_size_15 -1
+ #define default_param_dma_unalgned_tx -1
+ #define default_param_dma_unalgned_rx -1
+ #define default_param_thr_ctl -1
+ #define default_param_tx_thr_length -1
+ #define default_param_rx_thr_length -1
+ #endif //__IS_DEVICE__
+ #else // __IS_AR10__
+ #error "Please choose one platform!!"
+ #endif // __IS_VR9__
+
+#else //UEIP
+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__)
+ #define IFXUSB_IRQ 54
+ #define IFXUSB_IOMEM_BASE 0x1e101000
+ #define IFXUSB_FIFOMEM_BASE 0x1e120000
+ #define IFXUSB_FIFODBG_BASE 0x1e140000
+ #define IFXUSB_OC_IRQ 151
+
+
+ #ifndef DANUBE_RCU_BASE_ADDR
+ #define DANUBE_RCU_BASE_ADDR (0xBF203000)
+ #endif
+
+ #ifndef DANUBE_CGU
+ #define DANUBE_CGU (0xBF103000)
+ #endif
+ #ifndef DANUBE_CGU_IFCCR
+ #define DANUBE_CGU_IFCCR ((volatile unsigned long *)(DANUBE_CGU+ 0x0018))
+ #endif
+ #ifndef DANUBE_PMU
+ #define DANUBE_PMU (KSEG1+0x1F102000)
+ #endif
+ #ifndef DANUBE_PMU_PWDCR
+ #define DANUBE_PMU_PWDCR ((volatile unsigned long *)(DANUBE_PMU+0x001C))
+ #endif
+
+ #ifndef DANUBE_GPIO_P0_OUT
+ #define DANUBE_GPIO_P0_OUT (0xBF103000+0x10)
+ #define DANUBE_GPIO_P0_DIR (0xBF103000+0x18)
+ #define DANUBE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
+ #define DANUBE_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
+ #define DANUBE_GPIO_P0_OD (0xBF103000+0x24)
+ #define DANUBE_GPIO_P0_PUDSEL (0xBF103000+0x2C)
+ #define DANUBE_GPIO_P0_PUDEN (0xBF103000+0x30)
+ #define DANUBE_GPIO_P1_OUT (0xBF103000+0x40)
+ #define DANUBE_GPIO_P1_DIR (0xBF103000+0x48)
+ #define DANUBE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
+ #define DANUBE_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
+ #define DANUBE_GPIO_P1_OD (0xBF103000+0x54)
+ #define DANUBE_GPIO_P1_PUDSEL (0xBF103000+0x5C)
+ #define DANUBE_GPIO_P1_PUDEN (0xBF103000+0x60)
+ #endif
+
+
+ #define DANUBE_RCU_USBCFG ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x18))
+ #define DANUBE_RCU_RESET ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x10))
+ #define DANUBE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
+ #define DANUBE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
+ #define DANUBE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
+
+ #define default_param_dma_burst_size 4
+
+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
+
+ #define default_param_max_transfer_size -1 //(Max, hwcfg)
+ #define default_param_max_packet_count -1 //(Max, hwcfg)
+ #define default_param_phy_utmi_width 16
+
+ #define default_param_turn_around_time_hs 4 //(NoChange)
+ #define default_param_turn_around_time_fs 4 //(NoChange)
+ #define default_param_timeout_cal_hs -1 //(NoChange)
+ #define default_param_timeout_cal_fs -1 //(NoChange)
+
+ #define default_param_data_fifo_size -1 //(Max, hwcfg)
+ #ifdef __IS_HOST__
+ #define default_param_host_channels -1 //(Max, hwcfg)
+ #define default_param_rx_fifo_size 640
+ #define default_param_nperio_tx_fifo_size 640
+ #define default_param_perio_tx_fifo_size 768
+ #endif //__IS_HOST__
+
+ #ifdef __IS_DEVICE__
+ #ifdef __DED_INTR__
+ #define default_param_rx_fifo_size 1024
+ #define default_param_nperio_tx_fifo_size 1016
+ #define default_param_perio_tx_fifo_size_01 8
+ #else
+ #define default_param_rx_fifo_size 1024
+ #define default_param_nperio_tx_fifo_size 1024
+ #define default_param_perio_tx_fifo_size_01 0
+ #endif
+ #define default_param_perio_tx_fifo_size_02 0
+ #define default_param_perio_tx_fifo_size_03 0
+ #define default_param_perio_tx_fifo_size_04 0
+ #define default_param_perio_tx_fifo_size_05 0
+ #define default_param_perio_tx_fifo_size_06 0
+ #define default_param_perio_tx_fifo_size_07 0
+ #define default_param_perio_tx_fifo_size_08 0
+ #define default_param_perio_tx_fifo_size_09 0
+ #define default_param_perio_tx_fifo_size_10 0
+ #define default_param_perio_tx_fifo_size_11 0
+ #define default_param_perio_tx_fifo_size_12 0
+ #define default_param_perio_tx_fifo_size_13 0
+ #define default_param_perio_tx_fifo_size_14 0
+ #define default_param_perio_tx_fifo_size_15 0
+ #endif //__IS_DEVICE__
+
+ #elif defined(__IS_AMAZON_SE__)
+ #include <asm/amazon_se/amazon_se.h>
+ //#include <asm/amazon_se/irq.h>
+
+ #define IFXUSB_IRQ 31
+ #define IFXUSB_IOMEM_BASE 0x1e101000
+ #define IFXUSB_FIFOMEM_BASE 0x1e120000
+ #define IFXUSB_FIFODBG_BASE 0x1e140000
+ #define IFXUSB_OC_IRQ 20
+
+ #define AMAZON_SE_RCU_USBCFG ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x18))
+ #define AMAZON_SE_RCU_RESET ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x10))
+ #define AMAZON_SE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
+ #define AMAZON_SE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
+ #define AMAZON_SE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
+
+ #ifndef AMAZON_SE_GPIO_P0_OUT
+ #define AMAZON_SE_GPIO_P0_OUT (0xBF103000+0x10)
+ #define AMAZON_SE_GPIO_P0_DIR (0xBF103000+0x18)
+ #define AMAZON_SE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
+ #define AMAZON_SE_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
+ #define AMAZON_SE_GPIO_P0_OD (0xBF103000+0x24)
+ #define AMAZON_SE_GPIO_P0_PUDSEL (0xBF103000+0x2C)
+ #define AMAZON_SE_GPIO_P0_PUDEN (0xBF103000+0x30)
+ #define AMAZON_SE_GPIO_P1_OUT (0xBF103000+0x40)
+ #define AMAZON_SE_GPIO_P1_DIR (0xBF103000+0x48)
+ #define AMAZON_SE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
+ #define AMAZON_SE_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
+ #define AMAZON_SE_GPIO_P1_OD (0xBF103000+0x54)
+ #define AMAZON_SE_GPIO_P1_PUDSEL (0xBF103000+0x5C)
+ #define AMAZON_SE_GPIO_P1_PUDEN (0xBF103000+0x60)
+ #endif
+
+
+ #ifndef AMAZON_SE_CGU
+ #define AMAZON_SE_CGU (0xBF103000)
+ #endif
+ #ifndef AMAZON_SE_CGU_IFCCR
+ #define AMAZON_SE_CGU_IFCCR ((volatile unsigned long *)(AMAZON_SE_CGU+ 0x0018))
+ #endif
+ #ifndef AMAZON_SE_PMU
+ #define AMAZON_SE_PMU (KSEG1+0x1F102000)
+ #endif
+ #ifndef AMAZON_SE_PMU_PWDCR
+ #define AMAZON_SE_PMU_PWDCR ((volatile unsigned long *)(AMAZON_SE_PMU+0x001C))
+ #endif
+
+ #define default_param_dma_burst_size 4
+
+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
+
+ #define default_param_max_transfer_size -1 //(Max, hwcfg)
+ #define default_param_max_packet_count -1 //(Max, hwcfg)
+ #define default_param_phy_utmi_width 16
+
+ #define default_param_turn_around_time_hs 4 //(NoChange)
+ #define default_param_turn_around_time_fs 4 //(NoChange)
+ #define default_param_timeout_cal_hs -1 //(NoChange)
+ #define default_param_timeout_cal_fs -1 //(NoChange)
+
+ #define default_param_data_fifo_size -1 //(Max, hwcfg)
+
+ #ifdef __IS_HOST__
+ #define default_param_host_channels -1 //(Max, hwcfg)
+ #define default_param_rx_fifo_size 240
+ #define default_param_nperio_tx_fifo_size 240
+ #define default_param_perio_tx_fifo_size 32
+ #endif //__IS_HOST__
+ #ifdef __IS_DEVICE__
+ #ifdef __DED_INTR__
+ #define default_param_rx_fifo_size 256
+ #define default_param_nperio_tx_fifo_size 248
+ #define default_param_perio_tx_fifo_size_01 8
+ #else
+ #define default_param_rx_fifo_size 256
+ #define default_param_nperio_tx_fifo_size 256
+ #define default_param_perio_tx_fifo_size_01 0
+ #endif
+ #define default_param_perio_tx_fifo_size_02 0
+ #define default_param_perio_tx_fifo_size_03 0
+ #define default_param_perio_tx_fifo_size_04 0
+ #define default_param_perio_tx_fifo_size_05 0
+ #define default_param_perio_tx_fifo_size_06 0
+ #define default_param_perio_tx_fifo_size_07 0
+ #define default_param_perio_tx_fifo_size_08 0
+ #define default_param_perio_tx_fifo_size_09 0
+ #define default_param_perio_tx_fifo_size_10 0
+ #define default_param_perio_tx_fifo_size_11 0
+ #define default_param_perio_tx_fifo_size_12 0
+ #define default_param_perio_tx_fifo_size_13 0
+ #define default_param_perio_tx_fifo_size_14 0
+ #define default_param_perio_tx_fifo_size_15 0
+ #endif //__IS_DEVICE__
+
+ #elif defined(__IS_AR9__)
+ #define IFXUSB1_IRQ 54
+ #define IFXUSB1_IOMEM_BASE 0x1E101000
+ #define IFXUSB1_FIFOMEM_BASE 0x1E120000
+ #define IFXUSB1_FIFODBG_BASE 0x1E140000
+
+ #define IFXUSB2_IRQ 83
+ #define IFXUSB2_IOMEM_BASE 0x1E106000
+ #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000
+ #define IFXUSB2_FIFODBG_BASE 0x1E1C0000
+
+ #define IFXUSB_OC_IRQ 60
+
+ #ifndef AMAZON_S_RCU_BASE_ADDR
+ #define AMAZON_S_RCU_BASE_ADDR (0xBF203000)
+ #endif
+
+ #ifndef AMAZON_S_CGU
+ #define AMAZON_S_CGU (0xBF103000)
+ #endif
+ #ifndef AMAZON_S_CGU_IFCCR
+ #define AMAZON_S_CGU_IFCCR ((volatile unsigned long *)(AMAZON_S_CGU+ 0x0018))
+ #endif
+
+ #ifndef AMAZON_S_PMU
+ #define AMAZON_S_PMU (KSEG1+0x1F102000)
+ #endif
+ #ifndef AMAZON_S_PMU_PWDCR
+ #define AMAZON_S_PMU_PWDCR ((volatile unsigned long *)(AMAZON_S_PMU+0x001C))
+ #endif
+
+ #ifndef AMAZON_S_GPIO_P0_OUT
+ #define AMAZON_S_GPIO_P0_OUT (0xBF103000+0x10)
+ #define AMAZON_S_GPIO_P0_DIR (0xBF103000+0x18)
+ #define AMAZON_S_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
+ #define AMAZON_S_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
+ #define AMAZON_S_GPIO_P0_OD (0xBF103000+0x24)
+ #define AMAZON_S_GPIO_P0_PUDSEL (0xBF103000+0x2C)
+ #define AMAZON_S_GPIO_P0_PUDEN (0xBF103000+0x30)
+ #define AMAZON_S_GPIO_P1_OUT (0xBF103000+0x40)
+ #define AMAZON_S_GPIO_P1_DIR (0xBF103000+0x48)
+ #define AMAZON_S_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
+ #define AMAZON_S_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
+ #define AMAZON_S_GPIO_P1_OD (0xBF103000+0x54)
+ #define AMAZON_S_GPIO_P1_PUDSEL (0xBF103000+0x5C)
+ #define AMAZON_S_GPIO_P1_PUDEN (0xBF103000+0x60)
+ #endif
+
+ #define AMAZON_S_RCU_USB1CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x18))
+ #define AMAZON_S_RCU_USB2CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x34))
+ #define AMAZON_S_RCU_USBRESET ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x10))
+ #define AMAZON_S_USBCFG_ARB 7 //
+ #define AMAZON_S_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
+ #define AMAZON_S_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
+ #define AMAZON_S_USBCFG_SLV_END_BIT 17 // 0:little_end, 1:big_end
+
+ #define default_param_dma_burst_size 4
+
+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
+
+ #define default_param_max_transfer_size -1 //(Max, hwcfg)
+ #define default_param_max_packet_count -1 //(Max, hwcfg)
+ #define default_param_phy_utmi_width 16
+
+ #define default_param_turn_around_time_hs 4 //(NoChange)
+ #define default_param_turn_around_time_fs 4 //(NoChange)
+ #define default_param_timeout_cal_hs -1 //(NoChange)
+ #define default_param_timeout_cal_fs -1 //(NoChange)
+
+ #define default_param_data_fifo_size -1 //(Max, hwcfg)
+
+ #ifdef __IS_HOST__
+ #define default_param_host_channels -1 //(Max, hwcfg)
+ #define default_param_rx_fifo_size 240
+ #define default_param_nperio_tx_fifo_size 240
+ #define default_param_perio_tx_fifo_size 32
+ #endif //__IS_HOST__
+ #ifdef __IS_DEVICE__
+ #ifdef __DED_INTR__
+ #define default_param_rx_fifo_size 256
+ #define default_param_nperio_tx_fifo_size 248
+ #define default_param_perio_tx_fifo_size_01 8
+ #else
+ #define default_param_rx_fifo_size 256
+ #define default_param_nperio_tx_fifo_size 256
+ #define default_param_perio_tx_fifo_size_01 0
+ #endif
+ #define default_param_perio_tx_fifo_size_02 0
+ #define default_param_perio_tx_fifo_size_03 0
+ #define default_param_perio_tx_fifo_size_04 0
+ #define default_param_perio_tx_fifo_size_05 0
+ #define default_param_perio_tx_fifo_size_06 0
+ #define default_param_perio_tx_fifo_size_07 0
+ #define default_param_perio_tx_fifo_size_08 0
+ #define default_param_perio_tx_fifo_size_09 0
+ #define default_param_perio_tx_fifo_size_10 0
+ #define default_param_perio_tx_fifo_size_11 0
+ #define default_param_perio_tx_fifo_size_12 0
+ #define default_param_perio_tx_fifo_size_13 0
+ #define default_param_perio_tx_fifo_size_14 0
+ #define default_param_perio_tx_fifo_size_15 0
+ #endif //__IS_DEVICE__
+
+ #elif defined(__IS_VR9__)
+ #define IFXUSB1_IRQ 54
+ #define IFXUSB1_IOMEM_BASE 0x1E101000
+ #define IFXUSB1_FIFOMEM_BASE 0x1E120000
+ #define IFXUSB1_FIFODBG_BASE 0x1E140000
+
+ #define IFXUSB2_IRQ 83
+ #define IFXUSB2_IOMEM_BASE 0x1E106000
+ #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000
+ #define IFXUSB2_FIFODBG_BASE 0x1E1C0000
+ #define IFXUSB_OC_IRQ 68
+
+ #ifndef AMAZON_S_RCU_BASE_ADDR
+ #define AMAZON_S_RCU_BASE_ADDR (0xBF203000)
+ #endif
+
+ #ifndef AMAZON_S_CGU
+ #define AMAZON_S_CGU (0xBF103000)
+ #endif
+ #ifndef AMAZON_S_CGU_IFCCR
+ #define AMAZON_S_CGU_IFCCR ((volatile unsigned long *)(AMAZON_S_CGU+ 0x0018))
+ #endif
+
+ #ifndef AMAZON_S_PMU
+ #define AMAZON_S_PMU (KSEG1+0x1F102000)
+ #endif
+ #ifndef AMAZON_S_PMU_PWDCR
+ #define AMAZON_S_PMU_PWDCR ((volatile unsigned long *)(AMAZON_S_PMU+0x001C))
+ #endif
+
+ #ifndef AMAZON_S_GPIO_P0_OUT
+ #define AMAZON_S_GPIO_P0_OUT (0xBF103000+0x10)
+ #define AMAZON_S_GPIO_P0_DIR (0xBF103000+0x18)
+ #define AMAZON_S_GPIO_P0_ALTSEL0 (0xBF103000+0x1C)
+ #define AMAZON_S_GPIO_P0_ALTSEL1 (0xBF103000+0x20)
+ #define AMAZON_S_GPIO_P0_OD (0xBF103000+0x24)
+ #define AMAZON_S_GPIO_P0_PUDSEL (0xBF103000+0x2C)
+ #define AMAZON_S_GPIO_P0_PUDEN (0xBF103000+0x30)
+ #define AMAZON_S_GPIO_P1_OUT (0xBF103000+0x40)
+ #define AMAZON_S_GPIO_P1_DIR (0xBF103000+0x48)
+ #define AMAZON_S_GPIO_P1_ALTSEL0 (0xBF103000+0x4C)
+ #define AMAZON_S_GPIO_P1_ALTSEL1 (0xBF103000+0x50)
+ #define AMAZON_S_GPIO_P1_OD (0xBF103000+0x54)
+ #define AMAZON_S_GPIO_P1_PUDSEL (0xBF103000+0x5C)
+ #define AMAZON_S_GPIO_P1_PUDEN (0xBF103000+0x60)
+ #endif
+
+ #define AMAZON_S_RCU_USB1CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x18))
+ #define AMAZON_S_RCU_USB2CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x34))
+ #define AMAZON_S_RCU_USBRESET ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x10))
+ #define AMAZON_S_USBCFG_ARB 7 //
+ #define AMAZON_S_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
+ #define AMAZON_S_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
+ #define AMAZON_S_USBCFG_SLV_END_BIT 17 // 0:little_end, 1:big_end
+
+ #define default_param_dma_burst_size 4 //(ALL)
+
+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH
+
+ #define default_param_max_transfer_size -1 //(Max, hwcfg)
+ #define default_param_max_packet_count -1 //(Max, hwcfg)
+ #define default_param_phy_utmi_width 16
+
+ #define default_param_turn_around_time_hs 6 //(NoChange) snpsid >= 0x4f54260a
+ #define default_param_turn_around_time_fs 6 //(NoChange) snpsid >= 0x4f54260a
+ #define default_param_timeout_cal_hs -1 //(NoChange)
+ #define default_param_timeout_cal_fs -1 //(NoChange)
+
+ #define default_param_data_fifo_size -1 //(Max, hwcfg)
+
+ #ifdef __IS_HOST__
+ #define default_param_host_channels -1 //(Max, hwcfg)
+ #define default_param_rx_fifo_size 240
+ #define default_param_nperio_tx_fifo_size 240
+ #define default_param_perio_tx_fifo_size 32
+ #endif //__IS_HOST__
+ #ifdef __IS_DEVICE__
+ #define default_param_rx_fifo_size 256
+ #define default_param_tx_fifo_size_00 -1
+ #define default_param_tx_fifo_size_01 -1
+ #define default_param_tx_fifo_size_02 -1
+ #define default_param_tx_fifo_size_03 -1
+ #define default_param_tx_fifo_size_04 -1
+ #define default_param_tx_fifo_size_05 -1
+ #define default_param_tx_fifo_size_06 -1
+ #define default_param_tx_fifo_size_07 -1
+ #define default_param_tx_fifo_size_08 -1
+ #define default_param_tx_fifo_size_09 -1
+ #define default_param_tx_fifo_size_10 -1
+ #define default_param_tx_fifo_size_11 -1
+ #define default_param_tx_fifo_size_12 -1
+ #define default_param_tx_fifo_size_13 -1
+ #define default_param_tx_fifo_size_14 -1
+ #define default_param_tx_fifo_size_15 -1
+ #define default_param_dma_unalgned_tx -1
+ #define default_param_dma_unalgned_rx -1
+ #define default_param_thr_ctl -1
+ #define default_param_tx_thr_length -1
+ #define default_param_rx_thr_length -1
+ #endif //__IS_DEVICE__
+ #else // __IS_VR9__
+ #error "Please choose one platform!!"
+ #endif // __IS_VR9__
+#endif //UEIP
+
+/*@}*//*IFXUSB_PLATEFORM_MEM_ADDR*/
+
+/////////////////////////////////////////////////////////////////////////
+
+#ifdef __IS_HOST__
+ #if defined(CONFIG_USB_HOST_IFX_FORCE_USB11) || defined(__FORCE_USB11__)
+ #undef default_param_speed
+ #define default_param_speed IFXUSB_PARAM_SPEED_FULL
+ #endif
+#endif
+#ifdef __IS_DEVICE__
+ #if !defined(CONFIG_USB_GADGET_DUALSPEED) || defined(__FORCE_USB11__)
+ #undef default_param_speed
+ #define default_param_speed IFXUSB_PARAM_SPEED_FULL
+ #endif
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+
+static __inline__ void UDELAY( const uint32_t _usecs )
+{
+ udelay( _usecs );
+}
+
+static __inline__ void MDELAY( const uint32_t _msecs )
+{
+ mdelay( _msecs );
+}
+
+static __inline__ void SPIN_LOCK( spinlock_t *_lock )
+{
+ spin_lock(_lock);
+}
+
+static __inline__ void SPIN_UNLOCK( spinlock_t *_lock )
+{
+ spin_unlock(_lock);
+}
+
+#define SPIN_LOCK_IRQSAVE( _l, _f ) \
+ { \
+ spin_lock_irqsave(_l,_f); \
+ }
+
+#define SPIN_UNLOCK_IRQRESTORE( _l,_f ) \
+ { \
+ spin_unlock_irqrestore(_l,_f); \
+ }
+
+/////////////////////////////////////////////////////////////////////////
+/*!
+ \addtogroup IFXUSB_DBG_ROUTINE
+ */
+/*@{*/
+#ifdef __IS_HOST__
+ extern uint32_t h_dbg_lvl;
+#endif
+
+#ifdef __IS_DEVICE__
+ extern uint32_t d_dbg_lvl;
+#endif
+
+/*! \brief When debug level has the DBG_CIL bit set, display CIL Debug messages. */
+#define DBG_CIL (0x2)
+/*! \brief When debug level has the DBG_CILV bit set, display CIL Verbose debug messages */
+#define DBG_CILV (0x20)
+/*! \brief When debug level has the DBG_PCD bit set, display PCD (Device) debug messages */
+#define DBG_PCD (0x4)
+/*! \brief When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug messages */
+#define DBG_PCDV (0x40)
+/*! \brief When debug level has the DBG_HCD bit set, display Host debug messages */
+#define DBG_HCD (0x8)
+/*! \brief When debug level has the DBG_HCDV bit set, display Verbose Host debug messages */
+#define DBG_HCDV (0x80)
+/*! \brief When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host mode. */
+#define DBG_HCD_URB (0x800)
+/*! \brief When debug level has any bit set, display debug messages */
+#define DBG_ANY (0xFF)
+/*! \brief All debug messages off */
+#define DBG_OFF 0
+
+#define DBG_ENTRY (0x8000)
+
+#define IFXUSB "IFXUSB: "
+
+/*!
+ \fn inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new )
+ \brief Set the Debug Level variable.
+ \param _new 32-bit mask of debug level.
+ \return previous debug level
+ */
+static inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new )
+{
+ #ifdef __IS_HOST__
+ uint32_t old = h_dbg_lvl;
+ h_dbg_lvl = _new;
+ #endif
+
+ #ifdef __IS_DEVICE__
+ uint32_t old = d_dbg_lvl;
+ d_dbg_lvl = _new;
+ #endif
+ return old;
+}
+
+#ifdef __DEBUG__
+ #ifdef __IS_HOST__
+ # define IFX_DEBUGPL(lvl, x...) do{ if ((lvl)&h_dbg_lvl)printk( KERN_DEBUG IFXUSB x ); }while(0)
+ # define CHK_DEBUG_LEVEL(level) ((level) & h_dbg_lvl)
+ #endif
+
+ #ifdef __IS_DEVICE__
+ # define IFX_DEBUGPL(lvl, x...) do{ if ((lvl)&d_dbg_lvl)printk( KERN_DEBUG IFXUSB x ); }while(0)
+ # define CHK_DEBUG_LEVEL(level) ((level) & d_dbg_lvl)
+ #endif
+
+ # define IFX_DEBUGP(x...) IFX_DEBUGPL(DBG_ANY, x )
+#else
+ # define IFX_DEBUGPL(lvl, x...) do{}while(0)
+ # define IFX_DEBUGP(x...)
+ # define CHK_DEBUG_LEVEL(level) (0)
+#endif //__DEBUG__
+
+/* Print an Error message. */
+#define IFX_ERROR(x...) printk( KERN_ERR IFXUSB x )
+/* Print a Warning message. */
+#define IFX_WARN(x...) printk( KERN_WARNING IFXUSB x )
+/* Print a notice (normal but significant message). */
+#define IFX_NOTICE(x...) printk( KERN_NOTICE IFXUSB x )
+/* Basic message printing. */
+#define IFX_PRINT(x...) printk( KERN_INFO IFXUSB x )
+
+/*@}*//*IFXUSB_DBG_ROUTINE*/
+
+
+#endif //__IFXUSB_PLAT_H__
+
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxusb_regs.h b/package/kernel/lantiq/ltq-hcd/src/ifxusb_regs.h
new file mode 100644
index 0000000000..4b43821e9a
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxusb_regs.h
@@ -0,0 +1,1471 @@
+/*****************************************************************************
+ ** FILE NAME : ifxusb_regs.h
+ ** PROJECT : IFX USB sub-system V3
+ ** MODULES : IFX USB sub-system Host and Device driver
+ ** SRC VERSION : 3.2
+ ** DATE : 1/Jan/2011
+ ** AUTHOR : Chen, Howard
+ ** DESCRIPTION : This file contains the data structures for accessing the IFXUSB core
+ ** registers.
+ ** The application interfaces with the USB core by reading from and
+ ** writing to the Control and Status Register (CSR) space through the
+ ** AHB Slave interface. These registers are 32 bits wide, and the
+ ** addresses are 32-bit-block aligned.
+ ** CSRs are classified as follows:
+ ** - Core Global Registers
+ ** - Device Mode Registers
+ ** - Device Global Registers
+ ** - Device Endpoint Specific Registers
+ ** - Host Mode Registers
+ ** - Host Global Registers
+ ** - Host Port CSRs
+ ** - Host Channel Specific Registers
+ **
+ ** Only the Core Global registers can be accessed in both Device and
+ ** Host modes. When the USB core is operating in one mode, either
+ ** Device or Host, the application must not access registers from the
+ ** other mode. When the core switches from one mode to another, the
+ ** registers in the new mode of operation must be reprogrammed as they
+ ** would be after a power-on reset.
+ ** FUNCTIONS :
+ ** COMPILER : gcc
+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7
+ ** COPYRIGHT : Copyright (c) 2010
+ ** LANTIQ DEUTSCHLAND GMBH,
+ ** Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ ** This program is free software; 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.
+ **
+ ** Version Control Section **
+ ** $Author$
+ ** $Date$
+ ** $Revisions$
+ ** $Log$ Revision history
+*****************************************************************************/
+/******************************************************************************
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 10 NOV 2008 Wu Qi Ming Initial Version, to comply with COC
+*******************************************************************************/
+
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+
+/*!
+ \defgroup IFXUSB_CSR_DEFINITION Control and Status Register bit-map definition
+ \ingroup IFXUSB_DRIVER_V3
+ \brief Data structures for accessing the IFXUSB core registers.
+ The application interfaces with the USB core by reading from and
+ writing to the Control and Status Register (CSR) space through the
+ AHB Slave interface. These registers are 32 bits wide, and the
+ addresses are 32-bit-block aligned.
+ CSRs are classified as follows:
+ - Core Global Registers
+ - Device Mode Registers
+ - Device Global Registers
+ - Device Endpoint Specific Registers
+ - Host Mode Registers
+ - Host Global Registers
+ - Host Port CSRs
+ - Host Channel Specific Registers
+
+ Only the Core Global registers can be accessed in both Device andHost modes.
+ When the USB core is operating in one mode, either Device or Host, the
+ application must not access registers from the other mode. When the core
+ switches from one mode to another, the registers in the new mode of operation
+ must be reprogrammed as they would be after a power-on reset.
+ */
+
+/*!
+ \defgroup IFXUSB_CSR_DEVICE_GLOBAL_REG Device Mode Registers
+ \ingroup IFXUSB_CSR_DEFINITION
+ \brief Bit-mapped structure to access Device Mode Global Registers
+ */
+
+/*!
+ \defgroup IFXUSB_CSR_DEVICE_EP_REG Device Mode EP Registers
+ \ingroup IFXUSB_CSR_DEFINITION
+ \brief Bit-mapped structure to access Device Mode EP Registers
+ There will be one set of endpoint registers per logical endpoint
+ implemented.
+ These registers are visible only in Device mode and must not be
+ accessed in Host mode, as the results are unknown.
+ */
+
+/*!
+ \defgroup IFXUSB_CSR_DEVICE_DMA_DESC Device mode scatter dma descriptor strusture
+ \ingroup IFXUSB_CSR_DEFINITION
+ \brief Bit-mapped structure to DMA descriptor
+ */
+
+
+/*!
+ \defgroup IFXUSB_CSR_HOST_GLOBAL_REG Host Mode Registers
+ \ingroup IFXUSB_CSR_DEFINITION
+ \brief Bit-mapped structure to access Host Mode Global Registers
+ */
+
+/*!
+ \defgroup IFXUSB_CSR_HOST_HC_REG Host Mode HC Registers
+ \ingroup IFXUSB_CSR_DEFINITION
+ \brief Bit-mapped structure to access Host Mode Host Channel Registers
+ There will be one set of endpoint registers per host channel
+ implemented.
+ These registers are visible only in Host mode and must not be
+ accessed in Device mode, as the results are unknown.
+ */
+
+/*!
+ \defgroup IFXUSB_CSR_PWR_CLK_GATING_REG Power and Clock Gating Control Register
+ \ingroup IFXUSB_CSR_DEFINITION
+ \brief Bit-mapped structure to Power and Clock Gating Control Register
+ */
+
+/*!
+ \defgroup IFXUSB_CSR_CORE_GLOBAL_REG Core Global Registers
+ \ingroup IFXUSB_CSR_DEFINITION
+ \brief Bit-mapped structure to access Core Global Registers
+ */
+
+/*!
+ \defgroup IFXUSB_CSR_CORE_GLOBAL_REG Core Global Registers
+ \ingroup IFXUSB_CSR_DEFINITION
+ \brief Bit-mapped structure to access Core Global Registers
+ */
+
+
+
+/*!
+ \defgroup IFXUSB_CSR_ACCESS_MACROS Macros to manipulate CSRs
+ \ingroup IFXUSB_CSR_DEFINITION
+ \brief Macros to manipulate CSRs
+ */
+
+
+
+
+
+
+/*!
+ \file ifxusb_regs.h
+ \ingroup IFXUSB_DRIVER_V3
+ \brief This file contains the data structures for accessing the IFXUSB core registers.
+ */
+
+
+#ifndef __IFXUSB_REGS_H__
+#define __IFXUSB_REGS_H__
+
+/****************************************************************************/
+
+#define MAX_PERIO_FIFOS 15 /** Maximum number of Periodic FIFOs */
+#define MAX_TX_FIFOS 15 /** Maximum number of Periodic FIFOs */
+#define MAX_EPS_CHANNELS 16 /** Maximum number of Endpoints/HostChannels */
+
+/****************************************************************************/
+
+//#define __RecordRegRW__
+
+/*!
+ \fn static __inline__ uint32_t ifxusb_rreg( volatile uint32_t *_reg)
+ \brief Reads the content of a register.
+ \param _reg address of register to read.
+ \return contents of the register.
+ \ingroup IFXUSB_CSR_ACCESS_MACROS
+ */
+static __inline__ uint32_t ifxusb_rreg( volatile uint32_t *_reg)
+{
+ #ifdef __RecordRegRW__
+ uint32_t r;
+ r=*(_reg);
+ return (r);
+ #else
+ return (*(_reg));
+ #endif
+};
+
+
+/*!
+ \fn static __inline__ void ifxusb_wreg( volatile uint32_t *_reg, const uint32_t _value)
+ \brief Writes a register with a 32 bit value.
+ \param _reg address of register to write.
+ \param _value value to write to _reg.
+ \ingroup IFXUSB_CSR_ACCESS_MACROS
+ */
+static __inline__ void ifxusb_wreg( volatile uint32_t *_reg, const uint32_t _value)
+{
+ #ifdef __RecordRegRW__
+ printk(KERN_INFO "[W %p<-%08X]\n",_reg,_value);
+ #else
+ *(_reg)=_value;
+ #endif
+};
+
+/*!
+ \fn static __inline__ void ifxusb_mreg( volatile uint32_t *_reg, const uint32_t _clear_mask, const uint32_t _set_mask)
+ \brief Modifies bit values in a register. Using the
+ algorithm: (reg_contents & ~clear_mask) | set_mask.
+ \param _reg address of register to modify.
+ \param _clear_mask bit mask to be cleared.
+ \param _set_mask bit mask to be set.
+ \ingroup IFXUSB_CSR_ACCESS_MACROS
+ */
+static __inline__ void ifxusb_mreg( volatile uint32_t *_reg, const uint32_t _clear_mask, const uint32_t _set_mask)
+{
+ uint32_t v;
+ #ifdef __RecordRegRW__
+ uint32_t r;
+ v= *(_reg);
+ r=v;
+ r&=(~_clear_mask);
+ r|= _set_mask;
+ *(_reg)=r ;
+ printk(KERN_INFO "[M %p->%08X+%08X/%08X<-%08X]\n",_reg,r,_clear_mask,_set_mask,r);
+ #else
+ v= *(_reg);
+ v&=(~_clear_mask);
+ v|= _set_mask;
+ *(_reg)=v ;
+ #endif
+};
+
+/****************************************************************************/
+
+/*!
+ \addtogroup IFXUSB_CSR_CORE_GLOBAL_REG
+ */
+/*@{*/
+
+/*! typedef ifxusb_core_global_regs_t
+ \brief IFXUSB Core registers .
+ The ifxusb_core_global_regs structure defines the size
+ and relative field offsets for the Core Global registers.
+ */
+typedef struct ifxusb_core_global_regs
+{
+ volatile uint32_t gotgctl; /*!< 000h OTG Control and Status Register. */
+ volatile uint32_t gotgint; /*!< 004h OTG Interrupt Register. */
+ volatile uint32_t gahbcfg; /*!< 008h Core AHB Configuration Register. */
+ volatile uint32_t gusbcfg; /*!< 00Ch Core USB Configuration Register. */
+ volatile uint32_t grstctl; /*!< 010h Core Reset Register. */
+ volatile uint32_t gintsts; /*!< 014h Core Interrupt Register. */
+ volatile uint32_t gintmsk; /*!< 018h Core Interrupt Mask Register. */
+ volatile uint32_t grxstsr; /*!< 01Ch Receive Status Queue Read Register (Read Only). */
+ volatile uint32_t grxstsp; /*!< 020h Receive Status Queue Read & POP Register (Read Only). */
+ volatile uint32_t grxfsiz; /*!< 024h Receive FIFO Size Register. */
+ volatile uint32_t gnptxfsiz; /*!< 028h Non Periodic Transmit FIFO Size Register. */
+ volatile uint32_t gnptxsts; /*!< 02Ch Non Periodic Transmit FIFO/Queue Status Register (Read Only). */
+ volatile uint32_t gi2cctl; /*!< 030h I2C Access Register. */
+ volatile uint32_t gpvndctl; /*!< 034h PHY Vendor Control Register. */
+ volatile uint32_t ggpio; /*!< 038h General Purpose Input/Output Register. */
+ volatile uint32_t guid; /*!< 03Ch User ID Register. */
+ volatile uint32_t gsnpsid; /*!< 040h Synopsys ID Register (Read Only). */
+ volatile uint32_t ghwcfg1; /*!< 044h User HW Config1 Register (Read Only). */
+ volatile uint32_t ghwcfg2; /*!< 048h User HW Config2 Register (Read Only). */
+ volatile uint32_t ghwcfg3; /*!< 04Ch User HW Config3 Register (Read Only). */
+ volatile uint32_t ghwcfg4; /*!< 050h User HW Config4 Register (Read Only). */
+ volatile uint32_t reserved[43]; /*!< 054h Reserved 054h-0FFh */
+ volatile uint32_t hptxfsiz; /*!< 100h Host Periodic Transmit FIFO Size Register. */
+ volatile uint32_t dptxfsiz_dieptxf[15];/*!< 104h + (FIFO_Number-1)*04h, 1 <= FIFO Number <= 15.
+ Device Periodic Transmit FIFO#n Register if dedicated
+ fifos are disabled, otherwise Device Transmit FIFO#n
+ Register.
+ */
+} ifxusb_core_global_regs_t;
+
+/*!
+ \brief Bits of the Core OTG Control and Status Register (GOTGCTL).
+ */
+typedef union gotgctl_data
+{
+ uint32_t d32;
+ struct{
+ unsigned reserved21_31 : 11;
+ unsigned currmod : 1 ; /*!< 20 */
+ unsigned bsesvld : 1 ; /*!< 19 */
+ unsigned asesvld : 1 ; /*!< 18 */
+ unsigned reserved17 : 1 ;
+ unsigned conidsts : 1 ; /*!< 16 */
+ unsigned reserved12_15 : 4 ;
+ unsigned devhnpen : 1 ; /*!< 11 */
+ unsigned hstsethnpen : 1 ; /*!< 10 */
+ unsigned hnpreq : 1 ; /*!< 09 */
+ unsigned hstnegscs : 1 ; /*!< 08 */
+ unsigned reserved2_7 : 6 ;
+ unsigned sesreq : 1 ; /*!< 01 */
+ unsigned sesreqscs : 1 ; /*!< 00 */
+ } b;
+} gotgctl_data_t;
+
+/*!
+ \brief Bit fields of the Core OTG Interrupt Register (GOTGINT).
+ */
+typedef union gotgint_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved31_20 : 12;
+ unsigned debdone : 1 ; /*!< 19 Debounce Done */
+ unsigned adevtoutchng : 1 ; /*!< 18 A-Device Timeout Change */
+ unsigned hstnegdet : 1 ; /*!< 17 Host Negotiation Detected */
+ unsigned reserver10_16 : 7 ;
+ unsigned hstnegsucstschng : 1 ; /*!< 09 Host Negotiation Success Status Change */
+ unsigned sesreqsucstschng : 1 ; /*!< 08 Session Request Success Status Change */
+ unsigned reserved3_7 : 5 ;
+ unsigned sesenddet : 1 ; /*!< 02 Session End Detected */
+ unsigned reserved0_1 : 2 ;
+ } b;
+} gotgint_data_t;
+
+/*!
+ \brief Bit fields of the Core AHB Configuration Register (GAHBCFG).
+ */
+typedef union gahbcfg_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved9_31 : 23;
+ unsigned ptxfemplvl : 1 ; /*!< 08 Periodic FIFO empty level trigger condition*/
+ unsigned nptxfemplvl : 1 ; /*!< 07 Non-Periodic FIFO empty level trigger condition*/
+ #define IFXUSB_GAHBCFG_TXFEMPTYLVL_EMPTY 1
+ #define IFXUSB_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
+ unsigned reserved : 1 ;
+ unsigned dmaenable : 1 ; /*!< 05 DMA enable*/
+ #define IFXUSB_GAHBCFG_DMAENABLE 1
+ unsigned hburstlen : 4 ; /*!< 01-04 DMA Burst-length*/
+ #define IFXUSB_GAHBCFG_INT_DMA_BURST_SINGLE 0
+ #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR 1
+ #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR4 3
+ #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR8 5
+ #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR16 7
+ unsigned glblintrmsk : 1 ; /*!< 00 USB Global Interrupt Enable */
+ #define IFXUSB_GAHBCFG_GLBINT_ENABLE 1
+ } b;
+} gahbcfg_data_t;
+
+/*!
+ \brief Bit fields of the Core USB Configuration Register (GUSBCFG).
+*/
+typedef union gusbcfg_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved31 : 1;
+ unsigned ForceDevMode : 1; /*!< 30 Force Device Mode */
+ unsigned ForceHstMode : 1; /*!< 29 Force Host Mode */
+ unsigned TxEndDelay : 1; /*!< 28 Tx End Delay */
+ unsigned reserved2723 : 5;
+ unsigned term_sel_dl_pulse : 1; /*!< 22 TermSel DLine Pulsing Selection */
+ unsigned reserved2117 : 5;
+ unsigned otgutmifssel : 1; /*!< 16 UTMIFS Select */
+ unsigned phylpwrclksel : 1; /*!< 15 PHY Low-Power Clock Select */
+ unsigned reserved14 : 1;
+ unsigned usbtrdtim : 4; /*!< 13-10 USB Turnaround Time */
+ unsigned hnpcap : 1; /*!< 09 HNP-Capable */
+ unsigned srpcap : 1; /*!< 08 SRP-Capable */
+ unsigned reserved07 : 1;
+ unsigned physel : 1; /*!< 06 USB 2.0 High-Speed PHY or
+ USB 1.1 Full-Speed Serial
+ Transceiver Select */
+ unsigned fsintf : 1; /*!< 05 Full-Speed Serial Interface Select */
+ unsigned ulpi_utmi_sel : 1; /*!< 04 ULPI or UTMI+ Select */
+ unsigned phyif : 1; /*!< 03 PHY Interface */
+ unsigned toutcal : 3; /*!< 00-02 HS/FS Timeout Calibration */
+ }b;
+} gusbcfg_data_t;
+
+/*!
+ \brief Bit fields of the Core Reset Register (GRSTCTL).
+ */
+typedef union grstctl_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned ahbidle : 1; /*!< 31 AHB Master Idle. Indicates the AHB Master State
+ Machine is in IDLE condition. */
+ unsigned dmareq : 1; /*!< 30 DMA Request Signal. Indicated DMA request is in
+ probress. Used for debug purpose. */
+ unsigned reserved11_29 :19;
+ unsigned txfnum : 5; /*!< 10-06 TxFIFO Number (TxFNum) to be flushed.
+ 0x00: Non Periodic TxFIFO Flush or TxFIFO 0
+ 0x01-0x0F: Periodic TxFIFO Flush or TxFIFO n
+ 0x10: Flush all TxFIFO
+ */
+ unsigned txfflsh : 1; /*!< 05 TxFIFO Flush */
+ unsigned rxfflsh : 1; /*!< 04 RxFIFO Flush */
+ unsigned intknqflsh : 1; /*!< 03 In Token Sequence Learning Queue Flush (Device Only) */
+ unsigned hstfrm : 1; /*!< 02 Host Frame Counter Reset (Host Only) */
+ unsigned hsftrst : 1; /*!< 01 Hclk Soft Reset */
+
+ unsigned csftrst : 1; /*!< 00 Core Soft Reset
+ The application can flush the control logic in the
+ entire core using this bit. This bit resets the
+ pipelines in the AHB Clock domain as well as the
+ PHY Clock domain.
+ The state machines are reset to an IDLE state, the
+ control bits in the CSRs are cleared, all the
+ transmit FIFOs and the receive FIFO are flushed.
+ The status mask bits that control the generation of
+ the interrupt, are cleared, to clear the
+ interrupt. The interrupt status bits are not
+ cleared, so the application can get the status of
+ any events that occurred in the core after it has
+ set this bit.
+ Any transactions on the AHB are terminated as soon
+ as possible following the protocol. Any
+ transactions on the USB are terminated immediately.
+ The configuration settings in the CSRs are
+ unchanged, so the software doesn't have to
+ reprogram these registers (Device
+ Configuration/Host Configuration/Core System
+ Configuration/Core PHY Configuration).
+ The application can write to this bit, any time it
+ wants to reset the core. This is a self clearing
+ bit and the core clears this bit after all the
+ necessary logic is reset in the core, which may
+ take several clocks, depending on the current state
+ of the core.
+ */
+ }b;
+} grstctl_t;
+
+/*!
+ \brief Bit fields of the Core Interrupt Mask Register (GINTMSK) and
+ Core Interrupt Register (GINTSTS).
+ */
+typedef union gint_data
+{
+ uint32_t d32;
+ #define IFXUSB_SOF_INTR_MASK 0x0008
+ struct
+ {
+ unsigned wkupintr : 1; /*!< 31 Resume/Remote Wakeup Detected Interrupt */
+ unsigned sessreqintr : 1; /*!< 30 Session Request/New Session Detected Interrupt */
+ unsigned disconnect : 1; /*!< 29 Disconnect Detected Interrupt */
+ unsigned conidstschng : 1; /*!< 28 Connector ID Status Change */
+ unsigned reserved27 : 1;
+ unsigned ptxfempty : 1; /*!< 26 Periodic TxFIFO Empty */
+ unsigned hcintr : 1; /*!< 25 Host Channels Interrupt */
+ unsigned portintr : 1; /*!< 24 Host Port Interrupt */
+ unsigned reserved23 : 1;
+ unsigned fetsuspmsk : 1; /*!< 22 Data Fetch Suspended */
+ unsigned incomplisoout : 1; /*!< 21 Incomplete IsochronousOUT/Period Transfer */
+ unsigned incomplisoin : 1; /*!< 20 Incomplete Isochronous IN Transfer */
+ unsigned outepintr : 1; /*!< 19 OUT Endpoints Interrupt */
+ unsigned inepintr : 1; /*!< 18 IN Endpoints Interrupt */
+ unsigned epmismatch : 1; /*!< 17 Endpoint Mismatch Interrupt */
+ unsigned reserved16 : 1;
+ unsigned eopframe : 1; /*!< 15 End of Periodic Frame Interrupt */
+ unsigned isooutdrop : 1; /*!< 14 Isochronous OUT Packet Dropped Interrupt */
+ unsigned enumdone : 1; /*!< 13 Enumeration Done */
+ unsigned usbreset : 1; /*!< 12 USB Reset */
+ unsigned usbsuspend : 1; /*!< 11 USB Suspend */
+ unsigned erlysuspend : 1; /*!< 10 Early Suspend */
+ unsigned i2cintr : 1; /*!< 09 I2C Interrupt */
+ unsigned reserved8 : 1;
+ unsigned goutnakeff : 1; /*!< 07 Global OUT NAK Effective */
+ unsigned ginnakeff : 1; /*!< 06 Global Non-periodic IN NAK Effective */
+ unsigned nptxfempty : 1; /*!< 05 Non-periodic TxFIFO Empty */
+ unsigned rxstsqlvl : 1; /*!< 04 Receive FIFO Non-Empty */
+ unsigned sofintr : 1; /*!< 03 Start of (u)Frame */
+ unsigned otgintr : 1; /*!< 02 OTG Interrupt */
+ unsigned modemismatch : 1; /*!< 01 Mode Mismatch Interrupt */
+ unsigned reserved0 : 1;
+ } b;
+} gint_data_t;
+
+/*!
+ \brief Bit fields in the Receive Status Read and Pop Registers (GRXSTSR, GRXSTSP)
+ */
+typedef union grxsts_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved : 7;
+ unsigned fn : 4; /*!< 24-21 Frame Number */
+ unsigned pktsts : 4; /*!< 20-17 Packet Status */
+ #define IFXUSB_DSTS_DATA_UPDT 0x2 // OUT Data Packet
+ #define IFXUSB_DSTS_XFER_COMP 0x3 // OUT Data Transfer Complete
+ #define IFXUSB_DSTS_GOUT_NAK 0x1 // Global OUT NAK
+ #define IFXUSB_DSTS_SETUP_COMP 0x4 // Setup Phase Complete
+ #define IFXUSB_DSTS_SETUP_UPDT 0x6 // SETUP Packet
+ unsigned dpid : 2; /*!< 16-15 Data PID */
+ unsigned bcnt :11; /*!< 14-04 Byte Count */
+ unsigned epnum : 4; /*!< 03-00 Endpoint Number */
+ } db;
+ struct
+ {
+ unsigned reserved :11;
+ unsigned pktsts : 4; /*!< 20-17 Packet Status */
+ #define IFXUSB_HSTS_DATA_UPDT 0x2 // OUT Data Packet
+ #define IFXUSB_HSTS_XFER_COMP 0x3 // OUT Data Transfer Complete
+ #define IFXUSB_HSTS_DATA_TOGGLE_ERR 0x5 // DATA TOGGLE Error
+ #define IFXUSB_HSTS_CH_HALTED 0x7 // Channel Halted
+ unsigned dpid : 2; /*!< 16-15 Data PID */
+ unsigned bcnt :11; /*!< 14-04 Byte Count */
+ unsigned chnum : 4; /*!< 03-00 Channel Number */
+ } hb;
+} grxsts_data_t;
+
+/*!
+ \brief Bit fields in the FIFO Size Registers (HPTXFSIZ, GNPTXFSIZ, DPTXFSIZn).
+ */
+typedef union fifosize_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned depth : 16; /*!< 31-16 TxFIFO Depth (in DWord)*/
+ unsigned startaddr : 16; /*!< 15-00 RAM Starting address */
+ } b;
+} fifosize_data_t;
+
+/*!
+ \brief Bit fields in the Non-Periodic Transmit FIFO/Queue Status Register (GNPTXSTS).
+ */
+
+typedef union gnptxsts_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved : 1;
+ unsigned nptxqtop_chnep : 4; /*!< 30-27 Channel/EP Number of top of the Non-Periodic
+ Transmit Request Queue
+ */
+ unsigned nptxqtop_token : 2; /*!< 26-25 Token Type top of the Non-Periodic
+ Transmit Request Queue
+ 0 - IN/OUT
+ 1 - Zero Length OUT
+ 2 - PING/Complete Split
+ 3 - Channel Halt
+ */
+ unsigned nptxqtop_terminate : 1; /*!< 24 Terminate (Last entry for the selected
+ channel/EP)*/
+ unsigned nptxqspcavail : 8; /*!< 23-16 Transmit Request Queue Space Available */
+ unsigned nptxfspcavail :16; /*!< 15-00 TxFIFO Space Avail (in DWord)*/
+ }b;
+} gnptxsts_data_t;
+
+
+/*!
+ \brief Bit fields in the Transmit FIFO Status Register (DTXFSTS).
+ */
+typedef union dtxfsts_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved : 16;
+ unsigned txfspcavail : 16; /*!< 15-00 TxFIFO Space Avail (in DWord)*/
+ }b;
+} dtxfsts_data_t;
+
+
+/*!
+ \brief Bit fields in the I2C Control Register (I2CCTL).
+ */
+typedef union gi2cctl_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned bsydne : 1; /*!< 31 I2C Busy/Done*/
+ unsigned rw : 1; /*!< 30 Read/Write Indicator */
+ unsigned reserved : 2;
+ unsigned i2cdevaddr : 2; /*!< 27-26 I2C Device Address */
+ unsigned i2csuspctl : 1; /*!< 25 I2C Suspend Control */
+ unsigned ack : 1; /*!< 24 I2C ACK */
+ unsigned i2cen : 1; /*!< 23 I2C Enable */
+ unsigned addr : 7; /*!< 22-16 I2C Address */
+ unsigned regaddr : 8; /*!< 15-08 I2C Register Addr */
+ unsigned rwdata : 8; /*!< I2C Read/Write Data */
+ } b;
+} gi2cctl_data_t;
+
+
+/*!
+ \brief Bit fields in the User HW Config1 Register.
+ */
+typedef union hwcfg1_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned ep_dir15 : 2; /*!< Direction of each EP
+ 0: BIDIR (IN and OUT) endpoint
+ 1: IN endpoint
+ 2: OUT endpoint
+ 3: Reserved
+ */
+ unsigned ep_dir14 : 2;
+ unsigned ep_dir13 : 2;
+ unsigned ep_dir12 : 2;
+ unsigned ep_dir11 : 2;
+ unsigned ep_dir10 : 2;
+ unsigned ep_dir09 : 2;
+ unsigned ep_dir08 : 2;
+ unsigned ep_dir07 : 2;
+ unsigned ep_dir06 : 2;
+ unsigned ep_dir05 : 2;
+ unsigned ep_dir04 : 2;
+ unsigned ep_dir03 : 2;
+ unsigned ep_dir02 : 2;
+ unsigned ep_dir01 : 2;
+ unsigned ep_dir00 : 2;
+ }b;
+} hwcfg1_data_t;
+
+/*!
+ \brief Bit fields in the User HW Config2 Register.
+ */
+typedef union hwcfg2_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved31 : 1;
+ unsigned dev_token_q_depth : 5; /*!< 30-26 Device Mode IN Token Sequence Learning Queue Depth */
+ unsigned host_perio_tx_q_depth : 2; /*!< 25-24 Host Mode Periodic Request Queue Depth */
+ unsigned nonperio_tx_q_depth : 2; /*!< 23-22 Non-periodic Request Queue Depth */
+ unsigned rx_status_q_depth : 2; /*!< 21-20 Multi Processor Interrupt Enabled */
+ unsigned dynamic_fifo : 1; /*!< 19 Dynamic FIFO Sizing Enabled */
+ unsigned perio_ep_supported : 1; /*!< 18 Periodic OUT Channels Supported in Host Mode */
+ unsigned num_host_chan : 4; /*!< 17-14 Number of Host Channels */
+ unsigned num_dev_ep : 4; /*!< 13-10 Number of Device Endpoints */
+ unsigned fs_phy_type : 2; /*!< 09-08 Full-Speed PHY Interface Type */
+ #define IFXUSB_HWCFG2_FS_PHY_TYPE_NOT_SUPPORTED 0
+ #define IFXUSB_HWCFG2_FS_PHY_TYPE_DEDICATE 1
+ #define IFXUSB_HWCFG2_FS_PHY_TYPE_UTMI 2
+ #define IFXUSB_HWCFG2_FS_PHY_TYPE_ULPI 3
+ unsigned hs_phy_type : 2; /*!< 07-06 High-Speed PHY Interface Type */
+ #define IFXUSB_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
+ #define IFXUSB_HWCFG2_HS_PHY_TYPE_UTMI 1
+ #define IFXUSB_HWCFG2_HS_PHY_TYPE_ULPI 2
+ #define IFXUSB_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
+ unsigned point2point : 1; /*!< 05 Point-to-Point */
+ unsigned architecture : 2; /*!< 04-03 Architecture */
+ #define IFXUSB_HWCFG2_ARCH_SLAVE_ONLY 0
+ #define IFXUSB_HWCFG2_ARCH_EXT_DMA 1
+ #define IFXUSB_HWCFG2_ARCH_INT_DMA 2
+ unsigned op_mode : 3; /*!< 02-00 Mode of Operation */
+ #define IFXUSB_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0
+ #define IFXUSB_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1
+ #define IFXUSB_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2
+ #define IFXUSB_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
+ #define IFXUSB_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
+ #define IFXUSB_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
+ #define IFXUSB_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
+ } b;
+} hwcfg2_data_t;
+
+/*!
+ \brief Bit fields in the User HW Config3 Register.
+ */
+typedef union hwcfg3_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned dfifo_depth :16; /*!< 31-16 DFIFO Depth */
+ unsigned reserved15_12 : 4;
+ unsigned synch_reset_type : 1; /*!< 11 Reset Style for Clocked always Blocks in RTL */
+ unsigned optional_features : 1; /*!< 10 Optional Features Removed */
+ unsigned vendor_ctrl_if : 1; /*!< 09 Vendor Control Interface Support */
+ unsigned i2c : 1; /*!< 08 I2C Selection */
+ unsigned otg_func : 1; /*!< 07 OTG Function Enabled */
+ unsigned packet_size_cntr_width : 3; /*!< 06-04 Width of Packet Size Counters */
+ unsigned xfer_size_cntr_width : 4; /*!< 03-00 Width of Transfer Size Counters */
+ } b;
+} hwcfg3_data_t;
+
+/*!
+ \brief Bit fields in the User HW Config4
+ * Register. Read the register into the <i>d32</i> element then read
+ * out the bits using the <i>b</i>it elements.
+ */
+typedef union hwcfg4_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned desc_dma_dyn : 1; /*!< 31 Scatter/Gather DMA */
+ unsigned desc_dma : 1; /*!< 30 Scatter/Gather DMA configuration */
+ unsigned num_in_eps : 4; /*!< 29-26 Number of Device Mode IN Endpoints Including Control Endpoints */
+ unsigned ded_fifo_en : 1; /*!< 25 Enable Dedicated Transmit FIFO for device IN Endpoints */
+ unsigned session_end_filt_en : 1; /*!< 24 session_end Filter Enabled */
+ unsigned b_valid_filt_en : 1; /*!< 23 b_valid Filter Enabled */
+ unsigned a_valid_filt_en : 1; /*!< 22 a_valid Filter Enabled */
+ unsigned vbus_valid_filt_en : 1; /*!< 21 vbus_valid Filter Enabled */
+ unsigned iddig_filt_en : 1; /*!< 20 iddig Filter Enable */
+ unsigned num_dev_mode_ctrl_ep : 4; /*!< 19-16 Number of Device Mode Control Endpoints in Addition to Endpoint 0 */
+ unsigned utmi_phy_data_width : 2; /*!< 15-14 UTMI+ PHY/ULPI-to-Internal UTMI+ Wrapper Data Width */
+ unsigned reserved13_06 : 8;
+ unsigned min_ahb_freq : 1; /*!< 05 Minimum AHB Frequency Less Than 60 MHz */
+ unsigned power_optimiz : 1; /*!< 04 Enable Power Optimization? */
+ unsigned num_dev_perio_in_ep : 4; /*!< 03-00 Number of Device Mode Periodic IN Endpoints */
+ } b;
+} hwcfg4_data_t;
+
+/*@}*//*IFXUSB_CSR_CORE_GLOBAL_REG*/
+
+/****************************************************************************/
+/*!
+ \addtogroup IFXUSB_CSR_DEVICE_GLOBAL_REG
+ */
+/*@{*/
+
+/*! typedef ifxusb_dev_global_regs_t
+ \brief IFXUSB Device Mode Global registers. Offsets 800h-BFFh
+ The ifxusb_dev_global_regs structure defines the size
+ and relative field offsets for the Device Global registers.
+ These registers are visible only in Device mode and must not be
+ accessed in Host mode, as the results are unknown.
+ */
+typedef struct ifxusb_dev_global_regs
+{
+ volatile uint32_t dcfg; /*!< 800h Device Configuration Register. */
+ volatile uint32_t dctl; /*!< 804h Device Control Register. */
+ volatile uint32_t dsts; /*!< 808h Device Status Register (Read Only). */
+ uint32_t unused;
+ volatile uint32_t diepmsk; /*!< 810h Device IN Endpoint Common Interrupt Mask Register. */
+ volatile uint32_t doepmsk; /*!< 814h Device OUT Endpoint Common Interrupt Mask Register. */
+ volatile uint32_t daint; /*!< 818h Device All Endpoints Interrupt Register. */
+ volatile uint32_t daintmsk; /*!< 81Ch Device All Endpoints Interrupt Mask Register. */
+ volatile uint32_t dtknqr1; /*!< 820h Device IN Token Queue Read Register-1 (Read Only). */
+ volatile uint32_t dtknqr2; /*!< 824h Device IN Token Queue Read Register-2 (Read Only). */
+ volatile uint32_t dvbusdis; /*!< 828h Device VBUS discharge Register.*/
+ volatile uint32_t dvbuspulse; /*!< 82Ch Device VBUS Pulse Register. */
+ volatile uint32_t dtknqr3_dthrctl; /*!< 830h Device IN Token Queue Read Register-3 (Read Only).
+ Device Thresholding control register (Read/Write)
+ */
+ volatile uint32_t dtknqr4_fifoemptymsk; /*!< 834h Device IN Token Queue Read Register-4 (Read Only).
+ Device IN EPs empty Inr. Mask Register (Read/Write)
+ */
+} ifxusb_device_global_regs_t;
+
+/*!
+ \brief Bit fields in the Device Configuration Register.
+ */
+
+typedef union dcfg_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved31_26 : 6;
+ unsigned perschintvl : 2; /*!< 25-24 Periodic Scheduling Interval */
+ unsigned descdma : 1; /*!< 23 Enable Descriptor DMA in Device mode */
+ unsigned epmscnt : 5; /*!< 22-18 In Endpoint Mis-match count */
+ unsigned reserved13_17 : 5;
+ unsigned perfrint : 2; /*!< 12-11 Periodic Frame Interval */
+ #define IFXUSB_DCFG_FRAME_INTERVAL_80 0
+ #define IFXUSB_DCFG_FRAME_INTERVAL_85 1
+ #define IFXUSB_DCFG_FRAME_INTERVAL_90 2
+ #define IFXUSB_DCFG_FRAME_INTERVAL_95 3
+ unsigned devaddr : 7; /*!< 10-04 Device Addresses */
+ unsigned reserved3 : 1;
+ unsigned nzstsouthshk : 1; /*!< 02 Non Zero Length Status OUT Handshake */
+ #define IFXUSB_DCFG_SEND_STALL 1
+ unsigned devspd : 2; /*!< 01-00 Device Speed */
+ } b;
+} dcfg_data_t;
+
+/*!
+ \brief Bit fields in the Device Control Register.
+ */
+typedef union dctl_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved16_31 :16;
+ unsigned ifrmnum : 1; /*!< 15 Ignore Frame Number for ISOC EPs */
+ unsigned gmc : 2; /*!< 14-13 Global Multi Count */
+ unsigned gcontbna : 1; /*!< 12 Global Continue on BNA */
+ unsigned pwronprgdone : 1; /*!< 11 Power-On Programming Done */
+ unsigned cgoutnak : 1; /*!< 10 Clear Global OUT NAK */
+ unsigned sgoutnak : 1; /*!< 09 Set Global OUT NAK */
+ unsigned cgnpinnak : 1; /*!< 08 Clear Global Non-Periodic IN NAK */
+ unsigned sgnpinnak : 1; /*!< 07 Set Global Non-Periodic IN NAK */
+ unsigned tstctl : 3; /*!< 06-04 Test Control */
+ unsigned goutnaksts : 1; /*!< 03 Global OUT NAK Status */
+ unsigned gnpinnaksts : 1; /*!< 02 Global Non-Periodic IN NAK Status */
+ unsigned sftdiscon : 1; /*!< 01 Soft Disconnect */
+ unsigned rmtwkupsig : 1; /*!< 00 Remote Wakeup */
+ } b;
+} dctl_data_t;
+
+
+/*!
+ \brief Bit fields in the Device Status Register.
+ */
+typedef union dsts_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved22_31 :10;
+ unsigned soffn :14; /*!< 21-08 Frame or Microframe Number of the received SOF */
+ unsigned reserved4_7 : 4;
+ unsigned errticerr : 1; /*!< 03 Erratic Error */
+ unsigned enumspd : 2; /*!< 02-01 Enumerated Speed */
+ #define IFXUSB_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
+ #define IFXUSB_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
+ #define IFXUSB_DSTS_ENUMSPD_LS_PHY_6MHZ 2
+ #define IFXUSB_DSTS_ENUMSPD_FS_PHY_48MHZ 3
+ unsigned suspsts : 1; /*!< 00 Suspend Status */
+ } b;
+} dsts_data_t;
+
+/*!
+ \brief Bit fields in the Device IN EP Interrupt Register
+ and the Device IN EP Common Mask Register.
+ */
+typedef union diepint_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved14_31 :18;
+ unsigned nakmsk : 1; /*!< 13 NAK interrupt Mask */
+ unsigned reserved10_12 : 3;
+ unsigned bna : 1; /*!< 09 BNA Interrupt mask */
+ unsigned txfifoundrn : 1; /*!< 08 Fifo Underrun Mask */
+ unsigned emptyintr : 1; /*!< 07 IN Endpoint HAK Effective mask */
+ unsigned inepnakeff : 1; /*!< 06 IN Endpoint HAK Effective mask */
+ unsigned intknepmis : 1; /*!< 05 IN Token Received with EP mismatch mask */
+ unsigned intktxfemp : 1; /*!< 04 IN Token received with TxF Empty mask */
+ unsigned timeout : 1; /*!< 03 TimeOUT Handshake mask (non-ISOC EPs) */
+ unsigned ahberr : 1; /*!< 02 AHB Error mask */
+ unsigned epdisabled : 1; /*!< 01 Endpoint disable mask */
+ unsigned xfercompl : 1; /*!< 00 Transfer complete mask */
+ } b;
+} diepint_data_t;
+
+
+/*!
+ \brief Bit fields in the Device OUT EP Interrupt Register and
+ Device OUT EP Common Interrupt Mask Register.
+ */
+typedef union doepint_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved15_31 :17;
+ unsigned nyetmsk : 1; /*!< 14 NYET Interrupt */
+ unsigned nakmsk : 1; /*!< 13 NAK Interrupt */
+ unsigned bbleerrmsk : 1; /*!< 12 Babble Interrupt */
+ unsigned reserved10_11 : 2;
+ unsigned bna : 1; /*!< 09 BNA Interrupt */
+ unsigned outpkterr : 1; /*!< 08 OUT packet Error */
+ unsigned reserved07 : 1;
+ unsigned back2backsetup : 1; /*!< 06 Back-to-Back SETUP Packets Received */
+ unsigned stsphsercvd : 1; /*!< 05 */
+ unsigned outtknepdis : 1; /*!< 04 OUT Token Received when Endpoint Disabled */
+ unsigned setup : 1; /*!< 03 Setup Phase Done (contorl EPs) */
+ unsigned ahberr : 1; /*!< 02 AHB Error */
+ unsigned epdisabled : 1; /*!< 01 Endpoint disable */
+ unsigned xfercompl : 1; /*!< 00 Transfer complete */
+ } b;
+} doepint_data_t;
+
+
+/*!
+ \brief Bit fields in the Device All EP Interrupt Registers.
+ */
+typedef union daint_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned out : 16; /*!< 31-16 OUT Endpoint bits */
+ unsigned in : 16; /*!< 15-00 IN Endpoint bits */
+ } eps;
+ struct
+ {
+ /** OUT Endpoint bits */
+ unsigned outep15 : 1;
+ unsigned outep14 : 1;
+ unsigned outep13 : 1;
+ unsigned outep12 : 1;
+ unsigned outep11 : 1;
+ unsigned outep10 : 1;
+ unsigned outep09 : 1;
+ unsigned outep08 : 1;
+ unsigned outep07 : 1;
+ unsigned outep06 : 1;
+ unsigned outep05 : 1;
+ unsigned outep04 : 1;
+ unsigned outep03 : 1;
+ unsigned outep02 : 1;
+ unsigned outep01 : 1;
+ unsigned outep00 : 1;
+ /** IN Endpoint bits */
+ unsigned inep15 : 1;
+ unsigned inep14 : 1;
+ unsigned inep13 : 1;
+ unsigned inep12 : 1;
+ unsigned inep11 : 1;
+ unsigned inep10 : 1;
+ unsigned inep09 : 1;
+ unsigned inep08 : 1;
+ unsigned inep07 : 1;
+ unsigned inep06 : 1;
+ unsigned inep05 : 1;
+ unsigned inep04 : 1;
+ unsigned inep03 : 1;
+ unsigned inep02 : 1;
+ unsigned inep01 : 1;
+ unsigned inep00 : 1;
+ } ep;
+} daint_data_t;
+
+
+/*!
+ \brief Bit fields in the Device IN Token Queue Read Registers.
+ */
+typedef union dtknq1_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned epnums0_5 :24; /*!< 31-08 EP Numbers of IN Tokens 0 ... 4 */
+ unsigned wrap_bit : 1; /*!< 07 write pointer has wrapped */
+ unsigned reserved05_06 : 2;
+ unsigned intknwptr : 5; /*!< 04-00 In Token Queue Write Pointer */
+ }b;
+} dtknq1_data_t;
+
+
+/*!
+ \brief Bit fields in Threshold control Register
+ */
+typedef union dthrctl_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved26_31 : 6;
+ unsigned rx_thr_len : 9; /*!< 25-17 Rx Thr. Length */
+ unsigned rx_thr_en : 1; /*!< 16 Rx Thr. Enable */
+ unsigned reserved11_15 : 5;
+ unsigned tx_thr_len : 9; /*!< 10-02 Tx Thr. Length */
+ unsigned iso_thr_en : 1; /*!< 01 ISO Tx Thr. Enable */
+ unsigned non_iso_thr_en : 1; /*!< 00 non ISO Tx Thr. Enable */
+ } b;
+} dthrctl_data_t;
+
+/*@}*//*IFXUSB_CSR_DEVICE_GLOBAL_REG*/
+
+/****************************************************************************/
+
+/*!
+ \addtogroup IFXUSB_CSR_DEVICE_EP_REG
+ */
+/*@{*/
+
+/*! typedef ifxusb_dev_in_ep_regs_t
+ \brief Device Logical IN Endpoint-Specific Registers.
+ There will be one set of endpoint registers per logical endpoint
+ implemented.
+ each EP's IN EP Register are offset at :
+ 900h + * (ep_num * 20h)
+ */
+
+typedef struct ifxusb_dev_in_ep_regs
+{
+ volatile uint32_t diepctl; /*!< 00h: Endpoint Control Register */
+ uint32_t reserved04; /*!< 04h: */
+ volatile uint32_t diepint; /*!< 08h: Endpoint Interrupt Register */
+ uint32_t reserved0C; /*!< 0Ch: */
+ volatile uint32_t dieptsiz; /*!< 10h: Endpoint Transfer Size Register.*/
+ volatile uint32_t diepdma; /*!< 14h: Endpoint DMA Address Register. */
+ volatile uint32_t dtxfsts; /*!< 18h: Endpoint Transmit FIFO Status Register. */
+ volatile uint32_t diepdmab; /*!< 1Ch: Endpoint DMA Buffer Register. */
+} ifxusb_dev_in_ep_regs_t;
+
+/*! typedef ifxusb_dev_out_ep_regs_t
+ \brief Device Logical OUT Endpoint-Specific Registers.
+ There will be one set of endpoint registers per logical endpoint
+ implemented.
+ each EP's OUT EP Register are offset at :
+ B00h + * (ep_num * 20h) + 00h
+ */
+typedef struct ifxusb_dev_out_ep_regs
+{
+ volatile uint32_t doepctl; /*!< 00h: Endpoint Control Register */
+ volatile uint32_t doepfn; /*!< 04h: Endpoint Frame number Register */
+ volatile uint32_t doepint; /*!< 08h: Endpoint Interrupt Register */
+ uint32_t reserved0C; /*!< 0Ch: */
+ volatile uint32_t doeptsiz; /*!< 10h: Endpoint Transfer Size Register.*/
+ volatile uint32_t doepdma; /*!< 14h: Endpoint DMA Address Register. */
+ uint32_t reserved18; /*!< 18h: */
+ volatile uint32_t doepdmab; /*!< 1Ch: Endpoint DMA Buffer Register. */
+} ifxusb_dev_out_ep_regs_t;
+
+
+/*!
+ \brief Bit fields in the Device EP Control
+ Register.
+ */
+typedef union depctl_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned epena : 1; /*!< 31 Endpoint Enable */
+ unsigned epdis : 1; /*!< 30 Endpoint Disable */
+ unsigned setd1pid : 1; /*!< 29 Set DATA1 PID (INTR/Bulk IN and OUT endpoints) */
+ unsigned setd0pid : 1; /*!< 28 Set DATA0 PID (INTR/Bulk IN and OUT endpoints) */
+ unsigned snak : 1; /*!< 27 Set NAK */
+ unsigned cnak : 1; /*!< 26 Clear NAK */
+ unsigned txfnum : 4; /*!< 25-22 Tx Fifo Number */
+ unsigned stall : 1; /*!< 21 Stall Handshake */
+ unsigned snp : 1; /*!< 20 Snoop Mode */
+ unsigned eptype : 2; /*!< 19-18 Endpoint Type
+ 0: Control
+ 1: Isochronous
+ 2: Bulk
+ 3: Interrupt
+ */
+ unsigned naksts : 1; /*!< 17 NAK Status */
+ unsigned dpid : 1; /*!< 16 Endpoint DPID (INTR/Bulk IN and OUT endpoints) */
+ unsigned usbactep : 1; /*!< 15 USB Active Endpoint */
+ unsigned nextep : 4; /*!< 14-11 Next Endpoint */
+ unsigned mps :11; /*!< 10-00 Maximum Packet Size */
+ #define IFXUSB_DEP0CTL_MPS_64 0
+ #define IFXUSB_DEP0CTL_MPS_32 1
+ #define IFXUSB_DEP0CTL_MPS_16 2
+ #define IFXUSB_DEP0CTL_MPS_8 3
+ } b;
+} depctl_data_t;
+
+
+/*!
+ \brief Bit fields in the Device EP Transfer Size Register. (EP0 and EPn)
+ */
+typedef union deptsiz_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved31 : 1;
+ unsigned supcnt : 2; /*!< 30-29 Setup Packet Count */
+ #ifdef __DED_FIFO__
+ unsigned reserved21_28 : 8;
+ unsigned pktcnt : 2; /*!< 19-20 Packet Count */
+ #else
+ unsigned reserved20_28 : 9;
+ unsigned pktcnt : 1; /*!< 19 Packet Count */
+ #endif
+ unsigned reserved7_18 :12;
+ unsigned xfersize : 7; /*!< 06-00 Transfer size */
+ }b0;
+ struct
+ {
+ unsigned reserved : 1;
+ unsigned mc : 2; /*!< 30-29 Multi Count */
+ unsigned pktcnt :10; /*!< 28-19 Packet Count */
+ unsigned xfersize :19; /*!< 18-00 Transfer size */
+ } b;
+} deptsiz_data_t;
+
+/*@}*//*IFXUSB_CSR_DEVICE_EP_REG*/
+/****************************************************************************/
+
+/*!
+ \addtogroup IFXUSB_CSR_DEVICE_DMA_DESC
+ */
+/*@{*/
+/*!
+ \brief Bit fields in the DMA Descriptor status quadlet.
+ */
+typedef union desc_sts_data
+{
+ struct
+ {
+ unsigned bs : 2; /*!< 31-30 Buffer Status */
+ #define BS_HOST_READY 0x0
+ #define BS_DMA_BUSY 0x1
+ #define BS_DMA_DONE 0x2
+ #define BS_HOST_BUSY 0x3
+ unsigned sts : 2; /*!< 29-28 Receive/Trasmit Status */
+ #define RTS_SUCCESS 0x0
+ #define RTS_BUFFLUSH 0x1
+ #define RTS_RESERVED 0x2
+ #define RTS_BUFERR 0x3
+ unsigned l : 1; /*!< 27 Last */
+ unsigned sp : 1; /*!< 26 Short Packet */
+ unsigned ioc : 1; /*!< 25 Interrupt On Complete */
+ unsigned sr : 1; /*!< 24 Setup Packet received */
+ unsigned mtrf : 1; /*!< 23 Multiple Transfer */
+ unsigned reserved16_22 : 7;
+ unsigned bytes :16; /*!< 15-00 Transfer size in bytes */
+ } b;
+ uint32_t d32; /*!< DMA Descriptor data buffer pointer */
+} desc_sts_data_t;
+
+/*@}*//*IFXUSB_CSR_DEVICE_DMA_DESC*/
+/****************************************************************************/
+
+/*!
+ \addtogroup IFXUSB_CSR_HOST_GLOBAL_REG
+ */
+/*@{*/
+/*! typedef ifxusb_host_global_regs_t
+ \brief IFXUSB Host Mode Global registers. Offsets 400h-7FFh
+ The ifxusb_host_global_regs structure defines the size
+ and relative field offsets for the Host Global registers.
+ These registers are visible only in Host mode and must not be
+ accessed in Device mode, as the results are unknown.
+ */
+typedef struct ifxusb_host_global_regs
+{
+ volatile uint32_t hcfg; /*!< 400h Host Configuration Register. */
+ volatile uint32_t hfir; /*!< 404h Host Frame Interval Register. */
+ volatile uint32_t hfnum; /*!< 408h Host Frame Number / Frame Remaining Register. */
+ uint32_t reserved40C;
+ volatile uint32_t hptxsts; /*!< 410h Host Periodic Transmit FIFO/ Queue Status Register. */
+ volatile uint32_t haint; /*!< 414h Host All Channels Interrupt Register. */
+ volatile uint32_t haintmsk; /*!< 418h Host All Channels Interrupt Mask Register. */
+} ifxusb_host_global_regs_t;
+
+/*!
+ \brief Bit fields in the Host Configuration Register.
+ */
+typedef union hcfg_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved31_03 :29;
+ unsigned fslssupp : 1; /*!< 02 FS/LS Only Support */
+ unsigned fslspclksel : 2; /*!< 01-00 FS/LS Phy Clock Select */
+ #define IFXUSB_HCFG_30_60_MHZ 0
+ #define IFXUSB_HCFG_48_MHZ 1
+ #define IFXUSB_HCFG_6_MHZ 2
+ } b;
+} hcfg_data_t;
+
+/*!
+ \brief Bit fields in the Host Frame Interval Register.
+ */
+typedef union hfir_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved : 16;
+ unsigned frint : 16; /*!< 15-00 Frame Interval */
+ } b;
+} hfir_data_t;
+
+/*!
+ \brief Bit fields in the Host Frame Time Remaing/Number Register.
+ */
+typedef union hfnum_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned frrem : 16; /*!< 31-16 Frame Time Remaining */
+ unsigned frnum : 16; /*!< 15-00 Frame Number*/
+ #define IFXUSB_HFNUM_MAX_FRNUM 0x3FFF
+ } b;
+} hfnum_data_t;
+
+/*!
+ \brief Bit fields in the Host Periodic Transmit FIFO/Queue Status Register
+ */
+typedef union hptxsts_data
+{
+ /** raw register data */
+ uint32_t d32;
+ struct
+ {
+ /** Top of the Periodic Transmit Request Queue
+ * - bit 24 - Terminate (last entry for the selected channel)
+ */
+ unsigned ptxqtop_odd : 1; /*!< 31 Top of the Periodic Transmit Request
+ Queue Odd/even microframe*/
+ unsigned ptxqtop_chnum : 4; /*!< 30-27 Top of the Periodic Transmit Request
+ Channel Number */
+ unsigned ptxqtop_token : 2; /*!< 26-25 Top of the Periodic Transmit Request
+ Token Type
+ 0 - Zero length
+ 1 - Ping
+ 2 - Disable
+ */
+ unsigned ptxqtop_terminate : 1; /*!< 24 Top of the Periodic Transmit Request
+ Terminate (last entry for the selected channel)*/
+ unsigned ptxqspcavail : 8; /*!< 23-16 Periodic Transmit Request Queue Space Available */
+ unsigned ptxfspcavail :16; /*!< 15-00 Periodic Transmit Data FIFO Space Available */
+ } b;
+} hptxsts_data_t;
+
+/*!
+ \brief Bit fields in the Host Port Control and Status Register.
+ */
+typedef union hprt0_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved19_31 :13;
+ unsigned prtspd : 2; /*!< 18-17 Port Speed */
+ #define IFXUSB_HPRT0_PRTSPD_HIGH_SPEED 0
+ #define IFXUSB_HPRT0_PRTSPD_FULL_SPEED 1
+ #define IFXUSB_HPRT0_PRTSPD_LOW_SPEED 2
+ unsigned prttstctl : 4; /*!< 16-13 Port Test Control */
+ unsigned prtpwr : 1; /*!< 12 Port Power */
+ unsigned prtlnsts : 2; /*!< 11-10 Port Line Status */
+ unsigned reserved9 : 1;
+ unsigned prtrst : 1; /*!< 08 Port Reset */
+ unsigned prtsusp : 1; /*!< 07 Port Suspend */
+ unsigned prtres : 1; /*!< 06 Port Resume */
+ unsigned prtovrcurrchng : 1; /*!< 05 Port Overcurrent Change */
+ unsigned prtovrcurract : 1; /*!< 04 Port Overcurrent Active */
+ unsigned prtenchng : 1; /*!< 03 Port Enable/Disable Change */
+ unsigned prtena : 1; /*!< 02 Port Enable */
+ unsigned prtconndet : 1; /*!< 01 Port Connect Detected */
+ unsigned prtconnsts : 1; /*!< 00 Port Connect Status */
+ }b;
+} hprt0_data_t;
+
+/*!
+ \brief Bit fields in the Host All Interrupt Register.
+ */
+typedef union haint_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved : 16;
+ unsigned ch15 : 1;
+ unsigned ch14 : 1;
+ unsigned ch13 : 1;
+ unsigned ch12 : 1;
+ unsigned ch11 : 1;
+ unsigned ch10 : 1;
+ unsigned ch09 : 1;
+ unsigned ch08 : 1;
+ unsigned ch07 : 1;
+ unsigned ch06 : 1;
+ unsigned ch05 : 1;
+ unsigned ch04 : 1;
+ unsigned ch03 : 1;
+ unsigned ch02 : 1;
+ unsigned ch01 : 1;
+ unsigned ch00 : 1;
+ } b;
+ struct
+ {
+ unsigned reserved : 16;
+ unsigned chint : 16;
+ } b2;
+} haint_data_t;
+/*@}*//*IFXUSB_CSR_HOST_GLOBAL_REG*/
+/****************************************************************************/
+/*!
+ \addtogroup IFXUSB_CSR_HOST_HC_REG
+ */
+/*@{*/
+/*! typedef ifxusb_hc_regs_t
+ \brief Host Channel Specific Registers
+ There will be one set of hc registers per host channelimplemented.
+ each HC's Register are offset at :
+ 500h + * (hc_num * 20h)
+ */
+typedef struct ifxusb_hc_regs
+{
+ volatile uint32_t hcchar; /*!< 00h Host Channel Characteristic Register.*/
+ volatile uint32_t hcsplt; /*!< 04h Host Channel Split Control Register.*/
+ volatile uint32_t hcint; /*!< 08h Host Channel Interrupt Register. */
+ volatile uint32_t hcintmsk; /*!< 0Ch Host Channel Interrupt Mask Register. */
+ volatile uint32_t hctsiz; /*!< 10h Host Channel Transfer Size Register. */
+ volatile uint32_t hcdma; /*!< 14h Host Channel DMA Address Register. */
+ uint32_t reserved[2]; /*!< 18h Reserved. */
+} ifxusb_hc_regs_t;
+
+
+/*!
+ \brief Bit fields in the Host Channel Characteristics Register.
+ */
+typedef union hcchar_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned chen : 1; /*!< 31 Channel enable */
+ unsigned chdis : 1; /*!< 30 Channel disable */
+ unsigned oddfrm : 1; /*!< 29 Frame to transmit periodic transaction */
+ unsigned devaddr : 7; /*!< 28-22 Device address */
+ unsigned multicnt : 2; /*!< 21-20 Packets per frame for periodic transfers */
+ unsigned eptype : 2; /*!< 19-18 0: Control, 1: Isoc, 2: Bulk, 3: Intr */
+ unsigned lspddev : 1; /*!< 17 0: Full/high speed device, 1: Low speed device */
+ unsigned reserved : 1;
+ unsigned epdir : 1; /*!< 15 0: OUT, 1: IN */
+ unsigned epnum : 4; /*!< 14-11 Endpoint number */
+ unsigned mps :11; /*!< 10-00 Maximum packet size in bytes */
+ } b;
+} hcchar_data_t;
+
+/*!
+ \brief Bit fields in the Host Channel Split Control Register
+ */
+typedef union hcsplt_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned spltena : 1; /*!< 31 Split Enble */
+ unsigned reserved :14;
+ unsigned compsplt : 1; /*!< 16 Do Complete Split */
+ unsigned xactpos : 2; /*!< 15-14 Transaction Position */
+ #define IFXUSB_HCSPLIT_XACTPOS_MID 0
+ #define IFXUSB_HCSPLIT_XACTPOS_END 1
+ #define IFXUSB_HCSPLIT_XACTPOS_BEGIN 2
+ #define IFXUSB_HCSPLIT_XACTPOS_ALL 3
+ unsigned hubaddr : 7; /*!< 13-07 Hub Address */
+ unsigned prtaddr : 7; /*!< 06-00 Port Address */
+ } b;
+} hcsplt_data_t;
+
+/*!
+ \brief Bit fields in the Host Interrupt Register.
+ */
+typedef union hcint_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved :21;
+ unsigned datatglerr : 1; /*!< 10 Data Toggle Error */
+ unsigned frmovrun : 1; /*!< 09 Frame Overrun */
+ unsigned bblerr : 1; /*!< 08 Babble Error */
+ unsigned xacterr : 1; /*!< 07 Transaction Err */
+ unsigned nyet : 1; /*!< 06 NYET Response Received */
+ unsigned ack : 1; /*!< 05 ACK Response Received */
+ unsigned nak : 1; /*!< 04 NAK Response Received */
+ unsigned stall : 1; /*!< 03 STALL Response Received */
+ unsigned ahberr : 1; /*!< 02 AHB Error */
+ unsigned chhltd : 1; /*!< 01 Channel Halted */
+ unsigned xfercomp : 1; /*!< 00 Channel Halted */
+ }b;
+} hcint_data_t;
+
+
+/*!
+ \brief Bit fields in the Host Channel Transfer Size
+ Register.
+ */
+typedef union hctsiz_data
+{
+ uint32_t d32;
+ struct
+ {
+ /** */
+ unsigned dopng : 1; /*!< 31 Do PING protocol when 1 */
+ /**
+ * Packet ID for next data packet
+ * 0: DATA0
+ * 1: DATA2
+ * 2: DATA1
+ * 3: MDATA (non-Control), SETUP (Control)
+ */
+ unsigned pid : 2; /*!< 30-29 Packet ID for next data packet
+ 0: DATA0
+ 1: DATA2
+ 2: DATA1
+ 3: MDATA (non-Control), SETUP (Control)
+ */
+ #define IFXUSB_HCTSIZ_DATA0 0
+ #define IFXUSB_HCTSIZ_DATA1 2
+ #define IFXUSB_HCTSIZ_DATA2 1
+ #define IFXUSB_HCTSIZ_MDATA 3
+ #define IFXUSB_HCTSIZ_SETUP 3
+ unsigned pktcnt :10; /*!< 28-19 Data packets to transfer */
+ unsigned xfersize :19; /*!< 18-00 Total transfer size in bytes */
+ }b;
+} hctsiz_data_t;
+
+/*@}*//*IFXUSB_CSR_HOST_HC_REG*/
+
+/****************************************************************************/
+
+/*!
+ \addtogroup IFXUSB_CSR_PWR_CLK_GATING_REG
+ */
+/*@{*/
+/*!
+ \brief Bit fields in the Power and Clock Gating Control Register
+ */
+typedef union pcgcctl_data
+{
+ uint32_t d32;
+ struct
+ {
+ unsigned reserved : 27;
+ unsigned physuspended : 1; /*!< 04 PHY Suspended */
+ unsigned rstpdwnmodule : 1; /*!< 03 Reset Power Down Modules */
+ unsigned pwrclmp : 1; /*!< 02 Power Clamp */
+ unsigned gatehclk : 1; /*!< 01 Gate Hclk */
+ unsigned stoppclk : 1; /*!< 00 Stop Pclk */
+ } b;
+} pcgcctl_data_t;
+/*@}*//*IFXUSB_CSR_PWR_CLK_GATING_REG*/
+
+/****************************************************************************/
+
+#endif //__IFXUSB_REGS_H__
diff --git a/package/kernel/lantiq/ltq-hcd/src/ifxusb_version.h b/package/kernel/lantiq/ltq-hcd/src/ifxusb_version.h
new file mode 100644
index 0000000000..11e346e3db
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxusb_version.h
@@ -0,0 +1,5 @@
+
+#ifndef IFXUSB_VERSION
+#define IFXUSB_VERSION "3.2 B110801"
+#endif
+
diff --git a/package/kernel/lantiq/ltq-ifxos/Makefile b/package/kernel/lantiq/ltq-ifxos/Makefile
new file mode 100644
index 0000000000..1364849bc6
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ifxos/Makefile
@@ -0,0 +1,51 @@
+# Copyright (C) 2009-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=lib_ifxos
+PKG_VERSION:=1.5.14
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_RELEASE:=3
+PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
+PKG_MD5SUM:=bc107f9d8ff6bed4c2760a2817bbb029
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-ifxos
+ SECTION:=sys
+ CATEGORY:=Kernel modules
+ SUBMENU:=Libraries
+ TITLE:=Lantiq OS abstraction library
+ URL:=http://www.lantiq.com/
+ DEPENDS:=@TARGET_lantiq
+ FILES:=$(PKG_BUILD_DIR)/src/drv_ifxos.ko
+ AUTOLOAD:=$(call AutoLoad,10,drv_ifxos)
+endef
+
+CONFIGURE_ARGS += \
+ ARCH=$(LINUX_KARCH) \
+ --enable-linux-26 \
+ --enable-kernelbuild="$(LINUX_DIR)" \
+ --enable-kernelincl="$(LINUX_DIR)/include" \
+ --enable-add_drv_cflags="-fno-pic -mno-abicalls -mlong-calls -G 0"
+
+define Build/Configure
+ (cd $(PKG_BUILD_DIR); aclocal && autoconf && automake)
+ $(call Build/Configure/Default)
+endef
+
+ifdef CONFIG_TARGET_lantiq
+ define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/{lib,include/ifxos}
+ $(CP) $(PKG_BUILD_DIR)/src/include/* $(1)/usr/include/ifxos
+ mkdir -p $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/src/libifxos.a $(1)/usr/lib/libifxos.a
+ endef
+endif
+
+$(eval $(call KernelPackage,ltq-ifxos))
diff --git a/package/kernel/lantiq/ltq-ifxos/patches/100-compat.patch b/package/kernel/lantiq/ltq-ifxos/patches/100-compat.patch
new file mode 100644
index 0000000000..2fd7cd3e6d
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ifxos/patches/100-compat.patch
@@ -0,0 +1,96 @@
+Index: lib_ifxos-1.5.14/configure.in
+===================================================================
+--- lib_ifxos-1.5.14.orig/configure.in 2010-07-22 18:34:07.000000000 +0200
++++ lib_ifxos-1.5.14/configure.in 2013-03-14 08:23:57.481810836 +0100
+@@ -64,7 +64,7 @@
+ AC_ARG_ENABLE(kernelbuild,
+ AS_HELP_STRING(--enable-kernelbuild=x,Set the target kernel build path (only for kernel 2.6.x)),
+ [
+- if test -e $enableval/include/linux/autoconf.h; then
++ if test -e $enableval/include/linux/autoconf.h -o -e $enableval/include/generated/autoconf.h; then
+ AC_SUBST([KERNEL_BUILD_PATH],[$enableval])
+ else
+ AC_MSG_ERROR([The kernel build directory is not valid or not configured!])
+Index: lib_ifxos-1.5.14/src/linux/ifxos_linux_thread_drv.c
+===================================================================
+--- lib_ifxos-1.5.14.orig/src/linux/ifxos_linux_thread_drv.c 2010-01-08 18:10:47.000000000 +0100
++++ lib_ifxos-1.5.14/src/linux/ifxos_linux_thread_drv.c 2013-03-14 08:23:57.481810836 +0100
+@@ -34,8 +34,8 @@
+ #include <linux/sched.h>
+ #include <linux/version.h>
+ #include <linux/completion.h>
+-#include <linux/smp_lock.h>
+ #include <linux/signal.h>
++#include <linux/kthread.h>
+
+
+ #include "ifx_types.h"
+@@ -68,10 +68,6 @@
+ #if ( defined(IFXOS_HAVE_THREAD) && (IFXOS_HAVE_THREAD == 1) )
+
+
+-IFXOS_STATIC IFX_int32_t IFXOS_KernelThreadStartup(
+- IFXOS_ThreadCtrl_t *pThrCntrl);
+-
+-
+ /* ============================================================================
+ IFX Linux adaptation - Kernel Thread handling
+ ========================================================================= */
+@@ -96,9 +92,9 @@
+ - IFX_SUCCESS on success
+ - IFX_ERROR on error
+ */
+-IFXOS_STATIC IFX_int32_t IFXOS_KernelThreadStartup(
+- IFXOS_ThreadCtrl_t *pThrCntrl)
++int IFXOS_KernelThreadStartup(void *data)
+ {
++ IFXOS_ThreadCtrl_t *pThrCntrl = (IFXOS_ThreadCtrl_t*) data;
+ IFX_int32_t retVal = IFX_ERROR;
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+ struct task_struct *kthread = current;
+@@ -139,7 +135,7 @@
+ /* let others run */
+ unlock_kernel();
+ #else
+- daemonize(pThrCntrl->thrParams.pName);
++ //daemonize(pThrCntrl->thrParams.pName);
+
+ /* Enable signals in Kernel >= 2.6 */
+ allow_signal(SIGKILL);
+@@ -218,9 +214,7 @@
+ init_completion(&pThrCntrl->thrCompletion);
+
+ /* start kernel thread via the wrapper function */
+- pThrCntrl->tid = kernel_thread( (IFXOS_KERNEL_THREAD_StartRoutine)IFXOS_KernelThreadStartup,
+- (void *)pThrCntrl,
+- IFXOS_DRV_THREAD_OPTIONS);
++ pThrCntrl->tid = kthread_run(IFXOS_KernelThreadStartup, (void *)pThrCntrl, "ifxos");
+
+ pThrCntrl->bValid = IFX_TRUE;
+
+Index: lib_ifxos-1.5.14/src/include/ifxos_thread.h
+===================================================================
+--- lib_ifxos-1.5.14.orig/src/include/ifxos_thread.h 2010-01-14 10:59:13.000000000 +0100
++++ lib_ifxos-1.5.14/src/include/ifxos_thread.h 2013-03-14 08:24:43.577812806 +0100
+@@ -111,7 +111,7 @@
+ /**
+ Function type of the user thread/task function.
+ */
+-typedef IFX_int32_t (*IFXOS_ThreadFunction_t)(IFXOS_ThreadParams_t *);
++typedef int (*IFXOS_ThreadFunction_t)(void*);
+
+ /** @} */
+
+Index: lib_ifxos-1.5.14/src/include/linux/ifxos_linux_thread.h
+===================================================================
+--- lib_ifxos-1.5.14.orig/src/include/linux/ifxos_linux_thread.h 2010-01-08 18:10:27.000000000 +0100
++++ lib_ifxos-1.5.14/src/include/linux/ifxos_linux_thread.h 2013-03-14 08:25:13.193814073 +0100
+@@ -152,7 +152,7 @@
+ IFXOS_ThreadFunction_t pThrFct;
+
+ /** Kernel thread process ID */
+- IFX_int32_t tid;
++ struct task_struct *tid;
+
+ /** requested kernel thread priority */
+ IFX_int32_t nPriority;
diff --git a/package/kernel/lantiq/ltq-ptm/Makefile b/package/kernel/lantiq/ltq-ptm/Makefile
new file mode 100644
index 0000000000..f0fb25ac38
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/Makefile
@@ -0,0 +1,52 @@
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ltq-ptm
+PKG_RELEASE:=1
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-ptm-$(BUILD_VARIANT)
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-ptm-template
+ SECTION:=sys
+ CATEGORY:=Kernel modules
+ SUBMENU:=Network Devices
+ TITLE:=ptm driver for $(1)
+ URL:=http://www.lantiq.com/
+ VARIANT:=$(1)
+ DEPENDS:=@TARGET_lantiq_$(2)
+ FILES:=$(PKG_BUILD_DIR)/ltq_ptm_$(1).ko
+ AUTOLOAD:=$(call AutoLoad,52,ltq_ptm_$(1))
+endef
+
+KernelPackage/ltq-ptm-danube=$(call KernelPackage/ltq-ptm-template,danube,xway)
+KernelPackage/ltq-ptm-ar9=$(call KernelPackage/ltq-ptm-template,ar9,xway)
+KernelPackage/ltq-ptm-ase=$(call KernelPackage/ltq-ptm-template,ase,ase)
+KernelPackage/ltq-ptm-vr9=$(call KernelPackage/ltq-ptm-template,vr9,xway)
+
+define Build/Prepare
+ $(INSTALL_DIR) $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ cd $(LINUX_DIR); \
+ ARCH=mips CROSS_COMPILE="$(KERNEL_CROSS)" \
+ $(MAKE) BUILD_VARIANT=$(BUILD_VARIANT) M=$(PKG_BUILD_DIR) V=1 modules
+endef
+
+$(eval $(call KernelPackage,ltq-ptm-danube))
+$(eval $(call KernelPackage,ltq-ptm-ase))
+$(eval $(call KernelPackage,ltq-ptm-ar9))
+$(eval $(call KernelPackage,ltq-ptm-vr9))
diff --git a/package/kernel/lantiq/ltq-ptm/src/Makefile b/package/kernel/lantiq/ltq-ptm/src/Makefile
new file mode 100644
index 0000000000..0d0bda5ace
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/Makefile
@@ -0,0 +1,23 @@
+ifeq ($(BUILD_VARIANT),danube)
+ CFLAGS_MODULE+=-DCONFIG_DANUBE
+ obj-m = ltq_ptm_danube.o
+ ltq_ptm_danube-objs = ifxmips_ptm_adsl.o ifxmips_ptm_danube.o
+endif
+
+ifeq ($(BUILD_VARIANT),ase)
+ CFLAGS_MODULE+=-DCONFIG_AMAZON_SE
+ obj-m = ltq_ptm_ase.o
+ ltq_ptm_ase-objs = ifxmips_ptm_adsl.o ifxmips_ptm_amazon_se.o
+endif
+
+ifeq ($(BUILD_VARIANT),ar9)
+ CFLAGS_MODULE+=-DCONFIG_AR9
+ obj-m = ltq_ptm_ar9.o
+ ltq_ptm_ar9-objs = ifxmips_ptm_adsl.o ifxmips_ptm_ar9.o
+endif
+
+ifeq ($(BUILD_VARIANT),vr9)
+ CFLAGS_MODULE+=-DCONFIG_VR9
+ obj-m = ltq_ptm_vr9.o
+ ltq_ptm_vr9-objs = ifxmips_ptm_vdsl.o ifxmips_ptm_vr9.o
+endif
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.c b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.c
new file mode 100644
index 0000000000..391d56cf09
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.c
@@ -0,0 +1,1551 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_adsl.c
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver common source file (core functions for Danube/
+** Amazon-SE/AR9)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+/*
+ * ####################################
+ * Head File
+ * ####################################
+ */
+
+/*
+ * Common Head File
+ */
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/etherdevice.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+/*
+ * Chip Specific Head File
+ */
+#include "ifxmips_ptm_adsl.h"
+
+
+#include <lantiq_soc.h>
+
+/*
+ * ####################################
+ * Kernel Version Adaption
+ * ####################################
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
+ #define MODULE_PARM_ARRAY(a, b) module_param_array(a, int, NULL, 0)
+ #define MODULE_PARM(a, b) module_param(a, int, 0)
+#else
+ #define MODULE_PARM_ARRAY(a, b) MODULE_PARM(a, b)
+#endif
+
+
+
+/*
+ * ####################################
+ * Parameters to Configure PPE
+ * ####################################
+ */
+
+static int write_desc_delay = 0x20; /* Write descriptor delay */
+
+static int rx_max_packet_size = ETH_MAX_FRAME_LENGTH;
+ /* Max packet size for RX */
+
+static int dma_rx_descriptor_length = 24; /* Number of descriptors per DMA RX channel */
+static int dma_tx_descriptor_length = 24; /* Number of descriptors per DMA TX channel */
+
+static int eth_efmtc_crc_cfg = 0x03100710; /* default: tx_eth_crc_check: 1, tx_tc_crc_check: 1, tx_tc_crc_len = 16 */
+ /* rx_eth_crc_present: 1, rx_eth_crc_check: 1, rx_tc_crc_check: 1, rx_tc_crc_len = 16 */
+
+MODULE_PARM(write_desc_delay, "i");
+MODULE_PARM_DESC(write_desc_delay, "PPE core clock cycles between descriptor write and effectiveness in external RAM");
+
+MODULE_PARM(rx_max_packet_size, "i");
+MODULE_PARM_DESC(rx_max_packet_size, "Max packet size in byte for downstream ethernet frames");
+
+MODULE_PARM(dma_rx_descriptor_length, "i");
+MODULE_PARM_DESC(dma_rx_descriptor_length, "Number of descriptor assigned to DMA RX channel (>16)");
+MODULE_PARM(dma_tx_descriptor_length, "i");
+MODULE_PARM_DESC(dma_tx_descriptor_length, "Number of descriptor assigned to DMA TX channel (>16)");
+
+MODULE_PARM(eth_efmtc_crc_cfg, "i");
+MODULE_PARM_DESC(eth_efmtc_crc_cfg, "Configuration for PTM TX/RX ethernet/efm-tc CRC");
+
+
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+
+#define DUMP_SKB_LEN ~0
+
+
+
+/*
+ * ####################################
+ * Declaration
+ * ####################################
+ */
+
+/*
+ * Network Operations
+ */
+static void ptm_setup(struct net_device *, int);
+static struct net_device_stats *ptm_get_stats(struct net_device *);
+static int ptm_open(struct net_device *);
+static int ptm_stop(struct net_device *);
+ static unsigned int ptm_poll(int, unsigned int);
+ static int ptm_napi_poll(struct napi_struct *, int);
+static int ptm_hard_start_xmit(struct sk_buff *, struct net_device *);
+static int ptm_ioctl(struct net_device *, struct ifreq *, int);
+static void ptm_tx_timeout(struct net_device *);
+
+/*
+ * DSL Data LED
+ */
+static INLINE void adsl_led_flash(void);
+
+/*
+ * buffer manage functions
+ */
+static INLINE struct sk_buff* alloc_skb_rx(void);
+//static INLINE struct sk_buff* alloc_skb_tx(unsigned int);
+static INLINE struct sk_buff *get_skb_rx_pointer(unsigned int);
+static INLINE int get_tx_desc(unsigned int, unsigned int *);
+
+/*
+ * Mailbox handler and signal function
+ */
+static INLINE int mailbox_rx_irq_handler(unsigned int);
+static irqreturn_t mailbox_irq_handler(int, void *);
+static INLINE void mailbox_signal(unsigned int, int);
+#ifdef CONFIG_IFX_PTM_RX_TASKLET
+ static void do_ptm_tasklet(unsigned long);
+#endif
+
+/*
+ * Debug Functions
+ */
+#if defined(DEBUG_DUMP_SKB) && DEBUG_DUMP_SKB
+ static void dump_skb(struct sk_buff *, u32, char *, int, int, int);
+#else
+ #define dump_skb(skb, len, title, port, ch, is_tx) do {} while (0)
+#endif
+#if defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
+ static void skb_swap(struct sk_buff *);
+#else
+ #define skb_swap(skb) do {} while (0)
+#endif
+
+/*
+ * Proc File Functions
+ */
+static INLINE void proc_file_create(void);
+static INLINE void proc_file_delete(void);
+static int proc_read_version(char *, char **, off_t, int, int *, void *);
+static int proc_read_wanmib(char *, char **, off_t, int, int *, void *);
+static int proc_write_wanmib(struct file *, const char *, unsigned long, void *);
+#if defined(ENABLE_FW_PROC) && ENABLE_FW_PROC
+ static int proc_read_genconf(char *, char **, off_t, int, int *, void *);
+#endif
+#if defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
+ static int proc_read_dbg(char *, char **, off_t, int, int *, void *);
+ static int proc_write_dbg(struct file *, const char *, unsigned long, void *);
+#endif
+
+/*
+ * Proc Help Functions
+ */
+static INLINE int stricmp(const char *, const char *);
+#if defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
+ static INLINE int strincmp(const char *, const char *, int);
+#endif
+static INLINE int ifx_ptm_version(char *);
+
+/*
+ * Init & clean-up functions
+ */
+static INLINE void check_parameters(void);
+static INLINE int init_priv_data(void);
+static INLINE void clear_priv_data(void);
+static INLINE void init_tables(void);
+
+/*
+ * Exteranl Function
+ */
+#if defined(CONFIG_IFXMIPS_DSL_CPE_MEI) || defined(CONFIG_IFXMIPS_DSL_CPE_MEI_MODULE)
+ extern int ifx_mei_atm_showtime_check(int *is_showtime, struct port_cell_info *port_cell, void **xdata_addr);
+#else
+ static inline int ifx_mei_atm_showtime_check(int *is_showtime, struct port_cell_info *port_cell, void **xdata_addr)
+ {
+ if ( is_showtime != NULL )
+ *is_showtime = 0;
+ return 0;
+ }
+#endif
+
+/*
+ * External variable
+ */
+#if defined(CONFIG_IFXMIPS_DSL_CPE_MEI) || defined(CONFIG_IFXMIPS_DSL_CPE_MEI_MODULE)
+ extern int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *);
+ extern int (*ifx_mei_atm_showtime_exit)(void);
+#else
+ int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *) = NULL;
+ EXPORT_SYMBOL(ifx_mei_atm_showtime_enter);
+ int (*ifx_mei_atm_showtime_exit)(void) = NULL;
+ EXPORT_SYMBOL(ifx_mei_atm_showtime_exit);
+#endif
+
+
+
+/*
+ * ####################################
+ * Local Variable
+ * ####################################
+ */
+
+static struct ptm_priv_data g_ptm_priv_data;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
+static struct net_device_ops g_ptm_netdev_ops = {
+ .ndo_get_stats = ptm_get_stats,
+ .ndo_open = ptm_open,
+ .ndo_stop = ptm_stop,
+ .ndo_start_xmit = ptm_hard_start_xmit,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_do_ioctl = ptm_ioctl,
+ .ndo_tx_timeout = ptm_tx_timeout,
+};
+#endif
+
+static struct net_device *g_net_dev[2] = {0};
+static char *g_net_dev_name[2] = {"ptm0", "ptmfast0"};
+
+#ifdef CONFIG_IFX_PTM_RX_TASKLET
+ static struct tasklet_struct g_ptm_tasklet[] = {
+ {NULL, 0, ATOMIC_INIT(0), do_ptm_tasklet, 0},
+ {NULL, 0, ATOMIC_INIT(0), do_ptm_tasklet, 1},
+ };
+#endif
+
+unsigned int ifx_ptm_dbg_enable = DBG_ENABLE_MASK_ERR;
+
+static struct proc_dir_entry* g_ptm_dir = NULL;
+
+static int g_showtime = 0;
+
+
+
+/*
+ * ####################################
+ * Local Function
+ * ####################################
+ */
+
+static void ptm_setup(struct net_device *dev, int ndev)
+{
+ /* hook network operations */
+ dev->netdev_ops = &g_ptm_netdev_ops;
+ netif_napi_add(dev, &g_ptm_priv_data.itf[ndev].napi, ptm_napi_poll, 25);
+ dev->watchdog_timeo = ETH_WATCHDOG_TIMEOUT;
+
+ dev->dev_addr[0] = 0x00;
+ dev->dev_addr[1] = 0x20;
+ dev->dev_addr[2] = 0xda;
+ dev->dev_addr[3] = 0x86;
+ dev->dev_addr[4] = 0x23;
+ dev->dev_addr[5] = 0x75 + ndev;
+}
+
+static struct net_device_stats *ptm_get_stats(struct net_device *dev)
+{
+ int ndev;
+
+ for ( ndev = 0; ndev < ARRAY_SIZE(g_net_dev) && g_net_dev[ndev] != dev; ndev++ );
+ ASSERT(ndev >= 0 && ndev < ARRAY_SIZE(g_net_dev), "ndev = %d (wrong value)", ndev);
+
+ g_ptm_priv_data.itf[ndev].stats.rx_errors = WAN_MIB_TABLE[ndev].wrx_tccrc_err_pdu + WAN_MIB_TABLE[ndev].wrx_ethcrc_err_pdu;
+ g_ptm_priv_data.itf[ndev].stats.rx_dropped = WAN_MIB_TABLE[ndev].wrx_nodesc_drop_pdu + WAN_MIB_TABLE[ndev].wrx_len_violation_drop_pdu + (WAN_MIB_TABLE[ndev].wrx_correct_pdu - g_ptm_priv_data.itf[ndev].stats.rx_packets);
+
+ return &g_ptm_priv_data.itf[ndev].stats;
+}
+
+static int ptm_open(struct net_device *dev)
+{
+ int ndev;
+
+ for ( ndev = 0; ndev < ARRAY_SIZE(g_net_dev) && g_net_dev[ndev] != dev; ndev++ );
+ ASSERT(ndev >= 0 && ndev < ARRAY_SIZE(g_net_dev), "ndev = %d (wrong value)", ndev);
+
+ napi_enable(&g_ptm_priv_data.itf[ndev].napi);
+
+ IFX_REG_W32_MASK(0, 1 << ndev, MBOX_IGU1_IER);
+
+ netif_start_queue(dev);
+
+ return 0;
+}
+
+static int ptm_stop(struct net_device *dev)
+{
+ int ndev;
+
+ for ( ndev = 0; ndev < ARRAY_SIZE(g_net_dev) && g_net_dev[ndev] != dev; ndev++ );
+ ASSERT(ndev >= 0 && ndev < ARRAY_SIZE(g_net_dev), "ndev = %d (wrong value)", ndev);
+
+ IFX_REG_W32_MASK((1 << ndev) | (1 << (ndev + 16)), 0, MBOX_IGU1_IER);
+
+ napi_disable(&g_ptm_priv_data.itf[ndev].napi);
+
+ netif_stop_queue(dev);
+
+ return 0;
+}
+
+static unsigned int ptm_poll(int ndev, unsigned int work_to_do)
+{
+ unsigned int work_done = 0;
+
+ ASSERT(ndev >= 0 && ndev < ARRAY_SIZE(g_net_dev), "ndev = %d (wrong value)", ndev);
+
+ while ( work_done < work_to_do && WRX_DMA_CHANNEL_CONFIG(ndev)->vlddes > 0 ) {
+ if ( mailbox_rx_irq_handler(ndev) < 0 )
+ break;
+
+ work_done++;
+ }
+
+ return work_done;
+}
+static int ptm_napi_poll(struct napi_struct *napi, int budget)
+{
+ int ndev;
+ unsigned int work_done;
+
+ for ( ndev = 0; ndev < ARRAY_SIZE(g_net_dev) && g_net_dev[ndev] != napi->dev; ndev++ );
+
+ work_done = ptm_poll(ndev, budget);
+
+ // interface down
+ if ( !netif_running(napi->dev) ) {
+ napi_complete(napi);
+ return work_done;
+ }
+
+ // no more traffic
+ if ( WRX_DMA_CHANNEL_CONFIG(ndev)->vlddes == 0 ) {
+ // clear interrupt
+ IFX_REG_W32_MASK(0, 1 << ndev, MBOX_IGU1_ISRC);
+ // double check
+ if ( WRX_DMA_CHANNEL_CONFIG(ndev)->vlddes == 0 ) {
+ napi_complete(napi);
+ IFX_REG_W32_MASK(0, 1 << ndev, MBOX_IGU1_IER);
+ return work_done;
+ }
+ }
+
+ // next round
+ return work_done;
+}
+
+static int ptm_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ int ndev;
+ unsigned int f_full;
+ int desc_base;
+ register struct tx_descriptor reg_desc = {0};
+
+ for ( ndev = 0; ndev < ARRAY_SIZE(g_net_dev) && g_net_dev[ndev] != dev; ndev++ );
+ ASSERT(ndev >= 0 && ndev < ARRAY_SIZE(g_net_dev), "ndev = %d (wrong value)", ndev);
+
+ if ( !g_showtime ) {
+ err("not in showtime");
+ goto PTM_HARD_START_XMIT_FAIL;
+ }
+
+ /* allocate descriptor */
+ desc_base = get_tx_desc(ndev, &f_full);
+ if ( f_full ) {
+ dev->trans_start = jiffies;
+ netif_stop_queue(dev);
+
+ IFX_REG_W32_MASK(0, 1 << (ndev + 16), MBOX_IGU1_ISRC);
+ IFX_REG_W32_MASK(0, 1 << (ndev + 16), MBOX_IGU1_IER);
+ }
+ if ( desc_base < 0 )
+ goto PTM_HARD_START_XMIT_FAIL;
+
+ if ( g_ptm_priv_data.itf[ndev].tx_skb[desc_base] != NULL )
+ dev_kfree_skb_any(g_ptm_priv_data.itf[ndev].tx_skb[desc_base]);
+ g_ptm_priv_data.itf[ndev].tx_skb[desc_base] = skb;
+
+ reg_desc.dataptr = (unsigned int)skb->data >> 2;
+ reg_desc.datalen = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+ reg_desc.byteoff = (unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1);
+ reg_desc.own = 1;
+ reg_desc.c = 1;
+ reg_desc.sop = reg_desc.eop = 1;
+
+ /* write discriptor to memory and write back cache */
+ g_ptm_priv_data.itf[ndev].tx_desc[desc_base] = reg_desc;
+ dma_cache_wback((unsigned long)skb->data, skb->len);
+ wmb();
+
+ dump_skb(skb, DUMP_SKB_LEN, (char *)__func__, ndev, ndev, 1);
+
+ if ( (ifx_ptm_dbg_enable & DBG_ENABLE_MASK_MAC_SWAP) ) {
+ skb_swap(skb);
+ }
+
+ g_ptm_priv_data.itf[ndev].stats.tx_packets++;
+ g_ptm_priv_data.itf[ndev].stats.tx_bytes += reg_desc.datalen;
+
+ dev->trans_start = jiffies;
+ mailbox_signal(ndev, 1);
+
+ adsl_led_flash();
+
+ return NETDEV_TX_OK;
+
+PTM_HARD_START_XMIT_FAIL:
+ dev_kfree_skb_any(skb);
+ g_ptm_priv_data.itf[ndev].stats.tx_dropped++;
+ return NETDEV_TX_OK;
+}
+
+static int ptm_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ int ndev;
+
+ for ( ndev = 0; ndev < ARRAY_SIZE(g_net_dev) && g_net_dev[ndev] != dev; ndev++ );
+ ASSERT(ndev >= 0 && ndev < ARRAY_SIZE(g_net_dev), "ndev = %d (wrong value)", ndev);
+
+ switch ( cmd )
+ {
+ case IFX_PTM_MIB_CW_GET:
+ ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifRxNoIdleCodewords = WAN_MIB_TABLE[ndev].wrx_nonidle_cw;
+ ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifRxIdleCodewords = WAN_MIB_TABLE[ndev].wrx_idle_cw;
+ ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifRxCodingViolation = WAN_MIB_TABLE[ndev].wrx_err_cw;
+ ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifTxNoIdleCodewords = 0;
+ ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifTxIdleCodewords = 0;
+ break;
+ case IFX_PTM_MIB_FRAME_GET:
+ ((PTM_FRAME_MIB_T *)ifr->ifr_data)->RxCorrect = WAN_MIB_TABLE[ndev].wrx_correct_pdu;
+ ((PTM_FRAME_MIB_T *)ifr->ifr_data)->TC_CrcError = WAN_MIB_TABLE[ndev].wrx_tccrc_err_pdu;
+ ((PTM_FRAME_MIB_T *)ifr->ifr_data)->RxDropped = WAN_MIB_TABLE[ndev].wrx_nodesc_drop_pdu + WAN_MIB_TABLE[ndev].wrx_len_violation_drop_pdu;
+ ((PTM_FRAME_MIB_T *)ifr->ifr_data)->TxSend = WAN_MIB_TABLE[ndev].wtx_total_pdu;
+ break;
+ case IFX_PTM_CFG_GET:
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxEthCrcPresent = CFG_ETH_EFMTC_CRC->rx_eth_crc_present;
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxEthCrcCheck = CFG_ETH_EFMTC_CRC->rx_eth_crc_check;
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcCheck = CFG_ETH_EFMTC_CRC->rx_tc_crc_check;
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcLen = CFG_ETH_EFMTC_CRC->rx_tc_crc_len;
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxEthCrcGen = CFG_ETH_EFMTC_CRC->tx_eth_crc_gen;
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcGen = CFG_ETH_EFMTC_CRC->tx_tc_crc_gen;
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcLen = CFG_ETH_EFMTC_CRC->tx_tc_crc_len;
+ break;
+ case IFX_PTM_CFG_SET:
+ CFG_ETH_EFMTC_CRC->rx_eth_crc_present = ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxEthCrcPresent ? 1 : 0;
+ CFG_ETH_EFMTC_CRC->rx_eth_crc_check = ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxEthCrcCheck ? 1 : 0;
+ if ( ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcCheck && (((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcLen == 16 || ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcLen == 32) )
+ {
+ CFG_ETH_EFMTC_CRC->rx_tc_crc_check = 1;
+ CFG_ETH_EFMTC_CRC->rx_tc_crc_len = ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcLen;
+ }
+ else
+ {
+ CFG_ETH_EFMTC_CRC->rx_tc_crc_check = 0;
+ CFG_ETH_EFMTC_CRC->rx_tc_crc_len = 0;
+ }
+ CFG_ETH_EFMTC_CRC->tx_eth_crc_gen = ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxEthCrcGen ? 1 : 0;
+ if ( ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcGen && (((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcLen == 16 || ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcLen == 32) )
+ {
+ CFG_ETH_EFMTC_CRC->tx_tc_crc_gen = 1;
+ CFG_ETH_EFMTC_CRC->tx_tc_crc_len = ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcLen;
+ }
+ else
+ {
+ CFG_ETH_EFMTC_CRC->tx_tc_crc_gen = 0;
+ CFG_ETH_EFMTC_CRC->tx_tc_crc_len = 0;
+ }
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static void ptm_tx_timeout(struct net_device *dev)
+{
+ int ndev;
+
+ for ( ndev = 0; ndev < ARRAY_SIZE(g_net_dev) && g_net_dev[ndev] != dev; ndev++ );
+ ASSERT(ndev >= 0 && ndev < ARRAY_SIZE(g_net_dev), "ndev = %d (wrong value)", ndev);
+
+ /* disable TX irq, release skb when sending new packet */
+ IFX_REG_W32_MASK(1 << (ndev + 16), 0, MBOX_IGU1_IER);
+
+ /* wake up TX queue */
+ netif_wake_queue(dev);
+
+ return;
+}
+
+static INLINE void adsl_led_flash(void)
+{
+}
+
+static INLINE struct sk_buff* alloc_skb_rx(void)
+{
+ struct sk_buff *skb;
+
+ /* allocate memroy including trailer and padding */
+ skb = dev_alloc_skb(rx_max_packet_size + RX_HEAD_MAC_ADDR_ALIGNMENT + DATA_BUFFER_ALIGNMENT);
+ if ( skb != NULL ) {
+ /* must be burst length alignment and reserve two more bytes for MAC address alignment */
+ if ( ((unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1)) != 0 )
+ skb_reserve(skb, ~((unsigned int)skb->data + (DATA_BUFFER_ALIGNMENT - 1)) & (DATA_BUFFER_ALIGNMENT - 1));
+ /* pub skb in reserved area "skb->data - 4" */
+ *((struct sk_buff **)skb->data - 1) = skb;
+ wmb();
+ /* write back and invalidate cache */
+ dma_cache_wback_inv((unsigned long)skb->data - sizeof(skb), sizeof(skb));
+ /* invalidate cache */
+ dma_cache_inv((unsigned long)skb->data, (unsigned int)skb->end - (unsigned int)skb->data);
+ }
+
+ return skb;
+}
+
+#if 0
+static INLINE struct sk_buff* alloc_skb_tx(unsigned int size)
+{
+ struct sk_buff *skb;
+
+ /* allocate memory including padding */
+ size = (size + DATA_BUFFER_ALIGNMENT - 1) & ~(DATA_BUFFER_ALIGNMENT - 1);
+ skb = dev_alloc_skb(size + DATA_BUFFER_ALIGNMENT);
+ /* must be burst length alignment */
+ if ( skb != NULL )
+ skb_reserve(skb, ~((unsigned int)skb->data + (DATA_BUFFER_ALIGNMENT - 1)) & (DATA_BUFFER_ALIGNMENT - 1));
+ return skb;
+}
+#endif
+
+static INLINE struct sk_buff *get_skb_rx_pointer(unsigned int dataptr)
+{
+ unsigned int skb_dataptr;
+ struct sk_buff *skb;
+
+ skb_dataptr = ((dataptr - 1) << 2) | KSEG1;
+ skb = *(struct sk_buff **)skb_dataptr;
+
+ ASSERT((unsigned int)skb >= KSEG0, "invalid skb - skb = %#08x, dataptr = %#08x", (unsigned int)skb, dataptr);
+ ASSERT(((unsigned int)skb->data | KSEG1) == ((dataptr << 2) | KSEG1), "invalid skb - skb = %#08x, skb->data = %#08x, dataptr = %#08x", (unsigned int)skb, (unsigned int)skb->data, dataptr);
+
+ return skb;
+}
+
+static INLINE int get_tx_desc(unsigned int itf, unsigned int *f_full)
+{
+ int desc_base = -1;
+ struct ptm_itf *p_itf = &g_ptm_priv_data.itf[itf];
+
+ // assume TX is serial operation
+ // no protection provided
+
+ *f_full = 1;
+
+ if ( p_itf->tx_desc[p_itf->tx_desc_pos].own == 0 ) {
+ desc_base = p_itf->tx_desc_pos;
+ if ( ++(p_itf->tx_desc_pos) == dma_tx_descriptor_length )
+ p_itf->tx_desc_pos = 0;
+ if ( p_itf->tx_desc[p_itf->tx_desc_pos].own == 0 )
+ *f_full = 0;
+ }
+
+ return desc_base;
+}
+
+static INLINE int mailbox_rx_irq_handler(unsigned int ch) // return: < 0 - descriptor not available, 0 - received one packet
+{
+ unsigned int ndev = ch;
+ struct sk_buff *skb;
+ struct sk_buff *new_skb;
+ volatile struct rx_descriptor *desc;
+ struct rx_descriptor reg_desc;
+ int netif_rx_ret;
+
+ desc = &g_ptm_priv_data.itf[ndev].rx_desc[g_ptm_priv_data.itf[ndev].rx_desc_pos];
+ if ( desc->own || !desc->c ) // if PP32 hold descriptor or descriptor not completed
+ return -EAGAIN;
+ if ( ++g_ptm_priv_data.itf[ndev].rx_desc_pos == dma_rx_descriptor_length )
+ g_ptm_priv_data.itf[ndev].rx_desc_pos = 0;
+
+ reg_desc = *desc;
+ skb = get_skb_rx_pointer(reg_desc.dataptr);
+
+ if ( !reg_desc.err ) {
+ new_skb = alloc_skb_rx();
+ if ( new_skb != NULL ) {
+ skb_reserve(skb, reg_desc.byteoff);
+ skb_put(skb, reg_desc.datalen);
+
+ dump_skb(skb, DUMP_SKB_LEN, (char *)__func__, ndev, ndev, 0);
+
+ // parse protocol header
+ skb->dev = g_net_dev[ndev];
+ skb->protocol = eth_type_trans(skb, skb->dev);
+
+ g_net_dev[ndev]->last_rx = jiffies;
+
+ netif_rx_ret = netif_receive_skb(skb);
+
+ if ( netif_rx_ret != NET_RX_DROP ) {
+ g_ptm_priv_data.itf[ndev].stats.rx_packets++;
+ g_ptm_priv_data.itf[ndev].stats.rx_bytes += reg_desc.datalen;
+ }
+
+ reg_desc.dataptr = ((unsigned int)new_skb->data >> 2) & 0x0FFFFFFF;
+ reg_desc.byteoff = RX_HEAD_MAC_ADDR_ALIGNMENT;
+ }
+ }
+ else
+ reg_desc.err = 0;
+
+ reg_desc.datalen = rx_max_packet_size;
+ reg_desc.own = 1;
+ reg_desc.c = 0;
+
+ // update descriptor
+ *desc = reg_desc;
+ wmb();
+
+ mailbox_signal(ndev, 0);
+
+ adsl_led_flash();
+
+ return 0;
+}
+
+static irqreturn_t mailbox_irq_handler(int irq, void *dev_id)
+{
+ unsigned int isr;
+ int i;
+
+ isr = IFX_REG_R32(MBOX_IGU1_ISR);
+ IFX_REG_W32(isr, MBOX_IGU1_ISRC);
+ isr &= IFX_REG_R32(MBOX_IGU1_IER);
+
+ while ( (i = __fls(isr)) >= 0 ) {
+ isr ^= 1 << i;
+
+ if ( i >= 16 ) {
+ // TX
+ IFX_REG_W32_MASK(1 << i, 0, MBOX_IGU1_IER);
+ i -= 16;
+ if ( i < MAX_ITF_NUMBER )
+ netif_wake_queue(g_net_dev[i]);
+ }
+ else {
+ // RX
+#ifdef CONFIG_IFX_PTM_RX_INTERRUPT
+ while ( WRX_DMA_CHANNEL_CONFIG(i)->vlddes > 0 )
+ mailbox_rx_irq_handler(i);
+#else
+ IFX_REG_W32_MASK(1 << i, 0, MBOX_IGU1_IER);
+ napi_schedule(&g_ptm_priv_data.itf[i].napi);
+#endif
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static INLINE void mailbox_signal(unsigned int itf, int is_tx)
+{
+ int count = 1000;
+
+ if ( is_tx ) {
+ while ( MBOX_IGU3_ISR_ISR(itf + 16) && count > 0 )
+ count--;
+ IFX_REG_W32(MBOX_IGU3_ISRS_SET(itf + 16), MBOX_IGU3_ISRS);
+ }
+ else {
+ while ( MBOX_IGU3_ISR_ISR(itf) && count > 0 )
+ count--;
+ IFX_REG_W32(MBOX_IGU3_ISRS_SET(itf), MBOX_IGU3_ISRS);
+ }
+
+ ASSERT(count != 0, "MBOX_IGU3_ISR = 0x%08x", IFX_REG_R32(MBOX_IGU3_ISR));
+}
+
+#ifdef CONFIG_IFX_PTM_RX_TASKLET
+static void do_ptm_tasklet(unsigned long arg)
+{
+ unsigned int work_to_do = 25;
+ unsigned int work_done = 0;
+
+ ASSERT(arg >= 0 && arg < ARRAY_SIZE(g_net_dev), "arg = %lu (wrong value)", arg);
+
+ while ( work_done < work_to_do && WRX_DMA_CHANNEL_CONFIG(arg)->vlddes > 0 ) {
+ if ( mailbox_rx_irq_handler(arg) < 0 )
+ break;
+
+ work_done++;
+ }
+
+ // interface down
+ if ( !netif_running(g_net_dev[arg]) )
+ return;
+
+ // no more traffic
+ if ( WRX_DMA_CHANNEL_CONFIG(arg)->vlddes == 0 ) {
+ // clear interrupt
+ IFX_REG_W32_MASK(0, 1 << arg, MBOX_IGU1_ISRC);
+ // double check
+ if ( WRX_DMA_CHANNEL_CONFIG(arg)->vlddes == 0 ) {
+ IFX_REG_W32_MASK(0, 1 << arg, MBOX_IGU1_IER);
+ return;
+ }
+ }
+
+ // next round
+ tasklet_schedule(&g_ptm_tasklet[arg]);
+}
+#endif
+
+#if defined(DEBUG_DUMP_SKB) && DEBUG_DUMP_SKB
+static void dump_skb(struct sk_buff *skb, u32 len, char *title, int port, int ch, int is_tx)
+{
+ int i;
+
+ if ( !(ifx_ptm_dbg_enable & (is_tx ? DBG_ENABLE_MASK_DUMP_SKB_TX : DBG_ENABLE_MASK_DUMP_SKB_RX)) )
+ return;
+
+ if ( skb->len < len )
+ len = skb->len;
+
+ if ( len > rx_max_packet_size ) {
+ printk("too big data length: skb = %08x, skb->data = %08x, skb->len = %d\n", (u32)skb, (u32)skb->data, skb->len);
+ return;
+ }
+
+ if ( ch >= 0 )
+ printk("%s (port %d, ch %d)\n", title, port, ch);
+ else
+ printk("%s\n", title);
+ printk(" skb->data = %08X, skb->tail = %08X, skb->len = %d\n", (u32)skb->data, (u32)skb->tail, (int)skb->len);
+ for ( i = 1; i <= len; i++ ) {
+ if ( i % 16 == 1 )
+ printk(" %4d:", i - 1);
+ printk(" %02X", (int)(*((char*)skb->data + i - 1) & 0xFF));
+ if ( i % 16 == 0 )
+ printk("\n");
+ }
+ if ( (i - 1) % 16 != 0 )
+ printk("\n");
+}
+#endif
+
+#if defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
+static void skb_swap(struct sk_buff *skb)
+{
+ unsigned char tmp[8];
+ unsigned char *p = skb->data;
+
+ if ( !(p[0] & 0x01) ) { // bypass broadcast/multicast
+ // swap MAC
+ memcpy(tmp, p, 6);
+ memcpy(p, p + 6, 6);
+ memcpy(p + 6, tmp, 6);
+ p += 12;
+
+ // bypass VLAN
+ while ( p[0] == 0x81 && p[1] == 0x00 )
+ p += 4;
+
+ // IP
+ if ( p[0] == 0x08 && p[1] == 0x00 ) {
+ p += 14;
+ memcpy(tmp, p, 4);
+ memcpy(p, p + 4, 4);
+ memcpy(p + 4, tmp, 4);
+ p += 8;
+ }
+
+ dma_cache_wback((unsigned long)skb->data, (unsigned long)p - (unsigned long)skb->data);
+ }
+}
+#endif
+
+static INLINE void proc_file_create(void)
+{
+ struct proc_dir_entry *res;
+
+ g_ptm_dir = proc_mkdir("driver/ifx_ptm", NULL);
+
+ create_proc_read_entry("version",
+ 0,
+ g_ptm_dir,
+ proc_read_version,
+ NULL);
+
+ res = create_proc_entry("wanmib",
+ 0,
+ g_ptm_dir);
+ if ( res != NULL ) {
+ res->read_proc = proc_read_wanmib;
+ res->write_proc = proc_write_wanmib;
+ }
+
+#if defined(ENABLE_FW_PROC) && ENABLE_FW_PROC
+ create_proc_read_entry("genconf",
+ 0,
+ g_ptm_dir,
+ proc_read_genconf,
+ NULL);
+
+ #ifdef CONFIG_AR9
+ create_proc_read_entry("regs",
+ 0,
+ g_ptm_dir,
+ ifx_ptm_proc_read_regs,
+ NULL);
+ #endif
+#endif
+
+#if defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
+ res = create_proc_entry("dbg",
+ 0,
+ g_ptm_dir);
+ if ( res != NULL ) {
+ res->read_proc = proc_read_dbg;
+ res->write_proc = proc_write_dbg;
+ }
+#endif
+}
+
+static INLINE void proc_file_delete(void)
+{
+#if defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
+ remove_proc_entry("dbg", g_ptm_dir);
+#endif
+
+#if defined(ENABLE_FW_PROC) && ENABLE_FW_PROC
+ #ifdef CONFIG_AR9
+ remove_proc_entry("regs", g_ptm_dir);
+ #endif
+
+ remove_proc_entry("genconf", g_ptm_dir);
+#endif
+
+ remove_proc_entry("wanmib", g_ptm_dir);
+
+ remove_proc_entry("version", g_ptm_dir);
+
+ remove_proc_entry("driver/ifx_ptm", NULL);
+}
+
+static int proc_read_version(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+{
+ int len = 0;
+
+ len += ifx_ptm_version(buf + len);
+
+ if ( offset >= len ) {
+ *start = buf;
+ *eof = 1;
+ return 0;
+ }
+ *start = buf + offset;
+ if ( (len -= offset) > count )
+ return count;
+ *eof = 1;
+ return len;
+}
+
+static int proc_read_wanmib(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len = 0;
+ int i;
+ char *title[] = {
+ "ptm0\n",
+ "ptmfast0\n"
+ };
+
+ for ( i = 0; i < ARRAY_SIZE(title); i++ ) {
+ len += sprintf(page + off + len, title[i]);
+ len += sprintf(page + off + len, " wrx_correct_pdu = %d\n", WAN_MIB_TABLE[i].wrx_correct_pdu);
+ len += sprintf(page + off + len, " wrx_correct_pdu_bytes = %d\n", WAN_MIB_TABLE[i].wrx_correct_pdu_bytes);
+ len += sprintf(page + off + len, " wrx_tccrc_err_pdu = %d\n", WAN_MIB_TABLE[i].wrx_tccrc_err_pdu);
+ len += sprintf(page + off + len, " wrx_tccrc_err_pdu_bytes = %d\n", WAN_MIB_TABLE[i].wrx_tccrc_err_pdu_bytes);
+ len += sprintf(page + off + len, " wrx_ethcrc_err_pdu = %d\n", WAN_MIB_TABLE[i].wrx_ethcrc_err_pdu);
+ len += sprintf(page + off + len, " wrx_ethcrc_err_pdu_bytes = %d\n", WAN_MIB_TABLE[i].wrx_ethcrc_err_pdu_bytes);
+ len += sprintf(page + off + len, " wrx_nodesc_drop_pdu = %d\n", WAN_MIB_TABLE[i].wrx_nodesc_drop_pdu);
+ len += sprintf(page + off + len, " wrx_len_violation_drop_pdu = %d\n", WAN_MIB_TABLE[i].wrx_len_violation_drop_pdu);
+ len += sprintf(page + off + len, " wrx_idle_bytes = %d\n", WAN_MIB_TABLE[i].wrx_idle_bytes);
+ len += sprintf(page + off + len, " wrx_nonidle_cw = %d\n", WAN_MIB_TABLE[i].wrx_nonidle_cw);
+ len += sprintf(page + off + len, " wrx_idle_cw = %d\n", WAN_MIB_TABLE[i].wrx_idle_cw);
+ len += sprintf(page + off + len, " wrx_err_cw = %d\n", WAN_MIB_TABLE[i].wrx_err_cw);
+ len += sprintf(page + off + len, " wtx_total_pdu = %d\n", WAN_MIB_TABLE[i].wtx_total_pdu);
+ len += sprintf(page + off + len, " wtx_total_bytes = %d\n", WAN_MIB_TABLE[i].wtx_total_bytes);
+ }
+
+ *eof = 1;
+
+ return len;
+}
+
+static int proc_write_wanmib(struct file *file, const char *buf, unsigned long count, void *data)
+{
+ char str[2048];
+ char *p;
+ int len, rlen;
+
+ int i;
+
+ len = count < sizeof(str) ? count : sizeof(str) - 1;
+ rlen = len - copy_from_user(str, buf, len);
+ while ( rlen && str[rlen - 1] <= ' ' )
+ rlen--;
+ str[rlen] = 0;
+ for ( p = str; *p && *p <= ' '; p++, rlen-- );
+ if ( !*p )
+ return count;
+
+ if ( stricmp(p, "clear") == 0 || stricmp(p, "clean") == 0 ) {
+ for ( i = 0; i < 2; i++ )
+ memset((void*)&WAN_MIB_TABLE[i], 0, sizeof(WAN_MIB_TABLE[i]));
+ }
+
+ return count;
+}
+
+#if defined(ENABLE_FW_PROC) && ENABLE_FW_PROC
+
+static int proc_read_genconf(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len = 0;
+ int len_max = off + count;
+ char *pstr;
+ char str[2048];
+ int llen = 0;
+ int i;
+ unsigned long bit;
+
+ pstr = *start = page;
+
+ __sync();
+
+ llen += sprintf(str + llen, "CFG_WAN_WRDES_DELAY (0x%08X): %d\n", (unsigned int)CFG_WAN_WRDES_DELAY, IFX_REG_R32(CFG_WAN_WRDES_DELAY));
+ llen += sprintf(str + llen, "CFG_WRX_DMACH_ON (0x%08X):", (unsigned int)CFG_WRX_DMACH_ON);
+ for ( i = 0, bit = 1; i < MAX_RX_DMA_CHANNEL_NUMBER; i++, bit <<= 1 )
+ llen += sprintf(str + llen, " %d - %s", i, (IFX_REG_R32(CFG_WRX_DMACH_ON) & bit) ? "on " : "off");
+ llen += sprintf(str + llen, "\n");
+ llen += sprintf(str + llen, "CFG_WTX_DMACH_ON (0x%08X):", (unsigned int)CFG_WTX_DMACH_ON);
+ for ( i = 0, bit = 1; i < MAX_TX_DMA_CHANNEL_NUMBER; i++, bit <<= 1 )
+ llen += sprintf(str + llen, " %d - %s", i, (IFX_REG_R32(CFG_WTX_DMACH_ON) & bit) ? "on " : "off");
+ llen += sprintf(str + llen, "\n");
+ llen += sprintf(str + llen, "CFG_WRX_LOOK_BITTH (0x%08X): %d\n", (unsigned int)CFG_WRX_LOOK_BITTH, IFX_REG_R32(CFG_WRX_LOOK_BITTH));
+ llen += sprintf(str + llen, "CFG_ETH_EFMTC_CRC (0x%08X): rx_tc_crc_len - %2d, rx_tc_crc_check - %s\n", (unsigned int)CFG_ETH_EFMTC_CRC, CFG_ETH_EFMTC_CRC->rx_tc_crc_len, CFG_ETH_EFMTC_CRC->rx_tc_crc_check ? " on" : "off");
+ llen += sprintf(str + llen, " rx_eth_crc_check - %s, rx_eth_crc_present - %s\n", CFG_ETH_EFMTC_CRC->rx_eth_crc_check ? " on" : "off", CFG_ETH_EFMTC_CRC->rx_eth_crc_present ? " on" : "off");
+ llen += sprintf(str + llen, " tx_tc_crc_len - %2d, tx_tc_crc_gen - %s\n", CFG_ETH_EFMTC_CRC->tx_tc_crc_len, CFG_ETH_EFMTC_CRC->tx_tc_crc_gen ? " on" : "off");
+ llen += sprintf(str + llen, " tx_eth_crc_gen - %s\n", CFG_ETH_EFMTC_CRC->tx_eth_crc_gen ? " on" : "off");
+
+ llen += sprintf(str + llen, "RX Port:\n");
+ for ( i = 0; i < MAX_RX_DMA_CHANNEL_NUMBER; i++ )
+ llen += sprintf(str + llen, " %d (0x%08X). mfs - %5d, dmach - %d, local_state - %d, partner_state - %d\n", i, (unsigned int)WRX_PORT_CONFIG(i), WRX_PORT_CONFIG(i)->mfs, WRX_PORT_CONFIG(i)->dmach, WRX_PORT_CONFIG(i)->local_state, WRX_PORT_CONFIG(i)->partner_state);
+ llen += sprintf(str + llen, "RX DMA Channel:\n");
+ for ( i = 0; i < MAX_RX_DMA_CHANNEL_NUMBER; i++ )
+ llen += sprintf(str + llen, " %d (0x%08X). desba - 0x%08X (0x%08X), deslen - %d, vlddes - %d\n", i, (unsigned int)WRX_DMA_CHANNEL_CONFIG(i), WRX_DMA_CHANNEL_CONFIG(i)->desba, ((unsigned int)WRX_DMA_CHANNEL_CONFIG(i)->desba << 2) | KSEG1, WRX_DMA_CHANNEL_CONFIG(i)->deslen, WRX_DMA_CHANNEL_CONFIG(i)->vlddes);
+
+ llen += sprintf(str + llen, "TX Port:\n");
+ for ( i = 0; i < MAX_TX_DMA_CHANNEL_NUMBER; i++ )
+ llen += sprintf(str + llen, " %d (0x%08X). tx_cwth2 - %d, tx_cwth1 - %d\n", i, (unsigned int)WTX_PORT_CONFIG(i), WTX_PORT_CONFIG(i)->tx_cwth2, WTX_PORT_CONFIG(i)->tx_cwth1);
+ llen += sprintf(str + llen, "TX DMA Channel:\n");
+ for ( i = 0; i < MAX_TX_DMA_CHANNEL_NUMBER; i++ )
+ llen += sprintf(str + llen, " %d (0x%08X). desba - 0x%08X (0x%08X), deslen - %d, vlddes - %d\n", i, (unsigned int)WTX_DMA_CHANNEL_CONFIG(i), WTX_DMA_CHANNEL_CONFIG(i)->desba, ((unsigned int)WTX_DMA_CHANNEL_CONFIG(i)->desba << 2) | KSEG1, WTX_DMA_CHANNEL_CONFIG(i)->deslen, WTX_DMA_CHANNEL_CONFIG(i)->vlddes);
+
+ if ( len <= off && len + llen > off )
+ {
+ memcpy(pstr, str + off - len, len + llen - off);
+ pstr += len + llen - off;
+ }
+ else if ( len > off )
+ {
+ memcpy(pstr, str, llen);
+ pstr += llen;
+ }
+ len += llen;
+ if ( len >= len_max )
+ goto PROC_READ_GENCONF_OVERRUN_END;
+
+ *eof = 1;
+
+ return len - off;
+
+PROC_READ_GENCONF_OVERRUN_END:
+ return len - llen - off;
+}
+
+#endif // defined(ENABLE_FW_PROC) && ENABLE_FW_PROC
+
+#if defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
+
+static int proc_read_dbg(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len = 0;
+
+ len += sprintf(page + off + len, "error print - %s\n", (ifx_ptm_dbg_enable & DBG_ENABLE_MASK_ERR) ? "enabled" : "disabled");
+ len += sprintf(page + off + len, "debug print - %s\n", (ifx_ptm_dbg_enable & DBG_ENABLE_MASK_DEBUG_PRINT) ? "enabled" : "disabled");
+ len += sprintf(page + off + len, "assert - %s\n", (ifx_ptm_dbg_enable & DBG_ENABLE_MASK_ASSERT) ? "enabled" : "disabled");
+ len += sprintf(page + off + len, "dump rx skb - %s\n", (ifx_ptm_dbg_enable & DBG_ENABLE_MASK_DUMP_SKB_RX) ? "enabled" : "disabled");
+ len += sprintf(page + off + len, "dump tx skb - %s\n", (ifx_ptm_dbg_enable & DBG_ENABLE_MASK_DUMP_SKB_TX) ? "enabled" : "disabled");
+ len += sprintf(page + off + len, "mac swap - %s\n", (ifx_ptm_dbg_enable & DBG_ENABLE_MASK_MAC_SWAP) ? "enabled" : "disabled");
+
+ *eof = 1;
+
+ return len;
+}
+
+static int proc_write_dbg(struct file *file, const char *buf, unsigned long count, void *data)
+{
+ static const char *dbg_enable_mask_str[] = {
+ " error print",
+ " err",
+ " debug print",
+ " dbg",
+ " assert",
+ " assert",
+ " dump rx skb",
+ " rx",
+ " dump tx skb",
+ " tx",
+ " dump init",
+ " init",
+ " dump qos",
+ " qos",
+ " mac swap",
+ " swap",
+ " all"
+ };
+ static const int dbg_enable_mask_str_len[] = {
+ 12, 4,
+ 12, 4,
+ 7, 7,
+ 12, 3,
+ 12, 3,
+ 10, 5,
+ 9, 4,
+ 9, 5,
+ 4
+ };
+ unsigned int dbg_enable_mask[] = {
+ DBG_ENABLE_MASK_ERR,
+ DBG_ENABLE_MASK_DEBUG_PRINT,
+ DBG_ENABLE_MASK_ASSERT,
+ DBG_ENABLE_MASK_DUMP_SKB_RX,
+ DBG_ENABLE_MASK_DUMP_SKB_TX,
+ DBG_ENABLE_MASK_DUMP_INIT,
+ DBG_ENABLE_MASK_DUMP_QOS,
+ DBG_ENABLE_MASK_MAC_SWAP,
+ DBG_ENABLE_MASK_ALL
+ };
+
+ char str[2048];
+ char *p;
+
+ int len, rlen;
+
+ int f_enable = 0;
+ int i;
+
+ len = count < sizeof(str) ? count : sizeof(str) - 1;
+ rlen = len - copy_from_user(str, buf, len);
+ while ( rlen && str[rlen - 1] <= ' ' )
+ rlen--;
+ str[rlen] = 0;
+ for ( p = str; *p && *p <= ' '; p++, rlen-- );
+ if ( !*p )
+ return 0;
+
+ // debugging feature for enter/leave showtime
+ if ( strincmp(p, "enter", 5) == 0 && ifx_mei_atm_showtime_enter != NULL )
+ ifx_mei_atm_showtime_enter(NULL, NULL);
+ else if ( strincmp(p, "leave", 5) == 0 && ifx_mei_atm_showtime_exit != NULL )
+ ifx_mei_atm_showtime_exit();
+
+ if ( strincmp(p, "enable", 6) == 0 ) {
+ p += 6;
+ f_enable = 1;
+ }
+ else if ( strincmp(p, "disable", 7) == 0 ) {
+ p += 7;
+ f_enable = -1;
+ }
+ else if ( strincmp(p, "help", 4) == 0 || *p == '?' ) {
+ printk("echo <enable/disable> [err/dbg/assert/rx/tx/init/qos/swap/all] > /proc/driver/ifx_ptm/dbg\n");
+ }
+
+ if ( f_enable ) {
+ if ( *p == 0 ) {
+ if ( f_enable > 0 )
+ ifx_ptm_dbg_enable |= DBG_ENABLE_MASK_ALL & ~DBG_ENABLE_MASK_MAC_SWAP;
+ else
+ ifx_ptm_dbg_enable &= ~DBG_ENABLE_MASK_ALL | DBG_ENABLE_MASK_MAC_SWAP;
+ }
+ else {
+ do {
+ for ( i = 0; i < ARRAY_SIZE(dbg_enable_mask_str); i++ )
+ if ( strincmp(p, dbg_enable_mask_str[i], dbg_enable_mask_str_len[i]) == 0 ) {
+ if ( f_enable > 0 )
+ ifx_ptm_dbg_enable |= dbg_enable_mask[i >> 1];
+ else
+ ifx_ptm_dbg_enable &= ~dbg_enable_mask[i >> 1];
+ p += dbg_enable_mask_str_len[i];
+ break;
+ }
+ } while ( i < ARRAY_SIZE(dbg_enable_mask_str) );
+ }
+ }
+
+ return count;
+}
+
+#endif // defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
+
+static INLINE int stricmp(const char *p1, const char *p2)
+{
+ int c1, c2;
+
+ while ( *p1 && *p2 )
+ {
+ c1 = *p1 >= 'A' && *p1 <= 'Z' ? *p1 + 'a' - 'A' : *p1;
+ c2 = *p2 >= 'A' && *p2 <= 'Z' ? *p2 + 'a' - 'A' : *p2;
+ if ( (c1 -= c2) )
+ return c1;
+ p1++;
+ p2++;
+ }
+
+ return *p1 - *p2;
+}
+
+#if defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
+static INLINE int strincmp(const char *p1, const char *p2, int n)
+{
+ int c1 = 0, c2;
+
+ while ( n && *p1 && *p2 )
+ {
+ c1 = *p1 >= 'A' && *p1 <= 'Z' ? *p1 + 'a' - 'A' : *p1;
+ c2 = *p2 >= 'A' && *p2 <= 'Z' ? *p2 + 'a' - 'A' : *p2;
+ if ( (c1 -= c2) )
+ return c1;
+ p1++;
+ p2++;
+ n--;
+ }
+
+ return n ? *p1 - *p2 : c1;
+}
+#endif
+
+static INLINE int ifx_ptm_version(char *buf)
+{
+ int len = 0;
+ unsigned int major, minor;
+
+ ifx_ptm_get_fw_ver(&major, &minor);
+
+ len += sprintf(buf + len, "PTM %d.%d.%d", IFX_PTM_VER_MAJOR, IFX_PTM_VER_MID, IFX_PTM_VER_MINOR);
+ len += sprintf(buf + len, " PTM (E1) firmware version %d.%d\n", major, minor);
+
+ return len;
+}
+
+static INLINE void check_parameters(void)
+{
+ /* There is a delay between PPE write descriptor and descriptor is */
+ /* really stored in memory. Host also has this delay when writing */
+ /* descriptor. So PPE will use this value to determine if the write */
+ /* operation makes effect. */
+ if ( write_desc_delay < 0 )
+ write_desc_delay = 0;
+
+ /* Because of the limitation of length field in descriptors, the packet */
+ /* size could not be larger than 64K minus overhead size. */
+ if ( rx_max_packet_size < ETH_MIN_FRAME_LENGTH )
+ rx_max_packet_size = ETH_MIN_FRAME_LENGTH;
+ else if ( rx_max_packet_size > 65536 - 1 )
+ rx_max_packet_size = 65536 - 1;
+
+ if ( dma_rx_descriptor_length < 2 )
+ dma_rx_descriptor_length = 2;
+ if ( dma_tx_descriptor_length < 2 )
+ dma_tx_descriptor_length = 2;
+}
+
+static INLINE int init_priv_data(void)
+{
+ void *p;
+ int i;
+ struct rx_descriptor rx_desc = {0};
+ struct sk_buff *skb;
+ volatile struct rx_descriptor *p_rx_desc;
+ volatile struct tx_descriptor *p_tx_desc;
+ struct sk_buff **ppskb;
+
+ // clear ptm private data structure
+ memset(&g_ptm_priv_data, 0, sizeof(g_ptm_priv_data));
+
+ // allocate memory for RX descriptors
+ p = kzalloc(MAX_ITF_NUMBER * dma_rx_descriptor_length * sizeof(struct rx_descriptor) + DESC_ALIGNMENT, GFP_KERNEL);
+ if ( p == NULL )
+ return -1;
+ dma_cache_inv((unsigned long)p, MAX_ITF_NUMBER * dma_rx_descriptor_length * sizeof(struct rx_descriptor) + DESC_ALIGNMENT);
+ g_ptm_priv_data.rx_desc_base = p;
+ //p = (void *)((((unsigned int)p + DESC_ALIGNMENT - 1) & ~(DESC_ALIGNMENT - 1)) | KSEG1);
+
+ // allocate memory for TX descriptors
+ p = kzalloc(MAX_ITF_NUMBER * dma_tx_descriptor_length * sizeof(struct tx_descriptor) + DESC_ALIGNMENT, GFP_KERNEL);
+ if ( p == NULL )
+ return -1;
+ dma_cache_inv((unsigned long)p, MAX_ITF_NUMBER * dma_tx_descriptor_length * sizeof(struct tx_descriptor) + DESC_ALIGNMENT);
+ g_ptm_priv_data.tx_desc_base = p;
+
+ // allocate memroy for TX skb pointers
+ p = kzalloc(MAX_ITF_NUMBER * dma_tx_descriptor_length * sizeof(struct sk_buff *) + 4, GFP_KERNEL);
+ if ( p == NULL )
+ return -1;
+ dma_cache_wback_inv((unsigned long)p, MAX_ITF_NUMBER * dma_tx_descriptor_length * sizeof(struct sk_buff *) + 4);
+ g_ptm_priv_data.tx_skb_base = p;
+
+ p_rx_desc = (volatile struct rx_descriptor *)((((unsigned int)g_ptm_priv_data.rx_desc_base + DESC_ALIGNMENT - 1) & ~(DESC_ALIGNMENT - 1)) | KSEG1);
+ p_tx_desc = (volatile struct tx_descriptor *)((((unsigned int)g_ptm_priv_data.tx_desc_base + DESC_ALIGNMENT - 1) & ~(DESC_ALIGNMENT - 1)) | KSEG1);
+ ppskb = (struct sk_buff **)(((unsigned int)g_ptm_priv_data.tx_skb_base + 3) & ~3);
+ for ( i = 0; i < MAX_ITF_NUMBER; i++ ) {
+ g_ptm_priv_data.itf[i].rx_desc = &p_rx_desc[i * dma_rx_descriptor_length];
+ g_ptm_priv_data.itf[i].tx_desc = &p_tx_desc[i * dma_tx_descriptor_length];
+ g_ptm_priv_data.itf[i].tx_skb = &ppskb[i * dma_tx_descriptor_length];
+ }
+
+ rx_desc.own = 1;
+ rx_desc.c = 0;
+ rx_desc.sop = 1;
+ rx_desc.eop = 1;
+ rx_desc.byteoff = RX_HEAD_MAC_ADDR_ALIGNMENT;
+ rx_desc.id = 0;
+ rx_desc.err = 0;
+ rx_desc.datalen = rx_max_packet_size;
+ for ( i = 0; i < MAX_ITF_NUMBER * dma_rx_descriptor_length; i++ ) {
+ skb = alloc_skb_rx();
+ if ( skb == NULL )
+ return -1;
+ rx_desc.dataptr = ((unsigned int)skb->data >> 2) & 0x0FFFFFFF;
+ p_rx_desc[i] = rx_desc;
+ }
+
+ return 0;
+}
+
+static INLINE void clear_priv_data(void)
+{
+ int i, j;
+ struct sk_buff *skb;
+
+ for ( i = 0; i < MAX_ITF_NUMBER; i++ ) {
+ if ( g_ptm_priv_data.itf[i].tx_skb != NULL ) {
+ for ( j = 0; j < dma_tx_descriptor_length; j++ )
+ if ( g_ptm_priv_data.itf[i].tx_skb[j] != NULL )
+ dev_kfree_skb_any(g_ptm_priv_data.itf[i].tx_skb[j]);
+ }
+ if ( g_ptm_priv_data.itf[i].rx_desc != NULL ) {
+ for ( j = 0; j < dma_rx_descriptor_length; j++ ) {
+ if ( g_ptm_priv_data.itf[i].rx_desc[j].sop || g_ptm_priv_data.itf[i].rx_desc[j].eop ) { // descriptor initialized
+ skb = get_skb_rx_pointer(g_ptm_priv_data.itf[i].rx_desc[j].dataptr);
+ dev_kfree_skb_any(skb);
+ }
+ }
+ }
+ }
+
+ if ( g_ptm_priv_data.rx_desc_base != NULL )
+ kfree(g_ptm_priv_data.rx_desc_base);
+
+ if ( g_ptm_priv_data.tx_desc_base != NULL )
+ kfree(g_ptm_priv_data.tx_desc_base);
+
+ if ( g_ptm_priv_data.tx_skb_base != NULL )
+ kfree(g_ptm_priv_data.tx_skb_base);
+}
+
+static INLINE void init_tables(void)
+{
+ int i;
+ volatile unsigned int *p;
+ struct wrx_dma_channel_config rx_config = {0};
+ struct wtx_dma_channel_config tx_config = {0};
+ struct wrx_port_cfg_status rx_port_cfg = { 0 };
+ struct wtx_port_cfg tx_port_cfg = { 0 };
+
+ /*
+ * CDM Block 1
+ */
+ IFX_REG_W32(CDM_CFG_RAM1_SET(0x00) | CDM_CFG_RAM0_SET(0x00), CDM_CFG); // CDM block 1 must be data memory and mapped to 0x5000 (dword addr)
+ p = CDM_DATA_MEMORY(0, 0); // Clear CDM block 1
+ for ( i = 0; i < CDM_DATA_MEMORY_DWLEN; i++, p++ )
+ IFX_REG_W32(0, p);
+
+ /*
+ * General Registers
+ */
+ IFX_REG_W32(write_desc_delay, CFG_WAN_WRDES_DELAY);
+ IFX_REG_W32((1 << MAX_RX_DMA_CHANNEL_NUMBER) - 1, CFG_WRX_DMACH_ON);
+ IFX_REG_W32((1 << MAX_TX_DMA_CHANNEL_NUMBER) - 1, CFG_WTX_DMACH_ON);
+
+ IFX_REG_W32(8, CFG_WRX_LOOK_BITTH); // WAN RX EFM-TC Looking Threshold
+
+ IFX_REG_W32(eth_efmtc_crc_cfg, CFG_ETH_EFMTC_CRC);
+
+ /*
+ * WRX DMA Channel Configuration Table
+ */
+ rx_config.deslen = dma_rx_descriptor_length;
+ rx_port_cfg.mfs = ETH_MAX_FRAME_LENGTH;
+ rx_port_cfg.local_state = 0; // looking for sync
+ rx_port_cfg.partner_state = 0; // parter receiver is out of sync
+
+ for ( i = 0; i < MAX_RX_DMA_CHANNEL_NUMBER; i++ ) {
+ rx_config.desba = ((unsigned int)g_ptm_priv_data.itf[i].rx_desc >> 2) & 0x0FFFFFFF;
+ *WRX_DMA_CHANNEL_CONFIG(i) = rx_config;
+
+ rx_port_cfg.dmach = i;
+ *WRX_PORT_CONFIG(i) = rx_port_cfg;
+ }
+
+ /*
+ * WTX DMA Channel Configuration Table
+ */
+ tx_config.deslen = dma_tx_descriptor_length;
+ tx_port_cfg.tx_cwth1 = 5;
+ tx_port_cfg.tx_cwth2 = 4;
+
+ for ( i = 0; i < MAX_TX_DMA_CHANNEL_NUMBER; i++ ) {
+ tx_config.desba = ((unsigned int)g_ptm_priv_data.itf[i].tx_desc >> 2) & 0x0FFFFFFF;
+ *WTX_DMA_CHANNEL_CONFIG(i) = tx_config;
+
+ *WTX_PORT_CONFIG(i) = tx_port_cfg;
+ }
+}
+
+
+
+/*
+ * ####################################
+ * Global Function
+ * ####################################
+ */
+
+static int ptm_showtime_enter(struct port_cell_info *port_cell, void *xdata_addr)
+{
+
+ g_showtime = 1;
+
+ printk("enter showtime\n");
+
+ return 0;
+}
+
+static int ptm_showtime_exit(void)
+{
+ if ( !g_showtime )
+ return -1;
+
+ g_showtime = 0;
+
+ printk("leave showtime\n");
+
+ return 0;
+}
+
+
+
+/*
+ * ####################################
+ * Init/Cleanup API
+ * ####################################
+ */
+
+/*
+ * Description:
+ * Initialize global variables, PP32, comunication structures, register IRQ
+ * and register device.
+ * Input:
+ * none
+ * Output:
+ * 0 --- successful
+ * else --- failure, usually it is negative value of error code
+ */
+static int ifx_ptm_init(void)
+{
+ int ret;
+ struct port_cell_info port_cell = {0};
+ void *xdata_addr = NULL;
+ int i;
+ char ver_str[256];
+
+ check_parameters();
+
+ ret = init_priv_data();
+ if ( ret != 0 ) {
+ err("INIT_PRIV_DATA_FAIL");
+ goto INIT_PRIV_DATA_FAIL;
+ }
+
+ ifx_ptm_init_chip();
+ init_tables();
+
+ for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ ) {
+ g_net_dev[i] = alloc_netdev(0, g_net_dev_name[i], ether_setup);
+ if ( g_net_dev[i] == NULL )
+ goto ALLOC_NETDEV_FAIL;
+ ptm_setup(g_net_dev[i], i);
+ }
+
+ for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ ) {
+ ret = register_netdev(g_net_dev[i]);
+ if ( ret != 0 )
+ goto REGISTER_NETDEV_FAIL;
+ }
+
+ /* register interrupt handler */
+ ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, IRQF_DISABLED, "ptm_mailbox_isr", &g_ptm_priv_data);
+ if ( ret ) {
+ if ( ret == -EBUSY ) {
+ err("IRQ may be occupied by other driver, please reconfig to disable it.");
+ }
+ else {
+ err("request_irq fail");
+ }
+ goto REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL;
+ }
+ disable_irq(PPE_MAILBOX_IGU1_INT);
+
+ ret = ifx_pp32_start(0);
+ if ( ret ) {
+ err("ifx_pp32_start fail!");
+ goto PP32_START_FAIL;
+ }
+ IFX_REG_W32(0, MBOX_IGU1_IER);
+ IFX_REG_W32(~0, MBOX_IGU1_ISRC);
+
+ enable_irq(PPE_MAILBOX_IGU1_INT);
+
+
+ proc_file_create();
+
+ port_cell.port_num = 1;
+ ifx_mei_atm_showtime_check(&g_showtime, &port_cell, &xdata_addr);
+
+ ifx_mei_atm_showtime_enter = ptm_showtime_enter;
+ ifx_mei_atm_showtime_exit = ptm_showtime_exit;
+
+ ifx_ptm_version(ver_str);
+ printk(KERN_INFO "%s", ver_str);
+
+ printk("ifxmips_ptm: PTM init succeed\n");
+
+ return 0;
+
+PP32_START_FAIL:
+ free_irq(PPE_MAILBOX_IGU1_INT, &g_ptm_priv_data);
+REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL:
+ i = ARRAY_SIZE(g_net_dev);
+REGISTER_NETDEV_FAIL:
+ while ( i-- )
+ unregister_netdev(g_net_dev[i]);
+ i = ARRAY_SIZE(g_net_dev);
+ALLOC_NETDEV_FAIL:
+ while ( i-- ) {
+ free_netdev(g_net_dev[i]);
+ g_net_dev[i] = NULL;
+ }
+INIT_PRIV_DATA_FAIL:
+ clear_priv_data();
+ printk("ifxmips_ptm: PTM init failed\n");
+ return ret;
+}
+
+/*
+ * Description:
+ * Release memory, free IRQ, and deregister device.
+ * Input:
+ * none
+ * Output:
+ * none
+ */
+static void __exit ifx_ptm_exit(void)
+{
+ int i;
+
+ ifx_mei_atm_showtime_enter = NULL;
+ ifx_mei_atm_showtime_exit = NULL;
+
+ proc_file_delete();
+
+
+ ifx_pp32_stop(0);
+
+ free_irq(PPE_MAILBOX_IGU1_INT, &g_ptm_priv_data);
+
+ for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ )
+ unregister_netdev(g_net_dev[i]);
+
+ for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ ) {
+ free_netdev(g_net_dev[i]);
+ g_net_dev[i] = NULL;
+ }
+
+ ifx_ptm_uninit_chip();
+
+ clear_priv_data();
+}
+
+module_init(ifx_ptm_init);
+module_exit(ifx_ptm_exit);
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.h
new file mode 100644
index 0000000000..de307bf732
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.h
@@ -0,0 +1,137 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_adsl.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (core functions for Danube/Amazon-SE/
+** AR9)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 17 JUN 2009 Xu Liang Init Version
+*******************************************************************************/
+
+#ifndef IFXMIPS_PTM_ADSL_H
+#define IFXMIPS_PTM_ADSL_H
+
+
+
+#include <linux/version.h>
+#include <linux/netdevice.h>
+#include <lantiq_ptm.h>
+#include "ifxmips_ptm_common.h"
+#include "ifxmips_ptm_ppe_common.h"
+#include "ifxmips_ptm_fw_regs_adsl.h"
+
+#define CONFIG_IFXMIPS_DSL_CPE_MEI
+#define INT_NUM_IM2_IRL24 (INT_NUM_IM2_IRL0 + 24)
+
+#define IFX_REG_W32(_v, _r) __raw_writel((_v), (volatile unsigned int *)(_r))
+#define IFX_REG_R32(_r) __raw_readl((volatile unsigned int *)(_r))
+#define IFX_REG_W32_MASK(_clr, _set, _r) IFX_REG_W32((IFX_REG_R32((_r)) & ~(_clr)) | (_set), (_r))
+#define SET_BITS(x, msb, lsb, value) (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))
+
+
+
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+/*
+ * Constant Definition
+ */
+#define ETH_WATCHDOG_TIMEOUT (2 * HZ)
+
+/*
+ * DMA RX/TX Channel Parameters
+ */
+#define MAX_ITF_NUMBER 2
+#define MAX_RX_DMA_CHANNEL_NUMBER MAX_ITF_NUMBER
+#define MAX_TX_DMA_CHANNEL_NUMBER MAX_ITF_NUMBER
+#define DATA_BUFFER_ALIGNMENT EMA_ALIGNMENT
+#define DESC_ALIGNMENT 8
+
+/*
+ * Ethernet Frame Definitions
+ */
+#define ETH_MAC_HEADER_LENGTH 14
+#define ETH_CRC_LENGTH 4
+#define ETH_MIN_FRAME_LENGTH 64
+#define ETH_MAX_FRAME_LENGTH (1518 + 4 * 2)
+
+/*
+ * RX Frame Definitions
+ */
+#define RX_HEAD_MAC_ADDR_ALIGNMENT 2
+#define RX_TAIL_CRC_LENGTH 0 // PTM firmware does not have ethernet frame CRC
+ // The len in descriptor doesn't include ETH_CRC
+ // because ETH_CRC may not present in some configuration
+
+
+
+/*
+ * ####################################
+ * Data Type
+ * ####################################
+ */
+
+struct ptm_itf {
+ volatile struct rx_descriptor *rx_desc;
+ unsigned int rx_desc_pos;
+
+ volatile struct tx_descriptor *tx_desc;
+ unsigned int tx_desc_pos;
+ struct sk_buff **tx_skb;
+
+ struct net_device_stats stats;
+
+ struct napi_struct napi;
+};
+
+struct ptm_priv_data {
+ struct ptm_itf itf[MAX_ITF_NUMBER];
+
+ void *rx_desc_base;
+ void *tx_desc_base;
+ void *tx_skb_base;
+};
+
+
+
+/*
+ * ####################################
+ * Declaration
+ * ####################################
+ */
+
+extern unsigned int ifx_ptm_dbg_enable;
+
+extern void ifx_ptm_get_fw_ver(unsigned int *major, unsigned int *minor);
+
+extern void ifx_ptm_init_chip(void);
+extern void ifx_ptm_uninit_chip(void);
+
+extern int ifx_pp32_start(int pp32);
+extern void ifx_pp32_stop(int pp32);
+
+extern void ifx_reset_ppe(void);
+
+extern int ifx_ptm_proc_read_regs(char *page, char **start, off_t off, int count, int *eof, void *data);
+
+
+
+#endif // IFXMIPS_PTM_ADSL_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_amazon_se.c b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_amazon_se.c
new file mode 100644
index 0000000000..077c900e27
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_amazon_se.c
@@ -0,0 +1,322 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_amazon_se.c
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver common source file (core functions)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+/*
+ * ####################################
+ * Head File
+ * ####################################
+ */
+
+/*
+ * Common Head File
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <asm/delay.h>
+
+/*
+ * Chip Specific Head File
+ */
+#include <asm/ifx/ifx_types.h>
+#include <asm/ifx/ifx_regs.h>
+#include <asm/ifx/common_routines.h>
+#include <asm/ifx/ifx_pmu.h>
+#include <asm/ifx/ifx_rcu.h>
+#include "ifxmips_ptm_adsl.h"
+#include "ifxmips_ptm_fw_amazon_se.h"
+
+
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+/*
+ * EMA Settings
+ */
+#define EMA_CMD_BUF_LEN 0x0040
+#define EMA_CMD_BASE_ADDR (0x00001580 << 2)
+#define EMA_DATA_BUF_LEN 0x0100
+#define EMA_DATA_BASE_ADDR (0x00000B00 << 2)
+#define EMA_WRITE_BURST 0x2
+#define EMA_READ_BURST 0x2
+
+
+
+/*
+ * ####################################
+ * Declaration
+ * ####################################
+ */
+
+/*
+ * Hardware Init/Uninit Functions
+ */
+static inline void init_pmu(void);
+static inline void uninit_pmu(void);
+static inline void reset_ppe(void);
+static inline void init_ema(void);
+static inline void init_mailbox(void);
+static inline void init_atm_tc(void);
+static inline void clear_share_buffer(void);
+
+
+
+/*
+ * ####################################
+ * Local Variable
+ * ####################################
+ */
+
+
+
+/*
+ * ####################################
+ * Local Function
+ * ####################################
+ */
+
+static inline void init_pmu(void)
+{
+ //*(unsigned long *)0xBF10201C &= ~((1 << 15) | (1 << 13) | (1 << 9));
+ //PPE_TOP_PMU_SETUP(IFX_PMU_ENABLE);
+ PPE_SLL01_PMU_SETUP(IFX_PMU_ENABLE);
+ PPE_TC_PMU_SETUP(IFX_PMU_ENABLE);
+ PPE_EMA_PMU_SETUP(IFX_PMU_ENABLE);
+ //PPE_QSB_PMU_SETUP(IFX_PMU_ENABLE);
+ PPE_TPE_PMU_SETUP(IFX_PMU_ENABLE);
+ DSL_DFE_PMU_SETUP(IFX_PMU_ENABLE);
+}
+
+static inline void uninit_pmu(void)
+{
+ PPE_SLL01_PMU_SETUP(IFX_PMU_DISABLE);
+ PPE_TC_PMU_SETUP(IFX_PMU_DISABLE);
+ PPE_EMA_PMU_SETUP(IFX_PMU_DISABLE);
+ //PPE_QSB_PMU_SETUP(IFX_PMU_DISABLE);
+ PPE_TPE_PMU_SETUP(IFX_PMU_DISABLE);
+ DSL_DFE_PMU_SETUP(IFX_PMU_DISABLE);
+ //PPE_TOP_PMU_SETUP(IFX_PMU_DISABLE);
+}
+
+static inline void reset_ppe(void)
+{
+#ifdef MODULE
+ unsigned int etop_cfg;
+ unsigned int etop_mdio_cfg;
+ unsigned int etop_ig_plen_ctrl;
+ unsigned int enet_mac_cfg;
+
+ etop_cfg = *IFX_PP32_ETOP_CFG;
+ etop_mdio_cfg = *IFX_PP32_ETOP_MDIO_CFG;
+ etop_ig_plen_ctrl = *IFX_PP32_ETOP_IG_PLEN_CTRL;
+ enet_mac_cfg = *IFX_PP32_ENET_MAC_CFG;
+
+ *IFX_PP32_ETOP_CFG = (*IFX_PP32_ETOP_CFG & ~0x03C0) | 0x0001;
+
+ // reset PPE
+ ifx_rcu_rst(IFX_RCU_DOMAIN_PPE, IFX_RCU_MODULE_PTM);
+
+ *IFX_PP32_ETOP_MDIO_CFG = etop_mdio_cfg;
+ *IFX_PP32_ETOP_IG_PLEN_CTRL = etop_ig_plen_ctrl;
+ *IFX_PP32_ENET_MAC_CFG = enet_mac_cfg;
+ *IFX_PP32_ETOP_CFG = etop_cfg;
+#endif
+}
+
+static inline void init_ema(void)
+{
+ // Configure share buffer master selection
+ *SB_MST_PRI0 = 1;
+ *SB_MST_PRI1 = 1;
+
+ // EMA Settings
+ IFX_REG_W32((EMA_CMD_BUF_LEN << 16) | (EMA_CMD_BASE_ADDR >> 2), EMA_CMDCFG);
+ IFX_REG_W32((EMA_DATA_BUF_LEN << 16) | (EMA_DATA_BASE_ADDR >> 2), EMA_DATACFG);
+ IFX_REG_W32(0x000000FF, EMA_IER);
+ IFX_REG_W32(EMA_READ_BURST | (EMA_WRITE_BURST << 2), EMA_CFG);
+}
+
+static inline void init_mailbox(void)
+{
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU1_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU1_IER);
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU3_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU3_IER);
+}
+
+static inline void init_atm_tc(void)
+{
+ IFX_REG_W32(0x0F00, DREG_AT_CTRL);
+ IFX_REG_W32(0x3C00, DREG_AR_CTRL);
+ IFX_REG_W32(0x0, DREG_AT_IDLE0);
+ IFX_REG_W32(0x0, DREG_AT_IDLE1);
+ IFX_REG_W32(0x0, DREG_AR_IDLE0);
+ IFX_REG_W32(0x0, DREG_AR_IDLE1);
+ IFX_REG_W32(0x0, RFBI_CFG);
+ IFX_REG_W32(0x0200, SFSM_DBA0);
+ IFX_REG_W32(0x0800, SFSM_DBA1);
+ IFX_REG_W32(0x0321, SFSM_CBA0);
+ IFX_REG_W32(0x0921, SFSM_CBA1);
+ IFX_REG_W32(0x14011, SFSM_CFG0);
+ IFX_REG_W32(0x14011, SFSM_CFG1);
+ IFX_REG_W32(0x0332, FFSM_DBA0);
+ IFX_REG_W32(0x0932, FFSM_DBA1);
+ IFX_REG_W32(0x3000C, FFSM_CFG0);
+ IFX_REG_W32(0x3000C, FFSM_CFG1);
+ IFX_REG_W32(0xF0D10000, FFSM_IDLE_HEAD_BC0);
+ IFX_REG_W32(0xF0D10000, FFSM_IDLE_HEAD_BC1);
+}
+
+static inline void clear_share_buffer(void)
+{
+ volatile u32 *p = SB_RAM0_ADDR(0);
+ unsigned int i;
+
+ for ( i = 0; i < SB_RAM0_DWLEN + SB_RAM1_DWLEN; i++ )
+ IFX_REG_W32(0, p++);
+}
+
+/*
+ * Description:
+ * Download PPE firmware binary code.
+ * Input:
+ * src --- u32 *, binary code buffer
+ * dword_len --- unsigned int, binary code length in DWORD (32-bit)
+ * Output:
+ * int --- 0: Success
+ * else: Error Code
+ */
+static inline int pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
+{
+ volatile u32 *dest;
+
+ if ( code_src == 0 || ((unsigned long)code_src & 0x03) != 0
+ || data_src == 0 || ((unsigned long)data_src & 0x03) != 0 )
+ return -1;
+
+ if ( code_dword_len <= CDM_CODE_MEMORYn_DWLEN(0) )
+ IFX_REG_W32(0x00, CDM_CFG);
+ else
+ IFX_REG_W32(0x04, CDM_CFG);
+
+ /* copy code */
+ dest = CDM_CODE_MEMORY(0, 0);
+ while ( code_dword_len-- > 0 )
+ IFX_REG_W32(*code_src++, dest++);
+
+ /* copy data */
+ dest = CDM_DATA_MEMORY(0, 0);
+ while ( data_dword_len-- > 0 )
+ IFX_REG_W32(*data_src++, dest++);
+
+ return 0;
+}
+
+
+
+/*
+ * ####################################
+ * Global Function
+ * ####################################
+ */
+
+extern void ifx_ptm_get_fw_ver(unsigned int *major, unsigned int *minor)
+{
+ ASSERT(major != NULL, "pointer is NULL");
+ ASSERT(minor != NULL, "pointer is NULL");
+
+ *major = FW_VER_ID->major;
+ *minor = FW_VER_ID->minor;
+}
+
+void ifx_ptm_init_chip(void)
+{
+ init_pmu();
+
+ reset_ppe();
+
+ init_ema();
+
+ init_mailbox();
+
+ init_atm_tc();
+
+ clear_share_buffer();
+}
+
+void ifx_ptm_uninit_chip(void)
+{
+ uninit_pmu();
+}
+
+/*
+ * Description:
+ * Initialize and start up PP32.
+ * Input:
+ * none
+ * Output:
+ * int --- 0: Success
+ * else: Error Code
+ */
+int ifx_pp32_start(int pp32)
+{
+ int ret;
+
+ /* download firmware */
+ ret = pp32_download_code(firmware_binary_code, sizeof(firmware_binary_code) / sizeof(*firmware_binary_code), firmware_binary_data, sizeof(firmware_binary_data) / sizeof(*firmware_binary_data));
+ if ( ret != 0 )
+ return ret;
+
+ /* run PP32 */
+ IFX_REG_W32(DBG_CTRL_RESTART, PP32_DBG_CTRL(pp32));
+
+ /* idle for a while to let PP32 init itself */
+ udelay(10);
+
+ return 0;
+}
+
+/*
+ * Description:
+ * Halt PP32.
+ * Input:
+ * none
+ * Output:
+ * none
+ */
+void ifx_pp32_stop(int pp32)
+{
+ /* halt PP32 */
+ IFX_REG_W32(DBG_CTRL_STOP, PP32_DBG_CTRL(pp32));
+}
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ar9.c b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ar9.c
new file mode 100644
index 0000000000..777d5cfc9b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ar9.c
@@ -0,0 +1,376 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_ar9.c
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver common source file (core functions)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+/*
+ * ####################################
+ * Head File
+ * ####################################
+ */
+
+/*
+ * Common Head File
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <asm/delay.h>
+
+/*
+ * Chip Specific Head File
+ */
+#include "ifxmips_ptm_adsl.h"
+#include "ifxmips_ptm_fw_ar9.h"
+
+#include <lantiq_soc.h>
+
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+/*
+ * EMA Settings
+ */
+#define EMA_CMD_BUF_LEN 0x0040
+#define EMA_CMD_BASE_ADDR (0x00001B80 << 2)
+#define EMA_DATA_BUF_LEN 0x0100
+#define EMA_DATA_BASE_ADDR (0x00001C00 << 2)
+#define EMA_WRITE_BURST 0x2
+#define EMA_READ_BURST 0x2
+
+
+
+/*
+ * ####################################
+ * Declaration
+ * ####################################
+ */
+
+/*
+ * Hardware Init/Uninit Functions
+ */
+static inline void init_pmu(void);
+static inline void uninit_pmu(void);
+static inline void reset_ppe(void);
+static inline void init_ema(void);
+static inline void init_mailbox(void);
+static inline void init_atm_tc(void);
+static inline void clear_share_buffer(void);
+
+
+
+/*
+ * ####################################
+ * Local Variable
+ * ####################################
+ */
+
+
+
+/*
+ * ####################################
+ * Local Function
+ * ####################################
+ */
+
+#define IFX_PMU_MODULE_PPE_SLL01 BIT(19)
+#define IFX_PMU_MODULE_PPE_TC BIT(21)
+#define IFX_PMU_MODULE_PPE_EMA BIT(22)
+#define IFX_PMU_MODULE_PPE_QSB BIT(18)
+#define IFX_PMU_MODULE_TPE BIT(13)
+#define IFX_PMU_MODULE_DSL_DFE BIT(9)
+
+
+static inline void init_pmu(void)
+{
+ ltq_pmu_enable(IFX_PMU_MODULE_PPE_SLL01 |
+ IFX_PMU_MODULE_PPE_TC |
+ IFX_PMU_MODULE_PPE_EMA |
+ IFX_PMU_MODULE_TPE |
+ IFX_PMU_MODULE_DSL_DFE);
+
+}
+
+static inline void uninit_pmu(void)
+{
+ ltq_pmu_disable(IFX_PMU_MODULE_PPE_SLL01 |
+ IFX_PMU_MODULE_PPE_TC |
+ IFX_PMU_MODULE_PPE_EMA |
+ IFX_PMU_MODULE_TPE |
+ IFX_PMU_MODULE_DSL_DFE);
+
+}
+
+static inline void reset_ppe(void)
+{
+#ifdef MODULE
+ // reset PPE
+// ifx_rcu_rst(IFX_RCU_DOMAIN_PPE, IFX_RCU_MODULE_PTM);
+#endif
+}
+
+static inline void init_ema(void)
+{
+ // Configure share buffer master selection
+ IFX_REG_W32(1, SB_MST_PRI0);
+ IFX_REG_W32(1, SB_MST_PRI1);
+
+ // EMA Settings
+ IFX_REG_W32((EMA_CMD_BUF_LEN << 16) | (EMA_CMD_BASE_ADDR >> 2), EMA_CMDCFG);
+ IFX_REG_W32((EMA_DATA_BUF_LEN << 16) | (EMA_DATA_BASE_ADDR >> 2), EMA_DATACFG);
+ IFX_REG_W32(0x000000FF, EMA_IER);
+ IFX_REG_W32(EMA_READ_BURST | (EMA_WRITE_BURST << 2), EMA_CFG);
+}
+
+static inline void init_mailbox(void)
+{
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU1_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU1_IER);
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU3_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU3_IER);
+}
+
+static inline void init_atm_tc(void)
+{
+ IFX_REG_W32(0x0, RFBI_CFG);
+ IFX_REG_W32(0x1800, SFSM_DBA0);
+ IFX_REG_W32(0x1921, SFSM_DBA1);
+ IFX_REG_W32(0x1A42, SFSM_CBA0);
+ IFX_REG_W32(0x1A53, SFSM_CBA1);
+ IFX_REG_W32(0x14011, SFSM_CFG0);
+ IFX_REG_W32(0x14011, SFSM_CFG1);
+ IFX_REG_W32(0x1000, FFSM_DBA0);
+ IFX_REG_W32(0x1700, FFSM_DBA1);
+ IFX_REG_W32(0x3000C, FFSM_CFG0);
+ IFX_REG_W32(0x3000C, FFSM_CFG1);
+ IFX_REG_W32(0xF0D10000, FFSM_IDLE_HEAD_BC0);
+ IFX_REG_W32(0xF0D10000, FFSM_IDLE_HEAD_BC1);
+
+ /*
+ * 0. Backup port2 value to temp
+ * 1. Disable CPU port2 in switch (link and learning)
+ * 2. wait for a while
+ * 3. Configure DM register and counter
+ * 4. restore temp to CPU port2 in switch
+ * This code will cause network to stop working if there are heavy
+ * traffic during bootup. This part should be moved to switch and use
+ * the same code as ATM
+ */
+ {
+ int i;
+ u32 temp;
+
+ temp = IFX_REG_R32(SW_P2_CTL);
+
+ IFX_REG_W32(0x40020000, SW_P2_CTL);
+ for (i = 0; i < 200; i++)
+ udelay(2000);
+
+ IFX_REG_W32(0x00007028, DM_RXCFG);
+ IFX_REG_W32(0x00007028, DS_RXCFG);
+
+ IFX_REG_W32(0x00001100, DM_RXDB);
+ IFX_REG_W32(0x00001100, DS_RXDB);
+
+ IFX_REG_W32(0x00001600, DM_RXCB);
+ IFX_REG_W32(0x00001600, DS_RXCB);
+
+ /*
+ * For dynamic, must reset these counters,
+ * For once initialization, don't need to reset these counters
+ */
+ IFX_REG_W32(0x0, DM_RXPGCNT);
+ IFX_REG_W32(0x0, DS_RXPGCNT);
+ IFX_REG_W32(0x0, DM_RXPKTCNT);
+
+ IFX_REG_W32_MASK(0, 0x80000000, DM_RXCFG);
+ IFX_REG_W32_MASK(0, 0x8000, DS_RXCFG);
+
+ udelay(2000);
+ IFX_REG_W32(temp, SW_P2_CTL);
+ udelay(2000);
+ }
+}
+
+static inline void clear_share_buffer(void)
+{
+ volatile u32 *p = SB_RAM0_ADDR(0);
+ unsigned int i;
+
+ for ( i = 0; i < SB_RAM0_DWLEN + SB_RAM1_DWLEN + SB_RAM2_DWLEN + SB_RAM3_DWLEN + SB_RAM4_DWLEN; i++ )
+ IFX_REG_W32(0, p++);
+}
+
+/*
+ * Description:
+ * Download PPE firmware binary code.
+ * Input:
+ * src --- u32 *, binary code buffer
+ * dword_len --- unsigned int, binary code length in DWORD (32-bit)
+ * Output:
+ * int --- 0: Success
+ * else: Error Code
+ */
+static inline int pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
+{
+ volatile u32 *dest;
+
+ if ( code_src == 0 || ((unsigned long)code_src & 0x03) != 0
+ || data_src == 0 || ((unsigned long)data_src & 0x03) != 0 )
+ return -1;
+
+ if ( code_dword_len <= CDM_CODE_MEMORYn_DWLEN(0) )
+ IFX_REG_W32(0x00, CDM_CFG);
+ else
+ IFX_REG_W32(0x04, CDM_CFG);
+
+ /* copy code */
+ dest = CDM_CODE_MEMORY(0, 0);
+ while ( code_dword_len-- > 0 )
+ IFX_REG_W32(*code_src++, dest++);
+
+ /* copy data */
+ dest = CDM_DATA_MEMORY(0, 0);
+ while ( data_dword_len-- > 0 )
+ IFX_REG_W32(*data_src++, dest++);
+
+ return 0;
+}
+
+
+
+/*
+ * ####################################
+ * Global Function
+ * ####################################
+ */
+
+void ifx_ptm_get_fw_ver(unsigned int *major, unsigned int *minor)
+{
+ ASSERT(major != NULL, "pointer is NULL");
+ ASSERT(minor != NULL, "pointer is NULL");
+
+ *major = FW_VER_ID->major;
+ *minor = FW_VER_ID->minor;
+}
+
+void ifx_ptm_init_chip(void)
+{
+ init_pmu();
+
+ reset_ppe();
+
+ init_ema();
+
+ init_mailbox();
+
+ init_atm_tc();
+
+ clear_share_buffer();
+}
+
+void ifx_ptm_uninit_chip(void)
+{
+ uninit_pmu();
+}
+
+/*
+ * Description:
+ * Initialize and start up PP32.
+ * Input:
+ * none
+ * Output:
+ * int --- 0: Success
+ * else: Error Code
+ */
+int ifx_pp32_start(int pp32)
+{
+ int ret;
+
+ /* download firmware */
+ ret = pp32_download_code(firmware_binary_code, sizeof(firmware_binary_code) / sizeof(*firmware_binary_code), firmware_binary_data, sizeof(firmware_binary_data) / sizeof(*firmware_binary_data));
+ if ( ret != 0 )
+ return ret;
+
+ /* run PP32 */
+ IFX_REG_W32(DBG_CTRL_RESTART, PP32_DBG_CTRL(0));
+
+ /* idle for a while to let PP32 init itself */
+ udelay(10);
+
+ return 0;
+}
+
+/*
+ * Description:
+ * Halt PP32.
+ * Input:
+ * none
+ * Output:
+ * none
+ */
+void ifx_pp32_stop(int pp32)
+{
+ /* halt PP32 */
+ IFX_REG_W32(DBG_CTRL_STOP, PP32_DBG_CTRL(0));
+}
+
+int ifx_ptm_proc_read_regs(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len = 0;
+
+ len += sprintf(page + off + len, "EMA:\n");
+ len += sprintf(page + off + len, " SB_MST_PRI0 - 0x%08X, SB_MST_PRI1 - 0x%08X\n", IFX_REG_R32(SB_MST_PRI0), IFX_REG_R32(SB_MST_PRI1));
+ len += sprintf(page + off + len, " EMA_CMDCFG - 0x%08X, EMA_DATACFG - 0x%08X\n", IFX_REG_R32(EMA_CMDCFG), IFX_REG_R32(EMA_DATACFG));
+ len += sprintf(page + off + len, " EMA_IER - 0x%08X, EMA_CFG - 0x%08X\n", IFX_REG_R32(EMA_IER), IFX_REG_R32(EMA_CFG));
+
+ len += sprintf(page + off + len, "Mailbox:\n");
+ len += sprintf(page + off + len, " MBOX_IGU1_IER - 0x%08X, MBOX_IGU1_ISR - 0x%08X\n", IFX_REG_R32(MBOX_IGU1_IER), IFX_REG_R32(MBOX_IGU1_ISR));
+ len += sprintf(page + off + len, " MBOX_IGU3_IER - 0x%08X, MBOX_IGU3_ISR - 0x%08X\n", IFX_REG_R32(MBOX_IGU3_IER), IFX_REG_R32(MBOX_IGU3_ISR));
+
+ len += sprintf(page + off + len, "TC:\n");
+ len += sprintf(page + off + len, " RFBI_CFG - 0x%08X\n", IFX_REG_R32(RFBI_CFG));
+ len += sprintf(page + off + len, " SFSM_DBA0 - 0x%08X, SFSM_CBA0 - 0x%08X, SFSM_CFG0 - 0x%08X\n", IFX_REG_R32(SFSM_DBA0), IFX_REG_R32(SFSM_CBA0), IFX_REG_R32(SFSM_CFG0));
+ len += sprintf(page + off + len, " SFSM_DBA1 - 0x%08X, SFSM_CBA1 - 0x%08X, SFSM_CFG1 - 0x%08X\n", IFX_REG_R32(SFSM_DBA1), IFX_REG_R32(SFSM_CBA1), IFX_REG_R32(SFSM_CFG1));
+ len += sprintf(page + off + len, " FFSM_DBA0 - 0x%08X, FFSM_CFG0 - 0x%08X, IDLE_HEAD - 0x%08X\n", IFX_REG_R32(FFSM_DBA0), IFX_REG_R32(FFSM_CFG0), IFX_REG_R32(FFSM_IDLE_HEAD_BC0));
+ len += sprintf(page + off + len, " FFSM_DBA1 - 0x%08X, FFSM_CFG1 - 0x%08X, IDLE_HEAD - 0x%08X\n", IFX_REG_R32(FFSM_DBA1), IFX_REG_R32(FFSM_CFG1), IFX_REG_R32(FFSM_IDLE_HEAD_BC1));
+
+ len += sprintf(page + off + len, "DPlus:\n");
+ len += sprintf(page + off + len, " DM_RXDB - 0x%08X, DM_RXCB - 0x%08X, DM_RXCFG - 0x%08X\n", IFX_REG_R32(DM_RXDB), IFX_REG_R32(DM_RXCB), IFX_REG_R32(DM_RXCFG));
+ len += sprintf(page + off + len, " DM_RXPGCNT - 0x%08X, DM_RXPKTCNT - 0x%08X\n", IFX_REG_R32(DM_RXPGCNT), IFX_REG_R32(DM_RXPKTCNT));
+ len += sprintf(page + off + len, " DS_RXDB - 0x%08X, DS_RXCB - 0x%08X, DS_RXCFG - 0x%08X\n", IFX_REG_R32(DS_RXDB), IFX_REG_R32(DS_RXCB), IFX_REG_R32(DS_RXCFG));
+ len += sprintf(page + off + len, " DS_RXPGCNT - 0x%08X\n", IFX_REG_R32(DS_RXPGCNT));
+
+ *eof = 1;
+
+ return len;
+}
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_common.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_common.h
new file mode 100644
index 0000000000..ccd19b189b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_common.h
@@ -0,0 +1,102 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_common.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (common definitions)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 17 JUN 2009 Xu Liang Init Version
+*******************************************************************************/
+
+#ifndef IFXMIPS_PTM_COMMON_H
+#define IFXMIPS_PTM_COMMON_H
+
+
+
+/*
+ * ####################################
+ * Version No.
+ * ####################################
+ */
+
+#define IFX_PTM_VER_MAJOR 1
+#define IFX_PTM_VER_MID 0
+#define IFX_PTM_VER_MINOR 27
+
+
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+/*
+ * Compile Options
+ */
+
+#define ENABLE_DEBUG 1
+
+#define ENABLE_ASSERT 1
+
+#define INLINE
+
+#define DEBUG_DUMP_SKB 1
+
+#define DEBUG_QOS 1
+
+#define ENABLE_DBG_PROC 1
+
+#define ENABLE_FW_PROC 1
+
+#if defined(CONFIG_DSL_MEI_CPE_DRV) && !defined(CONFIG_IFXMIPS_DSL_CPE_MEI)
+ #define CONFIG_IFXMIPS_DSL_CPE_MEI 1
+#endif
+
+/*
+ * Debug/Assert/Error Message
+ */
+
+#define DBG_ENABLE_MASK_ERR (1 << 0)
+#define DBG_ENABLE_MASK_DEBUG_PRINT (1 << 1)
+#define DBG_ENABLE_MASK_ASSERT (1 << 2)
+#define DBG_ENABLE_MASK_DUMP_SKB_RX (1 << 8)
+#define DBG_ENABLE_MASK_DUMP_SKB_TX (1 << 9)
+#define DBG_ENABLE_MASK_DUMP_QOS (1 << 10)
+#define DBG_ENABLE_MASK_DUMP_INIT (1 << 11)
+#define DBG_ENABLE_MASK_MAC_SWAP (1 << 12)
+#define DBG_ENABLE_MASK_ALL (DBG_ENABLE_MASK_ERR | DBG_ENABLE_MASK_DEBUG_PRINT | DBG_ENABLE_MASK_ASSERT | DBG_ENABLE_MASK_DUMP_SKB_RX | DBG_ENABLE_MASK_DUMP_SKB_TX | DBG_ENABLE_MASK_DUMP_QOS | DBG_ENABLE_MASK_DUMP_INIT | DBG_ENABLE_MASK_MAC_SWAP)
+
+#define err(format, arg...) do { if ( (ifx_ptm_dbg_enable & DBG_ENABLE_MASK_ERR) ) printk(KERN_ERR __FILE__ ":%d:%s: " format "\n", __LINE__, __FUNCTION__, ##arg); } while ( 0 )
+
+#if defined(ENABLE_DEBUG) && ENABLE_DEBUG
+ #undef dbg
+ #define dbg(format, arg...) do { if ( (ifx_ptm_dbg_enable & DBG_ENABLE_MASK_DEBUG_PRINT) ) printk(KERN_WARNING __FILE__ ":%d:%s: " format "\n", __LINE__, __FUNCTION__, ##arg); } while ( 0 )
+#else
+ #if !defined(dbg)
+ #define dbg(format, arg...)
+ #endif
+#endif
+
+#if defined(ENABLE_ASSERT) && ENABLE_ASSERT
+ #define ASSERT(cond, format, arg...) do { if ( (ifx_ptm_dbg_enable & DBG_ENABLE_MASK_ASSERT) && !(cond) ) printk(KERN_ERR __FILE__ ":%d:%s: " format "\n", __LINE__, __FUNCTION__, ##arg); } while ( 0 )
+#else
+ #define ASSERT(cond, format, arg...)
+#endif
+
+
+
+#endif // IFXMIPS_PTM_COMMON_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_danube.c b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_danube.c
new file mode 100644
index 0000000000..279b03ba3a
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_danube.c
@@ -0,0 +1,317 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_danube.c
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver common source file (core functions)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+/*
+ * ####################################
+ * Head File
+ * ####################################
+ */
+
+/*
+ * Common Head File
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+
+/*
+ * Chip Specific Head File
+ */
+#include "ifxmips_ptm_adsl.h"
+#include "ifxmips_ptm_fw_danube.h"
+
+#include <lantiq_soc.h>
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+/*
+ * EMA Settings
+ */
+#define EMA_CMD_BUF_LEN 0x0040
+#define EMA_CMD_BASE_ADDR (0x00001580 << 2)
+#define EMA_DATA_BUF_LEN 0x0100
+#define EMA_DATA_BASE_ADDR (0x00000B00 << 2)
+#define EMA_WRITE_BURST 0x2
+#define EMA_READ_BURST 0x2
+
+
+
+/*
+ * ####################################
+ * Declaration
+ * ####################################
+ */
+
+/*
+ * Hardware Init/Uninit Functions
+ */
+static inline void init_pmu(void);
+static inline void uninit_pmu(void);
+static inline void reset_ppe(void);
+static inline void init_ema(void);
+static inline void init_mailbox(void);
+static inline void init_atm_tc(void);
+static inline void clear_share_buffer(void);
+
+
+
+/*
+ * ####################################
+ * Local Variable
+ * ####################################
+ */
+
+
+#define IFX_PMU_MODULE_PPE_SLL01 BIT(19)
+#define IFX_PMU_MODULE_PPE_TC BIT(21)
+#define IFX_PMU_MODULE_PPE_EMA BIT(22)
+#define IFX_PMU_MODULE_PPE_QSB BIT(18)
+#define IFX_PMU_MODULE_TPE BIT(13)
+#define IFX_PMU_MODULE_DSL_DFE BIT(9)
+
+/*
+ * ####################################
+ * Local Function
+ * ####################################
+ */
+
+static inline void init_pmu(void)
+{
+ ltq_pmu_enable(IFX_PMU_MODULE_PPE_SLL01 |
+ IFX_PMU_MODULE_PPE_TC |
+ IFX_PMU_MODULE_PPE_EMA |
+ IFX_PMU_MODULE_TPE |
+ IFX_PMU_MODULE_DSL_DFE);
+}
+
+static inline void uninit_pmu(void)
+{
+ ltq_pmu_disable(IFX_PMU_MODULE_PPE_SLL01 |
+ IFX_PMU_MODULE_PPE_TC |
+ IFX_PMU_MODULE_PPE_EMA |
+ IFX_PMU_MODULE_TPE |
+ IFX_PMU_MODULE_DSL_DFE);
+}
+
+static inline void reset_ppe(void)
+{
+#ifdef MODULE
+ /*unsigned int etop_cfg;
+ unsigned int etop_mdio_cfg;
+ unsigned int etop_ig_plen_ctrl;
+ unsigned int enet_mac_cfg;
+
+ etop_cfg = *IFX_PP32_ETOP_CFG;
+ etop_mdio_cfg = *IFX_PP32_ETOP_MDIO_CFG;
+ etop_ig_plen_ctrl = *IFX_PP32_ETOP_IG_PLEN_CTRL;
+ enet_mac_cfg = *IFX_PP32_ENET_MAC_CFG;
+
+ *IFX_PP32_ETOP_CFG &= ~0x03C0;
+
+ // reset PPE
+ ifx_rcu_rst(IFX_RCU_DOMAIN_PPE, IFX_RCU_MODULE_PTM);
+
+ *IFX_PP32_ETOP_MDIO_CFG = etop_mdio_cfg;
+ *IFX_PP32_ETOP_IG_PLEN_CTRL = etop_ig_plen_ctrl;
+ *IFX_PP32_ENET_MAC_CFG = enet_mac_cfg;
+ *IFX_PP32_ETOP_CFG = etop_cfg;*/
+#endif
+}
+
+static inline void init_ema(void)
+{
+ // Configure share buffer master selection
+ *SB_MST_SEL |= 0x03;
+
+ // EMA Settings
+ IFX_REG_W32((EMA_CMD_BUF_LEN << 16) | (EMA_CMD_BASE_ADDR >> 2), EMA_CMDCFG);
+ IFX_REG_W32((EMA_DATA_BUF_LEN << 16) | (EMA_DATA_BASE_ADDR >> 2), EMA_DATACFG);
+ IFX_REG_W32(0x000000FF, EMA_IER);
+ IFX_REG_W32(EMA_READ_BURST | (EMA_WRITE_BURST << 2), EMA_CFG);
+}
+
+static inline void init_mailbox(void)
+{
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU1_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU1_IER);
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU3_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU3_IER);
+}
+
+static inline void init_atm_tc(void)
+{
+ IFX_REG_W32(0x0F00, DREG_AT_CTRL);
+ IFX_REG_W32(0x3C00, DREG_AR_CTRL);
+ IFX_REG_W32(0x0, DREG_AT_IDLE0);
+ IFX_REG_W32(0x0, DREG_AT_IDLE1);
+ IFX_REG_W32(0x0, DREG_AR_IDLE0);
+ IFX_REG_W32(0x0, DREG_AR_IDLE1);
+ IFX_REG_W32(0x0, RFBI_CFG);
+ IFX_REG_W32(0x1600, SFSM_DBA0);
+ IFX_REG_W32(0x1721, SFSM_DBA1);
+ IFX_REG_W32(0x1842, SFSM_CBA0);
+ IFX_REG_W32(0x1853, SFSM_CBA1);
+ IFX_REG_W32(0x14011, SFSM_CFG0);
+ IFX_REG_W32(0x14011, SFSM_CFG1);
+ IFX_REG_W32(0x1864, FFSM_DBA0);
+ IFX_REG_W32(0x1930, FFSM_DBA1);
+ IFX_REG_W32(0x3000C, FFSM_CFG0);
+ IFX_REG_W32(0x3000C, FFSM_CFG1);
+ IFX_REG_W32(0xF0D10000, FFSM_IDLE_HEAD_BC0);
+ IFX_REG_W32(0xF0D10000, FFSM_IDLE_HEAD_BC1);
+}
+
+static inline void clear_share_buffer(void)
+{
+ volatile u32 *p = SB_RAM0_ADDR(0);
+ unsigned int i;
+
+ for ( i = 0; i < SB_RAM0_DWLEN + SB_RAM1_DWLEN + SB_RAM2_DWLEN + SB_RAM3_DWLEN; i++ )
+ IFX_REG_W32(0, p++);
+}
+
+/*
+ * Description:
+ * Download PPE firmware binary code.
+ * Input:
+ * src --- u32 *, binary code buffer
+ * dword_len --- unsigned int, binary code length in DWORD (32-bit)
+ * Output:
+ * int --- 0: Success
+ * else: Error Code
+ */
+static inline int pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
+{
+ volatile u32 *dest;
+
+ if ( code_src == 0 || ((unsigned long)code_src & 0x03) != 0
+ || data_src == 0 || ((unsigned long)data_src & 0x03) != 0 )
+ return -1;
+
+ if ( code_dword_len <= CDM_CODE_MEMORYn_DWLEN(0) )
+ IFX_REG_W32(0x00, CDM_CFG);
+ else
+ IFX_REG_W32(0x04, CDM_CFG);
+
+ /* copy code */
+ dest = CDM_CODE_MEMORY(0, 0);
+ while ( code_dword_len-- > 0 )
+ IFX_REG_W32(*code_src++, dest++);
+
+ /* copy data */
+ dest = CDM_DATA_MEMORY(0, 0);
+ while ( data_dword_len-- > 0 )
+ IFX_REG_W32(*data_src++, dest++);
+
+ return 0;
+}
+
+
+
+/*
+ * ####################################
+ * Global Function
+ * ####################################
+ */
+
+extern void ifx_ptm_get_fw_ver(unsigned int *major, unsigned int *minor)
+{
+ ASSERT(major != NULL, "pointer is NULL");
+ ASSERT(minor != NULL, "pointer is NULL");
+
+ *major = FW_VER_ID->major;
+ *minor = FW_VER_ID->minor;
+}
+
+void ifx_ptm_init_chip(void)
+{
+ init_pmu();
+
+ reset_ppe();
+
+ init_ema();
+
+ init_mailbox();
+
+ init_atm_tc();
+
+ clear_share_buffer();
+}
+
+void ifx_ptm_uninit_chip(void)
+{
+ uninit_pmu();
+}
+
+/*
+ * Description:
+ * Initialize and start up PP32.
+ * Input:
+ * none
+ * Output:
+ * int --- 0: Success
+ * else: Error Code
+ */
+int ifx_pp32_start(int pp32)
+{
+ int ret;
+
+ /* download firmware */
+ ret = pp32_download_code(firmware_binary_code, sizeof(firmware_binary_code) / sizeof(*firmware_binary_code), firmware_binary_data, sizeof(firmware_binary_data) / sizeof(*firmware_binary_data));
+ if ( ret != 0 )
+ return ret;
+
+ /* run PP32 */
+ IFX_REG_W32(DBG_CTRL_START_SET(1), PP32_DBG_CTRL);
+
+ /* idle for a while to let PP32 init itself */
+ udelay(10);
+
+ return 0;
+}
+
+/*
+ * Description:
+ * Halt PP32.
+ * Input:
+ * none
+ * Output:
+ * none
+ */
+void ifx_pp32_stop(int pp32)
+{
+ /* halt PP32 */
+ IFX_REG_W32(DBG_CTRL_STOP_SET(1), PP32_DBG_CTRL);
+}
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_amazon_se.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_amazon_se.h
new file mode 100644
index 0000000000..ae33bcc66a
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_amazon_se.h
@@ -0,0 +1,493 @@
+#ifndef IFXMIPS_PTM_FW_AMAZON_SE_H
+#define IFXMIPS_PTM_FW_AMAZON_SE_H
+
+
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_fw_amazon_se.h
+** PROJECT : UEIP
+** MODULES : PTM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM Driver (PP32 Firmware)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+** 9 JAN 2007 Xu Liang First version got from Anand (IC designer)
+*******************************************************************************/
+
+
+#define PTM_FW_VER_MAJOR 0
+#define PTM_FW_VER_MINOR 17
+
+
+static unsigned int firmware_binary_code[] = {
+ 0x800004b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000ffe0, 0x00000000, 0x00000000, 0x00000000,
+ 0xc1000002, 0xd90c00f8, 0xc2000002, 0xda0800f9, 0x800055e0, 0xc2000000, 0xda0800f9, 0x80005580,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80005e58, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc10e0002, 0xd90c00f8, 0xc0004808, 0xc84000f8, 0x80005250, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc3e1fffe, 0x597dfffe, 0x593dfef4, 0x900004d9, 0x00000000, 0x00000000, 0x00000000, 0x90cc0481,
+ 0x00000000, 0x00000000, 0x00000000, 0xc3e06262, 0x5bfc0022, 0xc0004802, 0xcfc000f8, 0xc0004810,
+ 0xcbc000f8, 0x00000000, 0xc3800000, 0xc7f80038, 0x5fb80000, 0xc7fa0038, 0xc7bfe802, 0x5fb80000,
+ 0x00000000, 0xc7bff802, 0xdbd400f9, 0xc00049a0, 0xc3800002, 0xa7ca006a, 0xc1200000, 0x5911fffe,
+ 0xcd0000f9, 0xc1200000, 0x59102042, 0xcd0000f9, 0xc1000004, 0xcd0000f9, 0xc1200000, 0x59103a1e,
+ 0xcd0000f9, 0x80000060, 0xc121fffe, 0x5911fffe, 0xcd0000f9, 0xc1203db8, 0x5910de82, 0xcd0000f9,
+ 0xc1000006, 0xcd0000f9, 0xc120385a, 0x591033da, 0xcd0000f9, 0x5fb80002, 0x8800001a, 0x6ffe0010,
+ 0x8000ff28, 0xdd7c00f9, 0xc3800000, 0xc7f86010, 0x5bb80008, 0xc3540002, 0x777da000, 0xc1000008,
+ 0x4791c002, 0xcf8000f9, 0xdb900038, 0xc3800008, 0xc3720002, 0x777da000, 0xa7f00028, 0x47b9c002,
+ 0xc1000000, 0xc7d26010, 0x4391c000, 0xcf8000f8, 0xdb900838, 0xc3c00000, 0xdbc800f9, 0xc0400000,
+ 0xc11c0000, 0xc000082c, 0xcd05ce00, 0xc11c0002, 0xc000082c, 0xcd05ce00, 0xc0400002, 0xc11c0000,
+ 0xc000082c, 0xcd05ce00, 0xc11c0002, 0xc000082c, 0xcd05ce00, 0xc0000824, 0x00000000, 0xcbc000f9,
+ 0xcb8000f9, 0xcb4000f9, 0xcb0000f8, 0xc0004878, 0x5bfc4000, 0xcfc000f9, 0x5bb84000, 0xcf8000f9,
+ 0x5b744000, 0xcf4000f9, 0x5b304000, 0xcf0000f8, 0xc0000a10, 0x00000000, 0xcbc000f9, 0xcb8000f8,
+ 0xc0004874, 0x5bfc4000, 0xcfc000f9, 0x5bb84000, 0xcf8000f8, 0xc30001fe, 0xc000140a, 0xcf0000f8,
+ 0xc3000000, 0x7f018000, 0xc000042e, 0xcf0000f8, 0xc000040e, 0xcf0000f8, 0xc3c1fffe, 0xc000490e,
+ 0xcfc00078, 0xc000492c, 0xcfc00078, 0xc0004924, 0xcfc00038, 0xc0004912, 0xcfc00038, 0xc000498c,
+ 0xcfc00038, 0xc000498e, 0xcfc00078, 0xc0004990, 0xcfc00078, 0xc3c00000, 0xc2800004, 0xc3000000,
+ 0x7f018000, 0x6ff88000, 0x6fd44000, 0x4395c000, 0x5bb84a00, 0xc00049a0, 0xcb0000f8, 0x00000000,
+ 0x58380006, 0xcf0000f8, 0xc321fffe, 0x5b31fffe, 0x58380024, 0xcf0000f8, 0x5bfc0002, 0xb7e8ff90,
+ 0x00000000, 0xc3c00000, 0xc2800010, 0x6ff86000, 0x47bdc000, 0x5bb84c80, 0xc3400000, 0x58380004,
+ 0xcb420078, 0x00000000, 0x58380008, 0xcf400078, 0x5bfc0002, 0xb7e8ffb0, 0x00000000, 0xc3c00000,
+ 0xc2800004, 0xc3400022, 0xc3000000, 0x7f018000, 0xc2c00016, 0x6ff8a000, 0x47bdc000, 0x5bb84e20,
+ 0x58380008, 0xcf400038, 0xc00049a8, 0xcb0000f8, 0x00000000, 0x5838000a, 0xcf0000f8, 0xc321fffe,
+ 0x5b31fffe, 0x5838000c, 0xcf0000f8, 0x58380034, 0xcec00038, 0x5bfc0002, 0xb7e8ff78, 0x00000000,
+ 0x00000000, 0xc0004840, 0xc3e12624, 0x5bfc2320, 0xcfc000f9, 0xc3e02f2c, 0x5bfd2a28, 0xcfc000f9,
+ 0xc3e03734, 0x5bfd3230, 0xcfc000f9, 0xc3e13e3c, 0x5bfc3b38, 0xcfc000f9, 0xc3e14644, 0x5bfc4340,
+ 0xcfc000f9, 0xc3e04f4c, 0x5bfd4a48, 0xcfc000f9, 0xc3e05754, 0x5bfd5250, 0xcfc000f9, 0xc3e15e5c,
+ 0x5bfc5b58, 0xcfc000f9, 0xc3e06764, 0x5bfd6260, 0xcfc000f9, 0xc3e16e6c, 0x5bfc6b68, 0xcfc000f9,
+ 0xc3e17674, 0x5bfc7370, 0xcfc000f9, 0xc3e07f7c, 0x5bfd7a78, 0xcfc000f9, 0xc3e18684, 0x5bfc8380,
+ 0xcfc000f9, 0xc3e08f8c, 0x5bfd8a88, 0xcfc000f9, 0xc3e09794, 0x5bfd9290, 0xcfc000f9, 0xc3e19e9c,
+ 0x5bfc9b98, 0xcfc000f9, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xc1000000, 0xd91c00f8, 0xc3e01002, 0x5bfd88c0, 0xc3a00f88,
+ 0x5bb839a2, 0x990068d8, 0xdbd800f8, 0xdb9800f9, 0x00000000, 0xc3c00000, 0xdf7f0038, 0xa7ccfff0,
+ 0xc3800000, 0xc00048c0, 0xcb818078, 0xc0001408, 0xcfc000f8, 0xc10e0002, 0xd90c00f8, 0x5d3802a6,
+ 0xc1000002, 0xd91c1f02, 0xc121fffe, 0x5911fef4, 0x14100000, 0xa9fe0270, 0xc3c00000, 0xddfc00f0,
+ 0x5d3c0000, 0x84000100, 0xc0000c04, 0xcb8000f8, 0xc11c0002, 0x00000000, 0x7391c000, 0xcf8000f8,
+ 0xc3800000, 0xc3400080, 0xdf780038, 0xb7b4ffea, 0xc3203002, 0x5b3188c4, 0xc2e00f88, 0x5aec100e,
+ 0x990068d8, 0xdb1800f8, 0xdad800f9, 0x00000000, 0xc3800000, 0xc3400080, 0xdf780038, 0xb7b4ffea,
+ 0xc3205002, 0x5b3188c8, 0xc2e00f90, 0x5aec180c, 0x990068d8, 0xdb1800f8, 0xdad800f9, 0x00000000,
+ 0x80000128, 0xc00048cc, 0xca8000f8, 0x00000000, 0xc1000006, 0x76914000, 0x840000fa, 0x00000000,
+ 0xa6800070, 0xc3800000, 0xc3400080, 0xdf780038, 0xb7b4ffea, 0xc3202002, 0x5b31c8c6, 0xc2e00f88,
+ 0x5aec100e, 0x990068d8, 0xdb1800f8, 0xdad800f9, 0x00000000, 0xa6820068, 0xc3800000, 0xc3400080,
+ 0xdf780038, 0xb7b4ffea, 0xc3204002, 0x5b31c8ca, 0xc2e00f90, 0x5aec180c, 0x990068d8, 0xdb1800f8,
+ 0xdad800f9, 0x00000000, 0xc00048cc, 0xc2800000, 0xce8000f8, 0xc3a00140, 0x5bfc0002, 0x47bc8000,
+ 0xc1000000, 0xc53c00fe, 0xdbdc00f0, 0x80000028, 0x00000000, 0x800004e8, 0x00000000, 0x8000fd70,
+ 0xc0004918, 0xd28000f8, 0xc2000000, 0xdf600038, 0x5e600080, 0x840002b2, 0x00000000, 0xc161fffe,
+ 0x5955fffe, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc000480a, 0xca0000f8, 0xc0004912, 0xca4000f8, 0xc0004924, 0xca8000f8, 0xc000498c, 0xcac000f8,
+ 0xc121fffe, 0x5911fef4, 0x14100000, 0x76250000, 0x76290000, 0x762d0000, 0x840001ea, 0xc0004918,
+ 0xca4000f8, 0xc28001fe, 0x76290000, 0x5a640002, 0x6a254010, 0x5ee80000, 0x8400001a, 0x6aa54000,
+ 0x80000010, 0xc62800f8, 0x62818008, 0xc0004918, 0xcf0000f8, 0xc161fffe, 0x5955fffe, 0x14140000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc000498c, 0xca4000f8,
+ 0xc2000002, 0x6a310000, 0x7e010000, 0x76612000, 0xce4000f8, 0xc121fffe, 0x5911fef4, 0x14100000,
+ 0x6f346000, 0x4771a000, 0x5b744c80, 0xc2800000, 0x58340006, 0xca800078, 0xc2c00000, 0x58340000,
+ 0xcac000d8, 0xc2400000, 0x5834000a, 0xca420078, 0x6ea82000, 0x42e9e000, 0x6f2ca000, 0x42e56000,
+ 0x5aec1400, 0xc3990040, 0xc7381c18, 0xc6f80060, 0x990068d8, 0xdb9800f8, 0xdbd800f9, 0x00000000,
+ 0xdea000f8, 0x46310000, 0x8400fd40, 0xc000495a, 0xc84000f8, 0x00000000, 0xc3c00002, 0x787c2000,
+ 0xcc4000f8, 0xc0000838, 0xc3800000, 0xcb840028, 0x6c748000, 0x6c544000, 0x4355a000, 0x5b744a00,
+ 0x5ef80000, 0x8400fca2, 0x58340004, 0xcb0000f8, 0x00000000, 0x00000000, 0xa7060020, 0x00000000,
+ 0x5ef80002, 0x8400fc62, 0x5834000c, 0xc8800038, 0xc2000000, 0xc000082c, 0xca040028, 0x5a880002,
+ 0xc2400000, 0xc0004958, 0xce4000f8, 0xb6280018, 0x00000000, 0xc2800000, 0x58340002, 0xc2000000,
+ 0xca020008, 0xc0004956, 0xce8000f8, 0x5e600000, 0x84001ca2, 0x5e600002, 0x84004062, 0x00000000,
+ 0x800021d0, 0xc0004958, 0xca0000f8, 0xc0004956, 0xca8000f8, 0x5e200000, 0x84000020, 0xc2500002,
+ 0xc0000838, 0xce450800, 0x6c748000, 0x6c544000, 0x4355a000, 0x5b744a00, 0x5834000c, 0xc6900038,
+ 0xcd000038, 0x8000fb38, 0xc2000000, 0xdf600038, 0x5e200080, 0x8400028a, 0x00000000, 0xc161fffe,
+ 0x5955fffe, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc000480c, 0xca0000f8, 0xc0004910, 0xca4000f8, 0xc000492c, 0xca8000f8, 0xc000498e, 0xcac000f8,
+ 0xc121fffe, 0x5911fef4, 0x14100000, 0x76250000, 0x76290000, 0x76e16000, 0x840001c2, 0xc0004926,
+ 0xca4000f8, 0xc201fffe, 0x76e16000, 0x5a640002, 0x6ae50010, 0x5f200000, 0x8400001a, 0x6a250000,
+ 0x80000010, 0xc6e000f8, 0x62014008, 0xc0004926, 0xce8000f8, 0xc161fffe, 0x5955fffe, 0x14140000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc000498e, 0xca4000f8,
+ 0xc2000002, 0x6a290000, 0x7e010000, 0x76612000, 0xce4000f8, 0xc121fffe, 0x5911fef4, 0x14100000,
+ 0x6eb4a000, 0x4769a000, 0x5b744e20, 0x58340002, 0xc2000000, 0xca0000d8, 0x58340036, 0xc2400000,
+ 0xca400078, 0x6eb0a000, 0x47298000, 0x5b300e56, 0x5b300004, 0x6e642000, 0x4225e000, 0xc39a8024,
+ 0xc7380060, 0xc6b81c18, 0x990068d8, 0xdb9800f8, 0xdbd800f9, 0x00000000, 0xc2000000, 0xdf600038,
+ 0x5e200080, 0x840002da, 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc000490e, 0xca0000f8, 0xc000492a, 0xca4000f8,
+ 0xc0004990, 0xcb0000f8, 0xc000498a, 0xcac000f8, 0xc121fffe, 0x5911fef4, 0x14100000, 0x77218000,
+ 0x77258000, 0x8400021a, 0xc201fffe, 0x77218000, 0x5aec0002, 0x6b2d0010, 0x5ea00000, 0x8400001a,
+ 0x6a2d0000, 0x80000010, 0xc72000f8, 0x62016008, 0xc000498a, 0xcec000f8, 0xc161fffe, 0x5955fffe,
+ 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc0004990,
+ 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x7e010000, 0x76612000, 0xce4000f8, 0xc121fffe, 0x5911fef4,
+ 0x14100000, 0x6ef4a000, 0x476da000, 0x5b744e20, 0x58340010, 0xc2000000, 0xca0000d8, 0x58340008,
+ 0xc2400000, 0xca420078, 0x5834000e, 0xc2800000, 0xca832010, 0xc3c00000, 0x47e48000, 0x6e644010,
+ 0xc7e800fc, 0x42250000, 0x4229e000, 0xc39a8008, 0x58340008, 0xcb801038, 0x58340008, 0xc2800000,
+ 0xca810010, 0x6ee0a000, 0x462d0000, 0x5a20000a, 0x5a200e28, 0x42290000, 0xc6380060, 0xc6f81c18,
+ 0x990068d8, 0xdb9800f8, 0xdbd800f9, 0x00000000, 0xc000495c, 0xc84000f8, 0xc3400000, 0xc3c00002,
+ 0x787c2000, 0xcc4000f8, 0x6c78a000, 0x4785c000, 0x5bb84e20, 0x58380034, 0xcb410038, 0xc0000a28,
+ 0xc3000000, 0xcb040028, 0xc0000a14, 0xc2c00000, 0x43358000, 0xcac40028, 0xc000490e, 0xca8000f8,
+ 0x5eec0002, 0x472d8000, 0x8800f258, 0x6bc5e000, 0x76bd4000, 0x8400f240, 0x6c7ca000, 0x47c5e000,
+ 0x5bfc4e20, 0x583c0008, 0xc2000000, 0xca020078, 0xc00049aa, 0x00000000, 0xca8000f9, 0xca4000f8,
+ 0xc0001008, 0xce8000f8, 0xc0001006, 0xce4000f8, 0x583c000a, 0xca4000f8, 0x00000000, 0xc000100a,
+ 0xce4000f8, 0xc2400006, 0xc0001000, 0xce4000f8, 0xc2600982, 0x5a643b6e, 0xc0001002, 0xce4000f8,
+ 0x583c000c, 0xca4000f8, 0x00000000, 0xc0001004, 0xce4000f8, 0x583c000e, 0xcb8000f8, 0x00000000,
+ 0xc2400000, 0xc7a40078, 0xc2800000, 0xc7aae020, 0xdaa000f9, 0x583c0034, 0xcb8000f8, 0x00000000,
+ 0xc2c00000, 0xc7ad0038, 0xc0004978, 0xcec000f8, 0xc0800000, 0xc7880038, 0xc3400000, 0xc7b60038,
+ 0xc0004980, 0xcf4000f8, 0x4661c000, 0x43a9c000, 0xc2400000, 0xc000497c, 0xce4000f8, 0xad2c0001,
+ 0xc2800000, 0x00000000, 0x80000010, 0xc2800002, 0xc0004976, 0xce8000f8, 0xc2c00000, 0xc34000a0,
+ 0xdb5c00f9, 0xc3400002, 0xc000497a, 0xcf4000f8, 0x5f600000, 0x84000180, 0xde2800f9, 0xc6a000f8,
+ 0x47a9c000, 0x583c0000, 0xc2800000, 0xca830038, 0xc0000a28, 0xc3000000, 0xcb040028, 0xc3400000,
+ 0xc0004976, 0x46b18000, 0x8800006a, 0xcf4000f8, 0x58880002, 0xc3000000, 0xc0000a14, 0xcb040028,
+ 0x00000000, 0x00000000, 0xb4b001a8, 0x00000000, 0xc0800000, 0x00000000, 0x80000188, 0xc0004980,
+ 0xcb4000f8, 0x00000000, 0x00000000, 0x5af40002, 0xacec0080, 0x00000000, 0xc2c00000, 0xc000497a,
+ 0xadec0001, 0x00000000, 0x00000000, 0xad2c007f, 0xc2800000, 0xce8000f8, 0x80000018, 0xc2800002,
+ 0xce8000f8, 0x5f6c0000, 0x840000e8, 0x00000000, 0x8000ff00, 0x5f780082, 0x88000258, 0xc3000002,
+ 0xc000497c, 0xcf0000f8, 0xc2800080, 0xc1000000, 0xdd110038, 0x46914000, 0x47a94000, 0x880001d8,
+ 0x4391a000, 0xc0004980, 0xcf4000f8, 0x6f684010, 0x6f77c000, 0x6f77c010, 0xc0004840, 0x40280000,
+ 0xca8000f8, 0xc3000000, 0x6f506000, 0x6a908010, 0xc5300038, 0xdb1c00f9, 0x8000fe30, 0xc3400000,
+ 0xc0000a10, 0xcb440060, 0x6cb04000, 0x6f288000, 0x6f744000, 0x42b14000, 0x43694000, 0xc3400000,
+ 0xc6b44060, 0xc0004000, 0x40340000, 0xc321e000, 0xcf0000f8, 0x5aa80008, 0x42ad4000, 0xc3400000,
+ 0xc6b44060, 0xc0004000, 0x40340000, 0xca4000f8, 0xc3000000, 0xc6f00008, 0xc1400000, 0xddd40039,
+ 0x6f306000, 0xc13001fe, 0x69308010, 0x7d008000, 0x76512000, 0x6d570000, 0x6970a010, 0x42552000,
+ 0xce4000f8, 0x5aa80002, 0x5aec0002, 0xacec0080, 0x00000000, 0xc2c00000, 0x5f6c0000, 0x84000118,
+ 0x00000000, 0x80000040, 0x4391a000, 0x5f740080, 0xc0004980, 0xcf4000f8, 0xc3000004, 0xc000497a,
+ 0xcf0000f8, 0x58880002, 0xc3400000, 0xc0000a14, 0xcb440028, 0x00000000, 0x00000000, 0xb4b40018,
+ 0x00000000, 0xc0800000, 0xc3400000, 0xc0000a10, 0xcb440060, 0x6cb04000, 0x6f248000, 0x6f744000,
+ 0x42712000, 0x43654000, 0xc3400000, 0xc6b44060, 0xc0004000, 0x40340000, 0xc3201e00, 0xcf0000f8,
+ 0x5aa80008, 0x42ad4000, 0xc000100c, 0xcb4000f8, 0xc3000000, 0x00000000, 0xc7340060, 0xc300fffe,
+ 0xc7341070, 0xcf4000f8, 0xc000100e, 0xcb4000f8, 0xc3000e28, 0x00000000, 0xc7340060, 0xc300fffe,
+ 0xc7341070, 0xcf4000f8, 0xc0001010, 0xcb4000f8, 0xc3000002, 0x00000000, 0xc7341a00, 0xc7341800,
+ 0xc3000000, 0xc7341900, 0xc6b40070, 0xcf4000f8, 0xc0004982, 0xce8000f8, 0x6c64a000, 0x46452000,
+ 0x5a64000a, 0xc0001012, 0xcb4000f8, 0xc2800002, 0x00000000, 0xc6740260, 0xc6340008, 0xc000497c,
+ 0xcb0000f8, 0xc6b41800, 0xc6b41b00, 0xc6b41c00, 0xc6b41d00, 0xc7341e00, 0xdd6800f9, 0x7e814000,
+ 0x6eab2010, 0x76b14000, 0xc6b41f00, 0xc2800000, 0xc6b41900, 0xc3000080, 0x472d8000, 0xc0004982,
+ 0xc90000f8, 0x47394000, 0x88000102, 0x41388000, 0xcd0000f8, 0xc7b41038, 0xc0004994, 0xce8000f8,
+ 0xde1000f9, 0x45208000, 0x840000b0, 0xc1000000, 0xdd110038, 0x41388000, 0x412c8000, 0x5d100080,
+ 0xc0004980, 0xcd0000f8, 0xc1000002, 0xc000497c, 0xcd0000f8, 0xc5341e00, 0xdd5000f9, 0x7d008000,
+ 0xc5373f00, 0xc000497a, 0xc90000f8, 0x42390000, 0x43adc000, 0x59100002, 0xcd0000f8, 0x80000050,
+ 0x42390000, 0x80000040, 0xc7341038, 0x41308000, 0xcd0000f8, 0x42310000, 0xc1000000, 0xc0004994,
+ 0xcd0000f8, 0xc0001012, 0xcf4000f8, 0xc000493c, 0xce0000f8, 0xc0004984, 0xcf8000f8, 0xc000497a,
+ 0xca4000f8, 0xc000497c, 0xca8000f8, 0x6c7ca000, 0x47c5e000, 0x5bfc4e20, 0xc0004976, 0xcac000f8,
+ 0xc0004978, 0xca0000f8, 0x5eec0002, 0x8400008a, 0x42250000, 0xc2400000, 0xc000497a, 0xce4000f8,
+ 0x583c0000, 0xc2c00000, 0xcac30038, 0x00000000, 0x00000000, 0x46e16000, 0x8800001a, 0x00000000,
+ 0xad280002, 0xc000497a, 0xce0000f8, 0xc2000000, 0x5fa80000, 0x840001da, 0x00000000, 0x6c508000,
+ 0xc0004880, 0x40100000, 0x58000018, 0xc90000f8, 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8,
+ 0x583c000e, 0xc2c00000, 0xcac00078, 0xc1000000, 0xdd532201, 0x42d16000, 0x6c508000, 0xc0004880,
+ 0x40100000, 0x5800001a, 0xc90000f8, 0x00000000, 0x00000000, 0x412c8000, 0xcd0000f8, 0x99006968,
+ 0xd85800f8, 0xdbd800f9, 0x00000000, 0x990066b0, 0xc000491c, 0xc1400000, 0xc9420048, 0xc000491c,
+ 0x99006b68, 0xc94000f9, 0xc98000f8, 0x00000000, 0x990068d8, 0xd95800f8, 0xd99800f9, 0x00000000,
+ 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x98c06528, 0xd85800f8, 0xdbd800f9, 0xc45800f8, 0xc121fffe, 0x5911fef4, 0x14100000,
+ 0xade80003, 0xc000493c, 0xcb4000f8, 0x00000000, 0xc3000000, 0xc7701078, 0x80000010, 0xc3000000,
+ 0x583c0008, 0xcf021078, 0x6e210000, 0x583c0034, 0xce010838, 0xc0004980, 0xcb8000f8, 0x583c0034,
+ 0x00000000, 0x6fba0000, 0xcf821038, 0xc000490e, 0xca0000f8, 0xc2c00002, 0x6ac56000, 0x722d0000,
+ 0xce0000f8, 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8,
+ 0x5fa80000, 0x84000712, 0xc00049a8, 0xca0000f8, 0x583c000a, 0x00000000, 0xce0000f8, 0xc221fffe,
+ 0x5a21fffe, 0x583c000c, 0xce0000f8, 0xc0001004, 0xca0000f8, 0x00000000, 0x583c0012, 0x7e010000,
+ 0xce0000f8, 0xa97000e1, 0x00000000, 0x00000000, 0xa97200c9, 0xc0001010, 0xc2740000, 0xce435a00,
+ 0x6c64a000, 0x46452000, 0x5a64000a, 0x6e644000, 0xc0001012, 0xce400070, 0xc2600008, 0xce421038,
+ 0xc27e0002, 0xce43ff00, 0xc2760002, 0xce437b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8, 0xc1000000, 0xdd110038, 0x5d100000,
+ 0x84000412, 0xc0004982, 0xca0000f8, 0xc0004984, 0xca4000f8, 0xc2800000, 0xc361fffe, 0x5b75fffe,
+ 0xa96a001b, 0xdfec00f8, 0xc6ec1078, 0x7af56000, 0x6c40a000, 0x44040000, 0x58004e20, 0x58000014,
+ 0xcec000f8, 0xa972001b, 0x5c000002, 0xcec000f8, 0xc0001010, 0xc2f40002, 0xcec35a00, 0x6c6ca000,
+ 0x46c56000, 0x5aec000a, 0x6eec4000, 0xc0001012, 0xcec00070, 0xc0004994, 0xc98000f8, 0xc1400000,
+ 0xdd150038, 0xc55c00f8, 0x45948000, 0x00000000, 0xc59c00fc, 0x5d1c0000, 0x840000d2, 0xc0001012,
+ 0xc5d01038, 0xcd021038, 0xc2f60002, 0xcec37b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8, 0x45948000, 0x88000052, 0xc0004994,
+ 0xcd0000f8, 0xc0004980, 0xcbc000f8, 0x42150000, 0xc0004982, 0xce0000f8, 0x5ffc0000, 0x84000218,
+ 0x58880002, 0xc3800000, 0xc0000a14, 0xcb840028, 0xc3c00000, 0xc0000a10, 0xb4b80018, 0x00000000,
+ 0xc0800000, 0xcbc40060, 0x6cb84000, 0x6fac8000, 0x6ffc4000, 0x42f96000, 0x43ed0000, 0xc3400000,
+ 0xc6344060, 0xc0004000, 0x40340000, 0xc2a1e000, 0xce8000f8, 0x5a200008, 0xc0004980, 0xcbc000f8,
+ 0xc3400000, 0xc0004840, 0x6ff84010, 0xc7f40008, 0x40380000, 0xcb8000f8, 0xc2800000, 0x6f506000,
+ 0x6b908010, 0xc52c1838, 0xc3400000, 0xc6344060, 0xc0004000, 0x40340000, 0xcec000f8, 0x5a200002,
+ 0x5ffc0000, 0x84000092, 0xc0001010, 0xc62c0070, 0xcec00070, 0xc0001012, 0xc7ec1038, 0xcec21038,
+ 0xc2f60002, 0xcec37b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffe8,
+ 0x00000000, 0xc1220002, 0xd90c00f8, 0xc0004994, 0xc100007e, 0x453c8000, 0xcd0000f8, 0x423d0000,
+ 0xc0004982, 0xce0000f8, 0xc0004994, 0xca0000f8, 0xc0004980, 0xca4000f8, 0x5e200000, 0x8400015a,
+ 0xc2000000, 0xc2800000, 0x5a640002, 0xc6684028, 0xc0004982, 0xcb0000f8, 0xc0004000, 0xc2c00000,
+ 0xc72c4060, 0x402c0000, 0x6e67c000, 0x6e67c010, 0x5ee40002, 0x8400003a, 0x5ee40004, 0x8400004a,
+ 0x5ee40006, 0x8400005a, 0x00000000, 0x80000060, 0xce0000b8, 0x5aa80002, 0x5b300006, 0x80000040,
+ 0xce000078, 0x5aa80002, 0x5b300004, 0x80000020, 0xce000038, 0x5aa80002, 0x5b300002, 0x5ee80020,
+ 0x84000052, 0xc0004000, 0xc2c00000, 0xc72c4060, 0x402c0000, 0xce0000f8, 0x5aa80002, 0x5b300008,
+ 0x8000ffb8, 0x00000000, 0x80000040, 0x583c000a, 0xd7c000f8, 0xc0001004, 0xca4000f8, 0x00000000,
+ 0x583c000c, 0xce4000f8, 0xc000497a, 0xca4000f8, 0xc2800002, 0xc0000a28, 0xc6780928, 0xc6b80800,
+ 0xcf850830, 0x6c7ca000, 0x47c5e000, 0x5bfc4e20, 0x583c0034, 0xc4900038, 0xcd000038, 0x8000e418,
+ 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00, 0xc0000824, 0xca0400f8, 0x6ca48000, 0x42492000,
+ 0xc3000000, 0xc3400000, 0x42250000, 0x58204000, 0xca4000f8, 0x5a200002, 0xda2400f9, 0xc2800000,
+ 0xc000495e, 0xce8000f8, 0xda6000f8, 0xc2800000, 0xc66b0038, 0xdaa800f8, 0x582c0010, 0x6f206010,
+ 0x40200000, 0xd82800f9, 0xca0000f8, 0xc2400000, 0xc7240010, 0x6e644000, 0xda6400f8, 0x6a254010,
+ 0xc3c00000, 0xc6bc0018, 0xc3800000, 0xdea000f8, 0x5e60001e, 0x8400002a, 0x5e6001e0, 0x8400001a,
+ 0x00000000, 0x80000080, 0xc7f800f8, 0x5e7c0008, 0x8400006a, 0x5bbc0002, 0x5e780008, 0x84000028,
+ 0x5b740002, 0xc0004960, 0xcf0000f8, 0x80000030, 0x5e780006, 0x88000022, 0xc2800002, 0xc000495e,
+ 0xce8000f8, 0xde8000f9, 0xca8000f8, 0xde6000f8, 0xc240001e, 0x6a612000, 0x7e412000, 0x76a54000,
+ 0x6ba12000, 0x72a54000, 0xce8000f8, 0x5e300080, 0x840000ba, 0xc2000000, 0xc7200008, 0x5e600000,
+ 0x84000058, 0xde6000f9, 0x58204000, 0xca4000f8, 0x5a200002, 0xda2400f9, 0xc2800000, 0xc66b0038,
+ 0xdaa800f8, 0xda6000f8, 0x80000038, 0xc2800000, 0x6e206000, 0xde2400f8, 0x6a610000, 0xc62b0038,
+ 0xdaa800f8, 0x5b300002, 0x8000fde0, 0xc2000000, 0x582c0020, 0xca020078, 0x00000000, 0xc2400000,
+ 0x5a200002, 0xc6241078, 0xce421078, 0xc000480e, 0xca8000f8, 0x5e740000, 0x84000160, 0x46a12000,
+ 0x8800e048, 0xc2400000, 0xc0000808, 0xca440010, 0x582c0010, 0xc1400000, 0xcd4000f9, 0xcd4000f9,
+ 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd400018, 0x582c0020,
+ 0xce021078, 0xc2000010, 0x5a640002, 0xb6240018, 0x00000000, 0xc2400000, 0xc6600010, 0xc0000808,
+ 0xce040010, 0xc0004956, 0xca4000f8, 0xc11c0000, 0xc000082c, 0xcd05ce00, 0xc6600928, 0xc2400000,
+ 0xc6600028, 0xc0000838, 0xce0400f8, 0xc2400002, 0xc0004958, 0xce4000f8, 0xc11c0002, 0xc000082c,
+ 0xcd05ce00, 0x8000df00, 0xc000495e, 0xca0000f8, 0x5e740002, 0x8400dee0, 0x5e200000, 0x8400ded0,
+ 0xc0004960, 0xca4000f8, 0xc2200004, 0x582c0002, 0xce021008, 0xc2000082, 0x46250000, 0xc6280030,
+ 0xc0000810, 0xce840030, 0x99007000, 0x582c0002, 0xc94000f8, 0xc1a20000, 0x5e640000, 0x8400fed0,
+ 0x00000000, 0x8000de40, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00, 0xc000487c, 0xc80400f8,
+ 0x00000000, 0x00000000, 0x40080000, 0xcb8000f8, 0xc42400f8, 0x00000000, 0xa78601a0, 0xc3c00000,
+ 0xc2000000, 0x582c000c, 0xca010038, 0x6c508000, 0xc0004880, 0x40100000, 0x58000016, 0xc90000f8,
+ 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x5a200002, 0x582c000c, 0xc6100838, 0xcd010838,
+ 0x5e600002, 0x84000020, 0xc2200004, 0x582c0002, 0xce021008, 0x5e600008, 0x84000060, 0xc2200002,
+ 0x582c0002, 0xce021008, 0x582c000c, 0xcfc10838, 0xc2220002, 0xc0000a14, 0xce063100, 0xc22001a2,
+ 0xc0000a1c, 0xce061038, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00, 0x582c0004, 0xcb0000f8,
+ 0xc3400000, 0x00000000, 0xa7060028, 0xcf406300, 0xc3100002, 0xc0000838, 0xcf050800, 0x582c000c,
+ 0xcf421000, 0x8000dc40, 0x582c000c, 0xcfc10838, 0xc2000000, 0xc7a06010, 0x5e200000, 0x84001c08,
+ 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00, 0xc000487c, 0xc80400f8, 0x00000000, 0x00000000,
+ 0x40080000, 0xcb8000f8, 0xc42400f8, 0x00000000, 0xc2800000, 0xc3400000, 0xc7b5c030, 0xc0004970,
+ 0xcf4000f8, 0xc2400000, 0xc7a4e030, 0xc000496c, 0xce4000f8, 0xc3000000, 0xc7b00010, 0xc3c00004,
+ 0xc000496e, 0xcfc000f8, 0x582c000c, 0xca0000f8, 0xc2400002, 0xc0004964, 0xce4000f8, 0xa6200372,
+ 0x00000000, 0x5e700004, 0x840000ea, 0x5e700006, 0x84000080, 0xc2000002, 0x582c0002, 0xce000000,
+ 0xc0000a14, 0xce863100, 0x6c508000, 0xc0004880, 0x40100000, 0x58000014, 0xc90000f8, 0x00000000,
+ 0x00000000, 0x59100002, 0xcd0000f8, 0x80001a58, 0x5e70000a, 0x84000040, 0xc2000000, 0x582c0002,
+ 0xce000000, 0xc2220002, 0xc0000a14, 0xce063100, 0x8000ff70, 0x5e700008, 0x84000228, 0xc2200002,
+ 0x582c000c, 0xce021000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000012, 0xc90000f8, 0x00000000,
+ 0x00000000, 0x59100002, 0xcd0000f8, 0x5e340002, 0x6c508000, 0xc0004880, 0x40100000, 0x58000010,
+ 0xc90000f8, 0x00000000, 0x00000000, 0x41208000, 0xcd0000f8, 0xc0000a14, 0xce863100, 0xc0004970,
+ 0xcb4000f8, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00, 0x582c000e, 0xc4900038, 0xcd000038,
+ 0x582c000e, 0xc7500838, 0xcd010838, 0xc2800000, 0x582c0004, 0xce821078, 0x582c0004, 0xce800000,
+ 0xc00049a0, 0xca4000f8, 0x00000000, 0x582c0006, 0xce4000f8, 0xc261fffe, 0x5a65fffe, 0x582c0024,
+ 0xce4000f8, 0xc2060002, 0x582c0004, 0xce006300, 0xc2400002, 0xc0004958, 0xce4000f8, 0xc0004878,
+ 0xc80400f8, 0x6c908000, 0x41088000, 0x40100000, 0x58000020, 0xc90000f8, 0x582c0026, 0x00000000,
+ 0xcd0000f8, 0x800017e8, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000016, 0xc90000f8,
+ 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x8000faf0, 0x5e700000, 0x840000c0, 0xc3400082,
+ 0xc0004970, 0xcf4000f8, 0xc2400080, 0xc000496c, 0xce4000f8, 0xc3c00002, 0xc000496e, 0xcfc000f8,
+ 0xc2400000, 0xc0004964, 0xce4000f8, 0xc0004878, 0xc80400f8, 0x6c908000, 0x41088000, 0x40100000,
+ 0x58000020, 0xc90000f8, 0x582c0026, 0x00000000, 0xcd0000f8, 0x80000078, 0x5e700002, 0x84000058,
+ 0xc3400082, 0xc0004970, 0xcf4000f8, 0xc3c00004, 0xc000496e, 0xcfc000f8, 0xc2200000, 0x582c000c,
+ 0xce021000, 0x80000030, 0x5e700004, 0x8400fe80, 0xc2600002, 0x582c000c, 0xce421000, 0xc0000a14,
+ 0xce863100, 0xc000496c, 0xca4000f8, 0x6c508000, 0xc0004880, 0x40100000, 0x58000012, 0xc90000f8,
+ 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0xc000496e, 0xcbc000f8, 0x00000000, 0x00000000,
+ 0x477d0000, 0x46250000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000010, 0xc90000f8, 0x00000000,
+ 0x00000000, 0x41208000, 0xcd0000f8, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00, 0x582c0004,
+ 0xca0000f8, 0x00000000, 0x00000000, 0xa60014e2, 0x00000000, 0x6c6c8000, 0x6c544000, 0x42d56000,
+ 0x5aec4a00, 0xc3000000, 0x582c0004, 0xcf006300, 0x582c0000, 0xcb002010, 0xc3c00000, 0x582c0004,
+ 0xcbc20078, 0xc000491a, 0xcf0000f8, 0xc000493c, 0xcfc000f8, 0x582c0008, 0xcb8000f8, 0x582c000a,
+ 0xca4000f8, 0xc0004930, 0xcf8000f8, 0xc0004932, 0xce4000f8, 0x5ffc0000, 0x840001f0, 0x00000000,
+ 0xa7be0102, 0xc2800000, 0x6f206000, 0x46310000, 0x5a204c80, 0x5820000c, 0xca800020, 0x00000000,
+ 0x00000000, 0x5ea80000, 0x84000112, 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x990063c8, 0xc000491a, 0xc94000f8,
+ 0x00000000, 0xc121fffe, 0x5911fef4, 0x14100000, 0xc0004930, 0xcb8000f8, 0xc0004932, 0xca4000f8,
+ 0xc4781108, 0xc0004930, 0xcf8000f8, 0x582c0008, 0xcf8000f8, 0x582c000a, 0xce4000f8, 0xc7b6e108,
+ 0x582c0004, 0xcf402108, 0x80000090, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x5800000c,
+ 0xc90000f8, 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0xc2000002, 0x582c0004, 0xce000000,
+ 0xc0000838, 0xc2500002, 0xce450800, 0x80001220, 0x6c7c8000, 0x6c544000, 0x43d5e000, 0x5bfc4a00,
+ 0x583c0006, 0xca0000f8, 0xc00049a2, 0x00000000, 0xca8000f9, 0xca4000f8, 0xc0001008, 0xce8000f8,
+ 0xc0001006, 0xce4000f8, 0xc000100a, 0xce0000f8, 0xc2400006, 0xc0001000, 0xce4000f8, 0xc2600982,
+ 0x5a643b6e, 0xc0001002, 0xce4000f8, 0x583c0024, 0xca4000f8, 0x00000000, 0xc0001004, 0xce4000f8,
+ 0xc0004862, 0xc2000000, 0xca000078, 0xc360fffe, 0xc0004862, 0xce0000f8, 0xc0000824, 0xcb440060,
+ 0x00000000, 0xc000100e, 0xcf4000f8, 0xc3801600, 0xc2400200, 0x6e644000, 0xc6781070, 0xc000100c,
+ 0xcf8000f8, 0xc3200a00, 0xc0001010, 0xcf031810, 0xc2e06200, 0xc0001012, 0xcec31838, 0xc2000000,
+ 0x583c0004, 0xca002008, 0xc2800000, 0xc0004966, 0xce0000f8, 0xc62400f8, 0xc3000000, 0xc000496a,
+ 0xcf0000f8, 0xc0004974, 0xcf0000f8, 0xc000493c, 0xcb4000f8, 0x583c000e, 0x00000000, 0x5f740000,
+ 0x84000180, 0xc3400000, 0xcb410038, 0xc3000002, 0xc000496a, 0x5fb40080, 0x84000152, 0xcf0000f8,
+ 0x583c000e, 0xc2c00000, 0xcac00038, 0xc3800080, 0x47b5c000, 0xc0004974, 0xcf8000f8, 0xc0001012,
+ 0x6fba0000, 0xcf821038, 0x6fba0010, 0x43a5c000, 0x5b380006, 0x6f284010, 0xc7a40008, 0x6eec4000,
+ 0x6ef08000, 0x432d8000, 0x43358000, 0x5b300008, 0xc0001012, 0xc7100070, 0xcd000070, 0xc2000200,
+ 0xc2c00000, 0xdf6d0048, 0x462d6000, 0x46e96000, 0x8800ffe2, 0xc2000000, 0xc0004862, 0xca000260,
+ 0x00000000, 0x583c0004, 0xca002008, 0xc3360002, 0xc0001010, 0xce000070, 0xc0001012, 0xcf037b00,
+ 0xc0004974, 0xcb8000f8, 0x00000000, 0x00000000, 0x5fb80000, 0x84000042, 0x00000000, 0x00000000,
+ 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8, 0xc000496c, 0xcac000f8, 0x00000000,
+ 0x00000000, 0x426dc000, 0x5b380006, 0x6f304010, 0xc7a40008, 0xc0004968, 0xce4000f8, 0xc000496e,
+ 0xcb4000f8, 0x6ca44000, 0x6e608000, 0x42250000, 0x5a200006, 0x42350000, 0xc0001012, 0xc6100070,
+ 0xcd000070, 0x6eee0000, 0xcec21038, 0xc2000200, 0xc2c00000, 0xdf6d0048, 0x462d6000, 0x42b14000,
+ 0x46e96000, 0x8800ffda, 0xc000493c, 0xcb4000f8, 0xc0000838, 0xc3100002, 0x5f740000, 0x84000060,
+ 0xcf050800, 0xc0004974, 0xcb8000f8, 0x00000000, 0x00000000, 0x5fb80000, 0x8400006a, 0xc0001012,
+ 0xc3360002, 0xcf037b00, 0x800000a0, 0x583c0022, 0xcb4000f8, 0xc0004862, 0xca0000f8, 0x00000000,
+ 0xc0005600, 0x40200000, 0xcf4000f8, 0xc2000000, 0xc0004862, 0xca000260, 0x00000000, 0x583c0004,
+ 0xca002008, 0xc3360002, 0xc0001010, 0xce000070, 0xc0001012, 0xcf037b00, 0xc0004968, 0xcbc000f8,
+ 0xc0004964, 0xca4000f8, 0xc7e000f8, 0x00000000, 0x5e640000, 0x84000012, 0xc2000000, 0xc0004974,
+ 0xca4000f8, 0xc000496c, 0xca8000f8, 0xc000493c, 0xcb8000f8, 0x42698000, 0x00000000, 0x43b1a000,
+ 0x5ef40080, 0x8800019a, 0xc0004966, 0xcac000f8, 0x6c648000, 0x6c544000, 0x42552000, 0x5a644a00,
+ 0x58240000, 0x436da000, 0x4761a000, 0xc2400000, 0xca420078, 0x00000000, 0x00000000, 0x46752000,
+ 0x88000122, 0x432d8000, 0x47218000, 0x88000010, 0xc3000000, 0x5b300006, 0x6f304010, 0xc000493a,
+ 0xcf0000f8, 0xc0004932, 0xc2400000, 0xca4000d8, 0x00000000, 0x6fb84010, 0x42792000, 0xc000491e,
+ 0xce4000f8, 0xc0004862, 0xca8000f8, 0x00000000, 0xc2c0000a, 0xc6e80d70, 0xc7281048, 0xc000491c,
+ 0xce8000f8, 0x6c708000, 0x6c544000, 0x43158000, 0x5b304a00, 0x6f760000, 0x58300004, 0xcf421078,
+ 0x6ffc2000, 0x58300004, 0xcfc02108, 0x800000d0, 0x6c708000, 0x6c544000, 0x43158000, 0x5b304a00,
+ 0xc2800002, 0x58300004, 0xce800000, 0x6c508000, 0xc0004880, 0x40100000, 0x5800000e, 0xc90000f8,
+ 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffe8,
+ 0x00000000, 0xc1220002, 0xd90c00f8, 0x80000920, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8, 0xc0004964, 0xca0000f8, 0x6c7c8000, 0x6c544000,
+ 0x43d5e000, 0x5bfc4a00, 0xdfe400f8, 0x5e200002, 0x84000608, 0x00000000, 0x583c0004, 0xc2800000,
+ 0xca820078, 0xc0004930, 0xcac000f8, 0x00000000, 0x00000000, 0x6eece000, 0x6eefc010, 0x46aca000,
+ 0xc1000000, 0xdd500039, 0x6d106010, 0x4550a000, 0xc1000000, 0xdd514201, 0x4550c000, 0xa95000f1,
+ 0xc00049a6, 0xca0000f8, 0xa94a0023, 0x00000000, 0x6e660000, 0x6e660010, 0x46612000, 0x840000b2,
+ 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000004, 0xc90000f8, 0x00000000, 0x00000000,
+ 0x59100002, 0xcd0000f8, 0x6c508000, 0xc0004880, 0x40100000, 0x58000006, 0xc90000f8, 0x00000000,
+ 0x00000000, 0x41148000, 0xcd0000f8, 0x80000720, 0x00000000, 0xa95203c1, 0xc0001004, 0xcb8000f8,
+ 0xc3400000, 0xdd740039, 0x5f740000, 0x840000d0, 0xc1218e08, 0x5911baf6, 0x45388000, 0x84000372,
+ 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000008, 0xc90000f8, 0x00000000, 0x00000000,
+ 0x59100002, 0xcd0000f8, 0x6c508000, 0xc0004880, 0x40100000, 0x5800000a, 0xc90000f8, 0x00000000,
+ 0x00000000, 0x41148000, 0xcd0000f8, 0x80000620, 0x00000000, 0xc000496c, 0xcb0000f8, 0x583c0026,
+ 0xcac000f8, 0xc0004878, 0xc80400f8, 0x6c908000, 0x41088000, 0x40100000, 0x58000002, 0xca8000f8,
+ 0x00000000, 0x00000000, 0x6ea90000, 0x5d300008, 0x8800004a, 0x59300002, 0xc3000000, 0xc5300008,
+ 0x6d104010, 0x40100000, 0xca8000f8, 0x5c000002, 0xcac000f8, 0x5d300000, 0x8400003a, 0x6f246000,
+ 0x6ae56000, 0xc1000040, 0x45252000, 0x6aa54010, 0x42e96000, 0x583c0026, 0xcec000f8, 0xc1218e08,
+ 0x5911baf6, 0xc0001004, 0xcd0000f8, 0x593c0026, 0xc000100e, 0xcd000060, 0xc1340000, 0xc0001010,
+ 0xcd035a00, 0xc1200008, 0xa94a0023, 0xc0001012, 0xc1200004, 0x59100004, 0xcd0000b8, 0xc1360002,
+ 0xcd037b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffe8, 0x00000000,
+ 0xc1220002, 0xd90c00f8, 0xc0001004, 0xc90000f8, 0x00000000, 0x00000000, 0x45388000, 0x840000b2,
+ 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000008, 0xc90000f8, 0x00000000, 0x00000000,
+ 0x59100002, 0xcd0000f8, 0x6c508000, 0xc0004880, 0x40100000, 0x5800000a, 0xc90000f8, 0x00000000,
+ 0x00000000, 0x41148000, 0xcd0000f8, 0x80000360, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000,
+ 0x58000000, 0xc90000f8, 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x6c508000, 0xc0004880,
+ 0x40100000, 0x58000002, 0xc90000f8, 0x00000000, 0x00000000, 0x41148000, 0xcd0000f8, 0xc0004930,
+ 0xcd800078, 0xc3000000, 0x583c0008, 0xcf0000f8, 0x80000038, 0xc0001004, 0xca0000f8, 0x583c0006,
+ 0xce4000f8, 0x583c0024, 0xce0000f8, 0xc0004862, 0xc2000000, 0xca000078, 0xc000493a, 0xca4000f8,
+ 0x00000000, 0x00000000, 0x42254000, 0x5ee80200, 0x88000012, 0xc6e800f8, 0xc0004000, 0x58001600,
+ 0x40280000, 0xcb8000f8, 0x00000000, 0x583c0022, 0xcf8000f8, 0xc0004862, 0xce800078, 0xc0001406,
+ 0xcac000f8, 0xc2800002, 0x00000000, 0xc66c1048, 0xc6ac0a00, 0xcec000f8, 0xc2000000, 0xdf600038,
+ 0x5e600080, 0x8400ffea, 0xc000491c, 0xca4000f8, 0xc000491e, 0xca8000f8, 0x990068d8, 0xda5800f8,
+ 0xda9800f9, 0x00000000, 0xc0004964, 0xcbc000f8, 0x00000000, 0x00000000, 0x5ffc0000, 0x84000102,
+ 0xc2000000, 0xdf610048, 0x5e6001fe, 0x8800ffe8, 0xc000491a, 0xc98000f8, 0xc0004862, 0xc94000f8,
+ 0x6d9c6000, 0x45d8e000, 0x59dc4c80, 0x99006738, 0xd95800f8, 0xd99800f9, 0xd9d400f8, 0x990066b0,
+ 0xc000491c, 0xc1400000, 0xc9420048, 0xc2000000, 0xdf600038, 0x5e600080, 0x8400ffea, 0xc000491c,
+ 0xca4000f8, 0xc000491e, 0xca8000f8, 0x990068d8, 0xda5800f8, 0xda9800f9, 0x00000000, 0xc0004970,
+ 0xcb4000f8, 0x00000000, 0x00000000, 0x5e740082, 0x8400e6d8, 0x00000000, 0x8000c018, 0x00000000,
+ 0x6c508000, 0xc0004880, 0x40100000, 0x58000016, 0xc90000f8, 0x00000000, 0x00000000, 0x59100002,
+ 0xcd0000f8, 0x8000e308, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00, 0xc000487c, 0xc80400f8,
+ 0x00000000, 0x00000000, 0x40080000, 0xca0000f8, 0xc42400f8, 0x00000000, 0xa60600f8, 0xc3c00000,
+ 0xc2000000, 0x582c000c, 0xca010038, 0x00000000, 0x00000000, 0x5a200002, 0xc6100838, 0xcd010838,
+ 0x5e60000e, 0x8400bf00, 0xc2200000, 0x582c0002, 0xce021008, 0x582c000c, 0xcfc10838, 0x582c0020,
+ 0xcfc21078, 0x582c0010, 0xc1400000, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9,
+ 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd400018, 0x8000be68, 0xc2200004, 0x582c0002, 0xce021008,
+ 0x582c000c, 0xcfc10838, 0x99007000, 0x582c0002, 0xc94000f8, 0xc1a20000, 0x8000be18, 0xc3e1fffe,
+ 0x597dfffe, 0x593dfef4, 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0xc0800000, 0xdf4b0038,
+ 0xc0004900, 0xcb8000f8, 0xc2000000, 0xc000490a, 0xa78000d0, 0xcbc000f8, 0xc1000000, 0xd90000f9,
+ 0xc1000002, 0xd90c00f8, 0x6ff46000, 0x477da000, 0x5b744c80, 0xc2400000, 0x58340004, 0xca400078,
+ 0xc0004900, 0xce000000, 0x5a640002, 0x58340004, 0xc6500078, 0xcd000078, 0xc0004914, 0xca4000f8,
+ 0xc2000002, 0x6a3d0000, 0x72612000, 0xce4000f8, 0xc0000408, 0xce0000f8, 0xa78200c8, 0xc0004908,
+ 0xcbc000f8, 0xc1000000, 0xd90000f9, 0xc1000002, 0xd90c00f8, 0x6ff4a000, 0x477da000, 0x5b744e20,
+ 0xc2800000, 0x58340006, 0xca800078, 0xc2000000, 0xc0004900, 0xce002100, 0x5ea80002, 0x58340006,
+ 0xc6900078, 0xcd000078, 0x5a7c0020, 0xc2000002, 0x6a250000, 0xc0000408, 0xce0000f8, 0xdca800f9,
+ 0x5ea80000, 0x8400a860, 0x00000000, 0xa4800230, 0x00000000, 0xc3c00000, 0xc000140e, 0xcbc00018,
+ 0xc3400000, 0xc2400000, 0x6ff86000, 0x47bdc000, 0x5bb84c80, 0x58380008, 0xcb400078, 0x58380006,
+ 0xca400078, 0x5f740002, 0x58380008, 0xc7500078, 0xcd000078, 0xc2000000, 0x58380004, 0xca020078,
+ 0xc3000000, 0x5838000c, 0xcb000020, 0x5a640002, 0x46610000, 0x84000010, 0xc2400000, 0x58380006,
+ 0xc6500078, 0xcd000078, 0xc2000000, 0x5838000a, 0xca020078, 0x5b300002, 0x5838000c, 0xc7100020,
+ 0xcd000020, 0xc2420020, 0x5a200004, 0x46252000, 0x84000010, 0xc2000000, 0x5838000a, 0xc6101078,
+ 0xcd021078, 0xc000498c, 0xca4000f8, 0xc2000002, 0x6a3d0000, 0x72612000, 0xce4000f8, 0x5f740000,
+ 0x84000040, 0xc0004912, 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x7ec16000, 0x762d0000, 0xce0000f8,
+ 0x5f300020, 0x84000040, 0xc0004924, 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x7ec16000, 0x762d0000,
+ 0xce0000f8, 0xa4820070, 0xc2400000, 0xc000140e, 0xca408018, 0xc2000002, 0xc0004900, 0xce000000,
+ 0xc000490a, 0xce4000f8, 0xc1000000, 0xd90000f9, 0xd8400078, 0xc1000004, 0xd90000f9, 0xa48402d8,
+ 0x00000000, 0xc3c00000, 0xc000140e, 0xcbc10018, 0xc2800000, 0xc2000000, 0x6ff8a000, 0x47bdc000,
+ 0x5bb84e20, 0x58380036, 0xca800078, 0x58380006, 0xca020078, 0xc3400000, 0x58380036, 0xcb420078,
+ 0x5aa80002, 0x46a10000, 0x84000010, 0xc2800000, 0x58380036, 0xc6900078, 0xcd000078, 0x5f740002,
+ 0x58380036, 0xc7501078, 0xcd021078, 0xc000498e, 0xca4000f8, 0xc2000002, 0x6a3d0000, 0x72612000,
+ 0xce4000f8, 0xc000492a, 0xca8000f8, 0x5e740000, 0x84000040, 0xc0004910, 0xca0000f8, 0xc2c00002,
+ 0x6afd6000, 0x7ec16000, 0x762d0000, 0xce0000f8, 0x6abd4010, 0xa6800132, 0x00000000, 0x5838003a,
+ 0xca0000f8, 0x58000002, 0xca4000f8, 0x5838000e, 0x00000000, 0xce0000f9, 0xce4000f8, 0xc2400000,
+ 0xdd250038, 0xc1000080, 0x45248000, 0xc2400000, 0xc6240078, 0x46510000, 0x00000000, 0xc52400fc,
+ 0x5d240078, 0xc1000078, 0xc52400fc, 0xc6600078, 0x5c000002, 0xce000078, 0xc000492a, 0xca0000f8,
+ 0xc2c00002, 0x6afd6000, 0x722d0000, 0xce0000f8, 0xc000492c, 0xca0000f8, 0xc2c00002, 0x6afd6000,
+ 0x722d0000, 0xce0000f8, 0x80000040, 0xc000492c, 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x7ec16000,
+ 0x762d0000, 0xce0000f8, 0xa4880088, 0xc2c00000, 0xc000140e, 0xcac20018, 0xc000490e, 0xca4000f8,
+ 0xc2000002, 0x6a2d0000, 0x7e010000, 0x76612000, 0xce4000f8, 0xc0004990, 0xca4000f8, 0xc2000002,
+ 0x6a2d0000, 0x72612000, 0xce4000f8, 0xa4860070, 0xc2400000, 0xc000140e, 0xca418018, 0xc2020002,
+ 0xc0004900, 0xce002100, 0xc0004908, 0xce4000f8, 0xc1000000, 0xd90000f9, 0xd8400078, 0xc1000004,
+ 0xd90000f9, 0xa48c00e8, 0xc2400000, 0xc000140e, 0xca430018, 0x00000000, 0x00000000, 0x5d240002,
+ 0x84000058, 0xc00048c4, 0xca0000f8, 0xc00048c6, 0xc1040002, 0x72110000, 0xce0000f8, 0xc1000002,
+ 0xc00048cc, 0xcd000000, 0x80000060, 0x5d240004, 0x84000050, 0xc00048c8, 0xca0000f8, 0xc00048ca,
+ 0xc1160002, 0x72110000, 0xce0000f8, 0xc1020002, 0xc00048cc, 0xcd002100, 0xc0001408, 0xcc8000f8,
+ 0xc10e0002, 0xd90c00f8, 0x8000f668, 0xdfbc00f9, 0xc0004992, 0x99007040, 0xc94000f8, 0xc7d800f8,
+ 0x00000000, 0xc57000f8, 0x5ef00020, 0x88000158, 0x6f346000, 0x4771a000, 0x5b744c80, 0x58340008,
+ 0xc2400000, 0xca400078, 0x00000000, 0xc2000000, 0x5a640002, 0xc6500078, 0xcd000078, 0x58340004,
+ 0xca000078, 0x00000000, 0x00000000, 0x5e200002, 0xc6100078, 0xcd000078, 0xc0004912, 0xca8000f8,
+ 0xc2400002, 0x6a712000, 0x72a54000, 0xce8000f8, 0x5e200000, 0x84000052, 0xc000480a, 0xca0000f8,
+ 0xc0000408, 0xca8000f8, 0x76250000, 0x00000000, 0x72a14000, 0xce8000f8, 0x80000038, 0xc0004914,
+ 0xca0000f8, 0x7e412000, 0x00000000, 0x76250000, 0xce0000f8, 0x800000c8, 0x6ef4a000, 0x476da000,
+ 0x5b744e20, 0x58340036, 0xc2400000, 0xca420078, 0x00000000, 0xc2000000, 0x5a640002, 0xc6501078,
+ 0xcd021078, 0x58340006, 0xca000078, 0x00000000, 0x00000000, 0x5a200002, 0xc6100078, 0xcd000078,
+ 0xc0004910, 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x72612000, 0xce4000f8, 0xc2000002, 0x6a310000,
+ 0xc000042a, 0xce0000f8, 0xc1040002, 0xd90c00f8, 0x00000000, 0x8000f3d0, 0x00000000, 0xc4980928,
+ 0x9d000000, 0xc5580028, 0xc0000838, 0xcd8400f8, 0xc1440200, 0xc1c01600, 0xc55c1070, 0xc000100e,
+ 0x9d000000, 0xcd8000f8, 0xc000100c, 0xcdc000f8, 0xc0004862, 0xc9c000f8, 0x00000000, 0x00000000,
+ 0xd9d800f9, 0xc0005600, 0x401c0000, 0x5dc05800, 0x88000012, 0x5c000200, 0xcd8000f8, 0xc1f0000a,
+ 0x715ca000, 0xdd9800f8, 0xdd9c00f9, 0x41d8e000, 0xc5d40260, 0xc0001010, 0xcd4000f8, 0x6c9c8000,
+ 0x45c8e000, 0x45c8e000, 0x59dc0004, 0xc1601260, 0xc5d40260, 0x9d000000, 0xc0001012, 0xcd4000f8,
+ 0x00000000, 0x00000000, 0xd95800f8, 0x6d586000, 0x4594c000, 0x59984c80, 0xd99800f9, 0x5818000a,
+ 0xc1800000, 0xc9800078, 0xc0005400, 0x6d5ca000, 0x401c0000, 0x40180000, 0xc94000f8, 0x58000002,
+ 0x00000000, 0xc9c000f8, 0xc0004930, 0xcd4000f8, 0xc0004932, 0xcdc000f8, 0x59980004, 0xc1c20020,
+ 0xb59c0018, 0x00000000, 0xc1800000, 0xdd9c00f9, 0x581c000a, 0xcd800078, 0x581c000c, 0xc1800000,
+ 0xc9800020, 0xc1c00002, 0xdd9400f8, 0x69d4e000, 0x5d980002, 0xcd800020, 0xc0004924, 0xc98000f8,
+ 0x00000000, 0x9d000000, 0x00000000, 0x719cc000, 0xcd8000f8, 0xc000492a, 0xc94000f8, 0xc1c00002,
+ 0x69d8e000, 0x7dc0c000, 0x7558a000, 0xcd4000f8, 0xc000492c, 0xc94000f8, 0xdd8000f9, 0x5800003a,
+ 0x755ca000, 0x84000108, 0xc94000f9, 0xc98000f8, 0xdd8000f9, 0x5800000e, 0x00000000, 0xcd4000f9,
+ 0xcd8000f8, 0xc1800000, 0xdd190038, 0xc1000080, 0x45188000, 0xc1800000, 0xc5580078, 0x4590a000,
+ 0x00000000, 0xc51800fc, 0x5d180078, 0xc1000078, 0xc51800fc, 0xc5940078, 0x5c000002, 0xcd400078,
+ 0xc000492c, 0xc94000f8, 0xc000492a, 0xc98000f8, 0x715ca000, 0xc000492c, 0xcd4000f8, 0x719cc000,
+ 0xc000492a, 0xcd8000f8, 0x9cc00000, 0x00000000, 0x00000000, 0x00000000, 0xc0004862, 0xc98000f8,
+ 0x00000000, 0xc1c00200, 0x4194c000, 0x459ce000, 0x88000012, 0xc5d800f8, 0xc0004862, 0xcd8000f8,
+ 0xc0001406, 0xc98000f8, 0xc1c00002, 0x9d000000, 0xc5d80a00, 0xc5581048, 0xcd8000f8, 0xc0004930,
+ 0xc98000f8, 0xc0004932, 0xc9c000f8, 0xc140000e, 0xc5581c18, 0xdd9400f8, 0xc0005600, 0x40140000,
+ 0x5d405800, 0x88000012, 0x5c000200, 0xcd8000f8, 0x58000002, 0x5d405800, 0x88000012, 0x5c000200,
+ 0xcdc000f8, 0xdd5400f8, 0xc1c00000, 0x58140006, 0xc9c20078, 0xc1800000, 0x58140000, 0xc98000d8,
+ 0x6ddc2000, 0xc000491e, 0x41d8e000, 0xcdc000f8, 0xdd9800f8, 0xc1c00022, 0xc5d80d70, 0xdd9400f9,
+ 0xc5581c18, 0xc000491c, 0xcd8000f8, 0xdd5400f8, 0xc1c00000, 0x58140006, 0xc9c20078, 0xc1800000,
+ 0x58140004, 0xc9820078, 0x00000000, 0x59dc0002, 0x45d8c000, 0x84000010, 0xc1c00000, 0x9d000000,
+ 0x58140006, 0xc5d81078, 0xcd821078, 0xc0004860, 0xc94000f8, 0xc1820080, 0xc1d00002, 0x58146b00,
+ 0xd58000f8, 0x58000002, 0xd58000f9, 0x59540004, 0xb5580018, 0xc0004860, 0xc1400000, 0xcd4000f8,
+ 0xdd9800f9, 0x9d000000, 0xdd9400f8, 0xc0001404, 0xcdc10800, 0xc1c00000, 0xc1800200, 0x5d980004,
+ 0xdf5d0048, 0x459ca000, 0x8800fff2, 0xdd8000f9, 0x5800000e, 0x00000000, 0xc94000f9, 0xc98000f8,
+ 0xc1c00002, 0xc5d43f00, 0xc5d81e00, 0xc0004862, 0xc9c000f8, 0x00000000, 0x00000000, 0x581c5600,
+ 0x5dc05800, 0x88000012, 0x5c000200, 0xcd4000f8, 0x58000002, 0x5dc05800, 0x88000012, 0x5c000200,
+ 0xcd8000f8, 0xc0004862, 0xc9c000f8, 0x00000000, 0xc15004c0, 0xc5d40060, 0xdd9c00f8, 0xc5d41c18,
+ 0xc1c00000, 0xdd8000f9, 0x58000038, 0xc9c00078, 0xdd8000f9, 0xc1800000, 0x58000002, 0xc98000d8,
+ 0x6ddc2000, 0xc000491c, 0x41d8e000, 0xcd4000f9, 0xcdc000f8, 0xdd9400f9, 0xc1c00000, 0x58140038,
+ 0xc9c00078, 0xc1800000, 0x58140006, 0xc9820078, 0x00000000, 0x59dc0002, 0x45d8c000, 0x84000010,
+ 0xc1c00000, 0x9d000000, 0x58140038, 0xc5d80078, 0xcd800078, 0xc1c00000, 0xdf5c0038, 0x5ddc0080,
+ 0x8400ffea, 0x00000000, 0x9d000000, 0x00000000, 0x00000000, 0x00000000, 0xc160fffe, 0xc0000a10,
+ 0xc9440060, 0xc1a0fffe, 0x59980e28, 0xc000100c, 0xcd4000f8, 0xc000100e, 0xcd8000f8, 0xc0004962,
+ 0xc98000f8, 0x00000000, 0xc170000a, 0x7158a000, 0x6c988000, 0x4588c000, 0x4588c000, 0x59980004,
+ 0xc5940270, 0xc0001010, 0xcd4000f8, 0xc0004946, 0xc94000f8, 0x00000000, 0x00000000, 0x6d58a000,
+ 0x6d5c4000, 0x459cc000, 0x4594c000, 0xc000494a, 0xc94000f8, 0xc0004948, 0xc9c000f8, 0x4194c000,
+ 0xc1400012, 0xc55c1818, 0x9d000000, 0xc59c0268, 0xc0001012, 0xcdc000f8, 0xc1400000, 0x58000014,
+ 0xc9410038, 0xc0004950, 0xc9c000f8, 0xc55800f8, 0xc5940838, 0xc5581078, 0xd99400f8, 0xc000493c,
+ 0xc94000f8, 0xc0004954, 0xc98000f8, 0x59dc00a8, 0x45d4e000, 0x41d8e000, 0x5d5c0030, 0x88000010,
+ 0xc1c00030, 0xc1800000, 0xc5d84028, 0xc1400000, 0xc5d40008, 0x5dd40002, 0x84000072, 0x5dd40004,
+ 0x8400009a, 0x5dd40006, 0x840000c2, 0x5dd80026, 0x840000ea, 0xdd5400f8, 0xdd8000f9, 0x58000008,
+ 0x40180000, 0xcd4000f8, 0x59980002, 0x8000ffc0, 0xdd5400f8, 0xdd8000f9, 0x58000008, 0x40180000,
+ 0xcd4000b8, 0x59980002, 0x8000ff88, 0xdd5400f8, 0xdd8000f9, 0x58000008, 0x40180000, 0xcd400078,
+ 0x59980002, 0x8000ff50, 0xdd5400f8, 0xdd8000f9, 0x58000008, 0x40180000, 0xcd400038, 0x59980002,
+ 0x8000ff18, 0x00000000, 0x9d000000, 0x00000000, 0x00000000, 0x00000000, 0x58000014, 0xc94000f8,
+ 0xc0004954, 0xc9c000f8, 0xc0004950, 0xc9400078, 0xdd8000f9, 0x5800002a, 0x5d9c0000, 0x84000052,
+ 0x5d9c0002, 0x84000052, 0x5d9c0004, 0x8400006a, 0xc55b0038, 0xc55c08b8, 0xcd800039, 0xcdc108b8,
+ 0x80000060, 0xcd4000f8, 0x80000050, 0xc55900b8, 0xc55c1838, 0xcd8000b9, 0xcdc31838, 0x80000028,
+ 0xc55a0078, 0xc55c1078, 0xcd800079, 0xcdc21078, 0x9d000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc1e00000, 0xa540001a, 0xc0000a14, 0xc1a20002, 0x9d000000, 0xcd863100, 0xc0000a1c, 0xcdc61038,
+ 0x59540002, 0x6994e018, 0x61c0c008, 0x4194a000, 0x5d940040, 0x88000012, 0xc59400f8, 0x9d000000,
+ 0xcd4000f8, 0x00000000, 0x00000000,
+};
+
+static unsigned int firmware_binary_data[] = {
+};
+
+
+#endif // IFXMIPS_PTM_FW_AMAZON_SE_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_ar9.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_ar9.h
new file mode 100644
index 0000000000..a61d313852
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_ar9.h
@@ -0,0 +1,473 @@
+#ifndef IFXMIPS_PTM_FW_AR9_H
+#define IFXMIPS_PTM_FW_AR9_H
+
+
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_fw_ar9.h
+** PROJECT : UEIP
+** MODULES : PTM (ADSL)
+**
+** DATE : 22 OCT 2007
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM Driver (PP32 Firmware)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 22 OCT 2007 Xu Liang Initiate Version, v00.01
+*******************************************************************************/
+
+
+#define PTM_FW_VER_MAJOR 0
+#define PTM_FW_VER_MINOR 17
+
+
+static unsigned int firmware_binary_code[] = {
+ 0x800004b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000ffe0, 0x00000000, 0x00000000, 0x00000000,
+ 0xc1000002, 0xd90c00f8, 0xc2000002, 0xda0800f9, 0x80005270, 0xc2000000, 0xda0800f9, 0x80005210,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80005a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc10e0002, 0xd90c00f8, 0xc0004808, 0xc84000f8, 0x80004ee0, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc3e1fffe, 0x597dfffe, 0x593dfef4, 0x900004d9, 0x00000000, 0x00000000, 0x00000000, 0x90cc0481,
+ 0x00000000, 0x00000000, 0x00000000, 0xc3e0a262, 0x5bfc0022, 0xc0004002, 0xcfc000f8, 0xc0004810,
+ 0xcbc000f8, 0x00000000, 0xc3800000, 0xc7f80038, 0x5fb80000, 0xc7fa0038, 0xc7bfe802, 0x5fb80000,
+ 0x00000000, 0xc7bff802, 0xdbd400f9, 0xc00049a0, 0xc3800002, 0xa7ca006a, 0xc1200000, 0x5911fffe,
+ 0xcd0000f9, 0xc1200000, 0x59102042, 0xcd0000f9, 0xc1000004, 0xcd0000f9, 0xc1200000, 0x59103a1e,
+ 0xcd0000f9, 0x80000060, 0xc121fffe, 0x5911fffe, 0xcd0000f9, 0xc1203db8, 0x5910de82, 0xcd0000f9,
+ 0xc1000006, 0xcd0000f9, 0xc120385a, 0x591033da, 0xcd0000f9, 0x5fb80002, 0x8800001a, 0x6ffe0010,
+ 0x8000ff28, 0xdd7c00f9, 0xc3800000, 0xc7f86010, 0x5bb80008, 0xc3540002, 0x777da000, 0xc1000008,
+ 0x4791c002, 0xcf8000f9, 0xdb900038, 0xc3800008, 0xc3720002, 0x777da000, 0xa7f00028, 0x47b9c002,
+ 0xc1000000, 0xc7d26010, 0x4391c000, 0xcf8000f8, 0xdb900838, 0xc3c00000, 0xdbc800f9, 0xc0400000,
+ 0xc11c0000, 0xc000082c, 0xcd05ce00, 0xc11c0002, 0xc000082c, 0xcd05ce00, 0xc0400002, 0xc11c0000,
+ 0xc000082c, 0xcd05ce00, 0xc11c0002, 0xc000082c, 0xcd05ce00, 0xc0000824, 0x00000000, 0xcbc000f9,
+ 0xcb8000f9, 0xcb4000f9, 0xcb0000f8, 0xc0004878, 0x5bfc4000, 0xcfc000f9, 0x5bb84000, 0xcf8000f9,
+ 0x5b744000, 0xcf4000f9, 0x5b304000, 0xcf0000f8, 0xc0000a10, 0x00000000, 0xcbc000f9, 0xcb8000f8,
+ 0xc0004874, 0x5bfc4000, 0xcfc000f9, 0x5bb84000, 0xcf8000f8, 0xc30001fe, 0xc000140a, 0xcf0000f8,
+ 0xc3000000, 0x7f018000, 0xc000042e, 0xcf0000f8, 0xc000040e, 0xcf0000f8, 0xc3c1fffe, 0xc000490e,
+ 0xcfc00078, 0xc000492c, 0xcfc00078, 0xc0004924, 0xcfc00038, 0xc0004912, 0xcfc00038, 0xc000498c,
+ 0xcfc00038, 0xc000498e, 0xcfc00078, 0xc0004990, 0xcfc00078, 0xc3c00000, 0xc2800004, 0xc3000000,
+ 0x7f018000, 0x6ff88000, 0x6fd44000, 0x4395c000, 0x5bb87e00, 0xc00049a0, 0xcb0000f8, 0x00000000,
+ 0x58380006, 0xcf0000f8, 0xc321fffe, 0x5b31fffe, 0x58380024, 0xcf0000f8, 0x5bfc0002, 0xb7e8ff90,
+ 0x00000000, 0xc3c00000, 0xc2800010, 0x6ff86000, 0x47bdc000, 0x5bb84c80, 0xc3400000, 0x58380004,
+ 0xcb420078, 0x00000000, 0x58380008, 0xcf400078, 0x5bfc0002, 0xb7e8ffb0, 0x00000000, 0xc3c00000,
+ 0xc2800004, 0xc3400022, 0xc3000000, 0x7f018000, 0xc2c00016, 0x6ff8a000, 0x47bdc000, 0x5bb87600,
+ 0x58380008, 0xcf400038, 0xc00049a8, 0xcb0000f8, 0x00000000, 0x5838000a, 0xcf0000f8, 0xc321fffe,
+ 0x5b31fffe, 0x5838000c, 0xcf0000f8, 0x58380034, 0xcec00038, 0x5bfc0002, 0xb7e8ff78, 0x00000000,
+ 0x00000000, 0xc0004840, 0xc3e12624, 0x5bfc2320, 0xcfc000f9, 0xc3e02f2c, 0x5bfd2a28, 0xcfc000f9,
+ 0xc3e03734, 0x5bfd3230, 0xcfc000f9, 0xc3e13e3c, 0x5bfc3b38, 0xcfc000f9, 0xc3e14644, 0x5bfc4340,
+ 0xcfc000f9, 0xc3e04f4c, 0x5bfd4a48, 0xcfc000f9, 0xc3e05754, 0x5bfd5250, 0xcfc000f9, 0xc3e15e5c,
+ 0x5bfc5b58, 0xcfc000f9, 0xc3e06764, 0x5bfd6260, 0xcfc000f9, 0xc3e16e6c, 0x5bfc6b68, 0xcfc000f9,
+ 0xc3e17674, 0x5bfc7370, 0xcfc000f9, 0xc3e07f7c, 0x5bfd7a78, 0xcfc000f9, 0xc3e18684, 0x5bfc8380,
+ 0xcfc000f9, 0xc3e08f8c, 0x5bfd8a88, 0xcfc000f9, 0xc3e09794, 0x5bfd9290, 0xcfc000f9, 0xc3e19e9c,
+ 0x5bfc9b98, 0xcfc000f9, 0xc121fffe, 0x5911fef4, 0x14100000, 0x80000028, 0x00000000, 0x800004e8,
+ 0x00000000, 0x8000ffe0, 0xc0004918, 0xd28000f8, 0xc2000000, 0xdf600038, 0x5e600080, 0x840002b2,
+ 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xc000480a, 0xca0000f8, 0xc0004912, 0xca4000f8, 0xc0004924, 0xca8000f8,
+ 0xc000498c, 0xcac000f8, 0xc121fffe, 0x5911fef4, 0x14100000, 0x76250000, 0x76290000, 0x762d0000,
+ 0x840001ea, 0xc0004918, 0xca4000f8, 0xc28001fe, 0x76290000, 0x5a640002, 0x6a254010, 0x5ee80000,
+ 0x8400001a, 0x6aa54000, 0x80000010, 0xc62800f8, 0x62818008, 0xc0004918, 0xcf0000f8, 0xc161fffe,
+ 0x5955fffe, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc000498c, 0xca4000f8, 0xc2000002, 0x6a310000, 0x7e010000, 0x76612000, 0xce4000f8, 0xc121fffe,
+ 0x5911fef4, 0x14100000, 0x6f346000, 0x4771a000, 0x5b744c80, 0xc2800000, 0x58340006, 0xca800078,
+ 0xc2c00000, 0x58340000, 0xcac000d8, 0xc2400000, 0x5834000a, 0xca420078, 0x6ea82000, 0x42e9e000,
+ 0x6f2ca000, 0x42e56000, 0x5aec3680, 0xc3990040, 0xc7381c18, 0xc6f80060, 0x99006480, 0xdb9800f8,
+ 0xdbd800f9, 0x00000000, 0xdea000f8, 0x46310000, 0x8400fd40, 0xc000495a, 0xc84000f8, 0x00000000,
+ 0xc3c00002, 0x787c2000, 0xcc4000f8, 0xc0000838, 0xc3800000, 0xcb840028, 0x6c748000, 0x6c544000,
+ 0x4355a000, 0x5b747e00, 0x5ef80000, 0x8400fca2, 0x58340004, 0xcb0000f8, 0x00000000, 0x00000000,
+ 0xa7060020, 0x00000000, 0x5ef80002, 0x8400fc62, 0x5834000c, 0xc8800038, 0xc2000000, 0xc000082c,
+ 0xca040028, 0x5a880002, 0xc2400000, 0xc0004958, 0xce4000f8, 0xb6280018, 0x00000000, 0xc2800000,
+ 0x58340002, 0xc2000000, 0xca020008, 0xc0004956, 0xce8000f8, 0x5e600000, 0x84001ca2, 0x5e600002,
+ 0x84004062, 0x00000000, 0x800021d0, 0xc0004958, 0xca0000f8, 0xc0004956, 0xca8000f8, 0x5e200000,
+ 0x84000020, 0xc2500002, 0xc0000838, 0xce450800, 0x6c748000, 0x6c544000, 0x4355a000, 0x5b747e00,
+ 0x5834000c, 0xc6900038, 0xcd000038, 0x8000fb38, 0xc2000000, 0xdf600038, 0x5e200080, 0x8400028a,
+ 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xc000480c, 0xca0000f8, 0xc0004910, 0xca4000f8, 0xc000492c, 0xca8000f8,
+ 0xc000498e, 0xcac000f8, 0xc121fffe, 0x5911fef4, 0x14100000, 0x76250000, 0x76290000, 0x76e16000,
+ 0x840001c2, 0xc0004926, 0xca4000f8, 0xc201fffe, 0x76e16000, 0x5a640002, 0x6ae50010, 0x5f200000,
+ 0x8400001a, 0x6a250000, 0x80000010, 0xc6e000f8, 0x62014008, 0xc0004926, 0xce8000f8, 0xc161fffe,
+ 0x5955fffe, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc000498e, 0xca4000f8, 0xc2000002, 0x6a290000, 0x7e010000, 0x76612000, 0xce4000f8, 0xc121fffe,
+ 0x5911fef4, 0x14100000, 0x6eb4a000, 0x4769a000, 0x5b747600, 0x58340002, 0xc2000000, 0xca0000d8,
+ 0x58340036, 0xc2400000, 0xca400078, 0x6eb0a000, 0x47298000, 0x5b303636, 0x5b300004, 0x6e642000,
+ 0x4225e000, 0xc39a8024, 0xc7380060, 0xc6b81c18, 0x99006480, 0xdb9800f8, 0xdbd800f9, 0x00000000,
+ 0xc2000000, 0xdf600038, 0x5e200080, 0x840002da, 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc000490e, 0xca0000f8,
+ 0xc000492a, 0xca4000f8, 0xc0004990, 0xcb0000f8, 0xc000498a, 0xcac000f8, 0xc121fffe, 0x5911fef4,
+ 0x14100000, 0x77218000, 0x77258000, 0x8400021a, 0xc201fffe, 0x77218000, 0x5aec0002, 0x6b2d0010,
+ 0x5ea00000, 0x8400001a, 0x6a2d0000, 0x80000010, 0xc72000f8, 0x62016008, 0xc000498a, 0xcec000f8,
+ 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xc0004990, 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x7e010000, 0x76612000, 0xce4000f8,
+ 0xc121fffe, 0x5911fef4, 0x14100000, 0x6ef4a000, 0x476da000, 0x5b747600, 0x58340010, 0xc2000000,
+ 0xca0000d8, 0x58340008, 0xc2400000, 0xca420078, 0x5834000e, 0xc2800000, 0xca832010, 0xc3c00000,
+ 0x47e48000, 0x6e644010, 0xc7e800fc, 0x42250000, 0x4229e000, 0xc39a8008, 0x58340008, 0xcb801038,
+ 0x58340008, 0xc2800000, 0xca810010, 0x6ee0a000, 0x462d0000, 0x5a20000a, 0x5a203608, 0x42290000,
+ 0xc6380060, 0xc6f81c18, 0x99006480, 0xdb9800f8, 0xdbd800f9, 0x00000000, 0xc000495c, 0xc84000f8,
+ 0xc3400000, 0xc3c00002, 0x787c2000, 0xcc4000f8, 0x6c78a000, 0x4785c000, 0x5bb87600, 0x58380034,
+ 0xcb410038, 0xc0000a28, 0xc3000000, 0xcb040028, 0xc0000a14, 0xc2c00000, 0x43358000, 0xcac40028,
+ 0xc000490e, 0xca8000f8, 0x5eec0002, 0x472d8000, 0x8800f4c8, 0x6bc5e000, 0x76bd4000, 0x8400f4b0,
+ 0x6c7ca000, 0x47c5e000, 0x5bfc7600, 0x583c0008, 0xc2000000, 0xca020078, 0xc00049aa, 0x00000000,
+ 0xca8000f9, 0xca4000f8, 0xc0001008, 0xce8000f8, 0xc0001006, 0xce4000f8, 0x583c000a, 0xca4000f8,
+ 0x00000000, 0xc000100a, 0xce4000f8, 0xc2400006, 0xc0001000, 0xce4000f8, 0xc2600982, 0x5a643b6e,
+ 0xc0001002, 0xce4000f8, 0x583c000c, 0xca4000f8, 0x00000000, 0xc0001004, 0xce4000f8, 0x583c000e,
+ 0xcb8000f8, 0x00000000, 0xc2400000, 0xc7a40078, 0xc2800000, 0xc7aae020, 0xdaa000f9, 0x583c0034,
+ 0xcb8000f8, 0x00000000, 0xc2c00000, 0xc7ad0038, 0xc0004978, 0xcec000f8, 0xc0800000, 0xc7880038,
+ 0xc3400000, 0xc7b60038, 0xc0004980, 0xcf4000f8, 0x4661c000, 0x43a9c000, 0xc2400000, 0xc000497c,
+ 0xce4000f8, 0xad2c0001, 0xc2800000, 0x00000000, 0x80000010, 0xc2800002, 0xc0004976, 0xce8000f8,
+ 0xc2c00000, 0xc34000a0, 0xdb5c00f9, 0xc3400002, 0xc000497a, 0xcf4000f8, 0x5f600000, 0x84000180,
+ 0xde2800f9, 0xc6a000f8, 0x47a9c000, 0x583c0000, 0xc2800000, 0xca830038, 0xc0000a28, 0xc3000000,
+ 0xcb040028, 0xc3400000, 0xc0004976, 0x46b18000, 0x8800006a, 0xcf4000f8, 0x58880002, 0xc3000000,
+ 0xc0000a14, 0xcb040028, 0x00000000, 0x00000000, 0xb4b001a8, 0x00000000, 0xc0800000, 0x00000000,
+ 0x80000188, 0xc0004980, 0xcb4000f8, 0x00000000, 0x00000000, 0x5af40002, 0xacec0080, 0x00000000,
+ 0xc2c00000, 0xc000497a, 0xadec0001, 0x00000000, 0x00000000, 0xad2c007f, 0xc2800000, 0xce8000f8,
+ 0x80000018, 0xc2800002, 0xce8000f8, 0x5f6c0000, 0x840000e8, 0x00000000, 0x8000ff00, 0x5f780082,
+ 0x88000258, 0xc3000002, 0xc000497c, 0xcf0000f8, 0xc2800080, 0xc1000000, 0xdd110038, 0x46914000,
+ 0x47a94000, 0x880001d8, 0x4391a000, 0xc0004980, 0xcf4000f8, 0x6f684010, 0x6f77c000, 0x6f77c010,
+ 0xc0004840, 0x40280000, 0xca8000f8, 0xc3000000, 0x6f506000, 0x6a908010, 0xc5300038, 0xdb1c00f9,
+ 0x8000fe30, 0xc3400000, 0xc0000a10, 0xcb440060, 0x6cb04000, 0x6f288000, 0x6f744000, 0x42b14000,
+ 0x43694000, 0xc3400000, 0xc6b44060, 0xc0004000, 0x40340000, 0xc321e000, 0xcf0000f8, 0x5aa80008,
+ 0x42ad4000, 0xc3400000, 0xc6b44060, 0xc0004000, 0x40340000, 0xca4000f8, 0xc3000000, 0xc6f00008,
+ 0xc1400000, 0xddd40039, 0x6f306000, 0xc13001fe, 0x69308010, 0x7d008000, 0x76512000, 0x6d570000,
+ 0x6970a010, 0x42552000, 0xce4000f8, 0x5aa80002, 0x5aec0002, 0xacec0080, 0x00000000, 0xc2c00000,
+ 0x5f6c0000, 0x84000118, 0x00000000, 0x80000040, 0x4391a000, 0x5f740080, 0xc0004980, 0xcf4000f8,
+ 0xc3000004, 0xc000497a, 0xcf0000f8, 0x58880002, 0xc3400000, 0xc0000a14, 0xcb440028, 0x00000000,
+ 0x00000000, 0xb4b40018, 0x00000000, 0xc0800000, 0xc3400000, 0xc0000a10, 0xcb440060, 0x6cb04000,
+ 0x6f248000, 0x6f744000, 0x42712000, 0x43654000, 0xc3400000, 0xc6b44060, 0xc0004000, 0x40340000,
+ 0xc3201e00, 0xcf0000f8, 0x5aa80008, 0x42ad4000, 0xc000100c, 0xcb4000f8, 0xc3000000, 0x00000000,
+ 0xc7340060, 0xc300fffe, 0xc7341070, 0xcf4000f8, 0xc000100e, 0xcb4000f8, 0xc3003608, 0x00000000,
+ 0xc7340060, 0xc300fffe, 0xc7341070, 0xcf4000f8, 0xc0001010, 0xcb4000f8, 0xc3000002, 0x00000000,
+ 0xc7341a00, 0xc7341800, 0xc3000000, 0xc7341900, 0xc6b40070, 0xcf4000f8, 0xc0004982, 0xce8000f8,
+ 0x6c64a000, 0x46452000, 0x5a64000a, 0xc0001012, 0xcb4000f8, 0xc2800002, 0x00000000, 0xc6740260,
+ 0xc6340008, 0xc000497c, 0xcb0000f8, 0xc6b41800, 0xc6b41b00, 0xc6b41c00, 0xc6b41d00, 0xc7341e00,
+ 0xdd6800f9, 0x7e814000, 0x6eab2010, 0x76b14000, 0xc6b41f00, 0xc2800000, 0xc6b41900, 0xc3000080,
+ 0x472d8000, 0xc0004982, 0xc90000f8, 0x47394000, 0x88000102, 0x41388000, 0xcd0000f8, 0xc7b41038,
+ 0xc0004994, 0xce8000f8, 0xde1000f9, 0x45208000, 0x840000b0, 0xc1000000, 0xdd110038, 0x41388000,
+ 0x412c8000, 0x5d100080, 0xc0004980, 0xcd0000f8, 0xc1000002, 0xc000497c, 0xcd0000f8, 0xc5341e00,
+ 0xdd5000f9, 0x7d008000, 0xc5373f00, 0xc000497a, 0xc90000f8, 0x42390000, 0x43adc000, 0x59100002,
+ 0xcd0000f8, 0x80000050, 0x42390000, 0x80000040, 0xc7341038, 0x41308000, 0xcd0000f8, 0x42310000,
+ 0xc1000000, 0xc0004994, 0xcd0000f8, 0xc0001012, 0xcf4000f8, 0xc000493c, 0xce0000f8, 0xc0004984,
+ 0xcf8000f8, 0xc000497a, 0xca4000f8, 0xc000497c, 0xca8000f8, 0x6c7ca000, 0x47c5e000, 0x5bfc7600,
+ 0xc0004976, 0xcac000f8, 0xc0004978, 0xca0000f8, 0x5eec0002, 0x8400008a, 0x42250000, 0xc2400000,
+ 0xc000497a, 0xce4000f8, 0x583c0000, 0xc2c00000, 0xcac30038, 0x00000000, 0x00000000, 0x46e16000,
+ 0x8800001a, 0x00000000, 0xad280002, 0xc000497a, 0xce0000f8, 0xc2000000, 0x5fa80000, 0x840001da,
+ 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000018, 0xc90000f8, 0x00000000, 0x00000000,
+ 0x59100002, 0xcd0000f8, 0x583c000e, 0xc2c00000, 0xcac00078, 0xc1000000, 0xdd532201, 0x42d16000,
+ 0x6c508000, 0xc0004880, 0x40100000, 0x5800001a, 0xc90000f8, 0x00000000, 0x00000000, 0x412c8000,
+ 0xcd0000f8, 0x99006510, 0xd85800f8, 0xdbd800f9, 0x00000000, 0x99006258, 0xc000491c, 0xc1400000,
+ 0xc9420048, 0xc000491c, 0x99006710, 0xc94000f9, 0xc98000f8, 0x00000000, 0x99006480, 0xd95800f8,
+ 0xd99800f9, 0x00000000, 0xc161fffe, 0x5955fffe, 0x14140000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x98c060d0, 0xd85800f8, 0xdbd800f9, 0xc45800f8, 0xc121fffe,
+ 0x5911fef4, 0x14100000, 0xade80003, 0xc000493c, 0xcb4000f8, 0x00000000, 0xc3000000, 0xc7701078,
+ 0x80000010, 0xc3000000, 0x583c0008, 0xcf021078, 0x6e210000, 0x583c0034, 0xce010838, 0xc0004980,
+ 0xcb8000f8, 0x583c0034, 0x00000000, 0x6fba0000, 0xcf821038, 0xc000490e, 0xca0000f8, 0xc2c00002,
+ 0x6ac56000, 0x722d0000, 0xce0000f8, 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffe8, 0x00000000,
+ 0xc1220002, 0xd90c00f8, 0x5fa80000, 0x84000712, 0xc00049a8, 0xca0000f8, 0x583c000a, 0x00000000,
+ 0xce0000f8, 0xc221fffe, 0x5a21fffe, 0x583c000c, 0xce0000f8, 0xc0001004, 0xca0000f8, 0x00000000,
+ 0x583c0012, 0x7e010000, 0xce0000f8, 0xa97000e1, 0x00000000, 0x00000000, 0xa97200c9, 0xc0001010,
+ 0xc2740000, 0xce435a00, 0x6c64a000, 0x46452000, 0x5a64000a, 0x6e644000, 0xc0001012, 0xce400070,
+ 0xc2600008, 0xce421038, 0xc27e0002, 0xce43ff00, 0xc2760002, 0xce437b00, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8, 0xc1000000,
+ 0xdd110038, 0x5d100000, 0x84000412, 0xc0004982, 0xca0000f8, 0xc0004984, 0xca4000f8, 0xc2800000,
+ 0xc361fffe, 0x5b75fffe, 0xa96a001b, 0xdfec00f8, 0xc6ec1078, 0x7af56000, 0x6c40a000, 0x44040000,
+ 0x58007600, 0x58000014, 0xcec000f8, 0xa972001b, 0x5c000002, 0xcec000f8, 0xc0001010, 0xc2f40002,
+ 0xcec35a00, 0x6c6ca000, 0x46c56000, 0x5aec000a, 0x6eec4000, 0xc0001012, 0xcec00070, 0xc0004994,
+ 0xc98000f8, 0xc1400000, 0xdd150038, 0xc55c00f8, 0x45948000, 0x00000000, 0xc59c00fc, 0x5d1c0000,
+ 0x840000d2, 0xc0001012, 0xc5d01038, 0xcd021038, 0xc2f60002, 0xcec37b00, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8, 0x45948000,
+ 0x88000052, 0xc0004994, 0xcd0000f8, 0xc0004980, 0xcbc000f8, 0x42150000, 0xc0004982, 0xce0000f8,
+ 0x5ffc0000, 0x84000218, 0x58880002, 0xc3800000, 0xc0000a14, 0xcb840028, 0xc3c00000, 0xc0000a10,
+ 0xb4b80018, 0x00000000, 0xc0800000, 0xcbc40060, 0x6cb84000, 0x6fac8000, 0x6ffc4000, 0x42f96000,
+ 0x43ed0000, 0xc3400000, 0xc6344060, 0xc0004000, 0x40340000, 0xc2a1e000, 0xce8000f8, 0x5a200008,
+ 0xc0004980, 0xcbc000f8, 0xc3400000, 0xc0004840, 0x6ff84010, 0xc7f40008, 0x40380000, 0xcb8000f8,
+ 0xc2800000, 0x6f506000, 0x6b908010, 0xc52c1838, 0xc3400000, 0xc6344060, 0xc0004000, 0x40340000,
+ 0xcec000f8, 0x5a200002, 0x5ffc0000, 0x84000092, 0xc0001010, 0xc62c0070, 0xcec00070, 0xc0001012,
+ 0xc7ec1038, 0xcec21038, 0xc2f60002, 0xcec37b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8, 0xc0004994, 0xc100007e, 0x453c8000,
+ 0xcd0000f8, 0x423d0000, 0xc0004982, 0xce0000f8, 0xc0004994, 0xca0000f8, 0xc0004980, 0xca4000f8,
+ 0x5e200000, 0x8400015a, 0xc2000000, 0xc2800000, 0x5a640002, 0xc6684028, 0xc0004982, 0xcb0000f8,
+ 0xc0004000, 0xc2c00000, 0xc72c4060, 0x402c0000, 0x6e67c000, 0x6e67c010, 0x5ee40002, 0x8400003a,
+ 0x5ee40004, 0x8400004a, 0x5ee40006, 0x8400005a, 0x00000000, 0x80000060, 0xce0000b8, 0x5aa80002,
+ 0x5b300006, 0x80000040, 0xce000078, 0x5aa80002, 0x5b300004, 0x80000020, 0xce000038, 0x5aa80002,
+ 0x5b300002, 0x5ee80020, 0x84000052, 0xc0004000, 0xc2c00000, 0xc72c4060, 0x402c0000, 0xce0000f8,
+ 0x5aa80002, 0x5b300008, 0x8000ffb8, 0x00000000, 0x80000040, 0x583c000a, 0xd7c000f8, 0xc0001004,
+ 0xca4000f8, 0x00000000, 0x583c000c, 0xce4000f8, 0xc000497a, 0xca4000f8, 0xc2800002, 0xc0000a28,
+ 0xc6780928, 0xc6b80800, 0xcf850830, 0x6c7ca000, 0x47c5e000, 0x5bfc7600, 0x583c0034, 0xc4900038,
+ 0xcd000038, 0x8000e418, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec7e00, 0xc0000824, 0xca0400f8,
+ 0x6ca48000, 0x42492000, 0xc3000000, 0xc3400000, 0x42250000, 0x58204000, 0xca4000f8, 0x5a200002,
+ 0xda2400f9, 0xc2800000, 0xc000495e, 0xce8000f8, 0xda6000f8, 0xc2800000, 0xc66b0038, 0xdaa800f8,
+ 0x582c0010, 0x6f206010, 0x40200000, 0xd82800f9, 0xca0000f8, 0xc2400000, 0xc7240010, 0x6e644000,
+ 0xda6400f8, 0x6a254010, 0xc3c00000, 0xc6bc0018, 0xc3800000, 0xdea000f8, 0x5e60001e, 0x8400002a,
+ 0x5e6001e0, 0x8400001a, 0x00000000, 0x80000080, 0xc7f800f8, 0x5e7c0008, 0x8400006a, 0x5bbc0002,
+ 0x5e780008, 0x84000028, 0x5b740002, 0xc0004960, 0xcf0000f8, 0x80000030, 0x5e780006, 0x88000022,
+ 0xc2800002, 0xc000495e, 0xce8000f8, 0xde8000f9, 0xca8000f8, 0xde6000f8, 0xc240001e, 0x6a612000,
+ 0x7e412000, 0x76a54000, 0x6ba12000, 0x72a54000, 0xce8000f8, 0x5e300080, 0x840000ba, 0xc2000000,
+ 0xc7200008, 0x5e600000, 0x84000058, 0xde6000f9, 0x58204000, 0xca4000f8, 0x5a200002, 0xda2400f9,
+ 0xc2800000, 0xc66b0038, 0xdaa800f8, 0xda6000f8, 0x80000038, 0xc2800000, 0x6e206000, 0xde2400f8,
+ 0x6a610000, 0xc62b0038, 0xdaa800f8, 0x5b300002, 0x8000fde0, 0xc2000000, 0x582c0020, 0xca020078,
+ 0x00000000, 0xc2400000, 0x5a200002, 0xc6241078, 0xce421078, 0xc000480e, 0xca8000f8, 0x5e740000,
+ 0x84000160, 0x46a12000, 0x8800e048, 0xc2400000, 0xc0000808, 0xca440010, 0x582c0010, 0xc1400000,
+ 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9,
+ 0xcd400018, 0x582c0020, 0xce021078, 0xc2000010, 0x5a640002, 0xb6240018, 0x00000000, 0xc2400000,
+ 0xc6600010, 0xc0000808, 0xce040010, 0xc0004956, 0xca4000f8, 0xc11c0000, 0xc000082c, 0xcd05ce00,
+ 0xc6600928, 0xc2400000, 0xc6600028, 0xc0000838, 0xce0400f8, 0xc2400002, 0xc0004958, 0xce4000f8,
+ 0xc11c0002, 0xc000082c, 0xcd05ce00, 0x8000df00, 0xc000495e, 0xca0000f8, 0x5e740002, 0x8400dee0,
+ 0x5e200000, 0x8400ded0, 0xc0004960, 0xca4000f8, 0xc2200004, 0x582c0002, 0xce021008, 0xc2000082,
+ 0x46250000, 0xc6280030, 0xc0000810, 0xce840030, 0x99006ba8, 0x582c0002, 0xc94000f8, 0xc1a20000,
+ 0x5e640000, 0x8400fed0, 0x00000000, 0x8000de40, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec7e00,
+ 0xc000487c, 0xc80400f8, 0x00000000, 0x00000000, 0x40080000, 0xcb8000f8, 0xc42400f8, 0x00000000,
+ 0xa78601a0, 0xc3c00000, 0xc2000000, 0x582c000c, 0xca010038, 0x6c508000, 0xc0004880, 0x40100000,
+ 0x58000016, 0xc90000f8, 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x5a200002, 0x582c000c,
+ 0xc6100838, 0xcd010838, 0x5e600002, 0x84000020, 0xc2200004, 0x582c0002, 0xce021008, 0x5e600008,
+ 0x84000060, 0xc2200002, 0x582c0002, 0xce021008, 0x582c000c, 0xcfc10838, 0xc2220002, 0xc0000a14,
+ 0xce063100, 0xc22001a2, 0xc0000a1c, 0xce061038, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec7e00,
+ 0x582c0004, 0xcb0000f8, 0xc3400000, 0x00000000, 0xa7060028, 0xcf406300, 0xc3100002, 0xc0000838,
+ 0xcf050800, 0x582c000c, 0xcf421000, 0x8000dc40, 0x582c000c, 0xcfc10838, 0xc2000000, 0xc7a06010,
+ 0x5e200000, 0x84001c08, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec7e00, 0xc000487c, 0xc80400f8,
+ 0x00000000, 0x00000000, 0x40080000, 0xcb8000f8, 0xc42400f8, 0x00000000, 0xc2800000, 0xc3400000,
+ 0xc7b5c030, 0xc0004970, 0xcf4000f8, 0xc2400000, 0xc7a4e030, 0xc000496c, 0xce4000f8, 0xc3000000,
+ 0xc7b00010, 0xc3c00004, 0xc000496e, 0xcfc000f8, 0x582c000c, 0xca0000f8, 0xc2400002, 0xc0004964,
+ 0xce4000f8, 0xa6200372, 0x00000000, 0x5e700004, 0x840000ea, 0x5e700006, 0x84000080, 0xc2000002,
+ 0x582c0002, 0xce000000, 0xc0000a14, 0xce863100, 0x6c508000, 0xc0004880, 0x40100000, 0x58000014,
+ 0xc90000f8, 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x80001a58, 0x5e70000a, 0x84000040,
+ 0xc2000000, 0x582c0002, 0xce000000, 0xc2220002, 0xc0000a14, 0xce063100, 0x8000ff70, 0x5e700008,
+ 0x84000228, 0xc2200002, 0x582c000c, 0xce021000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000012,
+ 0xc90000f8, 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x5e340002, 0x6c508000, 0xc0004880,
+ 0x40100000, 0x58000010, 0xc90000f8, 0x00000000, 0x00000000, 0x41208000, 0xcd0000f8, 0xc0000a14,
+ 0xce863100, 0xc0004970, 0xcb4000f8, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec7e00, 0x582c000e,
+ 0xc4900038, 0xcd000038, 0x582c000e, 0xc7500838, 0xcd010838, 0xc2800000, 0x582c0004, 0xce821078,
+ 0x582c0004, 0xce800000, 0xc00049a0, 0xca4000f8, 0x00000000, 0x582c0006, 0xce4000f8, 0xc261fffe,
+ 0x5a65fffe, 0x582c0024, 0xce4000f8, 0xc2060002, 0x582c0004, 0xce006300, 0xc2400002, 0xc0004958,
+ 0xce4000f8, 0xc0004878, 0xc80400f8, 0x6c908000, 0x41088000, 0x40100000, 0x58000020, 0xc90000f8,
+ 0x582c0026, 0x00000000, 0xcd0000f8, 0x800017e8, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000,
+ 0x58000016, 0xc90000f8, 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x8000faf0, 0x5e700000,
+ 0x840000c0, 0xc3400082, 0xc0004970, 0xcf4000f8, 0xc2400080, 0xc000496c, 0xce4000f8, 0xc3c00002,
+ 0xc000496e, 0xcfc000f8, 0xc2400000, 0xc0004964, 0xce4000f8, 0xc0004878, 0xc80400f8, 0x6c908000,
+ 0x41088000, 0x40100000, 0x58000020, 0xc90000f8, 0x582c0026, 0x00000000, 0xcd0000f8, 0x80000078,
+ 0x5e700002, 0x84000058, 0xc3400082, 0xc0004970, 0xcf4000f8, 0xc3c00004, 0xc000496e, 0xcfc000f8,
+ 0xc2200000, 0x582c000c, 0xce021000, 0x80000030, 0x5e700004, 0x8400fe80, 0xc2600002, 0x582c000c,
+ 0xce421000, 0xc0000a14, 0xce863100, 0xc000496c, 0xca4000f8, 0x6c508000, 0xc0004880, 0x40100000,
+ 0x58000012, 0xc90000f8, 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0xc000496e, 0xcbc000f8,
+ 0x00000000, 0x00000000, 0x477d0000, 0x46250000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000010,
+ 0xc90000f8, 0x00000000, 0x00000000, 0x41208000, 0xcd0000f8, 0x6c6c8000, 0x6c544000, 0x42d56000,
+ 0x5aec7e00, 0x582c0004, 0xca0000f8, 0x00000000, 0x00000000, 0xa60014e2, 0x00000000, 0x6c6c8000,
+ 0x6c544000, 0x42d56000, 0x5aec7e00, 0xc3000000, 0x582c0004, 0xcf006300, 0x582c0000, 0xcb002010,
+ 0xc3c00000, 0x582c0004, 0xcbc20078, 0xc000491a, 0xcf0000f8, 0xc000493c, 0xcfc000f8, 0x582c0008,
+ 0xcb8000f8, 0x582c000a, 0xca4000f8, 0xc0004930, 0xcf8000f8, 0xc0004932, 0xce4000f8, 0x5ffc0000,
+ 0x840001f0, 0x00000000, 0xa7be0102, 0xc2800000, 0x6f206000, 0x46310000, 0x5a204c80, 0x5820000c,
+ 0xca800020, 0x00000000, 0x00000000, 0x5ea80000, 0x84000112, 0x00000000, 0xc161fffe, 0x5955fffe,
+ 0x14140000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x99005f70,
+ 0xc000491a, 0xc94000f8, 0x00000000, 0xc121fffe, 0x5911fef4, 0x14100000, 0xc0004930, 0xcb8000f8,
+ 0xc0004932, 0xca4000f8, 0xc4781108, 0xc0004930, 0xcf8000f8, 0x582c0008, 0xcf8000f8, 0x582c000a,
+ 0xce4000f8, 0xc7b6e108, 0x582c0004, 0xcf402108, 0x80000090, 0x00000000, 0x6c508000, 0xc0004880,
+ 0x40100000, 0x5800000c, 0xc90000f8, 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0xc2000002,
+ 0x582c0004, 0xce000000, 0xc0000838, 0xc2500002, 0xce450800, 0x80001220, 0x6c7c8000, 0x6c544000,
+ 0x43d5e000, 0x5bfc7e00, 0x583c0006, 0xca0000f8, 0xc00049a2, 0x00000000, 0xca8000f9, 0xca4000f8,
+ 0xc0001008, 0xce8000f8, 0xc0001006, 0xce4000f8, 0xc000100a, 0xce0000f8, 0xc2400006, 0xc0001000,
+ 0xce4000f8, 0xc2600982, 0x5a643b6e, 0xc0001002, 0xce4000f8, 0x583c0024, 0xca4000f8, 0x00000000,
+ 0xc0001004, 0xce4000f8, 0xc0004862, 0xc2000000, 0xca000078, 0xc360fffe, 0xc0004862, 0xce0000f8,
+ 0xc0000824, 0xcb440060, 0x00000000, 0xc000100e, 0xcf4000f8, 0xc3803800, 0xc2400200, 0x6e644000,
+ 0xc6781070, 0xc000100c, 0xcf8000f8, 0xc3200a00, 0xc0001010, 0xcf031810, 0xc2e06200, 0xc0001012,
+ 0xcec31838, 0xc2000000, 0x583c0004, 0xca002008, 0xc2800000, 0xc0004966, 0xce0000f8, 0xc62400f8,
+ 0xc3000000, 0xc000496a, 0xcf0000f8, 0xc0004974, 0xcf0000f8, 0xc000493c, 0xcb4000f8, 0x583c000e,
+ 0x00000000, 0x5f740000, 0x84000180, 0xc3400000, 0xcb410038, 0xc3000002, 0xc000496a, 0x5fb40080,
+ 0x84000152, 0xcf0000f8, 0x583c000e, 0xc2c00000, 0xcac00038, 0xc3800080, 0x47b5c000, 0xc0004974,
+ 0xcf8000f8, 0xc0001012, 0x6fba0000, 0xcf821038, 0x6fba0010, 0x43a5c000, 0x5b380006, 0x6f284010,
+ 0xc7a40008, 0x6eec4000, 0x6ef08000, 0x432d8000, 0x43358000, 0x5b300008, 0xc0001012, 0xc7100070,
+ 0xcd000070, 0xc2000200, 0xc2c00000, 0xdf6d0048, 0x462d6000, 0x46e96000, 0x8800ffe2, 0xc2000000,
+ 0xc0004862, 0xca000260, 0x00000000, 0x583c0004, 0xca002008, 0xc3360002, 0xc0001010, 0xce000070,
+ 0xc0001012, 0xcf037b00, 0xc0004974, 0xcb8000f8, 0x00000000, 0x00000000, 0x5fb80000, 0x84000042,
+ 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8, 0xc000496c,
+ 0xcac000f8, 0x00000000, 0x00000000, 0x426dc000, 0x5b380006, 0x6f304010, 0xc7a40008, 0xc0004968,
+ 0xce4000f8, 0xc000496e, 0xcb4000f8, 0x6ca44000, 0x6e608000, 0x42250000, 0x5a200006, 0x42350000,
+ 0xc0001012, 0xc6100070, 0xcd000070, 0x6eee0000, 0xcec21038, 0xc2000200, 0xc2c00000, 0xdf6d0048,
+ 0x462d6000, 0x42b14000, 0x46e96000, 0x8800ffda, 0xc000493c, 0xcb4000f8, 0xc0000838, 0xc3100002,
+ 0x5f740000, 0x84000060, 0xcf050800, 0xc0004974, 0xcb8000f8, 0x00000000, 0x00000000, 0x5fb80000,
+ 0x8400006a, 0xc0001012, 0xc3360002, 0xcf037b00, 0x800000a0, 0x583c0022, 0xcb4000f8, 0xc0004862,
+ 0xca0000f8, 0x00000000, 0xc0007800, 0x40200000, 0xcf4000f8, 0xc2000000, 0xc0004862, 0xca000260,
+ 0x00000000, 0x583c0004, 0xca002008, 0xc3360002, 0xc0001010, 0xce000070, 0xc0001012, 0xcf037b00,
+ 0xc0004968, 0xcbc000f8, 0xc0004964, 0xca4000f8, 0xc7e000f8, 0x00000000, 0x5e640000, 0x84000012,
+ 0xc2000000, 0xc0004974, 0xca4000f8, 0xc000496c, 0xca8000f8, 0xc000493c, 0xcb8000f8, 0x42698000,
+ 0x00000000, 0x43b1a000, 0x5ef40080, 0x8800019a, 0xc0004966, 0xcac000f8, 0x6c648000, 0x6c544000,
+ 0x42552000, 0x5a647e00, 0x58240000, 0x436da000, 0x4761a000, 0xc2400000, 0xca420078, 0x00000000,
+ 0x00000000, 0x46752000, 0x88000122, 0x432d8000, 0x47218000, 0x88000010, 0xc3000000, 0x5b300006,
+ 0x6f304010, 0xc000493a, 0xcf0000f8, 0xc0004932, 0xc2400000, 0xca4000d8, 0x00000000, 0x6fb84010,
+ 0x42792000, 0xc000491e, 0xce4000f8, 0xc0004862, 0xca8000f8, 0x00000000, 0xc2c0000a, 0xc6e80d70,
+ 0xc7281048, 0xc000491c, 0xce8000f8, 0x6c708000, 0x6c544000, 0x43158000, 0x5b307e00, 0x6f760000,
+ 0x58300004, 0xcf421078, 0x6ffc2000, 0x58300004, 0xcfc02108, 0x800000d0, 0x6c708000, 0x6c544000,
+ 0x43158000, 0x5b307e00, 0xc2800002, 0x58300004, 0xce800000, 0x6c508000, 0xc0004880, 0x40100000,
+ 0x5800000e, 0xc90000f8, 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x00000000, 0x00000000,
+ 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8, 0x80000920, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8, 0xc0004964, 0xca0000f8,
+ 0x6c7c8000, 0x6c544000, 0x43d5e000, 0x5bfc7e00, 0xdfe400f8, 0x5e200002, 0x84000608, 0x00000000,
+ 0x583c0004, 0xc2800000, 0xca820078, 0xc0004930, 0xcac000f8, 0x00000000, 0x00000000, 0x6eece000,
+ 0x6eefc010, 0x46aca000, 0xc1000000, 0xdd500039, 0x6d106010, 0x4550a000, 0xc1000000, 0xdd514201,
+ 0x4550c000, 0xa95000f1, 0xc00049a6, 0xca0000f8, 0xa94a0023, 0x00000000, 0x6e660000, 0x6e660010,
+ 0x46612000, 0x840000b2, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000004, 0xc90000f8,
+ 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x6c508000, 0xc0004880, 0x40100000, 0x58000006,
+ 0xc90000f8, 0x00000000, 0x00000000, 0x41148000, 0xcd0000f8, 0x80000720, 0x00000000, 0xa95203c1,
+ 0xc0001004, 0xcb8000f8, 0xc3400000, 0xdd740039, 0x5f740000, 0x840000d0, 0xc1218e08, 0x5911baf6,
+ 0x45388000, 0x84000372, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000008, 0xc90000f8,
+ 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x6c508000, 0xc0004880, 0x40100000, 0x5800000a,
+ 0xc90000f8, 0x00000000, 0x00000000, 0x41148000, 0xcd0000f8, 0x80000620, 0x00000000, 0xc000496c,
+ 0xcb0000f8, 0x583c0026, 0xcac000f8, 0xc0004878, 0xc80400f8, 0x6c908000, 0x41088000, 0x40100000,
+ 0x58000002, 0xca8000f8, 0x00000000, 0x00000000, 0x6ea90000, 0x5d300008, 0x8800004a, 0x59300002,
+ 0xc3000000, 0xc5300008, 0x6d104010, 0x40100000, 0xca8000f8, 0x5c000002, 0xcac000f8, 0x5d300000,
+ 0x8400003a, 0x6f246000, 0x6ae56000, 0xc1000040, 0x45252000, 0x6aa54010, 0x42e96000, 0x583c0026,
+ 0xcec000f8, 0xc1218e08, 0x5911baf6, 0xc0001004, 0xcd0000f8, 0x593c0026, 0xc000100e, 0xcd000060,
+ 0xc1340000, 0xc0001010, 0xcd035a00, 0xc1200008, 0xa94a0023, 0xc0001012, 0xc1200004, 0x59100004,
+ 0xcd0000b8, 0xc1360002, 0xcd037b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xa8e2ffe8, 0x00000000, 0xc1220002, 0xd90c00f8, 0xc0001004, 0xc90000f8, 0x00000000, 0x00000000,
+ 0x45388000, 0x840000b2, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000008, 0xc90000f8,
+ 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8, 0x6c508000, 0xc0004880, 0x40100000, 0x5800000a,
+ 0xc90000f8, 0x00000000, 0x00000000, 0x41148000, 0xcd0000f8, 0x80000360, 0x00000000, 0x6c508000,
+ 0xc0004880, 0x40100000, 0x58000000, 0xc90000f8, 0x00000000, 0x00000000, 0x59100002, 0xcd0000f8,
+ 0x6c508000, 0xc0004880, 0x40100000, 0x58000002, 0xc90000f8, 0x00000000, 0x00000000, 0x41148000,
+ 0xcd0000f8, 0xc0004930, 0xcd800078, 0xc3000000, 0x583c0008, 0xcf0000f8, 0x80000038, 0xc0001004,
+ 0xca0000f8, 0x583c0006, 0xce4000f8, 0x583c0024, 0xce0000f8, 0xc0004862, 0xc2000000, 0xca000078,
+ 0xc000493a, 0xca4000f8, 0x00000000, 0x00000000, 0x42254000, 0x5ee80200, 0x88000012, 0xc6e800f8,
+ 0xc0004000, 0x58003800, 0x40280000, 0xcb8000f8, 0x00000000, 0x583c0022, 0xcf8000f8, 0xc0004862,
+ 0xce800078, 0xc0001406, 0xcac000f8, 0xc2800002, 0x00000000, 0xc66c1048, 0xc6ac0a00, 0xcec000f8,
+ 0xc2000000, 0xdf600038, 0x5e600080, 0x8400ffea, 0xc000491c, 0xca4000f8, 0xc000491e, 0xca8000f8,
+ 0x99006480, 0xda5800f8, 0xda9800f9, 0x00000000, 0xc0004964, 0xcbc000f8, 0x00000000, 0x00000000,
+ 0x5ffc0000, 0x84000102, 0xc2000000, 0xdf610048, 0x5e6001fe, 0x8800ffe8, 0xc000491a, 0xc98000f8,
+ 0xc0004862, 0xc94000f8, 0x6d9c6000, 0x45d8e000, 0x59dc4c80, 0x990062e0, 0xd95800f8, 0xd99800f9,
+ 0xd9d400f8, 0x99006258, 0xc000491c, 0xc1400000, 0xc9420048, 0xc2000000, 0xdf600038, 0x5e600080,
+ 0x8400ffea, 0xc000491c, 0xca4000f8, 0xc000491e, 0xca8000f8, 0x99006480, 0xda5800f8, 0xda9800f9,
+ 0x00000000, 0xc0004970, 0xcb4000f8, 0x00000000, 0x00000000, 0x5e740082, 0x8400e6d8, 0x00000000,
+ 0x8000c018, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000016, 0xc90000f8, 0x00000000,
+ 0x00000000, 0x59100002, 0xcd0000f8, 0x8000e308, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec7e00,
+ 0xc000487c, 0xc80400f8, 0x00000000, 0x00000000, 0x40080000, 0xca0000f8, 0xc42400f8, 0x00000000,
+ 0xa60600f8, 0xc3c00000, 0xc2000000, 0x582c000c, 0xca010038, 0x00000000, 0x00000000, 0x5a200002,
+ 0xc6100838, 0xcd010838, 0x5e60000e, 0x8400bf00, 0xc2200000, 0x582c0002, 0xce021008, 0x582c000c,
+ 0xcfc10838, 0x582c0020, 0xcfc21078, 0x582c0010, 0xc1400000, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9,
+ 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd4000f9, 0xcd400018, 0x8000be68, 0xc2200004,
+ 0x582c0002, 0xce021008, 0x582c000c, 0xcfc10838, 0x99006ba8, 0x582c0002, 0xc94000f8, 0xc1a20000,
+ 0x8000be18, 0xc3e1fffe, 0x597dfffe, 0x593dfef4, 0x94000001, 0x00000000, 0x00000000, 0x00000000,
+ 0xc0800000, 0xdf4b0038, 0xc0004900, 0xcb8000f8, 0xc2000000, 0xc000490a, 0xa78000d0, 0xcbc000f8,
+ 0xc1000000, 0xd90000f9, 0xc1000002, 0xd90c00f8, 0x6ff46000, 0x477da000, 0x5b744c80, 0xc2400000,
+ 0x58340004, 0xca400078, 0xc0004900, 0xce000000, 0x5a640002, 0x58340004, 0xc6500078, 0xcd000078,
+ 0xc0004914, 0xca4000f8, 0xc2000002, 0x6a3d0000, 0x72612000, 0xce4000f8, 0xc0000408, 0xce0000f8,
+ 0xa78200c8, 0xc0004908, 0xcbc000f8, 0xc1000000, 0xd90000f9, 0xc1000002, 0xd90c00f8, 0x6ff4a000,
+ 0x477da000, 0x5b747600, 0xc2800000, 0x58340006, 0xca800078, 0xc2000000, 0xc0004900, 0xce002100,
+ 0x5ea80002, 0x58340006, 0xc6900078, 0xcd000078, 0x5a7c0020, 0xc2000002, 0x6a250000, 0xc0000408,
+ 0xce0000f8, 0xdca800f9, 0x5ea80000, 0x8400abd0, 0x00000000, 0xa4800230, 0x00000000, 0xc3c00000,
+ 0xc000140e, 0xcbc00018, 0xc3400000, 0xc2400000, 0x6ff86000, 0x47bdc000, 0x5bb84c80, 0x58380008,
+ 0xcb400078, 0x58380006, 0xca400078, 0x5f740002, 0x58380008, 0xc7500078, 0xcd000078, 0xc2000000,
+ 0x58380004, 0xca020078, 0xc3000000, 0x5838000c, 0xcb000020, 0x5a640002, 0x46610000, 0x84000010,
+ 0xc2400000, 0x58380006, 0xc6500078, 0xcd000078, 0xc2000000, 0x5838000a, 0xca020078, 0x5b300002,
+ 0x5838000c, 0xc7100020, 0xcd000020, 0xc2420020, 0x5a200004, 0x46252000, 0x84000010, 0xc2000000,
+ 0x5838000a, 0xc6101078, 0xcd021078, 0xc000498c, 0xca4000f8, 0xc2000002, 0x6a3d0000, 0x72612000,
+ 0xce4000f8, 0x5f740000, 0x84000040, 0xc0004912, 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x7ec16000,
+ 0x762d0000, 0xce0000f8, 0x5f300020, 0x84000040, 0xc0004924, 0xca0000f8, 0xc2c00002, 0x6afd6000,
+ 0x7ec16000, 0x762d0000, 0xce0000f8, 0xa4820070, 0xc2400000, 0xc000140e, 0xca408018, 0xc2000002,
+ 0xc0004900, 0xce000000, 0xc000490a, 0xce4000f8, 0xc1000000, 0xd90000f9, 0xd8400078, 0xc1000004,
+ 0xd90000f9, 0xa48402d8, 0x00000000, 0xc3c00000, 0xc000140e, 0xcbc10018, 0xc2800000, 0xc2000000,
+ 0x6ff8a000, 0x47bdc000, 0x5bb87600, 0x58380036, 0xca800078, 0x58380006, 0xca020078, 0xc3400000,
+ 0x58380036, 0xcb420078, 0x5aa80002, 0x46a10000, 0x84000010, 0xc2800000, 0x58380036, 0xc6900078,
+ 0xcd000078, 0x5f740002, 0x58380036, 0xc7501078, 0xcd021078, 0xc000498e, 0xca4000f8, 0xc2000002,
+ 0x6a3d0000, 0x72612000, 0xce4000f8, 0xc000492a, 0xca8000f8, 0x5e740000, 0x84000040, 0xc0004910,
+ 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x7ec16000, 0x762d0000, 0xce0000f8, 0x6abd4010, 0xa6800132,
+ 0x00000000, 0x5838003a, 0xca0000f8, 0x58000002, 0xca4000f8, 0x5838000e, 0x00000000, 0xce0000f9,
+ 0xce4000f8, 0xc2400000, 0xdd250038, 0xc1000080, 0x45248000, 0xc2400000, 0xc6240078, 0x46510000,
+ 0x00000000, 0xc52400fc, 0x5d240078, 0xc1000078, 0xc52400fc, 0xc6600078, 0x5c000002, 0xce000078,
+ 0xc000492a, 0xca0000f8, 0xc2c00002, 0x6afd6000, 0x722d0000, 0xce0000f8, 0xc000492c, 0xca0000f8,
+ 0xc2c00002, 0x6afd6000, 0x722d0000, 0xce0000f8, 0x80000040, 0xc000492c, 0xca0000f8, 0xc2c00002,
+ 0x6afd6000, 0x7ec16000, 0x762d0000, 0xce0000f8, 0xa4880088, 0xc2c00000, 0xc000140e, 0xcac20018,
+ 0xc000490e, 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x7e010000, 0x76612000, 0xce4000f8, 0xc0004990,
+ 0xca4000f8, 0xc2000002, 0x6a2d0000, 0x72612000, 0xce4000f8, 0xa4860070, 0xc2400000, 0xc000140e,
+ 0xca418018, 0xc2020002, 0xc0004900, 0xce002100, 0xc0004908, 0xce4000f8, 0xc1000000, 0xd90000f9,
+ 0xd8400078, 0xc1000004, 0xd90000f9, 0xc0001408, 0xcc8000f8, 0xc10e0002, 0xd90c00f8, 0x8000f750,
+ 0xdfbc00f9, 0xc0004992, 0x99006be8, 0xc94000f8, 0xc7d800f8, 0x00000000, 0xc57000f8, 0x5ef00020,
+ 0x88000158, 0x6f346000, 0x4771a000, 0x5b744c80, 0x58340008, 0xc2400000, 0xca400078, 0x00000000,
+ 0xc2000000, 0x5a640002, 0xc6500078, 0xcd000078, 0x58340004, 0xca000078, 0x00000000, 0x00000000,
+ 0x5e200002, 0xc6100078, 0xcd000078, 0xc0004912, 0xca8000f8, 0xc2400002, 0x6a712000, 0x72a54000,
+ 0xce8000f8, 0x5e200000, 0x84000052, 0xc000480a, 0xca0000f8, 0xc0000408, 0xca8000f8, 0x76250000,
+ 0x00000000, 0x72a14000, 0xce8000f8, 0x80000038, 0xc0004914, 0xca0000f8, 0x7e412000, 0x00000000,
+ 0x76250000, 0xce0000f8, 0x800000c8, 0x6ef4a000, 0x476da000, 0x5b747600, 0x58340036, 0xc2400000,
+ 0xca420078, 0x00000000, 0xc2000000, 0x5a640002, 0xc6501078, 0xcd021078, 0x58340006, 0xca000078,
+ 0x00000000, 0x00000000, 0x5a200002, 0xc6100078, 0xcd000078, 0xc0004910, 0xca4000f8, 0xc2000002,
+ 0x6a2d0000, 0x72612000, 0xce4000f8, 0xc2000002, 0x6a310000, 0xc000042a, 0xce0000f8, 0xc1040002,
+ 0xd90c00f8, 0x00000000, 0x8000f4b8, 0x00000000, 0xc4980928, 0x9d000000, 0xc5580028, 0xc0000838,
+ 0xcd8400f8, 0xc1440200, 0xc1c03800, 0xc55c1070, 0xc000100e, 0x9d000000, 0xcd8000f8, 0xc000100c,
+ 0xcdc000f8, 0xc0004862, 0xc9c000f8, 0x00000000, 0x00000000, 0xd9d800f9, 0xc0007800, 0x401c0000,
+ 0x5dc07a00, 0x88000012, 0x5c000200, 0xcd8000f8, 0xc1f0000a, 0x715ca000, 0xdd9800f8, 0xdd9c00f9,
+ 0x41d8e000, 0xc5d40260, 0xc0001010, 0xcd4000f8, 0x6c9c8000, 0x45c8e000, 0x45c8e000, 0x59dc0004,
+ 0xc1601260, 0xc5d40260, 0x9d000000, 0xc0001012, 0xcd4000f8, 0x00000000, 0x00000000, 0xd95800f8,
+ 0x6d586000, 0x4594c000, 0x59984c80, 0xd99800f9, 0x5818000a, 0xc1800000, 0xc9800078, 0xc0007680,
+ 0x6d5ca000, 0x401c0000, 0x40180000, 0xc94000f8, 0x58000002, 0x00000000, 0xc9c000f8, 0xc0004930,
+ 0xcd4000f8, 0xc0004932, 0xcdc000f8, 0x59980004, 0xc1c20020, 0xb59c0018, 0x00000000, 0xc1800000,
+ 0xdd9c00f9, 0x581c000a, 0xcd800078, 0x581c000c, 0xc1800000, 0xc9800020, 0xc1c00002, 0xdd9400f8,
+ 0x69d4e000, 0x5d980002, 0xcd800020, 0xc0004924, 0xc98000f8, 0x00000000, 0x9d000000, 0x00000000,
+ 0x719cc000, 0xcd8000f8, 0xc000492a, 0xc94000f8, 0xc1c00002, 0x69d8e000, 0x7dc0c000, 0x7558a000,
+ 0xcd4000f8, 0xc000492c, 0xc94000f8, 0xdd8000f9, 0x5800003a, 0x755ca000, 0x84000108, 0xc94000f9,
+ 0xc98000f8, 0xdd8000f9, 0x5800000e, 0x00000000, 0xcd4000f9, 0xcd8000f8, 0xc1800000, 0xdd190038,
+ 0xc1000080, 0x45188000, 0xc1800000, 0xc5580078, 0x4590a000, 0x00000000, 0xc51800fc, 0x5d180078,
+ 0xc1000078, 0xc51800fc, 0xc5940078, 0x5c000002, 0xcd400078, 0xc000492c, 0xc94000f8, 0xc000492a,
+ 0xc98000f8, 0x715ca000, 0xc000492c, 0xcd4000f8, 0x719cc000, 0xc000492a, 0xcd8000f8, 0x9cc00000,
+ 0x00000000, 0x00000000, 0x00000000, 0xc0004862, 0xc98000f8, 0x00000000, 0xc1c00200, 0x4194c000,
+ 0x459ce000, 0x88000012, 0xc5d800f8, 0xc0004862, 0xcd8000f8, 0xc0001406, 0xc98000f8, 0xc1c00002,
+ 0x9d000000, 0xc5d80a00, 0xc5581048, 0xcd8000f8, 0xc0004930, 0xc98000f8, 0xc0004932, 0xc9c000f8,
+ 0xc140000e, 0xc5581c18, 0xdd9400f8, 0xc0007800, 0x40140000, 0x5d407a00, 0x88000012, 0x5c000200,
+ 0xcd8000f8, 0x58000002, 0x5d407a00, 0x88000012, 0x5c000200, 0xcdc000f8, 0xdd5400f8, 0xc1c00000,
+ 0x58140006, 0xc9c20078, 0xc1800000, 0x58140000, 0xc98000d8, 0x6ddc2000, 0xc000491e, 0x41d8e000,
+ 0xcdc000f8, 0xdd9800f8, 0xc1c00022, 0xc5d80d70, 0xdd9400f9, 0xc5581c18, 0xc000491c, 0xcd8000f8,
+ 0xdd5400f8, 0xc1c00000, 0x58140006, 0xc9c20078, 0xc1800000, 0x58140004, 0xc9820078, 0x00000000,
+ 0x59dc0002, 0x45d8c000, 0x84000010, 0xc1c00000, 0x9d000000, 0x58140006, 0xc5d81078, 0xcd821078,
+ 0xc0004860, 0xc94000f8, 0xc1820080, 0xc1d00002, 0x58147700, 0xd58000f8, 0x58000002, 0xd58000f9,
+ 0x59540004, 0xb5580018, 0xc0004860, 0xc1400000, 0xcd4000f8, 0xdd9800f9, 0x9d000000, 0xdd9400f8,
+ 0xc0001404, 0xcdc10800, 0xc1c00000, 0xc1800200, 0x5d980004, 0xdf5d0048, 0x459ca000, 0x8800fff2,
+ 0xdd8000f9, 0x5800000e, 0x00000000, 0xc94000f9, 0xc98000f8, 0xc1c00002, 0xc5d43f00, 0xc5d81e00,
+ 0xc0004862, 0xc9c000f8, 0x00000000, 0x00000000, 0x581c7800, 0x5dc07a00, 0x88000012, 0x5c000200,
+ 0xcd4000f8, 0x58000002, 0x5dc07a00, 0x88000012, 0x5c000200, 0xcd8000f8, 0xc0004862, 0xc9c000f8,
+ 0x00000000, 0xc15004c0, 0xc5d40060, 0xdd9c00f8, 0xc5d41c18, 0xc1c00000, 0xdd8000f9, 0x58000038,
+ 0xc9c00078, 0xdd8000f9, 0xc1800000, 0x58000002, 0xc98000d8, 0x6ddc2000, 0xc000491c, 0x41d8e000,
+ 0xcd4000f9, 0xcdc000f8, 0xdd9400f9, 0xc1c00000, 0x58140038, 0xc9c00078, 0xc1800000, 0x58140006,
+ 0xc9820078, 0x00000000, 0x59dc0002, 0x45d8c000, 0x84000010, 0xc1c00000, 0x9d000000, 0x58140038,
+ 0xc5d80078, 0xcd800078, 0xc1c00000, 0xdf5c0038, 0x5ddc0080, 0x8400ffea, 0x00000000, 0x9d000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xc160fffe, 0xc0000a10, 0xc9440060, 0xc1a0fffe, 0x59983608,
+ 0xc000100c, 0xcd4000f8, 0xc000100e, 0xcd8000f8, 0xc0004962, 0xc98000f8, 0x00000000, 0xc170000a,
+ 0x7158a000, 0x6c988000, 0x4588c000, 0x4588c000, 0x59980004, 0xc5940270, 0xc0001010, 0xcd4000f8,
+ 0xc0004946, 0xc94000f8, 0x00000000, 0x00000000, 0x6d58a000, 0x6d5c4000, 0x459cc000, 0x4594c000,
+ 0xc000494a, 0xc94000f8, 0xc0004948, 0xc9c000f8, 0x4194c000, 0xc1400012, 0xc55c1818, 0x9d000000,
+ 0xc59c0268, 0xc0001012, 0xcdc000f8, 0xc1400000, 0x58000014, 0xc9410038, 0xc0004950, 0xc9c000f8,
+ 0xc55800f8, 0xc5940838, 0xc5581078, 0xd99400f8, 0xc000493c, 0xc94000f8, 0xc0004954, 0xc98000f8,
+ 0x59dc00a8, 0x45d4e000, 0x41d8e000, 0x5d5c0030, 0x88000010, 0xc1c00030, 0xc1800000, 0xc5d84028,
+ 0xc1400000, 0xc5d40008, 0x5dd40002, 0x84000072, 0x5dd40004, 0x8400009a, 0x5dd40006, 0x840000c2,
+ 0x5dd80026, 0x840000ea, 0xdd5400f8, 0xdd8000f9, 0x58000008, 0x40180000, 0xcd4000f8, 0x59980002,
+ 0x8000ffc0, 0xdd5400f8, 0xdd8000f9, 0x58000008, 0x40180000, 0xcd4000b8, 0x59980002, 0x8000ff88,
+ 0xdd5400f8, 0xdd8000f9, 0x58000008, 0x40180000, 0xcd400078, 0x59980002, 0x8000ff50, 0xdd5400f8,
+ 0xdd8000f9, 0x58000008, 0x40180000, 0xcd400038, 0x59980002, 0x8000ff18, 0x00000000, 0x9d000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x58000014, 0xc94000f8, 0xc0004954, 0xc9c000f8, 0xc0004950,
+ 0xc9400078, 0xdd8000f9, 0x5800002a, 0x5d9c0000, 0x84000052, 0x5d9c0002, 0x84000052, 0x5d9c0004,
+ 0x8400006a, 0xc55b0038, 0xc55c08b8, 0xcd800039, 0xcdc108b8, 0x80000060, 0xcd4000f8, 0x80000050,
+ 0xc55900b8, 0xc55c1838, 0xcd8000b9, 0xcdc31838, 0x80000028, 0xc55a0078, 0xc55c1078, 0xcd800079,
+ 0xcdc21078, 0x9d000000, 0x00000000, 0x00000000, 0x00000000, 0xc1e00000, 0xa540001a, 0xc0000a14,
+ 0xc1a20002, 0x9d000000, 0xcd863100, 0xc0000a1c, 0xcdc61038, 0x59540002, 0x6994e018, 0x61c0c008,
+ 0x4194a000, 0x5d940040, 0x88000012, 0xc59400f8, 0x9d000000, 0xcd4000f8, 0x00000000, 0x00000000,
+};
+
+static unsigned int firmware_binary_data[] = {
+};
+
+
+#endif // IFXMIPS_PTM_FW_AR9_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_danube.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_danube.h
new file mode 100644
index 0000000000..3451682fb2
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_danube.h
@@ -0,0 +1,489 @@
+#ifndef IFXMIPS_PTM_FW_DANUBE_H
+#define IFXMIPS_PTM_FW_DANUBE_H
+
+
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_fw_danube.h
+** PROJECT : Danube
+** MODULES : PTM (ADSL)
+**
+** DATE : 1 AUG 2005
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM Driver (PP32 Firmware)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 4 AUG 2005 Xu Liang Initiate Version
+** 23 OCT 2006 Xu Liang Add GPL header.
+*******************************************************************************/
+
+
+#define PTM_FW_VER_MAJOR 0
+#define PTM_FW_VER_MINOR 17
+
+
+static unsigned int firmware_binary_code[] = {
+ 0x800004a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000ffc8, 0x00000000, 0x00000000, 0x00000000,
+ 0xc1000002, 0xd90c0000, 0xc2000002, 0xda080001, 0x80005618, 0xc2000000, 0xda080001, 0x800055b8,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x80005da8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc10e0002, 0xd90c0000, 0xc0004808, 0xc8400000, 0x80005288, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc3e1fffe, 0x597dfffe, 0x593dfef4, 0x900004d9, 0x00000000, 0x00000000, 0x00000000, 0x90cc0481,
+ 0x00000000, 0x00000000, 0x00000000, 0xc3e02262, 0x5bfc0022, 0xc0004002, 0xcfc00000, 0xc0004810,
+ 0xcbc00000, 0x00000000, 0xc3800000, 0xc7f80040, 0x5fb80000, 0xc7fa0040, 0xc7bfe80a, 0x5fb80000,
+ 0x00000000, 0xc7bff80a, 0xdbd40001, 0xc00049a0, 0xc3800002, 0xa7ca004a, 0xc1200000, 0x5911fffe,
+ 0xcd000001, 0xc1200000, 0x59102042, 0xcd000001, 0xc1000004, 0xcd000001, 0xc1200000, 0x59103a1e,
+ 0xcd000001, 0x80000048, 0xc121fffe, 0x5911fffe, 0xcd000001, 0xc1203db8, 0x5910de82, 0xcd000001,
+ 0xc1000006, 0xcd000001, 0xc120385a, 0x591033da, 0xcd000001, 0x5fb80002, 0x88000002, 0x6ffe0010,
+ 0x8000ff10, 0xdd7c0001, 0xc3800000, 0xc7f86018, 0x5bb80008, 0xc3540002, 0x77f5a000, 0xc1000008,
+ 0x4539c002, 0xcf800001, 0xdb900040, 0xc3800008, 0xc3720002, 0x77f5a000, 0xa7f00008, 0x47b9c002,
+ 0xc1000000, 0xc7d26018, 0x4391c000, 0xcf800000, 0xdb900840, 0xc3c00000, 0xdbc80001, 0xc0400000,
+ 0xc11c0000, 0xc000082c, 0xcd040e08, 0xc11c0002, 0xc000082c, 0xcd040e08, 0xc0400002, 0xc11c0000,
+ 0xc000082c, 0xcd040e08, 0xc11c0002, 0xc000082c, 0xcd040e08, 0xc0000824, 0x00000000, 0xcbc00001,
+ 0xcb800001, 0xcb400001, 0xcb000000, 0xc0004878, 0x5bfc4000, 0xcfc00001, 0x5bb84000, 0xcf800001,
+ 0x5b744000, 0xcf400001, 0x5b304000, 0xcf000000, 0xc0000a10, 0x00000000, 0xcbc00001, 0xcb800000,
+ 0xc0004874, 0x5bfc4000, 0xcfc00001, 0x5bb84000, 0xcf800000, 0xc30001fe, 0xc000140a, 0xcf000000,
+ 0xc3000000, 0x7f018000, 0xc000042e, 0xcf000000, 0xc000040e, 0xcf000000, 0xc3c1fffe, 0xc000490e,
+ 0xcfc00080, 0xc000492c, 0xcfc00080, 0xc0004924, 0xcfc00040, 0xc0004912, 0xcfc00040, 0xc000498c,
+ 0xcfc00040, 0xc000498e, 0xcfc00080, 0xc0004990, 0xcfc00080, 0xc3c00000, 0xc2800004, 0xc3000000,
+ 0x7f018000, 0x6ff88000, 0x6fd44000, 0x4395c000, 0x5bb84a00, 0xc00049a0, 0xcb000000, 0x00000000,
+ 0x58380006, 0xcf000000, 0xc321fffe, 0x5b31fffe, 0x58380024, 0xcf000000, 0x5bfc0002, 0xb7e8ff70,
+ 0x00000000, 0xc3c00000, 0xc2800010, 0x6ff86000, 0x47f9c000, 0x5bb84c80, 0xc3400000, 0x58380004,
+ 0xcb420080, 0x00000000, 0x58380008, 0xcf400080, 0x5bfc0002, 0xb7e8ff90, 0x00000000, 0xc3c00000,
+ 0xc2800004, 0xc3400022, 0xc3000000, 0x7f018000, 0xc2c00016, 0x6ff8a000, 0x47f9c000, 0x5bb84e20,
+ 0x58380008, 0xcf400040, 0xc00049a8, 0xcb000000, 0x00000000, 0x5838000a, 0xcf000000, 0xc321fffe,
+ 0x5b31fffe, 0x5838000c, 0xcf000000, 0x58380034, 0xcec00040, 0x5bfc0002, 0xb7e8ff58, 0x00000000,
+ 0x00000000, 0xc0004840, 0xc3e12624, 0x5bfc2320, 0xcfc00001, 0xc3e02f2c, 0x5bfd2a28, 0xcfc00001,
+ 0xc3e03734, 0x5bfd3230, 0xcfc00001, 0xc3e13e3c, 0x5bfc3b38, 0xcfc00001, 0xc3e14644, 0x5bfc4340,
+ 0xcfc00001, 0xc3e04f4c, 0x5bfd4a48, 0xcfc00001, 0xc3e05754, 0x5bfd5250, 0xcfc00001, 0xc3e15e5c,
+ 0x5bfc5b58, 0xcfc00001, 0xc3e06764, 0x5bfd6260, 0xcfc00001, 0xc3e16e6c, 0x5bfc6b68, 0xcfc00001,
+ 0xc3e17674, 0x5bfc7370, 0xcfc00001, 0xc3e07f7c, 0x5bfd7a78, 0xcfc00001, 0xc3e18684, 0x5bfc8380,
+ 0xcfc00001, 0xc3e08f8c, 0x5bfd8a88, 0xcfc00001, 0xc3e09794, 0x5bfd9290, 0xcfc00001, 0xc3e19e9c,
+ 0x5bfc9b98, 0xcfc00001, 0xc121fffe, 0x5911fef4, 0x15000000, 0x80000010, 0x00000000, 0x80000638,
+ 0x00000000, 0x8000ffc8, 0xc0004918, 0xd2800000, 0xc2000000, 0xdf600040, 0x5e600080, 0x8400029a,
+ 0x00000000, 0xc161fffe, 0x5955fffe, 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xc000480a, 0xca000000, 0xc0004912, 0xca400000, 0xc0004924, 0xca800000,
+ 0xc000498c, 0xcac00000, 0xc121fffe, 0x5911fef4, 0x15000000, 0x76610000, 0x76a10000, 0x76e10000,
+ 0x840001d2, 0xc0004918, 0xca400000, 0xc28001fe, 0x76a10000, 0x5a640002, 0x6a254010, 0x5ee80000,
+ 0x84000002, 0x6aa54000, 0x8000fff8, 0xc6280000, 0x62818008, 0xc0004918, 0xcf000000, 0xc161fffe,
+ 0x5955fffe, 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc000498c, 0xca400000, 0xc2000002, 0x6a310000, 0x7e010000, 0x76252000, 0xce400000, 0xc121fffe,
+ 0x5911fef4, 0x15000000, 0x6f346000, 0x4735a000, 0x5b744c80, 0xc2800000, 0x58340006, 0xca800080,
+ 0xc2c00000, 0x58340000, 0xcac000e0, 0xc2400000, 0x5834000a, 0xca420080, 0x6ea82000, 0x42e9e000,
+ 0x6f2ca000, 0x42e56000, 0x5aec1400, 0xc3990040, 0xc7381c20, 0xc6f80068, 0x99006840, 0xdb980000,
+ 0xdbd80001, 0x00000000, 0xdea00000, 0x47210000, 0x8400fd28, 0xc000495a, 0xc8400000, 0x00000000,
+ 0xc3c00002, 0x7bc42000, 0xcc400000, 0xc0000838, 0xc3800000, 0xcb840030, 0x6c748000, 0x6c544000,
+ 0x4355a000, 0x5b744a00, 0x5ef80000, 0x8400fc8a, 0x58340004, 0xcb000000, 0x00000000, 0x00000000,
+ 0xa7060000, 0x00000000, 0x5ef80002, 0x8400fc4a, 0x5834000c, 0xc8800040, 0xc2000000, 0xc000082c,
+ 0xca040030, 0x5a880002, 0xc2400000, 0xc0004958, 0xce400000, 0xb628fff8, 0x00000000, 0xc2800000,
+ 0x58340002, 0xc2000000, 0xca020010, 0xc0004956, 0xce800000, 0x5e600000, 0x84001df2, 0x5e600002,
+ 0x840043da, 0x00000000, 0x80002320, 0xc0004958, 0xca000000, 0xc0004956, 0xca800000, 0x5e200000,
+ 0x84000008, 0xc2500002, 0xc0000838, 0xce440808, 0x6c748000, 0x6c544000, 0x4355a000, 0x5b744a00,
+ 0x5834000c, 0xc6900040, 0xcd000040, 0x58340002, 0xc2000000, 0xca020010, 0x00000000, 0x00000000,
+ 0x5f600000, 0x84000122, 0xc0004818, 0xc8000000, 0x00000000, 0x00000000, 0x5c000000, 0x840000f2,
+ 0xc11c0000, 0xc000082c, 0xcd040e08, 0xc0000838, 0xc3800000, 0xc2400000, 0xcb840030, 0xca452030,
+ 0x00000000, 0x42b9a000, 0x5e340022, 0x88000012, 0xc200001e, 0x7635a000, 0x5f740002, 0x8000fff0,
+ 0x6e642010, 0x4675a000, 0x84000042, 0xc0004818, 0xc8000000, 0x00000000, 0x00000000, 0x5c000000,
+ 0x84000012, 0x00000000, 0x00000000, 0x00000000, 0x8000ffa0, 0xc11c0002, 0xc000082c, 0xcd040e08,
+ 0x8000f9b8, 0xc2000000, 0xdf600040, 0x5e200080, 0x84000272, 0x00000000, 0xc161fffe, 0x5955fffe,
+ 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc000480c,
+ 0xca000000, 0xc0004910, 0xca400000, 0xc000492c, 0xca800000, 0xc000498e, 0xcac00000, 0xc121fffe,
+ 0x5911fef4, 0x15000000, 0x76610000, 0x76a10000, 0x762d6000, 0x840001aa, 0xc0004926, 0xca400000,
+ 0xc201fffe, 0x762d6000, 0x5a640002, 0x6ae50010, 0x5f200000, 0x84000002, 0x6a250000, 0x8000fff8,
+ 0xc6e00000, 0x62014008, 0xc0004926, 0xce800000, 0xc161fffe, 0x5955fffe, 0x15400000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc000498e, 0xca400000, 0xc2000002,
+ 0x6a290000, 0x7e010000, 0x76252000, 0xce400000, 0xc121fffe, 0x5911fef4, 0x15000000, 0x6eb4a000,
+ 0x46b5a000, 0x5b744e20, 0x58340002, 0xc2000000, 0xca0000e0, 0x58340036, 0xc2400000, 0xca400080,
+ 0x6eb0a000, 0x46b18000, 0x5b300e56, 0x5b300004, 0x6e642000, 0x4225e000, 0xc39a8024, 0xc7380068,
+ 0xc6b81c20, 0x99006840, 0xdb980000, 0xdbd80001, 0x00000000, 0xc2000000, 0xdf600040, 0x5e200080,
+ 0x840002c2, 0x00000000, 0xc161fffe, 0x5955fffe, 0x15400000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xc000490e, 0xca000000, 0xc000492a, 0xca400000, 0xc0004990,
+ 0xcb000000, 0xc000498a, 0xcac00000, 0xc121fffe, 0x5911fef4, 0x15000000, 0x76318000, 0x76718000,
+ 0x84000202, 0xc201fffe, 0x76318000, 0x5aec0002, 0x6b2d0010, 0x5ea00000, 0x84000002, 0x6a2d0000,
+ 0x8000fff8, 0xc7200000, 0x62016008, 0xc000498a, 0xcec00000, 0xc161fffe, 0x5955fffe, 0x15400000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc0004990, 0xca400000,
+ 0xc2000002, 0x6a2d0000, 0x7e010000, 0x76252000, 0xce400000, 0xc121fffe, 0x5911fef4, 0x15000000,
+ 0x6ef4a000, 0x46f5a000, 0x5b744e20, 0x58340010, 0xc2000000, 0xca0000e0, 0x58340008, 0xc2400000,
+ 0xca420080, 0x5834000e, 0xc2800000, 0xca832018, 0xc3c00000, 0x467c8000, 0x6e644010, 0xc7e80004,
+ 0x42250000, 0x4229e000, 0xc39a8008, 0x58340008, 0xcb801040, 0x58340008, 0xc2800000, 0xca810018,
+ 0x6ee0a000, 0x46e10000, 0x5a20000a, 0x5a200e28, 0x42290000, 0xc6380068, 0xc6f81c20, 0x99006840,
+ 0xdb980000, 0xdbd80001, 0x00000000, 0xc000495c, 0xc8400000, 0xc3400000, 0xc3c00002, 0x7bc42000,
+ 0xcc400000, 0x6c78a000, 0x4479c000, 0x5bb84e20, 0x58380034, 0xcb410040, 0xc0000a28, 0xc3000000,
+ 0xcb040030, 0xc0000a14, 0xc2c00000, 0x43358000, 0xcac40030, 0xc000490e, 0xca800000, 0x5eec0002,
+ 0x46f18000, 0x8800f348, 0x6bc5e000, 0x77e94000, 0x8400f330, 0x6c7ca000, 0x447de000, 0x5bfc4e20,
+ 0x583c0008, 0xc2000000, 0xca020080, 0xc00049aa, 0x00000000, 0xca800001, 0xca400000, 0xc0001008,
+ 0xce800000, 0xc0001006, 0xce400000, 0x583c000a, 0xca400000, 0x00000000, 0xc000100a, 0xce400000,
+ 0xc2400006, 0xc0001000, 0xce400000, 0xc2600982, 0x5a643b6e, 0xc0001002, 0xce400000, 0x583c000c,
+ 0xca400000, 0x00000000, 0xc0001004, 0xce400000, 0x583c000e, 0xcb800000, 0x00000000, 0xc2400000,
+ 0xc7a40080, 0xc2800000, 0xc7aae028, 0xdaa00001, 0x583c0034, 0xcb800000, 0x00000000, 0xc2c00000,
+ 0xc7ad0040, 0xc0004978, 0xcec00000, 0xc0800000, 0xc7880040, 0xc3400000, 0xc7b60040, 0xc0004980,
+ 0xcf400000, 0x4625c000, 0x43a9c000, 0xc2400000, 0xc000497c, 0xce400000, 0xac2c0001, 0xc2800000,
+ 0x00000000, 0x8000fff8, 0xc2800002, 0xc0004976, 0xce800000, 0xc2c00000, 0xc34000a0, 0xdb5c0001,
+ 0xc3400002, 0xc000497a, 0xcf400000, 0x5f600000, 0x84000168, 0xde280001, 0xc6a00000, 0x46b9c000,
+ 0x583c0000, 0xc2800000, 0xca830040, 0xc0000a28, 0xc3000000, 0xcb040030, 0xc3400000, 0xc0004976,
+ 0x47298000, 0x88000052, 0xcf400000, 0x58880002, 0xc3000000, 0xc0000a14, 0xcb040030, 0x00000000,
+ 0x00000000, 0xb4b00188, 0x00000000, 0xc0800000, 0x00000000, 0x80000170, 0xc0004980, 0xcb400000,
+ 0x00000000, 0x00000000, 0x5af40002, 0xafec0080, 0x00000000, 0xc2c00000, 0xc000497a, 0xacec0001,
+ 0x00000000, 0x00000000, 0xac2c007f, 0xc2800000, 0xce800000, 0x80000000, 0xc2800002, 0xce800000,
+ 0x5f6c0000, 0x840000d0, 0x00000000, 0x8000fee8, 0x5f780082, 0x88000240, 0xc3000002, 0xc000497c,
+ 0xcf000000, 0xc2800080, 0xc1000000, 0xdd110040, 0x45294000, 0x46b94000, 0x880001c0, 0x4391a000,
+ 0xc0004980, 0xcf400000, 0x6f684010, 0x6f77c000, 0x6f77c010, 0xc0004840, 0x40280000, 0xca800000,
+ 0xc3000000, 0x6f506000, 0x6a908010, 0xc5300040, 0xdb1c0001, 0x8000fe18, 0xc3400000, 0xc0000a10,
+ 0xcb440068, 0x6cb04000, 0x6f288000, 0x6f744000, 0x42b14000, 0x43694000, 0xc3400000, 0xc6b44068,
+ 0xc0004000, 0x40340000, 0xc321e000, 0xcf000000, 0x5aa80008, 0x42ad4000, 0xc3400000, 0xc6b44068,
+ 0xc0004000, 0x40340000, 0xca400000, 0xc3000000, 0xc6f00010, 0xc1400000, 0xddd40041, 0x6f306000,
+ 0xc13001fe, 0x69308010, 0x7d008000, 0x75252000, 0x6d570000, 0x6970a010, 0x42552000, 0xce400000,
+ 0x5aa80002, 0x5aec0002, 0xafec0080, 0x00000000, 0xc2c00000, 0x5f6c0000, 0x84000100, 0x00000000,
+ 0x80000028, 0x4391a000, 0x5f740080, 0xc0004980, 0xcf400000, 0xc3000004, 0xc000497a, 0xcf000000,
+ 0x58880002, 0xc3400000, 0xc0000a14, 0xcb440030, 0x00000000, 0x00000000, 0xb4b4fff8, 0x00000000,
+ 0xc0800000, 0xc3400000, 0xc0000a10, 0xcb440068, 0x6cb04000, 0x6f248000, 0x6f744000, 0x42712000,
+ 0x43654000, 0xc3400000, 0xc6b44068, 0xc0004000, 0x40340000, 0xc3201e00, 0xcf000000, 0x5aa80008,
+ 0x42ad4000, 0xc000100c, 0xcb400000, 0xc3000000, 0x00000000, 0xc7340068, 0xc300fffe, 0xc7341078,
+ 0xcf400000, 0xc000100e, 0xcb400000, 0xc3000e28, 0x00000000, 0xc7340068, 0xc300fffe, 0xc7341078,
+ 0xcf400000, 0xc0001010, 0xcb400000, 0xc3000002, 0x00000000, 0xc7341a08, 0xc7341808, 0xc3000000,
+ 0xc7341908, 0xc6b40078, 0xcf400000, 0xc0004982, 0xce800000, 0x6c64a000, 0x44652000, 0x5a64000a,
+ 0xc0001012, 0xcb400000, 0xc2800002, 0x00000000, 0xc6740268, 0xc6340010, 0xc000497c, 0xcb000000,
+ 0xc6b41808, 0xc6b41b08, 0xc6b41c08, 0xc6b41d08, 0xc7341e08, 0xdd680001, 0x7e814000, 0x6eab2010,
+ 0x77294000, 0xc6b41f08, 0xc2800000, 0xc6b41908, 0xc3000080, 0x46f18000, 0xc0004982, 0xc9000000,
+ 0x47b14000, 0x880000ea, 0x41388000, 0xcd000000, 0xc7b41040, 0xc0004994, 0xce800000, 0xde100001,
+ 0x46108000, 0x84000098, 0xc1000000, 0xdd110040, 0x41388000, 0x412c8000, 0x5d100080, 0xc0004980,
+ 0xcd000000, 0xc1000002, 0xc000497c, 0xcd000000, 0xc5341e08, 0xdd500001, 0x7d008000, 0xc5373f08,
+ 0xc000497a, 0xc9000000, 0x42390000, 0x43adc000, 0x59100002, 0xcd000000, 0x80000038, 0x42390000,
+ 0x80000028, 0xc7341040, 0x41308000, 0xcd000000, 0x42310000, 0xc1000000, 0xc0004994, 0xcd000000,
+ 0xc0001012, 0xcf400000, 0xc000493c, 0xce000000, 0xc0004984, 0xcf800000, 0xc000497a, 0xca400000,
+ 0xc000497c, 0xca800000, 0x6c7ca000, 0x447de000, 0x5bfc4e20, 0xc0004976, 0xcac00000, 0xc0004978,
+ 0xca000000, 0x5eec0002, 0x84000072, 0x42250000, 0xc2400000, 0xc000497a, 0xce400000, 0x583c0000,
+ 0xc2c00000, 0xcac30040, 0x00000000, 0x00000000, 0x462d6000, 0x88000002, 0x00000000, 0xac280002,
+ 0xc000497a, 0xce000000, 0xc2000000, 0x5fa80000, 0x840001c2, 0x00000000, 0x6c508000, 0xc0004880,
+ 0x40100000, 0x58000018, 0xc9000000, 0x00000000, 0x00000000, 0x59100002, 0xcd000000, 0x583c000e,
+ 0xc2c00000, 0xcac00080, 0xc1000000, 0xdd532209, 0x42d16000, 0x6c508000, 0xc0004880, 0x40100000,
+ 0x5800001a, 0xc9000000, 0x00000000, 0x00000000, 0x412c8000, 0xcd000000, 0x990068d0, 0xd8580000,
+ 0xdbd80001, 0x00000000, 0x99006618, 0xc000491c, 0xc1400000, 0xc9420050, 0xc000491c, 0x99006ad0,
+ 0xc9400001, 0xc9800000, 0x00000000, 0x99006840, 0xd9580000, 0xd9980001, 0x00000000, 0xc161fffe,
+ 0x5955fffe, 0x15400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x98c06490, 0xd8580000, 0xdbd80001, 0xc4580000, 0xc121fffe, 0x5911fef4, 0x15000000, 0xace80003,
+ 0xc000493c, 0xcb400000, 0x00000000, 0xc3000000, 0xc7701080, 0x8000fff8, 0xc3000000, 0x583c0008,
+ 0xcf001080, 0x6e210000, 0x583c0034, 0xce000840, 0xc0004980, 0xcb800000, 0x583c0034, 0x00000000,
+ 0x6fba0000, 0xcf801040, 0xc000490e, 0xca000000, 0xc2c00002, 0x6ac56000, 0x72e10000, 0xce000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffc8, 0x00000000, 0xc1220002, 0xd90c0000, 0x5fa80000,
+ 0x840006fa, 0xc00049a8, 0xca000000, 0x583c000a, 0x00000000, 0xce000000, 0xc221fffe, 0x5a21fffe,
+ 0x583c000c, 0xce000000, 0xc0001004, 0xca000000, 0x00000000, 0x583c0012, 0x7e010000, 0xce000000,
+ 0xa97000c1, 0x00000000, 0x00000000, 0xa97200a9, 0xc0001010, 0xc2740000, 0xce401a08, 0x6c64a000,
+ 0x44652000, 0x5a64000a, 0x6e644000, 0xc0001012, 0xce400078, 0xc2600008, 0xce401040, 0xc27e0002,
+ 0xce401f08, 0xc2760002, 0xce401b08, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xa8e2ffc8, 0x00000000, 0xc1220002, 0xd90c0000, 0xc1000000, 0xdd110040, 0x5d100000, 0x840003fa,
+ 0xc0004982, 0xca000000, 0xc0004984, 0xca400000, 0xc2800000, 0xc361fffe, 0x5b75fffe, 0xa96afffb,
+ 0xdfec0000, 0xc6ec1080, 0x7b6d6000, 0x6c40a000, 0x44400000, 0x58004e20, 0x58000014, 0xcec00000,
+ 0xa972fffb, 0x5c000002, 0xcec00000, 0xc0001010, 0xc2f40002, 0xcec01a08, 0x6c6ca000, 0x446d6000,
+ 0x5aec000a, 0x6eec4000, 0xc0001012, 0xcec00078, 0xc0004994, 0xc9800000, 0xc1400000, 0xdd150040,
+ 0xc55c0000, 0x45588000, 0x00000000, 0xc59c0004, 0x5d1c0000, 0x840000ba, 0xc0001012, 0xc5d01040,
+ 0xcd001040, 0xc2f60002, 0xcec01b08, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xa8e2ffc8, 0x00000000, 0xc1220002, 0xd90c0000, 0x45588000, 0x8800003a, 0xc0004994, 0xcd000000,
+ 0xc0004980, 0xcbc00000, 0x42150000, 0xc0004982, 0xce000000, 0x5ffc0000, 0x84000200, 0x58880002,
+ 0xc3800000, 0xc0000a14, 0xcb840030, 0xc3c00000, 0xc0000a10, 0xb4b8fff8, 0x00000000, 0xc0800000,
+ 0xcbc40068, 0x6cb84000, 0x6fac8000, 0x6ffc4000, 0x42f96000, 0x43ed0000, 0xc3400000, 0xc6344068,
+ 0xc0004000, 0x40340000, 0xc2a1e000, 0xce800000, 0x5a200008, 0xc0004980, 0xcbc00000, 0xc3400000,
+ 0xc0004840, 0x6ff84010, 0xc7f40010, 0x40380000, 0xcb800000, 0xc2800000, 0x6f506000, 0x6b908010,
+ 0xc52c1840, 0xc3400000, 0xc6344068, 0xc0004000, 0x40340000, 0xcec00000, 0x5a200002, 0x5ffc0000,
+ 0x8400007a, 0xc0001010, 0xc62c0078, 0xcec00078, 0xc0001012, 0xc7ec1040, 0xcec01040, 0xc2f60002,
+ 0xcec01b08, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffc8, 0x00000000,
+ 0xc1220002, 0xd90c0000, 0xc0004994, 0xc100007e, 0x47d08000, 0xcd000000, 0x423d0000, 0xc0004982,
+ 0xce000000, 0xc0004994, 0xca000000, 0xc0004980, 0xca400000, 0x5e200000, 0x84000142, 0xc2000000,
+ 0xc2800000, 0x5a640002, 0xc6684030, 0xc0004982, 0xcb000000, 0xc0004000, 0xc2c00000, 0xc72c4068,
+ 0x402c0000, 0x6e67c000, 0x6e67c010, 0x5ee40002, 0x84000022, 0x5ee40004, 0x84000032, 0x5ee40006,
+ 0x84000042, 0x00000000, 0x80000048, 0xce0000c0, 0x5aa80002, 0x5b300006, 0x80000028, 0xce000080,
+ 0x5aa80002, 0x5b300004, 0x80000008, 0xce000040, 0x5aa80002, 0x5b300002, 0x5ee80020, 0x8400003a,
+ 0xc0004000, 0xc2c00000, 0xc72c4068, 0x402c0000, 0xce000000, 0x5aa80002, 0x5b300008, 0x8000ffa0,
+ 0x00000000, 0x80000028, 0x583c000a, 0xd7c00000, 0xc0001004, 0xca400000, 0x00000000, 0x583c000c,
+ 0xce400000, 0xc000497a, 0xca400000, 0xc2800002, 0xc0000a28, 0xc6780930, 0xc6b80808, 0xcf840838,
+ 0x6c7ca000, 0x447de000, 0x5bfc4e20, 0x583c0034, 0xc4900040, 0xcd000040, 0x8000e400, 0x6c6c8000,
+ 0x6c544000, 0x42d56000, 0x5aec4a00, 0xc0000824, 0xca040000, 0x6ca48000, 0x42492000, 0xc3000000,
+ 0xc3400000, 0x42250000, 0x58204000, 0xca400000, 0x5a200002, 0xda240001, 0xc2800000, 0xc000495e,
+ 0xce800000, 0xda600000, 0xc2800000, 0xc66b0040, 0xdaa80000, 0x582c0010, 0x6f206010, 0x40200000,
+ 0xd8280001, 0xca000000, 0xc2400000, 0xc7240018, 0x6e644000, 0xda640000, 0x6a254010, 0xc3c00000,
+ 0xc6bc0020, 0xc3800000, 0xdea00000, 0x5e60001e, 0x84000012, 0x5e6001e0, 0x84000002, 0x00000000,
+ 0x80000068, 0xc7f80000, 0x5e7c0008, 0x84000052, 0x5bbc0002, 0x5e780008, 0x84000010, 0x5b740002,
+ 0xc0004960, 0xcf000000, 0x80000018, 0x5e780006, 0x8800000a, 0xc2800002, 0xc000495e, 0xce800000,
+ 0xde800001, 0xca800000, 0xde600000, 0xc240001e, 0x6a612000, 0x7e412000, 0x76694000, 0x6ba12000,
+ 0x72694000, 0xce800000, 0x5e300080, 0x840000a2, 0xc2000000, 0xc7200010, 0x5e600000, 0x84000040,
+ 0xde600001, 0x58204000, 0xca400000, 0x5a200002, 0xda240001, 0xc2800000, 0xc66b0040, 0xdaa80000,
+ 0xda600000, 0x80000020, 0xc2800000, 0x6e206000, 0xde240000, 0x6a610000, 0xc62b0040, 0xdaa80000,
+ 0x5b300002, 0x8000fdc8, 0xc2000000, 0x582c0020, 0xca020080, 0x00000000, 0xc2400000, 0x5a200002,
+ 0xc6241080, 0xce401080, 0xc000480e, 0xca800000, 0x5e740000, 0x84000148, 0x46292000, 0x8800dec8,
+ 0xc2400000, 0xc0000808, 0xca440018, 0x582c0010, 0xc1400000, 0xcd400001, 0xcd400001, 0xcd400001,
+ 0xcd400001, 0xcd400001, 0xcd400001, 0xcd400001, 0xcd400001, 0xcd400020, 0x582c0020, 0xce001080,
+ 0xc2000010, 0x5a640002, 0xb624fff8, 0x00000000, 0xc2400000, 0xc6600018, 0xc0000808, 0xce040018,
+ 0xc0004956, 0xca400000, 0xc11c0000, 0xc000082c, 0xcd040e08, 0xc6600930, 0xc2400000, 0xc6600030,
+ 0xc0000838, 0xce040000, 0xc2400002, 0xc0004958, 0xce400000, 0xc11c0002, 0xc000082c, 0xcd040e08,
+ 0x8000dd80, 0xc000495e, 0xca000000, 0x5e740002, 0x8400dd60, 0x5e200000, 0x8400dd50, 0xc0004960,
+ 0xca400000, 0xc2200004, 0x582c0002, 0xce001010, 0xc2000082, 0x46610000, 0xc6280038, 0xc0000810,
+ 0xce840038, 0x99006f68, 0x582c0002, 0xc9400000, 0xc1a20000, 0x5e640000, 0x8400feb8, 0x00000000,
+ 0x8000dcc0, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00, 0xc000487c, 0xc8040000, 0x00000000,
+ 0x00000000, 0x40080000, 0xcb800000, 0xc4240000, 0x00000000, 0xa7860180, 0xc3c00000, 0xc2000000,
+ 0x582c000c, 0xca010040, 0x6c508000, 0xc0004880, 0x40100000, 0x58000016, 0xc9000000, 0x00000000,
+ 0x00000000, 0x59100002, 0xcd000000, 0x5a200002, 0x582c000c, 0xc6100840, 0xcd000840, 0x5e600002,
+ 0x84000008, 0xc2200004, 0x582c0002, 0xce001010, 0x5e600008, 0x84000048, 0xc2200002, 0x582c0002,
+ 0xce001010, 0x582c000c, 0xcfc00840, 0xc2220002, 0xc0000a14, 0xce041108, 0xc22001a2, 0xc0000a1c,
+ 0xce041040, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00, 0x582c0004, 0xcb000000, 0xc3400000,
+ 0x00000000, 0xa7060008, 0xcf400308, 0xc3100002, 0xc0000838, 0xcf040808, 0x582c000c, 0xcf401008,
+ 0x8000dac0, 0x582c000c, 0xcfc00840, 0xc2000000, 0xc7a06018, 0x5e200000, 0x84001e18, 0x6c6c8000,
+ 0x6c544000, 0x42d56000, 0x5aec4a00, 0xc000487c, 0xc8040000, 0x00000000, 0x00000000, 0x40080000,
+ 0xcb800000, 0xc4240000, 0x00000000, 0xc2800000, 0xc3400000, 0xc7b5c038, 0xc0004970, 0xcf400000,
+ 0xc2400000, 0xc7a4e038, 0xc000496c, 0xce400000, 0xc3000000, 0xc7b00018, 0xc3c00004, 0xc000496e,
+ 0xcfc00000, 0x582c000c, 0xca000000, 0xc2400002, 0xc0004964, 0xce400000, 0xa6200352, 0x00000000,
+ 0x5e700004, 0x840000d2, 0x5e700006, 0x84000068, 0xc2000002, 0x582c0002, 0xce000008, 0xc0000a14,
+ 0xce841108, 0x6c508000, 0xc0004880, 0x40100000, 0x58000014, 0xc9000000, 0x00000000, 0x00000000,
+ 0x59100002, 0xcd000000, 0x80001c68, 0x5e70000a, 0x84000028, 0xc2000000, 0x582c0002, 0xce000008,
+ 0xc2220002, 0xc0000a14, 0xce041108, 0x8000ff58, 0x5e700008, 0x84000210, 0xc2200002, 0x582c000c,
+ 0xce001008, 0x6c508000, 0xc0004880, 0x40100000, 0x58000012, 0xc9000000, 0x00000000, 0x00000000,
+ 0x59100002, 0xcd000000, 0x5e340002, 0x6c508000, 0xc0004880, 0x40100000, 0x58000010, 0xc9000000,
+ 0x00000000, 0x00000000, 0x41208000, 0xcd000000, 0xc0000a14, 0xce841108, 0xc0004970, 0xcb400000,
+ 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00, 0x582c000e, 0xc4900040, 0xcd000040, 0x582c000e,
+ 0xc7500840, 0xcd000840, 0xc2800000, 0x582c0004, 0xce801080, 0x582c0004, 0xce800008, 0xc00049a0,
+ 0xca400000, 0x00000000, 0x582c0006, 0xce400000, 0xc261fffe, 0x5a65fffe, 0x582c0024, 0xce400000,
+ 0xc2060002, 0x582c0004, 0xce000308, 0xc2400002, 0xc0004958, 0xce400000, 0xc0004878, 0xc8040000,
+ 0x6c908000, 0x41088000, 0x40100000, 0x58000020, 0xc9000000, 0x582c0026, 0x00000000, 0xcd000000,
+ 0x800019f8, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000016, 0xc9000000, 0x00000000,
+ 0x00000000, 0x59100002, 0xcd000000, 0x8000fad8, 0x5e700000, 0x840000a8, 0xc3400082, 0xc0004970,
+ 0xcf400000, 0xc2400080, 0xc000496c, 0xce400000, 0xc3c00002, 0xc000496e, 0xcfc00000, 0xc2400000,
+ 0xc0004964, 0xce400000, 0xc0004878, 0xc8040000, 0x6c908000, 0x41088000, 0x40100000, 0x58000020,
+ 0xc9000000, 0x582c0026, 0x00000000, 0xcd000000, 0x80000060, 0x5e700002, 0x84000040, 0xc3400082,
+ 0xc0004970, 0xcf400000, 0xc3c00004, 0xc000496e, 0xcfc00000, 0xc2200000, 0x582c000c, 0xce001008,
+ 0x80000018, 0x5e700004, 0x8400fe68, 0xc2600002, 0x582c000c, 0xce401008, 0xc0000a14, 0xce841108,
+ 0xc000496c, 0xca400000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000012, 0xc9000000, 0x00000000,
+ 0x00000000, 0x59100002, 0xcd000000, 0xc000496e, 0xcbc00000, 0x00000000, 0x00000000, 0x47f50000,
+ 0x46610000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000010, 0xc9000000, 0x00000000, 0x00000000,
+ 0x41208000, 0xcd000000, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00, 0x582c0004, 0xca000000,
+ 0x00000000, 0x00000000, 0xa60016ea, 0x00000000, 0x6c6c8000, 0x6c544000, 0x42d56000, 0x5aec4a00,
+ 0xc3000000, 0x582c0004, 0xcf000308, 0x582c0000, 0xcb002018, 0xc3c00000, 0x582c0004, 0xcbc20080,
+ 0xc000491a, 0xcf000000, 0xc000493c, 0xcfc00000, 0x582c0008, 0xcb800000, 0x582c000a, 0xca400000,
+ 0xc0004930, 0xcf800000, 0xc0004932, 0xce400000, 0x5ffc0000, 0x840001d8, 0x00000000, 0xa7be00e2,
+ 0xc2800000, 0x6f206000, 0x47210000, 0x5a204c80, 0x5820000c, 0xca800028, 0x00000000, 0x00000000,
+ 0x5ea80000, 0x840000fa, 0x00000000, 0xc161fffe, 0x5955fffe, 0x15400000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x99006330, 0xc000491a, 0xc9400000, 0x00000000,
+ 0xc121fffe, 0x5911fef4, 0x15000000, 0xc0004930, 0xcb800000, 0xc0004932, 0xca400000, 0xc4781110,
+ 0xc0004930, 0xcf800000, 0x582c0008, 0xcf800000, 0x582c000a, 0xce400000, 0xc7b6e110, 0x582c0004,
+ 0xcf400110, 0x80000078, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x5800000c, 0xc9000000,
+ 0x00000000, 0x00000000, 0x59100002, 0xcd000000, 0xc2000002, 0x582c0004, 0xce000008, 0xc0000838,
+ 0xc2500002, 0xce440808, 0x80001430, 0x6c7c8000, 0x6c544000, 0x43d5e000, 0x5bfc4a00, 0x583c0006,
+ 0xca000000, 0xc00049a2, 0x00000000, 0xca800001, 0xca400000, 0xc0001008, 0xce800000, 0xc0001006,
+ 0xce400000, 0xc000100a, 0xce000000, 0xc2400006, 0xc0001000, 0xce400000, 0xc2600982, 0x5a643b6e,
+ 0xc0001002, 0xce400000, 0x583c0024, 0xca400000, 0x00000000, 0xc0001004, 0xce400000, 0xc0004862,
+ 0xc2000000, 0xca000080, 0xc360fffe, 0xc0004862, 0xce000000, 0xc0000824, 0xcb440068, 0x00000000,
+ 0xc000100e, 0xcf400000, 0xc3801600, 0xc2400200, 0x6e644000, 0xc6781078, 0xc000100c, 0xcf800000,
+ 0xc3200a00, 0xc0001010, 0xcf001818, 0xc2e06200, 0xc0001012, 0xcec01840, 0xc2000000, 0x583c0004,
+ 0xca002010, 0xc2800000, 0xc0004966, 0xce000000, 0xc6240000, 0xc3000000, 0xc000496a, 0xcf000000,
+ 0xc0004974, 0xcf000000, 0xc000493c, 0xcb400000, 0x583c000e, 0x00000000, 0x5f740000, 0x84000168,
+ 0xc3400000, 0xcb410040, 0xc3000002, 0xc000496a, 0x5fb40080, 0x8400013a, 0xcf000000, 0x583c000e,
+ 0xc2c00000, 0xcac00040, 0xc3800080, 0x4779c000, 0xc0004974, 0xcf800000, 0xc0001012, 0x6fba0000,
+ 0xcf801040, 0x6fba0010, 0x43a5c000, 0x5b380006, 0x6f284010, 0xc7a40010, 0x6eec4000, 0x6ef08000,
+ 0x432d8000, 0x43358000, 0x5b300008, 0xc0001012, 0xc7100078, 0xcd000078, 0xc2000200, 0xc2c00000,
+ 0xdf6d0050, 0x46e16000, 0x46ad6000, 0x8800ffca, 0xc2000000, 0xc0004862, 0xca000268, 0x00000000,
+ 0x583c0004, 0xca002010, 0xc3360002, 0xc0001010, 0xce000078, 0xc0001012, 0xcf001b08, 0xc0004974,
+ 0xcb800000, 0x00000000, 0x00000000, 0x5fb80000, 0x8400002a, 0x00000000, 0x00000000, 0x00000000,
+ 0xa8e2ffc8, 0x00000000, 0xc1220002, 0xd90c0000, 0xc000496c, 0xcac00000, 0x00000000, 0x00000000,
+ 0x426dc000, 0x5b380006, 0x6f304010, 0xc7a40010, 0xc0004968, 0xce400000, 0xc000496e, 0xcb400000,
+ 0x6ca44000, 0x6e608000, 0x42250000, 0x5a200006, 0x42350000, 0xc0001012, 0xc6100078, 0xcd000078,
+ 0x6eee0000, 0xcec01040, 0xc2000200, 0xc2c00000, 0xdf6d0050, 0x46e16000, 0x42b14000, 0x46ad6000,
+ 0x8800ffc2, 0xc000493c, 0xcb400000, 0xc0000838, 0xc3100002, 0x5f740000, 0x84000048, 0xcf040808,
+ 0xc0004974, 0xcb800000, 0x00000000, 0x00000000, 0x5fb80000, 0x84000052, 0xc0001012, 0xc3360002,
+ 0xcf001b08, 0x80000088, 0x583c0022, 0xcb400000, 0xc0004862, 0xca000000, 0x00000000, 0xc0005600,
+ 0x40200000, 0xcf400000, 0xc2000000, 0xc0004862, 0xca000268, 0x00000000, 0x583c0004, 0xca002010,
+ 0xc3360002, 0xc0001010, 0xce000078, 0xc0001012, 0xcf001b08, 0xc0004968, 0xcbc00000, 0xc0004964,
+ 0xca400000, 0xc7e00000, 0x00000000, 0x5e640000, 0x8400fffa, 0xc2000000, 0xc0004974, 0xca400000,
+ 0xc000496c, 0xca800000, 0xc000493c, 0xcb800000, 0x42698000, 0x00000000, 0x43b1a000, 0x5ef40080,
+ 0x88000182, 0xc0004966, 0xcac00000, 0x6c648000, 0x6c544000, 0x42552000, 0x5a644a00, 0x58240000,
+ 0x436da000, 0x4635a000, 0xc2400000, 0xca420080, 0x00000000, 0x00000000, 0x47652000, 0x8800010a,
+ 0x432d8000, 0x46318000, 0x8800fff8, 0xc3000000, 0x5b300006, 0x6f304010, 0xc000493a, 0xcf000000,
+ 0xc0004932, 0xc2400000, 0xca4000e0, 0x00000000, 0x6fb84010, 0x42792000, 0xc000491e, 0xce400000,
+ 0xc0004862, 0xca800000, 0x00000000, 0xc2c0000a, 0xc6e80d78, 0xc7281050, 0xc000491c, 0xce800000,
+ 0x6c708000, 0x6c544000, 0x43158000, 0x5b304a00, 0x6f760000, 0x58300004, 0xcf401080, 0x6ffc2000,
+ 0x58300004, 0xcfc00110, 0x80000168, 0x6c708000, 0x6c544000, 0x43158000, 0x5b304a00, 0xc2800002,
+ 0x58300004, 0xce800008, 0x6c508000, 0xc0004880, 0x40100000, 0x5800000e, 0xc9000000, 0x00000000,
+ 0x00000000, 0x59100002, 0xcd000000, 0xc0004816, 0xc8000000, 0x00000000, 0x00000000, 0x5c000000,
+ 0x84000072, 0xc11c0000, 0xc000082c, 0xcd040e08, 0xc0004816, 0xc8000000, 0x00000000, 0x00000000,
+ 0x5c000000, 0x84000012, 0x00000000, 0x00000000, 0x00000000, 0x8000ffa0, 0xc11c0002, 0xc000082c,
+ 0xcd040e08, 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffc8, 0x00000000, 0xc1220002, 0xd90c0000,
+ 0x80000a80, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xa8e2ffc8, 0x00000000, 0xc1220002,
+ 0xd90c0000, 0xc0004964, 0xca000000, 0x6c7c8000, 0x6c544000, 0x43d5e000, 0x5bfc4a00, 0xdfe40000,
+ 0x5e200002, 0x840006a0, 0x00000000, 0x583c0004, 0xc2800000, 0xca820080, 0xc0004930, 0xcac00000,
+ 0x00000000, 0x00000000, 0x6eece000, 0x6eefc010, 0x46e8a000, 0xc1000000, 0xdd500041, 0x6d106010,
+ 0x4514a000, 0xc1000000, 0xdd514209, 0x4514c000, 0xa9500181, 0xc00049a6, 0xca000000, 0xa94a0003,
+ 0x00000000, 0x6e660000, 0x6e660010, 0x46252000, 0x8400014a, 0x00000000, 0xc0004812, 0xc8000000,
+ 0x00000000, 0x00000000, 0x5c000000, 0x84000072, 0xc11c0000, 0xc000082c, 0xcd040e08, 0xc0004812,
+ 0xc8000000, 0x00000000, 0x00000000, 0x5c000000, 0x84000012, 0x00000000, 0x00000000, 0x00000000,
+ 0x8000ffa0, 0xc11c0002, 0xc000082c, 0xcd040e08, 0x6c508000, 0xc0004880, 0x40100000, 0x58000004,
+ 0xc9000000, 0x00000000, 0x00000000, 0x59100002, 0xcd000000, 0x6c508000, 0xc0004880, 0x40100000,
+ 0x58000006, 0xc9000000, 0x00000000, 0x00000000, 0x41148000, 0xcd000000, 0x800007d0, 0x00000000,
+ 0xa95203a1, 0xc0001004, 0xcb800000, 0xc3400000, 0xdd740041, 0x5f740000, 0x840000b8, 0xc1218e08,
+ 0x5911baf6, 0x47908000, 0x8400035a, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000008,
+ 0xc9000000, 0x00000000, 0x00000000, 0x59100002, 0xcd000000, 0x6c508000, 0xc0004880, 0x40100000,
+ 0x5800000a, 0xc9000000, 0x00000000, 0x00000000, 0x41148000, 0xcd000000, 0x800006d0, 0x00000000,
+ 0xc000496c, 0xcb000000, 0x583c0026, 0xcac00000, 0xc0004878, 0xc8040000, 0x6c908000, 0x41088000,
+ 0x40100000, 0x58000002, 0xca800000, 0x00000000, 0x00000000, 0x6ea90000, 0x5d300008, 0x88000032,
+ 0x59300002, 0xc3000000, 0xc5300010, 0x6d104010, 0x40100000, 0xca800000, 0x5c000002, 0xcac00000,
+ 0x5d300000, 0x84000022, 0x6f246000, 0x6ae56000, 0xc1000040, 0x46512000, 0x6aa54010, 0x42e96000,
+ 0x583c0026, 0xcec00000, 0xc1218e08, 0x5911baf6, 0xc0001004, 0xcd000000, 0x593c0026, 0xc000100e,
+ 0xcd000068, 0xc1340000, 0xc0001010, 0xcd001a08, 0xc1200008, 0xa94a0003, 0xc0001012, 0xc1200004,
+ 0x59100004, 0xcd0000c0, 0xc1360002, 0xcd001b08, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xa8e2ffc8, 0x00000000, 0xc1220002, 0xd90c0000, 0xc0001004, 0xc9000000, 0x00000000,
+ 0x00000000, 0x47908000, 0x8400009a, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000008,
+ 0xc9000000, 0x00000000, 0x00000000, 0x59100002, 0xcd000000, 0x6c508000, 0xc0004880, 0x40100000,
+ 0x5800000a, 0xc9000000, 0x00000000, 0x00000000, 0x41148000, 0xcd000000, 0x80000410, 0x00000000,
+ 0x6c508000, 0xc0004880, 0x40100000, 0x58000000, 0xc9000000, 0x00000000, 0x00000000, 0x59100002,
+ 0xcd000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000002, 0xc9000000, 0x00000000, 0x00000000,
+ 0x41148000, 0xcd000000, 0xc0004930, 0xcd800080, 0xc3000000, 0x583c0008, 0xcf000000, 0x800000e8,
+ 0xc0001004, 0xca000000, 0x583c0006, 0xce400000, 0x583c0024, 0xce000000, 0xc0004814, 0xc8000000,
+ 0x00000000, 0x00000000, 0x5c000000, 0x8400008a, 0xc001fffe, 0x46400000, 0x84000070, 0xc11c0000,
+ 0xc000082c, 0xcd040e08, 0xc0004814, 0xc8000000, 0x00000000, 0x00000000, 0x5c000000, 0x84000012,
+ 0x00000000, 0x00000000, 0x00000000, 0x8000ffa0, 0xc11c0002, 0xc000082c, 0xcd040e08, 0xc0004862,
+ 0xc2000000, 0xca000080, 0xc000493a, 0xca400000, 0x00000000, 0x00000000, 0x42254000, 0x5ee80200,
+ 0x8800fffa, 0xc6e80000, 0xc0004000, 0x58001600, 0x40280000, 0xcb800000, 0x00000000, 0x583c0022,
+ 0xcf800000, 0xc0004862, 0xce800080, 0xc0001406, 0xcac00000, 0xc2800002, 0x00000000, 0xc66c1050,
+ 0xc6ac0a08, 0xcec00000, 0xc2000000, 0xdf600040, 0x5e600080, 0x8400ffd2, 0xc000491c, 0xca400000,
+ 0xc000491e, 0xca800000, 0x99006840, 0xda580000, 0xda980001, 0x00000000, 0xc0004964, 0xcbc00000,
+ 0x00000000, 0x00000000, 0x5ffc0000, 0x840000ea, 0xc2000000, 0xdf610050, 0x5e6001fe, 0x8800ffd0,
+ 0xc000491a, 0xc9800000, 0xc0004862, 0xc9400000, 0x6d9c6000, 0x459ce000, 0x59dc4c80, 0x990066a0,
+ 0xd9580000, 0xd9980001, 0xd9d40000, 0x99006618, 0xc000491c, 0xc1400000, 0xc9420050, 0xc2000000,
+ 0xdf600040, 0x5e600080, 0x8400ffd2, 0xc000491c, 0xca400000, 0xc000491e, 0xca800000, 0x99006840,
+ 0xda580000, 0xda980001, 0x00000000, 0xc0004970, 0xcb400000, 0x00000000, 0x00000000, 0x5e740082,
+ 0x8400e498, 0x00000000, 0x8000bc70, 0x00000000, 0x6c508000, 0xc0004880, 0x40100000, 0x58000016,
+ 0xc9000000, 0x00000000, 0x00000000, 0x59100002, 0xcd000000, 0x8000e0c8, 0x6c6c8000, 0x6c544000,
+ 0x42d56000, 0x5aec4a00, 0xc000487c, 0xc8040000, 0x00000000, 0x00000000, 0x40080000, 0xca000000,
+ 0xc4240000, 0x00000000, 0xa6060108, 0xc3c00000, 0xc2000000, 0x582c000c, 0xca010040, 0x00000000,
+ 0x00000000, 0x5a200002, 0xc6100840, 0xcd000840, 0x5e60000e, 0x8400bb58, 0xc2200000, 0x582c0002,
+ 0xce001010, 0x582c000c, 0xcfc00840, 0x582c0020, 0xcfc01080, 0x582c0010, 0xc1400000, 0xcd400001,
+ 0xcd400001, 0xcd400001, 0xcd400001, 0xcd400001, 0xcd400001, 0xcd400001, 0xcd400001, 0xcd400020,
+ 0xc000481a, 0xca000000, 0x00000000, 0x00000000, 0x5a200002, 0xce000000, 0x8000ba90, 0xc2200004,
+ 0x582c0002, 0xce001010, 0x582c000c, 0xcfc00840, 0x99006f68, 0x582c0002, 0xc9400000, 0xc1a20000,
+ 0x8000ba40, 0xc3e1fffe, 0x597dfffe, 0x593dfef4, 0x94000001, 0x00000000, 0x00000000, 0x00000000,
+ 0xc0800000, 0xdf4b0040, 0xc0004900, 0xcb800000, 0xc2000000, 0xc000490a, 0xa78000b0, 0xcbc00000,
+ 0xc1000000, 0xd9000001, 0xc1000002, 0xd90c0000, 0x6ff46000, 0x47f5a000, 0x5b744c80, 0xc2400000,
+ 0x58340004, 0xca400080, 0xc0004900, 0xce000008, 0x5a640002, 0x58340004, 0xc6500080, 0xcd000080,
+ 0xc0004914, 0xca400000, 0xc2000002, 0x6a3d0000, 0x72252000, 0xce400000, 0xc0000408, 0xce000000,
+ 0xa78200a8, 0xc0004908, 0xcbc00000, 0xc1000000, 0xd9000001, 0xc1000002, 0xd90c0000, 0x6ff4a000,
+ 0x47f5a000, 0x5b744e20, 0xc2800000, 0x58340006, 0xca800080, 0xc2000000, 0xc0004900, 0xce000108,
+ 0x5ea80002, 0x58340006, 0xc6900080, 0xcd000080, 0x5a7c0020, 0xc2000002, 0x6a250000, 0xc0000408,
+ 0xce000000, 0xdca80001, 0x5ea80000, 0x8400a7f8, 0x00000000, 0xa4800210, 0x00000000, 0xc3c00000,
+ 0xc000140e, 0xcbc00020, 0xc3400000, 0xc2400000, 0x6ff86000, 0x47f9c000, 0x5bb84c80, 0x58380008,
+ 0xcb400080, 0x58380006, 0xca400080, 0x5f740002, 0x58380008, 0xc7500080, 0xcd000080, 0xc2000000,
+ 0x58380004, 0xca020080, 0xc3000000, 0x5838000c, 0xcb000028, 0x5a640002, 0x46250000, 0x8400fff8,
+ 0xc2400000, 0x58380006, 0xc6500080, 0xcd000080, 0xc2000000, 0x5838000a, 0xca020080, 0x5b300002,
+ 0x5838000c, 0xc7100028, 0xcd000028, 0xc2420020, 0x5a200004, 0x46612000, 0x8400fff8, 0xc2000000,
+ 0x5838000a, 0xc6101080, 0xcd001080, 0xc000498c, 0xca400000, 0xc2000002, 0x6a3d0000, 0x72252000,
+ 0xce400000, 0x5f740000, 0x84000028, 0xc0004912, 0xca000000, 0xc2c00002, 0x6afd6000, 0x7ec16000,
+ 0x76e10000, 0xce000000, 0x5f300020, 0x84000028, 0xc0004924, 0xca000000, 0xc2c00002, 0x6afd6000,
+ 0x7ec16000, 0x76e10000, 0xce000000, 0xa4820050, 0xc2400000, 0xc000140e, 0xca408020, 0xc2000002,
+ 0xc0004900, 0xce000008, 0xc000490a, 0xce400000, 0xc1000000, 0xd9000001, 0xd8400080, 0xc1000004,
+ 0xd9000001, 0xa48402b8, 0x00000000, 0xc3c00000, 0xc000140e, 0xcbc10020, 0xc2800000, 0xc2000000,
+ 0x6ff8a000, 0x47f9c000, 0x5bb84e20, 0x58380036, 0xca800080, 0x58380006, 0xca020080, 0xc3400000,
+ 0x58380036, 0xcb420080, 0x5aa80002, 0x46290000, 0x8400fff8, 0xc2800000, 0x58380036, 0xc6900080,
+ 0xcd000080, 0x5f740002, 0x58380036, 0xc7501080, 0xcd001080, 0xc000498e, 0xca400000, 0xc2000002,
+ 0x6a3d0000, 0x72252000, 0xce400000, 0xc000492a, 0xca800000, 0x5e740000, 0x84000028, 0xc0004910,
+ 0xca000000, 0xc2c00002, 0x6afd6000, 0x7ec16000, 0x76e10000, 0xce000000, 0x6abd4010, 0xa6800112,
+ 0x00000000, 0x5838003a, 0xca000000, 0x58000002, 0xca400000, 0x5838000e, 0x00000000, 0xce000001,
+ 0xce400000, 0xc2400000, 0xdd250040, 0xc1000080, 0x46508000, 0xc2400000, 0xc6240080, 0x45250000,
+ 0x00000000, 0xc5240004, 0x5d240078, 0xc1000078, 0xc5240004, 0xc6600080, 0x5c000002, 0xce000080,
+ 0xc000492a, 0xca000000, 0xc2c00002, 0x6afd6000, 0x72e10000, 0xce000000, 0xc000492c, 0xca000000,
+ 0xc2c00002, 0x6afd6000, 0x72e10000, 0xce000000, 0x80000028, 0xc000492c, 0xca000000, 0xc2c00002,
+ 0x6afd6000, 0x7ec16000, 0x76e10000, 0xce000000, 0xa4880068, 0xc2c00000, 0xc000140e, 0xcac20020,
+ 0xc000490e, 0xca400000, 0xc2000002, 0x6a2d0000, 0x7e010000, 0x76252000, 0xce400000, 0xc0004990,
+ 0xca400000, 0xc2000002, 0x6a2d0000, 0x72252000, 0xce400000, 0xa4860050, 0xc2400000, 0xc000140e,
+ 0xca418020, 0xc2020002, 0xc0004900, 0xce000108, 0xc0004908, 0xce400000, 0xc1000000, 0xd9000001,
+ 0xd8400080, 0xc1000004, 0xd9000001, 0xc0001408, 0xcc800000, 0xc10e0002, 0xd90c0000, 0x8000f738,
+ 0xdfbc0001, 0xc0004992, 0x99006fa8, 0xc9400000, 0xc7d80000, 0x00000000, 0xc5700000, 0x5ef00020,
+ 0x88000140, 0x6f346000, 0x4735a000, 0x5b744c80, 0x58340008, 0xc2400000, 0xca400080, 0x00000000,
+ 0xc2000000, 0x5a640002, 0xc6500080, 0xcd000080, 0x58340004, 0xca000080, 0x00000000, 0x00000000,
+ 0x5e200002, 0xc6100080, 0xcd000080, 0xc0004912, 0xca800000, 0xc2400002, 0x6a712000, 0x72694000,
+ 0xce800000, 0x5e200000, 0x8400003a, 0xc000480a, 0xca000000, 0xc0000408, 0xca800000, 0x76610000,
+ 0x00000000, 0x72294000, 0xce800000, 0x80000020, 0xc0004914, 0xca000000, 0x7e412000, 0x00000000,
+ 0x76610000, 0xce000000, 0x800000b0, 0x6ef4a000, 0x46f5a000, 0x5b744e20, 0x58340036, 0xc2400000,
+ 0xca420080, 0x00000000, 0xc2000000, 0x5a640002, 0xc6501080, 0xcd001080, 0x58340006, 0xca000080,
+ 0x00000000, 0x00000000, 0x5a200002, 0xc6100080, 0xcd000080, 0xc0004910, 0xca400000, 0xc2000002,
+ 0x6a2d0000, 0x72252000, 0xce400000, 0xc2000002, 0x6a310000, 0xc000042a, 0xce000000, 0xc1040002,
+ 0xd90c0000, 0x00000000, 0x8000f4a0, 0x00000000, 0xc4980930, 0x9d000000, 0xc5580030, 0xc0000838,
+ 0xcd840000, 0xc1440200, 0xc1c01600, 0xc55c1078, 0xc000100e, 0x9d000000, 0xcd800000, 0xc000100c,
+ 0xcdc00000, 0xc0004862, 0xc9c00000, 0x00000000, 0x00000000, 0xd9d80001, 0xc0005600, 0x401c0000,
+ 0x5dc05800, 0x8800fffa, 0x5c000200, 0xcd800000, 0xc1f0000a, 0x71d4a000, 0xdd980000, 0xdd9c0001,
+ 0x41d8e000, 0xc5d40268, 0xc0001010, 0xcd400000, 0x6c9c8000, 0x449ce000, 0x449ce000, 0x59dc0004,
+ 0xc1601260, 0xc5d40268, 0x9d000000, 0xc0001012, 0xcd400000, 0x00000000, 0x00000000, 0xd9580000,
+ 0x6d586000, 0x4558c000, 0x59984c80, 0xd9980001, 0x5818000a, 0xc1800000, 0xc9800080, 0xc0005400,
+ 0x6d5ca000, 0x401c0000, 0x40180000, 0xc9400000, 0x58000002, 0x00000000, 0xc9c00000, 0xc0004930,
+ 0xcd400000, 0xc0004932, 0xcdc00000, 0x59980004, 0xc1c20020, 0xb59cfff8, 0x00000000, 0xc1800000,
+ 0xdd9c0001, 0x581c000a, 0xcd800080, 0x581c000c, 0xc1800000, 0xc9800028, 0xc1c00002, 0xdd940000,
+ 0x69d4e000, 0x5d980002, 0xcd800028, 0xc0004924, 0xc9800000, 0x00000000, 0x9d000000, 0x00000000,
+ 0x71d8c000, 0xcd800000, 0xc000492a, 0xc9400000, 0xc1c00002, 0x69d8e000, 0x7dc0c000, 0x7594a000,
+ 0xcd400000, 0xc000492c, 0xc9400000, 0xdd800001, 0x5800003a, 0x75d4a000, 0x840000f0, 0xc9400001,
+ 0xc9800000, 0xdd800001, 0x5800000e, 0x00000000, 0xcd400001, 0xcd800000, 0xc1800000, 0xdd190040,
+ 0xc1000080, 0x45908000, 0xc1800000, 0xc5580080, 0x4518a000, 0x00000000, 0xc5180004, 0x5d180078,
+ 0xc1000078, 0xc5180004, 0xc5940080, 0x5c000002, 0xcd400080, 0xc000492c, 0xc9400000, 0xc000492a,
+ 0xc9800000, 0x71d4a000, 0xc000492c, 0xcd400000, 0x71d8c000, 0xc000492a, 0xcd800000, 0x9cc00000,
+ 0x00000000, 0x00000000, 0x00000000, 0xc0004862, 0xc9800000, 0x00000000, 0xc1c00200, 0x4194c000,
+ 0x45d8e000, 0x8800fffa, 0xc5d80000, 0xc0004862, 0xcd800000, 0xc0001406, 0xc9800000, 0xc1c00002,
+ 0x9d000000, 0xc5d80a08, 0xc5581050, 0xcd800000, 0xc0004930, 0xc9800000, 0xc0004932, 0xc9c00000,
+ 0xc140000e, 0xc5581c20, 0xdd940000, 0xc0005600, 0x40140000, 0x5d405800, 0x8800fffa, 0x5c000200,
+ 0xcd800000, 0x58000002, 0x5d405800, 0x8800fffa, 0x5c000200, 0xcdc00000, 0xdd540000, 0xc1c00000,
+ 0x58140006, 0xc9c20080, 0xc1800000, 0x58140000, 0xc98000e0, 0x6ddc2000, 0xc000491e, 0x41d8e000,
+ 0xcdc00000, 0xdd980000, 0xc1c00022, 0xc5d80d78, 0xdd940001, 0xc5581c20, 0xc000491c, 0xcd800000,
+ 0xdd540000, 0xc1c00000, 0x58140006, 0xc9c20080, 0xc1800000, 0x58140004, 0xc9820080, 0x00000000,
+ 0x59dc0002, 0x459cc000, 0x8400fff8, 0xc1c00000, 0x9d000000, 0x58140006, 0xc5d81080, 0xcd801080,
+ 0xc0004860, 0xc9400000, 0xc1820080, 0xc1d00002, 0x58146b00, 0xd5800000, 0x58000002, 0xd5800001,
+ 0x59540004, 0xb558fff8, 0xc0004860, 0xc1400000, 0xcd400000, 0xdd980001, 0x9d000000, 0xdd940000,
+ 0xc0001404, 0xcdc00808, 0xc1c00000, 0xc1800200, 0x5d980004, 0xdf5d0050, 0x45d8a000, 0x8800ffda,
+ 0xdd800001, 0x5800000e, 0x00000000, 0xc9400001, 0xc9800000, 0xc1c00002, 0xc5d43f08, 0xc5d81e08,
+ 0xc0004862, 0xc9c00000, 0x00000000, 0x00000000, 0x581c5600, 0x5dc05800, 0x8800fffa, 0x5c000200,
+ 0xcd400000, 0x58000002, 0x5dc05800, 0x8800fffa, 0x5c000200, 0xcd800000, 0xc0004862, 0xc9c00000,
+ 0x00000000, 0xc15004c0, 0xc5d40068, 0xdd9c0000, 0xc5d41c20, 0xc1c00000, 0xdd800001, 0x58000038,
+ 0xc9c00080, 0xdd800001, 0xc1800000, 0x58000002, 0xc98000e0, 0x6ddc2000, 0xc000491c, 0x41d8e000,
+ 0xcd400001, 0xcdc00000, 0xdd940001, 0xc1c00000, 0x58140038, 0xc9c00080, 0xc1800000, 0x58140006,
+ 0xc9820080, 0x00000000, 0x59dc0002, 0x459cc000, 0x8400fff8, 0xc1c00000, 0x9d000000, 0x58140038,
+ 0xc5d80080, 0xcd800080, 0xc1c00000, 0xdf5c0040, 0x5ddc0080, 0x8400ffd2, 0x00000000, 0x9d000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xc160fffe, 0xc0000a10, 0xc9440068, 0xc1a0fffe, 0x59980e28,
+ 0xc000100c, 0xcd400000, 0xc000100e, 0xcd800000, 0xc0004962, 0xc9800000, 0x00000000, 0xc170000a,
+ 0x7194a000, 0x6c988000, 0x4498c000, 0x4498c000, 0x59980004, 0xc5940278, 0xc0001010, 0xcd400000,
+ 0xc0004946, 0xc9400000, 0x00000000, 0x00000000, 0x6d58a000, 0x6d5c4000, 0x45d8c000, 0x4558c000,
+ 0xc000494a, 0xc9400000, 0xc0004948, 0xc9c00000, 0x4194c000, 0xc1400012, 0xc55c1820, 0x9d000000,
+ 0xc59c0270, 0xc0001012, 0xcdc00000, 0xc1400000, 0x58000014, 0xc9410040, 0xc0004950, 0xc9c00000,
+ 0xc5580000, 0xc5940840, 0xc5581080, 0xd9940000, 0xc000493c, 0xc9400000, 0xc0004954, 0xc9800000,
+ 0x59dc00a8, 0x455ce000, 0x41d8e000, 0x5d5c0030, 0x8800fff8, 0xc1c00030, 0xc1800000, 0xc5d84030,
+ 0xc1400000, 0xc5d40010, 0x5dd40002, 0x8400005a, 0x5dd40004, 0x84000082, 0x5dd40006, 0x840000aa,
+ 0x5dd80026, 0x840000d2, 0xdd540000, 0xdd800001, 0x58000008, 0x40180000, 0xcd400000, 0x59980002,
+ 0x8000ffa8, 0xdd540000, 0xdd800001, 0x58000008, 0x40180000, 0xcd4000c0, 0x59980002, 0x8000ff70,
+ 0xdd540000, 0xdd800001, 0x58000008, 0x40180000, 0xcd400080, 0x59980002, 0x8000ff38, 0xdd540000,
+ 0xdd800001, 0x58000008, 0x40180000, 0xcd400040, 0x59980002, 0x8000ff00, 0x00000000, 0x9d000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x58000014, 0xc9400000, 0xc0004954, 0xc9c00000, 0xc0004950,
+ 0xc9400080, 0xdd800001, 0x5800002a, 0x5d9c0000, 0x8400003a, 0x5d9c0002, 0x8400003a, 0x5d9c0004,
+ 0x84000052, 0xc55b0040, 0xc55c08c0, 0xcd800041, 0xcdc008c0, 0x80000048, 0xcd400000, 0x80000038,
+ 0xc55900c0, 0xc55c1840, 0xcd8000c1, 0xcdc01840, 0x80000010, 0xc55a0080, 0xc55c1080, 0xcd800081,
+ 0xcdc01080, 0x9d000000, 0x00000000, 0x00000000, 0x00000000, 0xc1e00000, 0xa540fffa, 0xc0000a14,
+ 0xc1a20002, 0x9d000000, 0xcd841108, 0xc0000a1c, 0xcdc41040, 0x59540002, 0x6994e018, 0x61c0c008,
+ 0x4194a000, 0x5d940040, 0x8800fffa, 0xc5940000, 0x9d000000, 0xcd400000, 0x00000000, 0x00000000,
+};
+
+static unsigned int firmware_binary_data[] = {
+};
+
+
+#endif // IFXMIPS_PTM_FW_DANUBE_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_adsl.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_adsl.h
new file mode 100644
index 0000000000..d6bdfd9ef7
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_adsl.h
@@ -0,0 +1,284 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_fw_regs_adsl.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (firmware register for ADSL)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_PTM_FW_REGS_ADSL_H
+#define IFXMIPS_PTM_FW_REGS_ADSL_H
+
+
+
+#if defined(CONFIG_DANUBE)
+ #include "ifxmips_ptm_fw_regs_danube.h"
+#elif defined(CONFIG_AMAZON_SE)
+ #include "ifxmips_ptm_fw_regs_amazon_se.h"
+#elif defined(CONFIG_AR9)
+ #include "ifxmips_ptm_fw_regs_ar9.h"
+#elif defined(CONFIG_VR9)
+ #error VR9 is not ADSL PTM mode!
+#else
+ #error Platform is not specified!
+#endif
+
+
+
+/*
+ * MIB Table Maintained by Firmware
+ */
+
+struct wan_mib_table {
+ unsigned int wrx_correct_pdu; /* 0 */
+ unsigned int wrx_correct_pdu_bytes; /* 1 */
+ unsigned int wrx_tccrc_err_pdu; /* 2 */
+ unsigned int wrx_tccrc_err_pdu_bytes; /* 3 */
+ unsigned int wrx_ethcrc_err_pdu; /* 4 */
+ unsigned int wrx_ethcrc_err_pdu_bytes; /* 5 */
+ unsigned int wrx_nodesc_drop_pdu; /* 6 */
+ unsigned int wrx_len_violation_drop_pdu; /* 7 */
+ unsigned int wrx_idle_bytes; /* 8 */
+ unsigned int wrx_nonidle_cw; /* 9 */
+ unsigned int wrx_idle_cw; /* A */
+ unsigned int wrx_err_cw; /* B */
+ unsigned int wtx_total_pdu; /* C */
+ unsigned int wtx_total_bytes; /* D */
+ unsigned int res0; /* E */
+ unsigned int res1; /* F */
+};
+
+
+/*
+ * Host-PPE Communication Data Structure
+ */
+
+#if defined(__BIG_ENDIAN)
+
+ struct fw_ver_id {
+ unsigned int family :4;
+ unsigned int fwtype :4;
+ unsigned int interface :4;
+ unsigned int fwmode :4;
+ unsigned int major :8;
+ unsigned int minor :8;
+ };
+
+ struct wrx_port_cfg_status {
+ /* 0h */
+ unsigned int mfs :16;
+ unsigned int res0 :12;
+ unsigned int dmach :3;
+ unsigned int res1 :1;
+
+ /* 1h */
+ unsigned int res2 :14;
+ unsigned int local_state :2; // init with 0, written by firmware only
+ unsigned int res3 :15;
+ unsigned int partner_state :1; // init with 0, written by firmware only
+
+ };
+
+ struct wrx_dma_channel_config {
+ /* 0h */
+ unsigned int res3 :1;
+ unsigned int res4 :2;
+ unsigned int res5 :1;
+ unsigned int desba :28;
+ /* 1h */
+ unsigned int res1 :16;
+ unsigned int res2 :16;
+ /* 2h */
+ unsigned int deslen :16;
+ unsigned int vlddes :16;
+ };
+
+ struct wtx_port_cfg {
+ /* 0h */
+ unsigned int tx_cwth2 :8;
+ unsigned int tx_cwth1 :8;
+ unsigned int res0 :16;
+ };
+
+ struct wtx_dma_channel_config {
+ /* 0h */
+ unsigned int res3 :1;
+ unsigned int res4 :2;
+ unsigned int res5 :1;
+ unsigned int desba :28;
+
+ /* 1h */
+ unsigned int res1 :16;
+ unsigned int res2 :16;
+
+ /* 2h */
+ unsigned int deslen :16;
+ unsigned int vlddes :16;
+ };
+
+ struct eth_efmtc_crc_cfg {
+ /* 0h */
+ unsigned int res0 :6;
+ unsigned int tx_eth_crc_gen :1;
+ unsigned int tx_tc_crc_gen :1;
+ unsigned int tx_tc_crc_len :8;
+ unsigned int res1 :5;
+ unsigned int rx_eth_crc_present :1;
+ unsigned int rx_eth_crc_check :1;
+ unsigned int rx_tc_crc_check :1;
+ unsigned int rx_tc_crc_len :8;
+ };
+
+ /* DMA descriptor */
+ struct rx_descriptor {
+ /* 0 - 3h */
+ unsigned int own :1;
+ unsigned int c :1;
+ unsigned int sop :1;
+ unsigned int eop :1;
+ unsigned int res1 :3;
+ unsigned int byteoff :2;
+ unsigned int res2 :2;
+ unsigned int id :4;
+ unsigned int err :1;
+ unsigned int datalen :16;
+ /* 4 - 7h */
+ unsigned int res3 :4;
+ unsigned int dataptr :28;
+ };
+
+ struct tx_descriptor {
+ /* 0 - 3h */
+ unsigned int own :1;
+ unsigned int c :1;
+ unsigned int sop :1;
+ unsigned int eop :1;
+ unsigned int byteoff :5;
+ unsigned int res1 :5;
+ unsigned int iscell :1;
+ unsigned int clp :1;
+ unsigned int datalen :16;
+ /* 4 - 7h */
+ unsigned int res2 :4;
+ unsigned int dataptr :28;
+ };
+
+#else /* defined(__BIG_ENDIAN) */
+
+ struct wrx_port_cfg_status {
+ /* 0h */
+ unsigned int res1 :1;
+ unsigned int dmach :3;
+ unsigned int res0 :12;
+ unsigned int mfs :16;
+
+ /* 1h */
+ unsigned int partner_state :1;
+ unsigned int res3 :15;
+ unsigned int local_state :2;
+ unsigned int res2 :14;
+ };
+
+ struct wrx_dma_channel_config {
+ /* 0h */
+ unsigned int desba :28;
+ unsigned int res5 :1;
+ unsigned int res4 :2;
+ unsigned int res3 :1;
+ /* 1h */
+ unsigned int res2 :16;
+ unsigned int res1 :16;
+ /* 2h */
+ unsigned int vlddes :16;
+ unsigned int deslen :16;
+ };
+
+ struct wtx_port_cfg {
+ /* 0h */
+ unsigned int res0 :16;
+ unsigned int tx_cwth1 :8;
+ unsigned int tx_cwth2 :8;
+ };
+
+ struct wtx_dma_channel_config {
+ /* 0h */
+ unsigned int desba :28;
+ unsigned int res5 :1;
+ unsigned int res4 :2;
+ unsigned int res3 :1;
+ /* 1h */
+ unsigned int res2 :16;
+ unsigned int res1 :16;
+ /* 2h */
+ unsigned int vlddes :16;
+ unsigned int deslen :16;
+ };
+
+ struct eth_efmtc_crc_cfg {
+ /* 0h */
+ unsigned int rx_tc_crc_len :8;
+ unsigned int rx_tc_crc_check :1;
+ unsigned int rx_eth_crc_check :1;
+ unsigned int rx_eth_crc_present :1;
+ unsigned int res1 :5;
+ unsigned int tx_tc_crc_len :8;
+ unsigned int tx_tc_crc_gen :1;
+ unsigned int tx_eth_crc_gen :1;
+ unsigned int res0 :6;
+ };
+
+ /* DMA descriptor */
+ struct rx_descriptor {
+ /* 4 - 7h */
+ unsigned int dataptr :28;
+ unsigned int res3 :4;
+ /* 0 - 3h */
+ unsigned int datalen :16;
+ unsigned int err :1;
+ unsigned int id :4;
+ unsigned int res2 :2;
+ unsigned int byteoff :2;
+ unsigned int res1 :3;
+ unsigned int eop :1;
+ unsigned int sop :1;
+ unsigned int c :1;
+ unsigned int own :1;
+ };
+
+ struct tx_descriptor {
+ /* 4 - 7h */
+ unsigned int dataptr :28;
+ unsigned int res2 :4;
+ /* 0 - 3h */
+ unsigned int datalen :16;
+ unsigned int clp :1;
+ unsigned int iscell :1;
+ unsigned int res1 :5;
+ unsigned int byteoff :5;
+ unsigned int eop :1;
+ unsigned int sop :1;
+ unsigned int c :1;
+ unsigned int own :1;
+ };
+#endif /* defined(__BIG_ENDIAN) */
+
+
+
+#endif // IFXMIPS_PTM_FW_REGS_ADSL_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_amazon_se.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_amazon_se.h
new file mode 100644
index 0000000000..1219b6b0bf
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_amazon_se.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_fw_regs_amazon_se.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (firmware register for Amazon-SE)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_PTM_FW_REGS_AMAZON_SE_H
+#define IFXMIPS_PTM_FW_REGS_AMAZON_SE_H
+
+
+
+/*
+ * Host-PPE Communication Data Address Mapping
+ */
+#define FW_VER_ID ((volatile struct fw_ver_id *) SB_BUFFER(0x2401))
+#define CFG_WAN_WRDES_DELAY SB_BUFFER(0x2404)
+#define CFG_WRX_DMACH_ON SB_BUFFER(0x2405)
+#define CFG_WTX_DMACH_ON SB_BUFFER(0x2406)
+#define CFG_WRX_LOOK_BITTH SB_BUFFER(0x2407)
+#define CFG_ETH_EFMTC_CRC ((volatile struct eth_efmtc_crc_cfg *) SB_BUFFER(0x2408))
+#define WAN_MIB_TABLE ((volatile struct wan_mib_table*) SB_BUFFER(0x2440))
+#define WRX_PORT_CONFIG(i) ((volatile struct wrx_port_cfg_status*) SB_BUFFER(0x2500 + (i) * 20))
+#define WRX_DMA_CHANNEL_CONFIG(i) ((volatile struct wrx_dma_channel_config*) SB_BUFFER(0x2640 + (i) * 7))
+#define WTX_PORT_CONFIG(i) ((volatile struct wtx_port_cfg*) SB_BUFFER(0x2710 + (i) * 31))
+#define WTX_DMA_CHANNEL_CONFIG(i) ((volatile struct wtx_dma_channel_config*) SB_BUFFER(0x2711 + (i) * 31))
+
+
+
+#endif // IFXMIPS_PTM_FW_REGS_AMAZON_SE_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_ar9.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_ar9.h
new file mode 100644
index 0000000000..43f4da9388
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_ar9.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_fw_regs_ar9.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (firmware register for AR9)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_PTM_FW_REGS_AR9_H
+#define IFXMIPS_PTM_FW_REGS_AR9_H
+
+
+
+/*
+ * Host-PPE Communication Data Address Mapping
+ */
+#define FW_VER_ID ((volatile struct fw_ver_id *) SB_BUFFER(0x2001))
+#define CFG_WAN_WRDES_DELAY SB_BUFFER(0x2404)
+#define CFG_WRX_DMACH_ON SB_BUFFER(0x2405)
+#define CFG_WTX_DMACH_ON SB_BUFFER(0x2406)
+#define CFG_WRX_LOOK_BITTH SB_BUFFER(0x2407)
+#define CFG_ETH_EFMTC_CRC ((volatile struct eth_efmtc_crc_cfg *) SB_BUFFER(0x2408))
+#define WAN_MIB_TABLE ((volatile struct wan_mib_table*) SB_BUFFER(0x2440))
+#define WRX_PORT_CONFIG(i) ((volatile struct wrx_port_cfg_status*) SB_BUFFER(0x3F00 + (i) * 20))
+#define WRX_DMA_CHANNEL_CONFIG(i) ((volatile struct wrx_dma_channel_config*) SB_BUFFER(0x2640 + (i) * 7))
+#define WTX_PORT_CONFIG(i) ((volatile struct wtx_port_cfg*) SB_BUFFER(0x3B00 + (i) * 31))
+#define WTX_DMA_CHANNEL_CONFIG(i) ((volatile struct wtx_dma_channel_config*) SB_BUFFER(0x3B01 + (i) * 31))
+
+
+
+#endif // IFXMIPS_PTM_FW_REGS_AR9_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_danube.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_danube.h
new file mode 100644
index 0000000000..d8685f3da7
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_danube.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_fw_regs_danube.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (firmware register for Danube)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_PTM_FW_REGS_DANUBE_H
+#define IFXMIPS_PTM_FW_REGS_DANUBE_H
+
+
+
+/*
+ * Host-PPE Communication Data Address Mapping
+ */
+#define FW_VER_ID ((volatile struct fw_ver_id *) SB_BUFFER(0x2001))
+#define CFG_WAN_WRDES_DELAY SB_BUFFER(0x2404)
+#define CFG_WRX_DMACH_ON SB_BUFFER(0x2405)
+#define CFG_WTX_DMACH_ON SB_BUFFER(0x2406)
+#define CFG_WRX_LOOK_BITTH SB_BUFFER(0x2407)
+#define CFG_ETH_EFMTC_CRC ((volatile struct eth_efmtc_crc_cfg *) SB_BUFFER(0x2408))
+#define WAN_MIB_TABLE ((volatile struct wan_mib_table*) SB_BUFFER(0x2440))
+#define WRX_PORT_CONFIG(i) ((volatile struct wrx_port_cfg_status*) SB_BUFFER(0x2500 + (i) * 20))
+#define WRX_DMA_CHANNEL_CONFIG(i) ((volatile struct wrx_dma_channel_config*) SB_BUFFER(0x2640 + (i) * 7))
+#define WTX_PORT_CONFIG(i) ((volatile struct wtx_port_cfg*) SB_BUFFER(0x2710 + (i) * 31))
+#define WTX_DMA_CHANNEL_CONFIG(i) ((volatile struct wtx_dma_channel_config*) SB_BUFFER(0x2711 + (i) * 31))
+
+
+
+#endif // IFXMIPS_PTM_FW_REGS_DANUBE_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_vdsl.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_vdsl.h
new file mode 100644
index 0000000000..e3571976a5
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_vdsl.h
@@ -0,0 +1,278 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_fw_regs_vdsl.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (firmware register for VDSL)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_PTM_FW_REGS_VDSL_H
+#define IFXMIPS_PTM_FW_REGS_VDSL_H
+
+
+
+#if defined(CONFIG_DANUBE)
+ #error Danube is not VDSL PTM mode!
+#elif defined(CONFIG_AMAZON_SE)
+ #error Amazon-SE is not VDSL PTM mode!
+#elif defined(CONFIG_AR9)
+ #error AR9 is not VDSL PTM mode!
+#elif defined(CONFIG_VR9)
+ #include "ifxmips_ptm_fw_regs_vr9.h"
+#else
+ #error Platform is not specified!
+#endif
+
+
+
+/*
+ * MIB Table Maintained by Firmware
+ */
+
+struct wan_rx_mib_table {
+ unsigned int res1[2];
+ unsigned int wrx_dropdes_pdu;
+ unsigned int wrx_total_bytes;
+ unsigned int res2[4];
+ // wrx_total_pdu is implemented with hardware counter (not used by PTM TC)
+ // check register "TC_RX_MIB_CMD"
+ // "HEC_INC" used to increase preemption Gamma interface (wrx_total_pdu)
+ // "AIIDLE_INC" used to increase normal Gamma interface (wrx_total_pdu)
+};
+
+struct wan_tx_mib_table {
+ //unsigned int wtx_total_pdu; // version before 0.26
+ //unsigned int small_pkt_drop_cnt;
+ //unsigned int total_pkt_drop_cnt;
+ unsigned int wrx_total_pdu; // version 0.26 and onwards
+ unsigned int wrx_total_bytes;
+ unsigned int wtx_total_pdu;
+ unsigned int wtx_total_bytes;
+
+ unsigned int wtx_cpu_dropsmall_pdu;
+ unsigned int wtx_cpu_dropdes_pdu;
+ unsigned int wtx_fast_dropsmall_pdu;
+ unsigned int wtx_fast_dropdes_pdu;
+};
+
+
+/*
+ * Host-PPE Communication Data Structure
+ */
+
+#if defined(__BIG_ENDIAN)
+
+ struct fw_ver_id {
+ unsigned int family :4;
+ unsigned int fwtype :4;
+ unsigned int interface :4;
+ unsigned int fwmode :4;
+ unsigned int major :8;
+ unsigned int minor :8;
+ };
+
+ struct cfg_std_data_len {
+ unsigned int res1 :14;
+ unsigned int byte_off :2; // byte offset in RX DMA channel
+ unsigned int data_len :16; // data length for standard size packet buffer
+ };
+
+ struct tx_qos_cfg {
+ unsigned int time_tick :16; // number of PP32 cycles per basic time tick
+ unsigned int overhd_bytes :8; // number of overhead bytes per packet in rate shaping
+ unsigned int eth1_eg_qnum :4; // number of egress QoS queues (< 8);
+ unsigned int eth1_burst_chk :1; // always 1, more accurate WFQ
+ unsigned int eth1_qss :1; // 1: FW QoS, 0: HW QoS
+ unsigned int shape_en :1; // 1: enable rate shaping, 0: disable
+ unsigned int wfq_en :1; // 1: WFQ enabled, 0: strict priority enabled
+ };
+
+ struct psave_cfg {
+ unsigned int res1 :15;
+ unsigned int start_state :1; // 1: start from partial PPE reset, 0: start from full PPE reset
+ unsigned int res2 :15;
+ unsigned int sleep_en :1; // 1: enable sleep mode, 0: disable sleep mode
+ };
+
+ struct eg_bwctrl_cfg {
+ unsigned int fdesc_wm :16; // if free descriptors in QoS/Swap channel is less than this watermark, large size packets are discarded
+ unsigned int class_len :16; // if packet length is not less than this value, the packet is recognized as large packet
+ };
+
+ struct test_mode {
+ unsigned int res1 :30;
+ unsigned int mib_clear_mode :1; // 1: MIB counter is cleared with TPS-TC software reset, 0: MIB counter not cleared
+ unsigned int test_mode :1; // 1: test mode, 0: normal mode
+ };
+
+ struct gpio_mode {
+ unsigned int res1 :3;
+ unsigned int gpio_bit_bc1 :5;
+ unsigned int res2 :3;
+ unsigned int gpio_bit_bc0 :5;
+
+ unsigned int res3 :7;
+ unsigned int gpio_bc1_en :1;
+
+ unsigned int res4 :7;
+ unsigned int gpio_bc0_en :1;
+ };
+
+ struct gpio_wm_cfg {
+ unsigned int stop_wm_bc1 :8;
+ unsigned int start_wm_bc1 :8;
+ unsigned int stop_wm_bc0 :8;
+ unsigned int start_wm_bc0 :8;
+ };
+
+ struct rx_bc_cfg {
+ unsigned int res1 :14;
+ unsigned int local_state :2; // 0: local receiver is "Looking", 1: local receiver is "Freewheel Sync False", 2: local receiver is "Synced", 3: local receiver is "Freewheel Sync Truee"
+ unsigned int res2 :15;
+ unsigned int remote_state :1; // 0: remote receiver is "Out-of-Sync", 1: remote receiver is "Synced"
+ unsigned int to_false_th :16; // the number of consecutive "Miss Sync" for leaving "Freewheel Sync False" to "Looking" (default 3)
+ unsigned int to_looking_th :16; // the number of consecutive "Miss Sync" for leaving "Freewheel Sync True" to "Freewheel Sync False" (default 7)
+ unsigned int res_word[30];
+ };
+
+ struct rx_gamma_itf_cfg {
+ unsigned int res1 :31;
+ unsigned int receive_state :1; // 0: "Out-of-Fragment", 1: "In-Fragment"
+ unsigned int res2 :16;
+ unsigned int rx_min_len :8; // min length of packet, padding if packet length is smaller than this value
+ unsigned int rx_pad_en :1; // 0: padding disabled, 1: padding enabled
+ unsigned int res3 :2;
+ unsigned int rx_eth_fcs_ver_dis :1; // 0: ETH FCS verification is enabled, 1: disabled
+ unsigned int rx_rm_eth_fcs :1; // 0: ETH FCS field is not removed, 1: ETH FCS field is removed
+ unsigned int rx_tc_crc_ver_dis :1; // 0: TC CRC verification enabled, 1: disabled
+ unsigned int rx_tc_crc_size :2; // 0: 0-bit, 1: 16-bit, 2: 32-bit
+ unsigned int rx_eth_fcs_result; // if the ETH FCS result matches this magic number, then the packet is valid packet
+ unsigned int rx_tc_crc_result; // if the TC CRC result matches this magic number, then the packet is valid packet
+ unsigned int rx_crc_cfg :16; // TC CRC config, please check the description of SAR context data structure in the hardware spec
+ unsigned int res4 :16;
+ unsigned int rx_eth_fcs_init_value; // ETH FCS initialization value
+ unsigned int rx_tc_crc_init_value; // TC CRC initialization value
+ unsigned int res_word1;
+ unsigned int rx_max_len_sel :1; // 0: normal, the max length is given by MAX_LEN_NORMAL, 1: fragment, the max length is given by MAX_LEN_FRAG
+ unsigned int res5 :2;
+ unsigned int rx_edit_num2 :4; // number of bytes to be inserted/removed
+ unsigned int rx_edit_pos2 :7; // first byte position to be edited
+ unsigned int rx_edit_type2 :1; // 0: remove, 1: insert
+ unsigned int rx_edit_en2 :1; // 0: disable insertion or removal of data, 1: enable
+ unsigned int res6 :3;
+ unsigned int rx_edit_num1 :4; // number of bytes to be inserted/removed
+ unsigned int rx_edit_pos1 :7; // first byte position to be edited
+ unsigned int rx_edit_type1 :1; // 0: remove, 1: insert
+ unsigned int rx_edit_en1 :1; // 0: disable insertion or removal of data, 1: enable
+ unsigned int res_word2[2];
+ unsigned int rx_inserted_bytes_1l;
+ unsigned int rx_inserted_bytes_1h;
+ unsigned int rx_inserted_bytes_2l;
+ unsigned int rx_inserted_bytes_2h;
+ int rx_len_adj; // the packet length adjustment, it is sign integer
+ unsigned int res_word3[16];
+ };
+
+ struct tx_bc_cfg {
+ unsigned int fill_wm :16; // default 2
+ unsigned int uflw_wm :16; // default 2
+ unsigned int res_word[31];
+ };
+
+ struct tx_gamma_itf_cfg {
+ unsigned int res_word1;
+ unsigned int res1 :8;
+ unsigned int tx_len_adj :4; // 4 * (not TX_ETH_FCS_GEN_DIS) + TX_TC_CRC_SIZE
+ unsigned int tx_crc_off_adj :4; // 4 + TX_TC_CRC_SIZE
+ unsigned int tx_min_len :8; // min length of packet, if length is less than this value, packet is padded
+ unsigned int res2 :3;
+ unsigned int tx_eth_fcs_gen_dis :1; // 0: ETH FCS generation enabled, 1: disabled
+ unsigned int res3 :2;
+ unsigned int tx_tc_crc_size :2; // 0: 0-bit, 1: 16-bit, 2: 32-bit
+ unsigned int res4 :24;
+ unsigned int queue_mapping :8; // TX queue attached to this Gamma interface
+ unsigned int res_word2;
+ unsigned int tx_crc_cfg :16; // TC CRC config, please check the description of SAR context data structure in the hardware spec
+ unsigned int res5 :16;
+ unsigned int tx_eth_fcs_init_value; // ETH FCS initialization value
+ unsigned int tx_tc_crc_init_value; // TC CRC initialization value
+ unsigned int res_word3[25];
+ };
+
+ struct wtx_qos_q_desc_cfg {
+ unsigned int threshold :8;
+ unsigned int length :8;
+ unsigned int addr :16;
+ unsigned int rd_ptr :16;
+ unsigned int wr_ptr :16;
+ };
+
+ struct wtx_eg_q_shaping_cfg {
+ unsigned int t :8;
+ unsigned int w :24;
+ unsigned int s :16;
+ unsigned int r :16;
+ unsigned int res1 :8;
+ unsigned int d :24; // ppe internal variable
+ unsigned int res2 :8;
+ unsigned int tick_cnt :8; // ppe internal variable
+ unsigned int b :16; // ppe internal variable
+ };
+
+ /* DMA descriptor */
+ struct rx_descriptor {
+ /* 0 - 3h */
+ unsigned int own :1; // 0: Central DMA TX or MIPS, 1: PPE
+ unsigned int c :1; // PPE tells current descriptor is complete
+ unsigned int sop :1;
+ unsigned int eop :1;
+ unsigned int res1 :3;
+ unsigned int byteoff :2;
+ unsigned int res2 :7;
+ unsigned int datalen :16;
+ /* 4 - 7h */
+ unsigned int res3 :4;
+ unsigned int dataptr :28; // byte address
+ };
+
+ struct tx_descriptor {
+ /* 0 - 3h */
+ unsigned int own :1; // CPU path - 0: MIPS, 1: PPE Dispatcher, Fastpath - 0: PPE Dispatcher, 1: Central DMA, QoS Queue - 0: PPE Dispatcher, 1: PPE DMA, SWAP Channel - 0: MIPS, 1: PPE Dispatcher
+ unsigned int c :1; // MIPS or central DMA tells PPE the current descriptor is complete
+ unsigned int sop :1;
+ unsigned int eop :1;
+ unsigned int byteoff :5;
+ unsigned int qid :4; // TX Queue ID, bit 3 is reserved
+ unsigned int res1 :3;
+ unsigned int datalen :16;
+ /* 4 - 7h */
+ unsigned int small :1; // 0: standard size, 1: less than standard size
+ unsigned int res2 :3;
+ unsigned int dataptr :28; // byte address
+ };
+
+#else /* defined(__BIG_ENDIAN) */
+ #error structures are defined in big endian
+#endif /* defined(__BIG_ENDIAN) */
+
+
+
+#endif // IFXMIPS_PTM_FW_REGS_VDSL_H
+
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_vr9.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_vr9.h
new file mode 100644
index 0000000000..a640cfba4d
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_regs_vr9.h
@@ -0,0 +1,90 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_fw_regs_vr9.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (firmware register for VR9)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_PTM_FW_REGS_VR9_H
+#define IFXMIPS_PTM_FW_REGS_VR9_H
+
+
+
+/*
+ * Host-PPE Communication Data Address Mapping
+ */
+#define FW_VER_ID ((volatile struct fw_ver_id *) SB_BUFFER(0x2001))
+#define CFG_STD_DATA_LEN ((volatile struct cfg_std_data_len *) SB_BUFFER(0x2011))
+#define TX_QOS_CFG ((volatile struct tx_qos_cfg *) SB_BUFFER(0x2012))
+#define EG_BWCTRL_CFG ((volatile struct eg_bwctrl_cfg *) SB_BUFFER(0x2013))
+#define PSAVE_CFG ((volatile struct psave_cfg *) SB_BUFFER(0x2014))
+#define GPIO_ADDR SB_BUFFER(0x2019)
+#define GPIO_MODE ((volatile struct gpio_mode *) SB_BUFFER(0x201C))
+#define GPIO_WM_CFG ((volatile struct gpio_wm_cfg *) SB_BUFFER(0x201D))
+#define TEST_MODE ((volatile struct test_mode *) SB_BUFFER(0x201F))
+#define WTX_QOS_Q_DESC_CFG(i) ((volatile struct wtx_qos_q_desc_cfg *) SB_BUFFER(0x2FF0 + (i) * 2)) /* i < 8 */
+#define WTX_EG_Q_PORT_SHAPING_CFG(i) ((volatile struct wtx_eg_q_shaping_cfg *) SB_BUFFER(0x2680 + (i) * 4)) /* i < 1 */
+#define WTX_EG_Q_SHAPING_CFG(i) ((volatile struct wtx_eg_q_shaping_cfg *) SB_BUFFER(0x2684 + (i) * 4)) /* i < 8 */
+#define TX_QUEUE_CFG(i) WTX_EG_Q_PORT_SHAPING_CFG(i) // i < 9
+#define RX_BC_CFG(i) ((volatile struct rx_bc_cfg *) SB_BUFFER(0x3E80 + (i) * 0x20)) // i < 2
+#define TX_BC_CFG(i) ((volatile struct tx_bc_cfg *) SB_BUFFER(0x3EC0 + (i) * 0x20)) // i < 2
+#define RX_GAMMA_ITF_CFG(i) ((volatile struct rx_gamma_itf_cfg *) SB_BUFFER(0x3D80 + (i) * 0x20)) // i < 4
+#define TX_GAMMA_ITF_CFG(i) ((volatile struct tx_gamma_itf_cfg *) SB_BUFFER(0x3E00 + (i) * 0x20)) // i < 4
+#define WAN_RX_MIB_TABLE(i) ((volatile struct wan_rx_mib_table *) SB_BUFFER(0x5B00 + (i) * 8)) // i < 4
+#define WAN_TX_MIB_TABLE(i) ((volatile struct wan_tx_mib_table *) SB_BUFFER(0x5B20 + (i) * 8)) // i < 8
+#define TX_CTRL_K_TABLE(i) SB_BUFFER(0x47F0 + (i)) // i < 16
+// following MIB for debugging purpose
+#define RECEIVE_NON_IDLE_CELL_CNT(i) SB_BUFFER(5020 + (i))
+#define RECEIVE_IDLE_CELL_CNT(i) SB_BUFFER(5022 + (i))
+#define TRANSMIT_CELL_CNT(i) SB_BUFFER(5024 + (i))
+#define FP_RECEIVE_PKT_CNT SB_BUFFER(5026)
+
+#define UTP_CFG SB_BUFFER(0x2018) // bit 0~3 - 0x0F: in showtime, 0x00: not in showtime
+
+/*
+ * Descriptor Base Address
+ */
+#define CPU_TO_WAN_TX_DESC_BASE ((volatile struct tx_descriptor *)SB_BUFFER(0x3D00))
+#define __ETH_WAN_TX_QUEUE_NUM g_wanqos_en
+#define __ETH_WAN_TX_QUEUE_LEN ((WAN_TX_DESC_NUM_TOTAL / __ETH_WAN_TX_QUEUE_NUM) < 256 ? (WAN_TX_DESC_NUM_TOTAL / __ETH_WAN_TX_QUEUE_NUM) : 255)
+#define __ETH_WAN_TX_DESC_BASE(i) (0x5C00 + (i) * 2 * __ETH_WAN_TX_QUEUE_LEN)
+#define WAN_TX_DESC_BASE(i) ((volatile struct tx_descriptor *)SB_BUFFER(__ETH_WAN_TX_DESC_BASE(i))) // i < __ETH_WAN_TX_QUEUE_NUM, __ETH_WAN_TX_QUEUE_LEN each queue
+#define WAN_SWAP_DESC_BASE ((volatile struct tx_descriptor *)SB_BUFFER(0x2E80))
+#define FASTPATH_TO_WAN_TX_DESC_BASE ((volatile struct tx_descriptor *)SB_BUFFER(0x2580))
+#define DMA_RX_CH1_DESC_BASE FASTPATH_TO_WAN_TX_DESC_BASE
+#define WAN_RX_DESC_BASE ((volatile struct rx_descriptor *)SB_BUFFER(0x2600))
+#define DMA_TX_CH1_DESC_BASE WAN_RX_DESC_BASE
+
+/*
+ * Descriptor Number
+ */
+#define CPU_TO_WAN_TX_DESC_NUM 64
+#define WAN_TX_DESC_NUM __ETH_WAN_TX_QUEUE_LEN
+#define WAN_SWAP_DESC_NUM 64
+#define WAN_TX_DESC_NUM_TOTAL 512
+#define FASTPATH_TO_WAN_TX_DESC_NUM 64
+#define DMA_RX_CH1_DESC_NUM FASTPATH_TO_WAN_TX_DESC_NUM
+#define WAN_RX_DESC_NUM 64
+#define DMA_TX_CH1_DESC_NUM WAN_RX_DESC_NUM
+
+
+
+#endif // IFXMIPS_PTM_FW_REGS_VR9_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_vr9.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_vr9.h
new file mode 100644
index 0000000000..b895ee8f49
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_fw_vr9.h
@@ -0,0 +1,380 @@
+#ifndef IFXMIPS_PTM_FW_VR9_H
+#define IFXMIPS_PTM_FW_VR9_H
+
+
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_fw_vr9.h
+** PROJECT : UEIP
+** MODULES : PTM (VDSL)
+**
+** DATE : 22 OCT 2007
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM Driver (PP32 Firmware)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 22 OCT 2007 Xu Liang Initiate Version, v00.01
+*******************************************************************************/
+
+
+#define PTM_FW_VER_MAJOR 0
+#define PTM_FW_VER_MINOR 30
+
+
+static unsigned int firmware_binary_code[] = {
+ 0x80000980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000ffe0, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc1c20002, 0xd9cc00f8, 0xc0006950, 0xcbc000f8, 0xc0004024, 0xc8c000f8, 0xc0006950, 0x5bfc0002,
+ 0xcfc000f8, 0xa4c252a2, 0x00000000, 0x00000000, 0x800007a0, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x94000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc0e1fffe, 0x58cdfffe, 0xc1e1fffa, 0x59ddfffe, 0x94000001, 0x00000000, 0x00000000, 0x00000000,
+ 0xc0e1fffe, 0x58cdfffe, 0xc1e1fffa, 0x59ddfffe, 0x900009a1, 0x00000000, 0x00000000, 0x00000000,
+ 0x90cc0941, 0x00000000, 0x00000000, 0x00000000, 0xc3e0e2a2, 0x5bfc003c, 0xc0004002, 0xcfc000f8,
+ 0xc3c00000, 0xc0004024, 0xcbc20078, 0x00000000, 0x00000000, 0xc1c00000, 0xd9c400f9, 0xdbc40078,
+ 0xc1c00006, 0xd9c400f9, 0xc3c0fc10, 0xc0006952, 0xcfc000f8, 0xc3c00000, 0xc3400000, 0xc3000040,
+ 0xc2c00080, 0x6ff8a000, 0x5bb87d00, 0x5838001c, 0xcf4000f8, 0x5838001e, 0xcec000f8, 0x58380020,
+ 0xcf4000f8, 0x58380022, 0xcf0000f8, 0x5bfc0002, 0x5ebc0004, 0x8400ffa0, 0x00000000, 0xc1e1fffe,
+ 0x59ddfffa, 0x141c0000, 0xc1c00000, 0xc000691c, 0xcdc000f8, 0xab64002a, 0xc3c00000, 0xab66001a,
+ 0xc3c00002, 0x80001130, 0xc1c00002, 0xc000691c, 0xcdc000f8, 0x6ff8a000, 0x5bb87d00, 0x58380004,
+ 0xcb4000f8, 0xc2800000, 0x58380000, 0xca820008, 0xc000e824, 0xc3000000, 0xcb3c0070, 0x6f5c8000,
+ 0x41f4e000, 0x431d8000, 0x5b304000, 0xc000e828, 0xc1c00000, 0xc9fc0070, 0x00000000, 0xc0004000,
+ 0x41f4e000, 0x401c0000, 0xcac000f8, 0x5de80004, 0x84000880, 0xa6c607ea, 0x00000000, 0x6fe42000,
+ 0xc6e4a000, 0x6e60a000, 0x5a207b00, 0xc1800000, 0x58200000, 0xc9800000, 0xc2800000, 0xc6e80010,
+ 0x5dd80000, 0x8400003a, 0x5de80008, 0xc6a82012, 0xc1c00004, 0x45e8e000, 0x88000030, 0x80000558,
+ 0x5de80004, 0xc6a8010a, 0x5de80008, 0x84000538, 0x58380000, 0xc1c00002, 0xcdc00000, 0x58200000,
+ 0xc1c00002, 0xcdc00000, 0x5de80002, 0xcdc00002, 0xc000ea14, 0xc1e20000, 0xcdfe3100, 0xc000fb60,
+ 0xc1c00002, 0xcdfc0000, 0xc0006940, 0xc9c000f8, 0x403c0000, 0x00000000, 0x59dc0002, 0xcdc000f8,
+ 0xc1c00004, 0x45e8e000, 0x880000fa, 0x58200020, 0xc9c000f8, 0xc0c00018, 0xc1000000, 0xa5c0002a,
+ 0xc1400080, 0x5de80000, 0xc6ccf930, 0xc54c1932, 0x5de80000, 0xc1c0000a, 0xc5cc1230, 0xc5cc3202,
+ 0x58200022, 0xc9c000f8, 0xc74c0b30, 0xc7cc0008, 0xc5cc0528, 0xc1800000, 0xc6982000, 0xc1c00000,
+ 0xc69c0000, 0x71d8e000, 0xc5cc0400, 0x98404c78, 0xc5d00000, 0x7d80e000, 0xc5d00100, 0x5dd80002,
+ 0x84000388, 0xc1c00000, 0xc6ddc030, 0x59dc0006, 0xc5ec0e30, 0xc0c00018, 0xc1000004, 0x59dc0002,
+ 0xc5cc1230, 0xc74c0b30, 0xc7cc0008, 0xc0000088, 0x441ce000, 0xc5cc1930, 0xa6cc02b0, 0xc1c80002,
+ 0x70dc6000, 0xc1400000, 0xc6d5c030, 0x5d540002, 0x6d5c4010, 0x431c0000, 0xc88000f8, 0xc1c00000,
+ 0xc55c0008, 0xc0000006, 0x441ce000, 0x6ddc6000, 0x689c4010, 0xc1c001fe, 0x749c4000, 0x59540002,
+ 0xc1c000fe, 0x749c4000, 0x5c880020, 0xc48c1930, 0x4148c000, 0x59980002, 0x5dd80088, 0x8800002a,
+ 0x58200000, 0xc1c00000, 0xcdc00000, 0x800000c8, 0xc1400000, 0x6d9c4010, 0x431c0000, 0xc94000f8,
+ 0xc1c00000, 0xc59c0008, 0xc0000006, 0x441ce000, 0x6ddc6000, 0x695ca010, 0xc1c001fe, 0x755ca000,
+ 0x00000000, 0x00000000, 0x5dd40000, 0x84000018, 0x59980002, 0x8000ff48, 0x59980002, 0xc0800002,
+ 0x5dd400a0, 0xc4902100, 0xc4ac2602, 0x4588c002, 0xdbc800f9, 0xda4800f8, 0xda1000f9, 0x90404391,
+ 0x58200020, 0xc9c000f8, 0x58200022, 0xc94000f8, 0x5ddc0002, 0xc1c00000, 0xc5cc1932, 0xc6ddc030,
+ 0x59dc0002, 0x98404c78, 0xc5cc1230, 0xc54c0528, 0xc4d08000, 0xa5020072, 0xc1c00002, 0xc5d00100,
+ 0xc5ac0e30, 0xa6ccfdc2, 0xc1c00000, 0xc5cc0400, 0xc1c00086, 0x45d8e000, 0xc5cc1930, 0x8000ff28,
+ 0x00000000, 0x00000000, 0x00000000, 0x80000070, 0xdbc800f9, 0xda4800f8, 0xda1000f9, 0x90404391,
+ 0x58200022, 0xc98000f8, 0x58200020, 0xc9c000f8, 0x00000000, 0x98404c78, 0x5ddc0002, 0xc58c0528,
+ 0xc5cc1932, 0x80000200, 0xc1400000, 0xc000403e, 0xc9400000, 0xc1800000, 0x58200000, 0xc9800000,
+ 0x5dd40002, 0x84000020, 0x5dd80002, 0x84000010, 0x80000110, 0x5de80006, 0x84000088, 0x58380000,
+ 0xc1c00002, 0xcdc00000, 0xc000ea14, 0xc1e20000, 0xcdfe3100, 0xc000fb60, 0xc1c20002, 0xcdfc2100,
+ 0xc0006944, 0xc9c000f8, 0x403c0000, 0x00000000, 0x59dc0002, 0xcdc000f8, 0x800000f0, 0x5de8000a,
+ 0x84000070, 0x58380000, 0xc1c00000, 0xcdc00000, 0xc000ea14, 0xc1e20002, 0xcdfe3100, 0xc000fb60,
+ 0xc1c20002, 0xcdfc2100, 0xc000facc, 0xc1c00002, 0xcdfc0000, 0x80000078, 0xa6ca0040, 0xc000facc,
+ 0xc1ca0002, 0xcdfca500, 0xc000fb64, 0xc1c60002, 0xcdfc6300, 0x80000038, 0xc000facc, 0xc1c80002,
+ 0xcdfc8400, 0xc000fb64, 0xc1c40002, 0xcdfc4200, 0xc0c00010, 0x98404c78, 0xc7cc0008, 0xc74c0b30,
+ 0xc1000004, 0x80000808, 0xc1c00002, 0x58380008, 0xcdc000f8, 0x58380000, 0xc1e00006, 0xcdc21008,
+ 0xc000facc, 0xc1c80002, 0xcdfc8400, 0xc000fb64, 0xc1c40002, 0xcdfc4200, 0xc0c00010, 0x98404c78,
+ 0xc7cc0008, 0xc74c0b30, 0xc1000004, 0x80000778, 0x5de80006, 0x84000170, 0xa6c60032, 0x00000000,
+ 0x58380000, 0xc1e00004, 0xcdc21008, 0x8000f760, 0x58380008, 0xca8000f8, 0xc2400000, 0x58380002,
+ 0xca420078, 0x00000000, 0x5aa80002, 0x58380008, 0xce8000f8, 0x46a4e000, 0x8800008a, 0x58380000,
+ 0xc1e00002, 0xcdc21008, 0x58380000, 0xc1c00000, 0xcdc00000, 0xc000facc, 0xc1c20002, 0xcdfc2100,
+ 0xc1e1e1a2, 0xc000ea1c, 0xcdfc00f8, 0xc000ea14, 0xc1e20002, 0xcdfe3100, 0x80000038, 0xc000facc,
+ 0xc1c80002, 0xcdfc8400, 0xc000fb64, 0xc1c40002, 0xcdfc4200, 0xc0c00010, 0x98404c78, 0xc7cc0008,
+ 0xc74c0b30, 0xc1000004, 0x80000600, 0x5de80002, 0x84000150, 0xa6c6004a, 0x00000000, 0x58380000,
+ 0xc1e00004, 0xcdc21008, 0xc1f8001e, 0xc000ea1c, 0xcdfc00f8, 0x8000f5d0, 0x58380008, 0xca8000f8,
+ 0xc2400000, 0x58380002, 0xca400078, 0xc000facc, 0xc1c20002, 0xcdfc2100, 0x5aa80002, 0x58380008,
+ 0xce8000f8, 0x46a4e000, 0x88000072, 0x58380000, 0xc1e00000, 0xcdc21008, 0xc1c00000, 0x58380006,
+ 0xcdc000f8, 0xc000e82c, 0xc1c00000, 0xcdfdce00, 0xc000e820, 0xc1c00000, 0xcdfc0000, 0x80000300,
+ 0xc0c00010, 0x98404c78, 0xc7cc0008, 0xc74c0b30, 0xc1000004, 0x800004a8, 0x5838001c, 0xca8000f8,
+ 0x5838001e, 0xca4000f8, 0x5aa80002, 0x5838001c, 0xce8000f8, 0x4668e000, 0x88000098, 0x58380022,
+ 0xca4000f8, 0x58380020, 0xca0000f8, 0xc000e82c, 0xc1c00000, 0xcdfdce00, 0xc000e810, 0xce7c0030,
+ 0xc2800000, 0x5838001c, 0xce8000f8, 0x5a200002, 0x58380020, 0xce0000f8, 0xc000e82c, 0xc1dc0002,
+ 0xcdfdce00, 0x58380006, 0xc8c000f8, 0x5830001c, 0xca8000f9, 0xca4000f9, 0xc2000000, 0xca000001,
+ 0x5dcc0006, 0x88000028, 0x58cc0002, 0x58380006, 0xccc000f8, 0x80000250, 0x5838000a, 0xc8c000f9,
+ 0xc90000f9, 0xc1400000, 0xc9400001, 0x74e86000, 0x75248000, 0x7560a000, 0x58380010, 0xca8000f9,
+ 0xca4000f9, 0xc2000000, 0xca000001, 0x98404de8, 0x74e86000, 0x75248000, 0x7560a000, 0x5dc800a0,
+ 0x840001ba, 0x58380016, 0xca8000f9, 0xca4000f9, 0xc2000000, 0xca000001, 0x98404de8, 0x74e86000,
+ 0x75248000, 0x7560a000, 0x5dc800a0, 0x84000162, 0x58380000, 0xc1e00004, 0xcdc21008, 0x5838001c,
+ 0xc1c00000, 0xcdc000f8, 0xc000e82c, 0xc1c00000, 0xcdfdce00, 0xc1f8001e, 0xc000ea1c, 0xcdfc00f8,
+ 0xc000e820, 0xc1c00002, 0xcdfc0000, 0xc1c00082, 0x45c8e000, 0xc000e810, 0xcdfc0030, 0xc2400000,
+ 0xc000e82c, 0xca7c0038, 0xc000e83c, 0xc2800000, 0xcabc0038, 0xc0c00010, 0x98404c78, 0xc7cc0008,
+ 0xc74c0b30, 0xc1000004, 0x5b740002, 0x4674e000, 0xc1c00000, 0xc5f400fe, 0x5ea80002, 0x8400ffb0,
+ 0xc000e83c, 0xc1c00000, 0xcdfc0038, 0xc000e82c, 0xc1dc0002, 0xcdfdce00, 0x80000178, 0x58380010,
+ 0xca8000f9, 0xca4000f9, 0xc2000000, 0xca000001, 0x58380016, 0xce8000f9, 0xce4000f9, 0xce000001,
+ 0x5838000a, 0xca8000f9, 0xca4000f9, 0xc2000000, 0xca000001, 0x58380010, 0xce8000f9, 0xce4000f9,
+ 0xce000001, 0x5830001c, 0xca8000f9, 0xca4000f9, 0xc2000000, 0xca000001, 0x5838000a, 0xce8000f9,
+ 0xce4000f9, 0xce000001, 0xc000facc, 0xc1c20002, 0xcdfc2100, 0xc0c00010, 0x98404c78, 0xc7cc0008,
+ 0xc74c0b30, 0xc1000004, 0xc000e83c, 0xc1d00002, 0xcdfd0800, 0xc0c00000, 0xc000e82c, 0xc8fc0038,
+ 0x5b740002, 0x00000000, 0x44f4e000, 0xc1c00000, 0xc5f400fe, 0x58380004, 0xcf4000f8, 0x98404ec0,
+ 0x00000000, 0x00000000, 0x00000000, 0xc0006914, 0xcbc000f8, 0xc2800000, 0xc2400000, 0x5bfc4b00,
+ 0xc7c000f8, 0xcb0000f8, 0x58000002, 0xcac000f8, 0xc0004026, 0xca800078, 0xc0004026, 0xca420078,
+ 0xc3400000, 0xc7366018, 0xa73e0172, 0x00000000, 0xc777e300, 0xc000694c, 0xc9c000f8, 0x00000000,
+ 0x00000000, 0x59dc0002, 0xcdc000f8, 0x6f5c6000, 0x58dcb640, 0x580c0000, 0xc90000f8, 0x580c0002,
+ 0xc94000f8, 0x59100002, 0x580c0000, 0xcd0000f8, 0xc1c00000, 0xc71c0078, 0x415ca000, 0x580c0002,
+ 0xcd4000f8, 0x98402008, 0x5834fc10, 0xc8c000f8, 0xc1000000, 0x5dc80000, 0x84000070, 0x6f402000,
+ 0x58005fe0, 0xc3800000, 0x58000000, 0xcb800078, 0xc1c00000, 0x58000002, 0xc9c00078, 0x984022c0,
+ 0x00000000, 0x439dc000, 0x00000000, 0x80000028, 0x98402098, 0xc48c00f8, 0x00000000, 0x00000000,
+ 0xc0006916, 0xcbc000f8, 0xc3400000, 0x00000000, 0x5bfc7a00, 0xc7c000f8, 0xcb0000f8, 0x58000002,
+ 0xcac000f8, 0xc7366018, 0xa73e0900, 0x00000000, 0xc777e300, 0xc000694e, 0xc9c000f8, 0x00000000,
+ 0x00000000, 0x59dc0002, 0xcdc000f8, 0x6f5c6000, 0x58dcb640, 0x580c0000, 0xc90000f8, 0x580c0002,
+ 0xc94000f8, 0x59100002, 0x580c0000, 0xcd0000f8, 0xc1c00000, 0xc71c0078, 0x415ca000, 0x580c0002,
+ 0xcd4000f8, 0x98402008, 0x5834fc10, 0xc8c000f8, 0xc1000000, 0x5dc80000, 0x84000070, 0x6f402000,
+ 0x58005fe0, 0xc3800000, 0x58000000, 0xcb800078, 0xc1c00000, 0x58000002, 0xc9c00078, 0x984025d0,
+ 0x00000000, 0x439dc000, 0x00000000, 0x800007b8, 0x984021c0, 0xc48c00f8, 0x00000000, 0x00000000,
+ 0x80000790, 0xc7100078, 0xc0800000, 0x6f402000, 0x58005fe0, 0xc1400000, 0x58000000, 0xc9420038,
+ 0x4690e000, 0x88000030, 0x454ca000, 0x9c400000, 0x4564e000, 0xc1c00004, 0xc5c800fe, 0x9c400000,
+ 0x454ce000, 0xc1c00002, 0xc5c800fe, 0xc0006914, 0xc90000f8, 0xc1400000, 0xc0004022, 0xc9400078,
+ 0x583c0000, 0xc1fc0000, 0xcdc3de00, 0x583c0000, 0xcd400078, 0x583c0000, 0xc1fe0002, 0xcdc3ff00,
+ 0x59100004, 0xc1c00100, 0x45d0e000, 0xc1c00000, 0xc5d000fe, 0xc0006914, 0xcd0000f8, 0x6f546000,
+ 0x5954b640, 0x5dcc0002, 0x84000038, 0x5814000c, 0xc9c000f8, 0x00000000, 0x00000000, 0x59dc0002,
+ 0xcdc000f8, 0x5814000e, 0xc9c000f8, 0x00000000, 0x9c400000, 0x59dc0002, 0xcdc000f8, 0x00000000,
+ 0xc0006916, 0xc90000f8, 0x583c0000, 0xc1fc0000, 0xcdc3de00, 0x583c0000, 0xc1fe0000, 0xcdc3ff00,
+ 0x59100004, 0xc1c00100, 0x45d0e000, 0xc1c00000, 0xc5d000fe, 0xc0006916, 0xcd0000f8, 0x6f546000,
+ 0x5954b640, 0x5dcc0002, 0x84000038, 0x58140008, 0xc9c000f8, 0x00000000, 0x00000000, 0x59dc0002,
+ 0xcdc000f8, 0x5814000a, 0xc9c000f8, 0x00000000, 0x9c400000, 0x59dc0002, 0xcdc000f8, 0x00000000,
+ 0x58380002, 0xc90000f8, 0x5c000002, 0xc8c000f8, 0xa53e0178, 0xc0006918, 0xca0000f8, 0x00000000,
+ 0x00000000, 0x5a205d00, 0xc60000f8, 0xc94000f8, 0x58000002, 0xc98000f8, 0xa57e006a, 0xc1c00000,
+ 0xc0c00004, 0xc71c0078, 0xc46000f8, 0x98402098, 0x45e8e000, 0xc1c00002, 0xc5cc00fe, 0x9e000000,
+ 0xc1e00002, 0xc000e408, 0xcdc21000, 0xc55c00f8, 0xc4d400f8, 0xc5cc00f8, 0xc59c00f8, 0xc51800f8,
+ 0xc5d000f8, 0xc1c00000, 0xc5d41f00, 0xc5d3ff00, 0x58200002, 0xcd8000f8, 0x5c000002, 0xcd4000f8,
+ 0x5e205d00, 0x5a200004, 0xc1c00100, 0x45e0e000, 0xc1c00000, 0xc5e000fe, 0xc0006918, 0xce0000f8,
+ 0xc1e00002, 0xc000e408, 0xcdc21000, 0xc6dc00f8, 0xc52c00f8, 0xc5d000f8, 0xc71c00f8, 0xc4f000f8,
+ 0xc5cc00f8, 0xc0004022, 0xcb000078, 0xc1c00002, 0xc5cc1f00, 0xc5f01f00, 0xc5f3fe00, 0x58380002,
+ 0xcd0000f8, 0x5c000002, 0xccc000f8, 0x6f402000, 0x58005fe0, 0xc1c00000, 0xc9c20138, 0xc2000000,
+ 0x58000002, 0xca000078, 0x00000000, 0x00000000, 0x5a200004, 0x45e0e000, 0xc1c00000, 0xc5e000fe,
+ 0xce000078, 0x5e3c4b00, 0x5a200004, 0xc1c00100, 0x45e0e000, 0xc1c00000, 0xc5e000fe, 0xc0006914,
+ 0xce0000f8, 0xc1c00002, 0x69f4e000, 0xc5dc0838, 0xd9f000f8, 0x583c0002, 0xcec000f8, 0x5c000002,
+ 0xcf0000f8, 0x9c400000, 0x58380002, 0xc90000f8, 0x5c000002, 0xc8c000f8, 0xc6dc00f8, 0xc52c00f8,
+ 0xc5d000f8, 0xc71c00f8, 0xc4f000f8, 0xc5cc00f8, 0xc1c00002, 0xc5cc1f00, 0xc1c00000, 0xc5f01f00,
+ 0xc5f3fe00, 0x58380002, 0xcd0000f8, 0x5c000002, 0xccc000f8, 0x6f402000, 0x58005fe0, 0xc1c00000,
+ 0xc9c20138, 0xc2000000, 0x58000002, 0xca000078, 0x00000000, 0x00000000, 0x5a200004, 0x45e0e000,
+ 0xc1c00000, 0xc5e000fe, 0xce000078, 0x5e3c7a00, 0x5a200004, 0xc1c00100, 0x45e0e000, 0xc1c00000,
+ 0xc5e000fe, 0xc0006916, 0xce0000f8, 0xc1c00002, 0x69f4e000, 0xc5dc0838, 0xd9f000f8, 0x583c0002,
+ 0xcec000f8, 0x5c000002, 0xcf0000f8, 0xc1e20002, 0xc000e408, 0xcdc23100, 0x9c400000, 0x00000000,
+ 0x00000000, 0x00000000, 0xc3c00000, 0x6ff8a000, 0x5bb87d80, 0x583cfb50, 0xc2800000, 0xca80c030,
+ 0xc2400000, 0x58380000, 0xca400078, 0x58380006, 0xca0000f8, 0x583cea28, 0xc9c000f8, 0xc0c00000,
+ 0x00000000, 0xc5cc0038, 0x420c8000, 0x4268a000, 0x4514e000, 0x880000aa, 0x58380004, 0xca4000f8,
+ 0xc000ea28, 0x6e1d2000, 0xcdfd2928, 0xc000ea28, 0xc1d00002, 0xcdfd0800, 0xc0006948, 0xc9c000f8,
+ 0x403c0000, 0x00000000, 0x41e0e000, 0xcdc000f8, 0x46612000, 0x58380004, 0xce4000f8, 0x58380006,
+ 0xc1c00000, 0xcdc000f8, 0x58380004, 0xca4000f8, 0x583cea28, 0xc9c000f8, 0xc0c00000, 0x00000000,
+ 0xc5cc0038, 0xc1400000, 0x58380000, 0xc9420078, 0x424d0000, 0x00000000, 0x42948000, 0x4520e000,
+ 0x8800163a, 0xc000fa40, 0xc9bc00f8, 0x6ff42000, 0xc3000000, 0xc5b4e000, 0xc2c07c00, 0x6f5ca000,
+ 0x42dd6000, 0x582c0022, 0xc98000f8, 0x00000000, 0x00000000, 0x5dd80000, 0x840003c2, 0x582c0026,
+ 0xca8000f8, 0x5838000a, 0xc98000f8, 0xc000ea10, 0xc2400000, 0xca7c0070, 0x6d9c8000, 0x41d8e000,
+ 0x425d2000, 0x5a644000, 0x582c002e, 0xc98000f8, 0x582c0030, 0xc94000f8, 0x00000000, 0x00000000,
+ 0x4194e000, 0xd9f800f8, 0x5ddc0080, 0x880000a2, 0x00000000, 0xa7400018, 0xc180001e, 0xc180015e,
+ 0xc1400000, 0x6d5c4010, 0x425c0000, 0xc1c00006, 0x755c8000, 0x5dd00000, 0xcd80183a, 0x5dd00002,
+ 0xcd80103a, 0x5dd00004, 0xcd80083a, 0x5dd00006, 0xcd80003a, 0x5b300008, 0x80000278, 0x58240002,
+ 0xc1800000, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9,
+ 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9,
+ 0xcd8000f9, 0xa7400018, 0xc18001e0, 0xc18001ea, 0xc1400000, 0x6d5c4010, 0x425c0000, 0xc90000f8,
+ 0xc1c00000, 0xc55c0308, 0x691c8008, 0xc5901838, 0x691c8018, 0xcd0000f8, 0x6d5c4010, 0x425c0000,
+ 0xc1c00006, 0x755c8000, 0x5dd00000, 0xcd80183a, 0x5dd00002, 0xcd80103a, 0x5dd00004, 0xcd80083a,
+ 0x5dd00006, 0xcd80003a, 0x5b300008, 0xdf9400f8, 0xc1008fe0, 0x6d5c4010, 0x411c0000, 0xc98000f8,
+ 0xc1c00000, 0xc55c0308, 0x699cc000, 0x6d9b0010, 0x6f1c4010, 0x425c0000, 0xc94000f8, 0xc1c00000,
+ 0xc71c0308, 0x695ca008, 0xc5941838, 0x695ca018, 0xcd4000f8, 0x6f1c4010, 0x425c0000, 0xc1c00006,
+ 0x771ca000, 0x5dd40000, 0xcd80183a, 0x5dd40002, 0xcd80103a, 0x5dd40004, 0xcd80083a, 0x5dd40006,
+ 0xcd80003a, 0x5b300002, 0x582c0022, 0xc1c00000, 0xcdc000f8, 0x80000e18, 0xdb8800f9, 0xdb4800f8,
+ 0xc2400000, 0xdf240038, 0xc0004024, 0xcb8000f8, 0x00000000, 0xc3400000, 0xc7b50038, 0xc2800000,
+ 0xc7a88018, 0xc000fa40, 0xc8fc00f8, 0xc2800000, 0x582c0004, 0xca800038, 0xa4ce0042, 0x58ec0040,
+ 0xc1c00000, 0x580c0004, 0xc9c00038, 0x00000000, 0x00000000, 0x729d4000, 0x7e412000, 0x76692000,
+ 0xc0400000, 0xc7840008, 0xc000a0ae, 0x5de40000, 0x84000070, 0xc0c00000, 0xc8c000f8, 0x5dc40000,
+ 0xdcb800fb, 0xdcb400fa, 0x84000ffa, 0x5dcc0000, 0xdcb800fb, 0xdcb400fa, 0x84000fda, 0xc0c00000,
+ 0xccc000f8, 0x800001b8, 0xc0c00002, 0xccc000f8, 0xc65000f8, 0x61010028, 0x5dc40000, 0x84000018,
+ 0x62410008, 0x800002e8, 0x6e144000, 0x59544d08, 0xc0400000, 0x58140004, 0xc84000b8, 0xa78200d0,
+ 0xc0800000, 0xc1c00000, 0x6e1c2000, 0x59dc5fe0, 0x581c0002, 0xc8820078, 0x581c0000, 0xc9c00078,
+ 0xc1800000, 0x58140006, 0xc9800078, 0x409ce000, 0xc0800000, 0x581c0000, 0xc8800078, 0x00000000,
+ 0x00000000, 0x40b44000, 0x4588e000, 0x88000030, 0xc1c00002, 0x69e0e000, 0x7dc0e000, 0x765d2000,
+ 0x80000038, 0xa7800030, 0x5dc40000, 0x84000022, 0xc1ee0002, 0x75c4e000, 0xc4cc2002, 0x61010028,
+ 0xa60afed0, 0x00000000, 0x5de40000, 0xdcb800fb, 0xdcb400fa, 0x84000e22, 0x5dcc0000, 0x840000ba,
+ 0xa78000b0, 0x62810028, 0x840000a2, 0x6e0c4000, 0x58cc4d08, 0xc1000000, 0x580c0004, 0xc90000b8,
+ 0x580c0000, 0xc98000b8, 0x7d00a000, 0xc1f00002, 0x5ddc0002, 0x755ca000, 0x59540002, 0xc1ee0002,
+ 0x75d0e000, 0xc5d400fa, 0x45948000, 0x580c0004, 0xcd0000b8, 0x8000ff60, 0x5de40000, 0xdcb800fb,
+ 0xdcb400fa, 0x84000d42, 0x62410008, 0xa7800098, 0x00000000, 0xc0c00000, 0xc65000f8, 0x6100a028,
+ 0x6d584000, 0x59984d08, 0xc0400000, 0x58180004, 0xc84000b8, 0x00000000, 0x00000000, 0xa46e002a,
+ 0x44c4e000, 0x88000018, 0xc56000f8, 0xc44c00f8, 0x6100a028, 0xa54aff98, 0x6e184000, 0x59984d08,
+ 0xc0400000, 0xc0800000, 0x6e1c2000, 0x59dc5fe0, 0x581c0002, 0xc8420078, 0x581c0000, 0xc8800078,
+ 0xc1400000, 0x58180006, 0xc9400078, 0x40484000, 0xc0c00000, 0x58080000, 0xc8c00078, 0x00000000,
+ 0xa7820038, 0x40f42000, 0x5dd5fffe, 0x84000022, 0x4544a000, 0x58180006, 0xcd400078, 0xa7800088,
+ 0xc0400000, 0x58180000, 0xc84000b8, 0xc1000000, 0x58180004, 0xc90000b8, 0x5dc40000, 0x8400004a,
+ 0xc1ee0002, 0x5ddc0002, 0x445ce000, 0x8400002a, 0x450c8000, 0x45348000, 0x58180004, 0xcd0000b8,
+ 0x6e106000, 0x5910b640, 0x58100006, 0xc98000f8, 0x58100004, 0xc94000f8, 0x418cc000, 0x58100006,
+ 0xcd8000f8, 0x59540002, 0x58100004, 0xcd4000f8, 0x6e242000, 0x5a645fe0, 0xc0c00000, 0x58240002,
+ 0xc8c20078, 0xc1000000, 0x58240000, 0xc9020038, 0x582c002a, 0xcc8000f8, 0x582c002c, 0xce0000f8,
+ 0x6d102000, 0x58cc0004, 0x450ce000, 0xc1c00000, 0xc5cc00fe, 0x58240002, 0x6cde0000, 0xcdc21078,
+ 0xc0e00002, 0x68e06000, 0xd8f000f8, 0xdcb800f9, 0xdcb400f8, 0xc0006910, 0xc8c000f9, 0xc90000f8,
+ 0xc1c00000, 0xc1400040, 0x60c04000, 0x7494e000, 0x8400007a, 0xc1400080, 0x61004000, 0x58880040,
+ 0x7494e000, 0x84000052, 0x00000000, 0xab6c0002, 0x00000000, 0x00000000, 0x984047e8, 0xc0006902,
+ 0xc8c000f8, 0xc3c00000, 0x8000ff58, 0xc0006910, 0xc1c00000, 0xc49ca000, 0x401c0000, 0xc8c000f8,
+ 0xc1000002, 0xc1400000, 0xc4940020, 0x6914e000, 0x70dc6000, 0xccc000f8, 0x582c0020, 0xcc8000f8,
+ 0xc1c00002, 0x582c0022, 0xcdc000f8, 0xc2409c00, 0x6c9c6000, 0x425d2000, 0xc2807600, 0x6c9c6000,
+ 0x429d4000, 0x582c002c, 0xc98000f8, 0x582c0026, 0xce8000f8, 0x582c0028, 0xce4000f8, 0x58240008,
+ 0xcd8000f8, 0x5838000a, 0xc98000f8, 0xc000ea10, 0xc2000000, 0xca3c0070, 0x6d9c8000, 0x41d8e000,
+ 0x421d0000, 0x5a204000, 0x582c002a, 0xc98000f8, 0xc1400000, 0xc1000000, 0x58180000, 0xc942e020,
+ 0x58180002, 0xc90000e0, 0x5828000e, 0xcd8000f8, 0x58280002, 0xc1c00000, 0xcdc00078, 0x41148000,
+ 0x58280004, 0xcd0000e0, 0x58a40000, 0x586c0008, 0xc44000f8, 0xc8c000f9, 0xc90000f9, 0xc94000f8,
+ 0xc48000f8, 0xccc000f9, 0xcd0000f9, 0xcd4000f9, 0x5df00000, 0x84000138, 0x58200000, 0xc1800000,
+ 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9,
+ 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9, 0xcd8000f9,
+ 0xcd8000f9, 0xc18001ea, 0xc1c00002, 0x75f4e000, 0xc1c001e0, 0xc5d800fa, 0xc1400000, 0x6d5c4010,
+ 0x421c0000, 0xc1c00006, 0x755c8000, 0x5dd00000, 0xcd80183a, 0x5dd00002, 0xcd80103a, 0x5dd00004,
+ 0xcd80083a, 0x5dd00006, 0xcd80003a, 0x5b300008, 0xc000fa40, 0xc93c00f8, 0xc1400000, 0x582c0002,
+ 0xc9428018, 0xc0400000, 0xc0800080, 0x44944000, 0xc45800f8, 0xc1c00200, 0x75d0e000, 0xc49c00f8,
+ 0xc5d800fa, 0x582c0030, 0xcd4000f8, 0xd97800f8, 0x5828000e, 0xc9c000f8, 0xc0c00000, 0x582c0002,
+ 0xc8c10038, 0xc1000000, 0x581c0000, 0xc9000078, 0x00000000, 0x00000000, 0xc50800f8, 0x4518e000,
+ 0xc59c00f8, 0xc5c800fc, 0xc4d400f8, 0x44c8e000, 0xc49c00f8, 0xc5d400fc, 0x582c002e, 0xcd4000f8,
+ 0xdf9000f8, 0x4150e000, 0xd9f800f8, 0x41f0e000, 0x5ddc0086, 0x88000082, 0xc18000a0, 0x6f1c4010,
+ 0x421c0000, 0xc1c00006, 0x771ca000, 0x5dd40000, 0xcd80183a, 0x5dd40002, 0xcd80103a, 0x5dd40004,
+ 0xcd80083a, 0x5dd40006, 0xcd80003a, 0x5b300002, 0x80000158, 0x00000000, 0x00000000, 0x00000000,
+ 0xdf9400f8, 0xc1008fe0, 0x6d5c4010, 0x411c0000, 0xc98000f8, 0xc1c00000, 0xc55c0308, 0x699cc000,
+ 0x6d9b0010, 0x6f1c4010, 0x421c0000, 0xc1c00006, 0x771c6000, 0x5dcc0000, 0xcd80183a, 0x5dcc0002,
+ 0xcd80103a, 0x5dcc0004, 0xcd80083a, 0x5dcc0006, 0xcd80003a, 0x5b300002, 0xc18000a0, 0x6f1c4010,
+ 0x421c0000, 0xc1c00006, 0x771ca000, 0x5dd40000, 0xcd80183a, 0x5dd40002, 0xcd80103a, 0x5dd40004,
+ 0xcd80083a, 0x5dd40006, 0xcd80003a, 0x5b300002, 0x582c0022, 0xc1c00000, 0xcdc000f8, 0x00000000,
+ 0x00000000, 0x5df00088, 0x880002f8, 0x582c0020, 0xc98000f8, 0xc2800000, 0xc2400000, 0xc5a80528,
+ 0x582c002e, 0xc98000f8, 0xc1000088, 0x45308000, 0xc51400f8, 0x4590e000, 0xc59c00f8, 0xc5d400fc,
+ 0xc5681930, 0x5838000a, 0xc90000f8, 0xc7281230, 0xc7e80008, 0xc5280b30, 0xd93800f8, 0xc1c00002,
+ 0xc5e80400, 0x4594e000, 0x8400001a, 0xc1c00000, 0xc5e80400, 0x5dd80000, 0x8400002a, 0xc1c00002,
+ 0xc5e80300, 0xc1c00002, 0xc5e80200, 0x582c0022, 0xc94000f8, 0xc7640e08, 0x00000000, 0x5d540002,
+ 0x8400001a, 0xc1c00002, 0xc5e40d00, 0xc0c00000, 0xc68f2030, 0x430c8000, 0xc5241838, 0xc0800088,
+ 0x44904000, 0xc1c00000, 0xc5c800fc, 0x582c0030, 0xc94000f8, 0xc0400000, 0x582c0002, 0xc8420018,
+ 0xc49000f8, 0x4548e000, 0xc55c00f8, 0xc5d000fc, 0xc5241418, 0x44546000, 0xc4e41018, 0x4550a000,
+ 0x582c0030, 0xcd4000f8, 0xc0c00000, 0xc68f2030, 0x458cc000, 0x582c002e, 0xcd8000f8, 0x43118000,
+ 0x430d8000, 0xdf9800f8, 0xc000ea10, 0xc1400000, 0xc97c0070, 0x6d9c8000, 0x41d8e000, 0x415ca000,
+ 0x59544000, 0x00000000, 0xc1000000, 0xc0000000, 0xc9140038, 0x00000000, 0x00000000, 0x59100002,
+ 0xcd140038, 0x98404d30, 0xc68c00f8, 0xc65000f8, 0x00000000, 0x5df00088, 0x8800ef02, 0x00000000,
+ 0x80000008, 0x5df00000, 0x840000ba, 0xc1c00002, 0xc000691c, 0xcdc000f8, 0x5838000a, 0xc94000f8,
+ 0xc1000000, 0xc000ea14, 0xc93c0038, 0x59540002, 0x00000000, 0x4514e000, 0xc1c00000, 0xc5d400fe,
+ 0x5838000a, 0xcd4000f8, 0x58380004, 0xc94000f8, 0x00000000, 0x00000000, 0x59540002, 0x58380004,
+ 0xcd4000f8, 0x5df00000, 0x84000058, 0xa7400020, 0x00000000, 0x6ff42000, 0x8000ea00, 0x5bfc0002,
+ 0x5dfc0002, 0x8400e812, 0x00000000, 0x00000000, 0x00000000, 0xab6c0052, 0x984047e8, 0xc0006902,
+ 0xc8c000f8, 0xc3c00000, 0xab6c002a, 0x984047e8, 0xc0006902, 0xc8c000f8, 0xc3c00000, 0xc0004032,
+ 0xcbc000f8, 0xc0004038, 0xcb8000f8, 0xc000691a, 0xcb0000f8, 0xc000403a, 0xcb4000f8, 0xc72c00f8,
+ 0xa7800058, 0xc2800000, 0x00000000, 0x984041b8, 0xc0c07c80, 0xc0007c00, 0x00000000, 0x98404220,
+ 0xc0006952, 0xc80000f8, 0xc1000000, 0xa7900058, 0xc2800002, 0x00000000, 0x984041b8, 0xc0c07c80,
+ 0xc0007c00, 0x00000000, 0x98404220, 0xc0006952, 0xc80000f8, 0xc1000000, 0x472ce000, 0x8400023a,
+ 0xc0c00000, 0xc78e0020, 0xc1c00002, 0x69cc8000, 0xc78f0020, 0x69cce000, 0x711c8000, 0xc000f41a,
+ 0xcfc000f8, 0xc1c00000, 0xc7dc4050, 0x581cc000, 0xcb0000f8, 0x00000000, 0x00000000, 0x76d16000,
+ 0x7d008000, 0x77118000, 0x732d8000, 0xcf0000f8, 0xc000691a, 0xcec000f8, 0x80000180, 0x5ea80000,
+ 0xc40c00fa, 0xc2400000, 0x580c0004, 0xca400038, 0x58cc0040, 0xc1c00000, 0x580c0004, 0xc9c00038,
+ 0x9c400000, 0x00000000, 0x00000000, 0x725d2000, 0x62406028, 0x84000032, 0xc9cc00f8, 0x00000000,
+ 0x00000000, 0x411c8000, 0x8000ffd0, 0xc1400000, 0xc7970020, 0x6f4e0010, 0x5de80000, 0xc74c00fa,
+ 0xc7960022, 0xc1c00000, 0xc4dd0038, 0x45d0e000, 0x88000048, 0xc1c00000, 0xc4dc0038, 0x451ce000,
+ 0x88000050, 0x9c400000, 0x00000000, 0x00000000, 0x00000000, 0xc1c00002, 0x9c400000, 0x69d4e000,
+ 0x7dc0e000, 0x76dd6000, 0x9c400000, 0xc1c00002, 0x69d4e000, 0x72dd6000, 0xc0004028, 0xcbc000f8,
+ 0xc000691c, 0xcb8000f8, 0xa7c0c780, 0x00000000, 0x5df80000, 0x8400c768, 0xc1c00002, 0xc000e070,
+ 0xcdc00000, 0x8000c748, 0xdcbc00f9, 0xdcb800f8, 0xdd3400f9, 0xc2400040, 0xc000690c, 0xc8c000f9,
+ 0xc90000f8, 0xc1c00000, 0x60c18000, 0x7724e000, 0x84000052, 0x61018000, 0x7724e000, 0x84000032,
+ 0x98404ec0, 0x00000000, 0x00000000, 0x00000000, 0x8000ff90, 0x5b300040, 0xc2c09400, 0x6f1c6000,
+ 0x42dd6000, 0xc2809800, 0x429d4000, 0x58340022, 0xcf0000f8, 0x582c0008, 0xcf8000f8, 0xc000690c,
+ 0xc1c00000, 0xc71ca000, 0x401c0000, 0xc8c000f8, 0xc2000002, 0x6a30e000, 0x70dc6000, 0xccc000f8,
+ 0x58340008, 0xc8c000f9, 0xc90000f9, 0xc94000f9, 0x582c0000, 0xccc000f9, 0xcd0000f9, 0xcd4000f9,
+ 0x58340010, 0xc9c000f9, 0xc8c000f9, 0xc90000f9, 0xc94000f9, 0xc98000f9, 0xc84000f9, 0xc88000f9,
+ 0x58280000, 0xcdc000f9, 0xccc000f9, 0xcd0000f9, 0xcd4000f9, 0xcd8000f9, 0xcc4000f9, 0xcc8000f9,
+ 0xc1c00000, 0x5828000e, 0xc9c3e000, 0x00000000, 0x00000000, 0x5ddc0002, 0x840001ba, 0xc0006908,
+ 0xc8c000f8, 0xc0004c00, 0xc1000000, 0x400c0000, 0x58000000, 0xc903e000, 0x00000000, 0x00000000,
+ 0x5dd00002, 0x840000e8, 0xc1000000, 0x58000002, 0xc90000e0, 0xc1c00000, 0xc0004022, 0xc9c20008,
+ 0x5828000e, 0xcd0000e0, 0x411ce000, 0x58280004, 0xcdc000e0, 0x5828000e, 0xc1fe0002, 0xcdc3ff00,
+ 0x5828000e, 0xc1fc0000, 0xcdc3de00, 0x58340020, 0xc1c00000, 0xcdc000f8, 0x58cc0004, 0xc1c00100,
+ 0x45cce000, 0xc1c00000, 0xc5cc00fe, 0xc0006908, 0xccc000f8, 0x800000f8, 0xc0c0b600, 0x6f9c6000,
+ 0x40dc6000, 0x580c0004, 0xc90000f8, 0x5828000e, 0xc1fc0002, 0xcdc3de00, 0x58340020, 0xc1c00002,
+ 0xcdc000f8, 0x59100002, 0x580c0004, 0xcd0000f8, 0x80000080, 0xc0c00000, 0xc0004022, 0xc8c20008,
+ 0xc1000000, 0x5828000e, 0xc90000e0, 0x5828000e, 0xc1fc0000, 0xcdc3de00, 0x58340020, 0xc1c00000,
+ 0xcdc000f8, 0x410ce000, 0x58280004, 0xcdc000e0, 0x94000000, 0xc1c00002, 0xc000691c, 0xcdc000f8,
+ 0xd87800f8, 0xc3800000, 0x580c7400, 0xca4000f9, 0xca0000f8, 0xc3400000, 0xc67c0008, 0xc639c008,
+ 0xc674a028, 0xc0c00000, 0xc64d6030, 0xc000ea10, 0xc3000000, 0xcb3c0070, 0x6cdc8000, 0x41cce000,
+ 0x431d8000, 0x5b304000, 0x6faca000, 0x5aec7c00, 0xc0c00000, 0xc0000000, 0xc8f00038, 0x6f686000,
+ 0x5aa89c00, 0x5ccc0002, 0xccf00038, 0xc1000000, 0xc6128018, 0x5dd00000, 0x840000f2, 0xc1800000,
+ 0xc0800000, 0xc61a0018, 0xc60b0038, 0xc1c40002, 0x419cc000, 0x6d9c4010, 0x429c0000, 0xc94000f8,
+ 0xc1c00000, 0xc59c0308, 0x695ca000, 0x6d570010, 0x59980002, 0x6c9c4010, 0x431c0000, 0xc1c00006,
+ 0x749c2000, 0x5dc40000, 0xcd40183a, 0x5dc40002, 0xcd40103a, 0x5dc40004, 0xcd40083a, 0x5dc40006,
+ 0xcd40003a, 0x58880002, 0x5d100002, 0x8400ff50, 0xa61a00a0, 0x582c002a, 0xc90000f8, 0xc0000000,
+ 0xc1c00000, 0xcdd3ff00, 0xc1000002, 0x58280008, 0xc94000f8, 0x5df40040, 0xc0006912, 0x44100004,
+ 0xc98000f8, 0x6934e000, 0x7dc0e000, 0x759cc000, 0xcd8000f8, 0xc1b00002, 0x6994c000, 0xd9b000f8,
+ 0x5ccc0000, 0x84000160, 0x6fcca000, 0x58cc7d80, 0x580c0006, 0xc90000f8, 0xc1400000, 0xc615a000,
+ 0x59100002, 0x580c0006, 0xcd0000f8, 0xc1c00000, 0x7d40a000, 0xc55c0000, 0x582c0024, 0xcdc000f8,
+ 0xa61a00e8, 0x7f80e000, 0xc5f80000, 0x6faca000, 0x5aec7c00, 0x582c0024, 0xc94000f8, 0x580c0004,
+ 0xc98000f8, 0x5dd40002, 0x8400009a, 0xc000ea28, 0x6d1d2000, 0xcdfd2928, 0xc000ea28, 0xc1d00002,
+ 0xcdfd0800, 0xc0006948, 0xc9c000f8, 0x403c0000, 0x00000000, 0x41d0e000, 0xcdc000f8, 0x4590c000,
+ 0x580c0004, 0xcd8000f8, 0x580c0006, 0xc1c00000, 0xcdc000f8, 0xc0006902, 0xc8c000f8, 0x00000000,
+ 0x00000000, 0x58cc0004, 0xc1c00200, 0x45cce000, 0xc1c00000, 0xc5cc00fe, 0xccc000f8, 0xc000f01e,
+ 0xc1d00002, 0xcdc10800, 0xdf8400f8, 0x9c400000, 0x00000000, 0x00000000, 0x00000000, 0xc0006904,
+ 0xc94000f8, 0xab68008a, 0x00000000, 0x58147200, 0xccc000f9, 0xcd0000f9, 0xc000f016, 0xc1d00002,
+ 0xcdc10800, 0x59540004, 0xc1c00200, 0x45d4e000, 0xc1c00000, 0xc5d400fe, 0x9c400000, 0xc0006904,
+ 0xcd4000f8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000ff60, 0xc0006906, 0xc94000f8,
+ 0xab6a008a, 0x00000000, 0x58147400, 0xccc000f9, 0xcd0000f9, 0xc000f404, 0xc1d00002, 0xcdc10800,
+ 0x59540004, 0xc1c00200, 0x45d4e000, 0xc1c00000, 0xc5d400fe, 0x9c400000, 0xc0006906, 0xcd4000f8,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8000ff60, 0xc08000a0, 0x74d0c000, 0x84000090,
+ 0x78d0c000, 0x8400006a, 0x61800018, 0x6180e008, 0x441cc000, 0x84000060, 0x5d940000, 0x84000050,
+ 0x60c04008, 0xa48a0040, 0x9c400000, 0x61004008, 0x58880040, 0x00000000, 0xa5400018, 0x00000000,
+ 0xc0800080, 0x9c400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xc000f412, 0xc9c000f8, 0xc1800000, 0xc0800000, 0xa5c004e8, 0xc5d82028, 0x6d886000, 0x59089800,
+ 0x5810000e, 0xc9c3c000, 0x59489400, 0xd9b800f8, 0xa5c0044a, 0x58140008, 0xc98000f8, 0xc0c07b00,
+ 0xc0800000, 0x6d9ca000, 0x40dc6000, 0xd9b800f8, 0x580c0002, 0xc8808000, 0x00000000, 0x00000000,
+ 0xa480004a, 0x580c0004, 0xc98000f8, 0x58140002, 0xc88000f8, 0x00000000, 0x00000000, 0x4498e000,
+ 0x84000110, 0xc1c00000, 0x580c0002, 0xc9c04000, 0x00000000, 0x00000000, 0xa5c0004a, 0x580c0006,
+ 0xc98000f8, 0x58140004, 0xc88000f8, 0x00000000, 0x00000000, 0x4498e000, 0x840000a0, 0xc0800000,
+ 0x58100002, 0xc8800078, 0x580c001e, 0xc94000f8, 0xc1800000, 0x580c0002, 0xc9810038, 0x40944000,
+ 0xa4be0052, 0xc1400000, 0x4498e000, 0x88000118, 0x580c0002, 0xc940e000, 0x00000000, 0x00000000,
+ 0xa54000ca, 0xc1c00000, 0x00000000, 0x00000000, 0x00000000, 0xdf9400f8, 0x00000000, 0x00000000,
+ 0xc1800000, 0xc5582000, 0xa5400042, 0xc000fb64, 0xc1c00002, 0xcdd80000, 0xc000facc, 0xc1c40002,
+ 0xcdd84200, 0x80000220, 0xc000fb64, 0xc1c20002, 0xcdd82100, 0xc000facc, 0xc1c60002, 0xcdd86300,
+ 0x800001e8, 0x580c0002, 0xc9c10038, 0x00000000, 0x00000000, 0x589c0000, 0xc000690a, 0xc94000f8,
+ 0xc1c00000, 0x5810000e, 0xc9c000e0, 0x59944c00, 0x58180000, 0xcc800078, 0x58180002, 0xcdc000e0,
+ 0x58180000, 0xc1fa0002, 0xcdc3bd00, 0x58180000, 0xc1f80002, 0xcdc39c00, 0x58180000, 0xc1fe0000,
+ 0xcdc3ff00, 0x59540004, 0xc1c00100, 0x45d4e000, 0xc1c00000, 0xc5d400fe, 0xc000690a, 0xcd4000f8,
+ 0xc000e408, 0xc1c00002, 0xcdc000f8, 0x5810000e, 0xc1fe0000, 0xcdc3ff00, 0xdf9400f8, 0xc1800000,
+ 0x58100002, 0xc9800078, 0x6d486000, 0x5888b600, 0x58080006, 0xc9c000f8, 0x00000000, 0x00000000,
+ 0x419cc000, 0x58080006, 0xcd8000f8, 0xc1800000, 0xc5582000, 0xa540002a, 0xc000fb60, 0xc1c40002,
+ 0xcdd84200, 0x80000020, 0xc000fb60, 0xc1c60002, 0xcdd86300, 0xdf9400f8, 0xc1800002, 0x00000000,
+ 0x00000000, 0x5dd40040, 0xc000690e, 0x44180004, 0xc88000f8, 0x6994e000, 0x7dc0e000, 0x749c4000,
+ 0xcc8000f8, 0x9c400000, 0x00000000, 0x00000000, 0x00000000, 0xc3c00000, 0xc4fc8018, 0xc3800000,
+ 0x6fb44000, 0x5b744d08, 0xc3000000, 0x58340006, 0xcb020038, 0xc2c00000, 0xc2800000, 0x5f300002,
+ 0x84000080, 0x58340006, 0xcac00078, 0x58340002, 0xca800078, 0xc2000000, 0x58340002, 0xca020078,
+ 0x42e92000, 0x00000000, 0x4624e000, 0xc62400fc, 0x58340000, 0xcb030038, 0x58340006, 0xce400078,
+ 0x58340006, 0x6f1e0000, 0xcdc21038, 0x5bb80002, 0x47bce000, 0x8800ff1a, 0x8000b410, 0x00000000,
+ 0x00000000, 0x00000000,};
+
+static unsigned int firmware_binary_data[] = {
+};
+
+
+#endif // IFXMIPS_PTM_FW_VR9_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_amazon_se.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_amazon_se.h
new file mode 100644
index 0000000000..f912039c38
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_amazon_se.h
@@ -0,0 +1,186 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_ppe_amazon_se.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (PPE register for Amazon-SE)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_PTM_PPE_AMAZON_SE_H
+#define IFXMIPS_PTM_PPE_AMAZON_SE_H
+
+
+
+/*
+ * FPI Configuration Bus Register and Memory Address Mapping
+ */
+#define IFX_PPE (KSEG1 | 0x1E180000)
+#define PP32_DEBUG_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0000) << 2)))
+#define PPM_INT_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0030) << 2)))
+#define PP32_INTERNAL_RES_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0040) << 2)))
+#define CDM_CODE_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x1000) << 2)))
+#define PPE_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x4000) << 2)))
+#define CDM_DATA_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x5000) << 2)))
+#define PPM_INT_UNIT_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6000) << 2)))
+#define PPM_TIMER0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6100) << 2)))
+#define PPM_TASK_IND_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6200) << 2)))
+#define PPS_BRK_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6300) << 2)))
+#define PPM_TIMER1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6400) << 2)))
+#define SB_RAM0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8200) << 2)))
+#define SB_RAM1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8C00) << 2)))
+#define QSB_CONF_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0xC000) << 2)))
+
+/*
+ * DWORD-Length of Memory Blocks
+ */
+#define PP32_DEBUG_REG_DWLEN 0x0030
+#define PPM_INT_REG_DWLEN 0x0010
+#define PP32_INTERNAL_RES_DWLEN 0x00C0
+#define CDM_CODE_MEMORYn_DWLEN(n) ((n) == 0 ? 0x1000 : 0x0800)
+#define PPE_REG_DWLEN 0x1000
+#define CDM_DATA_MEMORY_DWLEN CDM_CODE_MEMORYn_DWLEN(1)
+#define PPM_INT_UNIT_DWLEN 0x0100
+#define PPM_TIMER0_DWLEN 0x0100
+#define PPM_TASK_IND_REG_DWLEN 0x0100
+#define PPS_BRK_DWLEN 0x0100
+#define PPM_TIMER1_DWLEN 0x0100
+#define SB_RAM0_DWLEN 0x0A00
+#define SB_RAM1_DWLEN 0x0A00
+#define QSB_CONF_REG_DWLEN 0x0100
+
+/*
+ * PP32 to FPI Address Mapping
+ */
+#define SB_BUFFER(__sb_addr) ((volatile unsigned int *)((((__sb_addr) >= 0x0000) && ((__sb_addr) <= 0x0FFF)) ? PPE_REG_ADDR((__sb_addr) - 0x0000) : \
+ (((__sb_addr) >= 0x2200) && ((__sb_addr) <= 0x2BFF)) ? SB_RAM0_ADDR((__sb_addr) - 0x2200) : \
+ (((__sb_addr) >= 0x2C00) && ((__sb_addr) <= 0x35FF)) ? SB_RAM1_ADDR((__sb_addr) - 0x2C00) : \
+ 0))
+
+/*
+ * PP32 Debug Control Register
+ */
+#define NUM_OF_PP32 1
+
+#define PP32_DBG_CTRL(n) PP32_DEBUG_REG_ADDR(n, 0x0000)
+
+#define DBG_CTRL_RESTART 0
+#define DBG_CTRL_STOP 1
+
+#define PP32_CTRL_CMD(n) PP32_DEBUG_REG_ADDR(n, 0x0B00)
+ #define PP32_CTRL_CMD_RESTART (1 << 0)
+ #define PP32_CTRL_CMD_STOP (1 << 1)
+ #define PP32_CTRL_CMD_STEP (1 << 2)
+ #define PP32_CTRL_CMD_BREAKOUT (1 << 3)
+
+#define PP32_CTRL_OPT(n) PP32_DEBUG_REG_ADDR(n, 0x0C00)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP_ON (3 << 0)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP_OFF (2 << 0)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN_ON (3 << 2)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN_OFF (2 << 2)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN_ON (3 << 4)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN_OFF (2 << 4)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT_ON (3 << 6)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT_OFF (2 << 6)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP(n) (*PP32_CTRL_OPT(n) & (1 << 0))
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN(n) (*PP32_CTRL_OPT(n) & (1 << 2))
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN(n) (*PP32_CTRL_OPT(n) & (1 << 4))
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT(n) (*PP32_CTRL_OPT(n) & (1 << 6))
+
+#define PP32_BRK_PC(n, i) PP32_DEBUG_REG_ADDR(n, 0x0900 + (i) * 2)
+#define PP32_BRK_PC_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0901 + (i) * 2)
+#define PP32_BRK_DATA_ADDR(n, i) PP32_DEBUG_REG_ADDR(n, 0x0904 + (i) * 2)
+#define PP32_BRK_DATA_ADDR_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0905 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_RD(n, i) PP32_DEBUG_REG_ADDR(n, 0x0908 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_RD_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0909 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_WR(n, i) PP32_DEBUG_REG_ADDR(n, 0x090C + (i) * 2)
+#define PP32_BRK_DATA_VALUE_WR_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x090D + (i) * 2)
+ #define PP32_BRK_CONTEXT_MASK(i) (1 << (i))
+ #define PP32_BRK_CONTEXT_MASK_EN (1 << 4)
+ #define PP32_BRK_COMPARE_GREATER_EQUAL (1 << 5) // valid for break data value rd/wr only
+ #define PP32_BRK_COMPARE_LOWER_EQUAL (1 << 6)
+ #define PP32_BRK_COMPARE_EN (1 << 7)
+
+#define PP32_BRK_SRC(n) PP32_DEBUG_REG_ADDR(n, 0x0F00)
+#define PP32_BRK_TRIG(n) PP32_BRK_SRC(n)
+ #define PP32_BRK_GRPi_PCn_ON(i, n) ((3 << ((n) * 2)) << ((i) * 16))
+ #define PP32_BRK_GRPi_PCn_OFF(i, n) ((2 << ((n) * 2)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_ADDRn_ON(i, n) ((3 << ((n) * 2 + 4)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_ADDRn_OFF(i, n) ((2 << ((n) * 2 + 4)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn_ON(i, n) ((3 << ((n) * 2 + 8)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn_OFF(i, n)((2 << ((n) * 2 + 8)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn_ON(i, n) ((3 << ((n) * 2 + 12)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn_OFF(i, n)((2 << ((n) * 2 + 12)) << ((i) * 16))
+ #define PP32_BRK_GRPi_PCn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n))) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_ADDRn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 2)) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 4)) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 6)) << ((i) * 8)))
+
+#define PP32_CPU_STATUS(n) PP32_DEBUG_REG_ADDR(n, 0x0D00)
+#define PP32_HALT_STAT(n) PP32_CPU_STATUS(n)
+#define PP32_DBG_CUR_PC(n) PP32_DEBUG_REG_ADDR(n, 0x0F80)
+ #define PP32_CPU_USER_STOPPED(n) (*PP32_CPU_STATUS(n) & (1 << 0))
+ #define PP32_CPU_USER_BREAKIN_RCV(n) (*PP32_CPU_STATUS(n) & (1 << 1))
+ #define PP32_CPU_USER_BREAKPOINT_MET(n) (*PP32_CPU_STATUS(n) & (1 << 2))
+ #define PP32_CPU_CUR_PC(n) (*PP32_DBG_CUR_PC(n) & 0xFFFF)
+
+#define PP32_BREAKPOINT_REASONS(n) PP32_DEBUG_REG_ADDR(n, 0x0A00)
+ #define PP32_BRK_PC_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << (i)))
+ #define PP32_BRK_DATA_ADDR_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 2)))
+ #define PP32_BRK_DATA_VALUE_RD_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 4)))
+ #define PP32_BRK_DATA_VALUE_WR_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 6)))
+ #define PP32_BRK_DATA_VALUE_RD_LO_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 8)))
+ #define PP32_BRK_DATA_VALUE_RD_GT_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 9)))
+ #define PP32_BRK_DATA_VALUE_WR_LO_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 12)))
+ #define PP32_BRK_DATA_VALUE_WR_GT_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 13)))
+// #define PP32_BRK_CUR_CONTEXT(n) ((*PP32_BREAKPOINT_REASONS(n) >> 16) & 0x03)
+#define PP32_DBG_TASK_NO(n) PP32_DEBUG_REG_ADDR(n, 0x0F81)
+ #define PP32_BRK_CUR_CONTEXT(n) (*PP32_DBG_TASK_NO(n) & 0x03)
+
+#define PP32_GP_REG_BASE(n) PP32_DEBUG_REG_ADDR(n, 0x0E00)
+#define PP32_GP_CONTEXTi_REGn(n, i, j) PP32_DEBUG_REG_ADDR(n, 0x0E00 + (i) * 16 + (j))
+
+/*
+ * Share Buffer
+ */
+#define SB_MST_PRI0 PPE_REG_ADDR(0x0300)
+#define SB_MST_PRI1 PPE_REG_ADDR(0x0301)
+
+/*
+ * EMA Registers
+ */
+#define EMA_CMDCFG PPE_REG_ADDR(0x0A00)
+#define EMA_DATACFG PPE_REG_ADDR(0x0A01)
+#define EMA_CMDCNT PPE_REG_ADDR(0x0A02)
+#define EMA_DATACNT PPE_REG_ADDR(0x0A03)
+#define EMA_ISR PPE_REG_ADDR(0x0A04)
+#define EMA_IER PPE_REG_ADDR(0x0A05)
+#define EMA_CFG PPE_REG_ADDR(0x0A06)
+#define EMA_SUBID PPE_REG_ADDR(0x0A07)
+
+#define EMA_ALIGNMENT 4
+
+/*
+ * Mailbox IGU1 Interrupt
+ */
+#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL13
+
+
+
+#endif // IFXMIPS_PTM_PPE_AMAZON_SE_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_ar9.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_ar9.h
new file mode 100644
index 0000000000..9355747af6
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_ar9.h
@@ -0,0 +1,213 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_ppe_ar9.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (PPE register for AR9)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_PTM_PPE_AR9_H
+#define IFXMIPS_PTM_PPE_AR9_H
+
+
+
+/*
+ * FPI Configuration Bus Register and Memory Address Mapping
+ */
+#define IFX_PPE (KSEG1 | 0x1E180000)
+#define PP32_DEBUG_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0000) << 2)))
+#define PPM_INT_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0030) << 2)))
+#define PP32_INTERNAL_RES_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0040) << 2)))
+#define CDM_CODE_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x1000) << 2)))
+#define PPE_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x4000) << 2)))
+#define CDM_DATA_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x5000) << 2)))
+#define PPM_INT_UNIT_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6000) << 2)))
+#define PPM_TIMER0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6100) << 2)))
+#define PPM_TASK_IND_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6200) << 2)))
+#define PPS_BRK_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6300) << 2)))
+#define PPM_TIMER1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6400) << 2)))
+#define SB_RAM0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8000) << 2)))
+#define SB_RAM1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8800) << 2)))
+#define SB_RAM2_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x9000) << 2)))
+#define SB_RAM3_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x9800) << 2)))
+#define SB_RAM4_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0xA000) << 2)))
+#define QSB_CONF_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0xC000) << 2)))
+
+/*
+ * DWORD-Length of Memory Blocks
+ */
+#define PP32_DEBUG_REG_DWLEN 0x0030
+#define PPM_INT_REG_DWLEN 0x0010
+#define PP32_INTERNAL_RES_DWLEN 0x00C0
+#define CDM_CODE_MEMORYn_DWLEN(n) 0x1000
+#define PPE_REG_DWLEN 0x1000
+#define CDM_DATA_MEMORY_DWLEN CDM_CODE_MEMORYn_DWLEN(1)
+#define PPM_INT_UNIT_DWLEN 0x0100
+#define PPM_TIMER0_DWLEN 0x0100
+#define PPM_TASK_IND_REG_DWLEN 0x0100
+#define PPS_BRK_DWLEN 0x0100
+#define PPM_TIMER1_DWLEN 0x0100
+#define SB_RAM0_DWLEN 0x0800
+#define SB_RAM1_DWLEN 0x0800
+#define SB_RAM2_DWLEN 0x0800
+#define SB_RAM3_DWLEN 0x0800
+#define SB_RAM4_DWLEN 0x0C00
+#define QSB_CONF_REG_DWLEN 0x0100
+
+/*
+ * PP32 to FPI Address Mapping
+ */
+#define SB_BUFFER(__sb_addr) ((volatile unsigned int *)((((__sb_addr) >= 0x0000) && ((__sb_addr) <= 0x0FFF)) ? PP32_DEBUG_REG_ADDR(0, (__sb_addr)): \
+ (((__sb_addr) >= 0x2000) && ((__sb_addr) <= 0x27FF)) ? SB_RAM0_ADDR((__sb_addr) - 0x2000) : \
+ (((__sb_addr) >= 0x2800) && ((__sb_addr) <= 0x2FFF)) ? SB_RAM1_ADDR((__sb_addr) - 0x2800) : \
+ (((__sb_addr) >= 0x3000) && ((__sb_addr) <= 0x37FF)) ? SB_RAM2_ADDR((__sb_addr) - 0x3000) : \
+ (((__sb_addr) >= 0x3800) && ((__sb_addr) <= 0x3FFF)) ? SB_RAM3_ADDR((__sb_addr) - 0x3800) : \
+ (((__sb_addr) >= 0x4000) && ((__sb_addr) <= 0x4BFF)) ? SB_RAM4_ADDR((__sb_addr) - 0x4000) : \
+ 0))
+
+/*
+ * PP32 Debug Control Register
+ */
+#define NUM_OF_PP32 1
+
+#define PP32_DBG_CTRL(n) PP32_DEBUG_REG_ADDR(n, 0x0000)
+
+#define DBG_CTRL_RESTART 0
+#define DBG_CTRL_STOP 1
+
+#define PP32_CTRL_CMD(n) PP32_DEBUG_REG_ADDR(n, 0x0B00)
+ #define PP32_CTRL_CMD_RESTART (1 << 0)
+ #define PP32_CTRL_CMD_STOP (1 << 1)
+ #define PP32_CTRL_CMD_STEP (1 << 2)
+ #define PP32_CTRL_CMD_BREAKOUT (1 << 3)
+
+#define PP32_CTRL_OPT(n) PP32_DEBUG_REG_ADDR(n, 0x0C00)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP_ON (3 << 0)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP_OFF (2 << 0)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN_ON (3 << 2)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN_OFF (2 << 2)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN_ON (3 << 4)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN_OFF (2 << 4)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT_ON (3 << 6)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT_OFF (2 << 6)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP(n) (*PP32_CTRL_OPT(n) & (1 << 0))
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN(n) (*PP32_CTRL_OPT(n) & (1 << 2))
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN(n) (*PP32_CTRL_OPT(n) & (1 << 4))
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT(n) (*PP32_CTRL_OPT(n) & (1 << 6))
+
+#define PP32_BRK_PC(n, i) PP32_DEBUG_REG_ADDR(n, 0x0900 + (i) * 2)
+#define PP32_BRK_PC_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0901 + (i) * 2)
+#define PP32_BRK_DATA_ADDR(n, i) PP32_DEBUG_REG_ADDR(n, 0x0904 + (i) * 2)
+#define PP32_BRK_DATA_ADDR_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0905 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_RD(n, i) PP32_DEBUG_REG_ADDR(n, 0x0908 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_RD_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0909 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_WR(n, i) PP32_DEBUG_REG_ADDR(n, 0x090C + (i) * 2)
+#define PP32_BRK_DATA_VALUE_WR_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x090D + (i) * 2)
+ #define PP32_BRK_CONTEXT_MASK(i) (1 << (i))
+ #define PP32_BRK_CONTEXT_MASK_EN (1 << 4)
+ #define PP32_BRK_COMPARE_GREATER_EQUAL (1 << 5) // valid for break data value rd/wr only
+ #define PP32_BRK_COMPARE_LOWER_EQUAL (1 << 6)
+ #define PP32_BRK_COMPARE_EN (1 << 7)
+
+#define PP32_BRK_TRIG(n) PP32_DEBUG_REG_ADDR(n, 0x0F00)
+ #define PP32_BRK_GRPi_PCn_ON(i, n) ((3 << ((n) * 2)) << ((i) * 16))
+ #define PP32_BRK_GRPi_PCn_OFF(i, n) ((2 << ((n) * 2)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_ADDRn_ON(i, n) ((3 << ((n) * 2 + 4)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_ADDRn_OFF(i, n) ((2 << ((n) * 2 + 4)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn_ON(i, n) ((3 << ((n) * 2 + 8)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn_OFF(i, n)((2 << ((n) * 2 + 8)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn_ON(i, n) ((3 << ((n) * 2 + 12)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn_OFF(i, n)((2 << ((n) * 2 + 12)) << ((i) * 16))
+ #define PP32_BRK_GRPi_PCn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n))) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_ADDRn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 2)) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 4)) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 6)) << ((i) * 8)))
+
+#define PP32_CPU_STATUS(n) PP32_DEBUG_REG_ADDR(n, 0x0D00)
+#define PP32_HALT_STAT(n) PP32_CPU_STATUS(n)
+#define PP32_DBG_CUR_PC(n) PP32_CPU_STATUS(n)
+ #define PP32_CPU_USER_STOPPED(n) (*PP32_CPU_STATUS(n) & (1 << 0))
+ #define PP32_CPU_USER_BREAKIN_RCV(n) (*PP32_CPU_STATUS(n) & (1 << 1))
+ #define PP32_CPU_USER_BREAKPOINT_MET(n) (*PP32_CPU_STATUS(n) & (1 << 2))
+ #define PP32_CPU_CUR_PC(n) (*PP32_CPU_STATUS(n) >> 16)
+
+#define PP32_BREAKPOINT_REASONS(n) PP32_DEBUG_REG_ADDR(n, 0x0A00)
+ #define PP32_BRK_PC_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << (i)))
+ #define PP32_BRK_DATA_ADDR_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 2)))
+ #define PP32_BRK_DATA_VALUE_RD_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 4)))
+ #define PP32_BRK_DATA_VALUE_WR_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 6)))
+ #define PP32_BRK_DATA_VALUE_RD_LO_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 8)))
+ #define PP32_BRK_DATA_VALUE_RD_GT_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 9)))
+ #define PP32_BRK_DATA_VALUE_WR_LO_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 12)))
+ #define PP32_BRK_DATA_VALUE_WR_GT_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 13)))
+ #define PP32_BRK_CUR_CONTEXT(n) ((*PP32_BREAKPOINT_REASONS(n) >> 16) & 0x03)
+
+#define PP32_GP_REG_BASE(n) PP32_DEBUG_REG_ADDR(n, 0x0E00)
+#define PP32_GP_CONTEXTi_REGn(n, i, j) PP32_DEBUG_REG_ADDR(n, 0x0E00 + (i) * 16 + (j))
+
+/*
+ * Share Buffer Registers
+ */
+#define SB_MST_PRI0 PPE_REG_ADDR(0x0300)
+#define SB_MST_PRI1 PPE_REG_ADDR(0x0301)
+
+/*
+ * EMA Registers
+ */
+#define EMA_CMDCFG PPE_REG_ADDR(0x0A00)
+#define EMA_DATACFG PPE_REG_ADDR(0x0A01)
+#define EMA_CMDCNT PPE_REG_ADDR(0x0A02)
+#define EMA_DATACNT PPE_REG_ADDR(0x0A03)
+#define EMA_ISR PPE_REG_ADDR(0x0A04)
+#define EMA_IER PPE_REG_ADDR(0x0A05)
+#define EMA_CFG PPE_REG_ADDR(0x0A06)
+#define EMA_SUBID PPE_REG_ADDR(0x0A07)
+
+#define EMA_ALIGNMENT 4
+
+/*
+ * DPlus Registers
+ */
+#define DM_RXDB PPE_REG_ADDR(0x0612)
+#define DM_RXCB PPE_REG_ADDR(0x0613)
+#define DM_RXCFG PPE_REG_ADDR(0x0614)
+#define DM_RXPGCNT PPE_REG_ADDR(0x0615)
+#define DM_RXPKTCNT PPE_REG_ADDR(0x0616)
+#define DS_RXDB PPE_REG_ADDR(0x0710)
+#define DS_RXCB PPE_REG_ADDR(0x0711)
+#define DS_RXCFG PPE_REG_ADDR(0x0712)
+#define DS_RXPGCNT PPE_REG_ADDR(0x0713)
+
+/*
+ * 3-Port Switch Registers (partial)
+ */
+#define IFX_SW (KSEG1 | 0x1E108000)
+#define SW_REG(off) ((volatile unsigned int*)(IFX_SW + (off)))
+#define SW_P2_CTL SW_REG(0x00C)
+
+
+/*
+ * Mailbox IGU1 Interrupt
+ */
+#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
+
+
+
+#endif // IFXMIPS_PTM_PPE_AR9_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_common.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_common.h
new file mode 100644
index 0000000000..63a5a3741a
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_common.h
@@ -0,0 +1,311 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_ppe_common.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (PPE register for all platform)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_PTM_PPE_COMMON_H
+#define IFXMIPS_PTM_PPE_COMMON_H
+
+
+
+#if defined(CONFIG_DANUBE)
+ #include "ifxmips_ptm_ppe_danube.h"
+#elif defined(CONFIG_AMAZON_SE)
+ #include "ifxmips_ptm_ppe_amazon_se.h"
+#elif defined(CONFIG_AR9)
+ #include "ifxmips_ptm_ppe_ar9.h"
+#elif defined(CONFIG_VR9)
+ #include "ifxmips_ptm_ppe_vr9.h"
+#else
+ #error Platform is not specified!
+#endif
+
+
+
+/*
+ * Code/Data Memory (CDM) Interface Configuration Register
+ */
+#define CDM_CFG PPE_REG_ADDR(0x0100)
+
+#define CDM_CFG_RAM1 GET_BITS(*CDM_CFG, 3, 2)
+#define CDM_CFG_RAM0 (*CDM_CFG & (1 << 1))
+
+#define CDM_CFG_RAM1_SET(value) SET_BITS(0, 3, 2, value)
+#define CDM_CFG_RAM0_SET(value) ((value) ? (1 << 1) : 0)
+
+/*
+ * QSB Internal Cell Delay Variation Register
+ */
+#define QSB_ICDV QSB_CONF_REG_ADDR(0x0007)
+
+#define QSB_ICDV_TAU GET_BITS(*QSB_ICDV, 5, 0)
+
+#define QSB_ICDV_TAU_SET(value) SET_BITS(0, 5, 0, value)
+
+/*
+ * QSB Scheduler Burst Limit Register
+ */
+#define QSB_SBL QSB_CONF_REG_ADDR(0x0009)
+
+#define QSB_SBL_SBL GET_BITS(*QSB_SBL, 3, 0)
+
+#define QSB_SBL_SBL_SET(value) SET_BITS(0, 3, 0, value)
+
+/*
+ * QSB Configuration Register
+ */
+#define QSB_CFG QSB_CONF_REG_ADDR(0x000A)
+
+#define QSB_CFG_TSTEPC GET_BITS(*QSB_CFG, 1, 0)
+
+#define QSB_CFG_TSTEPC_SET(value) SET_BITS(0, 1, 0, value)
+
+/*
+ * QSB RAM Transfer Table Register
+ */
+#define QSB_RTM QSB_CONF_REG_ADDR(0x000B)
+
+#define QSB_RTM_DM (*QSB_RTM)
+
+#define QSB_RTM_DM_SET(value) ((value) & 0xFFFFFFFF)
+
+/*
+ * QSB RAM Transfer Data Register
+ */
+#define QSB_RTD QSB_CONF_REG_ADDR(0x000C)
+
+#define QSB_RTD_TTV (*QSB_RTD)
+
+#define QSB_RTD_TTV_SET(value) ((value) & 0xFFFFFFFF)
+
+/*
+ * QSB RAM Access Register
+ */
+#define QSB_RAMAC QSB_CONF_REG_ADDR(0x000D)
+
+#define QSB_RAMAC_RW (*QSB_RAMAC & (1 << 31))
+#define QSB_RAMAC_TSEL GET_BITS(*QSB_RAMAC, 27, 24)
+#define QSB_RAMAC_LH (*QSB_RAMAC & (1 << 16))
+#define QSB_RAMAC_TESEL GET_BITS(*QSB_RAMAC, 9, 0)
+
+#define QSB_RAMAC_RW_SET(value) ((value) ? (1 << 31) : 0)
+#define QSB_RAMAC_TSEL_SET(value) SET_BITS(0, 27, 24, value)
+#define QSB_RAMAC_LH_SET(value) ((value) ? (1 << 16) : 0)
+#define QSB_RAMAC_TESEL_SET(value) SET_BITS(0, 9, 0, value)
+
+/*
+ * QSB Queue Scheduling and Shaping Definitions
+ */
+#define QSB_WFQ_NONUBR_MAX 0x3f00
+#define QSB_WFQ_UBR_BYPASS 0x3fff
+#define QSB_TP_TS_MAX 65472
+#define QSB_TAUS_MAX 64512
+#define QSB_GCR_MIN 18
+
+/*
+ * QSB Constant
+ */
+#define QSB_RAMAC_RW_READ 0
+#define QSB_RAMAC_RW_WRITE 1
+
+#define QSB_RAMAC_TSEL_QPT 0x01
+#define QSB_RAMAC_TSEL_SCT 0x02
+#define QSB_RAMAC_TSEL_SPT 0x03
+#define QSB_RAMAC_TSEL_VBR 0x08
+
+#define QSB_RAMAC_LH_LOW 0
+#define QSB_RAMAC_LH_HIGH 1
+
+#define QSB_QPT_SET_MASK 0x0
+#define QSB_QVPT_SET_MASK 0x0
+#define QSB_SET_SCT_MASK 0x0
+#define QSB_SET_SPT_MASK 0x0
+#define QSB_SET_SPT_SBVALID_MASK 0x7FFFFFFF
+
+#define QSB_SPT_SBV_VALID (1 << 31)
+#define QSB_SPT_PN_SET(value) (((value) & 0x01) ? (1 << 16) : 0)
+#define QSB_SPT_INTRATE_SET(value) SET_BITS(0, 13, 0, value)
+
+/*
+ * QSB Queue Parameter Table Entry and Queue VBR Parameter Table Entry
+ */
+#if defined(__BIG_ENDIAN)
+ union qsb_queue_parameter_table {
+ struct {
+ unsigned int res1 :1;
+ unsigned int vbr :1;
+ unsigned int wfqf :14;
+ unsigned int tp :16;
+ } bit;
+ u32 dword;
+ };
+
+ union qsb_queue_vbr_parameter_table {
+ struct {
+ unsigned int taus :16;
+ unsigned int ts :16;
+ } bit;
+ u32 dword;
+ };
+#else
+ union qsb_queue_parameter_table {
+ struct {
+ unsigned int tp :16;
+ unsigned int wfqf :14;
+ unsigned int vbr :1;
+ unsigned int res1 :1;
+ } bit;
+ u32 dword;
+ };
+
+ union qsb_queue_vbr_parameter_table {
+ struct {
+ unsigned int ts :16;
+ unsigned int taus :16;
+ } bit;
+ u32 dword;
+ };
+#endif // defined(__BIG_ENDIAN)
+
+/*
+ * Mailbox IGU0 Registers
+ */
+#define MBOX_IGU0_ISRS PPE_REG_ADDR(0x0200)
+#define MBOX_IGU0_ISRC PPE_REG_ADDR(0x0201)
+#define MBOX_IGU0_ISR PPE_REG_ADDR(0x0202)
+#define MBOX_IGU0_IER PPE_REG_ADDR(0x0203)
+
+#define MBOX_IGU0_ISRS_SET(n) (1 << (n))
+#define MBOX_IGU0_ISRC_CLEAR(n) (1 << (n))
+#define MBOX_IGU0_ISR_ISR(n) (*MBOX_IGU0_ISR & (1 << (n)))
+#define MBOX_IGU0_IER_EN(n) (*MBOX_IGU0_IER & (1 << (n)))
+#define MBOX_IGU0_IER_EN_SET(n) (1 << (n))
+
+/*
+ * Mailbox IGU1 Registers
+ */
+#define MBOX_IGU1_ISRS PPE_REG_ADDR(0x0204)
+#define MBOX_IGU1_ISRC PPE_REG_ADDR(0x0205)
+#define MBOX_IGU1_ISR PPE_REG_ADDR(0x0206)
+#define MBOX_IGU1_IER PPE_REG_ADDR(0x0207)
+
+#define MBOX_IGU1_ISRS_SET(n) (1 << (n))
+#define MBOX_IGU1_ISRC_CLEAR(n) (1 << (n))
+#define MBOX_IGU1_ISR_ISR(n) (*MBOX_IGU1_ISR & (1 << (n)))
+#define MBOX_IGU1_IER_EN(n) (*MBOX_IGU1_IER & (1 << (n)))
+#define MBOX_IGU1_IER_EN_SET(n) (1 << (n))
+
+/*
+ * Mailbox IGU3 Registers
+ */
+#define MBOX_IGU3_ISRS PPE_REG_ADDR(0x0214)
+#define MBOX_IGU3_ISRC PPE_REG_ADDR(0x0215)
+#define MBOX_IGU3_ISR PPE_REG_ADDR(0x0216)
+#define MBOX_IGU3_IER PPE_REG_ADDR(0x0217)
+
+#define MBOX_IGU3_ISRS_SET(n) (1 << (n))
+#define MBOX_IGU3_ISRC_CLEAR(n) (1 << (n))
+#define MBOX_IGU3_ISR_ISR(n) (*MBOX_IGU3_ISR & (1 << (n)))
+#define MBOX_IGU3_IER_EN(n) (*MBOX_IGU3_IER & (1 << (n)))
+#define MBOX_IGU3_IER_EN_SET(n) (1 << (n))
+
+/*
+ * RTHA/TTHA Registers
+ */
+#define RFBI_CFG PPE_REG_ADDR(0x0400)
+#define RBA_CFG0 PPE_REG_ADDR(0x0404)
+#define RBA_CFG1 PPE_REG_ADDR(0x0405)
+#define RCA_CFG0 PPE_REG_ADDR(0x0408)
+#define RCA_CFG1 PPE_REG_ADDR(0x0409)
+#define RDES_CFG0 PPE_REG_ADDR(0x040C)
+#define RDES_CFG1 PPE_REG_ADDR(0x040D)
+#define SFSM_STATE0 PPE_REG_ADDR(0x0410)
+#define SFSM_STATE1 PPE_REG_ADDR(0x0411)
+#define SFSM_DBA0 PPE_REG_ADDR(0x0412)
+#define SFSM_DBA1 PPE_REG_ADDR(0x0413)
+#define SFSM_CBA0 PPE_REG_ADDR(0x0414)
+#define SFSM_CBA1 PPE_REG_ADDR(0x0415)
+#define SFSM_CFG0 PPE_REG_ADDR(0x0416)
+#define SFSM_CFG1 PPE_REG_ADDR(0x0417)
+#define SFSM_PGCNT0 PPE_REG_ADDR(0x041C)
+#define SFSM_PGCNT1 PPE_REG_ADDR(0x041D)
+#define FFSM_DBA0 PPE_REG_ADDR(0x0508)
+#define FFSM_DBA1 PPE_REG_ADDR(0x0509)
+#define FFSM_CFG0 PPE_REG_ADDR(0x050A)
+#define FFSM_CFG1 PPE_REG_ADDR(0x050B)
+#define FFSM_IDLE_HEAD_BC0 PPE_REG_ADDR(0x050E)
+#define FFSM_IDLE_HEAD_BC1 PPE_REG_ADDR(0x050F)
+#define FFSM_PGCNT0 PPE_REG_ADDR(0x0514)
+#define FFSM_PGCNT1 PPE_REG_ADDR(0x0515)
+
+/*
+ * PPE TC Logic Registers (partial)
+ */
+#define DREG_A_VERSION PPE_REG_ADDR(0x0D00)
+#define DREG_A_CFG PPE_REG_ADDR(0x0D01)
+#define DREG_AT_CTRL PPE_REG_ADDR(0x0D02)
+#define DREG_AT_CB_CFG0 PPE_REG_ADDR(0x0D03)
+#define DREG_AT_CB_CFG1 PPE_REG_ADDR(0x0D04)
+#define DREG_AR_CTRL PPE_REG_ADDR(0x0D08)
+#define DREG_AR_CB_CFG0 PPE_REG_ADDR(0x0D09)
+#define DREG_AR_CB_CFG1 PPE_REG_ADDR(0x0D0A)
+#define DREG_A_UTPCFG PPE_REG_ADDR(0x0D0E)
+#define DREG_A_STATUS PPE_REG_ADDR(0x0D0F)
+#define DREG_AT_CFG0 PPE_REG_ADDR(0x0D20)
+#define DREG_AT_CFG1 PPE_REG_ADDR(0x0D21)
+#define DREG_AT_FB_SIZE0 PPE_REG_ADDR(0x0D22)
+#define DREG_AT_FB_SIZE1 PPE_REG_ADDR(0x0D23)
+#define DREG_AT_CELL0 PPE_REG_ADDR(0x0D24)
+#define DREG_AT_CELL1 PPE_REG_ADDR(0x0D25)
+#define DREG_AT_IDLE_CNT0 PPE_REG_ADDR(0x0D26)
+#define DREG_AT_IDLE_CNT1 PPE_REG_ADDR(0x0D27)
+#define DREG_AT_IDLE0 PPE_REG_ADDR(0x0D28)
+#define DREG_AT_IDLE1 PPE_REG_ADDR(0x0D29)
+#define DREG_AR_CFG0 PPE_REG_ADDR(0x0D60)
+#define DREG_AR_CFG1 PPE_REG_ADDR(0x0D61)
+#define DREG_AR_CELL0 PPE_REG_ADDR(0x0D68)
+#define DREG_AR_CELL1 PPE_REG_ADDR(0x0D69)
+#define DREG_AR_IDLE_CNT0 PPE_REG_ADDR(0x0D6A)
+#define DREG_AR_IDLE_CNT1 PPE_REG_ADDR(0x0D6B)
+#define DREG_AR_AIIDLE_CNT0 PPE_REG_ADDR(0x0D6C)
+#define DREG_AR_AIIDLE_CNT1 PPE_REG_ADDR(0x0D6D)
+#define DREG_AR_BE_CNT0 PPE_REG_ADDR(0x0D6E)
+#define DREG_AR_BE_CNT1 PPE_REG_ADDR(0x0D6F)
+#define DREG_AR_HEC_CNT0 PPE_REG_ADDR(0x0D70)
+#define DREG_AR_HEC_CNT1 PPE_REG_ADDR(0x0D71)
+#define DREG_AR_IDLE0 PPE_REG_ADDR(0x0D74)
+#define DREG_AR_IDLE1 PPE_REG_ADDR(0x0D75)
+#define DREG_AR_CERRN_CNT0 PPE_REG_ADDR(0x0DA0)
+#define DREG_AR_CERRN_CNT1 PPE_REG_ADDR(0x0DA1)
+#define DREG_AR_CERRNP_CNT0 PPE_REG_ADDR(0x0DA2)
+#define DREG_AR_CERRNP_CNT1 PPE_REG_ADDR(0x0DA3)
+#define DREG_AR_CVN_CNT0 PPE_REG_ADDR(0x0DA4)
+#define DREG_AR_CVN_CNT1 PPE_REG_ADDR(0x0DA5)
+#define DREG_AR_CVNP_CNT0 PPE_REG_ADDR(0x0DA6)
+#define DREG_AR_CVNP_CNT1 PPE_REG_ADDR(0x0DA7)
+#define DREG_B0_LADR PPE_REG_ADDR(0x0DA8)
+#define DREG_B1_LADR PPE_REG_ADDR(0x0DA9)
+
+
+
+#endif // IFXMIPS_PTM_PPE_COMMON_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_danube.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_danube.h
new file mode 100644
index 0000000000..5f896e60c2
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_danube.h
@@ -0,0 +1,135 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_ppe_danube.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (PPE register for Danube)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_PTM_PPE_DANUBE_H
+#define IFXMIPS_PTM_PPE_DANUBE_H
+
+
+
+/*
+ * FPI Configuration Bus Register and Memory Address Mapping
+ */
+#define IFX_PPE (KSEG1 | 0x1E180000)
+#define PP32_DEBUG_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0000) << 2)))
+#define PPM_INT_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0030) << 2)))
+#define PP32_INTERNAL_RES_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x0040) << 2)))
+#define CDM_CODE_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x1000) << 2)))
+#define PPE_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x4000) << 2)))
+#define CDM_DATA_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x5000) << 2)))
+#define PPM_INT_UNIT_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6000) << 2)))
+#define PPM_TIMER0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6100) << 2)))
+#define PPM_TASK_IND_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6200) << 2)))
+#define PPS_BRK_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6300) << 2)))
+#define PPM_TIMER1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x6400) << 2)))
+#define SB_RAM0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8000) << 2)))
+#define SB_RAM1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8400) << 2)))
+#define SB_RAM2_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x8C00) << 2)))
+#define SB_RAM3_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x9600) << 2)))
+#define QSB_CONF_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0xC000) << 2)))
+
+/*
+ * DWORD-Length of Memory Blocks
+ */
+#define PP32_DEBUG_REG_DWLEN 0x0030
+#define PPM_INT_REG_DWLEN 0x0010
+#define PP32_INTERNAL_RES_DWLEN 0x00C0
+#define CDM_CODE_MEMORYn_DWLEN(n) ((n) == 0 ? 0x1000 : 0x0800)
+#define PPE_REG_DWLEN 0x1000
+#define CDM_DATA_MEMORY_DWLEN CDM_CODE_MEMORYn_DWLEN(1)
+#define PPM_INT_UNIT_DWLEN 0x0100
+#define PPM_TIMER0_DWLEN 0x0100
+#define PPM_TASK_IND_REG_DWLEN 0x0100
+#define PPS_BRK_DWLEN 0x0100
+#define PPM_TIMER1_DWLEN 0x0100
+#define SB_RAM0_DWLEN 0x0400
+#define SB_RAM1_DWLEN 0x0800
+#define SB_RAM2_DWLEN 0x0A00
+#define SB_RAM3_DWLEN 0x0400
+#define QSB_CONF_REG_DWLEN 0x0100
+
+/*
+ * PP32 to FPI Address Mapping
+ */
+#define SB_BUFFER(__sb_addr) ((volatile unsigned int *)((((__sb_addr) >= 0x2000) && ((__sb_addr) <= 0x23FF)) ? SB_RAM0_ADDR((__sb_addr) - 0x2000) : \
+ (((__sb_addr) >= 0x2400) && ((__sb_addr) <= 0x2BFF)) ? SB_RAM1_ADDR((__sb_addr) - 0x2400) : \
+ (((__sb_addr) >= 0x2C00) && ((__sb_addr) <= 0x35FF)) ? SB_RAM2_ADDR((__sb_addr) - 0x2C00) : \
+ (((__sb_addr) >= 0x3600) && ((__sb_addr) <= 0x39FF)) ? SB_RAM3_ADDR((__sb_addr) - 0x3600) : \
+ 0))
+
+/*
+ * PP32 Debug Control Register
+ */
+#define PP32_DBG_CTRL PP32_DEBUG_REG_ADDR(0, 0x0000)
+
+#define DBG_CTRL_START_SET(value) ((value) ? (1 << 0) : 0)
+#define DBG_CTRL_STOP_SET(value) ((value) ? (1 << 1) : 0)
+#define DBG_CTRL_STEP_SET(value) ((value) ? (1 << 2) : 0)
+
+#define PP32_HALT_STAT PP32_DEBUG_REG_ADDR(0, 0x0001)
+
+#define PP32_BRK_SRC PP32_DEBUG_REG_ADDR(0, 0x0002)
+ #define PP32_BRK_SRC_PC(i) (1 << (i))
+ #define PP32_BRK_SRC_DATA(i, cmd) ((cmd) << ((i) * 3 + 8))
+
+#define PP32_DBG_PC_MIN(i) PP32_DEBUG_REG_ADDR(0, 0x0010 + (i))
+#define PP32_DBG_PC_MAX(i) PP32_DEBUG_REG_ADDR(0, 0x0014 + (i))
+#define PP32_DBG_DATA_MIN(i) PP32_DEBUG_REG_ADDR(0, 0x0018 + (i))
+#define PP32_DBG_DATA_MAX(i) PP32_DEBUG_REG_ADDR(0, 0x001A + (i))
+#define PP32_DBG_DATA_VAL(i) PP32_DEBUG_REG_ADDR(0, 0x001C + (i))
+
+#define PP32_DBG_TASK_GPR(task, i) PP32_DEBUG_REG_ADDR(0, 0x0040 + (task) * 0x0010 + (i))
+
+#define PP32_DBG_CUR_PC PP32_DEBUG_REG_ADDR(0, 0x0080)
+#define PP32_DBG_TASK_NO PP32_DEBUG_REG_ADDR(0, 0x0081)
+#define PP32_DBG_TASK_PRIO PP32_DEBUG_REG_ADDR(0, 0x0086)
+#define PP32_DBG_PC_OF_TASK(i) PP32_DEBUG_REG_ADDR(0, 0x0087 + (i))
+
+/*
+ * Share Buffer Registers
+ */
+#define SB_MST_SEL PPE_REG_ADDR(0x0304)
+
+/*
+ * EMA Registers
+ */
+#define EMA_CMDCFG PPE_REG_ADDR(0x0A00)
+#define EMA_DATACFG PPE_REG_ADDR(0x0A01)
+#define EMA_CMDCNT PPE_REG_ADDR(0x0A02)
+#define EMA_DATACNT PPE_REG_ADDR(0x0A03)
+#define EMA_ISR PPE_REG_ADDR(0x0A04)
+#define EMA_IER PPE_REG_ADDR(0x0A05)
+#define EMA_CFG PPE_REG_ADDR(0x0A06)
+#define EMA_SUBID PPE_REG_ADDR(0x0A07)
+
+#define EMA_ALIGNMENT 4
+
+/*
+ * Mailbox IGU1 Interrupt
+ */
+#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
+
+
+
+#endif // IFXMIPS_PTM_PPE_DANUBE_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_vr9.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_vr9.h
new file mode 100644
index 0000000000..4a8c2f7bc9
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_ppe_vr9.h
@@ -0,0 +1,205 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_ppe_vr9.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (PPE register for VR9)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifndef IFXMIPS_PTM_PPE_VR9_H
+#define IFXMIPS_PTM_PPE_VR9_H
+
+
+
+/*
+ * FPI Configuration Bus Register and Memory Address Mapping
+ */
+#define IFX_PPE (KSEG1 | 0x1E200000)
+#define PP32_DEBUG_REG_ADDR(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x000000 + (i) * 0x00010000) << 2)))
+#define CDM_CODE_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x001000 + (i) * 0x00010000) << 2)))
+#define CDM_DATA_MEMORY(i, x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x004000 + (i) * 0x00010000) << 2)))
+#define SB_RAM0_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x008000) << 2)))
+#define SB_RAM1_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x009000) << 2)))
+#define SB_RAM2_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x00A000) << 2)))
+#define SB_RAM3_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x00B000) << 2)))
+#define PPE_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x00D000) << 2)))
+#define QSB_CONF_REG_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x00E000) << 2)))
+#define SB_RAM6_ADDR(x) ((volatile unsigned int*)(IFX_PPE + (((x) + 0x018000) << 2)))
+
+/*
+ * DWORD-Length of Memory Blocks
+ */
+#define PP32_DEBUG_REG_DWLEN 0x0030
+#define CDM_CODE_MEMORYn_DWLEN(n) ((n) == 0 ? 0x1000 : 0x0800)
+#define CDM_DATA_MEMORY_DWLEN CDM_CODE_MEMORYn_DWLEN(1)
+#define SB_RAM0_DWLEN 0x1000
+#define SB_RAM1_DWLEN 0x1000
+#define SB_RAM2_DWLEN 0x1000
+#define SB_RAM3_DWLEN 0x1000
+#define SB_RAM6_DWLEN 0x8000
+#define QSB_CONF_REG_DWLEN 0x0100
+
+/*
+ * PP32 to FPI Address Mapping
+ */
+#define SB_BUFFER(__sb_addr) ((volatile unsigned int *)((((__sb_addr) >= 0x0000) && ((__sb_addr) <= 0x1FFF)) ? PPE_REG_ADDR((__sb_addr)) : \
+ (((__sb_addr) >= 0x2000) && ((__sb_addr) <= 0x2FFF)) ? SB_RAM0_ADDR((__sb_addr) - 0x2000) : \
+ (((__sb_addr) >= 0x3000) && ((__sb_addr) <= 0x3FFF)) ? SB_RAM1_ADDR((__sb_addr) - 0x3000) : \
+ (((__sb_addr) >= 0x4000) && ((__sb_addr) <= 0x4FFF)) ? SB_RAM2_ADDR((__sb_addr) - 0x4000) : \
+ (((__sb_addr) >= 0x5000) && ((__sb_addr) <= 0x5FFF)) ? SB_RAM3_ADDR((__sb_addr) - 0x5000) : \
+ (((__sb_addr) >= 0x7000) && ((__sb_addr) <= 0x7FFF)) ? PPE_REG_ADDR((__sb_addr) - 0x7000) : \
+ (((__sb_addr) >= 0x8000) && ((__sb_addr) <= 0xFFFF)) ? SB_RAM6_ADDR((__sb_addr) - 0x8000) : \
+ 0))
+
+/*
+ * PP32 Debug Control Register
+ */
+#define NUM_OF_PP32 2
+
+#define PP32_FREEZE PPE_REG_ADDR(0x0000)
+#define PP32_SRST PPE_REG_ADDR(0x0020)
+
+#define PP32_DBG_CTRL(n) PP32_DEBUG_REG_ADDR(n, 0x0000)
+
+#define DBG_CTRL_RESTART 0
+#define DBG_CTRL_STOP 1
+
+#define PP32_CTRL_CMD(n) PP32_DEBUG_REG_ADDR(n, 0x0B00)
+ #define PP32_CTRL_CMD_RESTART (1 << 0)
+ #define PP32_CTRL_CMD_STOP (1 << 1)
+ #define PP32_CTRL_CMD_STEP (1 << 2)
+ #define PP32_CTRL_CMD_BREAKOUT (1 << 3)
+
+#define PP32_CTRL_OPT(n) PP32_DEBUG_REG_ADDR(n, 0x0C00)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP_ON (3 << 0)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP_OFF (2 << 0)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN_ON (3 << 2)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN_OFF (2 << 2)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN_ON (3 << 4)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN_OFF (2 << 4)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT_ON (3 << 6)
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT_OFF (2 << 6)
+ #define PP32_CTRL_OPT_BREAKOUT_ON_STOP(n) (*PP32_CTRL_OPT(n) & (1 << 0))
+ #define PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN(n) (*PP32_CTRL_OPT(n) & (1 << 2))
+ #define PP32_CTRL_OPT_STOP_ON_BREAKIN(n) (*PP32_CTRL_OPT(n) & (1 << 4))
+ #define PP32_CTRL_OPT_STOP_ON_BREAKPOINT(n) (*PP32_CTRL_OPT(n) & (1 << 6))
+
+#define PP32_BRK_PC(n, i) PP32_DEBUG_REG_ADDR(n, 0x0900 + (i) * 2)
+#define PP32_BRK_PC_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0901 + (i) * 2)
+#define PP32_BRK_DATA_ADDR(n, i) PP32_DEBUG_REG_ADDR(n, 0x0904 + (i) * 2)
+#define PP32_BRK_DATA_ADDR_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0905 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_RD(n, i) PP32_DEBUG_REG_ADDR(n, 0x0908 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_RD_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x0909 + (i) * 2)
+#define PP32_BRK_DATA_VALUE_WR(n, i) PP32_DEBUG_REG_ADDR(n, 0x090C + (i) * 2)
+#define PP32_BRK_DATA_VALUE_WR_MASK(n, i) PP32_DEBUG_REG_ADDR(n, 0x090D + (i) * 2)
+ #define PP32_BRK_CONTEXT_MASK(i) (1 << (i))
+ #define PP32_BRK_CONTEXT_MASK_EN (1 << 4)
+ #define PP32_BRK_COMPARE_GREATER_EQUAL (1 << 5) // valid for break data value rd/wr only
+ #define PP32_BRK_COMPARE_LOWER_EQUAL (1 << 6)
+ #define PP32_BRK_COMPARE_EN (1 << 7)
+
+#define PP32_BRK_TRIG(n) PP32_DEBUG_REG_ADDR(n, 0x0F00)
+ #define PP32_BRK_GRPi_PCn_ON(i, n) ((3 << ((n) * 2)) << ((i) * 16))
+ #define PP32_BRK_GRPi_PCn_OFF(i, n) ((2 << ((n) * 2)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_ADDRn_ON(i, n) ((3 << ((n) * 2 + 4)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_ADDRn_OFF(i, n) ((2 << ((n) * 2 + 4)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn_ON(i, n) ((3 << ((n) * 2 + 8)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn_OFF(i, n)((2 << ((n) * 2 + 8)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn_ON(i, n) ((3 << ((n) * 2 + 12)) << ((i) * 16))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn_OFF(i, n)((2 << ((n) * 2 + 12)) << ((i) * 16))
+ #define PP32_BRK_GRPi_PCn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n))) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_ADDRn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 2)) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_VALUE_RDn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 4)) << ((i) * 8)))
+ #define PP32_BRK_GRPi_DATA_VALUE_WRn(k, i, n) (*PP32_BRK_TRIG(k) & ((1 << ((n) + 6)) << ((i) * 8)))
+
+#define PP32_CPU_STATUS(n) PP32_DEBUG_REG_ADDR(n, 0x0D00)
+#define PP32_HALT_STAT(n) PP32_CPU_STATUS(n)
+#define PP32_DBG_CUR_PC(n) PP32_CPU_STATUS(n)
+ #define PP32_CPU_USER_STOPPED(n) (*PP32_CPU_STATUS(n) & (1 << 0))
+ #define PP32_CPU_USER_BREAKIN_RCV(n) (*PP32_CPU_STATUS(n) & (1 << 1))
+ #define PP32_CPU_USER_BREAKPOINT_MET(n) (*PP32_CPU_STATUS(n) & (1 << 2))
+ #define PP32_CPU_CUR_PC(n) (*PP32_CPU_STATUS(n) >> 16)
+
+#define PP32_BREAKPOINT_REASONS(n) PP32_DEBUG_REG_ADDR(n, 0x0A00)
+ #define PP32_BRK_PC_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << (i)))
+ #define PP32_BRK_DATA_ADDR_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 2)))
+ #define PP32_BRK_DATA_VALUE_RD_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 4)))
+ #define PP32_BRK_DATA_VALUE_WR_MET(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) + 6)))
+ #define PP32_BRK_DATA_VALUE_RD_LO_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 8)))
+ #define PP32_BRK_DATA_VALUE_RD_GT_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 9)))
+ #define PP32_BRK_DATA_VALUE_WR_LO_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 12)))
+ #define PP32_BRK_DATA_VALUE_WR_GT_EQ(n, i) (*PP32_BREAKPOINT_REASONS(n) & (1 << ((i) * 2 + 13)))
+ #define PP32_BRK_CUR_CONTEXT(n) ((*PP32_BREAKPOINT_REASONS(n) >> 16) & 0x03)
+
+#define PP32_GP_REG_BASE(n) PP32_DEBUG_REG_ADDR(n, 0x0E00)
+#define PP32_GP_CONTEXTi_REGn(n, i, j) PP32_DEBUG_REG_ADDR(n, 0x0E00 + (i) * 16 + (j))
+
+/*
+ * SAR Registers
+ */
+#define SAR_MODE_CFG PPE_REG_ADDR(0x080A)
+#define SAR_RX_CMD_CNT PPE_REG_ADDR(0x080B)
+#define SAR_TX_CMD_CNT PPE_REG_ADDR(0x080C)
+#define SAR_RX_CTX_CFG PPE_REG_ADDR(0x080D)
+#define SAR_TX_CTX_CFG PPE_REG_ADDR(0x080E)
+#define SAR_TX_CMD_DONE_CNT PPE_REG_ADDR(0x080F)
+#define SAR_POLY_CFG_SET0 PPE_REG_ADDR(0x0812)
+#define SAR_POLY_CFG_SET1 PPE_REG_ADDR(0x0813)
+#define SAR_POLY_CFG_SET2 PPE_REG_ADDR(0x0814)
+#define SAR_POLY_CFG_SET3 PPE_REG_ADDR(0x0815)
+#define SAR_CRC_SIZE_CFG PPE_REG_ADDR(0x0816)
+
+/*
+ * PDMA/EMA Registers
+ */
+#define PDMA_CFG PPE_REG_ADDR(0x0A00)
+#define PDMA_RX_CMDCNT PPE_REG_ADDR(0x0A01)
+#define PDMA_TX_CMDCNT PPE_REG_ADDR(0x0A02)
+#define PDMA_RX_FWDATACNT PPE_REG_ADDR(0x0A03)
+#define PDMA_TX_FWDATACNT PPE_REG_ADDR(0x0A04)
+#define PDMA_RX_CTX_CFG PPE_REG_ADDR(0x0A05)
+#define PDMA_TX_CTX_CFG PPE_REG_ADDR(0x0A06)
+#define PDMA_RX_MAX_LEN_REG PPE_REG_ADDR(0x0A07)
+#define PDMA_RX_DELAY_CFG PPE_REG_ADDR(0x0A08)
+#define PDMA_INT_FIFO_RD PPE_REG_ADDR(0x0A09)
+#define PDMA_ISR PPE_REG_ADDR(0x0A0A)
+#define PDMA_IER PPE_REG_ADDR(0x0A0B)
+#define PDMA_SUBID PPE_REG_ADDR(0x0A0C)
+#define PDMA_BAR0 PPE_REG_ADDR(0x0A0D)
+#define PDMA_BAR1 PPE_REG_ADDR(0x0A0E)
+
+#define SAR_PDMA_RX_CMDBUF_CFG PPE_REG_ADDR(0x0F00)
+#define SAR_PDMA_TX_CMDBUF_CFG PPE_REG_ADDR(0x0F01)
+#define SAR_PDMA_RX_FW_CMDBUF_CFG PPE_REG_ADDR(0x0F02)
+#define SAR_PDMA_TX_FW_CMDBUF_CFG PPE_REG_ADDR(0x0F03)
+#define SAR_PDMA_RX_CMDBUF_STATUS PPE_REG_ADDR(0x0F04)
+#define SAR_PDMA_TX_CMDBUF_STATUS PPE_REG_ADDR(0x0F05)
+
+#define PDMA_ALIGNMENT 32 // same as Central DMA because of descriptor swap
+#define EMA_ALIGNMENT PDMA_ALIGNMENT
+
+/*
+ * Mailbox IGU1 Interrupt
+ */
+#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
+
+
+
+#endif // IFXMIPS_PTM_PPE_VR9_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_test.c b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_test.c
new file mode 100644
index 0000000000..15d8352707
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_test.c
@@ -0,0 +1,943 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_vdsl.c
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver common source file (core functions for VR9)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+#ifdef CONFIG_IFX_PTM_TEST_PROC
+
+/*
+ * ####################################
+ * Head File
+ * ####################################
+ */
+
+/*
+ * Common Head File
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/etherdevice.h>
+
+/*
+ * Chip Specific Head File
+ */
+#include <asm/ifx/ifx_types.h>
+#include <asm/ifx/ifx_regs.h>
+#include <asm/ifx/common_routines.h>
+#include "ifxmips_ptm_common.h"
+#include "ifxmips_ptm_ppe_common.h"
+
+
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+
+
+/*
+ * ####################################
+ * Declaration
+ * ####################################
+ */
+
+/*
+ * Proc File Functions
+ */
+static inline void proc_file_create(void);
+static inline void proc_file_delete(void);
+
+/*
+ * Proc Help Functions
+ */
+static int proc_write_mem(struct file *, const char *, unsigned long, void *);
+static int proc_read_pp32(char *, char **, off_t, int, int *, void *);
+static int proc_write_pp32(struct file *, const char *, unsigned long, void *);
+static int stricmp(const char *, const char *);
+static int strincmp(const char *, const char *, int);
+static int get_token(char **, char **, int *, int *);
+static int get_number(char **, int *, int);
+static inline void ignore_space(char **, int *);
+
+
+
+/*
+ * ####################################
+ * Local Variable
+ * ####################################
+ */
+
+
+
+/*
+ * ####################################
+ * Local Function
+ * ####################################
+ */
+
+static inline void proc_file_create(void)
+{
+ struct proc_dir_entry *res;
+
+ res = create_proc_entry("driver/ifx_ptm/mem",
+ 0,
+ NULL);
+ if ( res != NULL )
+ res->write_proc = proc_write_mem;
+ else
+ printk("%s:%s:%d: failed to create proc mem!", __FILE__, __func__, __LINE__);
+
+ res = create_proc_entry("driver/ifx_ptm/pp32",
+ 0,
+ NULL);
+ if ( res != NULL ) {
+ res->read_proc = proc_read_pp32;
+ res->write_proc = proc_write_pp32;
+ }
+ else
+ printk("%s:%s:%d: failed to create proc pp32!", __FILE__, __func__, __LINE__);
+}
+
+static inline void proc_file_delete(void)
+{
+ remove_proc_entry("driver/ifx_ptm/pp32", NULL);
+
+ remove_proc_entry("driver/ifx_ptm/mem", NULL);
+}
+
+static inline unsigned long sb_addr_to_fpi_addr_convert(unsigned long sb_addr)
+{
+#define PP32_SB_ADDR_END 0xFFFF
+
+ if ( sb_addr < PP32_SB_ADDR_END) {
+ return (unsigned long ) SB_BUFFER(sb_addr);
+ }
+ else {
+ return sb_addr;
+ }
+}
+
+static int proc_write_mem(struct file *file, const char *buf, unsigned long count, void *data)
+{
+ char *p1, *p2;
+ int len;
+ int colon;
+ unsigned long *p;
+ char local_buf[1024];
+ int i, n, l;
+
+ len = sizeof(local_buf) < count ? sizeof(local_buf) - 1 : count;
+ len = len - copy_from_user(local_buf, buf, len);
+ local_buf[len] = 0;
+
+ p1 = local_buf;
+ colon = 1;
+ while ( get_token(&p1, &p2, &len, &colon) )
+ {
+ if ( stricmp(p1, "w") == 0 || stricmp(p1, "write") == 0 || stricmp(p1, "r") == 0 || stricmp(p1, "read") == 0 )
+ break;
+
+ p1 = p2;
+ colon = 1;
+ }
+
+ if ( *p1 == 'w' )
+ {
+ ignore_space(&p2, &len);
+ p = (unsigned long *)get_number(&p2, &len, 1);
+ p = (unsigned long *)sb_addr_to_fpi_addr_convert( (unsigned long) p);
+
+ if ( (u32)p >= KSEG0 )
+ while ( 1 )
+ {
+ ignore_space(&p2, &len);
+ if ( !len || !((*p2 >= '0' && *p2 <= '9') || (*p2 >= 'a' && *p2 <= 'f') || (*p2 >= 'A' && *p2 <= 'F')) )
+ break;
+
+ *p++ = (u32)get_number(&p2, &len, 1);
+ }
+ }
+ else if ( *p1 == 'r' )
+ {
+ ignore_space(&p2, &len);
+ p = (unsigned long *)get_number(&p2, &len, 1);
+ p = (unsigned long *)sb_addr_to_fpi_addr_convert( (unsigned long) p);
+
+ if ( (u32)p >= KSEG0 )
+ {
+ ignore_space(&p2, &len);
+ n = (int)get_number(&p2, &len, 0);
+ if ( n )
+ {
+ char str[32] = {0};
+ char *pch = str;
+ int k;
+ u32 data;
+ char c;
+
+ n += (l = ((int)p >> 2) & 0x03);
+ p = (unsigned long *)((u32)p & ~0x0F);
+ for ( i = 0; i < n; i++ )
+ {
+ if ( (i & 0x03) == 0 )
+ {
+ printk("%08X:", (u32)p);
+ pch = str;
+ }
+ if ( i < l )
+ {
+ printk(" ");
+ sprintf(pch, " ");
+ }
+ else
+ {
+ data = (u32)*p;
+ printk(" %08X", data);
+ for ( k = 0; k < 4; k++ )
+ {
+ c = ((char*)&data)[k];
+ pch[k] = c < ' ' ? '.' : c;
+ }
+ }
+ p++;
+ pch += 4;
+ if ( (i & 0x03) == 0x03 )
+ {
+ pch[0] = 0;
+ printk(" ; %s\n", str);
+ }
+ }
+ if ( (n & 0x03) != 0x00 )
+ {
+ for ( k = 4 - (n & 0x03); k > 0; k-- )
+ printk(" ");
+ pch[0] = 0;
+ printk(" ; %s\n", str);
+ }
+ }
+ }
+ }
+
+ return count;
+}
+
+#ifdef CONFIG_DANUBE
+
+static int proc_read_pp32(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ static const char *halt_stat[] = {
+ "reset",
+ "break in line",
+ "stop",
+ "step",
+ "code",
+ "data0",
+ "data1"
+ };
+ static const char *brk_src_data[] = {
+ "off",
+ "read",
+ "write",
+ "read/write",
+ "write_equal",
+ "N/A",
+ "N/A",
+ "N/A"
+ };
+ static const char *brk_src_code[] = {
+ "off",
+ "on"
+ };
+
+ int len = 0;
+ int cur_task;
+ int i, j;
+ int k;
+ unsigned long bit;
+
+ len += sprintf(page + off + len, "Task No %d, PC %04x\n", *PP32_DBG_TASK_NO & 0x03, *PP32_DBG_CUR_PC & 0xFFFF);
+
+ if ( !(*PP32_HALT_STAT & 0x01) )
+ len += sprintf(page + off + len, " Halt State: Running\n");
+ else
+ {
+ len += sprintf(page + off + len, " Halt State: Stopped");
+ k = 0;
+ for ( bit = 2, i = 0; bit <= (1 << 7); bit <<= 1, i++ )
+ if ( (*PP32_HALT_STAT & bit) )
+ {
+ if ( !k )
+ {
+ len += sprintf(page + off + len, ", ");
+ k++;
+ }
+ else
+ len += sprintf(page + off + len, " | ");
+ len += sprintf(page + off + len, halt_stat[i]);
+ }
+
+ len += sprintf(page + off + len, "\n");
+
+ cur_task = *PP32_DBG_TASK_NO & 0x03;
+ len += sprintf(page + off + len, "General Purpose Register (Task %d):\n", cur_task);
+ for ( i = 0; i < 4; i++ )
+ {
+ for ( j = 0; j < 4; j++ )
+ len += sprintf(page + off + len, " %2d: %08x", i + j * 4, *PP32_DBG_TASK_GPR(cur_task, i + j * 4));
+ len += sprintf(page + off + len, "\n");
+ }
+ }
+
+ len += sprintf(page + off + len, " Break Src: data1 - %s, data0 - %s, pc3 - %s, pc2 - %s, pc1 - %s, pc0 - %s\n",
+ brk_src_data[(*PP32_BRK_SRC >> 11) & 0x07], brk_src_data[(*PP32_BRK_SRC >> 8) & 0x07], brk_src_code[(*PP32_BRK_SRC >> 3) & 0x01], brk_src_code[(*PP32_BRK_SRC >> 2) & 0x01], brk_src_code[(*PP32_BRK_SRC >> 1) & 0x01], brk_src_code[*PP32_BRK_SRC & 0x01]);
+
+ for ( i = 0; i < 4; i++ )
+ len += sprintf(page + off + len, " pc%d: %04x - %04x\n", i, *PP32_DBG_PC_MIN(i), *PP32_DBG_PC_MAX(i));
+
+ for ( i = 0; i < 2; i++ )
+ len += sprintf(page + off + len, " data%d: %04x - %04x (%08x)\n", i, *PP32_DBG_DATA_MIN(i), *PP32_DBG_DATA_MAX(i), *PP32_DBG_DATA_VAL(i));
+
+ *eof = 1;
+
+ return len;
+}
+
+static int proc_write_pp32(struct file *file, const char *buf, unsigned long count, void *data)
+{
+ char str[2048];
+ char *p;
+ int len, rlen;
+
+ int id;
+ u32 addr;
+ u32 cmd;
+
+ len = count < sizeof(str) ? count : sizeof(str) - 1;
+ rlen = len - copy_from_user(str, buf, len);
+ while ( rlen && str[rlen - 1] <= ' ' )
+ rlen--;
+ str[rlen] = 0;
+ for ( p = str; *p && *p <= ' '; p++, rlen-- );
+ if ( !*p )
+ {
+ return 0;
+ }
+
+ if ( stricmp(str, "start") == 0 )
+ *PP32_DBG_CTRL = DBG_CTRL_START_SET(1);
+ else if ( stricmp(str, "stop") == 0 )
+ *PP32_DBG_CTRL = DBG_CTRL_STOP_SET(1);
+ else if ( stricmp(str, "step") == 0 )
+ *PP32_DBG_CTRL = DBG_CTRL_STEP_SET(1);
+ else if ( strincmp(p, "pc", 2) == 0 && p[2] >= '0' && p[2] <= '3' && p[3] == ' ' )
+ {
+ id = (int)(p[2] - '0');
+ p += 4;
+ rlen -= 4;
+ *PP32_BRK_SRC &= ~PP32_BRK_SRC_PC(id);
+ if ( stricmp(p, "off") != 0 )
+ {
+ ignore_space(&p, &rlen);
+ *PP32_DBG_PC_MIN(id) = *PP32_DBG_PC_MAX(id) = get_number(&p, &rlen, 1);
+ ignore_space(&p, &rlen);
+ if ( rlen > 0 )
+ {
+ addr = get_number(&p, &rlen, 1);
+ if ( addr >= *PP32_DBG_PC_MIN(id) )
+ *PP32_DBG_PC_MAX(id) = addr;
+ else
+ *PP32_DBG_PC_MIN(id) = addr;
+ }
+ *PP32_BRK_SRC |= PP32_BRK_SRC_PC(id);
+ }
+ }
+ else if ( strincmp(p, "daddr", 5) == 0 && p[5] >= '0' && p[5] <= '1' && p[6] == ' ' )
+ {
+ id = (int)(p[5] - '0');
+ p += 7;
+ rlen -= 7;
+ *PP32_BRK_SRC &= ~PP32_BRK_SRC_DATA(id, 7);
+ if ( stricmp(p, "off") != 0 )
+ {
+ ignore_space(&p, &rlen);
+ *PP32_DBG_DATA_MIN(id) = *PP32_DBG_DATA_MAX(id) = get_number(&p, &rlen, 1);
+ cmd = 1;
+ ignore_space(&p, &rlen);
+ if ( rlen > 0 && ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F')) )
+ {
+ addr = get_number(&p, &rlen, 1);
+ if ( addr >= *PP32_DBG_PC_MIN(id) )
+ *PP32_DBG_DATA_MAX(id) = addr;
+ else
+ *PP32_DBG_DATA_MIN(id) = addr;
+ ignore_space(&p, &rlen);
+ }
+ if ( *p == 'w' )
+ cmd = 2;
+ else if ( *p == 'r' && p[1] == 'w' )
+ {
+ cmd = 3;
+ p++;
+ rlen--;
+ }
+ p++;
+ rlen--;
+ if ( rlen > 0 )
+ {
+ ignore_space(&p, &rlen);
+ if ( (*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F'))
+ {
+ *PP32_DBG_DATA_VAL(id) = get_number(&p, &rlen, 1);
+ cmd = 4;
+ }
+ }
+ *PP32_BRK_SRC |= PP32_BRK_SRC_DATA(id, cmd);
+ }
+ }
+ else
+ {
+ printk("echo \"<command>\" > /proc/driver/ifx_ptm/pp32\n");
+ printk(" command:\n");
+ printk(" start - run pp32\n");
+ printk(" stop - stop pp32\n");
+ printk(" step - run pp32 with one step only\n");
+ printk(" pc0 - pc0 <addr_min [addr_max]>/off, set break point PC0\n");
+ printk(" pc1 - pc1 <addr_min [addr_max]>/off, set break point PC1\n");
+ printk(" pc2 - pc2 <addr_min [addr_max]>/off, set break point PC2\n");
+ printk(" pc3 - pc3 <addr_min [addr_max]>/off, set break point PC3\n");
+ printk(" daddr0 - daddr0 <addr_min [addr_max] r/w/rw [value]>/off, set break point data address 0\n");
+ printk(" daddr1 - daddr1 <addr_min [addr_max] r/w/rw [value]>/off, set break point data address 1\n");
+ printk(" help - print this screen\n");
+ }
+
+ return count;
+}
+
+#else
+
+static int proc_read_pp32(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ static const char *stron = " on";
+ static const char *stroff = "off";
+
+ int len = 0;
+ int cur_context;
+ int f_stopped;
+ char str[256];
+ char strlength;
+ int i, j;
+
+ int pp32;
+
+ for ( pp32 = 0; pp32 < NUM_OF_PP32; pp32++ )
+ {
+ f_stopped = 0;
+
+ len += sprintf(page + off + len, "===== pp32 core %d =====\n", pp32);
+
+ #ifdef CONFIG_VR9
+ if ( (*PP32_FREEZE & (1 << (pp32 << 4))) != 0 )
+ {
+ sprintf(str, "freezed");
+ f_stopped = 1;
+ }
+ #else
+ if ( 0 )
+ {
+ }
+ #endif
+ else if ( PP32_CPU_USER_STOPPED(pp32) || PP32_CPU_USER_BREAKIN_RCV(pp32) || PP32_CPU_USER_BREAKPOINT_MET(pp32) )
+ {
+ strlength = 0;
+ if ( PP32_CPU_USER_STOPPED(pp32) )
+ strlength += sprintf(str + strlength, "stopped");
+ if ( PP32_CPU_USER_BREAKPOINT_MET(pp32) )
+ strlength += sprintf(str + strlength, strlength ? " | breakpoint" : "breakpoint");
+ if ( PP32_CPU_USER_BREAKIN_RCV(pp32) )
+ strlength += sprintf(str + strlength, strlength ? " | breakin" : "breakin");
+ f_stopped = 1;
+ }
+ else if ( PP32_CPU_CUR_PC(pp32) == PP32_CPU_CUR_PC(pp32) )
+ {
+ unsigned int pc_value[64] = {0};
+
+ f_stopped = 1;
+ for ( i = 0; f_stopped && i < NUM_ENTITY(pc_value); i++ )
+ {
+ pc_value[i] = PP32_CPU_CUR_PC(pp32);
+ for ( j = 0; j < i; j++ )
+ if ( pc_value[j] != pc_value[i] )
+ {
+ f_stopped = 0;
+ break;
+ }
+ }
+ if ( f_stopped )
+ sprintf(str, "hang");
+ }
+ if ( !f_stopped )
+ sprintf(str, "running");
+ cur_context = PP32_BRK_CUR_CONTEXT(pp32);
+ len += sprintf(page + off + len, "Context: %d, PC: 0x%04x, %s\n", cur_context, PP32_CPU_CUR_PC(pp32), str);
+
+ if ( PP32_CPU_USER_BREAKPOINT_MET(pp32) )
+ {
+ strlength = 0;
+ if ( PP32_BRK_PC_MET(pp32, 0) )
+ strlength += sprintf(str + strlength, "pc0");
+ if ( PP32_BRK_PC_MET(pp32, 1) )
+ strlength += sprintf(str + strlength, strlength ? " | pc1" : "pc1");
+ if ( PP32_BRK_DATA_ADDR_MET(pp32, 0) )
+ strlength += sprintf(str + strlength, strlength ? " | daddr0" : "daddr0");
+ if ( PP32_BRK_DATA_ADDR_MET(pp32, 1) )
+ strlength += sprintf(str + strlength, strlength ? " | daddr1" : "daddr1");
+ if ( PP32_BRK_DATA_VALUE_RD_MET(pp32, 0) )
+ {
+ strlength += sprintf(str + strlength, strlength ? " | rdval0" : "rdval0");
+ if ( PP32_BRK_DATA_VALUE_RD_LO_EQ(pp32, 0) )
+ {
+ if ( PP32_BRK_DATA_VALUE_RD_GT_EQ(pp32, 0) )
+ strlength += sprintf(str + strlength, " ==");
+ else
+ strlength += sprintf(str + strlength, " <=");
+ }
+ else if ( PP32_BRK_DATA_VALUE_RD_GT_EQ(pp32, 0) )
+ strlength += sprintf(str + strlength, " >=");
+ }
+ if ( PP32_BRK_DATA_VALUE_RD_MET(pp32, 1) )
+ {
+ strlength += sprintf(str + strlength, strlength ? " | rdval1" : "rdval1");
+ if ( PP32_BRK_DATA_VALUE_RD_LO_EQ(pp32, 1) )
+ {
+ if ( PP32_BRK_DATA_VALUE_RD_GT_EQ(pp32, 1) )
+ strlength += sprintf(str + strlength, " ==");
+ else
+ strlength += sprintf(str + strlength, " <=");
+ }
+ else if ( PP32_BRK_DATA_VALUE_RD_GT_EQ(pp32, 1) )
+ strlength += sprintf(str + strlength, " >=");
+ }
+ if ( PP32_BRK_DATA_VALUE_WR_MET(pp32, 0) )
+ {
+ strlength += sprintf(str + strlength, strlength ? " | wtval0" : "wtval0");
+ if ( PP32_BRK_DATA_VALUE_WR_LO_EQ(pp32, 0) )
+ {
+ if ( PP32_BRK_DATA_VALUE_WR_GT_EQ(pp32, 0) )
+ strlength += sprintf(str + strlength, " ==");
+ else
+ strlength += sprintf(str + strlength, " <=");
+ }
+ else if ( PP32_BRK_DATA_VALUE_WR_GT_EQ(pp32, 0) )
+ strlength += sprintf(str + strlength, " >=");
+ }
+ if ( PP32_BRK_DATA_VALUE_WR_MET(pp32, 1) )
+ {
+ strlength += sprintf(str + strlength, strlength ? " | wtval1" : "wtval1");
+ if ( PP32_BRK_DATA_VALUE_WR_LO_EQ(pp32, 1) )
+ {
+ if ( PP32_BRK_DATA_VALUE_WR_GT_EQ(pp32, 1) )
+ strlength += sprintf(str + strlength, " ==");
+ else
+ strlength += sprintf(str + strlength, " <=");
+ }
+ else if ( PP32_BRK_DATA_VALUE_WR_GT_EQ(pp32, 1) )
+ strlength += sprintf(str + strlength, " >=");
+ }
+ len += sprintf(page + off + len, "break reason: %s\n", str);
+ }
+
+ if ( f_stopped )
+ {
+ len += sprintf(page + off + len, "General Purpose Register (Context %d):\n", cur_context);
+ for ( i = 0; i < 4; i++ )
+ {
+ for ( j = 0; j < 4; j++ )
+ len += sprintf(page + off + len, " %2d: %08x", i + j * 4, *PP32_GP_CONTEXTi_REGn(pp32, cur_context, i + j * 4));
+ len += sprintf(page + off + len, "\n");
+ }
+ }
+
+ len += sprintf(page + off + len, "break out on: break in - %s, stop - %s\n",
+ PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN(pp32) ? stron : stroff,
+ PP32_CTRL_OPT_BREAKOUT_ON_STOP(pp32) ? stron : stroff);
+ len += sprintf(page + off + len, " stop on: break in - %s, break point - %s\n",
+ PP32_CTRL_OPT_STOP_ON_BREAKIN(pp32) ? stron : stroff,
+ PP32_CTRL_OPT_STOP_ON_BREAKPOINT(pp32) ? stron : stroff);
+ len += sprintf(page + off + len, "breakpoint:\n");
+ len += sprintf(page + off + len, " pc0: 0x%08x, %s\n", *PP32_BRK_PC(pp32, 0), PP32_BRK_GRPi_PCn(pp32, 0, 0) ? "group 0" : "off");
+ len += sprintf(page + off + len, " pc1: 0x%08x, %s\n", *PP32_BRK_PC(pp32, 1), PP32_BRK_GRPi_PCn(pp32, 1, 1) ? "group 1" : "off");
+ len += sprintf(page + off + len, " daddr0: 0x%08x, %s\n", *PP32_BRK_DATA_ADDR(pp32, 0), PP32_BRK_GRPi_DATA_ADDRn(pp32, 0, 0) ? "group 0" : "off");
+ len += sprintf(page + off + len, " daddr1: 0x%08x, %s\n", *PP32_BRK_DATA_ADDR(pp32, 1), PP32_BRK_GRPi_DATA_ADDRn(pp32, 1, 1) ? "group 1" : "off");
+ len += sprintf(page + off + len, " rdval0: 0x%08x\n", *PP32_BRK_DATA_VALUE_RD(pp32, 0));
+ len += sprintf(page + off + len, " rdval1: 0x%08x\n", *PP32_BRK_DATA_VALUE_RD(pp32, 1));
+ len += sprintf(page + off + len, " wrval0: 0x%08x\n", *PP32_BRK_DATA_VALUE_WR(pp32, 0));
+ len += sprintf(page + off + len, " wrval1: 0x%08x\n", *PP32_BRK_DATA_VALUE_WR(pp32, 1));
+ }
+
+ *eof = 1;
+
+ return len;
+}
+
+static int proc_write_pp32(struct file *file, const char *buf, unsigned long count, void *data)
+{
+ char str[2048];
+ char *p;
+ int len, rlen;
+
+ int pp32 = 0;
+ u32 addr;
+
+ len = count < sizeof(str) ? count : sizeof(str) - 1;
+ rlen = len - copy_from_user(str, buf, len);
+ while ( rlen && str[rlen - 1] <= ' ' )
+ rlen--;
+ str[rlen] = 0;
+ for ( p = str; *p && *p <= ' '; p++, rlen-- );
+ if ( !*p )
+ return 0;
+
+ if ( strincmp(p, "pp32 ", 5) == 0 )
+ {
+ p += 5;
+ rlen -= 5;
+
+ while ( rlen > 0 && *p >= '0' && *p <= '9' )
+ {
+ pp32 += *p - '0';
+ p++;
+ rlen--;
+ }
+ while ( rlen > 0 && *p && *p <= ' ' )
+ {
+ p++;
+ rlen--;
+ }
+
+ if ( pp32 >= NUM_OF_PP32 )
+ {
+ printk(KERN_ERR __FILE__ ":%d:%s: incorrect pp32 index - %d\n", __LINE__, __FUNCTION__, pp32);
+ return count;
+ }
+ }
+
+ if ( stricmp(p, "start") == 0 )
+ {
+ #ifdef CONFIG_AMAZON_SE
+ *PP32_CTRL_CMD(pp32) = 0;
+ #endif
+ *PP32_CTRL_CMD(pp32) = PP32_CTRL_CMD_RESTART;
+ }
+ else if ( stricmp(p, "stop") == 0 )
+ {
+ #ifdef CONFIG_AMAZON_SE
+ *PP32_CTRL_CMD(pp32) = 0;
+ #endif
+ *PP32_CTRL_CMD(pp32) = PP32_CTRL_CMD_STOP;
+ }
+ else if ( stricmp(p, "step") == 0 )
+ {
+ #ifdef CONFIG_AMAZON_SE
+ *PP32_CTRL_CMD(pp32) = 0;
+ #endif
+ *PP32_CTRL_CMD(pp32) = PP32_CTRL_CMD_STEP;
+ }
+ #ifdef CONFIG_VR9
+ else if ( stricmp(p, "unfreeze") == 0 )
+ *PP32_FREEZE &= ~(1 << (pp32 << 4));
+ else if ( stricmp(p, "freeze") == 0 )
+ *PP32_FREEZE |= 1 << (pp32 << 4);
+ #else
+ else if ( stricmp(p, "unfreeze") == 0 )
+ *PP32_DBG_CTRL(pp32) = DBG_CTRL_RESTART;
+ else if ( stricmp(p, "freeze") == 0 )
+ *PP32_DBG_CTRL(pp32) = DBG_CTRL_STOP;
+ #endif
+ else if ( strincmp(p, "pc0 ", 4) == 0 )
+ {
+ p += 4;
+ rlen -= 4;
+ if ( stricmp(p, "off") == 0 )
+ {
+ *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_PCn_OFF(0, 0);
+ *PP32_BRK_PC_MASK(pp32, 0) = PP32_BRK_CONTEXT_MASK_EN;
+ *PP32_BRK_PC(pp32, 0) = 0;
+ }
+ else
+ {
+ addr = get_number(&p, &rlen, 1);
+ *PP32_BRK_PC(pp32, 0) = addr;
+ *PP32_BRK_PC_MASK(pp32, 0) = PP32_BRK_CONTEXT_MASK_EN | PP32_BRK_CONTEXT_MASK(0) | PP32_BRK_CONTEXT_MASK(1) | PP32_BRK_CONTEXT_MASK(2) | PP32_BRK_CONTEXT_MASK(3);
+ *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_PCn_ON(0, 0);
+ }
+ }
+ else if ( strincmp(p, "pc1 ", 4) == 0 )
+ {
+ p += 4;
+ rlen -= 4;
+ if ( stricmp(p, "off") == 0 )
+ {
+ *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_PCn_OFF(1, 1);
+ *PP32_BRK_PC_MASK(pp32, 1) = PP32_BRK_CONTEXT_MASK_EN;
+ *PP32_BRK_PC(pp32, 1) = 0;
+ }
+ else
+ {
+ addr = get_number(&p, &rlen, 1);
+ *PP32_BRK_PC(pp32, 1) = addr;
+ *PP32_BRK_PC_MASK(pp32, 1) = PP32_BRK_CONTEXT_MASK_EN | PP32_BRK_CONTEXT_MASK(0) | PP32_BRK_CONTEXT_MASK(1) | PP32_BRK_CONTEXT_MASK(2) | PP32_BRK_CONTEXT_MASK(3);
+ *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_PCn_ON(1, 1);
+ }
+ }
+ else if ( strincmp(p, "daddr0 ", 7) == 0 )
+ {
+ p += 7;
+ rlen -= 7;
+ if ( stricmp(p, "off") == 0 )
+ {
+ *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_DATA_ADDRn_OFF(0, 0);
+ *PP32_BRK_DATA_ADDR_MASK(pp32, 0) = PP32_BRK_CONTEXT_MASK_EN;
+ *PP32_BRK_DATA_ADDR(pp32, 0) = 0;
+ }
+ else
+ {
+ addr = get_number(&p, &rlen, 1);
+ *PP32_BRK_DATA_ADDR(pp32, 0) = addr;
+ *PP32_BRK_DATA_ADDR_MASK(pp32, 0) = PP32_BRK_CONTEXT_MASK_EN | PP32_BRK_CONTEXT_MASK(0) | PP32_BRK_CONTEXT_MASK(1) | PP32_BRK_CONTEXT_MASK(2) | PP32_BRK_CONTEXT_MASK(3);
+ *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_DATA_ADDRn_ON(0, 0);
+ }
+ }
+ else if ( strincmp(p, "daddr1 ", 7) == 0 )
+ {
+ p += 7;
+ rlen -= 7;
+ if ( stricmp(p, "off") == 0 )
+ {
+ *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_DATA_ADDRn_OFF(1, 1);
+ *PP32_BRK_DATA_ADDR_MASK(pp32, 1) = PP32_BRK_CONTEXT_MASK_EN;
+ *PP32_BRK_DATA_ADDR(pp32, 1) = 0;
+ }
+ else
+ {
+ addr = get_number(&p, &rlen, 1);
+ *PP32_BRK_DATA_ADDR(pp32, 1) = addr;
+ *PP32_BRK_DATA_ADDR_MASK(pp32, 1) = PP32_BRK_CONTEXT_MASK_EN | PP32_BRK_CONTEXT_MASK(0) | PP32_BRK_CONTEXT_MASK(1) | PP32_BRK_CONTEXT_MASK(2) | PP32_BRK_CONTEXT_MASK(3);
+ *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_DATA_ADDRn_ON(1, 1);
+ }
+ }
+ else
+ {
+
+ printk("echo \"<command>\" > /proc/driver/ifx_ptm/pp32\n");
+ printk(" command:\n");
+ printk(" unfreeze - unfreeze pp32\n");
+ printk(" freeze - freeze pp32\n");
+ printk(" start - run pp32\n");
+ printk(" stop - stop pp32\n");
+ printk(" step - run pp32 with one step only\n");
+ printk(" pc0 - pc0 <addr>/off, set break point PC0\n");
+ printk(" pc1 - pc1 <addr>/off, set break point PC1\n");
+ printk(" daddr0 - daddr0 <addr>/off, set break point data address 0\n");
+ printk(" daddr1 - daddr1 <addr>/off, set break point data address 1\n");
+ printk(" help - print this screen\n");
+ }
+
+ if ( *PP32_BRK_TRIG(pp32) )
+ *PP32_CTRL_OPT(pp32) = PP32_CTRL_OPT_STOP_ON_BREAKPOINT_ON;
+ else
+ *PP32_CTRL_OPT(pp32) = PP32_CTRL_OPT_STOP_ON_BREAKPOINT_OFF;
+
+ return count;
+}
+
+#endif
+
+static int stricmp(const char *p1, const char *p2)
+{
+ int c1, c2;
+
+ while ( *p1 && *p2 )
+ {
+ c1 = *p1 >= 'A' && *p1 <= 'Z' ? *p1 + 'a' - 'A' : *p1;
+ c2 = *p2 >= 'A' && *p2 <= 'Z' ? *p2 + 'a' - 'A' : *p2;
+ if ( (c1 -= c2) )
+ return c1;
+ p1++;
+ p2++;
+ }
+
+ return *p1 - *p2;
+}
+
+static int strincmp(const char *p1, const char *p2, int n)
+{
+ int c1 = 0, c2;
+
+ while ( n && *p1 && *p2 )
+ {
+ c1 = *p1 >= 'A' && *p1 <= 'Z' ? *p1 + 'a' - 'A' : *p1;
+ c2 = *p2 >= 'A' && *p2 <= 'Z' ? *p2 + 'a' - 'A' : *p2;
+ if ( (c1 -= c2) )
+ return c1;
+ p1++;
+ p2++;
+ n--;
+ }
+
+ return n ? *p1 - *p2 : c1;
+}
+
+static int get_token(char **p1, char **p2, int *len, int *colon)
+{
+ int tlen = 0;
+
+ while ( *len && !((**p1 >= 'A' && **p1 <= 'Z') || (**p1 >= 'a' && **p1<= 'z')) )
+ {
+ (*p1)++;
+ (*len)--;
+ }
+ if ( !*len )
+ return 0;
+
+ if ( *colon )
+ {
+ *colon = 0;
+ *p2 = *p1;
+ while ( *len && **p2 > ' ' && **p2 != ',' )
+ {
+ if ( **p2 == ':' )
+ {
+ *colon = 1;
+ break;
+ }
+ (*p2)++;
+ (*len)--;
+ tlen++;
+ }
+ **p2 = 0;
+ }
+ else
+ {
+ *p2 = *p1;
+ while ( *len && **p2 > ' ' && **p2 != ',' )
+ {
+ (*p2)++;
+ (*len)--;
+ tlen++;
+ }
+ **p2 = 0;
+ }
+
+ return tlen;
+}
+
+static int get_number(char **p, int *len, int is_hex)
+{
+ int ret = 0;
+ int n = 0;
+
+ if ( (*p)[0] == '0' && (*p)[1] == 'x' )
+ {
+ is_hex = 1;
+ (*p) += 2;
+ (*len) -= 2;
+ }
+
+ if ( is_hex )
+ {
+ while ( *len && ((**p >= '0' && **p <= '9') || (**p >= 'a' && **p <= 'f') || (**p >= 'A' && **p <= 'F')) )
+ {
+ if ( **p >= '0' && **p <= '9' )
+ n = **p - '0';
+ else if ( **p >= 'a' && **p <= 'f' )
+ n = **p - 'a' + 10;
+ else if ( **p >= 'A' && **p <= 'F' )
+ n = **p - 'A' + 10;
+ ret = (ret << 4) | n;
+ (*p)++;
+ (*len)--;
+ }
+ }
+ else
+ {
+ while ( *len && **p >= '0' && **p <= '9' )
+ {
+ n = **p - '0';
+ ret = ret * 10 + n;
+ (*p)++;
+ (*len)--;
+ }
+ }
+
+ return ret;
+}
+
+static inline void ignore_space(char **p, int *len)
+{
+ while ( *len && (**p <= ' ' || **p == ':' || **p == '.' || **p == ',') )
+ {
+ (*p)++;
+ (*len)--;
+ }
+}
+
+
+
+/*
+ * ####################################
+ * Global Function
+ * ####################################
+ */
+
+
+
+/*
+ * ####################################
+ * Init/Cleanup API
+ * ####################################
+ */
+
+static int __init ifx_ptm_test_init(void)
+{
+ proc_file_create();
+
+ return 0;
+}
+
+static void __exit ifx_ptm_test_exit(void)
+{
+ proc_file_delete();
+}
+
+module_init(ifx_ptm_test_init);
+module_exit(ifx_ptm_test_exit);
+
+#endif
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.c b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.c
new file mode 100644
index 0000000000..745eb03321
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.c
@@ -0,0 +1,1080 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_vdsl.c
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver common source file (core functions for VR9)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/ctype.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/etherdevice.h>
+#include <linux/interrupt.h>
+
+#include "ifxmips_ptm_vdsl.h"
+#include <lantiq_soc.h>
+
+#define MODULE_PARM_ARRAY(a, b) module_param_array(a, int, NULL, 0)
+#define MODULE_PARM(a, b) module_param(a, int, 0)
+
+static int wanqos_en = 0;
+static int queue_gamma_map[4] = {0xFE, 0x01, 0x00, 0x00};
+
+MODULE_PARM(wanqos_en, "i");
+MODULE_PARM_DESC(wanqos_en, "WAN QoS support, 1 - enabled, 0 - disabled.");
+
+MODULE_PARM_ARRAY(queue_gamma_map, "4-4i");
+MODULE_PARM_DESC(queue_gamma_map, "TX QoS queues mapping to 4 TX Gamma interfaces.");
+
+extern int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *);
+extern int (*ifx_mei_atm_showtime_exit)(void);
+extern int ifx_mei_atm_showtime_check(int *is_showtime, struct port_cell_info *port_cell, void **xdata_addr);
+
+static int g_showtime = 0;
+static void *g_xdata_addr = NULL;
+
+
+#define ENABLE_TMP_DBG 0
+
+unsigned long cgu_get_pp32_clock(void)
+{
+ struct clk *c = clk_get_ppe();
+ unsigned long rate = clk_get_rate(c);
+ clk_put(c);
+ return rate;
+}
+
+static void ptm_setup(struct net_device *, int);
+static struct net_device_stats *ptm_get_stats(struct net_device *);
+static int ptm_open(struct net_device *);
+static int ptm_stop(struct net_device *);
+ static unsigned int ptm_poll(int, unsigned int);
+ static int ptm_napi_poll(struct napi_struct *, int);
+static int ptm_hard_start_xmit(struct sk_buff *, struct net_device *);
+static int ptm_ioctl(struct net_device *, struct ifreq *, int);
+static void ptm_tx_timeout(struct net_device *);
+
+static inline struct sk_buff* alloc_skb_rx(void);
+static inline struct sk_buff* alloc_skb_tx(unsigned int);
+static inline struct sk_buff *get_skb_pointer(unsigned int);
+static inline int get_tx_desc(unsigned int, unsigned int *);
+
+/*
+ * Mailbox handler and signal function
+ */
+static irqreturn_t mailbox_irq_handler(int, void *);
+
+/*
+ * Tasklet to Handle Swap Descriptors
+ */
+static void do_swap_desc_tasklet(unsigned long);
+
+
+/*
+ * Init & clean-up functions
+ */
+static inline int init_priv_data(void);
+static inline void clear_priv_data(void);
+static inline int init_tables(void);
+static inline void clear_tables(void);
+
+static int g_wanqos_en = 0;
+
+static int g_queue_gamma_map[4];
+
+static struct ptm_priv_data g_ptm_priv_data;
+
+static struct net_device_ops g_ptm_netdev_ops = {
+ .ndo_get_stats = ptm_get_stats,
+ .ndo_open = ptm_open,
+ .ndo_stop = ptm_stop,
+ .ndo_start_xmit = ptm_hard_start_xmit,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_do_ioctl = ptm_ioctl,
+ .ndo_tx_timeout = ptm_tx_timeout,
+};
+
+static struct net_device *g_net_dev[1] = {0};
+static char *g_net_dev_name[1] = {"ptm0"};
+
+static int g_ptm_prio_queue_map[8];
+
+static DECLARE_TASKLET(g_swap_desc_tasklet, do_swap_desc_tasklet, 0);
+
+
+unsigned int ifx_ptm_dbg_enable = DBG_ENABLE_MASK_ERR;
+
+/*
+ * ####################################
+ * Local Function
+ * ####################################
+ */
+
+static void ptm_setup(struct net_device *dev, int ndev)
+{
+ dev->netdev_ops = &g_ptm_netdev_ops;
+ netif_napi_add(dev, &g_ptm_priv_data.itf[ndev].napi, ptm_napi_poll, 16);
+ dev->watchdog_timeo = ETH_WATCHDOG_TIMEOUT;
+
+ dev->dev_addr[0] = 0x00;
+ dev->dev_addr[1] = 0x20;
+ dev->dev_addr[2] = 0xda;
+ dev->dev_addr[3] = 0x86;
+ dev->dev_addr[4] = 0x23;
+ dev->dev_addr[5] = 0x75 + ndev;
+}
+
+static struct net_device_stats *ptm_get_stats(struct net_device *dev)
+{
+ struct net_device_stats *s;
+
+ if ( dev != g_net_dev[0] )
+ return NULL;
+s = &g_ptm_priv_data.itf[0].stats;
+
+ return s;
+}
+
+static int ptm_open(struct net_device *dev)
+{
+ ASSERT(dev == g_net_dev[0], "incorrect device");
+
+ napi_enable(&g_ptm_priv_data.itf[0].napi);
+
+ IFX_REG_W32_MASK(0, 1, MBOX_IGU1_IER);
+
+ netif_start_queue(dev);
+
+ return 0;
+}
+
+static int ptm_stop(struct net_device *dev)
+{
+ ASSERT(dev == g_net_dev[0], "incorrect device");
+
+ IFX_REG_W32_MASK(1 | (1 << 17), 0, MBOX_IGU1_IER);
+
+ napi_disable(&g_ptm_priv_data.itf[0].napi);
+
+ netif_stop_queue(dev);
+
+ return 0;
+}
+
+static unsigned int ptm_poll(int ndev, unsigned int work_to_do)
+{
+ unsigned int work_done = 0;
+ volatile struct rx_descriptor *desc;
+ struct rx_descriptor reg_desc;
+ struct sk_buff *skb, *new_skb;
+
+ ASSERT(ndev >= 0 && ndev < ARRAY_SIZE(g_net_dev), "ndev = %d (wrong value)", ndev);
+
+ while ( work_done < work_to_do ) {
+ desc = &WAN_RX_DESC_BASE[g_ptm_priv_data.itf[0].rx_desc_pos];
+ if ( desc->own /* || !desc->c */ ) // if PP32 hold descriptor or descriptor not completed
+ break;
+ if ( ++g_ptm_priv_data.itf[0].rx_desc_pos == WAN_RX_DESC_NUM )
+ g_ptm_priv_data.itf[0].rx_desc_pos = 0;
+
+ reg_desc = *desc;
+ skb = get_skb_pointer(reg_desc.dataptr);
+ ASSERT(skb != NULL, "invalid pointer skb == NULL");
+
+ new_skb = alloc_skb_rx();
+ if ( new_skb != NULL ) {
+ skb_reserve(skb, reg_desc.byteoff);
+ skb_put(skb, reg_desc.datalen);
+
+ // parse protocol header
+ skb->dev = g_net_dev[0];
+ skb->protocol = eth_type_trans(skb, skb->dev);
+
+ g_net_dev[0]->last_rx = jiffies;
+
+ netif_receive_skb(skb);
+
+ g_ptm_priv_data.itf[0].stats.rx_packets++;
+ g_ptm_priv_data.itf[0].stats.rx_bytes += reg_desc.datalen;
+
+ reg_desc.dataptr = (unsigned int)new_skb->data & 0x0FFFFFFF;
+ reg_desc.byteoff = RX_HEAD_MAC_ADDR_ALIGNMENT;
+ }
+
+ reg_desc.datalen = RX_MAX_BUFFER_SIZE - RX_HEAD_MAC_ADDR_ALIGNMENT;
+ reg_desc.own = 1;
+ reg_desc.c = 0;
+
+ /* write discriptor to memory */
+ *((volatile unsigned int *)desc + 1) = *((unsigned int *)&reg_desc + 1);
+ wmb();
+ *(volatile unsigned int *)desc = *(unsigned int *)&reg_desc;
+
+ work_done++;
+ }
+
+ return work_done;
+}
+
+static int ptm_napi_poll(struct napi_struct *napi, int budget)
+{
+ int ndev = 0;
+ unsigned int work_done;
+
+ work_done = ptm_poll(ndev, budget);
+
+ // interface down
+ if ( !netif_running(napi->dev) ) {
+ napi_complete(napi);
+ return work_done;
+ }
+
+ // clear interrupt
+ IFX_REG_W32_MASK(0, 1, MBOX_IGU1_ISRC);
+ // no more traffic
+ if ( WAN_RX_DESC_BASE[g_ptm_priv_data.itf[0].rx_desc_pos].own ) { // if PP32 hold descriptor
+ napi_complete(napi);
+ IFX_REG_W32_MASK(0, 1, MBOX_IGU1_IER);
+ return work_done;
+ }
+
+ // next round
+ return work_done;
+}
+
+static int ptm_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ unsigned int f_full;
+ int desc_base;
+ volatile struct tx_descriptor *desc;
+ struct tx_descriptor reg_desc = {0};
+ struct sk_buff *skb_to_free;
+ unsigned int byteoff;
+
+ ASSERT(dev == g_net_dev[0], "incorrect device");
+
+ if ( !g_showtime ) {
+ err("not in showtime");
+ goto PTM_HARD_START_XMIT_FAIL;
+ }
+
+ /* allocate descriptor */
+ desc_base = get_tx_desc(0, &f_full);
+ if ( f_full ) {
+ dev->trans_start = jiffies;
+ netif_stop_queue(dev);
+
+ IFX_REG_W32_MASK(0, 1 << 17, MBOX_IGU1_ISRC);
+ IFX_REG_W32_MASK(0, 1 << 17, MBOX_IGU1_IER);
+ }
+ if ( desc_base < 0 )
+ goto PTM_HARD_START_XMIT_FAIL;
+ desc = &CPU_TO_WAN_TX_DESC_BASE[desc_base];
+
+ byteoff = (unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1);
+ if ( skb_headroom(skb) < sizeof(struct sk_buff *) + byteoff || skb_cloned(skb) ) {
+ struct sk_buff *new_skb;
+
+ ASSERT(skb_headroom(skb) >= sizeof(struct sk_buff *) + byteoff, "skb_headroom(skb) < sizeof(struct sk_buff *) + byteoff");
+ ASSERT(!skb_cloned(skb), "skb is cloned");
+
+ new_skb = alloc_skb_tx(skb->len);
+ if ( new_skb == NULL ) {
+ dbg("no memory");
+ goto ALLOC_SKB_TX_FAIL;
+ }
+ skb_put(new_skb, skb->len);
+ memcpy(new_skb->data, skb->data, skb->len);
+ dev_kfree_skb_any(skb);
+ skb = new_skb;
+ byteoff = (unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1);
+ /* write back to physical memory */
+ dma_cache_wback((unsigned long)skb->data, skb->len);
+ }
+
+ *(struct sk_buff **)((unsigned int)skb->data - byteoff - sizeof(struct sk_buff *)) = skb;
+ /* write back to physical memory */
+ dma_cache_wback((unsigned long)skb->data - byteoff - sizeof(struct sk_buff *), skb->len + byteoff + sizeof(struct sk_buff *));
+
+ /* free previous skb */
+ skb_to_free = get_skb_pointer(desc->dataptr);
+ if ( skb_to_free != NULL )
+ dev_kfree_skb_any(skb_to_free);
+
+ /* update descriptor */
+ reg_desc.small = 0;
+ reg_desc.dataptr = (unsigned int)skb->data & (0x0FFFFFFF ^ (DATA_BUFFER_ALIGNMENT - 1));
+ reg_desc.datalen = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+ reg_desc.qid = g_ptm_prio_queue_map[skb->priority > 7 ? 7 : skb->priority];
+ reg_desc.byteoff = byteoff;
+ reg_desc.own = 1;
+ reg_desc.c = 1;
+ reg_desc.sop = reg_desc.eop = 1;
+
+ /* update MIB */
+ g_ptm_priv_data.itf[0].stats.tx_packets++;
+ g_ptm_priv_data.itf[0].stats.tx_bytes += reg_desc.datalen;
+
+ /* write discriptor to memory */
+ *((volatile unsigned int *)desc + 1) = *((unsigned int *)&reg_desc + 1);
+ wmb();
+ *(volatile unsigned int *)desc = *(unsigned int *)&reg_desc;
+
+ dev->trans_start = jiffies;
+
+ return 0;
+
+ALLOC_SKB_TX_FAIL:
+PTM_HARD_START_XMIT_FAIL:
+ dev_kfree_skb_any(skb);
+ g_ptm_priv_data.itf[0].stats.tx_dropped++;
+ return 0;
+}
+
+static int ptm_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ ASSERT(dev == g_net_dev[0], "incorrect device");
+
+ switch ( cmd )
+ {
+ case IFX_PTM_MIB_CW_GET:
+ ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifRxNoIdleCodewords = IFX_REG_R32(DREG_AR_CELL0) + IFX_REG_R32(DREG_AR_CELL1);
+ ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifRxIdleCodewords = IFX_REG_R32(DREG_AR_IDLE_CNT0) + IFX_REG_R32(DREG_AR_IDLE_CNT1);
+ ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifRxCodingViolation = IFX_REG_R32(DREG_AR_CVN_CNT0) + IFX_REG_R32(DREG_AR_CVN_CNT1) + IFX_REG_R32(DREG_AR_CVNP_CNT0) + IFX_REG_R32(DREG_AR_CVNP_CNT1);
+ ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifTxNoIdleCodewords = IFX_REG_R32(DREG_AT_CELL0) + IFX_REG_R32(DREG_AT_CELL1);
+ ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifTxIdleCodewords = IFX_REG_R32(DREG_AT_IDLE_CNT0) + IFX_REG_R32(DREG_AT_IDLE_CNT1);
+ break;
+ case IFX_PTM_MIB_FRAME_GET:
+ {
+ PTM_FRAME_MIB_T data = {0};
+ int i;
+
+ data.RxCorrect = IFX_REG_R32(DREG_AR_HEC_CNT0) + IFX_REG_R32(DREG_AR_HEC_CNT1) + IFX_REG_R32(DREG_AR_AIIDLE_CNT0) + IFX_REG_R32(DREG_AR_AIIDLE_CNT1);
+ for ( i = 0; i < 4; i++ )
+ data.RxDropped += WAN_RX_MIB_TABLE(i)->wrx_dropdes_pdu;
+ for ( i = 0; i < 8; i++ )
+ data.TxSend += WAN_TX_MIB_TABLE(i)->wtx_total_pdu;
+
+ *((PTM_FRAME_MIB_T *)ifr->ifr_data) = data;
+ }
+ break;
+ case IFX_PTM_CFG_GET:
+ // use bear channel 0 preemption gamma interface settings
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxEthCrcPresent = 1;
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxEthCrcCheck = RX_GAMMA_ITF_CFG(0)->rx_eth_fcs_ver_dis == 0 ? 1 : 0;
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcCheck = RX_GAMMA_ITF_CFG(0)->rx_tc_crc_ver_dis == 0 ? 1 : 0;;
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcLen = RX_GAMMA_ITF_CFG(0)->rx_tc_crc_size == 0 ? 0 : (RX_GAMMA_ITF_CFG(0)->rx_tc_crc_size * 16);
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxEthCrcGen = TX_GAMMA_ITF_CFG(0)->tx_eth_fcs_gen_dis == 0 ? 1 : 0;
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcGen = TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size == 0 ? 0 : 1;
+ ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcLen = TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size == 0 ? 0 : (TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size * 16);
+ break;
+ case IFX_PTM_CFG_SET:
+ {
+ int i;
+
+ for ( i = 0; i < 4; i++ ) {
+ RX_GAMMA_ITF_CFG(i)->rx_eth_fcs_ver_dis = ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxEthCrcCheck ? 0 : 1;
+
+ RX_GAMMA_ITF_CFG(0)->rx_tc_crc_ver_dis = ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcCheck ? 0 : 1;
+
+ switch ( ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcLen ) {
+ case 16: RX_GAMMA_ITF_CFG(0)->rx_tc_crc_size = 1; break;
+ case 32: RX_GAMMA_ITF_CFG(0)->rx_tc_crc_size = 2; break;
+ default: RX_GAMMA_ITF_CFG(0)->rx_tc_crc_size = 0;
+ }
+
+ TX_GAMMA_ITF_CFG(0)->tx_eth_fcs_gen_dis = ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxEthCrcGen ? 0 : 1;
+
+ if ( ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcGen ) {
+ switch ( ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcLen ) {
+ case 16: TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size = 1; break;
+ case 32: TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size = 2; break;
+ default: TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size = 0;
+ }
+ }
+ else
+ TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size = 0;
+ }
+ }
+ break;
+ case IFX_PTM_MAP_PKT_PRIO_TO_Q:
+ {
+ struct ppe_prio_q_map cmd;
+
+ if ( copy_from_user(&cmd, ifr->ifr_data, sizeof(cmd)) )
+ return -EFAULT;
+
+ if ( cmd.pkt_prio < 0 || cmd.pkt_prio >= ARRAY_SIZE(g_ptm_prio_queue_map) )
+ return -EINVAL;
+
+ if ( cmd.qid < 0 || cmd.qid >= g_wanqos_en )
+ return -EINVAL;
+
+ g_ptm_prio_queue_map[cmd.pkt_prio] = cmd.qid;
+ }
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static void ptm_tx_timeout(struct net_device *dev)
+{
+ ASSERT(dev == g_net_dev[0], "incorrect device");
+
+ /* disable TX irq, release skb when sending new packet */
+ IFX_REG_W32_MASK(1 << 17, 0, MBOX_IGU1_IER);
+
+ /* wake up TX queue */
+ netif_wake_queue(dev);
+
+ return;
+}
+
+static inline struct sk_buff* alloc_skb_rx(void)
+{
+ struct sk_buff *skb;
+
+ /* allocate memroy including trailer and padding */
+ skb = dev_alloc_skb(RX_MAX_BUFFER_SIZE + DATA_BUFFER_ALIGNMENT);
+ if ( skb != NULL ) {
+ /* must be burst length alignment and reserve two more bytes for MAC address alignment */
+ if ( ((unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1)) != 0 )
+ skb_reserve(skb, ~((unsigned int)skb->data + (DATA_BUFFER_ALIGNMENT - 1)) & (DATA_BUFFER_ALIGNMENT - 1));
+ /* pub skb in reserved area "skb->data - 4" */
+ *((struct sk_buff **)skb->data - 1) = skb;
+ wmb();
+ /* write back and invalidate cache */
+ dma_cache_wback_inv((unsigned long)skb->data - sizeof(skb), sizeof(skb));
+ /* invalidate cache */
+ dma_cache_inv((unsigned long)skb->data, (unsigned int)skb->end - (unsigned int)skb->data);
+ }
+
+ return skb;
+}
+
+static inline struct sk_buff* alloc_skb_tx(unsigned int size)
+{
+ struct sk_buff *skb;
+
+ /* allocate memory including padding */
+ size = RX_MAX_BUFFER_SIZE;
+ size = (size + DATA_BUFFER_ALIGNMENT - 1) & ~(DATA_BUFFER_ALIGNMENT - 1);
+ skb = dev_alloc_skb(size + DATA_BUFFER_ALIGNMENT);
+ /* must be burst length alignment */
+ if ( skb != NULL )
+ skb_reserve(skb, ~((unsigned int)skb->data + (DATA_BUFFER_ALIGNMENT - 1)) & (DATA_BUFFER_ALIGNMENT - 1));
+ return skb;
+}
+
+static inline struct sk_buff *get_skb_pointer(unsigned int dataptr)
+{
+ unsigned int skb_dataptr;
+ struct sk_buff *skb;
+
+ // usually, CPE memory is less than 256M bytes
+ // so NULL means invalid pointer
+ if ( dataptr == 0 ) {
+ dbg("dataptr is 0, it's supposed to be invalid pointer");
+ return NULL;
+ }
+
+ skb_dataptr = (dataptr - 4) | KSEG1;
+ skb = *(struct sk_buff **)skb_dataptr;
+
+ ASSERT((unsigned int)skb >= KSEG0, "invalid skb - skb = %#08x, dataptr = %#08x", (unsigned int)skb, dataptr);
+ ASSERT((((unsigned int)skb->data & (0x0FFFFFFF ^ (DATA_BUFFER_ALIGNMENT - 1))) | KSEG1) == (dataptr | KSEG1), "invalid skb - skb = %#08x, skb->data = %#08x, dataptr = %#08x", (unsigned int)skb, (unsigned int)skb->data, dataptr);
+
+ return skb;
+}
+
+static inline int get_tx_desc(unsigned int itf, unsigned int *f_full)
+{
+ int desc_base = -1;
+ struct ptm_itf *p_itf = &g_ptm_priv_data.itf[0];
+
+ // assume TX is serial operation
+ // no protection provided
+
+ *f_full = 1;
+
+ if ( CPU_TO_WAN_TX_DESC_BASE[p_itf->tx_desc_pos].own == 0 ) {
+ desc_base = p_itf->tx_desc_pos;
+ if ( ++(p_itf->tx_desc_pos) == CPU_TO_WAN_TX_DESC_NUM )
+ p_itf->tx_desc_pos = 0;
+ if ( CPU_TO_WAN_TX_DESC_BASE[p_itf->tx_desc_pos].own == 0 )
+ *f_full = 0;
+ }
+
+ return desc_base;
+}
+
+static irqreturn_t mailbox_irq_handler(int irq, void *dev_id)
+{
+ unsigned int isr;
+ int i;
+
+ isr = IFX_REG_R32(MBOX_IGU1_ISR);
+ IFX_REG_W32(isr, MBOX_IGU1_ISRC);
+ isr &= IFX_REG_R32(MBOX_IGU1_IER);
+
+ if (isr & BIT(0)) {
+ IFX_REG_W32_MASK(1, 0, MBOX_IGU1_IER);
+ napi_schedule(&g_ptm_priv_data.itf[0].napi);
+#if defined(ENABLE_TMP_DBG) && ENABLE_TMP_DBG
+ {
+ volatile struct rx_descriptor *desc = &WAN_RX_DESC_BASE[g_ptm_priv_data.itf[0].rx_desc_pos];
+
+ if ( desc->own ) { // PP32 hold
+ err("invalid interrupt");
+ }
+ }
+#endif
+ }
+ if (isr & BIT(16)) {
+ IFX_REG_W32_MASK(1 << 16, 0, MBOX_IGU1_IER);
+ tasklet_hi_schedule(&g_swap_desc_tasklet);
+ }
+ if (isr & BIT(17)) {
+ IFX_REG_W32_MASK(1 << 17, 0, MBOX_IGU1_IER);
+ netif_wake_queue(g_net_dev[0]);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void do_swap_desc_tasklet(unsigned long arg)
+{
+ int budget = 32;
+ volatile struct tx_descriptor *desc;
+ struct sk_buff *skb;
+ unsigned int byteoff;
+
+ while ( budget-- > 0 ) {
+ if ( WAN_SWAP_DESC_BASE[g_ptm_priv_data.itf[0].tx_swap_desc_pos].own ) // if PP32 hold descriptor
+ break;
+
+ desc = &WAN_SWAP_DESC_BASE[g_ptm_priv_data.itf[0].tx_swap_desc_pos];
+ if ( ++g_ptm_priv_data.itf[0].tx_swap_desc_pos == WAN_SWAP_DESC_NUM )
+ g_ptm_priv_data.itf[0].tx_swap_desc_pos = 0;
+
+ skb = get_skb_pointer(desc->dataptr);
+ if ( skb != NULL )
+ dev_kfree_skb_any(skb);
+
+ skb = alloc_skb_tx(RX_MAX_BUFFER_SIZE);
+ if ( skb == NULL )
+ panic("can't allocate swap buffer for PPE firmware use\n");
+ byteoff = (unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1);
+ *(struct sk_buff **)((unsigned int)skb->data - byteoff - sizeof(struct sk_buff *)) = skb;
+
+ desc->dataptr = (unsigned int)skb->data & 0x0FFFFFFF;
+ desc->own = 1;
+ }
+
+ // clear interrupt
+ IFX_REG_W32_MASK(0, 16, MBOX_IGU1_ISRC);
+ // no more skb to be replaced
+ if ( WAN_SWAP_DESC_BASE[g_ptm_priv_data.itf[0].tx_swap_desc_pos].own ) { // if PP32 hold descriptor
+ IFX_REG_W32_MASK(0, 1 << 16, MBOX_IGU1_IER);
+ return;
+ }
+
+ tasklet_hi_schedule(&g_swap_desc_tasklet);
+ return;
+}
+
+
+static inline int ifx_ptm_version(char *buf)
+{
+ int len = 0;
+ unsigned int major, minor;
+
+ ifx_ptm_get_fw_ver(&major, &minor);
+
+ len += sprintf(buf + len, "PTM %d.%d.%d", IFX_PTM_VER_MAJOR, IFX_PTM_VER_MID, IFX_PTM_VER_MINOR);
+ len += sprintf(buf + len, " PTM (E1) firmware version %d.%d\n", major, minor);
+
+ return len;
+}
+
+static inline int init_priv_data(void)
+{
+ int i, j;
+
+ g_wanqos_en = wanqos_en ? wanqos_en : 8;
+ if ( g_wanqos_en > 8 )
+ g_wanqos_en = 8;
+
+ for ( i = 0; i < ARRAY_SIZE(g_queue_gamma_map); i++ )
+ {
+ g_queue_gamma_map[i] = queue_gamma_map[i] & ((1 << g_wanqos_en) - 1);
+ for ( j = 0; j < i; j++ )
+ g_queue_gamma_map[i] &= ~g_queue_gamma_map[j];
+ }
+
+ memset(&g_ptm_priv_data, 0, sizeof(g_ptm_priv_data));
+
+ {
+ int max_packet_priority = ARRAY_SIZE(g_ptm_prio_queue_map);
+ int tx_num_q;
+ int q_step, q_accum, p_step;
+
+ tx_num_q = __ETH_WAN_TX_QUEUE_NUM;
+ q_step = tx_num_q - 1;
+ p_step = max_packet_priority - 1;
+ for ( j = 0, q_accum = 0; j < max_packet_priority; j++, q_accum += q_step )
+ g_ptm_prio_queue_map[j] = q_step - (q_accum + (p_step >> 1)) / p_step;
+ }
+
+ return 0;
+}
+
+static inline void clear_priv_data(void)
+{
+}
+
+static inline int init_tables(void)
+{
+ struct sk_buff *skb_pool[WAN_RX_DESC_NUM] = {0};
+ struct cfg_std_data_len cfg_std_data_len = {0};
+ struct tx_qos_cfg tx_qos_cfg = {0};
+ struct psave_cfg psave_cfg = {0};
+ struct eg_bwctrl_cfg eg_bwctrl_cfg = {0};
+ struct test_mode test_mode = {0};
+ struct rx_bc_cfg rx_bc_cfg = {0};
+ struct tx_bc_cfg tx_bc_cfg = {0};
+ struct gpio_mode gpio_mode = {0};
+ struct gpio_wm_cfg gpio_wm_cfg = {0};
+ struct rx_gamma_itf_cfg rx_gamma_itf_cfg = {0};
+ struct tx_gamma_itf_cfg tx_gamma_itf_cfg = {0};
+ struct wtx_qos_q_desc_cfg wtx_qos_q_desc_cfg = {0};
+ struct rx_descriptor rx_desc = {0};
+ struct tx_descriptor tx_desc = {0};
+ int i;
+
+ for ( i = 0; i < WAN_RX_DESC_NUM; i++ ) {
+ skb_pool[i] = alloc_skb_rx();
+ if ( skb_pool[i] == NULL )
+ goto ALLOC_SKB_RX_FAIL;
+ }
+
+ cfg_std_data_len.byte_off = RX_HEAD_MAC_ADDR_ALIGNMENT; // this field replaces byte_off in rx descriptor of VDSL ingress
+ cfg_std_data_len.data_len = 1600;
+ *CFG_STD_DATA_LEN = cfg_std_data_len;
+
+ tx_qos_cfg.time_tick = cgu_get_pp32_clock() / 62500; // 16 * (cgu_get_pp32_clock() / 1000000)
+ tx_qos_cfg.overhd_bytes = 0;
+ tx_qos_cfg.eth1_eg_qnum = __ETH_WAN_TX_QUEUE_NUM;
+ tx_qos_cfg.eth1_burst_chk = 1;
+ tx_qos_cfg.eth1_qss = 0;
+ tx_qos_cfg.shape_en = 0; // disable
+ tx_qos_cfg.wfq_en = 0; // strict priority
+ *TX_QOS_CFG = tx_qos_cfg;
+
+ psave_cfg.start_state = 0;
+ psave_cfg.sleep_en = 1; // enable sleep mode
+ *PSAVE_CFG = psave_cfg;
+
+ eg_bwctrl_cfg.fdesc_wm = 16;
+ eg_bwctrl_cfg.class_len = 128;
+ *EG_BWCTRL_CFG = eg_bwctrl_cfg;
+
+ //*GPIO_ADDR = (unsigned int)IFX_GPIO_P0_OUT;
+ *GPIO_ADDR = (unsigned int)0x00000000; // disabled by default
+
+ gpio_mode.gpio_bit_bc1 = 2;
+ gpio_mode.gpio_bit_bc0 = 1;
+ gpio_mode.gpio_bc1_en = 0;
+ gpio_mode.gpio_bc0_en = 0;
+ *GPIO_MODE = gpio_mode;
+
+ gpio_wm_cfg.stop_wm_bc1 = 2;
+ gpio_wm_cfg.start_wm_bc1 = 4;
+ gpio_wm_cfg.stop_wm_bc0 = 2;
+ gpio_wm_cfg.start_wm_bc0 = 4;
+ *GPIO_WM_CFG = gpio_wm_cfg;
+
+ test_mode.mib_clear_mode = 0;
+ test_mode.test_mode = 0;
+ *TEST_MODE = test_mode;
+
+ rx_bc_cfg.local_state = 0;
+ rx_bc_cfg.remote_state = 0;
+ rx_bc_cfg.to_false_th = 7;
+ rx_bc_cfg.to_looking_th = 3;
+ *RX_BC_CFG(0) = rx_bc_cfg;
+ *RX_BC_CFG(1) = rx_bc_cfg;
+
+ tx_bc_cfg.fill_wm = 2;
+ tx_bc_cfg.uflw_wm = 2;
+ *TX_BC_CFG(0) = tx_bc_cfg;
+ *TX_BC_CFG(1) = tx_bc_cfg;
+
+ rx_gamma_itf_cfg.receive_state = 0;
+ rx_gamma_itf_cfg.rx_min_len = 60;
+ rx_gamma_itf_cfg.rx_pad_en = 1;
+ rx_gamma_itf_cfg.rx_eth_fcs_ver_dis = 0;
+ rx_gamma_itf_cfg.rx_rm_eth_fcs = 1;
+ rx_gamma_itf_cfg.rx_tc_crc_ver_dis = 0;
+ rx_gamma_itf_cfg.rx_tc_crc_size = 1;
+ rx_gamma_itf_cfg.rx_eth_fcs_result = 0xC704DD7B;
+ rx_gamma_itf_cfg.rx_tc_crc_result = 0x1D0F1D0F;
+ rx_gamma_itf_cfg.rx_crc_cfg = 0x2500;
+ rx_gamma_itf_cfg.rx_eth_fcs_init_value = 0xFFFFFFFF;
+ rx_gamma_itf_cfg.rx_tc_crc_init_value = 0x0000FFFF;
+ rx_gamma_itf_cfg.rx_max_len_sel = 0;
+ rx_gamma_itf_cfg.rx_edit_num2 = 0;
+ rx_gamma_itf_cfg.rx_edit_pos2 = 0;
+ rx_gamma_itf_cfg.rx_edit_type2 = 0;
+ rx_gamma_itf_cfg.rx_edit_en2 = 0;
+ rx_gamma_itf_cfg.rx_edit_num1 = 0;
+ rx_gamma_itf_cfg.rx_edit_pos1 = 0;
+ rx_gamma_itf_cfg.rx_edit_type1 = 0;
+ rx_gamma_itf_cfg.rx_edit_en1 = 0;
+ rx_gamma_itf_cfg.rx_inserted_bytes_1l = 0;
+ rx_gamma_itf_cfg.rx_inserted_bytes_1h = 0;
+ rx_gamma_itf_cfg.rx_inserted_bytes_2l = 0;
+ rx_gamma_itf_cfg.rx_inserted_bytes_2h = 0;
+ rx_gamma_itf_cfg.rx_len_adj = -6;
+ for ( i = 0; i < 4; i++ )
+ *RX_GAMMA_ITF_CFG(i) = rx_gamma_itf_cfg;
+
+ tx_gamma_itf_cfg.tx_len_adj = 6;
+ tx_gamma_itf_cfg.tx_crc_off_adj = 6;
+ tx_gamma_itf_cfg.tx_min_len = 0;
+ tx_gamma_itf_cfg.tx_eth_fcs_gen_dis = 0;
+ tx_gamma_itf_cfg.tx_tc_crc_size = 1;
+ tx_gamma_itf_cfg.tx_crc_cfg = 0x2F00;
+ tx_gamma_itf_cfg.tx_eth_fcs_init_value = 0xFFFFFFFF;
+ tx_gamma_itf_cfg.tx_tc_crc_init_value = 0x0000FFFF;
+ for ( i = 0; i < ARRAY_SIZE(g_queue_gamma_map); i++ ) {
+ tx_gamma_itf_cfg.queue_mapping = g_queue_gamma_map[i];
+ *TX_GAMMA_ITF_CFG(i) = tx_gamma_itf_cfg;
+ }
+
+ for ( i = 0; i < __ETH_WAN_TX_QUEUE_NUM; i++ ) {
+ wtx_qos_q_desc_cfg.length = WAN_TX_DESC_NUM;
+ wtx_qos_q_desc_cfg.addr = __ETH_WAN_TX_DESC_BASE(i);
+ *WTX_QOS_Q_DESC_CFG(i) = wtx_qos_q_desc_cfg;
+ }
+
+ // default TX queue QoS config is all ZERO
+
+ // TX Ctrl K Table
+ IFX_REG_W32(0x90111293, TX_CTRL_K_TABLE(0));
+ IFX_REG_W32(0x14959617, TX_CTRL_K_TABLE(1));
+ IFX_REG_W32(0x18999A1B, TX_CTRL_K_TABLE(2));
+ IFX_REG_W32(0x9C1D1E9F, TX_CTRL_K_TABLE(3));
+ IFX_REG_W32(0xA02122A3, TX_CTRL_K_TABLE(4));
+ IFX_REG_W32(0x24A5A627, TX_CTRL_K_TABLE(5));
+ IFX_REG_W32(0x28A9AA2B, TX_CTRL_K_TABLE(6));
+ IFX_REG_W32(0xAC2D2EAF, TX_CTRL_K_TABLE(7));
+ IFX_REG_W32(0x30B1B233, TX_CTRL_K_TABLE(8));
+ IFX_REG_W32(0xB43536B7, TX_CTRL_K_TABLE(9));
+ IFX_REG_W32(0xB8393ABB, TX_CTRL_K_TABLE(10));
+ IFX_REG_W32(0x3CBDBE3F, TX_CTRL_K_TABLE(11));
+ IFX_REG_W32(0xC04142C3, TX_CTRL_K_TABLE(12));
+ IFX_REG_W32(0x44C5C647, TX_CTRL_K_TABLE(13));
+ IFX_REG_W32(0x48C9CA4B, TX_CTRL_K_TABLE(14));
+ IFX_REG_W32(0xCC4D4ECF, TX_CTRL_K_TABLE(15));
+
+ // init RX descriptor
+ rx_desc.own = 1;
+ rx_desc.c = 0;
+ rx_desc.sop = 1;
+ rx_desc.eop = 1;
+ rx_desc.byteoff = RX_HEAD_MAC_ADDR_ALIGNMENT;
+ rx_desc.datalen = RX_MAX_BUFFER_SIZE - RX_HEAD_MAC_ADDR_ALIGNMENT;
+ for ( i = 0; i < WAN_RX_DESC_NUM; i++ ) {
+ rx_desc.dataptr = (unsigned int)skb_pool[i]->data & 0x0FFFFFFF;
+ WAN_RX_DESC_BASE[i] = rx_desc;
+ }
+
+ // init TX descriptor
+ tx_desc.own = 0;
+ tx_desc.c = 0;
+ tx_desc.sop = 1;
+ tx_desc.eop = 1;
+ tx_desc.byteoff = 0;
+ tx_desc.qid = 0;
+ tx_desc.datalen = 0;
+ tx_desc.small = 0;
+ tx_desc.dataptr = 0;
+ for ( i = 0; i < CPU_TO_WAN_TX_DESC_NUM; i++ )
+ CPU_TO_WAN_TX_DESC_BASE[i] = tx_desc;
+ for ( i = 0; i < WAN_TX_DESC_NUM_TOTAL; i++ )
+ WAN_TX_DESC_BASE(0)[i] = tx_desc;
+
+ // init Swap descriptor
+ for ( i = 0; i < WAN_SWAP_DESC_NUM; i++ )
+ WAN_SWAP_DESC_BASE[i] = tx_desc;
+
+ // init fastpath TX descriptor
+ tx_desc.own = 1;
+ for ( i = 0; i < FASTPATH_TO_WAN_TX_DESC_NUM; i++ )
+ FASTPATH_TO_WAN_TX_DESC_BASE[i] = tx_desc;
+
+ return 0;
+
+ALLOC_SKB_RX_FAIL:
+ while ( i-- > 0 )
+ dev_kfree_skb_any(skb_pool[i]);
+ return -1;
+}
+
+static inline void clear_tables(void)
+{
+ struct sk_buff *skb;
+ int i, j;
+
+ for ( i = 0; i < WAN_RX_DESC_NUM; i++ ) {
+ skb = get_skb_pointer(WAN_RX_DESC_BASE[i].dataptr);
+ if ( skb != NULL )
+ dev_kfree_skb_any(skb);
+ }
+
+ for ( i = 0; i < CPU_TO_WAN_TX_DESC_NUM; i++ ) {
+ skb = get_skb_pointer(CPU_TO_WAN_TX_DESC_BASE[i].dataptr);
+ if ( skb != NULL )
+ dev_kfree_skb_any(skb);
+ }
+
+ for ( j = 0; j < 8; j++ )
+ for ( i = 0; i < WAN_TX_DESC_NUM; i++ ) {
+ skb = get_skb_pointer(WAN_TX_DESC_BASE(j)[i].dataptr);
+ if ( skb != NULL )
+ dev_kfree_skb_any(skb);
+ }
+
+ for ( i = 0; i < WAN_SWAP_DESC_NUM; i++ ) {
+ skb = get_skb_pointer(WAN_SWAP_DESC_BASE[i].dataptr);
+ if ( skb != NULL )
+ dev_kfree_skb_any(skb);
+ }
+
+ for ( i = 0; i < FASTPATH_TO_WAN_TX_DESC_NUM; i++ ) {
+ skb = get_skb_pointer(FASTPATH_TO_WAN_TX_DESC_BASE[i].dataptr);
+ if ( skb != NULL )
+ dev_kfree_skb_any(skb);
+ }
+}
+
+static int ptm_showtime_enter(struct port_cell_info *port_cell, void *xdata_addr)
+{
+ ASSERT(port_cell != NULL, "port_cell is NULL");
+ ASSERT(xdata_addr != NULL, "xdata_addr is NULL");
+
+ // TODO: ReTX set xdata_addr
+ g_xdata_addr = xdata_addr;
+
+ g_showtime = 1;
+
+ IFX_REG_W32(0x0F, UTP_CFG);
+
+ //#ifdef CONFIG_VR9
+ // IFX_REG_W32_MASK(1 << 17, 0, FFSM_CFG0);
+ //#endif
+
+ printk("enter showtime\n");
+
+ return 0;
+}
+
+static int ptm_showtime_exit(void)
+{
+ if ( !g_showtime )
+ return -1;
+
+ //#ifdef CONFIG_VR9
+ // IFX_REG_W32_MASK(0, 1 << 17, FFSM_CFG0);
+ //#endif
+
+ IFX_REG_W32(0x00, UTP_CFG);
+
+ g_showtime = 0;
+
+ // TODO: ReTX clean state
+ g_xdata_addr = NULL;
+
+ printk("leave showtime\n");
+
+ return 0;
+}
+
+
+
+static int ifx_ptm_init(void)
+{
+ int ret;
+ int i;
+ char ver_str[128];
+ struct port_cell_info port_cell = {0};
+
+ ret = init_priv_data();
+ if ( ret != 0 ) {
+ err("INIT_PRIV_DATA_FAIL");
+ goto INIT_PRIV_DATA_FAIL;
+ }
+
+ ifx_ptm_init_chip();
+ ret = init_tables();
+ if ( ret != 0 ) {
+ err("INIT_TABLES_FAIL");
+ goto INIT_TABLES_FAIL;
+ }
+
+ for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ ) {
+ g_net_dev[i] = alloc_netdev(0, g_net_dev_name[i], ether_setup);
+ if ( g_net_dev[i] == NULL )
+ goto ALLOC_NETDEV_FAIL;
+ ptm_setup(g_net_dev[i], i);
+ }
+
+ for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ ) {
+ ret = register_netdev(g_net_dev[i]);
+ if ( ret != 0 )
+ goto REGISTER_NETDEV_FAIL;
+ }
+
+ /* register interrupt handler */
+ ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, IRQF_DISABLED, "ptm_mailbox_isr", &g_ptm_priv_data);
+ if ( ret ) {
+ if ( ret == -EBUSY ) {
+ err("IRQ may be occupied by other driver, please reconfig to disable it.");
+ }
+ else {
+ err("request_irq fail");
+ }
+ goto REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL;
+ }
+ disable_irq(PPE_MAILBOX_IGU1_INT);
+
+ ret = ifx_pp32_start(0);
+ if ( ret ) {
+ err("ifx_pp32_start fail!");
+ goto PP32_START_FAIL;
+ }
+ IFX_REG_W32(1 << 16, MBOX_IGU1_IER); // enable SWAP interrupt
+ IFX_REG_W32(~0, MBOX_IGU1_ISRC);
+
+ enable_irq(PPE_MAILBOX_IGU1_INT);
+
+ ifx_mei_atm_showtime_check(&g_showtime, &port_cell, &g_xdata_addr);
+
+ ifx_mei_atm_showtime_enter = ptm_showtime_enter;
+ ifx_mei_atm_showtime_exit = ptm_showtime_exit;
+
+ ifx_ptm_version(ver_str);
+ printk(KERN_INFO "%s", ver_str);
+
+ printk("ifxmips_ptm: PTM init succeed\n");
+
+ return 0;
+
+PP32_START_FAIL:
+ free_irq(PPE_MAILBOX_IGU1_INT, &g_ptm_priv_data);
+REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL:
+ i = ARRAY_SIZE(g_net_dev);
+REGISTER_NETDEV_FAIL:
+ while ( i-- )
+ unregister_netdev(g_net_dev[i]);
+ i = ARRAY_SIZE(g_net_dev);
+ALLOC_NETDEV_FAIL:
+ while ( i-- ) {
+ free_netdev(g_net_dev[i]);
+ g_net_dev[i] = NULL;
+ }
+INIT_TABLES_FAIL:
+INIT_PRIV_DATA_FAIL:
+ clear_priv_data();
+ printk("ifxmips_ptm: PTM init failed\n");
+ return ret;
+}
+
+static void __exit ifx_ptm_exit(void)
+{
+ int i;
+ ifx_mei_atm_showtime_enter = NULL;
+ ifx_mei_atm_showtime_exit = NULL;
+
+
+ ifx_pp32_stop(0);
+
+ free_irq(PPE_MAILBOX_IGU1_INT, &g_ptm_priv_data);
+
+ for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ )
+ unregister_netdev(g_net_dev[i]);
+
+ for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ ) {
+ free_netdev(g_net_dev[i]);
+ g_net_dev[i] = NULL;
+ }
+
+ clear_tables();
+
+ ifx_ptm_uninit_chip();
+
+ clear_priv_data();
+}
+
+#ifndef MODULE
+static int __init wanqos_en_setup(char *line)
+{
+ wanqos_en = simple_strtoul(line, NULL, 0);
+
+ if ( wanqos_en < 1 || wanqos_en > 8 )
+ wanqos_en = 0;
+
+ return 0;
+}
+
+static int __init queue_gamma_map_setup(char *line)
+{
+ char *p;
+ int i;
+
+ for ( i = 0, p = line; i < ARRAY_SIZE(queue_gamma_map) && isxdigit(*p); i++ )
+ {
+ queue_gamma_map[i] = simple_strtoul(p, &p, 0);
+ if ( *p == ',' || *p == ';' || *p == ':' )
+ p++;
+ }
+
+ return 0;
+}
+#endif
+module_init(ifx_ptm_init);
+module_exit(ifx_ptm_exit);
+#ifndef MODULE
+ __setup("wanqos_en=", wanqos_en_setup);
+ __setup("queue_gamma_map=", queue_gamma_map_setup);
+#endif
+
+MODULE_LICENSE("GPL");
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.h b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.h
new file mode 100644
index 0000000000..b06232d0f8
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.h
@@ -0,0 +1,126 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_vdsl.h
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver header file (core functions for VR9)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+#ifndef IFXMIPS_PTM_VDSL_H
+#define IFXMIPS_PTM_VDSL_H
+
+#include <linux/version.h>
+#include <linux/netdevice.h>
+#include <lantiq_ptm.h>
+#include "ifxmips_ptm_common.h"
+#include "ifxmips_ptm_ppe_common.h"
+#include "ifxmips_ptm_fw_regs_vdsl.h"
+
+#define INT_NUM_IM2_IRL24 (INT_NUM_IM2_IRL0 + 24)
+
+#define IFX_REG_W32(_v, _r) __raw_writel((_v), (volatile unsigned int *)(_r))
+#define IFX_REG_R32(_r) __raw_readl((volatile unsigned int *)(_r))
+#define IFX_REG_W32_MASK(_clr, _set, _r) IFX_REG_W32((IFX_REG_R32((_r)) & ~(_clr)) | (_set), (_r))
+#define SET_BITS(x, msb, lsb, value) (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))
+
+
+
+/*
+ * ####################################
+ * Definition
+ * ####################################
+ */
+
+/*
+ * Constant Definition
+ */
+#define ETH_WATCHDOG_TIMEOUT (10 * HZ)
+
+/*
+ * DMA RX/TX Channel Parameters
+ */
+#define MAX_ITF_NUMBER 1
+#define MAX_RX_DMA_CHANNEL_NUMBER 1
+#define MAX_TX_DMA_CHANNEL_NUMBER 1
+#define DATA_BUFFER_ALIGNMENT EMA_ALIGNMENT
+#define DESC_ALIGNMENT 8
+
+/*
+ * Ethernet Frame Definitions
+ */
+#define ETH_MAC_HEADER_LENGTH 14
+#define ETH_CRC_LENGTH 4
+#define ETH_MIN_FRAME_LENGTH 64
+#define ETH_MAX_FRAME_LENGTH (1518 + 4 * 2)
+
+/*
+ * RX Frame Definitions
+ */
+#define RX_MAX_BUFFER_SIZE (1600 + RX_HEAD_MAC_ADDR_ALIGNMENT)
+#define RX_HEAD_MAC_ADDR_ALIGNMENT 2
+#define RX_TAIL_CRC_LENGTH 0 // PTM firmware does not have ethernet frame CRC
+ // The len in descriptor doesn't include ETH_CRC
+ // because ETH_CRC may not present in some configuration
+
+
+
+/*
+ * ####################################
+ * Data Type
+ * ####################################
+ */
+
+struct ptm_itf {
+ unsigned int rx_desc_pos;
+
+ unsigned int tx_desc_pos;
+
+ unsigned int tx_swap_desc_pos;
+
+ struct net_device_stats stats;
+
+ struct napi_struct napi;
+};
+
+struct ptm_priv_data {
+ struct ptm_itf itf[MAX_ITF_NUMBER];
+};
+
+
+
+/*
+ * ####################################
+ * Declaration
+ * ####################################
+ */
+
+extern unsigned int ifx_ptm_dbg_enable;
+
+extern void ifx_ptm_get_fw_ver(unsigned int *major, unsigned int *minor);
+
+extern void ifx_ptm_init_chip(void);
+extern void ifx_ptm_uninit_chip(void);
+
+extern int ifx_pp32_start(int pp32);
+extern void ifx_pp32_stop(int pp32);
+
+extern void ifx_reset_ppe(void);
+
+
+
+#endif // IFXMIPS_PTM_VDSL_H
diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vr9.c b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vr9.c
new file mode 100644
index 0000000000..0a02569cef
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vr9.c
@@ -0,0 +1,295 @@
+/******************************************************************************
+**
+** FILE NAME : ifxmips_ptm_vr9.c
+** PROJECT : UEIP
+** MODULES : PTM
+**
+** DATE : 7 Jul 2009
+** AUTHOR : Xu Liang
+** DESCRIPTION : PTM driver common source file (core functions)
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 07 JUL 2009 Xu Liang Init Version
+*******************************************************************************/
+
+
+
+/*
+ * ####################################
+ * Head File
+ * ####################################
+ */
+
+/*
+ * Common Head File
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <asm/delay.h>
+
+/*
+ * Chip Specific Head File
+ */
+#include "ifxmips_ptm_vdsl.h"
+#include "ifxmips_ptm_fw_vr9.h"
+
+#include <lantiq_soc.h>
+
+static inline void init_pmu(void);
+static inline void uninit_pmu(void);
+static inline void reset_ppe(void);
+static inline void init_pdma(void);
+static inline void init_mailbox(void);
+static inline void init_atm_tc(void);
+static inline void clear_share_buffer(void);
+
+#define IFX_PMU_MODULE_PPE_SLL01 BIT(19)
+#define IFX_PMU_MODULE_PPE_TC BIT(21)
+#define IFX_PMU_MODULE_PPE_EMA BIT(22)
+#define IFX_PMU_MODULE_PPE_QSB BIT(18)
+#define IFX_PMU_MODULE_AHBS BIT(13)
+#define IFX_PMU_MODULE_DSL_DFE BIT(9)
+
+
+static inline void init_pmu(void)
+{
+ ltq_pmu_enable(IFX_PMU_MODULE_PPE_SLL01 |
+ IFX_PMU_MODULE_PPE_TC |
+ IFX_PMU_MODULE_PPE_EMA |
+ IFX_PMU_MODULE_AHBS |
+ IFX_PMU_MODULE_DSL_DFE);
+
+}
+
+static inline void uninit_pmu(void)
+{
+}
+
+static inline void reset_ppe(void)
+{
+/*#ifdef MODULE
+ // reset PPE
+ ifx_rcu_rst(IFX_RCU_DOMAIN_DSLDFE, IFX_RCU_MODULE_PTM);
+ udelay(1000);
+ ifx_rcu_rst(IFX_RCU_DOMAIN_DSLTC, IFX_RCU_MODULE_PTM);
+ udelay(1000);
+ ifx_rcu_rst(IFX_RCU_DOMAIN_PPE, IFX_RCU_MODULE_PTM);
+ udelay(1000);
+ *PP32_SRST &= ~0x000303CF;
+ udelay(1000);
+ *PP32_SRST |= 0x000303CF;
+ udelay(1000);
+#endif*/
+}
+
+static inline void init_pdma(void)
+{
+ IFX_REG_W32(0x00000001, PDMA_CFG);
+ IFX_REG_W32(0x00082C00, PDMA_RX_CTX_CFG);
+ IFX_REG_W32(0x00081B00, PDMA_TX_CTX_CFG);
+ IFX_REG_W32(0x02040604, PDMA_RX_MAX_LEN_REG);
+ IFX_REG_W32(0x000F003F, PDMA_RX_DELAY_CFG);
+
+ IFX_REG_W32(0x00000011, SAR_MODE_CFG);
+ IFX_REG_W32(0x00082A00, SAR_RX_CTX_CFG);
+ IFX_REG_W32(0x00082E00, SAR_TX_CTX_CFG);
+ IFX_REG_W32(0x00001021, SAR_POLY_CFG_SET0);
+ IFX_REG_W32(0x1EDC6F41, SAR_POLY_CFG_SET1);
+ IFX_REG_W32(0x04C11DB7, SAR_POLY_CFG_SET2);
+ IFX_REG_W32(0x00000F3E, SAR_CRC_SIZE_CFG);
+
+ IFX_REG_W32(0x01001900, SAR_PDMA_RX_CMDBUF_CFG);
+ IFX_REG_W32(0x01001A00, SAR_PDMA_TX_CMDBUF_CFG);
+}
+
+static inline void init_mailbox(void)
+{
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU1_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU1_IER);
+ IFX_REG_W32(0xFFFFFFFF, MBOX_IGU3_ISRC);
+ IFX_REG_W32(0x00000000, MBOX_IGU3_IER);
+}
+
+static inline void init_atm_tc(void)
+{
+ IFX_REG_W32(0x00010040, SFSM_CFG0);
+ IFX_REG_W32(0x00010040, SFSM_CFG1);
+ IFX_REG_W32(0x00020000, SFSM_PGCNT0);
+ IFX_REG_W32(0x00020000, SFSM_PGCNT1);
+ IFX_REG_W32(0x00000000, DREG_AT_IDLE0);
+ IFX_REG_W32(0x00000000, DREG_AT_IDLE1);
+ IFX_REG_W32(0x00000000, DREG_AR_IDLE0);
+ IFX_REG_W32(0x00000000, DREG_AR_IDLE1);
+ IFX_REG_W32(0x0000080C, DREG_B0_LADR);
+ IFX_REG_W32(0x0000080C, DREG_B1_LADR);
+
+ IFX_REG_W32(0x000001F0, DREG_AR_CFG0);
+ IFX_REG_W32(0x000001F0, DREG_AR_CFG1);
+ IFX_REG_W32(0x000001E0, DREG_AT_CFG0);
+ IFX_REG_W32(0x000001E0, DREG_AT_CFG1);
+
+ /* clear sync state */
+ //IFX_REG_W32(0, SFSM_STATE0);
+ //IFX_REG_W32(0, SFSM_STATE1);
+
+ IFX_REG_W32_MASK(0, 1 << 14, SFSM_CFG0); // enable SFSM storing
+ IFX_REG_W32_MASK(0, 1 << 14, SFSM_CFG1);
+
+ IFX_REG_W32_MASK(0, 1 << 15, SFSM_CFG0); // HW keep the IDLE cells in RTHA buffer
+ IFX_REG_W32_MASK(0, 1 << 15, SFSM_CFG1);
+
+ IFX_REG_W32(0xF0D10000, FFSM_IDLE_HEAD_BC0);
+ IFX_REG_W32(0xF0D10000, FFSM_IDLE_HEAD_BC1);
+ IFX_REG_W32(0x00030028, FFSM_CFG0); // Force_idle
+ IFX_REG_W32(0x00030028, FFSM_CFG1);
+}
+
+static inline void clear_share_buffer(void)
+{
+ volatile u32 *p;
+ unsigned int i;
+
+ p = SB_RAM0_ADDR(0);
+ for ( i = 0; i < SB_RAM0_DWLEN + SB_RAM1_DWLEN + SB_RAM2_DWLEN + SB_RAM3_DWLEN; i++ )
+ IFX_REG_W32(0, p++);
+
+ p = SB_RAM6_ADDR(0);
+ for ( i = 0; i < SB_RAM6_DWLEN; i++ )
+ IFX_REG_W32(0, p++);
+}
+
+/*
+ * Description:
+ * Download PPE firmware binary code.
+ * Input:
+ * pp32 --- int, which pp32 core
+ * src --- u32 *, binary code buffer
+ * dword_len --- unsigned int, binary code length in DWORD (32-bit)
+ * Output:
+ * int --- 0: Success
+ * else: Error Code
+ */
+static inline int pp32_download_code(int pp32, u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
+{
+ unsigned int clr, set;
+ volatile u32 *dest;
+
+ if ( code_src == 0 || ((unsigned long)code_src & 0x03) != 0
+ || data_src == 0 || ((unsigned long)data_src & 0x03) != 0 )
+ return -1;
+
+ clr = pp32 ? 0xF0 : 0x0F;
+ if ( code_dword_len <= CDM_CODE_MEMORYn_DWLEN(0) )
+ set = pp32 ? (3 << 6): (2 << 2);
+ else
+ set = 0x00;
+ IFX_REG_W32_MASK(clr, set, CDM_CFG);
+
+ /* copy code */
+ dest = CDM_CODE_MEMORY(pp32, 0);
+ while ( code_dword_len-- > 0 )
+ IFX_REG_W32(*code_src++, dest++);
+
+ /* copy data */
+ dest = CDM_DATA_MEMORY(pp32, 0);
+ while ( data_dword_len-- > 0 )
+ IFX_REG_W32(*data_src++, dest++);
+
+ return 0;
+}
+
+
+
+/*
+ * ####################################
+ * Global Function
+ * ####################################
+ */
+
+extern void ifx_ptm_get_fw_ver(unsigned int *major, unsigned int *minor)
+{
+ ASSERT(major != NULL, "pointer is NULL");
+ ASSERT(minor != NULL, "pointer is NULL");
+
+ *major = FW_VER_ID->major;
+ *minor = FW_VER_ID->minor;
+}
+
+void ifx_ptm_init_chip(void)
+{
+ init_pmu();
+
+ reset_ppe();
+
+ init_pdma();
+
+ init_mailbox();
+
+ init_atm_tc();
+
+ clear_share_buffer();
+}
+
+void ifx_ptm_uninit_chip(void)
+{
+ uninit_pmu();
+}
+
+/*
+ * Description:
+ * Initialize and start up PP32.
+ * Input:
+ * none
+ * Output:
+ * int --- 0: Success
+ * else: Error Code
+ */
+int ifx_pp32_start(int pp32)
+{
+ unsigned int mask = 1 << (pp32 << 4);
+ int ret;
+
+ /* download firmware */
+ ret = pp32_download_code(pp32, firmware_binary_code, sizeof(firmware_binary_code) / sizeof(*firmware_binary_code), firmware_binary_data, sizeof(firmware_binary_data) / sizeof(*firmware_binary_data));
+ if ( ret != 0 )
+ return ret;
+
+ /* run PP32 */
+ IFX_REG_W32_MASK(mask, 0, PP32_FREEZE);
+
+ /* idle for a while to let PP32 init itself */
+ udelay(10);
+
+ return 0;
+}
+
+/*
+ * Description:
+ * Halt PP32.
+ * Input:
+ * none
+ * Output:
+ * none
+ */
+void ifx_pp32_stop(int pp32)
+{
+ unsigned int mask = 1 << (pp32 << 4);
+
+ /* halt PP32 */
+ IFX_REG_W32_MASK(0, mask, PP32_FREEZE);
+}
diff --git a/package/kernel/lantiq/ltq-tapi/Config.in b/package/kernel/lantiq/ltq-tapi/Config.in
new file mode 100644
index 0000000000..84dbef2397
--- /dev/null
+++ b/package/kernel/lantiq/ltq-tapi/Config.in
@@ -0,0 +1,88 @@
+config VOICE_CPE_TAPI_FAX
+ bool "fax relay and modem support"
+ depends on PACKAGE_kmod-ltq-tapi
+ default n
+ help
+ Option to enable fax/modem support in TAPI.
+ Note: Newer platforms as AR9 and VR9 support a T.38 fax relay stack
+ in FW while older platforms like Danube or VINETIC-CPE require a
+ separate SW stack executed as an application.
+
+config VOICE_CPE_TAPI_CID
+ bool "CID support"
+ depends on PACKAGE_kmod-ltq-tapi
+ default y
+ help
+ Option to enable Caller ID support.
+
+config VOICE_CPE_TAPI_LT_GR909
+ bool "Linetesting GR-909 support"
+ depends on PACKAGE_kmod-ltq-tapi
+ default y
+ help
+ Option to enable linetesting GR-909.
+
+config VOICE_CPE_TAPI_DECT
+ bool "DECT encoding for COSIC modem"
+ depends on PACKAGE_kmod-ltq-tapi
+ default n
+ help
+ Option to enable DECT encoding for COSIC modem.
+
+config VOICE_CPE_TAPI_KPI
+ bool "KPI (Kernel Packet Interface)"
+ depends on PACKAGE_kmod-ltq-tapi
+ default y
+ help
+ Option to enable the generic kernel level packet interface
+ which allows accelerated packet transfer for various purposes.
+ The most important example is the QOS option, which allows
+ to redirect RTP packets directly into the IP stack.
+ Other options relying on KPI are DECT and HDLC.
+
+config VOICE_CPE_TAPI_QOS
+ bool "QOS for accelerated RTP packet handling"
+ depends on PACKAGE_kmod-ltq-tapi
+ default y
+ help
+ Option to enable an accelerated RTP packet transfer inside
+ the LINUX kernel space. This option requires the KPI2UDP
+ packet, which actually provides the OS specific hooks in
+ the IP stack.
+
+config VOICE_CPE_TAPI_STATISTICS
+ bool "TAPI statistics via /proc fs"
+ depends on PACKAGE_kmod-ltq-tapi
+ default y
+ help
+ Option to enable /proc fs statistics for packet counts etc.
+
+config VOICE_CPE_TAPI_METERING
+ bool "Metering (TTX) support"
+ depends on PACKAGE_kmod-ltq-tapi
+ default n
+ help
+ Option to enable metering (TTX) support.
+
+config VOICE_CPE_TAPI_HDLC
+ bool "PCM HDLC support, evaluation"
+ depends on PACKAGE_kmod-ltq-tapi
+ default n
+ help
+ Option to enable PCM HDLC framing inside the firmware, e.g. for
+ ISDN D-Channel access.
+
+config VOICE_CPE_TAPI_TRACES
+ bool "enable driver traces"
+ depends on PACKAGE_kmod-ltq-tapi
+ default y
+ help
+ enable driver traces with different trace levels to be
+ configured dynamically from the application or during insmod
+
+config VOICE_CPE_TAPI_LINUX_HOTPLUG
+ bool "enable driver Linux hotplug events"
+ depends on PACKAGE_kmod-ltq-tapi
+ default y
+ help
+ enable driver Linux hotplug events generation
diff --git a/package/kernel/lantiq/ltq-tapi/Makefile b/package/kernel/lantiq/ltq-tapi/Makefile
new file mode 100644
index 0000000000..2582235dc9
--- /dev/null
+++ b/package/kernel/lantiq/ltq-tapi/Makefile
@@ -0,0 +1,70 @@
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=drv_tapi
+PKG_VERSION:=3.13.0
+PKG_RELEASE:=3
+
+PKG_SOURCE:=drv_tapi-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
+PKG_MD5SUM:=edb43b494832c540cc035493d18db58f
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/ltqtapi.mk
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-tapi
+ SUBMENU:=Voice over IP
+ TITLE:=Lantiq TAPI subsystem
+ URL:=http://www.lantiq.com/
+ DEPENDS:=$(LTQ_TAPI_TARGET) +kmod-ltq-ifxos
+ FILES:=$(PKG_BUILD_DIR)/src/drv_tapi.ko
+ AUTOLOAD:=$(call AutoLoad,20,drv_tapi)
+endef
+
+define KernelPackage/ltq-tapi/description
+ Voice Subsystem Telephony API High Level Driver
+endef
+
+define KernelPackage/ltq-tapi/config
+ source "$(SOURCE)/Config.in"
+endef
+
+CONFIGURE_ARGS += \
+ ARCH=$(LINUX_KARCH) \
+ --enable-linux-26 \
+ --enable-kernelbuild="$(LINUX_DIR)" \
+ --enable-kernelincl="$(LINUX_DIR)/include" \
+ --with-ifxos-incl=$(STAGING_DIR)/usr/include/ifxos \
+ $(call autoconf_bool,CONFIG_IFX_DRV_TAPI_EVENT_LOGGER,el-debug) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_FAX,fax t38) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_CID,cid) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_DECT,dect) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_KPI,kpi) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_QOS,qos) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_LT_GR909,lt) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_STATISTICS,statistics) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_METERING,metering) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_HDLC,hdlc) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_TRACES,trace) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_LINUX_HOTPLUG,hotplug)
+
+define Build/Configure
+ (cd $(PKG_BUILD_DIR); aclocal && autoconf && automake)
+ $(call Build/Configure/Default)
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include/drv_tapi
+ $(CP) --dereference $(PKG_BUILD_DIR)/include/* $(1)/usr/include/drv_tapi
+ (cd $(1)/usr/include/drv_tapi && ln -s . include && ln -s ../ifxos/ifx_types.h .)
+endef
+
+$(eval $(call KernelPackage,ltq-tapi))
diff --git a/package/kernel/lantiq/ltq-tapi/patches/000-portability.patch b/package/kernel/lantiq/ltq-tapi/patches/000-portability.patch
new file mode 100644
index 0000000000..78fcbad668
--- /dev/null
+++ b/package/kernel/lantiq/ltq-tapi/patches/000-portability.patch
@@ -0,0 +1,82 @@
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -154,7 +154,7 @@ if KERNEL_2_6
+ drv_tapi_OBJS = "$(subst .c,.o, $(drv_tapi_SOURCES))"
+
+ drv_tapi.ko: $(drv_tapi_SOURCES) $(EXTRA_DIST)
+- @echo -e "Making Linux 2.6.x kernel object"
++ @echo "Making Linux 2.6.x kernel object"
+ @for f in $(drv_tapi_SOURCES) ; do \
+ if test ! -e $(PWD)/$$f; then \
+ echo " LN $$f" ; \
+@@ -162,10 +162,10 @@ drv_tapi.ko: $(drv_tapi_SOURCES) $(EXTRA
+ ln -s @abs_srcdir@/$$f $(PWD)/$$f; \
+ fi; \
+ done;
+- @echo -e "# drv_tapi: Generated to build Linux 2.6.x kernel object" > $(PWD)/Kbuild
+- @echo -e "obj-m := $(subst .ko,.o,$@)" >> $(PWD)/Kbuild
+- @echo -e "$(subst .ko,,$@)-y := $(drv_tapi_OBJS)" >> $(PWD)/Kbuild
+- @echo -e "EXTRA_CFLAGS := -DHAVE_CONFIG_H $(CFLAGS) $(drv_tapi_CFLAGS) $(INCLUDES)" >> $(PWD)/Kbuild
++ @echo "# drv_tapi: Generated to build Linux 2.6.x kernel object" > $(PWD)/Kbuild
++ @echo "obj-m := $(subst .ko,.o,$@)" >> $(PWD)/Kbuild
++ @echo "$(subst .ko,,$@)-y := $(drv_tapi_OBJS)" >> $(PWD)/Kbuild
++ @echo "EXTRA_CFLAGS := -DHAVE_CONFIG_H $(CFLAGS) $(drv_tapi_CFLAGS) $(INCLUDES)" >> $(PWD)/Kbuild
+ $(MAKE) ARCH=@KERNEL_ARCH@ -C @KERNEL_BUILD_PATH@ O=@KERNEL_BUILD_PATH@ M=$(PWD) modules
+
+ clean-generic:
+--- a/configure.in
++++ b/configure.in
+@@ -128,7 +128,7 @@ dnl Set kernel build path
+ AC_ARG_ENABLE(kernelbuild,
+ AS_HELP_STRING(--enable-kernelbuild=x,Set the target kernel build path),
+ [
+- if test -r $enableval/include/linux/autoconf.h; then
++ if test -e $enableval/include/linux/autoconf.h -o -e $enableval/include/generated/autoconf.h; then
+ AC_SUBST([KERNEL_BUILD_PATH],[$enableval])
+ else
+ AC_MSG_ERROR([The kernel build directory is not valid or not configured!])
+--- a/src/drv_tapi_linux.h
++++ b/src/drv_tapi_linux.h
+@@ -24,6 +24,7 @@
+ #include <linux/version.h>
+ #include <linux/interrupt.h> /* in_interrupt() */
+ #include <linux/delay.h> /* mdelay - udelay */
++#include <linux/workqueue.h> /* work_struct */
+ #include <asm/poll.h> /* POLLIN, POLLOUT */
+
+ #include "ifx_types.h" /* ifx type definitions */
+--- a/src/drv_tapi_linux.c
++++ b/src/drv_tapi_linux.c
+@@ -47,6 +47,7 @@
+ #include <linux/errno.h>
+ #include <asm/uaccess.h> /* copy_from_user(), ... */
+ #include <asm/byteorder.h>
++#include <linux/smp_lock.h> /* lock_kernel() */
+ #include <asm/io.h>
+
+ #ifdef LINUX_2_6
+@@ -55,7 +56,11 @@
+ #include <linux/sched.h>
+ #undef CONFIG_DEVFS_FS
+ #ifndef UTS_RELEASE
+- #include "linux/utsrelease.h"
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
++# include <linux/utsrelease.h>
++#else
++# include <generated/utsrelease.h>
++#endif
+ #endif /* UTC_RELEASE */
+ #else
+ #include <linux/tqueue.h>
+@@ -3718,7 +3723,11 @@ IFX_void_t TAPI_OS_ThreadKill(IFXOS_Thre
+ flag and released after the down() call. */
+ lock_kernel();
+ mb();
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
+ kill_proc(pThrCntrl->tid, SIGKILL, 1);
++#else
++ kill_pid(find_vpid(pThrCntrl->tid), SIGKILL, 1);
++#endif
+ /* release the big kernel lock */
+ unlock_kernel();
+ wait_for_completion (&pThrCntrl->thrCompletion);
diff --git a/package/kernel/lantiq/ltq-tapi/patches/100-ifxmips.patch b/package/kernel/lantiq/ltq-tapi/patches/100-ifxmips.patch
new file mode 100644
index 0000000000..a9c0d8116b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-tapi/patches/100-ifxmips.patch
@@ -0,0 +1,96 @@
+--- a/src/drv_tapi_linux.c
++++ b/src/drv_tapi_linux.c
+@@ -552,7 +552,7 @@ static ssize_t ifx_tapi_write (struct fi
+ IFX_uint8_t *pData;
+ IFX_size_t buf_size;
+ #endif /* TAPI_PACKET */
+- IFX_ssize_t size = 0;
++ ssize_t size = 0;
+
+ #ifdef TAPI_PACKET
+ if (pTapiDev->bInitialized == IFX_FALSE)
+--- a/src/drv_tapi_osmap.h
++++ b/src/drv_tapi_osmap.h
+@@ -17,39 +17,6 @@
+ */
+
+ #include "ifx_types.h" /* ifx type definitions */
+-
+-#ifndef HAVE_IFX_ULONG_T
+- #warning please update your ifx_types.h, using local definition of IFX_ulong_t
+- /* unsigned long type - valid for 32bit systems only */
+- typedef unsigned long IFX_ulong_t;
+- #define HAVE_IFX_ULONG_T
+-#endif /* HAVE_IFX_ULONG_T */
+-
+-#ifndef HAVE_IFX_LONG_T
+- #warning please update your ifx_types.h, using local definition of IFX_long_t
+- /* long type - valid for 32bit systems only */
+- typedef long IFX_long_t;
+- #define HAVE_IFX_LONG_T
+-#endif /* HAVE_IFX_LONG_T */
+-
+-#ifndef HAVE_IFX_INTPTR_T
+- #warning please update your ifx_types.h, using local definition of IFX_intptr_t
+- typedef IFX_long_t IFX_intptr_t;
+- #define HAVE_IFX_INTPTR_T
+-#endif /* HAVE_IFX_INTPTR_T */
+-
+-#ifndef HAVE_IFX_SIZE_T
+- #warning please update your ifx_types.h, using local definition of IFX_size_t
+- typedef IFX_ulong_t IFX_size_t;
+- #define HAVE_IFX_SIZE_T
+-#endif /* HAVE_IFX_SIZE_T */
+-
+-#ifndef HAVE_IFX_SSIZE_T
+- #warning please update your ifx_types.h, using local definition of IFX_ssize_t
+- typedef IFX_long_t IFX_ssize_t;
+- #define HAVE_IFX_SSIZE_T
+-#endif /* HAVE_IFX_SSIZE_T */
+-
+ #include "ifxos_interrupt.h"
+ #include "ifxos_memory_alloc.h"
+ #include "ifxos_copy_user_space.h"
+--- a/include/drv_tapi_ll_interface.h
++++ b/include/drv_tapi_ll_interface.h
+@@ -40,13 +40,6 @@
+ #include "ifxos_select.h"
+ #endif /* TAPI_PACKET */
+
+-#ifndef HAVE_IFX_ULONG_T
+- #warning please update your ifx_types.h, using local definition of IFX_ulong_t
+- /* unsigned long type - valid for 32bit systems only */
+- typedef unsigned long IFX_ulong_t;
+- #define HAVE_IFX_ULONG_T
+-#endif /* HAVE_IFX_ULONG_T */
+-
+ /* ============================= */
+ /* Local Macros Definitions */
+ /* ============================= */
+--- a/src/lib/lib_bufferpool/lib_bufferpool.c
++++ b/src/lib/lib_bufferpool/lib_bufferpool.c
+@@ -85,24 +85,6 @@
+ #include <stdlib.h>
+ #endif /*VXWORKS*/
+
+-
+-/* ============================= */
+-/* Extra type definitions */
+-/* ============================= */
+-#ifndef HAVE_IFX_ULONG_T
+- #warning please update your ifx_types.h, using local definition of IFX_ulong_t
+- /* unsigned long type - valid for 32bit systems only */
+- typedef unsigned long IFX_ulong_t;
+- #define HAVE_IFX_ULONG_T
+-#endif /* HAVE_IFX_ULONG_T */
+-
+-#ifndef HAVE_IFX_UINTPTR_T
+- #warning please update your ifx_types.h, using local definition of IFX_uintptr_t
+- typedef IFX_ulong_t IFX_uintptr_t;
+- #define HAVE_IFX_UINTPTR_T
+-#endif /* HAVE_IFX_UINTPTR_T */
+-
+-
+ /* ============================= */
+ /* Local Macros & Definitions */
+ /* ============================= */
diff --git a/package/kernel/lantiq/ltq-tapi/patches/200-linux-37.patch b/package/kernel/lantiq/ltq-tapi/patches/200-linux-37.patch
new file mode 100644
index 0000000000..9d7428df03
--- /dev/null
+++ b/package/kernel/lantiq/ltq-tapi/patches/200-linux-37.patch
@@ -0,0 +1,108 @@
+--- a/src/drv_tapi_linux.c
++++ b/src/drv_tapi_linux.c
+@@ -47,7 +47,9 @@
+ #include <linux/errno.h>
+ #include <asm/uaccess.h> /* copy_from_user(), ... */
+ #include <asm/byteorder.h>
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
+ #include <linux/smp_lock.h> /* lock_kernel() */
++#endif
+ #include <asm/io.h>
+
+ #ifdef LINUX_2_6
+@@ -65,7 +67,9 @@
+ #else
+ #include <linux/tqueue.h>
+ #include <linux/sched.h>
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
+ #include <linux/smp_lock.h> /* lock_kernel() */
++#endif
+ #endif /* LINUX_2_6 */
+
+ #include "drv_tapi.h"
+@@ -133,8 +137,13 @@
+ size_t count, loff_t * ppos);
+ static ssize_t ifx_tapi_read(struct file * filp, char *buf,
+ size_t length, loff_t * ppos);
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
+ static int ifx_tapi_ioctl(struct inode *inode, struct file *filp,
+ unsigned int nCmd, unsigned long nArgument);
++#else
++static long ifx_tapi_ioctl(struct file *filp,
++ unsigned int nCmd, unsigned long nArgument);
++#endif
+ static unsigned int ifx_tapi_poll (struct file *filp, poll_table *table);
+
+ #ifdef CONFIG_PROC_FS
+@@ -218,7 +227,11 @@
+ IFX_char_t *pRegDrvName = IFX_NULL;
+ IFX_int32_t ret = 0;
+
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
+ if (tapi_fops.ioctl == IFX_NULL)
++#else
++ if (tapi_fops.unlocked_ioctl == IFX_NULL)
++#endif
+ {
+ #ifdef MODULE
+ tapi_fops.owner = THIS_MODULE;
+@@ -226,7 +239,11 @@
+ tapi_fops.read = ifx_tapi_read;
+ tapi_fops.write = ifx_tapi_write;
+ tapi_fops.poll = ifx_tapi_poll;
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
+ tapi_fops.ioctl = ifx_tapi_ioctl;
++#else
++ tapi_fops.unlocked_ioctl = ifx_tapi_ioctl;
++#endif
+ tapi_fops.open = ifx_tapi_open;
+ tapi_fops.release = ifx_tapi_release;
+ }
+@@ -881,8 +898,13 @@
+ - 0 and positive values - success
+ - negative value - ioctl failed
+ */
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
+ static int ifx_tapi_ioctl(struct inode *inode, struct file *filp,
+ unsigned int nCmd, unsigned long nArg)
++#else
++static long ifx_tapi_ioctl(struct file *filp,
++ unsigned int nCmd, unsigned long nArg)
++#endif
+ {
+ TAPI_FD_PRIV_DATA_t *pTapiPriv;
+ IFX_TAPI_ioctlCtx_t ctx;
+@@ -3721,7 +3743,9 @@
+ kernel lock (lock_kernel()). The lock must be
+ grabbed before changing the terminate
+ flag and released after the down() call. */
+- lock_kernel();
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
++ lock_kernel();
++#endif
+ mb();
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
+ kill_proc(pThrCntrl->tid, SIGKILL, 1);
+@@ -3729,8 +3753,10 @@
+ kill_pid(find_vpid(pThrCntrl->tid), SIGKILL, 1);
+ #endif
+ /* release the big kernel lock */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+ unlock_kernel();
+- wait_for_completion (&pThrCntrl->thrCompletion);
++#endif
++ wait_for_completion (&pThrCntrl->thrCompletion);
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
+ /* Now we are sure the thread is in zombie state.
+--- a/src/lib/lib_fifo/lib_fifo.c
++++ b/src/lib/lib_fifo/lib_fifo.c
+@@ -41,7 +41,7 @@
+ #ifdef LINUX
+ /* if linux/slab.h is not available, use the precessor linux/malloc.h */
+ #include <linux/slab.h>
+-#elif VXWORKS
++#elif defined(VXWORKS)
+ #include <sys_drv_debug.h>
+ #endif /* LINUX */
+
diff --git a/package/kernel/lantiq/ltq-vdsl-app/Makefile b/package/kernel/lantiq/ltq-vdsl-app/Makefile
new file mode 100644
index 0000000000..3de29d5205
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-app/Makefile
@@ -0,0 +1,75 @@
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ltq-vdsl-app
+PKG_VERSION:=4.11.4
+PKG_RELEASE:=1
+PKG_BASE_NAME:=dsl_cpe_control_vrx
+PKG_SOURCE:=$(PKG_BASE_NAME)-$(PKG_VERSION).tar.gz
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/dsl_cpe_control-$(PKG_VERSION)
+
+PKG_BUILD_DEPENDS:=kmod-ltq-vdsl-vr9
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ltq-vdsl-app
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Lantiq VDSL userland tool
+ URL:=http://www.lantiq.com/
+ DEPENDS:=@TARGET_lantiq_xway +libpthread
+endef
+
+define Package/ltq-vdsl-app/description
+ Userland tool needed to control Lantiq VDSL CPE
+endef
+
+CONFIGURE_ARGS += \
+ --with-max-device="1" \
+ --with-lines-per-device="1" \
+ --with-channels-per-line="1" \
+ --enable-vrx \
+ --enable-driver-include="-I$(STAGING_DIR)/usr/include/drv_vdsl_cpe_api" \
+ --enable-device-driver-include="-I$(STAGING_DIR)/usr/include/vdsl/" \
+ --enable-add-appl-cflags="-DMAX_CLI_PIPES=2" \
+ --enable-ifxos \
+ --enable-ifxos-include="-I$(STAGING_DIR)/usr/include/ifxos" \
+ --enable-ifxos-library="-I$(STAGING_DIR)/usr/lib" \
+ --enable-dsl-ceoc \
+ --enable-dsl-pm-total \
+ --enable-dsl-pm-showtime \
+ --enable-dsl-pm-line-counters \
+ --enable-dsl-pm-line-failure-counters \
+ --enable-dsl-pm-datapath-counters \
+ --enable-dsl-pm-datapath-failure-counters \
+ --enable-deprecated \
+ --disable-soap-support \
+ --enable-dsl-bonding=no \
+ --disable-dti
+
+ifeq ($(CONFIG_IFX_CLI),y)
+CONFIGURE_ARGS += \
+ --enable-cli-support
+endif
+
+CONFIGURE_ARGS += --enable-model=full
+#CONFIGURE_ARGS += --enable-model=lite
+#CONFIGURE_ARGS += --enable-model=footprint
+#CONFIGURE_ARGS += --enable-model=typical
+#CONFIGURE_ARGS += --enable-model=debug
+
+define Package/ltq-vdsl-app/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/dsl_control $(1)/etc/init.d/
+
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dsl_cpe_control $(1)/sbin/vdsl_cpe_control
+ $(INSTALL_BIN) ./files/dsl_notify.sh $(1)/sbin
+endef
+
+$(eval $(call BuildPackage,ltq-vdsl-app))
diff --git a/package/kernel/lantiq/ltq-vdsl-app/files/dsl_control b/package/kernel/lantiq/ltq-vdsl-app/files/dsl_control
new file mode 100644
index 0000000000..0d7d32cb0b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-app/files/dsl_control
@@ -0,0 +1,311 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2012 OpenWrt.org
+
+START=99
+
+EXTRA_COMMANDS="status lucistat"
+EXTRA_HELP=" status Get DSL status information
+ lucistat Get status information if lua friendly format"
+
+SERVICE_DAEMONIZE=1
+SERVICE_WRITE_PID=1
+
+#
+# Basic functions to send CLI commands to the vdsl_cpe_control daemon
+#
+dsl_cmd() {
+ killall -0 vdsl_cpe_control && (
+ echo "$@" > /tmp/pipe/dsl_cpe0_cmd
+ cat /tmp/pipe/dsl_cpe0_ack
+ )
+}
+dsl_val() {
+ echo $(expr "$1" : '.*'$2'=\([-\.[:alnum:]]*\).*')
+}
+
+#
+# Simple divide by 10 routine to cope with one decimal place
+#
+dbt() {
+ local a=$(expr $1 / 10)
+ local b=$(expr $1 % 10)
+ echo "${a}.${b}"
+}
+#
+# Take a number and convert to k or meg
+#
+scale() {
+ local val=$1
+ local a
+ local b
+
+ if [ "$val" -gt 1000000 ]; then
+ a=$(expr $val / 1000)
+ b=$(expr $a % 1000)
+ a=$(expr $a / 1000)
+ printf "%d.%03d Mb" ${a} ${b}
+ elif [ "$val" -gt 1000 ]; then
+ a=$(expr $val / 1000)
+ printf "%d Kb" ${a}
+ else
+ echo "${val} b"
+ fi
+}
+
+#
+# Read the data rates for both directions
+#
+data_rates() {
+ local csg
+ local dru
+ local drd
+ local sdru
+ local sdrd
+
+ csg=$(dsl_cmd g997csg 0 1)
+ drd=$(dsl_val "$csg" ActualDataRate)
+
+ csg=$(dsl_cmd g997csg 0 0)
+ dru=$(dsl_val "$csg" ActualDataRate)
+
+ [ -z "$drd" ] && drd=0
+ [ -z "$dru" ] && dru=0
+
+ sdrd=$(scale $drd)
+ sdru=$(scale $dru)
+
+ if [ "$action" = "lucistat" ]; then
+ echo "dsl.data_rate_down=$drd"
+ echo "dsl.data_rate_up=$dru"
+ echo "dsl.data_rate_down_s=\"$sdrd\""
+ echo "dsl.data_rate_up_s=\"$sdru\""
+ else
+ echo "Data Rate: ${sdrd}/s / ${sdru}/s"
+ fi
+}
+
+#
+# Chipset
+#
+chipset() {
+ local vig
+ local cs
+ local csv
+
+ vig=$(dsl_cmd vig)
+ cs=$(dsl_val "$vig" DSL_ChipSetType)
+ csv=$(dsl_val "$vig" DSL_ChipSetHWVersion)
+
+ if [ "$action" = "lucistat" ]; then
+ echo "dsl.chipset=\"${cs} ${csv}\""
+ else
+ echo "Chipset: ${cs} ${csv}"
+ fi
+}
+
+#
+# Work out how long the line has been up
+#
+line_uptime() {
+ local ccsg
+ local et
+ local etr
+ local d
+ local h
+ local m
+ local s
+ local rc=""
+
+ ccsg=$(dsl_cmd pmccsg 0 0 0)
+ et=$(dsl_val "$ccsg" nElapsedTime)
+
+ [ -z "$et" ] && et=0
+
+ if [ "$action" = "lucistat" ]; then
+ echo "dsl.line_uptime=${et}"
+ return
+ fi
+
+ d=$(expr $et / 86400)
+ etr=$(expr $et % 86400)
+ h=$(expr $etr / 3600)
+ etr=$(expr $etr % 3600)
+ m=$(expr $etr / 60)
+ s=$(expr $etr % 60)
+
+
+ [ "${d}${h}${m}${s}" -ne 0 ] && rc="${s}s"
+ [ "${d}${h}${m}" -ne 0 ] && rc="${m}m ${rc}"
+ [ "${d}${h}" -ne 0 ] && rc="${h}h ${rc}"
+ [ "${d}" -ne 0 ] && rc="${d}d ${rc}"
+
+ [ -z "$rc" ] && rc="down"
+ echo "Line Uptime: ${rc}"
+}
+
+#
+# Get noise and attenuation figures
+#
+line_data() {
+ local lsg
+ local latnu
+ local latnd
+ local snru
+ local snrd
+
+ lsg=$(dsl_cmd g997lsg 1 1)
+ latnd=$(dsl_val "$lsg" LATN)
+ snrd=$(dsl_val "$lsg" SNR)
+
+ lsg=$(dsl_cmd g997lsg 0 1)
+ latnu=$(dsl_val "$lsg" LATN)
+ snru=$(dsl_val "$lsg" SNR)
+
+ [ -z "$latnd" ] && latnd=0
+ [ -z "$latnu" ] && latnu=0
+ [ -z "$snrd" ] && snrd=0
+ [ -z "$snru" ] && snru=0
+
+ latnd=$(dbt $latnd)
+ latnu=$(dbt $latnu)
+ snrd=$(dbt $snrd)
+ snru=$(dbt $snru)
+
+ if [ "$action" = "lucistat" ]; then
+ echo "dsl.line_attenuation_down=$latnd"
+ echo "dsl.line_attenuation_up=$latnu"
+ echo "dsl.noise_margin_down=$snrd"
+ echo "dsl.noise_margin_up=$snru"
+ else
+ echo "Line Attenuation: ${latnd}dB / ${latnu}dB"
+ echo "Noise Margin: ${snrd}dB / ${snru}dB"
+ fi
+}
+
+#
+# Is the line up? Or what state is it in?
+#
+line_state() {
+ local lsg=$(dsl_cmd lsg)
+ local ls=$(dsl_val "$lsg" nLineState);
+ local s;
+
+ case "$ls" in
+ "0x0") s="not initialized" ;;
+ "0x1") s="exception" ;;
+ "0x10") s="not updated" ;;
+ "0xff") s="idle request" ;;
+ "0x100") s="idle" ;;
+ "0x1ff") s="silent request" ;;
+ "0x200") s="silent" ;;
+ "0x300") s="handshake" ;;
+ "0x380") s="full_init" ;;
+ "0x400") s="discovery" ;;
+ "0x500") s="training" ;;
+ "0x600") s="analysis" ;;
+ "0x700") s="exchange" ;;
+ "0x800") s="showtime_no_sync" ;;
+ "0x801") s="showtime_tc_sync" ;;
+ "0x900") s="fastretrain" ;;
+ "0xa00") s="lowpower_l2" ;;
+ "0xb00") s="loopdiagnostic active" ;;
+ "0xb10") s="loopdiagnostic data exchange" ;;
+ "0xb20") s="loopdiagnostic data request" ;;
+ "0xc00") s="loopdiagnostic complete" ;;
+ "0x1000000") s="test" ;;
+ "0xd00") s="resync" ;;
+ "0x3c0") s="short init entry" ;;
+ "") s="not running daemon"; ls="0xfff" ;;
+ *) s="unknown" ;;
+ esac
+
+ if [ $action = "lucistat" ]; then
+ echo "dsl.line_state_num=$ls"
+ echo "dsl.line_state_detail=\"$s\""
+ if [ "$ls" = "0x801" ]; then
+ echo "dsl.line_state=\"UP\""
+ else
+ echo "dsl.line_state=\"DOWN\""
+ fi
+ else
+ if [ "$ls" = "0x801" ]; then
+ echo "Line State: UP [$ls: $s]"
+ else
+ echo "Line State: DOWN [$ls: $s]"
+ fi
+ fi
+}
+
+#
+# Main status routine
+#
+status() {
+ chipset
+ line_state
+ data_rates
+ line_data
+ line_uptime
+}
+
+#
+# Luci (lua) compatible version that's easy to parse
+#
+lucistat() {
+ echo "local dsl={}"
+ status
+ echo "return dsl"
+}
+
+
+annex_b=10_00_10_00_00_04_00_00
+annex_bdmt=10_00_00_00_00_00_00_00
+annex_b2=00_00_10_00_00_00_00_00
+annex_b2p=00_00_00_00_00_04_00_00
+annex_a=04_01_04_00_00_01_00_00
+annex_at1=01_00_00_00_00_00_00_00
+annex_alite=00_01_00_00_00_00_00_00
+annex_admt=04_00_00_00_00_00_00_00
+annex_a2=00_00_04_00_00_00_00_00
+annex_a2p=00_00_00_00_00_01_00_00
+annex_l=00_00_00_00_04_00_00_00
+annex_m=00_00_00_00_40_00_04_00
+annex_m2=00_00_00_00_40_00_00_00
+annex_m2p=00_00_00_00_00_00_04_00
+
+#
+# Simple start routine
+#
+start() {
+ local annex
+ local firmware
+ local xtu
+ config_load network
+ config_get annex wan annex
+ config_get firmware wan firmware
+
+ # get xtu
+ eval "xtu=\"\${annex_$annex}\""
+
+ # check for firmware
+ [ -z "${firmware}" ] &&
+ firmware=vdsl.bin
+
+ # start CPE dsl daemon in the background
+ service_start /sbin/vdsl_cpe_control -i${xtu} \
+ -n /sbin/dsl_notify.sh \
+ -f /lib/firmware/${firmware}
+}
+
+#
+# For stop we want to simulate the notification call for when
+# the line goes down, so that we can stop the ppp link before
+# we die.
+#
+stop() {
+ DSL_NOTIFICATION_TYPE="DSL_INTERFACE_STATUS" \
+ DSL_INTERFACE_STATUS="DOWN" \
+ /sbin/dsl_notify.sh
+
+ service_stop /sbin/vdsl_cpe_control
+}
+
diff --git a/package/kernel/lantiq/ltq-vdsl-app/files/dsl_notify.sh b/package/kernel/lantiq/ltq-vdsl-app/files/dsl_notify.sh
new file mode 100644
index 0000000000..5e9f3964e8
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-app/files/dsl_notify.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# This script is called by dsl_cpe_control whenever there is a DSL event,
+# we only actually care about the DSL_INTERFACE_STATUS events as these
+# tell us the line has either come up or gone down.
+#
+# The rest of the code is basically the same at the atm hotplug code
+#
+
+[ "$DSL_NOTIFICATION_TYPE" = "DSL_INTERFACE_STATUS" ] || exit 0
+
+. /lib/functions.sh
+
+include /lib/network
+scan_interfaces
+
+local found=0
+local ifc
+for ifc in $interfaces; do
+ local up
+ config_get_bool up "$ifc" up 0
+
+ local auto
+ config_get_bool auto "$ifc" auto 1
+
+ local proto
+ config_get proto "$ifc" proto
+
+ if [ "$DSL_INTERFACE_STATUS" = "UP" ]; then
+ if [ "$proto" = "pppoa" ] && [ "$up" != 1 ] && [ "$auto" = 1 ]; then
+ found=1
+ ( sleep 1; ifup "$ifc" ) &
+ fi
+ else
+ if [ "$proto" = "pppoa" ] && [ "$up" = 1 ] && [ "$auto" = 1 ]; then
+ found=1
+ ( sleep 1; ifdown "$ifc" ) &
+ fi
+ fi
+done
+
+if [ "$found" != 1 ]; then
+ logger "Found no matching interface for DSL notification ($DSL_INTERFACE_STATUS)"
+fi
diff --git a/package/kernel/lantiq/ltq-vdsl-app/patches/100-compat.patch b/package/kernel/lantiq/ltq-vdsl-app/patches/100-compat.patch
new file mode 100644
index 0000000000..da56232437
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-app/patches/100-compat.patch
@@ -0,0 +1,26 @@
+Index: dsl_cpe_control-4.11.4/src/dsl_cpe_init_cfg.c
+===================================================================
+--- dsl_cpe_control-4.11.4.orig/src/dsl_cpe_init_cfg.c 2011-10-26 00:35:26.000000000 +0200
++++ dsl_cpe_control-4.11.4/src/dsl_cpe_init_cfg.c 2012-11-28 15:53:10.857692092 +0100
+@@ -43,7 +43,7 @@
+ {
+ DSL_CPE_LL_CFG_SET(-1, -1, DSL_DEV_HS_TONE_GROUP_VDSL2_B43, \
+ DSL_DEV_HS_TONE_GROUP_VDSL2_B43, DSL_DEV_HS_TONE_GROUP_VDSL2_B43, \
+- 0x1E116000, 0x37, -1),
++ 0x1E116000, 0x3f, -1),
+ #endif
+
+ #if defined(INCLUDE_DSL_CPE_API_VINAX)
+Index: dsl_cpe_control-4.11.4/src/dsl_cpe_control.c
+===================================================================
+--- dsl_cpe_control-4.11.4.orig/src/dsl_cpe_control.c 2012-01-13 15:15:34.000000000 +0100
++++ dsl_cpe_control-4.11.4/src/dsl_cpe_control.c 2012-11-28 15:53:23.465692408 +0100
+@@ -6432,7 +6432,7 @@
+ for (nDevice = 0; nDevice < DSL_CPE_MAX_DEVICE_NUMBER; nDevice++)
+ {
+ #if defined(INCLUDE_DSL_CPE_API_VINAX) || defined(INCLUDE_DSL_CPE_API_VRX)
+- sprintf (device, "%s/%d", DSL_CPE_DEVICE_NAME, nDevice);
++ sprintf (device, "%s%d", DSL_CPE_DEVICE_NAME, nDevice);
+ #else
+ sprintf (device, "%s", DSL_CPE_DEVICE_NAME);
+ #endif /* defined(INCLUDE_DSL_CPE_API_VINAX) || defined(INCLUDE_DSL_CPE_API_VRX)*/
diff --git a/package/kernel/lantiq/ltq-vdsl-fw/Makefile b/package/kernel/lantiq/ltq-vdsl-fw/Makefile
new file mode 100644
index 0000000000..d4e0023bc1
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-fw/Makefile
@@ -0,0 +1,40 @@
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ltq-vdsl-fw
+PKG_VERSION:=1
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ltq-vdsl-vr9-fw-installer
+ TITLE:=Firmware installer
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=@TARGET_lantiq_xway +kmod-ltq-vdsl-vr9
+endef
+
+define Build/Prepare
+ $(INSTALL_DIR) $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)
+endef
+
+define Build/Compile
+ $(TARGET_CONFIGURE_OPTS) \
+ CFLAGS="$(TARGET_CFLAGS)" \
+ LDFLAGS="$(TARGET_LDFLAGS)" \
+ $(MAKE) -C $(PKG_BUILD_DIR)
+endef
+
+define Package/ltq-vdsl-vr9-fw-installer/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(CP) $(PKG_BUILD_DIR)/w921v_fw_cutter $(PKG_BUILD_DIR)/vdsl_fw_install.sh $(1)/sbin/
+endef
+
+$(eval $(call BuildPackage,ltq-vdsl-vr9-fw-installer))
diff --git a/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaDecode.c b/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaDecode.c
new file mode 100644
index 0000000000..cb8345377e
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaDecode.c
@@ -0,0 +1,584 @@
+/*
+ LzmaDecode.c
+ LZMA Decoder (optimized for Speed version)
+
+ LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this Code, expressly permits you to
+ statically or dynamically link your Code (or bind by name) to the
+ interfaces of this file without subjecting your linked Code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaDecode.h"
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+ { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#ifdef _LZMA_IN_CB
+
+#define RC_TEST { if (Buffer == BufferLim) \
+ { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
+ BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
+
+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
+
+#else
+
+#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+
+#endif
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+ { UpdateBit0(p); mi <<= 1; A0; } else \
+ { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
+
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+ { int i = numLevels; res = 1; \
+ do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+ res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+ unsigned char prop0;
+ if (size < LZMA_PROPERTIES_SIZE)
+ return LZMA_RESULT_DATA_ERROR;
+ prop0 = propsData[0];
+ if (prop0 >= (9 * 5 * 5))
+ return LZMA_RESULT_DATA_ERROR;
+ {
+ for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+ for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+ propsRes->lc = prop0;
+ /*
+ unsigned char remainder = (unsigned char)(prop0 / 9);
+ propsRes->lc = prop0 % 9;
+ propsRes->pb = remainder / 5;
+ propsRes->lp = remainder % 5;
+ */
+ }
+
+ #ifdef _LZMA_OUT_READ
+ {
+ int i;
+ propsRes->DictionarySize = 0;
+ for (i = 0; i < 4; i++)
+ propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+ if (propsRes->DictionarySize == 0)
+ propsRes->DictionarySize = 1;
+ }
+ #endif
+ return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *InCallback,
+ #else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ #endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+ CProb *p = vs->Probs;
+ SizeT nowPos = 0;
+ Byte previousByte = 0;
+ UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+ UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+ int lc = vs->Properties.lc;
+
+ #ifdef _LZMA_OUT_READ
+
+ UInt32 Range = vs->Range;
+ UInt32 Code = vs->Code;
+ #ifdef _LZMA_IN_CB
+ const Byte *Buffer = vs->Buffer;
+ const Byte *BufferLim = vs->BufferLim;
+ #else
+ const Byte *Buffer = inStream;
+ const Byte *BufferLim = inStream + inSize;
+ #endif
+ int state = vs->State;
+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+ int len = vs->RemainLen;
+ UInt32 globalPos = vs->GlobalPos;
+ UInt32 distanceLimit = vs->DistanceLimit;
+
+ Byte *dictionary = vs->Dictionary;
+ UInt32 dictionarySize = vs->Properties.DictionarySize;
+ UInt32 dictionaryPos = vs->DictionaryPos;
+
+ Byte tempDictionary[4];
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+ if (len == kLzmaStreamWasFinishedId)
+ return LZMA_RESULT_OK;
+
+ if (dictionarySize == 0)
+ {
+ dictionary = tempDictionary;
+ dictionarySize = 1;
+ tempDictionary[0] = vs->TempDictionary[0];
+ }
+
+ if (len == kLzmaNeedInitId)
+ {
+ {
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ UInt32 i;
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ rep0 = rep1 = rep2 = rep3 = 1;
+ state = 0;
+ globalPos = 0;
+ distanceLimit = 0;
+ dictionaryPos = 0;
+ dictionary[dictionarySize - 1] = 0;
+ #ifdef _LZMA_IN_CB
+ RC_INIT;
+ #else
+ RC_INIT(inStream, inSize);
+ #endif
+ }
+ len = 0;
+ }
+ while(len != 0 && nowPos < outSize)
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ len--;
+ }
+ if (dictionaryPos == 0)
+ previousByte = dictionary[dictionarySize - 1];
+ else
+ previousByte = dictionary[dictionaryPos - 1];
+
+ #else /* if !_LZMA_OUT_READ */
+
+ int state = 0;
+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+ int len = 0;
+ const Byte *Buffer;
+ const Byte *BufferLim;
+ UInt32 Range;
+ UInt32 Code;
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+
+ {
+ UInt32 i;
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ }
+
+ #ifdef _LZMA_IN_CB
+ RC_INIT;
+ #else
+ RC_INIT(inStream, inSize);
+ #endif
+
+ #endif /* _LZMA_OUT_READ */
+
+ while(nowPos < outSize)
+ {
+ CProb *prob;
+ UInt32 bound;
+ int posState = (int)(
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & posStateMask);
+
+ prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ int symbol = 1;
+ UpdateBit0(prob)
+ prob = p + Literal + (LZMA_LIT_SIZE *
+ (((
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+ if (state >= kNumLitStates)
+ {
+ int matchByte;
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ matchByte = dictionary[pos];
+ #else
+ matchByte = outStream[nowPos - rep0];
+ #endif
+ do
+ {
+ int bit;
+ CProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & 0x100);
+ probLit = prob + 0x100 + bit + symbol;
+ RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+ }
+ while (symbol < 0x100);
+ }
+ while (symbol < 0x100)
+ {
+ CProb *probLit = prob + symbol;
+ RC_GET_BIT(probLit, symbol)
+ }
+ previousByte = (Byte)symbol;
+
+ outStream[nowPos++] = previousByte;
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #endif
+ if (state < 4) state = 0;
+ else if (state < 10) state -= 3;
+ else state -= 6;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRep + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ state = state < kNumLitStates ? 0 : 3;
+ prob = p + LenCoder;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG0 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos;
+ #endif
+ UpdateBit0(prob);
+
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit == 0)
+ #else
+ if (nowPos == 0)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ state = state < kNumLitStates ? 9 : 11;
+ #ifdef _LZMA_OUT_READ
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ outStream[nowPos++] = previousByte;
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+ #endif
+
+ continue;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ UpdateBit1(prob);
+ prob = p + IsRepG1 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep1;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG2 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep2;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ state = state < kNumLitStates ? 8 : 11;
+ prob = p + RepLenCoder;
+ }
+ {
+ int numBits, offset;
+ CProb *probLen = prob + LenChoice;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ numBits = kLenNumLowBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenChoice2;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ numBits = kLenNumMidBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ numBits = kLenNumHighBits;
+ }
+ }
+ RangeDecoderBitTreeDecode(probLen, numBits, len);
+ len += offset;
+ }
+
+ if (state < 4)
+ {
+ int posSlot;
+ state += kNumLitStates;
+ prob = p + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits);
+ RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+ rep0 = (2 | ((UInt32)posSlot & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
+ rep0 <<= numDirectBits;
+ prob = p + SpecPos + rep0 - posSlot - 1;
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ RC_NORMALIZE
+ Range >>= 1;
+ rep0 <<= 1;
+ if (Code >= Range)
+ {
+ Code -= Range;
+ rep0 |= 1;
+ }
+ }
+ while (--numDirectBits != 0);
+ prob = p + Align;
+ rep0 <<= kNumAlignBits;
+ numDirectBits = kNumAlignBits;
+ }
+ {
+ int i = 1;
+ int mi = 1;
+ do
+ {
+ CProb *prob3 = prob + mi;
+ RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+ i <<= 1;
+ }
+ while(--numDirectBits != 0);
+ }
+ }
+ else
+ rep0 = posSlot;
+ if (++rep0 == (UInt32)(0))
+ {
+ /* it's for stream version */
+ len = kLzmaStreamWasFinishedId;
+ break;
+ }
+ }
+
+ len += kMatchMinLen;
+ #ifdef _LZMA_OUT_READ
+ if (rep0 > distanceLimit)
+ #else
+ if (rep0 > nowPos)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ #ifdef _LZMA_OUT_READ
+ if (dictionarySize - distanceLimit > (UInt32)len)
+ distanceLimit += len;
+ else
+ distanceLimit = dictionarySize;
+ #endif
+
+ do
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ len--;
+ outStream[nowPos++] = previousByte;
+ }
+ while(len != 0 && nowPos < outSize);
+ }
+ }
+ RC_NORMALIZE;
+
+ #ifdef _LZMA_OUT_READ
+ vs->Range = Range;
+ vs->Code = Code;
+ vs->DictionaryPos = dictionaryPos;
+ vs->GlobalPos = globalPos + (UInt32)nowPos;
+ vs->DistanceLimit = distanceLimit;
+ vs->Reps[0] = rep0;
+ vs->Reps[1] = rep1;
+ vs->Reps[2] = rep2;
+ vs->Reps[3] = rep3;
+ vs->State = state;
+ vs->RemainLen = len;
+ vs->TempDictionary[0] = tempDictionary[0];
+ #endif
+
+ #ifdef _LZMA_IN_CB
+ vs->Buffer = Buffer;
+ vs->BufferLim = BufferLim;
+ #else
+ *inSizeProcessed = (SizeT)(Buffer - inStream);
+ #endif
+ *outSizeProcessed = nowPos;
+ return LZMA_RESULT_OK;
+}
diff --git a/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaDecode.h b/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaDecode.h
new file mode 100644
index 0000000000..2870eeb9c9
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaDecode.h
@@ -0,0 +1,113 @@
+/*
+ LzmaDecode.h
+ LZMA Decoder interface
+
+ LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this code, expressly permits you to
+ statically or dynamically link your code (or bind by name) to the
+ interfaces of this file without subjecting your linked code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+#include "LzmaTypes.h"
+
+/* #define _LZMA_IN_CB */
+/* Use callback for input data */
+
+/* #define _LZMA_OUT_READ */
+/* Use read function for output data */
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs,
+ but memory usage will be doubled in that case */
+
+/* #define _LZMA_LOC_OPT */
+/* Enable local speed optimizations inside code */
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#ifdef _LZMA_IN_CB
+typedef struct _ILzmaInCallback
+{
+ int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
+} ILzmaInCallback;
+#endif
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+ int lc;
+ int lp;
+ int pb;
+ #ifdef _LZMA_OUT_READ
+ UInt32 DictionarySize;
+ #endif
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+ CLzmaProperties Properties;
+ CProb *Probs;
+
+ #ifdef _LZMA_IN_CB
+ const unsigned char *Buffer;
+ const unsigned char *BufferLim;
+ #endif
+
+ #ifdef _LZMA_OUT_READ
+ unsigned char *Dictionary;
+ UInt32 Range;
+ UInt32 Code;
+ UInt32 DictionaryPos;
+ UInt32 GlobalPos;
+ UInt32 DistanceLimit;
+ UInt32 Reps[4];
+ int State;
+ int RemainLen;
+ unsigned char TempDictionary[4];
+ #endif
+} CLzmaDecoderState;
+
+#ifdef _LZMA_OUT_READ
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
+#endif
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *inCallback,
+ #else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ #endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+
+#endif
diff --git a/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaTypes.h b/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaTypes.h
new file mode 100644
index 0000000000..9c27290757
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaTypes.h
@@ -0,0 +1,45 @@
+/*
+LzmaTypes.h
+
+Types for LZMA Decoder
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.40 (2006-05-01)
+*/
+
+#ifndef __LZMATYPES_H
+#define __LZMATYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif
+
+/* #define _LZMA_NO_SYSTEM_SIZE_T */
+/* You can use it, if you don't want <stddef.h> */
+
+#ifndef _7ZIP_SIZET_DEFINED
+#define _7ZIP_SIZET_DEFINED
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+#include <stddef.h>
+typedef size_t SizeT;
+#endif
+#endif
+
+#endif
diff --git a/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaWrapper.c b/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaWrapper.c
new file mode 100644
index 0000000000..7dce05666c
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaWrapper.c
@@ -0,0 +1,206 @@
+/******************************************************************************
+**
+** FILE NAME : LzmaWrapper.c
+** PROJECT : bootloader
+** MODULES : U-boot
+**
+** DATE : 2 Nov 2006
+** AUTHOR : Lin Mars
+** DESCRIPTION : LZMA decoder support for U-boot 1.1.5
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 2 Nov 2006 Lin Mars init version which derived from LzmaTest.c from
+** LZMA v4.43 SDK
+** 24 May 2007 Lin Mars Fix issue for multiple lzma_inflate involved
+*******************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "LzmaDecode.h"
+#include "LzmaWrapper.h"
+
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+static const char *kCantReadMessage = "Can not read from source buffer";
+static const char *kCantAllocateMessage = "Not enough buffer for decompression";
+#endif
+
+static size_t rpos=0, dpos=0;
+
+static int MyReadFileAndCheck(unsigned char *src, void *dest, size_t size)
+{
+ if (size == 0)
+ return 0;
+ memcpy(dest, src + rpos, size);
+ rpos += size;
+ return 1;
+}
+
+int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len)
+{
+ /* We use two 32-bit integers to construct 64-bit integer for file size.
+ You can remove outSizeHigh, if you don't need >= 4GB supporting,
+ or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
+ UInt32 outSize = 0;
+ UInt32 outSizeHigh = 0;
+ SizeT outSizeFull;
+ unsigned char *outStream;
+
+ int waitEOS = 1;
+ /* waitEOS = 1, if there is no uncompressed size in headers,
+ so decoder will wait EOS (End of Stream Marker) in compressed stream */
+
+ SizeT compressedSize;
+ unsigned char *inStream;
+
+ CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
+ unsigned char properties[LZMA_PROPERTIES_SIZE];
+
+ int res;
+
+ rpos=0; dpos=0;
+
+ if (sizeof(UInt32) < 4)
+ {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+ printf("LZMA decoder needs correct UInt32\n");
+#endif
+ return LZMA_RESULT_DATA_ERROR;
+ }
+
+ {
+ long length=s_len;
+ if ((long)(SizeT)length != length)
+ {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+ printf("Too big compressed stream\n");
+#endif
+ return LZMA_RESULT_DATA_ERROR;
+ }
+ compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
+ }
+
+ /* Read LZMA properties for compressed stream */
+
+ if (!MyReadFileAndCheck(source, properties, sizeof(properties)))
+ {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+ printf("%s\n", kCantReadMessage);
+#endif
+ return LZMA_RESULT_DATA_ERROR;
+ }
+
+ /* Read uncompressed size */
+ {
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ unsigned char b;
+ if (!MyReadFileAndCheck(source, &b, 1))
+ {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+ printf("%s\n", kCantReadMessage);
+#endif
+ return LZMA_RESULT_DATA_ERROR;
+ }
+ if (b != 0xFF)
+ waitEOS = 0;
+ if (i < 4)
+ outSize += (UInt32)(b) << (i * 8);
+ else
+ outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
+ }
+
+ if (waitEOS)
+ {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+ printf("Stream with EOS marker is not supported");
+#endif
+ return LZMA_RESULT_DATA_ERROR;
+ }
+ outSizeFull = (SizeT)outSize;
+ if (sizeof(SizeT) >= 8)
+ outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
+ else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
+ {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+ printf("Too big uncompressed stream");
+#endif
+ return LZMA_RESULT_DATA_ERROR;
+ }
+ }
+
+ /* Decode LZMA properties and allocate memory */
+ if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+ {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+ printf("Incorrect stream properties");
+#endif
+ return LZMA_RESULT_DATA_ERROR;
+ }
+ state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+
+ if (outSizeFull == 0)
+ outStream = 0;
+ else
+ {
+ if (outSizeFull > d_len)
+ outStream = 0;
+ else
+ outStream = dest;
+ }
+
+ if (compressedSize == 0)
+ inStream = 0;
+ else
+ {
+ if ((compressedSize+rpos) > s_len )
+ inStream = 0;
+ else
+ inStream = source + rpos;
+ }
+
+ if (state.Probs == 0
+ || (outStream == 0 && outSizeFull != 0)
+ || (inStream == 0 && compressedSize != 0)
+ )
+ {
+ free(state.Probs);
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+ printf("%s\n", kCantAllocateMessage);
+#endif
+ return LZMA_RESULT_DATA_ERROR;
+ }
+
+ /* Decompress */
+ {
+ SizeT inProcessed;
+ SizeT outProcessed;
+ res = LzmaDecode(&state,
+ inStream, compressedSize, &inProcessed,
+ outStream, outSizeFull, &outProcessed);
+ if (res != 0)
+ {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+ printf("\nDecoding error = %d\n", res);
+#endif
+ res = 1;
+ }
+ else
+ {
+ *d_len = outProcessed;
+ }
+ }
+
+ free(state.Probs);
+ return res;
+}
diff --git a/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaWrapper.h b/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaWrapper.h
new file mode 100644
index 0000000000..2f9a3ffbbb
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-fw/src/LzmaWrapper.h
@@ -0,0 +1,36 @@
+/******************************************************************************
+**
+** FILE NAME : LzmaWrapper.h
+** PROJECT : bootloader
+** MODULES : U-boot
+**
+** DATE : 2 Nov 2006
+** AUTHOR : Lin Mars
+** DESCRIPTION : LZMA decoder support for U-boot 1.1.5
+** COPYRIGHT : Copyright (c) 2006
+** Infineon Technologies AG
+** Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+** This program is free software; 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.
+**
+** HISTORY
+** $Date $Author $Comment
+** 2 Nov 2006 Lin Mars init version which derived from LzmaTest.c from
+** LZMA v4.43 SDK
+*******************************************************************************/
+#ifndef __LZMA_WRAPPER_H__
+#define __LZMA_WRAPPER_H__
+
+#ifndef LZMA_RESULT_OK
+#define LZMA_RESULT_OK 0
+#endif
+#ifndef LZMA_RESULT_DATA_ERROR
+#define LZMA_RESULT_DATA_ERROR 1
+#endif
+
+extern int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len);
+
+#endif /*__LZMA_WRAPPER_H__*/
diff --git a/package/kernel/lantiq/ltq-vdsl-fw/src/Makefile b/package/kernel/lantiq/ltq-vdsl-fw/src/Makefile
new file mode 100644
index 0000000000..2d50aaf023
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-fw/src/Makefile
@@ -0,0 +1,13 @@
+PROG=w921v_fw_cutter
+OBJS=w921v_fw_cutter.c LzmaDecode.c LzmaWrapper.c
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
+
+clean:
+ rm *.o $(PROG)
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $^ -o $@
diff --git a/package/kernel/lantiq/ltq-vdsl-fw/src/vdsl_fw_install.sh b/package/kernel/lantiq/ltq-vdsl-fw/src/vdsl_fw_install.sh
new file mode 100755
index 0000000000..4d407567d4
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-fw/src/vdsl_fw_install.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+FW="/tmp/Firmware_Speedport_W921V_1.20.000.bin"
+URL="http://hilfe.telekom.de/dlp/eki/downloads/Speedport/Speedport%20W%20921V/Firmware_Speedport_W921V_1.20.000.bin"
+FW_TAPI="/tmp/vr9_tapi_fw.bin"
+FW_DSL="/tmp/vr9_dsl_fw_annex_b.bin"
+FW_TGZ="/tmp/vr9_fw.tgz"
+MD5_FW="4d812f2c3476dadd738b022c4767c491"
+MD5_TAPI="06b6ab3481b8d3eb7e8bf6131f7f6b7f"
+MD5_DSL="59dd9dc81195c6854433c691b163f757"
+
+[ -f /lib/firmware/vdsl.bin] && exit 0
+
+[ -z "$1" ] || URL=$1
+
+[ -f "${FW}" ] || {
+ echo "${FW} does not exist. Try to Download it ? (y/N)"
+ read -n 1 R
+ echo ""
+ [ "$R" = "y" ] || {
+ echo "Please manually download the firmware from ${URL} and copy the file to ${FW}"
+ exit 1
+ }
+ echo "Download w921v Firmware"
+ wget "${URL}" -O "${FW}"
+ [ $? -eq 0 -a -f "${FW}" ] || exit 1
+}
+
+F=`md5sum -b ${FW} | cut -d" " -f1`
+[ "$F" = "${MD5_FW}" ] || {
+ echo "Failed to verify Firmware MD5"
+ exit 1
+}
+
+echo "Unpack and decompress w921v Firmware"
+w921v_fw_cutter
+[ $? -eq 0 ] || exit 1
+
+T=`md5sum -b ${FW_TAPI} | cut -d" " -f1`
+D=`md5sum -b ${FW_DSL} | cut -d" " -f1`
+
+[ "$T" = "${MD5_TAPI}" -a "$D" = "${MD5_DSL}" ] || {
+ echo "Failed to verify MD5"
+ exit 1
+}
+
+cp ${FW_TAPI} ${FW_DSL} /lib/firmware/
+ln -s /lib/firmware/vr9_dsl_fw_annex_b.bin /lib/firmware/vdsl.bin
diff --git a/package/kernel/lantiq/ltq-vdsl-fw/src/w921v_fw_cutter.c b/package/kernel/lantiq/ltq-vdsl-fw/src/w921v_fw_cutter.c
new file mode 100644
index 0000000000..b26c91ec22
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-fw/src/w921v_fw_cutter.c
@@ -0,0 +1,164 @@
+/*
+ * This program is free software; 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.
+ *
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "LzmaWrapper.h"
+
+#define FW_NAME "/tmp/Firmware_Speedport_W921V_1.20.000.bin"
+
+#define MAGIC 0x50
+#define MAGIC_SZ 0x3FFC00
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define MAGIC_PART 0x12345678
+#define MAGIC_LZMA 0x8000005D
+#define MAGIC_ANNEX_B 0x3C
+#define MAGIC_TAPI 0x5A
+#else
+#define MAGIC_PART 0x78563412
+#define MAGIC_LZMA 0x5D000080
+#define MAGIC_ANNEX_B 0x3C000000
+#define MAGIC_TAPI 0x5A000000
+#endif
+
+
+const char* part_type(u_int32_t id)
+{
+ switch(id) {
+ case MAGIC_ANNEX_B:
+ return "/tmp/vr9_dsl_fw_annex_b.bin";
+ case MAGIC_TAPI:
+ return "/tmp/vr9_tapi_fw.bin";
+ }
+ printf("\tUnknown lzma type 0x%02X\n", id);
+ return "/tmp/unknown.lzma";
+}
+
+int main(int argc, char **argv)
+{
+ struct stat s;
+ u_int8_t *buf_orig;
+ u_int32_t *buf;
+ int buflen;
+ int fd;
+ int i;
+ int err;
+ int start = 0, end = 0;
+
+ printf("Arcadyan Firmware cutter v0.1\n");
+ printf("-----------------------------\n");
+ printf("This tool extracts the different parts of an arcadyan firmware update file\n");
+ printf("This tool is for private use only. The Firmware that gets extracted has a license that forbids redistribution\n");
+ printf("Please only run this if you understand the risks\n\n");
+ printf("I understand the risks ? (y/N)\n");
+
+ if (getchar() != 'y')
+ return -1;
+
+ if (stat(FW_NAME, &s) != 0) {
+ printf("Failed to find %s\n", FW_NAME);
+ printf("Ask Google or try http://hilfe.telekom.de/dlp/eki/downloads/Speedport/Speedport%20W%20921V/Firmware_Speedport_W921V_1.20.000.bin\n");
+ return -1;
+ }
+
+ buf_orig = malloc(s.st_size);
+ if (!buf_orig) {
+ printf("Failed to alloc %d bytes\n", s.st_size);
+ return -1;
+ }
+
+ fd = open(FW_NAME, O_RDONLY);
+ if (fd < 0) {
+ printf("Unable to open %s\n", FW_NAME);
+ return -1;
+ }
+
+ buflen = read(fd, buf_orig, s.st_size);
+ close(fd);
+ if (buflen != s.st_size) {
+ printf("Loaded %d instead of %d bytes inside %s\n", buflen, s.st_size, FW_NAME);
+ return -1;
+ }
+
+ /* <magic> */
+ buf_orig++;
+ buflen -= 1;
+ for (i = 0; i < MAGIC_SZ; i++) {
+ if ((i % 16) < 3)
+ buf_orig[i] = buf_orig[i + 16] ^ MAGIC;
+ else
+ buf_orig[i] = buf_orig[i] ^ MAGIC;
+ }
+ buflen -= 3;
+ memmove(&buf_orig[MAGIC_SZ], &buf_orig[MAGIC_SZ + 3], buflen - MAGIC_SZ);
+ /* </magic> */
+
+ buf = (u_int32_t*) buf_orig;
+
+ do {
+ if (buf[end] == MAGIC_PART) {
+ end += 2;
+ printf("Found partition at 0x%08X with size %d\n",
+ start * sizeof(u_int32_t),
+ (end - start) * sizeof(u_int32_t));
+ if (buf[start] == MAGIC_LZMA) {
+ int dest_len = 1024 * 1024;
+ int len = buf[end - 3];
+ u_int32_t id = buf[end - 6];
+ const char *type = part_type(id);
+ u_int8_t *dest;
+
+ dest = malloc(dest_len);
+ if (!dest) {
+ printf("Failed to alloc dest buffer\n");
+ return -1;
+ }
+
+ if (lzma_inflate((u_int8_t*)&buf[start], len, dest, &dest_len)) {
+ printf("Failed to decompress data\n");
+ return -1;
+ }
+
+ fd = creat(type, S_IRUSR | S_IWUSR);
+ if (fd != -1) {
+ if (write(fd, dest, dest_len) != dest_len)
+ printf("\tFailed to write %d bytes\n", dest_len);
+ else
+ printf("\tWrote %d bytes to %s\n", dest_len, type);
+ close(fd);
+ } else {
+ printf("\tFailed to open %s\n", type);
+ }
+ free(dest);
+ } else {
+ printf("\tThis is not lzma\n");
+ }
+ start = end;
+ } else {
+ end++;
+ }
+ } while(end < buflen / sizeof(u_int32_t));
+
+ return 0;
+}
diff --git a/package/kernel/lantiq/ltq-vdsl-mei/Makefile b/package/kernel/lantiq/ltq-vdsl-mei/Makefile
new file mode 100644
index 0000000000..8561573f7d
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-mei/Makefile
@@ -0,0 +1,60 @@
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ltq-vdsl-vr9-mei
+PKG_VERSION:=1.2.0
+PKG_RELEASE:=1
+
+PKG_BASE_NAME:=drv_mei_cpe
+PKG_SOURCE:=$(PKG_BASE_NAME)-$(PKG_VERSION).tar.gz
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_BASE_NAME)-$(PKG_VERSION)
+PKG_MD5SUM:=cf2fccc1bc72390b2aec46650abf2f20
+PKG_FIXUP:=autoreconf
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-vdsl-vr9-mei
+ TITLE:=mei driver for vdsl
+ SECTION:=sys
+ SUBMENU:=Network Devices
+ DEPENDS:=@TARGET_lantiq_xway +kmod-ltq-ifxos
+ FILES:=$(PKG_BUILD_DIR)/src/drv_mei_cpe.ko
+ AUTOLOAD:=$(call AutoLoad,50,drv_mei_cpe)
+endef
+
+define KernelPackage/ltq-vdsl-vr9-mei/description
+ Lantiq MEI CPE Kernel Module Driver
+endef
+
+#DEBUG=-DDEBUG_PRINT=1
+
+CONFIGURE_ARGS += \
+ --enable-kernelincl="$(LINUX_DIR)/include" \
+ --enable-device=vr9 \
+ --with-max-device=1 \
+ --with-lines-per-device=1 \
+ --enable-debug \
+ --enable-error_print \
+ --enable-ifxos-include="-I$(STAGING_DIR)/usr/include/ifxos/" \
+ --enable-ifxos-library="-L$(STAGING_DIR)/usr/lib" \
+ --enable-add_drv_cflags="$(DEBUG) -DMEI_DRV_ATM_PTM_INTERFACE_ENABLE=1 -fno-pic -mno-abicalls -mlong-calls -O2 -g0" \
+ --enable-linux-26 \
+ --enable-kernelbuild="$(LINUX_DIR)" \
+ ARCH=$(LINUX_KARCH)
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include/vdsl
+ $(CP) $(PKG_BUILD_DIR)/src/drv_mei_cpe_api_intern.h $(1)/usr/include/vdsl/
+ $(CP) $(PKG_BUILD_DIR)/src/drv_mei_cpe_api_atm_ptm_intern.h $(1)/usr/include/vdsl/
+ $(CP) $(PKG_BUILD_DIR)/src/drv_mei_cpe_interface.h $(1)/usr/include/vdsl
+ $(CP) $(PKG_BUILD_DIR)/src/drv_mei_cpe_config.h $(1)/usr/include/vdsl/
+ $(CP) $(PKG_BUILD_DIR)/src/cmv_message_format.h $(1)/usr/include/vdsl/
+endef
+
+$(eval $(call KernelPackage,ltq-vdsl-vr9-mei))
diff --git a/package/kernel/lantiq/ltq-vdsl-mei/patches/100-compat.patch b/package/kernel/lantiq/ltq-vdsl-mei/patches/100-compat.patch
new file mode 100644
index 0000000000..5822e74a75
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-mei/patches/100-compat.patch
@@ -0,0 +1,298 @@
+Index: drv_mei_cpe-1.2.0/src/drv_mei_cpe_common.c
+===================================================================
+--- drv_mei_cpe-1.2.0.orig/src/drv_mei_cpe_common.c 2011-10-26 00:49:51.000000000 +0200
++++ drv_mei_cpe-1.2.0/src/drv_mei_cpe_common.c 2012-11-28 15:14:10.421633418 +0100
+@@ -20,7 +20,6 @@
+ /* get at first the driver configuration */
+ #include "drv_mei_cpe_config.h"
+
+-#include "ifx_types.h"
+ #include "drv_mei_cpe_os.h"
+ #include "drv_mei_cpe_dbg.h"
+
+Index: drv_mei_cpe-1.2.0/configure.in
+===================================================================
+--- drv_mei_cpe-1.2.0.orig/configure.in 2012-01-20 17:41:07.000000000 +0100
++++ drv_mei_cpe-1.2.0/configure.in 2012-11-28 15:14:10.421633418 +0100
+@@ -140,7 +140,7 @@
+ AC_ARG_ENABLE(kernelbuild,
+ AC_HELP_STRING([--enable-kernelbuild=x],[Set the target kernel build path]),
+ [
+- if test -e $enableval/include/linux/autoconf.h; then
++ if test -e $enableval/include/generated/autoconf.h; then
+ AC_SUBST([KERNEL_BUILD_PATH],[$enableval])
+ else
+ AC_MSG_ERROR([The kernel build directory is not valid or not configured!])
+Index: drv_mei_cpe-1.2.0/configure
+===================================================================
+--- drv_mei_cpe-1.2.0.orig/configure 2012-01-20 17:50:02.000000000 +0100
++++ drv_mei_cpe-1.2.0/configure 2012-11-28 15:14:56.637634577 +0100
+@@ -617,6 +617,7 @@
+ am__fastdepCC_FALSE
+ am__fastdepCC_TRUE
+ CCDEPMODE
++am__nodep
+ AMDEPBACKSLASH
+ AMDEP_FALSE
+ AMDEP_TRUE
+@@ -2367,11 +2368,11 @@
+
+ # We need awk for the "check" target. The system "awk" is bad on
+ # some platforms.
+-# Always define AMTAR for backward compatibility.
++# Always define AMTAR for backward compatibility. Yes, it's still used
++# in the wild :-( We should find a proper way to deprecate it ...
++AMTAR='$${TAR-tar}'
+
+-AMTAR=${AMTAR-"${am_missing_run}tar"}
+-
+-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
++am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+@@ -3219,6 +3220,7 @@
+ if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
++ am__nodep='_no'
+ fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+@@ -3243,6 +3245,7 @@
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
++ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+@@ -3302,7 +3305,7 @@
+ break
+ fi
+ ;;
+- msvisualcpp | msvcmsys)
++ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+@@ -3656,7 +3659,7 @@
+ # Check whether --enable-kernelbuild was given.
+ if test "${enable_kernelbuild+set}" = set; then :
+ enableval=$enable_kernelbuild;
+- if test -e $enableval/include/linux/autoconf.h; then
++ if test -e $enableval/include/generated/autoconf.h; then
+ KERNEL_BUILD_PATH=$enableval
+
+ else
+Index: drv_mei_cpe-1.2.0/src/drv_mei_cpe_linux.h
+===================================================================
+--- drv_mei_cpe-1.2.0.orig/src/drv_mei_cpe_linux.h 2011-07-25 20:41:02.000000000 +0200
++++ drv_mei_cpe-1.2.0/src/drv_mei_cpe_linux.h 2012-11-28 15:14:10.429633419 +0100
+@@ -34,8 +34,6 @@
+ #include <linux/sched.h>
+ #include <linux/interrupt.h>
+
+-#include <asm/ifx/irq.h>
+-
+ #if (MEI_DRV_IFXOS_ENABLE == 0)
+
+ #include <linux/version.h>
+@@ -44,8 +42,6 @@
+ #include <linux/poll.h>
+ #include <linux/types.h>
+
+-#include <asm/ifx/ifx_types.h>
+-
+ #endif /* #if (MEI_DRV_IFXOS_ENABLE == 0)*/
+
+ /* ============================================================================
+Index: drv_mei_cpe-1.2.0/src/drv_mei_cpe_mei_vr9.h
+===================================================================
+--- drv_mei_cpe-1.2.0.orig/src/drv_mei_cpe_mei_vr9.h 2011-07-25 20:41:02.000000000 +0200
++++ drv_mei_cpe-1.2.0/src/drv_mei_cpe_mei_vr9.h 2012-11-28 15:14:10.429633419 +0100
+@@ -40,12 +40,6 @@
+ #endif
+ #endif
+
+-#ifdef LINUX
+- #include <asm/ifx/ifx_pmu.h>
+-#else
+- #error "Please check PMU driver path!"
+-#endif
+-
+ /* ============================================================================
+ Module : RCU register address and bits
+ ========================================================================= */
+Index: drv_mei_cpe-1.2.0/src/drv_mei_cpe_api_atm_ptm_intern.c
+===================================================================
+--- drv_mei_cpe-1.2.0.orig/src/drv_mei_cpe_api_atm_ptm_intern.c 2011-07-25 20:41:02.000000000 +0200
++++ drv_mei_cpe-1.2.0/src/drv_mei_cpe_api_atm_ptm_intern.c 2012-11-28 15:14:10.429633419 +0100
+@@ -25,11 +25,7 @@
+ #include "ifx_types.h"
+ #include "drv_mei_cpe_os.h"
+
+-#ifdef LINUX
+- #include <asm/ifx/ifx_atm.h>
+-#else
+- #error "ATM/PTM internal interface is only supported for Linux!"
+-#endif
++#include <lantiq_atm.h>
+
+ /** get interface and configuration */
+ #include "drv_mei_cpe_interface.h"
+Index: drv_mei_cpe-1.2.0/src/drv_mei_cpe_linux.c
+===================================================================
+--- drv_mei_cpe-1.2.0.orig/src/drv_mei_cpe_linux.c 2011-07-25 20:41:02.000000000 +0200
++++ drv_mei_cpe-1.2.0/src/drv_mei_cpe_linux.c 2012-11-28 15:24:56.269649609 +0100
+@@ -32,11 +32,9 @@
+ #include <linux/module.h>
+ #include <linux/version.h>
+
+-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+-#include <linux/utsrelease.h>
+-#endif
+-#include <linux/init.h>
++#include <generated/utsrelease.h>
+
++#include <linux/device.h>
+ #include <linux/ioport.h>
+ #include <linux/irq.h>
+ #include <asm/io.h>
+@@ -87,6 +85,8 @@
+ #include "drv_mei_cpe_device_cntrl.h"
+ #endif
+
++#define INT_NUM_IM4_IRL30 (INT_NUM_IM4_IRL0 + 30)
++
+ /* ===================================
+ extern function declarations
+ =================================== */
+@@ -122,7 +122,7 @@
+ size_t length,
+ loff_t * ppos);
+
+-static int MEI_Ioctl( struct inode *inode, struct file *filp,
++static long MEI_Ioctl(struct file *filp,
+ unsigned int nCmd, unsigned long nArgument);
+
+ static unsigned int MEI_Poll (struct file *filp, poll_table *table);
+@@ -137,7 +137,7 @@
+
+ static void MEI_IfxFreeIrq(unsigned int usedIrq, void *pUsedDevId);
+
+-static irqreturn_t MEI_InterruptLinux(int irq, void *dev_id, struct pt_regs *regs);
++static irqreturn_t MEI_InterruptLinux(int irq, void *dev_id);
+ #endif
+
+ #if CONFIG_PROC_FS
+@@ -194,7 +194,9 @@
+ /* =================================== */
+ /* Local variables (LINUX) */
+ /* =================================== */
+-static IFX_uint8_t major_number = 0;
++#define MEI_MAJOR 105
++
++static IFX_uint8_t major_number = MEI_MAJOR;
+ #ifdef MODULE
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+ MODULE_PARM(major_number, "b");
+@@ -242,7 +244,7 @@
+ MEI_Write,
+ poll:
+ MEI_Poll,
+- ioctl:
++ unlocked_ioctl:
+ MEI_Ioctl,
+ open:
+ MEI_OpenOS,
+@@ -457,7 +459,7 @@
+ 0 and positive values - success,
+ negative value - ioctl failed
+ */
+-static int MEI_Ioctl( struct inode *inode, struct file *filp,
++static long MEI_Ioctl(struct file *filp,
+ unsigned int nCmd, unsigned long nArgument)
+ {
+ int ret = 0, retSize = sizeof(IOCTL_MEI_ioctl_t);
+@@ -1242,7 +1246,7 @@
+ \remark
+ None.
+ */
+-static irqreturn_t MEI_InterruptLinux(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t MEI_InterruptLinux(int irq, void *dev_id)
+ {
+ IFX_int32_t meiIntCnt = 0;
+ MEIX_CNTRL_T *pMeiXCntrlList = (MEIX_CNTRL_T*)dev_id;
+@@ -1691,6 +1695,7 @@
+ static int __init MEI_module_init (void)
+ {
+ int result;
++ static struct class *dsl_class;
+
+ printk(KERN_INFO "%s" MEI_DRV_CRLF, &MEI_WHATVERSION[4]);
+ printk(KERN_INFO "(c) Copyright 2009, Infineon Technologies AG" MEI_DRV_CRLF);
+@@ -1730,6 +1735,8 @@
+ return (result);
+ }
+
++ dsl_class = class_create(THIS_MODULE, "ifx_mei");
++ device_create(dsl_class, NULL, MKDEV(MEI_MAJOR, 0), NULL, "ifx_mei");
+ return 0;
+ }
+
+Index: drv_mei_cpe-1.2.0/src/drv_mei_cpe_mei_access_vr9.c
+===================================================================
+--- drv_mei_cpe-1.2.0.orig/src/drv_mei_cpe_mei_access_vr9.c 2011-07-25 20:41:02.000000000 +0200
++++ drv_mei_cpe-1.2.0/src/drv_mei_cpe_mei_access_vr9.c 2012-11-28 15:14:10.433633419 +0100
+@@ -37,6 +37,7 @@
+
+ #include "cmv_message_format.h"
+
++#include <lantiq_soc.h>
+
+ /* ============================================================================
+ Local macro definition
+@@ -1527,32 +1528,35 @@
+ return IFX_ERROR;
+ }
+
++#define PMU_DFE BIT(9)
++
+ IFX_int32_t MEI_BasicChipInit(IFX_void_t)
+ {
+ /* Power up MEI */
+- DSL_DFE_PMU_SETUP(IFX_PMU_ENABLE);
+-
+- if (ifx_pmu_pg_dsl_dfe_enable() != 0)
++// DSL_DFE_PMU_SETUP(IFX_PMU_ENABLE);
++ltq_pmu_enable(PMU_DFE);
++ /* if (ifx_pmu_pg_dsl_dfe_enable() != 0)
+ {
+ PRN_ERR_USR_NL( MEI_MEI_ACCESS, MEI_DRV_PRN_LEVEL_ERR,
+ ("MEI: ERROR - DSL DFE PG enable failed!" MEI_DRV_CRLF));
+ return IFX_ERROR;
+- }
++ }*/
+
+ return IFX_SUCCESS;
+ }
+
+ IFX_int32_t MEI_BasicChipExit(IFX_void_t)
+ {
+- if (ifx_pmu_pg_dsl_dfe_disable() != 0)
++/* if (ifx_pmu_pg_dsl_dfe_disable() != 0)
+ {
+ PRN_ERR_USR_NL( MEI_MEI_ACCESS, MEI_DRV_PRN_LEVEL_ERR,
+ ("MEI: ERROR - DSL DFE PG disable failed!" MEI_DRV_CRLF));
+ return IFX_ERROR;
+ }
+-
++*/
+ /* Power down MEI */
+- DSL_DFE_PMU_SETUP(IFX_PMU_DISABLE);
++// DSL_DFE_PMU_SETUP(IFX_PMU_DISABLE);
++ltq_pmu_disable(PMU_DFE);
+
+ return IFX_SUCCESS;
+ }
diff --git a/package/kernel/lantiq/ltq-vdsl/Makefile b/package/kernel/lantiq/ltq-vdsl/Makefile
new file mode 100644
index 0000000000..9f1e268037
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl/Makefile
@@ -0,0 +1,69 @@
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ltq-vdsl-vr9
+PKG_VERSION:=4.11.4
+PKG_RELEASE:=1
+
+PKG_BASE_NAME:=drv_dsl_cpe_api_vrx
+PKG_SOURCE:=$(PKG_BASE_NAME)-$(PKG_VERSION).tar.gz
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/drv_dsl_cpe_api-$(PKG_VERSION)
+PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
+PKG_MD5SUM:=b6d9c1e3c5db1bfcd6e81bb2f582cadb
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-vdsl-vr9
+ TITLE:=vdsl driver
+ SECTION:=sys
+ SUBMENU:=Network Devices
+ DEPENDS:=@TARGET_lantiq_xway +kmod-ltq-vdsl-vr9-mei
+ FILES:=$(PKG_BUILD_DIR)/src/drv_dsl_cpe_api.ko
+ AUTOLOAD:=$(call AutoLoad,51,drv_dsl_cpe_api)
+endef
+
+define Package/ltq-vdsl-vr9/description
+ This package contains the Lantiq DSL CPE API driver.
+
+ Supported Devices:
+ - VRX200 Family
+endef
+
+EXTRA_CFLAGS = -fno-pic -mno-abicalls -mlong-calls -G 0
+
+CONFIGURE_ARGS += --enable-kernel-include="$(LINUX_DIR)/include" \
+ --with-max-device="1" \
+ --with-lines-per-device="1" \
+ --with-channels-per-line="1" \
+ --enable-vrx \
+ --enable-ifxos \
+ --enable-ifxos-include="-I$(STAGING_DIR)/usr/include/ifxos" \
+ --enable-driver-include="-I$(STAGING_DIR)/usr/include/vdsl" \
+ --enable-add-drv-cflags="-DMODULE -DINCLUDE_DSL_ATM_PTM_INTERFACE_SUPPORT -DDSL_DEBUG_DISABLE" \
+ --enable-adsl-led=no \
+ --enable-adsl-mib=no \
+ --enable-dsl-ceoc=no \
+ --enable-dsl-bonding=no \
+ --enable-linux-26 \
+ --enable-kernelbuild="$(LINUX_DIR)" \
+ KERNEL_ARCH=mips
+
+CONFIGURE_ARGS += --enable-model=full
+#CONFIGURE_ARGS += --enable-model=lite
+#CONFIGURE_ARGS += --enable-model=footprint
+#CONFIGURE_ARGS += --enable-model=typical
+#CONFIGURE_ARGS += --enable-model=debug
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include/drv_vdsl_cpe_api
+ $(CP) $(PKG_BUILD_DIR)/src/include/drv_dsl_cpe*.h $(1)/usr/include/drv_vdsl_cpe_api/
+endef
+
+$(eval $(call KernelPackage,ltq-vdsl-vr9))
diff --git a/package/kernel/lantiq/ltq-vdsl/patches/100-compat.patch b/package/kernel/lantiq/ltq-vdsl/patches/100-compat.patch
new file mode 100644
index 0000000000..5abe4b2084
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl/patches/100-compat.patch
@@ -0,0 +1,148 @@
+Index: drv_dsl_cpe_api-4.11.4/src/include/drv_dsl_cpe_os_linux.h
+===================================================================
+--- drv_dsl_cpe_api-4.11.4.orig/src/include/drv_dsl_cpe_os_linux.h 2011-10-26 00:35:29.000000000 +0200
++++ drv_dsl_cpe_api-4.11.4/src/include/drv_dsl_cpe_os_linux.h 2012-11-28 23:05:38.766342592 +0100
+@@ -17,7 +17,7 @@
+ #endif
+
+ #include <asm/ioctl.h>
+-#include <linux/autoconf.h>
++#include <generated/autoconf.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+@@ -28,7 +28,7 @@
+ #include <linux/sched.h>
+
+ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+- #include <linux/utsrelease.h>
++ #include <generated/utsrelease.h>
+ #endif
+
+ #include <linux/types.h>
+@@ -40,7 +40,6 @@
+ #include <linux/delay.h>
+ #include <linux/poll.h>
+ #include <asm/uaccess.h>
+-#include <linux/smp_lock.h>
+
+ #ifdef INCLUDE_DSL_CPE_API_IFXOS_SUPPORT
+ /** IFXOS includes*/
+Index: drv_dsl_cpe_api-4.11.4/src/Makefile.in
+===================================================================
+--- drv_dsl_cpe_api-4.11.4.orig/src/Makefile.in 2012-03-05 15:24:31.000000000 +0100
++++ drv_dsl_cpe_api-4.11.4/src/Makefile.in 2012-11-28 23:05:38.770342592 +0100
+@@ -72,7 +72,7 @@
+
+ # the headerfile of linux kernels 2.6.x contain to much arithmetic
+ # with void pointers (which is allowed for gcc!)
+-@KERNEL_2_6_FALSE@am__append_8 = -Wpointer-arith
++@KERNEL_2_6_FALSE@am__append_8 =
+ subdir = src
+ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+Index: drv_dsl_cpe_api-4.11.4/src/common/drv_dsl_cpe_os_linux.c
+===================================================================
+--- drv_dsl_cpe_api-4.11.4.orig/src/common/drv_dsl_cpe_os_linux.c 2011-10-26 00:35:28.000000000 +0200
++++ drv_dsl_cpe_api-4.11.4/src/common/drv_dsl_cpe_os_linux.c 2012-11-28 23:05:38.770342592 +0100
+@@ -12,6 +12,7 @@
+
+ #define DSL_INTERN
+
++#include <linux/device.h>
+ #include "drv_dsl_cpe_api.h"
+ #include "drv_dsl_cpe_api_ioctl.h"
+
+@@ -34,7 +35,7 @@
+ static DSL_ssize_t DSL_DRV_Write(DSL_DRV_file_t *pFile, const DSL_char_t * pBuf,
+ DSL_DRV_size_t nSize, DSL_DRV_offset_t * pLoff);
+
+-static DSL_int_t DSL_DRV_Ioctls(DSL_DRV_inode_t * pINode, DSL_DRV_file_t * pFile,
++static long DSL_DRV_Ioctls(DSL_DRV_file_t * pFile,
+ DSL_uint_t nCommand, unsigned long nArg);
+
+ static int DSL_DRV_Open(DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil);
+@@ -71,7 +72,7 @@
+ open: DSL_DRV_Open,
+ release: DSL_DRV_Release,
+ write: DSL_DRV_Write,
+- ioctl: DSL_DRV_Ioctls,
++ unlocked_ioctl: DSL_DRV_Ioctls,
+ poll: DSL_DRV_Poll
+ };
+ #else
+@@ -172,7 +173,7 @@
+ \return Success or failure.
+ \ingroup Internal
+ */
+-static DSL_int_t DSL_DRV_Ioctls(DSL_DRV_inode_t * pINode,
++static long DSL_DRV_Ioctls(
+ DSL_DRV_file_t * pFile,
+ DSL_uint_t nCommand,
+ unsigned long nArg)
+@@ -222,14 +223,7 @@
+ }
+ }
+
+- if (pINode == DSL_NULL)
+- {
+- bIsInKernel = DSL_TRUE;
+- }
+- else
+- {
+ bIsInKernel = DSL_FALSE;
+- }
+
+ if ( (_IOC_TYPE(nCommand) == DSL_IOC_MAGIC_CPE_API) ||
+ (_IOC_TYPE(nCommand) == DSL_IOC_MAGIC_CPE_API_G997) ||
+@@ -1082,6 +1076,7 @@
+ int __init DSL_ModuleInit(void)
+ {
+ DSL_int_t i;
++ static struct class *dsl_class;
+
+ printk(DSL_DRV_CRLF DSL_DRV_CRLF "Lantiq CPE API Driver version: %s" DSL_DRV_CRLF,
+ &(dsl_cpe_api_version[4]));
+@@ -1127,6 +1122,10 @@
+
+ DSL_DRV_DevNodeInit();
+
++ dsl_class = class_create(THIS_MODULE, "dsl_cpe_api0");
++ device_create(dsl_class, NULL, MKDEV(DRV_DSL_CPE_API_DEV_MAJOR, 0), NULL, "dsl_cpe_api0");
++
++
+ return 0;
+ }
+
+Index: drv_dsl_cpe_api-4.11.4/src/device/drv_dsl_cpe_msg_vrx.c
+===================================================================
+--- drv_dsl_cpe_api-4.11.4.orig/src/device/drv_dsl_cpe_msg_vrx.c 2012-03-05 11:25:21.000000000 +0100
++++ drv_dsl_cpe_api-4.11.4/src/device/drv_dsl_cpe_msg_vrx.c 2012-11-28 23:06:46.418344288 +0100
+@@ -685,6 +685,7 @@
+ DSL_ProfileType_t nProfile = DSL_PROFILE_LAST;
+ DSL_G997_XTUSystemEnablingData_t data = {{0,0,0,0,0,0,0,0}};
+
++ //printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+ DSL_DEBUG( DSL_DBG_MSG,
+ (pContext, SYS_DBG_MSG"DSL[%02d]: IN - DSL_DRV_VXX_SendMsgSelectedProfileVdsl2Get"
+ DSL_DRV_CRLF, DSL_DEV_NUM(pContext)));
+@@ -985,8 +988,10 @@
+
+ /* Check consistency of XTSE status setting - Only one bit should be set at
+ a time */
++ //printk("XTSE (%d) - ", DSL_G997_NUM_XTSE_OCTETS);
+ for (i = 0, nBitCount = 0; i < DSL_G997_NUM_XTSE_OCTETS; i++)
+ {
++ //printk("%02X ", data.XTSE[i]);
+ for (j = 0; j < 8; j++)
+ {
+ if ( ((data.XTSE[i] >> j) & 0x01) != 0)
+@@ -996,6 +1001,8 @@
+ }
+ }
+
++ //printk("\n");
++
+ if (nBitCount > 1)
+ {
+ DSL_DEBUG( DSL_DBG_ERR,
diff --git a/package/kernel/lantiq/ltq-vmmc/Config.in b/package/kernel/lantiq/ltq-vmmc/Config.in
new file mode 100644
index 0000000000..89e1bc5cba
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vmmc/Config.in
@@ -0,0 +1,95 @@
+choice
+ prompt "device selection"
+ depends on PACKAGE_kmod-ltq-vmmc
+ default VOICE_CPE_VMMC_WITH_DEVICE_DANUBE
+ help
+ Select the target device.
+
+ config VOICE_CPE_VMMC_WITH_DEVICE_DANUBE
+ bool "Danube, Twinpass, Vinax"
+ depends on TARGET_lantiq_xway
+
+# config VOICE_CPE_VMMC_WITH_DEVICE_AR9
+# bool "AR9 family"
+# depends on TARGET_lantiq_ar9
+
+# config VOICE_CPE_VMMC_WITH_DEVICE_VR9
+# bool "VR9 family"
+# depends on TARGET_lantiq_vr9
+#
+ config VOICE_VMMC_WITH_DEVICE_FALCON
+ bool "FALC-ON"
+ depends on (TARGET_lantiq_falcon||TARGET_lantiq_falcon_stable)
+
+endchoice
+
+choice
+ depends on PACKAGE_kmod-ltq-vmmc
+ prompt "FXS coefficients"
+ default LTQ_VOICE_CPE_VMMC_COEF_FALCON_ETSI
+ help
+ Select country specific FXS coefficient file.
+
+ config LTQ_VOICE_CPE_VMMC_COEF_FALCON_ETSI
+ bool "ETSI_T3R10: Vl:40V, Ic:25mA, Vid:25V, Vri:45Vrms, f:25Hz"
+ help
+ These coefficents contains a parameter set with line impedance Zr according to ETSI.
+
+ T: gain in transmit direction (attenuation 3dBr) [dBr]
+ R: gain in receive direction (attenuation 10dBr) [dBr]
+ Vl: on-hook voltage limit [V]
+ Ic: off-hook loop current [mA]
+ Vid: low-power-standby voltage [V]
+ Vri: ring voltage [v]
+ f: ring frequency [V]
+
+ config LTQ_VOICE_CPE_VMMC_COEF_FALCON_US600R
+ bool "USA_600R_T3R10: Vl:40V, Ic:25mA, Vid:25V, Vri:45V, f:20Hz"
+ help
+ These coefficents contains a parameter set with line impedance e.g. for USA.
+
+ T: gain in transmit direction (attenuation 3dBr) [dBr]
+ R: gain in receive direction (attenuation 10dBr) [dBr]
+ Vl: on-hook voltage limit [V]
+ Ic: off-hook loop current [mA]
+ Vid: low-power-standby voltage [V]
+ Vri: ring voltage [v]
+ f: ring frequency [V]
+
+ config LTQ_VOICE_CPE_VMMC_COEF_FALCON_USE_CUSTOM_FILE
+ bool "Select own FXS coefficient file"
+endchoice
+
+config VOICE_CPE_VMMC_PMC
+ depends on (VOICE_CPE_VMMC_WITH_DEVICE_AR9 || VOICE_CPE_VMMC_WITH_DEVICE_VR9)
+ bool "Power Management Control support"
+ default n
+ help
+ Option to enable Power Management Control on AR9, VR9. Not supported for Danube.
+
+config VOICE_CPE_VMMC_DISABLE_DECT_NIBBLE_SWAP
+ bool "Disable DECT nibble swap"
+ depends on PACKAGE_kmod-ltq-vmmc
+ default n
+ help
+ Option to disable DECT nibble swap for COSIC modem (for backward compatibility only).
+
+config VOICE_CPE_VMMC_EVENT_LOGGER
+ depends on BROKEN
+ bool "Event logger support"
+ depends on PACKAGE_kmod-ltq-vmmc
+ default n
+ help
+ Option to enable details traces between drv_vmmc and the voice FW
+ - for debugging only
+ - requires package ifx-evtlog
+
+config VOICE_CPE_VMMC_MPS_HISTORY_SIZE
+ int "MPS history buffer in words (0<=size<=512)"
+ depends on PACKAGE_kmod-ltq-vmmc
+ default "128"
+ help
+ MPS history buffer (default=128 words, maximum=512 words, 0=disable)
+ To opimize the memory footprint in RAM, you might want to set the
+ buffer size to 0.
+
diff --git a/package/kernel/lantiq/ltq-vmmc/Makefile b/package/kernel/lantiq/ltq-vmmc/Makefile
new file mode 100644
index 0000000000..98355b1ecd
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vmmc/Makefile
@@ -0,0 +1,166 @@
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=drv_vmmc
+PKG_VERSION:=1.9.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_MD5SUM:=d8eee8cba0edb28974cc1f8532e3bd18
+PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/ltqtapi.mk
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-vmmc
+ SUBMENU:=Voice over IP
+ TITLE:=TAPI LL driver for Voice Macro
+ URL:=http://www.lantiq.com/
+ DEPENDS:=$(LTQ_TAPI_TARGET) +kmod-ltq-tapi
+ FILES:=$(PKG_BUILD_DIR)/src/drv_vmmc.ko
+ AUTOLOAD:=$(call AutoLoad,25,drv_vmmc)
+endef
+
+define KernelPackage/ltq-vmmc/description
+ Voice Subsystem Low Level Driver for Danube, AR9, VR9 device families
+endef
+
+define KernelPackage/ltq-vmmc/config
+ source "$(SOURCE)/Config.in"
+endef
+
+CONFIGURE_ARGS += \
+ ARCH=$(LINUX_KARCH) \
+ --enable-linux-26 \
+ --enable-kernelbuild="$(LINUX_DIR)" \
+ --enable-kernelincl="$(LINUX_DIR)/include" \
+ --enable-tapiincl="$(STAGING_DIR)/usr/include/drv_tapi" \
+ --with-ifxos-incl=$(STAGING_DIR)/usr/include/ifxos \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_VMMC_EVENT_LOGGER,el-debug) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_VMMC_PMC,pmc) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_VMMC_DISABLE_DECT_NIBBLE_SWAP,dect-nibble-swap) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_FAX,fax t38) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_CID,cid) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_DECT,dect) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_KPI,kpi) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_LT_GR909,lt calibration) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_HDLC,hdlc) \
+ $(call autoconf_bool,CONFIG_VOICE_CPE_TAPI_TRACES,trace)
+
+ifneq ($(CONFIG_VOICE_CPE_VMMC_MPS_HISTORY_SIZE),128)
+ CONFIGURE_ARGS += --enable-history-buf=$(CONFIG_VOICE_CPE_VMMC_MPS_HISTORY_SIZE)
+endif
+
+#defaults
+FW_URL:=http://localhost/
+FW_TARGET:=ifx_firmware.bin
+FW_FILE:=fw_voip_ifx.tar.gz
+COEF_TARGET:=ifx_bbd_fxs.bin
+COEF_FILE:=coef_voip_ifx.tar.gz
+
+FW_DIR:=lib/firmware
+
+FW_TARGET_GENERIC:=$(FW_TARGET)
+COEF_TARGET_GENERIC:=$(COEF_TARGET)
+
+ifeq ($(CONFIG_VOICE_CPE_VMMC_WITH_DEVICE_DANUBE)$(CONFIG_LTQ_VOICE_CPE_VMMC_WITH_DEVICE_DANUBE),y)
+ CONFIGURE_ARGS += --with-device=DANUBE
+ FW_SOURCE:=voip_R12.1.0.1.0-enc.bin
+ FW_TARGET:=danube_firmware.bin
+ FW_FILE=fw_voip_danube-12.1.0.1.0.tar.gz
+ FW_MD5SUM:=51868b88dee9dbc65d3dbba355ded91c
+ FW_DOWNLOAD:=1
+ COEF_SRC:=danube_bbd_fxs.bin
+ COEF_TARGET:=danube_bbd_fxs.bin
+ COEF_FILE:=coef_voip_danube-0.9.0.tar.gz
+ COEF_MD5SUM:=c8ac6592b304b03829a8123560e15710
+ COEF_DOWNLOAD:=1
+endif
+
+ifeq ($(CONFIG_VOICE_CPE_VMMC_WITH_DEVICE_AR9),y)
+ CONFIGURE_ARGS += --with-device=AR9
+ # TODO: add fw/coef
+endif
+
+COEF_SRC:=$(COEF_TARGET)
+
+ifeq ($(CONFIG_VOICE_VMMC_WITH_DEVICE_FALCON),y)
+ CONFIGURE_ARGS += --with-device=FALCON
+ FW_SOURCE:=voip_R1.1.0.6.0-enc.bin
+ FW_MD5SUM:=cd4366a52a8010b76793e3810a4f14b3
+ FW_TARGET:=falcon_voip_fw.bin
+ FW_FILE=fw_voip_falcon-1.1.0.6.0.tar.gz
+ FW_DOWNLOAD:=1
+ COEF_TARGET:=falcon_bbd.bin
+# FXS part
+ifeq ($(CONFIG_LTQ_VOICE_CPE_VMMC_COEF_FALCON_ETSI),y)
+ COEF_SRC:=ETSI_3_10.BIN
+endif
+ifeq ($(CONFIG_LTQ_VOICE_CPE_VMMC_COEF_FALCON_US600R),y)
+ COEF_SRC:=R600_3_10.BIN
+endif
+ifeq ($(CONFIG_LTQ_VOICE_CPE_VMMC_COEF_FALCON_USE_CUSTOM_FILE),y)
+ COEF_SRC:=$(CONFIG_LTQ_VOICE_CPE_VMMC_COEF_FALCON_CUSTOM_FILE)
+endif
+ COEF_FILE:=coef_voip_falcon.tar.gz
+ COEF_MD5SUM:=56c5a838f2bb9bd87d0e8dce271f810b
+ COEF_DOWNLOAD:=1
+endif
+
+ifeq ($(CONFIG_VOICE_CPE_VMMC_WITH_DEVICE_VR9),y)
+ CONFIGURE_ARGS += --with-device=VR9
+ # TODO: add fw/coef
+endif
+
+define Download/firmware
+ FILE:=$(FW_FILE)
+ URL:=$(FW_URL)
+ MD5SUM:=$(FW_MD5SUM)
+endef
+$(eval $(if $(FW_DOWNLOAD),$(call Download,firmware)))
+
+define Download/coef
+ FILE:=$(COEF_FILE)
+ URL:=$(FW_URL)
+ MD5SUM:=$(COEF_MD5SUM)
+endef
+$(eval $(if $(COEF_DOWNLOAD),$(call Download,coef)))
+
+define Build/Configure
+ rm -rf \
+ $(PKG_BUILD_DIR)/coef \
+ $(PKG_BUILD_DIR)/firmware
+ mkdir -p \
+ $(PKG_BUILD_DIR)/coef \
+ $(PKG_BUILD_DIR)/firmware
+ $(TAR) -C $(PKG_BUILD_DIR)/firmware -xvzf $(DL_DIR)/$(FW_FILE)
+ $(TAR) -C $(PKG_BUILD_DIR)/coef -xvzf $(DL_DIR)/$(COEF_FILE)
+ (cd $(PKG_BUILD_DIR); aclocal && autoconf && automake)
+ $(call Build/Configure/Default)
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ mkdir -p $(1)/usr/include/drv_vmmc
+ $(CP) -v --dereference $(PKG_BUILD_DIR)/include/* $(1)/usr/include/drv_vmmc
+ (cd $(1)/usr/include/drv_vmmc && ln -snf . include)
+endef
+
+define KernelPackage/ltq-vmmc/install
+ $(INSTALL_DIR) $(1)/etc/init.d $(1)/$(FW_DIR)
+ $(INSTALL_BIN) ./files/vmmc.init $(1)/etc/init.d/vmmc
+ $(CP) $(PKG_BUILD_DIR)/firmware/$(FW_SOURCE) $(1)/$(FW_DIR)/$(FW_TARGET)
+ ln -s /$(FW_DIR)/$(FW_TARGET) $(1)/$(FW_DIR)/$(FW_TARGET_GENERIC)
+ $(CP) $(PKG_BUILD_DIR)/coef/$(COEF_SRC) $(1)/$(FW_DIR)/$(COEF_TARGET)
+ ln -s /$(FW_DIR)/$(COEF_TARGET) $(1)/$(FW_DIR)/$(COEF_TARGET_GENERIC)
+endef
+
+$(eval $(call KernelPackage,ltq-vmmc))
diff --git a/package/kernel/lantiq/ltq-vmmc/files/vmmc.init b/package/kernel/lantiq/ltq-vmmc/files/vmmc.init
new file mode 100644
index 0000000000..100a97dc45
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vmmc/files/vmmc.init
@@ -0,0 +1,19 @@
+#!/bin/sh /etc/rc.common
+#
+# Activate Voice CPE TAPI subsystem LL driver for VMMC
+
+START=31
+
+start() {
+ [ ! -c /dev/vmmc10 ] && {
+ mknod /dev/vmmc10 c 122 10
+ mknod /dev/vmmc11 c 122 11
+ mknod /dev/vmmc12 c 122 12
+ mknod /dev/vmmc13 c 122 13
+ mknod /dev/vmmc14 c 122 14
+ mknod /dev/vmmc15 c 122 15
+ mknod /dev/vmmc16 c 122 16
+ mknod /dev/vmmc17 c 122 17
+ mknod /dev/vmmc18 c 122 18
+ }
+}
diff --git a/package/kernel/lantiq/ltq-vmmc/patches/000-portability.patch b/package/kernel/lantiq/ltq-vmmc/patches/000-portability.patch
new file mode 100644
index 0000000000..48602476f4
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vmmc/patches/000-portability.patch
@@ -0,0 +1,287 @@
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -228,7 +228,7 @@ drv_vmmc_CFLAGS += -fno-common
+ drv_vmmc_OBJS = "$(subst .c,.o, $(drv_vmmc_SOURCES) $(nodist_drv_vmmc_SOURCES))"
+
+ drv_vmmc.ko: $(drv_vmmc_SOURCES) $(EXTRA_DIST)
+- @echo -e "Making Linux 2.6.x kernel object"
++ @echo "Making Linux 2.6.x kernel object"
+ @for f in $(drv_vmmc_SOURCES) $(nodist_drv_vmmc_SOURCES) ; do \
+ if test ! -e $(PWD)/$$f; then \
+ echo " LN $$f" ; \
+@@ -236,10 +236,10 @@ drv_vmmc.ko: $(drv_vmmc_SOURCES) $(EXTRA
+ ln -s @abs_srcdir@/$$f $(PWD)/$$f; \
+ fi; \
+ done;
+- @echo -e "# drv_vmmc: Generated to build Linux 2.6.x kernel object" > $(PWD)/Kbuild
+- @echo -e "obj-m := $(subst .ko,.o,$@)" >> $(PWD)/Kbuild
+- @echo -e "$(subst .ko,,$@)-y := $(drv_vmmc_OBJS)" >> $(PWD)/Kbuild
+- @echo -e "EXTRA_CFLAGS := -DHAVE_CONFIG_H $(CFLAGS) $(drv_vmmc_CFLAGS) $(INCLUDES)" >> $(PWD)/Kbuild
++ @echo "# drv_vmmc: Generated to build Linux 2.6.x kernel object" > $(PWD)/Kbuild
++ @echo "obj-m := $(subst .ko,.o,$@)" >> $(PWD)/Kbuild
++ @echo "$(subst .ko,,$@)-y := $(drv_vmmc_OBJS)" >> $(PWD)/Kbuild
++ @echo "EXTRA_CFLAGS := -DHAVE_CONFIG_H $(CFLAGS) $(drv_vmmc_CFLAGS) $(INCLUDES)" >> $(PWD)/Kbuild
+ $(MAKE) ARCH=@KERNEL_ARCH@ -C @KERNEL_BUILD_PATH@ O=@KERNEL_BUILD_PATH@ M=$(PWD) modules
+
+ clean-generic:
+--- a/src/drv_vmmc_linux.c
++++ b/src/drv_vmmc_linux.c
+@@ -27,11 +27,18 @@
+ #include <linux/proc_fs.h>
+ #include <linux/wait.h>
+ #include <linux/vmalloc.h>
++#include <linux/sched.h>
+
+ #ifdef LINUX_2_6
+ #include <linux/version.h>
+ #ifndef UTS_RELEASE
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
++#include <linux/autoconf.h>
+ #include <linux/utsrelease.h>
++#else
++#include <generated/autoconf.h>
++#include <generated/utsrelease.h>
++#endif
+ #endif /* UTC_RELEASE */
+ #undef CONFIG_DEVFS_FS
+ #endif /* LINUX_2_6 */
+--- a/src/mps/drv_mps_vmmc_linux.c
++++ b/src/mps/drv_mps_vmmc_linux.c
+@@ -19,11 +19,22 @@
+ #include "drv_config.h"
+
+ #include "drv_mps_version.h"
++#include <linux/version.h>
+
+ #ifdef CONFIG_DEBUG_MINI_BOOT
+ #define IKOS_MINI_BOOT
+ #endif /* */
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
+ #include <linux/autoconf.h>
++#ifndef UTS_RELEASE
++#include <linux/utsrelease.h>
++#endif
++#else
++#include <generated/autoconf.h>
++#ifndef UTS_RELEASE
++#include <generated/utsrelease.h>
++#endif
++#endif
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/poll.h>
+@@ -34,7 +45,13 @@
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+ #ifdef LINUX_2_6
++#ifndef UTS_RELEASE
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
+ #include <linux/utsrelease.h>
++#else
++#include <generated/utsrelease.h>
++#endif
++#endif /* UTC_RELEASE */
+ #else /* */
+ #include <linux/uts.h>
+ #include <linux/moduleparam.h>
+@@ -94,8 +111,13 @@ IFX_int32_t ifx_mps_get_status_proc (IFX
+ #ifndef __KERNEL__
+ IFX_int32_t ifx_mps_open (struct inode *inode, struct file *file_p);
+ IFX_int32_t ifx_mps_close (struct inode *inode, struct file *file_p);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+ IFX_int32_t ifx_mps_ioctl (struct inode *inode, struct file *file_p,
+ IFX_uint32_t nCmd, IFX_ulong_t arg);
++#else
++long ifx_mps_ioctl (struct file *file_p,
++ IFX_uint32_t nCmd, IFX_ulong_t arg);
++#endif
+ IFX_int32_t ifx_mps_read_mailbox (mps_devices type, mps_message * rw);
+ IFX_int32_t ifx_mps_write_mailbox (mps_devices type, mps_message * rw);
+ IFX_int32_t ifx_mps_register_data_callback (mps_devices type, IFX_uint32_t dir,
+@@ -155,7 +177,11 @@ IFX_char_t voice_channel_int_name[NUM_VO
+ static struct file_operations ifx_mps_fops = {
+ owner:THIS_MODULE,
+ poll:ifx_mps_poll,
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+ ioctl:ifx_mps_ioctl,
++#else
++ unlocked_ioctl:ifx_mps_ioctl,
++#endif
+ open:ifx_mps_open,
+ release:ifx_mps_close
+ };
+@@ -598,8 +624,13 @@ static IFX_uint32_t ifx_mps_poll (struct
+ * \return -ENOIOCTLCMD Invalid command
+ * \ingroup API
+ */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+ IFX_int32_t ifx_mps_ioctl (struct inode * inode, struct file * file_p,
+ IFX_uint32_t nCmd, IFX_ulong_t arg)
++#else
++long ifx_mps_ioctl (struct file *file_p,
++ IFX_uint32_t nCmd, IFX_ulong_t arg)
++#endif
+ {
+ IFX_int32_t retvalue = -EINVAL;
+ mps_message rw_struct;
+@@ -613,17 +644,30 @@ IFX_int32_t ifx_mps_ioctl (struct inode
+ 'mps_devices' enum type, which in fact is [0..8]; So, if inode value is
+ [0..NUM_VOICE_CHANNEL+1], then we make sure that we are calling from
+ kernel space. */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+ if (((IFX_int32_t) inode >= 0) &&
+ ((IFX_int32_t) inode < NUM_VOICE_CHANNEL + 1))
++#else
++ if (((IFX_int32_t) file_p >= 0) &&
++ ((IFX_int32_t) file_p < NUM_VOICE_CHANNEL + 1))
++#endif
+ {
+ from_kernel = 1;
+
+ /* Get corresponding mailbox device structure */
+ if ((pMBDev =
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+ ifx_mps_get_device ((mps_devices) ((IFX_int32_t) inode))) == 0)
++#else
++ ifx_mps_get_device ((mps_devices) ((IFX_int32_t) file_p))) == 0)
++#endif
+ {
+ return (-EINVAL);
+ }
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
++#else
++ file_p = NULL;
++#endif
+ }
+ else
+ {
+--- a/src/mps/drv_mps_vmmc_common.c
++++ b/src/mps/drv_mps_vmmc_common.c
+@@ -21,7 +21,11 @@
+ #undef USE_PLAIN_VOICE_FIRMWARE
+ #undef PRINT_ON_ERR_INTERRUPT
+ #undef FAIL_ON_ERR_INTERRUPT
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
+ #include <linux/autoconf.h>
++#else
++#include <generated/autoconf.h>
++#endif
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+
+@@ -92,7 +96,9 @@ extern IFX_uint32_t danube_get_cpu_ver (
+ extern mps_mbx_dev *ifx_mps_get_device (mps_devices type);
+
+ #ifdef LINUX_2_6
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
+ extern IFX_void_t bsp_mask_and_ack_irq (IFX_uint32_t irq_nr);
++#endif
+
+ #else /* */
+ extern IFX_void_t mask_and_ack_danube_irq (IFX_uint32_t irq_nr);
+--- a/src/mps/drv_mps_vmmc_danube.c
++++ b/src/mps/drv_mps_vmmc_danube.c
+@@ -20,7 +20,11 @@
+
+ #ifdef SYSTEM_DANUBE /* defined in drv_mps_vmmc_config.h */
+
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
+ #include <linux/autoconf.h>
++#else
++#include <generated/autoconf.h>
++#endif
+
+ /* lib_ifxos headers */
+ #include "ifx_types.h"
+--- a/configure.in
++++ b/configure.in
+@@ -112,7 +112,7 @@ dnl Set kernel build path
+ AC_ARG_ENABLE(kernelbuild,
+ AS_HELP_STRING(--enable-kernelbuild=x,Set the target kernel build path),
+ [
+- if test -r $enableval/include/linux/autoconf.h; then
++ if test -e $enableval/include/linux/autoconf.h -o -e $enableval/include/generated/autoconf.h; then
+ AC_SUBST([KERNEL_BUILD_PATH],[$enableval])
+ else
+ AC_MSG_ERROR([The kernel build directory is not valid or not configured!])
+--- a/src/drv_vmmc_bbd.c
++++ b/src/drv_vmmc_bbd.c
+@@ -1072,7 +1072,11 @@ static IFX_int32_t vmmc_BBD_DownloadChCr
+ IFX_uint8_t padBytes = 0;
+ #endif
+ IFX_uint16_t cram_offset, cram_crc,
+- pCmd [MAX_CMD_WORD] = {0};
++ pCmd [MAX_CMD_WORD]
++#if defined (__GNUC__) || defined (__GNUG__)
++ __attribute__ ((aligned(4)))
++#endif
++ = {0};
+
+ /* read offset */
+ cpb2w (&cram_offset, &bbd_cram->pData[0], sizeof (IFX_uint16_t));
+--- a/src/drv_vmmc_init.c
++++ b/src/drv_vmmc_init.c
+@@ -776,8 +776,13 @@ IFX_int32_t VMMC_TAPI_LL_FW_Start(IFX_TA
+ dwld.fwDwld.length = IoInit.pram_size;
+
+ /* download firmware */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+ ret = ifx_mps_ioctl((IFX_void_t *) command, IFX_NULL, FIO_MPS_DOWNLOAD,
+ (IFX_uint32_t) &dwld.fwDwld);
++#else
++ ret = ifx_mps_ioctl((IFX_void_t *) command, FIO_MPS_DOWNLOAD,
++ (IFX_uint32_t) &dwld.fwDwld);
++#endif
+ }
+
+ if (VMMC_SUCCESS(ret))
+--- a/src/drv_vmmc_ioctl.c
++++ b/src/drv_vmmc_ioctl.c
+@@ -426,18 +426,31 @@ IFX_int32_t VMMC_Dev_Spec_Ioctl (IFX_TAP
+ /* MPS driver will do the USR2KERN so just pass on the pointer. */
+ dwnld_struct.data = (IFX_void_t *)IoInit.pPRAMfw;
+
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+ ret = ifx_mps_ioctl((IFX_void_t *)command, IFX_NULL,
+ FIO_MPS_DOWNLOAD, (IFX_uint32_t) &dwnld_struct);
++#else
++ ret = ifx_mps_ioctl((IFX_void_t *)command,
++ FIO_MPS_DOWNLOAD, (IFX_uint32_t) &dwnld_struct);
++#endif
+ break;
+ }
+ case FIO_DEV_RESET:
+ {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+ ret = ifx_mps_ioctl((IFX_void_t *)command, IFX_NULL, FIO_MPS_RESET, 0);
++#else
++ ret = ifx_mps_ioctl((IFX_void_t *)command, FIO_MPS_RESET, 0);
++#endif
+ break;
+ }
+ case FIO_DEV_RESTART:
+ {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+ ret = ifx_mps_ioctl((IFX_void_t *)command, IFX_NULL, FIO_MPS_RESTART, 0);
++#else
++ ret = ifx_mps_ioctl((IFX_void_t *)command, FIO_MPS_RESTART, 0);
++#endif
+ break;
+ }
+ case FIO_LASTERR:
+--- a/src/mps/drv_mps_vmmc.h
++++ b/src/mps/drv_mps_vmmc.h
+@@ -279,8 +279,13 @@ typedef struct
+ #include <linux/fs.h>
+ IFX_int32_t ifx_mps_open (struct inode *inode, struct file *file_p);
+ IFX_int32_t ifx_mps_close (struct inode *inode, struct file *filp);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+ IFX_int32_t ifx_mps_ioctl (struct inode *inode, struct file *file_p,
+ IFX_uint32_t nCmd, unsigned long arg);
++#else
++long ifx_mps_ioctl (struct file *filp,
++ IFX_uint32_t nCmd, unsigned long arg);
++#endif
+ IFX_int32_t ifx_mps_register_data_callback (mps_devices type, IFX_uint32_t dir,
+ IFX_void_t (*callback) (mps_devices
+ type));
diff --git a/package/kernel/lantiq/ltq-vmmc/patches/100-target.patch b/package/kernel/lantiq/ltq-vmmc/patches/100-target.patch
new file mode 100644
index 0000000000..cabd2d199c
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vmmc/patches/100-target.patch
@@ -0,0 +1,751 @@
+--- a/src/drv_vmmc_access.h
++++ b/src/drv_vmmc_access.h
+@@ -24,6 +24,10 @@
+ #include "drv_mps_vmmc.h"
+ #endif
+
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28))
++# define IFX_MPS IFXMIPS_MPS_BASE_ADDR
++#endif
++
+ /* ============================= */
+ /* Global Defines */
+ /* ============================= */
+--- a/src/drv_vmmc_danube.h
++++ b/src/drv_vmmc_danube.h
+@@ -15,56 +15,18 @@
+ */
+
+ #if defined SYSTEM_DANUBE
+-#include <asm/ifx/ifx_gpio.h>
++#include <lantiq_soc.h>
++
+ #else
+ #error no system selected
+ #endif
+
+-#define VMMC_TAPI_GPIO_MODULE_ID IFX_GPIO_MODULE_TAPI_VMMC
++#define VMMC_TAPI_GPIO_MODULE_ID IFX_GPIO_MODULE_TAPI_VMMC
+ /**
+
+ */
+ #define VMMC_PCM_IF_CFG_HOOK(mode, GPIOreserved, ret) \
+ do { \
+- ret = VMMC_statusOk; \
+- /* Reserve P0.0 as TDM/FSC */ \
+- if (!GPIOreserved) \
+- ret |= ifx_gpio_pin_reserve(IFX_GPIO_PIN_ID(0, 0), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_altsel0_set(IFX_GPIO_PIN_ID(0, 0), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_altsel1_set(IFX_GPIO_PIN_ID(0, 0), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_open_drain_set(IFX_GPIO_PIN_ID(0, 0), VMMC_TAPI_GPIO_MODULE_ID);\
+- \
+- /* Reserve P1.9 as TDM/DO */ \
+- if (!GPIOreserved) \
+- ret |= ifx_gpio_pin_reserve(IFX_GPIO_PIN_ID(1, 9), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_altsel0_set(IFX_GPIO_PIN_ID(1, 9), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_altsel1_clear(IFX_GPIO_PIN_ID(1, 9), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_dir_out_set(IFX_GPIO_PIN_ID(1, 9), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_open_drain_set(IFX_GPIO_PIN_ID(1, 9), VMMC_TAPI_GPIO_MODULE_ID); \
+- \
+- /* Reserve P1.10 as TDM/DI */ \
+- if (!GPIOreserved) \
+- ret |= ifx_gpio_pin_reserve(IFX_GPIO_PIN_ID(1,10), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_altsel0_clear(IFX_GPIO_PIN_ID(1,10), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_altsel1_set(IFX_GPIO_PIN_ID(1,10), VMMC_TAPI_GPIO_MODULE_ID);\
+- ret |= ifx_gpio_dir_in_set(IFX_GPIO_PIN_ID(1,10), VMMC_TAPI_GPIO_MODULE_ID); \
+- \
+- /* Reserve P1.11 as TDM/DCL */ \
+- if (!GPIOreserved) \
+- ret |= ifx_gpio_pin_reserve(IFX_GPIO_PIN_ID(1,11), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_altsel0_set(IFX_GPIO_PIN_ID(1,11), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_altsel1_clear(IFX_GPIO_PIN_ID(1,11), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_open_drain_set(IFX_GPIO_PIN_ID(1,11), VMMC_TAPI_GPIO_MODULE_ID); \
+- \
+- if (mode == 2) { \
+- /* TDM/FSC+DCL Master */ \
+- ret |= ifx_gpio_dir_out_set(IFX_GPIO_PIN_ID(0, 0), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_dir_out_set(IFX_GPIO_PIN_ID(1,11), VMMC_TAPI_GPIO_MODULE_ID); \
+- } else { \
+- /* TDM/FSC+DCL Slave */ \
+- ret |= ifx_gpio_dir_in_set(IFX_GPIO_PIN_ID(0, 0), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_dir_in_set(IFX_GPIO_PIN_ID(1,11), VMMC_TAPI_GPIO_MODULE_ID); \
+- } \
+ } while(0);
+
+ /**
+@@ -72,11 +34,6 @@
+ */
+ #define VMMC_DRIVER_UNLOAD_HOOK(ret) \
+ do { \
+- ret = VMMC_statusOk; \
+- ret |= ifx_gpio_pin_free(IFX_GPIO_PIN_ID(0, 0), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_pin_free(IFX_GPIO_PIN_ID(1, 9), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_pin_free(IFX_GPIO_PIN_ID(1,10), VMMC_TAPI_GPIO_MODULE_ID); \
+- ret |= ifx_gpio_pin_free(IFX_GPIO_PIN_ID(1,11), VMMC_TAPI_GPIO_MODULE_ID); \
+ } while (0)
+
+ #endif /* _DRV_VMMC_AMAZON_S_H */
+--- a/src/drv_vmmc_init.c
++++ b/src/drv_vmmc_init.c
+@@ -52,6 +52,14 @@
+ #include "ifx_pmu.h"
+ #endif /* PMU_SUPPORTED */
+
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28))
++# define IFX_MPS_CAD0SR IFXMIPS_MPS_CAD0SR
++# define IFX_MPS_CAD1SR IFXMIPS_MPS_CAD1SR
++# define IFX_MPS_CVC0SR IFXMIPS_MPS_CVC0SR
++# define IFX_MPS_CVC1SR IFXMIPS_MPS_CVC1SR
++# define IFX_MPS_CVC2SR IFXMIPS_MPS_CVC2SR
++# define IFX_MPS_CVC3SR IFXMIPS_MPS_CVC3SR
++#endif
+
+ /* ============================= */
+ /* Local Macros & Definitions */
+@@ -1591,7 +1599,7 @@
+ #ifdef VMMC_DRIVER_UNLOAD_HOOK
+ if (VDevices[0].nDevState & DS_GPIO_RESERVED)
+ {
+- IFX_int32_t ret;
++ IFX_int32_t ret = 0;
+ VMMC_DRIVER_UNLOAD_HOOK(ret);
+ if (!VMMC_SUCCESS(ret))
+ {
+--- a/src/drv_vmmc_init_cap.c
++++ b/src/drv_vmmc_init_cap.c
+@@ -22,6 +22,11 @@
+ #include "drv_mps_vmmc.h"
+ #include "drv_mps_vmmc_device.h"
+
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28))
++# define IFX_MPS_CHIPID_VERSION_GET IFXMIPS_MPS_CHIPID_VERSION_GET
++# define IFX_MPS_CHIPID IFXMIPS_MPS_CHIPID
++#endif
++
+ /* ============================= */
+ /* Configuration defintions */
+ /* ============================= */
+--- a/src/mps/drv_mps_vmmc_common.c
++++ b/src/mps/drv_mps_vmmc_common.c
+@@ -17,6 +17,7 @@
+ /* Includes */
+ /* ============================= */
+ #include "drv_config.h"
++#include "drv_vmmc_init.h"
+
+ #undef USE_PLAIN_VOICE_FIRMWARE
+ #undef PRINT_ON_ERR_INTERRUPT
+@@ -39,8 +40,32 @@
+ #include "ifxos_interrupt.h"
+ #include "ifxos_time.h"
+
+-#include <asm/ifx/ifx_regs.h>
+-#include <asm/ifx/ifx_gptu.h>
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28))
++# include <lantiq.h>
++# include <irq.h>
++# include <lantiq_timer.h>
++
++# define ifx_gptu_timer_request lq_request_timer
++# define ifx_gptu_timer_start lq_start_timer
++# define ifx_gptu_countvalue_get lq_get_count_value
++# define ifx_gptu_timer_free lq_free_timer
++
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
++# define bsp_mask_and_ack_irq ltq_mask_and_ack_irq
++#else
++extern void ltq_mask_and_ack_irq(struct irq_data *d);
++static void inline bsp_mask_and_ack_irq(int x)
++{
++ struct irq_data d;
++ d.hwirq = x;
++ ltq_mask_and_ack_irq(&d);
++}
++#endif
++#else
++# include <asm/ifx/ifx_regs.h>
++# include <asm/ifx/ifx_gptu.h>
++#endif
+
+ #include "drv_mps_vmmc.h"
+ #include "drv_mps_vmmc_dbg.h"
+@@ -104,6 +129,9 @@
+ extern IFX_void_t mask_and_ack_danube_irq (IFX_uint32_t irq_nr);
+
+ #endif /* */
++
++extern void sys_hw_setup (void);
++
+ extern IFXOS_event_t fw_ready_evt;
+ /* callback function to free all data buffers currently used by voice FW */
+ IFX_void_t (*ifx_mps_bufman_freeall)(IFX_void_t) = IFX_NULL;
+@@ -207,7 +235,8 @@
+ */
+ IFX_void_t *ifx_mps_fastbuf_malloc (IFX_size_t size, IFX_int32_t priority)
+ {
+- IFX_uint32_t ptr, flags;
++ IFXOS_INTSTAT flags;
++ IFX_uint32_t ptr;
+ IFX_int32_t index = fastbuf_index;
+
+ if (fastbuf_initialized == 0)
+@@ -261,7 +290,7 @@
+ */
+ IFX_void_t ifx_mps_fastbuf_free (const IFX_void_t * ptr)
+ {
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+ IFX_int32_t index = fastbuf_index;
+
+ IFXOS_LOCKINT (flags);
+@@ -457,7 +486,7 @@
+ */
+ static IFX_int32_t ifx_mps_bufman_inc_level (IFX_uint32_t value)
+ {
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+
+ if (mps_buffer.buf_level + value > MPS_BUFFER_MAX_LEVEL)
+ {
+@@ -484,7 +513,7 @@
+ */
+ static IFX_int32_t ifx_mps_bufman_dec_level (IFX_uint32_t value)
+ {
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+
+ if (mps_buffer.buf_level < value)
+ {
+@@ -636,7 +665,7 @@
+ mem_seg_ptr[i] =
+ (IFX_uint32_t *) CPHYSADDR ((IFX_uint32_t) mps_buffer.
+ malloc (segment_size, FASTBUF_FW_OWNED));
+- if (mem_seg_ptr[i] == CPHYSADDR (IFX_NULL))
++ if (mem_seg_ptr[i] == (IFX_uint32_t *)CPHYSADDR (IFX_NULL))
+ {
+ TRACE (MPS, DBG_LEVEL_HIGH,
+ ("%s(): cannot allocate buffer\n", __FUNCTION__));
+@@ -952,7 +981,7 @@
+ mps_mbx_dev * pMBDev, IFX_int32_t bcommand,
+ IFX_boolean_t from_kernel)
+ {
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+
+ IFXOS_LOCKINT (flags);
+
+@@ -1068,7 +1097,7 @@
+ IFX_void_t ifx_mps_release_structures (mps_comm_dev * pDev)
+ {
+ IFX_int32_t count;
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+
+ IFXOS_LOCKINT (flags);
+ IFXOS_BlockFree (pFW_img_data);
+@@ -1117,7 +1146,7 @@
+
+ /* Initialize MPS main structure */
+ memset ((IFX_void_t *) pDev, 0, sizeof (mps_comm_dev));
+- pDev->base_global = (mps_mbx_reg *) IFX_MPS_SRAM;
++ pDev->base_global = (mps_mbx_reg *) IFXMIPS_MPS_SRAM;
+ pDev->flags = 0x00000000;
+ MBX_Memory = pDev->base_global;
+
+@@ -1125,9 +1154,11 @@
+ for MBX communication. These are: mailbox base address, mailbox size, *
+ mailbox read index and mailbox write index. for command and voice
+ mailbox, * upstream and downstream direction. */
+- memset ((IFX_void_t *) MBX_Memory, /* avoid to overwrite CPU boot
+- registers */
+- 0, sizeof (mps_mbx_reg) - 2 * sizeof (mps_boot_cfg_reg));
++ memset (
++ /* avoid to overwrite CPU boot registers */
++ (IFX_void_t *) MBX_Memory,
++ 0,
++ sizeof (mps_mbx_reg) - 2 * sizeof (mps_boot_cfg_reg));
+ MBX_Memory->MBX_UPSTR_CMD_BASE =
+ (IFX_uint32_t *) CPHYSADDR ((IFX_uint32_t) MBX_UPSTRM_CMD_FIFO_BASE);
+ MBX_Memory->MBX_UPSTR_CMD_SIZE = MBX_CMD_FIFO_SIZE;
+@@ -1564,7 +1595,7 @@
+ IFX_uint32_t * bytes)
+ {
+ IFX_int32_t i, ret;
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+
+ IFXOS_LOCKINT (flags);
+
+@@ -1774,7 +1805,7 @@
+ {
+ mps_fifo *mbx;
+ IFX_uint32_t i;
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+ IFX_int32_t retval = -EAGAIN;
+ IFX_int32_t retries = 0;
+ IFX_uint32_t word = 0;
+@@ -2169,6 +2200,7 @@
+ TRACE (MPS, DBG_LEVEL_HIGH,
+ ("%s(): Invalid device ID %d !\n", __FUNCTION__, pMBDev->devID));
+ }
++
+ return retval;
+ }
+
+@@ -2192,7 +2224,7 @@
+ mps_mbx_dev *mbx_dev;
+ MbxMsg_s msg;
+ IFX_uint32_t bytes_read = 0;
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+ IFX_int32_t ret;
+
+ /* set pointer to data upstream mailbox, no matter if 0,1,2 or 3 because
+@@ -2283,7 +2315,7 @@
+ {
+ ifx_mps_bufman_dec_level (1);
+ if ((ifx_mps_bufman_get_level () <= mps_buffer.buf_threshold) &&
+- (atomic_read (&pMPSDev->provide_buffer->object.count) == 0))
++ ((volatile unsigned int)pMPSDev->provide_buffer->object.count == 0))
+ {
+ IFXOS_LockRelease (pMPSDev->provide_buffer);
+ }
+@@ -2326,7 +2358,7 @@
+ #endif /* CONFIG_PROC_FS */
+ ifx_mps_bufman_dec_level (1);
+ if ((ifx_mps_bufman_get_level () <= mps_buffer.buf_threshold) &&
+- (atomic_read (&pMPSDev->provide_buffer->object.count) == 0))
++ ((volatile unsigned int)pMPSDev->provide_buffer->object.count == 0))
+ {
+ IFXOS_LockRelease (pMPSDev->provide_buffer);
+ }
+@@ -2356,7 +2388,7 @@
+ IFX_void_t ifx_mps_mbx_cmd_upstream (IFX_ulong_t dummy)
+ {
+ mps_fifo *mbx;
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+
+ /* set pointer to upstream command mailbox */
+ mbx = &(pMPSDev->cmd_upstrm_fifo);
+@@ -2404,7 +2436,7 @@
+ mps_event_msg msg;
+ IFX_int32_t length = 0;
+ IFX_int32_t read_length = 0;
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+
+ /* set pointer to upstream event mailbox */
+ mbx = &(pMPSDev->event_upstrm_fifo);
+@@ -2619,6 +2651,7 @@
+ #endif
+
+ *IFX_MPS_AD0ENR = Ad0Reg.val;
++
+ }
+
+ /**
+@@ -2647,7 +2680,7 @@
+ */
+ IFX_void_t ifx_mps_dd_mbx_int_enable (IFX_void_t)
+ {
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+ MPS_Ad0Reg_u Ad0Reg;
+
+ IFXOS_LOCKINT (flags);
+@@ -2673,7 +2706,7 @@
+ */
+ IFX_void_t ifx_mps_dd_mbx_int_disable (IFX_void_t)
+ {
+- IFX_uint32_t flags;
++ IFXOS_INTSTAT flags;
+ MPS_Ad0Reg_u Ad0Reg;
+
+ IFXOS_LOCKINT (flags);
+@@ -2738,7 +2771,6 @@
+ #else /* */
+ mask_and_ack_danube_irq (irq);
+ #endif /* */
+-
+ /* FW is up and ready to process commands */
+ if (MPS_Ad0StatusReg.fld.dl_end)
+ {
+@@ -2800,6 +2832,7 @@
+ }
+ }
+
++
+ if (MPS_Ad0StatusReg.fld.du_mbx)
+ {
+ #ifdef CONFIG_PROC_FS
+@@ -2944,12 +2977,12 @@
+ IFX_MPS_CVC0SR[chan] = MPS_VCStatusReg.val;
+ /* handle only enabled interrupts */
+ MPS_VCStatusReg.val &= IFX_MPS_VC0ENR[chan];
+-
+ #ifdef LINUX_2_6
+ bsp_mask_and_ack_irq (irq);
+ #else /* */
+ mask_and_ack_danube_irq (irq);
+ #endif /* */
++
+ pMPSDev->event.MPS_VCStatReg[chan].val = MPS_VCStatusReg.val;
+ #ifdef PRINT_ON_ERR_INTERRUPT
+ if (MPS_VCStatusReg.fld.rcv_ov)
+@@ -3093,7 +3126,8 @@
+ */
+ IFX_return_t ifx_mps_init_gpt ()
+ {
+- IFX_uint32_t flags, timer_flags, timer, loops = 0;
++ unsigned long flags;
++ IFX_uint32_t timer_flags, timer, loops = 0;
+ IFX_ulong_t count;
+ #if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
+ timer = TIMER1A;
+@@ -3166,6 +3200,7 @@
+ #else /* Danube */
+ timer = TIMER1B;
+ #endif /* SYSTEM_AR9 || SYSTEM_VR9 */
++
+ ifx_gptu_timer_free (timer);
+ }
+
+--- a/src/mps/drv_mps_vmmc_danube.c
++++ b/src/mps/drv_mps_vmmc_danube.c
+@@ -16,6 +16,7 @@
+ /* ============================= */
+ /* Includes */
+ /* ============================= */
++#include "linux/version.h"
+ #include "drv_config.h"
+
+ #ifdef SYSTEM_DANUBE /* defined in drv_mps_vmmc_config.h */
+@@ -36,9 +37,22 @@
+ #include "ifxos_select.h"
+ #include "ifxos_interrupt.h"
+
+-#include <asm/ifx/ifx_regs.h>
+-#include <asm/ifx/ifx_gpio.h>
+-#include <asm/ifx/common_routines.h>
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28))
++# include <lantiq.h>
++# include <irq.h>
++# include <lantiq_timer.h>
++# include <linux/dma-mapping.h>
++
++
++#define LQ_RCU_BASE_ADDR (KSEG1 + LTQ_RCU_BASE_ADDR)
++# define LQ_RCU_RST ((u32 *)(LQ_RCU_BASE_ADDR + 0x0010))
++#define IFX_RCU_RST_REQ_CPU1 (1 << 3)
++# define IFX_RCU_RST_REQ LQ_RCU_RST
++#else
++# include <asm/ifx/ifx_regs.h>
++# include <asm/ifx_vpe.h>
++# include <asm/ifx/ifx_gpio.h>
++#endif
+
+ #include "drv_mps_vmmc.h"
+ #include "drv_mps_vmmc_dbg.h"
+@@ -75,6 +89,20 @@
+ /* Local function definition */
+ /* ============================= */
+
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28))
++IFX_uint32_t ifx_get_cp1_size(IFX_void_t)
++{
++ return 1;
++}
++
++unsigned int *ltq_get_cp1_base(void);
++
++IFX_uint32_t *ifx_get_cp1_base(IFX_void_t)
++{
++ return ltq_get_cp1_base();
++}
++#endif
++
+ /******************************************************************************
+ * DANUBE Specific Routines
+ ******************************************************************************/
+@@ -134,6 +162,15 @@
+ }
+
+ /* check if FW image fits in available memory space */
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28))
++ if (mem > ifx_get_cp1_size()<<20)
++ {
++ TRACE (MPS, DBG_LEVEL_HIGH,
++ ("[%s %s %d]: error, firmware memory exceeds reserved space (%i > %i)!\n",
++ __FILE__, __func__, __LINE__, mem, ifx_get_cp1_size()<<20));
++ return IFX_ERROR;
++ }
++#else
+ if (mem > ifx_get_cp1_size())
+ {
+ TRACE (MPS, DBG_LEVEL_HIGH,
+@@ -141,6 +178,7 @@
+ __FILE__, __func__, __LINE__, mem, ifx_get_cp1_size()));
+ return IFX_ERROR;
+ }
++#endif
+
+ /* reset the driver */
+ ifx_mps_reset ();
+@@ -361,7 +399,7 @@
+ */
+ IFX_void_t ifx_mps_wdog_expiry()
+ {
+- IFX_uint32_t flags;
++ unsigned long flags;
+
+ IFXOS_LOCKINT (flags);
+ /* recalculate and compare the firmware checksum */
+--- a/src/mps/drv_mps_vmmc_device.h
++++ b/src/mps/drv_mps_vmmc_device.h
+@@ -16,8 +16,58 @@
+ declarations.
+ *******************************************************************************/
+
+-#include <asm/ifx/ifx_regs.h>
+-#include <asm/ifx_vpe.h>
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28))
++# include <lantiq.h>
++# include <irq.h>
++# include <lantiq_soc.h>
++# include <gpio.h>
++#define IFXMIPS_MPS_SRAM ((u32 *)(KSEG1 + 0x1F200000))
++#define IFXMIPS_MPS_BASE_ADDR (KSEG1 + 0x1F107000)
++#define IFXMIPS_MPS_CHIPID ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0344))
++#define IFXMIPS_MPS_VC0ENR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0000))
++#define IFXMIPS_MPS_RVC0SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0010))
++#define IFXMIPS_MPS_CVC0SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0030))
++#define IFXMIPS_MPS_CVC1SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0034))
++#define IFXMIPS_MPS_CVC2SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0038))
++#define IFXMIPS_MPS_CVC3SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x003C))
++#define IFXMIPS_MPS_RAD0SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0040))
++#define IFXMIPS_MPS_RAD1SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0044))
++#define IFXMIPS_MPS_SAD0SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0048))
++#define IFXMIPS_MPS_SAD1SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x004C))
++#define IFXMIPS_MPS_CAD0SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0050))
++#define IFXMIPS_MPS_CAD1SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0054))
++#define IFXMIPS_MPS_AD0ENR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0058))
++#define IFXMIPS_MPS_AD1ENR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x005C))
++
++#define IFXMIPS_MPS_CHIPID_VERSION_GET(value) (((value) >> 28) & ((1 << 4) - 1))
++#define IFXMIPS_MPS_CHIPID_VERSION_SET(value) ((((1 << 4) - 1) & (value)) << 28)
++#define IFXMIPS_MPS_CHIPID_PARTNUM_GET(value) (((value) >> 12) & ((1 << 16) - 1))
++#define IFXMIPS_MPS_CHIPID_PARTNUM_SET(value) ((((1 << 16) - 1) & (value)) << 12)
++#define IFXMIPS_MPS_CHIPID_MANID_GET(value) (((value) >> 1) & ((1 << 10) - 1))
++#define IFXMIPS_MPS_CHIPID_MANID_SET(value) ((((1 << 10) - 1) & (value)) << 1)
++#else
++# include <asm/ifx/ifx_regs.h>
++# include <asm/ifx_vpe.h>
++#endif
++/* MPS register */
++# define IFX_MPS_AD0ENR IFXMIPS_MPS_AD0ENR
++# define IFX_MPS_AD1ENR IFXMIPS_MPS_AD1ENR
++# define IFX_MPS_RAD0SR IFXMIPS_MPS_RAD0SR
++# define IFX_MPS_RAD1SR IFXMIPS_MPS_RAD1SR
++# define IFX_MPS_VC0ENR IFXMIPS_MPS_VC0ENR
++# define IFX_MPS_RVC0SR IFXMIPS_MPS_RVC0SR
++# define IFX_MPS_CVC0SR IFXMIPS_MPS_CVC0SR
++# define IFX_MPS_CAD0SR IFXMIPS_MPS_CAD0SR
++# define IFX_MPS_CAD1SR IFXMIPS_MPS_CAD1SR
++# define IFX_MPS_CVC1SR IFXMIPS_MPS_CVC1SR
++# define IFX_MPS_CVC2SR IFXMIPS_MPS_CVC2SR
++# define IFX_MPS_CVC3SR IFXMIPS_MPS_CVC3SR
++# define IFX_MPS_SAD0SR IFXMIPS_MPS_SAD0SR
++/* interrupt vectors */
++# define INT_NUM_IM4_IRL14 (INT_NUM_IM4_IRL0 + 14)
++# define INT_NUM_IM4_IRL18 (INT_NUM_IM4_IRL0 + 18)
++# define INT_NUM_IM4_IRL19 (INT_NUM_IM4_IRL0 + 19)
++# define IFX_ICU_IM4_IER IFXMIPS_ICU_IM4_IER
+
+ /* ============================= */
+ /* MPS Common defines */
+@@ -26,32 +76,28 @@
+ #define MPS_BASEADDRESS 0xBF107000
+ #define MPS_RAD0SR MPS_BASEADDRESS + 0x0004
+
+-#define MPS_RAD0SR_DU (1<<0)
+-#define MPS_RAD0SR_CU (1<<1)
+-
+ #define MBX_BASEADDRESS 0xBF200000
+ #define VCPU_BASEADDRESS 0xBF208000 /* 0xBF108000 */
+ /*---------------------------------------------------------------------------*/
++#if !defined(CONFIG_LANTIQ)
++/* enabling interrupts is done with request_irq by the BSP
++ The related code should not be needed anymore */
+ #if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
+ /* TODO: doublecheck - IM4 or different! */
+ #define MPS_INTERRUPTS_ENABLE(X) *((volatile IFX_uint32_t*) IFX_ICU_IM4_IER) |= X;
+ #define MPS_INTERRUPTS_DISABLE(X) *((volatile IFX_uint32_t*) IFX_ICU_IM4_IER) &= ~X;
+-#define MPS_INTERRUPTS_CLEAR(X) *((volatile IFX_uint32_t*) IFX_ICU_IM4_ISR) = X;
+-#define MPS_INTERRUPTS_SET(X) *((volatile IFX_uint32_t*) IFX_ICU_IM4_IRSR) = X;/* |= ? */
+ #else /* Danube */
+ /* TODO: possibly needs to be changed to IM4 !!!!!! */
+ #ifdef LINUX_2_6
+ #define MPS_INTERRUPTS_ENABLE(X) *((volatile IFX_uint32_t*) IFX_ICU_IM4_IER) |= X;
+ #define MPS_INTERRUPTS_DISABLE(X) *((volatile IFX_uint32_t*) IFX_ICU_IM4_IER) &= ~X;
+-#define MPS_INTERRUPTS_CLEAR(X) *((volatile IFX_uint32_t*) IFX_ICU_IM4_ISR) = X;
+-#define MPS_INTERRUPTS_SET(X) *((volatile IFX_uint32_t*) IFX_ICU_IM4_IRSR) = X;/* |= ? */
+ #else /* */
+ #define MPS_INTERRUPTS_ENABLE(X) *((volatile IFX_uint32_t*) DANUBE_ICU_IM5_IER) |= X;
+ #define MPS_INTERRUPTS_DISABLE(X) *((volatile IFX_uint32_t*) DANUBE_ICU_IM5_IER) &= ~X;
+-#define MPS_INTERRUPTS_CLEAR(X) *((volatile IFX_uint32_t*) DANUBE_ICU_IM5_ISR) = X;
+-#define MPS_INTERRUPTS_SET(X) *((volatile IFX_uint32_t*) DANUBE_ICU_IM5_IRSR) = X;/* |= ? */
+ #endif /* LINUX_2_6 */
+ #endif /* SYSTEM_AR9 || SYSTEM_VR9 */
++#endif /* !defined(CONFIG_LANTIQ) */
++
+ /*---------------------------------------------------------------------------*/
+
+ /*---------------------------------------------------------------------------*/
+@@ -142,53 +188,9 @@
+ #if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
+ /* ***** Amazon-S specific defines ***** */
+ #define IFX_MPS_Base AMAZON_S_MPS
+-
+-//#define IFX_MPS_CHIPID AMAZON_S_MPS_CHIPID
+-//#define IFX_MPS_CHIPID_VERSION_GET AMAZON_S_MPS_CHIPID_VERSION_GET
+-
+-//#define IFX_MPS_AD0ENR AMAZON_S_MPS_AD0ENR
+-//#define IFX_MPS_AD1ENR AMAZON_S_MPS_AD1ENR
+-//#define IFX_MPS_VC0ENR AMAZON_S_MPS_VC0ENR
+-//#define IFX_MPS_SAD0SR AMAZON_S_MPS_SAD0SR
+-//#define IFX_MPS_RAD0SR AMAZON_S_MPS_RAD0SR
+-//#define IFX_MPS_CAD0SR AMAZON_S_MPS_CAD0SR
+-//#define IFX_MPS_RAD1SR AMAZON_S_MPS_RAD1SR
+-//#define IFX_MPS_CAD1SR AMAZON_S_MPS_CAD1SR
+-//#define IFX_MPS_RVC0SR AMAZON_S_MPS_RVC0SR
+-//#define IFX_MPS_CVC0SR AMAZON_S_MPS_CVC0SR
+-//#define IFX_MPS_CVC1SR AMAZON_S_MPS_CVC1SR
+-//#define IFX_MPS_CVC2SR AMAZON_S_MPS_CVC2SR
+-//#define IFX_MPS_CVC3SR AMAZON_S_MPS_CVC3SR
+-
+-//#define IFX_MPS_SRAM AMAZON_S_MPS_SRAM
+ #else /* */
+ /* ***** DANUBE specific defines ***** */
+ #define IFX_MPS_Base DANUBE_MPS
+-
+-//#define IFX_MPS_CHIPID DANUBE_MPS_CHIPID
+-//#define IFX_MPS_CHIPID_VERSION_GET DANUBE_MPS_CHIPID_VERSION_GET
+-//#define IFX_MPS_CHIPID_VERSION_SET DANUBE_MPS_CHIPID_VERSION_SET
+-//#define IFX_MPS_CHIPID_PARTNUM_GET DANUBE_MPS_CHIPID_PARTNUM_GET
+-//#define IFX_MPS_CHIPID_PARTNUM_SET DANUBE_MPS_CHIPID_PARTNUM_SET
+-//#define IFX_MPS_CHIPID_MANID_GET DANUBE_MPS_CHIPID_MANID_GET
+-//#define IFX_MPS_CHIPID_MANID_SET DANUBE_MPS_CHIPID_MANID_SET
+-//#define IFX_MPS_SUBVER DANUBE_MPS_SUBVER
+-
+-//#define IFX_MPS_AD0ENR DANUBE_MPS_AD0ENR
+-//#define IFX_MPS_AD1ENR DANUBE_MPS_AD1ENR
+-//#define IFX_MPS_VC0ENR DANUBE_MPS_VC0ENR
+-//#define IFX_MPS_SAD0SR DANUBE_MPS_SAD0SR
+-//#define IFX_MPS_RAD0SR DANUBE_MPS_RAD0SR
+-//#define IFX_MPS_CAD0SR DANUBE_MPS_CAD0SR
+-//#define IFX_MPS_RAD1SR DANUBE_MPS_RAD1SR
+-//#define IFX_MPS_CAD1SR DANUBE_MPS_CAD1SR
+-//#define IFX_MPS_RVC0SR DANUBE_MPS_RVC0SR
+-//#define IFX_MPS_CVC0SR DANUBE_MPS_CVC0SR
+-//#define IFX_MPS_CVC1SR DANUBE_MPS_CVC1SR
+-//#define IFX_MPS_CVC2SR DANUBE_MPS_CVC2SR
+-//#define IFX_MPS_CVC3SR DANUBE_MPS_CVC3SR
+-
+-//#define IFX_MPS_SRAM DANUBE_MPS_SRAM
+ #endif /* SYSTEM_AR9 || SYSTEM_VR9 */
+ typedef enum
+ {
+--- a/src/mps/drv_mps_vmmc_linux.c
++++ b/src/mps/drv_mps_vmmc_linux.c
+@@ -57,10 +57,11 @@
+ #include <linux/moduleparam.h>
+ #endif /* */
+
+-
++#if !defined CONFIG_LANTIQ
+ #include <asm/ifx/irq.h>
+ #include <asm/ifx/ifx_regs.h>
+ #include <asm/ifx_vpe.h>
++#endif
+
+ /* lib_ifxos headers */
+ #include "ifx_types.h"
+@@ -959,7 +960,7 @@
+ #endif /* MPS_FIFO_BLOCKING_WRITE */
+ case FIO_MPS_GET_STATUS:
+ {
+- IFX_uint32_t flags;
++ unsigned long flags;
+
+ /* get the status of the channel */
+ if (!from_kernel)
+@@ -993,7 +994,7 @@
+ #if CONFIG_MPS_HISTORY_SIZE > 0
+ case FIO_MPS_GET_CMD_HISTORY:
+ {
+- IFX_uint32_t flags;
++ unsigned long flags;
+
+ if (from_kernel)
+ {
+@@ -1685,6 +1686,7 @@
+ sprintf (buf + len, " minLv: \t %8d\n",
+ ifx_mps_dev.voice_mb[i].upstrm_fifo->min_space);
+ }
++
+ return len;
+ }
+
+@@ -2291,9 +2293,11 @@
+ return result;
+ }
+
++#if !defined(CONFIG_LANTIQ)
++ /** \todo This is handled already with request_irq, remove */
+ /* Enable all MPS Interrupts at ICU0 */
+ MPS_INTERRUPTS_ENABLE (0x0000FF80);
+-
++#endif
+ /* enable mailbox interrupts */
+ ifx_mps_enable_mailbox_int ();
+ /* init FW ready event */
+@@ -2421,9 +2425,11 @@
+ /* disable mailbox interrupts */
+ ifx_mps_disable_mailbox_int ();
+
++#if !defined(CONFIG_LANTIQ)
+ /* disable Interrupts at ICU0 */
+- MPS_INTERRUPTS_DISABLE (DANUBE_MPS_AD0_IR4); /* Disable DFE/AFE 0 Interrupts
+- */
++ /* Disable DFE/AFE 0 Interrupts*/
++ MPS_INTERRUPTS_DISABLE (DANUBE_MPS_AD0_IR4);
++#endif
+
+ /* disable all MPS interrupts */
+ ifx_mps_disable_all_int ();
+--- a/src/drv_vmmc_ioctl.c
++++ b/src/drv_vmmc_ioctl.c
+@@ -18,6 +18,7 @@
+ /* Includes */
+ /* ============================= */
+ #include "drv_api.h"
++#include "drv_vmmc_init.h"
+ #include "drv_vmmc_api.h"
+ #include "drv_vmmc_bbd.h"
+
+Index: drv_vmmc-1.9.0/src/mps/drv_mps_vmmc_danube.c
+===================================================================
+--- drv_vmmc-1.9.0.orig/src/mps/drv_mps_vmmc_danube.c 2012-12-13 08:43:16.080109377 +0100
++++ drv_vmmc-1.9.0/src/mps/drv_mps_vmmc_danube.c 2012-12-13 08:43:48.584110192 +0100
+@@ -44,7 +44,7 @@
+ # include <linux/dma-mapping.h>
+
+
+-#define LQ_RCU_BASE_ADDR (KSEG1 + LTQ_RCU_BASE_ADDR)
++#define LQ_RCU_BASE_ADDR (KSEG1 + 0x1F203000)
+ # define LQ_RCU_RST ((u32 *)(LQ_RCU_BASE_ADDR + 0x0010))
+ #define IFX_RCU_RST_REQ_CPU1 (1 << 3)
+ # define IFX_RCU_RST_REQ LQ_RCU_RST
diff --git a/package/kernel/lantiq/ltq-vmmc/patches/400-falcon.patch b/package/kernel/lantiq/ltq-vmmc/patches/400-falcon.patch
new file mode 100644
index 0000000000..490d6e5dc9
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vmmc/patches/400-falcon.patch
@@ -0,0 +1,968 @@
+--- a/configure.in
++++ b/configure.in
+@@ -956,14 +956,15 @@ AC_DEFINE([VMMC],[1],[enable VMMC suppor
+ AM_CONDITIONAL(DANUBE, false)
+ AM_CONDITIONAL(AR9, false)
+ AM_CONDITIONAL(VR9, false)
++AM_CONDITIONAL(FALCON, false)
+ AC_ARG_WITH(device,
+ AC_HELP_STRING(
+- [--with-device=DANUBE|TWINPASS|AR9|VR9],
++ [--with-device=DANUBE|TWINPASS|AR9|VR9|FALCON],
+ [Set device type, default is DANUBE]
+ ),
+ [
+ if test "$withval" = yes; then
+- AC_MSG_ERROR([Set device type! Valid choices are DANUBE|TWINPASS|AR9|VR9]);
++ AC_MSG_ERROR([Set device type! Valid choices are DANUBE|TWINPASS|AR9|VR9|FALCON]);
+ else
+ case $withval in
+ DANUBE)
+@@ -986,8 +987,13 @@ AC_ARG_WITH(device,
+ AC_DEFINE([SYSTEM_VR9],[1],[enable VR9 specific code])
+ AM_CONDITIONAL(VR9, true)
+ ;;
++ FALCON)
++ AC_MSG_RESULT(FALCON device is used);
++ AC_DEFINE([SYSTEM_FALCON],[1],[enable FALCON specific code])
++ AM_CONDITIONAL(FALCON, true)
++ ;;
+ *)
+- AC_MSG_ERROR([Set device type! Valid choices are DANUBE|TWINPASS|AR9|VR9]);
++ AC_MSG_ERROR([Set device type! Valid choices are DANUBE|TWINPASS|AR9|VR9|FALCON]);
+ ;;
+ esac
+ fi
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -70,6 +70,11 @@ drv_vmmc_SOURCES +=\
+ mps/drv_mps_vmmc_ar9.c
+ endif
+
++if FALCON
++drv_vmmc_SOURCES +=\
++ mps/drv_mps_vmmc_falcon.c
++endif
++
+ endif
+
+ if PMC_SUPPORT
+--- a/drv_version.h
++++ b/drv_version.h
+@@ -36,6 +36,10 @@
+ #define MIN_FW_MAJORSTEP 2
+ #define MIN_FW_MINORSTEP 1
+ #define MIN_FW_HOTFIXSTEP 0
++#elif defined(SYSTEM_FALCON)
++#define MIN_FW_MAJORSTEP 0
++#define MIN_FW_MINORSTEP 1
++#define MIN_FW_HOTFIXSTEP 0
+ #else
+ #error unknown system
+ #endif
+--- a/src/drv_vmmc_bbd.c
++++ b/src/drv_vmmc_bbd.c
+@@ -34,6 +34,7 @@
+ #define VMMC_WL_SDD_BASIC_CFG 0x04000400
+ #define VMMC_WL_SDD_RING_CFG 0x04000500
+ #define VMMC_WL_SDD_DCDC_CFG 0x04000C00
++#define VMMC_WL_SDD_MWI_CFG 0x04000600
+
+ #define IDLE_EXT_TOGGLE_SLEEP_MS 5
+
+@@ -52,6 +53,8 @@
+ #define BBD_VMMC_MAGIC 0x41523921 /* "AR9" */
+ #elif defined(SYSTEM_VR9)
+ #define BBD_VMMC_MAGIC 0x56523921 /* "VR9" */
++#elif defined(SYSTEM_FALCON)
++#define BBD_VMMC_MAGIC 0x46414C43 /* "FALC" */
+ #else
+ #error system undefined
+ #endif
+@@ -525,9 +528,6 @@ static IFX_int32_t VMMC_BBD_BlockHandler
+ IFX_uint16_t slic_val;
+ IFX_int32_t ret = IFX_SUCCESS;
+
+- TRACE(VMMC, DBG_LEVEL_LOW,
+- ("bbd block with tag 0x%04X passed\n", pBBDblock->tag));
+-
+ /* for FXO line allowed blocks are FXO_CRAM and TRANSPARENT */
+ if (pCh->pALM->line_type_fxs != IFX_TRUE)
+ {
+@@ -686,6 +686,7 @@ static IFX_int32_t VMMC_BBD_BlockHandler
+ break;
+ }
+ } /* if */
++
+ return ret;
+ }
+
+@@ -1026,6 +1027,7 @@ static IFX_int32_t vmmc_BBD_WhiteListedC
+ }
+ case VMMC_WL_SDD_RING_CFG:
+ case VMMC_WL_SDD_DCDC_CFG:
++ case VMMC_WL_SDD_MWI_CFG:
+ ret = CmdWrite (pCh->pParent, Msg.val, Msg.cmd.LENGTH);
+ break;
+
+@@ -1068,7 +1070,7 @@ static IFX_int32_t vmmc_BBD_DownloadChCr
+ IFX_uint32_t countWords;
+ IFX_uint32_t posBytes = 0;
+ IFX_uint8_t lenBytes, *pByte;
+-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ IFX_uint8_t padBytes = 0;
+ #endif
+ IFX_uint16_t cram_offset, cram_crc,
+@@ -1088,7 +1090,7 @@ static IFX_int32_t vmmc_BBD_DownloadChCr
+ #ifdef SYSTEM_DANUBE
+ /* CMD1 is a COP command */
+ pCmd[0] = (0x0200) | (pCh->nChannel - 1);
+-#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ /* SDD_Coef command */
+ pCmd[0] = (0x0400) | (pCh->nChannel - 1);
+ pCmd[1] = (0x0D00);
+@@ -1111,7 +1113,7 @@ static IFX_int32_t vmmc_BBD_DownloadChCr
+ pCmd[1] = ((cram_offset + (posBytes >> 1)) << 8);
+ /* set CRAM data while taking care of endianess */
+ cpb2w (&pCmd[2], &pByte[posBytes], lenBytes);
+-#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ /* calculate length to download (in words = 16bit),
+ maximum allowed length for this message is 56 Bytes = 28 Words */
+ if (countWords > ((MAX_CMD_WORD - CMD_HDR_CNT - 1)))
+@@ -1140,7 +1142,7 @@ static IFX_int32_t vmmc_BBD_DownloadChCr
+ /* write Data */
+ #if defined SYSTEM_DANUBE
+ ret = CmdWrite (pCh->pParent, (IFX_uint32_t *) pCmd, lenBytes);
+-#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ #if 1
+ /* lenBytes + 2 bytes for block offset/length which are not calculated
+ in the download progress */
+--- a/src/mps/drv_mps_version.h
++++ b/src/mps/drv_mps_version.h
+@@ -17,7 +17,7 @@
+ #define VERSIONSTEP 2
+ #define VERS_TYPE 5
+
+-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ #define IFX_MPS_PLATFORM_NAME "MIPS34KEc"
+ #elif defined(SYSTEM_DANUBE)
+ #define IFX_MPS_PLATFORM_NAME "MIPS24KEc"
+--- a/src/mps/drv_mps_vmmc_linux.c
++++ b/src/mps/drv_mps_vmmc_linux.c
+@@ -2225,7 +2225,7 @@ IFX_int32_t __init ifx_mps_init_module (
+ #if defined(CONFIG_MIPS) && !defined(CONFIG_MIPS_UNCACHED)
+ #if defined(SYSTEM_DANUBE)
+ bDoCacheOps = IFX_TRUE; /* on Danube always perform cache ops */
+-#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ /* on AR9/VR9 cache is configured by BSP;
+ here we check whether the D-cache is shared or partitioned;
+ 1) in case of shared D-cache all cache operations are omitted;
+@@ -2255,7 +2255,8 @@ IFX_int32_t __init ifx_mps_init_module (
+
+ /* reset the device before initializing the device driver */
+ ifx_mps_reset ();
+- result = request_irq (INT_NUM_IM4_IRL18,
++
++ result = request_irq (INT_NUM_IM4_IRL18,
+ #ifdef LINUX_2_6
+ ifx_mps_ad0_irq, IRQF_DISABLED
+ #else /* */
+@@ -2396,7 +2397,7 @@ IFX_int32_t __init ifx_mps_init_module (
+ if (result = ifx_mps_init_gpt_danube ())
+ return result;
+ #endif /*DANUBE*/
+- TRACE (MPS, DBG_LEVEL_HIGH, ("Downloading Firmware...\n"));
++ TRACE (MPS, DBG_LEVEL_HIGH, ("Downloading Firmware...\n"));
+ ifx_mps_download_firmware (IFX_NULL, (mps_fw *) 0xa0a00000);
+ udelay (500);
+ TRACE (MPS, DBG_LEVEL_HIGH, ("Providing Buffers...\n"));
+--- /dev/null
++++ b/src/mps/drv_mps_vmmc_falcon.c
+@@ -0,0 +1,463 @@
++/******************************************************************************
++
++ Copyright (c) 2009
++ Lantiq Deutschland GmbH
++ Am Campeon 3; 85579 Neubiberg, Germany
++
++ For licensing information, see the file 'LICENSE' in the root folder of
++ this software module.
++
++****************************************************************************
++ Module : drv_mps_vmmc_falcon.c
++ Description : This file contains the implementation of the FALC-ON specific
++ driver functions.
++*******************************************************************************/
++
++/* ============================= */
++/* Includes */
++/* ============================= */
++#include "drv_config.h"
++
++#if defined(SYSTEM_FALCON) /* defined in drv_config.h */
++
++/* lib_ifxos headers */
++#include "ifx_types.h"
++#include "ifxos_linux_drv.h"
++#include "ifxos_copy_user_space.h"
++#include "ifxos_event.h"
++#include "ifxos_lock.h"
++#include "ifxos_select.h"
++#include "ifxos_interrupt.h"
++#include <linux/gpio.h>
++#include <sys1_reg.h>
++#include <falcon.h>
++#include <falcon_irq.h>
++#include <vpe.h>
++#include <sysctrl.h>
++void (*ifx_bsp_basic_mps_decrypt)(unsigned int addr, int n) = (void (*)(unsigned int, int))0xbf000290;
++
++#define IFX_MPS_SRAM IFXMIPS_MPS_SRAM
++
++/*#define USE_PLAIN_VOICE_FIRMWARE*/
++/* board specific headers */
++
++/* device specific headers */
++#include "drv_mps_vmmc.h"
++#include "drv_mps_vmmc_dbg.h"
++#include "drv_mps_vmmc_device.h"
++
++/* ============================= */
++/* Local Macros & Definitions */
++/* ============================= */
++/* Firmware watchdog timer counter address */
++#define VPE1_WDOG_CTR_ADDR ((IFX_uint32_t)((IFX_uint8_t* )IFX_MPS_SRAM + 432))
++
++/* Firmware watchdog timeout range, values in ms */
++#define VPE1_WDOG_TMOUT_MIN 20
++#define VPE1_WDOG_TMOUT_MAX 5000
++
++/* ============================= */
++/* Global variable definition */
++/* ============================= */
++extern mps_comm_dev *pMPSDev;
++
++/* ============================= */
++/* Global function declaration */
++/* ============================= */
++IFX_void_t ifx_mps_release (IFX_void_t);
++extern IFX_uint32_t ifx_mps_reset_structures (mps_comm_dev * pMPSDev);
++extern IFX_int32_t ifx_mps_bufman_close (IFX_void_t);
++IFX_int32_t ifx_mps_wdog_callback (IFX_uint32_t wdog_cleared_ok_count);
++extern IFXOS_event_t fw_ready_evt;
++/* ============================= */
++/* Local function declaration */
++/* ============================= */
++static IFX_int32_t ifx_mps_fw_wdog_start_ar9(IFX_void_t);
++
++/* ============================= */
++/* Local variable definition */
++/* ============================= */
++static IFX_int32_t vpe1_started = 0;
++/* VMMC watchdog timer callback */
++IFX_int32_t (*ifx_wdog_callback) (IFX_uint32_t flags) = IFX_NULL;
++
++/* ============================= */
++/* Local function definition */
++/* ============================= */
++
++/******************************************************************************
++ * AR9 Specific Routines
++ ******************************************************************************/
++
++/**
++ * Start AR9 EDSP firmware watchdog mechanism.
++ * Called after download and startup of VPE1.
++ *
++ * \param none
++ * \return 0 IFX_SUCCESS
++ * \return -1 IFX_ERROR
++ * \ingroup Internal
++ */
++IFX_int32_t ifx_mps_fw_wdog_start_ar9()
++{
++ return IFX_SUCCESS;
++}
++
++/**
++ * Firmware download to Voice CPU
++ * This function performs a firmware download to the coprocessor.
++ *
++ * \param pMBDev Pointer to mailbox device structure
++ * \param pFWDwnld Pointer to firmware structure
++ * \return 0 IFX_SUCCESS, firmware ready
++ * \return -1 IFX_ERROR, firmware not downloaded.
++ * \ingroup Internal
++ */
++IFX_int32_t ifx_mps_download_firmware (mps_mbx_dev *pMBDev, mps_fw *pFWDwnld)
++{
++ IFX_uint32_t mem, cksum;
++ IFX_uint8_t crc;
++ IFX_boolean_t bMemReqNotPresent = IFX_FALSE;
++
++ /* VCC register */
++ /* dummy accesss on GTC for GPONC-55, otherwise upper bits are random on read */
++ ltq_r32 ((u32 *)((KSEG1 | 0x1DC000B0)));
++ /* NTR Frequency Select 1536 kHz per default or take existing,
++ NTR Output Enable and NTR8K Output Enable */
++ if ((ltq_r32 ((u32 *)(GPON_SYS_BASE + 0xBC)) & 7) == 0)
++ ltq_w32_mask (0x10187, 0x183, (u32 *)(GPON_SYS_BASE + 0xBC));
++ else
++ ltq_w32_mask (0x10180, 0x180, (u32 *)(GPON_SYS_BASE + 0xBC));
++#if 0
++ /* BIU-ICU1-IM1_ISR - IM1:FSCT_CMP1=1 and FSC_ROOT=1
++ (0x1f880328 = 0x00002800) */
++ ltq_w32 (0x00002800, (u32 *)(GPON_ICU1_BASE + 0x30));
++#endif
++ /* copy FW footer from user space */
++ if (IFX_NULL == IFXOS_CpyFromUser(pFW_img_data,
++ pFWDwnld->data+pFWDwnld->length/4-sizeof(*pFW_img_data)/4,
++ sizeof(*pFW_img_data)))
++ {
++ TRACE (MPS, DBG_LEVEL_HIGH,
++ (KERN_ERR "[%s %s %d]: copy_from_user error\r\n",
++ __FILE__, __func__, __LINE__));
++ return IFX_ERROR;
++ }
++
++ mem = pFW_img_data->mem;
++
++ /* memory requirement sanity check */
++ if ((crc = ~((mem >> 16) + (mem >> 8) + mem)) != (mem >> 24))
++ {
++ TRACE (MPS, DBG_LEVEL_HIGH,
++ ("[%s %s %d]: warning, image does not contain size - assuming 1MB!\n",
++ __FILE__, __func__, __LINE__));
++ mem = 1 * 1024 * 1024;
++ bMemReqNotPresent = IFX_TRUE;
++ }
++ else
++ {
++ mem &= 0x00FFFFFF;
++ }
++
++ /* check if FW image fits in available memory space */
++ if (mem > vpe1_get_max_mem(0))
++ {
++ TRACE (MPS, DBG_LEVEL_HIGH,
++ ("[%s %s %d]: error, firmware memory exceeds reserved space (%i > %i)!\n",
++ __FILE__, __func__, __LINE__, mem, vpe1_get_max_mem(0)));
++ return IFX_ERROR;
++ }
++
++ /* reset the driver */
++ ifx_mps_reset ();
++
++ /* call BSP to get cpu1 base address */
++ cpu1_base_addr = (IFX_uint32_t *)vpe1_get_load_addr(0);
++
++ /* check if CPU1 base address is sane
++ \todo: check if address is 1MB aligned,
++ also make it visible in a /proc fs */
++ if (!cpu1_base_addr)
++ {
++ TRACE (MPS, DBG_LEVEL_HIGH,
++ (KERN_ERR "IFX_MPS: CPU1 base address is invalid!\r\n"));
++ return IFX_ERROR;
++ }
++ /* further use uncached value */
++ cpu1_base_addr = (IFX_uint32_t *)KSEG1ADDR(cpu1_base_addr);
++
++ /* free all data buffers that might be currently used by FW */
++ if (IFX_NULL != ifx_mps_bufman_freeall)
++ {
++ ifx_mps_bufman_freeall();
++ }
++
++ if(FW_FORMAT_NEW)
++ {
++ /* adjust download length */
++ pFWDwnld->length -= (sizeof(*pFW_img_data)-sizeof(IFX_uint32_t));
++ }
++ else
++ {
++ pFWDwnld->length -= sizeof(IFX_uint32_t);
++
++ /* handle unlikely case if FW image does not contain memory requirement -
++ assumed for old format only */
++ if (IFX_TRUE == bMemReqNotPresent)
++ pFWDwnld->length += sizeof(IFX_uint32_t);
++
++ /* in case of old FW format always assume that FW is encrypted;
++ use compile switch USE_PLAIN_VOICE_FIRMWARE for plain FW */
++#ifndef USE_PLAIN_VOICE_FIRMWARE
++ pFW_img_data->enc = 1;
++#else
++#warning Using unencrypted firmware!
++ pFW_img_data->enc = 0;
++#endif /* USE_PLAIN_VOICE_FIRMWARE */
++ /* initializations for the old format */
++ pFW_img_data->st_addr_crc = 2*sizeof(IFX_uint32_t) +
++ FW_AR9_OLD_FMT_XCPT_AREA_SZ;
++ pFW_img_data->en_addr_crc = pFWDwnld->length;
++ pFW_img_data->fw_vers = 0;
++ pFW_img_data->magic = 0;
++ }
++
++ /* copy FW image to base address of CPU1 */
++ if (IFX_NULL ==
++ IFXOS_CpyFromUser ((IFX_void_t *)cpu1_base_addr,
++ (IFX_void_t *)pFWDwnld->data, pFWDwnld->length))
++ {
++ TRACE (MPS, DBG_LEVEL_HIGH,
++ (KERN_ERR "[%s %s %d]: copy_from_user error\r\n", __FILE__,
++ __func__, __LINE__));
++ return IFX_ERROR;
++ }
++
++ /* process firmware decryption */
++ if (pFW_img_data->enc == 1)
++ {
++ if(FW_FORMAT_NEW)
++ {
++ /* adjust decryption length (avoid decrypting CRC32 checksum) */
++ pFWDwnld->length -= sizeof(IFX_uint32_t);
++ }
++ /* BootROM actually decrypts n+4 bytes if n bytes were passed for
++ decryption. Subtract sizeof(u32) from length to avoid decryption
++ of data beyond the FW image code */
++ pFWDwnld->length -= sizeof(IFX_uint32_t);
++ ifx_bsp_basic_mps_decrypt((unsigned int)cpu1_base_addr, pFWDwnld->length);
++ }
++
++ /* calculate CRC32 checksum over downloaded image */
++ cksum = ifx_mps_fw_crc32(cpu1_base_addr, pFW_img_data);
++
++ /* verify the checksum */
++ if(FW_FORMAT_NEW)
++ {
++ if (cksum != pFW_img_data->crc32)
++ {
++ TRACE (MPS, DBG_LEVEL_HIGH,
++ ("MPS: FW checksum error: img=0x%08x calc=0x%08x\r\n",
++ pFW_img_data->crc32, cksum));
++ /*return IFX_ERROR;*/
++ }
++ }
++ else
++ {
++ /* just store self-calculated checksum */
++ pFW_img_data->crc32 = cksum;
++ }
++
++ /* start VPE1 */
++ ifx_mps_release ();
++#if 0
++ /* start FW watchdog mechanism */
++ ifx_mps_fw_wdog_start_ar9();
++#endif
++ /* get FW version */
++ return ifx_mps_get_fw_version (0);
++}
++
++
++/**
++ * Restart CPU1
++ * This function restarts CPU1 by accessing the reset request register and
++ * reinitializes the mailbox.
++ *
++ * \return 0 IFX_SUCCESS, successful restart
++ * \return -1 IFX_ERROR, if reset failed
++ * \ingroup Internal
++ */
++IFX_int32_t ifx_mps_restart (IFX_void_t)
++{
++ /* raise reset request for CPU1 and reset driver structures */
++ ifx_mps_reset ();
++ /* Disable GPTC Interrupt to CPU1 */
++ ifx_mps_shutdown_gpt ();
++ /* re-configure GPTC */
++ ifx_mps_init_gpt ();
++ /* let CPU1 run */
++ ifx_mps_release ();
++ /* start FW watchdog mechanism */
++ ifx_mps_fw_wdog_start_ar9();
++ TRACE (MPS, DBG_LEVEL_HIGH, ("IFX_MPS: Restarting firmware..."));
++ return ifx_mps_get_fw_version (0);
++}
++
++/**
++ * Shutdown MPS - stop VPE1
++ * This function stops VPE1
++ *
++ * \ingroup Internal
++ */
++IFX_void_t ifx_mps_shutdown (IFX_void_t)
++{
++ if (vpe1_started)
++ {
++ /* stop software watchdog timer */
++ vpe1_sw_wdog_stop (0);
++ /* clean up the BSP callback function */
++ vpe1_sw_wdog_register_reset_handler (IFX_NULL);
++ /* stop VPE1 */
++ vpe1_sw_stop (0);
++ vpe1_started = 0;
++ }
++ /* free GPTC */
++ ifx_mps_shutdown_gpt ();
++}
++
++/**
++ * Reset CPU1
++ * This function causes a reset of CPU1 by clearing the CPU0 boot ready bit
++ * in the reset request register RCU_RST_REQ.
++ * It does not change the boot configuration registers for CPU0 or CPU1.
++ *
++ * \return 0 IFX_SUCCESS, cannot fail
++ * \ingroup Internal
++ */
++IFX_void_t ifx_mps_reset (IFX_void_t)
++{
++ /* if VPE1 is already started, stop it */
++ if (vpe1_started)
++ {
++ /* stop software watchdog timer first */
++ vpe1_sw_wdog_stop (0);
++ vpe1_sw_stop (0);
++ vpe1_started = 0;
++ }
++
++ /* reset driver */
++ ifx_mps_reset_structures (pMPSDev);
++ ifx_mps_bufman_close ();
++ return;
++}
++
++/**
++ * Let CPU1 run
++ * This function starts VPE1
++ *
++ * \return none
++ * \ingroup Internal
++ */
++IFX_void_t ifx_mps_release (IFX_void_t)
++{
++ IFX_int_t ret;
++ IFX_int32_t RetCode = 0;
++
++ /* Start VPE1 */
++ if (IFX_SUCCESS !=
++ vpe1_sw_start ((IFX_void_t *)cpu1_base_addr, 0, 0))
++ {
++ TRACE (MPS, DBG_LEVEL_HIGH, (KERN_ERR "Error starting VPE1\r\n"));
++ return;
++ }
++ vpe1_started = 1;
++
++ /* sleep 3 seconds until FW is ready */
++ ret = IFXOS_EventWait (&fw_ready_evt, 3000, &RetCode);
++ if ((ret == IFX_ERROR) && (RetCode == 1))
++ {
++ /* timeout */
++ TRACE (MPS, DBG_LEVEL_HIGH,
++ (KERN_ERR "[%s %s %d]: Timeout waiting for firmware ready.\r\n",
++ __FILE__, __func__, __LINE__));
++ /* recalculate and compare the firmware checksum */
++ ifx_mps_fw_crc_compare(cpu1_base_addr, pFW_img_data);
++ /* dump exception area on a console */
++ ifx_mps_dump_fw_xcpt(cpu1_base_addr, pFW_img_data);
++ }
++}
++
++/**
++ * WDT callback.
++ * This function is called by BSP (module softdog_vpe) in case if software
++ * watchdog timer expiration is detected by BSP.
++ * This function needs to be registered at BSP as WDT callback using
++ * vpe1_sw_wdog_register_reset_handler() API.
++ *
++ * \return 0 IFX_SUCCESS, cannot fail
++ * \ingroup Internal
++ */
++IFX_int32_t ifx_mps_wdog_callback (IFX_uint32_t wdog_cleared_ok_count)
++{
++#ifdef DEBUG
++ TRACE (MPS, DBG_LEVEL_HIGH,
++ ("MPS: watchdog callback! arg=0x%08x\r\n", wdog_cleared_ok_count));
++#endif /* DEBUG */
++
++ /* reset SmartSLIC is done by FW */
++ /* recalculate and compare the firmware checksum */
++ ifx_mps_fw_crc_compare(cpu1_base_addr, pFW_img_data);
++
++ /* dump exception area on a console */
++ ifx_mps_dump_fw_xcpt(cpu1_base_addr, pFW_img_data);
++
++ if (IFX_NULL != ifx_wdog_callback)
++ {
++ /* call VMMC driver */
++ ifx_wdog_callback (wdog_cleared_ok_count);
++ }
++ else
++ {
++ TRACE (MPS, DBG_LEVEL_HIGH,
++ (KERN_WARNING "MPS: VMMC watchdog timer callback is NULL.\r\n"));
++ }
++ return 0;
++}
++
++/**
++ * Register WDT callback.
++ * This function is called by VMMC driver to register its callback in
++ * the MPS driver.
++ *
++ * \return 0 IFX_SUCCESS, cannot fail
++ * \ingroup Internal
++ */
++IFX_int32_t
++ifx_mps_register_wdog_callback (IFX_int32_t (*pfn) (IFX_uint32_t flags))
++{
++ ifx_wdog_callback = pfn;
++ return 0;
++}
++
++/**
++ Hardware setup on FALC ON
++*/
++void sys_hw_setup (void)
++{
++ /* Set INFRAC register bit 1: clock enable of the GPE primary clock. */
++ sys_gpe_hw_activate (0);
++ /* enable 1.5 V */
++ ltq_w32_mask (0xf, 0x0b, (u32 *)(GPON_SYS1_BASE | 0xbc));
++ /* SYS1-CLKEN:GPTC = 1 and MPS, no longer FSCT = 1 */
++ sys1_hw_activate (ACTS_MPS | ACTS_GPTC);
++ /* GPTC:CLC:RMC = 1 */
++ ltq_w32 (0x00000100, (u32 *)(KSEG1 | 0x1E100E00));
++}
++
++#ifndef VMMC_WITH_MPS
++EXPORT_SYMBOL (ifx_mps_register_wdog_callback);
++#endif /* !VMMC_WITH_MPS */
++
++#endif /* SYSTEM_FALCON */
+--- a/src/mps/drv_mps_vmmc_common.c
++++ b/src/mps/drv_mps_vmmc_common.c
+@@ -66,6 +66,10 @@ static void inline bsp_mask_and_ack_irq(
+ # include <asm/ifx/ifx_regs.h>
+ # include <asm/ifx/ifx_gptu.h>
+ #endif
++#if defined(SYSTEM_FALCON)
++#include <sys1_reg.h>
++#include <sysctrl.h>
++#endif
+
+ #include "drv_mps_vmmc.h"
+ #include "drv_mps_vmmc_dbg.h"
+@@ -1156,7 +1160,12 @@ IFX_uint32_t ifx_mps_init_structures (mp
+ mailbox, * upstream and downstream direction. */
+ memset (
+ /* avoid to overwrite CPU boot registers */
++#if defined(SYSTEM_FALCON)
++ (IFX_void_t *) MBX_Memory +
++ 2 * sizeof (mps_boot_cfg_reg),
++#else
+ (IFX_void_t *) MBX_Memory,
++#endif
+ 0,
+ sizeof (mps_mbx_reg) - 2 * sizeof (mps_boot_cfg_reg));
+ MBX_Memory->MBX_UPSTR_CMD_BASE =
+@@ -2651,7 +2660,6 @@ IFX_void_t ifx_mps_enable_mailbox_int ()
+ #endif
+
+ *IFX_MPS_AD0ENR = Ad0Reg.val;
+-
+ }
+
+ /**
+@@ -2669,6 +2677,7 @@ IFX_void_t ifx_mps_disable_mailbox_int (
+ Ad0Reg.fld.cu_mbx = 0;
+ Ad0Reg.fld.du_mbx = 0;
+ *IFX_MPS_AD0ENR = Ad0Reg.val;
++
+ }
+
+ /**
+@@ -2766,11 +2775,13 @@ irqreturn_t ifx_mps_ad0_irq (IFX_int32_t
+ /* handle only enabled interrupts */
+ MPS_Ad0StatusReg.val &= *IFX_MPS_AD0ENR;
+
++#if !defined(SYSTEM_FALCON)
+ #ifdef LINUX_2_6
+ bsp_mask_and_ack_irq (irq);
+ #else /* */
+ mask_and_ack_danube_irq (irq);
+ #endif /* */
++#endif /* !defined(SYSTEM_FALCON) */
+ /* FW is up and ready to process commands */
+ if (MPS_Ad0StatusReg.fld.dl_end)
+ {
+@@ -2919,11 +2930,13 @@ irqreturn_t ifx_mps_ad1_irq (IFX_int32_t
+ /* handle only enabled interrupts */
+ MPS_Ad1StatusReg.val &= *IFX_MPS_AD1ENR;
+
++#if !defined(SYSTEM_FALCON)
+ #ifdef LINUX_2_6
+ bsp_mask_and_ack_irq (irq);
+ #else /* */
+ mask_and_ack_danube_irq (irq);
+ #endif /* */
++#endif /* !defined(SYSTEM_FALCON) */
+ pMPSDev->event.MPS_Ad1Reg.val = MPS_Ad1StatusReg.val;
+
+ /* use callback function or queue wake up to notify about data reception */
+@@ -2977,11 +2990,13 @@ irqreturn_t ifx_mps_vc_irq (IFX_int32_t
+ IFX_MPS_CVC0SR[chan] = MPS_VCStatusReg.val;
+ /* handle only enabled interrupts */
+ MPS_VCStatusReg.val &= IFX_MPS_VC0ENR[chan];
++#if !defined(SYSTEM_FALCON)
+ #ifdef LINUX_2_6
+ bsp_mask_and_ack_irq (irq);
+ #else /* */
+ mask_and_ack_danube_irq (irq);
+ #endif /* */
++#endif /* !defined(SYSTEM_FALCON) */
+
+ pMPSDev->event.MPS_VCStatReg[chan].val = MPS_VCStatusReg.val;
+ #ifdef PRINT_ON_ERR_INTERRUPT
+@@ -3126,6 +3141,7 @@ IFX_int32_t ifx_mps_get_fw_version (IFX_
+ */
+ IFX_return_t ifx_mps_init_gpt ()
+ {
++#if !defined(SYSTEM_FALCON)
+ unsigned long flags;
+ IFX_uint32_t timer_flags, timer, loops = 0;
+ IFX_ulong_t count;
+@@ -3134,7 +3150,11 @@ IFX_return_t ifx_mps_init_gpt ()
+ #else /* Danube */
+ timer = TIMER1B;
+ #endif /* SYSTEM_AR9 || SYSTEM_VR9 */
++#endif
+
++#if defined(SYSTEM_FALCON)
++ sys_hw_setup ();
++#else
+ /* calibration loop - required to syncronize GPTC interrupt with falling
+ edge of FSC clock */
+ timer_flags =
+@@ -3179,7 +3199,7 @@ Probably already in use.\r\n", __FILE__,
+ #endif /* DEBUG */
+
+ IFXOS_UNLOCKINT (flags);
+-
++#endif
+ return IFX_SUCCESS;
+ }
+
+@@ -3194,6 +3214,9 @@ Probably already in use.\r\n", __FILE__,
+ */
+ IFX_void_t ifx_mps_shutdown_gpt (IFX_void_t)
+ {
++#if defined(SYSTEM_FALCON)
++ sys1_hw_deactivate (ACTS_MPS);
++#else
+ IFX_uint32_t timer;
+ #if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
+ timer = TIMER1A;
+@@ -3202,6 +3225,7 @@ IFX_void_t ifx_mps_shutdown_gpt (IFX_voi
+ #endif /* SYSTEM_AR9 || SYSTEM_VR9 */
+
+ ifx_gptu_timer_free (timer);
++#endif
+ }
+
+ /**
+--- a/src/mps/drv_mps_vmmc_device.h
++++ b/src/mps/drv_mps_vmmc_device.h
+@@ -22,7 +22,12 @@
+ # include <lantiq_soc.h>
+ # include <gpio.h>
+ #define IFXMIPS_MPS_SRAM ((u32 *)(KSEG1 + 0x1F200000))
++#if defined(SYSTEM_FALCON)
++#define IFXMIPS_MPS_BASE_ADDR (KSEG1 + 0x1D004000)
++#else
+ #define IFXMIPS_MPS_BASE_ADDR (KSEG1 + 0x1F107000)
++#endif
++
+ #define IFXMIPS_MPS_CHIPID ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0344))
+ #define IFXMIPS_MPS_VC0ENR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0000))
+ #define IFXMIPS_MPS_RVC0SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0010))
+@@ -73,10 +78,11 @@
+ /* MPS Common defines */
+ /* ============================= */
+
+-#define MPS_BASEADDRESS 0xBF107000
+-#define MPS_RAD0SR MPS_BASEADDRESS + 0x0004
+-
++#if defined(SYSTEM_FALCON)
++#define MBX_BASEADDRESS 0xBF200040
++#else
+ #define MBX_BASEADDRESS 0xBF200000
++#endif
+ #define VCPU_BASEADDRESS 0xBF208000 /* 0xBF108000 */
+ /*---------------------------------------------------------------------------*/
+ #if !defined(CONFIG_LANTIQ)
+@@ -118,7 +124,6 @@
+ /*---------------------------------------------------------------------------*/
+
+ #ifdef CONFIG_MPS_EVENT_MBX
+-
+ #define MBX_CMD_FIFO_SIZE 64 /**< Size of command FIFO in bytes */
+ #define MBX_DATA_UPSTRM_FIFO_SIZE 64
+ #define MBX_DATA_DNSTRM_FIFO_SIZE 128
+@@ -294,6 +299,10 @@ typedef struct
+ #ifdef CONFIG_MPS_EVENT_MBX
+ typedef struct
+ {
++#if defined(SYSTEM_FALCON)
++ mps_boot_cfg_reg MBX_CPU0_BOOT_CFG; /**< CPU0 Boot Configuration */
++ mps_boot_cfg_reg MBX_CPU1_BOOT_CFG; /**< CPU1 Boot Configuration */
++#endif
+ volatile IFX_uint32_t *MBX_UPSTR_CMD_BASE; /**< Upstream Command FIFO Base Address */
+ volatile IFX_uint32_t MBX_UPSTR_CMD_SIZE; /**< Upstream Command FIFO size in byte */
+ volatile IFX_uint32_t *MBX_DNSTR_CMD_BASE; /**< Downstream Command FIFO Base Address */
+@@ -317,13 +326,19 @@ typedef struct
+ volatile IFX_uint32_t MBX_UPSTR_EVENT_WRITE; /**< Upstream Event FIFO Write Index */
+ volatile IFX_uint32_t MBX_EVENT[MBX_EVENT_DATA_WORDS];
+ volatile IFX_uint32_t reserved[4];
++#if !defined(SYSTEM_FALCON)
+ mps_boot_cfg_reg MBX_CPU0_BOOT_CFG; /**< CPU0 Boot Configuration */
+ mps_boot_cfg_reg MBX_CPU1_BOOT_CFG; /**< CPU1 Boot Configuration */
++#endif
+ } mps_mbx_reg;
+
+ #else /* */
+ typedef struct
+ {
++#if defined(SYSTEM_FALCON)
++ mps_boot_cfg_reg MBX_CPU0_BOOT_CFG; /**< CPU0 Boot Configuration */
++ mps_boot_cfg_reg MBX_CPU1_BOOT_CFG; /**< CPU1 Boot Configuration */
++#endif
+ volatile IFX_uint32_t *MBX_UPSTR_CMD_BASE; /**< Upstream Command FIFO Base Address */
+ volatile IFX_uint32_t MBX_UPSTR_CMD_SIZE; /**< Upstream Command FIFO size in byte */
+ volatile IFX_uint32_t *MBX_DNSTR_CMD_BASE; /**< Downstream Command FIFO Base Address */
+@@ -341,8 +356,10 @@ typedef struct
+ volatile IFX_uint32_t MBX_DNSTR_DATA_READ; /**< Downstream Data FIFO Read Index */
+ volatile IFX_uint32_t MBX_DNSTR_DATA_WRITE; /**< Downstream Data FIFO Write Index */
+ volatile IFX_uint32_t MBX_DATA[MBX_DATA_WORDS];
++#if !defined(SYSTEM_FALCON)
+ mps_boot_cfg_reg MBX_CPU0_BOOT_CFG; /**< CPU0 Boot Configuration */
+ mps_boot_cfg_reg MBX_CPU1_BOOT_CFG; /**< CPU1 Boot Configuration */
++#endif
+ } mps_mbx_reg;
+ #endif /* CONFIG_MPS_EVENT_MBX */
+
+--- a/src/drv_api.h
++++ b/src/drv_api.h
+@@ -183,7 +183,7 @@
+ #endif
+
+ /* TAPI FXS Phone Detection feature is not available for Danube platform */
+-#if defined(TAPI_PHONE_DETECTION) && (defined(SYSTEM_AR9) || defined(SYSTEM_VR9))
++#if defined(TAPI_PHONE_DETECTION) && (defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON))
+ #define VMMC_CFG_ADD_FEAT_PHONE_DETECTION VMMC_FEAT_PHONE_DETECTION
+ #else
+ #define VMMC_CFG_ADD_FEAT_PHONE_DETECTION 0
+--- a/src/drv_vmmc_alm.c
++++ b/src/drv_vmmc_alm.c
+@@ -800,7 +800,7 @@ IFX_void_t VMMC_ALM_Free_Ch_Structures (
+ }
+
+
+-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ /**
+ Check whether SmartSLIC is connected
+
+@@ -836,7 +836,7 @@ IFX_boolean_t VMMC_ALM_SmartSLIC_IsConne
+ #endif /*SYSTEM_AR9 || SYSTEM_VR9*/
+
+
+-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ /**
+ Read the number of channels on the SmartSLIC.
+
+@@ -1876,7 +1876,7 @@ IFX_int32_t VMMC_TAPI_LL_ALM_VMMC_Test_L
+ /* write updated message contents */
+ ret = CmdWrite (pDev, (IFX_uint32_t *)((IFX_void_t *)&debugCfg),
+ DCCTL_CMD_LEN);
+-#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ IFX_uint32_t dcctrlLoop[2];
+ IFX_uint32_t ch = (IFX_uint32_t)(pCh->nChannel - 1);
+
+--- a/src/drv_vmmc_alm.h
++++ b/src/drv_vmmc_alm.h
+@@ -65,7 +65,7 @@ extern IFX_void_t irq_VMMC_ALM_LineDisab
+ extern IFX_void_t VMMC_ALM_CorrectLinemodeCache (VMMC_CHANNEL *pCh,
+ IFX_uint16_t lm);
+
+-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ extern IFX_boolean_t VMMC_ALM_SmartSLIC_IsConnected (
+ VMMC_DEVICE *pDev);
+
+--- a/src/drv_vmmc_init.c
++++ b/src/drv_vmmc_init.c
+@@ -52,15 +52,6 @@
+ #include "ifx_pmu.h"
+ #endif /* PMU_SUPPORTED */
+
+-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28))
+-# define IFX_MPS_CAD0SR IFXMIPS_MPS_CAD0SR
+-# define IFX_MPS_CAD1SR IFXMIPS_MPS_CAD1SR
+-# define IFX_MPS_CVC0SR IFXMIPS_MPS_CVC0SR
+-# define IFX_MPS_CVC1SR IFXMIPS_MPS_CVC1SR
+-# define IFX_MPS_CVC2SR IFXMIPS_MPS_CVC2SR
+-# define IFX_MPS_CVC3SR IFXMIPS_MPS_CVC3SR
+-#endif
+-
+ /* ============================= */
+ /* Local Macros & Definitions */
+ /* ============================= */
+@@ -820,7 +811,7 @@ static IFX_int32_t VMMC_TAPI_LL_FW_Init(
+ MIN_FW_HOTFIXSTEP};
+ IFX_uint8_t tmp1, tmp2;
+ IFX_TAPI_RESOURCE nResource;
+-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ IFX_uint8_t nChannels, nFXOChannels;
+ #endif /*SYSTEM_AR9 || SYSTEM_VR9*/
+ IFX_int32_t ret = VMMC_statusOk;
+@@ -874,7 +865,7 @@ static IFX_int32_t VMMC_TAPI_LL_FW_Init(
+ pDev->bSmartSlic = IFX_FALSE;
+ pDev->bSlicSupportsIdleMode = IFX_FALSE;
+
+-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ if (VMMC_SUCCESS(ret))
+ {
+ /* Reduce the number of ALM channels in the capabilities if the SLIC
+--- a/src/drv_vmmc_ioctl.c
++++ b/src/drv_vmmc_ioctl.c
+@@ -273,7 +273,7 @@ IFX_int32_t VMMC_Dev_Spec_Ioctl (IFX_TAP
+ case FIO_GET_VERS:
+ {
+ VMMC_IO_VERSION *pVers;
+-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ VMMC_SDD_REVISION_READ_t *pSDDVersCmd = IFX_NULL;
+ #endif /*SYSTEM_AR9 || SYSTEM_VR9*/
+ SYS_VER_t *pCmd;
+@@ -322,7 +322,7 @@ IFX_int32_t VMMC_Dev_Spec_Ioctl (IFX_TAP
+ pVers->nTapiVers = 3;
+ pVers->nDrvVers = MAJORSTEP << 24 | MINORSTEP << 16 |
+ VERSIONSTEP << 8 | VERS_TYPE;
+-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
++#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
+ /* in case of SmartSLIC based systems, we can give some more
+ versions.*/
+ if (VMMC_ALM_SmartSLIC_IsConnected(pDev))
diff --git a/package/kernel/Makefile b/package/kernel/linux/Makefile
index d44b5a7767..d44b5a7767 100644
--- a/package/kernel/Makefile
+++ b/package/kernel/linux/Makefile
diff --git a/package/kernel/modules/001-depends.mk b/package/kernel/linux/modules/001-depends.mk
index e0af735705..e0af735705 100644
--- a/package/kernel/modules/001-depends.mk
+++ b/package/kernel/linux/modules/001-depends.mk
diff --git a/package/kernel/modules/block.mk b/package/kernel/linux/modules/block.mk
index 1aa47def2d..1aa47def2d 100644
--- a/package/kernel/modules/block.mk
+++ b/package/kernel/linux/modules/block.mk
diff --git a/package/kernel/modules/crypto.mk b/package/kernel/linux/modules/crypto.mk
index be76f53251..be76f53251 100644
--- a/package/kernel/modules/crypto.mk
+++ b/package/kernel/linux/modules/crypto.mk
diff --git a/package/kernel/modules/firewire.mk b/package/kernel/linux/modules/firewire.mk
index 34edf0c511..34edf0c511 100644
--- a/package/kernel/modules/firewire.mk
+++ b/package/kernel/linux/modules/firewire.mk
diff --git a/package/kernel/modules/fs.mk b/package/kernel/linux/modules/fs.mk
index ecdfb6d3a7..ecdfb6d3a7 100644
--- a/package/kernel/modules/fs.mk
+++ b/package/kernel/linux/modules/fs.mk
diff --git a/package/kernel/modules/hwmon.mk b/package/kernel/linux/modules/hwmon.mk
index 969e8fa3aa..969e8fa3aa 100644
--- a/package/kernel/modules/hwmon.mk
+++ b/package/kernel/linux/modules/hwmon.mk
diff --git a/package/kernel/modules/i2c.mk b/package/kernel/linux/modules/i2c.mk
index 085570836f..085570836f 100644
--- a/package/kernel/modules/i2c.mk
+++ b/package/kernel/linux/modules/i2c.mk
diff --git a/package/kernel/modules/input.mk b/package/kernel/linux/modules/input.mk
index 78fa9241cd..78fa9241cd 100644
--- a/package/kernel/modules/input.mk
+++ b/package/kernel/linux/modules/input.mk
diff --git a/package/kernel/modules/leds.mk b/package/kernel/linux/modules/leds.mk
index 980d62610a..980d62610a 100644
--- a/package/kernel/modules/leds.mk
+++ b/package/kernel/linux/modules/leds.mk
diff --git a/package/kernel/modules/lib.mk b/package/kernel/linux/modules/lib.mk
index 0411e93702..0411e93702 100644
--- a/package/kernel/modules/lib.mk
+++ b/package/kernel/linux/modules/lib.mk
diff --git a/package/kernel/modules/netdevices.mk b/package/kernel/linux/modules/netdevices.mk
index 3dec19e3c0..3dec19e3c0 100644
--- a/package/kernel/modules/netdevices.mk
+++ b/package/kernel/linux/modules/netdevices.mk
diff --git a/package/kernel/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk
index 4e4c85f45c..4e4c85f45c 100644
--- a/package/kernel/modules/netfilter.mk
+++ b/package/kernel/linux/modules/netfilter.mk
diff --git a/package/kernel/modules/netsupport.mk b/package/kernel/linux/modules/netsupport.mk
index ff1f794701..ff1f794701 100644
--- a/package/kernel/modules/netsupport.mk
+++ b/package/kernel/linux/modules/netsupport.mk
diff --git a/package/kernel/modules/nls.mk b/package/kernel/linux/modules/nls.mk
index 28791b6b7b..28791b6b7b 100644
--- a/package/kernel/modules/nls.mk
+++ b/package/kernel/linux/modules/nls.mk
diff --git a/package/kernel/modules/other.mk b/package/kernel/linux/modules/other.mk
index aa16c142eb..aa16c142eb 100644
--- a/package/kernel/modules/other.mk
+++ b/package/kernel/linux/modules/other.mk
diff --git a/package/kernel/modules/pcmcia.mk b/package/kernel/linux/modules/pcmcia.mk
index cac727719c..cac727719c 100644
--- a/package/kernel/modules/pcmcia.mk
+++ b/package/kernel/linux/modules/pcmcia.mk
diff --git a/package/kernel/modules/sound.mk b/package/kernel/linux/modules/sound.mk
index 494394603b..494394603b 100644
--- a/package/kernel/modules/sound.mk
+++ b/package/kernel/linux/modules/sound.mk
diff --git a/package/kernel/modules/spi.mk b/package/kernel/linux/modules/spi.mk
index 416209825f..416209825f 100644
--- a/package/kernel/modules/spi.mk
+++ b/package/kernel/linux/modules/spi.mk
diff --git a/package/kernel/modules/usb.mk b/package/kernel/linux/modules/usb.mk
index 1cb8e2c1b2..1cb8e2c1b2 100644
--- a/package/kernel/modules/usb.mk
+++ b/package/kernel/linux/modules/usb.mk
diff --git a/package/kernel/modules/video.mk b/package/kernel/linux/modules/video.mk
index e652e8a4f0..e652e8a4f0 100644
--- a/package/kernel/modules/video.mk
+++ b/package/kernel/linux/modules/video.mk
diff --git a/package/kernel/modules/virtual.mk b/package/kernel/linux/modules/virtual.mk
index 5f8428be65..5f8428be65 100644
--- a/package/kernel/modules/virtual.mk
+++ b/package/kernel/linux/modules/virtual.mk
diff --git a/package/kernel/modules/w1.mk b/package/kernel/linux/modules/w1.mk
index 9093216831..9093216831 100644
--- a/package/kernel/modules/w1.mk
+++ b/package/kernel/linux/modules/w1.mk
diff --git a/package/kernel/modules/wireless.mk b/package/kernel/linux/modules/wireless.mk
index ee0f965944..ee0f965944 100644
--- a/package/kernel/modules/wireless.mk
+++ b/package/kernel/linux/modules/wireless.mk
diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile
new file mode 100644
index 0000000000..4d9d95cd2f
--- /dev/null
+++ b/package/kernel/mac80211/Makefile
@@ -0,0 +1,1630 @@
+#
+# Copyright (C) 2007-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=mac80211
+
+PKG_VERSION:=2013-06-13
+PKG_RELEASE:=1
+PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
+PKG_MD5SUM:=986749f5fbc5ec9b963e49c7171be300
+
+PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
+PKG_BUILD_PARALLEL:=1
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+
+PKG_DRIVERS = \
+ adm8211 ath5k libertas-usb libertas-sd p54-common p54-pci p54-usb p54-spi \
+ rt2x00-lib rt2x00-pci rt2x00-usb rt2x00-soc rt2800-lib rt2400-pci \
+ rt2500-pci rt2500-usb rt61-pci rt73-usb rt2800-pci rt2800-usb \
+ rtl8180 rtl8187 zd1211rw mac80211-hwsim carl9170 b43 b43legacy \
+ ath9k-common ath9k ath9k-htc ath net-libipw net-ipw2100 net-ipw2200 \
+ mwl8k net-hermes net-hermes-pci net-hermes-plx net-hermes-pcmcia \
+ iwl-legacy iwl3945 iwl4965 iwlagn wl12xx lib80211
+
+PKG_CONFIG_DEPENDS:= \
+ CONFIG_PACKAGE_kmod-mac80211 \
+ $(patsubst %,CONFIG_PACKAGE_kmod-%,$(PKG_DRIVERS)) \
+ CONFIG_PACKAGE_MAC80211_DEBUGFS \
+ CONFIG_PACKAGE_MAC80211_MESH \
+ CONFIG_PACKAGE_ATH_DEBUG \
+ CONFIG_PACKAGE_B43_DEBUG \
+ CONFIG_PACKAGE_B43_PIO \
+ CONFIG_PACKAGE_B43_N_PHY \
+ CONFIG_ATH_USER_REGD \
+
+CARL9170_FW_VERSION:=1.9.6
+
+include $(INCLUDE_DIR)/package.mk
+
+WMENU:=Wireless Drivers
+
+define KernelPackage/mac80211/Default
+ SUBMENU:=$(WMENU)
+ URL:=http://linuxwireless.org/
+ MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+ DEPENDS:=@(!(TARGET_avr32||TARGET_ps3||TARGET_pxcab)||BROKEN)
+endef
+
+define KernelPackage/cfg80211
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=cfg80211 - wireless configuration API
+ DEPENDS+= +iw
+ FILES:= \
+ $(PKG_BUILD_DIR)/compat/compat.ko \
+ $(PKG_BUILD_DIR)/net/wireless/cfg80211.ko
+ AUTOLOAD:=$(call AutoLoad,20,compat cfg80211)
+endef
+
+define KernelPackage/cfg80211/description
+cfg80211 is the Linux wireless LAN (802.11) configuration API.
+endef
+
+define KernelPackage/mac80211
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Linux 802.11 Wireless Networking Stack
+ DEPENDS+= +kmod-crypto-core +kmod-crypto-arc4 +kmod-crypto-aes +kmod-cfg80211
+ KCONFIG:=\
+ CONFIG_AVERAGE=y
+ FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko
+ AUTOLOAD:=$(call AutoLoad,21,mac80211)
+ MENU:=1
+endef
+
+define KernelPackage/mac80211/config
+ if PACKAGE_kmod-mac80211
+
+ config PACKAGE_MAC80211_DEBUGFS
+ bool "Export mac80211 internals in DebugFS"
+ select KERNEL_DEBUG_FS
+ select KERNEL_RELAY if PACKAGE_kmod-ath9k-common
+ default y
+ help
+ Select this to see extensive information about
+ the internal state of mac80211 in debugfs.
+
+ config PACKAGE_MAC80211_MESH
+ bool "Enable 802.11s mesh support"
+ default y
+
+ endif
+endef
+
+define KernelPackage/mac80211/description
+Generic IEEE 802.11 Networking Stack (mac80211)
+endef
+
+PKG_LINUX_FIRMWARE_NAME:=linux-firmware
+PKG_LINUX_FIRMWARE_VERSION:=6942dba419d2ebf8c15514972e89734fd7a8cebc
+PKG_LINUX_FIRMWARE_SOURCE:=$(PKG_LINUX_FIRMWARE_NAME)-$(PKG_LINUX_FIRMWARE_VERSION).tar.bz2
+PKG_LINUX_FIRMWARE_PROTO:=git
+PKG_LINUX_FIRMWARE_SOURCE_URL:=git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
+PKG_LINUX_FIRMWARE_SUBDIR:=$(PKG_LINUX_FIRMWARE_NAME)-$(PKG_LINUX_FIRMWARE_VERSION)
+PKG_LINUX_FIRMWARE_MIRROR_MD5SUM:=a5f8c27af9e43f0ad24d7f821c5a781e
+
+define Download/linux-firmware
+ FILE:=$(PKG_LINUX_FIRMWARE_SOURCE)
+ URL:=$(PKG_LINUX_FIRMWARE_SOURCE_URL)
+ MD5SUM:=$(PKG_LINUX_FIRMWARE_MD5SUM)
+ PROTO:=$(PKG_LINUX_FIRMWARE_PROTO)
+ VERSION:=$(PKG_LINUX_FIRMWARE_VERSION)
+ SUBDIR:=$(PKG_LINUX_FIRMWARE_SUBDIR)
+ MIRROR_MD5SUM:=$(PKG_LINUX_FIRMWARE_MIRROR_MD5SUM)
+endef
+$(eval $(call Download,linux-firmware))
+
+# Prism54 drivers
+P54PCIFW:=2.13.12.0.arm
+P54USBFW:=2.13.24.0.lm87.arm
+P54SPIFW:=2.13.0.0.a.13.14.arm
+CARL9170_FW:=carl9170-1.fw
+
+define Download/p54usb
+ FILE:=$(P54USBFW)
+ URL:=http://daemonizer.de/prism54/prism54-fw/fw-usb
+ MD5SUM:=8e8ab005a4f8f0123bcdc51bc25b47f6
+endef
+$(eval $(call Download,p54usb))
+
+define Download/p54pci
+ FILE:=$(P54PCIFW)
+ URL:=http://daemonizer.de/prism54/prism54-fw/fw-softmac
+ MD5SUM:=ff7536af2092b1c4b21315bd103ef4c4
+endef
+$(eval $(call Download,p54pci))
+
+define Download/p54spi
+ FILE:=$(P54SPIFW)
+ URL:=http://daemonizer.de/prism54/prism54-fw/stlc4560
+ MD5SUM:=42661f8ecbadd88012807493f596081d
+endef
+$(eval $(call Download,p54spi))
+
+define Download/carl9170
+ FILE:=$(CARL9170_FW)-$(CARL9170_FW_VERSION)
+ URL:=http://downloads.openwrt.org/sources/
+ MD5SUM:=2fa6ed98d53d0b5fbcc136d1cf5e9609
+endef
+$(eval $(call Download,carl9170))
+
+define KernelPackage/p54/Default
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Prism54 Drivers
+endef
+
+define KernelPackage/p54/description
+ Kernel module for Prism54 chipsets (mac80211)
+endef
+
+define KernelPackage/p54-common
+ $(call KernelPackage/p54/Default)
+ DEPENDS+= @PCI_SUPPORT||@USB_SUPPORT||@TARGET_omap24xx +kmod-mac80211 +kmod-lib-crc-ccitt
+ TITLE+= (COMMON)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/p54/p54common.ko
+ AUTOLOAD:=$(call AutoLoad,30,p54common)
+endef
+
+define KernelPackage/p54-pci
+ $(call KernelPackage/p54/Default)
+ TITLE+= (PCI)
+ DEPENDS+= @PCI_SUPPORT +kmod-p54-common
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/p54/p54pci.ko
+ AUTOLOAD:=$(call AutoLoad,31,p54pci)
+endef
+
+define KernelPackage/p54-usb
+ $(call KernelPackage/p54/Default)
+ TITLE+= (USB)
+ DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-p54-common
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/p54/p54usb.ko
+ AUTOLOAD:=$(call AutoLoad,31,p54usb)
+endef
+
+define KernelPackage/p54-spi
+ $(call KernelPackage/p54/Default)
+ TITLE+= (SPI)
+ DEPENDS+= @TARGET_omap24xx +kmod-p54-common
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/p54/p54spi.ko
+ AUTOLOAD:=$(call AutoLoad,31,p54spi)
+endef
+
+define KernelPackage/rt2x00/Default
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Ralink Drivers for RT2x00 cards
+endef
+
+define KernelPackage/rt2x00-lib
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-mac80211 +kmod-lib-crc-itu-t
+ TITLE+= (LIB)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00lib.ko
+ AUTOLOAD:=$(call AutoLoad,24,rt2x00lib)
+ MENU:=1
+endef
+
+define KernelPackage/rt2x00-lib/config
+ if PACKAGE_kmod-rt2x00-lib
+
+ config PACKAGE_RT2X00_LIB_DEBUGFS
+ bool "Enable rt2x00 debugfs support"
+ depends on PACKAGE_MAC80211_DEBUGFS
+ help
+ Enable creation of debugfs files for the rt2x00 drivers.
+ These debugfs files support both reading and writing of the
+ most important register types of the rt2x00 hardware.
+
+ config PACKAGE_RT2X00_DEBUG
+ bool "Enable rt2x00 debug output"
+ help
+ Enable debugging output for all rt2x00 modules
+
+ endif
+endef
+
+define KernelPackage/rt2x00-mmio
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @(PCI_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib +kmod-eeprom-93cx6
+ TITLE+= (MMIO)
+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00mmio.ko
+ AUTOLOAD:=$(call AutoLoad,25,rt2x00mmio)
+endef
+
+define KernelPackage/rt2x00-pci
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-mmio +kmod-rt2x00-lib
+ TITLE+= (PCI)
+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00pci.ko
+ AUTOLOAD:=$(call AutoLoad,26,rt2x00pci)
+endef
+
+define KernelPackage/rt2x00-usb
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @USB_SUPPORT +kmod-rt2x00-lib +kmod-usb-core
+ TITLE+= (USB)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00usb.ko
+ AUTOLOAD:=$(call AutoLoad,26,rt2x00usb)
+endef
+
+define KernelPackage/rt2x00-soc
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @TARGET_ramips +kmod-rt2x00-mmio +kmod-rt2x00-lib
+ TITLE+= (SoC)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00soc.ko
+ AUTOLOAD:=$(call AutoLoad,26,rt2x00soc)
+endef
+
+define KernelPackage/rt2800-lib
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib +TARGET_ramips:kmod-rt2x00-soc +@DRIVER_11N_SUPPORT
+ TITLE+= (rt2800 LIB)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2800lib.ko
+ AUTOLOAD:=$(call AutoLoad,27,rt2800lib)
+endef
+
+define KernelPackage/rt2400-pci
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci
+ TITLE+= (RT2400 PCI)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2400pci.ko
+ AUTOLOAD:=$(call AutoLoad,27,rt2400pci)
+endef
+
+define KernelPackage/rt2500-pci
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci
+ TITLE+= (RT2500 PCI)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2500pci.ko
+ AUTOLOAD:=$(call AutoLoad,27,rt2500pci)
+endef
+
+define KernelPackage/rt2500-usb
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb
+ TITLE+= (RT2500 USB)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2500usb.ko
+ AUTOLOAD:=$(call AutoLoad,27,rt2500usb)
+endef
+
+define KernelPackage/rt61-pci
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci
+ TITLE+= (RT2x61 PCI)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt61pci.ko
+ AUTOLOAD:=$(call AutoLoad,27,rt61pci)
+endef
+
+define KernelPackage/rt73-usb
+ $(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb
+ TITLE+= (RT73 USB)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt73usb.ko
+ AUTOLOAD:=$(call AutoLoad,27,rt73usb)
+endef
+
+define KernelPackage/rt2800-pci
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @(PCI_SUPPORT||TARGET_ramips) +PCI_SUPPORT:kmod-rt2x00-pci +kmod-rt2800-lib +kmod-lib-crc-ccitt +TARGET_ramips:kmod-rt2x00-soc
+ TITLE+= (RT2860 PCI)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2800pci.ko
+ AUTOLOAD:=$(call AutoLoad,28,rt2800pci)
+endef
+
+define KernelPackage/rt2800-usb
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb +kmod-rt2800-lib +kmod-lib-crc-ccitt
+ TITLE+= (RT2870 USB)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2800usb.ko
+ AUTOLOAD:=$(call AutoLoad,28,rt2800usb)
+endef
+
+define KernelPackage/rtl818x/Default
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Realtek Drivers for RTL818x devices
+ URL:=http://wireless.kernel.org/en/users/Drivers/rtl8187
+ DEPENDS+= +kmod-eeprom-93cx6 +kmod-mac80211
+endef
+
+define KernelPackage/rtl8180
+ $(call KernelPackage/rtl818x/Default)
+ DEPENDS+= @PCI_SUPPORT
+ TITLE+= (RTL8180 PCI)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8180/rtl8180.ko
+ AUTOLOAD:=$(call AutoLoad,27,rtl8180)
+endef
+
+define KernelPackage/rtl8187
+$(call KernelPackage/rtl818x/Default)
+ DEPENDS+= @USB_SUPPORT +kmod-usb-core
+ TITLE+= (RTL8187 USB)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8187/rtl8187.ko
+ AUTOLOAD:=$(call AutoLoad,27,rtl8187)
+endef
+
+ZD1211FW_NAME:=zd1211-firmware
+ZD1211FW_VERSION:=1.4
+define Download/zd1211rw
+ FILE:=$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2
+ URL:=@SF/zd1211/
+ MD5SUM:=19f28781d76569af8551c9d11294c870
+endef
+$(eval $(call Download,zd1211rw))
+
+define KernelPackage/zd1211rw
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Zydas ZD1211 support
+ DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-mac80211
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/zd1211rw/zd1211rw.ko
+ AUTOLOAD:=$(call AutoLoad,60,zd1211rw)
+endef
+
+define KernelPackage/adm8211
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=ADMTek 8211 support
+ DEPENDS+=@PCI_SUPPORT +kmod-mac80211 +kmod-eeprom-93cx6
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/adm8211.ko
+ AUTOLOAD:=$(call AutoLoad,60,adm8211)
+endef
+
+define KernelPackage/ath/config
+ if PACKAGE_kmod-ath
+ config ATH_USER_REGD
+ bool "Force Atheros drivers to respect the user's regdomain settings"
+ help
+ Atheros' idea of regulatory handling is that the EEPROM of the card defines
+ the regulatory limits and the user is only allowed to restrict the settings
+ even further, even if the country allows frequencies or power levels that
+ are forbidden by the EEPROM settings.
+
+ Select this option if you want the driver to respect the user's decision about
+ regulatory settings.
+
+ config PACKAGE_ATH_DEBUG
+ bool "Atheros wireless debugging"
+ help
+ Say Y, if you want to debug atheros wireless drivers.
+ Right now only ath9k makes use of this.
+ endif
+endef
+
+define KernelPackage/ath
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Atheros common driver part
+ DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx||TARGET_atheros +kmod-mac80211
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath.ko
+ AUTOLOAD:=$(call AutoLoad,26,ath)
+ MENU:=1
+endef
+
+define KernelPackage/ath/description
+ This module contains some common parts needed by Atheros Wireless drivers.
+endef
+
+define KernelPackage/ath5k
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Atheros 5xxx wireless cards support
+ URL:=http://linuxwireless.org/en/users/Drivers/ath5k
+ DEPENDS+= @PCI_SUPPORT||@TARGET_atheros +kmod-ath
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath5k/ath5k.ko
+ AUTOLOAD:=$(call AutoLoad,27,ath5k)
+endef
+
+define KernelPackage/ath5k/description
+ This module adds support for wireless adapters based on
+ Atheros 5xxx chipset.
+endef
+
+define KernelPackage/ath9k-common
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Atheros 802.11n wireless devices (common code for ath9k and ath9k_htc)
+ URL:=http://linuxwireless.org/en/users/Drivers/ath9k
+ DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx +kmod-ath +@DRIVER_11N_SUPPORT
+ FILES:= \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_common.ko \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_hw.ko
+ AUTOLOAD:=$(call AutoLoad,27,ath9k_hw ath9k_common)
+endef
+
+define KernelPackage/ath9k
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Atheros 802.11n PCI wireless cards support
+ URL:=http://linuxwireless.org/en/users/Drivers/ath9k
+ DEPENDS+= @PCI_SUPPORT||TARGET_ar71xx +kmod-ath9k-common
+ FILES:= \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k.ko
+ AUTOLOAD:=$(call AutoLoad,28,ath9k)
+endef
+
+define KernelPackage/ath9k/description
+This module adds support for wireless adapters based on
+Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
+endef
+
+define KernelPackage/ath9k-htc
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Atheros 802.11n USB device support
+ URL:=http://linuxwireless.org/en/users/Drivers/ath9k
+ DEPENDS+= @USB_SUPPORT +kmod-ath9k-common +kmod-usb-core
+ FILES:= \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_htc.ko
+ AUTOLOAD:=$(call AutoLoad,55,ath9k_htc)
+endef
+
+define KernelPackage/ath9k-htc/description
+This module adds support for wireless adapters based on
+Atheros USB AR9271 and AR7010 family of chipsets.
+endef
+
+define KernelPackage/carl9170
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Driver for Atheros AR9170 USB sticks
+ DEPENDS:=@USB_SUPPORT +kmod-mac80211 +kmod-ath +kmod-usb-core +kmod-input-core +@DRIVER_11N_SUPPORT
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/carl9170/carl9170.ko
+ AUTOLOAD:=$(call AutoLoad,60,carl9170)
+endef
+
+define KernelPackage/carl9170/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(DL_DIR)/$(CARL9170_FW)-$(CARL9170_FW_VERSION) $(1)/lib/firmware/$(CARL9170_FW)
+endef
+
+define KernelPackage/lib80211
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=802.11 Networking stack
+ FILES:= \
+ $(PKG_BUILD_DIR)/net/wireless/lib80211.ko \
+ $(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_wep.ko \
+ $(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_ccmp.ko \
+ $(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_tkip.ko
+ AUTOLOAD:=$(call AutoLoad,21, \
+ lib80211 \
+ lib80211_crypt_wep \
+ lib80211_crypt_ccmp \
+ lib80211_crypt_tkip \
+ )
+endef
+
+define KernelPackage/lib80211/description
+ Kernel modules for 802.11 Networking stack
+ Includes:
+ - lib80211
+ - lib80211_crypt_wep
+ - lib80211_crypt_tkip
+ - lib80211_crytp_ccmp
+endef
+
+define KernelPackage/libertas-usb
+ $(call KernelPackage/mac80211/Default)
+ DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +kmod-usb-core +kmod-lib80211 +@DRIVER_WEXT_SUPPORT
+ TITLE:=Marvell 88W8015 Wireless Driver
+ FILES:= \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/libertas/libertas.ko \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/libertas/usb8xxx.ko
+ AUTOLOAD:=$(call AutoLoad,27,libertas usb8xxx)
+endef
+
+define KernelPackage/libertas-sd
+ $(call KernelPackage/mac80211/Default)
+ DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +kmod-mmc +@DRIVER_WEXT_SUPPORT
+ TITLE:=Marvell 88W8686 Wireless Driver
+ FILES:= \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/libertas/libertas.ko \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/libertas/libertas_sdio.ko
+ AUTOLOAD:=$(call AutoLoad,91,libertas libertas_sdio)
+endef
+
+define KernelPackage/mac80211-hwsim
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=mac80211 HW simulation device
+ DEPENDS+= +kmod-mac80211
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mac80211_hwsim.ko
+ AUTOLOAD:=$(call AutoLoad,60,mac80211_hwsim)
+endef
+
+define KernelPackage/net-libipw
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=libipw for ipw2100 and ipw2200
+ DEPENDS:=@PCI_SUPPORT +kmod-crypto-core +kmod-crypto-arc4 +kmod-crypto-aes +kmod-crypto-michael-mic +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ipw2x00/libipw.ko
+ AUTOLOAD:=$(call AutoLoad,49,libipw)
+endef
+
+define KernelPackage/net-libipw/description
+ Hardware independent IEEE 802.11 networking stack for ipw2100 and ipw2200.
+endef
+
+IPW2100_NAME:=ipw2100-fw
+IPW2100_VERSION:=1.3
+
+define Download/net-ipw2100
+ URL:=http://bughost.org/firmware/
+ FILE:=$(IPW2100_NAME)-$(IPW2100_VERSION).tgz
+ MD5SUM=46aa75bcda1a00efa841f9707bbbd113
+endef
+$(eval $(call Download,net-ipw2100))
+
+define KernelPackage/net-ipw2100
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Intel IPW2100 driver
+ DEPENDS:=@PCI_SUPPORT +kmod-net-libipw
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ipw2x00/ipw2100.ko
+ AUTOLOAD:=$(call AutoLoad,50,ipw2100)
+endef
+
+define KernelPackage/net-ipw2100/description
+ Kernel support for Intel IPW2100
+ Includes:
+ - ipw2100
+endef
+
+IPW2200_NAME:=ipw2200-fw
+IPW2200_VERSION:=3.1
+
+define Download/net-ipw2200
+ URL:=http://bughost.org/firmware/
+ FILE:=$(IPW2200_NAME)-$(IPW2200_VERSION).tgz
+ MD5SUM=eaba788643c7cc7483dd67ace70f6e99
+endef
+$(eval $(call Download,net-ipw2200))
+
+define KernelPackage/net-ipw2200
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Intel IPW2200 driver
+ DEPENDS:=@PCI_SUPPORT +kmod-net-libipw
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ipw2x00/ipw2200.ko
+ AUTOLOAD:=$(call AutoLoad,50,ipw2200)
+endef
+
+define KernelPackage/net-ipw2200/description
+ Kernel support for Intel IPW2200
+ Includes:
+ - ipw2200
+endef
+
+
+define KernelPackage/net-hermes
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Hermes 802.11b chipset support
+ DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/orinoco/orinoco.ko
+ AUTOLOAD:=$(call AutoLoad,50,orinoco)
+endef
+
+define KernelPackage/net-hermes/description
+ Kernel support for Hermes 802.11b chipsets
+endef
+
+define KernelPackage/net-hermes-pci
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Intersil Prism 2.5 PCI support
+ DEPENDS:=@PCI_SUPPORT +kmod-net-hermes
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/orinoco/orinoco_pci.ko
+ AUTOLOAD:=$(call AutoLoad,55,orinoco_pci)
+endef
+
+define KernelPackage/net-hermes-pci/description
+ Kernel modules for Intersil Prism 2.5 PCI support
+endef
+
+define KernelPackage/net-hermes-plx
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=PLX9052 based PCI adaptor
+ DEPENDS:=@PCI_SUPPORT +kmod-net-hermes
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/orinoco/orinoco_plx.ko
+ AUTOLOAD:=$(call AutoLoad,55,orinoco_plx)
+endef
+
+define KernelPackage/net-hermes-plx/description
+ Kernel modules for Hermes in PLX9052 based PCI adaptors
+endef
+
+define KernelPackage/net-hermes-pcmcia
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Hermes based PCMCIA adaptors
+ DEPENDS:=@PCMCIA_SUPPORT +kmod-net-hermes @BROKEN
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/orinoco/orinoco_cs.ko
+ AUTOLOAD:=$(call AutoLoad,55,orinoco_cs)
+endef
+
+define KernelPackage/net-hermes-pcmcia/description
+ Kernel modules for Hermes based PCMCIA adaptors
+endef
+
+define KernelPackage/iwlagn
+ $(call KernelPackage/mac80211/Default)
+ DEPENDS:= +kmod-mac80211 @PCI_SUPPORT +@DRIVER_11N_SUPPORT
+ TITLE:=Intel AGN Wireless support
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlwifi/iwlwifi.ko
+ AUTOLOAD:=$(call AutoLoad,60,iwlwifi)
+ MENU:=1
+endef
+
+define KernelPackage/iwlagn/description
+ iwlagn kernel module for Intel 5000/5150/1000/6000/6050/6005/6030/100 support
+endef
+
+define KernelPackage/iwlagn/config
+ if PACKAGE_kmod-iwlagn
+
+ config IWL5000_FW
+ bool "Intel 5000 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN
+
+ config IWL5150_FW
+ bool "Intel 5150 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Wireless WiFi 5150AGN
+
+ config IWL1000_FW
+ bool "Intel 1000 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Wireless-N 1000
+
+ config IWL6000_FW
+ bool "Intel 6000 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Ultimate-N 6300 and Advanced-N 6200
+
+ config IWL6050_FW
+ bool "Intel 6050 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Advanced-N + WiMAX 6250 and Wireless-N + WiMAX 6150
+
+ config IWL6005_FW
+ bool "Intel 6005 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Advanced-N 6205
+
+ config IWL6030_FW
+ bool "Intel 6030 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Advanced-N 6230, Wireless-N 1030, Wireless-N 130 and Advanced-N 6235
+
+ config IWL100_FW
+ bool "Intel 100 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Wireless-N 100
+
+ config IWL2000_FW
+ bool "Intel 2000 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Wireless-N 2200
+
+ config IWL2030_FW
+ bool "Intel 2030 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Wireless-N 2230
+
+ config IWL105_FW
+ bool "Intel 105 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Wireless-N 105
+
+ config IWL135_FW
+ bool "Intel 135 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Wireless-N 135
+ endif
+endef
+
+define KernelPackage/iwl-legacy
+ $(call KernelPackage/mac80211/Default)
+ DEPENDS:= +kmod-mac80211 @PCI_SUPPORT
+ TITLE:=Intel legacy Wireless support
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlegacy/iwlegacy.ko
+ AUTOLOAD:=$(call AutoLoad,60,iwlegacy)
+endef
+
+define KernelPackage/iwl-legacy/description
+ iwl-legacy kernel module for legacy Intel wireless support
+endef
+
+define KernelPackage/iwl3945
+ $(call KernelPackage/mac80211/Default)
+ DEPENDS:= +kmod-mac80211 +kmod-iwl-legacy
+ TITLE:=Intel iwl3945 Wireless support
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlegacy/iwl3945.ko
+ AUTOLOAD:=$(call AutoLoad,61,iwl3945)
+endef
+
+define KernelPackage/iwl3945/description
+ iwl3945 kernel module for Intel 3945 support
+endef
+
+define KernelPackage/iwl4965
+ $(call KernelPackage/mac80211/Default)
+ DEPENDS:= +kmod-mac80211 +kmod-iwl-legacy +@DRIVER_11N_SUPPORT
+ TITLE:=Intel iwl4965 Wireless support
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlegacy/iwl4965.ko
+ AUTOLOAD:=$(call AutoLoad,61,iwl4965)
+endef
+
+define KernelPackage/iwl4965/description
+ iwl4965 kernel module for Intel 4965 support
+endef
+
+
+define KernelPackage/mwl8k
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Driver for Marvell TOPDOG 802.11 Wireless cards
+ URL:=http://wireless.kernel.org/en/users/Drivers/mwl8k
+ DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11N_SUPPORT
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mwl8k.ko
+ AUTOLOAD:=$(call AutoLoad,27,mwl8k)
+endef
+
+define KernelPackage/mwl8k/description
+ Kernel modules for Marvell TOPDOG 802.11 Wireless cards
+endef
+
+
+define KernelPackage/wl12xx
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Driver for TI WL12xx
+ URL:=http://wireless.kernel.org/en/users/Drivers/wl12xx
+ DEPENDS+= @TARGET_omap4 +kmod-mac80211
+ FILES:= \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl12xx/wl12xx.ko \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore.ko \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore_sdio.ko
+ AUTOLOAD:=$(call AutoLoad,61,wlcore wlcore_sdio wl12xx)
+endef
+
+define KernelPackage/wl12xx/description
+ Kernel modules for TI WL12xx
+endef
+
+#Broadcom firmware
+ifneq ($(CONFIG_B43_FW_5_10),)
+ PKG_B43_FWV4_NAME:=broadcom-wl
+ PKG_B43_FWV4_VERSION:=5.10.56.27.3
+ PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta/wl_prebuilt.o
+ PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)_mipsel.tar.bz2
+ PKG_B43_FWV4_SOURCE_URL:=http://mirror2.openwrt.org/sources/
+ PKG_B43_FWV4_MD5SUM:=3363e3a6b3d9d73c49dea870c7834eac
+else
+ifneq ($(CONFIG_B43_FW_4_178),)
+ PKG_B43_FWV4_NAME:=broadcom-wl
+ PKG_B43_FWV4_VERSION:=4.178.10.4
+ PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o
+ PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
+ PKG_B43_FWV4_SOURCE_URL:=http://mirror2.openwrt.org/sources/
+ PKG_B43_FWV4_MD5SUM:=14477e8cbbb91b11896affac9b219fdb
+else
+ifneq ($(CONFIG_B43_FW_5_100_138),)
+ PKG_B43_FWV4_NAME:=broadcom-wl
+ PKG_B43_FWV4_VERSION:=5.100.138
+ PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o
+ PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
+ PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
+ PKG_B43_FWV4_MD5SUM:=f4e357b09eaf5d8b1f1920cf3493a555
+else
+ PKG_B43_FWV4_NAME:=broadcom-wl
+ PKG_B43_FWV4_VERSION:=4.150.10.5
+ PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta_mimo.o
+ PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
+ PKG_B43_FWV4_SOURCE_URL:=http://mirror2.openwrt.org/sources/
+ PKG_B43_FWV4_MD5SUM:=0c6ba9687114c6b598e8019e262d9a60
+endif
+endif
+endif
+ifneq ($(CONFIG_B43_OPENFIRMWARE),)
+ PKG_B43_FWV4_NAME:=broadcom-wl
+ PKG_B43_FWV4_VERSION:=5.2
+ PKG_B43_FWV4_OBJECT:=openfwwf-$(PKG_B43_FWV4_VERSION)
+ PKG_B43_FWV4_SOURCE:=openfwwf-$(PKG_B43_FWV4_VERSION).tar.gz
+ PKG_B43_FWV4_SOURCE_URL:=http://www.ing.unibs.it/openfwwf/firmware/
+ PKG_B43_FWV4_MD5SUM:=e045a135453274e439ae183f8498b0fa
+endif
+
+
+PKG_B43_FWV3_NAME:=wl_apsta
+PKG_B43_FWV3_VERSION:=3.130.20.0
+PKG_B43_FWV3_SOURCE:=$(PKG_B43_FWV3_NAME)-$(PKG_B43_FWV3_VERSION).o
+PKG_B43_FWV3_SOURCE_URL:=http://downloads.openwrt.org/sources/
+PKG_B43_FWV3_MD5SUM:=e08665c5c5b66beb9c3b2dd54aa80cb3
+
+define Download/b43
+ FILE:=$(PKG_B43_FWV4_SOURCE)
+ URL:=$(PKG_B43_FWV4_SOURCE_URL)
+ MD5SUM:=$(PKG_B43_FWV4_MD5SUM)
+endef
+$(eval $(call Download,b43))
+
+define Download/b43legacy
+ FILE:=$(PKG_B43_FWV3_SOURCE)
+ URL:=$(PKG_B43_FWV3_SOURCE_URL)
+ MD5SUM:=$(PKG_B43_FWV3_MD5SUM)
+endef
+$(eval $(call Download,b43legacy))
+
+
+define KernelPackage/b43
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Broadcom 43xx wireless support
+ URL:=http://linuxwireless.org/en/users/Drivers/b43
+ KCONFIG:= \
+ CONFIG_HW_RANDOM=y
+ DEPENDS+= +kmod-mac80211 +!TARGET_brcm47xx:kmod-bcma +!(TARGET_brcm47xx||TARGET_brcm63xx):kmod-ssb
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/b43/b43.ko
+ AUTOLOAD:=$(call AutoLoad,30,b43)
+ MENU:=1
+endef
+
+define KernelPackage/b43/config
+ if PACKAGE_kmod-b43
+
+ choice
+ prompt "b43 firmware version"
+ default B43_FW_5_100_138
+ help
+ This option allows you to select the version of the b43 firmware.
+
+ config B43_FW_4_150
+ bool "Firmware 410.2160 from driver 4.150.10.5 (old stable)"
+ help
+ Stable firmware for BCM43xx devices.
+
+ If unsure, select this.
+
+ config B43_FW_4_178
+ bool "Firmware 478.104 from driver 4.178.10.4"
+ help
+ Experimental firmware for BCM43xx devices.
+
+ This firmware is not tested as much as the "stable" firmware.
+
+ If unsure, select the "stable" firmware.
+
+ config B43_FW_5_10
+ bool "Firmware 508.1084 from driver 5.10.56.27"
+ help
+ Newer experimental firmware for BCM43xx devices.
+
+ This firmware is mostly untested. It is needed for some N-PHY devices.
+
+ If unsure, select the "stable" firmware.
+
+ config B43_FW_5_100_138
+ bool "Firmware 666.2 from driver 5.100.138 (stable)"
+ help
+ Newer experimental firmware for BCM43xx devices.
+
+ This firmware is mostly untested. It is needed for some N-PHY devices.
+
+ If unsure, select the "stable" firmware.
+
+ config B43_OPENFIRMWARE
+ bool "Open FirmWare for WiFi networks"
+ help
+ Opensource firmware for BCM43xx devices.
+
+ Do _not_ select this, unless you know what you are doing.
+ The Opensource firmware is not suitable for embedded devices, yet.
+ It does not support QoS, which is bad for AccessPoints.
+ It does not support hardware crypto acceleration, which is a showstopper
+ for embedded devices with low CPU resources.
+
+ If unsure, select the "stable" firmware.
+
+ endchoice
+
+ config B43_FW_SQUASH
+ bool "Remove unnecessary firmware files"
+ depends on !B43_OPENFIRMWARE
+ default y
+ help
+ This options allows you to remove unnecessary b43 firmware files
+ from the final rootfs image. This can reduce the rootfs size by
+ up to 200k.
+
+ If unsure, say Y.
+
+ config B43_FW_SQUASH_COREREVS
+ string "Core revisions to include"
+ depends on B43_FW_SQUASH
+ default "5,6,7,8,9,10,11,13,15,16,29"
+ help
+ This is a comma seperated list of core revision numbers.
+
+ Example (keep files for rev5 only):
+ 5
+
+ Example (keep files for rev5 and rev11):
+ 5,11
+
+ config B43_FW_SQUASH_PHYTYPES
+ string "PHY types to include"
+ depends on B43_FW_SQUASH
+ default "G,LP,N,HT"
+ help
+ This is a comma seperated list of PHY types:
+ A => A-PHY
+ AG => Dual A-PHY G-PHY
+ G => G-PHY
+ LP => LP-PHY
+ N => N-PHY
+ HT => HT-PHY
+ LCN => LCN-PHY
+
+ Example (keep files for G-PHY only):
+ G
+
+ Example (keep files for G-PHY and N-PHY):
+ G,N
+
+ config PACKAGE_B43_DEBUG
+ bool "Enable debug output and debugfs for b43"
+ default n
+ help
+ Enable additional debug output and runtime sanity checks for b43
+ and enables the debugfs interface.
+
+ If unsure, say N.
+
+ config PACKAGE_B43_PIO
+ bool "Enable support for PIO transfer mode"
+ default n
+ help
+ Enable support for using PIO instead of DMA. Unless you have DMA
+ transfer problems you don't need this.
+
+ If unsure, say N.
+
+ config PACKAGE_B43_PHY_N
+ bool "Enable support for N-PHYs"
+ default y
+ help
+ Enable support for N-PHY. This includes support for the following devices:
+ PCI: BCM4321, BCM4322, BCM43222, BCM43224, BCM43225
+ SoC: BCM4716, BCM4717, BCM4718
+
+ Currently only 11g speed is available.
+
+ If unsure, say Y.
+
+ config PACKAGE_B43_PHY_HT
+ bool "Enable support for HT-PHYs"
+ default y
+ help
+ Enable support for HT-PHY. This includes support for the following devices:
+ PCI: BCM4331
+
+ Currently only 11g speed is available.
+
+ If unsure, say Y.
+
+ config PACKAGE_B43_PHY_LCN
+ bool "Enable support for LCN-PHYs"
+ depends on BROKEN
+ default n
+ help
+ Currently broken.
+
+ If unsure, say N.
+
+ endif
+endef
+
+define KernelPackage/b43/description
+Kernel module for Broadcom 43xx wireless support (mac80211 stack) new
+endef
+
+define KernelPackage/b43legacy
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Broadcom 43xx-legacy wireless support
+ URL:=http://linuxwireless.org/en/users/Drivers/b43
+ KCONFIG:= \
+ CONFIG_HW_RANDOM=y
+ DEPENDS+= +kmod-mac80211 +!(TARGET_brcm47xx||TARGET_brcm63xx):kmod-ssb
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/b43legacy/b43legacy.ko
+ AUTOLOAD:=$(call AutoLoad,30,b43legacy)
+ MENU:=1
+endef
+
+define KernelPackage/b43legacy/config
+ if PACKAGE_kmod-b43legacy
+
+ config B43LEGACY_FW_SQUASH
+ bool "Remove unnecessary firmware files"
+ default y
+ help
+ This options allows you to remove unnecessary b43legacy firmware files
+ from the final rootfs image. This can reduce the rootfs size by
+ up to 50k.
+
+ If unsure, say Y.
+
+ config B43LEGACY_FW_SQUASH_COREREVS
+ string "Core revisions to include"
+ depends on B43LEGACY_FW_SQUASH
+ default "1,2,3,4"
+ help
+ This is a comma seperated list of core revision numbers.
+
+ Example (keep files for rev4 only):
+ 4
+
+ Example (keep files for rev2 and rev4):
+ 2,4
+
+ endif
+endef
+
+define KernelPackage/b43legacy/description
+Kernel module for Broadcom 43xx-legacy wireless support (mac80211 stack) new
+endef
+
+
+define KernelPackage/brcmutil
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Broadcom IEEE802.11n common driver parts
+ URL:=http://linuxwireless.org/en/users/Drivers/brcm80211
+ DEPENDS+=@PCI_SUPPORT||USB_SUPPORT
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/brcm80211/brcmutil/brcmutil.ko
+ AUTOLOAD:=$(call AutoLoad,30,brcmutil)
+ MENU:=1
+endef
+
+define KernelPackage/brcmutil/description
+ This module contains some common parts needed by Broadcom Wireless drivers brcmsmac and brcmfmac.
+endef
+
+define KernelPackage/brcmutil/config
+ if PACKAGE_kmod-brcmutil
+
+ config PACKAGE_BRCM80211_DEBUG
+ bool "Broadcom wireless driver debugging"
+ help
+ Say Y, if you want to debug brcmsmac and brcmfmac wireless driver.
+
+ endif
+endef
+
+PKG_BRCMSMAC_FW_NAME:=broadcom-wl
+PKG_BRCMSMAC_FW_VERSION:=5.100.138
+PKG_BRCMSMAC_FW_OBJECT:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION)/linux/wl_apsta.o
+PKG_BRCMSMAC_FW_SOURCE:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION).tar.bz2
+PKG_BRCMSMAC_FW_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
+PKG_BRCMSMAC_FW_MD5SUM:=f4e357b09eaf5d8b1f1920cf3493a555
+
+define Download/brcmsmac
+ FILE:=$(PKG_BRCMSMAC_FW_SOURCE)
+ URL:=$(PKG_BRCMSMAC_FW_SOURCE_URL)
+ MD5SUM:=$(PKG_BRCMSMAC_FW_MD5SUM)
+endef
+$(eval $(call Download,brcmsmac))
+
+define KernelPackage/brcmsmac
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Broadcom IEEE802.11n PCIe SoftMAC WLAN driver
+ URL:=http://linuxwireless.org/en/users/Drivers/brcm80211
+ DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT +!TARGET_brcm47xx:kmod-bcma +kmod-lib-cordic +kmod-lib-crc8 +kmod-brcmutil
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/brcm80211/brcmsmac/brcmsmac.ko
+ AUTOLOAD:=$(call AutoLoad,31,brcmsmac)
+ MENU:=1
+endef
+
+define KernelPackage/brcmsmac/description
+ Kernel module for Broadcom IEEE802.11n PCIe Wireless cards
+endef
+
+define KernelPackage/brcmsmac/config
+ if PACKAGE_kmod-brcmsmac
+
+ config BRCMSMAC_USE_FW_FROM_WL
+ bool "Use firmware extracted from broadcom proprietary driver"
+ default y
+ help
+ Instead of using the official brcmsmac firmware a firmware
+ version 666.2 extracted from the proprietary Broadcom driver
+ is used. This is needed to get core rev 17 used in bcm4716
+ to work.
+
+ If unsure, say Y.
+
+ endif
+endef
+
+
+define KernelPackage/brcmfmac
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Broadcom IEEE802.11n USB FullMAC WLAN driver
+ URL:=http://linuxwireless.org/en/users/Drivers/brcm80211
+ DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-cfg80211 +@DRIVER_11N_SUPPORT +kmod-brcmutil
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/brcm80211/brcmfmac/brcmfmac.ko
+ AUTOLOAD:=$(call AutoLoad,60,brcmfmac)
+endef
+
+define KernelPackage/brcmfmac/description
+ Kernel module for Broadcom IEEE802.11n USB Wireless cards
+endef
+
+config_package=$(if $(CONFIG_PACKAGE_kmod-$(1)),m)
+
+config-y:= \
+ WLAN \
+ NL80211_TESTMODE \
+ CFG80211_WEXT \
+ CFG80211_INTERNAL_REGDB \
+ MAC80211_RC_MINSTREL \
+ MAC80211_RC_MINSTREL_HT \
+ MAC80211_RC_DEFAULT_MINSTREL \
+
+config-$(call config_package,cfg80211) += CFG80211
+
+config-$(call config_package,mac80211) += MAC80211
+config-$(CONFIG_PACKAGE_MAC80211_MESH) += MAC80211_MESH
+ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS
+ config-y += \
+ CFG80211_DEBUGFS \
+ MAC80211_DEBUGFS \
+ ATH9K_DEBUGFS \
+ ATH9K_HTC_DEBUGFS \
+ CARL9170_DEBUGFS \
+ ATH5K_DEBUG
+endif
+
+config-$(call config_package,lib80211) += LIB80211 LIB80211_CRYPT_WEP LIB80211_CRYPT_CCMP LIB80211_CRYPT_TKIP
+
+config-$(call config_package,ath) += ATH_CARDS ATH_COMMON
+config-$(CONFIG_PACKAGE_ATH_DEBUG) += ATH_DEBUG
+
+config-$(call config_package,ath9k) += ATH9K
+config-$(call config_package,ath9k-common) += ATH9K_COMMON
+config-$(CONFIG_TARGET_ar71xx) += ATH9K_AHB
+config-$(CONFIG_PCI) += ATH9K_PCI
+config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD
+
+config-$(call config_package,ath9k-htc) += ATH9K_HTC
+
+config-$(call config_package,ath5k) += ATH5K
+ifdef CONFIG_TARGET_atheros
+ config-y += ATH5K_AHB
+else
+ config-y += ATH5K_PCI
+endif
+
+config-$(call config_package,carl9170) += CARL9170
+
+config-$(call config_package,b43) += B43
+config-y += B43_SSB B43_BCMA B43_BCMA_EXTRA
+config-$(CONFIG_PACKAGE_B43_PHY_N) += B43_PHY_N
+config-$(CONFIG_PACKAGE_B43_PHY_LP) += B43_PHY_LP
+config-$(CONFIG_PACKAGE_B43_PHY_HT) += B43_PHY_HT
+config-$(CONFIG_PACKAGE_B43_PIO) += B43_PIO
+config-$(CONFIG_PACKAGE_B43_DEBUG) += B43_DEBUG
+
+config-$(call config_package,b43legacy) += B43LEGACY
+config-y += B43LEGACY_DMA_MODE
+
+config-$(call config_package,brcmutil) += BRCMUTIL
+config-$(call config_package,brcmsmac) += BRCMSMAC
+config-$(call config_package,brcmfmac) += BRCMFMAC BRCMFMAC_USB
+config-$(CONFIG_PACKAGE_BRCM80211_DEBUG) += BRCMDBG
+
+config-$(call config_package,mac80211-hwsim) += MAC80211_HWSIM
+
+config-$(call config_package,rt2x00-lib) += RT2X00 RT2X00_LIB
+config-$(call config_package,rt2x00-pci) += RT2X00_LIB_PCI
+config-$(call config_package,rt2x00-mmio) += RT2X00_LIB_MMIO
+config-$(call config_package,rt2x00-usb) += RT2X00_LIB_USB
+config-$(call config_package,rt2x00-soc) += RT2X00_LIB_SOC
+config-$(CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS) += RT2X00_LIB_DEBUGFS
+config-$(CONFIG_PACKAGE_RT2X00_DEBUG) += RT2X00_DEBUG
+
+config-$(call config_package,rt2400-pci) += RT2400PCI
+config-$(call config_package,rt2500-pci) += RT2500PCI
+config-$(call config_package,rt2500-usb) += RT2500USB
+config-$(call config_package,rt61-pci) += RT61PCI
+config-$(call config_package,rt73-usb) += RT73USB
+
+config-$(call config_package,rt2800-lib) += RT2800_LIB
+config-y += RT2800PCI_RT33XX RT2800PCI_RT35XX RT2800PCI_RT53XX RT2800PCI_RT3290
+
+config-$(call config_package,rt2800-pci) += RT2800PCI
+config-$(call config_package,rt2800-usb) += RT2800USB
+
+config-$(call config_package,iwl-legacy) += IWLEGACY
+config-$(call config_package,iwl3945) += IWL3945
+config-$(call config_package,iwl4965) += IWL4965
+config-$(call config_package,iwlagn) += IWLWIFI
+
+config-$(call config_package,net-libipw) += LIBIPW
+config-$(call config_package,net-ipw2100) += IPW2100
+config-$(call config_package,net-ipw2200) += IPW2200
+
+config-$(call config_package,p54-common) += P54_COMMON
+config-$(call config_package,p54-pci) += P54_PCI
+config-$(call config_package,p54-usb) += P54_USB
+config-$(call config_package,p54-spi) += P54_SPI
+
+config-$(call config_package,net-hermes) += HERMES
+config-$(call config_package,net-hermes-pci) += PCI_HERMES
+config-$(call config_package,net-hermes-plx) += PLX_HERMES
+config-$(call config_package,net-hermes-pcmcia) += PCMCIA_HERMES
+config-y += HERMES_PRISM
+
+config-$(call config_package,adm8211) += ADM8211
+config-$(call config_package,libertas-sd) += LIBERTAS LIBERTAS_SDIO
+config-$(call config_package,libertas-usb) += LIBERTAS LIBERTAS_USB
+config-$(call config_package,mwl8k) += MWL8K
+config-$(call config_package,rtl8180) += RTL8180
+config-$(call config_package,rtl8187) += RTL8187
+config-$(call config_package,wl12xx) += WL_TI WLCORE WLCORE_SDIO WL12XX
+config-$(call config_package,zd1211rw) += ZD1211RW
+
+config-$(CONFIG_LEDS_TRIGGERS) += MAC80211_LEDS B43_LEDS B43LEGACY_LEDS
+
+MAKE_OPTS:= -C "$(PKG_BUILD_DIR)" \
+ CROSS_COMPILE="$(KERNEL_CROSS)" \
+ ARCH="$(LINUX_KARCH)" \
+ EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include" \
+ KLIB_BUILD="$(LINUX_DIR)" \
+ MODPROBE=true \
+ KLIB=$(TARGET_MODULES_DIR) \
+ KERNEL_SUBLEVEL=$(lastword $(subst ., ,$(KERNEL_PATCHVER))) \
+ KBUILD_LDFLAGS_MODULE_PREREQ=
+
+define ConfigVars
+$(subst $(space),,$(foreach opt,$(config-$(1)),CPTCFG_$(opt)=$(1)
+))
+endef
+
+define mac80211_config
+$(call ConfigVars,m)$(call ConfigVars,y)
+endef
+$(eval $(call shexport,mac80211_config))
+
+define Build/Prepare
+ rm -rf $(PKG_BUILD_DIR)
+ mkdir -p $(PKG_BUILD_DIR)
+ $(PKG_UNPACK)
+ $(Build/Patch)
+ $(TAR) -C $(PKG_BUILD_DIR) -xzf $(DL_DIR)/$(IPW2100_NAME)-$(IPW2100_VERSION).tgz
+ $(TAR) -C $(PKG_BUILD_DIR) -xzf $(DL_DIR)/$(IPW2200_NAME)-$(IPW2200_VERSION).tgz
+ $(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2
+ $(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(PKG_LINUX_FIRMWARE_SOURCE)
+ rm -rf \
+ $(PKG_BUILD_DIR)/include/linux/ssb \
+ $(PKG_BUILD_DIR)/include/linux/bcma \
+ $(PKG_BUILD_DIR)/include/net/bluetooth
+
+ rm -f \
+ $(PKG_BUILD_DIR)/include/linux/cordic.h \
+ $(PKG_BUILD_DIR)/include/linux/crc8.h \
+ $(PKG_BUILD_DIR)/include/linux/eeprom_93cx6.h \
+ $(PKG_BUILD_DIR)/include/linux/wl12xx.h \
+ $(PKG_BUILD_DIR)/include/linux/spi/libertas_spi.h \
+ $(PKG_BUILD_DIR)/include/net/ieee80211.h
+
+ echo 'compat-wireless-$(PKG_VERSION)-$(PKG_RELEASE)-$(REVISION)' > $(PKG_BUILD_DIR)/compat_version
+ $(CP) ./files/regdb.txt $(PKG_BUILD_DIR)/net/wireless/db.txt
+endef
+
+ifneq ($(CONFIG_PACKAGE_kmod-cfg80211)$(CONFIG_PACKAGE_kmod-lib80211),)
+ define Build/Compile/kmod
+ rm -rf $(PKG_BUILD_DIR)/modules
+ +$(MAKE) $(PKG_JOBS) $(MAKE_OPTS) modules
+ endef
+endif
+
+define Build/Configure
+ cmp $(PKG_BUILD_DIR)/include/linux/ath9k_platform.h $(LINUX_DIR)/include/linux/ath9k_platform.h
+ cmp $(PKG_BUILD_DIR)/include/linux/ath5k_platform.h $(LINUX_DIR)/include/linux/ath5k_platform.h
+ cmp $(PKG_BUILD_DIR)/include/linux/rt2x00_platform.h $(LINUX_DIR)/include/linux/rt2x00_platform.h
+ $(SH_FUNC) var2file "$(call shvar,mac80211_config)" $(PKG_BUILD_DIR)/.config
+ $(MAKE) $(MAKE_OPTS) allnoconfig
+endef
+
+define Build/Compile
+ $(call Build/Compile/kmod)
+endef
+
+define Build/InstallDev
+ mkdir -p \
+ $(1)/usr/include/mac80211 \
+ $(1)/usr/include/mac80211-backport \
+ $(1)/usr/include/mac80211/ath \
+ $(1)/usr/include/net/mac80211
+ $(CP) $(PKG_BUILD_DIR)/net/mac80211/*.h $(PKG_BUILD_DIR)/include/* $(1)/usr/include/mac80211/
+ $(CP) $(PKG_BUILD_DIR)/backport-include/* $(1)/usr/include/mac80211-backport/
+ $(CP) $(PKG_BUILD_DIR)/net/mac80211/rate.h $(1)/usr/include/net/mac80211/
+ $(CP) $(PKG_BUILD_DIR)/drivers/net/wireless/ath/*.h $(1)/usr/include/mac80211/ath/
+endef
+
+define KernelPackage/libertas-usb/install
+ $(INSTALL_DIR) $(1)/lib/firmware/libertas
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/usb8388_v9.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/usb8682.bin \
+ $(1)/lib/firmware/libertas/
+endef
+
+define KernelPackage/libertas-sd/install
+ $(INSTALL_DIR) $(1)/lib/firmware/libertas
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8385_helper.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8385.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8686_v9_helper.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8686_v9.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8688_helper.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/libertas/sd8688.bin \
+ $(1)/lib/firmware/libertas
+endef
+
+define KernelPackage/cfg80211/install
+ $(INSTALL_DIR) $(1)/lib/wifi
+ $(INSTALL_DATA) ./files/lib/wifi/mac80211.sh $(1)/lib/wifi
+endef
+
+define KernelPackage/p54-pci/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(DL_DIR)/$(P54PCIFW) $(1)/lib/firmware/isl3886pci
+endef
+
+define KernelPackage/p54-usb/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(DL_DIR)/$(P54USBFW) $(1)/lib/firmware/isl3887usb
+endef
+
+define KernelPackage/p54-spi/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(DL_DIR)/$(P54SPIFW) $(1)/lib/firmware/3826.arm
+endef
+
+define KernelPackage/rt61-pci/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rt2561.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rt2561s.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rt2661.bin \
+ $(1)/lib/firmware/
+endef
+
+define KernelPackage/rt73-usb/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rt73.bin $(1)/lib/firmware/
+endef
+
+define KernelPackage/rt2800-pci/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rt2860.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rt3290.bin \
+ $(1)/lib/firmware
+endef
+
+define KernelPackage/rt2800-usb/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rt2870.bin $(1)/lib/firmware/
+endef
+
+define KernelPackage/wl12xx/install
+ $(INSTALL_DIR) $(1)/lib/firmware/ti-connectivity
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl127x-fw-5-mr.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl127x-fw-5-plt.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl127x-fw-5-sr.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl1271-nvs.bin \
+ $(1)/lib/firmware/ti-connectivity
+endef
+
+
+define KernelPackage/zd1211rw/install
+ $(INSTALL_DIR) $(1)/lib/firmware/zd1211
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(ZD1211FW_NAME)/zd1211* $(1)/lib/firmware/zd1211
+endef
+
+define KernelPackage/ath9k-htc/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/htc_9271.fw \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/htc_7010.fw \
+ $(1)/lib/firmware/
+endef
+
+define KernelPackage/mwl8k/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mwl8k
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/fmimage_8366_ap-3.fw \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/fmimage_8366.fw \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/helper_8366.fw \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/fmimage_8687.fw \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mwl8k/helper_8687.fw \
+ $(1)/lib/firmware/mwl8k/
+endef
+
+define KernelPackage/net-ipw2100/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/ipw2100-$(IPW2100_VERSION)*.fw $(1)/lib/firmware
+endef
+
+define KernelPackage/net-ipw2200/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(IPW2200_NAME)-$(IPW2200_VERSION)/ipw2200*.fw $(1)/lib/firmware
+endef
+
+define KernelPackage/iwlagn/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ifneq ($(CONFIG_IWL5000_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-5000-5.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL5150_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-5150-2.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL1000_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-1000-5.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL6000_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6000-4.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL6050_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6050-5.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL6005_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6000g2a-6.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL6030_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6000g2b-6.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL100_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-100-5.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL2000_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-2000-6.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL2030_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-2030-6.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL105_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-105-6.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL135_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-135-6.ucode $(1)/lib/firmware
+endif
+endef
+
+define KernelPackage/iwl3945/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-3945-2.ucode $(1)/lib/firmware
+endef
+
+define KernelPackage/iwl4965/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-4965-2.ucode $(1)/lib/firmware
+endef
+
+define KernelPackage/b43/install
+ rm -rf $(1)/lib/firmware/
+ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
+ tar xzf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)"
+else
+ tar xjf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)"
+endif
+ $(INSTALL_DIR) $(1)/lib/firmware/
+ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
+ $(MAKE) -C "$(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/"
+ $(INSTALL_DIR) $(1)/lib/firmware/b43-open/
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/ucode5.fw $(1)/lib/firmware/b43-open/ucode5.fw
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0bsinitvals5.fw $(1)/lib/firmware/b43-open/b0g0bsinitvals5.fw
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0initvals5.fw $(1)/lib/firmware/b43-open/b0g0initvals5.fw
+else
+ b43-fwcutter -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)
+endif
+ifneq ($(CONFIG_B43_FW_SQUASH),)
+ b43-fwsquash.py "$(CONFIG_B43_FW_SQUASH_PHYTYPES)" "$(CONFIG_B43_FW_SQUASH_COREREVS)" "$(1)/lib/firmware/b43"
+endif
+endef
+
+define KernelPackage/b43legacy/install
+ $(INSTALL_DIR) $(1)/lib/firmware/
+ b43-fwcutter --unsupported -w $(1)/lib/firmware/ $(DL_DIR)/$(PKG_B43_FWV3_SOURCE)
+ifneq ($(CONFIG_B43LEGACY_FW_SQUASH),)
+ b43-fwsquash.py "G" "$(CONFIG_B43LEGACY_FW_SQUASH_COREREVS)" "$(1)/lib/firmware/b43legacy"
+endif
+endef
+
+define KernelPackage/brcmsmac/install
+ $(INSTALL_DIR) $(1)/lib/firmware/brcm
+ifeq ($(CONFIG_BRCMSMAC_USE_FW_FROM_WL),y)
+ tar xjf "$(DL_DIR)/$(PKG_BRCMSMAC_FW_SOURCE)" -C "$(PKG_BUILD_DIR)"
+ b43-fwcutter --brcmsmac -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_BRCMSMAC_FW_OBJECT)
+else
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/bcm43xx-0.fw \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/bcm43xx_hdr-0.fw \
+ $(1)/lib/firmware/brcm/
+endif
+endef
+
+define KernelPackage/brcmfmac/install
+ $(INSTALL_DIR) $(1)/lib/firmware/brcm
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/brcmfmac43236b.bin \
+ $(1)/lib/firmware/brcm/
+endef
+
+$(eval $(call KernelPackage,adm8211))
+$(eval $(call KernelPackage,ath5k))
+$(eval $(call KernelPackage,lib80211))
+$(eval $(call KernelPackage,libertas-usb))
+$(eval $(call KernelPackage,libertas-sd))
+$(eval $(call KernelPackage,cfg80211))
+$(eval $(call KernelPackage,mac80211))
+$(eval $(call KernelPackage,p54-common))
+$(eval $(call KernelPackage,p54-pci))
+$(eval $(call KernelPackage,p54-usb))
+$(eval $(call KernelPackage,p54-spi))
+$(eval $(call KernelPackage,rt2x00-lib))
+$(eval $(call KernelPackage,rt2x00-mmio))
+$(eval $(call KernelPackage,rt2x00-pci))
+$(eval $(call KernelPackage,rt2x00-usb))
+$(eval $(call KernelPackage,rt2x00-soc))
+$(eval $(call KernelPackage,rt2800-lib))
+$(eval $(call KernelPackage,rt2400-pci))
+$(eval $(call KernelPackage,rt2500-pci))
+$(eval $(call KernelPackage,rt2500-usb))
+$(eval $(call KernelPackage,rt61-pci))
+$(eval $(call KernelPackage,rt73-usb))
+$(eval $(call KernelPackage,rt2800-pci))
+$(eval $(call KernelPackage,rt2800-usb))
+$(eval $(call KernelPackage,rtl8180))
+$(eval $(call KernelPackage,rtl8187))
+$(eval $(call KernelPackage,zd1211rw))
+$(eval $(call KernelPackage,mac80211-hwsim))
+$(eval $(call KernelPackage,ath9k-common))
+$(eval $(call KernelPackage,ath9k))
+$(eval $(call KernelPackage,ath9k-htc))
+$(eval $(call KernelPackage,ath))
+$(eval $(call KernelPackage,carl9170))
+$(eval $(call KernelPackage,b43))
+$(eval $(call KernelPackage,b43legacy))
+$(eval $(call KernelPackage,brcmutil))
+$(eval $(call KernelPackage,brcmsmac))
+$(eval $(call KernelPackage,brcmfmac))
+$(eval $(call KernelPackage,net-libipw))
+$(eval $(call KernelPackage,net-ipw2100))
+$(eval $(call KernelPackage,net-ipw2200))
+$(eval $(call KernelPackage,iwlagn))
+$(eval $(call KernelPackage,iwl-legacy))
+$(eval $(call KernelPackage,iwl4965))
+$(eval $(call KernelPackage,iwl3945))
+$(eval $(call KernelPackage,mwl8k))
+$(eval $(call KernelPackage,net-hermes))
+$(eval $(call KernelPackage,net-hermes-pci))
+$(eval $(call KernelPackage,net-hermes-plx))
+$(eval $(call KernelPackage,net-hermes-pcmcia))
+$(eval $(call KernelPackage,wl12xx))
diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh
new file mode 100644
index 0000000000..a052a1cbfb
--- /dev/null
+++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh
@@ -0,0 +1,641 @@
+#!/bin/sh
+append DRIVERS "mac80211"
+
+mac80211_hostapd_setup_base() {
+ local phy="$1"
+ local ifname="$2"
+
+ cfgfile="/var/run/hostapd-$phy.conf"
+
+ config_get device "$vif" device
+ config_get country "$device" country
+ config_get hwmode "$device" hwmode
+ config_get channel "$device" channel
+ config_get beacon_int "$device" beacon_int
+ config_get basic_rate_list "$device" basic_rate
+ config_get_bool noscan "$device" noscan
+
+ hostapd_set_log_options base_cfg "$device"
+
+ [ -n "$channel" -a -z "$hwmode" ] && wifi_fixup_hwmode "$device"
+
+ [ "$channel" = auto ] && {
+ channel=$(iw phy "$phy" info | \
+ sed -ne '/MHz/ { /disabled\|passive\|radar/d; s/.*\[//; s/\].*//; p; q }')
+ config_set "$device" channel "$channel"
+ }
+
+ [ -n "$hwmode" ] && {
+ config_get hwmode_11n "$device" hwmode_11n
+ [ -n "$hwmode_11n" ] && {
+ hwmode="$hwmode_11n"
+ append base_cfg "ieee80211n=1" "$N"
+ config_get htmode "$device" htmode
+ config_get ht_capab_list "$device" ht_capab
+ case "$htmode" in
+ HT20|HT40+|HT40-) ht_capab="[$htmode]";;
+ *)ht_capab=;;
+ esac
+ for cap in $ht_capab_list; do
+ ht_capab="$ht_capab[$cap]"
+ done
+ [ -n "$ht_capab" ] && append base_cfg "ht_capab=$ht_capab" "$N"
+ }
+ }
+
+ local country_ie=0
+ [ -n "$country" ] && country_ie=1
+ config_get_bool country_ie "$device" country_ie "$country_ie"
+ [ "$country_ie" -gt 0 ] && append base_cfg "ieee80211d=1" "$N"
+
+ local br brval brstr
+ [ -n "$basic_rate_list" ] && {
+ for br in $basic_rate_list; do
+ brval="$(($br / 100))"
+ [ -n "$brstr" ] && brstr="$brstr "
+ brstr="$brstr$brval"
+ done
+ }
+
+ cat >> "$cfgfile" <<EOF
+ctrl_interface=/var/run/hostapd-$phy
+driver=nl80211
+wmm_ac_bk_cwmin=4
+wmm_ac_bk_cwmax=10
+wmm_ac_bk_aifs=7
+wmm_ac_bk_txop_limit=0
+wmm_ac_bk_acm=0
+wmm_ac_be_aifs=3
+wmm_ac_be_cwmin=4
+wmm_ac_be_cwmax=10
+wmm_ac_be_txop_limit=0
+wmm_ac_be_acm=0
+wmm_ac_vi_aifs=2
+wmm_ac_vi_cwmin=3
+wmm_ac_vi_cwmax=4
+wmm_ac_vi_txop_limit=94
+wmm_ac_vi_acm=0
+wmm_ac_vo_aifs=2
+wmm_ac_vo_cwmin=2
+wmm_ac_vo_cwmax=3
+wmm_ac_vo_txop_limit=47
+wmm_ac_vo_acm=0
+tx_queue_data3_aifs=7
+tx_queue_data3_cwmin=15
+tx_queue_data3_cwmax=1023
+tx_queue_data3_burst=0
+tx_queue_data2_aifs=3
+tx_queue_data2_cwmin=15
+tx_queue_data2_cwmax=63
+tx_queue_data2_burst=0
+tx_queue_data1_aifs=1
+tx_queue_data1_cwmin=7
+tx_queue_data1_cwmax=15
+tx_queue_data1_burst=3.0
+tx_queue_data0_aifs=1
+tx_queue_data0_cwmin=3
+tx_queue_data0_cwmax=7
+tx_queue_data0_burst=1.5
+${hwmode:+hw_mode=$hwmode}
+${channel:+channel=$channel}
+${beacon_int:+beacon_int=$beacon_int}
+${country:+country_code=$country}
+${noscan:+noscan=$noscan}
+${brstr:+basic_rates=$brstr}
+$base_cfg
+
+EOF
+}
+
+mac80211_hostapd_setup_bss() {
+ local phy="$1"
+ local vif="$2"
+
+ hostapd_cfg=
+ cfgfile="/var/run/hostapd-$phy.conf"
+ config_get ifname "$vif" ifname
+
+ if [ -f "$cfgfile" ]; then
+ append hostapd_cfg "bss=$ifname" "$N"
+ else
+ mac80211_hostapd_setup_base "$phy" "$ifname"
+ append hostapd_cfg "interface=$ifname" "$N"
+ fi
+
+ local net_cfg bridge
+ net_cfg="$(find_net_config "$vif")"
+ [ -z "$net_cfg" ] || bridge="$(bridge_interface "$net_cfg")"
+ config_set "$vif" bridge "$bridge"
+
+ hostapd_set_bss_options hostapd_cfg "$vif"
+
+ config_get_bool wds "$vif" wds 0
+ [ "$wds" -gt 0 ] && append hostapd_cfg "wds_sta=1" "$N"
+
+ local macaddr hidden maxassoc wmm
+ config_get macaddr "$vif" macaddr
+ config_get maxassoc "$vif" maxassoc
+ config_get dtim_period "$vif" dtim_period
+ config_get max_listen_int "$vif" max_listen_int
+ config_get_bool hidden "$vif" hidden 0
+ config_get_bool wmm "$vif" wmm 1
+ cat >> /var/run/hostapd-$phy.conf <<EOF
+$hostapd_cfg
+wmm_enabled=$wmm
+bssid=$macaddr
+ignore_broadcast_ssid=$hidden
+${dtim_period:+dtim_period=$dtim_period}
+${max_listen_int:+max_listen_interval=$max_listen_int}
+${maxassoc:+max_num_sta=$maxassoc}
+EOF
+}
+
+mac80211_start_vif() {
+ local vif="$1"
+ local ifname="$2"
+
+ local net_cfg
+ net_cfg="$(find_net_config "$vif")"
+ [ -z "$net_cfg" ] || start_net "$ifname" "$net_cfg"
+
+ set_wifi_up "$vif" "$ifname"
+}
+
+lookup_phy() {
+ [ -n "$phy" ] && {
+ [ -d /sys/class/ieee80211/$phy ] && return
+ }
+
+ local devpath
+ config_get devpath "$device" path
+ [ -n "$devpath" -a -d "/sys/devices/$devpath/ieee80211" ] && {
+ phy="$(ls /sys/devices/$devpath/ieee80211 | grep -m 1 phy)"
+ [ -n "$phy" ] && return
+ }
+
+ local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
+ [ -n "$macaddr" ] && {
+ for _phy in $(ls /sys/class/ieee80211 2>/dev/null); do
+ [ "$macaddr" = "$(cat /sys/class/ieee80211/${_phy}/macaddress)" ] || continue
+ phy="$_phy"
+ return
+ done
+ }
+ phy=
+ return
+}
+
+find_mac80211_phy() {
+ local device="$1"
+
+ config_get phy "$device" phy
+ lookup_phy
+ [ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || {
+ echo "PHY for wifi device $1 not found"
+ return 1
+ }
+ config_set "$device" phy "$phy"
+
+ config_get macaddr "$device" macaddr
+ [ -z "$macaddr" ] && {
+ config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)"
+ }
+
+ return 0
+}
+
+scan_mac80211() {
+ local device="$1"
+ local adhoc sta ap monitor mesh disabled
+
+ config_get vifs "$device" vifs
+ for vif in $vifs; do
+ config_get_bool disabled "$vif" disabled 0
+ [ $disabled = 0 ] || continue
+
+ config_get mode "$vif" mode
+ case "$mode" in
+ adhoc|sta|ap|monitor|mesh)
+ append $mode "$vif"
+ ;;
+ *) echo "$device($vif): Invalid mode, ignored."; continue;;
+ esac
+ done
+
+ config_set "$device" vifs "${ap:+$ap }${adhoc:+$adhoc }${sta:+$sta }${monitor:+$monitor }${mesh:+$mesh}"
+}
+
+list_phy_interfaces() {
+ local phy="$1"
+ if [ -d "/sys/class/ieee80211/${phy}/device/net" ]; then
+ ls "/sys/class/ieee80211/${phy}/device/net" 2>/dev/null;
+ else
+ ls "/sys/class/ieee80211/${phy}/device" 2>/dev/null | grep net: | sed -e 's,net:,,g'
+ fi
+}
+
+disable_mac80211() (
+ local device="$1"
+
+ find_mac80211_phy "$device" || return 0
+ config_get phy "$device" phy
+
+ set_wifi_down "$device"
+ # kill all running hostapd and wpa_supplicant processes that
+ # are running on atheros/mac80211 vifs
+ for pid in `pidof hostapd`; do
+ grep -E "$phy" /proc/$pid/cmdline >/dev/null && \
+ kill $pid
+ done
+
+ include /lib/network
+ for wdev in $(list_phy_interfaces "$phy"); do
+ [ -f "/var/run/$wdev.pid" ] && kill $(cat /var/run/$wdev.pid) >&/dev/null 2>&1
+ for pid in `pidof wpa_supplicant`; do
+ grep "$wdev" /proc/$pid/cmdline >/dev/null && \
+ kill $pid
+ done
+ ifconfig "$wdev" down 2>/dev/null
+ unbridge "$dev"
+ iw dev "$wdev" del
+ done
+
+ return 0
+)
+
+get_freq() {
+ local phy="$1"
+ local chan="$2"
+ iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep MHz | awk '{print $2}'
+}
+
+mac80211_generate_mac() {
+ local id="$1"
+ local ref="$2"
+ local mask="$3"
+
+ [ "$mask" = "00:00:00:00:00:00" ] && mask="ff:ff:ff:ff:ff:ff";
+ local oIFS="$IFS"; IFS=":"; set -- $mask; IFS="$oIFS"
+
+ local mask1=$1
+ local mask6=$6
+
+ local oIFS="$IFS"; IFS=":"; set -- $ref; IFS="$oIFS"
+ [ "$((0x$mask1))" -gt 0 ] && {
+ b1="0x$1"
+ [ "$id" -gt 0 ] && \
+ b1=$((($b1 | 0x2) ^ (($id - 1) << 2)))
+ printf "%02x:%s:%s:%s:%s:%s" $b1 $2 $3 $4 $5 $6
+ return
+ }
+
+ [ "$((0x$mask6))" -lt 255 ] && {
+ printf "%s:%s:%s:%s:%s:%02x" $1 $2 $3 $4 $5 $(( 0x$6 ^ $id ))
+ return
+ }
+
+ off2=$(( (0x$6 + $id) / 0x100 ))
+ printf "%s:%s:%s:%s:%02x:%02x" \
+ $1 $2 $3 $4 \
+ $(( (0x$5 + $off2) % 0x100 )) \
+ $(( (0x$6 + $id) % 0x100 ))
+}
+
+enable_mac80211() {
+ local device="$1"
+ config_get channel "$device" channel
+ config_get vifs "$device" vifs
+ config_get txpower "$device" txpower
+ config_get country "$device" country
+ config_get distance "$device" distance
+ config_get txantenna "$device" txantenna all
+ config_get rxantenna "$device" rxantenna all
+ config_get antenna_gain "$device" antenna_gain 0
+ config_get frag "$device" frag
+ config_get rts "$device" rts
+ find_mac80211_phy "$device" || return 0
+ config_get phy "$device" phy
+ local i=0
+ local macidx=0
+ local apidx=0
+ fixed=""
+ local hostapd_ctrl=""
+
+ [ -n "$country" ] && {
+ iw reg get | grep -q "^country $country:" || {
+ iw reg set "$country"
+ sleep 1
+ }
+ }
+
+ config_get chanbw "$device" chanbw
+ [ -n "$chanbw" -a -d /sys/kernel/debug/ieee80211/$phy/ath9k ] && echo "$chanbw" > /sys/kernel/debug/ieee80211/$phy/ath9k/chanbw
+ [ -n "$chanbw" -a -d /sys/kernel/debug/ieee80211/$phy/ath5k ] && echo "$chanbw" > /sys/kernel/debug/ieee80211/$phy/ath5k/bwmode
+
+ [ "$channel" = "auto" -o "$channel" = "0" ] || {
+ fixed=1
+ }
+
+ iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1
+ iw phy "$phy" set antenna_gain $antenna_gain
+
+ [ -n "$distance" ] && iw phy "$phy" set distance "$distance"
+ [ -n "$frag" ] && iw phy "$phy" set frag "${frag%%.*}"
+ [ -n "$rts" ] && iw phy "$phy" set rts "${rts%%.*}"
+
+ export channel fixed
+ # convert channel to frequency
+ local freq="$(get_freq "$phy" "${fixed:+$channel}")"
+
+ wifi_fixup_hwmode "$device" "g"
+ for vif in $vifs; do
+ config_get ifname "$vif" ifname
+ [ -n "$ifname" ] || {
+ [ $i -gt 0 ] && ifname="wlan${phy#phy}-$i" || ifname="wlan${phy#phy}"
+ }
+ config_set "$vif" ifname "$ifname"
+
+ config_get mode "$vif" mode
+ config_get ssid "$vif" ssid
+
+ # It is far easier to delete and create the desired interface
+ case "$mode" in
+ adhoc)
+ iw phy "$phy" interface add "$ifname" type adhoc
+ ;;
+ ap)
+ # Hostapd will handle recreating the interface and
+ # it's accompanying monitor
+ apidx="$(($apidx + 1))"
+ [ "$apidx" -gt 1 ] || iw phy "$phy" interface add "$ifname" type managed
+ ;;
+ mesh)
+ config_get mesh_id "$vif" mesh_id
+ iw phy "$phy" interface add "$ifname" type mp mesh_id "$mesh_id"
+ ;;
+ monitor)
+ iw phy "$phy" interface add "$ifname" type monitor
+ ;;
+ sta)
+ local wdsflag
+ config_get_bool wds "$vif" wds 0
+ [ "$wds" -gt 0 ] && wdsflag="4addr on"
+ iw phy "$phy" interface add "$ifname" type managed $wdsflag
+ config_get_bool powersave "$vif" powersave 0
+ [ "$powersave" -gt 0 ] && powersave="on" || powersave="off"
+ iw "$ifname" set power_save "$powersave"
+ ;;
+ esac
+
+ # All interfaces must have unique mac addresses
+ # which can either be explicitly set in the device
+ # section, or automatically generated
+ config_get macaddr "$device" macaddr
+ config_get vif_mac "$vif" macaddr
+ [ -n "$vif_mac" ] || {
+ vif_mac="$(mac80211_generate_mac $macidx $macaddr $(cat /sys/class/ieee80211/${phy}/address_mask))"
+ macidx="$(($macidx + 1))"
+ }
+ [ "$mode" = "ap" ] || ifconfig "$ifname" hw ether "$vif_mac"
+ config_set "$vif" macaddr "$vif_mac"
+
+ # !! ap !!
+ #
+ # ALL ap functionality will be passed to hostapd
+ #
+ # !! station !!
+ #
+ # ALL station functionality will be passed to wpa_supplicant
+ #
+ if [ ! "$mode" = "ap" ]; then
+ # We attempt to set the channel for all interfaces, although
+ # mac80211 may not support it or the driver might not yet
+ # for ap mode this is handled by hostapd
+ config_get htmode "$device" htmode
+ case "$htmode" in
+ HT20|HT40+|HT40-) ;;
+ *) htmode= ;;
+ esac
+ [ -n "$fixed" -a -n "$channel" ] && iw dev "$ifname" set channel "$channel" $htmode
+ fi
+
+ i=$(($i + 1))
+ done
+
+ local start_hostapd=
+ rm -f /var/run/hostapd-$phy.conf
+ for vif in $vifs; do
+ config_get mode "$vif" mode
+ [ "$mode" = "ap" ] || continue
+ mac80211_hostapd_setup_bss "$phy" "$vif"
+ start_hostapd=1
+ done
+
+ [ -n "$start_hostapd" ] && {
+ hostapd -P /var/run/wifi-$phy.pid -B /var/run/hostapd-$phy.conf || {
+ echo "Failed to start hostapd for $phy"
+ return
+ }
+ sleep 2
+
+ for vif in $vifs; do
+ config_get mode "$vif" mode
+ config_get ifname "$vif" ifname
+ [ "$mode" = "ap" ] || continue
+ hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd-$phy/$ifname}"
+ mac80211_start_vif "$vif" "$ifname"
+ done
+ }
+
+ for vif in $vifs; do
+ config_get mode "$vif" mode
+ config_get ifname "$vif" ifname
+ [ "$mode" = "ap" ] || ifconfig "$ifname" up
+
+ config_get vif_txpower "$vif" txpower
+ # use vif_txpower (from wifi-iface) to override txpower (from
+ # wifi-device) if the latter doesn't exist
+ txpower="${txpower:-$vif_txpower}"
+ [ -z "$txpower" ] || iw dev "$ifname" set txpower fixed "${txpower%%.*}00"
+
+ case "$mode" in
+ adhoc)
+ config_get bssid "$vif" bssid
+ config_get ssid "$vif" ssid
+ config_get beacon_int "$device" beacon_int
+ config_get basic_rate_list "$device" basic_rate
+ config_get encryption "$vif" encryption
+ config_get key "$vif" key 1
+ config_get mcast_rate "$vif" mcast_rate
+ config_get htmode "$device" htmode
+ case "$htmode" in
+ HT20|HT40+|HT40-) ;;
+ *) htmode= ;;
+ esac
+
+
+ local keyspec=""
+ [ "$encryption" == "psk" -o "$encryption" == "psk2" ] && {
+ if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
+ wpa_supplicant_setup_vif "$vif" nl80211 "${hostapd_ctrl:+-H $hostapd_ctrl}" $freq $htmode || {
+ echo "enable_mac80211($device): Failed to set up wpa_supplicant for interface $ifname" >&2
+ # make sure this wifi interface won't accidentally stay open without encryption
+ ifconfig "$ifname" down
+ }
+ mac80211_start_vif "$vif" "$ifname"
+ continue
+ fi
+ }
+
+ [ "$encryption" == "wep" ] && {
+ case "$key" in
+ [1234])
+ local idx
+ for idx in 1 2 3 4; do
+ local ikey
+ config_get ikey "$vif" "key$idx"
+
+ [ -n "$ikey" ] && {
+ ikey="$(($idx - 1)):$(prepare_key_wep "$ikey")"
+ [ $idx -eq $key ] && ikey="d:$ikey"
+ append keyspec "$ikey"
+ }
+ done
+ ;;
+ *) append keyspec "d:0:$(prepare_key_wep "$key")" ;;
+ esac
+ }
+
+ local br brval brsub brstr
+ [ -n "$basic_rate_list" ] && {
+ for br in $basic_rate_list; do
+ brval="$(($br / 1000))"
+ brsub="$((($br / 100) % 10))"
+ [ "$brsub" -gt 0 ] && brval="$brval.$brsub"
+ [ -n "$brstr" ] && brstr="$brstr,"
+ brstr="$brstr$brval"
+ done
+ }
+
+ local mcval=""
+ [ -n "$mcast_rate" ] && {
+ mcval="$(($mcast_rate / 1000))"
+ mcsub="$(( ($mcast_rate / 100) % 10 ))"
+ [ "$mcsub" -gt 0 ] && mcval="$mcval.$mcsub"
+ }
+
+ iw dev "$ifname" ibss join "$ssid" $freq $htmode \
+ ${fixed:+fixed-freq} $bssid \
+ ${beacon_int:+beacon-interval $beacon_int} \
+ ${brstr:+basic-rates $brstr} \
+ ${mcval:+mcast-rate $mcval} \
+ ${keyspec:+keys $keyspec}
+ ;;
+ mesh)
+ mp_list="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh_max_peer_links
+ mesh_max_retries mesh_ttl mesh_element_ttl mesh_auto_open_plinks mesh_hwmp_max_preq_retries
+ mesh_path_refresh_time mesh_min_discovery_timeout mesh_hwmp_active_path_timeout
+ mesh_hwmp_preq_min_interval mesh_hwmp_net_diameter_traversal_time mesh_hwmp_rootmode
+ mesh_hwmp_rann_interval mesh_gate_announcements mesh_fwding mesh_sync_offset_max_neighor
+ mesh_rssi_threshold mesh_hwmp_active_path_to_root_timeout mesh_hwmp_root_interval
+ mesh_hwmp_confirmation_interval mesh_power_mode mesh_awake_window"
+ for mp in $mp_list
+ do
+ config_get mp_val "$vif" "$mp" ""
+ [ -n "$mp_val" ] && iw dev "$ifname" set mesh_param "$mp" "$mp_val"
+ done
+ ;;
+ sta)
+ if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
+ wpa_supplicant_setup_vif "$vif" nl80211 "${hostapd_ctrl:+-H $hostapd_ctrl}" || {
+ echo "enable_mac80211($device): Failed to set up wpa_supplicant for interface $ifname" >&2
+ # make sure this wifi interface won't accidentally stay open without encryption
+ ifconfig "$ifname" down
+ continue
+ }
+ fi
+ ;;
+ esac
+ [ "$mode" = "ap" ] || mac80211_start_vif "$vif" "$ifname"
+ done
+
+}
+
+
+check_mac80211_device() {
+ config_get phy "$1" phy
+ [ -z "$phy" ] && {
+ find_mac80211_phy "$1" >/dev/null || return 0
+ config_get phy "$1" phy
+ }
+ [ "$phy" = "$dev" ] && found=1
+}
+
+detect_mac80211() {
+ devidx=0
+ config_load wireless
+ while :; do
+ config_get type "radio$devidx" type
+ [ -n "$type" ] || break
+ devidx=$(($devidx + 1))
+ done
+ for dev in $(ls /sys/class/ieee80211); do
+ found=0
+ config_foreach check_mac80211_device wifi-device
+ [ "$found" -gt 0 ] && continue
+
+ mode_11n=""
+ mode_band="g"
+ channel="11"
+ ht_cap=0
+ for cap in $(iw phy "$dev" info | grep 'Capabilities:' | cut -d: -f2); do
+ ht_cap="$(($ht_cap | $cap))"
+ done
+ ht_capab="";
+ [ "$ht_cap" -gt 0 ] && {
+ mode_11n="n"
+ append ht_capab " option htmode HT20" "$N"
+
+ list=" list ht_capab"
+ [ "$(($ht_cap & 1))" -eq 1 ] && append ht_capab "$list LDPC" "$N"
+ [ "$(($ht_cap & 16))" -eq 16 ] && append ht_capab "$list GF" "$N"
+ [ "$(($ht_cap & 32))" -eq 32 ] && append ht_capab "$list SHORT-GI-20" "$N"
+ [ "$(($ht_cap & 64))" -eq 64 ] && append ht_capab "$list SHORT-GI-40" "$N"
+ [ "$(($ht_cap & 128))" -eq 128 ] && append ht_capab "$list TX-STBC" "$N"
+ [ "$(($ht_cap & 768))" -eq 256 ] && append ht_capab "$list RX-STBC1" "$N"
+ [ "$(($ht_cap & 768))" -eq 512 ] && append ht_capab "$list RX-STBC12" "$N"
+ [ "$(($ht_cap & 768))" -eq 768 ] && append ht_capab "$list RX-STBC123" "$N"
+ [ "$(($ht_cap & 4096))" -eq 4096 ] && append ht_capab "$list DSSS_CCK-40" "$N"
+ }
+ iw phy "$dev" info | grep -q '2412 MHz' || { mode_band="a"; channel="36"; }
+
+ if [ -x /usr/bin/readlink ]; then
+ path="$(readlink -f /sys/class/ieee80211/${dev}/device)"
+ path="${path##/sys/devices/}"
+ dev_id=" option path '$path'"
+ else
+ dev_id=" option macaddr $(cat /sys/class/ieee80211/${dev}/macaddress)"
+ fi
+
+ cat <<EOF
+config wifi-device radio$devidx
+ option type mac80211
+ option channel ${channel}
+ option hwmode 11${mode_11n}${mode_band}
+$dev_id
+$ht_capab
+ # REMOVE THIS LINE TO ENABLE WIFI:
+ option disabled 1
+
+config wifi-iface
+ option device radio$devidx
+ option network lan
+ option mode ap
+ option ssid OpenWrt
+ option encryption none
+
+EOF
+ devidx=$(($devidx + 1))
+ done
+}
+
diff --git a/package/kernel/mac80211/files/regdb.txt b/package/kernel/mac80211/files/regdb.txt
new file mode 100644
index 0000000000..b250e6926e
--- /dev/null
+++ b/package/kernel/mac80211/files/regdb.txt
@@ -0,0 +1,697 @@
+# This is the world regulatory domain
+country 00:
+ (2402 - 2472 @ 40), (3, 20)
+ # Channel 12 - 13. No HT40 channel fits here
+ (2457 - 2482 @ 20), (3, 20), PASSIVE-SCAN, NO-IBSS
+ # Channel 14. Only JP enables this and for 802.11b only
+ (2474 - 2494 @ 20), (3, 20), PASSIVE-SCAN, NO-IBSS, NO-OFDM
+ # Channel 36 - 48
+ (5170 - 5250 @ 40), (3, 20)
+ # NB: 5260 MHz - 5700 MHz requies DFS
+ # Channel 149 - 165
+ (5735 - 5835 @ 40), (3, 20), PASSIVE-SCAN, NO-IBSS
+
+
+country AE:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country AL:
+ (2402 - 2482 @ 20), (N/A, 20)
+
+country AM:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (N/A, 18)
+ (5250 - 5330 @ 20), (N/A, 18), DFS
+
+country AN:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country AR:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country AT: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country AU:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 23)
+ (5250 - 5330 @ 40), (3, 23), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country AW:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country AZ:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 18)
+ (5250 - 5330 @ 40), (N/A, 18), DFS
+
+country BA: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country BB:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 23)
+ (5250 - 5330 @ 40), (3, 23), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country BD:
+ (2402 - 2482 @ 40), (N/A, 20)
+
+country BE: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country BG: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 23)
+ (5250 - 5290 @ 40), (N/A, 23), DFS
+ (5490 - 5710 @ 40), (N/A, 30), DFS
+
+country BH:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (N/A, 20)
+ (5250 - 5330 @ 20), (N/A, 20), DFS
+ (5735 - 5835 @ 20), (N/A, 20)
+
+country BL:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 18)
+ (5250 - 5330 @ 40), (N/A, 18), DFS
+
+country BN:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country BO:
+ (2402 - 2482 @ 40), (N/A, 30)
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country BR:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country BY:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country BZ:
+ (2402 - 2482 @ 40), (N/A, 30)
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country CA:
+ (2402 - 2472 @ 40), (3, 27)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country CH: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country CL:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5735 - 5835 @ 40), (N/A, 20)
+
+country CN:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country CO:
+ (2402 - 2472 @ 40), (3, 27)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 23), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country CR:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (3, 17)
+ (5250 - 5330 @ 20), (3, 23), DFS
+ (5735 - 5835 @ 20), (3, 30)
+
+country CS:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country CY: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+# Data from http://www.ctu.eu/164/download/VOR/VOR-12-08-2005-34.pdf
+# and http://www.ctu.eu/164/download/VOR/VOR-12-05-2007-6-AN.pdf
+# Power at 5250 - 5350 MHz and 5470 - 5725 MHz can be doubled if TPC is
+# implemented.
+country CZ: DFS-ETSI
+ (2400 - 2483.5 @ 40), (N/A, 100 mW)
+ (5150 - 5250 @ 40), (N/A, 200 mW), NO-OUTDOOR
+ (5250 - 5350 @ 40), (N/A, 100 mW), NO-OUTDOOR, DFS
+ (5470 - 5725 @ 40), (N/A, 500 mW), DFS
+
+# Data from "Frequenznutzungsplan" (as published in April 2008), downloaded from
+# http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf
+# For the 5GHz range also see
+# http://www.bundesnetzagentur.de/cae/servlet/contentblob/38216/publicationFile/6579/WLAN5GHzVfg7_2010_28042010pdf.pdf
+# The values have been reduced by a factor of 2 (3db) for non TPC devices
+# (in other words: devices with TPC can use twice the tx power of this table).
+# Note that the docs do not require TPC for 5150--5250; the reduction to
+# 100mW thus is not strictly required -- however the conservative 100mW
+# limit is used here as the non-interference with radar and satellite
+# apps relies on the attenuation by the building walls only in the
+# absence of DFS; the neighbour countries have 100mW limit here as well.
+
+country DE: DFS-ETSI
+ # entries 279004 and 280006
+ (2400 - 2483.5 @ 40), (N/A, 100 mW)
+ # entry 303005
+ (5150 - 5250 @ 40), (N/A, 100 mW), NO-OUTDOOR
+ # entries 304002 and 305002
+ (5250 - 5350 @ 40), (N/A, 100 mW), NO-OUTDOOR, DFS
+ # entries 308002, 309001 and 310003
+ (5470 - 5725 @ 40), (N/A, 500 mW), DFS
+
+country DK: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country DO:
+ (2402 - 2472 @ 40), (3, 27)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 23), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country DZ:
+ (2402 - 2482 @ 40), (N/A, 20)
+
+country EC:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (3, 17)
+ (5250 - 5330 @ 20), (3, 23), DFS
+ (5735 - 5835 @ 20), (3, 30)
+
+country EE: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country EG:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (N/A, 20)
+ (5250 - 5330 @ 20), (N/A, 20), DFS
+
+country ES: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country FI: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country FR: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country GE:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 18)
+ (5250 - 5330 @ 40), (N/A, 18), DFS
+
+country GB: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country GD:
+ (2402 - 2472 @ 40), (3, 27)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country GR: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country GL: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (N/A, 20)
+ (5250 - 5330 @ 20), (N/A, 20), DFS
+ (5490 - 5710 @ 20), (N/A, 27), DFS
+
+country GT:
+ (2402 - 2472 @ 40), (3, 27)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 23), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country GU:
+ (2402 - 2472 @ 40), (3, 27)
+ (5170 - 5250 @ 20), (3, 17)
+ (5250 - 5330 @ 20), (3, 23), DFS
+ (5735 - 5835 @ 20), (3, 30)
+
+country HN:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country HK:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country HR: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country HT:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country HU: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country ID:
+ (2402 - 2482 @ 40), (N/A, 20)
+
+country IE: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country IL:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5150 - 5250 @ 40), (N/A, 200 mW), NO-OUTDOOR
+ (5250 - 5350 @ 40), (N/A, 200 mW), NO-OUTDOOR, DFS
+
+country IN:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5735 - 5835 @ 40), (N/A, 20)
+
+country IS: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country IR:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country IT: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country JM:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country JP:
+ (2402 - 2472 @ 40), (N/A, 20)
+ (2457 - 2482 @ 20), (N/A, 20)
+ (2474 - 2494 @ 20), (N/A, 20), NO-OFDM
+ (4910 - 4930 @ 10), (N/A, 23)
+ (4910 - 4990 @ 40), (N/A, 23)
+ (4930 - 4950 @ 10), (N/A, 23)
+ (5030 - 5045 @ 10), (N/A, 23)
+ (5030 - 5090 @ 40), (N/A, 23)
+ (5050 - 5060 @ 10), (N/A, 23)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 23), DFS
+
+country JO:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 18)
+
+country KE:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country KH:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country KP:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5330 @ 40), (3, 20)
+ (5160 - 5250 @ 40), (3, 20), DFS
+ (5490 - 5630 @ 40), (3, 30), DFS
+ (5735 - 5815 @ 40), (3, 30)
+
+country KR:
+ (2402 - 2482 @ 20), (N/A, 20)
+ (5170 - 5250 @ 20), (3, 20)
+ (5250 - 5330 @ 20), (3, 20), DFS
+ (5490 - 5630 @ 20), (3, 30), DFS
+ (5735 - 5815 @ 20), (3, 30)
+
+country KW:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+
+country KZ:
+ (2402 - 2482 @ 40), (N/A, 20)
+
+country LB:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country LI: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country LK:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (3, 17)
+ (5250 - 5330 @ 20), (3, 20), DFS
+ (5490 - 5710 @ 20), (3, 20), DFS
+ (5735 - 5835 @ 20), (3, 30)
+
+country LT: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country LU: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country LV: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country MC: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 18)
+ (5250 - 5330 @ 40), (N/A, 18), DFS
+
+country MA:
+ (2402 - 2482 @ 40), (N/A, 20)
+
+country MO:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 23)
+ (5250 - 5330 @ 40), (3, 23), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country MK: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country MT: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country MY:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 30), DFS
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country MX:
+ (2402 - 2472 @ 40), (3, 27)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 23), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country NL: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20), NO-OUTDOOR
+ (5250 - 5330 @ 40), (N/A, 20), NO-OUTDOOR, DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country NO: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country NP:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country NZ:
+ (2402 - 2482 @ 40), (N/A, 30)
+ (5170 - 5250 @ 20), (3, 23)
+ (5250 - 5330 @ 20), (3, 23), DFS
+ (5735 - 5835 @ 20), (3, 30)
+
+country OM:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country PA:
+ (2402 - 2472 @ 40), (3, 27)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 23), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country PE:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country PG:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 23), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country PH:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country PK:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country PL: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country PT: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country PR:
+ (2402 - 2472 @ 40), (3, 27)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 23), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country QA:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5735 - 5835 @ 40), (N/A, 30)
+
+country RO: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country RU:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5735 - 5835 @ 20), (N/A, 30)
+
+country SA:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (3, 23)
+ (5250 - 5330 @ 20), (3, 23), DFS
+ (5735 - 5835 @ 20), (3, 30)
+
+country SE: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country SG:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5735 - 5835 @ 40), (N/A, 20)
+
+country SI: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country SK: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+ (5490 - 5710 @ 40), (N/A, 27), DFS
+
+country SV:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (3, 17)
+ (5250 - 5330 @ 20), (3, 23), DFS
+ (5735 - 5835 @ 20), (3, 30)
+
+country SY:
+ (2402 - 2482 @ 40), (N/A, 20)
+
+country TW:
+ (2402 - 2472 @ 40), (3, 27)
+ (5270 - 5330 @ 40), (3, 17), DFS
+ (5735 - 5815 @ 40), (3, 30)
+
+country TH:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country TT:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country TN:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (N/A, 20)
+ (5250 - 5330 @ 20), (N/A, 20), DFS
+
+country TR: DFS-ETSI
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 20), (N/A, 20)
+ (5250 - 5330 @ 20), (N/A, 20), DFS
+
+country UA:
+ (2402 - 2482 @ 40), (N/A, 20)
+
+country US: DFS-FCC
+ (2402 - 2472 @ 40), (3, 27)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5600 @ 40), (3, 20), DFS
+ (5650 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country UY:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country UZ:
+ (2402 - 2472 @ 40), (3, 27)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country VE:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5735 - 5815 @ 40), (N/A, 23)
+
+country VN:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (N/A, 20)
+ (5250 - 5330 @ 40), (N/A, 20), DFS
+
+country YE:
+ (2402 - 2482 @ 40), (N/A, 20)
+
+country ZA:
+ (2402 - 2482 @ 40), (N/A, 20)
+ (5170 - 5250 @ 40), (3, 17)
+ (5250 - 5330 @ 40), (3, 20), DFS
+ (5490 - 5710 @ 40), (3, 20), DFS
+ (5735 - 5835 @ 40), (3, 30)
+
+country ZW:
+ (2402 - 2482 @ 40), (N/A, 20)
+
diff --git a/package/kernel/mac80211/patches/000-fix_kconfig.patch b/package/kernel/mac80211/patches/000-fix_kconfig.patch
new file mode 100644
index 0000000000..88d0b04984
--- /dev/null
+++ b/package/kernel/mac80211/patches/000-fix_kconfig.patch
@@ -0,0 +1,16 @@
+--- a/kconf/Makefile
++++ b/kconf/Makefile
+@@ -1,10 +1,10 @@
+-CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
++CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -DKBUILD_NO_NLS
+
+ LXDIALOG := lxdialog/checklist.o lxdialog/inputbox.o lxdialog/menubox.o lxdialog/textbox.o lxdialog/util.o lxdialog/yesno.o
+
+ conf: conf.o zconf.tab.o
+-mconf: LDFLAGS = -Wl,--no-as-needed $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
+-mconf: CFLAGS += -DCURSES_LOC="<ncurses.h>" -DLOCALE
++mconf: LDFLAGS = $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
++mconf: CFLAGS += -DCURSES_LOC="<ncurses.h>"
+ mconf: mconf.o zconf.tab.o $(LXDIALOG)
+
+ .PHONY: clean
diff --git a/package/kernel/mac80211/patches/001-fix_build.patch b/package/kernel/mac80211/patches/001-fix_build.patch
new file mode 100644
index 0000000000..c541985cf3
--- /dev/null
+++ b/package/kernel/mac80211/patches/001-fix_build.patch
@@ -0,0 +1,156 @@
+--- a/Makefile
++++ b/Makefile
+@@ -19,6 +19,7 @@ KLIB_BUILD ?= $(KLIB)/build/
+ KERNEL_CONFIG := $(KLIB_BUILD)/.config
+ KERNEL_MAKEFILE := $(KLIB_BUILD)/Makefile
+ CONFIG_MD5 := $(shell md5sum $(KERNEL_CONFIG) 2>/dev/null | sed 's/\s.*//')
++STAMP_KERNEL_CONFIG := .kernel_config_md5_$(CONFIG_MD5)
+
+ export KLIB KLIB_BUILD BACKPORT_PWD KMODDIR KMODPATH_ARG
+
+@@ -36,7 +37,8 @@ mrproper:
+ @rm -f .kernel_config_md5 Kconfig.versions Kconfig.kernel
+ @rm -f backport-include/backport/autoconf.h
+
+-.DEFAULT:
++.SILENT: $(STAMP_KERNEL_CONFIG)
++$(STAMP_KERNEL_CONFIG):
+ @set -e ; test -f .local-symbols || ( \
+ echo "/--------------" ;\
+ echo "| You shouldn't run make in the backports tree, but only in" ;\
+@@ -60,56 +62,60 @@ mrproper:
+ echo "| (that isn't currently running.)" ;\
+ echo "\\--" ;\
+ false)
+- @set -e ; if [ "$$(cat .kernel_config_md5 2>/dev/null)" != "$(CONFIG_MD5)" ] ;\
+- then \
+- echo -n "Generating local configuration database from kernel ..." ;\
+- grep -v -f .local-symbols $(KERNEL_CONFIG) | grep = | ( \
+- while read l ; do \
+- if [ "$${l:0:7}" != "CONFIG_" ] ; then \
+- continue ;\
+- fi ;\
+- l=$${l:7} ;\
+- n=$${l%%=*} ;\
+- v=$${l#*=} ;\
+- if [ "$$v" = "m" ] ; then \
+- echo config $$n ;\
+- echo ' tristate' ;\
+- elif [ "$$v" = "y" ] ; then \
+- echo config $$n ;\
+- echo ' bool' ;\
+- else \
+- continue ;\
+- fi ;\
+- echo " default $$v" ;\
+- echo "" ;\
+- done \
+- ) > Kconfig.kernel ;\
+- kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion | \
+- sed 's/^\(\(3\|2\.6\)\.[0-9]\+\).*/\1/;t;d') ;\
+- test "$$kver" != "" || echo "Kernel version parse failed!" ;\
+- test "$$kver" != "" ;\
+- kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\
+- kvers="$$kvers $$(seq 0 99 | sed 's/^/3./')" ;\
+- print=0 ;\
+- for v in $$kvers ; do \
+- if [ "$$print" = "1" ] ; then \
+- echo config BACKPORT_KERNEL_$$(echo $$v | tr . _) ;\
+- echo " def_bool y" ;\
+- fi ;\
+- if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\
+- done > Kconfig.versions ;\
+- # RHEL as well, sadly we need to grep for it ;\
+- RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \
+- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
+- RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \
+- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
+- for v in $$(seq 0 $$RHEL_MINOR) ; do \
+- echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\
+- echo " def_bool y" ;\
+- done >> Kconfig.versions ;\
+- echo " done." ;\
+- fi ;\
+- echo "$(CONFIG_MD5)" > .kernel_config_md5
++ @rm -f .kernel_config_md5_*
++ @touch $@
++
++Kconfig.kernel: $(STAMP_KERNEL_CONFIG) .local-symbols
++ @printf "Generating local configuration database from kernel ..."
++ @grep -v -f .local-symbols $(KERNEL_CONFIG) | grep = | ( \
++ while read l ; do \
++ if [ "$${l:0:7}" != "CONFIG_" ] ; then \
++ continue ;\
++ fi ;\
++ l=$${l:7} ;\
++ n=$${l%%=*} ;\
++ v=$${l#*=} ;\
++ if [ "$$v" = "m" ] ; then \
++ echo config $$n ;\
++ echo ' tristate' ;\
++ elif [ "$$v" = "y" ] ; then \
++ echo config $$n ;\
++ echo ' bool' ;\
++ else \
++ continue ;\
++ fi ;\
++ echo " default $$v" ;\
++ echo "" ;\
++ done \
++ ) > $@
++ @echo " done."
++
++Kconfig.versions: Kconfig.kernel
++ @kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion | \
++ sed 's/^\(\(3\|2\.6\)\.[0-9]\+\).*/\1/;t;d') ;\
++ test "$$kver" != "" || echo "Kernel version parse failed!" ;\
++ test "$$kver" != "" ;\
++ kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\
++ kvers="$$kvers $$(seq 0 99 | sed 's/^/3./')" ;\
++ print=0 ;\
++ for v in $$kvers ; do \
++ if [ "$$print" = "1" ] ; then \
++ echo config BACKPORT_KERNEL_$$(echo $$v | tr . _) ;\
++ echo " def_bool y" ;\
++ fi ;\
++ if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\
++ done > $@
++ @RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \
++ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
++ RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \
++ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
++ for v in $$(seq 0 $$RHEL_MINOR) ; do \
++ echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\
++ echo " def_bool y" ;\
++ done >> $@
++
++.DEFAULT:
++ @$(MAKE) Kconfig.versions
+ @$(MAKE) -f Makefile.real "$@"
+
+ else
+--- a/Makefile.real
++++ b/Makefile.real
+@@ -54,7 +54,7 @@ defconfig-%::
+
+ backport-include/backport/autoconf.h: .config Kconfig.versions Kconfig.kernel
+ @$(MAKE) oldconfig
+- @echo -n "Building backport-include/backport/autoconf.h ..."
++ @printf "Building backport-include/backport/autoconf.h ..."
+ @grep -f .local-symbols .config | ( \
+ echo "#ifndef COMPAT_AUTOCONF_INCLUDED" ;\
+ echo "#define COMPAT_AUTOCONF_INCLUDED" ;\
+@@ -75,7 +75,12 @@ backport-include/backport/autoconf.h: .c
+ esac ;\
+ done ;\
+ echo "#endif /* COMPAT_AUTOCONF_INCLUDED */" ;\
+- ) > backport-include/backport/autoconf.h
++ ) > $@.new
++ @if cmp -s $@ $@.new; then \
++ rm -f $@.new; \
++ else \
++ mv $@.new $@; \
++ fi
+ @echo " done."
+
+ .PHONY: modules
diff --git a/package/kernel/mac80211/patches/002-change_allconfig.patch b/package/kernel/mac80211/patches/002-change_allconfig.patch
new file mode 100644
index 0000000000..91ad20f06d
--- /dev/null
+++ b/package/kernel/mac80211/patches/002-change_allconfig.patch
@@ -0,0 +1,44 @@
+--- a/kconf/conf.c
++++ b/kconf/conf.c
+@@ -578,40 +578,12 @@ int main(int ac, char **av)
+ case oldconfig:
+ case listnewconfig:
+ case olddefconfig:
+- conf_read(NULL);
+- break;
+ case allnoconfig:
+ case allyesconfig:
+ case allmodconfig:
+ case alldefconfig:
+ case randconfig:
+- name = getenv("KCONFIG_ALLCONFIG");
+- if (!name)
+- break;
+- if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
+- if (conf_read_simple(name, S_DEF_USER)) {
+- fprintf(stderr,
+- _("*** Can't read seed configuration \"%s\"!\n"),
+- name);
+- exit(1);
+- }
+- break;
+- }
+- switch (input_mode) {
+- case allnoconfig: name = "allno.config"; break;
+- case allyesconfig: name = "allyes.config"; break;
+- case allmodconfig: name = "allmod.config"; break;
+- case alldefconfig: name = "alldef.config"; break;
+- case randconfig: name = "allrandom.config"; break;
+- default: break;
+- }
+- if (conf_read_simple(name, S_DEF_USER) &&
+- conf_read_simple("all.config", S_DEF_USER)) {
+- fprintf(stderr,
+- _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"),
+- name);
+- exit(1);
+- }
++ conf_read(NULL);
+ break;
+ default:
+ break;
diff --git a/package/kernel/mac80211/patches/010-disable_rfkill.patch b/package/kernel/mac80211/patches/010-disable_rfkill.patch
new file mode 100644
index 0000000000..c5a92d6b48
--- /dev/null
+++ b/package/kernel/mac80211/patches/010-disable_rfkill.patch
@@ -0,0 +1,13 @@
+--- a/backport-include/linux/rfkill.h
++++ b/backport-include/linux/rfkill.h
+@@ -2,6 +2,10 @@
+ #define __COMPAT_RFKILL_H
+ #include <linux/version.h>
+
++#undef CONFIG_RFKILL
++#undef CONFIG_RFKILL_LEDS
++#undef CONFIG_RFKILL_MODULE
++
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ #include_next <linux/rfkill.h>
+ #else
diff --git a/package/kernel/mac80211/patches/020-disable_tty_set_termios.patch b/package/kernel/mac80211/patches/020-disable_tty_set_termios.patch
new file mode 100644
index 0000000000..89c6a60e13
--- /dev/null
+++ b/package/kernel/mac80211/patches/020-disable_tty_set_termios.patch
@@ -0,0 +1,16 @@
+--- a/compat/compat-2.6.39.c
++++ b/compat/compat-2.6.39.c
+@@ -13,6 +13,7 @@
+ #include <linux/sched.h>
+ #include <linux/module.h>
+
++#ifdef CONFIG_COMPAT_BLUETOOTH
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
+ /*
+ * Termios Helper Methods
+@@ -112,4 +113,4 @@ int tty_set_termios(struct tty_struct *t
+ }
+ EXPORT_SYMBOL_GPL(tty_set_termios);
+ #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */
+-
++#endif
diff --git a/package/kernel/mac80211/patches/030-rt2x00_options.patch b/package/kernel/mac80211/patches/030-rt2x00_options.patch
new file mode 100644
index 0000000000..789a77ab12
--- /dev/null
+++ b/package/kernel/mac80211/patches/030-rt2x00_options.patch
@@ -0,0 +1,36 @@
+--- a/drivers/net/wireless/rt2x00/Kconfig
++++ b/drivers/net/wireless/rt2x00/Kconfig
+@@ -202,25 +202,28 @@ config RT2800USB_UNKNOWN
+ endif
+
+ config RT2800_LIB
+- tristate
++ tristate "RT2800 USB/PCI support"
+ depends on m
+
+ config RT2X00_LIB_MMIO
+- tristate
++ tristate "RT2x00 MMIO support"
+ depends on m
+
+ config RT2X00_LIB_PCI
+- tristate
++ tristate "RT2x00 PCI support"
++ depends on PCI
+ depends on m
+ select RT2X00_LIB
+
+ config RT2X00_LIB_SOC
+- tristate
++ tristate "RT2x00 SoC support"
++ depends on SOC_RT288X || SOC_RT305X
+ depends on m
+ select RT2X00_LIB
+
+ config RT2X00_LIB_USB
+- tristate
++ tristate "RT2x00 USB support"
++ depends on USB
+ depends on m
+ select RT2X00_LIB
+
diff --git a/package/kernel/mac80211/patches/040-brcmutil_option.patch b/package/kernel/mac80211/patches/040-brcmutil_option.patch
new file mode 100644
index 0000000000..8a6cae6122
--- /dev/null
+++ b/package/kernel/mac80211/patches/040-brcmutil_option.patch
@@ -0,0 +1,9 @@
+--- a/drivers/net/wireless/brcm80211/Kconfig
++++ b/drivers/net/wireless/brcm80211/Kconfig
+@@ -1,5 +1,5 @@
+ config BRCMUTIL
+- tristate
++ tristate "Broadcom 802.11 driver utility functions"
+ depends on m
+
+ config BRCMSMAC
diff --git a/package/kernel/mac80211/patches/050-lib80211_option.patch b/package/kernel/mac80211/patches/050-lib80211_option.patch
new file mode 100644
index 0000000000..5372114310
--- /dev/null
+++ b/package/kernel/mac80211/patches/050-lib80211_option.patch
@@ -0,0 +1,30 @@
+--- a/net/wireless/Kconfig
++++ b/net/wireless/Kconfig
+@@ -123,7 +123,7 @@ config CFG80211_WEXT
+ extensions with cfg80211-based drivers.
+
+ config LIB80211
+- tristate
++ tristate "lib80211"
+ depends on m
+ default n
+ help
+@@ -133,15 +133,15 @@ config LIB80211
+ Drivers should select this themselves if needed.
+
+ config LIB80211_CRYPT_WEP
+- tristate
++ tristate "lib80211 WEP support"
+ depends on m
+
+ config LIB80211_CRYPT_CCMP
+- tristate
++ tristate "lib80211 CCMP support"
+ depends on m
+
+ config LIB80211_CRYPT_TKIP
+- tristate
++ tristate "lib80211 TKIP support"
+ depends on m
+
+ config LIB80211_DEBUG
diff --git a/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
new file mode 100644
index 0000000000..062c2774ab
--- /dev/null
+++ b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
@@ -0,0 +1,129 @@
+--- a/.local-symbols
++++ b/.local-symbols
+@@ -365,42 +365,6 @@ USB_CDC_PHONET=
+ USB_IPHETH=
+ USB_SIERRA_NET=
+ USB_VL600=
+-SSB_POSSIBLE=
+-SSB=
+-SSB_SPROM=
+-SSB_BLOCKIO=
+-SSB_PCIHOST_POSSIBLE=
+-SSB_PCIHOST=
+-SSB_B43_PCI_BRIDGE=
+-SSB_PCMCIAHOST_POSSIBLE=
+-SSB_PCMCIAHOST=
+-SSB_SDIOHOST_POSSIBLE=
+-SSB_SDIOHOST=
+-SSB_SILENT=
+-SSB_DEBUG=
+-SSB_SERIAL=
+-SSB_DRIVER_PCICORE_POSSIBLE=
+-SSB_DRIVER_PCICORE=
+-SSB_PCICORE_HOSTMODE=
+-SSB_DRIVER_MIPS=
+-SSB_SFLASH=
+-SSB_EMBEDDED=
+-SSB_DRIVER_EXTIF=
+-SSB_DRIVER_GIGE=
+-SSB_DRIVER_GPIO=
+-BCMA_POSSIBLE=
+-BCMA=
+-BCMA_BLOCKIO=
+-BCMA_HOST_PCI_POSSIBLE=
+-BCMA_HOST_PCI=
+-BCMA_DRIVER_PCI_HOSTMODE=
+-BCMA_HOST_SOC=
+-BCMA_DRIVER_MIPS=
+-BCMA_SFLASH=
+-BCMA_NFLASH=
+-BCMA_DRIVER_GMAC_CMN=
+-BCMA_DRIVER_GPIO=
+-BCMA_DEBUG=
+ DRM=
+ DRM_USB=
+ DRM_KMS_HELPER=
+--- a/Kconfig
++++ b/Kconfig
+@@ -31,9 +31,6 @@ source drivers/net/wireless/Kconfig
+ source drivers/net/ethernet/Kconfig
+ source drivers/net/usb/Kconfig
+
+-source drivers/ssb/Kconfig
+-source drivers/bcma/Kconfig
+-
+ source drivers/gpu/drm/Kconfig
+
+ source net/nfc/Kconfig
+--- a/Makefile.kernel
++++ b/Makefile.kernel
+@@ -26,8 +26,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
+ obj-$(CPTCFG_WLAN) += drivers/net/wireless/
+ obj-$(CPTCFG_BT) += net/bluetooth/
+ obj-$(CPTCFG_BT) += drivers/bluetooth/
+-obj-$(CPTCFG_SSB) += drivers/ssb/
+-obj-$(CPTCFG_BCMA) += drivers/bcma/
+ obj-$(CPTCFG_ETHERNET) += drivers/net/ethernet/
+ obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/
+ obj-$(CPTCFG_DRM) += drivers/gpu/drm/
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -2727,7 +2727,7 @@ static struct ssb_device *b43_ssb_gpio_d
+ {
+ struct ssb_bus *bus = dev->dev->sdev->bus;
+
+-#ifdef CPTCFG_SSB_DRIVER_PCICORE
++#ifdef CONFIG_SSB_DRIVER_PCICORE
+ return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
+ #else
+ return bus->chipco.dev;
+@@ -4733,7 +4733,7 @@ static int b43_wireless_core_init(struct
+ }
+ if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
+ hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
+-#ifdef CPTCFG_SSB_DRIVER_PCICORE
++#ifdef CONFIG_SSB_DRIVER_PCICORE
+ if (dev->dev->bus_type == B43_BUS_SSB &&
+ dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
+ dev->dev->sdev->bus->pcicore.dev->id.revision <= 10)
+--- a/drivers/net/wireless/b43legacy/main.c
++++ b/drivers/net/wireless/b43legacy/main.c
+@@ -1937,7 +1937,7 @@ static int b43legacy_gpio_init(struct b4
+ if (dev->dev->id.revision >= 2)
+ mask |= 0x0010; /* FIXME: This is redundant. */
+
+-#ifdef CPTCFG_SSB_DRIVER_PCICORE
++#ifdef CONFIG_SSB_DRIVER_PCICORE
+ pcidev = bus->pcicore.dev;
+ #endif
+ gpiodev = bus->chipco.dev ? : pcidev;
+@@ -1956,7 +1956,7 @@ static void b43legacy_gpio_cleanup(struc
+ struct ssb_bus *bus = dev->dev->bus;
+ struct ssb_device *gpiodev, *pcidev = NULL;
+
+-#ifdef CPTCFG_SSB_DRIVER_PCICORE
++#ifdef CONFIG_SSB_DRIVER_PCICORE
+ pcidev = bus->pcicore.dev;
+ #endif
+ gpiodev = bus->chipco.dev ? : pcidev;
+--- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile
++++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+@@ -43,6 +43,6 @@ brcmsmac-y := \
+ brcms_trace_events.o \
+ debug.o
+
+-brcmsmac-$(CPTCFG_BCMA_DRIVER_GPIO) += led.o
++brcmsmac-$(CONFIG_BCMA_DRIVER_GPIO) += led.o
+
+ obj-$(CPTCFG_BRCMSMAC) += brcmsmac.o
+--- a/drivers/net/wireless/brcm80211/brcmsmac/led.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/led.h
+@@ -22,7 +22,7 @@ struct brcms_led {
+ bool active_low;
+ };
+
+-#ifdef CPTCFG_BCMA_DRIVER_GPIO
++#ifdef CONFIG_BCMA_DRIVER_GPIO
+ void brcms_led_unregister(struct brcms_info *wl);
+ int brcms_led_register(struct brcms_info *wl);
+ #else
diff --git a/package/kernel/mac80211/patches/150-disable_addr_notifier.patch b/package/kernel/mac80211/patches/150-disable_addr_notifier.patch
new file mode 100644
index 0000000000..92c1909981
--- /dev/null
+++ b/package/kernel/mac80211/patches/150-disable_addr_notifier.patch
@@ -0,0 +1,67 @@
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -300,7 +300,7 @@ void ieee80211_restart_hw(struct ieee802
+ }
+ EXPORT_SYMBOL(ieee80211_restart_hw);
+
+-#ifdef CONFIG_INET
++#ifdef __disabled__CONFIG_INET
+ static int ieee80211_ifa_changed(struct notifier_block *nb,
+ unsigned long data, void *arg)
+ {
+@@ -359,7 +359,7 @@ static int ieee80211_ifa_changed(struct
+ }
+ #endif
+
+-#if IS_ENABLED(CONFIG_IPV6)
++#if IS_ENABLED(__disabled__CONFIG_IPV6)
+ static int ieee80211_ifa6_changed(struct notifier_block *nb,
+ unsigned long data, void *arg)
+ {
+@@ -990,14 +990,14 @@ int ieee80211_register_hw(struct ieee802
+ goto fail_pm_qos;
+ }
+
+-#ifdef CONFIG_INET
++#ifdef __disabled__CONFIG_INET
+ local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
+ result = register_inetaddr_notifier(&local->ifa_notifier);
+ if (result)
+ goto fail_ifa;
+ #endif
+
+-#if IS_ENABLED(CONFIG_IPV6)
++#if IS_ENABLED(__disabled__CONFIG_IPV6)
+ local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
+ result = register_inet6addr_notifier(&local->ifa6_notifier);
+ if (result)
+@@ -1006,13 +1006,13 @@ int ieee80211_register_hw(struct ieee802
+
+ return 0;
+
+-#if IS_ENABLED(CONFIG_IPV6)
++#if IS_ENABLED(__disabled__CONFIG_IPV6)
+ fail_ifa6:
+-#ifdef CONFIG_INET
++#ifdef __disabled__CONFIG_INET
+ unregister_inetaddr_notifier(&local->ifa_notifier);
+ #endif
+ #endif
+-#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
++#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6)
+ fail_ifa:
+ pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
+ &local->network_latency_notifier);
+@@ -1045,10 +1045,10 @@ void ieee80211_unregister_hw(struct ieee
+
+ pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
+ &local->network_latency_notifier);
+-#ifdef CONFIG_INET
++#ifdef __disabled__CONFIG_INET
+ unregister_inetaddr_notifier(&local->ifa_notifier);
+ #endif
+-#if IS_ENABLED(CONFIG_IPV6)
++#if IS_ENABLED(__disabled__CONFIG_IPV6)
+ unregister_inet6addr_notifier(&local->ifa6_notifier);
+ #endif
+
diff --git a/package/kernel/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch b/package/kernel/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch
new file mode 100644
index 0000000000..d9672d473f
--- /dev/null
+++ b/package/kernel/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch
@@ -0,0 +1,38 @@
+--- a/drivers/net/wireless/ath/ath5k/initvals.c
++++ b/drivers/net/wireless/ath/ath5k/initvals.c
+@@ -62,8 +62,14 @@ static const struct ath5k_ini ar5210_ini
+ { AR5K_IMR, 0 },
+ { AR5K_IER, AR5K_IER_DISABLE },
+ { AR5K_BSR, 0, AR5K_INI_READ },
++#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79)
+ { AR5K_TXCFG, AR5K_DMASIZE_128B },
+ { AR5K_RXCFG, AR5K_DMASIZE_128B },
++#else
++ /* WAR for AR71xx PCI bug */
++ { AR5K_TXCFG, AR5K_DMASIZE_128B },
++ { AR5K_RXCFG, AR5K_DMASIZE_4B },
++#endif
+ { AR5K_CFG, AR5K_INIT_CFG },
+ { AR5K_TOPS, 8 },
+ { AR5K_RXNOFRM, 8 },
+--- a/drivers/net/wireless/ath/ath5k/dma.c
++++ b/drivers/net/wireless/ath/ath5k/dma.c
+@@ -860,10 +860,18 @@ ath5k_hw_dma_init(struct ath5k_hw *ah)
+ * guess we can tweak it and see how it goes ;-)
+ */
+ if (ah->ah_version != AR5K_AR5210) {
++#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79)
+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
+ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
++#else
++ /* WAR for AR71xx PCI bug */
++ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
++ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
++ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
++ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_4B);
++#endif
+ }
+
+ /* Pre-enable interrupts on 5211/5212*/
diff --git a/package/kernel/mac80211/patches/300-pending_work.patch b/package/kernel/mac80211/patches/300-pending_work.patch
new file mode 100644
index 0000000000..bd21e53405
--- /dev/null
+++ b/package/kernel/mac80211/patches/300-pending_work.patch
@@ -0,0 +1,313 @@
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -204,6 +204,8 @@ static void ieee80211_send_addba_resp(st
+ memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
++ else if (sdata->vif.type == NL80211_IFTYPE_WDS)
++ memcpy(mgmt->bssid, da, ETH_ALEN);
+
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -81,7 +81,8 @@ static void ieee80211_send_addba_request
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
+ if (sdata->vif.type == NL80211_IFTYPE_AP ||
+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
+- sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
++ sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
++ sdata->vif.type == NL80211_IFTYPE_WDS)
+ memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+@@ -527,6 +528,7 @@ int ieee80211_start_tx_ba_session(struct
+ sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
+ sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+ sdata->vif.type != NL80211_IFTYPE_AP &&
++ sdata->vif.type != NL80211_IFTYPE_WDS &&
+ sdata->vif.type != NL80211_IFTYPE_ADHOC)
+ return -EINVAL;
+
+--- a/net/mac80211/debugfs_sta.c
++++ b/net/mac80211/debugfs_sta.c
+@@ -66,11 +66,11 @@ static ssize_t sta_flags_read(struct fil
+ test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
+
+ int res = scnprintf(buf, sizeof(buf),
+- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
++ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
+ TEST(PS_DRIVER), TEST(AUTHORIZED),
+ TEST(SHORT_PREAMBLE),
+- TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
++ TEST(WME), TEST(CLEAR_PS_FILT),
+ TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
+ TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
+ TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
+--- a/net/mac80211/ht.c
++++ b/net/mac80211/ht.c
+@@ -281,13 +281,14 @@ void ieee80211_ba_session_work(struct wo
+ sta, tid, WLAN_BACK_RECIPIENT,
+ WLAN_REASON_UNSPECIFIED, true);
+
++ spin_lock_bh(&sta->lock);
++
+ tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
+ if (tid_tx) {
+ /*
+ * Assign it over to the normal tid_tx array
+ * where it "goes live".
+ */
+- spin_lock_bh(&sta->lock);
+
+ sta->ampdu_mlme.tid_start_tx[tid] = NULL;
+ /* could there be a race? */
+@@ -300,6 +301,7 @@ void ieee80211_ba_session_work(struct wo
+ ieee80211_tx_ba_session_handle_start(sta, tid);
+ continue;
+ }
++ spin_unlock_bh(&sta->lock);
+
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
+ if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -463,7 +463,6 @@ int ieee80211_do_open(struct wireless_de
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+ struct net_device *dev = wdev->netdev;
+ struct ieee80211_local *local = sdata->local;
+- struct sta_info *sta;
+ u32 changed = 0;
+ int res;
+ u32 hw_reconf_flags = 0;
+@@ -629,30 +628,8 @@ int ieee80211_do_open(struct wireless_de
+
+ set_bit(SDATA_STATE_RUNNING, &sdata->state);
+
+- if (sdata->vif.type == NL80211_IFTYPE_WDS) {
+- /* Create STA entry for the WDS peer */
+- sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
+- GFP_KERNEL);
+- if (!sta) {
+- res = -ENOMEM;
+- goto err_del_interface;
+- }
+-
+- sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+- sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
+- sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
+-
+- res = sta_info_insert(sta);
+- if (res) {
+- /* STA has been freed */
+- goto err_del_interface;
+- }
+-
+- rate_control_rate_init(sta);
+- netif_carrier_on(dev);
+- } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) {
++ if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE)
+ rcu_assign_pointer(local->p2p_sdata, sdata);
+- }
+
+ /*
+ * set_multicast_list will be invoked by the networking core
+@@ -1116,6 +1093,74 @@ static void ieee80211_if_setup(struct ne
+ dev->destructor = free_netdev;
+ }
+
++static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
++ struct sk_buff *skb)
++{
++ struct ieee80211_local *local = sdata->local;
++ struct ieee80211_rx_status *rx_status;
++ struct ieee802_11_elems elems;
++ struct ieee80211_mgmt *mgmt;
++ struct sta_info *sta;
++ size_t baselen;
++ u32 rates = 0;
++ u16 stype;
++ bool new = false;
++ enum ieee80211_band band;
++ struct ieee80211_supported_band *sband;
++
++ rx_status = IEEE80211_SKB_RXCB(skb);
++ band = rx_status->band;
++ sband = local->hw.wiphy->bands[band];
++ mgmt = (struct ieee80211_mgmt *) skb->data;
++ stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
++
++ if (stype != IEEE80211_STYPE_BEACON)
++ return;
++
++ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
++ if (baselen > skb->len)
++ return;
++
++ ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
++ skb->len - baselen, false, &elems);
++
++ rates = ieee80211_sta_get_rates(local, &elems, band, NULL);
++
++ rcu_read_lock();
++
++ sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
++
++ if (!sta) {
++ rcu_read_unlock();
++ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
++ GFP_KERNEL);
++ if (!sta)
++ return;
++
++ new = true;
++ }
++
++ sta->last_rx = jiffies;
++ sta->sta.supp_rates[band] = rates;
++
++ if (elems.ht_cap_elem)
++ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
++ elems.ht_cap_elem, sta);
++
++ if (elems.wmm_param)
++ set_sta_flag(sta, WLAN_STA_WME);
++
++ if (new) {
++ sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
++ sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
++ sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
++ rate_control_rate_init(sta);
++ sta_info_insert_rcu(sta);
++ }
++
++ rcu_read_unlock();
++}
++
+ static void ieee80211_iface_work(struct work_struct *work)
+ {
+ struct ieee80211_sub_if_data *sdata =
+@@ -1220,6 +1265,9 @@ static void ieee80211_iface_work(struct
+ break;
+ ieee80211_mesh_rx_queued_mgmt(sdata, skb);
+ break;
++ case NL80211_IFTYPE_WDS:
++ ieee80211_wds_rx_queued_mgmt(sdata, skb);
++ break;
+ default:
+ WARN(1, "frame for unexpected interface type");
+ break;
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2369,6 +2369,7 @@ ieee80211_rx_h_action(struct ieee80211_r
+ sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
+ sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+ sdata->vif.type != NL80211_IFTYPE_AP &&
++ sdata->vif.type != NL80211_IFTYPE_WDS &&
+ sdata->vif.type != NL80211_IFTYPE_ADHOC)
+ break;
+
+@@ -2720,14 +2721,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
+
+ if (!ieee80211_vif_is_mesh(&sdata->vif) &&
+ sdata->vif.type != NL80211_IFTYPE_ADHOC &&
+- sdata->vif.type != NL80211_IFTYPE_STATION)
++ sdata->vif.type != NL80211_IFTYPE_STATION &&
++ sdata->vif.type != NL80211_IFTYPE_WDS)
+ return RX_DROP_MONITOR;
+
+ switch (stype) {
+ case cpu_to_le16(IEEE80211_STYPE_AUTH):
+ case cpu_to_le16(IEEE80211_STYPE_BEACON):
+ case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
+- /* process for all: mesh, mlme, ibss */
++ /* process for all: mesh, mlme, ibss, wds */
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
+ case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
+@@ -3059,10 +3061,16 @@ static int prepare_for_handlers(struct i
+ }
+ break;
+ case NL80211_IFTYPE_WDS:
+- if (bssid || !ieee80211_is_data(hdr->frame_control))
+- return 0;
+ if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2))
+ return 0;
++
++ if (ieee80211_is_data(hdr->frame_control) ||
++ ieee80211_is_action(hdr->frame_control)) {
++ if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
++ return 0;
++ } else if (!ieee80211_is_beacon(hdr->frame_control))
++ return 0;
++
+ break;
+ case NL80211_IFTYPE_P2P_DEVICE:
+ if (!ieee80211_is_public_action(hdr, skb->len) &&
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -149,6 +149,7 @@ static void cleanup_single_sta(struct st
+ * directly by station destruction.
+ */
+ for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
++ kfree(sta->ampdu_mlme.tid_start_tx[i]);
+ tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
+ if (!tid_tx)
+ continue;
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -32,7 +32,6 @@
+ * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble
+ * frames.
+ * @WLAN_STA_WME: Station is a QoS-STA.
+- * @WLAN_STA_WDS: Station is one of our WDS peers.
+ * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
+ * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
+ * frame to this station is transmitted.
+@@ -66,7 +65,6 @@ enum ieee80211_sta_info_flags {
+ WLAN_STA_AUTHORIZED,
+ WLAN_STA_SHORT_PREAMBLE,
+ WLAN_STA_WME,
+- WLAN_STA_WDS,
+ WLAN_STA_CLEAR_PS_FILT,
+ WLAN_STA_MFP,
+ WLAN_STA_BLOCK_BA,
+@@ -203,6 +201,7 @@ struct tid_ampdu_rx {
+ * driver requested to close until the work for it runs
+ * @mtx: mutex to protect all TX data (except non-NULL assignments
+ * to tid_tx[idx], which are protected by the sta spinlock)
++ * tid_start_tx is also protected by sta->lock.
+ */
+ struct sta_ampdu_mlme {
+ struct mutex mtx;
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -1778,9 +1778,13 @@ static void ath_tx_txqaddbuf(struct ath_
+ }
+
+ if (!internal) {
+- txq->axq_depth++;
+- if (bf_is_ampdu_not_probing(bf))
+- txq->axq_ampdu_depth++;
++ while (bf) {
++ txq->axq_depth++;
++ if (bf_is_ampdu_not_probing(bf))
++ txq->axq_ampdu_depth++;
++
++ bf = bf->bf_lastbf->bf_next;
++ }
+ }
+ }
+
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+@@ -1183,7 +1183,7 @@ static int ath9k_htc_config(struct ieee8
+ mutex_lock(&priv->htc_pm_lock);
+
+ priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
+- if (priv->ps_idle)
++ if (!priv->ps_idle)
+ chip_reset = true;
+
+ mutex_unlock(&priv->htc_pm_lock);
diff --git a/package/kernel/mac80211/patches/310-ap_scan.patch b/package/kernel/mac80211/patches/310-ap_scan.patch
new file mode 100644
index 0000000000..d7479f2965
--- /dev/null
+++ b/package/kernel/mac80211/patches/310-ap_scan.patch
@@ -0,0 +1,11 @@
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -2092,7 +2092,7 @@ static int ieee80211_scan(struct wiphy *
+ * the frames sent while scanning on other channel will be
+ * lost)
+ */
+- if (sdata->u.ap.beacon &&
++ if (0 && sdata->u.ap.beacon &&
+ (!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
+ !(req->flags & NL80211_SCAN_FLAG_AP)))
+ return -EOPNOTSUPP;
diff --git a/package/kernel/mac80211/patches/400-ath_move_debug_code.patch b/package/kernel/mac80211/patches/400-ath_move_debug_code.patch
new file mode 100644
index 0000000000..a01db3ea9b
--- /dev/null
+++ b/package/kernel/mac80211/patches/400-ath_move_debug_code.patch
@@ -0,0 +1,28 @@
+--- a/drivers/net/wireless/ath/Makefile
++++ b/drivers/net/wireless/ath/Makefile
+@@ -11,7 +11,7 @@ obj-$(CPTCFG_ATH_COMMON) += ath.o
+ ath-objs := main.o \
+ regd.o \
+ hw.o \
+- key.o
++ key.o \
++ debug.o
+
+-ath-$(CPTCFG_ATH_DEBUG) += debug.o
+ ccflags-y += -D__CHECK_ENDIAN__
+--- a/drivers/net/wireless/ath/ath.h
++++ b/drivers/net/wireless/ath/ath.h
+@@ -281,13 +281,6 @@ void _ath_dbg(struct ath_common *common,
+ #endif /* CPTCFG_ATH_DEBUG */
+
+ /** Returns string describing opmode, or NULL if unknown mode. */
+-#ifdef CPTCFG_ATH_DEBUG
+ const char *ath_opmode_to_string(enum nl80211_iftype opmode);
+-#else
+-static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
+-{
+- return "UNKNOWN";
+-}
+-#endif
+
+ #endif /* ATH_H */
diff --git a/package/kernel/mac80211/patches/401-ath9k_blink_default.patch b/package/kernel/mac80211/patches/401-ath9k_blink_default.patch
new file mode 100644
index 0000000000..b0cef87762
--- /dev/null
+++ b/package/kernel/mac80211/patches/401-ath9k_blink_default.patch
@@ -0,0 +1,11 @@
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -45,7 +45,7 @@ int ath9k_modparam_nohwcrypt;
+ module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
+ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
+
+-int led_blink;
++int led_blink = 1;
+ module_param_named(blink, led_blink, int, 0444);
+ MODULE_PARM_DESC(blink, "Enable LED blink on activity");
+
diff --git a/package/kernel/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch b/package/kernel/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
new file mode 100644
index 0000000000..b2a7073307
--- /dev/null
+++ b/package/kernel/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
@@ -0,0 +1,29 @@
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -17,6 +17,7 @@
+ #include <linux/io.h>
+ #include <linux/slab.h>
+ #include <linux/module.h>
++#include <linux/etherdevice.h>
+ #include <asm/unaligned.h>
+
+ #include "hw.h"
+@@ -518,8 +519,16 @@ static int ath9k_hw_init_macaddr(struct
+ common->macaddr[2 * i] = eeval >> 8;
+ common->macaddr[2 * i + 1] = eeval & 0xff;
+ }
+- if (sum == 0 || sum == 0xffff * 3)
+- return -EADDRNOTAVAIL;
++ if (!is_valid_ether_addr(common->macaddr)) {
++ ath_err(common,
++ "eeprom contains invalid mac address: %pM\n",
++ common->macaddr);
++
++ random_ether_addr(common->macaddr);
++ ath_err(common,
++ "random mac address will be used: %pM\n",
++ common->macaddr);
++ }
+
+ return 0;
+ }
diff --git a/package/kernel/mac80211/patches/403-ath_regd_optional.patch b/package/kernel/mac80211/patches/403-ath_regd_optional.patch
new file mode 100644
index 0000000000..a9d5b6d44e
--- /dev/null
+++ b/package/kernel/mac80211/patches/403-ath_regd_optional.patch
@@ -0,0 +1,58 @@
+--- a/drivers/net/wireless/ath/regd.c
++++ b/drivers/net/wireless/ath/regd.c
+@@ -196,6 +196,10 @@ ath_reg_apply_beaconing_flags(struct wip
+ struct ieee80211_channel *ch;
+ unsigned int i;
+
++#ifdef CPTCFG_ATH_USER_REGD
++ return;
++#endif
++
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+
+ if (!wiphy->bands[band])
+@@ -250,6 +254,10 @@ ath_reg_apply_active_scan_flags(struct w
+ struct ieee80211_channel *ch;
+ const struct ieee80211_reg_rule *reg_rule;
+
++#ifdef CPTCFG_ATH_USER_REGD
++ return;
++#endif
++
+ sband = wiphy->bands[IEEE80211_BAND_2GHZ];
+ if (!sband)
+ return;
+@@ -299,6 +307,10 @@ static void ath_reg_apply_radar_flags(st
+ struct ieee80211_channel *ch;
+ unsigned int i;
+
++#ifdef CPTCFG_ATH_USER_REGD
++ return;
++#endif
++
+ if (!wiphy->bands[IEEE80211_BAND_5GHZ])
+ return;
+
+@@ -503,6 +515,10 @@ ath_regd_init_wiphy(struct ath_regulator
+ {
+ const struct ieee80211_regdomain *regd;
+
++#ifdef CPTCFG_ATH_USER_REGD
++ return 0;
++#endif
++
+ wiphy->reg_notifier = reg_notifier;
+ wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
+
+--- a/drivers/net/wireless/ath/Kconfig
++++ b/drivers/net/wireless/ath/Kconfig
+@@ -21,6 +21,9 @@ menuconfig ATH_CARDS
+
+ if ATH_CARDS
+
++config ATH_USER_REGD
++ bool "Do not enforce EEPROM regulatory restrictions"
++
+ config ATH_DEBUG
+ bool "Atheros wireless debugging"
+ ---help---
diff --git a/package/kernel/mac80211/patches/404-world_regd_fixup.patch b/package/kernel/mac80211/patches/404-world_regd_fixup.patch
new file mode 100644
index 0000000000..7a5840eb18
--- /dev/null
+++ b/package/kernel/mac80211/patches/404-world_regd_fixup.patch
@@ -0,0 +1,84 @@
+--- a/drivers/net/wireless/ath/regd.c
++++ b/drivers/net/wireless/ath/regd.c
+@@ -42,7 +42,8 @@ static int __ath_regd_init(struct ath_re
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
+
+ /* We allow IBSS on these on a case by case basis by regulatory domain */
+-#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\
++#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5250, 80, 0, 30, 0), \
++ REG_RULE(5250, 5350+10, 80, 0, 30,\
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+ #define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+@@ -60,57 +61,56 @@ static int __ath_regd_init(struct ath_re
+ #define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \
+ ATH9K_5GHZ_5725_5850
+
++#define REGD_RULES(...) \
++ .reg_rules = { __VA_ARGS__ }, \
++ .n_reg_rules = ARRAY_SIZE(((struct ieee80211_reg_rule[]) { __VA_ARGS__ }))
++
+ /* Can be used for:
+ * 0x60, 0x61, 0x62 */
+ static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
+- .n_reg_rules = 5,
+ .alpha2 = "99",
+- .reg_rules = {
++ REGD_RULES(
+ ATH9K_2GHZ_ALL,
+ ATH9K_5GHZ_ALL,
+- }
++ )
+ };
+
+ /* Can be used by 0x63 and 0x65 */
+ static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
+- .n_reg_rules = 4,
+ .alpha2 = "99",
+- .reg_rules = {
++ REGD_RULES(
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_2GHZ_CH12_13,
+ ATH9K_5GHZ_NO_MIDBAND,
+- }
++ )
+ };
+
+ /* Can be used by 0x64 only */
+ static const struct ieee80211_regdomain ath_world_regdom_64 = {
+- .n_reg_rules = 3,
+ .alpha2 = "99",
+- .reg_rules = {
++ REGD_RULES(
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_5GHZ_NO_MIDBAND,
+- }
++ )
+ };
+
+ /* Can be used by 0x66 and 0x69 */
+ static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
+- .n_reg_rules = 3,
+ .alpha2 = "99",
+- .reg_rules = {
++ REGD_RULES(
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_5GHZ_ALL,
+- }
++ )
+ };
+
+ /* Can be used by 0x67, 0x68, 0x6A and 0x6C */
+ static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
+- .n_reg_rules = 4,
+ .alpha2 = "99",
+- .reg_rules = {
++ REGD_RULES(
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_2GHZ_CH12_13,
+ ATH9K_5GHZ_ALL,
+- }
++ )
+ };
+
+ static inline bool is_wwr_sku(u16 regd)
diff --git a/package/kernel/mac80211/patches/405-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/405-regd_no_assoc_hints.patch
new file mode 100644
index 0000000000..5380853df6
--- /dev/null
+++ b/package/kernel/mac80211/patches/405-regd_no_assoc_hints.patch
@@ -0,0 +1,19 @@
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -1696,6 +1696,8 @@ void regulatory_hint_11d(struct wiphy *w
+ enum environment_cap env = ENVIRON_ANY;
+ struct regulatory_request *request = NULL, *lr;
+
++ return;
++
+ /* IE len must be evenly divisible by 2 */
+ if (country_ie_len & 0x01)
+ return;
+@@ -1890,6 +1892,7 @@ static void restore_regulatory_settings(
+
+ void regulatory_hint_disconnect(void)
+ {
++ return;
+ REG_DBG_PRINT("All devices are disconnected, going to restore regulatory settings\n");
+ restore_regulatory_settings(false);
+ }
diff --git a/package/kernel/mac80211/patches/406-ath_regd_us.patch b/package/kernel/mac80211/patches/406-ath_regd_us.patch
new file mode 100644
index 0000000000..cc55877809
--- /dev/null
+++ b/package/kernel/mac80211/patches/406-ath_regd_us.patch
@@ -0,0 +1,26 @@
+--- a/drivers/net/wireless/ath/regd_common.h
++++ b/drivers/net/wireless/ath/regd_common.h
+@@ -32,6 +32,7 @@ enum EnumRd {
+ FCC2_WORLD = 0x21,
+ FCC2_ETSIC = 0x22,
+ FCC6_WORLD = 0x23,
++ FCC3_FCCA_2 = 0x2A,
+ FRANCE_RES = 0x31,
+ FCC3_FCCA = 0x3A,
+ FCC3_WORLD = 0x3B,
+@@ -167,6 +168,7 @@ static struct reg_dmn_pair_mapping regDo
+ {FCC2_WORLD, CTL_FCC, CTL_ETSI},
+ {FCC2_ETSIC, CTL_FCC, CTL_ETSI},
+ {FCC3_FCCA, CTL_FCC, CTL_FCC},
++ {FCC3_FCCA_2, CTL_FCC, CTL_FCC},
+ {FCC3_WORLD, CTL_FCC, CTL_ETSI},
+ {FCC4_FCCA, CTL_FCC, CTL_FCC},
+ {FCC5_FCCA, CTL_FCC, CTL_FCC},
+@@ -463,6 +465,7 @@ static struct country_code_to_enum_rd al
+ {CTRY_UAE, NULL1_WORLD, "AE"},
+ {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
+ {CTRY_UNITED_STATES, FCC3_FCCA, "US"},
++ {CTRY_UNITED_STATES, FCC3_FCCA_2, "US"},
+ /* This "PS" is for US public safety actually... to support this we
+ * would need to assign new special alpha2 to CRDA db as with the world
+ * regdomain and use another alpha2 */
diff --git a/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
new file mode 100644
index 0000000000..2eae3916dd
--- /dev/null
+++ b/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
@@ -0,0 +1,10 @@
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -729,6 +729,7 @@ static const struct ieee80211_iface_limi
+ #endif
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_GO) },
++ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
+ };
+
+
diff --git a/package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
new file mode 100644
index 0000000000..12e03e1bb1
--- /dev/null
+++ b/package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
@@ -0,0 +1,46 @@
+--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+@@ -86,13 +86,8 @@ ath5k_add_interface(struct ieee80211_hw
+ goto end;
+ }
+
+- /* Don't allow other interfaces if one ad-hoc is configured.
+- * TODO: Fix the problems with ad-hoc and multiple other interfaces.
+- * We would need to operate the HW in ad-hoc mode to allow TSF updates
+- * for the IBSS, but this breaks with additional AP or STA interfaces
+- * at the moment. */
+- if (ah->num_adhoc_vifs ||
+- (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
++ /* Don't allow more than one ad-hoc interface */
++ if (ah->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) {
+ ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n");
+ ret = -ELNRNG;
+ goto end;
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -1916,7 +1916,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
+ }
+
+ if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
+- ah->num_mesh_vifs > 1) ||
++ ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) ||
+ ah->opmode == NL80211_IFTYPE_MESH_POINT) {
+ u64 tsf = ath5k_hw_get_tsf64(ah);
+ u32 tsftu = TSF_TO_TU(tsf);
+@@ -2002,7 +2002,7 @@ ath5k_beacon_update_timers(struct ath5k_
+
+ intval = ah->bintval & AR5K_BEACON_PERIOD;
+ if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
+- + ah->num_mesh_vifs > 1) {
++ + ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) {
+ intval /= ATH_BCBUF; /* staggered multi-bss beacons */
+ if (intval < 15)
+ ATH5K_WARN(ah, "intval %u is too low, min 15\n",
+@@ -2469,6 +2469,7 @@ static const struct ieee80211_iface_limi
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+ #endif
+ BIT(NL80211_IFTYPE_AP) },
++ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
+ };
+
+ static const struct ieee80211_iface_combination if_comb = {
diff --git a/package/kernel/mac80211/patches/420-ath5k_disable_fast_cc.patch b/package/kernel/mac80211/patches/420-ath5k_disable_fast_cc.patch
new file mode 100644
index 0000000000..414f49508f
--- /dev/null
+++ b/package/kernel/mac80211/patches/420-ath5k_disable_fast_cc.patch
@@ -0,0 +1,18 @@
+--- a/drivers/net/wireless/ath/ath5k/reset.c
++++ b/drivers/net/wireless/ath/ath5k/reset.c
+@@ -1154,6 +1154,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
+ tsf_lo = 0;
+ mode = 0;
+
++#if 0
+ /*
+ * Sanity check for fast flag
+ * Fast channel change only available
+@@ -1161,6 +1162,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
+ */
+ if (fast && (ah->ah_radio != AR5K_RF2413) &&
+ (ah->ah_radio != AR5K_RF5413))
++#endif
+ fast = false;
+
+ /* Disable sleep clock operation
diff --git a/package/kernel/mac80211/patches/430-add_ath5k_platform.patch b/package/kernel/mac80211/patches/430-add_ath5k_platform.patch
new file mode 100644
index 0000000000..b213e2a819
--- /dev/null
+++ b/package/kernel/mac80211/patches/430-add_ath5k_platform.patch
@@ -0,0 +1,33 @@
+--- /dev/null
++++ b/include/linux/ath5k_platform.h
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (c) 2008 Atheros Communications Inc.
++ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
++ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (c) 2010 Daniel Golle <daniel.golle@gmail.com>
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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_ATH5K_PLATFORM_H
++#define _LINUX_ATH5K_PLATFORM_H
++
++#define ATH5K_PLAT_EEP_MAX_WORDS 2048
++
++struct ath5k_platform_data {
++ u16 *eeprom_data;
++ u8 *macaddr;
++};
++
++#endif /* _LINUX_ATH5K_PLATFORM_H */
diff --git a/package/kernel/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch b/package/kernel/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch
new file mode 100644
index 0000000000..a223b38348
--- /dev/null
+++ b/package/kernel/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch
@@ -0,0 +1,56 @@
+--- a/drivers/net/wireless/ath/ath5k/pci.c
++++ b/drivers/net/wireless/ath/ath5k/pci.c
+@@ -21,6 +21,7 @@
+ #include <linux/pci-aspm.h>
+ #include <linux/etherdevice.h>
+ #include <linux/module.h>
++#include <linux/ath5k_platform.h>
+ #include "../ath.h"
+ #include "ath5k.h"
+ #include "debug.h"
+@@ -72,7 +73,7 @@ static void ath5k_pci_read_cachesize(str
+ }
+
+ /*
+- * Read from eeprom
++ * Read from eeprom or platform_data
+ */
+ static bool
+ ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
+@@ -80,6 +81,19 @@ ath5k_pci_eeprom_read(struct ath_common
+ struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;
+ u32 status, timeout;
+
++ struct ath5k_platform_data *pdata = NULL;
++
++ if (ah->pdev)
++ pdata = ah->pdev->dev.platform_data;
++
++ if (pdata && pdata->eeprom_data && pdata->eeprom_data[61] == AR5K_EEPROM_MAGIC_VALUE) {
++ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS)
++ return false;
++
++ *data = pdata->eeprom_data[offset];
++ return true;
++ }
++
+ /*
+ * Initialize EEPROM access
+ */
+@@ -123,6 +137,16 @@ static int ath5k_pci_eeprom_read_mac(str
+ u16 data;
+ int octet;
+
++ struct ath5k_platform_data *pdata = NULL;
++
++ if (ah->pdev)
++ pdata = ah->pdev->dev.platform_data;
++
++ if (pdata && pdata->macaddr) {
++ memcpy(mac, pdata->macaddr, ETH_ALEN);
++ return 0;
++ }
++
+ AR5K_EEPROM_READ(0x20, data);
+
+ for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
diff --git a/package/kernel/mac80211/patches/432-ath5k_add_pciids.patch b/package/kernel/mac80211/patches/432-ath5k_add_pciids.patch
new file mode 100644
index 0000000000..e5c85cee61
--- /dev/null
+++ b/package/kernel/mac80211/patches/432-ath5k_add_pciids.patch
@@ -0,0 +1,11 @@
+--- a/drivers/net/wireless/ath/ath5k/pci.c
++++ b/drivers/net/wireless/ath/ath5k/pci.c
+@@ -48,6 +48,8 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_pci
+ { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
+ { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
+ { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
++ { PCI_VDEVICE(ATHEROS, 0xff16) }, /* 2413,2414 sx76x on lantiq_danube */
++ { PCI_VDEVICE(ATHEROS, 0xff1a) }, /* 2417 arv45xx on lantiq_danube */
+ { PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */
+ { 0 }
+ };
diff --git a/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch b/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch
new file mode 100644
index 0000000000..01c28bcca2
--- /dev/null
+++ b/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch
@@ -0,0 +1,113 @@
+This adds a bwmode debugfs file which can be used to set alternate
+channel operating bandwidths. Only tested with AR5413 and only at
+5 and 20 mhz channels.
+
+Signed-off-by: Pat Erley <pat-lkml at erley.org>
+---
+Other devices will need to be added to the switch in write_file_bwmode
+
+drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++
+ 1 files changed, 86 insertions(+), 0 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath5k/debug.c
++++ b/drivers/net/wireless/ath/ath5k/debug.c
+@@ -811,6 +811,89 @@ static const struct file_operations fops
+ .llseek = default_llseek,
+ };
+
++/* debugfs: bwmode */
++
++static ssize_t read_file_bwmode(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath5k_hw *ah = file->private_data;
++ char buf[15];
++ unsigned int len = 0;
++
++ int cur_ah_bwmode = ah->ah_bwmode;
++
++#define print_selected(MODE, LABEL) \
++ if (cur_ah_bwmode == MODE) \
++ len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \
++ else \
++ len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \
++ len += snprintf(buf+len, sizeof(buf)-len, " ");
++
++ print_selected(AR5K_BWMODE_5MHZ, "5");
++ print_selected(AR5K_BWMODE_10MHZ, "10");
++ print_selected(AR5K_BWMODE_DEFAULT, "20");
++ print_selected(AR5K_BWMODE_40MHZ, "40");
++#undef print_selected
++
++ len += snprintf(buf+len, sizeof(buf)-len, "\n");
++
++ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
++}
++
++static ssize_t write_file_bwmode(struct file *file,
++ const char __user *userbuf,
++ size_t count, loff_t *ppos)
++{
++ struct ath5k_hw *ah = file->private_data;
++ char buf[3];
++ int bw = 20;
++ int tobwmode = AR5K_BWMODE_DEFAULT;
++
++ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
++ return -EFAULT;
++
++ /* TODO: Add check for active interface */
++
++ if(strncmp(buf, "5", 1) == 0 ) {
++ tobwmode = AR5K_BWMODE_5MHZ;
++ bw = 5;
++ } else if ( strncmp(buf, "10", 2) == 0 ) {
++ tobwmode = AR5K_BWMODE_10MHZ;
++ bw = 10;
++ } else if ( strncmp(buf, "20", 2) == 0 ) {
++ tobwmode = AR5K_BWMODE_DEFAULT;
++ bw = 20;
++ } else if ( strncmp(buf, "40", 2) == 0 ) {
++ tobwmode = AR5K_BWMODE_40MHZ;
++ bw = 40;
++ } else
++ return -EINVAL;
++
++ ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n",
++ bw, tobwmode);
++
++ switch (ah->ah_radio) {
++ /* TODO: only define radios that actually support 5/10mhz channels */
++ case AR5K_RF5413: case AR5K_RF5110: case AR5K_RF5111: case AR5K_RF5112: case AR5K_RF2413: case AR5K_RF2316: case AR5K_RF2317: case AR5K_RF2425:
++ if(ah->ah_bwmode != tobwmode) {
++ mutex_lock(&ah->lock);
++ ah->ah_bwmode = tobwmode;
++ mutex_unlock(&ah->lock);
++ }
++ break;
++ default:
++ return -EOPNOTSUPP;
++ }
++ return count;
++}
++
++static const struct file_operations fops_bwmode = {
++ .read = read_file_bwmode,
++ .write = write_file_bwmode,
++ .open = simple_open,
++ .owner = THIS_MODULE,
++ .llseek = default_llseek,
++};
+
+ /* debugfs: queues etc */
+
+@@ -902,6 +985,9 @@ ath5k_debug_init_device(struct ath5k_hw
+ debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah,
+ &fops_beacon);
+
++ debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah,
++ &fops_bwmode);
++
+ debugfs_create_file("reset", S_IWUSR, phydir, ah, &fops_reset);
+
+ debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah,
diff --git a/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch
new file mode 100644
index 0000000000..7f4e68d5ea
--- /dev/null
+++ b/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch
@@ -0,0 +1,65 @@
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -1735,6 +1735,53 @@ void ath9k_deinit_debug(struct ath_softc
+ }
+ }
+
++static ssize_t read_file_eeprom(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ struct ath_hw *ah = sc->sc_ah;
++ struct ath_common *common = ath9k_hw_common(ah);
++ int bytes = 0;
++ int pos = *ppos;
++ int size = 4096;
++ u16 val;
++ int i;
++
++ if (AR_SREV_9300_20_OR_LATER(ah))
++ size = 16384;
++
++ if (*ppos < 0)
++ return -EINVAL;
++
++ if (count > size - *ppos)
++ count = size - *ppos;
++
++ for (i = *ppos / 2; count > 0; count -= bytes, *ppos += bytes, i++) {
++ void *from = &val;
++
++ if (!common->bus_ops->eeprom_read(common, i, &val))
++ val = 0xffff;
++
++ if (*ppos % 2) {
++ from++;
++ bytes = 1;
++ } else if (count == 1) {
++ bytes = 1;
++ } else {
++ bytes = 2;
++ }
++ copy_to_user(user_buf, from, bytes);
++ user_buf += bytes;
++ }
++ return *ppos - pos;
++}
++
++static const struct file_operations fops_eeprom = {
++ .read = read_file_eeprom,
++ .open = simple_open,
++ .owner = THIS_MODULE
++};
++
+ int ath9k_init_debug(struct ath_hw *ah)
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
+@@ -1752,6 +1799,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+
+ ath9k_dfs_init_debug(sc);
+
++ debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
++ &fops_eeprom);
+ debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_dma);
+ debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
diff --git a/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch b/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch
new file mode 100644
index 0000000000..3d904e939d
--- /dev/null
+++ b/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch
@@ -0,0 +1,102 @@
+--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
+@@ -262,7 +262,7 @@ static int ath9k_hw_def_check_eeprom(str
+ {
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+ struct ath_common *common = ath9k_hw_common(ah);
+- u16 *eepdata, temp, magic, magic2;
++ u16 *eepdata, temp, magic;
+ u32 sum = 0, el;
+ bool need_swap = false;
+ int i, addr, size;
+@@ -272,27 +272,16 @@ static int ath9k_hw_def_check_eeprom(str
+ return false;
+ }
+
+- if (!ath9k_hw_use_flash(ah)) {
+- ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic);
+-
+- if (magic != AR5416_EEPROM_MAGIC) {
+- magic2 = swab16(magic);
+-
+- if (magic2 == AR5416_EEPROM_MAGIC) {
+- size = sizeof(struct ar5416_eeprom_def);
+- need_swap = true;
+- eepdata = (u16 *) (&ah->eeprom);
+-
+- for (addr = 0; addr < size / sizeof(u16); addr++) {
+- temp = swab16(*eepdata);
+- *eepdata = temp;
+- eepdata++;
+- }
+- } else {
+- ath_err(common,
+- "Invalid EEPROM Magic. Endianness mismatch.\n");
+- return -EINVAL;
+- }
++ if (swab16(magic) == AR5416_EEPROM_MAGIC &&
++ !(ah->ah_flags & AH_NO_EEP_SWAP)) {
++ size = sizeof(struct ar5416_eeprom_def);
++ need_swap = true;
++ eepdata = (u16 *) (&ah->eeprom);
++
++ for (addr = 0; addr < size / sizeof(u16); addr++) {
++ temp = swab16(*eepdata);
++ *eepdata = temp;
++ eepdata++;
+ }
+ }
+
+--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+@@ -57,7 +57,7 @@ static bool ath9k_hw_4k_fill_eeprom(stru
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
+
+- if (!ath9k_hw_use_flash(ah)) {
++ if (!(ah->ah_flags & AH_NO_EEP_SWAP)) {
+ ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n");
+ }
+
+--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+@@ -60,7 +60,7 @@ static bool ath9k_hw_ar9287_fill_eeprom(
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
+
+- if (!ath9k_hw_use_flash(ah)) {
++ if (!(ah->ah_flags & AH_NO_EEP_SWAP)) {
+ ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n");
+ }
+
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -735,6 +735,7 @@ enum ath_cal_list {
+ #define AH_USE_EEPROM 0x1
+ #define AH_UNPLUGGED 0x2 /* The card has been physically removed. */
+ #define AH_FASTCC 0x4
++#define AH_NO_EEP_SWAP 0x8 /* Do not swap EEPROM data */
+
+ struct ath_hw {
+ struct ath_ops reg_ops;
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -592,6 +592,8 @@ static int ath9k_init_softc(u16 devid, s
+ ah->is_clk_25mhz = pdata->is_clk_25mhz;
+ ah->get_mac_revision = pdata->get_mac_revision;
+ ah->external_reset = pdata->external_reset;
++ if (!pdata->endian_check)
++ ah->ah_flags |= AH_NO_EEP_SWAP;
+ }
+
+ common = ath9k_hw_common(ah);
+--- a/include/linux/ath9k_platform.h
++++ b/include/linux/ath9k_platform.h
+@@ -31,6 +31,7 @@ struct ath9k_platform_data {
+ u32 gpio_mask;
+ u32 gpio_val;
+
++ bool endian_check;
+ bool is_clk_25mhz;
+ int (*get_mac_revision)(void);
+ int (*external_reset)(void);
diff --git a/package/kernel/mac80211/patches/502-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/502-ath9k_ahb_init.patch
new file mode 100644
index 0000000000..9e715526a6
--- /dev/null
+++ b/package/kernel/mac80211/patches/502-ath9k_ahb_init.patch
@@ -0,0 +1,32 @@
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -984,23 +984,23 @@ static int __init ath9k_init(void)
+ goto err_out;
+ }
+
+- error = ath_pci_init();
++ error = ath_ahb_init();
+ if (error < 0) {
+- pr_err("No PCI devices found, driver not installed\n");
+ error = -ENODEV;
+ goto err_rate_unregister;
+ }
+
+- error = ath_ahb_init();
++ error = ath_pci_init();
+ if (error < 0) {
++ pr_err("No PCI devices found, driver not installed\n");
+ error = -ENODEV;
+- goto err_pci_exit;
++ goto err_ahb_exit;
+ }
+
+ return 0;
+
+- err_pci_exit:
+- ath_pci_exit();
++ err_ahb_exit:
++ ath_ahb_exit();
+
+ err_rate_unregister:
+ ath_rate_control_unregister();
diff --git a/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch b/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
new file mode 100644
index 0000000000..647bde2ca0
--- /dev/null
+++ b/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
@@ -0,0 +1,13 @@
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -2010,8 +2010,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+ REG_WRITE(ah, AR_OBS, 8);
+
+ if (ah->config.rx_intr_mitigation) {
+- REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
+- REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
++ REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 250);
++ REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 500);
+ }
+
+ if (ah->config.tx_intr_mitigation) {
diff --git a/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch
new file mode 100644
index 0000000000..8d8c5fd7fe
--- /dev/null
+++ b/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch
@@ -0,0 +1,11 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -119,7 +119,7 @@ int ath_descdma_setup(struct ath_softc *
+ /* RX / TX */
+ /***********/
+
+-#define ATH_RXBUF 512
++#define ATH_RXBUF 256
+ #define ATH_TXBUF 512
+ #define ATH_TXBUF_RESERVE 5
+ #define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
diff --git a/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
new file mode 100644
index 0000000000..ef87a35922
--- /dev/null
+++ b/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
@@ -0,0 +1,128 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -696,6 +696,7 @@ struct ath_softc {
+ struct ieee80211_hw *hw;
+ struct device *dev;
+
++ u32 chan_bw;
+ struct survey_info *cur_survey;
+ struct survey_info survey[ATH9K_NUM_CHANNELS];
+
+@@ -899,6 +900,7 @@ struct fft_sample_ht20 {
+ u8 data[SPECTRAL_HT20_NUM_BINS];
+ } __packed;
+
++int ath9k_config(struct ieee80211_hw *hw, u32 changed);
+ void ath9k_tasklet(unsigned long data);
+ int ath_cabq_update(struct ath_softc *);
+
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -1782,6 +1782,50 @@ static const struct file_operations fops
+ .owner = THIS_MODULE
+ };
+
++
++static ssize_t read_file_chan_bw(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ char buf[32];
++ unsigned int len;
++
++ len = sprintf(buf, "0x%08x\n", sc->chan_bw);
++ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
++}
++
++static ssize_t write_file_chan_bw(struct file *file, const char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ unsigned long chan_bw;
++ char buf[32];
++ ssize_t len;
++
++ len = min(count, sizeof(buf) - 1);
++ if (copy_from_user(buf, user_buf, len))
++ return -EFAULT;
++
++ buf[len] = '\0';
++ if (strict_strtoul(buf, 0, &chan_bw))
++ return -EINVAL;
++
++ sc->chan_bw = chan_bw;
++ if (!test_bit(SC_OP_INVALID, &sc->sc_flags))
++ ath9k_config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL);
++
++ return count;
++}
++
++static const struct file_operations fops_chanbw = {
++ .read = read_file_chan_bw,
++ .write = write_file_chan_bw,
++ .open = simple_open,
++ .owner = THIS_MODULE,
++ .llseek = default_llseek,
++};
++
++
+ int ath9k_init_debug(struct ath_hw *ah)
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
+@@ -1801,6 +1845,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+
+ debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_eeprom);
++ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
++ sc, &fops_chanbw);
+ debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_dma);
+ debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -1139,7 +1139,7 @@ int ath9k_spectral_scan_config(struct ie
+ return 0;
+ }
+
+-static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
++int ath9k_config(struct ieee80211_hw *hw, u32 changed)
+ {
+ struct ath_softc *sc = hw->priv;
+ struct ath_hw *ah = sc->sc_ah;
+@@ -1195,9 +1195,11 @@ static int ath9k_config(struct ieee80211
+ struct ieee80211_channel *curchan = hw->conf.chandef.chan;
+ enum nl80211_channel_type channel_type =
+ cfg80211_get_chandef_type(&conf->chandef);
++ struct ath9k_channel *hchan;
+ int pos = curchan->hw_value;
+ int old_pos = -1;
+ unsigned long flags;
++ u32 oldflags;
+
+ if (ah->curchan)
+ old_pos = ah->curchan - &ah->channels[0];
+@@ -1233,7 +1235,23 @@ static int ath9k_config(struct ieee80211
+ memset(&sc->survey[pos], 0, sizeof(struct survey_info));
+ }
+
+- if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
++ hchan = &sc->sc_ah->channels[pos];
++ oldflags = hchan->channelFlags;
++ switch (sc->chan_bw) {
++ case 5:
++ hchan->channelFlags &= ~CHANNEL_HALF;
++ hchan->channelFlags |= CHANNEL_QUARTER;
++ break;
++ case 10:
++ hchan->channelFlags &= ~CHANNEL_QUARTER;
++ hchan->channelFlags |= CHANNEL_HALF;
++ break;
++ default:
++ hchan->channelFlags &= ~(CHANNEL_HALF | CHANNEL_QUARTER);
++ break;
++ }
++
++ if (ath_set_channel(sc, hw, hchan) < 0) {
+ ath_err(common, "Unable to set channel\n");
+ mutex_unlock(&sc->mutex);
+ ath9k_ps_restore(sc);
diff --git a/package/kernel/mac80211/patches/520-mac80211_cur_txpower.patch b/package/kernel/mac80211/patches/520-mac80211_cur_txpower.patch
new file mode 100644
index 0000000000..8583cdc25b
--- /dev/null
+++ b/package/kernel/mac80211/patches/520-mac80211_cur_txpower.patch
@@ -0,0 +1,33 @@
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1614,6 +1614,7 @@ struct ieee80211_hw {
+ u8 max_tx_aggregation_subframes;
+ u8 offchannel_tx_hw_queue;
+ u8 radiotap_mcs_details;
++ s8 cur_power_level;
+ u16 radiotap_vht_details;
+ netdev_features_t netdev_features;
+ u8 uapsd_queues;
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -2273,7 +2273,9 @@ static int ieee80211_get_tx_power(struct
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+
+- if (!local->use_chanctx)
++ if (local->hw.cur_power_level)
++ *dbm = local->hw.cur_power_level;
++ else if (!local->use_chanctx)
+ *dbm = local->hw.conf.power_level;
+ else
+ *dbm = sdata->vif.bss_conf.txpower;
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -167,6 +167,7 @@ static u32 ieee80211_hw_conf_chan(struct
+
+ if (local->hw.conf.power_level != power) {
+ changed |= IEEE80211_CONF_CHANGE_POWER;
++ local->hw.cur_power_level = power;
+ local->hw.conf.power_level = power;
+ }
+
diff --git a/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch b/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch
new file mode 100644
index 0000000000..87a316c4f0
--- /dev/null
+++ b/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch
@@ -0,0 +1,19 @@
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -1258,6 +1258,8 @@ int ath9k_config(struct ieee80211_hw *hw
+ return -EINVAL;
+ }
+
++ hw->cur_power_level = sc->curtxpow / 2;
++
+ /*
+ * The most recent snapshot of channel->noisefloor for the old
+ * channel is only available after the hardware reset. Copy it to
+@@ -1294,6 +1296,7 @@ int ath9k_config(struct ieee80211_hw *hw
+ sc->config.txpowlimit = 2 * conf->power_level;
+ ath9k_cmn_update_txpow(ah, sc->curtxpow,
+ sc->config.txpowlimit, &sc->curtxpow);
++ hw->cur_power_level = sc->curtxpow / 2;
+ }
+
+ mutex_unlock(&sc->mutex);
diff --git a/package/kernel/mac80211/patches/522-ath9k_per_chain_signal_strength.patch b/package/kernel/mac80211/patches/522-ath9k_per_chain_signal_strength.patch
new file mode 100644
index 0000000000..50dbcd9902
--- /dev/null
+++ b/package/kernel/mac80211/patches/522-ath9k_per_chain_signal_strength.patch
@@ -0,0 +1,153 @@
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -133,12 +133,8 @@ struct ath_rx_status {
+ u8 rs_rate;
+ u8 rs_antenna;
+ u8 rs_more;
+- int8_t rs_rssi_ctl0;
+- int8_t rs_rssi_ctl1;
+- int8_t rs_rssi_ctl2;
+- int8_t rs_rssi_ext0;
+- int8_t rs_rssi_ext1;
+- int8_t rs_rssi_ext2;
++ int8_t rs_rssi_ctl[3];
++ int8_t rs_rssi_ext[3];
+ u8 rs_isaggr;
+ u8 rs_moreaggr;
+ u8 rs_num_delims;
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -939,6 +939,7 @@ static int ath9k_rx_skb_preprocess(struc
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ bool discard_current = sc->rx.discard_next;
++ int i, j;
+
+ sc->rx.discard_next = rx_stats->rs_more;
+ if (discard_current)
+@@ -968,6 +969,21 @@ static int ath9k_rx_skb_preprocess(struc
+ if (rx_stats->rs_moreaggr)
+ rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
+
++ for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) {
++ s8 rssi;
++
++ if (!(ah->rxchainmask & BIT(i)))
++ continue;
++
++ rssi = rx_stats->rs_rssi_ctl[i];
++ if (rssi != ATH9K_RSSI_BAD) {
++ rx_status->chains |= BIT(j);
++ rx_status->chain_signal[j] = ah->noise + rssi;
++ }
++ j++;
++ }
++
++
+ sc->rx.discard_next = false;
+ return 0;
+ }
+@@ -1077,7 +1093,7 @@ static int ath_process_fft(struct ath_so
+ fft_sample.tlv.length = __cpu_to_be16(length);
+
+ fft_sample.freq = __cpu_to_be16(ah->curchan->chan->center_freq);
+- fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
++ fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl[0]);
+ fft_sample.noise = ah->noise;
+
+ switch (len - SPECTRAL_HT20_TOTAL_DATA_LEN) {
+--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+@@ -476,12 +476,12 @@ int ath9k_hw_process_rxdesc_edma(struct
+
+ /* XXX: Keycache */
+ rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
+- rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
+- rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
+- rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
+- rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
+- rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
+- rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
++ rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00);
++ rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01);
++ rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02);
++ rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10);
++ rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11);
++ rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12);
+
+ if (rxsp->status11 & AR_RxKeyIdxValid)
+ rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -554,25 +554,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
+
+ if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
+ rs->rs_rssi = ATH9K_RSSI_BAD;
+- rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
+- rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
+- rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
+- rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
+- rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
+- rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
++ rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD;
++ rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD;
++ rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD;
++ rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD;
++ rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD;
++ rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD;
+ } else {
+ rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
+- rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
++ rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0,
+ AR_RxRSSIAnt00);
+- rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
++ rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0,
+ AR_RxRSSIAnt01);
+- rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
++ rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0,
+ AR_RxRSSIAnt02);
+- rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
++ rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4,
+ AR_RxRSSIAnt10);
+- rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
++ rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4,
+ AR_RxRSSIAnt11);
+- rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
++ rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4,
+ AR_RxRSSIAnt12);
+ }
+ if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
+--- a/drivers/net/wireless/ath/ath9k/dfs.c
++++ b/drivers/net/wireless/ath/ath9k/dfs.c
+@@ -158,8 +158,8 @@ void ath9k_dfs_process_phyerr(struct ath
+ return;
+ }
+
+- ard.rssi = rs->rs_rssi_ctl0;
+- ard.ext_rssi = rs->rs_rssi_ext0;
++ ard.rssi = rs->rs_rssi_ctl[0];
++ ard.ext_rssi = rs->rs_rssi_ext[0];
+
+ /*
+ * hardware stores this as 8 bit signed value.
+--- a/drivers/net/wireless/ath/ath9k/antenna.c
++++ b/drivers/net/wireless/ath/ath9k/antenna.c
+@@ -546,14 +546,14 @@ void ath_ant_comb_scan(struct ath_softc
+ 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;
+- int main_rssi = rs->rs_rssi_ctl0;
+- int alt_rssi = rs->rs_rssi_ctl1;
++ int main_rssi = rs->rs_rssi_ctl[0];
++ int alt_rssi = rs->rs_rssi_ctl[1];
+ int rx_ant_conf, main_ant_conf;
+ bool short_scan = false;
+
+- rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) &
++ rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) &
+ ATH_ANT_RX_MASK;
+- main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
++ main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) &
+ ATH_ANT_RX_MASK;
+
+ /* Record packet only when both main_rssi and alt_rssi is positive */
diff --git a/package/kernel/mac80211/patches/523-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/523-mac80211_configure_antenna_gain.patch
new file mode 100644
index 0000000000..759812bfd7
--- /dev/null
+++ b/package/kernel/mac80211/patches/523-mac80211_configure_antenna_gain.patch
@@ -0,0 +1,162 @@
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -997,6 +997,7 @@ enum ieee80211_smps_mode {
+ *
+ * @power_level: requested transmit power (in dBm), backward compatibility
+ * value only that is set to the minimum of all interfaces
++ * @max_antenna_gain: maximum antenna gain adjusted by user config (in dBi)
+ *
+ * @chandef: the channel definition to tune to
+ * @radar_enabled: whether radar detection is enabled
+@@ -1018,6 +1019,7 @@ struct ieee80211_conf {
+ u32 flags;
+ int power_level, dynamic_ps_timeout;
+ int max_sleep_period;
++ int max_antenna_gain;
+
+ u16 listen_interval;
+ u8 ps_dtim_period;
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1126,6 +1126,7 @@ struct ieee80211_local {
+ int dynamic_ps_forced_timeout;
+
+ int user_power_level; /* in dBm, for all interfaces */
++ int user_antenna_gain; /* in dBi */
+
+ enum ieee80211_smps_mode smps_mode;
+
+--- a/include/uapi/linux/nl80211.h
++++ b/include/uapi/linux/nl80211.h
+@@ -1736,6 +1736,8 @@ enum nl80211_attrs {
+
+ NL80211_ATTR_PEER_AID,
+
++ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
++
+ /* add attributes here, update the policy in nl80211.c */
+
+ __NL80211_ATTR_AFTER_LAST,
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -349,6 +349,7 @@ static const struct nla_policy nl80211_p
+ [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
+ .len = IEEE80211_MAX_DATA_LEN },
+ [NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
++ [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
+ };
+
+ /* policy for the key attributes */
+@@ -1953,6 +1954,22 @@ static int nl80211_set_wiphy(struct sk_b
+ goto bad_res;
+ }
+
++ if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) {
++ int idx, dbi = 0;
++
++ if (!rdev->ops->set_antenna_gain) {
++ result = -EOPNOTSUPP;
++ goto bad_res;
++ }
++
++ idx = NL80211_ATTR_WIPHY_ANTENNA_GAIN;
++ dbi = nla_get_u32(info->attrs[idx]);
++
++ result = rdev->ops->set_antenna_gain(&rdev->wiphy, dbi);
++ if (result)
++ goto bad_res;
++ }
++
+ if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
+ info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
+ u32 tx_ant, rx_ant;
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -2283,6 +2283,19 @@ static int ieee80211_get_tx_power(struct
+ return 0;
+ }
+
++static int ieee80211_set_antenna_gain(struct wiphy *wiphy, int dbi)
++{
++ struct ieee80211_local *local = wiphy_priv(wiphy);
++
++ if (dbi < 0)
++ return -EINVAL;
++
++ local->user_antenna_gain = dbi;
++ ieee80211_hw_config(local, 0);
++
++ return 0;
++}
++
+ static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *addr)
+ {
+@@ -3484,6 +3497,7 @@ struct cfg80211_ops mac80211_config_ops
+ .set_wiphy_params = ieee80211_set_wiphy_params,
+ .set_tx_power = ieee80211_set_tx_power,
+ .get_tx_power = ieee80211_get_tx_power,
++ .set_antenna_gain = ieee80211_set_antenna_gain,
+ .set_wds_peer = ieee80211_set_wds_peer,
+ .rfkill_poll = ieee80211_rfkill_poll,
+ CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -1942,6 +1942,7 @@ struct cfg80211_update_ft_ies_params {
+ * (as advertised by the nl80211 feature flag.)
+ * @get_tx_power: store the current TX power into the dbm variable;
+ * return 0 if successful
++ * @set_antenna_gain: set antenna gain to reduce maximum tx power if necessary
+ *
+ * @set_wds_peer: set the WDS peer for a WDS interface
+ *
+@@ -2161,6 +2162,7 @@ struct cfg80211_ops {
+ enum nl80211_tx_power_setting type, int mbm);
+ int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
+ int *dbm);
++ int (*set_antenna_gain)(struct wiphy *wiphy, int dbi);
+
+ int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *addr);
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -101,7 +101,7 @@ static u32 ieee80211_hw_conf_chan(struct
+ struct ieee80211_sub_if_data *sdata;
+ struct cfg80211_chan_def chandef = {};
+ u32 changed = 0;
+- int power;
++ int power, ant_gain, max_power;
+ u32 offchannel_flag;
+
+ offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
+@@ -165,8 +165,21 @@ static u32 ieee80211_hw_conf_chan(struct
+ }
+ rcu_read_unlock();
+
+- if (local->hw.conf.power_level != power) {
++ max_power = chandef.chan->max_reg_power;
++ ant_gain = chandef.chan->max_antenna_gain;
++ if (local->user_antenna_gain > 0) {
++ if (local->user_antenna_gain > ant_gain) {
++ max_power -= local->user_antenna_gain - ant_gain;
++ ant_gain = 0;
++ } else
++ ant_gain -= local->user_antenna_gain;
++ power = min(power, max_power);
++ }
++
++ if (local->hw.conf.power_level != power ||
++ local->hw.conf.max_antenna_gain != ant_gain) {
+ changed |= IEEE80211_CONF_CHANGE_POWER;
++ local->hw.conf.max_antenna_gain = ant_gain;
+ local->hw.cur_power_level = power;
+ local->hw.conf.power_level = power;
+ }
+@@ -597,6 +610,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
+ IEEE80211_RADIOTAP_MCS_HAVE_BW;
+ local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
+ IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
++ local->user_antenna_gain = 0;
+ local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
+ local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
+ local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
diff --git a/package/kernel/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch b/package/kernel/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch
new file mode 100644
index 0000000000..8f48eea3ad
--- /dev/null
+++ b/package/kernel/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch
@@ -0,0 +1,34 @@
+--- a/drivers/net/wireless/ath/ath.h
++++ b/drivers/net/wireless/ath/ath.h
+@@ -73,6 +73,7 @@ struct ath_regulatory {
+ u16 max_power_level;
+ u16 current_rd;
+ int16_t power_limit;
++ int16_t max_antenna_gain;
+ struct reg_dmn_pair_mapping *regpair;
+ };
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -2847,7 +2847,7 @@ void ath9k_hw_apply_txpower(struct ath_h
+ channel = chan->chan;
+ chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
+ new_pwr = min_t(int, chan_pwr, reg->power_limit);
+- max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2;
++ max_gain = chan_pwr - new_pwr + reg->max_antenna_gain * 2;
+
+ ant_gain = get_antenna_gain(ah, chan);
+ if (ant_gain > max_gain)
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -1292,7 +1292,10 @@ int ath9k_config(struct ieee80211_hw *hw
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
++ struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
++
+ ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
++ reg->max_antenna_gain = conf->max_antenna_gain;
+ sc->config.txpowlimit = 2 * conf->power_level;
+ ath9k_cmn_update_txpow(ah, sc->curtxpow,
+ sc->config.txpowlimit, &sc->curtxpow);
diff --git a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
new file mode 100644
index 0000000000..134b0978b2
--- /dev/null
+++ b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
@@ -0,0 +1,248 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -557,6 +557,9 @@ struct ath9k_wow_pattern {
+ void ath_init_leds(struct ath_softc *sc);
+ void ath_deinit_leds(struct ath_softc *sc);
+ void ath_fill_led_pin(struct ath_softc *sc);
++int ath_create_gpio_led(struct ath_softc *sc, int gpio, const char *name,
++ const char *trigger, bool active_low);
++
+ #else
+ static inline void ath_init_leds(struct ath_softc *sc)
+ {
+@@ -692,6 +695,13 @@ enum spectral_mode {
+ SPECTRAL_CHANSCAN,
+ };
+
++struct ath_led {
++ struct list_head list;
++ struct ath_softc *sc;
++ const struct gpio_led *gpio;
++ struct led_classdev cdev;
++};
++
+ struct ath_softc {
+ struct ieee80211_hw *hw;
+ struct device *dev;
+@@ -733,9 +743,8 @@ struct ath_softc {
+ struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
+
+ #ifdef CPTCFG_MAC80211_LEDS
+- bool led_registered;
+- char led_name[32];
+- struct led_classdev led_cdev;
++ const char *led_default_trigger;
++ struct list_head leds;
+ #endif
+
+ struct ath9k_hw_cal_data caldata;
+--- a/drivers/net/wireless/ath/ath9k/gpio.c
++++ b/drivers/net/wireless/ath/ath9k/gpio.c
+@@ -24,40 +24,102 @@
+ static void ath_led_brightness(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+ {
+- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
+- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF));
++ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev);
++ struct ath_softc *sc = led->sc;
++
++ ath9k_ps_wakeup(sc);
++ ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio,
++ (brightness != LED_OFF) ^ led->gpio->active_low);
++ ath9k_ps_restore(sc);
++}
++
++static int ath_add_led(struct ath_softc *sc, struct ath_led *led)
++{
++ const struct gpio_led *gpio = led->gpio;
++ int ret;
++
++ led->cdev.name = gpio->name;
++ led->cdev.default_trigger = gpio->default_trigger;
++ led->cdev.brightness_set = ath_led_brightness;
++
++ ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->cdev);
++ if (ret < 0)
++ return ret;
++
++ led->sc = sc;
++ list_add(&led->list, &sc->leds);
++
++ /* Configure gpio for output */
++ ath9k_hw_cfg_output(sc->sc_ah, gpio->gpio,
++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
++
++ /* LED off */
++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low);
++
++ return 0;
++}
++
++int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name,
++ const char *trigger, bool active_low)
++{
++ struct ath_led *led;
++ struct gpio_led *gpio;
++ char *_name;
++ int ret;
++
++ led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1,
++ GFP_KERNEL);
++ if (!led)
++ return -ENOMEM;
++
++ led->gpio = gpio = (struct gpio_led *) (led + 1);
++ _name = (char *) (led->gpio + 1);
++
++ strcpy(_name, name);
++ gpio->name = _name;
++ gpio->gpio = gpio_num;
++ gpio->active_low = active_low;
++ gpio->default_trigger = trigger;
++
++ ret = ath_add_led(sc, led);
++ if (unlikely(ret < 0))
++ kfree(led);
++
++ return ret;
+ }
+
+ void ath_deinit_leds(struct ath_softc *sc)
+ {
+- if (!sc->led_registered)
+- return;
++ struct ath_led *led;
+
+- ath_led_brightness(&sc->led_cdev, LED_OFF);
+- led_classdev_unregister(&sc->led_cdev);
++ while (!list_empty(&sc->leds)) {
++ led = list_first_entry(&sc->leds, struct ath_led, list);
++ list_del(&led->list);
++ ath_led_brightness(&led->cdev, LED_OFF);
++ led_classdev_unregister(&led->cdev);
++ kfree(led);
++ }
+ }
+
+ void ath_init_leds(struct ath_softc *sc)
+ {
+- int ret;
++ char led_name[32];
++ const char *trigger;
++
++ INIT_LIST_HEAD(&sc->leds);
+
+ if (AR_SREV_9100(sc->sc_ah))
+ return;
+
+- if (!led_blink)
+- sc->led_cdev.default_trigger =
+- ieee80211_get_radio_led_name(sc->hw);
+-
+- snprintf(sc->led_name, sizeof(sc->led_name),
+- "ath9k-%s", wiphy_name(sc->hw->wiphy));
+- sc->led_cdev.name = sc->led_name;
+- sc->led_cdev.brightness_set = ath_led_brightness;
++ snprintf(led_name, sizeof(led_name), "ath9k-%s",
++ wiphy_name(sc->hw->wiphy));
+
+- ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
+- if (ret < 0)
+- return;
++ if (led_blink)
++ trigger = sc->led_default_trigger;
++ else
++ trigger = ieee80211_get_radio_led_name(sc->hw);
+
+- sc->led_registered = true;
++ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1);
+ }
+
+ void ath_fill_led_pin(struct ath_softc *sc)
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -891,7 +891,7 @@ int ath9k_init_device(u16 devid, struct
+
+ #ifdef CPTCFG_MAC80211_LEDS
+ /* must be initialized before ieee80211_register_hw */
+- sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
++ sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
+ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
+ ARRAY_SIZE(ath9k_tpt_blink));
+ #endif
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -1825,6 +1825,61 @@ static const struct file_operations fops
+ .llseek = default_llseek,
+ };
+
++#ifdef CONFIG_MAC80211_LEDS
++
++static ssize_t write_file_gpio_led(struct file *file, const char __user *ubuf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ char buf[32], *str, *name, *c;
++ ssize_t len;
++ unsigned int gpio;
++ bool active_low = false;
++
++ len = min(count, sizeof(buf) - 1);
++ if (copy_from_user(buf, ubuf, len))
++ return -EFAULT;
++
++ buf[len] = '\0';
++ name = strchr(buf, ',');
++ if (!name)
++ return -EINVAL;
++
++ *(name++) = 0;
++ if (!*name)
++ return -EINVAL;
++
++ c = strchr(name, '\n');
++ if (c)
++ *c = 0;
++
++ str = buf;
++ if (*str == '!') {
++ str++;
++ active_low = true;
++ }
++
++ if (kstrtouint(str, 0, &gpio) < 0)
++ return -EINVAL;
++
++ if (gpio >= sc->sc_ah->caps.num_gpio_pins)
++ return -EINVAL;
++
++ if (ath_create_gpio_led(sc, gpio, name, NULL, active_low) < 0)
++ return -EINVAL;
++
++ return count;
++}
++
++static const struct file_operations fops_gpio_led = {
++ .write = write_file_gpio_led,
++ .open = simple_open,
++ .owner = THIS_MODULE,
++ .llseek = default_llseek,
++};
++
++#endif
++
+
+ int ath9k_init_debug(struct ath_hw *ah)
+ {
+@@ -1847,6 +1902,10 @@ int ath9k_init_debug(struct ath_hw *ah)
+ &fops_eeprom);
+ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_chanbw);
++#ifdef CONFIG_MAC80211_LEDS
++ debugfs_create_file("gpio_led", S_IWUSR,
++ sc->debug.debugfs_phy, sc, &fops_gpio_led);
++#endif
+ debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_dma);
+ debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
diff --git a/package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch b/package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch
new file mode 100644
index 0000000000..764242cd1c
--- /dev/null
+++ b/package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch
@@ -0,0 +1,71 @@
+--- a/include/linux/ath9k_platform.h
++++ b/include/linux/ath9k_platform.h
+@@ -35,6 +35,9 @@ struct ath9k_platform_data {
+ bool is_clk_25mhz;
+ int (*get_mac_revision)(void);
+ int (*external_reset)(void);
++
++ int num_leds;
++ const struct gpio_led *leds;
+ };
+
+ #endif /* _LINUX_ATH9K_PLATFORM_H */
+--- a/drivers/net/wireless/ath/ath9k/gpio.c
++++ b/drivers/net/wireless/ath/ath9k/gpio.c
+@@ -15,6 +15,7 @@
+ */
+
+ #include "ath9k.h"
++#include <linux/ath9k_platform.h>
+
+ /********************************/
+ /* LED functions */
+@@ -88,6 +89,24 @@ int ath_create_gpio_led(struct ath_softc
+ return ret;
+ }
+
++static int ath_create_platform_led(struct ath_softc *sc,
++ const struct gpio_led *gpio)
++{
++ struct ath_led *led;
++ int ret;
++
++ led = kzalloc(sizeof(*led), GFP_KERNEL);
++ if (!led)
++ return -ENOMEM;
++
++ led->gpio = gpio;
++ ret = ath_add_led(sc, led);
++ if (ret < 0)
++ kfree(led);
++
++ return ret;
++}
++
+ void ath_deinit_leds(struct ath_softc *sc)
+ {
+ struct ath_led *led;
+@@ -103,8 +122,10 @@ void ath_deinit_leds(struct ath_softc *s
+
+ void ath_init_leds(struct ath_softc *sc)
+ {
++ struct ath9k_platform_data *pdata = sc->dev->platform_data;
+ char led_name[32];
+ const char *trigger;
++ int i;
+
+ INIT_LIST_HEAD(&sc->leds);
+
+@@ -120,6 +141,12 @@ void ath_init_leds(struct ath_softc *sc)
+ trigger = ieee80211_get_radio_led_name(sc->hw);
+
+ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1);
++
++ if (!pdata)
++ return;
++
++ for (i = 0; i < pdata->num_leds; i++)
++ ath_create_platform_led(sc, &pdata->leds[i]);
+ }
+
+ void ath_fill_led_pin(struct ath_softc *sc)
diff --git a/package/kernel/mac80211/patches/541-ath9k_optimize_interrupt_mitigation.patch b/package/kernel/mac80211/patches/541-ath9k_optimize_interrupt_mitigation.patch
new file mode 100644
index 0000000000..95ceb3575d
--- /dev/null
+++ b/package/kernel/mac80211/patches/541-ath9k_optimize_interrupt_mitigation.patch
@@ -0,0 +1,30 @@
+--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+@@ -241,21 +241,19 @@ static bool ar9003_hw_get_isr(struct ath
+
+ *masked = isr & ATH9K_INT_COMMON;
+
+- if (ah->config.rx_intr_mitigation)
++ if (ah->config.rx_intr_mitigation) {
+ if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
+ *masked |= ATH9K_INT_RXLP;
+-
+- if (ah->config.tx_intr_mitigation)
+- if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
+- *masked |= ATH9K_INT_TX;
+-
+- if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
++ } else if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
+ *masked |= ATH9K_INT_RXLP;
+
+ if (isr & AR_ISR_HP_RXOK)
+ *masked |= ATH9K_INT_RXHP;
+
+- if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
++ if (ah->config.tx_intr_mitigation) {
++ if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
++ *masked |= ATH9K_INT_TX;
++ } else if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
+ *masked |= ATH9K_INT_TX;
+
+ if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
diff --git a/package/kernel/mac80211/patches/550-ath9k_reduce_ani_interval.patch b/package/kernel/mac80211/patches/550-ath9k_reduce_ani_interval.patch
new file mode 100644
index 0000000000..2b7cf21881
--- /dev/null
+++ b/package/kernel/mac80211/patches/550-ath9k_reduce_ani_interval.patch
@@ -0,0 +1,11 @@
+--- a/drivers/net/wireless/ath/ath9k/ani.h
++++ b/drivers/net/wireless/ath/ath9k/ani.h
+@@ -34,7 +34,7 @@
+ #define ATH9K_ANI_PERIOD 300
+
+ /* in ms */
+-#define ATH9K_ANI_POLLINTERVAL 1000
++#define ATH9K_ANI_POLLINTERVAL 300
+
+ #define ATH9K_SIG_FIRSTEP_SETTING_MIN 0
+ #define ATH9K_SIG_FIRSTEP_SETTING_MAX 20
diff --git a/package/kernel/mac80211/patches/552-ath9k_rx_dma_stop_check.patch b/package/kernel/mac80211/patches/552-ath9k_rx_dma_stop_check.patch
new file mode 100644
index 0000000000..5d063c7d65
--- /dev/null
+++ b/package/kernel/mac80211/patches/552-ath9k_rx_dma_stop_check.patch
@@ -0,0 +1,28 @@
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -705,7 +705,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
+ {
+ #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
+ struct ath_common *common = ath9k_hw_common(ah);
+- u32 mac_status, last_mac_status = 0;
++ u32 mac_status = 0, last_mac_status = 0;
+ int i;
+
+ /* Enable access to the DMA observation bus */
+@@ -735,6 +735,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
+ }
+
+ if (i == 0) {
++ if (!AR_SREV_9300_20_OR_LATER(ah) &&
++ (mac_status & 0x700) == 0) {
++ /*
++ * DMA is idle but the MAC is still stuck
++ * processing events
++ */
++ *reset = true;
++ return true;
++ }
++
+ ath_err(common,
+ "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x DMADBG_7=0x%08x\n",
+ AH_RX_STOP_DMA_TIMEOUT / 1000,
diff --git a/package/kernel/mac80211/patches/553-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/553-ath9k_debugfs_diag.patch
new file mode 100644
index 0000000000..0e1572af9a
--- /dev/null
+++ b/package/kernel/mac80211/patches/553-ath9k_debugfs_diag.patch
@@ -0,0 +1,139 @@
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -1881,6 +1881,50 @@ static const struct file_operations fops
+ #endif
+
+
++static ssize_t read_file_diag(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ struct ath_hw *ah = sc->sc_ah;
++ char buf[32];
++ unsigned int len;
++
++ len = sprintf(buf, "0x%08lx\n", ah->diag);
++ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
++}
++
++static ssize_t write_file_diag(struct file *file, const char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ struct ath_hw *ah = sc->sc_ah;
++ unsigned long diag;
++ char buf[32];
++ ssize_t len;
++
++ len = min(count, sizeof(buf) - 1);
++ if (copy_from_user(buf, user_buf, len))
++ return -EFAULT;
++
++ buf[len] = '\0';
++ if (strict_strtoul(buf, 0, &diag))
++ return -EINVAL;
++
++ ah->diag = diag;
++ ath9k_hw_update_diag(ah);
++
++ return count;
++}
++
++static const struct file_operations fops_diag = {
++ .read = read_file_diag,
++ .write = write_file_diag,
++ .open = simple_open,
++ .owner = THIS_MODULE,
++ .llseek = default_llseek,
++};
++
++
+ int ath9k_init_debug(struct ath_hw *ah)
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
+@@ -1906,6 +1950,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+ debugfs_create_file("gpio_led", S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_gpio_led);
+ #endif
++ debugfs_create_file("diag", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
++ sc, &fops_diag);
+ debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_dma);
+ debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -495,6 +495,12 @@ enum {
+ ATH9K_RESET_COLD,
+ };
+
++enum {
++ ATH_DIAG_DISABLE_RX,
++ ATH_DIAG_DISABLE_TX,
++ ATH_DIAG_TRIGGER_ERROR,
++};
++
+ struct ath9k_hw_version {
+ u32 magic;
+ u16 devid;
+@@ -773,6 +779,8 @@ struct ath_hw {
+ u32 rfkill_polarity;
+ u32 ah_flags;
+
++ unsigned long diag;
++
+ bool reset_power_on;
+ bool htc_reset_init;
+
+@@ -1020,6 +1028,7 @@ void ath9k_hw_set_sta_beacon_timers(stru
+ bool ath9k_hw_check_alive(struct ath_hw *ah);
+
+ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
++void ath9k_hw_update_diag(struct ath_hw *ah);
+
+ #ifdef CPTCFG_ATH9K_DEBUGFS
+ void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause);
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1853,6 +1853,20 @@ fail:
+ return -EINVAL;
+ }
+
++void ath9k_hw_update_diag(struct ath_hw *ah)
++{
++ if (test_bit(ATH_DIAG_DISABLE_RX, &ah->diag))
++ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
++ else
++ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
++
++ if (test_bit(ATH_DIAG_DISABLE_TX, &ah->diag))
++ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
++ else
++ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
++}
++EXPORT_SYMBOL(ath9k_hw_update_diag);
++
+ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+ struct ath9k_hw_cal_data *caldata, bool fastcc)
+ {
+@@ -2055,6 +2069,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+ }
+
+ ath9k_hw_apply_gpio_override(ah);
++ ath9k_hw_update_diag(ah);
+
+ if (AR_SREV_9565(ah) && ah->shared_chain_lnadiv)
+ REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -462,6 +462,11 @@ irqreturn_t ath_isr(int irq, void *dev)
+ ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
+ status &= ah->imask; /* discard unasked-for bits */
+
++ if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) {
++ status |= ATH9K_INT_FATAL;
++ clear_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag);
++ }
++
+ /*
+ * If there are no status bits set, then this interrupt was not
+ * for me (should have been caught above).
diff --git a/package/kernel/mac80211/patches/554-ath9k_ani_mrc_fix.patch b/package/kernel/mac80211/patches/554-ath9k_ani_mrc_fix.patch
new file mode 100644
index 0000000000..3bee413970
--- /dev/null
+++ b/package/kernel/mac80211/patches/554-ath9k_ani_mrc_fix.patch
@@ -0,0 +1,13 @@
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -1136,6 +1136,10 @@ skip_ws_det:
+ * is_on == 0 means MRC CCK is OFF (more noise imm)
+ */
+ bool is_on = param ? 1 : 0;
++
++ if (ah->caps.rx_chainmask == 1)
++ break;
++
+ REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
+ AR_PHY_MRC_CCK_ENABLE, is_on);
+ REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
diff --git a/package/kernel/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/kernel/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch
new file mode 100644
index 0000000000..fc0243162f
--- /dev/null
+++ b/package/kernel/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch
@@ -0,0 +1,70 @@
+--- a/include/linux/ath9k_platform.h
++++ b/include/linux/ath9k_platform.h
+@@ -33,6 +33,9 @@ struct ath9k_platform_data {
+
+ bool endian_check;
+ bool is_clk_25mhz;
++ bool disable_2ghz;
++ bool disable_5ghz;
++
+ int (*get_mac_revision)(void);
+ int (*external_reset)(void);
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -2448,17 +2448,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
+ }
+
+ eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
+- if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
+- ath_err(common,
+- "no band has been marked as supported in EEPROM\n");
+- return -EINVAL;
++
++ if (eeval & AR5416_OPFLAGS_11A) {
++ if (ah->disable_5ghz)
++ ath_warn(common, "disabling 5GHz band\n");
++ else
++ pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
+ }
+
+- if (eeval & AR5416_OPFLAGS_11A)
+- pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
++ if (eeval & AR5416_OPFLAGS_11G) {
++ if (ah->disable_2ghz)
++ ath_warn(common, "disabling 2GHz band\n");
++ else
++ pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
++ }
+
+- if (eeval & AR5416_OPFLAGS_11G)
+- pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
++ if ((pCap->hw_caps & (ATH9K_HW_CAP_2GHZ | ATH9K_HW_CAP_5GHZ)) == 0) {
++ ath_err(common, "both bands are disabled\n");
++ return -EINVAL;
++ }
+
+ if (AR_SREV_9485(ah) ||
+ AR_SREV_9285(ah) ||
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -940,6 +940,8 @@ struct ath_hw {
+ bool is_clk_25mhz;
+ int (*get_mac_revision)(void);
+ int (*external_reset)(void);
++ bool disable_2ghz;
++ bool disable_5ghz;
+
+ const struct firmware *eeprom_blob;
+ };
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -592,6 +592,8 @@ static int ath9k_init_softc(u16 devid, s
+ ah->is_clk_25mhz = pdata->is_clk_25mhz;
+ ah->get_mac_revision = pdata->get_mac_revision;
+ ah->external_reset = pdata->external_reset;
++ ah->disable_2ghz = pdata->disable_2ghz;
++ ah->disable_5ghz = pdata->disable_5ghz;
+ if (!pdata->endian_check)
+ ah->ah_flags |= AH_NO_EEP_SWAP;
+ }
diff --git a/package/kernel/mac80211/patches/556-ath9k_ani_revert.patch b/package/kernel/mac80211/patches/556-ath9k_ani_revert.patch
new file mode 100644
index 0000000000..006f3930e9
--- /dev/null
+++ b/package/kernel/mac80211/patches/556-ath9k_ani_revert.patch
@@ -0,0 +1,74 @@
+--- a/drivers/net/wireless/ath/ath9k/ani.h
++++ b/drivers/net/wireless/ath/ath9k/ani.h
+@@ -20,8 +20,12 @@
+ #define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
+
+ /* units are errors per second */
+-#define ATH9K_ANI_OFDM_TRIG_HIGH 1000
++#define ATH9K_ANI_OFDM_TRIG_HIGH 3500
++#define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
++
+ #define ATH9K_ANI_OFDM_TRIG_LOW 400
++#define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
++
+ #define ATH9K_ANI_CCK_TRIG_HIGH 600
+ #define ATH9K_ANI_CCK_TRIG_LOW 300
+
+--- a/drivers/net/wireless/ath/ath9k/ani.c
++++ b/drivers/net/wireless/ath/ath9k/ani.c
+@@ -177,14 +177,17 @@ static void ath9k_hw_set_ofdm_nil(struct
+ BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
+ weak_sig = true;
+
+- /*
+- * OFDM Weak signal detection is always enabled for AP mode.
+- */
+- if (ah->opmode != NL80211_IFTYPE_AP &&
+- aniState->ofdmWeakSigDetect != weak_sig) {
+- ath9k_hw_ani_control(ah,
+- ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+- entry_ofdm->ofdm_weak_signal_on);
++ if (aniState->ofdmWeakSigDetect != weak_sig)
++ ath9k_hw_ani_control(ah,
++ ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
++ entry_ofdm->ofdm_weak_signal_on);
++
++ if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
++ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
++ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI;
++ } else {
++ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI;
++ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
+ }
+ }
+
+@@ -420,25 +423,12 @@ void ath9k_hw_ani_monitor(struct ath_hw
+ ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
+ cckPhyErrRate, aniState->ofdmsTurn);
+
+- if (aniState->listenTime > 5 * ah->aniperiod) {
+- /*
+- * Check if we need to lower immunity if
+- * 5 ani_periods have passed.
+- */
+- if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
+- cckPhyErrRate <= ah->config.cck_trig_low) {
++ if (aniState->listenTime > ah->aniperiod) {
++ if (cckPhyErrRate < ah->config.cck_trig_low &&
++ ofdmPhyErrRate < ah->config.ofdm_trig_low) {
+ ath9k_hw_ani_lower_immunity(ah);
+ aniState->ofdmsTurn = !aniState->ofdmsTurn;
+- }
+- ath9k_ani_restart(ah);
+- } else if (aniState->listenTime > ah->aniperiod) {
+- /*
+- * Check if immunity has to be raised,
+- * (either OFDM or CCK).
+- */
+- if (ofdmPhyErrRate > ah->config.ofdm_trig_high &&
+- (cckPhyErrRate <= ah->config.cck_trig_high ||
+- aniState->ofdmsTurn)) {
++ } else if (ofdmPhyErrRate > ah->config.ofdm_trig_high) {
+ ath9k_hw_ani_ofdm_err_trigger(ah);
+ aniState->ofdmsTurn = false;
+ } else if (cckPhyErrRate > ah->config.cck_trig_high) {
diff --git a/package/kernel/mac80211/patches/601-rt2x00-set_pci_mwi.patch b/package/kernel/mac80211/patches/601-rt2x00-set_pci_mwi.patch
new file mode 100644
index 0000000000..d9a20bc107
--- /dev/null
+++ b/package/kernel/mac80211/patches/601-rt2x00-set_pci_mwi.patch
@@ -0,0 +1,13 @@
+--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
+@@ -96,8 +96,10 @@ int rt2x00pci_probe(struct pci_dev *pci_
+
+ pci_set_master(pci_dev);
+
++#ifdef CONFIG_PCI_SET_MWI
+ if (pci_set_mwi(pci_dev))
+ rt2x00_probe_err("MWI not available\n");
++#endif
+
+ if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) {
+ rt2x00_probe_err("PCI DMA not supported\n");
diff --git a/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch b/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch
new file mode 100644
index 0000000000..6c80c3dfa8
--- /dev/null
+++ b/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch
@@ -0,0 +1,32 @@
+--- /dev/null
++++ b/include/linux/rt2x00_platform.h
+@@ -0,0 +1,19 @@
++/*
++ * Platform data definition for the rt2x00 driver
++ *
++ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ */
++
++#ifndef _RT2X00_PLATFORM_H
++#define _RT2X00_PLATFORM_H
++
++struct rt2x00_platform_data {
++ char *eeprom_file_name;
++};
++
++#endif /* _RT2X00_PLATFORM_H */
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -39,6 +39,7 @@
+ #include <linux/input-polldev.h>
+ #include <linux/kfifo.h>
+ #include <linux/hrtimer.h>
++#include <linux/rt2x00_platform.h>
+
+ #include <net/mac80211.h>
+
diff --git a/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
new file mode 100644
index 0000000000..40a2576d7a
--- /dev/null
+++ b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
@@ -0,0 +1,289 @@
+--- /dev/null
++++ b/drivers/net/wireless/rt2x00/rt2x00eeprom.c
+@@ -0,0 +1,98 @@
++/*
++ Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
++ Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
++ <http://rt2x00.serialmonkey.com>
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the
++ Free Software Foundation, Inc.,
++ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++/*
++ Module: rt2x00lib
++ Abstract: rt2x00 eeprom file loading routines.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++
++#include "rt2x00.h"
++#include "rt2x00lib.h"
++
++static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev)
++{
++ const struct firmware *ee;
++ char *ee_name;
++ int retval;
++
++ ee_name = rt2x00dev->ops->lib->get_eeprom_file_name(rt2x00dev);
++ if (!ee_name) {
++ rt2x00_err(rt2x00dev,
++ "Invalid EEPROM filename.\n"
++ "Please file bug report to %s.\n", DRV_PROJECT);
++ return -EINVAL;
++ }
++
++ rt2x00_info(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name);
++
++ retval = request_firmware(&ee, ee_name, rt2x00dev->dev);
++ if (retval) {
++ rt2x00_err(rt2x00dev, "Failed to request EEPROM.\n");
++ return retval;
++ }
++
++ if (!ee || !ee->size || !ee->data) {
++ rt2x00_err(rt2x00dev, "Failed to read EEPROM file.\n");
++ retval = -ENOENT;
++ goto err_exit;
++ }
++
++ if (ee->size != rt2x00dev->ops->eeprom_size) {
++ rt2x00_err(rt2x00dev,
++ "EEPROM file size is invalid, it should be %d bytes\n",
++ rt2x00dev->ops->eeprom_size);
++ retval = -EINVAL;
++ goto err_release_ee;
++ }
++
++ rt2x00dev->eeprom_file = ee;
++ return 0;
++
++err_release_ee:
++ release_firmware(ee);
++err_exit:
++ return retval;
++}
++
++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev)
++{
++ int retval;
++
++ if (!test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags))
++ return 0;
++
++ if (!rt2x00dev->eeprom_file) {
++ retval = rt2x00lib_request_eeprom_file(rt2x00dev);
++ if (retval)
++ return retval;
++ }
++
++ return 0;
++}
++
++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev)
++{
++ release_firmware(rt2x00dev->eeprom_file);
++ rt2x00dev->eeprom_file = NULL;
++}
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -549,6 +549,7 @@ struct rt2x00lib_ops {
+ const u8 *data, const size_t len);
+ int (*load_firmware) (struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len);
++ char *(*get_eeprom_file_name) (struct rt2x00_dev *rt2x00dev);
+
+ /*
+ * Device initialization/deinitialization handlers.
+@@ -705,6 +706,7 @@ enum rt2x00_capability_flags {
+ REQUIRE_SW_SEQNO,
+ REQUIRE_HT_TX_DESC,
+ REQUIRE_PS_AUTOWAKE,
++ REQUIRE_EEPROM_FILE,
+
+ /*
+ * Capabilities
+@@ -974,6 +976,11 @@ struct rt2x00_dev {
+ const struct firmware *fw;
+
+ /*
++ * EEPROM image.
++ */
++ const struct firmware *eeprom_file;
++
++ /*
+ * FIFO for storing tx status reports between isr and tasklet.
+ */
+ DECLARE_KFIFO_PTR(txstatus_fifo, u32);
+--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
++++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
+@@ -322,6 +322,22 @@ static inline void rt2x00lib_free_firmwa
+ #endif /* CPTCFG_RT2X00_LIB_FIRMWARE */
+
+ /*
++ * EEPROM file handlers.
++ */
++#ifdef CPTCFG_RT2X00_LIB_EEPROM
++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev);
++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev);
++#else
++static inline int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev)
++{
++ return 0;
++}
++static inline void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev)
++{
++}
++#endif /* CPTCFG_RT2X00_LIB_EEPROM */
++
++/*
+ * Debugfs handlers.
+ */
+ #ifdef CPTCFG_RT2X00_LIB_DEBUGFS
+--- a/drivers/net/wireless/rt2x00/Kconfig
++++ b/drivers/net/wireless/rt2x00/Kconfig
+@@ -69,6 +69,7 @@ config RT2800PCI
+ select RT2X00_LIB_PCI if PCI
+ select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X
+ select RT2X00_LIB_FIRMWARE
++ select RT2X00_LIB_EEPROM
+ select RT2X00_LIB_CRYPTO
+ depends on CRC_CCITT
+ depends on EEPROM_93CX6
+@@ -235,6 +236,9 @@ config RT2X00_LIB_FIRMWARE
+ config RT2X00_LIB_CRYPTO
+ boolean
+
++config RT2X00_LIB_EEPROM
++ boolean
++
+ config RT2X00_LIB_LEDS
+ depends on !BACKPORT_KERNEL_2_6_25
+ boolean
+--- a/drivers/net/wireless/rt2x00/Makefile
++++ b/drivers/net/wireless/rt2x00/Makefile
+@@ -7,6 +7,7 @@ rt2x00lib-$(CPTCFG_RT2X00_LIB_DEBUGFS) +
+ rt2x00lib-$(CPTCFG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
+ rt2x00lib-$(CPTCFG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
+ rt2x00lib-$(CPTCFG_RT2X00_LIB_LEDS) += rt2x00leds.o
++rt2x00lib-$(CPTCFG_RT2X00_LIB_EEPROM) += rt2x00eeprom.o
+
+ obj-$(CPTCFG_RT2X00_LIB) += rt2x00lib.o
+ obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o
+--- a/drivers/net/wireless/rt2x00/rt2800pci.c
++++ b/drivers/net/wireless/rt2x00/rt2800pci.c
+@@ -90,25 +90,11 @@ static void rt2800pci_mcu_status(struct
+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+ }
+
+-#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
+ static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
+ {
+- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
+-
+- if (!base_addr)
+- return -ENOMEM;
+-
+- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
+-
+- iounmap(base_addr);
++ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE);
+ return 0;
+ }
+-#else
+-static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
+-{
+- return -ENOMEM;
+-}
+-#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
+
+ #ifdef CONFIG_PCI
+ static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
+@@ -332,6 +318,20 @@ static int rt2800pci_write_firmware(stru
+ }
+
+ /*
++ * EEPROM file functions.
++ */
++static char *rt2800pci_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2x00_platform_data *pdata;
++
++ pdata = rt2x00dev->dev->platform_data;
++ if (pdata)
++ return pdata->eeprom_file_name;
++
++ return NULL;
++}
++
++/*
+ * Initialization functions.
+ */
+ static bool rt2800pci_get_entry_state(struct queue_entry *entry)
+@@ -1155,6 +1155,7 @@ static const struct rt2x00lib_ops rt2800
+ .get_firmware_name = rt2800pci_get_firmware_name,
+ .check_firmware = rt2800_check_firmware,
+ .load_firmware = rt2800_load_firmware,
++ .get_eeprom_file_name = rt2800pci_get_eeprom_file_name,
+ .initialize = rt2x00mmio_initialize,
+ .uninitialize = rt2x00mmio_uninitialize,
+ .get_entry_state = rt2800pci_get_entry_state,
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -1325,6 +1325,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
+ INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
+ INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
+
++ retval = rt2x00lib_load_eeprom_file(rt2x00dev);
++ if (retval)
++ goto exit;
++
+ /*
+ * Let the driver probe the device to detect the capabilities.
+ */
+@@ -1455,6 +1459,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
+ */
+ if (rt2x00dev->drv_data)
+ kfree(rt2x00dev->drv_data);
++
++ /*
++ * Free EEPROM image.
++ */
++ rt2x00lib_free_eeprom_file(rt2x00dev);
+ }
+ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
+
+--- a/drivers/net/wireless/rt2x00/rt2x00soc.c
++++ b/drivers/net/wireless/rt2x00/rt2x00soc.c
+@@ -94,6 +94,7 @@ int rt2x00soc_probe(struct platform_devi
+ rt2x00dev->hw = hw;
+ rt2x00dev->irq = platform_get_irq(pdev, 0);
+ rt2x00dev->name = pdev->dev.driver->name;
++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags);
+
+ rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC);
+
+--- a/.local-symbols
++++ b/.local-symbols
+@@ -272,6 +272,7 @@ RT2X00_LIB_FIRMWARE=
+ RT2X00_LIB_CRYPTO=
+ RT2X00_LIB_LEDS=
+ RT2X00_LIB_DEBUGFS=
++RT2X00_LIB_EEPROM=
+ RT2X00_DEBUG=
+ RTLWIFI=
+ RTLWIFI_DEBUG=
diff --git a/package/kernel/mac80211/patches/605-rt2x00-pci-eeprom.patch b/package/kernel/mac80211/patches/605-rt2x00-pci-eeprom.patch
new file mode 100644
index 0000000000..d37f3acc28
--- /dev/null
+++ b/package/kernel/mac80211/patches/605-rt2x00-pci-eeprom.patch
@@ -0,0 +1,46 @@
+--- a/drivers/net/wireless/rt2x00/rt2800pci.c
++++ b/drivers/net/wireless/rt2x00/rt2800pci.c
+@@ -90,7 +90,7 @@ static void rt2800pci_mcu_status(struct
+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+ }
+
+-static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
++static int rt2800pci_read_eeprom_file(struct rt2x00_dev *rt2x00dev)
+ {
+ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE);
+ return 0;
+@@ -1092,8 +1092,9 @@ static int rt2800pci_read_eeprom(struct
+ {
+ int retval;
+
+- if (rt2x00_is_soc(rt2x00dev))
+- retval = rt2800pci_read_eeprom_soc(rt2x00dev);
++ if (rt2x00_is_soc(rt2x00dev) ||
++ test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags))
++ retval = rt2800pci_read_eeprom_file(rt2x00dev);
+ else if (rt2800pci_efuse_detect(rt2x00dev))
+ retval = rt2800pci_read_eeprom_efuse(rt2x00dev);
+ else
+--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
+@@ -78,6 +78,7 @@ exit:
+ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
+ {
+ struct ieee80211_hw *hw;
++ struct rt2x00_platform_data *pdata;
+ struct rt2x00_dev *rt2x00dev;
+ int retval;
+ u16 chip;
+@@ -125,6 +126,12 @@ int rt2x00pci_probe(struct pci_dev *pci_
+ rt2x00dev->irq = pci_dev->irq;
+ rt2x00dev->name = pci_name(pci_dev);
+
++ /* if we get passed the name of a eeprom_file_name, then use this in
++ favour of the eeprom */
++ pdata = rt2x00dev->dev->platform_data;
++ if (pdata && pdata->eeprom_file_name)
++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags);
++
+ if (pci_is_pcie(pci_dev))
+ rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
+ else
diff --git a/package/kernel/mac80211/patches/606-rt2x00_no_realign.patch b/package/kernel/mac80211/patches/606-rt2x00_no_realign.patch
new file mode 100644
index 0000000000..9608df2e20
--- /dev/null
+++ b/package/kernel/mac80211/patches/606-rt2x00_no_realign.patch
@@ -0,0 +1,67 @@
+[RFC] rt2x00: For drivers that only need L2 padding don't realign frames
+
+Signed-off-by: Helmut Schaa <helmut.schaa@...>
+---
+
+Ivo, Gertjan, do you remeber by any chance why this alignment stuff was added
+in the first place? Was it because of DMA restrictions?
+
+While doing some profiling on the rt3052 SoC I noticed that 30-40% time was
+spent in memmove calls. And the culprit is the memmove aligning the payload
+to a 4byte boundary since that has to move a whole bunch of data.
+
+Interesstingly the legacy drivers insert an l2pad between the header and the
+payload but doesn't realign the payload itself to a 4-byte boundary. Hence,
+I came up with this patch and indeed CPU usage improves impressively.
+
+Only tested on rt2800pci!
+
+Thanks,
+Helmut
+
+ drivers/net/wireless/rt2x00/rt2x00queue.c | 30 +++-------------------------
+ 1 files changed, 4 insertions(+), 26 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
++++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
+@@ -163,36 +163,14 @@ void rt2x00queue_align_frame(struct sk_b
+ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
+ {
+ unsigned int payload_length = skb->len - header_length;
+- unsigned int header_align = ALIGN_SIZE(skb, 0);
+- unsigned int payload_align = ALIGN_SIZE(skb, header_length);
+ unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
+
+- /*
+- * Adjust the header alignment if the payload needs to be moved more
+- * than the header.
+- */
+- if (payload_align > header_align)
+- header_align += 4;
+-
+- /* There is nothing to do if no alignment is needed */
+- if (!header_align)
++ if (!l2pad)
+ return;
+
+- /* Reserve the amount of space needed in front of the frame */
+- skb_push(skb, header_align);
+-
+- /*
+- * Move the header.
+- */
+- memmove(skb->data, skb->data + header_align, header_length);
+-
+- /* Move the payload, if present and if required */
+- if (payload_length && payload_align)
+- memmove(skb->data + header_length + l2pad,
+- skb->data + header_length + l2pad + payload_align,
+- payload_length);
+-
+- /* Trim the skb to the correct size */
++ /* insert l2pad -> Move header */
++ skb_push(skb, l2pad);
++ memmove(skb->data, skb->data + l2pad, header_length);
+ skb_trim(skb, header_length + l2pad + payload_length);
+ }
+
diff --git a/package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch
new file mode 100644
index 0000000000..5e6e27de98
--- /dev/null
+++ b/package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch
@@ -0,0 +1,47 @@
+--- a/include/linux/rt2x00_platform.h
++++ b/include/linux/rt2x00_platform.h
+@@ -14,6 +14,9 @@
+
+ struct rt2x00_platform_data {
+ char *eeprom_file_name;
++
++ int disable_2ghz;
++ int disable_5ghz;
+ };
+
+ #endif /* _RT2X00_PLATFORM_H */
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -938,6 +938,22 @@ static int rt2x00lib_probe_hw_modes(stru
+ unsigned int num_rates;
+ unsigned int i;
+
++ if (rt2x00dev->dev->platform_data) {
++ struct rt2x00_platform_data *pdata;
++
++ pdata = rt2x00dev->dev->platform_data;
++ if (pdata->disable_2ghz)
++ spec->supported_bands &= ~SUPPORT_BAND_2GHZ;
++ if (pdata->disable_5ghz)
++ spec->supported_bands &= ~SUPPORT_BAND_5GHZ;
++ }
++
++ if ((spec->supported_bands & SUPPORT_BAND_BOTH) == 0) {
++ rt2x00_err(rt2x00dev, "No supported bands\n");
++ return -EINVAL;
++ }
++
++
+ num_rates = 0;
+ if (spec->supported_rates & SUPPORT_RATE_CCK)
+ num_rates += 4;
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -414,6 +414,7 @@ struct hw_mode_spec {
+ unsigned int supported_bands;
+ #define SUPPORT_BAND_2GHZ 0x00000001
+ #define SUPPORT_BAND_5GHZ 0x00000002
++#define SUPPORT_BAND_BOTH (SUPPORT_BAND_2GHZ | SUPPORT_BAND_5GHZ)
+
+ unsigned int supported_rates;
+ #define SUPPORT_RATE_CCK 0x00000001
diff --git a/package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch
new file mode 100644
index 0000000000..0695b893b5
--- /dev/null
+++ b/package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch
@@ -0,0 +1,63 @@
+--- a/include/linux/rt2x00_platform.h
++++ b/include/linux/rt2x00_platform.h
+@@ -14,6 +14,7 @@
+
+ struct rt2x00_platform_data {
+ char *eeprom_file_name;
++ const u8 *mac_address;
+
+ int disable_2ghz;
+ int disable_5ghz;
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -929,6 +929,18 @@ static void rt2x00lib_rate(struct ieee80
+ entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE;
+ }
+
++const u8 *rt2x00lib_get_mac_address(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2x00_platform_data *pdata;
++
++ pdata = rt2x00dev->dev->platform_data;
++ if (!pdata)
++ return NULL;
++
++ return pdata->mac_address;
++}
++EXPORT_SYMBOL_GPL(rt2x00lib_get_mac_address);
++
+ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
+ struct hw_mode_spec *spec)
+ {
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -1326,6 +1326,7 @@ static inline void rt2x00debug_dump_fram
+ */
+ u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_vif *vif);
++const u8 *rt2x00lib_get_mac_address(struct rt2x00_dev *rt2x00dev);
+
+ /*
+ * Interrupt context handlers.
+--- a/drivers/net/wireless/rt2x00/rt61pci.c
++++ b/drivers/net/wireless/rt2x00/rt61pci.c
+@@ -2395,6 +2395,7 @@ static int rt61pci_validate_eeprom(struc
+ u32 reg;
+ u16 word;
+ u8 *mac;
++ const u8 *pdata_mac;
+ s8 value;
+
+ rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, &reg);
+@@ -2415,7 +2416,11 @@ static int rt61pci_validate_eeprom(struc
+ /*
+ * Start validation of the data that has been read.
+ */
++ pdata_mac = rt2x00lib_get_mac_address(rt2x00dev);
+ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
++ if (pdata_mac)
++ memcpy(mac, pdata_mac, 6);
++
+ if (!is_valid_ether_addr(mac)) {
+ eth_random_addr(mac);
+ rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
diff --git a/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch b/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
new file mode 100644
index 0000000000..f5709d9846
--- /dev/null
+++ b/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
@@ -0,0 +1,214 @@
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -2631,15 +2631,18 @@ static void rt2800_config_channel(struct
+ /*
+ * Change BBP settings
+ */
++ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
++ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
++ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
++
+ if (rt2x00_rt(rt2x00dev, RT3352)) {
+ rt2800_bbp_write(rt2x00dev, 27, 0x0);
+ rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 27, 0x20);
+ rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
++ rt2800_bbp_write(rt2x00dev, 86, 0x38);
++ rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+ } else {
+- rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+- rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+- rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 86, 0);
+ }
+
+@@ -4948,6 +4951,12 @@ static void rt2800_init_rfcsr_3290(struc
+
+ static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
+ {
++ int tx0_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX0,
++ &rt2x00dev->cap_flags);
++ int tx1_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX1,
++ &rt2x00dev->cap_flags);
++ u8 rfcsr;
++
+ rt2800_rf_init_calibration(rt2x00dev, 30);
+
+ rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
+@@ -4983,15 +4992,30 @@ static void rt2800_init_rfcsr_3352(struc
+ rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
+ rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
+ rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
+- rt2800_rfcsr_write(rt2x00dev, 34, 0x01);
++ rfcsr = 0x01;
++ if (!tx0_int_pa)
++ rt2x00_set_field8(&rfcsr, RFCSR34_TX0_EXT_PA, 1);
++ if (!tx1_int_pa)
++ rt2x00_set_field8(&rfcsr, RFCSR34_TX1_EXT_PA, 1);
++ rt2800_rfcsr_write(rt2x00dev, 34, rfcsr);
+ rt2800_rfcsr_write(rt2x00dev, 35, 0x03);
+ rt2800_rfcsr_write(rt2x00dev, 36, 0xbd);
+ rt2800_rfcsr_write(rt2x00dev, 37, 0x3c);
+ rt2800_rfcsr_write(rt2x00dev, 38, 0x5f);
+ rt2800_rfcsr_write(rt2x00dev, 39, 0xc5);
+ rt2800_rfcsr_write(rt2x00dev, 40, 0x33);
+- rt2800_rfcsr_write(rt2x00dev, 41, 0x5b);
+- rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
++ rfcsr = 0x52;
++ if (tx0_int_pa) {
++ rt2x00_set_field8(&rfcsr, RFCSR41_BIT1, 1);
++ rt2x00_set_field8(&rfcsr, RFCSR41_BIT4, 1);
++ }
++ rt2800_rfcsr_write(rt2x00dev, 41, rfcsr);
++ rfcsr = 0x52;
++ if (tx1_int_pa) {
++ rt2x00_set_field8(&rfcsr, RFCSR42_BIT1, 1);
++ rt2x00_set_field8(&rfcsr, RFCSR42_BIT4, 1);
++ }
++ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr);
+ rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
+ rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
+ rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
+@@ -4999,15 +5023,20 @@ static void rt2800_init_rfcsr_3352(struc
+ rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
+ rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
+ rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
+- rt2800_rfcsr_write(rt2x00dev, 50, 0x2d);
+- rt2800_rfcsr_write(rt2x00dev, 51, 0x7f);
+- rt2800_rfcsr_write(rt2x00dev, 52, 0x00);
+- rt2800_rfcsr_write(rt2x00dev, 53, 0x52);
+- rt2800_rfcsr_write(rt2x00dev, 54, 0x1b);
+- rt2800_rfcsr_write(rt2x00dev, 55, 0x7f);
+- rt2800_rfcsr_write(rt2x00dev, 56, 0x00);
+- rt2800_rfcsr_write(rt2x00dev, 57, 0x52);
+- rt2800_rfcsr_write(rt2x00dev, 58, 0x1b);
++ rfcsr = 0x2d;
++ if (!tx0_int_pa)
++ rt2x00_set_field8(&rfcsr, RFCSR50_TX0_EXT_PA, 1);
++ if (!tx1_int_pa)
++ rt2x00_set_field8(&rfcsr, RFCSR50_TX1_EXT_PA, 1);
++ rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
++ rt2800_rfcsr_write(rt2x00dev, 51, (tx0_int_pa ? 0x7f : 0x52));
++ rt2800_rfcsr_write(rt2x00dev, 52, (tx0_int_pa ? 0x00 : 0xc0));
++ rt2800_rfcsr_write(rt2x00dev, 53, (tx0_int_pa ? 0x52 : 0xd2));
++ rt2800_rfcsr_write(rt2x00dev, 54, (tx0_int_pa ? 0x1b : 0xc0));
++ rt2800_rfcsr_write(rt2x00dev, 55, (tx1_int_pa ? 0x7f : 0x52));
++ rt2800_rfcsr_write(rt2x00dev, 56, (tx1_int_pa ? 0x00 : 0xc0));
++ rt2800_rfcsr_write(rt2x00dev, 57, (tx0_int_pa ? 0x52 : 0x49));
++ rt2800_rfcsr_write(rt2x00dev, 58, (tx1_int_pa ? 0x1b : 0xc0));
+ rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
+@@ -5692,6 +5721,7 @@ static int rt2800_init_eeprom(struct rt2
+ * RT53xx: defined in "EEPROM_CHIP_ID" field
+ */
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
++ rt2x00_rt(rt2x00dev, RT3352) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+@@ -5781,7 +5811,8 @@ static int rt2800_init_eeprom(struct rt2
+ /*
+ * Detect if this device has Bluetooth co-existence.
+ */
+- if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST))
++ if (!rt2x00_rt(rt2x00dev, RT3352) &&
++ rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST))
+ __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
+
+ /*
+@@ -5810,6 +5841,22 @@ static int rt2800_init_eeprom(struct rt2
+ EIRP_MAX_TX_POWER_LIMIT)
+ __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
+
++ /*
++ * Detect if device uses internal or external PA
++ */
++ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++
++ if (rt2x00_rt(rt2x00dev, RT3352)) {
++ if (!rt2x00_get_field16(eeprom,
++ EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
++ __set_bit(CAPABILITY_INTERNAL_PA_TX0,
++ &rt2x00dev->cap_flags);
++ if (!rt2x00_get_field16(eeprom,
++ EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352))
++ __set_bit(CAPABILITY_INTERNAL_PA_TX1,
++ &rt2x00dev->cap_flags);
++ }
++
+ return 0;
+ }
+
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -2153,6 +2153,12 @@ struct mac_iveiv_entry {
+ #define RFCSR31_RX_CALIB FIELD8(0x7f)
+
+ /*
++ * RFCSR 34:
++ */
++#define RFCSR34_TX0_EXT_PA FIELD8(0x04)
++#define RFCSR34_TX1_EXT_PA FIELD8(0x08)
++
++/*
+ * RFCSR 38:
+ */
+ #define RFCSR38_RX_LO1_EN FIELD8(0x20)
+@@ -2163,6 +2169,18 @@ struct mac_iveiv_entry {
+ #define RFCSR39_RX_LO2_EN FIELD8(0x80)
+
+ /*
++ * RFCSR 41:
++ */
++#define RFCSR41_BIT1 FIELD8(0x01)
++#define RFCSR41_BIT4 FIELD8(0x08)
++
++/*
++ * RFCSR 42:
++ */
++#define RFCSR42_BIT1 FIELD8(0x01)
++#define RFCSR42_BIT4 FIELD8(0x08)
++
++/*
+ * RFCSR 49:
+ */
+ #define RFCSR49_TX FIELD8(0x3f)
+@@ -2172,6 +2190,8 @@ struct mac_iveiv_entry {
+ * RFCSR 50:
+ */
+ #define RFCSR50_TX FIELD8(0x3f)
++#define RFCSR50_TX0_EXT_PA FIELD8(0x02)
++#define RFCSR50_TX1_EXT_PA FIELD8(0x10)
+ #define RFCSR50_EP FIELD8(0xc0)
+
+ /*
+@@ -2260,6 +2280,8 @@ struct mac_iveiv_entry {
+ * INTERNAL_TX_ALC: 0: disable, 1: enable
+ * BT_COEXIST: 0: disable, 1: enable
+ * DAC_TEST: 0: disable, 1: enable
++ * EXTERNAL_TX0_PA: 0: disable, 1: enable (only on RT3352)
++ * EXTERNAL_TX1_PA: 0: disable, 1: enable (only on RT3352)
+ */
+ #define EEPROM_NIC_CONF1 0x001b
+ #define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001)
+@@ -2277,6 +2299,8 @@ struct mac_iveiv_entry {
+ #define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000)
+ #define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000)
+ #define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000)
++#define EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352 FIELD16(0x4000)
++#define EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352 FIELD16(0x8000)
+
+ /*
+ * EEPROM frequency
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -726,6 +726,8 @@ enum rt2x00_capability_flags {
+ CAPABILITY_DOUBLE_ANTENNA,
+ CAPABILITY_BT_COEXIST,
+ CAPABILITY_VCO_RECALIBRATION,
++ CAPABILITY_INTERNAL_PA_TX0,
++ CAPABILITY_INTERNAL_PA_TX1,
+ };
+
+ /*
diff --git a/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch b/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
new file mode 100644
index 0000000000..81df685043
--- /dev/null
+++ b/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
@@ -0,0 +1,115 @@
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -6133,6 +6133,27 @@ static const struct rf_channel rf_vals_5
+ {196, 83, 0, 12, 1},
+ };
+
++/*
++ * RF value list for rt3xxx with Xtal20MHz
++ * Supports: 2.4 GHz (all) (RF3322)
++ */
++static const struct rf_channel rf_vals_xtal20mhz_3x[] = {
++ {1, 0xE2, 2, 0x14},
++ {2, 0xE3, 2, 0x14},
++ {3, 0xE4, 2, 0x14},
++ {4, 0xE5, 2, 0x14},
++ {5, 0xE6, 2, 0x14},
++ {6, 0xE7, 2, 0x14},
++ {7, 0xE8, 2, 0x14},
++ {8, 0xE9, 2, 0x14},
++ {9, 0xEA, 2, 0x14},
++ {10, 0xEB, 2, 0x14},
++ {11, 0xEC, 2, 0x14},
++ {12, 0xED, 2, 0x14},
++ {13, 0xEE, 2, 0x14},
++ {14, 0xF0, 2, 0x18},
++};
++
+ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+ {
+ struct hw_mode_spec *spec = &rt2x00dev->spec;
+@@ -6211,7 +6232,6 @@ static int rt2800_probe_hw_mode(struct r
+ rt2x00_rf(rt2x00dev, RF3022) ||
+ rt2x00_rf(rt2x00dev, RF3290) ||
+ rt2x00_rf(rt2x00dev, RF3320) ||
+- rt2x00_rf(rt2x00dev, RF3322) ||
+ rt2x00_rf(rt2x00dev, RF5360) ||
+ rt2x00_rf(rt2x00dev, RF5370) ||
+ rt2x00_rf(rt2x00dev, RF5372) ||
+@@ -6219,6 +6239,12 @@ static int rt2800_probe_hw_mode(struct r
+ rt2x00_rf(rt2x00dev, RF5392)) {
+ spec->num_channels = 14;
+ spec->channels = rf_vals_3x;
++ } else if (rt2x00_rf(rt2x00dev, RF3322)) {
++ spec->num_channels = 14;
++ if (spec->clk_is_20mhz)
++ spec->channels = rf_vals_xtal20mhz_3x;
++ else
++ spec->channels = rf_vals_3x;
+ } else if (rt2x00_rf(rt2x00dev, RF3052)) {
+ spec->supported_bands |= SUPPORT_BAND_5GHZ;
+ spec->num_channels = ARRAY_SIZE(rf_vals_3x);
+@@ -6366,6 +6392,19 @@ static int rt2800_probe_rt(struct rt2x00
+ return 0;
+ }
+
++int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
++ struct hw_mode_spec *spec = &rt2x00dev->spec;
++
++ if (!pdata)
++ return -EINVAL;
++
++ spec->clk_is_20mhz = pdata->clk_is_20mhz;
++
++ return 0;
++}
++
+ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
+ {
+ int retval;
+@@ -6395,6 +6434,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+ rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
+
+ /*
++ * Probe SoC clock.
++ */
++ if (rt2x00_is_soc(rt2x00dev)) {
++ retval = rt2800_probe_clk(rt2x00dev);
++ if (retval)
++ return retval;
++ }
++
++ /*
+ * Initialize hw specifications.
+ */
+ retval = rt2800_probe_hw_mode(rt2x00dev);
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -409,6 +409,7 @@ static inline struct rt2x00_intf* vif_to
+ * @channels: Device/chipset specific channel values (See &struct rf_channel).
+ * @channels_info: Additional information for channels (See &struct channel_info).
+ * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
++ * @clk_is_20mhz: External crystal of WiSoC is 20MHz instead of 40MHz
+ */
+ struct hw_mode_spec {
+ unsigned int supported_bands;
+@@ -425,6 +426,7 @@ struct hw_mode_spec {
+ const struct channel_info *channels_info;
+
+ struct ieee80211_sta_ht_cap ht;
++ int clk_is_20mhz;
+ };
+
+ /*
+--- a/include/linux/rt2x00_platform.h
++++ b/include/linux/rt2x00_platform.h
+@@ -18,6 +18,7 @@ struct rt2x00_platform_data {
+
+ int disable_2ghz;
+ int disable_5ghz;
++ int clk_is_20mhz;
+ };
+
+ #endif /* _RT2X00_PLATFORM_H */
diff --git a/package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch b/package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
new file mode 100644
index 0000000000..6b783bc6e8
--- /dev/null
+++ b/package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
@@ -0,0 +1,34 @@
+From 04dbd87265f6ba4a373b211ba324b437d224fb2d Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 17 Mar 2013 00:03:31 +0100
+Subject: [PATCH 21/38] rt2x00: make wmac loadable via OF on rt288x/305x SoC
+
+This patch ads the match table to allow loading the wmac support from a
+devicetree.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800pci.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800pci.c
++++ b/drivers/net/wireless/rt2x00/rt2800pci.c
+@@ -1308,11 +1308,18 @@ static int rt2800soc_probe(struct platfo
+ return rt2x00soc_probe(pdev, &rt2800pci_ops);
+ }
+
++static const struct of_device_id rt2880_wmac_match[] = {
++ { .compatible = "ralink,rt2880-wmac" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, rt2880_wmac_match);
++
+ static struct platform_driver rt2800soc_driver = {
+ .driver = {
+ .name = "rt2800_wmac",
+ .owner = THIS_MODULE,
+ .mod_name = KBUILD_MODNAME,
++ .of_match_table = rt2880_wmac_match,
+ },
+ .probe = rt2800soc_probe,
+ .remove = rt2x00soc_remove,
diff --git a/package/kernel/mac80211/patches/614-rt2x00-of_load_eeprom_filename.patch b/package/kernel/mac80211/patches/614-rt2x00-of_load_eeprom_filename.patch
new file mode 100644
index 0000000000..293b71a183
--- /dev/null
+++ b/package/kernel/mac80211/patches/614-rt2x00-of_load_eeprom_filename.patch
@@ -0,0 +1,28 @@
+--- a/drivers/net/wireless/rt2x00/rt2800pci.c
++++ b/drivers/net/wireless/rt2x00/rt2800pci.c
+@@ -39,6 +39,7 @@
+ #include <linux/pci.h>
+ #include <linux/platform_device.h>
+ #include <linux/eeprom_93cx6.h>
++#include <linux/of.h>
+
+ #include "rt2x00.h"
+ #include "rt2x00mmio.h"
+@@ -323,11 +324,17 @@ static int rt2800pci_write_firmware(stru
+ static char *rt2800pci_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
+ {
+ struct rt2x00_platform_data *pdata;
++ struct device_node *np;
++ char *eep;
+
+ pdata = rt2x00dev->dev->platform_data;
+ if (pdata)
+ return pdata->eeprom_file_name;
+
++ np = rt2x00dev->dev->of_node;
++ if (np && !of_property_read_string(np, "ralink,eeprom", &eep))
++ return eep;
++
+ return NULL;
+ }
+
diff --git a/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch b/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
new file mode 100644
index 0000000000..a0dc81c28d
--- /dev/null
+++ b/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
@@ -0,0 +1,29 @@
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -38,6 +38,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
++#include <linux/clk.h>
+
+ #include "rt2x00.h"
+ #include "rt2800lib.h"
+@@ -6394,13 +6395,14 @@ static int rt2800_probe_rt(struct rt2x00
+
+ int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev)
+ {
+- struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
+ struct hw_mode_spec *spec = &rt2x00dev->spec;
++ struct clk *clk = clk_get(rt2x00dev->dev, NULL);
+
+- if (!pdata)
+- return -EINVAL;
++ if (IS_ERR(clk))
++ return PTR_ERR(clk);
+
+- spec->clk_is_20mhz = pdata->clk_is_20mhz;
++ if (clk_get_rate(clk) == 20000000)
++ spec->clk_is_20mhz = 1;
+
+ return 0;
+ }
diff --git a/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch b/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch
new file mode 100644
index 0000000000..79e864ba89
--- /dev/null
+++ b/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch
@@ -0,0 +1,285 @@
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -71,6 +71,7 @@
+ #define RF3053 0x000d
+ #define RF5592 0x000f
+ #define RF3290 0x3290
++#define RF5350 0x5350
+ #define RF5360 0x5360
+ #define RF5370 0x5370
+ #define RF5372 0x5372
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -2141,6 +2141,15 @@ static void rt2800_config_channel_rf53xx
+ if (rf->channel <= 14) {
+ int idx = rf->channel-1;
+
++ if (rt2x00_rt(rt2x00dev, RT5350)) {
++ static const char r59_non_bt[] = {0x0b, 0x0b,
++ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a,
++ 0x0a, 0x09, 0x08, 0x07, 0x07, 0x06};
++
++ rt2800_rfcsr_write(rt2x00dev, 59,
++ r59_non_bt[idx]);
++ }
++
+ if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
+ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
+ /* r55/r59 value array of channel 1~14 */
+@@ -2598,6 +2607,7 @@ static void rt2800_config_channel(struct
+ case RF3322:
+ rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
+ break;
++ case RF5350:
+ case RF5360:
+ case RF5370:
+ case RF5372:
+@@ -2614,6 +2624,7 @@ static void rt2800_config_channel(struct
+
+ if (rt2x00_rf(rt2x00dev, RF3290) ||
+ rt2x00_rf(rt2x00dev, RF3322) ||
++ rt2x00_rf(rt2x00dev, RF5350) ||
+ rt2x00_rf(rt2x00dev, RF5360) ||
+ rt2x00_rf(rt2x00dev, RF5370) ||
+ rt2x00_rf(rt2x00dev, RF5372) ||
+@@ -2755,7 +2766,8 @@ static void rt2800_config_channel(struct
+ /*
+ * Clear update flag
+ */
+- if (rt2x00_rt(rt2x00dev, RT3352)) {
++ if (rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350)) {
+ rt2800_bbp_read(rt2x00dev, 49, &bbp);
+ rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
+ rt2800_bbp_write(rt2x00dev, 49, bbp);
+@@ -3201,6 +3213,7 @@ void rt2800_vco_calibration(struct rt2x0
+ rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+ break;
+ case RF3290:
++ case RF5350:
+ case RF5360:
+ case RF5370:
+ case RF5372:
+@@ -3540,7 +3553,8 @@ static int rt2800_init_registers(struct
+ } else if (rt2x00_rt(rt2x00dev, RT3572)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+- } else if (rt2x00_rt(rt2x00dev, RT5390) ||
++ } else if (rt2x00_rt(rt2x00dev, RT5350) ||
++ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392) ||
+ rt2x00_rt(rt2x00dev, RT5592)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+@@ -4193,9 +4207,13 @@ static void rt2800_init_bbp_3352(struct
+
+ rt2800_bbp_write(rt2x00dev, 82, 0x62);
+
+- rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+-
+- rt2800_bbp_write(rt2x00dev, 84, 0x99);
++ if (rt2x00_rt(rt2x00dev, RT5350)) {
++ rt2800_bbp_write(rt2x00dev, 83, 0x7a);
++ rt2800_bbp_write(rt2x00dev, 84, 0x9a);
++ } else {
++ rt2800_bbp_write(rt2x00dev, 83, 0x6a);
++ rt2800_bbp_write(rt2x00dev, 84, 0x99);
++ }
+
+ rt2800_bbp_write(rt2x00dev, 86, 0x38);
+
+@@ -4209,9 +4227,13 @@ static void rt2800_init_bbp_3352(struct
+
+ rt2800_bbp_write(rt2x00dev, 104, 0x92);
+
+- rt2800_bbp_write(rt2x00dev, 105, 0x34);
+-
+- rt2800_bbp_write(rt2x00dev, 106, 0x05);
++ if (rt2x00_rt(rt2x00dev, RT5350)) {
++ rt2800_bbp_write(rt2x00dev, 105, 0x3c);
++ rt2800_bbp_write(rt2x00dev, 106, 0x03);
++ } else {
++ rt2800_bbp_write(rt2x00dev, 105, 0x34);
++ rt2800_bbp_write(rt2x00dev, 106, 0x05);
++ }
+
+ rt2800_bbp_write(rt2x00dev, 120, 0x50);
+
+@@ -4236,6 +4258,13 @@ static void rt2800_init_bbp_3352(struct
+ rt2800_bbp_write(rt2x00dev, 143, 0xa2);
+
+ rt2800_bbp_write(rt2x00dev, 148, 0xc8);
++
++ if (rt2x00_rt(rt2x00dev, RT5350)) {
++ rt2800_bbp_write(rt2x00dev, 150, 0x40); /* Antenna Software OFDM */
++ rt2800_bbp_write(rt2x00dev, 151, 0x30); /* Antenna Software CCK */
++ rt2800_bbp_write(rt2x00dev, 152, 0xa3);
++ rt2800_bbp_write(rt2x00dev, 154, 0); /* Clear previously selected antenna */
++ }
+ }
+
+ static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev)
+@@ -4520,6 +4549,7 @@ static void rt2800_init_bbp(struct rt2x0
+ rt2800_init_bbp_3290(rt2x00dev);
+ break;
+ case RT3352:
++ case RT5350:
+ rt2800_init_bbp_3352(rt2x00dev);
+ break;
+ case RT3390:
+@@ -5159,6 +5189,76 @@ static void rt2800_init_rfcsr_3572(struc
+ rt2800_normal_mode_setup_3xxx(rt2x00dev);
+ }
+
++static void rt2800_init_rfcsr_5350(struct rt2x00_dev *rt2x00dev)
++{
++ rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
++ rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
++ rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
++ rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
++ rt2800_rfcsr_write(rt2x00dev, 4, 0x49);
++ rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
++ rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
++ rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
++ rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
++ rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
++ rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
++ if(rt2x00dev->spec.clk_is_20mhz)
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x1f);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
++ rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 16, 0xc0);
++ rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
++ rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
++ rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
++ rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 29, 0xd0);
++ rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
++ rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
++ rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
++ rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
++ rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
++ rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
++ rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
++ rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
++ rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
++ rt2800_rfcsr_write(rt2x00dev, 43, 0x9b);
++ rt2800_rfcsr_write(rt2x00dev, 44, 0x0c);
++ rt2800_rfcsr_write(rt2x00dev, 45, 0xa6);
++ rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
++ rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
++ rt2800_rfcsr_write(rt2x00dev, 49, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 50, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 51, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
++ rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 54, 0x38);
++ rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
++ rt2800_rfcsr_write(rt2x00dev, 56, 0x82);
++ rt2800_rfcsr_write(rt2x00dev, 57, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 58, 0x39);
++ rt2800_rfcsr_write(rt2x00dev, 59, 0x0b);
++ rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
++ rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
++ rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
++}
++
+ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
+ {
+ rt2800_rf_init_calibration(rt2x00dev, 2);
+@@ -5387,6 +5487,9 @@ static void rt2800_init_rfcsr(struct rt2
+ case RT3572:
+ rt2800_init_rfcsr_3572(rt2x00dev);
+ break;
++ case RT5350:
++ rt2800_init_rfcsr_5350(rt2x00dev);
++ break;
+ case RT5390:
+ rt2800_init_rfcsr_5390(rt2x00dev);
+ break;
+@@ -5598,6 +5701,12 @@ static int rt2800_validate_eeprom(struct
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
+ rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
++ } else if (rt2x00_rt(rt2x00dev, RT5350)) {
++ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 1);
++ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1);
++ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF3320);
++ rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
++ rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
+ } else if (rt2x00_rt(rt2x00dev, RT2860) ||
+ rt2x00_rt(rt2x00dev, RT2872)) {
+ /*
+@@ -5723,9 +5832,12 @@ static int rt2800_init_eeprom(struct rt2
+ */
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT3352) ||
++ rt2x00_rt(rt2x00dev, RT5350) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
++ else if (rt2x00_rt(rt2x00dev, RT5350))
++ rf = RF5350;
+ else
+ rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
+
+@@ -5742,6 +5854,7 @@ static int rt2800_init_eeprom(struct rt2
+ case RF3290:
+ case RF3320:
+ case RF3322:
++ case RF5350:
+ case RF5360:
+ case RF5370:
+ case RF5372:
+@@ -6240,7 +6353,8 @@ static int rt2800_probe_hw_mode(struct r
+ rt2x00_rf(rt2x00dev, RF5392)) {
+ spec->num_channels = 14;
+ spec->channels = rf_vals_3x;
+- } else if (rt2x00_rf(rt2x00dev, RF3322)) {
++ } else if (rt2x00_rf(rt2x00dev, RF3322) ||
++ rt2x00_rf(rt2x00dev, RF5350)) {
+ spec->num_channels = 14;
+ if (spec->clk_is_20mhz)
+ spec->channels = rf_vals_xtal20mhz_3x;
+@@ -6341,6 +6455,7 @@ static int rt2800_probe_hw_mode(struct r
+ case RF3320:
+ case RF3052:
+ case RF3290:
++ case RF5350:
+ case RF5360:
+ case RF5370:
+ case RF5372:
+@@ -6378,6 +6493,7 @@ static int rt2800_probe_rt(struct rt2x00
+ case RT3352:
+ case RT3390:
+ case RT3572:
++ case RT5350:
+ case RT5390:
+ case RT5392:
+ case RT5592:
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -181,6 +181,7 @@ struct rt2x00_chip {
+ #define RT3572 0x3572
+ #define RT3593 0x3593
+ #define RT3883 0x3883 /* WSOC */
++#define RT5350 0x5350 /* WSOC 2.4GHz */
+ #define RT5390 0x5390 /* 2.4GHz */
+ #define RT5392 0x5392 /* 2.4GHz */
+ #define RT5592 0x5592
diff --git a/package/kernel/mac80211/patches/617-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch b/package/kernel/mac80211/patches/617-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch
new file mode 100644
index 0000000000..d5af4c9ae2
--- /dev/null
+++ b/package/kernel/mac80211/patches/617-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch
@@ -0,0 +1,102 @@
+From 339fe73f340161a624cc08e738d2244814852c3e Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 17 Mar 2013 00:55:04 +0100
+Subject: [PATCH] rt2x00: load eeprom on SoC from a mtd device defines inside
+ OF
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/Kconfig | 1 +
+ drivers/net/wireless/rt2x00/rt2800pci.c | 44 ++++++++++++++++++++++++++-----
+ 2 files changed, 39 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/Kconfig
++++ b/drivers/net/wireless/rt2x00/Kconfig
+@@ -71,6 +71,7 @@ config RT2800PCI
+ select RT2X00_LIB_FIRMWARE
+ select RT2X00_LIB_EEPROM
+ select RT2X00_LIB_CRYPTO
++ select MTD if SOC_RT288X || SOC_RT305X
+ depends on CRC_CCITT
+ depends on EEPROM_93CX6
+ ---help---
+--- a/drivers/net/wireless/rt2x00/rt2x00eeprom.c
++++ b/drivers/net/wireless/rt2x00/rt2x00eeprom.c
+@@ -30,12 +30,77 @@
+ #include "rt2x00.h"
+ #include "rt2x00lib.h"
+
++#ifdef CONFIG_OF
++#include <linux/of.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++
++static struct firmware mtd_fw;
++
++static int rt2800pci_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
++{
++ struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL;
++ size_t retlen, len = rt2x00dev->ops->eeprom_size;
++ int ret, size, offset = 0;
++ struct mtd_info *mtd;
++ const char *part;
++ const __be32 *list;
++ phandle phandle;
++
++ list = of_get_property(np, "ralink,mtd-eeprom", &size);
++ if (!list) {
++ dev_err(rt2x00dev->dev, "failed to load eeprom property\n");
++ return -ENOENT;
++ }
++
++ phandle = be32_to_cpup(list++);
++ if (phandle)
++ mtd_np = of_find_node_by_phandle(phandle);
++ if (!mtd_np) {
++ dev_err(rt2x00dev->dev, "failed to load mtd phandle\n");
++ return -EINVAL;
++ }
++
++ part = of_get_property(mtd_np, "label", NULL);
++ if (!part)
++ part = mtd_np->name;
++
++ mtd = get_mtd_device_nm(part);
++ if (IS_ERR(mtd)) {
++ dev_err(rt2x00dev->dev, "failed to get mtd device \"%s\"\n", part);
++ return PTR_ERR(mtd);
++ }
++
++ if (size > sizeof(*list))
++ offset = be32_to_cpup(list);
++
++ ret = mtd_read(mtd, offset, len, &retlen, (u_char *) rt2x00dev->eeprom);
++ put_mtd_device(mtd);
++
++ if (!ret) {
++ rt2x00dev->eeprom_file = &mtd_fw;
++ mtd_fw.size = len;
++ mtd_fw.data = rt2x00dev->eeprom;
++ }
++
++ return ret;
++}
++#else
++static inline int rt2800pci_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
++{
++ return -EINVAL;
++}
++#endif
++
+ static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev)
+ {
+ const struct firmware *ee;
+ char *ee_name;
+ int retval;
+
++ if (!rt2800pci_read_eeprom_mtd(rt2x00dev))
++ return 0;
++
+ ee_name = rt2x00dev->ops->lib->get_eeprom_file_name(rt2x00dev);
+ if (!ee_name) {
+ rt2x00_err(rt2x00dev,
diff --git a/package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
new file mode 100644
index 0000000000..3381ba56ad
--- /dev/null
+++ b/package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
@@ -0,0 +1,10 @@
+--- a/drivers/net/wireless/mwl8k.c
++++ b/drivers/net/wireless/mwl8k.c
+@@ -5530,6 +5530,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
+ MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
+
+ static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
++ { PCI_VDEVICE(MARVELL, 0x2a02), .driver_data = MWL8363, },
+ { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
+ { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
+ { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
diff --git a/package/kernel/mac80211/patches/800-b43-gpio-mask-module-option.patch b/package/kernel/mac80211/patches/800-b43-gpio-mask-module-option.patch
new file mode 100644
index 0000000000..d2ccf30d7d
--- /dev/null
+++ b/package/kernel/mac80211/patches/800-b43-gpio-mask-module-option.patch
@@ -0,0 +1,37 @@
+--- a/drivers/net/wireless/b43/b43.h
++++ b/drivers/net/wireless/b43/b43.h
+@@ -820,6 +820,7 @@ struct b43_wldev {
+ bool qos_enabled; /* TRUE, if QoS is used. */
+ bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */
+ bool use_pio; /* TRUE if next init should use PIO */
++ int gpiomask; /* GPIO LED mask as a module parameter */
+
+ /* PHY/Radio device. */
+ struct b43_phy phy;
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -76,6 +76,11 @@ MODULE_FIRMWARE("b43/ucode16_mimo.fw");
+ MODULE_FIRMWARE("b43/ucode5.fw");
+ MODULE_FIRMWARE("b43/ucode9.fw");
+
++static int modparam_gpiomask = 0x000F;
++module_param_named(gpiomask, modparam_gpiomask, int, 0444);
++MODULE_PARM_DESC(gpiomask,
++ "GPIO mask for LED control (default 0x000F)");
++
+ static int modparam_bad_frames_preempt;
+ module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
+ MODULE_PARM_DESC(bad_frames_preempt,
+@@ -2740,10 +2745,10 @@ static int b43_gpio_init(struct b43_wlde
+ u32 mask, set;
+
+ b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
+- b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF);
++ b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, modparam_gpiomask);
+
+ mask = 0x0000001F;
+- set = 0x0000000F;
++ set = modparam_gpiomask;
+ if (dev->dev->chip_id == 0x4301) {
+ mask |= 0x0060;
+ set |= 0x0060;
diff --git a/package/kernel/mac80211/patches/810-b43_no_pio.patch b/package/kernel/mac80211/patches/810-b43_no_pio.patch
new file mode 100644
index 0000000000..0821dc7856
--- /dev/null
+++ b/package/kernel/mac80211/patches/810-b43_no_pio.patch
@@ -0,0 +1,86 @@
+--- a/drivers/net/wireless/b43/Makefile
++++ b/drivers/net/wireless/b43/Makefile
+@@ -20,7 +20,7 @@ b43-y += xmit.o
+ b43-y += lo.o
+ b43-y += wa.o
+ b43-y += dma.o
+-b43-y += pio.o
++b43-$(CONFIG_B43_PIO) += pio.o
+ b43-y += rfkill.o
+ b43-$(CPTCFG_B43_LEDS) += leds.o
+ b43-$(CPTCFG_B43_PCMCIA) += pcmcia.o
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -1913,10 +1913,12 @@ static void b43_do_interrupt_thread(stru
+ dma_reason[0], dma_reason[1],
+ dma_reason[2], dma_reason[3],
+ dma_reason[4], dma_reason[5]);
++#ifdef CONFIG_B43_PIO
+ b43err(dev->wl, "This device does not support DMA "
+ "on your system. It will now be switched to PIO.\n");
+ /* Fall back to PIO transfers if we get fatal DMA errors! */
+ dev->use_pio = true;
++#endif
+ b43_controller_restart(dev, "DMA error");
+ return;
+ }
+--- a/drivers/net/wireless/b43/pio.h
++++ b/drivers/net/wireless/b43/pio.h
+@@ -150,7 +150,7 @@ static inline void b43_piorx_write32(str
+ b43_write32(q->dev, q->mmio_base + offset, value);
+ }
+
+-
++#ifdef CONFIG_B43_PIO
+ int b43_pio_init(struct b43_wldev *dev);
+ void b43_pio_free(struct b43_wldev *dev);
+
+@@ -161,5 +161,37 @@ void b43_pio_rx(struct b43_pio_rxqueue *
+
+ void b43_pio_tx_suspend(struct b43_wldev *dev);
+ void b43_pio_tx_resume(struct b43_wldev *dev);
++#else
++static inline int b43_pio_init(struct b43_wldev *dev)
++{
++ return 0;
++}
++
++static inline void b43_pio_free(struct b43_wldev *dev)
++{
++}
++
++static inline int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
++{
++ return 0;
++}
++
++static inline void b43_pio_handle_txstatus(struct b43_wldev *dev,
++ const struct b43_txstatus *status)
++{
++}
++
++static inline void b43_pio_rx(struct b43_pio_rxqueue *q)
++{
++}
++
++static inline void b43_pio_tx_suspend(struct b43_wldev *dev)
++{
++}
++
++static inline void b43_pio_tx_resume(struct b43_wldev *dev)
++{
++}
++#endif /* CONFIG_B43_PIO */
+
+ #endif /* B43_PIO_H_ */
+--- a/drivers/net/wireless/b43/Kconfig
++++ b/drivers/net/wireless/b43/Kconfig
+@@ -104,7 +104,7 @@ config B43_BCMA_PIO
+ default y
+
+ config B43_PIO
+- bool
++ bool "Broadcom 43xx PIO support"
+ depends on B43
+ select SSB_BLOCKIO
+ default y
diff --git a/package/kernel/mac80211/patches/820-b43-add-antenna-control.patch b/package/kernel/mac80211/patches/820-b43-add-antenna-control.patch
new file mode 100644
index 0000000000..c17c1ca0a9
--- /dev/null
+++ b/package/kernel/mac80211/patches/820-b43-add-antenna-control.patch
@@ -0,0 +1,131 @@
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -1560,7 +1560,7 @@ static void b43_write_beacon_template(st
+ len, ram_offset, shm_size_offset, rate);
+
+ /* Write the PHY TX control parameters. */
+- antenna = B43_ANTENNA_DEFAULT;
++ antenna = dev->tx_antenna;
+ antenna = b43_antenna_to_phyctl(antenna);
+ ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
+ /* We can't send beacons with short preamble. Would get PHY errors. */
+@@ -3098,8 +3098,8 @@ static int b43_chip_init(struct b43_wlde
+
+ /* Select the antennae */
+ if (phy->ops->set_rx_antenna)
+- phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT);
+- b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT);
++ phy->ops->set_rx_antenna(dev, dev->rx_antenna);
++ b43_mgmtframe_txantenna(dev, dev->tx_antenna);
+
+ if (phy->type == B43_PHYTYPE_B) {
+ value16 = b43_read16(dev, 0x005E);
+@@ -3843,7 +3843,6 @@ static int b43_op_config(struct ieee8021
+ struct b43_wldev *dev;
+ struct b43_phy *phy;
+ struct ieee80211_conf *conf = &hw->conf;
+- int antenna;
+ int err = 0;
+ bool reload_bss = false;
+
+@@ -3897,11 +3896,9 @@ static int b43_op_config(struct ieee8021
+ }
+
+ /* Antennas for RX and management frame TX. */
+- antenna = B43_ANTENNA_DEFAULT;
+- b43_mgmtframe_txantenna(dev, antenna);
+- antenna = B43_ANTENNA_DEFAULT;
++ b43_mgmtframe_txantenna(dev, dev->tx_antenna);
+ if (phy->ops->set_rx_antenna)
+- phy->ops->set_rx_antenna(dev, antenna);
++ phy->ops->set_rx_antenna(dev, dev->rx_antenna);
+
+ if (wl->radio_enabled != phy->radio_on) {
+ if (wl->radio_enabled) {
+@@ -5026,6 +5023,47 @@ static int b43_op_get_survey(struct ieee
+ return 0;
+ }
+
++static int b43_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
++{
++ struct b43_wl *wl = hw_to_b43_wl(hw);
++ struct b43_wldev *dev = wl->current_dev;
++
++ if (tx_ant == 1 && rx_ant == 1) {
++ dev->tx_antenna = B43_ANTENNA0;
++ dev->rx_antenna = B43_ANTENNA0;
++ }
++ else if (tx_ant == 2 && rx_ant == 2) {
++ dev->tx_antenna = B43_ANTENNA1;
++ dev->rx_antenna = B43_ANTENNA1;
++ }
++ else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) {
++ dev->tx_antenna = B43_ANTENNA_DEFAULT;
++ dev->rx_antenna = B43_ANTENNA_DEFAULT;
++ }
++ else {
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++
++static int b43_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
++{
++ struct b43_wl *wl = hw_to_b43_wl(hw);
++ struct b43_wldev *dev = wl->current_dev;
++
++ switch (dev->tx_antenna) {
++ case B43_ANTENNA0:
++ *tx_ant = 1; *rx_ant = 1; break;
++ case B43_ANTENNA1:
++ *tx_ant = 2; *rx_ant = 2; break;
++ case B43_ANTENNA_DEFAULT:
++ *tx_ant = 3; *rx_ant = 3; break;
++ }
++ return 0;
++}
++
+ static const struct ieee80211_ops b43_hw_ops = {
+ .tx = b43_op_tx,
+ .conf_tx = b43_op_conf_tx,
+@@ -5047,6 +5085,8 @@ static const struct ieee80211_ops b43_hw
+ .sw_scan_complete = b43_op_sw_scan_complete_notifier,
+ .get_survey = b43_op_get_survey,
+ .rfkill_poll = b43_rfkill_poll,
++ .set_antenna = b43_op_set_antenna,
++ .get_antenna = b43_op_get_antenna,
+ };
+
+ /* Hard-reset the chip. Do not call this directly.
+@@ -5293,6 +5333,8 @@ static int b43_one_core_attach(struct b4
+ if (!wldev)
+ goto out;
+
++ wldev->rx_antenna = B43_ANTENNA_DEFAULT;
++ wldev->tx_antenna = B43_ANTENNA_DEFAULT;
+ wldev->use_pio = b43_modparam_pio;
+ wldev->dev = dev;
+ wldev->wl = wl;
+@@ -5383,6 +5425,9 @@ static struct b43_wl *b43_wireless_init(
+
+ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
++ hw->wiphy->available_antennas_rx = 0x3;
++ hw->wiphy->available_antennas_tx = 0x3;
++
+ wl->hw_registred = false;
+ hw->max_rates = 2;
+ SET_IEEE80211_DEV(hw, dev->dev);
+--- a/drivers/net/wireless/b43/b43.h
++++ b/drivers/net/wireless/b43/b43.h
+@@ -821,6 +821,8 @@ struct b43_wldev {
+ bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */
+ bool use_pio; /* TRUE if next init should use PIO */
+ int gpiomask; /* GPIO LED mask as a module parameter */
++ int rx_antenna; /* Used RX antenna (B43_ANTENNAxxx) */
++ int tx_antenna; /* Used TX antenna (B43_ANTENNAxxx) */
+
+ /* PHY/Radio device. */
+ struct b43_phy phy;
diff --git a/package/kernel/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch b/package/kernel/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch
new file mode 100644
index 0000000000..e55d4fe4aa
--- /dev/null
+++ b/package/kernel/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch
@@ -0,0 +1,134 @@
+From 4f214b1ead0af7439921637645cb63f378516175 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Sat, 21 Jan 2012 18:48:38 +0100
+Subject: [PATCH 33/34] b43: add workaround for b43 on pcie bus of bcm4716.
+
+bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
+transactions. As a fix, a read after write is performed on certain
+places in the code. Older chips and the newer 5357 family don't require
+this fix.
+This code is based on the brcmsmac driver.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ drivers/net/wireless/b43/b43.h | 26 ++++++++++++++++++++++++++
+ drivers/net/wireless/b43/bus.h | 10 ++++++++++
+ drivers/net/wireless/b43/phy_common.c | 6 ++++++
+ drivers/net/wireless/b43/phy_n.c | 10 +++++-----
+ 4 files changed, 47 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/wireless/b43/b43.h
++++ b/drivers/net/wireless/b43/b43.h
+@@ -1061,6 +1061,32 @@ static inline bool b43_using_pio_transfe
+ return dev->__using_pio_transfers;
+ }
+
++/*
++ * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
++ * transactions. As a fix, a read after write is performed on certain places
++ * in the code. Older chips and the newer 5357 family don't require this fix.
++ */
++#ifdef CONFIG_BCM47XX_BCMA
++#include <asm/mach-bcm47xx/bcm47xx.h>
++static inline void b43_wflush16(struct b43_wldev *dev, u16 offset, u16 value)
++{
++ if (b43_bus_host_is_pci(dev->dev) &&
++ bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA &&
++ (bcm47xx_bus.bcma.bus.chipinfo.id == 0x4716 ||
++ bcm47xx_bus.bcma.bus.chipinfo.id == 0x5300)) {
++ b43_write16(dev, offset, value);
++ b43_read16(dev, offset);
++ } else {
++ b43_write16(dev, offset, value);
++ }
++}
++#else
++static inline void b43_wflush16(struct b43_wldev *dev, u16 offset, u16 value)
++{
++ b43_write16(dev, offset, value);
++}
++#endif
++
+ /* Message printing */
+ __printf(2, 3) void b43info(struct b43_wl *wl, const char *fmt, ...);
+ __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...);
+--- a/drivers/net/wireless/b43/bus.h
++++ b/drivers/net/wireless/b43/bus.h
+@@ -60,6 +60,16 @@ static inline bool b43_bus_host_is_sdio(
+ return (dev->bus_type == B43_BUS_SSB &&
+ dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO);
+ }
++static inline bool b43_bus_host_is_pci(struct b43_bus_dev *dev)
++{
++ if (dev->bus_type == B43_BUS_SSB)
++ return (dev->sdev->bus->bustype == SSB_BUSTYPE_PCI);
++#ifdef CONFIG_B43_BCMA
++ if (dev->bus_type == B43_BUS_BCMA)
++ return (dev->bdev->bus->hosttype == BCMA_HOSTTYPE_PCI);
++#endif
++ return false;
++}
+
+ struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core);
+ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev);
+--- a/drivers/net/wireless/b43/phy_common.c
++++ b/drivers/net/wireless/b43/phy_common.c
+@@ -266,6 +266,12 @@ void b43_phy_write(struct b43_wldev *dev
+ {
+ assert_mac_suspended(dev);
+ dev->phy.ops->phy_write(dev, reg, value);
++#ifdef CONFIG_BCM47XX
++ if (b43_bus_host_is_pci(dev->dev) && reg == 0x72) {
++ b43_read16(dev, B43_MMIO_PHY_VER);
++ return;
++ }
++#endif
+ if (++dev->phy.writes_counter == B43_MAX_WRITES_IN_ROW) {
+ b43_read16(dev, B43_MMIO_PHY_VER);
+ dev->phy.writes_counter = 0;
+--- a/drivers/net/wireless/b43/phy_n.c
++++ b/drivers/net/wireless/b43/phy_n.c
+@@ -5417,14 +5417,14 @@ static inline void check_phyreg(struct b
+ static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg)
+ {
+ check_phyreg(dev, reg);
+- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
++ b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
+ return b43_read16(dev, B43_MMIO_PHY_DATA);
+ }
+
+ static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
+ {
+ check_phyreg(dev, reg);
+- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
++ b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16(dev, B43_MMIO_PHY_DATA, value);
+ }
+
+@@ -5432,7 +5432,7 @@ static void b43_nphy_op_maskset(struct b
+ u16 set)
+ {
+ check_phyreg(dev, reg);
+- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
++ b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
+ }
+
+@@ -5443,7 +5443,7 @@ static u16 b43_nphy_op_radio_read(struct
+ /* N-PHY needs 0x100 for read access */
+ reg |= 0x100;
+
+- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
++ b43_wflush16(dev, B43_MMIO_RADIO_CONTROL, reg);
+ return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
+ }
+
+@@ -5452,7 +5452,7 @@ static void b43_nphy_op_radio_write(stru
+ /* Register 1 is a 32-bit register. */
+ B43_WARN_ON(reg == 1);
+
+- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
++ b43_wflush16(dev, B43_MMIO_RADIO_CONTROL, reg);
+ b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
+ }
+
diff --git a/package/kernel/mac80211/patches/841-b43-reduce-number-of-RX-slots.patch b/package/kernel/mac80211/patches/841-b43-reduce-number-of-RX-slots.patch
new file mode 100644
index 0000000000..9c51ac63d7
--- /dev/null
+++ b/package/kernel/mac80211/patches/841-b43-reduce-number-of-RX-slots.patch
@@ -0,0 +1,11 @@
+--- a/drivers/net/wireless/b43/dma.h
++++ b/drivers/net/wireless/b43/dma.h
+@@ -169,7 +169,7 @@ struct b43_dmadesc_generic {
+
+ /* DMA engine tuning knobs */
+ #define B43_TXRING_SLOTS 256
+-#define B43_RXRING_SLOTS 256
++#define B43_RXRING_SLOTS 32
+ #define B43_DMA0_RX_FW598_BUFSIZE (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN)
+ #define B43_DMA0_RX_FW351_BUFSIZE (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN)
+
diff --git a/package/kernel/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch b/package/kernel/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch
new file mode 100644
index 0000000000..35d774492e
--- /dev/null
+++ b/package/kernel/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch
@@ -0,0 +1,17 @@
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -2757,6 +2757,14 @@ static int b43_gpio_init(struct b43_wlde
+ } else if (dev->dev->chip_id == 0x5354) {
+ /* Don't allow overtaking buttons GPIOs */
+ set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */
++ } else if (dev->dev->chip_id == BCMA_CHIP_ID_BCM4716 ||
++ dev->dev->chip_id == BCMA_CHIP_ID_BCM47162 ||
++ dev->dev->chip_id == BCMA_CHIP_ID_BCM5356 ||
++ dev->dev->chip_id == BCMA_CHIP_ID_BCM5357 ||
++ dev->dev->chip_id == BCMA_CHIP_ID_BCM53572) {
++ /* just use gpio 0 and 1 for 2.4 GHz wifi led */
++ set &= 0x3;
++ mask &= 0x3;
+ }
+
+ if (0 /* FIXME: conditional unknown */ ) {
diff --git a/package/kernel/mac80211/patches/851-brcmsmac-remove-extra-regulation-restriction.patch b/package/kernel/mac80211/patches/851-brcmsmac-remove-extra-regulation-restriction.patch
new file mode 100644
index 0000000000..dd1393ae5d
--- /dev/null
+++ b/package/kernel/mac80211/patches/851-brcmsmac-remove-extra-regulation-restriction.patch
@@ -0,0 +1,31 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+@@ -59,23 +59,16 @@
+
+ #define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0)
+ #define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \
+- NL80211_RRF_PASSIVE_SCAN | \
+- NL80211_RRF_NO_IBSS)
++ 0)
+
+ #define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \
+- NL80211_RRF_PASSIVE_SCAN | \
+- NL80211_RRF_NO_IBSS)
++ 0)
+ #define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \
+- NL80211_RRF_PASSIVE_SCAN | \
+- NL80211_RRF_DFS | \
+- NL80211_RRF_NO_IBSS)
++ 0)
+ #define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \
+- NL80211_RRF_PASSIVE_SCAN | \
+- NL80211_RRF_DFS | \
+- NL80211_RRF_NO_IBSS)
++ 0)
+ #define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \
+- NL80211_RRF_PASSIVE_SCAN | \
+- NL80211_RRF_NO_IBSS)
++ 0)
+
+ static const struct ieee80211_regdomain brcms_regdom_x2 = {
+ .n_reg_rules = 6,
diff --git a/package/kernel/mmc_over_gpio/Makefile b/package/kernel/mmc_over_gpio/Makefile
new file mode 100644
index 0000000000..62d0ba5b7d
--- /dev/null
+++ b/package/kernel/mmc_over_gpio/Makefile
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=mmc-over-gpio
+PKG_RELEASE:=4
+
+include $(INCLUDE_DIR)/package.mk
+
+
+define KernelPackage/mmc-over-gpio
+ SUBMENU:=Other modules
+ DEPENDS:=@GPIO_SUPPORT +kmod-mmc-spi +kmod-spi-gpio-old +kmod-fs-configfs
+ KCONFIG:=CONFIG_GPIOMMC
+ TITLE:=MMC/SD card over GPIO support
+ FILES:=$(LINUX_DIR)/drivers/mmc/host/gpiommc.ko
+ AUTOLOAD:=$(call AutoLoad,93,gpiommc)
+ MENU:=1
+endef
+
+define Package/kmod-mmc-over-gpio/config
+ menu "Configuration"
+ depends on PACKAGE_kmod-mmc-over-gpio
+
+ config KMOD_MMC_OVER_GPIO_DI_PIN
+ int "GPIO DI (Data-In) pin"
+ default 1
+
+ config KMOD_MMC_OVER_GPIO_DO_PIN
+ int "GPIO DO (Data-Out) pin"
+ default 3
+
+ config KMOD_MMC_OVER_GPIO_CLK_PIN
+ int "GPIO CLK (Clock) pin"
+ default 4
+
+ config KMOD_MMC_OVER_GPIO_CS_PIN
+ int "GPIO CS (Chip-Select) pin"
+ default 7
+
+ endmenu
+endef
+
+define KernelPackage/mmc-over-gpio/description
+ Support for driving an MMC/SD card over GPIO pins via SPI.
+endef
+
+define KernelPackage/mmc-over-gpio/conffiles
+/etc/config/mmc_over_gpio
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+endef
+
+define Build/Compile
+endef
+
+define KernelPackage/mmc-over-gpio/install
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_DATA) ./files/mmc_over_gpio.config $(1)/etc/config/mmc_over_gpio
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/mmc_over_gpio.init $(1)/etc/init.d/mmc_over_gpio
+
+ $(SED) 's,@GPIO_DI_PIN@,$(CONFIG_KMOD_MMC_OVER_GPIO_DI_PIN),g' \
+ -e 's,@GPIO_DO_PIN@,$(CONFIG_KMOD_MMC_OVER_GPIO_DO_PIN),g' \
+ -e 's,@GPIO_CLK_PIN@,$(CONFIG_KMOD_MMC_OVER_GPIO_CLK_PIN),g' \
+ -e 's,@GPIO_CS_PIN@,$(CONFIG_KMOD_MMC_OVER_GPIO_CS_PIN),g' \
+ $(1)/etc/config/mmc_over_gpio
+endef
+
+$(eval $(call KernelPackage,mmc-over-gpio))
diff --git a/package/kernel/mmc_over_gpio/files/mmc_over_gpio.config b/package/kernel/mmc_over_gpio/files/mmc_over_gpio.config
new file mode 100644
index 0000000000..23f0084857
--- /dev/null
+++ b/package/kernel/mmc_over_gpio/files/mmc_over_gpio.config
@@ -0,0 +1,8 @@
+config 'mmc_over_gpio'
+ option 'name' 'default'
+ option 'enabled' '0'
+ option 'DI_pin' '@GPIO_DI_PIN@'
+ option 'DO_pin' '@GPIO_DO_PIN@'
+ option 'CLK_pin' '@GPIO_CLK_PIN@'
+ option 'CS_pin' '@GPIO_CS_PIN@'
+ option 'mode' '0'
diff --git a/package/kernel/mmc_over_gpio/files/mmc_over_gpio.init b/package/kernel/mmc_over_gpio/files/mmc_over_gpio.init
new file mode 100644
index 0000000000..121c80398c
--- /dev/null
+++ b/package/kernel/mmc_over_gpio/files/mmc_over_gpio.init
@@ -0,0 +1,83 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2008 OpenWrt.org
+START=90
+
+CONFIGFS_DIR="/config/gpiommc"
+
+# add_device(name, DI_pin, DO_pin, CLK_pin, CS_pin, mode)
+add_device() {
+ local dir="$CONFIGFS_DIR/$1"
+
+ mkdir -p $dir
+ [ $? -eq 0 ] || return 1
+ echo $2 > $dir/gpio_data_in
+ [ $? -eq 0 ] || return 1
+ echo $3 > $dir/gpio_data_out
+ [ $? -eq 0 ] || return 1
+ echo $4 > $dir/gpio_clock
+ [ $? -eq 0 ] || return 1
+ echo $5 > $dir/gpio_chipselect
+ [ $? -eq 0 ] || return 1
+ echo $6 > $dir/spi_mode
+ [ $? -eq 0 ] || return 1
+ # XXX We have more config options available. Use defaults for now.
+
+ echo 1 > $dir/register
+ [ $? -eq 0 ] || return 1
+
+ return 0
+}
+
+# remove_device(name)
+remove_device() {
+ local dir="$CONFIGFS_DIR/$1"
+
+ rmdir $dir
+}
+
+mount_configfs() {
+ # FIXME: This should probably be done somewhere else.
+ mount | grep configfs
+ if [ $? -eq 0 ]; then
+ # already mounted
+ return 0
+ fi
+ mkdir -p /config
+ [ $? -eq 0 ] || return 1
+ mount configfs -t configfs /config
+ [ $? -eq 0 ] || return 1
+
+ return 0
+}
+
+start_service() {
+ local section="$1"
+ config_get "name" "$section" "name"
+ config_get "DI_pin" "$section" "DI_pin"
+ config_get "DO_pin" "$section" "DO_pin"
+ config_get "CLK_pin" "$section" "CLK_pin"
+ config_get "CS_pin" "$section" "CS_pin"
+ config_get "mode" "$section" "mode"
+ config_get_bool "enabled" "$section" "enabled" '1'
+ [ "$enabled" -gt 0 ] && add_device "$name" $DI_pin $DO_pin $CLK_pin $CS_pin $mode &
+}
+
+stop_service() {
+ local section="$1"
+ config_get "name" "$section" "name"
+ remove_device "$name"
+}
+
+start() {
+ # Make sure configfs is mounted
+ mount_configfs
+ [ $? -eq 0 ] || return 1
+
+ config_load "mmc_over_gpio"
+ config_foreach start_service "mmc_over_gpio"
+}
+
+stop() {
+ config_load "mmc_over_gpio"
+ config_foreach stop_service "mmc_over_gpio"
+}
diff --git a/package/kernel/om-watchdog/Makefile b/package/kernel/om-watchdog/Makefile
new file mode 100644
index 0000000000..7d517a11eb
--- /dev/null
+++ b/package/kernel/om-watchdog/Makefile
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=om-watchdog
+PKG_RELEASE:=1
+PKG_VERSION:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/om-watchdog
+ SECTION:=base
+ CATEGORY:=Base system
+ TITLE:=om watchdog
+ URL:=http://openwrt.org/
+endef
+
+define Package/om-watchdog/description
+ This package contains the hw watchdog script for the OM1P and OM2P device.
+endef
+
+define Build/Prepare
+endef
+
+define Build/Compile
+endef
+
+define Build/Compile
+endef
+
+define Package/om-watchdog/install
+ $(INSTALL_DIR) $(1)/etc/init.d/
+ $(INSTALL_DIR) $(1)/sbin/
+ $(INSTALL_BIN) ./files/om-watchdog.init $(1)/etc/init.d/om-watchdog
+ $(INSTALL_BIN) ./files/om-watchdog $(1)/sbin/om-watchdog
+endef
+
+
+$(eval $(call BuildPackage,om-watchdog))
+
diff --git a/package/kernel/om-watchdog/files/om-watchdog b/package/kernel/om-watchdog/files/om-watchdog
new file mode 100644
index 0000000000..d730c68447
--- /dev/null
+++ b/package/kernel/om-watchdog/files/om-watchdog
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+GPIO=$1
+
+trap "" INT HUP
+
+echo $GPIO > /sys/class/gpio/export
+echo out > /sys/class/gpio/gpio${GPIO}/direction
+
+while true; do
+ echo 1 > /sys/class/gpio/gpio${GPIO}/value
+ sleep 1
+ echo 0 > /sys/class/gpio/gpio${GPIO}/value
+ sleep 180
+done
diff --git a/package/kernel/om-watchdog/files/om-watchdog.init b/package/kernel/om-watchdog/files/om-watchdog.init
new file mode 100644
index 0000000000..0298bce046
--- /dev/null
+++ b/package/kernel/om-watchdog/files/om-watchdog.init
@@ -0,0 +1,30 @@
+#!/bin/sh /etc/rc.common
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+
+START=11
+
+SERVICE_DAEMONIZE=1
+
+boot() {
+ if [ -r /lib/ar71xx.sh ]; then
+ . /lib/ar71xx.sh
+ local board=$(ar71xx_board_name)
+
+ case "$board" in
+ "om2p"|"om2p-hs")
+ service_start /sbin/om-watchdog 12
+ ;;
+ "om2p-lc")
+ service_start /sbin/om-watchdog 26
+ ;;
+ "mr600v2")
+ service_start /sbin/om-watchdog 15
+ ;;
+ esac
+ else
+ #we assume it is om1p in this case
+ service_start /sbin/om-watchdog 3
+ fi
+}
diff --git a/package/kernel/rotary-gpio-custom/Makefile b/package/kernel/rotary-gpio-custom/Makefile
new file mode 100644
index 0000000000..315ec31f4b
--- /dev/null
+++ b/package/kernel/rotary-gpio-custom/Makefile
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2008-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=rotary-gpio-custom
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/rotary-gpio-custom
+ SUBMENU:=Other modules
+ TITLE:=Custom GPIO-based rotary encoder device
+ DEPENDS:=@GPIO_SUPPORT +kmod-input-gpio-encoder
+ FILES:=$(PKG_BUILD_DIR)/rotary-gpio-custom.ko
+ KCONFIG:=
+endef
+
+define KernelPackage/rotary-gpio-custom/description
+ Kernel module for register a custom rotary-gpio-encoder platform device.
+endef
+
+EXTRA_KCONFIG:= \
+ CONFIG_ROTARY_GPIO_CUSTOM=m
+
+EXTRA_CFLAGS:= \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \
+
+MAKE_OPTS:= \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
+ $(EXTRA_KCONFIG)
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ $(MAKE_OPTS) \
+ modules
+endef
+
+$(eval $(call KernelPackage,rotary-gpio-custom))
diff --git a/package/kernel/rotary-gpio-custom/src/Kconfig b/package/kernel/rotary-gpio-custom/src/Kconfig
new file mode 100644
index 0000000000..b4d55d5354
--- /dev/null
+++ b/package/kernel/rotary-gpio-custom/src/Kconfig
@@ -0,0 +1,9 @@
+config ROTARY_GPIO_CUSTOM
+ tristate "Custom GPIO-based rotary driver"
+ depends on GENERIC_GPIO
+ help
+ This is a driver to register 1 to 4 custom rotary encoder using
+ GPIO lines.
+
+ This support is also available as a module. If so, the module
+ will be called rotary-gpio-custom.
diff --git a/package/kernel/rotary-gpio-custom/src/Makefile b/package/kernel/rotary-gpio-custom/src/Makefile
new file mode 100644
index 0000000000..133672687b
--- /dev/null
+++ b/package/kernel/rotary-gpio-custom/src/Makefile
@@ -0,0 +1 @@
+obj-${CONFIG_ROTARY_GPIO_CUSTOM} += rotary-gpio-custom.o
diff --git a/package/kernel/rotary-gpio-custom/src/rotary-gpio-custom.c b/package/kernel/rotary-gpio-custom/src/rotary-gpio-custom.c
new file mode 100644
index 0000000000..8cd8ef12ab
--- /dev/null
+++ b/package/kernel/rotary-gpio-custom/src/rotary-gpio-custom.c
@@ -0,0 +1,188 @@
+/*
+ * Custom GPIO-based rotary driver
+ *
+ * Copyright (C) 2010 Claudio Mignanti <c.mignanti@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.
+ *
+ * Strongly based on Custom GPIO-based I2C driver by:
+ * Copyright (C) 2007-2008 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * The behaviour of this driver can be altered by setting some parameters
+ * from the insmod command line.
+ *
+ * The following parameters are adjustable:
+ *
+ * bus0 These four arguments can be arrays of
+ * bus1 1-8 unsigned integers as follows:
+ * bus2
+ * bus3 <id>,<steps>,<axis>,<gpioa>,<gpiob>,<inverted>
+ *
+ *
+ * If this driver is built into the kernel, you can use the following kernel
+ * command line parameters, with the same values as the corresponding module
+ * parameters listed above:
+ *
+ * rotary-gpio-custom.bus0
+ * rotary-gpio-custom.bus1
+ * rotary-gpio-custom.bus2
+ * rotary-gpio-custom.bus3
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/rotary_encoder.h>
+
+#define DRV_NAME "rotary-gpio-custom"
+#define DRV_DESC "Custom GPIO-based rotary driver"
+#define DRV_VERSION "0.1.0"
+
+#define PFX DRV_NAME ": "
+
+#define BUS_PARAM_REQUIRED 5
+#define BUS_PARAM_COUNT 6
+#define BUS_COUNT_MAX 4
+
+static unsigned int bus0[BUS_PARAM_COUNT] __initdata;
+static unsigned int bus1[BUS_PARAM_COUNT] __initdata;
+static unsigned int bus2[BUS_PARAM_COUNT] __initdata;
+static unsigned int bus3[BUS_PARAM_COUNT] __initdata;
+
+static unsigned int bus_nump[BUS_COUNT_MAX] __initdata;
+
+#define BUS_PARM_DESC \
+ " config -> id,steps,axis,gpioa,gpiob[,inverted]"
+
+module_param_array(bus0, uint, &bus_nump[0], 0);
+MODULE_PARM_DESC(bus0, "bus0" BUS_PARM_DESC);
+module_param_array(bus1, uint, &bus_nump[1], 0);
+MODULE_PARM_DESC(bus1, "bus1" BUS_PARM_DESC);
+module_param_array(bus2, uint, &bus_nump[2], 0);
+MODULE_PARM_DESC(bus2, "bus2" BUS_PARM_DESC);
+module_param_array(bus3, uint, &bus_nump[3], 0);
+MODULE_PARM_DESC(bus3, "bus3" BUS_PARM_DESC);
+
+static struct platform_device *devices[BUS_COUNT_MAX];
+static unsigned int nr_devices;
+
+static void rotary_gpio_custom_cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < nr_devices; i++)
+ if (devices[i])
+ platform_device_put(devices[i]);
+}
+
+static int __init rotary_gpio_custom_add_one(unsigned int id, unsigned int *params)
+{
+ struct platform_device *pdev;
+ struct rotary_encoder_platform_data pdata;
+ int err;
+
+ if (!bus_nump[id])
+ return 0;
+
+ if (bus_nump[id] < BUS_PARAM_REQUIRED) {
+ printk(KERN_ERR PFX "not enough parameters for bus%d\n", id);
+ err = -EINVAL;
+ goto err;
+ }
+
+ pdev = platform_device_alloc("rotary-gpio", params[0]);
+ if (!pdev) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ pdata.steps = params[1];
+ pdata.axis = params[2];
+ pdata.relative_axis = false;
+ pdata.rollover = false;
+ pdata.gpio_a = params[3];
+ pdata.gpio_b = params[4];
+
+ if (params[5] == 1) {
+ pdata.inverted_a = 1;
+ pdata.inverted_b = 1;
+ } else {
+ pdata.inverted_a = 0;
+ pdata.inverted_b = 0;
+ }
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto err_put;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_put;
+
+ devices[nr_devices++] = pdev;
+ return 0;
+
+err_put:
+ platform_device_put(pdev);
+err:
+ return err;
+}
+
+static int __init rotary_gpio_custom_probe(void)
+{
+ int err;
+
+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
+
+ err = rotary_gpio_custom_add_one(0, bus0);
+ if (err) goto err;
+
+ err = rotary_gpio_custom_add_one(1, bus1);
+ if (err) goto err;
+
+ err = rotary_gpio_custom_add_one(2, bus2);
+ if (err) goto err;
+
+ err = rotary_gpio_custom_add_one(3, bus3);
+ if (err) goto err;
+
+ if (!nr_devices) {
+ printk(KERN_ERR PFX "no bus parameter(s) specified\n");
+ err = -ENODEV;
+ goto err;
+ }
+
+ return 0;
+
+err:
+ rotary_gpio_custom_cleanup();
+ return err;
+}
+
+#ifdef MODULE
+static int __init rotary_gpio_custom_init(void)
+{
+ return rotary_gpio_custom_probe();
+}
+module_init(rotary_gpio_custom_init);
+
+static void __exit rotary_gpio_custom_exit(void)
+{
+ rotary_gpio_custom_cleanup();
+}
+module_exit(rotary_gpio_custom_exit);
+#else
+subsys_initcall(rotary_gpio_custom_probe);
+#endif /* MODULE*/
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org >");
+MODULE_AUTHOR("Claudio Mignanti <c.mignanti@gmail.com>");
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_VERSION(DRV_VERSION);
diff --git a/package/kernel/rtc-rv5c386a/Makefile b/package/kernel/rtc-rv5c386a/Makefile
new file mode 100644
index 0000000000..e13ead528a
--- /dev/null
+++ b/package/kernel/rtc-rv5c386a/Makefile
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2006-2009 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=rtc-rv5c386a
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/rtc-rv5c386a
+ SUBMENU:=Other modules
+ DEPENDS:=@TARGET_brcm47xx
+ TITLE:=Driver for RTC RV5C386A (used in WL-700gE and WL-HDD)
+ AUTOLOAD:=$(call AutoLoad,70,rtc)
+ FILES:=$(PKG_BUILD_DIR)/rtc.ko
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ ARCH="$(LINUX_KARCH)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="$(BUILDFLAGS)" \
+ modules
+endef
+
+$(eval $(call KernelPackage,rtc-rv5c386a))
diff --git a/package/kernel/rtc-rv5c386a/src/Makefile b/package/kernel/rtc-rv5c386a/src/Makefile
new file mode 100644
index 0000000000..eeb0430774
--- /dev/null
+++ b/package/kernel/rtc-rv5c386a/src/Makefile
@@ -0,0 +1,18 @@
+# $Id$
+#
+# Makefile for Real Time Clock driver for WL-HDD
+#
+# Copyright (C) 2007 Andreas Engel
+#
+# This program is free software; 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.
+#
+
+obj-m := rtc.o
+
+ifeq ($(MAKING_MODULES),1)
+
+-include $(TOPDIR)/Rules.make
+endif
diff --git a/package/kernel/rtc-rv5c386a/src/rtc.c b/package/kernel/rtc-rv5c386a/src/rtc.c
new file mode 100644
index 0000000000..2fc6f093cf
--- /dev/null
+++ b/package/kernel/rtc-rv5c386a/src/rtc.c
@@ -0,0 +1,613 @@
+/*
+ * Real Time Clock driver for WL-HDD
+ *
+ * Copyright (C) 2007 Andreas Engel
+ *
+ * Hacked together mostly by copying the relevant code parts from:
+ * drivers/i2c/i2c-bcm5365.c
+ * drivers/i2c/i2c-algo-bit.c
+ * drivers/char/rtc.c
+ *
+ * Note 1:
+ * This module uses the standard char device (10,135), while the Asus module
+ * rtcdrv.o uses (12,0). So, both can coexist which might be handy during
+ * development (but see the comment in rtc_open()).
+ *
+ * Note 2:
+ * You might need to set the clock once after loading the driver the first
+ * time because the driver switches the chip into 24h mode if it is running
+ * in 12h mode.
+ *
+ * Usage:
+ * For compatibility reasons with the original asus driver, the time can be
+ * read and set via the /dev/rtc device entry. The only accepted data format
+ * is "YYYY:MM:DD:W:HH:MM:SS\n". See OpenWrt wiki for a script which handles
+ * this format.
+ *
+ * In addition, this driver supports the standard ioctl() calls for setting
+ * and reading the hardware clock, so the ordinary hwclock utility can also
+ * be used.
+ *
+ * This program is free software; 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.
+ *
+ * TODO:
+ * - add a /proc/driver/rtc interface?
+ * - make the battery failure bit available through the /proc interface?
+ *
+ * $Id: rtc.c 7 2007-05-25 19:37:01Z ae $
+ */
+
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/mc146818rtc.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/rtc.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <linux/gpio.h>
+#include <linux/uaccess.h>
+
+#include <asm/current.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
+#include <asm/system.h>
+#endif
+
+#include <bcm47xx.h>
+#include <bcm47xx_nvram.h>
+
+#define RTC_IS_OPEN 0x01 /* Means /dev/rtc is in use. */
+
+/* Can be changed via a module parameter. */
+static int rtc_debug = 0;
+
+static unsigned long rtc_status = 0; /* Bitmapped status byte. */
+
+/* These settings are platform dependents. */
+unsigned int sda_index = 0;
+unsigned int scl_index = 0;
+
+#define I2C_READ_MASK 1
+#define I2C_WRITE_MASK 0
+
+#define I2C_ACK 1
+#define I2C_NAK 0
+
+#define RTC_EPOCH 1900
+#define RTC_I2C_ADDRESS (0x32 << 1)
+#define RTC_24HOUR_MODE_MASK 0x20
+#define RTC_PM_MASK 0x20
+#define RTC_VDET_MASK 0x40
+#define RTC_Y2K_MASK 0x80
+
+/*
+ * Delay in microseconds for generating the pulses on the I2C bus. We use
+ * a rather conservative setting here. See datasheet of the RTC chip.
+ */
+#define ADAP_DELAY 50
+
+/* Avoid spurious compiler warnings. */
+#define UNUSED __attribute__((unused))
+
+MODULE_AUTHOR("Andreas Engel");
+MODULE_LICENSE("GPL");
+
+/* Test stolen from switch-adm.c. */
+module_param(rtc_debug, int, 0);
+
+static inline void sdalo(void)
+{
+ gpio_direction_output(sda_index, 1);
+ udelay(ADAP_DELAY);
+}
+
+static inline void sdahi(void)
+{
+ gpio_direction_input(sda_index);
+ udelay(ADAP_DELAY);
+}
+
+static inline void scllo(void)
+{
+ gpio_direction_output(scl_index, 1);
+ udelay(ADAP_DELAY);
+}
+
+static inline int getscl(void)
+{
+ return (gpio_get_value(scl_index));
+}
+
+static inline int getsda(void)
+{
+ return (gpio_get_value(sda_index));
+}
+
+/*
+ * We shouldn't simply set the SCL pin to high. Like SDA, the SCL line is
+ * bidirectional too. According to the I2C spec, the slave is allowed to
+ * pull down the SCL line to slow down the clock, so we need to check this.
+ * Generally, we'd need a timeout here, but in our case, we just check the
+ * line, assuming the RTC chip behaves well.
+ */
+static int sclhi(void)
+{
+ gpio_direction_input(scl_index);
+ udelay(ADAP_DELAY);
+ if (!getscl()) {
+ printk(KERN_ERR "SCL pin should be low\n");
+ return -ETIMEDOUT;
+ }
+ return 0;
+}
+
+static void i2c_start(void)
+{
+ sdalo();
+ scllo();
+}
+
+static void i2c_stop(void)
+{
+ sdalo();
+ sclhi();
+ sdahi();
+}
+
+static int i2c_outb(int c)
+{
+ int i;
+ int ack;
+
+ /* assert: scl is low */
+ for (i = 7; i >= 0; i--) {
+ if (c & ( 1 << i )) {
+ sdahi();
+ } else {
+ sdalo();
+ }
+ if (sclhi() < 0) { /* timed out */
+ sdahi(); /* we don't want to block the net */
+ return -ETIMEDOUT;
+ };
+ scllo();
+ }
+ sdahi();
+ if (sclhi() < 0) {
+ return -ETIMEDOUT;
+ };
+ /* read ack: SDA should be pulled down by slave */
+ ack = getsda() == 0; /* ack: sda is pulled low ->success. */
+ scllo();
+
+ if (rtc_debug)
+ printk(KERN_DEBUG "i2c_outb(0x%02x) -> %s\n",
+ c, ack ? "ACK": "NAK");
+
+ return ack; /* return 1 if device acked */
+ /* assert: scl is low (sda undef) */
+}
+
+static int i2c_inb(int ack)
+{
+ int i;
+ unsigned int indata = 0;
+
+ /* assert: scl is low */
+
+ sdahi();
+ for (i = 0; i < 8; i++) {
+ if (sclhi() < 0) {
+ return -ETIMEDOUT;
+ };
+ indata *= 2;
+ if (getsda())
+ indata |= 0x01;
+ scllo();
+ }
+ if (ack) {
+ sdalo();
+ } else {
+ sdahi();
+ }
+
+ if (sclhi() < 0) {
+ sdahi();
+ return -ETIMEDOUT;
+ }
+ scllo();
+ sdahi();
+
+ if (rtc_debug)
+ printk(KERN_DEBUG "i2c_inb() -> 0x%02x\n", indata);
+
+ /* assert: scl is low */
+ return indata & 0xff;
+}
+
+static void i2c_init(void)
+{
+ /* no gpio_control for EXTIF */
+ // ssb_gpio_control(&ssb, sda_mask | scl_mask, 0);
+
+ gpio_set_value(sda_index, 0);
+ gpio_set_value(scl_index, 0);
+ sdahi();
+ sclhi();
+}
+
+static int rtc_open(UNUSED struct inode *inode, UNUSED struct file *filp)
+{
+ spin_lock_irq(&rtc_lock);
+
+ if (rtc_status & RTC_IS_OPEN) {
+ spin_unlock_irq(&rtc_lock);
+ return -EBUSY;
+ }
+
+ rtc_status |= RTC_IS_OPEN;
+
+ /*
+ * The following call is only necessary if we use both this driver and
+ * the proprietary one from asus at the same time (which, b.t.w. only
+ * makes sense during development). Otherwise, each access via the asus
+ * driver will make access via this driver impossible.
+ */
+ i2c_init();
+
+ spin_unlock_irq(&rtc_lock);
+
+ return 0;
+}
+
+static int rtc_release(UNUSED struct inode *inode, UNUSED struct file *filp)
+{
+ /* No need for locking here. */
+ rtc_status &= ~RTC_IS_OPEN;
+ return 0;
+}
+
+static int from_bcd(int bcdnum)
+{
+ int fac, num = 0;
+
+ for (fac = 1; bcdnum; fac *= 10) {
+ num += (bcdnum % 16) * fac;
+ bcdnum /= 16;
+ }
+
+ return num;
+}
+
+static int to_bcd(int decnum)
+{
+ int fac, num = 0;
+
+ for (fac = 1; decnum; fac *= 16) {
+ num += (decnum % 10) * fac;
+ decnum /= 10;
+ }
+
+ return num;
+}
+
+static void get_rtc_time(struct rtc_time *rtc_tm)
+{
+ int cr2;
+
+ /*
+ * Read date and time from the RTC. We use read method (3).
+ */
+
+ spin_lock_irq(&rtc_lock);
+ i2c_start();
+ i2c_outb(RTC_I2C_ADDRESS | I2C_READ_MASK);
+ cr2 = i2c_inb(I2C_ACK);
+ rtc_tm->tm_sec = i2c_inb(I2C_ACK);
+ rtc_tm->tm_min = i2c_inb(I2C_ACK);
+ rtc_tm->tm_hour = i2c_inb(I2C_ACK);
+ rtc_tm->tm_wday = i2c_inb(I2C_ACK);
+ rtc_tm->tm_mday = i2c_inb(I2C_ACK);
+ rtc_tm->tm_mon = i2c_inb(I2C_ACK);
+ rtc_tm->tm_year = i2c_inb(I2C_NAK);
+ i2c_stop();
+ spin_unlock_irq(&rtc_lock);
+
+ if (cr2 & RTC_VDET_MASK) {
+ printk(KERN_WARNING "***RTC BATTERY FAILURE***\n");
+ }
+
+ /* Handle century bit */
+ if (rtc_tm->tm_mon & RTC_Y2K_MASK) {
+ rtc_tm->tm_mon &= ~RTC_Y2K_MASK;
+ rtc_tm->tm_year += 0x100;
+ }
+
+ rtc_tm->tm_sec = from_bcd(rtc_tm->tm_sec);
+ rtc_tm->tm_min = from_bcd(rtc_tm->tm_min);
+ rtc_tm->tm_hour = from_bcd(rtc_tm->tm_hour);
+ rtc_tm->tm_mday = from_bcd(rtc_tm->tm_mday);
+ rtc_tm->tm_mon = from_bcd(rtc_tm->tm_mon) - 1;
+ rtc_tm->tm_year = from_bcd(rtc_tm->tm_year);
+
+ rtc_tm->tm_isdst = -1; /* DST not known */
+}
+
+static void set_rtc_time(struct rtc_time *rtc_tm)
+{
+ rtc_tm->tm_sec = to_bcd(rtc_tm->tm_sec);
+ rtc_tm->tm_min = to_bcd(rtc_tm->tm_min);
+ rtc_tm->tm_hour = to_bcd(rtc_tm->tm_hour);
+ rtc_tm->tm_mday = to_bcd(rtc_tm->tm_mday);
+ rtc_tm->tm_mon = to_bcd(rtc_tm->tm_mon + 1);
+ rtc_tm->tm_year = to_bcd(rtc_tm->tm_year);
+
+ if (rtc_tm->tm_year >= 0x100) {
+ rtc_tm->tm_year -= 0x100;
+ rtc_tm->tm_mon |= RTC_Y2K_MASK;
+ }
+
+ spin_lock_irq(&rtc_lock);
+ i2c_start();
+ i2c_outb(RTC_I2C_ADDRESS | I2C_WRITE_MASK);
+ i2c_outb(0x00); /* set starting register to 0 (=seconds) */
+ i2c_outb(rtc_tm->tm_sec);
+ i2c_outb(rtc_tm->tm_min);
+ i2c_outb(rtc_tm->tm_hour);
+ i2c_outb(rtc_tm->tm_wday);
+ i2c_outb(rtc_tm->tm_mday);
+ i2c_outb(rtc_tm->tm_mon);
+ i2c_outb(rtc_tm->tm_year);
+ i2c_stop();
+ spin_unlock_irq(&rtc_lock);
+}
+
+static ssize_t rtc_write(UNUSED struct file *filp, const char *buf,
+ size_t count, loff_t *ppos)
+{
+ struct rtc_time rtc_tm;
+ char buffer[23];
+ char *p;
+
+ if (!capable(CAP_SYS_TIME))
+ return -EACCES;
+
+ if (ppos != &filp->f_pos)
+ return -ESPIPE;
+
+ /*
+ * For simplicity, the only acceptable format is:
+ * YYYY:MM:DD:W:HH:MM:SS\n
+ */
+
+ if (count != 22)
+ goto err_out;
+
+ if (copy_from_user(buffer, buf, count))
+ return -EFAULT;
+
+ buffer[sizeof(buffer)-1] = '\0';
+
+ p = &buffer[0];
+
+ rtc_tm.tm_year = simple_strtoul(p, &p, 10);
+ if (*p++ != ':') goto err_out;
+
+ rtc_tm.tm_mon = simple_strtoul(p, &p, 10) - 1;
+ if (*p++ != ':') goto err_out;
+
+ rtc_tm.tm_mday = simple_strtoul(p, &p, 10);
+ if (*p++ != ':') goto err_out;
+
+ rtc_tm.tm_wday = simple_strtoul(p, &p, 10);
+ if (*p++ != ':') goto err_out;
+
+ rtc_tm.tm_hour = simple_strtoul(p, &p, 10);
+ if (*p++ != ':') goto err_out;
+
+ rtc_tm.tm_min = simple_strtoul(p, &p, 10);
+ if (*p++ != ':') goto err_out;
+
+ rtc_tm.tm_sec = simple_strtoul(p, &p, 10);
+ if (*p != '\n') goto err_out;
+
+ rtc_tm.tm_year -= RTC_EPOCH;
+
+ set_rtc_time(&rtc_tm);
+
+ *ppos += count;
+
+ return count;
+
+ err_out:
+ printk(KERN_ERR "invalid format: use YYYY:MM:DD:W:HH:MM:SS\\n\n");
+ return -EINVAL;
+}
+
+
+static ssize_t rtc_read(UNUSED struct file *filp, char *buf, size_t count,
+ loff_t *ppos)
+{
+ char wbuf[23];
+ struct rtc_time tm;
+ ssize_t len;
+
+ if (count == 0 || *ppos != 0)
+ return 0;
+
+ get_rtc_time(&tm);
+
+ len = sprintf(wbuf, "%04d:%02d:%02d:%d:%02d:%02d:%02d\n",
+ tm.tm_year + RTC_EPOCH,
+ tm.tm_mon + 1,
+ tm.tm_mday,
+ tm.tm_wday,
+ tm.tm_hour,
+ tm.tm_min,
+ tm.tm_sec);
+
+ if (len > (ssize_t)count)
+ len = count;
+
+ if (copy_to_user(buf, wbuf, len))
+ return -EFAULT;
+
+ *ppos += len;
+
+ return len;
+}
+
+static int rtc_do_ioctl(unsigned int cmd, unsigned long arg)
+{
+ struct rtc_time rtc_tm;
+
+ switch (cmd) {
+ case RTC_RD_TIME:
+ memset(&rtc_tm, 0, sizeof(struct rtc_time));
+ get_rtc_time(&rtc_tm);
+ if (copy_to_user((void *)arg, &rtc_tm, sizeof(rtc_tm)))
+ return -EFAULT;
+ break;
+
+ case RTC_SET_TIME:
+ if (!capable(CAP_SYS_TIME))
+ return -EACCES;
+
+ if (copy_from_user(&rtc_tm, (struct rtc_time *)arg,
+ sizeof(struct rtc_time)))
+ return -EFAULT;
+
+ set_rtc_time(&rtc_tm);
+ break;
+
+ default:
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ long ret;
+ ret = rtc_do_ioctl(cmd, arg);
+ return ret;
+}
+
+static const struct file_operations rtc_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .read = rtc_read,
+ .write = rtc_write,
+ .unlocked_ioctl = rtc_ioctl,
+ .open = rtc_open,
+ .release = rtc_release,
+};
+
+static struct miscdevice rtc_dev = {
+ .minor = RTC_MINOR,
+ .name = "rtc",
+ .fops = &rtc_fops,
+};
+
+/* Savagely ripped from diag.c. */
+static inline int startswith (char *source, char *cmp)
+{
+ return !strncmp(source, cmp, strlen(cmp));
+}
+
+static void platform_detect(void)
+{
+ char buf[20];
+ int et0phyaddr, et1phyaddr;
+
+ /* Based on "model_no". */
+ if (bcm47xx_nvram_getenv("model_no", buf, sizeof(buf)) >= 0) {
+ if (startswith(buf, "WL700")) { /* WL700* */
+ sda_index = 2;
+ scl_index = 5;
+ return;
+ }
+ }
+
+ if (bcm47xx_nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 )
+ et0phyaddr = simple_strtoul(buf, NULL, 0);
+ if (bcm47xx_nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 )
+ et1phyaddr = simple_strtoul(buf, NULL, 0);
+
+ if (bcm47xx_nvram_getenv("hardware_version", buf, sizeof(buf)) >= 0) {
+ /* Either WL-300g or WL-HDD, do more extensive checks */
+ if (startswith(buf, "WL300-") && et0phyaddr == 0 && et1phyaddr == 1) {
+ sda_index = 4;
+ scl_index = 5;
+ return;
+ }
+ }
+ /* not found */
+}
+
+static int __init rtc_init(void)
+{
+ int cr1;
+
+ platform_detect();
+
+ if (sda_index == scl_index) {
+ printk(KERN_ERR "RTC-RV5C386A: unrecognized platform!\n");
+ return -ENODEV;
+ }
+
+ i2c_init();
+
+ /*
+ * Switch RTC to 24h mode
+ */
+ spin_lock_irq(&rtc_lock);
+ i2c_start();
+ i2c_outb(RTC_I2C_ADDRESS | I2C_WRITE_MASK);
+ i2c_outb(0xE4); /* start at address 0xE, transmission mode 4 */
+ cr1 = i2c_inb(I2C_NAK);
+ i2c_stop();
+ spin_unlock_irq(&rtc_lock);
+ if ((cr1 & RTC_24HOUR_MODE_MASK) == 0) {
+ /* RTC is running in 12h mode */
+ printk(KERN_INFO "rtc.o: switching to 24h mode\n");
+ spin_lock_irq(&rtc_lock);
+ i2c_start();
+ i2c_outb(RTC_I2C_ADDRESS | I2C_WRITE_MASK);
+ i2c_outb(0xE0);
+ i2c_outb(cr1 | RTC_24HOUR_MODE_MASK);
+ i2c_stop();
+ spin_unlock_irq(&rtc_lock);
+ }
+
+ misc_register(&rtc_dev);
+
+ printk(KERN_INFO "RV5C386A Real Time Clock Driver loaded\n");
+
+ return 0;
+}
+
+static void __exit rtc_exit (void)
+{
+ misc_deregister(&rtc_dev);
+ printk(KERN_INFO "Successfully removed RTC RV5C386A driver\n");
+}
+
+module_init(rtc_init);
+module_exit(rtc_exit);
+
+/*
+ * Local Variables:
+ * indent-tabs-mode:t
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/package/kernel/spi-ks8995/Makefile b/package/kernel/spi-ks8995/Makefile
new file mode 100644
index 0000000000..0be9fe3dc6
--- /dev/null
+++ b/package/kernel/spi-ks8995/Makefile
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=spi-ks8995
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/spi-ks8995
+ SUBMENU:=SPI Support
+ TITLE:=Micrel/Kendin KS8995 Ethernet switch control
+ FILES:=$(PKG_BUILD_DIR)/spi_ks8995.ko
+ KCONFIG:=CONFIG_SPI=y \
+ CONFIG_SPI_MASTER=y
+ AUTOLOAD:=$(call AutoLoad,50,spi_ks8995)
+endef
+
+define KernelPackage/spi-ks8995/description
+ Kernel module for Micrel/Kendin KS8995 ethernet switch
+endef
+
+EXTRA_KCONFIG:= \
+ CONFIG_SPI_KS8995=m
+
+EXTRA_CFLAGS:= \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \
+
+MAKE_OPTS:= \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
+ $(EXTRA_KCONFIG)
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ $(MAKE_OPTS) \
+ modules
+endef
+
+$(eval $(call KernelPackage,spi-ks8995))
diff --git a/package/kernel/spi-ks8995/src/Kconfig b/package/kernel/spi-ks8995/src/Kconfig
new file mode 100644
index 0000000000..7859be183d
--- /dev/null
+++ b/package/kernel/spi-ks8995/src/Kconfig
@@ -0,0 +1,3 @@
+config SPI_KS8995
+ tristate "Micrel/Kendin KS8995 Ethernet switch"
+ depends on SPI
diff --git a/package/kernel/spi-ks8995/src/Makefile b/package/kernel/spi-ks8995/src/Makefile
new file mode 100644
index 0000000000..810c3bd1db
--- /dev/null
+++ b/package/kernel/spi-ks8995/src/Makefile
@@ -0,0 +1 @@
+obj-${CONFIG_SPI_KS8995} += spi_ks8995.o \ No newline at end of file
diff --git a/package/kernel/spi-ks8995/src/spi_ks8995.c b/package/kernel/spi-ks8995/src/spi_ks8995.c
new file mode 100644
index 0000000000..dc42b5d318
--- /dev/null
+++ b/package/kernel/spi-ks8995/src/spi_ks8995.c
@@ -0,0 +1,419 @@
+/*
+ * SPI driver for Micrel/Kendin KS8995M ethernet switch
+ *
+ * Copyright (C) 2008 Gabor Juhos <juhosg at openwrt.org>
+ *
+ * This file was based on: drivers/spi/at25.c
+ * Copyright (C) 2006 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+
+#include <linux/spi/spi.h>
+
+#define DRV_VERSION "0.1.1"
+#define DRV_DESC "Micrel/Kendin KS8995 Ethernet switch SPI driver"
+
+/*-------------------------------------------------------------------------*/
+
+#define KS8995_REG_ID0 0x00 /* Chip ID0 */
+#define KS8995_REG_ID1 0x01 /* Chip ID1 */
+
+#define KS8995_REG_GC0 0x02 /* Global Control 0 */
+#define KS8995_REG_GC1 0x03 /* Global Control 1 */
+#define KS8995_REG_GC2 0x04 /* Global Control 2 */
+#define KS8995_REG_GC3 0x05 /* Global Control 3 */
+#define KS8995_REG_GC4 0x06 /* Global Control 4 */
+#define KS8995_REG_GC5 0x07 /* Global Control 5 */
+#define KS8995_REG_GC6 0x08 /* Global Control 6 */
+#define KS8995_REG_GC7 0x09 /* Global Control 7 */
+#define KS8995_REG_GC8 0x0a /* Global Control 8 */
+#define KS8995_REG_GC9 0x0b /* Global Control 9 */
+
+#define KS8995_REG_PC(p,r) ((0x10 * p) + r) /* Port Control */
+#define KS8995_REG_PS(p,r) ((0x10 * p) + r + 0xe) /* Port Status */
+
+#define KS8995_REG_TPC0 0x60 /* TOS Priority Control 0 */
+#define KS8995_REG_TPC1 0x61 /* TOS Priority Control 1 */
+#define KS8995_REG_TPC2 0x62 /* TOS Priority Control 2 */
+#define KS8995_REG_TPC3 0x63 /* TOS Priority Control 3 */
+#define KS8995_REG_TPC4 0x64 /* TOS Priority Control 4 */
+#define KS8995_REG_TPC5 0x65 /* TOS Priority Control 5 */
+#define KS8995_REG_TPC6 0x66 /* TOS Priority Control 6 */
+#define KS8995_REG_TPC7 0x67 /* TOS Priority Control 7 */
+
+#define KS8995_REG_MAC0 0x68 /* MAC address 0 */
+#define KS8995_REG_MAC1 0x69 /* MAC address 1 */
+#define KS8995_REG_MAC2 0x6a /* MAC address 2 */
+#define KS8995_REG_MAC3 0x6b /* MAC address 3 */
+#define KS8995_REG_MAC4 0x6c /* MAC address 4 */
+#define KS8995_REG_MAC5 0x6d /* MAC address 5 */
+
+#define KS8995_REG_IAC0 0x6e /* Indirect Access Control 0 */
+#define KS8995_REG_IAC1 0x6f /* Indirect Access Control 0 */
+
+#define KS8995_REG_IAD7 0x70 /* Indirect Access Data 7 */
+#define KS8995_REG_IAD6 0x71 /* Indirect Access Data 6 */
+#define KS8995_REG_IAD5 0x72 /* Indirect Access Data 5 */
+#define KS8995_REG_IAD4 0x73 /* Indirect Access Data 4 */
+#define KS8995_REG_IAD3 0x74 /* Indirect Access Data 3 */
+#define KS8995_REG_IAD2 0x75 /* Indirect Access Data 2 */
+#define KS8995_REG_IAD1 0x76 /* Indirect Access Data 1 */
+#define KS8995_REG_IAD0 0x77 /* Indirect Access Data 0 */
+
+#define KS8995_REGS_SIZE 0x80
+
+#define ID1_CHIPID_M 0xf
+#define ID1_CHIPID_S 4
+#define ID1_REVISION_M 0x7
+#define ID1_REVISION_S 1
+#define ID1_START_SW 1 /* start the switch */
+
+#define FAMILY_KS8995 0x95
+#define CHIPID_M 0
+
+#define KS8995_CMD_WRITE 0x02U
+#define KS8995_CMD_READ 0x03U
+
+#define KS8995_RESET_DELAY 10 /* usec */
+
+/*-------------------------------------------------------------------------*/
+
+struct ks8995_pdata {
+ /* not yet implemented */
+};
+
+struct ks8995_switch {
+ struct spi_device *spi;
+ struct mutex lock;
+ struct ks8995_pdata *pdata;
+};
+
+/*-------------------------------------------------------------------------*/
+
+static inline u8 get_chip_id(u8 val)
+{
+ return ((val >> ID1_CHIPID_S) & ID1_CHIPID_M);
+}
+
+static inline u8 get_chip_rev(u8 val)
+{
+ return ((val >> ID1_REVISION_S) & ID1_REVISION_M);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int ks8995_read(struct ks8995_switch *ks, char *buf,
+ unsigned offset, size_t count)
+{
+ u8 cmd[2];
+ struct spi_transfer t[2];
+ struct spi_message m;
+ int err;
+
+ spi_message_init(&m);
+
+ memset(&t, 0, sizeof(t));
+
+ t[0].tx_buf = cmd;
+ t[0].len = sizeof(cmd);
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].rx_buf = buf;
+ t[1].len = count;
+ spi_message_add_tail(&t[1], &m);
+
+ cmd[0] = KS8995_CMD_READ;
+ cmd[1] = offset;
+
+ mutex_lock(&ks->lock);
+ err = spi_sync(ks->spi, &m);
+ mutex_unlock(&ks->lock);
+
+ return err ? err : count;
+}
+
+
+static int ks8995_write(struct ks8995_switch *ks, char *buf,
+ unsigned offset, size_t count)
+{
+ u8 cmd[2];
+ struct spi_transfer t[2];
+ struct spi_message m;
+ int err;
+
+ spi_message_init(&m);
+
+ memset(&t, 0, sizeof(t));
+
+ t[0].tx_buf = cmd;
+ t[0].len = sizeof(cmd);
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].tx_buf = buf;
+ t[1].len = count;
+ spi_message_add_tail(&t[1], &m);
+
+ cmd[0] = KS8995_CMD_WRITE;
+ cmd[1] = offset;
+
+ mutex_lock(&ks->lock);
+ err = spi_sync(ks->spi, &m);
+ mutex_unlock(&ks->lock);
+
+ return err ? err : count;
+}
+
+static inline int ks8995_read_reg(struct ks8995_switch *ks, u8 addr, u8 *buf)
+{
+ return (ks8995_read(ks, buf, addr, 1) != 1);
+}
+
+static inline int ks8995_write_reg(struct ks8995_switch *ks, u8 addr, u8 val)
+{
+ char buf = val;
+
+ return (ks8995_write(ks, &buf, addr, 1) != 1);
+}
+
+/*-------------------------------------------------------------------------*/
+
+#if 0
+static int ks8995_setup(struct spi_device *spi)
+{
+ struct ks8995_switch *ks;
+ u8 t;
+
+ ks = dev_get_drvdata(&spi->dev);
+
+ ks8995_write_reg(ks, KS8995_REG_GC0, 0x4c);
+ ks8995_write_reg(ks, KS8995_REG_GC1, 0x05);
+
+ ks8995_read_reg(ks, KS8995_REG_GC2, &t);
+ ks8995_write_reg(ks, KS8995_REG_GC2, t | 1);
+
+ ks8995_write_reg(ks, KS8995_REG_GC4, 0x20);
+
+ ks8995_write_reg(ks, KS8995_REG_PC(1,0), 0x61);
+ ks8995_write_reg(ks, KS8995_REG_PC(2,0), 0x61);
+ ks8995_write_reg(ks, KS8995_REG_PC(3,0), 0x61);
+ ks8995_write_reg(ks, KS8995_REG_PC(4,0), 0x61);
+ ks8995_write_reg(ks, KS8995_REG_PC(5,0), 0x61);
+
+ ks8995_write_reg(ks, KS8995_REG_PC(5,11), 0x18);
+
+ ks8995_write_reg(ks, KS8995_REG_TPC0, 0xff);
+ ks8995_write_reg(ks, KS8995_REG_TPC1, 0xff);
+ ks8995_write_reg(ks, KS8995_REG_TPC2, 0xff);
+ ks8995_write_reg(ks, KS8995_REG_TPC3, 0xff);
+ ks8995_write_reg(ks, KS8995_REG_TPC4, 0xff);
+ ks8995_write_reg(ks, KS8995_REG_TPC5, 0xff);
+ ks8995_write_reg(ks, KS8995_REG_TPC6, 0xff);
+ ks8995_write_reg(ks, KS8995_REG_TPC7, 0xfe);
+
+ return 0;
+}
+#endif
+
+static int ks8995_stop(struct ks8995_switch *ks)
+{
+ return ks8995_write_reg(ks, KS8995_REG_ID1, 0);
+}
+
+static int ks8995_start(struct ks8995_switch *ks)
+{
+ return ks8995_write_reg(ks, KS8995_REG_ID1, 1);
+}
+
+static int ks8995_reset(struct ks8995_switch *ks)
+{
+ int err;
+
+ err = ks8995_stop(ks);
+ if (err)
+ return err;
+
+ udelay(KS8995_RESET_DELAY);
+
+ return ks8995_start(ks);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int ks8995_registers_read(struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
+{
+ struct device *dev;
+ struct ks8995_switch *ks8995;
+
+ dev = container_of(kobj, struct device, kobj);
+ ks8995 = dev_get_drvdata(dev);
+
+ if (unlikely(off > KS8995_REGS_SIZE))
+ return 0;
+
+ if ((off + count) > KS8995_REGS_SIZE)
+ count = KS8995_REGS_SIZE - off;
+
+ if (unlikely(!count))
+ return count;
+
+ return ks8995_read(ks8995, buf, off, count);
+}
+
+
+static int ks8995_registers_write(struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
+{
+ struct device *dev;
+ struct ks8995_switch *ks8995;
+
+ dev = container_of(kobj, struct device, kobj);
+ ks8995 = dev_get_drvdata(dev);
+
+ if (unlikely(off >= KS8995_REGS_SIZE))
+ return -EFBIG;
+
+ if ((off + count) > KS8995_REGS_SIZE)
+ count = KS8995_REGS_SIZE - off;
+
+ if (unlikely(!count))
+ return count;
+
+ return ks8995_write(ks8995, buf, off, count);
+}
+
+
+static struct bin_attribute ks8995_registers_attr = {
+ .attr = {
+ .name = "registers",
+ .mode = S_IRUSR | S_IWUSR,
+ },
+ .size = KS8995_REGS_SIZE,
+ .read = ks8995_registers_read,
+ .write = ks8995_registers_write,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int ks8995_probe(struct spi_device *spi)
+{
+ struct ks8995_switch *ks;
+ struct ks8995_pdata *pdata;
+ u8 ids[2];
+ int err;
+
+ /* Chip description */
+ pdata = spi->dev.platform_data;
+
+ ks = kzalloc(sizeof(*ks), GFP_KERNEL);
+ if (!ks) {
+ dev_err(&spi->dev, "no memory for private data\n");
+ return-ENOMEM;
+ }
+
+ mutex_init(&ks->lock);
+ ks->pdata = pdata;
+ ks->spi = spi_dev_get(spi);
+ dev_set_drvdata(&spi->dev, ks);
+
+ spi->mode = SPI_MODE_0;
+ spi->bits_per_word = 8;
+ err = spi_setup(spi);
+ if (err) {
+ dev_err(&spi->dev, "spi_setup failed, err=%d \n", err);
+ goto err_drvdata;
+ }
+
+ err = ks8995_read(ks, ids, KS8995_REG_ID0, sizeof(ids));
+ if (err < 0) {
+ dev_err(&spi->dev, "unable to read id registers, err=%d \n",
+ err);
+ goto err_drvdata;
+ }
+
+ switch (ids[0]) {
+ case FAMILY_KS8995:
+ break;
+ default:
+ dev_err(&spi->dev, "unknown family id:%02x\n", ids[0]);
+ err = -ENODEV;
+ goto err_drvdata;
+ }
+
+ err = ks8995_reset(ks);
+ if (err)
+ goto err_drvdata;
+
+ err = sysfs_create_bin_file(&spi->dev.kobj, &ks8995_registers_attr);
+ if (err) {
+ dev_err(&spi->dev, "unable to create sysfs file, err=%d\n",
+ err);
+ goto err_drvdata;
+ }
+
+ dev_info(&spi->dev, "KS89%02X device found, Chip ID:%01x, "
+ "Revision:%01x\n", ids[0],
+ get_chip_id(ids[1]), get_chip_rev(ids[1]));
+
+ return 0;
+
+err_drvdata:
+ dev_set_drvdata(&spi->dev, NULL);
+ kfree(ks);
+ return err;
+}
+
+static int ks8995_remove(struct spi_device *spi)
+{
+ struct ks8995_data *ks8995;
+
+ ks8995 = dev_get_drvdata(&spi->dev);
+ sysfs_remove_bin_file(&spi->dev.kobj, &ks8995_registers_attr);
+
+ dev_set_drvdata(&spi->dev, NULL);
+ kfree(ks8995);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct spi_driver ks8995_driver = {
+ .driver = {
+ .name = "spi-ks8995",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = ks8995_probe,
+ .remove = ks8995_remove,
+};
+
+static int __init ks8995_init(void)
+{
+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n");
+
+ return spi_register_driver(&ks8995_driver);
+}
+module_init(ks8995_init);
+
+static void __exit ks8995_exit(void)
+{
+ spi_unregister_driver(&ks8995_driver);
+}
+module_exit(ks8995_exit);
+
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/package/kernel/switch/Makefile b/package/kernel/switch/Makefile
new file mode 100644
index 0000000000..fd1504e156
--- /dev/null
+++ b/package/kernel/switch/Makefile
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=kmod-switch
+PKG_RELEASE:=6
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/switch
+ SUBMENU:=Other modules
+ DEPENDS:=@TARGET_brcm47xx
+ TITLE:=Switch drivers
+ FILES:= \
+ $(PKG_BUILD_DIR)/switch-core.ko \
+ $(PKG_BUILD_DIR)/switch-adm.ko \
+ $(PKG_BUILD_DIR)/switch-robo.ko
+ AUTOLOAD:=$(call AutoLoad,20,switch-core switch-robo switch-adm,1)
+endef
+
+define KernelPackage/switch/description
+ This package contains switch drivers for ADM6996L and BCM53XX RoboSwitch.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ ARCH="$(LINUX_KARCH)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="$(BUILDFLAGS)" \
+ modules
+endef
+
+define Build/InstallDev
+ mkdir -p $(1)/usr/include
+ $(CP) ./src/switch-core.h $(1)/usr/include/
+endef
+
+define Build/UninstallDev
+ rm -f $(1)/usr/include/switch-core.h
+endef
+
+define KernelPackage/switch/install
+ $(INSTALL_DIR) $(1)/lib/network/
+ $(INSTALL_BIN) ./files/switch.sh $(1)/lib/network/
+endef
+
+$(eval $(call KernelPackage,switch))
diff --git a/package/kernel/switch/files/switch.sh b/package/kernel/switch/files/switch.sh
new file mode 100644
index 0000000000..2563d410e5
--- /dev/null
+++ b/package/kernel/switch/files/switch.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+# Copyright (C) 2006-2010 OpenWrt.org
+
+setup_switch_hw() {
+ local dev="$1"
+ local enable reset evlan
+
+ config_get_bool enable "$dev" enable 1
+ config_get_bool evlan "$dev" enable_vlan 1
+ config_get_bool reset "$dev" reset 1
+
+ local proc="/proc/switch/$dev"
+ [ -d "$proc" ] && {
+ ifconfig "$dev" up
+ echo "$reset" > "$proc/reset"
+ echo "$evlan" > "$proc/enable_vlan"
+ [ -f "$proc/enable" ] && echo "$enable" > "$proc/enable"
+ }
+
+ local vlan
+ for vlan in `seq 0 15`; do
+ proc="/proc/switch/$dev/vlan/$vlan/ports"
+ [ -f "$proc" ] && echo "" > "$proc"
+ done
+}
+
+setup_switch_vlan() {
+ local s="$1"
+ local dev vlan ports
+
+ config_get dev "$s" device
+ config_get vlan "$s" vlan
+ config_get ports "$s" ports
+
+ [ -n "$dev" ] && [ -n "$vlan" ] && {
+ ports="${ports%\*}"
+
+ [ "$_vlan_pvid_set" = 1 ] || {
+ ports="$ports*"
+ _vlan_pvid_set=1
+ }
+
+ local proc="/proc/switch/$dev/vlan/$vlan/ports"
+ [ -f "$proc" ] && echo "$ports" > "$proc"
+ }
+}
+
+setup_switch() {
+ _vlan_pvid_set=0
+ config_load network
+ config_foreach setup_switch_hw switch
+ config_foreach setup_switch_vlan switch_vlan
+}
diff --git a/package/kernel/switch/src/Makefile b/package/kernel/switch/src/Makefile
new file mode 100644
index 0000000000..b6934cc66b
--- /dev/null
+++ b/package/kernel/switch/src/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for switch driver
+#
+# Copyright (C) 2005 Felix Fietkau <nbd@openwrt.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.
+#
+
+obj-m := switch-core.o switch-adm.o switch-robo.o
+
+ifeq ($(MAKING_MODULES),1)
+export-objs := switch-core.o
+
+-include $(TOPDIR)/Rules.make
+endif
diff --git a/package/kernel/switch/src/etc53xx.h b/package/kernel/switch/src/etc53xx.h
new file mode 100644
index 0000000000..0cd217e512
--- /dev/null
+++ b/package/kernel/switch/src/etc53xx.h
@@ -0,0 +1,624 @@
+/*
+ * Broadcom Home Gateway Reference Design
+ * BCM53xx Register definitions
+ *
+ * Copyright 2004, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ */
+
+#ifndef __BCM535M_H_
+#define __BCM535M_H_
+
+/* ROBO embedded device type */
+#define ROBO_DEV_5380 1
+#define ROBO_DEV_5365 2
+#define ROBO_DEV_5350 3
+#define ROBO_DEV_53115 4
+
+/* BCM5325m GLOBAL PAGE REGISTER MAP */
+#ifndef _CFE_
+#pragma pack(1)
+#endif
+
+/* BCM5325m Serial Management Port (SMP) Page offsets */
+#define ROBO_CTRL_PAGE 0x00 /* Control registers */
+#define ROBO_STAT_PAGE 0x01 /* Status register */
+#define ROBO_MGMT_PAGE 0x02 /* Management Mode registers */
+#define ROBO_MIB_AC_PAGE 0x03 /* MIB Autocast registers */
+#define ROBO_ARLCTRL_PAGE 0x04 /* ARL Control Registers */
+#define ROBO_ARLIO_PAGE 0x05 /* ARL Access Registers */
+#define ROBO_FRAMEBUF_PAGE 0x06 /* Management frame access registers */
+#define ROBO_MEM_ACCESS_PAGE 0x08 /* Memory access registers */
+
+/* PHY Registers */
+#define ROBO_PORT0_MII_PAGE 0x10 /* Port 0 MII Registers */
+#define ROBO_PORT1_MII_PAGE 0x11 /* Port 1 MII Registers */
+#define ROBO_PORT2_MII_PAGE 0x12 /* Port 2 MII Registers */
+#define ROBO_PORT3_MII_PAGE 0x13 /* Port 3 MII Registers */
+#define ROBO_PORT4_MII_PAGE 0x14 /* Port 4 MII Registers */
+/* (start) registers only for BCM5380 */
+#define ROBO_PORT5_MII_PAGE 0x15 /* Port 5 MII Registers */
+#define ROBO_PORT6_MII_PAGE 0x16 /* Port 6 MII Registers */
+#define ROBO_PORT7_MII_PAGE 0x17 /* Port 7 MII Registers */
+/* (end) registers only for BCM5380 */
+#define ROBO_IM_PORT_PAGE 0x18 /* Inverse MII Port (to EMAC) */
+#define ROBO_ALL_PORT_PAGE 0x19 /* All ports MII Registers (broadcast)*/
+
+/* MAC Statistics registers */
+#define ROBO_PORT0_MIB_PAGE 0x20 /* Port 0 10/100 MIB Statistics */
+#define ROBO_PORT1_MIB_PAGE 0x21 /* Port 1 10/100 MIB Statistics */
+#define ROBO_PORT2_MIB_PAGE 0x22 /* Port 2 10/100 MIB Statistics */
+#define ROBO_PORT3_MIB_PAGE 0x23 /* Port 3 10/100 MIB Statistics */
+#define ROBO_PORT4_MIB_PAGE 0x24 /* Port 4 10/100 MIB Statistics */
+/* (start) registers only for BCM5380 */
+#define ROBO_PORT5_MIB_PAGE 0x25 /* Port 5 10/100 MIB Statistics */
+#define ROBO_PORT6_MIB_PAGE 0x26 /* Port 6 10/100 MIB Statistics */
+#define ROBO_PORT7_MIB_PAGE 0x27 /* Port 7 10/100 MIB Statistics */
+/* (end) registers only for BCM5380 */
+#define ROBO_IM_PORT_MIB_PAGE 0x28 /* Inverse MII Port MIB Statistics */
+
+/* Quality of Service (QoS) Registers */
+#define ROBO_QOS_PAGE 0x30 /* QoS Registers */
+
+/* VLAN Registers */
+#define ROBO_VLAN_PAGE 0x34 /* VLAN Registers */
+
+/* Note SPI Data/IO Registers not used */
+#define ROBO_SPI_DATA_IO_0_PAGE 0xf0 /* SPI Data I/O 0 */
+#define ROBO_SPI_DATA_IO_1_PAGE 0xf1 /* SPI Data I/O 1 */
+#define ROBO_SPI_DATA_IO_2_PAGE 0xf2 /* SPI Data I/O 2 */
+#define ROBO_SPI_DATA_IO_3_PAGE 0xf3 /* SPI Data I/O 3 */
+#define ROBO_SPI_DATA_IO_4_PAGE 0xf4 /* SPI Data I/O 4 */
+#define ROBO_SPI_DATA_IO_5_PAGE 0xf5 /* SPI Data I/O 5 */
+#define ROBO_SPI_DATA_IO_6_PAGE 0xf6 /* SPI Data I/O 6 */
+#define ROBO_SPI_DATA_IO_7_PAGE 0xf7 /* SPI Data I/O 7 */
+
+#define ROBO_SPI_STATUS_PAGE 0xfe /* SPI Status Registers */
+#define ROBO_PAGE_PAGE 0xff /* Page Registers */
+
+
+/* BCM5325m CONTROL PAGE (0x00) REGISTER MAP : 8bit (byte) registers */
+typedef struct _ROBO_PORT_CTRL_STRUC
+{
+ unsigned char rx_disable:1; /* rx disable */
+ unsigned char tx_disable:1; /* tx disable */
+ unsigned char rsvd:3; /* reserved */
+ unsigned char stp_state:3; /* spanning tree state */
+} ROBO_PORT_CTRL_STRUC;
+
+#define ROBO_PORT0_CTRL 0x00 /* 10/100 Port 0 Control */
+#define ROBO_PORT1_CTRL 0x01 /* 10/100 Port 1 Control */
+#define ROBO_PORT2_CTRL 0x02 /* 10/100 Port 2 Control */
+#define ROBO_PORT3_CTRL 0x03 /* 10/100 Port 3 Control */
+#define ROBO_PORT4_CTRL 0x04 /* 10/100 Port 4 Control */
+/* (start) registers only for BCM5380 */
+#define ROBO_PORT5_CTRL 0x05 /* 10/100 Port 5 Control */
+#define ROBO_PORT6_CTRL 0x06 /* 10/100 Port 6 Control */
+#define ROBO_PORT7_CTRL 0x07 /* 10/100 Port 7 Control */
+/* (end) registers only for BCM5380 */
+#define ROBO_IM_PORT_CTRL 0x08 /* 10/100 Port 8 Control */
+#define ROBO_SMP_CTRL 0x0a /* SMP Control register */
+#define ROBO_SWITCH_MODE 0x0b /* Switch Mode Control */
+#define ROBO_PORT_OVERRIDE_CTRL 0x0e /* Port state override */
+#define ROBO_PORT_OVERRIDE_RVMII (1<<4) /* Bit 4 enables RvMII */
+#define ROBO_PD_MODE_CTRL 0x0f /* Power-down mode control */
+#define ROBO_IP_MULTICAST_CTRL 0x21 /* IP Multicast control */
+
+/* BCM5325m STATUS PAGE (0x01) REGISTER MAP : 16bit/48bit registers */
+#define ROBO_HALF_DUPLEX 0
+#define ROBO_FULL_DUPLEX 1
+
+#define ROBO_LINK_STAT_SUMMARY 0x00 /* Link Status Summary: 16bit */
+#define ROBO_LINK_STAT_CHANGE 0x02 /* Link Status Change: 16bit */
+#define ROBO_SPEED_STAT_SUMMARY 0x04 /* Port Speed Summary: 16bit*/
+#define ROBO_DUPLEX_STAT_SUMMARY 0x06 /* Duplex Status Summary: 16bit */
+#define ROBO_PAUSE_STAT_SUMMARY 0x08 /* PAUSE Status Summary: 16bit */
+#define ROBO_SOURCE_ADDR_CHANGE 0x0C /* Source Address Change: 16bit */
+#define ROBO_LSA_PORT0 0x10 /* Last Source Addr, Port 0: 48bits*/
+#define ROBO_LSA_PORT1 0x16 /* Last Source Addr, Port 1: 48bits*/
+#define ROBO_LSA_PORT2 0x1c /* Last Source Addr, Port 2: 48bits*/
+#define ROBO_LSA_PORT3 0x22 /* Last Source Addr, Port 3: 48bits*/
+#define ROBO_LSA_PORT4 0x28 /* Last Source Addr, Port 4: 48bits*/
+#define ROBO_LSA_IM_PORT 0x40 /* Last Source Addr, IM Port: 48bits*/
+
+/* BCM5325m MANAGEMENT MODE REGISTERS (0x02) REGISTER MAP: 8/48 bit regs*/
+typedef struct _ROBO_GLOBAL_CONFIG_STRUC
+{
+ unsigned char resetMIB:1; /* reset MIB counters */
+ unsigned char rxBPDU:1; /* receive BDPU enable */
+ unsigned char rsvd1:2; /* reserved */
+ unsigned char MIBacHdrCtrl:1; /* MIB autocast header control */
+ unsigned char MIBac:1; /* MIB autocast enable */
+ unsigned char frameMgmtPort:2; /* frame management port */
+} ROBO_GLOBAL_CONFIG_STRUC;
+#define ROBO_GLOBAL_CONFIG 0x00 /* Global Management Config: 8bit*/
+#define ROBO_MGMT_PORT_ID 0x02 /* Management Port ID: 8bit*/
+#define ROBO_RMON_MIB_STEER 0x04 /* RMON Mib Steering: 16bit */
+#define ROBO_MIB_MODE_SELECT 0x04 /* MIB Mode select: 16bit (BCM5350) */
+#define ROBO_AGE_TIMER_CTRL 0x06 /* Age time control: 32bit */
+#define ROBO_MIRROR_CAP_CTRL 0x10 /* Mirror Capture : 16bit */
+#define ROBO_MIRROR_ING_CTRL 0x12 /* Mirror Ingress Control: 16bit */
+#define ROBO_MIRROR_ING_DIV_CTRL 0x14 /* Mirror Ingress Divider: 16bit */
+#define ROBO_MIRROR_ING_MAC_ADDR 0x16 /* Ingress Mirror MAC Addr: 48bit*/
+#define ROBO_MIRROR_EGR_CTRL 0x1c /* Mirror Egress Control: 16bit */
+#define ROBO_MIRROR_EGR_DIV_CTRL 0x1e /* Mirror Egress Divider: 16bit */
+#define ROBO_MIRROR_EGR_MAC_ADDR 0x20 /* Egress Mirror MAC Addr: 48bit*/
+
+/* BCM5325m MIB AUTOCAST REGISTERS (0x03) REGISTER MAP: 8/16/48 bit regs */
+#define ROBO_MIB_AC_PORT 0x00 /* MIB Autocast Port: 16bit */
+#define ROBO_MIB_AC_HDR_PTR 0x02 /* MIB Autocast Header pointer:16bit*/
+#define ROBO_MIB_AC_HDR_LEN 0x04 /* MIB Autocast Header Len: 16bit */
+#define ROBO_MIB_AC_DA 0x06 /* MIB Autocast DA: 48bit */
+#define ROBO_MIB_AC_SA 0x0c /* MIB Autocast SA: 48bit */
+#define ROBO_MIB_AC_TYPE 0x12 /* MIB Autocast Type: 16bit */
+#define ROBO_MIB_AC_RATE 0x14 /* MIB Autocast Rate: 8bit */
+#define ROBO_GET_AC_RATE(secs) ((secs)*10)
+#define ROBO_AC_RATE_MAX 0xff
+#define ROBO_AC_RATE_DEFAULT 0x64 /* 10 secs */
+typedef struct _ROBO_MIB_AC_STRUCT
+{
+ unsigned char opcode:4; /* Tx MIB Autocast opcode */
+ unsigned char portno:4; /* zero-based port no. */
+ unsigned char portstate:8; /* port state */
+ unsigned long long TxOctets;
+ unsigned int TxDropPkts;
+ unsigned int rsvd;
+ unsigned int TxBroadcastPkts;
+ unsigned int TxMulticastPkts;
+ unsigned int TxUnicastPkts;
+ unsigned int TxCollisions;
+ unsigned int TxSingleCollision;
+ unsigned int TxMultiCollision;
+ unsigned int TxDeferredTransmit;
+ unsigned int TxLateCollision;
+ unsigned int TxExcessiveCollision;
+ unsigned int TxFrameInDiscards;
+ unsigned int TxPausePkts;
+ unsigned int rsvd1[2];
+ unsigned long long RxOctets;
+ unsigned int RxUndersizePkts;
+ unsigned int RxPausePkts;
+ unsigned int RxPkts64Octets;
+ unsigned int RxPkts64to127Octets;
+ unsigned int RxPkts128to255Octets;
+ unsigned int RxPkts256to511Octets;
+ unsigned int RxPkts512to1023Octets;
+ unsigned int RxPkts1024to1522Octets;
+ unsigned int RxOversizePkts;
+ unsigned int RxJabbers;
+ unsigned int RxAlignmentErrors;
+ unsigned int RxFCSErrors;
+ unsigned long long RxGoodOctets;
+ unsigned int RxDropPkts;
+ unsigned int RxUnicastPkts;
+ unsigned int RxMulticastPkts;
+ unsigned int RxBroadcastPkts;
+ unsigned int RxSAChanges;
+ unsigned int RxFragments;
+ unsigned int RxExcessSizeDisc;
+ unsigned int RxSymbolError;
+} ROBO_MIB_AC_STRUCT;
+
+/* BCM5325m ARL CONTROL REGISTERS (0x04) REGISTER MAP: 8/16/48/64 bit regs */
+#define ROBO_ARL_CONFIG 0x00 /* ARL Global Configuration: 8bit*/
+#define ROBO_BPDU_MC_ADDR_REG 0x04 /* BPDU Multicast Address Reg:64bit*/
+#define ROBO_MULTIPORT_ADDR_1 0x10 /* Multiport Address 1: 48 bits*/
+#define ROBO_MULTIPORT_VECTOR_1 0x16 /* Multiport Vector 1: 16 bits */
+#define ROBO_MULTIPORT_ADDR_2 0x20 /* Multiport Address 2: 48 bits*/
+#define ROBO_MULTIPORT_VECTOR_2 0x26 /* Multiport Vector 2: 16 bits */
+#define ROBO_SECURE_SRC_PORT_MASK 0x30 /* Secure Source Port Mask: 16 bits*/
+#define ROBO_SECURE_DST_PORT_MASK 0x32 /* Secure Dest Port Mask: 16 bits */
+
+
+/* BCM5325m ARL IO REGISTERS (0x05) REGISTER MAP: 8/16/48/64 bit regs */
+#define ARL_TABLE_WRITE 0 /* for read/write state in control reg */
+#define ARL_TABLE_READ 1 /* for read/write state in control reg */
+#ifdef BCM5380
+#define ARL_VID_BYTES 2 /* number of bytes for VID */
+#else
+#define ARL_VID_BYTES 1 /* number of bytes for VID */
+#endif
+typedef struct _ROBO_ARL_RW_CTRL_STRUC
+{
+ unsigned char ARLrw:1; /* ARL read/write (1=read) */
+ unsigned char rsvd:6; /* reserved */
+ unsigned char ARLStart:1; /* ARL start/done (1=start) */
+} ROBO_ARL_RW_CTRL_STRUC;
+typedef struct _ROBO_ARL_SEARCH_CTRL_STRUC
+{
+ unsigned char valid:1; /* ARL search result valid */
+ unsigned char rsvd:6; /* reserved */
+ unsigned char ARLStart:1; /* ARL start/done (1=start) */
+} ROBO_ARL_SEARCH_CTRL_STRUC;
+typedef struct _ROBO_ARL_ENTRY_CTRL_STRUC
+{
+ unsigned char portID:4; /* port id */
+ unsigned char chipID:2; /* chip id */
+ unsigned char rsvd:5; /* reserved */
+ unsigned char prio:2; /* priority */
+ unsigned char age:1; /* age */
+ unsigned char staticEn:1; /* static */
+ unsigned char valid:1; /* valid */
+} ROBO_ARL_ENTRY_CTRL_STRUC;
+typedef struct _ROBO_ARL_SEARCH_RESULT_CTRL_STRUC
+{
+ unsigned char portID:4; /* port id */
+ unsigned char rsvd:1; /* reserved */
+ unsigned char vid:8; /* vlan id */
+ unsigned char age:1; /* age */
+ unsigned char staticEn:1; /* static */
+ unsigned char valid:1; /* valid */
+} ROBO_ARL_SEARCH_RESULT_CTRL_STRUC;
+typedef struct _ROBO_ARL_ENTRY_MAC_STRUC
+{
+ unsigned char macBytes[6]; /* MAC address */
+} ROBO_ARL_ENTRY_MAC_STRUC;
+
+typedef struct _ROBO_ARL_ENTRY_STRUC
+{
+ ROBO_ARL_ENTRY_MAC_STRUC mac; /* MAC address */
+ ROBO_ARL_ENTRY_CTRL_STRUC ctrl; /* control bits */
+} ROBO_ARL_ENTRY_STRUC;
+
+typedef struct _ROBO_ARL_SEARCH_RESULT_STRUC
+{
+ ROBO_ARL_ENTRY_MAC_STRUC mac; /* MAC address */
+ ROBO_ARL_SEARCH_RESULT_CTRL_STRUC ctrl; /* control bits */
+} ROBO_ARL_SEARCH_RESULT_STRUC;
+
+/* multicast versions of ARL entry structs */
+typedef struct _ROBO_ARL_ENTRY_MCAST_CTRL_STRUC
+{
+ unsigned int portMask:12;/* multicast port mask */
+ unsigned char prio:1; /* priority */
+ unsigned char gigPort:1; /* gigabit port 1 mask */
+ unsigned char staticEn:1; /* static */
+ unsigned char valid:1; /* valid */
+} ROBO_ARL_ENTRY_MCAST_CTRL_STRUC;
+typedef struct _ROBO_ARL_SEARCH_RESULT_MCAST_CTRL_STRUC
+{
+ unsigned int portMask:13; /* multicast port mask */
+ unsigned char age:1; /* age */
+ unsigned char staticEn:1; /* static */
+ unsigned char valid:1; /* valid */
+} ROBO_ARL_SEARCH_RESULT_MCAST_CTRL_STRUC;
+/* BCM5350 extension register */
+typedef struct _ROBO_ARL_SEARCH_RESULT_EXTENSION
+{
+ unsigned int prio:2; /* priority */
+ unsigned int portMask:1; /* MSB (MII) of port mask for multicast */
+ unsigned int reserved:5;
+} ROBO_ARL_SEARCH_RESULT_EXTENSION;
+
+typedef struct _ROBO_ARL_ENTRY_MCAST_STRUC
+{
+ ROBO_ARL_ENTRY_MAC_STRUC mac; /* MAC address */
+ ROBO_ARL_ENTRY_MCAST_CTRL_STRUC ctrl; /* control bits */
+} ROBO_ARL_ENTRY_MCAST_STRUC;
+typedef struct _ROBO_ARL_SEARCH_RESULT_MCAST_STRUC
+{
+ ROBO_ARL_ENTRY_MAC_STRUC mac; /* MAC address */
+ ROBO_ARL_SEARCH_RESULT_MCAST_CTRL_STRUC ctrl; /* control bits */
+} ROBO_ARL_SEARCH_RESULT_MCAST_STRUC;
+
+#define ROBO_ARL_RW_CTRL 0x00 /* ARL Read/Write Control : 8bit */
+#define ROBO_ARL_MAC_ADDR_IDX 0x02 /* MAC Address Index: 48bit */
+#define ROBO_ARL_VID_TABLE_IDX 0x08 /* VID Table Address Index: 8bit */
+#define ROBO_ARL_ENTRY0 0x10 /* ARL Entry 0 : 64 bit */
+#define ROBO_ARL_ENTRY1 0x18 /* ARL Entry 1 : 64 bit */
+#define ROBO_ARL_SEARCH_CTRL 0x20 /* ARL Search Control: 8bit */
+#define ROBO_ARL_SEARCH_ADDR 0x22 /* ARL Search Address: 16bit */
+#define ROBO_ARL_SEARCH_RESULT 0x24 /* ARL Search Result: 64bit */
+#define ROBO_ARL_SEARCH_RESULT_EXT 0x2c /* ARL Search Result Extension (5350): 8bit */
+#define ROBO_ARL_VID_ENTRY0 0x30 /* ARL VID Entry 0: 64bit */
+#define ROBO_ARL_VID_ENTRY1 0x32 /* ARL VID Entry 1: 64bit */
+#define ROBO_ARL_SEARCH_CTRL_53115 0x50 /* ARL Search Control: 8bit */
+#define ROBO_ARL_SEARCH_ADDR_53115 0x51 /* ARL Search Address: 16bit */
+#define ROBO_ARL_SEARCH_RESULT_53115 0x60 /* ARL Search Result: 64bit */
+#define ROBO_ARL_SEARCH_RESULT_EXT_53115 0x68 /* ARL Search Result Extension (53115): 16bit */
+
+/* BCM5395/5397/5398/53115 */
+#define ROBO_VTBL_ACCESS 0x60 /* VLAN table access: 8bit */
+#define ROBO_VTBL_INDX 0x61 /* VLAN table address index: 16bit */
+#define ROBO_VTBL_ENTRY 0x63 /* VLAN table entry: 32bit */
+#define ROBO_VTBL_ACCESS_5395 0x80 /* VLAN table access: 8bit */
+#define ROBO_VTBL_INDX_5395 0x81 /* VLAN table address index: 16bit */
+#define ROBO_VTBL_ENTRY_5395 0x83 /* VLAN table entry: 32bit */
+
+/* BCM5325m MANAGEMENT FRAME REGISTERS (0x6) REGISTER MAP: 8/16 bit regs */
+#define ROBO_MGMT_FRAME_RD_DATA 0x00 /* Management Frame Read Data :8bit*/
+#define ROBO_MGMT_FRAME_WR_DATA 0x01 /* Management Frame Write Data:8bit*/
+#define ROBO_MGMT_FRAME_WR_CTRL 0x02 /* Write Control: 16bit */
+#define ROBO_MGMT_FRAME_RD_STAT 0x04 /* Read Status: 16bit */
+
+/* BCM5325m MEMORY ACCESS REGISTERS (Page 0x08) REGISTER MAP: 32 bit regs */
+#define MEM_TABLE_READ 1 /* for read/write state in mem access reg */
+#define MEM_TABLE_WRITE 0 /* for read/write state in mem access reg */
+#define MEM_TABLE_ACCESS_START 1 /* for mem access read/write start */
+#define MEM_TABLE_ACCESS_DONE 0 /* for mem access read/write done */
+#define VLAN_TABLE_ADDR 0x3800 /* BCM5380 only */
+#ifdef BCM5380
+#define NUM_ARL_TABLE_ENTRIES 4096 /* number of entries in ARL table */
+#define NUM_VLAN_TABLE_ENTRIES 2048 /* number of entries in VLAN table */
+#define ARL_TABLE_ADDR 0 /* offset of ARL table start */
+#else
+#define NUM_ARL_TABLE_ENTRIES 2048 /* number of entries in ARL table */
+#define NUM_VLAN_TABLE_ENTRIES 256 /* number of entries in VLAN table */
+#define ARL_TABLE_ADDR 0x3800 /* offset of ARL table start */
+/* corresponding values for 5350 */
+#define NUM_ARL_TABLE_ENTRIES_5350 1024 /* number of entries in ARL table (5350) */
+#define NUM_VLAN_TABLE_ENTRIES_5350 16 /* number of entries in VLAN table */
+#define ARL_TABLE_ADDR_5350 0x1c00 /* offset of ARL table start (5350) */
+#endif
+#define NUM_ARL_TABLE_ENTRIES_53115 4096 /* number of entries in ARL table (53115) */
+#define NUM_VLAN_TABLE_ENTRIES_53115 4096 /* number of entries in VLAN table */
+typedef struct _ROBO_MEM_ACCESS_CTRL_STRUC
+{
+ unsigned int memAddr:14; /* 64-bit memory address */
+ unsigned char rsvd:4; /* reserved */
+ unsigned char readEn:1; /* read enable (0 == write) */
+ unsigned char startDone:1;/* memory access start/done */
+ unsigned int rsvd1:12; /* reserved */
+} ROBO_MEM_ACCESS_CTRL_STRUC;
+typedef struct _ROBO_MEM_ACCESS_DATA_STRUC
+{
+ unsigned int memData[2]; /* 64-bit data */
+ unsigned short rsvd; /* reserved */
+} ROBO_MEM_ACCESS_DATA_STRUC;
+
+#ifdef BCM5380
+typedef struct _ROBO_ARL_TABLE_DATA_STRUC
+{
+ unsigned char MACaddr[6]; /* MAC addr */
+ unsigned int portID:4; /* port ID */
+ unsigned int chipID:2; /* chip ID */
+ unsigned int rsvd:6; /* reserved */
+ unsigned int highPrio:1; /* high priority address */
+ unsigned int age:1; /* entry accessed/learned since ageing process */
+ unsigned int staticAddr:1;/* entry is static */
+ unsigned int valid:1; /* entry is valid */
+ unsigned int vid:12; /* vlan id */
+ unsigned int rsvd2:4; /* reserved */
+} ROBO_ARL_TABLE_DATA_STRUC;
+#else
+typedef struct _ROBO_ARL_TABLE_DATA_STRUC
+{
+ unsigned char MACaddr[6]; /* MAC addr */
+ unsigned int portID:4; /* port ID */
+ unsigned int chipID:2; /* chip ID */
+ unsigned int rsvd:7; /* reserved */
+ unsigned int age:1; /* entry accessed/learned since ageing process */
+ unsigned int staticAddr:1;/* entry is static */
+ unsigned int valid:1; /* entry is valid */
+} ROBO_ARL_TABLE_DATA_STRUC;
+#endif
+
+/* multicast format*/
+typedef struct _ROBO_ARL_TABLE_MCAST_DATA_STRUC
+{
+ unsigned char MACaddr[6]; /* MAC addr */
+ unsigned int portMask:12;/* multicast port mask */
+ unsigned char prio:1; /* priority */
+ unsigned char gigPort:1; /* gigabit port 1 mask */
+ unsigned char staticEn:1; /* static */
+ unsigned char valid:1; /* valid */
+ unsigned int vid:12; /* vlan id */
+ unsigned int rsvd2:4; /* reserved */
+} ROBO_ARL_TABLE_MCAST_DATA_STRUC;
+#define ROBO_MEM_ACCESS_CTRL 0x00 /* Memory Read/Write Control :32bit*/
+#define ROBO_MEM_ACCESS_DATA 0x04 /* Memory Read/Write Data:64bit*/
+
+/* BCM5325m SWITCH PORT (0x10-18) REGISTER MAP: 8/16 bit regs */
+typedef struct _ROBO_MII_CTRL_STRUC
+{
+ unsigned char rsvd:8; /* reserved */
+ unsigned char duplex:1; /* duplex mode */
+ unsigned char restartAN:1;/* restart auto-negotiation */
+ unsigned char rsvd1:1; /* reserved */
+ unsigned char powerDown:1;/* power down */
+ unsigned char ANenable:1; /* auto-negotiation enable */
+ unsigned char speed:1; /* forced speed selection */
+ unsigned char loopback:1; /* loopback */
+ unsigned char reset:1; /* reset */
+} ROBO_MII_CTRL_STRUC;
+typedef struct _ROBO_MII_AN_ADVERT_STRUC
+{
+ unsigned char selector:5; /* advertise selector field */
+ unsigned char T10BaseT:1; /* advertise 10BaseT */
+ unsigned char T10BaseTFull:1; /* advertise 10BaseT, full duplex */
+ unsigned char T100BaseX:1; /* advertise 100BaseX */
+ unsigned char T100BaseXFull:1;/* advertise 100BaseX full duplex */
+ unsigned char noT4:1; /* do not advertise T4 */
+ unsigned char pause:1; /* advertise pause for full duplex */
+ unsigned char rsvd:2; /* reserved */
+ unsigned char remoteFault:1; /* transmit remote fault */
+ unsigned char rsvd1:1; /* reserved */
+ unsigned char nextPage:1; /* nex page operation supported */
+} ROBO_MII_AN_ADVERT_STRUC;
+#define ROBO_MII_CTRL 0x00 /* Port MII Control */
+#define ROBO_MII_STAT 0x02 /* Port MII Status */
+/* Fields of link status register */
+#define ROBO_MII_STAT_JABBER (1<<1) /* Jabber detected */
+#define ROBO_MII_STAT_LINK (1<<2) /* Link status */
+
+#define ROBO_MII_PHYID_HI 0x04 /* Port PHY ID High */
+#define ROBO_MII_PHYID_LO 0x06 /* Port PHY ID Low */
+#define ROBO_MII_ANA_REG 0x08 /* MII Auto-Neg Advertisement */
+#define ROBO_MII_ANP_REG 0x0a /* MII Auto-Neg Partner Ability */
+#define ROBO_MII_AN_EXP_REG 0x0c /* MII Auto-Neg Expansion */
+#define ROBO_MII_AN_NP_REG 0x0e /* MII next page */
+#define ROBO_MII_ANP_NP_REG 0x10 /* MII Partner next page */
+#define ROBO_MII_100BX_AUX_CTRL 0x20 /* 100BASE-X Auxiliary Control */
+#define ROBO_MII_100BX_AUX_STAT 0x22 /* 100BASE-X Auxiliary Status */
+#define ROBO_MII_100BX_RCV_ERR_CTR 0x24 /* 100BASE-X Receive Error Ctr */
+#define ROBO_MII_100BX_RCV_FS_ERR 0x26 /* 100BASE-X Rcv False Sense Ctr */
+#define ROBO_MII_AUX_CTRL 0x30 /* Auxiliary Control/Status */
+/* Fields of Auxiliary control register */
+#define ROBO_MII_AUX_CTRL_FD (1<<0) /* Full duplex link detected*/
+#define ROBO_MII_AUX_CTRL_SP100 (1<<1) /* Speed 100 indication */
+#define ROBO_MII_AUX_STATUS 0x32 /* Aux Status Summary */
+#define ROBO_MII_CONN_STATUS 0x34 /* Aux Connection Status */
+#define ROBO_MII_AUX_MODE2 0x36 /* Aux Mode 2 */
+#define ROBO_MII_AUX_ERR_STATUS 0x38 /* Aux Error and General Status */
+#define ROBO_MII_AUX_MULTI_PHY 0x3c /* Aux Multiple PHY Register*/
+#define ROBO_MII_BROADCOM_TEST 0x3e /* Broadcom Test Register */
+
+
+/* BCM5325m PORT MIB REGISTERS (Pages 0x20-0x24,0x28) REGISTER MAP: 64/32 */
+/* Tranmit Statistics */
+#define ROBO_MIB_TX_OCTETS 0x00 /* 64b: TxOctets */
+#define ROBO_MIB_TX_DROP_PKTS 0x08 /* 32b: TxDropPkts */
+#define ROBO_MIB_TX_BC_PKTS 0x10 /* 32b: TxBroadcastPkts */
+#define ROBO_MIB_TX_MC_PKTS 0x14 /* 32b: TxMulticastPkts */
+#define ROBO_MIB_TX_UC_PKTS 0x18 /* 32b: TxUnicastPkts */
+#define ROBO_MIB_TX_COLLISIONS 0x1c /* 32b: TxCollisions */
+#define ROBO_MIB_TX_SINGLE_COLLISIONS 0x20 /* 32b: TxSingleCollision */
+#define ROBO_MIB_TX_MULTI_COLLISIONS 0x24 /* 32b: TxMultiCollision */
+#define ROBO_MIB_TX_DEFER_TX 0x28 /* 32b: TxDeferred Transmit */
+#define ROBO_MIB_TX_LATE_COLLISIONS 0x2c /* 32b: TxLateCollision */
+#define ROBO_MIB_EXCESS_COLLISIONS 0x30 /* 32b: TxExcessiveCollision*/
+#define ROBO_MIB_FRAME_IN_DISCARDS 0x34 /* 32b: TxFrameInDiscards */
+#define ROBO_MIB_TX_PAUSE_PKTS 0x38 /* 32b: TxPausePkts */
+
+/* Receive Statistics */
+#define ROBO_MIB_RX_OCTETS 0x44 /* 64b: RxOctets */
+#define ROBO_MIB_RX_UNDER_SIZE_PKTS 0x4c /* 32b: RxUndersizePkts(runts)*/
+#define ROBO_MIB_RX_PAUSE_PKTS 0x50 /* 32b: RxPausePkts */
+#define ROBO_MIB_RX_PKTS_64 0x54 /* 32b: RxPkts64Octets */
+#define ROBO_MIB_RX_PKTS_65_TO_127 0x58 /* 32b: RxPkts64to127Octets*/
+#define ROBO_MIB_RX_PKTS_128_TO_255 0x5c /* 32b: RxPkts128to255Octets*/
+#define ROBO_MIB_RX_PKTS_256_TO_511 0x60 /* 32b: RxPkts256to511Octets*/
+#define ROBO_MIB_RX_PKTS_512_TO_1023 0x64 /* 32b: RxPkts512to1023Octets*/
+#define ROBO_MIB_RX_PKTS_1024_TO_1522 0x68 /* 32b: RxPkts1024to1522Octets*/
+#define ROBO_MIB_RX_OVER_SIZE_PKTS 0x6c /* 32b: RxOversizePkts*/
+#define ROBO_MIB_RX_JABBERS 0x70 /* 32b: RxJabbers*/
+#define ROBO_MIB_RX_ALIGNMENT_ERRORS 0x74 /* 32b: RxAlignmentErrors*/
+#define ROBO_MIB_RX_FCS_ERRORS 0x78 /* 32b: RxFCSErrors */
+#define ROBO_MIB_RX_GOOD_OCTETS 0x7c /* 32b: RxGoodOctets */
+#define ROBO_MIB_RX_DROP_PKTS 0x84 /* 32b: RxDropPkts */
+#define ROBO_MIB_RX_UC_PKTS 0x88 /* 32b: RxUnicastPkts */
+#define ROBO_MIB_RX_MC_PKTS 0x8c /* 32b: RxMulticastPkts */
+#define ROBO_MIB_RX_BC_PKTS 0x90 /* 32b: RxBroadcastPkts */
+#define ROBO_MIB_RX_SA_CHANGES 0x94 /* 32b: RxSAChanges */
+#define ROBO_MIB_RX_FRAGMENTS 0x98 /* 32b: RxFragments */
+#define ROBO_MIB_RX_EXCESS_SZ_DISC 0x9c /* 32b: RxExcessSizeDisc*/
+#define ROBO_MIB_RX_SYMBOL_ERROR 0xa0 /* 32b: RxSymbolError */
+
+/* BCM5350 MIB Statistics */
+/* Group 0 */
+#define ROBO_MIB_TX_GOOD_PKTS 0x00 /* 16b: TxGoodPkts */
+#define ROBO_MIB_TX_UNICAST_PKTS 0x02 /* 16b: TxUnicastPkts */
+#define ROBO_MIB_RX_GOOD_PKTS 0x04 /* 16b: RxGoodPkts */
+#define ROBO_MIB_RX_GOOD_UNICAST_PKTS 0x06 /* 16b: RxGoodUnicastPkts */
+/* Group 1 */
+#define ROBO_MIB_TX_COLLISION 0x00 /* 16b: TxCollision */
+#define ROBO_MIB_TX_OCTETS_5350 0x02 /* 16b: TxOctets */
+#define ROBO_MIB_RX_FCS_ERRORS_5350 0x04 /* 16b: RxFCSErrors */
+#define ROBO_MIB_RX_GOOD_OCTETS_5350 0x06 /* 16b: RxGoodOctets */
+
+/* BCM5325m QoS REGISTERS (Page 0x30) REGISTER MAP: 8/16 */
+#define ROBO_QOS_CTRL 0x00 /* 16b: QoS Control Register */
+#define ROBO_QOS_LOCAL_WEIGHT_CTRL 0x10 /* 8b: Local HQ/LQ Weight Register*/
+#define ROBO_QOS_CPU_WEIGHT_CTRL 0x12 /* 8b: CPU HQ/LQ Weight Register*/
+#define ROBO_QOS_PAUSE_ENA 0x13 /* 16b: Qos Pause Enable Register*/
+#define ROBO_QOS_PRIO_THRESHOLD 0x15 /* 8b: Priority Threshold Register*/
+#define ROBO_QOS_RESERVED 0x16 /* 8b: Qos Reserved Register */
+
+/* BCM5325m VLAN REGISTERS (Page 0x34) REGISTER MAP: 8/16bit */
+typedef struct _ROBO_VLAN_CTRL0_STRUC
+{
+ unsigned char frameControlP:2; /* 802.1P frame control */
+ unsigned char frameControlQ:2; /* 802.1Q frame control */
+ unsigned char dropMissedVID:1; /* enable drop missed VID packet */
+ unsigned char vidMacHash:1; /* VID_MAC hash enable */
+ unsigned char vidMacCheck:1; /* VID_MAC check enable */
+ unsigned char VLANen:1; /* 802.1Q VLAN enable */
+} ROBO_VLAN_CTRL0_STRUC;
+#define VLAN_TABLE_WRITE 1 /* for read/write state in table access reg */
+#define VLAN_TABLE_READ 0 /* for read/write state in table access reg */
+#define VLAN_ID_HIGH_BITS 0 /* static high bits in table access reg */
+#define VLAN_ID_MAX 15 /* max VLAN id (5350) */
+#define VLAN_ID_MAX_5365 255 /* max VLAN id */
+#define VLAN_ID_MAX_5395 4094 /* max VLAN id (5395) */
+#define VLAN_ID_MASK VLAN_ID_MAX /* VLAN id mask */
+#ifdef BCM5380
+#define VLAN_UNTAG_SHIFT 13 /* for postioning untag bits in write reg */
+#define VLAN_VALID 0x4000000 /* valid bit in write reg */
+#else
+#define VLAN_UNTAG_SHIFT 7 /* for postioning untag bits in write reg */
+#define VLAN_VALID 0x4000 /* valid bit in write reg */
+/* corresponding values for 5350 */
+#define VLAN_UNTAG_SHIFT_5350 6 /* for postioning untag bits in write reg */
+#define VLAN_VALID_5350 0x00100000 /* valid bit in write reg */
+#endif
+typedef struct _ROBO_VLAN_TABLE_ACCESS_STRUC
+{
+ unsigned char VLANid:8; /* VLAN ID (low 8 bits) */
+ unsigned char VLANidHi:4; /* VLAN ID (fixed upper portion) */
+ unsigned char readWriteState:1; /* read/write state (write = 1) */
+ volatile unsigned char readWriteEnable:1; /* table read/write enable */
+ unsigned char rsvd:2; /* reserved */
+} ROBO_VLAN_TABLE_ACCESS_STRUC;
+#ifdef BCM5380
+typedef struct _ROBO_VLAN_READ_WRITE_STRUC
+{
+ unsigned int VLANgroup:13;/* VLAN group mask */
+ unsigned int VLANuntag:13;/* VLAN untag enable mask */
+ unsigned char valid:1; /* valid */
+ unsigned char rsvd:5; /* reserved */
+} ROBO_VLAN_READ_WRITE_STRUC;
+#else
+typedef struct _ROBO_VLAN_READ_WRITE_STRUC
+{
+ unsigned char VLANgroup:7; /* VLAN group mask */
+ unsigned char VLANuntag:7; /* VLAN untag enable mask */
+ unsigned char valid:1; /* valid */
+ unsigned char rsvd:1; /* reserved */
+} ROBO_VLAN_READ_WRITE_STRUC;
+typedef struct _ROBO_VLAN_READ_WRITE_STRUC_5350
+{
+ unsigned char VLANgroup:6; /* VLAN group mask */
+ unsigned char VLANuntag:6; /* VLAN untag enable mask */
+ unsigned char highVID:8; /* upper bits of vid */
+ unsigned char valid:1; /* valid */
+ unsigned int rsvd:11; /* reserved */
+} ROBO_VLAN_READ_WRITE_STRUC_5350;
+#endif
+#define ROBO_VLAN_CTRL0 0x00 /* 8b: VLAN Control 0 Register */
+#define ROBO_VLAN_CTRL1 0x01 /* 8b: VLAN Control 1 Register */
+#define ROBO_VLAN_CTRL2 0x02 /* 8b: VLAN Control 2 Register */
+#define ROBO_VLAN_CTRL3 0x03 /* 8b: VLAN Control 3 Register */
+#define ROBO_VLAN_CTRL4 0x04 /* 8b: VLAN Control 4 Register */
+#define ROBO_VLAN_CTRL5 0x05 /* 8b: VLAN Control 5 Register */
+#define ROBO_VLAN_TABLE_ACCESS_5365 0x08 /* 14b: VLAN Table Access Register */
+#define ROBO_VLAN_TABLE_ACCESS 0x06 /* 14b: VLAN Table Access Register (5350) */
+#define ROBO_VLAN_WRITE_5365 0x0a /* 15b: VLAN Write Register */
+#define ROBO_VLAN_WRITE 0x08 /* 15b: VLAN Write Register (5350) */
+#define ROBO_VLAN_READ 0x0c /* 15b: VLAN Read Register */
+#define ROBO_VLAN_PORT0_DEF_TAG 0x10 /* 16b: VLAN Port 0 Default Tag Register */
+#define ROBO_VLAN_PORT1_DEF_TAG 0x12 /* 16b: VLAN Port 1 Default Tag Register */
+#define ROBO_VLAN_PORT2_DEF_TAG 0x14 /* 16b: VLAN Port 2 Default Tag Register */
+#define ROBO_VLAN_PORT3_DEF_TAG 0x16 /* 16b: VLAN Port 3 Default Tag Register */
+#define ROBO_VLAN_PORT4_DEF_TAG 0x18 /* 16b: VLAN Port 4 Default Tag Register */
+#define ROBO_VLAN_PORTMII_DEF_TAG 0x1a /* 16b: VLAN Port MII Default Tag Register */
+/* 5380 only */
+#define ROBO_VLAN_PORT5_DEF_TAG 0x1a /* 16b: VLAN Port 5 Default Tag Register */
+#define ROBO_VLAN_PORT6_DEF_TAG 0x1c /* 16b: VLAN Port 6 Default Tag Register */
+#define ROBO_VLAN_PORT7_DEF_TAG 0x1e /* 16b: VLAN Port 7 Default Tag Register */
+#define ROBO_VLAN_PORT8_DEF_TAG 0x20 /* 16b: VLAN Port 8 Default Tag Register */
+/* 53115 only */
+#define ROBO_DUPLEX_STAT_SUMMARY_53115 0x08 /* Duplex Status Summary: 16bit */
+#define ROBO_JUMBO_PAGE 0x40
+#define ROBO_JUMBO_CTRL 0x01 /* 32bit */
+#define ROBO_JUMBO_SIZE 0x05 /* 16bit */
+
+#ifndef _CFE_
+#pragma pack()
+#endif
+
+#endif /* !__BCM535M_H_ */
diff --git a/package/kernel/switch/src/gpio.h b/package/kernel/switch/src/gpio.h
new file mode 100644
index 0000000000..cb734f7b1b
--- /dev/null
+++ b/package/kernel/switch/src/gpio.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006 OpenWrt.org
+ *
+ * This is free software, licensed under the GNU General Public License v2.
+ * See /LICENSE for more information.
+ */
+
+#ifndef __GPIO_H
+#define __GPIO_H
+
+#ifdef CONFIG_BCM47XX
+#include <linux/gpio.h>
+#else
+#warning "Unsupported configuration."
+
+#define bcm47xx_gpio_in(mask) (-1U)
+#define bcm47xx_gpio_out(mask, value) (-1U)
+#define bcm47xx_gpio_outen(mask, value) (-1U)
+#define bcm47xx_gpio_control(mask, value) (-1U)
+#define bcm47xx_gpio_intmask(mask, value) (-1U)
+#define bcm47xx_gpio_polarity(mask, value) (-1U)
+
+#endif
+
+#endif /* __GPIO_H */
diff --git a/package/kernel/switch/src/switch-adm.c b/package/kernel/switch/src/switch-adm.c
new file mode 100644
index 0000000000..8c0ddc6c9a
--- /dev/null
+++ b/package/kernel/switch/src/switch-adm.c
@@ -0,0 +1,596 @@
+/*
+ * ADMTEK Adm6996 switch configuration module
+ *
+ * Copyright (C) 2005 Felix Fietkau <nbd@nbd.name>
+ *
+ * Partially based on Broadcom Home Networking Division 10/100 Mbit/s
+ * Ethernet Device Driver (from Montavista 2.4.20_mvl31 Kernel).
+ * Copyright (C) 2004 Broadcom Corporation
+ *
+ * adm_rreg function from adm6996
+ * Copyright (C) 2004 Nikki Chumakov <nikki@gattaca.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/init.h>
+#include <linux/if.h>
+#include <linux/if_arp.h>
+#include <linux/sockios.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+
+#include "switch-core.h"
+#include "gpio.h"
+
+#ifdef CONFIG_BCM47XX
+#include <bcm47xx_nvram.h>
+#endif
+
+#define DRIVER_NAME "adm6996"
+#define DRIVER_VERSION "0.01"
+
+static int eecs = 0;
+static int eesk = 0;
+static int eedi = 0;
+static int eerc = 0;
+static int force = 0;
+
+MODULE_AUTHOR("Felix Fietkau <openwrt@nbd.name>");
+MODULE_LICENSE("GPL");
+module_param(eecs, int, 0);
+module_param(eesk, int, 0);
+module_param(eedi, int, 0);
+module_param(eerc, int, 0);
+module_param(force, int, 0);
+
+/* Minimum timing constants */
+#define EECK_EDGE_TIME 3 /* 3us - max(adm 2.5us, 93c 1us) */
+#define EEDI_SETUP_TIME 1 /* 1us - max(adm 10ns, 93c 400ns) */
+#define EECS_SETUP_TIME 1 /* 1us - max(adm no, 93c 200ns) */
+
+/* Handy macros for writing fixed length values */
+#define adm_write8(cs, b) { __u8 val = (__u8) (b); adm_write(cs, &val, sizeof(val)*8); }
+#define adm_write16(cs, w) { __u16 val = hton16(w); adm_write(cs, (__u8 *)&val, sizeof(val)*8); }
+#define adm_write32(cs, i) { uint32 val = hton32(i); adm_write(cs, (__u8 *)&val, sizeof(val)*8); }
+
+#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0)
+
+#ifdef CONFIG_BCM47XX
+
+/* Return gpio pin number assigned to the named pin */
+/*
+* Variable should be in format:
+*
+* gpio<N>=pin_name
+*
+* 'def_pin' is returned if there is no such variable found.
+*/
+static unsigned int get_gpiopin(char *pin_name, unsigned int def_pin)
+{
+ char name[] = "gpioXXXX";
+ char val[10];
+ unsigned int pin;
+
+ /* Go thru all possibilities till a match in pin name */
+ for (pin = 0; pin < 16; pin ++) {
+ sprintf(name, "gpio%d", pin);
+ if (bcm47xx_nvram_getenv(name, val, sizeof(val)) >= 0) {
+ if (!strcmp(val, pin_name))
+ return pin;
+ }
+ }
+ return def_pin;
+}
+#endif
+
+
+static void adm_write(int cs, char *buf, unsigned int bits)
+{
+ int i, len = (bits + 7) / 8;
+ __u8 mask;
+
+ bcm47xx_gpio_out(eecs, (cs ? eecs : 0));
+ udelay(EECK_EDGE_TIME);
+
+ /* Byte assemble from MSB to LSB */
+ for (i = 0; i < len; i++) {
+ /* Bit bang from MSB to LSB */
+ for (mask = 0x80; mask && bits > 0; mask >>= 1, bits --) {
+ /* Clock low */
+ bcm47xx_gpio_out(eesk, 0);
+ udelay(EECK_EDGE_TIME);
+
+ /* Output on rising edge */
+ bcm47xx_gpio_out(eedi, ((mask & buf[i]) ? eedi : 0));
+ udelay(EEDI_SETUP_TIME);
+
+ /* Clock high */
+ bcm47xx_gpio_out(eesk, eesk);
+ udelay(EECK_EDGE_TIME);
+ }
+ }
+
+ /* Clock low */
+ bcm47xx_gpio_out(eesk, 0);
+ udelay(EECK_EDGE_TIME);
+
+ if (cs)
+ bcm47xx_gpio_out(eecs, 0);
+}
+
+
+static void adm_read(int cs, char *buf, unsigned int bits)
+{
+ int i, len = (bits + 7) / 8;
+ __u8 mask;
+
+ bcm47xx_gpio_out(eecs, (cs ? eecs : 0));
+ udelay(EECK_EDGE_TIME);
+
+ /* Byte assemble from MSB to LSB */
+ for (i = 0; i < len; i++) {
+ __u8 byte;
+
+ /* Bit bang from MSB to LSB */
+ for (mask = 0x80, byte = 0; mask && bits > 0; mask >>= 1, bits --) {
+ __u8 gp;
+
+ /* Clock low */
+ bcm47xx_gpio_out(eesk, 0);
+ udelay(EECK_EDGE_TIME);
+
+ /* Input on rising edge */
+ gp = bcm47xx_gpio_in(~0);
+ if (gp & eedi)
+ byte |= mask;
+
+ /* Clock high */
+ bcm47xx_gpio_out(eesk, eesk);
+ udelay(EECK_EDGE_TIME);
+ }
+
+ *buf++ = byte;
+ }
+
+ /* Clock low */
+ bcm47xx_gpio_out(eesk, 0);
+ udelay(EECK_EDGE_TIME);
+
+ if (cs)
+ bcm47xx_gpio_out(eecs, 0);
+}
+
+
+/* Enable outputs with specified value to the chip */
+static void adm_enout(__u8 pins, __u8 val)
+{
+ /* Prepare GPIO output value */
+ bcm47xx_gpio_out(pins, val);
+
+ /* Enable GPIO outputs */
+ bcm47xx_gpio_outen(pins, pins);
+ udelay(EECK_EDGE_TIME);
+}
+
+
+/* Disable outputs to the chip */
+static void adm_disout(__u8 pins)
+{
+ /* Disable GPIO outputs */
+ bcm47xx_gpio_outen(pins, 0);
+ udelay(EECK_EDGE_TIME);
+}
+
+
+/* Advance clock(s) */
+static void adm_adclk(int clocks)
+{
+ int i;
+ for (i = 0; i < clocks; i++) {
+ /* Clock high */
+ bcm47xx_gpio_out(eesk, eesk);
+ udelay(EECK_EDGE_TIME);
+
+ /* Clock low */
+ bcm47xx_gpio_out(eesk, 0);
+ udelay(EECK_EDGE_TIME);
+ }
+}
+
+static __u32 adm_rreg(__u8 table, __u8 addr)
+{
+ /* cmd: 01 10 T DD R RRRRRR */
+ __u8 bits[6] = {
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ (0x06 << 4) | ((table & 0x01) << 3 | (addr&64)>>6),
+ ((addr&63)<<2)
+ };
+
+ __u8 rbits[4];
+
+ /* Enable GPIO outputs with all pins to 0 */
+ adm_enout((__u8)(eecs | eesk | eedi), 0);
+
+ adm_write(0, bits, 46);
+ adm_disout((__u8)(eedi));
+ adm_adclk(2);
+ adm_read (0, rbits, 32);
+
+ /* Extra clock(s) required per datasheet */
+ adm_adclk(2);
+
+ /* Disable GPIO outputs */
+ adm_disout((__u8)(eecs | eesk));
+
+ if (!table) /* EEPROM has 16-bit registers, but pumps out two registers in one request */
+ return (addr & 0x01 ? (rbits[0]<<8) | rbits[1] : (rbits[2]<<8) | (rbits[3]));
+ else
+ return (rbits[0]<<24) | (rbits[1]<<16) | (rbits[2]<<8) | rbits[3];
+}
+
+
+
+/* Write chip configuration register */
+/* Follow 93c66 timing and chip's min EEPROM timing requirement */
+void
+adm_wreg(__u8 addr, __u16 val)
+{
+ /* cmd(27bits): sb(1) + opc(01) + addr(bbbbbbbb) + data(bbbbbbbbbbbbbbbb) */
+ __u8 bits[4] = {
+ (0x05 << 5) | (addr >> 3),
+ (addr << 5) | (__u8)(val >> 11),
+ (__u8)(val >> 3),
+ (__u8)(val << 5)
+ };
+
+ /* Enable GPIO outputs with all pins to 0 */
+ adm_enout((__u8)(eecs | eesk | eedi), 0);
+
+ /* Write cmd. Total 27 bits */
+ adm_write(1, bits, 27);
+
+ /* Extra clock(s) required per datasheet */
+ adm_adclk(2);
+
+ /* Disable GPIO outputs */
+ adm_disout((__u8)(eecs | eesk | eedi));
+}
+
+
+/* Port configuration registers */
+static int port_conf[] = { 0x01, 0x03, 0x05, 0x07, 0x08, 0x09 };
+
+/* Bits in VLAN port mapping */
+static int vlan_ports[] = { 1 << 0, 1 << 2, 1 << 4, 1 << 6, 1 << 7, 1 << 8 };
+
+static int handle_vlan_port_read(void *driver, char *buf, int nr)
+{
+ int ports, i, c, len = 0;
+
+ if ((nr < 0) || (nr > 15))
+ return 0;
+
+ /* Get VLAN port map */
+ ports = adm_rreg(0, 0x13 + nr);
+
+ for (i = 0; i <= 5; i++) {
+ if (ports & vlan_ports[i]) {
+ c = adm_rreg(0, port_conf[i]);
+
+ len += sprintf(buf + len, "%d", i);
+ if (c & (1 << 4)) {
+ buf[len++] = 't';
+ if (((c & (0xf << 10)) >> 10) == nr)
+ buf[len++] = '*';
+ } else if (i == 5)
+ buf[len++] = 'u';
+
+ buf[len++] = '\t';
+ }
+ }
+ len += sprintf(buf + len, "\n");
+
+ return len;
+}
+
+static int handle_vlan_port_write(void *driver, char *buf, int nr)
+{
+ int i, cfg, ports;
+ switch_driver *d = (switch_driver *) driver;
+ switch_vlan_config *c = switch_parse_vlan(d, buf);
+
+ if (c == NULL)
+ return -1;
+
+ ports = adm_rreg(0, 0x13 + nr);
+ for (i = 0; i < d->ports; i++) {
+ if (c->port & (1 << i)) {
+ ports |= vlan_ports[i];
+
+ cfg = adm_rreg(0, port_conf[i]);
+
+ /* Tagging */
+ if (c->untag & (1 << i))
+ cfg &= ~(1 << 4);
+ else
+ cfg |= (1 << 4);
+
+ if ((c->untag | c->pvid) & (1 << i)) {
+ cfg = (cfg & ~(0xf << 10)) | (nr << 10);
+ }
+
+ adm_wreg(port_conf[i], (__u16) cfg);
+ } else {
+ ports &= ~(vlan_ports[i]);
+ }
+ }
+ adm_wreg(0x13 + nr, (__u16) ports);
+
+ kfree(c);
+ return 0;
+}
+
+static int handle_port_enable_read(void *driver, char *buf, int nr)
+{
+ return sprintf(buf, "%d\n", ((adm_rreg(0, port_conf[nr]) & (1 << 5)) ? 0 : 1));
+}
+
+static int handle_port_enable_write(void *driver, char *buf, int nr)
+{
+ int reg = adm_rreg(0, port_conf[nr]);
+
+ if (buf[0] == '0')
+ reg |= (1 << 5);
+ else if (buf[0] == '1')
+ reg &= ~(1 << 5);
+ else return -1;
+
+ adm_wreg(port_conf[nr], (__u16) reg);
+ return 0;
+}
+
+static int handle_port_media_read(void *driver, char *buf, int nr)
+{
+ int len;
+ int media = 0;
+ int reg = adm_rreg(0, port_conf[nr]);
+
+ if (reg & (1 << 1))
+ media |= SWITCH_MEDIA_AUTO;
+ if (reg & (1 << 2))
+ media |= SWITCH_MEDIA_100;
+ if (reg & (1 << 3))
+ media |= SWITCH_MEDIA_FD;
+
+ len = switch_print_media(buf, media);
+ return len + sprintf(buf + len, "\n");
+}
+
+static int handle_port_media_write(void *driver, char *buf, int nr)
+{
+ int media = switch_parse_media(buf);
+ int reg = adm_rreg(0, port_conf[nr]);
+
+ if (media < 0 || media & SWITCH_MEDIA_1000)
+ return -1;
+
+ reg &= ~((1 << 1) | (1 << 2) | (1 << 3));
+ if (media & SWITCH_MEDIA_AUTO)
+ reg |= 1 << 1;
+ if (media & SWITCH_MEDIA_100)
+ reg |= 1 << 2;
+ if (media & SWITCH_MEDIA_FD)
+ reg |= 1 << 3;
+
+ adm_wreg(port_conf[nr], reg);
+
+ return 0;
+}
+
+static int handle_vlan_enable_read(void *driver, char *buf, int nr)
+{
+ return sprintf(buf, "%d\n", ((adm_rreg(0, 0x11) & (1 << 5)) ? 1 : 0));
+}
+
+static int handle_vlan_enable_write(void *driver, char *buf, int nr)
+{
+ int reg = adm_rreg(0, 0x11);
+
+ if (buf[0] == '1')
+ reg |= (1 << 5);
+ else if (buf[0] == '0')
+ reg &= ~(1 << 5);
+ else return -1;
+
+ adm_wreg(0x11, (__u16) reg);
+ return 0;
+}
+
+static int handle_reset(void *driver, char *buf, int nr)
+{
+ int i;
+ u32 cfg;
+
+ /*
+ * Reset sequence: RC high->low(100ms)->high(30ms)
+ *
+ * WAR: Certain boards don't have the correct power on
+ * reset logic therefore we must explicitly perform the
+ * sequence in software.
+ */
+ if (eerc) {
+ /* Keep RC high for at least 20ms */
+ adm_enout(eerc, eerc);
+ for (i = 0; i < 20; i ++)
+ udelay(1000);
+ /* Keep RC low for at least 100ms */
+ adm_enout(eerc, 0);
+ for (i = 0; i < 100; i++)
+ udelay(1000);
+ /* Set default configuration */
+ adm_enout((__u8)(eesk | eedi), eesk);
+ /* Keep RC high for at least 30ms */
+ adm_enout(eerc, eerc);
+ for (i = 0; i < 30; i++)
+ udelay(1000);
+ /* Leave RC high and disable GPIO outputs */
+ adm_disout((__u8)(eecs | eesk | eedi));
+
+ }
+
+ /* set up initial configuration for cpu port */
+ cfg = (0x8000 | /* Auto MDIX */
+ (0xf << 10) | /* PVID */
+ (1 << 4) | /* Tagging */
+ 0xf); /* full duplex, 100Mbps, auto neg, flow ctrl */
+ adm_wreg(port_conf[5], cfg);
+
+ /* vlan mode select register (0x11): vlan on, mac clone */
+ adm_wreg(0x11, 0xff30);
+
+ return 0;
+}
+
+static int handle_registers(void *driver, char *buf, int nr)
+{
+ int i, len = 0;
+
+ for (i = 0; i <= 0x33; i++) {
+ len += sprintf(buf + len, "0x%02x: 0x%04x\n", i, adm_rreg(0, i));
+ }
+
+ return len;
+}
+
+static int handle_counters(void *driver, char *buf, int nr)
+{
+ int i, len = 0;
+
+ for (i = 0; i <= 0x3c; i++) {
+ len += sprintf(buf + len, "0x%02x: 0x%08x\n", i, adm_rreg(1, i));
+ }
+
+ return len;
+}
+
+static int detect_adm(void)
+{
+ int ret = 0;
+
+#ifdef CONFIG_BCM47XX
+ char buf[20];
+ int boardflags = 0;
+ int boardnum = 0;
+
+ if (bcm47xx_nvram_getenv("boardflags", buf, sizeof(buf)) >= 0)
+ boardflags = simple_strtoul(buf, NULL, 0);
+
+ if (bcm47xx_nvram_getenv("boardnum", buf, sizeof(buf)) >= 0)
+ boardnum = simple_strtoul(buf, NULL, 0);
+
+ if ((boardnum == 44) && (boardflags == 0x0388)) { /* Trendware TEW-411BRP+ */
+ ret = 1;
+
+ eecs = get_gpiopin("adm_eecs", 2);
+ eesk = get_gpiopin("adm_eesk", 3);
+ eedi = get_gpiopin("adm_eedi", 4);
+ eerc = get_gpiopin("adm_rc", 5);
+
+ } else if ((boardflags & 0x80) || force) {
+ ret = 1;
+
+ eecs = get_gpiopin("adm_eecs", 2);
+ eesk = get_gpiopin("adm_eesk", 3);
+ eedi = get_gpiopin("adm_eedi", 4);
+ eerc = get_gpiopin("adm_rc", 0);
+
+ } else if (bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) {
+ if (strcmp(buf, "bcm94710dev") == 0) {
+ if (bcm47xx_nvram_getenv("boardnum", buf, sizeof(buf)) >= 0) {
+ if (strncmp(buf, "42", 2) == 0) {
+ /* WRT54G v1.1 hack */
+ eecs = 2;
+ eesk = 3;
+ eedi = 5;
+
+ ret = 1;
+ }
+ }
+ }
+ }
+
+ if (eecs)
+ eecs = (1 << eecs);
+ if (eesk)
+ eesk = (1 << eesk);
+ if (eedi)
+ eedi = (1 << eedi);
+ if (eerc)
+ eerc = (1 << eerc);
+#else
+ ret = 1;
+#endif
+
+ return ret;
+}
+
+static int __init adm_init(void)
+{
+ switch_config cfg[] = {
+ {"registers", handle_registers, NULL},
+ {"counters", handle_counters, NULL},
+ {"reset", NULL, handle_reset},
+ {"enable_vlan", handle_vlan_enable_read, handle_vlan_enable_write},
+ {NULL, NULL, NULL}
+ };
+ switch_config port[] = {
+ {"enable", handle_port_enable_read, handle_port_enable_write},
+ {"media", handle_port_media_read, handle_port_media_write},
+ {NULL, NULL, NULL}
+ };
+ switch_config vlan[] = {
+ {"ports", handle_vlan_port_read, handle_vlan_port_write},
+ {NULL, NULL, NULL}
+ };
+ switch_driver driver = {
+ name: DRIVER_NAME,
+ version: DRIVER_VERSION,
+ interface: "eth0",
+ ports: 6,
+ cpuport: 5,
+ vlans: 16,
+ driver_handlers: cfg,
+ port_handlers: port,
+ vlan_handlers: vlan,
+ };
+ snprintf(driver.dev_name, SWITCH_NAME_BUFSZ, DRIVER_NAME);
+
+ if (!detect_adm())
+ return -ENODEV;
+
+ return switch_register_driver(&driver);
+}
+
+static void __exit adm_exit(void)
+{
+ switch_unregister_driver(DRIVER_NAME);
+}
+
+
+module_init(adm_init);
+module_exit(adm_exit);
diff --git a/package/kernel/switch/src/switch-core.c b/package/kernel/switch/src/switch-core.c
new file mode 100644
index 0000000000..fc8a6bf2c7
--- /dev/null
+++ b/package/kernel/switch/src/switch-core.c
@@ -0,0 +1,527 @@
+/*
+ * switch-core.c
+ *
+ * Copyright (C) 2005 Felix Fietkau <openwrt@nbd.name>
+ *
+ * This program is free software; 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.
+ *
+ *
+ * Basic doc of driver's /proc interface:
+ * /proc/switch/<interface>/
+ * registers: read-only
+ * counters: read-only
+ * reset: write causes hardware reset
+ * enable_vlan: "0", "1"
+ * port/<port-number>/
+ * enabled: "0", "1"
+ * media: "AUTO", "1000FD", "1000HD", "100FD", "100HD", "10FD", "10HD"
+ * vlan/<port-number>/
+ * ports: same syntax as for nvram's vlan*ports (eg. "1 2 3 4 5*")
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+
+#include "switch-core.h"
+
+static int drv_num = 0;
+static struct proc_dir_entry *switch_root;
+switch_driver drivers;
+
+typedef struct {
+ struct list_head list;
+ struct proc_dir_entry *parent;
+ int nr;
+ void *driver;
+ switch_config handler;
+} switch_proc_handler;
+
+typedef struct {
+ struct proc_dir_entry *driver_dir, *port_dir, *vlan_dir;
+ struct proc_dir_entry **ports, **vlans;
+ switch_proc_handler data;
+ int nr;
+} switch_priv;
+
+static ssize_t switch_proc_read(struct file *file, char *buf, size_t count, loff_t *ppos);
+static ssize_t switch_proc_write(struct file *file, const char *buf, size_t count, void *data);
+
+static struct file_operations switch_proc_fops = {
+ .read = (ssize_t (*) (struct file *, char __user *, size_t, loff_t *))switch_proc_read,
+ .write = (ssize_t (*) (struct file *, const char __user *, size_t, loff_t *))switch_proc_write
+};
+
+static ssize_t switch_proc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+ struct proc_dir_entry *dent = PDE(file->f_dentry->d_inode);
+ char *page;
+ int len = 0;
+
+ if ((page = kmalloc(SWITCH_MAX_BUFSZ, GFP_KERNEL)) == NULL)
+ return -ENOBUFS;
+
+ if (dent->data != NULL) {
+ switch_proc_handler *handler = (switch_proc_handler *) dent->data;
+ if (handler->handler.read != NULL)
+ len += handler->handler.read(handler->driver, page + len, handler->nr);
+ }
+ len += 1;
+
+ if (*ppos < len) {
+ len = min_t(int, len - *ppos, count);
+ if (copy_to_user(buf, (page + *ppos), len)) {
+ kfree(page);
+ return -EFAULT;
+ }
+ *ppos += len;
+ } else {
+ len = 0;
+ }
+
+ kfree(page);
+ return len;
+}
+
+
+static ssize_t switch_proc_write(struct file *file, const char *buf, size_t count, void *data)
+{
+ struct proc_dir_entry *dent = PDE(file->f_dentry->d_inode);
+ char *page;
+ int ret = -EINVAL;
+
+ if ((page = kmalloc(count + 1, GFP_KERNEL)) == NULL)
+ return -ENOBUFS;
+
+ if (copy_from_user(page, buf, count)) {
+ kfree(page);
+ return -EINVAL;
+ }
+ page[count] = 0;
+
+ if (dent->data != NULL) {
+ switch_proc_handler *handler = (switch_proc_handler *) dent->data;
+ if (handler->handler.write != NULL) {
+ if ((ret = handler->handler.write(handler->driver, page, handler->nr)) >= 0)
+ ret = count;
+ }
+ }
+
+ kfree(page);
+ return ret;
+}
+
+static int handle_driver_name(void *driver, char *buf, int nr)
+{
+ const char *name = ((switch_driver *) driver)->name;
+ return sprintf(buf, "%s\n", name);
+}
+
+static int handle_driver_version(void *driver, char *buf, int nr)
+{
+ const char *version = ((switch_driver *) driver)->version;
+ strcpy(buf, version);
+ return sprintf(buf, "%s\n", version);
+}
+
+static int handle_driver_cpuport(void *driver, char *buf, int nr)
+{
+ int cpuport = ((switch_driver *) driver)->cpuport;
+ return sprintf(buf, "%i\n", cpuport);
+}
+
+static int handle_driver_ports(void *driver, char *buf, int nr)
+{
+ int ports = ((switch_driver *) driver)->ports;
+ return sprintf(buf, "%i\n", ports);
+}
+
+static int handle_driver_vlans(void *driver, char *buf, int nr)
+{
+ int vlans = ((switch_driver *) driver)->vlans;
+ return sprintf(buf, "%i\n", vlans);
+}
+
+static int handle_driver_dev_name(void *driver, char *buf, int nr)
+{
+ char *dev_name = ((switch_driver *) driver)->dev_name;
+ return sprintf(buf, "%s\n", dev_name);
+}
+
+static void add_handler(switch_driver *driver, const switch_config *handler, struct proc_dir_entry *parent, int nr)
+{
+ switch_priv *priv = (switch_priv *) driver->data;
+ struct proc_dir_entry *p;
+ int mode;
+
+ switch_proc_handler *tmp;
+ tmp = (switch_proc_handler *) kmalloc(sizeof(switch_proc_handler), GFP_KERNEL);
+ if (!tmp)
+ return;
+ INIT_LIST_HEAD(&tmp->list);
+ tmp->parent = parent;
+ tmp->nr = nr;
+ tmp->driver = driver;
+ memcpy(&tmp->handler, handler, sizeof(switch_config));
+ list_add(&tmp->list, &priv->data.list);
+
+ mode = 0;
+ if (handler->read != NULL) mode |= S_IRUSR;
+ if (handler->write != NULL) mode |= S_IWUSR;
+
+ if ((p = create_proc_entry(handler->name, mode, parent)) != NULL) {
+ p->data = (void *) tmp;
+ p->proc_fops = &switch_proc_fops;
+ }
+}
+
+static inline void add_handlers(switch_driver *driver, const switch_config *handlers, struct proc_dir_entry *parent, int nr)
+{
+ int i;
+
+ for (i = 0; handlers[i].name != NULL; i++) {
+ add_handler(driver, &(handlers[i]), parent, nr);
+ }
+}
+
+static void remove_handlers(switch_priv *priv)
+{
+ struct list_head *pos, *q;
+ switch_proc_handler *tmp;
+
+ list_for_each_safe(pos, q, &priv->data.list) {
+ tmp = list_entry(pos, switch_proc_handler, list);
+ list_del(pos);
+ remove_proc_entry(tmp->handler.name, tmp->parent);
+ kfree(tmp);
+ }
+}
+
+
+static void do_unregister(switch_driver *driver)
+{
+ char buf[4];
+ int i;
+ switch_priv *priv = (switch_priv *) driver->data;
+
+ remove_handlers(priv);
+
+ for(i = 0; priv->ports[i] != NULL; i++) {
+ sprintf(buf, "%d", i);
+ remove_proc_entry(buf, priv->port_dir);
+ }
+ kfree(priv->ports);
+ remove_proc_entry("port", priv->driver_dir);
+
+ for(i = 0; priv->vlans[i] != NULL; i++) {
+ sprintf(buf, "%d", i);
+ remove_proc_entry(buf, priv->vlan_dir);
+ }
+ kfree(priv->vlans);
+ remove_proc_entry("vlan", priv->driver_dir);
+
+ remove_proc_entry(driver->interface, switch_root);
+
+ if (priv->nr == (drv_num - 1))
+ drv_num--;
+
+ kfree(priv);
+}
+
+switch_config global_driver_handlers[] = {
+ {"driver", handle_driver_name, NULL},
+ {"version", handle_driver_version, NULL},
+ {"cpuport", handle_driver_cpuport, NULL},
+ {"ports", handle_driver_ports, NULL},
+ {"vlans", handle_driver_vlans, NULL},
+ {"dev_name", handle_driver_dev_name, NULL},
+ {NULL, NULL, NULL}
+};
+
+static int do_register(switch_driver *driver)
+{
+ switch_priv *priv;
+ int i;
+ char buf[4];
+
+ priv = kmalloc(sizeof(switch_priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ driver->data = (void *) priv;
+
+ priv->ports = kmalloc((driver->ports + 1) * sizeof(struct proc_dir_entry *),
+ GFP_KERNEL);
+ if (!priv->ports) {
+ kfree(priv);
+ return -ENOMEM;
+ }
+ priv->vlans = kmalloc((driver->vlans + 1) * sizeof(struct proc_dir_entry *),
+ GFP_KERNEL);
+ if (!priv->vlans) {
+ kfree(priv->ports);
+ kfree(priv);
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&priv->data.list);
+
+ priv->nr = drv_num++;
+ priv->driver_dir = proc_mkdir(driver->interface, switch_root);
+ if (driver->driver_handlers != NULL) {
+ add_handlers(driver, driver->driver_handlers, priv->driver_dir, 0);
+ add_handlers(driver, global_driver_handlers, priv->driver_dir, 0);
+ }
+
+ priv->port_dir = proc_mkdir("port", priv->driver_dir);
+ for (i = 0; i < driver->ports; i++) {
+ sprintf(buf, "%d", i);
+ priv->ports[i] = proc_mkdir(buf, priv->port_dir);
+ if (driver->port_handlers != NULL)
+ add_handlers(driver, driver->port_handlers, priv->ports[i], i);
+ }
+ priv->ports[i] = NULL;
+
+ priv->vlan_dir = proc_mkdir("vlan", priv->driver_dir);
+ for (i = 0; i < driver->vlans; i++) {
+ sprintf(buf, "%d", i);
+ priv->vlans[i] = proc_mkdir(buf, priv->vlan_dir);
+ if (driver->vlan_handlers != NULL)
+ add_handlers(driver, driver->vlan_handlers, priv->vlans[i], i);
+ }
+ priv->vlans[i] = NULL;
+
+
+ return 0;
+}
+
+static inline int isspace(char c) {
+ switch(c) {
+ case ' ':
+ case 0x09:
+ case 0x0a:
+ case 0x0d:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+#define toupper(c) (islower(c) ? ((c) ^ 0x20) : (c))
+#define islower(c) (((unsigned char)((c) - 'a')) < 26)
+
+int switch_parse_media(char *buf)
+{
+ char *str = buf;
+ while (*buf != 0) {
+ *buf = toupper(*buf);
+ buf++;
+ }
+
+ if (strncmp(str, "AUTO", 4) == 0)
+ return SWITCH_MEDIA_AUTO;
+ else if (strncmp(str, "1000FD", 6) == 0)
+ return SWITCH_MEDIA_1000 | SWITCH_MEDIA_FD;
+ else if (strncmp(str, "1000HD", 6) == 0)
+ return SWITCH_MEDIA_1000;
+ else if (strncmp(str, "100FD", 5) == 0)
+ return SWITCH_MEDIA_100 | SWITCH_MEDIA_FD;
+ else if (strncmp(str, "100HD", 5) == 0)
+ return SWITCH_MEDIA_100;
+ else if (strncmp(str, "10FD", 4) == 0)
+ return SWITCH_MEDIA_FD;
+ else if (strncmp(str, "10HD", 4) == 0)
+ return 0;
+ else return -1;
+}
+
+int switch_print_media(char *buf, int media)
+{
+ int len = 0;
+
+ if (media & SWITCH_MEDIA_AUTO)
+ len = sprintf(buf, "Auto");
+ else if (media == (SWITCH_MEDIA_1000 | SWITCH_MEDIA_FD))
+ len = sprintf(buf, "1000FD");
+ else if (media == SWITCH_MEDIA_1000)
+ len = sprintf(buf, "1000HD");
+ else if (media == (SWITCH_MEDIA_100 | SWITCH_MEDIA_FD))
+ len = sprintf(buf, "100FD");
+ else if (media == SWITCH_MEDIA_100)
+ len = sprintf(buf, "100HD");
+ else if (media == SWITCH_MEDIA_FD)
+ len = sprintf(buf, "10FD");
+ else if (media == 0)
+ len = sprintf(buf, "10HD");
+ else
+ len = sprintf(buf, "Invalid");
+
+ return len;
+}
+
+switch_vlan_config *switch_parse_vlan(switch_driver *driver, char *buf)
+{
+ switch_vlan_config *c;
+ int j, u, p, s;
+
+ c = kzalloc(sizeof(switch_vlan_config), GFP_KERNEL);
+ if (!c)
+ return NULL;
+
+ while (isspace(*buf)) buf++;
+ j = 0;
+ while (*buf >= '0' && *buf <= '9') {
+ j *= 10;
+ j += *buf++ - '0';
+
+ u = ((j == driver->cpuport) ? 0 : 1);
+ p = 0;
+ s = !(*buf >= '0' && *buf <= '9');
+
+ if (s) {
+ while (s && !isspace(*buf) && (*buf != 0)) {
+ switch(*buf) {
+ case 'u':
+ u = 1;
+ break;
+ case 't':
+ u = 0;
+ break;
+ case '*':
+ p = 1;
+ break;
+ }
+ buf++;
+ }
+ c->port |= (1 << j);
+ if (u)
+ c->untag |= (1 << j);
+ if (p)
+ c->pvid |= (1 << j);
+
+ j = 0;
+ }
+
+ while (isspace(*buf)) buf++;
+ }
+ if (*buf != 0) {
+ kfree(c);
+ return NULL;
+ }
+
+ c->port &= (1 << driver->ports) - 1;
+ c->untag &= (1 << driver->ports) - 1;
+ c->pvid &= (1 << driver->ports) - 1;
+
+ return c;
+}
+
+
+int switch_device_registered (char* device) {
+ struct list_head *pos;
+
+ list_for_each(pos, &drivers.list) {
+ if (strcmp(list_entry(pos, switch_driver, list)->interface, device) == 0) {
+ printk("There is already a switch registered on the device '%s'\n", device);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+
+int switch_register_driver(switch_driver *driver)
+{
+ struct list_head *pos;
+ switch_driver *new;
+ int ret;
+
+ list_for_each(pos, &drivers.list) {
+ if (strcmp(list_entry(pos, switch_driver, list)->name, driver->name) == 0) {
+ printk("Switch driver '%s' already exists in the kernel\n", driver->name);
+ return -EINVAL;
+ }
+ if (strcmp(list_entry(pos, switch_driver, list)->interface, driver->interface) == 0) {
+ printk("There is already a switch registered on the device '%s'\n", driver->interface);
+ return -EINVAL;
+ }
+ }
+
+ new = kmalloc(sizeof(switch_driver), GFP_KERNEL);
+ if (!new)
+ return -ENOMEM;
+ memcpy(new, driver, sizeof(switch_driver));
+ new->name = strdup(driver->name);
+ new->interface = strdup(driver->interface);
+
+ if ((ret = do_register(new)) < 0) {
+ kfree(new->name);
+ kfree(new);
+ return ret;
+ }
+ INIT_LIST_HEAD(&new->list);
+ list_add(&new->list, &drivers.list);
+
+ return 0;
+}
+
+void switch_unregister_driver(char *name) {
+ struct list_head *pos, *q;
+ switch_driver *tmp;
+
+ list_for_each_safe(pos, q, &drivers.list) {
+ tmp = list_entry(pos, switch_driver, list);
+ if (strcmp(tmp->name, name) == 0) {
+ do_unregister(tmp);
+ list_del(pos);
+ kfree(tmp->name);
+ kfree(tmp);
+
+ return;
+ }
+ }
+}
+
+static int __init switch_init(void)
+{
+ if ((switch_root = proc_mkdir("switch", NULL)) == NULL) {
+ printk("%s: proc_mkdir failed.\n", __FILE__);
+ return -ENODEV;
+ }
+
+ INIT_LIST_HEAD(&drivers.list);
+
+ return 0;
+}
+
+static void __exit switch_exit(void)
+{
+ remove_proc_entry("switch", NULL);
+}
+
+MODULE_AUTHOR("Felix Fietkau <openwrt@nbd.name>");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(switch_device_registered);
+EXPORT_SYMBOL(switch_register_driver);
+EXPORT_SYMBOL(switch_unregister_driver);
+EXPORT_SYMBOL(switch_parse_vlan);
+EXPORT_SYMBOL(switch_parse_media);
+EXPORT_SYMBOL(switch_print_media);
+
+module_init(switch_init);
+module_exit(switch_exit);
diff --git a/package/kernel/switch/src/switch-core.h b/package/kernel/switch/src/switch-core.h
new file mode 100644
index 0000000000..cc520e4935
--- /dev/null
+++ b/package/kernel/switch/src/switch-core.h
@@ -0,0 +1,55 @@
+#ifndef __SWITCH_CORE_H
+#define __SWITCH_CORE_H
+
+#include <linux/version.h>
+#include <linux/list.h>
+#define SWITCH_MAX_BUFSZ 4096
+#define SWITCH_NAME_BUFSZ 16
+
+#define SWITCH_MEDIA_AUTO 1
+#define SWITCH_MEDIA_100 2
+#define SWITCH_MEDIA_FD 4
+#define SWITCH_MEDIA_1000 8
+
+typedef int (*switch_handler)(void *driver, char *buf, int nr);
+
+typedef struct {
+ const char *name;
+ switch_handler read, write;
+} switch_config;
+
+typedef struct {
+ struct list_head list;
+ const char *name;
+ const char *version;
+ const char *interface;
+ int cpuport;
+ int ports;
+ int vlans;
+ const switch_config *driver_handlers, *port_handlers, *vlan_handlers;
+ void *data;
+ void *priv;
+ char dev_name[SWITCH_NAME_BUFSZ];
+} switch_driver;
+
+typedef struct {
+ u32 port, untag, pvid;
+} switch_vlan_config;
+
+
+extern int switch_device_registered (char* device);
+extern int switch_register_driver(switch_driver *driver);
+extern void switch_unregister_driver(char *name);
+extern switch_vlan_config *switch_parse_vlan(switch_driver *driver, char *buf);
+extern int switch_parse_media(char *buf);
+extern int switch_print_media(char *buf, int media);
+
+static inline char *strdup(const char *str)
+{
+ char *new = kmalloc(strlen(str) + 1, GFP_KERNEL);
+ strcpy(new, str);
+ return new;
+}
+
+
+#endif
diff --git a/package/kernel/switch/src/switch-robo.c b/package/kernel/switch/src/switch-robo.c
new file mode 100644
index 0000000000..f7159729b8
--- /dev/null
+++ b/package/kernel/switch/src/switch-robo.c
@@ -0,0 +1,892 @@
+/*
+ * Broadcom BCM5325E/536x switch configuration module
+ *
+ * Copyright (C) 2005 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2008 Michael Buesch <mb@bu3sch.de>
+ * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
+ * Based on 'robocfg' by Oleg I. Vdovikin
+ *
+ * This program is free software; 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/init.h>
+#include <linux/if.h>
+#include <linux/if_arp.h>
+#include <linux/sockios.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+
+#include "switch-core.h"
+#include "etc53xx.h"
+
+#ifdef CONFIG_BCM47XX
+#include <bcm47xx_nvram.h>
+#endif
+
+#define DRIVER_NAME "bcm53xx"
+#define DRIVER_VERSION "0.03"
+#define PFX "roboswitch: "
+
+#define ROBO_PHY_ADDR 0x1E /* robo switch phy address */
+#define ROBO_PHY_ADDR_TG3 0x01 /* Tigon3 PHY address */
+#define ROBO_PHY_ADDR_BCM63XX 0x00 /* BCM63XX PHY address */
+
+/* MII registers */
+#define REG_MII_PAGE 0x10 /* MII Page register */
+#define REG_MII_ADDR 0x11 /* MII Address register */
+#define REG_MII_DATA0 0x18 /* MII Data register 0 */
+
+#define REG_MII_PAGE_ENABLE 1
+#define REG_MII_ADDR_WRITE 1
+#define REG_MII_ADDR_READ 2
+
+/* Robo device ID register (in ROBO_MGMT_PAGE) */
+#define ROBO_DEVICE_ID 0x30
+#define ROBO_DEVICE_ID_5325 0x25 /* Faked */
+#define ROBO_DEVICE_ID_5395 0x95
+#define ROBO_DEVICE_ID_5397 0x97
+#define ROBO_DEVICE_ID_5398 0x98
+#define ROBO_DEVICE_ID_53115 0x3115
+#define ROBO_DEVICE_ID_53125 0x3125
+
+/* Private et.o ioctls */
+#define SIOCGETCPHYRD (SIOCDEVPRIVATE + 9)
+#define SIOCSETCPHYWR (SIOCDEVPRIVATE + 10)
+
+/* Data structure for a Roboswitch device. */
+struct robo_switch {
+ char *device; /* The device name string (ethX) */
+ u16 devid; /* ROBO_DEVICE_ID_53xx */
+ bool is_5365;
+ bool gmii; /* gigabit mii */
+ u8 corerev;
+ int gpio_robo_reset;
+ int gpio_lanports_enable;
+ struct ifreq ifr;
+ struct net_device *dev;
+ unsigned char port[9];
+};
+
+/* Currently we can only have one device in the system. */
+static struct robo_switch robo;
+
+
+static int do_ioctl(int cmd)
+{
+ mm_segment_t old_fs = get_fs();
+ int ret;
+
+ set_fs(KERNEL_DS);
+ ret = robo.dev->netdev_ops->ndo_do_ioctl(robo.dev, &robo.ifr, cmd);
+ set_fs(old_fs);
+
+ return ret;
+}
+
+static u16 mdio_read(__u16 phy_id, __u8 reg)
+{
+ struct mii_ioctl_data *mii = if_mii(&robo.ifr);
+ int err;
+
+ mii->phy_id = phy_id;
+ mii->reg_num = reg;
+
+ err = do_ioctl(SIOCGMIIREG);
+ if (err < 0) {
+ printk(KERN_ERR PFX "failed to read mdio reg %i with err %i.\n", reg, err);
+
+ return 0xffff;
+ }
+
+ return mii->val_out;
+}
+
+static void mdio_write(__u16 phy_id, __u8 reg, __u16 val)
+{
+ struct mii_ioctl_data *mii = if_mii(&robo.ifr);
+ int err;
+
+ mii->phy_id = phy_id;
+ mii->reg_num = reg;
+ mii->val_in = val;
+
+ err = do_ioctl(SIOCSMIIREG);
+ if (err < 0) {
+ printk(KERN_ERR PFX "failed to write mdio reg: %i with err %i.\n", reg, err);
+ return;
+ }
+}
+
+static int robo_reg(__u8 page, __u8 reg, __u8 op)
+{
+ int i = 3;
+
+ /* set page number */
+ mdio_write(ROBO_PHY_ADDR, REG_MII_PAGE,
+ (page << 8) | REG_MII_PAGE_ENABLE);
+
+ /* set register address */
+ mdio_write(ROBO_PHY_ADDR, REG_MII_ADDR,
+ (reg << 8) | op);
+
+ /* check if operation completed */
+ while (i--) {
+ if ((mdio_read(ROBO_PHY_ADDR, REG_MII_ADDR) & 3) == 0)
+ return 0;
+ }
+
+ printk(KERN_ERR PFX "timeout in robo_reg on page %i and reg %i with op %i.\n", page, reg, op);
+
+ return 1;
+}
+
+/*
+static void robo_read(__u8 page, __u8 reg, __u16 *val, int count)
+{
+ int i;
+
+ robo_reg(page, reg, REG_MII_ADDR_READ);
+
+ for (i = 0; i < count; i++)
+ val[i] = mdio_read(ROBO_PHY_ADDR, REG_MII_DATA0 + i);
+}
+*/
+
+static __u16 robo_read16(__u8 page, __u8 reg)
+{
+ robo_reg(page, reg, REG_MII_ADDR_READ);
+
+ return mdio_read(ROBO_PHY_ADDR, REG_MII_DATA0);
+}
+
+static __u32 robo_read32(__u8 page, __u8 reg)
+{
+ robo_reg(page, reg, REG_MII_ADDR_READ);
+
+ return mdio_read(ROBO_PHY_ADDR, REG_MII_DATA0) |
+ (mdio_read(ROBO_PHY_ADDR, REG_MII_DATA0 + 1) << 16);
+}
+
+static void robo_write16(__u8 page, __u8 reg, __u16 val16)
+{
+ /* write data */
+ mdio_write(ROBO_PHY_ADDR, REG_MII_DATA0, val16);
+
+ robo_reg(page, reg, REG_MII_ADDR_WRITE);
+}
+
+static void robo_write32(__u8 page, __u8 reg, __u32 val32)
+{
+ /* write data */
+ mdio_write(ROBO_PHY_ADDR, REG_MII_DATA0, val32 & 0xFFFF);
+ mdio_write(ROBO_PHY_ADDR, REG_MII_DATA0 + 1, val32 >> 16);
+
+ robo_reg(page, reg, REG_MII_ADDR_WRITE);
+}
+
+/* checks that attached switch is 5365 */
+static bool robo_bcm5365(void)
+{
+ /* set vlan access id to 15 and read it back */
+ __u16 val16 = 15;
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16);
+
+ /* 5365 will refuse this as it does not have this reg */
+ return robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS) != val16;
+}
+
+static bool robo_gmii(void)
+{
+ if (mdio_read(0, ROBO_MII_STAT) & 0x0100)
+ return ((mdio_read(0, 0x0f) & 0xf000) != 0);
+ return false;
+}
+
+static int robo_switch_enable(void)
+{
+ unsigned int i, last_port;
+ u16 val;
+#ifdef CONFIG_BCM47XX
+ char buf[20];
+#endif
+
+ val = robo_read16(ROBO_CTRL_PAGE, ROBO_SWITCH_MODE);
+ if (!(val & (1 << 1))) {
+ /* Unmanaged mode */
+ val &= ~(1 << 0);
+ /* With forwarding */
+ val |= (1 << 1);
+ robo_write16(ROBO_CTRL_PAGE, ROBO_SWITCH_MODE, val);
+ val = robo_read16(ROBO_CTRL_PAGE, ROBO_SWITCH_MODE);
+ if (!(val & (1 << 1))) {
+ printk(KERN_ERR PFX "Failed to enable switch\n");
+ return -EBUSY;
+ }
+
+ /* No spanning tree for unmanaged mode */
+ last_port = (robo.devid == ROBO_DEVICE_ID_5398) ?
+ ROBO_PORT7_CTRL : ROBO_PORT4_CTRL;
+ for (i = ROBO_PORT0_CTRL; i <= last_port; i++)
+ robo_write16(ROBO_CTRL_PAGE, i, 0);
+
+ /* No spanning tree on IMP port too */
+ robo_write16(ROBO_CTRL_PAGE, ROBO_IM_PORT_CTRL, 0);
+ }
+
+ if (robo.devid == ROBO_DEVICE_ID_53125) {
+ /* Make IM port status link by default */
+ val = robo_read16(ROBO_CTRL_PAGE, ROBO_PORT_OVERRIDE_CTRL) | 0xb1;
+ robo_write16(ROBO_CTRL_PAGE, ROBO_PORT_OVERRIDE_CTRL, val);
+ // TODO: init EEE feature
+ }
+
+#ifdef CONFIG_BCM47XX
+ /* WAN port LED, except for Netgear WGT634U */
+ if (bcm47xx_nvram_getenv("nvram_type", buf, sizeof(buf)) >= 0) {
+ if (strcmp(buf, "cfe") != 0)
+ robo_write16(ROBO_CTRL_PAGE, 0x16, 0x1F);
+ }
+#endif
+ return 0;
+}
+
+static void robo_switch_reset(void)
+{
+ if ((robo.devid == ROBO_DEVICE_ID_5395) ||
+ (robo.devid == ROBO_DEVICE_ID_5397) ||
+ (robo.devid == ROBO_DEVICE_ID_5398)) {
+ /* Trigger a software reset. */
+ robo_write16(ROBO_CTRL_PAGE, 0x79, 0x83);
+ mdelay(500);
+ robo_write16(ROBO_CTRL_PAGE, 0x79, 0);
+ }
+}
+
+#ifdef CONFIG_BCM47XX
+static int get_gpio_pin(const char *name)
+{
+ int i, err;
+ char nvram_var[10];
+ char buf[30];
+
+ for (i = 0; i < 16; i++) {
+ err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i);
+ if (err <= 0)
+ continue;
+ err = bcm47xx_nvram_getenv(nvram_var, buf, sizeof(buf));
+ if (err <= 0)
+ continue;
+ if (!strcmp(name, buf))
+ return i;
+ }
+ return -1;
+}
+#endif
+
+static int robo_probe(char *devname)
+{
+ __u32 phyid;
+ unsigned int i;
+ int err = -1;
+ struct mii_ioctl_data *mii;
+
+ printk(KERN_INFO PFX "Probing device '%s'\n", devname);
+ strcpy(robo.ifr.ifr_name, devname);
+
+ if ((robo.dev = dev_get_by_name(&init_net, devname)) == NULL) {
+ printk(KERN_ERR PFX "No such device\n");
+ err = -ENODEV;
+ goto err_done;
+ }
+ if (!robo.dev->netdev_ops || !robo.dev->netdev_ops->ndo_do_ioctl) {
+ printk(KERN_ERR PFX "ndo_do_ioctl not implemented in ethernet driver\n");
+ err = -ENXIO;
+ goto err_put;
+ }
+
+ robo.device = devname;
+
+ /* try access using MII ioctls - get phy address */
+ err = do_ioctl(SIOCGMIIPHY);
+ if (err < 0) {
+ printk(KERN_ERR PFX "error (%i) while accessing MII phy registers with ioctls\n", err);
+ goto err_put;
+ }
+
+ /* got phy address check for robo address */
+ mii = if_mii(&robo.ifr);
+ if ((mii->phy_id != ROBO_PHY_ADDR) &&
+ (mii->phy_id != ROBO_PHY_ADDR_BCM63XX) &&
+ (mii->phy_id != ROBO_PHY_ADDR_TG3)) {
+ printk(KERN_ERR PFX "Invalid phy address (%d)\n", mii->phy_id);
+ err = -ENODEV;
+ goto err_put;
+ }
+
+#ifdef CONFIG_BCM47XX
+ robo.gpio_lanports_enable = get_gpio_pin("lanports_enable");
+ if (robo.gpio_lanports_enable >= 0) {
+ err = gpio_request(robo.gpio_lanports_enable, "lanports_enable");
+ if (err) {
+ printk(KERN_ERR PFX "error (%i) requesting lanports_enable gpio (%i)\n",
+ err, robo.gpio_lanports_enable);
+ goto err_put;
+ }
+ gpio_direction_output(robo.gpio_lanports_enable, 1);
+ mdelay(5);
+ }
+
+ robo.gpio_robo_reset = get_gpio_pin("robo_reset");
+ if (robo.gpio_robo_reset >= 0) {
+ err = gpio_request(robo.gpio_robo_reset, "robo_reset");
+ if (err) {
+ printk(KERN_ERR PFX "error (%i) requesting robo_reset gpio (%i)\n",
+ err, robo.gpio_robo_reset);
+ goto err_gpio_robo;
+ }
+ gpio_set_value(robo.gpio_robo_reset, 0);
+ gpio_direction_output(robo.gpio_robo_reset, 1);
+ gpio_set_value(robo.gpio_robo_reset, 0);
+ mdelay(50);
+
+ gpio_set_value(robo.gpio_robo_reset, 1);
+ mdelay(20);
+ } else {
+ // TODO: reset the internal robo switch
+ }
+#endif
+
+ phyid = mdio_read(ROBO_PHY_ADDR, 0x2) |
+ (mdio_read(ROBO_PHY_ADDR, 0x3) << 16);
+
+ if (phyid == 0xffffffff || phyid == 0x55210022) {
+ printk(KERN_ERR PFX "No Robo switch in managed mode found, phy_id = 0x%08x\n", phyid);
+ err = -ENODEV;
+ goto err_gpio_lanports;
+ }
+
+ /* Get the device ID */
+ for (i = 0; i < 10; i++) {
+ robo.devid = robo_read16(ROBO_MGMT_PAGE, ROBO_DEVICE_ID);
+ if (robo.devid)
+ break;
+ udelay(10);
+ }
+ if (!robo.devid)
+ robo.devid = ROBO_DEVICE_ID_5325; /* Fake it */
+ if (robo.devid == ROBO_DEVICE_ID_5325)
+ robo.is_5365 = robo_bcm5365();
+ else
+ robo.is_5365 = false;
+
+ robo.gmii = robo_gmii();
+ if (robo.devid == ROBO_DEVICE_ID_5325) {
+ for (i = 0; i < 5; i++)
+ robo.port[i] = i;
+ } else {
+ for (i = 0; i < 8; i++)
+ robo.port[i] = i;
+ }
+ robo.port[i] = ROBO_IM_PORT_CTRL;
+
+ robo_switch_reset();
+ err = robo_switch_enable();
+ if (err)
+ goto err_gpio_lanports;
+
+ printk(KERN_INFO PFX "found a 5%s%x!%s at %s\n", robo.devid & 0xff00 ? "" : "3", robo.devid,
+ robo.is_5365 ? " It's a BCM5365." : "", devname);
+
+ return 0;
+
+err_gpio_lanports:
+ if (robo.gpio_lanports_enable >= 0)
+ gpio_free(robo.gpio_lanports_enable);
+err_gpio_robo:
+ if (robo.gpio_robo_reset >= 0)
+ gpio_free(robo.gpio_robo_reset);
+err_put:
+ dev_put(robo.dev);
+ robo.dev = NULL;
+err_done:
+ return err;
+}
+
+static int handle_vlan_port_read_old(switch_driver *d, char *buf, int nr)
+{
+ __u16 val16;
+ int len = 0;
+ int j;
+
+ val16 = (nr) /* vlan */ | (0 << 12) /* read */ | (1 << 13) /* enable */;
+
+ if (robo.is_5365) {
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5365, val16);
+ /* actual read */
+ val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_READ);
+ if ((val16 & (1 << 14)) /* valid */) {
+ for (j = 0; j < d->ports; j++) {
+ if (val16 & (1 << j)) {
+ len += sprintf(buf + len, "%d", j);
+ if (val16 & (1 << (j + 7))) {
+ if (j == d->cpuport)
+ buf[len++] = 'u';
+ } else {
+ buf[len++] = 't';
+ if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr)
+ buf[len++] = '*';
+ }
+ buf[len++] = '\t';
+ }
+ }
+ len += sprintf(buf + len, "\n");
+ }
+ } else {
+ u32 val32;
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16);
+ /* actual read */
+ val32 = robo_read32(ROBO_VLAN_PAGE, ROBO_VLAN_READ);
+ if ((val32 & (1 << 20)) /* valid */) {
+ for (j = 0; j < d->ports; j++) {
+ if (val32 & (1 << j)) {
+ len += sprintf(buf + len, "%d", j);
+ if (val32 & (1 << (j + d->ports))) {
+ if (j == d->cpuport)
+ buf[len++] = 'u';
+ } else {
+ buf[len++] = 't';
+ if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr)
+ buf[len++] = '*';
+ }
+ buf[len++] = '\t';
+ }
+ }
+ len += sprintf(buf + len, "\n");
+ }
+ }
+
+ buf[len] = '\0';
+
+ return len;
+}
+
+static int handle_vlan_port_read_new(switch_driver *d, char *buf, int nr)
+{
+ __u8 vtbl_entry, vtbl_index, vtbl_access;
+ __u32 val32;
+ int len = 0;
+ int j;
+
+ if ((robo.devid == ROBO_DEVICE_ID_5395) ||
+ (robo.devid == ROBO_DEVICE_ID_53115) ||
+ (robo.devid == ROBO_DEVICE_ID_53125)) {
+ vtbl_access = ROBO_VTBL_ACCESS_5395;
+ vtbl_index = ROBO_VTBL_INDX_5395;
+ vtbl_entry = ROBO_VTBL_ENTRY_5395;
+ } else {
+ vtbl_access = ROBO_VTBL_ACCESS;
+ vtbl_index = ROBO_VTBL_INDX;
+ vtbl_entry = ROBO_VTBL_ENTRY;
+ }
+
+ robo_write16(ROBO_ARLIO_PAGE, vtbl_index, nr);
+ robo_write16(ROBO_ARLIO_PAGE, vtbl_access, (1 << 7) | (1 << 0));
+ val32 = robo_read32(ROBO_ARLIO_PAGE, vtbl_entry);
+ for (j = 0; j < d->ports; j++) {
+ if (val32 & (1 << j)) {
+ len += sprintf(buf + len, "%d", j);
+ if (val32 & (1 << (j + d->ports))) {
+ if (j == d->cpuport)
+ buf[len++] = 'u';
+ } else {
+ buf[len++] = 't';
+ if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr)
+ buf[len++] = '*';
+ }
+ buf[len++] = '\t';
+ }
+ }
+ len += sprintf(buf + len, "\n");
+ buf[len] = '\0';
+ return len;
+}
+
+static int handle_vlan_port_read(void *driver, char *buf, int nr)
+{
+ switch_driver *d = (switch_driver *) driver;
+
+ if (robo.devid != ROBO_DEVICE_ID_5325)
+ return handle_vlan_port_read_new(d, buf, nr);
+ else
+ return handle_vlan_port_read_old(d, buf, nr);
+}
+
+static void handle_vlan_port_write_old(switch_driver *d, switch_vlan_config *c, int nr)
+{
+ __u16 val16;
+ __u32 val32;
+ __u32 untag = ((c->untag & ~(1 << d->cpuport)) << d->ports);
+
+ /* write config now */
+ val16 = (nr) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */;
+ if (robo.is_5365) {
+ robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5365,
+ (1 << 14) /* valid */ | (untag << 1 ) | c->port);
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5365, val16);
+ } else {
+ if (robo.corerev < 3)
+ val32 = (1 << 20) | ((nr >> 4) << 12) | untag | c->port;
+ else
+ val32 = (1 << 24) | (nr << 12) | untag | c->port;
+ robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, val32);
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16);
+ }
+}
+
+static void handle_vlan_port_write_new(switch_driver *d, switch_vlan_config *c, int nr)
+{
+ __u8 vtbl_entry, vtbl_index, vtbl_access;
+ __u32 untag = ((c->untag & ~(1 << d->cpuport)) << d->ports);
+
+ /* write config now */
+ if ((robo.devid == ROBO_DEVICE_ID_5395) ||
+ (robo.devid == ROBO_DEVICE_ID_53115) ||
+ (robo.devid == ROBO_DEVICE_ID_53125)) {
+ vtbl_access = ROBO_VTBL_ACCESS_5395;
+ vtbl_index = ROBO_VTBL_INDX_5395;
+ vtbl_entry = ROBO_VTBL_ENTRY_5395;
+ } else {
+ vtbl_access = ROBO_VTBL_ACCESS;
+ vtbl_index = ROBO_VTBL_INDX;
+ vtbl_entry = ROBO_VTBL_ENTRY;
+ }
+
+ robo_write32(ROBO_ARLIO_PAGE, vtbl_entry, untag | c->port);
+ robo_write16(ROBO_ARLIO_PAGE, vtbl_index, nr);
+ robo_write16(ROBO_ARLIO_PAGE, vtbl_access, 1 << 7);
+}
+
+static int handle_vlan_port_write(void *driver, char *buf, int nr)
+{
+ switch_driver *d = (switch_driver *)driver;
+ switch_vlan_config *c = switch_parse_vlan(d, buf);
+ int j;
+
+ if (c == NULL)
+ return -EINVAL;
+
+ for (j = 0; j < d->ports; j++) {
+ if ((c->untag | c->pvid) & (1 << j)) {
+ /* change default vlan tag */
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1), nr);
+ }
+ }
+
+ if (robo.devid != ROBO_DEVICE_ID_5325)
+ handle_vlan_port_write_new(d, c, nr);
+ else
+ handle_vlan_port_write_old(d, c, nr);
+
+ kfree(c);
+ return 0;
+}
+
+#define set_switch(state) \
+ robo_write16(ROBO_CTRL_PAGE, ROBO_SWITCH_MODE, (robo_read16(ROBO_CTRL_PAGE, ROBO_SWITCH_MODE) & ~2) | (state ? 2 : 0));
+
+static int handle_enable_read(void *driver, char *buf, int nr)
+{
+ return sprintf(buf, "%d\n", (((robo_read16(ROBO_CTRL_PAGE, ROBO_SWITCH_MODE) & 2) == 2) ? 1 : 0));
+}
+
+static int handle_enable_write(void *driver, char *buf, int nr)
+{
+ set_switch(buf[0] == '1');
+
+ return 0;
+}
+
+static int handle_port_enable_read(void *driver, char *buf, int nr)
+{
+ return sprintf(buf, "%d\n", ((robo_read16(ROBO_CTRL_PAGE, robo.port[nr]) & 3) == 3 ? 0 : 1));
+}
+
+static int handle_port_enable_write(void *driver, char *buf, int nr)
+{
+ u16 val16;
+
+ if (buf[0] == '0')
+ val16 = 3; /* disabled */
+ else if (buf[0] == '1')
+ val16 = 0; /* enabled */
+ else
+ return -EINVAL;
+
+ robo_write16(ROBO_CTRL_PAGE, robo.port[nr],
+ (robo_read16(ROBO_CTRL_PAGE, robo.port[nr]) & ~3) | val16);
+
+ return 0;
+}
+
+static int handle_port_media_read(void *driver, char *buf, int nr)
+{
+ u16 bmcr = mdio_read(robo.port[nr], MII_BMCR);
+ int media, len;
+
+ if (bmcr & BMCR_ANENABLE)
+ media = SWITCH_MEDIA_AUTO;
+ else {
+ if (bmcr & BMCR_SPEED1000)
+ media = SWITCH_MEDIA_1000;
+ else if (bmcr & BMCR_SPEED100)
+ media = SWITCH_MEDIA_100;
+ else
+ media = 0;
+
+ if (bmcr & BMCR_FULLDPLX)
+ media |= SWITCH_MEDIA_FD;
+ }
+
+ len = switch_print_media(buf, media);
+ return len + sprintf(buf + len, "\n");
+}
+
+static int handle_port_media_write(void *driver, char *buf, int nr)
+{
+ int media = switch_parse_media(buf);
+ u16 bmcr, bmcr_mask;
+
+ if (media & SWITCH_MEDIA_AUTO)
+ bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
+ else {
+ if (media & SWITCH_MEDIA_1000) {
+ if (!robo.gmii)
+ return -EINVAL;
+ bmcr = BMCR_SPEED1000;
+ }
+ else if (media & SWITCH_MEDIA_100)
+ bmcr = BMCR_SPEED100;
+ else
+ bmcr = 0;
+
+ if (media & SWITCH_MEDIA_FD)
+ bmcr |= BMCR_FULLDPLX;
+ }
+
+ bmcr_mask = ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_ANRESTART);
+ mdio_write(robo.port[nr], MII_BMCR,
+ (mdio_read(robo.port[nr], MII_BMCR) & bmcr_mask) | bmcr);
+
+ return 0;
+}
+
+static int handle_enable_vlan_read(void *driver, char *buf, int nr)
+{
+ return sprintf(buf, "%d\n", (((robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL0) & (1 << 7)) == (1 << 7)) ? 1 : 0));
+}
+
+static int handle_enable_vlan_write(void *driver, char *buf, int nr)
+{
+ __u16 val16;
+ int disable = ((buf[0] != '1') ? 1 : 0);
+
+ val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL0);
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL0, disable ? 0 :
+ val16 | (1 << 7) /* 802.1Q VLAN */ | (3 << 5) /* mac check and hash */);
+
+ val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL1);
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL1, disable ? 0 :
+ val16 | (robo.devid == ROBO_DEVICE_ID_5325 ? (1 << 1) :
+ 0) | (1 << 2) | (1 << 3)); /* RSV multicast */
+
+ if (robo.devid != ROBO_DEVICE_ID_5325)
+ return 0;
+
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL4, disable ? 0 :
+ (1 << 6) /* drop invalid VID frames */);
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL5, disable ? 0 :
+ (1 << 3) /* drop miss V table frames */);
+
+ return 0;
+}
+
+static void handle_reset_old(switch_driver *d, char *buf, int nr)
+{
+ int j;
+ __u16 val16;
+
+ /* reset vlans */
+ for (j = 0; j <= ((robo.is_5365) ? VLAN_ID_MAX_5365 : VLAN_ID_MAX); j++) {
+ /* write config now */
+ val16 = (j) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */;
+ if (robo.is_5365)
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5365, 0);
+ else
+ robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, 0);
+ robo_write16(ROBO_VLAN_PAGE, robo.is_5365 ? ROBO_VLAN_TABLE_ACCESS_5365 :
+ ROBO_VLAN_TABLE_ACCESS,
+ val16);
+ }
+}
+
+static void handle_reset_new(switch_driver *d, char *buf, int nr)
+{
+ int j;
+ __u8 vtbl_entry, vtbl_index, vtbl_access;
+
+ if ((robo.devid == ROBO_DEVICE_ID_5395) ||
+ (robo.devid == ROBO_DEVICE_ID_53115) ||
+ (robo.devid == ROBO_DEVICE_ID_53125)) {
+ vtbl_access = ROBO_VTBL_ACCESS_5395;
+ vtbl_index = ROBO_VTBL_INDX_5395;
+ vtbl_entry = ROBO_VTBL_ENTRY_5395;
+ } else {
+ vtbl_access = ROBO_VTBL_ACCESS;
+ vtbl_index = ROBO_VTBL_INDX;
+ vtbl_entry = ROBO_VTBL_ENTRY;
+ }
+
+ for (j = 0; j <= VLAN_ID_MAX; j++) {
+ /* write config now */
+ robo_write32(ROBO_ARLIO_PAGE, vtbl_entry, 0);
+ robo_write16(ROBO_ARLIO_PAGE, vtbl_index, j);
+ robo_write16(ROBO_ARLIO_PAGE, vtbl_access, 1 << 7);
+ }
+}
+
+static int handle_reset(void *driver, char *buf, int nr)
+{
+ int j;
+ switch_driver *d = (switch_driver *) driver;
+
+ /* disable switching */
+ set_switch(0);
+
+ if (robo.devid != ROBO_DEVICE_ID_5325)
+ handle_reset_new(d, buf, nr);
+ else
+ handle_reset_old(d, buf, nr);
+
+ /* reset ports to a known good state */
+ for (j = 0; j < d->ports; j++) {
+ robo_write16(ROBO_CTRL_PAGE, robo.port[j], 0x0000);
+ robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1), 0);
+ }
+
+ /* enable switching */
+ set_switch(1);
+
+ /* enable vlans */
+ handle_enable_vlan_write(driver, "1", 0);
+
+ return 0;
+}
+
+static int __init robo_init(void)
+{
+ int notfound = 1;
+ char *device;
+
+ device = strdup("ethX");
+ for (device[3] = '0'; (device[3] <= '3') && notfound; device[3]++) {
+ if (! switch_device_registered (device))
+ notfound = robo_probe(device);
+ }
+ device[3]--;
+
+ if (notfound) {
+ kfree(device);
+ return -ENODEV;
+ } else {
+ static const switch_config cfg[] = {
+ {
+ .name = "enable",
+ .read = handle_enable_read,
+ .write = handle_enable_write
+ }, {
+ .name = "enable_vlan",
+ .read = handle_enable_vlan_read,
+ .write = handle_enable_vlan_write
+ }, {
+ .name = "reset",
+ .read = NULL,
+ .write = handle_reset
+ }, { NULL, },
+ };
+ static const switch_config port[] = {
+ {
+ .name = "enable",
+ .read = handle_port_enable_read,
+ .write = handle_port_enable_write
+ }, {
+ .name = "media",
+ .read = handle_port_media_read,
+ .write = handle_port_media_write
+ }, { NULL, },
+ };
+ static const switch_config vlan[] = {
+ {
+ .name = "ports",
+ .read = handle_vlan_port_read,
+ .write = handle_vlan_port_write
+ }, { NULL, },
+ };
+ switch_driver driver = {
+ .name = DRIVER_NAME,
+ .version = DRIVER_VERSION,
+ .interface = device,
+ .cpuport = 5,
+ .ports = 6,
+ .vlans = 16,
+ .driver_handlers = cfg,
+ .port_handlers = port,
+ .vlan_handlers = vlan,
+ };
+ if (robo.devid != ROBO_DEVICE_ID_5325) {
+ driver.ports = 9;
+ driver.cpuport = 8;
+ }
+ if (robo.is_5365)
+ snprintf(driver.dev_name, SWITCH_NAME_BUFSZ, "BCM5365");
+ else
+ snprintf(driver.dev_name, SWITCH_NAME_BUFSZ, "BCM5%s%x", robo.devid & 0xff00 ? "" : "3", robo.devid);
+
+ return switch_register_driver(&driver);
+ }
+}
+
+static void __exit robo_exit(void)
+{
+ switch_unregister_driver(DRIVER_NAME);
+ if (robo.dev)
+ dev_put(robo.dev);
+ if (robo.gpio_robo_reset >= 0)
+ gpio_free(robo.gpio_robo_reset);
+ if (robo.gpio_lanports_enable >= 0)
+ gpio_free(robo.gpio_lanports_enable);
+ kfree(robo.device);
+}
+
+
+MODULE_AUTHOR("Felix Fietkau <openwrt@nbd.name>");
+MODULE_LICENSE("GPL");
+
+module_init(robo_init);
+module_exit(robo_exit);
diff --git a/package/kernel/trelay/Makefile b/package/kernel/trelay/Makefile
new file mode 100644
index 0000000000..82c41018a7
--- /dev/null
+++ b/package/kernel/trelay/Makefile
@@ -0,0 +1,50 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=trelay
+PKG_VERSION:=0.1
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/trelay
+ SUBMENU:=Network Support
+ TITLE:=Trivial Ethernet Relay
+ FILES:=$(PKG_BUILD_DIR)/trelay.ko
+ AUTOLOAD:=$(call AutoLoad,50,trelay)
+endef
+
+define KernelPackage/trelay/description
+trelay relays ethernet packets between two devices (similar to a bridge), but
+without any MAC address checks. This makes it possible to bridge client mode
+or ad-hoc mode wifi devices to ethernet VLANs, assuming the remote end uses
+the same source MAC address as the device that packets are supposed to exit
+from.
+endef
+
+include $(INCLUDE_DIR)/kernel-defaults.mk
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ cp src/Makefile src/trelay.c $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) $(KERNEL_MAKEOPTS) SUBDIRS="$(PKG_BUILD_DIR)" modules
+endef
+
+define KernelPackage/trelay/install
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/net $(1)/etc/init.d $(1)/etc/config
+ $(INSTALL_DATA) ./files/trelay.hotplug $(1)/etc/hotplug.d/net/50-trelay
+ $(INSTALL_BIN) ./files/trelay.init $(1)/etc/init.d/trelay
+ $(INSTALL_DATA) ./files/trelay.config $(1)/etc/config/trelay
+endef
+
+$(eval $(call KernelPackage,trelay))
diff --git a/package/kernel/trelay/files/trelay.config b/package/kernel/trelay/files/trelay.config
new file mode 100644
index 0000000000..eb05013056
--- /dev/null
+++ b/package/kernel/trelay/files/trelay.config
@@ -0,0 +1,4 @@
+config trelay
+ option enabled 0
+ option dev1 eth0
+ option dev2 wlan0
diff --git a/package/kernel/trelay/files/trelay.hotplug b/package/kernel/trelay/files/trelay.hotplug
new file mode 100644
index 0000000000..31f7378406
--- /dev/null
+++ b/package/kernel/trelay/files/trelay.hotplug
@@ -0,0 +1,5 @@
+case "$ACTION" in
+ add|register)
+ [ -f /var/run/trelay.active ] && /etc/init.d/trelay start
+ ;;
+esac
diff --git a/package/kernel/trelay/files/trelay.init b/package/kernel/trelay/files/trelay.init
new file mode 100644
index 0000000000..c812e12c69
--- /dev/null
+++ b/package/kernel/trelay/files/trelay.init
@@ -0,0 +1,32 @@
+#!/bin/sh /etc/rc.common
+START=80
+
+check_relay() {
+ local cfg="$1"
+
+ config_get_bool enabled "$cfg" enabled 1
+ [ "$enabled" -gt 0 ] || return
+
+ config_get dev1 "$cfg" dev1
+ config_get dev2 "$cfg" dev2
+
+ [ -d "/sys/kernel/debug/trelay/${dev1}-${dev2}" ] && return
+ [ -d "/sys/class/net/${dev1}" -a -d "/sys/class/net/${dev2}" ] || return
+
+ ifconfig "$dev1" up
+ ifconfig "$dev2" up
+ echo "${dev1}-${dev2},${dev1},${dev2}" > /sys/kernel/debug/trelay/add
+}
+
+start() {
+ config_load trelay
+ config_foreach check_relay trelay
+ touch /var/run/trelay.active
+}
+
+stop() {
+ rm -f /var/run/trelay.active
+ for relay in /sys/kernel/debug/trelay/*; do
+ [ -d "$relay" ] && echo > "$relay/remove"
+ done
+}
diff --git a/package/kernel/trelay/src/Makefile b/package/kernel/trelay/src/Makefile
new file mode 100644
index 0000000000..e6bde8969b
--- /dev/null
+++ b/package/kernel/trelay/src/Makefile
@@ -0,0 +1 @@
+obj-m := trelay.o
diff --git a/package/kernel/trelay/src/trelay.c b/package/kernel/trelay/src/trelay.c
new file mode 100644
index 0000000000..8fa4374c06
--- /dev/null
+++ b/package/kernel/trelay/src/trelay.c
@@ -0,0 +1,272 @@
+/*
+ * trelay.c: Trivial Ethernet Relay
+ *
+ * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/module.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/debugfs.h>
+
+static LIST_HEAD(trelay_devs);
+static struct dentry *debugfs_dir;
+
+struct trelay {
+ struct list_head list;
+ struct net_device *dev1, *dev2;
+ struct dentry *debugfs;
+ char name[];
+};
+
+rx_handler_result_t trelay_handle_frame(struct sk_buff **pskb)
+{
+ struct net_device *dev;
+ struct sk_buff *skb = *pskb;
+
+ dev = rcu_dereference(skb->dev->rx_handler_data);
+ if (!dev)
+ return RX_HANDLER_PASS;
+
+ if (skb->protocol == htons(ETH_P_PAE))
+ return RX_HANDLER_PASS;
+
+ skb_push(skb, ETH_HLEN);
+ skb->dev = dev;
+ skb_forward_csum(skb);
+ dev_queue_xmit(skb);
+
+ return RX_HANDLER_CONSUMED;
+}
+
+static int trelay_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static int trelay_do_remove(struct trelay *tr)
+{
+ list_del(&tr->list);
+
+ dev_put(tr->dev1);
+ dev_put(tr->dev2);
+
+ netdev_rx_handler_unregister(tr->dev1);
+ netdev_rx_handler_unregister(tr->dev2);
+
+ debugfs_remove_recursive(tr->debugfs);
+ kfree(tr);
+
+ return 0;
+}
+
+static struct trelay *trelay_find(struct net_device *dev)
+{
+ struct trelay *tr;
+
+ list_for_each_entry(tr, &trelay_devs, list) {
+ if (tr->dev1 == dev || tr->dev2 == dev)
+ return tr;
+ }
+ return NULL;
+}
+
+static int tr_device_event(struct notifier_block *unused, unsigned long event,
+ void *ptr)
+{
+ struct net_device *dev = ptr;
+ struct trelay *tr;
+
+ if (event != NETDEV_UNREGISTER)
+ goto out;
+
+ tr = trelay_find(dev);
+ if (!tr)
+ goto out;
+
+ trelay_do_remove(tr);
+
+out:
+ return NOTIFY_DONE;
+}
+
+static ssize_t trelay_remove_write(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct trelay *tr = file->private_data;
+ int ret;
+
+ rtnl_lock();
+ ret = trelay_do_remove(tr);
+ rtnl_unlock();
+
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static const struct file_operations fops_remove = {
+ .owner = THIS_MODULE,
+ .open = trelay_open,
+ .write = trelay_remove_write,
+ .llseek = default_llseek,
+};
+
+
+static int trelay_do_add(char *name, char *devn1, char *devn2)
+{
+ struct net_device *dev1, *dev2;
+ struct trelay *tr, *tr1;
+ int ret;
+
+ tr = kzalloc(sizeof(*tr) + strlen(name) + 1, GFP_KERNEL);
+ if (!tr)
+ return -ENOMEM;
+
+ rtnl_lock();
+ rcu_read_lock();
+
+ ret = -EEXIST;
+ list_for_each_entry(tr1, &trelay_devs, list) {
+ if (!strcmp(tr1->name, name))
+ goto out;
+ }
+
+ ret = -ENOENT;
+ dev1 = dev_get_by_name_rcu(&init_net, devn1);
+ dev2 = dev_get_by_name_rcu(&init_net, devn2);
+ if (!dev1 || !dev2)
+ goto out;
+
+ ret = netdev_rx_handler_register(dev1, trelay_handle_frame, dev2);
+ if (ret < 0)
+ goto out;
+
+ ret = netdev_rx_handler_register(dev2, trelay_handle_frame, dev1);
+ if (ret < 0) {
+ netdev_rx_handler_unregister(dev1);
+ goto out;
+ }
+
+ dev_hold(dev1);
+ dev_hold(dev2);
+
+ strcpy(tr->name, name);
+ tr->dev1 = dev1;
+ tr->dev2 = dev2;
+ list_add_tail(&tr->list, &trelay_devs);
+
+ tr->debugfs = debugfs_create_dir(name, debugfs_dir);
+ debugfs_create_file("remove", S_IWUSR, tr->debugfs, tr, &fops_remove);
+ ret = 0;
+
+out:
+ rcu_read_unlock();
+ rtnl_unlock();
+ if (ret < 0)
+ kfree(tr);
+
+ return ret;
+}
+
+static ssize_t trelay_add_write(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ char buf[256];
+ char *dev1, *dev2, *tmp;
+ ssize_t len, ret;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, ubuf, len))
+ return -EFAULT;
+
+ buf[len] = 0;
+
+ if ((tmp = strchr(buf, '\n')))
+ *tmp = 0;
+
+ dev1 = strchr(buf, ',');
+ if (!dev1)
+ return -EINVAL;
+
+ *(dev1++) = 0;
+
+ dev2 = strchr(dev1, ',');
+ if (!dev2)
+ return -EINVAL;
+
+ *(dev2++) = 0;
+ if (strchr(dev2, ','))
+ return -EINVAL;
+
+ if (!strlen(buf) || !strlen(dev1) || !strlen(dev2))
+ return -EINVAL;
+
+ ret = trelay_do_add(buf, dev1, dev2);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static const struct file_operations fops_add = {
+ .owner = THIS_MODULE,
+ .write = trelay_add_write,
+ .llseek = default_llseek,
+};
+
+static struct notifier_block tr_dev_notifier = {
+ .notifier_call = tr_device_event
+};
+
+static int __init trelay_init(void)
+{
+ int ret;
+
+ debugfs_dir = debugfs_create_dir("trelay", NULL);
+ if (!debugfs_dir)
+ return -ENOMEM;
+
+ debugfs_create_file("add", S_IWUSR, debugfs_dir, NULL, &fops_add);
+
+ ret = register_netdevice_notifier(&tr_dev_notifier);
+ if (ret < 0)
+ goto error;
+
+ return 0;
+
+error:
+ debugfs_remove_recursive(debugfs_dir);
+ return ret;
+}
+
+static void __exit trelay_exit(void)
+{
+ struct trelay *tr, *tmp;
+
+ unregister_netdevice_notifier(&tr_dev_notifier);
+
+ rtnl_lock();
+ list_for_each_entry_safe(tr, tmp, &trelay_devs, list)
+ trelay_do_remove(tr);
+ rtnl_unlock();
+
+ debugfs_remove_recursive(debugfs_dir);
+}
+
+module_init(trelay_init);
+module_exit(trelay_exit);
+MODULE_LICENSE("GPL");
diff --git a/package/kernel/w1-gpio-custom/Makefile b/package/kernel/w1-gpio-custom/Makefile
new file mode 100644
index 0000000000..bf50d1a50f
--- /dev/null
+++ b/package/kernel/w1-gpio-custom/Makefile
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2008-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=w1-gpio-custom
+PKG_RELEASE:=3
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/w1-gpio-custom
+ SUBMENU:=W1 support
+ TITLE:=Custom GPIO-based 1-wire device
+ DEPENDS:=kmod-w1 +kmod-w1-master-gpio
+ FILES:=$(PKG_BUILD_DIR)/w1-gpio-custom.ko
+ KCONFIG:=
+endef
+
+define KernelPackage/w1-gpio-custom/description
+ Kernel module to register a custom w1-gpio platform device.
+endef
+
+EXTRA_KCONFIG:= \
+ CONFIG_W1_MASTER_GPIO_CUSTOM=m
+
+EXTRA_CFLAGS:= \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG))))
+
+MAKE_OPTS:= \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
+ $(EXTRA_KCONFIG)
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ $(MAKE_OPTS) \
+ modules
+endef
+
+$(eval $(call KernelPackage,w1-gpio-custom))
+
diff --git a/package/kernel/w1-gpio-custom/src/Kconfig b/package/kernel/w1-gpio-custom/src/Kconfig
new file mode 100644
index 0000000000..74b9226c5c
--- /dev/null
+++ b/package/kernel/w1-gpio-custom/src/Kconfig
@@ -0,0 +1,4 @@
+config W1_MASTER_GPIO_CUSTOM
+ tristate "Custom GPIO-based W1 driver"
+ depends on GENERIC_GPIO
+ select W1_GPIO \ No newline at end of file
diff --git a/package/kernel/w1-gpio-custom/src/Makefile b/package/kernel/w1-gpio-custom/src/Makefile
new file mode 100644
index 0000000000..6a527432c1
--- /dev/null
+++ b/package/kernel/w1-gpio-custom/src/Makefile
@@ -0,0 +1 @@
+obj-${CONFIG_W1_MASTER_GPIO_CUSTOM} += w1-gpio-custom.o \ No newline at end of file
diff --git a/package/kernel/w1-gpio-custom/src/w1-gpio-custom.c b/package/kernel/w1-gpio-custom/src/w1-gpio-custom.c
new file mode 100644
index 0000000000..96cfcabc61
--- /dev/null
+++ b/package/kernel/w1-gpio-custom/src/w1-gpio-custom.c
@@ -0,0 +1,185 @@
+/*
+ * Custom GPIO-based W1 driver
+ *
+ * Copyright (C) 2007 Gabor Juhos <juhosg at openwrt.org>
+ * Copyright (C) 2008 Bifferos <bifferos at yahoo.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * The behaviour of this driver can be altered by setting some parameters
+ * from the insmod command line.
+ *
+ * The following parameters are adjustable:
+ *
+ * bus0 These four arguments must be arrays of
+ * bus1 3 unsigned integers as follows:
+ * bus2
+ * bus3 <id>,<pin>,<od>
+ *
+ * where:
+ *
+ * <id> ID to used as device_id for the corresponding bus (required)
+ * <sda> GPIO pin ID of data pin (required)
+ * <od> Pin is configured as open drain.
+ *
+ * See include/w1-gpio.h for more information about the parameters.
+ *
+ * If this driver is built into the kernel, you can use the following kernel
+ * command line parameters, with the same values as the corresponding module
+ * parameters listed above:
+ *
+ * w1-gpio-custom.bus0
+ * w1-gpio-custom.bus1
+ * w1-gpio-custom.bus2
+ * w1-gpio-custom.bus3
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/w1-gpio.h>
+
+#define DRV_NAME "w1-gpio-custom"
+#define DRV_DESC "Custom GPIO-based W1 driver"
+#define DRV_VERSION "0.1.1"
+
+#define PFX DRV_NAME ": "
+
+#define BUS_PARAM_ID 0
+#define BUS_PARAM_PIN 1
+#define BUS_PARAM_OD 2
+
+#define BUS_PARAM_REQUIRED 3
+#define BUS_PARAM_COUNT 3
+#define BUS_COUNT_MAX 4
+
+static unsigned int bus0[BUS_PARAM_COUNT] __initdata;
+static unsigned int bus1[BUS_PARAM_COUNT] __initdata;
+static unsigned int bus2[BUS_PARAM_COUNT] __initdata;
+static unsigned int bus3[BUS_PARAM_COUNT] __initdata;
+
+static unsigned int bus_nump[BUS_COUNT_MAX] __initdata;
+
+#define BUS_PARM_DESC " config -> id,pin,od"
+
+module_param_array(bus0, uint, &bus_nump[0], 0);
+MODULE_PARM_DESC(bus0, "bus0" BUS_PARM_DESC);
+module_param_array(bus1, uint, &bus_nump[1], 0);
+MODULE_PARM_DESC(bus1, "bus1" BUS_PARM_DESC);
+module_param_array(bus2, uint, &bus_nump[2], 0);
+MODULE_PARM_DESC(bus2, "bus2" BUS_PARM_DESC);
+module_param_array(bus3, uint, &bus_nump[3], 0);
+MODULE_PARM_DESC(bus3, "bus3" BUS_PARM_DESC);
+
+static struct platform_device *devices[BUS_COUNT_MAX];
+static unsigned int nr_devices;
+
+static void w1_gpio_custom_cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < nr_devices; i++)
+ if (devices[i])
+ platform_device_put(devices[i]);
+}
+
+static int __init w1_gpio_custom_add_one(unsigned int id, unsigned int *params)
+{
+ struct platform_device *pdev;
+ struct w1_gpio_platform_data pdata;
+ int err;
+
+ if (!bus_nump[id])
+ return 0;
+
+ if (bus_nump[id] < BUS_PARAM_REQUIRED) {
+ printk(KERN_ERR PFX "not enough parameters for bus%d\n", id);
+ err = -EINVAL;
+ goto err;
+ }
+
+ pdev = platform_device_alloc("w1-gpio", params[BUS_PARAM_ID]);
+ if (!pdev) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ pdata.pin = params[BUS_PARAM_PIN];
+ pdata.is_open_drain = params[BUS_PARAM_OD] ? 1:0;
+ pdata.enable_external_pullup = NULL;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto err_put;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_put;
+
+ devices[nr_devices++] = pdev;
+ return 0;
+
+ err_put:
+ platform_device_put(pdev);
+ err:
+ return err;
+}
+
+static int __init w1_gpio_custom_probe(void)
+{
+ int err;
+
+ nr_devices = 0;
+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
+
+ err = w1_gpio_custom_add_one(0, bus0);
+ if (err) goto err;
+
+ err = w1_gpio_custom_add_one(1, bus1);
+ if (err) goto err;
+
+ err = w1_gpio_custom_add_one(2, bus2);
+ if (err) goto err;
+
+ err = w1_gpio_custom_add_one(3, bus3);
+ if (err) goto err;
+
+ if (!nr_devices) {
+ printk(KERN_ERR PFX "no bus parameter(s) specified\n");
+ err = -ENODEV;
+ goto err;
+ }
+
+ return 0;
+
+err:
+ w1_gpio_custom_cleanup();
+ return err;
+}
+
+#ifdef MODULE
+static int __init w1_gpio_custom_init(void)
+{
+ return w1_gpio_custom_probe();
+}
+module_init(w1_gpio_custom_init);
+
+static void __exit w1_gpio_custom_exit(void)
+{
+ w1_gpio_custom_cleanup();
+}
+module_exit(w1_gpio_custom_exit);
+#else
+subsys_initcall(w1_gpio_custom_probe);
+#endif /* MODULE*/
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Bifferos <bifferos at yahoo.co.uk >");
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_VERSION(DRV_VERSION);
diff --git a/package/kernel/wrt55agv2-spidevs/Makefile b/package/kernel/wrt55agv2-spidevs/Makefile
new file mode 100644
index 0000000000..236c9a3be3
--- /dev/null
+++ b/package/kernel/wrt55agv2-spidevs/Makefile
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=wrt55agv2-spidevs
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/wrt55agv2-spidevs
+ SUBMENU:=Other modules
+ TITLE:=WRT55AG v2 SPI devices support
+ DEPENDS:=@TARGET_atheros +kmod-spi-gpio-old +kmod-spi-ks8995
+ FILES:=$(PKG_BUILD_DIR)/wrt55agv2_spidevs.ko
+endef
+
+define KernelPackage/wrt55agv2-spidevs/description
+ Kernel module for the SPI devices on the WRT55AG v2 board.
+endef
+
+EXTRA_KCONFIG:= \
+ CONFIG_WRT55AGV2_SPIDEVS=m
+
+EXTRA_CFLAGS:= \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \
+
+MAKE_OPTS:= \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
+ LINUXINCLUDE="-I$(LINUX_DIR)/include -I$(LINUX_DIR)/arch/mips/include -include generated/autoconf.h" \
+ $(EXTRA_KCONFIG)
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ $(MAKE_OPTS) \
+ modules
+endef
+
+$(eval $(call KernelPackage,wrt55agv2-spidevs))
diff --git a/package/kernel/wrt55agv2-spidevs/src/Kconfig b/package/kernel/wrt55agv2-spidevs/src/Kconfig
new file mode 100644
index 0000000000..75e8242be7
--- /dev/null
+++ b/package/kernel/wrt55agv2-spidevs/src/Kconfig
@@ -0,0 +1,3 @@
+config WRT55AGV2_SPIDEVS
+ tristate "SPI device support for the WRT55AG v2 board"
+ depends on SPI && MIPS_ATHEROS
diff --git a/package/kernel/wrt55agv2-spidevs/src/Makefile b/package/kernel/wrt55agv2-spidevs/src/Makefile
new file mode 100644
index 0000000000..7f2ddb4e58
--- /dev/null
+++ b/package/kernel/wrt55agv2-spidevs/src/Makefile
@@ -0,0 +1 @@
+obj-${CONFIG_WRT55AGV2_SPIDEVS} += wrt55agv2_spidevs.o \ No newline at end of file
diff --git a/package/kernel/wrt55agv2-spidevs/src/wrt55agv2_spidevs.c b/package/kernel/wrt55agv2-spidevs/src/wrt55agv2_spidevs.c
new file mode 100644
index 0000000000..dfb7f6abe7
--- /dev/null
+++ b/package/kernel/wrt55agv2-spidevs/src/wrt55agv2_spidevs.c
@@ -0,0 +1,114 @@
+/*
+ * SPI driver for the Linksys WRT55AG v2 board.
+ *
+ * Copyright (C) 2008 Gabor Juhos <juhosg at openwrt.org>
+ *
+ * This file was based on the mmc_over_gpio driver:
+ * Copyright 2008 Michael Buesch <mb@bu3sch.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/spi/spi_gpio_old.h>
+#include <linux/module.h>
+
+#define DRV_NAME "wrt55agv2-spidevs"
+#define DRV_DESC "SPI driver for the WRT55AG v2 board"
+#define DRV_VERSION "0.1.0"
+#define PFX DRV_NAME ": "
+
+#define GPIO_PIN_MISO 1
+#define GPIO_PIN_CS 2
+#define GPIO_PIN_CLK 3
+#define GPIO_PIN_MOSI 4
+
+static struct platform_device *spi_gpio_dev;
+
+static int __init boardinfo_setup(struct spi_board_info *bi,
+ struct spi_master *master, void *data)
+{
+
+ strlcpy(bi->modalias, "spi-ks8995", sizeof(bi->modalias));
+
+ bi->max_speed_hz = 5000000 /* Hz */;
+ bi->bus_num = master->bus_num;
+ bi->mode = SPI_MODE_0;
+
+ return 0;
+}
+
+static int __init wrt55agv2_spidevs_init(void)
+{
+ struct spi_gpio_platform_data pdata;
+ int err;
+
+ spi_gpio_dev = platform_device_alloc("spi-gpio", 0);
+ if (!spi_gpio_dev) {
+ printk(KERN_ERR PFX "no memory for spi-gpio device\n");
+ return -ENOMEM;
+ }
+
+ memset(&pdata, 0, sizeof(pdata));
+ pdata.pin_miso = GPIO_PIN_MISO;
+ pdata.pin_cs = GPIO_PIN_CS;
+ pdata.pin_clk = GPIO_PIN_CLK;
+ pdata.pin_mosi = GPIO_PIN_MOSI;
+ pdata.cs_activelow = 1;
+ pdata.no_spi_delay = 1;
+ pdata.boardinfo_setup = boardinfo_setup;
+ pdata.boardinfo_setup_data = NULL;
+
+ err = platform_device_add_data(spi_gpio_dev, &pdata, sizeof(pdata));
+ if (err)
+ goto err_free_dev;
+
+ err = platform_device_register(spi_gpio_dev);
+ if (err) {
+ printk(KERN_ERR PFX "unable to register device\n");
+ goto err_free_pdata;
+ }
+
+ return 0;
+
+err_free_pdata:
+ kfree(spi_gpio_dev->dev.platform_data);
+ spi_gpio_dev->dev.platform_data = NULL;
+
+err_free_dev:
+ platform_device_put(spi_gpio_dev);
+ return err;
+}
+
+static void __exit wrt55agv2_spidevs_cleanup(void)
+{
+ if (!spi_gpio_dev)
+ return;
+
+ platform_device_unregister(spi_gpio_dev);
+
+ kfree(spi_gpio_dev->dev.platform_data);
+ spi_gpio_dev->dev.platform_data = NULL;
+ platform_device_put(spi_gpio_dev);
+}
+
+static int __init wrt55agv2_spidevs_modinit(void)
+{
+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
+ return wrt55agv2_spidevs_init();
+}
+module_init(wrt55agv2_spidevs_modinit);
+
+static void __exit wrt55agv2_spidevs_modexit(void)
+{
+ wrt55agv2_spidevs_cleanup();
+}
+module_exit(wrt55agv2_spidevs_modexit);
+
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
+MODULE_LICENSE("GPL v2");
+