aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel')
-rw-r--r--package/kernel/acx-mac80211/Makefile260
-rw-r--r--package/kernel/acx-mac80211/patches/200-initial-macaddr.patch29
-rw-r--r--package/kernel/acx-mac80211/patches/300-kernel_4_2.patch67
-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.04.03.00/220-3.10-update_proc_code.patch2965
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/230-compile_fixes.patch44
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/240-3.18_fixes.patch38
-rw-r--r--package/kernel/ar7-atm/patches-D7.04.03.00/250-4.1_fixes.patch20
-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/ar7-atm/patches-D7.05.01.00/220-3.10-update_proc_code.patch3102
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/240-3.18_fixes.patch38
-rw-r--r--package/kernel/ar7-atm/patches-D7.05.01.00/250-4.1_fixes.patch20
-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/Makefile53
-rw-r--r--package/kernel/broadcom-wl/Makefile177
-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.sh477
-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.patch188
-rw-r--r--package/kernel/broadcom-wl/patches/008-fix_virtual_interfaces.patch132
-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/012-compat-3.10.patch47
-rw-r--r--package/kernel/broadcom-wl/patches/013-interface-name.patch11
-rw-r--r--package/kernel/broadcom-wl/patches/014-fix-band-reporting.patch41
-rw-r--r--package/kernel/broadcom-wl/patches/015-support-probe-of-wds-interfaces.patch11
-rw-r--r--package/kernel/broadcom-wl/patches/020-musl-fixes.patch75
-rw-r--r--package/kernel/broadcom-wl/patches/030-remove_devinit_devexit.patch74
-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/120-fixup-mac-addresses.patch92
-rw-r--r--package/kernel/broadcom-wl/patches/200-add_bcm_a8xx_support.patch12
-rw-r--r--package/kernel/broadcom-wl/patches/910-fallback-sprom.patch78
-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/patches/914-eliminate-date-time-error.patch21
-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.c1181
-rw-r--r--package/kernel/button-hotplug/Makefile55
-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.c343
-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/Makefile50
-rw-r--r--package/kernel/gpio-button-hotplug/src/Makefile1
-rw-r--r--package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c670
-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.c202
-rw-r--r--package/kernel/lantiq/ltq-adsl-fw/Makefile55
-rw-r--r--package/kernel/lantiq/ltq-adsl-mei/Makefile50
-rw-r--r--package/kernel/lantiq/ltq-adsl-mei/patches/100_no-date-time.patch13
-rw-r--r--package/kernel/lantiq/ltq-adsl-mei/src/Makefile17
-rw-r--r--package/kernel/lantiq/ltq-adsl-mei/src/ifxmips_mei_interface.h724
-rw-r--r--package/kernel/lantiq/ltq-adsl-mei/src/lantiq_mei.c2840
-rw-r--r--package/kernel/lantiq/ltq-adsl/Config.in5
-rw-r--r--package/kernel/lantiq/ltq-adsl/Makefile95
-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-adsl/patches/140-linux_3.18.patch40
-rw-r--r--package/kernel/lantiq/ltq-atm/Makefile54
-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.c1925
-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.c3961
-rw-r--r--package/kernel/lantiq/ltq-hcd/Makefile51
-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.c2138
-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.c1595
-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_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/Makefile50
-rw-r--r--package/kernel/lantiq/ltq-ifxos/patches/100-compat.patch158
-rw-r--r--package/kernel/lantiq/ltq-ptm/Makefile51
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/Makefile23
-rw-r--r--package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.c1555
-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.c1084
-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/Makefile68
-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-tapi/patches/300-linux-310.patch13
-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.sh57
-rw-r--r--package/kernel/lantiq/ltq-vdsl-fw/src/w921v_fw_cutter.c165
-rw-r--r--package/kernel/lantiq/ltq-vdsl-mei/Makefile67
-rw-r--r--package/kernel/lantiq/ltq-vdsl-mei/patches/100-compat.patch277
-rw-r--r--package/kernel/lantiq/ltq-vdsl-mei/patches/101_no-date-time.patch13
-rw-r--r--package/kernel/lantiq/ltq-vdsl/Makefile76
-rw-r--r--package/kernel/lantiq/ltq-vdsl/patches/100-compat.patch80
-rw-r--r--package/kernel/lantiq/ltq-vmmc/Config.in95
-rw-r--r--package/kernel/lantiq/ltq-vmmc/Makefile168
-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/200-compat.patch56
-rw-r--r--package/kernel/lantiq/ltq-vmmc/patches/400-falcon.patch968
-rw-r--r--package/kernel/linux/Makefile65
-rw-r--r--package/kernel/linux/modules/001-depends.mk14
-rw-r--r--package/kernel/linux/modules/block.mk656
-rw-r--r--package/kernel/linux/modules/can.mk277
-rw-r--r--package/kernel/linux/modules/crypto.mk627
-rw-r--r--package/kernel/linux/modules/firewire.mk74
-rw-r--r--package/kernel/linux/modules/fs.mk467
-rw-r--r--package/kernel/linux/modules/hwmon.mk315
-rw-r--r--package/kernel/linux/modules/i2c.mk251
-rw-r--r--package/kernel/linux/modules/input.mk225
-rw-r--r--package/kernel/linux/modules/leds.mk215
-rw-r--r--package/kernel/linux/modules/lib.mk223
-rw-r--r--package/kernel/linux/modules/netdevices.mk859
-rw-r--r--package/kernel/linux/modules/netfilter.mk851
-rw-r--r--package/kernel/linux/modules/netsupport.mk1007
-rw-r--r--package/kernel/linux/modules/nls.mk307
-rw-r--r--package/kernel/linux/modules/other.mk971
-rw-r--r--package/kernel/linux/modules/pcmcia.mk74
-rw-r--r--package/kernel/linux/modules/sound.mk275
-rw-r--r--package/kernel/linux/modules/spi.mk91
-rw-r--r--package/kernel/linux/modules/usb.mk1604
-rw-r--r--package/kernel/linux/modules/video.mk709
-rw-r--r--package/kernel/linux/modules/virtual.mk188
-rw-r--r--package/kernel/linux/modules/w1.mk192
-rw-r--r--package/kernel/linux/modules/wireless.mk106
-rw-r--r--package/kernel/linux/modules/wpan.mk122
-rw-r--r--package/kernel/mac80211/Makefile2154
-rw-r--r--package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh748
-rw-r--r--package/kernel/mac80211/files/lib/wifi/mac80211.sh131
-rw-r--r--package/kernel/mac80211/files/regdb.txt1262
-rw-r--r--package/kernel/mac80211/patches/000-fix_kconfig.patch14
-rw-r--r--package/kernel/mac80211/patches/001-fix_build.patch167
-rw-r--r--package/kernel/mac80211/patches/002-change_allconfig.patch64
-rw-r--r--package/kernel/mac80211/patches/003-remove_bogus_modparams.patch34
-rw-r--r--package/kernel/mac80211/patches/010-disable_rfkill.patch13
-rw-r--r--package/kernel/mac80211/patches/030-rt2x00_options.patch47
-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.patch130
-rw-r--r--package/kernel/mac80211/patches/070-ath_common_config.patch10
-rw-r--r--package/kernel/mac80211/patches/080-disable_clk_backport.patch20
-rw-r--r--package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch376
-rw-r--r--package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch12
-rw-r--r--package/kernel/mac80211/patches/120-cfg80211_allow_perm_addr_change.patch43
-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/210-ap_scan.patch11
-rw-r--r--package/kernel/mac80211/patches/300-ath9k-force-rx_clear-when-disabling-rx.patch31
-rw-r--r--package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch121
-rw-r--r--package/kernel/mac80211/patches/302-ath9k-fix-phyerror-codes.patch108
-rw-r--r--package/kernel/mac80211/patches/303-ath10k-enable-adaptive-CCA.patch239
-rw-r--r--package/kernel/mac80211/patches/304-ath10k-add-FW-API-support-to-test-mode.patch331
-rw-r--r--package/kernel/mac80211/patches/305-ath10k-add-fw_stats-support-to-10.4-firmware.patch468
-rw-r--r--package/kernel/mac80211/patches/306-ath10k-use-local-memory-instead-of-shadow-descriptor.patch60
-rw-r--r--package/kernel/mac80211/patches/307-ath10k-remove-send-completion-validation-in-diag-rea.patch49
-rw-r--r--package/kernel/mac80211/patches/308-ath10k-cleanup-copy-engine-send-completion.patch165
-rw-r--r--package/kernel/mac80211/patches/309-ath10k-remove-shadow-copy-of-CE-descriptors-for-sour.patch90
-rw-r--r--package/kernel/mac80211/patches/310-ath10k-remove-supported-chain-mask.patch77
-rw-r--r--package/kernel/mac80211/patches/311-ath10k-fill-HT-VHT-MCS-rateset-only-for-configured-c.patch37
-rw-r--r--package/kernel/mac80211/patches/312-ath10k-move-static-HT-VHT-capability-setup-functions.patch314
-rw-r--r--package/kernel/mac80211/patches/313-mac80211-fix-crash-on-mesh-local-link-ID-generation-.patch42
-rw-r--r--package/kernel/mac80211/patches/400-ath_move_debug_code.patch30
-rw-r--r--package/kernel/mac80211/patches/401-ath9k_blink_default.patch11
-rw-r--r--package/kernel/mac80211/patches/402-ath_regd_optional.patch69
-rw-r--r--package/kernel/mac80211/patches/403-world_regd_fixup.patch84
-rw-r--r--package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch19
-rw-r--r--package/kernel/mac80211/patches/405-ath_regd_us.patch26
-rw-r--r--package/kernel/mac80211/patches/406-ath_relax_default_regd.patch47
-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.patch143
-rw-r--r--package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch65
-rw-r--r--package/kernel/mac80211/patches/501-ath9k_ahb_init.patch32
-rw-r--r--package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch18
-rw-r--r--package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch11
-rw-r--r--package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch125
-rw-r--r--package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch30
-rw-r--r--package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch160
-rw-r--r--package/kernel/mac80211/patches/530-ath9k_extra_leds.patch251
-rw-r--r--package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch71
-rw-r--r--package/kernel/mac80211/patches/540-ath9k_reduce_ani_interval.patch11
-rw-r--r--package/kernel/mac80211/patches/541-ath9k_rx_dma_stop_check.patch28
-rw-r--r--package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch139
-rw-r--r--package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch186
-rw-r--r--package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch79
-rw-r--r--package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch155
-rw-r--r--package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch66
-rw-r--r--package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch80
-rw-r--r--package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch531
-rw-r--r--package/kernel/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch131
-rw-r--r--package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch62
-rw-r--r--package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch67
-rw-r--r--package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch24
-rw-r--r--package/kernel/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch30
-rw-r--r--package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch20
-rw-r--r--package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch112
-rw-r--r--package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch28
-rw-r--r--package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch235
-rw-r--r--package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch20
-rw-r--r--package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch77
-rw-r--r--package/kernel/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch30
-rw-r--r--package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch71
-rw-r--r--package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch178
-rw-r--r--package/kernel/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch22
-rw-r--r--package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch21
-rw-r--r--package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch136
-rw-r--r--package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch30
-rw-r--r--package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch23
-rw-r--r--package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch33
-rw-r--r--package/kernel/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch20
-rw-r--r--package/kernel/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch22
-rw-r--r--package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch22
-rw-r--r--package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch22
-rw-r--r--package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch32
-rw-r--r--package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch44
-rw-r--r--package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch42
-rw-r--r--package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch22
-rw-r--r--package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch23
-rw-r--r--package/kernel/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch22
-rw-r--r--package/kernel/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch136
-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.patch301
-rw-r--r--package/kernel/mac80211/patches/604-rt2x00-of_load_eeprom_filename.patch33
-rw-r--r--package/kernel/mac80211/patches/605-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch101
-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/609-rt2x00-allow_disabling_bands_through_dts.patch27
-rw-r--r--package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch211
-rw-r--r--package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch106
-rw-r--r--package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch33
-rw-r--r--package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch29
-rw-r--r--package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch276
-rw-r--r--package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch40
-rw-r--r--package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch11
-rw-r--r--package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch15
-rw-r--r--package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch29
-rw-r--r--package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch10
-rw-r--r--package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch21
-rw-r--r--package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch11
-rw-r--r--package/kernel/mac80211/patches/805-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/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/847-b43-always-take-overlapping-devs.patch11
-rw-r--r--package/kernel/mac80211/patches/850-brcmsmac-remove-extra-regulation-restriction.patch27
-rw-r--r--package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch97
-rw-r--r--package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch50
-rw-r--r--package/kernel/mac80211/patches/910-00-rt2x00-enable-rt2800soc-for-mt7620.patch20
-rw-r--r--package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch1202
-rw-r--r--package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch33
-rw-r--r--package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch37
-rw-r--r--package/kernel/mac80211/patches/940-mwl8k_init_devices_synchronously.patch20
-rwxr-xr-xpackage/kernel/mac80211/scripts/import-backports.sh109
-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/mt76/Makefile60
-rw-r--r--package/kernel/mwlwifi/Makefile62
-rw-r--r--package/kernel/mwlwifi/patches/100-drop_old_api.patch36
-rw-r--r--package/kernel/mwlwifi/patches/110-ampdu_api.patch11
-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.init36
-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.c193
-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-gpio-custom/Makefile53
-rw-r--r--package/kernel/spi-gpio-custom/src/Kconfig14
-rw-r--r--package/kernel/spi-gpio-custom/src/Makefile1
-rw-r--r--package/kernel/spi-gpio-custom/src/spi-gpio-custom.c365
-rw-r--r--package/kernel/trelay/Makefile54
-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.c190
-rw-r--r--package/kernel/wrt55agv2-spidevs/Makefile43
-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
443 files changed, 128039 insertions, 0 deletions
diff --git a/package/kernel/acx-mac80211/Makefile b/package/kernel/acx-mac80211/Makefile
new file mode 100644
index 0000000..c5c020d
--- /dev/null
+++ b/package/kernel/acx-mac80211/Makefile
@@ -0,0 +1,260 @@
+#
+# 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:=b6fc31491020cb01d2cd1acc170cfa03ced7e726
+PKG_VERSION:=20140216
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=git://git.code.sf.net/p/acx100/acx-mac80211
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=$(PKG_REV)
+# PKG_MIRROR_MD5SUM:=
+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) @!TARGET_cobalt @mipsel +kmod-mac80211
+ FILES:=$(PKG_BUILD_DIR)/acx-mac80211.ko
+ AUTOLOAD:=$(call AutoLoad,50,mac80211 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(4,2,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) \
+ -Iarch/$(LINUX_KARCH)/include/generated \
+ -Iarch/$(LINUX_KARCH)/include/generated/$(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/200-initial-macaddr.patch b/package/kernel/acx-mac80211/patches/200-initial-macaddr.patch
new file mode 100644
index 0000000..c0fdd43
--- /dev/null
+++ b/package/kernel/acx-mac80211/patches/200-initial-macaddr.patch
@@ -0,0 +1,29 @@
+--- a/cardsetting.c
++++ b/cardsetting.c
+@@ -715,10 +715,25 @@ int acx1xx_get_station_id(acx_device_t *
+ u8 *stationID = adev->ie_cmd_buf;
+ 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/acx-mac80211/patches/300-kernel_4_2.patch b/package/kernel/acx-mac80211/patches/300-kernel_4_2.patch
new file mode 100644
index 0000000..ee92b94
--- /dev/null
+++ b/package/kernel/acx-mac80211/patches/300-kernel_4_2.patch
@@ -0,0 +1,67 @@
+diff --git a/main.c b/main.c
+index bfec856..3c482d9 100644
+--- a/main.c
++++ b/main.c
+@@ -497,7 +497,7 @@ int acx_free_mechanics(acx_device_t *adev)
+
+ int acx_init_ieee80211(acx_device_t *adev, struct ieee80211_hw *hw)
+ {
+- hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
++ __clear_bit(IEEE80211_HW_RX_INCLUDES_FCS, hw->flags);
+ hw->queues = 1;
+ hw->wiphy->max_scan_ssids = 1;
+
+@@ -525,7 +525,7 @@ int acx_init_ieee80211(acx_device_t *adev, struct ieee80211_hw *hw)
+ /* We base signal quality on winlevel approach of previous driver
+ * TODO OW 20100615 This should into a common init code
+ */
+- hw->flags |= IEEE80211_HW_SIGNAL_UNSPEC;
++ __set_bit(IEEE80211_HW_SIGNAL_UNSPEC, hw->flags);
+ hw->max_signal = 100;
+
+ if (IS_ACX100(adev)) {
+@@ -945,8 +945,8 @@ void acx_op_configure_filter(struct ieee80211_hw *hw,
+ changed_flags, *total_flags);
+
+ /* OWI TODO: Set also FIF_PROBE_REQ ? */
+- *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL
+- | FIF_CONTROL | FIF_OTHER_BSS);
++ *total_flags &= (FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL
++ | FIF_OTHER_BSS);
+
+ logf1(L_DEBUG, "2: *total_flags=0x%08x\n", *total_flags);
+
+@@ -1045,9 +1045,10 @@ void acx_op_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
+ }
+
+ int acx_op_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+- struct cfg80211_scan_request *req)
++ struct ieee80211_scan_request *hw_req)
+ {
+ acx_device_t *adev = hw2adev(hw);
++ struct cfg80211_scan_request *req = &hw_req->req;
+ struct sk_buff *skb;
+ size_t ssid_len = 0;
+ u8 *ssid = NULL;
+@@ -1082,7 +1083,7 @@ int acx_op_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ goto out;
+ }
+ #else
+- skb = ieee80211_probereq_get(adev->hw, adev->vif, ssid, ssid_len,
++ skb = ieee80211_probereq_get(adev->hw, vif->addr, ssid, ssid_len,
+ req->ie_len);
+ if (!skb) {
+ ret = -ENOMEM;
+diff --git a/main.h b/main.h
+index 293f5c8..84ecb9a 100644
+--- a/main.h
++++ b/main.h
+@@ -62,7 +62,7 @@ void acx_op_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
+ #endif
+
+ int acx_op_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+- struct cfg80211_scan_request *req);
++ struct ieee80211_scan_request *req);
+
+ int acx_recover_hw(acx_device_t *adev);
+
diff --git a/package/kernel/ar7-atm/Config.in b/package/kernel/ar7-atm/Config.in
new file mode 100644
index 0000000..479b7ad
--- /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 0000000..74d334c
--- /dev/null
+++ b/package/kernel/ar7-atm/Makefile
@@ -0,0 +1,100 @@
+#
+# Copyright (C) 2006-2014 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) 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) 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 0000000..df5fe53
--- /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 0000000..9acb862
--- /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 0000000..2968fdc
--- /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 0000000..ec00df9
--- /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 0000000..ce3697b
--- /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 0000000..97b8cec
--- /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 0000000..c3d07a9
--- /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 @@ static int __init tn7atm_irq_request (st
+ * 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 @@ static int __init tn7atm_get_ESI (struct
+ {
+ 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 @@ static int tn7atm_autoDetectDspBoost (vo
+ //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 @@ static int __init tn7atm_init (struct at
+ // 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 @@ static int __init tn7atm_init (struct at
+ _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 @@ static int __init tn7atm_init (struct at
+ // 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 @@ static int __init tn7atm_init (struct at
+ _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 @@ static int __init tn7atm_init (struct at
+ 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 @@ static int __init tn7atm_init (struct at
+ 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 0000000..9f1f0fd
--- /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 0000000..6bd8f48
--- /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 0000000..11487bf
--- /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 0000000..e8668b6
--- /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
+@@ -1876,7 +1876,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 0000000..525218c
--- /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.04.03.00/220-3.10-update_proc_code.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/220-3.10-update_proc_code.patch
new file mode 100644
index 0000000..be81ee1
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/220-3.10-update_proc_code.patch
@@ -0,0 +1,2965 @@
+From 2826b9f6aa1ad2ac4c2846bbce10eb3378014555 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jogo@openwrt.org>
+Date: Thu, 26 Sep 2013 12:28:35 +0200
+Subject: [PATCH 3/3] update proc code to fix compilation for 3.10
+
+Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+---
+ tn7api.h | 63 ++-
+ tn7atm.c | 330 ++++++--------
+ tn7dsl.c | 1447 ++++++++++++++++++++++++++++++--------------------------------
+ tn7sar.c | 91 ++--
+ 4 files changed, 922 insertions(+), 1009 deletions(-)
+
+--- a/tn7api.h
++++ b/tn7api.h
+@@ -86,27 +86,26 @@ void * tn7atm_memcpy(void * dst, void co
+ /* tn7dsl.h */
+ void tn7dsl_exit(void);
+ int tn7dsl_init(void *priv);
+-int tn7dsl_proc_eoc(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_stats(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7dsl_proc_eoc_fops;
++extern struct file_operations tn7dsl_proc_stats_fops;
+
+ //#define ADV_DIAG_STATS 1 //CQ10275 To enable Adv Stats
+
+ #ifdef ADV_DIAG_STATS
+-int tn7dsl_proc_adv_stats(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_adv_stats1(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_adv_stats2(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_adv_stats3(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7dsl_proc_adv_stats_fops;
++extern struct file_operations tn7dsl_proc_adv1_stats_fops;
++extern struct file_operations tn7dsl_proc_adv2_stats_fops;
++extern struct file_operations tn7dsl_proc_adv3_stats_fops;
+ //UR8_MERGE_START CQ10682 Jack Zhang
+-int tn7dsl_proc_dbg_cmsgs(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_dbg_rmsgs1(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_dbg_rmsgs2(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_dbg_rmsgs3(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_dbg_rmsgs4(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7dsl_proc_dbg_cmsgs_fops;
++extern struct file_operations tn7dsl_proc_dbg_cmsgs1_fops;
++extern struct file_operations tn7dsl_proc_dbg_cmsgs2_fops;
++extern struct file_operations tn7dsl_proc_dbg_cmsgs3_fops;
++extern struct file_operations tn7dsl_proc_dbg_cmsgs4_fops;
+ //UR8_MERGE_END CQ10682*
+ #endif //ADV_DIAG_STATS
+
+-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);
++extern struct file_operations tn7dsl_proc_modem_fops;
+ int tn7dsl_handle_interrupt(void);
+
+ void tn7dsl_dslmod_sysctl_register(void);
+@@ -127,31 +126,31 @@ unsigned int tn7dsl_get_memory(unsigned
+ int os_atoi(const char *pStr);
+ int os_atoh(const char *pStr);
+ unsigned long os_atoul(const char *pStr);
+-int tn7dsl_proc_snr0(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_snr1(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_snr2(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_bit_allocation(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_ds_noise(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_generic_read_result(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_train_mode_export(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7dsl_proc_snr0_fops;
++extern struct file_operations tn7dsl_proc_snr1_fops;
++extern struct file_operations tn7dsl_proc_snr2_fops;
++extern struct file_operations tn7dsl_proc_bit_allocation_fops;
++extern struct file_operations tn7dsl_proc_ds_noise_fops;
++extern struct file_operations tn7dsl_proc_generic_read_result_fops;
++extern struct file_operations tn7dsl_proc_train_mode_export_fops;
+
+ #ifndef NO_ADV_STATS
+-int tn7dsl_proc_SNRpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_QLNpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7dsl_proc_SNRpsds_fops;
++extern struct file_operations tn7dsl_proc_QLNpsds_fops;
+ // * UR8_MERGE_START CQ10979 Jack Zhang
+ #ifdef TR69_HLIN_IN
+-//int tn7dsl_proc_HLINpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_HLINpsds1(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_HLINpsds2(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_HLINpsds3(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_HLINpsds4(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++//extern struct file_operations tn7dsl_proc_HLINpsds_fops;
++extern struct file_operations tn7dsl_proc_HLINpsds1_fops;
++extern struct file_operations tn7dsl_proc_HLINpsds2_fops;
++extern struct file_operations tn7dsl_proc_HLINpsds3_fops;
++extern struct file_operations tn7dsl_proc_HLINpsds4_fops;
+ #endif //TR69_HLIN_IN
+ // * UR8_MERGE_END CQ10979*
+ // * UR8_MERGE_START CQ11057 Jack Zhang
+ #define TR69_PMD_IN
+ #ifdef TR69_PMD_IN
+-//int tn7dsl_proc_PMDus(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_PMDus(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++//extern struct file_operations tn7dsl_proc_PMDus_fops;
++extern struct file_operations tn7dsl_proc_PMDus_fops;
+ #endif //TR69_PMD_IN
+ // * UR8_MERGE_END CQ11057 *
+ #endif
+@@ -168,9 +167,9 @@ void tn7sar_get_sar_version(Tn7AtmPrivat
+ int tn7sar_get_near_end_loopback_count(unsigned int *pF4count, unsigned int *pF5count);
+ int tn7sar_oam_generation(void *privContext, int chan, int type, int vpi, int vci, int timeout);
+ int tn7sar_get_stats(void *priv1);
+-int tn7sar_proc_sar_stat(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7sar_proc_sar_stat_fops;
+ void tn7sar_get_sar_firmware_version(unsigned int *pdsp_version_ms, unsigned int *pdsp_version_ls);
+-int tn7sar_proc_oam_ping(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7sar_proc_pvc_table(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7sar_proc_oam_ping_fops;
++extern struct file_operations tn7sar_proc_pvc_table_fops;
+ int tn7sar_tx_flush(void *privContext, int chan, int queue, int skip);
+ #endif __SGAPI_H
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -277,25 +277,15 @@ static int tn7atm_change_qos (struct atm
+ static int tn7atm_detect (void);
+ static int tn7atm_init (struct atm_dev *dev);
+ static int tn7atm_irq_request (struct atm_dev *dev);
+-static int tn7atm_proc_version (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data);
++
++static struct file_operations tn7atm_proc_version_fops;
+ static void tn7atm_exit (void);
+-static int tn7atm_proc_channels (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data);
+-static int tn7atm_proc_private (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data);
++static struct file_operations tn7atm_proc_channels_fops;
++static struct file_operations tn7atm_proc_private_fops;
+ inline static int tn7atm_queue_packet_to_sar (void *vcc1, void *skb1,
+ int chan);
+
+-static int tn7atm_xlate_proc_name (const char *name,
+- struct proc_dir_entry **ret,
+- const char **residual);
+-static int tn7atm_proc_match (int len, const char *name,
+- struct proc_dir_entry *de);
+-static int tn7atm_proc_qos_read (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data);
+-static int tn7atm_proc_qos_write (struct file *fp, const char *buf,
+- unsigned long count, void *data);
++static struct file_operations tn7atm_proc_qos_fops;
+
+ //CT - Added function to return chipset Id
+ void tn7atm_get_chipsetId (char *pVerId);
+@@ -415,63 +405,67 @@ const char drv_proc_root_folder[] = "ava
+ static struct proc_dir_entry *root_proc_dir_entry = NULL;
+ #define DRV_PROC_MODE 0644
+ static int proc_root_already_exists = TRUE;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
++#define PDE_DATA(inode) PDE(inode)->data
++#endif
++
+ static struct
+ {
+ const unsigned char name[32];
+- int (*read_func) (char* , char **, off_t , int ,int *, void *);
+- int (*write_func) (struct file *, const char * , unsigned long , void *);
++ struct file_operations *fops;
+
+ } proc_if[] = {
+- {"avsar_ver", tn7atm_proc_version, NULL},
+- {"avsar_channels", tn7atm_proc_channels, NULL},
+- {"avsar_sarhal_stats", tn7sar_proc_sar_stat, NULL},
+- {"avsar_oam_ping", tn7sar_proc_oam_ping, NULL},
+- {"avsar_pvc_table", tn7sar_proc_pvc_table, NULL},
+- {"avsar_rxsnr0", tn7dsl_proc_snr0, NULL},
+- {"avsar_rxsnr1", tn7dsl_proc_snr1, NULL},
+- {"avsar_rxsnr2", tn7dsl_proc_snr2, NULL},
+- {"clear_eoc_stats", tn7dsl_proc_eoc, NULL},
+- {"avsar_bit_allocation_table", tn7dsl_proc_bit_allocation, NULL},
+- {"avsar_dsl_modulation_schemes",tn7dsl_proc_train_mode_export, NULL},
++ {"avsar_ver", &tn7atm_proc_version_fops},
++ {"avsar_channels", &tn7atm_proc_channels_fops},
++ {"avsar_sarhal_stats", &tn7sar_proc_sar_stat_fops},
++ {"avsar_oam_ping", &tn7sar_proc_oam_ping_fops},
++ {"avsar_pvc_table", &tn7sar_proc_pvc_table_fops},
++ {"avsar_rxsnr0", &tn7dsl_proc_snr0_fops},
++ {"avsar_rxsnr1", &tn7dsl_proc_snr1_fops},
++ {"avsar_rxsnr2", &tn7dsl_proc_snr2_fops},
++ {"clear_eoc_stats", &tn7dsl_proc_eoc_fops},
++ {"avsar_bit_allocation_table", &tn7dsl_proc_bit_allocation_fops},
++ {"avsar_dsl_modulation_schemes",&tn7dsl_proc_train_mode_export_fops},
+ #ifndef NO_ADV_STATS
+- {"avsar_SNRpsds", tn7dsl_proc_SNRpsds, NULL},
+- {"avsar_QLNpsds", tn7dsl_proc_QLNpsds, NULL},
++ {"avsar_SNRpsds", &tn7dsl_proc_SNRpsds_fops},
++ {"avsar_QLNpsds", &tn7dsl_proc_QLNpsds_fops},
+ // * UR8_MERGE_START CQ10979 Jack Zhang
+ #ifdef TR69_HLIN_IN
+-// {"avsar_HLINpsds", tn7dsl_proc_HLINpsds, NULL},
+- {"avsar_HLINpsds1", tn7dsl_proc_HLINpsds1, NULL},
+- {"avsar_HLINpsds2", tn7dsl_proc_HLINpsds2, NULL},
+- {"avsar_HLINpsds3", tn7dsl_proc_HLINpsds3, NULL},
+- {"avsar_HLINpsds4", tn7dsl_proc_HLINpsds4, NULL},
++// {"avsar_HLINpsds", &tn7dsl_proc_HLINpsds_fops},
++ {"avsar_HLINpsds1", &tn7dsl_proc_HLINpsds1_fops},
++ {"avsar_HLINpsds2", &tn7dsl_proc_HLINpsds2_fops},
++ {"avsar_HLINpsds3", &tn7dsl_proc_HLINpsds3_fops},
++ {"avsar_HLINpsds4", &tn7dsl_proc_HLINpsds4_fops},
+ #endif //TR69_HLIN_IN
+ // * UR8_MERGE_END CQ10979*
+ // * UR8_MERGE_START CQ11057 Jack Zhang
+ #define TR69_PMD_IN
+ #ifdef TR69_PMD_IN
+- {"avsar_PMDTestus", tn7dsl_proc_PMDus, NULL},
+-// {"avsar_PMDTestus1", tn7dsl_proc_PMDus1, NULL},
++ {"avsar_PMDTestus", &tn7dsl_proc_PMDus_fops},
++// {"avsar_PMDTestus1", &tn7dsl_proc_PMDus1_fops},
+ #endif //TR69_PMD_IN
+ // * UR8_MERGE_END CQ11057 *
+ #endif
+- {"avsar_private", tn7atm_proc_private, NULL},
+- {"avsar_modem_training", tn7dsl_proc_modem, NULL},
+- {"avsar_modem_stats", tn7dsl_proc_stats, tn7dsl_proc_write_stats},
++ {"avsar_private", &tn7atm_proc_private_fops},
++ {"avsar_modem_training", &tn7dsl_proc_modem_fops},
++ {"avsar_modem_stats", &tn7dsl_proc_stats_fops},
+
+ #ifdef ADV_DIAG_STATS //CQ10275
+-//for 2.6 {"avsar_modem_adv_stats", tn7dsl_proc_adv_stats, NULL},
++//for 2.6 {"avsar_modem_adv_stats", &tn7dsl_proc_adv_stats_fops},
+ //For 2.4 kernel, due to proc file system size limitation
+- {"avsar_modem_adv_stats1", tn7dsl_proc_adv_stats1, NULL},
+- {"avsar_modem_adv_stats2", tn7dsl_proc_adv_stats2, NULL},
+- {"avsar_modem_adv_stats3", tn7dsl_proc_adv_stats3, NULL},
++ {"avsar_modem_adv_stats1", &tn7dsl_proc_adv_stats1_fops},
++ {"avsar_modem_adv_stats2", &tn7dsl_proc_adv_stats2_fops},
++ {"avsar_modem_adv_stats3", &tn7dsl_proc_adv_stats3_fops},
+ //UR8_MERGE_START CQ10682 Jack Zhang
+- {"avsar_modem_dbg_cmsgs", tn7dsl_proc_dbg_cmsgs, NULL},
+- {"avsar_modem_dbg_rmsgs1", tn7dsl_proc_dbg_rmsgs1, NULL},
+- {"avsar_modem_dbg_rmsgs2", tn7dsl_proc_dbg_rmsgs2, NULL},
+- {"avsar_modem_dbg_rmsgs3", tn7dsl_proc_dbg_rmsgs3, NULL},
+- {"avsar_modem_dbg_rmsgs4", tn7dsl_proc_dbg_rmsgs4, NULL},
++ {"avsar_modem_dbg_cmsgs", &tn7dsl_proc_dbg_cmsgs_fops},
++ {"avsar_modem_dbg_rmsgs1", &tn7dsl_proc_dbg_rmsgs1_fops},
++ {"avsar_modem_dbg_rmsgs2", &tn7dsl_proc_dbg_rmsgs2_fops},
++ {"avsar_modem_dbg_rmsgs3", &tn7dsl_proc_dbg_rmsgs3_fops},
++ {"avsar_modem_dbg_rmsgs4", &tn7dsl_proc_dbg_rmsgs4_fops},
+ // UR8_MERGE_END CQ10682*
+ #endif //ADV_DIAG_STATS
+- {"avsar_qos_enable", tn7atm_proc_qos_read, tn7atm_proc_qos_write}
++ {"avsar_qos_enable", &tn7atm_proc_qos_fops}
+ };
+
+ /* *INDENT-ON* */
+@@ -1709,75 +1703,81 @@ int tn7atm_receive (void *os_dev, int ch
+ return 0;
+ }
+
+-static int tn7atm_proc_channels (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data)
++static int tn7atm_proc_channels (struct seq_file *m, void *data)
+ {
+- int len = 0;
+- int limit = count - 80;
+ int i;
+
+ struct atm_dev *dev;
+ Tn7AtmPrivate *priv;
+
+- dev = (struct atm_dev *) data;
++ dev = (struct atm_dev *) m->private;
+ priv = (Tn7AtmPrivate *) dev->dev_data;
+
+- if (len <= limit)
+- len += sprintf (buf + len, "Chan Inuse ChanID VPI VCI \n");
+- if (len <= limit)
+- len +=
+- sprintf (buf + len,
++ seq_printf (m, "Chan Inuse ChanID VPI VCI \n");
++ seq_printf (m,
+ "------------------------------------------------------------------\n");
+
+ for (i = 0; i <= MAX_DMA_CHAN; i++)
+ {
+- if (len <= limit)
+- {
+- len += sprintf (buf + len,
+- " %02d %05d %05d %05d %05d \n",
+- i, priv->lut[i].inuse, priv->lut[i].chanid,
+- priv->lut[i].vpi, priv->lut[i].vci);
+- }
++ seq_printf (m,
++ " %02d %05d %05d %05d %05d \n",
++ i, priv->lut[i].inuse, priv->lut[i].chanid,
++ priv->lut[i].vpi, priv->lut[i].vci);
+ }
+
+- if (len <= limit)
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "------------------------------------------------------------------\n");
+
+- return len;
++ return 0;
++}
++
++static int tn7atm_proc_channels_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7atm_proc_channels, PDE_DATA(inode));
+ }
+
+-static int tn7atm_proc_private (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data)
++static struct file_operations tn7atm_proc_channels_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7atm_proc_channels_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++
++static int tn7atm_proc_private (struct seq_file *m, void *data)
+ {
+- int len = 0;
+- int limit = count - 80;
+ struct atm_dev *dev;
+ Tn7AtmPrivate *priv;
+
+- dev = (struct atm_dev *) data;
++ dev = (struct atm_dev *) m->private;
+ priv = (Tn7AtmPrivate *) dev->dev_data;
+
+- if (len <= limit)
+- len += sprintf (buf + len, "\nPrivate Data Structure(%s):\n", priv->name);
+- if (len <= limit)
+- len += sprintf (buf + len, "----------------------------------------\n");
+- if (len <= limit)
+- len += sprintf (buf + len, "priv: 0x%p\n", priv);
+- if (len <= limit)
+- len += sprintf (buf + len, "next: 0x%p", priv->next);
+- if (len <= limit)
+- len += sprintf (buf + len, "\tdev: 0x%p\n", priv->dev);
+-
+- if (len <= limit)
+- len += sprintf (buf + len, "tx_irq: %02d", priv->sar_irq);
+- if (len <= limit)
+- len += sprintf (buf + len, "rx_irq: %02d", priv->dsl_irq);
++ seq_printf (m, "\nPrivate Data Structure(%s):\n", priv->name);
++ seq_printf (m, "----------------------------------------\n");
++ seq_printf (m, "priv: 0x%p\n", priv);
++ seq_printf (m, "next: 0x%p", priv->next);
++ seq_printf (m, "\tdev: 0x%p\n", priv->dev);
++
++ seq_printf (m, "tx_irq: %02d", priv->sar_irq);
++ seq_printf (m, "rx_irq: %02d", priv->dsl_irq);
+
+- return len;
++ return 0;
++}
++
++static int tn7atm_proc_private_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7atm_proc_private, PDE_DATA(inode));
+ }
+
++static struct file_operations tn7atm_proc_private_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7atm_proc_private_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ void tn7atm_sarhal_isr_register (void *os_dev, void *hal_isr,
+ int interrupt_num)
+ {
+@@ -1900,10 +1900,8 @@ static int __init tn7atm_register (Tn7At
+ return ATM_REG_OK;
+ }
+
+-static int tn7atm_proc_version (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data)
++static int tn7atm_proc_version (struct seq_file *m, void *data)
+ {
+- int len = 0;
+ char dslVer[8];
+ char dspVer[10];
+ char chipsetID[32]; //CT CQ10076 - Added temporary buffer to store chipset Id
+@@ -1914,56 +1912,64 @@ static int tn7atm_proc_version (char *bu
+
+ priv = mydev->dev_data;
+
+- len +=
+- sprintf (buf + len, "ATM Driver version:[%d.%02d.%02d.%02d]\n",
+- LINUXATM_VERSION_MAJOR, LINUXATM_VERSION_MINOR,
+- LINUXATM_VERSION_BUGFIX, LINUXATM_VERSION_BUILDNUM);
++ seq_printf (m, "ATM Driver version:[%d.%02d.%02d.%02d]\n",
++ LINUXATM_VERSION_MAJOR, LINUXATM_VERSION_MINOR,
++ LINUXATM_VERSION_BUGFIX, LINUXATM_VERSION_BUILDNUM);
+
+ tn7dsl_get_dslhal_version (dslVer);
+
+- len +=
+- sprintf (buf + len, "DSL HAL version: [%d.%02d.%02d.%02d]\n", dslVer[0],
+- dslVer[1], dslVer[2], dslVer[3]);
++ seq_printf (m, "DSL HAL version: [%d.%02d.%02d.%02d]\n", dslVer[0],
++ dslVer[1], dslVer[2], dslVer[3]);
+ tn7dsl_get_dsp_version (dspVer);
+
+- len +=
+- sprintf (buf + len, "DSP Datapump version: [%d.%02d.%02d.%02d] ",
+- dspVer[4], dspVer[5], dspVer[6], dspVer[7]);
++ seq_printf (m, "DSP Datapump version: [%d.%02d.%02d.%02d] ",
++ dspVer[4], dspVer[5], dspVer[6], dspVer[7]);
+ if (dspVer[8] == 2) // annex B
+- len += sprintf (buf + len, "Annex B\n");
++ seq_printf (m, "Annex B\n");
+ else if (dspVer[8] == 3) // annex c
+- len += sprintf (buf + len, "Annex c\n");
++ seq_printf (m, "Annex c\n");
+ else
+- len += sprintf (buf + len, "Annex A\n");
++ seq_printf (m, "Annex A\n");
+
+ tn7sar_get_sar_version (priv, &pSarVer);
+
+- len += sprintf (buf + len, "SAR HAL version: [");
++ seq_printf (m, "SAR HAL version: [");
+ for (i = 0; i < 8; i++)
+ {
+- len += sprintf (buf + len, "%c", pSarVer[i + 7]);
++ seq_printf (m, "%c", pSarVer[i + 7]);
+ }
+- len += sprintf (buf + len, "]\n");
++ seq_printf (m, "]\n");
+
+ tn7sar_get_sar_firmware_version (&pdspV1, &pdspV2);
+- len += sprintf (buf + len, "PDSP Firmware version:[%01x.%02x]\n",
++ seq_printf (m, "PDSP Firmware version:[%01x.%02x]\n",
+ pdspV1, pdspV2);
+
+ //CT CQ10076 - Added code to report chipset ID using proc file system
+ tn7atm_get_chipsetId(chipsetID);
+- len += sprintf (buf + len, "Chipset ID: [%s]\n",chipsetID);
++ seq_printf (m, "Chipset ID: [%s]\n",chipsetID);
+
+- return len;
++ return 0;
+ }
+
++static int tn7atm_proc_version_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7atm_proc_version, PDE_DATA(inode));
++}
++
++static struct file_operations tn7atm_proc_version_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7atm_proc_version_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+
+ /* Device detection */
+
+ static int __init tn7atm_detect (void)
+ {
+ Tn7AtmPrivate *priv;
+- struct proc_dir_entry *dsl_wr_file = NULL; /* Only for ones with a write
+- * function. */
+ int ctr;
+ const char *residual;
+
+@@ -2012,24 +2018,7 @@ static int __init tn7atm_detect (void)
+ */
+ for (ctr = 0; ctr < (NUM_ELEMS (proc_if)); ctr++)
+ {
+- /* Only if we have a write function, we create a normal proc file. */
+- if(proc_if[ctr].write_func)
+- {
+- dsl_wr_file = create_proc_entry (proc_if[ctr].name, DRV_PROC_MODE, root_proc_dir_entry);
+- if (dsl_wr_file)
+- {
+- dsl_wr_file->read_proc = proc_if[ctr].read_func;
+- dsl_wr_file->write_proc = proc_if[ctr].write_func;
+- dsl_wr_file->data = (void *)mydev; //UR8_MERGE_START_END CQ10700 Manjula K
+- }
+- dsl_wr_file = NULL;
+- }
+- else
+- {
+- /* Create a read-only entry. */
+- create_proc_read_entry (proc_if[ctr].name, 0, root_proc_dir_entry,
+- proc_if[ctr].read_func, mydev);
+- }
++ proc_create_data(proc_if[ctr].name, DRV_PROC_MODE, root_proc_dir_entry, proc_if[ctr].fops, (void *)mydev);
+ }
+
+ tn7dsl_dslmod_sysctl_register ();
+@@ -2501,63 +2490,10 @@ static int tn7atm_set_can_support_adsl2
+ return TRUE;
+ }
+
+-/*
+- * This function matches a name such as "serial", and that specified by the
+- * proc_dir_entry
+- */
+-static int tn7atm_proc_match (int len, const char *name,
+- struct proc_dir_entry *de)
++static int tn7atm_proc_qos_read(struct seq_file *m, void *data)
+ {
+- if (!de || !de->low_ino)
+- return 0;
+- if (de->namelen != len)
++ seq_printf (m, "\nEnableQoS = %d\n", EnableQoS);
+ return 0;
+- return !strncmp (name, de->name, len);
+-}
+-
+-/*
+- * This function parses a name such as "tty/driver/serial", and
+- * returns the struct proc_dir_entry for "/proc/tty/driver", and
+- * returns "serial" in residual.
+- */
+-static int tn7atm_xlate_proc_name (const char *name,
+- struct proc_dir_entry **ret,
+- const char **residual)
+-{
+- const char *cp = name, *next;
+- struct proc_dir_entry *de;
+- int len;
+- extern struct proc_dir_entry proc_root;
+-
+- de = &proc_root;
+- while (1)
+- {
+- next = strchr (cp, '/');
+- if (!next)
+- break;
+-
+- len = next - cp;
+- for (de = de->subdir; de; de = de->next)
+- {
+- if (tn7atm_proc_match (len, cp, de))
+- break;
+- }
+- if (!de)
+- return -ENOENT;
+- cp += len + 1;
+- }
+- *residual = cp;
+- *ret = de;
+-
+- return 0;
+-}
+-
+-static int tn7atm_proc_qos_read(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+-{
+- int len = 0;
+-
+- len += sprintf (buf + len, "\nEnableQoS = %d\n", EnableQoS);
+- return len;
+
+ }
+ static int tn7atm_proc_qos_write(struct file *fp, const char *buf, unsigned long count, void *data)
+@@ -2591,5 +2527,19 @@ static int tn7atm_proc_qos_write(struct
+ return count;
+ }
+
++static int tn7atm_proc_qos_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7atm_proc_qos_read, PDE_DATA(inode));
++}
++
++static struct file_operations tn7atm_proc_qos_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7atm_proc_qos_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++ .write = tn7atm_proc_qos_write,
++};
++
+ module_init (tn7atm_detect);
+ module_exit (tn7atm_exit);
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -221,6 +221,9 @@ static struct led_funcs ledreg[2];
+
+ #define tn7dsl_kfree_skb(x) dev_kfree_skb(x)
+
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
++#define PDE_DATA(inode) PDE(inode)->data
++#endif
+
+ //---------------------------------------------
+ // Begin Clear EOC definitions
+@@ -349,7 +352,7 @@ static void tn7dsl_register_dslss_led(vo
+ void tn7dsl_dslmod_sysctl_register(void);
+ void tn7dsl_dslmod_sysctl_unregister(void);
+ static int tn7dsl_clear_eoc_receive(void);
+-static int tn7dsl_proc_snr_print (char *buf, int count, int *eof, int data);
++static int tn7dsl_proc_snr_print (struct seq_file *m, int data);
+ /* end of internal functions */
+
+ // UR8_MERGE_START CQ11054 Jack Zhang
+@@ -649,11 +652,9 @@ void shim_osCriticalExit(void)
+ spin_unlock_irqrestore(&shimLock, flags);
+ }
+
+-static int tn7dsl_proc_snr_print (char *buf, int count, int *eof, int data)
++static int tn7dsl_proc_snr_print (struct seq_file *m, int data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ int i, j;
+ int bin = (int) data;
+ unsigned short *rxSnrPerBin;
+@@ -674,95 +675,128 @@ static int tn7dsl_proc_snr_print (char *
+ break;
+
+ default:
+- if(len<=limit)
+- len += sprintf (buf + len, "\nInvalid bin selected Bin%d :\n", bin);
+- return len;
+-}
++ seq_printf (m, "\nInvalid bin selected Bin%d :\n", bin);
++ return 0;
++ }
+
+- if(len<=limit)
+- len += sprintf (buf + len, "\nAR7 DSL Modem Rx SNR Per Bin for Bin%d :\n", bin);
++ seq_printf (m, "\nAR7 DSL Modem Rx SNR Per Bin for Bin%d :\n", bin);
+
+ for (i=0; i<pIhw->AppData.max_ds_tones/16; i++)
+ {
+ for(j=0;j<16;j++)
+ {
+- if(len <=limit)
+- len +=
+- sprintf (buf + len, "%04x ",
++ seq_printf (m, "%04x ",
+ (unsigned short) rxSnrPerBin[i * 16 + j]);
+- }
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
+ }
++ seq_printf(m, "\n");
++ }
+
+- return len;
++ return 0;
+ }
+
+
+ //@Added SNR per bin info per customer request. 05-14-2004
+-int tn7dsl_proc_snr0 (char *buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_snr0 (struct seq_file *m, void *data)
+ {
+- return tn7dsl_proc_snr_print(buf, count, eof, 0);
++ return tn7dsl_proc_snr_print(m, 0);
+ }
+
+-int tn7dsl_proc_snr1 (char *buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_snr0_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_snr_print(buf, count, eof, 1);
++ return single_open(file, tn7dsl_proc_snr0, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_snr0_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_snr0_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++static int tn7dsl_proc_snr1 (struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_snr_print(m, 1);
+ }
+
+-int tn7dsl_proc_snr2 (char *buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_snr1_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_snr_print(buf, count, eof, 2);
++ return single_open(file, tn7dsl_proc_snr1, PDE_DATA(inode));
+ }
+
++struct file_operations tn7dsl_proc_snr1_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_snr1_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++static int tn7dsl_proc_snr2 (struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_snr_print(m, 2);
++}
++
++static int tn7dsl_proc_snr2_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_snr2, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_snr2_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_snr2_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ //@Added bit allocation table per customer request. 05-14-2004
+-int tn7dsl_proc_bit_allocation (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data)
++static int tn7dsl_proc_bit_allocation (struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ int i, j;
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 DSL Modem US Bit Allocation:");
++ seq_printf(m, "\nAR7 DSL Modem US Bit Allocation:");
+
+ for(i=0; i<pIhw->AppData.max_us_tones; i++)
+ {
+ if (!(i%16))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len <=limit)
+- len +=
+- sprintf (buf + len, "%02x ",
+- (unsigned char) pIhw->AppData.BitAllocTblUstrm[i]);
++ seq_printf (m, "%02x ",
++ (unsigned char) pIhw->AppData.BitAllocTblUstrm[i]);
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\nAR7 DSL Modem DS Bit Allocation:\n");
++ seq_printf(m, "\n\nAR7 DSL Modem DS Bit Allocation:\n");
+
+ for (i=0; i<pIhw->AppData.max_ds_tones/16; i++)
+ {
+ for(j=0;j<16;j++)
+ {
+- if(len <=limit)
+- len +=
+- sprintf (buf + len, "%02x ",
+- (unsigned char) pIhw->AppData.BitAllocTblDstrm[i * 16 +
+- j]);
++ seq_printf (m, "%02x ",
++ (unsigned char) pIhw->AppData.BitAllocTblDstrm[i * 16 +
++ j]);
+ }
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- return len;
++ return 0;
++}
++
++int tn7dsl_proc_bit_allocation_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_bit_allocation, PDE_DATA(inode));
+ }
+
++struct file_operations tn7dsl_proc_bit_allocation_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_bit_allocation_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #ifndef NO_ACT
+ int tn7dsl_proc_ds_noise(char* buf, char **start, off_t offset, int count,
+ int *eof, void *data)
+@@ -825,59 +859,48 @@ static char *pUnknown= "Unknown";
+ #ifdef ADV_DIAG_STATS //CQ10275, CQ10449
+ //UR8_MERGE_START CQ10449 Jack Zhang
+
+-static int proc_adv_stats_header(char* buf, int limit);
++static int proc_adv_stats_header(struct seq_file *m);
+
+-int tn7dsl_proc_adv_stats(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_adv_stats(struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ //char *cp = buf + offset;
+ char *cp = buf;
+ int i = 0;
+ int strt = 32;
+- static int ctr = 0;
+
+ // printk("proc_adv_stats: buf=0x%X, ctr=%d, offset=%d, count=%d, eof=%d\n",
+ // (unsigned int)buf, ctr, offset, count, *eof);
+- if( ctr == 0)
+- {
+- len = proc_adv_stats_header( cp, limit);
+-
+- if( len<=limit)
+- len += sprintf(cp+len, "\n\tBin No.\tBits:\tMargin:\tSNR\n");
+- }
+- else
+- {
+- strt = ctr;
+- }
+-
++ proc_adv_stats_header(m);
++
++ seq_printf(m, "\n\tBin No.\tBits:\tMargin:\tSNR\n");
++
+ for( i =strt; i<512; i++)
+ {
+- if(len<=limit)
+- {
+- len += sprintf(cp+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (int)pIhw->AppData.rxSnrPerBin0[i]);
+- }
+- else
+- {
+- ctr = i;
+- //*eof = 0;
+- *(cp + len) = '\0';
+- printk("proc_adv_stats - return: ctr=%d, len=%d\n", ctr, len);
+- return len;
+- }
+ }
+- ctr = 0;
+- *eof = 1;
+ printk("proc_adv_stats - return: ctr=%d, len=%d\n", ctr, len);
+- return len;
++ return 0;
++}
++
++
++static int tn7dsl_proc_adv_stats_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_adv_stats, PDE_DATA(inode));
+ }
+
+-static int proc_adv_stats_header(char* buf, int limit)
++struct file_operations tn7dsl_proc_adv_stats_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_adv_stats_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++static int proc_adv_stats_header(struct seq_file *m)
+ {
+ int len = 0;
+ int i = 0;
+@@ -886,66 +909,53 @@ static int proc_adv_stats_header(char* b
+ */
+
+ dslhal_api_gatherStatistics(pIhw);
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 DSL Modem Advanced Statistics:\n");
++ seq_printf(m, "\nAR7 DSL Modem Advanced Statistics:\n");
+
+- if(len<=limit)
++ if(pIhw->lConnected != 1)
+ {
+- if(pIhw->lConnected != 1)
+- {
+- pIhw->AppData.USConRate = 0;
+- pIhw->AppData.DSConRate = 0;
+- }
+- len +=
+- sprintf (buf + len,
++ pIhw->AppData.USConRate = 0;
++ pIhw->AppData.DSConRate = 0;
++ }
++ seq_printf (m,
+ "\t[Connection Rate]\tUS:\t%u\tDS:\t%u\n",
+ (unsigned int)pIhw->AppData.USConRate,
+ (unsigned int)pIhw->AppData.DSConRate );
+ }
+- if(len<=limit)
+ // UR8_MERGE_START CQ11054 Jack Zhang
++ if (dslhal_api_getHighPrecision())
+ {
+- if (dslhal_api_getHighPrecision())
+- {
+- len +=
+- sprintf (buf + len, "\t[Margin]\tUS:\t%d.%u\tDS:\t\t%d.%u\n",
+- gInt(pIhw->AppData.usMargin), gDot1(pIhw->AppData.usMargin),
+- gInt(pIhw->AppData.dsMargin), gDot1(pIhw->AppData.dsMargin));
+- }
+- else
+- {
+- len +=
+- sprintf (buf + len, "\t[Margin]\tUS:\t%u\tDS:\t\t%u\n",
+- (unsigned int)pIhw->AppData.usMargin,
+- (unsigned int)pIhw->AppData.dsMargin/2 );
+- }
++ seq_printf (m, "\t[Margin]\tUS:\t%d.%u\tDS:\t\t%d.%u\n",
++ gInt(pIhw->AppData.usMargin), gDot1(pIhw->AppData.usMargin),
++ gInt(pIhw->AppData.dsMargin), gDot1(pIhw->AppData.dsMargin));
++ }
++ else
++ {
++ seq_printf (m, "\t[Margin]\tUS:\t%u\tDS:\t\t%u\n",
++ (unsigned int)pIhw->AppData.usMargin,
++ (unsigned int)pIhw->AppData.dsMargin/2 );
+ }
+ // UR8_MERGE_END CQ11054*
+
+ /*
+ * Downstream/Upstream Interleaved Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\t[Interleave path] US (TX):\tCRC: \t%u\tFEC: \t%u\n",
++ seq_printf(m, "\t[Interleave path] US (TX):\tCRC: \t%u\tFEC: \t%u\n",
+ (unsigned int)pIhw->AppData.usICRC_errors,
+ (unsigned int)pIhw->AppData.usIFEC_errors);
+- if(len<=limit)
+- len += sprintf(buf+len, "\t[Interleave path] DS (RX):\tCRC: \t%u\tFEC: \t%u\n",
++ seq_printf(m, "\t[Interleave path] DS (RX):\tCRC: \t%u\tFEC: \t%u\n",
+ (unsigned int)pIhw->AppData.dsICRC_errors,
+ (unsigned int)pIhw->AppData.dsIFEC_errors);
+ /*
+ * Upstream/Downstream Fast Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\t[Fast path] US (TX): \tCRC: \t%u\tFEC: \t%u\n",
++ seq_printf(m, "\t[Fast path] US (TX): \tCRC: \t%u\tFEC: \t%u\n",
+ (unsigned int)pIhw->AppData.usFCRC_errors,
+ (unsigned int)pIhw->AppData.usFFEC_errors);
+- if(len<=limit)
+- len += sprintf(buf+len, "\t[Fast path] DS (RX):\tCRC: \t%u\tFEC: \t%u\n",
++ seq_printf(m, "\t[Fast path] DS (RX):\tCRC: \t%u\tFEC: \t%u\n",
+ (unsigned int)pIhw->AppData.dsFCRC_errors,
+ (unsigned int)pIhw->AppData.dsFFEC_errors);
+-
+- return len;
++
++ return 0;
+ }
+
+ static int getDiagDisplayMode()
+@@ -968,29 +978,24 @@ static int getDiagDisplayMode()
+ ret = 2;
+ return ret;
+ }
+-int tn7dsl_proc_adv_stats1(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++int tn7dsl_proc_adv_stats1(struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ int i;
+ int mode = 0; //mode = 0 => ADSL1 or ADSL2 & 2+
+ unsigned char SNRpsds[512];
+ int n;
+
+- len = proc_adv_stats_header( buf+len, limit);
++ proc_adv_stats_header( m);
+ mode = getDiagDisplayMode();
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\tBin No.\tBits:\tMargin:\tSNR (Part 1 of 3)\n");
+-
++ seq_printf(m, "\tBin No.\tBits:\tMargin:\tSNR (Part 1 of 3)\n");
++
+ if(mode==1) //ADSL1
+ {
+ for( i =32; i<128; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (int)pIhw->AppData.rxSnrPerBin0[i]);
+@@ -1001,26 +1006,34 @@ int tn7dsl_proc_adv_stats1(char* buf, ch
+ if (dslhal_api_getSNRpsds(pIhw, SNRpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getSNRpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+ for( i =32; i<128; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (i<pIhw->AppData.max_ds_tones)?(unsigned char)SNRpsds[i]:0);
+ }
+ }
+- return len;
++ return 0;
+ }
+
+-int tn7dsl_proc_adv_stats2(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_adv_stats1_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_adv_stats1, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++struct file_operations tn7dsl_proc_adv_stats1_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_adv_stats1_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++int tn7dsl_proc_adv_stats2(struct seq_file *m, void *data)
++{
+ int i;
+ int mode = 0; //mode = 0 => ADSL1 or ADSL2 & 2+
+ unsigned char SNRpsds[512];
+@@ -1030,12 +1043,10 @@ int tn7dsl_proc_adv_stats2(char* buf, ch
+ if( mode==1) //ADSL1
+ {
+ dslhal_api_gatherStatistics(pIhw);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tBin No.\tBits:\tMargin:\tSNR (Part 2 of 3):\n");
++ seq_printf(m, "\tBin No.\tBits:\tMargin:\tSNR (Part 2 of 3):\n");
+ for( i =128; i<320; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (int)pIhw->AppData.rxSnrPerBin0[i]);
+@@ -1046,26 +1057,35 @@ int tn7dsl_proc_adv_stats2(char* buf, ch
+ if (dslhal_api_getSNRpsds(pIhw, SNRpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getSNRpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+ for( i =128; i<320; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (i<pIhw->AppData.max_ds_tones)?(unsigned char)SNRpsds[i]:0);
+ }
+ }
+- return len;
++ return 0;
+ }
+
+-int tn7dsl_proc_adv_stats3(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_adv_stats2_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_adv_stats2, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_adv_stats2_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_adv_stats2_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++int tn7dsl_proc_adv_stats3(struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ int i;
+ int mode = 0; //mode = 0 => ADSL1 or ADSL2 & 2+
+ unsigned char SNRpsds[512];
+@@ -1075,12 +1095,10 @@ int tn7dsl_proc_adv_stats3(char* buf, ch
+ if( mode==1) //ADSL1
+ {
+ dslhal_api_gatherStatistics(pIhw);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tBin No.\tBits:\tMargin:\tSNR (Part 3 of 3):\n");
++ seq_printf(m, "\tBin No.\tBits:\tMargin:\tSNR (Part 3 of 3):\n");
+ for( i =320; i<512; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (int)pIhw->AppData.rxSnrPerBin0[i]);
+@@ -1091,283 +1109,287 @@ int tn7dsl_proc_adv_stats3(char* buf, ch
+ if (dslhal_api_getSNRpsds(pIhw, SNRpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getSNRpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+ for( i =320; i<512; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (i<pIhw->AppData.max_ds_tones)?(unsigned char)SNRpsds[i]:0);
+ }
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "[End of Stats]\n");
+- return len;
++ seq_printf(m, "[End of Stats]\n");
++ return 0;
+ }
+-//UR8_MERGE_END CQ10449
+-//UR8_MERGE_START CQ10682 Jack Zhang
+-int tn7dsl_proc_dbg_cmsgs(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++
++static int tn7dsl_proc_adv_stats3_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_adv_stats3, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++struct file_operations tn7dsl_proc_adv_stats3_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_adv_stats3_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
+
++//UR8_MERGE_END CQ10449
++//UR8_MERGE_START CQ10682 Jack Zhang
++int tn7dsl_proc_dbg_cmsgs(struct seq_file *m, void *data)
++{
+ int rc=0;
+
+ dslhal_api_gatherStatistics(pIhw);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "Training Messages (C-Msgs 1-5)..\n");
++ seq_printf(m, "Training Messages (C-Msgs 1-5)..\n");
+
+- if(len<=limit)
+- len += sprintf(buf+len, "ADSL2 DELT C-Msg1Ld \t Message Length:%d\n",
++ seq_printf(m, "ADSL2 DELT C-Msg1Ld \t Message Length:%d\n",
+ pIhw->adsl2DiagnosticMessages.cMsg1LdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.cMsg1LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg1Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg1Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT C-Msg2Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg2LdLen);
++ seq_printf(m, "\nADSL2 DELT C-Msg2Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg2LdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.cMsg2LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg2Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg2Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT C-Msg3Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg3LdLen);
++ seq_printf(m, "\nADSL2 DELT C-Msg3Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg3LdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.cMsg3LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg3Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg3Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT C-Msg4Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg4LdLen);
++ seq_printf(m, "\nADSL2 DELT C-Msg4Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg4LdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.cMsg4LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg4Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg4Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT C-Msg5Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg5LdLen);
++ seq_printf(m, "\nADSL2 DELT C-Msg5Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg5LdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.cMsg5LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg5Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg5Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
+- return len;
++ seq_printf(m, "\n");
++ return 0;
+ }
+
+-int tn7dsl_proc_dbg_rmsgs1(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_dbg_cmsgs_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_dbg_cmsgs, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_dbg_cmsgs_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_dbg_cmsgs_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
+
+- int len = 0;
+- int limit = count - 80;
++
++int tn7dsl_proc_dbg_rmsgs1(struct seq_file *m, void *data)
++{
+
+ int rc=0;
+
+ dslhal_api_gatherStatistics(pIhw);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "Training Messages (R-Msgs 1-3)..\n");
++ seq_printf(m, "Training Messages (R-Msgs 1-3)..\n");
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg1Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsg1LdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg1Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsg1LdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsg1LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg1Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg1Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg2Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg2Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg2Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg2Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg3Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg3Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg3Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg3Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
+- return len;
++ seq_printf(m, "\n");
++ return 0;
+ }
+
+-int tn7dsl_proc_dbg_rmsgs2(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_dbg_rmsgs1_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_dbg_rmsgs1, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++struct file_operations tn7dsl_proc_dbg_rmsgs1_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_dbg_rmsgs1_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++
++int tn7dsl_proc_dbg_rmsgs2(struct seq_file *m, void *data)
++{
+
+ int rc=0;
+
+ dslhal_api_gatherStatistics(pIhw);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "Training Messages (R-Msgs 4-5)..\n");
++ seq_printf(m, "Training Messages (R-Msgs 4-5)..\n");
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg4Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg4Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg4Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg4Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ len += sprintf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg5Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg5Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg5Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg5Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
+- return len;
++ seq_printf(m, "\n");
++ return 0;
+ }
+
+-int tn7dsl_proc_dbg_rmsgs3(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_dbg_rmsgs2_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_dbg_rmsgs2, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++struct file_operations _fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_dbg_rmsgs2_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++int tn7dsl_proc_dbg_rmsgs3(struct seq_file *m, void *data)
++{
+
+ int rc=0;
+
+ dslhal_api_gatherStatistics(pIhw);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "Training Messages (R-Msgs 6-7)..\n");
++ seq_printf(m, "Training Messages (R-Msgs 6-7)..\n");
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg6Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg6Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg6Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg6Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg7Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg7Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg7Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg7Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+- return len;
++ return 0;
+ }
+
+-int tn7dsl_proc_dbg_rmsgs4(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_dbg_rmsgs3_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_dbg_rmsgs3, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++struct file_operations tn7dsl_proc_dbg_rmsgs3_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_dbg_rmsgs3_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++int tn7dsl_proc_dbg_rmsgs4(struct seq_file *m, void *data)
++{
+
+ int rc=0;
+
+ dslhal_api_gatherStatistics(pIhw);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "Training Messages (R-Msgs 8-9)..\n");
++ seq_printf(m, "Training Messages (R-Msgs 8-9)..\n");
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg8Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg8Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg8Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg8Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg9Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg9Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg9Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg9Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+- return len;
++ return 0;
++}
++
++static int tn7dsl_proc_dbg_rmsgs4_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_dbg_rmsgs4, PDE_DATA(inode));
+ }
++
++struct file_operations tn7dsl_proc_dbg_rmsgs4_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_dbg_rmsgs4_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ //UR8_MERGE_END CQ10682*
+ #endif //ADV_DIAG_STATS
+
+-int tn7dsl_proc_stats(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_stats(struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ int F4count, F5count;
+ unsigned int maxRate=0;
+ unsigned int us_maxRate=0;
+@@ -1375,80 +1397,58 @@ int tn7dsl_proc_stats(char* buf, char **
+ //UR8_MERGE_START CQ10700 Manjula K
+ struct atm_dev *dev;
+ Tn7AtmPrivate *priv;
+- dev = (struct atm_dev *)data;
++ int offset[2] = { 32, 0 };
++ unsigned int usBitswap, dsBitswap;
++ dev = (struct atm_dev *)m->private;
+ priv = (Tn7AtmPrivate *)dev->dev_data;
+ //UR8_MERGE_END CQ10700
+
++
+ /*
+ * Read Ax5 Stats
+ */
+
+ dslhal_api_gatherStatistics(pIhw);
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 DSL Modem Statistics:\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "--------------------------------\n");
++ seq_printf(m, "\nAR7 DSL Modem Statistics:\n");
++ seq_printf(m, "--------------------------------\n");
+ /*
+ * us and ds Connection Rates
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "[DSL Modem Stats]\n");
++ seq_printf(m, "[DSL Modem Stats]\n");
+
+
+- if(len<=limit)
++ if(pIhw->lConnected != 1)
+ {
+- if(pIhw->lConnected != 1)
+- {
+- pIhw->AppData.USConRate = 0;
+- pIhw->AppData.DSConRate = 0;
+- }
+- len +=
+- sprintf (buf + len,
+- "\tUS Connection Rate:\t%u\tDS Connection Rate:\t%u\n",
+- (unsigned int)pIhw->AppData.USConRate,
+- (unsigned int)pIhw->AppData.DSConRate );
++ pIhw->AppData.USConRate = 0;
++ pIhw->AppData.DSConRate = 0;
+ }
+- if(len<=limit)
++ seq_printf (m,
++ "\tUS Connection Rate:\t%u\tDS Connection Rate:\t%u\n",
++ (unsigned int)pIhw->AppData.USConRate,
++ (unsigned int)pIhw->AppData.DSConRate );
+ // UR8_MERGE_START CQ11054 Jack Zhang
+- {
+- if (dslhal_api_getHighPrecision())
+- {
+- len +=
+- sprintf (buf + len, "\tDS Line Attenuation:\t%u.%u\tDS Margin:\t\t%d.%u\n",
++ if (dslhal_api_getHighPrecision())
++ seq_printf (m, "\tDS Line Attenuation:\t%u.%u\tDS Margin:\t\t%d.%u\n",
+ gInt(pIhw->AppData.dsLineAttn), gDot1(pIhw->AppData.dsLineAttn),
+ gInt(pIhw->AppData.dsMargin), gDot1(pIhw->AppData.dsMargin));
+- }
+- else{
+- len +=
+- sprintf (buf + len, "\tDS Line Attenuation:\t%u\tDS Margin:\t\t%u\n",
++ else
++ seq_printf (m, "\tDS Line Attenuation:\t%u\tDS Margin:\t\t%u\n",
+ (unsigned int)pIhw->AppData.dsLineAttn/2,
+ (unsigned int)pIhw->AppData.dsMargin/2 );
+- }
+- }
+ // UR8_MERGE_END CQ11054*
+
+- if(len<=limit)
+ // UR8_MERGE_START CQ11054 Jack Zhang
+- {
+- if (dslhal_api_getHighPrecision())
+- {
+- len +=
+- sprintf (buf + len, "\tUS Line Attenuation:\t%u.%u\tUS Margin:\t\t%d.%u\n",
++ if (dslhal_api_getHighPrecision())
++ seq_printf (m, "\tUS Line Attenuation:\t%u.%u\tUS Margin:\t\t%d.%u\n",
+ gInt(pIhw->AppData.usLineAttn), gDot1(pIhw->AppData.usLineAttn),
+ gInt(pIhw->AppData.usMargin), gDot1(pIhw->AppData.usMargin));
+- }
+- else
+- {
+- len +=
+- sprintf (buf + len, "\tUS Line Attenuation:\t%u\tUS Margin:\t\t%u\n",
++ else
++ seq_printf (m, "\tUS Line Attenuation:\t%u\tUS Margin:\t\t%u\n",
+ (unsigned int)pIhw->AppData.usLineAttn/2,
+ (unsigned int)pIhw->AppData.usMargin );
+- }
+- }
+ // UR8_MERGE_END CQ11054*
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\tUS Payload :\t\t%u\tDS Payload:\t\t%u\n",
++ seq_printf(m, "\tUS Payload :\t\t%u\tDS Payload:\t\t%u\n",
+ ((unsigned int) pIhw->AppData.usAtm_count[0] +
+ (unsigned int) pIhw->AppData.usAtm_count[1]) * 48,
+ ((unsigned int) pIhw->AppData.dsGood_count[0] +
+@@ -1456,9 +1456,7 @@ int tn7dsl_proc_stats(char* buf, char **
+ /*
+ * Superframe Count
+ */
+- if(len<=limit)
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "\tUS Superframe Cnt :\t%u\tDS Superframe Cnt:\t%u\n",
+ (unsigned int)pIhw->AppData.usSuperFrmCnt,
+ (unsigned int)pIhw->AppData.dsSuperFrmCnt );
+@@ -1466,57 +1464,45 @@ int tn7dsl_proc_stats(char* buf, char **
+ /*
+ * US and DS power
+ */
+- if(len<=limit)
++ if(pIhw->AppData.bState < 5)
+ {
+- if(pIhw->AppData.bState < 5)
+- {
+- pIhw->AppData.usTxPower = 0;
+- pIhw->AppData.dsTxPower = 0;
+- }
+- len +=
+- sprintf (buf + len,
++ pIhw->AppData.usTxPower = 0;
++ pIhw->AppData.dsTxPower = 0;
++ }
++ seq_printf (m,
++// UR8_MERGE_START - CQ11579 - Jeremy #1
+ "\tUS Transmit Power :\t%u\tDS Transmit Power:\t%u\n",
+ (unsigned int)pIhw->AppData.usTxPower/256,
+ (unsigned int)pIhw->AppData.dsTxPower/256 );
+- }
++// UR8_MERGE_END - CQ11579
+ /*
+ * DSL Stats Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\tLOS errors:\t\t%u\tSEF errors:\t\t%u\n",
++ seq_printf(m, "\tLOS errors:\t\t%u\tSEF errors:\t\t%u\n",
+ (unsigned int)pIhw->AppData.LOS_errors,
+ (unsigned int)pIhw->AppData.SEF_errors );
+
+ //UR8_MERGE_START Report_SES Manjula K
+ //CQ10369
+- if(len<=limit)
+- len += sprintf(buf+len, "\tErrored Seconds:\t%u\tSeverely Err Secs:\t%u\n",
++ seq_printf(m, "\tErrored Seconds:\t%u\tSeverely Err Secs:\t%u\n",
+ (unsigned int)pIhw->AppData.erroredSeconds,
+ (unsigned int)pIhw->AppData.severelyerrsecs );
+ //UR8_MERGE_END Report_SES
+-
+- if(len<=limit)
+- len += sprintf(buf+len, "\tFrame mode:\t\t%u\tMax Frame mode:\t\t%u\n",
++
++ seq_printf(m, "\tFrame mode:\t\t%u\tMax Frame mode:\t\t%u\n",
+ (unsigned int)pIhw->AppData.FrmMode,
+ (unsigned int)pIhw->AppData.MaxFrmMode );
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tTrained Path:\t\t%u\tUS Peak Cell Rate:\t%u\n",
++ seq_printf (m, "\tTrained Path:\t\t%u\tUS Peak Cell Rate:\t%u\n",
+ (unsigned int)pIhw->AppData.TrainedPath,
+ (unsigned int)pIhw->AppData.USConRate*1000/8/53 );
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tTrained Mode:\t\t%u\tSelected Mode:\t\t%u\n",
++ seq_printf (m, "\tTrained Mode:\t\t%u\tSelected Mode:\t\t%u\n",
+ (unsigned int) pIhw->AppData.TrainedMode,
+ (unsigned int) pIhw->AppData.StdMode);
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tATUC Vendor Code:\t%X\tATUC Revision:\t%u\n",
++ seq_printf (m, "\tATUC Vendor Code:\t%X\tATUC Revision:\t%u\n",
+ (unsigned int) pIhw->AppData.atucVendorId,
+ pIhw->AppData.atucRevisionNum);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tHybrid Selected:\t%u\tTrellis:\t\t%u\n",
++ seq_printf(m, "\tHybrid Selected:\t%u\tTrellis:\t\t%u\n",
+ (unsigned int)pIhw->AppData.currentHybridNum, trellis);
+
+ //@Added Maximum attainable bit rate information. 05-14-2004
+@@ -1528,12 +1514,12 @@ int tn7dsl_proc_stats(char* buf, char **
+ }
+ else
+ {
+- int offset[2] = {5, 1};
++ int dspOffset[2] = { 5, 1 };
+ unsigned char rMsgsRA[12];
+ int numPayloadBytes = 0;
+
+ dslhal_api_dspInterfaceRead (pIhw, (unsigned int) pIhw->pmainAddr, 2,
+- (unsigned int *) &offset,
++ (unsigned int *) &dspOffset,
+ (unsigned char *) &rMsgsRA[0], 12);
+
+ maxRate = (unsigned int)pIhw->AppData.DSConRate;
+@@ -1549,283 +1535,213 @@ int tn7dsl_proc_stats(char* buf, char **
+ }
+ }
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "\tShowtime Count:\t\t%u\tDS Max Attainable Bit Rate: %u kbps\n",
+ (unsigned int)pIhw->AppData.showtimeCount, maxRate);
+
+- if(len<=limit)
+- {
+- int offset[2] = {32, 0};
+- unsigned int usBitswap, dsBitswap;
++ tn7dsl_generic_read(2, (unsigned int *)&offset);
++ dsBitswap = dslReg & dslhal_support_byteSwap32(0x000000ff);
+
+- tn7dsl_generic_read(2, (unsigned int *)&offset);
+- dsBitswap = dslReg & dslhal_support_byteSwap32(0x000000ff);
++ offset[0] = 33;
++ tn7dsl_generic_read(2, (unsigned int *)&offset);
++ usBitswap = dslReg & dslhal_support_byteSwap32(0x000000ff);
+
+- offset[0] = 33;
+- tn7dsl_generic_read(2, (unsigned int *)&offset);
+- usBitswap = dslReg & dslhal_support_byteSwap32(0x000000ff);
+-
+- if(pIhw->AppData.dsl_modulation > 5)
+- len +=
+- sprintf (buf + len,
++ if(pIhw->AppData.dsl_modulation > 5)
++ seq_printf (m,
+ "\tBitSwap:\t\t%u\tUS Max Attainable Bit Rate: %u bps\n",
+ (unsigned int)(usBitswap && dsBitswap), us_maxRate);
+- else
+- len +=
+- sprintf (buf + len,
++ else
++ seq_printf (m,
+ "\tBitSwap:\t\t%u\tUS Max Attainable Bit Rate:\tn/a\n",
+ (unsigned int)(usBitswap && dsBitswap));
+- }
+
+ #if 1 // TR69
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tAnnex: \t\t\t%s\tpsd_mask_qualifier: 0x%04x\n",
++ seq_printf (m, "\tAnnex: \t\t\t%s\tpsd_mask_qualifier: 0x%04x\n",
+ tn7dsl_AnnexFromNum(pIhw->AppData.annex_selected),
+ pIhw->AppData.psd_mask_qualifier);
+
+ // UR8_MERGE_START CQ10979 Jack Zhang
+ // UR8_MERGE_START CQ10978 Jack Zhang
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tPower Management Status: L%d\tDS HLINSC: %d\n",
++ seq_printf (m, "\tPower Management Status: L%d\tDS HLINSC: %d\n",
+ pIhw->AppData.pwrStatus, pIhw->AppData.dsHLINSC);
+ // UR8_MERGE_END CQ10978*
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tUS ACTPSD: \t\t%d\tDS ACTPSD: %d\n",
++ seq_printf (m, "\tUS ACTPSD: \t\t%d\tDS ACTPSD: %d\n",
+ pIhw->AppData.usACTPSD, pIhw->AppData.dsACTPSD);
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tTotal init. errors: \t%d\tTotal init. timeouts: %d\n",
++ seq_printf (m, "\tTotal init. errors: \t%d\tTotal init. timeouts: %d\n",
+ pIhw->AppData.totalInitErrs, pIhw->AppData.totalInitTOs);
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tShowtime init. errors: \t%d\tShowtime init. timeouts: %d\n",
++ seq_printf (m, "\tShowtime init. errors: \t%d\tShowtime init. timeouts: %d\n",
+ pIhw->AppData.showtimeInitErrs, pIhw->AppData.showtimeInitTOs);
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tLast showtime init. errors: %ld\tLast showtime init. timeouts: %ld\n",
++ seq_printf (m, "\tLast showtime init. errors: %ld\tLast showtime init. timeouts: %ld\n",
+ pIhw->AppData.lastshowInitErrs, pIhw->AppData.lastshowInitTOs);
+ // UR8_MERGE_END CQ10979*
+
+- if (len<=limit)
+- {
+- len += sprintf(buf+len,"\tATUC ghsVid: ");
+- for (i=0; i<8; i++)
+- len+= sprintf(buf+len, " %02x", pIhw->AppData.ghsATUCVendorId[i]);
+- }
++ seq_printf(m,"\tATUC ghsVid: ");
++ for (i=0; i<8; i++)
++ seq_printf(m, " %02x", pIhw->AppData.ghsATUCVendorId[i]);
+
+- if (len<=limit)
+- {
+- len += sprintf (buf + len, "\n");
+- }
++ seq_printf (m, "\n");
+
+- if (len <= limit)
+- {
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "\tT1413Vid: %02x %02x\t\tT1413Rev: %02x\t\tVendorRev: %02x\n",
+ pIhw->AppData.t1413ATUC.VendorId[0],
+ pIhw->AppData.t1413ATUC.VendorId[1],
+ pIhw->AppData.t1413ATUC.t1413Revision,
+ pIhw->AppData.t1413ATUC.VendorRevision);
+- }
+
+- if (len<=limit)
+- {
+- len += sprintf(buf+len,"\tATUR ghsVid: ");
+- for (i=0; i<8; i++)
+- len+= sprintf(buf+len, " %02x", pIhw->AppData.ghsATURVendorId[i]);
+- }
++ seq_printf(m,"\tATUR ghsVid: ");
++ for (i=0; i<8; i++)
++ seq_printf(m, " %02x", pIhw->AppData.ghsATURVendorId[i]);
+
+- if (len<=limit)
+- {
+- len += sprintf (buf + len, "\n");
+- }
++ seq_printf (m, "\n");
+
+- if (len <= limit)
+- {
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "\tT1413Vid: %02x %02x\tT1413Rev: %02x\tVendorRev: %02x\n",
+ pIhw->AppData.t1413ATUR.VendorId[0],
+ pIhw->AppData.t1413ATUR.VendorId[1],
+ pIhw->AppData.t1413ATUR.t1413Revision,
+ pIhw->AppData.t1413ATUR.VendorRevision);
+- }
+
+ #endif
+ /*
+ * Upstream Interleaved Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Upstream (TX) Interleave path]\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
++ seq_printf(m, "\n\t[Upstream (TX) Interleave path]\n");
++ seq_printf(m, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
+ (unsigned int)pIhw->AppData.usICRC_errors,
+ (unsigned int)pIhw->AppData.usIFEC_errors,
+ (unsigned int)pIhw->AppData.usINCD_error);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n",
++ seq_printf(m, "\tLCD: \t%u\tHEC: \t%u\n",
+ (unsigned int)pIhw->AppData.usILCD_errors,
+ (unsigned int)pIhw->AppData.usIHEC_errors);
+ /*
+ * Downstream Interleaved Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Downstream (RX) Interleave path]\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
++ seq_printf(m, "\n\t[Downstream (RX) Interleave path]\n");
++ seq_printf(m, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
+ (unsigned int)pIhw->AppData.dsICRC_errors,
+ (unsigned int)pIhw->AppData.dsIFEC_errors,
+ (unsigned int)pIhw->AppData.dsINCD_error);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n",
++ seq_printf(m, "\tLCD: \t%u\tHEC: \t%u\n",
+ (unsigned int)pIhw->AppData.dsILCD_errors,
+ (unsigned int)pIhw->AppData.dsIHEC_errors);
+ /*
+ * Upstream Fast Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Upstream (TX) Fast path]\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
++ seq_printf(m, "\n\t[Upstream (TX) Fast path]\n");
++ seq_printf(m, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
+ (unsigned int)pIhw->AppData.usFCRC_errors,
+ (unsigned int)pIhw->AppData.usFFEC_errors,
+ (unsigned int)pIhw->AppData.usFNCD_error);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n",
++ seq_printf(m, "\tLCD: \t%u\tHEC: \t%u\n",
+ (unsigned int)pIhw->AppData.usFLCD_errors,
+ (unsigned int)pIhw->AppData.usFHEC_errors);
+ /*
+ * Downstream Fast Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Downstream (RX) Fast path]\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
++ seq_printf(m, "\n\t[Downstream (RX) Fast path]\n");
++ seq_printf(m, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
+ (unsigned int)pIhw->AppData.dsFCRC_errors,
+ (unsigned int)pIhw->AppData.dsFFEC_errors,
+ (unsigned int)pIhw->AppData.dsFNCD_error);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n",
+- (unsigned int)pIhw->AppData.dsFLCD_errors,
+- (unsigned int)pIhw->AppData.dsFHEC_errors);
++ seq_printf(m, "\tLCD: \t%u\tHEC: \t%u\n",
++ (unsigned int)pIhw->AppData.dsFLCD_errors,
++ (unsigned int)pIhw->AppData.dsFHEC_errors);
+
+ /*
+ * ATM stats upstream
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n[ATM Stats]");
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Upstream/TX]\n");
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tGood Cell Cnt:\t%u\n\tIdle Cell Cnt:\t%u\n\n",
+- (unsigned int) pIhw->AppData.usAtm_count[0] +
+- (unsigned int) pIhw->AppData.usAtm_count[1],
+- (unsigned int) pIhw->AppData.usIdle_count[0] +
+- (unsigned int) pIhw->AppData.usIdle_count[1]);
+-//UR8_MERGE_START CQ10700 Manjula K
+- if (len <= limit)
+- len +=
+- sprintf (buf + len,
++ seq_printf(m, "\n[ATM Stats]");
++ seq_printf(m, "\n\t[Upstream/TX]\n");
++ seq_printf (m, "\tGood Cell Cnt:\t%u\n\tIdle Cell Cnt:\t%u\n\n",
++ (unsigned int) pIhw->AppData.usAtm_count[0] +
++ (unsigned int) pIhw->AppData.usAtm_count[1],
++ (unsigned int) pIhw->AppData.usIdle_count[0] +
++ (unsigned int) pIhw->AppData.usIdle_count[1]);
++//UR8_MERGE_START CQ10700 Manjula K
++ seq_printf (m,
+ "\tTx Packets Dropped Count:\t%lu\n\tTx Bad Packets Count:\t%lu\n",
+ priv->stats.tx_dropped, priv->stats.tx_errors);
+ //UR8_MERGE_END CQ10700
+ /*
+ * ATM stats downstream
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Downstream/RX)]\n");
+- if(len<=limit)
+- len +=
+- sprintf (buf + len,
+- "\tGood Cell Cnt:\t%u\n\tIdle Cell Cnt:\t%u\n\tBad Hec Cell Cnt:\t%u\n",
+- (unsigned int) pIhw->AppData.dsGood_count[0] +
+- (unsigned int) pIhw->AppData.dsGood_count[1],
+- (unsigned int) pIhw->AppData.dsIdle_count[0] +
+- (unsigned int) pIhw->AppData.dsIdle_count[1],
+- (unsigned int) pIhw->AppData.dsBadHec_count[0] +
+- (unsigned int) pIhw->AppData.dsBadHec_count[1]);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tOverflow Dropped Cell Cnt:\t%u\n",
+- (unsigned int) pIhw->AppData.dsOVFDrop_count[0] +
+- (unsigned int) pIhw->AppData.dsOVFDrop_count[1]);
+-
+- //UR8_MERGE_START CQ10700 Manjula K
+- if (len <= limit)
+- len +=
+- sprintf (buf + len,
+- "\tRx Packets Dropped Count:\t%lu\n\tRx Bad Packets Count:\t%lu\n\n",
+- priv->stats.rx_dropped, priv->stats.rx_errors);
++ seq_printf(m, "\n\t[Downstream/RX)]\n");
++ seq_printf (m,
++ "\tGood Cell Cnt:\t%u\n\tIdle Cell Cnt:\t%u\n\tBad Hec Cell Cnt:\t%u\n",
++ (unsigned int) pIhw->AppData.dsGood_count[0] +
++ (unsigned int) pIhw->AppData.dsGood_count[1],
++ (unsigned int) pIhw->AppData.dsIdle_count[0] +
++ (unsigned int) pIhw->AppData.dsIdle_count[1],
++ (unsigned int) pIhw->AppData.dsBadHec_count[0] +
++ (unsigned int) pIhw->AppData.dsBadHec_count[1]);
++ seq_printf(m, "\tOverflow Dropped Cell Cnt:\t%u\n",
++ (unsigned int) pIhw->AppData.dsOVFDrop_count[0] +
++ (unsigned int) pIhw->AppData.dsOVFDrop_count[1]);
++
++ //UR8_MERGE_START CQ10700 Manjula K
++ seq_printf (m,
++ "\tRx Packets Dropped Count:\t%lu\n\tRx Bad Packets Count:\t%lu\n\n",
++ priv->stats.rx_dropped, priv->stats.rx_errors);
+ //UR8_MERGE_END CQ10700
+
+ tn7sar_get_stats(pIhw->pOsContext);
+- if(len<=limit)
+- len += sprintf(buf+len, "\n[SAR AAL5 Stats]\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "\tTx PDU's:\t%u\n\tRx PDU's:\t%u\n",
+- sarStat.txPktCnt, sarStat.rxPktCnt);
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tTx Total Bytes:\t%u\n\tRx Total Bytes:\t%u\n",
+- sarStat.txBytes, sarStat.rxBytes);
+- if (len <= limit)
+- len +=
+- sprintf (buf + len,
+- "\tTx Total Error Counts:\t%u\n\tRx Total Error Counts:\t%u\n\n",
+- sarStat.txErrors, sarStat.rxErrors);
++ seq_printf(m, "\n[SAR AAL5 Stats]\n");
++ seq_printf(m, "\tTx PDU's:\t%u\n\tRx PDU's:\t%u\n",
++ sarStat.txPktCnt, sarStat.rxPktCnt);
++ seq_printf (m, "\tTx Total Bytes:\t%u\n\tRx Total Bytes:\t%u\n",
++ sarStat.txBytes, sarStat.rxBytes);
++ seq_printf (m,
++ "\tTx Total Error Counts:\t%u\n\tRx Total Error Counts:\t%u\n\n",
++ sarStat.txErrors, sarStat.rxErrors);
+
+ /*
+ * oam loopback info
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n[OAM Stats]\n");
++ seq_printf(m, "\n[OAM Stats]\n");
+
+ tn7sar_get_near_end_loopback_count(&F4count, &F5count);
+
+- if(len<=limit)
+- {
+- len +=
+- sprintf (buf + len,
+- "\tNear End F5 Loop Back Count:\t%u\n\tNear End F4 Loop Back Count:\t%u\n\tFar End F5 Loop Back Count:\t%u\n\tFar End F4 Loop Back Count:\t%u\n",
++ seq_printf (m,
++ "\tNear End F5 Loop Back Count:\t%u\n\tNear End F4 Loop Back Count:\t%u\n\tFar End F5 Loop Back Count:\t%u\n\tFar End F4 Loop Back Count:\t%u\n",
+ F5count, F4count, oamFarLBCount[0] + oamFarLBCount[2],
+ oamFarLBCount[1] + oamFarLBCount[3]);
+- }
+
+ #define USE_OAM_DROP_COUNT //CQ10273
+ //Read OAM ping responses count:
+ #ifdef USE_OAM_DROP_COUNT
+- if(len<=limit)
+- {
+- /* len +=
+- sprintf (buf + len,
+- "\tSAR OAM Retry in 0x%X cycles, Drop Count=%d\n",
+- tn7dsl_get_memory(0xa30085cc), tn7dsl_get_memory(0xa30085c4)); */
++/* seq_printf (m,
++ "\tSAR OAM Retry in 0x%X cycles, Drop Count=%d\n",
++ tn7dsl_get_memory(0xa30085cc), tn7dsl_get_memory(0xa30085c4)); */
+
+- len += sprintf (buf + len, "\tSAR OAM Ping Response Drop Count=%d\n",
+- tn7dsl_get_memory(0xa30085b0));
+- }
++ seq_printf (m, "\tSAR OAM Ping Response Drop Count=%d\n",
++ tn7dsl_get_memory(0xa30085b0));
+ #endif // USE_OAM_DROP_COUNT
+
+- return len;
++ return 0;
+ }
+
+-int tn7dsl_proc_modem(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_stats_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_stats, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++int tn7dsl_proc_write_stats (struct file *fp, const char *buf, unsigned long count, void *data);
++
++struct file_operations tn7dsl_proc_stats_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_stats_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++ .write = tn7dsl_proc_write_stats,
++};
+
++static int tn7dsl_proc_modem(struct seq_file *m, void *data)
++{
+ char *state;
+ int tag;
+
+@@ -1859,16 +1775,26 @@ int tn7dsl_proc_modem(char* buf, char **
+
+ if(pIhw->lConnected == 1)
+ state = "SHOWTIME";
+- if(len<=limit)
+- len += sprintf(buf+len,"%s\n",state);
+- if(len<=limit)
+- len += sprintf(buf+len, "%d\n", dslReg);
+- if(len<=limit)
+- len += sprintf(buf+len, "failTrains=%d\n", pIhw->AppData.trainFails);
++ seq_printf(m,"%s\n",state);
++ seq_printf(m, "%d\n", dslReg);
++ seq_printf(m, "failTrains=%d\n", pIhw->AppData.trainFails);
+
+- return len;
++ return 0;
++}
++
++static int tn7dsl_proc_modem_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_modem, PDE_DATA(inode));
+ }
+
++struct file_operations tn7dsl_proc_modem_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_modem_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ /**********************************************************************
+ ** *
+ ** tn7dsl_hdlc_update_crc() -- Calculate CRC *
+@@ -2133,11 +2059,8 @@ static int tn7dsl_hdlc_rx_process(unsign
+ return(ret);
+ }
+
+-int tn7dsl_proc_eoc (char *buf, char **start, off_t OffSet, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_eoc (struct seq_file *m, void *data)
+ {
+- int len = 0;
+- int limit = count - 80;
+ int offset[2] = {34, 0}; // point to buffer parameter data structure
+ clearEocParm_t peoc;
+
+@@ -2146,62 +2069,49 @@ int tn7dsl_proc_eoc (char *buf, char **s
+ (unsigned char *) &peoc,
+ sizeof (clearEocParm_t));
+
+- if (len <= limit)
+- len += sprintf(buf+len, "\nClear EOC Channel:\n\n");
+- if (len <= limit)
+- len += sprintf(buf+len, " Enabled:\t%d\n", dslhal_support_byteSwap32(peoc.clearEocEnabled));
+- if (len <= limit)
+- len += sprintf(buf+len, " TxBuf[0]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[0]));
+- if (len <= limit)
+- len += sprintf(buf+len, " TxBuf[1]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[1]));
+- if (len <= limit)
+- len += sprintf(buf+len, " TxBuf[2]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[2]));
+- if (len <= limit)
+- len += sprintf(buf+len, " TxBuf[3]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[3]));
+- if (len <= limit)
+- len += sprintf(buf+len, " RxBuf[0]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[0]));
+- if (len <= limit)
+- len += sprintf(buf+len, " RxBuf[1]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[1]));
+- if (len <= limit)
+- len += sprintf(buf+len, " RxBuf[2]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[2]));
+- if (len <= limit)
+- len += sprintf(buf+len, " RxBuf[3]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[3]));
+- if (len <= limit)
+- len += sprintf(buf+len, " txRdIndex:\t%d\n", dslhal_support_byteSwap32(peoc.txRdIndex));
+- if (len <= limit)
+- len += sprintf(buf+len, " txWrIndex:\t%d\n", dslhal_support_byteSwap32(peoc.txWrIndex));
+- if (len <= limit)
+- len += sprintf(buf+len, " rxRdIndex:\t%d\n", dslhal_support_byteSwap32(peoc.rxRdIndex));
+- if (len <= limit)
+- len += sprintf(buf+len, " rxWrIndex:\t%d\n\n", dslhal_support_byteSwap32(peoc.rxWrIndex));
+- if (len <= limit)
+- len += sprintf(buf+len, " TotalTxPkts:\t%d\n", EocTxTotalPackets);
+- if (len <= limit)
+- len += sprintf(buf+len, " TotalRxPkts:\t%d\n", EocRxTotalPackets);
+- if (len <= limit)
+- len += sprintf(buf+len, " TotalTxBytes:\t%d\n", EocTxTotalBytes);
+- if (len <= limit)
+- len += sprintf(buf+len, " TotalRxBytes:\t%d\n\n", EocRxTotalBytes);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrBufFull:\t%d\n", ErrEocBufFull);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrBufIndx:\t%d\n", ErrEocBufIndex);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrBufMax:\t%d\n", ErrEocBufMax);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrMsgMax:\t%d\n", ErrEocMsgOversized);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrTxHDLC:\t%d\n", ErrEocTxHdlcCRC);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrRxHDLC:\t%d\n", ErrEocRxHdlcCRC);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrRxSnmp:\t%d\n", ErrEocRxHdlcFraming);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrRxPush:\t%d\n\n", ErrEocRxPush);
++ seq_printf(m, "\nClear EOC Channel:\n\n");
++ seq_printf(m, " Enabled:\t%d\n", dslhal_support_byteSwap32(peoc.clearEocEnabled));
++ seq_printf(m, " TxBuf[0]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[0]));
++ seq_printf(m, " TxBuf[1]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[1]));
++ seq_printf(m, " TxBuf[2]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[2]));
++ seq_printf(m, " TxBuf[3]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[3]));
++ seq_printf(m, " RxBuf[0]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[0]));
++ seq_printf(m, " RxBuf[1]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[1]));
++ seq_printf(m, " RxBuf[2]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[2]));
++ seq_printf(m, " RxBuf[3]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[3]));
++ seq_printf(m, " txRdIndex:\t%d\n", dslhal_support_byteSwap32(peoc.txRdIndex));
++ seq_printf(m, " txWrIndex:\t%d\n", dslhal_support_byteSwap32(peoc.txWrIndex));
++ seq_printf(m, " rxRdIndex:\t%d\n", dslhal_support_byteSwap32(peoc.rxRdIndex));
++ seq_printf(m, " rxWrIndex:\t%d\n\n", dslhal_support_byteSwap32(peoc.rxWrIndex));
++ seq_printf(m, " TotalTxPkts:\t%d\n", EocTxTotalPackets);
++ seq_printf(m, " TotalRxPkts:\t%d\n", EocRxTotalPackets);
++ seq_printf(m, " TotalTxBytes:\t%d\n", EocTxTotalBytes);
++ seq_printf(m, " TotalRxBytes:\t%d\n\n", EocRxTotalBytes);
++ seq_printf(m, " ErrBufFull:\t%d\n", ErrEocBufFull);
++ seq_printf(m, " ErrBufIndx:\t%d\n", ErrEocBufIndex);
++ seq_printf(m, " ErrBufMax:\t%d\n", ErrEocBufMax);
++ seq_printf(m, " ErrMsgMax:\t%d\n", ErrEocMsgOversized);
++ seq_printf(m, " ErrTxHDLC:\t%d\n", ErrEocTxHdlcCRC);
++ seq_printf(m, " ErrRxHDLC:\t%d\n", ErrEocRxHdlcCRC);
++ seq_printf(m, " ErrRxSnmp:\t%d\n", ErrEocRxHdlcFraming);
++ seq_printf(m, " ErrRxPush:\t%d\n\n", ErrEocRxPush);
+
+- return len;
++ return 0;
++}
++
++static int tn7dsl_proc_eoc_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_eoc, PDE_DATA(inode));
+ }
+
++struct file_operations tn7dsl_proc_eoc_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_eoc_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ int tn7dsl_clear_eoc_setup(void)
+ {
+ int i;
+@@ -4440,14 +4350,10 @@ int tn7dsl_proc_write_stats (struct file
+ }
+
+
+-int tn7dsl_proc_train_mode_export (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data)
++static int tn7dsl_proc_train_mode_export (struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- char *cp = buf + offset;
+ int i = 0;
+- static int ctr = 0;
+
+ typedef struct
+ {
+@@ -4528,197 +4434,185 @@ int tn7dsl_proc_train_mode_export (char
+ }
+
+
+- if(len <= count)
++ for (i = 0; (i < num_entries) ; i++)
+ {
+- for (i = ctr; ((i < num_entries)&& (len <= count)) ; i++)
+- {
+- /*
+- * Write the current string only if we can fit it into the buffer
+- */
+- if((strlen(dsl_modes[i].mode_name) + 6 + len) <= count)
+- {
+- len += snprintf(cp+len, (count - len), "%s\t\t\t%#x\n",
+- dsl_modes[i].mode_name, dsl_modes[i].mode_value);
+- }
+- else
+- break;
+- }
++ seq_printf(m, "%s\t\t\t%#x\n",
++ dsl_modes[i].mode_name, dsl_modes[i].mode_value);
+ }
+
+- /*
+- * Data was completely written
+- */
+- if (i >= num_entries)
+- {
+- /*
+- * We are done with this
+- */
+- *eof = 1;
+- ctr = 0;
+- }
+- else
+- {
+- /*
+- * We have not been able to write the complete data, and we have to nul
+- * terminate the buffer.
+- */
+- *(cp + len) = '\0';
+-
+- /*
+- * Save the value of the counter for the next read for the rest of the
+- * data.
+- */
+- ctr = i;
+- }
+-
+- return len;
++ return 0;
+ }
+
+-#ifndef NO_ADV_STATS
+-int tn7dsl_proc_SNRpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_train_mode_export_open(struct inode *inode, struct file *file)
+ {
+- int len = 0;
+-
++ return single_open(file, tn7dsl_proc_train_mode_export, PDE_DATA(inode));
++}
+
++struct file_operations tn7dsl_proc_train_mode_export_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_train_mode_export_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
+
+- int limit = count - 80;
++#ifndef NO_ADV_STATS
++int tn7dsl_proc_SNRpsds(struct seq_file *m, void *data)
++{
+ int i;
+ unsigned char SNRpsds[512];
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 SNRpsds:");
++ seq_printf(m, "\nAR7 SNRpsds:");
+
+ if (dslhal_api_getSNRpsds(pIhw, SNRpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getSNRpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+
+ for (i=0; i<pIhw->AppData.max_ds_tones; i++)
+ {
+ if (!(i%16))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "%d ", (unsigned char)SNRpsds[i]);
++ seq_printf(m, "%d ", (unsigned char)SNRpsds[i]);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+
+
+- return len;
++ return 0;
+ }
+
++static int tn7dsl_proc_SNRpsds_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_SNRpsds, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_SNRpsds_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_SNRpsds_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #endif
+
+ #ifndef NO_ADV_STATS
+-int tn7dsl_proc_QLNpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_QLNpsds(struct seq_file *m, void *data)
+ {
+- int len = 0;
+-
+- int limit = count - 80;
+ unsigned char QLNpsds[512];
+ int i;
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 QLNpsds:");
++ seq_printf(m, "\nAR7 QLNpsds:");
+
+ // call API instead of access internal buf directly
+ if (dslhal_api_getQLNpsds(pIhw, QLNpsds, 0))
+ {
+ dgprintf(4, "dslhal_api_getQLNpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+
+ for (i=0; i<pIhw->AppData.max_ds_tones; i++)
+ {
+ if (!(i%16))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "%d ", (unsigned char)QLNpsds[i]);
++ seq_printf(m, "%d ", (unsigned char)QLNpsds[i]);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+
+- return len;
++ return 0;
+ }
++
++static int tn7dsl_proc_QLNpsds_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_QLNpsds, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_QLNpsds_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_QLNpsds_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #endif
+
+ // UR8_MERGE_START CQ10979 Jack Zhang
+ #ifdef TR69_HLIN_IN
+ #ifndef NO_ADV_STATS
+-int tn7dsl_proc_HLINpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_HLINpsds(struct seq_file *m, void *data)
+ {
+- int len = 0;
+-
+- int limit = count - 80;
+ short HLINpsds[2*512];
+ int i;
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 HLINpsds:");
++ seq_printf(m, "\nAR7 HLINpsds:");
+
+ // call API instead of access internal buf directly
+ if (dslhal_api_getHLINpsds(pIhw, (unsigned char *)HLINpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getHLINpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+
+ for (i=0; i<pIhw->AppData.max_ds_tones; i++)
+ {
+ if (!(i%8))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "(%d,%d) ", HLINpsds[2*i], HLINpsds[2*i+1]);
++ seq_printf(m, "(%d,%d) ", HLINpsds[2*i], HLINpsds[2*i+1]);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+
+- return len;
++ return 0;
+ }
+
+-static int tn7dsl_proc_HLINpsdsIndx(char* buf, char **start, off_t offset, int count,int *eof, void *data, int indx)
++static int tn7dsl_proc_HLINpsds_open(struct inode *inode, struct file *file)
+ {
+- int len = 0;
++ return single_open(file, tn7dsl_proc_HLINpsds, PDE_DATA(inode));
++}
+
+- int limit = count - 80;
++struct file_operations tn7dsl_proc_HLINpsds_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_HLINpsds_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++static int tn7dsl_proc_HLINpsdsIndx(struct seq_file *m, void *data, int indx)
++{
+ short HLINpsds[2*512];
+ int i;
+ int start=0, dim=128;
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 HLINpsds: (section %d)", indx);
++ seq_printf(m, "\nAR7 HLINpsds: (section %d)", indx);
+
+ if((indx > 2) && (pIhw->AppData.max_ds_tones <= 256))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n[End of data]");
+- return len;
++ seq_printf(m, "\n[End of data]");
++ return 0;
+ }
+
+ // call API instead of access internal buf directly
+ if (dslhal_api_getHLINpsds(pIhw, (unsigned char *)HLINpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getHLINpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+
+ start = (indx -1) * 128;
+@@ -4727,39 +4621,89 @@ static int tn7dsl_proc_HLINpsdsIndx(char
+ {
+ if (!(i%8))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n%d: ", i);
++ seq_printf(m, "\n%d: ", i);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "(%d,%d) ", HLINpsds[2*i], HLINpsds[2*i+1]);
++ seq_printf(m, "(%d,%d) ", HLINpsds[2*i], HLINpsds[2*i+1]);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+- return len;
++ return 0;
++}
++
++static int tn7dsl_proc_HLINpsds1(struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_HLINpsdsIndx(m, data, 1);
++}
++
++static int tn7dsl_proc_HLINpsds2(struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_HLINpsdsIndx(m, data, 2);
++}
++
++static int tn7dsl_proc_HLINpsds3(struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_HLINpsdsIndx(m, data, 3);
++}
++
++static int tn7dsl_proc_HLINpsds4(struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_HLINpsdsIndx(m, data, 4);
+ }
+
+-int tn7dsl_proc_HLINpsds1(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_HLINpsds1_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_HLINpsdsIndx(buf, start, offset, count,eof, data, 1);
++ return single_open(file, tn7dsl_proc_HLINpsds1, PDE_DATA(inode));
+ }
+
+-int tn7dsl_proc_HLINpsds2(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_HLINpsds2_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_HLINpsdsIndx(buf, start, offset, count,eof, data, 2);
++ return single_open(file, tn7dsl_proc_HLINpsds2, PDE_DATA(inode));
+ }
+
+-int tn7dsl_proc_HLINpsds3(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_HLINpsds3_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_HLINpsdsIndx(buf, start, offset, count,eof, data, 3);
++ return single_open(file, tn7dsl_proc_HLINpsds3, PDE_DATA(inode));
+ }
+
+-int tn7dsl_proc_HLINpsds4(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_HLINpsds4_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_HLINpsdsIndx(buf, start, offset, count,eof, data, 4);
++ return single_open(file, tn7dsl_proc_HLINpsds4, PDE_DATA(inode));
+ }
++
++struct file_operations tn7dsl_proc_HLINpsds1_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_HLINpsds1_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++struct file_operations tn7dsl_proc_HLINpsds2_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_HLINpsds2_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++struct file_operations tn7dsl_proc_HLINpsds3_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_HLINpsds3_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++struct file_operations tn7dsl_proc_HLINpsds4_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_HLINpsds4_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #endif
+ #endif //TR69_HLIN_IN
+ // UR8_MERGE_END CQ10979*
+@@ -4767,64 +4711,48 @@ int tn7dsl_proc_HLINpsds4(char* buf, cha
+ // * UR8_MERGE_START CQ11057 Jack Zhang
+ #ifdef TR69_PMD_IN
+ #ifndef NO_ADV_STATS
+-int tn7dsl_proc_PMDus(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_PMDus(struct seq_file *m, void *data)
+ {
+- int len = 0;
+-
+- int limit = count - 80;
+ int i;
+ CoPMDTestParams_t co_pmdtest_params;
+-
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 US PMD Test:\n");
++
++ seq_printf(m, "\nAR7 US PMD Test:\n");
+
+ // call API instead of access internal buf directly
+ if (dslhal_api_getPMDTestus(pIhw, &co_pmdtest_params, 0) != DSLHAL_ERROR_NO_ERRORS)
+ {
+ dgprintf(4, "dslhal_api_getPMDTestus failed!\n");
+- return len;
++ return -EIO;
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "LATN=%d\n", co_pmdtest_params.co_latn);
++ seq_printf(m, "LATN=%d\n", co_pmdtest_params.co_latn);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "SATN=%d\n", co_pmdtest_params.co_satn);
++ seq_printf(m, "SATN=%d\n", co_pmdtest_params.co_satn);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "SNRM=%d\n", co_pmdtest_params.usMargin);
++ seq_printf(m, "SNRM=%d\n", co_pmdtest_params.usMargin);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "attndr=%ld\n", co_pmdtest_params.co_attndr);
++ seq_printf(m, "attndr=%ld\n", co_pmdtest_params.co_attndr);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "NearActatp=%d\n", co_pmdtest_params.co_near_actatp);
++ seq_printf(m, "NearActatp=%d\n", co_pmdtest_params.co_near_actatp);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "FarActatp=%d\n", co_pmdtest_params.co_far_actatp);
++ seq_printf(m, "FarActatp=%d\n", co_pmdtest_params.co_far_actatp);
+
+ //HLOG
+ for (i=0; i<pIhw->AppData.max_us_tones; i++)
+ {
+ if (!(i%16))
+- {
+- if(len <=limit)
+- len += sprintf(buf+len, "\nHLOG(%3d):", i);
+- }
+- if(len <=limit)
+- len += sprintf(buf+len, " %d", co_pmdtest_params.TestParmCOHlogfMsg[i]);
++ seq_printf(m, "\nHLOG(%3d):", i);
++
++ seq_printf(m, " %d", co_pmdtest_params.TestParmCOHlogfMsg[i]);
+ }
+
+ //QLN
+ for (i=0; i<pIhw->AppData.max_us_tones; i++)
+ {
+ if (!(i%16))
+- {
+- if(len <=limit)
+- len += sprintf(buf+len, "\nQLN(%3d):", i);
+- }
+- if(len <=limit)
+- len += sprintf(buf+len, " %d", co_pmdtest_params.TestParmCOQLNfMsg[i]);
++ seq_printf(m, "\nQLN(%3d):", i);
++
++ seq_printf(m, " %d", co_pmdtest_params.TestParmCOQLNfMsg[i]);
+
+ }
+
+@@ -4832,19 +4760,28 @@ int tn7dsl_proc_PMDus(char* buf, char **
+ for (i=0; i<pIhw->AppData.max_us_tones; i++)
+ {
+ if (!(i%16))
+- {
+- if(len <=limit)
+- len += sprintf(buf+len, "\nSNR(%3d):", i);
+- }
+- if(len <=limit)
+- len += sprintf(buf+len, " %d", co_pmdtest_params.TestParmCOSNRfMsg[i]);
++ seq_printf(m, "\nSNR(%3d):", i);
++ seq_printf(m, " %d", co_pmdtest_params.TestParmCOSNRfMsg[i]);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+- return len;
++ return 0;
++}
++
++static int tn7dsl_proc_PMDus_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_PMDus, PDE_DATA(inode));
+ }
++
++struct file_operations tn7dsl_proc_PMDus_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_PMDus_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #endif //NO_ADV_STATS
+ #endif //TR69_PMD_IN
+ // * UR8_MERGE_END CQ11057 *
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -1401,44 +1401,70 @@ int tn7sar_oam_generation(void *privCont
+ return 0;
+ }
+
+-int tn7sar_proc_oam_ping(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
++#define PDE_DATA(inode) PDE(inode)->data
++#endif
++
++static int tn7sar_proc_oam_ping(struct seq_file *m, void *data)
+ {
+- int len = 0;
+ unsigned int oam_ps = oamPingStatus;
+
+ if( oam_ps == OAM_PING_PENDING_RECVD )
+ oam_ps = OAM_PING_PENDING; //jz CQ9861: Only export the PENDING status, not internal state
+
+- len += sprintf(buf+len, "%d\n", oam_ps); //oamPingStatus);
++ seq_printf(m, "%d\n", oam_ps); //oamPingStatus);
+
+- return len;
++ return 0;
+ }
+
+-int tn7sar_proc_pvc_table(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7sar_proc_oam_ping_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7sar_proc_oam_ping, PDE_DATA(inode));
++}
++
++struct file_operations tn7sar_proc_oam_ping_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7sar_proc_oam_ping_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++
++static int tn7sar_proc_pvc_table(struct seq_file *m, void *data)
+ {
+- int len = 0;
+ int i;
+
+ for(i=0;i<16;i++)
+ {
+ if(pvc_result[i].bInUse)
+ {
+- len += sprintf(buf+len, "%d,%d\n", pvc_result[i].vpi,pvc_result[i].vci);
++ seq_printf(m, "%d,%d\n", pvc_result[i].vpi,pvc_result[i].vci);
+ }
+ else
+ {
+- len += sprintf(buf+len, "0,0\n");
++ seq_printf(m, "0,0\n");
+ }
+ }
+- return len;
++ return 0;
++}
++
++static int tn7sar_proc_pvc_table_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7sar_proc_pvc_table, PDE_DATA(inode));
+ }
+
++struct file_operations tn7sar_proc_pvc_table_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7sar_proc_pvc_table_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
+
+
+-int tn7sar_proc_sar_stat(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7sar_proc_sar_stat(struct seq_file *m, void *data)
+ {
+- int len = 0;
+- int limit = count - 80;
+ struct atm_dev *dev;
+ Tn7AtmPrivate *priv;
+ int i, j, k;
+@@ -1447,21 +1473,19 @@ int tn7sar_proc_sar_stat(char* buf, char
+ unsigned int *pStateBase, *pSarStat;
+ HAL_FUNCTIONS *pHalFunc;
+ HAL_DEVICE *pHalDev;
+- int dBytes;
+
+- dev = (struct atm_dev *)data;
++ dev = (struct atm_dev *)m->private;
+ priv = (Tn7AtmPrivate *)dev->dev_data;
+
+ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc;
+ pHalDev = (HAL_DEVICE *)priv->pSarHalDev;
+
+- len += sprintf(buf+len, "SAR HAL Statistics");
++ seq_printf(m, "SAR HAL Statistics");
+ for(i=0;i<MAX_DMA_CHAN;i++)
+ {
+ if(priv->lut[i].inuse)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\nChannel %d:\n",priv->lut[i].chanid);
++ seq_printf(m, "\nChannel %d:\n",priv->lut[i].chanid);
+ k=0;
+ for(j=0;j<4;j++)
+ {
+@@ -1474,26 +1498,16 @@ int tn7sar_proc_sar_stat(char* buf, char
+ {
+ if((char *)*pSarStat == NULL)
+ break;
+- if(len<=limit)
+- {
+- dBytes = sprintf(buf+len, "%s: ",(char *) *pSarStat);
+- len += dBytes;
+- k += dBytes;
+- }
++
++ k += seq_printf(m, "%s: ",(char *) *pSarStat);
+ pSarStat++;
+- if(len<=limit)
+- {
+- dBytes = sprintf(buf+len, "%s; \n",(char *) *pSarStat);
+- len += dBytes;
+- k += dBytes;
+- }
++ k += seq_printf(m, "%s; \n",(char *) *pSarStat);
+ pSarStat++;
+
+ if(k > 60)
+ {
+ k=0;
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+ }
+
+@@ -1502,9 +1516,22 @@ int tn7sar_proc_sar_stat(char* buf, char
+ }
+ }
+
+- return len;
++ return 0;
+ }
+
++static int tn7sar_proc_sar_stat_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7sar_proc_sar_stat, PDE_DATA(inode));
++}
++
++struct file_operations tn7sar_proc_sar_stat_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7sar_proc_sar_stat_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ void tn7sar_get_sar_firmware_version(unsigned int *pdsp_version_ms, unsigned int *pdsp_version_ls)
+ {
+
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/230-compile_fixes.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/230-compile_fixes.patch
new file mode 100644
index 0000000..c7d9127
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/230-compile_fixes.patch
@@ -0,0 +1,44 @@
+--- a/cp_sar_reg.h
++++ b/cp_sar_reg.h
+@@ -214,4 +214,4 @@
+
+ /* END OF FILE */
+
+-#endif _INC_SAR_REG
++#endif
+--- a/tn7api.h
++++ b/tn7api.h
+@@ -172,4 +172,4 @@ void tn7sar_get_sar_firmware_version(uns
+ extern struct file_operations tn7sar_proc_oam_ping_fops;
+ extern struct file_operations tn7sar_proc_pvc_table_fops;
+ int tn7sar_tx_flush(void *privContext, int chan, int queue, int skip);
+-#endif __SGAPI_H
++#endif
+--- a/tn7atm.h
++++ b/tn7atm.h
+@@ -276,4 +276,4 @@ typedef struct
+ #define PHYS_TO_K1(X) (PHYS_ADDR(X)|K1BASE)
+ #endif
+
+-#endif __TN7ATM_H
++#endif
+--- a/dsl_hal_api.h
++++ b/dsl_hal_api.h
+@@ -2448,7 +2448,7 @@ unsigned int dslhal_api_getHLINpsds(tids
+ *
+ ********************************************************************************************/
+
+-unsigned int dslhal_api_getHighPrecision();
++unsigned int dslhal_api_getHighPrecision(void);
+
+ /********************************************************************************************
+ * FUNCTION NAME: void dslhal_api_setHighPrecision
+@@ -2459,7 +2459,7 @@ unsigned int dslhal_api_getHighPrecision
+ * Return: None
+ ********************************************************************************************/
+
+-void dslhal_api_setHighPrecision();
++void dslhal_api_setHighPrecision(void);
+ // UR8_MERGE_END CQ11054*
+
+ #ifdef INTERNAL_BUILD
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/240-3.18_fixes.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/240-3.18_fixes.patch
new file mode 100644
index 0000000..e8bdab6
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/240-3.18_fixes.patch
@@ -0,0 +1,38 @@
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -346,7 +346,7 @@ static void tn7dsl_chng_modulation(void*
+ static unsigned int tn7dsl_set_modulation(void* data, int flag);
+ static void tn7dsl_ctrl_fineGain(int value);
+ static void tn7dsl_set_fineGainValue(int value);
+-static int dslmod_sysctl (ctl_table * ctl, int write, struct file *filp,
++static int dslmod_sysctl (struct ctl_table * ctl, int write, struct file *filp,
+ void *buffer, size_t * lenp);
+ static void tn7dsl_register_dslss_led(void);
+ void tn7dsl_dslmod_sysctl_register(void);
+@@ -3325,7 +3325,7 @@ unsigned int tn7dsl_get_memory(unsigned
+
+
+
+-static int dslmod_sysctl(ctl_table *ctl, int write, struct file * filp,
++static int dslmod_sysctl(struct ctl_table *ctl, int write, struct file * filp,
+ void *buffer, size_t *lenp)
+ {
+ char *ptr;
+@@ -3451,7 +3451,7 @@ static int dslmod_sysctl(ctl_table *ctl,
+ }
+
+
+-ctl_table dslmod_table[] = {
++struct 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
+@@ -3469,7 +3469,7 @@ ctl_table dslmod_table[] = {
+ };
+
+ /* Make sure that /proc/sys/dev is there */
+-ctl_table dslmod_root_table[] = {
++struct 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}
diff --git a/package/kernel/ar7-atm/patches-D7.04.03.00/250-4.1_fixes.patch b/package/kernel/ar7-atm/patches-D7.04.03.00/250-4.1_fixes.patch
new file mode 100644
index 0000000..97a26cb
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.04.03.00/250-4.1_fixes.patch
@@ -0,0 +1,20 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -788,7 +788,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, IRQF_DISABLED, "SAR ", dev))
++ if (request_irq (priv->sar_irq, tn7atm_sar_irq, 0, "SAR ", dev))
+ printk ("Could not register tn7atm_sar_irq\n");
+
+ /*
+@@ -806,7 +806,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, IRQF_DISABLED, "DSL ", dev))
++ if (request_irq (priv->dsl_irq, tn7atm_dsl_irq, 0, "DSL ", dev))
+ printk ("Could not register tn7atm_dsl_irq\n");
+
+ /***** VRB Tasklet Mode ****/
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 0000000..7dee220
--- /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 0000000..1122457
--- /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 0000000..e9d99df
--- /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 0000000..4154864
--- /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 0000000..3873827
--- /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 0000000..97b8cec
--- /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 0000000..9c504c0
--- /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 @@ static int __init tn7atm_irq_request (st
+ * 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 @@ static int __init tn7atm_get_ESI (struct
+ {
+ 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 @@ static int tn7atm_autoDetectDspBoost (vo
+ //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 @@ static int __init tn7atm_init (struct at
+ // 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 @@ static int __init tn7atm_init (struct at
+ // 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 @@ static int __init tn7atm_init (struct at
+ // 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 @@ static int __init tn7atm_init (struct at
+ 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 0000000..6692f40
--- /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 0000000..feb6ea8
--- /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 0000000..52ebbc1
--- /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 0000000..f6dba4b
--- /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
+@@ -2009,7 +2009,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 0000000..975ebaf
--- /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/ar7-atm/patches-D7.05.01.00/220-3.10-update_proc_code.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/220-3.10-update_proc_code.patch
new file mode 100644
index 0000000..747869b
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/220-3.10-update_proc_code.patch
@@ -0,0 +1,3102 @@
+From 42d0f4c2f5cf0f73edd827263dc65aefc8f82192 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jogo@openwrt.org>
+Date: Thu, 26 Sep 2013 12:28:35 +0200
+Subject: [PATCH] update proc code to fix compilation for 3.10
+
+Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+
+---
+ tn7api.h | 66 ++-
+ tn7atm.c | 395 ++++++++---------
+ tn7dsl.c | 1439 ++++++++++++++++++++++++++++++--------------------------------
+ tn7sar.c | 91 ++--
+ 4 files changed, 951 insertions(+), 1040 deletions(-)
+
+--- a/tn7api.h
++++ b/tn7api.h
+@@ -91,31 +91,29 @@ void * tn7atm_memcpy(void * dst, void co
+ /* tn7dsl.h */
+ void tn7dsl_exit(void);
+ int tn7dsl_init(void *priv);
+-int tn7dsl_proc_eoc(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_stats(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7dsl_proc_eoc_fops;
++extern struct file_operations tn7dsl_proc_stats_fops;
+
+ //#define ADV_DIAG_STATS 1 //CQ10275 To enable Adv Stats
+
+ #ifdef ADV_DIAG_STATS
+-int tn7dsl_proc_adv_stats(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_adv_stats1(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_adv_stats2(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_adv_stats3(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7dsl_proc_adv_stats_fops;
++extern struct file_operations tn7dsl_proc_adv1_stats_fops;
++extern struct file_operations tn7dsl_proc_adv2_stats_fops;
++extern struct file_operations tn7dsl_proc_adv3_stats_fops;
+ //UR8_MERGE_START CQ10682 Jack Zhang
+-int tn7dsl_proc_dbg_cmsgs(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_dbg_rmsgs1(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_dbg_rmsgs2(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_dbg_rmsgs3(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_dbg_rmsgs4(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7dsl_proc_dbg_cmsgs_fops;
++extern struct file_operations tn7dsl_proc_dbg_cmsgs1_fops;
++extern struct file_operations tn7dsl_proc_dbg_cmsgs2_fops;
++extern struct file_operations tn7dsl_proc_dbg_cmsgs3_fops;
++extern struct file_operations tn7dsl_proc_dbg_cmsgs4_fops;
+ //UR8_MERGE_END CQ10682*
+ #endif //ADV_DIAG_STATS
+
+-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);
++extern struct file_operations tn7dsl_proc_modem_fops;
+ //UR8_MERGE_START CQ11813 Hao-Ting
+ #ifdef LINUX_CLI_SUPPORT
+-int tn7dsl_proc_dbgmsg_write(struct file *fp, const char *buf, unsigned long count, void *data);
+-int tn7dsl_proc_dbgmsg_read(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7dsl_proc_dbgmsg_fops;
+ #endif
+ //UR8_MERGE_END CQ11813
+ int tn7dsl_handle_interrupt(void);
+@@ -142,31 +140,31 @@ int os_atoih(const char *pStr);
+ #endif
+
+ unsigned long os_atoul(const char *pStr);
+-int tn7dsl_proc_snr0(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_snr1(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_snr2(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_bit_allocation(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_ds_noise(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_generic_read_result(char* buf, char **start, off_t offset, int count, int *eof, void *data);
+-int tn7dsl_proc_train_mode_export(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7dsl_proc_snr0_fops;
++extern struct file_operations tn7dsl_proc_snr1_fops;
++extern struct file_operations tn7dsl_proc_snr2_fops;
++extern struct file_operations tn7dsl_proc_bit_allocation_fops;
++extern struct file_operations tn7dsl_proc_ds_noise_fops;
++extern struct file_operations tn7dsl_proc_generic_read_result_fops;
++extern struct file_operations tn7dsl_proc_train_mode_export_fops;
+
+ #ifndef NO_ADV_STATS
+-int tn7dsl_proc_SNRpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_QLNpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7dsl_proc_SNRpsds_fops;
++extern struct file_operations tn7dsl_proc_QLNpsds_fops;
+ // * UR8_MERGE_START CQ10979 Jack Zhang
+ #ifdef TR69_HLIN_IN
+-//int tn7dsl_proc_HLINpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_HLINpsds1(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_HLINpsds2(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_HLINpsds3(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_HLINpsds4(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++//extern struct file_operations tn7dsl_proc_HLINpsds_fops;
++extern struct file_operations tn7dsl_proc_HLINpsds1_fops;
++extern struct file_operations tn7dsl_proc_HLINpsds2_fops;
++extern struct file_operations tn7dsl_proc_HLINpsds3_fops;
++extern struct file_operations tn7dsl_proc_HLINpsds4_fops;
+ #endif //TR69_HLIN_IN
+ // * UR8_MERGE_END CQ10979*
+ // * UR8_MERGE_START CQ11057 Jack Zhang
+ #define TR69_PMD_IN
+ #ifdef TR69_PMD_IN
+-//int tn7dsl_proc_PMDus(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7dsl_proc_PMDus(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++//extern struct file_operations tn7dsl_proc_PMDus_fops;
++extern struct file_operations tn7dsl_proc_PMDus_fops;
+ #endif //TR69_PMD_IN
+ // * UR8_MERGE_END CQ11057 *
+ #endif
+@@ -183,12 +181,12 @@ void tn7sar_get_sar_version(Tn7AtmPrivat
+ int tn7sar_get_near_end_loopback_count(unsigned int *pF4count, unsigned int *pF5count);
+ int tn7sar_oam_generation(void *privContext, int chan, int type, int vpi, int vci, int timeout);
+ int tn7sar_get_stats(void *priv1);
+-int tn7sar_proc_sar_stat(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7sar_proc_sar_stat_fops;
+ #ifdef AR7_EFM
+ void tn7sar_get_EFM_firmware_version(unsigned int *pdsp_version_ms, unsigned int *pdsp_version_ls);
+ #endif
+ void tn7sar_get_sar_firmware_version(unsigned int *pdsp_version_ms, unsigned int *pdsp_version_ls);
+-int tn7sar_proc_oam_ping(char* buf, char **start, off_t offset, int count,int *eof, void *data);
+-int tn7sar_proc_pvc_table(char* buf, char **start, off_t offset, int count,int *eof, void *data);
++extern struct file_operations tn7sar_proc_oam_ping_fops;
++extern struct file_operations tn7sar_proc_pvc_table_fops;
+ int tn7sar_tx_flush(void *privContext, int chan, int queue, int skip);
+ #endif __SGAPI_H
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -265,11 +265,9 @@ MODULE_PARM_DESC(oam_lb_timeout, "OAM LB
+
+ #ifdef AR7_EFM
+ extern void tn7dsl_disable_alarm(void);
+-extern int tn7efm_proc_channels (char *buf, char **start,
+- off_t offset, int count, int *eof, void *data);
+-extern int tn7efm_proc_ctrl_read (char *buf, char **start, off_t offset, int count, int *eof, void *data);
+-extern int tn7efm_proc_ctrl_write (struct file *fp, const char *buf, unsigned long count, void *data);
+-extern int tn7efm_proc_info (char *buf, char **start, off_t offset, int count, int *eof, void *data);
++extern struct file_operations tn7efm_proc_channels_fops;
++extern struct file_operations tn7efm_proc_ctrl_fops;
++extern struct file_operations tn7efm_proc_info_fops;
+ extern unsigned int g_efm_proc_ctl;
+ extern struct net_device *mydev_efm;
+ extern Tn7AtmPrivate *mypriv;
+@@ -305,31 +303,17 @@ extern int tn7efm_register (Tn7AtmPrivat
+ static int tn7atm_irq_request (struct atm_dev *dev);
+ #endif
+
+-static int tn7atm_proc_version (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data);
++static struct file_operations tn7atm_proc_version_fops;
+ static void tn7atm_exit (void);
+-static int tn7atm_proc_channels (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data);
+-static int tn7atm_proc_private (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data);
++static struct file_operations tn7atm_proc_channels_fops;
++static struct file_operations tn7atm_proc_private_fops;
+ inline static int tn7atm_queue_packet_to_sar (void *vcc1, void *skb1,
+ int chan);
+
+-static int tn7atm_xlate_proc_name (const char *name,
+- struct proc_dir_entry **ret,
+- const char **residual);
+-static int tn7atm_proc_match (int len, const char *name,
+- struct proc_dir_entry *de);
+-static int tn7atm_proc_qos_read (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data);
+-static int tn7atm_proc_qos_write (struct file *fp, const char *buf,
+- unsigned long count, void *data);
++static struct file_operations tn7atm_proc_qos_fops;
+
+ // [KT]
+-static int tn7atm_proc_turbodsl_read (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data);
+-static int tn7atm_proc_turbodsl_write (struct file *fp, const char *buf,
+- unsigned long count, void *data);
++static struct file_operations tn7atm_proc_turbodsl_fops;
+
+ //CT - Added function to return chipset Id
+ void tn7atm_get_chipsetId (char *pVerId);
+@@ -456,78 +440,83 @@ const char drv_proc_root_folder[] = "ava
+ static struct proc_dir_entry *root_proc_dir_entry = NULL;
+ #define DRV_PROC_MODE 0644
+ static int proc_root_already_exists = TRUE;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
++#define PDE_DATA(inode) PDE(inode)->data
++#endif
++
+ static struct
+ {
+ const unsigned char name[32];
+- int (*read_func) (char* , char **, off_t , int ,int *, void *);
+- int (*write_func) (struct file *, const char * , unsigned long , void *);
++ struct file_operations *fops;
+
+ } proc_if[] = {
+ #ifdef AR7_EFM
+ #ifdef EFM_DEBUG
+- {"avsar_efm_channel", tn7efm_proc_channels, NULL},
++ {"avsar_efm_channel", &tn7efm_proc_channels_fops},
+ #endif
+- {"avsar_efm_info", tn7efm_proc_info, NULL},
+- {"avsar_efm_ctl", tn7efm_proc_ctrl_read, tn7efm_proc_ctrl_write},
++ {"avsar_efm_info", &tn7efm_proc_info_fops},
++ {"avsar_efm_ctl", &tn7efm_proc_ctrl_fops},
+ #endif
+- {"avsar_ver", tn7atm_proc_version, NULL},
+- {"avsar_channels", tn7atm_proc_channels, NULL},
+- {"avsar_sarhal_stats", tn7sar_proc_sar_stat, NULL},
+- {"avsar_oam_ping", tn7sar_proc_oam_ping, NULL},
+- {"avsar_pvc_table", tn7sar_proc_pvc_table, NULL},
+- {"avsar_rxsnr0", tn7dsl_proc_snr0, NULL},
+- {"avsar_rxsnr1", tn7dsl_proc_snr1, NULL},
+- {"avsar_rxsnr2", tn7dsl_proc_snr2, NULL},
+- {"clear_eoc_stats", tn7dsl_proc_eoc, NULL},
+- {"avsar_bit_allocation_table", tn7dsl_proc_bit_allocation, NULL},
+- {"avsar_dsl_modulation_schemes",tn7dsl_proc_train_mode_export, NULL},
++ {"avsar_ver", &tn7atm_proc_version_fops},
++ {"avsar_channels", &tn7atm_proc_channels_fops},
++ {"avsar_sarhal_stats", &tn7sar_proc_sar_stat_fops},
++ {"avsar_oam_ping", &tn7sar_proc_oam_ping_fops},
++ {"avsar_pvc_table", &tn7sar_proc_pvc_table_fops},
++ {"avsar_rxsnr0", &tn7dsl_proc_snr0_fops},
++ {"avsar_rxsnr1", &tn7dsl_proc_snr1_fops},
++ {"avsar_rxsnr2", &tn7dsl_proc_snr2_fops},
++ {"clear_eoc_stats", &tn7dsl_proc_eoc_fops},
++ {"avsar_bit_allocation_table", &tn7dsl_proc_bit_allocation_fops},
++ {"avsar_dsl_modulation_schemes",&tn7dsl_proc_train_mode_export_fops},
+ #ifndef NO_ADV_STATS
+- {"avsar_SNRpsds", tn7dsl_proc_SNRpsds, NULL},
+- {"avsar_QLNpsds", tn7dsl_proc_QLNpsds, NULL},
++ {"avsar_SNRpsds", &tn7dsl_proc_SNRpsds_fops},
++ {"avsar_QLNpsds", &tn7dsl_proc_QLNpsds_fops},
+ // * UR8_MERGE_START CQ10979 Jack Zhang
+ #ifdef TR69_HLIN_IN
+-// {"avsar_HLINpsds", tn7dsl_proc_HLINpsds, NULL},
+- {"avsar_HLINpsds1", tn7dsl_proc_HLINpsds1, NULL},
+- {"avsar_HLINpsds2", tn7dsl_proc_HLINpsds2, NULL},
+- {"avsar_HLINpsds3", tn7dsl_proc_HLINpsds3, NULL},
+- {"avsar_HLINpsds4", tn7dsl_proc_HLINpsds4, NULL},
++// {"avsar_HLINpsds", &tn7dsl_proc_HLINpsds_fops},
++ {"avsar_HLINpsds1", &tn7dsl_proc_HLINpsds1_fops},
++ {"avsar_HLINpsds2", &tn7dsl_proc_HLINpsds2_fops},
++ {"avsar_HLINpsds3", &tn7dsl_proc_HLINpsds3_fops},
++ {"avsar_HLINpsds4", &tn7dsl_proc_HLINpsds4_fops},
+ #endif //TR69_HLIN_IN
+ // * UR8_MERGE_END CQ10979*
+ // * UR8_MERGE_START CQ11057 Jack Zhang
+ #define TR69_PMD_IN
+ #ifdef TR69_PMD_IN
+- {"avsar_PMDTestus", tn7dsl_proc_PMDus, NULL},
+-// {"avsar_PMDTestus1", tn7dsl_proc_PMDus1, NULL},
++ {"avsar_PMDTestus", &tn7dsl_proc_PMDus_fops},
++// {"avsar_PMDTestus1", &tn7dsl_proc_PMDus1_fops},
+ #endif //TR69_PMD_IN
+ // * UR8_MERGE_END CQ11057 *
+ #endif
+- {"avsar_private", tn7atm_proc_private, NULL},
+- {"avsar_modem_training", tn7dsl_proc_modem, NULL},
+- {"avsar_modem_stats", tn7dsl_proc_stats, tn7dsl_proc_write_stats},
++ {"avsar_private", &tn7atm_proc_private_fops},
++ {"avsar_modem_training", &tn7dsl_proc_modem_fops},
++ {"avsar_modem_stats", &tn7dsl_proc_stats_fops},
+
+ #ifdef ADV_DIAG_STATS //CQ10275
+-//for 2.6 {"avsar_modem_adv_stats", tn7dsl_proc_adv_stats, NULL},
++//for 2.6 {"avsar_modem_adv_stats", &tn7dsl_proc_adv_stats_fops},
+ //For 2.4 kernel, due to proc file system size limitation
+- {"avsar_modem_adv_stats1", tn7dsl_proc_adv_stats1, NULL},
+- {"avsar_modem_adv_stats2", tn7dsl_proc_adv_stats2, NULL},
+- {"avsar_modem_adv_stats3", tn7dsl_proc_adv_stats3, NULL},
++ {"avsar_modem_adv_stats1", &tn7dsl_proc_adv_stats1_fops},
++ {"avsar_modem_adv_stats2", &tn7dsl_proc_adv_stats2_fops},
++ {"avsar_modem_adv_stats3", &tn7dsl_proc_adv_stats3_fops},
+ //UR8_MERGE_START CQ10682 Jack Zhang
+- {"avsar_modem_dbg_cmsgs", tn7dsl_proc_dbg_cmsgs, NULL},
+- {"avsar_modem_dbg_rmsgs1", tn7dsl_proc_dbg_rmsgs1, NULL},
+- {"avsar_modem_dbg_rmsgs2", tn7dsl_proc_dbg_rmsgs2, NULL},
+- {"avsar_modem_dbg_rmsgs3", tn7dsl_proc_dbg_rmsgs3, NULL},
+- {"avsar_modem_dbg_rmsgs4", tn7dsl_proc_dbg_rmsgs4, NULL},
++ {"avsar_modem_dbg_cmsgs", &tn7dsl_proc_dbg_cmsgs_fops},
++ {"avsar_modem_dbg_rmsgs1", &tn7dsl_proc_dbg_rmsgs1_fops},
++ {"avsar_modem_dbg_rmsgs2", &tn7dsl_proc_dbg_rmsgs2_fops},
++ {"avsar_modem_dbg_rmsgs3", &tn7dsl_proc_dbg_rmsgs3_fops},
++ {"avsar_modem_dbg_rmsgs4", &tn7dsl_proc_dbg_rmsgs4_fops},
+ // UR8_MERGE_END CQ10682*
+ #endif //ADV_DIAG_STATS
+ //UR8_MERGE_START CQ11813 Hao-Ting
+ #ifdef LINUX_CLI_SUPPORT
+- {"avsar_dbg_enable", tn7dsl_proc_dbgmsg_read, tn7dsl_proc_dbgmsg_write},
++ {"avsar_dbg_enable", &tn7dsl_proc_dbgmsg_fops},
+ #endif
+ //UR8_MERGE_END CQ11813
+- {"avsar_qos_enable", tn7atm_proc_qos_read, tn7atm_proc_qos_write},
++ {"avsar_qos_enable", &tn7atm_proc_qos_fops},
+ #if 1 /* [MS] */
+- {"avsar_turbodsl", tn7atm_proc_turbodsl_read, tn7atm_proc_turbodsl_write}
++ {"avsar_turbodsl", &tn7atm_proc_turbodsl_fops}
+ #endif
++
+ };
+
+ /* *INDENT-ON* */
+@@ -1811,76 +1800,81 @@ int tn7atm_receive (void *os_dev, int ch
+ return 0;
+ }
+
+-
+-static int tn7atm_proc_channels (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data)
++static int tn7atm_proc_channels (struct seq_file *m, void *data)
+ {
+- int len = 0;
+- int limit = count - 80;
+ int i;
+
+ struct atm_dev *dev;
+ Tn7AtmPrivate *priv;
+
+- dev = (struct atm_dev *) data;
++ dev = (struct atm_dev *) m->private;
+ priv = (Tn7AtmPrivate *) dev->dev_data;
+
+- if (len <= limit)
+- len += sprintf (buf + len, "Chan Inuse ChanID VPI VCI \n");
+- if (len <= limit)
+- len +=
+- sprintf (buf + len,
++ seq_printf (m, "Chan Inuse ChanID VPI VCI \n");
++ seq_printf (m,
+ "------------------------------------------------------------------\n");
+
+ for (i = 0; i <= MAX_DMA_CHAN; i++)
+ {
+- if (len <= limit)
+- {
+- len += sprintf (buf + len,
+- " %02d %05d %05d %05d %05d \n",
+- i, priv->lut[i].inuse, priv->lut[i].chanid,
+- priv->lut[i].vpi, priv->lut[i].vci);
+- }
++ seq_printf (m,
++ " %02d %05d %05d %05d %05d \n",
++ i, priv->lut[i].inuse, priv->lut[i].chanid,
++ priv->lut[i].vpi, priv->lut[i].vci);
+ }
+
+- if (len <= limit)
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "------------------------------------------------------------------\n");
+
+- return len;
++ return 0;
++}
++
++static int tn7atm_proc_channels_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7atm_proc_channels, PDE_DATA(inode));
+ }
+
+-static int tn7atm_proc_private (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data)
++static struct file_operations tn7atm_proc_channels_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7atm_proc_channels_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++
++static int tn7atm_proc_private (struct seq_file *m, void *data)
+ {
+- int len = 0;
+- int limit = count - 80;
+ struct atm_dev *dev;
+ Tn7AtmPrivate *priv;
+
+- dev = (struct atm_dev *) data;
++ dev = (struct atm_dev *) m->private;
+ priv = (Tn7AtmPrivate *) dev->dev_data;
+
+- if (len <= limit)
+- len += sprintf (buf + len, "\nPrivate Data Structure(%s):\n", priv->name);
+- if (len <= limit)
+- len += sprintf (buf + len, "----------------------------------------\n");
+- if (len <= limit)
+- len += sprintf (buf + len, "priv: 0x%p\n", priv);
+- if (len <= limit)
+- len += sprintf (buf + len, "next: 0x%p", priv->next);
+- if (len <= limit)
+- len += sprintf (buf + len, "\tdev: 0x%p\n", priv->dev);
+-
+- if (len <= limit)
+- len += sprintf (buf + len, "tx_irq: %02d", priv->sar_irq);
+- if (len <= limit)
+- len += sprintf (buf + len, "rx_irq: %02d", priv->dsl_irq);
++ seq_printf (m, "\nPrivate Data Structure(%s):\n", priv->name);
++ seq_printf (m, "----------------------------------------\n");
++ seq_printf (m, "priv: 0x%p\n", priv);
++ seq_printf (m, "next: 0x%p", priv->next);
++ seq_printf (m, "\tdev: 0x%p\n", priv->dev);
++
++ seq_printf (m, "tx_irq: %02d", priv->sar_irq);
++ seq_printf (m, "rx_irq: %02d", priv->dsl_irq);
++
++ return 0;
++}
+
+- return len;
++static int tn7atm_proc_private_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7atm_proc_private, PDE_DATA(inode));
+ }
+
++static struct file_operations tn7atm_proc_private_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7atm_proc_private_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ void tn7atm_sarhal_isr_register (void *os_dev, void *hal_isr,
+ int interrupt_num)
+ {
+@@ -2033,10 +2027,8 @@ static int __init tn7atm_register (Tn7At
+ return ATM_REG_OK;
+ }
+
+-static int tn7atm_proc_version (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data)
++static int tn7atm_proc_version (struct seq_file *m, void *data)
+ {
+- int len = 0;
+ char dslVer[8];
+ char dspVer[10];
+ char chipsetID[32]; //CT CQ10076 - Added temporary buffer to store chipset Id
+@@ -2051,58 +2043,52 @@ static int tn7atm_proc_version (char *bu
+ priv = mydev->dev_data;
+
+ #ifdef AR7_EFM
+- len +=
+- sprintf (buf + len, "ATM/EFM Driver version:[%d.%02d.%02d.%02d]\n",
+- LINUXATM_VERSION_MAJOR, LINUXATM_VERSION_MINOR,
+- LINUXATM_VERSION_BUGFIX, LINUXATM_VERSION_BUILDNUM);
+-
++ seq_printf (m, "ATM/EFM Driver version:[%d.%02d.%02d.%02d]\n",
++ LINUXATM_VERSION_MAJOR, LINUXATM_VERSION_MINOR,
++ LINUXATM_VERSION_BUGFIX, LINUXATM_VERSION_BUILDNUM);
+ #else
+- len +=
+- sprintf (buf + len, "ATM Driver version:[%d.%02d.%02d.%02d]\n",
+- LINUXATM_VERSION_MAJOR, LINUXATM_VERSION_MINOR,
+- LINUXATM_VERSION_BUGFIX, LINUXATM_VERSION_BUILDNUM);
++ seq_printf (m, "ATM Driver version:[%d.%02d.%02d.%02d]\n",
++ LINUXATM_VERSION_MAJOR, LINUXATM_VERSION_MINOR,
++ LINUXATM_VERSION_BUGFIX, LINUXATM_VERSION_BUILDNUM);
+ #endif
+
+ tn7dsl_get_dslhal_version (dslVer);
+
+- len +=
+- sprintf (buf + len, "DSL HAL version: [%d.%02d.%02d.%02d]\n", dslVer[0],
+- dslVer[1], dslVer[2], dslVer[3]);
++ seq_printf (m, "DSL HAL version: [%d.%02d.%02d.%02d]\n", dslVer[0],
++ dslVer[1], dslVer[2], dslVer[3]);
+ tn7dsl_get_dsp_version (dspVer);
+
+ #ifdef EFM_DEBUG
+- len +=
+- sprintf (buf + len, "DSP Datapump version: [%d.%02d.%02d.%02d(%u)] ",
+- dspVer[4], dspVer[5], dspVer[6], dspVer[7], (unsigned char) dspVer[7]);
++ seq_printf (m, "DSP Datapump version: [%d.%02d.%02d.%02d(%u)] ",
++ dspVer[4], dspVer[5], dspVer[6], dspVer[7], (unsigned char) dspVer[7]);
+ #else
+- len +=
+- sprintf (buf + len, "DSP Datapump version: [%d.%02d.%02d.%02d] ",
+- dspVer[4], dspVer[5], dspVer[6], dspVer[7]);
++ seq_printf (m, "DSP Datapump version: [%d.%02d.%02d.%02d] ",
++ dspVer[4], dspVer[5], dspVer[6], dspVer[7]);
+ #endif
+ if (dspVer[8] == 2) // annex B
+- len += sprintf (buf + len, "Annex B\n");
++ seq_printf (m, "Annex B\n");
+ else if (dspVer[8] == 3) // annex c
+- len += sprintf (buf + len, "Annex c\n");
++ seq_printf (m, "Annex c\n");
+ else
+- len += sprintf (buf + len, "Annex A\n");
++ seq_printf (m, "Annex A\n");
+
+ tn7sar_get_sar_version (priv, &pSarVer);
+
+- len += sprintf (buf + len, "SAR HAL version: [");
++ seq_printf (m, "SAR HAL version: [");
+ for (i = 0; i < 8; i++)
+ {
+- len += sprintf (buf + len, "%c", pSarVer[i + 7]);
++ seq_printf (m, "%c", pSarVer[i + 7]);
+ }
+- len += sprintf (buf + len, "]\n");
++ seq_printf (m, "]\n");
+
+ tn7sar_get_sar_firmware_version (&pdspV1, &pdspV2);
+
+ #ifndef AR7_EFM
+- len += sprintf (buf + len, "PDSP Firmware version:[%01x.%02x]\n",
++ seq_printf (m, "PDSP Firmware version:[%01x.%02x]\n",
+ pdspV1, pdspV2);
+ #else
+
+- len += sprintf (buf + len, "PDSP Firmware version:[%01x.%02x](ATM)%c\n",
++ seq_printf (m, "PDSP Firmware version:[%01x.%02x](ATM)%c\n",
+ pdspV1, pdspV2, (priv->curr_TC_mode== TC_MODE_ATM) ? '*' : ' ');
+
+ tn7sar_get_EFM_firmware_version (&pdspV1, &pdspV2);
+@@ -2114,26 +2100,37 @@ static int tn7atm_proc_version (char *bu
+ #endif
+ str = "EFM";
+
+- len += sprintf (buf + len, "PDSP Firmware version:[%01x.%02x](%s)%c\n",
++ seq_printf (m, "PDSP Firmware version:[%01x.%02x](%s)%c\n",
+ pdspV1, pdspV2, str, (priv->curr_TC_mode== TC_MODE_PTM) ? '*' : ' ');
+
+ #endif
+
+ //CT CQ10076 - Added code to report chipset ID using proc file system
+ tn7atm_get_chipsetId(chipsetID);
+- len += sprintf (buf + len, "Chipset ID: [%s]\n",chipsetID);
++ seq_printf (m, "Chipset ID: [%s]\n",chipsetID);
++
++ return 0;
++}
+
+- return len;
++static int tn7atm_proc_version_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7atm_proc_version, PDE_DATA(inode));
+ }
+
++static struct file_operations tn7atm_proc_version_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7atm_proc_version_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+
+ /* Device detection */
+
+ static int __init tn7atm_detect (void)
+ {
+ Tn7AtmPrivate *priv;
+- struct proc_dir_entry *dsl_wr_file = NULL; /* Only for ones with a write
+- * function. */
+ int ctr;
+ const char *residual;
+
+@@ -2214,24 +2211,7 @@ static int __init tn7atm_detect (void)
+ */
+ for (ctr = 0; ctr < (NUM_ELEMS (proc_if)); ctr++)
+ {
+- /* Only if we have a write function, we create a normal proc file. */
+- if(proc_if[ctr].write_func)
+- {
+- dsl_wr_file = create_proc_entry (proc_if[ctr].name, DRV_PROC_MODE, root_proc_dir_entry);
+- if (dsl_wr_file)
+- {
+- dsl_wr_file->read_proc = proc_if[ctr].read_func;
+- dsl_wr_file->write_proc = proc_if[ctr].write_func;
+- dsl_wr_file->data = (void *)mydev; //UR8_MERGE_START_END CQ10700 Manjula K
+- }
+- dsl_wr_file = NULL;
+- }
+- else
+- {
+- /* Create a read-only entry. */
+- create_proc_read_entry (proc_if[ctr].name, 0, root_proc_dir_entry,
+- proc_if[ctr].read_func, mydev);
+- }
++ proc_create_data(proc_if[ctr].name, DRV_PROC_MODE, root_proc_dir_entry, proc_if[ctr].fops, (void *)mydev);
+ }
+
+ tn7dsl_dslmod_sysctl_register ();
+@@ -2711,73 +2691,18 @@ static int tn7atm_set_can_support_adsl2
+ return TRUE;
+ }
+
+-/*
+- * This function matches a name such as "serial", and that specified by the
+- * proc_dir_entry
+- */
+-static int tn7atm_proc_match (int len, const char *name,
+- struct proc_dir_entry *de)
++static int tn7atm_proc_qos_read(struct seq_file *m, void *data)
+ {
+- if (!de || !de->low_ino)
++ seq_printf (m, "\nEnableQoS = %d\n", EnableQoS);
+ return 0;
+- if (de->namelen != len)
+- return 0;
+- return !strncmp (name, de->name, len);
+-}
+-
+-/*
+- * This function parses a name such as "tty/driver/serial", and
+- * returns the struct proc_dir_entry for "/proc/tty/driver", and
+- * returns "serial" in residual.
+- */
+-static int tn7atm_xlate_proc_name (const char *name,
+- struct proc_dir_entry **ret,
+- const char **residual)
+-{
+- const char *cp = name, *next;
+- struct proc_dir_entry *de;
+- int len;
+- extern struct proc_dir_entry proc_root;
+-
+- de = &proc_root;
+- while (1)
+- {
+- next = strchr (cp, '/');
+- if (!next)
+- break;
+-
+- len = next - cp;
+- for (de = de->subdir; de; de = de->next)
+- {
+- if (tn7atm_proc_match (len, cp, de))
+- break;
+- }
+- if (!de)
+- return -ENOENT;
+- cp += len + 1;
+- }
+- *residual = cp;
+- *ret = de;
+-
+- return 0;
+-}
+-
+-static int tn7atm_proc_qos_read(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+-{
+- int len = 0;
+-
+- len += sprintf (buf + len, "\nEnableQoS = %d\n", EnableQoS);
+- return len;
+
+ }
+
+ // [KT]
+-static int tn7atm_proc_turbodsl_read(char *buf, char **start, off_t offset, int count, int *eof, void *data)
++static int tn7atm_proc_turbodsl_read(struct seq_file *m, void *data)
+ {
+- int len = 0;
+-
+- len += sprintf (buf + len, "%d\n", bTurboDsl);
+- return len;
++ seq_printf (m, "%d\n", bTurboDsl);
++ return 0;
+ }
+
+ static int tn7atm_proc_qos_write(struct file *fp, const char *buf, unsigned long count, void *data)
+@@ -2812,7 +2737,7 @@ static int tn7atm_proc_qos_write(struct
+ }
+
+ // [KT]
+-int tn7atm_proc_turbodsl_write(struct file *fp, const char *buf, unsigned long count, void *data)
++static int tn7atm_proc_turbodsl_write(struct file *fp, const char *buf, unsigned long count, void *data)
+ {
+ char local_buf[10];
+
+@@ -2843,5 +2768,33 @@ int tn7atm_proc_turbodsl_write(struct fi
+ return count;
+ }
+
++static int tn7atm_proc_qos_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7atm_proc_qos_read, PDE_DATA(inode));
++}
++
++static struct file_operations tn7atm_proc_qos_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7atm_proc_qos_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++ .write = tn7atm_proc_qos_write,
++};
++
++static int tn7atm_proc_turbodsl_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7atm_proc_turbodsl_read, PDE_DATA(inode));
++}
++
++static struct file_operations tn7atm_proc_turbodsl_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7atm_proc_turbodsl_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++ .write = tn7atm_proc_turbodsl_write,
++};
++
+ module_init (tn7atm_detect);
+ module_exit (tn7atm_exit);
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -233,6 +233,9 @@ static struct led_funcs ledreg[2];
+
+ #define tn7dsl_kfree_skb(x) dev_kfree_skb(x)
+
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
++#define PDE_DATA(inode) PDE(inode)->data
++#endif
+
+ //---------------------------------------------
+ // Begin Clear EOC definitions
+@@ -366,7 +369,7 @@ static void tn7dsl_register_dslss_led(vo
+ void tn7dsl_dslmod_sysctl_register(void);
+ void tn7dsl_dslmod_sysctl_unregister(void);
+ static int tn7dsl_clear_eoc_receive(void);
+-static int tn7dsl_proc_snr_print (char *buf, int count, int *eof, int data);
++static int tn7dsl_proc_snr_print (struct seq_file *m, int data);
+ /* end of internal functions */
+
+ // UR8_MERGE_START CQ11054 Jack Zhang
+@@ -698,11 +701,9 @@ void shim_osCriticalExit(void)
+ spin_unlock_irqrestore(&shimLock, flags);
+ }
+
+-static int tn7dsl_proc_snr_print (char *buf, int count, int *eof, int data)
++static int tn7dsl_proc_snr_print (struct seq_file *m, int data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ int i, j;
+ int bin = (int) data;
+ unsigned short *rxSnrPerBin;
+@@ -723,95 +724,128 @@ static int tn7dsl_proc_snr_print (char *
+ break;
+
+ default:
+- if(len<=limit)
+- len += sprintf (buf + len, "\nInvalid bin selected Bin%d :\n", bin);
+- return len;
+-}
++ seq_printf (m, "\nInvalid bin selected Bin%d :\n", bin);
++ return 0;
++ }
+
+- if(len<=limit)
+- len += sprintf (buf + len, "\nAR7 DSL Modem Rx SNR Per Bin for Bin%d :\n", bin);
++ seq_printf (m, "\nAR7 DSL Modem Rx SNR Per Bin for Bin%d :\n", bin);
+
+ for (i=0; i<pIhw->AppData.max_ds_tones/16; i++)
+ {
+ for(j=0;j<16;j++)
+ {
+- if(len <=limit)
+- len +=
+- sprintf (buf + len, "%04x ",
++ seq_printf (m, "%04x ",
+ (unsigned short) rxSnrPerBin[i * 16 + j]);
+- }
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
+ }
++ seq_printf(m, "\n");
++ }
+
+- return len;
++ return 0;
+ }
+
+
+ //@Added SNR per bin info per customer request. 05-14-2004
+-int tn7dsl_proc_snr0 (char *buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_snr0 (struct seq_file *m, void *data)
+ {
+- return tn7dsl_proc_snr_print(buf, count, eof, 0);
++ return tn7dsl_proc_snr_print(m, 0);
+ }
+
+-int tn7dsl_proc_snr1 (char *buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_snr0_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_snr_print(buf, count, eof, 1);
++ return single_open(file, tn7dsl_proc_snr0, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_snr0_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_snr0_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++static int tn7dsl_proc_snr1 (struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_snr_print(m, 1);
+ }
+
+-int tn7dsl_proc_snr2 (char *buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_snr1_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_snr_print(buf, count, eof, 2);
++ return single_open(file, tn7dsl_proc_snr1, PDE_DATA(inode));
+ }
+
++struct file_operations tn7dsl_proc_snr1_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_snr1_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++static int tn7dsl_proc_snr2 (struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_snr_print(m, 2);
++}
++
++static int tn7dsl_proc_snr2_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_snr2, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_snr2_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_snr2_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ //@Added bit allocation table per customer request. 05-14-2004
+-int tn7dsl_proc_bit_allocation (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data)
++static int tn7dsl_proc_bit_allocation (struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ int i, j;
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 DSL Modem US Bit Allocation:");
++ seq_printf(m, "\nAR7 DSL Modem US Bit Allocation:");
+
+ for(i=0; i<pIhw->AppData.max_us_tones; i++)
+ {
+ if (!(i%16))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len <=limit)
+- len +=
+- sprintf (buf + len, "%02x ",
+- (unsigned char) pIhw->AppData.BitAllocTblUstrm[i]);
++ seq_printf (m, "%02x ",
++ (unsigned char) pIhw->AppData.BitAllocTblUstrm[i]);
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\nAR7 DSL Modem DS Bit Allocation:\n");
++ seq_printf(m, "\n\nAR7 DSL Modem DS Bit Allocation:\n");
+
+ for (i=0; i<pIhw->AppData.max_ds_tones/16; i++)
+ {
+ for(j=0;j<16;j++)
+ {
+- if(len <=limit)
+- len +=
+- sprintf (buf + len, "%02x ",
+- (unsigned char) pIhw->AppData.BitAllocTblDstrm[i * 16 +
+- j]);
++ seq_printf (m, "%02x ",
++ (unsigned char) pIhw->AppData.BitAllocTblDstrm[i * 16 +
++ j]);
+ }
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- return len;
++ return 0;
++}
++
++int tn7dsl_proc_bit_allocation_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_bit_allocation, PDE_DATA(inode));
+ }
+
++struct file_operations tn7dsl_proc_bit_allocation_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_bit_allocation_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #ifndef NO_ACT
+ int tn7dsl_proc_ds_noise(char* buf, char **start, off_t offset, int count,
+ int *eof, void *data)
+@@ -874,59 +908,48 @@ static char *pUnknown= "Unknown";
+ #ifdef ADV_DIAG_STATS //CQ10275, CQ10449
+ //UR8_MERGE_START CQ10449 Jack Zhang
+
+-static int proc_adv_stats_header(char* buf, int limit);
++static int proc_adv_stats_header(struct seq_file *m);
+
+-int tn7dsl_proc_adv_stats(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_adv_stats(struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ //char *cp = buf + offset;
+ char *cp = buf;
+ int i = 0;
+ int strt = 32;
+- static int ctr = 0;
+
+ // printk("proc_adv_stats: buf=0x%X, ctr=%d, offset=%d, count=%d, eof=%d\n",
+ // (unsigned int)buf, ctr, offset, count, *eof);
+- if( ctr == 0)
+- {
+- len = proc_adv_stats_header( cp, limit);
++ proc_adv_stats_header(m);
+
+- if( len<=limit)
+- len += sprintf(cp+len, "\n\tBin No.\tBits:\tMargin:\tSNR\n");
+- }
+- else
+- {
+- strt = ctr;
+- }
++ seq_printf(m, "\n\tBin No.\tBits:\tMargin:\tSNR\n");
+
+ for( i =strt; i<512; i++)
+ {
+- if(len<=limit)
+- {
+- len += sprintf(cp+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (int)pIhw->AppData.rxSnrPerBin0[i]);
+- }
+- else
+- {
+- ctr = i;
+- //*eof = 0;
+- *(cp + len) = '\0';
+- printk("proc_adv_stats - return: ctr=%d, len=%d\n", ctr, len);
+- return len;
+- }
+ }
+- ctr = 0;
+- *eof = 1;
+ printk("proc_adv_stats - return: ctr=%d, len=%d\n", ctr, len);
+- return len;
++ return 0;
+ }
+
+-static int proc_adv_stats_header(char* buf, int limit)
++
++static int tn7dsl_proc_adv_stats_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_adv_stats, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_adv_stats_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_adv_stats_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++static int proc_adv_stats_header(struct seq_file *m)
+ {
+ int len = 0;
+ int i = 0;
+@@ -935,66 +958,53 @@ static int proc_adv_stats_header(char* b
+ */
+
+ dslhal_api_gatherStatistics(pIhw);
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 DSL Modem Advanced Statistics:\n");
++ seq_printf(m, "\nAR7 DSL Modem Advanced Statistics:\n");
+
+- if(len<=limit)
++ if(pIhw->lConnected != 1)
+ {
+- if(pIhw->lConnected != 1)
+- {
+- pIhw->AppData.USConRate = 0;
+- pIhw->AppData.DSConRate = 0;
+- }
+- len +=
+- sprintf (buf + len,
++ pIhw->AppData.USConRate = 0;
++ pIhw->AppData.DSConRate = 0;
++ }
++ seq_printf (m,
+ "\t[Connection Rate]\tUS:\t%u\tDS:\t%u\n",
+ (unsigned int)pIhw->AppData.USConRate,
+ (unsigned int)pIhw->AppData.DSConRate );
+ }
+- if(len<=limit)
+ // UR8_MERGE_START CQ11054 Jack Zhang
++ if (dslhal_api_getHighPrecision())
+ {
+- if (dslhal_api_getHighPrecision())
+- {
+- len +=
+- sprintf (buf + len, "\t[Margin]\tUS:\t%d.%u\tDS:\t\t%d.%u\n",
+- gInt(pIhw->AppData.usMargin), gDot1(pIhw->AppData.usMargin),
+- gInt(pIhw->AppData.dsMargin), gDot1(pIhw->AppData.dsMargin));
+- }
+- else
+- {
+- len +=
+- sprintf (buf + len, "\t[Margin]\tUS:\t%u\tDS:\t\t%u\n",
+- (unsigned int)pIhw->AppData.usMargin,
+- (unsigned int)pIhw->AppData.dsMargin/2 );
+- }
++ seq_printf (m, "\t[Margin]\tUS:\t%d.%u\tDS:\t\t%d.%u\n",
++ gInt(pIhw->AppData.usMargin), gDot1(pIhw->AppData.usMargin),
++ gInt(pIhw->AppData.dsMargin), gDot1(pIhw->AppData.dsMargin));
++ }
++ else
++ {
++ seq_printf (m, "\t[Margin]\tUS:\t%u\tDS:\t\t%u\n",
++ (unsigned int)pIhw->AppData.usMargin,
++ (unsigned int)pIhw->AppData.dsMargin/2 );
+ }
+ // UR8_MERGE_END CQ11054*
+
+ /*
+ * Downstream/Upstream Interleaved Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\t[Interleave path] US (TX):\tCRC: \t%u\tFEC: \t%u\n",
++ seq_printf(m, "\t[Interleave path] US (TX):\tCRC: \t%u\tFEC: \t%u\n",
+ (unsigned int)pIhw->AppData.usICRC_errors,
+ (unsigned int)pIhw->AppData.usIFEC_errors);
+- if(len<=limit)
+- len += sprintf(buf+len, "\t[Interleave path] DS (RX):\tCRC: \t%u\tFEC: \t%u\n",
++ seq_printf(m, "\t[Interleave path] DS (RX):\tCRC: \t%u\tFEC: \t%u\n",
+ (unsigned int)pIhw->AppData.dsICRC_errors,
+ (unsigned int)pIhw->AppData.dsIFEC_errors);
+ /*
+ * Upstream/Downstream Fast Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\t[Fast path] US (TX): \tCRC: \t%u\tFEC: \t%u\n",
++ seq_printf(m, "\t[Fast path] US (TX): \tCRC: \t%u\tFEC: \t%u\n",
+ (unsigned int)pIhw->AppData.usFCRC_errors,
+ (unsigned int)pIhw->AppData.usFFEC_errors);
+- if(len<=limit)
+- len += sprintf(buf+len, "\t[Fast path] DS (RX):\tCRC: \t%u\tFEC: \t%u\n",
++ seq_printf(m, "\t[Fast path] DS (RX):\tCRC: \t%u\tFEC: \t%u\n",
+ (unsigned int)pIhw->AppData.dsFCRC_errors,
+ (unsigned int)pIhw->AppData.dsFFEC_errors);
+
+- return len;
++ return 0;
+ }
+
+ static int getDiagDisplayMode()
+@@ -1017,29 +1027,24 @@ static int getDiagDisplayMode()
+ ret = 2;
+ return ret;
+ }
+-int tn7dsl_proc_adv_stats1(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++int tn7dsl_proc_adv_stats1(struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ int i;
+ int mode = 0; //mode = 0 => ADSL1 or ADSL2 & 2+
+ unsigned char SNRpsds[512];
+ int n;
+
+- len = proc_adv_stats_header( buf+len, limit);
++ proc_adv_stats_header( m);
+ mode = getDiagDisplayMode();
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\tBin No.\tBits:\tMargin:\tSNR (Part 1 of 3)\n");
++ seq_printf(m, "\tBin No.\tBits:\tMargin:\tSNR (Part 1 of 3)\n");
+
+ if(mode==1) //ADSL1
+ {
+ for( i =32; i<128; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (int)pIhw->AppData.rxSnrPerBin0[i]);
+@@ -1050,26 +1055,34 @@ int tn7dsl_proc_adv_stats1(char* buf, ch
+ if (dslhal_api_getSNRpsds(pIhw, SNRpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getSNRpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+ for( i =32; i<128; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (i<pIhw->AppData.max_ds_tones)?(unsigned char)SNRpsds[i]:0);
+ }
+ }
+- return len;
++ return 0;
+ }
+
+-int tn7dsl_proc_adv_stats2(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_adv_stats1_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_adv_stats1, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++struct file_operations tn7dsl_proc_adv_stats1_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_adv_stats1_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++int tn7dsl_proc_adv_stats2(struct seq_file *m, void *data)
++{
+ int i;
+ int mode = 0; //mode = 0 => ADSL1 or ADSL2 & 2+
+ unsigned char SNRpsds[512];
+@@ -1079,12 +1092,10 @@ int tn7dsl_proc_adv_stats2(char* buf, ch
+ if( mode==1) //ADSL1
+ {
+ dslhal_api_gatherStatistics(pIhw);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tBin No.\tBits:\tMargin:\tSNR (Part 2 of 3):\n");
++ seq_printf(m, "\tBin No.\tBits:\tMargin:\tSNR (Part 2 of 3):\n");
+ for( i =128; i<320; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (int)pIhw->AppData.rxSnrPerBin0[i]);
+@@ -1095,26 +1106,35 @@ int tn7dsl_proc_adv_stats2(char* buf, ch
+ if (dslhal_api_getSNRpsds(pIhw, SNRpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getSNRpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+ for( i =128; i<320; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (i<pIhw->AppData.max_ds_tones)?(unsigned char)SNRpsds[i]:0);
+ }
+ }
+- return len;
++ return 0;
+ }
+
+-int tn7dsl_proc_adv_stats3(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_adv_stats2_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_adv_stats2, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_adv_stats2_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_adv_stats2_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++int tn7dsl_proc_adv_stats3(struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ int i;
+ int mode = 0; //mode = 0 => ADSL1 or ADSL2 & 2+
+ unsigned char SNRpsds[512];
+@@ -1124,12 +1144,10 @@ int tn7dsl_proc_adv_stats3(char* buf, ch
+ if( mode==1) //ADSL1
+ {
+ dslhal_api_gatherStatistics(pIhw);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tBin No.\tBits:\tMargin:\tSNR (Part 3 of 3):\n");
++ seq_printf(m, "\tBin No.\tBits:\tMargin:\tSNR (Part 3 of 3):\n");
+ for( i =320; i<512; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (int)pIhw->AppData.rxSnrPerBin0[i]);
+@@ -1140,283 +1158,287 @@ int tn7dsl_proc_adv_stats3(char* buf, ch
+ if (dslhal_api_getSNRpsds(pIhw, SNRpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getSNRpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+ for( i =320; i<512; i++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\t%u\t%u\t%u\t%d\n", i,
++ seq_printf(m, "\t%u\t%u\t%u\t%d\n", i,
+ (unsigned int)pIhw->AppData.BitAllocTblDstrm[i],
+ (unsigned int)pIhw->AppData.marginTblDstrm[i],
+ (i<pIhw->AppData.max_ds_tones)?(unsigned char)SNRpsds[i]:0);
+ }
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "[End of Stats]\n");
+- return len;
++ seq_printf(m, "[End of Stats]\n");
++ return 0;
+ }
+-//UR8_MERGE_END CQ10449
+-//UR8_MERGE_START CQ10682 Jack Zhang
+-int tn7dsl_proc_dbg_cmsgs(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++
++static int tn7dsl_proc_adv_stats3_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_adv_stats3, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++struct file_operations tn7dsl_proc_adv_stats3_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_adv_stats3_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
+
++//UR8_MERGE_END CQ10449
++//UR8_MERGE_START CQ10682 Jack Zhang
++int tn7dsl_proc_dbg_cmsgs(struct seq_file *m, void *data)
++{
+ int rc=0;
+
+ dslhal_api_gatherStatistics(pIhw);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "Training Messages (C-Msgs 1-5)..\n");
++ seq_printf(m, "Training Messages (C-Msgs 1-5)..\n");
+
+- if(len<=limit)
+- len += sprintf(buf+len, "ADSL2 DELT C-Msg1Ld \t Message Length:%d\n",
++ seq_printf(m, "ADSL2 DELT C-Msg1Ld \t Message Length:%d\n",
+ pIhw->adsl2DiagnosticMessages.cMsg1LdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.cMsg1LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg1Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg1Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT C-Msg2Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg2LdLen);
++ seq_printf(m, "\nADSL2 DELT C-Msg2Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg2LdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.cMsg2LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg2Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg2Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT C-Msg3Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg3LdLen);
++ seq_printf(m, "\nADSL2 DELT C-Msg3Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg3LdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.cMsg3LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg3Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg3Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT C-Msg4Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg4LdLen);
++ seq_printf(m, "\nADSL2 DELT C-Msg4Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg4LdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.cMsg4LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg4Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg4Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT C-Msg5Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg5LdLen);
++ seq_printf(m, "\nADSL2 DELT C-Msg5Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.cMsg5LdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.cMsg5LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg5Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.cMsg5Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
+- return len;
++ seq_printf(m, "\n");
++ return 0;
+ }
+
+-int tn7dsl_proc_dbg_rmsgs1(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_dbg_cmsgs_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_dbg_cmsgs, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++struct file_operations tn7dsl_proc_dbg_cmsgs_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_dbg_cmsgs_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++
++int tn7dsl_proc_dbg_rmsgs1(struct seq_file *m, void *data)
++{
+
+ int rc=0;
+
+ dslhal_api_gatherStatistics(pIhw);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "Training Messages (R-Msgs 1-3)..\n");
++ seq_printf(m, "Training Messages (R-Msgs 1-3)..\n");
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg1Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsg1LdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg1Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsg1LdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsg1LdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg1Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg1Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg2Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg2Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg2Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg2Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg3Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg3Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg3Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg3Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
+- return len;
++ seq_printf(m, "\n");
++ return 0;
+ }
+
+-int tn7dsl_proc_dbg_rmsgs2(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_dbg_rmsgs1_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_dbg_rmsgs1, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++struct file_operations tn7dsl_proc_dbg_rmsgs1_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_dbg_rmsgs1_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++
++int tn7dsl_proc_dbg_rmsgs2(struct seq_file *m, void *data)
++{
+
+ int rc=0;
+
+ dslhal_api_gatherStatistics(pIhw);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "Training Messages (R-Msgs 4-5)..\n");
++ seq_printf(m, "Training Messages (R-Msgs 4-5)..\n");
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg4Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg4Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg4Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg4Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ len += sprintf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg5Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg5Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg5Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg5Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
+- return len;
++ seq_printf(m, "\n");
++ return 0;
+ }
+
+-int tn7dsl_proc_dbg_rmsgs3(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_dbg_rmsgs2_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_dbg_rmsgs2, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++struct file_operations _fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_dbg_rmsgs2_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++int tn7dsl_proc_dbg_rmsgs3(struct seq_file *m, void *data)
++{
+
+ int rc=0;
+
+ dslhal_api_gatherStatistics(pIhw);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "Training Messages (R-Msgs 6-7)..\n");
++ seq_printf(m, "Training Messages (R-Msgs 6-7)..\n");
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg6Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg6Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg6Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg6Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg7Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg7Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg7Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg7Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+- return len;
++ return 0;
+ }
+
+-int tn7dsl_proc_dbg_rmsgs4(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_dbg_rmsgs3_open(struct inode *inode, struct file *file)
+ {
++ return single_open(file, tn7dsl_proc_dbg_rmsgs3, PDE_DATA(inode));
++}
+
+- int len = 0;
+- int limit = count - 80;
++struct file_operations tn7dsl_proc_dbg_rmsgs3_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_dbg_rmsgs3_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++int tn7dsl_proc_dbg_rmsgs4(struct seq_file *m, void *data)
++{
+
+ int rc=0;
+
+ dslhal_api_gatherStatistics(pIhw);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "Training Messages (R-Msgs 8-9)..\n");
++ seq_printf(m, "Training Messages (R-Msgs 8-9)..\n");
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg8Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg8Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg8Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg8Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nADSL2 DELT R-Msg9Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
++ seq_printf(m, "\nADSL2 DELT R-Msg9Ld \t Message Length:%d\n",pIhw->adsl2DiagnosticMessages.rMsgxLdLen);
+ for(rc=0;rc<pIhw->adsl2DiagnosticMessages.rMsgxLdLen;rc++)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg9Ld[rc]);
++ seq_printf(m, " %02x",(unsigned char)pIhw->adsl2DiagnosticMessages.rMsg9Ld[rc]);
+ if(rc!=0 && (rc%16==0))
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+- return len;
++ return 0;
+ }
++
++static int tn7dsl_proc_dbg_rmsgs4_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_dbg_rmsgs4, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_dbg_rmsgs4_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_dbg_rmsgs4_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ //UR8_MERGE_END CQ10682*
+ #endif //ADV_DIAG_STATS
+
+-int tn7dsl_proc_stats(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_stats(struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- int limit = count - 80;
+ int F4count, F5count;
+ unsigned int maxRate=0;
+ unsigned int us_maxRate=0;
+@@ -1424,80 +1446,58 @@ int tn7dsl_proc_stats(char* buf, char **
+ //UR8_MERGE_START CQ10700 Manjula K
+ struct atm_dev *dev;
+ Tn7AtmPrivate *priv;
+- dev = (struct atm_dev *)data;
++ int offset[2] = { 32, 0 };
++ unsigned int usBitswap, dsBitswap;
++ dev = (struct atm_dev *)m->private;
+ priv = (Tn7AtmPrivate *)dev->dev_data;
+ //UR8_MERGE_END CQ10700
+
++
+ /*
+ * Read Ax5 Stats
+ */
+
+ dslhal_api_gatherStatistics(pIhw);
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 DSL Modem Statistics:\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "--------------------------------\n");
++ seq_printf(m, "\nAR7 DSL Modem Statistics:\n");
++ seq_printf(m, "--------------------------------\n");
+ /*
+ * us and ds Connection Rates
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "[DSL Modem Stats]\n");
++ seq_printf(m, "[DSL Modem Stats]\n");
+
+
+- if(len<=limit)
++ if(pIhw->lConnected != 1)
+ {
+- if(pIhw->lConnected != 1)
+- {
+- pIhw->AppData.USConRate = 0;
+- pIhw->AppData.DSConRate = 0;
+- }
+- len +=
+- sprintf (buf + len,
+- "\tUS Connection Rate:\t%u\tDS Connection Rate:\t%u\n",
+- (unsigned int)pIhw->AppData.USConRate,
+- (unsigned int)pIhw->AppData.DSConRate );
++ pIhw->AppData.USConRate = 0;
++ pIhw->AppData.DSConRate = 0;
+ }
+- if(len<=limit)
++ seq_printf (m,
++ "\tUS Connection Rate:\t%u\tDS Connection Rate:\t%u\n",
++ (unsigned int)pIhw->AppData.USConRate,
++ (unsigned int)pIhw->AppData.DSConRate );
+ // UR8_MERGE_START CQ11054 Jack Zhang
+- {
+- if (dslhal_api_getHighPrecision())
+- {
+- len +=
+- sprintf (buf + len, "\tDS Line Attenuation:\t%u.%u\tDS Margin:\t\t%d.%u\n",
++ if (dslhal_api_getHighPrecision())
++ seq_printf (m, "\tDS Line Attenuation:\t%u.%u\tDS Margin:\t\t%d.%u\n",
+ gInt(pIhw->AppData.dsLineAttn), gDot1(pIhw->AppData.dsLineAttn),
+ gInt(pIhw->AppData.dsMargin), gDot1(pIhw->AppData.dsMargin));
+- }
+- else{
+- len +=
+- sprintf (buf + len, "\tDS Line Attenuation:\t%u\tDS Margin:\t\t%u\n",
++ else
++ seq_printf (m, "\tDS Line Attenuation:\t%u\tDS Margin:\t\t%u\n",
+ (unsigned int)pIhw->AppData.dsLineAttn/2,
+ (unsigned int)pIhw->AppData.dsMargin/2 );
+- }
+- }
+ // UR8_MERGE_END CQ11054*
+
+- if(len<=limit)
+ // UR8_MERGE_START CQ11054 Jack Zhang
+- {
+- if (dslhal_api_getHighPrecision())
+- {
+- len +=
+- sprintf (buf + len, "\tUS Line Attenuation:\t%u.%u\tUS Margin:\t\t%d.%u\n",
++ if (dslhal_api_getHighPrecision())
++ seq_printf (m, "\tUS Line Attenuation:\t%u.%u\tUS Margin:\t\t%d.%u\n",
+ gInt(pIhw->AppData.usLineAttn), gDot1(pIhw->AppData.usLineAttn),
+ gInt(pIhw->AppData.usMargin), gDot1(pIhw->AppData.usMargin));
+- }
+- else
+- {
+- len +=
+- sprintf (buf + len, "\tUS Line Attenuation:\t%u\tUS Margin:\t\t%u\n",
++ else
++ seq_printf (m, "\tUS Line Attenuation:\t%u\tUS Margin:\t\t%u\n",
+ (unsigned int)pIhw->AppData.usLineAttn/2,
+ (unsigned int)pIhw->AppData.usMargin );
+- }
+- }
+ // UR8_MERGE_END CQ11054*
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\tUS Payload :\t\t%u\tDS Payload:\t\t%u\n",
++ seq_printf(m, "\tUS Payload :\t\t%u\tDS Payload:\t\t%u\n",
+ ((unsigned int) pIhw->AppData.usAtm_count[0] +
+ (unsigned int) pIhw->AppData.usAtm_count[1]) * 48,
+ ((unsigned int) pIhw->AppData.dsGood_count[0] +
+@@ -1505,9 +1505,7 @@ int tn7dsl_proc_stats(char* buf, char **
+ /*
+ * Superframe Count
+ */
+- if(len<=limit)
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "\tUS Superframe Cnt :\t%u\tDS Superframe Cnt:\t%u\n",
+ (unsigned int)pIhw->AppData.usSuperFrmCnt,
+ (unsigned int)pIhw->AppData.dsSuperFrmCnt );
+@@ -1515,59 +1513,45 @@ int tn7dsl_proc_stats(char* buf, char **
+ /*
+ * US and DS power
+ */
+- if(len<=limit)
++ if(pIhw->AppData.bState < 5)
+ {
+- if(pIhw->AppData.bState < 5)
+- {
+- pIhw->AppData.usTxPower = 0;
+- pIhw->AppData.dsTxPower = 0;
+- }
+- len +=
+- sprintf (buf + len,
++ pIhw->AppData.usTxPower = 0;
++ pIhw->AppData.dsTxPower = 0;
++ }
++ seq_printf (m,
+ // UR8_MERGE_START - CQ11579 - Jeremy #1
+ "\tUS Transmit Power :\t%d\tDS Transmit Power:\t%d\n",
+ pIhw->AppData.usTxPower/256,
+ pIhw->AppData.dsTxPower/256 );
+ // UR8_MERGE_END - CQ11579
+- }
+ /*
+ * DSL Stats Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\tLOS errors:\t\t%u\tSEF errors:\t\t%u\n",
++ seq_printf(m, "\tLOS errors:\t\t%u\tSEF errors:\t\t%u\n",
+ (unsigned int)pIhw->AppData.LOS_errors,
+ (unsigned int)pIhw->AppData.SEF_errors );
+
+ //UR8_MERGE_START Report_SES Manjula K
+ //CQ10369
+- if(len<=limit)
+- len += sprintf(buf+len, "\tErrored Seconds:\t%u\tSeverely Err Secs:\t%u\n",
++ seq_printf(m, "\tErrored Seconds:\t%u\tSeverely Err Secs:\t%u\n",
+ (unsigned int)pIhw->AppData.erroredSeconds,
+ (unsigned int)pIhw->AppData.severelyerrsecs );
+ //UR8_MERGE_END Report_SES
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\tFrame mode:\t\t%u\tMax Frame mode:\t\t%u\n",
++ seq_printf(m, "\tFrame mode:\t\t%u\tMax Frame mode:\t\t%u\n",
+ (unsigned int)pIhw->AppData.FrmMode,
+ (unsigned int)pIhw->AppData.MaxFrmMode );
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tTrained Path:\t\t%u\tUS Peak Cell Rate:\t%u\n",
++ seq_printf (m, "\tTrained Path:\t\t%u\tUS Peak Cell Rate:\t%u\n",
+ (unsigned int)pIhw->AppData.TrainedPath,
+ (unsigned int)pIhw->AppData.USConRate*1000/8/53 );
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tTrained Mode:\t\t%u\tSelected Mode:\t\t%u\n",
++ seq_printf (m, "\tTrained Mode:\t\t%u\tSelected Mode:\t\t%u\n",
+ (unsigned int) pIhw->AppData.TrainedMode,
+ (unsigned int) pIhw->AppData.StdMode);
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tATUC Vendor Code:\t%X\tATUC Revision:\t%u\n",
++ seq_printf (m, "\tATUC Vendor Code:\t%X\tATUC Revision:\t%u\n",
+ (unsigned int) pIhw->AppData.atucVendorId,
+ pIhw->AppData.atucRevisionNum);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tHybrid Selected:\t%u\tTrellis:\t\t%u\n",
++ seq_printf(m, "\tHybrid Selected:\t%u\tTrellis:\t\t%u\n",
+ (unsigned int)pIhw->AppData.currentHybridNum, trellis);
+
+ //@Added Maximum attainable bit rate information. 05-14-2004
+@@ -1581,12 +1565,12 @@ int tn7dsl_proc_stats(char* buf, char **
+ }
+ else
+ {
+- int offset[2] = {5, 1};
++ int dspOffset[2] = { 5, 1 };
+ unsigned char rMsgsRA[12];
+ int numPayloadBytes = 0;
+
+ dslhal_api_dspInterfaceRead (pIhw, (unsigned int) pIhw->pmainAddr, 2,
+- (unsigned int *) &offset,
++ (unsigned int *) &dspOffset,
+ (unsigned char *) &rMsgsRA[0], 12);
+
+ maxRate = (unsigned int)pIhw->AppData.DSConRate;
+@@ -1602,294 +1586,223 @@ int tn7dsl_proc_stats(char* buf, char **
+ }
+ }
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "\tShowtime Count:\t\t%u\tDS Max Attainable Bit Rate: %u kbps\n",
+ (unsigned int)pIhw->AppData.showtimeCount, maxRate);
+
+- if(len<=limit)
+- {
+- int offset[2] = {32, 0};
+- unsigned int usBitswap, dsBitswap;
+-
+- tn7dsl_generic_read(2, (unsigned int *)&offset);
+- dsBitswap = dslReg & dslhal_support_byteSwap32(0x000000ff);
++ tn7dsl_generic_read(2, (unsigned int *)&offset);
++ dsBitswap = dslReg & dslhal_support_byteSwap32(0x000000ff);
+
+- offset[0] = 33;
+- tn7dsl_generic_read(2, (unsigned int *)&offset);
+- usBitswap = dslReg & dslhal_support_byteSwap32(0x000000ff);
++ offset[0] = 33;
++ tn7dsl_generic_read(2, (unsigned int *)&offset);
++ usBitswap = dslReg & dslhal_support_byteSwap32(0x000000ff);
+
+ // UR8_MERGE_START - CQ11579 - Jeremy
+- if((pIhw->AppData.dsl_modulation > 5) && (pIhw->AppData.dsl_modulation != 128))
++ if((pIhw->AppData.dsl_modulation > 5) && (pIhw->AppData.dsl_modulation != 128))
+ // UR8_MERGE_END - CQ11579 - Jeremy
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "\tBitSwap:\t\t%u\tUS Max Attainable Bit Rate: %u bps\n",
+ (unsigned int)(usBitswap && dsBitswap), us_maxRate);
+- else
+- len +=
+- sprintf (buf + len,
++ else
++ seq_printf (m,
+ "\tBitSwap:\t\t%u\tUS Max Attainable Bit Rate:\tn/a\n",
+ (unsigned int)(usBitswap && dsBitswap));
+- }
+
+ #if 1 // TR69
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tAnnex: \t\t\t%s\tpsd_mask_qualifier: 0x%04x\n",
++ seq_printf (m, "\tAnnex: \t\t\t%s\tpsd_mask_qualifier: 0x%04x\n",
+ tn7dsl_AnnexFromNum(pIhw->AppData.annex_selected),
+ pIhw->AppData.psd_mask_qualifier);
+
+ // UR8_MERGE_START CQ10979 Jack Zhang
+ // UR8_MERGE_START CQ10978 Jack Zhang
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tPower Management Status: L%d\tDS HLINSC: %d\n",
++ seq_printf (m, "\tPower Management Status: L%d\tDS HLINSC: %d\n",
+ pIhw->AppData.pwrStatus, pIhw->AppData.dsHLINSC);
+ // UR8_MERGE_END CQ10978*
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tUS ACTPSD: \t\t%d\tDS ACTPSD: %d\n",
++ seq_printf (m, "\tUS ACTPSD: \t\t%d\tDS ACTPSD: %d\n",
+ pIhw->AppData.usACTPSD, pIhw->AppData.dsACTPSD);
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tTotal init. errors: \t%d\tTotal init. timeouts: %d\n",
++ seq_printf (m, "\tTotal init. errors: \t%d\tTotal init. timeouts: %d\n",
+ pIhw->AppData.totalInitErrs, pIhw->AppData.totalInitTOs);
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tShowtime init. errors: \t%d\tShowtime init. timeouts: %d\n",
++ seq_printf (m, "\tShowtime init. errors: \t%d\tShowtime init. timeouts: %d\n",
+ pIhw->AppData.showtimeInitErrs, pIhw->AppData.showtimeInitTOs);
+
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tLast showtime init. errors: %d\tLast showtime init. timeouts: %d\n",
++ seq_printf (m, "\tLast showtime init. errors: %d\tLast showtime init. timeouts: %d\n",
+ pIhw->AppData.lastshowInitErrs, pIhw->AppData.lastshowInitTOs);
+ // UR8_MERGE_END CQ10979*
+
+- if (len<=limit)
+- {
+- len += sprintf(buf+len,"\tATUC ghsVid: ");
+- for (i=0; i<8; i++)
+- len+= sprintf(buf+len, " %02x", pIhw->AppData.ghsATUCVendorId[i]);
+- }
++ seq_printf(m,"\tATUC ghsVid: ");
++ for (i=0; i<8; i++)
++ seq_printf(m, " %02x", pIhw->AppData.ghsATUCVendorId[i]);
+
+- if (len<=limit)
+- {
+- len += sprintf (buf + len, "\n");
+- }
++ seq_printf (m, "\n");
+
+- if (len <= limit)
+- {
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "\tT1413Vid: %02x %02x\t\tT1413Rev: %02x\t\tVendorRev: %02x\n",
+ pIhw->AppData.t1413ATUC.VendorId[0],
+ pIhw->AppData.t1413ATUC.VendorId[1],
+ pIhw->AppData.t1413ATUC.t1413Revision,
+ pIhw->AppData.t1413ATUC.VendorRevision);
+- }
+
+- if (len<=limit)
+- {
+- len += sprintf(buf+len,"\tATUR ghsVid: ");
+- for (i=0; i<8; i++)
+- len+= sprintf(buf+len, " %02x", pIhw->AppData.ghsATURVendorId[i]);
+- }
++ seq_printf(m,"\tATUR ghsVid: ");
++ for (i=0; i<8; i++)
++ seq_printf(m, " %02x", pIhw->AppData.ghsATURVendorId[i]);
+
+- if (len<=limit)
+- {
+- len += sprintf (buf + len, "\n");
+- }
++ seq_printf (m, "\n");
+
+- if (len <= limit)
+- {
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "\tT1413Vid: %02x %02x\tT1413Rev: %02x\tVendorRev: %02x\n",
+ pIhw->AppData.t1413ATUR.VendorId[0],
+ pIhw->AppData.t1413ATUR.VendorId[1],
+ pIhw->AppData.t1413ATUR.t1413Revision,
+ pIhw->AppData.t1413ATUR.VendorRevision);
+- }
+
+ #ifdef AR7_EFM
+- if (len <= limit)
+- {
+- len += sprintf(buf + len, "\tTC Mode: %s\n",
++ seq_printf(m, "\tTC Mode: %s\n",
+ (priv->curr_TC_mode == TC_MODE_PTM) ? "PTM" : "ATM");
+- }
+ #endif
+
+ #endif
+ /*
+ * Upstream Interleaved Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Upstream (TX) Interleave path]\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
++ seq_printf(m, "\n\t[Upstream (TX) Interleave path]\n");
++ seq_printf(m, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
+ (unsigned int)pIhw->AppData.usICRC_errors,
+ (unsigned int)pIhw->AppData.usIFEC_errors,
+ (unsigned int)pIhw->AppData.usINCD_error);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n",
++ seq_printf(m, "\tLCD: \t%u\tHEC: \t%u\n",
+ (unsigned int)pIhw->AppData.usILCD_errors,
+ (unsigned int)pIhw->AppData.usIHEC_errors);
+ /*
+ * Downstream Interleaved Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Downstream (RX) Interleave path]\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
++ seq_printf(m, "\n\t[Downstream (RX) Interleave path]\n");
++ seq_printf(m, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
+ (unsigned int)pIhw->AppData.dsICRC_errors,
+ (unsigned int)pIhw->AppData.dsIFEC_errors,
+ (unsigned int)pIhw->AppData.dsINCD_error);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n",
++ seq_printf(m, "\tLCD: \t%u\tHEC: \t%u\n",
+ (unsigned int)pIhw->AppData.dsILCD_errors,
+ (unsigned int)pIhw->AppData.dsIHEC_errors);
+ /*
+ * Upstream Fast Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Upstream (TX) Fast path]\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
++ seq_printf(m, "\n\t[Upstream (TX) Fast path]\n");
++ seq_printf(m, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
+ (unsigned int)pIhw->AppData.usFCRC_errors,
+ (unsigned int)pIhw->AppData.usFFEC_errors,
+ (unsigned int)pIhw->AppData.usFNCD_error);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n",
++ seq_printf(m, "\tLCD: \t%u\tHEC: \t%u\n",
+ (unsigned int)pIhw->AppData.usFLCD_errors,
+ (unsigned int)pIhw->AppData.usFHEC_errors);
+ /*
+ * Downstream Fast Errors
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Downstream (RX) Fast path]\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
++ seq_printf(m, "\n\t[Downstream (RX) Fast path]\n");
++ seq_printf(m, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n",
+ (unsigned int)pIhw->AppData.dsFCRC_errors,
+ (unsigned int)pIhw->AppData.dsFFEC_errors,
+ (unsigned int)pIhw->AppData.dsFNCD_error);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n",
+- (unsigned int)pIhw->AppData.dsFLCD_errors,
+- (unsigned int)pIhw->AppData.dsFHEC_errors);
++ seq_printf(m, "\tLCD: \t%u\tHEC: \t%u\n",
++ (unsigned int)pIhw->AppData.dsFLCD_errors,
++ (unsigned int)pIhw->AppData.dsFHEC_errors);
+
+ /*
+ * ATM stats upstream
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n[ATM Stats]");
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Upstream/TX]\n");
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tGood Cell Cnt:\t%u\n\tIdle Cell Cnt:\t%u\n\n",
+- (unsigned int) pIhw->AppData.usAtm_count[0] +
+- (unsigned int) pIhw->AppData.usAtm_count[1],
+- (unsigned int) pIhw->AppData.usIdle_count[0] +
+- (unsigned int) pIhw->AppData.usIdle_count[1]);
++ seq_printf(m, "\n[ATM Stats]");
++ seq_printf(m, "\n\t[Upstream/TX]\n");
++ seq_printf (m, "\tGood Cell Cnt:\t%u\n\tIdle Cell Cnt:\t%u\n\n",
++ (unsigned int) pIhw->AppData.usAtm_count[0] +
++ (unsigned int) pIhw->AppData.usAtm_count[1],
++ (unsigned int) pIhw->AppData.usIdle_count[0] +
++ (unsigned int) pIhw->AppData.usIdle_count[1]);
+ //UR8_MERGE_START CQ10700 Manjula K
+- if (len <= limit)
+- len +=
+- sprintf (buf + len,
++ seq_printf (m,
+ "\tTx Packets Dropped Count:\t%lu\n\tTx Bad Packets Count:\t%lu\n",
+ priv->stats.tx_dropped, priv->stats.tx_errors);
+ //UR8_MERGE_END CQ10700
+ /*
+ * ATM stats downstream
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n\t[Downstream/RX)]\n");
+- if(len<=limit)
+- len +=
+- sprintf (buf + len,
+- "\tGood Cell Cnt:\t%u\n\tIdle Cell Cnt:\t%u\n\tBad Hec Cell Cnt:\t%u\n",
+- (unsigned int) pIhw->AppData.dsGood_count[0] +
+- (unsigned int) pIhw->AppData.dsGood_count[1],
+- (unsigned int) pIhw->AppData.dsIdle_count[0] +
+- (unsigned int) pIhw->AppData.dsIdle_count[1],
+- (unsigned int) pIhw->AppData.dsBadHec_count[0] +
+- (unsigned int) pIhw->AppData.dsBadHec_count[1]);
+- if(len<=limit)
+- len += sprintf(buf+len, "\tOverflow Dropped Cell Cnt:\t%u\n",
+- (unsigned int) pIhw->AppData.dsOVFDrop_count[0] +
+- (unsigned int) pIhw->AppData.dsOVFDrop_count[1]);
++ seq_printf(m, "\n\t[Downstream/RX)]\n");
++ seq_printf (m,
++ "\tGood Cell Cnt:\t%u\n\tIdle Cell Cnt:\t%u\n\tBad Hec Cell Cnt:\t%u\n",
++ (unsigned int) pIhw->AppData.dsGood_count[0] +
++ (unsigned int) pIhw->AppData.dsGood_count[1],
++ (unsigned int) pIhw->AppData.dsIdle_count[0] +
++ (unsigned int) pIhw->AppData.dsIdle_count[1],
++ (unsigned int) pIhw->AppData.dsBadHec_count[0] +
++ (unsigned int) pIhw->AppData.dsBadHec_count[1]);
++ seq_printf(m, "\tOverflow Dropped Cell Cnt:\t%u\n",
++ (unsigned int) pIhw->AppData.dsOVFDrop_count[0] +
++ (unsigned int) pIhw->AppData.dsOVFDrop_count[1]);
+
+ //UR8_MERGE_START CQ10700 Manjula K
+- if (len <= limit)
+- len +=
+- sprintf (buf + len,
+- "\tRx Packets Dropped Count:\t%lu\n\tRx Bad Packets Count:\t%lu\n\n",
+- priv->stats.rx_dropped, priv->stats.rx_errors);
++ seq_printf (m,
++ "\tRx Packets Dropped Count:\t%lu\n\tRx Bad Packets Count:\t%lu\n\n",
++ priv->stats.rx_dropped, priv->stats.rx_errors);
+ //UR8_MERGE_END CQ10700
+
+ tn7sar_get_stats(pIhw->pOsContext);
+- if(len<=limit)
+- len += sprintf(buf+len, "\n[SAR AAL5 Stats]\n");
+- if(len<=limit)
+- len += sprintf(buf+len, "\tTx PDU's:\t%u\n\tRx PDU's:\t%u\n",
+- sarStat.txPktCnt, sarStat.rxPktCnt);
+- if(len<=limit)
+- len +=
+- sprintf (buf + len, "\tTx Total Bytes:\t%u\n\tRx Total Bytes:\t%u\n",
+- sarStat.txBytes, sarStat.rxBytes);
+- if (len <= limit)
+- len +=
+- sprintf (buf + len,
+- "\tTx Total Error Counts:\t%u\n\tRx Total Error Counts:\t%u\n\n",
+- sarStat.txErrors, sarStat.rxErrors);
++ seq_printf(m, "\n[SAR AAL5 Stats]\n");
++ seq_printf(m, "\tTx PDU's:\t%u\n\tRx PDU's:\t%u\n",
++ sarStat.txPktCnt, sarStat.rxPktCnt);
++ seq_printf (m, "\tTx Total Bytes:\t%u\n\tRx Total Bytes:\t%u\n",
++ sarStat.txBytes, sarStat.rxBytes);
++ seq_printf (m,
++ "\tTx Total Error Counts:\t%u\n\tRx Total Error Counts:\t%u\n\n",
++ sarStat.txErrors, sarStat.rxErrors);
+
+ /*
+ * oam loopback info
+ */
+- if(len<=limit)
+- len += sprintf(buf+len, "\n[OAM Stats]\n");
++ seq_printf(m, "\n[OAM Stats]\n");
+
+ tn7sar_get_near_end_loopback_count(&F4count, &F5count);
+
+- if(len<=limit)
+- {
+- len +=
+- sprintf (buf + len,
+- "\tNear End F5 Loop Back Count:\t%u\n\tNear End F4 Loop Back Count:\t%u\n\tFar End F5 Loop Back Count:\t%u\n\tFar End F4 Loop Back Count:\t%u\n",
++ seq_printf (m,
++ "\tNear End F5 Loop Back Count:\t%u\n\tNear End F4 Loop Back Count:\t%u\n\tFar End F5 Loop Back Count:\t%u\n\tFar End F4 Loop Back Count:\t%u\n",
+ F5count, F4count, oamFarLBCount[0] + oamFarLBCount[2],
+ oamFarLBCount[1] + oamFarLBCount[3]);
+- }
+
+ #define USE_OAM_DROP_COUNT //CQ10273
+ //Read OAM ping responses count:
+ #ifdef USE_OAM_DROP_COUNT
+- if(len<=limit)
+- {
+- /* len +=
+- sprintf (buf + len,
+- "\tSAR OAM Retry in 0x%X cycles, Drop Count=%d\n",
+- tn7dsl_get_memory(0xa30085cc), tn7dsl_get_memory(0xa30085c4)); */
++/* seq_printf (m,
++ "\tSAR OAM Retry in 0x%X cycles, Drop Count=%d\n",
++ tn7dsl_get_memory(0xa30085cc), tn7dsl_get_memory(0xa30085c4)); */
+
+- len += sprintf (buf + len, "\tSAR OAM Ping Response Drop Count=%d\n",
+- tn7dsl_get_memory(0xa30085b0));
+- }
++ seq_printf (m, "\tSAR OAM Ping Response Drop Count=%d\n",
++ tn7dsl_get_memory(0xa30085b0));
+ #endif // USE_OAM_DROP_COUNT
+
+- return len;
++ return 0;
+ }
+
+-int tn7dsl_proc_modem(char* buf, char **start, off_t offset, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_stats_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_stats, PDE_DATA(inode));
++}
++
++int tn7dsl_proc_write_stats(struct file *fp, const char * buf, unsigned long count, void * data);
++
++struct file_operations tn7dsl_proc_stats_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_stats_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++ .write = tn7dsl_proc_write_stats,
++};
++
++static int tn7dsl_proc_modem(struct seq_file *m, void *data)
+ {
+ #ifdef AR7_EFM
+ extern int tn7efm_get_currTCmode(void);
+ #endif
+- int len = 0;
+- int limit = count - 80;
+ char *state;
+ int tag;
+
+@@ -1923,22 +1836,31 @@ extern int tn7efm_get_currTCmode(void);
+
+ if(pIhw->lConnected == 1)
+ state = "SHOWTIME";
+- if(len<=limit)
+- len += sprintf(buf+len,"%s\n",state);
+- if(len<=limit)
+- len += sprintf(buf+len, "%d\n", dslReg);
+- if(len<=limit)
+- len += sprintf(buf+len, "failTrains=%d\n", pIhw->AppData.trainFails);
++ seq_printf(m,"%s\n",state);
++ seq_printf(m, "%d\n", dslReg);
++ seq_printf(m, "failTrains=%d\n", pIhw->AppData.trainFails);
+
+ #ifdef AR7_EFM
+- if (len<=limit)
+- len += sprintf(buf+len, "TCMODE=%s\n",
+- tn7efm_get_currTCmode()== TC_MODE_PTM ? "EFM" : "ATM");
++ seq_printf(m, "TCMODE=%s\n",
++ tn7efm_get_currTCmode()== TC_MODE_PTM ? "EFM" : "ATM");
+ #endif
+
+- return len;
++ return 0;
++}
++
++static int tn7dsl_proc_modem_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_modem, PDE_DATA(inode));
+ }
+
++struct file_operations tn7dsl_proc_modem_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_modem_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ /**********************************************************************
+ ** *
+ ** tn7dsl_hdlc_update_crc() -- Calculate CRC *
+@@ -2203,11 +2125,8 @@ static int tn7dsl_hdlc_rx_process(unsign
+ return(ret);
+ }
+
+-int tn7dsl_proc_eoc (char *buf, char **start, off_t OffSet, int count,
+- int *eof, void *data)
++static int tn7dsl_proc_eoc (struct seq_file *m, void *data)
+ {
+- int len = 0;
+- int limit = count - 80;
+ int offset[2] = {34, 0}; // point to buffer parameter data structure
+ clearEocParm_t peoc;
+
+@@ -2216,62 +2135,49 @@ int tn7dsl_proc_eoc (char *buf, char **s
+ (unsigned char *) &peoc,
+ sizeof (clearEocParm_t));
+
+- if (len <= limit)
+- len += sprintf(buf+len, "\nClear EOC Channel:\n\n");
+- if (len <= limit)
+- len += sprintf(buf+len, " Enabled:\t%d\n", dslhal_support_byteSwap32(peoc.clearEocEnabled));
+- if (len <= limit)
+- len += sprintf(buf+len, " TxBuf[0]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[0]));
+- if (len <= limit)
+- len += sprintf(buf+len, " TxBuf[1]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[1]));
+- if (len <= limit)
+- len += sprintf(buf+len, " TxBuf[2]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[2]));
+- if (len <= limit)
+- len += sprintf(buf+len, " TxBuf[3]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[3]));
+- if (len <= limit)
+- len += sprintf(buf+len, " RxBuf[0]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[0]));
+- if (len <= limit)
+- len += sprintf(buf+len, " RxBuf[1]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[1]));
+- if (len <= limit)
+- len += sprintf(buf+len, " RxBuf[2]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[2]));
+- if (len <= limit)
+- len += sprintf(buf+len, " RxBuf[3]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[3]));
+- if (len <= limit)
+- len += sprintf(buf+len, " txRdIndex:\t%d\n", dslhal_support_byteSwap32(peoc.txRdIndex));
+- if (len <= limit)
+- len += sprintf(buf+len, " txWrIndex:\t%d\n", dslhal_support_byteSwap32(peoc.txWrIndex));
+- if (len <= limit)
+- len += sprintf(buf+len, " rxRdIndex:\t%d\n", dslhal_support_byteSwap32(peoc.rxRdIndex));
+- if (len <= limit)
+- len += sprintf(buf+len, " rxWrIndex:\t%d\n\n", dslhal_support_byteSwap32(peoc.rxWrIndex));
+- if (len <= limit)
+- len += sprintf(buf+len, " TotalTxPkts:\t%d\n", EocTxTotalPackets);
+- if (len <= limit)
+- len += sprintf(buf+len, " TotalRxPkts:\t%d\n", EocRxTotalPackets);
+- if (len <= limit)
+- len += sprintf(buf+len, " TotalTxBytes:\t%d\n", EocTxTotalBytes);
+- if (len <= limit)
+- len += sprintf(buf+len, " TotalRxBytes:\t%d\n\n", EocRxTotalBytes);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrBufFull:\t%d\n", ErrEocBufFull);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrBufIndx:\t%d\n", ErrEocBufIndex);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrBufMax:\t%d\n", ErrEocBufMax);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrMsgMax:\t%d\n", ErrEocMsgOversized);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrTxHDLC:\t%d\n", ErrEocTxHdlcCRC);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrRxHDLC:\t%d\n", ErrEocRxHdlcCRC);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrRxSnmp:\t%d\n", ErrEocRxHdlcFraming);
+- if (len <= limit)
+- len += sprintf(buf+len, " ErrRxPush:\t%d\n\n", ErrEocRxPush);
++ seq_printf(m, "\nClear EOC Channel:\n\n");
++ seq_printf(m, " Enabled:\t%d\n", dslhal_support_byteSwap32(peoc.clearEocEnabled));
++ seq_printf(m, " TxBuf[0]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[0]));
++ seq_printf(m, " TxBuf[1]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[1]));
++ seq_printf(m, " TxBuf[2]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[2]));
++ seq_printf(m, " TxBuf[3]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pTxBufDesc[3]));
++ seq_printf(m, " RxBuf[0]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[0]));
++ seq_printf(m, " RxBuf[1]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[1]));
++ seq_printf(m, " RxBuf[2]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[2]));
++ seq_printf(m, " RxBuf[3]:\t0x%08x\n", dslhal_support_byteSwap32((unsigned int)peoc.pRxBufDesc[3]));
++ seq_printf(m, " txRdIndex:\t%d\n", dslhal_support_byteSwap32(peoc.txRdIndex));
++ seq_printf(m, " txWrIndex:\t%d\n", dslhal_support_byteSwap32(peoc.txWrIndex));
++ seq_printf(m, " rxRdIndex:\t%d\n", dslhal_support_byteSwap32(peoc.rxRdIndex));
++ seq_printf(m, " rxWrIndex:\t%d\n\n", dslhal_support_byteSwap32(peoc.rxWrIndex));
++ seq_printf(m, " TotalTxPkts:\t%d\n", EocTxTotalPackets);
++ seq_printf(m, " TotalRxPkts:\t%d\n", EocRxTotalPackets);
++ seq_printf(m, " TotalTxBytes:\t%d\n", EocTxTotalBytes);
++ seq_printf(m, " TotalRxBytes:\t%d\n\n", EocRxTotalBytes);
++ seq_printf(m, " ErrBufFull:\t%d\n", ErrEocBufFull);
++ seq_printf(m, " ErrBufIndx:\t%d\n", ErrEocBufIndex);
++ seq_printf(m, " ErrBufMax:\t%d\n", ErrEocBufMax);
++ seq_printf(m, " ErrMsgMax:\t%d\n", ErrEocMsgOversized);
++ seq_printf(m, " ErrTxHDLC:\t%d\n", ErrEocTxHdlcCRC);
++ seq_printf(m, " ErrRxHDLC:\t%d\n", ErrEocRxHdlcCRC);
++ seq_printf(m, " ErrRxSnmp:\t%d\n", ErrEocRxHdlcFraming);
++ seq_printf(m, " ErrRxPush:\t%d\n\n", ErrEocRxPush);
+
+- return len;
++ return 0;
++}
++
++static int tn7dsl_proc_eoc_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_eoc, PDE_DATA(inode));
+ }
+
++struct file_operations tn7dsl_proc_eoc_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_eoc_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ int tn7dsl_clear_eoc_setup(void)
+ {
+ int i;
+@@ -4624,14 +4530,10 @@ int tn7dsl_proc_write_stats (struct file
+ }
+
+
+-int tn7dsl_proc_train_mode_export (char *buf, char **start, off_t offset,
+- int count, int *eof, void *data)
++static int tn7dsl_proc_train_mode_export (struct seq_file *m, void *data)
+ {
+
+- int len = 0;
+- char *cp = buf + offset;
+ int i = 0;
+- static int ctr = 0;
+
+ typedef struct
+ {
+@@ -4712,197 +4614,185 @@ int tn7dsl_proc_train_mode_export (char
+ }
+
+
+- if(len <= count)
++ for (i = 0; (i < num_entries) ; i++)
+ {
+- for (i = ctr; ((i < num_entries)&& (len <= count)) ; i++)
+- {
+- /*
+- * Write the current string only if we can fit it into the buffer
+- */
+- if((strlen(dsl_modes[i].mode_name) + 6 + len) <= count)
+- {
+- len += snprintf(cp+len, (count - len), "%s\t\t\t%#x\n",
+- dsl_modes[i].mode_name, dsl_modes[i].mode_value);
+- }
+- else
+- break;
+- }
++ seq_printf(m, "%s\t\t\t%#x\n",
++ dsl_modes[i].mode_name, dsl_modes[i].mode_value);
+ }
+
+- /*
+- * Data was completely written
+- */
+- if (i >= num_entries)
+- {
+- /*
+- * We are done with this
+- */
+- *eof = 1;
+- ctr = 0;
+- }
+- else
+- {
+- /*
+- * We have not been able to write the complete data, and we have to nul
+- * terminate the buffer.
+- */
+- *(cp + len) = '\0';
+-
+- /*
+- * Save the value of the counter for the next read for the rest of the
+- * data.
+- */
+- ctr = i;
+- }
+-
+- return len;
++ return 0;
+ }
+
+-#ifndef NO_ADV_STATS
+-int tn7dsl_proc_SNRpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_train_mode_export_open(struct inode *inode, struct file *file)
+ {
+- int len = 0;
+-
++ return single_open(file, tn7dsl_proc_train_mode_export, PDE_DATA(inode));
++}
+
++struct file_operations tn7dsl_proc_train_mode_export_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_train_mode_export_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
+
+- int limit = count - 80;
++#ifndef NO_ADV_STATS
++int tn7dsl_proc_SNRpsds(struct seq_file *m, void *data)
++{
+ int i;
+ unsigned char SNRpsds[512];
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 SNRpsds:");
++ seq_printf(m, "\nAR7 SNRpsds:");
+
+ if (dslhal_api_getSNRpsds(pIhw, SNRpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getSNRpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+
+ for (i=0; i<pIhw->AppData.max_ds_tones; i++)
+ {
+ if (!(i%16))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "%d ", (unsigned char)SNRpsds[i]);
++ seq_printf(m, "%d ", (unsigned char)SNRpsds[i]);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+
+
+- return len;
++ return 0;
++}
++
++static int tn7dsl_proc_SNRpsds_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_SNRpsds, PDE_DATA(inode));
+ }
+
++struct file_operations tn7dsl_proc_SNRpsds_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_SNRpsds_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #endif
+
+ #ifndef NO_ADV_STATS
+-int tn7dsl_proc_QLNpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_QLNpsds(struct seq_file *m, void *data)
+ {
+- int len = 0;
+-
+- int limit = count - 80;
+ unsigned char QLNpsds[512];
+ int i;
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 QLNpsds:");
++ seq_printf(m, "\nAR7 QLNpsds:");
+
+ // call API instead of access internal buf directly
+ if (dslhal_api_getQLNpsds(pIhw, QLNpsds, 0))
+ {
+ dgprintf(4, "dslhal_api_getQLNpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+
+ for (i=0; i<pIhw->AppData.max_ds_tones; i++)
+ {
+ if (!(i%16))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "%d ", (unsigned char)QLNpsds[i]);
++ seq_printf(m, "%d ", (unsigned char)QLNpsds[i]);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+
+- return len;
++ return 0;
+ }
++
++static int tn7dsl_proc_QLNpsds_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_QLNpsds, PDE_DATA(inode));
++}
++
++struct file_operations tn7dsl_proc_QLNpsds_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_QLNpsds_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #endif
+
+ // UR8_MERGE_START CQ10979 Jack Zhang
+ #ifdef TR69_HLIN_IN
+ #ifndef NO_ADV_STATS
+-int tn7dsl_proc_HLINpsds(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_HLINpsds(struct seq_file *m, void *data)
+ {
+- int len = 0;
+-
+- int limit = count - 80;
+ short HLINpsds[2*512];
+ int i;
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 HLINpsds:");
++ seq_printf(m, "\nAR7 HLINpsds:");
+
+ // call API instead of access internal buf directly
+ if (dslhal_api_getHLINpsds(pIhw, (unsigned char *)HLINpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getHLINpsds failed!\n");
+- return len;
++ return -EIO;
+ }
+
+ for (i=0; i<pIhw->AppData.max_ds_tones; i++)
+ {
+ if (!(i%8))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "(%d,%d) ", HLINpsds[2*i], HLINpsds[2*i+1]);
++ seq_printf(m, "(%d,%d) ", HLINpsds[2*i], HLINpsds[2*i+1]);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+
+- return len;
++ return 0;
+ }
+
+-static int tn7dsl_proc_HLINpsdsIndx(char* buf, char **start, off_t offset, int count,int *eof, void *data, int indx)
++static int tn7dsl_proc_HLINpsds_open(struct inode *inode, struct file *file)
+ {
+- int len = 0;
++ return single_open(file, tn7dsl_proc_HLINpsds, PDE_DATA(inode));
++}
+
+- int limit = count - 80;
++struct file_operations tn7dsl_proc_HLINpsds_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_HLINpsds_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++static int tn7dsl_proc_HLINpsdsIndx(struct seq_file *m, void *data, int indx)
++{
+ short HLINpsds[2*512];
+ int i;
+ int start=0, dim=128;
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 HLINpsds: (section %d)", indx);
++ seq_printf(m, "\nAR7 HLINpsds: (section %d)", indx);
+
+ if((indx > 2) && (pIhw->AppData.max_ds_tones <= 256))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n[End of data]");
+- return len;
++ seq_printf(m, "\n[End of data]");
++ return 0;
+ }
+
+ // call API instead of access internal buf directly
+ if (dslhal_api_getHLINpsds(pIhw, (unsigned char *)HLINpsds, 1))
+ {
+ dgprintf(4, "dslhal_api_getHLINpsds failed!\n");
+- return len;
++ return -1;
+ }
+
+ start = (indx -1) * 128;
+@@ -4911,39 +4801,89 @@ static int tn7dsl_proc_HLINpsdsIndx(char
+ {
+ if (!(i%8))
+ {
+- if(len <=limit)
+- len += sprintf(buf+len, "\n%d: ", i);
++ seq_printf(m, "\n%d: ", i);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "(%d,%d) ", HLINpsds[2*i], HLINpsds[2*i+1]);
++ seq_printf(m, "(%d,%d) ", HLINpsds[2*i], HLINpsds[2*i+1]);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+- return len;
++ return 0;
++}
++
++static int tn7dsl_proc_HLINpsds1(struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_HLINpsdsIndx(m, data, 1);
++}
++
++static int tn7dsl_proc_HLINpsds2(struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_HLINpsdsIndx(m, data, 2);
++}
++
++static int tn7dsl_proc_HLINpsds3(struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_HLINpsdsIndx(m, data, 3);
++}
++
++static int tn7dsl_proc_HLINpsds4(struct seq_file *m, void *data)
++{
++ return tn7dsl_proc_HLINpsdsIndx(m, data, 4);
+ }
+
+-int tn7dsl_proc_HLINpsds1(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_HLINpsds1_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_HLINpsdsIndx(buf, start, offset, count,eof, data, 1);
++ return single_open(file, tn7dsl_proc_HLINpsds1, PDE_DATA(inode));
+ }
+
+-int tn7dsl_proc_HLINpsds2(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_HLINpsds2_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_HLINpsdsIndx(buf, start, offset, count,eof, data, 2);
++ return single_open(file, tn7dsl_proc_HLINpsds2, PDE_DATA(inode));
+ }
+
+-int tn7dsl_proc_HLINpsds3(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_HLINpsds3_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_HLINpsdsIndx(buf, start, offset, count,eof, data, 3);
++ return single_open(file, tn7dsl_proc_HLINpsds3, PDE_DATA(inode));
+ }
+
+-int tn7dsl_proc_HLINpsds4(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_HLINpsds4_open(struct inode *inode, struct file *file)
+ {
+- return tn7dsl_proc_HLINpsdsIndx(buf, start, offset, count,eof, data, 4);
++ return single_open(file, tn7dsl_proc_HLINpsds4, PDE_DATA(inode));
+ }
++
++struct file_operations tn7dsl_proc_HLINpsds1_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_HLINpsds1_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++struct file_operations tn7dsl_proc_HLINpsds2_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_HLINpsds2_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++struct file_operations tn7dsl_proc_HLINpsds3_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_HLINpsds3_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++struct file_operations tn7dsl_proc_HLINpsds4_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_HLINpsds4_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #endif
+ #endif //TR69_HLIN_IN
+ // UR8_MERGE_END CQ10979*
+@@ -4951,64 +4891,48 @@ int tn7dsl_proc_HLINpsds4(char* buf, cha
+ // * UR8_MERGE_START CQ11057 Jack Zhang
+ #ifdef TR69_PMD_IN
+ #ifndef NO_ADV_STATS
+-int tn7dsl_proc_PMDus(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7dsl_proc_PMDus(struct seq_file *m, void *data)
+ {
+- int len = 0;
+-
+- int limit = count - 80;
+ int i;
+ CoPMDTestParams_t co_pmdtest_params;
+
+- if(len<=limit)
+- len += sprintf(buf+len, "\nAR7 US PMD Test:\n");
++ seq_printf(m, "\nAR7 US PMD Test:\n");
+
+ // call API instead of access internal buf directly
+ if (dslhal_api_getPMDTestus(pIhw, &co_pmdtest_params, 0) != DSLHAL_ERROR_NO_ERRORS)
+ {
+ dgprintf(4, "dslhal_api_getPMDTestus failed!\n");
+- return len;
++ return -EIO;
+ }
+
+- if(len<=limit)
+- len += sprintf(buf+len, "LATN=%d\n", co_pmdtest_params.co_latn);
++ seq_printf(m, "LATN=%d\n", co_pmdtest_params.co_latn);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "SATN=%d\n", co_pmdtest_params.co_satn);
++ seq_printf(m, "SATN=%d\n", co_pmdtest_params.co_satn);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "SNRM=%d\n", co_pmdtest_params.usMargin);
++ seq_printf(m, "SNRM=%d\n", co_pmdtest_params.usMargin);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "attndr=%ld\n", co_pmdtest_params.co_attndr);
++ seq_printf(m, "attndr=%ld\n", co_pmdtest_params.co_attndr);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "NearActatp=%d\n", co_pmdtest_params.co_near_actatp);
++ seq_printf(m, "NearActatp=%d\n", co_pmdtest_params.co_near_actatp);
+
+- if(len<=limit)
+- len += sprintf(buf+len, "FarActatp=%d\n", co_pmdtest_params.co_far_actatp);
++ seq_printf(m, "FarActatp=%d\n", co_pmdtest_params.co_far_actatp);
+
+ //HLOG
+ for (i=0; i<pIhw->AppData.max_us_tones; i++)
+ {
+ if (!(i%16))
+- {
+- if(len <=limit)
+- len += sprintf(buf+len, "\nHLOG(%3d):", i);
+- }
+- if(len <=limit)
+- len += sprintf(buf+len, " %d", co_pmdtest_params.TestParmCOHlogfMsg[i]);
++ seq_printf(m, "\nHLOG(%3d):", i);
++
++ seq_printf(m, " %d", co_pmdtest_params.TestParmCOHlogfMsg[i]);
+ }
+
+ //QLN
+ for (i=0; i<pIhw->AppData.max_us_tones; i++)
+ {
+ if (!(i%16))
+- {
+- if(len <=limit)
+- len += sprintf(buf+len, "\nQLN(%3d):", i);
+- }
+- if(len <=limit)
+- len += sprintf(buf+len, " %d", co_pmdtest_params.TestParmCOQLNfMsg[i]);
++ seq_printf(m, "\nQLN(%3d):", i);
++
++ seq_printf(m, " %d", co_pmdtest_params.TestParmCOQLNfMsg[i]);
+
+ }
+
+@@ -5016,19 +4940,28 @@ int tn7dsl_proc_PMDus(char* buf, char **
+ for (i=0; i<pIhw->AppData.max_us_tones; i++)
+ {
+ if (!(i%16))
+- {
+- if(len <=limit)
+- len += sprintf(buf+len, "\nSNR(%3d):", i);
+- }
+- if(len <=limit)
+- len += sprintf(buf+len, " %d", co_pmdtest_params.TestParmCOSNRfMsg[i]);
++ seq_printf(m, "\nSNR(%3d):", i);
++ seq_printf(m, " %d", co_pmdtest_params.TestParmCOSNRfMsg[i]);
+ }
+
+- if(len <=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+
+- return len;
++ return 0;
++}
++
++static int tn7dsl_proc_PMDus_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7dsl_proc_PMDus, PDE_DATA(inode));
+ }
++
++struct file_operations tn7dsl_proc_PMDus_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7dsl_proc_PMDus_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #endif //NO_ADV_STATS
+ #endif //TR69_PMD_IN
+ // * UR8_MERGE_END CQ11057 *
+--- a/tn7sar.c
++++ b/tn7sar.c
+@@ -1553,44 +1553,70 @@ int tn7sar_oam_generation(void *privCont
+ return 0;
+ }
+
+-int tn7sar_proc_oam_ping(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
++#define PDE_DATA(inode) PDE(inode)->data
++#endif
++
++static int tn7sar_proc_oam_ping(struct seq_file *m, void *data)
+ {
+- int len = 0;
+ unsigned int oam_ps = oamPingStatus;
+
+ if( oam_ps == OAM_PING_PENDING_RECVD )
+ oam_ps = OAM_PING_PENDING; //jz CQ9861: Only export the PENDING status, not internal state
+
+- len += sprintf(buf+len, "%d\n", oam_ps); //oamPingStatus);
++ seq_printf(m, "%d\n", oam_ps); //oamPingStatus);
+
+- return len;
++ return 0;
+ }
+
+-int tn7sar_proc_pvc_table(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7sar_proc_oam_ping_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7sar_proc_oam_ping, PDE_DATA(inode));
++}
++
++struct file_operations tn7sar_proc_oam_ping_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7sar_proc_oam_ping_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++
++static int tn7sar_proc_pvc_table(struct seq_file *m, void *data)
+ {
+- int len = 0;
+ int i;
+
+ for(i=0;i<16;i++)
+ {
+ if(pvc_result[i].bInUse)
+ {
+- len += sprintf(buf+len, "%d,%d\n", pvc_result[i].vpi,pvc_result[i].vci);
++ seq_printf(m, "%d,%d\n", pvc_result[i].vpi,pvc_result[i].vci);
+ }
+ else
+ {
+- len += sprintf(buf+len, "0,0\n");
++ seq_printf(m, "0,0\n");
+ }
+ }
+- return len;
++ return 0;
++}
++
++static int tn7sar_proc_pvc_table_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7sar_proc_pvc_table, PDE_DATA(inode));
+ }
+
++struct file_operations tn7sar_proc_pvc_table_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7sar_proc_pvc_table_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
+
+
+-int tn7sar_proc_sar_stat(char* buf, char **start, off_t offset, int count,int *eof, void *data)
++static int tn7sar_proc_sar_stat(struct seq_file *m, void *data)
+ {
+- int len = 0;
+- int limit = count - 80;
+ struct atm_dev *dev;
+ Tn7AtmPrivate *priv;
+ int i, j, k;
+@@ -1599,21 +1625,19 @@ int tn7sar_proc_sar_stat(char* buf, char
+ unsigned int *pStateBase, *pSarStat;
+ HAL_FUNCTIONS *pHalFunc;
+ HAL_DEVICE *pHalDev;
+- int dBytes;
+
+- dev = (struct atm_dev *)data;
++ dev = (struct atm_dev *)m->private;
+ priv = (Tn7AtmPrivate *)dev->dev_data;
+
+ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc;
+ pHalDev = (HAL_DEVICE *)priv->pSarHalDev;
+
+- len += sprintf(buf+len, "SAR HAL Statistics");
++ seq_printf(m, "SAR HAL Statistics");
+ for(i=0;i<MAX_DMA_CHAN;i++)
+ {
+ if(priv->lut[i].inuse)
+ {
+- if(len<=limit)
+- len += sprintf(buf+len, "\nChannel %d:\n",priv->lut[i].chanid);
++ seq_printf(m, "\nChannel %d:\n",priv->lut[i].chanid);
+ k=0;
+ for(j=0;j<4;j++)
+ {
+@@ -1626,26 +1650,16 @@ int tn7sar_proc_sar_stat(char* buf, char
+ {
+ if((char *)*pSarStat == NULL)
+ break;
+- if(len<=limit)
+- {
+- dBytes = sprintf(buf+len, "%s: ",(char *) *pSarStat);
+- len += dBytes;
+- k += dBytes;
+- }
++
++ k += seq_printf(m, "%s: ",(char *) *pSarStat);
+ pSarStat++;
+- if(len<=limit)
+- {
+- dBytes = sprintf(buf+len, "%s; \n",(char *) *pSarStat);
+- len += dBytes;
+- k += dBytes;
+- }
++ k += seq_printf(m, "%s; \n",(char *) *pSarStat);
+ pSarStat++;
+
+ if(k > 60)
+ {
+ k=0;
+- if(len<=limit)
+- len += sprintf(buf+len, "\n");
++ seq_printf(m, "\n");
+ }
+ }
+
+@@ -1654,9 +1668,22 @@ int tn7sar_proc_sar_stat(char* buf, char
+ }
+ }
+
+- return len;
++ return 0;
+ }
+
++static int tn7sar_proc_sar_stat_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, tn7sar_proc_sar_stat, PDE_DATA(inode));
++}
++
++struct file_operations tn7sar_proc_sar_stat_fops = {
++ .owner = THIS_MODULE,
++ .open = tn7sar_proc_sar_stat_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #ifdef AR7_EFM
+ void tn7sar_get_EFM_firmware_version(unsigned int *pdsp_version_ms, unsigned int *pdsp_version_ls)
+ {
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/240-3.18_fixes.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/240-3.18_fixes.patch
new file mode 100644
index 0000000..a29bae8
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/240-3.18_fixes.patch
@@ -0,0 +1,38 @@
+--- a/tn7dsl.c
++++ b/tn7dsl.c
+@@ -363,7 +363,7 @@ static void tn7dsl_chng_modulation(void*
+ static unsigned int tn7dsl_set_modulation(void* data, int flag);
+ static void tn7dsl_ctrl_fineGain(int value);
+ static void tn7dsl_set_fineGainValue(int value);
+-static int dslmod_sysctl (ctl_table * ctl, int write, struct file *filp,
++static int dslmod_sysctl (struct ctl_table * ctl, int write, struct file *filp,
+ void *buffer, size_t * lenp);
+ static void tn7dsl_register_dslss_led(void);
+ void tn7dsl_dslmod_sysctl_register(void);
+@@ -3505,7 +3505,7 @@ unsigned int tn7dsl_get_memory(unsigned
+
+
+
+-static int dslmod_sysctl(ctl_table *ctl, int write, struct file * filp,
++static int dslmod_sysctl(struct ctl_table *ctl, int write, struct file * filp,
+ void *buffer, size_t *lenp)
+ {
+ char *ptr;
+@@ -3631,7 +3631,7 @@ static int dslmod_sysctl(ctl_table *ctl,
+ }
+
+
+-ctl_table dslmod_table[] = {
++struct 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
+@@ -3649,7 +3649,7 @@ ctl_table dslmod_table[] = {
+ };
+
+ /* Make sure that /proc/sys/dev is there */
+-ctl_table dslmod_root_table[] = {
++struct 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}
diff --git a/package/kernel/ar7-atm/patches-D7.05.01.00/250-4.1_fixes.patch b/package/kernel/ar7-atm/patches-D7.05.01.00/250-4.1_fixes.patch
new file mode 100644
index 0000000..bc913a7
--- /dev/null
+++ b/package/kernel/ar7-atm/patches-D7.05.01.00/250-4.1_fixes.patch
@@ -0,0 +1,20 @@
+--- a/tn7atm.c
++++ b/tn7atm.c
+@@ -856,7 +856,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, IRQF_DISABLED, "SAR ", dev))
++ if (request_irq (priv->sar_irq, tn7atm_sar_irq, 0, "SAR ", dev))
+ printk ("Could not register tn7atm_sar_irq\n");
+
+ /*
+@@ -880,7 +880,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, IRQF_DISABLED, "DSL ", dev))
++ if (request_irq (priv->dsl_irq, tn7atm_dsl_irq, 0, "DSL ", dev))
+ printk ("Could not register tn7atm_dsl_irq\n");
+
+ /***** VRB Tasklet Mode ****/
diff --git a/package/kernel/avila-wdt/Makefile b/package/kernel/avila-wdt/Makefile
new file mode 100644
index 0000000..5bf6bf4
--- /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 0000000..90d9065
--- /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 0000000..981f385
--- /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 0000000..2686cf0
--- /dev/null
+++ b/package/kernel/brcm2708-gpu-fw/Makefile
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2012-2015 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:=9d268f00de7c13afa315fe2d303265d535c4bdf0
+PKG_VERSION:=20151025
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_REV).tar.gz
+PKG_SOURCE_URL:=https://github.com/Hexxeh/rpi-firmware/archive/
+PKG_MD5SUM:=21ac2ba64ef045655b4d4677b3fdf6cd
+
+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
+ true
+endef
+
+define Package/brcm2708-gpu-fw/install
+ true
+endef
+
+define Build/InstallDev
+ $(CP) $(PKG_BUILD_DIR)/bootcode.bin $(KERNEL_BUILD_DIR)
+ $(CP) $(PKG_BUILD_DIR)/COPYING.linux $(KERNEL_BUILD_DIR)
+ $(CP) $(PKG_BUILD_DIR)/LICENCE.broadcom $(KERNEL_BUILD_DIR)
+ $(CP) $(PKG_BUILD_DIR)/start.elf $(KERNEL_BUILD_DIR)
+ $(CP) $(PKG_BUILD_DIR)/start_cd.elf $(KERNEL_BUILD_DIR)
+ $(CP) $(PKG_BUILD_DIR)/fixup.dat $(KERNEL_BUILD_DIR)
+ $(CP) $(PKG_BUILD_DIR)/fixup_cd.dat $(KERNEL_BUILD_DIR)
+endef
+
+$(eval $(call BuildPackage,brcm2708-gpu-fw))
diff --git a/package/kernel/broadcom-wl/Makefile b/package/kernel/broadcom-wl/Makefile
new file mode 100644
index 0000000..003986c
--- /dev/null
+++ b/package/kernel/broadcom-wl/Makefile
@@ -0,0 +1,177 @@
+#
+# Copyright (C) 2006-2014 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:=8
+
+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))
+
+PKG_USE_MIPS16:=0
+
+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) nas $(1)/usr/sbin/nas4not
+ $(LN) 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 0000000..35c4218
--- /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-1]-*}" = 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 0000000..0a29db5
--- /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 0000000..a9c4de2
--- /dev/null
+++ b/package/kernel/broadcom-wl/files/lib/wifi/broadcom.sh
@@ -0,0 +1,477 @@
+append DRIVERS "broadcom"
+
+scan_broadcom() {
+ local device="$1"
+ local vif vifs wds
+ local adhoc sta apmode mon disabled
+ local adhoc_if sta_if ap_if mon_if
+
+ config_get vifs "$device" vifs
+ for vif in $vifs; do
+ config_get_bool disabled "$vif" disabled 0
+ [ $disabled -eq 0 ] || continue
+
+ local mode
+ config_get mode "$vif" mode
+ 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)
+ local addr
+ 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}"
+
+ 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"
+ (
+ include /lib/network
+
+ local pid_file=/var/run/nas.$device.pid
+ [ -e $pid_file ] && start-stop-daemon -K -q -s SIGKILL -p $pid_file && rm $pid_file
+
+ # make sure the interfaces are down and removed from all bridges
+ local dev ifname
+ for dev in /sys/class/net/wds${device##wl}-* /sys/class/net/${device}-* /sys/class/net/${device}; do
+ if [ -e "$dev" ]; then
+ ifname=${dev##/sys/class/net/}
+ ip link set dev "$ifname" down
+ unbridge "$ifname"
+ fi
+ done
+
+ # make sure all of the devices are disabled in the driver
+ local ifdown=
+ local bssmax=$(wlc ifname "$device" bssmax)
+ local vif=$((${bssmax:-4} - 1))
+ append ifdown "down" "$N"
+ append ifdown "wds none" "$N"
+ while [ $vif -ge 0 ]; do
+ append ifdown "vif $vif" "$N"
+ append ifdown "enabled 0" "$N"
+ vif=$(($vif - 1))
+ done
+
+ wlc ifname "$device" stdin <<EOF
+$ifdown
+leddc 0xffff
+EOF
+ )
+ true
+}
+
+enable_broadcom() {
+ local device="$1"
+ local channel country maxassoc wds vifs distance slottime rxantenna txantenna
+ local frameburst macfilter maclist macaddr txpower frag rts hwmode htmode
+ 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 $(wlc ifname "$device" default_bssid)
+ config_get txpower "$device" txpower
+ config_get frag "$device" frag
+ config_get rts "$device" rts
+ config_get hwmode "$device" hwmode
+ config_get htmode "$device" htmode
+ local doth=0
+ local wmm=1
+
+ [ -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
+
+ local gmode=2 nmode=0 nreqd=
+ case "$hwmode" in
+ *a) gmode=;;
+ *b) gmode=0;;
+ *bg) gmode=1;;
+ *g) gmode=2;;
+ *gst) gmode=4;;
+ *lrs) gmode=5;;
+ *) nmode=1; nreqd=0;;
+ esac
+
+ case "$hwmode" in
+ n|11n) nmode=1; nreqd=1;;
+ *n*) nmode=1; nreqd=0;;
+ esac
+
+ # Use 'nmode' for N-Phy only
+ [ "$(wlc ifname "$device" phytype)" = 4 ] || nmode=
+
+ local band chanspec
+ [ ${channel:-0} -ge 1 -a ${channel:-0} -le 14 ] && band=2
+ [ ${channel:-0} -ge 36 ] && {
+ band=1
+ gmode=
+ }
+
+ # Use 'chanspec' instead of 'channel' for 'N' modes (See bcmwifi.h)
+ [ -n "$nmode" -a -n "$band" -a -n "$channel" ] && {
+ case "$htmode" in
+ HT40)
+ if [ -n "$gmode" ]; then
+ [ $channel -lt 7 ] && htmode="HT40+" || htmode="HT40-"
+ else
+ [ $(( ($channel / 4) % 2 )) -eq 1 ] && htmode="HT40+" || htmode="HT40-"
+ fi
+ ;;
+ esac
+ case "$htmode" in
+ HT40-) chanspec=$(printf 0x%x%x%02x $band 0xe $(($channel - 2))); nmode=1; channel=;;
+ HT40+) chanspec=$(printf 0x%x%x%02x $band 0xd $(($channel + 2))); nmode=1; channel=;;
+ HT20) chanspec=$(printf 0x%x%x%02x $band 0xb $channel); nmode=1; channel=;;
+ *) ;;
+ esac
+ }
+
+ local leddc=$(wlc ifname "$device" leddc)
+ [ $((leddc)) -eq $((0xffff)) ] && {
+ leddc=0x005a000a;
+ }
+
+ local _c=0
+ local nas="$(which nas)"
+ local if_pre_up if_up nas_cmd
+ local vif vif_pre_up vif_post_up vif_do_up vif_txpower
+ local bssmax=$(wlc ifname "$device" bssmax)
+ bssmax=${bssmax:-4}
+
+ for vif in $vifs; do
+ [ $_c -ge $bssmax ] && break
+
+ config_get vif_txpower "$vif" txpower
+
+ local mode
+ 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" ] || {
+ local hidden isolate
+ 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"
+ }
+
+ local wsec_r=0
+ local eap_r=0
+ local wsec=0
+ local auth=0
+ local nasopts=
+ local enc key rekey
+
+ config_get enc "$vif" encryption
+ case "$enc" in
+ *wep*)
+ local def defkey k knr
+ 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*)
+ local auth_port auth_secret auth_server
+ 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"
+
+ local ssid
+ config_get ssid "$vif" ssid
+ append vif_post_up "vlan_mode 0" "$N"
+ append vif_pre_up "ssid $ssid" "$N"
+
+ [ "$mode" = "monitor" ] && {
+ append vif_post_up "monitor $monitor" "$N"
+ }
+
+ [ "$mode" = "adhoc" ] && {
+ local bssid
+ 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"
+
+ local ifname
+ config_get ifname "$vif" ifname
+ local if_cmd="if_pre_up"
+ [ "$ifname" != "${ifname##${device}-}" ] && if_cmd="if_up"
+ append $if_cmd "macaddr=\$(wlc ifname '$ifname' cur_etheraddr)" ";$N"
+ append $if_cmd "ip link set dev '$ifname' address \$macaddr" ";$N"
+ append if_up "ip link set dev '$ifname' up" ";$N"
+
+ local net_cfg="$(find_net_config "$vif")"
+ [ -z "$net_cfg" ] || {
+ ubus -t 30 wait_for network.interface."$net_cfg"
+ append if_up "set_wifi_up '$vif' '$ifname'" ";$N"
+ append if_up "start_net '$ifname' '$net_cfg'" ";$N"
+ }
+ [ -z "$nas" -o -z "$nasopts" ] || {
+ eval "${vif}_ssid=\"\$ssid\""
+ local nas_mode="-A"
+ [ "$mode" = "sta" ] && nas_mode="-S"
+ [ -z "$nas_cmd" ] && {
+ local pid_file=/var/run/nas.$device.pid
+ nas_cmd="start-stop-daemon -S -b -p $pid_file -x $nas -- -P $pid_file -H 34954"
+ }
+ append nas_cmd "-i $ifname $nas_mode -m $auth -w $wsec -s \"\$${vif}_ssid\" -g 3600 -F $nasopts"
+ }
+ _c=$(($_c + 1))
+ done
+ wlc ifname "$device" stdin <<EOF
+${macaddr:+bssid $macaddr}
+${macaddr:+cur_etheraddr $macaddr}
+band ${band:-0}
+${nmode:+nmode $nmode}
+${nmode:+${nreqd:+nreqd $nreqd}}
+${gmode:+gmode $gmode}
+leddc $leddc
+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:+wds $wds}
+country ${country:-US}
+${channel:+channel $channel}
+${chanspec:+chanspec $chanspec}
+maxassoc ${maxassoc:-128}
+slottime ${slottime:--1}
+${frameburst:+frameburst $frameburst}
+
+$vif_pre_up
+EOF
+ eval "$if_pre_up"
+ wlc ifname "$device" stdin <<EOF
+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 type
+
+ 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}
+ option txantenna 3
+ option rxantenna 3
+ # 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 0000000..89b6653
--- /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 0000000..36dda47
--- /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 0000000..41c246f
--- /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 0000000..d6dd5f0
--- /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 0000000..a30dcc4
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/007-use-glue-driver.patch
@@ -0,0 +1,188 @@
+--- 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,11 @@ wl_module_init(void)
+ return 0;
+
+ error_pci:
+- ssb_driver_unregister(&wl_ssb_driver);
++#if defined(CONFIG_SSB) || defined(CONFIG_BCMA)
++ wl_glue_unregister();
++ wl_glue_set_attach_callback(NULL);
++ wl_glue_set_remove_callback(NULL);
++#endif /* defined(CONFIG_SSB) || defined(CONFIG_BCMA) */
+ return error;
+ }
+
+@@ -1099,9 +1074,11 @@ 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();
++ wl_glue_set_attach_callback(NULL);
++ wl_glue_set_remove_callback(NULL);
++#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 0000000..23831df
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/008-fix_virtual_interfaces.patch
@@ -0,0 +1,132 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -354,6 +354,7 @@ static int wl_read_proc(char *buffer, ch
+ static int wl_dump(wl_info_t *wl, struct bcmstrbuf *b);
+ #endif /* BCMDBG */
+ struct wl_if *wl_alloc_if(wl_info_t *wl, int iftype, uint unit, struct wlc_if* wlc_if);
++static void wl_link_if(wl_info_t *wl, wl_if_t *wlif);
+ static void wl_free_if(wl_info_t *wl, wl_if_t *wlif);
+
+
+@@ -566,6 +567,9 @@ wl_attach(uint16 vendor, uint16 device,
+ wl->dev = dev;
+ wl_if_setup(dev);
+
++ /* add the interface to the interface linked list */
++ wl_link_if(wl, wlif);
++
+ /* map chip registers (47xx: and sprom) */
+ dev->base_addr = regs;
+
+@@ -1106,10 +1110,14 @@ wl_free(wl_info_t *wl)
+ free_irq(wl->dev->irq, wl);
+ }
+
+- if (wl->dev) {
+- wl_free_if(wl, WL_DEV_IF(wl->dev));
+- wl->dev = NULL;
++ /* free all interfaces */
++ while (wl->if_list) {
++ if ((wl->if_list->dev != wl->dev) || wl->if_list->next == NULL)
++ wl_free_if(wl, wl->if_list);
++ else
++ wl_free_if(wl, wl->if_list->next);
+ }
++ wl->dev = NULL;
+
+ #ifdef TOE
+ wl_toe_detach(wl->toei);
+@@ -1355,10 +1363,12 @@ wl_txflowcontrol(wl_info_t *wl, bool sta
+
+ ASSERT(prio == ALLPRIO);
+ for (wlif = wl->if_list; wlif != NULL; wlif = wlif->next) {
+- if (state == ON)
+- netif_stop_queue(wlif->dev);
+- else
+- netif_wake_queue(wlif->dev);
++ if (wlif->dev_registed) {
++ if (state == ON)
++ netif_stop_queue(wlif->dev);
++ else
++ netif_wake_queue(wlif->dev);
++ }
+ }
+ }
+
+@@ -1398,7 +1408,6 @@ wl_alloc_if(wl_info_t *wl, int iftype, u
+ {
+ struct net_device *dev;
+ wl_if_t *wlif;
+- wl_if_t *p;
+
+ dev = alloc_etherdev(sizeof(wl_if_t));
+ wlif = netdev_priv(dev);
+@@ -1411,9 +1420,13 @@ wl_alloc_if(wl_info_t *wl, int iftype, u
+ wlif->wlcif = wlcif;
+ wlif->subunit = subunit;
+
+- /* match current flow control state */
+- if (iftype != WL_IFTYPE_MON && wl->dev && netif_queue_stopped(wl->dev))
+- netif_stop_queue(dev);
++ return wlif;
++}
++
++static void
++wl_link_if(wl_info_t *wl, wl_if_t *wlif)
++{
++ wl_if_t *p;
+
+ /* add the interface to the interface linked list */
+ if (wl->if_list == NULL)
+@@ -1424,7 +1437,6 @@ wl_alloc_if(wl_info_t *wl, int iftype, u
+ p = p->next;
+ p->next = wlif;
+ }
+- return wlif;
+ }
+
+ static void
+@@ -1504,6 +1516,9 @@ _wl_add_if(wl_task_t *task)
+ wl_info_t *wl = wlif->wl;
+ struct net_device *dev = wlif->dev;
+
++ /* add the interface to the interface linked list */
++ wl_link_if(wl, wlif);
++
+ if (wlif->type == WL_IFTYPE_WDS)
+ dev->netdev_ops = &wl_wds_ops;
+
+@@ -1516,6 +1531,14 @@ _wl_add_if(wl_task_t *task)
+ }
+ wlif->dev_registed = TRUE;
+
++ /* match current flow control state */
++ if (wl->dev) {
++ if (netif_queue_stopped(wl->dev))
++ netif_stop_queue(dev);
++ else
++ netif_wake_queue(dev);
++ }
++
+ done:
+ MFREE(wl->osh, task, sizeof(wl_task_t));
+ atomic_dec(&wl->callbacks);
+@@ -1545,6 +1568,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);
+@@ -2778,6 +2803,9 @@ wl_add_monitor(wl_task_t *task)
+ dev = wlif->dev;
+ wl->monitor = dev;
+
++ /* add the interface to the interface linked list */
++ wl_link_if(wl, wlif);
++
+ /* override some fields */
+ sprintf(dev->name, "prism%d", wl->pub->unit);
+ bcopy(wl->dev->dev_addr, dev->dev_addr, 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 0000000..cb388a1
--- /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
+@@ -463,6 +463,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, \
+@@ -471,6 +481,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 0000000..7b60873
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/010-remove_irqf_samble_random.patch
@@ -0,0 +1,11 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -695,7 +695,7 @@ wl_attach(uint16 vendor, uint16 device,
+ 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 0000000..585d53c
--- /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/012-compat-3.10.patch b/package/kernel/broadcom-wl/patches/012-compat-3.10.patch
new file mode 100644
index 0000000..e36028a
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/012-compat-3.10.patch
@@ -0,0 +1,47 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -349,7 +349,7 @@ static void wl_mic_error(wl_info_t *wl,
+ defined(WL_MONITOR)
+ static int wl_schedule_task(wl_info_t *wl, void (*fn)(struct wl_task *), void *context);
+ #endif
+-#if defined(CONFIG_PROC_FS)
++#if defined(CONFIG_PROC_FS) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
+ static int wl_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
+ #endif /* defined(CONFIG_PROC_FS) */
+ #ifdef BCMDBG
+@@ -517,7 +517,7 @@ wl_attach(uint16 vendor, uint16 device,
+ struct net_device *dev;
+ wl_if_t *wlif;
+ wl_info_t *wl;
+-#if defined(CONFIG_PROC_FS)
++#if defined(CONFIG_PROC_FS) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
+ char tmp[128];
+ #endif
+ osl_t *osh;
+@@ -664,7 +664,7 @@ wl_attach(uint16 vendor, uint16 device,
+ WL_ERROR(("wl%d: Error setting MPC variable to 0\n", unit));
+ }
+ }
+-#if defined(CONFIG_PROC_FS)
++#if defined(CONFIG_PROC_FS) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
+ /* create /proc/net/wl<unit> */
+ sprintf(tmp, "net/wl%d", wl->pub->unit);
+ create_proc_read_entry(tmp, 0, 0, wl_read_proc, (void*)wl);
+@@ -810,7 +810,7 @@ wl_dbus_disconnect_cb(void *arg)
+ }
+ #endif /* BCMDBUS */
+
+-#if defined(CONFIG_PROC_FS)
++#if defined(CONFIG_PROC_FS) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
+ static int
+ wl_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
+ {
+@@ -1149,7 +1149,7 @@ wl_free(wl_info_t *wl)
+
+ /* free common resources */
+ if (wl->wlc) {
+-#if defined(CONFIG_PROC_FS)
++#if defined(CONFIG_PROC_FS) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
+ char tmp[128];
+ /* remove /proc/net/wl<unit> */
+ sprintf(tmp, "net/wl%d", wl->pub->unit);
diff --git a/package/kernel/broadcom-wl/patches/013-interface-name.patch b/package/kernel/broadcom-wl/patches/013-interface-name.patch
new file mode 100644
index 0000000..dbe1bdb
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/013-interface-name.patch
@@ -0,0 +1,11 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -1583,7 +1583,7 @@ wl_add_if(wl_info_t *wl, struct wlc_if*
+
+ wl_if_setup(wlif->dev);
+
+- sprintf(wlif->dev->name, "%s%d.%d", devname, wl->pub->unit, wlif->subunit);
++ 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/014-fix-band-reporting.patch b/package/kernel/broadcom-wl/patches/014-fix-band-reporting.patch
new file mode 100644
index 0000000..b231fed
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/014-fix-band-reporting.patch
@@ -0,0 +1,41 @@
+--- a/driver/wl_iw.c
++++ b/driver/wl_iw.c
+@@ -314,7 +314,7 @@ wl_iw_get_name(
+ )
+ {
+ int phytype, err;
+- uint band[3];
++ uint i, band[3], bands;
+ char cap[5];
+
+ WL_TRACE(("%s: SIOCGIWNAME\n", dev->name));
+@@ -335,16 +335,20 @@ wl_iw_get_name(
+ break;
+ case WLC_PHY_TYPE_LP:
+ case WLC_PHY_TYPE_G:
+- if (band[0] >= 2)
+- strcpy(cap, "abg");
+- else
+- strcpy(cap, "bg");
+- break;
+ case WLC_PHY_TYPE_N:
+- if (band[0] >= 2)
+- strcpy(cap, "abgn");
+- else
+- strcpy(cap, "bgn");
++ bands = 0;
++ for (i = 1; i <= band[0]; i++) {
++ bands |= dtoh32(band[i]);
++ }
++ strcpy(cap, "");
++ if (bands & WLC_BAND_5G)
++ strcat(cap, "a");
++ if (bands & WLC_BAND_2G)
++ strcat(cap, "bg");
++ if (phytype == WLC_PHY_TYPE_N)
++ strcat(cap, "n");
++ break;
++ default:
+ break;
+ }
+ done:
diff --git a/package/kernel/broadcom-wl/patches/015-support-probe-of-wds-interfaces.patch b/package/kernel/broadcom-wl/patches/015-support-probe-of-wds-interfaces.patch
new file mode 100644
index 0000000..f44921a
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/015-support-probe-of-wds-interfaces.patch
@@ -0,0 +1,11 @@
+--- a/shared/wl.c
++++ b/shared/wl.c
+@@ -27,7 +27,7 @@ wl_probe(char *name)
+ {
+ int ret, val;
+
+- if ((name[0] != 'w') || (name[1] != 'l'))
++ if ((name[0] != 'w') || ((name[1] != 'l') && ((name[1] != 'd') || (name[2] != 's'))))
+ return -1;
+
+ /* Check interface */
diff --git a/package/kernel/broadcom-wl/patches/020-musl-fixes.patch b/package/kernel/broadcom-wl/patches/020-musl-fixes.patch
new file mode 100644
index 0000000..a985b9c
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/020-musl-fixes.patch
@@ -0,0 +1,75 @@
+--- a/shared/wl_linux.c
++++ b/shared/wl_linux.c
+@@ -13,6 +13,7 @@
+ */
+
+ #include <stdio.h>
++#include <stdint.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <errno.h>
+@@ -20,10 +21,10 @@
+ #include <net/if.h>
+ #include <linux/types.h>
+
+-typedef u_int64_t u64;
+-typedef u_int32_t u32;
+-typedef u_int16_t u16;
+-typedef u_int8_t u8;
++typedef uint64_t u64;
++typedef uint32_t u32;
++typedef uint16_t u16;
++typedef uint8_t u8;
+ #include <linux/sockios.h>
+ #include <linux/ethtool.h>
+
+--- a/shared/linux_timer.c
++++ b/shared/linux_timer.c
+@@ -125,7 +125,7 @@ void unblock_timer();
+
+ static struct event *event_queue = NULL;
+ static struct event *event_freelist;
+-static uint g_granularity;
++static unsigned int g_granularity;
+ static int g_maxevents = 0;
+
+ uclock_t uclock()
+--- a/shared/wl.c
++++ b/shared/wl.c
+@@ -14,6 +14,7 @@
+ #include <typedefs.h>
+ #include <string.h>
+ #include <stdio.h>
++#include <stdlib.h>
+ #include <unistd.h>
+ #include <errno.h>
+ #include <sys/ioctl.h>
+@@ -263,3 +264,28 @@ wl_printlasterror(char *name)
+ fprintf(stderr, err_buf);
+ }
+ */
++
++static int in_assert; /* bss inits to 0. */
++
++void __assert(const char *assertion, const char * filename,
++ unsigned int linenumber, register const char * function)
++{
++ if (!in_assert) {
++ in_assert = 1;
++
++ fprintf(stderr,
++#ifdef ASSERT_SHOW_PROGNAME
++ "%s: %s: %d: %s: Assertion `%s' failed.\n", __uclibc_progname,
++#else
++ "%s: %d: %s: Assertion `%s' failed.\n",
++#endif
++ filename,
++ linenumber,
++ /* Function name isn't available with some compilers. */
++ ((function == NULL) ? "?function?" : function),
++ assertion
++ );
++ }
++ /* shouldn't we? fflush(stderr); */
++ abort();
++}
diff --git a/package/kernel/broadcom-wl/patches/030-remove_devinit_devexit.patch b/package/kernel/broadcom-wl/patches/030-remove_devinit_devexit.patch
new file mode 100644
index 0000000..ead108e
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/030-remove_devinit_devexit.patch
@@ -0,0 +1,74 @@
+--- a/driver/include/linuxver.h
++++ b/driver/include/linuxver.h
+@@ -139,22 +139,6 @@ typedef struct pcmcia_device dev_link_t;
+
+ #endif /* CONFIG_PCMCIA */
+
+-#ifndef __exit
+-#define __exit
+-#endif
+-#ifndef __devexit
+-#define __devexit
+-#endif
+-#ifndef __devinit
+-#define __devinit __init
+-#endif
+-#ifndef __devinitdata
+-#define __devinitdata
+-#endif
+-#ifndef __devexit_p
+-#define __devexit_p(x) x
+-#endif
+-
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
+
+ #define pci_get_drvdata(dev) (dev)->sysdata
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -854,7 +854,7 @@ wl_read_proc(char *buffer, char **start,
+ */
+ #if !defined(BCMJTAG)
+ #ifdef CONFIG_PCI
+-static void __devexit wl_remove(struct pci_dev *pdev);
++static void wl_remove(struct pci_dev *pdev);
+ /**
+ * determines if a device is a WL device, and if so, attaches it.
+ *
+@@ -862,7 +862,7 @@ static void __devexit wl_remove(struct p
+ * and if so, performs a wl_attach() on it.
+ *
+ */
+-int __devinit
++int
+ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+ int rc;
+@@ -976,7 +976,7 @@ wl_resume(struct pci_dev *pdev)
+ }
+ #endif /* LINUXSTA_PS */
+
+-static void __devexit
++static void
+ wl_remove(struct pci_dev *pdev)
+ {
+ wl_info_t *wl = (wl_info_t *) pci_get_drvdata(pdev);
+@@ -1007,7 +1007,7 @@ static struct pci_driver wl_pci_driver =
+ suspend: wl_suspend,
+ resume: wl_resume,
+ #endif /* LINUXSTA_PS */
+- remove: __devexit_p(wl_remove),
++ remove: wl_remove,
+ id_table: wl_id_table,
+ };
+ #endif /* CONFIG_PCI */
+--- a/driver/wl_linux.h
++++ b/driver/wl_linux.h
+@@ -33,7 +33,7 @@ extern irqreturn_t wl_isr(int irq, void
+ extern irqreturn_t wl_isr(int irq, void *dev_id, struct pt_regs *ptregs);
+ #endif
+
+-extern int __devinit wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
++extern int wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+ extern void wl_free(wl_info_t *wl);
+ extern int wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+ extern struct net_device * wl_netdev_get(wl_info_t *wl);
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 0000000..6cf6fae
--- /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;
++
+ 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 0000000..95f0beb
--- /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
+@@ -1425,7 +1425,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/120-fixup-mac-addresses.patch b/package/kernel/broadcom-wl/patches/120-fixup-mac-addresses.patch
new file mode 100644
index 0000000..a07176d
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/120-fixup-mac-addresses.patch
@@ -0,0 +1,92 @@
+--- a/driver/nvram_stub.c
++++ b/driver/nvram_stub.c
+@@ -5,6 +5,7 @@
+ #include <siutils.h>
+ #include <bcmendian.h>
+ #include <bcmnvram.h>
++#include <proto/ethernet.h>
+
+ #ifdef BCMDBG_ERR
+ #define NVR_MSG(x) printf x
+@@ -24,6 +25,7 @@ typedef struct _vars {
+ static vars_t *vars = NULL;
+ static int nvram_init_done = 0;
+ extern char *nvram_buf[];
++static void fixup_mac_addr(vars_t *new);
+
+ int
+ BCMATTACHFN(nvram_init)(void *si)
+@@ -55,6 +57,7 @@ BCMATTACHFN(nvram_init)(void *si)
+ vars = new;
+
+ bcopy((char *)(&nvh[1]), new->vars, nvs);
++ fixup_mac_addr(new);
+ return 0;
+ }
+
+@@ -164,3 +167,65 @@ nvram_getall(char *buf, int count)
+ *buf = '\0';
+ return 0;
+ }
++
++static bool nvram_is_valid_mac(struct ether_addr *mac)
++{
++ return mac && !(mac->octet[0] == 0x00 && mac->octet[1] == 0x90 && mac->octet[2] == 0x4c);
++}
++
++static int nvram_increase_mac_addr(struct ether_addr *mac, u8 num)
++{
++ u8 *oui = mac->octet + ETHER_ADDR_LEN/2 - 1;
++ u8 *p = mac->octet + ETHER_ADDR_LEN - 1;
++
++ do {
++ (*p) += num;
++ if (*p > num)
++ break;
++ p--;
++ num = 1;
++ } while (p != oui);
++
++ if (p == oui) {
++ pr_err("unable to fetch mac address\n");
++ return -ENOENT;
++ }
++ return 0;
++}
++
++static void nvram_change_mac_addr(vars_t *new, struct ether_addr *valid, const char *name)
++{
++ char *macaddr_c;
++ struct ether_addr macaddr;
++
++ macaddr_c = findvar(new->vars, new->vars + new->size, name);
++ if (!macaddr_c)
++ return;
++
++ bcm_ether_atoe(macaddr_c, &macaddr);
++ if (nvram_is_valid_mac(&macaddr))
++ return;
++ nvram_increase_mac_addr(valid, 1);
++ bcm_ether_ntoa(valid, macaddr_c);
++}
++
++static void fixup_mac_addr(vars_t *new)
++{
++ char *macaddr_base_c;
++ struct ether_addr macaddr_base;
++
++ macaddr_base_c = findvar(new->vars, new->vars + new->size, "et0macaddr");
++ if (!macaddr_base_c)
++ return;
++
++ bcm_ether_atoe(macaddr_base_c, &macaddr_base);
++ if (!nvram_is_valid_mac(&macaddr_base))
++ return;
++
++ /* jump over the first free address so it can be used for wan */
++ nvram_increase_mac_addr(&macaddr_base, 1);
++ nvram_change_mac_addr(new, &macaddr_base, "sb/1/macaddr");
++ nvram_change_mac_addr(new, &macaddr_base, "pci/1/1/macaddr");
++ nvram_change_mac_addr(new, &macaddr_base, "pci/1/2/macaddr");
++ nvram_change_mac_addr(new, &macaddr_base, "pci/2/1/macaddr");
++}
diff --git a/package/kernel/broadcom-wl/patches/200-add_bcm_a8xx_support.patch b/package/kernel/broadcom-wl/patches/200-add_bcm_a8xx_support.patch
new file mode 100644
index 0000000..c1d1344
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/200-add_bcm_a8xx_support.patch
@@ -0,0 +1,12 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -876,7 +876,8 @@ wl_pci_probe(struct pci_dev *pdev, const
+
+ if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
+ (((pdev->device & 0xff00) != 0x4300) &&
+- ((pdev->device & 0xff00) != 0x4700)))
++ ((pdev->device & 0xff00) != 0x4700) &&
++ ((pdev->device & 0xff00) != 0xa800)))
+ return (-ENODEV);
+
+ rc = pci_enable_device(pdev);
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 0000000..a85e40b
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/910-fallback-sprom.patch
@@ -0,0 +1,78 @@
+--- 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 int bcm63xx_get_fallback_sprom(uint pci_bus, uint pci_slot, struct ssb_sprom *out);
++#endif
++
+ #ifdef WLTEST
+ #include <sbsprom.h>
+ #endif /* WLTEST */
+@@ -2120,6 +2125,63 @@ 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 )
++ {
++ char eabuf[18];
++ struct ssb_sprom bcm63xx_sprom;
++ uint pci_bus = osl_pci_bus(osh), pci_slot = osl_pci_slot(osh);
++
++ bcm63xx_get_fallback_sprom(pci_bus, pci_slot, &bcm63xx_sprom);
++ printk("BCM%X(%02x:%02x) using sprom version %i\n", sih->chip, pci_bus, pci_slot, bcm63xx_sprom.revision);
++
++ varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
++
++ 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 0000000..65e8bd3
--- /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 0000000..412bce9
--- /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/patches/914-eliminate-date-time-error.patch b/package/kernel/broadcom-wl/patches/914-eliminate-date-time-error.patch
new file mode 100644
index 0000000..394a06d
--- /dev/null
+++ b/package/kernel/broadcom-wl/patches/914-eliminate-date-time-error.patch
@@ -0,0 +1,21 @@
+--- a/driver/wl_linux.c
++++ b/driver/wl_linux.c
+@@ -762,7 +762,7 @@ wl_attach(uint16 vendor, uint16 device,
+ dev->name, device);
+
+ #ifdef BCMDBG
+- printf(" (Compiled in " SRCBASE " at " __TIME__ " on " __DATE__ ")");
++ printf(" (Compiled in " SRCBASE ")");
+ #endif /* BCMDBG */
+ printf("\n");
+
+@@ -2298,8 +2298,7 @@ wl_sendup(wl_info_t *wl, wl_if_t *wlif,
+ void
+ wl_dump_ver(wl_info_t *wl, struct bcmstrbuf *b)
+ {
+- bcm_bprintf(b, "wl%d: %s %s version %s\n", wl->pub->unit,
+- __DATE__, __TIME__, EPI_VERSION_STR);
++ bcm_bprintf(b, "wl%d: version %s\n", wl->pub->unit, EPI_VERSION_STR);
+ }
+
+ #ifdef BCMDBG
diff --git a/package/kernel/broadcom-wl/src/glue/Makefile b/package/kernel/broadcom-wl/src/glue/Makefile
new file mode 100644
index 0000000..81f0c8a
--- /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 0000000..64f8486
--- /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),
+ {},
+};
+
+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),
+ {},
+};
+
+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_BCM47XX_SSB
+ case BCM47XX_BUS_TYPE_SSB:
+ active_bus_type = WL_GLUE_BUS_TYPE_SSB;
+ break;
+#endif /* CONFIG_BCM47XX_SSB */
+
+#ifdef CONFIG_BCM47XX_BCMA
+ case BCM47XX_BUS_TYPE_BCMA:
+ active_bus_type = WL_GLUE_BUS_TYPE_BCMA;
+ break;
+#endif /* CONFIG_BCM47XX_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 0000000..b3c8aa3
--- /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 0000000..db48b73
--- /dev/null
+++ b/package/kernel/broadcom-wl/src/wlc.c
@@ -0,0 +1,1181 @@
+/*
+ * 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 int wlc_cap(wlc_param param, void *data, void *value)
+{
+ char *iov = *((char **) data);
+
+ if (param & GET)
+ return wl_iovar_get(interface, iov, value, BUFSIZE);
+
+ return -1;
+}
+
+static int wlc_bssmax(wlc_param param, void *data, void *value)
+{
+ int *val = (int *) value;
+ char *iov = *((char **) data);
+ int ret = -1;
+
+ if (param & GET) {
+ ret = wl_iovar_get(interface, iov, wlbuf, BUFSIZE);
+ if (!ret) {
+ if (strstr(wlbuf, "mbss4"))
+ *val = 4;
+ else if (strstr(wlbuf, "mbss16"))
+ *val = 16;
+ else
+ *val = 1;
+ }
+ }
+
+ return ret;
+}
+
+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, str, WSEC_MAX_PSK_LEN);
+ pmk.key_len = strlen(str);
+
+ 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 = "cur_etheraddr",
+ .param = MAC,
+ .handler = wlc_iovar,
+ .data.str = "cur_etheraddr",
+ .desc = "Current MAC Address"
+ },
+ {
+ .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"
+ },
+ {
+ .name = "phytype",
+ .param = INT,
+ .data.num = (WLC_GET_PHYTYPE << 16),
+ .handler = wlc_ioctl,
+ .desc = "PHY Type (read-only)"
+ },
+ {
+ .name = "nmode",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "nmode",
+ .desc = "N Mode"
+ },
+ {
+ .name = "nreqd",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "nreqd",
+ .desc = "N Mode required"
+ },
+ {
+ .name = "chanspec",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "chanspec",
+ .desc = "Channel Spec (See bcmwifi.h)"
+ },
+ {
+ .name = "band",
+ .param = INT,
+ .data.num = ((WLC_GET_BAND << 16) | WLC_SET_BAND),
+ .handler = wlc_ioctl,
+ .desc = "Band (0=auto, 1=5Ghz, 2=2.4GHz)"
+ },
+ {
+ .name = "cap",
+ .param = STRING|NOARG,
+ .handler = wlc_cap,
+ .data.str = "cap",
+ .desc = "Capabilities"
+ },
+ {
+ .name = "bssmax",
+ .param = INT|NOARG,
+ .handler = wlc_bssmax,
+ .data.str = "cap",
+ .desc = "Number of VIF's supported"
+ },
+ {
+ .name = "leddc",
+ .param = INT,
+ .handler = wlc_iovar,
+ .data.str = "leddc",
+ .desc = "LED Duty Cycle"
+ },
+
+};
+#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, 0);
+ 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(s, ' ')) != NULL)
+ *(s2++) = 0;
+
+ while (s2 && isspace(*s2))
+ s2++;
+
+ if ((call = find_cmd(s)) == NULL) {
+ fprintf(stderr, "Invalid command: %s\n", s);
+ 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 0000000..347544c
--- /dev/null
+++ b/package/kernel/button-hotplug/Makefile
@@ -0,0 +1,55 @@
+#
+# 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
+ DEPENDS:=+kmod-input-core
+ 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 uevent-s from input subsystem events.
+ If your device uses GPIO buttons, see gpio-button-hotplug.
+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 0000000..aa292e9
--- /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 0000000..230d604
--- /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 0000000..41fdf3a
--- /dev/null
+++ b/package/kernel/button-hotplug/src/button-hotplug.c
@@ -0,0 +1,343 @@
+/*
+ * 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"),
+ BH_MAP(KEY_POWER, "power"),
+ BH_MAP(KEY_RFKILL, "rfkill"),
+ BH_MAP(KEY_WPS_BUTTON, "wps"),
+ BH_MAP(KEY_WIMAX, "wwan"),
+};
+
+/* -------------------------------------------------------------------------*/
+
+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;
+}
+
+/* -------------------------------------------------------------------------*/
+
+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;
+}
+
+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 0000000..61d3bc2
--- /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 0000000..80ca0ef
--- /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 0000000..f897527
--- /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 0000000..af231f2
--- /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 0000000..162449c
--- /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 0000000..921d464
--- /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 0000000..f7ca627
--- /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 0000000..71d2d54
--- /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 0000000..c6eced6
--- /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 0000000..d5fc46f
--- /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 0000000..a08e8c7
--- /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 0000000..ae74e0c
--- /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 0000000..2919466
--- /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 0000000..26c53dc
--- /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 0000000..2950cc7
--- /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 0000000..19dbb7e
--- /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 0000000..59242b8
--- /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 0000000..d858aff
--- /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 0000000..f3f9acb
--- /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 0000000..c11275e
--- /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 0000000..291fb0a
--- /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 0000000..ca8c1bb
--- /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 0000000..63a1326
--- /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 0000000..793d08d
--- /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 0000000..7b2df63
--- /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 0000000..f46f900
--- /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 0000000..47fb920
--- /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 0000000..60cc4ae
--- /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 0000000..ac5dd1f
--- /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 0000000..c2fdaec
--- /dev/null
+++ b/package/kernel/gpio-button-hotplug/Makefile
@@ -0,0 +1,50 @@
+#
+# 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/gpio-button-hotplug/description
+ This is a replacement for the following in-kernel drivers:
+ 1) gpio_keys (KEYBOARD_GPIO)
+ 2) gpio_keys_polled (KEYBOARD_GPIO_POLLED)
+
+ Instead of generating input events (like in-kernel drivers do) it generates
+ uevent-s and broadcasts them. This allows disabling input subsystem which is
+ an overkill for OpenWrt simple needs.
+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 0000000..e968865
--- /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 0000000..029a388
--- /dev/null
+++ b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c
@@ -0,0 +1,670 @@
+/*
+ * 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/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio_keys.h>
+
+#define DRV_NAME "gpio-keys"
+
+#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;
+ unsigned int type;
+ 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;
+ struct gpio_keys_button *b;
+};
+
+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_POWER, "power"),
+ BH_MAP(KEY_RESTART, "reset"),
+ BH_MAP(KEY_RFKILL, "rfkill"),
+ BH_MAP(KEY_WPS_BUTTON, "wps"),
+ BH_MAP(KEY_WIMAX, "wwan"),
+};
+
+/* -------------------------------------------------------------------------*/
+
+static __printf(3, 4)
+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)) {
+ WARN(1, "buffer size too small");
+ 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;
+
+ if (event->type == EV_SW) {
+ ret = bh_event_add_var(event, 0, "TYPE=%s", "switch");
+ 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 int type,
+ 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->type = type;
+ event->seen = seen;
+ event->action = pressed ? "pressed" : "released";
+
+ INIT_WORK(&event->work, (void *)(void *)button_hotplug_work);
+ schedule_work(&event->work);
+
+ return 0;
+}
+
+/* -------------------------------------------------------------------------*/
+
+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, 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, data->b->code, value);
+
+ if ((type != EV_KEY) && (type != EV_SW))
+ return;
+
+ btn = button_get_index(data->b->code);
+ if (btn < 0)
+ return;
+
+ button_hotplug_create_event(button_map[btn].name, type,
+ (seen - priv->seen) / HZ, value);
+ priv->seen = seen;
+}
+
+struct gpio_keys_button_dev {
+ int polled;
+ struct delayed_work work;
+
+ struct device *dev;
+ struct gpio_keys_platform_data *pdata;
+ struct gpio_keys_button_data data[0];
+};
+
+static int gpio_button_get_value(struct gpio_keys_button_data *bdata)
+{
+ int val;
+
+ if (bdata->can_sleep)
+ val = !!gpio_get_value_cansleep(bdata->b->gpio);
+ else
+ val = !!gpio_get_value(bdata->b->gpio);
+
+ return val ^ bdata->b->active_low;
+}
+
+static void gpio_keys_polled_check_state(struct gpio_keys_button_data *bdata)
+{
+ int state = gpio_button_get_value(bdata);
+
+ if (state != bdata->last_state) {
+ unsigned int type = bdata->b->type ?: EV_KEY;
+
+ if (bdata->count < bdata->threshold) {
+ bdata->count++;
+ return;
+ }
+
+ if ((bdata->last_state != -1) || (type == EV_SW))
+ button_hotplug_event(bdata, type, state);
+
+ bdata->last_state = state;
+ }
+
+ bdata->count = 0;
+}
+
+static void gpio_keys_polled_queue_work(struct gpio_keys_button_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_button_dev *bdev =
+ container_of(work, struct gpio_keys_button_dev, work.work);
+ int i;
+
+ for (i = 0; i < bdev->pdata->nbuttons; i++) {
+ struct gpio_keys_button_data *bdata = &bdev->data[i];
+ gpio_keys_polled_check_state(bdata);
+ }
+ gpio_keys_polled_queue_work(bdev);
+}
+
+static void gpio_keys_polled_close(struct gpio_keys_button_dev *bdev)
+{
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
+
+ cancel_delayed_work_sync(&bdev->work);
+
+ if (pdata->disable)
+ pdata->disable(bdev->dev);
+}
+
+static irqreturn_t button_handle_irq(int irq, void *_bdata)
+{
+ struct gpio_keys_button_data *bdata = (struct gpio_keys_button_data *) _bdata;
+
+ button_hotplug_event(bdata, bdata->b->type ?: EV_KEY, gpio_button_get_value(bdata));
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_OF
+static struct gpio_keys_platform_data *
+gpio_keys_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 = 0;
+
+ node = dev->of_node;
+ if (!node)
+ return NULL;
+
+ nbuttons = of_get_child_count(node);
+ if (nbuttons == 0)
+ return NULL;
+
+ pdata = devm_kzalloc(dev, 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);
+
+ 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);
+ if (button->gpio < 0) {
+ error = button->gpio;
+ if (error != -ENOENT) {
+ if (error != -EPROBE_DEFER)
+ dev_err(dev,
+ "Failed to get gpio flags, error: %d\n",
+ error);
+ return ERR_PTR(error);
+ }
+ } else {
+ 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_out;
+ }
+
+ 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_out;
+ }
+
+ return pdata;
+
+err_out:
+ return ERR_PTR(error);
+}
+
+static struct of_device_id gpio_keys_of_match[] = {
+ { .compatible = "gpio-keys", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, gpio_keys_of_match);
+
+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_get_devtree_pdata(struct device *dev)
+{
+ return NULL;
+}
+#endif
+
+static int gpio_keys_button_probe(struct platform_device *pdev,
+ struct gpio_keys_button_dev **_bdev, int polled)
+{
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+ struct device *dev = &pdev->dev;
+ struct gpio_keys_button_dev *bdev;
+ struct gpio_keys_button *buttons;
+ int error;
+ int i;
+
+ if (!pdata) {
+ pdata = gpio_keys_get_devtree_pdata(dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ if (!pdata) {
+ dev_err(dev, "missing platform data\n");
+ return -EINVAL;
+ }
+ pdev->dev.platform_data = pdata;
+ }
+
+ if (polled && !pdata->poll_interval) {
+ dev_err(dev, "missing poll_interval value\n");
+ return -EINVAL;
+ }
+
+ buttons = devm_kzalloc(dev, pdata->nbuttons * sizeof(struct gpio_keys_button),
+ GFP_KERNEL);
+ if (!buttons) {
+ dev_err(dev, "no memory for button data\n");
+ return -ENOMEM;
+ }
+ memcpy(buttons, pdata->buttons, pdata->nbuttons * sizeof(struct gpio_keys_button));
+
+ bdev = devm_kzalloc(dev, sizeof(struct gpio_keys_button_dev) +
+ pdata->nbuttons * sizeof(struct gpio_keys_button_data),
+ GFP_KERNEL);
+ if (!bdev) {
+ dev_err(dev, "no memory for private data\n");
+ return -ENOMEM;
+ }
+
+ bdev->polled = polled;
+
+ for (i = 0; i < pdata->nbuttons; i++) {
+ struct gpio_keys_button *button = &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");
+ return -EINVAL;
+ }
+
+ error = devm_gpio_request(dev, gpio,
+ button->desc ? button->desc : DRV_NAME);
+ if (error) {
+ dev_err(dev, "unable to claim gpio %u, err=%d\n",
+ gpio, error);
+ return error;
+ }
+
+ error = gpio_direction_input(gpio);
+ if (error) {
+ dev_err(dev,
+ "unable to set direction on gpio %u, err=%d\n",
+ gpio, error);
+ return error;
+ }
+
+ bdata->can_sleep = gpio_cansleep(gpio);
+ bdata->last_state = -1;
+
+ if (bdev->polled)
+ bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
+ pdata->poll_interval);
+ else
+ bdata->threshold = 1;
+
+ bdata->b = &pdata->buttons[i];
+ }
+
+ bdev->dev = &pdev->dev;
+ bdev->pdata = pdata;
+ platform_set_drvdata(pdev, bdev);
+
+ *_bdev = bdev;
+
+ return 0;
+}
+
+static int gpio_keys_probe(struct platform_device *pdev)
+{
+ struct gpio_keys_platform_data *pdata;
+ struct gpio_keys_button_dev *bdev;
+ int ret, i;
+
+
+ ret = gpio_keys_button_probe(pdev, &bdev, 0);
+
+ if (ret)
+ return ret;
+
+ pdata = pdev->dev.platform_data;
+ for (i = 0; i < pdata->nbuttons; i++) {
+ struct gpio_keys_button *button = &pdata->buttons[i];
+ struct gpio_keys_button_data *bdata = &bdev->data[i];
+
+ if (bdata->can_sleep) {
+ dev_err(&pdev->dev, "skipping gpio:%d, it can sleep\n", button->gpio);
+ continue;
+ }
+ if (!button->irq)
+ button->irq = gpio_to_irq(button->gpio);
+ if (button->irq < 0) {
+ dev_err(&pdev->dev, "failed to get irq for gpio:%d\n", button->gpio);
+ continue;
+ }
+ ret = devm_request_irq(&pdev->dev, button->irq, button_handle_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ dev_name(&pdev->dev), bdata);
+ if (ret)
+ dev_err(&pdev->dev, "failed to request irq:%d for gpio:%d\n", button->irq, button->gpio);
+ else
+ dev_dbg(&pdev->dev, "gpio:%d has irq:%d\n", button->gpio, button->irq);
+
+ if (bdata->b->type == EV_SW)
+ button_hotplug_event(bdata, EV_SW, gpio_button_get_value(bdata));
+ }
+
+ return 0;
+}
+
+static int gpio_keys_polled_probe(struct platform_device *pdev)
+{
+ struct gpio_keys_platform_data *pdata;
+ struct gpio_keys_button_dev *bdev;
+ int ret;
+ int i;
+
+ ret = gpio_keys_button_probe(pdev, &bdev, 1);
+
+ if (ret)
+ return ret;
+
+ INIT_DELAYED_WORK(&bdev->work, gpio_keys_polled_poll);
+
+ pdata = bdev->pdata;
+
+ if (pdata->enable)
+ pdata->enable(bdev->dev);
+
+ for (i = 0; i < pdata->nbuttons; i++)
+ gpio_keys_polled_check_state(&bdev->data[i]);
+
+ gpio_keys_polled_queue_work(bdev);
+
+ return ret;
+}
+
+static int gpio_keys_remove(struct platform_device *pdev)
+{
+ struct gpio_keys_button_dev *bdev = platform_get_drvdata(pdev);
+
+ platform_set_drvdata(pdev, NULL);
+
+ if (bdev->polled)
+ gpio_keys_polled_close(bdev);
+
+ return 0;
+}
+
+static struct platform_driver gpio_keys_driver = {
+ .probe = gpio_keys_probe,
+ .remove = gpio_keys_remove,
+ .driver = {
+ .name = "gpio-keys",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(gpio_keys_of_match),
+ },
+};
+
+static struct platform_driver gpio_keys_polled_driver = {
+ .probe = gpio_keys_polled_probe,
+ .remove = gpio_keys_remove,
+ .driver = {
+ .name = "gpio-keys-polled",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(gpio_keys_polled_of_match),
+ },
+};
+
+static int __init gpio_button_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&gpio_keys_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&gpio_keys_polled_driver);
+ if (ret)
+ platform_driver_unregister(&gpio_keys_driver);
+
+ return ret;
+}
+
+static void __exit gpio_button_exit(void)
+{
+ platform_driver_unregister(&gpio_keys_driver);
+ platform_driver_unregister(&gpio_keys_polled_driver);
+}
+
+module_init(gpio_button_init);
+module_exit(gpio_button_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 0000000..cd2eb69
--- /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 +hostapd-common-old
+ KCONFIG:=CONFIG_HOSTAP CONFIG_HOSTAP_FIRMWARE=y CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+ FILES:=$(LINUX_DIR)/drivers/net/wireless/hostap/hostap.ko
+ AUTOLOAD:=$(call AutoProbe,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 AutoProbe,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 AutoProbe,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 AutoProbe,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 0000000..e35b76c
--- /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")"
+ ip link set dev "$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
+ ip link set dev "$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
+ ip link set dev "$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 0000000..94ca344
--- /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 0000000..8585a5a
--- /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 0000000..e2e3a68
--- /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 0000000..dcb2e2a
--- /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 0000000..921d290
--- /dev/null
+++ b/package/kernel/i2c-gpio-custom/src/i2c-gpio-custom.c
@@ -0,0 +1,202 @@
+/*
+ * 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-fw/Makefile b/package/kernel/lantiq/ltq-adsl-fw/Makefile
new file mode 100644
index 0000000..53d223b
--- /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 0000000..a76591c
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-mei/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:=ltq-adsl-mei
+PKG_RELEASE:=1
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-adsl-mei-$(BUILD_VARIANT)/
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_CHECK_FORMAT_SECURITY:=0
+
+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/patches/100_no-date-time.patch b/package/kernel/lantiq/ltq-adsl-mei/patches/100_no-date-time.patch
new file mode 100644
index 0000000..741c5b7
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-mei/patches/100_no-date-time.patch
@@ -0,0 +1,13 @@
+--- a/src/drv_mei_cpe_linux.c
++++ b/src/drv_mei_cpe_linux.c
+@@ -1400,8 +1400,8 @@ struct proc_entry {
+ static void MEI_GetVersionProc(struct seq_file *s)
+ {
+ seq_printf(s, "%s" MEI_DRV_CRLF, &MEI_WHATVERSION[4]);
+- seq_printf(s, "Compiled on %s, %s for Linux kernel %s (jiffies: %ld)" MEI_DRV_CRLF,
+- __DATE__, __TIME__, UTS_RELEASE, jiffies);
++ seq_printf(s, "Compiled on for Linux kernel %s (jiffies: %ld)" MEI_DRV_CRLF,
++ UTS_RELEASE, jiffies);
+ }
+
+ /**
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 0000000..2d8645f
--- /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 0000000..1098b2b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-mei/src/ifxmips_mei_interface.h
@@ -0,0 +1,724 @@
+/******************************************************************************
+
+ 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)
+
+static inline long
+ugly_hack_sleep_on_timeout(wait_queue_head_t *q, long timeout)
+{
+ unsigned long flags;
+ wait_queue_t wait;
+
+ init_waitqueue_entry(&wait, current);
+
+ __set_current_state(TASK_INTERRUPTIBLE);
+ spin_lock_irqsave(&q->lock, flags);
+ __add_wait_queue(q, &wait);
+ spin_unlock(&q->lock);
+
+ timeout = schedule_timeout(timeout);
+
+ spin_lock_irq(&q->lock);
+ __remove_wait_queue(q, &wait);
+ spin_unlock_irqrestore(&q->lock, flags);
+
+ return timeout;
+}
+
+/* wait for an event, timeout is measured in ms */
+#define MEI_WAIT_EVENT_TIMEOUT(ev,timeout)\
+ ugly_hack_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 0000000..561b300
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl-mei/src/lantiq_mei.c
@@ -0,0 +1,2840 @@
+/******************************************************************************
+
+ 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, 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;
+ }
+
+ if (((unsigned long)org_mem_ptr) & (1023)) {
+ /* Pointer not 1k aligned, so free it and allocate a larger chunk
+ * for further alignment.
+ */
+ kfree(org_mem_ptr);
+ 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 + 1024);
+ err = -ENOMEM;
+ goto allocate_error;
+ }
+ mem_ptr = (unsigned long) (org_mem_ptr + 1023) & ~(1024 -1);
+ } else {
+ mem_ptr = (unsigned long) org_mem_ptr;
+ }
+
+ 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;
+ char *org_mem_ptr = NULL;
+ 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;
+
+ org_mem_ptr = kmalloc (SDRAM_SEGMENT_SIZE, GFP_KERNEL);
+ if (org_mem_ptr == NULL) {
+ IFX_MEI_EMSG ("kmalloc memory fail!\n");
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ if (((unsigned long)org_mem_ptr) & (1023)) {
+ /* Pointer not 1k aligned, so free it and allocate a larger chunk
+ * for further alignment.
+ */
+ kfree(org_mem_ptr);
+ org_mem_ptr = kmalloc (SDRAM_SEGMENT_SIZE + 1024, GFP_KERNEL);
+ if (org_mem_ptr == NULL) {
+ IFX_MEI_EMSG ("kmalloc memory fail!\n");
+ retval = -ENOMEM;
+ goto error;
+ }
+ adsl_mem_info[XDATA_REGISTER].address =
+ (char *) ((unsigned long) (org_mem_ptr + 1023) & ~(1024 -1));
+ } else {
+ adsl_mem_info[XDATA_REGISTER].address = org_mem_ptr;
+ }
+
+ adsl_mem_info[XDATA_REGISTER].org_address = org_mem_ptr;
+ adsl_mem_info[XDATA_REGISTER].size = SDRAM_SEGMENT_SIZE;
+
+ 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 0000000..6d9caf4
--- /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 0000000..26c931e
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl/Makefile
@@ -0,0 +1,95 @@
+#
+# 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>
+
+PKG_USE_MIPS16:=0
+PKG_CHECK_FORMAT_SECURITY:=0
+PKG_FIXUP:=autoreconf
+
+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/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 0000000..f2ed230
--- /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 0000000..870943d
--- /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 0000000..48c7581
--- /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 0000000..bf758e0
--- /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-adsl/patches/140-linux_3.18.patch b/package/kernel/lantiq/ltq-adsl/patches/140-linux_3.18.patch
new file mode 100644
index 0000000..80f0854
--- /dev/null
+++ b/package/kernel/lantiq/ltq-adsl/patches/140-linux_3.18.patch
@@ -0,0 +1,40 @@
+--- a/src/include/drv_dsl_cpe_os_linux.h
++++ b/src/include/drv_dsl_cpe_os_linux.h
+@@ -214,12 +214,35 @@ static inline int dsl_mutex_lock(struct
+ #define DSL_DRV_MUTEX_LOCK(id) down_interruptible(&(id))
+ #define DSL_DRV_MUTEX_UNLOCK(id) up(&(id))
+ #endif
++
++static inline long
++ugly_hack_sleep_on_timeout(wait_queue_head_t *q, long timeout)
++{
++ unsigned long flags;
++ wait_queue_t wait;
++
++ init_waitqueue_entry(&wait, current);
++
++ __set_current_state(TASK_INTERRUPTIBLE);
++ spin_lock_irqsave(&q->lock, flags);
++ __add_wait_queue(q, &wait);
++ spin_unlock(&q->lock);
++
++ timeout = schedule_timeout(timeout);
++
++ spin_lock_irq(&q->lock);
++ __remove_wait_queue(q, &wait);
++ spin_unlock_irqrestore(&q->lock, flags);
++
++ return timeout;
++}
++
+ #define DSL_DRV_INIT_WAKELIST(name,queue) init_waitqueue_head(&(queue))
+ #define DSL_DRV_WAKEUP_WAKELIST(queue) wake_up_interruptible(&(queue))
+ #define DSL_DRV_INIT_EVENT(name,ev) init_waitqueue_head(&(ev))
+ /* wait for an event, timeout is measured in ms */
+-#define DSL_DRV_WAIT_EVENT_TIMEOUT(ev,t) interruptible_sleep_on_timeout(&(ev), (t) * HZ / 1000)
+-#define DSL_DRV_WAIT_EVENT(ev) interruptible_sleep_on(&(ev))
++#define DSL_DRV_WAIT_EVENT_TIMEOUT(ev,t) ugly_hack_sleep_on_timeout(&(ev), (t) * HZ / 1000)
++#define DSL_DRV_WAIT_EVENT(ev) ugly_hack_sleep_on_timeout(&(ev), MAX_SCHEDULE_TIMEOUT)
+ #define DSL_DRV_WAKEUP_EVENT(ev) wake_up_interruptible(&(ev))
+ #define DSL_DRV_TimeMSecGet() DSL_DRV_ElapsedTimeMSecGet(0)
+ #define DSL_WAIT(ms) msleep(ms)
diff --git a/package/kernel/lantiq/ltq-atm/Makefile b/package/kernel/lantiq/ltq-atm/Makefile
new file mode 100644
index 0000000..9fe1b40
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/Makefile
@@ -0,0 +1,54 @@
+# 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 AutoProbe,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)
+define KernelPackage/ltq-atm-vr9
+ $(call KernelPackage/ltq-atm-template,vr9,xrx200)
+ AUTOLOAD:=
+endef
+
+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 0000000..3d68c8f
--- /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 0000000..6e8975b
--- /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 0000000..b68848b
--- /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 0000000..2f754c9
--- /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 0000000..9bab5b4
--- /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 0000000..b0a9c91
--- /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 0000000..5ee6d23
--- /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 0000000..0fc4789
--- /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 0000000..57b7586
--- /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 0000000..ff4e500
--- /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 0000000..87cbe5d
--- /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 0000000..dd010f5
--- /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 0000000..49be99e
--- /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 0000000..9bdefdb
--- /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 0000000..708d337
--- /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 0000000..99c351f
--- /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 0000000..412f605
--- /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 0000000..fae0252
--- /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 0000000..ee55fd7
--- /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 0000000..7aaaa8d
--- /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 0000000..144c396
--- /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 0000000..89c71e3
--- /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 0000000..658dfdc
--- /dev/null
+++ b/package/kernel/lantiq/ltq-atm/src/ltq_atm.c
@@ -0,0 +1,1925 @@
+/******************************************************************************
+**
+** 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))
+#if 0
+ || (vcc->qos.txtp.traffic_class == ATM_VBR_NRT && vcc->qos.txtp.scr > (port->tx_max_cell_rate - port->tx_current_cell_rate))
+#endif
+ || (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:
+#if 0
+ port->tx_current_cell_rate += vcc->qos.txtp.scr;
+#endif
+ 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:
+#if 0
+ port->tx_current_cell_rate -= vcc->qos.txtp.scr;
+#endif
+ 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;
+ #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 0
+ if ( qos->txtp.scr == 0 ) {
+#endif
+ /* disable shaper */
+ qsb_queue_vbr_parameter_table.bit.taus = 0;
+ qsb_queue_vbr_parameter_table.bit.ts = 0;
+#if 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;
+ }
+#endif
+ } 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 */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
+ ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, 0, "atm_mailbox_isr", &g_atm_priv_data);
+#else
+ ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, IRQF_DISABLED, "atm_mailbox_isr", &g_atm_priv_data);
+#endif
+ 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 0000000..add3009
--- /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_$(2) +kmod-crypto-manager
+ FILES:=$(PKG_BUILD_DIR)/ltq_deu_$(1).ko
+ AUTOLOAD:=$(call AutoProbe,ltq_deu_$(1))
+endef
+
+KernelPackage/ltq-deu-danube=$(call KernelPackage/ltq-deu-template,danube,xway)
+KernelPackage/ltq-deu-ar9=$(call KernelPackage/ltq-deu-template,ar9,xway)
+KernelPackage/ltq-deu-vr9=$(call KernelPackage/ltq-deu-template,vr9,xrx200)
+
+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 0000000..f6cb9c9
--- /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 0000000..bf77537
--- /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 0000000..ee56187
--- /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 0000000..64536da
--- /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 0000000..9c593ae
--- /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 0000000..dcf6c18
--- /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 0000000..05f1681
--- /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 0000000..c842d64
--- /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 0000000..9dc3e30
--- /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 0000000..1d84da3
--- /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 0000000..492391d
--- /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 0000000..62ad96d
--- /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 0000000..13dc921
--- /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 0000000..5198a4a
--- /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 0000000..aaa7bce
--- /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 0000000..d2cfd11
--- /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 0000000..591389f
--- /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 0000000..fc6f52e
--- /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 0000000..a5f5f90
--- /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 0000000..a5a6c39
--- /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 0000000..1e7047b
--- /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 0000000..27fe9a9
--- /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 0000000..2d22636
--- /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 0000000..054cac3
--- /dev/null
+++ b/package/kernel/lantiq/ltq-deu/src/ltq_deu_testmgr.c
@@ -0,0 +1,3961 @@
+/*
+ * 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()
+ */
+
+#ifndef INIT_COMPLETION
+#define INIT_COMPLETION(a) reinit_completion(&a)
+#endif
+
+
+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 0000000..d3a373d
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/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-hcd
+PKG_RELEASE:=1
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-hcd-$(BUILD_VARIANT)
+
+PKG_USE_MIPS16:=0
+
+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 AutoProbe,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)
+
+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))
diff --git a/package/kernel/lantiq/ltq-hcd/src/Kconfig b/package/kernel/lantiq/ltq-hcd/src/Kconfig
new file mode 100644
index 0000000..2a3a38d
--- /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 0000000..64fa9c5
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/Makefile
@@ -0,0 +1,74 @@
+ltq_hcd_$(BUILD_VARIANT)-objs := ifxusb_driver.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 0000000..3fb00e0
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxhcd.c
@@ -0,0 +1,2138 @@
+/*****************************************************************************
+ ** 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_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 0000000..243c5f5
--- /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 0000000..a7d18dd
--- /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 0000000..27885bb
--- /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 0000000..a30fcd0
--- /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 0000000..9f02625
--- /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 0000000..5af988f
--- /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 0000000..19f7650
--- /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 0000000..1fcdebf
--- /dev/null
+++ b/package/kernel/lantiq/ltq-hcd/src/ifxusb_cif_h.c
@@ -0,0 +1,1595 @@
+/*****************************************************************************
+ ** 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_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_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_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_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 0000000..32878e3
--- /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 0000000..425b3a9
--- /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 > 0) {
+ 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_plat.h b/package/kernel/lantiq/ltq-hcd/src/ifxusb_plat.h
new file mode 100644
index 0000000..df959cf
--- /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 0000000..4b43821
--- /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 0000000..11e346e
--- /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 0000000..9919a9b
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ifxos/Makefile
@@ -0,0 +1,50 @@
+# 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.19
+PKG_RELEASE:=1
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=https://github.com/xdarklight/$(PKG_NAME)/archive/v$(PKG_VERSION)
+PKG_MD5SUM:=39eace039ae4c3dde4da96bfdbee2721
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+PKG_USE_MIPS16:=0
+PKG_FIXUP:=autoreconf
+
+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"
+
+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 0000000..dcd260e
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ifxos/patches/100-compat.patch
@@ -0,0 +1,158 @@
+--- a/src/linux/ifxos_linux_thread_drv.c
++++ b/src/linux/ifxos_linux_thread_drv.c
+@@ -38,6 +38,7 @@
+ #include <linux/smp_lock.h>
+ #endif
+ #include <linux/signal.h>
++#include <linux/kthread.h>
+
+
+ #include "ifx_types.h"
+@@ -70,10 +71,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
+ ========================================================================= */
+@@ -98,9 +95,9 @@ IFXOS_STATIC IFX_int32_t IFXOS_KernelThr
+ - 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;
+@@ -141,7 +138,7 @@ IFXOS_STATIC IFX_int32_t IFXOS_KernelThr
+ /* let others run */
+ unlock_kernel();
+ #else
+- daemonize(pThrCntrl->thrParams.pName);
++ //daemonize(pThrCntrl->thrParams.pName);
+
+ /* Enable signals in Kernel >= 2.6 */
+ allow_signal(SIGKILL);
+@@ -221,9 +218,7 @@ IFX_int32_t IFXOS_ThreadInit(
+ 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;
+
+--- a/src/include/ifxos_thread.h
++++ b/src/include/ifxos_thread.h
+@@ -111,7 +111,7 @@ typedef struct IFXOS_ThreadParams_s
+ /**
+ Function type of the user thread/task function.
+ */
+-typedef IFX_int32_t (*IFXOS_ThreadFunction_t)(IFXOS_ThreadParams_t *);
++typedef int (*IFXOS_ThreadFunction_t)(void*);
+
+ /** @} */
+
+--- a/src/include/linux/ifxos_linux_thread.h
++++ b/src/include/linux/ifxos_linux_thread.h
+@@ -152,7 +152,7 @@ typedef struct
+ IFXOS_ThreadFunction_t pThrFct;
+
+ /** Kernel thread process ID */
+- IFX_int32_t tid;
++ struct task_struct *tid;
+
+ /** requested kernel thread priority */
+ IFX_int32_t nPriority;
+--- a/src/linux/ifxos_linux_socket_drv.c
++++ b/src/linux/ifxos_linux_socket_drv.c
+@@ -19,6 +19,7 @@
+ /* ============================================================================
+ IFX Linux adaptation - Global Includes - Kernel
+ ========================================================================= */
++#include <linux/version.h>
+ #include <linux/kernel.h>
+ #ifdef MODULE
+ #include <linux/module.h>
+@@ -166,23 +167,33 @@ IFX_int_t IFXOS_SocketSendTo(
+ IFXOS_RETURN_IF_POINTER_NULL(pBuffer, IFX_ERROR);
+ IFXOS_RETURN_IF_ARG_LE_ZERO(bufSize_byte, IFX_ERROR);
+
++ iov.iov_base = pBuffer;
++ iov.iov_len = (unsigned int) bufSize_byte;
++
+ msg.msg_name = (void *) pSocAddr;
+ msg.msg_namelen = sizeof(IFXOS_sockAddr_t);
+- msg.msg_iov = &iov;
+- msg.msg_iovlen = 1;
+ msg.msg_control = IFX_NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = MSG_DONTWAIT;
+
+- msg.msg_iov->iov_base = pBuffer;
+- msg.msg_iov->iov_len = (unsigned int) bufSize_byte;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
++ msg.msg_iov = &iov;
++ msg.msg_iovlen = 1;
++#else
++ iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, bufSize_byte);
++#endif
+
+ /* Modify address limitation which is used if user space is calling
+ kernel space, otherwise sock_sendmsg() will fail.*/
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
+ ret = sock_sendmsg((struct socket *) socFd, &msg, bufSize_byte);
++#else
++ ret = sock_sendmsg((struct socket *) socFd, &msg);
++#endif
++
+ set_fs(old_fs);
+
+ return ret;
+--- a/src/linux/ifxos_linux_memory_map_drv.c
++++ b/src/linux/ifxos_linux_memory_map_drv.c
+@@ -25,6 +25,7 @@
+ IFX Linux adaptation - Global Includes - Kernel
+ ========================================================================= */
+
++#include <linux/version.h>
+ #include <linux/kernel.h>
+ #ifdef MODULE
+ #include <linux/module.h>
+@@ -87,6 +88,7 @@ IFX_int32_t IFXOS_Phy2VirtMap(
+ IFXOS_RETURN_IF_POINTER_NOT_NULL(*ppVirtAddr, IFX_ERROR);
+ IFXOS_RETURN_IF_ARG_LE_ZERO(addrRangeSize_byte, IFX_ERROR);
+
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)
+ if ( check_mem_region(physicalAddr, addrRangeSize_byte) )
+ {
+ IFXOS_PRN_USR_ERR_NL( IFXOS, IFXOS_PRN_LEVEL_ERR,
+@@ -98,6 +100,16 @@ IFX_int32_t IFXOS_Phy2VirtMap(
+
+ /* can't fail */
+ request_mem_region(physicalAddr, addrRangeSize_byte, pName);
++#else
++ if ( !request_mem_region(physicalAddr, addrRangeSize_byte, pName) )
++ {
++ IFXOS_PRN_USR_ERR_NL( IFXOS, IFXOS_PRN_LEVEL_ERR,
++ ("IFXOS: ERROR Phy2Virt map, region request - addr 0x%08lX (size 0x%lX) not free" IFXOS_CRLF,
++ physicalAddr, addrRangeSize_byte));
++
++ return IFX_ERROR;
++ }
++#endif
+
+ /* remap memory (not cache able): physical --> virtual */
+ pVirtAddr = (IFX_uint8_t *)ioremap_nocache( physicalAddr,
diff --git a/package/kernel/lantiq/ltq-ptm/Makefile b/package/kernel/lantiq/ltq-ptm/Makefile
new file mode 100644
index 0000000..2792de6
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/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-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
+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,xrx200)
+
+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 0000000..0d0bda5
--- /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 0000000..38001c3
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.c
@@ -0,0 +1,1555 @@
+/******************************************************************************
+**
+** 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)
+{
+#if defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
+ 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
+
+ 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], NET_NAME_UNKNOWN, 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 */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
+ ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, 0, "ptm_mailbox_isr", &g_ptm_priv_data);
+#else
+ ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, IRQF_DISABLED, "ptm_mailbox_isr", &g_ptm_priv_data);
+#endif
+ 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 0000000..de307bf
--- /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 0000000..077c900
--- /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 0000000..777d5cf
--- /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 0000000..00d4177
--- /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 0
+
+#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 0000000..279b03b
--- /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 0000000..ae33bcc
--- /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 0000000..a61d313
--- /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 0000000..3451682
--- /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 0000000..d6bdfd9
--- /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 0000000..1219b6b
--- /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 0000000..43f4da9
--- /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 0000000..d8685f3
--- /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 0000000..e357197
--- /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 0000000..a640cfb
--- /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 0000000..c9f0893
--- /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 0000000..f912039
--- /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 0000000..9355747
--- /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 0000000..63a5a37
--- /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 0000000..5f896e6
--- /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 0000000..4a8c2f7
--- /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 0000000..15d8352
--- /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 0000000..9adeba4
--- /dev/null
+++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.c
@@ -0,0 +1,1084 @@
+/******************************************************************************
+**
+** 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 (work_done < budget) {
+ 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], NET_NAME_UNKNOWN, 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 */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
+ ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, 0, "ptm_mailbox_isr", &g_ptm_priv_data);
+#else
+ ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, IRQF_DISABLED, "ptm_mailbox_isr", &g_ptm_priv_data);
+#endif
+ 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 0000000..b06232d
--- /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 0000000..0a02569
--- /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 0000000..84dbef2
--- /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 0000000..87960ca
--- /dev/null
+++ b/package/kernel/lantiq/ltq-tapi/Makefile
@@ -0,0 +1,68 @@
+#
+# 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>
+
+PKG_USE_MIPS16:=0
+PKG_CHECK_FORMAT_SECURITY:=0
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-tapi
+ SUBMENU:=Voice over IP
+ TITLE:=Lantiq TAPI subsystem
+ URL:=http://www.lantiq.com/
+ DEPENDS:=@(TARGET_lantiq_falcon||TARGET_lantiq_xway) +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/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 0000000..78fcbad
--- /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 0000000..a9c0d81
--- /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 0000000..9d7428d
--- /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-tapi/patches/300-linux-310.patch b/package/kernel/lantiq/ltq-tapi/patches/300-linux-310.patch
new file mode 100644
index 0000000..ac72515
--- /dev/null
+++ b/package/kernel/lantiq/ltq-tapi/patches/300-linux-310.patch
@@ -0,0 +1,13 @@
+Index: drv_tapi-3.13.0/src/drv_tapi_linux.c
+===================================================================
+--- drv_tapi-3.13.0.orig/src/drv_tapi_linux.c 2013-09-05 22:28:16.868419283 +0200
++++ drv_tapi-3.13.0/src/drv_tapi_linux.c 2013-09-05 22:32:37.396425814 +0200
+@@ -93,6 +93,8 @@
+ #include "drv_tapi_announcements.h"
+ #endif /* TAPI_ANNOUNCEMENTS */
+
++#undef CONFIG_PROC_FS
++
+ #define TAPI_IOCTL_STACKSIZE 4000 /* allow some overhead 4 k */
+
+ /* ================================== */
diff --git a/package/kernel/lantiq/ltq-vdsl-fw/Makefile b/package/kernel/lantiq/ltq-vdsl-fw/Makefile
new file mode 100644
index 0000000..6404067
--- /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_xrx200 +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 0000000..cb83453
--- /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 0000000..2870eeb
--- /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 0000000..9c27290
--- /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 0000000..7dce056
--- /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 0000000..2f9a3ff
--- /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 0000000..2d50aaf
--- /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 0000000..4572abc
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-fw/src/vdsl_fw_install.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+. /lib/functions.sh
+
+FW="/tmp/Firmware_Speedport_W921V_1.21.000.bin"
+URL="http://hilfe.telekom.de/dlp/eki/downloads/Speedport/Speedport%20W%20921V/Firmware_Speedport_W921V_1.21.000.bin"
+FW_TAPI="vr9_tapi_fw.bin"
+FW_DSL="vr9_dsl_fw_annex_b.bin"
+MD5_FW="0a099d08dbf091c74d685b532cbb1390"
+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
+}
+
+cd /tmp
+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
+}
+
+MTD=$(find_mtd_index dsl_fw)
+if [ "$MTD" -gt 0 -a -e "/dev/mtd$MTD" ]; then
+ echo "Storing firmware in flash"
+ tar cvz ${FW_TAPI} ${FW_DSL} | mtd write - "/dev/mtd$MTD"
+ /etc/init.d/dsl_fs boot
+else
+ cp ${FW_TAPI} ${FW_DSL} /lib/firmware/
+ ln -s /lib/firmware/vr9_dsl_fw_annex_b.bin /lib/firmware/vdsl.bin
+fi
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 0000000..fcd0106
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-fw/src/w921v_fw_cutter.c
@@ -0,0 +1,165 @@
+/*
+ * This program is free software; 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.21.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(unsigned int 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;
+ unsigned char *buf_orig;
+ unsigned int *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.21.000.bin\n");
+ return -1;
+ }
+
+ buf_orig = malloc(s.st_size);
+ buf = malloc(s.st_size);
+ if (!buf_orig || !buf) {
+ 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);
+ memcpy(buf, buf_orig, s.st_size);
+
+ /* </magic> */
+ do {
+ if (buf[end] == MAGIC_PART) {
+ end += 2;
+ printf("Found partition at 0x%08X with size %d\n",
+ start * sizeof(unsigned int),
+ (end - start) * sizeof(unsigned int));
+ if (buf[start] == MAGIC_LZMA) {
+ int dest_len = 1024 * 1024;
+ int len = buf[end - 3];
+ unsigned int id = buf[end - 6];
+ const char *type = part_type(id);
+ unsigned char *dest;
+
+ dest = malloc(dest_len);
+ if (!dest) {
+ printf("Failed to alloc dest buffer\n");
+ return -1;
+ }
+
+ if (lzma_inflate((unsigned char*)&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(unsigned int));
+
+ 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 0000000..0f9f48d
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-mei/Makefile
@@ -0,0 +1,67 @@
+# 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.4.8.4
+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_SOURCE_URL:=https://github.com/xdarklight/$(PKG_BASE_NAME)/archive/v$(PKG_VERSION)
+PKG_MD5SUM:=30570722dc7f19ff2f0228838043f2a2
+PKG_FIXUP:=autoreconf
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_USE_MIPS16:=0
+PKG_CHECK_FORMAT_SECURITY:=0
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/ltq-vdsl-vr9-mei
+ TITLE:=mei driver for vdsl
+ SECTION:=sys
+ SUBMENU:=Network Devices
+ DEPENDS:=@TARGET_lantiq_xrx200 +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
+
+MAKE_FLAGS += \
+ SHELL="$(BASH)"
+
+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 -DMEI_EXPORT_INTERNAL_API=1 -DMEI_SUPPORT_DSM=0 -fno-pic -mno-abicalls -mlong-calls -O2 -g0" \
+ --enable-linux-26 \
+ --enable-kernelbuild="$(LINUX_DIR)" \
+ --enable-drv_test_appl=0 \
+ 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 0000000..c0e69a9
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-mei/patches/100-compat.patch
@@ -0,0 +1,277 @@
+--- a/src/drv_mei_cpe_common.c
++++ b/src/drv_mei_cpe_common.c
+@@ -19,7 +19,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"
+
+--- a/src/drv_mei_cpe_linux.h
++++ b/src/drv_mei_cpe_linux.h
+@@ -51,12 +51,6 @@
+ #include <linux/poll.h>
+ #include <linux/types.h>
+
+-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
+- #include <asm/ifx/ifx_types.h>
+-#else
+- #include <ifx_types.h>
+-#endif
+-
+ #endif /* #if (MEI_DRV_IFXOS_ENABLE == 0)*/
+
+ /* ============================================================================
+--- a/src/drv_mei_cpe_linux.c
++++ b/src/drv_mei_cpe_linux.c
+@@ -98,6 +98,8 @@
+
+ #include "drv_mei_cpe_api_atm_ptm_intern.h"
+
++#include <lantiq_soc.h>
++
+ /* ===================================
+ extern function declarations
+ =================================== */
+@@ -1783,7 +1785,9 @@ static int __init MEI_module_init (void)
+ return (result);
+ }
+
++#if 0
+ ppa_callback_set(LTQ_MEI_SHOWTIME_CHECK, (void *)ltq_mei_atm_showtime_check);
++#endif
+
+ return 0;
+ }
+@@ -1963,7 +1967,9 @@ static void MEI_module_exit (void)
+ ("MEI_DRV: Chipset Basic Exit failed" MEI_DRV_CRLF));
+ }
+
++#if 0
+ ppa_callback_set(LTQ_MEI_SHOWTIME_CHECK, (void *)NULL);
++#endif
+
+ /* touch one time this variable to avoid that the linker will remove it */
+ debug_level = MEI_DRV_PRN_LEVEL_OFF;
+@@ -2120,21 +2126,32 @@ static int MEI_InitModuleBasics(void)
+ }
+
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
++
++#define PMU_DFE BIT(9)
++
+ static int MEI_SysClkEnable(struct clk *clk)
+ {
++#if 0
+ if (IS_ERR(clk))
+ return -1;
+ clk_enable(clk);
++#else
++ ltq_pmu_enable(PMU_DFE);
++#endif
+
+ return 0;
+ }
+
+ static int MEI_SysClkDisable(struct clk *clk)
+ {
++#if 0
+ if (IS_ERR(clk))
+ return -1;
+ clk_disable(clk);
+ clk_put(clk);
++#else
++ ltq_pmu_disable(PMU_DFE);
++#endif
+
+ return 0;
+ }
+@@ -2454,11 +2471,15 @@ IFX_int32_t MEI_IoctlInitDevice(
+ pMeiDev->eModePoll = e_MEI_DEV_ACCESS_MODE_IRQ;
+ pMeiDev->intMask = ME_ARC2ME_INTERRUPT_UNMASK_ALL;
+
++#if 1
++ virq = (IFX_uint32_t)pInitDev->usedIRQ;
++#else
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
+ virq = (IFX_uint32_t)pInitDev->usedIRQ;
+ #else
+ virq = irq_create_mapping(NULL, (IFX_uint32_t)pInitDev->usedIRQ);
+ #endif
++#endif
+
+ pTmpXCntrl = MEI_VrxXDevToIrqListAdd(
+ MEI_DRV_LINENUM_GET(pMeiDev),
+--- a/src/drv_mei_cpe_api_atm_ptm_intern.c
++++ b/src/drv_mei_cpe_api_atm_ptm_intern.c
+@@ -193,6 +193,51 @@ int ifx_mei_atm_led_blink(void)
+ return IFX_SUCCESS;
+ }
+
++#if MEI_MAX_DFE_CHAN_DEVICES > 1
++#error "Compat functions do not support MEI_MAX_DFE_CHAN_DEVICES > 1 yet"
++#else
++int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *) = NULL;
++int (*ifx_mei_atm_showtime_exit)(void) = NULL;
++
++ltq_ifx_mei_atm_showtime_enter_compat(IFX_uint8_t dslLineNum,
++ struct port_cell_info *cellInfo,
++ void *xdata) {
++ if (ifx_mei_atm_showtime_enter)
++ return ifx_mei_atm_showtime_enter(cellInfo, xdata);
++
++ return -e_MEI_ERR_OP_FAILED;
++}
++
++ltq_ifx_mei_atm_showtime_exit_compat(IFX_uint8_t dslLineNum) {
++ if (ifx_mei_atm_showtime_exit)
++ return ifx_mei_atm_showtime_exit();
++
++ return -e_MEI_ERR_OP_FAILED;
++}
++
++void* ppa_callback_get(e_ltq_mei_cb_type type) {
++ switch (type) {
++ case LTQ_MEI_SHOWTIME_ENTER:
++ return &ltq_ifx_mei_atm_showtime_enter_compat;
++ case LTQ_MEI_SHOWTIME_EXIT:
++ return &ltq_ifx_mei_atm_showtime_exit_compat;
++ break;
++ }
++
++ BUG();
++}
++
++int ifx_mei_atm_showtime_check(int *is_showtime,
++ struct port_cell_info *port_cell,
++ void **xdata_addr) {
++ return ltq_mei_atm_showtime_check(0, is_showtime, port_cell, xdata_addr);
++}
++
++EXPORT_SYMBOL(ifx_mei_atm_showtime_enter);
++EXPORT_SYMBOL(ifx_mei_atm_showtime_exit);
++EXPORT_SYMBOL(ifx_mei_atm_showtime_check);
++#endif
++
+ EXPORT_SYMBOL (MEI_InternalXtmSwhowtimeEntrySignal);
+ EXPORT_SYMBOL (MEI_InternalXtmSwhowtimeExitSignal);
+ EXPORT_SYMBOL(ifx_mei_atm_led_blink);
+--- a/src/drv_mei_cpe_api_atm_ptm_intern.h
++++ b/src/drv_mei_cpe_api_atm_ptm_intern.h
+@@ -21,7 +21,6 @@
+
+ #include "drv_mei_cpe_config.h"
+ #include "drv_mei_cpe_interface.h"
+-#include <net/ppa_stack_al.h>
+
+ #if (MEI_EXPORT_INTERNAL_API == 1) && (MEI_DRV_ATM_PTM_INTERFACE_ENABLE == 1)
+
+@@ -42,8 +41,20 @@ extern IFX_int32_t MEI_InternalXtmSwhowt
+ MEI_DYN_CNTRL_T *pMeiDynCntrl,
+ MEI_XTM_ShowtimeExit_t *pArgXtm);
+
++#if 1
++typedef enum {
++ LTQ_MEI_SHOWTIME_ENTER,
++ LTQ_MEI_SHOWTIME_EXIT
++} e_ltq_mei_cb_type;
++
++typedef void (*ltq_mei_atm_showtime_enter_t)(IFX_uint8_t, struct port_cell_info *, void *);
++typedef void (*ltq_mei_atm_showtime_exit_t)(IFX_uint8_t);
++
++void* ppa_callback_get(e_ltq_mei_cb_type type);
++#else
+ extern int ppa_callback_set(e_ltq_mei_cb_type type, void *func);
+ extern void* ppa_callback_get(e_ltq_mei_cb_type type);
++#endif
+
+ int ltq_mei_atm_showtime_check (
+ const unsigned char line_idx,
+--- a/src/drv_mei_cpe_device_vrx.c
++++ b/src/drv_mei_cpe_device_vrx.c
+@@ -27,13 +27,6 @@
+ #include "drv_mei_cpe_mei_interface.h"
+ #include "drv_mei_cpe_api.h"
+
+-#if defined(LINUX)
+-# if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
+-# include "ifx_pcie.h"
+-# else
+-# include "lantiq_pcie.h"
+-# endif
+-#endif /* #if defined(LINUX)*/
+
+ IFX_int32_t MEI_GPIntProcess(MEI_MeiRegVal_t processInt, MEI_DEV_T *pMeiDev)
+ {
+@@ -81,6 +74,7 @@ IFX_int32_t MEI_GetChipInfo(MEI_DEV_T *p
+ */
+ IFX_int32_t MEI_VR10_PcieEntitiesCheck(IFX_uint8_t nEntityNum)
+ {
++#if 0
+ IFX_uint32_t pcie_entitiesNum;
+
+ /* get information from pcie driver */
+@@ -101,6 +95,9 @@ IFX_int32_t MEI_VR10_PcieEntitiesCheck(I
+ }
+
+ return IFX_SUCCESS;
++#else
++ return IFX_ERROR;
++#endif
+ }
+
+ /**
+@@ -115,6 +112,7 @@ IFX_int32_t MEI_VR10_PcieEntitiesCheck(I
+ */
+ IFX_int32_t MEI_VR10_PcieEntityInit(MEI_MEI_DRV_CNTRL_T *pMeiDrvCntrl)
+ {
++#if 0
+ IFX_uint8_t entityNum;
+ ifx_pcie_ep_dev_t MEI_pcie_ep_dev;
+
+@@ -137,6 +135,9 @@ IFX_int32_t MEI_VR10_PcieEntityInit(MEI_
+ pMeiDrvCntrl->MEI_pcie_irq = MEI_pcie_ep_dev.irq;
+
+ return IFX_SUCCESS;
++#else
++ return IFX_ERROR;
++#endif
+ }
+
+ /**
+@@ -151,6 +152,7 @@ IFX_int32_t MEI_VR10_PcieEntityInit(MEI_
+ */
+ IFX_int32_t MEI_VR10_PcieEntityFree(IFX_uint8_t entityNum)
+ {
++#if 0
+ if (ifx_pcie_ep_dev_info_release(entityNum))
+ {
+ PRN_ERR_USR_NL( MEI_DRV, MEI_DRV_PRN_LEVEL_ERR,
+@@ -160,6 +162,9 @@ IFX_int32_t MEI_VR10_PcieEntityFree(IFX_
+ }
+
+ return IFX_SUCCESS;
++#else
++ return IFX_ERROR;
++#endif
+ }
+
+ /**
+@@ -174,6 +179,7 @@ IFX_int32_t MEI_VR10_PcieEntityFree(IFX_
+ */
+ IFX_int32_t MEI_VR10_InternalInitDevice(MEI_DYN_CNTRL_T *pMeiDynCntrl)
+ {
++#if 0
+ IFX_int32_t retVal;
+ IOCTL_MEI_devInit_t InitDev;
+ MEI_DEV_T *pMeiDev = pMeiDynCntrl->pMeiDev;
+@@ -198,5 +204,8 @@ IFX_int32_t MEI_VR10_InternalInitDevice(
+ *MEI_GPIO_U32REG(GPIO_P0_ALSEL1) &= ~((1 << 0) | (1 << 3) | (1 << 8));
+
+ return IFX_SUCCESS;
++#else
++ return IFX_ERROR;
++#endif
+ }
+
diff --git a/package/kernel/lantiq/ltq-vdsl-mei/patches/101_no-date-time.patch b/package/kernel/lantiq/ltq-vdsl-mei/patches/101_no-date-time.patch
new file mode 100644
index 0000000..219243f
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl-mei/patches/101_no-date-time.patch
@@ -0,0 +1,13 @@
+--- a/src/drv_mei_cpe_linux.c
++++ b/src/drv_mei_cpe_linux.c
+@@ -1400,8 +1400,8 @@ struct proc_entry {
+ static void MEI_GetVersionProc(struct seq_file *s)
+ {
+ seq_printf(s, "%s" MEI_DRV_CRLF, &MEI_WHATVERSION[4]);
+- seq_printf(s, "Compiled on %s, %s for Linux kernel %s (jiffies: %ld)" MEI_DRV_CRLF,
+- __DATE__, __TIME__, UTS_RELEASE, jiffies);
++ seq_printf(s, "Compiled for Linux kernel %s (jiffies: %ld)" MEI_DRV_CRLF,
++ UTS_RELEASE, jiffies);
+ }
+
+ /**
diff --git a/package/kernel/lantiq/ltq-vdsl/Makefile b/package/kernel/lantiq/ltq-vdsl/Makefile
new file mode 100644
index 0000000..617d9bf
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl/Makefile
@@ -0,0 +1,76 @@
+# 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.16.2.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)/$(PKG_BASE_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=https://github.com/xdarklight/$(PKG_BASE_NAME)/archive/v$(PKG_VERSION)
+PKG_MD5SUM:=0a3e35d199eb8936f3e8f61bb074223a
+
+PKG_USE_MIPS16:=0
+
+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_xrx200 +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
+
+MAKE_FLAGS += \
+ SHELL="$(BASH)"
+
+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-vrx-device=vr9 \
+ --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" \
+ --enable-adsl-led=no \
+ --enable-adsl-mib=no \
+ --enable-dsl-ceoc=no \
+ --enable-dsl-bonding=no \
+ --enable-linux-26 \
+ --enable-kernelbuild="$(LINUX_DIR)" \
+ --enable-debug-prints=no \
+ 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 0000000..e68a6f0
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vdsl/patches/100-compat.patch
@@ -0,0 +1,80 @@
+--- a/src/Makefile.in
++++ b/src/Makefile.in
+@@ -63,7 +63,7 @@ POST_UNINSTALL = :
+
+ # 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_6 = -Wpointer-arith
++@KERNEL_2_6_FALSE@am__append_6 =
+ subdir = src
+ DIST_COMMON = $(drv_dsl_cpe_api_include_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+--- a/src/common/drv_dsl_cpe_os_linux.c
++++ b/src/common/drv_dsl_cpe_os_linux.c
+@@ -11,6 +11,7 @@
+
+ #define DSL_INTERN
+
++#include <linux/device.h>
+ #include "drv_dsl_cpe_api.h"
+ #include "drv_dsl_cpe_api_ioctl.h"
+
+@@ -238,24 +239,10 @@ static DSL_long_t DSL_DRV_Ioctls(DSL_DRV
+ }
+
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
+- if (pFile->f_dentry != DSL_NULL)
+- {
+- pINode = pFile->f_dentry->d_inode;
+- }
+- else
+- {
+- pINode = DSL_NULL;
+- }
++ pINode = file_inode(pFile);
+ #endif
+
+- 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) ||
+@@ -1102,6 +1089,9 @@ static void DSL_DRV_DebugInit(void)
+ return;
+ }
+
++static struct class *dsl_class;
++static dev_t dsl_devt;
++
+ /* Entry point of driver */
+ int __init DSL_ModuleInit(void)
+ {
+@@ -1140,6 +1130,10 @@ int __init DSL_ModuleInit(void)
+
+ DSL_DRV_DevNodeInit();
+
++ dsl_class = class_create(THIS_MODULE, "dsl_cpe_api0");
++ dsl_devt = MKDEV(DRV_DSL_CPE_API_DEV_MAJOR, 0);
++ device_create(dsl_class, NULL, dsl_devt, NULL, "dsl_cpe_api0");
++
+ return 0;
+ }
+
+@@ -1147,6 +1141,11 @@ void __exit DSL_ModuleCleanup(void)
+ {
+ printk("Module will be unloaded"DSL_DRV_CRLF);
+
++ device_destroy(dsl_class, dsl_devt);
++ dsl_devt = NULL;
++ class_destroy(dsl_class);
++ dsl_class = NULL;
++
+ unregister_chrdev(nMajorNum, DRV_DSL_CPE_API_DEV_NAME);
+
+ DSL_DRV_Cleanup();
diff --git a/package/kernel/lantiq/ltq-vmmc/Config.in b/package/kernel/lantiq/ltq-vmmc/Config.in
new file mode 100644
index 0000000..89e1bc5
--- /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 0000000..9e21a05
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vmmc/Makefile
@@ -0,0 +1,168 @@
+#
+# 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>
+
+PKG_USE_MIPS16:=0
+PKG_CHECK_FORMAT_SECURITY:=0
+PKG_FIXUP:=autoreconf
+
+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:=@(TARGET_lantiq_falcon||TARGET_lantiq_xway) +kmod-ltq-tapi
+ FILES:=$(PKG_BUILD_DIR)/src/drv_vmmc.ko
+ AUTOLOAD:=$(call AutoProbe,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://downloads.openwrt.org/sources/
+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)
+ $(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 0000000..100a97d
--- /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 0000000..4860247
--- /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 0000000..cabd2d1
--- /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/200-compat.patch b/package/kernel/lantiq/ltq-vmmc/patches/200-compat.patch
new file mode 100644
index 0000000..70010c6
--- /dev/null
+++ b/package/kernel/lantiq/ltq-vmmc/patches/200-compat.patch
@@ -0,0 +1,56 @@
+--- a/src/drv_vmmc_linux.c
++++ b/src/drv_vmmc_linux.c
+@@ -54,6 +54,8 @@
+ #include "drv_vmmc_res.h"
+ #endif /* (VMMC_CFG_FEATURES & VMMC_FEAT_HDLC) */
+
++#undef VMMC_USE_PROC
++
+ /* ============================= */
+ /* Local Macros & Definitions */
+ /* ============================= */
+--- a/src/mps/drv_mps_vmmc_linux.c
++++ b/src/mps/drv_mps_vmmc_linux.c
+@@ -80,11 +80,15 @@
+ /* ============================= */
+ #define IFX_MPS_DEV_NAME "ifx_mps"
+
++#undef CONFIG_MPS_HISTORY_SIZE
++#define CONFIG_MPS_HISTORY_SIZE 0
+ #ifndef CONFIG_MPS_HISTORY_SIZE
+ #define CONFIG_MPS_HISTORY_SIZE 128
+ #warning CONFIG_MPS_HISTORY_SIZE should have been set via cofigure - setting to default 128
+ #endif
+
++#undef CONFIG_PROC_FS
++
+ /* ============================= */
+ /* Global variable definition */
+ /* ============================= */
+@@ -2257,7 +2261,7 @@ IFX_int32_t __init ifx_mps_init_module (
+ ifx_mps_reset ();
+ result = request_irq (INT_NUM_IM4_IRL18,
+ #ifdef LINUX_2_6
+- ifx_mps_ad0_irq, IRQF_DISABLED
++ ifx_mps_ad0_irq, 0x0
+ #else /* */
+ (irqreturn_t (*)(int, IFX_void_t *, struct pt_regs *))
+ ifx_mps_ad0_irq, SA_INTERRUPT
+@@ -2267,7 +2271,7 @@ IFX_int32_t __init ifx_mps_init_module (
+ return result;
+ result = request_irq (INT_NUM_IM4_IRL19,
+ #ifdef LINUX_2_6
+- ifx_mps_ad1_irq, IRQF_DISABLED
++ ifx_mps_ad1_irq, 0x0
+ #else /* */
+ (irqreturn_t (*)(int, IFX_void_t *, struct pt_regs *))
+ ifx_mps_ad1_irq, SA_INTERRUPT
+@@ -2282,7 +2286,7 @@ IFX_int32_t __init ifx_mps_init_module (
+ sprintf (&voice_channel_int_name[i][0], "mps_mbx vc%d", i);
+ result = request_irq (INT_NUM_IM4_IRL14 + i,
+ #ifdef LINUX_2_6
+- ifx_mps_vc_irq, IRQF_DISABLED
++ ifx_mps_vc_irq, 0x0
+ #else /* */
+ (irqreturn_t (*)
+ (int, IFX_void_t *,
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 0000000..d2afc65
--- /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
+@@ -2229,7 +2229,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;
+@@ -2259,7 +2259,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, 0x0
+ #else /* */
+@@ -2400,7 +2401,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/linux/Makefile b/package/kernel/linux/Makefile
new file mode 100644
index 0000000..05b0b5e
--- /dev/null
+++ b/package/kernel/linux/Makefile
@@ -0,0 +1,65 @@
+#
+# 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:=kernel
+PKG_FLAGS:=hold
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/packages
+SCAN_DEPS=modules/*.mk $(TOPDIR)/target/linux/*/modules.mk $(TOPDIR)/include/netfilter.mk
+
+PKG_LICENSE:=GPLv2
+PKG_LICENSE_FILES:=
+
+export SHELL:=/bin/sh
+.ONESHELL:
+
+include $(INCLUDE_DIR)/package.mk
+
+STAMP_BUILT:=$(STAMP_BUILT)_$(firstword $(shell $(SCRIPT_DIR)/kconfig.pl $(LINUX_DIR)/.config | md5sum))
+
+ifeq ($(DUMP),)
+ -include $(LINUX_DIR)/.config
+endif
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define KernelPackage/depends
+endef
+
+CONFIG_PACKAGE_kernel=y
+define Package/kernel
+ SECTION:=sys
+ CATEGORY:=Kernel
+ DEFAULT:=y
+ TITLE:=Virtual kernel package
+ VERSION:=$(LINUX_VERSION)-$(LINUX_RELEASE)-$(LINUX_VERMAGIC)
+ URL:=http://www.kernel.org/
+endef
+
+define Package/kernel/install
+ # nothing to do
+endef
+
+define Package/kernel/extra_provides
+ sed -e 's,.*/,,' $(LINUX_DIR)/modules.builtin;
+endef
+
+$(eval $(if $(DUMP),,$(call BuildPackage,kernel)))
+
+include $(sort $(wildcard ./modules/*.mk))
+-include $(TOPDIR)/target/linux/*/modules.mk
diff --git a/package/kernel/linux/modules/001-depends.mk b/package/kernel/linux/modules/001-depends.mk
new file mode 100644
index 0000000..806c3dc
--- /dev/null
+++ b/package/kernel/linux/modules/001-depends.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (C) 2010-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define AddDepends/nls
+ DEPENDS+= +kmod-nls-base $(foreach cp,$(1),+kmod-nls-$(cp))
+endef
+
+define AddDepends/rfkill
+ DEPENDS+= +USE_RFKILL:kmod-rfkill $(1)
+endef
diff --git a/package/kernel/linux/modules/block.mk b/package/kernel/linux/modules/block.mk
new file mode 100644
index 0000000..32e6165
--- /dev/null
+++ b/package/kernel/linux/modules/block.mk
@@ -0,0 +1,656 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+BLOCK_MENU:=Block Devices
+
+define KernelPackage/aoe
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=ATA over Ethernet support
+ KCONFIG:=CONFIG_ATA_OVER_ETH
+ FILES:=$(LINUX_DIR)/drivers/block/aoe/aoe.ko
+ AUTOLOAD:=$(call AutoLoad,30,aoe)
+endef
+
+define KernelPackage/aoe/description
+ Kernel support for ATA over Ethernet
+endef
+
+$(eval $(call KernelPackage,aoe))
+
+
+define KernelPackage/ata-core
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=Serial and Parallel ATA support
+ DEPENDS:=@PCI_SUPPORT||TARGET_sunxi +kmod-scsi-core
+ KCONFIG:=CONFIG_ATA
+ FILES:=$(LINUX_DIR)/drivers/ata/libata.ko
+ifneq ($(wildcard $(LINUX_DIR)/drivers/ata/libahci.ko),)
+ FILES+=$(LINUX_DIR)/drivers/ata/libahci.ko
+endif
+endef
+
+$(eval $(call KernelPackage,ata-core))
+
+
+define AddDepends/ata
+ SUBMENU:=$(BLOCK_MENU)
+ DEPENDS+=kmod-ata-core $(1)
+endef
+
+
+define KernelPackage/ata-ahci
+ TITLE:=AHCI Serial ATA support
+ KCONFIG:=CONFIG_SATA_AHCI
+ FILES:= \
+ $(LINUX_DIR)/drivers/ata/ahci.ko
+ AUTOLOAD:=$(call AutoLoad,41,libahci ahci,1)
+ $(call AddDepends/ata)
+endef
+
+define KernelPackage/ata-ahci/description
+ Support for AHCI Serial ATA controllers
+endef
+
+$(eval $(call KernelPackage,ata-ahci))
+
+
+define KernelPackage/ata-ahci-platform
+ TITLE:=AHCI Serial ATA Platform support
+ KCONFIG:=CONFIG_SATA_AHCI_PLATFORM
+ FILES:= \
+ $(LINUX_DIR)/drivers/ata/ahci_platform.ko \
+ $(LINUX_DIR)/drivers/ata/libahci_platform.ko
+ AUTOLOAD:=$(call AutoLoad,40,libahci libahci_platform ahci_platform,1)
+ $(call AddDepends/ata,@TARGET_ipq806x||TARGET_mvebu||TARGET_sunxi)
+endef
+
+define KernelPackage/ata-ahci-platform/description
+ Platform support for AHCI Serial ATA controllers
+endef
+
+$(eval $(call KernelPackage,ata-ahci-platform))
+
+
+define KernelPackage/ata-artop
+ TITLE:=ARTOP 6210/6260 PATA support
+ KCONFIG:=CONFIG_PATA_ARTOP
+ FILES:=$(LINUX_DIR)/drivers/ata/pata_artop.ko
+ AUTOLOAD:=$(call AutoLoad,41,pata_artop,1)
+ $(call AddDepends/ata)
+endef
+
+define KernelPackage/ata-artop/description
+ PATA support for ARTOP 6210/6260 host controllers
+endef
+
+$(eval $(call KernelPackage,ata-artop))
+
+
+define KernelPackage/ata-imx
+ TITLE:=Freescale i.MX AHCI SATA support
+ DEPENDS:=@TARGET_imx6
+ KCONFIG:=\
+ CONFIG_AHCI_IMX \
+ CONFIG_SATA_AHCI_PLATFORM \
+ CONFIG_PATA_IMX=n
+ FILES:=$(LINUX_DIR)/drivers/ata/ahci_imx.ko
+ AUTOLOAD:=$(call AutoLoad,41,ahci_imx,1)
+ $(call AddDepends/ata)
+endef
+
+define KernelPackage/ata-imx/description
+ SATA support for the Freescale i.MX6 SoC's onboard AHCI SATA
+endef
+
+$(eval $(call KernelPackage,ata-imx))
+
+
+define KernelPackage/ata-marvell-sata
+ TITLE:=Marvell Serial ATA support
+ KCONFIG:=CONFIG_SATA_MV
+ FILES:=$(LINUX_DIR)/drivers/ata/sata_mv.ko
+ AUTOLOAD:=$(call AutoLoad,41,sata_mv,1)
+ $(call AddDepends/ata)
+endef
+
+define KernelPackage/ata-marvell-sata/description
+ SATA support for marvell chipsets
+endef
+
+$(eval $(call KernelPackage,ata-marvell-sata))
+
+
+define KernelPackage/ata-mvebu-ahci
+ TITLE:=Marvell EBU AHCI support
+ DEPENDS:=@TARGET_mvebu +kmod-ata-ahci-platform
+ KCONFIG:=CONFIG_AHCI_MVEBU
+ FILES:=$(LINUX_DIR)/drivers/ata/ahci_mvebu.ko
+ AUTOLOAD:=$(call AutoLoad,41,ahci_mvebu,1)
+ $(call AddDepends/ata)
+endef
+
+define KernelPackage/ata-mvebu-ahci/description
+ AHCI support for Marvell EBU SoCs
+endef
+
+$(eval $(call KernelPackage,ata-mvebu-ahci))
+
+
+define KernelPackage/ata-nvidia-sata
+ TITLE:=Nvidia Serial ATA support
+ KCONFIG:=CONFIG_SATA_NV
+ FILES:=$(LINUX_DIR)/drivers/ata/sata_nv.ko
+ AUTOLOAD:=$(call AutoLoad,41,sata_nv,1)
+ $(call AddDepends/ata)
+endef
+
+$(eval $(call KernelPackage,ata-nvidia-sata))
+
+
+define KernelPackage/ata-oxnas-sata
+ TITLE:=oxnas Serial ATA support
+ KCONFIG:=CONFIG_SATA_OXNAS
+ DEPENDS:=@TARGET_oxnas
+ FILES:=$(LINUX_DIR)/drivers/ata/sata_oxnas.ko
+ AUTOLOAD:=$(call AutoLoad,41,sata_oxnas,1)
+ $(call AddDepends/ata)
+endef
+
+define KernelPackage/ata-oxnas-sata/description
+ SATA support for OX934 core found in the OX82x/PLX782x SoCs
+endef
+
+$(eval $(call KernelPackage,ata-oxnas-sata))
+
+
+define KernelPackage/ata-pdc202xx-old
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=Older Promise PATA controller support
+ DEPENDS:=kmod-ata-core
+ KCONFIG:= \
+ CONFIG_ATA_SFF=y \
+ CONFIG_PATA_PDC_OLD
+ FILES:=$(LINUX_DIR)/drivers/ata/pata_pdc202xx_old.ko
+ AUTOLOAD:=$(call AutoLoad,41,pata_pdc202xx_old,1)
+endef
+
+define KernelPackage/ata-pdc202xx-old/description
+ This option enables support for the Promise 20246, 20262, 20263,
+ 20265 and 20267 adapters
+endef
+
+$(eval $(call KernelPackage,ata-pdc202xx-old))
+
+
+define KernelPackage/ata-piix
+ TITLE:=Intel PIIX PATA/SATA support
+ KCONFIG:=CONFIG_ATA_PIIX
+ FILES:=$(LINUX_DIR)/drivers/ata/ata_piix.ko
+ AUTOLOAD:=$(call AutoLoad,41,ata_piix,1)
+ $(call AddDepends/ata)
+endef
+
+define KernelPackage/ata-piix/description
+ SATA support for Intel ICH5/6/7/8 series host controllers and
+ PATA support for Intel ESB/ICH/PIIX3/PIIX4 series host controllers
+endef
+
+$(eval $(call KernelPackage,ata-piix))
+
+
+define KernelPackage/ata-sil
+ TITLE:=Silicon Image SATA support
+ KCONFIG:=CONFIG_SATA_SIL
+ FILES:=$(LINUX_DIR)/drivers/ata/sata_sil.ko
+ AUTOLOAD:=$(call AutoLoad,41,sata_sil,1)
+ $(call AddDepends/ata)
+endef
+
+define KernelPackage/ata-sil/description
+ Support for Silicon Image Serial ATA controllers
+endef
+
+$(eval $(call KernelPackage,ata-sil))
+
+
+define KernelPackage/ata-sil24
+ TITLE:=Silicon Image 3124/3132 SATA support
+ KCONFIG:=CONFIG_SATA_SIL24
+ FILES:=$(LINUX_DIR)/drivers/ata/sata_sil24.ko
+ AUTOLOAD:=$(call AutoLoad,41,sata_sil24,1)
+ $(call AddDepends/ata)
+endef
+
+define KernelPackage/ata-sil24/description
+ Support for Silicon Image 3124/3132 Serial ATA controllers
+endef
+
+$(eval $(call KernelPackage,ata-sil24))
+
+
+define KernelPackage/ata-via-sata
+ TITLE:=VIA SATA support
+ KCONFIG:=CONFIG_SATA_VIA
+ FILES:=$(LINUX_DIR)/drivers/ata/sata_via.ko
+ AUTOLOAD:=$(call AutoLoad,41,sata_via,1)
+ $(call AddDepends/ata)
+endef
+
+define KernelPackage/ata-via-sata/description
+ This option enables support for VIA Serial ATA
+endef
+
+$(eval $(call KernelPackage,ata-via-sata))
+
+
+define KernelPackage/block2mtd
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=Block device MTD emulation
+ KCONFIG:=CONFIG_MTD_BLOCK2MTD
+ FILES:=$(LINUX_DIR)/drivers/mtd/devices/block2mtd.ko
+endef
+
+$(eval $(call KernelPackage,block2mtd))
+
+
+define KernelPackage/dm
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=Device Mapper
+ DEPENDS:=+kmod-crypto-manager
+ # All the "=n" are unnecessary, they're only there
+ # to stop the config from asking the question.
+ # MIRROR is M because I've needed it for pvmove.
+ KCONFIG:= \
+ CONFIG_BLK_DEV_MD=n \
+ CONFIG_DM_DEBUG=n \
+ CONFIG_DM_UEVENT=n \
+ CONFIG_DM_DELAY=n \
+ CONFIG_DM_LOG_WRITES=n \
+ CONFIG_DM_MQ_DEFAULT=n \
+ CONFIG_DM_MULTIPATH=n \
+ CONFIG_DM_ZERO=n \
+ CONFIG_DM_SNAPSHOT=n \
+ CONFIG_DM_LOG_USERSPACE=n \
+ CONFIG_MD=y \
+ CONFIG_BLK_DEV_DM \
+ CONFIG_DM_CRYPT \
+ CONFIG_DM_MIRROR
+ FILES:=$(LINUX_DIR)/drivers/md/dm-*.ko
+ AUTOLOAD:=$(call AutoLoad,30,dm-mod dm-log dm-region-hash dm-mirror dm-crypt)
+endef
+
+define KernelPackage/dm/description
+ Kernel module necessary for LVM2 support
+endef
+
+$(eval $(call KernelPackage,dm))
+
+
+define KernelPackage/md-mod
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=MD RAID
+ KCONFIG:= \
+ CONFIG_MD=y \
+ CONFIG_BLK_DEV_MD=m \
+ CONFIG_MD_AUTODETECT=y \
+ CONFIG_MD_FAULTY=n
+ FILES:=$(LINUX_DIR)/drivers/md/md-mod.ko
+ AUTOLOAD:=$(call AutoLoad,27,md-mod)
+endef
+
+define KernelPackage/md-mod/description
+ Kernel RAID md module (md-mod.ko).
+ You will need to select at least one RAID level module below.
+endef
+
+$(eval $(call KernelPackage,md-mod))
+
+
+define KernelPackage/md/Depends
+ SUBMENU:=$(BLOCK_MENU)
+ DEPENDS:=kmod-md-mod $(1)
+endef
+
+
+define KernelPackage/md-linear
+$(call KernelPackage/md/Depends,)
+ TITLE:=RAID Linear Module
+ KCONFIG:=CONFIG_MD_LINEAR
+ FILES:=$(LINUX_DIR)/drivers/md/linear.ko
+ AUTOLOAD:=$(call AutoLoad,28,linear)
+endef
+
+define KernelPackage/md-linear/description
+ RAID "Linear" or "Append" driver module (linear.ko)
+endef
+
+$(eval $(call KernelPackage,md-linear))
+
+
+define KernelPackage/md-raid0
+$(call KernelPackage/md/Depends,)
+ TITLE:=RAID0 Module
+ KCONFIG:=CONFIG_MD_RAID0
+ FILES:=$(LINUX_DIR)/drivers/md/raid0.ko
+ AUTOLOAD:=$(call AutoLoad,28,raid0)
+endef
+
+define KernelPackage/md-raid0/description
+ RAID Level 0 (Striping) driver module (raid0.ko)
+endef
+
+$(eval $(call KernelPackage,md-raid0))
+
+
+define KernelPackage/md-raid1
+$(call KernelPackage/md/Depends,)
+ TITLE:=RAID1 Module
+ KCONFIG:=CONFIG_MD_RAID1
+ FILES:=$(LINUX_DIR)/drivers/md/raid1.ko
+ AUTOLOAD:=$(call AutoLoad,28,raid1)
+endef
+
+define KernelPackage/md-raid1/description
+ RAID Level 1 (Mirroring) driver (raid1.ko)
+endef
+
+$(eval $(call KernelPackage,md-raid1))
+
+
+define KernelPackage/md-raid10
+$(call KernelPackage/md/Depends,)
+ TITLE:=RAID10 Module
+ KCONFIG:=CONFIG_MD_RAID10
+ FILES:=$(LINUX_DIR)/drivers/md/raid10.ko
+ AUTOLOAD:=$(call AutoLoad,28,raid10)
+endef
+
+define KernelPackage/md-raid10/description
+ RAID Level 10 (Mirroring+Striping) driver module (raid10.ko)
+endef
+
+$(eval $(call KernelPackage,md-raid10))
+
+
+define KernelPackage/md-raid456
+$(call KernelPackage/md/Depends,+kmod-lib-raid6 +kmod-lib-xor)
+ TITLE:=RAID Level 456 Driver
+ KCONFIG:= \
+ CONFIG_ASYNC_CORE \
+ CONFIG_ASYNC_MEMCPY \
+ CONFIG_ASYNC_XOR \
+ CONFIG_ASYNC_PQ \
+ CONFIG_ASYNC_RAID6_RECOV \
+ CONFIG_ASYNC_RAID6_TEST=n \
+ CONFIG_MD_RAID456 \
+ CONFIG_MULTICORE_RAID456=n
+ FILES:= \
+ $(LINUX_DIR)/crypto/async_tx/async_tx.ko \
+ $(LINUX_DIR)/crypto/async_tx/async_memcpy.ko \
+ $(LINUX_DIR)/crypto/async_tx/async_xor.ko \
+ $(LINUX_DIR)/crypto/async_tx/async_pq.ko \
+ $(LINUX_DIR)/crypto/async_tx/async_raid6_recov.ko \
+ $(LINUX_DIR)/drivers/md/raid456.ko
+ AUTOLOAD:=$(call AutoLoad,28, async_tx async_memcpy async_xor async_pq async_raid6_recov raid456)
+endef
+
+define KernelPackage/md-raid456/description
+ RAID Level 4,5,6 kernel module (raid456.ko)
+
+ Includes the following modules required by
+ raid456.ko:
+ xor.ko
+ async_tx.ko
+ async_xor.ko
+ async_memcpy.ko
+ async_pq.ko
+ async_raid5_recov.ko
+ raid6_pq.ko
+endef
+
+$(eval $(call KernelPackage,md-raid456))
+
+
+define KernelPackage/md-multipath
+$(call KernelPackage/md/Depends,)
+ TITLE:=MD Multipath Module
+ KCONFIG:=CONFIG_MD_MULTIPATH
+ FILES:=$(LINUX_DIR)/drivers/md/multipath.ko
+ AUTOLOAD:=$(call AutoLoad,29,multipath)
+endef
+
+define KernelPackage/md-multipath/description
+ Multipath driver module (multipath.ko)
+endef
+
+$(eval $(call KernelPackage,md-multipath))
+
+
+define KernelPackage/ide-core
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=IDE (ATA/ATAPI) device support
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:= \
+ CONFIG_IDE \
+ CONFIG_BLK_DEV_IDE \
+ CONFIG_BLK_DEV_IDEDISK \
+ CONFIG_IDE_GD \
+ CONFIG_IDE_GD_ATA=y \
+ CONFIG_IDE_GD_ATAPI=n \
+ CONFIG_IDEPCI_PCIBUS_ORDER=y \
+ CONFIG_BLK_DEV_IDEDMA_PCI=y \
+ CONFIG_BLK_DEV_IDEPCI=y
+ FILES:= \
+ $(LINUX_DIR)/drivers/ide/ide-core.ko \
+ $(LINUX_DIR)/drivers/ide/ide-gd_mod.ko
+endef
+
+define KernelPackage/ide-core/description
+ Kernel support for IDE, useful for usb mass storage devices (e.g. on WL-HDD)
+ Includes:
+ - ide-core
+ - ide-gd_mod
+endef
+
+$(eval $(call KernelPackage,ide-core))
+
+
+define AddDepends/ide
+ SUBMENU:=$(BLOCK_MENU)
+ DEPENDS+=kmod-ide-core $(1)
+endef
+
+
+define KernelPackage/ide-generic
+ SUBMENU:=$(BLOCK_MENU)
+ DEPENDS:=@PCI_SUPPORT
+ TITLE:=Kernel support for generic PCI IDE chipsets
+ KCONFIG:=CONFIG_BLK_DEV_GENERIC
+ FILES:=$(LINUX_DIR)/drivers/ide/ide-pci-generic.ko
+ AUTOLOAD:=$(call AutoLoad,30,ide-pci-generic,1)
+ $(call AddDepends/ide)
+endef
+
+$(eval $(call KernelPackage,ide-generic))
+
+
+define KernelPackage/ide-generic-old
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=Kernel support for generic (legacy) IDE chipsets
+ KCONFIG:=CONFIG_IDE_GENERIC
+ FILES:=$(LINUX_DIR)/drivers/ide/ide-generic.ko
+ AUTOLOAD:=$(call AutoLoad,30,ide-generic,1)
+ $(call AddDepends/ide)
+endef
+
+$(eval $(call KernelPackage,ide-generic-old))
+
+
+define KernelPackage/ide-aec62xx
+ TITLE:=Acard AEC62xx IDE driver
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_BLK_DEV_AEC62XX
+ FILES:=$(LINUX_DIR)/drivers/ide/aec62xx.ko
+ AUTOLOAD:=$(call AutoLoad,30,aec62xx,1)
+ $(call AddDepends/ide)
+endef
+
+define KernelPackage/ide-aec62xx/description
+ Support for Acard AEC62xx (Artop ATP8xx) IDE controllers
+endef
+
+$(eval $(call KernelPackage,ide-aec62xx,1))
+
+
+define KernelPackage/ide-pdc202xx
+ TITLE:=Promise PDC202xx IDE driver
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_BLK_DEV_PDC202XX_OLD
+ FILES:=$(LINUX_DIR)/drivers/ide/pdc202xx_old.ko
+ AUTOLOAD:=$(call AutoLoad,30,pdc202xx_old,1)
+ $(call AddDepends/ide)
+endef
+
+define KernelPackage/ide-pdc202xx/description
+ Support for the Promise Ultra 33/66/100 (PDC202{46|62|65|67|68}) IDE
+ controllers.
+endef
+
+$(eval $(call KernelPackage,ide-pdc202xx))
+
+
+define KernelPackage/ide-it821x
+ TITLE:=ITE IT821x IDE driver
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_BLK_DEV_IT821X
+ FILES=$(LINUX_DIR)/drivers/ide/it821x.ko
+ AUTOLOAD:=$(call AutoLoad,30,it821x,1)
+ $(call AddDepends/ide)
+endef
+
+define KernelPackage/ide-it821x/description
+ Kernel module for the ITE IDE821x IDE controllers
+endef
+
+$(eval $(call KernelPackage,ide-it821x))
+
+
+define KernelPackage/libsas
+ SUBMENU:=$(BLOCK_MENU)
+ DEPENDS:=@TARGET_x86
+ TITLE:=SAS Domain Transport Attributes
+ KCONFIG:=CONFIG_SCSI_SAS_LIBSAS \
+ CONFIG_SCSI_SAS_ATTRS \
+ CONFIG_SCSI_SAS_ATA=y \
+ CONFIG_SCSI_SAS_HOST_SMP=y \
+ CONFIG_SCSI_SAS_LIBSAS_DEBUG=y
+ FILES:= \
+ $(LINUX_DIR)/drivers/scsi/scsi_transport_sas.ko \
+ $(LINUX_DIR)/drivers/scsi/libsas/libsas.ko
+ AUTOLOAD:=$(call AutoLoad,29,scsi_transport_sas libsas,1)
+endef
+
+define KernelPackage/libsas/description
+ SAS Domain Transport Attributes support
+endef
+
+$(eval $(call KernelPackage,libsas,1))
+
+
+define KernelPackage/loop
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=Loopback device support
+ KCONFIG:= \
+ CONFIG_BLK_DEV_LOOP \
+ CONFIG_BLK_DEV_CRYPTOLOOP=n
+ FILES:=$(LINUX_DIR)/drivers/block/loop.ko
+ AUTOLOAD:=$(call AutoLoad,30,loop)
+endef
+
+define KernelPackage/loop/description
+ Kernel module for loopback device support
+endef
+
+$(eval $(call KernelPackage,loop))
+
+
+define KernelPackage/mvsas
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=Marvell 88SE6440 SAS/SATA driver
+ DEPENDS:=@TARGET_x86 +kmod-libsas
+ KCONFIG:= \
+ CONFIG_SCSI_MVSAS \
+ CONFIG_SCSI_MVSAS_TASKLET=n
+ FILES:=$(LINUX_DIR)/drivers/scsi/mvsas/mvsas.ko
+ AUTOLOAD:=$(call AutoLoad,40,mvsas,1)
+endef
+
+define KernelPackage/mvsas/description
+ Kernel support for the Marvell SAS SCSI adapters
+endef
+
+$(eval $(call KernelPackage,mvsas))
+
+
+define KernelPackage/nbd
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=Network block device support
+ KCONFIG:=CONFIG_BLK_DEV_NBD
+ FILES:=$(LINUX_DIR)/drivers/block/nbd.ko
+ AUTOLOAD:=$(call AutoLoad,30,nbd)
+endef
+
+define KernelPackage/nbd/description
+ Kernel module for network block device support
+endef
+
+$(eval $(call KernelPackage,nbd))
+
+
+define KernelPackage/scsi-core
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=SCSI device support
+ KCONFIG:= \
+ CONFIG_SCSI \
+ CONFIG_BLK_DEV_SD
+ FILES:= \
+ $(LINUX_DIR)/drivers/scsi/scsi_mod.ko \
+ $(LINUX_DIR)/drivers/scsi/sd_mod.ko
+ AUTOLOAD:=$(call AutoLoad,40,scsi_mod sd_mod,1)
+endef
+
+$(eval $(call KernelPackage,scsi-core))
+
+
+define KernelPackage/scsi-generic
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=Kernel support for SCSI generic
+ DEPENDS:=+kmod-scsi-core
+ KCONFIG:= \
+ CONFIG_CHR_DEV_SG
+ FILES:= \
+ $(LINUX_DIR)/drivers/scsi/sg.ko
+ AUTOLOAD:=$(call AutoLoad,65,sg)
+endef
+
+$(eval $(call KernelPackage,scsi-generic))
+
+
+define KernelPackage/scsi-cdrom
+ SUBMENU:=$(BLOCK_MENU)
+ TITLE:=Kernel support for CD / DVD drives
+ DEPENDS:=+kmod-scsi-core
+ KCONFIG:= \
+ CONFIG_BLK_DEV_SR \
+ CONFIG_BLK_DEV_SR_VENDOR=n
+ FILES:= \
+ $(LINUX_DIR)/drivers/cdrom/cdrom.ko \
+ $(LINUX_DIR)/drivers/scsi/sr_mod.ko
+ AUTOLOAD:=$(call AutoLoad,45,sr_mod)
+endef
+
+$(eval $(call KernelPackage,scsi-cdrom))
diff --git a/package/kernel/linux/modules/can.mk b/package/kernel/linux/modules/can.mk
new file mode 100644
index 0000000..eeef88a
--- /dev/null
+++ b/package/kernel/linux/modules/can.mk
@@ -0,0 +1,277 @@
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+CAN_MENU:=CAN Support
+
+define KernelPackage/can
+ SUBMENU:=$(CAN_MENU)
+ TITLE:=CAN bus support
+ KCONFIG:=\
+ CONFIG_CAN=m \
+ CONFIG_CAN_DEV \
+ CONFIG_CAN_CALC_BITTIMING=y \
+ CONFIG_CAN_LEDS=y \
+ CONFIG_CAN_AT91=n \
+ CONFIG_CAN_TI_HECC=n \
+ CONFIG_CAN_MCP251X=n \
+ CONFIG_CAN_BFIN=n \
+ CONFIG_CAN_JANZ_ICAN3=n \
+ CONFIG_PCH_CAN=n \
+ CONFIG_CAN_GRCAN=n \
+ CONFIG_CAN_CC770=n \
+ CONFIG_CAN_MSCAN=n \
+ CONFIG_CAN_SJA1000=n \
+ CONFIG_CAN_SOFTING=n \
+ CONFIG_CAN_XILINXCAN=n \
+ CONFIG_NET_EMATCH_CANID=n \
+ CONFIG_CAN_DEBUG_DEVICES=n
+ FILES:=$(LINUX_DIR)/drivers/net/can/can-dev.ko \
+ $(LINUX_DIR)/net/can/can.ko
+ AUTOLOAD:=$(call AutoProbe,can can-dev)
+endef
+
+define KernelPackage/can/description
+ Kernel module for CAN bus support.
+endef
+
+$(eval $(call KernelPackage,can))
+
+
+define AddDepends/can
+ SUBMENU:=$(CAN_MENU)
+ DEPENDS+=kmod-can $(1)
+endef
+
+
+define KernelPackage/can-raw
+ TITLE:=Raw CAN Protcol
+ KCONFIG:=CONFIG_CAN_RAW
+ FILES:=$(LINUX_DIR)/net/can/can-raw.ko
+ AUTOLOAD:=$(call AutoProbe,can-raw)
+ $(call AddDepends/can)
+endef
+
+define KernelPackage/can-raw/description
+ The raw CAN protocol option offers access to the CAN bus via
+ the BSD socket API.
+endef
+
+$(eval $(call KernelPackage,can-raw))
+
+
+define KernelPackage/can-bcm
+ TITLE:=Broadcast Manager CAN Protcol
+ KCONFIG:=CONFIG_CAN_BCM
+ FILES:=$(LINUX_DIR)/net/can/can-bcm.ko
+ AUTOLOAD:=$(call AutoProbe,can-bcm)
+ $(call AddDepends/can)
+endef
+
+define KernelPackage/can-bcm/description
+ The Broadcast Manager offers content filtering, timeout monitoring,
+ sending of RTR frames, and cyclic CAN messages without permanent user
+ interaction.
+endef
+
+$(eval $(call KernelPackage,can-bcm))
+
+
+define KernelPackage/can-gw
+ TITLE:=CAN Gateway/Router
+ KCONFIG:=CONFIG_CAN_GW
+ FILES:=$(LINUX_DIR)/net/can/can-gw.ko
+ AUTOLOAD:=$(call AutoProbe,can-gw)
+ $(call AddDepends/can)
+endef
+
+define KernelPackage/can-gw/description
+ The CAN Gateway/Router is used to route (and modify) CAN frames.
+endef
+
+$(eval $(call KernelPackage,can-gw))
+
+
+define KernelPackage/can-vcan
+ TITLE:=Virtual Local CAN Interface (vcan)
+ KCONFIG:=CONFIG_CAN_VCAN
+ FILES:=$(LINUX_DIR)/drivers/net/can/vcan.ko
+ AUTOLOAD:=$(call AutoProbe,vcan)
+ $(call AddDepends/can)
+endef
+
+define KernelPackage/can-vcan/description
+ Similar to the network loopback devices, vcan offers a
+ virtual local CAN interface.
+endef
+
+$(eval $(call KernelPackage,can-vcan))
+
+
+define KernelPackage/can-slcan
+ TITLE:=Serial / USB serial CAN Adaptors (slcan)
+ KCONFIG:=CONFIG_CAN_SLCAN
+ FILES:=$(LINUX_DIR)/drivers/net/can/slcan.ko
+ AUTOLOAD:=$(call AutoProbe,slcan)
+ $(call AddDepends/can)
+endef
+
+define KernelPackage/can-slcan/description
+ CAN driver for several 'low cost' CAN interfaces that are attached
+ via serial lines or via USB-to-serial adapters using the LAWICEL
+ ASCII protocol.
+endef
+
+$(eval $(call KernelPackage,can-slcan))
+
+
+define KernelPackage/can-flexcan
+ TITLE:=Support for Freescale FLEXCAN based chips
+ KCONFIG:=CONFIG_CAN_FLEXCAN
+ FILES:=$(LINUX_DIR)/drivers/net/can/flexcan.ko
+ AUTOLOAD:=$(call AutoProbe,flexcan)
+ $(call AddDepends/can,@TARGET_imx6)
+endef
+
+define KernelPackage/can-flexcan/description
+ Freescale FLEXCAN CAN bus controller implementation.
+endef
+
+$(eval $(call KernelPackage,can-flexcan))
+
+
+define KernelPackage/can-usb-ems
+ TITLE:=EMS CPC-USB/ARM7 CAN/USB interface
+ KCONFIG:=CONFIG_CAN_EMS_USB
+ FILES:=$(LINUX_DIR)/drivers/net/can/usb/ems_usb.ko
+ AUTOLOAD:=$(call AutoProbe,ems_usb)
+ $(call AddDepends/can,+kmod-usb-core)
+endef
+
+define KernelPackage/can-usb-ems/description
+ This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
+ from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
+endef
+
+$(eval $(call KernelPackage,can-usb-ems))
+
+
+define KernelPackage/can-usb-esd
+ TITLE:=ESD USB/2 CAN/USB interface
+ KCONFIG:=CONFIG_CAN_ESD_USB2
+ FILES:=$(LINUX_DIR)/drivers/net/can/usb/esd_usb2.ko
+ AUTOLOAD:=$(call AutoProbe,esd_usb2)
+ $(call AddDepends/can,+kmod-usb-core)
+endef
+
+define KernelPackage/can-usb-esd/description
+ This driver supports the CAN-USB/2 interface
+ from esd electronic system design gmbh (http://www.esd.eu).
+endef
+
+$(eval $(call KernelPackage,can-usb-esd))
+
+
+define KernelPackage/can-usb-kvaser
+ TITLE:=Kvaser CAN/USB interface
+ KCONFIG:=CONFIG_CAN_KVASER_USB
+ FILES:=$(LINUX_DIR)/drivers/net/can/usb/kvaser_usb.ko
+ AUTOLOAD:=$(call AutoProbe,kvaser_usb)
+ $(call AddDepends/can,+kmod-usb-core)
+endef
+
+define KernelPackage/can-usb-kvaser/description
+ This driver adds support for Kvaser CAN/USB devices like Kvaser
+ Leaf Light.
+endef
+
+$(eval $(call KernelPackage,can-usb-kvaser))
+
+
+define KernelPackage/can-usb-peak
+ TITLE:=PEAK PCAN-USB/USB Pro interfaces
+ KCONFIG:=CONFIG_CAN_PEAK_USB
+ FILES:=$(LINUX_DIR)/drivers/net/can/usb/peak_usb/peak_usb.ko
+ AUTOLOAD:=$(call AutoProbe,peak_usb)
+ $(call AddDepends/can,+kmod-usb-core)
+endef
+
+define KernelPackage/can-usb-peak/description
+ This driver supports the PCAN-USB and PCAN-USB Pro adapters
+ from PEAK-System Technik (http://www.peak-system.com).
+endef
+
+$(eval $(call KernelPackage,can-usb-peak))
+
+
+define KernelPackage/can-usb-8dev
+ TITLE:=8 devices USB2CAN interface
+ KCONFIG:=CONFIG_CAN_8DEV_USB
+ FILES:=$(LINUX_DIR)/drivers/net/can/usb/usb_8dev.ko
+ AUTOLOAD:=$(call AutoProbe,usb_8dev)
+ $(call AddDepends/can,+kmod-usb-core)
+endef
+
+define KernelPackage/can-usb-8dev/description
+ This driver supports the USB2CAN interface
+ from 8 devices (http://www.8devices.com).
+endef
+
+$(eval $(call KernelPackage,can-usb-8dev))
+
+
+define KernelPackage/can-c-can
+ TITLE:=BOSCH C_CAN/D_CAN drivers
+ KCONFIG:=CONFIG_CAN_C_CAN
+ FILES:=$(LINUX_DIR)/drivers/net/can/c_can/c_can.ko
+ AUTOLOAD:=$(call AutoProbe,c_can)
+ $(call AddDepends/can)
+endef
+
+define KernelPackage/can-c-can/description
+ This driver adds generic support for the C_CAN/D_CAN chips.
+endef
+
+$(eval $(call KernelPackage,can-c-can))
+
+
+define KernelPackage/can-c-can-platform
+ TITLE:=Platform Bus based BOSCH C_CAN/D_CAN driver
+ KCONFIG:=CONFIG_CAN_C_CAN_PLATFORM
+ DEPENDS:=kmod-can-c-can +LINUX_4_1:kmod-regmap
+ FILES:=$(LINUX_DIR)/drivers/net/can/c_can/c_can_platform.ko
+ AUTOLOAD:=$(call AutoProbe,c_can_platform)
+ $(call AddDepends/can)
+endef
+
+define KernelPackage/can-c-can-platform/description
+ This driver adds support for the C_CAN/D_CAN chips connected
+ to the "platform bus" (Linux abstraction for directly to the
+ processor attached devices) which can be found on various
+ boards from ST Microelectronics (http://www.st.com) like the
+ SPEAr1310 and SPEAr320 evaluation boards & TI (www.ti.com)
+ boards like am335x, dm814x, dm813x and dm811x.
+endef
+
+$(eval $(call KernelPackage,can-c-can-platform))
+
+
+define KernelPackage/can-c-can-pci
+ TITLE:=PCI Bus based BOSCH C_CAN/D_CAN driver
+ KCONFIG:=CONFIG_CAN_C_CAN_PCI
+ DEPENDS:=kmod-can-c-can @PCI_SUPPORT
+ FILES:=$(LINUX_DIR)/drivers/net/can/c_can/c_can_pci.ko
+ AUTOLOAD:=$(call AutoProbe,c_can_pci)
+ $(call AddDepends/can)
+endef
+
+define KernelPackage/can-c-can-pci/description
+ This driver adds support for the C_CAN/D_CAN chips connected
+ to the PCI bus.
+endef
+
+$(eval $(call KernelPackage,can-c-can-pci))
+
diff --git a/package/kernel/linux/modules/crypto.mk b/package/kernel/linux/modules/crypto.mk
new file mode 100644
index 0000000..20fc858
--- /dev/null
+++ b/package/kernel/linux/modules/crypto.mk
@@ -0,0 +1,627 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+CRYPTO_MENU:=Cryptographic API modules
+
+CRYPTO_MODULES = \
+ ALGAPI2=crypto_algapi \
+ BLKCIPHER2=crypto_blkcipher
+
+crypto_confvar=CONFIG_CRYPTO_$(word 1,$(subst =,$(space),$(1)))
+crypto_file=$(LINUX_DIR)/crypto/$(word 2,$(subst =,$(space),$(1))).ko
+crypto_name=$(if $(findstring y,$($(call crypto_confvar,$(1)))),,$(word 2,$(subst =,$(space),$(1))))
+
+define AddDepends/crypto
+ SUBMENU:=$(CRYPTO_MENU)
+ DEPENDS+= $(1)
+endef
+
+define KernelPackage/crypto-aead
+ TITLE:=CryptoAPI AEAD support
+ KCONFIG:= \
+ CONFIG_CRYPTO_AEAD \
+ CONFIG_CRYPTO_AEAD2
+ FILES:=$(LINUX_DIR)/crypto/aead.ko
+ AUTOLOAD:=$(call AutoLoad,09,aead,1)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-aead))
+
+
+define KernelPackage/crypto-hash
+ TITLE:=CryptoAPI hash support
+ KCONFIG:=CONFIG_CRYPTO_HASH
+ FILES:=$(LINUX_DIR)/crypto/crypto_hash.ko
+ AUTOLOAD:=$(call AutoLoad,02,crypto_hash,1)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-hash))
+
+
+define KernelPackage/crypto-manager
+ TITLE:=CryptoAPI algorithm manager
+ DEPENDS:=+kmod-crypto-aead +kmod-crypto-hash +kmod-crypto-pcompress
+ KCONFIG:= \
+ CONFIG_CRYPTO_MANAGER \
+ CONFIG_CRYPTO_MANAGER2
+ FILES:=$(LINUX_DIR)/crypto/cryptomgr.ko
+ AUTOLOAD:=$(call AutoLoad,09,cryptomgr,1)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-manager))
+
+
+define KernelPackage/crypto-pcompress
+ TITLE:=CryptoAPI Partial (de)compression operations
+ KCONFIG:= \
+ CONFIG_CRYPTO_PCOMP=y \
+ CONFIG_CRYPTO_PCOMP2
+ FILES:=$(LINUX_DIR)/crypto/pcompress.ko
+ AUTOLOAD:=$(call AutoLoad,09,pcompress)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-pcompress))
+
+
+define KernelPackage/crypto-user
+ TITLE:=CryptoAPI userspace interface
+ DEPENDS:=+kmod-crypto-hash +kmod-crypto-manager
+ KCONFIG:= \
+ CONFIG_CRYPTO_USER_API \
+ CONFIG_CRYPTO_USER_API_HASH \
+ CONFIG_CRYPTO_USER_API_SKCIPHER
+ FILES:= \
+ $(LINUX_DIR)/crypto/af_alg.ko \
+ $(LINUX_DIR)/crypto/algif_hash.ko \
+ $(LINUX_DIR)/crypto/algif_skcipher.ko
+ AUTOLOAD:=$(call AutoLoad,09,af_alg algif_hash algif_skcipher)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-user))
+
+
+define KernelPackage/crypto-wq
+ TITLE:=CryptoAPI work queue handling
+ KCONFIG:=CONFIG_CRYPTO_WORKQUEUE
+ FILES:=$(LINUX_DIR)/crypto/crypto_wq.ko
+ AUTOLOAD:=$(call AutoLoad,09,crypto_wq)
+ $(call AddDepends/crypto)
+endef
+$(eval $(call KernelPackage,crypto-wq))
+
+define KernelPackage/crypto-rng
+ TITLE:=CryptoAPI random number generation
+ KCONFIG:=CONFIG_CRYPTO_RNG2
+ FILES:=$(LINUX_DIR)/crypto/rng.ko
+ifeq ($(strip $(call CompareKernelPatchVer,$(KERNEL_PATCHVER),lt,4.2.0)),1)
+ FILES+=$(LINUX_DIR)/crypto/krng.ko
+endif
+ AUTOLOAD:=$(call AutoLoad,09,rng krng)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-rng))
+
+define KernelPackage/crypto-rng-jitterentropy
+ TITLE:=Jitterentropy Non-Deterministic Random Number Generator
+ KCONFIG:=CONFIG_CRYPTO_JITTERENTROPY
+ FILES:= $(LINUX_DIR)/crypto/jitterentropy_rng.ko
+ AUTOLOAD:=$(call AutoLoad,10,jitterentropy-rng)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-rng-jitterentropy))
+
+define KernelPackage/crypto-iv
+ TITLE:=CryptoAPI initialization vectors
+ DEPENDS:=+kmod-crypto-manager +kmod-crypto-rng +kmod-crypto-wq
+ KCONFIG:= CONFIG_CRYPTO_BLKCIPHER2
+ FILES:= \
+ $(LINUX_DIR)/crypto/eseqiv.ko \
+ $(LINUX_DIR)/crypto/chainiv.ko
+ AUTOLOAD:=$(call AutoLoad,10,eseqiv chainiv)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-iv))
+
+define KernelPackage/crypto-seqiv
+ TITLE:=CryptoAPI Sequence Number IV Generator
+ DEPENDS:=+kmod-crypto-aead +kmod-crypto-rng
+ KCONFIG:=CONFIG_CRYPTO_SEQIV
+ FILES:=$(LINUX_DIR)/crypto/seqiv.ko
+ AUTOLOAD:=$(call AutoLoad,09,seqiv)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-seqiv))
+
+
+define KernelPackage/crypto-hw-talitos
+ TITLE:=Freescale integrated security engine (SEC) driver
+ DEPENDS:=+kmod-crypto-manager +kmod-crypto-hash +kmod-random-core +kmod-crypto-authenc
+ KCONFIG:= \
+ CONFIG_CRYPTO_HW=y \
+ CONFIG_CRYPTO_DEV_TALITOS
+ FILES:= \
+ $(LINUX_DIR)/drivers/crypto/talitos.ko
+ AUTOLOAD:=$(call AutoLoad,09,talitos)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-hw-talitos))
+
+
+define KernelPackage/crypto-hw-padlock
+ TITLE:=VIA PadLock ACE with AES/SHA hw crypto module
+ DEPENDS:=+kmod-crypto-manager
+ KCONFIG:= \
+ CONFIG_CRYPTO_HW=y \
+ CONFIG_CRYPTO_DEV_PADLOCK \
+ CONFIG_CRYPTO_DEV_PADLOCK_AES \
+ CONFIG_CRYPTO_DEV_PADLOCK_SHA
+ FILES:= \
+ $(LINUX_DIR)/drivers/crypto/padlock-aes.ko \
+ $(LINUX_DIR)/drivers/crypto/padlock-sha.ko
+ AUTOLOAD:=$(call AutoLoad,09,padlock-aes padlock-sha)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-hw-padlock))
+
+
+define KernelPackage/crypto-hw-geode
+ TITLE:=AMD Geode hardware crypto module
+ DEPENDS:=+kmod-crypto-manager
+ KCONFIG:= \
+ CONFIG_CRYPTO_HW=y \
+ CONFIG_CRYPTO_DEV_GEODE
+ FILES:=$(LINUX_DIR)/drivers/crypto/geode-aes.ko
+ AUTOLOAD:=$(call AutoLoad,09,geode-aes)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-hw-geode))
+
+
+define KernelPackage/crypto-hw-hifn-795x
+ TITLE:=HIFN 795x crypto accelerator
+ DEPENDS:=+kmod-random-core +kmod-crypto-manager
+ KCONFIG:= \
+ CONFIG_CRYPTO_HW=y \
+ CONFIG_CRYPTO_DEV_HIFN_795X \
+ CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y
+ FILES:=$(LINUX_DIR)/drivers/crypto/hifn_795x.ko
+ AUTOLOAD:=$(call AutoLoad,09,hifn_795x)
+ $(call AddDepends/crypto,+kmod-crypto-des)
+endef
+
+$(eval $(call KernelPackage,crypto-hw-hifn-795x))
+
+
+define KernelPackage/crypto-hw-ppc4xx
+ TITLE:=AMCC PPC4xx hardware crypto module
+ DEPENDS:=@TARGET_ppc40x||TARGET_ppc44x
+ KCONFIG:= \
+ CONFIG_CRYPTO_HW=y \
+ CONFIG_CRYPTO_DEV_PPC4XX
+ FILES:=$(LINUX_DIR)/drivers/crypto/amcc/crypto4xx.ko
+ AUTOLOAD:=$(call AutoLoad,90,crypto4xx)
+ $(call AddDepends/crypto,+kmod-crypto-manager +kmod-crypto-hash)
+endef
+
+define KernelPackage/crypto-hw-ppc4xx/description
+ Kernel support for the AMCC PPC4xx HW crypto engine.
+endef
+
+$(eval $(call KernelPackage,crypto-hw-ppc4xx))
+
+
+define KernelPackage/crypto-hw-omap
+ TITLE:=TI OMAP hardware crypto modules
+ DEPENDS:=@TARGET_omap
+ KCONFIG:= \
+ CONFIG_CRYPTO_HW=y \
+ CONFIG_CRYPTO_DEV_OMAP_AES \
+ CONFIG_CRYPTO_DEV_OMAP_DES \
+ CONFIG_CRYPTO_DEV_OMAP_SHAM
+ifneq ($(wildcard $(LINUX_DIR)/drivers/crypto/omap-des.ko),)
+ FILES:= \
+ $(LINUX_DIR)/drivers/crypto/omap-aes.ko \
+ $(LINUX_DIR)/drivers/crypto/omap-des.ko \
+ $(LINUX_DIR)/drivers/crypto/omap-sham.ko
+ AUTOLOAD:=$(call AutoLoad,90,omap-aes omap-des omap-sham)
+else
+ FILES:= \
+ $(LINUX_DIR)/drivers/crypto/omap-aes.ko \
+ $(LINUX_DIR)/drivers/crypto/omap-sham.ko
+ AUTOLOAD:=$(call AutoLoad,90,omap-aes omap-sham)
+endif
+ $(call AddDepends/crypto,+kmod-crypto-manager +kmod-crypto-hash)
+endef
+
+define KernelPackage/crypto-hw-omap/description
+ Kernel support for the TI OMAP HW crypto engine.
+endef
+
+$(eval $(call KernelPackage,crypto-hw-omap))
+
+
+define KernelPackage/crypto-authenc
+ TITLE:=Combined mode wrapper for IPsec
+ DEPENDS:=+kmod-crypto-manager
+ KCONFIG:=CONFIG_CRYPTO_AUTHENC
+ FILES:=$(LINUX_DIR)/crypto/authenc.ko
+ AUTOLOAD:=$(call AutoLoad,09,authenc)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-authenc))
+
+define KernelPackage/crypto-cbc
+ TITLE:=Cipher Block Chaining CryptoAPI module
+ DEPENDS:=+kmod-crypto-manager
+ KCONFIG:=CONFIG_CRYPTO_CBC
+ FILES:=$(LINUX_DIR)/crypto/cbc.ko
+ AUTOLOAD:=$(call AutoLoad,09,cbc)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-cbc))
+
+define KernelPackage/crypto-ctr
+ TITLE:=Counter Mode CryptoAPI module
+ DEPENDS:=+kmod-crypto-manager +kmod-crypto-seqiv +kmod-crypto-iv
+ KCONFIG:=CONFIG_CRYPTO_CTR
+ FILES:=$(LINUX_DIR)/crypto/ctr.ko
+ AUTOLOAD:=$(call AutoLoad,09,ctr)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-ctr))
+
+define KernelPackage/crypto-ccm
+ TITLE:=Support for Counter with CBC MAC (CCM)
+ DEPENDS:=+kmod-crypto-ctr +kmod-crypto-aead
+ KCONFIG:=CONFIG_CRYPTO_CCM
+ FILES:=$(LINUX_DIR)/crypto/ccm.ko
+ AUTOLOAD:=$(call AutoLoad,09,ccm)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-ccm))
+
+define KernelPackage/crypto-pcbc
+ TITLE:=Propagating Cipher Block Chaining CryptoAPI module
+ DEPENDS:=+kmod-crypto-manager
+ KCONFIG:=CONFIG_CRYPTO_PCBC
+ FILES:=$(LINUX_DIR)/crypto/pcbc.ko
+ AUTOLOAD:=$(call AutoLoad,09,pcbc)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-pcbc))
+
+define KernelPackage/crypto-crc32c
+ TITLE:=CRC32c CRC module
+ DEPENDS:=+kmod-crypto-hash
+ KCONFIG:=CONFIG_CRYPTO_CRC32C
+ FILES:=$(LINUX_DIR)/crypto/crc32c_generic.ko
+ AUTOLOAD:=$(call AutoLoad,04,crc32c_generic,1)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-crc32c))
+
+
+define KernelPackage/crypto-des
+ TITLE:=DES/3DES cipher CryptoAPI module
+ KCONFIG:=CONFIG_CRYPTO_DES
+ FILES:=$(LINUX_DIR)/crypto/des_generic.ko
+ AUTOLOAD:=$(call AutoLoad,09,des_generic)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-des))
+
+
+define KernelPackage/crypto-deflate
+ TITLE:=Deflate compression CryptoAPI module
+ DEPENDS:=+kmod-lib-zlib
+ KCONFIG:=CONFIG_CRYPTO_DEFLATE
+ FILES:=$(LINUX_DIR)/crypto/deflate.ko
+ AUTOLOAD:=$(call AutoLoad,09,deflate)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-deflate))
+
+
+define KernelPackage/crypto-fcrypt
+ TITLE:=FCRYPT cipher CryptoAPI module
+ KCONFIG:=CONFIG_CRYPTO_FCRYPT
+ FILES:=$(LINUX_DIR)/crypto/fcrypt.ko
+ AUTOLOAD:=$(call AutoLoad,09,fcrypt)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-fcrypt))
+
+define KernelPackage/crypto-ecb
+ TITLE:=Electronic CodeBook CryptoAPI module
+ DEPENDS:=+kmod-crypto-manager
+ KCONFIG:=CONFIG_CRYPTO_ECB
+ FILES:=$(LINUX_DIR)/crypto/ecb.ko
+ AUTOLOAD:=$(call AutoLoad,09,ecb)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-ecb))
+
+
+define KernelPackage/crypto-hmac
+ TITLE:=HMAC digest CryptoAPI module
+ DEPENDS:=+kmod-crypto-hash +kmod-crypto-manager
+ KCONFIG:=CONFIG_CRYPTO_HMAC
+ FILES:=$(LINUX_DIR)/crypto/hmac.ko
+ AUTOLOAD:=$(call AutoLoad,09,hmac)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-hmac))
+
+
+define KernelPackage/crypto-cmac
+ TITLE:=Support for Cipher-based Message Authentication Code (CMAC)
+ DEPENDS:=+kmod-crypto-hash
+ KCONFIG:=CONFIG_CRYPTO_CMAC
+ FILES:=$(LINUX_DIR)/crypto/cmac.ko
+ AUTOLOAD:=$(call AutoLoad,09,cmac)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-cmac))
+
+
+define KernelPackage/crypto-gcm
+ TITLE:=GCM/GMAC CryptoAPI module
+ DEPENDS:=+kmod-crypto-ctr +kmod-crypto-ghash +kmod-crypto-null
+ KCONFIG:=CONFIG_CRYPTO_GCM
+ FILES:=$(LINUX_DIR)/crypto/gcm.ko
+ AUTOLOAD:=$(call AutoLoad,09,gcm)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-gcm))
+
+
+define KernelPackage/crypto-gf128
+ TITLE:=GF(2^128) multiplication functions CryptoAPI module
+ KCONFIG:=CONFIG_CRYPTO_GF128MUL
+ FILES:=$(LINUX_DIR)/crypto/gf128mul.ko
+ AUTOLOAD:=$(call AutoLoad,09,gf128mul)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-gf128))
+
+
+define KernelPackage/crypto-ghash
+ TITLE:=GHASH digest CryptoAPI module
+ DEPENDS:=+kmod-crypto-gf128 +kmod-crypto-hash
+ KCONFIG:=CONFIG_CRYPTO_GHASH
+ FILES:=$(LINUX_DIR)/crypto/ghash-generic.ko
+ AUTOLOAD:=$(call AutoLoad,09,ghash-generic)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-ghash))
+
+
+define KernelPackage/crypto-md4
+ TITLE:=MD4 digest CryptoAPI module
+ DEPENDS:=+kmod-crypto-hash
+ KCONFIG:=CONFIG_CRYPTO_MD4
+ FILES:=$(LINUX_DIR)/crypto/md4.ko
+ AUTOLOAD:=$(call AutoLoad,09,md4)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-md4))
+
+
+define KernelPackage/crypto-md5
+ TITLE:=MD5 digest CryptoAPI module
+ DEPENDS:=+kmod-crypto-hash
+ KCONFIG:=CONFIG_CRYPTO_MD5
+ FILES:=$(LINUX_DIR)/crypto/md5.ko
+ AUTOLOAD:=$(call AutoLoad,09,md5)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-md5))
+
+
+define KernelPackage/crypto-michael-mic
+ TITLE:=Michael MIC keyed digest CryptoAPI module
+ DEPENDS:=+kmod-crypto-hash
+ KCONFIG:=CONFIG_CRYPTO_MICHAEL_MIC
+ FILES:=$(LINUX_DIR)/crypto/michael_mic.ko
+ AUTOLOAD:=$(call AutoLoad,09,michael_mic)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-michael-mic))
+
+
+define KernelPackage/crypto-sha1
+ TITLE:=SHA1 digest CryptoAPI module
+ DEPENDS:=+kmod-crypto-hash
+ KCONFIG:=CONFIG_CRYPTO_SHA1
+ FILES:=$(LINUX_DIR)/crypto/sha1_generic.ko
+ AUTOLOAD:=$(call AutoLoad,09,sha1_generic)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-sha1))
+
+
+define KernelPackage/crypto-sha256
+ TITLE:=SHA224 SHA256 digest CryptoAPI module
+ DEPENDS:=+kmod-crypto-hash
+ KCONFIG:=CONFIG_CRYPTO_SHA256
+ FILES:=$(LINUX_DIR)/crypto/sha256_generic.ko
+ AUTOLOAD:=$(call AutoLoad,09,sha256_generic)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-sha256))
+
+
+define KernelPackage/crypto-misc
+ TITLE:=Other CryptoAPI modules
+ DEPENDS:=+kmod-crypto-manager
+ KCONFIG:= \
+ CONFIG_CRYPTO_ANUBIS \
+ CONFIG_CRYPTO_BLOWFISH \
+ CONFIG_CRYPTO_CAMELLIA \
+ CONFIG_CRYPTO_CAST5 \
+ CONFIG_CRYPTO_CAST6 \
+ CONFIG_CRYPTO_FCRYPT \
+ CONFIG_CRYPTO_KHAZAD \
+ CONFIG_CRYPTO_SERPENT \
+ CONFIG_CRYPTO_SHA512 \
+ CONFIG_CRYPTO_TEA \
+ CONFIG_CRYPTO_TGR192 \
+ CONFIG_CRYPTO_TWOFISH \
+ CONFIG_CRYPTO_TWOFISH_COMMON \
+ CONFIG_CRYPTO_TWOFISH_586 \
+ CONFIG_CRYPTO_WP512
+ FILES:= \
+ $(LINUX_DIR)/crypto/anubis.ko \
+ $(LINUX_DIR)/crypto/camellia_generic.ko \
+ $(LINUX_DIR)/crypto/cast_common.ko \
+ $(LINUX_DIR)/crypto/cast5_generic.ko \
+ $(LINUX_DIR)/crypto/cast6_generic.ko \
+ $(LINUX_DIR)/crypto/khazad.ko \
+ $(LINUX_DIR)/crypto/sha512_generic.ko \
+ $(LINUX_DIR)/crypto/tea.ko \
+ $(LINUX_DIR)/crypto/tgr192.ko \
+ $(LINUX_DIR)/crypto/twofish_common.ko \
+ $(LINUX_DIR)/crypto/wp512.ko \
+ $(LINUX_DIR)/crypto/twofish_generic.ko \
+ $(LINUX_DIR)/crypto/blowfish_common.ko \
+ $(LINUX_DIR)/crypto/blowfish_generic.ko \
+ $(LINUX_DIR)/crypto/serpent_generic.ko
+ $(call AddDepends/crypto)
+endef
+
+ifndef CONFIG_TARGET_x86_64
+ define KernelPackage/crypto-misc/x86
+ FILES+=$(LINUX_DIR)/arch/x86/crypto/twofish-i586.ko
+ endef
+endif
+
+$(eval $(call KernelPackage,crypto-misc))
+
+
+define KernelPackage/crypto-ocf
+ TITLE:=OCF modules
+ DEPENDS:=+@OPENSSL_ENGINE_CRYPTO @!TARGET_uml +kmod-crypto-manager
+ KCONFIG:= \
+ CONFIG_OCF_OCF \
+ CONFIG_OCF_CRYPTODEV \
+ CONFIG_OCF_CRYPTOSOFT \
+ CONFIG_OCF_FIPS=y \
+ CONFIG_OCF_RANDOMHARVEST=y
+ FILES:= \
+ $(LINUX_DIR)/crypto/ocf/ocf.ko \
+ $(LINUX_DIR)/crypto/ocf/cryptodev.ko \
+ $(LINUX_DIR)/crypto/ocf/cryptosoft.ko
+ AUTOLOAD:=$(call AutoLoad,09, \
+ ocf \
+ cryptodev \
+ cryptosoft \
+ )
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-ocf))
+
+
+define KernelPackage/crypto-ocf-hifn7751
+ TITLE:=OCF support for Hifn 6500/7751/7811/795x, Invertex AEON and NetSec 7751 devices
+ DEPENDS:=+@OPENSSL_ENGINE_CRYPTO @PCI_SUPPORT @!TARGET_uml kmod-crypto-ocf
+ KCONFIG:=CONFIG_OCF_HIFN
+ FILES:=$(LINUX_DIR)/crypto/ocf/hifn/hifn7751.ko
+ AUTOLOAD:=$(call AutoLoad,10,hifn7751)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-ocf-hifn7751))
+
+
+define KernelPackage/crypto-ocf-hifnhipp
+ TITLE:=OCF support for Hifn 7855/8155 devices
+ DEPENDS:=+@OPENSSL_ENGINE_CRYPTO @PCI_SUPPORT @!TARGET_uml kmod-crypto-ocf
+ KCONFIG:=CONFIG_OCF_HIFNHIPP
+ FILES:=$(LINUX_DIR)/crypto/ocf/hifn/hifnHIPP.ko
+ AUTOLOAD:=$(call AutoLoad,10,hifnHIPP)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-ocf-hifnhipp))
+
+
+define KernelPackage/crypto-null
+ TITLE:=Null CryptoAPI module
+ KCONFIG:=CONFIG_CRYPTO_NULL
+ FILES:=$(LINUX_DIR)/crypto/crypto_null.ko
+ AUTOLOAD:=$(call AutoLoad,09,crypto_null)
+ $(call AddDepends/crypto,+kmod-crypto-manager)
+endef
+
+$(eval $(call KernelPackage,crypto-null))
+
+
+define KernelPackage/crypto-test
+ TITLE:=Test CryptoAPI module
+ KCONFIG:=CONFIG_CRYPTO_TEST
+ FILES:=$(LINUX_DIR)/crypto/tcrypt.ko
+ $(call AddDepends/crypto,+kmod-crypto-manager)
+endef
+
+$(eval $(call KernelPackage,crypto-test))
+
+
+define KernelPackage/crypto-xts
+ TITLE:=XTS cipher CryptoAPI module
+ DEPENDS:=+kmod-crypto-gf128 +kmod-crypto-manager
+ KCONFIG:=CONFIG_CRYPTO_XTS
+ FILES:=$(LINUX_DIR)/crypto/xts.ko
+ AUTOLOAD:=$(call AutoLoad,09,xts)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-xts))
+
+
+define KernelPackage/crypto-mv-cesa
+ TITLE:=Marvell crypto engine
+ DEPENDS:=+kmod-crypto-manager @TARGET_kirkwood||TARGET_orion||TARGET_mvebu
+ KCONFIG:=CONFIG_CRYPTO_DEV_MV_CESA
+ FILES:=$(LINUX_DIR)/drivers/crypto/mv_cesa.ko
+ AUTOLOAD:=$(call AutoLoad,09,mv_cesa)
+ $(call AddDepends/crypto)
+endef
+
+$(eval $(call KernelPackage,crypto-mv-cesa))
diff --git a/package/kernel/linux/modules/firewire.mk b/package/kernel/linux/modules/firewire.mk
new file mode 100644
index 0000000..18b531a
--- /dev/null
+++ b/package/kernel/linux/modules/firewire.mk
@@ -0,0 +1,74 @@
+#
+# Copyright (C) 2008-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+FIREWIRE_MENU:=FireWire support
+
+define KernelPackage/firewire
+ SUBMENU:=$(FIREWIRE_MENU)
+ TITLE:=Support for FireWire (new stack)
+ DEPENDS:=@PCI_SUPPORT +kmod-lib-crc-itu-t
+ KCONFIG:=CONFIG_FIREWIRE
+ FILES:=$(LINUX_DIR)/drivers/firewire/firewire-core.ko
+endef
+
+define KernelPackage/firewire/description
+ Kernel support for FireWire (new stack)
+endef
+
+$(eval $(call KernelPackage,firewire))
+
+
+define KernelPackage/firewire-ohci
+ SUBMENU:=$(FIREWIRE_MENU)
+ TITLE:=Support for OHCI-1394 controllers
+ DEPENDS:=kmod-firewire
+ KCONFIG:= \
+ CONFIG_FIREWIRE_OHCI \
+ CONFIG_FIREWIRE_OHCI_DEBUG=n \
+ CONFIG_FIREWIRE_OHCI_REMOTE_DMA=n
+ FILES:=$(LINUX_DIR)/drivers/firewire/firewire-ohci.ko
+ AUTOLOAD:=$(call AutoProbe,firewire-ohci)
+endef
+
+
+define KernelPackage/firewire-ohci/description
+ Kernel support for FireWire OHCI-1394 controllers
+endef
+
+$(eval $(call KernelPackage,firewire-ohci))
+
+
+define KernelPackage/firewire-sbp2
+ SUBMENU:=$(FIREWIRE_MENU)
+ TITLE:=Support for SBP-2 devices over FireWire
+ DEPENDS:=kmod-firewire +kmod-scsi-core
+ KCONFIG:=CONFIG_FIREWIRE_SBP2
+ FILES:=$(LINUX_DIR)/drivers/firewire/firewire-sbp2.ko
+ AUTOLOAD:=$(call AutoProbe,firewire-sbp2)
+endef
+
+define KernelPackage/firewire-sbp2/description
+ Kernel support for SBP-2 devices over FireWire
+endef
+
+$(eval $(call KernelPackage,firewire-sbp2))
+
+
+define KernelPackage/firewire-net
+ SUBMENU:=$(FIREWIRE_MENU)
+ TITLE:=Support for IP networking over FireWire
+ DEPENDS:=kmod-firewire
+ KCONFIG:=CONFIG_FIREWIRE_NET
+ FILES:=$(LINUX_DIR)/drivers/firewire/firewire-net.ko
+ AUTOLOAD:=$(call AutoProbe,firewire-net)
+endef
+
+define KernelPackage/firewire-net/description
+ Kernel support for IPv4 over FireWire
+endef
+
+$(eval $(call KernelPackage,firewire-net))
diff --git a/package/kernel/linux/modules/fs.mk b/package/kernel/linux/modules/fs.mk
new file mode 100644
index 0000000..5900a4b
--- /dev/null
+++ b/package/kernel/linux/modules/fs.mk
@@ -0,0 +1,467 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+FS_MENU:=Filesystems
+
+define KernelPackage/fs-fscache
+ SUBMENU:=$(FS_MENU)
+ TITLE:=General filesystem local cache manager
+ DEPENDS:=
+ KCONFIG:=\
+ CONFIG_FSCACHE=m \
+ CONFIG_FSCACHE_STATS=y \
+ CONFIG_FSCACHE_HISTOGRAM=n \
+ CONFIG_FSCACHE_DEBUG=n \
+ CONFIG_FSCACHE_OBJECT_LIST=n \
+ CONFIG_CACHEFILES=y \
+ CONFIG_CACHEFILES_DEBUG=n \
+ CONFIG_CACHEFILES_HISTOGRAM=n
+ FILES:=$(LINUX_DIR)/fs/fscache/fscache.ko
+ AUTOLOAD:=$(call AutoLoad,29,fscache)
+endef
+
+$(eval $(call KernelPackage,fs-fscache))
+
+define KernelPackage/fs-afs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=Andrew FileSystem client
+ DEPENDS:=+kmod-rxrpc +kmod-dnsresolver +kmod-fs-fscache
+ KCONFIG:=\
+ CONFIG_AFS_FS=m \
+ CONFIG_AFS_DEBUG=n \
+ CONFIG_AFS_FSCACHE=y
+ FILES:=$(LINUX_DIR)/fs/afs/kafs.ko
+ AUTOLOAD:=$(call AutoLoad,30,kafs)
+endef
+
+define KernelPackage/fs-afs/description
+ Kernel module for Andrew FileSystem client support
+endef
+
+$(eval $(call KernelPackage,fs-afs))
+
+define KernelPackage/fs-autofs4
+ SUBMENU:=$(FS_MENU)
+ TITLE:=AUTOFS4 filesystem support
+ KCONFIG:=CONFIG_AUTOFS4_FS
+ FILES:=$(LINUX_DIR)/fs/autofs4/autofs4.ko
+ AUTOLOAD:=$(call AutoLoad,30,autofs4)
+endef
+
+define KernelPackage/fs-autofs4/description
+ Kernel module for AutoFS4 support
+endef
+
+$(eval $(call KernelPackage,fs-autofs4))
+
+
+define KernelPackage/fs-btrfs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=BTRFS filesystem support
+ DEPENDS:=+kmod-lib-crc32c +kmod-lib-lzo +kmod-lib-zlib +kmod-lib-raid6 +kmod-lib-xor
+ KCONFIG:=\
+ CONFIG_BTRFS_FS \
+ CONFIG_BTRFS_FS_POSIX_ACL=n \
+ CONFIG_BTRFS_FS_CHECK_INTEGRITY=n
+ FILES:=\
+ $(LINUX_DIR)/fs/btrfs/btrfs.ko
+ AUTOLOAD:=$(call AutoLoad,30,btrfs,1)
+endef
+
+define KernelPackage/fs-btrfs/description
+ Kernel module for BTRFS support
+endef
+
+$(eval $(call KernelPackage,fs-btrfs))
+
+
+define KernelPackage/fs-cifs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=CIFS support
+ KCONFIG:= \
+ CONFIG_CIFS \
+ CONFIG_CIFS_DFS_UPCALL=n \
+ CONFIG_CIFS_UPCALL=n
+ FILES:=$(LINUX_DIR)/fs/cifs/cifs.ko
+ AUTOLOAD:=$(call AutoLoad,30,cifs)
+ $(call AddDepends/nls)
+ DEPENDS+= \
+ +kmod-crypto-hmac \
+ +kmod-crypto-md5 \
+ +kmod-crypto-md4 \
+ +kmod-crypto-des \
+ +kmod-crypto-ecb \
+ +kmod-crypto-sha256
+endef
+
+define KernelPackage/fs-cifs/description
+ Kernel module for CIFS support
+endef
+
+$(eval $(call KernelPackage,fs-cifs))
+
+
+define KernelPackage/fs-configfs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=Configuration filesystem support
+ KCONFIG:= \
+ CONFIG_CONFIGFS_FS
+ FILES:=$(LINUX_DIR)/fs/configfs/configfs.ko
+ AUTOLOAD:=$(call AutoLoad,30,configfs)
+endef
+
+define KernelPackage/fs-configfs/description
+ Kernel module for configfs support
+endef
+
+$(eval $(call KernelPackage,fs-configfs))
+
+define KernelPackage/fs-cramfs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=Compressed RAM/ROM filesystem support
+ DEPENDS:=+kmod-lib-zlib
+ KCONFIG:= \
+ CONFIG_CRAMFS
+ FILES:=$(LINUX_DIR)/fs/cramfs/cramfs.ko
+ AUTOLOAD:=$(call AutoLoad,30,cramfs)
+endef
+
+define KernelPackage/fs-cramfs/description
+ Kernel module for cramfs support
+endef
+
+$(eval $(call KernelPackage,fs-cramfs))
+
+define KernelPackage/fs-exportfs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=exportfs kernel server support
+ KCONFIG:=CONFIG_EXPORTFS
+ FILES=$(LINUX_DIR)/fs/exportfs/exportfs.ko
+ AUTOLOAD:=$(call AutoLoad,20,exportfs,1)
+endef
+
+define KernelPackage/fs-exportfs/description
+ Kernel module for exportfs. Needed for some other modules.
+endef
+
+$(eval $(call KernelPackage,fs-exportfs))
+
+
+define KernelPackage/fs-ext4
+ SUBMENU:=$(FS_MENU)
+ TITLE:=EXT4 filesystem support
+ DEPENDS := \
+ +kmod-lib-crc16 \
+ +kmod-crypto-hash
+ KCONFIG:= \
+ CONFIG_EXT4_FS \
+ CONFIG_EXT4_ENCRYPTION=n \
+ CONFIG_JBD2
+ FILES:= \
+ $(LINUX_DIR)/fs/ext4/ext4.ko \
+ $(LINUX_DIR)/fs/jbd2/jbd2.ko \
+ $(LINUX_DIR)/fs/mbcache.ko
+ AUTOLOAD:=$(call AutoLoad,30,mbcache jbd2 ext4,1)
+endef
+
+define KernelPackage/fs-ext4/description
+ Kernel module for EXT4 filesystem support
+endef
+
+$(eval $(call KernelPackage,fs-ext4))
+
+
+define KernelPackage/fs-f2fs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=F2FS filesystem support
+ KCONFIG:= \
+ CONFIG_F2FS_FS \
+ CONFIG_F2FS_STAT_FS=y \
+ CONFIG_F2FS_FS_XATTR=y \
+ CONFIG_F2FS_FS_POSIX_ACL=n \
+ CONFIG_F2FS_FS_SECURITY=n \
+ CONFIG_F2FS_CHECK_FS=n
+ FILES:=$(LINUX_DIR)/fs/f2fs/f2fs.ko
+ AUTOLOAD:=$(call AutoLoad,30,f2fs,1)
+endef
+
+define KernelPackage/fs-f2fs/description
+ Kernel module for F2FS filesystem support
+endef
+
+$(eval $(call KernelPackage,fs-f2fs))
+
+
+define KernelPackage/fuse
+ SUBMENU:=$(FS_MENU)
+ TITLE:=FUSE (Filesystem in Userspace) support
+ KCONFIG:= CONFIG_FUSE_FS
+ FILES:=$(LINUX_DIR)/fs/fuse/fuse.ko
+ AUTOLOAD:=$(call AutoLoad,80,fuse)
+endef
+
+define KernelPackage/fuse/description
+ Kernel module for userspace filesystem support
+endef
+
+$(eval $(call KernelPackage,fuse))
+
+
+define KernelPackage/fs-hfs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=HFS filesystem support
+ KCONFIG:=CONFIG_HFS_FS
+ FILES:=$(LINUX_DIR)/fs/hfs/hfs.ko
+ AUTOLOAD:=$(call AutoLoad,30,hfs)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/fs-hfs/description
+ Kernel module for HFS filesystem support
+endef
+
+$(eval $(call KernelPackage,fs-hfs))
+
+
+define KernelPackage/fs-hfsplus
+ SUBMENU:=$(FS_MENU)
+ TITLE:=HFS+ filesystem support
+ KCONFIG:=CONFIG_HFSPLUS_FS
+ FILES:=$(LINUX_DIR)/fs/hfsplus/hfsplus.ko
+ AUTOLOAD:=$(call AutoLoad,30,hfsplus)
+ $(call AddDepends/nls,utf8)
+endef
+
+define KernelPackage/fs-hfsplus/description
+ Kernel module for HFS+ filesystem support
+endef
+
+$(eval $(call KernelPackage,fs-hfsplus))
+
+
+define KernelPackage/fs-isofs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=ISO9660 filesystem support
+ DEPENDS:=+kmod-lib-zlib
+ KCONFIG:=CONFIG_ISO9660_FS CONFIG_JOLIET=y CONFIG_ZISOFS=n
+ FILES:=$(LINUX_DIR)/fs/isofs/isofs.ko
+ AUTOLOAD:=$(call AutoLoad,30,isofs)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/fs-isofs/description
+ Kernel module for ISO9660 filesystem support
+endef
+
+$(eval $(call KernelPackage,fs-isofs))
+
+
+define KernelPackage/fs-minix
+ SUBMENU:=$(FS_MENU)
+ TITLE:=Minix filesystem support
+ KCONFIG:=CONFIG_MINIX_FS
+ FILES:=$(LINUX_DIR)/fs/minix/minix.ko
+ AUTOLOAD:=$(call AutoLoad,30,minix)
+endef
+
+define KernelPackage/fs-minix/description
+ Kernel module for Minix filesystem support
+endef
+
+$(eval $(call KernelPackage,fs-minix))
+
+
+define KernelPackage/fs-msdos
+ SUBMENU:=$(FS_MENU)
+ TITLE:=MSDOS filesystem support
+ DEPENDS:=+kmod-fs-vfat
+ KCONFIG:=CONFIG_MSDOS_FS
+ FILES:=$(LINUX_DIR)/fs/fat/msdos.ko
+ AUTOLOAD:=$(call AutoLoad,40,msdos)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/fs-msdos/description
+ Kernel module for MSDOS filesystem support
+endef
+
+$(eval $(call KernelPackage,fs-msdos))
+
+
+define KernelPackage/fs-nfs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=NFS filesystem support
+ DEPENDS:=+kmod-fs-nfs-common +kmod-dnsresolver
+ KCONFIG:= \
+ CONFIG_NFS_FS \
+ CONFIG_NFS_USE_LEGACY_DNS=n \
+ CONFIG_NFS_USE_NEW_IDMAPPER=n
+ FILES:= \
+ $(LINUX_DIR)/fs/nfs/nfs.ko \
+ $(LINUX_DIR)/fs/nfs/nfsv3.ko
+ AUTOLOAD:=$(call AutoLoad,40,nfs nfsv3)
+endef
+
+define KernelPackage/fs-nfs/description
+ Kernel module for NFS support
+endef
+
+$(eval $(call KernelPackage,fs-nfs))
+
+
+define KernelPackage/fs-nfs-common
+ SUBMENU:=$(FS_MENU)
+ TITLE:=Common NFS filesystem modules
+ KCONFIG:= \
+ CONFIG_LOCKD \
+ CONFIG_SUNRPC \
+ CONFIG_GRACE_PERIOD
+ FILES:= \
+ $(LINUX_DIR)/fs/lockd/lockd.ko \
+ $(LINUX_DIR)/net/sunrpc/sunrpc.ko \
+ $(LINUX_DIR)/fs/nfs_common/grace.ko
+ AUTOLOAD:=$(call AutoLoad,30,grace sunrpc lockd)
+endef
+
+$(eval $(call KernelPackage,fs-nfs-common))
+
+
+define KernelPackage/fs-nfs-common-v4
+ SUBMENU:=$(FS_MENU)
+ TITLE:=Common NFS V4 filesystem modules
+ KCONFIG+=\
+ CONFIG_SUNRPC_GSS\
+ CONFIG_NFS_V4=y\
+ CONFIG_NFSD_V4=y
+ DEPENDS:= @BROKEN
+ FILES+=$(LINUX_DIR)/net/sunrpc/auth_gss/auth_rpcgss.ko
+ AUTOLOAD=$(call AutoLoad,30,auth_rpcgss)
+endef
+
+define KernelPackage/fs-nfs-common-v4/description
+ Kernel modules for NFS V4 & NFSD V4 kernel support
+endef
+
+$(eval $(call KernelPackage,fs-nfs-common-v4))
+
+
+define KernelPackage/fs-nfsd
+ SUBMENU:=$(FS_MENU)
+ TITLE:=NFS kernel server support
+ DEPENDS:=+kmod-fs-nfs-common +kmod-fs-exportfs
+ KCONFIG:= \
+ CONFIG_NFSD \
+ CONFIG_NFSD_FAULT_INJECTION=n
+ FILES:=$(LINUX_DIR)/fs/nfsd/nfsd.ko
+ AUTOLOAD:=$(call AutoLoad,40,nfsd)
+endef
+
+define KernelPackage/fs-nfsd/description
+ Kernel module for NFS kernel server support
+endef
+
+$(eval $(call KernelPackage,fs-nfsd))
+
+
+define KernelPackage/fs-ntfs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=NTFS filesystem support
+ KCONFIG:=CONFIG_NTFS_FS
+ FILES:=$(LINUX_DIR)/fs/ntfs/ntfs.ko
+ AUTOLOAD:=$(call AutoLoad,30,ntfs)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/fs-ntfs/description
+ Kernel module for NTFS filesystem support
+endef
+
+$(eval $(call KernelPackage,fs-ntfs))
+
+
+define KernelPackage/fs-reiserfs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=ReiserFS filesystem support
+ KCONFIG:=CONFIG_REISERFS_FS
+ FILES:=$(LINUX_DIR)/fs/reiserfs/reiserfs.ko
+ AUTOLOAD:=$(call AutoLoad,30,reiserfs,1)
+endef
+
+define KernelPackage/fs-reiserfs/description
+ Kernel module for ReiserFS support
+endef
+
+$(eval $(call KernelPackage,fs-reiserfs))
+
+
+define KernelPackage/fs-udf
+ SUBMENU:=$(FS_MENU)
+ TITLE:=UDF filesystem support
+ KCONFIG:=CONFIG_UDF_FS
+ FILES:=$(LINUX_DIR)/fs/udf/udf.ko
+ AUTOLOAD:=$(call AutoLoad,30,udf)
+ DEPENDS:=+kmod-lib-crc-itu-t
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/fs-udf/description
+ Kernel module for UDF filesystem support
+endef
+
+$(eval $(call KernelPackage,fs-udf))
+
+
+define KernelPackage/fs-vfat
+ SUBMENU:=$(FS_MENU)
+ TITLE:=VFAT filesystem support
+ KCONFIG:= \
+ CONFIG_FAT_FS \
+ CONFIG_VFAT_FS
+ FILES:= \
+ $(LINUX_DIR)/fs/fat/fat.ko \
+ $(LINUX_DIR)/fs/fat/vfat.ko
+ AUTOLOAD:=$(call AutoLoad,30,fat vfat)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/fs-vfat/description
+ Kernel module for VFAT filesystem support
+endef
+
+$(eval $(call KernelPackage,fs-vfat))
+
+
+define KernelPackage/fs-xfs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=XFS filesystem support
+ KCONFIG:=CONFIG_XFS_FS
+ DEPENDS:= +kmod-fs-exportfs +kmod-lib-crc32c
+ FILES:=$(LINUX_DIR)/fs/xfs/xfs.ko
+ AUTOLOAD:=$(call AutoLoad,30,xfs,1)
+endef
+
+define KernelPackage/fs-xfs/description
+ Kernel module for XFS support
+endef
+
+$(eval $(call KernelPackage,fs-xfs))
+
+
+define KernelPackage/fs-jfs
+ SUBMENU:=$(FS_MENU)
+ TITLE:=JFS filesystem support
+ KCONFIG:=CONFIG_JFS_FS
+ FILES:=$(LINUX_DIR)/fs/jfs/jfs.ko
+ AUTOLOAD:=$(call AutoLoad,30,jfs,1)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/fs-jfs/description
+ Kernel module for JFS support
+endef
+
+$(eval $(call KernelPackage,fs-jfs))
diff --git a/package/kernel/linux/modules/hwmon.mk b/package/kernel/linux/modules/hwmon.mk
new file mode 100644
index 0000000..c649847
--- /dev/null
+++ b/package/kernel/linux/modules/hwmon.mk
@@ -0,0 +1,315 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+HWMON_MENU:=Hardware Monitoring Support
+
+define KernelPackage/hwmon-core
+ SUBMENU:=$(HWMON_MENU)
+ TITLE:=Hardware monitoring support
+ KCONFIG:= \
+ CONFIG_HWMON \
+ CONFIG_HWMON_DEBUG_CHIP=n
+ FILES:= \
+ $(LINUX_DIR)/drivers/hwmon/hwmon.ko
+endef
+
+define KernelPackage/hwmon-core/description
+ Kernel modules for hardware monitoring
+endef
+
+$(eval $(call KernelPackage,hwmon-core))
+
+
+define AddDepends/hwmon
+ SUBMENU:=$(HWMON_MENU)
+ DEPENDS:=kmod-hwmon-core $(1)
+endef
+
+define KernelPackage/hwmon-vid
+ TITLE:=VID/VRM/VRD voltage conversion module.
+ KCONFIG:=CONFIG_HWMON_VID
+ FILES:=$(LINUX_DIR)/drivers/hwmon/hwmon-vid.ko
+ AUTOLOAD:=$(call AutoLoad,41,hwmon-vid)
+ $(call AddDepends/hwmon,)
+endef
+
+define KernelPackage/hwmon-vid/description
+ VID/VRM/VRD voltage conversion module for hardware monitoring
+endef
+
+$(eval $(call KernelPackage,hwmon-vid))
+
+
+define KernelPackage/hwmon-adt7410
+ TITLE:=ADT7410 monitoring support
+ KCONFIG:= \
+ CONFIG_SENSORS_ADT7X10 \
+ CONFIG_SENSORS_ADT7410
+ FILES:= \
+ $(LINUX_DIR)/drivers/hwmon/adt7x10.ko \
+ $(LINUX_DIR)/drivers/hwmon/adt7410.ko
+ AUTOLOAD:=$(call AutoLoad,60,adt7x10 adt7410)
+ $(call AddDepends/hwmon,+kmod-i2c-core)
+endef
+
+define KernelPackage/hwmon-adt7410/description
+ Kernel module for ADT7410/7420 I2C thermal monitor chip
+endef
+
+$(eval $(call KernelPackage,hwmon-adt7410))
+
+
+define KernelPackage/hwmon-adt7475
+ TITLE:=ADT7473/7475/7476/7490 monitoring support
+ KCONFIG:=CONFIG_SENSORS_ADT7475
+ FILES:=$(LINUX_DIR)/drivers/hwmon/adt7475.ko
+ AUTOLOAD:=$(call AutoProbe,adt7475)
+ $(call AddDepends/hwmon,+kmod-i2c-core +kmod-hwmon-vid)
+endef
+
+define KernelPackage/hwmon-adt7475/description
+ Kernel module for ADT7473/7475/7476/7490 thermal monitor chip
+endef
+
+$(eval $(call KernelPackage,hwmon-adt7475))
+
+
+define KernelPackage/hwmon-ina2xx
+ TITLE:=INA2XX monitoring support
+ KCONFIG:=CONFIG_SENSORS_INA2XX
+ FILES:=$(LINUX_DIR)/drivers/hwmon/ina2xx.ko
+ AUTOLOAD:=$(call AutoProbe,ina2xx)
+ $(call AddDepends/hwmon,+kmod-i2c-core)
+endef
+
+define KernelPackage/hwmon-ina2xx/description
+ Kernel module for ina2xx dc current monitor chips
+endef
+
+$(eval $(call KernelPackage,hwmon-ina2xx))
+
+
+define KernelPackage/hwmon-lm63
+ TITLE:=LM63/64 monitoring support
+ KCONFIG:=CONFIG_SENSORS_LM63
+ FILES:=$(LINUX_DIR)/drivers/hwmon/lm63.ko
+ AUTOLOAD:=$(call AutoProbe,lm63)
+ $(call AddDepends/hwmon,+kmod-i2c-core)
+endef
+
+define KernelPackage/hwmon-lm63/description
+ Kernel module for lm63 and lm64 thermal monitor chip
+endef
+
+$(eval $(call KernelPackage,hwmon-lm63))
+
+
+define KernelPackage/hwmon-lm75
+ TITLE:=LM75 monitoring support
+ KCONFIG:=CONFIG_SENSORS_LM75
+ FILES:=$(LINUX_DIR)/drivers/hwmon/lm75.ko
+ AUTOLOAD:=$(call AutoProbe,lm75)
+ $(call AddDepends/hwmon,+kmod-i2c-core +PACKAGE_kmod-thermal:kmod-thermal)
+endef
+
+define KernelPackage/hwmon-lm75/description
+ Kernel module for lm75 thermal monitor chip
+endef
+
+$(eval $(call KernelPackage,hwmon-lm75))
+
+
+define KernelPackage/hwmon-lm77
+ TITLE:=LM77 monitoring support
+ KCONFIG:=CONFIG_SENSORS_LM77
+ FILES:=$(LINUX_DIR)/drivers/hwmon/lm77.ko
+ AUTOLOAD:=$(call AutoProbe,lm77)
+ $(call AddDepends/hwmon,+kmod-i2c-core)
+endef
+
+define KernelPackage/hwmon-lm77/description
+ Kernel module for LM77 thermal monitor chip
+endef
+
+$(eval $(call KernelPackage,hwmon-lm77))
+
+
+define KernelPackage/hwmon-lm85
+ TITLE:=LM85 monitoring support
+ KCONFIG:=CONFIG_SENSORS_LM85
+ FILES:=$(LINUX_DIR)/drivers/hwmon/lm85.ko
+ AUTOLOAD:=$(call AutoProbe,lm85)
+ $(call AddDepends/hwmon,+kmod-i2c-core +kmod-hwmon-vid)
+endef
+
+define KernelPackage/hwmon-lm85/description
+ Kernel module for LM85 thermal monitor chip
+endef
+
+$(eval $(call KernelPackage,hwmon-lm85))
+
+
+define KernelPackage/hwmon-lm90
+ TITLE:=LM90 monitoring support
+ KCONFIG:=CONFIG_SENSORS_LM90
+ FILES:=$(LINUX_DIR)/drivers/hwmon/lm90.ko
+ AUTOLOAD:=$(call AutoProbe,lm90)
+ $(call AddDepends/hwmon,+kmod-i2c-core)
+endef
+
+define KernelPackage/hwmon-lm90/description
+ Kernel module for LM90 thermal monitor chip
+endef
+
+$(eval $(call KernelPackage,hwmon-lm90))
+
+define KernelPackage/hwmon-lm92
+ TITLE:=LM92 monitoring support
+ KCONFIG:=CONFIG_SENSORS_LM92
+ FILES:=$(LINUX_DIR)/drivers/hwmon/lm92.ko
+ AUTOLOAD:=$(call AutoProbe,lm92)
+ $(call AddDepends/hwmon,+kmod-i2c-core)
+endef
+
+define KernelPackage/hwmon-lm92/description
+ Kernel module for LM92 thermal monitor chip
+endef
+
+$(eval $(call KernelPackage,hwmon-lm92))
+
+define KernelPackage/hwmon-lm95241
+ TITLE:=LM95241 monitoring support
+ KCONFIG:=CONFIG_SENSORS_LM95241
+ FILES:=$(LINUX_DIR)/drivers/hwmon/lm95241.ko
+ AUTOLOAD:=$(call AutoProbe,lm95241)
+ $(call AddDepends/hwmon,+kmod-i2c-core)
+endef
+
+define KernelPackage/hwmon-lm95241/description
+ Kernel module for LM95241 thermal monitor chip
+endef
+
+$(eval $(call KernelPackage,hwmon-lm95241))
+
+define KernelPackage/hwmon-sht21
+ TITLE:=Sensiron SHT21 and compat. monitoring support
+ KCONFIG:=CONFIG_SENSORS_SHT21
+ FILES:=$(LINUX_DIR)/drivers/hwmon/sht21.ko
+ AUTOLOAD:=$(call AutoProbe,sht21)
+ $(call AddDepends/hwmon,+kmod-i2c-core)
+endef
+
+define KernelPackage/hwmon-sht21/description
+ Kernel module for Sensirion SHT21 and SHT25 temperature and humidity sensors chip
+endef
+
+$(eval $(call KernelPackage,hwmon-sht21))
+
+define KernelPackage/hwmon-pc87360
+ TITLE:=PC87360 monitoring support
+ KCONFIG:=CONFIG_SENSORS_PC87360
+ FILES:=$(LINUX_DIR)/drivers/hwmon/pc87360.ko
+ AUTOLOAD:=$(call AutoProbe,pc87360)
+ $(call AddDepends/hwmon,@TARGET_x86 +kmod-hwmon-vid)
+endef
+
+define KernelPackage/hwmon-pc87360/description
+ Kernel modules for PC87360 chips
+endef
+
+$(eval $(call KernelPackage,hwmon-pc87360))
+
+
+define KernelPackage/hwmon-w83627hf
+ TITLE:=Winbond W83627HF monitoring support
+ KCONFIG:=CONFIG_SENSORS_W83627HF
+ FILES:=$(LINUX_DIR)/drivers/hwmon/w83627hf.ko
+ AUTOLOAD:=$(call AutoLoad,50,w83627hf)
+ $(call AddDepends/hwmon,@TARGET_rdc||TARGET_x86 +kmod-hwmon-vid)
+endef
+
+define KernelPackage/hwmon-w83627hf/description
+ Kernel module for the Winbond W83627HF chips.
+endef
+
+$(eval $(call KernelPackage,hwmon-w83627hf))
+
+
+define KernelPackage/hwmon-gsc
+ TITLE:=Gateworks GSC monitoring support
+ KCONFIG:=CONFIG_SENSORS_GSC
+ FILES:=$(LINUX_DIR)/drivers/hwmon/gsc.ko
+ AUTOLOAD:=$(call AutoLoad,60,gsc)
+ $(call AddDepends/hwmon,+kmod-i2c-core)
+endef
+
+define KernelPackage/hwmon-gsc/description
+ Kernel module for the Gateworks System Controller chips.
+endef
+
+$(eval $(call KernelPackage,hwmon-gsc))
+
+
+define KernelPackage/hwmon-tmp421
+ TITLE:=TI TMP421 and compatible monitoring support
+ KCONFIG:=CONFIG_SENSORS_TMP421
+ FILES:=$(LINUX_DIR)/drivers/hwmon/tmp421.ko
+ AUTOLOAD:=$(call AutoLoad,60,tmp421)
+ $(call AddDepends/hwmon,+kmod-i2c-core)
+endef
+
+define KernelPackage/hwmon-tmp421/description
+ Kernel module for the Texas Instruments TMP421 and compatible chips.
+endef
+
+$(eval $(call KernelPackage,hwmon-tmp421))
+
+
+define KernelPackage/hwmon-gpiofan
+ TITLE:=Generic GPIO FAN support
+ KCONFIG:=CONFIG_SENSORS_GPIO_FAN
+ FILES:=$(LINUX_DIR)/drivers/hwmon/gpio-fan.ko
+ AUTOLOAD:=$(call AutoLoad,60,gpio-fan)
+ $(call AddDepends/hwmon,+kmod-i2c-core)
+endef
+
+define KernelPackage/hwmon-gpiofan/description
+ Kernel module for GPIO controlled FANs
+endef
+
+$(eval $(call KernelPackage,hwmon-gpiofan))
+
+
+define KernelPackage/hwmon-pwmfan
+ TITLE:=Generic PWM FAN support
+ KCONFIG:=CONFIG_SENSORS_PWM_FAN
+ FILES:=$(LINUX_DIR)/drivers/hwmon/pwm-fan.ko
+ AUTOLOAD:=$(call AutoLoad,60,pwm-fan)
+ $(call AddDepends/hwmon,)
+endef
+
+define KernelPackage/hwmon-pwmfan/description
+ Kernel module for PWM controlled FANs
+endef
+
+$(eval $(call KernelPackage,hwmon-pwmfan))
+
+
+define KernelPackage/hwmon-k10temp
+ TITLE:=AMD Family 10h+ temperature sensor
+ KCONFIG:=CONFIG_SENSORS_K10TEMP
+ FILES:=$(LINUX_DIR)/drivers/hwmon/k10temp.ko
+ AUTOLOAD:=$(call AutoLoad,60,k10temp)
+ $(call AddDepends/hwmon,@PCI_SUPPORT @TARGET_x86)
+endef
+
+define KernelPackage/hwmon-k10temp/description
+ Thermal sensor support for AMD 10h, 11h, 12h (Llano), 14h (Brazos),
+ 15h (Bulldozer/Trinity/Kaveri) and 16h (Kabini/Mullins) CPUs
+endef
+
+$(eval $(call KernelPackage,hwmon-k10temp))
diff --git a/package/kernel/linux/modules/i2c.mk b/package/kernel/linux/modules/i2c.mk
new file mode 100644
index 0000000..d4effee
--- /dev/null
+++ b/package/kernel/linux/modules/i2c.mk
@@ -0,0 +1,251 @@
+#
+# Copyright (C) 2006-2009 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+I2C_MENU:=I2C support
+
+ModuleConfVar=$(word 1,$(subst :,$(space),$(1)))
+ModuleFullPath=$(LINUX_DIR)/$(word 2,$(subst :,$(space),$(1))).ko
+ModuleKconfig=$(foreach mod,$(1),$(call ModuleConfVar,$(mod)))
+ModuleFiles=$(foreach mod,$(1),$(call ModuleFullPath,$(mod)))
+ModuleAuto=$(call AutoLoad,$(1),$(foreach mod,$(2),$(basename $(notdir $(call ModuleFullPath,$(mod))))),$(3))
+
+define i2c_defaults
+ SUBMENU:=$(I2C_MENU)
+ KCONFIG:=$(call ModuleKconfig,$(1))
+ FILES:=$(call ModuleFiles,$(1))
+ AUTOLOAD:=$(call ModuleAuto,$(2),$(1),$(3))
+endef
+
+I2C_CORE_MODULES:= \
+ CONFIG_I2C:drivers/i2c/i2c-core \
+ CONFIG_I2C_CHARDEV:drivers/i2c/i2c-dev
+
+ifeq ($(CONFIG_OF),y)
+ I2C_CORE_MODULES+=CONFIG_OF_I2C:drivers/of/of_i2c@lt3.12
+endif
+
+define KernelPackage/i2c-core
+ $(call i2c_defaults,$(I2C_CORE_MODULES),51)
+ TITLE:=I2C support
+endef
+
+define KernelPackage/i2c-core/description
+ Kernel modules for I2C support
+endef
+
+$(eval $(call KernelPackage,i2c-core))
+
+
+I2C_ALGOBIT_MODULES:= \
+ CONFIG_I2C_ALGOBIT:drivers/i2c/algos/i2c-algo-bit
+
+define KernelPackage/i2c-algo-bit
+ $(call i2c_defaults,$(I2C_ALGOBIT_MODULES),55)
+ TITLE:=I2C bit-banging interfaces
+ DEPENDS:=kmod-i2c-core
+endef
+
+define KernelPackage/i2c-algo-bit/description
+ Kernel modules for I2C bit-banging interfaces
+endef
+
+$(eval $(call KernelPackage,i2c-algo-bit))
+
+
+I2C_ALGOPCA_MODULES:= \
+ CONFIG_I2C_ALGOPCA:drivers/i2c/algos/i2c-algo-pca
+
+define KernelPackage/i2c-algo-pca
+ $(call i2c_defaults,$(I2C_ALGOPCA_MODULES),55)
+ TITLE:=I2C PCA 9564 interfaces
+ DEPENDS:=kmod-i2c-core
+endef
+
+define KernelPackage/i2c-algo-pca/description
+ Kernel modules for I2C PCA 9564 interfaces
+endef
+
+$(eval $(call KernelPackage,i2c-algo-pca))
+
+
+I2C_ALGOPCF_MODULES:= \
+ CONFIG_I2C_ALGOPCF:drivers/i2c/algos/i2c-algo-pcf
+
+define KernelPackage/i2c-algo-pcf
+ $(call i2c_defaults,$(I2C_ALGOPCF_MODULES),55)
+ TITLE:=I2C PCF 8584 interfaces
+ DEPENDS:=kmod-i2c-core
+endef
+
+define KernelPackage/i2c-algo-pcf/description
+ Kernel modules for I2C PCF 8584 interfaces
+endef
+
+$(eval $(call KernelPackage,i2c-algo-pcf))
+
+
+I2C_GPIO_MODULES:= \
+ CONFIG_I2C_GPIO:drivers/i2c/busses/i2c-gpio
+
+define KernelPackage/i2c-gpio
+ $(call i2c_defaults,$(I2C_GPIO_MODULES),59)
+ TITLE:=GPIO-based bitbanging I2C
+ DEPENDS:=@GPIO_SUPPORT +kmod-i2c-algo-bit
+endef
+
+define KernelPackage/i2c-gpio/description
+ Kernel modules for a very simple bitbanging I2C driver utilizing the
+ arch-neutral GPIO API to control the SCL and SDA lines.
+endef
+
+$(eval $(call KernelPackage,i2c-gpio))
+
+I2C_MPC_MODULES:=\
+ CONFIG_I2C_MPC:drivers/i2c/busses/i2c-mpc
+
+define KernelPackage/i2c-mpc
+ $(call i2c_defaults,$(I2C_MPC_MODULES),59)
+ TITLE:=MPC I2C accessors
+ DEPENDS:=@TARGET_mpc52xx||TARGET_mpc83xx||TARGET_mpc85xx +kmod-i2c-core
+endef
+
+define KernelPackage/i2c-mpc/description
+ Kernel module for Freescale MPC52xx MPC83xx MPC85xx I2C accessors
+endef
+
+$(eval $(call KernelPackage,i2c-mpc))
+
+I2C_IBM_IIC_MODULES:=\
+ CONFIG_I2C_IBM_IIC:drivers/i2c/busses/i2c-ibm_iic
+
+define KernelPackage/i2c-ibm-iic
+ $(call i2c_defaults,$(OF_I2C_MODULES),59)
+ TITLE:=IBM PPC 4xx on-chip I2C interface support
+ DEPENDS:=@TARGET_ppc40x||TARGET_ppc4xx +kmod-i2c-core
+endef
+
+define KernelPackage/i2c-ibm-iic/description
+ Kernel module for IIC peripheral found on embedded IBM PPC4xx based systems
+endef
+
+$(eval $(call KernelPackage,i2c-ibm-iic))
+
+I2C_MV64XXX_MODULES:=\
+ CONFIG_I2C_MV64XXX:drivers/i2c/busses/i2c-mv64xxx
+
+define KernelPackage/i2c-mv64xxx
+ $(call i2c_defaults,$(I2C_MV64XXX_MODULES),59)
+ TITLE:=Orion Platform I2C interface support
+ DEPENDS:=@TARGET_kirkwood||TARGET_orion||TARGET_mvebu +kmod-i2c-core
+endef
+
+define KernelPackage/i2c-mv64xxx/description
+ Kernel module for I2C interface on the Kirkwood, Orion and Armada XP/370
+ family processors
+endef
+
+$(eval $(call KernelPackage,i2c-mv64xxx))
+
+
+I2C_TINY_USB_MODULES:= \
+ CONFIG_I2C_TINY_USB:drivers/i2c/busses/i2c-tiny-usb
+
+define KernelPackage/i2c-tiny-usb
+ $(call i2c_defaults,$(I2C_TINY_USB_MODULES),59)
+ TITLE:=I2C Tiny USB adaptor
+ DEPENDS:=@USB_SUPPORT kmod-i2c-core +kmod-usb-core
+endef
+
+define KernelPackage/i2c-tiny-usb/description
+ Kernel module for the I2C Tiny USB adaptor developed
+ by Till Harbaum (http://www.harbaum.org/till/i2c_tiny_usb)
+endef
+
+$(eval $(call KernelPackage,i2c-tiny-usb))
+
+
+I2C_PIIX4_MODULES:= \
+ CONFIG_I2C_PIIX4:drivers/i2c/busses/i2c-piix4
+
+define KernelPackage/i2c-piix4
+ $(call i2c_defaults,$(I2C_PIIX4_MODULES),59)
+ TITLE:=Intel PIIX4 and compatible I2C interfaces
+ DEPENDS:=@PCI_SUPPORT @(x86||x86_64) kmod-i2c-core
+endef
+
+define KernelPackage/i2c-piix4/description
+ Support for the Intel PIIX4 family of mainboard I2C interfaces,
+ specifically Intel PIIX4, Intel 440MX, ATI IXP200, ATI IXP300,
+ ATI IXP400, ATI SB600, ATI SB700/SP5100, ATI SB800, AMD Hudson-2,
+ AMD ML, AMD CZ, Serverworks OSB4, Serverworks CSB5,
+ Serverworks CSB6, Serverworks HT-1000, Serverworks HT-1100 and
+ SMSC Victory66.
+endef
+
+$(eval $(call KernelPackage,i2c-piix4))
+
+
+I2C_MUX_MODULES:= \
+ CONFIG_I2C_MUX:drivers/i2c/i2c-mux
+
+define KernelPackage/i2c-mux
+ $(call i2c_defaults,$(I2C_MUX_MODULES),51)
+ TITLE:=I2C bus multiplexing support
+ DEPENDS:=kmod-i2c-core
+endef
+
+define KernelPackage/i2c-mux/description
+ Kernel modules for I2C bus multiplexing support
+endef
+
+$(eval $(call KernelPackage,i2c-mux))
+
+I2C_MUX_GPIO_MODULES:= \
+ CONFIG_I2C_MUX_GPIO:drivers/i2c/muxes/i2c-mux-gpio
+
+define KernelPackage/i2c-mux-gpio
+ $(call i2c_defaults,$(I2C_MUX_GPIO_MODULES),51)
+ TITLE:=GPIO-based I2C mux/switches
+ DEPENDS:=kmod-i2c-mux
+endef
+
+define KernelPackage/i2c-mux-gpio/description
+ Kernel modules for GENERIC_GPIO I2C bus mux/switching devices
+endef
+
+$(eval $(call KernelPackage,i2c-mux-gpio))
+
+I2C_MUX_PCA954x_MODULES:= \
+ CONFIG_I2C_MUX_PCA954x:drivers/i2c/muxes/i2c-mux-pca954x
+
+define KernelPackage/i2c-mux-pca954x
+ $(call i2c_defaults,$(I2C_MUX_PCA954x_MODULES),51)
+ TITLE:=Philips PCA954x I2C mux/switches
+ DEPENDS:=kmod-i2c-mux
+endef
+
+define KernelPackage/i2c-mux-pca954x/description
+ Kernel modules for PCA954x I2C bus mux/switching devices
+endef
+
+$(eval $(call KernelPackage,i2c-mux-pca954x))
+
+
+I2C_MUX_PCA9541_MODULES:= \
+ CONFIG_I2C_MUX_PCA9541:drivers/i2c/muxes/i2c-mux-pca9541
+
+define KernelPackage/i2c-mux-pca9541
+ $(call i2c_defaults,$(I2C_MUX_PCA9541_MODULES),51)
+ TITLE:=Philips PCA9541 I2C mux/switches
+ DEPENDS:=kmod-i2c-mux
+endef
+
+define KernelPackage/i2c-mux-pca9541/description
+ Kernel modules for PCA9541 I2C bus mux/switching devices
+endef
+
+$(eval $(call KernelPackage,i2c-mux-pca9541))
diff --git a/package/kernel/linux/modules/input.mk b/package/kernel/linux/modules/input.mk
new file mode 100644
index 0000000..0539493
--- /dev/null
+++ b/package/kernel/linux/modules/input.mk
@@ -0,0 +1,225 @@
+#
+# Copyright (C) 2006-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+INPUT_MODULES_MENU:=Input modules
+
+define KernelPackage/hid
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=HID Devices
+ DEPENDS:=+kmod-input-core +kmod-input-evdev
+ KCONFIG:=CONFIG_HID CONFIG_HIDRAW=y CONFIG_HID_BATTERY_STRENGTH=y
+ FILES:=$(LINUX_DIR)/drivers/hid/hid.ko
+ AUTOLOAD:=$(call AutoLoad,61,hid)
+endef
+
+define KernelPackage/hid/description
+ Kernel modules for HID devices
+endef
+
+$(eval $(call KernelPackage,hid))
+
+define KernelPackage/hid-generic
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=Generic HID device support
+ DEPENDS:=+kmod-hid
+ KCONFIG:=CONFIG_HID_GENERIC
+ FILES:=$(LINUX_DIR)/drivers/hid/hid-generic.ko
+ AUTOLOAD:=$(call AutoProbe,hid-generic)
+endef
+
+define KernelPackage/hid/description
+ Kernel modules for generic HID device (e.g. keyboards and mice) support
+endef
+
+$(eval $(call KernelPackage,hid-generic))
+
+define KernelPackage/input-core
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=Input device core
+ KCONFIG:=CONFIG_INPUT
+ FILES:=$(LINUX_DIR)/drivers/input/input-core.ko
+endef
+
+define KernelPackage/input-core/description
+ Kernel modules for support of input device
+endef
+
+$(eval $(call KernelPackage,input-core))
+
+
+define KernelPackage/input-evdev
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=Input event device
+ DEPENDS:=+kmod-input-core
+ KCONFIG:=CONFIG_INPUT_EVDEV
+ FILES:=$(LINUX_DIR)/drivers/input/evdev.ko
+ AUTOLOAD:=$(call AutoLoad,60,evdev)
+endef
+
+define KernelPackage/input-evdev/description
+ Kernel modules for support of input device events
+endef
+
+$(eval $(call KernelPackage,input-evdev))
+
+
+define KernelPackage/input-gpio-keys
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=GPIO key support
+ DEPENDS:= @GPIO_SUPPORT +kmod-input-core
+ KCONFIG:= \
+ CONFIG_KEYBOARD_GPIO \
+ CONFIG_INPUT_KEYBOARD=y
+ FILES:=$(LINUX_DIR)/drivers/input/keyboard/gpio_keys.ko
+ AUTOLOAD:=$(call AutoProbe,gpio_keys)
+endef
+
+define KernelPackage/input-gpio-keys/description
+ This driver implements support for buttons connected
+ to GPIO pins of various CPUs (and some other chips).
+
+ See also gpio-button-hotplug which is an alternative, lower overhead
+ implementation that generates uevents instead of kernel input events.
+endef
+
+$(eval $(call KernelPackage,input-gpio-keys))
+
+
+define KernelPackage/input-gpio-keys-polled
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=Polled GPIO key support
+ DEPENDS:=@GPIO_SUPPORT +kmod-input-polldev
+ KCONFIG:= \
+ CONFIG_KEYBOARD_GPIO_POLLED \
+ CONFIG_INPUT_KEYBOARD=y
+ FILES:=$(LINUX_DIR)/drivers/input/keyboard/gpio_keys_polled.ko
+ AUTOLOAD:=$(call AutoProbe,gpio_keys_polled,1)
+endef
+
+define KernelPackage/input-gpio-keys-polled/description
+ Kernel module for support polled GPIO keys input device
+
+ See also gpio-button-hotplug which is an alternative, lower overhead
+ implementation that generates uevents instead of kernel input events.
+endef
+
+$(eval $(call KernelPackage,input-gpio-keys-polled))
+
+
+define KernelPackage/input-gpio-encoder
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=GPIO rotay encoder
+ DEPENDS:=@GPIO_SUPPORT +kmod-input-core
+ KCONFIG:=CONFIG_INPUT_GPIO_ROTARY_ENCODER
+ FILES:=$(LINUX_DIR)/drivers/input/misc/rotary_encoder.ko
+ AUTOLOAD:=$(call AutoProbe,rotary_encoder)
+endef
+
+define KernelPackage/gpio-encoder/description
+ Kernel module to use rotary encoders connected to GPIO pins
+endef
+
+$(eval $(call KernelPackage,input-gpio-encoder))
+
+
+define KernelPackage/input-joydev
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=Joystick device support
+ DEPENDS:=+kmod-input-core
+ KCONFIG:=CONFIG_INPUT_JOYDEV
+ FILES:=$(LINUX_DIR)/drivers/input/joydev.ko
+ AUTOLOAD:=$(call AutoProbe,joydev)
+endef
+
+define KernelPackage/input-joydev/description
+ Kernel module for joystick support
+endef
+
+$(eval $(call KernelPackage,input-joydev))
+
+
+define KernelPackage/input-polldev
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=Polled Input device support
+ DEPENDS:=+kmod-input-core
+ KCONFIG:=CONFIG_INPUT_POLLDEV
+ FILES:=$(LINUX_DIR)/drivers/input/input-polldev.ko
+endef
+
+define KernelPackage/input-polldev/description
+ Kernel module for support of polled input devices
+endef
+
+$(eval $(call KernelPackage,input-polldev))
+
+
+define KernelPackage/input-matrixkmap
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=Input matrix devices support
+ DEPENDS:=+kmod-input-core
+ KCONFIG:=CONFIG_INPUT_MATRIXKMAP
+ FILES:=$(LINUX_DIR)/drivers/input/matrix-keymap.ko
+ AUTOLOAD:=$(call AutoProbe,matrix-keymap)
+endef
+
+define KernelPackage/input-matrix/description
+ Kernel module support for input matrix devices
+endef
+
+$(eval $(call KernelPackage,input-matrixkmap))
+
+
+define KernelPackage/acpi-button
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=ACPI Button Support
+ DEPENDS:=@(TARGET_x86_generic||TARGET_x86_kvm_guest||TARGET_x86_xen_domu||TARGET_x86_64) +kmod-input-evdev
+ KCONFIG:=CONFIG_ACPI_BUTTON
+ FILES:=$(LINUX_DIR)/drivers/acpi/button.ko
+ AUTOLOAD:=$(call AutoLoad,06,button)
+endef
+
+define KernelPackage/acpi-button/description
+ Kernel module for ACPI Button support
+endef
+
+$(eval $(call KernelPackage,acpi-button))
+
+
+define KernelPackage/keyboard-imx
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=IMX keypad support
+ DEPENDS:=@(TARGET_mxs||TARGET_imx6) +kmod-input-matrixkmap
+ KCONFIG:= \
+ CONFIG_KEYBOARD_IMX \
+ CONFIG_INPUT_KEYBOARD=y
+ FILES:=$(LINUX_DIR)/drivers/input/keyboard/imx_keypad.ko
+ AUTOLOAD:=$(call AutoProbe,imx_keypad)
+endef
+
+define KernelPackage/keyboard-imx/description
+ Enable support for IMX keypad port.
+endef
+
+$(eval $(call KernelPackage,keyboard-imx))
+
+
+define KernelPackage/input-uinput
+ SUBMENU:=$(INPUT_MODULES_MENU)
+ TITLE:=user input module
+ DEPENDS:=+kmod-input-core
+ KCONFIG:= \
+ CONFIG_INPUT_MISC=y \
+ CONFIG_INPUT_UINPUT
+ FILES:=$(LINUX_DIR)/drivers/input/misc/uinput.ko
+ AUTOLOAD:=$(call AutoProbe,uinput)
+endef
+
+define KernelPackage/input-uinput/description
+ user input modules needed for bluez
+endef
+
+$(eval $(call KernelPackage,input-uinput))
diff --git a/package/kernel/linux/modules/leds.mk b/package/kernel/linux/modules/leds.mk
new file mode 100644
index 0000000..996deb3
--- /dev/null
+++ b/package/kernel/linux/modules/leds.mk
@@ -0,0 +1,215 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+LEDS_MENU:=LED modules
+
+define KernelPackage/leds-gpio
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=GPIO LED support
+ DEPENDS:= @GPIO_SUPPORT
+ KCONFIG:=CONFIG_LEDS_GPIO
+ FILES:=$(LINUX_DIR)/drivers/leds/leds-gpio.ko
+ AUTOLOAD:=$(call AutoLoad,60,leds-gpio,1)
+endef
+
+define KernelPackage/leds-gpio/description
+ Kernel module for LEDs on GPIO lines
+endef
+
+$(eval $(call KernelPackage,leds-gpio))
+
+LED_TRIGGER_DIR=$(LINUX_DIR)/drivers/leds/trigger
+
+define KernelPackage/ledtrig-heartbeat
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=LED Heartbeat Trigger
+ KCONFIG:=CONFIG_LEDS_TRIGGER_HEARTBEAT
+ FILES:=$(LED_TRIGGER_DIR)/ledtrig-heartbeat.ko
+ AUTOLOAD:=$(call AutoLoad,50,ledtrig-heartbeat)
+endef
+
+define KernelPackage/ledtrig-gpio/description
+ Kernel module that allows LEDs to blink like heart beat
+endef
+
+$(eval $(call KernelPackage,ledtrig-heartbeat))
+
+
+define KernelPackage/ledtrig-gpio
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=LED GPIO Trigger
+ KCONFIG:=CONFIG_LEDS_TRIGGER_GPIO
+ FILES:=$(LED_TRIGGER_DIR)/ledtrig-gpio.ko
+ AUTOLOAD:=$(call AutoLoad,50,ledtrig-gpio)
+endef
+
+define KernelPackage/ledtrig-gpio/description
+ Kernel module that allows LEDs to be controlled by gpio events
+endef
+
+$(eval $(call KernelPackage,ledtrig-gpio))
+
+
+define KernelPackage/ledtrig-morse
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=LED Morse Trigger
+ KCONFIG:=CONFIG_LEDS_TRIGGER_MORSE
+ FILES:=$(LINUX_DIR)/drivers/leds/ledtrig-morse.ko
+ AUTOLOAD:=$(call AutoLoad,50,ledtrig-morse)
+endef
+
+define KernelPackage/ledtrig-morse/description
+ Kernel module to show morse coded messages on LEDs
+endef
+
+$(eval $(call KernelPackage,ledtrig-morse))
+
+
+define KernelPackage/ledtrig-netdev
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=LED NETDEV Trigger
+ KCONFIG:=CONFIG_LEDS_TRIGGER_NETDEV
+ FILES:=$(LINUX_DIR)/drivers/leds/ledtrig-netdev.ko
+ AUTOLOAD:=$(call AutoLoad,50,ledtrig-netdev)
+endef
+
+define KernelPackage/ledtrig-netdev/description
+ Kernel module to drive LEDs based on network activity
+endef
+
+$(eval $(call KernelPackage,ledtrig-netdev))
+
+
+define KernelPackage/ledtrig-netfilter
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=LED NetFilter Trigger
+ DEPENDS:=kmod-ipt-core
+ KCONFIG:=CONFIG_NETFILTER_XT_TARGET_LED
+ FILES:=$(LINUX_DIR)/net/netfilter/xt_LED.ko
+ AUTOLOAD:=$(call AutoLoad,50,xt_LED)
+endef
+
+define KernelPackage/ledtrig-netfilter/description
+ Kernel module to flash LED when a particular packets passing through your machine.
+
+ For example to create an LED trigger for incoming SSH traffic:
+ iptables -A INPUT -p tcp --dport 22 -j LED --led-trigger-id ssh --led-delay 1000
+ Then attach the new trigger to an LED on your system:
+ echo netfilter-ssh > /sys/class/leds/<ledname>/trigger
+endef
+
+$(eval $(call KernelPackage,ledtrig-netfilter))
+
+
+define KernelPackage/ledtrig-usbdev
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=LED USB device Trigger
+ DEPENDS:=@USB_SUPPORT kmod-usb-core
+ KCONFIG:=CONFIG_LEDS_TRIGGER_USBDEV
+ FILES:=$(LINUX_DIR)/drivers/leds/ledtrig-usbdev.ko
+ AUTOLOAD:=$(call AutoLoad,50,ledtrig-usbdev)
+endef
+
+define KernelPackage/ledtrig-usbdev/description
+ Kernel module to drive LEDs based on USB device presence/activity
+endef
+
+$(eval $(call KernelPackage,ledtrig-usbdev))
+
+
+define KernelPackage/ledtrig-default-on
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=LED Default ON Trigger
+ KCONFIG:=CONFIG_LEDS_TRIGGER_DEFAULT_ON
+ FILES:=$(LED_TRIGGER_DIR)/ledtrig-default-on.ko
+ AUTOLOAD:=$(call AutoLoad,50,ledtrig-default-on,1)
+endef
+
+define KernelPackage/ledtrig-default-on/description
+ Kernel module that allows LEDs to be initialised in the ON state
+endef
+
+$(eval $(call KernelPackage,ledtrig-default-on))
+
+
+define KernelPackage/ledtrig-timer
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=LED Timer Trigger
+ KCONFIG:=CONFIG_LEDS_TRIGGER_TIMER
+ FILES:=$(LED_TRIGGER_DIR)/ledtrig-timer.ko
+ AUTOLOAD:=$(call AutoLoad,50,ledtrig-timer,1)
+endef
+
+define KernelPackage/ledtrig-timer/description
+ Kernel module that allows LEDs to be controlled by a programmable timer
+ via sysfs
+endef
+
+$(eval $(call KernelPackage,ledtrig-timer))
+
+
+define KernelPackage/ledtrig-transient
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=LED Transient Trigger
+ KCONFIG:=CONFIG_LEDS_TRIGGER_TRANSIENT
+ FILES:=$(LED_TRIGGER_DIR)/ledtrig-transient.ko
+ AUTOLOAD:=$(call AutoLoad,50,ledtrig-transient,1)
+endef
+
+define KernelPackage/ledtrig-transient/description
+ Kernel module that allows LEDs one time activation of a transient state.
+endef
+
+$(eval $(call KernelPackage,ledtrig-transient))
+
+
+define KernelPackage/ledtrig-oneshot
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=LED One-Shot Trigger
+ KCONFIG:=CONFIG_LEDS_TRIGGER_ONESHOT
+ FILES:=$(LED_TRIGGER_DIR)/ledtrig-oneshot.ko
+ AUTOLOAD:=$(call AutoLoad,50,ledtrig-oneshot)
+endef
+
+define KernelPackage/ledtrig-oneshot/description
+ Kernel module that allows LEDs to be triggered by sporadic events in
+ one-shot pulses
+endef
+
+$(eval $(call KernelPackage,ledtrig-oneshot))
+
+
+define KernelPackage/leds-pca963x
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=PCA963x LED support
+ DEPENDS:=+kmod-i2c-core
+ KCONFIG:=CONFIG_LEDS_PCA963X
+ FILES:=$(LINUX_DIR)/drivers/leds/leds-pca963x.ko
+ AUTOLOAD:=$(call AutoLoad,60,leds-pca963x,1)
+endef
+
+define KernelPackage/leds-pca963x/description
+ Driver for the NXP PCA963x I2C LED controllers.
+endef
+
+$(eval $(call KernelPackage,leds-pca963x))
+
+
+define KernelPackage/leds-tlc59116
+ SUBMENU:=$(LEDS_MENU)
+ TITLE:=TLC59116 LED support
+ DEPENDS:=@TARGET_mvebu +kmod-i2c-core +kmod-regmap
+ KCONFIG:=CONFIG_LEDS_TLC59116
+ FILES:=$(LINUX_DIR)/drivers/leds/leds-tlc59116.ko
+ AUTOLOAD:=$(call AutoLoad,60,leds-tlc59116,1)
+endef
+
+define KernelPackage/leds-tlc59116/description
+ Kernel module for LEDs on TLC59116
+endef
+
+$(eval $(call KernelPackage,leds-tlc59116))
diff --git a/package/kernel/linux/modules/lib.mk b/package/kernel/linux/modules/lib.mk
new file mode 100644
index 0000000..9d35e42
--- /dev/null
+++ b/package/kernel/linux/modules/lib.mk
@@ -0,0 +1,223 @@
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+LIB_MENU:=Libraries
+
+define KernelPackage/lib-crc-ccitt
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=CRC-CCITT support
+ KCONFIG:=CONFIG_CRC_CCITT
+ FILES:=$(LINUX_DIR)/lib/crc-ccitt.ko
+ AUTOLOAD:=$(call AutoProbe,crc-ccitt)
+endef
+
+define KernelPackage/lib-crc-ccitt/description
+ Kernel module for CRC-CCITT support
+endef
+
+$(eval $(call KernelPackage,lib-crc-ccitt))
+
+
+define KernelPackage/lib-crc-itu-t
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=CRC ITU-T V.41 support
+ KCONFIG:=CONFIG_CRC_ITU_T
+ FILES:=$(LINUX_DIR)/lib/crc-itu-t.ko
+ AUTOLOAD:=$(call AutoProbe,crc-itu-t)
+endef
+
+define KernelPackage/lib-crc-itu-t/description
+ Kernel module for CRC ITU-T V.41 support
+endef
+
+$(eval $(call KernelPackage,lib-crc-itu-t))
+
+
+define KernelPackage/lib-crc7
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=CRC7 support
+ KCONFIG:=CONFIG_CRC7
+ FILES:=$(LINUX_DIR)/lib/crc7.ko
+ AUTOLOAD:=$(call AutoProbe,crc7)
+endef
+
+define KernelPackage/lib-crc7/description
+ Kernel module for CRC7 support
+endef
+
+$(eval $(call KernelPackage,lib-crc7))
+
+
+define KernelPackage/lib-crc8
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=CRC8 support
+ KCONFIG:=CONFIG_CRC8
+ FILES:=$(LINUX_DIR)/lib/crc8.ko
+ AUTOLOAD:=$(call AutoProbe,crc8)
+endef
+
+define KernelPackage/lib-crc8/description
+ Kernel module for CRC8 support
+endef
+
+$(eval $(call KernelPackage,lib-crc8))
+
+
+define KernelPackage/lib-crc16
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=CRC16 support
+ KCONFIG:=CONFIG_CRC16
+ FILES:=$(LINUX_DIR)/lib/crc16.ko
+ AUTOLOAD:=$(call AutoLoad,20,crc16,1)
+endef
+
+define KernelPackage/lib-crc16/description
+ Kernel module for CRC16 support
+endef
+
+$(eval $(call KernelPackage,lib-crc16))
+
+
+define KernelPackage/lib-crc32c
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=CRC32 support
+ KCONFIG:=CONFIG_LIBCRC32C
+ DEPENDS:=+kmod-crypto-crc32c
+ FILES:=$(LINUX_DIR)/lib/libcrc32c.ko
+ AUTOLOAD:=$(call AutoProbe,libcrc32c)
+endef
+
+define KernelPackage/lib-crc32c/description
+ Kernel module for CRC32 support
+endef
+
+$(eval $(call KernelPackage,lib-crc32c))
+
+
+define KernelPackage/lib-lzo
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=LZO support
+ KCONFIG:= \
+ CONFIG_LZO_COMPRESS \
+ CONFIG_LZO_DECOMPRESS
+ FILES:= \
+ $(LINUX_DIR)/lib/lzo/lzo_compress.ko \
+ $(LINUX_DIR)/lib/lzo/lzo_decompress.ko
+ AUTOLOAD:=$(call AutoProbe,lzo_compress lzo_decompress)
+endef
+
+define KernelPackage/lib-lzo/description
+ Kernel module for LZO compression/decompression support
+endef
+
+$(eval $(call KernelPackage,lib-lzo))
+
+
+define KernelPackage/lib-lz4
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=LZ4 support
+ KCONFIG:= \
+ CONFIG_LZ4_COMPRESS \
+ CONFIG_LZ4_DECOMPRESS
+ FILES:= \
+ $(LINUX_DIR)/lib/lz4/lz4_compress.ko \
+ $(LINUX_DIR)/lib/lz4/lz4_decompress.ko
+ AUTOLOAD:=$(call AutoProbe,lz4_compress lz4_decompress)
+endef
+
+define KernelPackage/lib-lz4/description
+ Kernel module for LZ4 compression/decompression support
+endef
+
+$(eval $(call KernelPackage,lib-lz4))
+
+
+define KernelPackage/lib-raid6
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=RAID6 algorithm support
+ HIDDEN:=1
+ KCONFIG:=CONFIG_RAID6_PQ
+ FILES:=$(LINUX_DIR)/lib/raid6/raid6_pq.ko
+ AUTOLOAD:=$(call AutoProbe,raid6_pq)
+endef
+
+define KernelPackage/lib-raid6/description
+ Kernel module for RAID6 algorithms
+endef
+
+$(eval $(call KernelPackage,lib-raid6))
+
+
+define KernelPackage/lib-xor
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=XOR blocks algorithm support
+ HIDDEN:=1
+ KCONFIG:=CONFIG_XOR_BLOCKS
+ifneq ($(wildcard $(LINUX_DIR)/arch/arm/lib/xor-neon.ko),)
+ FILES:= \
+ $(LINUX_DIR)/crypto/xor.ko \
+ $(LINUX_DIR)/arch/arm/lib/xor-neon.ko
+ AUTOLOAD:=$(call AutoProbe,xor-neon xor)
+else
+ FILES:=$(LINUX_DIR)/crypto/xor.ko
+ AUTOLOAD:=$(call AutoProbe,xor)
+endif
+endef
+
+define KernelPackage/lib-xor/description
+ Kernel module for XOR blocks algorithms
+endef
+
+$(eval $(call KernelPackage,lib-xor))
+
+
+define KernelPackage/lib-textsearch
+SUBMENU:=$(LIB_MENU)
+ TITLE:=Textsearch support
+ KCONFIG:= \
+ CONFIG_TEXTSEARCH=y \
+ CONFIG_TEXTSEARCH_KMP \
+ CONFIG_TEXTSEARCH_BM \
+ CONFIG_TEXTSEARCH_FSM
+ FILES:= \
+ $(LINUX_DIR)/lib/ts_kmp.ko \
+ $(LINUX_DIR)/lib/ts_bm.ko \
+ $(LINUX_DIR)/lib/ts_fsm.ko
+ AUTOLOAD:=$(call AutoProbe,ts_kmp ts_bm ts_fsm)
+endef
+
+$(eval $(call KernelPackage,lib-textsearch))
+
+
+define KernelPackage/lib-zlib
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=Zlib support
+ KCONFIG:= \
+ CONFIG_ZLIB_DEFLATE \
+ CONFIG_ZLIB_INFLATE
+ FILES:= \
+ $(LINUX_DIR)/lib/zlib_deflate/zlib_deflate.ko \
+ $(LINUX_DIR)/lib/zlib_inflate/zlib_inflate.ko
+ AUTOLOAD:=$(call AutoProbe,zlib_deflate zlib_inflate)
+endef
+
+$(eval $(call KernelPackage,lib-zlib))
+
+
+define KernelPackage/lib-cordic
+ SUBMENU:=$(LIB_MENU)
+ TITLE:=Cordic function support
+ KCONFIG:=CONFIG_CORDIC
+ FILES:=$(LINUX_DIR)/lib/cordic.ko
+ AUTOLOAD:=$(call AutoProbe,cordic)
+endef
+
+define KernelPackage/lib-cordic/description
+ Kernel module for Cordic function support
+endef
+
+$(eval $(call KernelPackage,lib-cordic))
diff --git a/package/kernel/linux/modules/netdevices.mk b/package/kernel/linux/modules/netdevices.mk
new file mode 100644
index 0000000..ef3cf85
--- /dev/null
+++ b/package/kernel/linux/modules/netdevices.mk
@@ -0,0 +1,859 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+NETWORK_DEVICES_MENU:=Network Devices
+
+define KernelPackage/sis190
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=SiS 190 Fast/Gigabit Ethernet support
+ DEPENDS:=@PCI_SUPPORT +kmod-mii
+ KCONFIG:=CONFIG_SIS190
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/sis/sis190.ko
+ AUTOLOAD:=$(call AutoProbe,sis190)
+endef
+
+$(eval $(call KernelPackage,sis190))
+
+
+define KernelPackage/skge
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=SysKonnect Yukon support
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_SKGE \
+ CONFIG_SKGE_DEBUG=n \
+ CONFIG_SKGE_GENESIS=n
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/marvell/skge.ko
+ AUTOLOAD:=$(call AutoProbe,skge)
+endef
+
+$(eval $(call KernelPackage,skge))
+
+
+define KernelPackage/atl2
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Atheros L2 Fast Ethernet support
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_ATL2
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/atheros/atlx/atl2.ko
+ AUTOLOAD:=$(call AutoProbe,atl2)
+endef
+
+$(eval $(call KernelPackage,atl2))
+
+
+define KernelPackage/atl1
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Atheros L1 Gigabit Ethernet support
+ DEPENDS:=@PCI_SUPPORT +kmod-mii
+ KCONFIG:=CONFIG_ATL1
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/atheros/atlx/atl1.ko
+ AUTOLOAD:=$(call AutoProbe,atl1)
+endef
+
+$(eval $(call KernelPackage,atl1))
+
+
+define KernelPackage/atl1c
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Atheros L1C
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_ATL1C
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/atheros/atl1c/atl1c.ko
+ AUTOLOAD:=$(call AutoProbe,atl1c)
+endef
+
+$(eval $(call KernelPackage,atl1c))
+
+
+define KernelPackage/atl1e
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Atheros L1E
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_ATL1E
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/atheros/atl1e/atl1e.ko
+ AUTOLOAD:=$(call AutoProbe,atl1e)
+endef
+
+$(eval $(call KernelPackage,atl1e))
+
+
+define KernelPackage/libphy
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=PHY library
+ KCONFIG:=CONFIG_PHYLIB
+ FILES:=$(LINUX_DIR)/drivers/net/phy/libphy.ko
+ AUTOLOAD:=$(call AutoLoad,15,libphy,1)
+endef
+
+define KernelPackage/libphy/description
+ PHY library
+endef
+
+$(eval $(call KernelPackage,libphy))
+
+define KernelPackage/mii
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=MII library
+ KCONFIG:=CONFIG_MII
+ FILES:=$(LINUX_DIR)/drivers/net/mii.ko
+ AUTOLOAD:=$(call AutoLoad,15,mii,1)
+endef
+
+define KernelPackage/mii/description
+ MII library
+endef
+
+$(eval $(call KernelPackage,mii))
+
+
+define KernelPackage/et131x
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Agere ET131x Gigabit Ethernet driver
+ URL:=http://sourceforge.net/projects/et131x
+ FILES:= \
+ $(LINUX_DIR)/drivers/net/ethernet/agere/et131x.ko
+ KCONFIG:= \
+ CONFIG_ET131X \
+ CONFIG_ET131X_DEBUG=n
+ DEPENDS:=@PCI_SUPPORT +kmod-libphy
+ AUTOLOAD:=$(call AutoProbe,et131x)
+endef
+
+define KernelPackage/et131x/description
+ This package contains the et131x kernel module
+endef
+
+$(eval $(call KernelPackage,et131x))
+
+
+define KernelPackage/gw16083
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Gateworks Ventana Ethernet Expansion Mezzanine driver
+ URL:=http://www.gateworks.com
+ FILES:=$(LINUX_DIR)/drivers/net/phy/gw16083.ko
+ KCONFIG:=CONFIG_GATEWORKS_GW16083
+ DEPENDS:=@TARGET_imx6 @PCI_SUPPORT +kmod-libphy +kmod-igb
+ AUTOLOAD:=$(call AutoLoad,36,gw16083)
+endef
+
+define KernelPackage/gw16083/description
+ This package contains the gw16083 kernel module for supporting the Gateworks
+ Ventana Ethernet Expansion Mezzanine.
+endef
+
+$(eval $(call KernelPackage,gw16083))
+
+
+define KernelPackage/phy-broadcom
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Broadcom Ethernet PHY driver
+ KCONFIG:=CONFIG_BROADCOM_PHY
+ DEPENDS:=+kmod-libphy
+ FILES:=$(LINUX_DIR)/drivers/net/phy/broadcom.ko
+ AUTOLOAD:=$(call AutoLoad,18,broadcom)
+endef
+
+define KernelPackage/phy-broadcom/description
+ Currently supports the BCM5411, BCM5421, BCM5461, BCM5464, BCM5481,
+ BCM5482 and BCM57780 PHYs.
+endef
+
+$(eval $(call KernelPackage,phy-broadcom))
+
+
+define KernelPackage/swconfig
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=switch configuration API
+ DEPENDS:=+kmod-libphy
+ KCONFIG:=CONFIG_SWCONFIG
+ FILES:=$(LINUX_DIR)/drivers/net/phy/swconfig.ko
+ AUTOLOAD:=$(call AutoLoad,41,swconfig)
+endef
+
+define KernelPackage/swconfig/description
+ Switch configuration API module
+endef
+
+$(eval $(call KernelPackage,swconfig))
+
+define KernelPackage/switch-mvsw61xx
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Marvell 88E61xx switch support
+ DEPENDS:=+kmod-swconfig
+ KCONFIG:=CONFIG_MVSW61XX_PHY
+ FILES:=$(LINUX_DIR)/drivers/net/phy/mvsw61xx.ko
+ AUTOLOAD:=$(call AutoLoad,42,mvsw61xx)
+endef
+
+define KernelPackage/switch-mvsw61xx/description
+ Marvell 88E61xx switch support
+endef
+
+$(eval $(call KernelPackage,switch-mvsw61xx))
+
+define KernelPackage/switch-ip17xx
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=IC+ IP17XX switch support
+ DEPENDS:=+kmod-swconfig
+ KCONFIG:=CONFIG_IP17XX_PHY
+ FILES:=$(LINUX_DIR)/drivers/net/phy/ip17xx.ko
+ AUTOLOAD:=$(call AutoLoad,42,ip17xx)
+endef
+
+define KernelPackage/switch-ip17xx/description
+ IC+ IP175C/IP178C switch support
+endef
+
+$(eval $(call KernelPackage,switch-ip17xx))
+
+
+define KernelPackage/switch-rtl8366-smi
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Realtek RTL8366 SMI switch interface support
+ DEPENDS:=@GPIO_SUPPORT +kmod-swconfig
+ KCONFIG:=CONFIG_RTL8366_SMI
+ FILES:=$(LINUX_DIR)/drivers/net/phy/rtl8366_smi.ko
+ AUTOLOAD:=$(call AutoLoad,42,rtl8366_smi)
+endef
+
+define KernelPackage/switch-rtl8366_smi/description
+ Realtek RTL8366 series SMI switch interface support
+endef
+
+$(eval $(call KernelPackage,switch-rtl8366-smi))
+
+
+define KernelPackage/switch-rtl8366rb
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Realtek RTL8366RB switch support
+ DEPENDS:=+kmod-switch-rtl8366-smi
+ KCONFIG:=CONFIG_RTL8366RB_PHY
+ FILES:=$(LINUX_DIR)/drivers/net/phy/rtl8366rb.ko
+ AUTOLOAD:=$(call AutoLoad,43,rtl8366rb)
+endef
+
+define KernelPackage/switch-rtl8366rb/description
+ Realtek RTL8366RB switch support
+endef
+
+$(eval $(call KernelPackage,switch-rtl8366rb))
+
+
+define KernelPackage/switch-rtl8366s
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Realtek RTL8366S switch support
+ DEPENDS:=+kmod-switch-rtl8366-smi
+ KCONFIG:=CONFIG_RTL8366S_PHY
+ FILES:=$(LINUX_DIR)/drivers/net/phy/rtl8366s.ko
+ AUTOLOAD:=$(call AutoLoad,43,rtl8366s)
+endef
+
+define KernelPackage/switch-rtl8366s/description
+ Realtek RTL8366S switch support
+endef
+
+$(eval $(call KernelPackage,switch-rtl8366s))
+
+
+define KernelPackage/natsemi
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=National Semiconductor DP8381x series
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_NATSEMI
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/natsemi/natsemi.ko
+ AUTOLOAD:=$(call AutoLoad,20,natsemi)
+endef
+
+define KernelPackage/natsemi/description
+ Kernel modules for National Semiconductor DP8381x series PCI Ethernet
+ adapters.
+endef
+
+$(eval $(call KernelPackage,natsemi))
+
+
+define KernelPackage/r6040
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=RDC Fast-Ethernet support
+ DEPENDS:=@PCI_SUPPORT +kmod-libphy
+ KCONFIG:=CONFIG_R6040 \
+ CONFIG_R6040_NAPI=y
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/rdc/r6040.ko
+ AUTOLOAD:=$(call AutoProbe,r6040)
+endef
+
+define KernelPackage/r6040/description
+ Kernel modules for RDC Fast-Ethernet adapters.
+endef
+
+$(eval $(call KernelPackage,r6040))
+
+
+define KernelPackage/sis900
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=SiS 900 Ethernet support
+ DEPENDS:=@PCI_SUPPORT +kmod-mii
+ KCONFIG:=CONFIG_SIS900
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/sis/sis900.ko
+ AUTOLOAD:=$(call AutoProbe,sis900)
+endef
+
+define KernelPackage/sis900/description
+ Kernel modules for Sis 900 Ethernet adapters.
+endef
+
+$(eval $(call KernelPackage,sis900))
+
+
+define KernelPackage/sky2
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=SysKonnect Yukon2 support
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_SKY2
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/marvell/sky2.ko
+ AUTOLOAD:=$(call AutoProbe,sky2)
+endef
+
+define KernelPackage/sky2/description
+ This driver supports Gigabit Ethernet adapters based on the
+ Marvell Yukon 2 chipset:
+ Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
+ 88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21
+
+ There is companion driver for the older Marvell Yukon and
+ Genesis based adapters: skge.
+endef
+
+$(eval $(call KernelPackage,sky2))
+
+
+define KernelPackage/via-rhine
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Via Rhine ethernet support
+ DEPENDS:=@PCI_SUPPORT +kmod-mii
+ KCONFIG:=CONFIG_VIA_RHINE \
+ CONFIG_VIA_RHINE_MMIO=y
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/via/via-rhine.ko
+ AUTOLOAD:=$(call AutoProbe,via-rhine)
+endef
+
+define KernelPackage/via-rhine/description
+ Kernel modules for Via Rhine Ethernet chipsets
+endef
+
+$(eval $(call KernelPackage,via-rhine))
+
+
+define KernelPackage/via-velocity
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=VIA Velocity Gigabit Ethernet Adapter kernel support
+ DEPENDS:=@TARGET_ixp4xx||TARGET_mpc83xx||PCI_SUPPORT +kmod-lib-crc-ccitt
+ KCONFIG:=CONFIG_VIA_VELOCITY
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/via/via-velocity.ko
+ AUTOLOAD:=$(call AutoProbe,via-velocity)
+endef
+
+define KernelPackage/via-velocity/description
+ Kernel modules for VIA Velocity Gigabit Ethernet chipsets
+endef
+
+$(eval $(call KernelPackage,via-velocity))
+
+
+define KernelPackage/8139too
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=RealTek RTL-8139 PCI Fast Ethernet Adapter kernel support
+ DEPENDS:=@PCI_SUPPORT +kmod-mii
+ KCONFIG:=CONFIG_8139TOO \
+ CONFIG_8139TOO_PIO=y \
+ CONFIG_8139TOO_TUNE_TWISTER=n \
+ CONFIG_8139TOO_8129=n \
+ CONFIG_8139_OLD_RX_RESET=n
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/realtek/8139too.ko
+ AUTOLOAD:=$(call AutoProbe,8139too)
+endef
+
+define KernelPackage/8139too/description
+ Kernel modules for RealTek RTL-8139 PCI Fast Ethernet adapters
+endef
+
+$(eval $(call KernelPackage,8139too))
+
+
+define KernelPackage/8139cp
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=RealTek RTL-8139C+ PCI Fast Ethernet Adapter kernel support
+ DEPENDS:=@PCI_SUPPORT +kmod-mii
+ KCONFIG:=CONFIG_8139CP
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/realtek/8139cp.ko
+ AUTOLOAD:=$(call AutoProbe,8139cp)
+endef
+
+define KernelPackage/8139cp/description
+ Kernel module for RealTek RTL-8139C+ PCI Fast Ethernet adapters
+endef
+
+$(eval $(call KernelPackage,8139cp))
+
+
+define KernelPackage/r8169
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=RealTek RTL-8169 PCI Gigabit Ethernet Adapter kernel support
+ DEPENDS:=@PCI_SUPPORT +kmod-mii +r8169-firmware
+ KCONFIG:=CONFIG_R8169 \
+ CONFIG_R8169_NAPI=y \
+ CONFIG_R8169_VLAN=n
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/realtek/r8169.ko
+ AUTOLOAD:=$(call AutoProbe,r8169)
+endef
+
+define KernelPackage/r8169/description
+ Kernel modules for RealTek RTL-8169 PCI Gigabit Ethernet adapters
+endef
+
+$(eval $(call KernelPackage,r8169))
+
+
+define KernelPackage/ne2k-pci
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=ne2k-pci Ethernet Adapter kernel support
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_NE2K_PCI
+ FILES:= \
+ $(LINUX_DIR)/drivers/net/ethernet/8390/ne2k-pci.ko \
+ $(LINUX_DIR)/drivers/net/ethernet/8390/8390.ko
+ AUTOLOAD:=$(call AutoProbe,8390 ne2k-pci)
+endef
+
+define KernelPackage/ne2k-pci/description
+ Kernel modules for NE2000 PCI Ethernet Adapter kernel
+endef
+
+$(eval $(call KernelPackage,ne2k-pci))
+
+
+define KernelPackage/e100
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Intel(R) PRO/100+ cards kernel support
+ DEPENDS:=@PCI_SUPPORT +kmod-mii
+ KCONFIG:=CONFIG_E100
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/intel/e100.ko
+ AUTOLOAD:=$(call AutoProbe,e100)
+endef
+
+define KernelPackage/e100/description
+ Kernel modules for Intel(R) PRO/100+ Ethernet adapters
+endef
+
+define KernelPackage/e100/install
+ $(INSTALL_DIR) $(1)/lib/firmware/e100
+ $(foreach file,d101m_ucode.bin d101s_ucode.bin d102e_ucode.bin, \
+ $(TARGET_CROSS)objcopy -Iihex -Obinary $(LINUX_DIR)/firmware/e100/$(file).ihex $(1)/lib/firmware/e100/$(file); \
+ )
+endef
+
+$(eval $(call KernelPackage,e100))
+
+
+define KernelPackage/e1000
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Intel(R) PRO/1000 PCI cards kernel support
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_E1000 \
+ CONFIG_E1000_DISABLE_PACKET_SPLIT=n \
+ CONFIG_E1000_NAPI=y
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/intel/e1000/e1000.ko
+ AUTOLOAD:=$(call AutoLoad,35,e1000)
+endef
+
+define KernelPackage/e1000/description
+ Kernel modules for Intel(R) PRO/1000 PCI Ethernet adapters.
+endef
+
+$(eval $(call KernelPackage,e1000))
+
+
+define KernelPackage/e1000e
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Intel(R) PRO/1000 PCIe cards kernel support
+ DEPENDS:=@PCIE_SUPPORT +kmod-ptp
+ KCONFIG:=CONFIG_E1000E
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/intel/e1000e/e1000e.ko
+ AUTOLOAD:=$(call AutoProbe,e1000e)
+endef
+
+define KernelPackage/e1000e/description
+ Kernel modules for Intel(R) PRO/1000 PCIe Ethernet adapters.
+endef
+
+$(eval $(call KernelPackage,e1000e))
+
+
+define KernelPackage/igb
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support
+ DEPENDS:=@PCI_SUPPORT +kmod-i2c-algo-bit +kmod-ptp
+ KCONFIG:=CONFIG_IGB \
+ CONFIG_IGB_HWMON=n \
+ CONFIG_IGB_DCA=n
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/intel/igb/igb.ko
+ AUTOLOAD:=$(call AutoLoad,35,igb)
+endef
+
+define KernelPackage/igb/description
+ Kernel modules for Intel(R) 82575/82576 PCI-Express Gigabit Ethernet adapters.
+endef
+
+$(eval $(call KernelPackage,igb))
+
+
+define KernelPackage/b44
+ TITLE:=Broadcom 44xx driver
+ KCONFIG:=CONFIG_B44
+ DEPENDS:=@PCI_SUPPORT @!TARGET_brcm47xx_mips74k +!TARGET_brcm47xx:kmod-ssb +kmod-mii +kmod-libphy
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/broadcom/b44.ko
+ AUTOLOAD:=$(call AutoLoad,19,b44,1)
+endef
+
+define KernelPackage/b44/description
+ Kernel modules for Broadcom 44xx Ethernet adapters.
+endef
+
+$(eval $(call KernelPackage,b44))
+
+
+define KernelPackage/3c59x
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=3Com 3c590/3c900 series (592/595/597) Vortex/Boomerang
+ DEPENDS:=@PCI_SUPPORT +kmod-mii
+ KCONFIG:=CONFIG_VORTEX
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/3com/3c59x.ko
+ AUTOLOAD:=$(call AutoProbe,3c59x)
+endef
+
+define KernelPackage/3c59x/description
+ This option enables driver support for a large number of 10mbps and
+ 10/100mbps EISA, PCI and PCMCIA 3Com Ethernet adapters:
+ - "Vortex" (Fast EtherLink 3c590/3c592/3c595/3c597) EISA and PCI
+ - "Boomerang" (EtherLink XL 3c900 or 3c905) PCI
+ - "Cyclone" (3c540/3c900/3c905/3c980/3c575/3c656) PCI and Cardbus
+ - "Tornado" (3c905) PCI
+ - "Hurricane" (3c555/3cSOHO) PCI
+endef
+
+$(eval $(call KernelPackage,3c59x))
+
+
+define KernelPackage/pcnet32
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=AMD PCnet32 PCI support
+ DEPENDS:=@(PCI_SUPPORT||TARGET_malta) +kmod-mii
+ KCONFIG:=CONFIG_PCNET32
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/amd/pcnet32.ko
+ AUTOLOAD:=$(call AutoProbe,pcnet32)
+endef
+
+define KernelPackage/pcnet32/description
+ Kernel modules for AMD PCnet32 Ethernet adapters
+endef
+
+$(eval $(call KernelPackage,pcnet32))
+
+
+define KernelPackage/tg3
+ TITLE:=Broadcom Tigon3 Gigabit Ethernet
+ KCONFIG:=CONFIG_TIGON3
+ DEPENDS:=+!TARGET_brcm47xx:kmod-libphy +kmod-hwmon-core +kmod-ptp
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/broadcom/tg3.ko
+ AUTOLOAD:=$(call AutoLoad,19,tg3,1)
+endef
+
+define KernelPackage/tg3/description
+ Kernel modules for Broadcom Tigon3 Gigabit Ethernet adapters
+endef
+
+$(eval $(call KernelPackage,tg3))
+
+
+define KernelPackage/hfcpci
+ TITLE:=HFC PCI cards (single port) support for mISDN
+ KCONFIG:=CONFIG_MISDN_HFCPCI
+ DEPENDS:=+kmod-misdn
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ FILES:=$(LINUX_DIR)/drivers/isdn/hardware/mISDN/hfcpci.ko
+ AUTOLOAD:=$(call AutoLoad,31,hfcpci)
+endef
+
+define KernelPackage/hfcpci/description
+ Kernel modules for Cologne AG's HFC pci cards (single port)
+ using the mISDN V2 stack
+endef
+
+$(eval $(call KernelPackage,hfcpci))
+
+
+define KernelPackage/hfcmulti
+ TITLE:=HFC multiport cards (HFC-4S/8S/E1) support for mISDN
+ KCONFIG:=CONFIG_MISDN_HFCMULTI
+ DEPENDS:=+kmod-misdn
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ FILES:=$(LINUX_DIR)/drivers/isdn/hardware/mISDN/hfcmulti.ko
+ AUTOLOAD:=$(call AutoLoad,31,hfcmulti)
+endef
+
+define KernelPackage/hfcmulti/description
+ Kernel modules for Cologne AG's HFC multiport cards (HFC-4S/8S/E1)
+ using the mISDN V2 stack
+endef
+
+$(eval $(call KernelPackage,hfcmulti))
+
+
+define KernelPackage/gigaset
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Siemens Gigaset support for isdn4linux
+ DEPENDS:=@USB_SUPPORT +kmod-isdn4linux +kmod-lib-crc-ccitt +kmod-usb-core
+ URL:=http://gigaset307x.sourceforge.net/
+ KCONFIG:= \
+ CONFIG_ISDN_DRV_GIGASET \
+ CONFIG_GIGASET_BASE \
+ CONFIG_GIGASET_M101 \
+ CONFIG_GIGASET_M105 \
+ CONFIG_GIGASET_UNDOCREQ=y \
+ CONFIG_GIGASET_I4L=y
+ FILES:= \
+ $(LINUX_DIR)/drivers/isdn/gigaset/gigaset.ko \
+ $(LINUX_DIR)/drivers/isdn/gigaset/bas_gigaset.ko \
+ $(LINUX_DIR)/drivers/isdn/gigaset/ser_gigaset.ko \
+ $(LINUX_DIR)/drivers/isdn/gigaset/usb_gigaset.ko
+ AUTOLOAD:=$(call AutoProbe,gigaset bas_gigaset ser_gigaset usb_gigaset)
+endef
+
+define KernelPackage/gigaset/description
+ This driver supports the Siemens Gigaset SX205/255 family of
+ ISDN DECT bases, including the predecessors Gigaset 3070/3075
+ and 4170/4175 and their T-Com versions Sinus 45isdn and Sinus
+ 721X.
+endef
+
+$(eval $(call KernelPackage,gigaset))
+
+
+define KernelPackage/macvlan
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=MAC-VLAN support
+ KCONFIG:=CONFIG_MACVLAN
+ FILES:=$(LINUX_DIR)/drivers/net/macvlan.ko
+ AUTOLOAD:=$(call AutoProbe,macvlan)
+endef
+
+define KernelPackage/macvlan/description
+ A kernel module which allows one to create virtual interfaces that
+ map packets to or from specific MAC addresses to a particular interface
+endef
+
+$(eval $(call KernelPackage,macvlan))
+
+
+define KernelPackage/tulip
+ TITLE:=Tulip family network device support
+ DEPENDS:=@PCI_SUPPORT +kmod-mii
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ KCONFIG:= \
+ CONFIG_NET_TULIP=y \
+ CONFIG_DE2104X \
+ CONFIG_DE2104X_DSL=0 \
+ CONFIG_TULIP \
+ CONFIG_TULIP_MWI=y \
+ CONFIG_TULIP_MMIO=y \
+ CONFIG_TULIP_NAPI=y \
+ CONFIG_TULIP_NAPI_HW_MITIGATION=y \
+ CONFIG_DE4X5=n \
+ CONFIG_WINBOND_840 \
+ CONFIG_DM9102 \
+ CONFIG_ULI526X
+ FILES:= \
+ $(LINUX_DIR)/drivers/net/ethernet/dec/tulip/tulip.ko \
+ $(LINUX_DIR)/drivers/net/ethernet/dec/tulip/de2104x.ko \
+ $(LINUX_DIR)/drivers/net/ethernet/dec/tulip/dmfe.ko \
+ $(LINUX_DIR)/drivers/net/ethernet/dec/tulip/uli526x.ko \
+ $(LINUX_DIR)/drivers/net/ethernet/dec/tulip/winbond-840.ko
+ AUTOLOAD:=$(call AutoProbe,tulip)
+endef
+
+define KernelPackage/tulip/description
+ Kernel modules for the Tulip family of network cards,
+ including DECchip Tulip, DIGITAL EtherWORKS, Winbond W89c840,
+ Davicom DM910x/DM980x and ULi M526x controller support.
+endef
+
+$(eval $(call KernelPackage,tulip))
+
+
+define KernelPackage/solos-pci
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Solos ADSL2+ multiport modem
+ DEPENDS:=@PCI_SUPPORT +kmod-atm
+ KCONFIG:=CONFIG_ATM_SOLOS
+ FILES:=$(LINUX_DIR)/drivers/atm/solos-pci.ko
+ AUTOLOAD:=$(call AutoProbe,solos-pci)
+endef
+
+define KernelPackage/solos-pci/description
+ Kernel module for Traverse Technologies' Solos PCI cards
+ and Geos ADSL2+ x86 motherboard
+endef
+
+$(eval $(call KernelPackage,solos-pci))
+
+
+define KernelPackage/dummy
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Dummy network device
+ KCONFIG:=CONFIG_DUMMY
+ FILES:=$(LINUX_DIR)/drivers/net/dummy.ko
+ AUTOLOAD:=$(call AutoLoad,34,dummy)
+endef
+
+define KernelPackage/dummy/description
+ The dummy network device
+endef
+
+$(eval $(call KernelPackage,dummy))
+
+
+define KernelPackage/ifb
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Intermediate Functional Block support
+ KCONFIG:= \
+ CONFIG_IFB \
+ CONFIG_NET_CLS=y
+ FILES:=$(LINUX_DIR)/drivers/net/ifb.ko
+ AUTOLOAD:=$(call AutoLoad,34,ifb)
+endef
+
+define KernelPackage/ifb/description
+ The Intermediate Functional Block
+endef
+
+$(eval $(call KernelPackage,ifb))
+
+
+define KernelPackage/dm9000
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Davicom 9000 Ethernet support
+ DEPENDS:=@PCI_SUPPORT +kmod-mii
+ KCONFIG:=CONFIG_DM9000 \
+ CONFIG_DM9000_DEBUGLEVEL=4 \
+ CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/davicom/dm9000.ko
+ AUTOLOAD:=$(call AutoLoad,34,dm9000)
+endef
+
+define KernelPackage/dm9000/description
+ Kernel driver for Davicom 9000 Ethernet adapters.
+endef
+
+$(eval $(call KernelPackage,dm9000))
+
+
+define KernelPackage/forcedeth
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=nForce Ethernet support
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_FORCEDETH
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/nvidia/forcedeth.ko
+ AUTOLOAD:=$(call AutoProbe,forcedeth)
+endef
+
+define KernelPackage/forcedeth/description
+ Kernel driver for Nvidia Ethernet support
+endef
+
+$(eval $(call KernelPackage,forcedeth))
+
+define KernelPackage/of-mdio
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=OpenFirmware MDIO support
+ DEPENDS:=+kmod-libphy
+ KCONFIG:=CONFIG_OF_MDIO
+ FILES:=$(LINUX_DIR)/drivers/of/of_mdio.ko
+ AUTOLOAD:=$(call AutoLoad,41,of_mdio)
+endef
+
+define KernelPackage/of-mdio/description
+ Kernel driver for OpenFirmware MDIO support
+endef
+
+$(eval $(call KernelPackage,of-mdio))
+
+
+define KernelPackage/fsl-pq-mdio
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Freescale PQ MDIO bus support
+ DEPENDS:=@TARGET_mpc85xx +kmod-of-mdio
+ KCONFIG:=CONFIG_FSL_PQ_MDIO
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/freescale/fsl_pq_mdio.ko
+ AUTOLOAD:=$(call AutoLoad,42,fsl_pq_mdio)
+endef
+
+define KernelPackage/fsl-pq-mdio/description
+ Kernel driver for the Freescale PQ MDIO bus
+endef
+
+$(eval $(call KernelPackage,fsl-pq-mdio))
+
+
+define KernelPackage/gianfar
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Gianfar Ethernet support
+ DEPENDS:=@TARGET_mpc85xx +kmod-fsl-pq-mdio
+ KCONFIG:=CONFIG_GIANFAR
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/freescale/gianfar_driver.ko
+ AUTOLOAD:=$(call AutoProbe,gianfar_driver)
+endef
+
+define KernelPackage/gianfar/description
+ Kernel driver for Freescale Gianfar Ethernet support
+endef
+
+$(eval $(call KernelPackage,gianfar))
+
+
+define KernelPackage/vmxnet3
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=VMware VMXNET3 ethernet driver
+ DEPENDS:=@PCI_SUPPORT
+ KCONFIG:=CONFIG_VMXNET3
+ FILES:=$(LINUX_DIR)/drivers/net/vmxnet3/vmxnet3.ko
+ AUTOLOAD:=$(call AutoLoad,35,vmxnet3)
+endef
+
+define KernelPackage/vmxnet3/description
+ Kernel modules for VMware VMXNET3 ethernet adapters.
+endef
+
+$(eval $(call KernelPackage,vmxnet3))
+
+
+define KernelPackage/spi-ks8995
+ SUBMENU:=$(NETWORK_DEVICES_MENU)
+ TITLE:=Micrel/Kendin KS8995 Ethernet switch control
+ FILES:=$(LINUX_DIR)/drivers/net/phy/spi_ks8995.ko
+ KCONFIG:=CONFIG_MICREL_KS8995MA \
+ 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
+
+$(eval $(call KernelPackage,spi-ks8995))
diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk
new file mode 100644
index 0000000..e21895d
--- /dev/null
+++ b/package/kernel/linux/modules/netfilter.mk
@@ -0,0 +1,851 @@
+
+#
+# Copyright (C) 2006-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+NF_MENU:=Netfilter Extensions
+NF_KMOD:=1
+include $(INCLUDE_DIR)/netfilter.mk
+
+
+define KernelPackage/nf-ipt
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Iptables core
+ KCONFIG:= \
+ CONFIG_NETFILTER=y \
+ CONFIG_NETFILTER_ADVANCED=y \
+ $(KCONFIG_NF_IPT)
+ FILES:=$(foreach mod,$(NF_IPT-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_IPT-m)))
+endef
+
+$(eval $(call KernelPackage,nf-ipt))
+
+
+define KernelPackage/nf-ipt6
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Ip6tables core
+ KCONFIG:=$(KCONFIG_NF_IPT6)
+ FILES:=$(foreach mod,$(NF_IPT6-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_IPT6-m)))
+ DEPENDS:=+kmod-nf-ipt +kmod-nf-conntrack6
+endef
+
+$(eval $(call KernelPackage,nf-ipt6))
+
+
+
+define KernelPackage/ipt-core
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Iptables core
+ KCONFIG:=$(KCONFIG_IPT_CORE)
+ FILES:=$(foreach mod,$(IPT_CORE-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CORE-m)))
+ DEPENDS:=+kmod-nf-ipt
+endef
+
+define KernelPackage/ipt-core/description
+ Netfilter core kernel modules
+ Includes:
+ - comment
+ - limit
+ - LOG
+ - mac
+ - multiport
+ - REJECT
+ - TCPMSS
+endef
+
+$(eval $(call KernelPackage,ipt-core))
+
+
+define KernelPackage/nf-conntrack
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Netfilter connection tracking
+ KCONFIG:= \
+ CONFIG_NETFILTER=y \
+ CONFIG_NETFILTER_ADVANCED=y \
+ $(KCONFIG_NF_CONNTRACK)
+ FILES:=$(foreach mod,$(NF_CONNTRACK-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_CONNTRACK-m)))
+endef
+
+$(eval $(call KernelPackage,nf-conntrack))
+
+
+define KernelPackage/nf-conntrack6
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Netfilter IPv6 connection tracking
+ KCONFIG:=$(KCONFIG_NF_CONNTRACK6)
+ DEPENDS:=@IPV6 +kmod-nf-conntrack
+ FILES:=$(foreach mod,$(NF_CONNTRACK6-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_CONNTRACK6-m)))
+endef
+
+$(eval $(call KernelPackage,nf-conntrack6))
+
+
+define KernelPackage/nf-nat
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Netfilter NAT
+ KCONFIG:=$(KCONFIG_NF_NAT)
+ DEPENDS:=+kmod-nf-conntrack +kmod-nf-ipt
+ FILES:=$(foreach mod,$(NF_NAT-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NAT-m)))
+endef
+
+$(eval $(call KernelPackage,nf-nat))
+
+
+define KernelPackage/nf-nat6
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Netfilter IPV6-NAT
+ KCONFIG:=$(KCONFIG_NF_NAT6)
+ DEPENDS:=+kmod-nf-conntrack6 +kmod-nf-ipt6 +kmod-nf-nat
+ FILES:=$(foreach mod,$(NF_NAT6-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NAT6-m)))
+endef
+
+$(eval $(call KernelPackage,nf-nat6))
+
+
+define AddDepends/ipt
+ SUBMENU:=$(NF_MENU)
+ DEPENDS+= +kmod-ipt-core $(1)
+endef
+
+
+define KernelPackage/ipt-conntrack
+ TITLE:=Basic connection tracking modules
+ KCONFIG:=$(KCONFIG_IPT_CONNTRACK)
+ FILES:=$(foreach mod,$(IPT_CONNTRACK-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CONNTRACK-m)))
+ $(call AddDepends/ipt,+kmod-nf-conntrack)
+endef
+
+define KernelPackage/ipt-conntrack/description
+ Netfilter (IPv4) kernel modules for connection tracking
+ Includes:
+ - conntrack
+ - defrag
+ - iptables_raw
+ - NOTRACK
+ - state
+endef
+
+$(eval $(call KernelPackage,ipt-conntrack))
+
+
+define KernelPackage/ipt-conntrack-extra
+ TITLE:=Extra connection tracking modules
+ KCONFIG:=$(KCONFIG_IPT_CONNTRACK_EXTRA)
+ FILES:=$(foreach mod,$(IPT_CONNTRACK_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CONNTRACK_EXTRA-m)))
+ $(call AddDepends/ipt,+kmod-ipt-conntrack)
+endef
+
+define KernelPackage/ipt-conntrack-extra/description
+ Netfilter (IPv4) extra kernel modules for connection tracking
+ Includes:
+ - connbytes
+ - connmark/CONNMARK
+ - conntrack
+ - helper
+ - recent
+endef
+
+$(eval $(call KernelPackage,ipt-conntrack-extra))
+
+
+define KernelPackage/ipt-filter
+ TITLE:=Modules for packet content inspection
+ KCONFIG:=$(KCONFIG_IPT_FILTER)
+ FILES:=$(foreach mod,$(IPT_FILTER-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_FILTER-m)))
+ $(call AddDepends/ipt,+kmod-lib-textsearch +kmod-ipt-conntrack)
+endef
+
+define KernelPackage/ipt-filter/description
+ Netfilter (IPv4) kernel modules for packet content inspection
+ Includes:
+ - string
+endef
+
+$(eval $(call KernelPackage,ipt-filter))
+
+
+define KernelPackage/ipt-ipopt
+ TITLE:=Modules for matching/changing IP packet options
+ KCONFIG:=$(KCONFIG_IPT_IPOPT)
+ FILES:=$(foreach mod,$(IPT_IPOPT-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_IPOPT-m)))
+ $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-ipopt/description
+ Netfilter (IPv4) modules for matching/changing IP packet options
+ Includes:
+ - CLASSIFY
+ - dscp/DSCP
+ - ecn/ECN
+ - hl/HL
+ - length
+ - mark/MARK
+ - statistic
+ - tcpmss
+ - time
+ - ttl/TTL
+ - unclean
+endef
+
+$(eval $(call KernelPackage,ipt-ipopt))
+
+
+define KernelPackage/ipt-ipsec
+ TITLE:=Modules for matching IPSec packets
+ KCONFIG:=$(KCONFIG_IPT_IPSEC)
+ FILES:=$(foreach mod,$(IPT_IPSEC-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_IPSEC-m)))
+ $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-ipsec/description
+ Netfilter (IPv4) modules for matching IPSec packets
+ Includes:
+ - ah
+ - esp
+ - policy
+endef
+
+$(eval $(call KernelPackage,ipt-ipsec))
+
+IPSET_MODULES:= \
+ ipset/ip_set \
+ ipset/ip_set_bitmap_ip \
+ ipset/ip_set_bitmap_ipmac \
+ ipset/ip_set_bitmap_port \
+ ipset/ip_set_hash_ip \
+ ipset/ip_set_hash_ipmark \
+ ipset/ip_set_hash_ipport \
+ ipset/ip_set_hash_ipportip \
+ ipset/ip_set_hash_ipportnet \
+ ipset/ip_set_hash_mac \
+ ipset/ip_set_hash_netportnet \
+ ipset/ip_set_hash_net \
+ ipset/ip_set_hash_netnet \
+ ipset/ip_set_hash_netport \
+ ipset/ip_set_hash_netiface \
+ ipset/ip_set_list_set \
+ xt_set
+
+define KernelPackage/ipt-ipset
+ SUBMENU:=Netfilter Extensions
+ TITLE:=IPset netfilter modules
+ DEPENDS+= +kmod-ipt-core +kmod-nfnetlink
+ KCONFIG:= \
+ CONFIG_IP_SET \
+ CONFIG_IP_SET_MAX=256 \
+ CONFIG_NETFILTER_XT_SET \
+ CONFIG_IP_SET_BITMAP_IP \
+ CONFIG_IP_SET_BITMAP_IPMAC \
+ CONFIG_IP_SET_BITMAP_PORT \
+ CONFIG_IP_SET_HASH_IP \
+ CONFIG_IP_SET_HASH_IPMARK \
+ CONFIG_IP_SET_HASH_IPPORT \
+ CONFIG_IP_SET_HASH_IPPORTIP \
+ CONFIG_IP_SET_HASH_IPPORTNET \
+ CONFIG_IP_SET_HASH_MAC \
+ CONFIG_IP_SET_HASH_NET \
+ CONFIG_IP_SET_HASH_NETNET \
+ CONFIG_IP_SET_HASH_NETIFACE \
+ CONFIG_IP_SET_HASH_NETPORT \
+ CONFIG_IP_SET_HASH_NETPORTNET \
+ CONFIG_IP_SET_LIST_SET \
+ CONFIG_NET_EMATCH_IPSET=n
+ FILES:=$(foreach mod,$(IPSET_MODULES),$(LINUX_DIR)/net/netfilter/$(mod).ko)
+ AUTOLOAD:=$(call AutoLoad,49,$(notdir $(IPSET_MODULES)))
+endef
+$(eval $(call KernelPackage,ipt-ipset))
+
+
+define KernelPackage/ipt-nat
+ TITLE:=Basic NAT targets
+ KCONFIG:=$(KCONFIG_IPT_NAT)
+ FILES:=$(foreach mod,$(IPT_NAT-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NAT-m)))
+ $(call AddDepends/ipt,+kmod-nf-nat)
+endef
+
+define KernelPackage/ipt-nat/description
+ Netfilter (IPv4) kernel modules for basic NAT targets
+ Includes:
+ - MASQUERADE
+endef
+
+$(eval $(call KernelPackage,ipt-nat))
+
+
+define KernelPackage/ipt-nat6
+ TITLE:=IPv6 NAT targets
+ KCONFIG:=$(KCONFIG_IPT_NAT6)
+ FILES:=$(foreach mod,$(IPT_NAT6-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoLoad,43,$(notdir $(IPT_NAT6-m)))
+ $(call AddDepends/ipt,+kmod-nf-nat6)
+ $(call AddDepends/ipt,+kmod-ipt-conntrack)
+ $(call AddDepends/ipt,+kmod-ipt-nat)
+ $(call AddDepends/ipt,+kmod-ip6tables)
+endef
+
+define KernelPackage/ipt-nat6/description
+ Netfilter (IPv6) kernel modules for NAT targets
+endef
+
+$(eval $(call KernelPackage,ipt-nat6))
+
+
+define KernelPackage/ipt-nat-extra
+ TITLE:=Extra NAT targets
+ KCONFIG:=$(KCONFIG_IPT_NAT_EXTRA)
+ FILES:=$(foreach mod,$(IPT_NAT_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NAT_EXTRA-m)))
+ $(call AddDepends/ipt,+kmod-ipt-nat)
+endef
+
+define KernelPackage/ipt-nat-extra/description
+ Netfilter (IPv4) kernel modules for extra NAT targets
+ Includes:
+ - NETMAP
+ - REDIRECT
+endef
+
+$(eval $(call KernelPackage,ipt-nat-extra))
+
+
+define KernelPackage/nf-nathelper
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Basic Conntrack and NAT helpers
+ KCONFIG:=$(KCONFIG_NF_NATHELPER)
+ FILES:=$(foreach mod,$(NF_NATHELPER-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NATHELPER-m)))
+ DEPENDS:=+kmod-nf-nat
+endef
+
+define KernelPackage/nf-nathelper/description
+ Default Netfilter (IPv4) Conntrack and NAT helpers
+ Includes:
+ - ftp
+ - irc
+ - tftp
+endef
+
+$(eval $(call KernelPackage,nf-nathelper))
+
+
+define KernelPackage/nf-nathelper-extra
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Extra Conntrack and NAT helpers
+ KCONFIG:=$(KCONFIG_NF_NATHELPER_EXTRA)
+ FILES:=$(foreach mod,$(NF_NATHELPER_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_NATHELPER_EXTRA-m)))
+ DEPENDS:=+kmod-nf-nat +kmod-lib-textsearch
+endef
+
+define KernelPackage/nf-nathelper-extra/description
+ Extra Netfilter (IPv4) Conntrack and NAT helpers
+ Includes:
+ - amanda
+ - h323
+ - mms
+ - pptp
+ - proto_gre
+ - sip
+ - snmp_basic
+ - broadcast
+endef
+
+$(eval $(call KernelPackage,nf-nathelper-extra))
+
+
+define KernelPackage/ipt-ulog
+ TITLE:=Module for user-space packet logging
+ KCONFIG:=$(KCONFIG_IPT_ULOG)
+ FILES:=$(foreach mod,$(IPT_ULOG-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_ULOG-m)))
+ $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-ulog/description
+ Netfilter (IPv4) module for user-space packet logging
+ Includes:
+ - ULOG
+endef
+
+$(eval $(call KernelPackage,ipt-ulog))
+
+
+define KernelPackage/ipt-nflog
+ TITLE:=Module for user-space packet logging
+ KCONFIG:=$(KCONFIG_IPT_NFLOG)
+ FILES:=$(foreach mod,$(IPT_NFLOG-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NFLOG-m)))
+ $(call AddDepends/ipt,+kmod-nfnetlink-log)
+endef
+
+define KernelPackage/ipt-nflog/description
+ Netfilter module for user-space packet logging
+ Includes:
+ - NFLOG
+endef
+
+$(eval $(call KernelPackage,ipt-nflog))
+
+
+define KernelPackage/ipt-nfqueue
+ TITLE:=Module for user-space packet queuing
+ KCONFIG:=$(KCONFIG_IPT_NFQUEUE)
+ FILES:=$(foreach mod,$(IPT_NFQUEUE-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_NFQUEUE-m)))
+ $(call AddDepends/ipt,+kmod-nfnetlink-queue)
+endef
+
+define KernelPackage/ipt-nfqueue/description
+ Netfilter module for user-space packet queuing
+ Includes:
+ - NFQUEUE
+endef
+
+$(eval $(call KernelPackage,ipt-nfqueue))
+
+
+define KernelPackage/ipt-debug
+ TITLE:=Module for debugging/development
+ KCONFIG:=$(KCONFIG_IPT_DEBUG)
+ DEFAULT:=n
+ FILES:=$(foreach mod,$(IPT_DEBUG-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_DEBUG-m)))
+ $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-debug/description
+ Netfilter modules for debugging/development of the firewall
+ Includes:
+ - TRACE
+endef
+
+$(eval $(call KernelPackage,ipt-debug))
+
+
+define KernelPackage/ipt-led
+ TITLE:=Module to trigger a LED with a Netfilter rule
+ KCONFIG:=$(KCONFIG_IPT_LED)
+ FILES:=$(foreach mod,$(IPT_LED-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_LED-m)))
+ $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-led/description
+ Netfilter target to trigger a LED when a network packet is matched.
+endef
+
+$(eval $(call KernelPackage,ipt-led))
+
+define KernelPackage/ipt-tproxy
+ TITLE:=Transparent proxying support
+ DEPENDS+=+kmod-ipt-conntrack +IPV6:kmod-ip6tables
+ KCONFIG:= \
+ CONFIG_NETFILTER_TPROXY \
+ CONFIG_NETFILTER_XT_MATCH_SOCKET \
+ CONFIG_NETFILTER_XT_TARGET_TPROXY
+ FILES:= \
+ $(foreach mod,$(IPT_TPROXY-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir nf_tproxy_core $(IPT_TPROXY-m)))
+ $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-tproxy/description
+ Kernel modules for Transparent Proxying
+endef
+
+$(eval $(call KernelPackage,ipt-tproxy))
+
+define KernelPackage/ipt-tee
+ TITLE:=TEE support
+ DEPENDS:=+kmod-ipt-conntrack
+ KCONFIG:= \
+ CONFIG_NETFILTER_XT_TARGET_TEE
+ FILES:= \
+ $(LINUX_DIR)/net/netfilter/xt_TEE.ko \
+ $(foreach mod,$(IPT_TEE-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir nf_tee $(IPT_TEE-m)))
+ $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-tee/description
+ Kernel modules for TEE
+endef
+
+$(eval $(call KernelPackage,ipt-tee))
+
+
+define KernelPackage/ipt-u32
+ TITLE:=U32 support
+ KCONFIG:= \
+ CONFIG_NETFILTER_XT_MATCH_U32
+ FILES:= \
+ $(LINUX_DIR)/net/netfilter/xt_u32.ko \
+ $(foreach mod,$(IPT_U32-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir nf_tee $(IPT_U32-m)))
+ $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-u32/description
+ Kernel modules for U32
+endef
+
+$(eval $(call KernelPackage,ipt-u32))
+
+
+define KernelPackage/ipt-iprange
+ TITLE:=Module for matching ip ranges
+ KCONFIG:=$(KCONFIG_IPT_IPRANGE)
+ FILES:=$(foreach mod,$(IPT_IPRANGE-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_IPRANGE-m)))
+ $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-iprange/description
+ Netfilter (IPv4) module for matching ip ranges
+ Includes:
+ - iprange
+endef
+
+$(eval $(call KernelPackage,ipt-iprange))
+
+define KernelPackage/ipt-cluster
+ TITLE:=Module for matching cluster
+ KCONFIG:=$(KCONFIG_IPT_CLUSTER)
+ FILES:=$(foreach mod,$(IPT_CLUSTER-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CLUSTER-m)))
+ $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-cluster/description
+ Netfilter (IPv4/IPv6) module for matching cluster
+ This option allows you to build work-load-sharing clusters of
+ network servers/stateful firewalls without having a dedicated
+ load-balancing router/server/switch. Basically, this match returns
+ true when the packet must be handled by this cluster node. Thus,
+ all nodes see all packets and this match decides which node handles
+ what packets. The work-load sharing algorithm is based on source
+ address hashing.
+
+ This module is usable for ipv4 and ipv6.
+
+ To use it also enable iptables-mod-cluster
+
+ see `iptables -m cluster --help` for more information.
+endef
+
+$(eval $(call KernelPackage,ipt-cluster))
+
+define KernelPackage/ipt-clusterip
+ TITLE:=Module for CLUSTERIP
+ KCONFIG:=$(KCONFIG_IPT_CLUSTERIP)
+ FILES:=$(foreach mod,$(IPT_CLUSTERIP-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CLUSTERIP-m)))
+ $(call AddDepends/ipt,+kmod-nf-conntrack)
+endef
+
+define KernelPackage/ipt-clusterip/description
+ Netfilter (IPv4-only) module for CLUSTERIP
+ The CLUSTERIP target allows you to build load-balancing clusters of
+ network servers without having a dedicated load-balancing
+ router/server/switch.
+
+ To use it also enable iptables-mod-clusterip
+
+ see `iptables -j CLUSTERIP --help` for more information.
+endef
+
+$(eval $(call KernelPackage,ipt-clusterip))
+
+
+define KernelPackage/ipt-extra
+ TITLE:=Extra modules
+ KCONFIG:=$(KCONFIG_IPT_EXTRA)
+ FILES:=$(foreach mod,$(IPT_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_EXTRA-m)))
+ $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-extra/description
+ Other Netfilter (IPv4) kernel modules
+ Includes:
+ - addrtype
+ - owner
+ - physdev (if bridge support was enabled in kernel)
+ - pkttype
+ - quota
+endef
+
+$(eval $(call KernelPackage,ipt-extra))
+
+
+define KernelPackage/ip6tables
+ SUBMENU:=$(NF_MENU)
+ TITLE:=IPv6 modules
+ DEPENDS:=+kmod-nf-ipt6 +kmod-ipt-core +kmod-ipt-conntrack
+ KCONFIG:=$(KCONFIG_IPT_IPV6)
+ FILES:=$(foreach mod,$(IPT_IPV6-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoLoad,42,$(notdir $(IPT_IPV6-m)))
+endef
+
+define KernelPackage/ip6tables/description
+ Netfilter IPv6 firewalling support
+endef
+
+$(eval $(call KernelPackage,ip6tables))
+
+define KernelPackage/ip6tables-extra
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Extra IPv6 modules
+ DEPENDS:=+kmod-ip6tables
+ KCONFIG:=$(KCONFIG_IPT_IPV6_EXTRA)
+ FILES:=$(foreach mod,$(IPT_IPV6_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoLoad,43,$(notdir $(IPT_IPV6_EXTRA-m)))
+endef
+
+define KernelPackage/ip6tables-extra/description
+ Netfilter IPv6 extra header matching modules
+endef
+
+$(eval $(call KernelPackage,ip6tables-extra))
+
+ARP_MODULES = arp_tables arpt_mangle arptable_filter
+define KernelPackage/arptables
+ SUBMENU:=$(NF_MENU)
+ TITLE:=ARP firewalling modules
+ DEPENDS:=+kmod-ipt-core
+ FILES:=$(LINUX_DIR)/net/ipv4/netfilter/arp*.ko
+ KCONFIG:=CONFIG_IP_NF_ARPTABLES \
+ CONFIG_IP_NF_ARPFILTER \
+ CONFIG_IP_NF_ARP_MANGLE
+ AUTOLOAD:=$(call AutoProbe,$(ARP_MODULES))
+endef
+
+define KernelPackage/arptables/description
+ Kernel modules for ARP firewalling
+endef
+
+$(eval $(call KernelPackage,arptables))
+
+
+define KernelPackage/ebtables
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Bridge firewalling modules
+ DEPENDS:=+kmod-ipt-core +kmod-bridge
+ FILES:=$(foreach mod,$(EBTABLES-m),$(LINUX_DIR)/net/$(mod).ko)
+ KCONFIG:=CONFIG_BRIDGE_NETFILTER=y \
+ $(KCONFIG_EBTABLES)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES-m)))
+endef
+
+define KernelPackage/ebtables/description
+ ebtables is a general, extensible frame/packet identification
+ framework. It provides you to do Ethernet
+ filtering/NAT/brouting on the Ethernet bridge.
+endef
+
+$(eval $(call KernelPackage,ebtables))
+
+
+define AddDepends/ebtables
+ SUBMENU:=$(NF_MENU)
+ DEPENDS+=kmod-ebtables $(1)
+endef
+
+
+define KernelPackage/ebtables-ipv4
+ TITLE:=ebtables: IPv4 support
+ FILES:=$(foreach mod,$(EBTABLES_IP4-m),$(LINUX_DIR)/net/$(mod).ko)
+ KCONFIG:=$(KCONFIG_EBTABLES_IP4)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES_IP4-m)))
+ $(call AddDepends/ebtables)
+endef
+
+define KernelPackage/ebtables-ipv4/description
+ This option adds the IPv4 support to ebtables, which allows basic
+ IPv4 header field filtering, ARP filtering as well as SNAT, DNAT targets.
+endef
+
+$(eval $(call KernelPackage,ebtables-ipv4))
+
+
+define KernelPackage/ebtables-ipv6
+ TITLE:=ebtables: IPv6 support
+ FILES:=$(foreach mod,$(EBTABLES_IP6-m),$(LINUX_DIR)/net/$(mod).ko)
+ KCONFIG:=$(KCONFIG_EBTABLES_IP6)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES_IP6-m)))
+ $(call AddDepends/ebtables)
+endef
+
+define KernelPackage/ebtables-ipv6/description
+ This option adds the IPv6 support to ebtables, which allows basic
+ IPv6 header field filtering and target support.
+endef
+
+$(eval $(call KernelPackage,ebtables-ipv6))
+
+
+define KernelPackage/ebtables-watchers
+ TITLE:=ebtables: watchers support
+ FILES:=$(foreach mod,$(EBTABLES_WATCHERS-m),$(LINUX_DIR)/net/$(mod).ko)
+ KCONFIG:=$(KCONFIG_EBTABLES_WATCHERS)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES_WATCHERS-m)))
+ $(call AddDepends/ebtables)
+endef
+
+define KernelPackage/ebtables-watchers/description
+ This option adds the log watchers, that you can use in any rule
+ in any ebtables table.
+endef
+
+$(eval $(call KernelPackage,ebtables-watchers))
+
+
+define KernelPackage/nfnetlink
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Netlink-based userspace interface
+ FILES:=$(foreach mod,$(NFNETLINK-m),$(LINUX_DIR)/net/$(mod).ko)
+ KCONFIG:=$(KCONFIG_NFNETLINK)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NFNETLINK-m)))
+endef
+
+define KernelPackage/nfnetlink/description
+ Kernel modules support for a netlink-based userspace interface
+endef
+
+$(eval $(call KernelPackage,nfnetlink))
+
+
+define AddDepends/nfnetlink
+ SUBMENU:=$(NF_MENU)
+ DEPENDS+=+kmod-nfnetlink $(1)
+endef
+
+
+define KernelPackage/nfnetlink-log
+ TITLE:=Netfilter LOG over NFNETLINK interface
+ FILES:=$(foreach mod,$(NFNETLINK_LOG-m),$(LINUX_DIR)/net/$(mod).ko)
+ KCONFIG:=$(KCONFIG_NFNETLINK_LOG)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NFNETLINK_LOG-m)))
+ $(call AddDepends/nfnetlink)
+endef
+
+define KernelPackage/nfnetlink-log/description
+ Kernel modules support for logging packets via NFNETLINK
+ Includes:
+ - NFLOG
+endef
+
+$(eval $(call KernelPackage,nfnetlink-log))
+
+
+define KernelPackage/nfnetlink-queue
+ TITLE:=Netfilter QUEUE over NFNETLINK interface
+ FILES:=$(foreach mod,$(NFNETLINK_QUEUE-m),$(LINUX_DIR)/net/$(mod).ko)
+ KCONFIG:=$(KCONFIG_NFNETLINK_QUEUE)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NFNETLINK_QUEUE-m)))
+ $(call AddDepends/nfnetlink)
+endef
+
+define KernelPackage/nfnetlink-queue/description
+ Kernel modules support for queueing packets via NFNETLINK
+ Includes:
+ - NFQUEUE
+endef
+
+$(eval $(call KernelPackage,nfnetlink-queue))
+
+
+define KernelPackage/nf-conntrack-netlink
+ TITLE:=Connection tracking netlink interface
+ FILES:=$(LINUX_DIR)/net/netfilter/nf_conntrack_netlink.ko
+ KCONFIG:=CONFIG_NF_CT_NETLINK CONFIG_NF_CONNTRACK_EVENTS=y
+ AUTOLOAD:=$(call AutoProbe,nf_conntrack_netlink)
+ $(call AddDepends/nfnetlink,+kmod-ipt-conntrack)
+endef
+
+define KernelPackage/nf-conntrack-netlink/description
+ Kernel modules support for a netlink-based connection tracking
+ userspace interface
+endef
+
+$(eval $(call KernelPackage,nf-conntrack-netlink))
+
+define KernelPackage/ipt-hashlimit
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Netfilter hashlimit match
+ DEPENDS:=+kmod-ipt-core
+ KCONFIG:=$(KCONFIG_IPT_HASHLIMIT)
+ FILES:=$(LINUX_DIR)/net/netfilter/xt_hashlimit.ko
+ AUTOLOAD:=$(call AutoProbe,xt_hashlimit)
+ $(call KernelPackage/ipt)
+endef
+
+define KernelPackage/ipt-hashlimit/description
+ Kernel modules support for the hashlimit bucket match module
+endef
+
+$(eval $(call KernelPackage,ipt-hashlimit))
+
+
+define KernelPackage/nft-core
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Netfilter nf_tables support
+ DEPENDS:=+kmod-nfnetlink +kmod-nf-conntrack6
+ FILES:=$(foreach mod,$(NFT_CORE-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_CORE-m)))
+ KCONFIG:= \
+ CONFIG_NETFILTER=y \
+ CONFIG_NETFILTER_ADVANCED=y \
+ CONFIG_NFT_COMPAT=n \
+ CONFIG_NFT_QUEUE=n \
+ CONFIG_NF_TABLES_ARP=n \
+ CONFIG_NF_TABLES_BRIDGE=n \
+ $(KCONFIG_NFT_CORE)
+endef
+
+define KernelPackage/nft-core/description
+ Kernel module support for nftables
+endef
+
+$(eval $(call KernelPackage,nft-core))
+
+
+define KernelPackage/nft-nat
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Netfilter nf_tables NAT support
+ DEPENDS:=+kmod-nft-core +kmod-nf-nat
+ FILES:=$(foreach mod,$(NFT_NAT-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_NAT-m)))
+ KCONFIG:=$(KCONFIG_NFT_NAT)
+endef
+
+$(eval $(call KernelPackage,nft-nat))
+
+
+define KernelPackage/nft-nat6
+ SUBMENU:=$(NF_MENU)
+ TITLE:=Netfilter nf_tables IPv6-NAT support
+ DEPENDS:=+kmod-nft-core +kmod-nf-nat6
+ FILES:=$(foreach mod,$(NFT_NAT6-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_NAT6-m)))
+ KCONFIG:=$(KCONFIG_NFT_NAT6)
+endef
+
+$(eval $(call KernelPackage,nft-nat6))
+
diff --git a/package/kernel/linux/modules/netsupport.mk b/package/kernel/linux/modules/netsupport.mk
new file mode 100644
index 0000000..b81d9b4
--- /dev/null
+++ b/package/kernel/linux/modules/netsupport.mk
@@ -0,0 +1,1007 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+NETWORK_SUPPORT_MENU:=Network Support
+
+define KernelPackage/atm
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=ATM support
+ KCONFIG:= \
+ CONFIG_ATM \
+ CONFIG_ATM_BR2684
+ FILES:= \
+ $(LINUX_DIR)/net/atm/atm.ko \
+ $(LINUX_DIR)/net/atm/br2684.ko
+ AUTOLOAD:=$(call AutoLoad,30,atm br2684)
+endef
+
+define KernelPackage/atm/description
+ Kernel modules for ATM support
+endef
+
+$(eval $(call KernelPackage,atm))
+
+
+define KernelPackage/atmtcp
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=ATM over TCP
+ DEPENDS:=kmod-atm
+ KCONFIG:=CONFIG_ATM_TCP CONFIG_ATM_DRIVERS=y
+ FILES:=$(LINUX_DIR)/drivers/atm/atmtcp.ko
+ AUTOLOAD:=$(call AutoLoad,40,atmtcp)
+endef
+
+define KernelPackage/atmtcp/description
+ Kernel module for ATM over TCP support
+endef
+
+$(eval $(call KernelPackage,atmtcp))
+
+
+define KernelPackage/appletalk
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Appletalk protocol support
+ DEPENDS:=+PACKAGE_kmod-llc:kmod-llc
+ KCONFIG:= \
+ CONFIG_ATALK \
+ CONFIG_DEV_APPLETALK \
+ CONFIG_IPDDP \
+ CONFIG_IPDDP_ENCAP=y \
+ CONFIG_IPDDP_DECAP=y
+ FILES:= \
+ $(LINUX_DIR)/net/appletalk/appletalk.ko \
+ $(LINUX_DIR)/drivers/net/appletalk/ipddp.ko
+ AUTOLOAD:=$(call AutoLoad,40,appletalk ipddp)
+endef
+
+define KernelPackage/appletalk/description
+ Kernel module for AppleTalk protocol.
+endef
+
+$(eval $(call KernelPackage,appletalk))
+
+
+define KernelPackage/bonding
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Ethernet bonding driver
+ KCONFIG:=CONFIG_BONDING
+ FILES:=$(LINUX_DIR)/drivers/net/bonding/bonding.ko
+ AUTOLOAD:=$(call AutoLoad,40,bonding)
+endef
+
+define KernelPackage/bonding/description
+ Kernel module for NIC bonding.
+endef
+
+$(eval $(call KernelPackage,bonding))
+
+
+define KernelPackage/bridge
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Ethernet bridging support
+ DEPENDS:=+kmod-stp
+ KCONFIG:= \
+ CONFIG_BRIDGE \
+ CONFIG_BRIDGE_IGMP_SNOOPING=y
+ FILES:=$(LINUX_DIR)/net/bridge/bridge.ko
+ AUTOLOAD:=$(call AutoLoad,11,bridge)
+endef
+
+define KernelPackage/bridge/description
+ Kernel module for Ethernet bridging.
+endef
+
+$(eval $(call KernelPackage,bridge))
+
+define KernelPackage/llc
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=ANSI/IEEE 802.2 LLC support
+ KCONFIG:=CONFIG_LLC
+ FILES:= \
+ $(LINUX_DIR)/net/llc/llc.ko \
+ $(LINUX_DIR)/net/802/p8022.ko \
+ $(LINUX_DIR)/net/802/psnap.ko
+ AUTOLOAD:=$(call AutoLoad,09,llc p8022 psnap)
+endef
+
+define KernelPackage/llc/description
+ Kernel module for ANSI/IEEE 802.2 LLC support.
+endef
+
+$(eval $(call KernelPackage,llc))
+
+define KernelPackage/stp
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Ethernet Spanning Tree Protocol support
+ DEPENDS:=+kmod-llc
+ KCONFIG:=CONFIG_STP
+ FILES:=$(LINUX_DIR)/net/802/stp.ko
+ AUTOLOAD:=$(call AutoLoad,10,stp)
+endef
+
+define KernelPackage/stp/description
+ Kernel module for Ethernet Spanning Tree Protocol support.
+endef
+
+$(eval $(call KernelPackage,stp))
+
+define KernelPackage/8021q
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=802.1Q VLAN support
+ KCONFIG:=CONFIG_VLAN_8021Q \
+ CONFIG_VLAN_8021Q_GVRP=n
+ FILES:=$(LINUX_DIR)/net/8021q/8021q.ko
+ AUTOLOAD:=$(call AutoLoad,12,8021q)
+endef
+
+define KernelPackage/8021q/description
+ Kernel module for 802.1Q VLAN support
+endef
+
+$(eval $(call KernelPackage,8021q))
+
+
+define KernelPackage/udptunnel4
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IPv4 UDP tunneling support
+ KCONFIG:=CONFIG_NET_UDP_TUNNEL
+ FILES:=$(LINUX_DIR)/net/ipv4/udp_tunnel.ko
+ AUTOLOAD:=$(call AutoLoad,32,udp_tunnel)
+endef
+
+
+$(eval $(call KernelPackage,udptunnel4))
+
+define KernelPackage/udptunnel6
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IPv6 UDP tunneling support
+ KCONFIG:=CONFIG_NET_UDP_TUNNEL
+ FILES:=$(LINUX_DIR)/net/ipv6/ip6_udp_tunnel.ko
+ AUTOLOAD:=$(call AutoLoad,32,ip6_udp_tunnel)
+endef
+
+$(eval $(call KernelPackage,udptunnel6))
+
+
+define KernelPackage/vxlan
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Native VXLAN Kernel support
+ DEPENDS:= \
+ +kmod-iptunnel \
+ +kmod-udptunnel4 \
+ +IPV6:kmod-udptunnel6
+ KCONFIG:=CONFIG_VXLAN
+ FILES:=$(LINUX_DIR)/drivers/net/vxlan.ko
+ AUTOLOAD:=$(call AutoLoad,13,vxlan)
+endef
+
+define KernelPackage/vxlan/description
+ Kernel module for supporting VXLAN in the Kernel.
+ Requires Kernel 3.12 or newer.
+endef
+
+$(eval $(call KernelPackage,vxlan))
+
+define KernelPackage/capi
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=CAPI (ISDN) Support
+ KCONFIG:= \
+ CONFIG_ISDN_CAPI \
+ CONFIG_ISDN_CAPI_CAPI20 \
+ CONFIG_ISDN_CAPIFS \
+ CONFIG_ISDN_CAPI_CAPIFS
+ FILES:= \
+ $(LINUX_DIR)/drivers/isdn/capi/kernelcapi.ko \
+ $(LINUX_DIR)/drivers/isdn/capi/capi.ko
+ AUTOLOAD:=$(call AutoLoad,30,kernelcapi capi)
+endef
+
+define KernelPackage/capi/description
+ Kernel module for basic CAPI (ISDN) support
+endef
+
+$(eval $(call KernelPackage,capi))
+
+define KernelPackage/misdn
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=mISDN (ISDN) Support
+ KCONFIG:= \
+ CONFIG_ISDN=y \
+ CONFIG_MISDN \
+ CONFIG_MISDN_DSP \
+ CONFIG_MISDN_L1OIP
+ FILES:= \
+ $(LINUX_DIR)/drivers/isdn/mISDN/mISDN_core.ko \
+ $(LINUX_DIR)/drivers/isdn/mISDN/mISDN_dsp.ko \
+ $(LINUX_DIR)/drivers/isdn/mISDN/l1oip.ko
+ AUTOLOAD:=$(call AutoLoad,30,mISDN_core mISDN_dsp l1oip)
+endef
+
+define KernelPackage/misdn/description
+ Modular ISDN driver support
+endef
+
+$(eval $(call KernelPackage,misdn))
+
+
+define KernelPackage/isdn4linux
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Old ISDN4Linux (deprecated)
+ DEPENDS:=+kmod-ppp
+ KCONFIG:= \
+ CONFIG_ISDN=y \
+ CONFIG_ISDN_I4L \
+ CONFIG_ISDN_PPP=y \
+ CONFIG_ISDN_PPP_VJ=y \
+ CONFIG_ISDN_MPP=y \
+ CONFIG_IPPP_FILTER=y \
+ CONFIG_ISDN_PPP_BSDCOMP \
+ CONFIG_ISDN_CAPI_MIDDLEWARE=y \
+ CONFIG_ISDN_CAPI_CAPIFS_BOOL=y \
+ CONFIG_ISDN_AUDIO=y \
+ CONFIG_ISDN_TTY_FAX=y \
+ CONFIG_ISDN_X25=y \
+ CONFIG_ISDN_DIVERSION
+ FILES:= \
+ $(LINUX_DIR)/drivers/isdn/divert/dss1_divert.ko \
+ $(LINUX_DIR)/drivers/isdn/i4l/isdn.ko \
+ $(LINUX_DIR)/drivers/isdn/i4l/isdn_bsdcomp.ko
+ AUTOLOAD:=$(call AutoLoad,40,isdn isdn_bsdcomp dss1_divert)
+endef
+
+define KernelPackage/isdn4linux/description
+ This driver allows you to use an ISDN adapter for networking
+endef
+
+$(eval $(call KernelPackage,isdn4linux))
+
+
+define KernelPackage/ipip
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IP-in-IP encapsulation
+ DEPENDS:=+kmod-iptunnel +kmod-iptunnel4
+ KCONFIG:=CONFIG_NET_IPIP
+ FILES:=$(LINUX_DIR)/net/ipv4/ipip.ko
+ AUTOLOAD:=$(call AutoLoad,32,ipip)
+endef
+
+define KernelPackage/ipip/description
+ Kernel modules for IP-in-IP encapsulation
+endef
+
+$(eval $(call KernelPackage,ipip))
+
+
+IPSEC-m:= \
+ xfrm/xfrm_algo \
+ xfrm/xfrm_ipcomp \
+ xfrm/xfrm_user \
+ key/af_key \
+
+define KernelPackage/ipsec
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IPsec related modules (IPv4 and IPv6)
+ DEPENDS:=+kmod-crypto-authenc +kmod-crypto-iv +kmod-crypto-des +kmod-crypto-hmac +kmod-crypto-md5 +kmod-crypto-sha1 +kmod-crypto-deflate +kmod-crypto-cbc
+ KCONFIG:= \
+ CONFIG_NET_KEY \
+ CONFIG_XFRM_USER \
+ CONFIG_INET_IPCOMP \
+ CONFIG_XFRM_IPCOMP
+ FILES:=$(foreach mod,$(IPSEC-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoLoad,30,$(notdir $(IPSEC-m)))
+endef
+
+define KernelPackage/ipsec/description
+ Kernel modules for IPsec support in both IPv4 and IPv6.
+ Includes:
+ - af_key
+ - xfrm_ipcomp
+ - xfrm_user
+endef
+
+$(eval $(call KernelPackage,ipsec))
+
+
+IPSEC4-m:= \
+ ipv4/ah4 \
+ ipv4/esp4 \
+ ipv4/xfrm4_mode_beet \
+ ipv4/xfrm4_mode_transport \
+ ipv4/xfrm4_mode_tunnel \
+ ipv4/xfrm4_tunnel \
+ ipv4/ipcomp \
+
+define KernelPackage/ipsec4
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IPsec related modules (IPv4)
+ DEPENDS:=kmod-ipsec +kmod-iptunnel4
+ KCONFIG:= \
+ CONFIG_INET_AH \
+ CONFIG_INET_ESP \
+ CONFIG_INET_IPCOMP \
+ CONFIG_INET_XFRM_MODE_BEET \
+ CONFIG_INET_XFRM_MODE_TRANSPORT \
+ CONFIG_INET_XFRM_MODE_TUNNEL \
+ CONFIG_INET_XFRM_TUNNEL
+ FILES:=$(foreach mod,$(IPSEC4-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoLoad,32,$(notdir $(IPSEC4-m)))
+endef
+
+define KernelPackage/ipsec4/description
+ Kernel modules for IPsec support in IPv4.
+ Includes:
+ - ah4
+ - esp4
+ - ipcomp4
+ - xfrm4_mode_beet
+ - xfrm4_mode_transport
+ - xfrm4_mode_tunnel
+ - xfrm4_tunnel
+endef
+
+$(eval $(call KernelPackage,ipsec4))
+
+
+IPSEC6-m:= \
+ ipv6/ah6 \
+ ipv6/esp6 \
+ ipv6/xfrm6_mode_beet \
+ ipv6/xfrm6_mode_transport \
+ ipv6/xfrm6_mode_tunnel \
+ ipv6/xfrm6_tunnel \
+ ipv6/ipcomp6 \
+
+define KernelPackage/ipsec6
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IPsec related modules (IPv6)
+ DEPENDS:=kmod-ipsec +kmod-iptunnel6
+ KCONFIG:= \
+ CONFIG_INET6_AH \
+ CONFIG_INET6_ESP \
+ CONFIG_INET6_IPCOMP \
+ CONFIG_INET6_XFRM_MODE_BEET \
+ CONFIG_INET6_XFRM_MODE_TRANSPORT \
+ CONFIG_INET6_XFRM_MODE_TUNNEL \
+ CONFIG_INET6_XFRM_TUNNEL
+ FILES:=$(foreach mod,$(IPSEC6-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoLoad,32,$(notdir $(IPSEC6-m)))
+endef
+
+define KernelPackage/ipsec6/description
+ Kernel modules for IPsec support in IPv6.
+ Includes:
+ - ah6
+ - esp6
+ - ipcomp6
+ - xfrm6_mode_beet
+ - xfrm6_mode_transport
+ - xfrm6_mode_tunnel
+ - xfrm6_tunnel
+endef
+
+$(eval $(call KernelPackage,ipsec6))
+
+
+define KernelPackage/iptunnel
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IP tunnel support
+ HIDDEN:=1
+ KCONFIG:= \
+ CONFIG_NET_IP_TUNNEL
+ FILES:=$(LINUX_DIR)/net/ipv4/ip_tunnel.ko
+ AUTOLOAD:=$(call AutoLoad,31,ip_tunnel)
+endef
+
+define KernelPackage/iptunnel/description
+ Kernel module for generic IP tunnel support
+endef
+
+$(eval $(call KernelPackage,iptunnel))
+
+
+define KernelPackage/ipvti
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IP VTI (Virtual Tunnel Interface)
+ DEPENDS:=+kmod-iptunnel +kmod-iptunnel4 +kmod-ipsec4
+ KCONFIG:=CONFIG_NET_IPVTI
+ FILES:=$(LINUX_DIR)/net/ipv4/ip_vti.ko
+ AUTOLOAD:=$(call AutoLoad,33,ip_vti)
+endef
+
+define KernelPackage/ipvti/description
+ Kernel modules for IP VTI (Virtual Tunnel Interface)
+endef
+
+$(eval $(call KernelPackage,ipvti))
+
+
+define KernelPackage/iptunnel4
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IPv4 tunneling
+ HIDDEN:=1
+ KCONFIG:= \
+ CONFIG_INET_TUNNEL
+ FILES:=$(LINUX_DIR)/net/ipv4/tunnel4.ko
+ AUTOLOAD:=$(call AutoLoad,31,tunnel4)
+endef
+
+define KernelPackage/iptunnel4/description
+ Kernel modules for IPv4 tunneling
+endef
+
+$(eval $(call KernelPackage,iptunnel4))
+
+
+define KernelPackage/iptunnel6
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IPv6 tunneling
+ DEPENDS:=@IPV6
+ KCONFIG:= \
+ CONFIG_INET6_TUNNEL
+ FILES:=$(LINUX_DIR)/net/ipv6/tunnel6.ko
+ AUTOLOAD:=$(call AutoLoad,31,tunnel6)
+endef
+
+define KernelPackage/iptunnel6/description
+ Kernel modules for IPv6 tunneling
+endef
+
+$(eval $(call KernelPackage,iptunnel6))
+
+
+define KernelPackage/ipv6
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IPv6 support
+ DEPENDS:=@IPV6
+ HIDDEN:=1
+ DEFAULT:=y
+ KCONFIG:= \
+ CONFIG_IPV6=y \
+ CONFIG_IPV6_PRIVACY=y \
+ CONFIG_IPV6_MULTIPLE_TABLES=y \
+ CONFIG_IPV6_MROUTE=y \
+ CONFIG_IPV6_PIMSM_V2=n \
+ CONFIG_IPV6_SUBTREES=y
+endef
+
+define KernelPackage/ipv6/description
+ Kernel modules for IPv6 support
+endef
+
+$(eval $(call KernelPackage,ipv6))
+
+
+define KernelPackage/sit
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ DEPENDS:=@IPV6 +kmod-iptunnel +kmod-iptunnel4
+ TITLE:=IPv6-in-IPv4 tunnel
+ KCONFIG:=CONFIG_IPV6_SIT \
+ CONFIG_IPV6_SIT_6RD=y
+ FILES:=$(LINUX_DIR)/net/ipv6/sit.ko
+ AUTOLOAD:=$(call AutoLoad,32,sit)
+endef
+
+define KernelPackage/sit/description
+ Kernel modules for IPv6-in-IPv4 tunnelling
+endef
+
+$(eval $(call KernelPackage,sit))
+
+
+define KernelPackage/ip6-tunnel
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IP-in-IPv6 tunnelling
+ DEPENDS:=@IPV6 +kmod-iptunnel6
+ KCONFIG:= CONFIG_IPV6_TUNNEL
+ FILES:=$(LINUX_DIR)/net/ipv6/ip6_tunnel.ko
+ AUTOLOAD:=$(call AutoLoad,32,ip6_tunnel)
+endef
+
+define KernelPackage/ip6-tunnel/description
+ Kernel modules for IPv6-in-IPv6 and IPv4-in-IPv6 tunnelling
+endef
+
+$(eval $(call KernelPackage,ip6-tunnel))
+
+
+define KernelPackage/gre
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=GRE support
+ DEPENDS:=+kmod-iptunnel
+ KCONFIG:=CONFIG_NET_IPGRE CONFIG_NET_IPGRE_DEMUX
+ FILES:=$(LINUX_DIR)/net/ipv4/ip_gre.ko $(LINUX_DIR)/net/ipv4/gre.ko
+ AUTOLOAD:=$(call AutoLoad,39,gre ip_gre)
+endef
+
+define KernelPackage/gre/description
+ Generic Routing Encapsulation support
+endef
+
+$(eval $(call KernelPackage,gre))
+
+
+define KernelPackage/gre6
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=GRE support over IPV6
+ DEPENDS:=@IPV6 +kmod-iptunnel +kmod-ip6-tunnel
+ KCONFIG:=CONFIG_IPV6_GRE
+ FILES:=$(LINUX_DIR)/net/ipv6/ip6_gre.ko
+ AUTOLOAD:=$(call AutoLoad,39,ip6_gre)
+endef
+
+define KernelPackage/gre6/description
+ Generic Routing Encapsulation support over IPv6
+endef
+
+$(eval $(call KernelPackage,gre6))
+
+
+define KernelPackage/tun
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Universal TUN/TAP driver
+ KCONFIG:=CONFIG_TUN
+ FILES:=$(LINUX_DIR)/drivers/net/tun.ko
+ AUTOLOAD:=$(call AutoLoad,30,tun)
+endef
+
+define KernelPackage/tun/description
+ Kernel support for the TUN/TAP tunneling device
+endef
+
+$(eval $(call KernelPackage,tun))
+
+
+define KernelPackage/veth
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Virtual ethernet pair device
+ KCONFIG:=CONFIG_VETH
+ FILES:=$(LINUX_DIR)/drivers/net/veth.ko
+ AUTOLOAD:=$(call AutoLoad,30,veth)
+endef
+
+define KernelPackage/veth/description
+ This device is a local ethernet tunnel. Devices are created in pairs.
+ When one end receives the packet it appears on its pair and vice
+ versa.
+endef
+
+$(eval $(call KernelPackage,veth))
+
+
+define KernelPackage/slhc
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ HIDDEN:=1
+ TITLE:=Serial Line Header Compression
+ DEPENDS:=+kmod-lib-crc-ccitt
+ KCONFIG:=CONFIG_SLHC
+ FILES:=$(LINUX_DIR)/drivers/net/slip/slhc.ko
+endef
+
+$(eval $(call KernelPackage,slhc))
+
+
+define KernelPackage/ppp
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=PPP modules
+ DEPENDS:=+kmod-lib-crc-ccitt +kmod-slhc
+ KCONFIG:= \
+ CONFIG_PPP \
+ CONFIG_PPP_ASYNC
+ FILES:= \
+ $(LINUX_DIR)/drivers/net/ppp/ppp_async.ko \
+ $(LINUX_DIR)/drivers/net/ppp/ppp_generic.ko
+ AUTOLOAD:=$(call AutoProbe,ppp_async)
+endef
+
+define KernelPackage/ppp/description
+ Kernel modules for PPP support
+endef
+
+$(eval $(call KernelPackage,ppp))
+
+
+define KernelPackage/ppp-synctty
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=PPP sync tty support
+ DEPENDS:=kmod-ppp
+ KCONFIG:=CONFIG_PPP_SYNC_TTY
+ FILES:=$(LINUX_DIR)/drivers/net/ppp/ppp_synctty.ko
+ AUTOLOAD:=$(call AutoProbe,ppp_synctty)
+endef
+
+define KernelPackage/ppp-synctty/description
+ Kernel modules for PPP sync tty support
+endef
+
+$(eval $(call KernelPackage,ppp-synctty))
+
+
+define KernelPackage/pppox
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=PPPoX helper
+ DEPENDS:=kmod-ppp
+ KCONFIG:=CONFIG_PPPOE
+ FILES:=$(LINUX_DIR)/drivers/net/ppp/pppox.ko
+endef
+
+define KernelPackage/pppox/description
+ Kernel helper module for PPPoE and PPTP support
+endef
+
+$(eval $(call KernelPackage,pppox))
+
+
+define KernelPackage/pppoe
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=PPPoE support
+ DEPENDS:=kmod-ppp +kmod-pppox
+ KCONFIG:=CONFIG_PPPOE
+ FILES:=$(LINUX_DIR)/drivers/net/ppp/pppoe.ko
+ AUTOLOAD:=$(call AutoProbe,pppoe)
+endef
+
+define KernelPackage/pppoe/description
+ Kernel module for PPPoE (PPP over Ethernet) support
+endef
+
+$(eval $(call KernelPackage,pppoe))
+
+
+define KernelPackage/pppoa
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=PPPoA support
+ DEPENDS:=kmod-ppp +kmod-atm
+ KCONFIG:=CONFIG_PPPOATM CONFIG_ATM_DRIVERS=y
+ FILES:=$(LINUX_DIR)/net/atm/pppoatm.ko
+ AUTOLOAD:=$(call AutoLoad,40,pppoatm)
+endef
+
+define KernelPackage/pppoa/description
+ Kernel modules for PPPoA (PPP over ATM) support
+endef
+
+$(eval $(call KernelPackage,pppoa))
+
+
+define KernelPackage/pptp
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=PPtP support
+ DEPENDS:=kmod-ppp +kmod-gre +kmod-pppox
+ KCONFIG:=CONFIG_PPTP
+ FILES:=$(LINUX_DIR)/drivers/net/ppp/pptp.ko
+ AUTOLOAD:=$(call AutoProbe,pptp)
+endef
+
+$(eval $(call KernelPackage,pptp))
+
+
+define KernelPackage/pppol2tp
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=PPPoL2TP support
+ DEPENDS:=kmod-ppp +kmod-pppox +kmod-l2tp
+ KCONFIG:=CONFIG_PPPOL2TP
+ FILES:=$(LINUX_DIR)/net/l2tp/l2tp_ppp.ko
+ AUTOLOAD:=$(call AutoProbe,l2tp_ppp)
+endef
+
+define KernelPackage/pppol2tp/description
+ Kernel modules for PPPoL2TP (PPP over L2TP) support
+endef
+
+$(eval $(call KernelPackage,pppol2tp))
+
+
+define KernelPackage/ipoa
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=IPoA support
+ DEPENDS:=kmod-atm
+ KCONFIG:=CONFIG_ATM_CLIP
+ FILES:=$(LINUX_DIR)/net/atm/clip.ko
+ AUTOLOAD:=$(call AutoProbe,clip)
+endef
+
+define KernelPackage/ipoa/description
+ Kernel modules for IPoA (IP over ATM) support
+endef
+
+$(eval $(call KernelPackage,ipoa))
+
+
+define KernelPackage/mppe
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Microsoft PPP compression/encryption
+ DEPENDS:=kmod-ppp +kmod-crypto-sha1 +kmod-crypto-ecb
+ KCONFIG:= \
+ CONFIG_PPP_MPPE_MPPC \
+ CONFIG_PPP_MPPE
+ FILES:=$(LINUX_DIR)/drivers/net/ppp/ppp_mppe.ko
+ AUTOLOAD:=$(call AutoProbe,ppp_mppe)
+endef
+
+define KernelPackage/mppe/description
+ Kernel modules for Microsoft PPP compression/encryption
+endef
+
+$(eval $(call KernelPackage,mppe))
+
+
+SCHED_MODULES = $(patsubst $(LINUX_DIR)/net/sched/%.ko,%,$(wildcard $(LINUX_DIR)/net/sched/*.ko))
+SCHED_MODULES_CORE = sch_ingress sch_fq_codel sch_hfsc cls_fw cls_route cls_flow cls_tcindex cls_u32 em_u32 act_mirred act_skbedit
+SCHED_MODULES_FILTER = $(SCHED_MODULES_CORE) act_connmark sch_esfq
+SCHED_MODULES_EXTRA = $(filter-out $(SCHED_MODULES_FILTER),$(SCHED_MODULES))
+SCHED_FILES = $(patsubst %,$(LINUX_DIR)/net/sched/%.ko,$(filter $(SCHED_MODULES_CORE),$(SCHED_MODULES)))
+SCHED_FILES_EXTRA = $(patsubst %,$(LINUX_DIR)/net/sched/%.ko,$(SCHED_MODULES_EXTRA))
+
+define KernelPackage/sched-core
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Traffic schedulers
+ KCONFIG:= \
+ CONFIG_NET_SCHED=y \
+ CONFIG_NET_SCH_HFSC \
+ CONFIG_NET_SCH_INGRESS \
+ CONFIG_NET_SCH_FQ_CODEL \
+ CONFIG_NET_CLS=y \
+ CONFIG_NET_CLS_ACT=y \
+ CONFIG_NET_CLS_FLOW \
+ CONFIG_NET_CLS_FW \
+ CONFIG_NET_CLS_ROUTE4 \
+ CONFIG_NET_CLS_TCINDEX \
+ CONFIG_NET_CLS_U32 \
+ CONFIG_NET_ACT_MIRRED \
+ CONFIG_NET_ACT_SKBEDIT \
+ CONFIG_NET_EMATCH=y \
+ CONFIG_NET_EMATCH_U32
+ FILES:=$(SCHED_FILES)
+ AUTOLOAD:=$(call AutoLoad,70, $(SCHED_MODULES_CORE))
+endef
+
+define KernelPackage/sched-core/description
+ Core kernel scheduler support for IP traffic
+endef
+
+$(eval $(call KernelPackage,sched-core))
+
+
+define KernelPackage/sched-connmark
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Traffic shaper conntrack mark support
+ DEPENDS:=+kmod-sched-core +kmod-ipt-core +kmod-ipt-conntrack-extra
+ KCONFIG:=CONFIG_NET_ACT_CONNMARK
+ FILES:=$(LINUX_DIR)/net/sched/act_connmark.ko
+ AUTOLOAD:=$(call AutoLoad,71, act_connmark)
+endef
+$(eval $(call KernelPackage,sched-connmark))
+
+define KernelPackage/sched-esfq
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Traffic shaper ESFQ support
+ DEPENDS:=+kmod-sched-core +kmod-ipt-core +kmod-ipt-conntrack
+ KCONFIG:= \
+ CONFIG_NET_SCH_ESFQ \
+ CONFIG_NET_SCH_ESFQ_NFCT=y
+ FILES:=$(LINUX_DIR)/net/sched/sch_esfq.ko
+ AUTOLOAD:=$(call AutoLoad,72, sch_esfq)
+endef
+$(eval $(call KernelPackage,sched-esfq))
+
+define KernelPackage/sched
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Extra traffic schedulers
+ DEPENDS:=+kmod-sched-core +kmod-ipt-core
+ KCONFIG:= \
+ CONFIG_NET_SCH_CODEL \
+ CONFIG_NET_SCH_DSMARK \
+ CONFIG_NET_SCH_HTB \
+ CONFIG_NET_SCH_FIFO \
+ CONFIG_NET_SCH_GRED \
+ CONFIG_NET_SCH_PRIO \
+ CONFIG_NET_SCH_RED \
+ CONFIG_NET_SCH_TBF \
+ CONFIG_NET_SCH_SFQ \
+ CONFIG_NET_SCH_TEQL \
+ CONFIG_NET_SCH_FQ \
+ CONFIG_NET_SCH_PIE \
+ CONFIG_NET_CLS_BASIC \
+ CONFIG_NET_ACT_POLICE \
+ CONFIG_NET_ACT_IPT \
+ CONFIG_NET_EMATCH_CMP \
+ CONFIG_NET_EMATCH_NBYTE \
+ CONFIG_NET_EMATCH_META \
+ CONFIG_NET_EMATCH_TEXT
+ FILES:=$(SCHED_FILES_EXTRA)
+ AUTOLOAD:=$(call AutoLoad,73, $(SCHED_MODULES_EXTRA))
+endef
+
+define KernelPackage/sched/description
+ Extra kernel schedulers modules for IP traffic
+endef
+
+$(eval $(call KernelPackage,sched))
+
+
+define KernelPackage/ax25
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=AX25 support
+ DEPENDS:=+kmod-lib-crc16
+ KCONFIG:= \
+ CONFIG_HAMRADIO=y \
+ CONFIG_AX25 \
+ CONFIG_MKISS
+ FILES:= \
+ $(LINUX_DIR)/net/ax25/ax25.ko \
+ $(LINUX_DIR)/drivers/net/hamradio/mkiss.ko
+ AUTOLOAD:=$(call AutoLoad,80,ax25 mkiss)
+endef
+
+define KernelPackage/ax25/description
+ Kernel modules for AX25 support
+endef
+
+$(eval $(call KernelPackage,ax25))
+
+
+define KernelPackage/pktgen
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ DEPENDS:=@!TARGET_uml
+ TITLE:=Network packet generator
+ KCONFIG:=CONFIG_NET_PKTGEN
+ FILES:=$(LINUX_DIR)/net/core/pktgen.ko
+ AUTOLOAD:=$(call AutoLoad,99,pktgen)
+endef
+
+define KernelPackage/pktgen/description
+ Kernel modules for the Network Packet Generator
+endef
+
+$(eval $(call KernelPackage,pktgen))
+
+define KernelPackage/l2tp
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Layer Two Tunneling Protocol (L2TP)
+ DEPENDS:= \
+ +kmod-udptunnel4 \
+ +IPV6:kmod-udptunnel6
+ KCONFIG:=CONFIG_L2TP \
+ CONFIG_L2TP_V3=y \
+ CONFIG_L2TP_DEBUGFS=n
+ FILES:=$(LINUX_DIR)/net/l2tp/l2tp_core.ko \
+ $(LINUX_DIR)/net/l2tp/l2tp_netlink.ko
+ AUTOLOAD:=$(call AutoLoad,32,l2tp_core l2tp_netlink)
+endef
+
+define KernelPackage/l2tp/description
+ Kernel modules for L2TP V3 Support
+endef
+
+$(eval $(call KernelPackage,l2tp))
+
+
+define KernelPackage/l2tp-eth
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=L2TP ethernet pseudowire support for L2TPv3
+ DEPENDS:=+kmod-l2tp
+ KCONFIG:=CONFIG_L2TP_ETH
+ FILES:=$(LINUX_DIR)/net/l2tp/l2tp_eth.ko
+ AUTOLOAD:=$(call AutoLoad,33,l2tp_eth)
+endef
+
+define KernelPackage/l2tp-eth/description
+ Kernel modules for L2TP ethernet pseudowire support for L2TPv3
+endef
+
+$(eval $(call KernelPackage,l2tp-eth))
+
+define KernelPackage/l2tp-ip
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=L2TP IP encapsulation for L2TPv3
+ DEPENDS:=+kmod-l2tp
+ KCONFIG:=CONFIG_L2TP_IP
+ FILES:= \
+ $(LINUX_DIR)/net/l2tp/l2tp_ip.ko \
+ $(if $(CONFIG_IPV6),$(LINUX_DIR)/net/l2tp/l2tp_ip6.ko)
+ AUTOLOAD:=$(call AutoLoad,33,l2tp_ip $(if $(CONFIG_IPV6),l2tp_ip6))
+endef
+
+define KernelPackage/l2tp-ip/description
+ Kernel modules for L2TP IP encapsulation for L2TPv3
+endef
+
+$(eval $(call KernelPackage,l2tp-ip))
+
+
+define KernelPackage/sctp
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=SCTP protocol kernel support
+ KCONFIG:=\
+ CONFIG_IP_SCTP \
+ CONFIG_SCTP_DBG_MSG=n \
+ CONFIG_SCTP_DBG_OBJCNT=n \
+ CONFIG_SCTP_HMAC_NONE=n \
+ CONFIG_SCTP_HMAC_SHA1=n \
+ CONFIG_SCTP_HMAC_MD5=y \
+ CONFIG_SCTP_COOKIE_HMAC_SHA1=n \
+ CONFIG_SCTP_COOKIE_HMAC_MD5=y \
+ CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE=n \
+ CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1=n \
+ CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y
+ FILES:= $(LINUX_DIR)/net/sctp/sctp.ko
+ AUTOLOAD:= $(call AutoLoad,32,sctp)
+ DEPENDS:=+kmod-lib-crc32c +kmod-crypto-md5 +kmod-crypto-hmac
+endef
+
+define KernelPackage/sctp/description
+ Kernel modules for SCTP protocol support
+endef
+
+$(eval $(call KernelPackage,sctp))
+
+
+define KernelPackage/netem
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=Network emulation functionality
+ DEPENDS:=+kmod-sched
+ KCONFIG:=CONFIG_NET_SCH_NETEM
+ FILES:=$(LINUX_DIR)/net/sched/sch_netem.ko
+ AUTOLOAD:=$(call AutoLoad,99,netem)
+endef
+
+define KernelPackage/netem/description
+ Kernel modules for emulating the properties of wide area networks
+endef
+
+$(eval $(call KernelPackage,netem))
+
+define KernelPackage/slip
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ DEPENDS:=+kmod-slhc
+ TITLE:=SLIP modules
+ KCONFIG:= \
+ CONFIG_SLIP \
+ CONFIG_SLIP_COMPRESSED=y \
+ CONFIG_SLIP_SMART=y \
+ CONFIG_SLIP_MODE_SLIP6=y
+
+ FILES:= \
+ $(LINUX_DIR)/drivers/net/slip/slip.ko
+ AUTOLOAD:=$(call AutoLoad,30,slip)
+endef
+
+define KernelPackage/slip/description
+ Kernel modules for SLIP support
+endef
+
+$(eval $(call KernelPackage,slip))
+
+define KernelPackage/dnsresolver
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=In-kernel DNS Resolver
+ KCONFIG:= CONFIG_DNS_RESOLVER
+ FILES:=$(LINUX_DIR)/net/dns_resolver/dns_resolver.ko
+ AUTOLOAD:=$(call AutoLoad,30,dns_resolver)
+endef
+
+$(eval $(call KernelPackage,dnsresolver))
+
+define KernelPackage/rxrpc
+ SUBMENU:=$(NETWORK_SUPPORT_MENU)
+ TITLE:=AF_RXRPC support
+ KCONFIG:= \
+ CONFIG_AF_RXRPC \
+ CONFIG_RXKAD=m \
+ CONFIG_AF_RXRPC_DEBUG=n
+ FILES:= \
+ $(LINUX_DIR)/net/rxrpc/af-rxrpc.ko \
+ $(LINUX_DIR)/net/rxrpc/rxkad.ko
+ AUTOLOAD:=$(call AutoLoad,30,rxkad af-rxrpc)
+ DEPENDS:= +kmod-crypto-manager +kmod-crypto-pcbc +kmod-crypto-fcrypt
+endef
+
+define KernelPackage/rxrpc/description
+ Kernel support for AF_RXRPC; required for AFS client
+endef
+
+$(eval $(call KernelPackage,rxrpc))
diff --git a/package/kernel/linux/modules/nls.mk b/package/kernel/linux/modules/nls.mk
new file mode 100644
index 0000000..55c5c1a
--- /dev/null
+++ b/package/kernel/linux/modules/nls.mk
@@ -0,0 +1,307 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define KernelPackage/nls-base
+ SUBMENU:=Native Language Support
+ TITLE:=Native Language Support
+ KCONFIG:=CONFIG_NLS
+ FILES:=$(LINUX_DIR)/fs/nls/nls_base.ko
+endef
+
+define KernelPackage/nls-base/description
+ Kernel module for NLS (Native Language Support)
+endef
+
+$(eval $(call KernelPackage,nls-base))
+
+
+define KernelPackage/nls-cp437
+ SUBMENU:=Native Language Support
+ TITLE:=Codepage 437 (United States, Canada)
+ KCONFIG:=CONFIG_NLS_CODEPAGE_437
+ FILES:=$(LINUX_DIR)/fs/nls/nls_cp437.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_cp437)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-cp437/description
+ Kernel module for NLS Codepage 437 (United States, Canada)
+endef
+
+$(eval $(call KernelPackage,nls-cp437))
+
+
+define KernelPackage/nls-cp775
+ SUBMENU:=Native Language Support
+ TITLE:=Codepage 775 (Baltic Rim)
+ KCONFIG:=CONFIG_NLS_CODEPAGE_775
+ FILES:=$(LINUX_DIR)/fs/nls/nls_cp775.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_cp775)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-cp775/description
+ Kernel module for NLS Codepage 775 (Baltic Rim)
+endef
+
+$(eval $(call KernelPackage,nls-cp775))
+
+
+define KernelPackage/nls-cp850
+ SUBMENU:=Native Language Support
+ TITLE:=Codepage 850 (Europe)
+ KCONFIG:=CONFIG_NLS_CODEPAGE_850
+ FILES:=$(LINUX_DIR)/fs/nls/nls_cp850.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_cp850)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-cp850/description
+ Kernel module for NLS Codepage 850 (Europe)
+endef
+
+$(eval $(call KernelPackage,nls-cp850))
+
+
+define KernelPackage/nls-cp852
+ SUBMENU:=Native Language Support
+ TITLE:=Codepage 852 (Europe)
+ KCONFIG:=CONFIG_NLS_CODEPAGE_852
+ FILES:=$(LINUX_DIR)/fs/nls/nls_cp852.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_cp852)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-cp852/description
+ Kernel module for NLS Codepage 852 (Europe)
+endef
+
+$(eval $(call KernelPackage,nls-cp852))
+
+
+define KernelPackage/nls-cp862
+ SUBMENU:=Native Language Support
+ TITLE:=Codepage 862 (Hebrew)
+ KCONFIG:=CONFIG_NLS_CODEPAGE_862
+ FILES:=$(LINUX_DIR)/fs/nls/nls_cp862.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_cp862)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-cp862/description
+ Kernel module for NLS Codepage 862 (Hebrew)
+endef
+
+$(eval $(call KernelPackage,nls-cp862))
+
+
+define KernelPackage/nls-cp864
+ SUBMENU:=Native Language Support
+ TITLE:=Codepage 864 (Arabic)
+ KCONFIG:=CONFIG_NLS_CODEPAGE_864
+ FILES:=$(LINUX_DIR)/fs/nls/nls_cp864.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_cp864)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-cp864/description
+ Kernel module for NLS Codepage 864 (Arabic)
+endef
+
+$(eval $(call KernelPackage,nls-cp864))
+
+
+define KernelPackage/nls-cp866
+ SUBMENU:=Native Language Support
+ TITLE:=Codepage 866 (Cyrillic)
+ KCONFIG:=CONFIG_NLS_CODEPAGE_866
+ FILES:=$(LINUX_DIR)/fs/nls/nls_cp866.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_cp866)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-cp866/description
+ Kernel module for NLS Codepage 866 (Cyrillic)
+endef
+
+$(eval $(call KernelPackage,nls-cp866))
+
+
+define KernelPackage/nls-cp932
+ SUBMENU:=Native Language Support
+ TITLE:=Codepage 932 (Japanese)
+ KCONFIG:=CONFIG_NLS_CODEPAGE_932
+ FILES:=$(LINUX_DIR)/fs/nls/nls_cp932.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_cp932)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-cp932/description
+ Kernel module for NLS Codepage 932 (Japanese)
+endef
+
+$(eval $(call KernelPackage,nls-cp932))
+
+
+define KernelPackage/nls-cp1250
+ SUBMENU:=Native Language Support
+ TITLE:=Codepage 1250 (Eastern Europe)
+ KCONFIG:=CONFIG_NLS_CODEPAGE_1250
+ FILES:=$(LINUX_DIR)/fs/nls/nls_cp1250.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_cp1250)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-cp1250/description
+ Kernel module for NLS Codepage 1250 (Eastern Europe)
+endef
+
+$(eval $(call KernelPackage,nls-cp1250))
+
+
+define KernelPackage/nls-cp1251
+ SUBMENU:=Native Language Support
+ TITLE:=Codepage 1251 (Russian)
+ KCONFIG:=CONFIG_NLS_CODEPAGE_1251
+ FILES:=$(LINUX_DIR)/fs/nls/nls_cp1251.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_cp1251)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-cp1251/description
+ Kernel module for NLS Codepage 1251 (Russian)
+endef
+
+$(eval $(call KernelPackage,nls-cp1251))
+
+
+define KernelPackage/nls-iso8859-1
+ SUBMENU:=Native Language Support
+ TITLE:=ISO 8859-1 (Latin 1; Western European Languages)
+ KCONFIG:=CONFIG_NLS_ISO8859_1
+ FILES:=$(LINUX_DIR)/fs/nls/nls_iso8859-1.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_iso8859-1)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-iso8859-1/description
+ Kernel module for NLS ISO 8859-1 (Latin 1)
+endef
+
+$(eval $(call KernelPackage,nls-iso8859-1))
+
+
+define KernelPackage/nls-iso8859-2
+ SUBMENU:=Native Language Support
+ TITLE:=ISO 8859-2 (Latin 2; Central European Languages)
+ KCONFIG:=CONFIG_NLS_ISO8859_2
+ FILES:=$(LINUX_DIR)/fs/nls/nls_iso8859-2.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_iso8859-2)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-iso8859-2/description
+ Kernel module for NLS ISO 8859-2 (Latin 2)
+endef
+
+$(eval $(call KernelPackage,nls-iso8859-2))
+
+
+define KernelPackage/nls-iso8859-6
+ SUBMENU:=Native Language Support
+ TITLE:=ISO 8859-6 (Arabic)
+ KCONFIG:=CONFIG_NLS_ISO8859_6
+ FILES:=$(LINUX_DIR)/fs/nls/nls_iso8859-6.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_iso8859-6)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-iso8859-6/description
+ Kernel module for NLS ISO 8859-6 (Arabic)
+endef
+
+$(eval $(call KernelPackage,nls-iso8859-6))
+
+
+define KernelPackage/nls-iso8859-8
+ SUBMENU:=Native Language Support
+ TITLE:=ISO 8859-8, CP1255 (Hebrew)
+ KCONFIG:=CONFIG_NLS_ISO8859_8
+ FILES:=$(LINUX_DIR)/fs/nls/nls_cp1255.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_cp1255)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-iso8859-8/description
+ Kernel module for Hebrew charsets (ISO-8859-8, CP1255)
+endef
+
+$(eval $(call KernelPackage,nls-iso8859-8))
+
+
+define KernelPackage/nls-iso8859-13
+ SUBMENU:=Native Language Support
+ TITLE:=ISO 8859-13 (Latin 7; Baltic)
+ KCONFIG:=CONFIG_NLS_ISO8859_13
+ FILES:=$(LINUX_DIR)/fs/nls/nls_iso8859-13.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_iso8859-13)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-iso8859-13/description
+ Kernel module for NLS ISO 8859-13 (Latin 7; Baltic)
+endef
+
+$(eval $(call KernelPackage,nls-iso8859-13))
+
+
+define KernelPackage/nls-iso8859-15
+ SUBMENU:=Native Language Support
+ TITLE:=ISO 8859-15 (Latin 9; Western, with Euro symbol)
+ KCONFIG:=CONFIG_NLS_ISO8859_15
+ FILES:=$(LINUX_DIR)/fs/nls/nls_iso8859-15.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_iso8859-15)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-iso8859-15/description
+ Kernel module for NLS ISO 8859-15 (Latin 9)
+endef
+
+$(eval $(call KernelPackage,nls-iso8859-15))
+
+
+define KernelPackage/nls-koi8r
+ SUBMENU:=Native Language Support
+ TITLE:=KOI8-R (Russian)
+ KCONFIG:=CONFIG_NLS_KOI8_R
+ FILES:=$(LINUX_DIR)/fs/nls/nls_koi8-r.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_koi8-r)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-koi8r/description
+ Kernel module for NLS KOI8-R (Russian)
+endef
+
+$(eval $(call KernelPackage,nls-koi8r))
+
+
+define KernelPackage/nls-utf8
+ SUBMENU:=Native Language Support
+ TITLE:=UTF-8
+ KCONFIG:=CONFIG_NLS_UTF8
+ FILES:=$(LINUX_DIR)/fs/nls/nls_utf8.ko
+ AUTOLOAD:=$(call AutoLoad,25,nls_utf8)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/nls-utf8/description
+ Kernel module for NLS UTF-8
+endef
+
+$(eval $(call KernelPackage,nls-utf8))
diff --git a/package/kernel/linux/modules/other.mk b/package/kernel/linux/modules/other.mk
new file mode 100644
index 0000000..022410f
--- /dev/null
+++ b/package/kernel/linux/modules/other.mk
@@ -0,0 +1,971 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+OTHER_MENU:=Other modules
+
+WATCHDOG_DIR:=watchdog
+
+
+define KernelPackage/6lowpan
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=6LoWPAN shared code
+ KCONFIG:= \
+ CONFIG_6LOWPAN \
+ CONFIG_6LOWPAN_NHC=n
+ FILES:=$(LINUX_DIR)/net/6lowpan/6lowpan.ko
+ AUTOLOAD:=$(call AutoProbe,6lowpan)
+endef
+
+define KernelPackage/6lowpan/description
+ Shared 6lowpan code for IEEE 802.15.4 and Bluetooth.
+endef
+
+$(eval $(call KernelPackage,6lowpan))
+
+
+define KernelPackage/bluetooth
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Bluetooth support
+ DEPENDS:=@USB_SUPPORT +kmod-usb-core +kmod-crypto-hash +kmod-crypto-ecb +kmod-lib-crc16 +kmod-hid +!LINUX_3_18:kmod-crypto-cmac
+ KCONFIG:= \
+ CONFIG_BLUEZ \
+ CONFIG_BLUEZ_L2CAP \
+ CONFIG_BLUEZ_SCO \
+ CONFIG_BLUEZ_RFCOMM \
+ CONFIG_BLUEZ_BNEP \
+ CONFIG_BLUEZ_HCIUART \
+ CONFIG_BLUEZ_HCIUSB \
+ CONFIG_BLUEZ_HIDP \
+ CONFIG_BT \
+ CONFIG_BT_BREDR=y \
+ CONFIG_BT_DEBUGFS=n \
+ CONFIG_BT_L2CAP=y \
+ CONFIG_BT_LE=y \
+ CONFIG_BT_SCO=y \
+ CONFIG_BT_RFCOMM \
+ CONFIG_BT_BNEP \
+ CONFIG_BT_HCIBTUSB \
+ CONFIG_BT_HCIBTUSB_BCM=n \
+ CONFIG_BT_HCIUSB \
+ CONFIG_BT_HCIUART \
+ CONFIG_BT_HCIUART_BCM=n \
+ CONFIG_BT_HCIUART_INTEL=n \
+ CONFIG_BT_HCIUART_H4 \
+ CONFIG_BT_HIDP \
+ CONFIG_HID_SUPPORT=y
+ $(call AddDepends/rfkill)
+ FILES:= \
+ $(LINUX_DIR)/net/bluetooth/bluetooth.ko \
+ $(LINUX_DIR)/net/bluetooth/rfcomm/rfcomm.ko \
+ $(LINUX_DIR)/net/bluetooth/bnep/bnep.ko \
+ $(LINUX_DIR)/net/bluetooth/hidp/hidp.ko \
+ $(LINUX_DIR)/drivers/bluetooth/hci_uart.ko \
+ $(LINUX_DIR)/drivers/bluetooth/btusb.ko
+ifeq ($(strip $(call CompareKernelPatchVer,$(KERNEL_PATCHVER),ge,4.1.0)),1)
+ FILES+= \
+ $(LINUX_DIR)/drivers/bluetooth/btintel.ko
+endif
+ AUTOLOAD:=$(call AutoProbe,bluetooth rfcomm bnep hidp hci_uart btusb)
+endef
+
+define KernelPackage/bluetooth/description
+ Kernel support for Bluetooth devices
+endef
+
+$(eval $(call KernelPackage,bluetooth))
+
+define KernelPackage/ath3k
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=ATH3K Kernel Module support
+ DEPENDS:=+kmod-bluetooth +ar3k-firmware
+ KCONFIG:= \
+ CONFIG_BT_ATH3K \
+ CONFIG_BT_HCIUART_ATH3K=y
+ $(call AddDepends/bluetooth)
+ FILES:= \
+ $(LINUX_DIR)/drivers/bluetooth/ath3k.ko
+ AUTOLOAD:=$(call AutoProbe,ath3k)
+endef
+
+define KernelPackage/ath3k/description
+ Kernel support for ATH3K Module
+endef
+
+$(eval $(call KernelPackage,ath3k))
+
+
+define KernelPackage/bluetooth_6lowpan
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Bluetooth 6LoWPAN support
+ DEPENDS:=+kmod-6lowpan +kmod-bluetooth
+ KCONFIG:=CONFIG_BT_6LOWPAN
+ FILES:=$(LINUX_DIR)/net/bluetooth/bluetooth_6lowpan.ko
+ AUTOLOAD:=$(call AutoProbe,bluetooth_6lowpan)
+endef
+
+define KernelPackage/bluetooth_6lowpan/description
+ Kernel support for 6LoWPAN over Bluetooth Low Energy devices
+endef
+
+$(eval $(call KernelPackage,bluetooth_6lowpan))
+
+
+define KernelPackage/bluetooth-hci-h4p
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=HCI driver with H4 Nokia extensions
+ DEPENDS:=@TARGET_omap24xx +kmod-bluetooth
+ KCONFIG:=CONFIG_BT_HCIH4P
+ FILES:=$(LINUX_DIR)/drivers/bluetooth/hci_h4p/hci_h4p.ko
+ AUTOLOAD:=$(call AutoProbe,hci_h4p)
+endef
+
+define KernelPackage/bluetooth-hci-h4p/description
+ HCI driver with H4 Nokia extensions
+endef
+
+$(eval $(call KernelPackage,bluetooth-hci-h4p))
+
+
+define KernelPackage/eeprom-93cx6
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=EEPROM 93CX6 support
+ KCONFIG:=CONFIG_EEPROM_93CX6
+ FILES:=$(LINUX_DIR)/drivers/misc/eeprom/eeprom_93cx6.ko
+ AUTOLOAD:=$(call AutoLoad,20,eeprom_93cx6)
+endef
+
+define KernelPackage/eeprom-93cx6/description
+ Kernel module for EEPROM 93CX6 support
+endef
+
+$(eval $(call KernelPackage,eeprom-93cx6))
+
+
+define KernelPackage/eeprom-at24
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=EEPROM AT24 support
+ KCONFIG:=CONFIG_EEPROM_AT24
+ DEPENDS:=+kmod-i2c-core
+ FILES:=$(LINUX_DIR)/drivers/misc/eeprom/at24.ko
+ AUTOLOAD:=$(call AutoProbe,at24)
+endef
+
+define KernelPackage/eeprom-at24/description
+ Kernel module for most I2C EEPROMs
+endef
+
+$(eval $(call KernelPackage,eeprom-at24))
+
+
+define KernelPackage/eeprom-at25
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=EEPROM AT25 support
+ KCONFIG:=CONFIG_EEPROM_AT25
+ FILES:=$(LINUX_DIR)/drivers/misc/eeprom/at25.ko
+ AUTOLOAD:=$(call AutoProbe,at25)
+endef
+
+define KernelPackage/eeprom-at25/description
+ Kernel module for most SPI EEPROMs
+endef
+
+$(eval $(call KernelPackage,eeprom-at25))
+
+
+define KernelPackage/gpio-dev
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Generic GPIO char device support
+ DEPENDS:=@GPIO_SUPPORT
+ KCONFIG:=CONFIG_GPIO_DEVICE
+ FILES:=$(LINUX_DIR)/drivers/char/gpio_dev.ko
+ AUTOLOAD:=$(call AutoLoad,40,gpio_dev)
+endef
+
+define KernelPackage/gpio-dev/description
+ Kernel module to allows control of GPIO pins using a character device.
+endef
+
+$(eval $(call KernelPackage,gpio-dev))
+
+
+define KernelPackage/gpio-mcp23s08
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Microchip MCP23xxx I/O expander
+ DEPENDS:=@GPIO_SUPPORT +PACKAGE_kmod-i2c-core:kmod-i2c-core
+ KCONFIG:=CONFIG_GPIO_MCP23S08
+ FILES:=$(LINUX_DIR)/drivers/gpio/gpio-mcp23s08.ko
+ AUTOLOAD:=$(call AutoLoad,40,gpio-mcp23s08)
+endef
+
+define KernelPackage/gpio-mcp23s08/description
+ Kernel module for Microchip MCP23xxx SPI/I2C I/O expander
+endef
+
+$(eval $(call KernelPackage,gpio-mcp23s08))
+
+
+define KernelPackage/gpio-nxp-74hc164
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=NXP 74HC164 GPIO expander support
+ KCONFIG:=CONFIG_GPIO_NXP_74HC164
+ FILES:=$(LINUX_DIR)/drivers/gpio/nxp_74hc164.ko
+ AUTOLOAD:=$(call AutoProbe,nxp_74hc164)
+endef
+
+define KernelPackage/gpio-nxp-74hc164/description
+ Kernel module for NXP 74HC164 GPIO expander
+endef
+
+$(eval $(call KernelPackage,gpio-nxp-74hc164))
+
+define KernelPackage/gpio-pca953x
+ SUBMENU:=$(OTHER_MENU)
+ DEPENDS:=@GPIO_SUPPORT +kmod-i2c-core
+ TITLE:=PCA95xx, TCA64xx, and MAX7310 I/O ports
+ KCONFIG:=CONFIG_GPIO_PCA953X
+ FILES:=$(LINUX_DIR)/drivers/gpio/gpio-pca953x.ko
+ AUTOLOAD:=$(call AutoLoad,55,gpio-pca953x)
+endef
+
+define KernelPackage/gpio-pca953x/description
+ Kernel module for MAX731{0,2,3,5}, PCA6107, PCA953{4-9}, PCA955{4-7},
+ PCA957{4,5} and TCA64{08,16} I2C GPIO expanders
+endef
+
+$(eval $(call KernelPackage,gpio-pca953x))
+
+define KernelPackage/gpio-pcf857x
+ SUBMENU:=$(OTHER_MENU)
+ DEPENDS:=@GPIO_SUPPORT +kmod-i2c-core
+ TITLE:=PCX857x, PCA967x and MAX732X I2C GPIO expanders
+ KCONFIG:=CONFIG_GPIO_PCF857X
+ FILES:=$(LINUX_DIR)/drivers/gpio/gpio-pcf857x.ko
+ AUTOLOAD:=$(call AutoLoad,55,gpio-pcf857x)
+endef
+
+define KernelPackage/gpio-pcf857x/description
+ Kernel module for PCF857x, PCA{85,96}7x, and MAX732[89] I2C GPIO expanders
+endef
+
+$(eval $(call KernelPackage,gpio-pcf857x))
+
+define KernelPackage/iio-core
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Industrial IO core
+ KCONFIG:= \
+ CONFIG_IIO \
+ CONFIG_IIO_BUFFER=y \
+ CONFIG_IIO_KFIFO_BUF \
+ CONFIG_IIO_TRIGGER=y \
+ CONFIG_IIO_TRIGGERED_BUFFER
+ FILES:= \
+ $(LINUX_DIR)/drivers/iio/industrialio.ko \
+ $(if $(CONFIG_IIO_TRIGGERED_BUFFER),$(LINUX_DIR)/drivers/iio/industrialio-triggered-buffer.ko) \
+ $(LINUX_DIR)/drivers/iio/kfifo_buf.ko
+ AUTOLOAD:=$(call AutoLoad,55,industrialio kfifo_buf industrialio-triggered-buffer)
+endef
+
+define KernelPackage/iio-core/description
+ The industrial I/O subsystem provides a unified framework for
+ drivers for many different types of embedded sensors using a
+ number of different physical interfaces (i2c, spi, etc)
+endef
+
+$(eval $(call KernelPackage,iio-core))
+
+
+define KernelPackage/iio-ad799x
+ SUBMENU:=$(OTHER_MENU)
+ DEPENDS:=kmod-i2c-core kmod-iio-core
+ TITLE:=Analog Devices AD799x ADC driver
+ KCONFIG:= \
+ CONFIG_AD799X_RING_BUFFER=y \
+ CONFIG_AD799X
+ FILES:=$(LINUX_DIR)/drivers/iio/adc/ad799x.ko
+ AUTOLOAD:=$(call AutoLoad,56,ad799x)
+endef
+
+define KernelPackage/iio-ad799x/description
+ support for Analog Devices:
+ ad7991, ad7995, ad7999, ad7992, ad7993, ad7994, ad7997, ad7998
+ i2c analog to digital converters (ADC).
+endef
+
+$(eval $(call KernelPackage,iio-ad799x))
+
+
+define KernelPackage/iio-dht11
+ SUBMENU:=$(OTHER_MENU)
+ DEPENDS:=kmod-iio-core @GPIO_SUPPORT @USES_DEVICETREE
+ TITLE:=DHT11 (and compatible) humidity and temperature sensors
+ KCONFIG:= \
+ CONFIG_DHT11
+ FILES:=$(LINUX_DIR)/drivers/iio/humidity/dht11.ko
+ AUTOLOAD:=$(call AutoLoad,56,dht11)
+endef
+
+define KernelPackage/iio-dht11/description
+ support for DHT11 and DHT22 digitial humidity and temperature sensors
+ attached at GPIO lines. You will need a custom device tree file to
+ specify the GPIO line to use.
+endef
+
+$(eval $(call KernelPackage,iio-dht11))
+
+
+define KernelPackage/lp
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Parallel port and line printer support
+ KCONFIG:= \
+ CONFIG_PARPORT \
+ CONFIG_PRINTER \
+ CONFIG_PPDEV
+ FILES:= \
+ $(LINUX_DIR)/drivers/parport/parport.ko \
+ $(LINUX_DIR)/drivers/char/lp.ko \
+ $(LINUX_DIR)/drivers/char/ppdev.ko
+ AUTOLOAD:=$(call AutoLoad,50,parport lp ppdev)
+endef
+
+$(eval $(call KernelPackage,lp))
+
+
+define KernelPackage/mmc
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=MMC/SD Card Support
+ KCONFIG:= \
+ CONFIG_MMC \
+ CONFIG_MMC_BLOCK \
+ CONFIG_MMC_DEBUG=n \
+ CONFIG_MMC_UNSAFE_RESUME=n \
+ CONFIG_MMC_BLOCK_BOUNCE=y \
+ CONFIG_MMC_TIFM_SD=n \
+ CONFIG_MMC_WBSD=n \
+ CONFIG_SDIO_UART=n
+ FILES:= \
+ $(LINUX_DIR)/drivers/mmc/core/mmc_core.ko \
+ $(LINUX_DIR)/drivers/mmc/card/mmc_block.ko
+ AUTOLOAD:=$(call AutoProbe,mmc_core mmc_block,1)
+endef
+
+define KernelPackage/mmc/description
+ Kernel support for MMC/SD cards
+endef
+
+$(eval $(call KernelPackage,mmc))
+
+
+define KernelPackage/sdhci
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Secure Digital Host Controller Interface support
+ DEPENDS:=+kmod-mmc
+ KCONFIG:= \
+ CONFIG_MMC_SDHCI \
+ CONFIG_MMC_SDHCI_PLTFM \
+ CONFIG_MMC_SDHCI_PCI=n
+ FILES:= \
+ $(LINUX_DIR)/drivers/mmc/host/sdhci.ko \
+ $(LINUX_DIR)/drivers/mmc/host/sdhci-pltfm.ko
+
+ AUTOLOAD:=$(call AutoProbe,sdhci sdhci-pltfm,1)
+endef
+
+define KernelPackage/sdhci/description
+ Kernel support for SDHCI Hosts
+endef
+
+$(eval $(call KernelPackage,sdhci))
+
+
+define KernelPackage/rfkill
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=RF switch subsystem support
+ DEPENDS:=@USE_RFKILL +kmod-input-core
+ KCONFIG:= \
+ CONFIG_RFKILL \
+ CONFIG_RFKILL_INPUT=y \
+ CONFIG_RFKILL_LEDS=y \
+ CONFIG_RFKILL_GPIO=y
+ FILES:= \
+ $(LINUX_DIR)/net/rfkill/rfkill.ko
+ AUTOLOAD:=$(call AutoLoad,20,rfkill)
+endef
+
+define KernelPackage/rfkill/description
+ Say Y here if you want to have control over RF switches
+ found on many WiFi and Bluetooth cards
+endef
+
+$(eval $(call KernelPackage,rfkill))
+
+
+define KernelPackage/softdog
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Software watchdog driver
+ KCONFIG:=CONFIG_SOFT_WATCHDOG
+ FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/softdog.ko
+ AUTOLOAD:=$(call AutoLoad,50,softdog)
+endef
+
+define KernelPackage/softdog/description
+ Software watchdog driver
+endef
+
+$(eval $(call KernelPackage,softdog))
+
+
+define KernelPackage/ssb
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Silicon Sonics Backplane glue code
+ DEPENDS:=@PCI_SUPPORT @!TARGET_brcm47xx @!TARGET_brcm63xx
+ KCONFIG:=\
+ CONFIG_SSB \
+ CONFIG_SSB_B43_PCI_BRIDGE=y \
+ CONFIG_SSB_DRIVER_MIPS=n \
+ CONFIG_SSB_DRIVER_PCICORE=y \
+ CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y \
+ CONFIG_SSB_PCIHOST=y \
+ CONFIG_SSB_PCIHOST_POSSIBLE=y \
+ CONFIG_SSB_POSSIBLE=y \
+ CONFIG_SSB_SPROM=y \
+ CONFIG_SSB_SILENT=y
+ FILES:=$(LINUX_DIR)/drivers/ssb/ssb.ko
+ AUTOLOAD:=$(call AutoLoad,18,ssb,1)
+endef
+
+define KernelPackage/ssb/description
+ Silicon Sonics Backplane glue code.
+endef
+
+$(eval $(call KernelPackage,ssb))
+
+
+define KernelPackage/bcma
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=BCMA support
+ DEPENDS:=@PCI_SUPPORT @!TARGET_brcm47xx @!TARGET_bcm53xx
+ KCONFIG:=\
+ CONFIG_BCMA \
+ CONFIG_BCMA_POSSIBLE=y \
+ CONFIG_BCMA_BLOCKIO=y \
+ CONFIG_BCMA_HOST_PCI_POSSIBLE=y \
+ CONFIG_BCMA_HOST_PCI=y \
+ CONFIG_BCMA_HOST_SOC=n \
+ CONFIG_BCMA_DRIVER_MIPS=n \
+ CONFIG_BCMA_DRIVER_PCI_HOSTMODE=n \
+ CONFIG_BCMA_DRIVER_GMAC_CMN=n \
+ CONFIG_BCMA_DEBUG=n
+ FILES:=$(LINUX_DIR)/drivers/bcma/bcma.ko
+ AUTOLOAD:=$(call AutoLoad,29,bcma)
+endef
+
+define KernelPackage/bcma/description
+ Bus driver for Broadcom specific Advanced Microcontroller Bus Architecture
+endef
+
+$(eval $(call KernelPackage,bcma))
+
+
+define KernelPackage/wdt-omap
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=OMAP Watchdog timer
+ DEPENDS:=@(TARGET_omap24xx||TARGET_omap35xx)
+ KCONFIG:=CONFIG_OMAP_WATCHDOG
+ FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/omap_wdt.ko
+ AUTOLOAD:=$(call AutoLoad,50,omap_wdt.ko,1)
+endef
+
+define KernelPackage/wdt-omap/description
+ Kernel module for TI omap watchdog timer
+endef
+
+$(eval $(call KernelPackage,wdt-omap))
+
+
+define KernelPackage/wdt-orion
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Marvell Orion Watchdog timer
+ DEPENDS:=@TARGET_orion||TARGET_kirkwood||TARGET_mvebu
+ KCONFIG:=CONFIG_ORION_WATCHDOG
+ FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/orion_wdt.ko
+ AUTOLOAD:=$(call AutoLoad,50,orion_wdt,1)
+endef
+
+define KernelPackage/wdt-orion/description
+ Kernel module for Marvell Orion, Kirkwood and Armada XP/370 watchdog timer
+endef
+
+$(eval $(call KernelPackage,wdt-orion))
+
+
+define KernelPackage/booke-wdt
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=PowerPC Book-E Watchdog Timer
+ DEPENDS:=@(TARGET_mpc85xx||TARGET_ppc40x||TARGET_ppc44x)
+ KCONFIG:=CONFIG_BOOKE_WDT
+ FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/booke_wdt.ko
+ AUTOLOAD:=$(call AutoLoad,50,booke_wdt,1)
+endef
+
+define KernelPackage/booke-wdt/description
+ Kernel module for PowerPC Book-E Watchdog Timer
+endef
+
+$(eval $(call KernelPackage,booke-wdt))
+
+
+define KernelPackage/rtc-ds1307
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Dallas/Maxim DS1307 (and compatible) RTC support
+ DEPENDS:=@RTC_SUPPORT +kmod-i2c-core
+ KCONFIG:=CONFIG_RTC_DRV_DS1307
+ FILES:=$(LINUX_DIR)/drivers/rtc/rtc-ds1307.ko
+ AUTOLOAD:=$(call AutoProbe,rtc-ds1307)
+endef
+
+define KernelPackage/rtc-ds1307/description
+ Kernel module for Dallas/Maxim DS1307/DS1337/DS1338/DS1340/DS1388/DS3231,
+ Epson RX-8025 and various other compatible RTC chips connected via I2C.
+endef
+
+$(eval $(call KernelPackage,rtc-ds1307))
+
+
+define KernelPackage/rtc-ds1672
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Dallas/Maxim DS1672 RTC support
+ DEPENDS:=@RTC_SUPPORT +kmod-i2c-core
+ KCONFIG:=CONFIG_RTC_DRV_DS1672
+ FILES:=$(LINUX_DIR)/drivers/rtc/rtc-ds1672.ko
+ AUTOLOAD:=$(call AutoProbe,rtc-ds1672)
+endef
+
+define KernelPackage/rtc-ds1672/description
+ Kernel module for Dallas/Maxim DS1672 RTC.
+endef
+
+$(eval $(call KernelPackage,rtc-ds1672))
+
+
+define KernelPackage/rtc-isl1208
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Intersil ISL1208 RTC support
+ DEPENDS:=@RTC_SUPPORT +kmod-i2c-core
+ KCONFIG:=CONFIG_RTC_DRV_ISL1208
+ FILES:=$(LINUX_DIR)/drivers/rtc/rtc-isl1208.ko
+ AUTOLOAD:=$(call AutoProbe,rtc-isl1208)
+endef
+
+define KernelPackage/rtc-isl1208/description
+ Kernel module for Intersil ISL1208 RTC.
+endef
+
+$(eval $(call KernelPackage,rtc-isl1208))
+
+
+define KernelPackage/rtc-marvell
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Marvell SoC built-in RTC support
+ DEPENDS:=@RTC_SUPPORT @TARGET_kirkwood||TARGET_orion||TARGET_mvebu
+ KCONFIG:=CONFIG_RTC_DRV_MV
+ FILES:=$(LINUX_DIR)/drivers/rtc/rtc-mv.ko
+ AUTOLOAD:=$(call AutoProbe,rtc-mv)
+endef
+
+define KernelPackage/rtc-marvell/description
+ Kernel module for Marvell SoC built-in RTC.
+endef
+
+$(eval $(call KernelPackage,rtc-marvell))
+
+
+define KernelPackage/rtc-armada38x
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Marvell Armada 38x SoC built-in RTC support
+ DEPENDS:=@RTC_SUPPORT @TARGET_mvebu
+ KCONFIG:=CONFIG_RTC_DRV_ARMADA38X
+ FILES:=$(LINUX_DIR)/drivers/rtc/rtc-armada38x.ko
+ AUTOLOAD:=$(call AutoProbe,rtc-armada38x)
+endef
+
+define KernelPackage/rtc-armada38x/description
+ Kernel module for Marvell Armada 38x SoC built-in RTC.
+endef
+
+$(eval $(call KernelPackage,rtc-armada38x))
+
+
+define KernelPackage/rtc-pcf8563
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Philips PCF8563/Epson RTC8564 RTC support
+ DEPENDS:=@RTC_SUPPORT +kmod-i2c-core
+ KCONFIG:=CONFIG_RTC_DRV_PCF8563
+ FILES:=$(LINUX_DIR)/drivers/rtc/rtc-pcf8563.ko
+ AUTOLOAD:=$(call AutoProbe,rtc-pcf8563)
+endef
+
+define KernelPackage/rtc-pcf8563/description
+ Kernel module for Philips PCF8563 RTC chip.
+ The Epson RTC8564 should work as well.
+endef
+
+$(eval $(call KernelPackage,rtc-pcf8563))
+
+
+define KernelPackage/rtc-pcf2123
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Philips PCF2123 RTC support
+ DEPENDS:=@RTC_SUPPORT
+ KCONFIG:=CONFIG_RTC_DRV_PCF2123
+ FILES:=$(LINUX_DIR)/drivers/rtc/rtc-pcf2123.ko
+ AUTOLOAD:=$(call AutoProbe,rtc-pcf2123)
+endef
+
+define KernelPackage/rtc-pcf2123/description
+ Kernel module for Philips PCF2123 RTC chip
+endef
+
+$(eval $(call KernelPackage,rtc-pcf2123))
+
+define KernelPackage/rtc-pt7c4338
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Pericom PT7C4338 RTC support
+ DEPENDS:=@RTC_SUPPORT +kmod-i2c-core
+ KCONFIG:=CONFIG_RTC_DRV_PT7C4338
+ FILES:=$(LINUX_DIR)/drivers/rtc/rtc-pt7c4338.ko
+ AUTOLOAD:=$(call AutoProbe,rtc-pt7c4338)
+endef
+
+define KernelPackage/rtc-pt7c4338/description
+ Kernel module for Pericom PT7C4338 i2c RTC chip
+endef
+
+$(eval $(call KernelPackage,rtc-pt7c4338))
+
+
+define KernelPackage/mtdtests
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=MTD subsystem tests
+ KCONFIG:=CONFIG_MTD_TESTS
+ FILES:=\
+ $(LINUX_DIR)/drivers/mtd/tests/mtd_nandecctest.ko \
+ $(LINUX_DIR)/drivers/mtd/tests/mtd_oobtest.ko \
+ $(LINUX_DIR)/drivers/mtd/tests/mtd_pagetest.ko \
+ $(LINUX_DIR)/drivers/mtd/tests/mtd_readtest.ko \
+ $(LINUX_DIR)/drivers/mtd/tests/mtd_speedtest.ko \
+ $(LINUX_DIR)/drivers/mtd/tests/mtd_stresstest.ko \
+ $(LINUX_DIR)/drivers/mtd/tests/mtd_subpagetest.ko \
+ $(LINUX_DIR)/drivers/mtd/tests/mtd_torturetest.ko
+endef
+
+define KernelPackage/mtdtests/description
+ Kernel modules for MTD subsystem/driver testing
+endef
+
+$(eval $(call KernelPackage,mtdtests))
+
+
+define KernelPackage/serial-8250
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=8250 UARTs
+ KCONFIG:= CONFIG_SERIAL_8250 \
+ CONFIG_SERIAL_8250_NR_UARTS=16 \
+ CONFIG_SERIAL_8250_RUNTIME_UARTS=16 \
+ CONFIG_SERIAL_8250_EXTENDED=y \
+ CONFIG_SERIAL_8250_MANY_PORTS=y \
+ CONFIG_SERIAL_8250_SHARE_IRQ=y \
+ CONFIG_SERIAL_8250_DETECT_IRQ=n \
+ CONFIG_SERIAL_8250_RSA=n
+ FILES:=$(LINUX_DIR)/drivers/tty/serial/8250/8250.ko
+endef
+
+define KernelPackage/serial-8250/description
+ Kernel module for 8250 UART based serial ports
+endef
+
+$(eval $(call KernelPackage,serial-8250))
+
+
+define KernelPackage/regmap
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Generic register map support
+ DEPENDS:=+kmod-lib-lzo +kmod-i2c-core
+ KCONFIG:=CONFIG_REGMAP \
+ CONFIG_REGMAP_MMIO \
+ CONFIG_REGMAP_SPI \
+ CONFIG_REGMAP_I2C \
+ CONFIG_SPI=y
+ FILES:= \
+ $(LINUX_DIR)/drivers/base/regmap/regmap-core.ko \
+ $(LINUX_DIR)/drivers/base/regmap/regmap-i2c.ko \
+ $(LINUX_DIR)/drivers/base/regmap/regmap-mmio.ko \
+ $(if $(CONFIG_SPI),$(LINUX_DIR)/drivers/base/regmap/regmap-spi.ko)
+ AUTOLOAD:=$(call AutoLoad,21,regmap-core regmap-i2c regmap-mmio regmap-spi)
+endef
+
+define KernelPackage/regmap/description
+ Generic register map support
+endef
+
+$(eval $(call KernelPackage,regmap))
+
+define KernelPackage/ikconfig
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Kernel configuration via /proc/config.gz
+ KCONFIG:=CONFIG_IKCONFIG \
+ CONFIG_IKCONFIG_PROC=y
+ FILES:=$(LINUX_DIR)/kernel/configs.ko
+ AUTOLOAD:=$(call AutoLoad,70,configs)
+endef
+
+define KernelPackage/ikconfig/description
+ Kernel configuration via /proc/config.gz
+endef
+
+$(eval $(call KernelPackage,ikconfig))
+
+
+define KernelPackage/zram
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=ZRAM
+ DEPENDS:=+kmod-lib-lzo +kmod-lib-lz4
+ KCONFIG:= \
+ CONFIG_ZSMALLOC \
+ CONFIG_ZRAM \
+ CONFIG_ZRAM_DEBUG=n \
+ CONFIG_PGTABLE_MAPPING=n \
+ CONFIG_ZSMALLOC_STAT=n \
+ CONFIG_ZRAM_LZ4_COMPRESS=y
+ FILES:= \
+ $(LINUX_DIR)/mm/zsmalloc.ko \
+ $(LINUX_DIR)/drivers/block/zram/zram.ko
+ AUTOLOAD:=$(call AutoLoad,20,zsmalloc zram)
+endef
+
+define KernelPackage/zram/description
+ Compressed RAM block device support
+endef
+
+$(eval $(call KernelPackage,zram))
+
+
+define KernelPackage/mvsdio
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Marvell SDIO support
+ DEPENDS:=@TARGET_orion||TARGET_kirkwood||TARGET_mvebu +kmod-mmc
+ KCONFIG:=CONFIG_MMC_MVSDIO
+ FILES:=$(LINUX_DIR)/drivers/mmc/host/mvsdio.ko
+ AUTOLOAD:=$(call AutoProbe,mvsdio)
+endef
+
+define KernelPackage/mvsdio/description
+ Kernel support for the Marvell SDIO controller
+endef
+
+$(eval $(call KernelPackage,mvsdio))
+
+
+define KernelPackage/pps
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=PPS support
+ KCONFIG:=CONFIG_PPS
+ FILES:=$(LINUX_DIR)/drivers/pps/pps_core.ko
+ AUTOLOAD:=$(call AutoLoad,17,pps_core,1)
+endef
+
+define KernelPackage/pps/description
+ PPS (Pulse Per Second) is a special pulse provided by some GPS
+ antennae. Userland can use it to get a high-precision time
+ reference.
+endef
+
+$(eval $(call KernelPackage,pps))
+
+
+define KernelPackage/pps-gpio
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=PPS client using GPIO
+ DEPENDS:=+kmod-pps
+ KCONFIG:=CONFIG_PPS_CLIENT_GPIO
+ FILES:=$(LINUX_DIR)/drivers/pps/clients/pps-gpio.ko
+ AUTOLOAD:=$(call AutoLoad,18,pps-gpio,1)
+endef
+
+define KernelPackage/pps-gpio/description
+ Support for a PPS source using GPIO. To be useful you must
+ also register a platform device specifying the GPIO pin and
+ other options, usually in your board setup.
+endef
+
+$(eval $(call KernelPackage,pps-gpio))
+
+
+define KernelPackage/ptp
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=PTP clock support
+ DEPENDS:=+kmod-pps
+ KCONFIG:=CONFIG_PTP_1588_CLOCK
+ FILES:=$(LINUX_DIR)/drivers/ptp/ptp.ko
+ AUTOLOAD:=$(call AutoLoad,18,ptp,1)
+endef
+
+define KernelPackage/ptp/description
+ The IEEE 1588 standard defines a method to precisely
+ synchronize distributed clocks over Ethernet networks.
+endef
+
+$(eval $(call KernelPackage,ptp))
+
+
+define KernelPackage/ptp-gianfar
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Freescale Gianfar PTP support
+ DEPENDS:=@TARGET_mpc85xx +kmod-gianfar +kmod-ptp
+ KCONFIG:=CONFIG_PTP_1588_CLOCK_GIANFAR
+ FILES:=$(LINUX_DIR)/drivers/net/ethernet/freescale/gianfar_ptp.ko
+ AUTOLOAD:=$(call AutoProbe,gianfar_ptp)
+endef
+
+define KernelPackage/ptp-gianfar/description
+ Kernel module for IEEE 1588 support for Freescale
+ Gianfar Ethernet drivers
+endef
+
+$(eval $(call KernelPackage,ptp-gianfar))
+
+
+define KernelPackage/random-core
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Hardware Random Number Generator Core support
+ KCONFIG:=CONFIG_HW_RANDOM
+ FILES:=$(LINUX_DIR)/drivers/char/hw_random/rng-core.ko
+endef
+
+define KernelPackage/random-core/description
+ Kernel module for the HW random number generator core infrastructure
+endef
+
+$(eval $(call KernelPackage,random-core))
+
+
+define KernelPackage/thermal
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Generic Thermal sysfs driver
+ DEPENDS:=+kmod-hwmon-core
+ HIDDEN:=1
+ KCONFIG:= \
+ CONFIG_THERMAL \
+ CONFIG_THERMAL_OF=y \
+ CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y \
+ CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE=n \
+ CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE=n \
+ CONFIG_THERMAL_GOV_FAIR_SHARE=n \
+ CONFIG_THERMAL_GOV_STEP_WISE=y \
+ CONFIG_THERMAL_GOV_USER_SPACE=n \
+ CONFIG_THERMAL_HWMON=y \
+ CONFIG_THERMAL_EMULATION=n
+ FILES:=$(LINUX_DIR)/drivers/thermal/thermal_sys.ko
+ AUTOLOAD:=$(call AutoProbe,thermal_sys)
+endef
+
+define KernelPackage/thermal/description
+ Generic Thermal Sysfs driver offers a generic mechanism for thermal
+ management. Usually it's made up of one or more thermal zone and cooling
+ device.
+endef
+
+$(eval $(call KernelPackage,thermal))
+
+
+define KernelPackage/thermal-armada
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Armada 370/XP thermal management
+ DEPENDS:=@TARGET_mvebu +kmod-thermal
+ KCONFIG:=CONFIG_ARMADA_THERMAL
+ FILES:=$(LINUX_DIR)/drivers/thermal/armada_thermal.ko
+ AUTOLOAD:=$(call AutoProbe,armada_thermal)
+endef
+
+define KernelPackage/thermal-armada/description
+ Enable this module if you want to have support for thermal management
+ controller present in Armada 370 and Armada XP SoC.
+endef
+
+$(eval $(call KernelPackage,thermal-armada))
+
+
+define KernelPackage/thermal-imx
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Temperature sensor driver for Freescale i.MX SoCs
+ DEPENDS:=@TARGET_imx6 +kmod-thermal
+ KCONFIG:= \
+ CONFIG_CPU_THERMAL=y \
+ CONFIG_IMX_THERMAL
+ FILES:=$(LINUX_DIR)/drivers/thermal/imx_thermal.ko
+ AUTOLOAD:=$(call AutoProbe,imx_thermal)
+endef
+
+define KernelPackage/thermal-imx/description
+ Support for Temperature Monitor (TEMPMON) found on Freescale i.MX SoCs.
+ It supports one critical trip point and one passive trip point. The
+ cpufreq is used as the cooling device to throttle CPUs when the
+ passive trip is crossed.
+endef
+
+$(eval $(call KernelPackage,thermal-imx))
+
+
+define KernelPackage/thermal-kirkwood
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Temperature sensor on Marvell Kirkwood SoCs
+ DEPENDS:=@TARGET_kirkwood +kmod-thermal
+ KCONFIG:=CONFIG_KIRKWOOD_THERMAL
+ FILES:=$(LINUX_DIR)/drivers/thermal/kirkwood_thermal.ko
+ AUTOLOAD:=$(call AutoProbe,kirkwood_thermal)
+endef
+
+define KernelPackage/thermal-kirkwood/description
+ Support for the Kirkwood thermal sensor driver into the Linux thermal
+ framework. Only kirkwood 88F6282 and 88F6283 have this sensor.
+endef
+
+$(eval $(call KernelPackage,thermal-kirkwood))
+
+
+define KernelPackage/gpio-beeper
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=GPIO beeper support
+ DEPENDS:=+kmod-input-core
+ KCONFIG:= \
+ CONFIG_INPUT_MISC=y \
+ CONFIG_INPUT_GPIO_BEEPER
+ FILES:= \
+ $(LINUX_DIR)/drivers/input/misc/gpio-beeper.ko
+ AUTOLOAD:=$(call AutoLoad,50,gpio-beeper)
+endef
+
+define KernelPackage/gpio-beeper/description
+ This enables playing beeps through an GPIO-connected buzzer
+endef
+
+$(eval $(call KernelPackage,gpio-beeper))
+
+
+define KernelPackage/echo
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Line Echo Canceller
+ KCONFIG:=CONFIG_ECHO
+ FILES:=$(LINUX_DIR)/drivers/misc/echo/echo.ko
+ AUTOLOAD:=$(call AutoLoad,50,echo)
+endef
+
+define KernelPackage/echo/description
+ This driver provides line echo cancelling support for mISDN and
+ DAHDI drivers
+endef
+
+$(eval $(call KernelPackage,echo))
diff --git a/package/kernel/linux/modules/pcmcia.mk b/package/kernel/linux/modules/pcmcia.mk
new file mode 100644
index 0000000..51668fa
--- /dev/null
+++ b/package/kernel/linux/modules/pcmcia.mk
@@ -0,0 +1,74 @@
+#
+# Copyright (C) 2006-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+PCMCIA_MENU:=PCMCIA support
+
+define KernelPackage/pcmcia-core
+ SUBMENU:=$(PCMCIA_MENU)
+ TITLE:=PCMCIA/CardBus support
+ DEPENDS:=@PCMCIA_SUPPORT
+ KCONFIG:= \
+ CONFIG_PCMCIA \
+ CONFIG_CARDBUS \
+ CONFIG_PCCARD \
+ PCMCIA_DEBUG=n
+ FILES:= \
+ $(LINUX_DIR)/drivers/pcmcia/pcmcia_core.ko \
+ $(LINUX_DIR)/drivers/pcmcia/pcmcia.ko
+ AUTOLOAD:=$(call AutoLoad,25,pcmcia_core pcmcia)
+endef
+
+define KernelPackage/pcmcia-core/description
+ Kernel support for PCMCIA/CardBus controllers
+endef
+
+$(eval $(call KernelPackage,pcmcia-core))
+
+define KernelPackage/pcmcia-rsrc
+ SUBMENU:=$(PCMCIA_MENU)
+ TITLE:=PCMCIA resource support
+ DEPENDS:=kmod-pcmcia-core
+ KCONFIG:=CONFIG_PCCARD_NONSTATIC=y
+ FILES:=$(LINUX_DIR)/drivers/pcmcia/pcmcia_rsrc.ko
+ AUTOLOAD:=$(call AutoLoad,26,pcmcia_rsrc)
+endef
+
+define KernelPackage/pcmcia-rsrc/description
+ Kernel support for PCMCIA resource allocation
+endef
+
+$(eval $(call KernelPackage,pcmcia-rsrc))
+
+
+define KernelPackage/pcmcia-yenta
+ SUBMENU:=$(PCMCIA_MENU)
+ TITLE:=yenta socket driver
+ DEPENDS:=kmod-pcmcia-rsrc
+ KCONFIG:=CONFIG_YENTA
+ FILES:=$(LINUX_DIR)/drivers/pcmcia/yenta_socket.ko
+ AUTOLOAD:=$(call AutoLoad,41,pcmcia_rsrc yenta_socket)
+endef
+
+$(eval $(call KernelPackage,pcmcia-yenta))
+
+
+define KernelPackage/pcmcia-serial
+ SUBMENU:=$(PCMCIA_MENU)
+ TITLE:=Serial devices support
+ DEPENDS:=kmod-pcmcia-core +kmod-serial-8250
+ KCONFIG:= \
+ CONFIG_PCMCIA_SERIAL_CS \
+ CONFIG_SERIAL_8250_CS
+ FILES:=$(LINUX_DIR)/drivers/tty/serial/8250/serial_cs.ko
+ AUTOLOAD:=$(call AutoLoad,45,serial_cs)
+endef
+
+define KernelPackage/pcmcia-serial/description
+ Kernel support for PCMCIA/CardBus serial devices
+endef
+
+$(eval $(call KernelPackage,pcmcia-serial))
diff --git a/package/kernel/linux/modules/sound.mk b/package/kernel/linux/modules/sound.mk
new file mode 100644
index 0000000..603bb70
--- /dev/null
+++ b/package/kernel/linux/modules/sound.mk
@@ -0,0 +1,275 @@
+#
+# Copyright (C) 2006-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+SOUND_MENU:=Sound Support
+
+# allow targets to override the soundcore stuff
+SOUNDCORE_LOAD ?= \
+ soundcore \
+ snd \
+ snd-hwdep \
+ snd-seq-device \
+ snd-rawmidi \
+ snd-timer \
+ snd-pcm \
+ snd-mixer-oss \
+ snd-pcm-oss \
+ snd-compress
+
+SOUNDCORE_FILES ?= \
+ $(LINUX_DIR)/sound/soundcore.ko \
+ $(LINUX_DIR)/sound/core/snd.ko \
+ $(LINUX_DIR)/sound/core/snd-hwdep.ko \
+ $(LINUX_DIR)/sound/core/seq/snd-seq-device.ko \
+ $(LINUX_DIR)/sound/core/snd-rawmidi.ko \
+ $(LINUX_DIR)/sound/core/snd-timer.ko \
+ $(LINUX_DIR)/sound/core/snd-pcm.ko \
+ $(LINUX_DIR)/sound/core/oss/snd-mixer-oss.ko \
+ $(LINUX_DIR)/sound/core/oss/snd-pcm-oss.ko \
+ $(LINUX_DIR)/sound/core/snd-compress.ko
+
+SOUNDCORE_LOAD += \
+ $(if $(CONFIG_SND_DMAENGINE_PCM),snd-pcm-dmaengine)
+
+SOUNDCORE_FILES += \
+ $(if $(CONFIG_SND_DMAENGINE_PCM),$(LINUX_DIR)/sound/core/snd-pcm-dmaengine.ko)
+
+define KernelPackage/sound-core
+ SUBMENU:=$(SOUND_MENU)
+ TITLE:=Sound support
+ DEPENDS:=@AUDIO_SUPPORT +kmod-input-core
+ KCONFIG:= \
+ CONFIG_SOUND \
+ CONFIG_SND \
+ CONFIG_SND_HWDEP \
+ CONFIG_SND_RAWMIDI \
+ CONFIG_SND_TIMER \
+ CONFIG_SND_PCM \
+ CONFIG_SND_SEQUENCER \
+ CONFIG_SND_VIRMIDI \
+ CONFIG_SND_SEQ_DUMMY \
+ CONFIG_SND_SEQUENCER_OSS=y \
+ CONFIG_HOSTAUDIO \
+ CONFIG_SND_PCM_OSS \
+ CONFIG_SND_MIXER_OSS \
+ CONFIG_SOUND_OSS_CORE_PRECLAIM=y \
+ CONFIG_SND_COMPRESS_OFFLOAD
+ FILES:=$(SOUNDCORE_FILES)
+ AUTOLOAD:=$(call AutoLoad,30,$(SOUNDCORE_LOAD))
+endef
+
+define KernelPackage/sound-core/uml
+ FILES:= \
+ $(LINUX_DIR)/sound/soundcore.ko \
+ $(LINUX_DIR)/arch/um/drivers/hostaudio.ko
+ AUTOLOAD:=$(call AutoLoad,30,soundcore hostaudio)
+endef
+
+define KernelPackage/sound-core/description
+ Kernel modules for sound support
+endef
+
+$(eval $(call KernelPackage,sound-core))
+
+
+define AddDepends/sound
+ SUBMENU:=$(SOUND_MENU)
+ DEPENDS+=kmod-sound-core $(1) @!TARGET_uml
+endef
+
+
+define KernelPackage/ac97
+ TITLE:=ac97 controller
+ KCONFIG:=CONFIG_SND_AC97_CODEC
+ FILES:= \
+ $(LINUX_DIR)/sound/ac97_bus.ko \
+ $(LINUX_DIR)/sound/pci/ac97/snd-ac97-codec.ko
+ AUTOLOAD:=$(call AutoLoad,35,ac97_bus snd-ac97-codec)
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/ac97/description
+ The ac97 controller
+endef
+
+$(eval $(call KernelPackage,ac97))
+
+
+define KernelPackage/sound-mpu401
+ TITLE:=MPU-401 uart driver
+ KCONFIG:=CONFIG_SND_MPU401_UART
+ FILES:= \
+ $(LINUX_DIR)/sound/drivers/mpu401/snd-mpu401-uart.ko
+ AUTOLOAD:=$(call AutoLoad,35,snd-mpu401-uart)
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-mpu401/description
+ support for MIDI ports compatible with the Roland MPU-401
+ interface in UART mode.
+endef
+
+$(eval $(call KernelPackage,sound-mpu401))
+
+
+define KernelPackage/sound-seq
+ TITLE:=Sequencer support
+ FILES:= \
+ $(LINUX_DIR)/sound/core/seq/snd-seq.ko \
+ $(LINUX_DIR)/sound/core/seq/snd-seq-midi-event.ko \
+ $(LINUX_DIR)/sound/core/seq/snd-seq-midi.ko
+ AUTOLOAD:=$(call AutoLoad,35,snd-seq snd-seq-midi-event snd-seq-midi)
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-seq/description
+ Kernel modules for sequencer support
+endef
+
+$(eval $(call KernelPackage,sound-seq))
+
+
+define KernelPackage/sound-i8x0
+ TITLE:=Intel/SiS/nVidia/AMD/ALi AC97 Controller
+ DEPENDS:=+kmod-ac97
+ KCONFIG:=CONFIG_SND_INTEL8X0
+ FILES:=$(LINUX_DIR)/sound/pci/snd-intel8x0.ko
+ AUTOLOAD:=$(call AutoLoad,36,snd-intel8x0)
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-i8x0/description
+ support for the integrated AC97 sound device on motherboards
+ with Intel/SiS/nVidia/AMD chipsets, or ALi chipsets using
+ the M5455 Audio Controller.
+endef
+
+$(eval $(call KernelPackage,sound-i8x0))
+
+
+define KernelPackage/sound-via82xx
+ TITLE:=VIA 82xx AC97 Controller
+ DEPENDS:=+kmod-ac97 +kmod-sound-mpu401
+ KCONFIG:=CONFIG_SND_VIA82XX
+ FILES:=$(LINUX_DIR)/sound/pci/snd-via82xx.ko
+ AUTOLOAD:=$(call AutoLoad,36,snd-via82xx)
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-via82xx/description
+ support for the integrated AC97 sound device on motherboards
+ with VIA chipsets.
+endef
+
+$(eval $(call KernelPackage,sound-via82xx))
+
+
+define KernelPackage/sound-soc-core
+ TITLE:=SoC sound support
+ DEPENDS:=+kmod-regmap +kmod-ac97
+ KCONFIG:= \
+ CONFIG_SND_SOC \
+ CONFIG_SND_SOC_DMAENGINE_PCM=y \
+ CONFIG_SND_SOC_ALL_CODECS=n
+ FILES:=$(LINUX_DIR)/sound/soc/snd-soc-core.ko
+ AUTOLOAD:=$(call AutoLoad,55, snd-soc-core)
+ $(call AddDepends/sound)
+endef
+
+$(eval $(call KernelPackage,sound-soc-core))
+
+
+define KernelPackage/sound-soc-ac97
+ TITLE:=AC97 Codec support
+ KCONFIG:=CONFIG_SND_SOC_AC97_CODEC
+ FILES:=$(LINUX_DIR)/sound/soc/codecs/snd-soc-ac97.ko
+ AUTOLOAD:=$(call AutoLoad,57,snd-soc-ac97)
+ DEPENDS:=+kmod-ac97 +kmod-sound-soc-core
+ $(call AddDepends/sound)
+endef
+
+$(eval $(call KernelPackage,sound-soc-ac97))
+
+
+define KernelPackage/sound-soc-imx
+ TITLE:=IMX SoC support
+ KCONFIG:=\
+ CONFIG_SND_IMX_SOC \
+ CONFIG_SND_SOC_IMX_AUDMUX \
+ CONFIG_SND_SOC_FSL_SSI \
+ CONFIG_SND_SOC_IMX_PCM_DMA
+ FILES:= \
+ $(LINUX_DIR)/sound/soc/fsl/snd-soc-imx-audmux.ko \
+ $(LINUX_DIR)/sound/soc/fsl/snd-soc-fsl-ssi.ko \
+ $(LINUX_DIR)/sound/soc/fsl/imx-pcm-dma.ko
+ AUTOLOAD:=$(call AutoLoad,56,snd-soc-imx-audmux snd-soc-fsl-ssi snd-soc-imx-pcm)
+ DEPENDS:=@TARGET_imx6 +kmod-sound-soc-core
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-soc-imx/description
+ Support for i.MX6 Platform sound (ssi/audmux/pcm)
+endef
+
+$(eval $(call KernelPackage,sound-soc-imx))
+
+
+define KernelPackage/sound-soc-imx-sgtl5000
+ TITLE:=IMX SoC support for SGTL5000
+ KCONFIG:=CONFIG_SND_SOC_IMX_SGTL5000
+ FILES:=\
+ $(LINUX_DIR)/sound/soc/codecs/snd-soc-sgtl5000.ko \
+ $(LINUX_DIR)/sound/soc/fsl/snd-soc-imx-sgtl5000.ko
+ AUTOLOAD:=$(call AutoLoad,57,snd-soc-sgtl5000 snd-soc-imx-sgtl5000)
+ DEPENDS:=@TARGET_imx6 +kmod-sound-soc-imx
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-soc-imx-sgtl5000/description
+ Support for i.MX6 Platform sound SGTL5000 codec
+endef
+
+$(eval $(call KernelPackage,sound-soc-imx-sgtl5000))
+
+
+define KernelPackage/sound-soc-gw_avila
+ TITLE:=Gateworks Avila SoC sound support
+ KCONFIG:= \
+ CONFIG_SND_GW_AVILA_SOC \
+ CONFIG_SND_GW_AVILA_SOC_PCM \
+ CONFIG_SND_GW_AVILA_SOC_HSS
+ FILES:= \
+ $(LINUX_DIR)/sound/soc/codecs/snd-soc-tlv320aic3x.ko \
+ $(LINUX_DIR)/sound/soc/gw-avila/snd-soc-gw-avila.ko \
+ $(LINUX_DIR)/sound/soc/gw-avila/snd-soc-gw-avila-pcm.ko \
+ $(LINUX_DIR)/sound/soc/gw-avila/snd-soc-gw-avila-hss.ko
+ AUTOLOAD:=$(call AutoLoad,65,snd-soc-tlv320aic3x snd-soc-gw-avila snd-soc-gw-avila-pcm snd-soc-gw-avila-hss)
+ DEPENDS:=@TARGET_ixp4xx +kmod-sound-soc-core
+ $(call AddDepends/sound)
+endef
+
+$(eval $(call KernelPackage,sound-soc-gw_avila))
+
+
+define KernelPackage/pcspkr
+ DEPENDS:=@TARGET_x86 +kmod-input-core
+ TITLE:=PC speaker support
+ KCONFIG:= \
+ CONFIG_INPUT_PCSPKR \
+ CONFIG_SND_PCSP
+ FILES:= \
+ $(LINUX_DIR)/drivers/input/misc/pcspkr.ko \
+ $(LINUX_DIR)/sound/drivers/pcsp/snd-pcsp.ko
+ AUTOLOAD:=$(call AutoLoad,50,pcspkr snd-pcsp)
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/pcspkr/description
+ This enables sounds (tones) through the pc speaker
+endef
+
+$(eval $(call KernelPackage,pcspkr))
diff --git a/package/kernel/linux/modules/spi.mk b/package/kernel/linux/modules/spi.mk
new file mode 100644
index 0000000..1c2a789
--- /dev/null
+++ b/package/kernel/linux/modules/spi.mk
@@ -0,0 +1,91 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+SPI_MENU:=SPI Support
+
+define KernelPackage/mmc-spi
+ SUBMENU:=$(SPI_MENU)
+ TITLE:=MMC/SD over SPI Support
+ DEPENDS:=+kmod-mmc +kmod-lib-crc-itu-t +kmod-lib-crc7
+ KCONFIG:=CONFIG_MMC_SPI \
+ CONFIG_SPI=y \
+ CONFIG_SPI_MASTER=y
+ FILES:=\
+ $(if $(CONFIG_OF),$(LINUX_DIR)/drivers/mmc/host/of_mmc_spi.ko) \
+ $(LINUX_DIR)/drivers/mmc/host/mmc_spi.ko
+ AUTOLOAD:=$(call AutoProbe,$(if $(CONFIG_OF),of_mmc_spi) mmc_spi)
+endef
+
+define KernelPackage/mmc-spi/description
+ Kernel support for MMC/SD over SPI
+endef
+
+$(eval $(call KernelPackage,mmc-spi))
+
+
+define KernelPackage/spi-bitbang
+ SUBMENU:=$(SPI_MENU)
+ TITLE:=Serial Peripheral Interface bitbanging library
+ KCONFIG:=CONFIG_SPI_BITBANG \
+ CONFIG_SPI=y \
+ CONFIG_SPI_MASTER=y
+ FILES:=$(LINUX_DIR)/drivers/spi/spi-bitbang.ko
+endef
+
+define KernelPackage/spi-bitbang/description
+ This package contains the SPI bitbanging library
+endef
+
+$(eval $(call KernelPackage,spi-bitbang))
+
+
+define KernelPackage/spi-gpio-old
+ SUBMENU:=$(SPI_MENU)
+ TITLE:=Old GPIO based bitbanging SPI controller (DEPRECATED)
+ DEPENDS:=@GPIO_SUPPORT +kmod-spi-bitbang
+ KCONFIG:=CONFIG_SPI_GPIO_OLD
+ FILES:=$(LINUX_DIR)/drivers/spi/spi_gpio_old.ko
+ AUTOLOAD:=$(call AutoProbe,spi_gpio_old)
+endef
+
+define KernelPackage/spi-gpio-old/description
+ This package contains the GPIO based bitbanging SPI controller driver
+endef
+
+$(eval $(call KernelPackage,spi-gpio-old))
+
+
+define KernelPackage/spi-gpio
+ SUBMENU:=$(SPI_MENU)
+ TITLE:=GPIO-based bitbanging SPI Master
+ DEPENDS:=@GPIO_SUPPORT +kmod-spi-bitbang
+ KCONFIG:=CONFIG_SPI_GPIO
+ FILES:=$(LINUX_DIR)/drivers/spi/spi-gpio.ko
+ AUTOLOAD:=$(call AutoProbe,spi-gpio)
+endef
+
+define KernelPackage/spi-gpio/description
+ This package contains the GPIO-based bitbanging SPI Master
+endef
+
+$(eval $(call KernelPackage,spi-gpio))
+
+define KernelPackage/spi-dev
+ SUBMENU:=$(SPI_MENU)
+ TITLE:=User mode SPI device driver
+ KCONFIG:=CONFIG_SPI_SPIDEV \
+ CONFIG_SPI=y \
+ CONFIG_SPI_MASTER=y
+ FILES:=$(LINUX_DIR)/drivers/spi/spidev.ko
+ AUTOLOAD:=$(call AutoProbe,spidev)
+endef
+
+define KernelPackage/spi-dev/description
+ This package contains the user mode SPI device driver
+endef
+
+$(eval $(call KernelPackage,spi-dev))
diff --git a/package/kernel/linux/modules/usb.mk b/package/kernel/linux/modules/usb.mk
new file mode 100644
index 0000000..487a17d
--- /dev/null
+++ b/package/kernel/linux/modules/usb.mk
@@ -0,0 +1,1604 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+USB_MENU:=USB Support
+
+USBNET_DIR:=net/usb
+USBHID_DIR?=hid/usbhid
+USBINPUT_DIR?=input/misc
+
+define KernelPackage/usb-core
+ SUBMENU:=$(USB_MENU)
+ TITLE:=Support for USB
+ DEPENDS:=@USB_SUPPORT
+ KCONFIG:=CONFIG_USB CONFIG_XPS_USB_HCD_XILINX=n CONFIG_USB_FHCI_HCD=n
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/core/usbcore.ko \
+ $(LINUX_DIR)/drivers/usb/common/usb-common.ko
+ AUTOLOAD:=$(call AutoLoad,20,usb-common usbcore,1)
+ $(call AddDepends/nls)
+endef
+
+define KernelPackage/usb-core/description
+ Kernel support for USB
+endef
+
+$(eval $(call KernelPackage,usb-core))
+
+
+define AddDepends/usb
+ SUBMENU:=$(USB_MENU)
+ DEPENDS+=+kmod-usb-core $(1)
+endef
+
+
+define KernelPackage/usb-musb-hdrc
+ TITLE:=Support for Mentor Graphics silicon dual role USB
+ KCONFIG:= \
+ CONFIG_USB_MUSB_HDRC \
+ CONFIG_USB_INVENTRA_DMA=n \
+ CONFIG_USB_TI_CPPI41_DMA=n \
+ CONFIG_MUSB_PIO_ONLY=y \
+ CONFIG_USB_MUSB_DUAL_ROLE=y \
+ CONFIG_USB_MUSB_GADGET=n \
+ CONFIG_USB_MUSB_HOST=n \
+ CONFIG_USB_MUSB_DEBUG=y
+ DEPENDS:= \
+ @(TARGET_omap||TARGET_omap24xx) +kmod-usb-gadget \
+ +TARGET_omap24xx:kmod-usb-musb-tusb6010
+ FILES:=$(LINUX_DIR)/drivers/usb/musb/musb_hdrc.ko
+ AUTOLOAD:=$(call AutoLoad,46,musb_hdrc)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-musb-hdrc/description
+ Kernel support for Mentor Graphics silicon dual role USB device.
+endef
+
+$(eval $(call KernelPackage,usb-musb-hdrc))
+
+
+define KernelPackage/usb-musb-platformglue
+ TITLE:=MUSB platform glue layer
+ KCONFIG:= \
+ CONFIG_USB_MUSB_TUSB6010=n \
+ CONFIG_USB_MUSB_OMAP2PLUS=n \
+ CONFIG_USB_MUSB_AM35X=n \
+ CONFIG_USB_MUSB_DSPS \
+ CONFIG_USB_MUSB_UX500=n
+ DEPENDS:=@TARGET_omap +kmod-usb-phy-nop +kmod-usb-musb-hdrc +kmod-usb-phy-am335x
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/musb/musb_dsps.ko \
+ $(LINUX_DIR)/drivers/usb/musb/musb_am335x.ko
+ AUTOLOAD:=$(call AutoLoad,45,phy-omap-control musb_dsps musb_am335x)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-musb-platformglue/description
+ MUSB platform glue modules
+endef
+
+$(eval $(call KernelPackage,usb-musb-platformglue))
+
+
+define KernelPackage/usb-musb-tusb6010
+ TITLE:=Support for TUSB 6010
+ KCONFIG:=CONFIG_USB_MUSB_TUSB6010
+ DEPENDS:=@TARGET_omap24xx
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-musb-tusb6010/description
+ TUSB6010 support
+endef
+
+$(eval $(call KernelPackage,usb-musb-tusb6010))
+
+
+define KernelPackage/usb-phy-nop
+ TITLE:=Support for USB NOP transceiver
+ KCONFIG:=CONFIG_NOP_USB_XCEIV
+ HIDDEN:=1
+ FILES:=$(LINUX_DIR)/drivers/usb/phy/phy-generic.ko
+ AUTOLOAD:=$(call AutoLoad,43,phy-generic)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-phy-nop/description
+ Support for USB NOP transceiver
+endef
+
+$(eval $(call KernelPackage,usb-phy-nop))
+
+
+define KernelPackage/usb-phy-am335x
+ TITLE:=Support for AM335x USB PHY
+ KCONFIG:= \
+ CONFIG_AM335X_PHY_USB \
+ CONFIG_AM335X_CONTROL_USB
+ DEPENDS:=@TARGET_omap +kmod-usb-phy-nop
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/phy/phy-am335x.ko \
+ $(LINUX_DIR)/drivers/usb/phy/phy-am335x-control.ko
+ AUTOLOAD:=$(call AutoLoad,44,phy-am335x)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-phy-am335x/description
+ Support for AM335x USB PHY
+endef
+
+$(eval $(call KernelPackage,usb-phy-am335x))
+
+
+define KernelPackage/usb-phy-omap-usb2
+ TITLE:=Support for OMAP2 USB PHY
+ KCONFIG:= \
+ CONFIG_OMAP_USB2 \
+ CONFIG_OMAP_CONTROL_PHY
+ DEPENDS:=@TARGET_omap
+ FILES:= \
+ $(LINUX_DIR)/drivers/phy/phy-omap-usb2.ko \
+ $(LINUX_DIR)/drivers/phy/phy-omap-control.ko
+ AUTOLOAD:=$(call AutoLoad,45,phy-omap-control phy-omap-usb2)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-phy-omap-usb2/description
+ Support for AM335x USB PHY
+endef
+
+$(eval $(call KernelPackage,usb-phy-omap-usb2))
+
+
+define KernelPackage/usb-phy-omap-usb3
+ TITLE:=Support for OMAP USB3 PHY
+ KCONFIG:=CONFIG_OMAP_USB3
+ DEPENDS:=@TARGET_omap +kmod-usb-phy-omap-usb2
+ FILES:=$(LINUX_DIR)/drivers/usb/phy/phy-omap-usb3.ko
+ AUTOLOAD:=$(call AutoLoad,45,phy-omap-usb3)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-phy-omap-usb3/description
+ Support for OMAP USB3 PHY
+endef
+
+$(eval $(call KernelPackage,usb-phy-omap-usb3))
+
+
+define KernelPackage/usb-phy-twl4030
+ TITLE:=Support for TWL4030 OTG PHY
+ KCONFIG:=CONFIG_TWL4030_USB
+ DEPENDS:=@TARGET_omap +kmod-usb-phy-omap-usb2 +kmod-usb-musb-hdrc
+ FILES:=$(LINUX_DIR)/drivers/phy/phy-twl4030-usb.ko
+ AUTOLOAD:=$(call AutoLoad,45,phy-twl4030-usb)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-phy-twl4030/description
+ Support for TWL4030/TWL5030/TPS659x0 OTG PHY
+endef
+
+$(eval $(call KernelPackage,usb-phy-twl4030))
+
+
+define KernelPackage/usb-phy-twl6030
+ TITLE:=Support for TWL6030 OTG PHY
+ KCONFIG:=CONFIG_TWL6030_USB
+ DEPENDS:=@TARGET_omap +kmod-usb-phy-omap-usb2 +kmod-usb-musb-hdrc
+ FILES:=$(LINUX_DIR)/drivers/usb/phy/phy-twl6030-usb.ko
+ AUTOLOAD:=$(call AutoLoad,45,phy-twl6030-usb)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-phy-twl6030/description
+ Support for TWL6030 OTG PHY
+endef
+
+$(eval $(call KernelPackage,usb-phy-twl6030))
+
+
+define KernelPackage/usb-gadget
+ TITLE:=USB Gadget support
+ KCONFIG:=CONFIG_USB_GADGET
+ FILES:=\
+ $(LINUX_DIR)/drivers/usb/gadget/udc/udc-core.ko
+ AUTOLOAD:=$(call AutoLoad,45,udc-core)
+ DEPENDS:=@USB_GADGET_SUPPORT
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-gadget/description
+ Kernel support for USB Gadget mode
+endef
+
+$(eval $(call KernelPackage,usb-gadget))
+
+define KernelPackage/usb-lib-composite
+ TITLE:=USB lib composite
+ KCONFIG:=CONFIG_USB_LIBCOMPOSITE
+ DEPENDS:=+kmod-usb-gadget +kmod-fs-configfs
+ FILES:=$(LINUX_DIR)/drivers/usb/gadget/libcomposite.ko
+ AUTOLOAD:=$(call AutoLoad,50,libcomposite)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-lib-composite/description
+ Lib Composite
+endef
+
+$(eval $(call KernelPackage,usb-lib-composite))
+
+
+define KernelPackage/usb-eth-gadget
+ TITLE:=USB Ethernet Gadget support
+ KCONFIG:= \
+ CONFIG_USB_ETH \
+ CONFIG_USB_ETH_RNDIS=y \
+ CONFIG_USB_ETH_EEM=n
+ DEPENDS:=+kmod-usb-gadget +kmod-usb-lib-composite
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/gadget/function/u_ether.ko \
+ $(LINUX_DIR)/drivers/usb/gadget/function/usb_f_ecm.ko \
+ $(LINUX_DIR)/drivers/usb/gadget/function/usb_f_ecm_subset.ko \
+ $(LINUX_DIR)/drivers/usb/gadget/function/usb_f_rndis.ko \
+ $(LINUX_DIR)/drivers/usb/gadget/legacy/g_ether.ko
+ AUTOLOAD:=$(call AutoLoad,52,usb_f_ecm g_ether)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-eth-gadget/description
+ Kernel support for USB Ethernet Gadget
+endef
+
+$(eval $(call KernelPackage,usb-eth-gadget))
+
+
+define KernelPackage/usb-serial-gadget
+ TITLE:=USB Serial Gadget support
+ KCONFIG:=CONFIG_USB_G_SERIAL
+ DEPENDS:=+kmod-usb-gadget +kmod-usb-lib-composite
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/gadget/function/u_serial.ko \
+ $(LINUX_DIR)/drivers/usb/gadget/function/usb_f_acm.ko \
+ $(LINUX_DIR)/drivers/usb/gadget/function/usb_f_obex.ko \
+ $(LINUX_DIR)/drivers/usb/gadget/function/usb_f_serial.ko \
+ $(LINUX_DIR)/drivers/usb/gadget/legacy/g_serial.ko
+ AUTOLOAD:=$(call AutoLoad,52,usb_f_acm g_serial)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-serial-gadget/description
+ Kernel support for USB Serial Gadget.
+endef
+
+$(eval $(call KernelPackage,usb-serial-gadget))
+
+define KernelPackage/usb-mass-storage-gadget
+ TITLE:=USB Mass Storage support
+ KCONFIG:=CONFIG_USB_MASS_STORAGE
+ DEPENDS:=+kmod-usb-gadget +kmod-usb-lib-composite
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/gadget/function/usb_f_mass_storage.ko \
+ $(LINUX_DIR)/drivers/usb/gadget/legacy/g_mass_storage.ko
+ AUTOLOAD:=$(call AutoLoad,52,usb_f_mass_storage g_mass_storage)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-mass-storage-gadget/description
+ Kernel support for USB Gadget Mass Storage
+endef
+
+$(eval $(call KernelPackage,usb-mass-storage-gadget))
+
+
+define KernelPackage/usb-uhci
+ TITLE:=Support for UHCI controllers
+ KCONFIG:= \
+ CONFIG_USB_UHCI_ALT \
+ CONFIG_USB_UHCI_HCD
+ FILES:=$(LINUX_DIR)/drivers/usb/host/uhci-hcd.ko
+ AUTOLOAD:=$(call AutoLoad,50,uhci-hcd,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-uhci/description
+ Kernel support for USB UHCI controllers
+endef
+
+$(eval $(call KernelPackage,usb-uhci,1))
+
+
+define KernelPackage/usb-ohci
+ TITLE:=Support for OHCI controllers
+ DEPENDS:= \
+ +TARGET_bcm53xx:kmod-usb-bcma \
+ +TARGET_brcm47xx:kmod-usb-bcma \
+ +TARGET_brcm47xx:kmod-usb-ssb
+ KCONFIG:= \
+ CONFIG_USB_OHCI \
+ CONFIG_USB_OHCI_HCD \
+ CONFIG_USB_OHCI_ATH79=y \
+ CONFIG_USB_OHCI_HCD_AT91=y \
+ CONFIG_USB_OHCI_BCM63XX=y \
+ CONFIG_USB_OCTEON_OHCI=y \
+ CONFIG_USB_OHCI_HCD_OMAP3=y \
+ CONFIG_USB_OHCI_HCD_PLATFORM=y
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/host/ohci-hcd.ko \
+ $(LINUX_DIR)/drivers/usb/host/ohci-platform.ko
+ ifneq ($(wildcard $(LINUX_DIR)/drivers/usb/host/ohci-at91.ko),)
+ FILES+=$(LINUX_DIR)/drivers/usb/host/ohci-at91.ko
+ endif
+ AUTOLOAD:=$(call AutoLoad,50,ohci-hcd ohci-platform ohci-at91,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-ohci/description
+ Kernel support for USB OHCI controllers
+endef
+
+$(eval $(call KernelPackage,usb-ohci,1))
+
+
+define KernelPackage/usb-ohci-pci
+ TITLE:=Support for PCI OHCI controllers
+ DEPENDS:=@PCI_SUPPORT +kmod-usb-ohci
+ KCONFIG:=CONFIG_USB_OHCI_HCD_PCI
+ FILES:=$(LINUX_DIR)/drivers/usb/host/ohci-pci.ko
+ AUTOLOAD:=$(call AutoLoad,51,ohci-pci,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-ohci-pci/description
+ Kernel support for PCI OHCI controllers
+endef
+
+$(eval $(call KernelPackage,usb-ohci-pci))
+
+
+define KernelPackage/usb2-fsl
+ TITLE:=Support for Freescale USB2 controllers
+ DEPENDS:=@TARGET_mpc85xx
+ KCONFIG:=\
+ CONFIG_USB_FSL_MPH_DR_OF \
+ CONFIG_USB_EHCI_FSL=y
+ FILES:=$(LINUX_DIR)/drivers/usb/host/fsl-mph-dr-of.ko
+ AUTOLOAD:=$(call AutoLoad,39,fsl-mph-dr-of,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb2-fsl/description
+ Kernel support for Freescale USB2 (EHCI) controllers
+endef
+
+$(eval $(call KernelPackage,usb2-fsl))
+
+
+define KernelPackage/usb2-omap
+ TITLE:=Support for USB2 for OMAP
+ DEPENDS:=@TARGET_omap +kmod-usb-phy-nop +kmod-usb-phy-am335x +kmod-usb2
+ KCONFIG:=\
+ CONFIG_MFD_OMAP_USB_HOST=y \
+ CONFIG_USB_EHCI_HCD_OMAP
+ FILES:=$(LINUX_DIR)/drivers/usb/host/ehci-omap.ko
+ AUTOLOAD:=$(call AutoLoad,39,ehci-omap)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb2-omap/description
+ Kernel support for OMAP USB2 (EHCI) controllers
+endef
+
+$(eval $(call KernelPackage,usb2-omap))
+
+define KernelPackage/usb-bcma
+ TITLE:=Support for BCMA USB controllers
+ DEPENDS:=@USB_SUPPORT @TARGET_brcm47xx||TARGET_bcm53xx
+ HIDDEN:=1
+ KCONFIG:=CONFIG_USB_HCD_BCMA
+ FILES:= \
+ $(if $(CONFIG_USB_HCD_BCMA),$(LINUX_DIR)/drivers/usb/host/bcma-hcd.ko)
+ AUTOLOAD:=$(call AutoLoad,19,$(if $(CONFIG_USB_HCD_BCMA),bcma-hcd),1)
+ $(call AddDepends/usb)
+endef
+$(eval $(call KernelPackage,usb-bcma))
+
+define KernelPackage/usb-ssb
+ TITLE:=Support for SSB USB controllers
+ DEPENDS:=@USB_SUPPORT @TARGET_brcm47xx
+ HIDDEN:=1
+ KCONFIG:=CONFIG_USB_HCD_SSB
+ FILES:= \
+ $(if $(CONFIG_USB_HCD_SSB),$(LINUX_DIR)/drivers/usb/host/ssb-hcd.ko)
+ AUTOLOAD:=$(call AutoLoad,19,$(if $(CONFIG_USB_HCD_SSB),ssb-hcd),1)
+ $(call AddDepends/usb)
+endef
+$(eval $(call KernelPackage,usb-ssb))
+
+define KernelPackage/usb2
+ TITLE:=Support for USB2 controllers
+ DEPENDS:=\
+ +TARGET_brcm47xx:kmod-usb-bcma \
+ +TARGET_brcm47xx:kmod-usb-ssb \
+ +TARGET_bcm53xx:kmod-usb-bcma \
+ +TARGET_mpc85xx:kmod-usb2-fsl
+ KCONFIG:=\
+ CONFIG_USB_EHCI_HCD \
+ CONFIG_USB_EHCI_ATH79=y \
+ CONFIG_USB_EHCI_BCM63XX=y \
+ CONFIG_USB_IMX21_HCD=y \
+ CONFIG_USB_EHCI_MXC=y \
+ CONFIG_USB_OCTEON_EHCI=y \
+ CONFIG_USB_EHCI_HCD_ORION=y \
+ CONFIG_USB_EHCI_HCD_PLATFORM=y \
+ CONFIG_USB_EHCI_HCD_AT91=y
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/host/ehci-hcd.ko \
+ $(LINUX_DIR)/drivers/usb/host/ehci-platform.ko
+ ifneq ($(wildcard $(LINUX_DIR)/drivers/usb/host/ehci-orion.ko),)
+ FILES+=$(LINUX_DIR)/drivers/usb/host/ehci-orion.ko
+ endif
+ ifneq ($(wildcard $(LINUX_DIR)/drivers/usb/host/ehci-atmel.ko),)
+ FILES+=$(LINUX_DIR)/drivers/usb/host/ehci-atmel.ko
+ endif
+ AUTOLOAD:=$(call AutoLoad,40,ehci-hcd ehci-platform ehci-orion ehci-atmel,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb2/description
+ Kernel support for USB2 (EHCI) controllers
+endef
+
+$(eval $(call KernelPackage,usb2))
+
+
+define KernelPackage/usb2-pci
+ TITLE:=Support for PCI USB2 controllers
+ DEPENDS:=@PCI_SUPPORT +kmod-usb2
+ KCONFIG:=CONFIG_USB_EHCI_PCI
+ FILES:=$(LINUX_DIR)/drivers/usb/host/ehci-pci.ko
+ AUTOLOAD:=$(call AutoLoad,42,ehci-pci,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb2-pci/description
+ Kernel support for PCI USB2 (EHCI) controllers
+endef
+
+$(eval $(call KernelPackage,usb2-pci))
+
+
+define KernelPackage/usb-dwc2
+ TITLE:=DWC2 USB controller driver
+ DEPENDS:=+(TARGET_brcm2708||TARGET_at91||TARGET_brcm63xx||TARGET_mxs||TARGET_imx6):kmod-usb-gadget
+ KCONFIG:= \
+ CONFIG_USB_DWC2 \
+ CONFIG_USB_DWC2_PCI \
+ CONFIG_USB_DWC2_PLATFORM \
+ CONFIG_USB_DWC2_DEBUG=n \
+ CONFIG_USB_DWC2_VERBOSE=n \
+ CONFIG_USB_DWC2_TRACK_MISSED_SOFS=n \
+ CONFIG_USB_DWC2_DEBUG_PERIODIC=n
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/dwc2/dwc2.ko \
+ $(LINUX_DIR)/drivers/usb/dwc2/dwc2_platform.ko
+ AUTOLOAD:=$(call AutoLoad,54,dwc2 dwc2_platform,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-dwc2/description
+ This driver provides USB Device Controller support for the
+ Synopsys DesignWare USB OTG Core
+endef
+
+$(eval $(call KernelPackage,usb-dwc2))
+
+
+define KernelPackage/usb2-oxnas
+ TITLE:=OXNAS USB controller driver
+ DEPENDS:=@TARGET_oxnas +kmod-usb2
+ KCONFIG:=CONFIG_USB_EHCI_OXNAS
+ FILES:=$(LINUX_DIR)/drivers/usb/host/ehci-oxnas.ko
+ AUTOLOAD:=$(call AutoLoad,55,ehci-oxnas,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb2-oxnas/description
+ This driver provides USB Device Controller support for the
+ EHCI USB host built-in to the PLXTECH NAS782x SoC
+endef
+
+$(eval $(call KernelPackage,usb2-oxnas))
+
+
+define KernelPackage/usb-dwc3
+ TITLE:=DWC3 USB controller driver
+ KCONFIG:= \
+ CONFIG_USB_DWC3 \
+ CONFIG_USB_DWC3_HOST=y \
+ CONFIG_USB_DWC3_GADGET=n \
+ CONFIG_USB_DWC3_DUAL_ROLE=n \
+ CONFIG_USB_DWC3_DEBUG=n \
+ CONFIG_USB_DWC3_VERBOSE=n
+ FILES:= $(LINUX_DIR)/drivers/usb/dwc3/dwc3.ko
+ AUTOLOAD:=$(call AutoLoad,54,dwc3,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-dwc3/description
+ This driver provides support for the Dual Role SuperSpeed
+ USB Controller based on the Synopsys DesignWare USB3 IP Core
+endef
+
+$(eval $(call KernelPackage,usb-dwc3))
+
+
+define KernelPackage/usb-acm
+ TITLE:=Support for modems/isdn controllers
+ KCONFIG:=CONFIG_USB_ACM
+ FILES:=$(LINUX_DIR)/drivers/usb/class/cdc-acm.ko
+ AUTOLOAD:=$(call AutoProbe,cdc-acm)
+$(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-acm/description
+ Kernel support for USB ACM devices (modems/isdn controllers)
+endef
+
+$(eval $(call KernelPackage,usb-acm))
+
+
+define KernelPackage/usb-wdm
+ TITLE:=USB Wireless Device Management
+ KCONFIG:=CONFIG_USB_WDM
+ FILES:=$(LINUX_DIR)/drivers/usb/class/cdc-wdm.ko
+ AUTOLOAD:=$(call AutoProbe,cdc-wdm)
+$(call AddDepends/usb)
+$(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-wdm/description
+ USB Wireless Device Management support
+endef
+
+$(eval $(call KernelPackage,usb-wdm))
+
+
+define KernelPackage/usb-audio
+ TITLE:=Support for USB audio devices
+ KCONFIG:= \
+ CONFIG_USB_AUDIO \
+ CONFIG_SND_USB_AUDIO
+ $(call AddDepends/usb)
+ $(call AddDepends/sound)
+ FILES:= \
+ $(LINUX_DIR)/sound/usb/snd-usbmidi-lib.ko \
+ $(LINUX_DIR)/sound/usb/snd-usb-audio.ko
+ AUTOLOAD:=$(call AutoProbe,snd-usbmidi-lib snd-usb-audio)
+endef
+
+define KernelPackage/usb-audio/description
+ Kernel support for USB audio devices
+endef
+
+$(eval $(call KernelPackage,usb-audio))
+
+
+define KernelPackage/usb-printer
+ TITLE:=Support for printers
+ KCONFIG:=CONFIG_USB_PRINTER
+ FILES:=$(LINUX_DIR)/drivers/usb/class/usblp.ko
+ AUTOLOAD:=$(call AutoProbe,usblp)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-printer/description
+ Kernel support for USB printers
+endef
+
+$(eval $(call KernelPackage,usb-printer))
+
+
+define KernelPackage/usb-serial
+ TITLE:=Support for USB-to-Serial converters
+ KCONFIG:=CONFIG_USB_SERIAL
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/usbserial.ko
+ AUTOLOAD:=$(call AutoProbe,usbserial)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-serial/description
+ Kernel support for USB-to-Serial converters
+endef
+
+$(eval $(call KernelPackage,usb-serial))
+
+
+define AddDepends/usb-serial
+ SUBMENU:=$(USB_MENU)
+ DEPENDS+=kmod-usb-serial $(1)
+endef
+
+
+define KernelPackage/usb-serial-belkin
+ TITLE:=Support for Belkin devices
+ KCONFIG:=CONFIG_USB_SERIAL_BELKIN
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/belkin_sa.ko
+ AUTOLOAD:=$(call AutoProbe,belkin_sa)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-belkin/description
+ Kernel support for Belkin USB-to-Serial converters
+endef
+
+$(eval $(call KernelPackage,usb-serial-belkin))
+
+
+define KernelPackage/usb-serial-ch341
+ TITLE:=Support for CH341 devices
+ KCONFIG:=CONFIG_USB_SERIAL_CH341
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/ch341.ko
+ AUTOLOAD:=$(call AutoProbe,ch341)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-ch341/description
+ Kernel support for Winchiphead CH341 USB-to-Serial converters
+endef
+
+$(eval $(call KernelPackage,usb-serial-ch341))
+
+
+define KernelPackage/usb-serial-ftdi
+ TITLE:=Support for FTDI devices
+ KCONFIG:=CONFIG_USB_SERIAL_FTDI_SIO
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/ftdi_sio.ko
+ AUTOLOAD:=$(call AutoProbe,ftdi_sio)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-ftdi/description
+ Kernel support for FTDI USB-to-Serial converters
+endef
+
+$(eval $(call KernelPackage,usb-serial-ftdi))
+
+
+define KernelPackage/usb-serial-garmin
+ TITLE:=Support for Garmin GPS devices
+ KCONFIG:=CONFIG_USB_SERIAL_GARMIN
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/garmin_gps.ko
+ AUTOLOAD:=$(call AutoProbe,garmin_gps)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-garmin/description
+ Should work with most Garmin GPS devices which have a native USB port.
+endef
+
+$(eval $(call KernelPackage,usb-serial-garmin))
+
+
+define KernelPackage/usb-serial-simple
+ TITLE:=USB Serial Simple (Motorola phone)
+ KCONFIG:=CONFIG_USB_SERIAL_SIMPLE
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/usb-serial-simple.ko
+ AUTOLOAD:=$(call AutoProbe,usb-serial-simple)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-simple/description
+ Kernel support for "very simple devices".
+
+Specifically, it supports:
+ - Suunto ANT+ USB device.
+ - Medtronic CareLink USB device (3.18)
+ - Fundamental Software dongle.
+ - Google USB serial devices (3.19)
+ - HP4x calculators
+ - a number of Motorola phones
+ - Novatel Wireless GPS receivers (3.18)
+ - Siemens USB/MPI adapter.
+ - ViVOtech ViVOpay USB device.
+ - Infineon Modem Flashloader USB interface
+ - ZIO Motherboard USB serial interface
+endef
+
+$(eval $(call KernelPackage,usb-serial-simple))
+
+
+define KernelPackage/usb-serial-ti-usb
+ TITLE:=Support for TI USB 3410/5052
+ KCONFIG:=CONFIG_USB_SERIAL_TI
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/ti_usb_3410_5052.ko
+ AUTOLOAD:=$(call AutoProbe,ti_usb_3410_5052)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-ti-usb/description
+ Kernel support for TI USB 3410/5052 devices
+endef
+
+$(eval $(call KernelPackage,usb-serial-ti-usb))
+
+
+define KernelPackage/usb-serial-ipw
+ TITLE:=Support for IPWireless 3G devices
+ KCONFIG:=CONFIG_USB_SERIAL_IPW
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/ipw.ko
+ AUTOLOAD:=$(call AutoProbe,ipw)
+ $(call AddDepends/usb-serial,+kmod-usb-serial-wwan)
+endef
+
+$(eval $(call KernelPackage,usb-serial-ipw))
+
+
+define KernelPackage/usb-serial-mct
+ TITLE:=Support for Magic Control Tech. devices
+ KCONFIG:=CONFIG_USB_SERIAL_MCT_U232
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/mct_u232.ko
+ AUTOLOAD:=$(call AutoProbe,mct_u232)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-mct/description
+ Kernel support for Magic Control Technology USB-to-Serial converters
+endef
+
+$(eval $(call KernelPackage,usb-serial-mct))
+
+
+define KernelPackage/usb-serial-mos7720
+ TITLE:=Support for Moschip MOS7720 devices
+ KCONFIG:=CONFIG_USB_SERIAL_MOS7720
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/mos7720.ko
+ AUTOLOAD:=$(call AutoProbe,mos7720)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-mos7720/description
+ Kernel support for Moschip MOS7720 USB-to-Serial converters
+endef
+
+$(eval $(call KernelPackage,usb-serial-mos7720))
+
+
+define KernelPackage/usb-serial-pl2303
+ TITLE:=Support for Prolific PL2303 devices
+ KCONFIG:=CONFIG_USB_SERIAL_PL2303
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/pl2303.ko
+ AUTOLOAD:=$(call AutoProbe,pl2303)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-pl2303/description
+ Kernel support for Prolific PL2303 USB-to-Serial converters
+endef
+
+$(eval $(call KernelPackage,usb-serial-pl2303))
+
+
+define KernelPackage/usb-serial-cp210x
+ TITLE:=Support for Silicon Labs cp210x devices
+ KCONFIG:=CONFIG_USB_SERIAL_CP210X
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/cp210x.ko
+ AUTOLOAD:=$(call AutoProbe,cp210x)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-cp210x/description
+ Kernel support for Silicon Labs cp210x USB-to-Serial converters
+endef
+
+$(eval $(call KernelPackage,usb-serial-cp210x))
+
+
+define KernelPackage/usb-serial-ark3116
+ TITLE:=Support for ArkMicroChips ARK3116 devices
+ KCONFIG:=CONFIG_USB_SERIAL_ARK3116
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/ark3116.ko
+ AUTOLOAD:=$(call AutoProbe,ark3116)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-ark3116/description
+ Kernel support for ArkMicroChips ARK3116 USB-to-Serial converters
+endef
+
+$(eval $(call KernelPackage,usb-serial-ark3116))
+
+
+define KernelPackage/usb-serial-oti6858
+ TITLE:=Support for Ours Technology OTI6858 devices
+ KCONFIG:=CONFIG_USB_SERIAL_OTI6858
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/oti6858.ko
+ AUTOLOAD:=$(call AutoProbe,oti6858)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-oti6858/description
+ Kernel support for Ours Technology OTI6858 USB-to-Serial converters
+endef
+
+$(eval $(call KernelPackage,usb-serial-oti6858))
+
+
+define KernelPackage/usb-serial-sierrawireless
+ TITLE:=Support for Sierra Wireless devices
+ KCONFIG:=CONFIG_USB_SERIAL_SIERRAWIRELESS
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/sierra.ko
+ AUTOLOAD:=$(call AutoProbe,sierra)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-sierrawireless/description
+ Kernel support for Sierra Wireless devices
+endef
+
+$(eval $(call KernelPackage,usb-serial-sierrawireless))
+
+
+define KernelPackage/usb-serial-visor
+ TITLE:=Support for Handspring Visor devices
+ KCONFIG:=CONFIG_USB_SERIAL_VISOR
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/visor.ko
+ AUTOLOAD:=$(call AutoProbe,visor)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-visor/description
+ Kernel support for Handspring Visor PDAs
+endef
+
+$(eval $(call KernelPackage,usb-serial-visor))
+
+
+define KernelPackage/usb-serial-cypress-m8
+ TITLE:=Support for CypressM8 USB-Serial
+ KCONFIG:=CONFIG_USB_SERIAL_CYPRESS_M8
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/cypress_m8.ko
+ AUTOLOAD:=$(call AutoProbe,cypress_m8)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-cypress-m8/description
+ Kernel support for devices with Cypress M8 USB to Serial chip
+ (for example, the Delorme Earthmate LT-20 GPS)
+ Supported microcontrollers in the CY4601 family are:
+ CY7C63741 CY7C63742 CY7C63743 CY7C64013
+endef
+
+$(eval $(call KernelPackage,usb-serial-cypress-m8))
+
+
+define KernelPackage/usb-serial-keyspan
+ TITLE:=Support for Keyspan USB-to-Serial devices
+ KCONFIG:= \
+ CONFIG_USB_SERIAL_KEYSPAN \
+ CONFIG_USB_SERIAL_KEYSPAN_USA28 \
+ CONFIG_USB_SERIAL_KEYSPAN_USA28X \
+ CONFIG_USB_SERIAL_KEYSPAN_USA28XA \
+ CONFIG_USB_SERIAL_KEYSPAN_USA28XB \
+ CONFIG_USB_SERIAL_KEYSPAN_USA19 \
+ CONFIG_USB_SERIAL_KEYSPAN_USA18X \
+ CONFIG_USB_SERIAL_KEYSPAN_USA19W \
+ CONFIG_USB_SERIAL_KEYSPAN_USA19QW \
+ CONFIG_USB_SERIAL_KEYSPAN_USA19QI \
+ CONFIG_USB_SERIAL_KEYSPAN_MPR \
+ CONFIG_USB_SERIAL_KEYSPAN_USA49W \
+ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/serial/keyspan.ko \
+ $(wildcard $(LINUX_DIR)/drivers/usb/misc/ezusb.ko)
+ AUTOLOAD:=$(call AutoProbe,ezusb keyspan)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-keyspan/description
+ Kernel support for Keyspan USB-to-Serial devices
+endef
+
+$(eval $(call KernelPackage,usb-serial-keyspan))
+
+
+define KernelPackage/usb-serial-wwan
+ TITLE:=Support for GSM and CDMA modems
+ KCONFIG:=CONFIG_USB_SERIAL_WWAN
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/usb_wwan.ko
+ AUTOLOAD:=$(call AutoProbe,usb_wwan)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-wwan/description
+ Kernel support for USB GSM and CDMA modems
+endef
+
+$(eval $(call KernelPackage,usb-serial-wwan))
+
+
+define KernelPackage/usb-serial-option
+ TITLE:=Support for Option HSDPA modems
+ DEPENDS:=+kmod-usb-serial-wwan
+ KCONFIG:=CONFIG_USB_SERIAL_OPTION
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/option.ko
+ AUTOLOAD:=$(call AutoProbe,option)
+ $(call AddDepends/usb-serial)
+endef
+
+define KernelPackage/usb-serial-option/description
+ Kernel support for Option HSDPA modems
+endef
+
+$(eval $(call KernelPackage,usb-serial-option))
+
+
+define KernelPackage/usb-serial-qualcomm
+ TITLE:=Support for Qualcomm USB serial
+ KCONFIG:=CONFIG_USB_SERIAL_QUALCOMM
+ FILES:=$(LINUX_DIR)/drivers/usb/serial/qcserial.ko
+ AUTOLOAD:=$(call AutoProbe,qcserial)
+ $(call AddDepends/usb-serial,+kmod-usb-serial-wwan)
+endef
+
+define KernelPackage/usb-serial-qualcomm/description
+ Kernel support for Qualcomm USB Serial devices (Gobi)
+endef
+
+$(eval $(call KernelPackage,usb-serial-qualcomm))
+
+
+define KernelPackage/usb-storage
+ TITLE:=USB Storage support
+ DEPENDS:= +kmod-scsi-core
+ KCONFIG:=CONFIG_USB_STORAGE
+ FILES:=$(LINUX_DIR)/drivers/usb/storage/usb-storage.ko
+ AUTOLOAD:=$(call AutoProbe,usb-storage,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-storage/description
+ Kernel support for USB Mass Storage devices
+endef
+
+$(eval $(call KernelPackage,usb-storage))
+
+
+define KernelPackage/usb-storage-extras
+ SUBMENU:=$(USB_MENU)
+ TITLE:=Extra drivers for usb-storage
+ DEPENDS:=+kmod-usb-storage
+ KCONFIG:= \
+ CONFIG_USB_STORAGE_ALAUDA \
+ CONFIG_USB_STORAGE_CYPRESS_ATACB \
+ CONFIG_USB_STORAGE_DATAFAB \
+ CONFIG_USB_STORAGE_FREECOM \
+ CONFIG_USB_STORAGE_ISD200 \
+ CONFIG_USB_STORAGE_JUMPSHOT \
+ CONFIG_USB_STORAGE_KARMA \
+ CONFIG_USB_STORAGE_SDDR09 \
+ CONFIG_USB_STORAGE_SDDR55 \
+ CONFIG_USB_STORAGE_USBAT
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/storage/ums-alauda.ko \
+ $(LINUX_DIR)/drivers/usb/storage/ums-cypress.ko \
+ $(LINUX_DIR)/drivers/usb/storage/ums-datafab.ko \
+ $(LINUX_DIR)/drivers/usb/storage/ums-freecom.ko \
+ $(LINUX_DIR)/drivers/usb/storage/ums-isd200.ko \
+ $(LINUX_DIR)/drivers/usb/storage/ums-jumpshot.ko \
+ $(LINUX_DIR)/drivers/usb/storage/ums-karma.ko \
+ $(LINUX_DIR)/drivers/usb/storage/ums-sddr09.ko \
+ $(LINUX_DIR)/drivers/usb/storage/ums-sddr55.ko \
+ $(LINUX_DIR)/drivers/usb/storage/ums-usbat.ko
+ AUTOLOAD:=$(call AutoProbe,ums-alauda ums-cypress ums-datafab \
+ ums-freecom ums-isd200 ums-jumpshot \
+ ums-karma ums-sddr09 ums-sddr55 ums-usbat)
+endef
+
+define KernelPackage/usb-storage-extras/description
+ Say Y here if you want to have some more drivers,
+ such as for SmartMedia card readers
+endef
+
+$(eval $(call KernelPackage,usb-storage-extras))
+
+
+define KernelPackage/usb-atm
+ TITLE:=Support for ATM on USB bus
+ DEPENDS:=+kmod-atm
+ KCONFIG:=CONFIG_USB_ATM
+ FILES:=$(LINUX_DIR)/drivers/usb/atm/usbatm.ko
+ AUTOLOAD:=$(call AutoProbe,usbatm)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-atm/description
+ Kernel support for USB DSL modems
+endef
+
+$(eval $(call KernelPackage,usb-atm))
+
+
+define AddDepends/usb-atm
+ SUBMENU:=$(USB_MENU)
+ DEPENDS+=kmod-usb-atm $(1)
+endef
+
+
+define KernelPackage/usb-atm-speedtouch
+ TITLE:=SpeedTouch USB ADSL modems support
+ KCONFIG:=CONFIG_USB_SPEEDTOUCH
+ FILES:=$(LINUX_DIR)/drivers/usb/atm/speedtch.ko
+ AUTOLOAD:=$(call AutoProbe,speedtch)
+ $(call AddDepends/usb-atm)
+endef
+
+define KernelPackage/usb-atm-speedtouch/description
+ Kernel support for SpeedTouch USB ADSL modems
+endef
+
+$(eval $(call KernelPackage,usb-atm-speedtouch))
+
+
+define KernelPackage/usb-atm-ueagle
+ TITLE:=Eagle 8051 based USB ADSL modems support
+ FILES:=$(LINUX_DIR)/drivers/usb/atm/ueagle-atm.ko
+ KCONFIG:=CONFIG_USB_UEAGLEATM
+ AUTOLOAD:=$(call AutoProbe,ueagle-atm)
+ $(call AddDepends/usb-atm)
+endef
+
+define KernelPackage/usb-atm-ueagle/description
+ Kernel support for Eagle 8051 based USB ADSL modems
+endef
+
+$(eval $(call KernelPackage,usb-atm-ueagle))
+
+
+define KernelPackage/usb-atm-cxacru
+ TITLE:=cxacru
+ FILES:=$(LINUX_DIR)/drivers/usb/atm/cxacru.ko
+ KCONFIG:=CONFIG_USB_CXACRU
+ AUTOLOAD:=$(call AutoProbe,cxacru)
+ $(call AddDepends/usb-atm)
+endef
+
+define KernelPackage/usb-atm-cxacru/description
+ Kernel support for cxacru based USB ADSL modems
+endef
+
+$(eval $(call KernelPackage,usb-atm-cxacru))
+
+
+define KernelPackage/usb-net
+ TITLE:=Kernel modules for USB-to-Ethernet convertors
+ DEPENDS:=+kmod-mii
+ KCONFIG:=CONFIG_USB_USBNET \
+ CONFIG_USB_NET_DRIVERS
+ AUTOLOAD:=$(call AutoProbe,usbnet)
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/usbnet.ko
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-net/description
+ Kernel modules for USB-to-Ethernet convertors
+endef
+
+$(eval $(call KernelPackage,usb-net))
+
+
+define AddDepends/usb-net
+ SUBMENU:=$(USB_MENU)
+ DEPENDS+=kmod-usb-net $(1)
+endef
+
+
+define KernelPackage/usb-net-asix
+ TITLE:=Kernel module for USB-to-Ethernet Asix convertors
+ DEPENDS:=+kmod-libphy
+ KCONFIG:=CONFIG_USB_NET_AX8817X
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/asix.ko
+ AUTOLOAD:=$(call AutoProbe,asix)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-asix/description
+ Kernel module for USB-to-Ethernet Asix convertors
+endef
+
+$(eval $(call KernelPackage,usb-net-asix))
+
+
+define KernelPackage/usb-net-asix-ax88179
+ TITLE:=Kernel module for USB-to-Gigabit-Ethernet Asix convertors
+ DEPENDS:=+kmod-libphy
+ KCONFIG:=CONFIG_USB_NET_AX88179_178A
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/ax88179_178a.ko
+ AUTOLOAD:=$(call AutoProbe,ax88179_178a)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-asix-ax88179/description
+ Kernel module for USB-to-Ethernet ASIX AX88179 based USB 3.0/2.0
+ to Gigabit Ethernet adapters.
+endef
+
+$(eval $(call KernelPackage,usb-net-asix-ax88179))
+
+
+define KernelPackage/usb-net-hso
+ TITLE:=Kernel module for Option USB High Speed Mobile Devices
+ KCONFIG:=CONFIG_USB_HSO
+ FILES:= \
+ $(LINUX_DIR)/drivers/$(USBNET_DIR)/hso.ko
+ AUTOLOAD:=$(call AutoProbe,hso)
+ $(call AddDepends/usb-net)
+ $(call AddDepends/rfkill)
+endef
+
+define KernelPackage/usb-net-hso/description
+ Kernel module for Option USB High Speed Mobile Devices
+endef
+
+$(eval $(call KernelPackage,usb-net-hso))
+
+
+define KernelPackage/usb-net-kaweth
+ TITLE:=Kernel module for USB-to-Ethernet Kaweth convertors
+ KCONFIG:=CONFIG_USB_KAWETH
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/kaweth.ko
+ AUTOLOAD:=$(call AutoProbe,kaweth)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-kaweth/description
+ Kernel module for USB-to-Ethernet Kaweth convertors
+endef
+
+$(eval $(call KernelPackage,usb-net-kaweth))
+
+
+define KernelPackage/usb-net-pegasus
+ TITLE:=Kernel module for USB-to-Ethernet Pegasus convertors
+ KCONFIG:=CONFIG_USB_PEGASUS
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/pegasus.ko
+ AUTOLOAD:=$(call AutoProbe,pegasus)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-pegasus/description
+ Kernel module for USB-to-Ethernet Pegasus convertors
+endef
+
+$(eval $(call KernelPackage,usb-net-pegasus))
+
+
+define KernelPackage/usb-net-mcs7830
+ TITLE:=Kernel module for USB-to-Ethernet MCS7830 convertors
+ KCONFIG:=CONFIG_USB_NET_MCS7830
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/mcs7830.ko
+ AUTOLOAD:=$(call AutoProbe,mcs7830)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-mcs7830/description
+ Kernel module for USB-to-Ethernet MCS7830 convertors
+endef
+
+$(eval $(call KernelPackage,usb-net-mcs7830))
+
+
+define KernelPackage/usb-net-smsc95xx
+ TITLE:=SMSC LAN95XX based USB 2.0 10/100 ethernet devices
+ KCONFIG:=CONFIG_USB_NET_SMSC95XX
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/smsc95xx.ko
+ AUTOLOAD:=$(call AutoProbe,smsc95xx)
+ $(call AddDepends/usb-net, +kmod-lib-crc16)
+endef
+
+define KernelPackage/usb-net-smsc95xx/description
+ Kernel module for SMSC LAN95XX based devices
+endef
+
+$(eval $(call KernelPackage,usb-net-smsc95xx))
+
+
+define KernelPackage/usb-net-dm9601-ether
+ TITLE:=Support for DM9601 ethernet connections
+ KCONFIG:=CONFIG_USB_NET_DM9601
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/dm9601.ko
+ AUTOLOAD:=$(call AutoProbe,dm9601)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-dm9601-ether/description
+ Kernel support for USB DM9601 devices
+endef
+
+$(eval $(call KernelPackage,usb-net-dm9601-ether))
+
+define KernelPackage/usb-net-cdc-ether
+ TITLE:=Support for cdc ethernet connections
+ KCONFIG:=CONFIG_USB_NET_CDCETHER
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/cdc_ether.ko
+ AUTOLOAD:=$(call AutoProbe,cdc_ether)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-cdc-ether/description
+ Kernel support for USB CDC Ethernet devices
+endef
+
+$(eval $(call KernelPackage,usb-net-cdc-ether))
+
+
+define KernelPackage/usb-net-cdc-eem
+ TITLE:=Support for CDC EEM connections
+ KCONFIG:=CONFIG_USB_NET_CDC_EEM
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/cdc_eem.ko
+ AUTOLOAD:=$(call AutoProbe,cdc_eem)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-cdc-eem/description
+ Kernel support for USB CDC EEM
+endef
+
+$(eval $(call KernelPackage,usb-net-cdc-eem))
+
+
+define KernelPackage/usb-net-cdc-subset
+ TITLE:=Support for CDC Ethernet subset connections
+ KCONFIG:= \
+ CONFIG_USB_NET_CDC_SUBSET \
+ CONFIG_USB_ARMLINUX
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/cdc_subset.ko
+ AUTOLOAD:=$(call AutoProbe,cdc_subset)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-cdc-subset/description
+ Kernel support for Simple USB Network Links (CDC Ethernet subset)
+endef
+
+$(eval $(call KernelPackage,usb-net-cdc-subset))
+
+
+define KernelPackage/usb-net-qmi-wwan
+ TITLE:=QMI WWAN driver
+ KCONFIG:=CONFIG_USB_NET_QMI_WWAN
+ FILES:= $(LINUX_DIR)/drivers/$(USBNET_DIR)/qmi_wwan.ko
+ AUTOLOAD:=$(call AutoProbe,qmi_wwan)
+ $(call AddDepends/usb-net,+kmod-usb-wdm)
+endef
+
+define KernelPackage/usb-net-qmi-wwan/description
+ QMI WWAN driver for Qualcomm MSM based 3G and LTE modems
+endef
+
+$(eval $(call KernelPackage,usb-net-qmi-wwan))
+
+
+define KernelPackage/usb-net-rtl8150
+ TITLE:=Kernel module for USB-to-Ethernet Realtek convertors
+ KCONFIG:=CONFIG_USB_RTL8150
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/rtl8150.ko
+ AUTOLOAD:=$(call AutoProbe,rtl8150)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-rtl8150/description
+ Kernel module for USB-to-Ethernet Realtek 8150 convertors
+endef
+
+$(eval $(call KernelPackage,usb-net-rtl8150))
+
+
+define KernelPackage/usb-net-rtl8152
+ TITLE:=Kernel module for USB-to-Ethernet Realtek convertors
+ KCONFIG:=CONFIG_USB_RTL8152
+ FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/r8152.ko
+ AUTOLOAD:=$(call AutoProbe,r8152)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-rtl8152/description
+ Kernel module for USB-to-Ethernet Realtek 8152 USB2.0/3.0 convertors
+endef
+
+$(eval $(call KernelPackage,usb-net-rtl8152))
+
+
+define KernelPackage/usb-net-rndis
+ TITLE:=Support for RNDIS connections
+ KCONFIG:=CONFIG_USB_NET_RNDIS_HOST
+ FILES:= $(LINUX_DIR)/drivers/$(USBNET_DIR)/rndis_host.ko
+ AUTOLOAD:=$(call AutoProbe,rndis_host)
+ $(call AddDepends/usb-net,+kmod-usb-net-cdc-ether)
+endef
+
+define KernelPackage/usb-net-rndis/description
+ Kernel support for RNDIS connections
+endef
+
+$(eval $(call KernelPackage,usb-net-rndis))
+
+
+define KernelPackage/usb-net-cdc-mbim
+ SUBMENU:=$(USB_MENU)
+ TITLE:=Kernel module for MBIM Devices
+ KCONFIG:=CONFIG_USB_NET_CDC_MBIM
+ FILES:= \
+ $(LINUX_DIR)/drivers/$(USBNET_DIR)/cdc_mbim.ko
+ AUTOLOAD:=$(call AutoProbe,cdc_mbim)
+ $(call AddDepends/usb-net,+kmod-usb-wdm +kmod-usb-net-cdc-ncm)
+endef
+
+define KernelPackage/usb-net-cdc-mbim/description
+ Kernel module for Option USB High Speed Mobile Devices
+endef
+
+$(eval $(call KernelPackage,usb-net-cdc-mbim))
+
+
+define KernelPackage/usb-net-cdc-ncm
+ TITLE:=Support for CDC NCM connections
+ KCONFIG:=CONFIG_USB_NET_CDC_NCM
+ FILES:= $(LINUX_DIR)/drivers/$(USBNET_DIR)/cdc_ncm.ko
+ AUTOLOAD:=$(call AutoProbe,cdc_ncm)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-cdc-ncm/description
+ Kernel support for CDC NCM connections
+endef
+
+$(eval $(call KernelPackage,usb-net-cdc-ncm))
+
+
+define KernelPackage/usb-net-huawei-cdc-ncm
+ TITLE:=Support for Huawei CDC NCM connections
+ KCONFIG:=CONFIG_USB_NET_HUAWEI_CDC_NCM
+ FILES:= $(LINUX_DIR)/drivers/$(USBNET_DIR)/huawei_cdc_ncm.ko
+ AUTOLOAD:=$(call AutoProbe,huawei_cdc_ncm)
+ $(call AddDepends/usb-net,+kmod-usb-net-cdc-ncm +kmod-usb-wdm)
+endef
+
+define KernelPackage/usb-net-huawei-cdc-ncm/description
+ Kernel support for Huawei CDC NCM connections
+endef
+
+$(eval $(call KernelPackage,usb-net-huawei-cdc-ncm))
+
+
+define KernelPackage/usb-net-sierrawireless
+ TITLE:=Support for Sierra Wireless devices
+ KCONFIG:=CONFIG_USB_SIERRA_NET
+ FILES:=$(LINUX_DIR)/drivers/net/usb/sierra_net.ko
+ AUTOLOAD:=$(call AutoProbe,sierra_net)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-sierrawireless/description
+ Kernel support for Sierra Wireless devices
+endef
+
+$(eval $(call KernelPackage,usb-net-sierrawireless))
+
+
+define KernelPackage/usb-net-ipheth
+ TITLE:=Apple iPhone USB Ethernet driver
+ KCONFIG:=CONFIG_USB_IPHETH
+ FILES:=$(LINUX_DIR)/drivers/net/usb/ipheth.ko
+ AUTOLOAD:=$(call AutoProbe,ipheth)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-ipheth/description
+ Kernel support for Apple iPhone USB Ethernet driver
+endef
+
+$(eval $(call KernelPackage,usb-net-ipheth))
+
+
+define KernelPackage/usb-net-kalmia
+ TITLE:=Samsung Kalmia based LTE USB modem
+ KCONFIG:=CONFIG_USB_NET_KALMIA
+ FILES:=$(LINUX_DIR)/drivers/net/usb/kalmia.ko
+ AUTOLOAD:=$(call AutoProbe,kalmia)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-kalmia/description
+ Kernel support for Samsung Kalmia based LTE USB modem
+endef
+
+$(eval $(call KernelPackage,usb-net-kalmia))
+
+
+define KernelPackage/usb-hid
+ TITLE:=Support for USB Human Input Devices
+ KCONFIG:=CONFIG_HID_SUPPORT=y CONFIG_USB_HID CONFIG_USB_HIDDEV=y
+ DEPENDS:=+kmod-hid +kmod-hid-generic +kmod-input-evdev
+ FILES:=$(LINUX_DIR)/drivers/$(USBHID_DIR)/usbhid.ko
+ AUTOLOAD:=$(call AutoProbe,usbhid)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-hid/description
+ Kernel support for USB HID devices such as keyboards and mice
+endef
+
+$(eval $(call KernelPackage,usb-hid))
+
+
+define KernelPackage/usb-yealink
+ TITLE:=USB Yealink VOIP phone
+ DEPENDS:=+kmod-input-evdev
+ KCONFIG:=CONFIG_USB_YEALINK CONFIG_INPUT_YEALINK CONFIG_INPUT=m CONFIG_INPUT_MISC=y
+ FILES:=$(LINUX_DIR)/drivers/$(USBINPUT_DIR)/yealink.ko
+ AUTOLOAD:=$(call AutoProbe,yealink)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-yealink/description
+ Kernel support for Yealink VOIP phone
+endef
+
+$(eval $(call KernelPackage,usb-yealink))
+
+
+define KernelPackage/usb-cm109
+ TITLE:=Support for CM109 device
+ DEPENDS:=+kmod-input-evdev
+ KCONFIG:=CONFIG_USB_CM109 CONFIG_INPUT_CM109 CONFIG_INPUT=m CONFIG_INPUT_MISC=y
+ FILES:=$(LINUX_DIR)/drivers/$(USBINPUT_DIR)/cm109.ko
+ AUTOLOAD:=$(call AutoProbe,cm109)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-cm109/description
+ Kernel support for CM109 VOIP phone
+endef
+
+$(eval $(call KernelPackage,usb-cm109))
+
+
+define KernelPackage/usb-test
+ TITLE:=USB Testing Driver
+ DEPENDS:=@DEVEL
+ KCONFIG:=CONFIG_USB_TEST
+ FILES:=$(LINUX_DIR)/drivers/usb/misc/usbtest.ko
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-test/description
+ Kernel support for testing USB Host Controller software
+endef
+
+$(eval $(call KernelPackage,usb-test))
+
+
+define KernelPackage/usbip
+ TITLE := USB-over-IP kernel support
+ KCONFIG:= \
+ CONFIG_USBIP_CORE \
+ CONFIG_USBIP_DEBUG=n
+ FILES:=$(LINUX_DIR)/drivers/usb/usbip/usbip-core.ko
+ AUTOLOAD:=$(call AutoProbe,usbip-core)
+ $(call AddDepends/usb)
+endef
+
+$(eval $(call KernelPackage,usbip))
+
+
+define KernelPackage/usbip-client
+ TITLE := USB-over-IP client driver
+ DEPENDS := +kmod-usbip
+ KCONFIG := CONFIG_USBIP_VHCI_HCD
+ FILES :=$(LINUX_DIR)/drivers/usb/usbip/vhci-hcd.ko
+ AUTOLOAD := $(call AutoProbe,vhci-hcd)
+ $(call AddDepends/usb)
+endef
+
+$(eval $(call KernelPackage,usbip-client))
+
+
+define KernelPackage/usbip-server
+$(call KernelPackage/usbip/Default)
+ TITLE := USB-over-IP host driver
+ DEPENDS := +kmod-usbip
+ KCONFIG := CONFIG_USBIP_HOST
+ FILES :=$(LINUX_DIR)/drivers/usb/usbip/usbip-host.ko
+ AUTOLOAD := $(call AutoProbe,usbip-host)
+ $(call AddDepends/usb)
+endef
+
+$(eval $(call KernelPackage,usbip-server))
+
+
+define KernelPackage/usb-chipidea-imx
+ TITLE:=Support for ChipIdea controllers
+ DEPENDS:=@TARGET_imx6||TARGET_mxs +kmod-usb2 +USB_GADGET_SUPPORT:kmod-usb-gadget
+ KCONFIG:=\
+ CONFIG_USB_CHIPIDEA \
+ CONFIG_USB_CHIPIDEA_HOST=y \
+ CONFIG_USB_CHIPIDEA_UDC=y \
+ CONFIG_USB_CHIPIDEA_DEBUG=y
+ FILES:=\
+ $(LINUX_DIR)/drivers/usb/chipidea/ci_hdrc.ko \
+ $(if $(CONFIG_OF),$(LINUX_DIR)/drivers/usb/chipidea/ci_hdrc_imx.ko) \
+ $(if $(CONFIG_OF),$(LINUX_DIR)/drivers/usb/chipidea/usbmisc_imx.ko)
+ AUTOLOAD:=$(call AutoLoad,51,ci_hdrc $(if $(CONFIG_OF),ci_hdrc_imx usbmisc_imx),1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-chipidea-imx/description
+ Kernel support for USB ChipIdea controllers
+endef
+
+$(eval $(call KernelPackage,usb-chipidea-imx,1))
+
+
+define KernelPackage/usb-mxs-phy
+ TITLE:=Support for Freescale MXS USB PHY
+ DEPENDS:=@TARGET_imx6||TARGET_mxs +TARGET_mxs:kmod-usb-chipidea-imx
+ KCONFIG:=CONFIG_USB_MXS_PHY
+ FILES:=\
+ $(LINUX_DIR)/drivers/usb/phy/phy-mxs-usb.ko
+ AUTOLOAD:=$(call AutoLoad,52,phy-mxs-usb,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-mxs-phy/description
+ Kernel support for Freescale MXS USB PHY
+endef
+
+$(eval $(call KernelPackage,usb-mxs-phy,1))
+
+
+define KernelPackage/usbmon
+ TITLE:=USB traffic monitor
+ KCONFIG:=CONFIG_USB_MON
+ $(call AddDepends/usb)
+ FILES:=$(LINUX_DIR)/drivers/usb/mon/usbmon.ko
+ AUTOLOAD:=$(call AutoProbe,usbmon)
+endef
+
+define KernelPackage/usbmon/description
+ Kernel support for USB traffic monitoring
+endef
+
+$(eval $(call KernelPackage,usbmon))
+
+XHCI_FILES := $(wildcard $(patsubst %,$(LINUX_DIR)/drivers/usb/host/%.ko,xhci-hcd xhci-pci xhci-plat-hcd))
+XHCI_AUTOLOAD := $(patsubst $(LINUX_DIR)/drivers/usb/host/%.ko,%,$(XHCI_FILES))
+
+define KernelPackage/usb3
+ TITLE:=Support for USB3 controllers
+ DEPENDS:= \
+ +TARGET_bcm53xx:kmod-usb-bcma \
+ +TARGET_omap:kmod-usb-phy-omap-usb3
+ KCONFIG:= \
+ CONFIG_USB_XHCI_HCD \
+ CONFIG_USB_XHCI_PCI \
+ CONFIG_USB_XHCI_PLATFORM \
+ CONFIG_USB_XHCI_MVEBU=y \
+ CONFIG_USB_XHCI_HCD_DEBUGGING=n
+ FILES:= \
+ $(XHCI_FILES)
+ AUTOLOAD:=$(call AutoLoad,54,$(XHCI_AUTOLOAD),1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb3/description
+ Kernel support for USB3 (XHCI) controllers
+endef
+
+$(eval $(call KernelPackage,usb3))
diff --git a/package/kernel/linux/modules/video.mk b/package/kernel/linux/modules/video.mk
new file mode 100644
index 0000000..3b06a14
--- /dev/null
+++ b/package/kernel/linux/modules/video.mk
@@ -0,0 +1,709 @@
+#
+# Copyright (C) 2009 David Cooper <dave@kupesoft.com>
+# Copyright (C) 2006-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+VIDEO_MENU:=Video Support
+
+V4L2_DIR=v4l2-core
+V4L2_USB_DIR=usb
+
+define KernelPackage/fb
+ SUBMENU:=$(VIDEO_MENU)
+ TITLE:=Framebuffer support
+ DEPENDS:=@DISPLAY_SUPPORT
+ KCONFIG:=CONFIG_FB
+ FILES:=$(LINUX_DIR)/drivers/video/fbdev/core/fb.ko
+ AUTOLOAD:=$(call AutoLoad,06,fb)
+endef
+
+define KernelPackage/fb/description
+ Kernel support for framebuffers
+endef
+
+define KernelPackage/fb/x86
+ FILES+=$(LINUX_DIR)/arch/x86/video/fbdev.ko
+ AUTOLOAD:=$(call AutoLoad,06,fbdev fb)
+endef
+
+$(eval $(call KernelPackage,fb))
+
+define KernelPackage/fb-cfb-fillrect
+ SUBMENU:=$(VIDEO_MENU)
+ TITLE:=Framebuffer software rectangle filling support
+ DEPENDS:=+kmod-fb
+ KCONFIG:=CONFIG_FB_CFB_FILLRECT
+ FILES:=$(LINUX_DIR)/drivers/video/fbdev/core/cfbfillrect.ko
+ AUTOLOAD:=$(call AutoLoad,07,cfbfillrect)
+endef
+
+define KernelPackage/fb-cfb-fillrect/description
+ Kernel support for software rectangle filling
+endef
+
+$(eval $(call KernelPackage,fb-cfb-fillrect))
+
+
+define KernelPackage/fb-cfb-copyarea
+ SUBMENU:=$(VIDEO_MENU)
+ TITLE:=Framebuffer software copy area support
+ DEPENDS:=+kmod-fb
+ KCONFIG:=CONFIG_FB_CFB_COPYAREA
+ FILES:=$(LINUX_DIR)/drivers/video/fbdev/core/cfbcopyarea.ko
+ AUTOLOAD:=$(call AutoLoad,07,cfbcopyarea)
+endef
+
+define KernelPackage/fb-cfb-copyarea/description
+ Kernel support for software copy area
+endef
+
+$(eval $(call KernelPackage,fb-cfb-copyarea))
+
+define KernelPackage/fb-cfb-imgblt
+ SUBMENU:=$(VIDEO_MENU)
+ TITLE:=Framebuffer software image blit support
+ DEPENDS:=+kmod-fb
+ KCONFIG:=CONFIG_FB_CFB_IMAGEBLIT
+ FILES:=$(LINUX_DIR)/drivers/video/fbdev/core/cfbimgblt.ko
+ AUTOLOAD:=$(call AutoLoad,07,cfbimgblt)
+endef
+
+define KernelPackage/fb-cfb-imgblt/description
+ Kernel support for software image blitting
+endef
+
+$(eval $(call KernelPackage,fb-cfb-imgblt))
+
+
+define KernelPackage/video-core
+ SUBMENU:=$(VIDEO_MENU)
+ TITLE=Video4Linux support
+ DEPENDS:=@PCI_SUPPORT||USB_SUPPORT +PACKAGE_kmod-i2c-core:kmod-i2c-core
+ KCONFIG:= \
+ CONFIG_MEDIA_SUPPORT=m \
+ CONFIG_MEDIA_CAMERA_SUPPORT=y \
+ CONFIG_VIDEO_DEV \
+ CONFIG_VIDEO_V4L1=y \
+ CONFIG_VIDEO_ALLOW_V4L1=y \
+ CONFIG_VIDEO_CAPTURE_DRIVERS=y \
+ CONFIG_V4L_USB_DRIVERS=y \
+ CONFIG_V4L_PCI_DRIVERS=y \
+ CONFIG_V4L_PLATFORM_DRIVERS=y \
+ CONFIG_V4L_ISA_PARPORT_DRIVERS=y
+ FILES:= \
+ $(LINUX_DIR)/drivers/media/$(V4L2_DIR)/v4l2-common.ko \
+ $(LINUX_DIR)/drivers/media/$(V4L2_DIR)/videodev.ko
+ AUTOLOAD:=$(call AutoLoad,60, videodev v4l2-common)
+endef
+
+define KernelPackage/video-core/description
+ Kernel modules for Video4Linux support
+endef
+
+$(eval $(call KernelPackage,video-core))
+
+
+define AddDepends/video
+ SUBMENU:=$(VIDEO_MENU)
+ DEPENDS+=kmod-video-core $(1)
+endef
+
+define AddDepends/camera
+ SUBMENU:=$(VIDEO_MENU)
+ KCONFIG+=CONFIG_MEDIA_USB_SUPPORT=y \
+ CONFIG_MEDIA_CAMERA_SUPPORT=y
+ DEPENDS+=kmod-video-core $(1)
+endef
+
+
+define KernelPackage/video-videobuf2
+ TITLE:=videobuf2 lib
+ KCONFIG:= \
+ CONFIG_VIDEOBUF2_CORE \
+ CONFIG_VIDEOBUF2_MEMOPS \
+ CONFIG_VIDEOBUF2_VMALLOC
+ FILES:= \
+ $(LINUX_DIR)/drivers/media/$(V4L2_DIR)/videobuf2-core.ko \
+ $(LINUX_DIR)/drivers/media/$(V4L2_DIR)/videobuf2-memops.ko \
+ $(LINUX_DIR)/drivers/media/$(V4L2_DIR)/videobuf2-vmalloc.ko
+ AUTOLOAD:=$(call AutoLoad,65,videobuf2-core videobuf2-memops videobuf2-vmalloc)
+ $(call AddDepends/video)
+endef
+
+define KernelPackage/video-videobuf2/description
+ Kernel modules that implements three basic types of media buffers.
+endef
+
+$(eval $(call KernelPackage,video-videobuf2))
+
+
+define KernelPackage/video-cpia2
+ TITLE:=CPIA2 video driver
+ DEPENDS:=@USB_SUPPORT +kmod-usb-core
+ KCONFIG:=CONFIG_VIDEO_CPIA2
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/cpia2/cpia2.ko
+ AUTOLOAD:=$(call AutoProbe,cpia2)
+ $(call AddDepends/camera)
+endef
+
+define KernelPackage/video-cpia2/description
+ Kernel modules for supporting CPIA2 USB based cameras
+endef
+
+$(eval $(call KernelPackage,video-cpia2))
+
+
+define KernelPackage/video-pwc
+ TITLE:=Philips USB webcam support
+ DEPENDS:=@USB_SUPPORT +kmod-usb-core +kmod-video-videobuf2
+ KCONFIG:= \
+ CONFIG_USB_PWC \
+ CONFIG_USB_PWC_DEBUG=n
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/pwc/pwc.ko
+ AUTOLOAD:=$(call AutoProbe,pwc)
+ $(call AddDepends/camera)
+endef
+
+define KernelPackage/video-pwc/description
+ Kernel modules for supporting Philips USB based cameras
+endef
+
+$(eval $(call KernelPackage,video-pwc))
+
+
+define KernelPackage/video-uvc
+ TITLE:=USB Video Class (UVC) support
+ DEPENDS:=@USB_SUPPORT +kmod-usb-core +kmod-video-videobuf2 +kmod-input-core
+ KCONFIG:= CONFIG_USB_VIDEO_CLASS
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/uvc/uvcvideo.ko
+ AUTOLOAD:=$(call AutoProbe,uvcvideo)
+ $(call AddDepends/camera)
+endef
+
+define KernelPackage/video-uvc/description
+ Kernel modules for supporting USB Video Class (UVC) devices
+endef
+
+$(eval $(call KernelPackage,video-uvc))
+
+
+define KernelPackage/video-gspca-core
+ MENU:=1
+ TITLE:=GSPCA webcam core support framework
+ DEPENDS:=@USB_SUPPORT +kmod-usb-core +kmod-input-core
+ KCONFIG:=CONFIG_USB_GSPCA
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_main.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_main)
+ $(call AddDepends/camera)
+endef
+
+define KernelPackage/video-gspca-core/description
+ Kernel modules for supporting GSPCA based webcam devices. Note this is just
+ the core of the driver, please select a submodule that supports your webcam.
+endef
+
+$(eval $(call KernelPackage,video-gspca-core))
+
+
+define AddDepends/camera-gspca
+ SUBMENU:=$(VIDEO_MENU)
+ DEPENDS+=kmod-video-gspca-core $(1)
+endef
+
+
+define KernelPackage/video-gspca-conex
+ TITLE:=conex webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_CONEX
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_conex.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_conex)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-conex/description
+ The Conexant Camera Driver (conex) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-conex))
+
+
+define KernelPackage/video-gspca-etoms
+ TITLE:=etoms webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_ETOMS
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_etoms.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_etoms)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-etoms/description
+ The Etoms USB Camera Driver (etoms) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-etoms))
+
+
+define KernelPackage/video-gspca-finepix
+ TITLE:=finepix webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_FINEPIX
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_finepix.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_finepix)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-finepix/description
+ The Fujifilm FinePix USB V4L2 driver (finepix) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-finepix))
+
+
+define KernelPackage/video-gspca-mars
+ TITLE:=mars webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_MARS
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_mars.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_mars)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-mars/description
+ The Mars USB Camera Driver (mars) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-mars))
+
+
+define KernelPackage/video-gspca-mr97310a
+ TITLE:=mr97310a webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_MR97310A
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_mr97310a.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_mr97310a)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-mr97310a/description
+ The Mars-Semi MR97310A USB Camera Driver (mr97310a) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-mr97310a))
+
+
+define KernelPackage/video-gspca-ov519
+ TITLE:=ov519 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_OV519
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_ov519.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_ov519)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-ov519/description
+ The OV519 USB Camera Driver (ov519) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-ov519))
+
+
+define KernelPackage/video-gspca-ov534
+ TITLE:=ov534 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_OV534
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_ov534.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_ov534)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-ov534/description
+ The OV534 USB Camera Driver (ov534) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-ov534))
+
+
+define KernelPackage/video-gspca-ov534-9
+ TITLE:=ov534-9 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_OV534_9
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_ov534_9.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_ov534_9)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-ov534-9/description
+ The OV534-9 USB Camera Driver (ov534_9) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-ov534-9))
+
+
+define KernelPackage/video-gspca-pac207
+ TITLE:=pac207 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_PAC207
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_pac207.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_pac207)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-pac207/description
+ The Pixart PAC207 USB Camera Driver (pac207) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-pac207))
+
+
+define KernelPackage/video-gspca-pac7311
+ TITLE:=pac7311 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_PAC7311
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_pac7311.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_pac7311)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-pac7311/description
+ The Pixart PAC7311 USB Camera Driver (pac7311) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-pac7311))
+
+
+define KernelPackage/video-gspca-se401
+ TITLE:=se401 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SE401
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_se401.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_se401)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-se401/description
+ The SE401 USB Camera Driver kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-se401))
+
+
+define KernelPackage/video-gspca-sn9c20x
+ TITLE:=sn9c20x webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SN9C20X
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_sn9c20x.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_sn9c20x)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-sn9c20x/description
+ The SN9C20X USB Camera Driver (sn9c20x) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-sn9c20x))
+
+
+define KernelPackage/video-gspca-sonixb
+ TITLE:=sonixb webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SONIXB
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_sonixb.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_sonixb)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-sonixb/description
+ The SONIX Bayer USB Camera Driver (sonixb) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-sonixb))
+
+
+define KernelPackage/video-gspca-sonixj
+ TITLE:=sonixj webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SONIXJ
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_sonixj.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_sonixj)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-sonixj/description
+ The SONIX JPEG USB Camera Driver (sonixj) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-sonixj))
+
+
+define KernelPackage/video-gspca-spca500
+ TITLE:=spca500 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SPCA500
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_spca500.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_spca500)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-spca500/description
+ The SPCA500 USB Camera Driver (spca500) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-spca500))
+
+
+define KernelPackage/video-gspca-spca501
+ TITLE:=spca501 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SPCA501
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_spca501.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_spca501)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-spca501/description
+ The SPCA501 USB Camera Driver (spca501) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-spca501))
+
+
+define KernelPackage/video-gspca-spca505
+ TITLE:=spca505 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SPCA505
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_spca505.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_spca505)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-spca505/description
+ The SPCA505 USB Camera Driver (spca505) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-spca505))
+
+
+define KernelPackage/video-gspca-spca506
+ TITLE:=spca506 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SPCA506
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_spca506.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_spca506)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-spca506/description
+ The SPCA506 USB Camera Driver (spca506) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-spca506))
+
+
+define KernelPackage/video-gspca-spca508
+ TITLE:=spca508 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SPCA508
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_spca508.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_spca508)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-spca508/description
+ The SPCA508 USB Camera Driver (spca508) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-spca508))
+
+
+define KernelPackage/video-gspca-spca561
+ TITLE:=spca561 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SPCA561
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_spca561.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_spca561)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-spca561/description
+ The SPCA561 USB Camera Driver (spca561) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-spca561))
+
+
+define KernelPackage/video-gspca-sq905
+ TITLE:=sq905 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SQ905
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_sq905.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_sq905)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-sq905/description
+ The SQ Technologies SQ905 based USB Camera Driver (sq905) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-sq905))
+
+
+define KernelPackage/video-gspca-sq905c
+ TITLE:=sq905c webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SQ905C
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_sq905c.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_sq905c)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-sq905c/description
+ The SQ Technologies SQ905C based USB Camera Driver (sq905c) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-sq905c))
+
+
+define KernelPackage/video-gspca-stk014
+ TITLE:=stk014 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_STK014
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_stk014.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_stk014)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-stk014/description
+ The Syntek DV4000 (STK014) USB Camera Driver (stk014) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-stk014))
+
+
+define KernelPackage/video-gspca-sunplus
+ TITLE:=sunplus webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_SUNPLUS
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_sunplus.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_sunplus)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-sunplus/description
+ The SUNPLUS USB Camera Driver (sunplus) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-sunplus))
+
+
+define KernelPackage/video-gspca-t613
+ TITLE:=t613 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_T613
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_t613.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_t613)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-t613/description
+ The T613 (JPEG Compliance) USB Camera Driver (t613) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-t613))
+
+
+define KernelPackage/video-gspca-tv8532
+ TITLE:=tv8532 webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_TV8532
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_tv8532.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_tv8532)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-tv8532/description
+ The TV8532 USB Camera Driver (tv8532) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-tv8532))
+
+
+define KernelPackage/video-gspca-vc032x
+ TITLE:=vc032x webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_VC032X
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_vc032x.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_vc032x)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-vc032x/description
+ The VC032X USB Camera Driver (vc032x) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-vc032x))
+
+
+define KernelPackage/video-gspca-zc3xx
+ TITLE:=zc3xx webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_ZC3XX
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_zc3xx.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_zc3xx)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-zc3xx/description
+ The ZC3XX USB Camera Driver (zc3xx) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-zc3xx))
+
+
+define KernelPackage/video-gspca-m5602
+ TITLE:=m5602 webcam support
+ KCONFIG:=CONFIG_USB_M5602
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/m5602/gspca_m5602.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_m5602)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-m5602/description
+ The ALi USB m5602 Camera Driver (m5602) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-m5602))
+
+
+define KernelPackage/video-gspca-stv06xx
+ TITLE:=stv06xx webcam support
+ KCONFIG:=CONFIG_USB_STV06XX
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/stv06xx/gspca_stv06xx.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_stv06xx)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-stv06xx/description
+ The STV06XX USB Camera Driver (stv06xx) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-stv06xx))
+
+
+define KernelPackage/video-gspca-gl860
+ TITLE:=gl860 webcam support
+ KCONFIG:=CONFIG_USB_GL860
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gl860/gspca_gl860.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_gl860)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-gl800/description
+ The GL860 USB Camera Driver (gl860) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-gl860))
+
+
+define KernelPackage/video-gspca-jeilinj
+ TITLE:=jeilinj webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_JEILINJ
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_jeilinj.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_jeilinj)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-jeilinj/description
+ The JEILINJ USB Camera Driver (jeilinj) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-jeilinj))
+
+
+define KernelPackage/video-gspca-konica
+ TITLE:=konica webcam support
+ KCONFIG:=CONFIG_USB_GSPCA_KONICA
+ FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/gspca/gspca_konica.ko
+ AUTOLOAD:=$(call AutoProbe,gspca_konica)
+ $(call AddDepends/camera-gspca)
+endef
+
+define KernelPackage/video-gspca-konica/description
+ The Konica USB Camera Driver (konica) kernel module
+endef
+
+$(eval $(call KernelPackage,video-gspca-konica))
diff --git a/package/kernel/linux/modules/virtual.mk b/package/kernel/linux/modules/virtual.mk
new file mode 100644
index 0000000..4464fe9
--- /dev/null
+++ b/package/kernel/linux/modules/virtual.mk
@@ -0,0 +1,188 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+VIRTUAL_MENU:=Virtualization Support
+
+define KernelPackage/virtio-balloon
+ SUBMENU:=$(VIRTUAL_MENU)
+ TITLE:=VirtIO balloon driver
+ DEPENDS:=@TARGET_x86_kvm_guest
+ KCONFIG:=CONFIG_VIRTIO_BALLOON
+ FILES:=$(LINUX_DIR)/drivers/virtio/virtio_balloon.ko
+ AUTOLOAD:=$(call AutoLoad,06,virtio-balloon)
+endef
+
+define KernelPackage/virtio-balloon/description
+ Kernel module for VirtIO memory ballooning support
+endef
+
+$(eval $(call KernelPackage,virtio-balloon))
+
+
+define KernelPackage/virtio-net
+ SUBMENU:=$(VIRTUAL_MENU)
+ TITLE:=VirtIO network driver
+ DEPENDS:=@TARGET_x86_kvm_guest
+ KCONFIG:=CONFIG_VIRTIO_NET
+ FILES:=$(LINUX_DIR)/drivers/net/virtio_net.ko
+ AUTOLOAD:=$(call AutoLoad,50,virtio_net)
+endef
+
+define KernelPackage/virtio-net/description
+ Kernel module for the VirtIO paravirtualized network device
+endef
+
+$(eval $(call KernelPackage,virtio-net))
+
+
+define KernelPackage/virtio-random
+ SUBMENU:=$(VIRTUAL_MENU)
+ TITLE:=VirtIO Random Number Generator support
+ DEPENDS:=@TARGET_x86_kvm_guest
+ KCONFIG:=CONFIG_HW_RANDOM_VIRTIO
+ FILES:=$(LINUX_DIR)/drivers/char/hw_random/virtio-rng.ko
+ AUTOLOAD:=$(call AutoLoad,09,virtio-rng)
+endef
+
+define KernelPackage/virtio-random/description
+ Kernel module for the VirtIO Random Number Generator
+endef
+
+$(eval $(call KernelPackage,virtio-random))
+
+
+define KernelPackage/xen-privcmd
+ SUBMENU:=$(VIRTUAL_MENU)
+ TITLE:=Xen private commands
+ DEPENDS:=@TARGET_x86_xen_domu
+ KCONFIG:=CONFIG_XEN_PRIVCMD
+ FILES:=$(LINUX_DIR)/drivers/xen/xen-privcmd.ko
+ AUTOLOAD:=$(call AutoLoad,04,xen-privcmd)
+endef
+
+define KernelPackage/xen-privcmd/description
+ Kernel module for Xen private commands
+endef
+
+$(eval $(call KernelPackage,xen-privcmd))
+
+
+define KernelPackage/xen-fs
+ SUBMENU:=$(VIRTUAL_MENU)
+ TITLE:=Xen filesystem
+ DEPENDS:=@TARGET_x86_xen_domu +kmod-xen-privcmd
+ KCONFIG:= \
+ CONFIG_XENFS \
+ CONFIG_XEN_COMPAT_XENFS=y
+ FILES:=$(LINUX_DIR)/drivers/xen/xenfs/xenfs.ko
+ AUTOLOAD:=$(call AutoLoad,05,xenfs)
+endef
+
+define KernelPackage/xen-fs/description
+ Kernel module for the Xen filesystem
+endef
+
+$(eval $(call KernelPackage,xen-fs))
+
+
+define KernelPackage/xen-evtchn
+ SUBMENU:=$(VIRTUAL_MENU)
+ TITLE:=Xen event channels
+ DEPENDS:=@TARGET_x86_xen_domu
+ KCONFIG:=CONFIG_XEN_DEV_EVTCHN
+ FILES:=$(LINUX_DIR)/drivers/xen/xen-evtchn.ko
+ AUTOLOAD:=$(call AutoLoad,06,xen-evtchn)
+endef
+
+define KernelPackage/xen-evtchn/description
+ Kernel module for the /dev/xen/evtchn device
+endef
+
+$(eval $(call KernelPackage,xen-evtchn))
+
+define KernelPackage/xen-fbdev
+ SUBMENU:=$(VIRTUAL_MENU)
+ TITLE:=Xen virtual frame buffer
+ DEPENDS:=@TARGET_x86_xen_domu +kmod-fb
+ KCONFIG:= \
+ CONFIG_XEN_FBDEV_FRONTEND \
+ CONFIG_FB_DEFERRED_IO=y \
+ CONFIG_FB_SYS_COPYAREA \
+ CONFIG_FB_SYS_FILLRECT \
+ CONFIG_FB_SYS_FOPS \
+ CONFIG_FB_SYS_IMAGEBLIT \
+ CONFIG_FIRMWARE_EDID=n
+ FILES:= \
+ $(LINUX_DIR)/drivers/video/fbdev/xen-fbfront.ko \
+ $(LINUX_DIR)/drivers/video/fbdev/core/syscopyarea.ko \
+ $(LINUX_DIR)/drivers/video/fbdev/core/sysfillrect.ko \
+ $(LINUX_DIR)/drivers/video/fbdev/core/fb_sys_fops.ko \
+ $(LINUX_DIR)/drivers/video/fbdev/core/sysimgblt.ko
+ AUTOLOAD:=$(call AutoLoad,07, \
+ fb \
+ syscopyarea \
+ sysfillrect \
+ fb_sys_fops \
+ sysimgblt \
+ xen-fbfront \
+ )
+endef
+
+define KernelPackage/xen-fbdev/description
+ Kernel module for the Xen virtual frame buffer
+endef
+
+$(eval $(call KernelPackage,xen-fbdev))
+
+
+define KernelPackage/xen-kbddev
+ SUBMENU:=$(VIRTUAL_MENU)
+ TITLE:=Xen virtual keyboard and mouse
+ DEPENDS:=@TARGET_x86_xen_domu +kmod-input-core
+ KCONFIG:=CONFIG_INPUT_MISC=y \
+ CONFIG_INPUT_XEN_KBDDEV_FRONTEND
+ FILES:=$(LINUX_DIR)/drivers/input/misc/xen-kbdfront.ko
+ AUTOLOAD:=$(call AutoLoad,08,xen-kbdfront)
+endef
+
+define KernelPackage/xen-kbddev/description
+ Kernel module for the Xen virtual keyboard and mouse
+endef
+
+$(eval $(call KernelPackage,xen-kbddev))
+
+
+define KernelPackage/xen-netdev
+ SUBMENU:=$(VIRTUAL_MENU)
+ TITLE:=Xen network device frontend
+ DEPENDS:=@TARGET_x86_xen_domu
+ KCONFIG:=CONFIG_XEN_NETDEV_FRONTEND
+ FILES:=$(LINUX_DIR)/drivers/net/xen-netfront.ko
+ AUTOLOAD:=$(call AutoLoad,09,xen-netfront)
+endef
+
+define KernelPackage/xen-netdev/description
+ Kernel module for the Xen network device frontend
+endef
+
+$(eval $(call KernelPackage,xen-netdev))
+
+
+define KernelPackage/xen-pcidev
+ SUBMENU:=$(VIRTUAL_MENU)
+ TITLE:=Xen PCI device frontend
+ DEPENDS:=@TARGET_x86_xen_domu
+ KCONFIG:=CONFIG_XEN_PCIDEV_FRONTEND
+ FILES:=$(LINUX_DIR)/drivers/pci/xen-pcifront.ko
+ AUTOLOAD:=$(call AutoLoad,10,xen-pcifront)
+endef
+
+define KernelPackage/xen-pcidev/description
+ Kernel module for the Xen network device frontend
+endef
+
+$(eval $(call KernelPackage,xen-pcidev))
diff --git a/package/kernel/linux/modules/w1.mk b/package/kernel/linux/modules/w1.mk
new file mode 100644
index 0000000..196fe67
--- /dev/null
+++ b/package/kernel/linux/modules/w1.mk
@@ -0,0 +1,192 @@
+#
+# Copyright (C) 2008-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+W1_MENU:=W1 support
+W1_MASTERS_DIR:=$(LINUX_DIR)/drivers/w1/masters
+W1_SLAVES_DIR:=$(LINUX_DIR)/drivers/w1/slaves
+
+define KernelPackage/w1
+ SUBMENU:=$(W1_MENU)
+ TITLE:=Dallas's 1-wire support
+ KCONFIG:=CONFIG_W1
+ FILES:=$(LINUX_DIR)/drivers/w1/wire.ko
+endef
+
+define KernelPackage/w1/description
+ Kernel module for Dallas's 1-wire support
+endef
+
+$(eval $(call KernelPackage,w1))
+
+
+define AddDepends/w1
+ SUBMENU:=$(W1_MENU)
+ DEPENDS+=kmod-w1 $(1)
+endef
+
+
+#
+# 1-wire masters
+#
+define KernelPackage/w1-master-gpio
+ TITLE:=GPIO 1-wire bus master driver
+ DEPENDS:=@GPIO_SUPPORT
+ KCONFIG:=CONFIG_W1_MASTER_GPIO
+ FILES:=$(W1_MASTERS_DIR)/w1-gpio.ko
+ AUTOLOAD:=$(call AutoProbe,w1-gpio)
+ $(call AddDepends/w1)
+endef
+
+define KernelPackage/w1-master-gpio/description
+ Kernel module for the GPIO 1-wire bus master driver
+endef
+
+$(eval $(call KernelPackage,w1-master-gpio))
+
+define KernelPackage/w1-master-ds2482
+ TITLE:=DS2482 1-wire i2c bus master driver
+ KCONFIG:=CONFIG_W1_MASTER_DS2482
+ FILES:=$(W1_MASTERS_DIR)/ds2482.ko
+ AUTOLOAD:=$(call AutoProbe,ds2482)
+ $(call AddDepends/w1,+kmod-i2c-core)
+endef
+
+define KernelPackage/w1-master-ds2482/description
+ Kernel module for the DS2482 i2c 1-wire bus master driver
+ NOTE: Init with: echo ds2482 0x18 > /sys/bus/i2c/devices/i2c-0/new_device
+ or use owfs
+endef
+
+$(eval $(call KernelPackage,w1-master-ds2482))
+
+
+define KernelPackage/w1-master-ds2490
+ TITLE:=DS2490 1-wire usb bus master driver
+ DEPENDS:=@USB_SUPPORT +kmod-usb-core
+ KCONFIG:=CONFIG_W1_MASTER_DS2490
+ FILES:=$(W1_MASTERS_DIR)/ds2490.ko
+ AUTOLOAD:=$(call AutoProbe,ds2490)
+ $(call AddDepends/w1)
+endef
+
+define KernelPackage/w1-master-ds2490/description
+ Kernel module for the DS2490 usb 1-wire bus master driver
+endef
+
+$(eval $(call KernelPackage,w1-master-ds2490))
+
+
+define KernelPackage/w1-master-mxc
+ TITLE:=Freescale MXC 1-wire busmaster
+ DEPENDS:=@(TARGET_mxs||TARGET_imx6)
+ KCONFIG:=CONFIG_W1_MASTER_MXC
+ FILES:=$(W1_MASTERS_DIR)/mxc_w1.ko
+ AUTOLOAD:=$(call AutoProbe,mxc_w1)
+ $(call AddDepends/w1)
+endef
+
+define KernelPackage/w1-master-mxc/description
+ Kernel module for 1-wire Freescale MXC 1-wire busmaster
+endef
+
+$(eval $(call KernelPackage,w1-master-mxc))
+
+
+#
+# 1-wire slaves
+#
+define KernelPackage/w1-slave-therm
+ TITLE:=Thermal family implementation
+ KCONFIG:=CONFIG_W1_SLAVE_THERM
+ FILES:=$(W1_SLAVES_DIR)/w1_therm.ko
+ AUTOLOAD:=$(call AutoProbe,w1_therm)
+ $(call AddDepends/w1)
+endef
+
+define KernelPackage/w1-slave-therm/description
+ Kernel module for 1-wire thermal sensors
+endef
+
+$(eval $(call KernelPackage,w1-slave-therm))
+
+
+define KernelPackage/w1-slave-smem
+ TITLE:=Simple 64bit memory family implementation
+ KCONFIG:=CONFIG_W1_SLAVE_SMEM
+ FILES:=$(W1_SLAVES_DIR)/w1_smem.ko
+ AUTOLOAD:=$(call AutoProbe,w1_smem)
+ $(call AddDepends/w1)
+endef
+
+define KernelPackage/w1-slave-smem/description
+ Kernel module for 1-wire simple 64bit memory rom(ds2401/ds2411/ds1990*)
+endef
+
+$(eval $(call KernelPackage,w1-slave-smem))
+
+define KernelPackage/w1-slave-ds2431
+ TITLE:=DS2431 1kb EEPROM driver
+ KCONFIG:= CONFIG_W1_SLAVE_DS2431
+ FILES:=$(W1_SLAVES_DIR)/w1_ds2431.ko
+ AUTOLOAD:=$(call AutoProbe,w1_ds2431)
+ $(call AddDepends/w1)
+endef
+
+define KernelPackage/w1-slave-ds2431/description
+ Kernel module for 1-wire 1kb EEPROM (DS2431)
+endef
+
+$(eval $(call KernelPackage,w1-slave-ds2431))
+
+define KernelPackage/w1-slave-ds2433
+ TITLE:=DS2433 4kb EEPROM driver
+ KCONFIG:= \
+ CONFIG_W1_SLAVE_DS2433 \
+ CONFIG_W1_SLAVE_DS2433_CRC=n
+ FILES:=$(W1_SLAVES_DIR)/w1_ds2433.ko
+ AUTOLOAD:=$(call AutoProbe,w1_ds2433)
+ $(call AddDepends/w1)
+endef
+
+define KernelPackage/w1-slave-ds2433/description
+ Kernel module for 1-wire 4kb EEPROM (DS2433)
+endef
+
+$(eval $(call KernelPackage,w1-slave-ds2433))
+
+
+define KernelPackage/w1-slave-ds2760
+ TITLE:=Dallas 2760 battery monitor chip (HP iPAQ & others)
+ KCONFIG:= \
+ CONFIG_W1_SLAVE_DS2760 \
+ CONFIG_W1_SLAVE_DS2433_CRC=n
+ FILES:=$(W1_SLAVES_DIR)/w1_ds2760.ko
+ AUTOLOAD:=$(call AutoProbe,w1_ds2760)
+ $(call AddDepends/w1)
+endef
+
+define KernelPackage/w1-slave-ds2760/description
+ Kernel module for 1-wire DS2760 battery monitor chip support
+endef
+
+$(eval $(call KernelPackage,w1-slave-ds2760))
+
+
+define KernelPackage/w1-slave-ds2413
+ TITLE:=DS2413 2 Ch. Addressable Switch
+ KCONFIG:= \
+ CONFIG_W1_SLAVE_DS2413
+ FILES:=$(W1_SLAVES_DIR)/w1_ds2413.ko
+ AUTOLOAD:=$(call AutoProbe,w1_ds2413)
+ $(call AddDepends/w1)
+endef
+
+define KernelPackage/w1-slave-ds2413/description
+ Kernel module for 1-wire DS2413 Dual Channel Addressable Switch support
+endef
+
+$(eval $(call KernelPackage,w1-slave-ds2413))
diff --git a/package/kernel/linux/modules/wireless.mk b/package/kernel/linux/modules/wireless.mk
new file mode 100644
index 0000000..2627b57
--- /dev/null
+++ b/package/kernel/linux/modules/wireless.mk
@@ -0,0 +1,106 @@
+#
+# Copyright (C) 2006-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+WIRELESS_MENU:=Wireless Drivers
+
+define KernelPackage/net-airo
+ SUBMENU:=$(WIRELESS_MENU)
+ TITLE:=Cisco Aironet driver
+ DEPENDS:=@PCI_SUPPORT +@DRIVER_WEXT_SUPPORT
+ KCONFIG:=CONFIG_AIRO
+ FILES:=$(LINUX_DIR)/drivers/net/wireless/airo.ko
+ AUTOLOAD:=$(call AutoProbe,airo)
+endef
+
+define KernelPackage/net-airo/description
+ Kernel support for Cisco Aironet cards
+endef
+
+$(eval $(call KernelPackage,net-airo))
+
+
+define KernelPackage/net-prism54
+ SUBMENU:=$(WIRELESS_MENU)
+ TITLE:=Intersil Prism54 support
+ DEPENDS:=@PCI_SUPPORT +@DRIVER_WEXT_SUPPORT
+ KCONFIG:=CONFIG_PRISM54
+ FILES:=$(LINUX_DIR)/drivers/net/wireless/prism54/prism54.ko
+ AUTOLOAD:=$(call AutoProbe,prism54)
+endef
+
+define KernelPackage/net-prism54/description
+ Kernel modules for Intersil Prism54 support
+endef
+
+# Prism54 FullMAC firmware (jbnore.free.fr seems to be rather slow, so we use daemonizer.de)
+PRISM54_FW:=1.0.4.3.arm
+
+define Download/net-prism54
+ FILE:=$(PRISM54_FW)
+ URL:=http://daemonizer.de/prism54/prism54-fw/fw-fullmac/
+ MD5SUM:=8bd4310971772a486b9784c77f8a6df9
+endef
+
+define KernelPackage/net-prism54/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(DL_DIR)/$(PRISM54_FW) $(1)/lib/firmware/isl3890
+endef
+
+$(eval $(call Download,net-prism54))
+$(eval $(call KernelPackage,net-prism54))
+
+define KernelPackage/net-rtl8188eu
+ SUBMENU:=$(WIRELESS_MENU)
+ TITLE:=RTL8188EU support (staging)
+ DEPENDS:=@USB_SUPPORT +@DRIVER_WEXT_SUPPORT +r8188eu-firmware +kmod-usb-core
+ KCONFIG:=\
+ CONFIG_STAGING=y \
+ CONFIG_R8188EU \
+ CONFIG_88EU_AP_MODE=y \
+ CONFIG_88EU_P2P=n
+ FILES:=$(LINUX_DIR)/drivers/staging/rtl8188eu/r8188eu.ko
+ AUTOLOAD:=$(call AutoProbe,r8188eu)
+endef
+
+define KernelPackage/net-rtl8188eu/description
+ Kernel modules for RealTek RTL8188EU support
+endef
+
+$(eval $(call KernelPackage,net-rtl8188eu))
+
+define KernelPackage/net-rtl8192su
+ SUBMENU:=$(WIRELESS_MENU)
+ TITLE:=RTL8192SU support (staging)
+ DEPENDS:=@USB_SUPPORT +@DRIVER_WEXT_SUPPORT +kmod-usb-core
+ KCONFIG:=\
+ CONFIG_STAGING=y \
+ CONFIG_R8712U
+ FILES:=$(LINUX_DIR)/drivers/staging/rtl8712/r8712u.ko
+ AUTOLOAD:=$(call AutoProbe,r8712u)
+endef
+
+define KernelPackage/net-rtl8192su/description
+ Kernel modules for RealTek RTL8712 and RTL81XXSU fullmac support.
+endef
+
+# R8712 FullMAC firmware
+R8712_FW:=rtl8712u.bin
+
+define Download/net-rtl8192su
+ FILE:=$(R8712_FW)
+
+ URL:=http://mirrors.arizona.edu/raspbmc/downloads/bin/lib/wifi/rtlwifi/
+ MD5SUM:=8e6396b5844a3e279ae8679555dec3f0
+endef
+
+define KernelPackage/net-rtl8192su/install
+ $(INSTALL_DIR) $(1)/lib/firmware/rtlwifi
+ $(INSTALL_DATA) $(DL_DIR)/$(R8712_FW) $(1)/lib/firmware/rtlwifi/
+endef
+
+$(eval $(call Download,net-rtl8192su))
+$(eval $(call KernelPackage,net-rtl8192su))
diff --git a/package/kernel/linux/modules/wpan.mk b/package/kernel/linux/modules/wpan.mk
new file mode 100644
index 0000000..8cb1bfc
--- /dev/null
+++ b/package/kernel/linux/modules/wpan.mk
@@ -0,0 +1,122 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+WPAN_MENU:=WPAN 802.15.4 Support
+
+define KernelPackage/ieee802154
+ SUBMENU:=$(WPAN_MENU)
+ TITLE:=IEEE-802.15.4 support
+ DEPENDS:=@!LINUX_3_18
+ KCONFIG:= \
+ CONFIG_IEEE802154 \
+ CONFIG_IEEE802154_SOCKET=y
+ FILES:= \
+ $(LINUX_DIR)/net/ieee802154/ieee802154.ko \
+ $(LINUX_DIR)/net/ieee802154/ieee802154_socket.ko@ge4.0
+ AUTOLOAD:=$(call AutoLoad,90,ieee802154 ieee802154_socket)
+endef
+
+define KernelPackage/ieee802154/description
+ IEEE Std 802.15.4 defines a low data rate, low power and low
+ complexity short range wireless personal area networks. It was
+ designed to organise networks of sensors, switches, etc automation
+ devices. Maximum allowed data rate is 250 kb/s and typical personal
+ operating space around 10m.
+endef
+
+$(eval $(call KernelPackage,ieee802154))
+
+define KernelPackage/mac802154
+ SUBMENU:=$(WPAN_MENU)
+ TITLE:=MAC-802.15.4 support
+ DEPENDS:=+kmod-ieee802154 +kmod-crypto-aead +kmod-lib-crc-ccitt @!LINUX_3_18
+ KCONFIG:= \
+ CONFIG_MAC802154 \
+ CONFIG_IEEE802154_DRIVERS=y
+ FILES:=$(LINUX_DIR)/net/mac802154/mac802154.ko
+ AUTOLOAD:=$(call AutoLoad,91,mac802154)
+endef
+
+define KernelPackage/mac802154/description
+ This option enables the hardware independent IEEE 802.15.4
+ networking stack for SoftMAC devices (the ones implementing
+ only PHY level of IEEE 802.15.4 standard).
+
+ Note: this implementation is neither certified, nor feature
+ complete! Compatibility with other implementations hasn't
+ been tested yet!
+endef
+
+$(eval $(call KernelPackage,mac802154))
+
+define KernelPackage/fakelb
+ SUBMENU:=$(WPAN_MENU)
+ TITLE:=Fake LR-WPAN driver
+ DEPENDS:=+kmod-mac802154 @!LINUX_3_18
+ KCONFIG:=CONFIG_IEEE802154_FAKELB
+ FILES:=$(LINUX_DIR)/drivers/net/ieee802154/fakelb.ko
+ AUTOLOAD:=$(call AutoLoad,92,fakelb)
+endef
+
+define KernelPackage/fakelb/description
+ Say Y here to enable the fake driver that can emulate a net
+ of several interconnected radio devices.
+endef
+
+$(eval $(call KernelPackage,fakelb))
+
+define KernelPackage/at86rf230
+ SUBMENU:=$(WPAN_MENU)
+ TITLE:=AT86RF230 transceiver driver
+ DEPENDS:=+kmod-mac802154 +kmod-regmap
+ KCONFIG:=CONFIG_IEEE802154_AT86RF230 \
+ CONFIG_SPI=y \
+ CONFIG_SPI_MASTER=y
+ FILES:=$(LINUX_DIR)/drivers/net/ieee802154/at86rf230.ko
+endef
+
+$(eval $(call KernelPackage,at86rf230))
+
+define KernelPackage/mrf24j40
+ SUBMENU:=$(WPAN_MENU)
+ TITLE:=MRF24J40 transceiver driver
+ DEPENDS:=+kmod-mac802154
+ KCONFIG:=CONFIG_IEEE802154_MRF24J40 \
+ CONFIG_SPI=y \
+ CONFIG_SPI_MASTER=y
+ FILES:=$(LINUX_DIR)/drivers/net/ieee802154/mrf24j40.ko
+endef
+
+$(eval $(call KernelPackage,mrf24j40))
+
+define KernelPackage/cc2520
+ SUBMENU:=$(WPAN_MENU)
+ TITLE:=CC2520 transceiver driver
+ DEPENDS:=+kmod-mac802154
+ KCONFIG:=CONFIG_IEEE802154_CC2520 \
+ CONFIG_SPI=y \
+ CONFIG_SPI_MASTER=y
+ FILES:=$(LINUX_DIR)/drivers/net/ieee802154/cc2520.ko
+endef
+
+$(eval $(call KernelPackage,cc2520))
+
+define KernelPackage/ieee802154_6lowpan
+ SUBMENU:=$(WPAN_MENU)
+ TITLE:= 6LoWPAN support over IEEE-802.15.4
+ DEPENDS:=@!LINUX_3_18 +kmod-6lowpan +kmod-ieee802154
+ KCONFIG:=CONFIG_IEEE802154_6LOWPAN
+ FILES:= \
+ $(LINUX_DIR)/net/ieee802154/6lowpan/ieee802154_6lowpan.ko@ge4.0 \
+ $(LINUX_DIR)/net/ieee802154/ieee802154_6lowpan.ko@lt4.0
+ AUTOLOAD:=$(call AutoLoad,91,ieee802154_6lowpan)
+endef
+
+define KernelPackage/ieee802154_6lowpan/description
+ IPv6 compression over IEEE 802.15.4
+endef
+
+$(eval $(call KernelPackage,ieee802154_6lowpan))
diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile
new file mode 100644
index 0000000..580b2c3
--- /dev/null
+++ b/package/kernel/mac80211/Makefile
@@ -0,0 +1,2154 @@
+#
+# Copyright (C) 2007-2015 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:=2015-10-26
+PKG_RELEASE:=1
+PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
+PKG_BACKPORT_VERSION:=
+PKG_MD5SUM:=3b07569065a18c6a69a340ea50235b7d
+
+PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_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 \
+ ath ath5k ath9k ath9k-common ath9k-htc ath10k \
+ b43 b43legacy \
+ carl9170 \
+ hermes hermes-pci hermes-pcmcia hermes-plx\
+ iwl-legacy iwl3945 iwl4965 iwlwifi \
+ lib80211 \
+ libipw ipw2100 ipw2200 \
+ libertas-sdio libertas-usb \
+ mac80211-hwsim \
+ mt7601u \
+ mwl8k mwifiex-pcie \
+ p54-common p54-pci p54-spi p54-usb \
+ rt2x00-lib rt2x00-pci rt2x00-usb \
+ rt2400-pci rt2500-pci rt2500-usb \
+ rt2800-lib rt2800-mmio rt2800-pci rt2800-soc rt2800-usb \
+ rt61-pci rt73-usb \
+ rtl8180 rtl8187 \
+ rtlwifi rtlwifi-pci rtlwifi-usb rtl8192c-common rtl8192ce rtl8192se \
+ rtl8192de rtl8192cu \
+ wlcore wl12xx wl18xx \
+ zd1211rw
+
+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_ATH_DFS \
+ CONFIG_PACKAGE_B43_DEBUG \
+ CONFIG_PACKAGE_B43_PIO \
+ CONFIG_PACKAGE_B43_PHY_G \
+ CONFIG_PACKAGE_B43_PHY_N \
+ CONFIG_PACKAGE_B43_PHY_LP \
+ CONFIG_PACKAGE_B43_PHY_HT \
+ CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB \
+ CONFIG_PACKAGE_B43_BUSES_BCMA \
+ CONFIG_PACKAGE_B43_BUSES_SSB \
+ CONFIG_PACKAGE_RTLWIFI_DEBUG \
+ CONFIG_ATH_USER_REGD \
+
+include $(INCLUDE_DIR)/package.mk
+
+WMENU:=Wireless Drivers
+
+define KernelPackage/mac80211/Default
+ SUBMENU:=$(WMENU)
+ URL:=https://wireless.wiki.kernel.org/
+ MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+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
+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-cfg80211 +hostapd-common
+ KCONFIG:=\
+ CONFIG_AVERAGE=y
+ FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko
+ 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
+ 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:=6ebf5d57d9f6d0cf05558baef1af2b90a3fe98ed
+PKG_LINUX_FIRMWARE_SOURCE:=$(PKG_LINUX_FIRMWARE_NAME)-2015-09-03-$(PKG_LINUX_FIRMWARE_VERSION).tar.xz
+PKG_LINUX_FIRMWARE_PROTO:=git
+PKG_LINUX_FIRMWARE_SOURCE_URL:=https://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:=e219333f01835c6e556875a9e0deb3f9
+
+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))
+
+
+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 AutoProbe,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.
+ Only ath9k & ath10k make use of this.
+
+ config PACKAGE_ATH_DFS
+ bool "Enable DFS support"
+ default y
+ help
+ Dynamic frequency selection (DFS) is required for most of the 5 GHz band
+ channels in Europe, US, and Japan.
+
+ Select this option if you want to use such channels.
+
+ endif
+endef
+
+define KernelPackage/ath
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Atheros common driver part
+ DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx||TARGET_ath25 +kmod-mac80211
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath.ko
+ 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:=https://wireless.wiki.kernel.org/en/users/drivers/ath5k
+ DEPENDS+= @PCI_SUPPORT||@TARGET_ath25 +kmod-ath
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath5k/ath5k.ko
+ AUTOLOAD:=$(call AutoProbe,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:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k
+ DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT +@KERNEL_RELAY
+ FILES:= \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_common.ko \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_hw.ko
+endef
+
+define KernelPackage/ath9k
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Atheros 802.11n PCI wireless cards support
+ URL:=https://wireless.wiki.kernel.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 AutoProbe,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/config
+
+ config ATH9K_SUPPORT_PCOEM
+ bool "Support chips used in PC OEM cards"
+ depends on PACKAGE_kmod-ath9k
+
+endef
+
+define KernelPackage/ath9k-htc
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Atheros 802.11n USB device support
+ URL:=https://wireless.wiki.kernel.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 AutoProbe,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/ath10k
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Atheros 802.11ac wireless cards support
+ URL:=https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
+ DEPENDS+= @PCI_SUPPORT +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT
+ FILES:= \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_core.ko \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_pci.ko
+ AUTOLOAD:=$(call AutoLoad,55,ath10k_core ath10k_pci)
+endef
+
+define KernelPackage/ath10k/description
+This module adds support for wireless adapters based on
+Atheros IEEE 802.11ac family of chipsets. For now only
+PCI is supported.
+endef
+
+#Broadcom firmware
+ifneq ($(CONFIG_B43_FW_6_30),)
+ PKG_B43_FWV4_NAME:=broadcom-wl
+ PKG_B43_FWV4_VERSION:=6.30.163.46
+ PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).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:=6fe97e9368d25342a1ab943d3cf3496d
+else
+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
+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:=https://wireless.wiki.kernel.org/en/users/drivers/b43
+ KCONFIG:= \
+ CONFIG_HW_RANDOM=y
+ # Depend on PCI_SUPPORT to make sure we can select kmod-bcma or kmod-ssb
+ DEPENDS += \
+ @PCI_SUPPORT +kmod-mac80211 \
+ $(if $(CONFIG_PACKAGE_B43_USE_SSB),+kmod-ssb) \
+ $(if $(CONFIG_PACKAGE_B43_USE_BCMA),+kmod-bcma)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/b43/b43.ko
+ AUTOLOAD:=$(call AutoProbe,b43)
+ MENU:=1
+endef
+
+define KernelPackage/b43/config
+
+config PACKAGE_B43_USE_SSB
+ select PACKAGE_kmod-ssb
+ tristate
+ depends on !TARGET_brcm47xx && !TARGET_brcm63xx
+ default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB
+ default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_SSB
+
+config PACKAGE_B43_USE_BCMA
+ select PACKAGE_kmod-bcma
+ tristate
+ depends on !TARGET_brcm47xx && !TARGET_bcm53xx
+ default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB
+ default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA
+
+ 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
+ Old 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
+ Older firmware for BCM43xx devices.
+
+ If unsure, select the "stable" firmware.
+
+ config B43_FW_5_10
+ bool "Firmware 508.1084 from driver 5.10.56.27"
+ help
+ Older firmware for BCM43xx devices.
+
+ If unsure, select the "stable" firmware.
+
+ config B43_FW_5_100_138
+ bool "Firmware 666.2 from driver 5.100.138 (stable)"
+ help
+ The currently default firmware for BCM43xx devices.
+
+ This firmware currently gets most of the testing and is needed for some N-PHY devices.
+
+ If unsure, select the this firmware.
+
+ config B43_FW_6_30
+ bool "Firmware 784.2 from driver 6.30.163.46 (experimental)"
+ help
+ Newer experimental firmware for BCM43xx devices.
+
+ This firmware is mostly untested.
+
+ 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" if TARGET_brcm47xx_legacy
+ default "16,28,29,30" if TARGET_brcm47xx_mips74k
+ default "5,6,7,8,9,10,11,13,15,16,28,29,30"
+ 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,N,LP" if TARGET_brcm47xx_legacy
+ default "N,HT" if TARGET_brcm47xx_mips74k
+ default "G,N,LP,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
+ LCN40 => LCN40-PHY
+ AC => AC-PHY
+
+ Example (keep files for G-PHY only):
+ G
+
+ Example (keep files for G-PHY and N-PHY):
+ G,N
+
+ choice
+ prompt "Supported buses"
+ default PACKAGE_B43_BUSES_BCMA_AND_SSB
+ help
+ This allows choosing buses that b43 should support.
+
+ config PACKAGE_B43_BUSES_BCMA_AND_SSB
+ depends on !TARGET_brcm47xx_legacy && !TARGET_brcm47xx_mips74k && !TARGET_bcm53xx
+ bool "BCMA and SSB"
+
+ config PACKAGE_B43_BUSES_BCMA
+ depends on !TARGET_brcm47xx_legacy
+ bool "BCMA only"
+
+ config PACKAGE_B43_BUSES_SSB
+ depends on !TARGET_brcm47xx_mips74k && !TARGET_bcm53xx
+ bool "SSB only"
+
+ endchoice
+
+ 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_G
+ bool "Enable support for G-PHYs"
+ default n if TARGET_brcm47xx_mips74k
+ default y
+ help
+ Enable support for G-PHY. This includes support for the following devices:
+ PCI: BCM4306, BCM4311, BCM4318
+ SoC: BCM5352E, BCM4712
+
+ If unsure, say Y.
+
+ 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_LP
+ bool "Enable support for LP-PHYs"
+ default n if TARGET_brcm47xx_mips74k
+ default y
+ help
+ Enable support for LP-PHY. This includes support for the following devices:
+ PCI: BCM4312
+ SoC: BCM5354
+
+ If unsure, say Y.
+
+ config PACKAGE_B43_PHY_HT
+ bool "Enable support for HT-PHYs"
+ default n if TARGET_brcm47xx_legacy
+ 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:=https://wireless.wiki.kernel.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 AutoProbe,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:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211
+ DEPENDS+=@PCI_SUPPORT||USB_SUPPORT
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/brcm80211/brcmutil/brcmutil.ko
+ AUTOLOAD:=$(call AutoProbe,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:=https://wireless.wiki.kernel.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 AutoProbe,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:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211
+ DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +@DRIVER_11N_SUPPORT +kmod-brcmutil +BRCMFMAC_SDIO:kmod-mmc +BRCMFMAC_USB:kmod-usb-core
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/brcm80211/brcmfmac/brcmfmac.ko
+ AUTOLOAD:=$(call AutoProbe,brcmfmac)
+endef
+
+define KernelPackage/brcmfmac/description
+ Kernel module for Broadcom IEEE802.11n USB Wireless cards
+endef
+
+define KernelPackage/brcmfmac/config
+ if PACKAGE_kmod-brcmfmac
+
+ config BRCMFMAC_SDIO
+ bool "Enable SDIO bus interface support"
+ default n
+ help
+ Enable support for cards attached to an SDIO bus.
+ Select this option only if you are sure that your
+ board has a Broadcom wireless chip atacched to
+ that bus.
+
+ config BRCMFMAC_USB
+ bool "Enable USB bus interface support"
+ depends on USB_SUPPORT
+ default y
+ help
+ Supported USB connected chipsets:
+ BCM43235, BCM43236, BCM43238 (all in revision 3 only)
+ BCM43143, BCM43242, BCM43566, BCM43569
+
+ config BRCMFMAC_PCIE
+ bool "Enable PCIE bus interface support"
+ depends on PCI_SUPPORT
+ default y
+ help
+ Supported PCIe connected chipsets:
+ BCM4354, BCM4356, BCM43567, BCM43570, BCM43602
+
+ endif
+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 AutoProbe,carl9170)
+endef
+
+
+define KernelPackage/hermes
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Hermes 802.11b chipset support
+ DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT +kmod-crypto-michael-mic
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/orinoco/orinoco.ko
+ AUTOLOAD:=$(call AutoProbe,orinoco)
+endef
+
+define KernelPackage/hermes/description
+ Kernel support for Hermes 802.11b chipsets
+endef
+
+define KernelPackage/hermes-pci
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Intersil Prism 2.5 PCI support
+ DEPENDS:=@PCI_SUPPORT +kmod-hermes
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/orinoco/orinoco_pci.ko
+ AUTOLOAD:=$(call AutoProbe,orinoco_pci)
+endef
+
+define KernelPackage/hermes-pci/description
+ Kernel modules for Intersil Prism 2.5 PCI support
+endef
+
+define KernelPackage/hermes-plx
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=PLX9052 based PCI adaptor
+ DEPENDS:=@PCI_SUPPORT +kmod-hermes
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/orinoco/orinoco_plx.ko
+ AUTOLOAD:=$(call AutoProbe,orinoco_plx)
+endef
+
+define KernelPackage/hermes-plx/description
+ Kernel modules for Hermes in PLX9052 based PCI adaptors
+endef
+
+define KernelPackage/hermes-pcmcia
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Hermes based PCMCIA adaptors
+ DEPENDS:=@PCMCIA_SUPPORT +kmod-hermes @BROKEN
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/orinoco/orinoco_cs.ko
+ AUTOLOAD:=$(call AutoProbe,orinoco_cs)
+endef
+
+define KernelPackage/hermes-pcmcia/description
+ Kernel modules for Hermes based PCMCIA adaptors
+endef
+
+
+define KernelPackage/iwlwifi
+ $(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 \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/iwlwifi/dvm/iwldvm.ko \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/iwlwifi/mvm/iwlmvm.ko
+ AUTOLOAD:=$(call AutoProbe,iwlwifi iwldvm iwlmvm)
+ MENU:=1
+endef
+
+define KernelPackage/iwlwifi/description
+ iwlwifi kernel module for
+ Intel Wireless WiFi Link 6250AGN Adapter
+ Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN)
+ Intel WiFi Link 1000BGN
+ Intel Wireless WiFi 5150AGN
+ Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN
+ Intel 6005 Series Wi-Fi Adapters
+ Intel 6030 Series Wi-Fi Adapters
+ Intel Wireless WiFi Link 6150BGN 2 Adapter
+ Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN)
+ Intel 2000 Series Wi-Fi Adapters
+ Intel 7260 Wi-Fi Adapter
+ Intel 3160 Wi-Fi Adapter
+ Intel 7265 Wi-Fi Adapter
+ Intel 8260 Wi-Fi Adapter
+ Intel 3165 Wi-Fi Adapter
+endef
+
+define KernelPackage/iwlwifi/config
+ if PACKAGE_kmod-iwlwifi
+
+ config PACKAGE_IWLWIFI_DEBUG
+ bool "Enable full debugging output in the iwlwifi driver"
+ default n
+ help
+ This option will enable debug tracing output for the iwlwifi drivers
+
+ This will result in the kernel module being ~100k larger. You can
+ control which debug output is sent to the kernel log by setting the
+ value in
+
+ /sys/module/iwlwifi/parameters/debug
+
+ This entry will only exist if this option is enabled.
+
+ To set a value, simply echo an 8-byte hex value to the same file:
+
+ % echo 0x43fff > /sys/module/iwlwifi/parameters/debug
+
+ You can find the list of debug mask values in:
+ drivers/net/wireless/iwlwifi/iwl-debug.h
+
+ If this is your first time using this driver, you should say Y here
+ as the debug information can assist others in helping you resolve
+ any problems you may encounter.
+
+ config PACKAGE_IWLWIFI_DEBUGFS
+ bool "iwlwifi debugfs support"
+ depends on PACKAGE_MAC80211_DEBUGFS
+ default n
+ help
+ Enable creation of debugfs files for the iwlwifi drivers. This
+ is a low-impact option that allows getting insight into the
+ driver's state at runtime.
+
+ config IWL100_FW
+ bool "Intel 100 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Wireless-N 100
+
+ config IWL1000_FW
+ bool "Intel 1000 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Wireless-N 1000
+
+ 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
+
+ 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 IWL3160_FW
+ bool "Intel 3160 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Wireless WiFi 3160
+
+ 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 IWL6000_FW
+ bool "Intel 6000 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Centrino Ultimate-N 6300 and Advanced-N 6200
+
+ 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 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 IWL7260_FW
+ bool "Intel 7260 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Dual Band Wireless-N 7260 and Intel Dual Band Wireless-AC 7260
+
+ config IWL7265_FW
+ bool "Intel 7265 Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Wireless 7265, 7265D, 3165
+
+ config IWL8000_FW
+ bool "Intel 8000 Series Firmware"
+ default y
+ help
+ Download and install firmware for:
+ Intel Wireless Series 8260, 4165
+
+ 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 AutoProbe,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 AutoProbe,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 AutoProbe,iwl4965)
+endef
+
+define KernelPackage/iwl4965/description
+ iwl4965 kernel module for Intel 4965 support
+endef
+
+
+define KernelPackage/lib80211
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=802.11 Networking stack
+ DEPENDS:=+kmod-cfg80211
+ 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 AutoProbe, \
+ 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/libipw
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=libipw for ipw2100 and ipw2200
+ DEPENDS:=@PCI_SUPPORT +kmod-crypto-michael-mic +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT @!BIG_ENDIAN
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ipw2x00/libipw.ko
+ AUTOLOAD:=$(call AutoProbe,libipw)
+endef
+
+define KernelPackage/libipw/description
+ Hardware independent IEEE 802.11 networking stack for ipw2100 and ipw2200.
+endef
+
+IPW2100_NAME:=ipw2100-fw
+IPW2100_VERSION:=1.3
+
+define Download/ipw2100
+ URL:=http://bughost.org/firmware/
+ FILE:=$(IPW2100_NAME)-$(IPW2100_VERSION).tgz
+ MD5SUM=46aa75bcda1a00efa841f9707bbbd113
+endef
+$(eval $(call Download,ipw2100))
+
+define KernelPackage/ipw2100
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Intel IPW2100 driver
+ DEPENDS:=@PCI_SUPPORT +kmod-libipw
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ipw2x00/ipw2100.ko
+ AUTOLOAD:=$(call AutoProbe,ipw2100)
+endef
+
+define KernelPackage/ipw2100/description
+ Kernel support for Intel IPW2100
+ Includes:
+ - ipw2100
+endef
+
+IPW2200_NAME:=ipw2200-fw
+IPW2200_VERSION:=3.1
+
+define Download/ipw2200
+ URL:=http://bughost.org/firmware/
+ FILE:=$(IPW2200_NAME)-$(IPW2200_VERSION).tgz
+ MD5SUM=eaba788643c7cc7483dd67ace70f6e99
+endef
+$(eval $(call Download,ipw2200))
+
+define KernelPackage/ipw2200
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Intel IPW2200 driver
+ DEPENDS:=@PCI_SUPPORT +kmod-libipw
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ipw2x00/ipw2200.ko
+ AUTOLOAD:=$(call AutoProbe,ipw2200)
+endef
+
+define KernelPackage/ipw2200/description
+ Kernel support for Intel IPW2200
+ Includes:
+ - ipw2200
+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 AutoProbe,libertas usb8xxx)
+endef
+
+define KernelPackage/libertas-sdio
+ $(call KernelPackage/mac80211/Default)
+ DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +kmod-mmc +@DRIVER_WEXT_SUPPORT @!TARGET_uml
+ 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 AutoProbe,libertas libertas_sdio)
+endef
+
+define KernelPackage/mac80211-hwsim
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=mac80211 HW simulation device
+ DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mac80211_hwsim.ko
+ AUTOLOAD:=$(call AutoProbe,mac80211_hwsim)
+endef
+
+PKG_MT7601U_FW_NAME:=DPO_MT7601U_LinuxSTA
+PKG_MT7601U_FW_VERSION:=3.0.0.4_20130913
+PKG_MT7601U_FW_MD5SUM:=5f440dccc8bc952745a191994fc34699
+PKG_MT7601U_FW_SOURCE:=$(PKG_MT7601U_FW_NAME)_$(PKG_MT7601U_FW_VERSION).tar.bz2
+PKG_MT7601U_FW_SOURCE_URL:=http://www.mediatek.com/AmazonS3/Downloads/linux/
+define Download/mt7601u-firmware
+ FILE:=$(PKG_MT7601U_FW_SOURCE)
+ URL:=$(PKG_MT7601U_FW_SOURCE_URL)
+ MD5SUM:=$(PKG_MT7601U_FW_MD5SUM)
+ SUBDIR:=$(PKG_MT7601U_FW_NAME)_$(PKG_MT7601U_FW_VERSION)
+endef
+$(eval $(call Download,mt7601u-firmware))
+
+define KernelPackage/mt7601u
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=MT7601U-based USB dongles Wireless Driver
+ DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT @USB_SUPPORT +kmod-usb-core
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mediatek/mt7601u/mt7601u.ko
+ AUTOLOAD:=$(call AutoProbe,mt7601)
+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 AutoProbe,mwl8k)
+endef
+
+define KernelPackage/mwl8k/description
+ Kernel modules for Marvell TOPDOG 802.11 Wireless cards
+endef
+
+
+define KernelPackage/mwifiex-pcie
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Driver for Marvell 802.11n/802.11ac PCIe Wireless cards
+ URL:=http://wireless.kernel.org/en/users/Drivers/mwifiex
+ DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11N_SUPPORT
+ FILES:= \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/mwifiex/mwifiex.ko \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/mwifiex/mwifiex_pcie.ko
+ AUTOLOAD:=$(call AutoProbe,mwifiex_pcie)
+endef
+
+define KernelPackage/mwifiex-pcie/description
+ Kernel modules for Marvell 802.11n/802.11ac PCIe Wireless cards
+endef
+
+
+# Prism54 drivers
+P54PCIFW:=2.13.12.0.arm
+P54USBFW:=2.13.24.0.lm87.arm
+P54SPIFW:=2.13.0.0.a.13.14.arm
+
+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 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
+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 AutoProbe,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 AutoProbe,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 AutoProbe,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
+ 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
+ HIDDEN:=1
+ TITLE+= (MMIO)
+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00mmio.ko
+endef
+
+define KernelPackage/rt2x00-pci
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-mmio +kmod-rt2x00-lib
+ HIDDEN:=1
+ TITLE+= (PCI)
+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00pci.ko
+ AUTOLOAD:=$(call AutoProbe,rt2x00pci)
+endef
+
+define KernelPackage/rt2x00-usb
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @USB_SUPPORT +kmod-rt2x00-lib +kmod-usb-core
+ HIDDEN:=1
+ TITLE+= (USB)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00usb.ko
+ AUTOLOAD:=$(call AutoProbe,rt2x00usb)
+endef
+
+define KernelPackage/rt2800-lib
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib +kmod-lib-crc-ccitt +@DRIVER_11N_SUPPORT
+ HIDDEN:=1
+ TITLE+= (rt2800 LIB)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2800lib.ko
+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 AutoProbe,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 AutoProbe,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 AutoProbe,rt2500usb)
+endef
+
+define KernelPackage/rt2800-mmio
+$(call KernelPackage/rt2x00/Default)
+ TITLE += (RT28xx/RT3xxx MMIO)
+ DEPENDS += +kmod-rt2800-lib +kmod-rt2x00-mmio
+ HIDDEN:=1
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2800mmio.ko
+endef
+
+define KernelPackage/rt2800-soc
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS += @(TARGET_ramips_rt288x||TARGET_ramips_rt305x||TARGET_ramips_rt3883||TARGET_ramips_mt7620) +kmod-rt2800-mmio +kmod-rt2800-lib
+ TITLE += (RT28xx/RT3xxx SoC)
+ FILES := \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00soc.ko \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2800soc.ko
+ AUTOLOAD:=$(call AutoProbe,rt2800soc)
+endef
+
+define KernelPackage/rt2800-pci
+$(call KernelPackage/rt2x00/Default)
+ DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-rt2800-lib +kmod-rt2800-mmio
+ TITLE+= (RT2860 PCI)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2800pci.ko
+ AUTOLOAD:=$(call AutoProbe,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 AutoProbe,rt2800usb)
+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 AutoProbe,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 AutoProbe,rt73usb)
+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/realtek/rtl818x/rtl8180/rtl818x_pci.ko
+ AUTOLOAD:=$(call AutoProbe,rtl818x_pci)
+endef
+
+define KernelPackage/rtl8187
+$(call KernelPackage/rtl818x/Default)
+ DEPENDS+= @USB_SUPPORT +kmod-usb-core
+ TITLE+= (RTL8187 USB)
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.ko
+ AUTOLOAD:=$(call AutoProbe,rtl8187)
+endef
+
+define KernelPackage/rtlwifi/config
+ config PACKAGE_RTLWIFI_DEBUG
+ bool "Realtek wireless debugging"
+ depends on PACKAGE_kmod-rtlwifi
+ help
+ Say Y, if you want to debug realtek wireless drivers.
+
+endef
+
+define KernelPackage/rtlwifi
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Realtek common driver part
+ DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 +@DRIVER_11N_SUPPORT
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtlwifi.ko
+ HIDDEN:=1
+endef
+
+define KernelPackage/rtlwifi-pci
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Realtek common driver part (PCI support)
+ DEPENDS+= @PCI_SUPPORT +kmod-rtlwifi
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_pci.ko
+ AUTOLOAD:=$(call AutoProbe,rtl_pci)
+ HIDDEN:=1
+endef
+
+define KernelPackage/rtlwifi-usb
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Realtek common driver part (USB support)
+ DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-rtlwifi
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_usb.ko
+ AUTOLOAD:=$(call AutoProbe,rtl_usb)
+ HIDDEN:=1
+endef
+
+define KernelPackage/rtl8192c-common
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Realtek RTL8192CE/RTL8192CU common support module
+ DEPENDS+= +kmod-rtlwifi
+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192c/rtl8192c-common.ko
+ HIDDEN:=1
+endef
+
+define KernelPackage/rtl8192ce
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Realtek RTL8192CE/RTL8188CE support
+ DEPENDS+= +kmod-rtlwifi-pci +kmod-rtl8192c-common
+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rtl8192ce.ko
+ AUTOLOAD:=$(call AutoProbe,rtl8192ce)
+endef
+
+define KernelPackage/rtl8192ce/install
+ $(INSTALL_DIR) $(1)/lib/firmware/rtlwifi
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rtlwifi/rtl8192cfw.bin $(1)/lib/firmware/rtlwifi
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rtlwifi/rtl8192cfwU.bin $(1)/lib/firmware/rtlwifi
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rtlwifi/rtl8192cfwU_B.bin $(1)/lib/firmware/rtlwifi
+endef
+
+define KernelPackage/rtl8192se
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Realtek RTL8192SE/RTL8191SE support
+ DEPENDS+= +kmod-rtlwifi-pci
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rtl8192se.ko
+ AUTOLOAD:=$(call AutoProbe,rtl8192se)
+endef
+
+define KernelPackage/rtl8192se/install
+ $(INSTALL_DIR) $(1)/lib/firmware/rtlwifi
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rtlwifi/rtl8192sefw.bin $(1)/lib/firmware/rtlwifi
+endef
+
+define KernelPackage/rtl8192de
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Realtek RTL8192DE/RTL8188DE support
+ DEPENDS+= +kmod-rtlwifi-pci
+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rtl8192de.ko
+ AUTOLOAD:=$(call AutoProbe,rtl8192de)
+endef
+
+define KernelPackage/rtl8192de/install
+ $(INSTALL_DIR) $(1)/lib/firmware/rtlwifi
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rtlwifi/rtl8192defw.bin $(1)/lib/firmware/rtlwifi
+endef
+
+define KernelPackage/rtl8192cu
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Realtek RTL8192CU/RTL8188CU support
+ DEPENDS+= +kmod-rtlwifi-usb +kmod-rtl8192c-common
+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rtl8192cu.ko
+ AUTOLOAD:=$(call AutoProbe,rtl8192cu)
+endef
+
+define KernelPackage/rtl8192cu/install
+ $(INSTALL_DIR) $(1)/lib/firmware/rtlwifi
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rtlwifi/rtl8192cufw.bin $(1)/lib/firmware/rtlwifi
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rtlwifi/rtl8192cufw_A.bin $(1)/lib/firmware/rtlwifi
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rtlwifi/rtl8192cufw_B.bin $(1)/lib/firmware/rtlwifi
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/rtlwifi/rtl8192cufw_TMSC.bin $(1)/lib/firmware/rtlwifi
+endef
+
+
+define KernelPackage/wlcore
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=TI common driver part
+ DEPENDS+= @TARGET_omap +kmod-mac80211 +@DRIVER_11N_SUPPORT
+ FILES:= \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore.ko \
+ $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore_sdio.ko
+ AUTOLOAD:=$(call AutoProbe,wlcore wlcore_sdio)
+endef
+
+define KernelPackage/wlcore/description
+ This module contains some common parts needed by TI Wireless drivers.
+endef
+
+define KernelPackage/wl12xx
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Driver for TI WL12xx
+ URL:=http://wireless.kernel.org/en/users/Drivers/wl12xx
+ DEPENDS+= +kmod-wlcore
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl12xx/wl12xx.ko
+ AUTOLOAD:=$(call AutoProbe,wl12xx)
+endef
+
+define KernelPackage/wl12xx/description
+ Kernel modules for TI WL12xx
+endef
+
+define KernelPackage/wl18xx
+ $(call KernelPackage/mac80211/Default)
+ TITLE:=Driver for TI WL18xx
+ URL:=http://wireless.kernel.org/en/users/Drivers/wl18xx
+ DEPENDS+= +kmod-wlcore
+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl18xx/wl18xx.ko
+ AUTOLOAD:=$(call AutoProbe,wl18xx)
+endef
+
+define KernelPackage/wl18xx/description
+ Kernel modules for TI WL18xx
+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 AutoProbe,zd1211rw)
+endef
+
+
+
+config_package=$(if $(CONFIG_PACKAGE_kmod-$(1)),m)
+
+config-y:= \
+ WLAN \
+ NL80211_TESTMODE \
+ CFG80211_WEXT \
+ CFG80211_INTERNAL_REGDB \
+ CFG80211_CERTIFICATION_ONUS \
+ MAC80211_RC_MINSTREL \
+ MAC80211_RC_MINSTREL_HT \
+ MAC80211_RC_MINSTREL_VHT \
+ 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 \
+ ATH10K_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 ATH10K_DEBUG
+config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED
+
+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-$(CONFIG_ATH9K_SUPPORT_PCOEM) += ATH9K_PCOEM
+
+config-$(call config_package,ath9k-htc) += ATH9K_HTC
+config-$(call config_package,ath10k) += ATH10K ATH10K_PCI
+
+config-$(call config_package,ath5k) += ATH5K
+ifdef CONFIG_TARGET_ath25
+ config-y += ATH5K_AHB
+else
+ config-y += ATH5K_PCI
+endif
+
+config-$(call config_package,carl9170) += CARL9170
+
+config-$(call config_package,b43) += B43
+config-$(CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB) += B43_BUSES_BCMA_AND_SSB
+config-$(CONFIG_PACKAGE_B43_BUSES_BCMA) += B43_BUSES_BCMA
+config-$(CONFIG_PACKAGE_B43_BUSES_SSB) += B43_BUSES_SSB
+config-$(CONFIG_PACKAGE_B43_PHY_G) += B43_PHY_G
+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
+config-$(CONFIG_BRCMFMAC_SDIO) += BRCMFMAC_SDIO
+config-$(CONFIG_BRCMFMAC_USB) += BRCMFMAC_USB
+config-$(CONFIG_BRCMFMAC_PCIE) += BRCMFMAC_PCIE
+config-$(CONFIG_PACKAGE_BRCM80211_DEBUG) += BRCMDBG
+
+config-$(call config_package,mac80211-hwsim) += MAC80211_HWSIM
+config-$(call config_package,mt7601u) += MT7601U
+config-y += WL_MEDIATEK
+
+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-$(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-$(call config_package,rt2800-soc) += RT2800SOC
+config-$(call config_package,rt2800-pci) += RT2800PCI
+config-y += RT2800PCI_RT33XX RT2800PCI_RT35XX RT2800PCI_RT53XX RT2800PCI_RT3290
+
+config-$(call config_package,rt2800-usb) += RT2800USB
+config-y += RT2800USB_RT33XX RT2800USB_RT35XX RT2800USB_RT3573 RT2800USB_RT53XX RT2800USB_RT55XX RT2800USB_UNKNOWN
+
+config-$(call config_package,iwl-legacy) += IWLEGACY
+config-$(call config_package,iwl3945) += IWL3945
+config-$(call config_package,iwl4965) += IWL4965
+config-$(call config_package,iwlwifi) += IWLWIFI IWLDVM IWLMVM
+config-$(CONFIG_PACKAGE_IWLWIFI_DEBUG)+= IWLWIFI_DEBUG
+config-$(CONFIG_PACKAGE_IWLWIFI_DEBUGFS)+= IWLWIFI_DEBUGFS
+
+config-$(call config_package,libipw) += LIBIPW
+config-$(call config_package,ipw2100) += IPW2100
+config-$(call config_package,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,hermes) += HERMES
+config-$(call config_package,hermes-pci) += PCI_HERMES
+config-$(call config_package,hermes-plx) += PLX_HERMES
+config-$(call config_package,hermes-pcmcia) += PCMCIA_HERMES
+config-y += HERMES_PRISM
+
+config-$(call config_package,adm8211) += ADM8211
+config-$(call config_package,libertas-sdio) += LIBERTAS LIBERTAS_SDIO
+config-$(call config_package,libertas-usb) += LIBERTAS LIBERTAS_USB
+config-$(call config_package,mwl8k) += MWL8K
+config-$(call config_package,mwifiex-pcie) += MWIFIEX MWIFIEX_PCIE
+config-$(call config_package,rtl8180) += RTL8180
+config-$(call config_package,rtl8187) += RTL8187
+config-$(call config_package,wlcore) += WLCORE WLCORE_SDIO
+config-$(call config_package,wl12xx) += WL12XX
+config-$(call config_package,wl18xx) += WL18XX
+config-y += WL_TI WILINK_PLATFORM_DATA
+config-$(call config_package,zd1211rw) += ZD1211RW
+
+config-$(call config_package,rtlwifi) += RTL_CARDS RTLWIFI
+config-$(call config_package,rtlwifi-pci) += RTLWIFI_PCI
+config-$(call config_package,rtlwifi-usb) += RTLWIFI_USB
+config-$(call config_package,rtl8192c-common) += RTL8192C_COMMON
+config-$(call config_package,rtl8192ce) += RTL8192CE
+config-$(call config_package,rtl8192se) += RTL8192SE
+config-$(call config_package,rtl8192de) += RTL8192DE
+config-$(call config_package,rtl8192cu) += RTL8192CU
+config-$(CONFIG_PACKAGE_RTLWIFI_DEBUG) += RTLWIFI_DEBUG
+
+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=
+
+ifneq ($(findstring c,$(OPENWRT_VERBOSE)),)
+ MAKE_OPTS += V=1
+endif
+
+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)
+ $(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(PKG_MT7601U_FW_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
+endef
+
+define Build/Compile
+ $(SH_FUNC) var2file "$(call shvar,mac80211_config)" $(PKG_BUILD_DIR)/.config
+ $(MAKE) $(MAKE_OPTS) allnoconfig
+ $(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/
+ rm -f $(1)/usr/include/mac80211-backport/linux/module.h
+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/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
+ifneq ($(CONFIG_BRCMFMAC_USB),)
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/brcmfmac43236b.bin \
+ $(1)/lib/firmware/brcm/
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/brcmfmac43143.bin \
+ $(1)/lib/firmware/brcm/
+endif
+ifneq ($(CONFIG_BRCMFMAC_PCIE),)
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/brcmfmac43602-pcie.ap.bin \
+ $(1)/lib/firmware/brcm/brcmfmac43602-pcie.bin
+endif
+endef
+
+define KernelPackage/carl9170/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/carl9170-1.fw $(1)/lib/firmware
+endef
+
+define KernelPackage/cfg80211/install
+ $(INSTALL_DIR) $(1)/lib/wifi $(1)/lib/netifd/wireless
+ $(INSTALL_DATA) ./files/lib/wifi/mac80211.sh $(1)/lib/wifi
+ $(INSTALL_BIN) ./files/lib/netifd/wireless/mac80211.sh $(1)/lib/netifd/wireless
+endef
+
+define KernelPackage/ipw2100/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/ipw2100-$(IPW2100_VERSION)*.fw $(1)/lib/firmware
+endef
+
+define KernelPackage/ipw2200/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(IPW2200_NAME)-$(IPW2200_VERSION)/ipw2200*.fw $(1)/lib/firmware
+endef
+
+define KernelPackage/iwlwifi/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ifneq ($(CONFIG_IWL100_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-100-5.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_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
+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_IWL3160_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-3160-13.ucode $(1)/lib/firmware
+endif
+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_IWL6000_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6000-4.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_IWL6050_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6050-5.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL7260_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-7260-13.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL7265_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-7265-13.ucode $(1)/lib/firmware
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-7265D-13.ucode $(1)/lib/firmware
+endif
+ifneq ($(CONFIG_IWL8000_FW),)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-8000C-13.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/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-sdio/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/mt7601u/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_MT7601U_FW_NAME)_$(PKG_MT7601U_FW_VERSION)/mcu/bin/MT7601.bin \
+ $(1)/lib/firmware/mt7601u.bin
+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/mwifiex-pcie/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mrvl
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/mrvl/pcie8897_uapsta.bin \
+ $(1)/lib/firmware/mrvl/
+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/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/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/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 \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl128x-fw-5-mr.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl128x-fw-5-plt.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl128x-fw-5-sr.bin \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl128x-nvs.bin \
+ $(1)/lib/firmware/ti-connectivity
+endef
+
+define KernelPackage/wl18xx/install
+ $(INSTALL_DIR) $(1)/lib/firmware/ti-connectivity
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-fw-4.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
+
+
+$(eval $(call KernelPackage,adm8211))
+$(eval $(call KernelPackage,ath))
+$(eval $(call KernelPackage,ath10k))
+$(eval $(call KernelPackage,ath5k))
+$(eval $(call KernelPackage,ath9k))
+$(eval $(call KernelPackage,ath9k-common))
+$(eval $(call KernelPackage,ath9k-htc))
+$(eval $(call KernelPackage,b43))
+$(eval $(call KernelPackage,b43legacy))
+$(eval $(call KernelPackage,brcmsmac))
+$(eval $(call KernelPackage,brcmfmac))
+$(eval $(call KernelPackage,brcmutil))
+$(eval $(call KernelPackage,carl9170))
+$(eval $(call KernelPackage,cfg80211))
+$(eval $(call KernelPackage,hermes))
+$(eval $(call KernelPackage,hermes-pci))
+$(eval $(call KernelPackage,hermes-plx))
+$(eval $(call KernelPackage,hermes-pcmcia))
+$(eval $(call KernelPackage,iwlwifi))
+$(eval $(call KernelPackage,iwl-legacy))
+$(eval $(call KernelPackage,iwl4965))
+$(eval $(call KernelPackage,iwl3945))
+$(eval $(call KernelPackage,lib80211))
+$(eval $(call KernelPackage,libertas-usb))
+$(eval $(call KernelPackage,libertas-sdio))
+$(eval $(call KernelPackage,libipw))
+$(eval $(call KernelPackage,ipw2100))
+$(eval $(call KernelPackage,ipw2200))
+$(eval $(call KernelPackage,mac80211))
+$(eval $(call KernelPackage,mac80211-hwsim))
+$(eval $(call KernelPackage,mt7601u))
+$(eval $(call KernelPackage,mwl8k))
+$(eval $(call KernelPackage,mwifiex-pcie))
+$(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,rt2800-lib))
+$(eval $(call KernelPackage,rt2400-pci))
+$(eval $(call KernelPackage,rt2500-pci))
+$(eval $(call KernelPackage,rt2500-usb))
+$(eval $(call KernelPackage,rt2800-mmio))
+$(eval $(call KernelPackage,rt2800-soc))
+$(eval $(call KernelPackage,rt2800-pci))
+$(eval $(call KernelPackage,rt2800-usb))
+$(eval $(call KernelPackage,rt61-pci))
+$(eval $(call KernelPackage,rt73-usb))
+$(eval $(call KernelPackage,rtl8180))
+$(eval $(call KernelPackage,rtl8187))
+$(eval $(call KernelPackage,rtlwifi))
+$(eval $(call KernelPackage,rtlwifi-pci))
+$(eval $(call KernelPackage,rtlwifi-usb))
+$(eval $(call KernelPackage,rtl8192c-common))
+$(eval $(call KernelPackage,rtl8192ce))
+$(eval $(call KernelPackage,rtl8192se))
+$(eval $(call KernelPackage,rtl8192de))
+$(eval $(call KernelPackage,rtl8192cu))
+$(eval $(call KernelPackage,wlcore))
+$(eval $(call KernelPackage,wl12xx))
+$(eval $(call KernelPackage,wl18xx))
+$(eval $(call KernelPackage,zd1211rw))
diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
new file mode 100644
index 0000000..2a8d2f9
--- /dev/null
+++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
@@ -0,0 +1,748 @@
+#!/bin/sh
+. /lib/netifd/netifd-wireless.sh
+. /lib/netifd/hostapd.sh
+
+init_wireless_driver "$@"
+
+MP_CONFIG_INT="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh_max_peer_links
+ mesh_max_retries mesh_ttl mesh_element_ttl 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_sync_offset_max_neighor
+ mesh_rssi_threshold mesh_hwmp_active_path_to_root_timeout mesh_hwmp_root_interval
+ mesh_hwmp_confirmation_interval mesh_awake_window mesh_plink_timeout"
+MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding"
+MP_CONFIG_STRING="mesh_power_mode"
+
+drv_mac80211_init_device_config() {
+ hostapd_common_add_device_config
+
+ config_add_string path phy 'macaddr:macaddr'
+ config_add_string hwmode
+ config_add_int beacon_int chanbw frag rts
+ config_add_int rxantenna txantenna antenna_gain txpower distance
+ config_add_boolean noscan ht_coex
+ config_add_array ht_capab
+ config_add_boolean \
+ rxldpc \
+ short_gi_80 \
+ short_gi_160 \
+ tx_stbc_2by1 \
+ su_beamformer \
+ su_beamformee \
+ mu_beamformer \
+ mu_beamformee \
+ vht_txop_ps \
+ htc_vht \
+ rx_antenna_pattern \
+ tx_antenna_pattern
+ config_add_int vht_max_a_mpdu_len_exp vht_max_mpdu vht_link_adapt vht160 rx_stbc tx_stbc
+ config_add_boolean \
+ ldpc \
+ greenfield \
+ short_gi_20 \
+ short_gi_40 \
+ max_amsdu \
+ dsss_cck_40
+}
+
+drv_mac80211_init_iface_config() {
+ hostapd_common_add_bss_config
+
+ config_add_string 'macaddr:macaddr' ifname
+
+ config_add_boolean wds powersave
+ config_add_int maxassoc
+ config_add_int max_listen_int
+ config_add_int dtim_period
+ config_add_int start_disabled
+
+ # mesh
+ config_add_string mesh_id
+ config_add_int $MP_CONFIG_INT
+ config_add_boolean $MP_CONFIG_BOOL
+ config_add_string $MP_CONFIG_STRING
+}
+
+mac80211_add_capabilities() {
+ local __var="$1"; shift
+ local __mask="$1"; shift
+ local __out= oifs
+
+ oifs="$IFS"
+ IFS=:
+ for capab in "$@"; do
+ set -- $capab
+
+ [ "$(($4))" -gt 0 ] || continue
+ [ "$(($__mask & $2))" -eq "$((${3:-$2}))" ] || continue
+ __out="$__out[$1]"
+ done
+ IFS="$oifs"
+
+ export -n -- "$__var=$__out"
+}
+
+mac80211_hostapd_setup_base() {
+ local phy="$1"
+
+ json_select config
+
+ [ "$auto_channel" -gt 0 ] && channel=acs_survey
+
+ json_get_vars noscan ht_coex
+ json_get_values ht_capab_list ht_capab
+
+ ieee80211n=1
+ ht_capab=
+ case "$htmode" in
+ VHT20|HT20) ;;
+ HT40*|VHT40|VHT80|VHT160)
+ case "$hwmode" in
+ a)
+ case "$(( ($channel / 4) % 2 ))" in
+ 1) ht_capab="[HT40+]";;
+ 0) ht_capab="[HT40-]";;
+ esac
+ ;;
+ *)
+ case "$htmode" in
+ HT40+) ht_capab="[HT40+]";;
+ HT40-) ht_capab="[HT40-]";;
+ *)
+ if [ "$channel" -lt 7 ]; then
+ ht_capab="[HT40+]"
+ else
+ ht_capab="[HT40-]"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ [ "$auto_channel" -gt 0 ] && ht_capab="[HT40+]"
+ ;;
+ *) ieee80211n= ;;
+ esac
+
+ [ -n "$ieee80211n" ] && {
+ append base_cfg "ieee80211n=1" "$N"
+
+ set_default ht_coex 0
+ append base_cfg "ht_coex=$ht_coex" "$N"
+
+ json_get_vars \
+ ldpc:1 \
+ greenfield:0 \
+ short_gi_20:1 \
+ short_gi_40:1 \
+ tx_stbc:1 \
+ rx_stbc:3 \
+ max_amsdu:1 \
+ dsss_cck_40:1
+
+ ht_cap_mask=0
+ for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do
+ ht_cap_mask="$(($ht_cap_mask | $cap))"
+ done
+
+ cap_rx_stbc=$((($ht_cap_mask >> 8) & 3))
+ [ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc"
+ ht_cap_mask="$(( ($ht_cap_mask & ~(0x300)) | ($cap_rx_stbc << 8) ))"
+
+ mac80211_add_capabilities ht_capab_flags $ht_cap_mask \
+ LDPC:0x1::$ldpc \
+ GF:0x10::$greenfield \
+ SHORT-GI-20:0x20::$short_gi_20 \
+ SHORT-GI-40:0x40::$short_gi_40 \
+ TX-STBC:0x80::$tx_stbc \
+ RX-STBC1:0x300:0x100:1 \
+ RX-STBC12:0x300:0x200:1 \
+ RX-STBC123:0x300:0x300:1 \
+ MAX-AMSDU-7935:0x800::$max_amsdu \
+ DSSS_CCK-40:0x1000::$dsss_cck_40
+
+ ht_capab="$ht_capab$ht_capab_flags"
+ [ -n "$ht_capab" ] && append base_cfg "ht_capab=$ht_capab" "$N"
+ }
+
+ # 802.11ac
+ enable_ac=0
+ idx="$channel"
+ case "$htmode" in
+ VHT20) enable_ac=1;;
+ VHT40)
+ case "$(( ($channel / 4) % 2 ))" in
+ 1) idx=$(($channel + 2));;
+ 0) idx=$(($channel - 2));;
+ esac
+ enable_ac=1
+ append base_cfg "vht_oper_chwidth=0" "$N"
+ append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N"
+ ;;
+ VHT80)
+ case "$(( ($channel / 4) % 4 ))" in
+ 1) idx=$(($channel + 6));;
+ 2) idx=$(($channel + 2));;
+ 3) idx=$(($channel - 2));;
+ 0) idx=$(($channel - 6));;
+ esac
+ enable_ac=1
+ append base_cfg "vht_oper_chwidth=1" "$N"
+ append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N"
+ ;;
+ VHT160)
+ case "$channel" in
+ 36|40|44|48|52|56|60|64) idx=50;;
+ 100|104|108|112|116|120|124|128) idx=114;;
+ esac
+ enable_ac=1
+ append base_cfg "vht_oper_chwidth=2" "$N"
+ append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N"
+ ;;
+ esac
+
+ if [ "$enable_ac" != "0" ]; then
+ json_get_vars \
+ rxldpc:1 \
+ short_gi_80:1 \
+ short_gi_160:1 \
+ tx_stbc_2by1:1 \
+ su_beamformer:1 \
+ su_beamformee:1 \
+ mu_beamformer:1 \
+ mu_beamformee:1 \
+ vht_txop_ps:1 \
+ htc_vht:1 \
+ rx_antenna_pattern:1 \
+ tx_antenna_pattern:1 \
+ vht_max_a_mpdu_len_exp:7 \
+ vht_max_mpdu:11454 \
+ rx_stbc:4 \
+ tx_stbc:4 \
+ vht_link_adapt:3 \
+ vht160:2
+
+ append base_cfg "ieee80211ac=1" "$N"
+ vht_cap=0
+ for cap in $(iw phy "$phy" info | awk -F "[()]" '/VHT Capabilities/ { print $2 }'); do
+ vht_cap="$(($vht_cap | $cap))"
+ done
+
+ cap_rx_stbc=$((($vht_cap >> 8) & 7))
+ [ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc"
+ ht_cap_mask="$(( ($vht_cap & ~(0x700)) | ($cap_rx_stbc << 8) ))"
+
+ mac80211_add_capabilities vht_capab $vht_cap \
+ RXLDPC:0x10::$rxldpc \
+ SHORT-GI-80:0x20::$short_gi_80 \
+ SHORT-GI-160:0x40::$short_gi_160 \
+ TX-STBC-2BY1:0x80::$tx_stbc \
+ SU-BEAMFORMER:0x800::$su_beamformer \
+ SU-BEAMFORMEE:0x1000::$su_beamformee \
+ MU-BEAMFORMER:0x80000::$mu_beamformer \
+ MU-BEAMFORMEE:0x100000::$mu_beamformee \
+ VHT-TXOP-PS:0x200000::$vht_txop_ps \
+ HTC-VHT:0x400000::$htc_vht \
+ RX-ANTENNA-PATTERN:0x10000000::$rx_antenna_pattern \
+ TX-ANTENNA-PATTERN:0x20000000::$tx_antenna_pattern \
+ RX-STBC1:0x700:0x100:1 \
+ RX-STBC12:0x700:0x200:1 \
+ RX-STBC123:0x700:0x300:1 \
+ RX-STBC1234:0x700:0x400:1 \
+
+ # supported Channel widths
+ vht160_hw=0
+ [ "$(($vht_cap & 12))" -eq 4 -a 1 -le "$vht160" ] && \
+ vht160_hw=1
+ [ "$(($vht_cap & 12))" -eq 8 -a 2 -le "$vht160" ] && \
+ vht160_hw=2
+ [ "$vht160_hw" = 1 ] && vht_capab="$vht_capab[VHT160]"
+ [ "$vht160_hw" = 2 ] && vht_capab="$vht_capab[VHT160-80PLUS80]"
+
+ # maximum MPDU length
+ vht_max_mpdu_hw=3895
+ [ "$(($vht_cap & 3))" -ge 1 -a 7991 -le "$vht_max_mpdu" ] && \
+ vht_max_mpdu_hw=7991
+ [ "$(($vht_cap & 3))" -ge 2 -a 11454 -le "$vht_max_mpdu" ] && \
+ vht_max_mpdu_hw=11454
+ [ "$vht_max_mpdu_hw" != 3895 ] && \
+ vht_capab="$vht_capab[MAX-MPDU-$vht_max_mpdu_hw]"
+
+ # maximum A-MPDU length exponent
+ vht_max_a_mpdu_len_exp_hw=0
+ [ "$(($vht_cap & 58720256))" -ge 8388608 -a 1 -le "$vht_max_a_mpdu_len_exp" ] && \
+ vht_max_a_mpdu_len_exp_hw=1
+ [ "$(($vht_cap & 58720256))" -ge 16777216 -a 2 -le "$vht_max_a_mpdu_len_exp" ] && \
+ vht_max_a_mpdu_len_exp_hw=2
+ [ "$(($vht_cap & 58720256))" -ge 25165824 -a 3 -le "$vht_max_a_mpdu_len_exp" ] && \
+ vht_max_a_mpdu_len_exp_hw=3
+ [ "$(($vht_cap & 58720256))" -ge 33554432 -a 4 -le "$vht_max_a_mpdu_len_exp" ] && \
+ vht_max_a_mpdu_len_exp_hw=4
+ [ "$(($vht_cap & 58720256))" -ge 41943040 -a 5 -le "$vht_max_a_mpdu_len_exp" ] && \
+ vht_max_a_mpdu_len_exp_hw=5
+ [ "$(($vht_cap & 58720256))" -ge 50331648 -a 6 -le "$vht_max_a_mpdu_len_exp" ] && \
+ vht_max_a_mpdu_len_exp_hw=6
+ [ "$(($vht_cap & 58720256))" -ge 58720256 -a 7 -le "$vht_max_a_mpdu_len_exp" ] && \
+ vht_max_a_mpdu_len_exp_hw=7
+ vht_capab="$vht_capab[MAX-A-MPDU-LEN-EXP$vht_max_a_mpdu_len_exp_hw]"
+
+ # whether or not the STA supports link adaptation using VHT variant
+ vht_link_adapt_hw=0
+ [ "$(($vht_cap & 201326592))" -ge 134217728 -a 2 -le "$vht_link_adapt" ] && \
+ vht_link_adapt_hw=2
+ [ "$(($vht_cap & 201326592))" -ge 201326592 -a 3 -le "$vht_link_adapt" ] && \
+ vht_link_adapt_hw=3
+ [ "$vht_link_adapt_hw" != 0 ] && \
+ vht_capab="$vht_capab[VHT-LINK-ADAPT-$vht_link_adapt_hw]"
+
+ [ -n "$vht_capab" ] && append base_cfg "vht_capab=$vht_capab" "$N"
+ fi
+
+ hostapd_prepare_device_config "$hostapd_conf_file" nl80211
+ cat >> "$hostapd_conf_file" <<EOF
+${channel:+channel=$channel}
+${noscan:+noscan=$noscan}
+$base_cfg
+
+EOF
+ json_select ..
+}
+
+mac80211_hostapd_setup_bss() {
+ local phy="$1"
+ local ifname="$2"
+ local macaddr="$3"
+ local type="$4"
+
+ hostapd_cfg=
+ append hostapd_cfg "$type=$ifname" "$N"
+
+ hostapd_set_bss_options hostapd_cfg "$vif" || return 1
+ json_get_vars wds dtim_period max_listen_int start_disabled
+
+ set_default wds 0
+ set_default start_disabled 0
+
+ [ "$wds" -gt 0 ] && append hostapd_cfg "wds_sta=1" "$N"
+ [ "$staidx" -gt 0 -o "$start_disabled" -eq 1 ] && append hostapd_cfg "start_disabled=1" "$N"
+
+ cat >> /var/run/hostapd-$phy.conf <<EOF
+$hostapd_cfg
+bssid=$macaddr
+${dtim_period:+dtim_period=$dtim_period}
+${max_listen_int:+max_listen_interval=$max_listen_int}
+EOF
+}
+
+mac80211_get_addr() {
+ local phy="$1"
+ local idx="$(($2 + 1))"
+
+ head -n $(($macidx + 1)) /sys/class/ieee80211/${phy}/addresses | tail -n1
+}
+
+mac80211_generate_mac() {
+ local phy="$1"
+ local id="${macidx:-0}"
+
+ local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)"
+ local mask="$(cat /sys/class/ieee80211/${phy}/address_mask)"
+
+ [ "$mask" = "00:00:00:00:00:00" ] && {
+ mask="ff:ff:ff:ff:ff:ff";
+
+ [ "$(wc -l < /sys/class/ieee80211/${phy}/addresses)" -gt 1 ] && {
+ addr="$(mac80211_get_addr "$phy" "$id")"
+ [ -n "$addr" ] && {
+ echo "$addr"
+ return
+ }
+ }
+ }
+
+ local oIFS="$IFS"; IFS=":"; set -- $mask; IFS="$oIFS"
+
+ local mask1=$1
+ local mask6=$6
+
+ local oIFS="$IFS"; IFS=":"; set -- $ref; IFS="$oIFS"
+
+ macidx=$(($id + 1))
+ [ "$((0x$mask1))" -gt 0 ] && {
+ b1="0x$1"
+ [ "$id" -gt 0 ] && \
+ b1=$(($b1 ^ ((($id - 1) << 2) | 0x2)))
+ 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 ))
+}
+
+find_phy() {
+ [ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0
+ [ -n "$path" ] && {
+ for phy in /sys/devices/$path/ieee80211/phy*; do
+ [ -e "$phy" ] && {
+ phy="${phy##*/}"
+ return 0
+ }
+ done
+ }
+ [ -n "$macaddr" ] && {
+ for phy in $(ls /sys/class/ieee80211 2>/dev/null); do
+ grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && return 0
+ done
+ }
+ return 1
+}
+
+mac80211_check_ap() {
+ has_ap=1
+}
+
+mac80211_prepare_vif() {
+ json_select config
+
+ json_get_vars ifname mode ssid wds powersave macaddr
+
+ [ -n "$ifname" ] || ifname="wlan${phy#phy}${if_idx:+-$if_idx}"
+ if_idx=$((${if_idx:-0} + 1))
+
+ set_default wds 0
+ set_default powersave 0
+
+ json_select ..
+
+ [ -n "$macaddr" ] || {
+ macaddr="$(mac80211_generate_mac $phy)"
+ macidx="$(($macidx + 1))"
+ }
+
+ json_add_object data
+ json_add_string ifname "$ifname"
+ json_close_object
+ json_select config
+
+ # 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
+ # subsequent virtual APs belonging to the same PHY
+ if [ -n "$hostapd_ctrl" ]; then
+ type=bss
+ else
+ type=interface
+ fi
+
+ mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return
+
+ [ -n "$hostapd_ctrl" ] || {
+ iw phy "$phy" interface add "$ifname" type __ap
+ hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}"
+ }
+ ;;
+ mesh)
+ json_get_vars key mesh_id
+ if [ -n "$key" ]; then
+ iw phy "$phy" interface add "$ifname" type mp
+ else
+ iw phy "$phy" interface add "$ifname" type mp mesh_id "$mesh_id"
+ fi
+ ;;
+ monitor)
+ iw phy "$phy" interface add "$ifname" type monitor
+ ;;
+ sta)
+ local wdsflag=
+ staidx="$(($staidx + 1))"
+ [ "$wds" -gt 0 ] && wdsflag="4addr on"
+ iw phy "$phy" interface add "$ifname" type managed $wdsflag
+ [ "$powersave" -gt 0 ] && powersave="on" || powersave="off"
+ iw "$ifname" set power_save "$powersave"
+ ;;
+ esac
+
+ case "$mode" in
+ monitor|mesh)
+ [ "$auto_channel" -gt 0 ] || iw dev "$ifname" set channel "$channel" $htmode
+ ;;
+ esac
+
+ if [ "$mode" != "ap" ]; then
+ # ALL ap functionality will be passed to hostapd
+ # All interfaces must have unique mac addresses
+ # which can either be explicitly set in the device
+ # section, or automatically generated
+ ip link set dev "$ifname" address "$macaddr"
+ fi
+
+ json_select ..
+}
+
+mac80211_setup_supplicant() {
+ wpa_supplicant_prepare_interface "$ifname" nl80211 || return 1
+ wpa_supplicant_add_network "$ifname"
+ wpa_supplicant_run "$ifname" ${hostapd_ctrl:+-H $hostapd_ctrl}
+}
+
+mac80211_setup_adhoc_htmode() {
+ case "$htmode" in
+ VHT20|HT20) ibss_htmode=HT20;;
+ HT40*|VHT40|VHT80|VHT160)
+ case "$hwmode" in
+ a)
+ case "$(( ($channel / 4) % 2 ))" in
+ 1) ibss_htmode="HT40+" ;;
+ 0) ibss_htmode="HT40-";;
+ esac
+ ;;
+ *)
+ case "$htmode" in
+ HT40+) ibss_htmode="HT40+";;
+ HT40-) ibss_htmode="HT40-";;
+ *)
+ if [ "$channel" -lt 7 ]; then
+ ibss_htmode="HT40+"
+ else
+ ibss_htmode="HT40-"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ [ "$auto_channel" -gt 0 ] && ibss_htmode="HT40+"
+ ;;
+ *) ibss_htmode="" ;;
+ esac
+
+}
+
+mac80211_setup_adhoc() {
+ json_get_vars bssid ssid key mcast_rate
+
+ keyspec=
+ [ "$auth_type" = "wep" ] && {
+ set_default key 1
+ case "$key" in
+ [1234])
+ local idx
+ for idx in 1 2 3 4; do
+ json_get_var ikey "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
+ }
+
+ brstr=
+ for br in $basic_rate_list; do
+ wpa_supplicant_add_rate brstr "$br"
+ done
+
+ mcval=
+ [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate"
+
+ iw dev "$ifname" ibss join "$ssid" $freq $ibss_htmode fixed-freq $bssid \
+ ${beacon_int:+beacon-interval $beacon_int} \
+ ${brstr:+basic-rates $brstr} \
+ ${mcval:+mcast-rate $mcval} \
+ ${keyspec:+keys $keyspec}
+}
+
+mac80211_setup_vif() {
+ local name="$1"
+ local failed
+
+ json_select data
+ json_get_vars ifname
+ json_select ..
+
+ json_select config
+ json_get_vars mode
+ json_get_var vif_txpower txpower
+
+ ip link set dev "$ifname" up || {
+ wireless_setup_vif_failed IFUP_ERROR
+ json_select ..
+ return
+ }
+
+ set_default vif_txpower "$txpower"
+ [ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00"
+
+ case "$mode" in
+ mesh)
+ # authsae or wpa_supplicant
+ json_get_vars key
+ if [ -n "$key" ]; then
+ if [ -e "/lib/wifi/authsae.sh" ]; then
+ . /lib/wifi/authsae.sh
+ authsae_start_interface || failed=1
+ else
+ wireless_vif_parse_encryption
+ mac80211_setup_supplicant || failed=1
+ fi
+ fi
+
+ for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do
+ json_get_var mp_val "$var"
+ [ -n "$mp_val" ] && iw dev "$ifname" set mesh_param "$var" "$mp_val"
+ done
+ ;;
+ adhoc)
+ wireless_vif_parse_encryption
+ mac80211_setup_adhoc_htmode
+ if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then
+ mac80211_setup_supplicant || failed=1
+ else
+ mac80211_setup_adhoc
+ fi
+ ;;
+ sta)
+ mac80211_setup_supplicant || failed=1
+ ;;
+ esac
+
+ json_select ..
+ [ -n "$failed" ] || wireless_add_vif "$name" "$ifname"
+}
+
+get_freq() {
+ local phy="$1"
+ local chan="$2"
+ iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep MHz | awk '{print $2}'
+}
+
+mac80211_interface_cleanup() {
+ local phy="$1"
+
+ for wdev in $(list_phy_interfaces "$phy"); do
+ ip link set dev "$wdev" down 2>/dev/null
+ iw dev "$wdev" del
+ done
+}
+
+drv_mac80211_cleanup() {
+ hostapd_common_cleanup
+}
+
+drv_mac80211_setup() {
+ json_select config
+ json_get_vars \
+ phy macaddr path \
+ country chanbw distance \
+ txpower antenna_gain \
+ rxantenna txantenna \
+ frag rts beacon_int htmode
+ json_get_values basic_rate_list basic_rate
+ json_select ..
+
+ find_phy || {
+ echo "Could not find PHY for device '$1'"
+ wireless_set_retry 0
+ return 1
+ }
+
+ wireless_set_data phy="$phy"
+ mac80211_interface_cleanup "$phy"
+
+ # convert channel to frequency
+ [ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel")"
+
+ [ -n "$country" ] && {
+ iw reg get | grep -q "^country $country:" || {
+ iw reg set "$country"
+ sleep 1
+ }
+ }
+
+ hostapd_conf_file="/var/run/hostapd-$phy.conf"
+
+ no_ap=1
+ macidx=0
+ staidx=0
+
+ [ -n "$chanbw" ] && {
+ for file in /sys/kernel/debug/ieee80211/$phy/ath9k/chanbw /sys/kernel/debug/ieee80211/$phy/ath5k/bwmode; do
+ [ -f "$file" ] && echo "$chanbw" > "$file"
+ done
+ }
+
+ set_default rxantenna all
+ set_default txantenna all
+ set_default distance 0
+ set_default antenna_gain 0
+
+ iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1
+ iw phy "$phy" set antenna_gain $antenna_gain
+ iw phy "$phy" set distance "$distance"
+
+ [ -n "$frag" ] && iw phy "$phy" set frag "${frag%%.*}"
+ [ -n "$rts" ] && iw phy "$phy" set rts "${rts%%.*}"
+
+ has_ap=
+ hostapd_ctrl=
+ for_each_interface "ap" mac80211_check_ap
+
+ rm -f "$hostapd_conf_file"
+ [ -n "$has_ap" ] && mac80211_hostapd_setup_base "$phy"
+
+ for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif
+ for_each_interface "ap" mac80211_prepare_vif
+
+ [ -n "$hostapd_ctrl" ] && {
+ /usr/sbin/hostapd -P /var/run/wifi-$phy.pid -B "$hostapd_conf_file"
+ ret="$?"
+ wireless_add_process "$(cat /var/run/wifi-$phy.pid)" "/usr/sbin/hostapd" 1
+ [ "$ret" != 0 ] && {
+ wireless_setup_failed HOSTAPD_START_FAILED
+ return
+ }
+ }
+
+ for_each_interface "ap sta adhoc mesh monitor" mac80211_setup_vif
+
+ wireless_set_up
+}
+
+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
+}
+
+drv_mac80211_teardown() {
+ wireless_process_kill_all
+
+ json_select data
+ json_get_vars phy
+ json_select ..
+
+ mac80211_interface_cleanup "$phy"
+}
+
+add_driver mac80211
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 0000000..ea229d6
--- /dev/null
+++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh
@@ -0,0 +1,131 @@
+#!/bin/sh
+append DRIVERS "mac80211"
+
+lookup_phy() {
+ [ -n "$phy" ] && {
+ [ -d /sys/class/ieee80211/$phy ] && return
+ }
+
+ local devpath
+ config_get devpath "$device" path
+ [ -n "$devpath" ] && {
+ for _phy in /sys/devices/$devpath/ieee80211/phy*; do
+ [ -e "$_phy" ] && {
+ phy="${_phy##*/}"
+ return
+ }
+ done
+ }
+
+ local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
+ [ -n "$macaddr" ] && {
+ for _phy in /sys/class/ieee80211/*; do
+ [ -e "$_phy" ] || continue
+
+ [ "$macaddr" = "$(cat ${_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
+}
+
+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 /sys/class/ieee80211/*; do
+ [ -e "$_dev" ] || continue
+
+ dev="${_dev##*/}"
+
+ found=0
+ config_foreach check_mac80211_device wifi-device
+ [ "$found" -gt 0 ] && continue
+
+ mode_band="g"
+ channel="11"
+ htmode=""
+ ht_capab=""
+
+ iw phy "$dev" info | grep -q 'Capabilities:' && htmode=HT20
+ iw phy "$dev" info | grep -q '2412 MHz' || { mode_band="a"; channel="36"; }
+
+ vht_cap=$(iw phy "$dev" info | grep -c 'VHT Capabilities')
+ cap_5ghz=$(iw phy "$dev" info | grep -c "Band 2")
+ [ "$vht_cap" -gt 0 -a "$cap_5ghz" -gt 0 ] && {
+ mode_band="a";
+ channel="36"
+ htmode="VHT80"
+ }
+
+ [ -n $htmode ] && append ht_capab " option htmode $htmode" "$N"
+
+ if [ -x /usr/bin/readlink -a -h /sys/class/ieee80211/${dev} ]; then
+ path="$(readlink -f /sys/class/ieee80211/${dev}/device)"
+ else
+ path=""
+ fi
+ if [ -n "$path" ]; then
+ 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_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 0000000..f318326
--- /dev/null
+++ b/package/kernel/mac80211/files/regdb.txt
@@ -0,0 +1,1262 @@
+# This is the world regulatory domain
+country 00:
+ (2402 - 2472 @ 40), (20)
+ # Channel 12 - 13.
+ (2457 - 2482 @ 40), (20), NO-IR
+ # Channel 14. Only JP enables this and for 802.11b only
+ (2474 - 2494 @ 20), (20), NO-IR, NO-OFDM
+ # Channel 36 - 48
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ # Channel 52 - 64
+ (5250 - 5330 @ 80), (20), NO-IR, DFS, AUTO-BW
+ # Channel 100 - 144
+ (5490 - 5730 @ 160), (20), NO-IR, DFS
+ # Channel 149 - 165
+ (5735 - 5835 @ 80), (20), NO-IR
+ # IEEE 802.11ad (60GHz), channels 1..3
+ (57240 - 63720 @ 2160), (0)
+
+
+country AD:
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country AE: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country AF: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source:
+# http://pucanguilla.org/Downloads/January2005-Anguilla%20Table%20of%20Allocations.pdf
+country AI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country AL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20.00), AUTO-BW
+ (5250 - 5330 @ 80), (20.00), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27.00), DFS
+
+country AM: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (18)
+ (5250 - 5330 @ 20), (18), DFS
+
+country AN: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country AR: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country AS: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country AT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country AU: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country AW: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country AZ: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (18), AUTO-BW
+ (5250 - 5330 @ 80), (18), DFS, AUTO-BW
+
+country BA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country BB: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country BD: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country BE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country BF: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country BG: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 5 GHz Short Range Devices, ref:
+ # Etsi EN 300 440-1
+ # Etsi EN 300 440-2
+ # http://crc.bg/files/_bg/Spisak_2015.pdf
+ # http://crc.bg/files/_bg/Pravila_2015_resh24.pdf
+ (5725 - 5875 @ 80), (14)
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country BH: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (20)
+ (5250 - 5330 @ 20), (20), DFS
+ (5735 - 5835 @ 20), (20)
+
+country BL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country BM: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country BN: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (20)
+
+country BO: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5250 - 5330 @ 80), (30), DFS
+ (5735 - 5835 @ 80), (30)
+
+country BR: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country BS: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://www.bicma.gov.bt/paper/publication/nrrpart4.pdf
+country BT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country BY: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country BZ: DFS-JP
+ (2402 - 2482 @ 40), (30)
+ (5735 - 5835 @ 80), (30)
+
+country CA: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5600 @ 80), (24), DFS
+ (5650 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://www.art-rca.org
+country CF: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 40), (17)
+ (5250 - 5330 @ 40), (24), DFS
+ (5490 - 5730 @ 40), (24), DFS
+ (5735 - 5835 @ 40), (30)
+
+country CH: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country CI: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country CL: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (20)
+
+country CN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+ # 60 GHz band channels 1,4: 28dBm, channels 2,3: 44dBm
+ # ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf
+ (57240 - 59400 @ 2160), (28)
+ (59400 - 63720 @ 2160), (44)
+ (63720 - 65880 @ 2160), (28)
+
+country CO: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country CR: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (17)
+ (5250 - 5330 @ 20), (24), DFS
+ (5490 - 5730 @ 20), (24), DFS
+ (5735 - 5835 @ 20), (30)
+
+country CX: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country CY: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+# 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), (100 mW)
+ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW
+ (5470 - 5725 @ 160), (500 mW), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+# 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), (100 mW)
+ # entry 303005
+ (5150 - 5250 @ 80), (100 mW), NO-OUTDOOR, AUTO-BW
+ # entries 304002 and 305002
+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW
+ # entries 308002, 309001 and 310003
+ (5470 - 5725 @ 160), (500 mW), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country DK: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+# Source:
+# http://www.ntrcdom.org/index.php?option=com_content&view=category&layout=blog&id=10&Itemid=55
+country DM: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country DO: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country DZ: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170.000 - 5250.000 @ 80.000), (23.00), AUTO-BW
+ (5250.000 - 5330.000 @ 80.000), (23.00), DFS, AUTO-BW
+ (5490.000 - 5670.000 @ 160.000), (23.00), DFS
+
+country EC: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (17)
+ (5250 - 5330 @ 20), (24), DFS
+ (5490 - 5730 @ 20), (24), DFS
+ (5735 - 5835 @ 20), (30)
+
+country EE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country EG: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 40), (20)
+ (5250 - 5330 @ 40), (20), DFS
+
+# Orden IET/787/2013, de 25 de abril, por la que se aprueba
+# el cuadro nacional de atribución de frecuencias.
+# http://www.boe.es/diario_boe/txt.php?id=BOE-A-2013-4845
+#
+# more info at "Cuadro nacional de atribución de frecuencias (CNAF)":
+# http://www.minetur.gob.es/telecomunicaciones/espectro/paginas/cnaf.aspx
+
+country ES: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW
+ (5470 - 5725 @ 160), (500 mW), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country ET: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country FI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country FM: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country FR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country GB: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country GD: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country GE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (18), AUTO-BW
+ (5250 - 5330 @ 80), (18), DFS, AUTO-BW
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country GF: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country GH: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country GL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country GP: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country GR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country GT: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country GU: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 20), (17)
+ (5250 - 5330 @ 20), (24), DFS
+ (5490 - 5730 @ 20), (24), DFS
+ (5735 - 5835 @ 20), (30)
+
+country GY:
+ (2402 - 2482 @ 40), (30)
+ (5735 - 5835 @ 80), (30)
+
+country HK: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country HN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country HR: DFS-ETSI
+ (2400 - 2483.5 @ 40), (20)
+ (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW
+ (5470 - 5725 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country HT: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country HU: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country ID: DFS-JP
+ # ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf
+ (2402 - 2482 @ 20), (20)
+ (5735 - 5815 @ 20), (23)
+
+country IE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country IL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (200 mW), NO-OUTDOOR, DFS, AUTO-BW
+
+country IN: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (20)
+
+country IR: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country IS: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country IT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country JM: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country JO: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23)
+ (5735 - 5835 @ 80), (23)
+
+country JP: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (2474 - 2494 @ 20), (20), NO-OFDM
+ (4910 - 4990 @ 40), (23)
+ (5030 - 5090 @ 40), (23)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (23), DFS
+ # 60 GHz band channels 2-4 at 10mW,
+ # ref: http://www.arib.or.jp/english/html/overview/doc/1-STD-T74v1_1.pdf
+ (59000 - 66000 @ 2160), (10 mW)
+
+country KE: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23)
+ (5490 - 5570 @ 80), (30), DFS
+ (5735 - 5775 @ 40), (23)
+
+country KH: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source
+# http://ntrc.kn/?page_id=7
+country KN: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (30), DFS
+ (5735 - 5815 @ 80), (30)
+
+country KP: DFS-JP
+ (2402 - 2482 @ 20), (20)
+ (5170 - 5250 @ 20), (20)
+ (5250 - 5330 @ 20), (20), DFS
+ (5490 - 5630 @ 20), (30), DFS
+ (5735 - 5815 @ 20), (30)
+
+country KR: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (30), DFS
+ (5735 - 5835 @ 80), (30)
+
+country KW: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+
+country KY: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country KZ:
+ (2402 - 2482 @ 40), (20)
+
+country LB: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://www.ntrc.org.lc/operational_structures.htm
+country LC: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (30), DFS
+ (5735 - 5815 @ 80), (30)
+
+country LI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country LK: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (17)
+ (5250 - 5330 @ 20), (24), DFS
+ (5490 - 5730 @ 20), (24), DFS
+ (5735 - 5835 @ 20), (30)
+
+# Source:
+# http://lca.org.ls/images/documents/lesotho_national_frequency_allocation_plan.pdf
+country LS: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country LT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country LU: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country LV: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country MA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+
+country MC: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source:
+# http://www.cnfr.md/index.php?pag=sec&id=117&l=en
+country MD: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source:
+# http://www.cept.org/files/1050/Tools%20and%20Services/EFIS%20-%20ECO%20Frequency%20Information%20System/National%20frequency%20tables/Montenegro%20NAFT%20-%202010.pdf
+country ME: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country MF: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country MH: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country MK: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country MN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country MO: DFS-FCC
+ (2402 - 2482 @ 40), (23)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5835 @ 80), (30)
+
+country MP: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country MQ: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source:
+# http://www.are.mr/pdfs/telec_freq_TNAbf_2010.pdf
+country MR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country MT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country MU: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://www.cam.gov.mv/docs/tech_standards/TAM-TS-100-2004-WLAN.pdf
+country MV: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (200 mW), AUTO-BW
+ (5250 - 5350 @ 80), (100 mW), DFS, AUTO-BW
+ (5725 - 5850 @ 80), (100 mW)
+
+country MW: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country MX: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country MY: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5650 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (24)
+
+country NG: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5250 - 5330 @ 80), (30), DFS
+ (5735 - 5835 @ 80), (30)
+
+country NI: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country NL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), NO-OUTDOOR, AUTO-BW
+ (5250 - 5330 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+# Data from http://www.lovdata.no/dokument/SF/forskrift/2012-01-19-77
+# Power at 5250 - 5350 MHz, 5470 - 5725 MHz and 5815 – 5850 MHz can
+# be doubled if TPC is implemented.
+# Up to 2W (or 4W with TPC) is allowed in the 5725 – 5795 MHz band
+# which has been merged with 5470 - 5725 MHz to allow wide channels
+country NO: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (200 mW), AUTO-BW
+ (5250 - 5350 @ 80), (100 mW), DFS, AUTO-BW
+ (5470 - 5795 @ 160), (500 mW), DFS
+ (5815 - 5850 @ 35), (2000 mW), DFS
+ (17100 - 17300 @ 200), (100 mW)
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country NP: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (20)
+
+country NZ: DFS-ETSI
+ (2402 - 2482 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country OM: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country PA: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country PE: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PF: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country PG: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PH: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PK: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country PL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country PM: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country PR: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country PW: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PY: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country QA: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country RE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country RO: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+
+# Source:
+# http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf
+country RS: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5350 @ 40), (200 mW), NO-OUTDOOR
+ (5470 - 5725 @ 20), (1000 mW), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country RU: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5650 - 5730 @ 80), (30), DFS
+ (5735 - 5835 @ 80), (30)
+ # 60 GHz band channels 1-4, ref: Changes to NLA 124_Order â„–129_22042015.pdf
+ (57000 - 66000 @ 2160), (40)
+
+country RW: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country SA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country SE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country SG: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country SI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country SK: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+# Source:
+# Regulation N° 2004-005 ART/DG/DRC/D.Rég
+country SN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country SR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country SV: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 20), (17)
+ (5250 - 5330 @ 20), (23), DFS
+ (5735 - 5835 @ 20), (30)
+
+country SY:
+ (2402 - 2482 @ 40), (20)
+
+# Source:
+# http://www.telecommission.tc/Spectrum-plan20110324-101210.html
+country TC: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country TD: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country TG: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 40), (20)
+ (5250 - 5330 @ 40), (20), DFS
+ (5490 - 5710 @ 40), (27), DFS
+
+country TH: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country TN: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+
+country TR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country TT: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# Table of Frequency Allocations of Republic of China (Taiwan) / Nov 2014:
+# http://www.motc.gov.tw/websitedowndoc?file=post/201411171137330.doc& \
+# filedisplay=Table+of+radio+frequency+allocation.doc
+# LP0002 Low-power Radio-frequency Devices Technical Regulations / 28 Jun 2011:
+# http://www.ncc.gov.tw/english/show_file.aspx?table_name=news&file_sn=681
+# (section 3.10.1, 4.7)
+country TW: DFS-FCC
+ (2400 - 2483.5 @ 40), (30)
+ # Follow US 5.15 ~ 5.25 GHz: 30 dBm for master mode, 23 dBm for clients
+ (5150 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5350 @ 80), (23), DFS, AUTO-BW
+ (5470 - 5725 @ 160), (23), DFS
+ (5725 - 5850 @ 80), (30)
+
+country TZ:
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# #914 / 06 Sep 2007: http://www.ucrf.gov.ua/uk/doc/nkrz/1196068874
+# #1174 / 23 Oct 2008: http://www.nkrz.gov.ua/uk/activities/ruling/1225269361
+# (appendix 8)
+# Listed 5GHz range is a lowest common denominator for all related
+# rules in the referenced laws. Such a range is used because of
+# disputable definitions there.
+country UA: DFS-ETSI
+ (2400 - 2483.5 @ 40), (20), NO-OUTDOOR
+ (5150 - 5250 @ 80), (20), NO-OUTDOOR, AUTO-BW
+ (5250 - 5350 @ 80), (20), DFS, NO-OUTDOOR, AUTO-BW
+ (5490 - 5670 @ 160), (20), DFS
+ (5735 - 5835 @ 80), (20)
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+country UG: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country US: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ # 5.15 ~ 5.25 GHz: 30 dBm for master mode, 23 dBm for clients
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (23), DFS
+ (5735 - 5835 @ 80), (30)
+ # 60g band
+ # reference: http://cfr.regstoday.com/47cfr15.aspx#47_CFR_15p255
+ # channels 1,2,3, EIRP=40dBm(43dBm peak)
+ (57240 - 63720 @ 2160), (40)
+
+country UY: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://cemc.uz/article/1976/
+country UZ: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+
+# Source:
+# http://www.ntrc.vc/regulations/Jun_2006_Spectrum_Managment_Regulations.pdf
+country VC: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+# Source:
+# Official Gazette (Gaceta Oficial) concerning Unlicensed transmitter use
+# (10 June 2013)
+# http://www.conatel.gob.ve/
+country VE: DFS-FCC
+ (2402 - 2482 @ 40), (30)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5735 - 5835 @ 80), (30)
+
+country VI: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (24), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country VN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+# Source:
+# http://www.trr.vu/attachments/category/130/GURL_for_Short-range_Radiocommunication_Devices2.pdf
+country VU: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17), AUTO-BW
+ (5250 - 5330 @ 80), (24), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country WF: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country WS: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 40), (20)
+ (5250 - 5330 @ 40), (20), DFS
+ (5490 - 5710 @ 40), (27), DFS
+
+country YE:
+ (2402 - 2482 @ 40), (20)
+
+country YT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+country ZA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (30)
+
+country ZW: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
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 0000000..3987aae
--- /dev/null
+++ b/package/kernel/mac80211/patches/000-fix_kconfig.patch
@@ -0,0 +1,14 @@
+--- a/kconf/Makefile
++++ b/kconf/Makefile
+@@ -1,9 +1,9 @@
+-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_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) -DLOCALE
++mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags)
+ mconf_LDFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
+ mconf: CFLAGS += $(mconf_CFLAGS)
+
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 0000000..402649d
--- /dev/null
+++ b/package/kernel/mac80211/patches/001-fix_build.patch
@@ -0,0 +1,167 @@
+--- a/Makefile
++++ b/Makefile
+@@ -5,7 +5,7 @@
+ ifeq ($(KERNELRELEASE),)
+
+ MAKEFLAGS += --no-print-directory
+-SHELL := /bin/bash
++SHELL := /usr/bin/env bash
+ BACKPORT_DIR := $(shell pwd)
+
+ KMODDIR ?= updates
+@@ -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_DIR 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,57 +62,61 @@ 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-4]\|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 19 | sed 's/^/3./')" ;\
+- kvers="$$kvers $$(seq 0 99 | sed 's/^/4./')" ;\
+- print=0 ;\
+- for v in $$kvers ; do \
+- if [ "$$print" = "1" ] ; then \
+- echo config 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-4]\|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 19 | sed 's/^/3./')" ;\
++ kvers="$$kvers $$(seq 0 99 | sed 's/^/4./')" ;\
++ print=0 ;\
++ for v in $$kvers ; do \
++ if [ "$$print" = "1" ] ; then \
++ echo config 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 "$@"
+
+ .PHONY: defconfig-help
+--- a/Makefile.real
++++ b/Makefile.real
+@@ -59,7 +59,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" ;\
+@@ -80,7 +80,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 0000000..bd5bebf
--- /dev/null
+++ b/package/kernel/mac80211/patches/002-change_allconfig.patch
@@ -0,0 +1,64 @@
+--- a/kconf/conf.c
++++ b/kconf/conf.c
+@@ -593,40 +593,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;
+--- a/kconf/confdata.c
++++ b/kconf/confdata.c
+@@ -1169,6 +1169,8 @@ bool conf_set_all_new_symbols(enum conf_
+ }
+ bool has_changed = false;
+
++ sym_clear_all_valid();
++
+ for_all_symbols(i, sym) {
+ if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
+ continue;
+@@ -1212,8 +1214,6 @@ bool conf_set_all_new_symbols(enum conf_
+
+ }
+
+- sym_clear_all_valid();
+-
+ /*
+ * We have different type of choice blocks.
+ * If curr.tri equals to mod then we can select several
diff --git a/package/kernel/mac80211/patches/003-remove_bogus_modparams.patch b/package/kernel/mac80211/patches/003-remove_bogus_modparams.patch
new file mode 100644
index 0000000..8fa465a
--- /dev/null
+++ b/package/kernel/mac80211/patches/003-remove_bogus_modparams.patch
@@ -0,0 +1,34 @@
+--- a/compat/main.c
++++ b/compat/main.c
+@@ -20,31 +20,6 @@ MODULE_LICENSE("GPL");
+ #error "You need a CPTCFG_VERSION"
+ #endif
+
+-static char *backported_kernel_name = CPTCFG_KERNEL_NAME;
+-
+-module_param(backported_kernel_name, charp, 0400);
+-MODULE_PARM_DESC(backported_kernel_name,
+- "The kernel tree name that was used for this backport (" CPTCFG_KERNEL_NAME ")");
+-
+-#ifdef BACKPORTS_GIT_TRACKED
+-static char *backports_tracker_id = BACKPORTS_GIT_TRACKED;
+-module_param(backports_tracker_id, charp, 0400);
+-MODULE_PARM_DESC(backports_tracker_id,
+- "The version of the tree containing this backport (" BACKPORTS_GIT_TRACKED ")");
+-#else
+-static char *backported_kernel_version = CPTCFG_KERNEL_VERSION;
+-static char *backports_version = CPTCFG_VERSION;
+-
+-module_param(backported_kernel_version, charp, 0400);
+-MODULE_PARM_DESC(backported_kernel_version,
+- "The kernel version that was used for this backport (" CPTCFG_KERNEL_VERSION ")");
+-
+-module_param(backports_version, charp, 0400);
+-MODULE_PARM_DESC(backports_version,
+- "The git version of the backports tree used to generate this backport (" CPTCFG_VERSION ")");
+-
+-#endif
+-
+ void backport_dependency_symbol(void)
+ {
+ }
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 0000000..c5a92d6
--- /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/030-rt2x00_options.patch b/package/kernel/mac80211/patches/030-rt2x00_options.patch
new file mode 100644
index 0000000..a25aeb2
--- /dev/null
+++ b/package/kernel/mac80211/patches/030-rt2x00_options.patch
@@ -0,0 +1,47 @@
+--- a/drivers/net/wireless/rt2x00/Kconfig
++++ b/drivers/net/wireless/rt2x00/Kconfig
+@@ -225,36 +225,37 @@ config RT2800SOC
+
+
+ config RT2800_LIB
+- tristate
++ tristate "RT2800 USB/PCI support"
+ depends on m
+
+ config RT2800_LIB_MMIO
+- tristate
++ tristate "RT2800 MMIO support"
+ depends on m
+ select RT2X00_LIB_MMIO
+ select RT2800_LIB
+
+ config RT2X00_LIB_MMIO
+- tristate
++ tristate "RT2x00 MMIO support"
+ depends on m
+
+ config RT2X00_LIB_PCI
+- tristate
++ tristate "RT2x00 PCI support"
+ 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 m
+ select RT2X00_LIB
+
+ config RT2X00_LIB
+- tristate
++ tristate "RT2x00 support"
+ depends on m
+
+ config RT2X00_LIB_FIRMWARE
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 0000000..8a6cae6
--- /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 0000000..50d3df8
--- /dev/null
+++ b/package/kernel/mac80211/patches/050-lib80211_option.patch
@@ -0,0 +1,30 @@
+--- a/net/wireless/Kconfig
++++ b/net/wireless/Kconfig
+@@ -184,7 +184,7 @@ config CFG80211_WEXT_EXPORT
+ wext compatibility symbols to be exported.
+
+ config LIB80211
+- tristate
++ tristate "lib80211"
+ depends on m
+ default n
+ help
+@@ -194,15 +194,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 0000000..69c9e01
--- /dev/null
+++ b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
@@ -0,0 +1,130 @@
+--- a/.local-symbols
++++ b/.local-symbols
+@@ -454,43 +454,6 @@ USB_IPHETH=
+ USB_SIERRA_NET=
+ USB_VL600=
+ USB_NET_CH9200=
+-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_HOST_SOC=
+-BCMA_DRIVER_PCI=
+-BCMA_DRIVER_PCI_HOSTMODE=
+-BCMA_DRIVER_MIPS=
+-BCMA_SFLASH=
+-BCMA_NFLASH=
+-BCMA_DRIVER_GMAC_CMN=
+-BCMA_DRIVER_GPIO=
+-BCMA_DEBUG=
+ NFC=
+ NFC_DIGITAL=
+ NFC_NCI=
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -2867,7 +2867,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;
+@@ -4904,7 +4904,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. */
+-#if defined(CPTCFG_B43_SSB) && defined(CPTCFG_SSB_DRIVER_PCICORE)
++#if defined(CPTCFG_B43_SSB) && defined(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
+--- a/Kconfig.sources
++++ b/Kconfig.sources
+@@ -9,9 +9,6 @@ source "$BACKPORT_DIR/drivers/net/wirele
+ source "$BACKPORT_DIR/drivers/net/ethernet/Kconfig"
+ source "$BACKPORT_DIR/drivers/net/usb/Kconfig"
+
+-source "$BACKPORT_DIR/drivers/ssb/Kconfig"
+-source "$BACKPORT_DIR/drivers/bcma/Kconfig"
+-
+ source "$BACKPORT_DIR/net/nfc/Kconfig"
+
+ source "$BACKPORT_DIR/drivers/media/Kconfig"
+--- a/Makefile.kernel
++++ b/Makefile.kernel
+@@ -38,8 +38,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_NFC) += net/nfc/
diff --git a/package/kernel/mac80211/patches/070-ath_common_config.patch b/package/kernel/mac80211/patches/070-ath_common_config.patch
new file mode 100644
index 0000000..c6e9cd8
--- /dev/null
+++ b/package/kernel/mac80211/patches/070-ath_common_config.patch
@@ -0,0 +1,10 @@
+--- a/drivers/net/wireless/ath/Kconfig
++++ b/drivers/net/wireless/ath/Kconfig
+@@ -6,6 +6,7 @@ menuconfig ATH_CARDS
+ tristate "Atheros Wireless Cards"
+ depends on m
+ depends on CFG80211 && (!UML || BROKEN)
++ select ATH_COMMON
+ ---help---
+ This will enable the support for the Atheros wireless drivers.
+ ath5k, ath9k, ath9k_htc and ar9170 drivers share some common code, this option
diff --git a/package/kernel/mac80211/patches/080-disable_clk_backport.patch b/package/kernel/mac80211/patches/080-disable_clk_backport.patch
new file mode 100644
index 0000000..3765591
--- /dev/null
+++ b/package/kernel/mac80211/patches/080-disable_clk_backport.patch
@@ -0,0 +1,20 @@
+--- a/compat/compat-3.6.c
++++ b/compat/compat-3.6.c
+@@ -147,17 +147,3 @@ int sg_alloc_table_from_pages(struct sg_
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(sg_alloc_table_from_pages);
+-
+-/* whoopsie ! */
+-#ifndef CONFIG_COMMON_CLK
+-int clk_enable(struct clk *clk)
+-{
+- return 0;
+-}
+-EXPORT_SYMBOL_GPL(clk_enable);
+-
+-void clk_disable(struct clk *clk)
+-{
+-}
+-EXPORT_SYMBOL_GPL(clk_disable);
+-#endif
diff --git a/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch b/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch
new file mode 100644
index 0000000..02f46c7
--- /dev/null
+++ b/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch
@@ -0,0 +1,376 @@
+--- a/net/mac80211/Kconfig
++++ b/net/mac80211/Kconfig
+@@ -5,8 +5,6 @@ config MAC80211
+ depends on CRYPTO
+ depends on CRYPTO_ARC4
+ depends on CRYPTO_AES
+- select BPAUTO_CRYPTO_CCM
+- depends on CRYPTO_GCM
+ depends on CRC32
+ ---help---
+ This option enables the hardware independent IEEE 802.11
+--- a/net/mac80211/Makefile
++++ b/net/mac80211/Makefile
+@@ -16,9 +16,7 @@ mac80211-y := \
+ michael.o \
+ tkip.o \
+ aes_ccm.o \
+- aes_gcm.o \
+ aes_cmac.o \
+- aes_gmac.o \
+ cfg.o \
+ ethtool.o \
+ rx.o \
+--- a/net/mac80211/aes_ccm.c
++++ b/net/mac80211/aes_ccm.c
+@@ -13,89 +13,132 @@
+ #include <linux/types.h>
+ #include <linux/err.h>
+ #include <crypto/aead.h>
++#include <crypto/aes.h>
+
+ #include <net/mac80211.h>
+ #include "key.h"
+ #include "aes_ccm.h"
+
+-void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+- u8 *data, size_t data_len, u8 *mic,
+- size_t mic_len)
++static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0,
++ u8 *a, u8 *b)
+ {
+- struct scatterlist sg[3];
++ int i;
++
++ crypto_cipher_encrypt_one(tfm, b, b_0);
++
++ /* Extra Authenticate-only data (always two AES blocks) */
++ for (i = 0; i < AES_BLOCK_SIZE; i++)
++ aad[i] ^= b[i];
++ crypto_cipher_encrypt_one(tfm, b, aad);
++
++ aad += AES_BLOCK_SIZE;
++
++ for (i = 0; i < AES_BLOCK_SIZE; i++)
++ aad[i] ^= b[i];
++ crypto_cipher_encrypt_one(tfm, a, aad);
+
+- char aead_req_data[sizeof(struct aead_request) +
+- crypto_aead_reqsize(tfm)]
+- __aligned(__alignof__(struct aead_request));
+- struct aead_request *aead_req = (void *) aead_req_data;
++ /* Mask out bits from auth-only-b_0 */
++ b_0[0] &= 0x07;
+
+- memset(aead_req, 0, sizeof(aead_req_data));
++ /* S_0 is used to encrypt T (= MIC) */
++ b_0[14] = 0;
++ b_0[15] = 0;
++ crypto_cipher_encrypt_one(tfm, s_0, b_0);
++}
+
+- sg_init_table(sg, 3);
+- sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad));
+- sg_set_buf(&sg[1], data, data_len);
+- sg_set_buf(&sg[2], mic, mic_len);
+
+- aead_request_set_tfm(aead_req, tfm);
+- aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
+- aead_request_set_ad(aead_req, sg[0].length);
++void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
++ u8 *data, size_t data_len, u8 *mic,
++ size_t mic_len)
++{
++ int i, j, last_len, num_blocks;
++ u8 b[AES_BLOCK_SIZE];
++ u8 s_0[AES_BLOCK_SIZE];
++ u8 e[AES_BLOCK_SIZE];
++ u8 *pos, *cpos;
++
++ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
++ last_len = data_len % AES_BLOCK_SIZE;
++ aes_ccm_prepare(tfm, b_0, aad, s_0, b, b);
++
++ /* Process payload blocks */
++ pos = data;
++ cpos = data;
++ for (j = 1; j <= num_blocks; j++) {
++ int blen = (j == num_blocks && last_len) ?
++ last_len : AES_BLOCK_SIZE;
++
++ /* Authentication followed by encryption */
++ for (i = 0; i < blen; i++)
++ b[i] ^= pos[i];
++ crypto_cipher_encrypt_one(tfm, b, b);
++
++ b_0[14] = (j >> 8) & 0xff;
++ b_0[15] = j & 0xff;
++ crypto_cipher_encrypt_one(tfm, e, b_0);
++ for (i = 0; i < blen; i++)
++ *cpos++ = *pos++ ^ e[i];
++ }
+
+- crypto_aead_encrypt(aead_req);
++ for (i = 0; i < mic_len; i++)
++ mic[i] = b[i] ^ s_0[i];
+ }
+
+-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
++int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
+ u8 *data, size_t data_len, u8 *mic,
+ size_t mic_len)
+ {
+- struct scatterlist sg[3];
+- char aead_req_data[sizeof(struct aead_request) +
+- crypto_aead_reqsize(tfm)]
+- __aligned(__alignof__(struct aead_request));
+- struct aead_request *aead_req = (void *) aead_req_data;
+-
+- if (data_len == 0)
+- return -EINVAL;
+-
+- memset(aead_req, 0, sizeof(aead_req_data));
+-
+- sg_init_table(sg, 3);
+- sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad));
+- sg_set_buf(&sg[1], data, data_len);
+- sg_set_buf(&sg[2], mic, mic_len);
+-
+- aead_request_set_tfm(aead_req, tfm);
+- aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
+- aead_request_set_ad(aead_req, sg[0].length);
++ int i, j, last_len, num_blocks;
++ u8 *pos, *cpos;
++ u8 a[AES_BLOCK_SIZE];
++ u8 b[AES_BLOCK_SIZE];
++ u8 s_0[AES_BLOCK_SIZE];
++
++ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
++ last_len = data_len % AES_BLOCK_SIZE;
++ aes_ccm_prepare(tfm, b_0, aad, s_0, a, b);
++
++ /* Process payload blocks */
++ cpos = data;
++ pos = data;
++ for (j = 1; j <= num_blocks; j++) {
++ int blen = (j == num_blocks && last_len) ?
++ last_len : AES_BLOCK_SIZE;
++
++ /* Decryption followed by authentication */
++ b_0[14] = (j >> 8) & 0xff;
++ b_0[15] = j & 0xff;
++ crypto_cipher_encrypt_one(tfm, b, b_0);
++ for (i = 0; i < blen; i++) {
++ *pos = *cpos++ ^ b[i];
++ a[i] ^= *pos++;
++ }
++ crypto_cipher_encrypt_one(tfm, a, a);
++ }
++
++ for (i = 0; i < mic_len; i++) {
++ if ((mic[i] ^ s_0[i]) != a[i])
++ return -1;
++ }
+
+- return crypto_aead_decrypt(aead_req);
++ return 0;
+ }
+
+-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
+- size_t key_len,
+- size_t mic_len)
++struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
++ size_t key_len,
++ size_t mic_len)
+ {
+- struct crypto_aead *tfm;
+- int err;
++ struct crypto_cipher *tfm;
+
+- tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
+- if (IS_ERR(tfm))
+- return tfm;
+-
+- err = crypto_aead_setkey(tfm, key, key_len);
+- if (err)
+- goto free_aead;
+- err = crypto_aead_setauthsize(tfm, mic_len);
+- if (err)
+- goto free_aead;
++ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
++ if (!IS_ERR(tfm))
++ crypto_cipher_setkey(tfm, key, key_len);
+
+ return tfm;
+-
+-free_aead:
+- crypto_free_aead(tfm);
+- return ERR_PTR(err);
+ }
+
+-void ieee80211_aes_key_free(struct crypto_aead *tfm)
++
++void ieee80211_aes_key_free(struct crypto_cipher *tfm)
+ {
+- crypto_free_aead(tfm);
++ crypto_free_cipher(tfm);
+ }
+--- a/net/mac80211/aes_ccm.h
++++ b/net/mac80211/aes_ccm.h
+@@ -12,15 +12,15 @@
+
+ #include <linux/crypto.h>
+
+-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
+- size_t key_len,
+- size_t mic_len);
+-void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
++struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
++ size_t key_len,
++ size_t mic_len);
++void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
+ u8 *data, size_t data_len, u8 *mic,
+ size_t mic_len);
+-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
++int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
+ u8 *data, size_t data_len, u8 *mic,
+ size_t mic_len);
+-void ieee80211_aes_key_free(struct crypto_aead *tfm);
++void ieee80211_aes_key_free(struct crypto_cipher *tfm);
+
+ #endif /* AES_CCM_H */
+--- a/net/mac80211/aes_gcm.h
++++ b/net/mac80211/aes_gcm.h
+@@ -11,12 +11,28 @@
+
+ #include <linux/crypto.h>
+
+-void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
+- u8 *data, size_t data_len, u8 *mic);
+-int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
+- u8 *data, size_t data_len, u8 *mic);
+-struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
+- size_t key_len);
+-void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
++static inline void
++ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
++ u8 *data, size_t data_len, u8 *mic)
++{
++}
++
++static inline int
++ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
++ u8 *data, size_t data_len, u8 *mic)
++{
++ return -EOPNOTSUPP;
++}
++
++static inline struct crypto_aead *
++ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
++{
++ return NULL;
++}
++
++static inline void
++ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
++{
++}
+
+ #endif /* AES_GCM_H */
+--- a/net/mac80211/aes_gmac.h
++++ b/net/mac80211/aes_gmac.h
+@@ -11,10 +11,22 @@
+
+ #include <linux/crypto.h>
+
+-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
+- size_t key_len);
+-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
+- const u8 *data, size_t data_len, u8 *mic);
+-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
++static inline struct crypto_aead *
++ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len)
++{
++ return NULL;
++}
++
++static inline int
++ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
++ const u8 *data, size_t data_len, u8 *mic)
++{
++ return -EOPNOTSUPP;
++}
++
++static inline void
++ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
++{
++}
+
+ #endif /* AES_GMAC_H */
+--- a/net/mac80211/key.h
++++ b/net/mac80211/key.h
+@@ -84,7 +84,7 @@ struct ieee80211_key {
+ * Management frames.
+ */
+ u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
+- struct crypto_aead *tfm;
++ struct crypto_cipher *tfm;
+ u32 replays; /* dot11RSNAStatsCCMPReplays */
+ } ccmp;
+ struct {
+--- a/net/mac80211/wpa.c
++++ b/net/mac80211/wpa.c
+@@ -307,7 +307,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
+ }
+
+
+-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
++static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad,
++ u16 data_len)
+ {
+ __le16 mask_fc;
+ int a4_included, mgmt;
+@@ -337,14 +338,8 @@ static void ccmp_special_blocks(struct s
+ else
+ qos_tid = 0;
+
+- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
+- * mode authentication are not allowed to collide, yet both are derived
+- * from this vector b_0. We only set L := 1 here to indicate that the
+- * data size can be represented in (L+1) bytes. The CCM layer will take
+- * care of storing the data length in the top (L+1) bytes and setting
+- * and clearing the other bits as is required to derive the two IVs.
+- */
+- b_0[0] = 0x1;
++ /* First block, b_0 */
++ b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
+
+ /* Nonce: Nonce Flags | A2 | PN
+ * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
+@@ -352,6 +347,8 @@ static void ccmp_special_blocks(struct s
+ b_0[1] = qos_tid | (mgmt << 4);
+ memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
+ memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
++ /* l(m) */
++ put_unaligned_be16(data_len, &b_0[14]);
+
+ /* AAD (extra authenticate-only data) / masked 802.11 header
+ * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
+@@ -463,7 +460,7 @@ static int ccmp_encrypt_skb(struct ieee8
+ return 0;
+
+ pos += IEEE80211_CCMP_HDR_LEN;
+- ccmp_special_blocks(skb, pn, b_0, aad);
++ ccmp_special_blocks(skb, pn, b_0, aad, len);
+ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
+ skb_put(skb, mic_len), mic_len);
+
+@@ -534,7 +531,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+ u8 aad[2 * AES_BLOCK_SIZE];
+ u8 b_0[AES_BLOCK_SIZE];
+ /* hardware didn't decrypt/verify MIC */
+- ccmp_special_blocks(skb, pn, b_0, aad);
++ ccmp_special_blocks(skb, pn, b_0, aad, data_len);
+
+ if (ieee80211_aes_ccm_decrypt(
+ key->u.ccmp.tfm, b_0, aad,
diff --git a/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch
new file mode 100644
index 0000000..d1d9fbd
--- /dev/null
+++ b/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch
@@ -0,0 +1,12 @@
+Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
+
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -846,7 +846,6 @@ static int ieee80211_stop_ap(struct wiph
+ sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
+
+ __sta_info_flush(sdata, true);
+- ieee80211_free_keys(sdata, true);
+
+ sdata->vif.bss_conf.enable_beacon = false;
+ sdata->vif.bss_conf.ssid_len = 0;
diff --git a/package/kernel/mac80211/patches/120-cfg80211_allow_perm_addr_change.patch b/package/kernel/mac80211/patches/120-cfg80211_allow_perm_addr_change.patch
new file mode 100644
index 0000000..ffd8807
--- /dev/null
+++ b/package/kernel/mac80211/patches/120-cfg80211_allow_perm_addr_change.patch
@@ -0,0 +1,43 @@
+--- a/net/wireless/sysfs.c
++++ b/net/wireless/sysfs.c
+@@ -24,18 +24,35 @@ static inline struct cfg80211_registered
+ return container_of(dev, struct cfg80211_registered_device, wiphy.dev);
+ }
+
+-#define SHOW_FMT(name, fmt, member) \
++#define SHOW_FMT(name, fmt, member, mode) \
+ static ssize_t name ## _show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+ { \
+ return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \
+ } \
+-static DEVICE_ATTR_RO(name)
++static DEVICE_ATTR_##mode(name)
+
+-SHOW_FMT(index, "%d", wiphy_idx);
+-SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
+-SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
++static ssize_t macaddress_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t len)
++{
++ u8 mac[ETH_ALEN];
++
++ if (!mac_pton(buf, mac))
++ return -EINVAL;
++
++ if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
++ return -EINVAL;
++
++ memcpy(dev_to_rdev(dev)->wiphy.perm_addr, mac, ETH_ALEN);
++
++ return strnlen(buf, len);
++}
++
++SHOW_FMT(index, "%d", wiphy_idx, RO);
++SHOW_FMT(macaddress, "%pM", wiphy.perm_addr, RW);
++SHOW_FMT(address_mask, "%pM", wiphy.addr_mask, RO);
+
+ static ssize_t name_show(struct device *dev,
+ struct device_attribute *attr,
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 0000000..cafed72
--- /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
+@@ -285,7 +285,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)
+ {
+@@ -344,7 +344,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)
+ {
+@@ -1081,14 +1081,14 @@ int ieee80211_register_hw(struct ieee802
+
+ rtnl_unlock();
+
+-#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)
+@@ -1097,13 +1097,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:
+ #endif
+ rtnl_lock();
+@@ -1131,10 +1131,10 @@ void ieee80211_unregister_hw(struct ieee
+ tasklet_kill(&local->tx_pending_tasklet);
+ tasklet_kill(&local->tasklet);
+
+-#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 0000000..21516ff
--- /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
+@@ -869,10 +869,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/210-ap_scan.patch b/package/kernel/mac80211/patches/210-ap_scan.patch
new file mode 100644
index 0000000..2980f8b
--- /dev/null
+++ b/package/kernel/mac80211/patches/210-ap_scan.patch
@@ -0,0 +1,11 @@
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1981,7 +1981,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/300-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/300-ath9k-force-rx_clear-when-disabling-rx.patch
new file mode 100644
index 0000000..bddb15a
--- /dev/null
+++ b/package/kernel/mac80211/patches/300-ath9k-force-rx_clear-when-disabling-rx.patch
@@ -0,0 +1,31 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sun, 7 Jun 2015 13:53:35 +0200
+Subject: [PATCH] ath9k: force rx_clear when disabling rx
+
+This makes stopping Rx more reliable and should reduce the frequency of
+Rx related DMA stop warnings
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -677,13 +677,15 @@ void ath9k_hw_startpcureceive(struct ath
+
+ ath9k_ani_reset(ah, is_scanning);
+
+- REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
++ REG_CLR_BIT(ah, AR_DIAG_SW,
++ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR);
+ }
+ EXPORT_SYMBOL(ath9k_hw_startpcureceive);
+
+ void ath9k_hw_abortpcurecv(struct ath_hw *ah)
+ {
+- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
++ REG_SET_BIT(ah, AR_DIAG_SW,
++ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR);
+
+ ath9k_hw_disable_mib_counters(ah);
+ }
diff --git a/package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch b/package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch
new file mode 100644
index 0000000..33b21e6
--- /dev/null
+++ b/package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch
@@ -0,0 +1,121 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Thu, 2 Jul 2015 15:20:56 +0200
+Subject: [PATCH] ath9k: limit retries for powersave response frames
+
+In some cases, the channel might be busy enough that an ath9k AP's
+response to PS-Poll frames might be too slow and the station has already
+gone to sleep. To avoid wasting too much airtime on this, limit the
+number of retries on such frames and ensure that no sample rate gets
+used.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -136,10 +136,25 @@ static void ath_send_bar(struct ath_atx_
+ }
+
+ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+- struct ath_buf *bf)
++ struct ath_buf *bf, bool ps)
+ {
++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
++
++ if (ps) {
++ /* Clear the first rate to avoid using a sample rate for PS frames */
++ info->control.rates[0].idx = -1;
++ info->control.rates[0].count = 0;
++ }
++
+ ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates,
+ ARRAY_SIZE(bf->rates));
++ if (!ps)
++ return;
++
++ if (bf->rates[0].count > 2)
++ bf->rates[0].count = 2;
++
++ bf->rates[1].idx = -1;
+ }
+
+ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
+@@ -1419,7 +1434,7 @@ ath_tx_form_burst(struct ath_softc *sc,
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
+ break;
+
+- ath_set_rates(tid->an->vif, tid->an->sta, bf);
++ ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
+ } while (1);
+ }
+
+@@ -1450,7 +1465,7 @@ static bool ath_tx_sched_aggr(struct ath
+ return false;
+ }
+
+- ath_set_rates(tid->an->vif, tid->an->sta, bf);
++ ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
+ if (aggr)
+ last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf,
+ tid_q, &aggr_len);
+@@ -1632,7 +1647,7 @@ void ath9k_release_buffered_frames(struc
+
+ __skb_unlink(bf->bf_mpdu, tid_q);
+ list_add_tail(&bf->list, &bf_q);
+- ath_set_rates(tid->an->vif, tid->an->sta, bf);
++ ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
+ if (bf_isampdu(bf)) {
+ ath_tx_addto_baw(sc, tid, bf);
+ bf->bf_state.bf_type &= ~BUF_AGGR;
+@@ -2278,7 +2293,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+ struct ath_txq *txq = txctl->txq;
+ struct ath_atx_tid *tid = NULL;
+ struct ath_buf *bf;
+- bool queue, skip_uapsd = false, ps_resp;
++ bool queue, ps_resp;
+ int q, ret;
+
+ if (vif)
+@@ -2325,13 +2340,13 @@ int ath_tx_start(struct ieee80211_hw *hw
+ if (!txctl->an)
+ txctl->an = &avp->mcast_node;
+ queue = true;
+- skip_uapsd = true;
++ ps_resp = false;
+ }
+
+ if (txctl->an && queue)
+ tid = ath_get_skb_tid(sc, txctl->an, skb);
+
+- if (!skip_uapsd && ps_resp) {
++ if (ps_resp) {
+ ath_txq_unlock(sc, txq);
+ txq = sc->tx.uapsdq;
+ ath_txq_lock(sc, txq);
+@@ -2369,7 +2384,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+ if (txctl->paprd)
+ bf->bf_state.bfs_paprd_timestamp = jiffies;
+
+- ath_set_rates(vif, sta, bf);
++ ath_set_rates(vif, sta, bf, ps_resp);
+ ath_tx_send_normal(sc, txq, tid, skb);
+
+ out:
+@@ -2408,7 +2423,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw
+ break;
+
+ bf->bf_lastbf = bf;
+- ath_set_rates(vif, NULL, bf);
++ ath_set_rates(vif, NULL, bf, false);
+ ath_buf_set_rate(sc, bf, &info, fi->framelen, false);
+ duration += info.rates[0].PktDuration;
+ if (bf_tail)
+@@ -2911,7 +2926,7 @@ int ath9k_tx99_send(struct ath_softc *sc
+ return -EINVAL;
+ }
+
+- ath_set_rates(sc->tx99_vif, NULL, bf);
++ ath_set_rates(sc->tx99_vif, NULL, bf, false);
+
+ ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr);
+ ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum);
diff --git a/package/kernel/mac80211/patches/302-ath9k-fix-phyerror-codes.patch b/package/kernel/mac80211/patches/302-ath9k-fix-phyerror-codes.patch
new file mode 100644
index 0000000..944b8e7
--- /dev/null
+++ b/package/kernel/mac80211/patches/302-ath9k-fix-phyerror-codes.patch
@@ -0,0 +1,108 @@
+From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
+Date: Tue, 20 Oct 2015 14:19:26 +0200
+Subject: [PATCH] ath9k: fix phyerror codes
+
+Some of the ath9k_phyerr enums were wrong from the
+beginning (and even before). Most of the time the
+codes were used for counters to be displayed over
+debugfs, which made this a non-functional issue.
+
+Some (e.g. ATH9K_PHYERR_FALSE_RADAR_EXT) are used
+for radar detection and require the correct code
+to work as intended.
+
+This patch includes:
+a) fixes
+ ATH9K_PHYERR_FALSE_RADAR_EXT: 24 => 36
+ ATH9K_PHYERR_CCK_LENGTH_ILLEGAL: 32 => 28
+ ATH9K_PHYERR_CCK_POWER_DROP: 33 => 29
+ ATH9K_PHYERR_HT_CRC_ERROR: 34 => 32
+ ATH9K_PHYERR_HT_LENGTH_ILLEGAL: 35 => 33
+ ATH9K_PHYERR_HT_RATE_ILLEGAL: 36 => 34
+
+b) extensions
+ ATH9K_PHYERR_CCK_BLOCKER = 24
+ ATH9K_PHYERR_HT_ZLF = 35
+ ATH9K_PHYERR_GREEN_FIELD = 37
+
+Aside from the correction and completion made in
+the enum, the patch also extends the display of
+the related counters in the debugfs.
+
+Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/common-debug.c
++++ b/drivers/net/wireless/ath/ath9k/common-debug.c
+@@ -207,6 +207,7 @@ static ssize_t read_file_phy_err(struct
+ PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR);
+ PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE);
+ PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR);
++
+ PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING);
+ PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
+ PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
+@@ -214,17 +215,24 @@ static ssize_t read_file_phy_err(struct
+ PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP);
+ PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE);
+ PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART);
+- PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
++
++ PHY_ERR("CCK-BLOCKER ERR", ATH9K_PHYERR_CCK_BLOCKER);
+ PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING);
+ PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC);
+ PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
+- PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
+- PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
+ PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
+ PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP);
++ PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
++ PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
++
+ PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR);
+ PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
+ PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
++ PHY_ERR("HT-ZLF ERR", ATH9K_PHYERR_HT_ZLF);
++
++ PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
++ PHY_ERR("GREEN-FIELD ERR", ATH9K_PHYERR_GREEN_FIELD);
++ PHY_ERR("SPECTRAL ERR", ATH9K_PHYERR_SPECTRAL);
+
+ if (len > size)
+ len = size;
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -209,21 +209,25 @@ enum ath9k_phyerr {
+ ATH9K_PHYERR_OFDM_POWER_DROP = 21,
+ ATH9K_PHYERR_OFDM_SERVICE = 22,
+ ATH9K_PHYERR_OFDM_RESTART = 23,
+- ATH9K_PHYERR_FALSE_RADAR_EXT = 24,
+
++ ATH9K_PHYERR_CCK_BLOCKER = 24,
+ ATH9K_PHYERR_CCK_TIMING = 25,
+ ATH9K_PHYERR_CCK_HEADER_CRC = 26,
+ ATH9K_PHYERR_CCK_RATE_ILLEGAL = 27,
++ ATH9K_PHYERR_CCK_LENGTH_ILLEGAL = 28,
++ ATH9K_PHYERR_CCK_POWER_DROP = 29,
+ ATH9K_PHYERR_CCK_SERVICE = 30,
+ ATH9K_PHYERR_CCK_RESTART = 31,
+- ATH9K_PHYERR_CCK_LENGTH_ILLEGAL = 32,
+- ATH9K_PHYERR_CCK_POWER_DROP = 33,
+
+- ATH9K_PHYERR_HT_CRC_ERROR = 34,
+- ATH9K_PHYERR_HT_LENGTH_ILLEGAL = 35,
+- ATH9K_PHYERR_HT_RATE_ILLEGAL = 36,
++ ATH9K_PHYERR_HT_CRC_ERROR = 32,
++ ATH9K_PHYERR_HT_LENGTH_ILLEGAL = 33,
++ ATH9K_PHYERR_HT_RATE_ILLEGAL = 34,
++ ATH9K_PHYERR_HT_ZLF = 35,
++
++ ATH9K_PHYERR_FALSE_RADAR_EXT = 36,
++ ATH9K_PHYERR_GREEN_FIELD = 37,
++ ATH9K_PHYERR_SPECTRAL = 38,
+
+- ATH9K_PHYERR_SPECTRAL = 38,
+ ATH9K_PHYERR_MAX = 39,
+ };
+
diff --git a/package/kernel/mac80211/patches/303-ath10k-enable-adaptive-CCA.patch b/package/kernel/mac80211/patches/303-ath10k-enable-adaptive-CCA.patch
new file mode 100644
index 0000000..dea65bb
--- /dev/null
+++ b/package/kernel/mac80211/patches/303-ath10k-enable-adaptive-CCA.patch
@@ -0,0 +1,239 @@
+From: Maharaja <c_mkenna@qti.qualcomm.com>
+Date: Wed, 21 Oct 2015 11:49:18 +0300
+Subject: [PATCH] ath10k: enable adaptive CCA
+
+European Union has made it mandatory that all devices working in 2.4 GHz
+has to adhere to the ETSI specification (ETSI EN 300 328 V1.9.1)
+beginnig this year. The standard basically speaks about interferences
+in 2.4Ghz band.
+For example, when 802.11 device detects interference, TX must be stopped
+as long as interference is present.
+
+Adaptive CCA is a feature, when enabled the device learns from the
+environment and configures CCA levels adaptively. This will improve
+detecting interferences and the device can stop trasmissions till the
+interference is present eventually leading to good performances in
+varying interference conditions.
+
+The patch includes code for enabling adaptive CCA for 10.2.4 firmware on
+QCA988X.
+
+Signed-off-by: Maharaja <c_mkenna@qti.qualcomm.com>
+Signed-off-by: Manikanta Pubbisetty <c_mpubbi@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -151,6 +151,7 @@ static const char *const ath10k_core_fw_
+ [ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING] = "no-4addr-pad",
+ [ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT] = "skip-clock-init",
+ [ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode",
++ [ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA] = "adaptive-cca",
+ };
+
+ static unsigned int ath10k_core_get_fw_feature_str(char *buf,
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -497,6 +497,9 @@ enum ath10k_fw_features {
+ */
+ ATH10K_FW_FEATURE_RAW_MODE_SUPPORT = 10,
+
++ /* Firmware Supports Adaptive CCA*/
++ ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA = 11,
++
+ /* keep last */
+ ATH10K_FW_FEATURE_COUNT,
+ };
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -3905,6 +3905,18 @@ static int ath10k_start(struct ieee80211
+ goto err_core_stop;
+ }
+
++ if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
++ ar->fw_features)) {
++ ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
++ WMI_CCA_DETECT_LEVEL_AUTO,
++ WMI_CCA_DETECT_MARGIN_AUTO);
++ if (ret) {
++ ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
++ ret);
++ goto err_core_stop;
++ }
++ }
++
+ ret = ath10k_wmi_pdev_set_param(ar,
+ ar->wmi.pdev_param->ani_enable, 1);
+ if (ret) {
+--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
++++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
+@@ -182,6 +182,10 @@ struct wmi_ops {
+ void (*fw_stats_fill)(struct ath10k *ar,
+ struct ath10k_fw_stats *fw_stats,
+ char *buf);
++ struct sk_buff *(*gen_pdev_enable_adaptive_cca)(struct ath10k *ar,
++ u8 enable,
++ u32 detect_level,
++ u32 detect_margin);
+ };
+
+ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
+@@ -1302,4 +1306,25 @@ ath10k_wmi_fw_stats_fill(struct ath10k *
+ ar->wmi.ops->fw_stats_fill(ar, fw_stats, buf);
+ return 0;
+ }
++
++static inline int
++ath10k_wmi_pdev_enable_adaptive_cca(struct ath10k *ar, u8 enable,
++ u32 detect_level, u32 detect_margin)
++{
++ struct sk_buff *skb;
++
++ if (!ar->wmi.ops->gen_pdev_enable_adaptive_cca)
++ return -EOPNOTSUPP;
++
++ skb = ar->wmi.ops->gen_pdev_enable_adaptive_cca(ar, enable,
++ detect_level,
++ detect_margin);
++
++ if (IS_ERR(skb))
++ return PTR_ERR(skb);
++
++ return ath10k_wmi_cmd_send(ar, skb,
++ ar->wmi.cmd->pdev_enable_adaptive_cca_cmdid);
++}
++
+ #endif
+--- a/drivers/net/wireless/ath/ath10k/wmi.c
++++ b/drivers/net/wireless/ath/ath10k/wmi.c
+@@ -148,6 +148,7 @@ static struct wmi_cmd_map wmi_cmd_map =
+ .gpio_config_cmdid = WMI_GPIO_CONFIG_CMDID,
+ .gpio_output_cmdid = WMI_GPIO_OUTPUT_CMDID,
+ .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
++ .pdev_enable_adaptive_cca_cmdid = WMI_CMD_UNSUPPORTED,
+ .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
+ .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
+ .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
+@@ -313,6 +314,7 @@ static struct wmi_cmd_map wmi_10x_cmd_ma
+ .gpio_config_cmdid = WMI_10X_GPIO_CONFIG_CMDID,
+ .gpio_output_cmdid = WMI_10X_GPIO_OUTPUT_CMDID,
+ .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
++ .pdev_enable_adaptive_cca_cmdid = WMI_CMD_UNSUPPORTED,
+ .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
+ .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
+ .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
+@@ -477,6 +479,7 @@ static struct wmi_cmd_map wmi_10_2_4_cmd
+ .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID,
+ .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID,
+ .pdev_get_temperature_cmdid = WMI_10_2_PDEV_GET_TEMPERATURE_CMDID,
++ .pdev_enable_adaptive_cca_cmdid = WMI_10_2_SET_CCA_PARAMS,
+ .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
+ .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
+ .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
+@@ -1407,6 +1410,7 @@ static struct wmi_cmd_map wmi_10_2_cmd_m
+ .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID,
+ .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID,
+ .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
++ .pdev_enable_adaptive_cca_cmdid = WMI_CMD_UNSUPPORTED,
+ .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
+ .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
+ .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
+@@ -6996,6 +7000,28 @@ unlock:
+ buf[len] = 0;
+ }
+
++static struct sk_buff *
++ath10k_wmi_op_gen_pdev_enable_adaptive_cca(struct ath10k *ar, u8 enable,
++ u32 detect_level, u32 detect_margin)
++{
++ struct wmi_pdev_set_adaptive_cca_params *cmd;
++ struct sk_buff *skb;
++
++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
++ if (!skb)
++ return ERR_PTR(-ENOMEM);
++
++ cmd = (struct wmi_pdev_set_adaptive_cca_params *)skb->data;
++ cmd->enable = __cpu_to_le32(enable);
++ cmd->cca_detect_level = __cpu_to_le32(detect_level);
++ cmd->cca_detect_margin = __cpu_to_le32(detect_margin);
++
++ ath10k_dbg(ar, ATH10K_DBG_WMI,
++ "wmi pdev set adaptive cca params enable:%d detection level:%d detection margin:%d\n",
++ enable, detect_level, detect_margin);
++ return skb;
++}
++
+ static const struct wmi_ops wmi_ops = {
+ .rx = ath10k_wmi_op_rx,
+ .map_svc = wmi_main_svc_map,
+@@ -7059,6 +7085,7 @@ static const struct wmi_ops wmi_ops = {
+ /* .gen_prb_tmpl not implemented */
+ /* .gen_p2p_go_bcn_ie not implemented */
+ /* .gen_adaptive_qcs not implemented */
++ /* .gen_pdev_enable_adaptive_cca not implemented */
+ };
+
+ static const struct wmi_ops wmi_10_1_ops = {
+@@ -7125,6 +7152,7 @@ static const struct wmi_ops wmi_10_1_ops
+ /* .gen_prb_tmpl not implemented */
+ /* .gen_p2p_go_bcn_ie not implemented */
+ /* .gen_adaptive_qcs not implemented */
++ /* .gen_pdev_enable_adaptive_cca not implemented */
+ };
+
+ static const struct wmi_ops wmi_10_2_ops = {
+@@ -7188,6 +7216,7 @@ static const struct wmi_ops wmi_10_2_ops
+ .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
+ .gen_delba_send = ath10k_wmi_op_gen_delba_send,
+ .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
++ /* .gen_pdev_enable_adaptive_cca not implemented */
+ };
+
+ static const struct wmi_ops wmi_10_2_4_ops = {
+@@ -7251,6 +7280,8 @@ static const struct wmi_ops wmi_10_2_4_o
+ .gen_delba_send = ath10k_wmi_op_gen_delba_send,
+ .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
+ .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
++ .gen_pdev_enable_adaptive_cca =
++ ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
+ /* .gen_bcn_tmpl not implemented */
+ /* .gen_prb_tmpl not implemented */
+ /* .gen_p2p_go_bcn_ie not implemented */
+--- a/drivers/net/wireless/ath/ath10k/wmi.h
++++ b/drivers/net/wireless/ath/ath10k/wmi.h
+@@ -772,6 +772,7 @@ struct wmi_cmd_map {
+ u32 mu_cal_start_cmdid;
+ u32 set_cca_params_cmdid;
+ u32 pdev_bss_chan_info_request_cmdid;
++ u32 pdev_enable_adaptive_cca_cmdid;
+ };
+
+ /*
+@@ -1381,6 +1382,9 @@ enum wmi_10_2_cmd_id {
+ WMI_10_2_VDEV_ATF_REQUEST_CMDID,
+ WMI_10_2_PEER_ATF_REQUEST_CMDID,
+ WMI_10_2_PDEV_GET_TEMPERATURE_CMDID,
++ WMI_10_2_MU_CAL_START_CMDID,
++ WMI_10_2_SET_LTEU_CONFIG_CMDID,
++ WMI_10_2_SET_CCA_PARAMS,
+ WMI_10_2_PDEV_UTF_CMDID = WMI_10_2_END_CMDID - 1,
+ };
+
+@@ -6094,6 +6098,15 @@ enum wmi_txbf_conf {
+ WMI_TXBF_CONF_AFTER_ASSOC,
+ };
+
++#define WMI_CCA_DETECT_LEVEL_AUTO 0
++#define WMI_CCA_DETECT_MARGIN_AUTO 0
++
++struct wmi_pdev_set_adaptive_cca_params {
++ __le32 enable;
++ __le32 cca_detect_level;
++ __le32 cca_detect_margin;
++} __packed;
++
+ struct ath10k;
+ struct ath10k_vif;
+ struct ath10k_fw_stats_pdev;
diff --git a/package/kernel/mac80211/patches/304-ath10k-add-FW-API-support-to-test-mode.patch b/package/kernel/mac80211/patches/304-ath10k-add-FW-API-support-to-test-mode.patch
new file mode 100644
index 0000000..e4ccac3
--- /dev/null
+++ b/package/kernel/mac80211/patches/304-ath10k-add-FW-API-support-to-test-mode.patch
@@ -0,0 +1,331 @@
+From: Alan Liu <alanliu@qca.qualcomm.com>
+Date: Wed, 28 Oct 2015 21:38:32 +0200
+Subject: [PATCH] ath10k: add FW API support to test mode
+
+Add WMI-TLV and FW API support in ath10k testmode.
+Ath10k can get right wmi command format from UTF image
+to communicate UTF firmware.
+
+Signed-off-by: Alan Liu <alanliu@qca.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -569,8 +569,8 @@ static int ath10k_download_fw(struct ath
+ }
+ break;
+ case ATH10K_FIRMWARE_MODE_UTF:
+- data = ar->testmode.utf->data;
+- data_len = ar->testmode.utf->size;
++ data = ar->testmode.utf_firmware_data;
++ data_len = ar->testmode.utf_firmware_len;
+ mode_name = "utf";
+ break;
+ default:
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -817,9 +817,12 @@ struct ath10k {
+ struct {
+ /* protected by conf_mutex */
+ const struct firmware *utf;
++ char utf_version[32];
++ const void *utf_firmware_data;
++ size_t utf_firmware_len;
+ DECLARE_BITMAP(orig_fw_features, ATH10K_FW_FEATURE_COUNT);
+ enum ath10k_fw_wmi_op_version orig_wmi_op_version;
+-
++ enum ath10k_fw_wmi_op_version op_version;
+ /* protected by data_lock */
+ bool utf_monitor;
+ } testmode;
+--- a/drivers/net/wireless/ath/ath10k/hw.h
++++ b/drivers/net/wireless/ath/ath10k/hw.h
+@@ -94,6 +94,7 @@ enum qca6174_chip_id_rev {
+ #define ATH10K_FW_API5_FILE "firmware-5.bin"
+
+ #define ATH10K_FW_UTF_FILE "utf.bin"
++#define ATH10K_FW_UTF_API2_FILE "utf-2.bin"
+
+ /* includes also the null byte */
+ #define ATH10K_FIRMWARE_MAGIC "QCA-ATH10K"
+--- a/drivers/net/wireless/ath/ath10k/testmode.c
++++ b/drivers/net/wireless/ath/ath10k/testmode.c
+@@ -139,11 +139,181 @@ static int ath10k_tm_cmd_get_version(str
+ return cfg80211_testmode_reply(skb);
+ }
+
+-static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[])
++static int ath10k_tm_fetch_utf_firmware_api_2(struct ath10k *ar)
++{
++ size_t len, magic_len, ie_len;
++ struct ath10k_fw_ie *hdr;
++ char filename[100];
++ __le32 *version;
++ const u8 *data;
++ int ie_id, ret;
++
++ snprintf(filename, sizeof(filename), "%s/%s",
++ ar->hw_params.fw.dir, ATH10K_FW_UTF_API2_FILE);
++
++ /* load utf firmware image */
++ ret = request_firmware(&ar->testmode.utf, filename, ar->dev);
++ if (ret) {
++ ath10k_warn(ar, "failed to retrieve utf firmware '%s': %d\n",
++ filename, ret);
++ return ret;
++ }
++
++ data = ar->testmode.utf->data;
++ len = ar->testmode.utf->size;
++
++ /* FIXME: call release_firmware() in error cases */
++
++ /* magic also includes the null byte, check that as well */
++ magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1;
++
++ if (len < magic_len) {
++ ath10k_err(ar, "utf firmware file is too small to contain magic\n");
++ ret = -EINVAL;
++ goto err;
++ }
++
++ if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) {
++ ath10k_err(ar, "invalid firmware magic\n");
++ ret = -EINVAL;
++ goto err;
++ }
++
++ /* jump over the padding */
++ magic_len = ALIGN(magic_len, 4);
++
++ len -= magic_len;
++ data += magic_len;
++
++ /* loop elements */
++ while (len > sizeof(struct ath10k_fw_ie)) {
++ hdr = (struct ath10k_fw_ie *)data;
++
++ ie_id = le32_to_cpu(hdr->id);
++ ie_len = le32_to_cpu(hdr->len);
++
++ len -= sizeof(*hdr);
++ data += sizeof(*hdr);
++
++ if (len < ie_len) {
++ ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",
++ ie_id, len, ie_len);
++ ret = -EINVAL;
++ goto err;
++ }
++
++ switch (ie_id) {
++ case ATH10K_FW_IE_FW_VERSION:
++ if (ie_len > sizeof(ar->testmode.utf_version) - 1)
++ break;
++
++ memcpy(ar->testmode.utf_version, data, ie_len);
++ ar->testmode.utf_version[ie_len] = '\0';
++
++ ath10k_dbg(ar, ATH10K_DBG_TESTMODE,
++ "testmode found fw utf version %s\n",
++ ar->testmode.utf_version);
++ break;
++ case ATH10K_FW_IE_TIMESTAMP:
++ /* ignore timestamp, but don't warn about it either */
++ break;
++ case ATH10K_FW_IE_FW_IMAGE:
++ ath10k_dbg(ar, ATH10K_DBG_TESTMODE,
++ "testmode found fw image ie (%zd B)\n",
++ ie_len);
++
++ ar->testmode.utf_firmware_data = data;
++ ar->testmode.utf_firmware_len = ie_len;
++ break;
++ case ATH10K_FW_IE_WMI_OP_VERSION:
++ if (ie_len != sizeof(u32))
++ break;
++ version = (__le32 *)data;
++ ar->testmode.op_version = le32_to_cpup(version);
++ ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode found fw ie wmi op version %d\n",
++ ar->testmode.op_version);
++ break;
++ default:
++ ath10k_warn(ar, "Unknown testmode FW IE: %u\n",
++ le32_to_cpu(hdr->id));
++ break;
++ }
++ /* jump over the padding */
++ ie_len = ALIGN(ie_len, 4);
++
++ len -= ie_len;
++ data += ie_len;
++ }
++
++ if (!ar->testmode.utf_firmware_data || !ar->testmode.utf_firmware_len) {
++ ath10k_err(ar, "No ATH10K_FW_IE_FW_IMAGE found\n");
++ ret = -EINVAL;
++ goto err;
++ }
++
++ return 0;
++
++err:
++ release_firmware(ar->testmode.utf);
++
++ return ret;
++}
++
++static int ath10k_tm_fetch_utf_firmware_api_1(struct ath10k *ar)
+ {
+ char filename[100];
+ int ret;
+
++ snprintf(filename, sizeof(filename), "%s/%s",
++ ar->hw_params.fw.dir, ATH10K_FW_UTF_FILE);
++
++ /* load utf firmware image */
++ ret = request_firmware(&ar->testmode.utf, filename, ar->dev);
++ if (ret) {
++ ath10k_warn(ar, "failed to retrieve utf firmware '%s': %d\n",
++ filename, ret);
++ return ret;
++ }
++
++ /* We didn't find FW UTF API 1 ("utf.bin") does not advertise
++ * firmware features. Do an ugly hack where we force the firmware
++ * features to match with 10.1 branch so that wmi.c will use the
++ * correct WMI interface.
++ */
++
++ ar->testmode.op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
++ ar->testmode.utf_firmware_data = ar->testmode.utf->data;
++ ar->testmode.utf_firmware_len = ar->testmode.utf->size;
++
++ return 0;
++}
++
++static int ath10k_tm_fetch_firmware(struct ath10k *ar)
++{
++ int ret;
++
++ ret = ath10k_tm_fetch_utf_firmware_api_2(ar);
++ if (ret == 0) {
++ ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode using fw utf api 2");
++ return 0;
++ }
++
++ ret = ath10k_tm_fetch_utf_firmware_api_1(ar);
++ if (ret) {
++ ath10k_err(ar, "failed to fetch utf firmware binary: %d", ret);
++ return ret;
++ }
++
++ ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode using utf api 1");
++
++ return 0;
++}
++
++static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[])
++{
++ const char *ver;
++ int ret;
++
+ ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode cmd utf start\n");
+
+ mutex_lock(&ar->conf_mutex);
+@@ -165,36 +335,27 @@ static int ath10k_tm_cmd_utf_start(struc
+ goto err;
+ }
+
+- snprintf(filename, sizeof(filename), "%s/%s",
+- ar->hw_params.fw.dir, ATH10K_FW_UTF_FILE);
+-
+- /* load utf firmware image */
+- ret = request_firmware(&ar->testmode.utf, filename, ar->dev);
++ ret = ath10k_tm_fetch_firmware(ar);
+ if (ret) {
+- ath10k_warn(ar, "failed to retrieve utf firmware '%s': %d\n",
+- filename, ret);
++ ath10k_err(ar, "failed to fetch UTF firmware: %d", ret);
+ goto err;
+ }
+
+ spin_lock_bh(&ar->data_lock);
+-
+ ar->testmode.utf_monitor = true;
+-
+ spin_unlock_bh(&ar->data_lock);
+-
+ BUILD_BUG_ON(sizeof(ar->fw_features) !=
+ sizeof(ar->testmode.orig_fw_features));
+
+ memcpy(ar->testmode.orig_fw_features, ar->fw_features,
+ sizeof(ar->fw_features));
+ ar->testmode.orig_wmi_op_version = ar->wmi.op_version;
+-
+- /* utf.bin firmware image does not advertise firmware features. Do
+- * an ugly hack where we force the firmware features so that wmi.c
+- * will use the correct WMI interface.
+- */
+ memset(ar->fw_features, 0, sizeof(ar->fw_features));
+- ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
++
++ ar->wmi.op_version = ar->testmode.op_version;
++
++ ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode wmi version %d\n",
++ ar->wmi.op_version);
+
+ ret = ath10k_hif_power_up(ar);
+ if (ret) {
+@@ -212,7 +373,12 @@ static int ath10k_tm_cmd_utf_start(struc
+
+ ar->state = ATH10K_STATE_UTF;
+
+- ath10k_info(ar, "UTF firmware started\n");
++ if (strlen(ar->testmode.utf_version) > 0)
++ ver = ar->testmode.utf_version;
++ else
++ ver = "API 1";
++
++ ath10k_info(ar, "UTF firmware %s started\n", ver);
+
+ mutex_unlock(&ar->conf_mutex);
+
+--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+@@ -23,6 +23,7 @@
+ #include "wmi-ops.h"
+ #include "wmi-tlv.h"
+ #include "p2p.h"
++#include "testmode.h"
+
+ /***************/
+ /* TLV helpers */
+@@ -419,6 +420,7 @@ static void ath10k_wmi_tlv_op_rx(struct
+ {
+ struct wmi_cmd_hdr *cmd_hdr;
+ enum wmi_tlv_event_id id;
++ bool consumed;
+
+ cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
+ id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
+@@ -428,6 +430,18 @@ static void ath10k_wmi_tlv_op_rx(struct
+
+ trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
+
++ consumed = ath10k_tm_event_wmi(ar, id, skb);
++
++ /* Ready event must be handled normally also in UTF mode so that we
++ * know the UTF firmware has booted, others we are just bypass WMI
++ * events to testmode.
++ */
++ if (consumed && id != WMI_TLV_READY_EVENTID) {
++ ath10k_dbg(ar, ATH10K_DBG_WMI,
++ "wmi tlv testmode consumed 0x%x\n", id);
++ goto out;
++ }
++
+ switch (id) {
+ case WMI_TLV_MGMT_RX_EVENTID:
+ ath10k_wmi_event_mgmt_rx(ar, skb);
diff --git a/package/kernel/mac80211/patches/305-ath10k-add-fw_stats-support-to-10.4-firmware.patch b/package/kernel/mac80211/patches/305-ath10k-add-fw_stats-support-to-10.4-firmware.patch
new file mode 100644
index 0000000..7deb19c
--- /dev/null
+++ b/package/kernel/mac80211/patches/305-ath10k-add-fw_stats-support-to-10.4-firmware.patch
@@ -0,0 +1,468 @@
+From: Manikanta Pubbisetty <c_mpubbi@qti.qualcomm.com>
+Date: Wed, 28 Oct 2015 21:38:33 +0200
+Subject: [PATCH] ath10k: add fw_stats support to 10.4 firmware
+
+This patch adds support for getting firmware debug stats in 10.4 fw.
+
+Signed-off-by: Manikanta Pubbisetty <c_mpubbi@qti.qualcomm.com>
+Signed-off-by: Tamizh chelvam <c_traja@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -214,6 +214,7 @@ struct ath10k_fw_stats_pdev {
+ s32 hw_queued;
+ s32 hw_reaped;
+ s32 underrun;
++ u32 hw_paused;
+ s32 tx_abort;
+ s32 mpdus_requed;
+ u32 tx_ko;
+@@ -226,6 +227,16 @@ struct ath10k_fw_stats_pdev {
+ u32 pdev_resets;
+ u32 phy_underrun;
+ u32 txop_ovf;
++ u32 seq_posted;
++ u32 seq_failed_queueing;
++ u32 seq_completed;
++ u32 seq_restarted;
++ u32 mu_seq_posted;
++ u32 mpdus_sw_flush;
++ u32 mpdus_hw_filter;
++ u32 mpdus_truncated;
++ u32 mpdus_ack_failed;
++ u32 mpdus_expired;
+
+ /* PDEV RX stats */
+ s32 mid_ppdu_route_change;
+@@ -242,6 +253,7 @@ struct ath10k_fw_stats_pdev {
+ s32 phy_errs;
+ s32 phy_err_drop;
+ s32 mpdu_errs;
++ s32 rx_ovfl_errs;
+ };
+
+ struct ath10k_fw_stats {
+--- a/drivers/net/wireless/ath/ath10k/wmi.c
++++ b/drivers/net/wireless/ath/ath10k/wmi.c
+@@ -2479,6 +2479,47 @@ void ath10k_wmi_pull_pdev_stats_tx(const
+ dst->txop_ovf = __le32_to_cpu(src->txop_ovf);
+ }
+
++static void
++ath10k_wmi_10_4_pull_pdev_stats_tx(const struct wmi_10_4_pdev_stats_tx *src,
++ struct ath10k_fw_stats_pdev *dst)
++{
++ dst->comp_queued = __le32_to_cpu(src->comp_queued);
++ dst->comp_delivered = __le32_to_cpu(src->comp_delivered);
++ dst->msdu_enqued = __le32_to_cpu(src->msdu_enqued);
++ dst->mpdu_enqued = __le32_to_cpu(src->mpdu_enqued);
++ dst->wmm_drop = __le32_to_cpu(src->wmm_drop);
++ dst->local_enqued = __le32_to_cpu(src->local_enqued);
++ dst->local_freed = __le32_to_cpu(src->local_freed);
++ dst->hw_queued = __le32_to_cpu(src->hw_queued);
++ dst->hw_reaped = __le32_to_cpu(src->hw_reaped);
++ dst->underrun = __le32_to_cpu(src->underrun);
++ dst->tx_abort = __le32_to_cpu(src->tx_abort);
++ dst->mpdus_requed = __le32_to_cpu(src->mpdus_requed);
++ dst->tx_ko = __le32_to_cpu(src->tx_ko);
++ dst->data_rc = __le32_to_cpu(src->data_rc);
++ dst->self_triggers = __le32_to_cpu(src->self_triggers);
++ dst->sw_retry_failure = __le32_to_cpu(src->sw_retry_failure);
++ dst->illgl_rate_phy_err = __le32_to_cpu(src->illgl_rate_phy_err);
++ dst->pdev_cont_xretry = __le32_to_cpu(src->pdev_cont_xretry);
++ dst->pdev_tx_timeout = __le32_to_cpu(src->pdev_tx_timeout);
++ dst->pdev_resets = __le32_to_cpu(src->pdev_resets);
++ dst->phy_underrun = __le32_to_cpu(src->phy_underrun);
++ dst->txop_ovf = __le32_to_cpu(src->txop_ovf);
++ dst->hw_paused = __le32_to_cpu(src->hw_paused);
++ dst->seq_posted = __le32_to_cpu(src->seq_posted);
++ dst->seq_failed_queueing =
++ __le32_to_cpu(src->seq_failed_queueing);
++ dst->seq_completed = __le32_to_cpu(src->seq_completed);
++ dst->seq_restarted = __le32_to_cpu(src->seq_restarted);
++ dst->mu_seq_posted = __le32_to_cpu(src->mu_seq_posted);
++ dst->mpdus_sw_flush = __le32_to_cpu(src->mpdus_sw_flush);
++ dst->mpdus_hw_filter = __le32_to_cpu(src->mpdus_hw_filter);
++ dst->mpdus_truncated = __le32_to_cpu(src->mpdus_truncated);
++ dst->mpdus_ack_failed = __le32_to_cpu(src->mpdus_ack_failed);
++ dst->mpdus_hw_filter = __le32_to_cpu(src->mpdus_hw_filter);
++ dst->mpdus_expired = __le32_to_cpu(src->mpdus_expired);
++}
++
+ void ath10k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src,
+ struct ath10k_fw_stats_pdev *dst)
+ {
+@@ -2789,6 +2830,86 @@ static int ath10k_wmi_10_2_4_op_pull_fw_
+ return 0;
+ }
+
++static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar,
++ struct sk_buff *skb,
++ struct ath10k_fw_stats *stats)
++{
++ const struct wmi_10_2_stats_event *ev = (void *)skb->data;
++ u32 num_pdev_stats;
++ u32 num_pdev_ext_stats;
++ u32 num_vdev_stats;
++ u32 num_peer_stats;
++ int i;
++
++ if (!skb_pull(skb, sizeof(*ev)))
++ return -EPROTO;
++
++ num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
++ num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats);
++ num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
++ num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
++
++ for (i = 0; i < num_pdev_stats; i++) {
++ const struct wmi_10_4_pdev_stats *src;
++ struct ath10k_fw_stats_pdev *dst;
++
++ src = (void *)skb->data;
++ if (!skb_pull(skb, sizeof(*src)))
++ return -EPROTO;
++
++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
++ if (!dst)
++ continue;
++
++ ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
++ ath10k_wmi_10_4_pull_pdev_stats_tx(&src->tx, dst);
++ ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
++ dst->rx_ovfl_errs = __le32_to_cpu(src->rx_ovfl_errs);
++ ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst);
++
++ list_add_tail(&dst->list, &stats->pdevs);
++ }
++
++ for (i = 0; i < num_pdev_ext_stats; i++) {
++ const struct wmi_10_2_pdev_ext_stats *src;
++
++ src = (void *)skb->data;
++ if (!skb_pull(skb, sizeof(*src)))
++ return -EPROTO;
++
++ /* FIXME: expose values to userspace
++ *
++ * Note: Even though this loop seems to do nothing it is
++ * required to parse following sub-structures properly.
++ */
++ }
++
++ /* fw doesn't implement vdev stats */
++
++ for (i = 0; i < num_peer_stats; i++) {
++ const struct wmi_10_4_peer_stats *src;
++ struct ath10k_fw_stats_peer *dst;
++
++ src = (void *)skb->data;
++ if (!skb_pull(skb, sizeof(*src)))
++ return -EPROTO;
++
++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
++ if (!dst)
++ continue;
++
++ ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr);
++ dst->peer_rssi = __le32_to_cpu(src->peer_rssi);
++ dst->peer_tx_rate = __le32_to_cpu(src->peer_tx_rate);
++ dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
++ /* FIXME: expose 10.4 specific values */
++
++ list_add_tail(&dst->list, &stats->peers);
++ }
++
++ return 0;
++}
++
+ void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb)
+ {
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n");
+@@ -4935,6 +5056,9 @@ static void ath10k_wmi_10_4_op_rx(struct
+ ath10k_dbg(ar, ATH10K_DBG_WMI,
+ "received event id %d not implemented\n", id);
+ break;
++ case WMI_10_4_UPDATE_STATS_EVENTID:
++ ath10k_wmi_event_update_stats(ar, skb);
++ break;
+ default:
+ ath10k_warn(ar, "Unknown eventid: %d\n", id);
+ break;
+@@ -7022,6 +7146,90 @@ ath10k_wmi_op_gen_pdev_enable_adaptive_c
+ return skb;
+ }
+
++void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
++ struct ath10k_fw_stats *fw_stats,
++ char *buf)
++{
++ u32 len = 0;
++ u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
++ const struct ath10k_fw_stats_pdev *pdev;
++ const struct ath10k_fw_stats_vdev *vdev;
++ const struct ath10k_fw_stats_peer *peer;
++ size_t num_peers;
++ size_t num_vdevs;
++
++ spin_lock_bh(&ar->data_lock);
++
++ pdev = list_first_entry_or_null(&fw_stats->pdevs,
++ struct ath10k_fw_stats_pdev, list);
++ if (!pdev) {
++ ath10k_warn(ar, "failed to get pdev stats\n");
++ goto unlock;
++ }
++
++ num_peers = ath10k_wmi_fw_stats_num_peers(&fw_stats->peers);
++ num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&fw_stats->vdevs);
++
++ ath10k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
++ ath10k_wmi_fw_pdev_extra_stats_fill(pdev, buf, &len);
++ ath10k_wmi_fw_pdev_tx_stats_fill(pdev, buf, &len);
++
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "HW paused", pdev->hw_paused);
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "Seqs posted", pdev->seq_posted);
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "Seqs failed queueing", pdev->seq_failed_queueing);
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "Seqs completed", pdev->seq_completed);
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "Seqs restarted", pdev->seq_restarted);
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "MU Seqs posted", pdev->mu_seq_posted);
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "MPDUs SW flushed", pdev->mpdus_sw_flush);
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "MPDUs HW filtered", pdev->mpdus_hw_filter);
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "MPDUs truncated", pdev->mpdus_truncated);
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "MPDUs receive no ACK", pdev->mpdus_ack_failed);
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "MPDUs expired", pdev->mpdus_expired);
++
++ ath10k_wmi_fw_pdev_rx_stats_fill(pdev, buf, &len);
++ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
++ "Num Rx Overflow errors", pdev->rx_ovfl_errs);
++
++ len += scnprintf(buf + len, buf_len - len, "\n");
++ len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
++ "ath10k VDEV stats", num_vdevs);
++ len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
++ "=================");
++
++ list_for_each_entry(vdev, &fw_stats->vdevs, list) {
++ ath10k_wmi_fw_vdev_stats_fill(vdev, buf, &len);
++ }
++
++ len += scnprintf(buf + len, buf_len - len, "\n");
++ len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
++ "ath10k PEER stats", num_peers);
++ len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
++ "=================");
++
++ list_for_each_entry(peer, &fw_stats->peers, list) {
++ ath10k_wmi_fw_peer_stats_fill(peer, buf, &len);
++ }
++
++unlock:
++ spin_unlock_bh(&ar->data_lock);
++
++ if (len >= buf_len)
++ buf[len - 1] = 0;
++ else
++ buf[len] = 0;
++}
++
+ static const struct wmi_ops wmi_ops = {
+ .rx = ath10k_wmi_op_rx,
+ .map_svc = wmi_main_svc_map,
+@@ -7292,6 +7500,7 @@ static const struct wmi_ops wmi_10_4_ops
+ .rx = ath10k_wmi_10_4_op_rx,
+ .map_svc = wmi_10_4_svc_map,
+
++ .pull_fw_stats = ath10k_wmi_10_4_op_pull_fw_stats,
+ .pull_scan = ath10k_wmi_op_pull_scan_ev,
+ .pull_mgmt_rx = ath10k_wmi_10_4_op_pull_mgmt_rx_ev,
+ .pull_ch_info = ath10k_wmi_10_4_op_pull_ch_info_ev,
+@@ -7341,9 +7550,11 @@ static const struct wmi_ops wmi_10_4_ops
+ .gen_addba_send = ath10k_wmi_op_gen_addba_send,
+ .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
+ .gen_delba_send = ath10k_wmi_op_gen_delba_send,
++ .fw_stats_fill = ath10k_wmi_10_4_op_fw_stats_fill,
+
+ /* shared with 10.2 */
+ .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
++ .gen_request_stats = ath10k_wmi_op_gen_request_stats,
+ };
+
+ int ath10k_wmi_attach(struct ath10k *ar)
+--- a/drivers/net/wireless/ath/ath10k/wmi.h
++++ b/drivers/net/wireless/ath/ath10k/wmi.h
+@@ -3866,6 +3866,111 @@ struct wmi_pdev_stats_tx {
+ __le32 txop_ovf;
+ } __packed;
+
++struct wmi_10_4_pdev_stats_tx {
++ /* Num HTT cookies queued to dispatch list */
++ __le32 comp_queued;
++
++ /* Num HTT cookies dispatched */
++ __le32 comp_delivered;
++
++ /* Num MSDU queued to WAL */
++ __le32 msdu_enqued;
++
++ /* Num MPDU queue to WAL */
++ __le32 mpdu_enqued;
++
++ /* Num MSDUs dropped by WMM limit */
++ __le32 wmm_drop;
++
++ /* Num Local frames queued */
++ __le32 local_enqued;
++
++ /* Num Local frames done */
++ __le32 local_freed;
++
++ /* Num queued to HW */
++ __le32 hw_queued;
++
++ /* Num PPDU reaped from HW */
++ __le32 hw_reaped;
++
++ /* Num underruns */
++ __le32 underrun;
++
++ /* HW Paused. */
++ __le32 hw_paused;
++
++ /* Num PPDUs cleaned up in TX abort */
++ __le32 tx_abort;
++
++ /* Num MPDUs requed by SW */
++ __le32 mpdus_requed;
++
++ /* excessive retries */
++ __le32 tx_ko;
++
++ /* data hw rate code */
++ __le32 data_rc;
++
++ /* Scheduler self triggers */
++ __le32 self_triggers;
++
++ /* frames dropped due to excessive sw retries */
++ __le32 sw_retry_failure;
++
++ /* illegal rate phy errors */
++ __le32 illgl_rate_phy_err;
++
++ /* wal pdev continuous xretry */
++ __le32 pdev_cont_xretry;
++
++ /* wal pdev tx timeouts */
++ __le32 pdev_tx_timeout;
++
++ /* wal pdev resets */
++ __le32 pdev_resets;
++
++ /* frames dropped due to non-availability of stateless TIDs */
++ __le32 stateless_tid_alloc_failure;
++
++ __le32 phy_underrun;
++
++ /* MPDU is more than txop limit */
++ __le32 txop_ovf;
++
++ /* Number of Sequences posted */
++ __le32 seq_posted;
++
++ /* Number of Sequences failed queueing */
++ __le32 seq_failed_queueing;
++
++ /* Number of Sequences completed */
++ __le32 seq_completed;
++
++ /* Number of Sequences restarted */
++ __le32 seq_restarted;
++
++ /* Number of MU Sequences posted */
++ __le32 mu_seq_posted;
++
++ /* Num MPDUs flushed by SW, HWPAUSED,SW TXABORT(Reset,channel change) */
++ __le32 mpdus_sw_flush;
++
++ /* Num MPDUs filtered by HW, all filter condition (TTL expired) */
++ __le32 mpdus_hw_filter;
++
++ /* Num MPDUs truncated by PDG
++ * (TXOP, TBTT, PPDU_duration based on rate, dyn_bw)
++ */
++ __le32 mpdus_truncated;
++
++ /* Num MPDUs that was tried but didn't receive ACK or BA */
++ __le32 mpdus_ack_failed;
++
++ /* Num MPDUs that was dropped due to expiry. */
++ __le32 mpdus_expired;
++} __packed;
++
+ struct wmi_pdev_stats_rx {
+ /* Cnts any change in ring routing mid-ppdu */
+ __le32 mid_ppdu_route_change;
+@@ -4039,6 +4144,16 @@ struct wmi_10_2_pdev_stats {
+ struct wmi_pdev_stats_extra extra;
+ } __packed;
+
++struct wmi_10_4_pdev_stats {
++ struct wmi_pdev_stats_base base;
++ struct wmi_10_4_pdev_stats_tx tx;
++ struct wmi_pdev_stats_rx rx;
++ __le32 rx_ovfl_errs;
++ struct wmi_pdev_stats_mem mem;
++ __le32 sram_free_size;
++ struct wmi_pdev_stats_extra extra;
++} __packed;
++
+ /*
+ * VDEV statistics
+ * TODO: add all VDEV stats here
+@@ -4080,6 +4195,23 @@ struct wmi_10_2_4_peer_stats {
+ __le32 unknown_value; /* FIXME: what is this word? */
+ } __packed;
+
++struct wmi_10_4_peer_stats {
++ struct wmi_mac_addr peer_macaddr;
++ __le32 peer_rssi;
++ __le32 peer_rssi_seq_num;
++ __le32 peer_tx_rate;
++ __le32 peer_rx_rate;
++ __le32 current_per;
++ __le32 retries;
++ __le32 tx_rate_count;
++ __le32 max_4ms_frame_len;
++ __le32 total_sub_frames;
++ __le32 tx_bytes;
++ __le32 num_pkt_loss_overflow[4];
++ __le32 num_pkt_loss_excess_retry[4];
++ __le32 peer_rssi_changed;
++} __packed;
++
+ struct wmi_10_2_pdev_ext_stats {
+ __le32 rx_rssi_comb;
+ __le32 rx_rssi[4];
+@@ -6201,5 +6333,8 @@ void ath10k_wmi_10x_op_fw_stats_fill(str
+ char *buf);
+ size_t ath10k_wmi_fw_stats_num_peers(struct list_head *head);
+ size_t ath10k_wmi_fw_stats_num_vdevs(struct list_head *head);
++void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
++ struct ath10k_fw_stats *fw_stats,
++ char *buf);
+
+ #endif /* _WMI_H_ */
diff --git a/package/kernel/mac80211/patches/306-ath10k-use-local-memory-instead-of-shadow-descriptor.patch b/package/kernel/mac80211/patches/306-ath10k-use-local-memory-instead-of-shadow-descriptor.patch
new file mode 100644
index 0000000..58db2b2
--- /dev/null
+++ b/package/kernel/mac80211/patches/306-ath10k-use-local-memory-instead-of-shadow-descriptor.patch
@@ -0,0 +1,60 @@
+From: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Date: Fri, 23 Oct 2015 18:01:03 +0530
+Subject: [PATCH] ath10k: use local memory instead of shadow descriptor
+ in ce_send
+
+Currently to avoid uncached memory access while filling up copy engine
+descriptors, shadow descriptors are used. This can be optimized further
+by removing shadow descriptors. To achieve that first shadow ring
+dependency in ce_send is removed by creating local copy of the
+descriptor on stack and make a one-shot copy into the "uncached"
+descriptor.
+
+Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/ce.c
++++ b/drivers/net/wireless/ath/ath10k/ce.c
+@@ -274,7 +274,7 @@ int ath10k_ce_send_nolock(struct ath10k_
+ {
+ struct ath10k *ar = ce_state->ar;
+ struct ath10k_ce_ring *src_ring = ce_state->src_ring;
+- struct ce_desc *desc, *sdesc;
++ struct ce_desc *desc, sdesc;
+ unsigned int nentries_mask = src_ring->nentries_mask;
+ unsigned int sw_index = src_ring->sw_index;
+ unsigned int write_index = src_ring->write_index;
+@@ -294,7 +294,6 @@ int ath10k_ce_send_nolock(struct ath10k_
+
+ desc = CE_SRC_RING_TO_DESC(src_ring->base_addr_owner_space,
+ write_index);
+- sdesc = CE_SRC_RING_TO_DESC(src_ring->shadow_base, write_index);
+
+ desc_flags |= SM(transfer_id, CE_DESC_FLAGS_META_DATA);
+
+@@ -303,11 +302,11 @@ int ath10k_ce_send_nolock(struct ath10k_
+ if (flags & CE_SEND_FLAG_BYTE_SWAP)
+ desc_flags |= CE_DESC_FLAGS_BYTE_SWAP;
+
+- sdesc->addr = __cpu_to_le32(buffer);
+- sdesc->nbytes = __cpu_to_le16(nbytes);
+- sdesc->flags = __cpu_to_le16(desc_flags);
++ sdesc.addr = __cpu_to_le32(buffer);
++ sdesc.nbytes = __cpu_to_le16(nbytes);
++ sdesc.flags = __cpu_to_le16(desc_flags);
+
+- *desc = *sdesc;
++ *desc = sdesc;
+
+ src_ring->per_transfer_context[write_index] = per_transfer_context;
+
+@@ -614,7 +613,7 @@ int ath10k_ce_completed_send_next_nolock
+ if (read_index == sw_index)
+ return -EIO;
+
+- sbase = src_ring->shadow_base;
++ sbase = src_ring->base_addr_owner_space;
+ sdesc = CE_SRC_RING_TO_DESC(sbase, sw_index);
+
+ /* Return data from completed source descriptor */
diff --git a/package/kernel/mac80211/patches/307-ath10k-remove-send-completion-validation-in-diag-rea.patch b/package/kernel/mac80211/patches/307-ath10k-remove-send-completion-validation-in-diag-rea.patch
new file mode 100644
index 0000000..a61a334
--- /dev/null
+++ b/package/kernel/mac80211/patches/307-ath10k-remove-send-completion-validation-in-diag-rea.patch
@@ -0,0 +1,49 @@
+From: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Date: Fri, 23 Oct 2015 18:01:04 +0530
+Subject: [PATCH] ath10k: remove send completion validation in diag
+ read/write
+
+CE diag window access is serialized (it has to be by design) so
+there's no way to get a different send completion. so there's no
+need for post completion validation.
+
+Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -920,16 +920,6 @@ static int ath10k_pci_diag_read_mem(stru
+ }
+ }
+
+- if (nbytes != completed_nbytes) {
+- ret = -EIO;
+- goto done;
+- }
+-
+- if (buf != (u32)address) {
+- ret = -EIO;
+- goto done;
+- }
+-
+ i = 0;
+ while (ath10k_ce_completed_recv_next_nolock(ce_diag, NULL, &buf,
+ &completed_nbytes,
+@@ -1094,16 +1084,6 @@ static int ath10k_pci_diag_write_mem(str
+ }
+ }
+
+- if (nbytes != completed_nbytes) {
+- ret = -EIO;
+- goto done;
+- }
+-
+- if (buf != ce_data) {
+- ret = -EIO;
+- goto done;
+- }
+-
+ i = 0;
+ while (ath10k_ce_completed_recv_next_nolock(ce_diag, NULL, &buf,
+ &completed_nbytes,
diff --git a/package/kernel/mac80211/patches/308-ath10k-cleanup-copy-engine-send-completion.patch b/package/kernel/mac80211/patches/308-ath10k-cleanup-copy-engine-send-completion.patch
new file mode 100644
index 0000000..e758665
--- /dev/null
+++ b/package/kernel/mac80211/patches/308-ath10k-cleanup-copy-engine-send-completion.patch
@@ -0,0 +1,165 @@
+From: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Date: Fri, 23 Oct 2015 18:01:05 +0530
+Subject: [PATCH] ath10k: cleanup copy engine send completion
+
+The physical address necessary to unmap DMA ('bufferp') is stored
+in ath10k_skb_cb as 'paddr'. ath10k doesn't rely on the meta/transfer_id
+when handling send completion (htc ep id is stored in sk_buff control
+buffer). So the unused output arguments {bufferp, nbytesp and transfer_idp}
+are removed from CE send completion. This change is needed before removing
+the shadow copy of copy engine (CE) descriptors in follow up patch.
+
+Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/ce.c
++++ b/drivers/net/wireless/ath/ath10k/ce.c
+@@ -578,17 +578,13 @@ int ath10k_ce_revoke_recv_next(struct at
+ * The caller takes responsibility for any necessary locking.
+ */
+ int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
+- void **per_transfer_contextp,
+- u32 *bufferp,
+- unsigned int *nbytesp,
+- unsigned int *transfer_idp)
++ void **per_transfer_contextp)
+ {
+ struct ath10k_ce_ring *src_ring = ce_state->src_ring;
+ u32 ctrl_addr = ce_state->ctrl_addr;
+ struct ath10k *ar = ce_state->ar;
+ unsigned int nentries_mask = src_ring->nentries_mask;
+ unsigned int sw_index = src_ring->sw_index;
+- struct ce_desc *sdesc, *sbase;
+ unsigned int read_index;
+
+ if (src_ring->hw_index == sw_index) {
+@@ -613,15 +609,6 @@ int ath10k_ce_completed_send_next_nolock
+ if (read_index == sw_index)
+ return -EIO;
+
+- sbase = src_ring->base_addr_owner_space;
+- sdesc = CE_SRC_RING_TO_DESC(sbase, sw_index);
+-
+- /* Return data from completed source descriptor */
+- *bufferp = __le32_to_cpu(sdesc->addr);
+- *nbytesp = __le16_to_cpu(sdesc->nbytes);
+- *transfer_idp = MS(__le16_to_cpu(sdesc->flags),
+- CE_DESC_FLAGS_META_DATA);
+-
+ if (per_transfer_contextp)
+ *per_transfer_contextp =
+ src_ring->per_transfer_context[sw_index];
+@@ -696,10 +683,7 @@ int ath10k_ce_cancel_send_next(struct at
+ }
+
+ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
+- void **per_transfer_contextp,
+- u32 *bufferp,
+- unsigned int *nbytesp,
+- unsigned int *transfer_idp)
++ void **per_transfer_contextp)
+ {
+ struct ath10k *ar = ce_state->ar;
+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+@@ -707,9 +691,7 @@ int ath10k_ce_completed_send_next(struct
+
+ spin_lock_bh(&ar_pci->ce_lock);
+ ret = ath10k_ce_completed_send_next_nolock(ce_state,
+- per_transfer_contextp,
+- bufferp, nbytesp,
+- transfer_idp);
++ per_transfer_contextp);
+ spin_unlock_bh(&ar_pci->ce_lock);
+
+ return ret;
+--- a/drivers/net/wireless/ath/ath10k/ce.h
++++ b/drivers/net/wireless/ath/ath10k/ce.h
+@@ -192,16 +192,10 @@ int ath10k_ce_completed_recv_next(struct
+ * Pops 1 completed send buffer from Source ring.
+ */
+ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
+- void **per_transfer_contextp,
+- u32 *bufferp,
+- unsigned int *nbytesp,
+- unsigned int *transfer_idp);
++ void **per_transfer_contextp);
+
+ int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
+- void **per_transfer_contextp,
+- u32 *bufferp,
+- unsigned int *nbytesp,
+- unsigned int *transfer_idp);
++ void **per_transfer_contextp);
+
+ /*==================CE Engine Initialization=======================*/
+
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -910,9 +910,8 @@ static int ath10k_pci_diag_read_mem(stru
+ goto done;
+
+ i = 0;
+- while (ath10k_ce_completed_send_next_nolock(ce_diag, NULL, &buf,
+- &completed_nbytes,
+- &id) != 0) {
++ while (ath10k_ce_completed_send_next_nolock(ce_diag,
++ NULL) != 0) {
+ mdelay(1);
+ if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
+ ret = -EBUSY;
+@@ -1073,9 +1072,8 @@ static int ath10k_pci_diag_write_mem(str
+ goto done;
+
+ i = 0;
+- while (ath10k_ce_completed_send_next_nolock(ce_diag, NULL, &buf,
+- &completed_nbytes,
+- &id) != 0) {
++ while (ath10k_ce_completed_send_next_nolock(ce_diag,
++ NULL) != 0) {
+ mdelay(1);
+
+ if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
+@@ -1139,13 +1137,9 @@ static void ath10k_pci_htc_tx_cb(struct
+ struct ath10k *ar = ce_state->ar;
+ struct sk_buff_head list;
+ struct sk_buff *skb;
+- u32 ce_data;
+- unsigned int nbytes;
+- unsigned int transfer_id;
+
+ __skb_queue_head_init(&list);
+- while (ath10k_ce_completed_send_next(ce_state, (void **)&skb, &ce_data,
+- &nbytes, &transfer_id) == 0) {
++ while (ath10k_ce_completed_send_next(ce_state, (void **)&skb) == 0) {
+ /* no need to call tx completion for NULL pointers */
+ if (skb == NULL)
+ continue;
+@@ -1215,12 +1209,8 @@ static void ath10k_pci_htt_tx_cb(struct
+ {
+ struct ath10k *ar = ce_state->ar;
+ struct sk_buff *skb;
+- u32 ce_data;
+- unsigned int nbytes;
+- unsigned int transfer_id;
+
+- while (ath10k_ce_completed_send_next(ce_state, (void **)&skb, &ce_data,
+- &nbytes, &transfer_id) == 0) {
++ while (ath10k_ce_completed_send_next(ce_state, (void **)&skb) == 0) {
+ /* no need to call tx completion for NULL pointers */
+ if (!skb)
+ continue;
+@@ -1796,12 +1786,8 @@ err_dma:
+ static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state)
+ {
+ struct bmi_xfer *xfer;
+- u32 ce_data;
+- unsigned int nbytes;
+- unsigned int transfer_id;
+
+- if (ath10k_ce_completed_send_next(ce_state, (void **)&xfer, &ce_data,
+- &nbytes, &transfer_id))
++ if (ath10k_ce_completed_send_next(ce_state, (void **)&xfer))
+ return;
+
+ xfer->tx_done = true;
diff --git a/package/kernel/mac80211/patches/309-ath10k-remove-shadow-copy-of-CE-descriptors-for-sour.patch b/package/kernel/mac80211/patches/309-ath10k-remove-shadow-copy-of-CE-descriptors-for-sour.patch
new file mode 100644
index 0000000..5bd8833
--- /dev/null
+++ b/package/kernel/mac80211/patches/309-ath10k-remove-shadow-copy-of-CE-descriptors-for-sour.patch
@@ -0,0 +1,90 @@
+From: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Date: Fri, 23 Oct 2015 18:01:06 +0530
+Subject: [PATCH] ath10k: remove shadow copy of CE descriptors for source
+ ring
+
+For the messages from host to target, shadow copy of CE descriptors
+are maintained in source ring. Before writing actual CE descriptor,
+first shadow copy is filled and then it is copied to CE address space.
+To optimize in download path and to reduce d-cache pressure, removing
+shadow copy of CE descriptors. This will also reduce driver memory
+consumption by 33KB during on device probing.
+
+Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/ce.c
++++ b/drivers/net/wireless/ath/ath10k/ce.c
+@@ -921,27 +921,6 @@ ath10k_ce_alloc_src_ring(struct ath10k *
+ src_ring->base_addr_ce_space_unaligned,
+ CE_DESC_RING_ALIGN);
+
+- /*
+- * Also allocate a shadow src ring in regular
+- * mem to use for faster access.
+- */
+- src_ring->shadow_base_unaligned =
+- kmalloc((nentries * sizeof(struct ce_desc) +
+- CE_DESC_RING_ALIGN), GFP_KERNEL);
+- if (!src_ring->shadow_base_unaligned) {
+- dma_free_coherent(ar->dev,
+- (nentries * sizeof(struct ce_desc) +
+- CE_DESC_RING_ALIGN),
+- src_ring->base_addr_owner_space,
+- src_ring->base_addr_ce_space);
+- kfree(src_ring);
+- return ERR_PTR(-ENOMEM);
+- }
+-
+- src_ring->shadow_base = PTR_ALIGN(
+- src_ring->shadow_base_unaligned,
+- CE_DESC_RING_ALIGN);
+-
+ return src_ring;
+ }
+
+@@ -1120,7 +1099,6 @@ void ath10k_ce_free_pipe(struct ath10k *
+ struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
+
+ if (ce_state->src_ring) {
+- kfree(ce_state->src_ring->shadow_base_unaligned);
+ dma_free_coherent(ar->dev,
+ (ce_state->src_ring->nentries *
+ sizeof(struct ce_desc) +
+--- a/drivers/net/wireless/ath/ath10k/ce.h
++++ b/drivers/net/wireless/ath/ath10k/ce.h
+@@ -100,12 +100,6 @@ struct ath10k_ce_ring {
+
+ /* CE address space */
+ u32 base_addr_ce_space;
+- /*
+- * Start of shadow copy of descriptors, within regular memory.
+- * Aligned to descriptor-size boundary.
+- */
+- void *shadow_base_unaligned;
+- struct ce_desc *shadow_base;
+
+ /* keep last */
+ void *per_transfer_context[0];
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -1594,7 +1594,6 @@ static void ath10k_pci_tx_pipe_cleanup(s
+ struct ath10k_pci *ar_pci;
+ struct ath10k_ce_pipe *ce_pipe;
+ struct ath10k_ce_ring *ce_ring;
+- struct ce_desc *ce_desc;
+ struct sk_buff *skb;
+ int i;
+
+@@ -1609,10 +1608,6 @@ static void ath10k_pci_tx_pipe_cleanup(s
+ if (!pci_pipe->buf_sz)
+ return;
+
+- ce_desc = ce_ring->shadow_base;
+- if (WARN_ON(!ce_desc))
+- return;
+-
+ for (i = 0; i < ce_ring->nentries; i++) {
+ skb = ce_ring->per_transfer_context[i];
+ if (!skb)
diff --git a/package/kernel/mac80211/patches/310-ath10k-remove-supported-chain-mask.patch b/package/kernel/mac80211/patches/310-ath10k-remove-supported-chain-mask.patch
new file mode 100644
index 0000000..cc79dd7
--- /dev/null
+++ b/package/kernel/mac80211/patches/310-ath10k-remove-supported-chain-mask.patch
@@ -0,0 +1,77 @@
+From: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Date: Tue, 27 Oct 2015 17:51:11 +0530
+Subject: [PATCH] ath10k: remove supported chain mask
+
+Removing supported chainmask fields as it can be always derived
+from num_rf_chains.
+
+Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -745,8 +745,6 @@ struct ath10k {
+ int num_started_vdevs;
+
+ /* Protected by conf-mutex */
+- u8 supp_tx_chainmask;
+- u8 supp_rx_chainmask;
+ u8 cfg_tx_chainmask;
+ u8 cfg_rx_chainmask;
+
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -3736,13 +3736,8 @@ static int ath10k_get_antenna(struct iee
+
+ mutex_lock(&ar->conf_mutex);
+
+- if (ar->cfg_tx_chainmask) {
+- *tx_ant = ar->cfg_tx_chainmask;
+- *rx_ant = ar->cfg_rx_chainmask;
+- } else {
+- *tx_ant = ar->supp_tx_chainmask;
+- *rx_ant = ar->supp_rx_chainmask;
+- }
++ *tx_ant = ar->cfg_tx_chainmask;
++ *rx_ant = ar->cfg_rx_chainmask;
+
+ mutex_unlock(&ar->conf_mutex);
+
+@@ -3884,9 +3879,7 @@ static int ath10k_start(struct ieee80211
+ }
+ }
+
+- if (ar->cfg_tx_chainmask)
+- __ath10k_set_antenna(ar, ar->cfg_tx_chainmask,
+- ar->cfg_rx_chainmask);
++ __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
+
+ /*
+ * By default FW set ARP frames ac to voice (6). In that case ARP
+@@ -7169,8 +7162,8 @@ int ath10k_mac_register(struct ath10k *a
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_MESH_POINT);
+
+- ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask;
+- ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask;
++ ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
++ ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
+
+ if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
+ ar->hw->wiphy->interface_modes |=
+--- a/drivers/net/wireless/ath/ath10k/wmi.c
++++ b/drivers/net/wireless/ath/ath10k/wmi.c
+@@ -4460,8 +4460,10 @@ static void ath10k_wmi_event_service_rea
+ ar->num_rf_chains = ar->max_spatial_stream;
+ }
+
+- ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1;
+- ar->supp_rx_chainmask = (1 << ar->num_rf_chains) - 1;
++ if (!ar->cfg_tx_chainmask) {
++ ar->cfg_tx_chainmask = (1 << ar->num_rf_chains) - 1;
++ ar->cfg_rx_chainmask = (1 << ar->num_rf_chains) - 1;
++ }
+
+ if (strlen(ar->hw->wiphy->fw_version) == 0) {
+ snprintf(ar->hw->wiphy->fw_version,
diff --git a/package/kernel/mac80211/patches/311-ath10k-fill-HT-VHT-MCS-rateset-only-for-configured-c.patch b/package/kernel/mac80211/patches/311-ath10k-fill-HT-VHT-MCS-rateset-only-for-configured-c.patch
new file mode 100644
index 0000000..b4ca9ca
--- /dev/null
+++ b/package/kernel/mac80211/patches/311-ath10k-fill-HT-VHT-MCS-rateset-only-for-configured-c.patch
@@ -0,0 +1,37 @@
+From: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Date: Tue, 27 Oct 2015 17:51:12 +0530
+Subject: [PATCH] ath10k: fill HT/VHT MCS rateset only for configured
+ chainmask
+
+HT/VHT MCS rateset should be filled only for configured chainmask
+rather that max supported chainmask. Fix that by checking configured
+chainmask while filling HT/VHT MCS rate map.
+
+Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -6984,7 +6984,7 @@ static struct ieee80211_sta_vht_cap ath1
+
+ mcs_map = 0;
+ for (i = 0; i < 8; i++) {
+- if (i < ar->num_rf_chains)
++ if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
+ mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i*2);
+ else
+ mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2);
+@@ -7051,8 +7051,10 @@ static struct ieee80211_sta_ht_cap ath10
+ if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
+ ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
+
+- for (i = 0; i < ar->num_rf_chains; i++)
+- ht_cap.mcs.rx_mask[i] = 0xFF;
++ for (i = 0; i < ar->num_rf_chains; i++) {
++ if (ar->cfg_rx_chainmask & BIT(i))
++ ht_cap.mcs.rx_mask[i] = 0xFF;
++ }
+
+ ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
+
diff --git a/package/kernel/mac80211/patches/312-ath10k-move-static-HT-VHT-capability-setup-functions.patch b/package/kernel/mac80211/patches/312-ath10k-move-static-HT-VHT-capability-setup-functions.patch
new file mode 100644
index 0000000..ea79b1a
--- /dev/null
+++ b/package/kernel/mac80211/patches/312-ath10k-move-static-HT-VHT-capability-setup-functions.patch
@@ -0,0 +1,314 @@
+From: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Date: Tue, 27 Oct 2015 17:51:13 +0530
+Subject: [PATCH] ath10k: move static HT/VHT capability setup functions
+
+Move HT and VHT capabiltity setup static functions to avoid
+forward declaration.
+
+Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -3757,6 +3757,146 @@ static void ath10k_check_chain_mask(stru
+ dbg, cm);
+ }
+
++static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
++{
++ int nsts = ar->vht_cap_info;
++
++ nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
++ nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
++
++ /* If firmware does not deliver to host number of space-time
++ * streams supported, assume it support up to 4 BF STS and return
++ * the value for VHT CAP: nsts-1)
++ */
++ if (nsts == 0)
++ return 3;
++
++ return nsts;
++}
++
++static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
++{
++ int sound_dim = ar->vht_cap_info;
++
++ sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
++ sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
++
++ /* If the sounding dimension is not advertised by the firmware,
++ * let's use a default value of 1
++ */
++ if (sound_dim == 0)
++ return 1;
++
++ return sound_dim;
++}
++
++static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
++{
++ struct ieee80211_sta_vht_cap vht_cap = {0};
++ u16 mcs_map;
++ u32 val;
++ int i;
++
++ vht_cap.vht_supported = 1;
++ vht_cap.cap = ar->vht_cap_info;
++
++ if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
++ IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
++ val = ath10k_mac_get_vht_cap_bf_sts(ar);
++ val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
++ val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
++
++ vht_cap.cap |= val;
++ }
++
++ if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
++ IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
++ val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
++ val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
++ val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
++
++ vht_cap.cap |= val;
++ }
++
++ mcs_map = 0;
++ for (i = 0; i < 8; i++) {
++ if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
++ mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
++ else
++ mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
++ }
++
++ vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
++ vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
++
++ return vht_cap;
++}
++
++static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
++{
++ int i;
++ struct ieee80211_sta_ht_cap ht_cap = {0};
++
++ if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
++ return ht_cap;
++
++ ht_cap.ht_supported = 1;
++ ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
++ ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
++ ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
++ ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
++ ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT;
++
++ if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
++ ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
++
++ if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
++ ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
++
++ if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
++ u32 smps;
++
++ smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
++ smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
++
++ ht_cap.cap |= smps;
++ }
++
++ if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC)
++ ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
++
++ if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
++ u32 stbc;
++
++ stbc = ar->ht_cap_info;
++ stbc &= WMI_HT_CAP_RX_STBC;
++ stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
++ stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
++ stbc &= IEEE80211_HT_CAP_RX_STBC;
++
++ ht_cap.cap |= stbc;
++ }
++
++ if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
++ ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
++
++ if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
++ ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
++
++ /* max AMSDU is implicitly taken from vht_cap_info */
++ if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
++ ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
++
++ for (i = 0; i < ar->num_rf_chains; i++) {
++ if (ar->cfg_rx_chainmask & BIT(i))
++ ht_cap.mcs.rx_mask[i] = 0xFF;
++ }
++
++ ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
++
++ return ht_cap;
++}
++
+ static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
+ {
+ int ret;
+@@ -4068,39 +4208,6 @@ static u32 get_nss_from_chainmask(u16 ch
+ return 1;
+ }
+
+-static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
+-{
+- int nsts = ar->vht_cap_info;
+-
+- nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
+- nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
+-
+- /* If firmware does not deliver to host number of space-time
+- * streams supported, assume it support up to 4 BF STS and return
+- * the value for VHT CAP: nsts-1)
+- * */
+- if (nsts == 0)
+- return 3;
+-
+- return nsts;
+-}
+-
+-static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
+-{
+- int sound_dim = ar->vht_cap_info;
+-
+- sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
+- sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
+-
+- /* If the sounding dimension is not advertised by the firmware,
+- * let's use a default value of 1
+- */
+- if (sound_dim == 0)
+- return 1;
+-
+- return sound_dim;
+-}
+-
+ static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
+ {
+ u32 value = 0;
+@@ -6954,113 +7061,6 @@ static const struct ieee80211_iface_comb
+ },
+ };
+
+-static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
+-{
+- struct ieee80211_sta_vht_cap vht_cap = {0};
+- u16 mcs_map;
+- u32 val;
+- int i;
+-
+- vht_cap.vht_supported = 1;
+- vht_cap.cap = ar->vht_cap_info;
+-
+- if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
+- IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
+- val = ath10k_mac_get_vht_cap_bf_sts(ar);
+- val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
+- val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
+-
+- vht_cap.cap |= val;
+- }
+-
+- if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
+- IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
+- val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
+- val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
+- val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
+-
+- vht_cap.cap |= val;
+- }
+-
+- mcs_map = 0;
+- for (i = 0; i < 8; i++) {
+- if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
+- mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i*2);
+- else
+- mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2);
+- }
+-
+- vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
+- vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
+-
+- return vht_cap;
+-}
+-
+-static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
+-{
+- int i;
+- struct ieee80211_sta_ht_cap ht_cap = {0};
+-
+- if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
+- return ht_cap;
+-
+- ht_cap.ht_supported = 1;
+- ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+- ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
+- ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+- ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
+- ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT;
+-
+- if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
+- ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
+-
+- if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
+- ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
+-
+- if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
+- u32 smps;
+-
+- smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
+- smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
+-
+- ht_cap.cap |= smps;
+- }
+-
+- if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC)
+- ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
+-
+- if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
+- u32 stbc;
+-
+- stbc = ar->ht_cap_info;
+- stbc &= WMI_HT_CAP_RX_STBC;
+- stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
+- stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
+- stbc &= IEEE80211_HT_CAP_RX_STBC;
+-
+- ht_cap.cap |= stbc;
+- }
+-
+- if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
+- ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
+-
+- if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
+- ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
+-
+- /* max AMSDU is implicitly taken from vht_cap_info */
+- if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
+- ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
+-
+- for (i = 0; i < ar->num_rf_chains; i++) {
+- if (ar->cfg_rx_chainmask & BIT(i))
+- ht_cap.mcs.rx_mask[i] = 0xFF;
+- }
+-
+- ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
+-
+- return ht_cap;
+-}
+-
+ static void ath10k_get_arvif_iter(void *data, u8 *mac,
+ struct ieee80211_vif *vif)
+ {
diff --git a/package/kernel/mac80211/patches/313-mac80211-fix-crash-on-mesh-local-link-ID-generation-.patch b/package/kernel/mac80211/patches/313-mac80211-fix-crash-on-mesh-local-link-ID-generation-.patch
new file mode 100644
index 0000000..7424ca4
--- /dev/null
+++ b/package/kernel/mac80211/patches/313-mac80211-fix-crash-on-mesh-local-link-ID-generation-.patch
@@ -0,0 +1,42 @@
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Sat, 24 Oct 2015 21:25:51 +0200
+Subject: [PATCH] mac80211: fix crash on mesh local link ID generation with
+ VIFs
+
+llid_in_use needs to be limited to stations of the same VIF, otherwise it
+will cause a NULL deref as the sta_info of non-mesh-VIFs don't have
+sta->mesh set.
+
+Steps to reproduce:
+
+ modprobe mac80211_hwsim channels=2
+ iw phy phy0 interface add ibss0 type ibss
+ iw phy phy0 interface add mesh0 type mp
+ iw phy phy1 interface add ibss1 type ibss
+ iw phy phy1 interface add mesh1 type mp
+ ip link set ibss0 up
+ ip link set mesh0 up
+ ip link set ibss1 up
+ ip link set mesh1 up
+ iw dev ibss0 ibss join foo 2412
+ iw dev ibss1 ibss join foo 2412
+ # Ensure that ibss0 and ibss1 are actually associated; I often need to
+ # leave and join the cell on ibss1 a second time.
+ iw dev mesh0 mesh join bar
+ iw dev mesh1 mesh join bar # crash
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+---
+
+--- a/net/mac80211/mesh_plink.c
++++ b/net/mac80211/mesh_plink.c
+@@ -686,6 +686,9 @@ static bool llid_in_use(struct ieee80211
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(sta, &local->sta_list, list) {
++ if (sdata != sta->sdata)
++ continue;
++
+ if (!memcmp(&sta->mesh->llid, &llid, sizeof(llid))) {
+ in_use = true;
+ break;
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 0000000..72e9a41
--- /dev/null
+++ b/package/kernel/mac80211/patches/400-ath_move_debug_code.patch
@@ -0,0 +1,30 @@
+--- a/drivers/net/wireless/ath/Makefile
++++ b/drivers/net/wireless/ath/Makefile
+@@ -13,10 +13,10 @@ ath-objs := main.o \
+ regd.o \
+ hw.o \
+ key.o \
++ debug.o \
+ dfs_pattern_detector.o \
+ dfs_pri_detector.o
+
+-ath-$(CPTCFG_ATH_DEBUG) += debug.o
+ ath-$(CPTCFG_ATH_TRACEPOINTS) += trace.o
+
+ ccflags-y += -D__CHECK_ENDIAN__
+--- a/drivers/net/wireless/ath/ath.h
++++ b/drivers/net/wireless/ath/ath.h
+@@ -318,13 +318,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 0000000..4a997f1
--- /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 ath9k_led_blink;
++int ath9k_led_blink = 1;
+ module_param_named(blink, ath9k_led_blink, int, 0444);
+ MODULE_PARM_DESC(blink, "Enable LED blink on activity");
+
diff --git a/package/kernel/mac80211/patches/402-ath_regd_optional.patch b/package/kernel/mac80211/patches/402-ath_regd_optional.patch
new file mode 100644
index 0000000..1000cd8
--- /dev/null
+++ b/package/kernel/mac80211/patches/402-ath_regd_optional.patch
@@ -0,0 +1,69 @@
+--- a/drivers/net/wireless/ath/regd.c
++++ b/drivers/net/wireless/ath/regd.c
+@@ -341,6 +341,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])
+ continue;
+@@ -374,6 +378,10 @@ ath_reg_apply_ir_flags(struct wiphy *wip
+ {
+ struct ieee80211_supported_band *sband;
+
++#ifdef CPTCFG_ATH_USER_REGD
++ return;
++#endif
++
+ sband = wiphy->bands[IEEE80211_BAND_2GHZ];
+ if (!sband)
+ return;
+@@ -402,6 +410,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;
+
+@@ -633,6 +645,11 @@ ath_regd_init_wiphy(struct ath_regulator
+ const struct ieee80211_regdomain *regd;
+
+ wiphy->reg_notifier = reg_notifier;
++
++#ifdef CPTCFG_ATH_USER_REGD
++ return 0;
++#endif
++
+ wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
+ REGULATORY_CUSTOM_REG;
+
+--- a/drivers/net/wireless/ath/Kconfig
++++ b/drivers/net/wireless/ath/Kconfig
+@@ -22,6 +22,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---
+--- a/.local-symbols
++++ b/.local-symbols
+@@ -140,6 +140,7 @@ RTL8187_LEDS=
+ ATH_COMMON=
+ ATH_CARDS=
+ ATH_DEBUG=
++ATH_USER_REGD=
+ ATH_TRACEPOINTS=
+ ATH_REG_DYNAMIC_USER_REG_HINTS=
+ ATH_REG_DYNAMIC_USER_CERT_TESTING=
diff --git a/package/kernel/mac80211/patches/403-world_regd_fixup.patch b/package/kernel/mac80211/patches/403-world_regd_fixup.patch
new file mode 100644
index 0000000..2b04309
--- /dev/null
+++ b/package/kernel/mac80211/patches/403-world_regd_fixup.patch
@@ -0,0 +1,84 @@
+--- a/drivers/net/wireless/ath/regd.c
++++ b/drivers/net/wireless/ath/regd.c
+@@ -43,7 +43,8 @@ static int __ath_regd_init(struct ath_re
+ 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, 5240+10, 80, 0, 30, 0),\
++ REG_RULE(5260-10, 5350+10, 80, 0, 30,\
+ NL80211_RRF_NO_IR)
+ #define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\
+ NL80211_RRF_NO_IR)
+@@ -61,57 +62,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 bool dynamic_country_user_possible(struct ath_regulatory *reg)
diff --git a/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch
new file mode 100644
index 0000000..ca11199
--- /dev/null
+++ b/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch
@@ -0,0 +1,19 @@
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -2480,6 +2480,8 @@ void regulatory_hint_country_ie(struct 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;
+@@ -2686,6 +2688,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/405-ath_regd_us.patch b/package/kernel/mac80211/patches/405-ath_regd_us.patch
new file mode 100644
index 0000000..cc55877
--- /dev/null
+++ b/package/kernel/mac80211/patches/405-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/406-ath_relax_default_regd.patch b/package/kernel/mac80211/patches/406-ath_relax_default_regd.patch
new file mode 100644
index 0000000..6336f1f
--- /dev/null
+++ b/package/kernel/mac80211/patches/406-ath_relax_default_regd.patch
@@ -0,0 +1,47 @@
+--- a/drivers/net/wireless/ath/regd.c
++++ b/drivers/net/wireless/ath/regd.c
+@@ -114,10 +114,22 @@ static const struct ieee80211_regdomain
+ )
+ };
+
++static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
++{
++ return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
++}
++
++static bool is_default_regd(struct ath_regulatory *reg)
++{
++ return ath_regd_get_eepromRD(reg) == CTRY_DEFAULT;
++}
++
+ static bool dynamic_country_user_possible(struct ath_regulatory *reg)
+ {
+ if (config_enabled(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
+ return true;
++ if (is_default_regd(reg))
++ return true;
+
+ switch (reg->country_code) {
+ case CTRY_UNITED_STATES:
+@@ -202,11 +214,6 @@ static inline bool is_wwr_sku(u16 regd)
+ (regd == WORLD));
+ }
+
+-static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
+-{
+- return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
+-}
+-
+ bool ath_is_world_regd(struct ath_regulatory *reg)
+ {
+ return is_wwr_sku(ath_regd_get_eepromRD(reg));
+@@ -650,6 +657,9 @@ ath_regd_init_wiphy(struct ath_regulator
+ return 0;
+ #endif
+
++ if (is_default_regd(reg))
++ return 0;
++
+ wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
+ REGULATORY_CUSTOM_REG;
+
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 0000000..1a62484
--- /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
+@@ -722,6 +722,7 @@ static const struct ieee80211_iface_limi
+ BIT(NL80211_IFTYPE_AP) },
+ { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO) },
++ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
+ };
+
+ static const struct ieee80211_iface_limit wds_limits[] = {
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 0000000..2a5ab3d
--- /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
+@@ -1965,7 +1965,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);
+@@ -2051,7 +2051,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",
+@@ -2518,6 +2518,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 0000000..414f495
--- /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 0000000..b213e2a
--- /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 0000000..cdc9315
--- /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 0000000..d82f800
--- /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 const struct pci_device_id ath5k_
+ { 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 0000000..924b62e
--- /dev/null
+++ b/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch
@@ -0,0 +1,143 @@
+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
+@@ -823,6 +823,97 @@ 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_debug;
++
++#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_debug != tobwmode) {
++ mutex_lock(&ah->lock);
++ ah->ah_bwmode = tobwmode;
++ ah->ah_bwmode_debug = 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 */
+
+@@ -1010,6 +1101,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,
+--- a/drivers/net/wireless/ath/ath5k/ath5k.h
++++ b/drivers/net/wireless/ath/ath5k/ath5k.h
+@@ -1372,6 +1372,7 @@ struct ath5k_hw {
+ u8 ah_coverage_class;
+ bool ah_ack_bitrate_high;
+ u8 ah_bwmode;
++ u8 ah_bwmode_debug;
+ bool ah_short_slot;
+
+ /* Antenna Control */
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -466,6 +466,9 @@ ath5k_chan_set(struct ath5k_hw *ah, stru
+ return -EINVAL;
+ }
+
++ if (ah->ah_bwmode_debug != AR5K_BWMODE_DEFAULT)
++ ah->ah_bwmode = ah->ah_bwmode_debug;
++
+ /*
+ * To switch channels clear any pending DMA operations;
+ * wait long enough for the RX fifo to drain, reset the
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 0000000..a7f9d9f
--- /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
+@@ -1301,6 +1301,53 @@ void ath9k_deinit_debug(struct ath_softc
+ ath9k_cmn_spectral_deinit_debug(&sc->spec_priv);
+ }
+
++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);
+@@ -1320,6 +1367,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+ ath9k_tx99_init_debug(sc);
+ ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy);
+
++ debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
++ &fops_eeprom);
+ debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
+ read_file_dma);
+ debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
diff --git a/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch
new file mode 100644
index 0000000..143545c
--- /dev/null
+++ b/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch
@@ -0,0 +1,32 @@
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -1038,23 +1038,23 @@ static int __init ath9k_init(void)
+ {
+ int error;
+
+- 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_out;
+ }
+
+- 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_out:
+ return error;
+ }
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 0000000..d2a3b96
--- /dev/null
+++ b/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
@@ -0,0 +1,18 @@
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -390,13 +390,8 @@ static void ath9k_hw_init_config(struct
+
+ ah->config.rx_intr_mitigation = true;
+
+- if (AR_SREV_9300_20_OR_LATER(ah)) {
+- ah->config.rimt_last = 500;
+- ah->config.rimt_first = 2000;
+- } else {
+- ah->config.rimt_last = 250;
+- ah->config.rimt_first = 700;
+- }
++ ah->config.rimt_last = 250;
++ ah->config.rimt_first = 500;
+
+ if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
+ ah->config.pll_pwrsave = 7;
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 0000000..d4104f0
--- /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
+@@ -87,7 +87,7 @@ int ath_descdma_setup(struct ath_softc *
+ (_l) &= ((_sz) - 1); \
+ } while (0)
+
+-#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 0000000..5ecf528
--- /dev/null
+++ b/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
@@ -0,0 +1,125 @@
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -1348,6 +1348,52 @@ 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;
++ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
++ char buf[32];
++ unsigned int len;
++
++ len = sprintf(buf, "0x%08x\n", common->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;
++ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
++ 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 (kstrtoul(buf, 0, &chan_bw))
++ return -EINVAL;
++
++ common->chan_bw = chan_bw;
++ if (!test_bit(ATH_OP_INVALID, &common->op_flags))
++ ath9k_ops.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);
+@@ -1369,6 +1415,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_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
+ read_file_dma);
+ debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
+--- a/drivers/net/wireless/ath/ath.h
++++ b/drivers/net/wireless/ath/ath.h
+@@ -151,6 +151,7 @@ struct ath_common {
+ int debug_mask;
+ enum ath_device_state state;
+ unsigned long op_flags;
++ u32 chan_bw;
+
+ struct ath_ani ani;
+
+--- a/drivers/net/wireless/ath/ath9k/common.c
++++ b/drivers/net/wireless/ath/ath9k/common.c
+@@ -296,11 +296,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke
+ /*
+ * Update internal channel flags.
+ */
+-static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
++static void ath9k_cmn_update_ichannel(struct ath_common *common,
++ struct ath9k_channel *ichan,
+ struct cfg80211_chan_def *chandef)
+ {
+ struct ieee80211_channel *chan = chandef->chan;
+ u16 flags = 0;
++ int width;
+
+ ichan->channel = chan->center_freq;
+ ichan->chan = chan;
+@@ -308,7 +310,19 @@ static void ath9k_cmn_update_ichannel(st
+ if (chan->band == IEEE80211_BAND_5GHZ)
+ flags |= CHANNEL_5GHZ;
+
+- switch (chandef->width) {
++ switch (common->chan_bw) {
++ case 5:
++ width = NL80211_CHAN_WIDTH_5;
++ break;
++ case 10:
++ width = NL80211_CHAN_WIDTH_10;
++ break;
++ default:
++ width = chandef->width;
++ break;
++ }
++
++ switch (width) {
+ case NL80211_CHAN_WIDTH_5:
+ flags |= CHANNEL_QUARTER;
+ break;
+@@ -341,10 +355,11 @@ struct ath9k_channel *ath9k_cmn_get_chan
+ struct cfg80211_chan_def *chandef)
+ {
+ struct ieee80211_channel *curchan = chandef->chan;
++ struct ath_common *common = ath9k_hw_common(ah);
+ struct ath9k_channel *channel;
+
+ channel = &ah->channels[curchan->hw_value];
+- ath9k_cmn_update_ichannel(channel, chandef);
++ ath9k_cmn_update_ichannel(common, channel, chandef);
+
+ return channel;
+ }
diff --git a/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch
new file mode 100644
index 0000000..c84d1bc
--- /dev/null
+++ b/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch
@@ -0,0 +1,30 @@
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -651,6 +651,7 @@ int ath9k_hw_init(struct ath_hw *ah)
+
+ /* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */
+ switch (ah->hw_version.devid) {
++ case AR9300_DEVID_INVALID:
+ case AR5416_DEVID_PCI:
+ case AR5416_DEVID_PCIE:
+ case AR5416_AR9100_DEVID:
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -36,6 +36,7 @@
+
+ #define ATHEROS_VENDOR_ID 0x168c
+
++#define AR9300_DEVID_INVALID 0xabcd
+ #define AR5416_DEVID_PCI 0x0023
+ #define AR5416_DEVID_PCIE 0x0024
+ #define AR9160_DEVID_PCI 0x0027
+--- a/drivers/net/wireless/ath/ath9k/pci.c
++++ b/drivers/net/wireless/ath/ath9k/pci.c
+@@ -751,6 +751,7 @@ static const struct pci_device_id ath_pc
+ .driver_data = ATH9K_PCI_BT_ANT_DIV },
+ #endif
+
++ { PCI_VDEVICE(ATHEROS, 0xabcd) }, /* PCI-E internal chip default ID */
+ { 0 }
+ };
+
diff --git a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
new file mode 100644
index 0000000..be7bd58
--- /dev/null
+++ b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
@@ -0,0 +1,160 @@
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -2361,6 +2361,7 @@ struct cfg80211_qos_map {
+ * (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
+ *
+@@ -2617,6 +2618,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/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1250,6 +1250,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
+@@ -1270,6 +1271,7 @@ enum ieee80211_smps_mode {
+ struct ieee80211_conf {
+ u32 flags;
+ int power_level, dynamic_ps_timeout;
++ int max_antenna_gain;
+
+ u16 listen_interval;
+ u8 ps_dtim_period;
+--- a/include/uapi/linux/nl80211.h
++++ b/include/uapi/linux/nl80211.h
+@@ -1783,6 +1783,9 @@ enum nl80211_commands {
+ * between scans. The scan plans are executed sequentially.
+ * Each scan plan is a nested attribute of &enum nl80211_sched_scan_plan.
+ *
++ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
++ * transmit power to stay within regulatory limits. u32, dBi.
++ *
+ * @NUM_NL80211_ATTR: total number of nl80211_attrs available
+ * @NL80211_ATTR_MAX: highest attribute number currently defined
+ * @__NL80211_ATTR_AFTER_LAST: internal use
+@@ -2157,6 +2160,8 @@ enum nl80211_attrs {
+ NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
+ NL80211_ATTR_SCHED_SCAN_PLANS,
+
++ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
++
+ /* add attributes here, update the policy in nl80211.c */
+
+ __NL80211_ATTR_AFTER_LAST,
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -2206,6 +2206,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)
+ {
+@@ -3849,6 +3862,7 @@ const struct cfg80211_ops mac80211_confi
+ .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/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1321,6 +1321,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/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -93,7 +93,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, max_power;
+ u32 offchannel_flag;
+
+ offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
+@@ -150,6 +150,12 @@ static u32 ieee80211_hw_conf_chan(struct
+ }
+ rcu_read_unlock();
+
++ max_power = chandef.chan->max_reg_power;
++ if (local->user_antenna_gain > 0) {
++ max_power -= local->user_antenna_gain;
++ power = min(power, max_power);
++ }
++
+ if (local->hw.conf.power_level != power) {
+ changed |= IEEE80211_CONF_CHANGE_POWER;
+ local->hw.conf.power_level = power;
+@@ -580,6 +586,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;
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -403,6 +403,7 @@ static const struct nla_policy nl80211_p
+ [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
+ [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
+ [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
++ [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
+ };
+
+ /* policy for the key attributes */
+@@ -2220,6 +2221,20 @@ static int nl80211_set_wiphy(struct sk_b
+ if (result)
+ return result;
+ }
++
++ if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) {
++ int idx, dbi = 0;
++
++ if (!rdev->ops->set_antenna_gain)
++ return -EOPNOTSUPP;
++
++ idx = NL80211_ATTR_WIPHY_ANTENNA_GAIN;
++ dbi = nla_get_u32(info->attrs[idx]);
++
++ result = rdev->ops->set_antenna_gain(&rdev->wiphy, dbi);
++ if (result)
++ return result;
++ }
+
+ if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
+ info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
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 0000000..89e3c97
--- /dev/null
+++ b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
@@ -0,0 +1,251 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -813,6 +813,9 @@ static inline int ath9k_dump_btcoex(stru
+ 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)
+ {
+@@ -952,6 +955,13 @@ void ath_ant_comb_scan(struct ath_softc
+
+ #define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */
+
++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;
+@@ -1003,9 +1013,8 @@ struct ath_softc {
+ spinlock_t chan_lock;
+
+ #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
+
+ #ifdef CPTCFG_ATH9K_DEBUGFS
+--- a/drivers/net/wireless/ath/ath9k/gpio.c
++++ b/drivers/net/wireless/ath/ath9k/gpio.c
+@@ -24,45 +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);
+- u32 val = (brightness == LED_OFF);
++ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev);
++ struct ath_softc *sc = led->sc;
+
+- if (sc->sc_ah->config.led_active_high)
+- val = !val;
++ 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;
+
+- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val);
++ 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 (!ath9k_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 (ath9k_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
+@@ -950,7 +950,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
+@@ -1393,6 +1393,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)
+ {
+@@ -1417,6 +1472,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_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
+ read_file_dma);
+ debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
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 0000000..dc33cd0
--- /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
+@@ -41,6 +41,9 @@ struct ath9k_platform_data {
+ int (*external_reset)(void);
+
+ bool use_eeprom;
++
++ 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/540-ath9k_reduce_ani_interval.patch b/package/kernel/mac80211/patches/540-ath9k_reduce_ani_interval.patch
new file mode 100644
index 0000000..e899903
--- /dev/null
+++ b/package/kernel/mac80211/patches/540-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
+@@ -42,7 +42,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/541-ath9k_rx_dma_stop_check.patch b/package/kernel/mac80211/patches/541-ath9k_rx_dma_stop_check.patch
new file mode 100644
index 0000000..3c5e9f5
--- /dev/null
+++ b/package/kernel/mac80211/patches/541-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
+@@ -695,7 +695,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 */
+@@ -725,6 +725,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/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
new file mode 100644
index 0000000..9758d5f
--- /dev/null
+++ b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
@@ -0,0 +1,139 @@
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -1449,6 +1449,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 (kstrtoul(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);
+@@ -1476,6 +1520,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_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
+ read_file_dma);
+ debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -519,6 +519,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;
+@@ -804,6 +810,8 @@ struct ath_hw {
+ u32 rfkill_polarity;
+ u32 ah_flags;
+
++ unsigned long diag;
++
+ bool reset_power_on;
+ bool htc_reset_init;
+
+@@ -1066,6 +1074,7 @@ void ath9k_hw_check_nav(struct ath_hw *a
+ 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);
+
+ /* Generic hw timer primitives */
+ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1809,6 +1809,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
+ }
+ EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
+
++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)
+ {
+@@ -2017,6 +2031,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+ ar9003_hw_disable_phy_restart(ah);
+
+ ath9k_hw_apply_gpio_override(ah);
++ ath9k_hw_update_diag(ah);
+
+ if (AR_SREV_9565(ah) && common->bt_ant_diversity)
+ 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
+@@ -533,6 +533,11 @@ irqreturn_t ath_isr(int irq, void *dev)
+ if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
+ return IRQ_HANDLED;
+
++ 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/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch
new file mode 100644
index 0000000..fa8eca5
--- /dev/null
+++ b/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch
@@ -0,0 +1,186 @@
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -720,6 +720,7 @@ struct ath_spec_scan {
+ * @config_pci_powersave:
+ * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
+ *
++ * @get_adc_entropy: get entropy from the raw ADC I/Q output
+ * @spectral_scan_config: set parameters for spectral scan and enable/disable it
+ * @spectral_scan_trigger: trigger a spectral scan run
+ * @spectral_scan_wait: wait for a spectral scan run to finish
+@@ -742,6 +743,7 @@ struct ath_hw_ops {
+ struct ath_hw_antcomb_conf *antconf);
+ void (*antdiv_comb_conf_set)(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf);
++ void (*get_adc_entropy)(struct ath_hw *ah, u8 *buf, size_t len);
+ void (*spectral_scan_config)(struct ath_hw *ah,
+ struct ath_spec_scan *param);
+ void (*spectral_scan_trigger)(struct ath_hw *ah);
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -1998,6 +1998,26 @@ void ar9003_hw_init_rate_txpower(struct
+ }
+ }
+
++static void ar9003_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len)
++{
++ int i, j;
++
++ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1);
++ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5);
++ REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0);
++
++ memset(buf, 0, len);
++ for (i = 0; i < len; i++) {
++ for (j = 0; j < 4; j++) {
++ u32 regval = REG_READ(ah, AR_PHY_TST_ADC);
++
++ buf[i] <<= 2;
++ buf[i] |= (regval & 1) | ((regval & BIT(10)) >> 9);
++ udelay(1);
++ }
++ }
++}
++
+ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
+ {
+ struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+@@ -2034,6 +2054,7 @@ void ar9003_hw_attach_phy_ops(struct ath
+ priv_ops->set_radar_params = ar9003_hw_set_radar_params;
+ priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
+
++ ops->get_adc_entropy = ar9003_hw_get_adc_entropy;
+ ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
+ ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
+ ops->spectral_scan_config = ar9003_hw_spectral_scan_config;
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -710,7 +710,8 @@ static void ath9k_init_txpower_limits(st
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
+ ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
+
+- ah->curchan = curchan;
++ if (curchan)
++ ah->curchan = curchan;
+ }
+
+ static const struct ieee80211_iface_limit if_limits[] = {
+@@ -910,6 +911,18 @@ static void ath9k_set_hw_capab(struct at
+ SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
+ }
+
++static void ath_get_initial_entropy(struct ath_softc *sc)
++{
++ struct ath_hw *ah = sc->sc_ah;
++ char buf[256];
++
++ /* reuse last channel initialized by the tx power test */
++ ath9k_hw_reset(ah, ah->curchan, NULL, false);
++
++ ath9k_hw_get_adc_entropy(ah, buf, sizeof(buf));
++ add_device_randomness(buf, sizeof(buf));
++}
++
+ int ath9k_init_device(u16 devid, struct ath_softc *sc,
+ const struct ath_bus_ops *bus_ops)
+ {
+@@ -955,6 +968,8 @@ int ath9k_init_device(u16 devid, struct
+ ARRAY_SIZE(ath9k_tpt_blink));
+ #endif
+
++ ath_get_initial_entropy(sc);
++
+ /* Register with mac80211 */
+ error = ieee80211_register_hw(hw);
+ if (error)
+--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
++++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
+@@ -100,6 +100,12 @@ static inline void ath9k_hw_tx99_set_txp
+ ath9k_hw_ops(ah)->tx99_set_txpower(ah, power);
+ }
+
++static inline void ath9k_hw_get_adc_entropy(struct ath_hw *ah,
++ u8 *buf, size_t len)
++{
++ ath9k_hw_ops(ah)->get_adc_entropy(ah, buf, len);
++}
++
+ #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT
+
+ static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+@@ -1327,9 +1327,30 @@ void ar5008_hw_init_rate_txpower(struct
+ }
+ }
+
++static void ar5008_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len)
++{
++ int i, j;
++
++ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1);
++ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5);
++ REG_RMW_FIELD(ah, AR_PHY_TEST2, AR_PHY_TEST2_RX_OBS_SEL, 0);
++
++ memset(buf, 0, len);
++ for (i = 0; i < len; i++) {
++ for (j = 0; j < 4; j++) {
++ u32 regval = REG_READ(ah, AR_PHY_TST_ADC);
++
++ buf[i] <<= 2;
++ buf[i] |= (regval & 1) | ((regval & BIT(9)) >> 8);
++ udelay(1);
++ }
++ }
++}
++
+ int ar5008_hw_attach_phy_ops(struct ath_hw *ah)
+ {
+ struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
++ struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+ static const u32 ar5416_cca_regs[6] = {
+ AR_PHY_CCA,
+ AR_PHY_CH1_CCA,
+@@ -1344,6 +1365,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
+ if (ret)
+ return ret;
+
++ ops->get_adc_entropy = ar5008_hw_get_adc_entropy;
++
+ priv_ops->rf_set_freq = ar5008_hw_set_channel;
+ priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
+
+--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
++++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+@@ -20,6 +20,12 @@
+ #define PHY_AGC_CLR 0x10000000
+ #define RFSILENT_BB 0x00002000
+
++#define AR_PHY_TEST_BBB_OBS_SEL 0x780000
++#define AR_PHY_TEST_BBB_OBS_SEL_S 19
++
++#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23
++#define AR_PHY_TEST_RX_OBS_SEL_BIT5 (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S)
++
+ #define AR_PHY_TURBO 0x9804
+ #define AR_PHY_FC_TURBO_MODE 0x00000001
+ #define AR_PHY_FC_TURBO_SHORT 0x00000002
+@@ -36,6 +42,9 @@
+
+ #define AR_PHY_TEST2 0x9808
+
++#define AR_PHY_TEST2_RX_OBS_SEL 0x3C00
++#define AR_PHY_TEST2_RX_OBS_SEL_S 10
++
+ #define AR_PHY_TIMING2 0x9810
+ #define AR_PHY_TIMING3 0x9814
+ #define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
+@@ -390,6 +399,8 @@
+ #define AR_PHY_RFBUS_GRANT 0x9C20
+ #define AR_PHY_RFBUS_GRANT_EN 0x00000001
+
++#define AR_PHY_TST_ADC 0x9C24
++
+ #define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4
+ #define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
+
diff --git a/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch b/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch
new file mode 100644
index 0000000..3f46226
--- /dev/null
+++ b/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch
@@ -0,0 +1,79 @@
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -246,6 +246,19 @@ void ath9k_hw_get_channel_centers(struct
+ centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
+ }
+
++static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah)
++{
++ /* On AR9330 and AR9340 devices, some PHY registers must be
++ * tuned to gain better stability/performance. These registers
++ * might be changed while doing wlan reset so the registers must
++ * be reprogrammed after each reset.
++ */
++ REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20));
++ REG_RMW(ah, AR_PHY_USB_CTRL2,
++ (1 << 21) | (0xf << 22),
++ (1 << 21) | (0x3 << 22));
++}
++
+ /******************/
+ /* Chip Revisions */
+ /******************/
+@@ -1387,6 +1400,9 @@ static bool ath9k_hw_set_reset(struct at
+ if (AR_SREV_9100(ah))
+ udelay(50);
+
++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
++ ath9k_hw_disable_pll_lock_detect(ah);
++
+ return true;
+ }
+
+@@ -1486,6 +1502,9 @@ static bool ath9k_hw_chip_reset(struct a
+ ar9003_hw_internal_regulator_apply(ah);
+ ath9k_hw_init_pll(ah, chan);
+
++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
++ ath9k_hw_disable_pll_lock_detect(ah);
++
+ return true;
+ }
+
+@@ -1787,8 +1806,14 @@ static int ath9k_hw_do_fastcc(struct ath
+ if (AR_SREV_9271(ah))
+ ar9002_hw_load_ani_reg(ah, chan);
+
++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
++ ath9k_hw_disable_pll_lock_detect(ah);
++
+ return 0;
+ fail:
++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
++ ath9k_hw_disable_pll_lock_detect(ah);
++
+ return -EINVAL;
+ }
+
+@@ -2042,6 +2067,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+ ath9k_hw_set_radar_params(ah);
+ }
+
++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
++ ath9k_hw_disable_pll_lock_detect(ah);
++
+ return 0;
+ }
+ EXPORT_SYMBOL(ath9k_hw_reset);
+--- a/drivers/net/wireless/ath/ath9k/phy.h
++++ b/drivers/net/wireless/ath/ath9k/phy.h
+@@ -48,6 +48,9 @@
+ #define AR_PHY_PLL_CONTROL 0x16180
+ #define AR_PHY_PLL_MODE 0x16184
+
++#define AR_PHY_USB_CTRL1 0x16c84
++#define AR_PHY_USB_CTRL2 0x16c88
++
+ enum ath9k_ant_div_comb_lna_conf {
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2,
+ ATH_ANT_DIV_COMB_LNA2,
diff --git a/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch b/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch
new file mode 100644
index 0000000..3d24ccd
--- /dev/null
+++ b/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch
@@ -0,0 +1,155 @@
+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+@@ -956,55 +956,6 @@ static bool ar5008_hw_ani_control_new(st
+ * on == 0 means more noise imm
+ */
+ u32 on = param ? 1 : 0;
+- /*
+- * make register setting for default
+- * (weak sig detect ON) come from INI file
+- */
+- int m1ThreshLow = on ?
+- aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
+- int m2ThreshLow = on ?
+- aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
+- int m1Thresh = on ?
+- aniState->iniDef.m1Thresh : m1Thresh_off;
+- int m2Thresh = on ?
+- aniState->iniDef.m2Thresh : m2Thresh_off;
+- int m2CountThr = on ?
+- aniState->iniDef.m2CountThr : m2CountThr_off;
+- int m2CountThrLow = on ?
+- aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
+- int m1ThreshLowExt = on ?
+- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
+- int m2ThreshLowExt = on ?
+- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
+- int m1ThreshExt = on ?
+- aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
+- int m2ThreshExt = on ?
+- aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
+-
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+- AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+- m1ThreshLow);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+- AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+- m2ThreshLow);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+- AR_PHY_SFCORR_M1_THRESH, m1Thresh);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+- AR_PHY_SFCORR_M2_THRESH, m2Thresh);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+- AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+- m2CountThrLow);
+-
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+- AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+- AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
+
+ if (on)
+ REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -41,20 +41,6 @@ static const int cycpwrThr1_table[] =
+ /* level: 0 1 2 3 4 5 6 7 8 */
+ { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */
+
+-/*
+- * register values to turn OFDM weak signal detection OFF
+- */
+-static const int m1ThreshLow_off = 127;
+-static const int m2ThreshLow_off = 127;
+-static const int m1Thresh_off = 127;
+-static const int m2Thresh_off = 127;
+-static const int m2CountThr_off = 31;
+-static const int m2CountThrLow_off = 63;
+-static const int m1ThreshLowExt_off = 127;
+-static const int m2ThreshLowExt_off = 127;
+-static const int m1ThreshExt_off = 127;
+-static const int m2ThreshExt_off = 127;
+-
+ static const u8 ofdm2pwr[] = {
+ ALL_TARGET_LEGACY_6_24,
+ ALL_TARGET_LEGACY_6_24,
+@@ -1089,11 +1075,6 @@ static bool ar9003_hw_ani_control(struct
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ath9k_channel *chan = ah->curchan;
+ struct ar5416AniState *aniState = &ah->ani;
+- int m1ThreshLow, m2ThreshLow;
+- int m1Thresh, m2Thresh;
+- int m2CountThr, m2CountThrLow;
+- int m1ThreshLowExt, m2ThreshLowExt;
+- int m1ThreshExt, m2ThreshExt;
+ s32 value, value2;
+
+ switch (cmd & ah->ani_function) {
+@@ -1107,61 +1088,6 @@ static bool ar9003_hw_ani_control(struct
+ */
+ u32 on = param ? 1 : 0;
+
+- if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
+- goto skip_ws_det;
+-
+- m1ThreshLow = on ?
+- aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
+- m2ThreshLow = on ?
+- aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
+- m1Thresh = on ?
+- aniState->iniDef.m1Thresh : m1Thresh_off;
+- m2Thresh = on ?
+- aniState->iniDef.m2Thresh : m2Thresh_off;
+- m2CountThr = on ?
+- aniState->iniDef.m2CountThr : m2CountThr_off;
+- m2CountThrLow = on ?
+- aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
+- m1ThreshLowExt = on ?
+- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
+- m2ThreshLowExt = on ?
+- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
+- m1ThreshExt = on ?
+- aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
+- m2ThreshExt = on ?
+- aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
+-
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+- AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+- m1ThreshLow);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+- AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+- m2ThreshLow);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+- AR_PHY_SFCORR_M1_THRESH,
+- m1Thresh);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+- AR_PHY_SFCORR_M2_THRESH,
+- m2Thresh);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+- AR_PHY_SFCORR_M2COUNT_THR,
+- m2CountThr);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+- m2CountThrLow);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+- AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
+- m1ThreshLowExt);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+- AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
+- m2ThreshLowExt);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+- AR_PHY_SFCORR_EXT_M1_THRESH,
+- m1ThreshExt);
+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+- AR_PHY_SFCORR_EXT_M2_THRESH,
+- m2ThreshExt);
+-skip_ws_det:
+ if (on)
+ REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
+ AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
diff --git a/package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch b/package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch
new file mode 100644
index 0000000..15863a6
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch
@@ -0,0 +1,66 @@
+From 7a69da907de668fb22a30ae218062d6f081864ea Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sat, 17 Aug 2013 19:31:41 +0200
+Subject: [PATCH] rt2x00: rt2800lib: move rt2800_drv_data declaration into
+ rt2800lib.h
+
+The rt2800_drv_data structure contains driver specific
+information. Move the declaration into the rt2800lib.h
+header which is a more logical place for it. Also fix
+the comment style to avoid checkpatch warning.
+
+The patch contains no functional changes, it is in
+preparation for the next patch.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+Changes since v1: ---
+---
+ drivers/net/wireless/rt2x00/rt2800.h | 13 -------------
+ drivers/net/wireless/rt2x00/rt2800lib.h | 11 +++++++++++
+ 2 files changed, 11 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
+@@ -20,6 +20,20 @@
+ #ifndef RT2800LIB_H
+ #define RT2800LIB_H
+
++#include "rt2800.h"
++
++/* RT2800 driver data structure */
++struct rt2800_drv_data {
++ u8 calibration_bw20;
++ u8 calibration_bw40;
++ u8 bbp25;
++ u8 bbp26;
++ u8 txmixer_gain_24g;
++ u8 txmixer_gain_5g;
++ unsigned int tbtt_tick;
++ DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
++};
++
+ struct rt2800_ops {
+ void (*register_read)(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset, u32 *value);
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -2969,18 +2969,4 @@ enum rt2800_eeprom_word {
+ #define WCID_END 222
+ #define STA_IDS_SIZE (WCID_END - WCID_START + 2)
+
+-/*
+- * RT2800 driver data structure
+- */
+-struct rt2800_drv_data {
+- u8 calibration_bw20;
+- u8 calibration_bw40;
+- u8 bbp25;
+- u8 bbp26;
+- u8 txmixer_gain_24g;
+- u8 txmixer_gain_5g;
+- unsigned int tbtt_tick;
+- DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
+-};
+-
+ #endif /* RT2800_H */
diff --git a/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch b/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch
new file mode 100644
index 0000000..9165eec
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch
@@ -0,0 +1,80 @@
+From a7f268af31dddf763fe3dbe9cbf96ea77e0540e0 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sat, 17 Aug 2013 19:31:41 +0200
+Subject: [PATCH] rt2x00: rt2800lib: introduce RT2800_HAS_HIGH_SHARED_MEM flag
+
+Some chipsets have more than 16KB of shared memory.
+Introduce a new rt2800 specific flag to indicate that
+and add a helper function which helps to check the
+presence of the new flag.
+
+Also enable the new flag for the RT3593 chipset which
+has 24KB of shared memory. The flag can also be used
+for other chipsets, but none of those has been tested
+yet.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+Changes since v1:
+ - don't enable the new flag for RT3071 and RT5592
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 4 ++++
+ drivers/net/wireless/rt2x00/rt2800lib.h | 13 +++++++++++++
+ 2 files changed, 17 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -7721,6 +7721,7 @@ static int rt2800_probe_rt(struct rt2x00
+
+ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
+ {
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+ int retval;
+ u32 reg;
+
+@@ -7728,6 +7729,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+ if (retval)
+ return retval;
+
++ if (rt2x00_rt(rt2x00dev, RT3593))
++ __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
++
+ /*
+ * Allocate eeprom data.
+ */
+--- a/drivers/net/wireless/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
+@@ -22,6 +22,10 @@
+
+ #include "rt2800.h"
+
++enum rt2800_flag {
++ RT2800_HAS_HIGH_SHARED_MEM,
++};
++
+ /* RT2800 driver data structure */
+ struct rt2800_drv_data {
+ u8 calibration_bw20;
+@@ -32,6 +36,8 @@ struct rt2800_drv_data {
+ u8 txmixer_gain_5g;
+ unsigned int tbtt_tick;
+ DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
++
++ unsigned long rt2800_flags;
+ };
+
+ struct rt2800_ops {
+@@ -64,6 +70,13 @@ struct rt2800_ops {
+ __le32 *(*drv_get_txwi)(struct queue_entry *entry);
+ };
+
++static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++
++ return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
++}
++
+ static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ u32 *value)
diff --git a/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch b/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch
new file mode 100644
index 0000000..5671515
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch
@@ -0,0 +1,531 @@
+From 250a1b520cd7fdc0df4fc3fedea9066913f49ecf Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sat, 17 Aug 2013 19:31:42 +0200
+Subject: [PATCH] rt2x00: rt2800: serialize shared memory access
+
+The shared memory of the rt2800 devices is accessible
+through the register offset range between 0x4000 and
+0x8000. The size of this range is 16KB only and on
+devices which have more than 16KB of shared memory either
+the low or the high part of the memory is accessible at a
+time.
+
+Serialize all accesses to the shared memory by a mutex,
+in order to avoid concurrent use of that.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+Changes since v1: ---
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 55 +++++++++++++++++++++++++++++-
+ drivers/net/wireless/rt2x00/rt2800lib.h | 32 +++++++++++++++++
+ drivers/net/wireless/rt2x00/rt2800mmio.c | 26 ++++++++++++++
+ drivers/net/wireless/rt2x00/rt2800mmio.h | 4 +++
+ drivers/net/wireless/rt2x00/rt2800pci.c | 14 ++++++++
+ drivers/net/wireless/rt2x00/rt2800soc.c | 3 ++
+ drivers/net/wireless/rt2x00/rt2800usb.c | 31 +++++++++++++++++
+ 7 files changed, 164 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -451,11 +451,13 @@ void rt2800_mcu_request(struct rt2x00_de
+ rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
+ rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0);
+ rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1);
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
+
+ reg = 0;
+ rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
+ rt2800_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg);
++ rt2800_shared_mem_unlock(rt2x00dev);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+@@ -674,7 +676,9 @@ int rt2800_load_firmware(struct rt2x00_d
+ * Wait for device to stabilize.
+ */
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
++ rt2800_shared_mem_unlock(rt2x00dev);
+ if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
+ break;
+ msleep(1);
+@@ -694,10 +698,16 @@ int rt2800_load_firmware(struct rt2x00_d
+ /*
+ * Initialize firmware.
+ */
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+ rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
++ rt2800_shared_mem_unlock(rt2x00dev);
++
+ if (rt2x00_is_usb(rt2x00dev)) {
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
++ rt2800_shared_mem_unlock(rt2x00dev);
++
+ rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
+ }
+ msleep(1);
+@@ -1035,8 +1045,10 @@ void rt2800_write_beacon(struct queue_en
+
+ beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
+
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
+ entry->skb->len + padding_len);
++ rt2800_shared_mem_unlock(rt2x00dev);
+ __set_bit(ENTRY_BCN_ENABLED, &entry->flags);
+
+ /*
+@@ -1066,6 +1078,8 @@ static inline void rt2800_clear_beacon_r
+
+ beacon_base = rt2800_hw_beacon_base(rt2x00dev, index);
+
++ rt2800_shared_mem_lock(rt2x00dev);
++
+ /*
+ * For the Beacon base registers we only need to clear
+ * the whole TXWI which (when set to 0) will invalidate
+@@ -1073,6 +1087,8 @@ static inline void rt2800_clear_beacon_r
+ */
+ for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
+ rt2800_register_write(rt2x00dev, beacon_base + i, 0);
++
++ rt2800_shared_mem_unlock(rt2x00dev);
+ }
+
+ void rt2800_clear_beacon(struct queue_entry *entry)
+@@ -1261,7 +1277,9 @@ static void rt2800_delete_wcid_attr(stru
+ {
+ u32 offset;
+ offset = MAC_WCID_ATTR_ENTRY(wcid);
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_write(rt2x00dev, offset, 0);
++ rt2800_shared_mem_unlock(rt2x00dev);
+ }
+
+ static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev,
+@@ -1274,11 +1292,13 @@ static void rt2800_config_wcid_attr_bssi
+ * The BSS Idx numbers is split in a main value of 3 bits,
+ * and a extended field for adding one additional bit to the value.
+ */
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX, (bssidx & 0x7));
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT,
+ (bssidx & 0x8) >> 3);
+ rt2800_register_write(rt2x00dev, offset, reg);
++ rt2800_shared_mem_unlock(rt2x00dev);
+ }
+
+ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
+@@ -1291,6 +1311,7 @@ static void rt2800_config_wcid_attr_ciph
+
+ offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
+
++ rt2800_shared_mem_lock(rt2x00dev);
+ if (crypto->cmd == SET_KEY) {
+ rt2800_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
+@@ -1315,6 +1336,7 @@ static void rt2800_config_wcid_attr_ciph
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0);
+ rt2800_register_write(rt2x00dev, offset, reg);
+ }
++ rt2800_shared_mem_unlock(rt2x00dev);
+
+ offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
+
+@@ -1324,8 +1346,11 @@ static void rt2800_config_wcid_attr_ciph
+ (crypto->cipher == CIPHER_AES))
+ iveiv_entry.iv[3] |= 0x20;
+ iveiv_entry.iv[3] |= key->keyidx << 6;
++
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_multiwrite(rt2x00dev, offset,
+ &iveiv_entry, sizeof(iveiv_entry));
++ rt2800_shared_mem_unlock(rt2x00dev);
+ }
+
+ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
+@@ -1348,8 +1373,11 @@ int rt2800_config_shared_key(struct rt2x
+ sizeof(key_entry.rx_mic));
+
+ offset = SHARED_KEY_ENTRY(key->hw_key_idx);
++
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_multiwrite(rt2x00dev, offset,
+ &key_entry, sizeof(key_entry));
++ rt2800_shared_mem_unlock(rt2x00dev);
+ }
+
+ /*
+@@ -1364,10 +1392,12 @@ int rt2800_config_shared_key(struct rt2x
+
+ offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
+
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, field,
+ (crypto->cmd == SET_KEY) * crypto->cipher);
+ rt2800_register_write(rt2x00dev, offset, reg);
++ rt2800_shared_mem_unlock(rt2x00dev);
+
+ /*
+ * Update WCID information
+@@ -1405,8 +1435,11 @@ int rt2800_config_pairwise_key(struct rt
+ sizeof(key_entry.rx_mic));
+
+ offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
++
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_multiwrite(rt2x00dev, offset,
+ &key_entry, sizeof(key_entry));
++ rt2800_shared_mem_unlock(rt2x00dev);
+ }
+
+ /*
+@@ -4884,14 +4917,19 @@ static int rt2800_init_registers(struct
+ /*
+ * ASIC will keep garbage value after boot, clear encryption keys.
+ */
++ rt2800_shared_mem_lock(rt2x00dev);
+ for (i = 0; i < 4; i++)
+ rt2800_register_write(rt2x00dev,
+ SHARED_KEY_MODE_ENTRY(i), 0);
++ rt2800_shared_mem_unlock(rt2x00dev);
+
+ for (i = 0; i < 256; i++) {
+ rt2800_config_wcid(rt2x00dev, NULL, i);
+ rt2800_delete_wcid_attr(rt2x00dev, i);
++
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
++ rt2800_shared_mem_unlock(rt2x00dev);
+ }
+
+ /*
+@@ -5017,8 +5055,10 @@ static int rt2800_wait_bbp_ready(struct
+ * BBP was enabled after firmware was loaded,
+ * but we need to reactivate it now.
+ */
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+ rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
++ rt2800_shared_mem_unlock(rt2x00dev);
+ msleep(1);
+
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+@@ -6714,11 +6754,19 @@ int rt2800_enable_radio(struct rt2x00_de
+ /*
+ * Send signal during boot time to initialize firmware.
+ */
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+ rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+- if (rt2x00_is_usb(rt2x00dev))
++ rt2800_shared_mem_unlock(rt2x00dev);
++
++ if (rt2x00_is_usb(rt2x00dev)) {
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
++ rt2800_shared_mem_unlock(rt2x00dev);
++ }
++
+ rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
++
+ msleep(1);
+
+ /*
+@@ -7725,6 +7773,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+ int retval;
+ u32 reg;
+
++ rt2800_shared_mem_init_lock(rt2x00dev);
++
+ retval = rt2800_probe_rt(rt2x00dev);
+ if (retval)
+ return retval;
+@@ -7808,8 +7858,11 @@ void rt2800_get_key_seq(struct ieee80211
+ return;
+
+ offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
++
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2800_register_multiread(rt2x00dev, offset,
+ &iveiv_entry, sizeof(iveiv_entry));
++ rt2800_shared_mem_unlock(rt2x00dev);
+
+ memcpy(&seq->tkip.iv16, &iveiv_entry.iv[0], 2);
+ memcpy(&seq->tkip.iv32, &iveiv_entry.iv[4], 4);
+--- a/drivers/net/wireless/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
+@@ -38,6 +38,11 @@ struct rt2800_drv_data {
+ DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
+
+ unsigned long rt2800_flags;
++
++ union {
++ spinlock_t spin;
++ struct mutex mutex;
++ } shmem_lock;
+ };
+
+ struct rt2800_ops {
+@@ -68,6 +73,10 @@ struct rt2800_ops {
+ const u8 *data, const size_t len);
+ int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
+ __le32 *(*drv_get_txwi)(struct queue_entry *entry);
++
++ void (*shmem_init_lock)(struct rt2x00_dev *rt2x00dev);
++ void (*shmem_lock)(struct rt2x00_dev *rt2x00dev);
++ void (*shmem_unlock)(struct rt2x00_dev *rt2x00dev);
+ };
+
+ static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
+@@ -77,6 +86,29 @@ static inline bool rt2800_has_high_share
+ return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
+ }
+
++static inline void rt2800_shared_mem_init_lock(struct rt2x00_dev *rt2x00dev)
++{
++ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
++
++ rt2800ops->shmem_init_lock(rt2x00dev);
++}
++
++static inline void rt2800_shared_mem_lock(struct rt2x00_dev *rt2x00dev)
++{
++ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
++
++ if (rt2800_has_high_shared_mem(rt2x00dev))
++ rt2800ops->shmem_lock(rt2x00dev);
++}
++
++static inline void rt2800_shared_mem_unlock(struct rt2x00_dev *rt2x00dev)
++{
++ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
++
++ if (rt2800_has_high_shared_mem(rt2x00dev))
++ rt2800ops->shmem_unlock(rt2x00dev);
++}
++
+ static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ u32 *value)
+--- a/drivers/net/wireless/rt2x00/rt2800mmio.c
++++ b/drivers/net/wireless/rt2x00/rt2800mmio.c
+@@ -820,8 +820,10 @@ int rt2800mmio_init_registers(struct rt2
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
+ rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
+
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
+ rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
++ rt2800_shared_mem_unlock(rt2x00dev);
+
+ if (rt2x00_is_pcie(rt2x00dev) &&
+ (rt2x00_rt(rt2x00dev, RT3090) ||
+@@ -865,6 +867,30 @@ int rt2800mmio_enable_radio(struct rt2x0
+ }
+ EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio);
+
++void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++
++ spin_lock_init(&drv_data->shmem_lock.spin);
++}
++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_init_lock);
++
++void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++
++ spin_lock_bh(&drv_data->shmem_lock.spin);
++}
++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_lock);
++
++void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++
++ spin_unlock_bh(&drv_data->shmem_lock.spin);
++}
++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_unlock);
++
+ MODULE_AUTHOR(DRV_PROJECT);
+ MODULE_VERSION(DRV_VERSION);
+ MODULE_DESCRIPTION("rt2800 MMIO library");
+--- a/drivers/net/wireless/rt2x00/rt2800mmio.h
++++ b/drivers/net/wireless/rt2x00/rt2800mmio.h
+@@ -160,4 +160,8 @@ int rt2800mmio_init_registers(struct rt2
+ /* Device state switch handlers. */
+ int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev);
+
++void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev);
++void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev);
++void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev);
++
+ #endif /* RT2800MMIO_H */
+--- a/drivers/net/wireless/rt2x00/rt2800pci.c
++++ b/drivers/net/wireless/rt2x00/rt2800pci.c
+@@ -69,7 +69,9 @@ static void rt2800pci_mcu_status(struct
+ return;
+
+ for (i = 0; i < 200; i++) {
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2x00mmio_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
++ rt2800_shared_mem_unlock(rt2x00dev);
+
+ if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) ||
+ (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) ||
+@@ -83,8 +85,10 @@ static void rt2800pci_mcu_status(struct
+ if (i == 200)
+ rt2x00_err(rt2x00dev, "MCU request failed, no response from hardware\n");
+
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
++ rt2800_shared_mem_unlock(rt2x00dev);
+ }
+
+ static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
+@@ -184,6 +188,8 @@ static int rt2800pci_write_firmware(stru
+ */
+ reg = 0;
+ rt2x00_set_field32(&reg, PBF_SYS_CTRL_HOST_RAM_WRITE, 1);
++
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
+
+ /*
+@@ -197,6 +203,7 @@ static int rt2800pci_write_firmware(stru
+
+ rt2x00mmio_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
++ rt2800_shared_mem_unlock(rt2x00dev);
+
+ return 0;
+ }
+@@ -213,8 +220,10 @@ static int rt2800pci_enable_radio(struct
+ return retval;
+
+ /* After resume MCU_BOOT_SIGNAL will trash these. */
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
++ rt2800_shared_mem_unlock(rt2x00dev);
+
+ rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02);
+ rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF);
+@@ -233,10 +242,12 @@ static int rt2800pci_set_state(struct rt
+ 0, 0x02);
+ rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP);
+ } else if (state == STATE_SLEEP) {
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS,
+ 0xffffffff);
+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID,
+ 0xffffffff);
++ rt2800_shared_mem_unlock(rt2x00dev);
+ rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP,
+ 0xff, 0x01);
+ }
+@@ -337,6 +348,9 @@ static const struct rt2800_ops rt2800pci
+ .drv_write_firmware = rt2800pci_write_firmware,
+ .drv_init_registers = rt2800mmio_init_registers,
+ .drv_get_txwi = rt2800mmio_get_txwi,
++ .shmem_init_lock = rt2800mmio_shmem_init_lock,
++ .shmem_lock = rt2800mmio_shmem_lock,
++ .shmem_unlock = rt2800mmio_shmem_unlock,
+ };
+
+ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
+--- a/drivers/net/wireless/rt2x00/rt2800soc.c
++++ b/drivers/net/wireless/rt2x00/rt2800soc.c
+@@ -176,6 +176,9 @@ static const struct rt2800_ops rt2800soc
+ .drv_write_firmware = rt2800soc_write_firmware,
+ .drv_init_registers = rt2800mmio_init_registers,
+ .drv_get_txwi = rt2800mmio_get_txwi,
++ .shmem_init_lock = rt2800mmio_shmem_init_lock,
++ .shmem_lock = rt2800mmio_shmem_lock,
++ .shmem_unlock = rt2800mmio_shmem_unlock,
+ };
+
+ static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
+--- a/drivers/net/wireless/rt2x00/rt2800usb.c
++++ b/drivers/net/wireless/rt2x00/rt2800usb.c
+@@ -51,6 +51,27 @@ static bool rt2800usb_hwcrypt_disabled(s
+ return modparam_nohwcrypt;
+ }
+
++static void rt2800usb_shmem_init_lock(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++
++ mutex_init(&drv_data->shmem_lock.mutex);
++}
++
++static void rt2800usb_shmem_lock(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++
++ mutex_lock(&drv_data->shmem_lock.mutex);
++}
++
++static void rt2800usb_shmem_unlock(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++
++ mutex_unlock(&drv_data->shmem_lock.mutex);
++}
++
+ /*
+ * Queue handlers.
+ */
+@@ -299,8 +320,10 @@ static int rt2800usb_write_firmware(stru
+ data + offset, length);
+ }
+
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
++ rt2800_shared_mem_unlock(rt2x00dev);
+
+ /*
+ * Send firmware request to device to load firmware,
+@@ -315,7 +338,10 @@ static int rt2800usb_write_firmware(stru
+ }
+
+ msleep(10);
++
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
++ rt2800_shared_mem_unlock(rt2x00dev);
+
+ return 0;
+ }
+@@ -333,8 +359,10 @@ static int rt2800usb_init_registers(stru
+ if (rt2800_wait_csr_ready(rt2x00dev))
+ return -EBUSY;
+
++ rt2800_shared_mem_lock(rt2x00dev);
+ rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+ rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
++ rt2800_shared_mem_unlock(rt2x00dev);
+
+ reg = 0;
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
+@@ -863,6 +891,9 @@ static const struct rt2800_ops rt2800usb
+ .drv_write_firmware = rt2800usb_write_firmware,
+ .drv_init_registers = rt2800usb_init_registers,
+ .drv_get_txwi = rt2800usb_get_txwi,
++ .shmem_init_lock = rt2800usb_shmem_init_lock,
++ .shmem_lock = rt2800usb_shmem_lock,
++ .shmem_unlock = rt2800usb_shmem_unlock,
+ };
+
+ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
diff --git a/package/kernel/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch b/package/kernel/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch
new file mode 100644
index 0000000..b8c1914
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch
@@ -0,0 +1,131 @@
+From dcfe3dd46242050f100162dce2bcad24d2c942c6 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sat, 17 Aug 2013 19:31:42 +0200
+Subject: [PATCH] rt2x00: rt2800lib: fix beacon generation on RT3593
+
+On the RT3593 chipset, the beacon registers are located
+in the high 8KB part of the shared memory.
+
+The high part of the shared memory is only accessible
+if it is explicitly selected. Add a helper function
+in order to be able to control the SHR_MSEL bit in
+the PBF_SYS_CTRL register. Also add a few more helper
+functions and use those to select the correct part of
+the shared memory before and after accessing the beacon
+registers.
+
+The base addresses of the beacon registers are also
+different from the actually used values, so fix the
+'rt2800_hw_beacon_base' function to return the correct
+values.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+Changes since v1: ---
+---
+ drivers/net/wireless/rt2x00/rt2800.h | 3 +++
+ drivers/net/wireless/rt2x00/rt2800lib.c | 44 +++++++++++++++++++++++++++++++
+ 2 files changed, 47 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -574,6 +574,7 @@
+ #define PBF_SYS_CTRL 0x0400
+ #define PBF_SYS_CTRL_READY FIELD32(0x00000080)
+ #define PBF_SYS_CTRL_HOST_RAM_WRITE FIELD32(0x00010000)
++#define PBF_SYS_CTRL_SHR_MSEL FIELD32(0x00080000)
+
+ /*
+ * HOST-MCU shared memory
+@@ -2026,6 +2027,8 @@ struct mac_iveiv_entry {
+ (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
+ (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
+
++#define HW_BEACON_BASE_HIGH(__index) (0x4000 + (__index) * 512)
++
+ #define BEACON_BASE_TO_OFFSET(_base) (((_base) - 0x4000) / 64)
+
+ /*
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -82,6 +82,39 @@ static inline bool rt2800_is_305x_soc(st
+ return false;
+ }
+
++static inline void rt2800_shared_mem_select(struct rt2x00_dev *rt2x00dev,
++ bool high)
++{
++ u32 reg;
++
++ if (WARN_ON_ONCE(!rt2800_has_high_shared_mem(rt2x00dev)))
++ return;
++
++ rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
++ rt2x00_set_field32(&reg, PBF_SYS_CTRL_SHR_MSEL, high);
++ rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
++}
++
++static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev)
++{
++ if (rt2x00_rt(rt2x00dev, RT3593))
++ return true;
++
++ return false;
++}
++
++static inline void rt2800_select_beacon_mem(struct rt2x00_dev *rt2x00dev)
++{
++ if (rt2800_beacon_uses_high_mem(rt2x00dev))
++ rt2800_shared_mem_select(rt2x00dev, true);
++}
++
++static inline void rt2800_deselect_beacon_mem(struct rt2x00_dev *rt2x00dev)
++{
++ if (rt2800_beacon_uses_high_mem(rt2x00dev))
++ rt2800_shared_mem_select(rt2x00dev, false);
++}
++
+ static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u8 value)
+ {
+@@ -948,6 +981,9 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
+ static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
+ unsigned int index)
+ {
++ if (rt2x00_rt(rt2x00dev, RT3593))
++ return HW_BEACON_BASE_HIGH(index);
++
+ return HW_BEACON_BASE(index);
+ }
+
+@@ -1046,8 +1082,12 @@ void rt2800_write_beacon(struct queue_en
+ beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
+
+ rt2800_shared_mem_lock(rt2x00dev);
++
++ rt2800_select_beacon_mem(rt2x00dev);
+ rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
+ entry->skb->len + padding_len);
++ rt2800_deselect_beacon_mem(rt2x00dev);
++
+ rt2800_shared_mem_unlock(rt2x00dev);
+ __set_bit(ENTRY_BCN_ENABLED, &entry->flags);
+
+@@ -1080,6 +1120,8 @@ static inline void rt2800_clear_beacon_r
+
+ rt2800_shared_mem_lock(rt2x00dev);
+
++ rt2800_select_beacon_mem(rt2x00dev);
++
+ /*
+ * For the Beacon base registers we only need to clear
+ * the whole TXWI which (when set to 0) will invalidate
+@@ -1088,6 +1130,8 @@ static inline void rt2800_clear_beacon_r
+ for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
+ rt2800_register_write(rt2x00dev, beacon_base + i, 0);
+
++ rt2800_deselect_beacon_mem(rt2x00dev);
++
+ rt2800_shared_mem_unlock(rt2x00dev);
+ }
+
diff --git a/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch b/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch
new file mode 100644
index 0000000..d04998a
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch
@@ -0,0 +1,62 @@
+From a058825fa7b53fab3b003d8928b60e5b686b3421 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 4 Aug 2013 14:36:11 +0200
+Subject: [PATCH] rt2x00: rt2800lib: add hw_beacon_count field to struct
+ rt2800_drv_data
+
+Some chipsets can handle more than 8 beacons at once.
+Add a new field to the rt2800_drv_data structure which
+will hold the number of supported beacons of the given
+chipset.
+
+Update the rt2x00_init_registers function to get the
+beacon count from the new field instead of using a
+hardcoded value.
+
+In order to keep the current behaviour, initialize the
+new field with the actually used value.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 5 ++++-
+ drivers/net/wireless/rt2x00/rt2800lib.h | 1 +
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -4614,6 +4614,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
+ */
+ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
+ {
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+ u32 reg;
+ u16 eeprom;
+ unsigned int i;
+@@ -4979,7 +4980,7 @@ static int rt2800_init_registers(struct
+ /*
+ * Clear all beacons
+ */
+- for (i = 0; i < 8; i++)
++ for (i = 0; i < drv_data->hw_beacon_count; i++)
+ rt2800_clear_beacon_register(rt2x00dev, i);
+
+ if (rt2x00_is_usb(rt2x00dev)) {
+@@ -7826,6 +7827,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+ if (rt2x00_rt(rt2x00dev, RT3593))
+ __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
+
++ drv_data->hw_beacon_count = 8;
++
+ /*
+ * Allocate eeprom data.
+ */
+--- a/drivers/net/wireless/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
+@@ -35,6 +35,7 @@ struct rt2800_drv_data {
+ u8 txmixer_gain_24g;
+ u8 txmixer_gain_5g;
+ unsigned int tbtt_tick;
++ unsigned int hw_beacon_count;
+ DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
+
+ unsigned long rt2800_flags;
diff --git a/package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch b/package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch
new file mode 100644
index 0000000..f5231f0
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch
@@ -0,0 +1,67 @@
+From 1bfa43ca8f30be53ce4fa79cfc3e219642a812b6 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Mon, 2 Sep 2013 10:58:32 +0200
+Subject: [PATCH] rt2x00: rt2800lib: init additional beacon offset registers
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800.h | 14 ++++++++++++++
+ drivers/net/wireless/rt2x00/rt2800lib.c | 24 ++++++++++++++++++++++++
+ 2 files changed, 38 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -629,6 +629,20 @@
+ */
+ #define PBF_DBG 0x043c
+
++/* BCN_OFFSET2 */
++#define BCN_OFFSET2 0x0444
++#define BCN_OFFSET2_BCN8 FIELD32(0x000000ff)
++#define BCN_OFFSET2_BCN9 FIELD32(0x0000ff00)
++#define BCN_OFFSET2_BCN10 FIELD32(0x00ff0000)
++#define BCN_OFFSET2_BCN11 FIELD32(0xff000000)
++
++/* BCN_OFFSET3 */
++#define BCN_OFFSET3 0x0448
++#define BCN_OFFSET3_BCN12 FIELD32(0x000000ff)
++#define BCN_OFFSET3_BCN13 FIELD32(0x0000ff00)
++#define BCN_OFFSET3_BCN14 FIELD32(0x00ff0000)
++#define BCN_OFFSET3_BCN15 FIELD32(0xff000000)
++
+ /*
+ * RF registers
+ */
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -4626,6 +4626,30 @@ static int rt2800_init_registers(struct
+ if (ret)
+ return ret;
+
++ if (drv_data->hw_beacon_count == 16) {
++ rt2800_register_read(rt2x00dev, BCN_OFFSET2, &reg);
++ rt2x00_set_field32(&reg, BCN_OFFSET2_BCN8,
++ rt2800_get_beacon_offset(rt2x00dev, 8));
++ rt2x00_set_field32(&reg, BCN_OFFSET2_BCN9,
++ rt2800_get_beacon_offset(rt2x00dev, 9));
++ rt2x00_set_field32(&reg, BCN_OFFSET2_BCN10,
++ rt2800_get_beacon_offset(rt2x00dev, 10));
++ rt2x00_set_field32(&reg, BCN_OFFSET2_BCN11,
++ rt2800_get_beacon_offset(rt2x00dev, 11));
++ rt2800_register_write(rt2x00dev, BCN_OFFSET2, reg);
++
++ rt2800_register_read(rt2x00dev, BCN_OFFSET3, &reg);
++ rt2x00_set_field32(&reg, BCN_OFFSET3_BCN12,
++ rt2800_get_beacon_offset(rt2x00dev, 12));
++ rt2x00_set_field32(&reg, BCN_OFFSET3_BCN13,
++ rt2800_get_beacon_offset(rt2x00dev, 13));
++ rt2x00_set_field32(&reg, BCN_OFFSET3_BCN14,
++ rt2800_get_beacon_offset(rt2x00dev, 14));
++ rt2x00_set_field32(&reg, BCN_OFFSET3_BCN15,
++ rt2800_get_beacon_offset(rt2x00dev, 15));
++ rt2800_register_write(rt2x00dev, BCN_OFFSET3, reg);
++ }
++
+ rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
+ rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+
diff --git a/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch b/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch
new file mode 100644
index 0000000..4b21eae
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch
@@ -0,0 +1,24 @@
+From 9bea8b61f6025cd633bd5ac71be258620b49bcb3 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Mon, 2 Sep 2013 11:00:06 +0200
+Subject: [PATCH] rt2x00: rt2800lib: fix max supported beacon count for RT3593
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -7851,7 +7851,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+ if (rt2x00_rt(rt2x00dev, RT3593))
+ __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
+
+- drv_data->hw_beacon_count = 8;
++ if (rt2x00_rt(rt2x00dev, RT3593))
++ drv_data->hw_beacon_count = 16;
++ else
++ drv_data->hw_beacon_count = 8;
+
+ /*
+ * Allocate eeprom data.
diff --git a/package/kernel/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch b/package/kernel/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch
new file mode 100644
index 0000000..8a10c6e
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch
@@ -0,0 +1,30 @@
+From 91094ed065f7794886b4a5490fd6de942f036bb4 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 24 Mar 2013 19:26:26 +0100
+Subject: [PATCH] rt2x00: allow to build rt2800soc module for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/Kconfig
++++ b/drivers/net/wireless/rt2x00/Kconfig
+@@ -210,7 +210,7 @@ endif
+ config RT2800SOC
+ tristate "Ralink WiSoC support"
+ depends on m
+- depends on SOC_RT288X || SOC_RT305X
++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
+ select RT2X00_LIB_SOC
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_CRYPTO
+@@ -245,7 +245,7 @@ config RT2X00_LIB_PCI
+
+ config RT2X00_LIB_SOC
+ tristate "RT2x00 SoC support"
+- depends on SOC_RT288X || SOC_RT305X
++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
+ depends on m
+ select RT2X00_LIB
+
diff --git a/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch b/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch
new file mode 100644
index 0000000..e77cd86
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch
@@ -0,0 +1,20 @@
+From 4f16582c93a71eba9d389e0f0a8aa9099a9587cd Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 24 Mar 2013 19:26:26 +0100
+Subject: [PATCH] rt2x00: rt2800lib: enable support for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -7821,6 +7821,7 @@ static int rt2800_probe_rt(struct rt2x00
+ case RT3390:
+ case RT3572:
+ case RT3593:
++ case RT3883:
+ case RT5390:
+ case RT5392:
+ case RT5592:
diff --git a/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch b/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch
new file mode 100644
index 0000000..780c1dd
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch
@@ -0,0 +1,112 @@
+From ecb394ccf248d8652c463133c4f404458a57a9c1 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 24 Mar 2013 19:26:26 +0100
+Subject: [PATCH] rt2x00: rt2800lib: add rf_vals for RF3853
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800.h | 4 +-
+ drivers/net/wireless/rt2x00/rt2800lib.c | 65 +++++++++++++++++++++++++++++++
+ 2 files changed, 68 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -48,7 +48,8 @@
+ * RF2853 2.4G/5G 3T3R
+ * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
+ * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
+- * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
++ * RF3053 2.4G/5G 3T3R(RT3563/RT3573/RT3593)
++ * RF3853 2.4G/5G 3T3R(RT3883/RT3662)
+ * RF5592 2.4G/5G 2T2R
+ * RF3070 2.4G 1T1R
+ * RF5360 2.4G 1T1R
+@@ -72,6 +73,7 @@
+ #define RF5592 0x000f
+ #define RF3070 0x3070
+ #define RF3290 0x3290
++#define RF3853 0x3853
+ #define RF5360 0x5360
+ #define RF5362 0x5362
+ #define RF5370 0x5370
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -7441,6 +7441,66 @@ static const struct rf_channel rf_vals_3
+ {173, 0x61, 0, 9},
+ };
+
++static const struct rf_channel rf_vals_3853[] = {
++ {1, 241, 6, 2},
++ {2, 241, 6, 7},
++ {3, 242, 6, 2},
++ {4, 242, 6, 7},
++ {5, 243, 6, 2},
++ {6, 243, 6, 7},
++ {7, 244, 6, 2},
++ {8, 244, 6, 7},
++ {9, 245, 6, 2},
++ {10, 245, 6, 7},
++ {11, 246, 6, 2},
++ {12, 246, 6, 7},
++ {13, 247, 6, 2},
++ {14, 248, 6, 4},
++
++ {36, 0x56, 8, 4},
++ {38, 0x56, 8, 6},
++ {40, 0x56, 8, 8},
++ {44, 0x57, 8, 0},
++ {46, 0x57, 8, 2},
++ {48, 0x57, 8, 4},
++ {52, 0x57, 8, 8},
++ {54, 0x57, 8, 10},
++ {56, 0x58, 8, 0},
++ {60, 0x58, 8, 4},
++ {62, 0x58, 8, 6},
++ {64, 0x58, 8, 8},
++
++ {100, 0x5b, 8, 8},
++ {102, 0x5b, 8, 10},
++ {104, 0x5c, 8, 0},
++ {108, 0x5c, 8, 4},
++ {110, 0x5c, 8, 6},
++ {112, 0x5c, 8, 8},
++ {114, 0x5c, 8, 10},
++ {116, 0x5d, 8, 0},
++ {118, 0x5d, 8, 2},
++ {120, 0x5d, 8, 4},
++ {124, 0x5d, 8, 8},
++ {126, 0x5d, 8, 10},
++ {128, 0x5e, 8, 0},
++ {132, 0x5e, 8, 4},
++ {134, 0x5e, 8, 6},
++ {136, 0x5e, 8, 8},
++ {140, 0x5f, 8, 0},
++
++ {149, 0x5f, 8, 9},
++ {151, 0x5f, 8, 11},
++ {153, 0x60, 8, 1},
++ {157, 0x60, 8, 5},
++ {159, 0x60, 8, 7},
++ {161, 0x60, 8, 9},
++ {165, 0x61, 8, 1},
++ {167, 0x61, 8, 3},
++ {169, 0x61, 8, 5},
++ {171, 0x61, 8, 7},
++ {173, 0x61, 8, 9},
++};
++
+ static const struct rf_channel rf_vals_5592_xtal20[] = {
+ /* Channel, N, K, mod, R */
+ {1, 482, 4, 10, 3},
+@@ -7668,6 +7728,11 @@ static int rt2800_probe_hw_mode(struct r
+ spec->channels = rf_vals_3x;
+ break;
+
++ case RF3853:
++ spec->num_channels = ARRAY_SIZE(rf_vals_3853);
++ spec->channels = rf_vals_3853;
++ break;
++
+ case RF5592:
+ rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX, &reg);
+ if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) {
diff --git a/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch b/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch
new file mode 100644
index 0000000..858dece
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch
@@ -0,0 +1,28 @@
+From f8e3fcf18e1f2d7f9e6a9680c5452da090f33d88 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Thu, 1 Aug 2013 14:40:44 +0200
+Subject: [PATCH] rt2x00: rt2800lib: enable VCO calibration for RF3853
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -4378,6 +4378,7 @@ void rt2800_vco_calibration(struct rt2x0
+ case RF3053:
+ case RF3070:
+ case RF3290:
++ case RF3853:
+ case RF5360:
+ case RF5362:
+ case RF5370:
+@@ -7847,6 +7848,7 @@ static int rt2800_probe_hw_mode(struct r
+ case RF3053:
+ case RF3070:
+ case RF3290:
++ case RF3853:
+ case RF5360:
+ case RF5362:
+ case RF5370:
diff --git a/package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch b/package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch
new file mode 100644
index 0000000..ed82e44
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch
@@ -0,0 +1,235 @@
+From 6e3a17190815c6aa4dc53c2cfe9125fb1154f187 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 24 Mar 2013 19:26:27 +0100
+Subject: [PATCH] rt2x00: rt2800lib: add channel configuration function for
+ RF3853
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 208 +++++++++++++++++++++++++++++++
+ 1 file changed, 208 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -2625,6 +2625,211 @@ static void rt2800_config_channel_rf3053
+ }
+ }
+
++static void rt2800_config_channel_rf3853(struct rt2x00_dev *rt2x00dev,
++ struct ieee80211_conf *conf,
++ struct rf_channel *rf,
++ struct channel_info *info)
++{
++ u8 rfcsr;
++ u8 bbp;
++ u8 pwr1, pwr2, pwr3;
++
++ const bool txbf_enabled = false; /* TODO */
++
++ /* TODO: add band selection */
++
++ if (rf->channel <= 14)
++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
++ else if (rf->channel < 132)
++ rt2800_rfcsr_write(rt2x00dev, 6, 0x80);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
++
++ rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
++ rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
++
++ if (rf->channel <= 14)
++ rt2800_rfcsr_write(rt2x00dev, 11, 0x46);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 11, 0x48);
++
++ if (rf->channel <= 14)
++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 12, 0x52);
++
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
++
++ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
++ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
++ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
++ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
++ rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
++
++ switch (rt2x00dev->default_ant.tx_chain_num) {
++ case 3:
++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
++ /* fallthrough */
++ case 2:
++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
++ /* fallthrough */
++ case 1:
++ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
++ break;
++ }
++
++ switch (rt2x00dev->default_ant.rx_chain_num) {
++ case 3:
++ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
++ /* fallthrough */
++ case 2:
++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
++ /* fallthrough */
++ case 1:
++ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
++ break;
++ }
++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
++
++ rt2800_adjust_freq_offset(rt2x00dev);
++
++ rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
++ if (!conf_is_ht40(conf))
++ rfcsr &= ~(0x06);
++ else
++ rfcsr |= 0x06;
++ rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
++
++ if (rf->channel <= 14)
++ rt2800_rfcsr_write(rt2x00dev, 31, 0xa0);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
++
++ if (conf_is_ht40(conf))
++ rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8);
++
++ if (rf->channel <= 14)
++ rt2800_rfcsr_write(rt2x00dev, 34, 0x3c);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 34, 0x20);
++
++ /* loopback RF_BS */
++ rt2800_rfcsr_read(rt2x00dev, 36, &rfcsr);
++ if (rf->channel <= 14)
++ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1);
++ else
++ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0);
++ rt2800_rfcsr_write(rt2x00dev, 36, rfcsr);
++
++ if (rf->channel <= 14)
++ rfcsr = 0x23;
++ else if (rf->channel < 100)
++ rfcsr = 0x36;
++ else if (rf->channel < 132)
++ rfcsr = 0x32;
++ else
++ rfcsr = 0x30;
++
++ if (txbf_enabled)
++ rfcsr |= 0x40;
++
++ rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
++
++ if (rf->channel <= 14)
++ rt2800_rfcsr_write(rt2x00dev, 44, 0x93);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 44, 0x9b);
++
++ if (rf->channel <= 14)
++ rfcsr = 0xbb;
++ else if (rf->channel < 100)
++ rfcsr = 0xeb;
++ else if (rf->channel < 132)
++ rfcsr = 0xb3;
++ else
++ rfcsr = 0x9b;
++ rt2800_rfcsr_write(rt2x00dev, 45, rfcsr);
++
++ if (rf->channel <= 14)
++ rfcsr = 0x8e;
++ else
++ rfcsr = 0x8a;
++
++ if (txbf_enabled)
++ rfcsr |= 0x20;
++
++ rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
++
++ rt2800_rfcsr_write(rt2x00dev, 50, 0x86);
++
++ rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
++ if (rf->channel <= 14)
++ rt2800_rfcsr_write(rt2x00dev, 51, 0x75);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 51, 0x51);
++
++ rt2800_rfcsr_read(rt2x00dev, 52, &rfcsr);
++ if (rf->channel <= 14)
++ rt2800_rfcsr_write(rt2x00dev, 52, 0x45);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
++
++ if (rf->channel <= 14) {
++ pwr1 = info->default_power1 & 0x1f;
++ pwr2 = info->default_power2 & 0x1f;
++ pwr3 = info->default_power3 & 0x1f;
++ } else {
++ pwr1 = 0x48 | ((info->default_power1 & 0x18) << 1) |
++ (info->default_power1 & 0x7);
++ pwr2 = 0x48 | ((info->default_power2 & 0x18) << 1) |
++ (info->default_power2 & 0x7);
++ pwr3 = 0x48 | ((info->default_power3 & 0x18) << 1) |
++ (info->default_power3 & 0x7);
++ }
++
++ rt2800_rfcsr_write(rt2x00dev, 53, pwr1);
++ rt2800_rfcsr_write(rt2x00dev, 54, pwr2);
++ rt2800_rfcsr_write(rt2x00dev, 55, pwr3);
++
++ rt2x00_dbg(rt2x00dev, "Channel:%d, pwr1:%02x, pwr2:%02x, pwr3:%02x\n",
++ rf->channel, pwr1, pwr2, pwr3);
++
++ bbp = (info->default_power1 >> 5) |
++ ((info->default_power2 & 0xe0) >> 1);
++ rt2800_bbp_write(rt2x00dev, 109, bbp);
++
++ rt2800_bbp_read(rt2x00dev, 110, &bbp);
++ bbp &= 0x0f;
++ bbp |= (info->default_power3 & 0xe0) >> 1;
++ rt2800_bbp_write(rt2x00dev, 110, bbp);
++
++ rt2800_rfcsr_read(rt2x00dev, 57, &rfcsr);
++ if (rf->channel <= 14)
++ rt2800_rfcsr_write(rt2x00dev, 57, 0x6e);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e);
++
++ /* Enable RF tuning */
++ rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
++ rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
++
++ udelay(2000);
++
++ rt2800_bbp_read(rt2x00dev, 49, &bbp);
++ /* clear update flag */
++ rt2800_bbp_write(rt2x00dev, 49, bbp & 0xfe);
++ rt2800_bbp_write(rt2x00dev, 49, bbp);
++
++ /* TODO: add calibration for TxBF */
++}
++
+ #define POWER_BOUND 0x27
+ #define POWER_BOUND_5G 0x2b
+
+@@ -3237,6 +3442,9 @@ static void rt2800_config_channel(struct
+ case RF3322:
+ rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
+ break;
++ case RF3853:
++ rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info);
++ break;
+ case RF3070:
+ case RF5360:
+ case RF5362:
diff --git a/package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch b/package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch
new file mode 100644
index 0000000..33cbc4c
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch
@@ -0,0 +1,20 @@
+From afd38ae82226551bf879b6c7c4b620c271fee9d2 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Thu, 1 Aug 2013 14:42:05 +0200
+Subject: [PATCH] rt2x00: rt2800lib: enable RF3853 support
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -7406,6 +7406,7 @@ static int rt2800_init_eeprom(struct rt2
+ case RF3290:
+ case RF3320:
+ case RF3322:
++ case RF3853:
+ case RF5360:
+ case RF5362:
+ case RF5370:
diff --git a/package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch b/package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch
new file mode 100644
index 0000000..c3a4798
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch
@@ -0,0 +1,77 @@
+From 0094872a5e8e4664c6ea1b2dfa487063d39ae363 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 24 Mar 2013 19:26:26 +0100
+Subject: [PATCH] rt2x00: rt2800lib: add MAC register initialization for
+ RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800.h | 14 ++++++++++++++
+ drivers/net/wireless/rt2x00/rt2800lib.c | 19 ++++++++++++++++---
+ 2 files changed, 30 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -1588,6 +1588,20 @@
+ #define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00)
+
+ /*
++ * TX_TXBF_CFG:
++ */
++#define TX_TXBF_CFG_0 0x138c
++#define TX_TXBF_CFG_1 0x13a4
++#define TX_TXBF_CFG_2 0x13a8
++#define TX_TXBF_CFG_3 0x13ac
++
++/*
++ * TX_FBK_CFG_3S:
++ */
++#define TX_FBK_CFG_3S_0 0x13c4
++#define TX_FBK_CFG_3S_1 0x13c8
++
++/*
+ * RX_FILTER_CFG: RX configuration register.
+ */
+ #define RX_FILTER_CFG 0x1400
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -4981,6 +4981,12 @@ static int rt2800_init_registers(struct
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2,
+ 0x00000000);
+ }
++ } else if (rt2x00_rt(rt2x00dev, RT3883)) {
++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402);
++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
++ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000);
++ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21);
++ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40);
+ } else if (rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392) ||
+ rt2x00_rt(rt2x00dev, RT5592)) {
+@@ -5011,9 +5017,11 @@ static int rt2800_init_registers(struct
+
+ rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
+- if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
+- rt2x00_rt(rt2x00dev, RT2883) ||
+- rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
++ if (rt2x00_rt(rt2x00dev, RT3883))
++ rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 3);
++ else if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
++ rt2x00_rt(rt2x00dev, RT2883) ||
++ rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
+ else
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
+@@ -5166,6 +5174,11 @@ static int rt2800_init_registers(struct
+ reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002;
+ rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);
+
++ if (rt2x00_rt(rt2x00dev, RT3883)) {
++ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008);
++ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413);
++ }
++
+ rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
+ rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES,
diff --git a/package/kernel/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch b/package/kernel/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch
new file mode 100644
index 0000000..837c025
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch
@@ -0,0 +1,30 @@
+From 6c2d32478159fffff0b85abb6817a21bb2338231 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 24 Mar 2013 19:26:27 +0100
+Subject: [PATCH] rt2x00: rt2800soc: fix rt2800soc_disable_radio for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800soc.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800soc.c
++++ b/drivers/net/wireless/rt2x00/rt2800soc.c
+@@ -51,9 +51,16 @@ static bool rt2800soc_hwcrypt_disabled(s
+
+ static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev)
+ {
++ u32 reg;
++
+ rt2800_disable_radio(rt2x00dev);
+ rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+- rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0);
++
++ reg = 0;
++ if (rt2x00_rt(rt2x00dev, RT3883))
++ rt2x00_set_field32(&reg, TX_PIN_CFG_RFTR_EN, 1);
++
++ rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, reg);
+ }
+
+ static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev,
diff --git a/package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch b/package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch
new file mode 100644
index 0000000..e647777
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch
@@ -0,0 +1,71 @@
+From 84833056aa7dd25f5b097e31c78f2a0914c5160c Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 24 Mar 2013 19:26:26 +0100
+Subject: [PATCH] rt2x00: rt2800lib: add BBP register initialization for
+ RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 44 +++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -5784,6 +5784,47 @@ static void rt2800_init_bbp_3593(struct
+ rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+ }
+
++static void rt2800_init_bbp_3883(struct rt2x00_dev *rt2x00dev)
++{
++ rt2800_init_bbp_early(rt2x00dev);
++
++ rt2800_bbp_write(rt2x00dev, 4, 0x50);
++ rt2800_bbp_write(rt2x00dev, 47, 0x48);
++
++ rt2800_bbp_write(rt2x00dev, 86, 0x46);
++ rt2800_bbp_write(rt2x00dev, 88, 0x90);
++
++ rt2800_bbp_write(rt2x00dev, 92, 0x02);
++
++ rt2800_bbp_write(rt2x00dev, 103, 0xc0);
++ rt2800_bbp_write(rt2x00dev, 104, 0x92);
++ rt2800_bbp_write(rt2x00dev, 105, 0x34);
++ rt2800_bbp_write(rt2x00dev, 106, 0x12);
++ rt2800_bbp_write(rt2x00dev, 120, 0x50);
++ rt2800_bbp_write(rt2x00dev, 137, 0x0f);
++ rt2800_bbp_write(rt2x00dev, 163, 0x9d);
++
++ /* Set ITxBF timeout to 0x9C40=1000msec */
++ rt2800_bbp_write(rt2x00dev, 179, 0x02);
++ rt2800_bbp_write(rt2x00dev, 180, 0x00);
++ rt2800_bbp_write(rt2x00dev, 182, 0x40);
++ rt2800_bbp_write(rt2x00dev, 180, 0x01);
++ rt2800_bbp_write(rt2x00dev, 182, 0x9c);
++
++ rt2800_bbp_write(rt2x00dev, 179, 0x00);
++
++ /* Reprogram the inband interface to put right values in RXWI */
++ rt2800_bbp_write(rt2x00dev, 142, 0x04);
++ rt2800_bbp_write(rt2x00dev, 143, 0x3b);
++ rt2800_bbp_write(rt2x00dev, 142, 0x06);
++ rt2800_bbp_write(rt2x00dev, 143, 0xa0);
++ rt2800_bbp_write(rt2x00dev, 142, 0x07);
++ rt2800_bbp_write(rt2x00dev, 143, 0xa1);
++ rt2800_bbp_write(rt2x00dev, 142, 0x08);
++ rt2800_bbp_write(rt2x00dev, 143, 0xa2);
++ rt2800_bbp_write(rt2x00dev, 148, 0xc8);
++}
++
+ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
+ {
+ int ant, div_mode;
+@@ -6002,6 +6043,9 @@ static void rt2800_init_bbp(struct rt2x0
+ case RT3593:
+ rt2800_init_bbp_3593(rt2x00dev);
+ return;
++ case RT3883:
++ rt2800_init_bbp_3883(rt2x00dev);
++ return;
+ case RT5390:
+ case RT5392:
+ rt2800_init_bbp_53xx(rt2x00dev);
diff --git a/package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch b/package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch
new file mode 100644
index 0000000..0fec3cd
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch
@@ -0,0 +1,178 @@
+From 99c659cf345640fd0f733cbcaf4583cc2c868ec0 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Mon, 29 Apr 2013 13:21:48 +0200
+Subject: [PATCH] rt2x00: rt2800lib: add RFCSR initialization for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800.h | 1 +
+ drivers/net/wireless/rt2x00/rt2800lib.c | 141 +++++++++++++++++++++++++++++++
+ 2 files changed, 142 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -2171,6 +2171,7 @@ struct mac_iveiv_entry {
+ /*
+ * RFCSR 2:
+ */
++#define RFCSR2_RESCAL_BP FIELD8(0x40)
+ #define RFCSR2_RESCAL_EN FIELD8(0x80)
+
+ /*
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -6819,6 +6819,144 @@ static void rt2800_init_rfcsr_3593(struc
+ /* TODO: enable stream mode support */
+ }
+
++static void rt2800_init_rfcsr_3883(struct rt2x00_dev *rt2x00dev)
++{
++ u8 rfcsr;
++
++ /* TODO: get the actual ECO value from the SoC */
++ const unsigned int eco = 5;
++
++ rt2800_rf_init_calibration(rt2x00dev, 2);
++
++ rt2800_rfcsr_write(rt2x00dev, 0, 0xe0);
++ rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
++ rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
++ rt2800_rfcsr_write(rt2x00dev, 3, 0x20);
++ rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 8, 0x5b);
++ rt2800_rfcsr_write(rt2x00dev, 9, 0x08);
++ rt2800_rfcsr_write(rt2x00dev, 10, 0xd3);
++ rt2800_rfcsr_write(rt2x00dev, 11, 0x48);
++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a);
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
++ rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
++
++ /* RFCSR 17 will be initialized later based on the
++ * frequency offset stored in the EEPROM
++ */
++
++ rt2800_rfcsr_write(rt2x00dev, 18, 0x40);
++ 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, 0xc0);
++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 29, 0x00);
++ 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, 0x20);
++ rt2800_rfcsr_write(rt2x00dev, 35, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 37, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 38, 0x86);
++ rt2800_rfcsr_write(rt2x00dev, 39, 0x23);
++ rt2800_rfcsr_write(rt2x00dev, 40, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 41, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 42, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 44, 0x93);
++ rt2800_rfcsr_write(rt2x00dev, 45, 0xbb);
++ rt2800_rfcsr_write(rt2x00dev, 46, 0x60);
++ rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 48, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 49, 0x8e);
++ rt2800_rfcsr_write(rt2x00dev, 50, 0x86);
++ rt2800_rfcsr_write(rt2x00dev, 51, 0x51);
++ rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
++ rt2800_rfcsr_write(rt2x00dev, 53, 0x76);
++ rt2800_rfcsr_write(rt2x00dev, 54, 0x76);
++ rt2800_rfcsr_write(rt2x00dev, 55, 0x76);
++ rt2800_rfcsr_write(rt2x00dev, 56, 0xdb);
++ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e);
++ rt2800_rfcsr_write(rt2x00dev, 58, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
++
++ /* TODO: rx filter calibration? */
++
++ rt2800_bbp_write(rt2x00dev, 137, 0x0f);
++
++ rt2800_bbp_write(rt2x00dev, 163, 0x9d);
++
++ rt2800_bbp_write(rt2x00dev, 105, 0x05);
++
++ rt2800_bbp_write(rt2x00dev, 179, 0x02);
++ rt2800_bbp_write(rt2x00dev, 180, 0x00);
++ rt2800_bbp_write(rt2x00dev, 182, 0x40);
++ rt2800_bbp_write(rt2x00dev, 180, 0x01);
++ rt2800_bbp_write(rt2x00dev, 182, 0x9c);
++
++ rt2800_bbp_write(rt2x00dev, 179, 0x00);
++
++ rt2800_bbp_write(rt2x00dev, 142, 0x04);
++ rt2800_bbp_write(rt2x00dev, 143, 0x3b);
++ rt2800_bbp_write(rt2x00dev, 142, 0x06);
++ rt2800_bbp_write(rt2x00dev, 143, 0xa0);
++ rt2800_bbp_write(rt2x00dev, 142, 0x07);
++ rt2800_bbp_write(rt2x00dev, 143, 0xa1);
++ rt2800_bbp_write(rt2x00dev, 142, 0x08);
++ rt2800_bbp_write(rt2x00dev, 143, 0xa2);
++ rt2800_bbp_write(rt2x00dev, 148, 0xc8);
++
++ if (eco == 5) {
++ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8);
++ rt2800_rfcsr_write(rt2x00dev, 33, 0x32);
++ }
++
++ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_BP, 0);
++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
++ msleep(1);
++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0);
++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
++ rfcsr |= 0xc0;
++ rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
++ rfcsr |= 0x20;
++ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 46, &rfcsr);
++ rfcsr |= 0x20;
++ rt2800_rfcsr_write(rt2x00dev, 46, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr);
++ rfcsr &= ~0xee;
++ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
++}
++
+ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
+ {
+ rt2800_rf_init_calibration(rt2x00dev, 2);
+@@ -7050,6 +7188,9 @@ static void rt2800_init_rfcsr(struct rt2
+ case RT3390:
+ rt2800_init_rfcsr_3390(rt2x00dev);
+ break;
++ case RT3883:
++ rt2800_init_rfcsr_3883(rt2x00dev);
++ break;
+ case RT3572:
+ rt2800_init_rfcsr_3572(rt2x00dev);
+ break;
diff --git a/package/kernel/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch b/package/kernel/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch
new file mode 100644
index 0000000..57af961
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch
@@ -0,0 +1,22 @@
+From 86022438ffeb1b87dfcd018bf477fdbb43076691 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Wed, 8 May 2013 19:35:33 +0200
+Subject: [PATCH] rt2x00: rt2800lib: use the extended EEPROM map for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -342,7 +342,8 @@ static unsigned int rt2800_eeprom_word_i
+ wiphy_name(rt2x00dev->hw->wiphy), word))
+ return 0;
+
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ map = rt2800_eeprom_map_ext;
+ else
+ map = rt2800_eeprom_map;
diff --git a/package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch b/package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch
new file mode 100644
index 0000000..c9d1e06
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch
@@ -0,0 +1,21 @@
+From 4cf5403f02fa65dc2207f61d223cffa9ae50e907 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Thu, 1 Aug 2013 14:48:21 +0200
+Subject: [PATCH] rt2x00: rt2800lib: force rf type to RF3853 on RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -7587,6 +7587,8 @@ static int rt2800_init_eeprom(struct rt2
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392))
+ rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
++ else if (rt2x00_rt(rt2x00dev, RT3883))
++ rf = RF3853;
+ else
+ rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
+
diff --git a/package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch b/package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch
new file mode 100644
index 0000000..12b9c33
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch
@@ -0,0 +1,136 @@
+From 269f19c848a2380db03a3f207cafb88e28d71c53 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 24 Mar 2013 19:26:28 +0100
+Subject: [PATCH] rt2x00: rt2800lib: add channel configuration code for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 72 +++++++++++++++++++++++++++++--
+ 1 file changed, 69 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -3405,6 +3405,36 @@ static char rt2800_txpower_to_dev(struct
+ return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
+ }
+
++static void rt3883_bbp_adjust(struct rt2x00_dev *rt2x00dev,
++ struct rf_channel *rf)
++{
++ u8 bbp;
++
++ bbp = (rf->channel > 14) ? 0x48 : 0x38;
++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp);
++
++ rt2800_bbp_write(rt2x00dev, 69, 0x12);
++
++ if (rf->channel <= 14) {
++ rt2800_bbp_write(rt2x00dev, 70, 0x0a);
++ } else {
++ /* Disable CCK packet detection */
++ rt2800_bbp_write(rt2x00dev, 70, 0x00);
++ }
++
++ rt2800_bbp_write(rt2x00dev, 73, 0x10);
++
++ if (rf->channel > 14) {
++ rt2800_bbp_write(rt2x00dev, 62, 0x1d);
++ rt2800_bbp_write(rt2x00dev, 63, 0x1d);
++ rt2800_bbp_write(rt2x00dev, 64, 0x1d);
++ } else {
++ rt2800_bbp_write(rt2x00dev, 62, 0x2d);
++ rt2800_bbp_write(rt2x00dev, 63, 0x2d);
++ rt2800_bbp_write(rt2x00dev, 64, 0x2d);
++ }
++}
++
+ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+@@ -3423,6 +3453,12 @@ static void rt2800_config_channel(struct
+ rt2800_txpower_to_dev(rt2x00dev, rf->channel,
+ info->default_power3);
+
++ switch (rt2x00dev->chip.rt) {
++ case RT3883:
++ rt3883_bbp_adjust(rt2x00dev, rf);
++ break;
++ }
++
+ switch (rt2x00dev->chip.rf) {
+ case RF2020:
+ case RF3020:
+@@ -3506,6 +3542,15 @@ static void rt2800_config_channel(struct
+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 77, 0x98);
++ } else if (rt2x00_rt(rt2x00dev, RT3883)) {
++ 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 (rt2x00dev->default_ant.rx_chain_num > 1)
++ rt2800_bbp_write(rt2x00dev, 86, 0x46);
++ else
++ rt2800_bbp_write(rt2x00dev, 86, 0);
+ } else {
+ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+@@ -3518,6 +3563,7 @@ static void rt2800_config_channel(struct
+ !rt2x00_rt(rt2x00dev, RT5392)) {
+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
+ rt2800_bbp_write(rt2x00dev, 82, 0x62);
++ rt2800_bbp_write(rt2x00dev, 82, 0x62);
+ rt2800_bbp_write(rt2x00dev, 75, 0x46);
+ } else {
+ if (rt2x00_rt(rt2x00dev, RT3593))
+@@ -3526,19 +3572,22 @@ static void rt2800_config_channel(struct
+ rt2800_bbp_write(rt2x00dev, 82, 0x84);
+ rt2800_bbp_write(rt2x00dev, 75, 0x50);
+ }
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ rt2800_bbp_write(rt2x00dev, 83, 0x8a);
+ }
+
+ } else {
+ if (rt2x00_rt(rt2x00dev, RT3572))
+ rt2800_bbp_write(rt2x00dev, 82, 0x94);
+- else if (rt2x00_rt(rt2x00dev, RT3593))
++ else if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ rt2800_bbp_write(rt2x00dev, 82, 0x82);
+ else
+ rt2800_bbp_write(rt2x00dev, 82, 0xf2);
+
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ rt2800_bbp_write(rt2x00dev, 83, 0x9a);
+
+ if (rt2x00_has_cap_external_lna_a(rt2x00dev))
+@@ -3660,6 +3709,23 @@ static void rt2800_config_channel(struct
+
+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+
++ usleep_range(1000, 1500);
++ }
++
++ if (rt2x00_rt(rt2x00dev, RT3883)) {
++ if (!conf_is_ht40(conf))
++ rt2800_bbp_write(rt2x00dev, 105, 0x34);
++ else
++ rt2800_bbp_write(rt2x00dev, 105, 0x04);
++
++ /* AGC init */
++ if (rf->channel <= 14)
++ reg = 0x2e + rt2x00dev->lna_gain;
++ else
++ reg = 0x20 + ((rt2x00dev->lna_gain * 5) / 3);
++
++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
++
+ usleep_range(1000, 1500);
+ }
+
diff --git a/package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch b/package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch
new file mode 100644
index 0000000..3f40b4e
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch
@@ -0,0 +1,30 @@
+From e37d93abaabe3ab72b0332a18092acc162307274 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Mon, 30 Sep 2013 13:57:26 +0200
+Subject: [PATCH] rt2x00: rt2800lib: fix txpower_to_dev function for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -3392,13 +3392,15 @@ static char rt2800_txpower_to_dev(struct
+ unsigned int channel,
+ char txpower)
+ {
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC);
+
+ if (channel <= 14)
+ return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER);
+
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ return clamp_t(char, txpower, MIN_A_TXPOWER_3593,
+ MAX_A_TXPOWER_3593);
+ else
diff --git a/package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch b/package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch
new file mode 100644
index 0000000..52baeec
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch
@@ -0,0 +1,23 @@
+From c4d79e344bd580d85821390d49f92dced7d8e125 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 24 Mar 2013 19:26:29 +0100
+Subject: [PATCH] rt2x00: rt2800lib: use correct txpower calculation function
+ for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -4611,7 +4611,8 @@ static void rt2800_config_txpower(struct
+ struct ieee80211_channel *chan,
+ int power_level)
+ {
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level);
+ else
+ rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level);
diff --git a/package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch b/package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch
new file mode 100644
index 0000000..b9dafc6
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch
@@ -0,0 +1,33 @@
+From caea0671cd8fd9ade4f5969cbe0ee545e94ae105 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sat, 24 Aug 2013 11:49:55 +0200
+Subject: [PATCH] rt2x00: rt2800lib: hardcode txmixer gain values to zero for
+ RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -7469,7 +7469,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
+ {
+ u16 word;
+
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ return 0;
+
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
+@@ -7483,7 +7484,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
+ {
+ u16 word;
+
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ return 0;
+
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
diff --git a/package/kernel/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch b/package/kernel/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch
new file mode 100644
index 0000000..53435aa
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch
@@ -0,0 +1,20 @@
+From 11c40fb47c4a4dd6ad060c2ae127ced89ffb9fe1 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Thu, 18 Apr 2013 14:33:33 +0200
+Subject: [PATCH] rt2x00: rt2800lib: use correct [RT]XWI size for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -558,6 +558,7 @@ void rt2800_get_txwi_rxwi_size(struct rt
+ {
+ switch (rt2x00dev->chip.rt) {
+ case RT3593:
++ case RT3883:
+ *txwi_size = TXWI_DESC_SIZE_4WORDS;
+ *rxwi_size = RXWI_DESC_SIZE_5WORDS;
+ break;
diff --git a/package/kernel/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch b/package/kernel/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch
new file mode 100644
index 0000000..08f3f88
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch
@@ -0,0 +1,22 @@
+From b403bdfa00665ce6b53583bdb837ffad0b91c09f Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 24 Mar 2013 19:26:29 +0100
+Subject: [PATCH] rt2x00: rt2800lib: use correct beacon base for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -983,7 +983,8 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
+ static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
+ unsigned int index)
+ {
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ return HW_BEACON_BASE_HIGH(index);
+
+ return HW_BEACON_BASE(index);
diff --git a/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch b/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch
new file mode 100644
index 0000000..f09f803
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch
@@ -0,0 +1,22 @@
+From 74b7eaf75fc6eb86292056ef705e543f9cd6086b Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 18 Aug 2013 09:57:58 +0200
+Subject: [PATCH] rt2x00: rt2800lib: use correct beacon count for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -8402,7 +8402,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+ if (rt2x00_rt(rt2x00dev, RT3593))
+ __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
+
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ drv_data->hw_beacon_count = 16;
+ else
+ drv_data->hw_beacon_count = 8;
diff --git a/package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch b/package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch
new file mode 100644
index 0000000..f7d23fc
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch
@@ -0,0 +1,22 @@
+From fa5ad9c025610c22048add2f0ad03f62b6ca1e74 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Mon, 30 Sep 2013 16:53:33 +0200
+Subject: [PATCH] rt2x00: rt2800lib: fix antenna configuration for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -1937,7 +1937,8 @@ void rt2800_config_ant(struct rt2x00_dev
+ rt2800_bbp_write(rt2x00dev, 3, r3);
+ rt2800_bbp_write(rt2x00dev, 1, r1);
+
+- if (rt2x00_rt(rt2x00dev, RT3593)) {
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883)) {
+ if (ant->rx_chain_num == 1)
+ rt2800_bbp_write(rt2x00dev, 86, 0x00);
+ else
diff --git a/package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch b/package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch
new file mode 100644
index 0000000..4da750e
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch
@@ -0,0 +1,32 @@
+From 6d668fef3a1baa60bdd715ee062ddb6333d2647c Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Mon, 30 Sep 2013 16:58:23 +0200
+Subject: [PATCH] rt2x00: rt2800lib: fix LNA gain configuration for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -1960,7 +1960,8 @@ static void rt2800_config_lna_gain(struc
+ rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
+ } else if (libconf->rf.channel <= 128) {
+- if (rt2x00_rt(rt2x00dev, RT3593)) {
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883)) {
+ rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom,
+ EEPROM_EXT_LNA2_A1);
+@@ -1970,7 +1971,8 @@ static void rt2800_config_lna_gain(struc
+ EEPROM_RSSI_BG2_LNA_A1);
+ }
+ } else {
+- if (rt2x00_rt(rt2x00dev, RT3593)) {
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883)) {
+ rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom,
+ EEPROM_EXT_LNA2_A2);
diff --git a/package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch b/package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch
new file mode 100644
index 0000000..628b237
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch
@@ -0,0 +1,44 @@
+From c49b2d829aa1c816a46a577cdec6d2ff14d9f06e Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Tue, 1 Oct 2013 15:40:08 +0200
+Subject: [PATCH] rt2x00: rt2800lib: fix VGC setup for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -4811,7 +4811,8 @@ static u8 rt2800_get_default_vgc(struct
+ else
+ vgc = 0x2e + rt2x00dev->lna_gain;
+ } else { /* 5GHZ band */
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3;
+ else if (rt2x00_rt(rt2x00dev, RT5592))
+ vgc = 0x24 + (2 * rt2x00dev->lna_gain);
+@@ -4831,7 +4832,8 @@ static inline void rt2800_set_vgc(struct
+ {
+ if (qual->vgc_level != vgc_level) {
+ if (rt2x00_rt(rt2x00dev, RT3572) ||
+- rt2x00_rt(rt2x00dev, RT3593)) {
++ rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883)) {
+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
+ vgc_level);
+ } else if (rt2x00_rt(rt2x00dev, RT5592)) {
+@@ -4878,6 +4880,11 @@ void rt2800_link_tuner(struct rt2x00_dev
+ }
+ break;
+
++ case RT3883:
++ if (qual->rssi > -65)
++ vgc += 0x10;
++ break;
++
+ case RT5592:
+ if (qual->rssi > -65)
+ vgc += 0x20;
diff --git a/package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch b/package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch
new file mode 100644
index 0000000..216b8b6
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch
@@ -0,0 +1,42 @@
+From 1616650aea676541d4dc8adc6f4219856d193c8b Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Tue, 1 Oct 2013 17:27:57 +0200
+Subject: [PATCH] rt2x00: rt2800lib: fix EEPROM LNA validation for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -7606,7 +7606,8 @@ static int rt2800_validate_eeprom(struct
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
+- if (!rt2x00_rt(rt2x00dev, RT3593)) {
++ if (!rt2x00_rt(rt2x00dev, RT3593) &&
++ !rt2x00_rt(rt2x00dev, RT3883)) {
+ if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
+ rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
+@@ -7626,7 +7627,8 @@ static int rt2800_validate_eeprom(struct
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
+- if (!rt2x00_rt(rt2x00dev, RT3593)) {
++ if (!rt2x00_rt(rt2x00dev, RT3593) &&
++ !rt2x00_rt(rt2x00dev, RT3883)) {
+ if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
+ rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
+@@ -7634,7 +7636,8 @@ static int rt2800_validate_eeprom(struct
+ }
+ rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
+
+- if (rt2x00_rt(rt2x00dev, RT3593)) {
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883)) {
+ rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &word);
+ if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 ||
+ rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff)
diff --git a/package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch b/package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch
new file mode 100644
index 0000000..515086f
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch
@@ -0,0 +1,22 @@
+From e3871034a0e7c8a95152dc3eafbcc4535398cbdc Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Wed, 2 Oct 2013 10:11:59 +0200
+Subject: [PATCH] rt2x00: rt2800lib: fix txpower compensation for RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -3981,6 +3981,9 @@ static u8 rt2800_compensate_txpower(stru
+ if (rt2x00_rt(rt2x00dev, RT3593))
+ return min_t(u8, txpower, 0xc);
+
++ if (rt2x00_rt(rt2x00dev, RT3883))
++ return min_t(u8, txpower, 0xf);
++
+ if (rt2x00_has_cap_power_limit(rt2x00dev)) {
+ /*
+ * Check if eirp txpower exceed txpower_limit.
diff --git a/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch b/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch
new file mode 100644
index 0000000..77e3f1b
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch
@@ -0,0 +1,23 @@
+From f6734ec72da936989a8ce4186b3ede28fbc47836 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 18 Aug 2013 21:57:34 +0200
+Subject: [PATCH] rt2x00: rt2800lib: enable RT2800_HAS_HIGH_SHARED_MEM for
+ RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -8415,7 +8415,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+ if (retval)
+ return retval;
+
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
+
+ if (rt2x00_rt(rt2x00dev, RT3593) ||
diff --git a/package/kernel/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch b/package/kernel/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch
new file mode 100644
index 0000000..dc06e6a
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch
@@ -0,0 +1,22 @@
+From f1acfc2f397e86548ae1b479c198d4bef57050f6 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 29 Sep 2013 18:10:34 +0200
+Subject: [PATCH] rt2x00: rt2800lib: use high memory for beacons on RT3883
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -97,7 +97,8 @@ static inline void rt2800_shared_mem_sel
+
+ static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev)
+ {
+- if (rt2x00_rt(rt2x00dev, RT3593))
++ if (rt2x00_rt(rt2x00dev, RT3593) ||
++ rt2x00_rt(rt2x00dev, RT3883))
+ return true;
+
+ return false;
diff --git a/package/kernel/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch b/package/kernel/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch
new file mode 100644
index 0000000..71f7bba
--- /dev/null
+++ b/package/kernel/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch
@@ -0,0 +1,136 @@
+From 5e67d4f8a46d19748b501c2ef86de3f50d3cfd51 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 24 Mar 2013 19:26:27 +0100
+Subject: [PATCH] rt2x00: rt2800mmio: add a workaround for spurious
+ TX_FIFO_STATUS interrupts
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/rt2x00/rt2800mmio.c | 72 +++++++++++++++++++++++++-----
+ drivers/net/wireless/rt2x00/rt2x00.h | 5 +++
+ 2 files changed, 65 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800mmio.c
++++ b/drivers/net/wireless/rt2x00/rt2800mmio.c
+@@ -415,9 +415,9 @@ void rt2800mmio_autowake_tasklet(unsigne
+ }
+ EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet);
+
+-static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
++static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev,
++ u32 status)
+ {
+- u32 status;
+ int i;
+
+ /*
+@@ -438,29 +438,77 @@ static void rt2800mmio_txstatus_interrup
+ * Since we have only one producer and one consumer we don't
+ * need to lock the kfifo.
+ */
+- for (i = 0; i < rt2x00dev->tx->limit; i++) {
+- rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status);
+-
+- if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
+- break;
+-
++ i = 0;
++ do {
+ if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) {
+- rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n");
++ rt2x00_warn(rt2x00dev,
++ "TX status FIFO overrun, drop TX status report\n");
+ break;
+ }
+- }
++
++ if (++i >= rt2x00dev->tx->limit)
++ break;
++
++ rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status);
++ } while (rt2x00_get_field32(status, TX_STA_FIFO_VALID));
+
+ /* Schedule the tasklet for processing the tx status. */
+ tasklet_schedule(&rt2x00dev->txstatus_tasklet);
+ }
+
++#define RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES 4
++
++static bool rt2800mmio_txstatus_is_spurious(struct rt2x00_dev *rt2x00dev,
++ u32 txstatus)
++{
++ if (likely(rt2x00_get_field32(txstatus, TX_STA_FIFO_VALID))) {
++ rt2x00dev->txstatus_irq_retries = 0;
++ return false;
++ }
++
++ rt2x00dev->txstatus_irq_retries++;
++
++ /* Ensure that we don't go into an infinite IRQ loop. */
++ if (rt2x00dev->txstatus_irq_retries >=
++ RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES) {
++ rt2x00_warn(rt2x00dev,
++ "%u spurious TX_FIFO_STATUS interrupt(s)\n",
++ rt2x00dev->txstatus_irq_retries);
++ rt2x00dev->txstatus_irq_retries = 0;
++ return false;
++ }
++
++ return true;
++}
++
+ irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance)
+ {
+ struct rt2x00_dev *rt2x00dev = dev_instance;
+ u32 reg, mask;
++ u32 txstatus = 0;
+
+- /* Read status and ACK all interrupts */
++ /* Read status */
+ rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
++
++ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) {
++ /* Due to unknown reason the hardware generates a
++ * TX_FIFO_STATUS interrupt before the TX_STA_FIFO
++ * register contain valid data. Read the TX status
++ * here to see if we have to process the actual
++ * request.
++ */
++ rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &txstatus);
++ if (rt2800mmio_txstatus_is_spurious(rt2x00dev, txstatus)) {
++ /* Remove the TX_FIFO_STATUS bit so it won't be
++ * processed in this turn. The hardware will
++ * generate another IRQ for us.
++ */
++ rt2x00_set_field32(&reg,
++ INT_SOURCE_CSR_TX_FIFO_STATUS, 0);
++ }
++ }
++
++ /* ACK interrupts */
+ rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
+
+ if (!reg)
+@@ -477,7 +525,7 @@ irqreturn_t rt2800mmio_interrupt(int irq
+ mask = ~reg;
+
+ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) {
+- rt2800mmio_txstatus_interrupt(rt2x00dev);
++ rt2800mmio_txstatus_interrupt(rt2x00dev, txstatus);
+ /*
+ * Never disable the TX_FIFO_STATUS interrupt.
+ */
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -989,6 +989,11 @@ struct rt2x00_dev {
+ int rf_channel;
+
+ /*
++ * Counter for tx status irq retries (rt2800pci).
++ */
++ unsigned int txstatus_irq_retries;
++
++ /*
+ * Protect the interrupt mask register.
+ */
+ spinlock_t irqmask_lock;
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 0000000..08c8fa6
--- /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
+@@ -94,8 +94,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 0000000..8c71075
--- /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
+@@ -38,6 +38,7 @@
+ #include <linux/kfifo.h>
+ #include <linux/hrtimer.h>
+ #include <linux/average.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 0000000..1255d75
--- /dev/null
+++ b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
@@ -0,0 +1,301 @@
+--- a/.local-symbols
++++ b/.local-symbols
+@@ -314,6 +314,7 @@ RT2X00_LIB_FIRMWARE=
+ RT2X00_LIB_CRYPTO=
+ RT2X00_LIB_LEDS=
+ RT2X00_LIB_DEBUGFS=
++RT2X00_LIB_EEPROM=
+ RT2X00_DEBUG=
+ WL_MEDIATEK=
+ MT7601U=
+--- a/drivers/net/wireless/rt2x00/Kconfig
++++ b/drivers/net/wireless/rt2x00/Kconfig
+@@ -69,6 +69,7 @@ config RT2800PCI
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_PCI
+ select RT2X00_LIB_FIRMWARE
++ select RT2X00_LIB_EEPROM
+ select RT2X00_LIB_CRYPTO
+ depends on CRC_CCITT
+ depends on EEPROM_93CX6
+@@ -215,6 +216,7 @@ config RT2800SOC
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_CRYPTO
+ select RT2X00_LIB_FIRMWARE
++ select RT2X00_LIB_EEPROM
+ select RT2800_LIB
+ select RT2800_LIB_MMIO
+ ---help---
+@@ -265,6 +267,9 @@ config RT2X00_LIB_FIRMWARE
+ config RT2X00_LIB_CRYPTO
+ bool
+
++config RT2X00_LIB_EEPROM
++ boolean
++
+ config RT2X00_LIB_LEDS
+ bool
+ default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n)
+--- 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/rt2800lib.h
++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
+@@ -46,6 +46,8 @@ struct rt2800_drv_data {
+ } shmem_lock;
+ };
+
++#include "rt2800.h"
++
+ struct rt2800_ops {
+ void (*register_read)(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset, u32 *value);
+@@ -179,6 +181,15 @@ static inline int rt2800_read_eeprom(str
+ {
+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
+
++ if (rt2x00dev->eeprom_file) {
++ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data,
++ EEPROM_SIZE);
++ return 0;
++ }
++
++ if (!rt2800ops->read_eeprom)
++ return -EINVAL;
++
+ return rt2800ops->read_eeprom(rt2x00dev);
+ }
+
+--- a/drivers/net/wireless/rt2x00/rt2800soc.c
++++ b/drivers/net/wireless/rt2x00/rt2800soc.c
+@@ -102,19 +102,6 @@ static int rt2800soc_set_device_state(st
+ return retval;
+ }
+
+-static int rt2800soc_read_eeprom(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);
+- return 0;
+-}
+-
+ /* Firmware functions */
+ static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev)
+ {
+@@ -178,7 +165,6 @@ static const struct rt2800_ops rt2800soc
+ .register_multiread = rt2x00mmio_register_multiread,
+ .register_multiwrite = rt2x00mmio_register_multiwrite,
+ .regbusy_read = rt2x00mmio_regbusy_read,
+- .read_eeprom = rt2800soc_read_eeprom,
+ .hwcrypt_disabled = rt2800soc_hwcrypt_disabled,
+ .drv_write_firmware = rt2800soc_write_firmware,
+ .drv_init_registers = rt2800mmio_init_registers,
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -697,6 +697,7 @@ enum rt2x00_capability_flags {
+ REQUIRE_HT_TX_DESC,
+ REQUIRE_PS_AUTOWAKE,
+ REQUIRE_DELAYED_RFKILL,
++ REQUIRE_EEPROM_FILE,
+
+ /*
+ * Capabilities
+@@ -966,6 +967,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/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -1334,6 +1334,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.
+ */
+@@ -1474,6 +1478,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
+ * Free the driver data.
+ */
+ kfree(rt2x00dev->drv_data);
++
++ /*
++ * Free EEPROM image.
++ */
++ rt2x00lib_free_eeprom_file(rt2x00dev);
+ }
+ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
+
+--- /dev/null
++++ b/drivers/net/wireless/rt2x00/rt2x00eeprom.c
+@@ -0,0 +1,111 @@
++/*
++ 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 const char *
++rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
++
++ if (pdata && pdata->eeprom_file_name)
++ return pdata->eeprom_file_name;
++
++ return NULL
++}
++
++static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev)
++{
++ const struct firmware *ee;
++ const char *ee_name;
++ int retval;
++
++ ee_name = rt2x00lib_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 (!rt2x00lib_get_eeprom_file_name(rt2x00dev))
++ return 0;
++
++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags);
++
++ 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/rt2x00lib.h
++++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
+@@ -320,6 +320,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/rt2x00soc.c
++++ b/drivers/net/wireless/rt2x00/rt2x00soc.c
+@@ -92,6 +92,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);
+
diff --git a/package/kernel/mac80211/patches/604-rt2x00-of_load_eeprom_filename.patch b/package/kernel/mac80211/patches/604-rt2x00-of_load_eeprom_filename.patch
new file mode 100644
index 0000000..4bc6f37
--- /dev/null
+++ b/package/kernel/mac80211/patches/604-rt2x00-of_load_eeprom_filename.patch
@@ -0,0 +1,33 @@
+--- a/drivers/net/wireless/rt2x00/rt2x00eeprom.c
++++ b/drivers/net/wireless/rt2x00/rt2x00eeprom.c
+@@ -26,6 +26,7 @@
+
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+
+ #include "rt2x00.h"
+ #include "rt2x00lib.h"
+@@ -34,11 +35,21 @@ static const char *
+ rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
+ {
+ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
++#ifdef CONFIG_OF
++ struct device_node *np;
++ const char *eep;
++#endif
+
+ if (pdata && pdata->eeprom_file_name)
+ return pdata->eeprom_file_name;
+
+- return NULL
++#ifdef CONFIG_OF
++ np = rt2x00dev->dev->of_node;
++ if (np && of_property_read_string(np, "ralink,eeprom", &eep) == 0)
++ return eep;
++#endif
++
++ return NULL;
+ }
+
+ static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev)
diff --git a/package/kernel/mac80211/patches/605-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch b/package/kernel/mac80211/patches/605-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch
new file mode 100644
index 0000000..75f0415
--- /dev/null
+++ b/package/kernel/mac80211/patches/605-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch
@@ -0,0 +1,101 @@
+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
+@@ -219,6 +219,7 @@ config RT2800SOC
+ select RT2X00_LIB_EEPROM
+ select RT2800_LIB
+ select RT2800_LIB_MMIO
++ select MTD if SOC_RT288X || SOC_RT305X
+ ---help---
+ This adds support for Ralink WiSoC devices.
+ Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352.
+--- a/drivers/net/wireless/rt2x00/rt2x00eeprom.c
++++ b/drivers/net/wireless/rt2x00/rt2x00eeprom.c
+@@ -26,11 +26,66 @@
+
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
+ #include <linux/of.h>
+
+ #include "rt2x00.h"
+ #include "rt2x00lib.h"
+
++static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
++{
++ int ret = -EINVAL;
++#ifdef CONFIG_OF
++ static struct firmware mtd_fw;
++ struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL;
++ size_t retlen, len = rt2x00dev->ops->eeprom_size;
++ int 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;
++ }
++#endif
++
++ return ret;
++}
++
+ static const char *
+ rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
+ {
+@@ -58,6 +113,9 @@ static int rt2x00lib_request_eeprom_file
+ const char *ee_name;
+ int retval;
+
++ if (!rt2800lib_read_eeprom_mtd(rt2x00dev))
++ return 0;
++
+ ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev);
+ if (!ee_name) {
+ rt2x00_err(rt2x00dev,
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 0000000..76269f2
--- /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
+@@ -940,6 +940,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
+@@ -405,6 +405,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 0000000..0177c80
--- /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
+@@ -931,6 +931,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
+@@ -1412,6 +1412,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
+@@ -2390,6 +2390,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);
+@@ -2410,7 +2411,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/609-rt2x00-allow_disabling_bands_through_dts.patch b/package/kernel/mac80211/patches/609-rt2x00-allow_disabling_bands_through_dts.patch
new file mode 100644
index 0000000..63a8641
--- /dev/null
+++ b/package/kernel/mac80211/patches/609-rt2x00-allow_disabling_bands_through_dts.patch
@@ -0,0 +1,27 @@
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -26,6 +26,7 @@
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/log2.h>
++#include <linux/of.h>
+
+ #include "rt2x00.h"
+ #include "rt2x00lib.h"
+@@ -951,6 +952,16 @@ static int rt2x00lib_probe_hw_modes(stru
+ struct ieee80211_rate *rates;
+ unsigned int num_rates;
+ unsigned int i;
++#ifdef CONFIG_OF
++ struct device_node *np = rt2x00dev->dev->of_node;
++ unsigned int enabled;
++ if (!of_property_read_u32(np, "ralink,2ghz",
++ &enabled) && !enabled)
++ spec->supported_bands &= ~SUPPORT_BAND_2GHZ;
++ if (!of_property_read_u32(np, "ralink,5ghz",
++ &enabled) && !enabled)
++ spec->supported_bands &= ~SUPPORT_BAND_5GHZ;
++#endif /* CONFIG_OF */
+
+ if (rt2x00dev->dev->platform_data) {
+ struct rt2x00_platform_data *pdata;
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 0000000..d6ea384
--- /dev/null
+++ b/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
@@ -0,0 +1,211 @@
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -3528,11 +3528,18 @@ static void rt2800_config_channel(struct
+ /*
+ * Change BBP settings
+ */
++
+ if (rt2x00_rt(rt2x00dev, RT3352)) {
++ 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, 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 if (rt2x00_rt(rt2x00dev, RT3593)) {
+ if (rf->channel > 14) {
+ /* Disable CCK Packet detection on 5GHz */
+@@ -6594,6 +6601,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);
+@@ -6629,15 +6642,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);
+@@ -6645,15 +6673,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);
+@@ -7674,6 +7707,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))
+ rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+@@ -7769,7 +7803,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);
+
+ /*
+@@ -7798,6 +7833,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
++ */
++ rt2800_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
+@@ -2335,6 +2335,12 @@ struct mac_iveiv_entry {
+ #define RFCSR36_RF_BS FIELD8(0x80)
+
+ /*
++ * 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)
+@@ -2346,6 +2352,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)
+@@ -2358,6 +2376,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)
+ /* bits for RT3593 */
+ #define RFCSR50_TX_LO1_EN FIELD8(0x20)
+@@ -2505,6 +2525,8 @@ enum rt2800_eeprom_word {
+ * 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_HW_RADIO FIELD16(0x0001)
+ #define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002)
+@@ -2521,6 +2543,8 @@ enum rt2800_eeprom_word {
+ #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
+@@ -717,6 +717,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 0000000..41a8294
--- /dev/null
+++ b/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
@@ -0,0 +1,106 @@
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -8185,6 +8185,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;
+@@ -8271,7 +8292,10 @@ static int rt2800_probe_hw_mode(struct r
+ case RF5390:
+ case RF5392:
+ spec->num_channels = 14;
+- spec->channels = rf_vals_3x;
++ if (spec->clk_is_20mhz)
++ spec->channels = rf_vals_xtal20mhz_3x;
++ else
++ spec->channels = rf_vals_3x;
+ break;
+
+ case RF3052:
+@@ -8455,6 +8479,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)
+ {
+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+@@ -8497,6 +8534,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
+@@ -400,6 +400,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;
+@@ -416,6 +417,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 0000000..1970efc
--- /dev/null
+++ b/package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
@@ -0,0 +1,33 @@
+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/rt2800soc.c
++++ b/drivers/net/wireless/rt2x00/rt2800soc.c
+@@ -237,10 +237,17 @@ static int rt2800soc_probe(struct platfo
+ return rt2x00soc_probe(pdev, &rt2800soc_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",
+ .mod_name = KBUILD_MODNAME,
++ .of_match_table = rt2880_wmac_match,
+ },
+ .probe = rt2800soc_probe,
+ .remove = rt2x00soc_remove,
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 0000000..9f11862
--- /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
+@@ -36,6 +36,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
++#include <linux/clk.h>
+
+ #include "rt2x00.h"
+ #include "rt2800lib.h"
+@@ -8481,13 +8482,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 0000000..9679d71
--- /dev/null
+++ b/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch
@@ -0,0 +1,276 @@
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -74,6 +74,7 @@
+ #define RF3070 0x3070
+ #define RF3290 0x3290
+ #define RF3853 0x3853
++#define RF5350 0x5350
+ #define RF5360 0x5360
+ #define RF5362 0x5362
+ #define RF5370 0x5370
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -3014,6 +3014,13 @@ static void rt2800_config_channel_rf53xx
+
+ rt2800_rfcsr_write(rt2x00dev, 59,
+ r59_non_bt[idx]);
++ } else 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]);
+ }
+ }
+ }
+@@ -3492,6 +3499,7 @@ static void rt2800_config_channel(struct
+ rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info);
+ break;
+ case RF3070:
++ case RF5350:
+ case RF5360:
+ case RF5362:
+ case RF5370:
+@@ -3510,6 +3518,7 @@ static void rt2800_config_channel(struct
+ if (rt2x00_rf(rt2x00dev, RF3070) ||
+ rt2x00_rf(rt2x00dev, RF3290) ||
+ rt2x00_rf(rt2x00dev, RF3322) ||
++ rt2x00_rf(rt2x00dev, RF5350) ||
+ rt2x00_rf(rt2x00dev, RF5360) ||
+ rt2x00_rf(rt2x00dev, RF5362) ||
+ rt2x00_rf(rt2x00dev, RF5370) ||
+@@ -3788,7 +3797,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);
+@@ -4674,6 +4684,7 @@ void rt2800_vco_calibration(struct rt2x0
+ case RF3070:
+ case RF3290:
+ case RF3853:
++ case RF5350:
+ case RF5360:
+ case RF5362:
+ case RF5370:
+@@ -5087,6 +5098,8 @@ static int rt2800_init_registers(struct
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
++ } else if (rt2x00_rt(rt2x00dev, RT5350)) {
++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+ } else {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+@@ -5742,9 +5755,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);
+
+@@ -5758,9 +5775,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);
+
+@@ -5785,6 +5806,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)
+@@ -6126,6 +6154,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:
+@@ -7077,6 +7106,76 @@ static void rt2800_init_rfcsr_3883(struc
+ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
+ }
+
++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);
+@@ -7317,6 +7416,9 @@ static void rt2800_init_rfcsr(struct rt2
+ case RT3593:
+ rt2800_init_rfcsr_3593(rt2x00dev);
+ break;
++ case RT5350:
++ rt2800_init_rfcsr_5350(rt2x00dev);
++ break;
+ case RT5390:
+ rt2800_init_rfcsr_5390(rt2x00dev);
+ break;
+@@ -7576,6 +7678,12 @@ static int rt2800_validate_eeprom(struct
+ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
+ rt2800_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)) {
+ /*
+@@ -7714,6 +7822,8 @@ static int rt2800_init_eeprom(struct rt2
+ rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+ else if (rt2x00_rt(rt2x00dev, RT3883))
+ rf = RF3853;
++ else if (rt2x00_rt(rt2x00dev, RT5350))
++ rf = RF5350;
+ else
+ rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
+
+@@ -7733,6 +7843,7 @@ static int rt2800_init_eeprom(struct rt2
+ case RF3320:
+ case RF3322:
+ case RF3853:
++ case RF5350:
+ case RF5360:
+ case RF5362:
+ case RF5370:
+@@ -8286,6 +8397,7 @@ static int rt2800_probe_hw_mode(struct r
+ case RF3290:
+ case RF3320:
+ case RF3322:
++ case RF5350:
+ case RF5360:
+ case RF5362:
+ case RF5370:
+@@ -8425,6 +8537,7 @@ static int rt2800_probe_hw_mode(struct r
+ case RF3070:
+ case RF3290:
+ case RF3853:
++ case RF5350:
+ case RF5360:
+ case RF5362:
+ case RF5370:
+@@ -8465,6 +8578,7 @@ static int rt2800_probe_rt(struct rt2x00
+ case RT3572:
+ case RT3593:
+ case RT3883:
++ case RT5350:
+ case RT5390:
+ case RT5392:
+ case RT5592:
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -169,6 +169,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/619-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
new file mode 100644
index 0000000..b085c5e
--- /dev/null
+++ b/package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
@@ -0,0 +1,40 @@
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -37,6 +37,7 @@
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/clk.h>
++#include <linux/of.h>
+
+ #include "rt2x00.h"
+ #include "rt2800lib.h"
+@@ -7933,6 +7934,17 @@ static int rt2800_init_eeprom(struct rt2
+ rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
+ rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
+
++ {
++ struct device_node *np = rt2x00dev->dev->of_node;
++ unsigned int led_polarity;
++
++ /* Allow overriding polarity from OF */
++ if (!of_property_read_u32(np, "ralink,led-polarity",
++ &led_polarity))
++ rt2x00_set_field16(&eeprom, EEPROM_FREQ_LED_POLARITY,
++ led_polarity);
++ }
++
+ rt2x00dev->led_mcu_reg = eeprom;
+ #endif /* CPTCFG_RT2X00_LIB_LEDS */
+
+--- a/drivers/net/wireless/rt2x00/rt2x00leds.c
++++ b/drivers/net/wireless/rt2x00/rt2x00leds.c
+@@ -109,6 +109,9 @@ static int rt2x00leds_register_led(struc
+ led->led_dev.name = name;
+ led->led_dev.brightness = LED_OFF;
+
++ if (rt2x00_is_soc(rt2x00dev))
++ led->led_dev.brightness_set(&led->led_dev, LED_OFF);
++
+ retval = led_classdev_register(device, &led->led_dev);
+ if (retval) {
+ rt2x00_err(rt2x00dev, "Failed to register led handler\n");
diff --git a/package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch
new file mode 100644
index 0000000..2dbfd10
--- /dev/null
+++ b/package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch
@@ -0,0 +1,11 @@
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -1283,7 +1283,7 @@ static inline void rt2x00lib_set_if_comb
+ */
+ if_limit = &rt2x00dev->if_limits_ap;
+ if_limit->max = rt2x00dev->ops->max_ap_intf;
+- if_limit->types = BIT(NL80211_IFTYPE_AP);
++ if_limit->types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_STATION);
+ #ifdef CPTCFG_MAC80211_MESH
+ if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT);
+ #endif
diff --git a/package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch b/package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
new file mode 100644
index 0000000..259cb1f
--- /dev/null
+++ b/package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
@@ -0,0 +1,15 @@
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -7817,10 +7817,11 @@ 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))
+ rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
++ else if (rt2x00_rt(rt2x00dev, RT3352))
++ rf = RF3322;
+ else if (rt2x00_rt(rt2x00dev, RT3883))
+ rf = RF3853;
+ else if (rt2x00_rt(rt2x00dev, RT5350))
diff --git a/package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch b/package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch
new file mode 100644
index 0000000..77d63fe
--- /dev/null
+++ b/package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch
@@ -0,0 +1,29 @@
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -2321,6 +2321,8 @@ struct mac_iveiv_entry {
+ #define RFCSR30_RX_H20M FIELD8(0x04)
+ #define RFCSR30_RX_VCM FIELD8(0x18)
+ #define RFCSR30_RF_CALIBRATION FIELD8(0x80)
++#define RF3322_RFCSR30_TX_H20M FIELD8(0x01)
++#define RF3322_RFCSR30_RX_H20M FIELD8(0x02)
+
+ /*
+ * RFCSR 31:
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -3527,8 +3527,13 @@ static void rt2800_config_channel(struct
+ rt2x00_rf(rt2x00dev, RF5390) ||
+ rt2x00_rf(rt2x00dev, RF5392)) {
+ rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+- rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0);
+- rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0);
++ if(rt2x00_rf(rt2x00dev, RF3322)) {
++ rt2x00_set_field8(&rfcsr, RF3322_RFCSR30_TX_H20M, conf_is_ht40(conf));
++ rt2x00_set_field8(&rfcsr, RF3322_RFCSR30_RX_H20M, conf_is_ht40(conf));
++ } else {
++ rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, conf_is_ht40(conf));
++ rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, conf_is_ht40(conf));
++ }
+ rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
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 0000000..9903aa5
--- /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
+@@ -5679,6 +5679,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
+ MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
+
+ static const struct pci_device_id 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/801-libertas-configure-sysfs-links.patch b/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch
new file mode 100644
index 0000000..3b8b756
--- /dev/null
+++ b/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch
@@ -0,0 +1,21 @@
+--- a/drivers/net/wireless/libertas/cfg.c
++++ b/drivers/net/wireless/libertas/cfg.c
+@@ -2083,6 +2083,8 @@ struct wireless_dev *lbs_cfg_alloc(struc
+ goto err_wiphy_new;
+ }
+
++ set_wiphy_dev(wdev->wiphy, dev);
++
+ lbs_deb_leave(LBS_DEB_CFG80211);
+ return wdev;
+
+--- a/drivers/net/wireless/libertas/main.c
++++ b/drivers/net/wireless/libertas/main.c
+@@ -987,6 +987,7 @@ struct lbs_private *lbs_add_card(void *c
+ goto err_adapter;
+ }
+
++ dev_net_set(dev, wiphy_net(wdev->wiphy));
+ dev->ieee80211_ptr = wdev;
+ dev->ml_priv = priv;
+ SET_NETDEV_DEV(dev, dmdev);
diff --git a/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch b/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch
new file mode 100644
index 0000000..dace56b
--- /dev/null
+++ b/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch
@@ -0,0 +1,11 @@
+--- a/drivers/net/wireless/libertas/cfg.c
++++ b/drivers/net/wireless/libertas/cfg.c
+@@ -2173,6 +2173,8 @@ int lbs_cfg_register(struct lbs_private
+ wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+ wdev->wiphy->reg_notifier = lbs_reg_notifier;
+
++ memcpy(wdev->wiphy->perm_addr, priv->current_addr, ETH_ALEN);
++
+ ret = wiphy_register(wdev->wiphy);
+ if (ret < 0)
+ pr_err("cannot register wiphy device\n");
diff --git a/package/kernel/mac80211/patches/805-b43-gpio-mask-module-option.patch b/package/kernel/mac80211/patches/805-b43-gpio-mask-module-option.patch
new file mode 100644
index 0000000..3993c6e
--- /dev/null
+++ b/package/kernel/mac80211/patches/805-b43-gpio-mask-module-option.patch
@@ -0,0 +1,37 @@
+--- a/drivers/net/wireless/b43/b43.h
++++ b/drivers/net/wireless/b43/b43.h
+@@ -839,6 +839,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,
+@@ -2883,10 +2888,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 0000000..d99f3ce
--- /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
+@@ -17,7 +17,7 @@ b43-$(CPTCFG_B43_PHY_AC) += phy_ac.o
+ b43-y += sysfs.o
+ b43-y += xmit.o
+ b43-y += dma.o
+-b43-y += pio.o
++b43-$(CPTCFG_B43_PIO) += pio.o
+ b43-y += rfkill.o
+ b43-y += ppr.o
+ b43-$(CPTCFG_B43_LEDS) += leds.o
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -2009,10 +2009,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 CPTCFG_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 CPTCFG_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 /* CPTCFG_B43_PIO */
+
+ #endif /* B43_PIO_H_ */
+--- a/drivers/net/wireless/b43/Kconfig
++++ b/drivers/net/wireless/b43/Kconfig
+@@ -118,7 +118,7 @@ config B43_BCMA_PIO
+ default y
+
+ config B43_PIO
+- bool
++ bool "Broadcom 43xx PIO support"
+ depends on B43 && B43_SSB
+ 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 0000000..4f06d8e
--- /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
+@@ -1649,7 +1649,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. */
+@@ -3301,8 +3301,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);
+@@ -4002,7 +4002,6 @@ static int b43_op_config(struct ieee8021
+ struct b43_wldev *dev = wl->current_dev;
+ struct b43_phy *phy = &dev->phy;
+ struct ieee80211_conf *conf = &hw->conf;
+- int antenna;
+ int err = 0;
+
+ mutex_lock(&wl->mutex);
+@@ -4045,11 +4044,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) {
+@@ -5210,6 +5207,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,
+@@ -5231,6 +5269,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.
+@@ -5539,6 +5579,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;
+@@ -5629,6 +5671,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
+@@ -840,6 +840,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/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 0000000..9c51ac6
--- /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 0000000..ab06b6e
--- /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
+@@ -2900,6 +2900,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/847-b43-always-take-overlapping-devs.patch b/package/kernel/mac80211/patches/847-b43-always-take-overlapping-devs.patch
new file mode 100644
index 0000000..9d1d419
--- /dev/null
+++ b/package/kernel/mac80211/patches/847-b43-always-take-overlapping-devs.patch
@@ -0,0 +1,11 @@
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -118,7 +118,7 @@ static int b43_modparam_pio = 0;
+ module_param_named(pio, b43_modparam_pio, int, 0644);
+ MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
+
+-static int modparam_allhwsupport = !IS_ENABLED(CPTCFG_BRCMSMAC);
++static int modparam_allhwsupport = 1;
+ module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
+ MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");
+
diff --git a/package/kernel/mac80211/patches/850-brcmsmac-remove-extra-regulation-restriction.patch b/package/kernel/mac80211/patches/850-brcmsmac-remove-extra-regulation-restriction.patch
new file mode 100644
index 0000000..185c427
--- /dev/null
+++ b/package/kernel/mac80211/patches/850-brcmsmac-remove-extra-regulation-restriction.patch
@@ -0,0 +1,27 @@
+--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+@@ -58,19 +58,12 @@
+ (((c) < 149) ? 3 : 4))))
+
+ #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_NO_IR)
++#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, 0)
+
+-#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \
+- NL80211_RRF_NO_IR)
+-#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \
+- NL80211_RRF_DFS | \
+- NL80211_RRF_NO_IR)
+-#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \
+- NL80211_RRF_DFS | \
+- NL80211_RRF_NO_IR)
+-#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \
+- NL80211_RRF_NO_IR)
++#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, 0)
++#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, 0)
++#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, 0)
++#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, 0)
+
+ static const struct ieee80211_regdomain brcms_regdom_x2 = {
+ .n_reg_rules = 6,
diff --git a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch
new file mode 100644
index 0000000..d60d3fa
--- /dev/null
+++ b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch
@@ -0,0 +1,97 @@
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Mon, 8 Jun 2015 16:11:40 +0200
+Subject: [PATCH] brcmfmac: register wiphy(s) during module_init
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is needed by OpenWrt which expects all PHYs to be created after
+module loads successfully.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
+@@ -1236,6 +1236,7 @@ static int __init brcmfmac_module_init(v
+ #endif
+ if (!schedule_work(&brcmf_driver_work))
+ return -EBUSY;
++ flush_work(&brcmf_driver_work);
+
+ return 0;
+ }
+--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
+@@ -420,6 +420,7 @@ struct brcmf_fw {
+ u16 bus_nr;
+ void (*done)(struct device *dev, const struct firmware *fw,
+ void *nvram_image, u32 nvram_len);
++ struct completion *completion;
+ };
+
+ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
+@@ -455,6 +456,8 @@ static void brcmf_fw_request_nvram_done(
+ goto fail;
+
+ fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length);
++ if (fwctx->completion)
++ complete(fwctx->completion);
+ kfree(fwctx);
+ return;
+
+@@ -462,6 +465,8 @@ fail:
+ brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
+ release_firmware(fwctx->code);
+ device_release_driver(fwctx->dev);
++ if (fwctx->completion)
++ complete(fwctx->completion);
+ kfree(fwctx);
+ }
+
+@@ -477,6 +482,8 @@ static void brcmf_fw_request_code_done(c
+ /* only requested code so done here */
+ if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) {
+ fwctx->done(fwctx->dev, fw, NULL, 0);
++ if (fwctx->completion)
++ complete(fwctx->completion);
+ kfree(fwctx);
+ return;
+ }
+@@ -494,6 +501,8 @@ static void brcmf_fw_request_code_done(c
+ fail:
+ brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
+ device_release_driver(fwctx->dev);
++ if (fwctx->completion)
++ complete(fwctx->completion);
+ kfree(fwctx);
+ }
+
+@@ -505,6 +514,8 @@ int brcmf_fw_get_firmwares_pcie(struct d
+ u16 domain_nr, u16 bus_nr)
+ {
+ struct brcmf_fw *fwctx;
++ struct completion completion;
++ int err;
+
+ brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
+ if (!fw_cb || !code)
+@@ -525,9 +536,17 @@ int brcmf_fw_get_firmwares_pcie(struct d
+ fwctx->domain_nr = domain_nr;
+ fwctx->bus_nr = bus_nr;
+
+- return request_firmware_nowait(THIS_MODULE, true, code, dev,
++ init_completion(&completion);
++ fwctx->completion = &completion;
++
++ err = request_firmware_nowait(THIS_MODULE, true, code, dev,
+ GFP_KERNEL, fwctx,
+ brcmf_fw_request_code_done);
++ if (!err)
++ wait_for_completion_timeout(fwctx->completion,
++ msecs_to_jiffies(5000));
++ fwctx->completion = NULL;
++ return err;
+ }
+
+ int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
diff --git a/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
new file mode 100644
index 0000000..43582f6
--- /dev/null
+++ b/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
@@ -0,0 +1,50 @@
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Thu, 9 Jul 2015 00:07:59 +0200
+Subject: [PATCH] brcmfmac: workaround bug with some inconsistent BSSes state
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+@@ -609,9 +609,37 @@ static struct wireless_dev *brcmf_cfg802
+ u32 *flags,
+ struct vif_params *params)
+ {
++ struct net_device *dev;
+ struct wireless_dev *wdev;
+ int err;
+
++ /*
++ * There is a bug with in-firmware BSS management. When adding virtual
++ * interface brcmfmac first tells firmware to create new BSS and then
++ * it creates new struct net_device.
++ *
++ * If creating/registering netdev(ice) fails, BSS remains in some bugged
++ * state. It conflicts with existing BSSes by overtaking their auth
++ * requests.
++ *
++ * It results in one BSS (addresss X) sending beacons and another BSS
++ * (address Y) replying to authentication requests. This makes interface
++ * unusable as AP.
++ *
++ * To workaround this bug we may try to guess if register_netdev(ice)
++ * will fail. The most obvious case is using interface name that already
++ * exists. This is actually quite likely with brcmfmac & some user space
++ * scripts as brcmfmac doesn't allow deleting virtual interfaces.
++ * So this bug can be triggered even by something trivial like:
++ * iw dev wlan0 delete
++ * iw phy phy0 interface add wlan0 type __ap
++ */
++ dev = dev_get_by_name(&init_net, name);
++ if (dev) {
++ dev_put(dev);
++ return ERR_PTR(-EEXIST);
++ }
++
+ brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
+ err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
+ if (err) {
diff --git a/package/kernel/mac80211/patches/910-00-rt2x00-enable-rt2800soc-for-mt7620.patch b/package/kernel/mac80211/patches/910-00-rt2x00-enable-rt2800soc-for-mt7620.patch
new file mode 100644
index 0000000..e6b2d7b
--- /dev/null
+++ b/package/kernel/mac80211/patches/910-00-rt2x00-enable-rt2800soc-for-mt7620.patch
@@ -0,0 +1,20 @@
+--- a/drivers/net/wireless/rt2x00/Kconfig
++++ b/drivers/net/wireless/rt2x00/Kconfig
+@@ -211,7 +211,7 @@ endif
+ config RT2800SOC
+ tristate "Ralink WiSoC support"
+ depends on m
+- depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620
+ select RT2X00_LIB_SOC
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_CRYPTO
+@@ -248,7 +248,7 @@ config RT2X00_LIB_PCI
+
+ config RT2X00_LIB_SOC
+ tristate "RT2x00 SoC support"
+- depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620
+ depends on m
+ select RT2X00_LIB
+
diff --git a/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch b/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch
new file mode 100644
index 0000000..b0536ce
--- /dev/null
+++ b/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch
@@ -0,0 +1,1202 @@
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -81,6 +81,7 @@
+ #define RF5372 0x5372
+ #define RF5390 0x5390
+ #define RF5392 0x5392
++#define RF7620 0x7620
+
+ /*
+ * Chipset revisions.
+@@ -656,6 +657,14 @@
+ #define RF_CSR_CFG_BUSY FIELD32(0x00020000)
+
+ /*
++ * mt7620 RF registers (reversed order)
++ */
++#define RF_CSR_CFG_DATA_MT7620 FIELD32(0x0000ff00)
++#define RF_CSR_CFG_REGNUM_MT7620 FIELD32(0x03ff0000)
++#define RF_CSR_CFG_WRITE_MT7620 FIELD32(0x00000010)
++#define RF_CSR_CFG_BUSY_MT7620 FIELD32(0x00000001)
++
++/*
+ * EFUSE_CSR: RT30x0 EEPROM
+ */
+ #define EFUSE_CTRL 0x0580
+@@ -1039,6 +1048,11 @@
+ #define AUTOWAKEUP_CFG_AUTOWAKE FIELD32(0x00008000)
+
+ /*
++ * mt7620
++ */
++#define MIMO_PS_CFG 0x1210
++
++/*
+ * EDCA_AC0_CFG:
+ */
+ #define EDCA_AC0_CFG 0x1300
+@@ -1218,6 +1232,8 @@
+ #define TX_PIN_CFG_RFTR_POL FIELD32(0x00020000)
+ #define TX_PIN_CFG_TRSW_EN FIELD32(0x00040000)
+ #define TX_PIN_CFG_TRSW_POL FIELD32(0x00080000)
++#define TX_PIN_CFG_RFRX_EN FIELD32(0x00100000) /* mt7620 */
++#define TX_PIN_CFG_RFRX_POL FIELD32(0x00200000) /* mt7620 */
+ #define TX_PIN_CFG_PA_PE_A2_EN FIELD32(0x01000000)
+ #define TX_PIN_CFG_PA_PE_G2_EN FIELD32(0x02000000)
+ #define TX_PIN_CFG_PA_PE_A2_POL FIELD32(0x04000000)
+@@ -1564,6 +1580,17 @@
+ #define TX_PWR_CFG_4_EXT_STBC4_CH2 FIELD32(0x0000000f)
+ #define TX_PWR_CFG_4_EXT_STBC6_CH2 FIELD32(0x00000f00)
+
++/* mt7620 */
++#define TX0_RF_GAIN_CORRECT 0x13a0
++#define TX1_RF_GAIN_CORRECT 0x13a4
++#define TX0_RF_GAIN_ATTEN 0x13a8
++#define TX1_RF_GAIN_ATTEN 0x13ac
++#define TX_ALG_CFG_0 0x13b0
++#define TX_ALG_CFG_1 0x13b4
++#define TX0_BB_GAIN_ATTEN 0x13c0
++#define TX1_BB_GAIN_ATTEN 0x13c4
++#define TX_ALC_VGA3 0x13c8
++
+ /* TX_PWR_CFG_7 */
+ #define TX_PWR_CFG_7 0x13d4
+ #define TX_PWR_CFG_7_OFDM54_CH0 FIELD32(0x0000000f)
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -61,6 +61,8 @@
+ rt2800_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg))
+ #define WAIT_FOR_RFCSR(__dev, __reg) \
+ rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg))
++#define WAIT_FOR_RFCSR_MT7620(__dev, __reg) \
++ rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY_MT7620, (__reg))
+ #define WAIT_FOR_RF(__dev, __reg) \
+ rt2800_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg))
+ #define WAIT_FOR_MCU(__dev, __reg) \
+@@ -186,19 +188,55 @@ static void rt2800_rfcsr_write(struct rt
+ * Wait until the RFCSR becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+- if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+- reg = 0;
+- rt2x00_set_field32(&reg, RF_CSR_CFG_DATA, value);
+- rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+- rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 1);
+- rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
++ switch (rt2x00dev->chip.rf) {
++ case RF7620:
++ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, &reg)) {
++ reg = 0;
++ rt2x00_set_field32(&reg, RF_CSR_CFG_DATA_MT7620, value);
++ rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM_MT7620, word);
++ rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE_MT7620, 1);
++ rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY_MT7620, 1);
++
++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
++ }
++ break;
++
++ default:
++ if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
++ reg = 0;
++ rt2x00_set_field32(&reg, RF_CSR_CFG_DATA, value);
++ rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
++ rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 1);
++ rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
+
+- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
++ }
++ break;
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+ }
+
++static void rt2800_rfcsr_write_bank(struct rt2x00_dev *rt2x00dev, const u8 bank,
++ const unsigned int reg, const u8 value)
++{
++ rt2800_rfcsr_write(rt2x00dev, (reg | (bank << 6)), value);
++}
++
++static void rt2800_rfcsr_write_chanreg(struct rt2x00_dev *rt2x00dev,
++ const unsigned int reg, const u8 value)
++{
++ rt2800_rfcsr_write_bank(rt2x00dev, 4, reg, value);
++ rt2800_rfcsr_write_bank(rt2x00dev, 6, reg, value);
++}
++
++static void rt2800_rfcsr_write_dccal(struct rt2x00_dev *rt2x00dev,
++ const unsigned int reg, const u8 value)
++{
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, reg, value);
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, reg, value);
++}
++
+ static void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, u8 *value)
+ {
+@@ -214,22 +252,47 @@ static void rt2800_rfcsr_read(struct rt2
+ * doesn't become available in time, reg will be 0xffffffff
+ * which means we return 0xff to the caller.
+ */
+- if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+- reg = 0;
+- rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+- rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 0);
+- rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
++ switch (rt2x00dev->chip.rf) {
++ case RF7620:
++ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, &reg)) {
++ reg = 0;
++ rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM_MT7620, word);
++ rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE_MT7620, 0);
++ rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY_MT7620, 1);
+
+- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
+
+- WAIT_FOR_RFCSR(rt2x00dev, &reg);
+- }
++ WAIT_FOR_RFCSR_MT7620(rt2x00dev, &reg);
++ }
+
+- *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
++ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA_MT7620);
++ break;
++
++ default:
++ if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
++ reg = 0;
++ rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
++ rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 0);
++ rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
++
++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
++
++ WAIT_FOR_RFCSR(rt2x00dev, &reg);
++ }
++
++ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
++ break;
++ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+ }
+
++static void rt2800_rfcsr_read_bank(struct rt2x00_dev *rt2x00dev, const u8 bank,
++ const unsigned int reg, u8 *value)
++{
++ rt2800_rfcsr_read(rt2x00dev, (reg | (bank << 6)), value);
++}
++
+ static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u32 value)
+ {
+@@ -566,6 +629,16 @@ void rt2800_get_txwi_rxwi_size(struct rt
+ *rxwi_size = RXWI_DESC_SIZE_5WORDS;
+ break;
+
++ case RT5390:
++ if ( rt2x00dev->chip.rf == RF7620 ) {
++ *txwi_size = TXWI_DESC_SIZE_5WORDS;
++ *rxwi_size = RXWI_DESC_SIZE_6WORDS;
++ } else {
++ *txwi_size = TXWI_DESC_SIZE_4WORDS;
++ *rxwi_size = RXWI_DESC_SIZE_4WORDS;
++ }
++ break;
++
+ case RT5592:
+ *txwi_size = TXWI_DESC_SIZE_5WORDS;
+ *rxwi_size = RXWI_DESC_SIZE_6WORDS;
+@@ -3302,6 +3375,312 @@ static void rt2800_config_channel_rf55xx
+ rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F);
+ }
+
++typedef struct mt7620_freqconfig {
++ u8 Channel;
++ u8 Rdiv;
++ u16 N;
++ u8 K;
++ u8 D;
++ u32 Ksd;
++} mt7620_freqconfig;
++
++mt7620_freqconfig mt7620_chanconfig[] =
++{
++ /* 2.4 to 2.483 GHz
++ * CH Rdiv N K D Ksd */
++ { 0, 0, 0, 0, 0, 0 },
++ { 1, 3, 0x50, 0, 0, 0x19999 },
++ { 2, 3, 0x50, 0, 0, 0x24444 },
++ { 3, 3, 0x50, 0, 0, 0x2EEEE },
++ { 4, 3, 0x50, 0, 0, 0x39999 },
++ { 5, 3, 0x51, 0, 0, 0x04444 },
++ { 6, 3, 0x51, 0, 0, 0x0EEEE },
++ { 7, 3, 0x51, 0, 0, 0x19999 },
++ { 8, 3, 0x51, 0, 0, 0x24444 },
++ { 9, 3, 0x51, 0, 0, 0x2EEEE },
++ { 10, 3, 0x51, 0, 0, 0x39999 },
++ { 11, 3, 0x52, 0, 0, 0x04444 },
++ { 12, 3, 0x52, 0, 0, 0x0EEEE },
++ { 13, 3, 0x52, 0, 0, 0x19999 },
++ { 14, 3, 0x52, 0, 0, 0x33333 },
++};
++
++static void rt2800_config_channel_rf7620(struct rt2x00_dev *rt2x00dev,
++ struct ieee80211_conf *conf,
++ struct rf_channel *rf,
++ struct channel_info *info)
++{
++ int i;
++ u8 bbp;
++ u8 rfcsr;
++ u8 txrx_agc_fc;
++ u32 reg;
++ u16 eeprom, target_power;
++ u32 mac_sys_ctrl, mac_status;
++ u32 tx_pin = 0x00150F0F;
++ struct hw_mode_spec *spec = &rt2x00dev->spec;
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++
++ /* Frequeny plan setting */
++ /*
++ * Rdiv setting
++ * R13[1:0]
++ */
++ rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr);
++ rfcsr = rfcsr & (~0x03);
++ if (spec->clk_is_20mhz)
++ rfcsr |= (mt7620_chanconfig[rf->channel].Rdiv & 0x3);
++ rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
++
++ /*
++ * N setting
++ * R21[0], R20[7:0]
++ */
++ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr);
++ rfcsr = (mt7620_chanconfig[rf->channel].N & 0x00ff);
++ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr);
++ rfcsr = rfcsr & (~0x01);
++ rfcsr |= ((mt7620_chanconfig[rf->channel].N & 0x0100) >> 8);
++ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
++
++ /*
++ * K setting
++ * R16[3:0] (RF PLL freq selection)
++ */
++ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr);
++ rfcsr = rfcsr & (~0x0f);
++ rfcsr |= (mt7620_chanconfig[rf->channel].K & 0x0f);
++ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
++
++ /*
++ * D setting
++ * R22[2:0] (D=15, R22[2:0]=<111>)
++ */
++ rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
++ rfcsr = rfcsr & (~0x07);
++ rfcsr |= (mt7620_chanconfig[rf->channel].D & 0x07);
++ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
++
++ /*
++ * Ksd setting
++ * Ksd: R19<1:0>,R18<7:0>,R17<7:0>
++ */
++ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
++ rfcsr = (mt7620_chanconfig[rf->channel].Ksd & 0x000000ff);
++ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 18, &rfcsr);
++ rfcsr = ((mt7620_chanconfig[rf->channel].Ksd & 0x0000ff00) >> 8);
++ rt2800_rfcsr_write(rt2x00dev, 18, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 19, &rfcsr);
++ rfcsr = rfcsr & (~0x03);
++ rfcsr |= ((mt7620_chanconfig[rf->channel].Ksd & 0x00030000) >> 16);
++ rt2800_rfcsr_write(rt2x00dev, 19, rfcsr);
++
++ /* Default: XO=20MHz , SDM mode */
++ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr);
++ rfcsr = rfcsr & (~0xE0);
++ rfcsr |= 0x80;
++ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr);
++ rfcsr |= 0x80;
++ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
++ if (rt2x00dev->default_ant.tx_chain_num == 1)
++ rfcsr &= (~0x2);
++ else
++ rfcsr |= 0x2;
++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
++ if (rt2x00dev->default_ant.tx_chain_num == 1)
++ rfcsr &= (~0x20);
++ else
++ rfcsr |= 0x20;
++ if (rt2x00dev->default_ant.rx_chain_num == 1)
++ rfcsr &= (~0x02);
++ else
++ rfcsr |= 0x02;
++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 42, &rfcsr);
++ if (rt2x00dev->default_ant.tx_chain_num == 1)
++ rfcsr &= (~0x40);
++ else
++ rfcsr |= 0x40;
++ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr);
++
++ /* RF for DC Cal BW */
++ if (conf_is_ht40(conf)) {
++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10);
++ } else {
++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20);
++ }
++
++ if (conf_is_ht40(conf)) {
++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08);
++ } else {
++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28);
++ }
++
++ rt2800_rfcsr_read(rt2x00dev, 28, &rfcsr);
++ if (conf_is_ht40(conf) && (rf->channel == 11))
++ rfcsr |= 0x4;
++ else
++ rfcsr &= (~0x4);
++ rt2800_rfcsr_write(rt2x00dev, 28, rfcsr);
++
++ /*if (bScan == FALSE)*/
++ if (conf_is_ht40(conf)) {
++ txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw40,
++ RFCSR24_TX_AGC_FC);
++ } else {
++ txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw20,
++ RFCSR24_TX_AGC_FC);
++ }
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= txrx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= txrx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 6, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= txrx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 6, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 7, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= txrx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 7, rfcsr);
++
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= txrx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= txrx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 58, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= txrx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 58, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 59, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= txrx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr);
++
++ rt2800_register_read(rt2x00dev, TX_ALG_CFG_0, &reg);
++ reg = reg & (~0x3F3F);
++ reg |= info->default_power1;
++ reg |= (info->default_power2 << 8);
++ reg |= (0x2F << 16);
++ reg |= (0x2F << 24);
++
++ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_INTERNAL_TX_ALC)) {
++ /* init base power by e2p target power */
++ rt2800_eeprom_read(rt2x00dev, 0xD0, &target_power);
++ target_power &= 0x3F;
++ reg = reg & (~0x3F3F);
++ reg |= target_power;
++ reg |= (target_power << 8);
++ }
++ rt2800_register_write(rt2x00dev, TX_ALG_CFG_0, reg);
++
++ rt2800_register_read(rt2x00dev, TX_ALG_CFG_1, &reg);
++ reg = reg & (~0x3F);
++ rt2800_register_write(rt2x00dev, TX_ALG_CFG_1, reg);
++
++ /*if (bScan == FALSE)*/
++ /* Save MAC SYS CTRL registers */
++ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &mac_sys_ctrl);
++ /* Disable Tx/Rx */
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
++ /* Check MAC Tx/Rx idle */
++ for (i = 0; i < 10000; i++) {
++ rt2800_register_read(rt2x00dev, MAC_STATUS_CFG, &mac_status);
++ if (mac_status & 0x3)
++ udelay(50);
++ else
++ break;
++ }
++
++ if (i == 10000)
++ rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n");
++
++ if (rf->channel > 10) {
++ rt2800_bbp_read(rt2x00dev, 30, &bbp);
++ bbp = 0x40;
++ rt2800_bbp_write(rt2x00dev, 30, bbp);
++ rt2800_rfcsr_write(rt2x00dev, 39, 0);
++ rt2800_rfcsr_write(rt2x00dev, 42, 0x7b);
++ } else {
++ rt2800_bbp_read(rt2x00dev, 30, &bbp);
++ bbp = 0x1f;
++ rt2800_bbp_write(rt2x00dev, 30, bbp);
++ rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
++ }
++
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl);
++
++ rt2800_rfcsr_write(rt2x00dev, 5, 0x40);
++ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C);
++
++ /* vcocal_en (initiate VCO calibration (reset after completion)) */
++ rt2800_rfcsr_read(rt2x00dev, 4, &rfcsr);
++ rfcsr = ((rfcsr & ~0x80) | 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 4, rfcsr);
++ mdelay(2);
++
++ rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
++
++ if (rt2x00dev->default_ant.tx_chain_num == 1) {
++ rt2800_bbp_write(rt2x00dev, 91, 0x07);
++ rt2800_bbp_write(rt2x00dev, 95, 0x1A);
++ rt2800_bbp_write(rt2x00dev, 195, 128);
++ rt2800_bbp_write(rt2x00dev, 196, 0xA0);
++ rt2800_bbp_write(rt2x00dev, 195, 170);
++ rt2800_bbp_write(rt2x00dev, 196, 0x12);
++ rt2800_bbp_write(rt2x00dev, 195, 171);
++ rt2800_bbp_write(rt2x00dev, 196, 0x10);
++ } else {
++ rt2800_bbp_write(rt2x00dev, 91, 0x06);
++ rt2800_bbp_write(rt2x00dev, 95, 0x9A);
++ rt2800_bbp_write(rt2x00dev, 195, 128);
++ rt2800_bbp_write(rt2x00dev, 196, 0xE0);
++ rt2800_bbp_write(rt2x00dev, 195, 170);
++ rt2800_bbp_write(rt2x00dev, 196, 0x30);
++ rt2800_bbp_write(rt2x00dev, 195, 171);
++ rt2800_bbp_write(rt2x00dev, 196, 0x30);
++ }
++
++ /* On 11A, We should delay and wait RF/BBP to be stable*/
++ /* and the appropriate time should be 1000 micro seconds */
++ /* 2005/06/05 - On 11G, We also need this delay time.
++ * Otherwise it's difficult to pass the WHQL.*/
++ udelay(1000);
++}
++
++
+ static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word,
+ const u8 value)
+@@ -3458,7 +3837,7 @@ static void rt2800_config_channel(struct
+ struct channel_info *info)
+ {
+ u32 reg;
+- unsigned int tx_pin;
++ u32 tx_pin;
+ u8 bbp, rfcsr;
+
+ info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
+@@ -3512,6 +3891,9 @@ static void rt2800_config_channel(struct
+ case RF5592:
+ rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info);
+ break;
++ case RF7620:
++ rt2800_config_channel_rf7620(rt2x00dev, conf, rf, info);
++ break;
+ default:
+ rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
+ }
+@@ -3614,7 +3996,7 @@ static void rt2800_config_channel(struct
+ else if (rt2x00_rt(rt2x00dev, RT3593) ||
+ rt2x00_rt(rt2x00dev, RT3883))
+ rt2800_bbp_write(rt2x00dev, 82, 0x82);
+- else
++ else if (rt2x00dev->chip.rf != RF7620)
+ rt2800_bbp_write(rt2x00dev, 82, 0xf2);
+
+ if (rt2x00_rt(rt2x00dev, RT3593) ||
+@@ -3636,7 +4018,7 @@ static void rt2800_config_channel(struct
+ if (rt2x00_rt(rt2x00dev, RT3572))
+ rt2800_rfcsr_write(rt2x00dev, 8, 0);
+
+- tx_pin = 0;
++ rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin);
+
+ switch (rt2x00dev->default_ant.tx_chain_num) {
+ case 3:
+@@ -3685,6 +4067,7 @@ static void rt2800_config_channel(struct
+
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); /* mt7620 */
+
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+
+@@ -4701,6 +5084,14 @@ void rt2800_vco_calibration(struct rt2x0
+ rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
+ rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
+ break;
++ case RF7620:
++ rt2800_rfcsr_read(rt2x00dev, 4, &rfcsr);
++ /* vcocal_en (initiate VCO calibration (reset after completion))
++ * It should be at the end of RF configuration. */
++ rfcsr = ((rfcsr & ~0x80) | 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 4, rfcsr);
++ mdelay(1);
++ break;
+ default:
+ return;
+ }
+@@ -5101,9 +5492,42 @@ static int rt2800_init_registers(struct
+ } else if (rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392) ||
+ rt2x00_rt(rt2x00dev, RT5592)) {
+- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
++ if (rt2x00dev->chip.rf == RF7620) {
++ rt2800_register_write(rt2x00dev, TX_SW_CFG0,
++ 0x00000401);
++ rt2800_register_write(rt2x00dev, TX_SW_CFG1,
++ 0x000C0000);
++ rt2800_register_write(rt2x00dev, TX_SW_CFG2,
++ 0x00000000);
++ rt2800_register_write(rt2x00dev, MIMO_PS_CFG,
++ 0x00000002);
++ rt2800_register_write(rt2x00dev, TX_PIN_CFG,
++ 0x00150F0F);
++ rt2800_register_write(rt2x00dev, TX_ALC_VGA3,
++ 0x06060606);
++ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN,
++ 0x0);
++ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN,
++ 0x0);
++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN,
++ 0x6C6C666C);
++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
++ 0x6C6C666C);
++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
++ 0x3630363A);
++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT,
++ 0x3630363A);
++ rt2800_register_read(rt2x00dev, TX_ALG_CFG_1, &reg);
++ reg = reg & (~0x80000000);
++ rt2800_register_write(rt2x00dev, TX_ALG_CFG_1, reg);
++ } else {
++ rt2800_register_write(rt2x00dev, TX_SW_CFG0,
++ 0x00000404);
++ rt2800_register_write(rt2x00dev, TX_SW_CFG1,
++ 0x00080606);
++ rt2800_register_write(rt2x00dev, TX_SW_CFG2,
++ 0x00000000);
++ }
+ } else if (rt2x00_rt(rt2x00dev, RT5350)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+ } else {
+@@ -6135,6 +6559,225 @@ static void rt2800_init_bbp_5592(struct
+ rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+ }
+
++static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev,
++ const u8 reg, const u8 value)
++{
++ rt2800_bbp_write(rt2x00dev, 195, reg);
++ rt2800_bbp_write(rt2x00dev, 196, value);
++}
++
++static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev,
++ const u8 reg, const u8 value)
++{
++ rt2800_bbp_write(rt2x00dev, 158, reg);
++ rt2800_bbp_write(rt2x00dev, 159, value);
++}
++
++static void rt2800_init_bbp_7620(struct rt2x00_dev *rt2x00dev)
++{
++ u8 bbp;
++
++ /* Apply Maximum Likelihood Detection (MLD) for 2 stream case */
++ rt2800_bbp_read(rt2x00dev, 105, &bbp);
++ rt2x00_set_field8(&bbp, BBP105_MLD,
++ rt2x00dev->default_ant.rx_chain_num == 2);
++ rt2800_bbp_write(rt2x00dev, 105, bbp);
++
++ /* Avoid data loss and CRC errors */
++ /* MAC interface control (MAC_IF_80M, 1: 80 MHz) */
++ rt2800_bbp4_mac_if_ctrl(rt2x00dev);
++
++ /* Fix I/Q swap issue */
++ rt2800_bbp_read(rt2x00dev, 1, &bbp);
++ bbp |= 0x04;
++ rt2800_bbp_write(rt2x00dev, 1, bbp);
++
++ /* BBP for G band */
++ rt2800_bbp_write(rt2x00dev, 3, 0x08);
++ rt2800_bbp_write(rt2x00dev, 4, 0x00); /* rt2800_bbp4_mac_if_ctrl? */
++ rt2800_bbp_write(rt2x00dev, 6, 0x08);
++ rt2800_bbp_write(rt2x00dev, 14, 0x09);
++ rt2800_bbp_write(rt2x00dev, 15, 0xFF);
++ rt2800_bbp_write(rt2x00dev, 16, 0x01);
++ rt2800_bbp_write(rt2x00dev, 20, 0x06);
++ rt2800_bbp_write(rt2x00dev, 21, 0x00);
++ rt2800_bbp_write(rt2x00dev, 22, 0x00);
++ rt2800_bbp_write(rt2x00dev, 27, 0x00);
++ rt2800_bbp_write(rt2x00dev, 28, 0x00);
++ rt2800_bbp_write(rt2x00dev, 30, 0x00);
++ rt2800_bbp_write(rt2x00dev, 31, 0x48);
++ rt2800_bbp_write(rt2x00dev, 47, 0x40);
++ rt2800_bbp_write(rt2x00dev, 62, 0x00);
++ rt2800_bbp_write(rt2x00dev, 63, 0x00);
++ rt2800_bbp_write(rt2x00dev, 64, 0x00);
++ rt2800_bbp_write(rt2x00dev, 65, 0x2C);
++ rt2800_bbp_write(rt2x00dev, 66, 0x1C);
++ rt2800_bbp_write(rt2x00dev, 67, 0x20);
++ rt2800_bbp_write(rt2x00dev, 68, 0xDD);
++ rt2800_bbp_write(rt2x00dev, 69, 0x10);
++ rt2800_bbp_write(rt2x00dev, 70, 0x05);
++ rt2800_bbp_write(rt2x00dev, 73, 0x18);
++ rt2800_bbp_write(rt2x00dev, 74, 0x0F);
++ rt2800_bbp_write(rt2x00dev, 75, 0x60);
++ rt2800_bbp_write(rt2x00dev, 76, 0x44);
++ rt2800_bbp_write(rt2x00dev, 77, 0x59);
++ rt2800_bbp_write(rt2x00dev, 78, 0x1E);
++ rt2800_bbp_write(rt2x00dev, 79, 0x1C);
++ rt2800_bbp_write(rt2x00dev, 80, 0x0C);
++ rt2800_bbp_write(rt2x00dev, 81, 0x3A);
++ rt2800_bbp_write(rt2x00dev, 82, 0xB6);
++ rt2800_bbp_write(rt2x00dev, 83, 0x9A);
++ rt2800_bbp_write(rt2x00dev, 84, 0x9A);
++ rt2800_bbp_write(rt2x00dev, 86, 0x38);
++ rt2800_bbp_write(rt2x00dev, 88, 0x90);
++ rt2800_bbp_write(rt2x00dev, 91, 0x04);
++ rt2800_bbp_write(rt2x00dev, 92, 0x02);
++ rt2800_bbp_write(rt2x00dev, 95, 0x9A);
++ rt2800_bbp_write(rt2x00dev, 96, 0x00);
++ rt2800_bbp_write(rt2x00dev, 103, 0xC0);
++ rt2800_bbp_write(rt2x00dev, 104, 0x92);
++ /* FIXME BBP105 owerwrite */
++ rt2800_bbp_write(rt2x00dev, 105, 0x3C);
++ rt2800_bbp_write(rt2x00dev, 106, 0x12);
++ rt2800_bbp_write(rt2x00dev, 109, 0x00);
++ rt2800_bbp_write(rt2x00dev, 134, 0x10);
++ rt2800_bbp_write(rt2x00dev, 135, 0xA6);
++ rt2800_bbp_write(rt2x00dev, 137, 0x04);
++ rt2800_bbp_write(rt2x00dev, 142, 0x30);
++ rt2800_bbp_write(rt2x00dev, 143, 0xF7);
++ rt2800_bbp_write(rt2x00dev, 160, 0xEC);
++ rt2800_bbp_write(rt2x00dev, 161, 0xC4);
++ rt2800_bbp_write(rt2x00dev, 162, 0x77);
++ rt2800_bbp_write(rt2x00dev, 163, 0xF9);
++ rt2800_bbp_write(rt2x00dev, 164, 0x00);
++ rt2800_bbp_write(rt2x00dev, 165, 0x00);
++ rt2800_bbp_write(rt2x00dev, 186, 0x00);
++ rt2800_bbp_write(rt2x00dev, 187, 0x00);
++ rt2800_bbp_write(rt2x00dev, 188, 0x00);
++ rt2800_bbp_write(rt2x00dev, 186, 0x00);
++ rt2800_bbp_write(rt2x00dev, 187, 0x01);
++ rt2800_bbp_write(rt2x00dev, 188, 0x00);
++ rt2800_bbp_write(rt2x00dev, 189, 0x00);
++
++ rt2800_bbp_write(rt2x00dev, 91, 0x06);
++ rt2800_bbp_write(rt2x00dev, 92, 0x04);
++ rt2800_bbp_write(rt2x00dev, 93, 0x54);
++ rt2800_bbp_write(rt2x00dev, 99, 0x50);
++ rt2800_bbp_write(rt2x00dev, 148, 0x84);
++ rt2800_bbp_write(rt2x00dev, 167, 0x80);
++ rt2800_bbp_write(rt2x00dev, 178, 0xFF);
++ rt2800_bbp_write(rt2x00dev, 106, 0x13);
++
++ /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */
++ rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00);
++ rt2800_bbp_glrt_write(rt2x00dev, 1, 0x14); /* ? see above */
++ rt2800_bbp_glrt_write(rt2x00dev, 2, 0x20);
++ rt2800_bbp_glrt_write(rt2x00dev, 3, 0x0A);
++ rt2800_bbp_glrt_write(rt2x00dev, 10, 0x16);
++ rt2800_bbp_glrt_write(rt2x00dev, 11, 0x06);
++ rt2800_bbp_glrt_write(rt2x00dev, 12, 0x02);
++ rt2800_bbp_glrt_write(rt2x00dev, 13, 0x07);
++ rt2800_bbp_glrt_write(rt2x00dev, 14, 0x05);
++ rt2800_bbp_glrt_write(rt2x00dev, 15, 0x09);
++ rt2800_bbp_glrt_write(rt2x00dev, 16, 0x20);
++ rt2800_bbp_glrt_write(rt2x00dev, 17, 0x08);
++ rt2800_bbp_glrt_write(rt2x00dev, 18, 0x4A);
++ rt2800_bbp_glrt_write(rt2x00dev, 19, 0x00);
++ rt2800_bbp_glrt_write(rt2x00dev, 20, 0x00);
++ rt2800_bbp_glrt_write(rt2x00dev, 128, 0xE0);
++ rt2800_bbp_glrt_write(rt2x00dev, 129, 0x1F);
++ rt2800_bbp_glrt_write(rt2x00dev, 130, 0x4F);
++ rt2800_bbp_glrt_write(rt2x00dev, 131, 0x32);
++ rt2800_bbp_glrt_write(rt2x00dev, 132, 0x08);
++ rt2800_bbp_glrt_write(rt2x00dev, 133, 0x28);
++ rt2800_bbp_glrt_write(rt2x00dev, 134, 0x19);
++ rt2800_bbp_glrt_write(rt2x00dev, 135, 0x0A);
++ rt2800_bbp_glrt_write(rt2x00dev, 138, 0x16);
++ rt2800_bbp_glrt_write(rt2x00dev, 139, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 140, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1A);
++ rt2800_bbp_glrt_write(rt2x00dev, 142, 0x36);
++ rt2800_bbp_glrt_write(rt2x00dev, 143, 0x2C);
++ rt2800_bbp_glrt_write(rt2x00dev, 144, 0x26);
++ rt2800_bbp_glrt_write(rt2x00dev, 145, 0x24);
++ rt2800_bbp_glrt_write(rt2x00dev, 146, 0x42);
++ rt2800_bbp_glrt_write(rt2x00dev, 147, 0x40);
++ rt2800_bbp_glrt_write(rt2x00dev, 148, 0x30);
++ rt2800_bbp_glrt_write(rt2x00dev, 149, 0x29);
++ rt2800_bbp_glrt_write(rt2x00dev, 150, 0x4C);
++ rt2800_bbp_glrt_write(rt2x00dev, 151, 0x46);
++ rt2800_bbp_glrt_write(rt2x00dev, 152, 0x3D);
++ rt2800_bbp_glrt_write(rt2x00dev, 153, 0x40);
++ rt2800_bbp_glrt_write(rt2x00dev, 154, 0x3E);
++ rt2800_bbp_glrt_write(rt2x00dev, 155, 0x38);
++ rt2800_bbp_glrt_write(rt2x00dev, 156, 0x3D);
++ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2F);
++ rt2800_bbp_glrt_write(rt2x00dev, 158, 0x3C);
++ rt2800_bbp_glrt_write(rt2x00dev, 159, 0x34);
++ rt2800_bbp_glrt_write(rt2x00dev, 160, 0x2C);
++ rt2800_bbp_glrt_write(rt2x00dev, 161, 0x2F);
++ rt2800_bbp_glrt_write(rt2x00dev, 162, 0x3C);
++ rt2800_bbp_glrt_write(rt2x00dev, 163, 0x35);
++ rt2800_bbp_glrt_write(rt2x00dev, 164, 0x2E);
++ rt2800_bbp_glrt_write(rt2x00dev, 165, 0x2F);
++ rt2800_bbp_glrt_write(rt2x00dev, 166, 0x49);
++ rt2800_bbp_glrt_write(rt2x00dev, 167, 0x41);
++ rt2800_bbp_glrt_write(rt2x00dev, 168, 0x36);
++ rt2800_bbp_glrt_write(rt2x00dev, 169, 0x39);
++ rt2800_bbp_glrt_write(rt2x00dev, 170, 0x30);
++ rt2800_bbp_glrt_write(rt2x00dev, 171, 0x30);
++ rt2800_bbp_glrt_write(rt2x00dev, 172, 0x0E);
++ rt2800_bbp_glrt_write(rt2x00dev, 173, 0x0D);
++ rt2800_bbp_glrt_write(rt2x00dev, 174, 0x28);
++ rt2800_bbp_glrt_write(rt2x00dev, 175, 0x21);
++ rt2800_bbp_glrt_write(rt2x00dev, 176, 0x1C);
++ rt2800_bbp_glrt_write(rt2x00dev, 177, 0x16);
++ rt2800_bbp_glrt_write(rt2x00dev, 178, 0x50);
++ rt2800_bbp_glrt_write(rt2x00dev, 179, 0x4A);
++ rt2800_bbp_glrt_write(rt2x00dev, 180, 0x43);
++ rt2800_bbp_glrt_write(rt2x00dev, 181, 0x50);
++ rt2800_bbp_glrt_write(rt2x00dev, 182, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 183, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 184, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 185, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 200, 0x7D);
++ rt2800_bbp_glrt_write(rt2x00dev, 201, 0x14);
++ rt2800_bbp_glrt_write(rt2x00dev, 202, 0x32);
++ rt2800_bbp_glrt_write(rt2x00dev, 203, 0x2C);
++ rt2800_bbp_glrt_write(rt2x00dev, 204, 0x36);
++ rt2800_bbp_glrt_write(rt2x00dev, 205, 0x4C);
++ rt2800_bbp_glrt_write(rt2x00dev, 206, 0x43);
++ rt2800_bbp_glrt_write(rt2x00dev, 207, 0x2C);
++ rt2800_bbp_glrt_write(rt2x00dev, 208, 0x2E);
++ rt2800_bbp_glrt_write(rt2x00dev, 209, 0x36);
++ rt2800_bbp_glrt_write(rt2x00dev, 210, 0x30);
++ rt2800_bbp_glrt_write(rt2x00dev, 211, 0x6E);
++
++ /* BBP for G band DCOC function */
++ rt2800_bbp_dcoc_write(rt2x00dev, 140, 0x0C);
++ rt2800_bbp_dcoc_write(rt2x00dev, 141, 0x00);
++ rt2800_bbp_dcoc_write(rt2x00dev, 142, 0x10);
++ rt2800_bbp_dcoc_write(rt2x00dev, 143, 0x10);
++ rt2800_bbp_dcoc_write(rt2x00dev, 144, 0x10);
++ rt2800_bbp_dcoc_write(rt2x00dev, 145, 0x10);
++ rt2800_bbp_dcoc_write(rt2x00dev, 146, 0x08);
++ rt2800_bbp_dcoc_write(rt2x00dev, 147, 0x40);
++ rt2800_bbp_dcoc_write(rt2x00dev, 148, 0x04);
++ rt2800_bbp_dcoc_write(rt2x00dev, 149, 0x04);
++ rt2800_bbp_dcoc_write(rt2x00dev, 150, 0x08);
++ rt2800_bbp_dcoc_write(rt2x00dev, 151, 0x08);
++ rt2800_bbp_dcoc_write(rt2x00dev, 152, 0x03);
++ rt2800_bbp_dcoc_write(rt2x00dev, 153, 0x03);
++ rt2800_bbp_dcoc_write(rt2x00dev, 154, 0x03);
++ rt2800_bbp_dcoc_write(rt2x00dev, 155, 0x02);
++ rt2800_bbp_dcoc_write(rt2x00dev, 156, 0x40);
++ rt2800_bbp_dcoc_write(rt2x00dev, 157, 0x40);
++ rt2800_bbp_dcoc_write(rt2x00dev, 158, 0x64);
++ rt2800_bbp_dcoc_write(rt2x00dev, 159, 0x64);
++
++ rt2800_bbp4_mac_if_ctrl(rt2x00dev);
++}
++
+ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
+ {
+ unsigned int i;
+@@ -6177,7 +6820,10 @@ static void rt2800_init_bbp(struct rt2x0
+ return;
+ case RT5390:
+ case RT5392:
+- rt2800_init_bbp_53xx(rt2x00dev);
++ if (rt2x00dev->chip.rf == RF7620)
++ rt2800_init_bbp_7620(rt2x00dev);
++ else
++ rt2800_init_bbp_53xx(rt2x00dev);
+ break;
+ case RT5592:
+ rt2800_init_bbp_5592(rt2x00dev);
+@@ -7391,6 +8037,296 @@ static void rt2800_init_rfcsr_5592(struc
+ rt2800_led_open_drain_enable(rt2x00dev);
+ }
+
++static void rt2800_init_rfcsr_7620(struct rt2x00_dev *rt2x00dev)
++{
++ u16 freq;
++ u8 rfvalue;
++ struct hw_mode_spec *spec = &rt2x00dev->spec;
++
++ /* Initialize RF central register to default value */
++ rt2800_rfcsr_write(rt2x00dev, 0, 0x02);
++ rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
++ rt2800_rfcsr_write(rt2x00dev, 2, 0x33);
++ rt2800_rfcsr_write(rt2x00dev, 3, 0xFF);
++ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C);
++ rt2800_rfcsr_write(rt2x00dev, 5, 0x40); /* Read only */
++ rt2800_rfcsr_write(rt2x00dev, 6, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 8, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 9, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 10, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 11, 0x00);
++ /* rt2800_rfcsr_write(rt2x00dev, 12, 0x43); *//* EEPROM */
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 14, 0x40);
++ rt2800_rfcsr_write(rt2x00dev, 15, 0x22);
++ rt2800_rfcsr_write(rt2x00dev, 16, 0x4C);
++ rt2800_rfcsr_write(rt2x00dev, 17, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 18, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 20, 0xA0);
++ rt2800_rfcsr_write(rt2x00dev, 21, 0x12);
++ rt2800_rfcsr_write(rt2x00dev, 22, 0x07);
++ rt2800_rfcsr_write(rt2x00dev, 23, 0x13);
++ rt2800_rfcsr_write(rt2x00dev, 24, 0xFE);
++ rt2800_rfcsr_write(rt2x00dev, 25, 0x24);
++ rt2800_rfcsr_write(rt2x00dev, 26, 0x7A);
++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 29, 0x05);
++ rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 31, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 32, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 34, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 35, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 37, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 38, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 39, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 40, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 41, 0xD0);
++ rt2800_rfcsr_write(rt2x00dev, 42, 0x5B);
++ rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
++
++ rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
++ if (spec->clk_is_20mhz)
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x03);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 14, 0x7C);
++ rt2800_rfcsr_write(rt2x00dev, 16, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 17, 0x99);
++ rt2800_rfcsr_write(rt2x00dev, 18, 0x99);
++ rt2800_rfcsr_write(rt2x00dev, 19, 0x09);
++ rt2800_rfcsr_write(rt2x00dev, 20, 0x50);
++ rt2800_rfcsr_write(rt2x00dev, 21, 0xB0);
++ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 23, 0x06);
++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 26, 0x5D);
++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 28, 0x61);
++ rt2800_rfcsr_write(rt2x00dev, 29, 0xB5);
++ rt2800_rfcsr_write(rt2x00dev, 43, 0x02);
++
++ rt2800_rfcsr_write(rt2x00dev, 28, 0x62);
++ rt2800_rfcsr_write(rt2x00dev, 29, 0xAD);
++ rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
++ /* RTMP_TEMPERATURE_CALIBRATION */
++ /* rt2800_rfcsr_write(rt2x00dev, 34, 0x23); */
++ /* rt2800_rfcsr_write(rt2x00dev, 35, 0x01); */
++
++ /* use rt2800_adjust_freq_offset ? */
++ rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &freq);
++ rfvalue = freq & 0xff;
++ rt2800_rfcsr_write(rt2x00dev, 12, rfvalue);
++
++ /* Initialize RF channel register to default value */
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 1, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 2, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 3, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 4, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 5, 0x08);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 6, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 7, 0x51);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x53);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x16);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x61);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 12, 0x22);
++ /* rt2800_rfcsr_write_chanreg(rt2x00dev, 13, 0x3D); */ /* fails */
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 15, 0x13);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 16, 0x22);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x27);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x02);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x01);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x52);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 22, 0x80);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 23, 0xB3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 24, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 25, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 26, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 27, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x5C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0x6B);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 30, 0x6B);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 31, 0x31);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x5D);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 33, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xE6);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 35, 0x55);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 37, 0xBB);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 39, 0xB3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 40, 0x03);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 41, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 42, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xB3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xD3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x07);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x68);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xEF);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x07);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xA8);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0x85);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x10);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x07);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6A);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0x85);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x10);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 62, 0x1C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 63, 0x00);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5);
++
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x69);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x20);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09);
++
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
++
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
++
++ /* Initialize RF channel register for DRQFN */
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7);
++
++ /* reduce power consumption */
++/* rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x53);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x53);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x53);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x64);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0x4F);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x02);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0x4F);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x02);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x64);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0x4F);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x02);
++*/
++ /* Initialize RF DC calibration register to default value */
++ rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 1, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 2, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 9, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 10, 0x07);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 11, 0x01);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 12, 0x07);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 13, 0x07);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 14, 0x07);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 15, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 16, 0x22);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 18, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 19, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 20, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 21, 0xF1);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 22, 0x11);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 23, 0x02);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 24, 0x41);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 25, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 26, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 27, 0xD7);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 28, 0xA2);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 29, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 30, 0x49);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 31, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 32, 0x04);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 33, 0xF1);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 34, 0xA1);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 35, 0x01);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 41, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 42, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 43, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 44, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 45, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 46, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 47, 0x3E);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 48, 0x3D);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 49, 0x3E);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 50, 0x3D);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 51, 0x3E);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 52, 0x3D);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 53, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 54, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 55, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 56, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 57, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 60, 0x0A);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 61, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00);
++
++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20);
++
++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
++}
++
+ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+ {
+ if (rt2800_is_305x_soc(rt2x00dev)) {
+@@ -7426,7 +8362,10 @@ static void rt2800_init_rfcsr(struct rt2
+ rt2800_init_rfcsr_5350(rt2x00dev);
+ break;
+ case RT5390:
+- rt2800_init_rfcsr_5390(rt2x00dev);
++ if (rt2x00dev->chip.rf == RF7620)
++ rt2800_init_rfcsr_7620(rt2x00dev);
++ else
++ rt2800_init_rfcsr_5390(rt2x00dev);
+ break;
+ case RT5392:
+ rt2800_init_rfcsr_5392(rt2x00dev);
+@@ -7858,6 +8797,7 @@ static int rt2800_init_eeprom(struct rt2
+ case RF5390:
+ case RF5392:
+ case RF5592:
++ case RF7620:
+ break;
+ default:
+ rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n",
+@@ -8422,6 +9362,7 @@ static int rt2800_probe_hw_mode(struct r
+ case RF5372:
+ case RF5390:
+ case RF5392:
++ case RF7620:
+ spec->num_channels = 14;
+ if (spec->clk_is_20mhz)
+ spec->channels = rf_vals_xtal20mhz_3x;
+@@ -8562,6 +9503,7 @@ static int rt2800_probe_hw_mode(struct r
+ case RF5372:
+ case RF5390:
+ case RF5392:
++ case RF7620:
+ __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags);
+ break;
+ }
diff --git a/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch
new file mode 100644
index 0000000..af35560
--- /dev/null
+++ b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch
@@ -0,0 +1,33 @@
+From: Sven Eckelmann <sven@open-mesh.com>
+Date: Tue, 18 Nov 2014 12:29:28 +0100
+Subject: [PATCH] ath10k: Don't initialize devices asynchronously
+
+OpenWrt requires all PHYs to be initialized to create the configuration files
+during bootup. ath10k violates this because it delays the creation of the PHY
+to a not well defined point in the future.
+
+Forcing the work to be done immediately works around this problem but may also
+delay the boot when firmware images cannot be found.
+
+Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -1844,6 +1844,16 @@ int ath10k_core_register(struct ath10k *
+ ar->chip_id = chip_id;
+ queue_work(ar->workqueue, &ar->register_work);
+
++ /* OpenWrt requires all PHYs to be initialized to create the
++ * configuration files during bootup. ath10k violates this
++ * because it delays the creation of the PHY to a not well defined
++ * point in the future.
++ *
++ * Forcing the work to be done immediately works around this problem
++ * but may also delay the boot when firmware images cannot be found.
++ */
++ flush_workqueue(ar->workqueue);
++
+ return 0;
+ }
+ EXPORT_SYMBOL(ath10k_core_register);
diff --git a/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch
new file mode 100644
index 0000000..f2718c7
--- /dev/null
+++ b/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch
@@ -0,0 +1,37 @@
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -7092,6 +7092,21 @@ struct ath10k_vif *ath10k_get_arvif(stru
+ return arvif_iter.arvif;
+ }
+
++#ifdef CPTCFG_MAC80211_LEDS
++static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = {
++ { .throughput = 0 * 1024, .blink_time = 334 },
++ { .throughput = 1 * 1024, .blink_time = 260 },
++ { .throughput = 2 * 1024, .blink_time = 220 },
++ { .throughput = 5 * 1024, .blink_time = 190 },
++ { .throughput = 10 * 1024, .blink_time = 170 },
++ { .throughput = 25 * 1024, .blink_time = 150 },
++ { .throughput = 54 * 1024, .blink_time = 130 },
++ { .throughput = 120 * 1024, .blink_time = 110 },
++ { .throughput = 265 * 1024, .blink_time = 80 },
++ { .throughput = 586 * 1024, .blink_time = 50 },
++};
++#endif
++
+ int ath10k_mac_register(struct ath10k *ar)
+ {
+ static const u32 cipher_suites[] = {
+@@ -7317,6 +7332,12 @@ int ath10k_mac_register(struct ath10k *a
+ ar->hw->wiphy->cipher_suites = cipher_suites;
+ ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
++#if CPTCFG_MAC80211_LEDS
++ ieee80211_create_tpt_led_trigger(ar->hw,
++ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink,
++ ARRAY_SIZE(ath10k_tpt_blink));
++#endif
++
+ ret = ieee80211_register_hw(ar->hw);
+ if (ret) {
+ ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
diff --git a/package/kernel/mac80211/patches/940-mwl8k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/940-mwl8k_init_devices_synchronously.patch
new file mode 100644
index 0000000..d487504
--- /dev/null
+++ b/package/kernel/mac80211/patches/940-mwl8k_init_devices_synchronously.patch
@@ -0,0 +1,20 @@
+--- a/drivers/net/wireless/mwl8k.c
++++ b/drivers/net/wireless/mwl8k.c
+@@ -6262,6 +6262,8 @@ static int mwl8k_probe(struct pci_dev *p
+
+ priv->running_bsses = 0;
+
++ wait_for_completion(&priv->firmware_loading_complete);
++
+ return rc;
+
+ err_stop_firmware:
+@@ -6295,8 +6297,6 @@ static void mwl8k_remove(struct pci_dev
+ return;
+ priv = hw->priv;
+
+- wait_for_completion(&priv->firmware_loading_complete);
+-
+ if (priv->fw_state == FW_STATE_ERROR) {
+ mwl8k_hw_reset(priv);
+ goto unmap;
diff --git a/package/kernel/mac80211/scripts/import-backports.sh b/package/kernel/mac80211/scripts/import-backports.sh
new file mode 100755
index 0000000..d056eb6
--- /dev/null
+++ b/package/kernel/mac80211/scripts/import-backports.sh
@@ -0,0 +1,109 @@
+#!/usr/bin/env bash
+BASE=$1; shift
+
+usage() {
+ echo "Usage: $0 NNN <file>..."
+ exit 1
+}
+
+check_number() {
+ case "$1" in
+ [0-9][0-9][0-9]) return 0;;
+ esac
+ return 1;
+}
+
+patch_header()
+{
+ awk '
+ /^(---|\*\*\*|Index:)[ \t][^ \t]|^diff -/ \
+ { exit }
+ { print }
+ '
+}
+
+strip_diffstat()
+{
+ awk '
+ /#? .* \| / \
+ { eat = eat $0 "\n"
+ next }
+ /^#? .* files? changed(, .* insertions?\(\+\))?(, .* deletions?\(-\))?/ \
+ { eat = ""
+ next }
+ { print eat $0
+ eat = "" }
+ '
+}
+
+strip_trailing_whitespace() {
+ sed -e 's:[ '$'\t'']*$::'
+}
+
+fixup_header() {
+ awk '
+ /^From / { next }
+ /^Subject: / {
+ sub("Subject: \\[[^\]]*\\]", "Subject: [PATCH]")
+ }
+ { print }
+ '
+}
+
+check_number "$BASE" || usage
+
+quilt series > /dev/null || {
+ echo "Not in quilt directory"
+ exit 2
+}
+
+get_next() {
+ NEW=$BASE
+ quilt series | while read CUR; do
+ [ -n "$CUR" ] || break
+ CUR=${CUR%%-*}
+ check_number "$CUR" || continue
+ [ "$CUR" -lt "$NEW" ] && continue
+ [ "$CUR" -ge "$(($BASE + 100))" ] && continue
+ NEW="$(($CUR + 1))"
+ echo $NEW
+ done | tail -n1
+}
+
+CUR=`get_next`
+CUR="${CUR:-$BASE}"
+
+while [ -n "$1" ]; do
+ FILE="$1"; shift
+ NAME="$(basename $FILE)"
+ NAME="${NAME#[0-9]*-}"
+ echo -n "Processing patch $NAME: "
+
+ [ -e "$FILE" ] || {
+ echo "file $FILE not found"
+ exit 1
+ }
+
+ grep -qE "$NAME$" patches/series && {
+ echo "already applied"
+ continue
+ }
+
+ quilt new "$CUR-$NAME" || exit 1
+ patch_header < "$FILE" |
+ strip_diffstat |
+ strip_trailing_whitespace |
+ fixup_header > "patches/$CUR-$NAME"
+
+ quilt fold < "$FILE" || {
+ cp "$FILE" ./cur_patch
+ echo "patch $FILE failed to apply, copied to ./cur_patch"
+ exit 1
+ }
+
+ quilt refresh -p ab --no-index --no-timestamps
+
+ CUR="$(($CUR + 1))"
+done
+
+exit 0
diff --git a/package/kernel/mmc_over_gpio/Makefile b/package/kernel/mmc_over_gpio/Makefile
new file mode 100644
index 0000000..69985a7
--- /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 AutoProbe,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 0000000..23f0084
--- /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 0000000..121c803
--- /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/mt76/Makefile b/package/kernel/mt76/Makefile
new file mode 100644
index 0000000..11ba79f
--- /dev/null
+++ b/package/kernel/mt76/Makefile
@@ -0,0 +1,60 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mt76
+PKG_VERSION:=2015-10-30
+PKG_RELEASE=1
+
+PKG_LICENSE:=GPLv2
+PKG_LICENSE_FILES:=
+
+PKG_SOURCE_URL:=https://github.com/openwrt/mt76
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=a3ba5b080d1a4bcbf8dc891ba835ed742603382f
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/kernel.mk
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/mt76
+ SUBMENU:=Wireless Drivers
+ TITLE:=MediaTek MT76x2 wireless driver
+ DEPENDS:=+kmod-mac80211 +@DRIVER_11N_SUPPORT @PCI_SUPPORT
+ FILES:=$(PKG_BUILD_DIR)/mt76pci.ko
+ AUTOLOAD:=$(call AutoLoad,50,mac80211 mt76pci)
+endef
+
+NOSTDINC_FLAGS = \
+ -I$(PKG_BUILD_DIR) \
+ -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 \
+ -include backport/autoconf.h \
+ -include backport/backport.h
+
+ifdef CONFIG_PACKAGE_MAC80211_MESH
+ NOSTDINC_FLAGS += -DCONFIG_MAC80211_MESH
+endif
+
+define Build/Compile
+ +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
+ modules
+endef
+
+define KernelPackage/mt76/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ cp \
+ $(PKG_BUILD_DIR)/firmware/mt7662_rom_patch.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7662.bin \
+ $(1)/lib/firmware
+endef
+
+$(eval $(call KernelPackage,mt76))
diff --git a/package/kernel/mwlwifi/Makefile b/package/kernel/mwlwifi/Makefile
new file mode 100644
index 0000000..bec2732
--- /dev/null
+++ b/package/kernel/mwlwifi/Makefile
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2014-2015 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:=mwlwifi
+PKG_VERSION:=10.3.0.12-20151029
+PKG_RELEASE=1
+
+PKG_LICENSE:=ISC
+PKG_LICENSE_FILES:=
+
+PKG_SOURCE_URL:=https://github.com/kaloz/mwlwifi
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=30e6b06de659f1d5e46d1dd3bf590caf3529bb65
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
+
+PKG_MAINTAINER:=Imre Kaloz <kaloz@openwrt.org>
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/kernel.mk
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/mwlwifi
+ SUBMENU:=Wireless Drivers
+ TITLE:=Marvell 88W8864 wireless driver
+ DEPENDS:=+kmod-mac80211 +@DRIVER_11N_SUPPORT @PCI_SUPPORT @TARGET_mvebu
+ FILES:=$(PKG_BUILD_DIR)/mwlwifi.ko
+ AUTOLOAD:=$(call AutoLoad,50,mac80211 mwlwifi)
+endef
+
+NOSTDINC_FLAGS = \
+ -I$(PKG_BUILD_DIR) \
+ -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 \
+ -include backport/backport.h
+
+define Build/Compile
+ +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ SUBDIRS="$(PKG_BUILD_DIR)" \
+ NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
+ modules
+endef
+
+define KernelPackage/mwlwifi/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ $(INSTALL_DIR) $(1)/lib/firmware/mwlwifi
+ $(CP) $(PKG_BUILD_DIR)/bin/firmware/88W8864.bin $(1)/lib/firmware/mwlwifi/
+ $(CP) $(PKG_BUILD_DIR)/bin/firmware/88W8897.bin $(1)/lib/firmware/mwlwifi/
+ $(CP) $(PKG_BUILD_DIR)/bin/firmware/Marvell_license.txt $(1)/lib/firmware/mwlwifi/
+endef
+
+$(eval $(call KernelPackage,mwlwifi))
diff --git a/package/kernel/mwlwifi/patches/100-drop_old_api.patch b/package/kernel/mwlwifi/patches/100-drop_old_api.patch
new file mode 100644
index 0000000..1ab1615
--- /dev/null
+++ b/package/kernel/mwlwifi/patches/100-drop_old_api.patch
@@ -0,0 +1,36 @@
+--- a/main.c
++++ b/main.c
+@@ -414,11 +414,7 @@ static void mwl_set_ht_caps(struct mwl_p
+ band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
+ band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
+
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
+- hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+-#else
+ ieee80211_hw_set(hw, AMPDU_AGGREGATION);
+-#endif
+ band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+ band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_4;
+
+@@ -520,21 +516,13 @@ static int mwl_wl_init(struct mwl_priv *
+ hw->queues = SYSADPT_TX_WMM_QUEUES;
+
+ /* Set rssi values to dBm */
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
+- hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL;
+-#else
+ ieee80211_hw_set(hw, SIGNAL_DBM);
+ ieee80211_hw_set(hw, HAS_RATE_CONTROL);
+-#endif
+
+ /* Ask mac80211 not to trigger PS mode
+ * based on PM bit of incoming frames.
+ */
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
+- hw->flags |= IEEE80211_HW_AP_LINK_PS;
+-#else
+ ieee80211_hw_set(hw, AP_LINK_PS);
+-#endif
+
+ hw->vif_data_size = sizeof(struct mwl_vif);
+ hw->sta_data_size = sizeof(struct mwl_sta);
diff --git a/package/kernel/mwlwifi/patches/110-ampdu_api.patch b/package/kernel/mwlwifi/patches/110-ampdu_api.patch
new file mode 100644
index 0000000..5e52b09
--- /dev/null
+++ b/package/kernel/mwlwifi/patches/110-ampdu_api.patch
@@ -0,0 +1,11 @@
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -574,7 +574,7 @@ static int mwl_mac80211_ampdu_action(str
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta,
+- u16 tid, u16 *ssn, u8 buf_size)
++ u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
+ {
+ int rc = 0;
+ struct mwl_priv *priv = hw->priv;
diff --git a/package/kernel/om-watchdog/Makefile b/package/kernel/om-watchdog/Makefile
new file mode 100644
index 0000000..7d517a1
--- /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 0000000..d730c68
--- /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 0000000..c792968
--- /dev/null
+++ b/package/kernel/om-watchdog/files/om-watchdog.init
@@ -0,0 +1,36 @@
+#!/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"|"om2p-hsv2")
+ service_start /sbin/om-watchdog 12
+ ;;
+ "om2pv2"|"om2p-lc")
+ service_start /sbin/om-watchdog 26
+ ;;
+ "om5p"|"om5p-an")
+ service_start /sbin/om-watchdog 11
+ ;;
+ "mr600v2")
+ service_start /sbin/om-watchdog 15
+ ;;
+ "mr900"|"mr900v2"|"mr1750")
+ service_start /sbin/om-watchdog 16
+ ;;
+ 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 0000000..315ec31
--- /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 0000000..b4d55d5
--- /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 0000000..1336726
--- /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 0000000..9a16e45
--- /dev/null
+++ b/package/kernel/rotary-gpio-custom/src/rotary-gpio-custom.c
@@ -0,0 +1,193 @@
+/*
+ * 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 0000000..e13ead5
--- /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 0000000..eeb0430
--- /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 0000000..2fc6f09
--- /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-gpio-custom/Makefile b/package/kernel/spi-gpio-custom/Makefile
new file mode 100644
index 0000000..3282f06
--- /dev/null
+++ b/package/kernel/spi-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:=spi-gpio-custom
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/spi-gpio-custom
+ SUBMENU:=SPI Support
+ TITLE:=Custom GPIO-based SPI device
+ DEPENDS:=@GPIO_SUPPORT +kmod-spi-bitbang +kmod-spi-gpio +kmod-spi-dev
+ FILES:=$(PKG_BUILD_DIR)/spi-gpio-custom.ko
+ KCONFIG:=
+endef
+
+define KernelPackage/spi-gpio-custom/description
+ Kernel module for register a custom spi-gpio platform device.
+endef
+
+EXTRA_KCONFIG:= \
+ CONFIG_SPI_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,spi-gpio-custom))
diff --git a/package/kernel/spi-gpio-custom/src/Kconfig b/package/kernel/spi-gpio-custom/src/Kconfig
new file mode 100644
index 0000000..5e15f05
--- /dev/null
+++ b/package/kernel/spi-gpio-custom/src/Kconfig
@@ -0,0 +1,14 @@
+config SPI_GPIO_CUSTOM
+ tristate "Custom GPIO-based SPI driver"
+ depends on GENERIC_GPIO
+ select SPI_GPIO
+ help
+ This is an SPI driver to register 1 to 4 custom SPI buses using
+ GPIO lines. Each bus can have up to 8 slaves.
+ The devices will be exposed to userspace as /dev/spidevX.X
+
+ This module is maily intended to interface microcontrollers
+ and other SPI devices without a specific kernel driver.
+
+ This support is also available as a module. If so, the module
+ will be called spi-gpio-custom.
diff --git a/package/kernel/spi-gpio-custom/src/Makefile b/package/kernel/spi-gpio-custom/src/Makefile
new file mode 100644
index 0000000..cf8c55f
--- /dev/null
+++ b/package/kernel/spi-gpio-custom/src/Makefile
@@ -0,0 +1 @@
+obj-${CONFIG_SPI_GPIO_CUSTOM} += spi-gpio-custom.o \ No newline at end of file
diff --git a/package/kernel/spi-gpio-custom/src/spi-gpio-custom.c b/package/kernel/spi-gpio-custom/src/spi-gpio-custom.c
new file mode 100644
index 0000000..a4f93c6
--- /dev/null
+++ b/package/kernel/spi-gpio-custom/src/spi-gpio-custom.c
@@ -0,0 +1,365 @@
+/*
+ * Custom GPIO-based SPI driver
+ *
+ * Copyright (C) 2013 Marco Burato <zmaster.adsl@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.
+ *
+ * Based on i2c-gpio-custom 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>,<sck>,<mosi>,<miso>,<mode1>,<maxfreq1>,<cs1>,...
+ *
+ * where:
+ *
+ * <id> ID to used as device_id for the corresponding bus (required)
+ * <sck> GPIO pin ID to be used for bus SCK (required)
+ * <mosi> GPIO pin ID to be used for bus MOSI (required*)
+ * <miso> GPIO pin ID to be used for bus MISO (required*)
+ * <modeX> Mode configuration for slave X in the bus (required)
+ * (see /include/linux/spi/spi.h)
+ * <maxfreqX> Maximum clock frequency in Hz for slave X in the bus (required)
+ * <csX> GPIO pin ID to be used for slave X CS (required**)
+ *
+ * Notes:
+ * * If a signal is not used (for example there is no MISO) you need
+ * to set the GPIO pin ID for that signal to an invalid value.
+ * ** If you only have 1 slave in the bus with no CS, you can omit the
+ * <cs1> param or set it to an invalid GPIO id to disable it. When
+ * you have 2 or more slaves, they must all have a valid CS.
+ *
+ * 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:
+ *
+ * spi-gpio-custom.bus0
+ * spi-gpio-custom.bus1
+ * spi-gpio-custom.bus2
+ * spi-gpio-custom.bus3
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+
+#define DRV_NAME "spi-gpio-custom"
+#define DRV_DESC "Custom GPIO-based SPI driver"
+#define DRV_VERSION "0.1"
+
+#define PFX DRV_NAME ": "
+
+#define BUS_PARAM_ID 0
+#define BUS_PARAM_SCK 1
+#define BUS_PARAM_MOSI 2
+#define BUS_PARAM_MISO 3
+#define BUS_PARAM_MODE1 4
+#define BUS_PARAM_MAXFREQ1 5
+#define BUS_PARAM_CS1 6
+
+#define BUS_SLAVE_COUNT_MAX 8
+#define BUS_PARAM_REQUIRED 6
+#define BUS_PARAM_PER_SLAVE 3
+#define BUS_PARAM_COUNT (4+BUS_PARAM_PER_SLAVE*BUS_SLAVE_COUNT_MAX)
+#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,sck,mosi,miso,mode1,maxfreq1[,cs1,mode2,maxfreq2,cs2,...]"
+
+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 spi_gpio_custom_cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < nr_devices; i++)
+ if (devices[i])
+ platform_device_unregister(devices[i]);
+}
+
+static int spi_gpio_custom_get_slave_mode(unsigned int id,
+ unsigned int *params,
+ int slave_index)
+{
+ int param_index;
+
+ param_index = BUS_PARAM_MODE1+slave_index*BUS_PARAM_PER_SLAVE;
+ if (param_index >= bus_nump[id])
+ return -1;
+
+ return params[param_index];
+}
+static int spi_gpio_custom_get_slave_maxfreq(unsigned int id,
+ unsigned int *params,
+ int slave_index)
+{
+ int param_index;
+
+ param_index = BUS_PARAM_MAXFREQ1+slave_index*BUS_PARAM_PER_SLAVE;
+ if (param_index >= bus_nump[id])
+ return -1;
+
+ return params[param_index];
+}
+static int spi_gpio_custom_get_slave_cs(unsigned int id,
+ unsigned int *params,
+ int slave_index)
+{
+ int param_index;
+
+ param_index = BUS_PARAM_CS1+slave_index*BUS_PARAM_PER_SLAVE;
+ if (param_index >= bus_nump[id])
+ return -1;
+ if (!gpio_is_valid(params[param_index]))
+ return -1;
+
+ return params[param_index];
+}
+
+static int spi_gpio_custom_check_params(unsigned int id, unsigned int *params)
+{
+ int i;
+ struct spi_master *master;
+
+ if (bus_nump[id] < BUS_PARAM_REQUIRED) {
+ printk(KERN_ERR PFX "not enough values for parameter bus%d\n",
+ id);
+ return -EINVAL;
+ }
+
+ if (bus_nump[id] > (1+BUS_PARAM_CS1)) {
+ /* more than 1 device: check CS GPIOs */
+ for (i = 0; i < BUS_SLAVE_COUNT_MAX; i++) {
+ /* no more slaves? */
+ if (spi_gpio_custom_get_slave_mode(id, params, i) < 0)
+ break;
+
+ if (spi_gpio_custom_get_slave_cs(id, params, i) < 0) {
+ printk(KERN_ERR PFX "invalid/missing CS gpio for slave %d on bus %d\n",
+ i, params[BUS_PARAM_ID]);
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (!gpio_is_valid(params[BUS_PARAM_SCK])) {
+ printk(KERN_ERR PFX "invalid SCK gpio for bus %d\n",
+ params[BUS_PARAM_ID]);
+ return -EINVAL;
+ }
+
+ master = spi_busnum_to_master(params[BUS_PARAM_ID]);
+ if (master) {
+ spi_master_put(master);
+ printk(KERN_ERR PFX "bus %d already exists\n",
+ params[BUS_PARAM_ID]);
+ return -EEXIST;
+ }
+
+ return 0;
+}
+
+static int __init spi_gpio_custom_add_one(unsigned int id, unsigned int *params)
+{
+ struct platform_device *pdev;
+ struct spi_gpio_platform_data pdata;
+ int i;
+ int num_cs;
+ int err;
+ struct spi_master *master;
+ struct spi_device *slave;
+ struct spi_board_info slave_info;
+ int mode, maxfreq, cs;
+
+
+ if (!bus_nump[id])
+ return 0;
+
+ err = spi_gpio_custom_check_params(id, params);
+ if (err)
+ goto err;
+
+ /* Create BUS device node */
+
+ pdev = platform_device_alloc("spi_gpio", params[BUS_PARAM_ID]);
+ if (!pdev) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ num_cs = 0;
+ for (i = 0; i < BUS_SLAVE_COUNT_MAX; i++) {
+ /* no more slaves? */
+ if (spi_gpio_custom_get_slave_mode(id, params, i) < 0)
+ break;
+
+ if (spi_gpio_custom_get_slave_cs(id, params, i) >= 0)
+ num_cs++;
+ }
+ if (num_cs == 0) {
+ /*
+ * Even if no CS is used, spi modules expect
+ * at least 1 (unused)
+ */
+ num_cs = 1;
+ }
+
+ pdata.sck = params[BUS_PARAM_SCK];
+ pdata.mosi = gpio_is_valid(params[BUS_PARAM_MOSI])
+ ? params[BUS_PARAM_MOSI]
+ : SPI_GPIO_NO_MOSI;
+ pdata.miso = gpio_is_valid(params[BUS_PARAM_MISO])
+ ? params[BUS_PARAM_MISO]
+ : SPI_GPIO_NO_MISO;
+ pdata.num_chipselect = num_cs;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err) {
+ platform_device_put(pdev);
+ goto err;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ printk(KERN_ERR PFX "platform_device_add failed with return code %d\n",
+ err);
+ platform_device_put(pdev);
+ goto err;
+ }
+
+ /* Register SLAVE devices */
+
+ for (i = 0; i < BUS_SLAVE_COUNT_MAX; i++) {
+ mode = spi_gpio_custom_get_slave_mode(id, params, i);
+ maxfreq = spi_gpio_custom_get_slave_maxfreq(id, params, i);
+ cs = spi_gpio_custom_get_slave_cs(id, params, i);
+
+ /* no more slaves? */
+ if (mode < 0)
+ break;
+
+ memset(&slave_info, 0, sizeof(slave_info));
+ strcpy(slave_info.modalias, "spidev");
+ slave_info.controller_data = (void *)((cs >= 0)
+ ? cs
+ : SPI_GPIO_NO_CHIPSELECT);
+ slave_info.max_speed_hz = maxfreq;
+ slave_info.bus_num = params[BUS_PARAM_ID];
+ slave_info.chip_select = i;
+ slave_info.mode = mode;
+
+ master = spi_busnum_to_master(params[BUS_PARAM_ID]);
+ if (!master) {
+ printk(KERN_ERR PFX "unable to get master for bus %d\n",
+ params[BUS_PARAM_ID]);
+ err = -EINVAL;
+ goto err_unregister;
+ }
+ slave = spi_new_device(master, &slave_info);
+ spi_master_put(master);
+ if (!slave) {
+ printk(KERN_ERR PFX "unable to create slave %d for bus %d\n",
+ i, params[BUS_PARAM_ID]);
+ /* Will most likely fail due to unsupported mode bits */
+ err = -EINVAL;
+ goto err_unregister;
+ }
+ }
+
+ devices[nr_devices++] = pdev;
+
+ return 0;
+
+err_unregister:
+ platform_device_unregister(pdev);
+err:
+ return err;
+}
+
+static int __init spi_gpio_custom_probe(void)
+{
+ int err;
+
+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
+
+ err = spi_gpio_custom_add_one(0, bus0);
+ if (err)
+ goto err;
+
+ err = spi_gpio_custom_add_one(1, bus1);
+ if (err)
+ goto err;
+
+ err = spi_gpio_custom_add_one(2, bus2);
+ if (err)
+ goto err;
+
+ err = spi_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:
+ spi_gpio_custom_cleanup();
+ return err;
+}
+
+#ifdef MODULE
+static int __init spi_gpio_custom_init(void)
+{
+ return spi_gpio_custom_probe();
+}
+module_init(spi_gpio_custom_init);
+
+static void __exit spi_gpio_custom_exit(void)
+{
+ spi_gpio_custom_cleanup();
+}
+module_exit(spi_gpio_custom_exit);
+#else
+subsys_initcall(spi_gpio_custom_probe);
+#endif /* MODULE*/
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Marco Burato <zmaster.adsl@gmail.com>");
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_VERSION(DRV_VERSION);
diff --git a/package/kernel/trelay/Makefile b/package/kernel/trelay/Makefile
new file mode 100644
index 0000000..2727ea5
--- /dev/null
+++ b/package/kernel/trelay/Makefile
@@ -0,0 +1,54 @@
+#
+# 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/conffiles
+/etc/config/trelay
+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 0000000..eb05013
--- /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 0000000..31f7378
--- /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 0000000..e705275
--- /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
+
+ ip link set dev "$dev1" up
+ ip link set dev "$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 0000000..e6bde89
--- /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 0000000..8fa4374
--- /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 0000000..bf50d1a
--- /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 0000000..74b9226
--- /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 0000000..6a52743
--- /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 0000000..004c924
--- /dev/null
+++ b/package/kernel/w1-gpio-custom/src/w1-gpio-custom.c
@@ -0,0 +1,190 @@
+/*
+ * 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;
+ pdata.ext_pullup_enable_pin = -EINVAL;
+
+ 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 0000000..a63180b
--- /dev/null
+++ b/package/kernel/wrt55agv2-spidevs/Makefile
@@ -0,0 +1,43 @@
+#
+# 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_ath25 +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
+
+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,wrt55agv2-spidevs))
diff --git a/package/kernel/wrt55agv2-spidevs/src/Kconfig b/package/kernel/wrt55agv2-spidevs/src/Kconfig
new file mode 100644
index 0000000..75e8242
--- /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 0000000..76b0939
--- /dev/null
+++ b/package/kernel/wrt55agv2-spidevs/src/Makefile
@@ -0,0 +1 @@
+obj-m += wrt55agv2_spidevs.o
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 0000000..dfb7f6a
--- /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");
+