From 83f33fa122351e113f2e7c9a8a79953cd4d73681 Mon Sep 17 00:00:00 2001 From: juanesf Date: Thu, 7 Aug 2025 16:17:15 -0400 Subject: [PATCH] Migrate Radxa Cubie A5E to mainline 6.16 (#8447) * migrate u-boot and kernel to mainline * Add patches for 6.17 * fix compile for patches addes * Orderer patches, switch kernel config to sunxi64, recreate some patches for fix build * Update linux-sunxi64-edge.config after pm-domain & sun55i-gmac200 activate * enable wifi and bluetooth * revert linux-sunxi64-edge.config - Revert linux-sunxi64-edge.config - Add modules: CONFIG_IOMMUFD, CONFIG_SUN50I_IOMMU, CONFIG_SUN55I_PCK600. * drop sunxi-dev-6.14 and cleanup involved patches * Update radxa-cubie-a5e.csc make change proposed by igorpecovnik --- config/boards/radxa-cubie-a5e.csc | 47 +- config/kernel/linux-sunxi64-edge.config | 3 + config/sources/families/sun55iw3.conf | 16 +- .../00-Add-leds-Radxa-Cubie-A5E.patch | 44 + .../01-Add-wifi-to-Radxa-Cubie-A5E.patch | 78 + ...dts-allwinner-a523-add-Mali-GPU-node.patch | 42 + ...23-Add-power-controller-device-nodes.patch | 57 + ...64-dts-allwinner-a523-Add-UART1-pins.patch | 41 + ...3-Move-mmc-nodes-to-correct-position.patch | 164 + ...Move-rgmii0-pins-to-correct-location.patch | 59 + ...e-a5e-Add-ethernet-PHY-reset-setting.patch | 29 + ...ubie-a5e-Enable-second-Ethernet-port.patch | 82 + ...allwinner-t527-Add-OrangePi-4A-board.patch | 441 + ...5i-a523-r-ccu-Add-missing-PPU0-reset.patch | 30 + ...n8i-emac-Add-A523-GMAC200-compatible.patch | 134 + ...523-PPU-and-PCK600-power-controllers.patch | 76 + ...5i-a523-r-ccu-Add-missing-PPU0-reset.patch | 29 + ...Set-explicit-ID-for-AXP313-regulator.patch | 38 + ...lator-cell-if-no-IRQ-line-is-present.patch | 49 + ...d-support-for-Allwinner-A523-GMAC200.patch | 227 + ...nner-A523's PCK-600-power-controller.patch | 278 + ...in-sunxi-sun20i-ppu-add-A523-support.patch | 48 + ...20x-force-polyphase-setup-for-axp323.patch | 135 + ...20-soc-sunxi-sram-add-entry-for-a523.patch | 42 + ...sunxi-sram-register-regmap-as-syscon.patch | 44 + ...-a523-enable-Mali-GPU-for-all-boards.patch | 96 + ...a523-Add-GMAC200-ethernet-controller.patch | 94 + .../24-Enable-uart1-on-Radxa-Cubie-A5E.patch | 48 + ...ort-aic8800-sdio-v2024_0327_3561b08f.patch | 84726 ---------------- ...xes-aic8800-sdio-v2024_0327_3561b08f.patch | 388 - ...mfd-axp20x-Allow-multiple-regulators.patch | 60 - ...et-phy-add-Maxio-MAE0621A-phy-driver.patch | 368 - ...hernet-allwinner-add-gmac200-support.patch | 3238 - ...-ethernet-allwinner-add-gmac-support.patch | 4470 - ...tsi-allwinner-add-gmac1-in-A523-dtsi.patch | 99 - ...tsi-allwinner-add-gmac0-in-A523-dtsi.patch | 69 - ...sun8i-Add-initial-support-for-A523-T.patch | 307 - .../sunxi-dev-6.14/update-cubie-a5e-dts.patch | 161 - 38 files changed, 2455 insertions(+), 93902 deletions(-) create mode 100644 patch/kernel/archive/sunxi-6.16/00-Add-leds-Radxa-Cubie-A5E.patch create mode 100644 patch/kernel/archive/sunxi-6.16/01-Add-wifi-to-Radxa-Cubie-A5E.patch create mode 100644 patch/kernel/archive/sunxi-6.16/02-arm64-dts-allwinner-a523-add-Mali-GPU-node.patch create mode 100644 patch/kernel/archive/sunxi-6.16/03-arm64-dts-allwinner-a523-Add-power-controller-device-nodes.patch create mode 100644 patch/kernel/archive/sunxi-6.16/04-arm64-dts-allwinner-a523-Add-UART1-pins.patch create mode 100644 patch/kernel/archive/sunxi-6.16/05-arm64-dts-allwinner-a523-Move-mmc-nodes-to-correct-position.patch create mode 100644 patch/kernel/archive/sunxi-6.16/06-arm64-dts-allwinner-a523-Move-rgmii0-pins-to-correct-location.patch create mode 100644 patch/kernel/archive/sunxi-6.16/07-arm64-dts-allwinner-a527-cubie-a5e-Add-ethernet-PHY-reset-setting.patch create mode 100644 patch/kernel/archive/sunxi-6.16/08-arm64-dts-allwinner-a527-cubie-a5e-Enable-second-Ethernet-port.patch create mode 100644 patch/kernel/archive/sunxi-6.16/09-arm64-dts-allwinner-t527-Add-OrangePi-4A-board.patch create mode 100644 patch/kernel/archive/sunxi-6.16/10-clk-sunxi-ng-sun55i-a523-r-ccu-Add-missing-PPU0-reset.patch create mode 100644 patch/kernel/archive/sunxi-6.16/11-dt-bindings-net-sun8i-emac-Add-A523-GMAC200-compatible.patch create mode 100644 patch/kernel/archive/sunxi-6.16/12-dt-bindings-power-Add-A523-PPU-and-PCK600-power-controllers.patch create mode 100644 patch/kernel/archive/sunxi-6.16/13-dt-bindings-reset-sun55i-a523-r-ccu-Add-missing-PPU0-reset.patch create mode 100644 patch/kernel/archive/sunxi-6.16/14-mfd-axp20x-Set-explicit-ID-for-AXP313-regulator.patch create mode 100644 patch/kernel/archive/sunxi-6.16/15-mfd-axp20x-set-explicit-ID-for-regulator-cell-if-no-IRQ-line-is-present.patch create mode 100644 patch/kernel/archive/sunxi-6.16/16-net-stmmac-Add-support-for-Allwinner-A523-GMAC200.patch create mode 100644 patch/kernel/archive/sunxi-6.16/17-pmdomain-sunxi-add-driver-for-Allwinner-A523's PCK-600-power-controller.patch create mode 100644 patch/kernel/archive/sunxi-6.16/18-pmdomain-sunxi-sun20i-ppu-add-A523-support.patch create mode 100644 patch/kernel/archive/sunxi-6.16/19-regulator-axp20x-force-polyphase-setup-for-axp323.patch create mode 100644 patch/kernel/archive/sunxi-6.16/20-soc-sunxi-sram-add-entry-for-a523.patch create mode 100644 patch/kernel/archive/sunxi-6.16/21-soc-sunxi-sram-register-regmap-as-syscon.patch create mode 100644 patch/kernel/archive/sunxi-6.16/22-arm64-dts-allwinner-a523-enable-Mali-GPU-for-all-boards.patch create mode 100644 patch/kernel/archive/sunxi-6.16/23-arm64-dts-allwinner-a523-Add-GMAC200-ethernet-controller.patch create mode 100644 patch/kernel/archive/sunxi-6.16/24-Enable-uart1-on-Radxa-Cubie-A5E.patch delete mode 100644 patch/kernel/archive/sunxi-dev-6.14/0801-net-wireless-backport-aic8800-sdio-v2024_0327_3561b08f.patch delete mode 100644 patch/kernel/archive/sunxi-dev-6.14/0802-net-wireless-mm2-fixes-aic8800-sdio-v2024_0327_3561b08f.patch delete mode 100644 patch/kernel/archive/sunxi-dev-6.14/1103-mfd-axp20x-Allow-multiple-regulators.patch delete mode 100644 patch/kernel/archive/sunxi-dev-6.14/1137-net-phy-add-Maxio-MAE0621A-phy-driver.patch delete mode 100644 patch/kernel/archive/sunxi-dev-6.14/1139-net-ethernet-allwinner-add-gmac200-support.patch delete mode 100644 patch/kernel/archive/sunxi-dev-6.14/1140-net-ethernet-allwinner-add-gmac-support.patch delete mode 100644 patch/kernel/archive/sunxi-dev-6.14/1151-arm64-dtsi-allwinner-add-gmac1-in-A523-dtsi.patch delete mode 100644 patch/kernel/archive/sunxi-dev-6.14/1152-arm64-dtsi-allwinner-add-gmac0-in-A523-dtsi.patch delete mode 100644 patch/kernel/archive/sunxi-dev-6.14/1208-thermal-drivers-sun8i-Add-initial-support-for-A523-T.patch delete mode 100644 patch/kernel/archive/sunxi-dev-6.14/update-cubie-a5e-dts.patch diff --git a/config/boards/radxa-cubie-a5e.csc b/config/boards/radxa-cubie-a5e.csc index aebd76142..95e4cd2cd 100644 --- a/config/boards/radxa-cubie-a5e.csc +++ b/config/boards/radxa-cubie-a5e.csc @@ -2,10 +2,10 @@ BOARD_NAME="radxa cubie a5e" BOARDFAMILY="sun55iw3" BOARD_MAINTAINER="" -BOOTCONFIG="radxa-a5e_defconfig" +BOOTCONFIG="radxa-cubie-a5e_defconfig" OVERLAY_PREFIX="sun55i-a527" #BOOT_LOGO="desktop" -KERNEL_TARGET="dev" +KERNEL_TARGET="edge" BOOT_FDT_FILE="dtb/allwinner/sun55i-a527-radxa-a5e.dtb" IMAGE_PARTITION_TABLE="gpt" #IMAGE_PARTITION_TABLE="msdos" @@ -14,9 +14,42 @@ BOOTSTART="1" BOOTSIZE="512" ROOTSTART="513" -function post_family_tweaks__radxa_cubie-a5e() { - display_alert "Applying wifi firmware" - pushd "$SDCARD/lib/firmware" - ln -s "aic8800/SDIO/aic8800D80" "aic8800_sdio" # use armbian-firmware - popd +PACKAGE_LIST_BOARD="rfkill bluetooth bluez bluez-tools" + +# AIC8800 +AIC8800_TYPE="sdio" +enable_extension "radxa-aic8800" + +# AIC8800 Wireless +function post_family_tweaks_bsp__aic8800_wireless() { + display_alert "$BOARD" "Installing AIC8800 Tweaks" "info" + mkdir -p "${destination}"/etc/modprobe.d + mkdir -p "${destination}"/etc/modules-load.d + # Add wireless conf + cat > "${destination}"/etc/modprobe.d/aic8800-wireless.conf <<- EOT + options aic8800_fdrv_sdio aicwf_dbg_level=0 custregd=0 ps_on=0 + #options aic8800_bsp_sdio aic_fw_path=/lib/firmware/aic8800_fw/SDIO/aic8800 + EOT + # Add needed bluetooth modules + cat > "${destination}"/etc/modules-load.d/aic8800-btlpm.conf <<- EOT + hidp + rfcomm + bnep + aic8800_btlpm_sdio + EOT + # Add AIC8800 Bluetooth Service and Script + if [[ -d "$SRC/packages/bsp/aic8800" ]]; then + mkdir -p "${destination}"/etc/systemd/system + mkdir -p "${destination}"/usr/bin + cp -f "$SRC/packages/bsp/aic8800/aic-bluetooth" "${destination}"/usr/bin + chmod +x "${destination}"/usr/bin/aic-bluetooth + cp -f "$SRC/packages/bsp/aic8800/aic-bluetooth.service" "${destination}"/etc/systemd/system + fi } + +# Enable AIC8800 Bluetooth Service +function post_family_tweaks__enable_aic8800_bluetooth_service() { + display_alert "$BOARD" "Enabling AIC8800 Bluetooth Service" "info" + chroot_sdcard systemctl --no-reload enable aic-bluetooth.service +} + diff --git a/config/kernel/linux-sunxi64-edge.config b/config/kernel/linux-sunxi64-edge.config index baf93745f..0d8c9a9d6 100644 --- a/config/kernel/linux-sunxi64-edge.config +++ b/config/kernel/linux-sunxi64-edge.config @@ -2234,10 +2234,13 @@ CONFIG_SUN50I_IOMMU=y CONFIG_ARM_SMMU=m CONFIG_ARM_SMMU_V3=m CONFIG_ARM_SMMU_V3_SVA=y +CONFIG_IOMMUFD=m +CONFIG_SUN50I_IOMMU=y CONFIG_REMOTEPROC=y CONFIG_REMOTEPROC_CDEV=y CONFIG_SUN20I_PPU=y CONFIG_SUN50I_H6_PRCM_PPU=m +CONFIG_SUN55I_PCK600=y CONFIG_DEVFREQ_GOV_PERFORMANCE=y CONFIG_DEVFREQ_GOV_POWERSAVE=y CONFIG_DEVFREQ_GOV_USERSPACE=y diff --git a/config/sources/families/sun55iw3.conf b/config/sources/families/sun55iw3.conf index 36244f001..89cad6234 100644 --- a/config/sources/families/sun55iw3.conf +++ b/config/sources/families/sun55iw3.conf @@ -13,23 +13,21 @@ declare -g ATF_TARGET_MAP="PLAT=sun55i_a523 DEBUG=1 bl31;;build/sun55i_a523/debu declare -g ATFBRANCH="branch:a523" declare -g BOOTSCRIPT='boot-sun50i-next.cmd:boot.cmd' declare -g BOOTDELAY=1 -declare -g BOOTSOURCE='https://github.com/jernejsk/u-boot/' +declare -g BOOTSOURCE='https://github.com/u-boot/u-boot.git' declare -g BOOTPATCHDIR="sunxi-dev-${BOOTPATCHDIR:-"u-boot-a523"}" -declare -g BOOTBRANCH="${BOOTBRANCH:-"branch:a523"}" +declare -g BOOTBRANCH="${BOOTBRANCH:-"branch:master"}" declare -g BOOTENV_FILE='sunxi.txt' declare -g UBOOT_TARGET_MAP="${UBOOT_TARGET_MAP:-BINMAN_ALLOW_MISSING=1;;u-boot-sunxi-with-spl.bin}" declare -g OVERLAY_DIR="/boot/dtb/allwinner/overlay" -declare -g LINUXFAMILY="sun55iw3" +declare -g LINUXFAMILY="sunxi64" case "${BRANCH}" in - dev) - declare -g KERNELSOURCE='https://github.com/apritzel/linux' - declare -g KERNELBRANCH='branch:a523-v3' - declare -g KERNEL_MAJOR_MINOR="6.14" # Major and minor versions of this kernel. - KERNELPATCHDIR="archive/sunxi-dev-${KERNEL_MAJOR_MINOR}" + edge) + declare -g KERNEL_MAJOR_MINOR="6.16" # Major and minor versions of this kernel. + declare -g KERNELBRANCH="tag:v6.16" + KERNELPATCHDIR="archive/sunxi-${KERNEL_MAJOR_MINOR}" ;; - esac family_tweaks() { diff --git a/patch/kernel/archive/sunxi-6.16/00-Add-leds-Radxa-Cubie-A5E.patch b/patch/kernel/archive/sunxi-6.16/00-Add-leds-Radxa-Cubie-A5E.patch new file mode 100644 index 000000000..71f4db1c1 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/00-Add-leds-Radxa-Cubie-A5E.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Juan Sanchez +Date: Sat, 14 Jun 2025 19:07:52 -0400 +Subject: Add leds to Radxa Cubie A5E + +Signed-off-by: Juan Sanchez +--- + arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts | 16 ++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +index 0f58d92a6adc..1c56306dffa1 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +@@ -18,10 +18,26 @@ aliases { + + chosen { + stdout-path = "serial0:115200n8"; + }; + ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-0 { ++ label = "radxa:green:power"; ++ gpios = <&r_pio 0 4 GPIO_ACTIVE_LOW>; /* PL4 */ ++ linux,default-trigger = "heartbeat"; ++ }; ++ ++ led-1 { ++ label = "radxa:blue:user"; ++ gpios = <&r_pio 0 5 GPIO_ACTIVE_LOW>; /* PL5 */ ++ linux,default-trigger = "default-on"; ++ }; ++ }; ++ + ext_osc32k: ext-osc32k-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "ext_osc32k"; +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-6.16/01-Add-wifi-to-Radxa-Cubie-A5E.patch b/patch/kernel/archive/sunxi-6.16/01-Add-wifi-to-Radxa-Cubie-A5E.patch new file mode 100644 index 000000000..ce6ab963e --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/01-Add-wifi-to-Radxa-Cubie-A5E.patch @@ -0,0 +1,78 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Juan Sanchez +Date: Fri, 4 Jul 2025 15:17:54 -0400 +Subject: Add wifi (mmc1) to Radxa Cubie A5E + +Signed-off-by: Juan Sanchez +--- + arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts | 28 ++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +index 1c56306dffa1..d9bbfb916090 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +@@ -11,10 +11,11 @@ / { + model = "Radxa Cubie A5E"; + compatible = "radxa,cubie-a5e", "allwinner,sun55i-a527"; + + aliases { + ethernet0 = &gmac0; ++ ethernet2 = &sdio_wifi; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; +@@ -41,10 +42,20 @@ ext_osc32k: ext-osc32k-clk { + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "ext_osc32k"; + }; + ++ reg_3v3_wifi: 3v3-wifi { ++ compatible = "regulator-fixed"; ++ regulator-name = "3v3-wifi"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <®_vcc5v>; ++ gpio = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */ ++ enable-active-high; ++ }; ++ + reg_vcc5v: vcc5v { + /* board wide 5V supply from the USB-C connector */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; +@@ -94,10 +105,27 @@ &mmc0 { + cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */ + bus-width = <4>; + status = "okay"; + }; + ++&mmc1_pins { ++ drive-strength = <40>; ++}; ++ ++&mmc1 { ++ bus-width = <4>; ++ vmmc-supply = <®_3v3_wifi>; ++ non-removable; ++ // todo: investigate why clock above 40MHz makes data errors ++ max-frequency = <35000000>; ++ status = "okay"; ++ ++ sdio_wifi: wifi@1 { ++ reg = <1>; ++ }; ++}; ++ + &ohci0 { + status = "okay"; + }; + + &ohci1 { +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-6.16/02-arm64-dts-allwinner-a523-add-Mali-GPU-node.patch b/patch/kernel/archive/sunxi-6.16/02-arm64-dts-allwinner-a523-add-Mali-GPU-node.patch new file mode 100644 index 000000000..54b789c8b --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/02-arm64-dts-allwinner-a523-add-Mali-GPU-node.patch @@ -0,0 +1,42 @@ +From: Mikhail Kalashnikov + +The Allwinner A523 SoC features the Mali-G57 MC1 GPU, which belongs +to the Mali Valhall (v9) family. There is a power domain specifically +for this GPU that needs to be enabled to utilize it. + +To enable in a specific device, we need to enable the gpu node and specify +the “mali-supply” regulator additionally in the device tree. + +Signed-off-by: Mikhail Kalashnikov +--- + arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +index dd6fa22f9..d3528d498 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +@@ -108,6 +108,21 @@ soc { + #size-cells = <1>; + ranges = <0x0 0x0 0x0 0x40000000>; + ++ gpu: gpu@1800000 { ++ compatible = "allwinner,sun55i-a523-mali", ++ "arm,mali-valhall-jm"; ++ reg = <0x1800000 0x10000>; ++ interrupts = , ++ , ++ ; ++ interrupt-names = "job", "mmu", "gpu"; ++ clocks = <&ccu CLK_GPU>, <&ccu CLK_BUS_GPU>; ++ clock-names = "core", "bus"; ++ power-domains = <&pck600 PD_GPU>; ++ resets = <&ccu RST_BUS_GPU>; ++ status = "disabled"; ++ }; ++ + pio: pinctrl@2000000 { + compatible = "allwinner,sun55i-a523-pinctrl"; + reg = <0x2000000 0x800>; +-- +2.50.0 diff --git a/patch/kernel/archive/sunxi-6.16/03-arm64-dts-allwinner-a523-Add-power-controller-device-nodes.patch b/patch/kernel/archive/sunxi-6.16/03-arm64-dts-allwinner-a523-Add-power-controller-device-nodes.patch new file mode 100644 index 000000000..f986acfa9 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/03-arm64-dts-allwinner-a523-Add-power-controller-device-nodes.patch @@ -0,0 +1,57 @@ +From: Chen-Yu Tsai + +The A523 SoC family has two power controllers, one based on the existing +PPU, and one newer one based on ARM's PCK-600. + +Add device nodes for both of them. + +Signed-off-by: Chen-Yu Tsai +--- + arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +index 6f62201fd739..255e0ef98219 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +@@ -7,6 +7,8 @@ + #include + #include + #include ++#include ++#include + + / { + interrupt-parent = <&gic>; +@@ -576,6 +578,14 @@ mdio0: mdio { + }; + }; + ++ ppu: power-controller@7001400 { ++ compatible = "allwinner,sun55i-a523-ppu"; ++ reg = <0x07001400 0x400>; ++ clocks = <&r_ccu CLK_BUS_R_PPU1>; ++ resets = <&r_ccu RST_BUS_R_PPU1>; ++ #power-domain-cells = <1>; ++ }; ++ + r_ccu: clock-controller@7010000 { + compatible = "allwinner,sun55i-a523-r-ccu"; + reg = <0x7010000 0x250>; +@@ -622,6 +632,14 @@ r_i2c_pins: r-i2c-pins { + }; + }; + ++ pck600: power-controller@7060000 { ++ compatible = "allwinner,sun55i-a523-pck-600"; ++ reg = <0x07060000 0x8000>; ++ clocks = <&r_ccu CLK_BUS_R_PPU0>; ++ resets = <&r_ccu RST_BUS_R_PPU0>; ++ #power-domain-cells = <1>; ++ }; ++ + r_i2c0: i2c@7081400 { + compatible = "allwinner,sun55i-a523-i2c", + "allwinner,sun8i-v536-i2c", +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/04-arm64-dts-allwinner-a523-Add-UART1-pins.patch b/patch/kernel/archive/sunxi-6.16/04-arm64-dts-allwinner-a523-Add-UART1-pins.patch new file mode 100644 index 000000000..69210645f --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/04-arm64-dts-allwinner-a523-Add-UART1-pins.patch @@ -0,0 +1,41 @@ +From: Chen-Yu Tsai + +UART1 is normally used to connect to the Bluetooth side of a Broadcom +WiFi+BT combo chip. The connection uses 4 pins. + +Add pinmux nodes for UART1, one for the RX/TX pins, and one for the +RTS/CTS pins. + +Reviewed-by: Andre Przywara +Signed-off-by: Chen-Yu Tsai +--- + arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +index 4839411e51cf..cf0bc39aab04 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +@@ -168,6 +168,20 @@ uart0_pb_pins: uart0-pb-pins { + allwinner,pinmux = <2>; + function = "uart0"; + }; ++ ++ /omit-if-no-ref/ ++ uart1_pins: uart1-pins { ++ pins = "PG6", "PG7"; ++ function = "uart1"; ++ allwinner,pinmux = <2>; ++ }; ++ ++ /omit-if-no-ref/ ++ uart1_rts_cts_pins: uart1-rts-cts-pins { ++ pins = "PG8", "PG9"; ++ function = "uart1"; ++ allwinner,pinmux = <2>; ++ }; + }; + + ccu: clock-controller@2001000 { +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/05-arm64-dts-allwinner-a523-Move-mmc-nodes-to-correct-position.patch b/patch/kernel/archive/sunxi-6.16/05-arm64-dts-allwinner-a523-Move-mmc-nodes-to-correct-position.patch new file mode 100644 index 000000000..8898c6bf3 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/05-arm64-dts-allwinner-a523-Move-mmc-nodes-to-correct-position.patch @@ -0,0 +1,164 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Juan Sanchez +Date: Sat, 5 Jul 2025 22:27:55 -0400 +Subject: From: Chen-Yu Tsai + +Signed-off-by: Juan Sanchez +--- + arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 124 +++++----- + 1 file changed, 63 insertions(+), 61 deletions(-) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +index 720580f9764c..979edfc79816 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +@@ -193,72 +193,11 @@ ccu: clock-controller@2001000 { + "iosc", "losc-fanout"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + +- mmc0: mmc@4020000 { +- compatible = "allwinner,sun55i-a523-mmc", +- "allwinner,sun20i-d1-mmc"; +- reg = <0x04020000 0x1000>; +- clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>; +- clock-names = "ahb", "mmc"; +- resets = <&ccu RST_BUS_MMC0>; +- reset-names = "ahb"; +- interrupts = ; +- pinctrl-names = "default"; +- pinctrl-0 = <&mmc0_pins>; +- status = "disabled"; +- +- max-frequency = <150000000>; +- cap-sd-highspeed; +- cap-mmc-highspeed; +- cap-sdio-irq; +- #address-cells = <1>; +- #size-cells = <0>; +- }; +- +- mmc1: mmc@4021000 { +- compatible = "allwinner,sun55i-a523-mmc", +- "allwinner,sun20i-d1-mmc"; +- reg = <0x04021000 0x1000>; +- clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>; +- clock-names = "ahb", "mmc"; +- resets = <&ccu RST_BUS_MMC1>; +- reset-names = "ahb"; +- interrupts = ; +- pinctrl-names = "default"; +- pinctrl-0 = <&mmc1_pins>; +- status = "disabled"; + +- max-frequency = <150000000>; +- cap-sd-highspeed; +- cap-mmc-highspeed; +- cap-sdio-irq; +- #address-cells = <1>; +- #size-cells = <0>; +- }; +- +- mmc2: mmc@4022000 { +- compatible = "allwinner,sun55i-a523-mmc", +- "allwinner,sun20i-d1-mmc"; +- reg = <0x04022000 0x1000>; +- clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>; +- clock-names = "ahb", "mmc"; +- resets = <&ccu RST_BUS_MMC2>; +- reset-names = "ahb"; +- interrupts = ; +- pinctrl-names = "default"; +- pinctrl-0 = <&mmc2_pins>; +- status = "disabled"; +- +- max-frequency = <150000000>; +- cap-sd-highspeed; +- cap-mmc-highspeed; +- cap-sdio-irq; +- #address-cells = <1>; +- #size-cells = <0>; +- }; + + wdt: watchdog@2050000 { + compatible = "allwinner,sun55i-a523-wdt"; + reg = <0x2050000 0x20>; + interrupts = ; +@@ -461,10 +400,73 @@ its: msi-controller@3440000 { + #msi-cells = <1>; + dma-noncoherent; + }; + }; + ++ mmc0: mmc@4020000 { ++ compatible = "allwinner,sun55i-a523-mmc", ++ "allwinner,sun20i-d1-mmc"; ++ reg = <0x04020000 0x1000>; ++ clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>; ++ clock-names = "ahb", "mmc"; ++ resets = <&ccu RST_BUS_MMC0>; ++ reset-names = "ahb"; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins>; ++ status = "disabled"; ++ ++ max-frequency = <150000000>; ++ cap-sd-highspeed; ++ cap-mmc-highspeed; ++ cap-sdio-irq; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ mmc1: mmc@4021000 { ++ compatible = "allwinner,sun55i-a523-mmc", ++ "allwinner,sun20i-d1-mmc"; ++ reg = <0x04021000 0x1000>; ++ clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>; ++ clock-names = "ahb", "mmc"; ++ resets = <&ccu RST_BUS_MMC1>; ++ reset-names = "ahb"; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc1_pins>; ++ status = "disabled"; ++ ++ max-frequency = <150000000>; ++ cap-sd-highspeed; ++ cap-mmc-highspeed; ++ cap-sdio-irq; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ mmc2: mmc@4022000 { ++ compatible = "allwinner,sun55i-a523-mmc", ++ "allwinner,sun20i-d1-mmc"; ++ reg = <0x04022000 0x1000>; ++ clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>; ++ clock-names = "ahb", "mmc"; ++ resets = <&ccu RST_BUS_MMC2>; ++ reset-names = "ahb"; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc2_pins>; ++ status = "disabled"; ++ ++ max-frequency = <150000000>; ++ cap-sd-highspeed; ++ cap-mmc-highspeed; ++ cap-sdio-irq; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ + usb_otg: usb@4100000 { + compatible = "allwinner,sun55i-a523-musb", + "allwinner,sun8i-a33-musb"; + reg = <0x4100000 0x400>; + interrupts = ; +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-6.16/06-arm64-dts-allwinner-a523-Move-rgmii0-pins-to-correct-location.patch b/patch/kernel/archive/sunxi-6.16/06-arm64-dts-allwinner-a523-Move-rgmii0-pins-to-correct-location.patch new file mode 100644 index 000000000..e8f89ca58 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/06-arm64-dts-allwinner-a523-Move-rgmii0-pins-to-correct-location.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Juan Sanchez +Date: Sat, 2 Aug 2025 00:22:05 -0400 +Subject: Subject: From: Chen-Yu Tsai + +Signed-off-by: Juan Sanchez +--- + arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 20 +++++----- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +index 0136ac625605..7fbba60ec76e 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +@@ -141,20 +141,10 @@ pio: pinctrl@2000000 { + gpio-controller; + #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <3>; + +- rgmii0_pins: rgmii0-pins { +- pins = "PH0", "PH1", "PH2", "PH3", "PH4", +- "PH5", "PH6", "PH7", "PH9", "PH10", +- "PH14", "PH15", "PH16", "PH17", "PH18"; +- allwinner,pinmux = <5>; +- function = "gmac0"; +- drive-strength = <40>; +- bias-disable; +- }; +- + mmc0_pins: mmc0-pins { + pins = "PF0" ,"PF1", "PF2", "PF3", "PF4", "PF5"; + allwinner,pinmux = <2>; + function = "mmc0"; + drive-strength = <30>; +@@ -178,10 +168,20 @@ mmc2_pins: mmc2-pins { + function = "mmc2"; + drive-strength = <30>; + bias-pull-up; + }; + ++ rgmii0_pins: rgmii0-pins { ++ pins = "PH0", "PH1", "PH2", "PH3", "PH4", ++ "PH5", "PH6", "PH7", "PH9", "PH10", ++ "PH14", "PH15", "PH16", "PH17", "PH18"; ++ allwinner,pinmux = <5>; ++ function = "gmac0"; ++ drive-strength = <40>; ++ bias-disable; ++ }; ++ + uart0_pb_pins: uart0-pb-pins { + pins = "PB9", "PB10"; + allwinner,pinmux = <2>; + function = "uart0"; + }; +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-6.16/07-arm64-dts-allwinner-a527-cubie-a5e-Add-ethernet-PHY-reset-setting.patch b/patch/kernel/archive/sunxi-6.16/07-arm64-dts-allwinner-a527-cubie-a5e-Add-ethernet-PHY-reset-setting.patch new file mode 100644 index 000000000..92aebda74 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/07-arm64-dts-allwinner-a527-cubie-a5e-Add-ethernet-PHY-reset-setting.patch @@ -0,0 +1,29 @@ +From: Chen-Yu Tsai + +The external Ethernet PHY has a reset pin that is connected to the SoC. +It is missing from the original submission. + +Add it to complete the description. + +Fixes: acca163f3f51 ("arm64: dts: allwinner: a527: add EMAC0 to Radxa A5E board") +Signed-off-by: Chen-Yu Tsai +--- + arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +index 8bc0f2c72a24..c57ecc420aed 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +@@ -70,6 +70,9 @@ &mdio0 { + ext_rgmii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; ++ reset-gpios = <&pio 7 8 GPIO_ACTIVE_LOW>; /* PH8 */ ++ reset-assert-us = <10000>; ++ reset-deassert-us = <150000>; + }; + }; + +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/08-arm64-dts-allwinner-a527-cubie-a5e-Enable-second-Ethernet-port.patch b/patch/kernel/archive/sunxi-6.16/08-arm64-dts-allwinner-a527-cubie-a5e-Enable-second-Ethernet-port.patch new file mode 100644 index 000000000..6d3929191 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/08-arm64-dts-allwinner-a527-cubie-a5e-Enable-second-Ethernet-port.patch @@ -0,0 +1,82 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Juan Sanchez +Date: Sat, 5 Jul 2025 22:59:14 -0400 +Subject: From: Chen-Yu Tsai + +Signed-off-by: Juan Sanchez +--- + arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts | 26 +++++++++- + 1 file changed, 24 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +index 76e41202ecc8..592a50436454 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +@@ -11,10 +11,11 @@ / { + model = "Radxa Cubie A5E"; + compatible = "radxa,cubie-a5e", "allwinner,sun55i-a527"; + + aliases { + ethernet0 = &gmac0; ++ ethernet1 = &gmac1; + ethernet2 = &sdio_wifi; + serial0 = &uart0; + }; + + chosen { +@@ -82,29 +83,50 @@ &ehci1 { + status = "okay"; + }; + + &gmac0 { + phy-mode = "rgmii-id"; +- phy-handle = <&ext_rgmii_phy>; ++ phy-handle = <&ext_rgmii0_phy>; + phy-supply = <®_cldo3>; + + allwinner,tx-delay-ps = <300>; + allwinner,rx-delay-ps = <400>; + + status = "okay"; + }; + ++&gmac1 { ++ phy-mode = "rgmii-id"; ++ phy-handle = <&ext_rgmii1_phy>; ++ phy-supply = <®_cldo4>; ++ ++ allwinner,tx-delay-ps = <300>; ++ allwinner,rx-delay-ps = <400>; ++ ++ status = "okay"; ++}; ++ + &mdio0 { +- ext_rgmii_phy: ethernet-phy@1 { ++ ext_rgmii0_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + reset-gpios = <&pio 7 8 GPIO_ACTIVE_LOW>; /* PH8 */ + reset-assert-us = <10000>; + reset-deassert-us = <150000>; + }; + }; + ++&mdio1 { ++ ext_rgmii1_phy: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ reset-gpios = <&pio 9 16 GPIO_ACTIVE_LOW>; /* PJ16 */ ++ reset-assert-us = <10000>; ++ reset-deassert-us = <150000>; ++ }; ++}; ++ + &mmc0 { + vmmc-supply = <®_cldo3>; + cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */ + bus-width = <4>; + status = "okay"; +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-6.16/09-arm64-dts-allwinner-t527-Add-OrangePi-4A-board.patch b/patch/kernel/archive/sunxi-6.16/09-arm64-dts-allwinner-t527-Add-OrangePi-4A-board.patch new file mode 100644 index 000000000..a02aff9e8 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/09-arm64-dts-allwinner-t527-Add-OrangePi-4A-board.patch @@ -0,0 +1,441 @@ +From: Chen-Yu Tsai + +The OrangePi 4A is a typical Raspberry Pi model B sized development +board from Xunlong designed around an Allwinner T527 SoC. + +The board has the following features: +- Allwinner T527 SoC +- AXP717B + AXP323 PMICs +- Up to 4GB LPDDR4 DRAM +- micro SD slot +- optional eMMC module +- M.2 slot for PCIe 2.0 x1 +- 16 MB SPI-NOR flash +- 4x USB 2.0 type-A ports (one can be used in gadget mode) +- 1x Gigabit ethernet w/ Motorcomm PHY (through yet to be supported GMAC200) +- 3.5mm audio jack via internal audio codec +- HDMI 2.0 output +- eDP, MIPI CSI (2-lane and 4-lane) and MIPI DSI (4-lane) connectors +- USB type-C port purely for power +- AP6256 (Broadcom BCM4345) WiFi 5.0 + BT 5.0 +- unsoldered headers for ADC and an additional USB 2.0 host port +- 40-pin GPIO header + +Add a device tree for it, enabling all peripherals currently supported. + +Signed-off-by: Chen-Yu Tsai +--- +Changes since v1: +- Fixed regulator names for bldo3 and bldo4 +- Dropped labels for aldo1, bldo3, and bldo4, which are not really used +- Added voltage constraints to aldo2, based on specifications from + schematic +- Appended "-usb-0v9" to cpusldo's regulator name +- Added comments to explain how axp323 aldo1 and dldo1 are tied together + + arch/arm64/boot/dts/allwinner/Makefile | 1 + + .../dts/allwinner/sun55i-t527-orangepi-4a.dts | 383 ++++++++++++++++++ + 2 files changed, 384 insertions(+) + create mode 100644 arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts + +diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile +index 773cc02a13d0..780aeba0f3a4 100644 +--- a/arch/arm64/boot/dts/allwinner/Makefile ++++ b/arch/arm64/boot/dts/allwinner/Makefile +@@ -57,3 +57,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h700-anbernic-rg35xx-sp.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun55i-a527-cubie-a5e.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun55i-h728-x96qpro+.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun55i-t527-avaota-a1.dtb ++dtb-$(CONFIG_ARCH_SUNXI) += sun55i-t527-orangepi-4a.dtb +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts b/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts +new file mode 100644 +index 000000000000..ff2fd8e71e03 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts +@@ -0,0 +1,384 @@ ++// SPDX-License-Identifier: (GPL-2.0-only OR MIT) ++/* ++ * Copyright (C) 2025 Chen-Yu Tsai ++ */ ++ ++/dts-v1/; ++ ++#include "sun55i-a523.dtsi" ++ ++#include ++#include ++ ++/ { ++ model = "OrangePi 4A"; ++ compatible = "xunlong,orangepi-4a", "allwinner,sun55i-t527"; ++ ++ aliases { ++ serial0 = &uart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ ext_osc32k: ext-osc32k-clk { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "ext_osc32k"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ /* PWM capable pin, but PWM isn't supported yet. */ ++ led { ++ function = LED_FUNCTION_STATUS; ++ color = ; ++ gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */ ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++ ++ wifi_pwrseq: pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&r_pio 1 1 GPIO_ACTIVE_LOW>; /* PM1 */ ++ clocks = <&rtc CLK_OSC32K_FANOUT>; ++ clock-names = "ext_clock"; ++ }; ++ ++ reg_otg_vbus: regulator-otg-vbus { ++ compatible = "regulator-fixed"; ++ regulator-name = "otg-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <®_vcc5v>; ++ gpio = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */ ++ enable-active-high; ++ }; ++ ++ reg_pcie_vcc3v3: regulator-pcie-vcc3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-pcie-3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <®_vcc5v>; ++ gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ ++ enable-active-high; ++ }; ++ ++ reg_usb_vbus: regulator-usb-vbus { ++ compatible = "regulator-fixed"; ++ regulator-name = "usb-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <®_vcc5v>; ++ gpio = <&r_pio 0 12 GPIO_ACTIVE_HIGH>; /* PL12 */ ++ enable-active-high; ++ }; ++ ++ reg_vcc5v: regulator-vcc5v { ++ /* board wide 5V supply from USB type-C port */ ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-5v"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ }; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ehci1 { ++ status = "okay"; ++}; ++ ++&mmc0 { ++ vmmc-supply = <®_cldo3>; ++ cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */ ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&mmc1 { ++ bus-width = <4>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ non-removable; ++ vmmc-supply = <®_dldo1_323>; ++ vqmmc-supply = <®_bldo1>; ++ status = "okay"; ++ ++ brcmf: wifi@1 { ++ compatible = "brcm,bcm4329-fmac"; ++ reg = <1>; ++ interrupt-parent = <&r_pio>; ++ interrupts = <1 0 IRQ_TYPE_LEVEL_LOW>; /* PM0 */ ++ interrupt-names = "host-wake"; ++ }; ++}; ++ ++&mmc2 { ++ bus-width = <8>; ++ cap-mmc-hw-reset; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ non-removable; ++ vmmc-supply = <®_cldo3>; ++ vqmmc-supply = <®_cldo1>; ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&ohci1 { ++ status = "okay"; ++}; ++ ++&pio { ++ vcc-pb-supply = <®_cldo3>; /* via VCC-IO */ ++ vcc-pc-supply = <®_cldo1>; ++ vcc-pd-supply = <®_cldo3>; ++ vcc-pe-supply = <®_aldo2>; ++ vcc-pf-supply = <®_cldo3>; /* VCC-IO for 3.3v; VCC-MCSI for 1.8v */ ++ vcc-pg-supply = <®_bldo1>; ++ vcc-ph-supply = <®_cldo3>; /* via VCC-IO */ ++ vcc-pi-supply = <®_cldo3>; ++ vcc-pj-supply = <®_cldo1>; ++ vcc-pk-supply = <®_cldo1>; ++}; ++ ++&r_i2c0 { ++ status = "okay"; ++ ++ axp717: pmic@35 { ++ compatible = "x-powers,axp717"; ++ reg = <0x35>; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ interrupts-extended = <&nmi_intc 0 IRQ_TYPE_LEVEL_LOW>; ++ ++ vin1-supply = <®_vcc5v>; ++ vin2-supply = <®_vcc5v>; ++ vin3-supply = <®_vcc5v>; ++ vin4-supply = <®_vcc5v>; ++ aldoin-supply = <®_vcc5v>; ++ bldoin-supply = <®_vcc5v>; ++ cldoin-supply = <®_vcc5v>; ++ ++ regulators { ++ /* Supplies the "little" cluster (1.4 GHz cores) */ ++ reg_dcdc1: dcdc1 { ++ regulator-always-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <1160000>; ++ regulator-name = "vdd-cpul"; ++ }; ++ ++ reg_dcdc2: dcdc2 { ++ regulator-always-on; ++ regulator-min-microvolt = <920000>; ++ regulator-max-microvolt = <920000>; ++ regulator-name = "vdd-gpu-sys"; ++ }; ++ ++ reg_dcdc3: dcdc3 { ++ regulator-always-on; ++ regulator-min-microvolt = <1160000>; ++ regulator-max-microvolt = <1160000>; ++ regulator-name = "vcc-dram"; ++ }; ++ ++ reg_dcdc4: dcdc4 { ++ /* feeds 3.3V pin on GPIO header */ ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vdd-io"; ++ }; ++ ++ aldo1 { ++ /* not actually connected */ ++ regulator-name = "avdd-csi"; ++ }; ++ ++ reg_aldo2: aldo2 { ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc-pe"; ++ }; ++ ++ reg_aldo3: aldo3 { ++ /* supplies the I2C pins for this PMIC */ ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-pl-usb"; ++ }; ++ ++ reg_aldo4: aldo4 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc-pll-dxco-avcc"; ++ }; ++ ++ reg_bldo1: bldo1 { ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc-pg-wifi"; ++ }; ++ ++ reg_bldo2: bldo2 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc-pm-lpddr"; ++ }; ++ ++ bldo3 { ++ /* not actually connected */ ++ regulator-name = "afvcc-csi"; ++ }; ++ ++ bldo4 { ++ /* not actually connected */ ++ regulator-name = "dvdd-csi"; ++ }; ++ ++ reg_cldo1: cldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc-cvp-pc-lvds-mcsi-pk-efuse-pcie-edp-1v8"; ++ }; ++ ++ reg_cldo2: cldo2 { ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc3v3-csi"; ++ }; ++ ++ reg_cldo3: cldo3 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-io-mmc-nand-pd-pi-usb"; ++ }; ++ ++ reg_cldo4: cldo4 { ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-3v3-phy1-lcd"; ++ }; ++ ++ reg_cpusldo: cpusldo { ++ /* supplies the management core */ ++ regulator-always-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ regulator-name = "vdd-cpus"; ++ }; ++ }; ++ }; ++ ++ axp323: pmic@36 { ++ compatible = "x-powers,axp323"; ++ reg = <0x36>; ++ #interrupt-cells = <1>; ++ interrupt-controller; ++ status = "okay"; ++ ++ vin1-supply = <®_vcc5v>; ++ vin2-supply = <®_vcc5v>; ++ vin3-supply = <®_vcc5v>; ++ ++ regulators { ++ reg_aldo1_323: aldo1 { ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-wifi"; ++ }; ++ ++ reg_dldo1_323: dldo1 { ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-wifi2"; ++ }; ++ ++ /* Supplies the "big" cluster (1.8 GHz cores) */ ++ reg_dcdc1_323: dcdc1 { ++ regulator-always-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-name = "vdd-cpub"; ++ }; ++ ++ /* DCDC2 is polyphased with DCDC1 */ ++ ++ /* Some RISC-V management core related voltage */ ++ reg_dcdc3_323: dcdc3 { ++ regulator-always-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ regulator-name = "vdd-dnr"; ++ }; ++ }; ++ }; ++}; ++ ++&r_pio { ++/* ++ * Specifying the supply would create a circular dependency. ++ * ++ * vcc-pl-supply = <®_aldo3>; ++ */ ++ vcc-pm-supply = <®_bldo2>; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pb_pins>; ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; ++ uart-has-rtscts; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "brcm,bcm4345c5"; ++ clocks = <&rtc CLK_OSC32K_FANOUT>; ++ clock-names = "lpo"; ++ vbat-supply = <®_aldo1_323>; ++ vddio-supply = <®_bldo1>; ++ device-wakeup-gpios = <&r_pio 1 3 GPIO_ACTIVE_HIGH>; /* PM3 */ ++ host-wakeup-gpios = <&r_pio 1 4 GPIO_ACTIVE_HIGH>; /* PM4 */ ++ shutdown-gpios = <&r_pio 1 2 GPIO_ACTIVE_HIGH>; /* PM2 */ ++ }; ++}; ++ ++&usb_otg { ++ /* ++ * The OTG controller is connected to one of the type-A ports. ++ * There is a regulator, controlled by a GPIO, to provide VBUS power ++ * to the port, and a VBUSDET GPIO, to detect externally provided ++ * power. But without ID or CC pins there is no real way to do a ++ * runtime role detection. ++ */ ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usbphy { ++ usb0_vbus-supply = <®_otg_vbus>; ++ usb0_vbus_det-gpios = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */ ++ usb1_vbus-supply = <®_usb_vbus>; ++ status = "okay"; ++}; +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/10-clk-sunxi-ng-sun55i-a523-r-ccu-Add-missing-PPU0-reset.patch b/patch/kernel/archive/sunxi-6.16/10-clk-sunxi-ng-sun55i-a523-r-ccu-Add-missing-PPU0-reset.patch new file mode 100644 index 000000000..d6491d20e --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/10-clk-sunxi-ng-sun55i-a523-r-ccu-Add-missing-PPU0-reset.patch @@ -0,0 +1,30 @@ +From: Chen-Yu Tsai + +There is a PPU0 reset control bit in the same register as the PPU1 +reset control. This missing reset control is for the PCK-600 unit +in the SoC. Manual tests show that the reset control indeed exists, +and if not configured, the system will hang when the PCK-600 registers +are accessed. + +Add a reset entry for it at the end of the existing ones. + +Fixes: 8cea339cfb81 ("clk: sunxi-ng: add support for the A523/T527 PRCM CCU") +Signed-off-by: Chen-Yu Tsai +--- + drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c +index b5464d8083c8..70ce0ca0cb7d 100644 +--- a/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c ++++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c +@@ -204,6 +204,7 @@ static struct ccu_reset_map sun55i_a523_r_ccu_resets[] = { + [RST_BUS_R_IR_RX] = { 0x1cc, BIT(16) }, + [RST_BUS_R_RTC] = { 0x20c, BIT(16) }, + [RST_BUS_R_CPUCFG] = { 0x22c, BIT(16) }, ++ [RST_BUS_R_PPU0] = { 0x1ac, BIT(16) }, + }; + + static const struct sunxi_ccu_desc sun55i_a523_r_ccu_desc = { +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/11-dt-bindings-net-sun8i-emac-Add-A523-GMAC200-compatible.patch b/patch/kernel/archive/sunxi-6.16/11-dt-bindings-net-sun8i-emac-Add-A523-GMAC200-compatible.patch new file mode 100644 index 000000000..004056112 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/11-dt-bindings-net-sun8i-emac-Add-A523-GMAC200-compatible.patch @@ -0,0 +1,134 @@ +From: Chen-Yu Tsai + +The Allwinner A523 SoC family has a second Ethernet controller, called +the GMAC200 in the BSP and T527 datasheet, and referred to as GMAC1 for +numbering. This controller, according to BSP sources, is fully +compatible with a slightly newer version of the Synopsys DWMAC core. +The glue layer around the controller is the same as found around older +DWMAC cores on Allwinner SoCs. The only slight difference is that since +this is the second controller on the SoC, the register for the clock +delay controls is at a different offset. Last, the integration includes +a dedicated clock gate for the memory bus and the whole thing is put in +a separately controllable power domain. + +Add a compatible string entry for it, and work in the requirements for +a second clock and a power domain. + +Signed-off-by: Chen-Yu Tsai +--- + .../net/allwinner,sun8i-a83t-emac.yaml | 68 ++++++++++++++++++- + 1 file changed, 66 insertions(+), 2 deletions(-) + +diff --git a/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml b/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml +index 2ac709a4c472..1058e5af92ba 100644 +--- a/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml ++++ b/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml +@@ -26,6 +26,9 @@ properties: + - allwinner,sun50i-h616-emac0 + - allwinner,sun55i-a523-gmac0 + - const: allwinner,sun50i-a64-emac ++ - items: ++ - const: allwinner,sun55i-a523-gmac200 ++ - const: snps,dwmac-4.20a + + reg: + maxItems: 1 +@@ -37,14 +40,19 @@ properties: + const: macirq + + clocks: +- maxItems: 1 ++ minItems: 1 ++ maxItems: 2 + + clock-names: +- const: stmmaceth ++ minItems: 1 ++ maxItems: 2 + + phy-supply: + description: PHY regulator + ++ power-domains: ++ maxItems: 1 ++ + syscon: + $ref: /schemas/types.yaml#/definitions/phandle + description: +@@ -75,6 +83,7 @@ allOf: + - allwinner,sun8i-h3-emac + - allwinner,sun8i-v3s-emac + - allwinner,sun50i-a64-emac ++ - allwinner,sun55i-a523-gmac200 + + then: + properties: +@@ -191,6 +200,31 @@ allOf: + - mdio-parent-bus + - mdio@1 + ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: allwinner,sun55i-a523-gmac200 ++ then: ++ properties: ++ clocks: ++ minItems: 2 ++ clock-names: ++ items: ++ - const: stmmaceth ++ - const: mbus ++ required: ++ - power-domains ++ else: ++ properties: ++ clocks: ++ maxItems: 1 ++ clock-names: ++ items: ++ - const: stmmaceth ++ power-domains: false ++ ++ + unevaluatedProperties: false + + examples: +@@ -323,4 +357,34 @@ examples: + }; + }; + ++ - | ++ ethernet@4510000 { ++ compatible = "allwinner,sun55i-a523-gmac200", ++ "snps,dwmac-4.20a"; ++ reg = <0x04510000 0x10000>; ++ clocks = <&ccu 117>, <&ccu 79>; ++ clock-names = "stmmaceth", "mbus"; ++ resets = <&ccu 43>; ++ reset-names = "stmmaceth"; ++ interrupts = <0 47 4>; ++ interrupt-names = "macirq"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmii1_pins>; ++ power-domains = <&pck600 4>; ++ syscon = <&syscon>; ++ phy-handle = <&ext_rgmii_phy_1>; ++ phy-mode = "rgmii-id"; ++ snps,fixed-burst; ++ snps,axi-config = <&gmac1_stmmac_axi_setup>; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ext_rgmii_phy_1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++ }; ++ }; + ... +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/12-dt-bindings-power-Add-A523-PPU-and-PCK600-power-controllers.patch b/patch/kernel/archive/sunxi-6.16/12-dt-bindings-power-Add-A523-PPU-and-PCK600-power-controllers.patch new file mode 100644 index 000000000..a236ae57b --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/12-dt-bindings-power-Add-A523-PPU-and-PCK600-power-controllers.patch @@ -0,0 +1,76 @@ +From: Chen-Yu Tsai + +The A523 PPU is likely the same kind of hardware seen on previous SoCs. + +The A523 PCK600, as the name suggests, is likely a customized version +of ARM's PCK-600 power controller. Comparing the BSP driver against +ARM's PPU datasheet shows that the basic registers line up, but +Allwinner's hardware has some additional delay controls in the reserved +register range. As such it is likely not fully compatible with the +standard ARM version. + +Document A523 PPU and PCK600 compatibles. + +Signed-off-by: Chen-Yu Tsai +--- + .../bindings/power/allwinner,sun20i-d1-ppu.yaml | 2 ++ + .../power/allwinner,sun55i-a523-pck600.h | 15 +++++++++++++++ + .../dt-bindings/power/allwinner,sun55i-a523-ppu.h | 12 ++++++++++++ + 3 files changed, 29 insertions(+) + create mode 100644 include/dt-bindings/power/allwinner,sun55i-a523-pck600.h + create mode 100644 include/dt-bindings/power/allwinner,sun55i-a523-ppu.h + +diff --git a/Documentation/devicetree/bindings/power/allwinner,sun20i-d1-ppu.yaml b/Documentation/devicetree/bindings/power/allwinner,sun20i-d1-ppu.yaml +index f578be6a3bc8..b9f550994512 100644 +--- a/Documentation/devicetree/bindings/power/allwinner,sun20i-d1-ppu.yaml ++++ b/Documentation/devicetree/bindings/power/allwinner,sun20i-d1-ppu.yaml +@@ -18,6 +18,8 @@ properties: + enum: + - allwinner,sun20i-d1-ppu + - allwinner,sun8i-v853-ppu ++ - allwinner,sun55i-a523-ppu ++ - allwinner,sun55i-a523-pck-600 + + reg: + maxItems: 1 +diff --git a/include/dt-bindings/power/allwinner,sun55i-a523-pck600.h b/include/dt-bindings/power/allwinner,sun55i-a523-pck600.h +new file mode 100644 +index 000000000000..6b3d8ea7bb69 +--- /dev/null ++++ b/include/dt-bindings/power/allwinner,sun55i-a523-pck600.h +@@ -0,0 +1,15 @@ ++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ ++ ++#ifndef _DT_BINDINGS_POWER_SUN55I_A523_PCK600_H_ ++#define _DT_BINDINGS_POWER_SUN55I_A523_PCK600_H_ ++ ++#define PD_VE 0 ++#define PD_GPU 1 ++#define PD_VI 2 ++#define PD_VO0 3 ++#define PD_VO1 4 ++#define PD_DE 5 ++#define PD_NAND 6 ++#define PD_PCIE 7 ++ ++#endif /* _DT_BINDINGS_POWER_SUN55I_A523_PCK600_H_ */ +diff --git a/include/dt-bindings/power/allwinner,sun55i-a523-ppu.h b/include/dt-bindings/power/allwinner,sun55i-a523-ppu.h +new file mode 100644 +index 000000000000..bc9aba73c19a +--- /dev/null ++++ b/include/dt-bindings/power/allwinner,sun55i-a523-ppu.h +@@ -0,0 +1,12 @@ ++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ ++ ++#ifndef _DT_BINDINGS_POWER_SUN55I_A523_PPU_H_ ++#define _DT_BINDINGS_POWER_SUN55I_A523_PPU_H_ ++ ++#define PD_DSP 0 ++#define PD_NPU 1 ++#define PD_AUDIO 2 ++#define PD_SRAM 3 ++#define PD_RISCV 4 ++ ++#endif /* _DT_BINDINGS_POWER_SUN55I_A523_PPU_H_ */ +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/13-dt-bindings-reset-sun55i-a523-r-ccu-Add-missing-PPU0-reset.patch b/patch/kernel/archive/sunxi-6.16/13-dt-bindings-reset-sun55i-a523-r-ccu-Add-missing-PPU0-reset.patch new file mode 100644 index 000000000..b581a2fcc --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/13-dt-bindings-reset-sun55i-a523-r-ccu-Add-missing-PPU0-reset.patch @@ -0,0 +1,29 @@ +From: Chen-Yu Tsai + +There is a PPU0 reset control bit in the same register as the PPU1 +reset control. This missing reset control is for the PCK-600 unit +in the SoC. Manual tests show that the reset control indeed exists, +and if not configured, the system will hang when the PCK-600 registers +are accessed. + +Add a reset entry for it at the end of the existing ones. + +Fixes: 52dbf84857f0 ("dt-bindings: clk: sunxi-ng: document two Allwinner A523 CCUs") +Signed-off-by: Chen-Yu Tsai +--- + include/dt-bindings/reset/sun55i-a523-r-ccu.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/dt-bindings/reset/sun55i-a523-r-ccu.h b/include/dt-bindings/reset/sun55i-a523-r-ccu.h +index dd6fbb372e19..eb31ae9958d6 100644 +--- a/include/dt-bindings/reset/sun55i-a523-r-ccu.h ++++ b/include/dt-bindings/reset/sun55i-a523-r-ccu.h +@@ -21,5 +21,6 @@ + #define RST_BUS_R_IR_RX 12 + #define RST_BUS_R_RTC 13 + #define RST_BUS_R_CPUCFG 14 ++#define RST_BUS_R_PPU0 15 + + #endif /* _DT_BINDINGS_RST_SUN55I_A523_R_CCU_H_ */ +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/14-mfd-axp20x-Set-explicit-ID-for-AXP313-regulator.patch b/patch/kernel/archive/sunxi-6.16/14-mfd-axp20x-Set-explicit-ID-for-AXP313-regulator.patch new file mode 100644 index 000000000..650c8c948 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/14-mfd-axp20x-Set-explicit-ID-for-AXP313-regulator.patch @@ -0,0 +1,38 @@ +From: Chen-Yu Tsai + +On newer boards featuring the A523 SoC, the AXP323 (related to the +AXP313) is paired with the AXP717 and serves as a secondary PMIC +providing additional regulator outputs. However the mfd cells are all +registered with PLATFORM_DEVID_NONE, which causes the regulator cells +to conflict with each other. + +Commit e37ec3218870 ("mfd: axp20x: Allow multiple regulators") attempted +to fix this by switching to PLATFORM_DEVID_AUTO so that the device names +would all be different, however that broke IIO channel mapping, which is +also tied to the device names. As a result the change was later reverted. + +Instead, here we attempt to make sure the AXP313/AXP323 regulator cell +does not conflict by explicitly giving it an ID number. This was +previously done for the AXP809+AXP806 pair used with the A80 SoC. + +Signed-off-by: Chen-Yu Tsai +--- + drivers/mfd/axp20x.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c +index e9914e8a29a3..25c639b348cd 100644 +--- a/drivers/mfd/axp20x.c ++++ b/drivers/mfd/axp20x.c +@@ -1053,7 +1053,8 @@ static const struct mfd_cell axp152_cells[] = { + }; + + static struct mfd_cell axp313a_cells[] = { +- MFD_CELL_NAME("axp20x-regulator"), ++ /* AXP323 is sometimes paired with AXP717 as sub-PMIC */ ++ MFD_CELL_BASIC("axp20x-regulator", NULL, NULL, 0, 1), + MFD_CELL_RES("axp313a-pek", axp313a_pek_resources), + }; + +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/15-mfd-axp20x-set-explicit-ID-for-regulator-cell-if-no-IRQ-line-is-present.patch b/patch/kernel/archive/sunxi-6.16/15-mfd-axp20x-set-explicit-ID-for-regulator-cell-if-no-IRQ-line-is-present.patch new file mode 100644 index 000000000..b161a862f --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/15-mfd-axp20x-set-explicit-ID-for-regulator-cell-if-no-IRQ-line-is-present.patch @@ -0,0 +1,49 @@ +From: Chen-Yu Tsai + +Originally an explicit ID for the AXP313/AXP323 regulator was set to +avoid a conflict with the primary AXP717 PMIC on Allwinner A523 family +boards. + +This didn't entirely work since on some or all of these boards, the +interrupt line on this secondary PMIC was left unconnected, and thus +the driver would fall back to the generic "no interrupt; only regulators" +case, which didn't have the explicit ID set, thus undoing the intended +fix. + +Also set an explicit ID for the regulator cell in the no IRQ generic +fall back case. This fixes the conflict for the AXP717 + AXP313/AXP323 +case. For the actual single PMIC with no IRQ connected case, the ID does +not affect functionality, only the device naming of the regulator cell, +and by extension the name and path under sysfs. + +Fixes: 249abf9b1e25 ("mfd: axp20x: Set explicit ID for AXP313 regulator") +Signed-off-by: Chen-Yu Tsai +--- + +This is an alternative to + + mfd: axp20x: Skip PEK on AXP313A/AXP323 if no interrupt line is available + +which was deemed too fragile. +--- + drivers/mfd/axp20x.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c +index 25c639b348cd..c5f0ebae327f 100644 +--- a/drivers/mfd/axp20x.c ++++ b/drivers/mfd/axp20x.c +@@ -1231,9 +1231,8 @@ static const struct mfd_cell axp15060_cells[] = { + + /* For boards that don't have IRQ line connected to SOC. */ + static const struct mfd_cell axp_regulator_only_cells[] = { +- { +- .name = "axp20x-regulator", +- }, ++ /* PMIC without IRQ line may be secondary PMIC */ ++ MFD_CELL_BASIC("axp20x-regulator", NULL, NULL, 0, 1), + }; + + static int axp20x_power_off(struct sys_off_data *data) +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/16-net-stmmac-Add-support-for-Allwinner-A523-GMAC200.patch b/patch/kernel/archive/sunxi-6.16/16-net-stmmac-Add-support-for-Allwinner-A523-GMAC200.patch new file mode 100644 index 000000000..bd3f569a0 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/16-net-stmmac-Add-support-for-Allwinner-A523-GMAC200.patch @@ -0,0 +1,227 @@ +From: Chen-Yu Tsai + +The Allwinner A523 SoC family has a second Ethernet controller, called +the GMAC200 in the BSP and T527 datasheet, and referred to as GMAC1 for +numbering. This controller, according to BSP sources, is fully +compatible with a slightly newer version of the Synopsys DWMAC core. +The glue layer around the controller is the same as found around older +DWMAC cores on Allwinner SoCs. The only slight difference is that since +this is the second controller on the SoC, the register for the clock +delay controls is at a different offset. Last, the integration includes +a dedicated clock gate for the memory bus and the whole thing is put in +a separately controllable power domain. + +Add a new driver for this hardware supporting the integration layer. + +Signed-off-by: Chen-Yu Tsai +--- + drivers/net/ethernet/stmicro/stmmac/Kconfig | 12 ++ + drivers/net/ethernet/stmicro/stmmac/Makefile | 1 + + .../ethernet/stmicro/stmmac/dwmac-sun55i.c | 161 ++++++++++++++++++ + 3 files changed, 174 insertions(+) + create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-sun55i.c + +diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig +index 67fa879b1e52..38ce9a0cfb5b 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig ++++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig +@@ -263,6 +263,18 @@ config DWMAC_SUN8I + stmmac device driver. This driver is used for H3/A83T/A64 + EMAC ethernet controller. + ++config DWMAC_SUN55I ++ tristate "Allwinner sun55i GMAC200 support" ++ default ARCH_SUNXI ++ depends on OF && (ARCH_SUNXI || COMPILE_TEST) ++ select MDIO_BUS_MUX ++ help ++ Support for Allwinner A523/T527 GMAC200 ethernet controllers. ++ ++ This selects Allwinner SoC glue layer support for the ++ stmmac device driver. This driver is used for A523/T527 ++ GMAC200 ethernet controller. ++ + config DWMAC_THEAD + tristate "T-HEAD dwmac support" + depends on OF && (ARCH_THEAD || COMPILE_TEST) +diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile +index b591d93f8503..51e068e26ce4 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/Makefile ++++ b/drivers/net/ethernet/stmicro/stmmac/Makefile +@@ -31,6 +31,7 @@ obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o + obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o + obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o + obj-$(CONFIG_DWMAC_SUN8I) += dwmac-sun8i.o ++obj-$(CONFIG_DWMAC_SUN55I) += dwmac-sun55i.o + obj-$(CONFIG_DWMAC_THEAD) += dwmac-thead.o + obj-$(CONFIG_DWMAC_DWC_QOS_ETH) += dwmac-dwc-qos-eth.o + obj-$(CONFIG_DWMAC_INTEL_PLAT) += dwmac-intel-plat.o +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun55i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun55i.c +new file mode 100644 +index 000000000000..7fadb90e3098 +--- /dev/null ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun55i.c +@@ -0,0 +1,161 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * dwmac-sun55i.c - Allwinner sun55i GMAC200 specific glue layer ++ * ++ * Copyright (C) 2025 Chen-Yu Tsai ++ * ++ * syscon parts taken from dwmac-sun8i.c, which is ++ * ++ * Copyright (C) 2017 Corentin Labbe ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "stmmac.h" ++#include "stmmac_platform.h" ++ ++#define SYSCON_REG 0x34 ++ ++/* RMII specific bits */ ++#define SYSCON_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */ ++/* Generic system control EMAC_CLK bits */ ++#define SYSCON_ETXDC_MASK GENMASK(12, 10) ++#define SYSCON_ERXDC_MASK GENMASK(9, 5) ++/* EMAC PHY Interface Type */ ++#define SYSCON_EPIT BIT(2) /* 1: RGMII, 0: MII */ ++#define SYSCON_ETCS_MASK GENMASK(1, 0) ++#define SYSCON_ETCS_MII 0x0 ++#define SYSCON_ETCS_EXT_GMII 0x1 ++#define SYSCON_ETCS_INT_GMII 0x2 ++ ++#define MASK_TO_VAL(mask) ((mask) >> (__builtin_ffsll(mask) - 1)) ++ ++static int sun55i_gmac200_set_syscon(struct device *dev, ++ struct plat_stmmacenet_data *plat) ++{ ++ struct device_node *node = dev->of_node; ++ struct regmap *regmap; ++ u32 val, reg = 0; ++ ++ regmap = syscon_regmap_lookup_by_phandle(node, "syscon"); ++ if (IS_ERR(regmap)) ++ return dev_err_probe(dev, PTR_ERR(regmap), "Unable to map syscon\n"); ++ ++ if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) { ++ if (val % 100) { ++ dev_err(dev, "tx-delay must be a multiple of 100\n"); ++ return -EINVAL; ++ } ++ val /= 100; ++ dev_dbg(dev, "set tx-delay to %x\n", val); ++ if (val > MASK_TO_VAL(SYSCON_ETXDC_MASK)) ++ return dev_err_probe(dev, -EINVAL, ++ "Invalid TX clock delay: %d\n", ++ val); ++ ++ reg |= FIELD_PREP(SYSCON_ETXDC_MASK, val); ++ } ++ ++ if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) { ++ if (val % 100) { ++ dev_err(dev, "rx-delay must be a multiple of 100\n"); ++ return -EINVAL; ++ } ++ val /= 100; ++ dev_dbg(dev, "set rx-delay to %x\n", val); ++ if (val > MASK_TO_VAL(SYSCON_ERXDC_MASK)) ++ return dev_err_probe(dev, -EINVAL, ++ "Invalid RX clock delay: %d\n", ++ val); ++ ++ reg |= FIELD_PREP(SYSCON_ERXDC_MASK, val); ++ } ++ ++ switch (plat->mac_interface) { ++ case PHY_INTERFACE_MODE_MII: ++ /* default */ ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ reg |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII; ++ break; ++ case PHY_INTERFACE_MODE_RMII: ++ reg |= SYSCON_RMII_EN; ++ break; ++ default: ++ dev_err(dev, "Unsupported interface mode: %s", ++ phy_modes(plat->mac_interface)); ++ return -EINVAL; ++ } ++ ++ regmap_write(regmap, SYSCON_REG, reg); ++ ++ return 0; ++} ++ ++static int sun55i_gmac200_probe(struct platform_device *pdev) ++{ ++ struct plat_stmmacenet_data *plat_dat; ++ struct stmmac_resources stmmac_res; ++ struct device *dev = &pdev->dev; ++ struct clk *clk; ++ int ret; ++ ++ ret = stmmac_get_platform_resources(pdev, &stmmac_res); ++ if (ret) ++ return ret; ++ ++ plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac); ++ if (IS_ERR(plat_dat)) ++ return PTR_ERR(plat_dat); ++ ++ /* BSP disables it */ ++ plat_dat->flags |= STMMAC_FLAG_SPH_DISABLE; ++ plat_dat->host_dma_width = 32; ++ ++ ret = sun55i_gmac200_set_syscon(dev, plat_dat); ++ if (ret) ++ return ret; ++ ++ clk = devm_clk_get_enabled(dev, "mbus"); ++ if (IS_ERR(clk)) ++ return dev_err_probe(dev, PTR_ERR(clk), ++ "Failed to get or enable MBUS clock\n"); ++ ++ ret = devm_regulator_get_enable_optional(dev, "phy"); ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to get or enable PHY supply\n"); ++ ++ return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res); ++} ++ ++static const struct of_device_id sun55i_gmac200_match[] = { ++ { .compatible = "allwinner,sun55i-a523-gmac200" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, sun55i_gmac200_match); ++ ++static struct platform_driver sun55i_gmac200_driver = { ++ .probe = sun55i_gmac200_probe, ++ .driver = { ++ .name = "sun55i-gmac200", ++ .pm = &stmmac_pltfr_pm_ops, ++ .of_match_table = sun55i_gmac200_match, ++ }, ++}; ++module_platform_driver(sun55i_gmac200_driver); ++ ++MODULE_AUTHOR("Chen-Yu Tsai "); ++MODULE_DESCRIPTION("Allwinner sun55i GMAC200 specific glue layer"); ++MODULE_LICENSE("GPL"); +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/17-pmdomain-sunxi-add-driver-for-Allwinner-A523's PCK-600-power-controller.patch b/patch/kernel/archive/sunxi-6.16/17-pmdomain-sunxi-add-driver-for-Allwinner-A523's PCK-600-power-controller.patch new file mode 100644 index 000000000..2d1396281 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/17-pmdomain-sunxi-add-driver-for-Allwinner-A523's PCK-600-power-controller.patch @@ -0,0 +1,278 @@ +From: Chen-Yu Tsai + +Allwinner A523 family has a second power controller, named PCK-600 in +the datasheets and BSP. It is likely based on ARM's PCK-600 hardware +block, with some additional delay controls. The only documentation for +this hardware is the BSP driver. The standard registers defined in ARM's +Power Policy Unit Architecture Specification line up. Some extra delay +controls are found in the reserved range of registers. + +Add a driver for this power controller. Delay control register values +and power domain names are from the BSP driver. + +Signed-off-by: Chen-Yu Tsai +--- + drivers/pmdomain/sunxi/Kconfig | 8 + + drivers/pmdomain/sunxi/Makefile | 1 + + drivers/pmdomain/sunxi/sun55i-pck600.c | 225 +++++++++++++++++++++++++ + 3 files changed, 234 insertions(+) + create mode 100644 drivers/pmdomain/sunxi/sun55i-pck600.c + +diff --git a/drivers/pmdomain/sunxi/Kconfig b/drivers/pmdomain/sunxi/Kconfig +index 43eecb3ea981..3e2b77cd9a2b 100644 +--- a/drivers/pmdomain/sunxi/Kconfig ++++ b/drivers/pmdomain/sunxi/Kconfig +@@ -18,3 +18,11 @@ config SUN50I_H6_PRCM_PPU + Say y to enable the Allwinner H6/H616 PRCM power domain driver. + This is required to enable the Mali GPU in the H616 SoC, it is + optional for the H6. ++ ++config SUN55I_PCK600 ++ bool "Allwinner A523 PCK-600 power domain driver" ++ depends on PM ++ select PM_GENERIC_DOMAINS ++ help ++ Say y to enable the PCK-600 power domain driver. This saves power ++ when certain peripherals, such as the video engine, are idle. +diff --git a/drivers/pmdomain/sunxi/Makefile b/drivers/pmdomain/sunxi/Makefile +index c1343e123759..e344b232fc9f 100644 +--- a/drivers/pmdomain/sunxi/Makefile ++++ b/drivers/pmdomain/sunxi/Makefile +@@ -1,3 +1,4 @@ + # SPDX-License-Identifier: GPL-2.0-only + obj-$(CONFIG_SUN20I_PPU) += sun20i-ppu.o + obj-$(CONFIG_SUN50I_H6_PRCM_PPU) += sun50i-h6-prcm-ppu.o ++obj-$(CONFIG_SUN55I_PCK600) += sun55i-pck600.o +diff --git a/drivers/pmdomain/sunxi/sun55i-pck600.c b/drivers/pmdomain/sunxi/sun55i-pck600.c +new file mode 100644 +index 000000000000..7248f6113665 +--- /dev/null ++++ b/drivers/pmdomain/sunxi/sun55i-pck600.c +@@ -0,0 +1,225 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Allwinner PCK-600 power domain support ++ * ++ * Copyright (c) 2025 Chen-Yu Tsai ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PPU_PWPR 0x0 ++#define PPU_PWSR 0x8 ++#define PPU_DCDR0 0x170 ++#define PPU_DCDR1 0x174 ++ ++#define PPU_PWSR_PWR_STATUS GENMASK(3, 0) ++#define PPU_POWER_MODE_ON 0x8 ++#define PPU_POWER_MODE_OFF 0x0 ++ ++#define PPU_REG_SIZE 0x1000 ++ ++struct sunxi_pck600_desc { ++ const char * const *pd_names; ++ unsigned int num_domains; ++ u32 logic_power_switch0_delay_offset; ++ u32 logic_power_switch1_delay_offset; ++ u32 off2on_delay_offset; ++ u32 device_ctrl0_delay; ++ u32 device_ctrl1_delay; ++ u32 logic_power_switch0_delay; ++ u32 logic_power_switch1_delay; ++ u32 off2on_delay; ++}; ++ ++struct sunxi_pck600_pd { ++ struct generic_pm_domain genpd; ++ struct sunxi_pck600 *pck; ++ void __iomem *base; ++}; ++ ++struct sunxi_pck600 { ++ struct device *dev; ++ struct genpd_onecell_data genpd_data; ++ struct sunxi_pck600_pd pds[]; ++}; ++ ++#define to_sunxi_pd(gpd) container_of(gpd, struct sunxi_pck600_pd, genpd) ++ ++static int sunxi_pck600_pd_set_power(struct sunxi_pck600_pd *pd, bool on) ++{ ++ struct sunxi_pck600 *pck = pd->pck; ++ struct generic_pm_domain *genpd = &pd->genpd; ++ int ret; ++ u32 val, reg; ++ ++ val = on ? PPU_POWER_MODE_ON : PPU_POWER_MODE_OFF; ++ ++ reg = readl(pd->base + PPU_PWPR); ++ FIELD_MODIFY(PPU_PWSR_PWR_STATUS, ®, val); ++ writel(reg, pd->base + PPU_PWPR); ++ ++ /* push write out to hardware */ ++ reg = readl(pd->base + PPU_PWPR); ++ ++ ret = readl_poll_timeout_atomic(pd->base + PPU_PWSR, reg, ++ FIELD_GET(PPU_PWSR_PWR_STATUS, reg) == val, ++ 0, 10000); ++ if (ret) ++ dev_err(pck->dev, "failed to turn domain \"%s\" %s: %d\n", ++ genpd->name, str_on_off(on), ret); ++ ++ return ret; ++} ++ ++static int sunxi_pck600_power_on(struct generic_pm_domain *domain) ++{ ++ struct sunxi_pck600_pd *pd = to_sunxi_pd(domain); ++ ++ return sunxi_pck600_pd_set_power(pd, true); ++} ++ ++static int sunxi_pck600_power_off(struct generic_pm_domain *domain) ++{ ++ struct sunxi_pck600_pd *pd = to_sunxi_pd(domain); ++ ++ return sunxi_pck600_pd_set_power(pd, false); ++} ++ ++static void sunxi_pck600_pd_setup(struct sunxi_pck600_pd *pd, ++ const struct sunxi_pck600_desc *desc) ++{ ++ writel(desc->device_ctrl0_delay, pd->base + PPU_DCDR0); ++ writel(desc->device_ctrl1_delay, pd->base + PPU_DCDR1); ++ writel(desc->logic_power_switch0_delay, ++ pd->base + desc->logic_power_switch0_delay_offset); ++ writel(desc->logic_power_switch1_delay, ++ pd->base + desc->logic_power_switch1_delay_offset); ++ writel(desc->off2on_delay, pd->base + desc->off2on_delay_offset); ++} ++ ++static int sunxi_pck600_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ const struct sunxi_pck600_desc *desc; ++ struct genpd_onecell_data *genpds; ++ struct sunxi_pck600 *pck; ++ struct reset_control *rst; ++ struct clk *clk; ++ void __iomem *base; ++ int i, ret; ++ ++ desc = of_device_get_match_data(dev); ++ ++ pck = devm_kzalloc(dev, struct_size(pck, pds, desc->num_domains), GFP_KERNEL); ++ if (!pck) ++ return -ENOMEM; ++ ++ pck->dev = &pdev->dev; ++ platform_set_drvdata(pdev, pck); ++ ++ genpds = &pck->genpd_data; ++ genpds->num_domains = desc->num_domains; ++ genpds->domains = devm_kcalloc(dev, desc->num_domains, ++ sizeof(*genpds->domains), GFP_KERNEL); ++ if (!genpds->domains) ++ return -ENOMEM; ++ ++ base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ rst = devm_reset_control_get_exclusive_released(dev, NULL); ++ if (IS_ERR(rst)) ++ return dev_err_probe(dev, PTR_ERR(rst), "failed to get reset control\n"); ++ ++ clk = devm_clk_get_enabled(dev, NULL); ++ if (IS_ERR(clk)) ++ return dev_err_probe(dev, PTR_ERR(clk), "failed to get clock\n"); ++ ++ for (i = 0; i < desc->num_domains; i++) { ++ struct sunxi_pck600_pd *pd = &pck->pds[i]; ++ ++ pd->genpd.name = desc->pd_names[i]; ++ pd->genpd.power_off = sunxi_pck600_power_off; ++ pd->genpd.power_on = sunxi_pck600_power_on; ++ pd->base = base + PPU_REG_SIZE * i; ++ ++ sunxi_pck600_pd_setup(pd, desc); ++ ret = pm_genpd_init(&pd->genpd, NULL, false); ++ if (ret) { ++ dev_err_probe(dev, ret, "failed to initialize power domain\n"); ++ goto err_remove_pds; ++ } ++ ++ genpds->domains[i] = &pd->genpd; ++ } ++ ++ ret = of_genpd_add_provider_onecell(dev_of_node(dev), genpds); ++ if (ret) { ++ dev_err_probe(dev, ret, "failed to add PD provider\n"); ++ goto err_remove_pds; ++ } ++ ++ return 0; ++ ++err_remove_pds: ++ for (i--; i >= 0; i--) ++ pm_genpd_remove(genpds->domains[i]); ++ ++ return ret; ++} ++ ++static const char * const sun55i_a523_pck600_pd_names[] = { ++ "VE", "GPU", "VI", "VO0", "VO1", "DE", "NAND", "PCIE" ++}; ++ ++static const struct sunxi_pck600_desc sun55i_a523_pck600_desc = { ++ .pd_names = sun55i_a523_pck600_pd_names, ++ .num_domains = ARRAY_SIZE(sun55i_a523_pck600_pd_names), ++ .logic_power_switch0_delay_offset = 0xc00, ++ .logic_power_switch1_delay_offset = 0xc04, ++ .off2on_delay_offset = 0xc10, ++ .device_ctrl0_delay = 0xffffff, ++ .device_ctrl1_delay = 0xffff, ++ .logic_power_switch0_delay = 0x8080808, ++ .logic_power_switch1_delay = 0x808, ++ .off2on_delay = 0x8 ++}; ++ ++static const struct of_device_id sunxi_pck600_of_match[] = { ++ { ++ .compatible = "allwinner,sun55i-a523-pck-600", ++ .data = &sun55i_a523_pck600_desc, ++ }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, sunxi_pck600_of_match); ++ ++static struct platform_driver sunxi_pck600_driver = { ++ .probe = sunxi_pck600_probe, ++ .driver = { ++ .name = "sunxi-pck-600", ++ .of_match_table = sunxi_pck600_of_match, ++ /* Power domains cannot be removed if in use. */ ++ .suppress_bind_attrs = true, ++ }, ++}; ++module_platform_driver(sunxi_pck600_driver); ++ ++MODULE_DESCRIPTION("Allwinner PCK-600 power domain driver"); ++MODULE_AUTHOR("Chen-Yu Tsai "); ++MODULE_LICENSE("GPL"); +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/18-pmdomain-sunxi-sun20i-ppu-add-A523-support.patch b/patch/kernel/archive/sunxi-6.16/18-pmdomain-sunxi-sun20i-ppu-add-A523-support.patch new file mode 100644 index 000000000..7d7d7f845 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/18-pmdomain-sunxi-sun20i-ppu-add-A523-support.patch @@ -0,0 +1,48 @@ +From: Chen-Yu Tsai + +A523 has a PPU like the one in the Allwinner D1 SoC. + +Add a compatible entry and a list of power domain names for it. + +Signed-off-by: Chen-Yu Tsai +--- + drivers/pmdomain/sunxi/sun20i-ppu.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/drivers/pmdomain/sunxi/sun20i-ppu.c b/drivers/pmdomain/sunxi/sun20i-ppu.c +index 9f002748d224..b65876a68cc1 100644 +--- a/drivers/pmdomain/sunxi/sun20i-ppu.c ++++ b/drivers/pmdomain/sunxi/sun20i-ppu.c +@@ -193,6 +193,19 @@ static const struct sun20i_ppu_desc sun8i_v853_ppu_desc = { + .num_domains = ARRAY_SIZE(sun8i_v853_ppu_pd_names), + }; + ++static const char *const sun55i_a523_ppu_pd_names[] = { ++ "DSP", ++ "NPU", ++ "AUDIO", ++ "SRAM", ++ "RISCV", ++}; ++ ++static const struct sun20i_ppu_desc sun55i_a523_ppu_desc = { ++ .names = sun55i_a523_ppu_pd_names, ++ .num_domains = ARRAY_SIZE(sun55i_a523_ppu_pd_names), ++}; ++ + static const struct of_device_id sun20i_ppu_of_match[] = { + { + .compatible = "allwinner,sun20i-d1-ppu", +@@ -202,6 +215,10 @@ static const struct of_device_id sun20i_ppu_of_match[] = { + .compatible = "allwinner,sun8i-v853-ppu", + .data = &sun8i_v853_ppu_desc, + }, ++ { ++ .compatible = "allwinner,sun55i-a523-ppu", ++ .data = &sun55i_a523_ppu_desc, ++ }, + { } + }; + MODULE_DEVICE_TABLE(of, sun20i_ppu_of_match); +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/19-regulator-axp20x-force-polyphase-setup-for-axp323.patch b/patch/kernel/archive/sunxi-6.16/19-regulator-axp20x-force-polyphase-setup-for-axp323.patch new file mode 100644 index 000000000..bfddd37e5 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/19-regulator-axp20x-force-polyphase-setup-for-axp323.patch @@ -0,0 +1,135 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Juan Sanchez +Date: Sun, 6 Jul 2025 00:31:46 -0400 +Subject: From: iuncuim Date: Mon, 7 Apr 2025 03:28:37 + +0300 Subject: [PATCH] regulator: axp20x: force polyphase setup for axp323 + +Signed-off-by: Juan Sanchez +--- + arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts | 3 ++ + arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts | 3 ++ + arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts | 3 ++ + arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts | 3 ++ + drivers/regulator/axp20x-regulator.c | 19 ++++++++++ + 5 files changed, 31 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +index f7a6221d02c2..369bde1556ff 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +@@ -330,10 +330,13 @@ reg_dcdc1_323: dcdc1 { + regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpub"; + }; + + /* DCDC2 is polyphased with DCDC1 */ ++ reg_dcdc2_323: dcdc2 { ++ x-powers,polyphased; ++ }; + + /* RISC-V management core supply */ + reg_dcdc3_323: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <900000>; +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts b/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts +index 0d7fb419c9b4..5732088add32 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts +@@ -253,10 +253,13 @@ reg_dcdc1_323: dcdc1 { + regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpub"; + }; + + /* DCDC2 is polyphased with DCDC1 */ ++ reg_dcdc2_323: dcdc2 { ++ x-powers,polyphased; ++ }; + + reg_dcdc3_323: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts b/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts +index 4f2366b3624a..bd1ebb15bb3e 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts +@@ -283,10 +283,13 @@ reg_dcdc1_323: dcdc1 { + regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpub"; + }; + + /* DCDC2 is polyphased with DCDC1 */ ++ reg_dcdc2_323: dcdc2 { ++ x-powers,polyphased; ++ }; + + /* Some RISC-V management core related voltage */ + reg_dcdc3_323: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <900000>; +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts b/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts +index d1ffc9faec80..fb7933091edf 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts +@@ -321,10 +321,13 @@ reg_dcdc1_323: dcdc1 { + regulator-max-microvolt = <1150000>; + regulator-name = "vdd-cpub"; + }; + + /* DCDC2 is polyphased with DCDC1 */ ++ reg_dcdc2_323: dcdc2 { ++ x-powers,polyphased; ++ }; + + /* Some RISC-V management core related voltage */ + reg_dcdc3_323: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <900000>; +diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c +index da891415efc0..2e2d35d31ce6 100644 +--- a/drivers/regulator/axp20x-regulator.c ++++ b/drivers/regulator/axp20x-regulator.c +@@ -1479,10 +1479,23 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work + } + + return regmap_update_bits(rdev->regmap, reg, mask, workmode); + } + ++static void axp20x_set_polyphased(struct axp20x_dev *axp20x, int id) ++{ ++ switch (axp20x->variant) { ++ case AXP323_ID: ++ switch (id) { ++ case AXP313A_DCDC2: ++ regmap_write(axp20x->regmap, AXP323_DCDC_MODE_CTRL2, BIT(1)); ++ } ++ break; ++ ++ default: ++ } ++} + /* + * This function checks whether a regulator is part of a poly-phase + * output setup based on the registers settings. Returns true if it is. + */ + static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id) +@@ -1702,10 +1715,16 @@ static int axp20x_regulator_probe(struct platform_device *pdev) + if (axp20x_set_dcdc_workmode(rdev, i, workmode)) + dev_err(&pdev->dev, "Failed to set workmode on %s\n", + rdev->desc->name); + } + ++ /* ++ * Currently only the AXP323 needs to force dual phase setup. ++ */ ++ if (of_property_read_bool(rdev->dev.of_node,"x-powers,polyphased")) ++ axp20x_set_polyphased(axp20x, i); ++ + /* + * Save AXP22X DCDC1 / DCDC5 / AXP15060 ALDO1 regulator names for later. + */ + if ((regulators == axp22x_regulators && i == AXP22X_DCDC1) || + (regulators == axp809_regulators && i == AXP809_DCDC1) || +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-6.16/20-soc-sunxi-sram-add-entry-for-a523.patch b/patch/kernel/archive/sunxi-6.16/20-soc-sunxi-sram-add-entry-for-a523.patch new file mode 100644 index 000000000..f7b6409d4 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/20-soc-sunxi-sram-add-entry-for-a523.patch @@ -0,0 +1,42 @@ +From: Chen-Yu Tsai + +The A523 has two Ethernet controllers. So in the system controller +address space, there are two registers for Ethernet clock delays, +one for each controller. + +Add a new entry for the A523 system controller that allows access to +the second register. + +Signed-off-by: Chen-Yu Tsai +--- + drivers/soc/sunxi/sunxi_sram.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c +index 08e264ea0697..4f8d510b7e1e 100644 +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -320,6 +320,10 @@ static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = { + .has_ths_offset = true, + }; + ++static const struct sunxi_sramc_variant sun55i_a523_sramc_variant = { ++ .num_emac_clocks = 2, ++}; ++ + #define SUNXI_SRAM_THS_OFFSET_REG 0x0 + #define SUNXI_SRAM_EMAC_CLOCK_REG 0x30 + #define SUNXI_SYS_LDO_CTRL_REG 0x150 +@@ -440,6 +444,10 @@ static const struct of_device_id sunxi_sram_dt_match[] = { + .compatible = "allwinner,sun50i-h616-system-control", + .data = &sun50i_h616_sramc_variant, + }, ++ { ++ .compatible = "allwinner,sun55i-a523-system-control", ++ .data = &sun55i_a523_sramc_variant, ++ }, + { }, + }; + MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match); +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/21-soc-sunxi-sram-register-regmap-as-syscon.patch b/patch/kernel/archive/sunxi-6.16/21-soc-sunxi-sram-register-regmap-as-syscon.patch new file mode 100644 index 000000000..a57e8d465 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/21-soc-sunxi-sram-register-regmap-as-syscon.patch @@ -0,0 +1,44 @@ +From: Chen-Yu Tsai + +Until now, if the system controller had a ethernet controller glue layer +control register, a limited access regmap would be registered and tied +to the system controller struct device for the ethernet driver to use. + +Signed-off-by: Chen-Yu Tsai +--- + drivers/soc/sunxi/sunxi_sram.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c +index 4f8d510b7e1e..63c23bdffa78 100644 +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -12,6 +12,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -377,6 +378,7 @@ static int __init sunxi_sram_probe(struct platform_device *pdev) + const struct sunxi_sramc_variant *variant; + struct device *dev = &pdev->dev; + struct regmap *regmap; ++ int ret; + + sram_dev = &pdev->dev; + +@@ -394,6 +396,10 @@ static int __init sunxi_sram_probe(struct platform_device *pdev) + regmap = devm_regmap_init_mmio(dev, base, &sunxi_sram_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); ++ ++ ret = of_syscon_register_regmap(dev->of_node, regmap); ++ if (IS_ERR(ret)) ++ return ret; + } + + of_platform_populate(dev->of_node, NULL, NULL, dev); +-- +2.39.5 diff --git a/patch/kernel/archive/sunxi-6.16/22-arm64-dts-allwinner-a523-enable-Mali-GPU-for-all-boards.patch b/patch/kernel/archive/sunxi-6.16/22-arm64-dts-allwinner-a523-enable-Mali-GPU-for-all-boards.patch new file mode 100644 index 000000000..ad92e4d52 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/22-arm64-dts-allwinner-a523-enable-Mali-GPU-for-all-boards.patch @@ -0,0 +1,96 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Juan Sanchez +Date: Sun, 6 Jul 2025 00:12:02 -0400 +Subject: From: Mikhail Kalashnikov + +Signed-off-by: Juan Sanchez +--- + arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts | 5 +++++ + arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts | 5 +++++ + arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts | 5 +++++ + arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts | 5 +++++ + 4 files changed, 20 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +index 592a50436454..f7a6221d02c2 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +@@ -103,10 +103,15 @@ &gmac1 { + allwinner,rx-delay-ps = <400>; + + status = "okay"; + }; + ++&gpu { ++ mali-supply = <®_dcdc2>; ++ status = "okay"; ++}; ++ + &mdio0 { + ext_rgmii0_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + reset-gpios = <&pio 7 8 GPIO_ACTIVE_LOW>; /* PH8 */ +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts b/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts +index 59db103546f6..0d7fb419c9b4 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts +@@ -52,10 +52,15 @@ &ehci0 { + + &ehci1 { + status = "okay"; + }; + ++&gpu { ++ mali-supply = <®_dcdc2>; ++ status = "okay"; ++}; ++ + &mmc0 { + vmmc-supply = <®_vcc3v3>; + cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */ + bus-width = <4>; + disable-wp; +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts b/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts +index 142177c1f737..4f2366b3624a 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts +@@ -74,10 +74,15 @@ &gmac0 { + allwinner,rx-delay-ps = <300>; + + status = "okay"; + }; + ++&gpu { ++ mali-supply = <®_dcdc2>; ++ status = "okay"; ++}; ++ + &mdio0 { + ext_rgmii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts b/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts +index ff2fd8e71e03..d1ffc9faec80 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts +@@ -93,10 +93,15 @@ &ehci0 { + + &ehci1 { + status = "okay"; + }; + ++&gpu { ++ mali-supply = <®_dcdc2>; ++ status = "okay"; ++}; ++ + &mmc0 { + vmmc-supply = <®_cldo3>; + cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */ + bus-width = <4>; + status = "okay"; +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-6.16/23-arm64-dts-allwinner-a523-Add-GMAC200-ethernet-controller.patch b/patch/kernel/archive/sunxi-6.16/23-arm64-dts-allwinner-a523-Add-GMAC200-ethernet-controller.patch new file mode 100644 index 000000000..0b9bd611e --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/23-arm64-dts-allwinner-a523-Add-GMAC200-ethernet-controller.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Juan Sanchez +Date: Sat, 2 Aug 2025 00:36:05 -0400 +Subject: Subject: From: Chen-Yu Tsai + +Signed-off-by: Juan Sanchez +--- + arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 55 ++++++++++ + 1 file changed, 55 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +index 7fbba60ec76e..50bebaa67d32 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +@@ -178,10 +178,20 @@ rgmii0_pins: rgmii0-pins { + function = "gmac0"; + drive-strength = <40>; + bias-disable; + }; + ++ rgmii1_pins: rgmii1-pins { ++ pins = "PJ0", "PJ1", "PJ2", "PJ3", "PJ4", ++ "PJ5", "PJ6", "PJ7", "PJ8", "PJ9", ++ "PJ11", "PJ12", "PJ13", "PJ14", "PJ15"; ++ allwinner,pinmux = <5>; ++ function = "gmac1"; ++ drive-strength = <40>; ++ bias-disable; ++ }; ++ + uart0_pb_pins: uart0-pb-pins { + pins = "PB9", "PB10"; + allwinner,pinmux = <2>; + function = "uart0"; + }; +@@ -593,10 +603,55 @@ mdio0: mdio { + #address-cells = <1>; + #size-cells = <0>; + }; + }; + ++ gmac1: ethernet@4510000 { ++ compatible = "allwinner,sun55i-a523-gmac200", ++ "snps,dwmac-4.20a"; ++ reg = <0x04510000 0x10000>; ++ clocks = <&ccu CLK_BUS_EMAC1>, <&ccu CLK_MBUS_EMAC1>; ++ clock-names = "stmmaceth", "mbus"; ++ resets = <&ccu RST_BUS_EMAC1>; ++ reset-names = "stmmaceth"; ++ interrupts = ; ++ interrupt-names = "macirq"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmii1_pins>; ++ power-domains = <&pck600 PD_VO1>; ++ syscon = <&syscon>; ++ snps,fixed-burst; ++ snps,axi-config = <&gmac1_stmmac_axi_setup>; ++ snps,mtl-rx-config = <&gmac1_mtl_rx_setup>; ++ snps,mtl-tx-config = <&gmac1_mtl_tx_setup>; ++ status = "disabled"; ++ ++ mdio1: mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ gmac1_mtl_rx_setup: rx-queues-config { ++ snps,rx-queues-to-use = <1>; ++ ++ queue0 {}; ++ }; ++ ++ gmac1_stmmac_axi_setup: stmmac-axi-config { ++ snps,wr_osr_lmt = <0xf>; ++ snps,rd_osr_lmt = <0xf>; ++ snps,blen = <256 128 64 32 16 8 4>; ++ }; ++ ++ gmac1_mtl_tx_setup: tx_queues-config { ++ snps,tx-queues-to-use = <1>; ++ ++ queue0 {}; ++ }; ++ }; ++ + ppu: power-controller@7001400 { + compatible = "allwinner,sun55i-a523-ppu"; + reg = <0x07001400 0x400>; + clocks = <&r_ccu CLK_BUS_R_PPU1>; + resets = <&r_ccu RST_BUS_R_PPU1>; +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-6.16/24-Enable-uart1-on-Radxa-Cubie-A5E.patch b/patch/kernel/archive/sunxi-6.16/24-Enable-uart1-on-Radxa-Cubie-A5E.patch new file mode 100644 index 000000000..ef8377636 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/24-Enable-uart1-on-Radxa-Cubie-A5E.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Juan Sanchez +Date: Tue, 5 Aug 2025 14:55:52 -0400 +Subject: Enable uart1 (bluetooth) on Radxa Cubie A5E + +Signed-off-by: Juan Sanchez +--- + arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +index 369bde1556ff..37585cac6648 100644 +--- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts ++++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +@@ -14,10 +14,11 @@ / { + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + ethernet2 = &sdio_wifi; + serial0 = &uart0; ++ serial1 = &uart1; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +@@ -360,10 +361,18 @@ &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; + }; + ++/* Bluetooth */ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; ++ uart-has-rtscts; ++ status = "okay"; ++}; ++ + &usb_otg { + /* + * The USB-C port is the primary power supply, so in this configuration + * relies on the other end of the USB cable to supply the VBUS power. + * So use this port in peripheral mode. +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-dev-6.14/0801-net-wireless-backport-aic8800-sdio-v2024_0327_3561b08f.patch b/patch/kernel/archive/sunxi-dev-6.14/0801-net-wireless-backport-aic8800-sdio-v2024_0327_3561b08f.patch deleted file mode 100644 index 8b00d029d..000000000 --- a/patch/kernel/archive/sunxi-dev-6.14/0801-net-wireless-backport-aic8800-sdio-v2024_0327_3561b08f.patch +++ /dev/null @@ -1,84726 +0,0 @@ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800d80_compat.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800d80_compat.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800d80_compat.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800d80_compat.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,252 @@ -+#include "aic8800d80_compat.h" -+#include "aic_bsp_driver.h" -+ -+extern struct aicbsp_info_t aicbsp_info; -+extern int adap_test; -+ -+typedef u32 (*array2_tbl_t)[2]; -+ -+#define AIC_PATCH_MAGIG_NUM 0x48435450 // "PTCH" -+#define AIC_PATCH_MAGIG_NUM_2 0x50544348 // "HCTP" -+#define AIC_PATCH_BLOCK_MAX 4 -+ -+typedef struct { -+ uint32_t magic_num; -+ uint32_t pair_start; -+ uint32_t magic_num_2; -+ uint32_t pair_count; -+ uint32_t block_dst[AIC_PATCH_BLOCK_MAX]; -+ uint32_t block_src[AIC_PATCH_BLOCK_MAX]; -+ uint32_t block_size[AIC_PATCH_BLOCK_MAX]; // word count -+} aic_patch_t; -+ -+#define AIC_PATCH_OFST(mem) ((size_t) &((aic_patch_t *)0)->mem) -+#define AIC_PATCH_ADDR(mem) ((u32)(aic_patch_str_base + AIC_PATCH_OFST(mem))) -+ -+u32 aicbsp_syscfg_tbl_8800d80[][2] = { -+}; -+ -+int aicbsp_system_config_8800d80(struct aic_sdio_dev *sdiodev) -+{ -+ int syscfg_num = sizeof(aicbsp_syscfg_tbl_8800d80) / sizeof(u32) / 2; -+ int ret, cnt; -+ for (cnt = 0; cnt < syscfg_num; cnt++) { -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, aicbsp_syscfg_tbl_8800d80[cnt][0], aicbsp_syscfg_tbl_8800d80[cnt][1]); -+ if (ret) { -+ printk("%x write fail: %d\n", aicbsp_syscfg_tbl_8800d80[cnt][0], ret); -+ return ret; -+ } -+ } -+ return 0; -+} -+ -+ -+u32 adaptivity_patch_tbl_8800d80[][2] = { -+ {0x000C, 0x0000320A}, //linkloss_thd -+ {0x009C, 0x00000000}, //ac_param_conf -+ {0x0168, 0x00010000}, //tx_adaptivity_en -+}; -+ -+#define USER_CHAN_MAX_TXPWR_EN_FLAG (0x01U << 1) -+#define USER_TX_USE_ANA_F_FLAG (0x01U << 2) -+ -+#define CFG_USER_CHAN_MAX_TXPWR_EN 0 -+#define CFG_USER_TX_USE_ANA_F 0 -+ -+#define CFG_USER_EXT_FLAGS_EN (CFG_USER_CHAN_MAX_TXPWR_EN || CFG_USER_TX_USE_ANA_F) -+ -+u32 patch_tbl_8800d80[][2] = { -+ #ifdef USE_5G -+ {0x00b4, 0xf3010001}, -+ #else -+ {0x00b4, 0xf3010000}, -+ #endif -+#if defined(CONFIG_AMSDU_RX) -+ {0x170, 0x0100000a} -+#endif -+#ifdef CONFIG_IRQ_FALL -+ {0x00000170, 0x0000010a}, //irqf -+#endif -+ -+ #if CFG_USER_EXT_FLAGS_EN -+ {0x0188, 0x00000001 -+ #if CFG_USER_CHAN_MAX_TXPWR_EN -+ | USER_CHAN_MAX_TXPWR_EN_FLAG -+ #endif -+ #if CFG_USER_TX_USE_ANA_F -+ | USER_TX_USE_ANA_F_FLAG -+ #endif -+ }, // user_ext_flags -+ #endif -+}; -+ -+#ifdef CONFIG_OOB -+// for 8800d40/d80 map data1 isr to gpiob1 -+u32 gpio_cfg_tbl_8800d40d80[][2] = { -+ {0x40504084, 0x00000006}, -+ {0x40500040, 0x00000000}, -+ {0x40100030, 0x00000001}, -+ {0x40241020, 0x00000001}, -+ {0x40240030, 0x00000004}, -+ {0x40240020, 0x03020700}, -+}; -+#endif -+ -+int aicwifi_sys_config_8800d80(struct aic_sdio_dev *sdiodev) -+{ -+#ifdef CONFIG_OOB -+ int ret, cnt; -+ int gpiocfg_num = sizeof(gpio_cfg_tbl_8800d40d80) / sizeof(u32) / 2; -+ for (cnt = 0; cnt < gpiocfg_num; cnt++) { -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, gpio_cfg_tbl_8800d40d80[cnt][0], gpio_cfg_tbl_8800d40d80[cnt][1]); -+ if (ret) { -+ printk("%x write fail: %d\n", gpio_cfg_tbl_8800d40d80[cnt][0], ret); -+ return ret; -+ } -+ } -+#endif -+ -+ return 0; -+} -+ -+#define NEW_PATCH_BUFFER_MAP 1 -+ -+int aicwifi_patch_config_8800d80(struct aic_sdio_dev *sdiodev) -+{ -+ const u32 rd_patch_addr = RAM_FMAC_FW_ADDR + 0x0198; -+ u32 aic_patch_addr; -+ u32 config_base, aic_patch_str_base; -+ #if (NEW_PATCH_BUFFER_MAP) -+ u32 patch_buff_addr, patch_buff_base, rd_version_addr, rd_version_val; -+ #endif -+ uint32_t start_addr = 0x0016F800; -+ u32 patch_addr = start_addr; -+ u32 patch_cnt = sizeof(patch_tbl_8800d80)/sizeof(u32)/2; -+ struct dbg_mem_read_cfm rd_patch_addr_cfm; -+ int ret = 0; -+ int cnt = 0; -+ //adap test -+ int adap_patch_cnt = 0; -+ -+ if (adap_test) { -+ printk("%s for adaptivity test \r\n", __func__); -+ adap_patch_cnt = sizeof(adaptivity_patch_tbl_8800d80)/sizeof(u32)/2; -+ } -+ -+ aic_patch_addr = rd_patch_addr + 8; -+ -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, rd_patch_addr, &rd_patch_addr_cfm); -+ if (ret) { -+ printk("patch rd fail\n"); -+ return ret; -+ } -+ -+ config_base = rd_patch_addr_cfm.memdata; -+ -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, aic_patch_addr, &rd_patch_addr_cfm); -+ if (ret) { -+ printk("patch str rd fail\n"); -+ return ret; -+ } -+ aic_patch_str_base = rd_patch_addr_cfm.memdata; -+ -+ #if (NEW_PATCH_BUFFER_MAP) -+ rd_version_addr = RAM_FMAC_FW_ADDR + 0x01C; -+ if ((ret = rwnx_send_dbg_mem_read_req(sdiodev, rd_version_addr, &rd_patch_addr_cfm))) { -+ printk("version val[0x%x] rd fail: %d\n", rd_version_addr, ret); -+ return ret; -+ } -+ rd_version_val = rd_patch_addr_cfm.memdata; -+ printk("rd_version_val=%08X\n", rd_version_val); -+ sdiodev->fw_version_uint = rd_version_val; -+ if (rd_version_val > 0x06090100) { -+ patch_buff_addr = rd_patch_addr + 12; -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, patch_buff_addr, &rd_patch_addr_cfm); -+ if (ret) { -+ printk("patch buf rd fail\n"); -+ return ret; -+ } -+ patch_buff_base = rd_patch_addr_cfm.memdata; -+ patch_addr = start_addr = patch_buff_base; -+ } -+ #endif -+ -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(magic_num), AIC_PATCH_MAGIG_NUM); -+ if (ret) { -+ printk("0x%x write fail\n", AIC_PATCH_ADDR(magic_num)); -+ return ret; -+ } -+ -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(magic_num_2), AIC_PATCH_MAGIG_NUM_2); -+ if (ret) { -+ printk("0x%x write fail\n", AIC_PATCH_ADDR(magic_num_2)); -+ return ret; -+ } -+ -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(pair_start), patch_addr); -+ if (ret) { -+ printk("0x%x write fail\n", AIC_PATCH_ADDR(pair_start)); -+ return ret; -+ } -+ -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(pair_count), patch_cnt + adap_patch_cnt); -+ if (ret) { -+ printk("0x%x write fail\n", AIC_PATCH_ADDR(pair_count)); -+ return ret; -+ } -+ -+ for (cnt = 0; cnt < patch_cnt; cnt++) { -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt, patch_tbl_8800d80[cnt][0]+config_base); -+ if (ret) { -+ printk("%x write fail\n", start_addr+8*cnt); -+ return ret; -+ } -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt+4, patch_tbl_8800d80[cnt][1]); -+ if (ret) { -+ printk("%x write fail\n", start_addr+8*cnt+4); -+ return ret; -+ } -+ } -+ -+ if (adap_test){ -+ int tmp_cnt = patch_cnt + adap_patch_cnt; -+ for (cnt = patch_cnt; cnt < tmp_cnt; cnt++) { -+ int tbl_idx = cnt - patch_cnt; -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt, adaptivity_patch_tbl_8800d80[tbl_idx][0]+config_base); -+ if(ret) { -+ printk("%x write fail\n", start_addr+8*cnt); -+ return ret; -+ } -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt+4, adaptivity_patch_tbl_8800d80[tbl_idx][1]); -+ if(ret) { -+ printk("%x write fail\n", start_addr+8*cnt+4); -+ return ret; -+ } -+ } -+ } -+ -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(block_size[0]), 0); -+ if (ret) { -+ printk("block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[0]), ret); -+ return ret; -+ } -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(block_size[1]), 0); -+ if (ret) { -+ printk("block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[1]), ret); -+ return ret; -+ } -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(block_size[2]), 0); -+ if (ret) { -+ printk("block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[2]), ret); -+ return ret; -+ } -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(block_size[3]), 0); -+ if (ret) { -+ printk("block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[3]), ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800d80_compat.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800d80_compat.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800d80_compat.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800d80_compat.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,24 @@ -+#ifndef _AIC8800D80_COMPAT_H_ -+#define _AIC8800D80_COMPAT_H_ -+ -+#include "aicsdio.h" -+/*typedef u32 (*array2_tbl_t)[2]; -+ -+typedef uint8_t u8_l; -+typedef int8_t s8_l; -+typedef bool bool_l; -+typedef uint16_t u16_l; -+typedef int16_t s16_l; -+typedef uint32_t u32_l; -+typedef int32_t s32_l; -+typedef uint64_t u64_l;*/ -+ -+int aicbsp_system_config_8800d80(struct aic_sdio_dev *sdiodev); -+int aicwifi_sys_config_8800d80(struct aic_sdio_dev *sdiodev); -+int aicwifi_patch_config_8800d80(struct aic_sdio_dev *sdiodev); -+ -+ -+#endif -+ -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800dc_compat.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800dc_compat.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800dc_compat.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800dc_compat.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,2275 @@ -+#include -+#include "aic8800dc_compat.h" -+#include "aic_bsp_driver.h" -+ -+u8 chip_sub_id = 0; -+u8 chip_mcu_id = 0; -+extern int testmode; -+ -+u32 syscfg_tbl_8800dc[][2] = { -+ {0x40500010, 0x00000004}, -+ {0x40500010, 0x00000006},//160m clk -+}; -+ -+u32 syscfg_tbl_8800dc_sdio_u01[][2] = { -+ {0x40030000, 0x00036724}, // loop forever after assert_err -+ {0x0011E800, 0xE7FE4070}, -+ {0x40030084, 0x0011E800}, -+ {0x40030080, 0x00000001}, -+ {0x4010001C, 0x00000000}, -+}; -+ -+u32 syscfg_tbl_8800dc_sdio_u02[][2] = { -+ {0x40030000, 0x00036DA4}, // loop forever after assert_err -+ {0x0011E800, 0xE7FE4070}, -+ {0x40030084, 0x0011E800}, -+ {0x40030080, 0x00000001}, -+ {0x4010001C, 0x00000000}, -+}; -+#ifdef CONFIG_OOB -+u32 oobcfg_tbl_8800dc_sdio_u02[][2] = { -+ {0x40504044, 0x2},//oob_enable -+ {0x40500060, 0x03020700}, -+ {0x40500040, 0}, -+ {0x40100030, 1}, -+ {0x40241020, 1}, -+ {0x402400f0, 0x340022}, -+}; -+#endif //CONFIG_OOB -+ -+ -+u32 syscfg_tbl_masked_8800dc[][3] = { -+ //#ifdef CONFIG_PMIC_SETTING -+ #if defined(CONFIG_VRF_DCDC_MODE) -+ {0x7000216C, (0x3 << 2), (0x1 << 2)}, // pmic_pmu_init -+ {0x700021BC, (0x3 << 2), (0x1 << 2)}, -+ {0x70002118, ((0x7 << 4) | (0x1 << 7)), ((0x2 << 4) | (0x1 << 7))}, -+ {0x70002104, ((0x3F << 0) | (0x1 << 6)), ((0x2 << 0) | (0x1 << 6))}, -+ {0x7000210C, ((0x3F << 0) | (0x1 << 6)), ((0x2 << 0) | (0x1 << 6))}, -+ {0x70002170, (0xF << 0), (0x1 << 0)}, -+ {0x70002190, (0x3F << 0), (24 << 0)}, -+ {0x700021CC, ((0x7 << 4) | (0x1 << 7)), ((0x0 << 4) | (0x0 << 7))}, -+ {0x700010A0, (0x1 << 11), (0x1 << 11)}, -+ {0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, -+ {0x70001038, (0x1 << 8), (0x1 << 8)}, -+ {0x70001094, (0x3 << 2), (0x0 << 2)}, -+ {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, -+ {0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)), -+ ((0x1 << 0) | (0x1 << 20) | (0x0 << 22))}, -+ {0x70001028, (0xf << 2), (0x1 << 2)}, -+ #else -+ {0x7000216C, (0x3 << 2), (0x1 << 2)}, // pmic_pmu_init -+ {0x700021BC, (0x3 << 2), (0x1 << 2)}, -+ {0x70002118, ((0x7 << 4) | (0x1 << 7)), ((0x2 << 4) | (0x1 << 7))}, -+ {0x70002104, ((0x3F << 0) | (0x1 << 6)), ((0x2 << 0) | (0x1 << 6))}, -+ {0x7000210C, ((0x3F << 0) | (0x1 << 6)), ((0x2 << 0) | (0x1 << 6))}, -+ {0x70002170, (0xF << 0), (0x1 << 0)}, -+ {0x70002190, (0x3F << 0), (24 << 0)}, -+ {0x700021CC, ((0x7 << 4) | (0x1 << 7)), ((0x0 << 4) | (0x0 << 7))}, -+ {0x700010A0, (0x1 << 11), (0x1 << 11)}, -+ {0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, -+ {0x70001038, (0x1 << 8), (0x1 << 8)}, -+ {0x70001094, (0x3 << 2), (0x0 << 2)}, -+ {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, -+ {0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)), -+ ((0x0 << 0) | (0x1 << 20) | (0x0 << 22))}, -+ {0x70001028, (0xf << 2), (0x1 << 2)}, -+ #endif -+ //#endif /* CONFIG_PMIC_SETTING */ -+ {0x00000000, 0x00000000, 0x00000000}, // last one -+}; -+ -+u32 syscfg_tbl_masked_8800dc_h[][3] = { -+ {0x7000216C, ((0x3 << 2) | (0x3 << 4)), ((0x2 << 2) | (0x2 << 4))}, // pmic_pmu_init -+ {0x70002138, (0xFF << 0), (0xFF << 0)}, -+ {0x7000213C, (0xFF << 0), (0xFF << 0)}, -+ {0x70002144, (0xFF << 0), (0xFF << 0)}, -+ {0x700021BC, (0x3 << 2), (0x1 << 2)}, -+ {0x70002118, ((0x7 << 4) | (0x1 << 7)), ((0x2 << 4) | (0x1 << 7))}, -+ {0x70002104, ((0x3F << 0) | (0x1 << 6)), ((0x2 << 0) | (0x1 << 6))}, -+ {0x7000210C, ((0x3F << 0) | (0x1 << 6)), ((0x2 << 0) | (0x1 << 6))}, -+ {0x70002170, (0xF << 0), (0x1 << 0)}, -+ {0x70002190, (0x3F << 0), (24 << 0)}, -+ {0x700021CC, ((0x7 << 4) | (0x1 << 7)), ((0x0 << 4) | (0x0 << 7))}, -+ {0x700010A0, (0x1 << 11), (0x1 << 11)}, -+ //{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, -+ {0x70001038, (0x1 << 8), (0x1 << 8)}, -+ {0x70001094, (0x3 << 2), (0x0 << 2)}, -+ {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, -+ #if defined(CONFIG_VRF_DCDC_MODE) -+ {0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)), -+ ((0x1 << 0) | (0x1 << 20) | (0x0 << 22))}, -+ #else -+ {0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)), -+ ((0x0 << 0) | (0x1 << 20) | (0x0 << 22))}, -+ #endif -+ {0x70001028, (0xf << 2), (0x1 << 2)}, -+ -+ {0x00000000, 0x00000000, 0x00000000}, // last one -+}; -+ -+u32 syscfg_tbl_masked_8800dc_u01[][3] = { -+ //#ifdef CONFIG_PMIC_SETTING -+ {0x70001000, (0x1 << 16), (0x1 << 16)}, // for low temperature -+ {0x70001028, (0x1 << 6), (0x1 << 6)}, -+ {0x70001000, (0x1 << 16), (0x0 << 16)}, -+ //#endif /* CONFIG_PMIC_SETTING */ -+}; -+ -+u32 patch_tbl_wifisetting_8800dc_u01[][2] = -+{ -+ {0x010c,0x01001E01} -+}; -+ -+u32 patch_tbl_wifisetting_8800dc_u02[][2] = -+{ -+#if defined(CONFIG_SDIO_PWRCTRL) -+ {0x0124,0x01011E01} -+#else -+ {0x0124,0x01001E01} -+#endif -+}; -+ -+ -+ -+uint32_t ldpc_cfg_ram[] = { -+#if 0//def CONFIG_FPGA_VERIFICATION -+ 0x00363638, -+ 0x1DF8F834, -+ 0x1DF8F834, -+ 0x1DF8F834, -+ 0x1DF8F834, -+ 0x002F2F31, -+ 0x1DF8F82C, -+ 0x1DF8F82C, -+ 0x1DF8F82C, -+ 0x1DF8F82C, -+ 0x00363639, -+ 0x1AA5F834, -+ 0x1AA5F834, -+ 0x1ADEF834, -+ 0x1ADEF834, -+ 0x003A3A3E, -+ 0x1578F436, -+ 0x1578F436, -+ 0x1578F436, -+ 0x15B6F436, -+ 0x003B3B40, -+ 0x1DF8F838, -+ 0x1DF8F838, -+ 0x1DF8F838, -+ 0x1DF8F838, -+ 0x003B3B41, -+ 0x1DC4F838, -+ 0x1DC4F838, -+ 0x1DF8F838, -+ 0x1DF8F838, -+ 0x003B3B40, -+ 0x1781F838, -+ 0x1781F838, -+ 0x1781F838, -+ 0x17C4F838, -+ 0x003B3B40, -+ 0x0E81F838, -+ 0x0E81F838, -+ 0x0E81F838, -+ 0x0E82F838, -+ 0x003F3F43, -+ 0x1A92F83D, -+ 0x1A92F83E, -+ 0x1A92F83D, -+ 0x1ADDF83D, -+ 0x00272729, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x1DF8F843, -+ 0x1DF8F843, -+ 0x00272729, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x1DF8F842, -+ 0x1DF8F842, -+ 0x00262628, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x00252528, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x00262628, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x00242427, -+ 0x1DF8F821, -+ 0x1DF8F821, -+ 0x1DF8F821, -+ 0x1DF8F821, -+ 0x00232326, -+ 0x1DF8F821, -+ 0x1DF8F820, -+ 0x1DF8F820, -+ 0x1DF8F820, -+ 0x00262628, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x00242427, -+ 0x1DF8F821, -+ 0x1DF8F821, -+ 0x1DF8F821, -+ 0x1DF8F821, -+ 0x001F1F21, -+ 0x1DF8F81D, -+ 0x1DF8F81D, -+ 0x1DF8F81D, -+ 0x1DF8F81D, -+ 0x00262643, -+ 0x1DF8F822, -+ 0x1DF8F821, -+ 0x1DF8F821, -+ 0x1DF8F821, -+ 0x0018182B, -+ 0x1DF8F816, -+ 0x1DBDF815, -+ 0x1DF8F815, -+ 0x1DF8F815, -+ 0x0018182A, -+ 0x1195F836, -+ 0x1195F815, -+ 0x1195F815, -+ 0x1196F815, -+ 0x0028282C, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x0027272C, -+ 0x1DF8F824, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x1DF8F823, -+ 0x0082824A, -+ 0x1ADFF841, -+ 0x1ADDF822, -+ 0x1ADEF822, -+ 0x1ADFF822, -+ 0x003E3E40, -+ 0x09D1F81D, -+ 0x095BF81D, -+ 0x095BF81D, -+ 0x095BF81D, -+ 0x0029292D, -+ 0x1DF8F825, -+ 0x1DF8F825, -+ 0x1DF8F825, -+ 0x1DF8F825, -+ 0x0028282C, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x0029292D, -+ 0x1DF8F825, -+ 0x1DF8F825, -+ 0x1DF8F825, -+ 0x1DF8F825, -+ 0x0028282E, -+ 0x1DF8F825, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x0026262C, -+ 0x1DF8F823, -+ 0x1DF8F822, -+ 0x1DF8F822, -+ 0x1DF8F822, -+ 0x0028282D, -+ 0x1DF8F825, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x00282852, -+ 0x1DF8F827, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x1DF8F824, -+ 0x0029294E, -+ 0x1DF8F823, -+ 0x1DF8F822, -+ 0x1DF8F822, -+ 0x1DF8F822, -+ 0x00212143, -+ 0x1DF8F821, -+ 0x1DECF81D, -+ 0x1DF4F81D, -+ 0x1DF8F81D, -+ 0x0086864D, -+ 0x1CF0F844, -+ 0x1CEDF823, -+ 0x1CEFF822, -+ 0x1CF0F822, -+ 0x0047474D, -+ 0x1BE8F823, -+ 0x1BE8F823, -+ 0x1BE9F822, -+ 0x1BEAF822, -+ 0x0018182F, -+ 0x14B0F83C, -+ 0x14B0F814, -+ 0x14B0F814, -+ 0x14B0F814, -+ 0x00404040, -+ 0x0AE1F81E, -+ 0x0A61F81D, -+ 0x0A61F81D, -+ 0x0A61F81D, -+ 0x002C2C40, -+ 0x09555526, -+ 0x09555512, -+ 0x09555513, -+ 0x09555512, -+ 0x00181840, -+ 0x06333329, -+ 0x06333314, -+ 0x06333314, -+ 0x06333314, -+ 0x002B2B2F, -+ 0x1DF8F828, -+ 0x1DF8F828, -+ 0x1DF8F828, -+ 0x1DF8F828, -+ 0x002B2B32, -+ 0x1DF8F829, -+ 0x1DF8F828, -+ 0x1DF8F828, -+ 0x1DF8F828, -+ 0x002A2A2F, -+ 0x1DF8F827, -+ 0x1DF8F827, -+ 0x1DF8F827, -+ 0x1DF8F827, -+ 0x002A2A57, -+ 0x1DF8F82B, -+ 0x1DF8F827, -+ 0x1DF8F827, -+ 0x1DF8F827, -+ 0x00919152, -+ 0x1DF8F84B, -+ 0x1DF8F825, -+ 0x1DF8F825, -+ 0x1DF8F825, -+ 0x004C4C51, -+ 0x1DF8F826, -+ 0x1DF8F825, -+ 0x1DF8F825, -+ 0x1DF8F825, -+ 0x00444440, -+ 0x0CF8F820, -+ 0x0C6EF81F, -+ 0x0C6EF81F, -+ 0x0C6EF81F, -+ 0x00424240, -+ 0x0D75753E, -+ 0x0D75751E, -+ 0x0D75751E, -+ 0x0D75751E, -+ 0x00191940, -+ 0x0539392E, -+ 0x05393914, -+ 0x05393914, -+ 0x05393914, -+ 0x002F2F32, -+ 0x1AA5F82C, -+ 0x1AA5F82C, -+ 0x1ADEF82C, -+ 0x1ADEF82C, -+ 0x002F2F40, -+ 0x0C6EDE2C, -+ 0x0C6EDE2C, -+ 0x0C6EDE2C, -+ 0x0C6EDE2C, -+ 0x00323240, -+ 0x053BB62E, -+ 0x053BB62E, -+ 0x053BB62E, -+ 0x053BB62E, -+ 0x00333339, -+ 0x1DC4F82F, -+ 0x1DC4F82F, -+ 0x1DF8F82F, -+ 0x1DF8F82F, -+ 0x00333340, -+ 0x0E81F82F, -+ 0x0E81F82F, -+ 0x0E81F82F, -+ 0x0E82F82F, -+ 0x00333340, -+ 0x063FC42F, -+ 0x063FC42F, -+ 0x063FC42F, -+ 0x063FC42F, -+ 0x00404040, -+ 0x063FC42F, -+ 0x063FC42F, -+ 0x063FC42F, -+ 0x063FC42F, -+ 0x00363640, -+ 0x0747DD33, -+ 0x0747DD33, -+ 0x0747DD33, -+ 0x0747DD33, -+ 0x00404040, -+ 0x0747DD33, -+ 0x0747DD33, -+ 0x0747DD33, -+ 0x0747DD33, -+ 0x00292940, -+ 0x07484825, -+ 0x07484812, -+ 0x07484812, -+ 0x07484812, -+ 0x00404040, -+ 0x07343428, -+ 0x07343414, -+ 0x07343414, -+ 0x07343414, -+ 0x00404040, -+ 0x0538382A, -+ 0x05383814, -+ 0x05383814, -+ 0x05383814, -+ 0x00404040, -+ 0x05292914, -+ 0x05292909, -+ 0x05292909, -+ 0x05292909, -+ 0x000B0B40, -+ 0x02111108, -+ 0x0211110E, -+ 0x02111108, -+ 0x02111108, -+ 0x00404040, -+ 0x063E3E2E, -+ 0x063E3E15, -+ 0x063E3E14, -+ 0x063E3E14, -+ 0x00404040, -+ 0x062E2E14, -+ 0x062E2E09, -+ 0x062E2E09, -+ 0x062E2E09, -+ 0x000B0B40, -+ 0x02131308, -+ 0x0213130F, -+ 0x02131308, -+ 0x02131308 -+#else -+ 0x00767679, -+ 0x1DF8F870, -+ 0x1DF8F870, -+ 0x1DF8F870, -+ 0x1DF8F870, -+ 0x006E6E72, -+ 0x1DF8F869, -+ 0x1DF8F869, -+ 0x1DF8F869, -+ 0x1DF8F869, -+ 0x0076767B, -+ 0x1DF8F870, -+ 0x1DF8F870, -+ 0x1DF8F870, -+ 0x1DF8F870, -+ 0x007E7E85, -+ 0x1DF4F876, -+ 0x1DF4F876, -+ 0x1DF4F876, -+ 0x1DF8F876, -+ 0x0081818A, -+ 0x1DF8F87B, -+ 0x1DF8F87B, -+ 0x1DF8F87B, -+ 0x1DF8F87B, -+ 0x0081818D, -+ 0x1DF8F87B, -+ 0x1DF8F87B, -+ 0x1DF8F87B, -+ 0x1DF8F87B, -+ 0x0081818A, -+ 0x1DF8F87B, -+ 0x1DF8F87C, -+ 0x1DF8F87B, -+ 0x1DF8F87B, -+ 0x007E7E40, -+ 0x1DF8F87B, -+ 0x1DF8F87B, -+ 0x1DF8F87B, -+ 0x1DF8F87B, -+ 0x008B8B92, -+ 0x1DF8F887, -+ 0x1DF8F889, -+ 0x1DF8F887, -+ 0x1DF8F887, -+ 0x00515155, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x1DF8F889, -+ 0x1DF8F889, -+ 0x00515154, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x1DF8F888, -+ 0x1DF8F888, -+ 0x004F4F53, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x004F4F53, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x004F4F53, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x004E4E53, -+ 0x1DF8F849, -+ 0x1DF8F848, -+ 0x1DF8F848, -+ 0x1DF8F848, -+ 0x004D4D52, -+ 0x1DF8F847, -+ 0x1DF8F847, -+ 0x1DF8F847, -+ 0x1DF8F847, -+ 0x004F4F55, -+ 0x1DF8F84B, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x004E4E53, -+ 0x1DF8F849, -+ 0x1DF8F848, -+ 0x1DF8F848, -+ 0x1DF8F848, -+ 0x0049494D, -+ 0x1DF8F844, -+ 0x1DF8F844, -+ 0x1DF8F844, -+ 0x1DF8F844, -+ 0x0051518F, -+ 0x1DF8F849, -+ 0x1DF8F848, -+ 0x1DF8F848, -+ 0x1DF8F848, -+ 0x00424277, -+ 0x1DF8F83F, -+ 0x1DF8F83C, -+ 0x1DF8F83C, -+ 0x1DF8F83C, -+ 0x00424275, -+ 0x1DF8F89E, -+ 0x1DF8F83C, -+ 0x1DF8F83C, -+ 0x1DF8F83C, -+ 0x0055555C, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x0053535C, -+ 0x1DF8F84C, -+ 0x1DF8F84B, -+ 0x1DF8F84B, -+ 0x1DF8F84B, -+ 0x00F8F89E, -+ 0x1DF8F88C, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x00898940, -+ 0x18F8F846, -+ 0x18CFF845, -+ 0x18CFF844, -+ 0x18CFF844, -+ 0x0056565F, -+ 0x1DF8F84F, -+ 0x1DF8F84F, -+ 0x1DF8F84F, -+ 0x1DF8F84F, -+ 0x0055555E, -+ 0x1DF8F84E, -+ 0x1DF8F84E, -+ 0x1DF8F84E, -+ 0x1DF8F84E, -+ 0x0056565F, -+ 0x1DF8F84F, -+ 0x1DF8F84F, -+ 0x1DF8F84F, -+ 0x1DF8F84F, -+ 0x00555561, -+ 0x1DF8F850, -+ 0x1DF8F84E, -+ 0x1DF8F84E, -+ 0x1DF8F84E, -+ 0x0053535F, -+ 0x1DF8F84D, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x0055555F, -+ 0x1DF8F84F, -+ 0x1DF8F84E, -+ 0x1DF8F84E, -+ 0x1DF8F84E, -+ 0x005555AA, -+ 0x1DF8F854, -+ 0x1DF8F84E, -+ 0x1DF8F84E, -+ 0x1DF8F84E, -+ 0x005959A6, -+ 0x1DF8F84D, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x004F4F9B, -+ 0x1DF8F84E, -+ 0x1DF8F846, -+ 0x1DF8F846, -+ 0x1DF8F846, -+ 0x00F8F8A5, -+ 0x1DF8F894, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x009898A4, -+ 0x1DF8F84D, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x00464686, -+ 0x1DF8F8B3, -+ 0x1DF8F83D, -+ 0x1DF8F83D, -+ 0x1DF8F83D, -+ 0x008E8E40, -+ 0x1AF8F848, -+ 0x1ADFF848, -+ 0x1ADFF846, -+ 0x1ADFF846, -+ 0x007F7F40, -+ 0x18D2D275, -+ 0x18D2D23A, -+ 0x18D2D23A, -+ 0x18D2D239, -+ 0x00454540, -+ 0x0F868664, -+ 0x0F86863E, -+ 0x0F86863D, -+ 0x0F86863D, -+ 0x005C5C64, -+ 0x1DF8F856, -+ 0x1DF8F855, -+ 0x1DF8F855, -+ 0x1DF8F855, -+ 0x005B5B68, -+ 0x1DF8F858, -+ 0x1DF8F855, -+ 0x1DF8F855, -+ 0x1DF8F855, -+ 0x005A5A64, -+ 0x1DF8F855, -+ 0x1DF8F854, -+ 0x1DF8F854, -+ 0x1DF8F854, -+ 0x005A5AB5, -+ 0x1DF8F85B, -+ 0x1DF8F855, -+ 0x1DF8F854, -+ 0x1DF8F854, -+ 0x00F8F8B0, -+ 0x1DF8F8A3, -+ 0x1DF8F852, -+ 0x1DF8F852, -+ 0x1DF8F852, -+ 0x00A4A4AE, -+ 0x1DF8F854, -+ 0x1DF8F852, -+ 0x1DF8F852, -+ 0x1DF8F852, -+ 0x009A9A40, -+ 0x1DF8F84E, -+ 0x1DF8F84D, -+ 0x1DF8F84C, -+ 0x1DF8F84C, -+ 0x009C9C40, -+ 0x1DF8F895, -+ 0x1DF8F849, -+ 0x1DF8F84A, -+ 0x1DF8F84A, -+ 0x00494940, -+ 0x1197976F, -+ 0x11979742, -+ 0x11979741, -+ 0x11979741, -+ 0x006E6E74, -+ 0x1DF8F869, -+ 0x1DF8F869, -+ 0x1DF8F869, -+ 0x1DF8F869, -+ 0x006E6E40, -+ 0x1ADEF869, -+ 0x1ADEF869, -+ 0x1ADEF869, -+ 0x1ADEF869, -+ 0x00757540, -+ 0x0D78F86E, -+ 0x0D78F86E, -+ 0x0D78F86E, -+ 0x0D79F86E, -+ 0x00787885, -+ 0x1DF8F873, -+ 0x1DF8F873, -+ 0x1DF8F873, -+ 0x1DF8F873, -+ 0x00787840, -+ 0x1DF8F873, -+ 0x1DF8F873, -+ 0x1DF8F873, -+ 0x1DF8F873, -+ 0x00787840, -+ 0x0E81F873, -+ 0x0E81F873, -+ 0x0E81F873, -+ 0x0E82F873, -+ 0x00404040, -+ 0x0E82F873, -+ 0x0E82F873, -+ 0x0E82F873, -+ 0x0E82F873, -+ 0x00818140, -+ 0x1092F87E, -+ 0x1092F87E, -+ 0x1092F87E, -+ 0x1092F87E, -+ 0x00404040, -+ 0x1092F87E, -+ 0x1092F87E, -+ 0x1092F87E, -+ 0x1092F87E, -+ 0x00737340, -+ 0x14B2B26B, -+ 0x14B2B235, -+ 0x14B2B235, -+ 0x14B2B235, -+ 0x00404040, -+ 0x0E828260, -+ 0x0E82823D, -+ 0x0E82823C, -+ 0x0E82823C, -+ 0x00404040, -+ 0x0F8B8B66, -+ 0x0F8B8B3F, -+ 0x0F8B8B3D, -+ 0x0F8B8B3D, -+ 0x00404040, -+ 0x0B68683D, -+ 0x0B68681E, -+ 0x0B68681E, -+ 0x0B68681E, -+ 0x00222240, -+ 0x06434318, -+ 0x06434329, -+ 0x06434318, -+ 0x06434318, -+ 0x00404040, -+ 0x129D9D72, -+ 0x129D9D43, -+ 0x129D9D41, -+ 0x129D9D41, -+ 0x00404040, -+ 0x0D757542, -+ 0x0D757520, -+ 0x0D757520, -+ 0x0D757520, -+ 0x00232340, -+ 0x084C4C19, -+ 0x084C4C2C, -+ 0x084C4C19, -+ 0x084C4C19 -+#endif -+}; -+ -+uint32_t agc_cfg_ram[] = { -+ 0x20000000, -+ 0x0400000E, -+ 0x3000200E, -+ 0x5B000000, -+ 0x0400004B, -+ 0x3000008E, -+ 0x32000000, -+ 0x0400007B, -+ 0x40000000, -+ 0xF8000026, -+ 0x04000011, -+ 0x4819008E, -+ 0x9C000020, -+ 0x08000191, -+ 0x38008000, -+ 0x0A000000, -+ 0x08104411, -+ 0x38018000, -+ 0x0C004641, -+ 0x08D00014, -+ 0x30000000, -+ 0x01000000, -+ 0x04000017, -+ 0x30000000, -+ 0x3C000000, -+ 0x0400001A, -+ 0x38020000, -+ 0x40000001, -+ 0x0800001D, -+ 0x3808008E, -+ 0x14000050, -+ 0x08000020, -+ 0x4000008E, -+ 0xA400007B, -+ 0x00000101, -+ 0x3000339F, -+ 0x41000700, -+ 0x04104420, -+ 0x90000000, -+ 0x49000000, -+ 0xF00E842F, -+ 0xEC0E842C, -+ 0xEC0E842C, -+ 0x04000032, -+ 0x30000000, -+ 0x48000101, -+ 0x04000032, -+ 0x30000000, -+ 0x48000202, -+ 0x04000032, -+ 0x30000000, -+ 0x46000000, -+ 0x04000011, -+ 0x58010006, -+ 0x3D040472, -+ 0xDC204439, -+ 0x081DD4D2, -+ 0x480A0006, -+ 0xDC2044DC, -+ 0x081DD43C, -+ 0x38050004, -+ 0x0EF1F1C3, -+ 0x342044DC, -+ 0x30000000, -+ 0x01000000, -+ 0x04000042, -+ 0x30000000, -+ 0x33000000, -+ 0x04104445, -+ 0x38008000, -+ 0x2200109C, -+ 0x08104448, -+ 0x38008000, -+ 0x23D4509C, -+ 0x08104417, -+ 0x9000A000, -+ 0x32000000, -+ 0x18000063, -+ 0x14000060, -+ 0x1C000051, -+ 0x10000057, -+ 0x38028000, -+ 0x0C000001, -+ 0x08D04466, -+ 0x3000200F, -+ 0x00000000, -+ 0x00000000, -+ 0x38030000, -+ 0x0C002601, -+ 0x08D0445A, -+ 0x30000000, -+ 0x3D020230, -+ 0x0400005D, -+ 0x30000000, -+ 0x3E000100, -+ 0x04000066, -+ 0x38028000, -+ 0x0C001601, -+ 0x34204466, -+ 0x38028000, -+ 0x0C000A01, -+ 0x34204466, -+ 0x38008004, -+ 0xFF000000, -+ 0x0800007B, -+ 0x3800802F, -+ 0x26000000, -+ 0x0800006C, -+ 0x380404AF, -+ 0x1F191010, -+ 0x0800006F, -+ 0x20000CAF, -+ 0x04000071, -+ 0x60000CAF, -+ 0x18700079, -+ 0x14000077, -+ 0x10000075, -+ 0x28140CAF, -+ 0x09B00084, -+ 0x280A0CAF, -+ 0x09B00084, -+ 0x28060CAF, -+ 0x09B00084, -+ 0x28048086, -+ 0x0800007D, -+ 0x38000086, -+ 0x22800000, -+ 0x04000080, -+ 0x30000000, -+ 0x0EF1F101, -+ 0x36004883, -+ 0x28020000, -+ 0x08000085, -+ 0x3802008E, -+ 0x3D040431, -+ 0x08000088, -+ 0x3805008E, -+ 0x1F241821, -+ 0x0800008B, -+ 0x3000008E, -+ 0xA0163021, -+ 0x0400008E, -+ 0x3000008E, -+ 0x0EF10012, -+ 0x34000091, -+ 0x300000CC, -+ 0x50000000, -+ 0x04000094, -+ 0x380095FE, -+ 0x32010000, -+ 0x04000097, -+ 0x50001FFE, -+ 0x5A010000, -+ 0x6DC9989B, -+ 0xFC19D4B9, -+ 0x30000186, -+ 0x3D840373, -+ 0x0400009E, -+ 0x3000008E, -+ 0x0A000000, -+ 0x040000A1, -+ 0x3000008E, -+ 0x22C00000, -+ 0x040000A4, -+ 0x9000028E, -+ 0x32010001, -+ 0x8E4000AA, -+ 0xC80000B0, -+ 0x00000000, -+ 0x00000000, -+ 0x3000008E, -+ 0x32010001, -+ 0x040000CB, -+ 0x3000008E, -+ 0x29000000, -+ 0x94045011, -+ 0x300019B6, -+ 0x32010000, -+ 0x040000B3, -+ 0x300019B6, -+ 0x3D040431, -+ 0x040000B6, -+ 0x300019B6, -+ 0x22800000, -+ 0x04000097, -+ 0x30000186, -+ 0x3D840473, -+ 0x040000BC, -+ 0x3000008E, -+ 0x29030000, -+ 0x040000BF, -+ 0x9AEE028E, -+ 0x32010100, -+ 0x7C0000C5, -+ 0xCC0000B0, -+ 0x080000B0, -+ 0x00000000, -+ 0x3000008E, -+ 0x32010100, -+ 0x040000C8, -+ 0x3000028E, -+ 0x29000000, -+ 0x94045011, -+ 0x5000038E, -+ 0x29000000, -+ 0x94045011, -+ 0xC0000035, -+ 0x38010006, -+ 0x3D040472, -+ 0x080000D2, -+ 0x30000004, -+ 0x0EF1F141, -+ 0x340000D5, -+ 0x28040004, -+ 0x080000D7, -+ 0x2808000E, -+ 0x080000D9, -+ 0x3000018E, -+ 0x0EF10052, -+ 0x340000DC, -+ 0x3000038E, -+ 0x29000000, -+ 0x94045011, -+ 0x38020000, -+ 0x32000000, -+ 0x080000E2, -+ 0x60000000, -+ 0xD80000E6, -+ 0xD40000E9, -+ 0x040000EC, -+ 0x30000000, -+ 0x0EF1F121, -+ 0x360048EF, -+ 0x30000000, -+ 0x0C002421, -+ 0x360048EF, -+ 0x30000000, -+ 0x0C000021, -+ 0x360048EF, -+ 0x28020000, -+ 0x0800007B, -+ 0x50001EFE, -+ 0x5A010000, -+ 0x6DC998F5, -+ 0xFC19D4F8, -+ 0x3000028E, -+ 0x32000040, -+ 0x040000FB, -+ 0x3AEE028E, -+ 0x32000080, -+ 0x040000FB, -+ 0x30000000, -+ 0x0EF1F101, -+ 0x360048FE, -+ 0x28020000, -+ 0x08000100, -+ 0x3802008E, -+ 0x3D040431, -+ 0x08000103, -+ 0x3805008E, -+ 0x1F241821, -+ 0x08000106, -+ 0x3000008E, -+ 0xA0163021, -+ 0x04000109, -+ 0x3000008E, -+ 0x0EF10012, -+ 0x3400010C, -+ 0x300014F6, -+ 0x32010000, -+ 0x04000114, -+ 0x20000000, -+ 0x04000111, -+ 0x300000EC, -+ 0x50000000, -+ 0x040000F1, -+ 0x300014F6, -+ 0x32030000, -+ 0x04000117, -+ 0x30001086, -+ 0x3D840473, -+ 0x0400011A, -+ 0x5000108E, -+ 0x22C00000, -+ 0x8E47C0CB, -+ 0xCB30011E, -+ 0x300019B6, -+ 0x32040000, -+ 0x04000121, -+ 0x300019B6, -+ 0x3D040431, -+ 0x04000124, -+ 0x300019B6, -+ 0x22800000, -+ 0x04000111, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x30000186, -+ 0x3D840473, -+ 0x0400012D, -+ 0x5000038E, -+ 0x29000000, -+ 0x94045011, -+ 0xC0000131, -+ 0x380C800E, -+ 0xFF000000, -+ 0x08000134, -+ 0x30000004, -+ 0x0FF1F103, -+ 0x34000137, -+ 0x28020000, -+ 0x08000139, -+ 0x3000038E, -+ 0x29000000, -+ 0x94045011, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x58010006, -+ 0x3D040472, -+ 0xDC204543, -+ 0x081DD4D2, -+ 0x480A0006, -+ 0xDC2044DC, -+ 0x081DD546, -+ 0x38050004, -+ 0x0EF1F141, -+ 0x342044DC, -+ 0x2802800E, -+ 0x080000DC, -+ 0x48000035, -+ 0x0400014A, -+ 0x7896638F, -+ 0x4100000F, -+ 0x8C00014F, -+ 0x080450C4, -+ 0x90104574, -+ 0x88C8620F, -+ 0xC000015A, -+ 0x90104574, -+ 0x08104554, -+ 0x94104557, -+ 0x3000628F, -+ 0x29000000, -+ 0x9404517A, -+ 0x3000638F, -+ 0x29000000, -+ 0x0410457A, -+ 0x3800E005, -+ 0x3D010131, -+ 0x0810455D, -+ 0xA832600F, -+ 0x90104574, -+ 0x08000154, -+ 0x94104557, -+ 0xC6104567, -+ 0xC4185563, -+ 0x5802E00F, -+ 0x0FEEEA07, -+ 0x80000174, -+ 0x3420456B, -+ 0x5802E00F, -+ 0x0EEEEA07, -+ 0x80000174, -+ 0x3420456B, -+ 0x30004000, -+ 0x33000001, -+ 0x0400016E, -+ 0x38034005, -+ 0x3D030373, -+ 0x08000171, -+ 0x30006007, -+ 0x33000000, -+ 0x04000174, -+ 0x3000608F, -+ 0x29000000, -+ 0x94045177, -+ 0x4000608F, -+ 0xA010457D, -+ 0x0410457A, -+ 0x3000608F, -+ 0x64000101, -+ 0x04104411, -+ 0x3000608F, -+ 0x64000101, -+ 0x04104580, -+ 0x3000618F, -+ 0x42000001, -+ 0x04000183, -+ 0x38028000, -+ 0x32000000, -+ 0x08104586, -+ 0x280A618F, -+ 0x08000188, -+ 0x480A618F, -+ 0xBC00018B, -+ 0x0800018E, -+ 0x3000618F, -+ 0x34000001, -+ 0x04000005, -+ 0x3000618F, -+ 0x34000000, -+ 0x04000008, -+ 0x3000008F, -+ 0x0EEAED0F, -+ 0x36000194, -+ 0x38038000, -+ 0x34000000, -+ 0x08000197, -+ 0x38028005, -+ 0x29010002, -+ 0x0800019A, -+ 0x3000028F, -+ 0x2200209C, -+ 0x0400019D, -+ 0x3000028F, -+ 0x23D4509C, -+ 0x040001A0, -+ 0x2814028F, -+ 0x080001A2, -+ 0x3000028F, -+ 0x43010201, -+ 0x040001A5, -+ 0x3000128F, -+ 0x32000100, -+ 0x040001A8, -+ 0x5AEE138F, -+ 0x4100000F, -+ 0x7C0001AC, -+ 0x080000F9, -+ 0x592C138F, -+ 0x29000000, -+ 0x8C0001B0, -+ 0x080000F9, -+ 0x2000138F, -+ 0x94045011, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000 -+}; -+ -+ -+uint32_t txgain_map[96] = { -+#ifdef CONFIG_FPGA_VERIFICATION -+ 0x20c0c971, -+ 0x20c0c980, -+ 0x20c0c992, -+ 0x20c0c9a6, -+ 0x20c0c9bf, -+ 0x20c0caa5, -+ 0x20c0cabd, -+ 0x20c0cba0, -+ 0x20c0cbb6, -+ 0x20c0cbea, -+ 0x20c0ccc5, -+ 0x20c0cdac, -+ 0x20c0cdd0, -+ 0x20c0ceb2, -+ 0x20c0ceff, -+ 0x20c0cfff, -+ 0x20c0c922, -+ 0x20c0c922, -+ 0x20c0c922, -+ 0x20c0c922, -+ 0x20c0c922, -+ 0x20c0c922, -+ 0x20c0c922, -+ 0x20c0c927, -+ 0x20c0c92c, -+ 0x20c0c931, -+ 0x20c0c937, -+ 0x20c0c93f, -+ 0x20c0c946, -+ 0x20c0c94f, -+ 0x20c0c959, -+ 0x20c0c964, -+ 0x20c0cbee, -+ 0x20c0cce0, -+ 0x20c0ccff, -+ 0x20c0cde2, -+ 0x20c0cdfe, -+ 0x20c0cede, -+ 0x20c0cefc, -+ 0x20c0cfd9, -+ 0x20c0cff8, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c98c, -+ 0x20c0ca79, -+ 0x20c0ca89, -+ 0x20c0cb74, -+ 0x20c0cb84, -+ 0x20c0cb94, -+ 0x20c0cba8, -+ 0x20c0cbbb, -+ 0x20c0cbd2, -+ 0x20c0cbee, -+ 0x20c0cce0, -+ 0x20c0ccff, -+ 0x20c0cde2, -+ 0x20c0cdfe, -+ 0x20c0cede, -+ 0x20c0cefc, -+ 0x20c0cfd9, -+ 0x20c0cff8, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0cfff, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c97c, -+ 0x20c0c98c, -+ 0x20c0ca79, -+ 0x20c0ca89, -+ 0x20c0cb74, -+ 0x20c0cb84, -+ 0x20c0cb94, -+ 0x20c0cba8, -+ 0x20c0cbbb, -+ 0x20c0cbd2, -+#else -+ //11b -+ 0x00ffd780, -+ 0x00ffd872, -+ 0x00ffd880, -+ 0x00ffd972, -+ 0x00ffd980, -+ 0x00ffda75, -+ 0x00ffda86, -+ 0x00ffdb77, -+ 0x00ffdb86, -+ 0x00ffdc78, -+ 0x00ffdc89, -+ 0x00ffdd79, -+ 0x00ffdd89, -+ 0x00ffde83, -+ 0x00ffdf79, -+ 0x00ffdf8b, -+ 0x00ffd072, -+ 0x00ffd072, -+ 0x00ffd080, -+ 0x00ffd172, -+ 0x00ffd180, -+ 0x00ffd272, -+ 0x00ffd280, -+ 0x00ffd36d, -+ 0x00ffd379, -+ 0x00ffd46d, -+ 0x00ffd479, -+ 0x00ffd572, -+ 0x00ffd580, -+ 0x00ffd672, -+ 0x00ffd680, -+ 0x00ffd772, -+ //high -+ 0x00ffc87d, -+ 0x00ffc88b, -+ 0x00ffc979, -+ 0x00ffc989, -+ 0x00ffcc4b, -+ 0x00ffcc54, -+ 0x00ffcc5e, -+ 0x00ffcc69, -+ 0x00ffcc78, -+ 0x00ffcc85, -+ 0x00ffcd70, -+ 0x00ffcd80, -+ 0x00ffce70, -+ 0x00ffce80, -+ 0x00ffcf7d, -+ 0x00ffcf90, -+ 0x00ffc080, -+ 0x00ffc090, -+ 0x00ffc180, -+ 0x00ffc190, -+ 0x00ffc27b, -+ 0x00ffc28b, -+ 0x00ffc37b, -+ 0x00ffc390, -+ 0x00ffc485, -+ 0x00ffc495, -+ 0x00ffc579, -+ 0x00ffc589, -+ 0x00ffc679, -+ 0x00ffc689, -+ 0x00ffc780, -+ 0x00ffc790, -+ //low -+ 0x00ffc87d, -+ 0x00ffc88b, -+ 0x00ffc979, -+ 0x00ffc989, -+ 0x00ffcc4b, -+ 0x00ffcc54, -+ 0x00ffcc5e, -+ 0x00ffcc69, -+ 0x00ffcc78, -+ 0x00ffcc85, -+ 0x00ffcd70, -+ 0x00ffcd80, -+ 0x00ffcd90, -+ 0x00ffce80, -+ 0x00ffce93, -+ 0x00ffcf90, -+ 0x00ffc080, -+ 0x00ffc090, -+ 0x00ffc180, -+ 0x00ffc190, -+ 0x00ffc27b, -+ 0x00ffc28b, -+ 0x00ffc37b, -+ 0x00ffc390, -+ 0x00ffc485, -+ 0x00ffc495, -+ 0x00ffc579, -+ 0x00ffc589, -+ 0x00ffc679, -+ 0x00ffc689, -+ 0x00ffc780, -+ 0x00ffc790, -+#endif -+}; -+ -+const uint32_t txgain_map_h[96] = -+{ -+ //11b -+ 0xffd888, //11 -+ 0xffd979, //12 -+ 0xffd988, //13 -+ 0xffda79, //14 -+ 0xffda88, //15 -+ 0xffdb79, //16 -+ 0xffdb88, //17 -+ 0xffdc72, //18 -+ 0xffdc80, //19 -+ 0xffdd80, //20 -+ 0xffde66, //21 -+ 0xffde72, //22 -+ 0xffde80, //23 -+ 0xffdf79, //24 -+ 0xffdf88, //25 -+ 0xffdf98, //26 -+ 0xffd079, //-5 -+ 0xffd088, //-4 -+ 0xffd179, //-3 -+ 0xffd188, //-2 -+ 0xffd288, //-1 -+ 0xffd36c, //0 -+ 0xffd379, //1 -+ 0xffd388, //2 -+ 0xffd479, //3 -+ 0xffd488, //4 -+ 0xffd579, //5 -+ 0xffd588, //6 -+ 0xffd679, //7 -+ 0xffd688, //8 -+ 0xffd779, //9 -+ 0xffd879, //10 -+ //high -+ 0xffc879, //8 -+ 0xffc96b, //9 -+ 0xffc979, //10 -+ 0xffcc45, //11 -+ 0xffcc4d, //12 -+ 0xffcc56, //13 -+ 0xffcc60, //14 -+ 0xffcc6b, //15 -+ 0xffcc79, //16 -+ 0xffcd72, //17 -+ 0xffce60, //18 -+ 0xffce72, //19 -+ 0xffcf72, //20 -+ 0xffcf80, //21 -+ 0xffcf90, //22 -+ 0xffcf90, //23 -+ 0xffc079, //-8 -+ 0xffc16b, //-7 -+ 0xffc179, //-6 -+ 0xffc26b, //-5 -+ 0xffc279, //-4 -+ 0xffc36b, //-3 -+ 0xffc379, //-2 -+ 0xffc46b, //-1 -+ 0xffc479, //0 -+ 0xffc56b, //1 -+ 0xffc579, //2 -+ 0xffc66b, //3 -+ 0xffc679, //4 -+ 0xffc76b, //5 -+ 0xffc779, //6 -+ 0xffc86b, //7 -+ //low -+ 0xffc879, //8 -+ 0xffc96b, //9 -+ 0xffc979, //10 -+ 0xffcc45, //11 -+ 0xffcc4d, //12 -+ 0xffcc56, //13 -+ 0xffcc60, //14 -+ 0xffcc6b, //15 -+ 0xffcc79, //16 -+ 0xffcd72, //17 -+ 0xffce60, //18 -+ 0xffce72, //19 -+ 0xffcf72, //20 -+ 0xffcf80, //21 -+ 0xffcf90, //22 -+ 0xffcf90, //23 -+ 0xffc079, //-8 -+ 0xffc16b, //-7 -+ 0xffc179, //-6 -+ 0xffc26b, //-5 -+ 0xffc279, //-4 -+ 0xffc36b, //-3 -+ 0xffc379, //-2 -+ 0xffc46b, //-1 -+ 0xffc479, //0 -+ 0xffc56b, //1 -+ 0xffc579, //2 -+ 0xffc66b, //3 -+ 0xffc679, //4 -+ 0xffc76b, //5 -+ 0xffc779, //6 -+ 0xffc86b, //7 -+}; -+ -+ -+u32 jump_tbl[][2] = -+{ -+#ifndef CONFIG_FOR_IPCOM -+ {296, 0x180001}, -+ {137, 0x180011}, -+ {303, 0x1810f9}, -+ {168, 0x18186d}, -+ {308, 0x181bbd}, -+ {288, 0x1820c1}, -+#else -+ {308, 0x181001}, -+ {288, 0x181031}, -+ {296, 0x18120d}, -+ {137, 0x18121d}, -+ {303, 0x182305}, -+ {168, 0x182a79}, -+ {258, 0x182ae1}, -+#endif -+}; -+ -+u32 jump_tbl_u02[][2] = -+{ -+ {303, 0x00180d25}, -+ {168, 0x001814a5}, -+ {265, 0x001816b1}, -+ {266, 0x00181849}, -+ {256, 0x001818ad}, -+ {288, 0x00181bf9}, -+ {333, 0x00182d0d}, -+ { 26, 0x00182d45} -+}; -+ -+ -+u32 patch_tbl_func[][2] = -+{ -+#ifndef CONFIG_FOR_IPCOM -+ {0x00110054, 0x0018186D}, // same as jump_tbl idx 168 -+ {0x0011005C, 0x0018186D}, // same as jump_tbl idx 168 -+#else -+ {0x00110054, 0x00182A79}, // same as jump_tbl idx 168 -+ {0x0011005C, 0x00182A79}, // same as jump_tbl idx 168 -+ {0x001118D4, 0x00000011}, -+#endif -+}; -+ -+u32 patch_tbl_func_u02[][2] = -+{ -+ {0x00110054, 0x001814a5}, // same as jump_tbl idx 168 -+ {0x0011005C, 0x001814a5}, // same as jump_tbl idx 168 -+ {0x001109c0, 0x00181e3d}, -+ {0x00110bb4, 0x001824e1}, -+ {0x00110f08, 0x00182d25}, -+}; -+ -+ -+u32 patch_tbl_rf_func[][2] = -+{ -+ {0x00110bf0, 0x00180001}, -+}; -+ -+static u8 chip_id = 0; -+#define CHIP_ID_H_MASK 0xC0 -+#define IS_CHIP_ID_H() ((chip_id & CHIP_ID_H_MASK) == CHIP_ID_H_MASK) -+ -+//Crystal provided by CPU (start) -+int set_bbpll_config(struct aic_sdio_dev *rwnx_hw){ -+// {0x40505010, 0x7C301010},//bbpll -+ int ret = 0; -+ struct dbg_mem_read_cfm rd_mem_addr_cfm; -+ -+ //Read crystal provided by CPU or not. -+ ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x40500148, &rd_mem_addr_cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "%x rd fail: %d\n", 0x40500148, ret); -+ return -1; -+ } -+ -+ AICWFDBG(LOGDEBUG, "%s rd_mem_addr_cfm.memdata:%x \r\n", __func__, rd_mem_addr_cfm.memdata); -+ -+ if(!(rd_mem_addr_cfm.memdata & 0x01)){ -+ AICWFDBG(LOGINFO, "%s Crystal not provided by CPU \r\n", __func__); -+ return 0; -+ }else{ -+ AICWFDBG(LOGINFO, "%s Crystal provided by CPU \r\n", __func__); -+ //Read 0x40505010 value to check bbpll set or not. -+ ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x40505010, &rd_mem_addr_cfm); -+ if(ret < 0){ -+ AICWFDBG(LOGERROR, "%s error ret_val:%d\r\n", __func__, ret); -+ return -1; -+ } -+ -+ if((rd_mem_addr_cfm.memdata >> 29) == 3){ -+ AICWFDBG(LOGERROR, "%s Not need to set \r\n", __func__); -+ return 0; -+ }else{ -+ rd_mem_addr_cfm.memdata |= ((0x1 << 29) | (0x1 << 30)); -+ rd_mem_addr_cfm.memdata &= (~(0x1 << 31)); -+ rwnx_send_dbg_mem_write_req(rwnx_hw, 0x40505010, rd_mem_addr_cfm.memdata); -+ } -+ } -+ return 0; -+} -+//Crystal provided by CPU (end) -+ -+ -+void system_config_8800dc(struct aic_sdio_dev *rwnx_hw) -+{ -+ int syscfg_num; -+ array3_tbl_t p_syscfg_msk_tbl; -+ int ret, cnt; -+ const u32 mem_addr = 0x40500000; -+ struct dbg_mem_read_cfm rd_mem_addr_cfm; -+#ifdef CONFIG_OOB -+ int oobcfg_num; -+#endif -+ -+ ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret); -+ return; -+ } -+ chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16); -+ //printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata); -+ if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL) { -+ chip_mcu_id = 1; -+ } -+ -+ ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret); -+ return; -+ } -+ chip_sub_id = (u8)(rd_mem_addr_cfm.memdata); -+ //printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata); -+ AICWFDBG(LOGINFO, "chip_id=%x, chip_sub_id=%x!!\n", chip_id, chip_sub_id); -+ -+ //Crystal provided by CPU (start) -+ ret = set_bbpll_config(rwnx_hw); -+ if (ret) { -+ AICWFDBG(LOGERROR, "set_bbpll_config fail: %d\n", ret); -+ return; -+ } -+ //Crystal provided by CPU (end) -+ -+ -+ ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x40500010, &rd_mem_addr_cfm); -+ AICWFDBG(LOGDEBUG, "[0x40500010]=%x\n", rd_mem_addr_cfm.memdata); -+ if (ret) { -+ AICWFDBG(LOGERROR, "[0x40500010] rd fail: %d\n", ret); -+ return; -+ } -+ -+ syscfg_num = sizeof(syscfg_tbl_8800dc) / sizeof(uint32_t) / 2; -+ -+ for (cnt = 0; cnt < syscfg_num; cnt++) { -+ ret = rwnx_send_dbg_mem_write_req(rwnx_hw, syscfg_tbl_8800dc[cnt][0], syscfg_tbl_8800dc[cnt][1]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "%x write fail: %d\n", syscfg_tbl_8800dc[cnt][0], ret); -+ return; -+ } -+ } -+ -+ if (chip_mcu_id == 0) { -+ if (chip_sub_id == 0) { -+ syscfg_num = sizeof(syscfg_tbl_8800dc_sdio_u01) / sizeof(u32) / 2; -+ for (cnt = 0; cnt < syscfg_num; cnt++) { -+ ret = rwnx_send_dbg_mem_write_req(rwnx_hw, syscfg_tbl_8800dc_sdio_u01[cnt][0], syscfg_tbl_8800dc_sdio_u01[cnt][1]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "%x write fail: %d\n", syscfg_tbl_8800dc_sdio_u01[cnt][0], ret); -+ return; -+ } -+ } -+ } else if ((chip_sub_id == 1) || (chip_sub_id == 2)) { -+ syscfg_num = sizeof(syscfg_tbl_8800dc_sdio_u02) / sizeof(u32) / 2; -+ for (cnt = 0; cnt < syscfg_num; cnt++) { -+ ret = rwnx_send_dbg_mem_write_req(rwnx_hw, syscfg_tbl_8800dc_sdio_u02[cnt][0], syscfg_tbl_8800dc_sdio_u02[cnt][1]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "%x write fail: %d\n", syscfg_tbl_8800dc_sdio_u02[cnt][0], ret); -+ return; -+ } -+ } -+ } -+ } -+#ifdef CONFIG_OOB -+ if ((chip_sub_id == 1) || (chip_sub_id == 2)) { -+ oobcfg_num = sizeof(oobcfg_tbl_8800dc_sdio_u02) / sizeof(u32) / 2; -+ for (cnt = 0; cnt < oobcfg_num; cnt++) { -+ ret = rwnx_send_dbg_mem_write_req(rwnx_hw, oobcfg_tbl_8800dc_sdio_u02[cnt][0], oobcfg_tbl_8800dc_sdio_u02[cnt][1]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "%x write fail: %d\n", oobcfg_tbl_8800dc_sdio_u02[cnt][0], ret); -+ return; -+ } -+ } -+ } -+#endif -+ if (IS_CHIP_ID_H()) { -+ syscfg_num = sizeof(syscfg_tbl_masked_8800dc_h) / sizeof(u32) / 3; -+ p_syscfg_msk_tbl = syscfg_tbl_masked_8800dc_h; -+ } else { -+ syscfg_num = sizeof(syscfg_tbl_masked_8800dc) / sizeof(u32) / 3; -+ p_syscfg_msk_tbl = syscfg_tbl_masked_8800dc; -+ } -+ -+ -+ for (cnt = 0; cnt < syscfg_num; cnt++) { -+ if (p_syscfg_msk_tbl[cnt][0] == 0x00000000) { -+ break; -+ } else if (p_syscfg_msk_tbl[cnt][0] == 0x70001000) { -+ if (chip_mcu_id == 0) { -+ p_syscfg_msk_tbl[cnt][1] |= ((0x1 << 8) | (0x1 << 15)); // mask -+ p_syscfg_msk_tbl[cnt][2] |= ((0x1 << 8) | (0x1 << 15)); -+ } -+ } -+ -+ ret = rwnx_send_dbg_mem_mask_write_req(rwnx_hw, -+ p_syscfg_msk_tbl[cnt][0], p_syscfg_msk_tbl[cnt][1], p_syscfg_msk_tbl[cnt][2]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "%x mask write fail: %d\n", p_syscfg_msk_tbl[cnt][0], ret); -+ return; -+ } -+ } -+ -+ if (chip_sub_id == 0) { -+ syscfg_num = sizeof(syscfg_tbl_masked_8800dc_u01) / sizeof(u32) / 3; -+ for (cnt = 0; cnt < syscfg_num; cnt++) { -+ ret = rwnx_send_dbg_mem_mask_write_req(rwnx_hw, -+ syscfg_tbl_masked_8800dc_u01[cnt][0], syscfg_tbl_masked_8800dc_u01[cnt][1], syscfg_tbl_masked_8800dc_u01[cnt][2]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "%x mask write fail: %d\n", syscfg_tbl_masked_8800dc_u01[cnt][0], ret); -+ return; -+ } -+ } -+ } -+ -+} -+ -+ -+void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw) -+{ -+ int ret = 0; -+ int cnt = 0; -+ if (testmode == 0) { -+ const u32 cfg_base = 0x10164; -+ struct dbg_mem_read_cfm cfm; -+ int i; -+ u32 wifisetting_cfg_addr; -+ u32 ldpc_cfg_addr; -+ u32 agc_cfg_addr; -+ u32 txgain_cfg_addr; -+ u32 jump_tbl_addr = 0; -+ -+ u32 patch_tbl_wifisetting_num;// = sizeof(patch_tbl_wifisetting_8800dc_u02)/sizeof(u32)/2; -+ u32 ldpc_cfg_size = sizeof(ldpc_cfg_ram); -+ u32 agc_cfg_size = sizeof(agc_cfg_ram); -+ u32 txgain_cfg_size, *txgain_cfg_array; -+ u32 jump_tbl_size = 0; -+ u32 patch_tbl_func_num = 0; -+ -+ array2_tbl_t jump_tbl_base = NULL; -+ array2_tbl_t patch_tbl_func_base = NULL; -+ array2_tbl_t patch_tbl_wifisetting_8800dc_base = NULL; -+ -+ if (chip_sub_id == 0) { -+ jump_tbl_base = jump_tbl; -+ jump_tbl_size = sizeof(jump_tbl)/2; -+ patch_tbl_func_base = patch_tbl_func; -+ patch_tbl_func_num = sizeof(patch_tbl_func)/sizeof(u32)/2; -+ patch_tbl_wifisetting_num = sizeof(patch_tbl_wifisetting_8800dc_u01)/sizeof(u32)/2; -+ patch_tbl_wifisetting_8800dc_base = patch_tbl_wifisetting_8800dc_u01; -+ } else if ((chip_sub_id == 1) || (chip_sub_id == 2)) { -+ patch_tbl_wifisetting_num = sizeof(patch_tbl_wifisetting_8800dc_u02)/sizeof(u32)/2; -+ patch_tbl_wifisetting_8800dc_base = patch_tbl_wifisetting_8800dc_u02; -+ } else { -+ printk("unsupported id: %d", chip_sub_id); -+ return; -+ } -+ -+ //struct dbg_mem_read_cfm cfm; -+ //int i; -+ -+ if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm))) { -+ AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", cfg_base, ret); -+ } -+ wifisetting_cfg_addr = cfm.memdata; -+ -+ if(chip_sub_id == 0){ -+ if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 4, &cfm))) { -+ AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", cfg_base + 4, ret); -+ } -+ jump_tbl_addr = cfm.memdata; -+ } -+ -+ if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 8, &cfm))) { -+ AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", cfg_base + 8, ret); -+ } -+ ldpc_cfg_addr = cfm.memdata; -+ -+ if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0xc, &cfm))) { -+ AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", cfg_base + 0xc, ret); -+ } -+ agc_cfg_addr = cfm.memdata; -+ -+ if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x10, &cfm))) { -+ AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", cfg_base + 0x10, ret); -+ } -+ txgain_cfg_addr = cfm.memdata; -+ -+ AICWFDBG(LOGINFO, "wifisetting_cfg_addr=%x, ldpc_cfg_addr=%x, agc_cfg_addr=%x, txgain_cfg_addr=%x\n", wifisetting_cfg_addr, ldpc_cfg_addr, agc_cfg_addr, txgain_cfg_addr); -+ -+ for (cnt = 0; cnt < patch_tbl_wifisetting_num; cnt++) { -+ if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + patch_tbl_wifisetting_8800dc_base[cnt][0], patch_tbl_wifisetting_8800dc_base[cnt][1]))) { -+ AICWFDBG(LOGERROR, "wifisetting %x write fail\n", patch_tbl_wifisetting_8800dc_base[cnt][0]); -+ } -+ } -+ -+ if (ldpc_cfg_size > 512) {// > 0.5KB data -+ for (i = 0; i < (ldpc_cfg_size - 512); i += 512) {//each time write 0.5KB -+ ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ldpc_cfg_addr + i, 512, ldpc_cfg_ram + i / 4); -+ if (ret) { -+ AICWFDBG(LOGERROR, "ldpc upload fail: %x, err:%d\r\n", ldpc_cfg_addr + i, ret); -+ break; -+ } -+ } -+ } -+ -+ if (!ret && (i < ldpc_cfg_size)) {// < 0.5KB data -+ ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ldpc_cfg_addr + i, ldpc_cfg_size - i, ldpc_cfg_ram + i / 4); -+ if (ret) { -+ AICWFDBG(LOGERROR, "ldpc upload fail: %x, err:%d\r\n", ldpc_cfg_addr + i, ret); -+ } -+ } -+ -+ if (agc_cfg_size > 512) {// > 0.5KB data -+ for (i = 0; i < (agc_cfg_size - 512); i += 512) {//each time write 0.5KB -+ ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, agc_cfg_addr + i, 512, agc_cfg_ram + i / 4); -+ if (ret) { -+ AICWFDBG(LOGERROR, "agc upload fail: %x, err:%d\r\n", agc_cfg_addr + i, ret); -+ break; -+ } -+ } -+ } -+ -+ if (!ret && (i < agc_cfg_size)) {// < 0.5KB data -+ ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, agc_cfg_addr + i, agc_cfg_size - i, agc_cfg_ram + i / 4); -+ if (ret) { -+ AICWFDBG(LOGERROR, "agc upload fail: %x, err:%d\r\n", agc_cfg_addr + i, ret); -+ } -+ } -+ -+ #if !defined(CONFIG_FPGA_VERIFICATION) -+ if ((IS_CHIP_ID_H())) { -+ txgain_cfg_size = sizeof(txgain_map_h); -+ txgain_cfg_array = (u32 *)txgain_map_h; -+ } else { -+ txgain_cfg_size = sizeof(txgain_map); -+ txgain_cfg_array = (u32 *)txgain_map; -+ } -+ ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, txgain_cfg_addr, txgain_cfg_size, txgain_cfg_array); -+ if (ret) { -+ AICWFDBG(LOGERROR, "txgain upload fail: %x, err:%d\r\n", txgain_cfg_addr, ret); -+ } -+ -+ if (chip_sub_id == 0) { -+ for (cnt = 0; cnt < jump_tbl_size/4; cnt+=1) { -+ AICWFDBG(LOGDEBUG, "%x = %x\n", jump_tbl_base[cnt][0]*4+jump_tbl_addr, jump_tbl_base[cnt][1]); -+ if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, jump_tbl_base[cnt][0]*4+jump_tbl_addr, jump_tbl_base[cnt][1]))) { -+ AICWFDBG(LOGERROR, "%x write fail\n", jump_tbl_addr+8*cnt); -+ } -+ } -+ for (cnt = 0; cnt < patch_tbl_func_num; cnt++) { -+ if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_func_base[cnt][0], patch_tbl_func_base[cnt][1]))) { -+ AICWFDBG(LOGERROR, "patch_tbl_func %x write fail\n", patch_tbl_func_base[cnt][0]); -+ } -+ } -+ } else if (chip_sub_id == 1) { -+ ret = aicwf_patch_table_load(rwnx_hw, RWNX_MAC_PATCH_TABLE_8800DC_U02); -+ if(ret){ -+ printk("patch_tbl upload fail: err:%d\r\n", ret); -+ } -+ } else if (chip_sub_id == 2) { -+ ret = aicwf_patch_table_load(rwnx_hw, RWNX_MAC_PATCH_TABLE_8800DC_H_U02); -+ if(ret){ -+ printk("patch_tbl upload fail: err:%d\r\n", ret); -+ } -+ } else { -+ printk("unsupported id: %d\n", chip_sub_id); -+ } -+ -+ #endif -+ } else { -+ if (chip_sub_id == 0) { -+ u32 patch_tbl_rf_func_num = sizeof(patch_tbl_rf_func)/sizeof(u32)/2; -+ for (cnt = 0; cnt < patch_tbl_rf_func_num; cnt++) { -+ if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_rf_func[cnt][0], patch_tbl_rf_func[cnt][1]))) { -+ AICWFDBG(LOGERROR, "patch_tbl_rf_func %x write fail\n", patch_tbl_rf_func[cnt][0]); -+ } -+ } -+ } -+ } -+} -+ -+int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ uint32_t cfg_base = 0x10164; -+ struct dbg_mem_read_cfm cfm; -+ uint32_t misc_ram_addr; -+ uint32_t misc_ram_size = 12; -+ int i; -+ -+ if (testmode == FW_RFTEST_MODE) { -+ cfg_base = RAM_LMAC_FW_ADDR + 0x0164; -+ } -+ // init misc ram -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x14, &cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); -+ return ret; -+ } -+ misc_ram_addr = cfm.memdata; -+ AICWFDBG(LOGERROR, "misc_ram_addr=%x\n", misc_ram_addr); -+ for (i = 0; i < (misc_ram_size / 4); i++) { -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, misc_ram_addr + i * 4, 0); -+ if (ret) { -+ AICWFDBG(LOGERROR, "rf misc ram[0x%x] wr fail: %d\n", misc_ram_addr + i * 4, ret); -+ return ret; -+ } -+ } -+ return ret; -+} -+ -+#ifdef CONFIG_DPD -+int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res) -+{ -+ int ret = 0; -+ uint32_t fw_addr, boot_type; -+ int valid_flag; -+ -+ printk("%s\n", __func__); -+ -+ ret = aicwf_misc_ram_valid_check_8800dc(sdiodev, &valid_flag); -+ if (ret) { -+ AICWFDBG(LOGINFO, "misc ram check fail: %d\n", ret); -+ return ret; -+ } -+ if (valid_flag) { -+ AICWFDBG(LOGINFO, "misc ram valid, skip calib process\n"); -+ return ret; -+ } -+ ret = aicwf_plat_calib_load_8800dc(sdiodev); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load calib bin fail: %d\n", ret); -+ return ret; -+ } -+ /* fw start */ -+ fw_addr = 0x00130009; -+ boot_type = HOST_START_APP_FNCALL; -+ AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type); -+ ret = rwnx_send_dbg_start_app_req(sdiodev, fw_addr, boot_type, NULL); -+ if (ret) { -+ AICWFDBG(LOGINFO, "start app fail: %d\n", ret); -+ return ret; -+ } -+ { // read dpd res -+ const uint32_t cfg_base = 0x10164; -+ struct dbg_mem_read_cfm cfm; -+ uint32_t misc_ram_addr; -+ uint32_t ram_base_addr, ram_word_cnt; -+ int i; -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x14, &cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); -+ return ret; -+ } -+ misc_ram_addr = cfm.memdata; -+ // bit_mask -+ ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask); -+ ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4; -+ for (i = 0; i < ram_word_cnt; i++) { -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, ram_base_addr + i * 4, &cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); -+ return ret; -+ } -+ dpd_res->bit_mask[i] = cfm.memdata; -+ } -+ // dpd_high -+ ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high); -+ ram_word_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high) / 4; -+ for (i = 0; i < ram_word_cnt; i++) { -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, ram_base_addr + i * 4, &cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); -+ return ret; -+ } -+ dpd_res->dpd_high[i] = cfm.memdata; -+ } -+ // loft_res -+ ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res); -+ ram_word_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res) / 4; -+ for (i = 0; i < ram_word_cnt; i++) { -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, ram_base_addr + i * 4, &cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); -+ return ret; -+ } -+ dpd_res->loft_res[i] = cfm.memdata; -+ } -+ } -+ return ret; -+} -+ -+int aicwf_dpd_result_apply_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res) -+{ -+ int ret = 0; -+ uint32_t cfg_base = 0x10164; -+ struct dbg_mem_read_cfm cfm; -+ uint32_t misc_ram_addr; -+ uint32_t ram_base_addr, ram_byte_cnt; -+ AICWFDBG(LOGINFO, "bit_mask[1]=%x\n", dpd_res->bit_mask[1]); -+ if (dpd_res->bit_mask[1] == 0) { -+ AICWFDBG(LOGERROR, "void dpd_res, bypass it.\n"); -+ return 0; -+ } -+ if (testmode == FW_RFTEST_MODE) { -+ cfg_base = RAM_LMAC_FW_ADDR + 0x0164; -+ } -+ if ((ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x14, &cfm))) { -+ AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); -+ return ret; -+ } -+ misc_ram_addr = cfm.memdata; -+ AICWFDBG(LOGINFO, "misc_ram_addr: %x\n", misc_ram_addr); -+ /* Copy dpd_res on the Embedded side */ -+ // bit_mask -+ AICWFDBG(LOGINFO, "bit_mask[0]=%x\n", dpd_res->bit_mask[0]); -+ ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask); -+ ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved); -+ ret = rwnx_send_dbg_mem_block_write_req(sdiodev, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->bit_mask[0]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "bit_mask wr fail: %x, ret:%d\r\n", ram_base_addr, ret); -+ return ret; -+ } -+ // dpd_high -+ AICWFDBG(LOGINFO, "dpd_high[0]=%x\n", dpd_res->dpd_high[0]); -+ ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high); -+ ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high); -+ ret = rwnx_send_dbg_mem_block_write_req(sdiodev, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->dpd_high[0]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "dpd_high wr fail: %x, ret:%d\r\n", ram_base_addr, ret); -+ return ret; -+ } -+ // loft_res -+ AICWFDBG(LOGINFO, "loft_res[0]=%x\n", dpd_res->loft_res[0]); -+ ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res); -+ ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res); -+ ret = rwnx_send_dbg_mem_block_write_req(sdiodev, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->loft_res[0]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "loft_res wr fail: %x, ret:%d\r\n", ram_base_addr, ret); -+ return ret; -+ } -+ return ret; -+} -+ -+#ifndef CONFIG_FORCE_DPD_CALIB -+int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res) -+{ -+ int ret = 0; -+ int size; -+ u32 *dst=NULL; -+ char *filename = FW_DPDRESULT_NAME_8800DC; -+ struct device *dev = sdiodev->dev; -+ AICWFDBG(LOGINFO, "%s: dpd_res file path:%s \r\n", __func__, filename); -+ /* load file */ -+ size = rwnx_load_firmware(&dst, filename, dev); -+ if (size <= 0) { -+ AICWFDBG(LOGERROR, "wrong size of dpd_res file\n"); -+ if (dst) { -+ #ifndef CONFIG_FIRMWARE_ARRAY -+ vfree(dst); -+ #endif -+ dst = NULL; -+ } -+ return -1; -+ } -+ AICWFDBG(LOGINFO, "### Load file done: %s, size=%d, dst[0]=%x\n", filename, size, dst[0]); -+ memcpy((u8 *)dpd_res, (u8 *)dst, sizeof(rf_misc_ram_lite_t)); -+ if (dst) { -+ #ifndef CONFIG_FIRMWARE_ARRAY -+ vfree(dst); -+ #endif -+ dst = NULL; -+ } -+ return ret; -+} -+ -+int aicwf_dpd_result_write_8800dc(void *buf, int buf_len) -+{ -+ int sum = 0, len = 0; -+ char *path = NULL; -+ struct file *fp = NULL; -+ loff_t pos = 0; -+ mm_segment_t fs; -+ -+ AICWFDBG(LOGINFO, "%s\n", __func__); -+ -+ path = __getname(); -+ if (!path) { -+ AICWFDBG(LOGINFO, "get path fail\n"); -+ return -1; -+ } -+ -+ len = snprintf(path, FW_PATH_MAX_LEN, "%s/%s", AICBSP_FW_PATH, FW_DPDRESULT_NAME_8800DC); -+ printk("%s\n", path); -+ -+ fp = filp_open(path, O_RDWR | O_CREAT, 0644); -+ if (IS_ERR(fp)) { -+ AICWFDBG(LOGINFO, "fp open fial\n"); -+ __putname(path); -+ fp = NULL; -+ return -1; -+ } -+ -+ fs = get_fs(); -+ set_fs(KERNEL_DS); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ sum = kernel_write(fp, buf, buf_len, &pos); -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) -+ sum = kernel_write(fp, (char *)buf, buf_len, pos); -+#else -+ sum = vfs_write(fp, (char *)buf, buf_len, &pos); -+#endif -+ -+ set_fs(fs); -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ -+ return 0; -+} -+#endif /* !CONFIG_FORCE_DPD_CALIB */ -+#endif -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800dc_compat.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800dc_compat.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800dc_compat.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic8800dc_compat.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,37 @@ -+#ifndef _AIC8800DC_COMPAT_H_ -+#define _AIC8800DC_COMPAT_H_ -+ -+#include "aicsdio.h" -+typedef u32 (*array2_tbl_t)[2]; -+typedef u32 (*array3_tbl_t)[3]; -+ -+typedef uint8_t u8_l; -+typedef int8_t s8_l; -+typedef bool bool_l; -+typedef uint16_t u16_l; -+typedef int16_t s16_l; -+typedef uint32_t u32_l; -+typedef int32_t s32_l; -+typedef uint64_t u64_l; -+ -+extern u8 chip_sub_id; -+extern u8 chip_mcu_id; -+#define FW_PATH_MAX_LEN 200 -+ -+void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw); -+void system_config_8800dc(struct aic_sdio_dev *rwnx_hw); -+int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev); -+ -+#ifdef CONFIG_DPD -+int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res); -+int aicwf_dpd_result_apply_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res); -+#ifndef CONFIG_FORCE_DPD_CALIB -+int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res); -+int aicwf_dpd_result_write_8800dc(void *buf, int buf_len); -+#endif/* !CONFIG_FORCE_DPD_CALIB */ -+#endif -+ -+#endif -+ -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,2051 @@ -+/** -+ ****************************************************************************** -+ * -+ * rwnx_cmds.c -+ * -+ * Handles queueing (push to IPC, ack/cfm from IPC) of commands issued to -+ * LMAC FW -+ * -+ * Copyright (C) RivieraWaves 2014-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0) -+#include -+#endif -+#include -+#include "aicsdio_txrxif.h" -+#include "aicsdio.h" -+#include "aic_bsp_driver.h" -+#include "md5.h" -+#include "aic8800dc_compat.h" -+#include "aic8800d80_compat.h" -+#include "aicwf_firmware_array.h" -+#define FW_PATH_MAX 200 -+ -+extern int adap_test; -+extern char aic_fw_path[FW_PATH_MAX]; -+extern struct aic_sdio_dev *aicbsp_sdiodev; -+ -+static void cmd_dump(const struct rwnx_cmd *cmd) -+{ -+ printk(KERN_CRIT "tkn[%d] flags:%04x result:%3d cmd:%4d - reqcfm(%4d)\n", -+ cmd->tkn, cmd->flags, cmd->result, cmd->id, cmd->reqid); -+} -+ -+static void cmd_complete(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) -+{ -+ //printk("cmdcmp\n"); -+ lockdep_assert_held(&cmd_mgr->lock); -+ -+ list_del(&cmd->list); -+ cmd_mgr->queue_sz--; -+ -+ cmd->flags |= RWNX_CMD_FLAG_DONE; -+ if (cmd->flags & RWNX_CMD_FLAG_NONBLOCK) { -+ kfree(cmd); -+ } else { -+ if (RWNX_CMD_WAIT_COMPLETE(cmd->flags)) { -+ cmd->result = 0; -+ complete(&cmd->complete); -+ } -+ } -+} -+ -+static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) -+{ -+ bool defer_push = false; -+ int err = 0; -+ -+ spin_lock_bh(&cmd_mgr->lock); -+ -+ if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) { -+ printk(KERN_CRIT"cmd queue crashed\n"); -+ cmd->result = -EPIPE; -+ spin_unlock_bh(&cmd_mgr->lock); -+ return -EPIPE; -+ } -+ -+ if (!list_empty(&cmd_mgr->cmds)) { -+ struct rwnx_cmd *last; -+ -+ if (cmd_mgr->queue_sz == cmd_mgr->max_queue_sz) { -+ printk(KERN_CRIT"Too many cmds (%d) already queued\n", -+ cmd_mgr->max_queue_sz); -+ cmd->result = -ENOMEM; -+ spin_unlock_bh(&cmd_mgr->lock); -+ return -ENOMEM; -+ } -+ last = list_entry(cmd_mgr->cmds.prev, struct rwnx_cmd, list); -+ if (last->flags & (RWNX_CMD_FLAG_WAIT_ACK | RWNX_CMD_FLAG_WAIT_PUSH)) { -+ cmd->flags |= RWNX_CMD_FLAG_WAIT_PUSH; -+ defer_push = true; -+ } -+ } -+ -+ if (cmd->flags & RWNX_CMD_FLAG_REQ_CFM) -+ cmd->flags |= RWNX_CMD_FLAG_WAIT_CFM; -+ -+ cmd->tkn = cmd_mgr->next_tkn++; -+ cmd->result = -EINTR; -+ -+ if (!(cmd->flags & RWNX_CMD_FLAG_NONBLOCK)) -+ init_completion(&cmd->complete); -+ -+ list_add_tail(&cmd->list, &cmd_mgr->cmds); -+ cmd_mgr->queue_sz++; -+ spin_unlock_bh(&cmd_mgr->lock); -+ -+ if (!defer_push) { -+ //printk("queue:id=%x, param_len=%u\n", cmd->a2e_msg->id, cmd->a2e_msg->param_len); -+ rwnx_set_cmd_tx((void *)(cmd_mgr->sdiodev), cmd->a2e_msg, sizeof(struct lmac_msg) + cmd->a2e_msg->param_len); -+ //rwnx_ipc_msg_push(rwnx_hw, cmd, RWNX_CMD_A2EMSG_LEN(cmd->a2e_msg)); -+ kfree(cmd->a2e_msg); -+ } else { -+ //WAKE_CMD_WORK(cmd_mgr); -+ printk("ERR: never defer push!!!!"); -+ return 0; -+ } -+ -+ if (!(cmd->flags & RWNX_CMD_FLAG_NONBLOCK)) { -+ unsigned long tout = msecs_to_jiffies(RWNX_80211_CMD_TIMEOUT_MS * cmd_mgr->queue_sz); -+ if (!wait_for_completion_killable_timeout(&cmd->complete, tout)) { -+ printk(KERN_CRIT"cmd timed-out\n"); -+ cmd_dump(cmd); -+ spin_lock_bh(&cmd_mgr->lock); -+ cmd_mgr->state = RWNX_CMD_MGR_STATE_CRASHED; -+ if (!(cmd->flags & RWNX_CMD_FLAG_DONE)) { -+ cmd->result = -ETIMEDOUT; -+ cmd_complete(cmd_mgr, cmd); -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+ err = -ETIMEDOUT; -+ } else { -+ kfree(cmd); -+ } -+ } else { -+ cmd->result = 0; -+ } -+ -+ return err; -+} -+ -+static int cmd_mgr_run_callback(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd, -+ struct rwnx_cmd_e2amsg *msg, msg_cb_fct cb) -+{ -+ int res; -+ -+ if (!cb) { -+ return 0; -+ } -+ spin_lock(&cmd_mgr->cb_lock); -+ res = cb(cmd, msg); -+ spin_unlock(&cmd_mgr->cb_lock); -+ -+ return res; -+} -+ -+static int cmd_mgr_msgind(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd_e2amsg *msg, -+ msg_cb_fct cb) -+{ -+ struct rwnx_cmd *cmd; -+ bool found = false; -+ -+ //printk("cmd->id=%x\n", msg->id); -+ spin_lock(&cmd_mgr->lock); -+ list_for_each_entry(cmd, &cmd_mgr->cmds, list) { -+ if (cmd->reqid == msg->id && -+ (cmd->flags & RWNX_CMD_FLAG_WAIT_CFM)) { -+ -+ if (!cmd_mgr_run_callback(cmd_mgr, cmd, msg, cb)) { -+ found = true; -+ cmd->flags &= ~RWNX_CMD_FLAG_WAIT_CFM; -+ -+ if (WARN((msg->param_len > RWNX_CMD_E2AMSG_LEN_MAX), -+ "Unexpect E2A msg len %d > %d\n", msg->param_len, -+ RWNX_CMD_E2AMSG_LEN_MAX)) { -+ msg->param_len = RWNX_CMD_E2AMSG_LEN_MAX; -+ } -+ -+ if (cmd->e2a_msg && msg->param_len) -+ memcpy(cmd->e2a_msg, &msg->param, msg->param_len); -+ -+ if (RWNX_CMD_WAIT_COMPLETE(cmd->flags)) -+ cmd_complete(cmd_mgr, cmd); -+ -+ break; -+ } -+ } -+ } -+ spin_unlock(&cmd_mgr->lock); -+ -+ if (!found) -+ cmd_mgr_run_callback(cmd_mgr, NULL, msg, cb); -+ -+ return 0; -+} -+ -+static void cmd_mgr_print(struct rwnx_cmd_mgr *cmd_mgr) -+{ -+ struct rwnx_cmd *cur; -+ -+ spin_lock_bh(&cmd_mgr->lock); -+ list_for_each_entry(cur, &cmd_mgr->cmds, list) { -+ cmd_dump(cur); -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+} -+ -+static void cmd_mgr_drain(struct rwnx_cmd_mgr *cmd_mgr) -+{ -+ struct rwnx_cmd *cur, *nxt; -+ -+ spin_lock_bh(&cmd_mgr->lock); -+ list_for_each_entry_safe(cur, nxt, &cmd_mgr->cmds, list) { -+ list_del(&cur->list); -+ cmd_mgr->queue_sz--; -+ if (!(cur->flags & RWNX_CMD_FLAG_NONBLOCK)) -+ complete(&cur->complete); -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+} -+ -+void rwnx_cmd_mgr_init(struct rwnx_cmd_mgr *cmd_mgr) -+{ -+ cmd_mgr->max_queue_sz = RWNX_CMD_MAX_QUEUED; -+ INIT_LIST_HEAD(&cmd_mgr->cmds); -+ cmd_mgr->state = RWNX_CMD_MGR_STATE_INITED; -+ spin_lock_init(&cmd_mgr->lock); -+ spin_lock_init(&cmd_mgr->cb_lock); -+ cmd_mgr->queue = &cmd_mgr_queue; -+ cmd_mgr->print = &cmd_mgr_print; -+ cmd_mgr->drain = &cmd_mgr_drain; -+ cmd_mgr->llind = NULL;//&cmd_mgr_llind; -+ cmd_mgr->msgind = &cmd_mgr_msgind; -+ -+#if 0 -+ INIT_WORK(&cmd_mgr->cmdWork, cmd_mgr_task_process); -+ cmd_mgr->cmd_wq = create_singlethread_workqueue("cmd_wq"); -+ if (!cmd_mgr->cmd_wq) { -+ txrx_err("insufficient memory to create cmd workqueue.\n"); -+ return; -+ } -+#endif -+} -+ -+void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr) -+{ -+ cmd_mgr->print(cmd_mgr); -+ cmd_mgr->drain(cmd_mgr); -+ cmd_mgr->print(cmd_mgr); -+ memset(cmd_mgr, 0, sizeof(*cmd_mgr)); -+} -+ -+void rwnx_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len) -+{ -+ struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev; -+ struct aicwf_bus *bus = sdiodev->bus_if; -+ u8 *buffer = bus->cmd_buf; -+ u16 index = 0; -+ -+ memset(buffer, 0, CMD_BUF_MAX); -+ buffer[0] = (len+4) & 0x00ff; -+ buffer[1] = ((len+4) >> 8) &0x0f; -+ buffer[2] = 0x11; -+ if (sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DW) -+ buffer[3] = 0x0; -+ else if (sdiodev->chipid == PRODUCT_ID_AIC8800D80) -+ buffer[3] = crc8_ponl_107(&buffer[0], 3); // crc8 -+ index += 4; -+ //there is a dummy word -+ index += 4; -+ -+ //make sure little endian -+ put_u16(&buffer[index], msg->id); -+ index += 2; -+ put_u16(&buffer[index], msg->dest_id); -+ index += 2; -+ put_u16(&buffer[index], msg->src_id); -+ index += 2; -+ put_u16(&buffer[index], msg->param_len); -+ index += 2; -+ memcpy(&buffer[index], (u8 *)msg->param, msg->param_len); -+ -+ aicwf_bus_txmsg(bus, buffer, len + 8); -+} -+ -+static inline void *rwnx_msg_zalloc(lmac_msg_id_t const id, -+ lmac_task_id_t const dest_id, -+ lmac_task_id_t const src_id, -+ uint16_t const param_len) -+{ -+ struct lmac_msg *msg; -+ gfp_t flags; -+ -+ if (in_softirq()) -+ flags = GFP_ATOMIC; -+ else -+ flags = GFP_KERNEL; -+ -+ msg = (struct lmac_msg *)kzalloc(sizeof(struct lmac_msg) + param_len, -+ flags); -+ if (msg == NULL) { -+ printk(KERN_CRIT "%s: msg allocation failed\n", __func__); -+ return NULL; -+ } -+ msg->id = id; -+ msg->dest_id = dest_id; -+ msg->src_id = src_id; -+ msg->param_len = param_len; -+ -+ return msg->param; -+} -+ -+static void rwnx_msg_free(struct lmac_msg *msg, const void *msg_params) -+{ -+ kfree(msg); -+} -+ -+ -+static int rwnx_send_msg(struct aic_sdio_dev *sdiodev, const void *msg_params, -+ int reqcfm, lmac_msg_id_t reqid, void *cfm) -+{ -+ struct lmac_msg *msg; -+ struct rwnx_cmd *cmd; -+ bool nonblock; -+ int ret = 0; -+ -+ msg = container_of((void *)msg_params, struct lmac_msg, param); -+ if (sdiodev->bus_if->state == BUS_DOWN_ST) { -+ rwnx_msg_free(msg, msg_params); -+ printk("bus is down\n"); -+ return 0; -+ } -+ -+ nonblock = 0; -+ cmd = kzalloc(sizeof(struct rwnx_cmd), nonblock ? GFP_ATOMIC : GFP_KERNEL); -+ cmd->result = -EINTR; -+ cmd->id = msg->id; -+ cmd->reqid = reqid; -+ cmd->a2e_msg = msg; -+ cmd->e2a_msg = cfm; -+ if (nonblock) -+ cmd->flags = RWNX_CMD_FLAG_NONBLOCK; -+ if (reqcfm) -+ cmd->flags |= RWNX_CMD_FLAG_REQ_CFM; -+ -+ if (reqcfm) { -+ cmd->flags &= ~RWNX_CMD_FLAG_WAIT_ACK; // we don't need ack any more -+ ret = sdiodev->cmd_mgr.queue(&sdiodev->cmd_mgr, cmd); -+ } else { -+ rwnx_set_cmd_tx((void *)(sdiodev), cmd->a2e_msg, sizeof(struct lmac_msg) + cmd->a2e_msg->param_len); -+ } -+ -+ if (!reqcfm) -+ kfree(cmd); -+ -+ return ret; -+} -+ -+ -+int rwnx_send_dbg_mem_block_write_req(struct aic_sdio_dev *sdiodev, u32 mem_addr, -+ u32 mem_size, u32 *mem_data) -+{ -+ struct dbg_mem_block_write_req *mem_blk_write_req; -+ -+ /* Build the DBG_MEM_BLOCK_WRITE_REQ message */ -+ mem_blk_write_req = rwnx_msg_zalloc(DBG_MEM_BLOCK_WRITE_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_mem_block_write_req)); -+ if (!mem_blk_write_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_MEM_BLOCK_WRITE_REQ message */ -+ mem_blk_write_req->memaddr = mem_addr; -+ mem_blk_write_req->memsize = mem_size; -+ memcpy(mem_blk_write_req->memdata, mem_data, mem_size); -+ -+ /* Send the DBG_MEM_BLOCK_WRITE_REQ message to LMAC FW */ -+ return rwnx_send_msg(sdiodev, mem_blk_write_req, 1, DBG_MEM_BLOCK_WRITE_CFM, NULL); -+} -+ -+int rwnx_send_dbg_mem_read_req(struct aic_sdio_dev *sdiodev, u32 mem_addr, -+ struct dbg_mem_read_cfm *cfm) -+{ -+ struct dbg_mem_read_req *mem_read_req; -+ -+ /* Build the DBG_MEM_READ_REQ message */ -+ mem_read_req = rwnx_msg_zalloc(DBG_MEM_READ_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_mem_read_req)); -+ if (!mem_read_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_MEM_READ_REQ message */ -+ mem_read_req->memaddr = mem_addr; -+ -+ /* Send the DBG_MEM_READ_REQ message to LMAC FW */ -+ return rwnx_send_msg(sdiodev, mem_read_req, 1, DBG_MEM_READ_CFM, cfm); -+} -+ -+ -+int rwnx_send_dbg_mem_write_req(struct aic_sdio_dev *sdiodev, u32 mem_addr, u32 mem_data) -+{ -+ struct dbg_mem_write_req *mem_write_req; -+ -+ /* Build the DBG_MEM_WRITE_REQ message */ -+ mem_write_req = rwnx_msg_zalloc(DBG_MEM_WRITE_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_mem_write_req)); -+ if (!mem_write_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_MEM_WRITE_REQ message */ -+ mem_write_req->memaddr = mem_addr; -+ mem_write_req->memdata = mem_data; -+ -+ /* Send the DBG_MEM_WRITE_REQ message to LMAC FW */ -+ return rwnx_send_msg(sdiodev, mem_write_req, 1, DBG_MEM_WRITE_CFM, NULL); -+} -+ -+int rwnx_send_dbg_mem_mask_write_req(struct aic_sdio_dev *sdiodev, u32 mem_addr, -+ u32 mem_mask, u32 mem_data) -+{ -+ struct dbg_mem_mask_write_req *mem_mask_write_req; -+ -+ /* Build the DBG_MEM_MASK_WRITE_REQ message */ -+ mem_mask_write_req = rwnx_msg_zalloc(DBG_MEM_MASK_WRITE_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_mem_mask_write_req)); -+ if (!mem_mask_write_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_MEM_MASK_WRITE_REQ message */ -+ mem_mask_write_req->memaddr = mem_addr; -+ mem_mask_write_req->memmask = mem_mask; -+ mem_mask_write_req->memdata = mem_data; -+ -+ /* Send the DBG_MEM_MASK_WRITE_REQ message to LMAC FW */ -+ return rwnx_send_msg(sdiodev, mem_mask_write_req, 1, DBG_MEM_MASK_WRITE_CFM, NULL); -+} -+ -+ -+int rwnx_send_dbg_start_app_req(struct aic_sdio_dev *sdiodev, u32 boot_addr, u32 boot_type, struct dbg_start_app_cfm *start_app_cfm) -+{ -+ struct dbg_start_app_req *start_app_req; -+ -+ /* Build the DBG_START_APP_REQ message */ -+ start_app_req = rwnx_msg_zalloc(DBG_START_APP_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_start_app_req)); -+ if (!start_app_req) { -+ printk("start app nomen\n"); -+ return -ENOMEM; -+ } -+ -+ /* Set parameters for the DBG_START_APP_REQ message */ -+ start_app_req->bootaddr = boot_addr; -+ start_app_req->boottype = boot_type; -+ -+ /* Send the DBG_START_APP_REQ message to LMAC FW */ -+ return rwnx_send_msg(sdiodev, start_app_req, 1, DBG_START_APP_CFM, start_app_cfm); -+} -+ -+static msg_cb_fct dbg_hdlrs[MSG_I(DBG_MAX)] = { -+}; -+ -+static msg_cb_fct *msg_hdlrs[] = { -+ [TASK_DBG] = dbg_hdlrs, -+}; -+ -+void rwnx_rx_handle_msg(struct aic_sdio_dev *sdiodev, struct ipc_e2a_msg *msg) -+{ -+ sdiodev->cmd_mgr.msgind(&sdiodev->cmd_mgr, msg, -+ msg_hdlrs[MSG_T(msg->id)][MSG_I(msg->id)]); -+} -+ -+#if MODULE_IMPORT_NS -+MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); -+#endif -+ -+#define MD5(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15] -+#define MD5PINRT "file md5:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\r\n" -+ -+int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *device) -+{ -+ -+#ifdef CONFIG_USE_FW_REQUEST -+ const struct firmware *fw = NULL; -+ u32 *dst = NULL; -+ void *buffer=NULL; -+ MD5_CTX md5; -+ unsigned char decrypt[16]; -+ int size = 0; -+ int ret = 0; -+ -+ printk("%s: request firmware = %s \n", __func__ ,name); -+ -+ -+ ret = request_firmware(&fw, name, NULL); -+ -+ if (ret < 0) { -+ printk("Load %s fail\n", name); -+ release_firmware(fw); -+ return -1; -+ } -+ -+ size = fw->size; -+ dst = (u32 *)fw->data; -+ -+ if (size <= 0) { -+ printk("wrong size of firmware file\n"); -+ release_firmware(fw); -+ return -1; -+ } -+ -+ -+ buffer = vmalloc(size); -+ memset(buffer, 0, size); -+ memcpy(buffer, dst, size); -+ -+ *fw_buf = buffer; -+ -+ MD5Init(&md5); -+ MD5Update(&md5, (unsigned char *)buffer, size); -+ MD5Final(&md5, decrypt); -+ printk(MD5PINRT, MD5(decrypt)); -+ -+ release_firmware(fw); -+ -+ return size; -+#else -+ void *buffer = NULL; -+ char *path = NULL; -+ struct file *fp = NULL; -+ int size = 0, len = 0;// i = 0; -+ ssize_t rdlen = 0; -+ //u32 *src = NULL, *dst = NULL; -+ MD5_CTX md5; -+ unsigned char decrypt[16]; -+ -+ #ifdef CONFIG_FIRMWARE_ARRAY -+ size = aicwf_get_firmware_array((char*)name, fw_buf); -+ printk("%s size:%d \r\n", __func__, size); -+ MD5Init(&md5); -+ MD5Update(&md5, (unsigned char *)*fw_buf, size); -+ MD5Final(&md5, decrypt); -+ printk(MD5PINRT, MD5(decrypt)); -+ -+ return size; -+ #endif -+ -+ /* get the firmware path */ -+ path = __getname(); -+ if (!path) { -+ *fw_buf = NULL; -+ return -1; -+ } -+ -+ if(strlen(aic_fw_path) > 0){ -+ len = snprintf(path, AICBSP_FW_PATH_MAX, "%s/%s", aic_fw_path, name); -+ }else{ -+ len = snprintf(path, AICBSP_FW_PATH_MAX, "%s/%s", AICBSP_FW_PATH, name); -+ } -+ if (len >= AICBSP_FW_PATH_MAX) { -+ printk("%s: %s file's path too long\n", __func__, name); -+ *fw_buf = NULL; -+ __putname(path); -+ return -1; -+ } -+ -+ printk("%s :firmware path = %s \n", __func__, path); -+ -+ /* open the firmware file */ -+ fp = filp_open(path, O_RDONLY, 0); -+ if (IS_ERR_OR_NULL(fp)) { -+ printk("%s: %s file failed to open\n", __func__, name); -+ *fw_buf = NULL; -+ __putname(path); -+ fp = NULL; -+ return -1; -+ } -+ -+ size = i_size_read(file_inode(fp)); -+ if (size <= 0) { -+ printk("%s: %s file size invalid %d\n", __func__, name, size); -+ *fw_buf = NULL; -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ return -1; -+ } -+ -+ /* start to read from firmware file */ -+ buffer = vmalloc(size); -+ -+ if (!buffer) { -+ *fw_buf = NULL; -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ return -1; -+ }else{ -+ memset(buffer, 0, size); -+ } -+ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 13, 16) -+ rdlen = kernel_read(fp, buffer, size, &fp->f_pos); -+#else -+ rdlen = kernel_read(fp, fp->f_pos, buffer, size); -+#endif -+ -+ if (size != rdlen) { -+ printk("%s: %s file rdlen invalid %ld\n", __func__, name, (long int)rdlen); -+ *fw_buf = NULL; -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ vfree(buffer); -+ buffer = NULL; -+ return -1; -+ } -+ if (rdlen > 0) { -+ fp->f_pos += rdlen; -+ } -+ -+#if 0 -+ /*start to transform the data format*/ -+ src = (u32 *)buffer; -+ dst = (u32 *)vmalloc(size); -+ -+ if (!dst) { -+ *fw_buf = NULL; -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ vfree(buffer); -+ buffer = NULL; -+ return -1; -+ }else{ -+ memset(dst, 0, size); -+ } -+ -+ for (i = 0; i < (size/4); i++) { -+ dst[i] = src[i]; -+ } -+#endif -+ -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ //vfree(buffer); -+ //buffer = NULL; -+ *fw_buf = (u32*)buffer; -+ -+ MD5Init(&md5); -+ MD5Update(&md5, (unsigned char *)buffer, size); -+ MD5Final(&md5, decrypt); -+ -+ printk(MD5PINRT, MD5(decrypt)); -+ -+ return size; -+#endif -+} -+ -+extern int testmode; -+ -+#ifdef CONFIG_M2D_OTA_AUTO_SUPPORT -+extern char saved_sdk_ver[64]; -+ -+int rwnx_plat_m2d_flash_ota_android(struct aic_sdio_dev *sdiodev, char *filename) -+{ -+ struct device *dev = sdiodev->dev; -+ unsigned int i=0; -+ int size; -+ u32 *dst=NULL; -+ int err=0; -+ int ret; -+ u8 bond_id; -+ const u32 mem_addr = 0x40500000; -+ struct dbg_mem_read_cfm rd_mem_addr_cfm; -+ -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm); -+ if (ret) { -+ printk("m2d %x rd fail: %d\n", mem_addr, ret); -+ return ret; -+ } -+ bond_id = (u8)(rd_mem_addr_cfm.memdata >> 24); -+ printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata); -+ if (bond_id & (1<<1)) { -+ //flash is invalid -+ printk("m2d flash is invalid\n"); -+ return -1; -+ } -+ -+ /* load aic firmware */ -+ size = rwnx_load_firmware(&dst, filename, dev); -+ if(size<=0){ -+ printk("wrong size of m2d file\n"); -+ vfree(dst); -+ dst = NULL; -+ return -1; -+ } -+ -+ /* Copy the file on the Embedded side */ -+ printk("### Upload m2d %s flash, size=%d\n", filename, size); -+ -+ /*send info first*/ -+ err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_INFO_ADDR, 4, (u32 *)&size); -+ -+ /*send data first*/ -+ if (size > 1024) {// > 1KB data -+ for (i = 0; i < (size - 1024); i += 1024) {//each time write 1KB -+ err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, 1024, dst + i / 4); -+ if (err) { -+ printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err); -+ break; -+ } -+ } -+ } -+ -+ if (!err && (i < size)) {// <1KB data -+ err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, size - i, dst + i / 4); -+ if (err) { -+ printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err); -+ } -+ } -+ -+ if (dst) { -+ vfree(dst); -+ dst = NULL; -+ } -+ testmode = FW_NORMAL_MODE; -+ aicbsp_info.cpmode = testmode; -+ -+ printk("m2d flash update complete\n\n"); -+ -+ return err; -+} -+ -+int rwnx_plat_m2d_flash_ota_check(struct aic_sdio_dev *sdiodev, char *filename) -+{ -+ struct device *dev = sdiodev->dev; -+ unsigned int i=0,j=0; -+ int size; -+ u32 *dst=NULL; -+ int err=0; -+ int ret=0; -+ u8 bond_id; -+ const u32 mem_addr = 0x40500000; -+ const u32 mem_addr_code_start = AIC_M2D_OTA_CODE_START_ADDR; -+ const u32 mem_addr_sdk_ver = AIC_M2D_OTA_VER_ADDR; -+ const u32 driver_code_start_idx = (AIC_M2D_OTA_CODE_START_ADDR-AIC_M2D_OTA_FLASH_ADDR)/4; -+ const u32 driver_sdk_ver_idx = (AIC_M2D_OTA_VER_ADDR-AIC_M2D_OTA_FLASH_ADDR)/4; -+ u32 driver_sdk_ver_addr_idx = 0; -+ u32 code_start_addr = 0xffffffff; -+ u32 sdk_ver_addr = 0xffffffff; -+ u32 drv_code_start_addr = 0xffffffff; -+ u32 drv_sdk_ver_addr = 0xffffffff; -+ struct dbg_mem_read_cfm rd_mem_addr_cfm; -+ char m2d_sdk_ver[64]; -+ char flash_sdk_ver[64]; -+ u32 flash_ver[16]; -+ u32 ota_ver[16]; -+ -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm); -+ if (ret) { -+ printk("m2d %x rd fail: %d\n", mem_addr, ret); -+ return ret; -+ } -+ bond_id = (u8)(rd_mem_addr_cfm.memdata >> 24); -+ printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata); -+ if (bond_id & (1<<1)) { -+ //flash is invalid -+ printk("m2d flash is invalid\n"); -+ return -1; -+ } -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr_code_start, &rd_mem_addr_cfm); -+ if (ret){ -+ printk("mem_addr_code_start %x rd fail: %d\n", mem_addr_code_start, ret); -+ return ret; -+ } -+ code_start_addr = rd_mem_addr_cfm.memdata; -+ -+ #if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT) -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr_sdk_ver, &rd_mem_addr_cfm); -+ if (ret){ -+ printk("mem_addr_sdk_ver %x rd fail: %d\n", mem_addr_code_start, ret); -+ return ret; -+ } -+ sdk_ver_addr = rd_mem_addr_cfm.memdata; -+ #else -+ sdk_ver_addr = mem_addr_sdk_ver; -+ #endif -+ printk("code_start_addr: 0x%x, sdk_ver_addr: 0x%x\n", code_start_addr,sdk_ver_addr); -+ -+ /* load aic firmware */ -+ size = rwnx_load_firmware(&dst, filename, dev); -+ if(size<=0){ -+ printk("wrong size of m2d file\n"); -+ vfree(dst); -+ dst = NULL; -+ return -1; -+ } -+ if(code_start_addr == 0xffffffff && sdk_ver_addr == 0xffffffff) { -+ printk("########m2d flash old version , must be upgrade\n"); -+ drv_code_start_addr = dst[driver_code_start_idx]; -+ drv_sdk_ver_addr = dst[driver_sdk_ver_idx]; -+ -+ printk("drv_code_start_addr: 0x%x, drv_sdk_ver_addr: 0x%x\n", drv_code_start_addr,drv_sdk_ver_addr); -+ -+ if(drv_sdk_ver_addr == 0xffffffff){ -+ printk("########driver m2d_ota.bin is old ,not need upgrade\n"); -+ return -1; -+ } -+ -+ } else { -+ for(i=0;i<16;i++){ -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, (sdk_ver_addr+i*4), &rd_mem_addr_cfm); -+ if (ret){ -+ printk("mem_addr_sdk_ver %x rd fail: %d\n", mem_addr_code_start, ret); -+ return ret; -+ } -+ flash_ver[i] = rd_mem_addr_cfm.memdata; -+ } -+ memcpy((u8 *)flash_sdk_ver,(u8 *)flash_ver,64); -+ memcpy((u8 *)saved_sdk_ver,(u8 *)flash_sdk_ver,64); -+ printk("flash SDK Version: %s\r\n\r\n", flash_sdk_ver); -+ -+ drv_code_start_addr = dst[driver_code_start_idx]; -+ drv_sdk_ver_addr = dst[driver_sdk_ver_idx]; -+ -+ printk("drv_code_start_addr: 0x%x, drv_sdk_ver_addr: 0x%x\n", drv_code_start_addr,drv_sdk_ver_addr); -+ -+ if(drv_sdk_ver_addr == 0xffffffff){ -+ printk("########driver m2d_ota.bin is old ,not need upgrade\n"); -+ return -1; -+ } -+ -+ #if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT) -+ driver_sdk_ver_addr_idx = (drv_sdk_ver_addr-drv_code_start_addr)/4; -+ #else -+ driver_sdk_ver_addr_idx = driver_sdk_ver_idx; -+ #endif -+ printk("driver_sdk_ver_addr_idx %d\n",driver_sdk_ver_addr_idx); -+ -+ if (driver_sdk_ver_addr_idx){ -+ for(j = 0; j < 16; j++){ -+ ota_ver[j] = dst[driver_sdk_ver_addr_idx+j]; -+ } -+ memcpy((u8 *)m2d_sdk_ver,(u8 *)ota_ver,64); -+ printk("m2d_ota SDK Version: %s\r\n\r\n", m2d_sdk_ver); -+ } else { -+ return -1; -+ } -+ -+ if(!strcmp(m2d_sdk_ver,flash_sdk_ver)){ -+ printk("######## m2d %s flash is not need upgrade\r\n", filename); -+ return -1; -+ } -+ } -+ -+ /* Copy the file on the Embedded side */ -+ printk("### Upload m2d %s flash, size=%d\n", filename, size); -+ -+ /*send info first*/ -+ err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_INFO_ADDR, 4, (u32 *)&size); -+ -+ /*send data first*/ -+ if (size > 1024) {// > 1KB data -+ for (i = 0; i < (size - 1024); i += 1024) {//each time write 1KB -+ err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, 1024, dst + i / 4); -+ if (err) { -+ printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err); -+ break; -+ } -+ } -+ } -+ -+ if (!err && (i < size)) {// <1KB data -+ err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, size - i, dst + i / 4); -+ if (err) { -+ printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err); -+ } -+ } -+ -+ if (dst) { -+ vfree(dst); -+ dst = NULL; -+ } -+ testmode = FW_NORMAL_MODE; -+ -+ printk("m2d flash update complete\n\n"); -+ -+ return err; -+} -+#endif//CONFIG_M2D_OTA_AUTO_SUPPORT -+ -+int aicwf_patch_table_load(struct aic_sdio_dev *rwnx_hw, char *filename) -+{ -+ struct device *dev = rwnx_hw->dev; -+ int err = 0; -+ unsigned int i = 0, size; -+ u32 *dst = NULL; -+ u8 *describle; -+ u32 fmacfw_patch_tbl_8800dc_u02_describe_size = 124; -+ u32 fmacfw_patch_tbl_8800dc_u02_describe_base;//read from patch_tbl -+ -+ /* Copy the file on the Embedded side */ -+ printk("### Upload %s \n", filename); -+ -+ size = rwnx_load_firmware(&dst, filename,dev); -+ if (!dst) { -+ printk("No such file or directory\n"); -+ return -1; -+ } -+ if (size <= 0) { -+ printk("wrong size of firmware file\n"); -+ dst = NULL; -+ err = -1; -+ } -+ -+ printk("tbl size = %d \n",size); -+ -+ fmacfw_patch_tbl_8800dc_u02_describe_base = dst[0]; -+ AICWFDBG(LOGINFO, "FMACFW_PATCH_TBL_8800DC_U02_DESCRIBE_BASE = %x \n",fmacfw_patch_tbl_8800dc_u02_describe_base); -+ -+ if (!err && (i < size)) { -+ err=rwnx_send_dbg_mem_block_write_req(rwnx_hw, fmacfw_patch_tbl_8800dc_u02_describe_base, fmacfw_patch_tbl_8800dc_u02_describe_size + 4, dst); -+ if(err){ -+ printk("write describe information fail \n"); -+ } -+ -+ describle=kzalloc(fmacfw_patch_tbl_8800dc_u02_describe_size,GFP_KERNEL); -+ memcpy(describle,&dst[1],fmacfw_patch_tbl_8800dc_u02_describe_size); -+ printk("%s",describle); -+ kfree(describle); -+ describle=NULL; -+ } -+ -+ if (!err && (i < size)) { -+ for (i =(128/4); i < (size/4); i +=2) { -+ printk("patch_tbl: %x %x\n", dst[i], dst[i+1]); -+ err = rwnx_send_dbg_mem_write_req(rwnx_hw, dst[i], dst[i+1]); -+ } -+ if (err) { -+ printk("bin upload fail: %x, err:%d\r\n", dst[i], err); -+ } -+ } -+ -+ if (dst) { -+#ifndef CONFIG_FIRMWARE_ARRAY -+ vfree(dst); -+#endif -+ dst = NULL; -+ } -+ -+ -+ return err; -+ -+} -+ -+extern char aic_fw_path[200]; -+int aicwf_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ #if !defined(CONFIG_FPGA_VERIFICATION) -+ if (chip_sub_id == 0) { -+ printk("u01 is loaing ###############\n"); -+ ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_8800DC); -+ } else if (chip_sub_id == 1) { -+ printk("u02 is loaing ###############\n"); -+ ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_8800DC_U02); -+ } else if (chip_sub_id == 2) { -+ printk("h_u02 is loaing ###############\n"); -+ ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_8800DC_H_U02); -+ } else { -+ printk("unsupported id: %d\n", chip_sub_id); -+ } -+ #endif -+ return ret; -+} -+ -+int aicwf_plat_rftest_load_8800dc(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ ret = rwnx_plat_bin_fw_upload_android(sdiodev, RAM_LMAC_FW_ADDR, RWNX_MAC_FW_RF_BASE_NAME_8800DC); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret); -+ return ret; -+ } -+ return ret; -+} -+ -+#ifdef CONFIG_DPD -+int aicwf_misc_ram_valid_check_8800dc(struct aic_sdio_dev *sdiodev, int *valid_out) -+{ -+ int ret = 0; -+ uint32_t cfg_base = 0x10164; -+ struct dbg_mem_read_cfm cfm; -+ uint32_t misc_ram_addr; -+ uint32_t ram_base_addr, ram_word_cnt; -+ uint32_t bit_mask[4]; -+ int i; -+ if (valid_out) { -+ *valid_out = 0; -+ } -+ if (testmode == FW_RFTEST_MODE) { -+ -+ uint32_t vect1 = 0; -+ uint32_t vect2 = 0; -+ cfg_base = RAM_LMAC_FW_ADDR + 0x0004; -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base, &cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "cfg_base:%x vcet1 rd fail: %d\n", cfg_base, ret); -+ return ret; -+ } -+ vect1 = cfm.memdata; -+ if ((vect1 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) { -+ AICWFDBG(LOGERROR, "vect1 invalid: %x\n", vect1); -+ return ret; -+ } -+ cfg_base = RAM_LMAC_FW_ADDR + 0x0008; -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base, &cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "cfg_base:%x vcet2 rd fail: %d\n", cfg_base, ret); -+ return ret; -+ } -+ vect2 = cfm.memdata; -+ if ((vect2 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) { -+ AICWFDBG(LOGERROR, "vect2 invalid: %x\n", vect2); -+ return ret; -+ } -+ -+ cfg_base = RAM_LMAC_FW_ADDR + 0x0164; -+ } -+ // init misc ram -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x14, &cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); -+ return ret; -+ } -+ misc_ram_addr = cfm.memdata; -+ AICWFDBG(LOGERROR, "misc_ram_addr=%x\n", misc_ram_addr); -+ // bit_mask -+ ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask); -+ ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4; -+ for (i = 0; i < ram_word_cnt; i++) { -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, ram_base_addr + i * 4, &cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); -+ return ret; -+ } -+ bit_mask[i] = cfm.memdata; -+ } -+ AICWFDBG(LOGTRACE, "bit_mask:%x,%x,%x,%x\n",bit_mask[0],bit_mask[1],bit_mask[2],bit_mask[3]); -+ if ((bit_mask[0] == 0) && ((bit_mask[1] & 0xFFF00000) == 0x80000000) && -+ (bit_mask[2] == 0) && ((bit_mask[3] & 0xFFFFFF00) == 0x00000000)) { -+ if (valid_out) { -+ *valid_out = 1; -+ } -+ } -+ return ret; -+} -+ -+int aicwf_plat_calib_load_8800dc(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ if (chip_sub_id == 1) { -+ ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_CALIB_ADDR, RWNX_MAC_CALIB_NAME_8800DC_U02); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret); -+ return ret; -+ } -+ } else if (chip_sub_id == 2) { -+ ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_CALIB_ADDR, RWNX_MAC_CALIB_NAME_8800DC_H_U02); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret); -+ return ret; -+ } -+ } -+ return ret; -+} -+ -+#ifndef CONFIG_FORCE_DPD_CALIB -+int is_file_exist(char* name) -+{ -+ char *path = NULL; -+ struct file *fp = NULL; -+ int len; -+ -+ path = __getname(); -+ if (!path) { -+ AICWFDBG(LOGINFO, "%s getname fail\n", __func__); -+ return -1; -+ } -+ -+ len = snprintf(path, FW_PATH_MAX_LEN, "%s/%s", AICBSP_FW_PATH, name); -+ -+ fp = filp_open(path, O_RDONLY, 0); -+ if (IS_ERR(fp)) { -+ __putname(path); -+ fp = NULL; -+ return 0; -+ } else { -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ return 1; -+ } -+} -+ -+EXPORT_SYMBOL(is_file_exist); -+#endif -+#endif -+ -+#ifdef CONFIG_DPD -+rf_misc_ram_lite_t dpd_res = {{0},}; -+EXPORT_SYMBOL(dpd_res); -+#endif -+ -+static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (sdiodev->chipid == PRODUCT_ID_AIC8800DC || sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ AICWFDBG(LOGINFO, "testmode=%d\n", testmode); -+ if (chip_sub_id == 0) { -+ if (testmode == FW_NORMAL_MODE) { -+ AICWFDBG(LOGINFO, "rwnx_plat_patch_loading\n"); -+ ret = aicwf_plat_patch_load_8800dc(sdiodev); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load patch bin fail: %d\n", ret); -+ return ret; -+ } -+ } else if (testmode == FW_RFTEST_MODE) { -+ ret = aicwf_plat_rftest_load_8800dc(sdiodev); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret); -+ return ret; -+ } -+ } -+ } else if (chip_sub_id >= 1) { -+ if (testmode == FW_NORMAL_MODE) { -+ AICWFDBG(LOGINFO, "rwnx_plat_patch_loading\n"); -+ ret = aicwf_plat_patch_load_8800dc(sdiodev); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load patch bin fail: %d\n", ret); -+ return ret; -+ } -+ #ifdef CONFIG_DPD -+ #ifdef CONFIG_FORCE_DPD_CALIB -+ if (1) { -+ AICWFDBG(LOGINFO, "dpd calib & write\n"); -+ ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res); -+ if (ret) { -+ AICWFDBG(LOGINFO, "dpd calib fail: %d\n", ret); -+ return ret; -+ } -+ } -+ #else -+ if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) { -+ AICWFDBG(LOGINFO, "dpd bin load\n"); -+ ret = aicwf_dpd_result_load_8800dc(sdiodev, &dpd_res); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load dpd bin fail: %d\n", ret); -+ return ret; -+ } -+ ret = aicwf_dpd_result_apply_8800dc(sdiodev, &dpd_res); -+ if (ret) { -+ AICWFDBG(LOGINFO, "apply dpd bin fail: %d\n", ret); -+ return ret; -+ } -+ } -+ #endif -+ else -+ #endif -+ { -+ ret = aicwf_misc_ram_init_8800dc(sdiodev); -+ if (ret) { -+ AICWFDBG(LOGINFO, "misc ram init fail: %d\n", ret); -+ return ret; -+ } -+ } -+ } else if (testmode == FW_RFTEST_MODE) { -+ #ifdef CONFIG_DPD -+ #ifdef CONFIG_FORCE_DPD_CALIB -+ if (1) { -+ AICWFDBG(LOGINFO, "patch load\n"); -+ ret = aicwf_plat_patch_load_8800dc(sdiodev); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load patch bin fail: %d\n", ret); -+ return ret; -+ } -+ AICWFDBG(LOGINFO, "dpd calib & write\n"); -+ ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res); -+ if (ret) { -+ AICWFDBG(LOGINFO, "dpd calib fail: %d\n", ret); -+ return ret; -+ } -+ } -+ #endif -+ #endif -+ ret = aicwf_plat_rftest_load_8800dc(sdiodev); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret); -+ return ret; -+ } -+ } else if (testmode == FW_DPDCALIB_MODE) { -+ #if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB)) -+ if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 0) { -+ AICWFDBG(LOGINFO, "patch load\n"); -+ ret = aicwf_plat_patch_load_8800dc(sdiodev); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load patch bin fail: %d\n", ret); -+ return ret; -+ } -+ AICWFDBG(LOGINFO, "dpd calib & write\n"); -+ ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res); -+ if (ret) { -+ AICWFDBG(LOGINFO, "dpd calib fail: %d\n", ret); -+ return ret; -+ } -+ ret = aicwf_dpd_result_write_8800dc((void *)&dpd_res, DPD_RESULT_SIZE_8800DC); -+ if (ret) { -+ AICWFDBG(LOGINFO, "file write fail: %d\n", ret); -+ return ret; -+ } -+ } -+ #endif -+ return 1; // exit calib mode -+ } -+ } -+ } -+ -+ return ret; -+} -+ -+int rwnx_plat_bin_fw_upload_android(struct aic_sdio_dev *sdiodev, u32 fw_addr, -+ const char *filename) -+{ -+ struct device *dev = sdiodev->dev; -+ unsigned int i = 0; -+ int size; -+ u32 *dst = NULL; -+ int err = 0; -+ -+ printk("%s\n",__func__); -+ -+ /* load aic firmware */ -+ size = rwnx_load_firmware(&dst, filename, dev); -+ if (size <= 0) { -+ printk("wrong size of firmware file\n"); -+#ifndef CONFIG_FIRMWARE_ARRAY -+ vfree(dst); -+#endif -+ dst = NULL; -+ return -1; -+ } -+ -+ /* Copy the file on the Embedded side */ -+ if (size > 1024) {// > 1KB data -+ for (i = 0; i < (size - 1024); i += 1024) {//each time write 1KB -+ err = rwnx_send_dbg_mem_block_write_req(sdiodev, fw_addr + i, 1024, dst + i / 4); -+ if (err) { -+ printk("bin upload fail: %x, err:%d\r\n", fw_addr + i, err); -+ break; -+ } -+ } -+ } -+ -+ if (!err && (i < size)) {// <1KB data -+ err = rwnx_send_dbg_mem_block_write_req(sdiodev, fw_addr + i, size - i, dst + i / 4); -+ if (err) { -+ printk("bin upload fail: %x, err:%d\r\n", fw_addr + i, err); -+ } -+ } -+ -+ if (dst) { -+#ifndef CONFIG_FIRMWARE_ARRAY -+ vfree(dst); -+#endif -+ dst = NULL; -+ } -+ -+ return err; -+} -+ -+int aicbt_patch_table_free(struct aicbt_patch_table **head) -+{ -+ struct aicbt_patch_table *p = *head, *n = NULL; -+ while (p) { -+ n = p->next; -+ vfree(p->name); -+ vfree(p->data); -+ vfree(p); -+ p = n; -+ } -+ *head = NULL; -+ return 0; -+} -+ -+struct aicbt_patch_table *aicbt_patch_table_alloc(const char *filename) -+{ -+ uint8_t *rawdata = NULL, *p; -+ int size; -+ struct aicbt_patch_table *head = NULL, *new = NULL, *cur = NULL; -+ -+ /* load aic firmware */ -+ size = rwnx_load_firmware((u32 **)&rawdata, filename, NULL); -+ if (size <= 0) { -+ printk("wrong size of firmware file\n"); -+ goto err; -+ } -+ -+ p = rawdata; -+ if (memcmp(p, AICBT_PT_TAG, sizeof(AICBT_PT_TAG) < 16 ? sizeof(AICBT_PT_TAG) : 16)) { -+ printk("TAG err\n"); -+ goto err; -+ } -+ p += 16; -+ -+ while (p - rawdata < size) { -+ new = (struct aicbt_patch_table *)vmalloc(sizeof(struct aicbt_patch_table)); -+ memset(new, 0, sizeof(struct aicbt_patch_table)); -+ if (head == NULL) { -+ head = new; -+ cur = new; -+ } else { -+ cur->next = new; -+ cur = cur->next; -+ } -+ -+ cur->name = (char *)vmalloc(sizeof(char) * 16); -+ memset(cur->name, 0, sizeof(char) * 16); -+ memcpy(cur->name, p, 16); -+ p += 16; -+ -+ cur->type = *(uint32_t *)p; -+ p += 4; -+ -+ cur->len = *(uint32_t *)p; -+ p += 4; -+ -+ if((cur->type ) >= 1000 ) {//Temp Workaround -+ cur->len = 0; -+ }else{ -+ if(cur->len > 0){ -+ cur->data = (uint32_t *)vmalloc(sizeof(uint8_t) * cur->len * 8); -+ memset(cur->data, 0, sizeof(uint8_t) * cur->len * 8); -+ memcpy(cur->data, p, cur->len * 8); -+ p += cur->len * 8; -+ } -+ } -+ } -+#ifndef CONFIG_FIRMWARE_ARRAY -+ vfree(rawdata); -+#endif -+ return head; -+ -+err: -+ aicbt_patch_table_free(&head); -+ if (rawdata) -+ vfree(rawdata); -+ return NULL; -+} -+int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t) -+{ -+ if (AICBT_PT_INF == head_t->type) { -+ patch_info->info_len = head_t->len; -+ if(patch_info->info_len == 0) -+ return 0; -+ memcpy(&patch_info->adid_addrinf, head_t->data, patch_info->info_len * sizeof(uint32_t) * 2); -+ } -+ return 0; -+} -+int aicbt_patch_trap_data_load(struct aic_sdio_dev *sdiodev, struct aicbt_patch_table *head) -+{ -+ struct aicbt_patch_info_t patch_info = { -+ .info_len = 0, -+ .adid_addrinf = 0, -+ .addr_adid = 0, -+ .patch_addrinf = 0, -+ .addr_patch = 0, -+ .reset_addr = 0, -+ .reset_val = 0, -+ .adid_flag_addr = 0, -+ .adid_flag = 0, -+ }; -+ if(head == NULL){ -+ return -1; -+ } -+ -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801){ -+ patch_info.addr_adid = FW_RAM_ADID_BASE_ADDR; -+ patch_info.addr_patch = FW_RAM_PATCH_BASE_ADDR; -+ } -+ else if(sdiodev->chipid == PRODUCT_ID_AIC8800DC){ -+ if(aicbsp_info.chip_rev == CHIP_REV_U01){ -+ patch_info.addr_adid = RAM_8800DC_U01_ADID_ADDR; -+ }else if(aicbsp_info.chip_rev == CHIP_REV_U02){ -+ patch_info.addr_adid = RAM_8800DC_U02_ADID_ADDR; -+ } -+ patch_info.addr_patch = RAM_8800DC_FW_PATCH_ADDR; -+ aicbt_patch_info_unpack(&patch_info, head); -+ if(patch_info.reset_addr == 0) { -+ patch_info.reset_addr = FW_RESET_START_ADDR; -+ patch_info.reset_val = FW_RESET_START_VAL; -+ patch_info.adid_flag_addr = FW_ADID_FLAG_ADDR; -+ patch_info.adid_flag = FW_ADID_FLAG_VAL; -+ if (rwnx_send_dbg_mem_write_req(sdiodev, patch_info.reset_addr, patch_info.reset_val)) -+ return -1; -+ if (rwnx_send_dbg_mem_write_req(sdiodev, patch_info.adid_flag_addr, patch_info.adid_flag)) -+ return -1; -+ } -+ } else if(sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ if (aicbsp_info.chip_rev == CHIP_REV_U01) { -+ patch_info.addr_adid = FW_RAM_ADID_BASE_ADDR_8800D80; -+ patch_info.addr_patch = FW_RAM_PATCH_BASE_ADDR_8800D80; -+ } else if (aicbsp_info.chip_rev == CHIP_REV_U02 || aicbsp_info.chip_rev == CHIP_REV_U03) { -+ patch_info.addr_adid = FW_RAM_ADID_BASE_ADDR_8800D80_U02; -+ patch_info.addr_patch = FW_RAM_PATCH_BASE_ADDR_8800D80_U02; -+ } -+ aicbt_patch_info_unpack(&patch_info, head); -+ if(patch_info.info_len == 0) { -+ printk("%s, aicbt_patch_info_unpack fail\n", __func__); -+ return -1; -+ } -+ } -+ -+ if (rwnx_plat_bin_fw_upload_android(sdiodev, patch_info.addr_adid, aicbsp_firmware_list[aicbsp_info.cpmode].bt_adid)) -+ return -1; -+ if (rwnx_plat_bin_fw_upload_android(sdiodev, patch_info.addr_patch, aicbsp_firmware_list[aicbsp_info.cpmode].bt_patch)) -+ return -1; -+ return 0; -+ -+} -+ -+static struct aicbt_info_t aicbt_info[]={ -+ { -+ .btmode = AICBT_BTMODE_DEFAULT, -+ .btport = AICBT_BTPORT_DEFAULT, -+ .uart_baud = AICBT_UART_BAUD_DEFAULT, -+ .uart_flowctrl = AICBT_UART_FC_DEFAULT, -+ .lpm_enable = AICBT_LPM_ENABLE_DEFAULT, -+ .txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT, -+ },//PRODUCT_ID_AIC8801 -+ { -+ .btmode = AICBT_BTMODE_BT_WIFI_COMBO, -+ .btport = AICBT_BTPORT_DEFAULT, -+ .uart_baud = AICBT_UART_BAUD_DEFAULT, -+ .uart_flowctrl = AICBT_UART_FC_DEFAULT, -+ .lpm_enable = AICBT_LPM_ENABLE_DEFAULT, -+ .txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT_8800dc, -+ },//PRODUCT_ID_AIC8800DC -+ { -+ .btmode = AICBT_BTMODE_BT_WIFI_COMBO, -+ .btport = AICBT_BTPORT_DEFAULT, -+ .uart_baud = AICBT_UART_BAUD_DEFAULT, -+ .uart_flowctrl = AICBT_UART_FC_DEFAULT, -+ .lpm_enable = AICBT_LPM_ENABLE_DEFAULT, -+ .txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT_8800dc, -+ },//PRODUCT_ID_AIC8800DW -+ { -+ .btmode = AICBT_BTMODE_DEFAULT_8800d80, -+ .btport = AICBT_BTPORT_DEFAULT, -+ .uart_baud = AICBT_UART_BAUD_DEFAULT, -+ .uart_flowctrl = AICBT_UART_FC_DEFAULT, -+ .lpm_enable = AICBT_LPM_ENABLE_DEFAULT, -+ .txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT_8800d80, -+ }//PRODUCT_ID_AIC8800D80 -+}; -+ -+ -+int aicbt_patch_table_load(struct aic_sdio_dev *sdiodev, struct aicbt_patch_table *head) -+{ -+ struct aicbt_patch_table *p; -+ int ret = 0, i; -+ uint32_t *data = NULL; -+ if(head == NULL){ -+ return -1; -+ } -+ -+ for (p = head; p != NULL; p = p->next) { -+ data = p->data; -+ if (AICBT_PT_BTMODE == p->type) { -+ *(data + 1) = aicbsp_info.hwinfo < 0; -+ *(data + 3) = aicbsp_info.hwinfo; -+ *(data + 5) = (sdiodev->chipid == PRODUCT_ID_AIC8800DC?aicbsp_info.cpmode:0);//0;//aicbsp_info.cpmode; -+ -+ *(data + 7) = aicbt_info[sdiodev->chipid].btmode; -+ *(data + 9) = aicbt_info[sdiodev->chipid].btport; -+ *(data + 11) = aicbt_info[sdiodev->chipid].uart_baud; -+ *(data + 13) = aicbt_info[sdiodev->chipid].uart_flowctrl; -+ *(data + 15) = aicbt_info[sdiodev->chipid].lpm_enable; -+ *(data + 17) = aicbt_info[sdiodev->chipid].txpwr_lvl; -+ -+ printk("%s bt btmode[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].btmode); -+ printk("%s bt uart_baud[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].uart_baud); -+ printk("%s bt uart_flowctrl[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].uart_flowctrl); -+ printk("%s bt lpm_enable[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].lpm_enable); -+ printk("%s bt tx_pwr[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].txpwr_lvl); -+ } -+ -+ if (AICBT_PT_VER == p->type) { -+ printk("aicbsp: bt patch version: %s\n", (char *)p->data); -+ continue; -+ } -+ -+ for (i = 0; i < p->len; i++) { -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, *data, *(data + 1)); -+ if (ret != 0) -+ return ret; -+ data += 2; -+ } -+ if (p->type == AICBT_PT_PWRON) -+ udelay(500); -+ } -+ -+ -+ ///aicbt_patch_table_free(&head); -+ return 0; -+} -+ -+ -+int aicbt_init(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ struct aicbt_patch_table *head = aicbt_patch_table_alloc(aicbsp_firmware_list[aicbsp_info.cpmode].bt_table); -+ if (head == NULL){ -+ printk("aicbt_patch_table_alloc fail\n"); -+ return -1; -+ } -+ -+ if (aicbt_patch_trap_data_load(sdiodev, head)) { -+ printk("aicbt_patch_trap_data_load fail\n"); -+ ret = -1; -+ goto err; -+ } -+ -+ if (aicbt_patch_table_load(sdiodev, head)) { -+ printk("aicbt_patch_table_load fail\n"); -+ ret = -1; -+ goto err; -+ } -+ -+err: -+ aicbt_patch_table_free(&head); -+ return ret; -+} -+ -+static int aicwifi_start_from_bootrom(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ -+ /* memory access */ -+ const u32 fw_addr = RAM_FMAC_FW_ADDR; -+ struct dbg_start_app_cfm start_app_cfm; -+ -+ /* fw start */ -+ ret = rwnx_send_dbg_start_app_req(sdiodev, fw_addr, HOST_START_APP_AUTO, &start_app_cfm); -+ if (ret) { -+ return -1; -+ } -+ aicbsp_info.hwinfo_r = start_app_cfm.bootstatus & 0xFF; -+ -+ return 0; -+} -+ -+static int start_from_bootrom_8800DC(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ u32 rd_addr; -+ u32 fw_addr; -+ u32 boot_type; -+ struct dbg_mem_read_cfm rd_cfm; -+ -+ /* memory access */ -+ if(testmode == 1){ -+ rd_addr = RAM_LMAC_FW_ADDR; -+ fw_addr = RAM_LMAC_FW_ADDR; -+ } -+ else{ -+ rd_addr = RAM_FMAC_FW_ADDR; -+ fw_addr = RAM_FMAC_FW_ADDR; -+ } -+ -+ AICWFDBG(LOGINFO, "Read FW mem: %08x\n", rd_addr); -+ if ((ret = rwnx_send_dbg_mem_read_req(sdiodev, rd_addr, &rd_cfm))) { -+ return -1; -+ } -+ AICWFDBG(LOGINFO, "cfm: [%08x] = %08x\n", rd_cfm.memaddr, rd_cfm.memdata); -+ -+ if (testmode == 0) { -+ boot_type = HOST_START_APP_DUMMY; -+ } else { -+ boot_type = HOST_START_APP_AUTO; -+ } -+ /* fw start */ -+ AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type); -+ if ((ret = rwnx_send_dbg_start_app_req(sdiodev, fw_addr, boot_type ,NULL))) { -+ return -1; -+ } -+ return 0; -+} -+ -+u32 adaptivity_patch_tbl[][2] = { -+ {0x0004, 0x0000320A}, //linkloss_thd -+ {0x0094, 0x00000000}, //ac_param_conf -+ {0x00F8, 0x00010138}, //tx_adaptivity_en -+}; -+ -+u32 patch_tbl[][2] = { -+#if !defined(CONFIG_LINK_DET_5G) -+ {0x0104, 0x00000000}, //link_det_5g -+#endif -+#if defined(CONFIG_MCU_MESSAGE) -+ {0x004c, 0x0000004B}, //pkt_cnt_1724=0x4B -+ {0x0050, 0x0011FC00}, //ipc_base_addr -+#endif -+}; -+ -+u32 syscfg_tbl_masked[][3] = { -+ {0x40506024, 0x000000FF, 0x000000DF}, // for clk gate lp_level -+}; -+ -+u32 rf_tbl_masked[][3] = { -+ {0x40344058, 0x00800000, 0x00000000},// pll trx -+}; -+ -+static int aicwifi_sys_config(struct aic_sdio_dev *sdiodev) -+{ -+ int ret, cnt; -+ int syscfg_num = sizeof(syscfg_tbl_masked) / sizeof(u32) / 3; -+ for (cnt = 0; cnt < syscfg_num; cnt++) { -+ ret = rwnx_send_dbg_mem_mask_write_req(sdiodev, -+ syscfg_tbl_masked[cnt][0], syscfg_tbl_masked[cnt][1], syscfg_tbl_masked[cnt][2]); -+ if (ret) { -+ printk("%x mask write fail: %d\n", syscfg_tbl_masked[cnt][0], ret); -+ return ret; -+ } -+ } -+ -+ ret = rwnx_send_dbg_mem_mask_write_req(sdiodev, -+ rf_tbl_masked[0][0], rf_tbl_masked[0][1], rf_tbl_masked[0][2]); -+ if (ret) { -+ printk("rf config %x write fail: %d\n", rf_tbl_masked[0][0], ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int aicwifi_patch_config(struct aic_sdio_dev *sdiodev) -+{ -+ const u32 rd_patch_addr = RAM_FMAC_FW_ADDR + 0x0180; -+ u32 config_base; -+ uint32_t start_addr = 0x1e6000; -+ u32 patch_addr = start_addr; -+ u32 patch_num = sizeof(patch_tbl)/4; -+ struct dbg_mem_read_cfm rd_patch_addr_cfm; -+ u32 patch_addr_reg = 0x1e5318; -+ u32 patch_num_reg = 0x1e531c; -+ int ret = 0; -+ u16 cnt = 0; -+ int tmp_cnt = 0; -+ int adap_patch_num = 0; -+ -+ if (aicbsp_info.cpmode == AICBSP_CPMODE_TEST) { -+ patch_addr_reg = 0x1e5304; -+ patch_num_reg = 0x1e5308; -+ } -+ -+ ret = rwnx_send_dbg_mem_read_req(sdiodev, rd_patch_addr, &rd_patch_addr_cfm); -+ if (ret) { -+ printk("patch rd fail\n"); -+ return ret; -+ } -+ -+ config_base = rd_patch_addr_cfm.memdata; -+ -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, patch_addr_reg, patch_addr); -+ if (ret) { -+ printk("0x%x write fail\n", patch_addr_reg); -+ return ret; -+ } -+ -+ if(adap_test){ -+ printk("%s for adaptivity test \r\n", __func__); -+ adap_patch_num = sizeof(adaptivity_patch_tbl)/4; -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, patch_num_reg, patch_num + adap_patch_num); -+ }else{ -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, patch_num_reg, patch_num); -+ } -+ if (ret) { -+ printk("0x%x write fail\n", patch_num_reg); -+ return ret; -+ } -+ -+ for (cnt = 0; cnt < patch_num/2; cnt += 1) { -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt, patch_tbl[cnt][0]+config_base); -+ if (ret) { -+ printk("%x write fail\n", start_addr+8*cnt); -+ return ret; -+ } -+ -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt+4, patch_tbl[cnt][1]); -+ if (ret) { -+ printk("%x write fail\n", start_addr+8*cnt+4); -+ return ret; -+ } -+ } -+ -+ tmp_cnt = cnt; -+ -+ if(adap_test){ -+ for(cnt = 0; cnt < adap_patch_num/2; cnt+=1) -+ { -+ if((ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*(cnt+tmp_cnt), adaptivity_patch_tbl[cnt][0]+config_base))) { -+ printk("%x write fail\n", start_addr+8*cnt); -+ } -+ -+ if((ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*(cnt+tmp_cnt)+4, adaptivity_patch_tbl[cnt][1]))) { -+ printk("%x write fail\n", start_addr+8*cnt+4); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+int aicwifi_init(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801){ -+ #ifdef CONFIG_M2D_OTA_AUTO_SUPPORT -+ if (testmode == FW_M2D_OTA_MODE) { -+ rwnx_plat_m2d_flash_ota_android(sdiodev, FW_M2D_OTA_NAME); -+ } else if (testmode == FW_NORMAL_MODE) { -+ rwnx_plat_m2d_flash_ota_check(sdiodev, FW_M2D_OTA_NAME); -+ } -+ #endif -+ if (rwnx_plat_bin_fw_upload_android(sdiodev, RAM_FMAC_FW_ADDR, aicbsp_firmware_list[aicbsp_info.cpmode].wl_fw)) { -+ printk("download wifi fw fail\n"); -+ return -1; -+ } -+ -+ if (aicwifi_patch_config(sdiodev)) { -+ printk("aicwifi_patch_config fail\n"); -+ return -1; -+ } -+ -+ if (aicwifi_sys_config(sdiodev)) { -+ printk("aicwifi_sys_config fail\n"); -+ return -1; -+ } -+ -+ if (aicwifi_start_from_bootrom(sdiodev)) { -+ printk("wifi start fail\n"); -+ return -1; -+ } -+ }else if (sdiodev->chipid == PRODUCT_ID_AIC8800DC || sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ printk("############ aicwifi_init begin \n"); -+ -+ system_config_8800dc(sdiodev); -+ printk("############ system_config_8800dc done\n"); -+ -+ ret = rwnx_plat_patch_load(sdiodev); -+ if (ret) { -+ printk("patch load return %d\n", ret); -+ return ret; -+ } -+ printk("############ rwnx_plat_patch_load done\n"); -+ -+ //rwnx_plat_userconfig_load(sdiodev); -+ -+ aicwf_patch_config_8800dc(sdiodev); -+ printk("############ aicwf_patch_config_8800dc done\n"); -+ -+ start_from_bootrom_8800DC(sdiodev); -+ }else if(sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ if (rwnx_plat_bin_fw_upload_android(sdiodev, RAM_FMAC_FW_ADDR, aicbsp_firmware_list[aicbsp_info.cpmode].wl_fw)) { -+ printk("8800d80 download wifi fw fail\n"); -+ return -1; -+ } -+ -+ if (aicwifi_patch_config_8800d80(sdiodev)) { -+ printk("aicwifi_patch_config_8800d80 fail\n"); -+ return -1; -+ } -+ -+ if (aicwifi_sys_config_8800d80(sdiodev)) { -+ printk("aicwifi_patch_config_8800d80 fail\n"); -+ return -1; -+ } -+ -+ if (aicwifi_start_from_bootrom(sdiodev)) { -+ printk("8800d80 wifi start fail\n"); -+ return -1; -+ } -+ } -+ -+#ifdef CONFIG_GPIO_WAKEUP -+ if (aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.wakeup_reg, 4)) { -+ sdio_err("reg:%d write failed!\n", sdiodev->sdio_reg.wakeup_reg); -+ return -1; -+ } -+#endif -+ return 0; -+} -+ -+u32 aicbsp_syscfg_tbl[][2] = { -+ {0x40500014, 0x00000101}, // 1) -+ {0x40500018, 0x00000109}, // 2) -+ {0x40500004, 0x00000010}, // 3) the order should not be changed -+ -+ // def CONFIG_PMIC_SETTING -+ // U02 bootrom only -+ {0x40040000, 0x00001AC8}, // 1) fix panic -+ {0x40040084, 0x00011580}, -+ {0x40040080, 0x00000001}, -+ {0x40100058, 0x00000000}, -+ -+ {0x50000000, 0x03220204}, // 2) pmic interface init -+ {0x50019150, 0x00000002}, // 3) for 26m xtal, set div1 -+ {0x50017008, 0x00000000}, // 4) stop wdg -+}; -+ -+static int aicbsp_system_config(struct aic_sdio_dev *sdiodev) -+{ -+ int syscfg_num = sizeof(aicbsp_syscfg_tbl) / sizeof(u32) / 2; -+ int ret, cnt; -+ for (cnt = 0; cnt < syscfg_num; cnt++) { -+ ret = rwnx_send_dbg_mem_write_req(sdiodev, aicbsp_syscfg_tbl[cnt][0], aicbsp_syscfg_tbl[cnt][1]); -+ if (ret) { -+ sdio_err("%x write fail: %d\n", aicbsp_syscfg_tbl[cnt][0], ret); -+ return ret; -+ } -+ } -+ return 0; -+} -+ -+ -+ -+int aicbsp_platform_init(struct aic_sdio_dev *sdiodev) -+{ -+ rwnx_cmd_mgr_init(&sdiodev->cmd_mgr); -+ sdiodev->cmd_mgr.sdiodev = (void *)sdiodev; -+ -+ return 0; -+} -+ -+void aicbsp_platform_deinit(struct aic_sdio_dev *sdiodev) -+{ -+ (void)sdiodev; -+} -+ -+int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev) -+{ -+ u32 mem_addr; -+ struct dbg_mem_read_cfm rd_mem_addr_cfm; -+ u32 btenable = 0; -+ u8 is_chip_id_h = 0; -+ int ret = 0; -+ -+ mem_addr = 0x40500000; -+ -+ testmode = aicbsp_info.cpmode; -+ -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801){ -+ -+ if (rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm)) -+ return -1; -+ -+ aicbsp_info.chip_rev = (u8)(rd_mem_addr_cfm.memdata >> 16); -+ btenable = 1; -+ -+ if (aicbsp_info.chip_rev != CHIP_REV_U02 && -+ aicbsp_info.chip_rev != CHIP_REV_U03 && -+ aicbsp_info.chip_rev != CHIP_REV_U04) { -+ pr_err("aicbsp: %s, unsupport chip rev: %d\n", __func__, aicbsp_info.chip_rev); -+ return -1; -+ } -+ -+ if (aicbsp_info.chip_rev != CHIP_REV_U02) -+ aicbsp_firmware_list = fw_u03; -+ -+ if (aicbsp_system_config(sdiodev)) -+ return -1; -+ } -+ else if (sdiodev->chipid == PRODUCT_ID_AIC8800DC || sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ if (rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm)) -+ return -1; -+ -+ aicbsp_info.chip_rev = (u8)((rd_mem_addr_cfm.memdata >> 16) & 0x3F); -+ is_chip_id_h = (u8)(((rd_mem_addr_cfm.memdata >> 16) & 0xC0) == 0xC0); -+ -+ btenable = ((rd_mem_addr_cfm.memdata >> 26) & 0x1); -+ AICWFDBG(LOGINFO, "btenable = %d \n",btenable); -+ -+ if(btenable == 0){ -+ sdiodev->chipid = PRODUCT_ID_AIC8800DW; -+ AICWFDBG(LOGINFO, "AIC8800DC change to AIC8800DW \n"); -+ } -+ -+ if (aicbsp_info.chip_rev != CHIP_REV_U01 && -+ aicbsp_info.chip_rev != CHIP_REV_U02 && -+ aicbsp_info.chip_rev != CHIP_REV_U03 && -+ aicbsp_info.chip_rev != CHIP_REV_U04) { -+ pr_err("aicbsp: %s, unsupport chip rev: %d\n", __func__, aicbsp_info.chip_rev); -+ return -1; -+ } -+ if (is_chip_id_h) { -+ AICWFDBG(LOGINFO, "IS_CHIP_ID_H \n"); -+ aicbsp_firmware_list = fw_8800dc_h_u02; -+ } else { -+ if(aicbsp_info.chip_rev == CHIP_REV_U01){ -+ aicbsp_firmware_list = fw_8800dc_u01; -+ }else{ -+ aicbsp_firmware_list = fw_8800dc_u02; -+ } -+ } -+ } -+ else if(sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ -+ if (rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm)) -+ return -1; -+ -+ aicbsp_info.chip_rev = (u8)(rd_mem_addr_cfm.memdata >> 16); -+ btenable = 1; -+ -+ if (aicbsp_info.chip_rev == CHIP_REV_U01) -+ aicbsp_firmware_list = fw_8800d80_u01; -+ if (aicbsp_info.chip_rev == CHIP_REV_U02 || aicbsp_info.chip_rev == CHIP_REV_U03) -+ aicbsp_firmware_list = fw_8800d80_u02; -+ if (aicbsp_system_config_8800d80(sdiodev)) -+ return -1; -+ } -+ -+ AICWFDBG(LOGINFO, "aicbsp: %s, chip rev: %d\n", __func__, aicbsp_info.chip_rev); -+ -+ #ifndef CONFIG_MCU_MESSAGE -+ if (testmode != 4) { -+ if(btenable == 1){ -+ if (aicbt_init(sdiodev)) -+ return -1; -+ } -+ } -+ #endif -+ -+ ret = aicwifi_init(sdiodev); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path) -+{ -+ if (aicbsp_sdiodev->chipid == PRODUCT_ID_AIC8801 || -+ aicbsp_sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ aicbsp_sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ feature->sdio_clock = FEATURE_SDIO_CLOCK; -+ }else if (aicbsp_sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ feature->sdio_clock = FEATURE_SDIO_CLOCK_V3; -+ } -+ feature->sdio_phase = FEATURE_SDIO_PHASE; -+ feature->hwinfo = aicbsp_info.hwinfo; -+ feature->fwlog_en = aicbsp_info.fwlog_en; -+ feature->irqf = aicbsp_info.irqf; -+ if(fw_path != NULL){ -+ sprintf(fw_path,"%s", AICBSP_FW_PATH); -+ } -+ sdio_dbg("%s, set FEATURE_SDIO_CLOCK %d MHz\n", __func__, feature->sdio_clock/1000000); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(aicbsp_get_feature); -+ -+#ifdef CONFIG_RESV_MEM_SUPPORT -+static struct skb_buff_pool resv_skb[] = { -+ {AIC_RESV_MEM_TXDATA, 1536*64, "resv_mem_txdata", 0, NULL}, -+}; -+ -+int aicbsp_resv_mem_init(void) -+{ -+ int i = 0; -+ printk("%s \n",__func__); -+ for (i = 0; i < sizeof(resv_skb) / sizeof(resv_skb[0]); i++) { -+ resv_skb[i].skb = dev_alloc_skb(resv_skb[i].size); -+ } -+ return 0; -+} -+ -+int aicbsp_resv_mem_deinit(void) -+{ -+ int i = 0; -+ printk("%s \n",__func__); -+ for (i = 0; i < sizeof(resv_skb) / sizeof(resv_skb[0]); i++) { -+ if (resv_skb[i].used == 0 && resv_skb[i].skb) -+ dev_kfree_skb(resv_skb[i].skb); -+ } -+ return 0; -+} -+ -+struct sk_buff *aicbsp_resv_mem_alloc_skb(unsigned int length, uint32_t id) -+{ -+ if (resv_skb[id].size < length) { -+ pr_err("aicbsp: %s, no enough mem\n", __func__); -+ goto fail; -+ } -+ -+ if (resv_skb[id].used) { -+ pr_err("aicbsp: %s, mem in use\n", __func__); -+ goto fail; -+ } -+ -+ if (resv_skb[id].skb == NULL) { -+ pr_err("aicbsp: %s, mem not initialazed\n", __func__); -+ resv_skb[id].skb = dev_alloc_skb(resv_skb[id].size); -+ if (resv_skb[id].skb == NULL) { -+ pr_err("aicbsp: %s, mem reinitial still fail\n", __func__); -+ goto fail; -+ } -+ } -+ -+ printk("aicbsp: %s, alloc %s succuss, id: %d, size: %d\n", __func__, -+ resv_skb[id].name, resv_skb[id].id, resv_skb[id].size); -+ -+ resv_skb[id].used = 1; -+ return resv_skb[id].skb; -+ -+fail: -+ return NULL; -+} -+EXPORT_SYMBOL_GPL(aicbsp_resv_mem_alloc_skb); -+ -+void aicbsp_resv_mem_kfree_skb(struct sk_buff *skb, uint32_t id) -+{ -+ resv_skb[id].used = 0; -+ printk("aicbsp: %s, free %s succuss, id: %d, size: %d\n", __func__, -+ resv_skb[id].name, resv_skb[id].id, resv_skb[id].size); -+} -+EXPORT_SYMBOL_GPL(aicbsp_resv_mem_kfree_skb); -+ -+#else -+ -+int aicbsp_resv_mem_init(void) -+{ -+ return 0; -+} -+ -+int aicbsp_resv_mem_deinit(void) -+{ -+ return 0; -+} -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,581 @@ -+/** -+ ****************************************************************************** -+ * -+ * rwnx_cmds.h -+ * -+ * Copyright (C) RivieraWaves 2014-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _AIC_BSP_DRIVER_H -+#define _AIC_BSP_DRIVER_H -+ -+#include -+#include -+#include -+#include "aic_bsp_export.h" -+ -+#define RWNX_80211_CMD_TIMEOUT_MS 3000//500//300 -+ -+#define RWNX_CMD_FLAG_NONBLOCK BIT(0) -+#define RWNX_CMD_FLAG_REQ_CFM BIT(1) -+#define RWNX_CMD_FLAG_WAIT_PUSH BIT(2) -+#define RWNX_CMD_FLAG_WAIT_ACK BIT(3) -+#define RWNX_CMD_FLAG_WAIT_CFM BIT(4) -+#define RWNX_CMD_FLAG_DONE BIT(5) -+/* ATM IPC design makes it possible to get the CFM before the ACK, -+ * otherwise this could have simply been a state enum */ -+#define RWNX_CMD_WAIT_COMPLETE(flags) \ -+ (!(flags & (RWNX_CMD_FLAG_WAIT_ACK | RWNX_CMD_FLAG_WAIT_CFM))) -+ -+#define RWNX_CMD_MAX_QUEUED 8 -+ -+#define IPC_E2A_MSG_PARAM_SIZE 256 -+ -+#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__ -+ -+/* message levels */ -+#define LOGERROR 0x0001 -+#define LOGINFO 0x0002 -+#define LOGTRACE 0x0004 -+#define LOGDEBUG 0x0008 -+#define LOGDATA 0x0010 -+ -+extern int aicwf_dbg_level_bsp; -+ -+#define AICWF_LOG "AICWFDBG(" -+ -+#define AICWFDBG(level, args, arg...) \ -+do { \ -+ if (aicwf_dbg_level_bsp & level) { \ -+ printk(AICWF_LOG#level")\t" args, ##arg); \ -+ } \ -+} while (0) -+ -+#define RWNX_DBG(fmt, ...) \ -+do { \ -+ if (aicwf_dbg_level_bsp & LOGTRACE) { \ -+ printk(AICWF_LOG"LOGTRACE)\t"fmt , ##__VA_ARGS__); \ -+ } \ -+} while (0) -+ -+/// Message structure for MSGs from Emb to App -+struct ipc_e2a_msg { -+ u16 id; ///< Message id. -+ u16 dummy_dest_id; -+ u16 dummy_src_id; -+ u16 param_len; ///< Parameter embedded struct length. -+ u32 pattern; ///< Used to stamp a valid MSG buffer -+ u32 param[IPC_E2A_MSG_PARAM_SIZE]; ///< Parameter embedded struct. Must be word-aligned. -+}; -+ -+typedef u16 lmac_msg_id_t; -+typedef u16 lmac_task_id_t; -+ -+struct lmac_msg { -+ lmac_msg_id_t id; ///< Message id. -+ lmac_task_id_t dest_id; ///< Destination kernel identifier. -+ lmac_task_id_t src_id; ///< Source kernel identifier. -+ u16 param_len; ///< Parameter embedded struct length. -+ u32 param[]; ///< Parameter embedded struct. Must be word-aligned. -+}; -+ -+#define rwnx_cmd_e2amsg ipc_e2a_msg -+#define rwnx_cmd_a2emsg lmac_msg -+#define RWNX_CMD_A2EMSG_LEN(m) (sizeof(struct lmac_msg) + m->param_len) -+#define RWNX_CMD_E2AMSG_LEN_MAX (IPC_E2A_MSG_PARAM_SIZE * 4) -+ -+static inline void put_u16(u8 *buf, u16 data) -+{ -+ buf[0] = (u8)(data&0x00ff); -+ buf[1] = (u8)((data >> 8)&0x00ff); -+} -+ -+enum rwnx_cmd_mgr_state { -+ RWNX_CMD_MGR_STATE_DEINIT, -+ RWNX_CMD_MGR_STATE_INITED, -+ RWNX_CMD_MGR_STATE_CRASHED, -+}; -+ -+struct rwnx_cmd { -+ struct list_head list; -+ lmac_msg_id_t id; -+ lmac_msg_id_t reqid; -+ struct rwnx_cmd_a2emsg *a2e_msg; -+ char *e2a_msg; -+ u32 tkn; -+ u16 flags; -+ struct completion complete; -+ u32 result; -+}; -+ -+struct aic_sdio_dev; -+struct rwnx_cmd; -+typedef int (*msg_cb_fct)(struct rwnx_cmd *cmd, struct rwnx_cmd_e2amsg *msg); -+ -+struct rwnx_cmd_mgr { -+ enum rwnx_cmd_mgr_state state; -+ spinlock_t lock; -+ u32 next_tkn; -+ u32 queue_sz; -+ u32 max_queue_sz; -+ spinlock_t cb_lock; -+ void *sdiodev; -+ -+ struct list_head cmds; -+ -+ int (*queue)(struct rwnx_cmd_mgr *, struct rwnx_cmd *); -+ int (*llind)(struct rwnx_cmd_mgr *, struct rwnx_cmd *); -+ int (*msgind)(struct rwnx_cmd_mgr *, struct rwnx_cmd_e2amsg *, msg_cb_fct); -+ void (*print)(struct rwnx_cmd_mgr *); -+ void (*drain)(struct rwnx_cmd_mgr *); -+ -+ struct work_struct cmdWork; -+ struct workqueue_struct *cmd_wq; -+}; -+ -+void rwnx_cmd_mgr_init(struct rwnx_cmd_mgr *cmd_mgr); -+void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr); -+int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd); -+void rwnx_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len); -+ -+enum { -+ TASK_NONE = (u8) -1, -+ -+ // MAC Management task. -+ TASK_MM = 0, -+ // DEBUG task -+ TASK_DBG, -+ /// SCAN task -+ TASK_SCAN, -+ /// TDLS task -+ TASK_TDLS, -+ /// SCANU task -+ TASK_SCANU, -+ /// ME task -+ TASK_ME, -+ /// SM task -+ TASK_SM, -+ /// APM task -+ TASK_APM, -+ /// BAM task -+ TASK_BAM, -+ /// MESH task -+ TASK_MESH, -+ /// RXU task -+ TASK_RXU, -+ // This is used to define the last task that is running on the EMB processor -+ TASK_LAST_EMB = TASK_RXU, -+ -+ // nX API task -+ TASK_API, -+ TASK_MAX, -+}; -+ -+#define LMAC_FIRST_MSG(task) ((lmac_msg_id_t)((task) << 10)) -+#define DRV_TASK_ID 100 -+#define MSG_I(msg) ((msg) & ((1<<10)-1)) -+#define MSG_T(msg) ((lmac_task_id_t)((msg) >> 10)) -+ -+enum dbg_msg_tag { -+ /// Memory read request -+ DBG_MEM_READ_REQ = LMAC_FIRST_MSG(TASK_DBG), -+ /// Memory read confirm -+ DBG_MEM_READ_CFM, -+ /// Memory write request -+ DBG_MEM_WRITE_REQ, -+ /// Memory write confirm -+ DBG_MEM_WRITE_CFM, -+ /// Module filter request -+ DBG_SET_MOD_FILTER_REQ, -+ /// Module filter confirm -+ DBG_SET_MOD_FILTER_CFM, -+ /// Severity filter request -+ DBG_SET_SEV_FILTER_REQ, -+ /// Severity filter confirm -+ DBG_SET_SEV_FILTER_CFM, -+ /// LMAC/MAC HW fatal error indication -+ DBG_ERROR_IND, -+ /// Request to get system statistics -+ DBG_GET_SYS_STAT_REQ, -+ /// COnfirmation of system statistics -+ DBG_GET_SYS_STAT_CFM, -+ /// Memory block write request -+ DBG_MEM_BLOCK_WRITE_REQ, -+ /// Memory block write confirm -+ DBG_MEM_BLOCK_WRITE_CFM, -+ /// Start app request -+ DBG_START_APP_REQ, -+ /// Start app confirm -+ DBG_START_APP_CFM, -+ /// Start npc request -+ DBG_START_NPC_REQ, -+ /// Start npc confirm -+ DBG_START_NPC_CFM, -+ /// Memory mask write request -+ DBG_MEM_MASK_WRITE_REQ, -+ /// Memory mask write confirm -+ DBG_MEM_MASK_WRITE_CFM, -+ -+ DBG_RFTEST_CMD_REQ, -+ DBG_RFTEST_CMD_CFM, -+ DBG_BINDING_REQ, -+ DBG_BINDING_CFM, -+ DBG_BINDING_IND, -+ -+ DBG_CUSTOM_MSG_REQ, -+ DBG_CUSTOM_MSG_CFM, -+ DBG_CUSTOM_MSG_IND, -+ -+ DBG_GPIO_WRITE_REQ, -+ DBG_GPIO_WRITE_CFM, -+ -+ -+ /// Max number of Debug messages -+ DBG_MAX, -+}; -+ -+#if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT) -+#define FW_M2D_OTA_NAME "m2d_ota.bin" -+#else -+#define FW_M2D_OTA_NAME "m2d_ota_lzma.bin" -+#endif -+ -+enum { -+ HOST_START_APP_AUTO = 1, -+ HOST_START_APP_CUSTOM, -+ HOST_START_APP_FNCALL = 4, -+ HOST_START_APP_DUMMY = 5, -+}; -+ -+ -+struct dbg_mem_block_write_req { -+ u32 memaddr; -+ u32 memsize; -+ u32 memdata[1024 / sizeof(u32)]; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_BLOCK_WRITE_CFM message. -+struct dbg_mem_block_write_cfm { -+ u32 wstatus; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_WRITE_REQ message. -+struct dbg_mem_write_req { -+ u32 memaddr; -+ u32 memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_WRITE_CFM message. -+struct dbg_mem_write_cfm { -+ u32 memaddr; -+ u32 memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_READ_REQ message. -+struct dbg_mem_read_req { -+ u32 memaddr; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_READ_CFM message. -+struct dbg_mem_read_cfm { -+ u32 memaddr; -+ u32 memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_MASK_WRITE_REQ message. -+struct dbg_mem_mask_write_req { -+ u32 memaddr; -+ u32 memmask; -+ u32 memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_MASK_WRITE_CFM message. -+struct dbg_mem_mask_write_cfm { -+ u32 memaddr; -+ u32 memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_START_APP_REQ message. -+struct dbg_start_app_req { -+ u32 bootaddr; -+ u32 boottype; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_START_APP_CFM message. -+struct dbg_start_app_cfm { -+ u32 bootstatus; -+}; -+ -+int aicwf_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev); -+int aicwf_plat_rftest_load_8800dc(struct aic_sdio_dev *sdiodev); -+#ifdef CONFIG_DPD -+int aicwf_misc_ram_valid_check_8800dc(struct aic_sdio_dev *sdiodev, int *valid_out); -+int aicwf_plat_calib_load_8800dc(struct aic_sdio_dev *sdiodev); -+#endif -+ -+int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *device); -+int aicwf_patch_table_load(struct aic_sdio_dev *rwnx_hw, char *filename); -+ -+int rwnx_send_dbg_mem_read_req(struct aic_sdio_dev *sdiodev, u32 mem_addr, -+ struct dbg_mem_read_cfm *cfm); -+int rwnx_send_dbg_mem_block_write_req(struct aic_sdio_dev *sdiodev, u32 mem_addr, -+ u32 mem_size, u32 *mem_data); -+int rwnx_send_dbg_mem_write_req(struct aic_sdio_dev *sdiodev, u32 mem_addr, u32 mem_data); -+int rwnx_send_dbg_mem_mask_write_req(struct aic_sdio_dev *sdiodev, u32 mem_addr, -+ u32 mem_mask, u32 mem_data); -+int rwnx_send_dbg_start_app_req(struct aic_sdio_dev *sdiodev, u32 boot_addr, u32 boot_type, struct dbg_start_app_cfm *start_app_cfm); -+ -+int rwnx_plat_bin_fw_upload_android(struct aic_sdio_dev *sdiodev, u32 fw_addr, const char *filename); -+ -+void rwnx_rx_handle_msg(struct aic_sdio_dev *sdiodev, struct ipc_e2a_msg *msg); -+int aicbsp_platform_init(struct aic_sdio_dev *sdiodev); -+void aicbsp_platform_deinit(struct aic_sdio_dev *sdiodev); -+int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev); -+#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB)) -+int is_file_exist(char* name); -+#endif -+int aicbsp_resv_mem_init(void); -+int aicbsp_resv_mem_deinit(void); -+ -+#define AICBSP_FW_PATH CONFIG_AIC_FW_PATH -+#define AICBSP_FW_PATH_MAX 200 -+ -+#define RAM_FMAC_FW_ADDR 0x00120000 -+#define FW_RAM_ADID_BASE_ADDR 0x00161928 -+#define FW_RAM_ADID_BASE_ADDR_U03 0x00161928 -+#define FW_RAM_PATCH_BASE_ADDR 0x00100000 -+#define RAM_8800DC_U01_ADID_ADDR 0x00101788 -+#define RAM_8800DC_U02_ADID_ADDR 0x001017d8 -+#define RAM_8800DC_FW_PATCH_ADDR 0x00184000 -+#define FW_RESET_START_ADDR 0x40500128 -+#define FW_RESET_START_VAL 0x40 -+#define FW_ADID_FLAG_ADDR 0x40500150 -+#define FW_ADID_FLAG_VAL 0x01 -+#define FW_RAM_ADID_BASE_ADDR_8800D80 0x002017E0 -+#define FW_RAM_PATCH_BASE_ADDR_8800D80 0x0020B2B0 -+#define FW_RAM_ADID_BASE_ADDR_8800D80_U02 0x00201940 -+#define FW_RAM_PATCH_BASE_ADDR_8800D80_U02 0x0020b43c -+ -+#define AICBT_PT_TAG "AICBT_PT_TAG" -+ -+ -+/***************************************************************************** -+ * Addresses within RWNX_ADDR_CPU -+ *****************************************************************************/ -+#define RAM_LMAC_FW_ADDR 0x00150000 -+ -+#define ROM_FMAC_FW_ADDR 0x00010000 -+#define ROM_FMAC_PATCH_ADDR 0x00180000 -+ -+#define RWNX_MAC_CALIB_BASE_NAME_8800DC "fmacfw_calib_8800dc" -+#define RWNX_MAC_CALIB_NAME_8800DC_U02 RWNX_MAC_CALIB_BASE_NAME_8800DC"_u02.bin" -+#ifdef CONFIG_SDIO_BT -+#define RWNX_MAC_CALIB_NAME_8800DC_H_U02 RWNX_MAC_CALIB_BASE_NAME_8800DC"_hbt_u02.bin" -+#else -+#define RWNX_MAC_CALIB_NAME_8800DC_H_U02 RWNX_MAC_CALIB_BASE_NAME_8800DC"_h_u02.bin" -+#endif -+ -+#ifdef CONFIG_DPD -+#define ROM_FMAC_CALIB_ADDR 0x00130000 -+#ifndef CONFIG_FORCE_DPD_CALIB -+#define FW_DPDRESULT_NAME_8800DC "aic_dpdresult_lite_8800dc.bin" -+#endif -+#endif -+ -+#define RWNX_MAC_FW_RF_BASE_NAME_8800DC "lmacfw_rf_8800dc.bin" -+ -+#ifdef CONFIG_FOR_IPCOM -+#define RWNX_MAC_PATCH_BASE_NAME_8800DC "fmacfw_patch_8800dc_ipc" -+#define RWNX_MAC_PATCH_NAME2_8800DC RWNX_MAC_PATCH_BASE_NAME_8800DC".bin" -+#else -+#define RWNX_MAC_PATCH_BASE_NAME_8800DC "fmacfw_patch_8800dc" -+#define RWNX_MAC_PATCH_NAME2_8800DC RWNX_MAC_PATCH_BASE_NAME_8800DC".bin" -+#define RWNX_MAC_PATCH_NAME2_8800DC_U02 RWNX_MAC_PATCH_BASE_NAME_8800DC"_u02.bin" -+#ifdef CONFIG_SDIO_BT -+#define RWNX_MAC_PATCH_NAME2_8800DC_H_U02 RWNX_MAC_PATCH_BASE_NAME_8800DC"_hbt_u02.bin" -+#else -+#define RWNX_MAC_PATCH_NAME2_8800DC_H_U02 RWNX_MAC_PATCH_BASE_NAME_8800DC"_h_u02.bin" -+#endif -+#endif -+ -+#define RWNX_MAC_PATCH_TABLE_NAME_8800DC "fmacfw_patch_tbl_8800dc" -+#define RWNX_MAC_PATCH_TABLE_8800DC RWNX_MAC_PATCH_TABLE_NAME_8800DC ".bin" -+#define RWNX_MAC_PATCH_TABLE_8800DC_U02 RWNX_MAC_PATCH_TABLE_NAME_8800DC "_u02.bin" -+#ifdef CONFIG_SDIO_BT -+#define RWNX_MAC_PATCH_TABLE_8800DC_H_U02 RWNX_MAC_PATCH_TABLE_NAME_8800DC "_hbt_u02.bin" -+#else -+#define RWNX_MAC_PATCH_TABLE_8800DC_H_U02 RWNX_MAC_PATCH_TABLE_NAME_8800DC "_h_u02.bin" -+#endif -+ -+#define RWNX_MAC_RF_PATCH_BASE_NAME_8800DC "fmacfw_rf_patch_8800dc" -+#define RWNX_MAC_RF_PATCH_NAME_8800DC RWNX_MAC_RF_PATCH_BASE_NAME_8800DC".bin" -+#define FW_USERCONFIG_NAME_8800DC "aic_userconfig_8800dc.txt" -+ -+enum { -+ FW_NORMAL_MODE = 0, -+ FW_RFTEST_MODE = 1, -+ FW_BLE_SCAN_WAKEUP_MODE = 2, -+ FW_M2D_OTA_MODE = 3, -+ FW_DPDCALIB_MODE = 4, -+ FW_BLE_SCAN_AD_FILTER_MODE = 5, -+}; -+ -+enum aicbt_patch_table_type { -+ AICBT_PT_INF = 0x00, -+ AICBT_PT_TRAP = 0x1, -+ AICBT_PT_B4, -+ AICBT_PT_BTMODE, -+ AICBT_PT_PWRON, -+ AICBT_PT_AF, -+ AICBT_PT_VER, -+}; -+ -+enum aicbt_btport_type { -+ AICBT_BTPORT_NULL, -+ AICBT_BTPORT_MB, -+ AICBT_BTPORT_UART, -+}; -+ -+/* btmode -+ * used for force bt mode,if not AICBSP_MODE_NULL -+ * efuse valid and vendor_info will be invalid, even has beed set valid -+*/ -+enum aicbt_btmode_type { -+ AICBT_BTMODE_BT_ONLY_SW = 0x0, // bt only mode with switch -+ AICBT_BTMODE_BT_WIFI_COMBO, // wifi/bt combo mode -+ AICBT_BTMODE_BT_ONLY, // bt only mode without switch -+ AICBT_BTMODE_BT_ONLY_TEST, // bt only test mode -+ AICBT_BTMODE_BT_WIFI_COMBO_TEST, // wifi/bt combo test mode -+ AICBT_BTMODE_BT_ONLY_COANT, // bt only mode with no external switch -+ AICBT_MODE_NULL = 0xFF, // invalid value -+}; -+ -+/* uart_baud -+ * used for config uart baud when btport set to uart, -+ * otherwise meaningless -+*/ -+enum aicbt_uart_baud_type { -+ AICBT_UART_BAUD_115200 = 115200, -+ AICBT_UART_BAUD_921600 = 921600, -+ AICBT_UART_BAUD_1_5M = 1500000, -+ AICBT_UART_BAUD_3_25M = 3250000, -+}; -+ -+enum aicbt_uart_flowctrl_type { -+ AICBT_UART_FLOWCTRL_DISABLE = 0x0, // uart without flow ctrl -+ AICBT_UART_FLOWCTRL_ENABLE, // uart with flow ctrl -+}; -+ -+enum aicbsp_cpmode_type { -+ AICBSP_CPMODE_WORK, -+ AICBSP_CPMODE_TEST, -+ AICBSP_CPMODE_MAX, -+}; -+ -+enum chip_rev { -+ CHIP_REV_U01 = 1, -+ CHIP_REV_U02 = 3, -+ CHIP_REV_U03 = 7, -+ CHIP_REV_U04 = 7, -+}; -+ -+#define AIC_M2D_OTA_INFO_ADDR 0x88000020 -+#define AIC_M2D_OTA_DATA_ADDR 0x88000040 -+#if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT) -+#define AIC_M2D_OTA_FLASH_ADDR 0x08004000 -+#define AIC_M2D_OTA_CODE_START_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x0188) -+#define AIC_M2D_OTA_VER_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x018C) -+#else -+#define AIC_M2D_OTA_FLASH_ADDR 0x08005000 -+#define AIC_M2D_OTA_CODE_START_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x1188) -+#define AIC_M2D_OTA_VER_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x0010) -+#endif -+///aic bt tx pwr lvl :lsb->msb: first byte, min pwr lvl; second byte, max pwr lvl; -+///pwr lvl:20(min), 30 , 40 , 50 , 60(max) -+#define AICBT_TXPWR_LVL 0x00006020 -+#define AICBT_TXPWR_LVL_8800dc 0x00006f2f -+#define AICBT_TXPWR_LVL_8800d80 0x00006f2f -+ -+#define AICBSP_HWINFO_DEFAULT (-1) -+#define AICBSP_CPMODE_DEFAULT AICBSP_CPMODE_WORK -+#define AICBSP_FWLOG_EN_DEFAULT 0 -+ -+#define AICBT_BTMODE_DEFAULT_8800d80 AICBT_BTMODE_BT_ONLY_COANT -+#define AICBT_BTMODE_DEFAULT AICBT_BTMODE_BT_ONLY_SW -+#ifdef CONFIG_SDIO_BT -+#define AICBT_BTPORT_DEFAULT AICBT_BTPORT_MB -+#else -+#define AICBT_BTPORT_DEFAULT AICBT_BTPORT_UART -+#endif -+#define AICBT_UART_BAUD_DEFAULT AICBT_UART_BAUD_1_5M -+#define AICBT_UART_FC_DEFAULT AICBT_UART_FLOWCTRL_ENABLE -+#define AICBT_LPM_ENABLE_DEFAULT 0 -+#define AICBT_TXPWR_LVL_DEFAULT AICBT_TXPWR_LVL -+#define AICBT_TXPWR_LVL_DEFAULT_8800dc AICBT_TXPWR_LVL_8800dc -+#define AICBT_TXPWR_LVL_DEFAULT_8800d80 AICBT_TXPWR_LVL_8800d80 -+ -+ -+#define FEATURE_SDIO_CLOCK 50000000 // 0: default, other: target clock rate -+#define FEATURE_SDIO_CLOCK_V3 150000000 // 0: default, other: target clock rate -+#define FEATURE_SDIO_PHASE 2 // 0: default, 2: 180° -+ -+struct aicbt_patch_table { -+ char *name; -+ uint32_t type; -+ uint32_t *data; -+ uint32_t len; -+ struct aicbt_patch_table *next; -+}; -+ -+struct aicbt_info_t { -+ uint32_t btmode; -+ uint32_t btport; -+ uint32_t uart_baud; -+ uint32_t uart_flowctrl; -+ uint32_t lpm_enable; -+ uint32_t txpwr_lvl; -+}; -+ -+struct aicbt_patch_info_t { -+ uint32_t info_len; -+ uint32_t adid_addrinf; -+ uint32_t addr_adid; -+ uint32_t patch_addrinf; -+ uint32_t addr_patch; -+ uint32_t reset_addr; -+ uint32_t reset_val; -+ uint32_t adid_flag_addr; -+ uint32_t adid_flag; -+}; -+ -+struct aicbsp_firmware { -+ const char *desc; -+ const char *bt_adid; -+ const char *bt_patch; -+ const char *bt_table; -+ const char *wl_fw; -+}; -+ -+struct aicbsp_info_t { -+ int hwinfo; -+ int hwinfo_r; -+ uint32_t cpmode; -+ uint32_t chip_rev; -+ bool fwlog_en; -+ uint8_t irqf; -+}; -+ -+extern struct aicbsp_info_t aicbsp_info; -+extern struct mutex aicbsp_power_lock; -+extern const struct aicbsp_firmware *aicbsp_firmware_list; -+extern const struct aicbsp_firmware fw_u02[]; -+extern const struct aicbsp_firmware fw_u03[]; -+extern const struct aicbsp_firmware fw_8800dc_u01[]; -+extern const struct aicbsp_firmware fw_8800dc_u02[]; -+extern const struct aicbsp_firmware fw_8800dc_h_u02[]; -+extern const struct aicbsp_firmware fw_8800d80_u01[]; -+extern const struct aicbsp_firmware fw_8800d80_u02[]; -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_export.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_export.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_export.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_export.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,65 @@ -+#ifndef __AIC_BSP_EXPORT_H -+#define __AIC_BSP_EXPORT_H -+ -+enum aicbsp_subsys { -+ AIC_BLUETOOTH, -+ AIC_WIFI, -+}; -+ -+enum aicbsp_pwr_state { -+ AIC_PWR_OFF, -+ AIC_PWR_ON, -+}; -+ -+enum skb_buff_id { -+ AIC_RESV_MEM_TXDATA, -+}; -+ -+struct skb_buff_pool { -+ uint32_t id; -+ uint32_t size; -+ const char *name; -+ uint8_t used; -+ struct sk_buff *skb; -+}; -+ -+struct aicbsp_feature_t { -+ int hwinfo; -+ uint32_t sdio_clock; -+ uint8_t sdio_phase; -+ bool fwlog_en; -+ uint8_t irqf; -+}; -+ -+#ifdef CONFIG_DPD -+typedef struct { -+ uint32_t bit_mask[3]; -+ uint32_t reserved; -+ uint32_t dpd_high[96]; -+ uint32_t dpd_11b[96]; -+ uint32_t dpd_low[96]; -+ uint32_t idac_11b[48]; -+ uint32_t idac_high[48]; -+ uint32_t idac_low[48]; -+ uint32_t loft_res[18]; -+ uint32_t rx_iqim_res[16]; -+} rf_misc_ram_t; -+ -+typedef struct { -+ uint32_t bit_mask[4]; -+ uint32_t dpd_high[96]; -+ uint32_t loft_res[18]; -+} rf_misc_ram_lite_t; -+ -+#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -+#define DPD_RESULT_SIZE_8800DC sizeof(rf_misc_ram_lite_t) -+ -+extern rf_misc_ram_lite_t dpd_res; -+#endif -+ -+int aicbsp_set_subsys(int, int); -+int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path); -+struct sk_buff *aicbsp_resv_mem_alloc_skb(unsigned int length, uint32_t id); -+void aicbsp_resv_mem_kfree_skb(struct sk_buff *skb, uint32_t id); -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_main.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_main.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_main.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_main.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,393 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "aic_bsp_driver.h" -+#include "rwnx_version_gen.h" -+#include "aicwf_txq_prealloc.h" -+ -+ -+#define DRV_DESCRIPTION "AIC BSP" -+#define DRV_COPYRIGHT "Copyright(c) 2015-2020 AICSemi" -+#define DRV_AUTHOR "AICSemi" -+#define DRV_VERS_MOD "1.0" -+ -+int aicwf_dbg_level_bsp = LOGERROR|LOGINFO|LOGDEBUG|LOGTRACE; -+ -+static struct platform_device *aicbsp_pdev; -+ -+const struct aicbsp_firmware *aicbsp_firmware_list = fw_u02; -+ -+const struct aicbsp_firmware fw_u02[] = { -+ [AICBSP_CPMODE_WORK] = { -+ .desc = "normal work mode(sdio u02)", -+ .bt_adid = "fw_adid.bin", -+ .bt_patch = "fw_patch.bin", -+ .bt_table = "fw_patch_table.bin", -+ #ifdef CONFIG_SDIO_BT -+ .wl_fw = "fmacfwbt.bin" -+ #else -+ .wl_fw = "fmacfw.bin" -+ #endif -+ }, -+ [AICBSP_CPMODE_TEST] = { -+ .desc = "rf test mode(sdio u02)", -+ .bt_adid = "fw_adid.bin", -+ .bt_patch = "fw_patch.bin", -+ .bt_table = "fw_patch_table.bin", -+ .wl_fw = "fmacfw_rf.bin" -+ }, -+}; -+ -+const struct aicbsp_firmware fw_u03[] = { -+ [AICBSP_CPMODE_WORK] = { -+ .desc = "normal work mode(sdio u03/u04)", -+ .bt_adid = "fw_adid_u03.bin", -+ .bt_patch = "fw_patch_u03.bin", -+ .bt_table = "fw_patch_table_u03.bin", -+ #ifdef CONFIG_MCU_MESSAGE -+ .wl_fw = "fmacfw_8800m_custmsg.bin" -+ #elif defined(CONFIG_SDIO_BT) -+ .wl_fw = "fmacfwbt.bin" -+ #else -+ .wl_fw = "fmacfw.bin" -+ #endif -+ }, -+ -+ [AICBSP_CPMODE_TEST] = { -+ .desc = "rf test mode(sdio u03/u04)", -+ .bt_adid = "fw_adid_u03.bin", -+ .bt_patch = "fw_patch_u03.bin", -+ .bt_table = "fw_patch_table_u03.bin", -+ .wl_fw = "fmacfw_rf.bin" -+ }, -+}; -+ -+const struct aicbsp_firmware fw_8800dc_u01[] = { -+ [AICBSP_CPMODE_WORK] = { -+ .desc = "normal work mode(sdio u01)", -+ .bt_adid = "fw_adid_8800dc.bin", -+ .bt_patch = "fw_patch_8800dc.bin", -+ .bt_table = "fw_patch_table_8800dc.bin", -+ .wl_fw = "fmacfw_8800dc.bin" -+ }, -+ -+ [AICBSP_CPMODE_TEST] = { -+ .desc = "rf test mode(sdio u01)", -+ .bt_adid = "fw_adid_8800dc.bin", -+ .bt_patch = "fw_patch_8800dc.bin", -+ .bt_table = "fw_patch_table_8800dc.bin", -+ .wl_fw = "fmacfw_rf_8800dc.bin" -+ }, -+}; -+ -+ -+const struct aicbsp_firmware fw_8800dc_u02[] = { -+ [AICBSP_CPMODE_WORK] = { -+ .desc = "normal work mode(8800dc sdio u02)", -+ .bt_adid = "fw_adid_8800dc_u02.bin", -+ .bt_patch = "fw_patch_8800dc_u02.bin", -+ .bt_table = "fw_patch_table_8800dc_u02.bin", -+ .wl_fw = "fmacfw_patch_8800dc_u02.bin" -+ }, -+ -+ [AICBSP_CPMODE_TEST] = { -+ .desc = "rf test mode(8800dc sdio u02)", -+ .bt_adid = "fw_adid_8800dc_u02.bin", -+ .bt_patch = "fw_patch_8800dc_u02.bin", -+ .bt_table = "fw_patch_table_8800dc_u02.bin", -+ .wl_fw = "lmacfw_rf_8800dc.bin" //u01,u02 lmacfw load same bin -+ }, -+}; -+ -+const struct aicbsp_firmware fw_8800dc_h_u02[] = { -+ [AICBSP_CPMODE_WORK] = { -+ .desc = "normal work mode(8800dc_h sdio u02)", -+ .bt_adid = "fw_adid_8800dc_u02h.bin", -+ .bt_patch = "fw_patch_8800dc_u02h.bin", -+ .bt_table = "fw_patch_table_8800dc_u02h.bin", -+ .wl_fw = "fmacfw_patch_8800dc_h_u02.bin" -+ }, -+ -+ [AICBSP_CPMODE_TEST] = { -+ .desc = "rf test mode(8800dc_h sdio u02)", -+ .bt_adid = "fw_adid_8800dc_u02h.bin", -+ .bt_patch = "fw_patch_8800dc_u02h.bin", -+ .bt_table = "fw_patch_table_8800dc_u02h.bin", -+ .wl_fw = "lmacfw_rf_8800dc.bin" //u01,u02 lmacfw load same bin -+ }, -+}; -+ -+ -+const struct aicbsp_firmware fw_8800d80_u01[] = { -+ [AICBSP_CPMODE_WORK] = { -+ .desc = "normal work mode(8800d80 sdio u01)", -+ .bt_adid = "fw_adid_8800d80.bin", -+ .bt_patch = "fw_patch_8800d80.bin", -+ .bt_table = "fw_patch_table_8800d80.bin", -+ .wl_fw = "fmacfw_8800d80.bin" -+ }, -+ -+ [AICBSP_CPMODE_TEST] = { -+ .desc = "rf test mode(8800d80 sdio u01)", -+ .bt_adid = "fw_adid_8800d80.bin", -+ .bt_patch = "fw_patch_8800d80.bin", -+ .bt_table = "fw_patch_table_8800d80.bin", -+ .wl_fw = "lmacfw_rf_8800d80.bin" -+ }, -+}; -+ -+const struct aicbsp_firmware fw_8800d80_u02[] = { -+ [AICBSP_CPMODE_WORK] = { -+ .desc = "normal work mode(8800d80 sdio u02)", -+ .bt_adid = "fw_adid_8800d80_u02.bin", -+ .bt_patch = "fw_patch_8800d80_u02.bin", -+ .bt_table = "fw_patch_table_8800d80_u02.bin", -+ #ifdef CONFIG_SDIO_BT -+ .wl_fw = "fmacfwbt_8800d80_u02.bin" -+ #else -+ .wl_fw = "fmacfw_8800d80_u02.bin" -+ #endif -+ }, -+ -+ [AICBSP_CPMODE_TEST] = { -+ .desc = "rf test mode(8800d80 sdio u02)", -+ .bt_adid = "fw_adid_8800d80_u02.bin", -+ .bt_patch = "fw_patch_8800d80_u02.bin", -+ .bt_table = "fw_patch_table_8800d80_u02.bin", -+ .wl_fw = "lmacfw_rf_8800d80_u02.bin" -+ }, -+}; -+ -+struct aicbsp_info_t aicbsp_info = { -+ .hwinfo_r = AICBSP_HWINFO_DEFAULT, -+ .hwinfo = AICBSP_HWINFO_DEFAULT, -+ .cpmode = AICBSP_CPMODE_DEFAULT, -+ .fwlog_en = AICBSP_FWLOG_EN_DEFAULT, -+#ifdef CONFIG_IRQ_FALL -+ .irqf = 1, -+#else -+ .irqf = 0, -+#endif -+}; -+ -+struct mutex aicbsp_power_lock; -+ -+static struct platform_driver aicbsp_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "aic_bsp", -+ }, -+ //.probe = aicbsp_probe, -+ //.remove = aicbsp_remove, -+}; -+ -+static ssize_t cpmode_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ ssize_t count = 0; -+ uint8_t i = 0; -+ -+ count += sprintf(&buf[count], "Support mode value:\n"); -+ -+ for (i = 0; i < AICBSP_CPMODE_MAX; i++) { -+ if (aicbsp_firmware_list[i].desc) -+ count += sprintf(&buf[count], " %2d: %s\n", i, aicbsp_firmware_list[i].desc); -+ } -+ -+ count += sprintf(&buf[count], "Current: %d, firmware info:\n", aicbsp_info.cpmode); -+ count += sprintf(&buf[count], " BT ADID : %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_adid); -+ count += sprintf(&buf[count], " BT PATCH: %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_patch); -+ count += sprintf(&buf[count], " BT TABLE: %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_table); -+ count += sprintf(&buf[count], " WIFI FW : %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].wl_fw); -+ return count; -+} -+ -+static ssize_t cpmode_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ unsigned long val; -+ int err = kstrtoul(buf, 0, &val); -+ if (err) -+ return err; -+ -+ if (val >= AICBSP_CPMODE_MAX) { -+ pr_err("mode value must less than %d\n", AICBSP_CPMODE_MAX); -+ return -EINVAL; -+ } -+ -+ aicbsp_info.cpmode = val; -+ printk("%s, set mode to: %lu[%s] done\n", __func__, val, aicbsp_firmware_list[val].desc); -+ -+ return count; -+} -+ -+static ssize_t hwinfo_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ ssize_t count = 0; -+ -+ count += sprintf(&buf[count], "chip hw rev: "); -+ if (aicbsp_info.hwinfo_r < 0) -+ count += sprintf(&buf[count], "-1(not avalible)\n"); -+ else -+ count += sprintf(&buf[count], "0x%02X\n", aicbsp_info.chip_rev); -+ -+ count += sprintf(&buf[count], "hwinfo read: "); -+ if (aicbsp_info.hwinfo_r < 0) -+ count += sprintf(&buf[count], "%d(not avalible), ", aicbsp_info.hwinfo_r); -+ else -+ count += sprintf(&buf[count], "0x%02X, ", aicbsp_info.hwinfo_r); -+ -+ if (aicbsp_info.hwinfo < 0) -+ count += sprintf(&buf[count], "set: %d(not avalible)\n", aicbsp_info.hwinfo); -+ else -+ count += sprintf(&buf[count], "set: 0x%02X\n", aicbsp_info.hwinfo); -+ -+ return count; -+} -+ -+static ssize_t hwinfo_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ long val; -+ int err = kstrtol(buf, 0, &val); -+ -+ if (err) { -+ pr_err("invalid input\n"); -+ return err; -+ } -+ -+ if ((val == -1) || (val >= 0 && val <= 0xFF)) { -+ aicbsp_info.hwinfo = val; -+ } else { -+ pr_err("invalid values\n"); -+ return -EINVAL; -+ } -+ return count; -+} -+ -+static ssize_t fwdebug_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ ssize_t count = 0; -+ -+ count += sprintf(&buf[count], "fw log status: %s\n", -+ aicbsp_info.fwlog_en ? "on" : "off"); -+ -+ return count; -+} -+ -+static ssize_t fwdebug_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ long val; -+ int err = kstrtol(buf, 0, &val); -+ -+ if (err) { -+ pr_err("invalid input\n"); -+ return err; -+ } -+ -+ if (val > 1 || val < 0) { -+ pr_err("must be 0 or 1\n"); -+ return -EINVAL; -+ } -+ -+ aicbsp_info.fwlog_en = val; -+ return count; -+} -+ -+static DEVICE_ATTR(cpmode, S_IRUGO | S_IWUSR, -+ cpmode_show, cpmode_store); -+ -+static DEVICE_ATTR(hwinfo, S_IRUGO | S_IWUSR, -+ hwinfo_show, hwinfo_store); -+ -+static DEVICE_ATTR(fwdebug, S_IRUGO | S_IWUSR, -+ fwdebug_show, fwdebug_store); -+ -+static struct attribute *aicbsp_attributes[] = { -+ &dev_attr_cpmode.attr, -+ &dev_attr_hwinfo.attr, -+ &dev_attr_fwdebug.attr, -+ NULL, -+}; -+ -+static struct attribute_group aicbsp_attribute_group = { -+ .name = "aicbsp_info", -+ .attrs = aicbsp_attributes, -+}; -+ -+int testmode = AICBSP_CPMODE_DEFAULT; -+int adap_test = 0; -+module_param(testmode, int, 0660); -+module_param(adap_test, int, 0660); -+ -+ -+static int __init aicbsp_init(void) -+{ -+ int ret; -+ printk("%s\n", __func__); -+ printk("RELEASE_DATE:%s\r\n", RELEASE_DATE); -+ -+ aicbsp_info.cpmode = testmode; -+ -+ aicbsp_resv_mem_init(); -+ ret = platform_driver_register(&aicbsp_driver); -+ if (ret) { -+ pr_err("register platform driver failed: %d\n", ret); -+ return ret; -+ } -+ -+ aicbsp_pdev = platform_device_alloc("aic-bsp", -1); -+ ret = platform_device_add(aicbsp_pdev); -+ if (ret) { -+ pr_err("register platform device failed: %d\n", ret); -+ return ret; -+ } -+ -+ ret = sysfs_create_group(&(aicbsp_pdev->dev.kobj), &aicbsp_attribute_group); -+ if (ret) { -+ pr_err("register sysfs create group failed!\n"); -+ return ret; -+ } -+ -+ mutex_init(&aicbsp_power_lock); -+#if defined CONFIG_PLATFORM_ROCKCHIP || defined CONFIG_PLATFORM_ROCKCHIP2 -+ aicbsp_set_subsys(AIC_BLUETOOTH, AIC_PWR_ON); -+#endif -+ return 0; -+} -+ -+void aicbsp_sdio_exit(void); -+extern struct aic_sdio_dev *aicbsp_sdiodev; -+ -+static void __exit aicbsp_exit(void) -+{ -+#if defined CONFIG_PLATFORM_ROCKCHIP || defined CONFIG_PLATFORM_ROCKCHIP2 -+ if(aicbsp_sdiodev){ -+ aicbsp_sdio_exit(); -+ } -+#endif -+ sysfs_remove_group(&(aicbsp_pdev->dev.kobj), &aicbsp_attribute_group); -+ platform_device_del(aicbsp_pdev); -+ platform_driver_unregister(&aicbsp_driver); -+ mutex_destroy(&aicbsp_power_lock); -+ aicbsp_resv_mem_deinit(); -+#ifdef CONFIG_PREALLOC_TXQ -+ aicwf_prealloc_txq_free(); -+#endif -+ printk("%s\n", __func__); -+} -+ -+module_init(aicbsp_init); -+module_exit(aicbsp_exit); -+ -+MODULE_DESCRIPTION(DRV_DESCRIPTION); -+MODULE_VERSION(DRV_VERS_MOD); -+MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); -+MODULE_LICENSE("GPL"); -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,1980 @@ -+/** -+ * aicwf_sdmmc.c -+ * -+ * SDIO function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "aicsdio_txrxif.h" -+#include "aicsdio.h" -+#include "aic_bsp_driver.h" -+#include -+#include -+#ifdef CONFIG_PLATFORM_ROCKCHIP -+#include -+#endif /* CONFIG_PLATFORM_ROCKCHIP */ -+#ifdef CONFIG_PLATFORM_ROCKCHIP2 -+#include -+#endif /* CONFIG_PLATFORM_ROCKCHIP */ -+ -+ -+#ifdef CONFIG_PLATFORM_ALLWINNER -+extern void sunxi_mmc_rescan_card(unsigned ids); -+extern void sunxi_wlan_set_power(int on); -+extern int sunxi_wlan_get_bus_index(void); -+static int aicbsp_bus_index = -1; -+#endif -+ -+#ifdef CONFIG_PLATFORM_AMLOGIC//for AML -+#include -+extern void sdio_reinit(void); -+extern void extern_wifi_set_enable(int is_on); -+extern void set_power_control_lock(int lock); -+#endif//for AML -+ -+ -+static int aicbsp_platform_power_on(void); -+static void aicbsp_platform_power_off(void); -+ -+struct aic_sdio_dev *aicbsp_sdiodev = NULL; -+static struct semaphore *aicbsp_notify_semaphore; -+static struct semaphore *aicbsp_probe_semaphore; -+ -+static const struct sdio_device_id aicbsp_sdmmc_ids[]; -+static bool aicbsp_load_fw_in_fdrv = false; -+ -+#define FW_PATH_MAX 200 -+ -+//#ifdef CONFIG_PLATFORM_UBUNTU -+//static const char* aic_default_fw_path = "/lib/firmware/aic8800_sdio"; -+//#else -+static const char* aic_default_fw_path = CONFIG_AIC_FW_PATH; -+//#endif -+char aic_fw_path[FW_PATH_MAX]; -+module_param_string(aic_fw_path, aic_fw_path, FW_PATH_MAX, 0660); -+#ifdef CONFIG_M2D_OTA_AUTO_SUPPORT -+char saved_sdk_ver[64]; -+module_param_string(saved_sdk_ver, saved_sdk_ver,64, 0660); -+#endif -+ -+extern int testmode; -+ -+ -+#define SDIO_DEVICE_ID_AIC8801_FUNC2 0x0146 -+#define SDIO_DEVICE_ID_AIC8800D80_FUNC2 0x0182 -+ -+/* SDIO Device ID */ -+#define SDIO_VENDOR_ID_AIC8801 0x5449 -+#define SDIO_VENDOR_ID_AIC8800DC 0xc8a1 -+#define SDIO_VENDOR_ID_AIC8800D80 0xc8a1 -+ -+#define SDIO_DEVICE_ID_AIC8801 0x0145 -+#define SDIO_DEVICE_ID_AIC8800DC 0xc08d -+#define SDIO_DEVICE_ID_AIC8800D80 0x0082 -+ -+ -+static int aicbsp_dummy_probe(struct sdio_func *func, const struct sdio_device_id *id) -+{ -+ if (func && (func->num != 2)) -+ return 0; -+ -+ if(func->vendor != SDIO_VENDOR_ID_AIC8801 && -+ func->device != SDIO_DEVICE_ID_AIC8801 && -+ func->device != SDIO_DEVICE_ID_AIC8801_FUNC2 && -+ func->vendor != SDIO_VENDOR_ID_AIC8800DC && -+ func->device != SDIO_DEVICE_ID_AIC8800DC && -+ func->vendor != SDIO_VENDOR_ID_AIC8800D80 && -+ func->device != SDIO_DEVICE_ID_AIC8800D80 && -+ func->device != SDIO_DEVICE_ID_AIC8800D80_FUNC2){ -+ printk("VID:%x DID:%X \r\n", func->vendor, func->device); -+ aicbsp_load_fw_in_fdrv = true; -+ } -+ -+ if (aicbsp_notify_semaphore) -+ up(aicbsp_notify_semaphore); -+ return 0; -+} -+ -+static void aicbsp_dummy_remove(struct sdio_func *func) -+{ -+} -+ -+static struct sdio_driver aicbsp_dummy_sdmmc_driver = { -+ .probe = aicbsp_dummy_probe, -+ .remove = aicbsp_dummy_remove, -+ .name = "aicbsp_dummy_sdmmc", -+ .id_table = aicbsp_sdmmc_ids, -+}; -+ -+static int aicbsp_reg_sdio_notify(void *semaphore) -+{ -+ aicbsp_notify_semaphore = semaphore; -+ return sdio_register_driver(&aicbsp_dummy_sdmmc_driver); -+} -+ -+static void aicbsp_unreg_sdio_notify(void) -+{ -+ mdelay(15); -+ sdio_unregister_driver(&aicbsp_dummy_sdmmc_driver); -+} -+ -+static const char *aicbsp_subsys_name(int subsys) -+{ -+ switch (subsys) { -+ case AIC_BLUETOOTH: -+ return "AIC_BLUETOOTH"; -+ case AIC_WIFI: -+ return "AIC_WIFI"; -+ default: -+ return "unknown subsys"; -+ } -+} -+ -+#ifdef CONFIG_PLATFORM_ROCKCHIP -+#if 1//FOR RK SUSPEND -+void rfkill_rk_sleep_bt(bool sleep); -+#endif -+#endif -+ -+#ifdef CONFIG_PLATFORM_ROCKCHIP2 -+#if 1//FOR RK SUSPEND -+void rfkill_rk_sleep_bt(bool sleep); -+#endif -+#endif -+ -+int aicbsp_set_subsys(int subsys, int state) -+{ -+ static int pre_power_map; -+ int cur_power_map; -+ int pre_power_state; -+ int cur_power_state; -+ -+ mutex_lock(&aicbsp_power_lock); -+ aicbsp_load_fw_in_fdrv = false; -+ cur_power_map = pre_power_map; -+ if (state) -+ cur_power_map |= (1 << subsys); -+ else -+ cur_power_map &= ~(1 << subsys); -+ -+ pre_power_state = pre_power_map > 0; -+ cur_power_state = cur_power_map > 0; -+ -+ sdio_dbg("%s, subsys: %s, state to: %d\n", __func__, aicbsp_subsys_name(subsys), state); -+ -+ if (cur_power_state != pre_power_state) { -+ sdio_dbg("%s, power state change to %d dure to %s\n", __func__, cur_power_state, aicbsp_subsys_name(subsys)); -+ if (cur_power_state) { -+ if (aicbsp_platform_power_on() < 0) -+ goto err0; -+ if (aicbsp_sdio_init()) -+ goto err1; -+ if (aicbsp_driver_fw_init(aicbsp_sdiodev)) -+ goto err2; -+#ifndef CONFIG_FDRV_NO_REG_SDIO -+ aicbsp_sdio_release(aicbsp_sdiodev); -+#endif -+ -+#if defined CONFIG_PLATFORM_ROCKCHIP || defined CONFIG_PLATFORM_ROCKCHIP2 -+#ifdef CONFIG_GPIO_WAKEUP -+ //BT_SLEEP:true,BT_WAKEUP:false -+ rfkill_rk_sleep_bt(true); -+ printk("%s BT wake default to SLEEP\r\n", __func__); -+#endif -+#endif -+ -+//#ifndef CONFIG_PLATFORM_ROCKCHIP -+// aicbsp_sdio_exit(); -+//#endif -+ } else { -+ #ifndef CONFIG_PLATFORM_ROCKCHIP -+ aicbsp_sdio_exit(); -+ #endif -+ aicbsp_platform_power_off(); -+ } -+ } else { -+ sdio_dbg("%s, power state no need to change, current: %d\n", __func__, cur_power_state); -+ } -+ pre_power_map = cur_power_map; -+ mutex_unlock(&aicbsp_power_lock); -+ -+ return cur_power_state; -+ -+err2: -+ aicbsp_sdio_release(aicbsp_sdiodev); -+ aicbsp_sdio_exit(); -+ -+err1: -+ aicbsp_platform_power_off(); -+ -+err0: -+ sdio_dbg("%s, fail to set %s power state to %d\n", __func__, aicbsp_subsys_name(subsys), state); -+ mutex_unlock(&aicbsp_power_lock); -+ return -1; -+} -+EXPORT_SYMBOL_GPL(aicbsp_set_subsys); -+ -+bool aicbsp_get_load_fw_in_fdrv(void){ -+ return aicbsp_load_fw_in_fdrv; -+} -+ -+EXPORT_SYMBOL_GPL(aicbsp_get_load_fw_in_fdrv); -+ -+static int aicwf_sdio_chipmatch(struct aic_sdio_dev *sdio_dev, uint16_t vid, uint16_t did){ -+ -+ if(vid == SDIO_VENDOR_ID_AIC8801 && did == SDIO_DEVICE_ID_AIC8801){ -+ sdio_dev->chipid = PRODUCT_ID_AIC8801; -+ AICWFDBG(LOGINFO, "%s USE AIC8801\r\n", __func__); -+ return 0; -+ }else if(vid == SDIO_VENDOR_ID_AIC8800DC && did == SDIO_DEVICE_ID_AIC8800DC){ -+ sdio_dev->chipid = PRODUCT_ID_AIC8800DC; -+ AICWFDBG(LOGINFO, "%s USE AIC8800DC\r\n", __func__); -+ return 0; -+ }else if(vid == SDIO_VENDOR_ID_AIC8800D80 && did == SDIO_DEVICE_ID_AIC8800D80){ -+ sdio_dev->chipid = PRODUCT_ID_AIC8800D80; -+ AICWFDBG(LOGINFO, "%s USE AIC8800D80\r\n", __func__); -+ return 0; -+ }else{ -+ return -1; -+ } -+} -+ -+void *aicbsp_get_drvdata(void *args) -+{ -+ (void)args; -+ if (aicbsp_sdiodev) -+ return aicbsp_sdiodev->bus_if; -+ return dev_get_drvdata((const struct device *)args); -+} -+ -+ -+static int aicbsp_sdio_probe(struct sdio_func *func, -+ const struct sdio_device_id *id) -+{ -+ struct mmc_host *host; -+ struct aic_sdio_dev *sdiodev; -+ struct aicwf_bus *bus_if; -+ int err = -ENODEV; -+ -+ sdio_dbg("%s:%d vid:0x%04X did:0x%04X\n", __func__, func->num, -+ func->vendor, func->device); -+ -+ if(func->vendor != SDIO_VENDOR_ID_AIC8801 && -+ func->device != SDIO_DEVICE_ID_AIC8801 && -+ func->device != SDIO_DEVICE_ID_AIC8801_FUNC2 && -+ func->vendor != SDIO_VENDOR_ID_AIC8800DC && -+ func->device != SDIO_DEVICE_ID_AIC8800DC && -+ func->vendor != SDIO_VENDOR_ID_AIC8800D80 && -+ func->device != SDIO_DEVICE_ID_AIC8800D80 && -+ func->device != SDIO_DEVICE_ID_AIC8800D80_FUNC2){ -+ aicbsp_load_fw_in_fdrv = true; -+ return err; -+ } -+ -+ if (func->num != 2) { -+ return err; -+ } -+ -+ func = func->card->sdio_func[1 - 1]; //replace 2 with 1 -+ host = func->card->host; -+ sdio_dbg("%s after replace:%d\n", __func__, func->num); -+ -+ bus_if = kzalloc(sizeof(struct aicwf_bus), GFP_KERNEL); -+ if (!bus_if) { -+ sdio_err("alloc bus fail\n"); -+ return -ENOMEM; -+ } -+ -+ -+ sdiodev = kzalloc(sizeof(struct aic_sdio_dev), GFP_KERNEL); -+ if (!sdiodev) { -+ sdio_err("alloc sdiodev fail\n"); -+ kfree(bus_if); -+ return -ENOMEM; -+ } -+ aicbsp_sdiodev = sdiodev; -+ -+ err = aicwf_sdio_chipmatch(sdiodev, func->vendor, func->device); -+ -+ sdiodev->func = func; -+ if(sdiodev->chipid == PRODUCT_ID_AIC8800DC || sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ sdiodev->func_msg = func->card->sdio_func[1]; -+ } -+ sdiodev->bus_if = bus_if; -+ bus_if->bus_priv.sdio = sdiodev; -+ if(sdiodev->chipid == PRODUCT_ID_AIC8800DC || sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ dev_set_drvdata(&sdiodev->func_msg->dev, bus_if); -+ printk("the device is PRODUCT_ID_AIC8800DC \n"); -+ } -+ dev_set_drvdata(&func->dev, bus_if); -+ sdiodev->dev = &func->dev; -+ -+ if (sdiodev->chipid != PRODUCT_ID_AIC8800D80) { -+ err = aicwf_sdio_func_init(sdiodev); -+ } else { -+ err = aicwf_sdiov3_func_init(sdiodev); -+ } -+ if (err < 0) { -+ sdio_err("sdio func init fail\n"); -+ goto fail; -+ } -+ -+ if (aicwf_sdio_bus_init(sdiodev) == NULL) { -+ sdio_err("sdio bus init err\r\n"); -+ goto fail; -+ } -+ host->caps |= MMC_CAP_NONREMOVABLE; -+ aicbsp_platform_init(sdiodev); -+ -+ up(aicbsp_probe_semaphore); -+ -+ return 0; -+fail: -+ aicwf_sdio_func_deinit(sdiodev); -+ dev_set_drvdata(&func->dev, NULL); -+ kfree(sdiodev); -+ kfree(bus_if); -+ return err; -+} -+ -+static void aicbsp_sdio_remove(struct sdio_func *func) -+{ -+ struct mmc_host *host; -+ struct aicwf_bus *bus_if = NULL; -+ struct aic_sdio_dev *sdiodev = NULL; -+ -+ sdio_dbg("%s\n", __func__); -+ if (aicbsp_sdiodev == NULL) { -+ sdio_dbg("%s: allready unregister\n", __func__); -+ return; -+ } -+ -+ bus_if = aicbsp_get_drvdata(&func->dev); -+ -+ if (!bus_if) { -+ AICWFDBG(LOGERROR, "%s bus_if is NULL \r\n", __func__); -+ return; -+ } -+ -+ func = aicbsp_sdiodev->func; -+ host = func->card->host; -+ host->caps &= ~MMC_CAP_NONREMOVABLE; -+ -+ sdiodev = bus_if->bus_priv.sdio; -+ if (!sdiodev) { -+ AICWFDBG(LOGERROR, "%s sdiodev is NULL \r\n", __func__); -+ return; -+ } -+ -+ aicwf_sdio_release(sdiodev); -+ aicwf_sdio_func_deinit(sdiodev); -+ -+ dev_set_drvdata(&sdiodev->func->dev, NULL); -+ kfree(sdiodev); -+ kfree(bus_if); -+ aicbsp_sdiodev = NULL; -+ sdio_dbg("%s done\n", __func__); -+} -+ -+static int aicbsp_sdio_suspend(struct device *dev) -+{ -+ struct sdio_func *func = dev_to_sdio_func(dev); -+ int err; -+ mmc_pm_flag_t sdio_flags; -+ -+#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2) -+#ifdef CONFIG_GPIO_WAKEUP -+ //BT_SLEEP:true,BT_WAKEUP:false -+ rfkill_rk_sleep_bt(false); -+#endif -+#endif -+ -+ sdio_dbg("%s, func->num = %d\n", __func__, func->num); -+ if (func->num != 2) -+ return 0; -+ -+ sdio_flags = sdio_get_host_pm_caps(func); -+ if (!(sdio_flags & MMC_PM_KEEP_POWER)) { -+ sdio_dbg("%s: can't keep power while host is suspended\n", __func__); -+ return -EINVAL; -+ } -+ -+ /* keep power while host suspended */ -+ err = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); -+ if (err) { -+ sdio_dbg("%s: error while trying to keep power\n", __func__); -+ return err; -+ } -+ -+#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2) -+#ifdef CONFIG_GPIO_WAKEUP -+ //BT_SLEEP:true,BT_WAKEUP:false -+ rfkill_rk_sleep_bt(true); -+ printk("%s BT wake to SLEEP\r\n", __func__); -+#endif -+#endif -+ -+ return 0; -+} -+ -+static int aicbsp_sdio_resume(struct device *dev) -+{ -+ sdio_dbg("%s\n", __func__); -+ -+#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2) -+#ifdef CONFIG_GPIO_WAKEUP -+ //BT_SLEEP:true,BT_WAKEUP:false -+ rfkill_rk_sleep_bt(false); -+#endif -+#endif -+ -+ return 0; -+} -+ -+static const struct sdio_device_id aicbsp_sdmmc_ids[] = { -+ {SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN)}, -+ { }, -+}; -+ -+MODULE_DEVICE_TABLE(sdio, aicbsp_sdmmc_ids); -+ -+static const struct dev_pm_ops aicbsp_sdio_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(aicbsp_sdio_suspend, aicbsp_sdio_resume) -+}; -+ -+static struct sdio_driver aicbsp_sdio_driver = { -+ .probe = aicbsp_sdio_probe, -+ .remove = aicbsp_sdio_remove, -+ .name = AICBSP_SDIO_NAME, -+ .id_table = aicbsp_sdmmc_ids, -+ .drv = { -+ .pm = &aicbsp_sdio_pm_ops, -+ }, -+}; -+ -+static int aicbsp_platform_power_on(void) -+{ -+ int ret = 0; -+ struct semaphore aic_chipup_sem; -+ sdio_dbg("%s\n", __func__); -+ -+#ifdef CONFIG_PLATFORM_ALLWINNER -+ if (aicbsp_bus_index < 0) -+ aicbsp_bus_index = sunxi_wlan_get_bus_index(); -+ if (aicbsp_bus_index < 0) -+ return aicbsp_bus_index; -+#endif //CONFIG_PLATFORM_ALLWINNER -+ -+#ifdef CONFIG_PLATFORM_AMLOGIC -+ extern_wifi_set_enable(0); -+ mdelay(200); -+ extern_wifi_set_enable(1); -+ mdelay(200); -+ sdio_reinit(); -+ set_power_control_lock(1); -+#endif -+ -+#ifdef CONFIG_PLATFORM_ROCKCHIP2 -+ rockchip_wifi_power(0); -+ mdelay(50); -+ rockchip_wifi_power(1); -+ mdelay(50); -+ rockchip_wifi_set_carddetect(1); -+#endif /*CONFIG_PLATFORM_ROCKCHIP2*/ -+ -+ sema_init(&aic_chipup_sem, 0); -+ ret = aicbsp_reg_sdio_notify(&aic_chipup_sem); -+ if (ret) { -+ sdio_dbg("%s aicbsp_reg_sdio_notify fail(%d)\n", __func__, ret); -+ return ret; -+ } -+ -+#ifdef CONFIG_PLATFORM_ALLWINNER -+ sunxi_wlan_set_power(0); -+ mdelay(50); -+ sunxi_wlan_set_power(1); -+ mdelay(50); -+ sunxi_mmc_rescan_card(aicbsp_bus_index); -+#endif //CONFIG_PLATFORM_ALLWINNER -+ -+ if (down_timeout(&aic_chipup_sem, msecs_to_jiffies(2000)) == 0) { -+ aicbsp_unreg_sdio_notify(); -+ if(aicbsp_load_fw_in_fdrv){ -+ printk("%s load fw in fdrv\r\n", __func__); -+ return -1; -+ } -+ return 0; -+ } -+ -+ aicbsp_unreg_sdio_notify(); -+#ifdef CONFIG_PLATFORM_ALLWINNER -+ sunxi_wlan_set_power(0); -+#endif //CONFIG_PLATFORM_ALLWINNER -+ -+#ifdef CONFIG_PLATFORM_AMLOGIC -+ extern_wifi_set_enable(0); -+#endif -+ -+ -+#ifdef CONFIG_PLATFORM_ROCKCHIP2 -+ rockchip_wifi_power(0); -+#endif /*CONFIG_PLATFORM_ROCKCHIP2*/ -+ -+ return -1; -+} -+ -+static void aicbsp_platform_power_off(void) -+{ -+//TODO wifi disable and sdio card detection -+#ifdef CONFIG_PLATFORM_ALLWINNER -+ if (aicbsp_bus_index < 0) -+ aicbsp_bus_index = sunxi_wlan_get_bus_index(); -+ if (aicbsp_bus_index < 0) { -+ sdio_dbg("no aicbsp_bus_index\n"); -+ return; -+ } -+ sunxi_wlan_set_power(0); -+ mdelay(100); -+ sunxi_mmc_rescan_card(aicbsp_bus_index); -+#endif //CONFIG_PLATFORM_ALLWINNER -+ -+#ifdef CONFIG_PLATFORM_ROCKCHIP2 -+ rockchip_wifi_set_carddetect(0); -+ mdelay(200); -+ rockchip_wifi_power(0); -+ mdelay(200); -+#endif /*CONFIG_PLATFORM_ROCKCHIP*/ -+#ifdef CONFIG_PLATFORM_AMLOGIC -+ extern_wifi_set_enable(0); -+#endif -+ -+ -+ sdio_dbg("%s\n", __func__); -+} -+ -+ -+int aicbsp_sdio_init(void) -+{ -+ struct semaphore aic_chipup_sem; -+ -+ sema_init(&aic_chipup_sem, 0); -+ aicbsp_probe_semaphore = &aic_chipup_sem; -+ -+ if (sdio_register_driver(&aicbsp_sdio_driver)) { -+ return -1; -+ } else { -+ //may add mmc_rescan here -+ } -+ if (down_timeout(aicbsp_probe_semaphore, msecs_to_jiffies(2000)) != 0){ -+ printk("%s aicbsp_sdio_probe fail\r\n", __func__); -+ return -1; -+ } -+ -+ -+ return 0; -+} -+ -+void aicbsp_sdio_exit(void) -+{ -+ sdio_unregister_driver(&aicbsp_sdio_driver); -+} -+ -+void aicbsp_sdio_release(struct aic_sdio_dev *sdiodev) -+{ -+ sdiodev->bus_if->state = BUS_DOWN_ST; -+ sdio_claim_host(sdiodev->func); -+ sdio_release_irq(sdiodev->func); -+ sdio_release_host(sdiodev->func); -+ if(sdiodev->chipid == PRODUCT_ID_AIC8800DC || sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ sdio_claim_host(sdiodev->func_msg); -+ sdio_release_irq(sdiodev->func_msg); -+ sdio_release_host(sdiodev->func_msg); -+ } -+} -+ -+int aicwf_sdio_readb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 *val) -+{ -+ int ret; -+ sdio_claim_host(sdiodev->func); -+ *val = sdio_readb(sdiodev->func, regaddr, &ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+} -+ -+int aicwf_sdio_readb_func2(struct aic_sdio_dev *sdiodev, uint regaddr, u8 *val) -+{ -+ int ret; -+ sdio_claim_host(sdiodev->func_msg); -+ *val = sdio_readb(sdiodev->func_msg, regaddr, &ret); -+ sdio_release_host(sdiodev->func_msg); -+ return ret; -+} -+ -+int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val) -+{ -+ int ret; -+ sdio_claim_host(sdiodev->func); -+ sdio_writeb(sdiodev->func, val, regaddr, &ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+} -+ -+int aicwf_sdio_writeb_func2(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val) -+{ -+ int ret; -+ sdio_claim_host(sdiodev->func_msg); -+ sdio_writeb(sdiodev->func_msg, val, regaddr, &ret); -+ sdio_release_host(sdiodev->func_msg); -+ return ret; -+} -+ -+int aicwf_sdio_flow_ctrl(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = -1; -+ u8 fc_reg = 0; -+ u32 count = 0; -+ -+ while (true) { -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.flow_ctrl_reg, &fc_reg); -+ if (ret) { -+ return -1; -+ } -+ -+ if (sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ fc_reg = fc_reg & SDIOWIFI_FLOWCTRL_MASK_REG; -+ } -+ -+ if (fc_reg != 0) { -+ ret = fc_reg; -+ return ret; -+ } else { -+ if (count >= FLOW_CTRL_RETRY_COUNT) { -+ ret = -fc_reg; -+ break; -+ } -+ count++; -+ if (count < 30) -+ udelay(200); -+ else if (count < 40) -+ mdelay(1); -+ else -+ mdelay(10); -+ } -+ } -+ -+ return ret; -+} -+ -+int aicwf_sdio_send_msg(struct aic_sdio_dev *sdiodev, u8 *buf, uint count) -+{ -+ int ret = 0; -+ -+ sdio_claim_host(sdiodev->func_msg); -+ ret = sdio_writesb(sdiodev->func_msg, 7, buf, count); -+ sdio_release_host(sdiodev->func_msg); -+ -+ return ret; -+} -+ -+int aicwf_sdio_send_pkt(struct aic_sdio_dev *sdiodev, u8 *buf, uint count) -+{ -+ int ret = 0; -+ -+ sdio_claim_host(sdiodev->func); -+ ret = sdio_writesb(sdiodev->func, sdiodev->sdio_reg.wr_fifo_addr, buf, count); -+ sdio_release_host(sdiodev->func); -+ -+ return ret; -+} -+ -+int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct sk_buff *skbbuf, -+ u32 size, u8 msg) -+{ -+ int ret; -+ -+ if ((!skbbuf) || (!size)) { -+ return -EINVAL;; -+ } -+ -+ if(!msg) { -+ sdio_claim_host(sdiodev->func); -+ ret = sdio_readsb(sdiodev->func, skbbuf->data, sdiodev->sdio_reg.rd_fifo_addr, size); -+ sdio_release_host(sdiodev->func); -+ } else { -+ sdio_claim_host(sdiodev->func_msg); -+ ret = sdio_readsb(sdiodev->func_msg, skbbuf->data, sdiodev->sdio_reg.rd_fifo_addr, size); -+ sdio_release_host(sdiodev->func_msg); -+ } -+ -+ -+ if (ret < 0) { -+ return ret; -+ } -+ skbbuf->len = size; -+ -+ return ret; -+} -+ -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+int aicwf_sdio_wakeup(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ int read_retry; -+ int write_retry = 20; -+ int wakeup_reg_val = 0; -+ -+ if (sdiodev->chipid == PRODUCT_ID_AIC8801 || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ wakeup_reg_val = 1; -+ } else if (sdiodev->chipid == PRODUCT_ID_AIC8800D80) { -+ wakeup_reg_val = 0x11; -+ } -+ -+ if (sdiodev->state == SDIO_SLEEP_ST) { -+ //if (sdiodev->rwnx_hw->vif_started) { -+ down(&sdiodev->pwrctl_wakeup_sema); -+ while (write_retry) { -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.wakeup_reg, wakeup_reg_val); -+ if (ret) { -+ txrx_err("sdio wakeup fail\n"); -+ ret = -1; -+ } else { -+ read_retry = 10; -+ while (read_retry) { -+ u8 val; -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.sleep_reg, &val); -+ if ((ret == 0) && (val & 0x10)) { -+ break; -+ } -+ read_retry--; -+ udelay(200); -+ } -+ if (read_retry != 0) -+ break; -+ } -+ sdio_dbg("write retry: %d \n", write_retry); -+ write_retry--; -+ udelay(100); -+ } -+ up(&sdiodev->pwrctl_wakeup_sema); -+ // } -+ } -+ -+ sdiodev->state = SDIO_ACTIVE_ST; -+ aicwf_sdio_pwrctl_timer(sdiodev, sdiodev->active_duration); -+ -+ return ret; -+} -+ -+extern u8 dhcped; -+int aicwf_sdio_sleep_allow(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ struct aicwf_bus *bus_if = sdiodev->bus_if; -+ -+ if (bus_if->state == BUS_DOWN_ST) { -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.sleep_reg, 0x10); -+ if (ret) { -+ sdio_err("Write sleep fail!\n"); -+ } -+ aicwf_sdio_pwrctl_timer(sdiodev, 0); -+ return ret; -+ } -+ -+ if (sdiodev->state == SDIO_ACTIVE_ST) { -+ { -+ sdio_dbg("s\n"); -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.sleep_reg, 0x10); -+ if (ret) -+ sdio_err("Write sleep fail!\n"); -+ } -+ sdiodev->state = SDIO_SLEEP_ST; -+ aicwf_sdio_pwrctl_timer(sdiodev, 0); -+ } else { -+ aicwf_sdio_pwrctl_timer(sdiodev, sdiodev->active_duration); -+ } -+ -+ return ret; -+} -+ -+int aicwf_sdio_pwr_stctl(struct aic_sdio_dev *sdiodev, uint target) -+{ -+ int ret = 0; -+ -+ if (sdiodev->bus_if->state == BUS_DOWN_ST) { -+ return -1; -+ } -+ -+ if (sdiodev->state == target) { -+ if (target == SDIO_ACTIVE_ST) { -+ aicwf_sdio_pwrctl_timer(sdiodev, sdiodev->active_duration); -+ } -+ return ret; -+ } -+ -+ switch (target) { -+ case SDIO_ACTIVE_ST: -+ aicwf_sdio_wakeup(sdiodev); -+ break; -+ case SDIO_SLEEP_ST: -+ aicwf_sdio_sleep_allow(sdiodev); -+ break; -+ } -+ -+ return ret; -+} -+#endif -+ -+int aicwf_sdio_txpkt(struct aic_sdio_dev *sdiodev, struct sk_buff *pkt) -+{ -+ int ret = 0; -+ u8 *frame; -+ u32 len = 0; -+ struct aicwf_bus *bus_if = dev_get_drvdata(sdiodev->dev); -+ -+ if (bus_if->state == BUS_DOWN_ST) { -+ sdio_dbg("tx bus is down!\n"); -+ return -EINVAL; -+ } -+ -+ frame = (u8 *) (pkt->data); -+ len = pkt->len; -+ len = (len + SDIOWIFI_FUNC_BLOCKSIZE - 1) / SDIOWIFI_FUNC_BLOCKSIZE * SDIOWIFI_FUNC_BLOCKSIZE; -+ ret = aicwf_sdio_send_pkt(sdiodev, pkt->data, len); -+ if (ret) -+ sdio_err("aicwf_sdio_send_pkt fail%d\n", ret); -+ -+ return ret; -+} -+ -+static int aicwf_sdio_intr_get_len_bytemode(struct aic_sdio_dev *sdiodev, u8 *byte_len) -+{ -+ int ret = 0; -+ -+ if (!byte_len) -+ return -EBADE; -+ -+ if (sdiodev->bus_if->state == BUS_DOWN_ST) { -+ *byte_len = 0; -+ } else { -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.bytemode_len_reg, byte_len); -+ sdiodev->rx_priv->data_len = (*byte_len)*4; -+ } -+ -+ return ret; -+} -+ -+static void aicwf_sdio_bus_stop(struct device *dev) -+{ -+ struct aicwf_bus *bus_if = aicbsp_get_drvdata(dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ int ret; -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwrctl_timer(sdiodev, 0); -+ sdio_dbg("%s\n", __func__); -+ if (sdiodev->pwrctl_tsk) { -+ complete_all(&sdiodev->pwrctrl_trgg); -+ kthread_stop(sdiodev->pwrctl_tsk); -+ sdiodev->pwrctl_tsk = NULL; -+ } -+#endif -+ bus_if->state = BUS_DOWN_ST; -+ ret = down_interruptible(&sdiodev->tx_priv->txctl_sema); -+ if (ret) -+ sdio_err("down txctl_sema fail\n"); -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwr_stctl(sdiodev, SDIO_SLEEP_ST); -+#endif -+ if (!ret) -+ up(&sdiodev->tx_priv->txctl_sema); -+ aicwf_frame_queue_flush(&sdiodev->tx_priv->txq); -+} -+ -+struct sk_buff *aicwf_sdio_readframes(struct aic_sdio_dev *sdiodev, u8 msg) -+{ -+ int ret = 0; -+ u32 size = 0; -+ struct sk_buff *skb = NULL; -+ struct aicwf_bus *bus_if = dev_get_drvdata(sdiodev->dev); -+ -+ if (bus_if->state == BUS_DOWN_ST) { -+ sdio_dbg("bus down\n"); -+ return NULL; -+ } -+ -+ size = sdiodev->rx_priv->data_len; -+ skb = __dev_alloc_skb(size, GFP_KERNEL); -+ if (!skb) { -+ return NULL; -+ } -+ -+ ret = aicwf_sdio_recv_pkt(sdiodev, skb, size, msg); -+ if (ret) { -+ dev_kfree_skb(skb); -+ skb = NULL; -+ } -+ -+ return skb; -+} -+ -+static int aicwf_sdio_tx_msg(struct aic_sdio_dev *sdiodev) -+{ -+ int err = 0; -+ u16 len; -+ u8 *payload = sdiodev->tx_priv->cmd_buf; -+ u16 payload_len = sdiodev->tx_priv->cmd_len; -+ u8 adjust_str[4] = {0, 0, 0, 0}; -+ int adjust_len = 0; -+ int buffer_cnt = 0; -+ u8 retry = 0; -+ -+ len = payload_len; -+ if ((len % TX_ALIGNMENT) != 0) { -+ adjust_len = roundup(len, TX_ALIGNMENT); -+ memcpy(payload+payload_len, adjust_str, (adjust_len - len)); -+ payload_len += (adjust_len - len); -+ } -+ len = payload_len; -+ -+ //link tail is necessary -+ if ((len % SDIOWIFI_FUNC_BLOCKSIZE) != 0) { -+ memset(payload+payload_len, 0, TAIL_LEN); -+ payload_len += TAIL_LEN; -+ len = (payload_len/SDIOWIFI_FUNC_BLOCKSIZE + 1) * SDIOWIFI_FUNC_BLOCKSIZE; -+ } else -+ len = payload_len; -+ -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ buffer_cnt = aicwf_sdio_flow_ctrl(sdiodev); -+ while ((buffer_cnt <= 0 || (buffer_cnt > 0 && len > (buffer_cnt * BUFFER_SIZE))) && retry < 10) { -+ retry++; -+ buffer_cnt = aicwf_sdio_flow_ctrl(sdiodev); -+ printk("buffer_cnt = %d\n", buffer_cnt); -+ } -+ } -+ down(&sdiodev->tx_priv->cmd_txsema); -+ -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ if (buffer_cnt > 0 && len < (buffer_cnt * BUFFER_SIZE)) { -+ err = aicwf_sdio_send_pkt(sdiodev, payload, len); -+ if (err) { -+ sdio_err("aicwf_sdio_send_pkt fail%d\n", err); -+ } -+ } else { -+ sdio_err("tx msg fc retry fail:%d, %d\n", buffer_cnt, len); -+ up(&sdiodev->tx_priv->cmd_txsema); -+ return -1; -+ } -+ }else if(sdiodev->chipid == PRODUCT_ID_AIC8800DC || sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ err = aicwf_sdio_send_msg(sdiodev, payload, len); -+ if (err) { -+ sdio_err("aicwf_sdio_send_pkt fail%d\n", err); -+ } -+ } else { -+ sdio_err("tx msg fc retry fail:%d, %d\n", buffer_cnt, len); -+ up(&sdiodev->tx_priv->cmd_txsema); -+ return -1; -+ } -+ -+ sdiodev->tx_priv->cmd_txstate = false; -+ if (!err) -+ sdiodev->tx_priv->cmd_tx_succ = true; -+ else -+ sdiodev->tx_priv->cmd_tx_succ = false; -+ -+ up(&sdiodev->tx_priv->cmd_txsema); -+ -+ return err; -+} -+ -+static void aicwf_sdio_tx_process(struct aic_sdio_dev *sdiodev) -+{ -+ int err = 0; -+ -+ if (sdiodev->bus_if->state == BUS_DOWN_ST) { -+ sdio_err("Bus is down\n"); -+ return; -+ } -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwr_stctl(sdiodev, SDIO_ACTIVE_ST); -+#endif -+ -+ //config -+ sdio_info("send cmd\n"); -+ if (sdiodev->tx_priv->cmd_txstate) { -+ if (down_interruptible(&sdiodev->tx_priv->txctl_sema)) { -+ txrx_err("txctl down bus->txctl_sema fail\n"); -+ return; -+ } -+ if (sdiodev->state != SDIO_ACTIVE_ST) { -+ txrx_err("state err\n"); -+ up(&sdiodev->tx_priv->txctl_sema); -+ txrx_err("txctl up bus->txctl_sema fail\n"); -+ return; -+ } -+ -+ err = aicwf_sdio_tx_msg(sdiodev); -+ up(&sdiodev->tx_priv->txctl_sema); -+ if (waitqueue_active(&sdiodev->tx_priv->cmd_txdone_wait)) -+ wake_up(&sdiodev->tx_priv->cmd_txdone_wait); -+ } -+ -+ //data -+ sdio_info("send data\n"); -+ if (down_interruptible(&sdiodev->tx_priv->txctl_sema)) { -+ txrx_err("txdata down bus->txctl_sema\n"); -+ return; -+ } -+ -+ if (sdiodev->state != SDIO_ACTIVE_ST) { -+ txrx_err("sdio state err\n"); -+ up(&sdiodev->tx_priv->txctl_sema); -+ return; -+ } -+ -+ if(!aicwf_is_framequeue_empty(&sdiodev->tx_priv->txq)) -+ sdiodev->tx_priv->fw_avail_bufcnt = aicwf_sdio_flow_ctrl(sdiodev); -+ while (!aicwf_is_framequeue_empty(&sdiodev->tx_priv->txq)) { -+ aicwf_sdio_send(sdiodev->tx_priv); -+ if (sdiodev->tx_priv->cmd_txstate) -+ break; -+ } -+ -+ up(&sdiodev->tx_priv->txctl_sema); -+} -+ -+static int aicwf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) -+{ -+ uint prio; -+ int ret = -EBADE; -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ -+ prio = (pkt->priority & 0x7); -+ spin_lock_bh(&sdiodev->tx_priv->txqlock); -+ if (!aicwf_frame_enq(sdiodev->dev, &sdiodev->tx_priv->txq, pkt, prio)) { -+ spin_unlock_bh(&sdiodev->tx_priv->txqlock); -+ return -ENOSR; -+ } else { -+ ret = 0; -+ } -+ -+ if (bus_if->state != BUS_UP_ST) { -+ sdio_err("bus_if stopped\n"); -+ spin_unlock_bh(&sdiodev->tx_priv->txqlock); -+ return -1; -+ } -+ -+ atomic_inc(&sdiodev->tx_priv->tx_pktcnt); -+ spin_unlock_bh(&sdiodev->tx_priv->txqlock); -+ complete(&bus_if->bustx_trgg); -+ -+ return ret; -+} -+ -+static int aicwf_sdio_bus_txmsg(struct device *dev, u8 *msg, uint msglen) -+{ -+ int ret = -1; -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ -+ down(&sdiodev->tx_priv->cmd_txsema); -+ sdiodev->tx_priv->cmd_txstate = true; -+ sdiodev->tx_priv->cmd_tx_succ = false; -+ sdiodev->tx_priv->cmd_buf = msg; -+ sdiodev->tx_priv->cmd_len = msglen; -+ up(&sdiodev->tx_priv->cmd_txsema); -+ -+ if (bus_if->state != BUS_UP_ST) { -+ sdio_err("bus has stop\n"); -+ return -1; -+ } -+ -+ complete(&bus_if->bustx_trgg); -+ -+ if (sdiodev->tx_priv->cmd_txstate) { -+ int timeout = msecs_to_jiffies(CMD_TX_TIMEOUT); -+ ret = wait_event_timeout(sdiodev->tx_priv->cmd_txdone_wait, \ -+ !(sdiodev->tx_priv->cmd_txstate), timeout); -+ } -+ -+ if (!sdiodev->tx_priv->cmd_txstate && sdiodev->tx_priv->cmd_tx_succ) { -+ ret = 0; -+ } else { -+ sdio_err("send faild:%d, %d,%x\n", sdiodev->tx_priv->cmd_txstate, sdiodev->tx_priv->cmd_tx_succ, ret); -+ ret = -EIO; -+ } -+ -+ return ret; -+} -+ -+int aicwf_sdio_send(struct aicwf_tx_priv *tx_priv) -+{ -+ struct sk_buff *pkt; -+ struct aic_sdio_dev *sdiodev = tx_priv->sdiodev; -+ u16 aggr_len = 0; -+ int retry_times = 0; -+ int max_retry_times = 5; -+ -+ aggr_len = (tx_priv->tail - tx_priv->head); -+ if (((atomic_read(&tx_priv->aggr_count) == 0) && (aggr_len != 0)) -+ || ((atomic_read(&tx_priv->aggr_count) != 0) && (aggr_len == 0))) { -+ if (aggr_len > 0) -+ aicwf_sdio_aggrbuf_reset(tx_priv); -+ goto done; -+ } -+ -+ if (tx_priv->fw_avail_bufcnt <= 0) { //flow control failed -+ tx_priv->fw_avail_bufcnt = aicwf_sdio_flow_ctrl(sdiodev); -+ while (tx_priv->fw_avail_bufcnt <= 0 && retry_times < max_retry_times) { -+ retry_times++; -+ tx_priv->fw_avail_bufcnt = aicwf_sdio_flow_ctrl(sdiodev); -+ } -+ if (tx_priv->fw_avail_bufcnt <= 0) { -+ sdio_err("fc retry %d fail\n", tx_priv->fw_avail_bufcnt); -+ goto done; -+ } -+ } -+ -+ if (atomic_read(&tx_priv->aggr_count) == tx_priv->fw_avail_bufcnt) { -+ if (atomic_read(&tx_priv->aggr_count) > 0) { -+ tx_priv->fw_avail_bufcnt -= atomic_read(&tx_priv->aggr_count); -+ aicwf_sdio_aggr_send(tx_priv); //send and check the next pkt; -+ } -+ } else { -+ spin_lock_bh(&sdiodev->tx_priv->txqlock); -+ pkt = aicwf_frame_dequeue(&sdiodev->tx_priv->txq); -+ if (pkt == NULL) { -+ sdio_err("txq no pkt\n"); -+ spin_unlock_bh(&sdiodev->tx_priv->txqlock); -+ goto done; -+ } -+ atomic_dec(&sdiodev->tx_priv->tx_pktcnt); -+ spin_unlock_bh(&sdiodev->tx_priv->txqlock); -+ -+ if (tx_priv == NULL || tx_priv->tail == NULL || pkt == NULL) -+ txrx_err("null error\n"); -+ if (aicwf_sdio_aggr(tx_priv, pkt)) { -+ aicwf_sdio_aggrbuf_reset(tx_priv); -+ sdio_err("add aggr pkts failed!\n"); -+ goto done; -+ } -+ -+ //when aggr finish or there is cmd to send, just send this aggr pkt to fw -+ if ((int)atomic_read(&sdiodev->tx_priv->tx_pktcnt) == 0 || sdiodev->tx_priv->cmd_txstate) { //no more pkt send it! -+ tx_priv->fw_avail_bufcnt -= atomic_read(&tx_priv->aggr_count); -+ aicwf_sdio_aggr_send(tx_priv); -+ } else -+ goto done; -+ } -+ -+done: -+ return 0; -+} -+ -+int aicwf_sdio_aggr(struct aicwf_tx_priv *tx_priv, struct sk_buff *pkt) -+{ -+ //struct rwnx_txhdr *txhdr = (struct rwnx_txhdr *)pkt->data; -+ u8 *start_ptr = tx_priv->tail; -+ u8 sdio_header[4]; -+ u8 adjust_str[4] = {0, 0, 0, 0}; -+ u16 curr_len = 0; -+ int allign_len = 0; -+ -+ //sdio_header[0] =((pkt->len - sizeof(struct rwnx_txhdr) + sizeof(struct txdesc_api)) & 0xff); -+ //sdio_header[1] =(((pkt->len - sizeof(struct rwnx_txhdr) + sizeof(struct txdesc_api)) >> 8)&0x0f); -+ sdio_header[2] = 0x01; //data -+ if (tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8801 || tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8800DW) -+ sdio_header[3] = 0; //reserved -+ else if (tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8800D80) -+ sdio_header[3] = crc8_ponl_107(&sdio_header[0], 3); // crc8 -+ -+ memcpy(tx_priv->tail, (u8 *)&sdio_header, sizeof(sdio_header)); -+ tx_priv->tail += sizeof(sdio_header); -+ //payload -+ //memcpy(tx_priv->tail, (u8 *)(long)&txhdr->sw_hdr->desc, sizeof(struct txdesc_api)); -+ //tx_priv->tail += sizeof(struct txdesc_api); //hostdesc -+ //memcpy(tx_priv->tail, (u8 *)((u8 *)txhdr + txhdr->sw_hdr->headroom), pkt->len-txhdr->sw_hdr->headroom); -+ //tx_priv->tail += (pkt->len - txhdr->sw_hdr->headroom); -+ -+ //word alignment -+ curr_len = tx_priv->tail - tx_priv->head; -+ if (curr_len & (TX_ALIGNMENT - 1)) { -+ allign_len = roundup(curr_len, TX_ALIGNMENT)-curr_len; -+ memcpy(tx_priv->tail, adjust_str, allign_len); -+ tx_priv->tail += allign_len; -+ } -+ -+ if (tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8801 || tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ start_ptr[0] = ((tx_priv->tail - start_ptr - 4) & 0xff); -+ start_ptr[1] = (((tx_priv->tail - start_ptr - 4)>>8) & 0x0f); -+ } -+ -+ tx_priv->aggr_buf->dev = pkt->dev; -+ -+ #if 0 -+ if (!txhdr->sw_hdr->need_cfm) { -+ kmem_cache_free(txhdr->sw_hdr->rwnx_vif->rwnx_hw->sw_txhdr_cache, txhdr->sw_hdr); -+ skb_pull(pkt, txhdr->sw_hdr->headroom); -+ consume_skb(pkt); -+ } -+ #endif -+ -+ consume_skb(pkt); -+ atomic_inc(&tx_priv->aggr_count); -+ return 0; -+} -+ -+void aicwf_sdio_aggr_send(struct aicwf_tx_priv *tx_priv) -+{ -+ struct sk_buff *tx_buf = tx_priv->aggr_buf; -+ int ret = 0; -+ int curr_len = 0; -+ -+ //link tail is necessary -+ curr_len = tx_priv->tail - tx_priv->head; -+ if ((curr_len % TXPKT_BLOCKSIZE) != 0) { -+ memset(tx_priv->tail, 0, TAIL_LEN); -+ tx_priv->tail += TAIL_LEN; -+ } -+ -+ tx_buf->len = tx_priv->tail - tx_priv->head; -+ ret = aicwf_sdio_txpkt(tx_priv->sdiodev, tx_buf); -+ if (ret < 0) { -+ sdio_err("fail to send aggr pkt!\n"); -+ } -+ -+ aicwf_sdio_aggrbuf_reset(tx_priv); -+} -+ -+void aicwf_sdio_aggrbuf_reset(struct aicwf_tx_priv *tx_priv) -+{ -+ struct sk_buff *aggr_buf = tx_priv->aggr_buf; -+ -+ tx_priv->tail = tx_priv->head; -+ aggr_buf->len = 0; -+ atomic_set(&tx_priv->aggr_count, 0); -+} -+ -+static int aicwf_sdio_bus_start(struct device *dev) -+{ -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ int ret = 0; -+ -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801){ -+ sdio_claim_host(sdiodev->func); -+ sdio_claim_irq(sdiodev->func, aicwf_sdio_hal_irqhandler); -+ //enable sdio interrupt -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x07); -+ if (ret != 0) -+ sdio_err("intr register failed:%d\n", ret); -+ sdio_release_host(sdiodev->func); -+ }else if(sdiodev->chipid == PRODUCT_ID_AIC8800DC || sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ sdio_claim_host(sdiodev->func); -+ -+ //since we have func2 we don't register irq handler -+ sdio_claim_irq(sdiodev->func, NULL); -+ sdio_claim_irq(sdiodev->func_msg, NULL); -+ -+ sdiodev->func->irq_handler = (sdio_irq_handler_t *)aicwf_sdio_hal_irqhandler; -+ sdiodev->func_msg->irq_handler = (sdio_irq_handler_t *)aicwf_sdio_hal_irqhandler_func2; -+ sdio_release_host(sdiodev->func); -+ -+ //enable sdio interrupt -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x07); -+ -+ if (ret != 0) -+ sdio_err("intr register failed:%d\n", ret); -+ -+ //enable sdio interrupt -+ ret = aicwf_sdio_writeb_func2(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x07); -+ -+ if (ret != 0) -+ sdio_err("func2 intr register failed:%d\n", ret); -+ }else if(sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ sdio_claim_host(sdiodev->func); -+ sdio_claim_irq(sdiodev->func, aicwf_sdio_hal_irqhandler); -+ -+ sdio_f0_writeb(sdiodev->func, 0x07, 0x04, &ret); -+ if (ret) { -+ sdio_err("set func0 int en fail %d\n", ret); -+ } -+ sdio_release_host(sdiodev->func); -+ //enable sdio interrupt -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x07); -+ if (ret != 0) -+ sdio_err("intr register failed:%d\n", ret); -+ } -+ -+ bus_if->state = BUS_UP_ST; -+ return ret; -+} -+ -+int aicwf_sdio_bustx_thread(void *data) -+{ -+ struct aicwf_bus *bus = (struct aicwf_bus *) data; -+ struct aic_sdio_dev *sdiodev = bus->bus_priv.sdio; -+ -+ while (1) { -+ if (kthread_should_stop()) { -+ sdio_err("sdio bustx thread stop\n"); -+ break; -+ } -+ if (!wait_for_completion_interruptible(&bus->bustx_trgg)) { -+ if ((int)(atomic_read(&sdiodev->tx_priv->tx_pktcnt) > 0) || (sdiodev->tx_priv->cmd_txstate == true)) -+ aicwf_sdio_tx_process(sdiodev); -+ } -+ } -+ -+ return 0; -+} -+ -+int aicwf_sdio_busrx_thread(void *data) -+{ -+ struct aicwf_rx_priv *rx_priv = (struct aicwf_rx_priv *)data; -+ struct aicwf_bus *bus_if = rx_priv->sdiodev->bus_if; -+ -+ while (1) { -+ if (kthread_should_stop()) { -+ sdio_err("sdio busrx thread stop\n"); -+ break; -+ } -+ if (!wait_for_completion_interruptible(&bus_if->busrx_trgg)) { -+ aicwf_process_rxframes(rx_priv); -+ } -+ } -+ -+ return 0; -+} -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+static void aicwf_sdio_bus_pwrctl(struct timer_list *t) -+{ -+ struct aic_sdio_dev *sdiodev = from_timer(sdiodev, t, timer); -+#else -+static void aicwf_sdio_bus_pwrctl(ulong data) -+{ -+ struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data; -+#endif -+ if (sdiodev->bus_if->state == BUS_DOWN_ST) { -+ sdio_err("bus down\n"); -+ return; -+ } -+ -+ if (sdiodev->pwrctl_tsk) { -+ complete(&sdiodev->pwrctrl_trgg); -+ } -+} -+#endif -+ -+static void aicwf_sdio_enq_rxpkt(struct aic_sdio_dev *sdiodev, struct sk_buff *pkt) -+{ -+ struct aicwf_rx_priv *rx_priv = sdiodev->rx_priv; -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&rx_priv->rxqlock, flags); -+ if (!aicwf_rxframe_enqueue(sdiodev->dev, &rx_priv->rxq, pkt)) { -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ aicwf_dev_skb_free(pkt); -+ return; -+ } -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ -+ atomic_inc(&rx_priv->rx_cnt); -+} -+ -+#define SDIO_OTHER_INTERRUPT (0x1ul << 7) -+ -+void aicwf_sdio_hal_irqhandler(struct sdio_func *func) -+{ -+ struct aicwf_bus *bus_if = dev_get_drvdata(&func->dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ u8 intstatus = 0; -+ u8 byte_len = 0; -+ struct sk_buff *pkt = NULL; -+ int ret; -+ -+ //AICWFDBG(LOGDEBUG,"%s bsp enter \r\n", __func__); -+ -+ if(aicbsp_sdiodev->sdio_hal_irqhandler){ -+ aicbsp_sdiodev->sdio_hal_irqhandler(func); -+ return; -+ } -+ -+ if (!bus_if || bus_if->state == BUS_DOWN_ST) { -+ sdio_err("bus err\n"); -+ return; -+ } -+ -+ if (sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.block_cnt_reg, &intstatus); -+ -+ while(intstatus){ -+ sdiodev->rx_priv->data_len = intstatus * SDIOWIFI_FUNC_BLOCKSIZE; -+ if (intstatus > 0) { -+ if(intstatus < 64) { -+ pkt = aicwf_sdio_readframes(sdiodev, 0); -+ } else { -+ aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len);//byte_len must<= 128 -+ sdio_info("byte mode len=%d\r\n", byte_len); -+ pkt = aicwf_sdio_readframes(sdiodev, 0); -+ } -+ } else { -+ #ifndef CONFIG_PLATFORM_ALLWINNER -+ sdio_err("Interrupt but no data\n"); -+ #endif -+ } -+ -+ if (pkt) -+ aicwf_sdio_enq_rxpkt(sdiodev, pkt); -+ -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.block_cnt_reg, &intstatus); -+ } -+ }else if (sdiodev->chipid == PRODUCT_ID_AIC8800D80) { -+ do { -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.misc_int_status_reg, &intstatus); -+ if (!ret) { -+ break; -+ } -+ sdio_err("ret=%d, intstatus=%x\r\n",ret, intstatus); -+ } while (1); -+ if (intstatus & SDIO_OTHER_INTERRUPT) { -+ u8 int_pending; -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.sleep_reg, &int_pending); -+ if (ret < 0) { -+ sdio_err("reg:%d read failed!\n", sdiodev->sdio_reg.sleep_reg); -+ } -+ int_pending &= ~0x01; // dev to host soft irq -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.sleep_reg, int_pending); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!\n", sdiodev->sdio_reg.sleep_reg); -+ } -+ } -+ -+ if (intstatus > 0) { -+ uint8_t intmaskf2 = intstatus | (0x1UL << 3); -+ if (intmaskf2 > 120U) { // func2 -+ if (intmaskf2 == 127U) { // byte mode -+ //aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len, 1);//byte_len must<= 128 -+ aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len);//byte_len must<= 128 -+ sdio_info("byte mode len=%d\r\n", byte_len); -+ pkt = aicwf_sdio_readframes(sdiodev, 1); -+ } else { // block mode -+ sdiodev->rx_priv->data_len = (intstatus & 0x7U) * SDIOWIFI_FUNC_BLOCKSIZE; -+ pkt = aicwf_sdio_readframes(sdiodev, 1); -+ } -+ } else { // func1 -+ if (intstatus == 120U) { // byte mode -+ //aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len, 0);//byte_len must<= 128 -+ aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len);//byte_len must<= 128 -+ sdio_info("byte mode len=%d\r\n", byte_len); -+ pkt = aicwf_sdio_readframes(sdiodev, 0); -+ } else { // block mode -+ sdiodev->rx_priv->data_len = (intstatus & 0x7FU) * SDIOWIFI_FUNC_BLOCKSIZE; -+ pkt = aicwf_sdio_readframes(sdiodev, 0); -+ } -+ } -+ } else { -+ #ifndef CONFIG_PLATFORM_ALLWINNER -+ sdio_err("Interrupt but no data\n"); -+ #endif -+ } -+ -+ if (pkt) -+ aicwf_sdio_enq_rxpkt(sdiodev, pkt); -+ } -+ -+ complete(&bus_if->busrx_trgg); -+} -+ -+void aicwf_sdio_hal_irqhandler_func2(struct sdio_func *func) -+{ -+ struct aicwf_bus *bus_if = dev_get_drvdata(&func->dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ u8 intstatus = 0; -+ u8 byte_len = 0; -+ #ifdef CONFIG_PREALLOC_RX_SKB -+ struct rx_buff *pkt = NULL; -+ #else -+ struct sk_buff *pkt = NULL; -+ #endif -+ int ret; -+ -+ if (!bus_if || bus_if->state == BUS_DOWN_ST) { -+ sdio_err("bus err\n"); -+ return; -+ } -+ -+ #ifdef CONFIG_PREALLOC_RX_SKB -+ if (list_empty(&aic_rx_buff_list.rxbuff_list)) { -+ printk("%s %d, rxbuff list is empty\n", __func__, __LINE__); -+ return; -+ } -+ #endif -+ -+ ret = aicwf_sdio_readb_func2(sdiodev, sdiodev->sdio_reg.block_cnt_reg, &intstatus); -+ -+ while(intstatus) { -+ sdiodev->rx_priv->data_len = intstatus * SDIOWIFI_FUNC_BLOCKSIZE; -+ if (intstatus > 0) { -+ if(intstatus < 64) { -+ pkt = aicwf_sdio_readframes(sdiodev,1); -+ } else { -+ sdio_info("byte mode len=%d\r\n", byte_len); -+ -+ aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len);//byte_len must<= 128 -+ pkt = aicwf_sdio_readframes(sdiodev,1); -+ } -+ } else { -+ #ifndef CONFIG_PLATFORM_ALLWINNER -+ sdio_err("Interrupt but no data\n"); -+ #endif -+ } -+ -+ if (pkt){ -+ aicwf_sdio_enq_rxpkt(sdiodev, pkt); -+ } -+ ret = aicwf_sdio_readb_func2(sdiodev, sdiodev->sdio_reg.block_cnt_reg, &intstatus); -+ } -+ -+ complete(&bus_if->busrx_trgg); -+} -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration) -+{ -+ uint timeout; -+ -+ if (sdiodev->bus_if->state == BUS_DOWN_ST && duration) -+ return; -+ -+ spin_lock_bh(&sdiodev->pwrctl_lock); -+ if (!duration) { -+ if (timer_pending(&sdiodev->timer)) -+ del_timer_sync(&sdiodev->timer); -+ } else { -+ sdiodev->active_duration = duration; -+ timeout = msecs_to_jiffies(sdiodev->active_duration); -+ mod_timer(&sdiodev->timer, jiffies + timeout); -+ } -+ spin_unlock_bh(&sdiodev->pwrctl_lock); -+} -+#endif -+ -+static struct aicwf_bus_ops aicwf_sdio_bus_ops = { -+ .stop = aicwf_sdio_bus_stop, -+ .start = aicwf_sdio_bus_start, -+ .txdata = aicwf_sdio_bus_txdata, -+ .txmsg = aicwf_sdio_bus_txmsg, -+}; -+ -+void aicwf_sdio_release_func2(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ sdio_dbg("%s\n", __func__); -+ sdio_claim_host(sdiodev->func_msg); -+ //disable sdio interrupt -+ ret = aicwf_sdio_writeb_func2(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x0); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!\n", sdiodev->sdio_reg.intr_config_reg); -+ } -+ sdio_release_irq(sdiodev->func_msg); -+ sdio_release_host(sdiodev->func_msg); -+ -+} -+ -+void aicwf_sdio_release(struct aic_sdio_dev *sdiodev) -+{ -+ struct aicwf_bus *bus_if; -+ int ret = 0; -+ -+ sdio_dbg("%s\n", __func__); -+ -+ bus_if = aicbsp_get_drvdata(sdiodev->dev); -+ bus_if->state = BUS_DOWN_ST; -+ -+ sdio_claim_host(sdiodev->func); -+ //disable sdio interrupt -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x0); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!, ret=%d\n", sdiodev->sdio_reg.intr_config_reg, ret); -+ } -+ sdio_release_irq(sdiodev->func); -+ sdio_release_host(sdiodev->func); -+ -+ if(sdiodev->chipid == PRODUCT_ID_AIC8800DC || sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ aicwf_sdio_release_func2(sdiodev); -+ } -+ -+ if (sdiodev->dev) -+ aicwf_bus_deinit(sdiodev->dev); -+ -+ if (sdiodev->tx_priv) -+ aicwf_tx_deinit(sdiodev->tx_priv); -+ -+ if (sdiodev->rx_priv) -+ aicwf_rx_deinit(sdiodev->rx_priv); -+ -+ rwnx_cmd_mgr_deinit(&sdiodev->cmd_mgr); -+} -+ -+void aicwf_sdio_reg_init(struct aic_sdio_dev *sdiodev) -+{ -+ sdio_dbg("%s\n", __func__); -+ -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ sdiodev->sdio_reg.bytemode_len_reg = SDIOWIFI_BYTEMODE_LEN_REG; -+ sdiodev->sdio_reg.intr_config_reg = SDIOWIFI_INTR_CONFIG_REG; -+ sdiodev->sdio_reg.sleep_reg = SDIOWIFI_SLEEP_REG; -+ sdiodev->sdio_reg.wakeup_reg = SDIOWIFI_WAKEUP_REG; -+ sdiodev->sdio_reg.flow_ctrl_reg = SDIOWIFI_FLOW_CTRL_REG; -+ sdiodev->sdio_reg.register_block = SDIOWIFI_REGISTER_BLOCK; -+ sdiodev->sdio_reg.bytemode_enable_reg = SDIOWIFI_BYTEMODE_ENABLE_REG; -+ sdiodev->sdio_reg.block_cnt_reg = SDIOWIFI_BLOCK_CNT_REG; -+ sdiodev->sdio_reg.rd_fifo_addr = SDIOWIFI_RD_FIFO_ADDR; -+ sdiodev->sdio_reg.wr_fifo_addr = SDIOWIFI_WR_FIFO_ADDR; -+ } else if (sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ sdiodev->sdio_reg.bytemode_len_reg = SDIOWIFI_BYTEMODE_LEN_REG_V3; -+ sdiodev->sdio_reg.intr_config_reg = SDIOWIFI_INTR_ENABLE_REG_V3; -+ sdiodev->sdio_reg.sleep_reg = SDIOWIFI_INTR_PENDING_REG_V3; -+ sdiodev->sdio_reg.wakeup_reg = SDIOWIFI_INTR_TO_DEVICE_REG_V3; -+ sdiodev->sdio_reg.flow_ctrl_reg = SDIOWIFI_FLOW_CTRL_Q1_REG_V3; -+ sdiodev->sdio_reg.bytemode_enable_reg = SDIOWIFI_BYTEMODE_ENABLE_REG_V3; -+ sdiodev->sdio_reg.misc_int_status_reg = SDIOWIFI_MISC_INT_STATUS_REG_V3; -+ sdiodev->sdio_reg.rd_fifo_addr = SDIOWIFI_RD_FIFO_ADDR_V3; -+ sdiodev->sdio_reg.wr_fifo_addr = SDIOWIFI_WR_FIFO_ADDR_V3; -+ } -+} -+ -+int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev) -+{ -+ struct mmc_host *host; -+ u8 block_bit0 = 0x1; -+ u8 byte_mode_disable = 0x1;//1: no byte mode -+ int ret = 0; -+ struct aicbsp_feature_t feature; -+ -+ aicbsp_get_feature(&feature, NULL); -+ aicwf_sdio_reg_init(sdiodev); -+ -+ host = sdiodev->func->card->host; -+ -+ sdio_claim_host(sdiodev->func); -+#if 0//SDIO PHASE SETTING -+ sdiodev->func->card->quirks |= MMC_QUIRK_LENIENT_FN0; -+ sdio_f0_writeb(sdiodev->func, feature.sdio_phase, 0x13, &ret); -+ if (ret < 0) { -+ sdio_err("write func0 fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+#endif -+ -+ ret = sdio_set_block_size(sdiodev->func, SDIOWIFI_FUNC_BLOCKSIZE); -+ if (ret < 0) { -+ sdio_err("set blocksize fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ ret = sdio_enable_func(sdiodev->func); -+ if (ret < 0) { -+ sdio_err("enable func fail %d.\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ udelay(100); -+#if 1//SDIO CLOCK SETTING -+ if (feature.sdio_clock > 0) { -+ host->ios.clock = feature.sdio_clock; -+ host->ops->set_ios(host, &host->ios); -+ sdio_dbg("Set SDIO Clock %d MHz\n", host->ios.clock/1000000); -+ } -+#endif -+ sdio_release_host(sdiodev->func); -+ -+ if(sdiodev->chipid == PRODUCT_ID_AIC8800DC || sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ -+ sdio_claim_host(sdiodev->func_msg); -+ -+ //set sdio blocksize -+ ret = sdio_set_block_size(sdiodev->func_msg, SDIOWIFI_FUNC_BLOCKSIZE); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "set func2 blocksize fail %d\n", ret); -+ sdio_release_host(sdiodev->func_msg); -+ return ret; -+ } -+ -+ //set sdio enable func -+ ret = sdio_enable_func(sdiodev->func_msg); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "enable func2 fail %d.\n", ret); -+ } -+ -+ sdio_release_host(sdiodev->func_msg); -+ -+ ret = aicwf_sdio_writeb_func2(sdiodev, sdiodev->sdio_reg.register_block, block_bit0); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.register_block); -+ return ret; -+ } -+ -+ //1: no byte mode -+ ret = aicwf_sdio_writeb_func2(sdiodev, sdiodev->sdio_reg.bytemode_enable_reg, byte_mode_disable); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.bytemode_enable_reg); -+ return ret; -+ } -+ } -+ -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.register_block, block_bit0); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!\n", sdiodev->sdio_reg.register_block); -+ return ret; -+ } -+ -+ //1: no byte mode -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.bytemode_enable_reg, byte_mode_disable); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!\n", sdiodev->sdio_reg.bytemode_enable_reg); -+ return ret; -+ } -+ -+ return ret; -+} -+ -+int aicwf_sdiov3_func_init(struct aic_sdio_dev *sdiodev) -+{ -+ struct mmc_host *host; -+ u8 byte_mode_disable = 0x1;//1: no byte mode -+ int ret = 0; -+ //u8 val; -+ struct aicbsp_feature_t feature; -+ -+ aicbsp_get_feature(&feature, NULL); -+ aicwf_sdio_reg_init(sdiodev); -+ -+ host = sdiodev->func->card->host; -+ -+ sdio_claim_host(sdiodev->func); -+ sdiodev->func->card->quirks |= MMC_QUIRK_LENIENT_FN0; -+ -+ ret = sdio_set_block_size(sdiodev->func, SDIOWIFI_FUNC_BLOCKSIZE); -+ if (ret < 0) { -+ sdio_err("set blocksize fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ ret = sdio_enable_func(sdiodev->func); -+ if (ret < 0) { -+ sdio_err("enable func fail %d.\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ -+ sdio_f0_writeb(sdiodev->func, 0x7F, 0xF2, &ret); -+ if (ret) { -+ sdio_err("set fn0 0xF2 fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+#if 0 -+ if (host->ios.timing == MMC_TIMING_UHS_DDR50) { -+ val = 0x21;//0x1D;//0x5; -+ } else { -+ val = 0x01;//0x19;//0x1; -+ } -+ val |= SDIOCLK_FREE_RUNNING_BIT; -+ sdio_f0_writeb(sdiodev->func, val, 0xF0, &ret); -+ if (ret) { -+ sdio_err("set iopad ctrl fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ sdio_f0_writeb(sdiodev->func, 0x0, 0xF8, &ret); -+ if (ret) { -+ sdio_err("set iopad delay2 fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ sdio_f0_writeb(sdiodev->func, 0x40, 0xF1, &ret); -+ if (ret) { -+ sdio_err("set iopad delay1 fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ msleep(1); -+#if 1//SDIO CLOCK SETTING -+ if ((feature.sdio_clock > 0) && (host->ios.timing != MMC_TIMING_UHS_DDR50)) { -+ host->ios.clock = feature.sdio_clock; -+ host->ops->set_ios(host, &host->ios); -+ sdio_dbg("Set SDIO Clock %d MHz\n", host->ios.clock/1000000); -+ } -+#endif -+#endif -+ sdio_release_host(sdiodev->func); -+ -+ //1: no byte mode -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.bytemode_enable_reg, byte_mode_disable); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!\n", sdiodev->sdio_reg.bytemode_enable_reg); -+ return ret; -+ } -+ -+ return ret; -+} -+ -+void aicwf_sdio_func_deinit(struct aic_sdio_dev *sdiodev) -+{ -+ sdio_claim_host(sdiodev->func); -+ sdio_disable_func(sdiodev->func); -+ sdio_release_host(sdiodev->func); -+ if(sdiodev->chipid == PRODUCT_ID_AIC8800DC || sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ sdio_claim_host(sdiodev->func_msg); -+ sdio_disable_func(sdiodev->func_msg); -+ sdio_release_host(sdiodev->func_msg); -+ } -+} -+ -+void *aicwf_sdio_bus_init(struct aic_sdio_dev *sdiodev) -+{ -+ int ret; -+ struct aicwf_bus *bus_if; -+ struct aicwf_rx_priv *rx_priv; -+ struct aicwf_tx_priv *tx_priv; -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+ spin_lock_init(&sdiodev->pwrctl_lock); -+ sema_init(&sdiodev->pwrctl_wakeup_sema, 1); -+#endif -+ -+ bus_if = sdiodev->bus_if; -+ bus_if->dev = sdiodev->dev; -+ bus_if->ops = &aicwf_sdio_bus_ops; -+ bus_if->state = BUS_DOWN_ST; -+#if defined(CONFIG_SDIO_PWRCTRL) -+ sdiodev->state = SDIO_SLEEP_ST; -+ sdiodev->active_duration = SDIOWIFI_PWR_CTRL_INTERVAL; -+#else -+ sdiodev->state = SDIO_ACTIVE_ST; -+#endif -+ -+ rx_priv = aicwf_rx_init(sdiodev); -+ if (!rx_priv) { -+ sdio_err("rx init fail\n"); -+ goto fail; -+ } -+ sdiodev->rx_priv = rx_priv; -+ -+ tx_priv = aicwf_tx_init(sdiodev); -+ if (!tx_priv) { -+ sdio_err("tx init fail\n"); -+ goto fail; -+ } -+ sdiodev->tx_priv = tx_priv; -+ aicwf_frame_queue_init(&tx_priv->txq, 8, TXQLEN); -+ spin_lock_init(&tx_priv->txqlock); -+ sema_init(&tx_priv->txctl_sema, 1); -+ sema_init(&tx_priv->cmd_txsema, 1); -+ init_waitqueue_head(&tx_priv->cmd_txdone_wait); -+ atomic_set(&tx_priv->tx_pktcnt, 0); -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ timer_setup(&sdiodev->timer, aicwf_sdio_bus_pwrctl, 0); -+#else -+ init_timer(&sdiodev->timer); -+ sdiodev->timer.data = (ulong) sdiodev; -+ sdiodev->timer.function = aicwf_sdio_bus_pwrctl; -+#endif -+ init_completion(&sdiodev->pwrctrl_trgg); -+#endif -+ ret = aicwf_bus_init(0, sdiodev->dev); -+ if (ret < 0) { -+ sdio_err("bus init fail\n"); -+ goto fail; -+ } -+ -+ ret = aicwf_bus_start(bus_if); -+ if (ret != 0) { -+ sdio_err("bus start fail\n"); -+ goto fail; -+ } -+ -+ return sdiodev; -+ -+fail: -+ aicwf_sdio_release(sdiodev); -+ return NULL; -+} -+ -+void get_fw_path(char* fw_path){ -+ if (strlen(aic_fw_path) > 0) { -+ memcpy(fw_path, aic_fw_path, strlen(aic_fw_path)); -+ }else{ -+ memcpy(fw_path, aic_default_fw_path, strlen(aic_default_fw_path)); -+ } -+} -+ -+int get_testmode(void){ -+ return testmode; -+} -+ -+struct sdio_func *get_sdio_func(void){ -+ return aicbsp_sdiodev->func; -+} -+ -+void set_irq_handler(void *fn){ -+ aicbsp_sdiodev->sdio_hal_irqhandler = (sdio_irq_handler_t *)fn; -+} -+ -+uint8_t crc8_ponl_107(uint8_t *p_buffer, uint16_t cal_size) -+{ -+ uint8_t i; -+ uint8_t crc = 0; -+ if (cal_size==0) { -+ return crc; -+ } -+ while (cal_size--) { -+ for (i = 0x80; i > 0; i /= 2) { -+ if (crc & 0x80) { -+ crc *= 2; -+ crc ^= 0x07; //polynomial X8 + X2 + X + 1,(0x107) -+ } else { -+ crc *= 2; -+ } -+ if ((*p_buffer) & i) { -+ crc ^= 0x07; -+ } -+ } -+ p_buffer++; -+ } -+ return crc; -+} -+ -+EXPORT_SYMBOL(get_fw_path); -+EXPORT_SYMBOL(get_testmode); -+EXPORT_SYMBOL(get_sdio_func); -+EXPORT_SYMBOL(set_irq_handler); -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,148 @@ -+/** -+ * aicwf_sdio.h -+ * -+ * SDIO function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+#ifndef _AICWF_SDMMC_H_ -+#define _AICWF_SDMMC_H_ -+ -+#ifdef AICWF_SDIO_SUPPORT -+#include -+#include -+#include -+#include -+#include "aic_bsp_driver.h" -+ -+#define AICBSP_SDIO_NAME "aicbsp_sdio" -+#define SDIOWIFI_FUNC_BLOCKSIZE 512 -+ -+#define SDIO_VENDOR_ID_AIC 0x8800 -+#define SDIO_DEVICE_ID_AIC 0x0001 -+#define SDIOWIFI_BYTEMODE_LEN_REG 0x02 -+#define SDIOWIFI_INTR_CONFIG_REG 0x04 -+#define SDIOWIFI_SLEEP_REG 0x05 -+#define SDIOWIFI_WAKEUP_REG 0x09 -+#define SDIOWIFI_FLOW_CTRL_REG 0x0A -+#define SDIOWIFI_REGISTER_BLOCK 0x0B -+#define SDIOWIFI_BYTEMODE_ENABLE_REG 0x11 -+#define SDIOWIFI_BLOCK_CNT_REG 0x12 -+#define SDIOWIFI_FLOWCTRL_MASK_REG 0x7F -+#define SDIOWIFI_WR_FIFO_ADDR 0x07 -+#define SDIOWIFI_RD_FIFO_ADDR 0x08 -+ -+#define SDIOWIFI_INTR_ENABLE_REG_V3 0x00 -+#define SDIOWIFI_INTR_PENDING_REG_V3 0x01 -+#define SDIOWIFI_INTR_TO_DEVICE_REG_V3 0x02 -+#define SDIOWIFI_FLOW_CTRL_Q1_REG_V3 0x03 -+#define SDIOWIFI_MISC_INT_STATUS_REG_V3 0x04 -+#define SDIOWIFI_BYTEMODE_LEN_REG_V3 0x05 -+#define SDIOWIFI_BYTEMODE_LEN_MSB_REG_V3 0x06 -+#define SDIOWIFI_BYTEMODE_ENABLE_REG_V3 0x07 -+#define SDIOWIFI_MISC_CTRL_REG_V3 0x08 -+#define SDIOWIFI_FLOW_CTRL_Q2_REG_V3 0x09 -+#define SDIOWIFI_CLK_TEST_RESULT_REG_V3 0x0A -+#define SDIOWIFI_RD_FIFO_ADDR_V3 0x0F -+#define SDIOWIFI_WR_FIFO_ADDR_V3 0x10 -+ -+#define SDIOCLK_FREE_RUNNING_BIT (1 << 6) -+ -+#define SDIOWIFI_PWR_CTRL_INTERVAL 30 -+#define FLOW_CTRL_RETRY_COUNT 50 -+#define BUFFER_SIZE 1536 -+#define TAIL_LEN 4 -+#define TXQLEN (2048*4) -+ -+#define SDIO_SLEEP_ST 0 -+#define SDIO_ACTIVE_ST 1 -+ -+typedef enum { -+ SDIO_TYPE_DATA = 0X00, -+ SDIO_TYPE_CFG = 0X10, -+ SDIO_TYPE_CFG_CMD_RSP = 0X11, -+ SDIO_TYPE_CFG_DATA_CFM = 0X12 -+} sdio_type; -+ -+enum AICWF_IC{ -+ PRODUCT_ID_AIC8801 = 0, -+ PRODUCT_ID_AIC8800DC, -+ PRODUCT_ID_AIC8800DW, -+ PRODUCT_ID_AIC8800D80 -+}; -+ -+struct aic_sdio_reg { -+ u8 bytemode_len_reg; -+ u8 intr_config_reg; -+ u8 sleep_reg; -+ u8 wakeup_reg; -+ u8 flow_ctrl_reg; -+ u8 flowctrl_mask_reg; -+ u8 register_block; -+ u8 bytemode_enable_reg; -+ u8 block_cnt_reg; -+ u8 misc_int_status_reg; -+ u8 rd_fifo_addr; -+ u8 wr_fifo_addr; -+}; -+ -+struct aic_sdio_dev { -+ struct rwnx_cmd_mgr cmd_mgr; -+ struct sdio_func *func; -+ struct sdio_func *func_msg; -+ struct device *dev; -+ struct aicwf_bus *bus_if; -+ -+ struct aicwf_rx_priv *rx_priv; -+ struct aicwf_tx_priv *tx_priv; -+ u32 state; -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+ //for sdio pwr ctrl -+ struct timer_list timer; -+ uint active_duration; -+ struct completion pwrctrl_trgg; -+ struct task_struct *pwrctl_tsk; -+ spinlock_t pwrctl_lock; -+ struct semaphore pwrctl_wakeup_sema; -+#endif -+ u16 chipid; -+ u32 fw_version_uint; -+ struct aic_sdio_reg sdio_reg; -+ void (*sdio_hal_irqhandler) (struct sdio_func *func); -+}; -+ -+void *aicbsp_get_drvdata(void *args); -+int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val); -+void aicwf_sdio_hal_irqhandler(struct sdio_func *func); -+void aicwf_sdio_hal_irqhandler_func2(struct sdio_func *func); -+#if defined(CONFIG_SDIO_PWRCTRL) -+void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration); -+int aicwf_sdio_pwr_stctl(struct aic_sdio_dev *sdiodev, uint target); -+#endif -+void aicwf_sdio_reg_init(struct aic_sdio_dev *sdiodev); -+int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev); -+int aicwf_sdiov3_func_init(struct aic_sdio_dev *sdiodev); -+void aicwf_sdio_func_deinit(struct aic_sdio_dev *sdiodev); -+int aicwf_sdio_flow_ctrl(struct aic_sdio_dev *sdiodev); -+int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct sk_buff *skbbuf, u32 size, u8 msg); -+int aicwf_sdio_send_pkt(struct aic_sdio_dev *sdiodev, u8 *buf, uint count); -+void *aicwf_sdio_bus_init(struct aic_sdio_dev *sdiodev); -+void aicwf_sdio_release(struct aic_sdio_dev *sdiodev); -+void aicbsp_sdio_exit(void); -+int aicbsp_sdio_init(void); -+void aicbsp_sdio_release(struct aic_sdio_dev *sdiodev); -+int aicwf_sdio_txpkt(struct aic_sdio_dev *sdiodev, struct sk_buff *pkt); -+int aicwf_sdio_bustx_thread(void *data); -+int aicwf_sdio_busrx_thread(void *data); -+int aicwf_sdio_aggr(struct aicwf_tx_priv *tx_priv, struct sk_buff *pkt); -+int aicwf_sdio_send(struct aicwf_tx_priv *tx_priv); -+void aicwf_sdio_aggr_send(struct aicwf_tx_priv *tx_priv); -+void aicwf_sdio_aggrbuf_reset(struct aicwf_tx_priv *tx_priv); -+extern void aicwf_hostif_ready(void); -+int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv); -+uint8_t crc8_ponl_107(uint8_t *p_buffer, uint16_t cal_size); -+#endif /* AICWF_SDIO_SUPPORT */ -+ -+#endif /*_AICWF_SDMMC_H_*/ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio_txrxif.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio_txrxif.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio_txrxif.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio_txrxif.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,465 @@ -+/** -+ * aicwf_bus.c -+ * -+ * bus function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "aicsdio_txrxif.h" -+#include "aic_bsp_driver.h" -+ -+int aicwf_bus_init(uint bus_hdrlen, struct device *dev) -+{ -+ int ret = 0; -+ struct aicwf_bus *bus_if; -+ -+ if (!dev) { -+ txrx_err("device not found\n"); -+ return -1; -+ } -+ bus_if = dev_get_drvdata(dev); -+ bus_if->cmd_buf = kzalloc(CMD_BUF_MAX, GFP_KERNEL); -+ if (!bus_if->cmd_buf) { -+ ret = -ENOMEM; -+ txrx_err("proto_attach failed\n"); -+ goto fail; -+ } -+ memset(bus_if->cmd_buf, '\0', CMD_BUF_MAX); -+ -+ init_completion(&bus_if->bustx_trgg); -+ init_completion(&bus_if->busrx_trgg); -+#ifdef AICWF_SDIO_SUPPORT -+ bus_if->bustx_thread = kthread_run(aicwf_sdio_bustx_thread, (void *)bus_if, "aicwf_bustx_thread"); -+ bus_if->busrx_thread = kthread_run(aicwf_sdio_busrx_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busrx_thread"); -+#endif -+ -+ if (IS_ERR(bus_if->bustx_thread)) { -+ bus_if->bustx_thread = NULL; -+ txrx_err("aicwf_bustx_thread run fail\n"); -+ ret = -1; -+ goto fail; -+ } -+ -+ if (IS_ERR(bus_if->busrx_thread)) { -+ bus_if->busrx_thread = NULL; -+ txrx_err("aicwf_bustx_thread run fail\n"); -+ ret = -1; -+ goto fail; -+ } -+ -+ return ret; -+fail: -+ aicwf_bus_deinit(dev); -+ -+ return ret; -+} -+ -+void aicwf_bus_deinit(struct device *dev) -+{ -+ struct aicwf_bus *bus_if; -+ struct aic_sdio_dev *sdiodev; -+ -+ if (!dev) { -+ txrx_err("device not found\n"); -+ return; -+ } -+ sdio_dbg("%s", __func__); -+ bus_if = aicbsp_get_drvdata(dev); -+ aicwf_bus_stop(bus_if); -+ -+ sdiodev = bus_if->bus_priv.sdio; -+ -+ if (bus_if->cmd_buf) { -+ kfree(bus_if->cmd_buf); -+ bus_if->cmd_buf = NULL; -+ } -+ -+ if (bus_if->bustx_thread) { -+ complete_all(&bus_if->bustx_trgg); -+ kthread_stop(bus_if->bustx_thread); -+ bus_if->bustx_thread = NULL; -+ } -+} -+ -+void aicwf_frame_tx(void *dev, struct sk_buff *skb) -+{ -+ struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev; -+ aicwf_bus_txdata(sdiodev->bus_if, skb); -+} -+ -+struct aicwf_tx_priv *aicwf_tx_init(void *arg) -+{ -+ struct aicwf_tx_priv *tx_priv; -+ -+ tx_priv = kzalloc(sizeof(struct aicwf_tx_priv), GFP_KERNEL); -+ if (!tx_priv) -+ return NULL; -+ -+ tx_priv->sdiodev = (struct aic_sdio_dev *)arg; -+ -+ atomic_set(&tx_priv->aggr_count, 0); -+ tx_priv->aggr_buf = dev_alloc_skb(MAX_AGGR_TXPKT_LEN); -+ if (!tx_priv->aggr_buf) { -+ txrx_err("Alloc bus->txdata_buf failed!\n"); -+ kfree(tx_priv); -+ return NULL; -+ } -+ tx_priv->head = tx_priv->aggr_buf->data; -+ tx_priv->tail = tx_priv->aggr_buf->data; -+ -+ return tx_priv; -+} -+ -+void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv) -+{ -+ if (tx_priv && tx_priv->aggr_buf) -+ dev_kfree_skb(tx_priv->aggr_buf); -+ -+ kfree(tx_priv); -+ //tx_priv = NULL; -+} -+ -+static bool aicwf_another_ptk(struct sk_buff *skb) -+{ -+ u8 *data; -+ u16 aggr_len = 0; -+ -+ if (skb->data == NULL || skb->len == 0) { -+ return false; -+ } -+ data = skb->data; -+ aggr_len = (*skb->data | (*(skb->data + 1) << 8)); -+ if (aggr_len == 0) { -+ return false; -+ } -+ -+ return true; -+} -+ -+int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv) -+{ -+ int ret = 0; -+ unsigned long flags = 0; -+ struct sk_buff *skb = NULL; -+ u16 pkt_len = 0; -+ struct sk_buff *skb_inblock = NULL; -+ u16 aggr_len = 0, adjust_len = 0; -+ u8 *data = NULL; -+ -+ while (1) { -+ spin_lock_irqsave(&rx_priv->rxqlock, flags); -+ if (aicwf_is_framequeue_empty(&rx_priv->rxq)) { -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ break; -+ } -+ skb = aicwf_frame_dequeue(&rx_priv->rxq); -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ if (skb == NULL) { -+ txrx_err("skb_error\r\n"); -+ break; -+ } -+ while (aicwf_another_ptk(skb)) { -+ data = skb->data; -+ pkt_len = (*skb->data | (*(skb->data + 1) << 8)); -+ -+ if ((skb->data[2] & SDIO_TYPE_CFG) != SDIO_TYPE_CFG) { // type : data -+ aggr_len = pkt_len + RX_HWHRD_LEN; -+ -+ if (aggr_len & (RX_ALIGNMENT - 1)) -+ adjust_len = roundup(aggr_len, RX_ALIGNMENT); -+ else -+ adjust_len = aggr_len; -+ -+ skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL);//8 is for ccmp mic or wep icv -+ if (skb_inblock == NULL) { -+ txrx_err("no more space!\n"); -+ aicwf_dev_skb_free(skb); -+ return -EBADE; -+ } -+ -+ skb_put(skb_inblock, aggr_len); -+ memcpy(skb_inblock->data, data, aggr_len); -+ #if 0 -+ rwnx_rxdataind_aicwf(rx_priv->sdiodev->rwnx_hw, skb_inblock, (void *)rx_priv); -+ #endif -+ skb_pull(skb, adjust_len); -+ } else { // type : config -+ aggr_len = pkt_len; -+ -+ if (aggr_len & (RX_ALIGNMENT - 1)) -+ adjust_len = roundup(aggr_len, RX_ALIGNMENT); -+ else -+ adjust_len = aggr_len; -+ -+ skb_inblock = __dev_alloc_skb(aggr_len+4, GFP_KERNEL); -+ if (skb_inblock == NULL) { -+ txrx_err("no more space!\n"); -+ aicwf_dev_skb_free(skb); -+ return -EBADE; -+ } -+ -+ skb_put(skb_inblock, aggr_len+4); -+ memcpy(skb_inblock->data, data, aggr_len+4); -+ if ((*(skb_inblock->data + 2) & 0x7f) == SDIO_TYPE_CFG_CMD_RSP) -+ rwnx_rx_handle_msg(rx_priv->sdiodev, (struct ipc_e2a_msg *)(skb_inblock->data + 4)); -+ #if 0 -+ if ((*(skb_inblock->data + 2) & 0x7f) == SDIO_TYPE_CFG_DATA_CFM) -+ aicwf_sdio_host_tx_cfm_handler(&(rx_priv->sdiodev->rwnx_hw->sdio_env), (u32 *)(skb_inblock->data + 4)); -+ #endif -+ skb_pull(skb, adjust_len+4); -+ } -+ } -+ -+ /* skb_inblock no used currently, just free it! */ -+ dev_kfree_skb(skb_inblock); -+ dev_kfree_skb(skb); -+ atomic_dec(&rx_priv->rx_cnt); -+ } -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwr_stctl(rx_priv->sdiodev, SDIO_ACTIVE_ST); -+#endif -+ -+ return ret; -+} -+ -+static struct recv_msdu *aicwf_rxframe_queue_init(struct list_head *q, int qsize) -+{ -+ int i; -+ struct recv_msdu *req, *reqs; -+ -+ reqs = vmalloc(qsize*sizeof(struct recv_msdu)); -+ if (reqs == NULL) -+ return NULL; -+ -+ req = reqs; -+ for (i = 0; i < qsize; i++) { -+ INIT_LIST_HEAD(&req->rxframe_list); -+ list_add(&req->rxframe_list, q); -+ req->len = 0; -+ req++; -+ } -+ -+ return reqs; -+} -+ -+struct aicwf_rx_priv *aicwf_rx_init(void *arg) -+{ -+ struct aicwf_rx_priv *rx_priv; -+ rx_priv = kzalloc(sizeof(struct aicwf_rx_priv), GFP_KERNEL); -+ if (!rx_priv) -+ return NULL; -+ -+ rx_priv->sdiodev = (struct aic_sdio_dev *)arg; -+ aicwf_frame_queue_init(&rx_priv->rxq, 1, MAX_RXQLEN); -+ spin_lock_init(&rx_priv->rxqlock); -+ atomic_set(&rx_priv->rx_cnt, 0); -+ -+ INIT_LIST_HEAD(&rx_priv->rxframes_freequeue); -+ spin_lock_init(&rx_priv->freeq_lock); -+ rx_priv->recv_frames = aicwf_rxframe_queue_init(&rx_priv->rxframes_freequeue, MAX_REORD_RXFRAME); -+ if (!rx_priv->recv_frames) { -+ txrx_err("no enough buffer for free recv frame queue!\n"); -+ kfree(rx_priv); -+ return NULL; -+ } -+ spin_lock_init(&rx_priv->stas_reord_lock); -+ INIT_LIST_HEAD(&rx_priv->stas_reord_list); -+ -+ return rx_priv; -+} -+ -+ -+static void aicwf_recvframe_queue_deinit(struct list_head *q) -+{ -+ struct recv_msdu *req, *next; -+ -+ list_for_each_entry_safe(req, next, q, rxframe_list) { -+ list_del_init(&req->rxframe_list); -+ } -+} -+ -+void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv) -+{ -+ if (rx_priv->sdiodev->bus_if->busrx_thread) { -+ complete_all(&rx_priv->sdiodev->bus_if->busrx_trgg); -+ kthread_stop(rx_priv->sdiodev->bus_if->busrx_thread); -+ rx_priv->sdiodev->bus_if->busrx_thread = NULL; -+ } -+ -+ aicwf_frame_queue_flush(&rx_priv->rxq); -+ aicwf_recvframe_queue_deinit(&rx_priv->rxframes_freequeue); -+ if (rx_priv->recv_frames) -+ vfree(rx_priv->recv_frames); -+ -+ kfree(rx_priv); -+ //rx_priv = NULL; -+} -+ -+bool aicwf_rxframe_enqueue(struct device *dev, struct frame_queue *q, struct sk_buff *pkt) -+{ -+ return aicwf_frame_enq(dev, q, pkt, 0); -+} -+ -+ -+void aicwf_dev_skb_free(struct sk_buff *skb) -+{ -+ if (!skb) -+ return; -+ -+ dev_kfree_skb_any(skb); -+} -+ -+static struct sk_buff *aicwf_frame_queue_penq(struct frame_queue *pq, int prio, struct sk_buff *p) -+{ -+ struct sk_buff_head *q; -+ -+ if (pq->queuelist[prio].qlen >= pq->qmax) -+ return NULL; -+ -+ q = &pq->queuelist[prio]; -+ __skb_queue_tail(q, p); -+ pq->qcnt++; -+ if (pq->hi_prio < prio) -+ pq->hi_prio = (u16)prio; -+ -+ return p; -+} -+ -+void aicwf_frame_queue_flush(struct frame_queue *pq) -+{ -+ int prio; -+ struct sk_buff_head *q; -+ struct sk_buff *p, *next; -+ -+ for (prio = 0; prio < pq->num_prio; prio++) { -+ q = &pq->queuelist[prio]; -+ skb_queue_walk_safe(q, p, next) { -+ skb_unlink(p, q); -+ aicwf_dev_skb_free(p); -+ pq->qcnt--; -+ } -+ } -+} -+ -+void aicwf_frame_queue_init(struct frame_queue *pq, int num_prio, int max_len) -+{ -+ int prio; -+ -+ memset(pq, 0, offsetof(struct frame_queue, queuelist) + (sizeof(struct sk_buff_head) * num_prio)); -+ pq->num_prio = (u16)num_prio; -+ pq->qmax = (u16)max_len; -+ -+ for (prio = 0; prio < num_prio; prio++) { -+ skb_queue_head_init(&pq->queuelist[prio]); -+ } -+} -+ -+struct sk_buff *aicwf_frame_queue_peek_tail(struct frame_queue *pq, int *prio_out) -+{ -+ int prio; -+ -+ if (pq->qcnt == 0) -+ return NULL; -+ -+ for (prio = 0; prio < pq->hi_prio; prio++) -+ if (!skb_queue_empty(&pq->queuelist[prio])) -+ break; -+ -+ if (prio_out) -+ *prio_out = prio; -+ -+ return skb_peek_tail(&pq->queuelist[prio]); -+} -+ -+bool aicwf_is_framequeue_empty(struct frame_queue *pq) -+{ -+ int prio, len = 0; -+ -+ for (prio = 0; prio <= pq->hi_prio; prio++) -+ len += pq->queuelist[prio].qlen; -+ -+ if (len > 0) -+ return false; -+ else -+ return true; -+} -+ -+struct sk_buff *aicwf_frame_dequeue(struct frame_queue *pq) -+{ -+ struct sk_buff_head *q; -+ struct sk_buff *p; -+ int prio; -+ -+ if (pq->qcnt == 0) -+ return NULL; -+ -+ while ((prio = pq->hi_prio) > 0 && skb_queue_empty(&pq->queuelist[prio])) -+ pq->hi_prio--; -+ -+ q = &pq->queuelist[prio]; -+ p = __skb_dequeue(q); -+ if (p == NULL) -+ return NULL; -+ -+ pq->qcnt--; -+ -+ return p; -+} -+ -+static struct sk_buff *aicwf_skb_dequeue_tail(struct frame_queue *pq, int prio) -+{ -+ struct sk_buff_head *q = &pq->queuelist[prio]; -+ struct sk_buff *p = skb_dequeue_tail(q); -+ -+ if (!p) -+ return NULL; -+ -+ pq->qcnt--; -+ return p; -+} -+ -+bool aicwf_frame_enq(struct device *dev, struct frame_queue *q, struct sk_buff *pkt, int prio) -+{ -+ struct sk_buff *p = NULL; -+ int prio_modified = -1; -+ -+ if (q->queuelist[prio].qlen < q->qmax && q->qcnt < q->qmax) { -+ aicwf_frame_queue_penq(q, prio, pkt); -+ return true; -+ } -+ if (q->queuelist[prio].qlen >= q->qmax) { -+ prio_modified = prio; -+ } else if (q->qcnt >= q->qmax) { -+ p = aicwf_frame_queue_peek_tail(q, &prio_modified); -+ if (prio_modified > prio) -+ return false; -+ } -+ -+ if (prio_modified >= 0) { -+ if (prio_modified == prio) -+ return false; -+ -+ p = aicwf_skb_dequeue_tail(q, prio_modified); -+ aicwf_dev_skb_free(p); -+ -+ p = aicwf_frame_queue_penq(q, prio_modified, pkt); -+ if (p == NULL) -+ txrx_err("failed\n"); -+ } -+ -+ return p != NULL; -+} -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio_txrxif.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio_txrxif.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio_txrxif.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicsdio_txrxif.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,214 @@ -+/** -+ * aicwf_txrxif.h -+ * -+ * bus function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+#ifndef _AICWF_TXRXIF_H_ -+#define _AICWF_TXRXIF_H_ -+ -+#include -+#include -+#include "aicsdio.h" -+ -+#define CMD_BUF_MAX 1536 -+#define TXPKT_BLOCKSIZE 512 -+#define MAX_AGGR_TXPKT_LEN (1536*4) -+#define CMD_TX_TIMEOUT 5000 -+#define TX_ALIGNMENT 4 -+ -+#define RX_HWHRD_LEN 60 //58->60 word allined -+#define CCMP_OR_WEP_INFO 8 -+#define MAX_RXQLEN 2000 -+#define RX_ALIGNMENT 4 -+ -+#define DEBUG_ERROR_LEVEL 0 -+#define DEBUG_DEBUG_LEVEL 1 -+#define DEBUG_INFO_LEVEL 2 -+ -+#define DBG_LEVEL DEBUG_DEBUG_LEVEL -+ -+#define txrx_err(fmt, ...) pr_err("aicbsp: txrx_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__) -+#define sdio_err(fmt, ...) pr_err("aicbsp: sdio_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__) -+#define usb_err(fmt, ...) pr_err("aicbsp: usb_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__) -+#if DBG_LEVEL >= DEBUG_DEBUG_LEVEL -+#define sdio_dbg(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__) -+#define usb_dbg(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__) -+#else -+#define sdio_dbg(fmt, ...) -+#define usb_dbg(fmt, ...) -+#endif -+#if DBG_LEVEL >= DEBUG_INFO_LEVEL -+#define sdio_info(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__) -+#define usb_info(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__) -+#else -+#define sdio_info(fmt, ...) -+#define usb_info(fmt, ...) -+#endif -+ -+enum aicwf_bus_state { -+ BUS_DOWN_ST, -+ BUS_UP_ST -+}; -+ -+struct aicwf_bus_ops { -+ int (*start) (struct device *dev); -+ void (*stop) (struct device *dev); -+ int (*txdata) (struct device *dev, struct sk_buff *skb); -+ int (*txmsg) (struct device *dev, u8 *msg, uint len); -+}; -+ -+struct frame_queue { -+ u16 num_prio; -+ u16 hi_prio; -+ u16 qmax; /* max number of queued frames */ -+ u16 qcnt; -+ struct sk_buff_head queuelist[8]; -+}; -+ -+struct aicwf_bus { -+ union { -+ struct aic_sdio_dev *sdio; -+ struct aic_usb_dev *usb; -+ } bus_priv; -+ struct device *dev; -+ struct aicwf_bus_ops *ops; -+ enum aicwf_bus_state state; -+ u8 *cmd_buf; -+ struct completion bustx_trgg; -+ struct completion busrx_trgg; -+ struct task_struct *bustx_thread; -+ struct task_struct *busrx_thread; -+}; -+ -+struct aicwf_tx_priv { -+#ifdef AICWF_SDIO_SUPPORT -+ struct aic_sdio_dev *sdiodev; -+ int fw_avail_bufcnt; -+ //for cmd tx -+ u8 *cmd_buf; -+ uint cmd_len; -+ bool cmd_txstate; -+ bool cmd_tx_succ; -+ struct semaphore cmd_txsema; -+ wait_queue_head_t cmd_txdone_wait; -+ //for data tx -+ atomic_t tx_pktcnt; -+ -+ struct frame_queue txq; -+ spinlock_t txqlock; -+ struct semaphore txctl_sema; -+#endif -+#ifdef AICWF_USB_SUPPORT -+ struct aic_usb_dev *usbdev; -+#endif -+ struct sk_buff *aggr_buf; -+ atomic_t aggr_count; -+ u8 *head; -+ u8 *tail; -+}; -+ -+ -+#define MAX_REORD_RXFRAME 250 -+#define REORDER_UPDATE_TIME 50 -+#define AICWF_REORDER_WINSIZE 64 -+#define SN_LESS(a, b) (((a-b)&0x800) != 0) -+#define SN_EQUAL(a, b) (a == b) -+ -+struct reord_ctrl { -+ struct aicwf_rx_priv *rx_priv; -+ u8 enable; -+ u16 ind_sn; -+ u8 wsize_b; -+ spinlock_t reord_list_lock; -+ struct list_head reord_list; -+ struct timer_list reord_timer; -+ struct work_struct reord_timer_work; -+}; -+ -+struct reord_ctrl_info { -+ u8 mac_addr[6]; -+ struct reord_ctrl preorder_ctrl[8]; -+ struct list_head list; -+}; -+ -+struct recv_msdu { -+ struct sk_buff *pkt; -+ u8 tid; -+ u16 seq_num; -+ uint len; -+ u8 *rx_data; -+ //for pending rx reorder list -+ struct list_head reord_pending_list; -+ //for total frame list, when rxframe from busif, dequeue, when submit frame to net, enqueue -+ struct list_head rxframe_list; -+ struct reord_ctrl *preorder_ctrl; -+}; -+ -+struct aicwf_rx_priv { -+ struct aic_sdio_dev *sdiodev; -+ void *rwnx_vif; -+ atomic_t rx_cnt; -+ u32 data_len; -+ spinlock_t rxqlock; -+ struct frame_queue rxq; -+ -+ spinlock_t freeq_lock; -+ struct list_head rxframes_freequeue; -+ struct list_head stas_reord_list; -+ spinlock_t stas_reord_lock; -+ struct recv_msdu *recv_frames; -+}; -+ -+static inline int aicwf_bus_start(struct aicwf_bus *bus) -+{ -+ return bus->ops->start(bus->dev); -+} -+ -+static inline void aicwf_bus_stop(struct aicwf_bus *bus) -+{ -+ bus->ops->stop(bus->dev); -+} -+ -+static inline int aicwf_bus_txdata(struct aicwf_bus *bus, struct sk_buff *skb) -+{ -+ return bus->ops->txdata(bus->dev, skb); -+} -+ -+static inline int aicwf_bus_txmsg(struct aicwf_bus *bus, u8 *msg, uint len) -+{ -+ return bus->ops->txmsg(bus->dev, msg, len); -+} -+ -+static inline void aicwf_sched_timeout(u32 millisec) -+{ -+ ulong timeout = 0, expires = 0; -+ expires = jiffies + msecs_to_jiffies(millisec); -+ timeout = millisec; -+ -+ while (timeout) { -+ timeout = schedule_timeout(timeout); -+ if (time_after(jiffies, expires)) -+ break; -+ } -+} -+ -+int aicwf_bus_init(uint bus_hdrlen, struct device *dev); -+void aicwf_bus_deinit(struct device *dev); -+void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv); -+void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv); -+struct aicwf_tx_priv *aicwf_tx_init(void *arg); -+struct aicwf_rx_priv *aicwf_rx_init(void *arg); -+void aicwf_frame_queue_init(struct frame_queue *pq, int num_prio, int max_len); -+void aicwf_frame_queue_flush(struct frame_queue *pq); -+bool aicwf_frame_enq(struct device *dev, struct frame_queue *q, struct sk_buff *pkt, int prio); -+bool aicwf_rxframe_enqueue(struct device *dev, struct frame_queue *q, struct sk_buff *pkt); -+bool aicwf_is_framequeue_empty(struct frame_queue *pq); -+void aicwf_frame_tx(void *dev, struct sk_buff *skb); -+void aicwf_dev_skb_free(struct sk_buff *skb); -+struct sk_buff *aicwf_frame_dequeue(struct frame_queue *pq); -+struct sk_buff *aicwf_frame_queue_peek_tail(struct frame_queue *pq, int *prio_out); -+ -+#endif /* _AICWF_TXRXIF_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_firmware_array.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_firmware_array.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_firmware_array.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_firmware_array.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,16138 @@ -+#include -+ -+char fmacfw[259592] = { -+0x00, 0x38, 0x18, 0x00, 0x89, 0x01, 0x12, 0x00, 0xA5, 0xC6, 0x12, 0x00, 0xA1, 0xCA, 0x12, 0x00, 0xA9, 0xCA, 0x12, 0x00, -+0xB1, 0xCA, 0x12, 0x00, 0xB9, 0xCA, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0xA5, 0xC6, 0x12, 0x00, 0xA5, 0xC6, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xC6, 0x12, 0x00, -+0xA5, 0xC6, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xBB, 0x12, 0x00, 0x19, 0x1E, 0x14, 0x00, 0x35, 0xEE, 0x12, 0x00, -+0x49, 0xED, 0x12, 0x00, 0x79, 0x5C, 0x13, 0x00, 0x99, 0x1A, 0x12, 0x00, 0x79, 0x5C, 0x13, 0x00, 0x49, 0x11, 0x12, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x99, 0x1A, 0x12, 0x00, 0x99, 0x1A, 0x12, 0x00, 0x65, 0x5A, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xED, 0x12, 0x00, 0x45, 0xED, 0x12, 0x00, -+0x45, 0xED, 0x12, 0x00, 0x45, 0xED, 0x12, 0x00, 0x45, 0xED, 0x12, 0x00, 0x7D, 0x4A, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x99, 0x1A, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x1A, 0x12, 0x00, 0x99, 0x1A, 0x12, 0x00, 0x99, 0x1A, 0x12, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x99, 0x1A, 0x12, 0x00, 0x8D, 0x52, 0x12, 0x00, 0x79, 0x51, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0xCD, 0x5B, 0x12, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x05, 0x48, 0x00, 0x68, 0x10, 0xF0, 0x00, 0x4F, -+0x0C, 0xBF, 0x04, 0x48, 0x20, 0xF0, 0x7F, 0x40, 0x80, 0xF3, 0x08, 0x88, 0x02, 0x48, 0x00, 0x47, 0x44, 0x01, 0x50, 0x40, -+0x00, 0x38, 0x18, 0x00, 0x05, 0xC7, 0x12, 0x00, 0xF0, 0xB4, 0x86, 0x07, 0x46, 0xD0, 0x54, 0x1E, 0x00, 0x2A, 0x3C, 0xD0, -+0xCA, 0xB2, 0x03, 0x46, 0x01, 0xE0, 0x01, 0x3C, 0x37, 0xD3, 0x03, 0xF8, 0x01, 0x2B, 0x9D, 0x07, 0xF9, 0xD1, 0x03, 0x2C, -+0x2A, 0xD9, 0xCD, 0xB2, 0x45, 0xEA, 0x05, 0x25, 0x0F, 0x2C, 0x45, 0xEA, 0x05, 0x45, 0x34, 0xD9, 0xA4, 0xF1, 0x10, 0x02, -+0x22, 0xF0, 0x0F, 0x0C, 0x03, 0xF1, 0x20, 0x07, 0x16, 0x09, 0x67, 0x44, 0x03, 0xF1, 0x10, 0x02, 0x42, 0xE9, 0x04, 0x55, -+0x42, 0xE9, 0x02, 0x55, 0x10, 0x32, 0xBA, 0x42, 0xF8, 0xD1, 0x72, 0x1C, 0x14, 0xF0, 0x0C, 0x0F, 0x03, 0xEB, 0x02, 0x12, -+0x04, 0xF0, 0x0F, 0x06, 0x13, 0xD0, 0x33, 0x1F, 0x23, 0xF0, 0x03, 0x03, 0x04, 0x33, 0x13, 0x44, 0x42, 0xF8, 0x04, 0x5B, -+0x93, 0x42, 0xFB, 0xD1, 0x06, 0xF0, 0x03, 0x04, 0x2C, 0xB1, 0xCA, 0xB2, 0x1C, 0x44, 0x03, 0xF8, 0x01, 0x2B, 0x9C, 0x42, -+0xFB, 0xD1, 0xF0, 0xBC, 0x70, 0x47, 0x34, 0x46, 0x13, 0x46, 0x00, 0x2C, 0xF3, 0xD1, 0xF8, 0xE7, 0x14, 0x46, 0x03, 0x46, -+0xC1, 0xE7, 0x1A, 0x46, 0x26, 0x46, 0xE0, 0xE7, 0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0x68, 0x91, 0x4F, 0x4F, 0xD9, 0xF8, -+0x00, 0x60, 0xDF, 0xF8, 0x64, 0xC1, 0x33, 0x89, 0xD6, 0xF8, 0x34, 0xE0, 0xC7, 0xF8, 0x10, 0xE0, 0xD6, 0xE9, 0x09, 0x10, -+0xD6, 0xE9, 0x0B, 0x45, 0x39, 0x60, 0xC9, 0x08, 0x03, 0x29, 0x78, 0x60, 0x4F, 0xEA, 0xD0, 0x00, 0x38, 0xBF, 0x03, 0x21, -+0xBC, 0x60, 0x03, 0x28, 0x4F, 0xEA, 0xD4, 0x04, 0x38, 0xBF, 0x03, 0x20, 0xFD, 0x60, 0x03, 0x2C, 0x4F, 0xEA, 0xD5, 0x05, -+0x4F, 0xF0, 0x54, 0x02, 0x4F, 0xEA, 0xDE, 0x07, 0x2C, 0xF0, 0x03, 0x0C, 0x38, 0xBF, 0x03, 0x24, 0xDF, 0xF8, 0x1C, 0xE1, -+0xDF, 0xF8, 0x1C, 0x81, 0xDF, 0xF8, 0x1C, 0xA1, 0xC8, 0xF8, 0x00, 0x10, 0x03, 0x2D, 0x03, 0xFB, 0x02, 0x22, 0x38, 0xBF, -+0x03, 0x25, 0x62, 0x44, 0x03, 0x2F, 0x38, 0xBF, 0x03, 0x27, 0x72, 0x45, 0xC8, 0xE9, 0x01, 0x04, 0xC8, 0xE9, 0x03, 0x57, -+0xCA, 0xF8, 0x00, 0xC0, 0x4F, 0xD8, 0x01, 0x33, 0xDF, 0xF8, 0xF4, 0xE0, 0x2E, 0x4A, 0xDF, 0xF8, 0xF4, 0x80, 0xDF, 0xF8, -+0xF4, 0x90, 0x4F, 0xF0, 0x58, 0x0C, 0x0C, 0xFB, 0x03, 0xE3, 0xD2, 0xF8, 0x00, 0xC0, 0x2A, 0x4A, 0x13, 0x60, 0x4F, 0xF4, -+0xAC, 0x72, 0x02, 0xFB, 0x01, 0x33, 0x02, 0xFB, 0x00, 0x30, 0x02, 0xFB, 0x04, 0x04, 0x02, 0xFB, 0x05, 0x45, 0xDC, 0xF8, -+0x00, 0x10, 0xC8, 0xF8, 0x00, 0x50, 0x02, 0xFB, 0x07, 0x52, 0xC9, 0xF8, 0x00, 0x40, 0x21, 0x4F, 0x21, 0x4D, 0x22, 0x4C, -+0x38, 0x60, 0x2B, 0x60, 0xC4, 0xF8, 0x00, 0xE0, 0x41, 0xB9, 0xDC, 0xF8, 0x04, 0x30, 0x04, 0x33, 0x11, 0x1D, 0x23, 0xF0, -+0x03, 0x03, 0xCC, 0xF8, 0x00, 0x10, 0x1A, 0x44, 0xDC, 0xF8, 0x08, 0x30, 0x13, 0xB9, 0x04, 0x32, 0xCC, 0xF8, 0x08, 0x20, -+0x18, 0x4B, 0xF2, 0x68, 0x1A, 0x60, 0x33, 0x78, 0x02, 0x2B, 0x0E, 0xD0, 0x01, 0x2B, 0x01, 0xD0, 0xBD, 0xE8, 0xF0, 0x87, -+0x72, 0x69, 0x00, 0x2A, 0xFA, 0xD0, 0x13, 0x49, 0x91, 0x42, 0xF7, 0xD9, 0xBD, 0xE8, 0xF0, 0x47, 0x11, 0x48, 0x05, 0xF0, -+0xC1, 0xBF, 0x32, 0x69, 0xF3, 0xE7, 0x71, 0x46, 0x0F, 0x48, 0x05, 0xF0, 0xBB, 0xFF, 0xD9, 0xF8, 0x00, 0x60, 0xD8, 0xF8, -+0x00, 0x10, 0x33, 0x89, 0xD8, 0xE9, 0x01, 0x04, 0xD8, 0xE9, 0x03, 0x57, 0x01, 0x33, 0xA1, 0xE7, 0x7C, 0x28, 0x17, 0x00, -+0x30, 0x36, 0x17, 0x00, 0xEC, 0x57, 0x18, 0x00, 0xF4, 0x57, 0x18, 0x00, 0xF0, 0x57, 0x18, 0x00, 0x14, 0x63, 0x18, 0x00, -+0x00, 0x38, 0x18, 0x00, 0x00, 0x38, 0x18, 0x00, 0x44, 0x76, 0x15, 0x00, 0x18, 0x76, 0x15, 0x00, 0x78, 0x36, 0x17, 0x00, -+0x2B, 0x07, 0x18, 0x00, 0x00, 0x24, 0x18, 0x00, 0x8C, 0x1F, 0x17, 0x00, 0x40, 0x61, 0x17, 0x00, 0xE0, 0x9F, 0x18, 0x00, -+0xFC, 0x57, 0x18, 0x00, 0xF8, 0x57, 0x18, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x49, 0x4C, 0x4A, 0x49, 0x4A, 0x4E, 0x4B, 0x4A, -+0x4B, 0x4D, 0x4C, 0x48, 0x0C, 0x60, 0x04, 0xF1, 0x44, 0x07, 0x21, 0x1D, 0xD4, 0xF8, 0xD0, 0x30, 0x37, 0x60, 0x04, 0xF1, -+0x80, 0x07, 0x11, 0x60, 0x2F, 0x60, 0x47, 0x49, 0x47, 0x4A, 0x04, 0xF1, 0x90, 0x05, 0x23, 0xF0, 0x7F, 0x43, 0x05, 0x60, -+0x04, 0xF1, 0xA8, 0x00, 0x08, 0x60, 0x23, 0xF0, 0xFF, 0x03, 0x04, 0xF1, 0xAA, 0x01, 0x11, 0x60, 0x83, 0xB1, 0x94, 0xF8, -+0xD1, 0x30, 0x23, 0xB1, 0x3F, 0x4A, 0x53, 0x6D, 0x23, 0xF0, 0x01, 0x03, 0x53, 0x65, 0x94, 0xF8, 0xD2, 0x30, 0x00, 0x2B, -+0x5B, 0xD1, 0x3B, 0x4B, 0x4F, 0xF0, 0x80, 0x62, 0xC3, 0xF8, 0x10, 0x21, 0x39, 0x4D, 0x3A, 0x4F, 0xD5, 0xF8, 0x30, 0x32, -+0xDF, 0xF8, 0xF8, 0x80, 0x98, 0x47, 0x01, 0x21, 0x00, 0x20, 0x05, 0xF0, 0x5F, 0xFF, 0x00, 0x20, 0x05, 0xF0, 0x9A, 0xFF, -+0x01, 0x21, 0x02, 0x20, 0x05, 0xF0, 0x58, 0xFF, 0x02, 0x20, 0x05, 0xF0, 0x93, 0xFF, 0x01, 0x21, 0x03, 0x20, 0x05, 0xF0, -+0x51, 0xFF, 0x03, 0x20, 0x05, 0xF0, 0x8C, 0xFF, 0x3B, 0x68, 0x03, 0xF0, 0x0F, 0x03, 0xA3, 0xF1, 0x0A, 0x03, 0xB3, 0xFA, -+0x83, 0xF3, 0x5B, 0x09, 0x88, 0xF8, 0x02, 0x30, 0x25, 0xF0, 0x0E, 0xFA, 0x05, 0xF0, 0x90, 0xFA, 0x06, 0xF0, 0x54, 0xF8, -+0xD5, 0xF8, 0x74, 0x32, 0x98, 0x47, 0x94, 0xF8, 0x44, 0x10, 0x23, 0x48, 0x24, 0xF0, 0xEE, 0xF8, 0x07, 0xF0, 0x8C, 0xF8, -+0x06, 0xF0, 0xA8, 0xF9, 0x98, 0xF8, 0x02, 0x30, 0x0B, 0xB3, 0xD5, 0xF8, 0x6C, 0x34, 0x98, 0x47, 0x1D, 0x4A, 0x1E, 0x49, -+0x13, 0x68, 0x23, 0xF0, 0x08, 0x03, 0x13, 0x60, 0x3B, 0x68, 0x23, 0xF0, 0x0F, 0x03, 0x3B, 0x60, 0x02, 0x20, 0x24, 0xF0, -+0x27, 0xF9, 0x33, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0x02, 0xD1, 0x17, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xD5, 0xF8, 0x80, 0x32, -+0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0x0D, 0x4A, 0x53, 0x6D, 0x23, 0xF0, 0x02, 0x03, 0x53, 0x65, 0x9D, 0xE7, 0x11, 0x49, -+0x02, 0x20, 0x24, 0xF0, 0x11, 0xF9, 0xE8, 0xE7, 0x2C, 0x19, 0x17, 0x00, 0x34, 0x36, 0x17, 0x00, 0x78, 0x36, 0x17, 0x00, -+0xC8, 0x35, 0x17, 0x00, 0x30, 0x36, 0x17, 0x00, 0xAC, 0x35, 0x17, 0x00, 0x74, 0x36, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x00, 0x00, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x1C, 0x00, 0x58, 0x40, 0x70, 0x76, 0x15, 0x00, 0x10, 0x00, 0x58, 0x40, -+0x80, 0x76, 0x15, 0x00, 0x00, 0x41, 0x04, 0x40, 0x8C, 0x76, 0x15, 0x00, 0x3C, 0x36, 0x17, 0x00, 0xF8, 0xB5, 0x20, 0x4B, -+0x04, 0x46, 0x1E, 0x68, 0x1D, 0x68, 0x00, 0xF0, 0xAB, 0xFE, 0x07, 0x46, 0x00, 0xF0, 0xAA, 0xFE, 0x01, 0x2C, 0xC6, 0xF3, -+0x03, 0x26, 0xC5, 0xF3, 0xC0, 0x65, 0x14, 0xD0, 0x02, 0x2C, 0x0E, 0xD0, 0x3C, 0xB1, 0x18, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x1C, 0xDB, 0x00, 0x20, 0xF8, 0xBD, 0x90, 0xB9, 0x05, 0xBB, 0x70, 0x1E, 0x18, 0xBF, 0x01, 0x20, -+0xF8, 0xBD, 0x01, 0x2E, 0x0D, 0xD0, 0x68, 0x1D, 0xF8, 0xBD, 0x30, 0xB9, 0x01, 0x2E, 0x17, 0xD0, 0x00, 0x2F, 0x0C, 0xBF, -+0x03, 0x20, 0x09, 0x20, 0xF8, 0xBD, 0x0B, 0x20, 0xF8, 0xBD, 0x0A, 0x20, 0xF8, 0xBD, 0x00, 0x2D, 0x14, 0xBF, 0x07, 0x20, -+0x04, 0x20, 0xF8, 0xBD, 0x07, 0x49, 0x08, 0x48, 0x40, 0xF2, 0xB5, 0x12, 0x24, 0xF0, 0xDC, 0xFA, 0x00, 0x20, 0xF8, 0xBD, -+0x08, 0x20, 0xF8, 0xBD, 0x02, 0x20, 0xF8, 0xBD, 0x00, 0x00, 0x33, 0x40, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x64, 0x7D, 0x15, 0x00, 0x10, 0xB4, 0x09, 0x49, 0x0B, 0x69, 0x83, 0xB0, 0x18, 0x44, 0x20, 0x24, 0x01, 0x94, 0x01, 0x9B, -+0x5A, 0x1E, 0x01, 0x92, 0x00, 0x2B, 0xFA, 0xD1, 0x0B, 0x69, 0x1B, 0x1A, 0x00, 0x2B, 0xF5, 0xDB, 0x03, 0xB0, 0x5D, 0xF8, -+0x04, 0x4B, 0x70, 0x47, 0x00, 0x10, 0x50, 0x40, 0x08, 0xB5, 0xFF, 0xF7, 0x9D, 0xFF, 0x03, 0x4B, 0x1A, 0x78, 0x82, 0x42, -+0x18, 0xBF, 0x18, 0x70, 0x08, 0xBD, 0x00, 0xBF, 0x60, 0x25, 0x17, 0x00, 0x38, 0xB5, 0x10, 0x4B, 0x10, 0x4C, 0x18, 0x68, -+0xC0, 0xF3, 0x01, 0x60, 0xFF, 0xF7, 0x8C, 0xFF, 0x08, 0x22, 0x05, 0x46, 0x00, 0x21, 0x20, 0x46, 0xFF, 0xF7, 0xB6, 0xFD, -+0x0B, 0x48, 0x0C, 0x4A, 0x00, 0xEB, 0x05, 0x10, 0xFF, 0x21, 0xC3, 0x88, 0x80, 0x88, 0x10, 0x60, 0xC3, 0xF3, 0x85, 0x12, -+0x03, 0xF0, 0x3F, 0x03, 0x1A, 0x44, 0x21, 0x70, 0x4F, 0xF4, 0x96, 0x63, 0xB3, 0xFB, 0xF2, 0xF3, 0x63, 0x70, 0x38, 0xBD, -+0x00, 0x00, 0x33, 0x40, 0x60, 0x25, 0x17, 0x00, 0x98, 0x76, 0x15, 0x00, 0x6C, 0x00, 0x34, 0x40, 0x01, 0x4B, 0x58, 0x78, -+0x70, 0x47, 0x00, 0xBF, 0x60, 0x25, 0x17, 0x00, 0x10, 0xB4, 0x13, 0x4B, 0x13, 0x49, 0x11, 0x22, 0x1A, 0x60, 0x08, 0x69, -+0x83, 0xB0, 0x0A, 0x30, 0x20, 0x24, 0x00, 0x94, 0x00, 0x9B, 0x5A, 0x1E, 0x00, 0x92, 0x00, 0x2B, 0xFA, 0xD1, 0x0A, 0x69, -+0x12, 0x1A, 0x00, 0x2A, 0xF5, 0xDB, 0x0A, 0x4A, 0x0A, 0x4C, 0x13, 0x60, 0x09, 0x69, 0x20, 0x20, 0x0A, 0x31, 0x01, 0x90, -+0x01, 0x9B, 0x5A, 0x1E, 0x01, 0x92, 0x00, 0x2B, 0xFA, 0xD1, 0x23, 0x69, 0x5B, 0x1A, 0x00, 0x2B, 0xF5, 0xDB, 0x03, 0xB0, -+0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0xBF, 0x18, 0x00, 0x34, 0x40, 0x00, 0x10, 0x50, 0x40, 0x16, 0x4A, 0x13, 0x68, -+0x43, 0xF4, 0x80, 0x53, 0x10, 0xB4, 0x13, 0x60, 0x00, 0xBF, 0x02, 0xF5, 0x99, 0x42, 0x13, 0x68, 0x43, 0xF0, 0x00, 0x53, -+0x13, 0x60, 0x00, 0xBF, 0x10, 0x4B, 0x11, 0x48, 0x03, 0xF5, 0x00, 0x64, 0xC0, 0x1A, 0x1A, 0x18, 0x53, 0xF8, 0x04, 0x1B, -+0x11, 0x60, 0xA3, 0x42, 0xF9, 0xD1, 0x00, 0xBF, 0x09, 0x4B, 0x1A, 0x68, 0x42, 0xF4, 0x00, 0x22, 0x1A, 0x60, 0x00, 0xBF, -+0x1A, 0x68, 0x22, 0xF4, 0x80, 0x52, 0x1A, 0x60, 0x00, 0xBF, 0x07, 0x4A, 0x5D, 0xF8, 0x04, 0x4B, 0x13, 0x68, 0x23, 0xF0, -+0x00, 0x53, 0x13, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x90, 0xB3, 0x33, 0x40, 0xB0, 0x05, 0x17, 0x00, 0x00, 0xA0, 0x33, 0x40, -+0x10, 0x00, 0x34, 0x40, 0x2D, 0xE9, 0xF0, 0x41, 0x07, 0x46, 0x15, 0x46, 0x1C, 0x46, 0x9D, 0xF8, 0x18, 0x80, 0x0E, 0x46, -+0xFF, 0xF7, 0x94, 0xFF, 0x6C, 0x4A, 0x13, 0x68, 0x01, 0x2F, 0x23, 0xF0, 0x40, 0x03, 0x13, 0x60, 0x00, 0xF0, 0x98, 0x80, -+0x69, 0x4A, 0x6A, 0x49, 0x13, 0x68, 0x23, 0xF4, 0xE0, 0x33, 0x43, 0xF4, 0x40, 0x43, 0x13, 0x60, 0x0B, 0x68, 0x02, 0xF5, -+0xD9, 0x32, 0x02, 0xF5, 0xA2, 0x72, 0x43, 0xF0, 0x01, 0x03, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF4, 0x80, 0x73, 0x13, 0x60, -+0x61, 0x4A, 0x10, 0x68, 0x20, 0xF4, 0xFF, 0x40, 0x20, 0xF0, 0x7F, 0x00, 0x4F, 0xF0, 0x80, 0x63, 0xB3, 0xFB, 0xF5, 0xF3, -+0xC3, 0xF3, 0x0E, 0x03, 0x03, 0x43, 0x01, 0x2C, 0x13, 0x60, 0x60, 0xD0, 0x02, 0x2C, 0x48, 0xD0, 0x00, 0x25, 0x59, 0x4B, -+0x1E, 0x68, 0x26, 0xF0, 0x03, 0x06, 0x35, 0x43, 0x1D, 0x60, 0x00, 0x23, 0x56, 0x4A, 0x57, 0x49, 0x13, 0x60, 0x0B, 0x68, -+0x56, 0x4D, 0x57, 0x48, 0x57, 0x4E, 0x22, 0x06, 0x02, 0xF0, 0x40, 0x72, 0x23, 0xF0, 0x40, 0x73, 0x13, 0x43, 0x0B, 0x60, -+0x29, 0x68, 0x23, 0x04, 0x21, 0xF4, 0x40, 0x31, 0x03, 0xF4, 0x40, 0x33, 0x0B, 0x43, 0x2B, 0x60, 0x03, 0x68, 0x23, 0xF0, -+0x80, 0x43, 0x03, 0x60, 0x31, 0x68, 0x05, 0xF5, 0x82, 0x35, 0x04, 0xF0, 0x0F, 0x03, 0x21, 0xF0, 0x0F, 0x01, 0x05, 0xF5, -+0x88, 0x75, 0x0B, 0x43, 0x33, 0x60, 0x2B, 0x68, 0x23, 0xF0, 0x40, 0x73, 0x1A, 0x43, 0x2A, 0x60, 0xEC, 0xB9, 0x50, 0xF8, -+0x08, 0x3C, 0x45, 0x49, 0x45, 0x4A, 0x23, 0xF0, 0x7F, 0x43, 0x43, 0xF0, 0xC8, 0x53, 0x40, 0xF8, 0x08, 0x3C, 0x0B, 0x68, -+0x23, 0xF0, 0x30, 0x03, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF4, 0x7F, 0x43, 0x43, 0xF4, 0x1C, 0x43, 0x13, 0x60, 0xBD, 0xE8, -+0xF0, 0x81, 0xAD, 0x1B, 0x00, 0x2D, 0x42, 0xDD, 0x0A, 0x2D, 0xCC, 0xBF, 0x00, 0x25, 0x01, 0x25, 0xAF, 0xE7, 0x01, 0x2C, -+0x41, 0xD0, 0x38, 0x4A, 0x38, 0x49, 0x13, 0x68, 0x38, 0x48, 0x23, 0xF0, 0x7F, 0x43, 0x43, 0xF0, 0x60, 0x63, 0x13, 0x60, -+0x08, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0xF5, 0x28, 0x42, 0xB5, 0x42, 0x53, 0x6B, 0x88, 0xBF, 0x01, 0x21, 0x23, 0xF0, -+0x03, 0x03, 0x98, 0xBF, 0x02, 0x21, 0x43, 0xEA, 0x01, 0x03, 0x02, 0xF1, 0x34, 0x02, 0x13, 0x60, 0x94, 0xBF, 0x01, 0x23, -+0x00, 0x23, 0x95, 0xE7, 0x1D, 0x49, 0x1E, 0x48, 0x0B, 0x68, 0x23, 0xF4, 0xE0, 0x33, 0x43, 0xF4, 0xC0, 0x33, 0x0B, 0x60, -+0x03, 0x68, 0x01, 0xF5, 0xD9, 0x31, 0x01, 0xF5, 0xA2, 0x71, 0x23, 0xF0, 0x01, 0x03, 0x03, 0x60, 0x0B, 0x68, 0x18, 0xF0, -+0x04, 0x0F, 0x43, 0xF4, 0x80, 0x73, 0x0B, 0x60, 0x3F, 0xF4, 0x64, 0xAF, 0x13, 0x68, 0x43, 0xF0, 0x40, 0x03, 0x13, 0x60, -+0x5E, 0xE7, 0x15, 0xF1, 0x0A, 0x0F, 0xB4, 0xBF, 0x03, 0x25, 0x02, 0x25, 0x6B, 0xE7, 0x1A, 0x48, 0x14, 0x49, 0x03, 0x68, -+0x14, 0x4A, 0x23, 0xF0, 0x7F, 0x43, 0x43, 0xF0, 0xC0, 0x53, 0x03, 0x60, 0x0B, 0x68, 0x23, 0xF0, 0x30, 0x03, 0x43, 0xF0, -+0x10, 0x03, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF4, 0x7F, 0x43, 0x43, 0xF4, 0xD8, 0x43, 0x13, 0x60, 0xBD, 0xE8, 0xF0, 0x81, -+0x24, 0x03, 0x32, 0x40, 0x4C, 0x00, 0x32, 0x40, 0x20, 0x08, 0x33, 0x40, 0x4C, 0x08, 0x33, 0x40, 0x80, 0xB0, 0x33, 0x40, -+0x50, 0x08, 0x33, 0x40, 0x24, 0x08, 0x33, 0x40, 0x10, 0x03, 0x32, 0x40, 0x0C, 0x08, 0x33, 0x40, 0x00, 0x08, 0x33, 0x40, -+0x08, 0x00, 0x34, 0x40, 0x8C, 0x08, 0x33, 0x40, 0x34, 0x08, 0x33, 0x40, 0x18, 0x08, 0x33, 0x40, 0x06, 0x0C, 0x8E, 0x01, -+0x04, 0x08, 0x33, 0x40, 0x44, 0x49, 0x45, 0x4A, 0x0B, 0x68, 0x23, 0xF4, 0xFC, 0x63, 0x70, 0xB4, 0x0B, 0x60, 0x13, 0x68, -+0x42, 0x4C, 0x43, 0x4D, 0x43, 0x4E, 0x23, 0xF4, 0xE0, 0x23, 0x43, 0xF4, 0x80, 0x33, 0x13, 0x60, 0x13, 0x68, 0x23, 0xF4, -+0xE0, 0x03, 0x43, 0xF4, 0x00, 0x13, 0x13, 0x60, 0x23, 0x68, 0xA1, 0xF5, 0x0F, 0x41, 0x23, 0xF4, 0x00, 0x03, 0x23, 0x60, -+0x04, 0x39, 0x0C, 0x23, 0x2B, 0x60, 0x0B, 0x68, 0x32, 0x6A, 0x23, 0xF4, 0xFE, 0x43, 0x23, 0xF0, 0x7F, 0x03, 0x13, 0x43, -+0x40, 0xF6, 0xB4, 0x12, 0x90, 0x42, 0x0B, 0x60, 0x34, 0x4B, 0x26, 0xD0, 0x72, 0x6A, 0x1A, 0x60, 0xA0, 0xF6, 0x6C, 0x13, -+0x3C, 0x2B, 0x22, 0xD8, 0xDF, 0xE8, 0x03, 0xF0, 0x40, 0x21, 0x21, 0x21, 0x21, 0x40, 0x21, 0x21, 0x21, 0x21, 0x40, 0x21, -+0x21, 0x21, 0x21, 0x40, 0x21, 0x21, 0x21, 0x21, 0x40, 0x21, 0x21, 0x21, 0x21, 0x40, 0x21, 0x21, 0x21, 0x21, 0x40, 0x21, -+0x21, 0x21, 0x21, 0x47, 0x21, 0x21, 0x21, 0x21, 0x47, 0x21, 0x21, 0x21, 0x21, 0x47, 0x21, 0x21, 0x21, 0x21, 0x47, 0x21, -+0x21, 0x21, 0x21, 0x47, 0x21, 0x21, 0x21, 0x21, 0x47, 0x00, 0x21, 0x4A, 0x1A, 0x60, 0x21, 0x4A, 0x21, 0x49, 0x13, 0x68, -+0x91, 0xF8, 0xB4, 0x10, 0x23, 0xF0, 0x04, 0x03, 0x13, 0x60, 0x99, 0xB1, 0x1E, 0x49, 0x1F, 0x4B, 0x0A, 0x68, 0x22, 0xF4, -+0xFE, 0x62, 0x0A, 0x60, 0x1A, 0x68, 0x22, 0xF0, 0x0F, 0x02, 0x42, 0xF0, 0x01, 0x02, 0x1A, 0x60, 0x9A, 0x68, 0x22, 0xF0, -+0x0F, 0x02, 0x9A, 0x60, 0xDA, 0x68, 0x22, 0xF0, 0x0F, 0x02, 0xDA, 0x60, 0x70, 0xBC, 0x70, 0x47, 0x15, 0x49, 0x16, 0x4B, -+0xB0, 0x6A, 0x72, 0x6B, 0x08, 0x60, 0x1A, 0x60, 0xD9, 0xE7, 0x12, 0x4B, 0xF4, 0x6A, 0xB1, 0x6B, 0x11, 0x4A, 0x1C, 0x60, -+0x40, 0xF6, 0xA8, 0x13, 0x98, 0x42, 0x11, 0x60, 0xCF, 0xD1, 0x0F, 0x4B, 0x11, 0x22, 0x1A, 0x60, 0xCB, 0xE7, 0x00, 0xBF, -+0x04, 0x40, 0x34, 0x40, 0x34, 0x21, 0x34, 0x40, 0x2C, 0x20, 0x34, 0x40, 0x00, 0xB3, 0x33, 0x40, 0xDC, 0x18, 0x17, 0x00, -+0x20, 0x03, 0x33, 0x40, 0x1B, 0x88, 0xB3, 0x01, 0x30, 0x20, 0x34, 0x40, 0x2C, 0x19, 0x17, 0x00, 0x78, 0x40, 0x34, 0x40, -+0x00, 0x30, 0x50, 0x40, 0x30, 0x40, 0x34, 0x40, 0x2C, 0x40, 0x34, 0x40, 0x24, 0x01, 0x58, 0x40, 0x70, 0x47, 0x00, 0xBF, -+0x3A, 0x49, 0x3B, 0x4A, 0x0B, 0x68, 0x23, 0xF4, 0xFC, 0x63, 0x43, 0xF4, 0xA8, 0x63, 0x30, 0xB4, 0x0B, 0x60, 0x13, 0x68, -+0x37, 0x4C, 0x38, 0x4D, 0x23, 0xF4, 0xE0, 0x23, 0x43, 0xF4, 0x00, 0x33, 0x13, 0x60, 0x13, 0x68, 0x23, 0xF4, 0xE0, 0x03, -+0x13, 0x60, 0x23, 0x68, 0x33, 0x4A, 0xA1, 0xF5, 0x0F, 0x41, 0x43, 0xF4, 0x00, 0x03, 0x23, 0x60, 0x04, 0x39, 0x0C, 0x23, -+0x2B, 0x60, 0x0B, 0x68, 0xD4, 0x6C, 0x23, 0xF4, 0xFE, 0x43, 0x23, 0xF0, 0x7F, 0x03, 0x23, 0x43, 0x41, 0xF2, 0xC8, 0x44, -+0xA0, 0x42, 0x0B, 0x60, 0x40, 0xD8, 0x2A, 0x4B, 0x12, 0x6C, 0x1A, 0x60, 0x29, 0x4A, 0x2A, 0x4C, 0x13, 0x68, 0x2A, 0x4D, -+0x2A, 0x48, 0x2B, 0x49, 0x23, 0xF0, 0x80, 0x63, 0x13, 0x60, 0x13, 0x68, 0x94, 0xF8, 0xB4, 0x40, 0x23, 0xF0, 0x0F, 0x03, -+0x43, 0xF0, 0x08, 0x03, 0x13, 0x60, 0x2B, 0x68, 0x23, 0xF0, 0xC0, 0x63, 0x43, 0xF0, 0x80, 0x63, 0x2B, 0x60, 0x03, 0x68, -+0x43, 0xF4, 0x70, 0x63, 0x03, 0x60, 0x0B, 0x68, 0x43, 0xF0, 0x04, 0x03, 0x0B, 0x60, 0xDC, 0xB1, 0x01, 0xF5, 0x01, 0x51, -+0x1D, 0x4B, 0x8A, 0x68, 0x22, 0xF4, 0xFE, 0x62, 0x42, 0xF4, 0x88, 0x62, 0x8A, 0x60, 0x1A, 0x68, 0x22, 0xF0, 0x0F, 0x02, -+0x42, 0xF0, 0x03, 0x02, 0x1A, 0x60, 0x9A, 0x68, 0x22, 0xF0, 0x0F, 0x02, 0x42, 0xF0, 0x03, 0x02, 0x9A, 0x60, 0xDA, 0x68, -+0x22, 0xF0, 0x0F, 0x02, 0x42, 0xF0, 0x03, 0x02, 0x08, 0x31, 0xDA, 0x60, 0x30, 0xBC, 0x70, 0x47, 0x41, 0xF2, 0x44, 0x63, -+0x98, 0x42, 0x08, 0x4B, 0x94, 0xBF, 0x52, 0x6C, 0x92, 0x6C, 0x1A, 0x60, 0xB8, 0xE7, 0x00, 0xBF, 0x04, 0x40, 0x34, 0x40, -+0x34, 0x21, 0x34, 0x40, 0x2C, 0x20, 0x34, 0x40, 0x00, 0xB3, 0x33, 0x40, 0xDC, 0x18, 0x17, 0x00, 0x30, 0x40, 0x34, 0x40, -+0x38, 0x40, 0x34, 0x40, 0x2C, 0x19, 0x17, 0x00, 0x3C, 0x40, 0x34, 0x40, 0x08, 0x01, 0x58, 0x40, 0x30, 0x20, 0x34, 0x40, -+0x00, 0x30, 0x50, 0x40, 0x70, 0x47, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x4F, 0x85, 0xB0, 0x0F, 0x46, 0x9D, 0xF8, 0x3C, 0x10, -+0x02, 0x91, 0xCD, 0xE9, 0x00, 0x23, 0x05, 0x46, 0x14, 0x46, 0x1E, 0x46, 0x02, 0x46, 0x3B, 0x46, 0xAE, 0x49, 0xAF, 0x48, -+0x9D, 0xF8, 0x38, 0xA0, 0xDF, 0xF8, 0x08, 0x83, 0xDF, 0xF8, 0x08, 0x93, 0x23, 0xF0, 0x4C, 0xFD, 0xAB, 0x49, 0x22, 0x46, -+0x04, 0x20, 0x23, 0xF0, 0x97, 0xFD, 0x30, 0x46, 0xFF, 0xF7, 0x06, 0xFD, 0x39, 0x46, 0x33, 0x46, 0xD8, 0xF8, 0x40, 0x71, -+0xCD, 0xF8, 0x00, 0xA0, 0x22, 0x46, 0x28, 0x46, 0xB8, 0x47, 0x99, 0xF8, 0x2A, 0x30, 0xAB, 0x42, 0x0A, 0xD0, 0xD8, 0xF8, -+0x80, 0x34, 0x28, 0x46, 0x98, 0x47, 0x99, 0xF8, 0x2A, 0x20, 0x9F, 0x49, 0x2B, 0x46, 0x04, 0x20, 0x23, 0xF0, 0x7C, 0xFD, -+0x9D, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xA8, 0x80, 0x00, 0x2D, 0x00, 0xF0, 0xB7, 0x80, -+0x41, 0xF2, 0x43, 0x63, 0x9C, 0x42, 0x00, 0xF2, 0xAE, 0x80, 0x41, 0xF2, 0x7B, 0x53, 0x9C, 0x42, 0x8B, 0xBF, 0x4F, 0xF0, -+0xEC, 0x09, 0x4F, 0xF0, 0xFC, 0x09, 0x3B, 0x27, 0x3F, 0x27, 0x20, 0x46, 0x35, 0xF0, 0x0E, 0xFD, 0x02, 0x46, 0x0B, 0x46, -+0x82, 0x46, 0x8B, 0x46, 0x35, 0xF0, 0xBC, 0xFB, 0x8D, 0x4B, 0x00, 0x22, 0x35, 0xF0, 0x98, 0xFE, 0x8C, 0x4B, 0x00, 0x22, -+0x35, 0xF0, 0x6A, 0xFD, 0x35, 0xF0, 0x62, 0xFB, 0x36, 0xF0, 0x00, 0xF8, 0x52, 0x46, 0x5B, 0x46, 0x88, 0x49, 0x05, 0x46, -+0x00, 0x20, 0x35, 0xF0, 0x89, 0xFE, 0x00, 0x22, 0x4F, 0xF0, 0x83, 0x43, 0x35, 0xF0, 0x5A, 0xFD, 0x35, 0xF0, 0x52, 0xFB, -+0x35, 0xF0, 0xF0, 0xFF, 0x03, 0x46, 0x38, 0x46, 0x1F, 0x46, 0x35, 0xF0, 0xE7, 0xFC, 0x80, 0x4B, 0x00, 0x22, 0x35, 0xF0, -+0x4D, 0xFD, 0x02, 0x46, 0x0B, 0x46, 0x50, 0x46, 0x59, 0x46, 0x35, 0xF0, 0x71, 0xFE, 0x00, 0x22, 0x4F, 0xF0, 0x83, 0x43, -+0x35, 0xF0, 0x42, 0xFD, 0x35, 0xF0, 0x3A, 0xFB, 0x35, 0xF0, 0xD8, 0xFF, 0x77, 0x4B, 0x78, 0x4A, 0xD3, 0xF8, 0x00, 0xE0, -+0x2E, 0xF4, 0x00, 0x0E, 0xC3, 0xF8, 0x00, 0xE0, 0xD3, 0xF8, 0x00, 0xE0, 0x4E, 0xF4, 0x80, 0x0E, 0xC3, 0xF8, 0x00, 0xE0, -+0xD3, 0xF8, 0x00, 0xE0, 0x2E, 0xF4, 0x00, 0x1E, 0xC3, 0xF8, 0x00, 0xE0, 0xD3, 0xF8, 0x00, 0xE0, 0x4E, 0xF0, 0x08, 0x0E, -+0xC3, 0xF8, 0x00, 0xE0, 0xD3, 0xF8, 0x00, 0xE0, 0x01, 0x46, 0x2E, 0xF0, 0x04, 0x0E, 0x6A, 0x48, 0xC3, 0xF8, 0x00, 0xE0, -+0x03, 0x68, 0x43, 0xF0, 0x80, 0x43, 0x03, 0x60, 0x03, 0x68, 0x43, 0xF0, 0x00, 0x53, 0x03, 0x60, 0x13, 0x68, 0x23, 0xF4, -+0xFF, 0x63, 0x23, 0xF0, 0x04, 0x03, 0x43, 0xEA, 0x09, 0x03, 0x13, 0x60, 0x20, 0x46, 0xD8, 0xF8, 0xA8, 0x34, 0x89, 0x46, -+0x98, 0x47, 0x20, 0x46, 0xD8, 0xF8, 0xAC, 0x34, 0x64, 0x08, 0x98, 0x47, 0x5C, 0x4B, 0x5D, 0x4A, 0x1D, 0x60, 0x17, 0x60, -+0xC3, 0xF8, 0x48, 0x90, 0x00, 0x2E, 0x00, 0xF0, 0x8D, 0x80, 0x01, 0x2E, 0x04, 0xD1, 0x59, 0x4A, 0x13, 0x68, 0x23, 0xF4, -+0x00, 0x63, 0x13, 0x60, 0x57, 0x49, 0x58, 0x4B, 0x08, 0x68, 0x58, 0x4A, 0x03, 0x40, 0x43, 0xEA, 0x04, 0x33, 0x01, 0x20, -+0x0B, 0x60, 0x10, 0x60, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x01, 0x2D, 0x7F, 0xF6, 0x55, 0xAF, 0x52, 0x49, 0x53, 0x48, -+0x40, 0xF6, 0x4A, 0x22, 0x23, 0xF0, 0xEE, 0xFE, 0x41, 0xF2, 0x43, 0x63, 0x9C, 0x42, 0x7F, 0xF6, 0x52, 0xAF, 0x4F, 0xF0, -+0xF0, 0x09, 0x3C, 0x27, 0x57, 0xE7, 0x20, 0x46, 0x35, 0xF0, 0x66, 0xFC, 0x4B, 0x4B, 0x00, 0x22, 0x82, 0x46, 0x8B, 0x46, -+0x35, 0xF0, 0xCA, 0xFC, 0x39, 0x4B, 0x00, 0x22, 0x35, 0xF0, 0xF0, 0xFD, 0x38, 0x4B, 0x00, 0x22, 0x35, 0xF0, 0xC2, 0xFC, -+0x35, 0xF0, 0xBA, 0xFA, 0x35, 0xF0, 0x58, 0xFF, 0x52, 0x46, 0x5B, 0x46, 0x05, 0x46, 0x42, 0x49, 0x00, 0x20, 0x35, 0xF0, -+0xE1, 0xFD, 0x00, 0x22, 0x4F, 0xF0, 0x83, 0x43, 0x35, 0xF0, 0xB2, 0xFC, 0x35, 0xF0, 0xAA, 0xFA, 0x35, 0xF0, 0x48, 0xFF, -+0x24, 0xA3, 0xD3, 0xE9, 0x00, 0x23, 0x07, 0x46, 0x59, 0x46, 0x50, 0x46, 0x35, 0xF0, 0xD0, 0xFD, 0x00, 0x22, 0x4F, 0xF0, -+0x83, 0x43, 0x35, 0xF0, 0xA1, 0xFC, 0x35, 0xF0, 0x99, 0xFA, 0x35, 0xF0, 0x37, 0xFF, 0x27, 0x4B, 0x28, 0x4A, 0x19, 0x68, -+0x21, 0xF4, 0x00, 0x01, 0x19, 0x60, 0x19, 0x68, 0x21, 0xF4, 0x80, 0x01, 0x19, 0x60, 0x19, 0x68, 0x41, 0xF4, 0x00, 0x11, -+0x19, 0x60, 0x19, 0x68, 0x21, 0xF0, 0x08, 0x01, 0x19, 0x60, 0x19, 0x68, 0x41, 0xF0, 0x04, 0x01, 0x19, 0x60, 0x13, 0x68, -+0x23, 0xF0, 0x80, 0x43, 0x13, 0x60, 0x13, 0x68, 0x81, 0x46, 0x23, 0xF0, 0x00, 0x53, 0x19, 0x48, 0x13, 0x60, 0x03, 0x68, -+0x23, 0xF4, 0xFF, 0x63, 0x23, 0xF0, 0x04, 0x03, 0x43, 0xF0, 0xEC, 0x03, 0x03, 0x60, 0xD8, 0xF8, 0xA0, 0x34, 0x20, 0x46, -+0x98, 0x47, 0xD8, 0xF8, 0xA4, 0x34, 0x20, 0x46, 0x98, 0x47, 0x69, 0xE7, 0x13, 0x4A, 0x13, 0x68, 0x43, 0xF4, 0x00, 0x63, -+0x13, 0x60, 0x73, 0xE7, 0xAF, 0xF3, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xA2, 0x40, 0x78, 0x78, 0x15, 0x00, -+0x58, 0x77, 0x15, 0x00, 0x8C, 0x77, 0x15, 0x00, 0x9C, 0x77, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x00, 0x00, 0x6A, 0x40, -+0x00, 0x00, 0x50, 0x41, 0x00, 0x00, 0xB9, 0x40, 0x00, 0x00, 0x54, 0x40, 0x14, 0x40, 0x34, 0x40, 0x3C, 0x40, 0x34, 0x40, -+0x30, 0x40, 0x34, 0x40, 0x10, 0x20, 0x34, 0x40, 0x54, 0x20, 0x34, 0x40, 0x20, 0x40, 0x34, 0x40, 0x1C, 0x20, 0x34, 0x40, -+0xFF, 0x0F, 0x00, 0xE0, 0x84, 0x21, 0x34, 0x40, 0x70, 0x79, 0x15, 0x00, 0xB4, 0x77, 0x15, 0x00, 0x00, 0x00, 0x10, 0x40, -+0x00, 0x00, 0xA4, 0x40, 0x88, 0x1A, 0x17, 0x00, 0xBC, 0x34, 0x17, 0x00, 0xF8, 0xB5, 0x43, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x6B, 0xDB, 0xFF, 0xF7, 0xBD, 0xFB, 0x40, 0x49, 0x40, 0x4A, 0x0B, 0x68, 0x40, 0x48, 0x43, 0xF0, -+0x00, 0x63, 0x0B, 0x60, 0x13, 0x68, 0x43, 0xF0, 0x08, 0x03, 0x13, 0x60, 0x03, 0x68, 0xC3, 0xF3, 0x03, 0x23, 0x02, 0x2B, -+0x06, 0xD1, 0xA2, 0xF5, 0x99, 0x42, 0x04, 0x3A, 0x13, 0x68, 0x43, 0xF0, 0x03, 0x03, 0x13, 0x60, 0x36, 0x4B, 0x1B, 0x68, -+0xC3, 0xF3, 0x03, 0x13, 0x02, 0x2B, 0x02, 0xD1, 0x34, 0x4B, 0x35, 0x4A, 0x1A, 0x60, 0x35, 0x4A, 0x35, 0x49, 0x13, 0x68, -+0xDF, 0xF8, 0x04, 0xC1, 0x34, 0x4D, 0x35, 0x4F, 0x35, 0x4C, 0x36, 0x48, 0x36, 0x4E, 0x23, 0xF4, 0xFF, 0x63, 0x23, 0xF0, -+0x07, 0x03, 0x43, 0xF4, 0xE0, 0x63, 0x13, 0x60, 0x4F, 0xF4, 0x80, 0x73, 0x0B, 0x60, 0x04, 0x23, 0xCC, 0xF8, 0x00, 0x30, -+0x01, 0x22, 0xC4, 0x23, 0x3A, 0x60, 0x2B, 0x60, 0x00, 0x23, 0x23, 0x60, 0x6F, 0x24, 0x04, 0x60, 0x2C, 0x4C, 0xB0, 0x27, -+0x37, 0x60, 0x23, 0x60, 0xC3, 0x60, 0xAB, 0x61, 0x6B, 0x25, 0xE5, 0x60, 0x29, 0x4D, 0x83, 0x61, 0x2A, 0x60, 0xA3, 0x61, -+0x07, 0x24, 0x44, 0x62, 0xEC, 0x26, 0x27, 0x4C, 0xEE, 0x60, 0x03, 0x25, 0xC5, 0x62, 0x23, 0x60, 0xD0, 0xF8, 0xEC, 0x31, -+0x93, 0x42, 0x00, 0xF5, 0xF6, 0x70, 0x0F, 0xD9, 0x22, 0x4B, 0xA0, 0xF5, 0x56, 0x70, 0x1A, 0x60, 0x03, 0x68, 0x23, 0xF0, -+0x7F, 0x43, 0x43, 0xF0, 0x20, 0x43, 0x03, 0x60, 0x0B, 0x68, 0x23, 0xF4, 0x40, 0x73, 0x43, 0xF4, 0x80, 0x73, 0x0B, 0x60, -+0xF8, 0xBD, 0x1B, 0x4A, 0x13, 0x68, 0x12, 0x68, 0x1B, 0x0E, 0x02, 0x33, 0x03, 0xEB, 0x83, 0x03, 0xC2, 0xF3, 0x07, 0x42, -+0x02, 0xEB, 0x43, 0x03, 0x1E, 0x2B, 0x86, 0xD0, 0x15, 0x49, 0x16, 0x48, 0x40, 0xF6, 0x2C, 0x32, 0x23, 0xF0, 0xBC, 0xFD, -+0x7F, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x10, 0x00, 0x34, 0x40, 0x14, 0x00, 0x34, 0x40, 0x00, 0x00, 0x33, 0x40, -+0x04, 0xB1, 0x33, 0x40, 0x34, 0x34, 0x34, 0x00, 0xB4, 0xB3, 0x33, 0x40, 0x00, 0x10, 0x34, 0x40, 0x08, 0x12, 0x34, 0x40, -+0x04, 0x12, 0x34, 0x40, 0x0C, 0x12, 0x34, 0x40, 0x10, 0x12, 0x34, 0x40, 0x14, 0x12, 0x34, 0x40, 0x18, 0x12, 0x34, 0x40, -+0x2C, 0x12, 0x34, 0x40, 0x40, 0x12, 0x34, 0x40, 0x0C, 0x10, 0x34, 0x40, 0x3C, 0x00, 0x33, 0x40, 0x70, 0x79, 0x15, 0x00, -+0xC8, 0x77, 0x15, 0x00, 0x00, 0x12, 0x34, 0x40, 0x10, 0xB5, 0x1A, 0x4C, 0x82, 0xB0, 0xD4, 0xF8, 0x3C, 0x31, 0x98, 0x47, -+0x18, 0x4B, 0x19, 0x4A, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF0, 0x00, 0x42, 0x1A, 0x60, 0x1A, 0x68, 0x00, 0x2A, 0xFC, 0xDB, -+0x15, 0x4A, 0x1A, 0x60, 0x19, 0x68, 0x12, 0x4A, 0x41, 0xF0, 0x00, 0x41, 0x19, 0x60, 0x13, 0x68, 0x00, 0x2B, 0xFC, 0xDB, -+0x11, 0x4B, 0x13, 0x60, 0x13, 0x68, 0x0D, 0x49, 0x43, 0xF0, 0x00, 0x43, 0x13, 0x60, 0x0B, 0x68, 0xDB, 0x0F, 0xFC, 0xD1, -+0xCD, 0xE9, 0x00, 0x33, 0x40, 0xF6, 0x85, 0x12, 0x11, 0x46, 0x18, 0x46, 0xD4, 0xF8, 0x28, 0x42, 0xA0, 0x47, 0x09, 0x49, -+0x09, 0x4B, 0x0A, 0x4A, 0x0C, 0x20, 0x08, 0x60, 0x1A, 0x60, 0x02, 0xB0, 0x10, 0xBD, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, -+0x20, 0x00, 0x58, 0x40, 0xBF, 0x3F, 0x42, 0x01, 0xA2, 0x30, 0x43, 0x01, 0xDD, 0x1D, 0x44, 0x01, 0x00, 0xB3, 0x33, 0x40, -+0xC0, 0xB3, 0x33, 0x40, 0xA0, 0xA0, 0x28, 0x28, 0x70, 0xB5, 0x13, 0x4B, 0x13, 0x4D, 0x04, 0x46, 0xED, 0x1A, 0x03, 0xF2, -+0x3C, 0x50, 0x5A, 0x19, 0x53, 0xF8, 0x04, 0x1B, 0x11, 0x60, 0x83, 0x42, 0xF9, 0xD1, 0xFF, 0xF7, 0xEB, 0xFA, 0x0E, 0x4B, -+0x0E, 0x4E, 0xD3, 0xF8, 0x24, 0x32, 0x20, 0x46, 0x98, 0x47, 0x00, 0x23, 0x86, 0xF8, 0x2A, 0x30, 0x0F, 0xCC, 0x35, 0x46, -+0x0F, 0xC5, 0x0F, 0xCC, 0x0F, 0xC5, 0x23, 0x68, 0x2B, 0x60, 0x05, 0x21, 0x4F, 0xF0, 0xFF, 0x12, 0xFF, 0x23, 0x86, 0xF8, -+0x2B, 0x10, 0x72, 0x62, 0x33, 0x85, 0x70, 0xBD, 0xB0, 0x0D, 0x17, 0x00, 0x00, 0x90, 0x33, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0xBC, 0x34, 0x17, 0x00, 0x08, 0xB5, 0x05, 0x4B, 0x1B, 0x68, 0x1B, 0x07, 0x00, 0xD4, 0x08, 0xBD, 0x14, 0xF0, 0xF4, 0xFD, -+0x02, 0x4B, 0x08, 0x22, 0x1A, 0x60, 0x08, 0xBD, 0xA8, 0x10, 0x34, 0x40, 0xAC, 0x10, 0x34, 0x40, 0x03, 0x4A, 0x04, 0x4B, -+0x12, 0x68, 0x02, 0x60, 0x1B, 0x68, 0x0B, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x00, 0x33, 0x40, 0x3C, 0x00, 0x33, 0x40, -+0x2D, 0xE9, 0xF0, 0x4F, 0x83, 0xB0, 0x9D, 0xF8, 0x38, 0x40, 0xBD, 0xF8, 0x30, 0xA0, 0x9D, 0xF8, 0x34, 0x90, 0x00, 0x2C, -+0x43, 0xD1, 0x98, 0x46, 0x25, 0x4B, 0x1B, 0x78, 0x05, 0x46, 0x0E, 0x46, 0x17, 0x46, 0xD3, 0xB1, 0x23, 0x4C, 0x24, 0x4A, -+0xCD, 0xF8, 0x00, 0x90, 0x00, 0x23, 0xD2, 0xF8, 0x28, 0xB2, 0x01, 0x93, 0x42, 0x46, 0x33, 0x46, 0x39, 0x46, 0x28, 0x46, -+0xD8, 0x47, 0x84, 0xF8, 0x2A, 0x50, 0x84, 0xF8, 0x2B, 0x60, 0x84, 0xF8, 0x2C, 0x90, 0xA7, 0x84, 0xA4, 0xF8, 0x26, 0x80, -+0xA4, 0xF8, 0x28, 0xA0, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x18, 0x4A, 0x15, 0x4C, 0x13, 0x68, 0x23, 0xF4, 0x00, 0x73, -+0x13, 0x60, 0x94, 0xF8, 0x2A, 0x30, 0x83, 0x42, 0xDB, 0xD1, 0x94, 0xF8, 0x2B, 0x30, 0x8B, 0x42, 0xD7, 0xD1, 0x94, 0xF8, -+0x2C, 0x30, 0x4B, 0x45, 0xD3, 0xD1, 0xA3, 0x8C, 0xBB, 0x42, 0xD0, 0xD1, 0xE3, 0x8C, 0x43, 0x45, 0xCD, 0xD1, 0x23, 0x8D, -+0x53, 0x45, 0xCA, 0xD1, 0x0B, 0x49, 0x0C, 0x48, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x23, 0xF0, 0x35, 0xBA, 0x08, 0x49, -+0x09, 0x48, 0x22, 0x46, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x23, 0xF0, 0x2D, 0xBA, 0x00, 0xBF, 0x3C, 0x36, 0x17, 0x00, -+0xBC, 0x34, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x90, 0xB3, 0x33, 0x40, 0x8C, 0x78, 0x15, 0x00, 0x38, 0x78, 0x15, 0x00, -+0x18, 0x78, 0x15, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x71, 0xB9, 0x0A, 0x4A, 0x93, 0x8C, 0x92, 0xF8, 0x2B, 0x00, 0x92, 0xF8, -+0x2A, 0x10, 0xD2, 0xF8, 0x26, 0x20, 0x62, 0x60, 0x1B, 0x04, 0x43, 0xEA, 0x00, 0x23, 0x0B, 0x43, 0x23, 0x60, 0x10, 0xBD, -+0x0A, 0x46, 0x03, 0x48, 0x03, 0x49, 0x23, 0xF0, 0x07, 0xFA, 0xEA, 0xE7, 0xBC, 0x34, 0x17, 0x00, 0x18, 0x78, 0x15, 0x00, -+0x9C, 0x78, 0x15, 0x00, 0x04, 0x4B, 0x1B, 0x68, 0x1B, 0x07, 0x00, 0xD1, 0x70, 0x47, 0x03, 0x49, 0x03, 0x48, 0x23, 0xF0, -+0xF7, 0xB9, 0x00, 0xBF, 0x38, 0x00, 0x32, 0x40, 0xAC, 0x78, 0x15, 0x00, 0x60, 0x78, 0x15, 0x00, 0x4F, 0xF4, 0x7A, 0x70, -+0x70, 0x47, 0x00, 0xBF, 0x01, 0x20, 0x70, 0x47, 0x02, 0x4B, 0x18, 0x68, 0xC0, 0xF3, 0x40, 0x50, 0x70, 0x47, 0x00, 0xBF, -+0x00, 0x00, 0x33, 0x40, 0x03, 0x4B, 0x18, 0x68, 0x01, 0x28, 0x94, 0xBF, 0x00, 0x20, 0x01, 0x20, 0x70, 0x47, 0x00, 0xBF, -+0xFC, 0x13, 0x34, 0x40, 0x04, 0x4A, 0x13, 0x68, 0xC0, 0x00, 0x00, 0xF0, 0x08, 0x00, 0x23, 0xF0, 0x08, 0x03, 0x18, 0x43, -+0x10, 0x60, 0x70, 0x47, 0xA0, 0x10, 0x34, 0x40, 0x02, 0x4B, 0x18, 0x68, 0xC0, 0xF3, 0x80, 0x60, 0x70, 0x47, 0x00, 0xBF, -+0x00, 0x00, 0x33, 0x40, 0x02, 0x4B, 0x18, 0x68, 0xC0, 0xF3, 0x00, 0x70, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x00, 0x33, 0x40, -+0x02, 0x4B, 0x18, 0x68, 0xC0, 0xF3, 0x80, 0x70, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x00, 0x33, 0x40, 0x06, 0x4B, 0x02, 0x68, -+0x1A, 0x60, 0x42, 0x68, 0x5A, 0x60, 0x0A, 0x68, 0x9A, 0x60, 0x4A, 0x68, 0xDA, 0x60, 0x8A, 0x68, 0x1A, 0x61, 0xCA, 0x68, -+0x5A, 0x61, 0x70, 0x47, 0xA8, 0x08, 0x33, 0x40, 0x30, 0xB4, 0x06, 0x49, 0x06, 0x4D, 0x07, 0x4B, 0x00, 0x24, 0xC0, 0xF3, -+0x0A, 0x00, 0x40, 0xF2, 0xFF, 0x72, 0x28, 0x60, 0x0C, 0x60, 0x30, 0xBC, 0x1A, 0x60, 0x70, 0x47, 0xC4, 0x08, 0x33, 0x40, -+0xC0, 0x08, 0x33, 0x40, 0xC8, 0x08, 0x33, 0x40, 0x03, 0x4B, 0x18, 0x68, 0xC0, 0xF3, 0x03, 0x20, 0x01, 0x38, 0xC0, 0xB2, -+0x70, 0x47, 0x00, 0xBF, 0x00, 0x00, 0x33, 0x40, 0x03, 0x4B, 0x18, 0x68, 0xC0, 0xF3, 0x03, 0x10, 0x01, 0x38, 0xC0, 0xB2, -+0x70, 0x47, 0x00, 0xBF, 0x00, 0x00, 0x33, 0x40, 0x03, 0x4B, 0x18, 0x68, 0x00, 0xF0, 0x0F, 0x00, 0x01, 0x38, 0xC0, 0xB2, -+0x70, 0x47, 0x00, 0xBF, 0x00, 0x00, 0x33, 0x40, 0xF0, 0xB5, 0xBE, 0x4C, 0x94, 0xF8, 0x2A, 0x30, 0x00, 0x2B, 0x76, 0xD1, -+0xBC, 0x4B, 0x93, 0xF8, 0xBD, 0x50, 0x00, 0x2D, 0x66, 0xD0, 0xE0, 0x8C, 0x40, 0xF6, 0x7B, 0x14, 0xA0, 0x42, 0x40, 0xF2, -+0xCA, 0x80, 0x40, 0xF6, 0x94, 0x14, 0xA0, 0x42, 0xB6, 0x48, 0x94, 0xBF, 0x90, 0xF9, 0x01, 0x60, 0x90, 0xF9, 0x02, 0x60, -+0x93, 0xF8, 0xBE, 0x40, 0xB3, 0x48, 0x06, 0xF1, 0x0F, 0x05, 0x1E, 0x2D, 0x00, 0x5D, 0xA8, 0xBF, 0x1E, 0x25, 0x0A, 0x2C, -+0x4F, 0xEA, 0x20, 0x17, 0x00, 0xF0, 0x0F, 0x0C, 0x25, 0xEA, 0xE5, 0x75, 0x00, 0xF3, 0xCF, 0x80, 0x00, 0xF0, 0xE4, 0x80, -+0xAB, 0x48, 0x04, 0xEB, 0x44, 0x04, 0x10, 0xF9, 0x14, 0xE0, 0x75, 0x45, 0x00, 0xEB, 0x44, 0x04, 0x00, 0xF3, 0x06, 0x81, -+0x64, 0x78, 0xA4, 0xEB, 0x0E, 0x04, 0x2C, 0x44, 0x60, 0xB2, 0x6F, 0xF0, 0x04, 0x04, 0xA0, 0x42, 0x07, 0xF1, 0xFF, 0x37, -+0xB8, 0xBF, 0x20, 0x46, 0x60, 0x44, 0x80, 0xF3, 0x04, 0x00, 0x40, 0xEA, 0x07, 0x10, 0x08, 0x70, 0x93, 0xF8, 0xBF, 0x10, -+0x9D, 0x4B, 0x5B, 0x5C, 0x0A, 0x29, 0x4F, 0xEA, 0x23, 0x10, 0x03, 0xF0, 0x0F, 0x03, 0x17, 0xDC, 0x00, 0xF0, 0xD1, 0x80, -+0x01, 0x31, 0x97, 0x4C, 0x01, 0xEB, 0x41, 0x01, 0x14, 0xF9, 0x11, 0x60, 0xAE, 0x42, 0x04, 0xEB, 0x41, 0x01, 0xC0, 0xF2, -+0xD2, 0x80, 0x49, 0x78, 0x89, 0x1B, 0x0D, 0x44, 0x6D, 0xB2, 0x6F, 0xF0, 0x04, 0x01, 0x01, 0x38, 0x8D, 0x42, 0xAC, 0xBF, -+0x5B, 0x19, 0x5B, 0x18, 0x83, 0xF3, 0x04, 0x03, 0x43, 0xEA, 0x00, 0x13, 0x13, 0x70, 0xF0, 0xBD, 0x93, 0xF8, 0xAC, 0x40, -+0xE5, 0x07, 0x68, 0xD5, 0x93, 0xF8, 0xB7, 0x00, 0x08, 0x70, 0x93, 0xF8, 0xAD, 0x30, 0x13, 0x70, 0xF0, 0xBD, 0x81, 0x4B, -+0x93, 0xF8, 0xBD, 0x50, 0x00, 0x2D, 0x3A, 0xD0, 0xE0, 0x8C, 0x41, 0xF2, 0xC8, 0x44, 0xA0, 0x42, 0x4F, 0xD9, 0xB0, 0xF5, -+0xAF, 0x5F, 0x7D, 0xD8, 0x7F, 0x48, 0x90, 0xF9, 0x01, 0x60, 0x93, 0xF8, 0xC3, 0x00, 0x7E, 0x4B, 0x1B, 0x5C, 0x0A, 0x28, -+0x4F, 0xEA, 0x23, 0x15, 0x03, 0xF0, 0x0F, 0x03, 0x1D, 0xDC, 0x06, 0xF1, 0x0F, 0x04, 0x1E, 0x2C, 0xA8, 0xBF, 0x1E, 0x24, -+0x0A, 0x28, 0x24, 0xEA, 0xE4, 0x74, 0x7A, 0xD0, 0x76, 0x4E, 0x00, 0xEB, 0x40, 0x00, 0x16, 0xF9, 0x10, 0x70, 0xBC, 0x42, -+0x06, 0xEB, 0x40, 0x00, 0x00, 0xF3, 0x9E, 0x80, 0x40, 0x78, 0xC0, 0x1B, 0x04, 0x44, 0x64, 0xB2, 0x6F, 0xF0, 0x04, 0x00, -+0x01, 0x3D, 0x84, 0x42, 0xAC, 0xBF, 0x1B, 0x19, 0x1B, 0x18, 0x83, 0xF3, 0x04, 0x03, 0x43, 0xEA, 0x05, 0x13, 0xDB, 0xB2, -+0x13, 0x70, 0x0B, 0x70, 0xF0, 0xBD, 0x93, 0xF8, 0xAC, 0x40, 0xA4, 0x07, 0x04, 0xD5, 0x93, 0xF8, 0xAE, 0x30, 0x0B, 0x70, -+0x13, 0x70, 0xF0, 0xBD, 0x90, 0xF9, 0x00, 0x30, 0x61, 0x48, 0x6F, 0xF0, 0x04, 0x04, 0xA3, 0x42, 0xB8, 0xBF, 0x23, 0x46, -+0x12, 0x2B, 0xA8, 0xBF, 0x12, 0x23, 0x05, 0x33, 0x5B, 0x10, 0xC3, 0x5C, 0x0B, 0x70, 0x13, 0x70, 0xF0, 0xBD, 0x59, 0x48, -+0x90, 0xF9, 0x00, 0x60, 0xB1, 0xE7, 0x53, 0x48, 0x90, 0xF9, 0x00, 0x60, 0x3A, 0xE7, 0x90, 0xF9, 0x00, 0x30, 0x51, 0x4D, -+0x52, 0x4C, 0x01, 0x2B, 0x6F, 0xF0, 0x01, 0x06, 0x18, 0x46, 0xB8, 0xBF, 0x01, 0x20, 0xB3, 0x42, 0xB8, 0xBF, 0x33, 0x46, -+0x17, 0x28, 0xA8, 0xBF, 0x17, 0x20, 0x14, 0x2B, 0xA8, 0xBF, 0x14, 0x23, 0x01, 0x38, 0x02, 0x33, 0x40, 0x10, 0x5B, 0x10, -+0x28, 0x5C, 0xE3, 0x5C, 0x08, 0x70, 0x13, 0x70, 0xF0, 0xBD, 0x74, 0x1C, 0x55, 0xDA, 0xA5, 0xF1, 0x0D, 0x00, 0x40, 0xB2, -+0x6F, 0xF0, 0x04, 0x04, 0xA0, 0x42, 0xA7, 0xF1, 0x02, 0x07, 0xB8, 0xBF, 0x20, 0x46, 0x3B, 0xE7, 0x41, 0xF2, 0x44, 0x64, -+0xA0, 0x42, 0x3F, 0x48, 0x94, 0xBF, 0x90, 0xF9, 0x02, 0x60, 0x90, 0xF9, 0x03, 0x60, 0x7A, 0xE7, 0xB0, 0x1C, 0x53, 0xDB, -+0x01, 0x2E, 0x00, 0xF3, 0x8D, 0x80, 0xA5, 0xF1, 0x0F, 0x00, 0x40, 0xB2, 0x28, 0xE7, 0x03, 0x36, 0x43, 0xDA, 0x09, 0x3C, -+0x64, 0xB2, 0x6F, 0xF0, 0x04, 0x00, 0x01, 0x3D, 0x84, 0x42, 0xAC, 0xBF, 0x1B, 0x19, 0x1B, 0x18, 0x8D, 0xE7, 0x03, 0x36, -+0x30, 0xDA, 0x09, 0x3D, 0x6D, 0xB2, 0x6F, 0xF0, 0x04, 0x01, 0x01, 0x38, 0x8D, 0x42, 0xAC, 0xBF, 0x5B, 0x19, 0x5B, 0x18, -+0x38, 0xE7, 0x91, 0xF9, 0x04, 0x40, 0xAC, 0x42, 0x3B, 0xDD, 0xCC, 0x78, 0x89, 0x78, 0x61, 0x1A, 0x0D, 0x44, 0x43, 0xFA, -+0x85, 0xF3, 0x2D, 0xE7, 0x94, 0xF9, 0x04, 0xE0, 0x75, 0x45, 0x57, 0xDA, 0xE0, 0x78, 0xA4, 0x78, 0x00, 0x1B, 0x28, 0x44, -+0x40, 0xB2, 0xFB, 0xE6, 0x90, 0xF9, 0x04, 0x60, 0xB4, 0x42, 0x43, 0xDA, 0xC6, 0x78, 0x80, 0x78, 0x30, 0x1A, 0x04, 0x44, -+0x43, 0xFA, 0x84, 0xF3, 0x61, 0xE7, 0xA5, 0xF1, 0x0F, 0x04, 0x60, 0xB2, 0x03, 0x28, 0xA8, 0xBF, 0x03, 0x20, 0xE9, 0xE6, -+0x0F, 0x3D, 0x6D, 0xB2, 0x05, 0x2D, 0xD4, 0xBF, 0x5B, 0x19, 0x05, 0x33, 0x0A, 0xE7, 0x0F, 0x3C, 0x64, 0xB2, 0x05, 0x2C, -+0xD4, 0xBF, 0x1B, 0x19, 0x05, 0x33, 0x4C, 0xE7, 0xA5, 0xF1, 0x0A, 0x00, 0x40, 0xB2, 0x6F, 0xF0, 0x04, 0x04, 0xA0, 0x42, -+0x07, 0xF1, 0xFF, 0x37, 0xB8, 0xBF, 0x20, 0x46, 0xD0, 0xE6, 0x49, 0x79, 0x09, 0x1B, 0x0D, 0x44, 0x6D, 0xB2, 0x05, 0x2D, -+0xD4, 0xBF, 0x5B, 0x19, 0x05, 0x33, 0x01, 0x30, 0xEE, 0xE6, 0x00, 0xBF, 0xBC, 0x34, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, -+0x68, 0x25, 0x17, 0x00, 0xEC, 0x12, 0x17, 0x00, 0xB8, 0x78, 0x15, 0x00, 0xF8, 0x12, 0x17, 0x00, 0x6C, 0x25, 0x17, 0x00, -+0x04, 0x13, 0x17, 0x00, 0x0C, 0x79, 0x15, 0x00, 0x40, 0x79, 0x80, 0x1B, 0x04, 0x44, 0x64, 0xB2, 0x05, 0x2C, 0xD4, 0xBF, -+0x1B, 0x19, 0x05, 0x33, 0x01, 0x35, 0x1A, 0xE7, 0x60, 0x79, 0xA0, 0xEB, 0x0E, 0x00, 0x28, 0x44, 0x40, 0xB2, 0x05, 0x28, -+0xA8, 0xBF, 0x05, 0x20, 0x01, 0x37, 0x9F, 0xE6, 0xA5, 0xF1, 0x11, 0x00, 0x40, 0xB2, 0x03, 0x28, 0x07, 0xF1, 0x02, 0x07, -+0xA8, 0xBF, 0x03, 0x20, 0x96, 0xE6, 0x00, 0xBF, 0xF0, 0xB4, 0xB9, 0x4B, 0x93, 0xF8, 0x2A, 0x20, 0xDC, 0x8C, 0x52, 0xBB, -+0xC0, 0xB9, 0x03, 0x29, 0x00, 0xF2, 0x91, 0x80, 0xB5, 0x4A, 0xB6, 0x4B, 0x92, 0xF8, 0xBE, 0x50, 0x5B, 0x5D, 0x02, 0x46, -+0x01, 0x46, 0x07, 0x46, 0x40, 0xF6, 0x7B, 0x10, 0x84, 0x42, 0x00, 0xF2, 0xBA, 0x80, 0xB1, 0x48, 0x90, 0xF9, 0x00, 0x60, -+0x00, 0x29, 0x00, 0xF0, 0xC0, 0x80, 0xD8, 0xB2, 0xF0, 0xBC, 0x70, 0x47, 0x04, 0x28, 0x40, 0xF2, 0x8F, 0x80, 0x09, 0x29, -+0x40, 0xF2, 0x8E, 0x80, 0xA7, 0x4B, 0x93, 0xF8, 0xC2, 0x50, 0x08, 0x2D, 0x40, 0xF3, 0x17, 0x81, 0x01, 0x21, 0x0F, 0x46, -+0x09, 0x25, 0xD4, 0x23, 0xE0, 0xE7, 0x04, 0x28, 0x44, 0xD9, 0x09, 0x29, 0x44, 0xD9, 0xA0, 0x4B, 0xA2, 0x49, 0x93, 0xF8, -+0xC6, 0x30, 0x09, 0x2B, 0xA8, 0xBF, 0x09, 0x23, 0x41, 0xF2, 0xC8, 0x42, 0x94, 0x42, 0xC8, 0x5C, 0x4F, 0xF0, 0x00, 0x05, -+0x53, 0xD9, 0xB4, 0xF5, 0xAF, 0x5F, 0x00, 0xF2, 0xCC, 0x80, 0x9B, 0x4A, 0x92, 0xF9, 0x01, 0x20, 0x00, 0x2D, 0xD1, 0xD1, -+0x0A, 0x2B, 0x4F, 0xEA, 0x20, 0x14, 0x00, 0xF0, 0x0F, 0x00, 0x1E, 0xDC, 0x02, 0xF1, 0x0F, 0x01, 0x1E, 0x29, 0xA8, 0xBF, -+0x1E, 0x21, 0x0A, 0x2B, 0x21, 0xEA, 0xE1, 0x71, 0x00, 0xF0, 0x3C, 0x81, 0x91, 0x4A, 0x03, 0xEB, 0x43, 0x03, 0x12, 0xF9, -+0x13, 0x50, 0x8D, 0x42, 0x02, 0xEB, 0x43, 0x02, 0x80, 0xF2, 0xF6, 0x80, 0x92, 0xF9, 0x04, 0x50, 0x8D, 0x42, 0x40, 0xF3, -+0x40, 0x81, 0xD3, 0x78, 0x92, 0x78, 0x9B, 0x1A, 0x19, 0x44, 0x40, 0xFA, 0x81, 0xF0, 0x80, 0xF3, 0x04, 0x00, 0x40, 0xEA, -+0x04, 0x10, 0xC0, 0xB2, 0xF0, 0xBC, 0x70, 0x47, 0x01, 0x28, 0x0C, 0xD9, 0x07, 0x29, 0x2C, 0xD8, 0x04, 0x29, 0x0A, 0xD8, -+0x7B, 0x4B, 0x93, 0xF8, 0xC3, 0x30, 0xA3, 0xF1, 0x0B, 0x05, 0xB5, 0xFA, 0x85, 0xF5, 0x6D, 0x09, 0x09, 0xE0, 0x09, 0x29, -+0xF4, 0xD9, 0x76, 0x4B, 0x93, 0xF8, 0xC4, 0x30, 0x0A, 0x2B, 0x4F, 0xF0, 0x00, 0x05, 0xA8, 0xBF, 0x0A, 0x23, 0x75, 0x49, -+0x41, 0xF2, 0xC8, 0x42, 0x94, 0x42, 0xC8, 0x5C, 0xAB, 0xD8, 0x73, 0x4A, 0x92, 0xF9, 0x00, 0x20, 0xAE, 0xE7, 0x09, 0x29, -+0x26, 0xD8, 0x6C, 0x4B, 0x93, 0xF8, 0xBF, 0x50, 0x0B, 0x2D, 0x00, 0xF0, 0xF0, 0x80, 0x6F, 0x4B, 0x00, 0x22, 0x5B, 0x5D, -+0x11, 0x46, 0x01, 0x27, 0x68, 0xE7, 0x66, 0x4B, 0x93, 0xF8, 0xC5, 0x30, 0x09, 0x2B, 0x4F, 0xF0, 0x00, 0x05, 0xA8, 0xBF, -+0x09, 0x23, 0xDE, 0xE7, 0x01, 0x28, 0xE6, 0xD0, 0x07, 0x29, 0x0B, 0xD9, 0x5F, 0x4A, 0x65, 0x4B, 0x92, 0xF8, 0xC1, 0x50, -+0x0A, 0x2D, 0xA8, 0xBF, 0x0A, 0x25, 0x00, 0x22, 0x5B, 0x5D, 0x11, 0x46, 0x01, 0x27, 0x4F, 0xE7, 0x04, 0x29, 0xD8, 0xD9, -+0x58, 0x4A, 0x5E, 0x4B, 0x92, 0xF8, 0xC0, 0x50, 0xA5, 0xF1, 0x0B, 0x01, 0xB1, 0xFA, 0x81, 0xF1, 0x5B, 0x5D, 0x00, 0x22, -+0x49, 0x09, 0x01, 0x27, 0x40, 0xE7, 0x40, 0xF6, 0x94, 0x10, 0x84, 0x42, 0x52, 0x48, 0x94, 0xBF, 0x90, 0xF9, 0x01, 0x60, -+0x90, 0xF9, 0x02, 0x60, 0x00, 0x29, 0x7F, 0xF4, 0x40, 0xAF, 0x06, 0xF1, 0x0F, 0x01, 0x1E, 0x29, 0xA8, 0xBF, 0x1E, 0x21, -+0x0B, 0x2D, 0x21, 0xEA, 0xE1, 0x74, 0x4F, 0xEA, 0x23, 0x10, 0x29, 0x46, 0x03, 0xF0, 0x0F, 0x03, 0xA8, 0xBF, 0x0B, 0x21, -+0x00, 0x2F, 0x3B, 0xD1, 0x0A, 0x2D, 0x2C, 0xDC, 0x48, 0xD0, 0x49, 0x4D, 0x01, 0xEB, 0x41, 0x01, 0x15, 0xF9, 0x11, 0x60, -+0xB4, 0x42, 0x05, 0xEB, 0x41, 0x01, 0x34, 0xDC, 0x49, 0x78, 0x89, 0x1B, 0x21, 0x44, 0x49, 0xB2, 0x6F, 0xF0, 0x04, 0x04, -+0x01, 0x38, 0xA1, 0x42, 0xAC, 0xBF, 0x5B, 0x18, 0x1B, 0x19, 0x83, 0xF3, 0x04, 0x03, 0x43, 0xEA, 0x00, 0x13, 0xD8, 0xB2, -+0x00, 0x2A, 0x3F, 0xF4, 0x11, 0xAF, 0x82, 0x42, 0xBF, 0xF6, 0x0E, 0xAF, 0xD0, 0xB2, 0xF0, 0xBC, 0x70, 0x47, 0x41, 0xF2, -+0x44, 0x62, 0x94, 0x42, 0x33, 0x4A, 0x94, 0xBF, 0x92, 0xF9, 0x02, 0x20, 0x92, 0xF9, 0x03, 0x20, 0x2C, 0xE7, 0x01, 0x36, -+0x2A, 0xDA, 0xA4, 0xF1, 0x0D, 0x01, 0x49, 0xB2, 0x6F, 0xF0, 0x04, 0x04, 0x02, 0x38, 0xA1, 0x42, 0xAC, 0xBF, 0x5B, 0x18, -+0x1B, 0x19, 0xDA, 0xE7, 0x0A, 0x2D, 0xD8, 0xDC, 0x58, 0xD0, 0x01, 0x31, 0xC1, 0xE7, 0x91, 0xF9, 0x04, 0x50, 0xAC, 0x42, -+0x1E, 0xDA, 0xCD, 0x78, 0x89, 0x78, 0x69, 0x1A, 0x21, 0x44, 0x43, 0xFA, 0x81, 0xF3, 0xCA, 0xE7, 0xB1, 0x1C, 0x2B, 0xDB, -+0x01, 0x2E, 0x76, 0xDC, 0xA4, 0xF1, 0x0F, 0x01, 0x43, 0xFA, 0x81, 0xF3, 0xC1, 0xE7, 0x1F, 0x4B, 0x08, 0xBF, 0xD4, 0x22, -+0x5B, 0x5D, 0x00, 0x21, 0x01, 0x27, 0xC7, 0xE6, 0xA4, 0xF1, 0x0F, 0x01, 0x49, 0xB2, 0x03, 0x29, 0xD4, 0xBF, 0x5B, 0x18, -+0x03, 0x33, 0xB2, 0xE7, 0x49, 0x79, 0x49, 0x1B, 0x21, 0x44, 0x49, 0xB2, 0x05, 0x29, 0xD4, 0xBF, 0x5B, 0x18, 0x05, 0x33, -+0x01, 0x30, 0xA8, 0xE7, 0x53, 0x78, 0x5B, 0x1B, 0x19, 0x44, 0x49, 0xB2, 0x6F, 0xF0, 0x04, 0x03, 0x01, 0x3C, 0x99, 0x42, -+0xAC, 0xBF, 0x40, 0x18, 0xC0, 0x18, 0x08, 0xE7, 0xA4, 0xF1, 0x0A, 0x01, 0x49, 0xB2, 0x6F, 0xF0, 0x04, 0x04, 0x01, 0x38, -+0xA1, 0x42, 0xAC, 0xBF, 0x5B, 0x18, 0x1B, 0x19, 0x91, 0xE7, 0x00, 0xBF, 0xBC, 0x34, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, -+0xEC, 0x12, 0x17, 0x00, 0x68, 0x25, 0x17, 0x00, 0x04, 0x13, 0x17, 0x00, 0x6C, 0x25, 0x17, 0x00, 0x0C, 0x79, 0x15, 0x00, -+0xF8, 0x12, 0x17, 0x00, 0xB8, 0x78, 0x15, 0x00, 0x03, 0x36, 0x35, 0xDA, 0xA4, 0xF1, 0x09, 0x01, 0x49, 0xB2, 0x6F, 0xF0, -+0x04, 0x04, 0x01, 0x38, 0xA1, 0x42, 0xAC, 0xBF, 0x5B, 0x18, 0x1B, 0x19, 0x71, 0xE7, 0x01, 0x21, 0x0F, 0x46, 0x00, 0x22, -+0x0F, 0x23, 0x79, 0xE6, 0x03, 0x32, 0x09, 0xDA, 0x09, 0x39, 0x49, 0xB2, 0x6F, 0xF0, 0x04, 0x03, 0x01, 0x3C, 0x99, 0x42, -+0xAC, 0xBF, 0x40, 0x18, 0xC0, 0x18, 0xCC, 0xE6, 0x0F, 0x39, 0x49, 0xB2, 0x05, 0x29, 0xD4, 0xBF, 0x40, 0x18, 0x05, 0x30, -+0xC5, 0xE6, 0x53, 0x79, 0x5B, 0x1B, 0x19, 0x44, 0x49, 0xB2, 0x05, 0x29, 0xD4, 0xBF, 0x40, 0x18, 0x05, 0x30, 0x01, 0x34, -+0xBB, 0xE6, 0xA4, 0xF1, 0x11, 0x01, 0x49, 0xB2, 0x03, 0x29, 0xD4, 0xBF, 0x5B, 0x18, 0x03, 0x33, 0x02, 0x30, 0x46, 0xE7, -+0xA4, 0xF1, 0x0F, 0x01, 0x49, 0xB2, 0x05, 0x29, 0xD4, 0xBF, 0x5B, 0x18, 0x05, 0x33, 0x3E, 0xE7, 0x14, 0x22, 0xF6, 0x23, -+0x02, 0x70, 0x0B, 0x70, 0x70, 0x47, 0x00, 0xBF, 0x08, 0xB5, 0x09, 0x49, 0x09, 0x48, 0x22, 0xF0, 0xF3, 0xFD, 0x09, 0x4B, -+0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x00, 0xDB, 0x08, 0xBD, 0xBD, 0xE8, 0x08, 0x40, 0x05, 0x49, 0x06, 0x48, -+0x39, 0x22, 0x23, 0xF0, 0x5F, 0xB8, 0x00, 0xBF, 0x50, 0x79, 0x15, 0x00, 0xCC, 0xB5, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x1F, 0x49, 0x20, 0x4A, 0x88, 0x68, 0x20, 0x4B, 0x10, 0xB4, 0xD2, 0xF8, -+0x14, 0x44, 0x04, 0x65, 0x10, 0x20, 0x18, 0x60, 0x88, 0x68, 0xD2, 0xF8, 0xA0, 0x42, 0x44, 0x65, 0x20, 0x20, 0x18, 0x60, -+0x88, 0x68, 0xD2, 0xF8, 0xA0, 0x42, 0xC4, 0x65, 0x80, 0x20, 0x18, 0x60, 0x88, 0x68, 0xD2, 0xF8, 0xD8, 0x40, 0x84, 0x64, -+0x04, 0x20, 0x18, 0x60, 0x88, 0x68, 0xD2, 0xF8, 0x0C, 0x44, 0xC4, 0x64, 0xF8, 0x24, 0x08, 0x20, 0x83, 0xF8, 0x03, 0x43, -+0x18, 0x60, 0x88, 0x68, 0xD2, 0xF8, 0x1C, 0x41, 0xC0, 0xF8, 0x0C, 0x41, 0x4F, 0xF4, 0x00, 0x20, 0x58, 0x60, 0x89, 0x68, -+0xD2, 0xF8, 0x2C, 0x21, 0xC1, 0xF8, 0x10, 0x21, 0x4F, 0xF4, 0x80, 0x10, 0x4F, 0xF4, 0x00, 0x41, 0x4F, 0xF4, 0x00, 0x12, -+0x58, 0x60, 0x99, 0x60, 0x1A, 0x60, 0x62, 0xB6, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0xBF, 0x00, 0xED, 0x00, 0xE0, -+0x88, 0x1A, 0x17, 0x00, 0x00, 0xE1, 0x00, 0xE0, 0x33, 0x49, 0x34, 0x4B, 0x0A, 0x68, 0x00, 0x28, 0x22, 0xF4, 0x00, 0x62, -+0xF0, 0xB5, 0x32, 0x4D, 0x0A, 0x60, 0x06, 0xBF, 0x1D, 0x46, 0x30, 0x26, 0x20, 0x26, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, -+0x13, 0xF0, 0xFF, 0x03, 0xFA, 0xD1, 0x2A, 0x4F, 0x2C, 0x4C, 0x3A, 0x68, 0x22, 0xF4, 0x80, 0x52, 0x3A, 0x60, 0x3A, 0x68, -+0x42, 0xF4, 0x80, 0x62, 0x3A, 0x60, 0x3A, 0x68, 0x42, 0xF4, 0x00, 0x62, 0x3A, 0x60, 0xB6, 0x00, 0x19, 0x46, 0x3A, 0x46, -+0x4F, 0xF0, 0xFF, 0x0E, 0xC8, 0x1C, 0xC0, 0xB2, 0xAC, 0x46, 0x13, 0x68, 0x23, 0xF0, 0xFF, 0x03, 0x03, 0x43, 0x13, 0x60, -+0x5C, 0xF8, 0x04, 0x3B, 0x23, 0x60, 0x13, 0x68, 0x43, 0xF4, 0x80, 0x73, 0x13, 0x60, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, -+0x00, 0xBF, 0x13, 0x68, 0x9B, 0x04, 0xFC, 0xD5, 0x01, 0x38, 0xC0, 0xB2, 0x70, 0x45, 0xE8, 0xD1, 0x04, 0x31, 0x04, 0x30, -+0xB1, 0x42, 0x5F, 0xFA, 0x80, 0xFE, 0x05, 0xF1, 0x10, 0x05, 0xDD, 0xD1, 0x3B, 0x68, 0x23, 0xF4, 0x80, 0x63, 0x3B, 0x60, -+0xC8, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x13, 0xF0, 0xFF, 0x03, 0xFA, 0xD1, 0x0A, 0x4A, 0x13, 0x68, 0x23, 0xF4, 0x00, 0x63, -+0x13, 0x60, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x13, 0xF0, 0xFF, 0x03, 0xFA, 0xD1, 0x05, 0x4B, 0x1A, 0x68, 0x42, 0xF4, -+0x80, 0x52, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF4, 0x00, 0x62, 0x1A, 0x60, 0xF0, 0xBD, 0x00, 0xBF, 0x60, 0x40, 0x34, 0x40, -+0x1C, 0x13, 0x17, 0x00, 0x1C, 0x16, 0x17, 0x00, 0x64, 0x40, 0x34, 0x40, 0x44, 0x4A, 0x45, 0x49, 0x13, 0x68, 0xF0, 0xB4, -+0x44, 0x4D, 0x23, 0xF4, 0x00, 0x63, 0x13, 0x60, 0x00, 0x28, 0x0C, 0xBF, 0x28, 0x46, 0x08, 0x46, 0x32, 0x23, 0x00, 0xBF, -+0x01, 0x3B, 0x13, 0xF0, 0xFF, 0x03, 0xFA, 0xD1, 0x3B, 0x4A, 0x3E, 0x4D, 0x13, 0x68, 0x23, 0xF4, 0x80, 0x53, 0x13, 0x60, -+0x13, 0x68, 0x43, 0xF4, 0x80, 0x63, 0x13, 0x60, 0x13, 0x68, 0x43, 0xF4, 0x00, 0x63, 0x13, 0x60, 0x03, 0x21, 0xA0, 0xF1, -+0x0C, 0x04, 0x13, 0x68, 0x23, 0xF0, 0xFF, 0x03, 0x0B, 0x43, 0x13, 0x60, 0x54, 0xF8, 0x21, 0x30, 0x2B, 0x60, 0x13, 0x68, -+0x43, 0xF4, 0x80, 0x73, 0x13, 0x60, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x13, 0x68, 0x9E, 0x04, 0xFC, 0xD5, -+0x04, 0x31, 0x43, 0x29, 0xE9, 0xD1, 0x28, 0x4B, 0x2B, 0x4E, 0x2A, 0x4D, 0x04, 0x1F, 0x02, 0x21, 0x1A, 0x68, 0x22, 0xF0, -+0xFF, 0x02, 0x0A, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF4, 0x00, 0x72, 0x1A, 0x60, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, -+0x00, 0xBF, 0x1A, 0x68, 0x90, 0x04, 0xFC, 0xD5, 0x37, 0x68, 0x54, 0xF8, 0x21, 0x20, 0x18, 0x68, 0x27, 0xF0, 0x7F, 0x47, -+0x02, 0xF0, 0x7F, 0x42, 0x20, 0xF0, 0xFF, 0x00, 0x3A, 0x43, 0x08, 0x43, 0x18, 0x60, 0x2A, 0x60, 0x1A, 0x68, 0x42, 0xF4, -+0x80, 0x72, 0x1A, 0x60, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x1A, 0x68, 0x92, 0x04, 0xFC, 0xD5, 0x04, 0x31, -+0x42, 0x29, 0xD3, 0xD1, 0x1A, 0x68, 0x22, 0xF4, 0x80, 0x62, 0x1A, 0x60, 0xC8, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x13, 0xF0, -+0xFF, 0x03, 0xFA, 0xD1, 0x0A, 0x4A, 0x13, 0x68, 0x23, 0xF4, 0x00, 0x63, 0x13, 0x60, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, -+0x13, 0xF0, 0xFF, 0x03, 0xFA, 0xD1, 0x05, 0x4B, 0x1A, 0x68, 0x42, 0xF4, 0x80, 0x52, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF4, -+0x00, 0x62, 0xF0, 0xBC, 0x1A, 0x60, 0x70, 0x47, 0x60, 0x40, 0x34, 0x40, 0x1C, 0x16, 0x17, 0x00, 0x1C, 0x13, 0x17, 0x00, -+0x64, 0x40, 0x34, 0x40, 0x68, 0x40, 0x34, 0x40, 0x2C, 0x49, 0x2D, 0x4B, 0x0A, 0x68, 0x30, 0xB4, 0x2C, 0x4C, 0x00, 0x28, -+0x22, 0xF4, 0x80, 0x72, 0x0C, 0xBF, 0x18, 0x46, 0x20, 0x46, 0x0A, 0x60, 0x0C, 0xBF, 0x20, 0x24, 0x10, 0x24, 0x32, 0x23, -+0x00, 0xBF, 0x01, 0x3B, 0x13, 0xF0, 0xFF, 0x03, 0xFA, 0xD1, 0x22, 0x49, 0x24, 0x4D, 0x0A, 0x68, 0x22, 0xF4, 0x00, 0x72, -+0x0A, 0x60, 0x0A, 0x68, 0x42, 0xF0, 0x80, 0x02, 0x0A, 0x60, 0x0A, 0x68, 0x42, 0xF4, 0x80, 0x72, 0x04, 0x38, 0x0A, 0x60, -+0x0A, 0x68, 0x22, 0xF0, 0x1F, 0x02, 0x1A, 0x43, 0x0A, 0x60, 0x50, 0xF8, 0x04, 0x2F, 0x2A, 0x60, 0x0A, 0x68, 0x42, 0xF0, -+0x20, 0x02, 0x0A, 0x60, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x0A, 0x68, 0x52, 0x05, 0xFC, 0xD5, 0x01, 0x33, -+0x9C, 0x42, 0xE9, 0xD1, 0x0B, 0x68, 0x23, 0xF0, 0x80, 0x03, 0x0B, 0x60, 0xC8, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x13, 0xF0, -+0xFF, 0x03, 0xFA, 0xD1, 0x0A, 0x4A, 0x13, 0x68, 0x23, 0xF4, 0x80, 0x73, 0x13, 0x60, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, -+0x13, 0xF0, 0xFF, 0x03, 0xFA, 0xD1, 0x05, 0x4B, 0x1A, 0x68, 0x42, 0xF4, 0x00, 0x72, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF4, -+0x80, 0x72, 0x30, 0xBC, 0x1A, 0x60, 0x70, 0x47, 0x6C, 0x40, 0x34, 0x40, 0x1C, 0x18, 0x17, 0x00, 0x9C, 0x18, 0x17, 0x00, -+0x70, 0x40, 0x34, 0x40, 0x2D, 0xE9, 0xF0, 0x41, 0xA6, 0x49, 0xA7, 0x4C, 0xA7, 0x4B, 0xA8, 0x4A, 0xDF, 0xF8, 0xE8, 0xE2, -+0x00, 0x28, 0x0E, 0xBF, 0xA4, 0x46, 0x8C, 0x46, 0x9E, 0x46, 0x13, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0xA3, 0x4C, 0xA4, 0x49, -+0x23, 0x68, 0x23, 0xF0, 0x02, 0x03, 0x23, 0x60, 0x01, 0x23, 0x13, 0x60, 0x0B, 0x68, 0xA1, 0x4A, 0x23, 0xF4, 0x00, 0x63, -+0x0B, 0x60, 0x13, 0x68, 0x23, 0xF4, 0x80, 0x73, 0x13, 0x60, 0x32, 0x24, 0x00, 0xBF, 0x01, 0x3C, 0x14, 0xF0, 0xFF, 0x04, -+0xFA, 0xD1, 0xDF, 0xF8, 0x64, 0x82, 0x99, 0x4A, 0xD8, 0xF8, 0x00, 0x30, 0x98, 0x4F, 0x23, 0xF4, 0x80, 0x53, 0xC8, 0xF8, -+0x00, 0x30, 0x13, 0x68, 0x23, 0xF4, 0x00, 0x73, 0x13, 0x60, 0xD8, 0xF8, 0x00, 0x30, 0x43, 0xF4, 0x80, 0x63, 0xC8, 0xF8, -+0x00, 0x30, 0xD8, 0xF8, 0x00, 0x30, 0x43, 0xF4, 0x00, 0x63, 0xC8, 0xF8, 0x00, 0x30, 0x42, 0x46, 0xFF, 0x26, 0xE1, 0x1C, -+0xC9, 0xB2, 0x75, 0x46, 0x13, 0x68, 0x23, 0xF0, 0xFF, 0x03, 0x0B, 0x43, 0x13, 0x60, 0x55, 0xF8, 0x04, 0x3B, 0x3B, 0x60, -+0x13, 0x68, 0x43, 0xF4, 0x80, 0x73, 0x13, 0x60, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x13, 0x68, 0x9B, 0x04, -+0xFC, 0xD5, 0x01, 0x39, 0xC9, 0xB2, 0x8E, 0x42, 0xE8, 0xD1, 0x04, 0x34, 0x04, 0x36, 0x80, 0x2C, 0xF6, 0xB2, 0x0E, 0xF1, -+0x10, 0x0E, 0xDE, 0xD1, 0xD8, 0xF8, 0x00, 0x30, 0x23, 0xF4, 0x80, 0x63, 0xC8, 0xF8, 0x00, 0x30, 0xC8, 0x23, 0x00, 0xBF, -+0x01, 0x3B, 0x13, 0xF0, 0xFF, 0x03, 0xFA, 0xD1, 0x74, 0x4C, 0x75, 0x49, 0x22, 0x68, 0x22, 0xF4, 0x00, 0x62, 0x22, 0x60, -+0x0A, 0x68, 0x42, 0xF0, 0x80, 0x02, 0x0A, 0x60, 0x0A, 0x68, 0x42, 0xF4, 0x80, 0x72, 0x10, 0x34, 0xAC, 0xF1, 0x04, 0x0C, -+0x0A, 0x60, 0x0A, 0x68, 0x22, 0xF0, 0x1F, 0x02, 0x1A, 0x43, 0x0A, 0x60, 0x5C, 0xF8, 0x04, 0x2F, 0x22, 0x60, 0x0A, 0x68, -+0x42, 0xF0, 0x20, 0x02, 0x0A, 0x60, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x0A, 0x68, 0x52, 0x05, 0xFC, 0xD5, -+0x01, 0x33, 0x10, 0x2B, 0xE9, 0xD1, 0x0B, 0x68, 0x23, 0xF0, 0x80, 0x03, 0x0B, 0x60, 0xC8, 0x23, 0x00, 0xBF, 0x01, 0x3B, -+0x13, 0xF0, 0xFF, 0x03, 0xFA, 0xD1, 0x5D, 0x49, 0x5E, 0x4A, 0x0B, 0x68, 0x23, 0xF4, 0x80, 0x73, 0x0B, 0x60, 0x13, 0x68, -+0x43, 0xF4, 0x00, 0x13, 0x13, 0x60, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x13, 0xF0, 0xFF, 0x03, 0xFA, 0xD1, 0x54, 0x49, -+0x54, 0x4B, 0x0C, 0x68, 0x56, 0x4A, 0x57, 0x4D, 0x44, 0xF4, 0x80, 0x54, 0x0C, 0x60, 0x1C, 0x68, 0x44, 0xF4, 0x00, 0x74, -+0x1C, 0x60, 0x0C, 0x68, 0x44, 0xF4, 0x00, 0x64, 0x0C, 0x60, 0x19, 0x68, 0x51, 0x4C, 0x41, 0xF4, 0x80, 0x71, 0x19, 0x60, -+0x11, 0x68, 0x50, 0x4B, 0x41, 0xF4, 0x80, 0x51, 0x11, 0x60, 0x29, 0x68, 0x21, 0xF4, 0x80, 0x21, 0x29, 0x60, 0x21, 0x68, -+0x21, 0xF0, 0x00, 0x51, 0x21, 0x60, 0xA5, 0xF5, 0xBC, 0x45, 0x1C, 0x68, 0x2C, 0x60, 0x49, 0x49, 0x5D, 0x68, 0x0D, 0x60, -+0x48, 0x4C, 0x9D, 0x68, 0x25, 0x60, 0xDD, 0x68, 0x8D, 0x60, 0x1D, 0x69, 0xA5, 0x60, 0x5C, 0x69, 0x0C, 0x61, 0xD3, 0xE9, -+0x06, 0x64, 0x44, 0x4D, 0x44, 0x4B, 0x2E, 0x60, 0x8C, 0x61, 0x9B, 0x78, 0x18, 0x31, 0xCB, 0xB1, 0xA5, 0xF6, 0x78, 0x65, -+0x41, 0x4C, 0x2B, 0x68, 0x23, 0xF0, 0xC0, 0x63, 0x43, 0xF0, 0x00, 0x73, 0x2B, 0x60, 0x23, 0x68, 0x01, 0xF5, 0xBB, 0x41, -+0x7C, 0x31, 0x43, 0xF0, 0x80, 0x63, 0x23, 0x60, 0x0B, 0x68, 0x43, 0xF4, 0x00, 0x63, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF4, -+0x40, 0x63, 0x43, 0xF4, 0x00, 0x63, 0x13, 0x60, 0x36, 0x4B, 0x93, 0xF8, 0xFA, 0x30, 0x38, 0xB9, 0x43, 0xBB, 0x35, 0x4A, -+0x13, 0x68, 0x23, 0xF0, 0x02, 0x03, 0x13, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0xCB, 0xB1, 0x32, 0x49, 0x32, 0x4A, 0x0B, 0x68, -+0x23, 0xF0, 0xFF, 0x03, 0x43, 0xF0, 0xB5, 0x03, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF0, 0xFF, 0x03, 0x43, 0xF0, 0xB5, 0x03, -+0x13, 0x60, 0x0B, 0x68, 0x23, 0xF4, 0x7F, 0x23, 0x43, 0xF4, 0x32, 0x23, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF4, 0x7F, 0x23, -+0x43, 0xF4, 0x32, 0x23, 0x13, 0x60, 0x24, 0x4A, 0x13, 0x68, 0x43, 0xF0, 0x02, 0x03, 0x13, 0x60, 0xBD, 0xE8, 0xF0, 0x81, -+0x21, 0x49, 0x22, 0x4A, 0x0B, 0x68, 0x23, 0xF0, 0xFF, 0x03, 0x43, 0xF0, 0xC2, 0x03, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF0, -+0xFF, 0x03, 0x43, 0xF0, 0xC2, 0x03, 0x13, 0x60, 0x0B, 0x68, 0x23, 0xF4, 0x7F, 0x23, 0x43, 0xF4, 0x3F, 0x23, 0x0B, 0x60, -+0x13, 0x68, 0x23, 0xF4, 0x7F, 0x23, 0x43, 0xF4, 0x3F, 0x23, 0x13, 0x60, 0xBB, 0xE7, 0x00, 0xBF, 0x9C, 0x18, 0x17, 0x00, -+0x1C, 0x18, 0x17, 0x00, 0x1C, 0x16, 0x17, 0x00, 0x40, 0x42, 0x04, 0x40, 0x18, 0x00, 0x58, 0x40, 0x60, 0x40, 0x34, 0x40, -+0x6C, 0x40, 0x34, 0x40, 0x64, 0x40, 0x34, 0x40, 0x58, 0x40, 0x34, 0x40, 0x14, 0x20, 0x34, 0x40, 0x18, 0x20, 0x34, 0x40, -+0x1C, 0x20, 0x34, 0x40, 0xDC, 0x18, 0x17, 0x00, 0x1C, 0xC2, 0x33, 0x40, 0x20, 0xC2, 0x33, 0x40, 0x30, 0xC2, 0x33, 0x40, -+0x3C, 0x36, 0x17, 0x00, 0x38, 0x40, 0x34, 0x40, 0x2C, 0x19, 0x17, 0x00, 0x94, 0x40, 0x04, 0x40, 0xAC, 0xB3, 0x33, 0x40, -+0xD4, 0xB3, 0x33, 0x40, 0x1C, 0x13, 0x17, 0x00, 0x10, 0xB4, 0x1C, 0x4B, 0x1C, 0x4C, 0x0F, 0xCB, 0x85, 0xB0, 0x0D, 0xF1, -+0x10, 0x0C, 0x0C, 0xE9, 0x0F, 0x00, 0x63, 0x68, 0xDB, 0x06, 0x16, 0xD5, 0x61, 0x68, 0xA3, 0x69, 0x5C, 0xFA, 0x83, 0xF3, -+0xC8, 0x04, 0x13, 0xF8, 0x10, 0x2C, 0x22, 0xD4, 0x60, 0x68, 0x14, 0x49, 0x14, 0x4B, 0x10, 0xF4, 0x80, 0x7F, 0x08, 0xBF, -+0x0B, 0x46, 0x11, 0x06, 0x44, 0xBF, 0x5B, 0x00, 0x02, 0xF0, 0x7F, 0x02, 0xB3, 0xFB, 0xF2, 0xF3, 0x00, 0xE0, 0x0F, 0x4B, -+0x0B, 0x4A, 0x0F, 0x4C, 0x52, 0x69, 0x0F, 0x48, 0x0F, 0x49, 0xD2, 0xB2, 0xB3, 0xFB, 0xF2, 0xF3, 0x23, 0x60, 0xD0, 0xF8, -+0x84, 0x20, 0xD2, 0xB2, 0xB3, 0xFB, 0xF2, 0xF3, 0x0B, 0x60, 0x05, 0xB0, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x09, 0x4B, -+0xE1, 0xE7, 0x00, 0xBF, 0x60, 0x79, 0x15, 0x00, 0x00, 0x00, 0x50, 0x40, 0x00, 0x38, 0x9C, 0x1C, 0x00, 0xD0, 0x12, 0x13, -+0x00, 0x75, 0x19, 0x03, 0x18, 0x13, 0x17, 0x00, 0x00, 0x00, 0x10, 0x40, 0x14, 0x13, 0x17, 0x00, 0x00, 0x70, 0x38, 0x39, -+0x70, 0xB4, 0x5D, 0x4C, 0x5D, 0x48, 0x23, 0x68, 0x5D, 0x4D, 0x5E, 0x49, 0x5E, 0x4A, 0x23, 0xF4, 0xC0, 0x63, 0x43, 0xF4, -+0x00, 0x73, 0x23, 0x60, 0x03, 0x68, 0x95, 0xF8, 0xFA, 0x40, 0x23, 0xF4, 0xBC, 0x03, 0x23, 0xF4, 0x70, 0x53, 0x43, 0xF4, -+0x60, 0x23, 0x43, 0xF4, 0x80, 0x63, 0x03, 0x60, 0x0B, 0x68, 0x23, 0xF0, 0x60, 0x03, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF4, -+0xFE, 0x33, 0x43, 0xF4, 0x98, 0x33, 0x13, 0x60, 0x00, 0x2C, 0x00, 0xF0, 0x8F, 0x80, 0xA2, 0xF5, 0x11, 0x12, 0xA2, 0xF6, -+0x4C, 0x52, 0x13, 0x68, 0x23, 0xF0, 0xC0, 0x63, 0x13, 0x60, 0x4C, 0x4D, 0x4C, 0x48, 0x2B, 0x68, 0x4C, 0x4C, 0x4D, 0x4A, -+0x4D, 0x49, 0x4E, 0x4E, 0x43, 0xF0, 0x80, 0x63, 0x2B, 0x60, 0x03, 0x68, 0x43, 0xF4, 0x00, 0x63, 0x03, 0x60, 0x23, 0x68, -+0x23, 0xF4, 0x7F, 0x73, 0x43, 0xF0, 0x04, 0x03, 0x23, 0x60, 0x03, 0x68, 0x23, 0xF4, 0x80, 0x53, 0x43, 0xF4, 0x00, 0x63, -+0x03, 0x60, 0x13, 0x68, 0x23, 0xF0, 0xCC, 0x03, 0x43, 0xF0, 0xC4, 0x03, 0x13, 0x60, 0x0B, 0x68, 0x03, 0xF0, 0x7F, 0x43, -+0xA5, 0xF5, 0xF8, 0x55, 0x43, 0xF4, 0x78, 0x13, 0x0C, 0x3D, 0x43, 0xF4, 0x78, 0x73, 0x0B, 0x60, 0x2B, 0x68, 0x1B, 0x0C, -+0xA4, 0xF5, 0x00, 0x54, 0x1B, 0x04, 0x34, 0x3C, 0x43, 0xF0, 0x84, 0x03, 0x2B, 0x60, 0x23, 0x68, 0x37, 0x4D, 0x23, 0xF4, -+0x40, 0x63, 0x43, 0xF4, 0x00, 0x63, 0x23, 0x60, 0xD0, 0xF8, 0x04, 0x31, 0x02, 0xF5, 0xF8, 0x52, 0x23, 0xF4, 0xE0, 0x23, -+0x18, 0x32, 0x43, 0xF4, 0x80, 0x33, 0xC0, 0xF8, 0x04, 0x31, 0x13, 0x68, 0x23, 0xF0, 0x76, 0x53, 0x23, 0xF0, 0x07, 0x03, -+0x01, 0xF5, 0xF7, 0x51, 0x43, 0xF0, 0x04, 0x53, 0x04, 0x31, 0x43, 0xF0, 0x07, 0x03, 0x13, 0x60, 0x0B, 0x68, 0x04, 0xF5, -+0x00, 0x54, 0x02, 0xF1, 0xEF, 0x52, 0x00, 0xF5, 0x01, 0x50, 0x1C, 0x34, 0x02, 0xF5, 0x3D, 0x22, 0x02, 0xF6, 0x44, 0x02, -+0x1D, 0x40, 0x08, 0x30, 0x22, 0x4B, 0x0D, 0x60, 0x32, 0x60, 0x23, 0x60, 0x03, 0x68, 0x21, 0x4A, 0x21, 0x4C, 0x23, 0xF4, -+0x7F, 0x23, 0x23, 0xF4, 0x00, 0x63, 0x43, 0xF4, 0x32, 0x33, 0x03, 0x60, 0xCB, 0x68, 0x43, 0xF4, 0x00, 0x63, 0xCB, 0x60, -+0x13, 0x68, 0x23, 0xF0, 0x09, 0x03, 0x43, 0xF4, 0x80, 0x53, 0x13, 0x60, 0x23, 0x68, 0x1B, 0x07, 0x08, 0xD5, 0xA2, 0xF5, -+0x0F, 0x12, 0xA2, 0xF5, 0x03, 0x52, 0x24, 0x3A, 0x13, 0x68, 0x23, 0xF4, 0x00, 0x53, 0x13, 0x60, 0x70, 0xBC, 0x70, 0x47, -+0x12, 0x4A, 0x13, 0x68, 0x23, 0xF0, 0xC0, 0x63, 0x43, 0xF0, 0x00, 0x73, 0x13, 0x60, 0x70, 0xE7, 0x20, 0x40, 0x34, 0x40, -+0x24, 0x40, 0x34, 0x40, 0x2C, 0x19, 0x17, 0x00, 0x28, 0x40, 0x34, 0x40, 0x04, 0x01, 0x58, 0x40, 0x38, 0x40, 0x34, 0x40, -+0x30, 0x20, 0x34, 0x40, 0x48, 0x40, 0x34, 0x40, 0x28, 0x21, 0x34, 0x40, 0x24, 0x21, 0x34, 0x40, 0x2C, 0x40, 0x34, 0x40, -+0x03, 0x00, 0x00, 0xFF, 0x08, 0x51, 0x2E, 0x1A, 0x08, 0x01, 0x58, 0x40, 0x94, 0x40, 0x04, 0x40, 0xB8, 0xB3, 0x33, 0x40, -+0x38, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0D, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0D, 0x4D, -+0x0D, 0x4C, 0x2B, 0x68, 0x01, 0x33, 0x2B, 0x60, 0x23, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x4F, 0xF4, 0xDE, 0x73, 0x1B, 0x68, -+0x98, 0x47, 0x01, 0x23, 0x23, 0x60, 0x2B, 0x68, 0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x38, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x5C, 0x40, 0x04, 0x40, -+0x38, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0D, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0D, 0x4D, -+0x0D, 0x4C, 0x2B, 0x68, 0x01, 0x33, 0x2B, 0x60, 0x23, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x4F, 0xF4, 0xE6, 0x73, 0x1B, 0x68, -+0x98, 0x47, 0x01, 0x23, 0x23, 0x60, 0x2B, 0x68, 0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x38, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x5C, 0x40, 0x04, 0x40, -+0x38, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0D, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0D, 0x4D, -+0x0D, 0x4C, 0x2B, 0x68, 0x01, 0x33, 0x2B, 0x60, 0x23, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x4F, 0xF4, 0xE8, 0x73, 0x1B, 0x68, -+0x98, 0x47, 0x01, 0x23, 0x23, 0x60, 0x2B, 0x68, 0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x38, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x5C, 0x40, 0x04, 0x40, -+0x38, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0D, 0x4B, 0x01, 0x24, 0x1C, 0x60, 0x0D, 0x4D, -+0x0D, 0x4C, 0x2B, 0x68, 0x01, 0x33, 0x2B, 0x60, 0x23, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x4F, 0xF4, 0xEA, 0x73, 0x1B, 0x68, -+0x98, 0x47, 0x01, 0x23, 0x23, 0x60, 0x2B, 0x68, 0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x38, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x5C, 0x40, 0x04, 0x40, -+0x2D, 0xE9, 0xF0, 0x47, 0x4C, 0x4B, 0x4D, 0x4D, 0x08, 0x22, 0xC3, 0xF8, 0x00, 0x21, 0xAB, 0x78, 0x33, 0xB9, 0x4B, 0x4A, -+0x93, 0x68, 0x23, 0xF4, 0x80, 0x23, 0x43, 0xF4, 0x00, 0x33, 0x93, 0x60, 0x47, 0x4A, 0x13, 0x6B, 0x03, 0xF0, 0x22, 0x03, -+0x02, 0x2B, 0xFA, 0xD1, 0x93, 0x68, 0x45, 0x4C, 0x41, 0x49, 0x45, 0x48, 0x23, 0xF4, 0x00, 0x63, 0x43, 0xF0, 0x01, 0x13, -+0x43, 0xF4, 0x04, 0x43, 0x93, 0x60, 0x06, 0x23, 0x23, 0x60, 0x53, 0x6D, 0x40, 0x4C, 0x23, 0xF4, 0x40, 0x13, 0x53, 0x65, -+0x4F, 0xF4, 0x00, 0x63, 0xC1, 0xF8, 0x34, 0x31, 0x13, 0x68, 0x11, 0x68, 0xC3, 0xF3, 0x09, 0x03, 0x43, 0xF0, 0x80, 0x03, -+0x01, 0x40, 0x0B, 0x43, 0x13, 0x60, 0x23, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x08, 0xD1, 0x13, 0x68, 0x11, 0x68, 0xC3, 0xF3, -+0x09, 0x03, 0x43, 0xF0, 0x08, 0x03, 0x08, 0x40, 0x18, 0x43, 0x10, 0x60, 0x2E, 0x49, 0x2C, 0x4E, 0x0B, 0x68, 0x0A, 0x68, -+0x30, 0x48, 0xC3, 0xF3, 0x09, 0x03, 0x22, 0xF4, 0x7F, 0x72, 0x22, 0xF0, 0x03, 0x02, 0x43, 0xF4, 0x80, 0x73, 0x13, 0x43, -+0x0B, 0x60, 0x73, 0x6F, 0x2B, 0x4A, 0x43, 0xF0, 0x02, 0x03, 0x73, 0x67, 0x03, 0x68, 0x2A, 0x4E, 0x23, 0xF4, 0x00, 0x63, -+0x03, 0x60, 0x13, 0x68, 0x96, 0xF8, 0xA9, 0x00, 0x43, 0xF0, 0x80, 0x73, 0x13, 0x60, 0x68, 0xB1, 0x0B, 0x6B, 0x5F, 0x06, -+0x05, 0xD4, 0x0B, 0x6B, 0x58, 0x07, 0x02, 0xD5, 0x22, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0x1A, 0x4B, 0x1A, 0x6B, 0x52, 0x06, -+0x40, 0xF1, 0x10, 0x82, 0x1F, 0x4B, 0xD6, 0xF8, 0xA0, 0x20, 0x1A, 0x60, 0xAB, 0x78, 0x00, 0x2B, 0x3E, 0xD0, 0x1D, 0x4B, -+0x1A, 0x68, 0x13, 0x78, 0x02, 0x2B, 0x00, 0xF0, 0x6C, 0x82, 0x11, 0x4B, 0x0E, 0x48, 0x02, 0x21, 0x11, 0x70, 0x1A, 0x6D, -+0xA9, 0x78, 0x42, 0xF4, 0x80, 0x22, 0x1A, 0x65, 0x02, 0x69, 0x22, 0xF0, 0x80, 0x02, 0x02, 0x61, 0x5A, 0x6A, 0x22, 0xF0, -+0xFF, 0x02, 0x42, 0xF0, 0xDF, 0x02, 0x5A, 0x62, 0x5A, 0x6A, 0x22, 0xF4, 0x7F, 0x42, 0x42, 0xF4, 0x5F, 0x42, 0x5A, 0x62, -+0x00, 0x29, 0x33, 0xD0, 0x03, 0xF0, 0xB0, 0xFC, 0x0C, 0x4F, 0x33, 0xE0, 0x00, 0x00, 0x50, 0x40, 0x3C, 0x36, 0x17, 0x00, -+0x00, 0x60, 0x50, 0x40, 0x10, 0x00, 0x58, 0x40, 0x00, 0xFC, 0xFF, 0xFF, 0x78, 0x36, 0x17, 0x00, 0x00, 0x01, 0x58, 0x40, -+0x20, 0x01, 0x58, 0x40, 0x2C, 0x19, 0x17, 0x00, 0x4C, 0x36, 0x17, 0x00, 0xE0, 0x50, 0x34, 0x40, 0x74, 0x36, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0xC0, 0x4B, 0xC1, 0x49, 0x1A, 0x6D, 0x42, 0xF4, 0x80, 0x22, 0x1A, 0x65, 0x0A, 0x69, 0x22, 0xF0, -+0x80, 0x02, 0x0A, 0x61, 0x5A, 0x6A, 0x22, 0xF0, 0xFF, 0x02, 0x42, 0xF0, 0xDF, 0x02, 0x5A, 0x62, 0x5A, 0x6A, 0x22, 0xF4, -+0x7F, 0x42, 0x42, 0xF4, 0x5F, 0x42, 0x5A, 0x62, 0xB7, 0x4F, 0xD7, 0xF8, 0xCC, 0x30, 0x98, 0x47, 0x03, 0xF0, 0xF4, 0xF9, -+0xD7, 0xF8, 0x9C, 0x34, 0x98, 0x47, 0xB2, 0x4B, 0xB3, 0x49, 0x1B, 0x68, 0xB3, 0x4A, 0xA8, 0x78, 0x1B, 0x0C, 0x0B, 0x70, -+0x04, 0x23, 0x1B, 0x68, 0x1B, 0x09, 0x13, 0x70, 0x10, 0xB9, 0xD7, 0xF8, 0x80, 0x34, 0x98, 0x47, 0xAE, 0x48, 0xAF, 0x4D, -+0xFF, 0xF7, 0x78, 0xFE, 0xAE, 0x48, 0xFF, 0xF7, 0x9D, 0xFE, 0x03, 0x46, 0x1A, 0x0C, 0xAD, 0x49, 0x2A, 0x70, 0x1B, 0x0F, -+0x02, 0x22, 0x0B, 0x70, 0xAB, 0x48, 0x11, 0x46, 0xFF, 0xF7, 0xE2, 0xFE, 0x4F, 0xF4, 0x80, 0x52, 0x11, 0x46, 0xA9, 0x48, -+0xFF, 0xF7, 0xDC, 0xFE, 0xA8, 0x4A, 0xA9, 0x49, 0xA9, 0x48, 0xFF, 0xF7, 0xD7, 0xFE, 0x2B, 0x78, 0x01, 0x2B, 0x00, 0xF0, -+0x8E, 0x81, 0xA7, 0x48, 0x4F, 0xF4, 0x7F, 0x52, 0x4F, 0xF4, 0x9E, 0x51, 0xFF, 0xF7, 0xCC, 0xFE, 0x04, 0x22, 0xA4, 0x48, -+0x11, 0x46, 0xFF, 0xF7, 0xC7, 0xFE, 0x23, 0x68, 0x1B, 0x78, 0x02, 0x2B, 0x04, 0xD0, 0xA1, 0x48, 0x07, 0x22, 0x00, 0x21, -+0xFF, 0xF7, 0xBE, 0xFE, 0x01, 0x21, 0x02, 0x20, 0x03, 0xF0, 0x5C, 0xFE, 0x04, 0x22, 0x9D, 0x48, 0x00, 0x21, 0xFF, 0xF7, -+0xB5, 0xFE, 0x01, 0x21, 0x03, 0x20, 0x03, 0xF0, 0x53, 0xFE, 0x08, 0x22, 0x98, 0x48, 0x00, 0x21, 0xFF, 0xF7, 0xAC, 0xFE, -+0x00, 0x21, 0x05, 0x20, 0x03, 0xF0, 0x4A, 0xFE, 0x95, 0x48, 0x20, 0x22, 0x00, 0x21, 0xFF, 0xF7, 0xA3, 0xFE, 0x20, 0x22, -+0x11, 0x46, 0x93, 0x48, 0xFF, 0xF7, 0x9E, 0xFE, 0x20, 0x22, 0x11, 0x46, 0x91, 0x48, 0xFF, 0xF7, 0x99, 0xFE, 0x02, 0x22, -+0x90, 0x48, 0x11, 0x46, 0xFF, 0xF7, 0x94, 0xFE, 0x4F, 0xF4, 0xD2, 0x73, 0x0F, 0x20, 0x1B, 0x68, 0x98, 0x47, 0x00, 0xF0, -+0x60, 0x00, 0x20, 0x28, 0x00, 0xF0, 0x74, 0x81, 0x4F, 0xF4, 0xFC, 0x02, 0x11, 0x46, 0x89, 0x48, 0xFF, 0xF7, 0x84, 0xFE, -+0x88, 0x4A, 0x89, 0x48, 0x4F, 0xF0, 0x46, 0x41, 0xFF, 0xF7, 0x7E, 0xFE, 0x87, 0x48, 0x3F, 0x22, 0x1F, 0x21, 0xFF, 0xF7, -+0x79, 0xFE, 0x4F, 0xF4, 0x80, 0x22, 0x85, 0x48, 0x00, 0x21, 0xFF, 0xF7, 0x73, 0xFE, 0x84, 0x48, 0x4F, 0xF4, 0x8E, 0x71, -+0xFF, 0xF7, 0x46, 0xFE, 0x82, 0x48, 0x4F, 0xF4, 0xF8, 0x22, 0x4F, 0xF4, 0xD8, 0x21, 0xFF, 0xF7, 0x67, 0xFE, 0x40, 0x22, -+0x11, 0x46, 0x7F, 0x48, 0xFF, 0xF7, 0x62, 0xFE, 0x4F, 0xF4, 0xC0, 0x32, 0x11, 0x46, 0x7D, 0x48, 0xFF, 0xF7, 0x5C, 0xFE, -+0x7C, 0x48, 0x4F, 0xF4, 0xE0, 0x62, 0x4F, 0xF4, 0x00, 0x71, 0xFF, 0xF7, 0x55, 0xFE, 0x96, 0xF8, 0xC7, 0x70, 0xB7, 0xB3, -+0x78, 0x4A, 0x96, 0xF8, 0xC8, 0x10, 0x78, 0x4B, 0x96, 0xF8, 0xC9, 0x00, 0x11, 0x70, 0x96, 0xF8, 0xCA, 0x10, 0x50, 0x70, -+0x91, 0x70, 0x96, 0xF8, 0xCB, 0x50, 0x96, 0xF8, 0xCC, 0x00, 0x96, 0xF8, 0xCD, 0x10, 0x96, 0xF8, 0xCE, 0x20, 0x1D, 0x70, -+0x58, 0x70, 0x99, 0x70, 0xDA, 0x70, 0x4F, 0xF4, 0xD2, 0x73, 0x0F, 0x20, 0x1B, 0x68, 0x98, 0x47, 0x10, 0xF4, 0x60, 0x2F, -+0xC0, 0xF3, 0x42, 0x41, 0x0E, 0xD0, 0x6A, 0x4A, 0x8D, 0x01, 0x02, 0xF1, 0x40, 0x00, 0x52, 0xF8, 0x04, 0x3F, 0x23, 0xF4, -+0xE0, 0x73, 0x2B, 0x43, 0x90, 0x42, 0x13, 0x60, 0xF7, 0xD1, 0x65, 0x48, 0x03, 0xF0, 0x68, 0xFD, 0x23, 0x68, 0x1C, 0x78, -+0x01, 0x2C, 0x00, 0xF0, 0xEF, 0x80, 0xBD, 0xE8, 0xF0, 0x87, 0x4F, 0xF4, 0xD2, 0x76, 0x0A, 0x20, 0x33, 0x68, 0xDF, 0xF8, -+0x6C, 0xA1, 0x98, 0x47, 0x33, 0x68, 0x05, 0x46, 0x0B, 0x20, 0x98, 0x47, 0x33, 0x68, 0x80, 0x46, 0x0F, 0x20, 0x98, 0x47, -+0x5F, 0xEA, 0x95, 0x7C, 0x3A, 0x46, 0x0C, 0xBF, 0x4F, 0xF0, 0x08, 0x09, 0x4F, 0xF0, 0x10, 0x09, 0x4F, 0xEA, 0x15, 0x6E, -+0xD3, 0x00, 0x25, 0xFA, 0x03, 0xF3, 0xDF, 0xB2, 0xC3, 0xF3, 0x03, 0x13, 0xBC, 0xF1, 0x00, 0x0F, 0x38, 0xD1, 0x00, 0x2B, -+0x54, 0xD1, 0x00, 0x2F, 0x40, 0xF0, 0x1F, 0x81, 0x01, 0x32, 0x03, 0x2A, 0xEE, 0xD1, 0xDF, 0xF8, 0x24, 0xE1, 0x07, 0x0E, -+0x00, 0x21, 0xCB, 0x00, 0x28, 0xFA, 0x03, 0xF3, 0xDE, 0xB2, 0xC3, 0xF3, 0x03, 0x13, 0xBC, 0xF1, 0x00, 0x0F, 0x0B, 0xD1, -+0xEB, 0xB1, 0x08, 0x22, 0x93, 0x42, 0x28, 0xBF, 0xD3, 0x1A, 0x5B, 0xB2, 0x0E, 0xF8, 0x01, 0x30, 0x01, 0x31, 0x04, 0x29, -+0xEB, 0xD1, 0x9C, 0xE7, 0x4D, 0x00, 0x6A, 0x1C, 0x47, 0xFA, 0x02, 0xF2, 0x12, 0x01, 0x02, 0xF0, 0x10, 0x02, 0x13, 0x43, -+0x13, 0xF0, 0xFF, 0x03, 0x1F, 0xD1, 0x47, 0xFA, 0x05, 0xF3, 0x1B, 0x01, 0x03, 0xF0, 0x10, 0x03, 0x06, 0xF0, 0x0F, 0x06, -+0x1E, 0x43, 0x00, 0x2E, 0xE6, 0xD0, 0x33, 0x46, 0x4A, 0x46, 0xDD, 0xE7, 0x56, 0x00, 0x71, 0x1C, 0x4E, 0xFA, 0x01, 0xF1, -+0x09, 0x01, 0x01, 0xF0, 0x10, 0x01, 0x0B, 0x43, 0x13, 0xF0, 0xFF, 0x03, 0x09, 0xD0, 0x10, 0x21, 0x8B, 0x42, 0x28, 0xBF, -+0xCB, 0x1A, 0x5B, 0xB2, 0x0A, 0xF8, 0x02, 0x30, 0xB8, 0xE7, 0x10, 0x22, 0xC8, 0xE7, 0x4E, 0xFA, 0x06, 0xF3, 0x1B, 0x01, -+0x03, 0xF0, 0x10, 0x03, 0x07, 0xF0, 0x0F, 0x07, 0x1F, 0x43, 0xAA, 0xE7, 0x08, 0x21, 0xEB, 0xE7, 0x00, 0x60, 0x50, 0x40, -+0x00, 0x00, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x11, 0x13, 0x17, 0x00, 0x12, 0x13, 0x17, 0x00, 0x04, 0x02, 0x22, 0x03, -+0x10, 0x13, 0x17, 0x00, 0x00, 0x00, 0x01, 0x50, 0x70, 0x25, 0x17, 0x00, 0x50, 0x91, 0x01, 0x50, 0x20, 0x91, 0x01, 0x50, -+0xC0, 0xFD, 0x01, 0x00, 0xC0, 0xF1, 0x01, 0x00, 0x24, 0x91, 0x01, 0x50, 0x08, 0x88, 0x01, 0x50, 0x18, 0x88, 0x01, 0x50, -+0x2C, 0x91, 0x01, 0x50, 0x00, 0x10, 0x01, 0x50, 0x0C, 0x10, 0x01, 0x50, 0x10, 0x10, 0x01, 0x50, 0x18, 0x10, 0x01, 0x50, -+0x00, 0x30, 0x01, 0x50, 0x00, 0x88, 0x01, 0x50, 0x00, 0x00, 0xC0, 0xFF, 0x04, 0x88, 0x01, 0x50, 0x28, 0x91, 0x01, 0x50, -+0x5C, 0x00, 0x01, 0x50, 0x58, 0x00, 0x01, 0x50, 0x74, 0x91, 0x01, 0x50, 0x18, 0x91, 0x01, 0x50, 0x00, 0x91, 0x01, 0x50, -+0x30, 0x88, 0x01, 0x50, 0x68, 0x25, 0x17, 0x00, 0x6C, 0x25, 0x17, 0x00, 0x18, 0x18, 0x17, 0x00, 0x74, 0x79, 0x15, 0x00, -+0x1B, 0x6B, 0x59, 0x07, 0x7F, 0xF5, 0xEC, 0xAD, 0xD6, 0xF8, 0xA0, 0x30, 0x3F, 0x48, 0x40, 0x49, 0x40, 0x4A, 0x43, 0xF0, -+0x00, 0x73, 0x01, 0x27, 0x07, 0x70, 0x0B, 0x60, 0x53, 0x6F, 0x43, 0xF0, 0x10, 0x03, 0x53, 0x67, 0xE0, 0xE5, 0x3C, 0x4A, -+0x3C, 0x49, 0x3D, 0x48, 0xFF, 0xF7, 0x40, 0xFD, 0x3C, 0x48, 0x4F, 0xF4, 0x08, 0x42, 0x4F, 0xF4, 0x00, 0x41, 0xFF, 0xF7, -+0x39, 0xFD, 0x3A, 0x4A, 0x3A, 0x49, 0x3B, 0x48, 0xFF, 0xF7, 0x34, 0xFD, 0x3A, 0x48, 0x8F, 0x22, 0x06, 0x21, 0xFF, 0xF7, -+0x2F, 0xFD, 0x66, 0xE6, 0x38, 0x49, 0x39, 0x48, 0x4F, 0xF0, 0xFF, 0x32, 0xFF, 0xF7, 0x28, 0xFD, 0x4F, 0xF0, 0xFF, 0x32, -+0x36, 0x48, 0x4F, 0xF0, 0x02, 0x11, 0xFF, 0xF7, 0x21, 0xFD, 0x35, 0x49, 0x35, 0x48, 0xFF, 0xF7, 0xF5, 0xFC, 0x22, 0x46, -+0x21, 0x46, 0x34, 0x48, 0xBD, 0xE8, 0xF0, 0x47, 0xFF, 0xF7, 0x16, 0xBD, 0x32, 0x48, 0x0F, 0x22, 0x01, 0x21, 0xFF, 0xF7, -+0x11, 0xFD, 0x02, 0x22, 0x11, 0x46, 0x30, 0x48, 0xFF, 0xF7, 0x0C, 0xFD, 0x02, 0x22, 0x11, 0x46, 0x2E, 0x48, 0xFF, 0xF7, -+0x07, 0xFD, 0x4F, 0xF4, 0x00, 0x52, 0x11, 0x46, 0x2A, 0x48, 0xFF, 0xF7, 0x01, 0xFD, 0x4F, 0xF4, 0x00, 0x52, 0x11, 0x46, -+0x28, 0x48, 0xFF, 0xF7, 0xFB, 0xFC, 0x02, 0x22, 0x11, 0x46, 0x27, 0x48, 0xFF, 0xF7, 0xF6, 0xFC, 0x25, 0x48, 0x4F, 0xF4, -+0x00, 0x52, 0x00, 0x21, 0xFF, 0xF7, 0xF0, 0xFC, 0x64, 0xE6, 0x23, 0x4B, 0x0F, 0x49, 0x1A, 0x6D, 0x22, 0x4F, 0x42, 0xF4, -+0x80, 0x22, 0x1A, 0x65, 0x0A, 0x69, 0x22, 0xF0, 0x80, 0x02, 0x0A, 0x61, 0x5A, 0x6A, 0x22, 0xF0, 0xFF, 0x02, 0x42, 0xF0, -+0xDF, 0x02, 0x5A, 0x62, 0x5A, 0x6A, 0x22, 0xF4, 0x7F, 0x42, 0x42, 0xF4, 0x5F, 0x42, 0x5A, 0x62, 0x03, 0xF0, 0x48, 0xFA, -+0xCC, 0xE5, 0x3B, 0x46, 0x49, 0x46, 0x1D, 0xE7, 0x4C, 0x36, 0x17, 0x00, 0xE0, 0x50, 0x34, 0x40, 0x00, 0x00, 0x50, 0x40, -+0xC0, 0x3F, 0x00, 0x40, 0x40, 0x12, 0x00, 0x40, 0x08, 0x88, 0x01, 0x50, 0x04, 0x91, 0x01, 0x50, 0xE0, 0x01, 0x00, 0x22, -+0xC0, 0x00, 0x00, 0x02, 0x08, 0x91, 0x01, 0x50, 0x00, 0x91, 0x01, 0x50, 0x00, 0x01, 0x00, 0x03, 0x0C, 0x80, 0x01, 0x50, -+0x18, 0x80, 0x01, 0x50, 0x0A, 0x33, 0x41, 0x01, 0x38, 0x91, 0x01, 0x50, 0x04, 0x00, 0x01, 0x50, 0x04, 0x20, 0x01, 0x50, -+0x04, 0x10, 0x01, 0x50, 0x08, 0x10, 0x01, 0x50, 0x00, 0x10, 0x01, 0x50, 0x00, 0x60, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0x10, 0x4B, 0x11, 0x4A, 0x19, 0x68, 0x21, 0xF4, 0x78, 0x11, 0x41, 0xF4, 0x50, 0x11, 0x19, 0x60, 0x19, 0x68, 0x21, 0xF4, -+0x78, 0x11, 0x41, 0xF4, 0xA0, 0x11, 0x19, 0x60, 0x11, 0x69, 0x18, 0x68, 0x20, 0xF4, 0x78, 0x10, 0x40, 0xF4, 0x50, 0x10, -+0x32, 0x31, 0x18, 0x60, 0x13, 0x69, 0xCB, 0x1A, 0x00, 0x2B, 0xFB, 0xDA, 0x03, 0x4A, 0x13, 0x68, 0x23, 0xF4, 0x78, 0x13, -+0x43, 0xF4, 0x00, 0x13, 0x13, 0x60, 0x70, 0x47, 0x58, 0x40, 0x34, 0x40, 0x00, 0x10, 0x50, 0x40, 0x1E, 0x49, 0x1F, 0x4A, -+0x0B, 0x68, 0x43, 0xF4, 0x00, 0x13, 0x10, 0xB4, 0x0B, 0x60, 0x13, 0x68, 0x59, 0x07, 0x08, 0xD4, 0x32, 0x23, 0x00, 0xBF, -+0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0x13, 0x68, 0x59, 0x07, 0xF6, 0xD5, 0x15, 0x49, 0x15, 0x4A, 0x0B, 0x68, -+0x43, 0xF4, 0xC0, 0x23, 0x0B, 0x60, 0x13, 0x68, 0x9B, 0x07, 0x08, 0xD4, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, -+0x00, 0x2B, 0xFA, 0xD1, 0x13, 0x68, 0x9B, 0x07, 0xF6, 0xD5, 0x0E, 0x4C, 0x0E, 0x48, 0x23, 0x68, 0x0E, 0x4A, 0x0F, 0x49, -+0x43, 0xF4, 0x00, 0x33, 0x23, 0x60, 0x03, 0x68, 0x5D, 0xF8, 0x04, 0x4B, 0x43, 0xF0, 0x80, 0x73, 0x03, 0x60, 0x13, 0x68, -+0x43, 0xF4, 0xA4, 0x63, 0x43, 0xF0, 0x04, 0x03, 0x13, 0x60, 0x4F, 0xF4, 0x00, 0x50, 0x21, 0xF0, 0xA1, 0xBD, 0x00, 0xBF, -+0x58, 0x40, 0x34, 0x40, 0x80, 0x40, 0x34, 0x40, 0x2C, 0x20, 0x34, 0x40, 0x10, 0x00, 0x34, 0x40, 0x30, 0x20, 0x34, 0x40, -+0x9C, 0x79, 0x15, 0x00, 0x10, 0xB5, 0x10, 0x4C, 0x10, 0x48, 0x23, 0x68, 0x10, 0x49, 0x11, 0x4A, 0x23, 0xF4, 0x05, 0x43, -+0x23, 0xF0, 0xEC, 0x03, 0x23, 0x60, 0x03, 0x68, 0x23, 0xF4, 0x00, 0x33, 0x03, 0x60, 0x0B, 0x68, 0x23, 0xF0, 0x80, 0x73, -+0x0B, 0x60, 0x13, 0x68, 0x23, 0xF4, 0xC0, 0x23, 0x0A, 0x20, 0x13, 0x60, 0xFD, 0xF7, 0xD6, 0xFC, 0xBD, 0xE8, 0x10, 0x40, -+0x06, 0x49, 0x4F, 0xF4, 0x00, 0x50, 0x21, 0xF0, 0x73, 0xBD, 0x00, 0xBF, 0x30, 0x20, 0x34, 0x40, 0x2C, 0x20, 0x34, 0x40, -+0x10, 0x00, 0x34, 0x40, 0x58, 0x40, 0x34, 0x40, 0xB8, 0x79, 0x15, 0x00, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, -+0x00, 0x2B, 0xFA, 0xD1, 0x19, 0x4B, 0x02, 0x22, 0x1A, 0x60, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, -+0xFA, 0xD1, 0x16, 0x4A, 0x13, 0x68, 0xDB, 0x07, 0x11, 0xD4, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, -+0xFA, 0xD1, 0x13, 0x68, 0xDB, 0x07, 0xF6, 0xD5, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, -+0x13, 0x68, 0xDB, 0x07, 0xED, 0xD5, 0x0B, 0x4B, 0x1A, 0x68, 0x53, 0x0C, 0x00, 0x2A, 0xBC, 0xBF, 0x6F, 0xEA, 0x43, 0x43, -+0x6F, 0xEA, 0x53, 0x43, 0x03, 0x60, 0xC2, 0xF3, 0x4E, 0x03, 0x12, 0x04, 0x44, 0xBF, 0x6F, 0xEA, 0x43, 0x43, 0x6F, 0xEA, -+0x53, 0x43, 0x0B, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x84, 0x21, 0x34, 0x40, 0x00, 0x22, 0x34, 0x40, 0x2D, 0xE9, 0xF0, 0x41, -+0x2A, 0x4F, 0x2B, 0x4D, 0x3B, 0x68, 0x2B, 0x4A, 0x23, 0xF4, 0x7F, 0x53, 0x3B, 0x60, 0x2B, 0x68, 0x43, 0xF4, 0x80, 0x63, -+0x2B, 0x60, 0x13, 0x68, 0x43, 0xF0, 0x40, 0x03, 0x13, 0x60, 0x01, 0x20, 0xFD, 0xF7, 0x72, 0xFC, 0x00, 0x24, 0x26, 0x46, -+0x4F, 0xF0, 0x07, 0x08, 0x02, 0x20, 0xFD, 0xF7, 0x6B, 0xFC, 0x2B, 0x68, 0xDA, 0x05, 0x54, 0xBF, 0x01, 0x36, 0x06, 0xF1, -+0xFF, 0x36, 0x76, 0xB2, 0x1B, 0x06, 0x3B, 0x68, 0x54, 0xBF, 0x01, 0x34, 0x04, 0xF1, 0xFF, 0x34, 0x00, 0x2E, 0x23, 0xF4, -+0x7F, 0x53, 0xDC, 0xBF, 0x70, 0x42, 0x43, 0xEA, 0x80, 0x23, 0x64, 0xB2, 0xD4, 0xBF, 0x43, 0xF4, 0x00, 0x53, 0x43, 0xEA, -+0x86, 0x23, 0x00, 0x2C, 0xDC, 0xBF, 0x60, 0x42, 0x43, 0xEA, 0x80, 0x13, 0x08, 0xF1, 0xFF, 0x32, 0xCC, 0xBF, 0x43, 0xEA, -+0x84, 0x13, 0x43, 0xF4, 0x00, 0x73, 0x12, 0xF0, 0xFF, 0x08, 0x3B, 0x60, 0xD2, 0xD1, 0x0A, 0x48, 0x0A, 0x49, 0x02, 0x68, -+0x22, 0xF4, 0x80, 0x62, 0x02, 0x60, 0x0A, 0x68, 0xC3, 0xF3, 0x83, 0x10, 0x22, 0xF0, 0x40, 0x02, 0xC3, 0xF3, 0x83, 0x23, -+0x0A, 0x60, 0x43, 0xEA, 0x00, 0x10, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0xBF, 0x50, 0x40, 0x34, 0x40, 0x14, 0x40, 0x34, 0x40, -+0x5C, 0x40, 0x34, 0x40, 0x01, 0x28, 0x15, 0xD0, 0x02, 0x28, 0x05, 0xD0, 0x4B, 0x78, 0x10, 0x2B, 0x19, 0xD8, 0x30, 0x23, -+0x8B, 0x70, 0x70, 0x47, 0xD2, 0xE9, 0x00, 0x32, 0x00, 0x2B, 0x24, 0xDD, 0x00, 0x2A, 0x37, 0xDB, 0xB3, 0xEB, 0x42, 0x0F, -+0x0B, 0x78, 0xCC, 0xBF, 0x10, 0x3B, 0x18, 0x3B, 0x4B, 0x70, 0x70, 0x47, 0x13, 0x68, 0xB3, 0xF5, 0x00, 0x5F, 0x10, 0xDA, -+0x00, 0x2B, 0x1A, 0xDD, 0x40, 0x23, 0x0B, 0x70, 0x70, 0x47, 0x30, 0x2B, 0x0C, 0xD9, 0x60, 0x2B, 0x1A, 0xD8, 0x92, 0x68, -+0x00, 0x2A, 0x28, 0xDB, 0x60, 0x2B, 0xDC, 0xD1, 0x20, 0x23, 0x8B, 0x70, 0x70, 0x47, 0x20, 0x23, 0x0B, 0x70, 0x70, 0x47, -+0x18, 0x23, 0x8B, 0x70, 0x70, 0x47, 0x00, 0x2A, 0x1E, 0xDD, 0x0B, 0x78, 0x20, 0x3B, 0x4B, 0x70, 0x70, 0x47, 0x13, 0xF5, -+0x00, 0x5F, 0xD4, 0xBF, 0xE0, 0x23, 0xC0, 0x23, 0x0B, 0x70, 0x70, 0x47, 0xC0, 0x2B, 0x09, 0xD8, 0x92, 0x68, 0x00, 0x2A, -+0x19, 0xDD, 0x60, 0x23, 0x8B, 0x70, 0x70, 0x47, 0x0B, 0x78, 0x20, 0x33, 0x4B, 0x70, 0x70, 0x47, 0xD8, 0x2B, 0x0D, 0xD8, -+0xE8, 0x23, 0x8B, 0x70, 0x70, 0x47, 0xA0, 0x23, 0x8B, 0x70, 0x70, 0x47, 0xB3, 0xEB, 0x42, 0x0F, 0x0B, 0x78, 0xB4, 0xBF, -+0x10, 0x33, 0x18, 0x33, 0x4B, 0x70, 0x70, 0x47, 0xD0, 0x23, 0x8B, 0x70, 0x70, 0x47, 0xA0, 0x2B, 0xFA, 0xD1, 0xE0, 0x23, -+0x8B, 0x70, 0x70, 0x47, 0x01, 0x28, 0x1D, 0xD0, 0x02, 0x28, 0x08, 0xD0, 0x09, 0x78, 0x01, 0x39, 0x05, 0x29, 0x69, 0xD8, -+0xDF, 0xE8, 0x01, 0xF0, 0x3C, 0x42, 0x39, 0x33, 0x2D, 0x2A, 0x10, 0xB4, 0x1C, 0x68, 0xB4, 0xF5, 0x00, 0x5F, 0x19, 0xDA, -+0x00, 0x2C, 0x4A, 0xDD, 0x5B, 0x68, 0x00, 0x2B, 0x13, 0x78, 0xAA, 0xBF, 0x03, 0x20, 0x10, 0x33, 0x10, 0x3B, 0x53, 0x70, -+0x08, 0x70, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x1B, 0x68, 0xB3, 0xF5, 0x00, 0x5F, 0x04, 0xDA, 0x00, 0x2B, 0x2B, 0xDD, -+0x50, 0x23, 0x13, 0x70, 0x70, 0x47, 0x30, 0x23, 0x13, 0x70, 0x70, 0x47, 0x13, 0x78, 0x01, 0x20, 0x10, 0x33, 0x53, 0x70, -+0x08, 0x70, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0xC8, 0x23, 0x93, 0x70, 0x70, 0x47, 0x9B, 0x68, 0x00, 0x2B, 0x21, 0xDD, -+0x70, 0x23, 0x93, 0x70, 0x70, 0x47, 0x9B, 0x68, 0x00, 0x2B, 0x18, 0xDD, 0x90, 0x23, 0x93, 0x70, 0x70, 0x47, 0x38, 0x23, -+0x93, 0x70, 0x70, 0x47, 0x9B, 0x68, 0x00, 0x2B, 0xF0, 0xDD, 0x20, 0x23, 0x93, 0x70, 0x70, 0x47, 0x9B, 0x68, 0x00, 0x2B, -+0xF0, 0xDD, 0x40, 0x23, 0x93, 0x70, 0x70, 0x47, 0x13, 0xF5, 0x00, 0x5F, 0xD4, 0xBF, 0xD0, 0x23, 0xB0, 0x23, 0x13, 0x70, -+0x70, 0x47, 0xE0, 0x23, 0x93, 0x70, 0x70, 0x47, 0xC0, 0x23, 0x93, 0x70, 0x70, 0x47, 0x14, 0xF5, 0x00, 0x5F, 0x05, 0xDC, -+0x13, 0x78, 0x04, 0x20, 0x10, 0x3B, 0x53, 0x70, 0x08, 0x70, 0xB4, 0xE7, 0x5B, 0x68, 0x00, 0x2B, 0x13, 0x78, 0xCC, 0xBF, -+0x05, 0x20, 0x06, 0x20, 0x10, 0x3B, 0x53, 0x70, 0x08, 0x70, 0xAA, 0xE7, 0x88, 0x23, 0x93, 0x70, 0x70, 0x47, 0x00, 0xBF, -+0x30, 0xB4, 0x0F, 0x29, 0x15, 0x46, 0x1C, 0x46, 0x02, 0x9A, 0x03, 0xD0, 0x30, 0xBC, 0x19, 0x46, 0xFF, 0xF7, 0x1C, 0xBF, -+0x13, 0x46, 0x29, 0x46, 0x22, 0x46, 0x30, 0xBC, 0xFF, 0xF7, 0x7A, 0xBF, 0x70, 0xB4, 0x50, 0xEA, 0x01, 0x04, 0x02, 0xD1, -+0x70, 0xBC, 0x1A, 0x60, 0x70, 0x47, 0x08, 0x18, 0x18, 0xBF, 0x00, 0x21, 0x03, 0xD1, 0x20, 0xE0, 0xE9, 0xB2, 0x81, 0x42, -+0x1D, 0xDA, 0x53, 0xF8, 0x21, 0x40, 0x94, 0x42, 0x01, 0xF1, 0x01, 0x05, 0x03, 0xEB, 0x81, 0x06, 0xF4, 0xDC, 0xC0, 0xB2, -+0x88, 0x42, 0x0F, 0xD9, 0x44, 0x1E, 0x61, 0x1A, 0x1C, 0x1F, 0xC9, 0xB2, 0x04, 0xEB, 0x80, 0x04, 0xA4, 0xEB, 0x81, 0x04, -+0x03, 0xEB, 0x80, 0x03, 0x53, 0xF8, 0x04, 0x1C, 0x43, 0xF8, 0x04, 0x19, 0xA3, 0x42, 0xF9, 0xD1, 0x32, 0x60, 0x70, 0xBC, -+0x70, 0x47, 0x70, 0xBC, 0x43, 0xF8, 0x20, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x4F, 0x00, 0xF1, 0xFF, 0x3C, -+0x85, 0xB0, 0xCC, 0xF3, 0x47, 0x0C, 0x4F, 0xF0, 0x80, 0x34, 0x48, 0xF2, 0x80, 0x03, 0x01, 0x28, 0xCD, 0xE9, 0x01, 0xC4, -+0xAD, 0xF8, 0x0C, 0x30, 0x40, 0xF2, 0x83, 0x80, 0x80, 0x24, 0xA2, 0x46, 0x16, 0x46, 0x00, 0x25, 0x01, 0x23, 0x43, 0xF2, -+0xB0, 0x69, 0x8E, 0x46, 0x00, 0x92, 0x18, 0xE0, 0x80, 0x2C, 0x04, 0xBF, 0x04, 0xAA, 0x02, 0xEB, 0x45, 0x01, 0x4F, 0xEA, -+0x45, 0x07, 0x04, 0xAA, 0x17, 0x44, 0x04, 0xBF, 0x03, 0xF1, 0xFF, 0x34, 0x01, 0xF8, 0x08, 0x4C, 0x07, 0xF8, 0x07, 0x3C, -+0x01, 0x33, 0xDB, 0xB2, 0x98, 0x42, 0x22, 0xD0, 0x04, 0xAA, 0x02, 0xEB, 0x45, 0x01, 0x11, 0xF8, 0x08, 0x4C, 0x37, 0x68, -+0x56, 0xF8, 0x04, 0x1F, 0x7F, 0x1A, 0x77, 0x45, 0xE0, 0xDD, 0x80, 0x2C, 0xEE, 0xD0, 0x00, 0x9A, 0x52, 0xF8, 0x24, 0x10, -+0x49, 0x45, 0x4F, 0xEA, 0x45, 0x07, 0x04, 0xAA, 0x55, 0xDD, 0x02, 0xEB, 0x45, 0x01, 0x11, 0xF8, 0x07, 0x8C, 0x61, 0x46, -+0x0C, 0x44, 0xA0, 0x45, 0x61, 0xDB, 0x01, 0x33, 0xDB, 0xB2, 0x01, 0x35, 0x98, 0x42, 0xED, 0xB2, 0xDC, 0xD1, 0x02, 0x2D, -+0x00, 0x9A, 0x68, 0xD9, 0x9D, 0xF8, 0x08, 0x10, 0x80, 0x29, 0x3A, 0xD0, 0x9D, 0xF8, 0x09, 0x30, 0x52, 0xF8, 0x21, 0x40, -+0x52, 0xF8, 0x23, 0x50, 0x58, 0x1C, 0x40, 0x1A, 0x64, 0x1B, 0xC0, 0xB2, 0x02, 0xAD, 0x94, 0xFB, 0xF0, 0xF4, 0x01, 0x27, -+0xA4, 0xB2, 0x00, 0x26, 0x95, 0xF8, 0x02, 0xE0, 0xBE, 0xF1, 0x80, 0x0F, 0x5F, 0xFA, 0x87, 0xFC, 0x16, 0xD0, 0x95, 0xF8, -+0x03, 0x80, 0x52, 0xF8, 0x2E, 0x30, 0x08, 0xF1, 0x01, 0x01, 0xA1, 0xEB, 0x0E, 0x01, 0xC9, 0xB2, 0x52, 0xF8, 0x28, 0xE0, -+0x81, 0x42, 0xA3, 0xEB, 0x0E, 0x03, 0x93, 0xFB, 0xF1, 0xF3, 0x9B, 0xB2, 0x32, 0xD8, 0x61, 0xD0, 0x02, 0x2F, 0x05, 0xF1, -+0x02, 0x05, 0x34, 0xD1, 0x04, 0xAB, 0x03, 0xEB, 0x46, 0x06, 0x16, 0xF8, 0x08, 0x1C, 0x16, 0xF8, 0x07, 0x3C, 0x5B, 0x1A, -+0x01, 0x33, 0x01, 0xEB, 0x63, 0x03, 0xDB, 0xB2, 0x01, 0x93, 0x01, 0x9B, 0x52, 0xF8, 0x23, 0x00, 0x05, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0x02, 0xEB, 0x45, 0x08, 0x00, 0x9A, 0x18, 0xF8, 0x07, 0x8C, 0x52, 0xF8, 0x28, 0xB0, 0x25, 0x4A, 0x93, 0x45, -+0xA3, 0xDB, 0xB1, 0xF5, 0x7A, 0x7F, 0x02, 0xDA, 0x23, 0x4A, 0x93, 0x45, 0x9D, 0xDA, 0x02, 0x21, 0x0C, 0x44, 0xA0, 0x45, -+0x9D, 0xDA, 0x04, 0xAA, 0x17, 0x44, 0x07, 0xF8, 0x08, 0xAC, 0x07, 0xF8, 0x07, 0xAC, 0x75, 0xE7, 0x02, 0x2F, 0x1C, 0x46, -+0x08, 0x46, 0x66, 0x46, 0x05, 0xF1, 0x02, 0x05, 0xCA, 0xD0, 0x02, 0x27, 0xAA, 0xE7, 0x04, 0xAB, 0x03, 0xEB, 0x45, 0x01, -+0x6D, 0x00, 0x11, 0xF8, 0x08, 0x3C, 0x80, 0x2B, 0x8E, 0xD0, 0x52, 0xF8, 0x23, 0x00, 0x11, 0xF8, 0x07, 0x1C, 0x43, 0xF2, -+0xB0, 0x64, 0xA0, 0x42, 0x0A, 0xDC, 0x0F, 0x4E, 0x52, 0xF8, 0x21, 0x40, 0xB4, 0x42, 0x05, 0xDB, 0xB0, 0xF5, 0x7A, 0x7F, -+0x13, 0xDA, 0x14, 0xF5, 0x7A, 0x7F, 0x10, 0xDD, 0x9C, 0x44, 0x61, 0x45, 0xBF, 0xF6, 0x78, 0xAF, 0x04, 0xAB, 0x1D, 0x44, -+0x80, 0x23, 0x05, 0xF8, 0x08, 0x3C, 0x05, 0xF8, 0x07, 0x3C, 0x6F, 0xE7, 0xA3, 0x42, 0x9B, 0xD2, 0x1C, 0x46, 0x66, 0x46, -+0x98, 0xE7, 0x4F, 0xF0, 0x02, 0x0C, 0xEB, 0xE7, 0x50, 0xC9, 0xFF, 0xFF, 0x19, 0xFC, 0xFF, 0xFF, 0xD0, 0xED, 0x00, 0x7A, -+0x90, 0xED, 0x01, 0x7A, 0xF4, 0xEE, 0xC7, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x08, 0xD5, 0x91, 0xED, 0x00, 0x6A, 0xD1, 0xED, -+0x01, 0x6A, 0xB4, 0xEE, 0xE6, 0x6A, 0xF1, 0xEE, 0x10, 0xFA, 0x5E, 0xDA, 0xF4, 0xEE, 0xC7, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, -+0x08, 0xDD, 0x91, 0xED, 0x00, 0x6A, 0xD1, 0xED, 0x01, 0x6A, 0xB4, 0xEE, 0xE6, 0x6A, 0xF1, 0xEE, 0x10, 0xFA, 0x50, 0xD9, -+0xD0, 0xED, 0x02, 0x6A, 0xF4, 0xEE, 0xE6, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x08, 0xD5, 0xD1, 0xED, 0x00, 0x5A, 0x91, 0xED, -+0x02, 0x6A, 0xF4, 0xEE, 0xC6, 0x5A, 0xF1, 0xEE, 0x10, 0xFA, 0x40, 0xDA, 0xF4, 0xEE, 0xE6, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, -+0x32, 0xDC, 0xB4, 0xEE, 0xE6, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x08, 0xD5, 0x91, 0xED, 0x01, 0x6A, 0xD1, 0xED, 0x02, 0x7A, -+0xB4, 0xEE, 0xE7, 0x6A, 0xF1, 0xEE, 0x10, 0xFA, 0x2D, 0xDA, 0xB4, 0xEE, 0xE6, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x08, 0xDD, -+0x91, 0xED, 0x01, 0x7A, 0xD1, 0xED, 0x02, 0x7A, 0xB4, 0xEE, 0xE7, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x1F, 0xD9, 0xD1, 0xED, -+0x00, 0x7A, 0xF5, 0xEE, 0xC0, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x1A, 0xDD, 0x91, 0xED, 0x01, 0x7A, 0xB5, 0xEE, 0xC0, 0x7A, -+0xF1, 0xEE, 0x10, 0xFA, 0x13, 0xDD, 0x91, 0xED, 0x02, 0x7A, 0xB5, 0xEE, 0xC0, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x0C, 0xDD, -+0x01, 0x20, 0x70, 0x47, 0x91, 0xED, 0x00, 0x6A, 0xD1, 0xED, 0x02, 0x7A, 0xB4, 0xEE, 0xE7, 0x6A, 0xF1, 0xEE, 0x10, 0xFA, -+0xC3, 0xD8, 0x02, 0x20, 0x70, 0x47, 0xF5, 0xEE, 0xC0, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x01, 0xD4, 0x00, 0x20, 0x70, 0x47, -+0xD1, 0xED, 0x01, 0x7A, 0xF5, 0xEE, 0xC0, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0xF6, 0xD5, 0xD1, 0xED, 0x02, 0x7A, 0xF5, 0xEE, -+0xC0, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x4C, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x28, 0x00, 0xF0, -+0xC7, 0x80, 0x2D, 0xE9, 0xF0, 0x47, 0x00, 0x22, 0xA1, 0xF1, 0x02, 0x08, 0x82, 0xB0, 0x44, 0x46, 0x17, 0x46, 0x94, 0x46, -+0x10, 0x46, 0x4F, 0xF0, 0x01, 0x0E, 0x02, 0xE0, 0x05, 0x2E, 0x11, 0xD0, 0x01, 0x32, 0x34, 0xF9, 0x02, 0x5F, 0x0E, 0xFA, -+0x02, 0xF3, 0x00, 0x2D, 0xD6, 0xB2, 0x43, 0xEA, 0x00, 0x03, 0xF3, 0xDA, 0x01, 0x2A, 0xD8, 0xB2, 0x40, 0xF2, 0x83, 0x80, -+0x01, 0x37, 0x05, 0x2E, 0xFF, 0xB2, 0xED, 0xD1, 0x04, 0x2F, 0x00, 0xF0, 0x81, 0x80, 0x02, 0x2F, 0x00, 0xF2, 0x81, 0x80, -+0xBC, 0xF1, 0x00, 0x0F, 0x0B, 0xD1, 0xB1, 0xF9, 0x02, 0x30, 0xB1, 0xF9, 0x00, 0x20, 0x03, 0xF1, 0x09, 0x04, 0x94, 0x42, -+0x02, 0xDB, 0x09, 0x3B, 0x9A, 0x42, 0x00, 0xDA, 0x4A, 0x80, 0xB1, 0xF9, 0x04, 0x20, 0xB1, 0xF9, 0x06, 0x30, 0x03, 0x24, -+0x40, 0xF2, 0x04, 0x55, 0x9A, 0x42, 0x8D, 0xF8, 0x01, 0x40, 0xAD, 0xF8, 0x02, 0x50, 0xC0, 0xF2, 0x8E, 0x80, 0xB1, 0xF9, -+0x08, 0x20, 0xB1, 0xF9, 0x0A, 0x30, 0x9A, 0x42, 0x25, 0x46, 0x4F, 0xF0, 0x06, 0x09, 0x4F, 0xF0, 0x04, 0x07, 0x4F, 0xF0, -+0x02, 0x04, 0x80, 0xF2, 0x8E, 0x80, 0x40, 0xF2, 0x05, 0x43, 0xAD, 0xF8, 0x02, 0x30, 0x4F, 0xF0, 0x05, 0x0E, 0x4F, 0xF0, -+0x08, 0x08, 0x04, 0x26, 0x0A, 0x22, 0xCB, 0x5F, 0x8F, 0x5E, 0xBB, 0x42, 0x07, 0xDA, 0xBA, 0x46, 0x72, 0x46, 0x8D, 0xF8, -+0x02, 0x40, 0x1F, 0x46, 0xA6, 0x46, 0x53, 0x46, 0x14, 0x46, 0x31, 0xF9, 0x09, 0x20, 0x31, 0xF9, 0x08, 0x80, 0x42, 0x45, -+0x05, 0xDA, 0x8D, 0xF8, 0x03, 0x50, 0x8D, 0xF8, 0x01, 0x60, 0x42, 0x46, 0x35, 0x46, 0x97, 0x42, 0x05, 0xDD, 0x8D, 0xF8, -+0x02, 0x50, 0x8D, 0xF8, 0x01, 0xE0, 0x3A, 0x46, 0x75, 0x46, 0x9D, 0xF8, 0x02, 0xE0, 0x9D, 0xF8, 0x01, 0x60, 0x31, 0xF9, -+0x1E, 0x70, 0x31, 0xF9, 0x16, 0x80, 0x07, 0x32, 0xFE, 0x1D, 0x93, 0x42, 0xD4, 0xBF, 0x04, 0x23, 0x00, 0x23, 0xB0, 0x45, -+0x9D, 0xF8, 0x03, 0x60, 0x31, 0xF9, 0x16, 0x20, 0x02, 0xF1, 0x07, 0x02, 0xD8, 0xBF, 0x43, 0xF0, 0x02, 0x03, 0xBA, 0x42, -+0xA8, 0xBF, 0x43, 0xF0, 0x01, 0x03, 0x06, 0x2B, 0x4E, 0xD8, 0xDF, 0xE8, 0x03, 0xF0, 0x4A, 0xA9, 0xA1, 0x9B, 0x93, 0x4A, -+0xB1, 0x00, 0x0C, 0xF1, 0x01, 0x0C, 0x5F, 0xFA, 0x8C, 0xFC, 0x69, 0xE7, 0xBC, 0xF1, 0x02, 0x0F, 0x78, 0xD0, 0x00, 0x23, -+0x1C, 0x46, 0x1A, 0x46, 0x40, 0xFA, 0x03, 0xF5, 0xEF, 0x07, 0x05, 0xD4, 0x31, 0xF8, 0x13, 0x50, 0x01, 0x34, 0x2A, 0x44, -+0xE4, 0xB2, 0x12, 0xB2, 0x01, 0x33, 0x06, 0x2B, 0xF2, 0xD1, 0x92, 0xFB, 0xF4, 0xF2, 0x00, 0x23, 0x40, 0xFA, 0x03, 0xF4, -+0xE6, 0x07, 0x48, 0xBF, 0x21, 0xF8, 0x13, 0x20, 0x01, 0x33, 0x06, 0x2B, 0xF6, 0xD1, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, -+0x8B, 0x1E, 0x80, 0x20, 0x0A, 0x31, 0x33, 0xF9, 0x02, 0x2F, 0x00, 0x2A, 0xB8, 0xBF, 0x18, 0x80, 0x99, 0x42, 0xF8, 0xD1, -+0x70, 0x47, 0xB1, 0xF9, 0x08, 0x20, 0xB1, 0xF9, 0x0A, 0x30, 0x02, 0x25, 0x9A, 0x42, 0x8D, 0xF8, 0x01, 0x50, 0x4F, 0xF0, -+0x04, 0x09, 0x4F, 0xF0, 0x06, 0x07, 0xFF, 0xF6, 0x72, 0xAF, 0x4F, 0xF0, 0x0A, 0x08, 0x08, 0x22, 0x4F, 0xF0, 0x04, 0x0E, -+0x75, 0xE7, 0xBC, 0xF1, 0x00, 0x0F, 0x69, 0xD0, 0x00, 0x24, 0x22, 0x46, 0x02, 0x23, 0x40, 0xFA, 0x03, 0xF5, 0xED, 0x07, -+0x05, 0xD4, 0x31, 0xF8, 0x13, 0x50, 0x01, 0x34, 0x2A, 0x44, 0xE4, 0xB2, 0x12, 0xB2, 0x01, 0x33, 0x06, 0x2B, 0xF2, 0xD1, -+0x64, 0xB9, 0xC3, 0x07, 0x03, 0xD4, 0x0B, 0x88, 0x1A, 0x44, 0x12, 0xB2, 0x01, 0x24, 0x87, 0x07, 0x04, 0xD4, 0x4B, 0x88, -+0x01, 0x34, 0x13, 0x44, 0xE4, 0xB2, 0x1A, 0xB2, 0x00, 0x23, 0x92, 0xFB, 0xF4, 0xF4, 0x00, 0xE0, 0x01, 0x33, 0x40, 0xFA, -+0x03, 0xF2, 0xD6, 0x07, 0xDD, 0xB2, 0x03, 0xD5, 0x01, 0x2B, 0x14, 0xD9, 0x21, 0xF8, 0x13, 0x40, 0x05, 0x2D, 0xF3, 0xD1, -+0xBC, 0xF1, 0x01, 0x0F, 0xA9, 0xD1, 0xC2, 0x07, 0x0F, 0xD4, 0x83, 0x07, 0xA5, 0xD5, 0x0B, 0x88, 0x4B, 0x80, 0xA2, 0xE7, -+0x0A, 0x31, 0x80, 0x23, 0x28, 0xF8, 0x02, 0x3F, 0x88, 0x45, 0xFB, 0xD1, 0x9B, 0xE7, 0xBC, 0xF1, 0x02, 0x0F, 0xDF, 0xD1, -+0xE6, 0xE7, 0x4B, 0x88, 0x0B, 0x80, 0x94, 0xE7, 0x01, 0x22, 0x02, 0xFA, 0x0E, 0xF3, 0xB2, 0x40, 0x13, 0x43, 0x18, 0x43, -+0xC0, 0xB2, 0xB1, 0xE7, 0x01, 0x23, 0x03, 0xFA, 0x04, 0xF4, 0x20, 0x43, 0xC0, 0xB2, 0xAB, 0xE7, 0x01, 0x23, 0x03, 0xFA, -+0x06, 0xF6, 0x30, 0x43, 0xA3, 0x40, 0x18, 0x43, 0xC0, 0xB2, 0xA3, 0xE7, 0x01, 0x23, 0x03, 0xFA, 0x04, 0xF4, 0x20, 0x43, -+0xAB, 0x40, 0x18, 0x43, 0xC0, 0xB2, 0x9B, 0xE7, 0x01, 0x23, 0x03, 0xFA, 0x06, 0xF6, 0x30, 0x43, 0xC0, 0xB2, 0x95, 0xE7, -+0x40, 0xF0, 0x3C, 0x00, 0x92, 0xE7, 0x00, 0xBF, 0xF0, 0xB5, 0xD1, 0xED, 0x01, 0x6A, 0x91, 0xED, 0x00, 0x7A, 0x2D, 0xED, -+0x08, 0x8B, 0xF4, 0xEE, 0xC7, 0x6A, 0xF1, 0xEE, 0x10, 0xFA, 0x83, 0xB0, 0x0C, 0x46, 0x07, 0x46, 0x15, 0x46, 0x1E, 0x46, -+0x05, 0xDC, 0xF0, 0xEE, 0x66, 0x7A, 0xF0, 0xEE, 0x47, 0x6A, 0xB0, 0xEE, 0x67, 0x7A, 0xD4, 0xED, 0x02, 0x7A, 0xF4, 0xEE, -+0xE6, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x08, 0xDC, 0xF4, 0xEE, 0xC7, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x48, 0xBF, 0xB0, 0xEE, -+0x67, 0x7A, 0xF0, 0xEE, 0x66, 0x7A, 0x77, 0xEE, 0xC7, 0x7A, 0xB0, 0xEE, 0x08, 0xBA, 0xFC, 0xEE, 0xE7, 0x7A, 0x17, 0xEE, -+0x90, 0x3A, 0xB3, 0x70, 0xD4, 0xED, 0x00, 0x8A, 0x94, 0xED, 0x01, 0xAA, 0xD4, 0xED, 0x02, 0x9A, 0x6A, 0xEE, 0x0A, 0x7A, -+0x28, 0xEE, 0xA8, 0x6A, 0x69, 0xEE, 0xA9, 0xAA, 0x36, 0xEE, 0x27, 0x6A, 0x38, 0xEE, 0x8A, 0x7A, 0x76, 0xEE, 0x2A, 0xAA, -+0x37, 0xEE, 0x29, 0x9A, 0x2A, 0xEE, 0x8B, 0xBA, 0x69, 0xEE, 0x09, 0x7A, 0x3B, 0xEE, 0x67, 0xBA, 0xB5, 0xEE, 0xC0, 0xBA, -+0xF1, 0xEE, 0x10, 0xFA, 0x40, 0xF3, 0xD0, 0x80, 0x1B, 0xEE, 0x10, 0x0A, 0x33, 0xF0, 0x44, 0xF8, 0x6F, 0xA3, 0xD3, 0xE9, -+0x00, 0x23, 0x33, 0xF0, 0x09, 0xFB, 0x80, 0xB1, 0x9F, 0xED, 0x6E, 0xBA, 0x33, 0x78, 0x6E, 0x49, 0x43, 0xF0, 0x04, 0x03, -+0x33, 0x70, 0x4F, 0xF4, 0x00, 0x50, 0x21, 0xF0, 0x73, 0xF8, 0xD4, 0xED, 0x00, 0x8A, 0x94, 0xED, 0x01, 0xAA, 0xD4, 0xED, -+0x02, 0x9A, 0x95, 0xED, 0x00, 0x4A, 0xD5, 0xED, 0x01, 0x4A, 0x95, 0xED, 0x02, 0x5A, 0xF7, 0xEE, 0x00, 0x7A, 0x87, 0xEE, -+0x8B, 0x6A, 0x0D, 0x2F, 0xF0, 0xEE, 0x08, 0x6A, 0x26, 0xEE, 0x49, 0x7A, 0x66, 0xEE, 0x26, 0x6A, 0x2A, 0xEE, 0x86, 0x6A, -+0x66, 0xEE, 0xA8, 0x7A, 0x66, 0xEE, 0x8A, 0x5A, 0x67, 0xEE, 0x28, 0x8A, 0x27, 0xEE, 0x0A, 0xAA, 0x77, 0xEE, 0x87, 0x7A, -+0x26, 0xEE, 0xA9, 0x8A, 0x78, 0xEE, 0x86, 0x8A, 0x67, 0xEE, 0x29, 0x9A, 0x75, 0xEE, 0x87, 0x5A, 0x3A, 0xEE, 0x06, 0xAA, -+0x38, 0xEE, 0x07, 0x8A, 0x67, 0xEE, 0x84, 0x7A, 0x68, 0xEE, 0x84, 0x8A, 0x79, 0xEE, 0x86, 0x9A, 0x25, 0xEE, 0xA4, 0x7A, -+0x2A, 0xEE, 0x24, 0xAA, 0x77, 0xEE, 0x87, 0x7A, 0x78, 0xEE, 0x8A, 0x8A, 0x28, 0xEE, 0x05, 0x8A, 0x69, 0xEE, 0x85, 0x9A, -+0x37, 0xEE, 0x88, 0x8A, 0x78, 0xEE, 0xA9, 0x8A, 0x2E, 0xD9, 0xF3, 0xEE, 0x04, 0x7A, 0xB4, 0xEE, 0xE7, 0x8A, 0xF1, 0xEE, -+0x10, 0xFA, 0x27, 0xD5, 0x33, 0x78, 0x44, 0x49, 0x43, 0xF0, 0x08, 0x03, 0x33, 0x70, 0x4F, 0xF4, 0x00, 0x50, 0x21, 0xF0, -+0x1D, 0xF8, 0xB7, 0xEE, 0x00, 0x8A, 0xF0, 0xEE, 0x00, 0x6A, 0xB1, 0xEE, 0x68, 0x7A, 0xC7, 0xEE, 0x08, 0x7A, 0x9F, 0xED, -+0x3D, 0x7A, 0xF4, 0xEE, 0xC7, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x21, 0xDC, 0xF5, 0xEE, 0xC0, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, -+0x4E, 0xD4, 0xB6, 0xEE, 0x00, 0x7A, 0x77, 0xEE, 0x87, 0x7A, 0xFC, 0xEE, 0xE7, 0x7A, 0xCD, 0xED, 0x01, 0x7A, 0x9D, 0xF8, -+0x04, 0x30, 0x12, 0xE0, 0x18, 0xEE, 0x10, 0x0A, 0x32, 0xF0, 0xBA, 0xFF, 0x2A, 0xA3, 0xD3, 0xE9, 0x00, 0x23, 0x33, 0xF0, -+0x7F, 0xFA, 0x00, 0x28, 0xCC, 0xD1, 0x68, 0xEE, 0x08, 0x6A, 0xF7, 0xEE, 0x00, 0x7A, 0x76, 0xEE, 0xA7, 0x6A, 0xD2, 0xE7, -+0xFF, 0x23, 0x73, 0x70, 0xD4, 0xED, 0x00, 0x7A, 0x94, 0xED, 0x01, 0x7A, 0xD4, 0xED, 0x02, 0x4A, 0x95, 0xED, 0x00, 0x5A, -+0xD5, 0xED, 0x01, 0x5A, 0x95, 0xED, 0x02, 0x6A, 0x68, 0xEE, 0x27, 0x7A, 0x28, 0xEE, 0x07, 0x7A, 0x77, 0xEE, 0xA8, 0x7A, -+0x37, 0xEE, 0x28, 0x7A, 0x28, 0xEE, 0x24, 0x8A, 0x77, 0xEE, 0xC5, 0x7A, 0x37, 0xEE, 0x65, 0x7A, 0x38, 0xEE, 0x28, 0x8A, -+0x27, 0xEE, 0x07, 0x7A, 0x38, 0xEE, 0x46, 0x8A, 0x67, 0xEE, 0xA7, 0x7A, 0x28, 0xEE, 0x08, 0x8A, 0x77, 0xEE, 0x87, 0x7A, -+0x37, 0xEE, 0x88, 0x8A, 0xC8, 0xEE, 0x26, 0x7A, 0xC6, 0xED, 0x01, 0x7A, 0x03, 0xB0, 0xBD, 0xEC, 0x08, 0x8B, 0xF0, 0xBD, -+0x00, 0x23, 0xCC, 0xE7, 0xF1, 0xEE, 0x4B, 0x7A, 0x17, 0xEE, 0x90, 0x0A, 0x32, 0xF0, 0x72, 0xFF, 0x06, 0xA3, 0xD3, 0xE9, -+0x00, 0x23, 0x33, 0xF0, 0x37, 0xFA, 0x00, 0x28, 0x3F, 0xF4, 0x3D, 0xAF, 0x9F, 0xED, 0x08, 0xBA, 0x2A, 0xE7, 0x00, 0xBF, -+0xAF, 0xF3, 0x00, 0x80, 0xF1, 0x68, 0xE3, 0x88, 0xB5, 0xF8, 0xE4, 0x3E, 0x00, 0x50, 0xC3, 0x47, 0xD4, 0x79, 0x15, 0x00, -+0x00, 0x7A, 0x15, 0x00, 0x00, 0x00, 0x7F, 0x43, 0xAC, 0xC5, 0x27, 0xB7, 0x2D, 0xE9, 0xF0, 0x47, 0x09, 0x29, 0x8E, 0xB0, -+0x88, 0x46, 0x1D, 0x46, 0x70, 0xD9, 0x03, 0x28, 0x6E, 0xD0, 0x4F, 0xF0, 0x86, 0x4A, 0x57, 0x1E, 0x00, 0x26, 0x0D, 0xF1, -+0x18, 0x09, 0x00, 0x22, 0x10, 0x46, 0xF1, 0xB2, 0xD3, 0xB2, 0x8B, 0x42, 0x19, 0xD0, 0x00, 0x2B, 0x00, 0xF0, 0xAF, 0x80, -+0xBB, 0x5C, 0x07, 0xEE, 0x90, 0x3A, 0x0E, 0xAB, 0xF8, 0xEE, 0x67, 0x7A, 0x03, 0xEB, 0x80, 0x03, 0x43, 0xED, 0x0E, 0x7A, -+0x84, 0x00, 0x55, 0xF8, 0x22, 0x30, 0x07, 0xEE, 0x90, 0x3A, 0x0E, 0xAB, 0xF8, 0xEE, 0xE7, 0x7A, 0x1C, 0x44, 0x01, 0x30, -+0xC0, 0xB2, 0x44, 0xED, 0x0B, 0x7A, 0x01, 0x32, 0x04, 0x2A, 0xDF, 0xD1, 0x00, 0x23, 0x03, 0xA9, 0x68, 0x46, 0x09, 0xF8, -+0x36, 0x30, 0xFF, 0xF7, 0x9F, 0xFC, 0x10, 0xF0, 0x0E, 0x0F, 0x09, 0xF8, 0x36, 0x00, 0x00, 0xF0, 0x95, 0x80, 0x01, 0x36, -+0x04, 0x2E, 0xCC, 0xD1, 0x07, 0xAD, 0x00, 0x24, 0x2A, 0x46, 0x23, 0x46, 0x80, 0x21, 0x12, 0xF8, 0x04, 0x0C, 0x00, 0x28, -+0x40, 0xF0, 0x82, 0x80, 0x0E, 0xA8, 0x80, 0x29, 0x00, 0xEB, 0xC1, 0x00, 0x00, 0xF0, 0x8A, 0x80, 0x92, 0xED, 0x00, 0x7A, -+0x50, 0xED, 0x07, 0x7A, 0xB4, 0xEE, 0x67, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, 0x98, 0xBF, 0x19, 0x46, 0x01, 0x33, 0xDB, 0xB2, -+0x04, 0x2B, 0x02, 0xF1, 0x08, 0x02, 0xE4, 0xD1, 0x00, 0x2C, 0x00, 0xF0, 0x84, 0x80, 0x80, 0x29, 0x76, 0xD0, 0x0E, 0xAB, -+0x03, 0xEB, 0xC1, 0x00, 0x42, 0x46, 0x10, 0xF8, 0x1F, 0x4C, 0x10, 0xF8, 0x20, 0x3C, 0x55, 0x49, 0x4F, 0xF4, 0x00, 0x50, -+0x20, 0xF0, 0x22, 0xFF, 0x20, 0x46, 0x0E, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x13, 0x78, 0xD5, 0xED, 0x00, 0x6A, 0x95, 0xED, -+0x01, 0x7A, 0xD5, 0xED, 0x02, 0x7A, 0x05, 0xEE, 0x90, 0x3A, 0x53, 0x78, 0x06, 0xEE, 0x10, 0x3A, 0xF8, 0xEE, 0x65, 0x5A, -+0xB8, 0xEE, 0x46, 0x6A, 0xF8, 0xEE, 0xE6, 0x6A, 0xB8, 0xEE, 0xC7, 0x7A, 0xF8, 0xEE, 0xE7, 0x7A, 0x4F, 0xF0, 0x86, 0x42, -+0x00, 0x23, 0xB8, 0xF1, 0x09, 0x0F, 0xCD, 0xED, 0x01, 0x5A, 0x8D, 0xED, 0x02, 0x6A, 0xCD, 0xED, 0x03, 0x6A, 0x8D, 0xED, -+0x04, 0x7A, 0xCD, 0xED, 0x05, 0x7A, 0x00, 0x92, 0x8D, 0xF8, 0x18, 0x30, 0x16, 0xD8, 0x06, 0xAB, 0x03, 0xAA, 0x69, 0x46, -+0x40, 0x46, 0xFF, 0xF7, 0x17, 0xFE, 0x9D, 0xF8, 0x18, 0x30, 0x13, 0xF0, 0x0E, 0x0F, 0x4C, 0xD1, 0x9D, 0xF8, 0x19, 0x40, -+0x35, 0x49, 0x42, 0x46, 0x4F, 0xF4, 0x00, 0x50, 0x20, 0xF0, 0xE2, 0xFE, 0x20, 0x46, 0x0E, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, -+0x03, 0xA9, 0x68, 0x46, 0xFF, 0xF7, 0x1C, 0xFC, 0x10, 0xF0, 0x0E, 0x0F, 0x8D, 0xF8, 0x18, 0x00, 0x18, 0xBF, 0x03, 0x46, -+0x49, 0xD0, 0xC8, 0xF1, 0x09, 0x04, 0x64, 0x01, 0xE6, 0xE7, 0x0E, 0xAB, 0x03, 0xEB, 0x80, 0x03, 0x84, 0x00, 0x43, 0xF8, -+0x38, 0xAC, 0x54, 0xE7, 0x06, 0x07, 0x1B, 0xD4, 0x01, 0x28, 0x08, 0xBF, 0x01, 0x24, 0x87, 0xE7, 0x09, 0xEB, 0xC6, 0x03, -+0x03, 0xAA, 0x69, 0x46, 0x40, 0x46, 0xFF, 0xF7, 0xE3, 0xFD, 0x62, 0xE7, 0x19, 0x46, 0x7D, 0xE7, 0x00, 0x23, 0x15, 0xF8, -+0x04, 0x2C, 0x01, 0x2A, 0x17, 0xD0, 0x01, 0x33, 0xDB, 0xB2, 0x04, 0x2B, 0x05, 0xF1, 0x08, 0x05, 0xF5, 0xD1, 0x80, 0x29, -+0x7F, 0xF4, 0x7B, 0xAF, 0x17, 0x49, 0x42, 0x46, 0x4F, 0xF4, 0x00, 0x50, 0x20, 0xF0, 0xA4, 0xFE, 0xC8, 0xF1, 0x09, 0x04, -+0x64, 0x01, 0x20, 0x46, 0x0E, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x80, 0x24, 0xB2, 0xE7, 0x0E, 0xAA, 0x80, 0x29, 0x02, 0xEB, -+0xC1, 0x02, 0x0A, 0xD0, 0x95, 0xED, 0x00, 0x7A, 0x52, 0xED, 0x07, 0x7A, 0xB4, 0xEE, 0x67, 0x7A, 0xF1, 0xEE, 0x10, 0xFA, -+0x98, 0xBF, 0x19, 0x46, 0xD7, 0xE7, 0x19, 0x46, 0xD5, 0xE7, 0x06, 0xAB, 0x03, 0xAA, 0x69, 0x46, 0x40, 0x46, 0xFF, 0xF7, -+0xAB, 0xFD, 0x9D, 0xF8, 0x18, 0x30, 0x13, 0xF0, 0x0E, 0x0F, 0x93, 0xD0, 0xA9, 0xE7, 0x00, 0xBF, 0x14, 0x7A, 0x15, 0x00, -+0x30, 0x7A, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x9A, 0x4A, 0xDF, 0xF8, 0x8C, 0x82, 0x13, 0x68, 0x2D, 0xED, 0x08, 0x8B, -+0x23, 0xF4, 0xFF, 0x43, 0x43, 0xF4, 0xCE, 0x35, 0x8B, 0xB0, 0x43, 0xF4, 0x1D, 0x43, 0x0C, 0x46, 0x45, 0xF4, 0x80, 0x75, -+0x01, 0x46, 0x13, 0x60, 0x01, 0x20, 0x15, 0x60, 0x0D, 0x46, 0x03, 0x91, 0xFC, 0xF7, 0xBA, 0xFD, 0xA2, 0x7B, 0x8F, 0x48, -+0x02, 0xF0, 0x0F, 0x03, 0x01, 0x68, 0x12, 0x09, 0x9B, 0x02, 0x43, 0xEA, 0x82, 0x13, 0x21, 0xF4, 0x7F, 0x52, 0x13, 0x43, -+0x03, 0x60, 0x02, 0x20, 0xFC, 0xF7, 0xAA, 0xFD, 0xAB, 0x6B, 0xC3, 0xF3, 0x07, 0x22, 0x02, 0x92, 0x4F, 0xEA, 0x02, 0x4B, -+0xDA, 0xB2, 0x01, 0x92, 0x4F, 0xEA, 0x03, 0x6A, 0x4F, 0xF0, 0x00, 0x09, 0xDD, 0xE9, 0x01, 0x32, 0xB9, 0xF1, 0x00, 0x0F, -+0x18, 0xBF, 0x13, 0x46, 0xA3, 0xF1, 0x40, 0x02, 0x12, 0xB2, 0x40, 0x33, 0x5F, 0xFA, 0x89, 0xF1, 0x00, 0x2A, 0xAD, 0xF8, -+0x14, 0x20, 0xAD, 0xF8, 0x16, 0x30, 0x00, 0x91, 0xC0, 0xF2, 0xEA, 0x80, 0xFF, 0x2B, 0x01, 0xD9, 0x77, 0x4B, 0x05, 0x93, -+0x00, 0x25, 0x2E, 0x46, 0x05, 0x24, 0x48, 0xF2, 0x80, 0x07, 0xBD, 0xF9, 0x14, 0x30, 0x08, 0xA9, 0x06, 0xA8, 0xB9, 0xF1, -+0x00, 0x0F, 0x00, 0xF0, 0xC3, 0x80, 0x4A, 0xEA, 0x03, 0x43, 0x3B, 0x43, 0xC8, 0xF8, 0x00, 0x30, 0xFF, 0xF7, 0xAE, 0xF8, -+0xBD, 0xF9, 0x16, 0x30, 0x4A, 0xEA, 0x03, 0x43, 0x3B, 0x43, 0xC8, 0xF8, 0x00, 0x30, 0x09, 0xA9, 0x07, 0xA8, 0xFF, 0xF7, -+0xA3, 0xF8, 0xDD, 0xE9, 0x06, 0x02, 0xDD, 0xE9, 0x08, 0x13, 0x01, 0x3C, 0x12, 0x1A, 0x5B, 0x1A, 0x14, 0xF0, 0xFF, 0x04, -+0x16, 0x44, 0x1D, 0x44, 0xD9, 0xD1, 0x62, 0x4B, 0x83, 0xFB, 0x06, 0x12, 0xF6, 0x17, 0xC6, 0xEB, 0x62, 0x06, 0x07, 0xEE, -+0x90, 0x6A, 0x83, 0xFB, 0x05, 0x13, 0xED, 0x17, 0xC5, 0xEB, 0x63, 0x05, 0xB8, 0xEE, 0xE7, 0x7A, 0x07, 0xEE, 0x90, 0x5A, -+0xF8, 0xEE, 0xE7, 0x7A, 0xB9, 0xF1, 0x00, 0x0F, 0x00, 0xF0, 0x9D, 0x80, 0x00, 0x9B, 0x01, 0x2B, 0x40, 0xF0, 0x9D, 0x80, -+0xC7, 0xEE, 0x27, 0x9A, 0x03, 0x9B, 0x54, 0x49, 0x54, 0x4F, 0x4F, 0xF4, 0x00, 0x50, 0x1E, 0x1F, 0x03, 0xF1, 0x3C, 0x08, -+0xB6, 0xEE, 0x00, 0xAA, 0x79, 0xEE, 0x88, 0x9A, 0xF7, 0xEE, 0x00, 0xAA, 0x69, 0xEE, 0x8A, 0x9A, 0x8A, 0xEE, 0xA9, 0x8A, -+0xFD, 0xEE, 0xC8, 0x8A, 0x18, 0xEE, 0x90, 0x2A, 0x20, 0xF0, 0xCA, 0xFD, 0xF8, 0xEE, 0xE8, 0x8A, 0xDF, 0xED, 0x49, 0x7A, -+0x49, 0x49, 0x38, 0xEE, 0x68, 0x8A, 0x4F, 0xF4, 0x00, 0x50, 0x28, 0xEE, 0x27, 0x8A, 0xFD, 0xEE, 0xC8, 0x7A, 0x17, 0xEE, -+0x90, 0x2A, 0x20, 0xF0, 0xB9, 0xFD, 0x69, 0xEE, 0xA9, 0x7A, 0x39, 0xEE, 0xAA, 0xBA, 0x17, 0xEE, 0x90, 0x0A, 0x32, 0xF0, -+0x71, 0xFD, 0x40, 0x4B, 0x00, 0x22, 0x32, 0xF0, 0x0F, 0xFC, 0x7A, 0xEE, 0xE9, 0xAA, 0x04, 0x46, 0x0D, 0x46, 0x56, 0xF8, -+0x04, 0x3F, 0xC3, 0xF3, 0x07, 0x22, 0x08, 0xEE, 0x90, 0x2A, 0xDB, 0xB2, 0x08, 0xEE, 0x10, 0x3A, 0xF8, 0xEE, 0xE8, 0x8A, -+0xB8, 0xEE, 0xC8, 0x8A, 0x68, 0xEE, 0xAA, 0x8A, 0x28, 0xEE, 0x0B, 0x8A, 0x69, 0xEE, 0xA8, 0x7A, 0x78, 0xEE, 0x67, 0x7A, -+0x29, 0xEE, 0x88, 0x8A, 0x17, 0xEE, 0x90, 0x0A, 0x32, 0xF0, 0x4E, 0xFD, 0x22, 0x46, 0x2B, 0x46, 0x32, 0xF0, 0xCC, 0xFE, -+0x33, 0xF0, 0x5A, 0xF8, 0x78, 0xEE, 0x28, 0x7A, 0x09, 0xEE, 0x10, 0x0A, 0x17, 0xEE, 0x90, 0x0A, 0x32, 0xF0, 0x40, 0xFD, -+0x22, 0x46, 0x2B, 0x46, 0x32, 0xF0, 0xBE, 0xFE, 0x33, 0xF0, 0x4C, 0xF8, 0x07, 0xEE, 0x90, 0x0A, 0x77, 0xEE, 0x8A, 0x7A, -+0x39, 0xEE, 0x0A, 0x9A, 0xFD, 0xEE, 0xE7, 0x7A, 0xB0, 0x45, 0x17, 0xEE, 0x90, 0x3A, 0xFD, 0xEE, 0xC9, 0x7A, 0x4F, 0xEA, -+0x03, 0x23, 0xCD, 0xED, 0x00, 0x7A, 0x9D, 0xF8, 0x00, 0x20, 0x03, 0xF4, 0x7F, 0x43, 0x43, 0xEA, 0x02, 0x03, 0x43, 0xEA, -+0x07, 0x03, 0x33, 0x60, 0xB5, 0xD1, 0x0B, 0xB0, 0xBD, 0xEC, 0x08, 0x8B, 0xBD, 0xE8, 0xF0, 0x8F, 0x4B, 0xEA, 0x03, 0x63, -+0x3B, 0x43, 0xC8, 0xF8, 0x00, 0x30, 0x08, 0xA9, 0x06, 0xA8, 0xFE, 0xF7, 0xE9, 0xFF, 0xBD, 0xF9, 0x16, 0x30, 0x4B, 0xEA, -+0x03, 0x63, 0x3B, 0x43, 0x39, 0xE7, 0xF1, 0xEE, 0x67, 0x7A, 0x87, 0xEE, 0x87, 0x8A, 0x09, 0xF1, 0x01, 0x09, 0x01, 0xE7, -+0x4F, 0xF4, 0x00, 0x03, 0x05, 0x93, 0x15, 0xE7, 0x58, 0x40, 0x34, 0x40, 0x50, 0x40, 0x34, 0x40, 0x80, 0x00, 0xFF, 0x00, -+0x67, 0x66, 0x66, 0x66, 0x48, 0x7A, 0x15, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x7A, 0x44, 0x58, 0x7A, 0x15, 0x00, -+0x00, 0x00, 0xF0, 0x3F, 0x4C, 0x40, 0x34, 0x40, 0x2D, 0xE9, 0xF0, 0x4F, 0xB5, 0x4C, 0x2D, 0xED, 0x04, 0x8B, 0x27, 0x68, -+0xAD, 0xF2, 0xE4, 0x7D, 0x06, 0x46, 0x0D, 0x46, 0x14, 0x46, 0xB2, 0x49, 0x0A, 0x94, 0x3A, 0x46, 0x4F, 0xF4, 0x00, 0x50, -+0x9A, 0x46, 0xCD, 0xE9, 0x13, 0x56, 0x20, 0xF0, 0x17, 0xFD, 0xAE, 0x4B, 0xAE, 0x49, 0x1A, 0x68, 0x4F, 0xF4, 0x00, 0x50, -+0x20, 0xF0, 0x10, 0xFD, 0xAC, 0x4B, 0xAD, 0x49, 0x1A, 0x68, 0x4F, 0xF4, 0x00, 0x50, 0x20, 0xF0, 0x09, 0xFD, 0xAB, 0x4B, -+0xAB, 0x49, 0x1A, 0x68, 0x4F, 0xF4, 0x00, 0x50, 0x20, 0xF0, 0x02, 0xFD, 0xA9, 0x49, 0x4F, 0xF4, 0x00, 0x50, 0x20, 0xF0, -+0xFD, 0xFC, 0x16, 0xF0, 0x01, 0x03, 0x15, 0x93, 0x07, 0xD1, 0xA6, 0x4A, 0x13, 0x68, 0x43, 0xF4, 0x00, 0x61, 0x43, 0xF4, -+0xC0, 0x53, 0x11, 0x60, 0x13, 0x60, 0x14, 0x9A, 0xC2, 0xF3, 0x40, 0x03, 0x03, 0x33, 0x12, 0xF0, 0x0C, 0x0F, 0x09, 0xEE, -+0x10, 0x3A, 0xC2, 0xF3, 0x81, 0x03, 0x00, 0xF0, 0x9C, 0x82, 0x01, 0x2B, 0x14, 0xBF, 0x0A, 0x23, 0x05, 0x23, 0x08, 0xEE, -+0x90, 0x3A, 0x9A, 0x4A, 0x9A, 0x4E, 0x14, 0x68, 0xDF, 0xF8, 0x7C, 0xE2, 0x99, 0x4B, 0x9A, 0x49, 0xDF, 0xF8, 0x78, 0x92, -+0xDF, 0xF8, 0x78, 0xB2, 0x98, 0x48, 0xDF, 0xF8, 0x78, 0xC2, 0x98, 0x4F, 0xDF, 0xF8, 0x74, 0x82, 0x24, 0xF0, 0x04, 0x04, -+0x14, 0x60, 0x35, 0x68, 0x00, 0x24, 0x25, 0xF4, 0x70, 0x45, 0x35, 0x60, 0xCE, 0xF8, 0x00, 0x40, 0x1D, 0x68, 0x45, 0xF0, -+0x80, 0x05, 0x1D, 0x60, 0x0D, 0x68, 0x45, 0xF0, 0x00, 0x45, 0x0D, 0x60, 0x15, 0x68, 0x01, 0x26, 0x45, 0xF0, 0x04, 0x05, -+0x15, 0x60, 0xCB, 0xF8, 0x00, 0x60, 0xC9, 0xF8, 0x00, 0x40, 0x15, 0x68, 0x25, 0xF0, 0x04, 0x05, 0x15, 0x60, 0x0D, 0x68, -+0x25, 0xF0, 0x00, 0x45, 0x0D, 0x60, 0x1D, 0x68, 0x25, 0xF0, 0x80, 0x05, 0x1D, 0x60, 0x15, 0x68, 0x45, 0xF0, 0x04, 0x05, -+0x15, 0x60, 0x82, 0x4D, 0x2A, 0x68, 0x42, 0xF0, 0x02, 0x02, 0x2A, 0x60, 0x1A, 0x68, 0x22, 0xF4, 0xE0, 0x42, 0x22, 0xF0, -+0x04, 0x02, 0x42, 0xF4, 0x80, 0x42, 0x32, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x22, 0xF0, 0x07, 0x22, 0x42, 0xF0, 0xC0, 0x62, -+0x42, 0xF4, 0x84, 0x72, 0x1A, 0x60, 0x0B, 0x68, 0x03, 0xF0, 0x00, 0x43, 0x43, 0xEA, 0x0A, 0x03, 0x0B, 0x60, 0x03, 0x68, -+0x43, 0xF0, 0x3F, 0x03, 0x03, 0x60, 0xDC, 0xF8, 0x00, 0x30, 0x0B, 0x94, 0x43, 0xF4, 0x00, 0x63, 0x38, 0xAA, 0x78, 0xA9, -+0x10, 0x92, 0x0F, 0x91, 0xCC, 0xF8, 0x00, 0x30, 0x0D, 0xF1, 0x7F, 0x03, 0xCD, 0xE9, 0x11, 0x21, 0x0D, 0x93, 0x08, 0xEE, -+0x10, 0x4A, 0x0D, 0xF1, 0xAF, 0x03, 0x81, 0x46, 0x0E, 0x93, 0x00, 0x23, 0x0C, 0x93, 0x9D, 0xF8, 0x30, 0x50, 0x18, 0xEE, -+0x10, 0x3A, 0x2B, 0x43, 0x09, 0x93, 0x00, 0x24, 0x3D, 0xE0, 0x0C, 0x9B, 0x00, 0x2B, 0x6C, 0xD0, 0x66, 0x00, 0x0D, 0x9B, -+0x26, 0x44, 0x48, 0xF2, 0x80, 0x0B, 0x13, 0xF8, 0x06, 0xA0, 0x0E, 0x9B, 0x9E, 0x5D, 0x4F, 0xEA, 0x0A, 0x63, 0x43, 0xEA, -+0x0A, 0x43, 0x43, 0xEA, 0x0B, 0x03, 0xC8, 0xF8, 0x00, 0x30, 0x19, 0xA9, 0x18, 0xA8, 0xFE, 0xF7, 0xE3, 0xFE, 0xB2, 0x45, -+0x0A, 0xD0, 0x33, 0x06, 0x43, 0xEA, 0x06, 0x46, 0x46, 0xEA, 0x0B, 0x06, 0xC8, 0xF8, 0x00, 0x60, 0x19, 0xA9, 0x17, 0xA8, -+0xFE, 0xF7, 0xD6, 0xFE, 0x04, 0xEB, 0x84, 0x03, 0xB8, 0xAA, 0xDE, 0x00, 0x00, 0x21, 0x02, 0xEB, 0xC3, 0x03, 0x28, 0x46, -+0x18, 0x9A, 0xFF, 0xF7, 0x51, 0xF8, 0x0D, 0xF5, 0xAC, 0x63, 0x33, 0x44, 0x19, 0x9A, 0x01, 0x34, 0x00, 0x21, 0x28, 0x46, -+0xFF, 0xF7, 0x48, 0xF8, 0x10, 0x2C, 0xB8, 0xAE, 0x0D, 0xF5, 0xAC, 0x6B, 0x59, 0xD0, 0x3B, 0x68, 0x23, 0xF4, 0xFF, 0x43, -+0x43, 0xEA, 0x44, 0x23, 0x43, 0xF4, 0x01, 0x42, 0x43, 0xF4, 0xC0, 0x33, 0x43, 0xF4, 0x80, 0x73, 0x3A, 0x60, 0x01, 0x20, -+0x3B, 0x60, 0xFC, 0xF7, 0x71, 0xFB, 0x09, 0x9B, 0xE6, 0xB2, 0x00, 0x2B, 0x3D, 0xD0, 0x0A, 0x9B, 0xD9, 0xF8, 0x00, 0x10, -+0x1A, 0x5D, 0x02, 0xF0, 0x0F, 0x03, 0x9B, 0x02, 0x12, 0x09, 0x43, 0xEA, 0x82, 0x13, 0x21, 0xF4, 0x7F, 0x52, 0x13, 0x43, -+0xC9, 0xF8, 0x00, 0x30, 0x02, 0x20, 0xFC, 0xF7, 0x5B, 0xFB, 0x0B, 0x9B, 0x00, 0x2B, 0x98, 0xD1, 0x4F, 0xF0, 0x80, 0x33, -+0xC8, 0xF8, 0x00, 0x30, 0x19, 0xA9, 0x18, 0xA8, 0xFE, 0xF7, 0x8C, 0xFE, 0xB4, 0xE7, 0x10, 0x9B, 0x04, 0xEB, 0x44, 0x0B, -+0x03, 0xEB, 0x04, 0x12, 0x20, 0xAB, 0x18, 0xEE, 0x10, 0x0A, 0x5B, 0x44, 0x00, 0x92, 0x31, 0x46, 0x0D, 0xF1, 0x5A, 0x02, -+0xFE, 0xF7, 0xF2, 0xFF, 0x0F, 0x9B, 0x4F, 0xEA, 0x04, 0x1A, 0x0A, 0xEB, 0x03, 0x02, 0x2C, 0xAB, 0x31, 0x46, 0x00, 0x92, -+0x18, 0xEE, 0x10, 0x0A, 0x5B, 0x44, 0x0D, 0xF1, 0x5B, 0x02, 0x66, 0x00, 0xFE, 0xF7, 0xE2, 0xFF, 0x73, 0xE7, 0xFE, 0xF7, -+0xA7, 0xFE, 0x0A, 0x9B, 0x18, 0x55, 0x02, 0x20, 0xFC, 0xF7, 0x28, 0xFB, 0xCE, 0xE7, 0x0C, 0x9B, 0x18, 0xEE, 0x90, 0x2A, -+0x01, 0x33, 0x93, 0x42, 0x0C, 0x93, 0x7F, 0xF4, 0x58, 0xAF, 0x18, 0xEE, 0x90, 0xAA, 0x00, 0x25, 0x45, 0xE0, 0x00, 0xBF, -+0x10, 0x20, 0x34, 0x40, 0x60, 0x7A, 0x15, 0x00, 0x1C, 0x20, 0x34, 0x40, 0x74, 0x7A, 0x15, 0x00, 0x04, 0x22, 0x34, 0x40, -+0x88, 0x7A, 0x15, 0x00, 0x18, 0x00, 0x58, 0x40, 0x9C, 0x7A, 0x15, 0x00, 0xB0, 0x7A, 0x15, 0x00, 0x04, 0x40, 0x34, 0x40, -+0x30, 0x20, 0x34, 0x40, 0x60, 0x20, 0x34, 0x40, 0x5C, 0x20, 0x34, 0x40, 0x64, 0x20, 0x34, 0x40, 0x50, 0x40, 0x34, 0x40, -+0x58, 0x40, 0x34, 0x40, 0x80, 0x21, 0x34, 0x40, 0x68, 0x20, 0x34, 0x40, 0x0C, 0xB6, 0x33, 0x40, 0x08, 0xB6, 0x33, 0x40, -+0x20, 0x40, 0x34, 0x40, 0x4C, 0x40, 0x34, 0x40, 0x06, 0x2D, 0x34, 0xBF, 0x32, 0x21, 0x64, 0x21, 0x09, 0x91, 0xFE, 0xF7, -+0xDB, 0xFF, 0x11, 0x9B, 0x09, 0x99, 0x84, 0x46, 0x43, 0xF8, 0x04, 0xC0, 0x5A, 0x46, 0x50, 0x46, 0xFE, 0xF7, 0xD2, 0xFF, -+0x01, 0x35, 0x12, 0x9B, 0x10, 0x2D, 0x18, 0x51, 0x06, 0xF1, 0x28, 0x06, 0x0B, 0xF1, 0x28, 0x0B, 0x14, 0xD0, 0xBA, 0xF1, -+0x01, 0x0F, 0x32, 0x46, 0x4F, 0xEA, 0x05, 0x14, 0x50, 0x46, 0xDF, 0xD1, 0x11, 0x9B, 0x30, 0x68, 0x18, 0x51, 0x01, 0x35, -+0x12, 0x9B, 0xDB, 0xF8, 0x00, 0x10, 0x19, 0x51, 0x10, 0x2D, 0x06, 0xF1, 0x28, 0x06, 0x0B, 0xF1, 0x28, 0x0B, 0xEA, 0xD1, -+0x11, 0x9A, 0x0B, 0x9B, 0x04, 0x32, 0x11, 0x92, 0x12, 0x9A, 0x04, 0x32, 0x12, 0x92, 0x0D, 0x9A, 0x01, 0x32, 0x0D, 0x92, -+0x0E, 0x9A, 0x01, 0x32, 0x01, 0x33, 0x0E, 0x92, 0x19, 0xEE, 0x10, 0x2A, 0x0B, 0x93, 0xDB, 0xB2, 0x9A, 0x42, 0x08, 0xEE, -+0x10, 0x3A, 0x3F, 0xF6, 0xE0, 0xAE, 0x20, 0xAD, 0x2C, 0xAC, 0xAB, 0x46, 0x0B, 0x95, 0xDD, 0xF8, 0x40, 0x80, 0x0F, 0x9F, -+0x09, 0x94, 0x19, 0xEE, 0x10, 0x5A, 0xA2, 0x46, 0x00, 0x26, 0x09, 0xE0, 0x13, 0x9A, 0x42, 0xF8, 0x26, 0x30, 0x01, 0x36, -+0x0B, 0xF1, 0x03, 0x0B, 0x08, 0xF1, 0x10, 0x08, 0x0A, 0xF1, 0x03, 0x0A, 0x5F, 0xFA, 0x86, 0xF9, 0x49, 0x46, 0x43, 0x46, -+0x5A, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0x98, 0xFB, 0x07, 0xEB, 0x06, 0x13, 0x04, 0x46, 0x52, 0x46, 0x49, 0x46, 0x28, 0x46, -+0xFF, 0xF7, 0x90, 0xFB, 0x03, 0x02, 0xE2, 0xB2, 0x03, 0xF4, 0x7F, 0x43, 0x13, 0x43, 0x43, 0xF0, 0x00, 0x43, 0x09, 0x2E, -+0x43, 0xF4, 0x00, 0x03, 0xDA, 0xD9, 0x1A, 0xAB, 0x03, 0xEB, 0x46, 0x02, 0x1D, 0xAB, 0x03, 0xEB, 0x46, 0x03, 0xB9, 0xF1, -+0x0F, 0x0F, 0x22, 0xF8, 0x14, 0x4C, 0x23, 0xF8, 0x14, 0x0C, 0xD0, 0xD1, 0x14, 0x9B, 0x09, 0x9C, 0x0B, 0x9D, 0xC3, 0xF3, -+0x40, 0x10, 0x1A, 0xA9, 0x09, 0x90, 0xFF, 0xF7, 0xD3, 0xF8, 0x09, 0x98, 0x1D, 0xA9, 0xFF, 0xF7, 0xCF, 0xF8, 0x13, 0x9B, -+0xDF, 0xF8, 0x98, 0xC1, 0x1D, 0xA8, 0x1A, 0xA9, 0x03, 0xF1, 0x24, 0x06, 0x03, 0xF1, 0x3C, 0x07, 0x30, 0xF9, 0x02, 0x3B, -+0x31, 0xF9, 0x02, 0x2B, 0x1B, 0x02, 0x03, 0xF4, 0x7F, 0x43, 0xD2, 0xB2, 0x13, 0x43, 0x43, 0xEA, 0x0C, 0x03, 0x46, 0xF8, -+0x04, 0x3F, 0xBE, 0x42, 0xF0, 0xD1, 0x10, 0x9B, 0xDF, 0xF8, 0x6C, 0x81, 0xDD, 0xF8, 0x3C, 0xA0, 0x03, 0xF5, 0x80, 0x77, -+0x00, 0x26, 0x99, 0x46, 0xD9, 0xF8, 0x0C, 0x20, 0xAB, 0x78, 0xD9, 0xF8, 0x08, 0xC0, 0x68, 0x78, 0xD9, 0xF8, 0x04, 0x10, -+0x06, 0x92, 0x15, 0xF8, 0x03, 0x2B, 0x05, 0x93, 0x59, 0xF8, 0x10, 0x3B, 0x00, 0x93, 0xCD, 0xE9, 0x03, 0x0C, 0xCD, 0xE9, -+0x01, 0x21, 0x80, 0x23, 0x32, 0x46, 0x41, 0x46, 0x4F, 0xF4, 0x00, 0x50, 0x20, 0xF0, 0xC6, 0xFA, 0xDA, 0xF8, 0x0C, 0x20, -+0xA3, 0x78, 0x60, 0x78, 0xDA, 0xF8, 0x04, 0x10, 0xDA, 0xF8, 0x08, 0xC0, 0x06, 0x92, 0x14, 0xF8, 0x03, 0x2B, 0x05, 0x93, -+0x5A, 0xF8, 0x10, 0x3B, 0x00, 0x93, 0xCD, 0xE9, 0x01, 0x21, 0xCD, 0xE9, 0x03, 0x0C, 0x32, 0x46, 0x36, 0x49, 0x80, 0x23, -+0x4F, 0xF4, 0x00, 0x50, 0x20, 0xF0, 0xAC, 0xFA, 0x4F, 0x45, 0x06, 0xF1, 0x01, 0x06, 0xC7, 0xD1, 0x13, 0x9B, 0x32, 0x4E, -+0x1D, 0x1F, 0x00, 0x24, 0x55, 0xF8, 0x04, 0x3F, 0xC3, 0xF3, 0x07, 0x22, 0x00, 0x92, 0xDB, 0xB2, 0x22, 0x46, 0x31, 0x46, -+0x01, 0x34, 0x4F, 0xF4, 0x00, 0x50, 0x20, 0xF0, 0x97, 0xFA, 0x10, 0x2C, 0xF0, 0xD1, 0x14, 0x9B, 0xDB, 0x06, 0x0D, 0xD5, -+0x15, 0x9B, 0x3B, 0xB1, 0x27, 0x4A, 0x13, 0x68, 0x43, 0xF4, 0x00, 0x61, 0x43, 0xF4, 0xC0, 0x53, 0x11, 0x60, 0x13, 0x60, -+0x0A, 0x99, 0x13, 0x98, 0xFF, 0xF7, 0x0C, 0xFC, 0x22, 0x49, 0x23, 0x4A, 0x0B, 0x68, 0x23, 0x4E, 0x23, 0x4C, 0x24, 0x48, -+0x23, 0xF0, 0x02, 0x03, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF4, 0xEE, 0x43, 0x23, 0xF0, 0x09, 0x03, 0x43, 0xF4, 0x58, 0x53, -+0xA1, 0xF5, 0xD6, 0x41, 0x43, 0xF0, 0x04, 0x03, 0x13, 0x60, 0x74, 0x39, 0x02, 0xF5, 0xFF, 0x52, 0x1C, 0x32, 0x00, 0x23, -+0x4F, 0xF0, 0x80, 0x35, 0x33, 0x60, 0x25, 0x60, 0x03, 0x60, 0x0B, 0x60, 0x13, 0x68, 0x17, 0x49, 0x23, 0xF4, 0x7F, 0x43, -+0x00, 0xF5, 0x09, 0x40, 0x23, 0xF0, 0x80, 0x03, 0xFC, 0x30, 0x43, 0xF4, 0x80, 0x34, 0x13, 0x60, 0x14, 0x60, 0x03, 0x68, -+0x23, 0xF4, 0xC0, 0x53, 0x03, 0x60, 0x4F, 0xF4, 0x00, 0x50, 0x20, 0xF0, 0x4F, 0xFA, 0x0D, 0xF2, 0xE4, 0x7D, 0xBD, 0xEC, -+0x04, 0x8B, 0xBD, 0xE8, 0xF0, 0x8F, 0x01, 0x23, 0x08, 0xEE, 0x90, 0x3A, 0x65, 0xE5, 0x00, 0xBF, 0xF0, 0x7A, 0x15, 0x00, -+0x1C, 0x7B, 0x15, 0x00, 0x04, 0x40, 0x34, 0x40, 0x80, 0x21, 0x34, 0x40, 0x5C, 0x20, 0x34, 0x40, 0x50, 0x40, 0x34, 0x40, -+0x4C, 0x40, 0x34, 0x40, 0x08, 0xB6, 0x33, 0x40, 0x3C, 0x7B, 0x15, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC4, 0x7A, 0x15, 0x00, -+0xF0, 0xB5, 0x07, 0x78, 0x43, 0x68, 0x83, 0xB0, 0x0E, 0x46, 0x3A, 0x46, 0x27, 0x49, 0x01, 0x93, 0x4F, 0xF4, 0x00, 0x50, -+0x20, 0xF0, 0x22, 0xFA, 0x01, 0x9B, 0x30, 0x1F, 0x06, 0xF1, 0x3C, 0x01, 0x4F, 0xF0, 0x80, 0x32, 0x40, 0xF8, 0x04, 0x2F, -+0x88, 0x42, 0xFB, 0xD1, 0x06, 0xF1, 0x3F, 0x00, 0x06, 0xF1, 0x4F, 0x02, 0x00, 0x24, 0x00, 0xF8, 0x01, 0x4F, 0x82, 0x42, -+0xFB, 0xD1, 0x30, 0x46, 0x34, 0x65, 0x06, 0xF1, 0x94, 0x05, 0x40, 0xF8, 0x54, 0x4F, 0x00, 0x24, 0x40, 0xF8, 0x04, 0x4F, -+0xA8, 0x42, 0xFB, 0xD1, 0xBA, 0x09, 0x18, 0xD0, 0x15, 0x4C, 0xDF, 0xF8, 0x74, 0xC0, 0x21, 0x68, 0x14, 0x4D, 0x15, 0x4A, -+0x15, 0x48, 0x21, 0xF4, 0x00, 0x11, 0x21, 0x60, 0xF9, 0x09, 0x00, 0x29, 0x08, 0xBF, 0x62, 0x46, 0x2A, 0x60, 0x05, 0x68, -+0x11, 0x49, 0x12, 0x4C, 0x12, 0x4A, 0x01, 0xEA, 0x05, 0x01, 0x08, 0xBF, 0x22, 0x46, 0x0A, 0x43, 0x02, 0x60, 0x01, 0x93, -+0xFE, 0xF7, 0x08, 0xFC, 0x0E, 0x4A, 0x01, 0x9B, 0xD2, 0xF8, 0xBC, 0x44, 0x38, 0x46, 0x06, 0xF1, 0x40, 0x02, 0x31, 0x46, -+0xA0, 0x47, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x40, 0xFE, 0xF7, 0x44, 0xBC, 0x50, 0x7B, 0x15, 0x00, 0x58, 0x40, 0x34, 0x40, -+0x10, 0x20, 0x34, 0x40, 0x76, 0x62, 0xF7, 0x0B, 0x1C, 0x20, 0x34, 0x40, 0xFF, 0x0F, 0x00, 0xE0, 0x00, 0x50, 0x98, 0x00, -+0x00, 0x90, 0x9B, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x76, 0x62, 0xB7, 0x0B, 0x17, 0x4B, 0x01, 0x22, 0x30, 0xB4, 0x1A, 0x60, -+0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0x13, 0x4A, 0x13, 0x68, 0x00, 0x2B, 0x08, 0xDB, -+0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0x13, 0x68, 0x00, 0x2B, 0xF6, 0xDA, 0x0E, 0x4A, -+0x0C, 0x4B, 0x15, 0x68, 0x1C, 0x68, 0xC5, 0xF3, 0x10, 0x02, 0xED, 0x03, 0x44, 0xBF, 0x6F, 0xEA, 0x02, 0x42, 0x6F, 0xEA, -+0x12, 0x42, 0xC4, 0xF3, 0x10, 0x03, 0x02, 0x60, 0xE2, 0x03, 0x44, 0xBF, 0x6F, 0xEA, 0x03, 0x43, 0x6F, 0xEA, 0x13, 0x43, -+0x30, 0xBC, 0x0B, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x6C, 0x08, 0x62, 0x40, 0x90, 0x08, 0x62, 0x40, 0x8C, 0x08, 0x62, 0x40, -+0x30, 0xB4, 0x11, 0x4C, 0x11, 0x4D, 0x12, 0x4B, 0x04, 0xEA, 0x02, 0x42, 0xC1, 0xF3, 0x0E, 0x01, 0x0A, 0x43, 0x2A, 0x60, -+0x1A, 0x68, 0x00, 0xF0, 0x07, 0x00, 0x22, 0xF0, 0xE0, 0x62, 0x02, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF0, 0x00, 0x42, -+0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF0, 0x80, 0x42, 0x1A, 0x60, 0x1A, 0x68, 0x22, 0xF0, 0x80, 0x42, 0x1A, 0x60, 0x1A, 0x68, -+0x22, 0xF0, 0x00, 0x42, 0x30, 0xBC, 0x1A, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x00, 0xFF, 0x7F, 0x44, 0x05, 0x62, 0x40, -+0x28, 0x05, 0x62, 0x40, 0x38, 0xB5, 0x28, 0x4C, 0x28, 0x4A, 0x23, 0x68, 0x28, 0x49, 0x23, 0xF0, 0xFF, 0x03, 0x03, 0x43, -+0x43, 0xF0, 0x80, 0x03, 0x23, 0x60, 0x13, 0x68, 0x43, 0xF0, 0x01, 0x03, 0x13, 0x60, 0x0A, 0x68, 0x22, 0xF0, 0x03, 0x02, -+0x42, 0xF0, 0x02, 0x03, 0x0B, 0x60, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0x1D, 0x4B, -+0x42, 0xF0, 0x03, 0x02, 0x1A, 0x60, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0x19, 0x4A, -+0x13, 0x68, 0x98, 0x07, 0x08, 0xD4, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0x13, 0x68, -+0x98, 0x07, 0xF6, 0xD5, 0x13, 0x4C, 0x22, 0x68, 0x51, 0x00, 0x0E, 0xD4, 0x12, 0x4D, 0x29, 0x46, 0x4F, 0xF4, 0x00, 0x50, -+0x20, 0xF0, 0x28, 0xF9, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0x22, 0x68, 0x53, 0x00, -+0xF1, 0xD5, 0x0C, 0x4A, 0x0C, 0x49, 0x13, 0x68, 0x43, 0xF4, 0x80, 0x03, 0x13, 0x60, 0x4F, 0xF4, 0x00, 0x50, 0xBD, 0xE8, -+0x38, 0x40, 0x20, 0xF0, 0x13, 0xB9, 0x00, 0xBF, 0x08, 0x01, 0x60, 0x40, 0x08, 0x05, 0x62, 0x40, 0x00, 0x00, 0x62, 0x40, -+0x80, 0x40, 0x34, 0x40, 0x04, 0x22, 0x34, 0x40, 0x68, 0x7B, 0x15, 0x00, 0x04, 0x00, 0x62, 0x40, 0x7C, 0x7B, 0x15, 0x00, -+0x10, 0xB5, 0x0F, 0x4C, 0x0F, 0x4A, 0x23, 0x68, 0x0F, 0x48, 0x10, 0x49, 0x23, 0xF4, 0x80, 0x03, 0x23, 0x60, 0x13, 0x68, -+0x23, 0xF0, 0x03, 0x03, 0x13, 0x60, 0x13, 0x60, 0x03, 0x68, 0x23, 0xF0, 0xFF, 0x03, 0x03, 0x60, 0x0B, 0x68, 0x23, 0xF0, -+0x01, 0x03, 0x0B, 0x60, 0x14, 0x20, 0xFC, 0xF7, 0x45, 0xF8, 0xBD, 0xE8, 0x10, 0x40, 0x06, 0x49, 0x4F, 0xF4, 0x00, 0x50, -+0x20, 0xF0, 0xE2, 0xB8, 0x04, 0x00, 0x62, 0x40, 0x00, 0x00, 0x62, 0x40, 0x08, 0x01, 0x60, 0x40, 0x08, 0x05, 0x62, 0x40, -+0x88, 0x7B, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x83, 0xB0, 0x07, 0x46, 0x10, 0x1A, 0x0E, 0x46, 0x9B, 0x46, 0xDD, 0xE9, -+0x0E, 0x54, 0x9D, 0xF8, 0x30, 0x90, 0x9D, 0xF8, 0x34, 0x80, 0x32, 0xF0, 0x65, 0xFD, 0x82, 0x46, 0xAB, 0xEB, 0x06, 0x00, -+0x32, 0xF0, 0x60, 0xFD, 0xBA, 0xF1, 0x00, 0x0F, 0x11, 0xD0, 0x07, 0xFA, 0x09, 0xF7, 0x07, 0xEE, 0x90, 0x7A, 0xB8, 0xEE, -+0xE7, 0x7A, 0x07, 0xEE, 0x90, 0xAA, 0xF8, 0xEE, 0xE7, 0x7A, 0xC7, 0xEE, 0x27, 0x6A, 0xFD, 0xEE, 0xE6, 0x7A, 0xCD, 0xED, -+0x01, 0x7A, 0x9D, 0xF9, 0x04, 0xA0, 0x85, 0xF8, 0x00, 0xA0, 0xA8, 0xB1, 0x06, 0xFA, 0x08, 0xF6, 0x07, 0xEE, 0x90, 0x6A, -+0xB8, 0xEE, 0xE7, 0x7A, 0x07, 0xEE, 0x90, 0x0A, 0xF8, 0xEE, 0xE7, 0x7A, 0xC7, 0xEE, 0x27, 0x6A, 0xFD, 0xEE, 0xE6, 0x7A, -+0xCD, 0xED, 0x01, 0x7A, 0x9D, 0xF9, 0x04, 0x30, 0x23, 0x70, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x03, 0x46, 0x23, 0x70, -+0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x4F, 0xA1, 0x4F, 0xA2, 0x4C, 0x3D, 0x68, 0xA2, 0x4E, -+0xAD, 0xB2, 0x25, 0x43, 0x2D, 0xED, 0x02, 0x8B, 0x3D, 0x60, 0x35, 0x68, 0x91, 0xB0, 0x25, 0xF0, 0x01, 0x05, 0x86, 0x46, -+0x35, 0x60, 0x8C, 0x46, 0x4F, 0xF4, 0x00, 0x50, 0x9B, 0x49, 0xCD, 0xF8, 0x1C, 0xE0, 0xCD, 0xE9, 0x08, 0x23, 0x08, 0xEE, -+0x10, 0xCA, 0x75, 0x46, 0x20, 0xF0, 0x72, 0xF8, 0x3B, 0x68, 0x9B, 0xB2, 0x23, 0x43, 0x3B, 0x60, 0x00, 0x2D, 0x00, 0xF0, -+0x16, 0x81, 0x00, 0x26, 0x34, 0x46, 0x35, 0x46, 0x0D, 0xF1, 0x34, 0x0B, 0x0D, 0xF1, 0x30, 0x0A, 0x32, 0x23, 0x00, 0xBF, -+0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0x59, 0x46, 0x50, 0x46, 0xFF, 0xF7, 0x96, 0xFE, 0xDD, 0xE9, 0x0C, 0x32, -+0x8A, 0x49, 0xCD, 0xE9, 0x00, 0x32, 0x4F, 0xF4, 0x00, 0x50, 0x23, 0x46, 0x2A, 0x46, 0x20, 0xF0, 0x4F, 0xF8, 0x0C, 0x9B, -+0x00, 0x2B, 0xC0, 0xF2, 0xA5, 0x80, 0x00, 0x2E, 0x00, 0xF0, 0xB9, 0x80, 0x01, 0x2E, 0x00, 0xF0, 0xDD, 0x80, 0x0D, 0x9B, -+0x15, 0xF1, 0x7C, 0x0F, 0xAC, 0xBF, 0x2A, 0x1F, 0x2A, 0x1D, 0x00, 0x2B, 0x80, 0xF2, 0xA1, 0x80, 0x01, 0x2E, 0x4F, 0xF0, -+0x02, 0x08, 0x00, 0xF0, 0xDA, 0x80, 0x7B, 0x2C, 0x00, 0xF3, 0xA1, 0x80, 0x23, 0x1D, 0x4F, 0xF0, 0x02, 0x09, 0xA3, 0xF1, -+0x80, 0x01, 0x38, 0x68, 0xC9, 0xB2, 0x09, 0x04, 0xA2, 0xF1, 0x80, 0x0C, 0x41, 0xEA, 0x0C, 0x61, 0x80, 0xB2, 0x01, 0x43, -+0x39, 0x60, 0x32, 0x21, 0x00, 0xBF, 0x01, 0x39, 0x89, 0xB2, 0x00, 0x29, 0xFA, 0xD1, 0x0F, 0xA9, 0x0E, 0xA8, 0xCD, 0xE9, -+0x05, 0x23, 0xFF, 0xF7, 0x55, 0xFE, 0xDD, 0xE9, 0x0E, 0x10, 0xDD, 0xE9, 0x05, 0x23, 0x01, 0x90, 0x00, 0x91, 0x4F, 0xF4, -+0x00, 0x50, 0x68, 0x49, 0x20, 0xF0, 0x0E, 0xF8, 0x0D, 0xF1, 0x2F, 0x03, 0x03, 0x93, 0x0D, 0xF1, 0x2E, 0x03, 0xCD, 0xE9, -+0x01, 0x93, 0xDD, 0xE9, 0x0C, 0x01, 0xDD, 0xE9, 0x0E, 0x23, 0xCD, 0xF8, 0x00, 0x80, 0xFF, 0xF7, 0x27, 0xFF, 0x9D, 0xF9, -+0x2F, 0x30, 0x9D, 0xF9, 0x2E, 0x20, 0x5E, 0x49, 0x4F, 0xF4, 0x00, 0x50, 0x1F, 0xF0, 0xF6, 0xFF, 0x9D, 0xF9, 0x2F, 0x30, -+0x9D, 0xF9, 0x2E, 0x20, 0x39, 0x68, 0xE4, 0x1A, 0x6F, 0xF0, 0x7F, 0x03, 0x9C, 0x42, 0xB8, 0xBF, 0x1C, 0x46, 0xAD, 0x1A, -+0x7F, 0x2C, 0xA8, 0xBF, 0x7F, 0x24, 0x9D, 0x42, 0xB8, 0xBF, 0x1D, 0x46, 0x04, 0xEB, 0x03, 0x08, 0x7F, 0x2D, 0xA8, 0xBF, -+0x7F, 0x25, 0x5F, 0xFA, 0x88, 0xF8, 0xA5, 0xF1, 0x80, 0x02, 0x4F, 0xEA, 0x08, 0x43, 0x43, 0xEA, 0x02, 0x63, 0x89, 0xB2, -+0x0B, 0x43, 0x01, 0x36, 0x3B, 0x60, 0x07, 0x9B, 0xF6, 0xB2, 0xB3, 0x42, 0x5F, 0xFA, 0x82, 0xF9, 0x7F, 0xF4, 0x68, 0xAF, -+0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0x59, 0x46, 0x50, 0x46, 0xFF, 0xF7, 0xFE, 0xFD, -+0xDD, 0xE9, 0x0C, 0x13, 0x2A, 0x46, 0x01, 0x93, 0x00, 0x91, 0x23, 0x46, 0x3F, 0x49, 0x4F, 0xF4, 0x00, 0x50, 0x1F, 0xF0, -+0xB7, 0xFF, 0x08, 0x9B, 0x83, 0xF8, 0x00, 0x90, 0x09, 0x9B, 0xDD, 0xE9, 0x0C, 0x12, 0x18, 0xEE, 0x10, 0x0A, 0x83, 0xF8, -+0x00, 0x80, 0xFF, 0xF7, 0x1D, 0xFE, 0x11, 0xB0, 0xBD, 0xEC, 0x02, 0x8B, 0xBD, 0xE8, 0xF0, 0x8F, 0x06, 0xB3, 0x01, 0x2E, -+0x29, 0xD0, 0x0D, 0x9B, 0x7B, 0x2D, 0xD4, 0xBF, 0x2A, 0x1D, 0x2A, 0x1F, 0x00, 0x2B, 0xFF, 0xF6, 0x5F, 0xAF, 0x01, 0x2E, -+0x4F, 0xF0, 0x02, 0x08, 0x26, 0xD0, 0x14, 0xF1, 0x7C, 0x0F, 0xFF, 0xF6, 0x5F, 0xAF, 0x23, 0x1F, 0x4F, 0xF0, 0x02, 0x09, -+0x5D, 0xE7, 0x0D, 0x9B, 0x00, 0x2B, 0xA5, 0xF1, 0x20, 0x02, 0x0A, 0xDA, 0x4F, 0xF0, 0x05, 0x08, 0xC1, 0x46, 0x04, 0xF1, -+0x20, 0x03, 0x52, 0xE7, 0x0D, 0x9B, 0x00, 0x2B, 0x05, 0xF1, 0x20, 0x02, 0xF4, 0xDB, 0x4F, 0xF0, 0x05, 0x08, 0xC1, 0x46, -+0xA4, 0xF1, 0x20, 0x03, 0x47, 0xE7, 0x6F, 0x2D, 0xD3, 0xDC, 0x0D, 0x9B, 0x00, 0x2B, 0x05, 0xF1, 0x10, 0x02, 0x4F, 0xF0, -+0x04, 0x08, 0x12, 0xDB, 0x14, 0xF1, 0x70, 0x0F, 0xD5, 0xDB, 0xA4, 0xF1, 0x10, 0x03, 0x4F, 0xF0, 0x04, 0x09, 0x36, 0xE7, -+0x15, 0xF1, 0x70, 0x0F, 0xFF, 0xF6, 0x1F, 0xAF, 0x0D, 0x9B, 0x00, 0x2B, 0xA5, 0xF1, 0x10, 0x02, 0x4F, 0xF0, 0x04, 0x08, -+0xEC, 0xDA, 0x6F, 0x2C, 0x3F, 0xF7, 0x23, 0xAF, 0x04, 0xF1, 0x10, 0x03, 0x4F, 0xF0, 0x04, 0x09, 0x23, 0xE7, 0x07, 0x9C, -+0x4F, 0xF0, 0x80, 0x08, 0x25, 0x46, 0xC1, 0x46, 0x0D, 0xF1, 0x34, 0x0B, 0x0D, 0xF1, 0x30, 0x0A, 0x7E, 0xE7, 0x00, 0xBF, -+0x4C, 0x40, 0x34, 0x40, 0x00, 0x00, 0x80, 0x80, 0x1C, 0x40, 0x34, 0x40, 0x94, 0x7B, 0x15, 0x00, 0xA8, 0x7B, 0x15, 0x00, -+0xCC, 0x7B, 0x15, 0x00, 0xF0, 0x7B, 0x15, 0x00, 0x0C, 0x7C, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x22, 0x4B, 0x23, 0x4E, -+0x1A, 0x68, 0x00, 0x25, 0x22, 0xF4, 0x7F, 0x52, 0x1A, 0x60, 0x98, 0x46, 0x2F, 0x46, 0x4F, 0xF0, 0x07, 0x09, 0x02, 0x20, -+0xFB, 0xF7, 0x86, 0xFE, 0x33, 0x68, 0xD8, 0xF8, 0x00, 0x40, 0xDA, 0x05, 0x54, 0xBF, 0x01, 0x37, 0x07, 0xF1, 0xFF, 0x37, -+0x7F, 0xB2, 0x1B, 0x06, 0x54, 0xBF, 0x01, 0x35, 0x05, 0xF1, 0xFF, 0x35, 0x00, 0x2F, 0x24, 0xF4, 0x7F, 0x54, 0xDC, 0xBF, -+0x7B, 0x42, 0x44, 0xEA, 0x83, 0x24, 0x6D, 0xB2, 0xD4, 0xBF, 0x44, 0xF4, 0x00, 0x54, 0x44, 0xEA, 0x87, 0x24, 0x00, 0x2D, -+0xDC, 0xBF, 0x6B, 0x42, 0x44, 0xEA, 0x83, 0x14, 0x09, 0xF1, 0xFF, 0x33, 0xCC, 0xBF, 0x44, 0xEA, 0x85, 0x14, 0x44, 0xF4, -+0x00, 0x74, 0x13, 0xF0, 0xFF, 0x09, 0xC8, 0xF8, 0x00, 0x40, 0xD0, 0xD1, 0x07, 0x49, 0x2B, 0x46, 0x3A, 0x46, 0x4F, 0xF4, -+0x00, 0x50, 0x1F, 0xF0, 0xF7, 0xFE, 0xC4, 0xF3, 0x87, 0x10, 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0xBF, 0x50, 0x40, 0x34, 0x40, -+0x14, 0x40, 0x34, 0x40, 0x34, 0x7C, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x4E, 0x4A, 0x4F, 0x4D, 0x13, 0x68, 0x87, 0xB0, -+0xC1, 0xF3, 0x03, 0x24, 0x03, 0x93, 0x23, 0xF0, 0x00, 0x43, 0x23, 0xF4, 0xE0, 0x03, 0x43, 0xEA, 0x04, 0x53, 0x43, 0xF0, -+0x0A, 0x03, 0x13, 0x60, 0x2C, 0x68, 0x48, 0x4B, 0x24, 0xF4, 0xC0, 0x54, 0xC1, 0xF3, 0x01, 0x62, 0x22, 0x43, 0x2A, 0x60, -+0x1A, 0x68, 0x01, 0xF0, 0x0F, 0x04, 0xC1, 0xF3, 0x03, 0x15, 0x42, 0xF0, 0x3F, 0x02, 0xA5, 0x42, 0x02, 0x94, 0xC1, 0xF3, -+0x03, 0x3A, 0x1A, 0x60, 0x5E, 0xD8, 0xDF, 0xF8, 0x04, 0x81, 0x3E, 0x4E, 0xDF, 0xF8, 0x00, 0xB1, 0x44, 0x19, 0x99, 0x46, -+0xEF, 0xB2, 0xD8, 0xF8, 0x00, 0x20, 0x22, 0xF4, 0xFF, 0x42, 0x42, 0xEA, 0x45, 0x22, 0x42, 0xF4, 0x40, 0x40, 0x42, 0xF4, -+0xE0, 0x31, 0xC8, 0xF8, 0x00, 0x00, 0x2A, 0x46, 0xC8, 0xF8, 0x00, 0x10, 0x4F, 0xF4, 0x00, 0x50, 0x33, 0x49, 0x1F, 0xF0, -+0xA9, 0xFE, 0x32, 0x68, 0x42, 0xF4, 0x80, 0x62, 0x32, 0x60, 0xDB, 0xF8, 0x00, 0x20, 0x42, 0xF0, 0x40, 0x02, 0xCB, 0xF8, -+0x00, 0x20, 0x32, 0x22, 0x00, 0xBF, 0x01, 0x3A, 0x92, 0xB2, 0x00, 0x2A, 0xFA, 0xD1, 0xFF, 0xF7, 0x5D, 0xFF, 0x04, 0xF8, -+0x01, 0x0B, 0x32, 0x68, 0x22, 0xF4, 0x80, 0x62, 0x32, 0x60, 0xD9, 0xF8, 0x00, 0x20, 0x22, 0xF0, 0x40, 0x02, 0xC9, 0xF8, -+0x00, 0x20, 0x32, 0x22, 0x00, 0xBF, 0x01, 0x3A, 0x92, 0xB2, 0x00, 0x2A, 0xFA, 0xD1, 0x0D, 0xF1, 0x17, 0x03, 0x01, 0x93, -+0x0D, 0xF1, 0x16, 0x03, 0x39, 0x46, 0x00, 0x93, 0x05, 0xAA, 0x0D, 0xF1, 0x15, 0x03, 0x50, 0x46, 0xFF, 0xF7, 0xE8, 0xFD, -+0x01, 0x35, 0x02, 0x9B, 0x9D, 0xF8, 0x16, 0xC0, 0x9D, 0xF8, 0x17, 0x00, 0x9D, 0xF8, 0x14, 0x10, 0x9D, 0xF8, 0x15, 0x20, -+0x84, 0xF8, 0x04, 0xC0, 0xEF, 0xB2, 0xBB, 0x42, 0x60, 0x72, 0xA1, 0x73, 0xE2, 0x74, 0xA8, 0xD2, 0x11, 0x4A, 0x0D, 0x48, -+0x13, 0x68, 0x0D, 0x49, 0x0A, 0x4C, 0x23, 0xF4, 0x7F, 0x43, 0x23, 0xF0, 0x80, 0x03, 0x13, 0x60, 0x43, 0xF4, 0x80, 0x33, -+0x13, 0x60, 0x03, 0x68, 0x23, 0xF4, 0xC0, 0x53, 0x03, 0x60, 0x0B, 0x68, 0x23, 0xF0, 0x3F, 0x03, 0x0B, 0x60, 0x03, 0x9B, -+0x23, 0x60, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1C, 0x05, 0x62, 0x40, 0x04, 0x40, 0x34, 0x40, 0x50, 0x40, 0x34, 0x40, -+0x14, 0x40, 0x34, 0x40, 0x54, 0x7C, 0x15, 0x00, 0x58, 0x40, 0x34, 0x40, 0x5C, 0x40, 0x34, 0x40, 0x2D, 0xE9, 0xF0, 0x4F, -+0x3C, 0x4D, 0x3D, 0x49, 0x81, 0x46, 0x89, 0xB0, 0x4F, 0xF4, 0x00, 0x50, 0x1F, 0xF0, 0x34, 0xFE, 0x2B, 0x68, 0xD9, 0xF8, -+0x00, 0x40, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xE2, 0xB2, 0x04, 0xF0, 0x7F, 0x0A, 0xC4, 0xF3, 0x03, 0x18, 0x04, 0xF0, -+0x0F, 0x04, 0x4A, 0xDB, 0x33, 0x4D, 0x34, 0x4F, 0x2E, 0x68, 0x2B, 0x68, 0x43, 0xF4, 0x80, 0x73, 0x2B, 0x60, 0xD7, 0xF8, -+0x00, 0xB0, 0x3B, 0x68, 0x23, 0xF0, 0x02, 0x03, 0x3B, 0x60, 0x50, 0x46, 0xFF, 0xF7, 0xB2, 0xFC, 0xD9, 0xF8, 0x00, 0x10, -+0x01, 0xA8, 0xFF, 0xF7, 0x25, 0xFF, 0xFF, 0xF7, 0x0D, 0xFD, 0xC7, 0xF8, 0x00, 0xB0, 0x2B, 0x68, 0x2B, 0x68, 0x06, 0xF4, -+0x80, 0x76, 0x1E, 0x43, 0xA0, 0x45, 0x2E, 0x60, 0x26, 0xD8, 0x25, 0x48, 0x0D, 0xF1, 0x05, 0x03, 0xA4, 0xEB, 0x08, 0x04, -+0x43, 0x44, 0x01, 0xAA, 0x42, 0x44, 0x53, 0xFA, 0x84, 0xF4, 0x00, 0xEB, 0x08, 0x10, 0x15, 0x78, 0x53, 0x79, 0x92, 0xF8, -+0x0A, 0xC0, 0xD7, 0x7B, 0x16, 0x7D, 0x29, 0x06, 0x1B, 0x04, 0x01, 0xF0, 0x70, 0x41, 0x43, 0xEA, 0x0C, 0x63, 0x41, 0xEA, -+0x05, 0x51, 0x3B, 0x43, 0x01, 0x32, 0x09, 0x0E, 0x43, 0xEA, 0x06, 0x23, 0xA2, 0x42, 0x80, 0xF8, 0x07, 0x12, 0xC0, 0xF8, -+0x00, 0x32, 0x00, 0xF1, 0x10, 0x00, 0xE4, 0xD1, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x12, 0xF0, 0x0C, 0x0F, 0x08, 0xD1, -+0xA0, 0x45, 0xAF, 0xD9, 0x0E, 0x49, 0x0F, 0x48, 0x41, 0xF2, 0x7F, 0x02, 0x1F, 0xF0, 0xFA, 0xFF, 0xA8, 0xE7, 0x0B, 0x49, -+0x0C, 0x48, 0x41, 0xF2, 0x7E, 0x02, 0x1F, 0xF0, 0xF3, 0xFF, 0x2B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xEB, 0xDB, -+0x9C, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x68, 0x7C, 0x15, 0x00, 0x00, 0x04, 0x60, 0x40, 0x18, 0x00, 0x58, 0x40, -+0x1C, 0x13, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x88, 0x7C, 0x15, 0x00, 0x78, 0x7C, 0x15, 0x00, 0x24, 0x4B, 0x25, 0x4A, -+0x06, 0x21, 0x10, 0xB4, 0xC3, 0xF8, 0x00, 0x11, 0x53, 0x68, 0x23, 0xF4, 0x80, 0x23, 0x53, 0x60, 0x53, 0x68, 0x43, 0xF4, -+0x00, 0x33, 0x53, 0x60, 0x13, 0x6B, 0x03, 0xF0, 0x44, 0x03, 0x04, 0x2B, 0xFA, 0xD1, 0x1D, 0x4B, 0x1D, 0x4C, 0x1B, 0x68, -+0x1D, 0x48, 0x19, 0x49, 0xA4, 0xFB, 0x03, 0x43, 0x9B, 0x0C, 0x43, 0xF0, 0x00, 0x44, 0x44, 0xF4, 0xA0, 0x14, 0x43, 0xF4, -+0xA0, 0x13, 0x03, 0x60, 0x04, 0x60, 0x03, 0x60, 0x53, 0x68, 0x5D, 0xF8, 0x04, 0x4B, 0x43, 0xF4, 0xC4, 0x33, 0x43, 0xF0, -+0x02, 0x03, 0x4F, 0xF4, 0x80, 0x50, 0x53, 0x60, 0xC1, 0xF8, 0x34, 0x01, 0x13, 0x68, 0x43, 0xF0, 0x40, 0x03, 0x13, 0x60, -+0x4B, 0x6F, 0x43, 0xF0, 0x01, 0x03, 0x4B, 0x67, 0x53, 0x6C, 0x43, 0xF0, 0x08, 0x43, 0x53, 0x64, 0x53, 0x6D, 0x23, 0xF4, -+0x00, 0x13, 0x53, 0x65, 0x53, 0x6D, 0x43, 0xF0, 0x02, 0x03, 0x53, 0x65, 0x53, 0x6D, 0x23, 0xF4, 0x00, 0x63, 0x53, 0x65, -+0x70, 0x47, 0x00, 0xBF, 0x00, 0x00, 0x50, 0x40, 0x00, 0x60, 0x50, 0x40, 0x18, 0x13, 0x17, 0x00, 0x83, 0xDE, 0x1B, 0x43, -+0x08, 0x00, 0x58, 0x40, 0x3B, 0x4A, 0x3C, 0x48, 0x13, 0x68, 0x3C, 0x49, 0xDF, 0xF8, 0x24, 0xC1, 0x43, 0xF0, 0x7C, 0x53, -+0xF0, 0xB4, 0x13, 0x60, 0x39, 0x4C, 0x3A, 0x4B, 0x23, 0x60, 0x03, 0xF1, 0xBE, 0x43, 0xA3, 0xF5, 0x69, 0x03, 0xA3, 0xF6, -+0x77, 0x33, 0x03, 0x60, 0x36, 0x4B, 0x0B, 0x60, 0x36, 0x4F, 0x37, 0x4E, 0x37, 0x4D, 0x40, 0xF6, 0x77, 0x13, 0xCC, 0xF8, -+0x00, 0x30, 0x36, 0x4B, 0x3B, 0x60, 0x04, 0xF5, 0x00, 0x24, 0x01, 0xF5, 0x2F, 0x11, 0x00, 0xF5, 0x2F, 0x10, 0x49, 0xF2, -+0x02, 0x43, 0x02, 0xF5, 0x00, 0x22, 0x33, 0x60, 0x0C, 0x34, 0x30, 0x4B, 0x2B, 0x60, 0x01, 0xF5, 0x05, 0x61, 0x00, 0xF6, -+0x58, 0x00, 0x02, 0xF6, 0x7C, 0x02, 0x07, 0xF5, 0x2F, 0x17, 0x2C, 0x4D, 0x25, 0x60, 0x07, 0xF6, 0x68, 0x07, 0x0B, 0x60, -+0x06, 0xF5, 0x37, 0x16, 0x03, 0x60, 0x13, 0x60, 0x40, 0xF6, 0x34, 0x03, 0x3B, 0x60, 0x06, 0xF2, 0xE4, 0x46, 0x26, 0x4B, -+0x33, 0x60, 0x01, 0xF5, 0xFE, 0x31, 0x03, 0xF1, 0x50, 0x53, 0x88, 0x31, 0x03, 0xF5, 0x54, 0x13, 0x0F, 0x33, 0x0B, 0x60, -+0x00, 0xF5, 0xFE, 0x30, 0x03, 0xF1, 0x48, 0x43, 0x1F, 0x4D, 0x00, 0xF5, 0x90, 0x70, 0x02, 0xF5, 0xFE, 0x32, 0xA3, 0xF5, -+0x78, 0x13, 0x02, 0xF5, 0xB4, 0x72, 0xA3, 0xF2, 0x1F, 0x63, 0x4F, 0xF0, 0x36, 0x36, 0x2B, 0x60, 0x06, 0x60, 0x4F, 0xF4, -+0x7F, 0x40, 0x10, 0x60, 0x04, 0xF5, 0x01, 0x34, 0x02, 0xF1, 0xAC, 0x42, 0x20, 0x34, 0x15, 0x4B, 0x15, 0x4D, 0x25, 0x60, -+0xA2, 0xF5, 0xB5, 0x12, 0x45, 0xF2, 0x55, 0x30, 0xA2, 0xF6, 0x8A, 0x62, 0xC1, 0xF8, 0xA8, 0x00, 0xF0, 0xBC, 0x1A, 0x60, -+0x70, 0x47, 0x00, 0xBF, 0x0C, 0x00, 0x58, 0x40, 0x2C, 0x40, 0x34, 0x40, 0x30, 0x40, 0x34, 0x40, 0x04, 0x01, 0x58, 0x40, -+0xFB, 0x23, 0x09, 0x00, 0x08, 0x51, 0x2E, 0x1A, 0x24, 0x40, 0x34, 0x40, 0x28, 0x40, 0x34, 0x40, 0x8C, 0x04, 0x60, 0x40, -+0x94, 0xC5, 0x2E, 0x00, 0x34, 0x08, 0x50, 0x00, 0x58, 0x00, 0x7E, 0x02, 0x13, 0x20, 0x20, 0x20, 0xA0, 0x05, 0x62, 0x40, -+0x1C, 0x05, 0x62, 0x40, 0x0F, 0x12, 0x15, 0x0C, 0x20, 0x40, 0x34, 0x40, 0x63, 0x49, 0x64, 0x4A, 0x0B, 0x68, 0x23, 0xF4, -+0x00, 0x63, 0xF0, 0xB4, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF4, 0x80, 0x73, 0x13, 0x60, 0x32, 0x23, 0x00, 0xBF, 0x01, 0x3B, -+0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0xDF, 0xF8, 0x6C, 0xC1, 0x5B, 0x4A, 0xDC, 0xF8, 0x00, 0x30, 0x5A, 0x4F, 0x5B, 0x4E, -+0x23, 0xF4, 0x80, 0x53, 0xCC, 0xF8, 0x00, 0x30, 0x13, 0x68, 0x23, 0xF4, 0x00, 0x73, 0x13, 0x60, 0xDC, 0xF8, 0x00, 0x30, -+0x43, 0xF4, 0x80, 0x63, 0xCC, 0xF8, 0x00, 0x30, 0xDC, 0xF8, 0x00, 0x30, 0x43, 0xF4, 0x00, 0x63, 0xCC, 0xF8, 0x00, 0x30, -+0x62, 0x46, 0xFF, 0x25, 0x2B, 0x1D, 0x2C, 0x46, 0xDD, 0xB2, 0x29, 0x46, 0x38, 0x46, 0x13, 0x68, 0x23, 0xF0, 0xFF, 0x03, -+0x0B, 0x43, 0x13, 0x60, 0x50, 0xF8, 0x04, 0x3B, 0x33, 0x60, 0x13, 0x68, 0x43, 0xF4, 0x80, 0x73, 0x13, 0x60, 0x00, 0xBF, -+0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x13, 0x68, 0x9B, 0x04, 0xFC, 0xD5, 0x01, 0x39, 0xC9, 0xB2, 0xA1, 0x42, 0xE8, 0xD1, -+0x8F, 0x2D, 0x07, 0xF1, 0x10, 0x07, 0xDF, 0xD1, 0xDC, 0xF8, 0x00, 0x30, 0x23, 0xF4, 0x80, 0x63, 0xCC, 0xF8, 0x00, 0x30, -+0xC8, 0x23, 0x00, 0xBF, 0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0x36, 0x4D, 0x37, 0x49, 0x2A, 0x68, 0x39, 0x48, -+0x39, 0x4C, 0x22, 0xF4, 0x00, 0x62, 0x2A, 0x60, 0x0A, 0x68, 0x42, 0xF0, 0x80, 0x02, 0x0A, 0x60, 0x0A, 0x68, 0x42, 0xF4, -+0x80, 0x72, 0x0A, 0x60, 0x0A, 0x68, 0x22, 0xF0, 0x1F, 0x02, 0x1A, 0x43, 0x0A, 0x60, 0x50, 0xF8, 0x04, 0x2F, 0x22, 0x60, -+0x0A, 0x68, 0x42, 0xF0, 0x20, 0x02, 0x0A, 0x60, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x0A, 0x68, 0x52, 0x05, -+0xFC, 0xD5, 0x01, 0x33, 0x20, 0x2B, 0xE9, 0xD1, 0x0B, 0x68, 0x23, 0xF0, 0x80, 0x03, 0x0B, 0x60, 0xC8, 0x23, 0x00, 0xBF, -+0x01, 0x3B, 0x9B, 0xB2, 0x00, 0x2B, 0xFA, 0xD1, 0x1F, 0x4C, 0x24, 0x48, 0x22, 0x68, 0x24, 0x49, 0x24, 0x4D, 0x22, 0xF4, -+0x80, 0x72, 0x22, 0x60, 0x02, 0x68, 0x22, 0xF0, 0x02, 0x02, 0x02, 0x60, 0x0A, 0x68, 0x22, 0xF0, 0x80, 0x62, 0x0A, 0x60, -+0x32, 0x22, 0x2B, 0x60, 0x00, 0xBF, 0x01, 0x3A, 0x92, 0xB2, 0x00, 0x2A, 0xFA, 0xD1, 0x13, 0x49, 0x13, 0x4A, 0x08, 0x68, -+0x1A, 0x4D, 0x1B, 0x4C, 0x1B, 0x4B, 0x40, 0xF4, 0x80, 0x50, 0x08, 0x60, 0x08, 0x68, 0x40, 0xF4, 0x00, 0x60, 0x08, 0x60, -+0x11, 0x68, 0x41, 0xF4, 0x00, 0x71, 0x11, 0x60, 0x11, 0x68, 0x41, 0xF4, 0x80, 0x71, 0x11, 0x60, 0x2A, 0x68, 0x42, 0xF4, -+0x80, 0x52, 0x2A, 0x60, 0x22, 0x68, 0x22, 0xF4, 0x80, 0x22, 0x22, 0x60, 0x1A, 0x68, 0x22, 0xF0, 0x00, 0x52, 0x1A, 0x60, -+0x1A, 0x68, 0x42, 0xF0, 0x80, 0x42, 0xF0, 0xBC, 0x1A, 0x60, 0x70, 0x47, 0x60, 0x40, 0x34, 0x40, 0x6C, 0x40, 0x34, 0x40, -+0x1C, 0x13, 0x17, 0x00, 0x64, 0x40, 0x34, 0x40, 0x18, 0x18, 0x17, 0x00, 0x70, 0x40, 0x34, 0x40, 0x18, 0x00, 0x58, 0x40, -+0x58, 0x40, 0x34, 0x40, 0x08, 0x40, 0x34, 0x40, 0x14, 0x20, 0x34, 0x40, 0x18, 0x20, 0x34, 0x40, 0x1C, 0x20, 0x34, 0x40, -+0x10, 0xB5, 0x09, 0x4C, 0x82, 0xB0, 0xD4, 0xF8, 0xC0, 0x34, 0x01, 0x90, 0x98, 0x47, 0xD4, 0xF8, 0xC4, 0x34, 0x98, 0x47, -+0xD4, 0xF8, 0xC8, 0x34, 0x98, 0x47, 0xD4, 0xF8, 0xCC, 0x34, 0x00, 0x21, 0x01, 0xA8, 0x98, 0x47, 0x02, 0xB0, 0x10, 0xBD, -+0x88, 0x1A, 0x17, 0x00, 0x10, 0xB5, 0x2D, 0x4C, 0x23, 0x68, 0x1B, 0x78, 0x02, 0x2B, 0x17, 0xD0, 0x0F, 0x24, 0x4F, 0xF4, -+0x00, 0x62, 0x11, 0x46, 0x29, 0x48, 0xFD, 0xF7, 0x61, 0xFA, 0x4F, 0xF4, 0x40, 0x72, 0x28, 0x48, 0x00, 0x21, 0xFD, 0xF7, -+0x5B, 0xFA, 0x21, 0x46, 0x26, 0x48, 0xFD, 0xF7, 0x2F, 0xFA, 0x02, 0x22, 0xBD, 0xE8, 0x10, 0x40, 0x24, 0x48, 0x11, 0x46, -+0xFD, 0xF7, 0x50, 0xBA, 0x04, 0xF0, 0x2E, 0xFD, 0x22, 0x4B, 0x4F, 0xF4, 0x00, 0x42, 0xC3, 0xF8, 0x80, 0x20, 0xBF, 0xF3, -+0x4F, 0x8F, 0xBF, 0xF3, 0x6F, 0x8F, 0x1F, 0x48, 0x1F, 0xF0, 0x52, 0xFB, 0x1E, 0x4A, 0xD2, 0xF8, 0x04, 0x38, 0x43, 0xF0, -+0x02, 0x03, 0xC2, 0xF8, 0x04, 0x38, 0x13, 0x69, 0x43, 0xF0, 0x01, 0x03, 0x13, 0x61, 0x13, 0x69, 0xDB, 0x07, 0xFC, 0xD4, -+0x18, 0x48, 0x1F, 0xF0, 0x41, 0xFB, 0x18, 0x4A, 0x18, 0x48, 0x4F, 0xF4, 0x00, 0x21, 0xFD, 0xF7, 0x2B, 0xFA, 0x17, 0x4B, -+0x4F, 0xF4, 0x80, 0x61, 0x4F, 0xF4, 0x00, 0x02, 0xC3, 0xF8, 0x28, 0x11, 0xC3, 0xF8, 0x18, 0x21, 0x23, 0x68, 0x1B, 0x78, -+0x02, 0x2B, 0xB5, 0xD1, 0x04, 0xF0, 0xB6, 0xFE, 0x00, 0x28, 0xB1, 0xD0, 0x0F, 0x4B, 0x10, 0x48, 0xD3, 0xF8, 0x00, 0x41, -+0x21, 0x46, 0x1F, 0xF0, 0x23, 0xFB, 0xAA, 0xE7, 0x78, 0x36, 0x17, 0x00, 0x0C, 0x88, 0x01, 0x50, 0x14, 0x88, 0x01, 0x50, -+0x00, 0x70, 0x01, 0x50, 0x08, 0x70, 0x01, 0x50, 0x00, 0xE1, 0x00, 0xE0, 0x9C, 0x7C, 0x15, 0x00, 0x00, 0x00, 0x20, 0x40, -+0xA8, 0x7C, 0x15, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x90, 0x01, 0x50, 0x00, 0x00, 0x10, 0x40, 0x2C, 0x19, 0x17, 0x00, -+0xB8, 0x7C, 0x15, 0x00, 0x38, 0xB5, 0x36, 0x4C, 0x36, 0x48, 0x44, 0x22, 0x00, 0x21, 0xFB, 0xF7, 0x91, 0xF8, 0x23, 0x68, -+0x1A, 0x07, 0xC3, 0xF3, 0xC0, 0x01, 0x51, 0xD5, 0x22, 0x46, 0x00, 0xBF, 0x13, 0x68, 0xDB, 0x06, 0xFB, 0xD5, 0x30, 0x4D, -+0x30, 0x48, 0x29, 0x68, 0x30, 0x4B, 0x00, 0x68, 0x30, 0x4A, 0xC1, 0xF8, 0x44, 0x02, 0x00, 0x21, 0x19, 0x60, 0x11, 0x60, -+0x19, 0x68, 0x2E, 0x48, 0x2E, 0x4C, 0x21, 0xF0, 0x03, 0x01, 0x41, 0xF0, 0x02, 0x01, 0x19, 0x60, 0x19, 0x68, 0x21, 0xF0, -+0x0C, 0x01, 0x41, 0xF0, 0x08, 0x01, 0x19, 0x60, 0x19, 0x68, 0x21, 0xF4, 0x40, 0x71, 0x41, 0xF4, 0x00, 0x71, 0x19, 0x60, -+0x19, 0x68, 0x21, 0xF4, 0x40, 0x61, 0x41, 0xF4, 0x00, 0x61, 0x19, 0x60, 0x19, 0x68, 0x21, 0xF4, 0x40, 0x51, 0x41, 0xF4, -+0x00, 0x51, 0x19, 0x60, 0x11, 0x68, 0x21, 0xF0, 0x40, 0x51, 0x41, 0xF0, 0x00, 0x51, 0x11, 0x60, 0x11, 0x68, 0x21, 0xF0, -+0x40, 0x41, 0x41, 0xF0, 0x00, 0x41, 0x11, 0x60, 0x1A, 0x68, 0x42, 0xF4, 0x40, 0x32, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF4, -+0x40, 0x22, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF4, 0x40, 0x12, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF4, 0x40, 0x02, 0x1A, 0x60, -+0x1A, 0x68, 0x42, 0xF0, 0x40, 0x72, 0x1A, 0x60, 0x04, 0x60, 0x38, 0xBD, 0x23, 0x68, 0x09, 0x4D, 0x43, 0xF0, 0x08, 0x03, -+0x23, 0x60, 0x28, 0x68, 0x4F, 0xF4, 0x12, 0x72, 0xFB, 0xF7, 0x30, 0xF8, 0x23, 0x68, 0x43, 0xF0, 0x10, 0x03, 0x23, 0x60, -+0xA4, 0xE7, 0x00, 0xBF, 0x80, 0x40, 0x04, 0x40, 0x04, 0x35, 0x17, 0x00, 0x00, 0x38, 0x18, 0x00, 0x84, 0x1A, 0x17, 0x00, -+0x14, 0x41, 0x04, 0x40, 0x18, 0x41, 0x04, 0x40, 0x0C, 0x41, 0x04, 0x40, 0x33, 0x1F, 0x00, 0xC0, 0x0C, 0x4B, 0x10, 0xB5, -+0x1C, 0x68, 0x14, 0xF4, 0xF8, 0x54, 0x00, 0xD1, 0x10, 0xBD, 0x60, 0x08, 0x1E, 0xF0, 0x02, 0xF8, 0x08, 0x4A, 0x09, 0x49, -+0x09, 0x4B, 0x0C, 0x60, 0x14, 0x60, 0x1A, 0x78, 0x00, 0x2A, 0xF3, 0xD0, 0x07, 0x4A, 0x01, 0x21, 0x59, 0x70, 0x13, 0x68, -+0x0B, 0x43, 0x13, 0x60, 0x10, 0xBD, 0x00, 0xBF, 0x1C, 0x41, 0x04, 0x40, 0x08, 0x41, 0x04, 0x40, 0x10, 0x41, 0x04, 0x40, -+0x3C, 0x36, 0x17, 0x00, 0x10, 0x00, 0x58, 0x40, 0x2D, 0xE9, 0xF8, 0x4F, 0x29, 0x4B, 0x06, 0x46, 0x53, 0xF8, 0x20, 0x00, -+0x1E, 0xF0, 0x04, 0xF8, 0x27, 0x4A, 0x13, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x26, 0x4B, 0xD3, 0xF8, 0x00, 0xA0, 0xDA, 0xF8, -+0x3C, 0x32, 0x0A, 0xF5, 0x0F, 0x7B, 0x8B, 0xB3, 0x23, 0x4D, 0xDF, 0xF8, 0x98, 0x90, 0xDF, 0xF8, 0x98, 0x80, 0x05, 0xF2, -+0x14, 0x57, 0x1D, 0xE0, 0x95, 0xF8, 0x10, 0x35, 0x85, 0xF8, 0x11, 0x45, 0x01, 0x33, 0xA9, 0xFB, 0x03, 0x24, 0xA4, 0x09, -+0x04, 0xEB, 0xC4, 0x04, 0x04, 0xEB, 0xC4, 0x04, 0x1C, 0x1B, 0x85, 0xF8, 0x10, 0x45, 0x1E, 0xF0, 0xA1, 0xF8, 0xD8, 0xF8, -+0x00, 0x20, 0x05, 0xEB, 0x04, 0x11, 0x02, 0x44, 0xC1, 0xE9, 0x01, 0x26, 0x38, 0x46, 0x1E, 0xF0, 0x53, 0xF8, 0xDA, 0xF8, -+0x3C, 0x32, 0x5B, 0xB1, 0x95, 0xF8, 0x11, 0x15, 0x95, 0xF8, 0x12, 0x25, 0x91, 0x42, 0x58, 0x46, 0x01, 0xF1, 0x01, 0x04, -+0xD8, 0xD3, 0x0D, 0x48, 0x01, 0xF0, 0x54, 0xF8, 0x08, 0x4B, 0x01, 0x24, 0x1C, 0x60, 0x20, 0x20, 0x08, 0x36, 0x1D, 0xF0, -+0x9B, 0xFF, 0x04, 0xFA, 0x06, 0xF6, 0x08, 0x4B, 0x06, 0xF4, 0xF8, 0x56, 0x1E, 0x60, 0xBD, 0xE8, 0xF8, 0x8F, 0x00, 0xBF, -+0x80, 0x7E, 0x15, 0x00, 0x4C, 0x40, 0x04, 0x40, 0x00, 0x38, 0x18, 0x00, 0x58, 0x58, 0x17, 0x00, 0xCC, 0x7C, 0x15, 0x00, -+0x0C, 0x41, 0x04, 0x40, 0xE7, 0x87, 0x45, 0xCA, 0x84, 0x1A, 0x17, 0x00, 0x1D, 0x4B, 0x10, 0xB5, 0x1C, 0x68, 0xA0, 0x06, -+0x2C, 0xD4, 0xE1, 0x06, 0x20, 0xD4, 0xA2, 0x07, 0x16, 0xD4, 0x63, 0x00, 0x08, 0xD5, 0x19, 0x4B, 0x01, 0x20, 0xD3, 0xF8, -+0x78, 0x34, 0x98, 0x47, 0x17, 0x4B, 0x4F, 0xF0, 0x80, 0x42, 0x1A, 0x60, 0x00, 0x2C, 0x00, 0xDB, 0x10, 0xBD, 0x13, 0x4B, -+0xD3, 0xF8, 0x68, 0x34, 0x98, 0x47, 0x12, 0x4B, 0x4F, 0xF0, 0x00, 0x42, 0x1A, 0x60, 0x10, 0xBD, 0x4F, 0xF0, 0x80, 0x50, -+0x1D, 0xF0, 0x5E, 0xFF, 0x0E, 0x4B, 0x02, 0x22, 0x1A, 0x60, 0xE0, 0xE7, 0x0C, 0x49, 0x0B, 0x4A, 0x10, 0x23, 0x0B, 0x60, -+0x4F, 0xF4, 0x00, 0x10, 0x13, 0x60, 0x1D, 0xF0, 0x51, 0xFF, 0xD4, 0xE7, 0x07, 0x49, 0x06, 0x4A, 0x20, 0x23, 0x0B, 0x60, -+0x4F, 0xF4, 0x80, 0x10, 0x13, 0x60, 0x1D, 0xF0, 0x47, 0xFF, 0xC8, 0xE7, 0x1C, 0x41, 0x04, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0x08, 0x41, 0x04, 0x40, 0x10, 0x41, 0x04, 0x40, 0x06, 0x4A, 0x07, 0x49, 0x12, 0x68, 0xD2, 0xF8, 0x24, 0x02, 0x20, 0x23, -+0x0B, 0x60, 0x08, 0xB1, 0x01, 0x20, 0x70, 0x47, 0x03, 0x4A, 0x13, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x38, 0x18, 0x00, -+0x08, 0x41, 0x04, 0x40, 0x0C, 0x41, 0x04, 0x40, 0x10, 0xB5, 0x15, 0x4C, 0x23, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x14, 0x4B, -+0x18, 0x68, 0xD0, 0xF8, 0x24, 0x32, 0xBB, 0xB1, 0x00, 0xF5, 0x09, 0x70, 0x1E, 0xF0, 0x02, 0xF8, 0x10, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x01, 0x22, 0x00, 0x2B, 0x22, 0x60, 0x01, 0xDB, 0x14, 0x30, 0x10, 0xBD, 0x00, 0x28, 0xFB, 0xD1, -+0x0B, 0x49, 0x0C, 0x48, 0x40, 0xF2, 0x92, 0x32, 0x1F, 0xF0, 0x00, 0xFC, 0x14, 0x20, 0x10, 0xBD, 0x06, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x01, 0x22, 0x00, 0x2B, 0x22, 0x60, 0xF5, 0xDA, 0xEE, 0xE7, 0x00, 0xBF, 0x54, 0x40, 0x04, 0x40, -+0x00, 0x38, 0x18, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xE4, 0x7C, 0x15, 0x00, 0x10, 0xB5, 0x0A, 0x4C, -+0x23, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x09, 0x4B, 0x1B, 0x68, 0xD3, 0xF8, 0x14, 0x02, 0x40, 0xB1, 0x03, 0xF5, 0x05, 0x70, -+0x1D, 0xF0, 0xCC, 0xFF, 0x01, 0x23, 0x23, 0x60, 0x00, 0xB1, 0x04, 0x30, 0x10, 0xBD, 0x01, 0x23, 0x23, 0x60, 0x10, 0xBD, -+0x58, 0x40, 0x04, 0x40, 0x00, 0x38, 0x18, 0x00, 0x70, 0x47, 0x00, 0xBF, 0x01, 0x4B, 0x08, 0x22, 0x1A, 0x60, 0x70, 0x47, -+0x00, 0x41, 0x04, 0x40, 0x02, 0x4B, 0x4F, 0xF4, 0x80, 0x72, 0x1A, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x41, 0x04, 0x40, -+0x01, 0x4B, 0x80, 0x22, 0x1A, 0x60, 0x70, 0x47, 0x00, 0x41, 0x04, 0x40, 0xF8, 0xB5, 0x04, 0x46, 0x40, 0x89, 0x29, 0x4F, -+0x10, 0x30, 0x1D, 0xF0, 0xA3, 0xFB, 0x3E, 0x68, 0xB6, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x05, 0x46, 0x22, 0xDB, 0xA3, 0x88, -+0x62, 0x89, 0xE0, 0x88, 0xAB, 0x80, 0x00, 0x21, 0x0C, 0x23, 0x2B, 0x81, 0x6A, 0x81, 0xE8, 0x80, 0x29, 0x60, 0xE3, 0x18, -+0x62, 0xB1, 0x01, 0x3A, 0x22, 0xF0, 0x03, 0x02, 0x10, 0x32, 0x14, 0x44, 0x05, 0xF1, 0x08, 0x02, 0x53, 0xF8, 0x04, 0x1B, -+0x42, 0xF8, 0x04, 0x1F, 0xA3, 0x42, 0xF9, 0xD1, 0xB6, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x0F, 0xDB, 0x05, 0xF1, 0x0C, 0x00, -+0xBD, 0xE8, 0xF8, 0x40, 0x1D, 0xF0, 0xD8, 0xBA, 0x00, 0x28, 0xDA, 0xD1, 0x12, 0x49, 0x13, 0x48, 0x40, 0xF2, 0x6F, 0x42, -+0x1F, 0xF0, 0x82, 0xFB, 0x3E, 0x68, 0xD2, 0xE7, 0x0D, 0x28, 0x0D, 0xD8, 0x0B, 0x28, 0xEB, 0xD9, 0x0C, 0x49, 0x0E, 0x48, -+0x4F, 0xF4, 0x90, 0x62, 0x1F, 0xF0, 0x76, 0xFB, 0x05, 0xF1, 0x0C, 0x00, 0xBD, 0xE8, 0xF8, 0x40, 0x1D, 0xF0, 0xBE, 0xBA, -+0x06, 0x49, 0x09, 0x48, 0xBB, 0x22, 0x1F, 0xF0, 0x6B, 0xFB, 0x04, 0x49, 0x05, 0x48, 0x4F, 0xF4, 0x90, 0x62, 0x1F, 0xF0, -+0x65, 0xFB, 0xED, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xFC, 0x7C, 0x15, 0x00, 0x20, 0x7D, 0x15, 0x00, -+0x10, 0x7D, 0x15, 0x00, 0xF8, 0xB5, 0x05, 0x46, 0x40, 0x89, 0x2B, 0x4F, 0x10, 0x30, 0x1D, 0xF0, 0x43, 0xFB, 0x3E, 0x68, -+0xB6, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0x46, 0x2A, 0xDB, 0xAB, 0x88, 0x6A, 0x89, 0xEF, 0x88, 0xA3, 0x80, 0x00, 0x21, -+0x0C, 0x23, 0x23, 0x81, 0x62, 0x81, 0xE7, 0x80, 0x21, 0x60, 0xEB, 0x18, 0x62, 0xB1, 0x01, 0x3A, 0x22, 0xF0, 0x03, 0x02, -+0x10, 0x32, 0x2A, 0x44, 0x04, 0xF1, 0x08, 0x01, 0x53, 0xF8, 0x04, 0x0B, 0x41, 0xF8, 0x04, 0x0F, 0x93, 0x42, 0xF9, 0xD1, -+0x1A, 0x4A, 0x53, 0x7D, 0x59, 0x1C, 0x51, 0x75, 0x2B, 0x81, 0xB6, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x12, 0xDB, 0x17, 0x4B, -+0x04, 0x22, 0x04, 0xF1, 0x0C, 0x00, 0x1A, 0x60, 0xBD, 0xE8, 0xF8, 0x40, 0x1D, 0xF0, 0x70, 0xBA, 0x00, 0x28, 0xD2, 0xD1, -+0x12, 0x49, 0x13, 0x48, 0x40, 0xF2, 0x8E, 0x42, 0x1F, 0xF0, 0x1A, 0xFB, 0x3E, 0x68, 0xCA, 0xE7, 0x0D, 0x2F, 0x08, 0xD8, -+0x0B, 0x2F, 0xE8, 0xD9, 0x0C, 0x49, 0x0E, 0x48, 0x40, 0xF2, 0xA3, 0x42, 0x1F, 0xF0, 0x0E, 0xFB, 0xE1, 0xE7, 0x09, 0x49, -+0x0B, 0x48, 0xBB, 0x22, 0x1F, 0xF0, 0x08, 0xFB, 0x06, 0x49, 0x08, 0x48, 0x40, 0xF2, 0xA3, 0x42, 0x1F, 0xF0, 0x02, 0xFB, -+0xD5, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x04, 0x35, 0x17, 0x00, 0x00, 0x41, 0x04, 0x40, 0x70, 0x79, 0x15, 0x00, -+0xFC, 0x7C, 0x15, 0x00, 0x20, 0x7D, 0x15, 0x00, 0x10, 0x7D, 0x15, 0x00, 0xF8, 0xB5, 0x0B, 0x4C, 0x23, 0x68, 0x9A, 0x07, -+0x0A, 0xD5, 0x0A, 0x4F, 0x0A, 0x4E, 0x02, 0x25, 0x38, 0x68, 0x35, 0x60, 0x04, 0x30, 0xFF, 0xF7, 0x8B, 0xFF, 0x23, 0x68, -+0x9B, 0x07, 0xF7, 0xD4, 0x4F, 0xF0, 0x80, 0x50, 0x1D, 0xF0, 0x0C, 0xFE, 0x04, 0x4B, 0x02, 0x22, 0x1A, 0x60, 0xF8, 0xBD, -+0x04, 0x41, 0x04, 0x40, 0x00, 0x38, 0x18, 0x00, 0x08, 0x41, 0x04, 0x40, 0x0C, 0x41, 0x04, 0x40, 0x2D, 0xE9, 0xF0, 0x47, -+0xDF, 0xF8, 0x20, 0x93, 0xD9, 0xF8, 0x00, 0x20, 0x13, 0x78, 0x03, 0x2B, 0x82, 0xB0, 0x04, 0x46, 0x00, 0xF0, 0x16, 0x81, -+0x00, 0x27, 0x3E, 0x46, 0x01, 0x2B, 0x00, 0xF0, 0xC2, 0x80, 0x02, 0x2B, 0x4F, 0xF0, 0x00, 0x05, 0x00, 0xF0, 0xD3, 0x80, -+0x62, 0x89, 0xA3, 0x88, 0x33, 0x80, 0xF2, 0x80, 0x7A, 0xB9, 0xD9, 0xF8, 0x00, 0x30, 0x1B, 0x78, 0x03, 0x2B, 0x1C, 0xD0, -+0x02, 0x2B, 0x2F, 0xD0, 0x01, 0x2B, 0x00, 0xF0, 0x89, 0x80, 0x20, 0x46, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x47, 0x1D, 0xF0, -+0x41, 0xBA, 0xA3, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0x20, 0x81, 0x06, 0xF1, 0x0C, 0x00, -+0x04, 0xF1, 0x0C, 0x01, 0x31, 0xF0, 0x40, 0xFD, 0xD9, 0xF8, 0x00, 0x30, 0x1B, 0x78, 0x03, 0x2B, 0xE2, 0xD1, 0x9B, 0x4E, -+0x33, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x9A, 0x4B, 0x18, 0x68, 0x39, 0x1F, 0x00, 0xF5, 0x03, 0x70, 0x1D, 0xF0, 0x36, 0xFE, -+0x97, 0x4B, 0x01, 0x21, 0x02, 0x22, 0x31, 0x60, 0x1A, 0x60, 0xD9, 0xF8, 0x00, 0x30, 0x1B, 0x78, 0x02, 0x2B, 0xCF, 0xD1, -+0x60, 0x89, 0x10, 0xF0, 0x03, 0x03, 0x40, 0xF0, 0xE9, 0x80, 0x19, 0x46, 0x9C, 0x46, 0x90, 0x4E, 0x42, 0xF2, 0x34, 0x03, -+0xF2, 0x5A, 0xB2, 0xF5, 0xC3, 0x7F, 0x00, 0xF2, 0xFD, 0x80, 0x57, 0x1C, 0xBF, 0xB2, 0x4F, 0xEA, 0xC2, 0x0E, 0x8B, 0x4B, -+0xA8, 0xF8, 0x0C, 0x20, 0xD3, 0xF8, 0x00, 0xA0, 0x00, 0xF1, 0x10, 0x03, 0x0A, 0xEB, 0x0E, 0x00, 0x0C, 0xEB, 0x03, 0x02, -+0x45, 0x60, 0x2A, 0xF8, 0x0E, 0x20, 0xC2, 0x78, 0x02, 0xF0, 0x31, 0x02, 0x42, 0xF0, 0x04, 0x02, 0xC2, 0x70, 0x96, 0xF8, -+0x02, 0x2C, 0x42, 0xF2, 0x34, 0x0C, 0x0B, 0x44, 0x01, 0x32, 0x01, 0x21, 0x4F, 0xF0, 0x00, 0x0E, 0x26, 0xF8, 0x0C, 0x70, -+0x86, 0xF8, 0x02, 0x2C, 0xC8, 0xE9, 0x01, 0x03, 0x88, 0xF8, 0x0E, 0x10, 0xC8, 0xF8, 0x00, 0xE0, 0xEF, 0xF3, 0x10, 0x83, -+0xDB, 0x07, 0x02, 0xD4, 0x72, 0xB6, 0x76, 0x4B, 0x19, 0x60, 0x76, 0x4E, 0x76, 0x48, 0x33, 0x68, 0x41, 0x46, 0x01, 0x33, -+0x33, 0x60, 0x1D, 0xF0, 0xE3, 0xFD, 0x74, 0x4B, 0xD3, 0xF8, 0x44, 0x34, 0x98, 0x47, 0x33, 0x68, 0x33, 0xB1, 0x6E, 0x4A, -+0x01, 0x3B, 0x12, 0x68, 0x33, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xD9, 0xF8, 0x00, 0x30, 0x1B, 0x78, 0x01, 0x2B, -+0x7F, 0xF4, 0x77, 0xAF, 0x01, 0xF0, 0xF2, 0xFF, 0x00, 0x28, 0x00, 0xF0, 0x0C, 0x81, 0xA1, 0x7A, 0x68, 0x4A, 0x0C, 0x31, -+0x29, 0x70, 0x61, 0x89, 0x0C, 0x31, 0x00, 0x27, 0x09, 0x12, 0x11, 0x26, 0x69, 0x70, 0xAE, 0x70, 0xEF, 0x70, 0x61, 0x89, -+0x86, 0x68, 0x47, 0x60, 0x10, 0x31, 0xC1, 0xF3, 0x0B, 0x01, 0x32, 0x40, 0x0A, 0x43, 0x42, 0xF0, 0x00, 0x42, 0x05, 0x60, -+0x82, 0x60, 0x03, 0xF0, 0x35, 0xF8, 0x20, 0x46, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x47, 0x1D, 0xF0, 0x99, 0xB9, 0x63, 0x89, -+0x6C, 0x2B, 0x40, 0xF2, 0x8C, 0x80, 0x58, 0x4B, 0x1B, 0x68, 0xD3, 0xE9, 0x01, 0x02, 0x13, 0x69, 0x98, 0x47, 0x05, 0x46, -+0x00, 0x2D, 0x00, 0xF0, 0x8A, 0x80, 0xD9, 0xF8, 0x00, 0x30, 0x1B, 0x78, 0x02, 0x2B, 0x05, 0xF1, 0x04, 0x06, 0x7F, 0xF4, -+0x2D, 0xAF, 0x63, 0x89, 0x6C, 0x2B, 0x7A, 0xD9, 0x4D, 0x4B, 0x1B, 0x68, 0xD3, 0xE9, 0x01, 0x02, 0x13, 0x69, 0x98, 0x47, -+0x05, 0x46, 0x00, 0x2D, 0x75, 0xD0, 0x42, 0x4A, 0x42, 0xF2, 0x24, 0x03, 0xD3, 0x58, 0x00, 0x2B, 0x00, 0xF0, 0x9A, 0x80, -+0xEF, 0xF3, 0x10, 0x83, 0xD9, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x3E, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x3D, 0x4E, 0x42, 0x48, -+0x33, 0x68, 0x01, 0x33, 0x33, 0x60, 0x1D, 0xF0, 0xB7, 0xFD, 0x33, 0x68, 0x80, 0x46, 0x33, 0xB1, 0x37, 0x4A, 0x01, 0x3B, -+0x12, 0x68, 0x33, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xA3, 0x7A, 0x0C, 0x33, 0x2B, 0x70, 0x63, 0x89, 0x0C, 0x33, -+0x1B, 0x12, 0x11, 0x22, 0x6B, 0x70, 0x00, 0x23, 0xAA, 0x70, 0xEB, 0x70, 0x2E, 0x1D, 0xF3, 0xE6, 0x28, 0x4D, 0x2B, 0x68, -+0x00, 0x2B, 0xFC, 0xD0, 0x27, 0x4B, 0x18, 0x68, 0xD0, 0xF8, 0x04, 0x32, 0xD3, 0xB1, 0x00, 0xF5, 0x01, 0x70, 0x1D, 0xF0, -+0x93, 0xFD, 0x21, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x01, 0x22, 0x00, 0x2B, 0x2A, 0x60, 0xC0, 0xF2, 0x8B, 0x80, -+0x07, 0x1D, 0xD9, 0xF8, 0x00, 0x20, 0x3E, 0x46, 0x27, 0x4B, 0xB3, 0x60, 0x13, 0x78, 0xCD, 0xE6, 0xC3, 0xF1, 0x04, 0x03, -+0x5F, 0xFA, 0x83, 0xFC, 0x61, 0x46, 0x12, 0xE7, 0x15, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x01, 0x21, 0x00, 0x2B, -+0x29, 0x60, 0xC0, 0xF2, 0x82, 0x80, 0x04, 0x26, 0x37, 0x46, 0xE9, 0xE7, 0xB2, 0xF5, 0x80, 0x6F, 0x7F, 0xF6, 0xDC, 0xAE, -+0x4F, 0xF4, 0xB1, 0x62, 0x1A, 0x49, 0x1B, 0x48, 0x1F, 0xF0, 0x76, 0xF9, 0x62, 0x89, 0xD3, 0xE6, 0x4F, 0xF0, 0x00, 0x0E, -+0x72, 0x46, 0x01, 0x27, 0x01, 0xE7, 0x01, 0xF0, 0xCF, 0xFF, 0x05, 0x46, 0x76, 0xE7, 0x05, 0xF0, 0x2B, 0xF8, 0x05, 0x46, -+0x87, 0xE7, 0xE3, 0x88, 0x22, 0x89, 0xA1, 0x88, 0x11, 0x48, 0x00, 0xF0, 0x1D, 0xFD, 0xB2, 0xE6, 0x38, 0x36, 0x17, 0x00, -+0x50, 0x40, 0x04, 0x40, 0x00, 0x38, 0x18, 0x00, 0x00, 0x41, 0x04, 0x40, 0x7C, 0x36, 0x17, 0x00, 0x54, 0x60, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xA8, 0x56, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x00, 0xF0, 0xFF, 0x7F, -+0x1C, 0x58, 0x17, 0x00, 0xA0, 0x56, 0x17, 0x00, 0x2A, 0xDE, 0xDE, 0xAD, 0x70, 0x79, 0x15, 0x00, 0xDC, 0x7D, 0x15, 0x00, -+0x68, 0x7D, 0x15, 0x00, 0x78, 0x36, 0x17, 0x00, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x20, 0x4B, -+0x01, 0x22, 0x1A, 0x60, 0x1F, 0x4D, 0x20, 0x4A, 0x2B, 0x68, 0xD2, 0xF8, 0x44, 0x24, 0x01, 0x33, 0x2B, 0x60, 0x90, 0x47, -+0x2A, 0x68, 0x03, 0x46, 0x32, 0xB1, 0x19, 0x49, 0x01, 0x3A, 0x09, 0x68, 0x2A, 0x60, 0x0A, 0xB9, 0x01, 0xB1, 0x62, 0xB6, -+0x18, 0x48, 0x01, 0x93, 0x1D, 0xF0, 0x4E, 0xFD, 0x00, 0x90, 0x17, 0x48, 0x1D, 0xF0, 0x4A, 0xFD, 0xDD, 0xE9, 0x00, 0x13, -+0x02, 0x46, 0x15, 0x48, 0x00, 0xF0, 0xD0, 0xFC, 0x65, 0xE6, 0x14, 0x48, 0x00, 0xF0, 0xCC, 0xFC, 0x61, 0xE6, 0x60, 0xB1, -+0x07, 0x1D, 0x7F, 0xF4, 0x72, 0xAF, 0x40, 0xF2, 0x31, 0x52, 0x10, 0x49, 0x10, 0x48, 0x1F, 0xF0, 0x05, 0xF9, 0x3E, 0x46, -+0xD9, 0xF8, 0x00, 0x20, 0x6A, 0xE7, 0x40, 0xF2, 0x26, 0x32, 0x0B, 0x49, 0x0C, 0x48, 0x04, 0x26, 0x1F, 0xF0, 0xFA, 0xF8, -+0x37, 0x46, 0xD9, 0xF8, 0x00, 0x20, 0x5F, 0xE7, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xA0, 0x56, 0x17, 0x00, 0xA8, 0x56, 0x17, 0x00, 0xA4, 0x7D, 0x15, 0x00, 0x08, 0x7E, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x54, 0x7D, 0x15, 0x00, 0x44, 0x7D, 0x15, 0x00, 0x10, 0xB4, 0x15, 0x49, 0x15, 0x4C, 0x16, 0x4B, 0x4F, 0xF4, 0x4C, 0x02, -+0x22, 0x60, 0x0A, 0x60, 0x1A, 0x68, 0x22, 0xF0, 0x30, 0x02, 0x1A, 0x60, 0x1A, 0x68, 0x22, 0xF0, 0xC0, 0x02, 0x1A, 0x60, -+0x1A, 0x68, 0x22, 0xF4, 0x40, 0x52, 0x1A, 0x60, 0x1A, 0x68, 0x4F, 0xF0, 0x60, 0x50, 0x22, 0xF4, 0x40, 0x42, 0x1A, 0x60, -+0x20, 0x60, 0x08, 0x60, 0x1A, 0x68, 0x5D, 0xF8, 0x04, 0x4B, 0x22, 0xF4, 0x40, 0x02, 0x1A, 0x60, 0x1A, 0x68, 0x22, 0xF0, -+0x40, 0x72, 0x1A, 0x60, 0x1A, 0x68, 0x22, 0xF0, 0x40, 0x62, 0x1A, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x0C, 0x40, 0x04, 0x40, -+0x08, 0x40, 0x04, 0x40, 0x18, 0x40, 0x04, 0x40, 0x10, 0xB5, 0x01, 0x46, 0x04, 0x46, 0x05, 0x48, 0x1E, 0xF0, 0x30, 0xFE, -+0x04, 0x4A, 0x05, 0x4B, 0x14, 0x60, 0x4F, 0xF0, 0x80, 0x72, 0x1A, 0x60, 0x10, 0xBD, 0x00, 0xBF, 0x2C, 0x7E, 0x15, 0x00, -+0x98, 0x40, 0x04, 0x40, 0x00, 0x40, 0x04, 0x40, 0x02, 0x4B, 0x4F, 0xF0, 0x00, 0x72, 0x1A, 0x60, 0x70, 0x47, 0x00, 0xBF, -+0x00, 0x40, 0x04, 0x40, 0x02, 0x4B, 0x4F, 0xF0, 0x80, 0x62, 0x1A, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x40, 0x04, 0x40, -+0x08, 0xB5, 0x25, 0x4B, 0x19, 0x68, 0x4A, 0x03, 0x04, 0xD5, 0x4F, 0xF4, 0x80, 0x22, 0x43, 0xF8, 0x14, 0x2C, 0x08, 0xBD, -+0x08, 0x03, 0x04, 0xD5, 0x20, 0x4B, 0x4F, 0xF4, 0x00, 0x22, 0x1A, 0x60, 0x08, 0xBD, 0x4A, 0x02, 0x0F, 0xD4, 0x0B, 0x02, -+0x1D, 0xD4, 0x08, 0x01, 0x10, 0xD5, 0x1C, 0x4B, 0x1A, 0x4A, 0xDB, 0x7D, 0x4F, 0xF0, 0x00, 0x61, 0x01, 0x2B, 0x11, 0x60, -+0xE9, 0xD1, 0xBD, 0xE8, 0x08, 0x40, 0x23, 0xF0, 0xED, 0xBE, 0x15, 0x4B, 0x4F, 0xF4, 0x80, 0x02, 0x1A, 0x60, 0x08, 0xBD, -+0x11, 0xF0, 0x80, 0x53, 0x16, 0xD0, 0x12, 0x49, 0x10, 0x4B, 0x01, 0x20, 0x4F, 0xF0, 0x80, 0x52, 0x48, 0x75, 0x1A, 0x60, -+0x08, 0xBD, 0x0D, 0x4B, 0x0E, 0x48, 0x4F, 0xF4, 0x00, 0x02, 0x1A, 0x60, 0x00, 0xF0, 0x0E, 0xFC, 0x03, 0x20, 0x00, 0xF0, -+0x93, 0xFC, 0x0B, 0x4B, 0x4F, 0xF4, 0x80, 0x02, 0x1A, 0x60, 0x08, 0xBD, 0x8A, 0x00, 0xC4, 0xD5, 0x05, 0x49, 0x04, 0x4A, -+0x4B, 0x75, 0x4F, 0xF0, 0x00, 0x53, 0x13, 0x60, 0x08, 0xBD, 0x00, 0xBF, 0x1C, 0x40, 0x04, 0x40, 0x08, 0x40, 0x04, 0x40, -+0x4C, 0x36, 0x17, 0x00, 0x40, 0x7E, 0x15, 0x00, 0x00, 0x40, 0x04, 0x40, 0x15, 0x4B, 0xD3, 0xF8, 0x24, 0x31, 0x59, 0x06, -+0x09, 0xD5, 0x10, 0xB5, 0x13, 0x4C, 0x23, 0x68, 0x1A, 0x07, 0x88, 0xB0, 0xC3, 0xF3, 0xC0, 0x00, 0x03, 0xD4, 0x08, 0xB0, -+0x10, 0xBD, 0x01, 0x20, 0x70, 0x47, 0x0F, 0x49, 0x20, 0x22, 0x68, 0x46, 0x31, 0xF0, 0xC6, 0xFA, 0x0D, 0x4B, 0x1B, 0x68, -+0x23, 0x68, 0xC3, 0xF3, 0x40, 0x00, 0x9B, 0x07, 0xEF, 0xD5, 0x0B, 0x4B, 0x0B, 0x4A, 0x4F, 0xF4, 0x00, 0x11, 0x19, 0x60, -+0x10, 0x68, 0x10, 0xF4, 0x40, 0x13, 0xFB, 0xD0, 0x08, 0x4A, 0xC0, 0xF3, 0x00, 0x50, 0x13, 0x60, 0xE1, 0xE7, 0x00, 0xBF, -+0x00, 0x00, 0x50, 0x40, 0x84, 0x40, 0x04, 0x40, 0x30, 0x95, 0x16, 0x00, 0x30, 0x60, 0x50, 0x40, 0x00, 0x40, 0x04, 0x40, -+0x04, 0x40, 0x04, 0x40, 0x08, 0x40, 0x04, 0x40, 0x01, 0x28, 0x06, 0xD0, 0x02, 0x28, 0x09, 0xD1, 0x0B, 0x4B, 0x4F, 0xF4, -+0x00, 0x22, 0x1A, 0x60, 0x70, 0x47, 0x09, 0x4B, 0x4F, 0xF4, 0x80, 0x22, 0x1A, 0x60, 0x70, 0x47, 0x07, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x00, 0xDB, 0x70, 0x47, 0x05, 0x49, 0x05, 0x48, 0x40, 0xF2, 0x52, 0x72, 0x1E, 0xF0, -+0xE1, 0xBF, 0x00, 0xBF, 0x00, 0x40, 0x04, 0x40, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, -+0x38, 0xB5, 0x22, 0x48, 0xFC, 0xF7, 0xFA, 0xFB, 0x83, 0x07, 0x23, 0xD5, 0x20, 0x48, 0x00, 0xF0, 0x8B, 0xFB, 0x20, 0x48, -+0xFC, 0xF7, 0xF2, 0xFB, 0x04, 0x46, 0x1F, 0x48, 0xFC, 0xF7, 0xEE, 0xFB, 0x03, 0x46, 0x1D, 0x48, 0x1C, 0x40, 0xFC, 0xF7, -+0xE9, 0xFB, 0x84, 0x42, 0x1F, 0xD0, 0x05, 0x20, 0x00, 0xF0, 0x14, 0xFC, 0x01, 0x28, 0x04, 0x46, 0x17, 0xD0, 0x03, 0x20, -+0x00, 0xF0, 0x06, 0xFC, 0x02, 0x25, 0x21, 0x46, 0x15, 0x48, 0x00, 0xF0, 0x6F, 0xFB, 0x28, 0x46, 0xBD, 0xE8, 0x38, 0x40, -+0xFF, 0xF7, 0xB2, 0xBF, 0x01, 0x46, 0x12, 0x48, 0x00, 0xF0, 0x66, 0xFB, 0x11, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x08, 0xDB, 0x38, 0xBD, 0x05, 0x46, 0xE9, 0xE7, 0x20, 0x22, 0x0D, 0x48, 0x11, 0x46, 0xFC, 0xF7, 0x12, 0xFC, -+0xD9, 0xE7, 0xBD, 0xE8, 0x38, 0x40, 0x0B, 0x49, 0x0B, 0x48, 0x4F, 0xF4, 0xD3, 0x62, 0x1E, 0xF0, 0x93, 0xBF, 0x00, 0xBF, -+0x08, 0x30, 0x01, 0x50, 0x54, 0x7E, 0x15, 0x00, 0x20, 0x10, 0x01, 0x50, 0x18, 0x10, 0x01, 0x50, 0x60, 0x7E, 0x15, 0x00, -+0x6C, 0x7E, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x24, 0x10, 0x01, 0x50, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, -+0x02, 0x48, 0x38, 0x22, 0x00, 0x21, 0xFA, 0xF7, 0x91, 0xBA, 0x00, 0xBF, 0x48, 0x35, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, -+0x5D, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x80, 0x46, 0x0F, 0x46, 0x16, 0x46, 0xC0, 0xF2, 0xA8, 0x80, -+0x00, 0x23, 0x3B, 0x62, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x56, 0x4B, 0x01, 0x22, 0x1A, 0x60, -+0xB5, 0x01, 0x05, 0xF1, 0x80, 0x42, 0x02, 0xF5, 0xE2, 0x24, 0x53, 0x49, 0x23, 0x68, 0x08, 0x68, 0x43, 0xF0, 0x01, 0x03, -+0x00, 0xF1, 0x01, 0x0C, 0x02, 0xF5, 0xE0, 0x22, 0x23, 0x60, 0xC1, 0xF8, 0x00, 0xC0, 0x23, 0x68, 0xDB, 0x03, 0xFC, 0xD5, -+0xDF, 0xF8, 0x38, 0xE1, 0x5E, 0xF8, 0x26, 0x90, 0xB9, 0xF1, 0x00, 0x0F, 0x0A, 0xD0, 0x05, 0xF1, 0x80, 0x43, 0x03, 0xF5, -+0xE0, 0x23, 0x41, 0xF2, 0x0C, 0x0A, 0x53, 0xF8, 0x0A, 0xA0, 0x1A, 0xF4, 0x00, 0x6F, 0x61, 0xD0, 0x05, 0xF1, 0x80, 0x43, -+0x03, 0xF5, 0xE0, 0x23, 0x41, 0xF2, 0x08, 0x09, 0xDF, 0xF8, 0x0C, 0xA1, 0x43, 0xF8, 0x09, 0xA0, 0x41, 0xF2, 0x0C, 0x05, -+0x4F, 0xF0, 0x14, 0x0A, 0x43, 0xF8, 0x05, 0xA0, 0x41, 0xF2, 0x10, 0x0B, 0x41, 0xF2, 0x14, 0x0A, 0x00, 0x25, 0x43, 0xF8, -+0x0B, 0x50, 0x43, 0xF8, 0x0A, 0x50, 0x41, 0xF2, 0x18, 0x0B, 0x41, 0xF2, 0x1C, 0x0A, 0x43, 0xF8, 0x0B, 0x50, 0x43, 0xF8, -+0x0A, 0x50, 0x03, 0xF5, 0x81, 0x5B, 0x41, 0xF2, 0x24, 0x0A, 0xCB, 0xF8, 0x00, 0x50, 0x43, 0xF8, 0x0A, 0x50, 0x41, 0xF2, -+0x28, 0x0B, 0x41, 0xF2, 0x2C, 0x0A, 0x43, 0xF8, 0x0B, 0x50, 0x43, 0xF8, 0x0A, 0x50, 0x41, 0xF2, 0x34, 0x0B, 0x41, 0xF2, -+0x38, 0x0A, 0x43, 0xF8, 0x0B, 0x50, 0x43, 0xF8, 0x0A, 0x50, 0x41, 0xF2, 0x3C, 0x0B, 0x41, 0xF2, 0x30, 0x0A, 0x43, 0xF8, -+0x0B, 0x50, 0x43, 0xF8, 0x0A, 0x80, 0xBD, 0x68, 0x45, 0xF4, 0x00, 0x25, 0xBD, 0x60, 0x53, 0xF8, 0x09, 0x50, 0x45, 0xF0, -+0x01, 0x05, 0x43, 0xF8, 0x09, 0x50, 0x41, 0xF2, 0x04, 0x05, 0x53, 0x59, 0x43, 0xF0, 0x01, 0x03, 0x53, 0x51, 0x23, 0x68, -+0x4E, 0xF8, 0x26, 0x70, 0x23, 0xF0, 0x01, 0x03, 0x23, 0x60, 0xBC, 0xF1, 0x00, 0x0F, 0x05, 0xD0, 0x14, 0x4B, 0x08, 0x60, -+0x1B, 0x68, 0x08, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0xBD, 0xE8, 0xF8, 0x8F, 0x41, 0xF2, 0x18, 0x02, 0x9D, 0x58, 0x2D, 0x03, -+0x07, 0xD5, 0x9D, 0x58, 0x41, 0xF2, 0x30, 0x0A, 0x25, 0xF4, 0x00, 0x25, 0x9D, 0x50, 0x43, 0xF8, 0x0A, 0x80, 0xD9, 0xF8, -+0x08, 0x30, 0x23, 0xF4, 0x00, 0x23, 0xC9, 0xF8, 0x08, 0x30, 0xC9, 0xF8, 0x20, 0x80, 0xD8, 0xE7, 0x0D, 0x2A, 0x7F, 0xF7, -+0x55, 0xAF, 0x06, 0x49, 0x06, 0x48, 0x4E, 0x22, 0x1E, 0xF0, 0xBA, 0xFE, 0x4E, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x94, 0x7E, 0x15, 0x00, 0x48, 0x35, 0x17, 0x00, -+0x10, 0x00, 0x01, 0x00, 0x03, 0x4B, 0x04, 0x4A, 0x01, 0x30, 0x43, 0xEA, 0x00, 0x43, 0x13, 0x63, 0x70, 0x47, 0x00, 0xBF, -+0x3F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x40, 0x70, 0xB4, 0x18, 0x4D, 0x18, 0x4C, 0x2E, 0x6B, 0xB1, 0xF5, 0x00, 0x6F, -+0x46, 0xF0, 0x80, 0x56, 0x2E, 0x63, 0x60, 0x60, 0xEB, 0x63, 0x20, 0x60, 0x0B, 0x46, 0x28, 0xBF, 0x4F, 0xF4, 0x00, 0x63, -+0x80, 0x07, 0x11, 0xD0, 0xC1, 0xF3, 0x10, 0x05, 0x10, 0x48, 0x43, 0xF0, 0x0C, 0x53, 0x21, 0xF0, 0x70, 0x41, 0xA3, 0x60, -+0xE5, 0x60, 0x21, 0x61, 0x60, 0x61, 0x0B, 0x49, 0x00, 0x23, 0x23, 0x62, 0x08, 0x46, 0x70, 0xBC, 0xFF, 0xF7, 0x04, 0xBF, -+0xC1, 0xF3, 0x10, 0x05, 0x43, 0xF0, 0x23, 0x43, 0x21, 0xF0, 0x70, 0x41, 0x4F, 0xF0, 0x04, 0x10, 0xA3, 0x60, 0xE5, 0x60, -+0x21, 0x61, 0x60, 0x61, 0xEB, 0xE7, 0x00, 0xBF, 0x00, 0x00, 0x07, 0x40, 0x74, 0x25, 0x17, 0x00, 0x01, 0x00, 0x04, 0x00, -+0x01, 0x23, 0x06, 0x4A, 0x03, 0xFA, 0x00, 0xF0, 0x93, 0x69, 0x03, 0x42, 0xFC, 0xD1, 0x13, 0x6B, 0x23, 0xF0, 0x80, 0x53, -+0x13, 0x63, 0x10, 0x6C, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x00, 0x07, 0x40, 0x08, 0x4A, 0xD3, 0x68, 0x19, 0x04, 0x44, 0xBF, -+0x4F, 0xF4, 0x00, 0x01, 0x91, 0x60, 0x5B, 0x05, 0x00, 0xD4, 0x70, 0x47, 0x03, 0x4B, 0x4F, 0xF4, 0x80, 0x22, 0x9A, 0x60, -+0x4F, 0xF0, 0x80, 0x40, 0x1D, 0xF0, 0x4E, 0xB9, 0x00, 0x10, 0x50, 0x40, 0x11, 0x4A, 0x13, 0x68, 0x13, 0xF0, 0x01, 0x01, -+0x0A, 0xD1, 0x23, 0xF4, 0x40, 0x73, 0x43, 0xF4, 0x90, 0x73, 0x43, 0xF0, 0x01, 0x03, 0x11, 0x20, 0x11, 0x61, 0x51, 0x61, -+0x50, 0x60, 0x13, 0x60, 0x5A, 0x04, 0x03, 0xD4, 0x08, 0x4A, 0x43, 0xF4, 0x80, 0x43, 0x13, 0x60, 0x07, 0x4B, 0x08, 0x49, -+0x9A, 0x68, 0xD1, 0xF8, 0xD0, 0x10, 0xC2, 0xF8, 0xB4, 0x10, 0xA3, 0xF5, 0x40, 0x63, 0x4F, 0xF0, 0x00, 0x52, 0x1A, 0x60, -+0x70, 0x47, 0x00, 0xBF, 0x00, 0x10, 0x50, 0x40, 0x00, 0xED, 0x00, 0xE0, 0x88, 0x1A, 0x17, 0x00, 0x06, 0x4B, 0x07, 0x49, -+0x9A, 0x68, 0xD1, 0xF8, 0xD0, 0x10, 0xC2, 0xF8, 0xB4, 0x10, 0xA3, 0xF5, 0x40, 0x63, 0x4F, 0xF0, 0x00, 0x52, 0x1A, 0x60, -+0x70, 0x47, 0x00, 0xBF, 0x00, 0xED, 0x00, 0xE0, 0x88, 0x1A, 0x17, 0x00, 0x3E, 0x4B, 0x1A, 0x68, 0x00, 0x2A, 0x6F, 0xD1, -+0x3D, 0x49, 0xD1, 0xF8, 0xA4, 0x10, 0x00, 0x29, 0xF0, 0xB4, 0x56, 0xDA, 0x3B, 0x48, 0x00, 0x68, 0x00, 0x28, 0x4E, 0xD0, -+0x3A, 0x4D, 0x3B, 0x48, 0x3B, 0x4C, 0x2A, 0x60, 0x01, 0x25, 0x02, 0x60, 0x25, 0x60, 0xC2, 0x68, 0x39, 0x4D, 0x3A, 0x4C, -+0x42, 0xF4, 0x80, 0x72, 0xC2, 0x60, 0x03, 0x22, 0x2A, 0x60, 0x62, 0x68, 0x92, 0x07, 0x21, 0xF0, 0x00, 0x41, 0x57, 0xD5, -+0x35, 0x4A, 0x12, 0x68, 0x10, 0x09, 0x81, 0x42, 0x4D, 0xD2, 0xB2, 0xFB, 0xF1, 0xF1, 0xC1, 0xF3, 0x42, 0x04, 0x01, 0xF0, -+0x0F, 0x02, 0x12, 0x1B, 0xC1, 0xF3, 0x07, 0x1C, 0x04, 0xEB, 0x02, 0x14, 0xC1, 0xF3, 0x07, 0x31, 0x2A, 0x4A, 0x28, 0x4D, -+0x10, 0x68, 0x2C, 0x4E, 0x2C, 0x4F, 0x40, 0xF0, 0x80, 0x00, 0x10, 0x60, 0xC7, 0xF8, 0x00, 0xC0, 0x29, 0x60, 0x34, 0x60, -+0x11, 0x68, 0x21, 0x4C, 0x22, 0x48, 0x28, 0x4E, 0x21, 0xF0, 0x80, 0x01, 0x11, 0x60, 0x07, 0x22, 0x22, 0x60, 0x02, 0x68, -+0x25, 0x4C, 0x26, 0x49, 0xD4, 0xF8, 0xBC, 0x40, 0x22, 0xF4, 0xFF, 0x72, 0x22, 0xF0, 0x01, 0x02, 0x42, 0xF0, 0x01, 0x02, -+0x02, 0x60, 0x01, 0x22, 0x2A, 0x60, 0xB0, 0x68, 0x4F, 0xF4, 0x80, 0x32, 0xC0, 0xF8, 0x80, 0x40, 0x0A, 0x60, 0x01, 0x22, -+0xF0, 0xBC, 0x1A, 0x60, 0x70, 0x47, 0x10, 0x4A, 0x12, 0x68, 0x00, 0x2A, 0xF7, 0xD0, 0x10, 0x48, 0x17, 0x4C, 0x16, 0x49, -+0xD4, 0xF8, 0xBC, 0x40, 0x16, 0x4A, 0x01, 0x25, 0x05, 0x60, 0x88, 0x68, 0x4F, 0xF4, 0x80, 0x31, 0xC0, 0xF8, 0x80, 0x40, -+0x11, 0x60, 0xE8, 0xE7, 0x70, 0x47, 0x00, 0x24, 0x21, 0x46, 0x4F, 0xF0, 0x01, 0x0C, 0xB9, 0xE7, 0x0F, 0x48, 0x10, 0x4A, -+0xA7, 0xE7, 0x00, 0xBF, 0xA4, 0x25, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x68, 0x28, 0x17, 0x00, 0x08, 0x10, 0x04, 0x40, -+0x04, 0x10, 0x04, 0x40, 0x24, 0x10, 0x04, 0x40, 0x0C, 0x10, 0x04, 0x40, 0x00, 0x00, 0x10, 0x40, 0x14, 0x13, 0x17, 0x00, -+0x28, 0x10, 0x04, 0x40, 0x00, 0x10, 0x04, 0x40, 0x00, 0xED, 0x00, 0xE0, 0x88, 0x1A, 0x17, 0x00, 0x00, 0xE1, 0x00, 0xE0, -+0x50, 0x97, 0x31, 0x00, 0x00, 0x75, 0x19, 0x03, 0x03, 0x4A, 0x13, 0x68, 0x1B, 0x03, 0xFC, 0xD4, 0x02, 0x4B, 0x18, 0x60, -+0x70, 0x47, 0x00, 0xBF, 0x20, 0x10, 0x04, 0x40, 0x00, 0x10, 0x04, 0x40, 0x03, 0x4A, 0x13, 0x68, 0xDB, 0x07, 0xFC, 0xD5, -+0x02, 0x4B, 0x18, 0x68, 0xC0, 0xB2, 0x70, 0x47, 0x14, 0x10, 0x04, 0x40, 0x00, 0x10, 0x04, 0x40, 0xF0, 0xB5, 0x03, 0x46, -+0xC3, 0xB0, 0xEF, 0xF3, 0x05, 0x85, 0x73, 0x4C, 0x22, 0x68, 0x12, 0x78, 0x02, 0x2A, 0x04, 0xD1, 0x71, 0x4A, 0xB2, 0xF8, -+0xAA, 0x20, 0x52, 0x04, 0x56, 0xD4, 0x00, 0x91, 0x00, 0x22, 0x4F, 0xF4, 0x80, 0x71, 0x02, 0xA8, 0x1D, 0xF0, 0x46, 0xFE, -+0x06, 0x46, 0x00, 0x2E, 0x31, 0xDD, 0x6B, 0x4B, 0x1B, 0x68, 0x1B, 0xB9, 0x6A, 0x4B, 0xD3, 0xF8, 0x28, 0x33, 0x98, 0x47, -+0x1D, 0xB9, 0x69, 0x4A, 0x13, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x68, 0x4B, 0x1B, 0x68, 0x33, 0xB9, 0x67, 0x4A, 0x13, 0x68, -+0x1F, 0x03, 0xFC, 0xD4, 0x66, 0x4B, 0x5F, 0x22, 0x1A, 0x60, 0x5F, 0x4B, 0xB3, 0xF8, 0xAA, 0x30, 0x13, 0xF4, 0x80, 0x43, -+0x18, 0xD1, 0x02, 0xA9, 0x60, 0x4A, 0x61, 0x48, 0x77, 0x18, 0x4F, 0xF0, 0x0D, 0x0C, 0x11, 0xF8, 0x01, 0x4B, 0x0A, 0x2C, -+0x1C, 0xD0, 0x13, 0x68, 0x1B, 0x03, 0xFC, 0xD4, 0x04, 0x60, 0xB9, 0x42, 0x11, 0xF8, 0x01, 0x3C, 0xF3, 0xD1, 0x15, 0xB9, -+0x55, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x30, 0x46, 0x43, 0xB0, 0xF0, 0xBD, 0x23, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x1C, 0xD0, -+0x02, 0x2B, 0xF2, 0xD1, 0x53, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0xED, 0xD0, 0x00, 0x2D, 0xEF, 0xD1, 0x26, 0xE0, -+0x0D, 0x2B, 0xE0, 0xD0, 0x13, 0x68, 0x1C, 0x03, 0xFC, 0xD4, 0xC0, 0xF8, 0x00, 0xC0, 0x11, 0xF8, 0x01, 0x4C, 0xD8, 0xE7, -+0x00, 0x91, 0x00, 0x22, 0x4F, 0xF4, 0x80, 0x71, 0x03, 0xA8, 0x1D, 0xF0, 0xEF, 0xFD, 0x06, 0x46, 0xA7, 0xE7, 0x46, 0x4F, -+0x3B, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0xD2, 0xD0, 0x00, 0x2D, 0xD4, 0xD1, 0x43, 0x48, 0x1D, 0xF0, 0x07, 0xF9, 0x04, 0x28, -+0x62, 0xD8, 0x23, 0x68, 0x1B, 0x78, 0x02, 0x2B, 0xC8, 0xD1, 0x3B, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0xC4, 0xD0, 0x3E, 0x48, -+0x1D, 0xF0, 0xFA, 0xF8, 0x04, 0x28, 0xBF, 0xD9, 0x3B, 0x48, 0x3C, 0x4C, 0x1D, 0xF0, 0xB4, 0xF8, 0x42, 0xF2, 0x34, 0x03, -+0x13, 0x25, 0xE2, 0x5A, 0x8D, 0xF8, 0x08, 0x60, 0x00, 0x23, 0xB2, 0xF5, 0xC3, 0x7F, 0x02, 0xAF, 0x01, 0x46, 0x7D, 0x80, -+0x7B, 0x70, 0x4D, 0xD8, 0x55, 0x1C, 0xAD, 0xB2, 0xD3, 0x00, 0x33, 0x48, 0x8A, 0x81, 0xD0, 0xF8, 0x00, 0xC0, 0x0C, 0xEB, -+0x03, 0x00, 0x32, 0x1D, 0x47, 0x60, 0x2C, 0xF8, 0x03, 0x20, 0xC3, 0x78, 0x03, 0xF0, 0x31, 0x03, 0x43, 0xF0, 0x04, 0x03, -+0xC3, 0x70, 0x94, 0xF8, 0x02, 0x3C, 0x42, 0xF2, 0x34, 0x0C, 0x01, 0x33, 0x84, 0xF8, 0x02, 0x3C, 0x01, 0x27, 0x00, 0x23, -+0x24, 0xF8, 0x0C, 0x50, 0xC1, 0xE9, 0x01, 0x02, 0x8F, 0x73, 0x0B, 0x60, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x02, 0xD4, -+0x72, 0xB6, 0x22, 0x4B, 0x1F, 0x60, 0x22, 0x4C, 0x22, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x1D, 0xF0, 0x32, 0xF8, -+0x13, 0x4B, 0xD3, 0xF8, 0x44, 0x34, 0x98, 0x47, 0x23, 0x68, 0x00, 0x2B, 0x3F, 0xF4, 0x76, 0xAF, 0x19, 0x4A, 0x01, 0x3B, -+0x12, 0x68, 0x23, 0x60, 0x00, 0x2B, 0x7F, 0xF4, 0x6F, 0xAF, 0x00, 0x2A, 0x3F, 0xF4, 0x6C, 0xAF, 0x62, 0xB6, 0x69, 0xE7, -+0x7C, 0x2E, 0x32, 0x46, 0xA8, 0xBF, 0x7C, 0x22, 0x92, 0xB2, 0x02, 0xA9, 0x13, 0x20, 0x02, 0xF0, 0xF9, 0xFA, 0x5F, 0xE7, -+0x1A, 0x46, 0x01, 0x25, 0xB1, 0xE7, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0xA4, 0x25, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x40, 0x40, 0x04, 0x40, 0x68, 0x28, 0x17, 0x00, 0x20, 0x10, 0x04, 0x40, 0x00, 0x10, 0x04, 0x40, -+0x74, 0x36, 0x17, 0x00, 0x20, 0x60, 0x17, 0x00, 0xA0, 0x56, 0x17, 0x00, 0x7C, 0x36, 0x17, 0x00, 0x54, 0x60, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xA8, 0x56, 0x17, 0x00, 0x0F, 0xB4, 0x00, 0xB5, 0x83, 0xB0, 0x04, 0xA9, -+0x05, 0x4B, 0x51, 0xF8, 0x04, 0x0B, 0xD3, 0xF8, 0x30, 0x34, 0x01, 0x91, 0x98, 0x47, 0x03, 0xB0, 0x5D, 0xF8, 0x04, 0xEB, -+0x04, 0xB0, 0x70, 0x47, 0x88, 0x1A, 0x17, 0x00, 0x01, 0x22, 0x90, 0x42, 0x10, 0xB4, 0x02, 0xFA, 0x00, 0xF4, 0x11, 0xDD, -+0xA0, 0xF1, 0x08, 0x03, 0x93, 0x42, 0x0D, 0xD9, 0x0F, 0x28, 0x25, 0xDD, 0x1F, 0x28, 0x12, 0xDC, 0x15, 0x4A, 0x52, 0xF8, -+0x20, 0x30, 0x23, 0xF0, 0x0F, 0x03, 0x43, 0xF0, 0x02, 0x03, 0x42, 0xF8, 0x20, 0x30, 0x08, 0xE0, 0x10, 0x4A, 0x52, 0xF8, -+0x20, 0x30, 0x23, 0xF0, 0x0F, 0x03, 0x43, 0xF0, 0x01, 0x03, 0x42, 0xF8, 0x20, 0x30, 0x0D, 0x4B, 0x5A, 0x68, 0x22, 0x43, -+0x5A, 0x60, 0x9A, 0x68, 0x29, 0xB9, 0x22, 0xEA, 0x04, 0x02, 0x9A, 0x60, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x22, 0x43, -+0x9A, 0x60, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x03, 0x4A, 0x52, 0xF8, 0x20, 0x30, 0x23, 0xF0, 0x0F, 0x03, 0x42, 0xF8, -+0x20, 0x30, 0xE6, 0xE7, 0x00, 0x30, 0x50, 0x40, 0x00, 0x40, 0x50, 0x40, 0x04, 0x49, 0x01, 0x22, 0x0B, 0x68, 0x02, 0xFA, -+0x00, 0xF0, 0x23, 0xEA, 0x00, 0x03, 0x0B, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x40, 0x50, 0x40, 0x10, 0xB5, 0x01, 0x29, -+0x82, 0xB0, 0x04, 0x46, 0x10, 0xD0, 0x20, 0xF0, 0x03, 0x03, 0x0F, 0x22, 0x9A, 0x40, 0x11, 0x46, 0x0D, 0x48, 0xFC, 0xF7, -+0x51, 0xF8, 0x01, 0x22, 0xA2, 0x40, 0x0C, 0x48, 0x11, 0x46, 0x02, 0xB0, 0xBD, 0xE8, 0x10, 0x40, 0xFC, 0xF7, 0x48, 0xB8, -+0x01, 0xFA, 0x00, 0xF2, 0x11, 0x46, 0x07, 0x48, 0x01, 0x92, 0xFC, 0xF7, 0x41, 0xF8, 0x01, 0x9A, 0x05, 0x48, 0x11, 0x46, -+0x02, 0xB0, 0xBD, 0xE8, 0x10, 0x40, 0xFC, 0xF7, 0x39, 0xB8, 0x00, 0xBF, 0x2C, 0x10, 0x01, 0x50, 0x04, 0x10, 0x01, 0x50, -+0x08, 0x10, 0x01, 0x50, 0x01, 0x23, 0x03, 0xFA, 0x00, 0xF2, 0x11, 0x46, 0x01, 0x48, 0xFC, 0xF7, 0x2B, 0xB8, 0x00, 0xBF, -+0x00, 0x10, 0x01, 0x50, 0x01, 0x22, 0x82, 0x40, 0x00, 0x21, 0x01, 0x48, 0xFC, 0xF7, 0x22, 0xB8, 0x00, 0x10, 0x01, 0x50, -+0x10, 0xB5, 0x04, 0x46, 0x03, 0x48, 0xFB, 0xF7, 0xCB, 0xFF, 0xE0, 0x40, 0x00, 0xF0, 0x01, 0x00, 0x10, 0xBD, 0x00, 0xBF, -+0x00, 0x10, 0x01, 0x50, 0x70, 0x47, 0x00, 0xBF, 0x70, 0x47, 0x00, 0xBF, 0x70, 0x47, 0x00, 0xBF, 0x0E, 0x48, 0x0F, 0x4A, -+0x03, 0x68, 0x0F, 0x49, 0x23, 0xF0, 0xFF, 0x03, 0x43, 0xF0, 0xC2, 0x03, 0x03, 0x60, 0x13, 0x68, 0x23, 0xF0, 0xFF, 0x03, -+0x43, 0xF0, 0xC2, 0x03, 0x13, 0x60, 0x03, 0x68, 0x23, 0xF4, 0x7F, 0x23, 0x43, 0xF4, 0x3F, 0x23, 0x03, 0x60, 0x13, 0x68, -+0x23, 0xF4, 0x7F, 0x23, 0x43, 0xF4, 0x3F, 0x23, 0xC2, 0x20, 0x13, 0x60, 0xC8, 0x71, 0x70, 0x47, 0xAC, 0xB3, 0x33, 0x40, -+0xD4, 0xB3, 0x33, 0x40, 0x80, 0x35, 0x17, 0x00, 0x24, 0x4B, 0x25, 0x48, 0x1B, 0x68, 0x2D, 0xE9, 0xF0, 0x41, 0x24, 0x4D, -+0x24, 0x4F, 0x6A, 0x79, 0x95, 0xF9, 0x07, 0x10, 0x3C, 0x68, 0x23, 0x4E, 0x03, 0xF0, 0x0F, 0x03, 0x1A, 0x44, 0x52, 0xB2, -+0x89, 0x1A, 0x6F, 0xF0, 0x3D, 0x03, 0x99, 0x42, 0xB8, 0xBF, 0x19, 0x46, 0x5F, 0xFA, 0x81, 0xFC, 0x24, 0xF0, 0xFF, 0x04, -+0x44, 0xEA, 0x0C, 0x04, 0x3C, 0x60, 0x33, 0x68, 0x23, 0xF0, 0xFF, 0x03, 0x43, 0xEA, 0x0C, 0x03, 0x33, 0x60, 0x3C, 0x68, -+0xCB, 0x1E, 0x5F, 0xFA, 0x83, 0xFC, 0x24, 0xF4, 0x7F, 0x24, 0x44, 0xEA, 0x0C, 0x34, 0x3C, 0x60, 0x33, 0x68, 0x23, 0xF4, -+0x7F, 0x23, 0x4C, 0xB2, 0x43, 0xEA, 0x0C, 0x33, 0x33, 0x60, 0x21, 0x46, 0xEC, 0x71, 0x1E, 0xF0, 0xC3, 0xF8, 0x3D, 0x34, -+0x0E, 0xDB, 0x0D, 0x4B, 0x29, 0x89, 0x1A, 0x69, 0x0C, 0x4B, 0x47, 0xF2, 0x30, 0x54, 0x05, 0xF1, 0x0C, 0x00, 0x04, 0xFB, -+0x01, 0x21, 0xD3, 0xF8, 0xE0, 0x31, 0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0xBD, 0xE8, 0xF0, 0x81, 0x1C, 0x01, 0x32, 0x40, -+0xB8, 0x7E, 0x15, 0x00, 0x80, 0x35, 0x17, 0x00, 0xAC, 0xB3, 0x33, 0x40, 0xD4, 0xB3, 0x33, 0x40, 0x00, 0x10, 0x50, 0x40, -+0x88, 0x1A, 0x17, 0x00, 0x12, 0x4A, 0x12, 0x68, 0xD2, 0xE9, 0x06, 0x01, 0x38, 0xB5, 0x11, 0x4B, 0x15, 0x6A, 0x18, 0x60, -+0x59, 0x60, 0x50, 0x6A, 0x0F, 0x4C, 0xD2, 0xE9, 0x0A, 0x12, 0xC3, 0xE9, 0x02, 0x50, 0xC3, 0xE9, 0x04, 0x12, 0xD4, 0xF8, -+0x2C, 0x33, 0x98, 0x47, 0xD4, 0xF8, 0xC0, 0x30, 0x98, 0x47, 0xFB, 0xF7, 0xAF, 0xFA, 0x09, 0x4B, 0x1B, 0x68, 0x1B, 0x78, -+0x03, 0x2B, 0x02, 0xD1, 0xD4, 0xF8, 0x20, 0x31, 0x98, 0x47, 0xBD, 0xE8, 0x38, 0x40, 0xFF, 0xF7, 0x79, 0xBB, 0x00, 0xBF, -+0xC8, 0x35, 0x17, 0x00, 0xB0, 0x35, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x78, 0x36, 0x17, 0x00, 0x30, 0xB4, 0x08, 0x4B, -+0x08, 0x48, 0x18, 0x60, 0xC2, 0x25, 0x40, 0xF6, 0xEC, 0x20, 0x4F, 0xF4, 0x7A, 0x74, 0x06, 0x49, 0x06, 0x4A, 0xDD, 0x71, -+0x98, 0x80, 0x1C, 0x81, 0x19, 0x61, 0x30, 0xBC, 0x1A, 0x62, 0x70, 0x47, 0x80, 0x35, 0x17, 0x00, 0x01, 0x00, 0x00, 0x14, -+0x95, 0x64, 0x12, 0x00, 0x4D, 0x64, 0x12, 0x00, 0x90, 0xF8, 0x62, 0x30, 0xCB, 0xB9, 0x0D, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x10, 0xB5, 0x04, 0x46, 0x03, 0xDB, 0x00, 0x23, 0x84, 0xF8, 0xAC, 0x30, 0x10, 0xBD, 0x90, 0xF8, -+0xAC, 0x30, 0x01, 0x2B, 0xF7, 0xD0, 0x06, 0x49, 0x06, 0x48, 0x40, 0xF2, 0xE7, 0x12, 0x1E, 0xF0, 0xBB, 0xFA, 0x00, 0x23, -+0x84, 0xF8, 0xAC, 0x30, 0x10, 0xBD, 0x70, 0x47, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xCC, 0x7E, 0x15, 0x00, -+0x13, 0x4A, 0x90, 0xF8, 0x22, 0x30, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, 0x62, 0x30, 0x02, 0x2B, -+0x1B, 0xD1, 0x0F, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x10, 0xB5, 0x04, 0x46, 0x08, 0xDB, 0x94, 0xF8, -+0x23, 0x10, 0x0B, 0x48, 0x1E, 0xF0, 0x1E, 0xF8, 0x00, 0x23, 0x84, 0xF8, 0x70, 0x32, 0x10, 0xBD, 0x90, 0xF8, 0x70, 0x32, -+0x01, 0x2B, 0xF2, 0xD0, 0x06, 0x49, 0x07, 0x48, 0x40, 0xF2, 0xF3, 0x12, 0x1E, 0xF0, 0x8A, 0xFA, 0xEB, 0xE7, 0x70, 0x47, -+0x18, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x10, 0x7F, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, 0xF0, 0x7E, 0x15, 0x00, -+0x2D, 0xE9, 0xF0, 0x41, 0x90, 0xF8, 0x62, 0x40, 0x1C, 0xB9, 0x90, 0xF8, 0x64, 0x30, 0x06, 0x46, 0x0B, 0xB9, 0xBD, 0xE8, -+0xF0, 0x81, 0xD0, 0xE9, 0x24, 0x23, 0xD0, 0xF8, 0x98, 0x10, 0x42, 0x48, 0xDF, 0xF8, 0x30, 0x81, 0x1D, 0xF0, 0xF0, 0xFF, -+0x45, 0x46, 0x06, 0xF5, 0xB2, 0x77, 0x28, 0x46, 0x06, 0x22, 0x39, 0x46, 0x30, 0xF0, 0xD8, 0xFC, 0x14, 0x35, 0x40, 0xB1, -+0x01, 0x34, 0x05, 0x2C, 0xF5, 0xD1, 0x3A, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x5B, 0xDB, 0x04, 0xEB, -+0x84, 0x03, 0x08, 0xEB, 0x83, 0x03, 0xA2, 0x00, 0xD9, 0x79, 0x00, 0x29, 0xD9, 0xD1, 0x1B, 0x7A, 0x03, 0xBB, 0xD6, 0xF8, -+0x90, 0x30, 0x31, 0x2B, 0x29, 0xD9, 0xD6, 0xF8, 0x94, 0x10, 0xB1, 0xEB, 0x53, 0x0F, 0x3B, 0xD8, 0x14, 0x44, 0x08, 0xEB, -+0x84, 0x08, 0x98, 0xF8, 0x06, 0x30, 0x00, 0x2B, 0x48, 0xD1, 0x00, 0x23, 0xC6, 0xE9, 0x24, 0x33, 0x29, 0x4A, 0xC6, 0xF8, -+0x98, 0x30, 0x12, 0x69, 0x28, 0x49, 0x29, 0x4B, 0x06, 0xF1, 0x9C, 0x00, 0xD3, 0xF8, 0xE0, 0x31, 0xBD, 0xE8, 0xF0, 0x41, -+0x11, 0x44, 0x18, 0x47, 0xD6, 0xF8, 0x98, 0x30, 0x53, 0xB3, 0xD6, 0xF8, 0x90, 0x30, 0x00, 0x2B, 0x37, 0xD0, 0x11, 0x19, -+0x08, 0xEB, 0x81, 0x01, 0x00, 0x20, 0x08, 0x72, 0xD3, 0xE7, 0x0B, 0x2B, 0x12, 0xD8, 0xD6, 0xF8, 0x98, 0x20, 0x14, 0x2A, -+0xDB, 0xD9, 0x00, 0x2B, 0xD9, 0xD1, 0x1B, 0x48, 0x1D, 0xF0, 0x9A, 0xFF, 0x18, 0x4B, 0x01, 0x22, 0x88, 0xF8, 0x06, 0x20, -+0x30, 0x46, 0xD3, 0xF8, 0xBC, 0x31, 0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0xD6, 0xF8, 0x94, 0x10, 0x14, 0x4A, 0xA2, 0xFB, -+0x03, 0x02, 0x22, 0xF0, 0x03, 0x00, 0x00, 0xEB, 0x92, 0x02, 0x8A, 0x42, 0xE1, 0xD8, 0xE6, 0xE7, 0xD6, 0xF8, 0x90, 0x30, -+0xD5, 0xE7, 0x0F, 0x49, 0x0F, 0x48, 0x40, 0xF2, 0x13, 0x22, 0x1E, 0xF0, 0xF5, 0xF9, 0x9C, 0xE7, 0x00, 0x23, 0x0D, 0x48, -+0x88, 0xF8, 0x06, 0x30, 0x1D, 0xF0, 0x74, 0xFF, 0xAF, 0xE7, 0x0B, 0x48, 0xD4, 0xE7, 0x00, 0xBF, 0x1C, 0x7F, 0x15, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x80, 0xC3, 0xC9, 0x01, 0x88, 0x1A, 0x17, 0x00, 0x44, 0x7F, 0x15, 0x00, -+0xAB, 0xAA, 0xAA, 0xAA, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x3C, 0x7F, 0x15, 0x00, 0x30, 0x7F, 0x15, 0x00, -+0xCC, 0x35, 0x17, 0x00, 0x06, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x05, 0xD0, 0x02, 0x2B, 0x01, 0xD0, 0x04, 0xF0, -+0xEF, 0xBC, 0x03, 0xF0, 0xD5, 0xBF, 0x00, 0xF0, 0xD7, 0xBF, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, 0x08, 0xB5, 0x08, 0x46, -+0x00, 0xF0, 0x6C, 0xFE, 0x01, 0x20, 0x08, 0xBD, 0x70, 0xB5, 0x30, 0x4C, 0x23, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x1E, 0xD0, -+0x02, 0x2B, 0x14, 0xD1, 0x2D, 0x4B, 0x2E, 0x49, 0x2E, 0x4A, 0xC3, 0xE9, 0x06, 0x12, 0x2E, 0x4D, 0xD5, 0xF8, 0x14, 0x31, -+0x98, 0x47, 0xD5, 0xF8, 0x18, 0x31, 0x98, 0x47, 0x23, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x36, 0xD0, 0x02, 0x2B, 0x1D, 0xD0, -+0x03, 0x2B, 0x0E, 0xD0, 0x70, 0xBD, 0x03, 0x2B, 0xED, 0xD1, 0x22, 0x4B, 0x25, 0x49, 0x26, 0x4A, 0xC3, 0xE9, 0x08, 0x12, -+0xE7, 0xE7, 0x1F, 0x4B, 0x24, 0x49, 0x25, 0x4A, 0xC3, 0xE9, 0x02, 0x12, 0xE1, 0xE7, 0x24, 0x4B, 0x1B, 0x4C, 0x24, 0x4A, -+0x1A, 0x60, 0x04, 0xF0, 0x87, 0xFC, 0x23, 0x6A, 0x22, 0x48, 0x98, 0x47, 0x63, 0x6A, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, -+0x1D, 0x4B, 0x20, 0x49, 0x20, 0x4A, 0x19, 0x60, 0x13, 0x4D, 0x42, 0xF2, 0x34, 0x03, 0x00, 0x21, 0xD1, 0x52, 0x04, 0xF0, -+0x1B, 0xF8, 0x03, 0xF0, 0x35, 0xFF, 0xAB, 0x69, 0x18, 0x48, 0x98, 0x47, 0xEB, 0x69, 0x98, 0x47, 0x04, 0xF0, 0x1A, 0xFC, -+0x23, 0x68, 0x1B, 0x78, 0xCA, 0xE7, 0x12, 0x4B, 0x09, 0x4D, 0x16, 0x4A, 0x1A, 0x60, 0x00, 0xF0, 0xCB, 0xFE, 0x00, 0xF0, -+0xE9, 0xFE, 0x00, 0xF0, 0x13, 0xFF, 0xAB, 0x68, 0x0E, 0x48, 0x98, 0x47, 0xEB, 0x68, 0x98, 0x47, 0x23, 0x68, 0x1B, 0x78, -+0xB6, 0xE7, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, 0x28, 0x58, 0x17, 0x00, 0xA1, 0xA9, 0x12, 0x00, 0x85, 0xA9, 0x12, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x3D, 0xB2, 0x12, 0x00, 0x29, 0xB2, 0x12, 0x00, 0x0D, 0x7A, 0x12, 0x00, 0xF9, 0x79, 0x12, 0x00, -+0x1C, 0x58, 0x17, 0x00, 0xBC, 0x60, 0x17, 0x00, 0xB8, 0x7F, 0x15, 0x00, 0xA4, 0x60, 0x17, 0x00, 0x7C, 0x36, 0x17, 0x00, -+0x28, 0x60, 0x17, 0x00, 0x10, 0xB5, 0x0B, 0x4C, 0x50, 0x22, 0x51, 0x23, 0x04, 0xF2, 0x14, 0x50, 0xA4, 0xF8, 0x10, 0x25, -+0x84, 0xF8, 0x12, 0x35, 0x1C, 0xF0, 0xD8, 0xFC, 0x27, 0x22, 0x28, 0x23, 0x04, 0xF5, 0xF4, 0x60, 0xA4, 0xF8, 0x9C, 0x27, -+0x84, 0xF8, 0x9E, 0x37, 0xBD, 0xE8, 0x10, 0x40, 0x1C, 0xF0, 0xCC, 0xBC, 0x58, 0x58, 0x17, 0x00, 0x70, 0xB5, 0x41, 0xF6, -+0x10, 0x02, 0x25, 0x4D, 0x25, 0x4C, 0x4C, 0xF2, 0xBF, 0x03, 0x41, 0xF6, 0x12, 0x00, 0x00, 0x26, 0xAB, 0x52, 0x41, 0xF6, -+0x14, 0x01, 0x05, 0xF5, 0xC1, 0x52, 0xA5, 0xF8, 0x00, 0x3C, 0x2E, 0x54, 0x05, 0xF6, 0x08, 0x40, 0x6E, 0x50, 0x16, 0x70, -+0x85, 0xF8, 0x02, 0x6C, 0xC5, 0xF8, 0x04, 0x6C, 0x1C, 0xF0, 0xAE, 0xFC, 0xA4, 0xF1, 0x0C, 0x00, 0x1C, 0xF0, 0xAA, 0xFC, -+0x04, 0xF5, 0x00, 0x60, 0x1C, 0xF0, 0xA6, 0xFC, 0x04, 0xF6, 0x08, 0x00, 0x1C, 0xF0, 0xA2, 0xFC, 0x42, 0xF2, 0x34, 0x03, -+0x31, 0x46, 0x4F, 0xF4, 0x00, 0x62, 0x20, 0x46, 0xEE, 0x52, 0x85, 0xF8, 0x02, 0x6C, 0xC5, 0xF8, 0x04, 0x6C, 0xF9, 0xF7, -+0x05, 0xFC, 0x04, 0xF5, 0x00, 0x65, 0x2E, 0x46, 0x21, 0x46, 0x30, 0x46, 0x10, 0x34, 0x1C, 0xF0, 0x91, 0xFC, 0xAC, 0x42, -+0xF8, 0xD1, 0x09, 0x4A, 0x00, 0x21, 0x02, 0xF5, 0xB4, 0x70, 0xA2, 0xF1, 0x24, 0x03, 0x43, 0xF8, 0x04, 0x1B, 0x93, 0x42, -+0xFB, 0xD1, 0x03, 0xF1, 0x24, 0x02, 0x82, 0x42, 0xF5, 0xD1, 0x70, 0xBD, 0x7C, 0x36, 0x17, 0x00, 0xA0, 0x4E, 0x17, 0x00, -+0xD8, 0x56, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x40, 0x20, 0x85, 0xB0, 0x1C, 0xF0, 0xF6, 0xFB, 0xA7, 0x4B, 0x9B, 0x68, -+0x03, 0x93, 0x00, 0x2B, 0x00, 0xF0, 0x80, 0x81, 0xDF, 0xF8, 0xB0, 0x92, 0xDF, 0xF8, 0xB0, 0xB2, 0x09, 0xE0, 0x94, 0xF8, -+0x64, 0x30, 0x63, 0xB1, 0x03, 0x9B, 0x1B, 0x68, 0x03, 0x93, 0x03, 0x9B, 0x00, 0x2B, 0x00, 0xF0, 0x71, 0x81, 0x03, 0x9C, -+0x20, 0x46, 0x07, 0xF0, 0x33, 0xFF, 0x00, 0x28, 0xEF, 0xD0, 0x03, 0x9B, 0x9A, 0x4C, 0x03, 0xF5, 0xA3, 0x65, 0x01, 0x26, -+0xEF, 0xF3, 0x10, 0x83, 0xDF, 0x07, 0x02, 0xD4, 0x72, 0xB6, 0xC9, 0xF8, 0x00, 0x60, 0x23, 0x68, 0x28, 0x46, 0x01, 0x33, -+0x23, 0x60, 0x1C, 0xF0, 0x8B, 0xFC, 0x23, 0x68, 0x5A, 0x1E, 0x2B, 0xB1, 0xD9, 0xF8, 0x00, 0x30, 0x22, 0x60, 0x0A, 0xB9, -+0x03, 0xB1, 0x62, 0xB6, 0x05, 0x21, 0x38, 0xB1, 0xDB, 0xF8, 0x24, 0x34, 0x98, 0x47, 0xEF, 0xF3, 0x10, 0x83, 0xDF, 0x07, -+0xE7, 0xD4, 0xE3, 0xE7, 0x89, 0x4B, 0x93, 0xF8, 0xFF, 0x31, 0x00, 0x2B, 0xC8, 0xD1, 0xDD, 0xF8, 0x0C, 0xA0, 0x87, 0x4E, -+0x04, 0x23, 0x01, 0x93, 0xDA, 0xF8, 0x10, 0x35, 0x00, 0x2B, 0x00, 0xF0, 0x8C, 0x80, 0x9D, 0xF8, 0x04, 0x70, 0x0A, 0xF5, -+0xA2, 0x68, 0x40, 0x46, 0x1C, 0xF0, 0x62, 0xFC, 0x80, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x05, 0x46, -+0x43, 0x7F, 0x7F, 0xDB, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x03, 0x62, 0x92, 0xF8, 0x25, 0x10, 0x19, 0xB9, 0xE9, 0x8B, -+0x08, 0x07, 0x40, 0xF1, 0x07, 0x81, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x03, 0x62, 0x92, 0xF8, 0x24, 0x20, 0x01, 0x2A, -+0x00, 0xF0, 0x9E, 0x80, 0xDB, 0xF8, 0x24, 0x34, 0x28, 0x46, 0x39, 0x46, 0x98, 0x47, 0xDA, 0xF8, 0x10, 0x35, 0x00, 0x2B, -+0xD7, 0xD1, 0x0A, 0xF5, 0x9D, 0x65, 0xA8, 0x46, 0xEF, 0xF3, 0x10, 0x83, 0xDD, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x01, 0x23, -+0xC9, 0xF8, 0x00, 0x30, 0x23, 0x68, 0xDA, 0xF8, 0xE8, 0x14, 0x5A, 0x1C, 0x22, 0x60, 0x2A, 0xB1, 0xD9, 0xF8, 0x00, 0x20, -+0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x00, 0x29, 0x34, 0xD0, 0x4A, 0x7F, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, -+0x02, 0x63, 0x93, 0xF8, 0x25, 0x00, 0x00, 0x28, 0x00, 0xF0, 0x87, 0x80, 0x93, 0xF8, 0x24, 0x30, 0x01, 0x2B, 0x46, 0xD0, -+0xC9, 0x7E, 0xDB, 0xF8, 0x34, 0x31, 0x10, 0x46, 0x98, 0x47, 0x00, 0x28, 0x00, 0xF0, 0xD7, 0x80, 0xEF, 0xF3, 0x10, 0x83, -+0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x01, 0x23, 0xC9, 0xF8, 0x00, 0x30, 0x23, 0x68, 0x40, 0x46, 0x01, 0x33, 0x23, 0x60, -+0x1C, 0xF0, 0x00, 0xFC, 0x23, 0x68, 0x05, 0x46, 0x33, 0xB1, 0x01, 0x3B, 0xD9, 0xF8, 0x00, 0x20, 0x23, 0x60, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0xDB, 0xF8, 0x24, 0x34, 0x39, 0x46, 0x28, 0x46, 0x98, 0x47, 0x00, 0x2D, 0xB4, 0xD1, 0x01, 0x9B, -+0x01, 0x3B, 0x1D, 0x46, 0x38, 0x46, 0x01, 0x93, 0x0B, 0xF0, 0x26, 0xFA, 0x2B, 0x46, 0x01, 0x33, 0xAA, 0xF1, 0x08, 0x0A, -+0x3F, 0xF4, 0x38, 0xAF, 0xDA, 0xF8, 0x10, 0x35, 0x00, 0x2B, 0x7F, 0xF4, 0x74, 0xAF, 0x9D, 0xF8, 0x04, 0x70, 0x9C, 0xE7, -+0x09, 0x2B, 0x7F, 0xF6, 0x7D, 0xAF, 0x3C, 0x49, 0x3C, 0x48, 0x4F, 0xF4, 0x96, 0x72, 0x1D, 0xF0, 0xE1, 0xFF, 0x6B, 0x7F, -+0x74, 0xE7, 0xEF, 0xF3, 0x10, 0x81, 0xC9, 0x07, 0x02, 0xD4, 0x72, 0xB6, 0xC9, 0xF8, 0x00, 0x30, 0x23, 0x68, 0x02, 0x92, -+0x01, 0x33, 0x40, 0x46, 0x23, 0x60, 0x1C, 0xF0, 0xC1, 0xFB, 0x23, 0x68, 0x02, 0x9A, 0x05, 0x46, 0x33, 0xB1, 0x01, 0x3B, -+0xD9, 0xF8, 0x00, 0x10, 0x23, 0x60, 0x0B, 0xB9, 0x01, 0xB1, 0x62, 0xB6, 0x01, 0x9B, 0x4F, 0x20, 0x00, 0xFB, 0x02, 0x30, -+0x41, 0x30, 0x06, 0xEB, 0xC0, 0x00, 0x29, 0x46, 0x1C, 0xF0, 0x68, 0xFB, 0x00, 0x2D, 0x7F, 0xF4, 0x6F, 0xAF, 0xB8, 0xE7, -+0x23, 0x4A, 0x12, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x4D, 0xDB, 0xEA, 0x8B, 0xD2, 0x07, 0x7F, 0xF5, 0x5D, 0xAF, -+0x01, 0x9A, 0x4F, 0x20, 0x46, 0x32, 0x10, 0xFB, 0x03, 0x20, 0x29, 0x46, 0x06, 0xEB, 0xC0, 0x00, 0x1C, 0xF0, 0x50, 0xFB, -+0x51, 0xE7, 0x93, 0xF8, 0x23, 0x10, 0x1B, 0x48, 0x1D, 0xF0, 0x24, 0xFD, 0xEF, 0xF3, 0x10, 0x83, 0xD8, 0x07, 0x03, 0xD4, -+0x72, 0xB6, 0x01, 0x23, 0xC9, 0xF8, 0x00, 0x30, 0x23, 0x68, 0x40, 0x46, 0x01, 0x33, 0x23, 0x60, 0x1C, 0xF0, 0x80, 0xFB, -+0x4F, 0xF0, 0x00, 0x42, 0x39, 0x46, 0x05, 0x46, 0x28, 0xF0, 0x2A, 0xFE, 0x23, 0x68, 0x00, 0x2B, 0x85, 0xD0, 0x01, 0x3B, -+0xD9, 0xF8, 0x00, 0x20, 0x23, 0x60, 0x00, 0x2B, 0x7F, 0xF4, 0x7F, 0xAF, 0x00, 0x2A, 0x3F, 0xF4, 0x7C, 0xAF, 0x62, 0xB6, -+0x00, 0x2D, 0x7F, 0xF4, 0x2F, 0xAF, 0x78, 0xE7, 0x00, 0x88, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, -+0x68, 0x65, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x50, 0x7F, 0x15, 0x00, 0x7C, 0x7F, 0x15, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xEA, 0x8B, 0xD1, 0x07, 0xB2, 0xD4, 0x11, 0x49, 0x11, 0x48, 0x02, 0x93, -+0x40, 0xF2, 0x35, 0x12, 0x1D, 0xF0, 0x5A, 0xFF, 0x02, 0x9B, 0xA5, 0xE7, 0x92, 0xF8, 0x23, 0x10, 0x0D, 0x48, 0x1D, 0xF0, -+0xD9, 0xFC, 0x28, 0x46, 0x4F, 0xF0, 0x00, 0x42, 0x39, 0x46, 0x28, 0xF0, 0xED, 0xFD, 0xDA, 0xF8, 0x10, 0x35, 0x00, 0x2B, -+0x7F, 0xF4, 0xD3, 0xAE, 0xF9, 0xE6, 0x07, 0x4A, 0x01, 0x23, 0x82, 0xF8, 0x00, 0x32, 0x42, 0xE7, 0x05, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0x00, 0xBF, 0x70, 0x79, 0x15, 0x00, 0x8C, 0x7F, 0x15, 0x00, 0x7C, 0x7F, 0x15, 0x00, 0x20, 0x62, 0x17, 0x00, -+0x08, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x05, 0xD0, 0x02, 0x2B, 0x07, 0xD0, 0x06, 0x4B, 0xD3, 0xF8, 0x30, 0x31, -+0x18, 0x47, 0x04, 0x4B, 0xD3, 0xF8, 0x08, 0x33, 0x18, 0x47, 0x03, 0xF0, 0x8F, 0xBF, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x08, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x07, 0xD0, 0x02, 0x2B, 0x03, 0xD1, 0x06, 0x4B, -+0xD3, 0xF8, 0x34, 0x34, 0x18, 0x47, 0x04, 0xF0, 0x93, 0xBB, 0x03, 0x4B, 0xD3, 0xF8, 0x00, 0x33, 0x18, 0x47, 0x00, 0xBF, -+0x78, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x07, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x05, 0xD0, 0x02, 0x2B, -+0x01, 0xD0, 0x04, 0xF0, 0x83, 0xBB, 0x04, 0xF0, 0x7B, 0xB8, 0x03, 0x4B, 0xD3, 0xF8, 0x0C, 0x33, 0x18, 0x47, 0x00, 0xBF, -+0x78, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x08, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x07, 0xD0, 0x02, 0x2B, -+0x03, 0xD1, 0x06, 0x4B, 0xD3, 0xF8, 0x38, 0x34, 0x18, 0x47, 0x04, 0xF0, 0x6D, 0xBB, 0x03, 0x4B, 0xD3, 0xF8, 0x04, 0x33, -+0x18, 0x47, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x06, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, -+0x05, 0xD0, 0x02, 0x2B, 0x01, 0xD0, 0x04, 0xF0, 0x5D, 0xBB, 0x04, 0xF0, 0xAD, 0xB9, 0x01, 0xF0, 0x6B, 0xB9, 0x00, 0xBF, -+0x78, 0x36, 0x17, 0x00, 0x08, 0xB5, 0x0C, 0x22, 0x08, 0x23, 0x01, 0x21, 0x40, 0xF2, 0x0D, 0x40, 0x1B, 0xF0, 0xE6, 0xFD, -+0xBD, 0xE8, 0x08, 0x40, 0x1B, 0xF0, 0x12, 0xBE, 0x2D, 0xE9, 0xF0, 0x4F, 0x89, 0xB0, 0x82, 0x46, 0x00, 0x68, 0x05, 0x91, -+0x03, 0x90, 0x07, 0x92, 0x62, 0xB1, 0xB0, 0xFB, 0xF2, 0xF3, 0x11, 0x46, 0x02, 0xFB, 0x13, 0x02, 0x0B, 0x46, 0x00, 0x2A, -+0x40, 0xF0, 0xDE, 0x80, 0x03, 0x9A, 0x04, 0x3B, 0x1A, 0x44, 0x03, 0x92, 0x9A, 0xF8, 0x08, 0x30, 0x00, 0x2B, 0x00, 0xF0, -+0xD2, 0x80, 0x00, 0x23, 0xDF, 0xF8, 0xC0, 0x81, 0xDF, 0xF8, 0xC0, 0x91, 0x00, 0x93, 0x1F, 0x46, 0xD3, 0x46, 0x08, 0xE0, -+0x00, 0x9B, 0x9B, 0xF8, 0x08, 0x20, 0x01, 0x33, 0xDF, 0xB2, 0xBA, 0x42, 0x00, 0x93, 0x40, 0xF2, 0xC0, 0x80, 0x05, 0x9B, -+0xDB, 0xF8, 0x0C, 0x10, 0x33, 0xF8, 0x27, 0x00, 0x03, 0xEB, 0x87, 0x02, 0x00, 0x24, 0x55, 0x88, 0x07, 0xEB, 0x47, 0x02, -+0x01, 0xEB, 0x82, 0x06, 0x41, 0xF8, 0x22, 0x40, 0xB4, 0x80, 0x00, 0x2D, 0xE4, 0xD0, 0x03, 0x1D, 0x01, 0x93, 0x03, 0x9B, -+0x75, 0x80, 0x03, 0xF1, 0x04, 0x0A, 0x02, 0x95, 0xB0, 0x80, 0x55, 0x46, 0xCD, 0xF8, 0x18, 0xB0, 0xA2, 0x46, 0x04, 0x97, -+0x34, 0xE0, 0xD8, 0xF8, 0x04, 0x20, 0x13, 0x44, 0xAB, 0x42, 0x37, 0xD3, 0x04, 0x9B, 0x05, 0xF8, 0x04, 0x3C, 0xD8, 0xF8, -+0x00, 0x30, 0xAB, 0x42, 0x41, 0xD8, 0xD8, 0xF8, 0x04, 0x20, 0x13, 0x44, 0xAB, 0x42, 0x3C, 0xD3, 0x55, 0x23, 0x05, 0xF8, -+0x03, 0x3C, 0xD8, 0xF8, 0x00, 0x30, 0xAB, 0x42, 0x46, 0xD8, 0xD8, 0xF8, 0x04, 0x20, 0x13, 0x44, 0xAB, 0x42, 0x41, 0xD3, -+0x00, 0x23, 0x05, 0xF8, 0x02, 0x3C, 0xD8, 0xF8, 0x00, 0x30, 0xAB, 0x42, 0x4B, 0xD8, 0xD8, 0xF8, 0x04, 0x20, 0x13, 0x44, -+0xAB, 0x42, 0x46, 0xD3, 0xCB, 0xF8, 0x04, 0x70, 0x33, 0x88, 0x01, 0x99, 0x01, 0x33, 0x01, 0x34, 0x33, 0x80, 0x02, 0x9B, -+0xA2, 0xB2, 0x93, 0x42, 0x0D, 0x44, 0x48, 0xD9, 0xD8, 0xF8, 0x00, 0x30, 0xAB, 0x42, 0x57, 0x46, 0xA5, 0xF1, 0x04, 0x0B, -+0xAA, 0x46, 0xC2, 0xD9, 0xD9, 0xF8, 0x00, 0x30, 0xAB, 0x42, 0x04, 0xD8, 0xD9, 0xF8, 0x04, 0x20, 0x13, 0x44, 0xAB, 0x42, -+0xBE, 0xD2, 0x31, 0x48, 0x29, 0x46, 0xFF, 0xF7, 0xE9, 0xF9, 0xD8, 0xF8, 0x00, 0x30, 0xAB, 0x42, 0xBD, 0xD9, 0xD9, 0xF8, -+0x00, 0x30, 0xAB, 0x42, 0x04, 0xD8, 0xD9, 0xF8, 0x04, 0x20, 0x13, 0x44, 0xAB, 0x42, 0xB9, 0xD2, 0x29, 0x48, 0x29, 0x46, -+0xFF, 0xF7, 0xD8, 0xF9, 0xD8, 0xF8, 0x00, 0x30, 0xAB, 0x42, 0xB8, 0xD9, 0xD9, 0xF8, 0x00, 0x30, 0xAB, 0x42, 0x04, 0xD8, -+0xD9, 0xF8, 0x04, 0x20, 0x13, 0x44, 0xAB, 0x42, 0xB4, 0xD2, 0x22, 0x48, 0x29, 0x46, 0xFF, 0xF7, 0xC7, 0xF9, 0xD8, 0xF8, -+0x00, 0x30, 0xAB, 0x42, 0xB3, 0xD9, 0xD9, 0xF8, 0x00, 0x30, 0xAB, 0x42, 0x04, 0xD8, 0xD9, 0xF8, 0x04, 0x20, 0x13, 0x44, -+0xAB, 0x42, 0xAF, 0xD2, 0x29, 0x46, 0x1A, 0x48, 0xFF, 0xF7, 0xB6, 0xF9, 0xAC, 0xE7, 0x0A, 0x46, 0x5D, 0x1E, 0x03, 0x99, -+0xDD, 0xF8, 0x18, 0xB0, 0xAD, 0xB2, 0x05, 0xFB, 0x02, 0x13, 0x05, 0xFB, 0x02, 0x25, 0x48, 0x19, 0x07, 0x99, 0x03, 0x90, -+0x04, 0x33, 0xB3, 0x60, 0x00, 0x29, 0x3F, 0xF4, 0x47, 0xAF, 0xB0, 0xFB, 0xF1, 0xF3, 0x01, 0xFB, 0x13, 0x02, 0x0B, 0x46, -+0x22, 0xB1, 0x8B, 0x1A, 0x03, 0x2B, 0x9C, 0xBF, 0x0A, 0x46, 0x9B, 0x18, 0x03, 0x9A, 0x04, 0x3B, 0x1A, 0x44, 0x03, 0x92, -+0x36, 0xE7, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x8B, 0x1A, 0x03, 0x2B, 0x9C, 0xBF, 0x0A, 0x46, 0x9B, 0x18, 0x1B, 0xE7, -+0xE0, 0x7F, 0x15, 0x00, 0x10, 0x80, 0x15, 0x00, 0x38, 0x80, 0x15, 0x00, 0x64, 0x80, 0x15, 0x00, 0xC8, 0x25, 0x17, 0x00, -+0xE4, 0x25, 0x17, 0x00, 0xF8, 0xB5, 0x06, 0x7A, 0x00, 0x2E, 0x00, 0xF0, 0xBC, 0x80, 0xC5, 0x68, 0x00, 0x2D, 0x00, 0xF0, -+0x82, 0x80, 0x2C, 0x46, 0x01, 0x23, 0x09, 0xE0, 0x22, 0x88, 0xA2, 0xB9, 0x9E, 0x42, 0x0F, 0xD9, 0x03, 0xEB, 0x43, 0x04, -+0x05, 0xEB, 0x84, 0x04, 0x01, 0x33, 0xDB, 0xB2, 0xA0, 0x88, 0x88, 0x42, 0x03, 0xEB, 0x43, 0x02, 0xF0, 0xD2, 0x9E, 0x42, -+0x02, 0xD9, 0x05, 0xEB, 0x82, 0x04, 0xF3, 0xE7, 0x9E, 0x42, 0x00, 0xF0, 0x9E, 0x80, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, -+0x03, 0xD4, 0x72, 0xB6, 0x4E, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x4E, 0x4E, 0x23, 0x88, 0x35, 0x68, 0x6A, 0x1C, 0x32, 0x60, -+0x00, 0x2B, 0x5D, 0xD0, 0x4B, 0x4F, 0xA5, 0x68, 0x3A, 0x68, 0xAA, 0x42, 0x28, 0xD8, 0x79, 0x68, 0x11, 0x44, 0x8D, 0x42, -+0x24, 0xD8, 0x29, 0x68, 0xA1, 0x60, 0x01, 0x3B, 0xAA, 0x42, 0x23, 0x80, 0x32, 0xD8, 0x7B, 0x68, 0x13, 0x44, 0xAB, 0x42, -+0x2E, 0xD3, 0x15, 0xF8, 0x03, 0x1C, 0x55, 0x29, 0x53, 0xD1, 0xAA, 0x23, 0x05, 0xF8, 0x03, 0x3C, 0x3B, 0x68, 0x9D, 0x42, -+0x5D, 0xD3, 0x7A, 0x68, 0x13, 0x44, 0x9D, 0x42, 0x59, 0xD8, 0x01, 0x23, 0x05, 0xF8, 0x02, 0x3C, 0x33, 0x68, 0x00, 0x2B, -+0x34, 0xD0, 0x36, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x33, 0x60, 0x7B, 0xBB, 0x72, 0xB3, 0x35, 0xE0, 0x35, 0x48, 0x01, 0x68, -+0x8D, 0x42, 0x03, 0xD3, 0x40, 0x68, 0x01, 0x44, 0x8D, 0x42, 0xD2, 0xD9, 0x29, 0x46, 0x32, 0x48, 0xFF, 0xF7, 0x12, 0xF9, -+0x23, 0x88, 0x3A, 0x68, 0x00, 0x21, 0x01, 0x3B, 0xAA, 0x42, 0xA1, 0x60, 0x23, 0x80, 0xCC, 0xD9, 0x2B, 0x48, 0x03, 0x68, -+0xAB, 0x42, 0x1F, 0xD8, 0x41, 0x68, 0x19, 0x44, 0xA9, 0x42, 0x1B, 0xD3, 0x15, 0xF8, 0x03, 0x1C, 0x55, 0x29, 0x1C, 0xD1, -+0xAA, 0x42, 0x37, 0xD9, 0x42, 0x68, 0x13, 0x44, 0x9D, 0x42, 0xC2, 0xD9, 0x29, 0x46, 0x24, 0x48, 0xFF, 0xF7, 0xF4, 0xF8, -+0xC0, 0xE7, 0x23, 0x48, 0xFF, 0xF7, 0xF0, 0xF8, 0x28, 0x46, 0xF8, 0xBD, 0xC2, 0xB1, 0x1A, 0x4B, 0x35, 0x60, 0x1B, 0x68, -+0xA5, 0xB9, 0x9B, 0xB1, 0x62, 0xB6, 0xF5, 0xE7, 0x29, 0x46, 0x1D, 0x48, 0xFF, 0xF7, 0xE2, 0xF8, 0x00, 0x21, 0x33, 0x68, -+0x33, 0xB1, 0x13, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x33, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x17, 0x48, 0x2A, 0x46, -+0xFF, 0xF7, 0xD4, 0xF8, 0x00, 0x25, 0x28, 0x46, 0xF8, 0xBD, 0x0F, 0x4A, 0x13, 0x68, 0x9D, 0x42, 0x03, 0xD3, 0x52, 0x68, -+0x13, 0x44, 0x9D, 0x42, 0x9D, 0xD9, 0x29, 0x46, 0x10, 0x48, 0xFF, 0xF7, 0xC5, 0xF8, 0x9B, 0xE7, 0x79, 0x68, 0x0A, 0x44, -+0x95, 0x42, 0x8A, 0xD9, 0x9D, 0x42, 0xC5, 0xD3, 0xC0, 0xE7, 0x0C, 0x48, 0xFF, 0xF7, 0xBA, 0xF8, 0x00, 0x25, 0xC7, 0xE7, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xC8, 0x25, 0x17, 0x00, 0xE4, 0x25, 0x17, 0x00, 0xCC, 0x80, 0x15, 0x00, -+0x10, 0x80, 0x15, 0x00, 0x98, 0x80, 0x15, 0x00, 0x00, 0x81, 0x15, 0x00, 0x28, 0x81, 0x15, 0x00, 0x38, 0x80, 0x15, 0x00, -+0xB4, 0x80, 0x15, 0x00, 0x00, 0x29, 0x00, 0xF0, 0x0F, 0x81, 0x2D, 0xE9, 0xF8, 0x43, 0x03, 0x68, 0x8B, 0x42, 0x05, 0x46, -+0x0C, 0x46, 0x59, 0xD8, 0x42, 0x68, 0x13, 0x44, 0x99, 0x42, 0x55, 0xD8, 0x83, 0x4F, 0x3B, 0x68, 0x99, 0x42, 0x55, 0xD3, -+0x7A, 0x68, 0x13, 0x44, 0x99, 0x42, 0x51, 0xD8, 0x14, 0xF8, 0x04, 0x6C, 0x2B, 0x7A, 0xB3, 0x42, 0x48, 0xD9, 0xD5, 0xF8, -+0x0C, 0x80, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x7A, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x7A, 0x4D, -+0x38, 0x68, 0x2B, 0x68, 0x84, 0x42, 0x03, 0xF1, 0x01, 0x03, 0x2B, 0x60, 0x25, 0xD3, 0x7B, 0x68, 0x03, 0x44, 0x9C, 0x42, -+0x21, 0xD8, 0x14, 0xF8, 0x03, 0x9C, 0xB9, 0xF1, 0xAA, 0x0F, 0x00, 0xF0, 0xAB, 0x80, 0xB9, 0xF1, 0xFF, 0x0F, 0x20, 0xD1, -+0x7B, 0x68, 0x18, 0x44, 0x84, 0x42, 0x00, 0xF2, 0xA1, 0x80, 0x14, 0xF8, 0x02, 0x0C, 0x01, 0x38, 0xC0, 0xB2, 0x04, 0xF8, -+0x02, 0x0C, 0x00, 0x28, 0x47, 0xD0, 0x2B, 0x68, 0x33, 0xB1, 0x67, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x40, 0xB2, 0xBD, 0xE8, 0xF8, 0x83, 0x64, 0x4B, 0x1A, 0x68, 0x94, 0x42, 0x1E, 0xD2, 0x63, 0x48, -+0x21, 0x46, 0xFF, 0xF7, 0x47, 0xF8, 0x2B, 0x68, 0x33, 0xB1, 0x5D, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x4F, 0xF0, 0xFF, 0x30, 0xBD, 0xE8, 0xF8, 0x83, 0x59, 0x4B, 0x1A, 0x68, 0x94, 0x42, 0x03, 0xD3, -+0x5B, 0x68, 0x1A, 0x44, 0x94, 0x42, 0xA5, 0xD9, 0x57, 0x48, 0x21, 0x46, 0xFF, 0xF7, 0x2E, 0xF8, 0x00, 0x26, 0xA1, 0xE7, -+0x59, 0x68, 0x11, 0x44, 0x8C, 0x42, 0xDC, 0xD8, 0x14, 0xF8, 0x03, 0x9C, 0xB9, 0xF1, 0xAA, 0x0F, 0x6C, 0xD0, 0xB9, 0xF1, -+0xFF, 0x0F, 0xD8, 0xD1, 0x84, 0x42, 0xB5, 0xD2, 0x1A, 0x68, 0x94, 0x42, 0x03, 0xD3, 0x5B, 0x68, 0x1A, 0x44, 0x94, 0x42, -+0xB3, 0xD9, 0x4B, 0x48, 0x21, 0x46, 0xFF, 0xF7, 0x13, 0xF8, 0xB9, 0xF1, 0xFF, 0x0F, 0x5D, 0xD0, 0x06, 0xEB, 0x46, 0x06, -+0x08, 0xEB, 0x86, 0x09, 0x38, 0xF8, 0x26, 0x20, 0xB9, 0xF8, 0x02, 0x30, 0x9A, 0x42, 0x4F, 0xEA, 0x86, 0x06, 0xBC, 0xD2, -+0x3B, 0x68, 0x9C, 0x42, 0x31, 0xD3, 0x7A, 0x68, 0x13, 0x44, 0x9C, 0x42, 0x2D, 0xD8, 0x55, 0x23, 0x04, 0xF8, 0x03, 0x3C, -+0x3B, 0x68, 0x9C, 0x42, 0x1A, 0xD3, 0x7A, 0x68, 0x13, 0x44, 0x9C, 0x42, 0x16, 0xD8, 0xD9, 0xF8, 0x08, 0x30, 0x23, 0x60, -+0x38, 0xF8, 0x06, 0x30, 0x28, 0x68, 0xC9, 0xF8, 0x08, 0x40, 0x01, 0x33, 0x28, 0xF8, 0x06, 0x30, 0x38, 0xB1, 0x2E, 0x4B, -+0x01, 0x38, 0x1B, 0x68, 0x28, 0x60, 0x10, 0xB9, 0x0B, 0xB1, 0x62, 0xB6, 0xA2, 0xE7, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, -+0x2A, 0x4A, 0x13, 0x68, 0x9C, 0x42, 0x03, 0xD3, 0x52, 0x68, 0x13, 0x44, 0x9C, 0x42, 0xE0, 0xD9, 0x21, 0x46, 0x2A, 0x48, -+0xFE, 0xF7, 0xD0, 0xFF, 0xDE, 0xE7, 0x24, 0x4A, 0x13, 0x68, 0x9C, 0x42, 0x03, 0xD3, 0x52, 0x68, 0x13, 0x44, 0x9C, 0x42, -+0xC9, 0xD9, 0x21, 0x46, 0x24, 0x48, 0xFE, 0xF7, 0xC3, 0xFF, 0xC7, 0xE7, 0x1D, 0x4B, 0xA1, 0xE7, 0x14, 0xF8, 0x02, 0x0C, -+0x01, 0x38, 0xC0, 0xB2, 0x04, 0xF8, 0x02, 0x0C, 0x00, 0x28, 0x7F, 0xF4, 0x5C, 0xAF, 0xA5, 0xE7, 0x84, 0x42, 0xBF, 0xF4, -+0x4B, 0xAF, 0x96, 0xE7, 0x3B, 0x68, 0x9C, 0x42, 0x11, 0xD3, 0x7A, 0x68, 0x13, 0x44, 0x9C, 0x42, 0x0D, 0xD8, 0x01, 0x23, -+0x04, 0xF8, 0x02, 0x3C, 0x2B, 0x68, 0x33, 0xB1, 0x0D, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0x01, 0x20, 0x60, 0xE7, 0x0B, 0x4A, 0x13, 0x68, 0x9C, 0x42, 0x03, 0xD3, 0x52, 0x68, 0x13, 0x44, 0x9C, 0x42, -+0xE9, 0xD9, 0x21, 0x46, 0x0C, 0x48, 0xFE, 0xF7, 0x91, 0xFF, 0xE7, 0xE7, 0x4F, 0xF0, 0xFF, 0x30, 0x70, 0x47, 0x00, 0xBF, -+0xC8, 0x25, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xE4, 0x25, 0x17, 0x00, 0x00, 0x81, 0x15, 0x00, -+0x50, 0x81, 0x15, 0x00, 0x80, 0x81, 0x15, 0x00, 0x64, 0x80, 0x15, 0x00, 0x10, 0x80, 0x15, 0x00, 0x38, 0x80, 0x15, 0x00, -+0x0B, 0x4A, 0x13, 0x68, 0x83, 0x42, 0x05, 0xD8, 0x52, 0x68, 0x13, 0x44, 0x98, 0x42, 0x01, 0xD8, 0x01, 0x20, 0x70, 0x47, -+0x07, 0x4A, 0x13, 0x68, 0x98, 0x42, 0x06, 0xD3, 0x52, 0x68, 0x13, 0x44, 0x98, 0x42, 0x8C, 0xBF, 0x00, 0x20, 0x01, 0x20, -+0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0xBF, 0xC8, 0x25, 0x17, 0x00, 0xE4, 0x25, 0x17, 0x00, 0x10, 0x4B, 0x70, 0xB5, -+0x10, 0x4C, 0xDC, 0x60, 0x15, 0x46, 0x0E, 0x46, 0x03, 0x24, 0x01, 0x46, 0x20, 0x22, 0x18, 0x46, 0x5D, 0x60, 0x1C, 0x72, -+0x1E, 0x60, 0xFF, 0xF7, 0xCD, 0xFC, 0x0B, 0x4B, 0x4F, 0xF4, 0x80, 0x32, 0x01, 0x21, 0x4F, 0xF0, 0x02, 0x15, 0x04, 0x24, -+0x4F, 0xF4, 0x80, 0x20, 0x5A, 0x60, 0x00, 0x22, 0xC3, 0xE9, 0x05, 0x40, 0xDD, 0x60, 0x19, 0x60, 0x99, 0x60, 0x1A, 0x61, -+0x9A, 0x83, 0x70, 0xBD, 0xE4, 0x25, 0x17, 0x00, 0xF4, 0x25, 0x17, 0x00, 0xA8, 0x25, 0x17, 0x00, 0x38, 0xB5, 0x0F, 0x4B, -+0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x05, 0x46, 0x0D, 0xD0, 0x0D, 0x48, 0x7C, 0x21, 0xFF, 0xF7, 0xAB, 0xFD, 0x04, 0x46, -+0x2C, 0xB1, 0x20, 0x46, 0xFF, 0xF7, 0xAC, 0xFF, 0x38, 0xB1, 0x04, 0xF8, 0x01, 0x5C, 0x20, 0x46, 0x38, 0xBD, 0x00, 0xF0, -+0xC3, 0xF9, 0x04, 0x46, 0xF2, 0xE7, 0x21, 0x46, 0x04, 0x48, 0xFE, 0xF7, 0x17, 0xFF, 0x20, 0x46, 0x38, 0xBD, 0x00, 0xBF, -+0x78, 0x36, 0x17, 0x00, 0xE4, 0x25, 0x17, 0x00, 0xAC, 0x81, 0x15, 0x00, 0x10, 0xB5, 0x04, 0x46, 0xFF, 0xF7, 0x92, 0xFF, -+0x98, 0xB1, 0x31, 0x4B, 0x14, 0xF8, 0x04, 0x2C, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x23, 0xD0, 0x02, 0x2B, 0x2A, 0xD0, -+0x03, 0x2B, 0x15, 0xD1, 0x2C, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x30, 0xDB, 0x02, 0x2A, 0x30, 0xD0, -+0x10, 0xBD, 0x29, 0x48, 0x21, 0x46, 0xFE, 0xF7, 0xF1, 0xFE, 0x25, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x11, 0xD0, -+0x02, 0x2B, 0x18, 0xD0, 0x03, 0x2B, 0x29, 0xD0, 0x20, 0x46, 0xFF, 0xF7, 0x6D, 0xFF, 0x90, 0xB3, 0x21, 0x46, 0x21, 0x48, -+0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0x3C, 0xBE, 0x02, 0x2A, 0x0F, 0xD0, 0x00, 0x2A, 0xE3, 0xD1, 0x20, 0x46, 0xBD, 0xE8, -+0x10, 0x40, 0x00, 0xF0, 0x9B, 0xB9, 0x02, 0x2A, 0x26, 0xD0, 0x00, 0x2A, 0xDA, 0xD1, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, -+0x03, 0xF0, 0xF2, 0xB9, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x45, 0xB9, 0x02, 0x2A, 0x0C, 0xD1, 0x13, 0x4B, -+0x20, 0x46, 0xD3, 0xF8, 0xE8, 0x34, 0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0x0C, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xC1, 0xDA, 0xBD, 0xE8, 0x10, 0x40, 0x0C, 0x49, 0x0D, 0x48, 0xBE, 0x22, 0x1D, 0xF0, 0xF5, 0xBA, 0x21, 0x46, -+0x0B, 0x48, 0xFE, 0xF7, 0xAD, 0xFE, 0xC7, 0xE7, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x03, 0xF0, 0x21, 0xB9, 0x00, 0xBF, -+0x78, 0x36, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x50, 0x81, 0x15, 0x00, 0xE4, 0x25, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xD4, 0x81, 0x15, 0x00, 0xE4, 0x81, 0x15, 0x00, 0x30, 0xB5, 0x1A, 0x4C, 0x1A, 0x4A, 0x23, 0x68, -+0x1A, 0x48, 0x5D, 0x88, 0x99, 0x88, 0xB2, 0xF8, 0xD4, 0x20, 0x85, 0xB0, 0x04, 0x3A, 0xAD, 0xF8, 0x02, 0x50, 0xDD, 0x88, -+0xAD, 0xF8, 0x06, 0x10, 0x19, 0x89, 0xAD, 0xF8, 0x0A, 0x50, 0xD3, 0xE9, 0x05, 0x35, 0xAD, 0xF8, 0x0E, 0x10, 0x01, 0x21, -+0x03, 0x60, 0x01, 0x72, 0x10, 0x4B, 0x45, 0x60, 0x0C, 0x21, 0xC3, 0x60, 0xAD, 0xF8, 0x0C, 0x20, 0x40, 0xF2, 0x3C, 0x63, -+0xAD, 0xF8, 0x00, 0x10, 0x7C, 0x25, 0x69, 0x46, 0x20, 0x22, 0xAD, 0xF8, 0x08, 0x30, 0xAD, 0xF8, 0x04, 0x50, 0xFF, 0xF7, -+0xE9, 0xFB, 0x23, 0x68, 0x01, 0xA8, 0xD3, 0xE9, 0x07, 0x12, 0xFF, 0xF7, 0x07, 0xFF, 0x05, 0xB0, 0x30, 0xBD, 0x00, 0xBF, -+0x78, 0x36, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0xC8, 0x25, 0x17, 0x00, 0xD8, 0x25, 0x17, 0x00, 0xF8, 0xB5, 0x0C, 0x4D, -+0x0C, 0x48, 0x1B, 0xF0, 0x3F, 0xFE, 0x2B, 0x68, 0x5B, 0x88, 0x83, 0xB1, 0x0A, 0x4F, 0x09, 0x4E, 0x00, 0x24, 0x0C, 0x21, -+0x38, 0x46, 0xFF, 0xF7, 0xCB, 0xFC, 0x01, 0x46, 0x30, 0x46, 0x1B, 0xF0, 0x35, 0xFE, 0x2B, 0x68, 0x01, 0x34, 0x5A, 0x88, -+0xA3, 0xB2, 0x9A, 0x42, 0xF1, 0xD8, 0xF8, 0xBD, 0x78, 0x36, 0x17, 0x00, 0x08, 0x60, 0x17, 0x00, 0xC8, 0x25, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x41, 0xDF, 0xF8, 0x4C, 0x80, 0x0F, 0x48, 0x1B, 0xF0, 0x1D, 0xFE, 0xD8, 0xF8, 0x00, 0x30, 0x1B, 0x89, -+0xB3, 0xB1, 0x0D, 0x4D, 0x0D, 0x4F, 0x0B, 0x4E, 0x00, 0x24, 0x4F, 0xF4, 0xD7, 0x61, 0x38, 0x46, 0xFF, 0xF7, 0xA6, 0xFC, -+0x01, 0x46, 0x30, 0x46, 0x1B, 0xF0, 0x10, 0xFE, 0xD8, 0xF8, 0x00, 0x20, 0x2B, 0x68, 0x11, 0x89, 0x01, 0x34, 0xA2, 0xB2, -+0x01, 0x33, 0x91, 0x42, 0x2B, 0x60, 0xEC, 0xD8, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x60, 0x17, 0x00, 0x18, 0x26, 0x17, 0x00, -+0xE4, 0x25, 0x17, 0x00, 0x78, 0x36, 0x17, 0x00, 0xF8, 0xB5, 0x0C, 0x4D, 0x0C, 0x48, 0x1B, 0xF0, 0xF3, 0xFD, 0x2B, 0x68, -+0x9B, 0x88, 0x83, 0xB1, 0x0A, 0x4F, 0x09, 0x4E, 0x00, 0x24, 0x7C, 0x21, 0x38, 0x46, 0xFF, 0xF7, 0x7F, 0xFC, 0x01, 0x46, -+0x30, 0x46, 0x1B, 0xF0, 0xE9, 0xFD, 0x2B, 0x68, 0x01, 0x34, 0x9A, 0x88, 0xA3, 0xB2, 0x9A, 0x42, 0xF1, 0xD8, 0xF8, 0xBD, -+0x78, 0x36, 0x17, 0x00, 0x20, 0x60, 0x17, 0x00, 0xE4, 0x25, 0x17, 0x00, 0x10, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, -+0x03, 0xD4, 0x72, 0xB6, 0x09, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x09, 0x4C, 0x09, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, -+0x1B, 0xF0, 0x10, 0xFE, 0x23, 0x68, 0x33, 0xB1, 0x03, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0x10, 0xBD, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x08, 0x60, 0x17, 0x00, 0x10, 0xB5, 0x01, 0x46, -+0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0A, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x09, 0x4C, 0x0A, 0x48, -+0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x1B, 0xF0, 0xAB, 0xFD, 0x23, 0x68, 0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, -+0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x10, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x08, 0x60, 0x17, 0x00, 0x10, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0C, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x0C, 0x4C, 0x0C, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x1B, 0xF0, 0xCE, 0xFD, 0x18, 0xB1, 0x0A, 0x4A, -+0x13, 0x68, 0x01, 0x3B, 0x13, 0x60, 0x23, 0x68, 0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x10, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x00, 0x60, 0x17, 0x00, -+0x18, 0x26, 0x17, 0x00, 0x10, 0xB5, 0x01, 0x46, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0C, 0x4B, -+0x01, 0x22, 0x1A, 0x60, 0x0B, 0x4C, 0x0C, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x1B, 0xF0, 0x61, 0xFD, 0x0A, 0x49, -+0x23, 0x68, 0x0A, 0x68, 0x01, 0x32, 0x0A, 0x60, 0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x10, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x00, 0x60, 0x17, 0x00, -+0x18, 0x26, 0x17, 0x00, 0x10, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x09, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x09, 0x4C, 0x09, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x1B, 0xF0, 0x7E, 0xFD, 0x23, 0x68, 0x33, 0xB1, -+0x03, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x10, 0xBD, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x20, 0x60, 0x17, 0x00, 0x10, 0xB5, 0x01, 0x46, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, -+0x72, 0xB6, 0x0A, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x09, 0x4C, 0x0A, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x1B, 0xF0, -+0x19, 0xFD, 0x23, 0x68, 0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, -+0x10, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x20, 0x60, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, -+0x41, 0x4B, 0xDF, 0xF8, 0x20, 0xB1, 0x1B, 0x68, 0x40, 0x4D, 0x1F, 0x8E, 0xDF, 0xF8, 0x18, 0x91, 0xDF, 0xF8, 0x18, 0x81, -+0x8B, 0x89, 0x0C, 0x46, 0x06, 0x46, 0x9F, 0x42, 0x6A, 0xD9, 0xD8, 0xF8, 0x00, 0x30, 0x04, 0x2B, 0x63, 0xD9, 0xD6, 0xE9, -+0x01, 0x03, 0x1B, 0x69, 0x98, 0x47, 0x82, 0x46, 0x00, 0x28, 0x62, 0xD0, 0xFF, 0xF7, 0x0E, 0xFF, 0x00, 0x28, 0x4A, 0xD0, -+0x00, 0x22, 0x34, 0x4B, 0x02, 0x60, 0x1B, 0x68, 0x42, 0x60, 0x53, 0x44, 0x82, 0x60, 0x03, 0x60, 0xEF, 0xF3, 0x10, 0x83, -+0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x2F, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x2E, 0x4A, 0xDB, 0xF8, 0x00, 0x30, 0xD2, 0xF8, -+0x00, 0xC0, 0x43, 0xF0, 0x01, 0x03, 0x0C, 0xF1, 0x01, 0x01, 0x11, 0x60, 0xCB, 0xF8, 0x00, 0x30, 0xDB, 0xF8, 0x00, 0x30, -+0x9B, 0x07, 0xFB, 0xD4, 0x2B, 0x68, 0x1B, 0xBB, 0xD9, 0xF8, 0x00, 0x30, 0xC9, 0xF8, 0x00, 0x00, 0x2B, 0x68, 0xB4, 0xF8, -+0x0C, 0xE0, 0x60, 0x60, 0x0E, 0xF1, 0x01, 0x0E, 0x98, 0xB2, 0x01, 0x30, 0x1F, 0xFA, 0x8E, 0xF3, 0xA3, 0x81, 0x28, 0x60, -+0xDB, 0xF8, 0x00, 0x00, 0x20, 0xF0, 0x01, 0x00, 0xCB, 0xF8, 0x00, 0x00, 0x00, 0x29, 0xB4, 0xD0, 0x18, 0x49, 0xC2, 0xF8, -+0x00, 0xC0, 0x0A, 0x68, 0xBC, 0xF1, 0x00, 0x0F, 0xAD, 0xD1, 0x00, 0x2A, 0xAB, 0xD0, 0x62, 0xB6, 0xA3, 0x89, 0xA8, 0xE7, -+0x63, 0x68, 0x00, 0x2B, 0xDC, 0xD0, 0x58, 0x60, 0xDA, 0xE7, 0x12, 0x48, 0xFE, 0xF7, 0xAA, 0xFC, 0xD6, 0xE9, 0x01, 0x03, -+0x51, 0x46, 0x5B, 0x69, 0x98, 0x47, 0x09, 0x4B, 0xA2, 0x89, 0x1B, 0x68, 0x5B, 0x8E, 0x9A, 0x42, 0x02, 0xD2, 0x04, 0x20, -+0x1B, 0xF0, 0xEA, 0xFB, 0x01, 0x20, 0xBD, 0xE8, 0xF8, 0x8F, 0xD8, 0xF8, 0x00, 0x10, 0x08, 0x48, 0xFE, 0xF7, 0x94, 0xFC, -+0xED, 0xE7, 0x00, 0xBF, 0xC8, 0x35, 0x17, 0x00, 0x64, 0x00, 0x24, 0x40, 0x34, 0x1A, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x24, 0x82, 0x15, 0x00, 0x0C, 0x82, 0x15, 0x00, 0x60, 0x00, 0x24, 0x40, 0x68, 0x00, 0x24, 0x40, -+0x18, 0x26, 0x17, 0x00, 0x08, 0xB5, 0x03, 0x4B, 0xD3, 0xF8, 0xF8, 0x32, 0x98, 0x47, 0x01, 0x20, 0x08, 0xBD, 0x00, 0xBF, -+0x88, 0x1A, 0x17, 0x00, 0x10, 0xB5, 0x0A, 0x4A, 0x0A, 0x49, 0x0B, 0x4C, 0x00, 0x23, 0xC2, 0xE9, 0x02, 0x03, 0xC2, 0xE9, -+0x04, 0x33, 0xC2, 0xE9, 0x00, 0x33, 0xC1, 0xE9, 0x00, 0x33, 0x8B, 0x81, 0x8B, 0x60, 0x8B, 0x73, 0x10, 0x46, 0xD4, 0xF8, -+0x10, 0x31, 0x98, 0x47, 0x01, 0x20, 0x10, 0xBD, 0x28, 0x60, 0x17, 0x00, 0x10, 0x60, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x4F, 0x89, 0xB0, 0xB9, 0x4B, 0xD3, 0xF8, 0x14, 0x35, 0x00, 0x2B, 0x00, 0xF0, 0x30, 0x81, 0xEF, 0xF3, -+0x10, 0x83, 0xD8, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0xB4, 0x4A, 0x01, 0x23, 0x13, 0x60, 0xDF, 0xF8, 0x04, 0x93, 0xB1, 0x4B, -+0xD9, 0xF8, 0x00, 0x20, 0xD3, 0xF8, 0x14, 0x35, 0x51, 0x1C, 0xC9, 0xF8, 0x00, 0x10, 0x31, 0xB1, 0xAD, 0x49, 0xC9, 0xF8, -+0x00, 0x20, 0x09, 0x68, 0x0A, 0xB9, 0x01, 0xB1, 0x62, 0xB6, 0x93, 0xF8, 0x0C, 0xB0, 0x5A, 0x7B, 0x5C, 0x68, 0x05, 0x92, -+0xBB, 0xF1, 0x00, 0x0F, 0x00, 0xF0, 0x38, 0x81, 0x00, 0x2C, 0x00, 0xF0, 0x35, 0x81, 0x9B, 0x68, 0x00, 0x2B, 0x00, 0xF0, -+0x31, 0x81, 0xA3, 0x4B, 0x07, 0x93, 0x9B, 0x89, 0x1F, 0xFA, 0x8B, 0xF2, 0x5B, 0x45, 0x06, 0x92, 0xC0, 0xF0, 0x5C, 0x81, -+0xDF, 0xF8, 0xB0, 0xA2, 0x00, 0x26, 0xAA, 0xE0, 0xD4, 0xE9, 0x00, 0x53, 0x03, 0x93, 0x6B, 0x1E, 0xB3, 0xF5, 0xE8, 0x1F, -+0x27, 0xD3, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x95, 0x4A, 0x01, 0x23, 0x13, 0x60, 0x03, 0x9B, -+0xD9, 0xF8, 0x00, 0x70, 0x01, 0x93, 0x23, 0x68, 0x93, 0x48, 0x00, 0x93, 0x5A, 0x46, 0x23, 0x46, 0x31, 0x46, 0x01, 0x37, -+0xC9, 0xF8, 0x00, 0x70, 0x1C, 0xF0, 0xC4, 0xFD, 0x4F, 0xF4, 0x80, 0x71, 0xA4, 0xF1, 0x80, 0x00, 0x1D, 0xF0, 0x9C, 0xF9, -+0xD9, 0xF8, 0x00, 0x30, 0x3B, 0xB1, 0x88, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xC9, 0xF8, 0x00, 0x30, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0x20, 0x46, 0xFF, 0xF7, 0x1A, 0xFE, 0x6B, 0x7E, 0x2F, 0x7E, 0x09, 0x2B, 0x09, 0xD8, 0x83, 0x4A, 0x4F, 0xF4, -+0x1E, 0x71, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, 0x25, 0x30, 0x00, 0x2B, 0x00, 0xF0, 0xDD, 0x80, 0x6B, 0x8B, 0x13, 0xF0, -+0x08, 0x0F, 0x7E, 0x4B, 0x40, 0xF0, 0xBC, 0x80, 0x1A, 0x46, 0x04, 0x93, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x07, 0x23, -+0x93, 0xF8, 0x64, 0x30, 0x00, 0x2B, 0x00, 0xF0, 0xCC, 0x80, 0x95, 0xF8, 0x16, 0x80, 0xB8, 0xF1, 0x05, 0x0F, 0x00, 0xF2, -+0x09, 0x81, 0x75, 0x4C, 0x75, 0x48, 0x1B, 0xF0, 0xF1, 0xFB, 0x23, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0x46, -+0xC0, 0xF2, 0xA5, 0x80, 0xE1, 0x8B, 0x71, 0x4B, 0xE2, 0x6C, 0x13, 0xF8, 0x08, 0xC0, 0x21, 0xF0, 0x01, 0x01, 0x00, 0x23, -+0xE1, 0x83, 0x63, 0x64, 0x13, 0x61, 0xE3, 0x62, 0x6B, 0x4B, 0x29, 0x46, 0x0C, 0xF1, 0x01, 0x0C, 0x1C, 0x22, 0x20, 0x1D, -+0x03, 0xF8, 0x08, 0xC0, 0x2F, 0xF0, 0x8A, 0xFA, 0xE1, 0x8B, 0xDA, 0xF8, 0x00, 0x00, 0x00, 0x23, 0x21, 0xF4, 0x00, 0x42, -+0x84, 0xF8, 0x42, 0x30, 0x22, 0xF0, 0x02, 0x02, 0x2D, 0x1A, 0x63, 0x62, 0x23, 0x65, 0x0B, 0x07, 0xE2, 0x83, 0xA5, 0x64, -+0x00, 0xF1, 0x87, 0x80, 0x63, 0x7F, 0x09, 0x2B, 0x0E, 0xD8, 0xE2, 0x7E, 0x08, 0x2A, 0x0B, 0xD8, 0x03, 0xEB, 0xC3, 0x03, -+0x13, 0x44, 0x5A, 0x49, 0xA0, 0x88, 0x03, 0xF6, 0x0E, 0x03, 0x51, 0xF8, 0x23, 0x20, 0x02, 0x44, 0x41, 0xF8, 0x23, 0x20, -+0xA4, 0x20, 0x04, 0x9B, 0x00, 0xFB, 0x07, 0x80, 0x99, 0x30, 0x21, 0x46, 0x03, 0xEB, 0xC0, 0x00, 0x03, 0x9C, 0x1B, 0xF0, -+0x61, 0xFB, 0x01, 0x36, 0xF3, 0xB2, 0x9B, 0x45, 0x16, 0xD9, 0x05, 0x9B, 0x00, 0x2B, 0x3F, 0xF4, 0x51, 0xAF, 0x4D, 0x49, -+0x4F, 0xF4, 0x80, 0x60, 0x1C, 0xF0, 0x7E, 0xFD, 0x20, 0x46, 0xD4, 0xE9, 0x00, 0x54, 0xFF, 0xF7, 0x93, 0xFD, 0xDA, 0xF8, -+0x00, 0x00, 0x01, 0x36, 0x28, 0x1A, 0xFF, 0xF7, 0x4B, 0xFC, 0xF3, 0xB2, 0x9B, 0x45, 0xE8, 0xD8, 0x07, 0x9A, 0x06, 0x99, -+0x93, 0x89, 0x5B, 0x1A, 0x93, 0x81, 0xEF, 0xF3, 0x10, 0x83, 0xD9, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x35, 0x4A, 0x01, 0x23, -+0x13, 0x60, 0xD9, 0xF8, 0x00, 0x30, 0x3D, 0x48, 0x01, 0x33, 0xC9, 0xF8, 0x00, 0x30, 0x1B, 0xF0, 0x75, 0xFB, 0x2F, 0x49, -+0x91, 0xF8, 0x11, 0x35, 0xD1, 0xF8, 0x14, 0x25, 0x01, 0x3B, 0x81, 0xF8, 0x11, 0x35, 0x00, 0x2A, 0x00, 0xF0, 0x94, 0x80, -+0xD9, 0xF8, 0x00, 0x30, 0x00, 0x2B, 0x3F, 0xF4, 0xDC, 0xAE, 0x28, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xC9, 0xF8, 0x00, 0x30, -+0x00, 0x2B, 0x7F, 0xF4, 0xD4, 0xAE, 0x00, 0x2A, 0x3F, 0xF4, 0xD1, 0xAE, 0x62, 0xB6, 0x21, 0x4B, 0xD3, 0xF8, 0x14, 0x35, -+0x00, 0x2B, 0x7F, 0xF4, 0xD0, 0xAE, 0x40, 0x20, 0x1B, 0xF0, 0x6A, 0xFA, 0x04, 0x20, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, -+0x1B, 0xF0, 0x64, 0xBA, 0x1F, 0x4C, 0x04, 0x93, 0x4F, 0xF0, 0x05, 0x08, 0x50, 0xE7, 0x00, 0x28, 0x7F, 0xF4, 0x58, 0xAF, -+0x21, 0x49, 0x22, 0x48, 0x4F, 0xF4, 0xE5, 0x72, 0x1C, 0xF0, 0x4C, 0xFF, 0x50, 0xE7, 0x04, 0x9B, 0x4F, 0xF4, 0xA4, 0x60, -+0x00, 0xFB, 0x07, 0x30, 0x21, 0x46, 0x00, 0xF5, 0xA3, 0x60, 0x03, 0x9C, 0x1B, 0xF0, 0xEC, 0xFA, 0x89, 0xE7, 0xDA, 0xF8, -+0x00, 0x00, 0x03, 0x9C, 0x28, 0x1A, 0xFF, 0xF7, 0xE7, 0xFB, 0x82, 0xE7, 0x0A, 0x4B, 0x16, 0x48, 0x07, 0x93, 0x1D, 0x46, -+0xFE, 0xF7, 0xEE, 0xFA, 0xAB, 0x89, 0x1F, 0xFA, 0x8B, 0xF2, 0x5B, 0x45, 0x06, 0x92, 0x27, 0xD3, 0xBB, 0xF1, 0x00, 0x0F, -+0x7F, 0xF4, 0xC8, 0xAE, 0x8C, 0xE7, 0x00, 0xBF, 0x58, 0x58, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x10, 0x60, 0x17, 0x00, -+0x50, 0x82, 0x15, 0x00, 0x68, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x20, 0x58, 0x17, 0x00, -+0x74, 0x28, 0x17, 0x00, 0x7C, 0x36, 0x17, 0x00, 0xB4, 0x82, 0x15, 0x00, 0x6C, 0x5D, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x9C, 0x82, 0x15, 0x00, 0x34, 0x82, 0x15, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x34, 0x1A, 0x17, 0x00, 0x10, 0x48, 0xFE, 0xF7, -+0xBD, 0xFA, 0xBB, 0xF1, 0x00, 0x0F, 0x7F, 0xF4, 0x9D, 0xAE, 0x61, 0xE7, 0x0D, 0x48, 0x0E, 0x4C, 0x1C, 0xF0, 0x7E, 0xFC, -+0x80, 0x21, 0xA5, 0xF1, 0x40, 0x00, 0x1D, 0xF0, 0x57, 0xF8, 0x23, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xBF, 0xF6, -+0xE9, 0xAE, 0x08, 0x49, 0x08, 0x48, 0x4F, 0xF4, 0xE3, 0x72, 0x1C, 0xF0, 0xE7, 0xFE, 0xE1, 0xE6, 0x20, 0x20, 0x1B, 0xF0, -+0x11, 0xFA, 0x67, 0xE7, 0x44, 0x82, 0x15, 0x00, 0x74, 0x82, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x88, 0x82, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0xDF, 0xF8, 0x24, 0x91, 0xDF, 0xF8, 0x24, 0x81, 0x42, 0x4F, 0x43, 0x4B, -+0xD3, 0xF8, 0xA0, 0x27, 0x00, 0x2A, 0x5E, 0xD0, 0x15, 0x7B, 0xD2, 0xF8, 0x04, 0xA0, 0x56, 0x7B, 0x65, 0xB3, 0x4F, 0xF0, -+0x00, 0x0B, 0x11, 0xE0, 0xDA, 0xE9, 0x00, 0x4A, 0xFF, 0xF7, 0xB0, 0xFC, 0x20, 0x46, 0xFD, 0xF7, 0x03, 0xFB, 0xD8, 0xF8, -+0x00, 0x00, 0x0B, 0xF1, 0x01, 0x0B, 0x20, 0x1A, 0xFF, 0xF7, 0x64, 0xFB, 0x5F, 0xFA, 0x8B, 0xF1, 0xA9, 0x42, 0x17, 0xD2, -+0x50, 0x46, 0x39, 0x46, 0x00, 0x2E, 0xE9, 0xD0, 0x4F, 0xF4, 0x80, 0x60, 0x1C, 0xF0, 0x80, 0xFC, 0x50, 0x46, 0xDA, 0xE9, -+0x00, 0x4A, 0xFF, 0xF7, 0x95, 0xFC, 0xD8, 0xF8, 0x00, 0x00, 0x0B, 0xF1, 0x01, 0x0B, 0x20, 0x1A, 0xFF, 0xF7, 0x4C, 0xFB, -+0x5F, 0xFA, 0x8B, 0xF1, 0xA9, 0x42, 0xE7, 0xD3, 0x28, 0x4A, 0x93, 0x89, 0x5D, 0x1B, 0x95, 0x81, 0xEF, 0xF3, 0x10, 0x83, -+0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x25, 0x4A, 0x01, 0x23, 0x13, 0x60, 0xD9, 0xF8, 0x00, 0x30, 0x23, 0x48, 0x01, 0x33, -+0xC9, 0xF8, 0x00, 0x30, 0x1B, 0xF0, 0x76, 0xFA, 0x1D, 0x49, 0xD9, 0xF8, 0x00, 0x20, 0x91, 0xF8, 0x9D, 0x37, 0x01, 0x3B, -+0x81, 0xF8, 0x9D, 0x37, 0x00, 0x2A, 0xAA, 0xD0, 0x1A, 0x4B, 0x01, 0x3A, 0x1B, 0x68, 0xC9, 0xF8, 0x00, 0x20, 0x00, 0x2A, -+0xA3, 0xD1, 0x00, 0x2B, 0xA1, 0xD0, 0x62, 0xB6, 0x13, 0x4B, 0xD3, 0xF8, 0xA0, 0x27, 0x00, 0x2A, 0xA0, 0xD1, 0xEF, 0xF3, -+0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x10, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xD9, 0xF8, 0x00, 0x30, 0x4F, 0xF4, -+0x00, 0x00, 0x01, 0x33, 0xC9, 0xF8, 0x00, 0x30, 0x1B, 0xF0, 0x8A, 0xF9, 0x04, 0x20, 0x1B, 0xF0, 0x63, 0xF9, 0xD9, 0xF8, -+0x00, 0x30, 0x3B, 0xB1, 0x07, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xC9, 0xF8, 0x00, 0x30, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, -+0xBD, 0xE8, 0xF8, 0x8F, 0xB0, 0x82, 0x15, 0x00, 0x58, 0x58, 0x17, 0x00, 0x10, 0x60, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, -+0xF8, 0x5F, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x34, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0xDF, 0xF8, 0xD8, 0x80, -+0xDF, 0xF8, 0xD8, 0x90, 0xDF, 0xF8, 0xD8, 0xA0, 0xD9, 0xF8, 0x08, 0x3C, 0x00, 0x2B, 0x41, 0xD0, 0x1F, 0x89, 0x5D, 0x68, -+0xBF, 0xB1, 0x00, 0x24, 0x26, 0x46, 0x23, 0x46, 0xB3, 0x42, 0xAB, 0x46, 0x04, 0xF1, 0x01, 0x04, 0x6D, 0x68, 0x08, 0xD1, -+0xDA, 0xF8, 0x8C, 0x32, 0x98, 0x47, 0x9B, 0xF8, 0x0B, 0x30, 0x03, 0xF0, 0x7F, 0x03, 0x1E, 0x44, 0xB6, 0xB2, 0x58, 0x46, -+0xFF, 0xF7, 0x0A, 0xFC, 0xA3, 0xB2, 0xBB, 0x42, 0xEA, 0xD3, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x1F, 0x4A, 0x01, 0x23, 0x13, 0x60, 0xD8, 0xF8, 0x00, 0x30, 0x1E, 0x48, 0x01, 0x33, 0xC8, 0xF8, 0x00, 0x30, 0x1B, 0xF0, -+0xF7, 0xF9, 0x99, 0xF8, 0x02, 0x3C, 0xD8, 0xF8, 0x00, 0x20, 0x01, 0x3B, 0x89, 0xF8, 0x02, 0x3C, 0x00, 0x2A, 0xC7, 0xD0, -+0x15, 0x4B, 0x01, 0x3A, 0x1B, 0x68, 0xC8, 0xF8, 0x00, 0x20, 0x00, 0x2A, 0xC0, 0xD1, 0x00, 0x2B, 0xBE, 0xD0, 0x62, 0xB6, -+0xD9, 0xF8, 0x08, 0x3C, 0x00, 0x2B, 0xBD, 0xD1, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0C, 0x4B, -+0x01, 0x22, 0x1A, 0x60, 0xD8, 0xF8, 0x00, 0x30, 0x10, 0x20, 0x01, 0x33, 0xC8, 0xF8, 0x00, 0x30, 0x1B, 0xF0, 0x0E, 0xF9, -+0xD8, 0xF8, 0x00, 0x30, 0x3B, 0xB1, 0x05, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xC8, 0xF8, 0x00, 0x30, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0xBD, 0xE8, 0xF8, 0x8F, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x84, 0x42, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x7C, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0xDF, 0xF8, 0xB4, 0x80, 0x2A, 0x4E, 0xC1, 0x46, -+0xA8, 0xF1, 0x06, 0x07, 0xD8, 0xF8, 0x00, 0x30, 0x00, 0x2B, 0x33, 0xD0, 0x1D, 0x89, 0x5C, 0x68, 0x7D, 0xB1, 0x4F, 0xF0, -+0x00, 0x0B, 0x20, 0x68, 0xA2, 0x46, 0x0B, 0xF1, 0x01, 0x0B, 0x64, 0x68, 0xFF, 0xF7, 0x5E, 0xFA, 0x50, 0x46, 0xFF, 0xF7, -+0x9D, 0xFB, 0x1F, 0xFA, 0x8B, 0xF2, 0xAA, 0x42, 0xF1, 0xD3, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x1B, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x33, 0x68, 0x48, 0x46, 0x01, 0x33, 0x33, 0x60, 0x1B, 0xF0, 0x8B, 0xF9, 0x3B, 0x78, -+0x32, 0x68, 0x01, 0x3B, 0x3B, 0x70, 0x00, 0x2A, 0xD4, 0xD0, 0x14, 0x4B, 0x01, 0x3A, 0x1B, 0x68, 0x32, 0x60, 0x00, 0x2A, -+0xCE, 0xD1, 0x00, 0x2B, 0xCC, 0xD0, 0x62, 0xB6, 0xD8, 0xF8, 0x00, 0x30, 0x00, 0x2B, 0xCB, 0xD1, 0xEF, 0xF3, 0x10, 0x83, -+0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0B, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x33, 0x68, 0x08, 0x20, 0x01, 0x33, 0x33, 0x60, -+0x1B, 0xF0, 0xA8, 0xF8, 0x33, 0x68, 0x33, 0xB1, 0x05, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x33, 0x60, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0xBD, 0xE8, 0xF8, 0x8F, 0x00, 0xBF, 0x6C, 0x28, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x94, 0x4E, 0x17, 0x00, -+0x10, 0xB5, 0x04, 0x20, 0x1B, 0xF0, 0x92, 0xF8, 0x03, 0x4B, 0x04, 0x49, 0xD3, 0xF8, 0x10, 0x31, 0x03, 0x48, 0xBD, 0xE8, -+0x10, 0x40, 0x18, 0x47, 0x88, 0x1A, 0x17, 0x00, 0x10, 0x60, 0x17, 0x00, 0x28, 0x60, 0x17, 0x00, 0xF8, 0xB5, 0xA8, 0x4B, -+0xA8, 0x4A, 0x1B, 0x68, 0x14, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xB7, 0x81, 0x65, 0x05, 0x18, 0xD5, -+0xA4, 0x4A, 0x13, 0x68, 0x98, 0x00, 0xFC, 0xD4, 0xA3, 0x4B, 0xA2, 0x49, 0x13, 0x60, 0x0B, 0x68, 0x13, 0xF0, 0x00, 0x53, -+0xFB, 0xD1, 0xA1, 0x49, 0xA1, 0x48, 0x0A, 0x68, 0x42, 0xF0, 0x10, 0x02, 0x0A, 0x60, 0x02, 0x78, 0x02, 0xB1, 0x03, 0x70, -+0x9E, 0x4B, 0x1A, 0x78, 0x00, 0x2A, 0x40, 0xF0, 0xE0, 0x81, 0x21, 0x05, 0x09, 0xD5, 0x97, 0x4A, 0x13, 0x68, 0x9B, 0x00, -+0xFC, 0xD4, 0x9A, 0x4B, 0x94, 0x49, 0x13, 0x60, 0x0B, 0x68, 0x9F, 0x00, 0xFC, 0xD4, 0xE2, 0x04, 0x05, 0xD5, 0x94, 0x49, -+0x96, 0x4B, 0x97, 0x4A, 0x01, 0x20, 0x08, 0x70, 0x1A, 0x60, 0x66, 0x06, 0x04, 0xD5, 0x95, 0x4B, 0x95, 0x48, 0x19, 0x68, -+0x1C, 0xF0, 0x9C, 0xFA, 0x14, 0xF4, 0x9B, 0x7F, 0x40, 0xF0, 0x89, 0x81, 0xA5, 0x05, 0x00, 0xF1, 0x8D, 0x81, 0x20, 0x06, -+0x00, 0xF1, 0x94, 0x81, 0x21, 0x04, 0x00, 0xF1, 0x9F, 0x81, 0xE2, 0x02, 0x00, 0xF1, 0xA6, 0x81, 0xA3, 0x02, 0x03, 0xD5, -+0x8B, 0x4B, 0x4F, 0xF4, 0x00, 0x12, 0x1A, 0x60, 0xE7, 0x03, 0x41, 0xD5, 0x89, 0x4B, 0x93, 0xF8, 0x11, 0x15, 0x93, 0xF8, -+0x12, 0x25, 0x91, 0x42, 0x80, 0xF0, 0xB1, 0x81, 0x93, 0xF8, 0x10, 0x05, 0x85, 0x4A, 0x86, 0x4D, 0x86, 0x4E, 0x01, 0x30, -+0xA2, 0xFB, 0x00, 0x72, 0x92, 0x09, 0x02, 0xEB, 0xC2, 0x02, 0x02, 0xEB, 0xC2, 0x02, 0x82, 0x1A, 0x01, 0x31, 0x83, 0xF8, -+0x11, 0x15, 0x83, 0xF8, 0x10, 0x25, 0x03, 0xEB, 0x02, 0x11, 0x30, 0x68, 0x2E, 0x68, 0x4E, 0x60, 0x6E, 0x68, 0x8E, 0x60, -+0x28, 0x3D, 0xC0, 0xF3, 0x00, 0x26, 0x08, 0x73, 0x4E, 0x73, 0x28, 0x68, 0x40, 0xF0, 0x10, 0x00, 0x11, 0x01, 0x28, 0x60, -+0x28, 0x68, 0x86, 0x06, 0xFC, 0xD4, 0x19, 0x44, 0x75, 0x4B, 0x8A, 0x68, 0x75, 0x48, 0x52, 0x68, 0x1A, 0x60, 0x2B, 0x68, -+0x23, 0xF0, 0x10, 0x03, 0x2B, 0x60, 0x1B, 0xF0, 0x6F, 0xF8, 0x20, 0x20, 0x1A, 0xF0, 0xCA, 0xFF, 0x69, 0x4B, 0x4F, 0xF4, -+0x80, 0x32, 0x1A, 0x60, 0x65, 0x03, 0x4E, 0xD5, 0x67, 0x4B, 0x93, 0xF8, 0x9D, 0x17, 0x93, 0xF8, 0x9E, 0x27, 0x91, 0x42, -+0x80, 0xF0, 0x7B, 0x81, 0x93, 0xF8, 0x9C, 0x07, 0x68, 0x4A, 0x69, 0x4F, 0x69, 0x4D, 0xDF, 0xF8, 0xE0, 0xC1, 0x01, 0x30, -+0xA2, 0xFB, 0x00, 0x62, 0x56, 0x09, 0x06, 0xEB, 0x86, 0x06, 0xA0, 0xEB, 0xC6, 0x06, 0x4A, 0x1C, 0x83, 0xF8, 0x9D, 0x27, -+0x83, 0xF8, 0x9C, 0x67, 0x03, 0xEB, 0x06, 0x11, 0x3A, 0x68, 0x28, 0x68, 0xC1, 0xF8, 0x20, 0x05, 0x06, 0xF1, 0x52, 0x07, -+0x03, 0xEB, 0x07, 0x15, 0xDC, 0xF8, 0x00, 0x10, 0x5C, 0x48, 0x69, 0x60, 0xC2, 0xF3, 0x00, 0x21, 0x69, 0x72, 0x2A, 0x72, -+0x05, 0x68, 0x45, 0xF0, 0x04, 0x05, 0x05, 0x60, 0x31, 0x01, 0x05, 0x46, 0x2A, 0x68, 0x10, 0x07, 0xFC, 0xD4, 0x03, 0xEB, -+0x07, 0x12, 0x01, 0xF2, 0x1C, 0x51, 0x50, 0x68, 0x53, 0x4A, 0x40, 0x68, 0x10, 0x60, 0x2A, 0x68, 0x52, 0x48, 0x22, 0xF0, -+0x04, 0x02, 0x19, 0x44, 0x2A, 0x60, 0x1B, 0xF0, 0x1F, 0xF8, 0x4F, 0xF4, 0x00, 0x00, 0x1A, 0xF0, 0x79, 0xFF, 0x41, 0x4B, -+0x4F, 0xF4, 0x80, 0x22, 0x1A, 0x60, 0xA2, 0x03, 0x1B, 0xD5, 0x4B, 0x4B, 0x1A, 0x78, 0x00, 0x2A, 0x40, 0xF0, 0x35, 0x81, -+0x49, 0x48, 0x90, 0xF8, 0x02, 0x1C, 0x90, 0xF8, 0x01, 0x2C, 0x91, 0x42, 0xC0, 0xF0, 0xA2, 0x80, 0x46, 0x48, 0x1C, 0xF0, -+0xDF, 0xF9, 0x36, 0x4B, 0x4F, 0xF4, 0x00, 0x32, 0x1A, 0x60, 0x44, 0x4B, 0x1B, 0x68, 0x23, 0xB9, 0x43, 0x4A, 0x13, 0x78, -+0x23, 0xF0, 0x01, 0x03, 0x13, 0x70, 0x23, 0x03, 0x1D, 0xD5, 0x3C, 0x4B, 0x1A, 0x78, 0x00, 0x2A, 0x40, 0xF0, 0x09, 0x81, -+0x3A, 0x48, 0x41, 0xF6, 0x12, 0x04, 0x41, 0xF6, 0x11, 0x03, 0x02, 0x5D, 0xC3, 0x5C, 0x93, 0x42, 0x10, 0xD8, 0x11, 0x46, -+0x39, 0x48, 0x1C, 0xF0, 0xBF, 0xF9, 0x26, 0x4B, 0x4F, 0xF4, 0x00, 0x22, 0x1A, 0x60, 0x37, 0x4B, 0x1B, 0x68, 0x23, 0xB9, -+0x33, 0x4A, 0x13, 0x78, 0x23, 0xF0, 0x02, 0x03, 0x13, 0x70, 0xF8, 0xBD, 0x41, 0xF6, 0x10, 0x05, 0x32, 0x4B, 0x41, 0x5D, -+0x01, 0x31, 0xA3, 0xFB, 0x01, 0x63, 0xDB, 0x09, 0x03, 0xEB, 0x43, 0x03, 0xA1, 0xEB, 0x83, 0x13, 0x43, 0x55, 0x03, 0xF1, -+0xC1, 0x01, 0x2D, 0x4E, 0x00, 0xEB, 0x01, 0x11, 0x35, 0x68, 0x4D, 0x60, 0x2B, 0x4D, 0x00, 0xEB, 0x03, 0x13, 0x01, 0x32, -+0x2D, 0x68, 0xA3, 0xF8, 0x18, 0x5C, 0x02, 0x55, 0x28, 0x48, 0x1A, 0xF0, 0xB9, 0xFF, 0x08, 0x20, 0x1A, 0xF0, 0x14, 0xFF, -+0x0E, 0x4B, 0x4F, 0xF4, 0x00, 0x22, 0x1A, 0x60, 0xCF, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x24, 0x00, 0x24, 0x40, -+0x40, 0x00, 0x24, 0x40, 0x01, 0x09, 0x00, 0x32, 0x44, 0x00, 0x24, 0x40, 0x1C, 0x26, 0x17, 0x00, 0x3C, 0x36, 0x17, 0x00, -+0x02, 0x09, 0x00, 0x32, 0x2C, 0x00, 0x24, 0x40, 0x09, 0x70, 0x00, 0xCF, 0x08, 0x00, 0x24, 0x40, 0xDC, 0x82, 0x15, 0x00, -+0x28, 0x00, 0x24, 0x40, 0x58, 0x58, 0x17, 0x00, 0xE7, 0x87, 0x45, 0xCA, 0x88, 0x00, 0x24, 0x40, 0x90, 0x00, 0x24, 0x40, -+0x74, 0x00, 0x24, 0x40, 0x6C, 0x5D, 0x17, 0x00, 0xCD, 0xCC, 0xCC, 0xCC, 0x84, 0x00, 0x24, 0x40, 0x7C, 0x00, 0x24, 0x40, -+0x60, 0x00, 0x24, 0x40, 0x6C, 0x00, 0x24, 0x40, 0xF8, 0x5F, 0x17, 0x00, 0x1D, 0x26, 0x17, 0x00, 0x7C, 0x36, 0x17, 0x00, -+0x80, 0x83, 0x15, 0x00, 0xA0, 0x00, 0x24, 0x40, 0x9C, 0x4E, 0x17, 0x00, 0x98, 0x83, 0x15, 0x00, 0x98, 0x00, 0x24, 0x40, -+0xAB, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x24, 0x40, 0xA8, 0x00, 0x24, 0x40, 0x94, 0x4E, 0x17, 0x00, 0x80, 0x00, 0x24, 0x40, -+0x90, 0xF8, 0x00, 0x2C, 0x4B, 0x4B, 0x4C, 0x4D, 0x01, 0x32, 0xA3, 0xFB, 0x02, 0x63, 0xDB, 0x09, 0x03, 0xEB, 0x43, 0x03, -+0xA2, 0xEB, 0x83, 0x13, 0x00, 0xEB, 0x03, 0x12, 0x2D, 0x68, 0x55, 0x60, 0x46, 0x4D, 0x80, 0xF8, 0x00, 0x3C, 0x2B, 0x68, -+0x13, 0x81, 0x01, 0x31, 0x80, 0xF8, 0x02, 0x1C, 0x11, 0x46, 0x00, 0xF6, 0x08, 0x40, 0x1A, 0xF0, 0x49, 0xFF, 0x10, 0x20, -+0x1A, 0xF0, 0xA4, 0xFE, 0x3F, 0x4B, 0x4F, 0xF4, 0x00, 0x32, 0x1A, 0x60, 0x3F, 0xE7, 0x00, 0x2C, 0x7F, 0xF4, 0x46, 0xAE, -+0x3C, 0x49, 0x3D, 0x48, 0x26, 0x22, 0x1C, 0xF0, 0x8D, 0xFB, 0x14, 0xF4, 0x9B, 0x7F, 0x3F, 0xF4, 0x77, 0xAE, 0x3A, 0x48, -+0x21, 0x46, 0x1C, 0xF0, 0x0B, 0xF9, 0xA5, 0x05, 0x7F, 0xF5, 0x73, 0xAE, 0x37, 0x48, 0x1C, 0xF0, 0x05, 0xF9, 0x32, 0x4B, -+0x4F, 0xF4, 0x00, 0x72, 0x20, 0x06, 0x1A, 0x60, 0x7F, 0xF5, 0x6C, 0xAE, 0x33, 0x48, 0x1C, 0xF0, 0xFB, 0xF8, 0x33, 0x4A, -+0x2C, 0x49, 0x13, 0x68, 0x80, 0x20, 0x23, 0xF0, 0x10, 0x03, 0x13, 0x60, 0x08, 0x60, 0x21, 0x04, 0x7F, 0xF5, 0x61, 0xAE, -+0x2E, 0x48, 0x1C, 0xF0, 0xED, 0xF8, 0x26, 0x4B, 0x4F, 0xF4, 0x00, 0x42, 0x1A, 0x60, 0xE2, 0x02, 0x7F, 0xF5, 0x5A, 0xAE, -+0x2A, 0x4A, 0x2B, 0x4B, 0x15, 0x68, 0x2B, 0x48, 0x1A, 0x78, 0x29, 0x46, 0xFD, 0xF7, 0x14, 0xFF, 0x29, 0x4A, 0x1E, 0x4B, -+0x15, 0x60, 0x4F, 0xF4, 0x80, 0x12, 0x1A, 0x60, 0x4A, 0xE6, 0x27, 0x4A, 0x01, 0x21, 0x59, 0x70, 0x13, 0x68, 0x26, 0x49, -+0x43, 0xF0, 0x01, 0x03, 0x13, 0x60, 0x02, 0x20, 0x1C, 0xF0, 0x1C, 0xF9, 0x13, 0xE6, 0x23, 0x48, 0x1C, 0xF0, 0xC8, 0xF8, -+0x13, 0x4B, 0x4F, 0xF4, 0x80, 0x32, 0x1A, 0x60, 0x80, 0xE6, 0x00, 0x22, 0x02, 0x20, 0x1A, 0x70, 0xFD, 0xF7, 0x86, 0xFF, -+0xF0, 0xE6, 0x1D, 0x48, 0x1C, 0xF0, 0xBA, 0xF8, 0x0C, 0x4B, 0x4F, 0xF4, 0x80, 0x22, 0x1A, 0x60, 0xC3, 0xE6, 0x00, 0x22, -+0x02, 0x20, 0x1A, 0x70, 0xFD, 0xF7, 0x78, 0xFF, 0x17, 0x48, 0x90, 0xF8, 0x02, 0x1C, 0x90, 0xF8, 0x01, 0x2C, 0x91, 0x42, -+0xBF, 0xF4, 0xC6, 0xAE, 0x66, 0xE7, 0x00, 0xBF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAC, 0x00, 0x24, 0x40, 0xB0, 0x00, 0x24, 0x40, -+0x28, 0x00, 0x24, 0x40, 0x70, 0x79, 0x15, 0x00, 0xC0, 0x82, 0x15, 0x00, 0xEC, 0x82, 0x15, 0x00, 0x08, 0x83, 0x15, 0x00, -+0x1C, 0x83, 0x15, 0x00, 0x4C, 0x00, 0x24, 0x40, 0x30, 0x83, 0x15, 0x00, 0x30, 0x00, 0x24, 0x40, 0x45, 0x00, 0x24, 0x40, -+0x48, 0x83, 0x15, 0x00, 0x34, 0x00, 0x24, 0x40, 0x10, 0x00, 0x58, 0x40, 0xD0, 0x82, 0x15, 0x00, 0xCC, 0x7C, 0x15, 0x00, -+0x64, 0x83, 0x15, 0x00, 0x7C, 0x36, 0x17, 0x00, 0xF8, 0xB5, 0x47, 0x4B, 0x1A, 0x68, 0x42, 0xF0, 0x10, 0x02, 0x1A, 0x60, -+0x1B, 0x68, 0x5A, 0x07, 0x7F, 0xD4, 0x44, 0x49, 0x0B, 0x68, 0x9B, 0x00, 0xFC, 0xD4, 0x43, 0x4B, 0x41, 0x4A, 0x0B, 0x60, -+0x13, 0x68, 0x9F, 0x00, 0xFC, 0xD4, 0x13, 0x68, 0x9E, 0x07, 0x03, 0xD4, 0x3C, 0x4A, 0x13, 0x68, 0xDD, 0x07, 0xFC, 0xD5, -+0x3A, 0x4A, 0x3D, 0x4D, 0x13, 0x68, 0x3D, 0x48, 0x3D, 0x49, 0x3E, 0x4C, 0x3E, 0x4F, 0x3F, 0x4E, 0x43, 0xF0, 0x02, 0x03, -+0x13, 0x60, 0x2B, 0x68, 0x03, 0x40, 0x43, 0xF0, 0x10, 0x03, 0x2B, 0x60, 0x2B, 0x68, 0x9B, 0xB2, 0x43, 0xF4, 0x80, 0x13, -+0x2B, 0x60, 0x0B, 0x68, 0x03, 0x40, 0x43, 0xF0, 0x10, 0x03, 0x0B, 0x60, 0x0B, 0x68, 0x9B, 0xB2, 0x43, 0xF4, 0x80, 0x13, -+0x0B, 0x60, 0x4F, 0xF6, 0xFF, 0x73, 0x23, 0x60, 0x52, 0xF8, 0x34, 0x3C, 0x03, 0x40, 0x43, 0xF4, 0x88, 0x53, 0x43, 0xF0, -+0x11, 0x03, 0x42, 0xF8, 0x34, 0x3C, 0x03, 0x23, 0xAB, 0x64, 0x4F, 0xF4, 0xFC, 0x53, 0x3B, 0x60, 0x4F, 0xF0, 0xFF, 0x33, -+0x33, 0x60, 0x2A, 0x48, 0x2A, 0x4B, 0x23, 0x62, 0x00, 0x24, 0x20, 0x23, 0x04, 0x60, 0x41, 0xF8, 0xAC, 0x3C, 0x52, 0xF8, -+0x34, 0x3C, 0x27, 0x4C, 0x27, 0x48, 0x23, 0xF4, 0x7F, 0x03, 0x43, 0xF4, 0x80, 0x33, 0x42, 0xF8, 0x34, 0x3C, 0x41, 0xF8, -+0x84, 0x4C, 0x1C, 0xF0, 0x1B, 0xF8, 0x17, 0x4B, 0x17, 0x49, 0x1A, 0x68, 0x94, 0x00, 0xFC, 0xD4, 0x19, 0x60, 0x1A, 0x68, -+0x90, 0x00, 0xFC, 0xD4, 0x1A, 0x68, 0x12, 0xF0, 0x06, 0x0F, 0xF4, 0xD0, 0x10, 0x4A, 0x13, 0x68, 0x99, 0x00, 0xFC, 0xD4, -+0x1A, 0x4B, 0x0E, 0x49, 0x13, 0x60, 0x0B, 0x68, 0x9B, 0x00, 0xFC, 0xD4, 0x18, 0x48, 0x1C, 0xF0, 0x01, 0xF8, 0x18, 0x4B, -+0x18, 0x49, 0x9A, 0x68, 0xD1, 0xF8, 0xFC, 0x12, 0x91, 0x67, 0xA3, 0xF5, 0x40, 0x63, 0x4F, 0xF4, 0x80, 0x42, 0x1A, 0x60, -+0xF8, 0xBD, 0x14, 0x4B, 0x0C, 0x4A, 0x1A, 0x60, 0xFE, 0xF7, 0x9A, 0xFB, 0xED, 0xE7, 0x00, 0xBF, 0x44, 0x00, 0x24, 0x40, -+0x40, 0x00, 0x24, 0x40, 0x00, 0x02, 0x00, 0x20, 0x04, 0x00, 0x24, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x24, 0x40, -+0x0C, 0x00, 0x24, 0x40, 0xB4, 0x00, 0x24, 0x40, 0x28, 0x00, 0x24, 0x40, 0x38, 0x00, 0x24, 0x40, 0x09, 0x60, 0x00, 0xCF, -+0x00, 0x00, 0x20, 0x4E, 0xB8, 0x83, 0x15, 0x00, 0x06, 0x03, 0x00, 0x30, 0xCC, 0x83, 0x15, 0x00, 0x00, 0xED, 0x00, 0xE0, -+0x88, 0x1A, 0x17, 0x00, 0x2C, 0x00, 0x24, 0x40, 0x2D, 0xE9, 0xF0, 0x41, 0x07, 0x46, 0x82, 0xB0, 0xEF, 0xF3, 0x10, 0x83, -+0xD8, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x24, 0x4B, 0x01, 0x20, 0x18, 0x60, 0x23, 0x4E, 0x24, 0x4B, 0x35, 0x68, 0x1B, 0x68, -+0x01, 0x35, 0x35, 0x60, 0x1C, 0x78, 0x01, 0x2C, 0x2B, 0xD0, 0x21, 0x4C, 0x23, 0x68, 0x43, 0xF4, 0x80, 0x73, 0x23, 0x60, -+0x23, 0x68, 0x9B, 0x05, 0xFC, 0xD4, 0x1E, 0x4B, 0x18, 0x68, 0xC8, 0xB1, 0x1D, 0x4B, 0x1E, 0x4C, 0xD3, 0xF8, 0x04, 0x0C, -+0x47, 0x60, 0x20, 0x68, 0x01, 0x44, 0x21, 0x60, 0x17, 0x49, 0xC3, 0xF8, 0x04, 0x2C, 0x0B, 0x68, 0x23, 0xF4, 0x80, 0x73, -+0x0B, 0x60, 0x35, 0xB1, 0x10, 0x4B, 0x01, 0x3D, 0x1B, 0x68, 0x35, 0x60, 0x0D, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x02, 0xB0, -+0xBD, 0xE8, 0xF0, 0x81, 0x11, 0x48, 0x1F, 0x60, 0x04, 0x68, 0x0F, 0x4B, 0x21, 0x44, 0x01, 0x60, 0xE6, 0xE7, 0xDF, 0xF8, -+0x3C, 0x80, 0x98, 0xF8, 0x00, 0x30, 0x00, 0x2B, 0xCD, 0xD1, 0x02, 0x20, 0xCD, 0xE9, 0x00, 0x12, 0xFD, 0xF7, 0x3C, 0xFE, -+0xDD, 0xE9, 0x00, 0x12, 0x35, 0x68, 0x88, 0xF8, 0x00, 0x40, 0xC2, 0xE7, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x74, 0x36, 0x17, 0x00, 0x60, 0x00, 0x24, 0x40, 0xA0, 0x00, 0x24, 0x40, 0x7C, 0x36, 0x17, 0x00, 0x9C, 0x00, 0x24, 0x40, -+0x1D, 0x26, 0x17, 0x00, 0x30, 0xB4, 0x85, 0x68, 0x06, 0x4C, 0xC3, 0xF3, 0x0B, 0x03, 0x2C, 0x40, 0x02, 0x9D, 0x1C, 0x43, -+0x44, 0xEA, 0xC5, 0x74, 0x84, 0x60, 0xC0, 0xE9, 0x00, 0x12, 0x30, 0xBC, 0x70, 0x47, 0x00, 0xBF, 0x00, 0xF0, 0xFF, 0x7F, -+0xF8, 0xB5, 0x04, 0x46, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x23, 0x4B, 0x01, 0x22, 0x1A, 0x60, -+0x22, 0x4D, 0x23, 0x4B, 0x29, 0x68, 0x1B, 0x68, 0x01, 0x31, 0x29, 0x60, 0x1E, 0x78, 0x01, 0x2E, 0x30, 0xD0, 0x20, 0x4A, -+0x13, 0x68, 0x43, 0xF0, 0x40, 0x03, 0x13, 0x60, 0x13, 0x68, 0x1B, 0x06, 0xFC, 0xD4, 0x1D, 0x4B, 0x1A, 0x68, 0xF2, 0xB1, -+0x1C, 0x4B, 0x1D, 0x48, 0x41, 0xF6, 0x14, 0x02, 0x9A, 0x58, 0x54, 0x60, 0x02, 0x68, 0x01, 0x32, 0x02, 0x60, 0x41, 0xF6, -+0x14, 0x02, 0x15, 0x4E, 0x9C, 0x50, 0x18, 0x48, 0x32, 0x68, 0x03, 0x78, 0x22, 0xF0, 0x40, 0x02, 0x43, 0xF0, 0x02, 0x03, -+0x32, 0x60, 0x03, 0x70, 0x31, 0xB1, 0x0C, 0x4B, 0x01, 0x39, 0x1B, 0x68, 0x29, 0x60, 0x09, 0xB9, 0x03, 0xB1, 0x62, 0xB6, -+0xF8, 0xBD, 0x0E, 0x48, 0x1C, 0x60, 0x02, 0x68, 0x0B, 0x4B, 0x01, 0x32, 0x02, 0x60, 0xE2, 0xE7, 0x0C, 0x4F, 0x3B, 0x78, -+0x00, 0x2B, 0xCA, 0xD1, 0x02, 0x20, 0xFD, 0xF7, 0xC9, 0xFD, 0x29, 0x68, 0x3E, 0x70, 0xC4, 0xE7, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x74, 0x36, 0x17, 0x00, 0x60, 0x00, 0x24, 0x40, 0x98, 0x00, 0x24, 0x40, 0x7C, 0x36, 0x17, 0x00, -+0x94, 0x00, 0x24, 0x40, 0x9C, 0x4E, 0x17, 0x00, 0x1D, 0x26, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x80, 0x46, 0x04, 0x20, -+0x0F, 0x46, 0x15, 0x46, 0xFE, 0xF7, 0xF0, 0xFD, 0x68, 0xB3, 0x04, 0x46, 0xFE, 0xF7, 0x34, 0xFF, 0x06, 0x46, 0x00, 0xB3, -+0xC5, 0xF3, 0x03, 0x23, 0x4F, 0xF0, 0x00, 0x09, 0x25, 0x70, 0x63, 0x70, 0x2A, 0x46, 0x84, 0xF8, 0x02, 0x80, 0x39, 0x46, -+0x84, 0xF8, 0x03, 0x90, 0x20, 0x1D, 0x2E, 0xF0, 0xF9, 0xFB, 0xB2, 0x68, 0x0E, 0x4B, 0xC6, 0xF8, 0x04, 0x90, 0x04, 0x35, -+0x13, 0x40, 0xC5, 0xF3, 0x0B, 0x05, 0x1D, 0x43, 0x45, 0xF0, 0x00, 0x45, 0x34, 0x60, 0xB5, 0x60, 0x30, 0x46, 0xBD, 0xE8, -+0xF8, 0x43, 0xFF, 0xF7, 0x71, 0xBF, 0x07, 0x48, 0x1C, 0xF0, 0xCC, 0xFF, 0x20, 0x46, 0xBD, 0xE8, 0xF8, 0x43, 0xFE, 0xF7, -+0xE7, 0xBD, 0xBD, 0xE8, 0xF8, 0x43, 0x03, 0x48, 0x1C, 0xF0, 0xC2, 0xBF, 0x00, 0xF0, 0xFF, 0x7F, 0xEC, 0x83, 0x15, 0x00, -+0xD8, 0x83, 0x15, 0x00, 0x05, 0x4B, 0x1B, 0x78, 0x33, 0xB9, 0x05, 0x4B, 0x18, 0x68, 0x6F, 0xEA, 0x10, 0x10, 0x00, 0xF0, -+0x01, 0x00, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x1C, 0x26, 0x17, 0x00, 0x44, 0x00, 0x24, 0x40, 0x44, 0x4A, 0x13, 0x69, -+0x43, 0xF0, 0x01, 0x03, 0x30, 0xB4, 0x13, 0x61, 0x13, 0x69, 0xD9, 0x07, 0xFC, 0xD4, 0x40, 0x4A, 0x13, 0x69, 0x00, 0x2B, -+0xFC, 0xDA, 0xD3, 0x68, 0x3E, 0x48, 0x3D, 0x49, 0x43, 0xF0, 0x80, 0x43, 0x43, 0xF0, 0x07, 0x03, 0xD3, 0x60, 0xD3, 0x68, -+0x18, 0x43, 0xD0, 0x60, 0xD3, 0x68, 0x23, 0xF4, 0x71, 0x53, 0x23, 0xF0, 0x28, 0x03, 0xD3, 0x60, 0x13, 0x69, 0x43, 0xF0, -+0x01, 0x03, 0x13, 0x61, 0x0B, 0x69, 0xDA, 0x07, 0xFC, 0xD4, 0x32, 0x4B, 0x1A, 0x69, 0x00, 0x2A, 0xFC, 0xDA, 0xDA, 0x68, -+0x30, 0x48, 0x2F, 0x49, 0x42, 0xF0, 0x80, 0x42, 0x42, 0xF0, 0x07, 0x02, 0xDA, 0x60, 0xDA, 0x68, 0x10, 0x43, 0xD8, 0x60, -+0xDA, 0x68, 0x22, 0xF4, 0x71, 0x52, 0x22, 0xF0, 0x28, 0x02, 0xDA, 0x60, 0xD3, 0xF8, 0x00, 0x28, 0x22, 0xF4, 0xC0, 0x52, -+0x22, 0xF0, 0x03, 0x02, 0xC3, 0xF8, 0x00, 0x28, 0xD3, 0xF8, 0x00, 0x28, 0x42, 0xF4, 0x00, 0x02, 0x42, 0xF0, 0x04, 0x02, -+0xC3, 0xF8, 0x00, 0x28, 0x00, 0x24, 0x4F, 0xF0, 0xFF, 0x35, 0x01, 0x22, 0x9C, 0x61, 0x01, 0x2A, 0x5D, 0x61, 0xC3, 0xF8, -+0x1C, 0x48, 0xC3, 0xF8, 0x14, 0x48, 0xC3, 0xF8, 0x10, 0x48, 0xA2, 0xF1, 0x02, 0x03, 0x28, 0x46, 0x01, 0xEB, 0x43, 0x13, -+0x0B, 0xD0, 0x05, 0x2A, 0xC3, 0xF8, 0x28, 0x0B, 0xC3, 0xF8, 0x28, 0x09, 0x0A, 0xD0, 0x01, 0x32, 0x93, 0x1E, 0x01, 0x2A, -+0x01, 0xEB, 0x43, 0x13, 0xF3, 0xD1, 0xC1, 0xF8, 0x08, 0x0B, 0xC1, 0xF8, 0x08, 0x09, 0xF4, 0xE7, 0x0F, 0x48, 0x10, 0x4B, -+0x0C, 0x4A, 0x88, 0x61, 0x4B, 0x63, 0x53, 0x6B, 0x1B, 0x01, 0xFC, 0xD5, 0xD2, 0xF8, 0x04, 0x38, 0x23, 0xF0, 0x02, 0x03, -+0xC2, 0xF8, 0x04, 0x38, 0xD2, 0xF8, 0x04, 0x38, 0x2E, 0x21, 0x43, 0xF4, 0x00, 0x43, 0xC2, 0xF8, 0x04, 0x38, 0x91, 0x60, -+0x93, 0x68, 0x43, 0xF0, 0x01, 0x03, 0x30, 0xBC, 0x93, 0x60, 0x70, 0x47, 0x00, 0x00, 0x20, 0x40, 0x10, 0x00, 0x06, 0x40, -+0x00, 0x38, 0x00, 0x80, 0x41, 0x00, 0x44, 0x02, 0x0A, 0x4B, 0x0B, 0x49, 0x1A, 0x68, 0x08, 0x68, 0x0A, 0x49, 0x0B, 0x4B, -+0xC2, 0xE9, 0x00, 0x10, 0xC3, 0xF8, 0x14, 0x2B, 0xD3, 0xF8, 0x08, 0x2B, 0xC3, 0xF8, 0x08, 0x2B, 0xD3, 0xF8, 0x00, 0x2B, -+0x42, 0xF0, 0x04, 0x42, 0xC3, 0xF8, 0x00, 0x2B, 0x70, 0x47, 0x00, 0xBF, 0x5C, 0x60, 0x17, 0x00, 0x60, 0x60, 0x17, 0x00, -+0x40, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x20, 0x40, 0x12, 0x4A, 0x13, 0x4B, 0x11, 0x68, 0x18, 0x68, 0x12, 0x4B, 0x30, 0xB4, -+0x12, 0x4C, 0x4F, 0xF0, 0x20, 0x62, 0x00, 0x25, 0x65, 0x81, 0xC1, 0xE9, 0x00, 0x20, 0x1A, 0x69, 0x22, 0xF4, 0xFC, 0x62, -+0x42, 0xF0, 0x20, 0x02, 0x1A, 0x61, 0x18, 0x69, 0x10, 0xF0, 0x20, 0x00, 0xFB, 0xD1, 0xD3, 0xF8, 0x08, 0x29, 0xC3, 0xF8, -+0x08, 0x29, 0xC3, 0xF8, 0x14, 0x19, 0xD3, 0xF8, 0x00, 0x29, 0x42, 0xF0, 0x04, 0x42, 0x30, 0xBC, 0xC3, 0xF8, 0x00, 0x29, -+0x70, 0x47, 0x00, 0xBF, 0x40, 0x60, 0x17, 0x00, 0x58, 0x60, 0x17, 0x00, 0x00, 0x00, 0x20, 0x40, 0xB4, 0x27, 0x17, 0x00, -+0x70, 0xB5, 0x0B, 0x4B, 0x04, 0x46, 0x01, 0x38, 0x03, 0xEB, 0x00, 0x10, 0x10, 0x22, 0x05, 0x7A, 0x00, 0x21, 0xF7, 0xF7, -+0x4D, 0xFB, 0x55, 0xB1, 0x06, 0x48, 0x00, 0xEB, 0x84, 0x04, 0x23, 0x6A, 0x2B, 0xB1, 0x00, 0x21, 0xBD, 0xE8, 0x70, 0x40, -+0x08, 0x46, 0x01, 0x22, 0x18, 0x47, 0x70, 0xBD, 0x08, 0x28, 0x17, 0x00, 0x20, 0x26, 0x17, 0x00, 0x70, 0xB5, 0x0B, 0x4B, -+0x04, 0x46, 0x01, 0x38, 0x03, 0xEB, 0x00, 0x10, 0x10, 0x22, 0xC5, 0x7A, 0x00, 0x21, 0xF7, 0xF7, 0x31, 0xFB, 0x55, 0xB1, -+0x06, 0x48, 0x00, 0xEB, 0x84, 0x04, 0x23, 0x6B, 0x2B, 0xB1, 0x00, 0x21, 0xBD, 0xE8, 0x70, 0x40, 0x08, 0x46, 0x01, 0x22, -+0x18, 0x47, 0x70, 0xBD, 0xC8, 0x27, 0x17, 0x00, 0x20, 0x26, 0x17, 0x00, 0x10, 0xB5, 0x01, 0x24, 0x82, 0xB0, 0xE0, 0xB2, -+0x01, 0x90, 0x01, 0x34, 0xFF, 0xF7, 0xC0, 0xFF, 0x01, 0x98, 0xFF, 0xF7, 0xD9, 0xFF, 0x05, 0x2C, 0xF5, 0xD1, 0x02, 0xB0, -+0x10, 0xBD, 0x00, 0xBF, 0x38, 0xB5, 0x0C, 0x46, 0x00, 0x28, 0x39, 0xD0, 0x09, 0xBB, 0x1D, 0x4B, 0x1D, 0x4A, 0x1B, 0x68, -+0x51, 0x81, 0x1D, 0x4D, 0x4F, 0xF0, 0x42, 0x42, 0x1A, 0x60, 0xDA, 0x78, 0x42, 0xF0, 0x04, 0x02, 0xDA, 0x70, 0xD9, 0x78, -+0x28, 0x68, 0x19, 0x4A, 0x58, 0x60, 0x01, 0xF0, 0x07, 0x01, 0x41, 0xF0, 0x08, 0x01, 0xD9, 0x70, 0xD2, 0xF8, 0x08, 0x19, -+0xC2, 0xF8, 0x08, 0x19, 0xC2, 0xF8, 0x14, 0x39, 0xD2, 0xF8, 0x00, 0x39, 0x43, 0xF0, 0x04, 0x43, 0xC2, 0xF8, 0x00, 0x39, -+0x38, 0xBD, 0x0E, 0x4D, 0x01, 0x46, 0x22, 0x46, 0x28, 0x68, 0x2E, 0xF0, 0x71, 0xFA, 0x09, 0x4B, 0x09, 0x4A, 0x1B, 0x68, -+0x54, 0x81, 0x4F, 0xF0, 0x40, 0x41, 0xC2, 0x22, 0x40, 0x2C, 0x19, 0x60, 0x1C, 0x80, 0xDA, 0x70, 0xD3, 0xD1, 0xD2, 0xB2, -+0x6F, 0xF3, 0x82, 0x02, 0xDA, 0x70, 0xD2, 0xE7, 0x02, 0x4D, 0xEC, 0xE7, 0x40, 0x60, 0x17, 0x00, 0xB4, 0x27, 0x17, 0x00, -+0x58, 0x60, 0x17, 0x00, 0x00, 0x00, 0x20, 0x40, 0xF0, 0xB4, 0x80, 0xB3, 0x27, 0x4D, 0x43, 0x1E, 0x05, 0xEB, 0x43, 0x16, -+0x08, 0x36, 0x05, 0xEB, 0x43, 0x15, 0x2F, 0x68, 0x17, 0xF0, 0x80, 0x2F, 0x22, 0xD0, 0x23, 0x4B, 0x3B, 0x40, 0xB3, 0xF5, -+0x00, 0x3F, 0x2C, 0xD0, 0x21, 0x4C, 0xD4, 0xF8, 0x04, 0x38, 0x43, 0xF4, 0x00, 0x73, 0xC4, 0xF8, 0x04, 0x38, 0x63, 0x69, -+0x1B, 0x06, 0xFC, 0xD5, 0x2B, 0x68, 0x19, 0x43, 0x41, 0xF0, 0x00, 0x61, 0x41, 0xF4, 0x00, 0x41, 0x29, 0x60, 0x1A, 0xB1, -+0x2B, 0x68, 0x23, 0xEA, 0x02, 0x02, 0x2A, 0x60, 0x60, 0xB9, 0x16, 0x4A, 0xD2, 0xF8, 0x04, 0x38, 0x43, 0xF4, 0x80, 0x63, -+0xC2, 0xF8, 0x04, 0x38, 0xF0, 0xBC, 0xFF, 0xF7, 0x3D, 0xBF, 0x12, 0x4E, 0x12, 0x4D, 0xD2, 0xE7, 0x00, 0x2F, 0x0C, 0xDB, -+0x3B, 0x04, 0xEE, 0xD4, 0x2B, 0x68, 0x23, 0xF4, 0x00, 0x43, 0x2B, 0x60, 0xE9, 0xE7, 0xB1, 0xF1, 0x00, 0x6F, 0xCF, 0xD1, -+0x00, 0x2A, 0xCD, 0xD1, 0xEA, 0xE7, 0x02, 0x23, 0x33, 0x60, 0x2B, 0x68, 0x43, 0xF0, 0x80, 0x43, 0x2B, 0x60, 0x33, 0x68, -+0x9A, 0x07, 0xFC, 0xD5, 0x3B, 0x04, 0xD8, 0xD4, 0xE8, 0xE7, 0x00, 0xBF, 0x20, 0x0B, 0x20, 0x40, 0x00, 0x00, 0x02, 0x80, -+0x00, 0x00, 0x20, 0x40, 0x08, 0x0B, 0x20, 0x40, 0x00, 0x0B, 0x20, 0x40, 0x70, 0xB4, 0x70, 0xB3, 0x44, 0x1E, 0x36, 0x4B, -+0x66, 0x01, 0x03, 0xEB, 0x44, 0x14, 0xF5, 0x58, 0x15, 0xF0, 0x80, 0x2F, 0x4D, 0xD0, 0x08, 0x36, 0x33, 0x44, 0x32, 0x4E, -+0x2E, 0x40, 0xB6, 0xF5, 0x00, 0x3F, 0x29, 0xD1, 0xB1, 0xF1, 0x00, 0x6F, 0x46, 0xD0, 0x40, 0x26, 0x1E, 0x60, 0x23, 0x68, -+0x0B, 0x43, 0x43, 0xF0, 0x00, 0x63, 0x43, 0xF4, 0x00, 0x43, 0x23, 0x60, 0x00, 0x2A, 0x45, 0xD1, 0x29, 0x4A, 0x83, 0x01, -+0x43, 0xF0, 0x20, 0x03, 0x13, 0x61, 0x13, 0x69, 0x99, 0x06, 0xFC, 0xD4, 0x2B, 0x04, 0x03, 0xD4, 0x23, 0x68, 0x23, 0xF4, -+0x00, 0x43, 0x23, 0x60, 0x48, 0xBB, 0x70, 0xBC, 0x70, 0x47, 0x22, 0x4C, 0x25, 0x68, 0x15, 0xF0, 0x80, 0x2F, 0xF8, 0xD0, -+0x1D, 0x4E, 0x20, 0x4B, 0x2E, 0x40, 0xB6, 0xF5, 0x00, 0x3F, 0xD5, 0xD0, 0x40, 0x26, 0x1E, 0x60, 0x26, 0x68, 0x31, 0x43, -+0x41, 0xF0, 0x00, 0x61, 0x41, 0xF4, 0x00, 0x41, 0x00, 0x2D, 0x21, 0x60, 0xD6, 0xDA, 0xAE, 0x03, 0x04, 0xD4, 0x19, 0x68, -+0x49, 0x06, 0xFC, 0xD5, 0x40, 0x21, 0x19, 0x60, 0xDA, 0xB9, 0x02, 0x22, 0x1A, 0x60, 0x22, 0x68, 0x42, 0xF0, 0x80, 0x42, -+0x22, 0x60, 0x1A, 0x68, 0x96, 0x07, 0xFC, 0xD5, 0xC6, 0xE7, 0x70, 0xBC, 0xFF, 0xF7, 0xD4, 0xBE, 0x00, 0x2A, 0xCF, 0xD0, -+0x40, 0x21, 0x19, 0x60, 0x23, 0x68, 0x43, 0xF0, 0x00, 0x63, 0x43, 0xF4, 0x00, 0x43, 0x23, 0x60, 0x23, 0x68, 0x23, 0xEA, -+0x02, 0x02, 0x22, 0x60, 0xB4, 0xE7, 0x21, 0x68, 0x21, 0xEA, 0x02, 0x02, 0x22, 0x60, 0xDE, 0xE7, 0x20, 0x09, 0x20, 0x40, -+0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x20, 0x40, 0x00, 0x09, 0x20, 0x40, 0x08, 0x09, 0x20, 0x40, 0x49, 0xB9, 0x0A, 0x4B, -+0x0A, 0x4A, 0x01, 0x28, 0x0C, 0xBF, 0x18, 0x46, 0x10, 0x46, 0x00, 0x68, 0xC0, 0xF3, 0x40, 0x50, 0x70, 0x47, 0x01, 0x28, -+0x0C, 0xBF, 0x04, 0x48, 0x04, 0x48, 0x49, 0x01, 0x08, 0x44, 0x00, 0x68, 0xC0, 0xF3, 0x40, 0x50, 0x70, 0x47, 0x00, 0xBF, -+0x00, 0x09, 0x20, 0x40, 0x00, 0x0B, 0x20, 0x40, 0x38, 0xB9, 0x04, 0x29, 0x0D, 0xD8, 0x02, 0x46, 0x08, 0x46, 0x4F, 0xF0, -+0x00, 0x61, 0xFF, 0xF7, 0x07, 0xBF, 0x04, 0x29, 0x05, 0xD8, 0x08, 0x46, 0x00, 0x22, 0x4F, 0xF0, 0x00, 0x61, 0xFF, 0xF7, -+0x5B, 0xBF, 0x70, 0x47, 0x38, 0xB9, 0x04, 0x29, 0x0D, 0xD8, 0x02, 0x46, 0x08, 0x46, 0x4F, 0xF4, 0x00, 0x11, 0xFF, 0xF7, -+0xF5, 0xBE, 0x04, 0x29, 0x05, 0xD8, 0x08, 0x46, 0x00, 0x22, 0x4F, 0xF4, 0x00, 0x11, 0xFF, 0xF7, 0x49, 0xBF, 0x70, 0x47, -+0x40, 0xB9, 0x04, 0x29, 0x0F, 0xD8, 0x08, 0x46, 0x4F, 0xF4, 0x00, 0x12, 0x4F, 0xF0, 0x00, 0x61, 0xFF, 0xF7, 0xE2, 0xBE, -+0x04, 0x29, 0x06, 0xD8, 0x08, 0x46, 0x4F, 0xF4, 0x00, 0x12, 0x4F, 0xF0, 0x00, 0x61, 0xFF, 0xF7, 0x35, 0xBF, 0x70, 0x47, -+0xFF, 0xF7, 0xC6, 0xBF, 0x2D, 0xE9, 0xF8, 0x43, 0x04, 0x46, 0x0D, 0x46, 0x57, 0x48, 0x00, 0x21, 0x1B, 0xF0, 0x04, 0xFC, -+0x00, 0x2C, 0x00, 0xF0, 0x95, 0x80, 0x23, 0x68, 0x00, 0x2B, 0x7B, 0xD0, 0x63, 0x68, 0x00, 0x2B, 0x78, 0xD0, 0xA3, 0x68, -+0x00, 0x2B, 0x75, 0xD0, 0x63, 0x69, 0x00, 0x2B, 0x72, 0xD0, 0x4F, 0x4E, 0x33, 0x78, 0x03, 0xF0, 0xFF, 0x07, 0x00, 0x2B, -+0x6F, 0xD1, 0xDF, 0xF8, 0x68, 0x81, 0x21, 0x46, 0x40, 0x46, 0x01, 0x24, 0x48, 0x22, 0x34, 0x70, 0x2E, 0xF0, 0x06, 0xF9, -+0x48, 0x4B, 0xD3, 0xF8, 0x94, 0x30, 0x00, 0x2B, 0x77, 0xD0, 0x47, 0x48, 0x1B, 0xF0, 0xDE, 0xFB, 0x46, 0x4B, 0xD3, 0xF8, -+0x00, 0x28, 0x12, 0xF4, 0xFE, 0x6F, 0x5B, 0xD0, 0x44, 0x49, 0x45, 0x4A, 0xD1, 0xF8, 0x00, 0xC0, 0x44, 0x49, 0x12, 0x68, -+0xDF, 0xF8, 0x30, 0x91, 0x09, 0x68, 0xC9, 0xF8, 0x04, 0x70, 0x04, 0x20, 0xC9, 0xF8, 0x08, 0x70, 0x89, 0xF8, 0x00, 0x70, -+0xC2, 0xF8, 0x04, 0xC0, 0x30, 0x70, 0xC3, 0xF8, 0x14, 0x2B, 0xC8, 0x78, 0x3C, 0x4A, 0x40, 0xF0, 0xC0, 0x00, 0xD2, 0xF8, -+0x00, 0xC0, 0xC8, 0x70, 0x9C, 0xF8, 0x03, 0x00, 0x39, 0x4A, 0x40, 0xF0, 0xC0, 0x00, 0x17, 0x68, 0x8C, 0xF8, 0x03, 0x00, -+0xF8, 0x78, 0xD2, 0xF8, 0x04, 0xE0, 0x40, 0xF0, 0xC0, 0x00, 0xF8, 0x70, 0x9E, 0xF8, 0x03, 0x00, 0xD2, 0xE9, 0x02, 0xC7, -+0x40, 0xF0, 0xC0, 0x02, 0x8E, 0xF8, 0x03, 0x20, 0x9C, 0xF8, 0x03, 0x20, 0x42, 0xF0, 0xC0, 0x02, 0x8C, 0xF8, 0x03, 0x20, -+0xFA, 0x78, 0x42, 0xF0, 0xC0, 0x02, 0xFA, 0x70, 0xC3, 0xF8, 0x14, 0x19, 0xFF, 0xF7, 0x86, 0xFD, 0xD8, 0xF8, 0x44, 0x30, -+0x89, 0xF8, 0x00, 0x40, 0x03, 0xB1, 0x98, 0x47, 0x26, 0x4B, 0x27, 0x49, 0x9A, 0x68, 0xD1, 0xF8, 0x04, 0x11, 0xD1, 0x67, -+0xA3, 0xF5, 0x40, 0x63, 0x4F, 0xF4, 0x00, 0x42, 0x01, 0x2D, 0x1A, 0x60, 0x23, 0xD0, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, -+0x02, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x03, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x9A, 0x68, 0xD2, 0x07, 0x14, 0xD5, 0x9A, 0x68, -+0x22, 0xF0, 0x01, 0x02, 0x9A, 0x60, 0xD3, 0xF8, 0x04, 0x28, 0x42, 0xF0, 0x02, 0x02, 0xC3, 0xF8, 0x04, 0x28, 0xFF, 0xF7, -+0xC9, 0xFC, 0xD9, 0xE7, 0x01, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x14, 0x48, 0xFD, 0xF7, 0x9C, 0xF9, 0x04, 0x20, 0xE2, 0xE7, -+0xFF, 0xF7, 0xBE, 0xFC, 0xCE, 0xE7, 0x11, 0x4B, 0x11, 0x48, 0x1B, 0x69, 0x1B, 0xF0, 0x5C, 0xFB, 0x33, 0x78, 0x04, 0x2B, -+0xFC, 0xD1, 0xD2, 0xE7, 0xFC, 0x83, 0x15, 0x00, 0x6F, 0x26, 0x17, 0x00, 0x00, 0x00, 0x10, 0x40, 0x08, 0x84, 0x15, 0x00, -+0x00, 0x00, 0x20, 0x40, 0x60, 0x60, 0x17, 0x00, 0x5C, 0x60, 0x17, 0x00, 0x40, 0x60, 0x17, 0x00, 0x54, 0x60, 0x17, 0x00, -+0x44, 0x60, 0x17, 0x00, 0x00, 0xED, 0x00, 0xE0, 0x88, 0x1A, 0x17, 0x00, 0x1C, 0x84, 0x15, 0x00, 0x00, 0x10, 0x50, 0x40, -+0x34, 0x84, 0x15, 0x00, 0x20, 0x26, 0x17, 0x00, 0xB4, 0x27, 0x17, 0x00, 0x14, 0x4B, 0x4F, 0xF4, 0x00, 0x42, 0xC3, 0xF8, -+0x80, 0x20, 0xBF, 0xF3, 0x4F, 0x8F, 0xBF, 0xF3, 0x6F, 0x8F, 0x11, 0x4A, 0x11, 0x4B, 0x12, 0x48, 0x00, 0x21, 0x11, 0x70, -+0x9A, 0x68, 0x22, 0xF0, 0x01, 0x02, 0x9A, 0x60, 0xD3, 0xF8, 0x04, 0x28, 0x42, 0xF0, 0x02, 0x02, 0xC3, 0xF8, 0x04, 0x28, -+0x1A, 0x69, 0x42, 0xF0, 0x01, 0x02, 0x1A, 0x61, 0xD3, 0xF8, 0x04, 0x28, 0x42, 0xF0, 0x02, 0x02, 0xC3, 0xF8, 0x04, 0x28, -+0x1A, 0x69, 0x42, 0xF0, 0x01, 0x02, 0x1A, 0x61, 0x48, 0x22, 0xF7, 0xF7, 0x9F, 0xB8, 0x00, 0xBF, 0x00, 0xE1, 0x00, 0xE0, -+0x6F, 0x26, 0x17, 0x00, 0x00, 0x00, 0x20, 0x40, 0x20, 0x26, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0x4E, 0x1E, 0xF7, 0xB2, -+0x03, 0x2F, 0x41, 0xD8, 0x14, 0x46, 0x0D, 0x46, 0x9B, 0x46, 0x02, 0x46, 0x00, 0x28, 0x3D, 0xD0, 0x04, 0xF0, 0xFD, 0x01, -+0x01, 0x29, 0x5B, 0xD0, 0xDF, 0x1C, 0xBF, 0x10, 0x7F, 0x00, 0xBF, 0xB2, 0xBA, 0x46, 0x4F, 0xEA, 0x07, 0x49, 0x4F, 0xEA, -+0x45, 0x18, 0x08, 0xF1, 0x80, 0x48, 0x08, 0xF5, 0x00, 0x18, 0xD8, 0xF8, 0x00, 0x19, 0x11, 0xF0, 0x80, 0x2F, 0x68, 0xD1, -+0xA2, 0x04, 0x02, 0xF4, 0x40, 0x22, 0xCB, 0xF3, 0x0A, 0x03, 0x3B, 0x4C, 0x13, 0x43, 0x43, 0xEA, 0x85, 0x53, 0x21, 0x88, -+0x43, 0xF0, 0xC0, 0x53, 0x43, 0xF4, 0x00, 0x43, 0xC8, 0xF8, 0x00, 0x39, 0x01, 0xEB, 0x0A, 0x03, 0xB3, 0xF5, 0xC0, 0x6F, -+0x5E, 0xDC, 0x34, 0x4A, 0x40, 0x36, 0x02, 0xEB, 0x86, 0x06, 0x41, 0xEA, 0x09, 0x03, 0x73, 0x60, 0xD2, 0xF8, 0x1C, 0x38, -+0x0F, 0x44, 0x01, 0x21, 0x01, 0xFA, 0x05, 0xF5, 0x1D, 0x43, 0x27, 0x80, 0xC2, 0xF8, 0x1C, 0x58, 0xBD, 0xE8, 0xF8, 0x8F, -+0x4E, 0x01, 0x06, 0xF1, 0x80, 0x46, 0x06, 0xF5, 0x00, 0x16, 0xD6, 0xF8, 0x00, 0x2B, 0x12, 0xF0, 0x80, 0x2F, 0x33, 0xD1, -+0xA4, 0x04, 0x04, 0xF4, 0x40, 0x24, 0xCB, 0xF3, 0x0A, 0x03, 0x23, 0x43, 0x43, 0xF0, 0xC0, 0x53, 0x21, 0x4A, 0x43, 0xF4, -+0x00, 0x43, 0xC6, 0xF8, 0x00, 0x3B, 0xD2, 0xF8, 0x1C, 0x38, 0x4F, 0xF4, 0x80, 0x31, 0x01, 0xFA, 0x05, 0xF5, 0x1D, 0x43, -+0xC2, 0xF8, 0x1C, 0x58, 0xBD, 0xE8, 0xF8, 0x8F, 0xB3, 0xF5, 0x48, 0x7F, 0x20, 0xD8, 0xDF, 0x1C, 0xBF, 0x10, 0x7F, 0x00, -+0xBF, 0xB2, 0xBA, 0x46, 0x4F, 0xEA, 0x07, 0x49, 0xBB, 0xF5, 0x80, 0x6F, 0x9D, 0xD9, 0x6F, 0xF4, 0x80, 0x63, 0x0B, 0xEB, -+0x03, 0x01, 0xB1, 0xF5, 0x80, 0x6F, 0x25, 0xBF, 0x10, 0x4B, 0xA3, 0xFB, 0x0B, 0x13, 0x4F, 0xEA, 0x5B, 0x0B, 0xC3, 0xF3, -+0x4F, 0x0B, 0x8E, 0xE7, 0xFF, 0xF7, 0x34, 0xFE, 0xC8, 0xE7, 0x10, 0x46, 0x29, 0x46, 0xFF, 0xF7, 0x2F, 0xFE, 0x91, 0xE7, -+0x4F, 0xF4, 0xC8, 0x7A, 0x57, 0x46, 0x4F, 0xF0, 0xC8, 0x79, 0xDF, 0xE7, 0x06, 0x48, 0x52, 0x46, 0x4F, 0xF4, 0xC0, 0x63, -+0xFD, 0xF7, 0x9E, 0xF8, 0x21, 0x88, 0x98, 0xE7, 0x48, 0x28, 0x17, 0x00, 0x00, 0x00, 0x20, 0x40, 0xAB, 0xAA, 0xAA, 0xAA, -+0x40, 0x84, 0x15, 0x00, 0xF8, 0xB5, 0x27, 0x4B, 0x1B, 0x78, 0x04, 0x2B, 0x3C, 0xD1, 0x44, 0x1E, 0xDF, 0xB2, 0xE3, 0xB2, -+0x04, 0x2B, 0x39, 0xD8, 0x8D, 0x07, 0x3D, 0xD1, 0x22, 0x4E, 0x4F, 0xEA, 0x04, 0x1E, 0x06, 0xEB, 0x04, 0x1C, 0x56, 0xF8, -+0x0E, 0x50, 0x8D, 0xBB, 0x43, 0x01, 0x03, 0xF1, 0x80, 0x43, 0x03, 0xF5, 0x00, 0x13, 0xD3, 0xF8, 0x00, 0x0B, 0x00, 0x04, -+0x2A, 0xD5, 0x1B, 0x48, 0x46, 0xF8, 0x0E, 0x10, 0x50, 0xF8, 0x24, 0x00, 0x19, 0x4F, 0x01, 0x26, 0x8C, 0xF8, 0x08, 0x60, -+0xC6, 0x78, 0x64, 0x01, 0x04, 0xF1, 0x80, 0x44, 0xBA, 0x42, 0x04, 0xF5, 0x00, 0x14, 0x06, 0xF0, 0x31, 0x06, 0x28, 0xBF, -+0x3A, 0x46, 0x46, 0xF0, 0x0E, 0x06, 0xCC, 0xF8, 0x04, 0x20, 0x02, 0x80, 0x41, 0x60, 0xC6, 0x70, 0xC4, 0xF8, 0x34, 0x0B, -+0xD3, 0xF8, 0x00, 0x2B, 0x42, 0xF0, 0x04, 0x42, 0x28, 0x46, 0xC3, 0xF8, 0x00, 0x2B, 0xF8, 0xBD, 0x01, 0x20, 0xF8, 0xBD, -+0x02, 0x20, 0xF8, 0xBD, 0x38, 0x46, 0xF8, 0xBD, 0x05, 0x20, 0xF8, 0xBD, 0x06, 0x48, 0xFD, 0xF7, 0x47, 0xF8, 0x03, 0x20, -+0xF8, 0xBD, 0x00, 0xBF, 0x6F, 0x26, 0x17, 0x00, 0x08, 0x28, 0x17, 0x00, 0x44, 0x60, 0x17, 0x00, 0xFF, 0xFF, 0x07, 0x00, -+0x80, 0x84, 0x15, 0x00, 0xF8, 0xB5, 0x28, 0x4B, 0x1B, 0x78, 0x04, 0x2B, 0x3E, 0xD1, 0x44, 0x1E, 0xDF, 0xB2, 0xE3, 0xB2, -+0x04, 0x2B, 0x3B, 0xD8, 0x8D, 0x07, 0x3F, 0xD1, 0x23, 0x4E, 0x4F, 0xEA, 0x04, 0x1E, 0x06, 0xEB, 0x04, 0x1C, 0x56, 0xF8, -+0x0E, 0x50, 0x9D, 0xBB, 0x43, 0x01, 0x03, 0xF1, 0x80, 0x43, 0x03, 0xF5, 0x00, 0x13, 0xD3, 0xF8, 0x00, 0x0B, 0x00, 0x04, -+0x2C, 0xD5, 0x1C, 0x48, 0x46, 0xF8, 0x0E, 0x10, 0x50, 0xF8, 0x24, 0x00, 0x1A, 0x4F, 0x01, 0x26, 0x8C, 0xF8, 0x08, 0x60, -+0xC6, 0x78, 0x64, 0x01, 0x04, 0xF1, 0x80, 0x44, 0xBA, 0x42, 0x04, 0xF5, 0x00, 0x14, 0x06, 0xF0, 0x31, 0x06, 0x28, 0xBF, -+0x3A, 0x46, 0x46, 0xF0, 0x0E, 0x06, 0xCC, 0xF8, 0x04, 0x20, 0x02, 0x80, 0x41, 0x60, 0xC6, 0x70, 0xC4, 0xF8, 0x34, 0x0B, -+0xD3, 0xF8, 0x00, 0x2B, 0x22, 0xF0, 0x04, 0x42, 0x42, 0xF0, 0x00, 0x42, 0x28, 0x46, 0xC3, 0xF8, 0x00, 0x2B, 0xF8, 0xBD, -+0x01, 0x20, 0xF8, 0xBD, 0x02, 0x20, 0xF8, 0xBD, 0x38, 0x46, 0xF8, 0xBD, 0x05, 0x20, 0xF8, 0xBD, 0x06, 0x48, 0xFC, 0xF7, -+0xEB, 0xFF, 0x03, 0x20, 0xF8, 0xBD, 0x00, 0xBF, 0x6F, 0x26, 0x17, 0x00, 0x08, 0x28, 0x17, 0x00, 0x44, 0x60, 0x17, 0x00, -+0xFF, 0xFF, 0x07, 0x00, 0x80, 0x84, 0x15, 0x00, 0x10, 0xB5, 0x0C, 0x4C, 0x0C, 0x4B, 0xE0, 0x89, 0x18, 0x80, 0x20, 0xB9, -+0x0B, 0x4B, 0x03, 0x22, 0x1A, 0x70, 0x01, 0x20, 0x10, 0xBD, 0x0A, 0x4B, 0x5B, 0x69, 0x4B, 0xB1, 0xC0, 0xB2, 0x98, 0x47, -+0x30, 0xB1, 0x06, 0x4A, 0x04, 0x21, 0x07, 0x23, 0x11, 0x70, 0x23, 0x70, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, -+0xB4, 0x27, 0x17, 0x00, 0x6C, 0x26, 0x17, 0x00, 0x6F, 0x26, 0x17, 0x00, 0x20, 0x26, 0x17, 0x00, 0xF8, 0xB5, 0x0C, 0x46, -+0x00, 0x28, 0x70, 0xD1, 0x01, 0xF0, 0x21, 0x03, 0x21, 0x2B, 0x7F, 0xD0, 0xE1, 0x07, 0x76, 0xD5, 0x14, 0xF0, 0x08, 0x01, -+0x00, 0xF0, 0x8B, 0x80, 0xB5, 0x4D, 0x2B, 0x78, 0x00, 0x2B, 0x40, 0xF0, 0x76, 0x82, 0x63, 0x06, 0x40, 0xF1, 0x15, 0x81, -+0xB2, 0x4B, 0xD3, 0xF8, 0x14, 0x3B, 0x08, 0x3B, 0x00, 0x22, 0xC5, 0xE9, 0x01, 0x22, 0x02, 0x20, 0x28, 0x70, 0x1A, 0x78, -+0x29, 0x7B, 0xD2, 0x09, 0x62, 0xF3, 0xC7, 0x11, 0x29, 0x73, 0x19, 0x78, 0x2A, 0x7B, 0x49, 0x11, 0x61, 0xF3, 0x46, 0x12, -+0x2A, 0x73, 0x19, 0x78, 0x61, 0xF3, 0x04, 0x02, 0x2A, 0x73, 0x5A, 0x78, 0x6A, 0x73, 0xD9, 0x78, 0x9A, 0x78, 0x42, 0xEA, -+0x01, 0x22, 0xEA, 0x81, 0x59, 0x79, 0x1A, 0x79, 0x42, 0xEA, 0x01, 0x22, 0x2A, 0x82, 0xDA, 0x79, 0x9B, 0x79, 0x43, 0xEA, -+0x02, 0x23, 0x6B, 0x82, 0x23, 0xB9, 0x95, 0xF9, 0x0C, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0x73, 0x82, 0x9A, 0x4B, 0x9B, 0x4C, -+0xD3, 0xF8, 0x14, 0x28, 0xE1, 0x68, 0x22, 0xF0, 0x10, 0x02, 0xC3, 0xF8, 0x14, 0x28, 0xD3, 0xF8, 0x10, 0x28, 0x22, 0xF0, -+0x10, 0x02, 0xC3, 0xF8, 0x10, 0x28, 0x21, 0xB1, 0x91, 0x48, 0x88, 0x47, 0x00, 0x28, 0x40, 0xF0, 0xB5, 0x80, 0x92, 0x4F, -+0x2B, 0x7B, 0x3A, 0x78, 0x13, 0xF0, 0x60, 0x0F, 0xD6, 0xB2, 0x40, 0xF0, 0xCF, 0x80, 0x68, 0x7B, 0x0B, 0x28, 0x00, 0xF2, -+0xDA, 0x80, 0xDF, 0xE8, 0x10, 0xF0, 0xDE, 0x00, 0x27, 0x01, 0xD8, 0x00, 0xFA, 0x00, 0xD8, 0x00, 0x8C, 0x00, 0x5D, 0x01, -+0xD8, 0x00, 0x4F, 0x01, 0x44, 0x01, 0x98, 0x01, 0x85, 0x01, 0x82, 0x4D, 0x2B, 0x78, 0x02, 0x2B, 0x53, 0xD0, 0xCA, 0x07, -+0x55, 0xD4, 0xA1, 0x06, 0x02, 0xD5, 0x2B, 0x78, 0x06, 0x2B, 0x3D, 0xD0, 0xF8, 0xBD, 0x7C, 0x4D, 0x22, 0x07, 0x2B, 0x78, -+0x35, 0xD5, 0x01, 0x2B, 0x8B, 0xD0, 0xF8, 0xBD, 0x79, 0x4A, 0xD2, 0xF8, 0x10, 0x3B, 0x03, 0xF0, 0x7F, 0x03, 0x40, 0x2B, -+0x7F, 0xF4, 0x78, 0xAF, 0xD2, 0xF8, 0x10, 0x3B, 0x18, 0x03, 0x7F, 0xF5, 0x73, 0xAF, 0xBD, 0xE8, 0xF8, 0x40, 0xFF, 0xF7, -+0xDB, 0xBA, 0x74, 0x4B, 0x6F, 0x4D, 0x1E, 0x68, 0xF3, 0x78, 0x13, 0xF0, 0x01, 0x03, 0x40, 0xF0, 0xE2, 0x81, 0x2A, 0x78, -+0x02, 0x2A, 0x3F, 0xF4, 0x6E, 0xAF, 0x03, 0x2A, 0x00, 0xF0, 0xE6, 0x81, 0x05, 0x2A, 0x0D, 0xD1, 0x68, 0x4A, 0x2B, 0x70, -+0xD2, 0xF8, 0x14, 0x38, 0x23, 0xF0, 0x10, 0x03, 0xC2, 0xF8, 0x14, 0x38, 0xD2, 0xF8, 0x10, 0x38, 0x23, 0xF0, 0x10, 0x03, -+0xC2, 0xF8, 0x10, 0x38, 0xFF, 0xF7, 0xBA, 0xFA, 0xBF, 0xE7, 0x02, 0x2B, 0xBD, 0xD1, 0x54, 0xE7, 0xFF, 0xF7, 0xB4, 0xFA, -+0x5D, 0x4A, 0x07, 0x23, 0x2B, 0x70, 0xD2, 0xF8, 0x14, 0x38, 0x43, 0xF0, 0x10, 0x03, 0xC2, 0xF8, 0x14, 0x38, 0xBD, 0xE8, -+0xF8, 0x40, 0xFF, 0xF7, 0xC5, 0xBA, 0x5B, 0x48, 0xFC, 0xF7, 0xEC, 0xFE, 0x41, 0xE7, 0x04, 0x2B, 0x00, 0xF0, 0xDD, 0x81, -+0x07, 0x2B, 0xA4, 0xD1, 0x52, 0x4B, 0x57, 0x49, 0x00, 0x20, 0x28, 0x70, 0xD3, 0xF8, 0x14, 0x28, 0x22, 0xF0, 0x10, 0x02, -+0xC3, 0xF8, 0x14, 0x28, 0xD3, 0xF8, 0x10, 0x28, 0x22, 0xF0, 0x10, 0x02, 0xC3, 0xF8, 0x10, 0x28, 0x0A, 0x78, 0x00, 0x2A, -+0x96, 0xD0, 0xD3, 0xF8, 0x04, 0x48, 0x12, 0x01, 0x02, 0xF0, 0x70, 0x02, 0x24, 0xF0, 0x70, 0x04, 0x22, 0x43, 0xC3, 0xF8, -+0x04, 0x28, 0x08, 0x70, 0xF8, 0xBD, 0x43, 0x48, 0xE9, 0x89, 0xD0, 0xF8, 0x00, 0x28, 0x0B, 0x01, 0x22, 0xF4, 0xFE, 0x62, -+0x03, 0xF4, 0xFE, 0x63, 0x13, 0x43, 0x07, 0x22, 0xC0, 0xF8, 0x00, 0x38, 0x2A, 0x70, 0x00, 0x29, 0x40, 0xF0, 0xF2, 0x81, -+0x02, 0x23, 0x3B, 0x70, 0x04, 0x2E, 0x40, 0xF0, 0x9F, 0x80, 0x3B, 0x78, 0x04, 0x2B, 0x01, 0xD0, 0xFF, 0xF7, 0xE8, 0xFA, -+0x2B, 0x78, 0x03, 0x2B, 0x26, 0xD0, 0x04, 0x2B, 0x00, 0xF0, 0xAB, 0x80, 0x07, 0x2B, 0x00, 0xF0, 0x91, 0x80, 0x00, 0x24, -+0x22, 0x46, 0x20, 0x46, 0x4F, 0xF4, 0x00, 0x11, 0x2C, 0x70, 0xFF, 0xF7, 0x2F, 0xFB, 0x22, 0x46, 0x20, 0x46, 0x4F, 0xF4, -+0x00, 0x11, 0xFF, 0xF7, 0x85, 0xFB, 0xBD, 0xE8, 0xF8, 0x40, 0xFF, 0xF7, 0x49, 0xBA, 0x2B, 0x4B, 0x1B, 0x68, 0x5B, 0x68, -+0xEA, 0xE6, 0x2C, 0x48, 0xFC, 0xF7, 0x8A, 0xFE, 0x04, 0x2E, 0xE4, 0xD1, 0x3B, 0x78, 0x04, 0x2B, 0xE1, 0xD0, 0xFF, 0xF7, -+0xBF, 0xFA, 0xDE, 0xE7, 0x6B, 0x68, 0x00, 0x2B, 0x7F, 0xF4, 0x57, 0xAF, 0x25, 0x4B, 0x6B, 0x60, 0x53, 0xE7, 0x04, 0x2E, -+0xD5, 0xD1, 0x3B, 0x78, 0x04, 0x2B, 0xF0, 0xD1, 0xD1, 0xE7, 0x3B, 0x78, 0x04, 0x2B, 0x00, 0xF0, 0xCB, 0x81, 0x2B, 0x8A, -+0x00, 0x2B, 0xE3, 0xD1, 0x2B, 0x7B, 0x03, 0xF0, 0x1F, 0x03, 0x01, 0x2B, 0x00, 0xF0, 0xCF, 0x81, 0x02, 0x2B, 0x00, 0xF0, -+0xC1, 0x80, 0x00, 0x2B, 0xE7, 0xD1, 0x19, 0x4A, 0x19, 0x4B, 0x12, 0x78, 0x1A, 0x80, 0x02, 0x21, 0x04, 0x22, 0x6B, 0x60, -+0x29, 0x81, 0x2A, 0x70, 0x5A, 0xE0, 0x3B, 0x78, 0x04, 0x2B, 0x02, 0xD0, 0x2B, 0x8A, 0x00, 0x2B, 0xC8, 0xD1, 0x2B, 0x7B, -+0x13, 0xF0, 0x1F, 0x03, 0x00, 0xF0, 0xB9, 0x81, 0x02, 0x2B, 0x03, 0xD1, 0xEB, 0x89, 0x00, 0x2B, 0x00, 0xF0, 0xBF, 0x81, -+0x07, 0x23, 0x04, 0x2E, 0x2B, 0x70, 0xA0, 0xD1, 0xC9, 0xE7, 0x00, 0xBF, 0xB4, 0x27, 0x17, 0x00, 0x00, 0x00, 0x20, 0x40, -+0x20, 0x26, 0x17, 0x00, 0x6F, 0x26, 0x17, 0x00, 0x5C, 0x60, 0x17, 0x00, 0x98, 0x84, 0x15, 0x00, 0x70, 0x26, 0x17, 0x00, -+0xD8, 0x84, 0x15, 0x00, 0x74, 0x26, 0x17, 0x00, 0x6E, 0x26, 0x17, 0x00, 0x50, 0x28, 0x17, 0x00, 0x3B, 0x78, 0x04, 0x2B, -+0x02, 0xD0, 0x2B, 0x8A, 0x00, 0x2B, 0x9B, 0xD1, 0x2B, 0x7B, 0x03, 0xF0, 0x1F, 0x03, 0x02, 0x2B, 0xD8, 0xD1, 0xEB, 0x89, -+0x00, 0x2B, 0xD5, 0xD1, 0x28, 0x8A, 0x00, 0xF0, 0x0F, 0x01, 0xC0, 0xF3, 0xC0, 0x10, 0xFF, 0xF7, 0xBF, 0xFB, 0x07, 0x23, -+0x04, 0x2E, 0x2B, 0x70, 0x00, 0xF0, 0x95, 0x81, 0xFF, 0xF7, 0xE6, 0xF9, 0xE7, 0xE6, 0xA9, 0x4B, 0xD3, 0xF8, 0xE0, 0x34, -+0x98, 0x47, 0x04, 0x46, 0x04, 0x2E, 0x5A, 0xD0, 0x00, 0x2C, 0x7F, 0xF4, 0x59, 0xAF, 0x60, 0xE7, 0xA4, 0x4B, 0x6B, 0x60, -+0x02, 0x22, 0x04, 0x23, 0x2A, 0x81, 0x2B, 0x70, 0x04, 0x2E, 0x3F, 0xF4, 0x4A, 0xAF, 0x29, 0x89, 0x68, 0x68, 0xFF, 0xF7, -+0x43, 0xFA, 0xCE, 0xE6, 0xE8, 0x89, 0x03, 0x0A, 0x01, 0x3B, 0x01, 0x0A, 0x0E, 0x2B, 0x3F, 0xF6, 0x62, 0xAF, 0x01, 0xA2, -+0x52, 0xF8, 0x23, 0xF0, 0xC1, 0x97, 0x12, 0x00, 0x05, 0x98, 0x12, 0x00, 0xF1, 0x97, 0x12, 0x00, 0xFF, 0x95, 0x12, 0x00, -+0xFF, 0x95, 0x12, 0x00, 0x65, 0x98, 0x12, 0x00, 0xDB, 0x95, 0x12, 0x00, 0xDB, 0x95, 0x12, 0x00, 0xDB, 0x95, 0x12, 0x00, -+0xDB, 0x95, 0x12, 0x00, 0xDB, 0x95, 0x12, 0x00, 0xDB, 0x95, 0x12, 0x00, 0xDB, 0x95, 0x12, 0x00, 0xDB, 0x95, 0x12, 0x00, -+0x45, 0x98, 0x12, 0x00, 0xA3, 0x69, 0x00, 0x2B, 0x3F, 0xF4, 0x40, 0xAF, 0xE9, 0x89, 0x28, 0x8A, 0x98, 0x47, 0x00, 0x28, -+0x3F, 0xF4, 0x3A, 0xAF, 0x85, 0x4A, 0x86, 0x4B, 0x29, 0x8A, 0x11, 0x80, 0xEA, 0x89, 0x1A, 0x70, 0x07, 0x23, 0x2B, 0x70, -+0x06, 0xE7, 0x3B, 0x78, 0x04, 0x2B, 0xDA, 0xB2, 0x7F, 0xF4, 0x2C, 0xAF, 0x7E, 0x4B, 0x7F, 0x49, 0x18, 0x88, 0x2A, 0x70, -+0x01, 0x23, 0x28, 0x82, 0x69, 0x60, 0x2B, 0x81, 0xAE, 0xE7, 0x3B, 0x78, 0x04, 0x2B, 0xA1, 0xD0, 0xFF, 0xF7, 0xE4, 0xF9, -+0x00, 0x2C, 0x7F, 0xF4, 0xF9, 0xAE, 0x00, 0xE7, 0x01, 0x46, 0xFF, 0xF7, 0x0B, 0xFB, 0x00, 0x28, 0x00, 0xF0, 0x05, 0x81, -+0x74, 0x4B, 0x01, 0x22, 0x1A, 0x80, 0x3A, 0xE7, 0x23, 0x68, 0x01, 0x20, 0x98, 0x47, 0x00, 0x28, 0x3F, 0xF4, 0x0A, 0xAF, -+0x03, 0x78, 0x12, 0x2B, 0x7F, 0xF4, 0x06, 0xAF, 0x42, 0x78, 0x01, 0x2A, 0x7F, 0xF4, 0x02, 0xAF, 0x2B, 0x81, 0x68, 0x60, -+0x6B, 0x8A, 0x2A, 0x89, 0x9A, 0x42, 0x88, 0xBF, 0x2B, 0x81, 0x04, 0x23, 0x2B, 0x70, 0x83, 0xE7, 0xA3, 0x68, 0xC0, 0xB2, -+0x98, 0x47, 0x68, 0x60, 0x00, 0x28, 0x3F, 0xF4, 0xF1, 0xAE, 0x03, 0x78, 0x2B, 0x81, 0xED, 0xE7, 0x63, 0x68, 0x00, 0x20, -+0x98, 0x47, 0x00, 0x28, 0x3F, 0xF4, 0xE8, 0xAE, 0x03, 0x78, 0x09, 0x2B, 0x7F, 0xF4, 0xE4, 0xAE, 0x43, 0x78, 0x02, 0x2B, -+0x7F, 0xF4, 0xE0, 0xAE, 0xC2, 0x78, 0x83, 0x78, 0x68, 0x60, 0x43, 0xEA, 0x02, 0x23, 0x2B, 0x81, 0xC3, 0x79, 0x58, 0x4A, -+0x13, 0xF0, 0x40, 0x0F, 0x13, 0x78, 0x14, 0xBF, 0x43, 0xF0, 0x01, 0x03, 0x23, 0xF0, 0x01, 0x03, 0x13, 0x70, 0xCD, 0xE7, -+0x23, 0x68, 0x0F, 0x20, 0x98, 0x47, 0x00, 0x28, 0x3F, 0xF4, 0xC8, 0xAE, 0x03, 0x78, 0x05, 0x2B, 0x7F, 0xF4, 0xC4, 0xAE, -+0x43, 0x78, 0x0F, 0x2B, 0x7F, 0xF4, 0xC0, 0xAE, 0x83, 0x78, 0xBB, 0xE7, 0x23, 0x68, 0x06, 0x20, 0x98, 0x47, 0x00, 0x28, -+0x3F, 0xF4, 0xB8, 0xAE, 0x03, 0x78, 0x0A, 0x2B, 0x7F, 0xF4, 0xB4, 0xAE, 0x42, 0x78, 0x06, 0x2A, 0x7F, 0xF4, 0xB0, 0xAE, -+0xAC, 0xE7, 0x2B, 0x78, 0x00, 0x2B, 0x51, 0xD1, 0x01, 0x23, 0x2B, 0x70, 0xF8, 0xBD, 0x00, 0x21, 0x01, 0x20, 0xFF, 0xF7, -+0xB3, 0xFA, 0x84, 0xE5, 0x68, 0x89, 0x2B, 0x89, 0x36, 0x88, 0x6A, 0x68, 0x3C, 0x49, 0x1B, 0x1A, 0xC6, 0xF1, 0x40, 0x06, -+0x9B, 0xB2, 0x9E, 0x42, 0xA8, 0xBF, 0x1E, 0x46, 0x10, 0x44, 0x09, 0x68, 0xB2, 0xB2, 0x2D, 0xF0, 0x07, 0xFC, 0x6A, 0x89, -+0x2B, 0x89, 0x16, 0x44, 0xB6, 0xB2, 0xB3, 0x42, 0x6E, 0x81, 0x7F, 0xF4, 0x11, 0xAE, 0x33, 0x4B, 0x1B, 0x69, 0x0B, 0xB1, -+0x28, 0x46, 0x98, 0x47, 0xA0, 0x06, 0x35, 0xD4, 0x06, 0x23, 0x2B, 0x70, 0xF8, 0xBD, 0x29, 0x89, 0x6A, 0x89, 0x88, 0x1A, -+0x80, 0xB2, 0x30, 0xB9, 0x05, 0x23, 0x2B, 0x70, 0xF8, 0xBD, 0x2B, 0x48, 0xFC, 0xF7, 0x00, 0xFD, 0x88, 0xE5, 0x40, 0x28, -+0x22, 0xD0, 0x40, 0x28, 0x28, 0xBF, 0x40, 0x20, 0x00, 0x26, 0x02, 0x44, 0x92, 0xB2, 0x91, 0x42, 0x6A, 0x81, 0x29, 0xD3, -+0x89, 0x1A, 0x89, 0xB2, 0x40, 0x29, 0x0F, 0xD8, 0x79, 0xB9, 0x66, 0xBB, 0x21, 0x4A, 0x05, 0x23, 0x2B, 0x70, 0xD2, 0xF8, -+0x10, 0x38, 0x43, 0xF0, 0x10, 0x03, 0xC2, 0xF8, 0x10, 0x38, 0xF8, 0xBD, 0x01, 0x20, 0xFF, 0xF7, 0x65, 0xFA, 0xA9, 0xE7, -+0x40, 0x21, 0x68, 0x68, 0x10, 0x44, 0xFF, 0xF7, 0x27, 0xF9, 0x98, 0xE5, 0x01, 0x26, 0xDE, 0xE7, 0xFF, 0xF7, 0x8E, 0xF8, -+0x15, 0x4A, 0x07, 0x23, 0x2B, 0x70, 0xD2, 0xF8, 0x14, 0x38, 0x43, 0xF0, 0x10, 0x03, 0xC2, 0xF8, 0x14, 0x38, 0xFF, 0xF7, -+0xA1, 0xF8, 0x8A, 0xE5, 0x10, 0x48, 0xFC, 0xF7, 0xC7, 0xFC, 0x29, 0x89, 0x6A, 0x89, 0xCF, 0xE7, 0x03, 0x23, 0x3B, 0x70, -+0x0C, 0xE6, 0x08, 0x46, 0xFF, 0xF7, 0x0A, 0xF9, 0x7B, 0xE5, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x6C, 0x26, 0x17, 0x00, -+0x6A, 0x26, 0x17, 0x00, 0x68, 0x26, 0x17, 0x00, 0x50, 0x28, 0x17, 0x00, 0x6E, 0x26, 0x17, 0x00, 0x60, 0x60, 0x17, 0x00, -+0x20, 0x26, 0x17, 0x00, 0xB4, 0x84, 0x15, 0x00, 0x00, 0x00, 0x20, 0x40, 0xF0, 0x84, 0x15, 0x00, 0x2B, 0x7B, 0x03, 0xF0, -+0x1F, 0x03, 0x01, 0x2B, 0x07, 0xD0, 0x02, 0x2B, 0x7F, 0xF4, 0x39, 0xAE, 0x28, 0x8A, 0x00, 0xF0, 0x0F, 0x01, 0x04, 0x29, -+0x2A, 0xD9, 0x17, 0x4B, 0x00, 0x22, 0x1A, 0x80, 0x35, 0xE6, 0xE8, 0x89, 0x02, 0x28, 0x19, 0xD0, 0x00, 0xF1, 0xFF, 0x3C, -+0x07, 0x23, 0xDC, 0xF1, 0x00, 0x04, 0x44, 0xEB, 0x0C, 0x04, 0x2B, 0x70, 0x7E, 0xE6, 0x28, 0x8A, 0x00, 0xF0, 0x0F, 0x01, -+0xC0, 0xF3, 0xC0, 0x10, 0xFF, 0xF7, 0x18, 0xFA, 0x07, 0x23, 0x04, 0x2E, 0x2B, 0x70, 0x7F, 0xF4, 0x6B, 0xAE, 0x3B, 0x78, -+0x04, 0x2B, 0x3F, 0xF4, 0x67, 0xAE, 0xC9, 0xE5, 0x2B, 0x8A, 0x07, 0x49, 0x1B, 0x0A, 0x07, 0x22, 0x04, 0x2E, 0x0B, 0x70, -+0x2A, 0x70, 0x7F, 0xF4, 0x5D, 0xAE, 0xF0, 0xE7, 0xC0, 0xF3, 0xC0, 0x10, 0xC7, 0xE6, 0x00, 0xBF, 0x50, 0x28, 0x17, 0x00, -+0x70, 0x26, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0xB4, 0x4B, 0xB5, 0x4D, 0xD3, 0xF8, 0x00, 0x38, 0x13, 0xF4, 0xFE, 0x6F, -+0x03, 0xD0, 0x2B, 0x78, 0x04, 0x2B, 0x00, 0xF0, 0x8F, 0x81, 0xAF, 0x4C, 0xB0, 0x4A, 0xB1, 0x48, 0x00, 0x21, 0x02, 0x23, -+0x2B, 0x70, 0x11, 0x70, 0x1A, 0xF0, 0x1A, 0xFE, 0xD4, 0xF8, 0x00, 0x3E, 0x23, 0xF0, 0x01, 0x03, 0xC4, 0xF8, 0x00, 0x3E, -+0xD4, 0xF8, 0x04, 0x38, 0x23, 0xF0, 0x01, 0x03, 0xC4, 0xF8, 0x04, 0x38, 0xFF, 0xF7, 0x7E, 0xF8, 0xA3, 0x69, 0x1D, 0x06, -+0x03, 0xD5, 0xA3, 0x69, 0x23, 0xF0, 0x80, 0x03, 0xA3, 0x61, 0xA0, 0x4B, 0xD3, 0xF8, 0x04, 0x28, 0x42, 0xF4, 0x00, 0x72, -+0xC3, 0xF8, 0x04, 0x28, 0x5A, 0x69, 0x14, 0x06, 0xFC, 0xD5, 0x01, 0x23, 0x01, 0x2B, 0x9E, 0x4C, 0x9E, 0x4D, 0x9F, 0x4A, -+0x9F, 0x4F, 0x4F, 0xF0, 0x02, 0x0C, 0x1C, 0xD0, 0x4F, 0xEA, 0x43, 0x1E, 0x5E, 0xF8, 0x02, 0x10, 0x11, 0xF0, 0x80, 0x2F, -+0x10, 0xD0, 0x5E, 0xF8, 0x02, 0x00, 0x00, 0x29, 0x40, 0xEA, 0x05, 0x00, 0x4E, 0xF8, 0x02, 0x00, 0xC0, 0xF2, 0x0F, 0x81, -+0x08, 0x04, 0x05, 0xD4, 0x5E, 0xF8, 0x02, 0x10, 0x21, 0xF4, 0x00, 0x41, 0x4E, 0xF8, 0x02, 0x10, 0x05, 0x2B, 0x0A, 0xD0, -+0x01, 0x33, 0x01, 0x2B, 0xE2, 0xD1, 0x21, 0x68, 0x11, 0xF0, 0x80, 0x2F, 0xF8, 0xD0, 0x21, 0x68, 0x29, 0x43, 0x21, 0x60, -+0xF4, 0xE7, 0x84, 0x4B, 0xD3, 0xF8, 0x04, 0x28, 0x42, 0xF4, 0x80, 0x62, 0xC3, 0xF8, 0x04, 0x28, 0xD3, 0xF8, 0x04, 0x28, -+0x42, 0xF0, 0x80, 0x02, 0xC3, 0xF8, 0x04, 0x28, 0x5A, 0x69, 0x51, 0x06, 0xFC, 0xD5, 0x01, 0x23, 0x01, 0x2B, 0x83, 0x4F, -+0xDF, 0xF8, 0x40, 0x82, 0xDF, 0xF8, 0xF8, 0xC1, 0x81, 0x4D, 0xDF, 0xF8, 0x3C, 0xE2, 0x4F, 0xF0, 0x40, 0x06, 0x4F, 0xF0, -+0x02, 0x09, 0x19, 0xD0, 0x5A, 0x01, 0x05, 0xEB, 0x43, 0x10, 0x51, 0x59, 0x11, 0xF0, 0x80, 0x2F, 0x0D, 0xD0, 0x72, 0x44, -+0x16, 0x60, 0x04, 0x68, 0x00, 0x29, 0x44, 0xEA, 0x0C, 0x04, 0x04, 0x60, 0x11, 0xDB, 0x0A, 0x04, 0x03, 0xD4, 0x02, 0x68, -+0x22, 0xF4, 0x00, 0x42, 0x02, 0x60, 0x05, 0x2B, 0x1A, 0xD0, 0x01, 0x33, 0x01, 0x2B, 0xE5, 0xD1, 0x39, 0x68, 0x11, 0xF0, -+0x80, 0x2F, 0xF8, 0xD0, 0x42, 0x46, 0x38, 0x46, 0xE6, 0xE7, 0x8C, 0x03, 0x09, 0xD5, 0xC2, 0xF8, 0x00, 0x90, 0x04, 0x68, -+0x44, 0xF0, 0x80, 0x44, 0x04, 0x60, 0x14, 0x68, 0xA4, 0x07, 0xFC, 0xD5, 0xE1, 0xE7, 0x14, 0x68, 0x64, 0x06, 0xFC, 0xD5, -+0x16, 0x60, 0xF0, 0xE7, 0x5B, 0x4B, 0x4F, 0xF4, 0x86, 0x62, 0x1A, 0x61, 0x1A, 0x69, 0x12, 0xF0, 0x30, 0x0F, 0xFB, 0xD1, -+0xD3, 0xF8, 0x04, 0x28, 0x4F, 0xF0, 0x01, 0x14, 0x42, 0xF4, 0x80, 0x72, 0x29, 0x20, 0x09, 0x21, 0xC3, 0xF8, 0x04, 0x28, -+0xC3, 0xF8, 0x1C, 0x48, 0xC3, 0xF8, 0x14, 0x08, 0xC3, 0xF8, 0x10, 0x18, 0x9A, 0x69, 0x42, 0xF4, 0x40, 0x22, 0x9A, 0x61, -+0x9A, 0x6C, 0x14, 0x03, 0x4C, 0xD4, 0x4C, 0x4D, 0x55, 0x4B, 0xD5, 0xF8, 0x00, 0x28, 0x55, 0x48, 0x00, 0x24, 0x22, 0xF4, -+0xFE, 0x62, 0xC5, 0xF8, 0x00, 0x28, 0x21, 0x46, 0xC3, 0xE9, 0x01, 0x44, 0x40, 0x22, 0x1C, 0x70, 0xF6, 0xF7, 0xDE, 0xFA, -+0x21, 0x46, 0x40, 0x22, 0x4E, 0x48, 0xF6, 0xF7, 0xD9, 0xFA, 0x4E, 0x4A, 0x4E, 0x4B, 0x11, 0x68, 0x4E, 0x4A, 0x1B, 0x68, -+0x12, 0x68, 0x59, 0x60, 0xC5, 0xF8, 0x14, 0x3B, 0xD1, 0x78, 0x4C, 0x4B, 0x4C, 0x48, 0x1F, 0x68, 0x4C, 0x4B, 0x06, 0x6A, -+0x18, 0x68, 0xD3, 0xF8, 0x04, 0xC0, 0x41, 0xF0, 0xC0, 0x01, 0xD1, 0x70, 0xF9, 0x78, 0x41, 0xF0, 0xC0, 0x01, 0xF9, 0x70, -+0xC1, 0x78, 0x41, 0xF0, 0xC0, 0x01, 0xC1, 0x70, 0x9C, 0xF8, 0x03, 0x10, 0xD3, 0xE9, 0x02, 0x70, 0x41, 0xF0, 0xC0, 0x03, -+0x8C, 0xF8, 0x03, 0x30, 0xFB, 0x78, 0x43, 0xF0, 0xC0, 0x03, 0xFB, 0x70, 0xC3, 0x78, 0x43, 0xF0, 0xC0, 0x03, 0xC3, 0x70, -+0xC5, 0xF8, 0x14, 0x29, 0x0E, 0xB1, 0x20, 0x46, 0xB0, 0x47, 0xBD, 0xE8, 0xF8, 0x43, 0x3A, 0x48, 0x1A, 0xF0, 0x10, 0xBD, -+0x39, 0x49, 0x3A, 0x4C, 0x24, 0x4A, 0x40, 0xF2, 0x17, 0x15, 0x5D, 0x62, 0x4F, 0xF4, 0x9C, 0x70, 0x9C, 0x62, 0x08, 0x80, -+0xD3, 0xF8, 0x04, 0x18, 0x41, 0xF0, 0x80, 0x01, 0xC3, 0xF8, 0x04, 0x18, 0x53, 0x69, 0x58, 0x06, 0xFC, 0xD5, 0x1C, 0x49, -+0x0B, 0x69, 0x00, 0x2B, 0xFC, 0xDA, 0x4F, 0xF4, 0x84, 0x63, 0x19, 0x4A, 0x0B, 0x61, 0x13, 0x69, 0x99, 0x06, 0xFC, 0xD4, -+0xD2, 0xF8, 0x04, 0x38, 0x15, 0x49, 0x43, 0xF4, 0x80, 0x73, 0xC2, 0xF8, 0x04, 0x38, 0xD2, 0xF8, 0x04, 0x38, 0x43, 0xF4, -+0x00, 0x73, 0xC2, 0xF8, 0x04, 0x38, 0x4B, 0x69, 0x1A, 0x06, 0xFC, 0xD5, 0x0B, 0x69, 0x0E, 0x4A, 0x43, 0xF0, 0x10, 0x03, -+0x0B, 0x61, 0x13, 0x69, 0xDB, 0x06, 0xFC, 0xD4, 0xD2, 0xF8, 0x04, 0x38, 0x43, 0xF4, 0x80, 0x63, 0xC2, 0xF8, 0x04, 0x38, -+0x75, 0xE7, 0x4E, 0xF8, 0x07, 0xC0, 0x5E, 0xF8, 0x02, 0x00, 0x40, 0xF0, 0x80, 0x40, 0x4E, 0xF8, 0x02, 0x00, 0x0E, 0xEB, -+0x07, 0x06, 0x30, 0x68, 0x80, 0x07, 0xFC, 0xD5, 0xE2, 0xE6, 0x00, 0xBF, 0x00, 0x00, 0x20, 0x40, 0x6F, 0x26, 0x17, 0x00, -+0x6E, 0x26, 0x17, 0x00, 0x20, 0x85, 0x15, 0x00, 0x00, 0x0B, 0x20, 0x40, 0x00, 0x80, 0x00, 0x08, 0xE0, 0x0A, 0x20, 0x40, -+0xE8, 0x0A, 0x20, 0x40, 0x00, 0x09, 0x20, 0x40, 0xE0, 0x08, 0x20, 0x40, 0xB4, 0x27, 0x17, 0x00, 0x08, 0x28, 0x17, 0x00, -+0xC8, 0x27, 0x17, 0x00, 0x60, 0x60, 0x17, 0x00, 0x5C, 0x60, 0x17, 0x00, 0x40, 0x60, 0x17, 0x00, 0x54, 0x60, 0x17, 0x00, -+0x20, 0x26, 0x17, 0x00, 0x44, 0x60, 0x17, 0x00, 0x28, 0x85, 0x15, 0x00, 0x48, 0x28, 0x17, 0x00, 0x17, 0x01, 0x21, 0x00, -+0x08, 0x09, 0x20, 0x40, 0xE8, 0x08, 0x20, 0x40, 0x05, 0x48, 0x1E, 0x21, 0x1A, 0xF0, 0x90, 0xFC, 0x4F, 0xF4, 0xF0, 0x42, -+0x01, 0x21, 0x40, 0xF2, 0x1E, 0x40, 0x18, 0xF0, 0x7F, 0xFC, 0x64, 0xE6, 0x0C, 0x85, 0x15, 0x00, 0x08, 0xB5, 0x04, 0x49, -+0x04, 0x48, 0x1A, 0xF0, 0x81, 0xFC, 0x04, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0x08, 0xBD, 0x00, 0xBF, 0x54, 0x85, 0x15, 0x00, -+0xCC, 0xB5, 0x15, 0x00, 0x52, 0x28, 0x17, 0x00, 0x01, 0x4B, 0x18, 0x78, 0x70, 0x47, 0x00, 0xBF, 0x52, 0x28, 0x17, 0x00, -+0x08, 0xB5, 0x07, 0x48, 0x1A, 0xF0, 0x6C, 0xFC, 0x06, 0x4B, 0x07, 0x4A, 0x00, 0x21, 0x19, 0x70, 0xD2, 0xF8, 0x00, 0x3E, -+0x23, 0xF0, 0x01, 0x03, 0xC2, 0xF8, 0x00, 0x3E, 0x08, 0xBD, 0x00, 0xBF, 0x30, 0x85, 0x15, 0x00, 0x52, 0x28, 0x17, 0x00, -+0x00, 0x00, 0x20, 0x40, 0x38, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x1A, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x1A, 0x4C, 0x1A, 0x4D, 0x23, 0x68, 0x2A, 0x78, 0x01, 0x33, 0x23, 0x60, 0x1A, 0xB1, 0x18, 0x4A, 0x12, 0x78, -+0x04, 0x2A, 0x08, 0xD0, 0x33, 0xB1, 0x13, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, -+0x38, 0xBD, 0x13, 0x4A, 0x13, 0x49, 0xD2, 0xF8, 0x04, 0x38, 0x43, 0xF0, 0x01, 0x03, 0xC2, 0xF8, 0x04, 0x38, 0x0A, 0x69, -+0x02, 0xF5, 0x0C, 0x52, 0x28, 0x32, 0x0B, 0x69, 0xD3, 0x1A, 0x00, 0x2B, 0xFB, 0xDA, 0x0B, 0x4A, 0x0C, 0x48, 0xD2, 0xF8, -+0x04, 0x38, 0x23, 0xF0, 0x01, 0x03, 0xC2, 0xF8, 0x04, 0x38, 0x1A, 0xF0, 0x23, 0xFC, 0x00, 0x22, 0x23, 0x68, 0x2A, 0x70, -+0xD8, 0xE7, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x52, 0x28, 0x17, 0x00, 0x6F, 0x26, 0x17, 0x00, -+0x00, 0x00, 0x20, 0x40, 0x00, 0x10, 0x50, 0x40, 0x3C, 0x85, 0x15, 0x00, 0x38, 0xB5, 0x04, 0x46, 0x0D, 0x46, 0xFF, 0xF7, -+0xB1, 0xFF, 0x15, 0x4B, 0x1B, 0x78, 0x04, 0x2B, 0x20, 0xD1, 0x62, 0x1E, 0xD3, 0xB2, 0x04, 0x2B, 0x1E, 0xD8, 0x60, 0x01, -+0x00, 0xF1, 0x80, 0x40, 0x00, 0xF5, 0x00, 0x10, 0xD0, 0xF8, 0x00, 0x39, 0x1B, 0x04, 0x17, 0xD5, 0x0D, 0x49, 0x53, 0x01, -+0x03, 0xF1, 0x80, 0x43, 0x01, 0xEB, 0x02, 0x12, 0x03, 0xF5, 0x00, 0x13, 0x01, 0x21, 0xD1, 0x72, 0xC3, 0xF8, 0x34, 0x59, -+0xD0, 0xF8, 0x00, 0x39, 0x43, 0xF0, 0x04, 0x43, 0xC0, 0xF8, 0x00, 0x39, 0x00, 0x20, 0x38, 0xBD, 0x01, 0x20, 0x38, 0xBD, -+0x02, 0x20, 0x38, 0xBD, 0x05, 0x20, 0x38, 0xBD, 0x6F, 0x26, 0x17, 0x00, 0xC8, 0x27, 0x17, 0x00, 0x93, 0x4B, 0x5A, 0x69, -+0x2D, 0xE9, 0xF0, 0x4F, 0x5A, 0x61, 0x9C, 0x69, 0x14, 0x40, 0xE1, 0x04, 0x85, 0xB0, 0x0A, 0xD5, 0x8F, 0x4B, 0xD3, 0xF8, -+0xDC, 0x34, 0x98, 0x47, 0x14, 0xF4, 0x00, 0x5A, 0x40, 0xF0, 0xAB, 0x80, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xDF, 0xF8, -+0x44, 0xA2, 0xA2, 0x04, 0x04, 0xEA, 0x0A, 0x0A, 0x04, 0xF4, 0x80, 0x25, 0x04, 0xF4, 0x00, 0x29, 0x04, 0xF4, 0x00, 0x6B, -+0x00, 0xF1, 0x9F, 0x80, 0x00, 0x2D, 0x42, 0xD0, 0x81, 0x4D, 0x83, 0x4E, 0xD5, 0xF8, 0x18, 0x28, 0xD5, 0xF8, 0x1C, 0x38, -+0x00, 0x24, 0x02, 0xEA, 0x03, 0x08, 0x01, 0x20, 0x00, 0xFA, 0x04, 0xF3, 0x13, 0xEA, 0x08, 0x0F, 0xE7, 0xB2, 0x2D, 0xD0, -+0x00, 0x2C, 0x00, 0xF0, 0xA0, 0x80, 0x63, 0x1E, 0x05, 0xEB, 0x43, 0x13, 0xD3, 0xF8, 0x28, 0x29, 0xC3, 0xF8, 0x28, 0x29, -+0xD5, 0xF8, 0x10, 0x18, 0x11, 0x40, 0x11, 0xF0, 0x09, 0x0F, 0x74, 0xD0, 0x16, 0xF8, 0x05, 0x3C, 0xD3, 0xB1, 0x56, 0xF8, -+0x0C, 0x3C, 0x01, 0x93, 0xD2, 0x43, 0x56, 0xF8, 0x10, 0x3C, 0x02, 0x93, 0x12, 0xF0, 0x01, 0x03, 0x00, 0x93, 0x40, 0xF0, -+0xB6, 0x80, 0x10, 0x22, 0x00, 0x21, 0xA6, 0xF1, 0x10, 0x00, 0xF6, 0xF7, 0x15, 0xF9, 0x6A, 0x4B, 0x03, 0xEB, 0x84, 0x03, -+0x1B, 0x6B, 0x1B, 0xB1, 0xDD, 0xE9, 0x00, 0x21, 0x02, 0x98, 0x98, 0x47, 0x04, 0x2F, 0x02, 0xD0, 0x01, 0x34, 0x10, 0x36, -+0xC5, 0xE7, 0xB9, 0xF1, 0x00, 0x0F, 0x3C, 0xD0, 0x5E, 0x4D, 0x62, 0x4E, 0xD5, 0xF8, 0x18, 0x78, 0xD5, 0xF8, 0x1C, 0x38, -+0xDF, 0xF8, 0x90, 0x81, 0xDF, 0xF8, 0x74, 0x91, 0x1F, 0x40, 0x00, 0x24, 0x4F, 0xF4, 0x80, 0x33, 0xA3, 0x40, 0x3B, 0x42, -+0x0C, 0xD0, 0xC4, 0xB1, 0x63, 0x1E, 0x05, 0xEB, 0x43, 0x13, 0xD3, 0xF8, 0x28, 0x2B, 0xC3, 0xF8, 0x28, 0x2B, 0xD5, 0xF8, -+0x14, 0x38, 0x13, 0x40, 0xDB, 0x07, 0x5F, 0xD4, 0xE3, 0xB2, 0x04, 0x2B, 0x1B, 0xD0, 0x01, 0x34, 0x4F, 0xF4, 0x80, 0x33, -+0xA3, 0x40, 0x3B, 0x42, 0x06, 0xF1, 0x10, 0x06, 0xF4, 0xD0, 0x00, 0x2C, 0xE6, 0xD1, 0xD5, 0xF8, 0x08, 0x1B, 0xC5, 0xF8, -+0x08, 0x1B, 0xD5, 0xF8, 0x14, 0x38, 0x0B, 0x40, 0xDA, 0x06, 0x7B, 0xD4, 0x13, 0xF0, 0x29, 0x0F, 0xE9, 0xD0, 0x44, 0x4B, -+0x20, 0x46, 0xD3, 0xF8, 0x00, 0x31, 0x98, 0x47, 0xE3, 0xE7, 0xBB, 0xF1, 0x00, 0x0F, 0x03, 0xD0, 0x3F, 0x4B, 0xD3, 0xF8, -+0x8C, 0x34, 0x98, 0x47, 0xBA, 0xF1, 0x00, 0x0F, 0xBF, 0xF6, 0x60, 0xAF, 0x3B, 0x4B, 0xD3, 0xF8, 0x90, 0x34, 0x05, 0xB0, -+0xBD, 0xE8, 0xF0, 0x4F, 0x18, 0x47, 0x3C, 0x48, 0xFC, 0xF7, 0x56, 0xF9, 0xA4, 0xE7, 0x4F, 0xF0, 0x00, 0x0B, 0xD9, 0x46, -+0x5D, 0x46, 0x33, 0x4B, 0xD3, 0xF8, 0x08, 0x38, 0x13, 0xF0, 0x06, 0x0F, 0xC3, 0xF3, 0x47, 0x02, 0x04, 0xD0, 0xD3, 0x07, -+0x02, 0xD5, 0x34, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x2C, 0x4B, 0x33, 0x4A, 0xC3, 0xF8, 0x00, 0x29, 0xC3, 0xF8, 0x00, 0x2B, -+0xFE, 0xF7, 0xF4, 0xFC, 0x4A, 0xE7, 0xD5, 0xF8, 0x08, 0x19, 0xC5, 0xF8, 0x08, 0x19, 0xD5, 0xF8, 0x10, 0x38, 0x0B, 0x40, -+0x13, 0xF0, 0x18, 0x0F, 0x2B, 0xD1, 0xDF, 0x07, 0x80, 0xD5, 0x23, 0x4B, 0xD3, 0xF8, 0x00, 0x31, 0x98, 0x47, 0x7B, 0xE7, -+0x16, 0xF8, 0x08, 0x3C, 0x00, 0x2B, 0x9B, 0xD0, 0x58, 0xF8, 0x24, 0x30, 0x56, 0xF8, 0x0C, 0x1C, 0x1B, 0x88, 0x02, 0x93, -+0x30, 0x46, 0xA3, 0x00, 0x50, 0xF8, 0x10, 0x2D, 0x03, 0x92, 0x01, 0x91, 0x10, 0x22, 0x00, 0x21, 0x00, 0x93, 0xF6, 0xF7, -+0x71, 0xF8, 0x00, 0x9B, 0x4B, 0x44, 0x1B, 0x6A, 0x00, 0x2B, 0x85, 0xD0, 0xDD, 0xE9, 0x01, 0x01, 0x00, 0x22, 0x41, 0x1A, -+0x03, 0x98, 0x98, 0x47, 0x7E, 0xE7, 0x39, 0x46, 0xFE, 0xF7, 0x8A, 0xFE, 0x45, 0xE7, 0xD5, 0xF8, 0x10, 0x38, 0x23, 0xF0, -+0x10, 0x03, 0xC5, 0xF8, 0x10, 0x38, 0x22, 0x46, 0x4F, 0xF4, 0x00, 0x11, 0x20, 0x46, 0xFE, 0xF7, 0xE9, 0xFD, 0x49, 0xE7, -+0xD5, 0xF8, 0x14, 0x38, 0x23, 0xF0, 0x10, 0x03, 0xC5, 0xF8, 0x14, 0x38, 0x22, 0x46, 0x4F, 0xF4, 0x00, 0x11, 0x20, 0x46, -+0xFE, 0xF7, 0x80, 0xFD, 0x63, 0xE7, 0x00, 0xBF, 0x00, 0x00, 0x20, 0x40, 0x88, 0x1A, 0x17, 0x00, 0xC8, 0x27, 0x17, 0x00, -+0x20, 0x26, 0x17, 0x00, 0x08, 0x28, 0x17, 0x00, 0x48, 0x85, 0x15, 0x00, 0x4C, 0x28, 0x17, 0x00, 0x00, 0x80, 0x00, 0x08, -+0x00, 0x3C, 0x0C, 0x88, 0x40, 0x60, 0x17, 0x00, 0x38, 0xB9, 0x0C, 0x4A, 0x0C, 0x4B, 0x10, 0x70, 0x18, 0x70, 0x0C, 0x4B, -+0x1B, 0x68, 0x5B, 0xB1, 0x18, 0x47, 0x01, 0x28, 0x09, 0xD0, 0x09, 0x4B, 0x02, 0x38, 0x1B, 0x68, 0x01, 0x28, 0x94, 0xBF, -+0x02, 0x20, 0x03, 0x20, 0x00, 0x2B, 0xF3, 0xD1, 0x70, 0x47, 0x05, 0x4A, 0x05, 0x4B, 0x10, 0x70, 0x18, 0x70, 0xEA, 0xE7, -+0x59, 0x28, 0x17, 0x00, 0x5A, 0x28, 0x17, 0x00, 0x60, 0x28, 0x17, 0x00, 0x5B, 0x28, 0x17, 0x00, 0x5C, 0x28, 0x17, 0x00, -+0x00, 0x48, 0x70, 0x47, 0x54, 0x86, 0x15, 0x00, 0x01, 0x28, 0x15, 0xD1, 0x08, 0xB5, 0x0B, 0x4B, 0x1B, 0x68, 0x0B, 0xB1, -+0x04, 0x20, 0x98, 0x47, 0x02, 0x22, 0x11, 0x46, 0x4F, 0xF4, 0x00, 0x73, 0x01, 0x20, 0xFE, 0xF7, 0x65, 0xFF, 0x4F, 0xF4, -+0x00, 0x73, 0x02, 0x22, 0x01, 0x21, 0x00, 0x20, 0xFE, 0xF7, 0x5E, 0xFF, 0x01, 0x20, 0x08, 0xBD, 0x00, 0x20, 0x70, 0x47, -+0x60, 0x28, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x58, 0x4E, 0xDF, 0xF8, 0x9C, 0xE1, 0x33, 0x88, 0x57, 0x4C, 0x00, 0x2A, -+0x03, 0xF1, 0x01, 0x03, 0x0C, 0xBF, 0x02, 0x25, 0x03, 0x25, 0x9B, 0xB2, 0x00, 0x27, 0x33, 0x80, 0x8E, 0xF8, 0x00, 0x50, -+0x27, 0x70, 0x9E, 0xF8, 0x00, 0xC0, 0xBC, 0xF1, 0x02, 0x0F, 0x4C, 0xD1, 0x03, 0x29, 0x04, 0x46, 0x0D, 0x46, 0x8E, 0xF8, -+0x00, 0x70, 0x55, 0xD9, 0x43, 0x78, 0x4C, 0x4A, 0x07, 0x78, 0x12, 0x78, 0x90, 0xF8, 0x02, 0x80, 0x1B, 0x02, 0x03, 0xF4, -+0x70, 0x63, 0x1F, 0x43, 0x00, 0x2A, 0x78, 0xD1, 0xB8, 0xF1, 0x01, 0x0F, 0x64, 0xD0, 0xB8, 0xF1, 0x11, 0x0F, 0x55, 0xD1, -+0xDF, 0xF8, 0x44, 0x81, 0x98, 0xF8, 0x9D, 0x27, 0x98, 0xF8, 0x9E, 0x37, 0x9A, 0x42, 0x77, 0xD2, 0x3B, 0x1D, 0xAB, 0x42, -+0x02, 0xD0, 0x7B, 0x1D, 0x9D, 0x42, 0x6E, 0xD1, 0x3D, 0x4B, 0xD3, 0xF8, 0x3C, 0x34, 0x98, 0x47, 0x98, 0xF8, 0x9C, 0x37, -+0x3B, 0x49, 0x98, 0xF8, 0x9D, 0x27, 0x01, 0x33, 0xA1, 0xFB, 0x03, 0x01, 0x49, 0x09, 0x01, 0xEB, 0x81, 0x01, 0xA3, 0xEB, -+0xC1, 0x01, 0x08, 0xEB, 0x01, 0x15, 0x04, 0x34, 0x53, 0x1C, 0x88, 0xF8, 0x9C, 0x17, 0x34, 0x48, 0xC5, 0xF8, 0x20, 0x45, -+0x05, 0xF2, 0x1C, 0x51, 0xC5, 0xF8, 0x24, 0x75, 0x88, 0xF8, 0x9D, 0x37, 0x19, 0xF0, 0x22, 0xF8, 0x4F, 0xF4, 0x00, 0x00, -+0x18, 0xF0, 0x7C, 0xFF, 0x0B, 0xE0, 0x9E, 0xF8, 0x00, 0x10, 0x2C, 0x48, 0xFC, 0xF7, 0x28, 0xF8, 0x47, 0xF2, 0x30, 0x52, -+0x01, 0x21, 0x40, 0xF2, 0x1E, 0x40, 0x18, 0xF0, 0xE1, 0xF9, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x31, 0x88, 0x26, 0x48, -+0x89, 0xB2, 0x2A, 0x46, 0xFC, 0xF7, 0x18, 0xF8, 0x24, 0x4B, 0x18, 0x68, 0x20, 0x1A, 0xFD, 0xF7, 0x05, 0xF9, 0x1D, 0x4B, -+0xD3, 0xF8, 0x3C, 0x34, 0x98, 0x47, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x41, 0x46, 0x1F, 0x48, 0xFC, 0xF7, 0x08, 0xF8, -+0x31, 0x88, 0x1E, 0x48, 0x89, 0xB2, 0x2B, 0x46, 0x3A, 0x46, 0xFC, 0xF7, 0x01, 0xF8, 0xE7, 0xE7, 0xBD, 0x42, 0x02, 0xD0, -+0x7B, 0x1C, 0xAB, 0x42, 0x12, 0xD1, 0x11, 0x4D, 0xD5, 0xF8, 0x3C, 0x34, 0x98, 0x47, 0x20, 0x1D, 0xD5, 0xF8, 0x0C, 0x31, -+0x98, 0x47, 0x40, 0x20, 0x18, 0xF0, 0x3E, 0xFF, 0xCD, 0xE7, 0x0A, 0x46, 0x4F, 0xF4, 0x00, 0x70, 0x11, 0x49, 0x1A, 0xF0, -+0x03, 0xFA, 0x7F, 0xE7, 0x31, 0x88, 0x10, 0x48, 0xDE, 0xE7, 0x31, 0x88, 0x0F, 0x48, 0xDB, 0xE7, 0x0F, 0x48, 0xFB, 0xF7, -+0xDF, 0xFF, 0xC5, 0xE7, 0x56, 0x28, 0x17, 0x00, 0x58, 0x28, 0x17, 0x00, 0x64, 0x28, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xCD, 0xCC, 0xCC, 0xCC, 0xF8, 0x5F, 0x17, 0x00, 0xD0, 0x85, 0x15, 0x00, 0xC0, 0x85, 0x15, 0x00, 0x80, 0x1A, 0x17, 0x00, -+0xB0, 0x85, 0x15, 0x00, 0x78, 0x85, 0x15, 0x00, 0x68, 0x85, 0x15, 0x00, 0x70, 0x85, 0x15, 0x00, 0x84, 0x85, 0x15, 0x00, -+0x98, 0x85, 0x15, 0x00, 0x59, 0x28, 0x17, 0x00, 0x58, 0x58, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x00, 0x2A, 0x2A, 0x4B, -+0x0C, 0xBF, 0x02, 0x21, 0x03, 0x21, 0x19, 0x70, 0x19, 0x78, 0x02, 0x29, 0x3D, 0xD1, 0x27, 0x4C, 0x22, 0x78, 0x00, 0x21, -+0x19, 0x70, 0x52, 0xB3, 0x25, 0x4D, 0x26, 0x4F, 0xA5, 0xF1, 0x08, 0x06, 0x0A, 0xE0, 0x01, 0x2A, 0x41, 0x46, 0x38, 0x46, -+0x28, 0xD1, 0x13, 0x2B, 0x40, 0x46, 0x01, 0xD0, 0xFD, 0xF7, 0x90, 0xF8, 0x23, 0x78, 0xD3, 0xB1, 0x28, 0x46, 0x18, 0xF0, -+0xCD, 0xFF, 0x42, 0x68, 0x23, 0x78, 0xD2, 0xF8, 0x04, 0x80, 0x01, 0x3B, 0x01, 0x46, 0x30, 0x46, 0x23, 0x70, 0x18, 0xF0, -+0x7F, 0xFF, 0x98, 0xF8, 0x02, 0x30, 0x1A, 0x09, 0xE3, 0xD1, 0x17, 0x4A, 0x13, 0x88, 0x10, 0x20, 0x01, 0x33, 0x13, 0x80, -+0x18, 0xF0, 0xD2, 0xFE, 0x23, 0x78, 0x00, 0x2B, 0xE4, 0xD1, 0x13, 0x4B, 0xD3, 0xF8, 0x44, 0x34, 0x98, 0x47, 0x01, 0x20, -+0xBD, 0xE8, 0xF0, 0x81, 0xFB, 0xF7, 0x78, 0xFF, 0x40, 0x46, 0x20, 0x21, 0x1A, 0xF0, 0x1C, 0xFD, 0xD4, 0xE7, 0x19, 0x78, -+0x0C, 0x48, 0xFB, 0xF7, 0x6F, 0xFF, 0x47, 0xF2, 0x30, 0x52, 0x01, 0x21, 0x40, 0xF2, 0x1E, 0x40, 0x18, 0xF0, 0x28, 0xF9, -+0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0xBF, 0x5A, 0x28, 0x17, 0x00, 0x64, 0x60, 0x17, 0x00, 0xA8, 0x56, 0x17, 0x00, -+0xF0, 0x85, 0x15, 0x00, 0x54, 0x28, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x00, 0x86, 0x15, 0x00, 0x10, 0x4B, 0x11, 0x49, -+0x11, 0x4A, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x00, 0x68, 0x18, 0x60, 0xDF, 0xF8, 0x44, 0x80, 0x0E, 0x4F, 0x0F, 0x4E, -+0x00, 0x23, 0x0B, 0x70, 0x13, 0x70, 0x29, 0x7A, 0xD8, 0xF8, 0x08, 0x31, 0x00, 0x39, 0x18, 0xBF, 0x01, 0x21, 0x38, 0x46, -+0x98, 0x47, 0x04, 0x46, 0x01, 0x46, 0x30, 0x46, 0x1A, 0xF0, 0x04, 0xF9, 0x00, 0x2C, 0xF0, 0xD1, 0x20, 0x46, 0xBD, 0xE8, -+0xF0, 0x81, 0x00, 0xBF, 0x60, 0x28, 0x17, 0x00, 0x59, 0x28, 0x17, 0x00, 0x5A, 0x28, 0x17, 0x00, 0x38, 0x1A, 0x17, 0x00, -+0x20, 0x86, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xF8, 0xB5, 0x1D, 0x4D, 0x2B, 0x78, 0xFB, 0xB9, 0xD8, 0xB1, 0x0A, 0x46, -+0xC9, 0xB1, 0x1B, 0x4F, 0x3B, 0x78, 0xE3, 0xB9, 0x1A, 0x4C, 0x01, 0x26, 0x3E, 0x70, 0xD4, 0xF8, 0x30, 0x3B, 0x23, 0xF0, -+0xFF, 0x53, 0x23, 0xF4, 0xC0, 0x13, 0x01, 0x46, 0xC4, 0xF8, 0x30, 0x3B, 0x30, 0x46, 0xFE, 0xF7, 0x7B, 0xFE, 0x04, 0x46, -+0xC8, 0xB9, 0x13, 0x4B, 0x1E, 0x70, 0x2B, 0x78, 0x73, 0xB9, 0x20, 0x46, 0xF8, 0xBD, 0x6F, 0xF0, 0x0A, 0x04, 0xFA, 0xE7, -+0x6F, 0xF0, 0x0D, 0x04, 0xF7, 0xE7, 0x39, 0x78, 0x0D, 0x48, 0xFB, 0xF7, 0xFD, 0xFE, 0x6F, 0xF0, 0x02, 0x04, 0xF0, 0xE7, -+0x31, 0x46, 0xFE, 0xF7, 0xB3, 0xFC, 0x3C, 0x70, 0x6F, 0xF0, 0x0D, 0x04, 0xE9, 0xE7, 0x01, 0x46, 0x07, 0x48, 0xFB, 0xF7, -+0xEF, 0xFE, 0x4F, 0xF0, 0xFF, 0x34, 0xE2, 0xE7, 0x5B, 0x28, 0x17, 0x00, 0x59, 0x28, 0x17, 0x00, 0x00, 0x00, 0x20, 0x40, -+0x58, 0x28, 0x17, 0x00, 0x30, 0x86, 0x15, 0x00, 0x48, 0x86, 0x15, 0x00, 0xF8, 0xB5, 0x20, 0x4D, 0x2B, 0x78, 0x2B, 0xBB, -+0x08, 0xB3, 0x0A, 0x46, 0xF9, 0xB1, 0x1E, 0x4F, 0x3B, 0x78, 0x13, 0xBB, 0x1D, 0x4C, 0x01, 0x26, 0x3E, 0x70, 0xD4, 0xF8, -+0x30, 0x3B, 0x23, 0xF0, 0xFF, 0x53, 0x23, 0xF4, 0xC0, 0x13, 0xC4, 0xF8, 0x30, 0x3B, 0xD4, 0xF8, 0x00, 0x38, 0x43, 0xF4, -+0x00, 0x53, 0x01, 0x46, 0xC4, 0xF8, 0x00, 0x38, 0x30, 0x46, 0xFE, 0xF7, 0x87, 0xFE, 0x04, 0x46, 0xC8, 0xB9, 0x13, 0x4B, -+0x1E, 0x70, 0x2B, 0x78, 0x73, 0xB9, 0x20, 0x46, 0xF8, 0xBD, 0x6F, 0xF0, 0x0A, 0x04, 0xFA, 0xE7, 0x6F, 0xF0, 0x0D, 0x04, -+0xF7, 0xE7, 0x39, 0x78, 0x0D, 0x48, 0xFB, 0xF7, 0xAF, 0xFE, 0x6F, 0xF0, 0x02, 0x04, 0xF0, 0xE7, 0x31, 0x46, 0xFE, 0xF7, -+0x65, 0xFC, 0x3C, 0x70, 0x6F, 0xF0, 0x0D, 0x04, 0xE9, 0xE7, 0x01, 0x46, 0x07, 0x48, 0xFB, 0xF7, 0xA1, 0xFE, 0x4F, 0xF0, -+0xFF, 0x34, 0xE2, 0xE7, 0x5B, 0x28, 0x17, 0x00, 0x59, 0x28, 0x17, 0x00, 0x00, 0x00, 0x20, 0x40, 0x58, 0x28, 0x17, 0x00, -+0x30, 0x86, 0x15, 0x00, 0x48, 0x86, 0x15, 0x00, 0xF8, 0xB5, 0x26, 0x4C, 0xFF, 0xF7, 0xFE, 0xFB, 0x23, 0x78, 0x00, 0x2B, -+0x42, 0xD1, 0x24, 0x4D, 0x28, 0x46, 0x18, 0xF0, 0xFB, 0xFE, 0xDF, 0xF8, 0x90, 0xC0, 0xC0, 0xB2, 0x8C, 0xF8, 0x00, 0x00, -+0x00, 0x28, 0x31, 0xD0, 0x1F, 0x4A, 0x2F, 0x68, 0x42, 0xF2, 0x30, 0x03, 0x01, 0x28, 0xD6, 0x58, 0x28, 0xD0, 0xBD, 0x89, -+0xB3, 0x89, 0xAB, 0x42, 0x11, 0xD2, 0x39, 0x46, 0x03, 0x46, 0x03, 0xE0, 0x53, 0xB1, 0x95, 0x89, 0x0E, 0x46, 0x11, 0x46, -+0xC2, 0x1A, 0xD2, 0xB2, 0x01, 0x3B, 0xF5, 0xB1, 0x0A, 0x68, 0xDB, 0xB2, 0x00, 0x2A, 0xF3, 0xD1, 0x8C, 0xF8, 0x00, 0x30, -+0x0E, 0x46, 0xB3, 0x7B, 0x72, 0x68, 0x79, 0x68, 0x01, 0x3B, 0x02, 0xEB, 0xC3, 0x02, 0x01, 0x20, 0xD3, 0x78, 0x20, 0x70, -+0x23, 0xF0, 0x0A, 0x03, 0x43, 0xF0, 0x0A, 0x03, 0xD3, 0x70, 0x02, 0x20, 0xBD, 0xE8, 0xF8, 0x40, 0xFF, 0xF7, 0x0A, 0xBC, -+0x00, 0x2E, 0xEA, 0xD1, 0x6F, 0xF0, 0x61, 0x00, 0xF8, 0xBD, 0x8C, 0xF8, 0x00, 0x20, 0xE4, 0xE7, 0x6F, 0xF0, 0x62, 0x00, -+0xF8, 0xBD, 0x00, 0xBF, 0x5A, 0x28, 0x17, 0x00, 0xA8, 0x56, 0x17, 0x00, 0x7C, 0x36, 0x17, 0x00, 0x64, 0x60, 0x17, 0x00, -+0x01, 0x28, 0x07, 0xD0, 0x06, 0x28, 0x07, 0xD0, 0x04, 0x4B, 0x0F, 0x28, 0x0C, 0xBF, 0x18, 0x46, 0x00, 0x20, 0x70, 0x47, -+0x02, 0x48, 0x70, 0x47, 0x02, 0x48, 0x70, 0x47, 0x74, 0x86, 0x15, 0x00, 0x80, 0x86, 0x15, 0x00, 0x94, 0x86, 0x15, 0x00, -+0x06, 0x28, 0x0B, 0xD8, 0x01, 0x38, 0x05, 0x28, 0x16, 0xD8, 0xDF, 0xE8, 0x00, 0xF0, 0x05, 0x03, 0x13, 0x0F, 0x11, 0x03, -+0x09, 0x48, 0x70, 0x47, 0x09, 0x48, 0x70, 0x47, 0x12, 0x30, 0xC0, 0xB2, 0x06, 0x4B, 0x02, 0x28, 0x34, 0xBF, 0x18, 0x46, -+0x00, 0x20, 0x70, 0x47, 0x05, 0x48, 0x70, 0x47, 0x05, 0x48, 0x70, 0x47, 0x05, 0x48, 0x70, 0x47, 0x05, 0x48, 0x70, 0x47, -+0xC4, 0x86, 0x15, 0x00, 0xB4, 0x86, 0x15, 0x00, 0xA0, 0x86, 0x15, 0x00, 0xA8, 0x86, 0x15, 0x00, 0xD8, 0x86, 0x15, 0x00, -+0xEC, 0x86, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0x1D, 0x4F, 0x1E, 0x48, 0x18, 0xF0, 0xE4, 0xFD, 0x3B, 0x68, 0x1B, 0x89, -+0x93, 0xB3, 0xDF, 0xF8, 0x7C, 0x90, 0x1B, 0x4E, 0xDF, 0xF8, 0x78, 0x80, 0xDF, 0xF8, 0x78, 0xB0, 0xDF, 0xF8, 0x78, 0xA0, -+0x00, 0x25, 0x0C, 0xE0, 0x21, 0x46, 0x15, 0x48, 0x18, 0xF0, 0xD6, 0xFD, 0x3A, 0x68, 0x33, 0x88, 0x11, 0x89, 0x01, 0x35, -+0xAA, 0xB2, 0x01, 0x33, 0x91, 0x42, 0x33, 0x80, 0x1A, 0xD9, 0xB9, 0xF8, 0xD4, 0x10, 0x04, 0x39, 0x89, 0xB2, 0x40, 0x46, -+0xFC, 0xF7, 0x58, 0xFC, 0x04, 0x46, 0x00, 0x28, 0xE8, 0xD1, 0xA9, 0xB2, 0x58, 0x46, 0x19, 0xF0, 0x99, 0xFF, 0xDA, 0xF8, -+0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xDE, 0xDA, 0x07, 0x49, 0x07, 0x48, 0x4F, 0xF4, 0xFB, 0x72, 0x1A, 0xF0, -+0x07, 0xFA, 0xD7, 0xE7, 0xBD, 0xE8, 0xF8, 0x8F, 0x78, 0x36, 0x17, 0x00, 0x80, 0x60, 0x17, 0x00, 0x66, 0x28, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x2C, 0x19, 0x17, 0x00, 0xE4, 0x25, 0x17, 0x00, 0xF0, 0x86, 0x15, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x10, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0C, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x0C, 0x4C, 0x0C, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x18, 0xF0, 0xD2, 0xFD, 0x18, 0xB1, 0x0A, 0x4A, -+0x13, 0x88, 0x01, 0x3B, 0x13, 0x80, 0x23, 0x68, 0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x10, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x80, 0x60, 0x17, 0x00, -+0x66, 0x28, 0x17, 0x00, 0x38, 0xB5, 0x01, 0x46, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x28, 0x4B, -+0x01, 0x22, 0x1A, 0x60, 0x27, 0x4C, 0x28, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x18, 0xF0, 0x65, 0xFD, 0x26, 0x4A, -+0x26, 0x49, 0x13, 0x88, 0x0D, 0x78, 0x01, 0x33, 0x9B, 0xB2, 0x13, 0x80, 0x24, 0x4A, 0x11, 0x78, 0x9D, 0xB9, 0x49, 0xB9, -+0x23, 0x68, 0x33, 0xB1, 0x1C, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x38, 0xBD, -+0x1E, 0x49, 0x09, 0x78, 0x99, 0x42, 0xF1, 0xD8, 0x01, 0x21, 0x40, 0xF2, 0x1F, 0x40, 0x15, 0x70, 0x1B, 0xE0, 0x00, 0x29, -+0xEA, 0xD0, 0x19, 0x49, 0x09, 0x78, 0x99, 0x42, 0xE6, 0xD8, 0x18, 0x4B, 0x00, 0x21, 0x11, 0x70, 0xD3, 0xF8, 0x00, 0x28, -+0x22, 0xF4, 0x00, 0x52, 0xC3, 0xF8, 0x00, 0x28, 0xD3, 0xF8, 0x20, 0x2B, 0x8A, 0x42, 0x05, 0xDA, 0xD3, 0xF8, 0x20, 0x2B, -+0x42, 0xF0, 0x80, 0x62, 0xC3, 0xF8, 0x20, 0x2B, 0x01, 0x21, 0x40, 0xF2, 0x1F, 0x40, 0x17, 0xF0, 0xA9, 0xFF, 0x0D, 0x49, -+0x4F, 0xF4, 0x00, 0x70, 0x19, 0xF0, 0x4E, 0xFF, 0x0B, 0x4B, 0xD3, 0xF8, 0x3C, 0x34, 0x98, 0x47, 0xC4, 0xE7, 0x00, 0xBF, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x80, 0x60, 0x17, 0x00, 0x66, 0x28, 0x17, 0x00, 0x68, 0x60, 0x17, 0x00, -+0x64, 0x28, 0x17, 0x00, 0x88, 0x60, 0x17, 0x00, 0x00, 0x00, 0x20, 0x40, 0x20, 0x87, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xF8, 0xB5, 0x0C, 0x4D, 0x0C, 0x48, 0x18, 0xF0, 0x01, 0xFD, 0x2B, 0x68, 0x9B, 0x88, 0x83, 0xB1, 0x0A, 0x4F, 0x09, 0x4E, -+0x00, 0x24, 0x7C, 0x21, 0x38, 0x46, 0xFC, 0xF7, 0x8D, 0xFB, 0x01, 0x46, 0x30, 0x46, 0x18, 0xF0, 0xF7, 0xFC, 0x2B, 0x68, -+0x01, 0x34, 0x9A, 0x88, 0xA3, 0xB2, 0x9A, 0x42, 0xF1, 0xD8, 0xF8, 0xBD, 0x78, 0x36, 0x17, 0x00, 0x70, 0x60, 0x17, 0x00, -+0xE4, 0x25, 0x17, 0x00, 0x10, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x09, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x09, 0x4C, 0x09, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x18, 0xF0, 0x1E, 0xFD, 0x23, 0x68, 0x33, 0xB1, -+0x03, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x10, 0xBD, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x70, 0x60, 0x17, 0x00, 0x10, 0xB5, 0x01, 0x46, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, -+0x72, 0xB6, 0x0A, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x09, 0x4C, 0x0A, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x18, 0xF0, -+0xB9, 0xFC, 0x23, 0x68, 0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, -+0x10, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x70, 0x60, 0x17, 0x00, 0x08, 0xB5, 0x04, 0x48, -+0xFF, 0xF7, 0x5E, 0xFD, 0x03, 0x48, 0x19, 0xF0, 0x7B, 0xFE, 0x01, 0x20, 0x08, 0xBD, 0x00, 0xBF, 0xFC, 0x87, 0x15, 0x00, -+0x28, 0x87, 0x15, 0x00, 0x70, 0xB5, 0x3C, 0x4D, 0x3C, 0x4C, 0x2A, 0x68, 0x3C, 0x49, 0x12, 0x69, 0x3C, 0x4B, 0x22, 0x60, -+0x02, 0xF1, 0x40, 0x06, 0x00, 0x24, 0x0E, 0x60, 0x3A, 0x4E, 0x98, 0x60, 0xC3, 0xE9, 0x00, 0x44, 0x21, 0x46, 0x10, 0x46, -+0x4F, 0xF4, 0xA0, 0x72, 0xC3, 0xE9, 0x04, 0x44, 0xDC, 0x60, 0xB4, 0x81, 0xF5, 0xF7, 0xEC, 0xFB, 0x2B, 0x68, 0x34, 0x49, -+0x58, 0x69, 0x34, 0x4A, 0x34, 0x4B, 0x08, 0x60, 0x21, 0x46, 0x00, 0xF1, 0x08, 0x04, 0x14, 0x60, 0x00, 0xF1, 0x10, 0x02, -+0x1A, 0x60, 0x00, 0xF1, 0x18, 0x02, 0x5A, 0x60, 0x00, 0xF1, 0x20, 0x02, 0x9A, 0x60, 0x2E, 0x4C, 0x00, 0xF1, 0x28, 0x02, -+0xDA, 0x60, 0x00, 0xF1, 0x30, 0x03, 0x4F, 0xF4, 0x4B, 0x62, 0x23, 0x60, 0xF5, 0xF7, 0xCE, 0xFB, 0x29, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x2E, 0xDB, 0x27, 0x4B, 0x28, 0x49, 0xB3, 0xF8, 0xD4, 0x20, 0x0C, 0x68, 0xB3, 0xF8, -+0xD6, 0x00, 0xB3, 0xF8, 0xE6, 0x10, 0x25, 0x4D, 0x25, 0x4E, 0x12, 0x1B, 0x25, 0x4C, 0x04, 0x3A, 0x22, 0x60, 0x04, 0x38, -+0x24, 0x4C, 0x30, 0x60, 0x05, 0xFB, 0x01, 0xF1, 0x93, 0xF8, 0xE0, 0x00, 0x22, 0x4D, 0x20, 0x70, 0x22, 0x4A, 0x93, 0xF8, -+0xE1, 0x00, 0x28, 0x70, 0x93, 0xF8, 0xE2, 0x50, 0x20, 0x48, 0x15, 0x70, 0x20, 0x4C, 0x21, 0x4A, 0x93, 0xF8, 0xE3, 0x50, -+0x93, 0xF8, 0xE4, 0x30, 0x03, 0x70, 0x1F, 0x4B, 0x25, 0x70, 0x91, 0x42, 0xD4, 0xBF, 0x19, 0x60, 0x1A, 0x60, 0x01, 0x20, -+0x70, 0xBD, 0x2B, 0x68, 0x9B, 0x69, 0xB3, 0xF5, 0x4B, 0x6F, 0xCB, 0xD2, 0x19, 0x49, 0x1A, 0x48, 0x40, 0xF2, 0xF2, 0x22, -+0x1A, 0xF0, 0x76, 0xF8, 0xC4, 0xE7, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, 0x60, 0x60, 0x17, 0x00, 0x58, 0x60, 0x17, 0x00, -+0xA4, 0x60, 0x17, 0x00, 0x8C, 0x60, 0x17, 0x00, 0x5C, 0x60, 0x17, 0x00, 0x40, 0x60, 0x17, 0x00, 0x44, 0x60, 0x17, 0x00, -+0x54, 0x60, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x80, 0x1A, 0x17, 0x00, 0x40, 0x42, 0x0F, 0x00, -+0x9C, 0x60, 0x17, 0x00, 0x78, 0x60, 0x17, 0x00, 0x7C, 0x60, 0x17, 0x00, 0x88, 0x60, 0x17, 0x00, 0xA0, 0x60, 0x17, 0x00, -+0x68, 0x60, 0x17, 0x00, 0xA1, 0x60, 0x17, 0x00, 0xFF, 0xA2, 0xE1, 0x11, 0x6C, 0x60, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x3C, 0x87, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x43, 0x7E, 0x07, 0x7E, 0x09, 0x2B, 0x05, 0x46, 0x09, 0xD8, 0x49, 0x4A, -+0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, 0x25, 0x30, 0x00, 0x2B, 0x00, 0xF0, 0x81, 0x80, 0x6B, 0x8B, -+0xDF, 0xF8, 0x30, 0x81, 0x1A, 0x07, 0x5A, 0xD4, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x07, 0x83, 0x93, 0xF8, 0x64, 0x30, -+0x00, 0x2B, 0x73, 0xD0, 0x3E, 0x4B, 0xAE, 0x7D, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x63, 0xDB, 0x3C, 0x48, -+0x18, 0xF0, 0x0C, 0xFC, 0x04, 0x46, 0x00, 0x28, 0x4C, 0xD0, 0x3A, 0x48, 0xE1, 0x8B, 0x83, 0x5D, 0xE2, 0x6C, 0x4F, 0xF0, -+0x00, 0x09, 0x01, 0x33, 0x21, 0xF0, 0x01, 0x01, 0x83, 0x55, 0xE1, 0x83, 0xC4, 0xF8, 0x44, 0x90, 0x29, 0x46, 0xC2, 0xF8, -+0x10, 0x90, 0x20, 0x1D, 0x1C, 0x22, 0xC4, 0xF8, 0x2C, 0x90, 0x2C, 0xF0, 0xA9, 0xFA, 0x30, 0x4B, 0xE1, 0x8B, 0x1B, 0x68, -+0x84, 0xF8, 0x42, 0x90, 0xEB, 0x1A, 0x04, 0x3B, 0x21, 0xF4, 0x00, 0x42, 0x22, 0xF0, 0x02, 0x02, 0xA3, 0x64, 0x0B, 0x07, -+0xC4, 0xF8, 0x24, 0x90, 0xC4, 0xF8, 0x50, 0x90, 0xE2, 0x83, 0x29, 0xD4, 0x63, 0x7F, 0x09, 0x2B, 0x0E, 0xD8, 0xE2, 0x7E, -+0x08, 0x2A, 0x0B, 0xD8, 0x03, 0xEB, 0xC3, 0x03, 0x13, 0x44, 0x23, 0x49, 0xA0, 0x88, 0x03, 0xF6, 0x0E, 0x03, 0x51, 0xF8, -+0x23, 0x20, 0x02, 0x44, 0x41, 0xF8, 0x23, 0x20, 0xA4, 0x20, 0x00, 0xFB, 0x07, 0x60, 0x99, 0x30, 0x21, 0x46, 0x08, 0xEB, -+0xC0, 0x00, 0xBD, 0xE8, 0xF8, 0x43, 0x18, 0xF0, 0x7F, 0xBB, 0x16, 0x48, 0x18, 0xF0, 0xC0, 0xFB, 0x05, 0x26, 0x04, 0x46, -+0x00, 0x28, 0xB2, 0xD1, 0x13, 0x4B, 0x16, 0x48, 0x99, 0x5D, 0xFB, 0xF7, 0x83, 0xFB, 0xFE, 0xE7, 0x4F, 0xF4, 0xA4, 0x60, -+0x00, 0xFB, 0x07, 0x80, 0x21, 0x46, 0x00, 0xF5, 0xA3, 0x60, 0xBD, 0xE8, 0xF8, 0x43, 0x18, 0xF0, 0x67, 0xBB, 0x05, 0x2E, -+0x99, 0xD9, 0x0E, 0x49, 0x0E, 0x48, 0x40, 0xF2, 0x5F, 0x32, 0x19, 0xF0, 0xB3, 0xFF, 0x92, 0xE7, 0x07, 0x4B, 0x18, 0x68, -+0x28, 0x1A, 0x04, 0x38, 0xBD, 0xE8, 0xF8, 0x43, 0xFC, 0xF7, 0x58, 0xBC, 0x68, 0x65, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x20, 0x58, 0x17, 0x00, 0x74, 0x28, 0x17, 0x00, 0x80, 0x1A, 0x17, 0x00, 0x7C, 0x36, 0x17, 0x00, 0x60, 0x87, 0x15, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x88, 0x82, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0xDF, 0xF8, 0x48, 0x81, -+0xDF, 0xF8, 0x48, 0x91, 0xDF, 0xF8, 0x48, 0xA1, 0x59, 0xE0, 0x47, 0x48, 0x18, 0xF0, 0x7A, 0xFB, 0x04, 0x46, 0xDF, 0xF8, -+0x40, 0xE1, 0x1C, 0x22, 0x29, 0x46, 0x04, 0x30, 0x00, 0x2C, 0x63, 0xD0, 0xB4, 0xF8, 0x1E, 0xB0, 0x1E, 0xF8, 0x07, 0xC0, -+0xE3, 0x6C, 0x66, 0x64, 0x2B, 0xF0, 0x01, 0x0B, 0x0C, 0xF1, 0x01, 0x0C, 0xA4, 0xF8, 0x1E, 0xB0, 0x1E, 0x61, 0xE6, 0x62, -+0x0E, 0xF8, 0x07, 0xC0, 0x2C, 0xF0, 0x16, 0xFA, 0x95, 0xF8, 0x20, 0x20, 0xE3, 0x8B, 0x38, 0x48, 0x12, 0xF0, 0x01, 0x0F, -+0x14, 0xBF, 0x4F, 0xF4, 0x00, 0x52, 0x4F, 0xF4, 0x08, 0x52, 0x2A, 0x61, 0x84, 0xF8, 0x42, 0x60, 0xC5, 0xE9, 0x05, 0x66, -+0x62, 0x7F, 0x10, 0x32, 0x92, 0x02, 0x45, 0xF8, 0x18, 0x2C, 0x21, 0x7F, 0x26, 0x65, 0xA4, 0x22, 0x99, 0x37, 0x23, 0xF4, -+0x00, 0x43, 0x12, 0xFB, 0x01, 0x77, 0x23, 0xF0, 0x02, 0x03, 0x4C, 0x3D, 0xA5, 0x64, 0x00, 0xEB, 0xC7, 0x00, 0xE3, 0x83, -+0x21, 0x46, 0x18, 0xF0, 0xF5, 0xFA, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x24, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x24, 0x4C, 0x24, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x18, 0xF0, 0x2A, 0xFB, 0x98, 0xF8, 0x11, 0x35, -+0x22, 0x68, 0x01, 0x3B, 0x88, 0xF8, 0x11, 0x35, 0x3A, 0xBB, 0xD8, 0xF8, 0x14, 0x35, 0x00, 0x26, 0xDB, 0xB1, 0xD9, 0xF8, -+0x00, 0x20, 0x5D, 0x68, 0xB2, 0xF9, 0x00, 0x30, 0xAF, 0x7D, 0x00, 0x2B, 0x99, 0xDA, 0x05, 0x2F, 0x97, 0xD9, 0x18, 0x49, -+0x4F, 0xF4, 0x66, 0x72, 0x50, 0x46, 0x19, 0xF0, 0x1F, 0xFF, 0x90, 0xE7, 0x15, 0x48, 0x1E, 0xF8, 0x07, 0x10, 0xFB, 0xF7, -+0xD5, 0xFA, 0x14, 0x4B, 0x18, 0x68, 0x28, 0x1A, 0x04, 0x38, 0xFC, 0xF7, 0xC1, 0xFB, 0x20, 0x20, 0x18, 0xF0, 0x3E, 0xFA, -+0xBD, 0xE8, 0xF8, 0x4F, 0x40, 0x20, 0x18, 0xF0, 0x15, 0xBA, 0x08, 0x4B, 0x01, 0x3A, 0x1B, 0x68, 0x22, 0x60, 0x00, 0x2A, -+0x7F, 0xF4, 0x74, 0xAF, 0x00, 0x2B, 0x3F, 0xF4, 0x71, 0xAF, 0x62, 0xB6, 0x6E, 0xE7, 0x00, 0xBF, 0x20, 0x58, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x6C, 0x5D, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x60, 0x87, 0x15, 0x00, 0x80, 0x1A, 0x17, 0x00, 0x58, 0x58, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x88, 0x82, 0x15, 0x00, -+0x74, 0x28, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0xDF, 0xF8, 0xB8, 0x90, 0x29, 0x4D, 0x2A, 0x4F, 0xDF, 0xF8, 0xAC, 0x80, -+0x29, 0x4E, 0x20, 0xE0, 0x5C, 0x68, 0x20, 0x46, 0xFA, 0xF7, 0x1E, 0xFB, 0x38, 0x68, 0x20, 0x1A, 0x04, 0x38, 0xFC, 0xF7, -+0x81, 0xFB, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x01, 0x23, 0xC8, 0xF8, 0x00, 0x30, 0xD9, 0xF8, -+0x00, 0x30, 0x30, 0x46, 0x01, 0x33, 0xC9, 0xF8, 0x00, 0x30, 0x18, 0xF0, 0xB3, 0xFA, 0x95, 0xF8, 0x9D, 0x37, 0xD9, 0xF8, -+0x00, 0x20, 0x01, 0x3B, 0x85, 0xF8, 0x9D, 0x37, 0x0A, 0xBB, 0xD5, 0xF8, 0xA0, 0x37, 0x00, 0x2B, 0xDA, 0xD1, 0xEF, 0xF3, -+0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x14, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xD9, 0xF8, 0x00, 0x30, 0x4F, 0xF4, -+0x00, 0x00, 0x01, 0x33, 0xC9, 0xF8, 0x00, 0x30, 0x18, 0xF0, 0xD4, 0xF9, 0xD9, 0xF8, 0x00, 0x30, 0x3B, 0xB1, 0x0D, 0x4A, -+0x01, 0x3B, 0x12, 0x68, 0xC9, 0xF8, 0x00, 0x30, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xBD, 0xE8, 0xF8, 0x83, 0x01, 0x3A, -+0xD8, 0xF8, 0x00, 0x30, 0xC9, 0xF8, 0x00, 0x20, 0x00, 0x2A, 0xB3, 0xD1, 0x00, 0x2B, 0xB1, 0xD0, 0x62, 0xB6, 0xAF, 0xE7, -+0x58, 0x58, 0x17, 0x00, 0x80, 0x1A, 0x17, 0x00, 0xF8, 0x5F, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x0E, 0x4B, 0x10, 0xB5, 0xD3, 0xF8, 0x90, 0x32, 0x98, 0x47, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x0A, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0A, 0x4C, 0x23, 0x68, 0x10, 0x20, 0x01, 0x33, 0x23, 0x60, 0x18, 0xF0, 0x9E, 0xF9, -+0x23, 0x68, 0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x10, 0xBD, -+0x88, 0x1A, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xF8, 0xB5, 0x16, 0x4C, 0x16, 0x4E, 0x17, 0x4F, -+0x14, 0x4D, 0x15, 0xE0, 0x58, 0x68, 0xFC, 0xF7, 0x05, 0xFB, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x02, 0xD4, 0x72, 0xB6, -+0x01, 0x23, 0x33, 0x60, 0x3B, 0x68, 0x28, 0x46, 0x01, 0x33, 0x3B, 0x60, 0x18, 0xF0, 0x3A, 0xFA, 0x0E, 0x4A, 0x39, 0x68, -+0x13, 0x78, 0x01, 0x3B, 0x13, 0x70, 0x39, 0xB9, 0x23, 0x68, 0x00, 0x2B, 0xE6, 0xD1, 0xBD, 0xE8, 0xF8, 0x40, 0x08, 0x20, -+0x18, 0xF0, 0x6A, 0xB9, 0x01, 0x39, 0x33, 0x68, 0x39, 0x60, 0x00, 0x29, 0xDA, 0xD1, 0x00, 0x2B, 0xD8, 0xD0, 0x62, 0xB6, -+0xD6, 0xE7, 0x00, 0xBF, 0x94, 0x4E, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x8E, 0x4E, 0x17, 0x00, -+0x59, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0x67, 0xD1, 0x2D, 0xE9, 0xF0, 0x47, 0x57, 0x4D, 0x2B, 0x78, 0x00, 0x2B, 0x47, 0xD1, -+0x56, 0x4B, 0x1A, 0x78, 0x00, 0x2A, 0x5B, 0xD1, 0x55, 0x49, 0x56, 0x4A, 0x09, 0x78, 0x12, 0x88, 0x91, 0x42, 0x5E, 0xD2, -+0x54, 0x4B, 0xD3, 0xE9, 0x01, 0x02, 0x13, 0x69, 0x98, 0x47, 0x04, 0x46, 0x00, 0x28, 0x78, 0xD0, 0x2B, 0x78, 0x00, 0x2B, -+0x4D, 0xD0, 0x4C, 0x4B, 0xDF, 0xF8, 0x60, 0xA1, 0x1B, 0x78, 0x4E, 0x4F, 0xDA, 0xF8, 0x00, 0x00, 0x00, 0x2B, 0x7B, 0xD1, -+0x4C, 0x4B, 0x39, 0x68, 0xD3, 0xF8, 0x40, 0x34, 0x20, 0x44, 0x98, 0x47, 0x00, 0x28, 0x39, 0xD0, 0x01, 0x46, 0x49, 0x48, -+0xDF, 0xF8, 0x08, 0x91, 0xDF, 0xF8, 0x18, 0x81, 0xFB, 0xF7, 0xAE, 0xF9, 0x05, 0x26, 0x2B, 0x78, 0x00, 0x2B, 0x48, 0xD1, -+0xDA, 0xF8, 0x00, 0x00, 0xD8, 0xF8, 0x40, 0x34, 0x39, 0x68, 0x20, 0x44, 0x98, 0x47, 0x28, 0xB3, 0x01, 0x3E, 0xF2, 0xD1, -+0x05, 0x21, 0x3F, 0x48, 0xFB, 0xF7, 0x9C, 0xF9, 0x20, 0x46, 0xFC, 0xF7, 0x8B, 0xFA, 0xBD, 0xE8, 0xF0, 0x47, 0x04, 0x20, -+0x18, 0xF0, 0xE2, 0xB8, 0x34, 0x4B, 0x1B, 0x88, 0x00, 0x2B, 0x46, 0xD0, 0x31, 0x4A, 0x12, 0x78, 0x9A, 0x42, 0xB9, 0xD3, -+0x36, 0x4A, 0x2E, 0x4B, 0x12, 0x68, 0x01, 0x21, 0x19, 0x70, 0x00, 0x2A, 0x47, 0xD1, 0x34, 0x4B, 0x34, 0x49, 0x1A, 0x88, -+0x4F, 0xF4, 0x00, 0x70, 0x92, 0xB2, 0x19, 0xF0, 0x97, 0xFB, 0xA9, 0xE7, 0xBD, 0xE8, 0xF0, 0x87, 0x70, 0x47, 0xDF, 0xF8, -+0xC8, 0xA0, 0x28, 0x4F, 0xDA, 0xF8, 0x00, 0x00, 0xB4, 0xE7, 0x1A, 0x78, 0x00, 0x2A, 0x9D, 0xD1, 0x28, 0x4A, 0x12, 0x68, -+0x01, 0x21, 0x19, 0x70, 0x92, 0xBB, 0x27, 0x4B, 0x27, 0x49, 0x1A, 0x88, 0xBD, 0xE8, 0xF0, 0x47, 0x4F, 0xF4, 0x00, 0x70, -+0x92, 0xB2, 0x19, 0xF0, 0x7B, 0xBB, 0x99, 0xF8, 0x00, 0x30, 0xDA, 0xF8, 0x00, 0x00, 0x2B, 0xB9, 0xD8, 0xF8, 0x40, 0x34, -+0x39, 0x68, 0x20, 0x44, 0x98, 0x47, 0xB2, 0xE7, 0x39, 0x68, 0x20, 0x44, 0xFF, 0xF7, 0x72, 0xFA, 0xAD, 0xE7, 0x04, 0x20, -+0x18, 0xF0, 0x9C, 0xF8, 0xBD, 0xE8, 0xF0, 0x47, 0x19, 0x48, 0xFB, 0xF7, 0x49, 0xB9, 0xBD, 0xE8, 0xF0, 0x47, 0x18, 0x49, -+0x4F, 0xF4, 0x00, 0x70, 0x19, 0xF0, 0x5C, 0xBB, 0x39, 0x68, 0x20, 0x44, 0xFF, 0xF7, 0x5E, 0xFA, 0x84, 0xE7, 0x40, 0xF2, -+0x1F, 0x40, 0x17, 0xF0, 0xF9, 0xFA, 0xB2, 0xE7, 0x40, 0xF2, 0x1F, 0x40, 0x17, 0xF0, 0xF4, 0xFA, 0xC7, 0xE7, 0x00, 0xBF, -+0x58, 0x28, 0x17, 0x00, 0x68, 0x60, 0x17, 0x00, 0x64, 0x28, 0x17, 0x00, 0x7C, 0x60, 0x17, 0x00, 0x66, 0x28, 0x17, 0x00, -+0xA4, 0x60, 0x17, 0x00, 0x78, 0x60, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x8C, 0x87, 0x15, 0x00, 0xAC, 0x87, 0x15, 0x00, -+0x6C, 0x60, 0x17, 0x00, 0x56, 0x28, 0x17, 0x00, 0x7C, 0x87, 0x15, 0x00, 0x98, 0x87, 0x15, 0x00, 0x84, 0x87, 0x15, 0x00, -+0x80, 0x1A, 0x17, 0x00, 0x08, 0xB5, 0x0F, 0x48, 0x19, 0xF0, 0xD8, 0xFA, 0x0E, 0x4B, 0xD3, 0xE9, 0x01, 0x02, 0x13, 0x69, -+0x98, 0x47, 0x80, 0xB1, 0x0C, 0x4B, 0x0D, 0x49, 0x1A, 0x68, 0x0D, 0x4B, 0x09, 0x68, 0xD3, 0xF8, 0x40, 0x34, 0x10, 0x44, -+0x98, 0x47, 0x01, 0x1E, 0x00, 0xDB, 0x08, 0xBD, 0xBD, 0xE8, 0x08, 0x40, 0x08, 0x48, 0xFB, 0xF7, 0xF7, 0xB8, 0xBD, 0xE8, -+0x08, 0x40, 0x07, 0x48, 0xFB, 0xF7, 0xF2, 0xB8, 0xC0, 0x87, 0x15, 0x00, 0xA4, 0x60, 0x17, 0x00, 0x80, 0x1A, 0x17, 0x00, -+0x78, 0x60, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xCC, 0x87, 0x15, 0x00, 0xE4, 0x87, 0x15, 0x00, 0x10, 0xB5, 0x04, 0x20, -+0x18, 0xF0, 0x52, 0xF8, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0A, 0x4B, 0x01, 0x22, 0x1A, 0x60, -+0x09, 0x4C, 0x0A, 0x4A, 0x23, 0x68, 0xD2, 0xF8, 0x3C, 0x24, 0x01, 0x33, 0x23, 0x60, 0x90, 0x47, 0x23, 0x68, 0x33, 0xB1, -+0x03, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x10, 0xBD, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xF8, 0xB5, 0x11, 0x4D, 0x11, 0x4F, 0x28, 0x68, 0x00, 0xF5, 0x0D, 0x70, -+0x18, 0xF0, 0xA4, 0xF8, 0x28, 0x68, 0x00, 0xF5, 0x0F, 0x70, 0x18, 0xF0, 0x9F, 0xF8, 0x3B, 0x68, 0x1B, 0x89, 0x93, 0xB1, -+0x0B, 0x4E, 0x00, 0x24, 0x4F, 0xF4, 0xD7, 0x61, 0x30, 0x46, 0xFB, 0xF7, 0x2B, 0xFF, 0x01, 0x46, 0x28, 0x68, 0x00, 0xF5, -+0x0D, 0x70, 0x18, 0xF0, 0x93, 0xF8, 0x3B, 0x68, 0x01, 0x34, 0x1A, 0x89, 0xA3, 0xB2, 0x9A, 0x42, 0xEE, 0xD8, 0xF8, 0xBD, -+0x00, 0x38, 0x18, 0x00, 0x78, 0x36, 0x17, 0x00, 0xE4, 0x25, 0x17, 0x00, 0x00, 0x20, 0x70, 0x47, 0x10, 0xB5, 0x12, 0x4A, -+0x01, 0x46, 0x13, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0E, 0x4B, -+0x01, 0x22, 0x1A, 0x60, 0x0D, 0x4C, 0x0E, 0x4A, 0x23, 0x68, 0x10, 0x68, 0x01, 0x33, 0x00, 0xF5, 0x0D, 0x70, 0x23, 0x60, -+0x18, 0xF0, 0x6C, 0xF8, 0x23, 0x68, 0x33, 0xB1, 0x06, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0x02, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x10, 0xBD, 0x00, 0xBF, 0x4C, 0x40, 0x04, 0x40, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x00, 0x38, 0x18, 0x00, 0x08, 0xB5, 0x03, 0x49, 0x4F, 0xF4, 0x80, 0x70, 0x19, 0xF0, 0x7A, 0xFA, -+0x01, 0x20, 0x08, 0xBD, 0x08, 0x88, 0x15, 0x00, 0x05, 0x4A, 0x06, 0x49, 0x00, 0x23, 0xC2, 0xE9, 0x02, 0x03, 0xC2, 0xE9, -+0x04, 0x33, 0xC2, 0xE9, 0x00, 0x33, 0x8B, 0x81, 0x01, 0x20, 0x70, 0x47, 0xBC, 0x60, 0x17, 0x00, 0xD4, 0x60, 0x17, 0x00, -+0x2D, 0xE9, 0xF8, 0x4F, 0xDF, 0xF8, 0x0C, 0x92, 0xDF, 0xF8, 0x0C, 0x82, 0xD9, 0xF8, 0x14, 0x35, 0x00, 0x2B, 0x00, 0xF0, -+0x8F, 0x80, 0xDF, 0xF8, 0xE8, 0xA1, 0xDF, 0xF8, 0x00, 0xB2, 0x78, 0xE0, 0x71, 0x49, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, -+0x06, 0x12, 0x92, 0xF8, 0x64, 0x20, 0x00, 0x2A, 0x00, 0xF0, 0xB2, 0x80, 0x6D, 0x4A, 0x1F, 0x7A, 0x13, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xA1, 0x80, 0x6A, 0x48, 0x18, 0xF0, 0x5B, 0xF8, 0x04, 0x46, 0x00, 0x28, 0x6C, 0xD0, -+0xC2, 0x8B, 0xC1, 0x6C, 0x1A, 0xF8, 0x07, 0xC0, 0x00, 0x23, 0x22, 0xF0, 0x01, 0x02, 0xC2, 0x83, 0x43, 0x64, 0x0C, 0xF1, -+0x01, 0x0C, 0x0B, 0x61, 0x1C, 0x22, 0xC3, 0x62, 0x29, 0x46, 0x04, 0x30, 0x0A, 0xF8, 0x07, 0xC0, 0x2B, 0xF0, 0xFA, 0xFE, -+0xE2, 0x8B, 0xDB, 0xF8, 0x00, 0x10, 0x6D, 0x1A, 0xC2, 0xF3, 0x0E, 0x01, 0x00, 0x23, 0xE1, 0x83, 0x11, 0x07, 0x84, 0xF8, -+0x42, 0x30, 0x23, 0x65, 0xA5, 0x64, 0x6F, 0xD4, 0x63, 0x7F, 0x09, 0x2B, 0x0E, 0xD8, 0xE2, 0x7E, 0x08, 0x2A, 0x0B, 0xD8, -+0x03, 0xEB, 0xC3, 0x03, 0x13, 0x44, 0x53, 0x49, 0xA0, 0x88, 0x03, 0xF6, 0x0E, 0x03, 0x51, 0xF8, 0x23, 0x20, 0x02, 0x44, -+0x41, 0xF8, 0x23, 0x20, 0xA4, 0x20, 0x00, 0xFB, 0x06, 0x76, 0x4A, 0x48, 0x99, 0x36, 0x21, 0x46, 0x00, 0xEB, 0xC6, 0x00, -+0x17, 0xF0, 0xD6, 0xFF, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x48, 0x4B, 0x01, 0x22, 0x1A, 0x60, -+0xD8, 0xF8, 0x00, 0x30, 0x46, 0x48, 0x01, 0x33, 0xC8, 0xF8, 0x00, 0x30, 0x18, 0xF0, 0x0A, 0xF8, 0x99, 0xF8, 0x11, 0x35, -+0xD8, 0xF8, 0x00, 0x20, 0x01, 0x3B, 0x89, 0xF8, 0x11, 0x35, 0x3A, 0xB1, 0x3E, 0x4B, 0x01, 0x3A, 0x1B, 0x68, 0xC8, 0xF8, -+0x00, 0x20, 0x0A, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0xD9, 0xF8, 0x14, 0x35, 0x83, 0xB1, 0x5D, 0x68, 0x6A, 0x8B, 0x2E, 0x7E, -+0x14, 0x07, 0x81, 0xD5, 0x34, 0x48, 0x17, 0xF0, 0xEF, 0xFF, 0x05, 0x27, 0x04, 0x46, 0x00, 0x28, 0x92, 0xD1, 0x35, 0x4B, -+0x35, 0x48, 0xD9, 0x5D, 0xFA, 0xF7, 0xB2, 0xFF, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x2E, 0x4B, -+0x01, 0x22, 0x1A, 0x60, 0xD8, 0xF8, 0x00, 0x30, 0x20, 0x20, 0x01, 0x33, 0xC8, 0xF8, 0x00, 0x30, 0x17, 0xF0, 0x14, 0xFF, -+0x40, 0x20, 0x17, 0xF0, 0xED, 0xFE, 0xD8, 0xF8, 0x00, 0x30, 0x3B, 0xB1, 0x25, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xC8, 0xF8, -+0x00, 0x30, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xBD, 0xE8, 0xF8, 0x8F, 0x24, 0x4B, 0x4F, 0xF4, 0xA4, 0x60, 0x21, 0x46, -+0x00, 0xFB, 0x06, 0x30, 0x17, 0xF0, 0x7A, 0xFF, 0xA2, 0xE7, 0x05, 0x2F, 0x7F, 0xF6, 0x5C, 0xAF, 0x1F, 0x49, 0x20, 0x48, -+0xB8, 0x22, 0x19, 0xF0, 0xC5, 0xFB, 0x55, 0xE7, 0xDB, 0xF8, 0x00, 0x00, 0x28, 0x1A, 0xFC, 0xF7, 0x6D, 0xF8, 0xEF, 0xF3, -+0x10, 0x83, 0xD8, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x12, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xD8, 0xF8, 0x00, 0x30, 0x11, 0x48, -+0x01, 0x33, 0xC8, 0xF8, 0x00, 0x30, 0x17, 0xF0, 0x9F, 0xFF, 0x99, 0xF8, 0x11, 0x25, 0xD8, 0xF8, 0x00, 0x30, 0x01, 0x3A, -+0x89, 0xF8, 0x11, 0x25, 0x00, 0x2B, 0x9B, 0xD0, 0x08, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xC8, 0xF8, 0x00, 0x30, 0x00, 0x2B, -+0x94, 0xD1, 0x00, 0x2A, 0x92, 0xD0, 0x90, 0xE7, 0x18, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x20, 0x58, 0x17, 0x00, -+0x7C, 0x36, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x5D, 0x17, 0x00, 0x74, 0x28, 0x17, 0x00, 0x1C, 0x88, 0x15, 0x00, -+0x30, 0x8D, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x88, 0x82, 0x15, 0x00, 0x58, 0x58, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x84, 0x1A, 0x17, 0x00, 0x70, 0x47, 0x00, 0xBF, 0x70, 0x47, 0x00, 0xBF, 0x70, 0x47, 0x00, 0xBF, 0x04, 0x20, 0x17, 0xF0, -+0xA5, 0xBE, 0x00, 0xBF, 0x2D, 0xE9, 0xF8, 0x43, 0xD0, 0xF8, 0xA8, 0x44, 0xD1, 0xF8, 0xB0, 0x50, 0x07, 0x46, 0x0E, 0x46, -+0x00, 0x2C, 0x00, 0xF0, 0x8F, 0x80, 0xA2, 0x49, 0xA2, 0x4A, 0x4F, 0xF0, 0xFF, 0x33, 0x0B, 0x60, 0x13, 0x60, 0x94, 0xF8, -+0x60, 0x80, 0xB8, 0xF1, 0x04, 0x0F, 0x00, 0xF2, 0xB9, 0x81, 0xDF, 0xE8, 0x18, 0xF0, 0x49, 0x00, 0xF3, 0x00, 0x45, 0x01, -+0x03, 0x01, 0x05, 0x00, 0x9A, 0x4B, 0x62, 0x6E, 0x1A, 0x60, 0xA2, 0x6E, 0x5A, 0x60, 0xE2, 0x6E, 0x9A, 0x60, 0x22, 0x6F, -+0xDA, 0x60, 0x22, 0x6D, 0xDA, 0x61, 0x62, 0x6D, 0x1A, 0x62, 0xA2, 0x6D, 0x5A, 0x62, 0x94, 0x4B, 0x94, 0x4A, 0xE1, 0x6D, -+0x1B, 0x68, 0x11, 0x60, 0x1B, 0x78, 0x13, 0xF0, 0x02, 0x0F, 0xC1, 0x46, 0x4F, 0xF4, 0x80, 0x63, 0x4F, 0xF4, 0x80, 0x51, -+0x4F, 0xF0, 0x01, 0x08, 0x48, 0xD0, 0x97, 0xF8, 0x63, 0xC0, 0x94, 0xF8, 0x62, 0x00, 0x8C, 0x4A, 0x43, 0xEA, 0x0C, 0x13, -+0x43, 0xEA, 0x00, 0x43, 0x0B, 0x43, 0x43, 0xF0, 0x80, 0x43, 0x13, 0x60, 0x13, 0x68, 0x5C, 0x00, 0xFC, 0xD4, 0x00, 0x2D, -+0x48, 0xD0, 0x81, 0x4B, 0x7F, 0x49, 0xD6, 0xF8, 0x26, 0x00, 0x72, 0x8D, 0x08, 0x60, 0x1A, 0x60, 0x95, 0xF8, 0x60, 0x30, -+0x04, 0x2B, 0x00, 0xF2, 0x68, 0x81, 0xDF, 0xE8, 0x13, 0xF0, 0x78, 0x00, 0x41, 0x00, 0xD4, 0x00, 0xCF, 0x00, 0xC5, 0x00, -+0x00, 0x21, 0x4F, 0xF0, 0x01, 0x09, 0x77, 0x4B, 0x62, 0x6E, 0x1A, 0x60, 0xA2, 0x6E, 0x5A, 0x60, 0xE2, 0x6E, 0x9A, 0x60, -+0x22, 0x6F, 0xDA, 0x60, 0x73, 0x4B, 0x1B, 0x68, 0xB9, 0xF1, 0x02, 0x0F, 0x1B, 0x78, 0x40, 0xF0, 0xF2, 0x80, 0xD8, 0x07, -+0x40, 0xF1, 0x20, 0x81, 0x71, 0x48, 0x22, 0x6D, 0x02, 0x60, 0x62, 0x6D, 0x42, 0x60, 0xA2, 0x6D, 0x82, 0x60, 0xE2, 0x6D, -+0xC2, 0x60, 0x9B, 0x07, 0x00, 0xF1, 0xFF, 0x80, 0x4F, 0xF4, 0x00, 0x73, 0x97, 0xF8, 0x63, 0xC0, 0x94, 0xF8, 0x62, 0x00, -+0x67, 0x4A, 0x43, 0xEA, 0x0C, 0x13, 0x43, 0xEA, 0x00, 0x43, 0x0B, 0x43, 0x43, 0xF0, 0x80, 0x43, 0x13, 0x60, 0x13, 0x68, -+0x58, 0x00, 0xFC, 0xD4, 0x00, 0x2D, 0xB6, 0xD1, 0xBD, 0xE8, 0xF8, 0x83, 0xA1, 0x46, 0x4F, 0xF0, 0x01, 0x08, 0xAE, 0xE7, -+0x4F, 0xF0, 0x02, 0x09, 0x59, 0x4B, 0x6A, 0x6E, 0x1A, 0x60, 0xAA, 0x6E, 0x5A, 0x60, 0xEA, 0x6E, 0x9A, 0x60, 0x2A, 0x6F, -+0xDA, 0x60, 0xB9, 0xF1, 0x04, 0x0F, 0x40, 0xF0, 0x96, 0x80, 0x57, 0x4B, 0x2A, 0x6D, 0x1A, 0x60, 0x6A, 0x6D, 0x5A, 0x60, -+0xAA, 0x6D, 0x9A, 0x60, 0x50, 0x4B, 0x51, 0x4A, 0xE9, 0x6D, 0x1B, 0x68, 0x11, 0x60, 0x1B, 0x78, 0x99, 0x07, 0x40, 0xF1, -+0xD6, 0x80, 0x4F, 0xEA, 0x08, 0x38, 0x4F, 0xF4, 0x80, 0x69, 0x97, 0xF8, 0x63, 0x30, 0x95, 0xF8, 0x62, 0x10, 0x4A, 0x4A, -+0x1B, 0x01, 0x43, 0xEA, 0x01, 0x43, 0x43, 0xEA, 0x08, 0x03, 0x43, 0xEA, 0x09, 0x03, 0x43, 0xF0, 0x80, 0x43, 0x13, 0x60, -+0x13, 0x68, 0x58, 0x00, 0xFC, 0xD4, 0xBD, 0xE8, 0xF8, 0x83, 0x4F, 0xF0, 0x00, 0x08, 0x4F, 0xF0, 0x01, 0x09, 0x3D, 0x4B, -+0x6A, 0x6E, 0x1A, 0x60, 0xAA, 0x6E, 0x5A, 0x60, 0xEA, 0x6E, 0x9A, 0x60, 0x2A, 0x6F, 0xDA, 0x60, 0xB9, 0xF1, 0x02, 0x0F, -+0x62, 0xD1, 0x38, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0xDA, 0x07, 0x40, 0xF1, 0xB3, 0x80, 0x38, 0x4A, 0x29, 0x6D, 0x11, 0x60, -+0x69, 0x6D, 0x51, 0x60, 0xA9, 0x6D, 0x91, 0x60, 0xE9, 0x6D, 0xD1, 0x60, 0x9A, 0x07, 0x7A, 0xD4, 0x4F, 0xF4, 0x00, 0x79, -+0x97, 0xF8, 0x63, 0x30, 0x95, 0xF8, 0x62, 0x10, 0x2E, 0x4A, 0x1B, 0x01, 0x43, 0xEA, 0x01, 0x43, 0x43, 0xEA, 0x08, 0x03, -+0x43, 0xEA, 0x09, 0x03, 0x43, 0xF0, 0x80, 0x43, 0x13, 0x60, 0x13, 0x68, 0x59, 0x00, 0xFC, 0xD4, 0xBD, 0xE8, 0xF8, 0x83, -+0x4F, 0xF0, 0x02, 0x09, 0x22, 0x4B, 0x62, 0x6E, 0x1A, 0x60, 0xA2, 0x6E, 0x5A, 0x60, 0xE2, 0x6E, 0x9A, 0x60, 0x22, 0x6F, -+0xDA, 0x60, 0x4F, 0xF4, 0x80, 0x51, 0x4F, 0xF0, 0x01, 0x08, 0x51, 0xE7, 0x4F, 0xF0, 0x01, 0x09, 0xC8, 0x46, 0x4F, 0xF4, -+0x80, 0x51, 0x42, 0xE7, 0x18, 0x4B, 0x6A, 0x6E, 0x1A, 0x60, 0xAA, 0x6E, 0x5A, 0x60, 0xEA, 0x6E, 0x9A, 0x60, 0x2A, 0x6F, -+0xDA, 0x60, 0x80, 0xE7, 0x4F, 0xEA, 0x08, 0x38, 0x4F, 0xF0, 0x01, 0x09, 0xA7, 0xE7, 0x95, 0xF8, 0x74, 0x30, 0x10, 0x2B, -+0x00, 0xF0, 0x83, 0x80, 0x20, 0x2B, 0x7B, 0xD0, 0x0D, 0x4B, 0x6A, 0x6E, 0x1A, 0x60, 0xAA, 0x6E, 0x5A, 0x60, 0xEA, 0x6E, -+0x9A, 0x60, 0x2A, 0x6F, 0xDA, 0x60, 0x4F, 0xF0, 0x03, 0x09, 0xB9, 0xF1, 0x02, 0x0F, 0x4F, 0xEA, 0x08, 0x38, 0x9C, 0xD0, -+0x06, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x9E, 0x07, 0x56, 0xD4, 0x4F, 0xEA, 0x09, 0x29, 0xA7, 0xE7, 0xBC, 0x00, 0x32, 0x40, -+0xC0, 0x00, 0x32, 0x40, 0xAC, 0x00, 0x32, 0x40, 0x34, 0x36, 0x17, 0x00, 0xD4, 0x00, 0x32, 0x40, 0xC4, 0x00, 0x32, 0x40, -+0xC8, 0x00, 0x32, 0x40, 0x94, 0xF8, 0x74, 0x30, 0x10, 0x2B, 0x5B, 0xD0, 0x20, 0x2B, 0x4A, 0xD0, 0x4F, 0xF0, 0x03, 0x09, -+0xA6, 0xE7, 0x9A, 0x07, 0x42, 0xD5, 0x09, 0xF1, 0xFF, 0x33, 0xDB, 0xB2, 0x01, 0x2B, 0x14, 0xD9, 0x4F, 0xEA, 0x09, 0x23, -+0xCB, 0xE6, 0x97, 0xF8, 0x63, 0x30, 0x95, 0xF8, 0x62, 0x10, 0x3A, 0x4A, 0x1B, 0x01, 0x43, 0xEA, 0x01, 0x43, 0x43, 0xEA, -+0x08, 0x03, 0x43, 0xF0, 0x80, 0x43, 0x13, 0x60, 0x13, 0x68, 0x5C, 0x00, 0xFC, 0xD4, 0xBD, 0xE8, 0xF8, 0x83, 0x97, 0xF8, -+0x63, 0x30, 0x94, 0xF8, 0x62, 0x00, 0x31, 0x4A, 0x41, 0xEA, 0x03, 0x13, 0x43, 0xEA, 0x00, 0x43, 0x43, 0xF0, 0x80, 0x43, -+0x13, 0x60, 0x13, 0x68, 0x5B, 0x00, 0xFC, 0xD4, 0xB9, 0xE6, 0x4F, 0xEA, 0x08, 0x38, 0x4F, 0xF4, 0x80, 0x69, 0x5F, 0xE7, -+0x29, 0x48, 0x02, 0x68, 0x22, 0xF0, 0x01, 0x02, 0x02, 0x60, 0xE2, 0xE6, 0x26, 0x49, 0x0A, 0x68, 0x22, 0xF0, 0x01, 0x02, -+0x0A, 0x60, 0x4F, 0xE7, 0x09, 0xF1, 0xFF, 0x33, 0xDB, 0xB2, 0x01, 0x2B, 0xC7, 0xD9, 0x4F, 0xEA, 0x09, 0x29, 0x14, 0xE7, -+0x4F, 0xEA, 0x09, 0x23, 0xD6, 0xE6, 0x4F, 0xF4, 0x00, 0x51, 0x4F, 0xF0, 0x03, 0x09, 0xB0, 0xE6, 0x4F, 0xF4, 0x00, 0x58, -+0x4F, 0xF0, 0x03, 0x09, 0x1F, 0xE7, 0x4F, 0xF0, 0x00, 0x08, 0x4F, 0xF0, 0x03, 0x09, 0x1A, 0xE7, 0x00, 0x21, 0x88, 0x46, -+0x4F, 0xF0, 0x03, 0x09, 0xA1, 0xE6, 0x15, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xBF, 0xF6, 0xD6, 0xAE, -+0x12, 0x49, 0x13, 0x48, 0xA6, 0x22, 0x19, 0xF0, 0xA7, 0xF9, 0xCF, 0xE6, 0x0E, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x06, 0xDB, 0x4F, 0xF4, 0x80, 0x51, 0x4F, 0xF0, 0x00, 0x09, 0x4F, 0xF0, 0x01, 0x08, 0x87, 0xE6, 0x09, 0x49, -+0x09, 0x48, 0x4F, 0x22, 0x19, 0xF0, 0x94, 0xF9, 0x4F, 0xF0, 0x00, 0x09, 0x4F, 0xF4, 0x80, 0x51, 0x4F, 0xF0, 0x01, 0x08, -+0x7B, 0xE6, 0x00, 0xBF, 0xC4, 0x00, 0x32, 0x40, 0x64, 0x05, 0x32, 0x40, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x64, 0x7D, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0xA3, 0x4E, 0x0D, 0x46, 0xD6, 0xF8, 0xF0, 0x70, 0x04, 0x46, 0xF4, 0xF7, -+0xF7, 0xFE, 0xB8, 0x47, 0xA0, 0x4A, 0xA1, 0x49, 0x13, 0x68, 0x23, 0xF4, 0x00, 0x63, 0x13, 0x60, 0x0A, 0x68, 0x9F, 0x4B, -+0x42, 0xF4, 0x80, 0x32, 0x0A, 0x60, 0x1A, 0x68, 0x42, 0xF0, 0x7F, 0x42, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF4, 0x00, 0x02, -+0x1A, 0x60, 0x1A, 0x68, 0x22, 0xF4, 0xFE, 0x02, 0x42, 0xF4, 0x80, 0x12, 0x1A, 0x60, 0x97, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x4F, 0xF4, 0x40, 0x52, 0x00, 0x2B, 0xC1, 0xF8, 0x04, 0x21, 0xC0, 0xF2, 0xAD, 0x80, 0x92, 0x4B, 0x8E, 0x4A, -+0x92, 0x49, 0x19, 0x60, 0x13, 0x68, 0x92, 0x4F, 0x43, 0xF4, 0x00, 0x53, 0x13, 0x60, 0xF5, 0xF7, 0x49, 0xFD, 0xDF, 0xF8, -+0x9C, 0xC2, 0x8F, 0x49, 0xDC, 0xF8, 0x00, 0x20, 0x43, 0x1C, 0x9B, 0x06, 0x22, 0xF0, 0xE0, 0x52, 0x03, 0xF0, 0xE0, 0x53, -+0x13, 0x43, 0xCC, 0xF8, 0x00, 0x30, 0x0B, 0x68, 0x89, 0x4A, 0x23, 0xF0, 0x01, 0x03, 0x0B, 0x60, 0x13, 0x68, 0x43, 0xF0, -+0x02, 0x03, 0x13, 0x60, 0x3B, 0x68, 0x9A, 0x03, 0x00, 0xF1, 0xAF, 0x80, 0x84, 0x4A, 0x28, 0x8C, 0x13, 0x68, 0x80, 0x49, -+0x9B, 0xB2, 0x43, 0xEA, 0x00, 0x43, 0x13, 0x60, 0x0B, 0x68, 0x1F, 0x04, 0x00, 0xF1, 0x87, 0x80, 0x75, 0x4B, 0xDF, 0xF8, -+0x50, 0xE2, 0x1A, 0x68, 0xDF, 0xF8, 0x4C, 0xC2, 0x7C, 0x48, 0x7D, 0x4F, 0x7D, 0x49, 0x42, 0xF0, 0x01, 0x02, 0x1A, 0x60, -+0x4F, 0xF4, 0x40, 0x72, 0xCE, 0xF8, 0x00, 0x20, 0xE2, 0x6D, 0xCC, 0xF8, 0x00, 0x20, 0xB4, 0xF8, 0x60, 0x20, 0x02, 0x60, -+0xA2, 0x6B, 0xA0, 0x8F, 0x3A, 0x60, 0xD4, 0xF8, 0x90, 0x21, 0x08, 0x60, 0x91, 0x78, 0x74, 0x4A, 0x02, 0xEB, 0x81, 0x01, -+0x50, 0x68, 0x49, 0x69, 0xC7, 0xF8, 0xBC, 0x10, 0x19, 0x68, 0x21, 0xF4, 0xE0, 0x61, 0x19, 0x60, 0x13, 0x68, 0x6F, 0x49, -+0x6F, 0x4A, 0x03, 0x43, 0x3B, 0x64, 0x6F, 0x48, 0x6F, 0x4B, 0x08, 0x60, 0x13, 0x60, 0xD6, 0xF8, 0xB0, 0x31, 0x94, 0xF8, -+0x63, 0x10, 0x95, 0xF8, 0x23, 0x00, 0x98, 0x47, 0x29, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x70, 0xFD, 0x09, 0xF0, 0xAC, 0xFB, -+0x68, 0x4B, 0x93, 0xF8, 0xB6, 0x30, 0x23, 0xB1, 0x67, 0x4A, 0x13, 0x68, 0x43, 0xF0, 0x01, 0x03, 0x13, 0x60, 0xD6, 0xF8, -+0x60, 0x32, 0x98, 0x47, 0x64, 0x4A, 0x65, 0x49, 0xD6, 0xF8, 0x9C, 0x34, 0x11, 0x60, 0x98, 0x47, 0x4D, 0x4A, 0x63, 0x48, -+0x13, 0x68, 0x30, 0x24, 0x43, 0xF0, 0x04, 0x03, 0x13, 0x60, 0x01, 0x21, 0x04, 0x60, 0x00, 0x20, 0x17, 0xF0, 0xDE, 0xF9, -+0x5E, 0x4B, 0x1B, 0x68, 0x5A, 0x78, 0x22, 0xB1, 0x5D, 0x49, 0x0A, 0x68, 0x42, 0xF0, 0x40, 0x02, 0x0A, 0x60, 0x5C, 0x49, -+0x9B, 0x78, 0x0A, 0x68, 0xD8, 0x06, 0x4C, 0xBF, 0x22, 0xF0, 0x00, 0x42, 0x42, 0xF0, 0x00, 0x42, 0x0A, 0x60, 0x58, 0x4A, -+0x13, 0xF0, 0x01, 0x0F, 0x13, 0x68, 0x14, 0xBF, 0x43, 0xF4, 0x80, 0x23, 0x23, 0xF4, 0x80, 0x23, 0x13, 0x60, 0xBD, 0xE8, -+0xF0, 0x81, 0x3C, 0x4B, 0x1B, 0x68, 0xB3, 0xF1, 0xC8, 0x5F, 0xBF, 0xF4, 0x4D, 0xAF, 0x50, 0x49, 0x50, 0x48, 0xF3, 0x22, -+0x19, 0xF0, 0x9C, 0xF8, 0x46, 0xE7, 0xF5, 0xF7, 0x35, 0xFC, 0x00, 0x28, 0x3F, 0xF4, 0x74, 0xAF, 0x6B, 0x68, 0x9A, 0x06, -+0x7F, 0xF5, 0x70, 0xAF, 0x28, 0x8C, 0xF5, 0xF7, 0x71, 0xFC, 0x07, 0xF0, 0xB9, 0xFF, 0xD6, 0xF8, 0xE0, 0x33, 0x98, 0x47, -+0x94, 0xF8, 0x62, 0x30, 0x04, 0x2B, 0x3F, 0xF4, 0x63, 0xAF, 0xD6, 0xF8, 0x30, 0x33, 0x94, 0xF8, 0x63, 0x00, 0x98, 0x47, -+0x5C, 0xE7, 0xF5, 0xF7, 0x3F, 0xFC, 0x00, 0x28, 0x3F, 0xF4, 0x4C, 0xAF, 0xF5, 0xF7, 0x6E, 0xFC, 0xDF, 0xF8, 0xF4, 0x80, -+0xD8, 0xF8, 0x00, 0x30, 0x00, 0x02, 0x23, 0xF4, 0xE0, 0x63, 0x00, 0xF4, 0xE0, 0x60, 0x18, 0x43, 0xC8, 0xF8, 0x00, 0x00, -+0xD8, 0xF8, 0x00, 0x30, 0x23, 0xF0, 0xE0, 0x03, 0x43, 0xF0, 0x60, 0x03, 0xC8, 0xF8, 0x00, 0x30, 0xD8, 0xF8, 0x00, 0x30, -+0x43, 0xF0, 0x04, 0x03, 0xC8, 0xF8, 0x00, 0x30, 0xD8, 0xF8, 0x00, 0x30, 0x43, 0xF0, 0x01, 0x03, 0xC8, 0xF8, 0x00, 0x30, -+0x3B, 0x68, 0x1B, 0x04, 0x0F, 0xD4, 0x15, 0x4B, 0x1B, 0x68, 0x9B, 0x03, 0x7F, 0xF5, 0x22, 0xAF, 0xF5, 0xF7, 0x18, 0xFC, -+0x00, 0x28, 0x3F, 0xF4, 0x1D, 0xAF, 0x27, 0x4A, 0x13, 0x68, 0x43, 0xF0, 0x02, 0x03, 0x13, 0x60, 0x16, 0xE7, 0xF5, 0xF7, -+0xDF, 0xFB, 0x00, 0x28, 0xEB, 0xD0, 0xD8, 0xF8, 0x00, 0x30, 0x23, 0xF0, 0x60, 0x63, 0x43, 0xF0, 0x80, 0x63, 0xC8, 0xF8, -+0x00, 0x30, 0xE2, 0xE7, 0x88, 0x1A, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, 0x54, 0x00, 0x32, 0x40, 0x64, 0x00, 0x32, 0x40, -+0x38, 0x36, 0x17, 0x00, 0xD8, 0x00, 0x32, 0x40, 0x10, 0x19, 0x04, 0x00, 0x04, 0x00, 0x32, 0x40, 0x48, 0x80, 0x32, 0x40, -+0x6C, 0x00, 0x32, 0x40, 0x68, 0x00, 0x32, 0x40, 0x14, 0x00, 0x32, 0x40, 0x20, 0x00, 0x32, 0x40, 0x24, 0x00, 0x32, 0x40, -+0x98, 0x9C, 0x17, 0x00, 0x74, 0x80, 0x32, 0x40, 0x80, 0x80, 0x32, 0x40, 0x4C, 0xF1, 0x73, 0x8B, 0xC0, 0x07, 0xF9, 0x80, -+0x2C, 0x19, 0x17, 0x00, 0x8C, 0x00, 0x32, 0x40, 0xC0, 0xB3, 0x33, 0x40, 0xA0, 0xA0, 0x28, 0x28, 0x38, 0x00, 0x32, 0x40, -+0x34, 0x36, 0x17, 0x00, 0x24, 0x02, 0x32, 0x40, 0x80, 0x04, 0x32, 0x40, 0x10, 0x03, 0x32, 0x40, 0x70, 0x79, 0x15, 0x00, -+0x40, 0x88, 0x15, 0x00, 0x50, 0x03, 0x32, 0x40, 0x9C, 0x00, 0x32, 0x40, 0x1C, 0x00, 0x32, 0x40, 0x10, 0x00, 0x32, 0x40, -+0x2D, 0xE9, 0xF0, 0x47, 0x5B, 0x4B, 0x5C, 0x4A, 0x1D, 0x68, 0xD2, 0xF8, 0x20, 0x80, 0x15, 0xF0, 0x01, 0x05, 0xD8, 0xF8, -+0xE4, 0x90, 0x84, 0xB0, 0x00, 0xF0, 0x83, 0x80, 0x1A, 0x68, 0x57, 0x4F, 0x22, 0xF0, 0x01, 0x02, 0x1A, 0x60, 0x00, 0x23, -+0x7B, 0x70, 0x01, 0x22, 0x54, 0x48, 0x55, 0x49, 0x03, 0x68, 0x55, 0x4C, 0x43, 0xF0, 0x10, 0x03, 0x03, 0x60, 0x0B, 0x68, -+0x00, 0xF5, 0xEC, 0x10, 0x00, 0xF6, 0x6C, 0x70, 0x23, 0xF0, 0x01, 0x03, 0x0B, 0x60, 0x23, 0x68, 0x01, 0x69, 0x00, 0x91, -+0x02, 0x20, 0x4E, 0x49, 0x4E, 0x4C, 0x18, 0xF0, 0x9D, 0xFD, 0x3B, 0x78, 0x00, 0x2B, 0x42, 0xD0, 0xD4, 0xF8, 0x3C, 0x31, -+0xD8, 0xF8, 0x40, 0x60, 0x00, 0x20, 0x98, 0x47, 0x49, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x62, 0xDB, -+0xD4, 0xF8, 0x9C, 0x34, 0xDF, 0xF8, 0x38, 0xA1, 0x98, 0x47, 0xD4, 0xF8, 0x80, 0x34, 0x30, 0x79, 0x98, 0x47, 0x4F, 0xF0, -+0x00, 0x0C, 0x33, 0x89, 0xF2, 0x88, 0x71, 0x79, 0x30, 0x79, 0xCD, 0xF8, 0x08, 0xC0, 0x96, 0xF8, 0x0D, 0xC0, 0xCD, 0xF8, -+0x04, 0xC0, 0xB6, 0xF8, 0x0A, 0xC0, 0xCD, 0xF8, 0x00, 0xC0, 0xF5, 0xF7, 0x9F, 0xFA, 0xD4, 0xF8, 0x3C, 0x33, 0x96, 0xF9, -+0x0C, 0x00, 0x98, 0x47, 0x9A, 0xF8, 0x2A, 0x30, 0x00, 0x2B, 0x33, 0xD0, 0xD4, 0xF8, 0xA8, 0x34, 0xBA, 0xF8, 0x26, 0x00, -+0x98, 0x47, 0xBA, 0xF8, 0x26, 0x00, 0xD4, 0xF8, 0xAC, 0x34, 0x98, 0x47, 0xD4, 0xF8, 0xD8, 0x34, 0x49, 0x46, 0x40, 0x46, -+0x98, 0x47, 0x00, 0x23, 0xC7, 0xE9, 0x01, 0x33, 0x3B, 0x70, 0x00, 0x2D, 0x33, 0xD0, 0x2B, 0x49, 0x2B, 0x4A, 0x0B, 0x68, -+0x23, 0xF4, 0x00, 0x73, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF0, 0x01, 0x03, 0x13, 0x60, 0x28, 0x4A, 0x28, 0x48, 0x13, 0x68, -+0x28, 0x49, 0x23, 0xF0, 0xFF, 0x03, 0x43, 0xF0, 0x10, 0x03, 0x13, 0x60, 0x83, 0x68, 0xD4, 0xF8, 0xA0, 0x22, 0x5A, 0x65, -+0x20, 0x23, 0x0B, 0x60, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x16, 0x4F, 0x2A, 0x46, 0x81, 0xE7, 0xD4, 0xF8, 0xA0, 0x34, -+0xBA, 0xF8, 0x26, 0x00, 0x98, 0x47, 0xBA, 0xF8, 0x26, 0x00, 0xD4, 0xF8, 0xA4, 0x34, 0x98, 0x47, 0xCA, 0xE7, 0x33, 0x7E, -+0xFF, 0x2B, 0x99, 0xD1, 0x19, 0x49, 0x1A, 0x48, 0x40, 0xF2, 0x89, 0x12, 0x18, 0xF0, 0x4C, 0xFF, 0x92, 0xE7, 0x40, 0x46, -+0x0B, 0xF0, 0xF6, 0xF8, 0xD8, 0xF8, 0x04, 0x30, 0x15, 0x4A, 0x43, 0xF0, 0x01, 0x03, 0xC8, 0xF8, 0x04, 0x30, 0x92, 0xF8, -+0xB6, 0x30, 0x00, 0x2B, 0xC7, 0xD0, 0x03, 0xF0, 0x99, 0xF8, 0xC4, 0xE7, 0x10, 0x00, 0x58, 0x40, 0x1C, 0x9E, 0x17, 0x00, -+0x3C, 0x36, 0x17, 0x00, 0x94, 0x80, 0x32, 0x40, 0x84, 0x40, 0x04, 0x40, 0x88, 0x00, 0x32, 0x40, 0x88, 0x88, 0x15, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x90, 0xB3, 0x33, 0x40, 0x8C, 0x00, 0x32, 0x40, 0x78, 0x00, 0x32, 0x40, -+0x00, 0xED, 0x00, 0xE0, 0x00, 0xE1, 0x00, 0xE0, 0x70, 0x79, 0x15, 0x00, 0xA4, 0x88, 0x15, 0x00, 0x2C, 0x19, 0x17, 0x00, -+0xBC, 0x34, 0x17, 0x00, 0xF8, 0xB5, 0x3F, 0x4F, 0x3F, 0x4C, 0x3E, 0x6A, 0x3F, 0x49, 0xD6, 0xF8, 0xE4, 0x50, 0x4F, 0xF4, -+0xBE, 0x72, 0x20, 0x46, 0x2B, 0xF0, 0xB0, 0xF9, 0x31, 0x46, 0x4F, 0xF4, 0xA4, 0x62, 0x04, 0xF5, 0xBE, 0x70, 0x2B, 0xF0, -+0xA9, 0xF9, 0x29, 0x46, 0x4F, 0xF4, 0x1E, 0x72, 0x04, 0xF2, 0x9C, 0x60, 0x2B, 0xF0, 0xA2, 0xF9, 0x06, 0xF1, 0xEC, 0x01, -+0xE8, 0x22, 0x04, 0xF6, 0x14, 0x10, 0x2B, 0xF0, 0x9B, 0xF9, 0x31, 0x6C, 0x1C, 0x22, 0x04, 0xF6, 0xFC, 0x10, 0x2B, 0xF0, -+0x95, 0xF9, 0x2F, 0x49, 0x34, 0x22, 0x04, 0xF6, 0x18, 0x20, 0x2B, 0xF0, 0x8F, 0xF9, 0x2D, 0x49, 0x18, 0x22, 0x04, 0xF6, -+0x4C, 0x20, 0x2B, 0xF0, 0x89, 0xF9, 0x2B, 0x49, 0x4F, 0xF4, 0x40, 0x72, 0x04, 0xF6, 0x64, 0x20, 0x2B, 0xF0, 0x82, 0xF9, -+0x28, 0x49, 0x4F, 0xF4, 0x98, 0x62, 0x04, 0xF6, 0x64, 0x50, 0x2B, 0xF0, 0x7B, 0xF9, 0x26, 0x49, 0x26, 0x48, 0x40, 0x22, -+0x2B, 0xF0, 0x76, 0xF9, 0x39, 0x46, 0x28, 0x22, 0x24, 0x48, 0x2B, 0xF0, 0x71, 0xF9, 0x24, 0x49, 0x24, 0x48, 0x60, 0x22, -+0x2B, 0xF0, 0x6C, 0xF9, 0x23, 0x4A, 0x24, 0x4B, 0x12, 0x68, 0xD3, 0xF8, 0x84, 0x60, 0xB2, 0xF8, 0x3C, 0xC0, 0xD3, 0xF8, -+0x80, 0x20, 0xD3, 0xE9, 0x22, 0x07, 0x41, 0xF2, 0x10, 0x33, 0x41, 0xF2, 0x30, 0x31, 0x24, 0xF8, 0x03, 0xC0, 0x41, 0xF2, -+0x2C, 0x33, 0x66, 0x50, 0xE2, 0x50, 0x41, 0xF2, 0x38, 0x36, 0x41, 0xF2, 0x3C, 0x33, 0x41, 0xF2, 0x34, 0x31, 0x18, 0x4A, -+0xE2, 0x50, 0xA7, 0x51, 0x17, 0x4B, 0x60, 0x50, 0x05, 0xF5, 0xBC, 0x70, 0x05, 0xF5, 0xCE, 0x71, 0x50, 0xF8, 0x04, 0x2F, -+0x1A, 0xB1, 0x14, 0x7B, 0x9C, 0x70, 0x12, 0x89, 0x1A, 0x80, 0x88, 0x42, 0x03, 0xF1, 0x04, 0x03, 0xF4, 0xD1, 0xF8, 0xBD, -+0x1C, 0x9E, 0x17, 0x00, 0x00, 0x40, 0x1E, 0x00, 0xE4, 0xB8, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, -+0xF4, 0xE4, 0x17, 0x00, 0x34, 0xE0, 0x17, 0x00, 0xF4, 0xDF, 0x17, 0x00, 0x24, 0x52, 0x1E, 0x00, 0x64, 0x52, 0x1E, 0x00, -+0x30, 0x9D, 0x17, 0x00, 0x8C, 0x52, 0x1E, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0xEC, 0x34, 0x17, 0x00, -+0xEC, 0x52, 0x1E, 0x00, 0x70, 0xB5, 0x65, 0x4A, 0x53, 0x78, 0x00, 0x2B, 0x7F, 0xD1, 0x64, 0x4B, 0x1B, 0x68, 0x3B, 0xB1, -+0x63, 0x48, 0xD9, 0x68, 0x00, 0x69, 0x09, 0x1A, 0xB1, 0xF5, 0xFA, 0x6F, 0x00, 0xF1, 0xA5, 0x80, 0x13, 0x78, 0x00, 0x2B, -+0x68, 0xD0, 0xD2, 0xE9, 0x01, 0x35, 0x5D, 0x48, 0x5D, 0x4A, 0x5E, 0x49, 0x04, 0x69, 0x0E, 0x68, 0xB2, 0xF8, 0xB0, 0x00, -+0xB2, 0xF8, 0xB2, 0x10, 0xB2, 0x8E, 0x2B, 0x44, 0x1B, 0x1B, 0x1B, 0x1A, 0x5B, 0x1A, 0x9B, 0x1A, 0x00, 0x2B, 0xC0, 0xF2, -+0x98, 0x80, 0xFF, 0xF7, 0x37, 0xFF, 0x56, 0x4B, 0x1B, 0x6A, 0x1C, 0x6C, 0x23, 0x79, 0x20, 0x89, 0x00, 0x2B, 0x56, 0xD0, -+0x2A, 0xF0, 0xC8, 0xFB, 0x02, 0x46, 0x0B, 0x46, 0x2A, 0xF0, 0x78, 0xFA, 0x50, 0x4B, 0x00, 0x22, 0x2A, 0xF0, 0x54, 0xFD, -+0x4F, 0x4B, 0x00, 0x22, 0x2A, 0xF0, 0x26, 0xFC, 0x2A, 0xF0, 0x1E, 0xFA, 0x2A, 0xF0, 0xBC, 0xFE, 0x05, 0x46, 0x20, 0x89, -+0x2A, 0xF0, 0xB4, 0xFB, 0x02, 0x46, 0x0B, 0x46, 0x00, 0x20, 0x49, 0x49, 0x2A, 0xF0, 0x42, 0xFD, 0x00, 0x22, 0x4F, 0xF0, -+0x83, 0x43, 0x2A, 0xF0, 0x13, 0xFC, 0x2A, 0xF0, 0x0B, 0xFA, 0x2A, 0xF0, 0xA9, 0xFE, 0x03, 0x46, 0x20, 0x89, 0x1C, 0x46, -+0x2A, 0xF0, 0xA0, 0xFB, 0x34, 0xA3, 0xD3, 0xE9, 0x00, 0x23, 0x2A, 0xF0, 0x2F, 0xFD, 0x00, 0x22, 0x4F, 0xF0, 0x83, 0x43, -+0x2A, 0xF0, 0x00, 0xFC, 0x2A, 0xF0, 0xF8, 0xF9, 0x2A, 0xF0, 0x96, 0xFE, 0x3A, 0x4B, 0x3B, 0x49, 0x03, 0xF5, 0x99, 0x56, -+0x02, 0x46, 0x35, 0x60, 0x41, 0xF2, 0x24, 0x30, 0x41, 0xF2, 0x28, 0x35, 0x1C, 0x50, 0x5A, 0x51, 0x02, 0x20, 0x18, 0xF0, -+0xD5, 0xFB, 0x35, 0x4B, 0x4F, 0xF0, 0x80, 0x42, 0x1A, 0x60, 0x70, 0xBD, 0x33, 0x49, 0x02, 0x20, 0x18, 0xF0, 0xCC, 0xFB, -+0x30, 0x4B, 0x4F, 0xF0, 0x00, 0x42, 0x1A, 0x60, 0x70, 0xBD, 0x30, 0x49, 0xF5, 0xE7, 0x2A, 0xF0, 0x71, 0xFB, 0x2F, 0x4B, -+0x00, 0x22, 0x2A, 0xF0, 0xD7, 0xFB, 0x25, 0x4B, 0x00, 0x22, 0x2A, 0xF0, 0xFD, 0xFC, 0x24, 0x4B, 0x00, 0x22, 0x2A, 0xF0, -+0xCF, 0xFB, 0x2A, 0xF0, 0xC7, 0xF9, 0x2A, 0xF0, 0x65, 0xFE, 0x05, 0x46, 0x20, 0x89, 0x2A, 0xF0, 0x5D, 0xFB, 0x02, 0x46, -+0x0B, 0x46, 0x00, 0x20, 0x24, 0x49, 0x2A, 0xF0, 0xEB, 0xFC, 0x00, 0x22, 0x4F, 0xF0, 0x83, 0x43, 0x2A, 0xF0, 0xBC, 0xFB, -+0x2A, 0xF0, 0xB4, 0xF9, 0x2A, 0xF0, 0x52, 0xFE, 0x03, 0x46, 0x20, 0x89, 0x1C, 0x46, 0x2A, 0xF0, 0x49, 0xFB, 0x0B, 0xA3, -+0xD3, 0xE9, 0x00, 0x23, 0xA7, 0xE7, 0x5A, 0x68, 0x1A, 0x49, 0x02, 0x20, 0x18, 0xF0, 0x92, 0xFB, 0x13, 0x4B, 0x4F, 0xF0, -+0x00, 0x42, 0x1A, 0x60, 0x70, 0xBD, 0x17, 0x49, 0xBB, 0xE7, 0x00, 0xBF, 0xAF, 0xF3, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x10, 0xB3, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xA2, 0x40, 0x3C, 0x36, 0x17, 0x00, 0xD0, 0x9C, 0x17, 0x00, -+0x00, 0x10, 0x50, 0x40, 0x2C, 0x19, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, 0x00, 0x00, 0x6A, 0x40, -+0x00, 0x00, 0x50, 0x41, 0x00, 0x00, 0xB9, 0x40, 0x00, 0x40, 0x1E, 0x00, 0x20, 0x89, 0x15, 0x00, 0x00, 0x41, 0x04, 0x40, -+0x1C, 0x89, 0x15, 0x00, 0xC4, 0x88, 0x15, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0xA4, 0x40, 0xE8, 0x88, 0x15, 0x00, -+0x00, 0x89, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x2D, 0xED, 0x02, 0x8B, 0x56, 0x4E, 0xDF, 0xF8, 0x90, 0x81, 0x96, 0xF8, -+0xDF, 0x31, 0x96, 0xF8, 0xBF, 0x56, 0xDF, 0xF8, 0x88, 0xB1, 0x53, 0x4C, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x03, 0xF7, -+0x83, 0xB0, 0x08, 0xEB, 0x07, 0x09, 0x06, 0xF5, 0xBE, 0x71, 0x48, 0x46, 0x01, 0x93, 0x4F, 0xF4, 0x1E, 0x7A, 0x00, 0x97, -+0x2B, 0xF0, 0x0E, 0xF8, 0x07, 0xF1, 0xEC, 0x00, 0x0A, 0xFB, 0x05, 0xF5, 0x06, 0xF6, 0x14, 0x11, 0xE8, 0x22, 0x40, 0x44, -+0x2B, 0xF0, 0x04, 0xF8, 0x05, 0xEB, 0x0B, 0x03, 0x18, 0x46, 0x52, 0x46, 0x06, 0xF2, 0x9C, 0x61, 0x08, 0xEE, 0x10, 0x3A, -+0x2A, 0xF0, 0xFA, 0xFF, 0x06, 0xF6, 0xFC, 0x11, 0x1C, 0x22, 0xD9, 0xF8, 0x40, 0x00, 0x3F, 0x4F, 0xDF, 0xF8, 0x30, 0xA1, -+0x2A, 0xF0, 0xF0, 0xFF, 0x06, 0xF6, 0x18, 0x21, 0x34, 0x22, 0x3C, 0x48, 0x2A, 0xF0, 0xEA, 0xFF, 0x31, 0x46, 0x4F, 0xF4, -+0xBE, 0x72, 0x3A, 0x48, 0x2A, 0xF0, 0xE4, 0xFF, 0x06, 0xF6, 0x4C, 0x21, 0x18, 0x22, 0x38, 0x48, 0x2A, 0xF0, 0xDE, 0xFF, -+0x06, 0xF6, 0x64, 0x21, 0x4F, 0xF4, 0x18, 0x62, 0x35, 0x48, 0x2A, 0xF0, 0xD7, 0xFF, 0x06, 0xF6, 0x64, 0x51, 0x4F, 0xF4, -+0x98, 0x62, 0x33, 0x48, 0x33, 0x4E, 0x2A, 0xF0, 0xCF, 0xFF, 0x40, 0x22, 0xA4, 0xF1, 0xC8, 0x01, 0x31, 0x48, 0x2A, 0xF0, -+0xC9, 0xFF, 0x28, 0x22, 0xA4, 0xF1, 0x88, 0x01, 0x2F, 0x48, 0x2A, 0xF0, 0xC3, 0xFF, 0x2F, 0x48, 0x60, 0x22, 0xA4, 0xF1, -+0x60, 0x01, 0x2A, 0xF0, 0xBD, 0xFF, 0x05, 0xF5, 0xBE, 0x75, 0xAB, 0x44, 0x5B, 0xF8, 0x04, 0x3B, 0x50, 0x46, 0x19, 0x46, -+0x4B, 0xB1, 0xA2, 0x78, 0x1A, 0x73, 0xD7, 0xF8, 0xDC, 0x22, 0x25, 0x88, 0x1D, 0x81, 0xC3, 0xE9, 0x45, 0x23, 0x17, 0xF0, -+0x01, 0xF9, 0x04, 0x34, 0xB4, 0x42, 0xED, 0xD1, 0x1B, 0x48, 0x22, 0x4D, 0x49, 0x46, 0x17, 0xF0, 0xF9, 0xF8, 0x21, 0x48, -+0x49, 0x46, 0x17, 0xF0, 0xA5, 0xF8, 0x00, 0x9E, 0x06, 0xF1, 0xE4, 0x00, 0x18, 0xEE, 0x10, 0x1A, 0x40, 0x44, 0x17, 0xF0, -+0x9D, 0xF8, 0x01, 0x9A, 0xA4, 0x24, 0x99, 0x23, 0x14, 0xFB, 0x02, 0x34, 0x08, 0xEB, 0xC4, 0x04, 0x35, 0x44, 0x20, 0x46, -+0x17, 0xF0, 0x8E, 0xF8, 0x04, 0xF1, 0x28, 0x00, 0x08, 0x34, 0x17, 0xF0, 0x89, 0xF8, 0xAC, 0x42, 0xF5, 0xD1, 0x00, 0x9B, -+0x03, 0xF5, 0xA3, 0x60, 0x40, 0x44, 0x03, 0xB0, 0xBD, 0xEC, 0x02, 0x8B, 0xBD, 0xE8, 0xF0, 0x4F, 0x17, 0xF0, 0x7C, 0xB8, -+0x00, 0x40, 0x1E, 0x00, 0xEC, 0x52, 0x1E, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, 0xE4, 0xB8, 0x17, 0x00, -+0x00, 0x88, 0x17, 0x00, 0xF4, 0xE4, 0x17, 0x00, 0x34, 0xE0, 0x17, 0x00, 0x10, 0x53, 0x1E, 0x00, 0xF4, 0xDF, 0x17, 0x00, -+0x1C, 0x9E, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, 0x08, 0x8D, 0x17, 0x00, 0x08, 0x88, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x68, 0x65, 0x17, 0x00, 0xF8, 0xDE, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x6C, 0x4E, 0x6D, 0x4A, 0x33, 0x68, 0xDF, 0xF8, -+0x00, 0x82, 0x0D, 0x46, 0x09, 0x8C, 0x9B, 0xB2, 0x43, 0xEA, 0x01, 0x43, 0xD0, 0xF8, 0x90, 0x11, 0x33, 0x60, 0x8B, 0x78, -+0x67, 0x49, 0x02, 0xEB, 0x83, 0x03, 0x1C, 0x3E, 0x5B, 0x69, 0x0B, 0x60, 0x31, 0x68, 0x21, 0xF4, 0xE0, 0x61, 0x04, 0x46, -+0x50, 0x68, 0x31, 0x60, 0x13, 0x68, 0x62, 0x49, 0x62, 0x4A, 0x03, 0x43, 0x0B, 0x60, 0x62, 0x4B, 0x62, 0x49, 0x11, 0x60, -+0x62, 0x4A, 0x1A, 0x60, 0xD8, 0xF8, 0x00, 0x30, 0x9F, 0x03, 0x70, 0xD4, 0x60, 0x4B, 0x1B, 0x68, 0x1A, 0x68, 0xE2, 0xB1, -+0x5F, 0x49, 0x0A, 0x60, 0x5A, 0x68, 0xF2, 0xB1, 0xC2, 0xF3, 0x0B, 0x01, 0x00, 0x29, 0x61, 0xD1, 0xE1, 0x68, 0x5C, 0x48, -+0x22, 0xF4, 0x7F, 0x62, 0x22, 0xF0, 0x0F, 0x02, 0xC1, 0xF3, 0x0B, 0x01, 0x0A, 0x43, 0x02, 0x60, 0x9A, 0x68, 0xA2, 0xB9, -+0x57, 0x4A, 0x21, 0x69, 0x11, 0x60, 0xDB, 0x68, 0xA3, 0xB9, 0x56, 0x4B, 0x62, 0x69, 0x1A, 0x60, 0x12, 0xE0, 0x51, 0x4A, -+0xA1, 0x68, 0x11, 0x60, 0x5A, 0x68, 0x00, 0x2A, 0xE0, 0xD1, 0x4F, 0x4A, 0xE1, 0x68, 0x11, 0x60, 0x9A, 0x68, 0x00, 0x2A, -+0xEA, 0xD0, 0x4D, 0x49, 0x0A, 0x60, 0xDB, 0x68, 0x00, 0x2B, 0xEA, 0xD0, 0x4B, 0x4A, 0x13, 0x60, 0x4B, 0x4B, 0xD3, 0xF8, -+0x60, 0x32, 0x98, 0x47, 0x4A, 0x4B, 0x1B, 0x68, 0x9C, 0x01, 0x06, 0xD4, 0x49, 0x4B, 0x3E, 0x4A, 0x01, 0x21, 0x19, 0x60, -+0x13, 0x68, 0x0B, 0x43, 0x13, 0x60, 0x28, 0x46, 0x1B, 0xF0, 0xE4, 0xFA, 0x43, 0x4A, 0x13, 0x68, 0x23, 0xF0, 0x04, 0x03, -+0x13, 0x60, 0x01, 0x21, 0x00, 0x20, 0x16, 0xF0, 0x51, 0xFD, 0x41, 0x4B, 0x1B, 0x68, 0x5A, 0x78, 0x22, 0xB1, 0x40, 0x49, -+0x0A, 0x68, 0x42, 0xF0, 0x40, 0x02, 0x0A, 0x60, 0x3E, 0x49, 0x9B, 0x78, 0x0A, 0x68, 0xD8, 0x06, 0x4C, 0xBF, 0x22, 0xF0, -+0x00, 0x42, 0x42, 0xF0, 0x00, 0x42, 0x0A, 0x60, 0x3A, 0x4A, 0x13, 0xF0, 0x01, 0x0F, 0x13, 0x68, 0x14, 0xBF, 0x43, 0xF4, -+0x80, 0x23, 0x23, 0xF4, 0x80, 0x23, 0x13, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0x2B, 0x49, 0x0A, 0x60, 0xB8, 0xE7, 0xF4, 0xF7, -+0xD7, 0xFF, 0x00, 0x28, 0x8A, 0xD0, 0xF5, 0xF7, 0x07, 0xF8, 0x31, 0x4F, 0x3B, 0x68, 0x00, 0x02, 0x23, 0xF4, 0xE0, 0x63, -+0x00, 0xF4, 0xE0, 0x60, 0x18, 0x43, 0x38, 0x60, 0x3B, 0x68, 0x23, 0xF0, 0xE0, 0x03, 0x43, 0xF0, 0x60, 0x03, 0x3B, 0x60, -+0x3B, 0x68, 0x43, 0xF0, 0x04, 0x03, 0x3B, 0x60, 0x3B, 0x68, 0x43, 0xF0, 0x01, 0x03, 0x3B, 0x60, 0xD8, 0xF8, 0x00, 0x30, -+0x1B, 0x04, 0x0F, 0xD4, 0x24, 0x4B, 0x1B, 0x68, 0x9E, 0x03, 0x7F, 0xF5, 0x69, 0xAF, 0xF4, 0xF7, 0xB9, 0xFF, 0x00, 0x28, -+0x3F, 0xF4, 0x64, 0xAF, 0x1E, 0x4A, 0x13, 0x68, 0x43, 0xF0, 0x02, 0x03, 0x13, 0x60, 0x5D, 0xE7, 0xF4, 0xF7, 0x80, 0xFF, -+0x00, 0x28, 0xEB, 0xD0, 0x33, 0x68, 0x43, 0xF4, 0x00, 0x23, 0x33, 0x60, 0x3B, 0x68, 0x23, 0xF0, 0x60, 0x63, 0x43, 0xF0, -+0x80, 0x63, 0x3B, 0x60, 0xE0, 0xE7, 0x00, 0xBF, 0x68, 0x00, 0x32, 0x40, 0x98, 0x9C, 0x17, 0x00, 0xDC, 0x00, 0x32, 0x40, -+0x60, 0x00, 0x32, 0x40, 0x74, 0x80, 0x32, 0x40, 0x80, 0x80, 0x32, 0x40, 0x4C, 0xF1, 0x73, 0x8B, 0xC0, 0x07, 0xF9, 0x80, -+0xAC, 0x35, 0x17, 0x00, 0x00, 0x02, 0x32, 0x40, 0x04, 0x02, 0x32, 0x40, 0x08, 0x02, 0x32, 0x40, 0x0C, 0x02, 0x32, 0x40, -+0x88, 0x1A, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, 0x70, 0x80, 0x32, 0x40, 0x34, 0x36, 0x17, 0x00, 0x24, 0x02, 0x32, 0x40, -+0x80, 0x04, 0x32, 0x40, 0x10, 0x03, 0x32, 0x40, 0x50, 0x03, 0x32, 0x40, 0x04, 0x00, 0x32, 0x40, 0x2D, 0xE9, 0xF0, 0x41, -+0x33, 0x4D, 0xDF, 0xF8, 0xE4, 0x80, 0xD5, 0xF8, 0xD0, 0x34, 0x32, 0x4E, 0x41, 0xF2, 0x12, 0x32, 0x18, 0xF8, 0x02, 0x70, -+0x98, 0x47, 0xD5, 0xF8, 0x9C, 0x34, 0x98, 0x47, 0xD8, 0xF8, 0xBC, 0x41, 0xF4, 0xF7, 0x46, 0xF9, 0x2C, 0x49, 0xD5, 0xF8, -+0x88, 0x24, 0x0B, 0x68, 0x23, 0xF4, 0x00, 0x73, 0x0B, 0x60, 0x20, 0x79, 0x90, 0x47, 0x23, 0x79, 0x86, 0xF8, 0x2A, 0x30, -+0x62, 0x79, 0x86, 0xF8, 0x2B, 0x20, 0x62, 0x7B, 0x86, 0xF8, 0x2C, 0x20, 0xE1, 0x88, 0x20, 0x89, 0x62, 0x89, 0x32, 0x85, -+0xFF, 0xB2, 0xB1, 0x84, 0xF0, 0x84, 0xD3, 0xB9, 0xD5, 0xF8, 0xA0, 0x34, 0x98, 0x47, 0xF0, 0x8C, 0xD5, 0xF8, 0xA4, 0x34, -+0x98, 0x47, 0x1D, 0x4E, 0x94, 0xF9, 0x0C, 0x00, 0xD5, 0xF8, 0x3C, 0x33, 0x98, 0x47, 0xD5, 0xF8, 0xD4, 0x34, 0x06, 0xF5, -+0xA4, 0x61, 0x30, 0x46, 0x98, 0x47, 0x17, 0xF0, 0x0D, 0x0F, 0x0C, 0xD0, 0xD5, 0xF8, 0x54, 0x32, 0xBD, 0xE8, 0xF0, 0x41, -+0x18, 0x47, 0xD5, 0xF8, 0xA8, 0x34, 0x98, 0x47, 0xF0, 0x8C, 0xD5, 0xF8, 0xAC, 0x34, 0x98, 0x47, 0xE3, 0xE7, 0xBB, 0x07, -+0x14, 0xD5, 0x0F, 0x4A, 0xD8, 0xF8, 0x80, 0x31, 0x11, 0x69, 0x0E, 0x48, 0xD5, 0xF8, 0xE0, 0x21, 0x46, 0x61, 0x05, 0x24, -+0x44, 0x77, 0x01, 0xF5, 0x1C, 0x51, 0x43, 0xF0, 0x02, 0x03, 0xC8, 0xF8, 0x80, 0x31, 0x10, 0x31, 0xBD, 0xE8, 0xF0, 0x41, -+0x0C, 0x30, 0x10, 0x47, 0xBD, 0xE8, 0xF0, 0x81, 0x88, 0x1A, 0x17, 0x00, 0xBC, 0x34, 0x17, 0x00, 0x90, 0xB3, 0x33, 0x40, -+0x7C, 0x41, 0x1E, 0x00, 0x00, 0x10, 0x50, 0x40, 0x1C, 0x9E, 0x17, 0x00, 0x00, 0x40, 0x1E, 0x00, 0x38, 0xB5, 0x50, 0xBB, -+0x1A, 0x4B, 0x1A, 0x68, 0x52, 0xB1, 0x1A, 0x4B, 0x1A, 0x49, 0x18, 0x69, 0xD3, 0x68, 0xB1, 0xF8, 0xB0, 0x10, 0x1B, 0x1A, -+0x5B, 0x1A, 0xB3, 0xF5, 0xFA, 0x6F, 0x17, 0xD4, 0x16, 0x4A, 0x13, 0x78, 0x7B, 0xB1, 0xD2, 0xE9, 0x01, 0x34, 0x12, 0x48, -+0x14, 0x4D, 0x12, 0x49, 0x00, 0x69, 0x2A, 0x68, 0xB1, 0xF8, 0xB0, 0x10, 0x92, 0x8E, 0x23, 0x44, 0x1B, 0x1A, 0x5B, 0x1A, -+0x9B, 0x1A, 0x00, 0x2B, 0x0E, 0xDB, 0x0F, 0x4B, 0x4F, 0xF0, 0x80, 0x42, 0x1A, 0x60, 0x38, 0xBD, 0x52, 0x68, 0x0D, 0x49, -+0x02, 0x20, 0x18, 0xF0, 0xDB, 0xF8, 0x0A, 0x4B, 0x4F, 0xF0, 0x00, 0x42, 0x1A, 0x60, 0x38, 0xBD, 0x09, 0x49, 0x02, 0x20, -+0x18, 0xF0, 0xD2, 0xF8, 0xF5, 0xE7, 0x00, 0xBF, 0xD0, 0x9C, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x2C, 0x19, 0x17, 0x00, -+0x3C, 0x36, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x00, 0x41, 0x04, 0x40, 0xE8, 0x88, 0x15, 0x00, 0x28, 0x89, 0x15, 0x00, -+0xF0, 0xB5, 0x1B, 0x4B, 0x01, 0x22, 0x85, 0xB0, 0xDA, 0x60, 0xEF, 0xF3, 0x14, 0x81, 0xEF, 0xF3, 0x03, 0x82, 0xEF, 0xF3, -+0x09, 0x85, 0xEF, 0xF3, 0x08, 0x84, 0xEF, 0xF3, 0x10, 0x83, 0x70, 0x46, 0xCD, 0xE9, 0x01, 0x30, 0x00, 0x94, 0x13, 0x48, -+0x2B, 0x46, 0x18, 0xF0, 0x59, 0xF8, 0x15, 0xB9, 0x34, 0xB9, 0x05, 0xB0, 0xF0, 0xBD, 0x10, 0x48, 0x18, 0xF0, 0x52, 0xF8, -+0x00, 0x2C, 0xF8, 0xD0, 0x0E, 0x48, 0x0F, 0x4F, 0x0F, 0x4E, 0x24, 0xF0, 0x0F, 0x04, 0x18, 0xF0, 0x49, 0xF8, 0x04, 0xF5, -+0x80, 0x75, 0x06, 0xE0, 0x54, 0xF8, 0x04, 0x1B, 0x30, 0x46, 0x18, 0xF0, 0x41, 0xF8, 0xA5, 0x42, 0xE7, 0xD0, 0x23, 0x07, -+0xF6, 0xD1, 0x21, 0x46, 0x38, 0x46, 0x18, 0xF0, 0x39, 0xF8, 0xF1, 0xE7, 0x00, 0xA0, 0x10, 0x40, 0x40, 0x89, 0x15, 0x00, -+0x94, 0x89, 0x15, 0x00, 0xA0, 0x89, 0x15, 0x00, 0xAC, 0x89, 0x15, 0x00, 0xB8, 0x89, 0x15, 0x00, 0x30, 0xB4, 0x0C, 0x4C, -+0x0C, 0x49, 0xD4, 0xF8, 0x3C, 0x31, 0x0C, 0x4A, 0x0C, 0x4D, 0x43, 0xF0, 0x04, 0x03, 0xC4, 0xF8, 0x3C, 0x31, 0xC0, 0x03, -+0x03, 0x24, 0xF4, 0x23, 0x08, 0x60, 0x8C, 0x60, 0x82, 0xF8, 0x44, 0x33, 0xAB, 0x68, 0x07, 0x49, 0xC3, 0xF8, 0x50, 0x11, -+0x10, 0x23, 0x30, 0xBC, 0x93, 0x60, 0x70, 0x47, 0x00, 0x00, 0x50, 0x40, 0x00, 0xA0, 0x10, 0x40, 0x00, 0xE1, 0x00, 0xE0, -+0x00, 0xED, 0x00, 0xE0, 0xA9, 0xC5, 0x12, 0x00, 0x01, 0x4B, 0x1A, 0x68, 0x1A, 0x60, 0x70, 0x47, 0x00, 0xA0, 0x10, 0x40, -+0x02, 0x4A, 0x93, 0x68, 0x23, 0xF0, 0x02, 0x03, 0x93, 0x60, 0x70, 0x47, 0x00, 0xA0, 0x10, 0x40, 0x02, 0x4A, 0x93, 0x68, -+0x43, 0xF0, 0x02, 0x03, 0x93, 0x60, 0x70, 0x47, 0x00, 0xA0, 0x10, 0x40, 0x08, 0xB5, 0x06, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x00, 0xDB, 0xFE, 0xE7, 0x03, 0x49, 0x04, 0x48, 0xBA, 0x22, 0x18, 0xF0, 0x5F, 0xFA, 0xF8, 0xE7, -+0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x0B, 0x4B, 0x41, 0xF2, 0x1C, 0x32, 0x41, 0xF2, -+0x18, 0x31, 0x9A, 0x58, 0x5B, 0x58, 0x72, 0xB1, 0x10, 0xB4, 0x08, 0x4C, 0x00, 0x22, 0x19, 0x68, 0x58, 0x68, 0x08, 0x60, -+0x21, 0x68, 0x02, 0x32, 0x91, 0x42, 0x03, 0xF1, 0x08, 0x03, 0xF6, 0xD8, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x70, 0x47, -+0x00, 0x40, 0x1E, 0x00, 0x1C, 0x53, 0x1E, 0x00, 0x32, 0x49, 0x33, 0x4B, 0x99, 0x42, 0x10, 0xB5, 0x0C, 0xD2, 0x01, 0x3B, -+0x5B, 0x1A, 0x31, 0x4A, 0x23, 0xF0, 0x03, 0x03, 0x04, 0x33, 0x13, 0x44, 0x52, 0xF8, 0x04, 0x0B, 0x41, 0xF8, 0x04, 0x0B, -+0x9A, 0x42, 0xF9, 0xD1, 0x2C, 0x4A, 0x2D, 0x4B, 0x9A, 0x42, 0x0A, 0xD2, 0x01, 0x3B, 0x9B, 0x1A, 0x23, 0xF0, 0x03, 0x03, -+0x04, 0x33, 0x13, 0x44, 0x00, 0x21, 0x42, 0xF8, 0x04, 0x1B, 0x9A, 0x42, 0xFB, 0xD1, 0x27, 0x49, 0x27, 0x4B, 0x99, 0x42, -+0x0D, 0xD2, 0x01, 0x3B, 0x5B, 0x1A, 0x26, 0x4A, 0x23, 0xF0, 0x03, 0x03, 0x04, 0x33, 0x13, 0x44, 0x08, 0x46, 0x52, 0xF8, -+0x04, 0x4B, 0x40, 0xF8, 0x04, 0x4B, 0x9A, 0x42, 0xF9, 0xD1, 0x21, 0x4A, 0x21, 0x48, 0xD2, 0xF8, 0x88, 0x30, 0x43, 0xF4, -+0x70, 0x03, 0xC2, 0xF8, 0x88, 0x30, 0x91, 0x60, 0x00, 0x23, 0xFF, 0x21, 0xC2, 0x18, 0x01, 0x33, 0x50, 0x2B, 0x82, 0xF8, -+0x00, 0x13, 0xF9, 0xD1, 0x1A, 0x4B, 0x1B, 0x68, 0x13, 0xF0, 0x80, 0x6F, 0x16, 0x4B, 0x1B, 0x68, 0x4F, 0xF6, 0xF0, 0x72, -+0x03, 0xEA, 0x02, 0x03, 0x0D, 0xD0, 0x4C, 0xF2, 0x40, 0x22, 0x93, 0x42, 0x0D, 0xD0, 0x14, 0x4C, 0xF5, 0xF7, 0xBC, 0xFC, -+0xD4, 0xF8, 0x7C, 0x34, 0x98, 0x47, 0xD4, 0xF8, 0x74, 0x34, 0x98, 0x47, 0xFE, 0xE7, 0x4D, 0xF2, 0x10, 0x22, 0x93, 0x42, -+0xF1, 0xD1, 0x0E, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xED, 0xE7, 0x00, 0xBF, 0x80, 0x01, 0x17, 0x00, 0x5C, 0x25, 0x17, 0x00, -+0x2C, 0xD2, 0x15, 0x00, 0x60, 0x25, 0x17, 0x00, 0x28, 0x07, 0x18, 0x00, 0x00, 0x00, 0x17, 0x00, 0x80, 0x01, 0x17, 0x00, -+0x00, 0x00, 0x12, 0x00, 0x00, 0xED, 0x00, 0xE0, 0x00, 0xE1, 0x00, 0xE0, 0x00, 0x00, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0x68, 0x28, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x72, 0x4F, 0x73, 0x4E, 0x86, 0xB0, 0x3D, 0x46, 0x00, 0x24, 0x21, 0x46, -+0x55, 0xF8, 0x04, 0x2B, 0x30, 0x46, 0x01, 0x34, 0xF9, 0xF7, 0x6A, 0xFD, 0x0D, 0x2C, 0xF6, 0xD1, 0xD7, 0xE9, 0x11, 0x21, -+0x3B, 0x6C, 0x6C, 0x4D, 0x00, 0x93, 0xCD, 0xE9, 0x01, 0x21, 0x6B, 0x48, 0x79, 0x6B, 0xD7, 0xE9, 0x0E, 0x23, 0xF9, 0xF7, -+0x5B, 0xFD, 0x29, 0x68, 0x6A, 0x68, 0xAB, 0x68, 0xE8, 0x68, 0x00, 0x90, 0x66, 0x48, 0xF9, 0xF7, 0x53, 0xFD, 0x69, 0x6A, -+0xAA, 0x6A, 0xEB, 0x6A, 0x28, 0x6B, 0xEC, 0x6B, 0xCD, 0xE9, 0x00, 0x04, 0x62, 0x48, 0xF9, 0xF7, 0x49, 0xFD, 0xAC, 0x6A, -+0x14, 0xF0, 0xFF, 0x01, 0x68, 0xD1, 0xC4, 0xF3, 0x07, 0x25, 0x14, 0xF4, 0x7F, 0x4F, 0x29, 0x46, 0x44, 0xD1, 0x21, 0x0C, -+0x2E, 0xD1, 0xFB, 0x6C, 0x1C, 0x07, 0x23, 0xD5, 0x5A, 0x48, 0xF9, 0xF7, 0x37, 0xFD, 0x3B, 0x6D, 0xD8, 0x07, 0x21, 0xD4, -+0x58, 0x48, 0xF9, 0xF7, 0x31, 0xFD, 0xFB, 0x6C, 0x59, 0x07, 0x4C, 0xBF, 0x56, 0x48, 0x57, 0x48, 0xF9, 0xF7, 0x2A, 0xFD, -+0x39, 0x6D, 0xEF, 0xF3, 0x10, 0x82, 0xEF, 0xF3, 0x13, 0x83, 0xEF, 0xF3, 0x11, 0x80, 0x00, 0x90, 0x52, 0x48, 0xF9, 0xF7, -+0x1F, 0xFD, 0xBC, 0x6C, 0x00, 0x2C, 0x71, 0xD1, 0x7C, 0x6C, 0x00, 0x2C, 0x56, 0xD1, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, -+0x4D, 0x48, 0xF9, 0xF7, 0x13, 0xFD, 0xDD, 0xE7, 0x4C, 0x48, 0xF9, 0xF7, 0x0F, 0xFD, 0xDC, 0xE7, 0xC4, 0xF3, 0x40, 0x63, -+0xC4, 0xF3, 0x00, 0x60, 0xC4, 0xF3, 0xC0, 0x42, 0x03, 0x93, 0xC4, 0xF3, 0x80, 0x43, 0xCD, 0xE9, 0x01, 0x20, 0x00, 0x93, -+0xC4, 0xF3, 0x00, 0x42, 0xC4, 0xF3, 0x40, 0x43, 0x43, 0x48, 0xF9, 0xF7, 0xFB, 0xFC, 0xBC, 0xE7, 0xC4, 0xF3, 0xC0, 0x33, -+0xC4, 0xF3, 0x00, 0x30, 0xC4, 0xF3, 0xC0, 0x22, 0x04, 0x93, 0xC4, 0xF3, 0x40, 0x36, 0xC4, 0xF3, 0x80, 0x23, 0xCD, 0xE9, -+0x00, 0x32, 0xCD, 0xE9, 0x02, 0x06, 0xC4, 0xF3, 0x40, 0x23, 0x3A, 0x48, 0xC4, 0xF3, 0x00, 0x22, 0xF9, 0xF7, 0xE4, 0xFC, -+0x2D, 0x06, 0xA2, 0xD5, 0x2A, 0x4B, 0x37, 0x48, 0x99, 0x6B, 0xF9, 0xF7, 0xDD, 0xFC, 0x9C, 0xE7, 0xC4, 0xF3, 0xC0, 0x16, -+0xC4, 0xF3, 0x40, 0x10, 0xC4, 0xF3, 0x00, 0x12, 0xC4, 0xF3, 0xC0, 0x03, 0xCD, 0xE9, 0x02, 0x06, 0xCD, 0xE9, 0x00, 0x32, -+0x2F, 0x48, 0xC4, 0xF3, 0x40, 0x03, 0x04, 0xF0, 0x01, 0x02, 0xF9, 0xF7, 0xC9, 0xFC, 0x26, 0x06, 0x81, 0xD5, 0x69, 0x6B, -+0x2B, 0x48, 0xF9, 0xF7, 0xC3, 0xFC, 0x7C, 0xE7, 0x2A, 0x48, 0x2B, 0x4F, 0x2B, 0x4E, 0x24, 0xF0, 0x0F, 0x04, 0xF9, 0xF7, -+0xBB, 0xFC, 0x04, 0xF5, 0x80, 0x75, 0x06, 0xE0, 0x54, 0xF8, 0x04, 0x1B, 0x30, 0x46, 0xF9, 0xF7, 0xB3, 0xFC, 0xA5, 0x42, -+0x97, 0xD0, 0x23, 0x07, 0xF6, 0xD1, 0x21, 0x46, 0x38, 0x46, 0xF9, 0xF7, 0xAB, 0xFC, 0xF1, 0xE7, 0x21, 0x48, 0xDF, 0xF8, -+0x7C, 0x80, 0x1F, 0x4E, 0x24, 0xF0, 0x0F, 0x04, 0xF9, 0xF7, 0xA2, 0xFC, 0x04, 0xF5, 0x80, 0x75, 0x07, 0xE0, 0x54, 0xF8, -+0x04, 0x1B, 0x30, 0x46, 0xF9, 0xF7, 0x9A, 0xFC, 0xA5, 0x42, 0x3F, 0xF4, 0x7B, 0xAF, 0x22, 0x07, 0xF5, 0xD1, 0x21, 0x46, -+0x40, 0x46, 0xF9, 0xF7, 0x91, 0xFC, 0xF0, 0xE7, 0xE4, 0x60, 0x17, 0x00, 0xC0, 0x89, 0x15, 0x00, 0x00, 0xED, 0x00, 0xE0, -+0xD0, 0x89, 0x15, 0x00, 0x1C, 0x8A, 0x15, 0x00, 0x50, 0x8A, 0x15, 0x00, 0xF0, 0x8B, 0x15, 0x00, 0x10, 0x8C, 0x15, 0x00, -+0x34, 0x8C, 0x15, 0x00, 0x40, 0x8C, 0x15, 0x00, 0x4C, 0x8C, 0x15, 0x00, 0x24, 0x8C, 0x15, 0x00, 0x00, 0x8C, 0x15, 0x00, -+0x8C, 0x8B, 0x15, 0x00, 0x04, 0x8B, 0x15, 0x00, 0x7C, 0x8B, 0x15, 0x00, 0x90, 0x8A, 0x15, 0x00, 0xF4, 0x8A, 0x15, 0x00, -+0x80, 0x8C, 0x15, 0x00, 0xAC, 0x89, 0x15, 0x00, 0xB8, 0x89, 0x15, 0x00, 0xA0, 0x89, 0x15, 0x00, 0x08, 0xB5, 0x02, 0x48, -+0xF9, 0xF7, 0x60, 0xFC, 0xFE, 0xE7, 0x00, 0xBF, 0x8C, 0x8C, 0x15, 0x00, 0x04, 0x46, 0x08, 0xB5, 0x10, 0x48, 0xF9, 0xF7, -+0x57, 0xFC, 0x30, 0x2C, 0x10, 0xD0, 0x40, 0x2C, 0x16, 0xD0, 0x20, 0x2C, 0x10, 0xD0, 0x0D, 0x48, 0xF9, 0xF7, 0x4E, 0xFC, -+0x0C, 0x48, 0xF9, 0xF7, 0x4B, 0xFC, 0xFF, 0xF7, 0xD1, 0xFE, 0x0B, 0x48, 0xF9, 0xF7, 0x46, 0xFC, 0xFF, 0xF7, 0xE0, 0xFF, -+0x09, 0x48, 0xF9, 0xF7, 0x41, 0xFC, 0xF1, 0xE7, 0x08, 0x48, 0xF9, 0xF7, 0x3D, 0xFC, 0xED, 0xE7, 0x07, 0x48, 0xF9, 0xF7, -+0x39, 0xFC, 0xE9, 0xE7, 0x98, 0x8C, 0x15, 0x00, 0xE8, 0x8C, 0x15, 0x00, 0xF4, 0x8C, 0x15, 0x00, 0x00, 0x8D, 0x15, 0x00, -+0xD0, 0x8C, 0x15, 0x00, 0xC0, 0x8C, 0x15, 0x00, 0xDC, 0x8C, 0x15, 0x00, 0x4F, 0xF0, 0x10, 0x03, 0x00, 0xF0, 0x0C, 0xB8, -+0x4F, 0xF0, 0x20, 0x03, 0x00, 0xF0, 0x08, 0xB8, 0x4F, 0xF0, 0x30, 0x03, 0x00, 0xF0, 0x04, 0xB8, 0x4F, 0xF0, 0x40, 0x03, -+0x00, 0xF0, 0x00, 0xB8, 0xEF, 0xF3, 0x08, 0x80, 0x4F, 0xF0, 0x04, 0x01, 0x72, 0x46, 0x0A, 0x42, 0x01, 0xD0, 0xEF, 0xF3, -+0x09, 0x80, 0x9C, 0x46, 0x24, 0x49, 0x02, 0x68, 0x0A, 0x60, 0x04, 0x31, 0x42, 0x68, 0x0A, 0x60, 0x04, 0x31, 0x82, 0x68, -+0x0A, 0x60, 0x04, 0x31, 0xC2, 0x68, 0x0A, 0x60, 0x04, 0x31, 0xF0, 0xC1, 0x47, 0x46, 0x0F, 0x60, 0x04, 0x31, 0x4F, 0x46, -+0x0F, 0x60, 0x04, 0x31, 0x57, 0x46, 0x0F, 0x60, 0x04, 0x31, 0x5F, 0x46, 0x0F, 0x60, 0x04, 0x31, 0x02, 0x69, 0x0A, 0x60, -+0x08, 0x31, 0x42, 0x69, 0x0A, 0x60, 0x04, 0x31, 0x82, 0x69, 0x0A, 0x60, 0x04, 0x31, 0xC2, 0x69, 0x0A, 0x60, 0x04, 0x31, -+0x03, 0x46, 0x20, 0x33, 0x4F, 0xF4, 0x00, 0x76, 0x32, 0x42, 0x00, 0xD0, 0x04, 0x33, 0x75, 0x46, 0x4F, 0xF0, 0x10, 0x06, -+0x35, 0x42, 0x00, 0xD1, 0x48, 0x33, 0x0C, 0x46, 0x10, 0x3C, 0x23, 0x60, 0xEF, 0xF3, 0x09, 0x82, 0x0A, 0x60, 0x04, 0x31, -+0xEF, 0xF3, 0x08, 0x82, 0x0A, 0x60, 0x04, 0x31, 0x72, 0x46, 0x0A, 0x60, 0x04, 0x31, 0xEF, 0xF3, 0x14, 0x82, 0x0A, 0x60, -+0x03, 0x4B, 0x60, 0x46, 0x01, 0x49, 0x98, 0x47, 0xFE, 0xE7, 0x00, 0x00, 0xE4, 0x60, 0x17, 0x00, 0x3D, 0xCA, 0x12, 0x00, -+0x08, 0xB5, 0x08, 0x4B, 0x00, 0x22, 0x5A, 0x70, 0x18, 0xF0, 0x3E, 0xF8, 0x1A, 0xF0, 0x14, 0xFC, 0x05, 0x4B, 0xD3, 0xF8, -+0xA8, 0x31, 0x98, 0x47, 0x16, 0xF0, 0x88, 0xFB, 0xBD, 0xE8, 0x08, 0x40, 0x18, 0xF0, 0x42, 0xB8, 0x70, 0x28, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0x4B, 0x4E, 0x4C, 0x4A, 0x4C, 0x49, 0x4D, 0x48, 0x17, 0xF0, 0x6E, 0xFD, -+0x33, 0x68, 0xDB, 0x78, 0x00, 0x2B, 0x40, 0xF0, 0x89, 0x80, 0x62, 0xB6, 0xBF, 0xF3, 0x4F, 0x8F, 0xBF, 0xF3, 0x6F, 0x8F, -+0xDF, 0xF8, 0x3C, 0x81, 0xDF, 0xF8, 0x3C, 0x91, 0x45, 0x4D, 0x46, 0x4F, 0x46, 0x4C, 0xDF, 0xF8, 0x38, 0xB1, 0x4F, 0xF0, -+0x01, 0x0A, 0x33, 0x68, 0xDB, 0x78, 0xFB, 0xB9, 0x98, 0xF8, 0x00, 0x30, 0x13, 0xB3, 0x18, 0xF0, 0x71, 0xFE, 0xEF, 0xF3, -+0x10, 0x83, 0xDB, 0x07, 0x02, 0xD4, 0x72, 0xB6, 0xC9, 0xF8, 0x00, 0xA0, 0x2B, 0x68, 0x3A, 0x68, 0x01, 0x33, 0x2B, 0x60, -+0xBA, 0xB1, 0x00, 0x2B, 0xE9, 0xD0, 0x01, 0x3B, 0xD9, 0xF8, 0x00, 0x20, 0x2B, 0x60, 0x00, 0x2B, 0xE3, 0xD1, 0x00, 0x2A, -+0xE1, 0xD0, 0x62, 0xB6, 0x33, 0x68, 0xDB, 0x78, 0x00, 0x2B, 0xDF, 0xD0, 0xFF, 0xF7, 0x2C, 0xFD, 0x98, 0xF8, 0x00, 0x30, -+0x00, 0x2B, 0xDC, 0xD1, 0x16, 0xF0, 0xF8, 0xFA, 0xD9, 0xE7, 0xD4, 0xF8, 0x7C, 0x32, 0x98, 0x47, 0x33, 0x68, 0xDB, 0x78, -+0x00, 0x2B, 0x37, 0xD1, 0xDB, 0xF8, 0x00, 0x30, 0x1B, 0x78, 0x01, 0x2B, 0x17, 0xD0, 0xBF, 0xF3, 0x4F, 0x8F, 0x30, 0xBF, -+0xBF, 0xF3, 0x6F, 0x8F, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0xD4, 0xF8, 0x78, 0x32, 0x98, 0x47, 0x00, 0x28, -+0xF1, 0xD0, 0x33, 0x68, 0xDB, 0x78, 0x23, 0xBB, 0xD4, 0xF8, 0x84, 0x32, 0x98, 0x47, 0x2B, 0x68, 0x00, 0x2B, 0xB0, 0xD0, -+0xC5, 0xE7, 0x1D, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0xE3, 0xD0, 0x1C, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0x17, 0xD0, -+0x01, 0x2B, 0x05, 0xD0, 0x00, 0x2B, 0xDA, 0xD1, 0x18, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0xD6, 0xD0, 0x17, 0x4B, 0x5B, 0x78, -+0x00, 0x2B, 0xD2, 0xD0, 0x16, 0x4A, 0x13, 0x68, 0x43, 0xF4, 0x80, 0x53, 0x13, 0x60, 0xCC, 0xE7, 0xFF, 0xF7, 0xEA, 0xFC, -+0xC4, 0xE7, 0xFF, 0xF7, 0xEF, 0xFC, 0xD7, 0xE7, 0xFB, 0xF7, 0x32, 0xFE, 0x00, 0x28, 0xEF, 0xD1, 0x0B, 0x4B, 0x1B, 0x68, -+0x1B, 0x78, 0xDF, 0xE7, 0x10, 0x20, 0xFF, 0xF7, 0xB1, 0xFC, 0x72, 0xE7, 0x34, 0x36, 0x17, 0x00, 0xDC, 0xD1, 0x15, 0x00, -+0x00, 0xD2, 0x15, 0x00, 0x1C, 0x8D, 0x15, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x80, 0xB6, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x3D, 0x61, 0x17, 0x00, 0x74, 0x36, 0x17, 0x00, 0x3C, 0x61, 0x17, 0x00, 0x70, 0x28, 0x17, 0x00, 0x00, 0x60, 0x50, 0x40, -+0x3C, 0x36, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x78, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0xEF, 0xF3, 0x10, 0x83, -+0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x72, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x71, 0x4C, 0x72, 0x4A, 0x23, 0x68, 0x72, 0x49, -+0x72, 0x4D, 0x01, 0x33, 0x4F, 0xF4, 0x80, 0x60, 0x23, 0x60, 0x17, 0xF0, 0xF9, 0xFC, 0x4F, 0xF0, 0x00, 0x40, 0x16, 0xF0, -+0x4D, 0xFA, 0xD5, 0xF8, 0xEC, 0x30, 0x98, 0x47, 0x6C, 0x4B, 0x6D, 0x4A, 0x19, 0x68, 0x21, 0xF0, 0x7F, 0x41, 0x19, 0x60, -+0x19, 0x68, 0x41, 0xF0, 0x10, 0x01, 0x19, 0x60, 0x11, 0x69, 0x64, 0x31, 0x13, 0x69, 0xCB, 0x1A, 0x00, 0x2B, 0xFB, 0xDA, -+0x66, 0x4E, 0xD5, 0xF8, 0x10, 0x24, 0x33, 0x68, 0x40, 0xF2, 0x11, 0x17, 0x3B, 0x43, 0x33, 0x60, 0x90, 0x47, 0x60, 0x49, -+0x62, 0x4A, 0x0B, 0x68, 0xDF, 0xF8, 0xAC, 0xC1, 0x23, 0xF0, 0x10, 0x03, 0x0B, 0x60, 0x33, 0x68, 0x23, 0xF4, 0x88, 0x73, -+0x23, 0xF0, 0x01, 0x03, 0x33, 0x60, 0x0B, 0x23, 0x10, 0x68, 0x13, 0x60, 0xDC, 0xF8, 0x00, 0x30, 0xDB, 0x06, 0x18, 0xD5, -+0x59, 0x4B, 0x40, 0xF2, 0x01, 0x2C, 0x19, 0x68, 0xC3, 0xF8, 0x00, 0xC0, 0x19, 0x60, 0x33, 0x68, 0xA2, 0xF5, 0x7C, 0x72, -+0x1F, 0x43, 0x37, 0x60, 0x11, 0x68, 0x02, 0x31, 0x13, 0x68, 0x5B, 0x1A, 0x00, 0x2B, 0xFB, 0xDB, 0x4E, 0x4A, 0x13, 0x68, -+0x23, 0xF4, 0x88, 0x73, 0x23, 0xF0, 0x01, 0x03, 0x13, 0x60, 0x4C, 0x4B, 0x18, 0x60, 0x0A, 0xF0, 0xBD, 0xFF, 0x00, 0x20, -+0x16, 0xF0, 0x8E, 0xF8, 0x00, 0x28, 0x6C, 0xD0, 0x49, 0x4E, 0x09, 0xF0, 0xA1, 0xFB, 0xB3, 0x79, 0x00, 0x2B, 0x4F, 0xD0, -+0x47, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0x66, 0xD0, 0x33, 0x78, 0x00, 0x2B, 0x47, 0xD0, 0x44, 0x4B, 0x77, 0x79, -+0x1A, 0x68, 0x96, 0xF9, 0x07, 0x30, 0x96, 0xF9, 0x04, 0xE0, 0xDF, 0xF8, 0x20, 0xC1, 0x41, 0x48, 0xDC, 0xF8, 0x00, 0x10, -+0xD5, 0xF8, 0xE0, 0x81, 0x37, 0x4D, 0x02, 0xF0, 0x0F, 0x02, 0x17, 0x44, 0x7F, 0xB2, 0x3B, 0x44, 0x73, 0x45, 0xA8, 0xBF, -+0x73, 0x46, 0x5F, 0xFA, 0x83, 0xFE, 0x21, 0xF0, 0xFF, 0x01, 0x41, 0xEA, 0x0E, 0x01, 0xCC, 0xF8, 0x00, 0x10, 0x02, 0x68, -+0x22, 0xF0, 0xFF, 0x02, 0x42, 0xEA, 0x0E, 0x02, 0x02, 0x60, 0xDC, 0xF8, 0x00, 0x10, 0xDA, 0x1E, 0x5F, 0xFA, 0x82, 0xFE, -+0x21, 0xF4, 0x7F, 0x21, 0x41, 0xEA, 0x0E, 0x31, 0xCC, 0xF8, 0x00, 0x10, 0x02, 0x68, 0xB6, 0xF8, 0x08, 0xC0, 0x22, 0xF4, -+0x7F, 0x22, 0x42, 0xEA, 0x0E, 0x32, 0x02, 0x60, 0x2A, 0x69, 0x2A, 0x48, 0x5D, 0xB2, 0x4E, 0xF6, 0x60, 0x21, 0x01, 0xFB, -+0x0C, 0x21, 0xF5, 0x71, 0xC0, 0x47, 0x00, 0x23, 0x26, 0x48, 0xB3, 0x71, 0x29, 0x46, 0x3A, 0x46, 0x17, 0xF0, 0xFC, 0xFB, -+0x24, 0x49, 0x4F, 0xF4, 0x80, 0x60, 0x17, 0xF0, 0x47, 0xFC, 0x08, 0xF0, 0x85, 0xFE, 0x18, 0xB1, 0x4F, 0xF4, 0x80, 0x10, -+0x16, 0xF0, 0x74, 0xF9, 0x23, 0x68, 0x33, 0xB1, 0x0D, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0xBD, 0xE8, 0xF0, 0x81, 0x4F, 0xF0, 0x80, 0x60, 0x16, 0xF0, 0x89, 0xF9, 0x8D, 0xE7, 0x17, 0x4B, 0x1B, 0x68, -+0x00, 0x22, 0x1A, 0x60, 0xF8, 0xF7, 0x8C, 0xFA, 0x33, 0x78, 0x00, 0x2B, 0xDA, 0xD0, 0xB3, 0x79, 0x00, 0x2B, 0x8F, 0xD1, -+0xD6, 0xE7, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x30, 0x8E, 0x15, 0x00, 0xCC, 0xB5, 0x15, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x00, 0x04, 0x32, 0x40, 0x00, 0x10, 0x50, 0x40, 0x18, 0x00, 0x34, 0x40, 0x10, 0x05, 0x32, 0x40, -+0x00, 0x10, 0x34, 0x40, 0x80, 0x35, 0x17, 0x00, 0x78, 0x36, 0x17, 0x00, 0x1C, 0x01, 0x32, 0x40, 0xD4, 0xB3, 0x33, 0x40, -+0x8C, 0x35, 0x17, 0x00, 0x30, 0x8D, 0x15, 0x00, 0x40, 0x8D, 0x15, 0x00, 0x00, 0x38, 0x18, 0x00, 0x0C, 0x05, 0x32, 0x40, -+0xAC, 0xB3, 0x33, 0x40, 0x22, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0x01, 0xD0, 0x01, 0x20, 0x70, 0x47, 0x20, 0x4B, -+0xD3, 0xF8, 0x04, 0x31, 0x1A, 0x03, 0x10, 0xB5, 0x16, 0xD4, 0x00, 0x22, 0x93, 0x00, 0x03, 0xF1, 0x60, 0x43, 0x03, 0xF5, -+0x61, 0x43, 0x01, 0x2A, 0xD3, 0xF8, 0x00, 0x01, 0x1B, 0x68, 0x00, 0xEA, 0x03, 0x00, 0x04, 0xD0, 0x30, 0xB9, 0x02, 0x2A, -+0x05, 0xD0, 0x01, 0x32, 0xEE, 0xE7, 0x30, 0xF4, 0x00, 0x23, 0xFA, 0xD0, 0x01, 0x20, 0x10, 0xBD, 0x12, 0x4B, 0x1C, 0x68, -+0x41, 0xF6, 0x33, 0x70, 0x20, 0x40, 0xF7, 0xD1, 0x63, 0x00, 0x0F, 0xD4, 0x00, 0x2C, 0x07, 0xDA, 0x0E, 0x4B, 0xD3, 0xF8, -+0x68, 0x34, 0x98, 0x47, 0x0D, 0x4B, 0x4F, 0xF0, 0x00, 0x42, 0x1A, 0x60, 0x08, 0x4B, 0x4F, 0xF4, 0x00, 0x22, 0xC3, 0xF8, -+0x84, 0x21, 0xD0, 0xE7, 0x07, 0x4B, 0xD3, 0xF8, 0x78, 0x34, 0x98, 0x47, 0x06, 0x4B, 0x4F, 0xF0, 0x80, 0x42, 0x1A, 0x60, -+0xE6, 0xE7, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, 0x00, 0xE1, 0x00, 0xE0, 0x1C, 0x41, 0x04, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0x08, 0x41, 0x04, 0x40, 0x38, 0xB5, 0x3F, 0x4C, 0x3F, 0x4D, 0x23, 0x68, 0x3F, 0x49, 0x03, 0xF0, 0x0F, 0x03, 0x02, 0x20, -+0x2B, 0x70, 0x17, 0xF0, 0x9F, 0xFB, 0x23, 0x68, 0x18, 0x07, 0x40, 0xD0, 0x3B, 0x49, 0x3C, 0x4A, 0x0B, 0x68, 0x00, 0x20, -+0x23, 0xF0, 0x00, 0x43, 0x0B, 0x60, 0x20, 0x60, 0x13, 0x68, 0x59, 0x07, 0xFC, 0xD5, 0x38, 0x4B, 0x35, 0x49, 0x38, 0x4A, -+0x04, 0x20, 0x18, 0x60, 0x0B, 0x68, 0x43, 0xF0, 0x00, 0x43, 0x0B, 0x60, 0x13, 0x68, 0x43, 0xF0, 0x00, 0x63, 0x13, 0x60, -+0x33, 0x4B, 0x1B, 0x78, 0x01, 0x22, 0x6A, 0x70, 0x9B, 0xB1, 0x32, 0x49, 0x32, 0x4A, 0x0B, 0x68, 0x23, 0xF4, 0x00, 0x13, -+0x0B, 0x60, 0x13, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x2F, 0x4B, 0x19, 0x68, 0x21, 0xF0, 0x01, 0x01, 0x19, 0x60, 0x19, 0x68, -+0x01, 0x20, 0x41, 0xF0, 0x02, 0x01, 0x19, 0x60, 0x10, 0x60, 0x20, 0x4B, 0x2A, 0x4A, 0x2B, 0x49, 0x20, 0x20, 0x18, 0x60, -+0x13, 0x68, 0x43, 0xF0, 0x10, 0x03, 0x13, 0x60, 0x0B, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0x26, 0xD0, 0x01, 0x2B, 0x06, 0xD0, -+0x38, 0xBD, 0x1E, 0x4A, 0x13, 0x68, 0x23, 0xF0, 0x00, 0x63, 0x13, 0x60, 0xD0, 0xE7, 0x22, 0x4A, 0x13, 0x68, 0x5B, 0x03, -+0xFC, 0xD5, 0x21, 0x4A, 0x11, 0x69, 0x1C, 0x31, 0x13, 0x69, 0xCB, 0x1A, 0x00, 0x2B, 0xFB, 0xDA, 0x1E, 0x49, 0x1F, 0x4A, -+0x0B, 0x68, 0x43, 0xF4, 0x00, 0x43, 0x0B, 0x60, 0x13, 0x6D, 0x43, 0xF4, 0x00, 0x43, 0x13, 0x65, 0xD3, 0x6D, 0x23, 0xF0, -+0x03, 0x03, 0x43, 0xF0, 0x00, 0x43, 0x43, 0xF0, 0x01, 0x03, 0xD3, 0x65, 0x38, 0xBD, 0x17, 0x4B, 0x1A, 0x68, 0x42, 0xF0, -+0x01, 0x02, 0x1A, 0x60, 0x1B, 0x68, 0x5A, 0x07, 0xD2, 0xD5, 0x14, 0x4B, 0x4F, 0xF4, 0x00, 0x72, 0x1A, 0x60, 0x38, 0xBD, -+0x38, 0x00, 0x32, 0x40, 0x70, 0x28, 0x17, 0x00, 0x50, 0x8D, 0x15, 0x00, 0x74, 0x80, 0x32, 0x40, 0x6C, 0x80, 0x32, 0x40, -+0x70, 0x80, 0x32, 0x40, 0x48, 0x80, 0x32, 0x40, 0x3D, 0x61, 0x17, 0x00, 0x58, 0x40, 0x34, 0x40, 0x40, 0x42, 0x04, 0x40, -+0x18, 0x00, 0x58, 0x40, 0x10, 0x00, 0x58, 0x40, 0x78, 0x36, 0x17, 0x00, 0x20, 0x10, 0x04, 0x40, 0x00, 0x10, 0x50, 0x40, -+0x14, 0x00, 0x24, 0x40, 0x00, 0x60, 0x50, 0x40, 0x84, 0x40, 0x04, 0x40, 0x00, 0x41, 0x04, 0x40, 0x00, 0x28, 0x00, 0xF0, -+0xE7, 0x80, 0x2D, 0xE9, 0xF8, 0x4F, 0x90, 0xF8, 0x64, 0x30, 0x04, 0x46, 0x0B, 0xB9, 0xBD, 0xE8, 0xF8, 0x8F, 0x83, 0x4B, -+0x83, 0x4A, 0x84, 0x4F, 0xDF, 0xF8, 0x2C, 0x92, 0xDF, 0xF8, 0x64, 0x82, 0x82, 0x4E, 0x83, 0x48, 0x0D, 0x46, 0x83, 0x49, -+0x4F, 0xF0, 0x02, 0x0B, 0xD1, 0xF8, 0x70, 0xC4, 0xC3, 0xF8, 0x80, 0xB1, 0x92, 0x68, 0x80, 0x49, 0xC2, 0xF8, 0x44, 0xC0, -+0x01, 0x22, 0xC3, 0xF8, 0x00, 0xB0, 0x3A, 0x70, 0xD9, 0xF8, 0x10, 0x20, 0x0B, 0x68, 0x7A, 0x60, 0x23, 0xF0, 0x02, 0x03, -+0x0B, 0x60, 0xD8, 0xF8, 0x00, 0x10, 0xB6, 0xF8, 0xB2, 0xC0, 0x8B, 0x8F, 0x01, 0x68, 0x63, 0x44, 0xB3, 0xEB, 0x41, 0x1F, -+0x4F, 0xEA, 0x41, 0x1A, 0xD1, 0xD2, 0x74, 0x49, 0x58, 0x46, 0x17, 0xF0, 0xC9, 0xFA, 0xD9, 0xF8, 0x10, 0x20, 0xFB, 0x68, -+0x9B, 0x1A, 0x00, 0x2B, 0x80, 0xF2, 0xB6, 0x80, 0xB4, 0xF8, 0x68, 0x20, 0x6E, 0x4B, 0xA8, 0x68, 0x41, 0xF2, 0x13, 0x31, -+0x01, 0x2A, 0x5C, 0x5C, 0x40, 0xF2, 0x9F, 0x80, 0x01, 0x3A, 0x00, 0xFB, 0x02, 0xAA, 0x41, 0xF2, 0x13, 0x31, 0x52, 0x46, -+0x5B, 0x5C, 0x68, 0x49, 0x02, 0x20, 0x17, 0xF0, 0xAD, 0xFA, 0xD8, 0xF8, 0x00, 0x30, 0xB6, 0xF8, 0xB2, 0x00, 0x9A, 0x8F, -+0x60, 0x49, 0x64, 0x4B, 0xDF, 0xF8, 0xA8, 0xC1, 0x1C, 0x69, 0x0B, 0x68, 0x02, 0x44, 0xAA, 0xEB, 0x02, 0x02, 0x22, 0xF0, -+0x03, 0x05, 0x03, 0xF0, 0x03, 0x03, 0x2B, 0x43, 0x5E, 0x4D, 0x0B, 0x60, 0x2B, 0x68, 0xBA, 0x60, 0x43, 0xF0, 0x01, 0x03, -+0x2B, 0x60, 0xDC, 0xF8, 0x00, 0x30, 0xDC, 0xF8, 0x00, 0x10, 0xC3, 0xF3, 0x09, 0x03, 0x21, 0xF4, 0x7F, 0x71, 0x43, 0xF0, -+0x01, 0x03, 0x21, 0xF0, 0x03, 0x01, 0x0B, 0x43, 0xCC, 0xF8, 0x00, 0x30, 0x2B, 0x68, 0x22, 0x44, 0x5B, 0x07, 0xFA, 0x60, -+0x03, 0xD5, 0x52, 0x4B, 0x4F, 0xF4, 0x00, 0x72, 0x1A, 0x60, 0x51, 0x49, 0x51, 0x4A, 0x0B, 0x68, 0x43, 0xF0, 0x08, 0x03, -+0x0B, 0x60, 0x13, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x4E, 0x4C, 0x45, 0x49, 0x23, 0x68, 0x43, 0xF0, 0x02, 0x03, 0x23, 0x60, -+0x01, 0x23, 0x13, 0x60, 0x0B, 0x68, 0x45, 0x4A, 0x43, 0xF0, 0x01, 0x03, 0x0B, 0x60, 0x11, 0x69, 0x01, 0xF5, 0x96, 0x71, -+0x13, 0x69, 0x5B, 0x1A, 0x00, 0x2B, 0xFB, 0xDB, 0x45, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x7F, 0xF4, 0x5D, 0xAF, -+0x43, 0x49, 0x44, 0x4C, 0x4B, 0x6A, 0x24, 0x68, 0x23, 0xF0, 0xFF, 0x03, 0x43, 0xF0, 0xDF, 0x03, 0x4B, 0x62, 0x4B, 0x6A, -+0x23, 0xF4, 0x7F, 0x43, 0x43, 0xF4, 0x5F, 0x43, 0x4B, 0x62, 0xB4, 0xB1, 0x3D, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x3F, 0xDB, 0xE3, 0x68, 0x62, 0x68, 0x3A, 0x49, 0x02, 0x20, 0x17, 0xF0, 0x3C, 0xFA, 0xB6, 0xF8, 0xB2, 0x10, -+0xE2, 0x68, 0x2D, 0x4B, 0x52, 0x1A, 0x4F, 0xF4, 0x80, 0x20, 0x04, 0x21, 0x98, 0x60, 0x1A, 0x63, 0x99, 0x60, 0x34, 0x49, -+0x2F, 0x4A, 0x0B, 0x68, 0x43, 0xF4, 0x00, 0x43, 0x0B, 0x60, 0x13, 0x6D, 0x43, 0xF4, 0x00, 0x43, 0x13, 0x65, 0xD3, 0x6D, -+0x23, 0xF0, 0x03, 0x03, 0x43, 0xF0, 0x00, 0x43, 0x43, 0xF0, 0x01, 0x03, 0xD3, 0x65, 0x13, 0x68, 0x43, 0xF4, 0x80, 0x53, -+0x13, 0x60, 0x1E, 0xE7, 0x70, 0x47, 0x41, 0xF2, 0x14, 0x32, 0x9C, 0x5C, 0x01, 0x2C, 0x7F, 0xF6, 0x5E, 0xAF, 0x5C, 0x5C, -+0xDC, 0xB1, 0x5A, 0x5C, 0x01, 0x3A, 0x00, 0xFB, 0x02, 0xAA, 0x56, 0xE7, 0x14, 0x4A, 0x22, 0x49, 0x41, 0xF2, 0x13, 0x33, -+0x58, 0x46, 0xD3, 0x5C, 0x52, 0x46, 0x17, 0xF0, 0x03, 0xFA, 0x54, 0xE7, 0x12, 0x69, 0xE3, 0x68, 0x9A, 0x1A, 0x10, 0x1A, -+0x00, 0x28, 0xBA, 0xDA, 0x1B, 0x49, 0x1C, 0x48, 0x40, 0xF2, 0x4F, 0x22, 0x17, 0xF0, 0x20, 0xFC, 0xB2, 0xE7, 0x9A, 0x5C, -+0x3A, 0xE7, 0x00, 0xBF, 0x00, 0xE1, 0x00, 0xE0, 0x00, 0xED, 0x00, 0xE0, 0x3C, 0x36, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, -+0x40, 0x80, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x84, 0x00, 0x32, 0x40, 0x54, 0x8D, 0x15, 0x00, 0x00, 0x40, 0x1E, 0x00, -+0x70, 0x8D, 0x15, 0x00, 0x00, 0x10, 0x50, 0x40, 0x84, 0x40, 0x04, 0x40, 0x00, 0x41, 0x04, 0x40, 0x10, 0x00, 0x58, 0x40, -+0x40, 0x42, 0x04, 0x40, 0x18, 0x00, 0x58, 0x40, 0x78, 0x36, 0x17, 0x00, 0x00, 0x60, 0x50, 0x40, 0xD0, 0x9C, 0x17, 0x00, -+0x38, 0x36, 0x17, 0x00, 0xC8, 0x8D, 0x15, 0x00, 0x14, 0x00, 0x24, 0x40, 0x5C, 0x8D, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x80, 0x8D, 0x15, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x70, 0xB5, 0x45, 0x4C, 0x21, 0x68, 0x0B, 0x78, 0x73, 0xB9, 0x44, 0x4B, -+0x44, 0x4D, 0x9B, 0x68, 0x01, 0x22, 0x2A, 0x70, 0x00, 0x2B, 0x3E, 0xD1, 0x0A, 0x78, 0x42, 0x49, 0x01, 0x23, 0x02, 0x20, -+0x17, 0xF0, 0xAC, 0xF9, 0x01, 0x23, 0x2B, 0x70, 0x3F, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x40, 0xD0, 0x02, 0x2B, -+0x28, 0xD0, 0x11, 0xF0, 0x8F, 0xFD, 0x28, 0xB3, 0x3B, 0x4B, 0xD3, 0xF8, 0xF8, 0x31, 0x0B, 0xBB, 0x3A, 0x4B, 0x3B, 0x4D, -+0x1B, 0x68, 0x95, 0xF8, 0x24, 0x20, 0xC3, 0xF3, 0x40, 0x63, 0x13, 0x43, 0x18, 0xD0, 0x6B, 0x7F, 0xB3, 0xB9, 0x37, 0x4E, -+0xD6, 0xF8, 0xF4, 0x30, 0x98, 0x47, 0x88, 0xB1, 0xF8, 0xF7, 0x7E, 0xFB, 0x34, 0x4A, 0xC0, 0xB2, 0x10, 0x70, 0x00, 0x28, -+0x35, 0xD0, 0x23, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x04, 0xD8, 0xD6, 0xF8, 0xB4, 0x34, 0x98, 0x47, 0x23, 0x68, 0x1B, 0x78, -+0x02, 0x2B, 0x22, 0xD0, 0x70, 0xBD, 0x93, 0xF8, 0x64, 0x20, 0x42, 0xB9, 0x1B, 0x68, 0x00, 0x2B, 0xC0, 0xD0, 0x93, 0xF8, -+0x62, 0x20, 0x00, 0x2A, 0xF5, 0xD0, 0x02, 0x2A, 0xF6, 0xD1, 0x0A, 0x78, 0x1F, 0x49, 0x00, 0x23, 0x02, 0x20, 0x17, 0xF0, -+0x67, 0xF9, 0x00, 0x23, 0x2B, 0x70, 0x70, 0xBD, 0x23, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0x15, 0xD0, 0xFB, 0xF7, 0x5A, 0xFA, -+0x00, 0x28, 0xE1, 0xD0, 0x1E, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0xB4, 0xD0, 0x70, 0xBD, 0x28, 0x6A, 0xD6, 0xF8, 0xB8, 0x34, -+0xD0, 0xF8, 0xE4, 0x10, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, 0x19, 0x49, 0x02, 0x20, 0x17, 0xF0, 0x4B, 0xF9, 0xC4, 0xE7, -+0xF8, 0xF7, 0x3C, 0xFB, 0x13, 0x4B, 0x18, 0x70, 0xFB, 0xF7, 0x40, 0xFA, 0x18, 0xB1, 0x10, 0x4B, 0xD3, 0xF8, 0xB4, 0x34, -+0x98, 0x47, 0x12, 0x4A, 0x13, 0x68, 0x5B, 0x03, 0xFC, 0xD5, 0x11, 0x4A, 0x11, 0x69, 0x1C, 0x31, 0x13, 0x69, 0xCB, 0x1A, -+0x00, 0x2B, 0xFB, 0xDA, 0x70, 0xBD, 0x00, 0xBF, 0x74, 0x36, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x3C, 0x61, 0x17, 0x00, -+0xD8, 0x8D, 0x15, 0x00, 0x78, 0x36, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, 0x1C, 0x9E, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x3D, 0x61, 0x17, 0x00, 0x9C, 0x4E, 0x17, 0x00, 0xD4, 0x8D, 0x15, 0x00, 0x20, 0x10, 0x04, 0x40, -+0x00, 0x10, 0x50, 0x40, 0x38, 0xB5, 0x43, 0x4D, 0x6B, 0x78, 0x03, 0xB9, 0x38, 0xBD, 0x42, 0x48, 0x42, 0x49, 0x03, 0x68, -+0x42, 0x4A, 0x23, 0xF0, 0x10, 0x03, 0x03, 0x60, 0x4B, 0x6F, 0x43, 0xF0, 0x10, 0x03, 0x4B, 0x67, 0x13, 0x68, 0x23, 0xF0, -+0x00, 0x73, 0x13, 0x60, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xBF, 0x3C, 0x4C, 0x3C, 0x49, 0x23, 0x68, 0x43, 0xF0, 0x00, 0x43, -+0x23, 0x60, 0x02, 0x20, 0x17, 0xF0, 0xF6, 0xF8, 0x00, 0x23, 0x22, 0x46, 0x6B, 0x70, 0x13, 0x68, 0x5B, 0x00, 0xFC, 0xD5, -+0x36, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x3C, 0xDB, 0x31, 0x4B, 0x34, 0x4A, 0x19, 0x68, 0x21, 0xF0, -+0x80, 0x41, 0x19, 0x60, 0x19, 0x68, 0x21, 0xF0, 0x00, 0x41, 0x19, 0x60, 0x13, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x2F, 0x4B, -+0x2F, 0x48, 0x19, 0x68, 0x2F, 0x4C, 0x41, 0xF0, 0x01, 0x01, 0x19, 0x60, 0x19, 0x68, 0x01, 0x25, 0x21, 0xF0, 0x02, 0x01, -+0x19, 0x60, 0x15, 0x60, 0x03, 0x68, 0x43, 0xF4, 0x00, 0x13, 0x03, 0x60, 0x23, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0x2E, 0xD0, -+0x01, 0x2B, 0x26, 0xD0, 0x26, 0x4B, 0x1B, 0x78, 0x53, 0xB1, 0x1D, 0x4A, 0x25, 0x49, 0x13, 0x68, 0x43, 0xF0, 0x00, 0x73, -+0x13, 0x60, 0x02, 0x20, 0xBD, 0xE8, 0x38, 0x40, 0x17, 0xF0, 0xB8, 0xB8, 0x16, 0x4A, 0x20, 0x49, 0x53, 0x6F, 0x23, 0xF0, -+0x10, 0x03, 0x53, 0x67, 0x02, 0x20, 0xBD, 0xE8, 0x38, 0x40, 0x17, 0xF0, 0xAD, 0xB8, 0x1C, 0x4B, 0x2A, 0x78, 0x1B, 0x68, -+0x03, 0xF0, 0x0F, 0x03, 0x9A, 0x42, 0xBB, 0xD0, 0x19, 0x49, 0x1A, 0x48, 0x4F, 0xF4, 0x3A, 0x72, 0x17, 0xF0, 0xCA, 0xFA, -+0xB4, 0xE7, 0x18, 0x4A, 0x13, 0x68, 0x23, 0xF4, 0x00, 0x43, 0x13, 0x60, 0xD2, 0xE7, 0x16, 0x4A, 0x13, 0x68, 0x23, 0xF0, -+0x01, 0x03, 0x13, 0x60, 0x0D, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0xCC, 0xD1, 0xD6, 0xE7, 0x00, 0xBF, 0x70, 0x28, 0x17, 0x00, -+0x10, 0x00, 0x58, 0x40, 0x00, 0x00, 0x50, 0x40, 0xE0, 0x50, 0x34, 0x40, 0x48, 0x80, 0x32, 0x40, 0xEC, 0x8D, 0x15, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x40, 0x42, 0x04, 0x40, 0x18, 0x00, 0x58, 0x40, 0x58, 0x40, 0x34, 0x40, 0x78, 0x36, 0x17, 0x00, -+0x4C, 0x36, 0x17, 0x00, 0x28, 0x8E, 0x15, 0x00, 0x38, 0x00, 0x32, 0x40, 0x70, 0x79, 0x15, 0x00, 0xF0, 0x8D, 0x15, 0x00, -+0x14, 0x00, 0x24, 0x40, 0x84, 0x40, 0x04, 0x40, 0x2D, 0xE9, 0xF0, 0x47, 0x1F, 0x48, 0x20, 0x4D, 0x15, 0xF0, 0x36, 0xFE, -+0x1F, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x28, 0xDB, 0x1D, 0x4E, 0x28, 0x68, 0xDF, 0xF8, 0x7C, 0x90, -+0xDF, 0xF8, 0x60, 0x80, 0xD9, 0xF8, 0x00, 0x30, 0x1A, 0x89, 0x54, 0x24, 0x02, 0xFB, 0x04, 0x42, 0x00, 0x21, 0xF2, 0xF7, -+0x91, 0xFD, 0x4F, 0xF0, 0x00, 0x0A, 0x58, 0x27, 0x29, 0x68, 0x33, 0x68, 0x1F, 0xFA, 0x8A, 0xF2, 0x04, 0xFB, 0x02, 0x11, -+0x07, 0xFB, 0x02, 0x33, 0xCB, 0x64, 0x40, 0x46, 0x15, 0xF0, 0x16, 0xFE, 0xD9, 0xF8, 0x00, 0x30, 0x0A, 0xF1, 0x01, 0x0A, -+0x1A, 0x89, 0x1F, 0xFA, 0x8A, 0xF3, 0x9A, 0x42, 0xEA, 0xD2, 0xBD, 0xE8, 0xF0, 0x87, 0x28, 0x68, 0x08, 0x4E, 0x10, 0xB1, -+0x33, 0x68, 0x00, 0x2B, 0xD2, 0xD1, 0x07, 0x48, 0x07, 0x49, 0x5B, 0x22, 0x17, 0xF0, 0x54, 0xFA, 0x28, 0x68, 0xCB, 0xE7, -+0x20, 0x58, 0x17, 0x00, 0x40, 0x61, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x14, 0x63, 0x18, 0x00, 0x40, 0x8E, 0x15, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x78, 0x36, 0x17, 0x00, 0x0D, 0x49, 0x00, 0xEB, 0xC0, 0x03, 0x10, 0xB4, 0x9C, 0x00, 0x00, 0x22, -+0x01, 0xEB, 0x83, 0x03, 0x16, 0x30, 0x0A, 0x51, 0x01, 0xEB, 0xC0, 0x00, 0x4F, 0xF4, 0x55, 0x64, 0x4F, 0xF0, 0xFF, 0x31, -+0xC3, 0xE9, 0x02, 0x41, 0xC0, 0xE9, 0x01, 0x22, 0x5D, 0xF8, 0x04, 0x4B, 0x5A, 0x60, 0x83, 0xF8, 0x20, 0x20, 0x5A, 0x61, -+0x19, 0x61, 0x70, 0x47, 0x44, 0x61, 0x17, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x80, 0x6C, 0x18, 0xB1, 0xF9, 0xF7, 0xCE, 0xFE, -+0x00, 0x23, 0xA3, 0x64, 0x10, 0xBD, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x41, 0x38, 0x4C, 0xDF, 0xF8, 0xF0, 0x80, 0x38, 0x4F, -+0x38, 0x4D, 0x04, 0xF5, 0x20, 0x76, 0xC4, 0xF8, 0x00, 0x80, 0xF3, 0xF7, 0x0F, 0xFE, 0x80, 0x03, 0x60, 0x60, 0xF3, 0xF7, -+0x0B, 0xFE, 0x01, 0x23, 0x01, 0x30, 0x03, 0xFA, 0x00, 0xF0, 0x01, 0x38, 0x00, 0x23, 0xC4, 0xE9, 0x02, 0x03, 0xC4, 0xE9, -+0x05, 0x33, 0xC4, 0xE9, 0x07, 0x33, 0x27, 0x61, 0x2B, 0x68, 0x2A, 0x68, 0x1B, 0x02, 0xD2, 0xB2, 0x9B, 0xB2, 0x13, 0x43, -+0x63, 0x62, 0x2B, 0x68, 0x2A, 0x68, 0x1B, 0x02, 0xD2, 0xB2, 0x9B, 0xB2, 0x13, 0x43, 0xA3, 0x62, 0x2B, 0x68, 0x2A, 0x68, -+0x1B, 0x02, 0xD2, 0xB2, 0x9B, 0xB2, 0x13, 0x43, 0xE3, 0x62, 0x2B, 0x68, 0x2A, 0x68, 0x1B, 0x02, 0xD2, 0xB2, 0x9B, 0xB2, -+0x13, 0x43, 0x4F, 0xF4, 0x08, 0x51, 0x4F, 0xF4, 0x7C, 0x12, 0xA2, 0x63, 0xC4, 0xE9, 0x0C, 0x31, 0x40, 0x34, 0xB4, 0x42, -+0xC5, 0xD1, 0x1B, 0x4C, 0x1B, 0x4F, 0x18, 0x4E, 0xDF, 0xF8, 0x60, 0x80, 0x04, 0xF5, 0x80, 0x75, 0x27, 0x60, 0xF3, 0xF7, -+0xCF, 0xFD, 0x80, 0x03, 0x60, 0x60, 0xF3, 0xF7, 0xCB, 0xFD, 0x01, 0x23, 0x01, 0x30, 0x03, 0xFA, 0x00, 0xF0, 0x01, 0x38, -+0x00, 0x23, 0xC4, 0xE9, 0x02, 0x03, 0xC4, 0xE9, 0x05, 0x33, 0xC4, 0xE9, 0x07, 0x33, 0x26, 0x61, 0xD8, 0xF8, 0x00, 0x20, -+0xD8, 0xF8, 0x00, 0x10, 0xA3, 0x62, 0x12, 0x02, 0xC9, 0xB2, 0x92, 0xB2, 0x0A, 0x43, 0x4F, 0xF4, 0x7C, 0x11, 0x62, 0x62, -+0xC4, 0xE9, 0x0B, 0x33, 0xC4, 0xE9, 0x0D, 0x31, 0x40, 0x34, 0xAC, 0x42, 0xD8, 0xD1, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0xBF, -+0x04, 0x39, 0x18, 0x00, 0x04, 0x07, 0xFF, 0xFF, 0xA0, 0x00, 0x32, 0x40, 0x04, 0x38, 0x18, 0x00, 0x1E, 0xAB, 0xDC, 0xBA, -+0xF0, 0xB5, 0x16, 0x4C, 0x24, 0x68, 0x24, 0x78, 0x1D, 0x46, 0xE3, 0x07, 0x87, 0xB0, 0x16, 0x46, 0x06, 0xD5, 0x50, 0x19, -+0x00, 0x21, 0x08, 0x22, 0xF2, 0xF7, 0xA8, 0xFC, 0x07, 0xB0, 0xF0, 0xBD, 0xC3, 0x7E, 0x00, 0x93, 0x02, 0xAC, 0x07, 0x46, -+0x07, 0xF1, 0x12, 0x03, 0x20, 0x46, 0x07, 0xF1, 0x0C, 0x02, 0x1A, 0xF0, 0xE7, 0xFF, 0x2A, 0x46, 0x31, 0x46, 0x20, 0x46, -+0x1B, 0xF0, 0x08, 0xF8, 0x20, 0x46, 0x1B, 0xF0, 0xA3, 0xF8, 0x35, 0x44, 0x21, 0x46, 0x04, 0xAA, 0x60, 0x1A, 0x14, 0xF8, -+0x01, 0x3B, 0x43, 0x55, 0x94, 0x42, 0xF9, 0xD1, 0x07, 0xB0, 0xF0, 0xBD, 0x34, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x83, 0x6C, 0x90, 0xF8, 0x42, 0xA0, 0x90, 0xF8, 0x33, 0x40, 0x90, 0xF8, 0x35, 0x20, 0x87, 0x88, 0x90, 0xF8, 0x32, 0x80, -+0xD3, 0xF8, 0x24, 0xC0, 0xC6, 0x6C, 0x93, 0xF8, 0x20, 0xE0, 0xA3, 0xEB, 0x0A, 0x05, 0xA8, 0x35, 0x22, 0x44, 0x01, 0x3F, -+0xAA, 0xEB, 0x04, 0x04, 0x3A, 0x44, 0x08, 0xEB, 0x05, 0x09, 0x2C, 0xF0, 0x02, 0x07, 0x04, 0xEB, 0x09, 0x0B, 0x5F, 0x62, -+0x54, 0x19, 0x03, 0xF1, 0x0C, 0x0A, 0xB8, 0xF1, 0x00, 0x0F, 0x03, 0xD0, 0x09, 0xF1, 0xFF, 0x32, 0xC6, 0xE9, 0x09, 0x52, -+0xF2, 0x6C, 0xC3, 0xF8, 0x14, 0xB0, 0x00, 0x25, 0x42, 0xF4, 0x80, 0x72, 0x1C, 0xF0, 0x01, 0x0F, 0x9C, 0x61, 0x1D, 0x61, -+0xC6, 0xF8, 0x20, 0xA0, 0xDD, 0x61, 0xF2, 0x64, 0x16, 0xD1, 0x40, 0x6A, 0x00, 0xF4, 0x60, 0x14, 0xB4, 0xF5, 0x60, 0x1F, -+0x01, 0xD0, 0x80, 0x02, 0x0E, 0xD4, 0x09, 0x48, 0x71, 0x44, 0x01, 0xEB, 0xC1, 0x01, 0x00, 0xEB, 0x81, 0x01, 0x47, 0xF0, -+0x01, 0x07, 0x91, 0xF8, 0x20, 0x00, 0x5F, 0x62, 0x01, 0x30, 0x81, 0xF8, 0x20, 0x00, 0xF2, 0x64, 0x00, 0x22, 0x1A, 0x61, -+0xBD, 0xE8, 0xF0, 0x8F, 0x44, 0x61, 0x17, 0x00, 0x0A, 0x88, 0x03, 0x7F, 0x0A, 0x49, 0x12, 0xF4, 0x00, 0x5F, 0x4F, 0xF4, -+0xA4, 0x62, 0x02, 0xFB, 0x03, 0x12, 0x4F, 0xF4, 0xA4, 0x60, 0x92, 0xF8, 0xDA, 0x20, 0x00, 0xFB, 0x03, 0x13, 0x14, 0xBF, -+0x42, 0xF0, 0x02, 0x02, 0x02, 0xF0, 0xFD, 0x02, 0x83, 0xF8, 0xDA, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, -+0x43, 0x6A, 0x2D, 0xE9, 0xF0, 0x47, 0x91, 0x46, 0x9A, 0x02, 0xD0, 0xF8, 0x48, 0x80, 0x06, 0x46, 0x0F, 0x46, 0x29, 0xD5, -+0x03, 0xF4, 0x60, 0x13, 0xB3, 0xF5, 0x20, 0x1F, 0x24, 0xD0, 0x50, 0x4C, 0x88, 0xF8, 0x20, 0x90, 0xD4, 0xF8, 0x80, 0x33, -+0x39, 0x46, 0x30, 0x46, 0x98, 0x47, 0x31, 0x8B, 0x48, 0xF6, 0x88, 0x63, 0x99, 0x42, 0x68, 0xD0, 0x4A, 0x4B, 0xB1, 0x6C, -+0x93, 0xF8, 0x05, 0x31, 0x00, 0x2B, 0x59, 0xD1, 0xB3, 0x68, 0x00, 0x2B, 0x49, 0xDB, 0x4B, 0x6A, 0x46, 0x4A, 0xCA, 0x60, -+0x23, 0xF0, 0x10, 0x03, 0x4B, 0x62, 0x30, 0x46, 0xD4, 0xF8, 0x04, 0x34, 0x8E, 0x60, 0x3A, 0x46, 0x98, 0x47, 0x00, 0x20, -+0xBD, 0xE8, 0xF0, 0x87, 0xD6, 0xF8, 0x2C, 0xA0, 0x08, 0xF1, 0x24, 0x04, 0x0A, 0xF1, 0x40, 0x00, 0x53, 0x46, 0x53, 0xF8, -+0x04, 0x5B, 0x44, 0xF8, 0x04, 0x5F, 0x83, 0x42, 0xF9, 0xD1, 0xF3, 0x8B, 0x9D, 0x04, 0xCA, 0xD5, 0x38, 0x4B, 0x39, 0x49, -+0x1A, 0x68, 0x73, 0x7F, 0xB2, 0xF9, 0x00, 0x20, 0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, 0x03, 0x13, 0x00, 0x2A, 0xD3, 0xF8, -+0x4C, 0x41, 0x38, 0xDB, 0x41, 0x46, 0xDA, 0xF8, 0x14, 0x20, 0xD4, 0xF8, 0x9C, 0x30, 0xC8, 0xF8, 0x40, 0x20, 0xDA, 0xF8, -+0x24, 0x20, 0xC8, 0xF8, 0x50, 0x20, 0xC3, 0xF3, 0xC2, 0x22, 0x05, 0x2A, 0xC8, 0xF8, 0x3C, 0x30, 0x31, 0xD0, 0xDA, 0xF8, -+0x3C, 0x30, 0x5C, 0x07, 0x5E, 0xBF, 0xD8, 0xF8, 0x2C, 0x30, 0x23, 0xF4, 0xC0, 0x73, 0xC8, 0xF8, 0x2C, 0x30, 0x88, 0x46, -+0x9F, 0xE7, 0x32, 0x8B, 0x33, 0x65, 0x48, 0xF6, 0x88, 0x63, 0x9A, 0x42, 0xAF, 0xD1, 0x8B, 0x6B, 0x23, 0xF4, 0x7F, 0x43, -+0x43, 0xF4, 0x60, 0x63, 0x8B, 0x63, 0xA8, 0xE7, 0xF2, 0x8B, 0x10, 0x07, 0xA5, 0xD4, 0xB2, 0x68, 0x52, 0x00, 0x58, 0xBF, -+0x81, 0xF8, 0x39, 0x30, 0x9F, 0xE7, 0xF3, 0x6C, 0x19, 0x48, 0xDA, 0x6A, 0x16, 0xF0, 0xFA, 0xFD, 0x90, 0xE7, 0x00, 0x2C, -+0xC4, 0xD1, 0x17, 0x49, 0x17, 0x48, 0x40, 0xF2, 0x4B, 0x12, 0x17, 0xF0, 0x6B, 0xF8, 0xB1, 0x6C, 0xBD, 0xE7, 0x03, 0xF4, -+0xC0, 0x63, 0xD8, 0xF8, 0x4C, 0x20, 0x94, 0xF8, 0xA1, 0x00, 0xB3, 0xF5, 0x80, 0x6F, 0x14, 0xBF, 0x4F, 0xF4, 0x80, 0x34, -+0x4F, 0xF4, 0x00, 0x34, 0x22, 0xF4, 0x40, 0x33, 0x23, 0x43, 0x20, 0xB1, 0x43, 0xF4, 0x80, 0x23, 0xC8, 0xF8, 0x4C, 0x30, -+0xB7, 0xE7, 0x23, 0xF4, 0x80, 0x23, 0xC8, 0xF8, 0x4C, 0x30, 0xB2, 0xE7, 0x88, 0x1A, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, -+0xDE, 0xFA, 0xFE, 0xCA, 0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x78, 0x8E, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x68, 0x8E, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x43, 0x6A, 0x85, 0x6C, 0x13, 0xF4, 0x00, 0x18, 0x83, 0xB0, 0x04, 0x46, -+0x05, 0xF1, 0x28, 0x07, 0x08, 0xD0, 0x03, 0xF4, 0x60, 0x13, 0xB3, 0xF5, 0x20, 0x1F, 0x00, 0xF0, 0x93, 0x80, 0x03, 0xB0, -+0xBD, 0xE8, 0xF0, 0x83, 0xC3, 0x8B, 0xC6, 0x6C, 0x1A, 0x07, 0x38, 0xD5, 0xDF, 0xF8, 0x58, 0x92, 0xD9, 0xF8, 0x00, 0x20, -+0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xC0, 0xF2, 0xCF, 0x80, 0x71, 0x6A, 0x09, 0xB9, 0x32, 0x6A, 0x91, 0x68, 0x18, 0x06, -+0x09, 0xD5, 0x94, 0xF8, 0x33, 0x30, 0x00, 0x2B, 0x40, 0xF0, 0xDD, 0x80, 0x94, 0xF8, 0x35, 0x30, 0x00, 0x2B, 0x40, 0xF0, -+0xDF, 0x80, 0xF3, 0x6C, 0x23, 0xF4, 0xF0, 0x03, 0xF3, 0x64, 0x0B, 0x79, 0xB7, 0x63, 0x13, 0xF0, 0x01, 0x0F, 0x08, 0xBF, -+0x4F, 0xF4, 0x00, 0x78, 0x00, 0x23, 0xC6, 0xF8, 0x48, 0x80, 0x33, 0x65, 0xEB, 0x6A, 0x2A, 0x6E, 0x72, 0x63, 0x43, 0xF0, -+0x02, 0x03, 0xEB, 0x62, 0x20, 0x46, 0x06, 0xF0, 0xBB, 0xF8, 0xA2, 0x6C, 0x53, 0x6A, 0x43, 0xF0, 0x10, 0x03, 0x53, 0x62, -+0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x74, 0x4B, 0xD3, 0xF8, 0x28, 0x34, 0x98, 0x47, 0xEB, 0x6D, 0xB3, 0x64, 0x22, 0x7F, -+0x71, 0x49, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x02, 0x12, 0x92, 0xF8, 0x62, 0x20, 0x5A, 0xBB, 0x6E, 0x49, 0x62, 0x7F, -+0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, 0x02, 0x12, 0x52, 0x68, 0x91, 0x06, 0x22, 0xD5, 0xE2, 0x8B, 0x12, 0xF4, 0x00, 0x5F, -+0xE2, 0x6A, 0xD2, 0x6B, 0x14, 0xBF, 0xC2, 0xF3, 0x00, 0x12, 0xC2, 0xF3, 0xC0, 0x02, 0xBA, 0xB9, 0x70, 0x6A, 0x02, 0x88, -+0x91, 0xB2, 0x12, 0x04, 0x12, 0xD5, 0xC1, 0xF3, 0x0E, 0x01, 0x01, 0x80, 0x94, 0xF8, 0x33, 0x10, 0x94, 0xF8, 0x32, 0x20, -+0x04, 0x39, 0x04, 0x3A, 0x84, 0xF8, 0x33, 0x10, 0x84, 0xF8, 0x32, 0x20, 0xD6, 0xE9, 0x0A, 0x21, 0x04, 0x39, 0x04, 0x3A, -+0xC6, 0xE9, 0x0A, 0x21, 0xDF, 0xF8, 0x70, 0x81, 0xB7, 0x63, 0xD8, 0xF8, 0x00, 0x20, 0xE7, 0x6C, 0xB2, 0xF9, 0x00, 0x20, -+0x00, 0x2A, 0x4F, 0xDB, 0x7A, 0x6A, 0x0A, 0xB9, 0x3A, 0x6A, 0x92, 0x68, 0x23, 0xF4, 0xC0, 0x63, 0xB3, 0x64, 0x12, 0x79, -+0xD2, 0x07, 0x5C, 0xBF, 0x43, 0xF4, 0x00, 0x73, 0xB3, 0x64, 0x9B, 0xE7, 0x83, 0x6A, 0x46, 0x6C, 0xC3, 0xF3, 0xC2, 0x22, -+0x05, 0x2A, 0x37, 0x63, 0x15, 0xD1, 0x03, 0xF4, 0xC0, 0x63, 0xEA, 0x6C, 0x90, 0xF8, 0x36, 0x10, 0xB3, 0xF5, 0x80, 0x6F, -+0x14, 0xBF, 0x4F, 0xF4, 0x80, 0x33, 0x4F, 0xF4, 0x00, 0x33, 0x22, 0xF4, 0x40, 0x32, 0x1A, 0x43, 0x89, 0x06, 0x4C, 0xBF, -+0x42, 0xF4, 0x80, 0x22, 0x22, 0xF4, 0x80, 0x22, 0xEA, 0x64, 0x04, 0xF1, 0x28, 0x00, 0x04, 0xF0, 0xDD, 0xF9, 0xD4, 0xF8, -+0x48, 0xC0, 0xA2, 0x6A, 0xB0, 0x88, 0xDC, 0xF8, 0x24, 0x30, 0xE9, 0x6D, 0xEA, 0x63, 0xEA, 0x6A, 0x40, 0xF0, 0x08, 0x04, -+0xB4, 0x80, 0x41, 0xF4, 0xC0, 0x60, 0x2C, 0x6E, 0xF4, 0x62, 0x42, 0xF0, 0x02, 0x02, 0x30, 0x64, 0x43, 0xF0, 0x10, 0x03, -+0xEA, 0x62, 0x39, 0x46, 0x06, 0xF5, 0x82, 0x70, 0x34, 0x22, 0xCC, 0xF8, 0x24, 0x30, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x43, -+0x29, 0xF0, 0xFE, 0xB9, 0xA2, 0x6C, 0x00, 0x2A, 0x3C, 0xD0, 0x7A, 0x6A, 0x00, 0x2A, 0xAD, 0xD1, 0x3A, 0x6A, 0x92, 0xB1, -+0xB3, 0x6C, 0xA8, 0xE7, 0x2D, 0xB3, 0x71, 0x6A, 0x00, 0x29, 0x7F, 0xF4, 0x30, 0xAF, 0x32, 0x6A, 0x0A, 0xB1, 0xE3, 0x8B, -+0x2A, 0xE7, 0x23, 0x49, 0x23, 0x48, 0x40, 0xF2, 0xB9, 0x12, 0x16, 0xF0, 0x3F, 0xFF, 0x32, 0x6A, 0xF5, 0xE7, 0x1F, 0x49, -+0x1F, 0x48, 0x40, 0xF2, 0xB9, 0x12, 0x16, 0xF0, 0x37, 0xFF, 0x3A, 0x6A, 0xE4, 0xE7, 0x20, 0x22, 0x20, 0x46, 0x01, 0x91, -+0x22, 0xF0, 0xD8, 0xF8, 0x01, 0x99, 0x20, 0xE7, 0xA2, 0x88, 0x01, 0x91, 0x20, 0x46, 0x23, 0xF0, 0x87, 0xFA, 0x01, 0x99, -+0x19, 0xE7, 0x14, 0x49, 0x15, 0x48, 0x4F, 0xF4, 0xD9, 0x72, 0x16, 0xF0, 0x21, 0xFF, 0x71, 0x6A, 0xA9, 0xB9, 0xD9, 0xF8, -+0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xCF, 0xDB, 0xD8, 0xE7, 0x4F, 0xF4, 0xD9, 0x72, 0x0B, 0x49, 0x0D, 0x48, -+0x16, 0xF0, 0x12, 0xFF, 0x7A, 0x6A, 0x42, 0xB9, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xB7, 0xDB, -+0xD1, 0xE7, 0xE3, 0x8B, 0xED, 0xE6, 0xB3, 0x6C, 0x60, 0xE7, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x68, 0x65, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xAC, 0x8E, 0x15, 0x00, 0x8C, 0x8E, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x05, 0x28, 0x1C, 0xD8, 0xDF, 0xE8, 0x00, 0xF0, 0x07, 0x0B, 0x0F, 0x13, 0x17, 0x03, 0x12, 0x4B, 0x20, 0x22, 0x1A, 0x60, -+0x70, 0x47, 0x10, 0x4B, 0x02, 0x22, 0x1A, 0x60, 0x70, 0x47, 0x0E, 0x4B, 0x04, 0x22, 0x1A, 0x60, 0x70, 0x47, 0x0C, 0x4B, -+0x08, 0x22, 0x1A, 0x60, 0x70, 0x47, 0x0A, 0x4B, 0x10, 0x22, 0x1A, 0x60, 0x70, 0x47, 0x08, 0x4B, 0x01, 0x22, 0x1A, 0x60, -+0x70, 0x47, 0x07, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x00, 0xDB, 0x70, 0x47, 0x04, 0x49, 0x05, 0x48, -+0x4F, 0xF4, 0x77, 0x72, 0x16, 0xF0, 0xCA, 0xBE, 0x80, 0x81, 0x32, 0x40, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x64, 0x7D, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x05, 0x28, 0x85, 0xB0, 0x06, 0x46, 0x00, 0xF0, 0xE5, 0x81, 0xAE, 0x4C, -+0x00, 0xEB, 0x40, 0x03, 0xC3, 0xEB, 0xC3, 0x03, 0x04, 0xEB, 0x83, 0x04, 0xAB, 0x4B, 0xAC, 0x4F, 0xDF, 0xF8, 0xD4, 0x92, -+0x01, 0x22, 0x19, 0x46, 0xB2, 0x40, 0x71, 0x18, 0x00, 0x92, 0xA3, 0x7E, 0x02, 0x91, 0xD2, 0x43, 0x4F, 0xEA, 0x81, 0x08, -+0x01, 0x92, 0x00, 0x2B, 0x3A, 0xD0, 0x3B, 0x68, 0x65, 0x6A, 0x5B, 0x78, 0xD5, 0xF8, 0x8C, 0x20, 0x00, 0x2B, 0x00, 0xF0, -+0x8B, 0x80, 0x69, 0x6D, 0x00, 0x29, 0x00, 0xF0, 0x11, 0x81, 0x00, 0x2A, 0x80, 0xF2, 0x29, 0x81, 0x9D, 0x49, 0xD9, 0xF8, -+0x00, 0x30, 0x51, 0xF8, 0x26, 0x10, 0x0B, 0x44, 0x11, 0x02, 0xC8, 0xF8, 0x00, 0x30, 0x40, 0xF1, 0xA2, 0x80, 0xAB, 0x88, -+0x99, 0x06, 0x40, 0xF1, 0x43, 0x81, 0x97, 0x4A, 0x43, 0xF0, 0x10, 0x03, 0x52, 0xF8, 0x26, 0x00, 0xAB, 0x80, 0x15, 0xF0, -+0x87, 0xF9, 0x94, 0xF8, 0x50, 0x30, 0x3A, 0x68, 0x01, 0x3B, 0x84, 0xF8, 0x50, 0x30, 0x00, 0x23, 0xA3, 0x76, 0x63, 0x62, -+0x53, 0x78, 0x00, 0x2B, 0x00, 0xF0, 0x8F, 0x80, 0x6B, 0x6D, 0x00, 0x2B, 0x00, 0xF0, 0x8F, 0x80, 0xA5, 0x62, 0xEB, 0x7A, -+0x01, 0x33, 0xEB, 0x72, 0xE5, 0x68, 0x00, 0x2D, 0x00, 0xF0, 0x90, 0x81, 0xD5, 0xF8, 0x4C, 0xB0, 0xDB, 0xF8, 0x50, 0xA0, -+0xBA, 0xF1, 0x00, 0x0F, 0x80, 0xF2, 0xA9, 0x81, 0x30, 0x46, 0xCB, 0xF8, 0x10, 0xA0, 0x04, 0xF0, 0x03, 0xF9, 0x6A, 0x6A, -+0x12, 0xF4, 0x00, 0x10, 0x11, 0xD1, 0xDB, 0xF8, 0x18, 0x10, 0x00, 0x29, 0x00, 0xF0, 0x97, 0x80, 0x8B, 0x6B, 0x03, 0xF4, -+0x60, 0x13, 0xB3, 0xF5, 0x00, 0x1F, 0x8C, 0x46, 0x00, 0xF0, 0x29, 0x81, 0xDC, 0xF8, 0x3C, 0x30, 0x00, 0x2B, 0x80, 0xF2, -+0x9D, 0x81, 0x1A, 0xF4, 0x00, 0x0F, 0x0B, 0xD0, 0x6B, 0x7F, 0x0D, 0x2B, 0x08, 0xD8, 0x73, 0x48, 0x73, 0x49, 0x4F, 0xF4, -+0x1E, 0x7C, 0x0C, 0xFB, 0x03, 0x03, 0x09, 0x69, 0xC3, 0xF8, 0x58, 0x12, 0x02, 0xF4, 0x60, 0x12, 0xB2, 0xF5, 0x60, 0x1F, -+0x00, 0xF0, 0x9E, 0x80, 0x04, 0xF1, 0x0C, 0x00, 0x15, 0xF0, 0x18, 0xFA, 0x6B, 0x6A, 0x9B, 0x02, 0x04, 0xD4, 0x94, 0xF8, -+0x50, 0x30, 0x01, 0x3B, 0x84, 0xF8, 0x50, 0x30, 0xAB, 0x88, 0x00, 0x2B, 0x5F, 0xD1, 0x28, 0x46, 0x02, 0xF0, 0x4C, 0xF8, -+0x60, 0x4A, 0xD9, 0xF8, 0x00, 0x30, 0x52, 0xF8, 0x26, 0x20, 0x13, 0x44, 0xC8, 0xF8, 0x00, 0x30, 0xA3, 0x7E, 0x6A, 0xE7, -+0x29, 0x69, 0x00, 0x29, 0x00, 0xF0, 0xA4, 0x80, 0xAB, 0x6C, 0x00, 0x2B, 0x80, 0xF2, 0x9D, 0x80, 0x57, 0x4B, 0xD9, 0xF8, -+0x00, 0x20, 0x53, 0xF8, 0x26, 0x10, 0xAB, 0x88, 0x0A, 0x44, 0xC8, 0xF8, 0x00, 0x20, 0x9A, 0x06, 0x3F, 0xF5, 0x77, 0xAF, -+0xDF, 0xF8, 0x6C, 0xB1, 0xDB, 0xF8, 0x9C, 0x32, 0x98, 0x47, 0x4F, 0xF0, 0x04, 0x0A, 0xAB, 0x88, 0x99, 0x06, 0x3F, 0xF5, -+0x6C, 0xAF, 0xDB, 0xF8, 0x9C, 0x32, 0x98, 0x47, 0xBA, 0xF1, 0x01, 0x0A, 0xF5, 0xD1, 0xAB, 0x88, 0x9A, 0x06, 0x3F, 0xF5, -+0x62, 0xAF, 0x04, 0xF1, 0x1C, 0x00, 0x15, 0xF0, 0xD3, 0xF9, 0xAB, 0x88, 0x5B, 0xE7, 0x2B, 0x69, 0x00, 0x2B, 0x7F, 0xF4, -+0x71, 0xAF, 0x46, 0x4B, 0x1B, 0x68, 0xEF, 0xF3, 0x10, 0x82, 0xD0, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x43, 0x4A, 0x01, 0x21, -+0x11, 0x60, 0x43, 0x4A, 0x01, 0x99, 0x10, 0x68, 0x3F, 0x4D, 0x0B, 0x40, 0x41, 0x1C, 0x11, 0x60, 0x2B, 0x60, 0x29, 0xB1, -+0x3D, 0x4B, 0x10, 0x60, 0x1B, 0x68, 0x08, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x3C, 0x4B, 0x00, 0x9A, 0x1A, 0x60, 0x00, 0x22, -+0xA3, 0x7E, 0x22, 0x60, 0x17, 0xE7, 0x51, 0x46, 0x28, 0x46, 0x32, 0x46, 0x01, 0xF0, 0xC6, 0xF9, 0x9C, 0xE7, 0x33, 0x4B, -+0x1B, 0x68, 0xEF, 0xF3, 0x10, 0x82, 0xD2, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x30, 0x4A, 0x01, 0x21, 0x11, 0x60, 0xDF, 0xF8, -+0xC0, 0xC0, 0x01, 0x99, 0xDC, 0xF8, 0x00, 0x00, 0x2B, 0x4A, 0x0B, 0x40, 0x41, 0x1C, 0xCC, 0xF8, 0x00, 0x10, 0x13, 0x60, -+0x39, 0xB1, 0x29, 0x4B, 0xCC, 0xF8, 0x00, 0x00, 0x1B, 0x68, 0x10, 0xB9, 0x00, 0x2B, 0x40, 0xF0, 0xA2, 0x80, 0x27, 0x4B, -+0x00, 0x9A, 0x1A, 0x60, 0x94, 0xF8, 0x50, 0x30, 0x00, 0x22, 0x01, 0x2B, 0x22, 0x60, 0x7C, 0xD0, 0x6A, 0x6A, 0x4C, 0xE7, -+0x6B, 0x6C, 0x63, 0x62, 0x01, 0x23, 0x40, 0x20, 0xA3, 0x76, 0x15, 0xF0, 0x91, 0xF8, 0x59, 0xE7, 0x94, 0xF8, 0x50, 0x10, -+0x01, 0x29, 0x7F, 0xF4, 0xEA, 0xAE, 0xE1, 0x6A, 0x00, 0x29, 0x3F, 0xF4, 0xE6, 0xAE, 0x21, 0x6B, 0x19, 0x48, 0x09, 0x7F, -+0x4F, 0xF0, 0xA4, 0x0C, 0x0C, 0xFB, 0x01, 0x61, 0x99, 0x31, 0x50, 0xF8, 0x31, 0x10, 0x00, 0x29, 0x7B, 0xD0, 0x00, 0x2B, -+0x3F, 0xF4, 0x62, 0xAF, 0x00, 0x2A, 0xFF, 0xF6, 0xD7, 0xAE, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x94, 0xF8, 0x50, 0x10, -+0x01, 0x29, 0x7F, 0xF4, 0x57, 0xAF, 0xE1, 0x6A, 0x00, 0x29, 0xE2, 0xD1, 0x52, 0xE7, 0x00, 0xBF, 0x20, 0x62, 0x17, 0x00, -+0x4A, 0x80, 0x0C, 0x10, 0x34, 0x36, 0x17, 0x00, 0xB0, 0x35, 0x17, 0x00, 0xC4, 0x90, 0x15, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x00, 0x10, 0x50, 0x40, 0x8C, 0x80, 0x32, 0x40, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x88, 0x80, 0x32, 0x40, -+0x18, 0x88, 0x17, 0x00, 0x20, 0x01, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0xDF, 0xF8, 0x68, 0xB1, 0xDB, 0xF8, 0x9C, 0x32, -+0x98, 0x47, 0x4F, 0xF0, 0x04, 0x0A, 0xAB, 0x88, 0x9A, 0x06, 0x3F, 0xF5, 0xB2, 0xAE, 0xDB, 0xF8, 0x9C, 0x32, 0x98, 0x47, -+0xBA, 0xF1, 0x01, 0x0A, 0xF5, 0xD1, 0x4D, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xAB, 0x88, 0xBF, 0xF6, -+0xA4, 0xAE, 0x98, 0x06, 0x3F, 0xF5, 0xA1, 0xAE, 0x48, 0x49, 0x49, 0x48, 0x4F, 0xF4, 0xAC, 0x62, 0x05, 0xB0, 0xBD, 0xE8, -+0xF0, 0x4F, 0x16, 0xF0, 0xEB, 0xBC, 0x43, 0x48, 0x8B, 0x68, 0x01, 0x68, 0xB1, 0xF9, 0x00, 0x10, 0x00, 0x29, 0x33, 0xDB, -+0x60, 0x46, 0x9C, 0x46, 0xCC, 0xE6, 0xE3, 0x6A, 0x00, 0x2B, 0x3F, 0xF4, 0x7F, 0xAF, 0x23, 0x6B, 0x3E, 0x4A, 0x1B, 0x7F, -+0xA4, 0x21, 0x01, 0xFB, 0x03, 0x63, 0x99, 0x33, 0x52, 0xF8, 0x33, 0x30, 0x00, 0x2B, 0x7F, 0xF4, 0x73, 0xAF, 0x3A, 0x4B, -+0x93, 0xF8, 0xFF, 0x31, 0x00, 0x2B, 0x7F, 0xF4, 0x6D, 0xAF, 0x38, 0x4B, 0x30, 0x46, 0xD3, 0xF8, 0x5C, 0x33, 0x98, 0x47, -+0x66, 0xE7, 0x62, 0xB6, 0x5B, 0xE7, 0x33, 0x49, 0x91, 0xF8, 0xFF, 0x11, 0x00, 0x29, 0x7F, 0xF4, 0x7E, 0xAF, 0x31, 0x4B, -+0x03, 0x92, 0xD3, 0xF8, 0x5C, 0x33, 0x30, 0x46, 0x98, 0x47, 0x3B, 0x68, 0x03, 0x9A, 0x5B, 0x78, 0x00, 0x2B, 0x7F, 0xF4, -+0x75, 0xAF, 0xD5, 0xE6, 0x00, 0x2B, 0xC9, 0xD1, 0x25, 0x49, 0x2A, 0x48, 0x00, 0x93, 0x40, 0xF2, 0x56, 0x42, 0x16, 0xF0, -+0xD9, 0xFC, 0x00, 0x9B, 0xDB, 0x6B, 0xFF, 0xDE, 0x26, 0x4C, 0x1F, 0xE6, 0x26, 0x4B, 0x25, 0x60, 0x1B, 0x68, 0xEF, 0xF3, -+0x10, 0x82, 0xD0, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x23, 0x4A, 0x01, 0x21, 0x11, 0x60, 0x23, 0x4A, 0x01, 0x99, 0x10, 0x68, -+0x1F, 0x4C, 0x19, 0x40, 0x0B, 0x46, 0x41, 0x1C, 0x11, 0x60, 0x23, 0x60, 0x29, 0xB1, 0x1D, 0x4B, 0x10, 0x60, 0x1B, 0x68, -+0x08, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x1C, 0x4B, 0x00, 0x9A, 0x1A, 0x60, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x6B, 0x6A, -+0x03, 0xF4, 0x60, 0x13, 0xB3, 0xF5, 0x20, 0x1F, 0x7F, 0xF4, 0x41, 0xAF, 0x68, 0x6C, 0x31, 0x46, 0x0C, 0x30, 0x05, 0xB0, -+0xBD, 0xE8, 0xF0, 0x4F, 0x03, 0xF0, 0x28, 0xBF, 0x10, 0xB1, 0x31, 0x46, 0x03, 0xF0, 0x24, 0xFF, 0x10, 0x4B, 0x11, 0x4A, -+0x53, 0xF8, 0x26, 0x10, 0x02, 0x9B, 0x12, 0x68, 0x9B, 0x00, 0x0A, 0x44, 0x1A, 0x60, 0x2A, 0xE7, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xD4, 0x8E, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xC0, 0x8E, 0x15, 0x00, 0xC4, 0x63, 0x17, 0x00, 0x8C, 0x80, 0x32, 0x40, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x88, 0x80, 0x32, 0x40, 0xB0, 0x35, 0x17, 0x00, 0x20, 0x01, 0x32, 0x40, 0x43, 0x6A, 0x9B, 0x02, 0x03, 0xD5, 0x4B, 0x6A, -+0x5B, 0x07, 0x07, 0xD4, 0x70, 0x47, 0xC1, 0x6C, 0x05, 0x4B, 0x14, 0x31, 0xD3, 0xF8, 0x9C, 0x33, 0x08, 0x46, 0x18, 0x47, -+0x42, 0x6C, 0x93, 0x88, 0x43, 0xF0, 0x02, 0x03, 0x93, 0x80, 0x70, 0x47, 0x88, 0x1A, 0x17, 0x00, 0x70, 0xB5, 0x43, 0x7F, -+0x0B, 0x4E, 0x4F, 0xF4, 0x1E, 0x75, 0x04, 0x46, 0x05, 0xFB, 0x03, 0xF5, 0x05, 0xF5, 0xFE, 0x70, 0x01, 0x23, 0xE1, 0x76, -+0x84, 0xF8, 0x5D, 0x30, 0x30, 0x44, 0x21, 0x46, 0x14, 0xF0, 0xFE, 0xFF, 0x04, 0x4B, 0x71, 0x19, 0x20, 0x46, 0x5B, 0x69, -+0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x83, 0x88, 0x2D, 0xE9, -+0xF0, 0x41, 0x04, 0x46, 0x0E, 0x46, 0x15, 0x46, 0xEB, 0xB1, 0x3A, 0x4B, 0xD0, 0xF8, 0x4C, 0x80, 0x1A, 0x68, 0xB2, 0xF9, -+0x00, 0x20, 0x00, 0x2A, 0x23, 0xDB, 0xD8, 0xF8, 0x24, 0x70, 0x17, 0xB9, 0xD8, 0xF8, 0x20, 0x30, 0x9F, 0x68, 0x04, 0x2D, -+0x03, 0xD1, 0x39, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x13, 0xFB, 0xE3, 0x7E, 0xFF, 0x2B, 0x25, 0xD0, 0x2F, 0x4F, 0x29, 0x46, -+0xD7, 0xF8, 0x00, 0x34, 0x20, 0x46, 0x98, 0x47, 0x05, 0xE0, 0x82, 0x6C, 0x2B, 0x4F, 0x53, 0x6A, 0x43, 0xF0, 0x10, 0x03, -+0x53, 0x62, 0xD7, 0xF8, 0xA4, 0x33, 0x2A, 0x46, 0x31, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0x82, 0x6C, -+0x5A, 0xB3, 0xD8, 0xF8, 0x24, 0x70, 0x00, 0x2F, 0xDB, 0xD1, 0xD8, 0xF8, 0x20, 0x30, 0x00, 0x2B, 0xD6, 0xD1, 0x21, 0x49, -+0x21, 0x48, 0x40, 0xF2, 0xB9, 0x12, 0x16, 0xF0, 0x03, 0xFC, 0xCD, 0xE7, 0xE3, 0x8B, 0x1A, 0x07, 0x04, 0xD5, 0x3A, 0x88, -+0x02, 0xF0, 0xDC, 0x02, 0x10, 0x2A, 0x25, 0xD0, 0xBB, 0x7D, 0x13, 0xF0, 0x0F, 0x03, 0x07, 0xF1, 0x16, 0x07, 0x06, 0xD0, -+0x18, 0x4A, 0xB2, 0xF8, 0xFC, 0x21, 0x43, 0xEA, 0x02, 0x13, 0x3B, 0x80, 0xC4, 0xE7, 0x15, 0x49, 0xB1, 0xF8, 0xFC, 0x21, -+0x01, 0x32, 0x92, 0xB2, 0xA1, 0xF8, 0xFC, 0x21, 0xF3, 0xE7, 0x0F, 0x49, 0x11, 0x48, 0x4F, 0xF4, 0xD9, 0x72, 0x16, 0xF0, -+0xDF, 0xFB, 0xD8, 0xF8, 0x24, 0x70, 0x00, 0x2F, 0xA9, 0xD1, 0x08, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0xC7, 0xDB, 0x9F, 0xE7, 0x7A, 0x8B, 0x00, 0x2A, 0xD6, 0xD1, 0x43, 0xF0, 0x20, 0x03, 0xE3, 0x83, 0x38, 0x1D, 0x20, 0xF0, -+0xF9, 0xFE, 0xCF, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xAC, 0x8E, 0x15, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x8C, 0x8E, 0x15, 0x00, 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x29, 0x00, 0xF2, 0x33, 0x81, 0xDF, 0xE8, -+0x01, 0xF0, 0x36, 0x44, 0x51, 0x5E, 0x6B, 0x03, 0x9D, 0x4A, 0x13, 0x68, 0xC3, 0xF3, 0x01, 0x63, 0x02, 0x2B, 0x00, 0xF0, -+0x04, 0x81, 0x9B, 0x4A, 0x9B, 0x4B, 0x10, 0x60, 0x4F, 0xF4, 0x80, 0x42, 0x1A, 0x60, 0x9A, 0x49, 0x9A, 0x4A, 0x9B, 0x4B, -+0x51, 0xF8, 0x24, 0x50, 0x12, 0x68, 0x9A, 0x48, 0x23, 0x44, 0x9B, 0x00, 0x01, 0x21, 0x2A, 0x44, 0x01, 0xFA, 0x04, 0xF4, -+0x1A, 0x60, 0x04, 0x60, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x02, 0xD4, 0x72, 0xB6, 0x94, 0x4B, 0x19, 0x60, 0x94, 0x4B, -+0x94, 0x49, 0x18, 0x68, 0x0D, 0x68, 0x42, 0x1C, 0x2C, 0x43, 0x1A, 0x60, 0x0C, 0x60, 0x2A, 0xB1, 0x8E, 0x4A, 0x18, 0x60, -+0x13, 0x68, 0x08, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x38, 0xBD, 0x84, 0x4A, 0x13, 0x68, 0xC3, 0xF3, 0x01, 0x13, 0x02, 0x2B, -+0x00, 0xF0, 0xAE, 0x80, 0x8A, 0x4A, 0x82, 0x4B, 0x10, 0x60, 0x4F, 0xF4, 0x00, 0x72, 0x1A, 0x60, 0xCB, 0xE7, 0x7D, 0x4A, -+0x13, 0x68, 0xC3, 0xF3, 0x01, 0x23, 0x02, 0x2B, 0x7D, 0xD0, 0x85, 0x4A, 0x7B, 0x4B, 0x10, 0x60, 0x4F, 0xF4, 0x80, 0x62, -+0x1A, 0x60, 0xBE, 0xE7, 0x76, 0x4A, 0x13, 0x68, 0xC3, 0xF3, 0x01, 0x33, 0x02, 0x2B, 0x4F, 0xD0, 0x7F, 0x4A, 0x75, 0x4B, -+0x10, 0x60, 0x4F, 0xF4, 0x00, 0x62, 0x1A, 0x60, 0xB1, 0xE7, 0x70, 0x4A, 0x13, 0x68, 0xC3, 0xF3, 0x01, 0x43, 0x02, 0x2B, -+0x21, 0xD0, 0x7A, 0x4A, 0x6E, 0x4B, 0x10, 0x60, 0x4F, 0xF4, 0x80, 0x52, 0x1A, 0x60, 0xA4, 0xE7, 0x77, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x06, 0xDB, 0x75, 0x4A, 0x68, 0x4B, 0x10, 0x60, 0x4F, 0xF4, 0x80, 0x72, 0x1A, 0x60, -+0x97, 0xE7, 0x63, 0x4B, 0x1B, 0x68, 0x03, 0xF0, 0x03, 0x03, 0x02, 0x2B, 0xF2, 0xD1, 0xBD, 0xE8, 0x38, 0x40, 0x6F, 0x49, -+0x6F, 0x48, 0x4F, 0xF4, 0xEC, 0x62, 0x16, 0xF0, 0xFF, 0xBA, 0x60, 0x49, 0x0D, 0x68, 0x02, 0x35, 0x03, 0xE0, 0x0B, 0x68, -+0x5B, 0x1B, 0x00, 0x2B, 0x04, 0xDA, 0x13, 0x68, 0xC3, 0xF3, 0x01, 0x43, 0x02, 0x2B, 0xF6, 0xD0, 0x63, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xCA, 0xDA, 0x52, 0x4B, 0x1B, 0x68, 0xC3, 0xF3, 0x01, 0x43, 0x02, 0x2B, 0xC4, 0xD1, -+0xBD, 0xE8, 0x38, 0x40, 0x5E, 0x49, 0x60, 0x48, 0x40, 0xF2, 0x6C, 0x72, 0x16, 0xF0, 0xDE, 0xBA, 0x4F, 0x49, 0x0D, 0x68, -+0x02, 0x35, 0x03, 0xE0, 0x0B, 0x68, 0x5B, 0x1B, 0x00, 0x2B, 0x04, 0xDA, 0x13, 0x68, 0xC3, 0xF3, 0x01, 0x33, 0x02, 0x2B, -+0xF6, 0xD0, 0x53, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x9C, 0xDA, 0x42, 0x4B, 0x1B, 0x68, 0xC3, 0xF3, -+0x01, 0x33, 0x02, 0x2B, 0x96, 0xD1, 0xBD, 0xE8, 0x38, 0x40, 0x4E, 0x49, 0x50, 0x48, 0x4F, 0xF4, 0xEF, 0x62, 0x16, 0xF0, -+0xBD, 0xBA, 0x3F, 0x49, 0x0D, 0x68, 0x02, 0x35, 0x03, 0xE0, 0x0B, 0x68, 0x5B, 0x1B, 0x00, 0x2B, 0x04, 0xDA, 0x13, 0x68, -+0xC3, 0xF3, 0x01, 0x23, 0x02, 0x2B, 0xF6, 0xD0, 0x42, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xBF, 0xF6, -+0x6E, 0xAF, 0x31, 0x4B, 0x1B, 0x68, 0xC3, 0xF3, 0x01, 0x23, 0x02, 0x2B, 0x7F, 0xF4, 0x67, 0xAF, 0xBD, 0xE8, 0x38, 0x40, -+0x3C, 0x49, 0x40, 0x48, 0x40, 0xF2, 0x84, 0x72, 0x16, 0xF0, 0x9A, 0xBA, 0x2D, 0x49, 0x0D, 0x68, 0x02, 0x35, 0x03, 0xE0, -+0x0B, 0x68, 0x5B, 0x1B, 0x00, 0x2B, 0x04, 0xDA, 0x13, 0x68, 0xC3, 0xF3, 0x01, 0x13, 0x02, 0x2B, 0xF6, 0xD0, 0x31, 0x4B, -+0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xBF, 0xF6, 0x3E, 0xAF, 0x1F, 0x4B, 0x1B, 0x68, 0xC3, 0xF3, 0x01, 0x13, -+0x02, 0x2B, 0x7F, 0xF4, 0x37, 0xAF, 0xBD, 0xE8, 0x38, 0x40, 0x2B, 0x49, 0x2F, 0x48, 0x4F, 0xF4, 0xF2, 0x62, 0x16, 0xF0, -+0x77, 0xBA, 0x1C, 0x49, 0x0D, 0x68, 0x02, 0x35, 0x03, 0xE0, 0x0B, 0x68, 0x5B, 0x1B, 0x00, 0x2B, 0x04, 0xDA, 0x13, 0x68, -+0xC3, 0xF3, 0x01, 0x63, 0x02, 0x2B, 0xF6, 0xD0, 0x1F, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xBF, 0xF6, -+0xE8, 0xAE, 0x0E, 0x4B, 0x1B, 0x68, 0xC3, 0xF3, 0x01, 0x63, 0x02, 0x2B, 0x7F, 0xF4, 0xE1, 0xAE, 0xBD, 0xE8, 0x38, 0x40, -+0x19, 0x49, 0x1F, 0x48, 0x40, 0xF2, 0x9C, 0x72, 0x16, 0xF0, 0x54, 0xBA, 0x14, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xBF, 0xF6, 0xD8, 0xAE, 0x13, 0x49, 0x19, 0x48, 0x40, 0xF2, 0xA2, 0x72, 0x16, 0xF0, 0x79, 0xFA, 0xD0, 0xE6, -+0x88, 0x81, 0x32, 0x40, 0x34, 0x83, 0x32, 0x40, 0x80, 0x81, 0x32, 0x40, 0xB0, 0x35, 0x17, 0x00, 0x20, 0x01, 0x32, 0x40, -+0x4A, 0x80, 0x0C, 0x10, 0x88, 0x80, 0x32, 0x40, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x8C, 0x80, 0x32, 0x40, -+0x9C, 0x81, 0x32, 0x40, 0xA0, 0x81, 0x32, 0x40, 0xA4, 0x81, 0x32, 0x40, 0xA8, 0x81, 0x32, 0x40, 0x38, 0x36, 0x17, 0x00, -+0x98, 0x81, 0x32, 0x40, 0x70, 0x79, 0x15, 0x00, 0xF8, 0x8E, 0x15, 0x00, 0x18, 0x8F, 0x15, 0x00, 0x38, 0x8F, 0x15, 0x00, -+0x58, 0x8F, 0x15, 0x00, 0x78, 0x8F, 0x15, 0x00, 0x98, 0x8F, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x05, 0x2A, 0xF8, 0xB5, -+0x06, 0x46, 0x0D, 0x46, 0x35, 0xD0, 0x54, 0x21, 0x33, 0x4C, 0x01, 0xFB, 0x02, 0xF1, 0x02, 0xEB, 0x42, 0x03, 0x61, 0x58, -+0xC3, 0xEB, 0xC3, 0x03, 0x04, 0xEB, 0x83, 0x04, 0x00, 0x29, 0x37, 0xD0, 0x2E, 0x4F, 0x3B, 0x68, 0x5B, 0x78, 0xF3, 0xB1, -+0x4E, 0x60, 0x05, 0x2A, 0x0B, 0xD0, 0x2C, 0x48, 0x02, 0xEB, 0x42, 0x01, 0x00, 0xEB, 0x81, 0x01, 0x91, 0xF8, 0x2E, 0x10, -+0x41, 0xB9, 0x90, 0xF8, 0x8C, 0x10, 0x00, 0x29, 0x3E, 0xD1, 0x10, 0x46, 0xFF, 0xF7, 0x2A, 0xFB, 0x3B, 0x68, 0x5B, 0x78, -+0x3B, 0xB9, 0xAA, 0x6B, 0x92, 0x02, 0x46, 0xBF, 0x01, 0x23, 0xC4, 0xE9, 0x01, 0x63, 0xC4, 0xE9, 0x01, 0x33, 0x25, 0x60, -+0xF8, 0xBD, 0xA0, 0x68, 0x00, 0x28, 0xDD, 0xD0, 0x61, 0x68, 0x4E, 0x60, 0xDB, 0xE7, 0x19, 0x4C, 0xD4, 0xF8, 0xA4, 0x11, -+0x04, 0xF5, 0xD2, 0x74, 0x00, 0x29, 0xCF, 0xD1, 0x11, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0x44, 0xFE, 0x14, 0x4B, 0x1B, 0x68, -+0x5B, 0x78, 0xDF, 0xE7, 0x13, 0x4B, 0x02, 0xEB, 0x42, 0x00, 0x03, 0xEB, 0x80, 0x00, 0x51, 0x00, 0x90, 0xF8, 0x2E, 0x00, -+0x38, 0xB9, 0x93, 0xF8, 0x8C, 0x00, 0x93, 0xF8, 0x7E, 0x70, 0x00, 0x28, 0xE8, 0xD0, 0xBA, 0x42, 0xE6, 0xD1, 0x0A, 0x44, -+0x03, 0xEB, 0x82, 0x03, 0x5A, 0x6A, 0x42, 0xB1, 0x07, 0x4B, 0x1B, 0x68, 0x5B, 0x78, 0xC5, 0xE7, 0x90, 0xF8, 0x7E, 0x10, -+0x91, 0x42, 0xBC, 0xD1, 0xC0, 0xE7, 0x03, 0x4A, 0x5E, 0x62, 0x13, 0x68, 0x5B, 0x78, 0xBB, 0xE7, 0x20, 0x62, 0x17, 0x00, -+0x34, 0x36, 0x17, 0x00, 0x94, 0x64, 0x17, 0x00, 0x38, 0xB5, 0x83, 0x88, 0x33, 0xB1, 0x04, 0x46, 0x80, 0x6C, 0x18, 0xB1, -+0x63, 0x6A, 0x13, 0xF4, 0x00, 0x15, 0x00, 0xD0, 0x38, 0xBD, 0xF8, 0xF7, 0x75, 0xFE, 0xA5, 0x64, 0x38, 0xBD, 0x00, 0xBF, -+0x70, 0xB5, 0x20, 0x4C, 0x20, 0x4D, 0x02, 0xF0, 0xD9, 0xFC, 0xD4, 0xF8, 0x44, 0x33, 0x98, 0x47, 0xFE, 0xF7, 0x9E, 0xFF, -+0x00, 0xF0, 0xA8, 0xFD, 0xD4, 0xF8, 0xA8, 0x33, 0x00, 0x20, 0x98, 0x47, 0x04, 0xF0, 0xBA, 0xFE, 0x4F, 0xF4, 0x01, 0x72, -+0x00, 0x21, 0xA5, 0xF1, 0x0C, 0x00, 0xF1, 0xF7, 0xC3, 0xFC, 0x05, 0xF5, 0xD2, 0x76, 0x00, 0x24, 0x28, 0x46, 0x14, 0xF0, -+0x4D, 0xFD, 0x45, 0xF8, 0x0C, 0x4C, 0xAC, 0x73, 0x85, 0xF8, 0x44, 0x40, 0xC5, 0xE9, 0x06, 0x44, 0x05, 0xF1, 0x10, 0x00, -+0x54, 0x35, 0x14, 0xF0, 0x41, 0xFD, 0xB5, 0x42, 0xEE, 0xD1, 0x0C, 0x4D, 0x05, 0xF5, 0xD8, 0x70, 0x14, 0xF0, 0x3A, 0xFD, -+0x05, 0xF5, 0xE0, 0x70, 0xC5, 0xE9, 0x72, 0x44, 0xC5, 0xF8, 0xA4, 0x41, 0x85, 0xF8, 0xBE, 0x41, 0x85, 0xF8, 0xF4, 0x41, -+0x14, 0xF0, 0x2E, 0xFD, 0xA5, 0xF8, 0xFC, 0x41, 0x70, 0xBD, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x2C, 0x62, 0x17, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x0C, 0x4B, 0x93, 0xF8, 0xFE, 0x31, 0x0B, 0xB1, 0x00, 0x20, 0x70, 0x47, 0x10, 0xB5, 0x04, 0x46, -+0x10, 0xF0, 0xBC, 0xF8, 0x20, 0xB1, 0x94, 0xF8, 0xC0, 0x34, 0x1B, 0xB9, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, -+0x94, 0xF8, 0xC1, 0x04, 0x11, 0xF0, 0x16, 0xFD, 0x00, 0x38, 0x18, 0xBF, 0x01, 0x20, 0x10, 0xBD, 0x20, 0x62, 0x17, 0x00, -+0x45, 0x4B, 0x01, 0x22, 0x70, 0xB4, 0x1B, 0x68, 0x02, 0xFA, 0x00, 0xF6, 0xEF, 0xF3, 0x10, 0x81, 0xC9, 0x07, 0x02, 0xD4, -+0x72, 0xB6, 0x41, 0x49, 0x0A, 0x60, 0x41, 0x4A, 0x3E, 0x4D, 0x14, 0x68, 0x23, 0xEA, 0x06, 0x03, 0x61, 0x1C, 0x11, 0x60, -+0x2B, 0x60, 0x29, 0xB1, 0x3B, 0x4B, 0x14, 0x60, 0x1B, 0x68, 0x0C, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x3A, 0x4B, 0x1E, 0x60, -+0x05, 0x28, 0x5D, 0xD8, 0xDF, 0xE8, 0x00, 0xF0, 0x12, 0x21, 0x3F, 0x30, 0x4E, 0x03, 0x37, 0x4B, 0x37, 0x4A, 0x4F, 0xF4, -+0x00, 0x11, 0x19, 0x60, 0x13, 0x68, 0x13, 0xF0, 0x40, 0x7F, 0xFB, 0xD1, 0x34, 0x4B, 0x4F, 0xF4, 0x00, 0x12, 0x70, 0xBC, -+0x1A, 0x60, 0x70, 0x47, 0x2F, 0x4B, 0x30, 0x4A, 0x4F, 0xF4, 0x80, 0x31, 0x19, 0x60, 0x13, 0x68, 0x13, 0xF0, 0x30, 0x0F, -+0xFB, 0xD1, 0x2D, 0x4B, 0x4F, 0xF4, 0x80, 0x32, 0x70, 0xBC, 0x1A, 0x60, 0x70, 0x47, 0x28, 0x4B, 0x28, 0x4A, 0x4F, 0xF4, -+0x00, 0x31, 0x19, 0x60, 0x13, 0x68, 0x13, 0xF4, 0x40, 0x7F, 0xFB, 0xD1, 0x25, 0x4B, 0x4F, 0xF4, 0x00, 0x32, 0x70, 0xBC, -+0x1A, 0x60, 0x70, 0x47, 0x20, 0x4B, 0x21, 0x4A, 0x4F, 0xF4, 0x00, 0x21, 0x19, 0x60, 0x13, 0x68, 0x13, 0xF4, 0x40, 0x3F, -+0xFB, 0xD1, 0x1E, 0x4B, 0x4F, 0xF4, 0x00, 0x22, 0x70, 0xBC, 0x1A, 0x60, 0x70, 0x47, 0x19, 0x4B, 0x19, 0x4A, 0x4F, 0xF4, -+0x80, 0x21, 0x19, 0x60, 0x13, 0x68, 0x13, 0xF4, 0x40, 0x5F, 0xFB, 0xD1, 0x16, 0x4B, 0x4F, 0xF4, 0x80, 0x22, 0x70, 0xBC, -+0x1A, 0x60, 0x70, 0x47, 0x11, 0x4B, 0x12, 0x4A, 0x4F, 0xF4, 0x00, 0x41, 0x19, 0x60, 0x13, 0x68, 0x9B, 0x07, 0xFC, 0xD1, -+0x0F, 0x4B, 0x4F, 0xF4, 0x00, 0x42, 0x1A, 0x60, 0x70, 0xBC, 0x70, 0x47, 0x0D, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xF7, 0xDA, 0x70, 0xBC, 0x0B, 0x49, 0x0B, 0x48, 0x40, 0xF6, 0xE7, 0x02, 0x16, 0xF0, 0xD5, 0xB8, 0x00, 0xBF, -+0x8C, 0x80, 0x32, 0x40, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x88, 0x80, 0x32, 0x40, 0x80, 0x81, 0x32, 0x40, -+0x88, 0x81, 0x32, 0x40, 0x84, 0x81, 0x32, 0x40, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, -+0x70, 0xB5, 0x05, 0x28, 0x82, 0xB0, 0x04, 0x46, 0x0A, 0x46, 0x3B, 0xD0, 0x1E, 0x4B, 0x00, 0xEB, 0x40, 0x05, 0xC5, 0xEB, -+0xC5, 0x05, 0x03, 0xEB, 0x85, 0x05, 0x1C, 0x4E, 0x1C, 0x49, 0xD6, 0xF8, 0x84, 0x33, 0x01, 0x92, 0x01, 0xEB, 0xC4, 0x01, -+0x20, 0x46, 0x98, 0x47, 0x01, 0x9A, 0xD6, 0xF8, 0x84, 0x33, 0x05, 0xF1, 0x0C, 0x01, 0x20, 0x46, 0x98, 0x47, 0x00, 0x23, -+0x20, 0x46, 0x2B, 0x60, 0x6B, 0x61, 0xFE, 0xF7, 0x59, 0xFE, 0x13, 0x4B, 0x01, 0x22, 0x1B, 0x68, 0x02, 0xFA, 0x04, 0xF4, -+0xEF, 0xF3, 0x10, 0x81, 0xC9, 0x07, 0x02, 0xD4, 0x72, 0xB6, 0x0F, 0x49, 0x0A, 0x60, 0x0F, 0x4A, 0x0C, 0x4D, 0x11, 0x68, -+0x23, 0xEA, 0x04, 0x03, 0x48, 0x1C, 0x10, 0x60, 0x2B, 0x60, 0x28, 0xB1, 0x09, 0x4B, 0x11, 0x60, 0x1B, 0x68, 0x09, 0xB9, -+0x03, 0xB1, 0x62, 0xB6, 0x08, 0x4B, 0x1C, 0x60, 0x02, 0xB0, 0x70, 0xBD, 0x07, 0x4D, 0xC8, 0xE7, 0x20, 0x62, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x24, 0x64, 0x17, 0x00, 0x8C, 0x80, 0x32, 0x40, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x88, 0x80, 0x32, 0x40, 0xC4, 0x63, 0x17, 0x00, 0x70, 0xB5, 0x0E, 0x4E, 0x82, 0xB0, 0x00, 0xF5, 0x9E, 0x64, 0x00, 0x25, -+0xE8, 0xB2, 0x21, 0x46, 0xD6, 0xF8, 0x84, 0x33, 0x01, 0x90, 0x4F, 0xF0, 0x80, 0x42, 0x98, 0x47, 0x01, 0x35, 0xA4, 0xF1, -+0x28, 0x01, 0x01, 0x98, 0xD6, 0xF8, 0x84, 0x33, 0x4F, 0xF0, 0x80, 0x42, 0x98, 0x47, 0x05, 0x2D, 0x04, 0xF1, 0x08, 0x04, -+0xEA, 0xD1, 0x02, 0xB0, 0x70, 0xBD, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x05, 0x29, 0x2D, 0xE9, 0xF0, 0x41, 0x0E, 0x46, -+0x04, 0x46, 0x64, 0xD0, 0x33, 0x4D, 0x01, 0xEB, 0x41, 0x03, 0xC3, 0xEB, 0xC3, 0x03, 0x05, 0xEB, 0x83, 0x05, 0x94, 0xF8, -+0x35, 0x10, 0x94, 0xF8, 0x33, 0x20, 0xA3, 0x88, 0x2E, 0x48, 0x0A, 0x44, 0x1A, 0x44, 0xE3, 0x6C, 0xE1, 0x8B, 0x58, 0x61, -+0x04, 0x32, 0xDA, 0x62, 0x00, 0x22, 0xC3, 0xE9, 0x0F, 0x22, 0xC3, 0xE9, 0x06, 0x22, 0xC3, 0xE9, 0x08, 0x22, 0x5A, 0x64, -+0x9A, 0x62, 0x9A, 0x63, 0xDA, 0x64, 0x1A, 0x63, 0x1A, 0x65, 0xCA, 0x07, 0x05, 0xD4, 0x22, 0x4A, 0xD2, 0xF8, 0xF8, 0x31, -+0x01, 0x33, 0xC2, 0xF8, 0xF8, 0x31, 0x21, 0x4B, 0x1B, 0x6A, 0x23, 0xB1, 0x20, 0x4A, 0x13, 0x68, 0x43, 0xF4, 0x80, 0x33, -+0x13, 0x60, 0xDF, 0xF8, 0x88, 0x80, 0x61, 0x7F, 0x20, 0x7F, 0x00, 0x22, 0x12, 0xF0, 0x5A, 0xF9, 0xD8, 0xF8, 0x48, 0x32, -+0xE1, 0x7E, 0x60, 0x7F, 0x98, 0x47, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x16, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x16, 0x4F, 0xD8, 0xF8, 0x68, 0x33, 0x3A, 0x68, 0x01, 0x32, 0x3A, 0x60, 0x31, 0x46, 0x20, 0x46, 0x98, 0x47, -+0xD8, 0xF8, 0x08, 0x34, 0x31, 0x46, 0x00, 0x22, 0x20, 0x46, 0x98, 0x47, 0x21, 0x46, 0x05, 0xF1, 0x0C, 0x00, 0x14, 0xF0, -+0x99, 0xFB, 0x3B, 0x68, 0x33, 0xB1, 0x0A, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x3B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, -+0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x07, 0x4D, 0x9F, 0xE7, 0x00, 0xBF, 0x20, 0x62, 0x17, 0x00, 0xBE, 0xBA, 0xFE, 0xCA, -+0x1C, 0x9E, 0x17, 0x00, 0x80, 0x00, 0x32, 0x40, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xC4, 0x63, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x03, 0x4A, 0xD2, 0xF8, 0xF8, 0x31, 0x01, 0x33, 0xC2, 0xF8, 0xF8, 0x31, 0x70, 0x47, 0x00, 0xBF, -+0x20, 0x62, 0x17, 0x00, 0x05, 0x29, 0x2D, 0xE9, 0xF0, 0x41, 0x0D, 0x46, 0x04, 0x46, 0x1C, 0xD0, 0x47, 0x4E, 0x01, 0xEB, -+0x41, 0x03, 0xC3, 0xEB, 0xC3, 0x03, 0x06, 0xEB, 0x83, 0x06, 0x22, 0x7F, 0x44, 0x4B, 0xE7, 0x6C, 0x4F, 0xF4, 0xA4, 0x60, -+0x00, 0xFB, 0x02, 0x30, 0xFF, 0xF7, 0x32, 0xFE, 0x68, 0xB9, 0x63, 0x7F, 0xFF, 0x2B, 0x67, 0xD0, 0x3F, 0x4B, 0x20, 0x46, -+0xD3, 0xF8, 0x90, 0x33, 0x29, 0x46, 0x98, 0x47, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x3C, 0x4E, 0xE7, 0xE7, 0x20, 0x46, -+0x1C, 0xF0, 0xEE, 0xFF, 0x00, 0x28, 0xEC, 0xD0, 0xFB, 0x6C, 0x43, 0xF4, 0x80, 0x73, 0xFB, 0x64, 0xEF, 0xF3, 0x10, 0x83, -+0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x35, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x34, 0x4F, 0x96, 0xF8, 0x50, 0x30, 0x3A, 0x68, -+0xF1, 0x6A, 0xDF, 0xF8, 0xBC, 0x80, 0x01, 0x32, 0x01, 0x33, 0x3A, 0x60, 0x86, 0xF8, 0x50, 0x30, 0x19, 0xB1, 0xD8, 0xF8, -+0x5C, 0x33, 0x28, 0x46, 0x98, 0x47, 0x73, 0x69, 0x00, 0x2B, 0x42, 0xD0, 0x06, 0xF1, 0x0C, 0x00, 0x21, 0x46, 0x14, 0xF0, -+0x21, 0xFB, 0x3B, 0x68, 0x2B, 0xB1, 0x26, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x3B, 0x60, 0x00, 0x2B, 0x31, 0xD0, 0x1F, 0x4A, -+0x24, 0x49, 0xD2, 0xF8, 0xF8, 0x31, 0x09, 0x6A, 0x01, 0x33, 0xC2, 0xF8, 0xF8, 0x31, 0x21, 0xB1, 0x21, 0x4A, 0x13, 0x68, -+0x43, 0xF4, 0x80, 0x33, 0x13, 0x60, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x19, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x3B, 0x68, 0xD8, 0xF8, 0x04, 0x64, 0xA1, 0x6C, 0x01, 0x33, 0x3B, 0x60, 0x2A, 0x46, 0x20, 0x46, 0xB0, 0x47, -+0x3B, 0x68, 0x33, 0xB1, 0x12, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x3B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x01, 0x20, -+0xBD, 0xE8, 0xF0, 0x81, 0x20, 0x46, 0x00, 0x21, 0x01, 0xF0, 0x7E, 0xF9, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x2A, -+0xCB, 0xD0, 0x62, 0xB6, 0xC9, 0xE7, 0xA3, 0x6C, 0x0B, 0x49, 0x5A, 0x6A, 0x9C, 0x60, 0x22, 0xF0, 0x10, 0x02, 0x5A, 0x62, -+0xD9, 0x60, 0xB3, 0xE7, 0x20, 0x62, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xC4, 0x63, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, 0x80, 0x00, 0x32, 0x40, 0xDE, 0xFA, 0xFE, 0xCA, -+0x70, 0x47, 0x00, 0xBF, 0x20, 0x4B, 0x70, 0xB5, 0x1C, 0x68, 0xE1, 0x04, 0x2C, 0xD4, 0x1F, 0x4D, 0x2C, 0x42, 0x24, 0xD1, -+0x1E, 0x4B, 0x23, 0x40, 0x20, 0xD0, 0x22, 0x03, 0x0B, 0xD5, 0x1D, 0x4B, 0x4F, 0xF4, 0x00, 0x22, 0x1A, 0x60, 0x05, 0x24, -+0x1B, 0x4B, 0x20, 0x46, 0xD3, 0xF8, 0xA0, 0x33, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, 0x19, 0x4A, 0x12, 0x68, 0xB2, 0xF9, -+0x00, 0x20, 0xB3, 0xFA, 0x83, 0xF3, 0xC3, 0xF1, 0x19, 0x04, 0x00, 0x2A, 0xE4, 0xB2, 0x14, 0xDB, 0x05, 0x2C, 0xE6, 0xD0, -+0x10, 0x4A, 0xA1, 0x1D, 0x01, 0x23, 0x8B, 0x40, 0x13, 0x60, 0xE5, 0xE7, 0x70, 0xBD, 0x04, 0xF0, 0x07, 0xFB, 0x0C, 0x4B, -+0x1D, 0x60, 0xD5, 0xE7, 0x04, 0xF0, 0x56, 0xFA, 0x09, 0x4B, 0x4F, 0xF4, 0x80, 0x52, 0x1A, 0x60, 0xCB, 0xE7, 0x06, 0x2C, -+0xE8, 0xD9, 0x09, 0x49, 0x09, 0x48, 0x40, 0xF6, 0xC2, 0x22, 0x15, 0xF0, 0xD9, 0xFE, 0xE3, 0xE7, 0x78, 0x80, 0x32, 0x40, -+0x00, 0x08, 0x00, 0x20, 0xC0, 0x07, 0x08, 0x00, 0x7C, 0x80, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xB8, 0x8F, 0x15, 0x00, 0x38, 0xB5, 0x0D, 0x4B, 0x0D, 0x4D, 0x1C, 0x68, 0xE3, 0x06, 0x05, 0xEA, -+0x04, 0x05, 0x03, 0xD5, 0x0B, 0x4B, 0xD3, 0xF8, 0xF0, 0x33, 0x98, 0x47, 0x14, 0xF4, 0x70, 0x04, 0x08, 0xD0, 0x08, 0x4B, -+0xB4, 0xFA, 0x84, 0xF4, 0xC4, 0xF1, 0x0B, 0x00, 0xD3, 0xF8, 0x48, 0x33, 0xC0, 0xB2, 0x98, 0x47, 0x04, 0x4B, 0x1D, 0x60, -+0x38, 0xBD, 0x00, 0xBF, 0x78, 0x80, 0x32, 0x40, 0x1F, 0x00, 0xF0, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x7C, 0x80, 0x32, 0x40, -+0xFF, 0xF7, 0xDA, 0xBF, 0x2D, 0xE9, 0xF8, 0x43, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x1C, 0x4B, -+0x01, 0x22, 0x1A, 0x60, 0xDF, 0xF8, 0x70, 0x90, 0x1A, 0x4F, 0xD9, 0xF8, 0x00, 0x30, 0xDF, 0xF8, 0x6C, 0x80, 0x01, 0x33, -+0xC9, 0xF8, 0x00, 0x30, 0x3D, 0x46, 0x46, 0x46, 0x04, 0x24, 0x95, 0xF8, 0x5E, 0x30, 0xE2, 0xB2, 0x63, 0xB9, 0x97, 0xF8, -+0x8C, 0x30, 0x97, 0xF8, 0x7E, 0x10, 0x10, 0x46, 0x0B, 0xB1, 0x91, 0x42, 0x04, 0xD0, 0xD6, 0xF8, 0x50, 0x31, 0x0B, 0xB1, -+0xFF, 0xF7, 0x1A, 0xFD, 0x01, 0x3C, 0x63, 0x1C, 0xA5, 0xF1, 0x0C, 0x05, 0xA6, 0xF1, 0x54, 0x06, 0xE7, 0xD1, 0xD9, 0xF8, -+0x00, 0x30, 0x01, 0x22, 0x88, 0xF8, 0xFF, 0x21, 0x3B, 0xB1, 0x05, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xC9, 0xF8, 0x00, 0x30, -+0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x94, 0x64, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x83, 0xB0, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, -+0x03, 0xD4, 0x72, 0xB6, 0x31, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x31, 0x4E, 0x31, 0x4D, 0x33, 0x68, 0x31, 0x4F, 0xDF, 0xF8, -+0xD0, 0xB0, 0xDF, 0xF8, 0xD0, 0xA0, 0xDF, 0xF8, 0xD0, 0x80, 0x01, 0x33, 0x00, 0x22, 0x33, 0x60, 0x85, 0xF8, 0xFF, 0x21, -+0xB9, 0x46, 0x04, 0x24, 0x99, 0xF8, 0x5E, 0x30, 0xE0, 0xB2, 0x00, 0x2B, 0x34, 0xD1, 0x97, 0xF8, 0x8C, 0x30, 0x97, 0xF8, -+0x7E, 0x20, 0x0B, 0xB1, 0x82, 0x42, 0x2D, 0xD0, 0xD5, 0xF8, 0x50, 0x31, 0x43, 0xB3, 0x01, 0x90, 0xFE, 0xF7, 0x36, 0xFF, -+0x5A, 0xF8, 0x24, 0x30, 0xDB, 0xF8, 0x00, 0x20, 0x20, 0x48, 0x1A, 0x44, 0x40, 0xF8, 0x24, 0x20, 0x01, 0x21, 0x1F, 0x4A, -+0x01, 0xFA, 0x04, 0xF3, 0x13, 0x60, 0xEF, 0xF3, 0x10, 0x82, 0x12, 0xF0, 0x01, 0x0F, 0x01, 0x98, 0x02, 0xD1, 0x72, 0xB6, -+0x14, 0x4A, 0x11, 0x60, 0x32, 0x68, 0xD8, 0xF8, 0x00, 0xC0, 0x51, 0x1C, 0x43, 0xEA, 0x0C, 0x03, 0x31, 0x60, 0xC8, 0xF8, -+0x00, 0x30, 0x29, 0xB1, 0x0E, 0x4B, 0x32, 0x60, 0x1B, 0x68, 0x0A, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x03, 0xF0, 0x32, 0xF8, -+0x01, 0x3C, 0x63, 0x1C, 0xA9, 0xF1, 0x0C, 0x09, 0xA5, 0xF1, 0x54, 0x05, 0xBE, 0xD1, 0x33, 0x68, 0x33, 0xB1, 0x06, 0x4A, -+0x01, 0x3B, 0x12, 0x68, 0x33, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x40, 0x20, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, -+0x14, 0xF0, 0xF8, 0xB8, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x94, 0x64, 0x17, 0x00, -+0x28, 0x01, 0x32, 0x40, 0x88, 0x80, 0x32, 0x40, 0x20, 0x01, 0x32, 0x40, 0xB0, 0x35, 0x17, 0x00, 0x8C, 0x80, 0x32, 0x40, -+0x2D, 0xE9, 0xF0, 0x4F, 0x5D, 0x4E, 0xDF, 0xF8, 0x90, 0x91, 0xB6, 0xF8, 0xFC, 0x31, 0x83, 0xB0, 0x4F, 0xF4, 0x78, 0x30, -+0x00, 0x93, 0x06, 0xF1, 0x0C, 0x05, 0x14, 0xF0, 0xFB, 0xF8, 0x01, 0x23, 0x86, 0xF8, 0xFE, 0x31, 0xAA, 0x46, 0x4F, 0xF4, -+0x9E, 0x67, 0x4F, 0xF0, 0x00, 0x0B, 0x01, 0x95, 0x53, 0x49, 0xD9, 0xF8, 0x84, 0x33, 0x5F, 0xFA, 0x8B, 0xF8, 0x40, 0x46, -+0x4F, 0xF0, 0x80, 0x42, 0x39, 0x44, 0x98, 0x47, 0x4F, 0x4B, 0x9D, 0x68, 0xA7, 0xF1, 0x28, 0x04, 0xC5, 0xB1, 0xE9, 0x19, -+0xD9, 0xF8, 0x84, 0x33, 0x4F, 0xF0, 0x80, 0x42, 0x40, 0x46, 0x98, 0x47, 0x29, 0x19, 0xD9, 0xF8, 0x84, 0x33, 0x4F, 0xF0, -+0x80, 0x42, 0x40, 0x46, 0x98, 0x47, 0x05, 0xF5, 0xA3, 0x61, 0xD9, 0xF8, 0x84, 0x33, 0x4F, 0xF0, 0x80, 0x42, 0x40, 0x46, -+0x98, 0x47, 0x2D, 0x68, 0x00, 0x2D, 0xE6, 0xD1, 0x51, 0x46, 0xD9, 0xF8, 0x84, 0x33, 0x40, 0x46, 0x08, 0x37, 0x4F, 0xF0, -+0x80, 0x42, 0x98, 0x47, 0xB7, 0xF5, 0xA3, 0x6F, 0x0B, 0xF1, 0x01, 0x0B, 0x0A, 0xF1, 0x54, 0x0A, 0xC8, 0xD1, 0xD9, 0xF8, -+0x84, 0x33, 0x39, 0x49, 0x01, 0x9D, 0x4F, 0xF0, 0x80, 0x42, 0x05, 0x20, 0x98, 0x47, 0x37, 0x49, 0xD9, 0xF8, 0x84, 0x33, -+0x4F, 0xF0, 0x80, 0x42, 0x05, 0x20, 0x98, 0x47, 0x02, 0xF0, 0x30, 0xF9, 0x00, 0xF0, 0x6A, 0xF9, 0xD9, 0xF8, 0xCC, 0x33, -+0x98, 0x47, 0x2C, 0x48, 0x4F, 0xF4, 0x01, 0x72, 0x00, 0x21, 0xF1, 0xF7, 0x89, 0xF8, 0x2B, 0x4B, 0xD3, 0xF8, 0x08, 0x80, -+0x00, 0x9B, 0xA6, 0xF8, 0xFC, 0x31, 0xB8, 0xF1, 0x00, 0x0F, 0x17, 0xD0, 0x2B, 0x46, 0x45, 0x46, 0x98, 0x46, 0x05, 0xF5, -+0x9E, 0x64, 0x05, 0xF5, 0xA3, 0x67, 0x20, 0x46, 0x14, 0xF0, 0x06, 0xF9, 0xA4, 0xF1, 0x28, 0x00, 0x08, 0x34, 0x14, 0xF0, -+0x01, 0xF9, 0xBC, 0x42, 0xF5, 0xD1, 0x20, 0x46, 0x14, 0xF0, 0xFC, 0xF8, 0x2D, 0x68, 0x00, 0x2D, 0xEB, 0xD1, 0x45, 0x46, -+0x1B, 0x4F, 0x00, 0x24, 0x28, 0x46, 0x14, 0xF0, 0xF3, 0xF8, 0x45, 0xF8, 0x0C, 0x4C, 0xAC, 0x73, 0x85, 0xF8, 0x44, 0x40, -+0xC5, 0xE9, 0x06, 0x44, 0x05, 0xF1, 0x10, 0x00, 0x54, 0x35, 0x14, 0xF0, 0xE7, 0xF8, 0xAF, 0x42, 0xEE, 0xD1, 0x12, 0x48, -+0x14, 0xF0, 0xE2, 0xF8, 0x12, 0x48, 0xC6, 0xF8, 0xA4, 0x41, 0xC6, 0xE9, 0x72, 0x44, 0x86, 0xF8, 0xBE, 0x41, 0x86, 0xF8, -+0xF4, 0x41, 0x14, 0xF0, 0xD7, 0xF8, 0x0E, 0x4A, 0x00, 0x21, 0x02, 0xF5, 0xB4, 0x70, 0xA2, 0xF1, 0x24, 0x03, 0x43, 0xF8, -+0x04, 0x1B, 0x93, 0x42, 0xFB, 0xD1, 0x03, 0xF1, 0x24, 0x02, 0x90, 0x42, 0xF5, 0xD1, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0x20, 0x62, 0x17, 0x00, 0x34, 0x5F, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0xD0, 0x63, 0x17, 0x00, 0x4C, 0x64, 0x17, 0x00, -+0xE0, 0x63, 0x17, 0x00, 0xD8, 0x56, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x03, 0x8C, 0x08, 0x8C, 0x83, 0x42, 0x08, 0xD8, -+0x05, 0xD2, 0xC0, 0x1A, 0x3F, 0x28, 0xCC, 0xBF, 0x00, 0x20, 0x01, 0x20, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, -+0x70, 0x47, 0x00, 0xBF, 0x51, 0xB9, 0x81, 0x6C, 0x90, 0xF8, 0x42, 0x30, 0xCB, 0x1A, 0x93, 0xF8, 0xB8, 0x30, 0xDB, 0x07, -+0x02, 0xD4, 0x03, 0x8B, 0x08, 0x2B, 0x00, 0xD0, 0x70, 0x47, 0x91, 0xF8, 0xA8, 0x30, 0x03, 0xF0, 0xF0, 0x03, 0x40, 0x2B, -+0xF8, 0xD1, 0x91, 0xF8, 0xB1, 0x30, 0x06, 0x2B, 0x01, 0xD0, 0x01, 0x2B, 0xF2, 0xD1, 0x13, 0x68, 0x01, 0x33, 0x13, 0x60, -+0xEE, 0xE7, 0x00, 0xBF, 0x03, 0x6D, 0x00, 0x2B, 0x00, 0xDB, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x43, 0x56, 0x4A, 0x12, 0x68, -+0x12, 0x78, 0x02, 0x2A, 0x83, 0xB0, 0x04, 0x46, 0x0D, 0x46, 0x07, 0xD0, 0x01, 0x2A, 0x7E, 0xD0, 0x03, 0x2A, 0x00, 0xF0, -+0x8D, 0x80, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0xFB, 0xF7, 0x8A, 0xFB, 0x06, 0x46, 0x00, 0x28, 0x00, 0xF0, 0x94, 0x80, -+0xDF, 0xF8, 0x60, 0x91, 0x42, 0xF2, 0x24, 0x03, 0x59, 0xF8, 0x03, 0x30, 0x00, 0x2B, 0x00, 0xF0, 0x87, 0x80, 0x48, 0x48, -+0x14, 0xF0, 0xA8, 0xF8, 0x4F, 0xF0, 0x00, 0x08, 0x08, 0x22, 0x12, 0x23, 0x32, 0x70, 0x86, 0xF8, 0x01, 0x80, 0x86, 0xF8, -+0x03, 0x80, 0xB3, 0x70, 0x23, 0x6D, 0x29, 0x68, 0x00, 0x91, 0x23, 0xF0, 0x40, 0x43, 0x07, 0x46, 0x69, 0x46, 0x30, 0x1D, -+0x01, 0x93, 0x27, 0xF0, 0x49, 0xFF, 0x42, 0xF2, 0x34, 0x03, 0x39, 0xF8, 0x03, 0x30, 0xB3, 0xF5, 0xC3, 0x7F, 0x62, 0xD8, -+0x03, 0xF1, 0x01, 0x0E, 0x1F, 0xFA, 0x8E, 0xFE, 0xDA, 0x00, 0x37, 0x49, 0xBB, 0x81, 0x09, 0x68, 0x36, 0x4B, 0x01, 0xEB, -+0x02, 0x0C, 0x42, 0xF2, 0x34, 0x08, 0xCC, 0xF8, 0x04, 0x60, 0x88, 0x58, 0x03, 0x40, 0x43, 0xF0, 0x80, 0x63, 0x43, 0xF0, -+0x0C, 0x03, 0x8B, 0x50, 0x99, 0xF8, 0x02, 0x3C, 0x29, 0xF8, 0x08, 0xE0, 0x01, 0x33, 0x01, 0x22, 0x00, 0x20, 0x0C, 0x21, -+0x89, 0xF8, 0x02, 0x3C, 0xC7, 0xF8, 0x04, 0xC0, 0xBA, 0x73, 0x38, 0x60, 0xB9, 0x60, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, -+0x02, 0xD4, 0x72, 0xB6, 0x26, 0x4B, 0x1A, 0x60, 0x26, 0x4E, 0x2B, 0x68, 0x31, 0x68, 0x22, 0x8C, 0x25, 0x48, 0x4D, 0x1C, -+0x21, 0x46, 0x35, 0x60, 0x15, 0xF0, 0xEC, 0xF9, 0x23, 0x48, 0x39, 0x46, 0x14, 0xF0, 0x0E, 0xF8, 0x22, 0x4B, 0xD3, 0xF8, -+0x44, 0x34, 0x98, 0x47, 0x33, 0x68, 0x00, 0x2B, 0x8D, 0xD0, 0x1B, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x33, 0x60, 0x00, 0x2B, -+0x87, 0xD1, 0x00, 0x2A, 0x85, 0xD0, 0x62, 0xB6, 0x83, 0xE7, 0x0E, 0x68, 0x00, 0x96, 0x23, 0xF0, 0x40, 0x43, 0x69, 0x46, -+0x08, 0x22, 0x12, 0x20, 0x01, 0x93, 0xF9, 0xF7, 0xD7, 0xFA, 0x2B, 0x68, 0x22, 0x8C, 0x15, 0x48, 0x21, 0x46, 0x15, 0xF0, -+0xC7, 0xF9, 0x72, 0xE7, 0x13, 0x4B, 0x0A, 0x68, 0x1B, 0x68, 0x1A, 0x60, 0xF6, 0xF7, 0x72, 0xF8, 0x6B, 0xE7, 0x42, 0x46, -+0x43, 0x46, 0x4F, 0xF0, 0x01, 0x0E, 0x9C, 0xE7, 0x0E, 0x48, 0xF6, 0xF7, 0xED, 0xFF, 0x62, 0xE7, 0x0D, 0x48, 0xF6, 0xF7, -+0xE9, 0xFF, 0x5E, 0xE7, 0x78, 0x36, 0x17, 0x00, 0xA0, 0x56, 0x17, 0x00, 0x54, 0x60, 0x17, 0x00, 0x00, 0x00, 0xFF, 0x31, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x00, 0x90, 0x15, 0x00, 0xA8, 0x56, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x20, 0x90, 0x15, 0x00, 0x00, 0x38, 0x18, 0x00, 0xDC, 0x8F, 0x15, 0x00, 0xD8, 0x83, 0x15, 0x00, 0x7C, 0x36, 0x17, 0x00, -+0x10, 0xB5, 0x0D, 0x4C, 0x30, 0x22, 0x00, 0x21, 0x20, 0x46, 0xF0, 0xF7, 0x21, 0xFF, 0x20, 0x46, 0x13, 0xF0, 0xAE, 0xFF, -+0x04, 0xF1, 0x08, 0x00, 0x13, 0xF0, 0xAA, 0xFF, 0x04, 0xF1, 0x10, 0x00, 0x13, 0xF0, 0xA6, 0xFF, 0x04, 0xF1, 0x18, 0x00, -+0x13, 0xF0, 0xA2, 0xFF, 0x04, 0xF1, 0x20, 0x00, 0xBD, 0xE8, 0x10, 0x40, 0x13, 0xF0, 0x9C, 0xBF, 0x24, 0x64, 0x17, 0x00, -+0x38, 0xB5, 0xC3, 0x6C, 0x04, 0x46, 0x09, 0x48, 0x19, 0x61, 0x00, 0xEB, 0xC2, 0x00, 0x21, 0x46, 0x15, 0x46, 0x13, 0xF0, -+0x93, 0xFF, 0x63, 0x6A, 0x9B, 0x02, 0x00, 0xD5, 0x38, 0xBD, 0x04, 0x4B, 0x53, 0xF8, 0x25, 0x00, 0xBD, 0xE8, 0x38, 0x40, -+0x13, 0xF0, 0xE6, 0xBE, 0x24, 0x64, 0x17, 0x00, 0xC4, 0x90, 0x15, 0x00, 0x38, 0xB5, 0x38, 0x4B, 0x93, 0xF8, 0x8C, 0x20, -+0x05, 0x46, 0x00, 0x2A, 0x42, 0xD1, 0x43, 0x6D, 0xC3, 0xF3, 0xC1, 0x23, 0x54, 0x22, 0x1C, 0x21, 0x33, 0x48, 0x12, 0xFB, -+0x03, 0x13, 0x18, 0x44, 0x13, 0xF0, 0xB6, 0xFF, 0x04, 0x46, 0x31, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x20, 0x00, 0x2A, -+0x01, 0xDB, 0x14, 0xB9, 0x38, 0xBD, 0x00, 0x2C, 0x4C, 0xD0, 0xA2, 0x88, 0x68, 0x6D, 0x42, 0xF0, 0x20, 0x02, 0x81, 0x01, -+0xA2, 0x80, 0xF5, 0xD5, 0xB3, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xC0, 0xF3, 0xCF, 0x31, 0xC0, 0xF3, 0xC9, 0x33, 0x26, 0xDB, -+0x62, 0x7A, 0x10, 0x3B, 0x93, 0x42, 0xE9, 0xD1, 0xEB, 0x69, 0x99, 0x68, 0x0B, 0x8A, 0x03, 0xF0, 0x1E, 0x02, 0x16, 0x2A, -+0x25, 0xD0, 0x82, 0x05, 0xE0, 0xD4, 0x2A, 0x8E, 0x1C, 0x2A, 0xDD, 0xD1, 0xA2, 0x7A, 0xB2, 0xEB, 0x13, 0x3F, 0xD9, 0xD1, -+0x04, 0xF1, 0xE0, 0x05, 0x12, 0x31, 0x28, 0x46, 0x0A, 0x22, 0x27, 0xF0, 0x37, 0xFE, 0xC4, 0xF8, 0xDC, 0x50, 0x1A, 0xE0, -+0x93, 0xF8, 0x7E, 0x30, 0x05, 0x2B, 0xBB, 0xD1, 0x14, 0x48, 0x13, 0xF0, 0x77, 0xFF, 0x04, 0x46, 0xBF, 0xE7, 0x11, 0xF4, -+0x7C, 0x7F, 0xD5, 0xD1, 0xBD, 0xE8, 0x38, 0x40, 0x10, 0x49, 0x11, 0x48, 0xD0, 0x22, 0x15, 0xF0, 0x49, 0xBB, 0x10, 0x4B, -+0x28, 0x46, 0xD3, 0xF8, 0xB4, 0x33, 0x21, 0x46, 0x98, 0x47, 0x00, 0x28, 0xB4, 0xD0, 0xA3, 0x88, 0x43, 0xF0, 0x40, 0x03, -+0xA3, 0x80, 0x38, 0xBD, 0xBD, 0xE8, 0x38, 0x40, 0x06, 0x49, 0x09, 0x48, 0x40, 0xF2, 0x5F, 0x12, 0x15, 0xF0, 0x34, 0xBB, -+0x94, 0x64, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0xE0, 0x63, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x50, 0x90, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x3C, 0x90, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xB0, 0x4B, 0xB1, 0x4C, -+0x1B, 0x68, 0xB1, 0x4A, 0xB3, 0xF9, 0x00, 0x30, 0x2D, 0xED, 0x02, 0x8B, 0x87, 0xB0, 0x01, 0x46, 0x01, 0x90, 0x00, 0x2B, -+0x04, 0xEB, 0xC0, 0x00, 0x08, 0xEE, 0x10, 0x0A, 0x52, 0xF8, 0x21, 0x40, 0xC0, 0xF2, 0x38, 0x83, 0x20, 0x46, 0x13, 0xF0, -+0x6B, 0xFE, 0xA6, 0x4B, 0x01, 0x9A, 0x53, 0xF8, 0x32, 0x40, 0x00, 0x2C, 0x00, 0xF0, 0xAD, 0x80, 0x00, 0x23, 0xCD, 0xE9, -+0x04, 0x33, 0x9B, 0x46, 0x98, 0x46, 0xA2, 0x4B, 0x62, 0x7F, 0x93, 0xF8, 0x00, 0x32, 0x03, 0x92, 0x01, 0x2B, 0x22, 0x7F, -+0xE6, 0x6C, 0x67, 0x6C, 0x02, 0x92, 0x00, 0xF0, 0xA1, 0x80, 0x00, 0x2F, 0x00, 0xF0, 0xA8, 0x80, 0x3B, 0x79, 0xD8, 0x06, -+0x40, 0xF1, 0x95, 0x80, 0x35, 0x69, 0x59, 0x06, 0x25, 0xF4, 0x00, 0x05, 0x0B, 0xF1, 0x01, 0x0B, 0x35, 0x61, 0x00, 0xF1, -+0x9B, 0x81, 0xDF, 0xF8, 0x70, 0xA2, 0x00, 0x21, 0xDA, 0xF8, 0x18, 0x34, 0x20, 0x46, 0x98, 0x47, 0x63, 0x6A, 0x03, 0xF4, -+0x60, 0x13, 0xB3, 0xF5, 0x20, 0x1F, 0x08, 0xBF, 0xA0, 0x46, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x8B, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xDF, 0xF8, 0x38, 0x92, 0xD9, 0xF8, 0x00, 0x30, 0x18, 0xEE, 0x10, 0x0A, 0x01, 0x33, -+0xC9, 0xF8, 0x00, 0x30, 0x13, 0xF0, 0xE4, 0xFE, 0x63, 0x6A, 0x03, 0xF4, 0x60, 0x13, 0xB3, 0xF5, 0x60, 0x1F, 0x00, 0xF0, -+0x5F, 0x81, 0xD9, 0xF8, 0x00, 0x30, 0x3B, 0xB1, 0x7F, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xC9, 0xF8, 0x00, 0x30, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x22, 0x8B, 0x48, 0xF6, 0x88, 0x63, 0x9A, 0x42, 0x00, 0xF0, 0x30, 0x81, 0xE2, 0x6A, 0xD3, 0x6B, -+0x98, 0x06, 0x40, 0xF1, 0xFD, 0x80, 0x15, 0xF4, 0x00, 0x05, 0x00, 0xF0, 0x7E, 0x81, 0xE1, 0x6C, 0x4F, 0x6A, 0x39, 0x88, -+0x88, 0xB2, 0x09, 0x04, 0x00, 0xF1, 0xEB, 0x81, 0x71, 0x4F, 0x3B, 0x68, 0x1B, 0x78, 0x00, 0x2B, 0x36, 0xD0, 0x63, 0x7F, -+0x09, 0x2B, 0x0E, 0xD8, 0xE2, 0x7E, 0x08, 0x2A, 0x0B, 0xD8, 0x03, 0xEB, 0xC3, 0x03, 0x13, 0x44, 0x6B, 0x49, 0xA0, 0x88, -+0x03, 0xF6, 0x0E, 0x03, 0x51, 0xF8, 0x23, 0x20, 0x12, 0x1A, 0x41, 0xF8, 0x23, 0x20, 0x68, 0x4B, 0x93, 0xF8, 0x04, 0x31, -+0x13, 0xB1, 0x00, 0x2D, 0x40, 0xF0, 0x33, 0x82, 0x06, 0xF1, 0x10, 0x01, 0x20, 0x46, 0xFF, 0xF7, 0xC9, 0xFD, 0xE3, 0x8B, -+0xDA, 0x07, 0x00, 0xF1, 0x93, 0x81, 0xA0, 0x6C, 0x30, 0xB1, 0xF7, 0xF7, 0x4F, 0xFF, 0x3B, 0x68, 0x1D, 0x78, 0x01, 0x2D, -+0x00, 0xF0, 0xCB, 0x81, 0x9D, 0xF8, 0x04, 0x00, 0x21, 0x46, 0x15, 0xF0, 0x5B, 0xFB, 0x63, 0x6A, 0x03, 0xF4, 0x60, 0x13, -+0xB3, 0xF5, 0x60, 0x1F, 0x00, 0xF0, 0x74, 0x81, 0x4F, 0x4B, 0x01, 0x9A, 0x53, 0xF8, 0x32, 0x40, 0x00, 0x2C, 0x7F, 0xF4, -+0x58, 0xAF, 0x07, 0xB0, 0xBD, 0xEC, 0x02, 0x8B, 0xBD, 0xE8, 0xF0, 0x8F, 0x4B, 0x4A, 0x00, 0x23, 0x40, 0x20, 0x82, 0xF8, -+0x00, 0x32, 0x13, 0xF0, 0x87, 0xFD, 0x00, 0x2F, 0x7F, 0xF4, 0x58, 0xAF, 0xEF, 0xF3, 0x10, 0x83, 0xDD, 0x07, 0x03, 0xD4, -+0x72, 0xB6, 0x45, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x47, 0x4D, 0x2B, 0x68, 0x18, 0xEE, 0x10, 0x0A, 0x01, 0x33, 0x2B, 0x60, -+0x13, 0xF0, 0x5A, 0xFE, 0x2B, 0x68, 0x3B, 0xB1, 0x3E, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x13, 0xB9, 0x00, 0x2A, -+0x40, 0xF0, 0xF3, 0x81, 0x20, 0x46, 0xD6, 0xF8, 0x10, 0x90, 0x94, 0xF8, 0x1C, 0xA0, 0x23, 0xF0, 0x95, 0xFF, 0xE2, 0x6A, -+0xD3, 0x6B, 0x98, 0x06, 0x40, 0xF1, 0x8C, 0x80, 0x19, 0xF4, 0x00, 0x0F, 0x0C, 0xD0, 0xE1, 0x6C, 0x4D, 0x6A, 0x29, 0x88, -+0x88, 0xB2, 0x09, 0x04, 0x00, 0xF1, 0xFE, 0x81, 0x32, 0x4B, 0x93, 0xF8, 0x04, 0x31, 0x00, 0x2B, 0x40, 0xF0, 0x86, 0x80, -+0x31, 0x4D, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x0A, 0x53, 0x93, 0xF8, 0xC0, 0x24, 0x42, 0xB1, 0x93, 0xF8, 0xC1, 0x34, -+0x2D, 0x4F, 0x03, 0xEB, 0x83, 0x03, 0xC3, 0xEB, 0xC3, 0x03, 0x07, 0xEB, 0x83, 0x07, 0x63, 0x7F, 0x09, 0x2B, 0x08, 0xD8, -+0xE3, 0x8B, 0x18, 0x07, 0x05, 0xD4, 0x09, 0xF4, 0x01, 0x09, 0xB9, 0xF5, 0x80, 0x3F, 0x00, 0xF0, 0x2B, 0x82, 0x25, 0x4F, -+0x9D, 0xF8, 0x04, 0x50, 0xD7, 0xF8, 0x18, 0x34, 0x00, 0x21, 0x20, 0x46, 0x98, 0x47, 0xD7, 0xF8, 0xAC, 0x33, 0x00, 0x22, -+0x29, 0x46, 0x20, 0x46, 0x98, 0x47, 0x22, 0x8B, 0x48, 0xF6, 0x88, 0x63, 0x9A, 0x42, 0x00, 0xF0, 0x05, 0x81, 0x63, 0x7F, -+0x09, 0x2B, 0x0E, 0xD8, 0xE2, 0x7E, 0x08, 0x2A, 0x0B, 0xD8, 0x03, 0xEB, 0xC3, 0x03, 0x13, 0x44, 0x11, 0x49, 0xA0, 0x88, -+0x03, 0xF6, 0x0E, 0x03, 0x51, 0xF8, 0x23, 0x20, 0x12, 0x1A, 0x41, 0xF8, 0x23, 0x20, 0x06, 0xF1, 0x10, 0x01, 0x20, 0x46, -+0xFF, 0xF7, 0x1C, 0xFD, 0xE3, 0x8B, 0xDB, 0x07, 0x00, 0xF1, 0x08, 0x81, 0x21, 0x46, 0x28, 0x46, 0x15, 0xF0, 0xB8, 0xFA, -+0x62, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x24, 0x64, 0x17, 0x00, 0xC4, 0x90, 0x15, 0x00, 0x20, 0x62, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x78, 0x36, 0x17, 0x00, 0x7C, 0x36, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x48, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xB7, 0x4F, 0x3B, 0x68, 0x1B, 0x78, 0x00, 0x2B, -+0x3F, 0xF4, 0x44, 0xAF, 0x15, 0xF4, 0x00, 0x05, 0x7F, 0xF4, 0x09, 0xAF, 0xB4, 0xF9, 0x1E, 0x30, 0xE2, 0x8B, 0x00, 0x2B, -+0xC0, 0xF2, 0x81, 0x80, 0x00, 0x25, 0x00, 0xE7, 0xAF, 0x4B, 0x93, 0xF8, 0x04, 0x31, 0x00, 0x2B, 0x3F, 0xF4, 0x7E, 0xAF, -+0x19, 0xF4, 0x00, 0x0F, 0x3F, 0xF4, 0x7A, 0xAF, 0xE3, 0x8B, 0x1D, 0x07, 0x3F, 0xF5, 0x76, 0xAF, 0x23, 0x7F, 0xA9, 0x4D, -+0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x03, 0x53, 0x03, 0xF1, 0x98, 0x02, 0x93, 0xF8, 0x62, 0x10, 0x20, 0x46, 0xFF, 0xF7, -+0xAF, 0xFC, 0x68, 0xE7, 0x33, 0x69, 0x03, 0xF0, 0x0F, 0x03, 0x09, 0x2B, 0x7F, 0xF4, 0xCA, 0xAE, 0x03, 0x9B, 0xA0, 0x48, -+0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x03, 0x00, 0x90, 0xF8, 0x5D, 0x32, 0x01, 0x2B, 0x3F, 0xF6, 0xBF, 0xAE, 0xE2, 0x6C, -+0xB0, 0xF8, 0x5E, 0x12, 0xD2, 0x6A, 0x8A, 0x42, 0x3F, 0xF4, 0xB8, 0xAE, 0x01, 0x33, 0x80, 0xF8, 0x5D, 0x32, 0xA0, 0xF8, -+0x5E, 0x22, 0xB1, 0xE6, 0x95, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0x9B, 0x80, 0x59, 0x46, -+0x40, 0x46, 0x04, 0x9A, 0x23, 0xF0, 0xCA, 0xFE, 0x38, 0x46, 0x02, 0xF0, 0x9D, 0xF8, 0x00, 0x23, 0x04, 0x93, 0x9B, 0x46, -+0x98, 0x46, 0x8C, 0xE6, 0xD7, 0xF8, 0xDC, 0x20, 0xDA, 0xB1, 0x11, 0x88, 0x23, 0x8C, 0xA3, 0xEB, 0x11, 0x13, 0xC3, 0xF3, -+0x0B, 0x03, 0x40, 0xF2, 0xFE, 0x71, 0x8B, 0x42, 0x0C, 0xD8, 0x3F, 0x2B, 0x4F, 0xEA, 0x13, 0x11, 0x08, 0xD8, 0x02, 0xEB, -+0x41, 0x02, 0x03, 0xF0, 0x0F, 0x03, 0x52, 0x88, 0x42, 0xFA, 0x03, 0xF3, 0xDA, 0x07, 0x04, 0xD4, 0x4F, 0xF4, 0x80, 0x23, -+0x1D, 0x43, 0x35, 0x61, 0x45, 0xE6, 0x04, 0x9B, 0x01, 0x33, 0x04, 0x93, 0x4F, 0xF4, 0x04, 0x03, 0xF6, 0xE7, 0x75, 0x4F, -+0x3B, 0x68, 0x1B, 0x78, 0x00, 0x2B, 0x3F, 0xF4, 0xBF, 0xAE, 0xB4, 0xF9, 0x1E, 0x30, 0xE2, 0x8B, 0x00, 0x2B, 0xBF, 0xF6, -+0x7F, 0xAF, 0x71, 0x4D, 0x02, 0x99, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x01, 0x53, 0x93, 0xF8, 0x64, 0x30, 0x00, 0x2B, -+0x3F, 0xF4, 0x74, 0xAF, 0xE6, 0x6C, 0x01, 0x98, 0x00, 0x21, 0xC2, 0xF3, 0x0E, 0x03, 0x31, 0x65, 0x43, 0xF0, 0x01, 0x03, -+0x61, 0x64, 0x31, 0x61, 0x02, 0x9E, 0xE3, 0x83, 0x9E, 0x30, 0xA4, 0x23, 0x13, 0xFB, 0x06, 0x00, 0xE1, 0x62, 0x61, 0x62, -+0x65, 0x4A, 0x05, 0xEB, 0xC0, 0x00, 0x21, 0x46, 0x13, 0xF0, 0x60, 0xFD, 0x63, 0x6A, 0x03, 0xF4, 0x60, 0x13, 0xB3, 0xF5, -+0x60, 0x1F, 0x00, 0xF0, 0xE4, 0x80, 0x01, 0x23, 0x05, 0x93, 0x8B, 0xE6, 0x05, 0x9B, 0x00, 0x2B, 0x40, 0xF0, 0xDC, 0x80, -+0x40, 0x20, 0x13, 0xF0, 0x1F, 0xFC, 0x00, 0x23, 0x05, 0x93, 0x81, 0xE6, 0x40, 0x20, 0x13, 0xF0, 0x19, 0xFC, 0x68, 0xE6, -+0x33, 0x69, 0x03, 0xF0, 0x0F, 0x03, 0x09, 0x2B, 0x7F, 0xF4, 0xF5, 0xAE, 0x03, 0x9B, 0x51, 0x48, 0x4F, 0xF4, 0x1E, 0x72, -+0x02, 0xFB, 0x03, 0x00, 0x90, 0xF8, 0x5D, 0x32, 0x01, 0x2B, 0x3F, 0xF6, 0xEA, 0xAE, 0xE2, 0x6C, 0xB0, 0xF8, 0x5E, 0x12, -+0xD2, 0x6A, 0x8A, 0x42, 0x3F, 0xF4, 0xE3, 0xAE, 0x01, 0x33, 0x80, 0xF8, 0x5D, 0x32, 0xA0, 0xF8, 0x5E, 0x22, 0xDC, 0xE6, -+0x40, 0x20, 0x13, 0xF0, 0xF7, 0xFB, 0xF3, 0xE6, 0xB8, 0xF1, 0x00, 0x0F, 0x7F, 0xF4, 0x61, 0xAF, 0x44, 0x49, 0x45, 0x48, -+0x40, 0xF2, 0x3D, 0x22, 0x15, 0xF0, 0xE2, 0xF8, 0x59, 0xE7, 0x00, 0xF0, 0x0C, 0x00, 0x08, 0x28, 0x7F, 0xF4, 0x10, 0xAE, -+0xD7, 0xF8, 0x1A, 0x10, 0x01, 0xF0, 0x3F, 0x01, 0x07, 0x29, 0x7F, 0xF4, 0x09, 0xAE, 0x23, 0xF0, 0x20, 0x03, 0xD3, 0x63, -+0x04, 0xE6, 0x3B, 0x4B, 0xD3, 0xE9, 0x01, 0x02, 0x13, 0x69, 0x98, 0x47, 0x06, 0x46, 0x00, 0x28, 0x3F, 0xF4, 0x2C, 0xAE, -+0xF7, 0xF7, 0x96, 0xFE, 0x07, 0x46, 0x00, 0x28, 0x00, 0xF0, 0x02, 0x81, 0x00, 0x22, 0x34, 0x4B, 0x02, 0x60, 0x1B, 0x68, -+0x42, 0x60, 0x1E, 0x44, 0x82, 0x60, 0x06, 0x60, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x02, 0xD4, 0x72, 0xB6, 0x2F, 0x4B, -+0x1D, 0x60, 0x2F, 0x49, 0xD9, 0xF8, 0x00, 0x20, 0x0B, 0x68, 0x01, 0x32, 0x43, 0xF0, 0x01, 0x03, 0xC9, 0xF8, 0x00, 0x20, -+0x0B, 0x60, 0x2A, 0x4B, 0x1B, 0x68, 0x9E, 0x07, 0xFB, 0xD4, 0x29, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x40, 0xF0, 0xE4, 0x80, -+0x27, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x40, 0xF0, 0xF0, 0x80, 0x25, 0x4B, 0x25, 0x4D, 0x1F, 0x60, 0x22, 0x48, 0xA9, 0x89, -+0x03, 0x68, 0x6F, 0x60, 0x01, 0x31, 0xA9, 0x81, 0x01, 0x33, 0x1E, 0x49, 0x03, 0x60, 0x0B, 0x68, 0x23, 0xF0, 0x01, 0x03, -+0x0B, 0x60, 0x00, 0x2A, 0x3F, 0xF4, 0xEC, 0xAD, 0x18, 0x4B, 0x01, 0x3A, 0x1B, 0x68, 0xC9, 0xF8, 0x00, 0x20, 0x00, 0x2A, -+0x7F, 0xF4, 0xE4, 0xAD, 0x00, 0x2B, 0x3F, 0xF4, 0xE1, 0xAD, 0x62, 0xB6, 0xDE, 0xE5, 0x23, 0x7F, 0x09, 0x4D, 0x4F, 0xF4, -+0xA4, 0x62, 0x02, 0xFB, 0x03, 0x55, 0x05, 0xF1, 0x98, 0x02, 0x95, 0xF8, 0x62, 0x10, 0x20, 0x46, 0xFF, 0xF7, 0x70, 0xFB, -+0xBE, 0xE5, 0x62, 0xB6, 0x0A, 0xE6, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x68, 0x65, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x61, 0xF1, 0x12, 0x00, 0x70, 0x79, 0x15, 0x00, 0x90, 0x90, 0x15, 0x00, -+0x28, 0x60, 0x17, 0x00, 0x34, 0x1A, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x60, 0x00, 0x24, 0x40, 0x64, 0x00, 0x24, 0x40, -+0x68, 0x00, 0x24, 0x40, 0x10, 0x60, 0x17, 0x00, 0x00, 0xF0, 0x0C, 0x00, 0x08, 0x28, 0x7F, 0xF4, 0xFD, 0xAD, 0xD5, 0xF8, -+0x1A, 0x10, 0x01, 0xF0, 0x3F, 0x01, 0x07, 0x29, 0x7F, 0xF4, 0xF6, 0xAD, 0x23, 0xF0, 0x20, 0x03, 0xD3, 0x63, 0xF1, 0xE5, -+0x4E, 0x4D, 0x02, 0x9B, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x03, 0x50, 0xFE, 0xF7, 0xB8, 0xFE, 0x00, 0x28, 0x3F, 0xF4, -+0x19, 0xAF, 0x4A, 0x4B, 0x93, 0xF8, 0xFF, 0x31, 0x00, 0x2B, 0x7F, 0xF4, 0x13, 0xAF, 0x01, 0x9A, 0x02, 0x99, 0xA4, 0x23, -+0x02, 0xF1, 0x9E, 0x06, 0x13, 0xFB, 0x01, 0x66, 0x03, 0xFB, 0x01, 0x23, 0x03, 0xF1, 0x9E, 0x04, 0x05, 0xEB, 0xC6, 0x06, -+0xD7, 0xB2, 0xA1, 0x46, 0x0C, 0xE0, 0x13, 0xF0, 0x09, 0xFC, 0xDA, 0xF8, 0x24, 0x34, 0x20, 0x46, 0x39, 0x46, 0x98, 0x47, -+0x3B, 0x4B, 0x93, 0xF8, 0xFF, 0x31, 0x00, 0x2B, 0x7F, 0xF4, 0xF6, 0xAE, 0x55, 0xF8, 0x39, 0x40, 0x30, 0x46, 0x00, 0x2C, -+0xED, 0xD1, 0xEF, 0xE6, 0x36, 0x4B, 0x1B, 0x68, 0x1C, 0x42, 0x7F, 0xF4, 0xC3, 0xAC, 0x35, 0x49, 0x35, 0x48, 0x4F, 0xF4, -+0xF2, 0x72, 0x14, 0xF0, 0xFD, 0xFF, 0xBB, 0xE4, 0x4F, 0xF4, 0xA4, 0x69, 0x09, 0xFB, 0x0A, 0x59, 0x99, 0xF8, 0x64, 0x10, -+0x00, 0x29, 0x3F, 0xF4, 0xCC, 0xAD, 0x2F, 0x48, 0x03, 0x99, 0x4F, 0xF4, 0x1E, 0x7C, 0x0C, 0xFB, 0x01, 0x01, 0x91, 0xF8, -+0x24, 0x10, 0x01, 0x29, 0x0F, 0xD0, 0x99, 0x07, 0x2F, 0xD4, 0x00, 0x2A, 0x3F, 0xF4, 0xBD, 0xAD, 0x97, 0xF8, 0x70, 0x30, -+0x01, 0x2B, 0x7F, 0xF4, 0xB8, 0xAD, 0x97, 0xF8, 0x85, 0x30, 0x00, 0x2B, 0x7F, 0xF4, 0xB3, 0xAD, 0xE3, 0x8B, 0xE1, 0x6C, -+0x01, 0x98, 0x22, 0x4A, 0xC3, 0xF3, 0x0E, 0x03, 0x00, 0x26, 0x43, 0xF0, 0x01, 0x03, 0x0E, 0x65, 0x0E, 0x61, 0x9E, 0x30, -+0xE3, 0x83, 0xA4, 0x23, 0x13, 0xFB, 0x0A, 0x00, 0x05, 0xEB, 0xC0, 0x00, 0xE6, 0x62, 0x21, 0x46, 0x13, 0xF0, 0xFE, 0xFB, -+0x40, 0x20, 0x13, 0xF0, 0xCB, 0xFA, 0x2F, 0xE5, 0x30, 0x46, 0xF7, 0xF7, 0x6B, 0xFC, 0x1F, 0xE5, 0x15, 0x4D, 0x6B, 0x68, -+0x9B, 0xB1, 0x5F, 0x60, 0x1E, 0xE7, 0xB4, 0xF8, 0x40, 0x00, 0x20, 0xF0, 0x75, 0xFC, 0x00, 0x28, 0xD6, 0xD0, 0x99, 0xF8, -+0xC0, 0x24, 0x00, 0x2A, 0x3F, 0xF4, 0x85, 0xAD, 0xC6, 0xE7, 0x0E, 0x48, 0x14, 0xF0, 0x2E, 0xFD, 0xD9, 0xF8, 0x00, 0x20, -+0x09, 0xE7, 0x0C, 0x48, 0x14, 0xF0, 0x28, 0xFD, 0xD9, 0xF8, 0x00, 0x20, 0x06, 0xE7, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x80, 0xB6, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x78, 0x90, 0x15, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x61, 0xF1, 0x12, 0x00, 0x10, 0x60, 0x17, 0x00, 0xA8, 0x90, 0x15, 0x00, 0xB0, 0x90, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x47, -+0x27, 0x4F, 0xDF, 0xF8, 0xA0, 0xA0, 0x91, 0x46, 0x06, 0x46, 0x0D, 0x46, 0x42, 0xF0, 0x70, 0x58, 0x28, 0x46, 0x13, 0xF0, -+0x6D, 0xFB, 0x04, 0x46, 0x80, 0xB1, 0x42, 0x6C, 0xC1, 0x6C, 0x00, 0x2A, 0x38, 0xD0, 0xC1, 0xF8, 0x10, 0x80, 0xA2, 0x88, -+0x62, 0xB9, 0x20, 0x46, 0x00, 0xF0, 0xA2, 0xF9, 0x28, 0x46, 0x13, 0xF0, 0x5D, 0xFB, 0x04, 0x46, 0x00, 0x28, 0xEE, 0xD1, -+0xBD, 0xE8, 0xF0, 0x47, 0x00, 0xF0, 0xBC, 0xB9, 0x0A, 0x69, 0x42, 0xF4, 0x00, 0x02, 0x41, 0xF8, 0x10, 0x2F, 0x20, 0x46, -+0xFF, 0xF7, 0x7E, 0xFA, 0xD7, 0xF8, 0x18, 0x34, 0x01, 0x21, 0x20, 0x46, 0x98, 0x47, 0x63, 0x7F, 0x09, 0x2B, 0x0D, 0xD8, -+0xE2, 0x7E, 0x08, 0x2A, 0x0A, 0xD8, 0x03, 0xEB, 0xC3, 0x03, 0x13, 0x44, 0x03, 0xF6, 0x0E, 0x03, 0xA1, 0x88, 0x5A, 0xF8, -+0x23, 0x20, 0x52, 0x1A, 0x4A, 0xF8, 0x23, 0x20, 0x31, 0x46, 0x20, 0x46, 0xD7, 0xF8, 0x78, 0x33, 0x98, 0x47, 0x21, 0x46, -+0x30, 0x46, 0x15, 0xF0, 0x03, 0xF8, 0xBD, 0xE7, 0x0A, 0x69, 0x00, 0x2A, 0xA8, 0xBF, 0xC1, 0xF8, 0x10, 0x90, 0xC2, 0xE7, -+0x88, 0x1A, 0x17, 0x00, 0x7C, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0x6C, 0x80, 0x92, 0x46, 0x06, 0x46, -+0x0F, 0x46, 0x42, 0xF0, 0x70, 0x59, 0x38, 0x46, 0x13, 0xF0, 0x18, 0xFB, 0x04, 0x46, 0xF0, 0xB1, 0x42, 0x6C, 0xC3, 0x6C, -+0x12, 0xB3, 0xC3, 0xF8, 0x10, 0x90, 0xA2, 0x88, 0x00, 0x21, 0x20, 0x46, 0xCA, 0xB1, 0x1D, 0x69, 0x45, 0xF4, 0x00, 0x05, -+0x1D, 0x61, 0xD8, 0xF8, 0x18, 0x34, 0x98, 0x47, 0xD8, 0xF8, 0x78, 0x33, 0x20, 0x46, 0x31, 0x46, 0x98, 0x47, 0x21, 0x46, -+0x30, 0x46, 0x14, 0xF0, 0xD1, 0xFF, 0x38, 0x46, 0x13, 0xF0, 0xFA, 0xFA, 0x04, 0x46, 0x00, 0x28, 0xE0, 0xD1, 0xBD, 0xE8, -+0xF0, 0x47, 0x00, 0xF0, 0x59, 0xB9, 0x00, 0xF0, 0x33, 0xF9, 0xD4, 0xE7, 0x1A, 0x69, 0x00, 0x2A, 0xA8, 0xBF, 0xC3, 0xF8, -+0x10, 0xA0, 0xD8, 0xE7, 0x88, 0x1A, 0x17, 0x00, 0xF8, 0xB5, 0x14, 0x46, 0x05, 0x46, 0x0F, 0x46, 0x60, 0x22, 0x00, 0x21, -+0x1E, 0x46, 0xF0, 0xF7, 0x07, 0xFA, 0x4F, 0xF0, 0x01, 0x0C, 0x85, 0xF8, 0x5C, 0xC0, 0x00, 0x23, 0x07, 0x49, 0x08, 0x4A, -+0xAF, 0x64, 0x07, 0xF1, 0x68, 0x00, 0xEE, 0x62, 0xEC, 0x64, 0xC4, 0xE9, 0x0F, 0x33, 0x60, 0x62, 0x61, 0x61, 0x23, 0x63, -+0x63, 0x64, 0x32, 0x60, 0xF8, 0xBD, 0x00, 0xBF, 0xBE, 0xBA, 0xFE, 0xCA, 0x1E, 0xAB, 0xDC, 0xBA, 0x2D, 0xE9, 0xF8, 0x4F, -+0x07, 0x46, 0x3C, 0x48, 0x3C, 0x4C, 0xDF, 0xF8, 0x08, 0xA1, 0x3C, 0x4E, 0x3C, 0x4D, 0xDF, 0xF8, 0x04, 0xB1, 0x81, 0x46, -+0x13, 0xF0, 0x70, 0xFA, 0x09, 0xF1, 0x08, 0x00, 0x13, 0xF0, 0x6C, 0xFA, 0x04, 0xF5, 0xC0, 0x78, 0x00, 0x21, 0x20, 0x46, -+0x60, 0x22, 0x17, 0xB1, 0x94, 0xF8, 0x5D, 0x30, 0xC3, 0xB9, 0xF0, 0xF7, 0xD1, 0xF9, 0x00, 0x22, 0x32, 0x4B, 0xC4, 0xF8, -+0x48, 0xA0, 0x0A, 0xF1, 0x68, 0x0C, 0xC5, 0xE9, 0x0F, 0x22, 0x21, 0x46, 0x48, 0x46, 0xE6, 0x62, 0xE5, 0x64, 0xC5, 0xF8, -+0x14, 0xB0, 0x33, 0x60, 0x84, 0xF8, 0x5C, 0x20, 0x2A, 0x63, 0x6A, 0x64, 0xC5, 0xF8, 0x24, 0xC0, 0x13, 0xF0, 0x4E, 0xFA, -+0x60, 0x34, 0xA0, 0x45, 0x0A, 0xF5, 0xF4, 0x7A, 0x06, 0xF1, 0x40, 0x06, 0x05, 0xF1, 0x58, 0x05, 0xD6, 0xD1, 0x24, 0x4E, -+0xDF, 0xF8, 0x88, 0x90, 0xC6, 0xF8, 0x00, 0x90, 0x00, 0x24, 0xC6, 0xE9, 0x0D, 0x44, 0xF4, 0x63, 0xF1, 0xF7, 0x8E, 0xFA, -+0x80, 0x03, 0x70, 0x60, 0xF1, 0xF7, 0x8A, 0xFA, 0x01, 0x27, 0x43, 0x1C, 0x07, 0xFA, 0x03, 0xF3, 0x1B, 0x4D, 0xDF, 0xF8, -+0x78, 0x80, 0xF4, 0x60, 0x01, 0x3B, 0xB3, 0x60, 0x4F, 0xF4, 0x80, 0x63, 0xC6, 0xE9, 0x04, 0x83, 0xC6, 0xE9, 0x06, 0x44, -+0x34, 0x62, 0xC5, 0xF8, 0x00, 0x90, 0xC6, 0xE9, 0x0A, 0x44, 0xC5, 0xE9, 0x0D, 0x44, 0x34, 0x63, 0xEC, 0x63, 0xF1, 0xF7, -+0x6F, 0xFA, 0x80, 0x03, 0x68, 0x60, 0xF1, 0xF7, 0x6B, 0xFA, 0x38, 0x44, 0x87, 0x40, 0x01, 0x3F, 0x04, 0x23, 0xC5, 0xE9, -+0x02, 0x74, 0xC5, 0xE9, 0x06, 0x44, 0xC5, 0xE9, 0x0A, 0x44, 0xC5, 0xF8, 0x10, 0x80, 0x2C, 0x62, 0x2C, 0x63, 0x6B, 0x61, -+0xBD, 0xE8, 0xF8, 0x8F, 0x54, 0x64, 0x17, 0x00, 0x90, 0x28, 0x17, 0x00, 0x84, 0x3B, 0x18, 0x00, 0x04, 0x3D, 0x18, 0x00, -+0x1E, 0xAB, 0xDC, 0xBA, 0xC4, 0x3C, 0x18, 0x00, 0x84, 0x3C, 0x18, 0x00, 0x4C, 0x50, 0x18, 0x00, 0xBE, 0xBA, 0xFE, 0xCA, -+0x04, 0x07, 0xFF, 0xFF, 0xF8, 0xB5, 0xD0, 0xE9, 0x12, 0x64, 0x63, 0x6A, 0x05, 0x46, 0x50, 0x1E, 0x03, 0x44, 0x04, 0x32, -+0xC4, 0xE9, 0x0A, 0x32, 0xC1, 0xB1, 0x01, 0x29, 0x1A, 0xD0, 0x06, 0xF1, 0x28, 0x01, 0x0F, 0x46, 0x34, 0x22, 0x38, 0x46, -+0x27, 0xF0, 0xD8, 0xF8, 0x0B, 0x4A, 0x13, 0x68, 0x12, 0x68, 0x1B, 0x02, 0xD2, 0xB2, 0x9B, 0xB2, 0x13, 0x43, 0x00, 0x22, -+0xF3, 0x64, 0xC4, 0xE9, 0x0D, 0x27, 0xE2, 0x64, 0x22, 0x62, 0xC5, 0xE9, 0x15, 0x22, 0xF8, 0xBD, 0x04, 0x49, 0x06, 0xF1, -+0x28, 0x07, 0xE7, 0xE7, 0x03, 0x49, 0x06, 0xF1, 0x28, 0x07, 0xE3, 0xE7, 0xA0, 0x00, 0x32, 0x40, 0xC4, 0x3C, 0x18, 0x00, -+0x84, 0x3C, 0x18, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x05, 0x48, 0x0E, 0x46, 0x13, 0xF0, 0xFE, 0xF9, 0x04, 0x46, 0x18, 0xB1, -+0x32, 0x46, 0x29, 0x46, 0xFF, 0xF7, 0xC2, 0xFF, 0x20, 0x46, 0x70, 0xBD, 0x54, 0x64, 0x17, 0x00, 0x16, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x2D, 0xE9, 0xF0, 0x41, 0xC4, 0x6C, 0x00, 0x2B, 0x62, 0x6A, 0x05, 0x46, 0x0E, 0x46, 0x16, 0xDB, -+0xE3, 0x6C, 0x11, 0x4F, 0x23, 0xF4, 0xF0, 0x03, 0xE3, 0x64, 0x00, 0x23, 0xC4, 0xE9, 0x06, 0x33, 0x12, 0x79, 0x23, 0x65, -+0x12, 0xF0, 0x01, 0x0F, 0x08, 0xBF, 0x4F, 0xF4, 0x00, 0x73, 0xA3, 0x64, 0xD7, 0xF8, 0x98, 0x33, 0x31, 0x46, 0x28, 0x46, -+0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0xD3, 0x07, 0xE6, 0xD5, 0x4F, 0xF4, 0xB1, 0x72, 0x05, 0x49, 0x05, 0x48, 0x14, 0xF0, -+0xD9, 0xFD, 0x62, 0x6A, 0xDE, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xDC, 0x90, 0x15, 0x00, 0x08, 0xB5, 0x01, 0x46, 0x04, 0x48, 0x13, 0xF0, 0x75, 0xF9, 0xBD, 0xE8, 0x08, 0x40, 0x4F, 0xF4, -+0x80, 0x20, 0x13, 0xF0, 0xCD, 0xB8, 0x00, 0xBF, 0x5C, 0x64, 0x17, 0x00, 0x70, 0xB5, 0x90, 0xF8, 0x5C, 0x30, 0x04, 0x46, -+0x0D, 0x46, 0x43, 0xB1, 0x35, 0xB1, 0x63, 0x6D, 0x23, 0xB1, 0xA0, 0x6D, 0x00, 0x21, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, -+0x70, 0xBD, 0x01, 0x46, 0x01, 0x48, 0x13, 0xF0, 0x59, 0xF9, 0xF1, 0xE7, 0x54, 0x64, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, -+0x4F, 0xF4, 0x80, 0x20, 0x13, 0xF0, 0xD2, 0xF8, 0xDF, 0xF8, 0x88, 0x80, 0x1D, 0x4F, 0x1E, 0x4E, 0x1E, 0x4D, 0xEF, 0xF3, -+0x10, 0x83, 0xDB, 0x07, 0x02, 0xD4, 0x72, 0xB6, 0x01, 0x23, 0x3B, 0x60, 0xD8, 0xF8, 0x00, 0x30, 0x30, 0x46, 0x01, 0x33, -+0xC8, 0xF8, 0x00, 0x30, 0x13, 0xF0, 0x80, 0xF9, 0xD8, 0xF8, 0x00, 0x30, 0x04, 0x46, 0x33, 0xB1, 0x01, 0x3B, 0x3A, 0x68, -+0xC8, 0xF8, 0x00, 0x30, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xD4, 0xB1, 0xD5, 0xF8, 0xF8, 0x31, 0x62, 0x6D, 0x01, 0x3B, -+0xC5, 0xF8, 0xF8, 0x31, 0x32, 0xB1, 0xE3, 0x6C, 0xA0, 0x6D, 0x19, 0x6D, 0x90, 0x47, 0x94, 0xF8, 0x5E, 0x30, 0x43, 0xB9, -+0x94, 0xF8, 0x5C, 0x30, 0x00, 0x2B, 0xD2, 0xD1, 0x08, 0x48, 0x21, 0x46, 0x13, 0xF0, 0x1A, 0xF9, 0xCD, 0xE7, 0x00, 0x23, -+0x84, 0xF8, 0x5E, 0x30, 0xC9, 0xE7, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x5C, 0x64, 0x17, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x54, 0x64, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0x78, 0x91, -+0x58, 0x4D, 0x80, 0x46, 0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, 0x08, 0x90, 0x4F, 0xF4, 0xA4, 0x63, 0x90, 0xF8, 0x22, 0xA0, -+0x03, 0xFB, 0x0A, 0x53, 0x0F, 0x46, 0x1B, 0x6C, 0x16, 0x46, 0x00, 0x2B, 0x00, 0xF0, 0x98, 0x80, 0x50, 0x49, 0x1A, 0x79, -+0x0B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x5A, 0xDB, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x0A, 0x53, 0x18, 0x21, -+0x93, 0xF8, 0xC0, 0x34, 0x13, 0x43, 0x14, 0xBF, 0x01, 0x20, 0x00, 0x20, 0xFF, 0xF7, 0x1E, 0xFF, 0x04, 0x46, 0x00, 0x28, -+0x59, 0xD0, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x0A, 0x55, 0x28, 0x46, 0x21, 0x46, 0x12, 0xF0, 0x11, 0xF8, 0x95, 0xF8, -+0x62, 0x20, 0xA3, 0x6C, 0x02, 0x2A, 0x4F, 0xD0, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x08, 0x92, 0xE8, 0x6D, 0x52, 0xF8, -+0x26, 0x1F, 0xB5, 0xF8, 0x60, 0xC0, 0xB2, 0xF8, 0x04, 0xE0, 0x15, 0x68, 0xD9, 0x66, 0x91, 0x88, 0xA3, 0xF8, 0x7C, 0x10, -+0x00, 0x22, 0x9D, 0x67, 0x01, 0x21, 0x48, 0x25, 0xA3, 0xF8, 0x70, 0xE0, 0xC3, 0xF8, 0x72, 0x00, 0xA3, 0xF8, 0x76, 0xC0, -+0x83, 0xF8, 0x6A, 0x20, 0x83, 0xF8, 0x6B, 0x20, 0x83, 0xF8, 0x68, 0x50, 0x83, 0xF8, 0x69, 0x10, 0x2E, 0x49, 0xB1, 0xF8, -+0xFC, 0x51, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x08, 0x99, 0x01, 0x35, 0xAD, 0xB2, 0xA1, 0xF8, 0xFC, 0x51, 0x99, 0xF8, -+0x22, 0x20, 0x2D, 0x01, 0xA3, 0xF8, 0x7E, 0x50, 0x20, 0x46, 0xC4, 0xE9, 0x15, 0x76, 0x22, 0x77, 0x84, 0xF8, 0x1D, 0x80, -+0x05, 0x21, 0xFF, 0xF7, 0xE3, 0xFE, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x02, 0x2A, 0xA2, 0xD1, 0x20, 0x49, 0x21, 0x48, -+0x4F, 0xF4, 0x09, 0x72, 0x14, 0xF0, 0xDC, 0xFC, 0x01, 0x20, 0x18, 0x21, 0xFF, 0xF7, 0xC4, 0xFE, 0x04, 0x46, 0x00, 0x28, -+0xA5, 0xD1, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x08, 0x91, 0xE8, 0x6D, 0x51, 0xF8, -+0x26, 0xEF, 0x83, 0xF8, 0x69, 0x20, 0x89, 0x88, 0xA3, 0xF8, 0x70, 0x10, 0x00, 0x22, 0xB5, 0xF8, 0x60, 0x10, 0xC3, 0xF8, -+0x72, 0x00, 0x4F, 0xF0, 0x48, 0x0C, 0xE8, 0x6D, 0x83, 0xF8, 0x6A, 0x20, 0x83, 0xF8, 0x6B, 0x20, 0xB5, 0xF8, 0x60, 0x20, -+0xC3, 0xF8, 0x6C, 0xE0, 0x83, 0xF8, 0x68, 0xC0, 0xA3, 0xF8, 0x76, 0x10, 0x98, 0x67, 0xA3, 0xF8, 0x7C, 0x20, 0xAD, 0xE7, -+0x04, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xCB, 0xDA, 0xC4, 0xE7, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xFC, 0x90, 0x15, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x2D, 0xE9, 0xF8, 0x4F, 0xDF, 0xF8, 0x38, 0xB1, 0x49, 0x4C, 0x4F, 0xF4, 0x1E, 0x75, 0x05, 0xFB, 0x00, 0xB5, 0x06, 0x46, -+0x95, 0xF8, 0x22, 0x70, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x07, 0x40, 0x98, 0x46, 0x00, 0x6C, 0x43, 0x4B, 0x8A, 0x46, -+0x91, 0x46, 0x00, 0x28, 0x7A, 0xD0, 0x1B, 0x68, 0x02, 0x79, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x62, 0xDB, 0x4F, 0xF4, -+0xA4, 0x63, 0x03, 0xFB, 0x07, 0x43, 0x1A, 0x21, 0x93, 0xF8, 0xC0, 0x34, 0x13, 0x43, 0x14, 0xBF, 0x01, 0x20, 0x00, 0x20, -+0xFF, 0xF7, 0x5C, 0xFE, 0x05, 0x46, 0x00, 0x28, 0x61, 0xD0, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x07, 0x47, 0x38, 0x46, -+0x29, 0x46, 0x11, 0xF0, 0x4F, 0xFF, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x06, 0xB3, 0xAC, 0x6C, 0x53, 0xF8, 0x26, 0x1F, -+0x97, 0xF8, 0x62, 0xC0, 0xB3, 0xF8, 0x04, 0xE0, 0xF8, 0x6D, 0xB7, 0xF8, 0x60, 0x20, 0xA4, 0xF8, 0x76, 0x20, 0x00, 0x23, -+0xA4, 0xF8, 0x70, 0xE0, 0xE1, 0x66, 0xC4, 0xF8, 0x72, 0x00, 0x84, 0xF8, 0x6A, 0x30, 0x84, 0xF8, 0x6B, 0x30, 0xBC, 0xF1, -+0x00, 0x0F, 0x22, 0xD0, 0xF8, 0x6D, 0xA0, 0x67, 0x6F, 0xF0, 0x37, 0x01, 0x02, 0x23, 0xA4, 0xF8, 0x7C, 0x20, 0x84, 0xF8, -+0x68, 0x10, 0x84, 0xF8, 0x69, 0x30, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x06, 0xBB, 0x00, 0x27, 0x9B, 0xF8, 0x22, 0x30, -+0xA4, 0xF8, 0x80, 0xA0, 0x84, 0xF8, 0x7E, 0x70, 0x84, 0xF8, 0x7F, 0x70, 0x28, 0x46, 0xC5, 0xE9, 0x15, 0x98, 0x2B, 0x77, -+0x6E, 0x77, 0x05, 0x21, 0xFF, 0xF7, 0x24, 0xFE, 0x38, 0x46, 0xBD, 0xE8, 0xF8, 0x8F, 0x6F, 0xF0, 0x37, 0x02, 0x01, 0x23, -+0xA1, 0x67, 0xA4, 0xF8, 0x7C, 0xE0, 0x84, 0xF8, 0x68, 0x20, 0x84, 0xF8, 0x69, 0x30, 0xDC, 0xE7, 0x02, 0x2A, 0x9A, 0xD1, -+0x0C, 0x49, 0x0D, 0x48, 0x4F, 0xF4, 0x09, 0x72, 0x14, 0xF0, 0x12, 0xFC, 0x01, 0x20, 0x1A, 0x21, 0xFF, 0xF7, 0xFA, 0xFD, -+0x05, 0x46, 0x00, 0x28, 0x9D, 0xD1, 0x01, 0x20, 0xBD, 0xE8, 0xF8, 0x8F, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0xF0, 0xDA, 0xE9, 0xE7, 0x18, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xFC, 0x90, 0x15, 0x00, -+0x68, 0x65, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0x9C, 0xA1, 0xDF, 0xF8, 0x9C, 0x81, 0x4F, 0xF4, 0x1E, 0x76, -+0x06, 0xFB, 0x00, 0xA6, 0x05, 0x46, 0x96, 0xF8, 0x22, 0x90, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x09, 0x80, 0x83, 0xB0, -+0x00, 0x6C, 0x00, 0x93, 0x0E, 0x1E, 0x17, 0x46, 0x9D, 0xF8, 0x30, 0x40, 0x9D, 0xF8, 0x34, 0xB0, 0x55, 0x4A, 0x0C, 0xBF, -+0x1E, 0x23, 0x1D, 0x23, 0x00, 0x28, 0x00, 0xF0, 0x9D, 0x80, 0x12, 0x68, 0x01, 0x79, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, -+0xC0, 0xF2, 0x85, 0x80, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x09, 0x82, 0x92, 0xF8, 0xC0, 0x24, 0x0A, 0x43, 0x14, 0xBF, -+0x01, 0x20, 0x00, 0x20, 0x19, 0x46, 0xFF, 0xF7, 0xAF, 0xFD, 0x03, 0x46, 0x00, 0x28, 0x00, 0xF0, 0x81, 0x80, 0x4F, 0xF4, -+0xA4, 0x62, 0x02, 0xFB, 0x09, 0x88, 0xD0, 0xF8, 0x48, 0x90, 0x01, 0x93, 0x40, 0x46, 0x19, 0x46, 0x11, 0xF0, 0x9E, 0xFE, -+0xD9, 0xF8, 0x38, 0x00, 0x01, 0x9B, 0x40, 0x4A, 0x99, 0x6C, 0xB8, 0xF8, 0x60, 0xE0, 0x00, 0x0C, 0x4F, 0xF0, 0x00, 0x0C, -+0x46, 0xEA, 0x07, 0x17, 0x00, 0x04, 0xC9, 0xF8, 0x38, 0x00, 0xD8, 0xF8, 0x5C, 0x00, 0x8F, 0x67, 0x81, 0xF8, 0x7C, 0xC0, -+0x81, 0xF8, 0x7D, 0xC0, 0x81, 0xF8, 0x7E, 0xC0, 0x81, 0xF8, 0x7F, 0xC0, 0x92, 0xF8, 0x43, 0x70, 0xDF, 0xF8, 0xE8, 0x80, -+0xC1, 0xF8, 0x72, 0x00, 0x24, 0x20, 0xB8, 0xF8, 0x04, 0x20, 0xA1, 0xF8, 0x76, 0xE0, 0x81, 0xF8, 0x68, 0x00, 0xD8, 0xF8, -+0x00, 0xE0, 0xA1, 0xF8, 0x70, 0x20, 0xB8, 0x06, 0xC1, 0xF8, 0x6C, 0xE0, 0x81, 0xF8, 0x69, 0xC0, 0x81, 0xF8, 0x6A, 0xC0, -+0x81, 0xF8, 0x6B, 0xC0, 0xC7, 0xF3, 0x40, 0x12, 0x0B, 0xD5, 0x27, 0x48, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x05, 0x02, -+0x52, 0x78, 0x12, 0xF0, 0x20, 0x0F, 0x0C, 0xBF, 0x62, 0x46, 0x4F, 0xF4, 0x80, 0x12, 0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, -+0x05, 0xA5, 0x64, 0x05, 0x28, 0x8C, 0x00, 0x9D, 0x44, 0xEA, 0x45, 0x34, 0x04, 0x43, 0x14, 0x43, 0xD8, 0x22, 0xC1, 0xF8, -+0x80, 0x40, 0x81, 0xF8, 0x84, 0x20, 0x6E, 0xB1, 0x0E, 0x9A, 0x5A, 0x65, 0x0F, 0x9A, 0x9A, 0x65, 0x59, 0x46, 0x18, 0x46, -+0xFF, 0xF7, 0x54, 0xFD, 0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x12, 0x4A, 0x12, 0xF8, -+0x0B, 0x20, 0x92, 0x01, 0x81, 0xF8, 0x85, 0x20, 0xEA, 0xE7, 0x02, 0x29, 0x7F, 0xF4, 0x78, 0xAF, 0x0E, 0x48, 0x0F, 0x49, -+0x01, 0x93, 0x4F, 0xF4, 0x09, 0x72, 0x14, 0xF0, 0x41, 0xFB, 0x01, 0x9B, 0x01, 0x20, 0x77, 0xE7, 0x01, 0x20, 0x03, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0x12, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xEC, 0xDB, 0x01, 0x20, 0x6C, 0xE7, 0x00, 0xBF, -+0x38, 0x36, 0x17, 0x00, 0xE4, 0xB8, 0x17, 0x00, 0x62, 0x66, 0x17, 0x00, 0xA0, 0xB2, 0x15, 0x00, 0xFC, 0x90, 0x15, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x68, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0xAC, 0xB2, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x43, -+0x90, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0x77, 0xD1, 0x03, 0x6C, 0x04, 0x46, 0x89, 0x46, 0x00, 0x2B, 0x79, 0xD0, 0x40, 0x4A, -+0x1B, 0x79, 0x12, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x51, 0xDB, 0x94, 0xF8, 0xC0, 0x24, 0xDF, 0xF8, 0x08, 0x81, -+0x13, 0x43, 0xB8, 0xF8, 0x00, 0x10, 0x14, 0xBF, 0x01, 0x20, 0x00, 0x20, 0xFF, 0xF7, 0xEE, 0xFC, 0x06, 0x46, 0x00, 0x28, -+0x54, 0xD0, 0x01, 0x46, 0x20, 0x46, 0x11, 0xF0, 0xE5, 0xFD, 0xB5, 0x6C, 0x00, 0x27, 0x50, 0x23, 0x49, 0x46, 0x85, 0xF8, -+0x68, 0x30, 0x85, 0xF8, 0x69, 0x70, 0x85, 0xF8, 0x6A, 0x70, 0x85, 0xF8, 0x6B, 0x70, 0x05, 0xF1, 0x6C, 0x00, 0x06, 0x22, -+0x26, 0xF0, 0x90, 0xFD, 0x2B, 0x49, 0xE0, 0x6D, 0xB1, 0xF8, 0xFC, 0x31, 0xB4, 0xF8, 0x60, 0xC0, 0xB8, 0xF8, 0x00, 0x20, -+0xB4, 0xF8, 0x60, 0xE0, 0xC5, 0xF8, 0x72, 0x00, 0x01, 0x33, 0x9B, 0xB2, 0xE0, 0x6D, 0xA5, 0xF8, 0x76, 0xC0, 0x4F, 0xEA, -+0x03, 0x1C, 0xA8, 0x67, 0xA5, 0xF8, 0x7C, 0xE0, 0x18, 0x3A, 0xA1, 0xF8, 0xFC, 0x31, 0x05, 0xF1, 0x80, 0x00, 0xA5, 0xF8, -+0x7E, 0xC0, 0x1E, 0x49, 0x26, 0xF0, 0x70, 0xFD, 0xC6, 0xE9, 0x15, 0x77, 0x94, 0xF8, 0x63, 0x30, 0x33, 0x77, 0xFF, 0x23, -+0x73, 0x77, 0x30, 0x46, 0x05, 0x21, 0xFF, 0xF7, 0xBB, 0xFC, 0x38, 0x46, 0xBD, 0xE8, 0xF8, 0x83, 0x02, 0x2B, 0xAB, 0xD1, -+0x15, 0x49, 0x16, 0x48, 0x4F, 0xF4, 0x09, 0x72, 0x14, 0xF0, 0xB4, 0xFA, 0xDF, 0xF8, 0x58, 0x80, 0x01, 0x20, 0xB8, 0xF8, -+0x00, 0x10, 0xFF, 0xF7, 0x99, 0xFC, 0x06, 0x46, 0x00, 0x28, 0xAA, 0xD1, 0xB8, 0xF8, 0x00, 0x10, 0x0E, 0x48, 0x14, 0xF0, -+0x2B, 0xF8, 0x01, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x0C, 0x48, 0x19, 0x46, 0x14, 0xF0, 0x24, 0xF8, 0x01, 0x20, 0xBD, 0xE8, -+0xF8, 0x83, 0x03, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xE0, 0xDA, 0xD9, 0xE7, 0x38, 0x36, 0x17, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x2C, 0x2A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xFC, 0x90, 0x15, 0x00, 0x28, 0x91, 0x15, 0x00, -+0x14, 0x91, 0x15, 0x00, 0x14, 0x2C, 0x17, 0x00, 0x02, 0x4B, 0x40, 0xEA, 0x41, 0x01, 0x33, 0xF8, 0x11, 0x00, 0x70, 0x47, -+0xA0, 0x92, 0x15, 0x00, 0x02, 0x4B, 0x40, 0xEA, 0x41, 0x01, 0x58, 0x5C, 0x70, 0x47, 0x00, 0xBF, 0x40, 0x93, 0x15, 0x00, -+0xF0, 0xB4, 0x1D, 0x4C, 0x1D, 0x4D, 0x1E, 0x4F, 0x4F, 0xF4, 0x1E, 0x76, 0x06, 0xFB, 0x02, 0x42, 0x16, 0x46, 0x92, 0xF8, -+0x22, 0x40, 0x4F, 0xF4, 0xA4, 0x6C, 0x0C, 0xFB, 0x04, 0x54, 0x56, 0xF8, 0x26, 0x5F, 0xB4, 0xF8, 0x60, 0xC0, 0x02, 0x46, -+0xE0, 0x6D, 0xB4, 0x88, 0xA2, 0xF8, 0x9C, 0x40, 0x00, 0x24, 0x54, 0x65, 0xC2, 0xF8, 0x8C, 0x40, 0x3C, 0x68, 0x3E, 0x68, -+0x9D, 0xF8, 0x10, 0x70, 0xC2, 0xF8, 0x9E, 0x00, 0x24, 0x02, 0xF6, 0xB2, 0x1B, 0x03, 0xA4, 0xB2, 0x40, 0xF6, 0x08, 0x00, -+0x34, 0x43, 0x40, 0xEA, 0xC7, 0x10, 0x43, 0xF0, 0x04, 0x03, 0x09, 0x01, 0xC2, 0xF8, 0x98, 0x50, 0xC2, 0xF8, 0xCC, 0x40, -+0xA2, 0xF8, 0xA2, 0xC0, 0xF0, 0xBC, 0xA2, 0xF8, 0xA4, 0x30, 0xA2, 0xF8, 0xA6, 0x10, 0xC2, 0xF8, 0xBC, 0x00, 0x70, 0x47, -+0x68, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0xA0, 0x00, 0x32, 0x40, 0xC2, 0x6C, 0x53, 0x6A, 0x13, 0xB3, 0x12, 0x49, -+0x12, 0x4B, 0xC9, 0x6E, 0x10, 0xB5, 0x04, 0x46, 0x18, 0x68, 0x63, 0x6A, 0x92, 0x6A, 0x03, 0xF4, 0x60, 0x13, 0xB3, 0xF5, -+0x60, 0x1F, 0x42, 0xF8, 0x03, 0x1C, 0x08, 0xD0, 0xB0, 0xF9, 0x00, 0x30, 0x24, 0x68, 0x00, 0x2B, 0x04, 0xDB, 0xE2, 0x6C, -+0x53, 0x6A, 0x00, 0x2B, 0xED, 0xD1, 0x10, 0xBD, 0x00, 0x2C, 0xF8, 0xD1, 0x06, 0x49, 0x07, 0x48, 0x40, 0xF2, 0xF9, 0x22, -+0x14, 0xF0, 0x0E, 0xFA, 0xE3, 0x6C, 0xFF, 0xDE, 0x70, 0x47, 0x00, 0xBF, 0x94, 0x64, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x3C, 0x91, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x89, 0xB0, 0x04, 0x46, 0x9D, 0xF8, 0x48, 0x00, -+0x67, 0x6C, 0x07, 0x90, 0x9B, 0x46, 0x05, 0x28, 0x4F, 0xF0, 0x00, 0x03, 0x06, 0x91, 0x03, 0x92, 0x9A, 0x46, 0x00, 0xF0, -+0x12, 0x81, 0xAA, 0x4A, 0x00, 0xEB, 0x40, 0x03, 0xC3, 0xEB, 0xC3, 0x03, 0x02, 0xEB, 0x83, 0x03, 0x04, 0x93, 0xDF, 0xF8, -+0xC8, 0x92, 0xA6, 0x48, 0x12, 0xF0, 0xD4, 0xFD, 0xD9, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x05, 0x46, -+0xC0, 0xF2, 0xF3, 0x80, 0xBB, 0x88, 0xAB, 0x80, 0x7B, 0x7A, 0x6B, 0x72, 0xBB, 0x7A, 0xAB, 0x72, 0x01, 0x23, 0xEB, 0x72, -+0xD7, 0xE9, 0x10, 0xC0, 0xFE, 0x6A, 0x79, 0x69, 0x3A, 0x6B, 0xEE, 0x62, 0x00, 0x23, 0x1E, 0x46, 0x69, 0x61, 0x6B, 0x62, -+0x19, 0x46, 0x98, 0x46, 0x02, 0x93, 0x05, 0xF1, 0x0C, 0x03, 0xC5, 0xE9, 0x10, 0xC0, 0x2A, 0x63, 0x05, 0x93, 0x01, 0x96, -+0x53, 0xE0, 0x9B, 0x45, 0x40, 0xF2, 0xB4, 0x80, 0xAB, 0xEB, 0x03, 0x0A, 0x1F, 0xFA, 0x8A, 0xFA, 0x0A, 0xF1, 0x03, 0x0A, -+0x4F, 0xEA, 0x9A, 0x0A, 0x03, 0xEB, 0x8A, 0x03, 0x9B, 0xB2, 0x03, 0x9E, 0x19, 0x44, 0xB1, 0x42, 0x5A, 0xD8, 0xB8, 0xF1, -+0x00, 0x0F, 0x57, 0xD1, 0xDE, 0xF8, 0x24, 0x00, 0x28, 0xB1, 0x87, 0x4E, 0xDE, 0xF8, 0x28, 0x00, 0xF6, 0x6E, 0x40, 0xF8, -+0x03, 0x6C, 0xDC, 0x45, 0x65, 0x64, 0x0D, 0xD2, 0xDE, 0xF8, 0x4C, 0x20, 0x22, 0xF4, 0xFF, 0x22, 0x22, 0xF4, 0xC0, 0x62, -+0x42, 0xEA, 0x4A, 0x22, 0x42, 0xF4, 0x80, 0x70, 0x62, 0x62, 0x63, 0x46, 0xCE, 0xF8, 0x4C, 0x00, 0x69, 0x62, 0x79, 0x6A, -+0x02, 0xF4, 0x60, 0x12, 0xCB, 0x1A, 0xB2, 0xF5, 0x60, 0x1F, 0x7B, 0x62, 0x00, 0xF0, 0xAA, 0x80, 0x77, 0x4A, 0xD9, 0xF8, -+0x00, 0x30, 0x11, 0x68, 0x76, 0x4A, 0x91, 0xF8, 0x3E, 0x80, 0x12, 0x68, 0xB3, 0xF9, 0x00, 0x10, 0x23, 0x68, 0x02, 0xF0, -+0x3F, 0x02, 0x90, 0x45, 0x94, 0xBF, 0x4F, 0xF0, 0x00, 0x08, 0x4F, 0xF0, 0x01, 0x08, 0x00, 0x29, 0x5D, 0xDB, 0x01, 0x9A, -+0x69, 0x6A, 0x02, 0x94, 0x01, 0x32, 0x01, 0x92, 0x1C, 0x46, 0xD4, 0xF8, 0x4C, 0xE0, 0x62, 0x6A, 0xDE, 0xF8, 0x2C, 0x30, -+0x9D, 0xF8, 0x04, 0x00, 0x03, 0x33, 0x23, 0xF0, 0x03, 0x03, 0x04, 0x33, 0x9B, 0xB2, 0xC2, 0xF3, 0x49, 0x2C, 0x03, 0xEB, -+0x8C, 0x0C, 0x1F, 0xFA, 0x8C, 0xFC, 0xDC, 0x45, 0x97, 0xD3, 0x03, 0x9E, 0x63, 0x46, 0x19, 0x44, 0xB1, 0x42, 0xA4, 0xD9, -+0x02, 0x9B, 0x00, 0x2B, 0x00, 0xF0, 0xA2, 0x80, 0x02, 0x9B, 0x5B, 0x6A, 0x03, 0xF4, 0x60, 0x12, 0xB2, 0xF5, 0x20, 0x1F, -+0x41, 0xD0, 0x02, 0x9E, 0xF2, 0x6C, 0x43, 0xF4, 0x60, 0x11, 0x43, 0xF4, 0x60, 0x13, 0x50, 0x73, 0xC5, 0xF8, 0x38, 0x61, -+0x73, 0x62, 0xD9, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x41, 0xF4, 0x80, 0x71, 0x00, 0x20, 0x00, 0x2B, 0xD1, 0x64, -+0xD0, 0x61, 0x3D, 0xDB, 0x04, 0x9A, 0x92, 0xF8, 0x50, 0x30, 0x01, 0x33, 0x82, 0xF8, 0x50, 0x30, 0x63, 0x6A, 0x03, 0xF4, -+0x60, 0x13, 0xB3, 0xF5, 0x60, 0x1F, 0x73, 0xD0, 0x1C, 0x32, 0x16, 0x46, 0x48, 0x4B, 0x06, 0x9A, 0x1B, 0x68, 0x14, 0x60, -+0x5B, 0x78, 0x13, 0xB9, 0x63, 0x6C, 0x0C, 0x33, 0x2B, 0x61, 0x29, 0x46, 0x30, 0x46, 0x12, 0xF0, 0xE7, 0xFC, 0x05, 0x98, -+0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x2B, 0x9F, 0xD1, 0x40, 0x49, 0x40, 0x48, 0x02, 0x93, 0x40, 0xF2, 0xBD, 0x32, -+0x14, 0xF0, 0x0A, 0xF9, 0x02, 0x9B, 0x96, 0xE7, 0x4F, 0xF0, 0x00, 0x0A, 0x53, 0xE7, 0x02, 0x9E, 0x3B, 0x4B, 0x01, 0x21, -+0xD3, 0xF8, 0x58, 0x33, 0x30, 0x46, 0x98, 0x47, 0xF3, 0x6C, 0x75, 0x64, 0x14, 0x33, 0x05, 0x93, 0xD9, 0xF8, 0x00, 0x30, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC1, 0xDA, 0x04, 0x9B, 0xDB, 0x69, 0x9F, 0x42, 0xBD, 0xD0, 0x2F, 0x49, 0x32, 0x48, -+0x40, 0xF2, 0xC3, 0x32, 0x14, 0xF0, 0xEA, 0xF8, 0xB6, 0xE7, 0x00, 0x28, 0x7F, 0xF4, 0x0A, 0xAF, 0x2A, 0x49, 0x2E, 0x48, -+0x40, 0xF2, 0x27, 0x32, 0x14, 0xF0, 0xE0, 0xF8, 0x02, 0xE7, 0x2C, 0x4B, 0x04, 0x93, 0xF2, 0xE6, 0xD9, 0xF8, 0x00, 0x30, -+0xC5, 0xF8, 0x38, 0x41, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x16, 0xDB, 0x04, 0x9E, 0x1C, 0x36, 0x30, 0x46, 0x12, 0xF0, -+0xBF, 0xFC, 0x1E, 0x4B, 0x1B, 0x68, 0x5B, 0x78, 0x0B, 0xB9, 0x3B, 0x69, 0x2B, 0x61, 0x39, 0x46, 0xD7, 0xF8, 0x48, 0x01, -+0x12, 0xF0, 0x70, 0xFC, 0x06, 0x99, 0x22, 0x68, 0xE3, 0x6C, 0x0A, 0x60, 0x00, 0x22, 0xDA, 0x61, 0xA1, 0xE7, 0x04, 0x9B, -+0xDB, 0x69, 0xBB, 0x42, 0xE4, 0xD0, 0x14, 0x49, 0x16, 0x48, 0x40, 0xF2, 0xC3, 0x32, 0x14, 0xF0, 0xB3, 0xF8, 0xDD, 0xE7, -+0x04, 0x9E, 0x1C, 0x36, 0x30, 0x46, 0x12, 0xF0, 0x9D, 0xFC, 0x87, 0xE7, 0x0F, 0x4B, 0x07, 0x99, 0xD3, 0xF8, 0xBC, 0x33, -+0x07, 0xF1, 0x0C, 0x00, 0x98, 0x47, 0x02, 0x9B, 0xD5, 0xF8, 0x48, 0x01, 0x05, 0x93, 0x29, 0x46, 0x12, 0xF0, 0x4A, 0xFC, -+0x85, 0xE7, 0x00, 0xBF, 0x20, 0x62, 0x17, 0x00, 0x8C, 0x64, 0x17, 0x00, 0x94, 0x64, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, -+0x54, 0x83, 0x32, 0x40, 0x34, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x3C, 0x91, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x64, 0x91, 0x15, 0x00, 0x4C, 0x91, 0x15, 0x00, 0xC4, 0x63, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x0C, 0x46, 0x41, 0x7F, 0x63, 0x7F, 0x99, 0x42, 0x85, 0xB0, 0x05, 0xD1, 0xE3, 0x7E, 0x16, 0x46, 0xC2, 0x7E, 0x9A, 0x42, -+0x05, 0x46, 0x03, 0xD0, 0x00, 0x20, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xD4, 0xE9, 0x11, 0x73, 0x00, 0x2B, 0x00, 0xF0, -+0x8F, 0x80, 0xBB, 0x88, 0x13, 0xF0, 0x08, 0x00, 0xF3, 0xD0, 0x13, 0xF0, 0x02, 0x00, 0xF0, 0xD0, 0x13, 0xF0, 0x01, 0x00, -+0x40, 0xF0, 0x86, 0x80, 0xDF, 0xF8, 0x4C, 0x91, 0x54, 0x23, 0x03, 0xFB, 0x06, 0x93, 0x93, 0xF8, 0x4D, 0x20, 0x01, 0x2A, -+0xE3, 0xD0, 0xD3, 0xF8, 0x34, 0x80, 0xD8, 0xE9, 0x12, 0xBA, 0xBB, 0xF1, 0x00, 0x0F, 0x05, 0xD0, 0xDA, 0xF8, 0x20, 0x20, -+0x46, 0x4B, 0x12, 0x68, 0x9A, 0x42, 0xD6, 0xD1, 0x45, 0x4A, 0x46, 0x4B, 0x11, 0x68, 0x1A, 0x68, 0x91, 0xF8, 0x3E, 0x30, -+0x91, 0xF8, 0x3F, 0x10, 0x02, 0xF0, 0x3F, 0x02, 0x0B, 0x44, 0x9A, 0x42, 0xC8, 0xDD, 0xD8, 0xF8, 0x24, 0x20, 0x54, 0x23, -+0x03, 0xFB, 0x06, 0x93, 0x42, 0xF4, 0x60, 0x12, 0x18, 0x6B, 0xC8, 0xF8, 0x24, 0x20, 0xC7, 0xF8, 0x38, 0x81, 0x03, 0x93, -+0x03, 0xF0, 0xE0, 0xF8, 0x39, 0x4A, 0x03, 0x9B, 0x12, 0x68, 0x93, 0xF8, 0x4D, 0x10, 0x8A, 0xF8, 0x0D, 0x10, 0x52, 0x78, -+0x00, 0x2A, 0x4F, 0xD1, 0xEB, 0x6C, 0x3A, 0x61, 0xD9, 0x6C, 0xCA, 0xE9, 0x06, 0x22, 0x8A, 0x02, 0x44, 0xD5, 0x6B, 0x6C, -+0x07, 0xF1, 0x0C, 0x01, 0x19, 0x61, 0x54, 0x23, 0x03, 0xFB, 0x06, 0xF3, 0x0A, 0xF1, 0x14, 0x00, 0x09, 0xEB, 0x03, 0x02, -+0x49, 0xF8, 0x03, 0x00, 0x01, 0x23, 0xC2, 0xE9, 0x01, 0x13, 0xD8, 0xF8, 0x24, 0x30, 0xBA, 0x88, 0x43, 0xF4, 0x80, 0x73, -+0xCA, 0xF8, 0x4C, 0x30, 0x42, 0xF0, 0x01, 0x03, 0xBB, 0x80, 0xBB, 0xF1, 0x00, 0x0F, 0x08, 0xD0, 0x50, 0x07, 0x06, 0xD4, -+0x11, 0x07, 0x37, 0xD4, 0xA1, 0x6C, 0x4A, 0x6A, 0x42, 0xF0, 0x04, 0x02, 0x4A, 0x62, 0x9B, 0x07, 0x06, 0xD5, 0x54, 0x23, -+0x03, 0xFB, 0x06, 0x93, 0x3A, 0x6B, 0x1B, 0x6B, 0x9B, 0x6A, 0x53, 0x61, 0x54, 0x24, 0x04, 0xFB, 0x06, 0x90, 0x04, 0xFB, -+0x06, 0x96, 0x1C, 0x30, 0x39, 0x46, 0x12, 0xF0, 0x91, 0xFB, 0x96, 0xF8, 0x50, 0x30, 0x00, 0x22, 0x01, 0x33, 0xF2, 0x62, -+0x86, 0xF8, 0x50, 0x30, 0x01, 0x20, 0x68, 0xE7, 0xBB, 0x88, 0x72, 0xE7, 0x01, 0x20, 0x64, 0xE7, 0x07, 0xF1, 0x0C, 0x01, -+0x99, 0x61, 0xBA, 0xE7, 0xB8, 0x7A, 0x93, 0xF8, 0x4E, 0x30, 0x7A, 0x7A, 0xB8, 0xF8, 0x22, 0x10, 0x00, 0x93, 0x03, 0x46, -+0x38, 0x46, 0xFF, 0xF7, 0x55, 0xFD, 0x07, 0xF1, 0x50, 0x03, 0xCA, 0xF8, 0x1C, 0x30, 0xB6, 0xE7, 0x42, 0xF0, 0x03, 0x03, -+0xBB, 0x80, 0xC8, 0xE7, 0xDE, 0xFA, 0xFE, 0xCA, 0xC8, 0x35, 0x17, 0x00, 0x54, 0x83, 0x32, 0x40, 0x34, 0x36, 0x17, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x45, 0x6C, 0x0C, 0x68, 0x6E, 0x7A, 0x60, 0x7F, 0x9D, 0xF8, 0x20, 0x70, -+0x86, 0x42, 0x03, 0xD1, 0xAE, 0x7A, 0xE0, 0x7E, 0x86, 0x42, 0x02, 0xD0, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0xE6, 0x6C, -+0xD5, 0xF8, 0x38, 0xE1, 0xD6, 0xF8, 0x24, 0xC0, 0xDE, 0xF8, 0x4C, 0x80, 0xBC, 0xF1, 0x00, 0x0F, 0x00, 0xF0, 0x82, 0x80, -+0xBC, 0xF8, 0x00, 0x90, 0x19, 0xF4, 0x00, 0x4F, 0x1F, 0xFA, 0x89, 0xF0, 0x7A, 0xD1, 0x6F, 0xEA, 0x40, 0x40, 0x6F, 0xEA, -+0x50, 0x40, 0xAC, 0xF8, 0x00, 0x00, 0x94, 0xF8, 0x33, 0x90, 0x94, 0xF8, 0x32, 0x00, 0x09, 0xF1, 0x04, 0x09, 0x04, 0x30, -+0x84, 0xF8, 0x33, 0x90, 0x84, 0xF8, 0x32, 0x00, 0xF0, 0x6A, 0x00, 0xF1, 0x04, 0x0A, 0xB0, 0x6A, 0x00, 0xF1, 0x04, 0x09, -+0xC6, 0xE9, 0x0A, 0x9A, 0x0A, 0xF1, 0x03, 0x00, 0x20, 0xF0, 0x03, 0x00, 0x04, 0x30, 0x80, 0xB2, 0x83, 0x42, 0x5C, 0xD9, -+0xA3, 0xEB, 0x00, 0x09, 0x1F, 0xFA, 0x89, 0xF9, 0x09, 0xF1, 0x03, 0x09, 0x4F, 0xEA, 0x99, 0x09, 0x00, 0xEB, 0x89, 0x00, -+0x80, 0xB2, 0x6B, 0x6A, 0x18, 0x44, 0x90, 0x42, 0xBA, 0xD8, 0x28, 0x4A, 0xDE, 0xF8, 0x24, 0x30, 0x4F, 0xF0, 0x54, 0x0A, -+0x0A, 0xFB, 0x07, 0x27, 0x23, 0xF4, 0xC0, 0x13, 0x97, 0xF8, 0x50, 0x20, 0xDF, 0xF8, 0x90, 0xA0, 0x01, 0x3A, 0x87, 0xF8, -+0x50, 0x20, 0x43, 0xF4, 0x40, 0x12, 0xCE, 0xF8, 0x24, 0x20, 0x62, 0x6A, 0xDA, 0xF8, 0x00, 0x70, 0xD4, 0xF8, 0x00, 0xE0, -+0x22, 0xF4, 0xC0, 0x12, 0x42, 0xEA, 0x49, 0x29, 0x43, 0xF4, 0x40, 0x13, 0x49, 0xF4, 0xF0, 0x0A, 0x43, 0xF4, 0x80, 0x73, -+0xC8, 0xF8, 0x4C, 0x30, 0x49, 0xF4, 0xF0, 0x02, 0x00, 0x23, 0x4A, 0xF4, 0x80, 0x7A, 0x06, 0xF1, 0x14, 0x09, 0xC8, 0xF8, -+0x1C, 0x90, 0x62, 0x62, 0xC6, 0xF8, 0x4C, 0xA0, 0xB3, 0x61, 0xB3, 0x63, 0x68, 0x62, 0x65, 0x64, 0xC5, 0xF8, 0x38, 0x41, -+0xC1, 0xF8, 0x00, 0xE0, 0x7B, 0x78, 0x03, 0xB9, 0x2B, 0x61, 0xBC, 0xF1, 0x00, 0x0F, 0x04, 0xD0, 0x09, 0x4A, 0xB3, 0x6A, -+0xD2, 0x6E, 0x43, 0xF8, 0x03, 0x2C, 0x98, 0xF8, 0x0D, 0x30, 0x01, 0x33, 0x73, 0x73, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x87, -+0xD6, 0xF8, 0x2C, 0xA0, 0x9A, 0xE7, 0x4F, 0xF0, 0x00, 0x09, 0xAA, 0xE7, 0x20, 0x62, 0x17, 0x00, 0x94, 0x64, 0x17, 0x00, -+0x34, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x85, 0xB0, 0xD1, 0xF8, 0x00, 0xB0, 0x9D, 0xF8, 0x38, 0x90, 0xDF, 0xF8, -+0x20, 0xA1, 0xDB, 0xF8, 0x44, 0x60, 0xDA, 0xF8, 0x60, 0x43, 0x03, 0x93, 0x0F, 0x46, 0x90, 0x46, 0x59, 0x46, 0x4A, 0x46, -+0x05, 0x46, 0xA0, 0x47, 0x00, 0x28, 0x60, 0xD0, 0xE9, 0x6C, 0x03, 0x9B, 0xCA, 0x6A, 0x02, 0xF1, 0x03, 0x0E, 0x2E, 0xF0, -+0x03, 0x0E, 0x0E, 0xF1, 0x04, 0x0E, 0x1F, 0xFA, 0x8E, 0xFE, 0x73, 0x45, 0x01, 0xF1, 0x14, 0x0C, 0x54, 0xD8, 0x00, 0x20, -+0x72, 0x6A, 0x0E, 0xEB, 0x02, 0x03, 0x43, 0x45, 0x05, 0xD9, 0x34, 0x4A, 0x12, 0x68, 0x02, 0xF0, 0x3F, 0x02, 0x11, 0x2A, -+0x5D, 0xD9, 0x32, 0x4A, 0x6C, 0x6A, 0x4F, 0xF0, 0x54, 0x0E, 0x0E, 0xFB, 0x09, 0x22, 0x24, 0xF4, 0xC0, 0x14, 0x92, 0xF8, -+0x50, 0xE0, 0x44, 0xEA, 0x40, 0x24, 0x0E, 0xF1, 0xFF, 0x30, 0x82, 0xF8, 0x50, 0x00, 0x44, 0xF4, 0xD0, 0x0E, 0x72, 0x69, -+0xCA, 0x61, 0xC6, 0xF8, 0x14, 0xC0, 0x73, 0x62, 0xC5, 0xF8, 0x24, 0xE0, 0xDB, 0xF8, 0x24, 0x20, 0xD6, 0xF8, 0x38, 0xC1, -+0x6E, 0x64, 0x22, 0xF4, 0xC0, 0x12, 0x74, 0x46, 0x42, 0xF4, 0x40, 0x10, 0xDB, 0xF8, 0x4C, 0xE0, 0xDC, 0xF8, 0x4C, 0xC0, -+0x44, 0xF4, 0x80, 0x74, 0xCC, 0x64, 0x42, 0xF4, 0x40, 0x12, 0x40, 0xF4, 0x80, 0x70, 0x00, 0x24, 0x8C, 0x63, 0xCB, 0xF8, -+0x24, 0x20, 0xCE, 0xF8, 0x4C, 0x00, 0x9C, 0xF8, 0x0D, 0x20, 0x43, 0x45, 0x02, 0xF1, 0x01, 0x02, 0x8C, 0xF8, 0x0D, 0x20, -+0x16, 0xD9, 0xDA, 0xF8, 0x70, 0x63, 0x03, 0x9B, 0xCD, 0xF8, 0x00, 0x90, 0x42, 0x46, 0x39, 0x46, 0x28, 0x46, 0xB0, 0x47, -+0x20, 0x46, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xA3, 0xEB, 0x0E, 0x04, 0xA4, 0xB2, 0x03, 0x34, 0xA0, 0x08, 0x0E, 0xEB, -+0x80, 0x0E, 0x1F, 0xFA, 0x8E, 0xFE, 0xA1, 0xE7, 0x58, 0x46, 0xFF, 0xF7, 0x53, 0xFC, 0xD6, 0xF8, 0x38, 0x31, 0x1B, 0x68, -+0x3B, 0x60, 0x01, 0x20, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x20, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0xBF, -+0x54, 0x83, 0x32, 0x40, 0x20, 0x62, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x2D, 0xED, 0x02, 0x8B, -+0x05, 0x46, 0x89, 0xB0, 0x6E, 0x6C, 0x9D, 0xF8, 0x50, 0x40, 0x04, 0x91, 0x0F, 0x46, 0x1C, 0x20, 0x54, 0x21, 0x11, 0xFB, -+0x04, 0x01, 0xD6, 0xF8, 0x38, 0x01, 0x06, 0x90, 0xAB, 0x48, 0x05, 0x94, 0x41, 0x18, 0x3C, 0x68, 0x01, 0x92, 0x08, 0x46, -+0x08, 0xEE, 0x10, 0x1A, 0x07, 0x93, 0xD4, 0xF8, 0x44, 0x80, 0xD4, 0xF8, 0x4C, 0x90, 0x12, 0xF0, 0x41, 0xFA, 0xA5, 0x4B, -+0x05, 0x9A, 0xD3, 0xF8, 0x60, 0x33, 0x28, 0x46, 0x21, 0x46, 0x98, 0x47, 0x00, 0x23, 0x02, 0x93, 0x00, 0x28, 0x00, 0xF0, -+0xF8, 0x80, 0xDF, 0xF8, 0x98, 0xA2, 0x9F, 0x48, 0xDA, 0xF8, 0x00, 0x20, 0x03, 0x68, 0x92, 0xF8, 0x3E, 0x20, 0x03, 0xF0, -+0x3F, 0x03, 0x9A, 0x42, 0x00, 0xF2, 0xFD, 0x80, 0x06, 0x9A, 0x04, 0x9D, 0x53, 0x6A, 0x2D, 0x68, 0x03, 0x90, 0x17, 0x46, -+0x23, 0xF4, 0xC0, 0x13, 0xD2, 0x6C, 0x43, 0xF4, 0x40, 0x11, 0x09, 0xF1, 0x14, 0x0C, 0x92, 0xF8, 0x0D, 0xB0, 0xC2, 0xF8, -+0x1C, 0xC0, 0x79, 0x62, 0x61, 0x6A, 0x07, 0x9F, 0x43, 0xF4, 0x40, 0x13, 0x21, 0xF4, 0xC0, 0x11, 0x43, 0xF4, 0x80, 0x73, -+0x41, 0xF4, 0x40, 0x11, 0xD3, 0x64, 0x61, 0x62, 0x6B, 0x6A, 0x43, 0xF4, 0x80, 0x73, 0xC9, 0xF8, 0x4C, 0x30, 0x02, 0x9B, -+0x99, 0x46, 0x4C, 0xE0, 0x9F, 0x42, 0x40, 0xF2, 0x93, 0x80, 0xFA, 0x1A, 0x92, 0xB2, 0x03, 0x32, 0x4F, 0xEA, 0x92, 0x09, -+0x03, 0xEB, 0x89, 0x03, 0x9B, 0xB2, 0x72, 0x6A, 0x01, 0x98, 0x1A, 0x44, 0x82, 0x42, 0x53, 0xD8, 0x03, 0x9D, 0xDA, 0xF8, -+0x00, 0x00, 0x2D, 0x68, 0x90, 0xF8, 0x3E, 0x00, 0x05, 0xF0, 0x3F, 0x05, 0xA8, 0x42, 0x49, 0xD8, 0xDC, 0xF8, 0x24, 0x00, -+0x28, 0xB1, 0x79, 0x4D, 0xDC, 0xF8, 0x28, 0x00, 0xED, 0x6E, 0x40, 0xF8, 0x03, 0x5C, 0xBE, 0x45, 0x66, 0x64, 0x0D, 0xD2, -+0xDC, 0xF8, 0x4C, 0x10, 0x21, 0xF4, 0xFF, 0x21, 0x21, 0xF4, 0xC0, 0x61, 0x41, 0xEA, 0x49, 0x21, 0x41, 0xF4, 0x80, 0x70, -+0x61, 0x62, 0x73, 0x46, 0xCC, 0xF8, 0x4C, 0x00, 0x72, 0x62, 0xD8, 0xF8, 0x24, 0x20, 0x01, 0xF4, 0x60, 0x11, 0xD3, 0x1A, -+0xB1, 0xF5, 0x60, 0x1F, 0xC8, 0xF8, 0x24, 0x30, 0x59, 0xD0, 0x69, 0x4B, 0x25, 0x68, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x0B, 0xF1, 0x01, 0x0B, 0x00, 0x2B, 0x5F, 0xFA, 0x8B, 0xFB, 0x42, 0xDB, 0x69, 0x6A, 0x02, 0x94, 0x2C, 0x46, 0xD4, 0xF8, -+0x4C, 0xC0, 0xDC, 0xF8, 0x2C, 0x30, 0x03, 0x33, 0x23, 0xF0, 0x03, 0x03, 0x04, 0x33, 0x9B, 0xB2, 0xC1, 0xF3, 0x49, 0x2E, -+0x03, 0xEB, 0x8E, 0x0E, 0x1F, 0xFA, 0x8E, 0xFE, 0xBE, 0x45, 0xA1, 0xD3, 0x72, 0x6A, 0x01, 0x98, 0x73, 0x46, 0x1A, 0x44, -+0x82, 0x42, 0xAB, 0xD9, 0xDD, 0xF8, 0x08, 0x90, 0xB9, 0xF1, 0x00, 0x0F, 0x7E, 0xD0, 0xD9, 0xF8, 0x4C, 0x10, 0x81, 0xF8, -+0x0D, 0xB0, 0xD9, 0xF8, 0x24, 0x30, 0xC6, 0xF8, 0x38, 0x91, 0x43, 0xF4, 0x60, 0x12, 0xC9, 0xF8, 0x24, 0x20, 0x62, 0x6A, -+0x43, 0xF4, 0x60, 0x13, 0x02, 0xF4, 0x60, 0x12, 0x43, 0xF4, 0x80, 0x73, 0x00, 0x20, 0xB2, 0xF5, 0x60, 0x1F, 0xCB, 0x64, -+0xC8, 0x61, 0x60, 0xD0, 0x48, 0x4B, 0x04, 0x9A, 0x1B, 0x68, 0x14, 0x60, 0x5D, 0x78, 0x00, 0x2D, 0x47, 0xD1, 0x63, 0x6C, -+0x0C, 0x33, 0x33, 0x61, 0x2C, 0xE0, 0x00, 0x2D, 0xBA, 0xD1, 0x43, 0x49, 0x43, 0x48, 0x40, 0xF2, 0xF4, 0x52, 0x13, 0xF0, -+0x7D, 0xFD, 0xB3, 0xE7, 0x4F, 0xF0, 0x00, 0x09, 0x71, 0xE7, 0x05, 0x9A, 0x11, 0x46, 0x37, 0x4A, 0x54, 0x23, 0x03, 0xFB, -+0x01, 0x23, 0x3A, 0x49, 0x93, 0xF8, 0x50, 0x20, 0x09, 0x68, 0xC6, 0xF8, 0x38, 0x41, 0x01, 0x3A, 0x83, 0xF8, 0x50, 0x20, -+0x4B, 0x78, 0x43, 0xB3, 0x18, 0xEE, 0x10, 0x0A, 0x12, 0xF0, 0x54, 0xF9, 0x41, 0x46, 0xD8, 0xF8, 0x48, 0x01, 0x12, 0xF0, -+0x0B, 0xF9, 0x04, 0x99, 0x22, 0x68, 0xE3, 0x6C, 0x0A, 0x60, 0x00, 0x22, 0xDA, 0x61, 0x01, 0x25, 0x18, 0xEE, 0x10, 0x0A, -+0x31, 0x46, 0x12, 0xF0, 0x23, 0xF9, 0x28, 0x46, 0x09, 0xB0, 0xBD, 0xEC, 0x02, 0x8B, 0xBD, 0xE8, 0xF0, 0x8F, 0x05, 0x46, -+0x31, 0x46, 0x18, 0xEE, 0x10, 0x0A, 0x12, 0xF0, 0x17, 0xF9, 0x28, 0x46, 0x09, 0xB0, 0xBD, 0xEC, 0x02, 0x8B, 0xBD, 0xE8, -+0xF0, 0x8F, 0x00, 0x25, 0xE6, 0xE7, 0xD8, 0xF8, 0x10, 0x30, 0x33, 0x61, 0xD2, 0xE7, 0x18, 0xEE, 0x10, 0x0A, 0x31, 0x46, -+0x12, 0xF0, 0x06, 0xF9, 0x02, 0x9D, 0x28, 0x46, 0x09, 0xB0, 0xBD, 0xEC, 0x02, 0x8B, 0xBD, 0xE8, 0xF0, 0x8F, 0x18, 0xEE, -+0x10, 0x0A, 0x12, 0xF0, 0x1B, 0xF9, 0x99, 0xE7, 0x06, 0x99, 0x4A, 0x6A, 0xCD, 0x6C, 0x42, 0xF4, 0x60, 0x13, 0xC5, 0xF8, -+0x1C, 0x90, 0x4B, 0x62, 0x63, 0x6A, 0x23, 0xF4, 0xC0, 0x13, 0x43, 0xF4, 0x20, 0x17, 0x42, 0xF4, 0x60, 0x12, 0x43, 0xF4, -+0x20, 0x13, 0x42, 0xF4, 0x80, 0x72, 0x47, 0xF4, 0x80, 0x77, 0xEA, 0x64, 0x18, 0xEE, 0x10, 0x0A, 0x63, 0x62, 0x31, 0x46, -+0xCC, 0xF8, 0x4C, 0x70, 0x12, 0xF0, 0xDC, 0xF8, 0x04, 0x9B, 0x4D, 0x46, 0x1C, 0x60, 0xB4, 0xE7, 0x20, 0x62, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x54, 0x83, 0x32, 0x40, 0x94, 0x64, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x34, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xA4, 0x91, 0x15, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x82, 0x69, 0x03, 0x32, 0x22, 0xF0, 0x03, 0x02, -+0x04, 0x32, 0x93, 0xB2, 0x99, 0x42, 0x04, 0xD9, 0xC8, 0x1A, 0x80, 0xB2, 0x03, 0x30, 0x80, 0x08, 0x70, 0x47, 0x00, 0x20, -+0x70, 0x47, 0x00, 0xBF, 0x2D, 0xE9, 0xF8, 0x4F, 0x43, 0x4A, 0x44, 0x4B, 0x11, 0x68, 0x18, 0x68, 0x88, 0x42, 0x08, 0xD0, -+0xD2, 0xE9, 0x01, 0x54, 0xD2, 0xE9, 0x03, 0x02, 0xC3, 0xE9, 0x00, 0x15, 0xC3, 0xE9, 0x02, 0x40, 0x1A, 0x61, 0x3E, 0x48, -+0x3C, 0x4D, 0x3E, 0x4F, 0xDF, 0xF8, 0x04, 0x81, 0x30, 0x22, 0x00, 0x21, 0x06, 0x46, 0xEE, 0xF7, 0xE3, 0xFF, 0x05, 0xF1, -+0x18, 0x09, 0x3B, 0x68, 0x55, 0xF8, 0x04, 0x0B, 0x4F, 0xF4, 0xAC, 0x72, 0x02, 0xFB, 0x03, 0xF2, 0x00, 0x21, 0xEE, 0xF7, -+0xD7, 0xFF, 0x57, 0xF8, 0x04, 0x3B, 0x00, 0x2B, 0x58, 0xDD, 0x4F, 0xF0, 0x00, 0x0B, 0xDA, 0x46, 0x55, 0xF8, 0x04, 0x4C, -+0x30, 0x4B, 0x5C, 0x44, 0x05, 0x20, 0x04, 0xF1, 0xA8, 0x01, 0x63, 0x64, 0x2E, 0x4B, 0xC4, 0xF8, 0xA8, 0x30, 0x84, 0xF8, -+0x97, 0x00, 0x04, 0xF1, 0x94, 0x03, 0x04, 0xF1, 0xAB, 0x00, 0x61, 0x67, 0x18, 0x21, 0x6F, 0xF0, 0x7B, 0x0C, 0x23, 0x66, -+0x60, 0x66, 0x4F, 0xF4, 0xC0, 0x63, 0x40, 0xF2, 0x43, 0x10, 0xA1, 0x66, 0x00, 0x21, 0xC4, 0xE9, 0x21, 0x30, 0xC4, 0xE9, -+0x0D, 0x11, 0xC4, 0xE9, 0x16, 0x11, 0xC4, 0xE9, 0x1E, 0x11, 0x84, 0xF8, 0x94, 0xC0, 0x84, 0xF8, 0x95, 0x10, 0x84, 0xF8, -+0x96, 0x10, 0xA1, 0x62, 0xE1, 0x63, 0xE1, 0x66, 0xC4, 0xF8, 0x80, 0x10, 0x21, 0x67, 0xC4, 0xF8, 0x48, 0x61, 0xC4, 0xF8, -+0x0C, 0x80, 0xC4, 0xF8, 0x50, 0x80, 0xF0, 0xF7, 0x7F, 0xF8, 0x80, 0x03, 0xC4, 0xF8, 0xAC, 0x00, 0xF0, 0xF7, 0x7A, 0xF8, -+0x4F, 0xF0, 0x01, 0x0C, 0x01, 0x30, 0x0C, 0xFA, 0x00, 0xF0, 0x12, 0x4B, 0xC4, 0xF8, 0xB8, 0x30, 0x01, 0x38, 0x00, 0x21, -+0xC4, 0xE9, 0x2C, 0x01, 0x21, 0x46, 0x30, 0x46, 0x12, 0xF0, 0x16, 0xF8, 0x57, 0xF8, 0x04, 0x1C, 0x0A, 0xF1, 0x01, 0x0A, -+0x8A, 0x45, 0x0B, 0xF5, 0xAC, 0x7B, 0xA9, 0xDB, 0x4D, 0x45, 0x06, 0xF1, 0x08, 0x06, 0x94, 0xD1, 0xBD, 0xE8, 0xF8, 0x8F, -+0xEC, 0x57, 0x18, 0x00, 0x74, 0x1F, 0x17, 0x00, 0x64, 0x64, 0x17, 0x00, 0x8C, 0x1F, 0x17, 0x00, 0x00, 0x01, 0x20, 0x00, -+0x1E, 0xAB, 0xDC, 0xBA, 0x04, 0x07, 0xFF, 0xFF, 0xBE, 0xBA, 0xFE, 0xCA, 0x2D, 0xE9, 0xF8, 0x43, 0x18, 0x4A, 0x19, 0x4B, -+0x11, 0x68, 0x18, 0x68, 0x88, 0x42, 0x08, 0xD0, 0xD2, 0xE9, 0x01, 0x54, 0xD2, 0xE9, 0x03, 0x02, 0xC3, 0xE9, 0x00, 0x15, -+0xC3, 0xE9, 0x02, 0x40, 0x1A, 0x61, 0x13, 0x4C, 0x13, 0x4F, 0x11, 0x4E, 0x04, 0xF1, 0x30, 0x09, 0x20, 0x46, 0x11, 0xF0, -+0xDB, 0xFF, 0x57, 0xF8, 0x04, 0x3B, 0x00, 0x2B, 0x0E, 0xDD, 0x00, 0x25, 0xA8, 0x46, 0x31, 0x68, 0x20, 0x46, 0x29, 0x44, -+0x11, 0xF0, 0xD4, 0xFF, 0x57, 0xF8, 0x04, 0x3C, 0x08, 0xF1, 0x01, 0x08, 0x98, 0x45, 0x05, 0xF5, 0xAC, 0x75, 0xF2, 0xDB, -+0x08, 0x34, 0x4C, 0x45, 0x06, 0xF1, 0x04, 0x06, 0xE4, 0xD1, 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0xBF, 0xEC, 0x57, 0x18, 0x00, -+0x74, 0x1F, 0x17, 0x00, 0x64, 0x64, 0x17, 0x00, 0x8C, 0x1F, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x05, 0x28, 0x82, 0xB0, -+0x06, 0x46, 0x00, 0xF0, 0xBD, 0x80, 0x6A, 0x4C, 0x00, 0xEB, 0x40, 0x03, 0xC3, 0xEB, 0xC3, 0x03, 0x04, 0xEB, 0x83, 0x04, -+0x94, 0xF8, 0x4D, 0x30, 0xE7, 0x6A, 0x65, 0x6B, 0x01, 0x2B, 0x69, 0xD1, 0xD5, 0xE9, 0x12, 0x38, 0x00, 0x22, 0x4F, 0xF4, -+0x80, 0x71, 0x6A, 0x62, 0xC8, 0xF8, 0x1C, 0x20, 0xC8, 0xF8, 0x4C, 0x10, 0x00, 0x2B, 0x4C, 0xD0, 0xBA, 0x88, 0x11, 0x07, -+0x49, 0xD5, 0xD3, 0xE9, 0x17, 0x21, 0x28, 0x33, 0xC8, 0xF8, 0x34, 0x10, 0xC8, 0xF8, 0x48, 0x20, 0xC8, 0xF8, 0x38, 0x30, -+0x2B, 0x7F, 0x58, 0x4A, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, 0x62, 0x30, 0x63, 0xBB, 0x55, 0x4A, -+0x6B, 0x7F, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x03, 0x23, 0x5B, 0x68, 0x9A, 0x06, 0x23, 0xD5, 0xEB, 0x8B, 0x13, 0xF4, -+0x00, 0x5F, 0xEB, 0x6A, 0xDB, 0x6B, 0x14, 0xBF, 0xC3, 0xF3, 0x00, 0x13, 0xC3, 0xF3, 0xC0, 0x03, 0xC3, 0xB9, 0xD8, 0xF8, -+0x24, 0x10, 0x0B, 0x88, 0x9A, 0xB2, 0x1B, 0x04, 0x12, 0xD5, 0xC2, 0xF3, 0x0E, 0x02, 0x0A, 0x80, 0x95, 0xF8, 0x33, 0x20, -+0x95, 0xF8, 0x32, 0x30, 0x04, 0x3A, 0x04, 0x3B, 0x85, 0xF8, 0x33, 0x20, 0x85, 0xF8, 0x32, 0x30, 0xD8, 0xE9, 0x0A, 0x32, -+0x04, 0x3A, 0x04, 0x3B, 0xC8, 0xE9, 0x0A, 0x32, 0x28, 0x46, 0x02, 0xF0, 0x71, 0xFC, 0x3E, 0x4B, 0x08, 0xF1, 0x14, 0x01, -+0xD3, 0xF8, 0x9C, 0x33, 0x32, 0x46, 0x08, 0x46, 0x98, 0x47, 0xD7, 0xF8, 0x48, 0x01, 0x39, 0x46, 0x11, 0xF0, 0x4A, 0xFF, -+0x00, 0x23, 0x6B, 0x64, 0x94, 0xF8, 0x50, 0x30, 0x00, 0x22, 0x01, 0x33, 0x84, 0xF8, 0x50, 0x30, 0xE2, 0x62, 0x02, 0xB0, -+0xBD, 0xE8, 0xF0, 0x87, 0x6B, 0x6A, 0xDF, 0xF8, 0xCC, 0x90, 0x20, 0x6B, 0xD5, 0xE9, 0x12, 0xA8, 0x43, 0xF4, 0x60, 0x13, -+0x6B, 0x62, 0xC7, 0xF8, 0x38, 0x51, 0x02, 0xF0, 0x37, 0xFC, 0x94, 0xF8, 0x4D, 0x20, 0xD9, 0xF8, 0x00, 0x30, 0x88, 0xF8, -+0x0D, 0x20, 0x5B, 0x78, 0x00, 0x2B, 0x34, 0xD1, 0x3B, 0x61, 0x6B, 0x6A, 0xB9, 0x88, 0x43, 0xF4, 0x80, 0x73, 0x41, 0xF0, -+0x01, 0x02, 0xC8, 0xF8, 0x4C, 0x30, 0xBA, 0x80, 0xBA, 0xF1, 0x00, 0x0F, 0x09, 0xD0, 0x4D, 0x07, 0x07, 0xD4, 0x08, 0x07, -+0x31, 0xD4, 0x23, 0x6B, 0x99, 0x6C, 0x4B, 0x6A, 0x43, 0xF0, 0x04, 0x03, 0x4B, 0x62, 0x93, 0x07, 0x10, 0xD5, 0xD9, 0xF8, -+0x00, 0x30, 0x5B, 0x78, 0xA3, 0xB9, 0x08, 0xF1, 0x14, 0x01, 0x23, 0x6B, 0x3A, 0x6B, 0x98, 0x6A, 0x15, 0x4B, 0x50, 0x61, -+0xD3, 0xF8, 0x9C, 0x33, 0x32, 0x46, 0x07, 0xF1, 0x0C, 0x00, 0x98, 0x47, 0x39, 0x46, 0x04, 0xF1, 0x1C, 0x00, 0x11, 0xF0, -+0xF9, 0xFE, 0xAF, 0xE7, 0x0F, 0x4C, 0x47, 0xE7, 0x07, 0xF1, 0x50, 0x01, 0xE9, 0xE7, 0x94, 0xF8, 0x4E, 0x00, 0xBB, 0x7A, -+0x7A, 0x7A, 0x69, 0x8C, 0x00, 0x90, 0x38, 0x46, 0xFF, 0xF7, 0xCA, 0xF8, 0x07, 0xF1, 0x50, 0x03, 0xC8, 0xF8, 0x1C, 0x30, -+0xBD, 0xE7, 0x41, 0xF0, 0x03, 0x02, 0xBA, 0x80, 0xCF, 0xE7, 0x00, 0xBF, 0x20, 0x62, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x68, 0x65, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xC4, 0x63, 0x17, 0x00, 0x34, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0xD0, 0xF8, 0x4C, 0x90, 0x8B, 0xB0, 0x09, 0xF1, 0x14, 0x03, 0x05, 0x29, 0x04, 0x46, 0x0E, 0x46, 0x00, 0x93, 0x00, 0xF0, -+0xAD, 0x81, 0x57, 0x4D, 0x01, 0xEB, 0x41, 0x03, 0xC3, 0xEB, 0xC3, 0x03, 0x05, 0xEB, 0x83, 0x05, 0x94, 0xF8, 0x1B, 0xB0, -+0x94, 0xF8, 0x1D, 0xA0, 0xEF, 0xF3, 0x10, 0x83, 0xDF, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x50, 0x4B, 0x01, 0x22, 0x1A, 0x60, -+0xDF, 0xF8, 0x40, 0x81, 0xEA, 0x6A, 0xD8, 0xF8, 0x00, 0x30, 0x01, 0x33, 0xC8, 0xF8, 0x00, 0x30, 0x00, 0x2A, 0x79, 0xD0, -+0x4A, 0x4F, 0x06, 0xE0, 0xD7, 0xF8, 0x5C, 0x33, 0x30, 0x46, 0x98, 0x47, 0xEA, 0x6A, 0x00, 0x2A, 0x70, 0xD0, 0x63, 0x6A, -+0x99, 0x02, 0xF5, 0xD5, 0x03, 0xF4, 0x60, 0x11, 0xB1, 0xF5, 0x20, 0x1F, 0xF0, 0xD0, 0x50, 0x7A, 0x61, 0x7F, 0x88, 0x42, -+0xEC, 0xD1, 0x90, 0x7A, 0xE1, 0x7E, 0x88, 0x42, 0xE8, 0xD1, 0xD9, 0xF8, 0x2C, 0x10, 0xB5, 0xF8, 0x48, 0x00, 0x03, 0x31, -+0x21, 0xF0, 0x03, 0x01, 0x04, 0x31, 0x89, 0xB2, 0x88, 0x42, 0x00, 0xF2, 0x5D, 0x81, 0x00, 0x20, 0x03, 0x90, 0x05, 0x90, -+0x86, 0x46, 0x68, 0x6B, 0x01, 0x90, 0x50, 0x6A, 0x02, 0x90, 0x01, 0x98, 0x95, 0xF8, 0x4F, 0xC0, 0xC0, 0x6C, 0x04, 0x90, -+0x03, 0x98, 0xA5, 0xF8, 0x4A, 0xE0, 0x08, 0x44, 0x02, 0x99, 0x05, 0xEB, 0x8C, 0x0E, 0x08, 0x44, 0x4F, 0xEA, 0x8C, 0x01, -+0x03, 0x91, 0xDE, 0xF8, 0x38, 0x10, 0x88, 0x42, 0x40, 0xF2, 0x82, 0x81, 0x95, 0xF8, 0x4E, 0x10, 0x61, 0x45, 0xBB, 0xD9, -+0x95, 0xF8, 0x4D, 0x10, 0x01, 0x29, 0xB7, 0xD0, 0xDE, 0xF8, 0x3C, 0xE0, 0x70, 0x45, 0xB3, 0xD8, 0x03, 0x9F, 0x17, 0x44, -+0xBB, 0x46, 0x01, 0x9F, 0xCB, 0xF8, 0x3C, 0x71, 0x0C, 0xF1, 0x01, 0x0C, 0x02, 0x9F, 0xCB, 0xF8, 0x34, 0x70, 0x85, 0xF8, -+0x4F, 0xC0, 0x05, 0x9F, 0x62, 0x64, 0x43, 0xEA, 0x47, 0x23, 0x23, 0xF4, 0xC0, 0x13, 0x43, 0xF4, 0xE0, 0x03, 0x63, 0x62, -+0xC9, 0xF8, 0x4C, 0x30, 0x04, 0x9B, 0x1F, 0x46, 0x00, 0x9B, 0xFB, 0x61, 0x50, 0x62, 0x95, 0xF8, 0x4C, 0x20, 0x6C, 0x63, -+0x4B, 0x1C, 0xDB, 0xB2, 0x9A, 0x42, 0x85, 0xF8, 0x4D, 0x30, 0x0D, 0xD8, 0x10, 0x4B, 0x30, 0x46, 0xD3, 0xF8, 0x5C, 0x33, -+0x98, 0x47, 0x07, 0xE0, 0x63, 0x6A, 0x98, 0x02, 0x1C, 0xD4, 0x95, 0xF8, 0x50, 0x30, 0x01, 0x33, 0x85, 0xF8, 0x50, 0x30, -+0xD8, 0xF8, 0x00, 0x30, 0x3B, 0xB1, 0x07, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xC8, 0xF8, 0x00, 0x30, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0x00, 0x20, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0xBF, 0x20, 0x62, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xA3, 0x6A, 0xDB, 0x0A, 0x13, 0xF0, 0x06, 0x0F, 0xDD, 0xD0, 0xB0, 0x48, -+0x00, 0xEB, 0xC6, 0x00, 0x11, 0xF0, 0x4A, 0xFE, 0xE8, 0x62, 0x00, 0x28, 0x00, 0xF0, 0xEA, 0x80, 0xAC, 0x4F, 0x80, 0xF8, -+0x0A, 0xB0, 0x00, 0x23, 0x01, 0x21, 0x3A, 0x68, 0x80, 0xF8, 0x09, 0xA0, 0x03, 0x72, 0x43, 0x60, 0xC1, 0x72, 0xA3, 0x6A, -+0xB2, 0xF9, 0x00, 0x20, 0x61, 0x7F, 0x03, 0x91, 0xC3, 0xF3, 0xC1, 0x1B, 0xC3, 0xF3, 0xC7, 0x21, 0x00, 0x2A, 0xC3, 0xF3, -+0xC2, 0x23, 0x01, 0x93, 0xC0, 0xF2, 0xD2, 0x80, 0x01, 0x9B, 0x05, 0x2B, 0x00, 0xF0, 0xD9, 0x80, 0xD4, 0xF8, 0x28, 0xA0, -+0x63, 0x7F, 0x05, 0x93, 0x0A, 0xF0, 0x7F, 0x03, 0x04, 0x93, 0xCA, 0xF3, 0x40, 0x23, 0x06, 0x93, 0x01, 0x9B, 0x04, 0x2B, -+0x3B, 0x68, 0x00, 0xF0, 0xF2, 0x80, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0x01, 0x81, 0x94, 0x4A, 0x05, 0x99, -+0x02, 0x92, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x01, 0x23, 0x04, 0x9A, 0x9B, 0x8A, 0x08, 0x93, 0xC2, 0xF3, 0xC1, 0x02, -+0x01, 0x32, 0x09, 0x92, 0x0A, 0xF0, 0x07, 0x0A, 0x8D, 0x4B, 0x05, 0x93, 0x8D, 0x4B, 0x9C, 0x46, 0x06, 0x9B, 0x00, 0x27, -+0x43, 0xEA, 0xCA, 0x0A, 0x5F, 0xFA, 0x8B, 0xF3, 0x19, 0x46, 0x05, 0xF1, 0x38, 0x0B, 0x04, 0x93, 0x85, 0xF8, 0x4E, 0x10, -+0x00, 0x23, 0x31, 0x1D, 0xCD, 0xF8, 0x18, 0x90, 0x07, 0x94, 0xD1, 0x46, 0x85, 0xF8, 0x4F, 0x30, 0xDA, 0x46, 0x1E, 0x46, -+0x64, 0x46, 0x8B, 0x46, 0x01, 0x2A, 0xF1, 0xB2, 0x00, 0xF0, 0xA8, 0x80, 0x48, 0x46, 0xA0, 0x47, 0x7E, 0x4B, 0x09, 0x9A, -+0x33, 0xF8, 0x1B, 0xC0, 0x08, 0x99, 0x02, 0xFB, 0x0C, 0xFC, 0x00, 0xFB, 0x0C, 0xF0, 0xF8, 0x40, 0x81, 0x42, 0x28, 0xBF, -+0x01, 0x46, 0x4A, 0xF8, 0x04, 0x1B, 0x95, 0xF8, 0x4E, 0x10, 0x01, 0x36, 0x8E, 0x42, 0xE5, 0xDD, 0xCA, 0x46, 0x04, 0x99, -+0x05, 0x9B, 0x50, 0x46, 0xDD, 0xE9, 0x06, 0x94, 0x98, 0x47, 0x03, 0x9B, 0xD5, 0xF8, 0x38, 0xC0, 0x1E, 0x46, 0x02, 0x9B, -+0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x06, 0x32, 0x09, 0x9B, 0x16, 0x7F, 0xEA, 0x6A, 0x03, 0xFB, 0x06, 0xF6, 0x00, 0xFB, -+0x06, 0xF6, 0xFE, 0x40, 0xB6, 0xB2, 0xA5, 0xF8, 0x48, 0x60, 0xE1, 0x7E, 0x63, 0x7F, 0xEF, 0x6B, 0x9E, 0x20, 0x00, 0xFB, -+0x03, 0x13, 0x02, 0x99, 0x28, 0x6C, 0x01, 0xEB, 0x83, 0x03, 0x4F, 0xF0, 0x01, 0x0E, 0x93, 0xF8, 0x5A, 0x31, 0x85, 0xF8, -+0x4C, 0x30, 0xD9, 0xF8, 0x2C, 0x10, 0x00, 0x9B, 0x53, 0x61, 0x03, 0x31, 0x21, 0xF0, 0x03, 0x01, 0x04, 0x31, 0x00, 0x23, -+0x89, 0xB2, 0x51, 0x62, 0xC2, 0xF8, 0x54, 0x01, 0xC2, 0xE9, 0x53, 0xC7, 0xC2, 0xE9, 0x0D, 0x33, 0x93, 0x64, 0x93, 0x61, -+0xD3, 0x63, 0x85, 0xF8, 0x4D, 0xE0, 0xD9, 0xF8, 0x2C, 0x00, 0x03, 0x30, 0x20, 0xF0, 0x03, 0x00, 0x04, 0x30, 0x80, 0xB2, -+0xB0, 0x42, 0x57, 0xD2, 0x30, 0x1A, 0x80, 0xB2, 0x03, 0x30, 0x83, 0x10, 0x01, 0xEB, 0x83, 0x01, 0x80, 0x08, 0x5B, 0x02, -+0x66, 0x6A, 0xA5, 0xF8, 0x4A, 0x00, 0x33, 0x43, 0x23, 0xF4, 0xC0, 0x13, 0x43, 0xF4, 0xD0, 0x03, 0x51, 0x62, 0xC5, 0xE9, -+0x0C, 0x44, 0x63, 0x62, 0x62, 0x64, 0xC9, 0xF8, 0x4C, 0x30, 0xFF, 0xE6, 0xA0, 0xEB, 0x01, 0x0E, 0x1F, 0xFA, 0x8E, 0xFE, -+0x0E, 0xF1, 0x03, 0x0E, 0x4F, 0xEA, 0xAE, 0x00, 0x05, 0x90, 0x80, 0x00, 0x4F, 0xEA, 0x9E, 0x0E, 0x03, 0x90, 0x98, 0xE6, -+0x3D, 0x4D, 0x57, 0xE6, 0x60, 0x62, 0xE8, 0xE6, 0x11, 0xF0, 0x06, 0x0F, 0x7F, 0xF4, 0x2A, 0xAF, 0x3A, 0x49, 0x3B, 0x48, -+0x4F, 0xF4, 0xEA, 0x72, 0x13, 0xF0, 0x60, 0xF9, 0x22, 0xE7, 0x09, 0xAB, 0x08, 0xAA, 0x01, 0x99, 0x20, 0x46, 0x02, 0xF0, -+0x39, 0xF9, 0x36, 0x4B, 0x05, 0x93, 0x36, 0x4B, 0x94, 0xF8, 0x36, 0x70, 0x09, 0x9A, 0x9C, 0x46, 0x2B, 0x4B, 0x02, 0x93, -+0x82, 0x46, 0xC7, 0xF3, 0x40, 0x17, 0x3F, 0xE7, 0x01, 0x9B, 0x04, 0x2B, 0x7F, 0xF4, 0x54, 0xAF, 0x4F, 0xEA, 0xE9, 0x02, -+0x00, 0x2E, 0x7F, 0xF4, 0x4F, 0xAF, 0x09, 0x2A, 0x04, 0xBF, 0x09, 0xF0, 0x07, 0x03, 0x43, 0xF0, 0x40, 0x09, 0x47, 0xE7, -+0x18, 0x46, 0xAD, 0xE7, 0x95, 0xF8, 0x4D, 0x10, 0x93, 0xE6, 0x04, 0x9A, 0xB3, 0xF9, 0x00, 0x30, 0x11, 0x09, 0x4A, 0x1C, -+0x00, 0x2B, 0x0A, 0xF0, 0x0F, 0x0A, 0x09, 0x92, 0x14, 0xDB, 0x19, 0x49, 0x05, 0x98, 0x02, 0x91, 0x4F, 0xF4, 0x1E, 0x73, -+0x03, 0xFB, 0x00, 0x13, 0x1B, 0x69, 0x08, 0x93, 0x0E, 0xE7, 0x1A, 0xF0, 0x60, 0x0F, 0x3F, 0xF4, 0xFB, 0xAE, 0x17, 0x49, -+0x1A, 0x48, 0x4F, 0xF4, 0xD2, 0x72, 0x13, 0xF0, 0x19, 0xF9, 0xF3, 0xE6, 0x03, 0x29, 0x04, 0xD8, 0xBA, 0xF1, 0x09, 0x0F, -+0x0D, 0xD8, 0x09, 0x9A, 0xE3, 0xE7, 0x10, 0x49, 0x14, 0x48, 0x40, 0xF2, 0x9B, 0x12, 0x13, 0xF0, 0x0B, 0xF9, 0x3B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xEF, 0xDB, 0xF1, 0xE7, 0x0A, 0x49, 0x0F, 0x48, 0x4F, 0xF4, 0xCE, 0x72, 0x13, 0xF0, -+0xFF, 0xF8, 0xEA, 0xE7, 0x64, 0x64, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x85, 0x06, 0x13, 0x00, -+0x75, 0x06, 0x13, 0x00, 0x98, 0x9C, 0x17, 0x00, 0xC4, 0x63, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xB8, 0x91, 0x15, 0x00, -+0x21, 0x3B, 0x13, 0x00, 0x05, 0x3B, 0x13, 0x00, 0x0C, 0x92, 0x15, 0x00, 0xE0, 0x91, 0x15, 0x00, 0xFC, 0x91, 0x15, 0x00, -+0xC3, 0x7A, 0x01, 0x3B, 0xDB, 0xB2, 0xC3, 0x72, 0x03, 0xB1, 0x70, 0x47, 0x01, 0x46, 0xD0, 0xF8, 0x48, 0x01, 0x11, 0xF0, -+0x83, 0xBC, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x47, 0xD0, 0xE9, 0x12, 0x67, 0x00, 0x23, 0x4F, 0xF4, 0x80, 0x72, 0x43, 0x62, -+0x43, 0x64, 0xFB, 0x61, 0xFA, 0x64, 0x00, 0x2E, 0x00, 0xF0, 0x81, 0x80, 0xD0, 0xF8, 0x2C, 0x80, 0x8A, 0x46, 0x05, 0x46, -+0x06, 0xF1, 0x28, 0x09, 0x08, 0xF1, 0x40, 0x01, 0x43, 0x46, 0x06, 0xF1, 0x24, 0x02, 0x53, 0xF8, 0x04, 0x4B, 0x42, 0xF8, -+0x04, 0x4F, 0x8B, 0x42, 0xF9, 0xD1, 0xEB, 0x8B, 0x9C, 0x04, 0x22, 0xD5, 0x48, 0x4B, 0x49, 0x49, 0x1A, 0x68, 0x6B, 0x7F, -+0xB2, 0xF9, 0x00, 0x20, 0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, 0x03, 0x13, 0x00, 0x2A, 0xD3, 0xF8, 0x4C, 0x41, 0x61, 0xDB, -+0xD8, 0xF8, 0x14, 0x20, 0xD4, 0xF8, 0x9C, 0x30, 0x32, 0x64, 0xD8, 0xF8, 0x24, 0x20, 0x32, 0x65, 0xC3, 0xF3, 0xC2, 0x22, -+0x05, 0x2A, 0xF3, 0x63, 0x5D, 0xD0, 0xD8, 0xF8, 0x3C, 0x30, 0x58, 0x07, 0x03, 0xD4, 0xF3, 0x6A, 0x23, 0xF4, 0xC0, 0x73, -+0xF3, 0x62, 0x39, 0x4A, 0x2B, 0x7F, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, 0x62, 0x30, 0x7B, 0xB1, -+0x73, 0x6A, 0x43, 0xF0, 0x10, 0x03, 0x28, 0x46, 0x73, 0x62, 0x02, 0xF0, 0x47, 0xF9, 0xD6, 0xE9, 0x17, 0x23, 0x07, 0xF1, -+0x14, 0x00, 0xC7, 0xE9, 0x0D, 0x39, 0xBA, 0x64, 0xBD, 0xE8, 0xF0, 0x87, 0x2B, 0x4A, 0x6B, 0x7F, 0x4F, 0xF4, 0x1E, 0x71, -+0x01, 0xFB, 0x03, 0x23, 0x5B, 0x68, 0x99, 0x06, 0xE6, 0xD5, 0xBA, 0xF1, 0x00, 0x0F, 0xE3, 0xD1, 0xEB, 0x8B, 0x13, 0xF4, -+0x00, 0x5F, 0xEB, 0x6A, 0xDB, 0x6B, 0x14, 0xBF, 0xC3, 0xF3, 0x00, 0x13, 0xC3, 0xF3, 0xC0, 0x03, 0x00, 0x2B, 0xD7, 0xD1, -+0x79, 0x6A, 0x0A, 0x88, 0x93, 0xB2, 0x12, 0x04, 0xD2, 0xD5, 0xC3, 0xF3, 0x0E, 0x03, 0x0B, 0x80, 0x95, 0xF8, 0x33, 0x20, -+0x95, 0xF8, 0x32, 0x30, 0x04, 0x3A, 0x04, 0x3B, 0x85, 0xF8, 0x33, 0x20, 0x85, 0xF8, 0x32, 0x30, 0xD7, 0xE9, 0x0A, 0x32, -+0x04, 0x3A, 0x04, 0x3B, 0xC7, 0xE9, 0x0A, 0x32, 0xBE, 0xE7, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0x2C, 0x9B, 0xD1, -+0x12, 0x49, 0x13, 0x48, 0x40, 0xF2, 0x4B, 0x12, 0x13, 0xF0, 0x3C, 0xF8, 0x94, 0xE7, 0x03, 0xF4, 0xC0, 0x63, 0xF2, 0x6C, -+0x94, 0xF8, 0xA1, 0x10, 0xB3, 0xF5, 0x80, 0x6F, 0x14, 0xBF, 0x4F, 0xF4, 0x80, 0x30, 0x4F, 0xF4, 0x00, 0x30, 0x22, 0xF4, -+0x40, 0x33, 0x03, 0x43, 0x19, 0xB1, 0x43, 0xF4, 0x80, 0x23, 0xF3, 0x64, 0x8D, 0xE7, 0x23, 0xF4, 0x80, 0x23, 0xF3, 0x64, -+0x89, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x68, 0x8E, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x05, 0x28, 0x89, 0xB0, 0x81, 0x46, 0x00, 0xF0, 0x79, 0x81, 0xBE, 0x4A, -+0x00, 0xEB, 0x40, 0x03, 0xC3, 0xEB, 0xC3, 0x03, 0x02, 0xEB, 0x83, 0x03, 0x03, 0x93, 0x03, 0x9B, 0xDC, 0x68, 0xBA, 0x4B, -+0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x09, 0xDA, 0x5D, 0xE1, 0xE3, 0x6C, 0x1B, 0x6D, 0x00, 0x2B, 0x80, 0xF2, -+0xFE, 0x80, 0x24, 0x68, 0x00, 0x2C, 0x00, 0xF0, 0xFA, 0x80, 0x63, 0x6A, 0x9A, 0x02, 0xF3, 0xD5, 0xB0, 0x4D, 0x2A, 0x68, -+0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xC0, 0xF2, 0x80, 0x81, 0xAE, 0x4B, 0x67, 0x6C, 0x1B, 0x68, 0xDB, 0xB2, 0x07, 0xEB, -+0x83, 0x03, 0xD3, 0xF8, 0x3C, 0x41, 0xE5, 0x6C, 0x63, 0x6A, 0xAA, 0x49, 0x43, 0xF4, 0x60, 0x10, 0x09, 0x68, 0x60, 0x62, -+0x49, 0x78, 0x23, 0xF4, 0xC0, 0x13, 0x00, 0x29, 0x40, 0xF0, 0x58, 0x81, 0x43, 0xF4, 0x60, 0x13, 0x43, 0xF4, 0x80, 0x73, -+0x00, 0x2A, 0x26, 0x68, 0xEB, 0x64, 0xE9, 0x61, 0xC0, 0xF2, 0x57, 0x81, 0x72, 0x6A, 0x02, 0xF4, 0x60, 0x1A, 0xBA, 0xF5, -+0x60, 0x1F, 0x00, 0xF0, 0xEC, 0x80, 0x9D, 0x48, 0x50, 0xF8, 0x39, 0x30, 0x00, 0x2B, 0x00, 0xF0, 0xE6, 0x80, 0x00, 0xEB, -+0xC9, 0x00, 0x11, 0xF0, 0xAD, 0xFB, 0xBB, 0x88, 0x83, 0x80, 0x7B, 0x7A, 0x43, 0x72, 0xBB, 0x7A, 0x83, 0x72, 0x01, 0x23, -+0xC3, 0x72, 0x72, 0x6A, 0xD6, 0xF8, 0x4C, 0xA0, 0xF9, 0x6A, 0xD7, 0xF8, 0x4C, 0xB1, 0xB5, 0x6C, 0x05, 0x95, 0x04, 0x46, -+0xD7, 0xE9, 0x10, 0x03, 0x22, 0xF4, 0xC0, 0x12, 0xE1, 0x62, 0x42, 0xF4, 0x20, 0x12, 0x00, 0x21, 0xC4, 0xE9, 0x10, 0x03, -+0xA1, 0x64, 0x3B, 0x6B, 0x72, 0x62, 0xCA, 0xF8, 0x4C, 0x20, 0xC4, 0xF8, 0x4C, 0xB1, 0x06, 0x93, 0xD7, 0xF8, 0x50, 0x31, -+0xC4, 0xF8, 0x50, 0x31, 0xD7, 0xF8, 0x54, 0x31, 0xC4, 0xF8, 0x54, 0x31, 0x04, 0xF1, 0x0C, 0x03, 0x0A, 0xF1, 0x14, 0x0C, -+0x28, 0x35, 0xC4, 0xE9, 0x0D, 0x11, 0xA1, 0x61, 0xE1, 0x63, 0x61, 0x62, 0x04, 0x93, 0x04, 0xF5, 0x82, 0x73, 0xC4, 0xF8, -+0x14, 0xC0, 0x25, 0x63, 0xBC, 0x46, 0x08, 0x46, 0x57, 0x46, 0x07, 0x93, 0xAA, 0x46, 0x8E, 0x46, 0x25, 0x46, 0x0C, 0x46, -+0x06, 0xE0, 0x5A, 0x6A, 0xDF, 0x6C, 0xD8, 0xF8, 0x34, 0x00, 0xD8, 0xF8, 0x4C, 0xB1, 0x1E, 0x46, 0xFB, 0x6A, 0x03, 0x33, -+0xC2, 0xF3, 0x49, 0x28, 0x23, 0xF0, 0x03, 0x03, 0x03, 0xEB, 0x88, 0x03, 0x04, 0x33, 0x9B, 0xB2, 0x18, 0x44, 0x01, 0x31, -+0x58, 0x45, 0x02, 0xF4, 0x60, 0x12, 0xC9, 0xB2, 0x06, 0xD9, 0x05, 0xEB, 0x8E, 0x00, 0x0E, 0xF1, 0x01, 0x0E, 0x44, 0x63, -+0x5F, 0xFA, 0x8E, 0xFE, 0x05, 0xEB, 0x8E, 0x08, 0x1C, 0x44, 0xC8, 0xF8, 0x3C, 0x61, 0xB2, 0xF5, 0x60, 0x1F, 0x33, 0x68, -+0x75, 0x64, 0x6C, 0x62, 0x00, 0xF0, 0x18, 0x81, 0x00, 0x2B, 0xD2, 0xD1, 0x2C, 0x46, 0x98, 0x46, 0x55, 0x46, 0xC4, 0xF8, -+0x38, 0x61, 0xBA, 0x46, 0x67, 0x46, 0x03, 0x98, 0x8A, 0xF8, 0x0D, 0x10, 0x90, 0xF8, 0x50, 0x30, 0x03, 0xF1, 0x01, 0x0C, -+0x03, 0x46, 0x22, 0x46, 0x1C, 0x30, 0x83, 0xF8, 0x50, 0xC0, 0x39, 0x46, 0x11, 0xF0, 0xA0, 0xFB, 0x53, 0x4B, 0x1B, 0x68, -+0x58, 0x78, 0x00, 0x28, 0x40, 0xF0, 0x11, 0x81, 0xD7, 0xF8, 0x38, 0x11, 0xF2, 0x6C, 0xDF, 0xF8, 0x30, 0xC1, 0xC9, 0x6C, -+0xD0, 0x61, 0x54, 0x23, 0x03, 0xFB, 0x09, 0xF3, 0x3A, 0x69, 0x5C, 0xF8, 0x03, 0x00, 0x22, 0x61, 0x14, 0x31, 0x04, 0x9A, -+0x3A, 0x61, 0x88, 0x42, 0x63, 0x44, 0x00, 0xF0, 0x2A, 0x81, 0x06, 0x9B, 0x07, 0x9A, 0xA3, 0xF1, 0x28, 0x00, 0x05, 0x9B, -+0xC0, 0x1A, 0x03, 0xF1, 0x5C, 0x01, 0x2B, 0x18, 0x1C, 0x68, 0x45, 0xF8, 0x04, 0x4B, 0x1B, 0x68, 0x42, 0xF8, 0x04, 0x3B, -+0x8D, 0x42, 0xF6, 0xD1, 0x3B, 0x4C, 0x48, 0x46, 0xFC, 0xF7, 0x10, 0xF8, 0x23, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0xD7, 0xF8, 0x38, 0x31, 0x04, 0xDB, 0xB3, 0x42, 0x1C, 0xD1, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xB3, 0x42, 0xFA, 0xD0, -+0x36, 0x49, 0x37, 0x48, 0x40, 0xF6, 0x2A, 0x42, 0x12, 0xF0, 0xF2, 0xFE, 0xD7, 0xF8, 0x38, 0x31, 0xB3, 0x42, 0xF0, 0xD0, -+0x23, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x08, 0xDA, 0xB8, 0xF1, 0x00, 0x0F, 0x05, 0xD1, 0x2D, 0x49, 0x2F, 0x48, -+0x4F, 0xF4, 0x43, 0x62, 0x12, 0xF0, 0xE0, 0xFE, 0xD8, 0xF8, 0x24, 0x20, 0x46, 0x46, 0x02, 0xF4, 0x60, 0x1A, 0x26, 0x4B, -+0x1B, 0x68, 0x5B, 0x78, 0x00, 0x2B, 0x58, 0xD1, 0xD7, 0xF8, 0x38, 0x31, 0xD7, 0xF8, 0x10, 0x80, 0xDB, 0x6C, 0x07, 0xF1, -+0x0C, 0x05, 0x03, 0xF1, 0x14, 0x07, 0x1C, 0x4B, 0x04, 0x97, 0x54, 0x24, 0x04, 0xFB, 0x09, 0x34, 0x57, 0x46, 0xDF, 0xF8, -+0x88, 0xB0, 0xDF, 0xF8, 0x7C, 0x90, 0xA2, 0x46, 0x03, 0x9C, 0x94, 0xF8, 0x50, 0x10, 0xDB, 0xF8, 0x58, 0x33, 0x01, 0x31, -+0x84, 0xF8, 0x50, 0x10, 0x30, 0x46, 0x00, 0x21, 0x98, 0x47, 0x58, 0xB1, 0x13, 0x4B, 0x68, 0x60, 0x1B, 0x68, 0x59, 0x78, -+0xDA, 0xF8, 0x00, 0x30, 0x00, 0x29, 0x65, 0xD0, 0xAB, 0x42, 0x00, 0xF0, 0xAD, 0x80, 0x05, 0x46, 0xB7, 0xF5, 0x60, 0x1F, -+0x65, 0xD1, 0xC0, 0xF8, 0x04, 0x80, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x2C, 0x7F, 0xF4, 0xA8, 0xAE, 0x0A, 0x49, -+0x0B, 0x48, 0x40, 0xF6, 0x8B, 0x32, 0x12, 0xF0, 0x99, 0xFE, 0xA0, 0xE6, 0x09, 0x4B, 0x03, 0x93, 0x8B, 0xE6, 0x00, 0xBF, -+0x20, 0x62, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x30, 0x83, 0x32, 0x40, 0x34, 0x36, 0x17, 0x00, 0x64, 0x64, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x4C, 0x92, 0x15, 0x00, 0x3C, 0x91, 0x15, 0x00, 0xC4, 0x63, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x07, 0xF1, 0x50, 0x01, 0xA4, 0xE6, 0xD7, 0xF8, 0x54, 0x80, 0x07, 0xF1, 0x50, 0x05, 0x00, 0x27, 0xA9, 0xE7, 0x00, 0x2E, -+0x7F, 0xF4, 0xA6, 0xAE, 0x49, 0x49, 0x4A, 0x48, 0x40, 0xF6, 0xB6, 0x32, 0x12, 0xF0, 0x6E, 0xFE, 0x9E, 0xE6, 0x03, 0xF4, -+0x60, 0x13, 0xB3, 0xF5, 0x20, 0x1F, 0x3E, 0xD0, 0x40, 0xF6, 0x9B, 0x32, 0x42, 0x49, 0x44, 0x48, 0x12, 0xF0, 0x62, 0xFE, -+0x43, 0x4B, 0x67, 0x6C, 0x1B, 0x68, 0x2A, 0x68, 0xDB, 0xB2, 0x07, 0xEB, 0x83, 0x03, 0xB2, 0xF9, 0x00, 0x20, 0xD3, 0xF8, -+0x3C, 0x41, 0x00, 0x2A, 0xE5, 0x6C, 0xBF, 0xF6, 0x6F, 0xAE, 0x63, 0x6A, 0x03, 0xF4, 0x60, 0x12, 0xB2, 0xF5, 0x60, 0x1F, -+0x60, 0xD0, 0x3A, 0x4A, 0x12, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x64, 0xE6, 0x04, 0x9A, 0x93, 0x42, 0x99, 0xD1, 0xCA, 0xE9, -+0x01, 0x11, 0x05, 0x46, 0x96, 0xE7, 0x34, 0x4B, 0x36, 0x68, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x3F, 0xDB, -+0x77, 0x6A, 0x07, 0xF4, 0x60, 0x17, 0x74, 0xE7, 0x20, 0x46, 0x2C, 0x46, 0x04, 0xEB, 0x8E, 0x0E, 0x55, 0x46, 0xC4, 0xF8, -+0x38, 0x61, 0xBA, 0x46, 0x98, 0x46, 0x67, 0x46, 0xCE, 0xF8, 0x34, 0x00, 0xE3, 0xE6, 0x27, 0x4B, 0x67, 0x6C, 0x1B, 0x68, -+0xDB, 0xB2, 0x07, 0xEB, 0x83, 0x03, 0xD3, 0xF8, 0x3C, 0x41, 0xE5, 0x6C, 0xCB, 0xE7, 0xB0, 0x6A, 0xA3, 0x7A, 0x62, 0x7A, -+0x71, 0x8C, 0xC0, 0xF3, 0xC1, 0x10, 0x00, 0x90, 0x20, 0x46, 0xFE, 0xF7, 0xA1, 0xFB, 0x54, 0x23, 0x1E, 0x49, 0xF2, 0x6C, -+0xD7, 0xF8, 0x54, 0xE0, 0x03, 0xFB, 0x09, 0xF3, 0x04, 0xF1, 0x50, 0x00, 0x51, 0xF8, 0x03, 0xC0, 0xD0, 0x61, 0x07, 0xF1, -+0x50, 0x02, 0xC4, 0xF8, 0x54, 0xE0, 0x94, 0x45, 0x04, 0x9C, 0x7C, 0x65, 0x7F, 0xF4, 0xE5, 0xAE, 0xC8, 0x50, 0xE2, 0xE6, -+0xCA, 0xF8, 0x00, 0x00, 0x05, 0x46, 0x4F, 0xE7, 0x00, 0x2E, 0xBD, 0xD1, 0x0B, 0x49, 0x40, 0xF6, 0x62, 0x42, 0x48, 0x46, -+0x12, 0xF0, 0xF2, 0xFD, 0xB6, 0xE7, 0x04, 0x99, 0x01, 0x22, 0xC3, 0xE9, 0x01, 0x12, 0xD0, 0xE6, 0x40, 0xF6, 0xA5, 0x32, -+0x04, 0x49, 0x0A, 0x48, 0x12, 0xF0, 0xE6, 0xFD, 0x06, 0x4B, 0x1A, 0x68, 0x63, 0x6A, 0xB2, 0xF9, 0x00, 0x20, 0xFC, 0xE5, -+0x70, 0x79, 0x15, 0x00, 0x3C, 0x91, 0x15, 0x00, 0x1C, 0x92, 0x15, 0x00, 0x30, 0x83, 0x32, 0x40, 0x38, 0x36, 0x17, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x34, 0x92, 0x15, 0x00, 0x05, 0x28, 0x10, 0xB5, 0x25, 0xD0, 0x14, 0x4A, 0x00, 0xEB, 0x40, 0x03, -+0xC3, 0xEB, 0xC3, 0x03, 0x02, 0xEB, 0x83, 0x02, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0F, 0x4B, -+0x01, 0x21, 0x19, 0x60, 0x0E, 0x4C, 0x92, 0xF8, 0x50, 0x10, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x31, 0xB9, 0xD2, 0x6A, -+0x22, 0xB1, 0x0B, 0x4B, 0xD3, 0xF8, 0x5C, 0x33, 0x98, 0x47, 0x23, 0x68, 0x33, 0xB1, 0x06, 0x4A, 0x01, 0x3B, 0x12, 0x68, -+0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x10, 0xBD, 0x05, 0x4A, 0xDE, 0xE7, 0x00, 0xBF, 0x20, 0x62, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xC4, 0x63, 0x17, 0x00, 0x03, 0x68, 0x13, 0xF4, -+0xE0, 0x3F, 0x1A, 0xD1, 0x9A, 0x04, 0x4C, 0xBF, 0x03, 0xF0, 0x0F, 0x02, 0x03, 0xF0, 0x07, 0x02, 0x02, 0x2A, 0xC3, 0xF3, -+0xC1, 0x11, 0x88, 0xBF, 0x4F, 0xF4, 0x80, 0x12, 0x23, 0xF0, 0xFF, 0x53, 0x98, 0xBF, 0x4F, 0xF4, 0x00, 0x22, 0x23, 0xF4, -+0xFE, 0x13, 0x42, 0xEA, 0x01, 0x62, 0x13, 0x43, 0x43, 0xF0, 0x80, 0x63, 0x43, 0xF4, 0x00, 0x43, 0x03, 0x60, 0x70, 0x47, -+0xC3, 0x6B, 0x00, 0x2B, 0x00, 0xDB, 0x70, 0x47, 0x10, 0xB4, 0x0E, 0x4C, 0x42, 0x6A, 0x24, 0x68, 0xB4, 0xF9, 0x00, 0x40, -+0x00, 0x2C, 0x01, 0xDA, 0xDB, 0x03, 0x0B, 0xD5, 0x53, 0x69, 0x23, 0xF4, 0xE0, 0x33, 0x00, 0x24, 0x43, 0xF4, 0x80, 0x43, -+0xC4, 0x63, 0x5D, 0xF8, 0x04, 0x4B, 0x53, 0x61, 0xFC, 0xF7, 0xA4, 0xB9, 0x04, 0x49, 0x05, 0x48, 0x5D, 0xF8, 0x04, 0x4B, -+0x40, 0xF6, 0xD9, 0x42, 0x12, 0xF0, 0x28, 0xBD, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x78, 0x92, 0x15, 0x00, -+0x05, 0x28, 0x10, 0xB5, 0x17, 0xD0, 0x0D, 0x4C, 0x00, 0xEB, 0x40, 0x00, 0xC0, 0xEB, 0xC0, 0x00, 0x04, 0xEB, 0x80, 0x04, -+0xA1, 0x6A, 0x31, 0xB1, 0xCB, 0x7A, 0x01, 0x3B, 0xDB, 0xB2, 0xCB, 0x72, 0x13, 0xB1, 0x00, 0x23, 0xA3, 0x62, 0x10, 0xBD, -+0xD1, 0xF8, 0x48, 0x01, 0x11, 0xF0, 0xE8, 0xF8, 0x00, 0x23, 0xA3, 0x62, 0xF7, 0xE7, 0x02, 0x4C, 0xEC, 0xE7, 0x00, 0xBF, -+0x20, 0x62, 0x17, 0x00, 0xC4, 0x63, 0x17, 0x00, 0xF0, 0xB4, 0xC5, 0x6C, 0x42, 0x6A, 0xEB, 0x6C, 0xD0, 0xE9, 0x11, 0x67, -+0x22, 0xF4, 0xC0, 0x12, 0x23, 0xF4, 0x60, 0x13, 0x05, 0xF1, 0x14, 0x0C, 0x42, 0xF4, 0x20, 0x14, 0x43, 0xF4, 0x20, 0x12, -+0x06, 0xF5, 0x82, 0x73, 0xC6, 0xF8, 0x14, 0xC0, 0x33, 0x63, 0x44, 0x62, 0xEA, 0x64, 0x06, 0xF1, 0x0C, 0x00, 0x07, 0xF1, -+0x24, 0x02, 0x06, 0xF5, 0x9C, 0x75, 0x53, 0xF8, 0x04, 0x4B, 0x42, 0xF8, 0x04, 0x4F, 0xAB, 0x42, 0xF9, 0xD1, 0x77, 0xB1, -+0x09, 0x4B, 0x1B, 0x68, 0x5B, 0x78, 0x33, 0xB9, 0xD6, 0xF8, 0x38, 0x31, 0xDB, 0x6C, 0x14, 0x33, 0x0B, 0x60, 0xF0, 0xBC, -+0x70, 0x47, 0x50, 0x36, 0x0E, 0x60, 0xF0, 0xBC, 0x70, 0x47, 0x01, 0x23, 0x38, 0x46, 0x73, 0x60, 0xF5, 0xE7, 0x00, 0xBF, -+0x34, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x47, 0x6A, 0xD0, 0xF8, 0x4C, 0xE0, 0x85, 0xB0, 0x17, 0xF4, 0x00, 0x1C, -+0x9D, 0xF8, 0x38, 0x90, 0x04, 0x46, 0x0E, 0xF1, 0x14, 0x08, 0x0D, 0x46, 0x16, 0x46, 0x9A, 0x46, 0x2A, 0xD0, 0x07, 0xF4, -+0x60, 0x17, 0xB7, 0xF5, 0x20, 0x1F, 0x40, 0xF0, 0xBB, 0x80, 0xD0, 0xF8, 0x44, 0xB0, 0xBB, 0xF8, 0x04, 0x70, 0x07, 0xF0, -+0x03, 0x07, 0x03, 0x2F, 0x40, 0xF0, 0xB2, 0x80, 0xDF, 0xF8, 0x30, 0xC2, 0x83, 0x4F, 0xDC, 0xF8, 0x00, 0xC0, 0x3F, 0x68, -+0x9C, 0xF8, 0x3E, 0xC0, 0x07, 0xF0, 0x3F, 0x07, 0xBC, 0x45, 0x00, 0xF2, 0xA5, 0x80, 0xDB, 0xF8, 0x24, 0x70, 0x97, 0x42, -+0x40, 0xF2, 0xC1, 0x80, 0x7C, 0x4C, 0xCD, 0xF8, 0x38, 0x90, 0xD4, 0xF8, 0x70, 0x43, 0xA4, 0x46, 0x05, 0xB0, 0xBD, 0xE8, -+0xF0, 0x4F, 0x60, 0x47, 0x83, 0x6C, 0x00, 0x2B, 0x00, 0xF0, 0x92, 0x80, 0x5B, 0x6A, 0x13, 0xF0, 0x10, 0x03, 0x00, 0xF0, -+0x8D, 0x80, 0x82, 0x88, 0x00, 0x2A, 0x00, 0xF0, 0x8F, 0x80, 0xC3, 0x8B, 0x1F, 0x07, 0x00, 0xF1, 0x8B, 0x80, 0xDE, 0xF8, -+0x24, 0x10, 0x00, 0x29, 0x00, 0xF0, 0xB9, 0x80, 0x08, 0x88, 0x83, 0xB2, 0x00, 0x04, 0x00, 0xF1, 0xB4, 0x80, 0x6F, 0xEA, -+0x43, 0x43, 0x6F, 0xEA, 0x53, 0x43, 0x0B, 0x80, 0x94, 0xF8, 0x33, 0x20, 0x94, 0xF8, 0x32, 0x30, 0x04, 0x32, 0x04, 0x33, -+0x84, 0xF8, 0x32, 0x30, 0x84, 0xF8, 0x33, 0x20, 0xDE, 0xE9, 0x0A, 0x12, 0xD3, 0x1D, 0x23, 0xF0, 0x03, 0x03, 0x04, 0x33, -+0x9B, 0xB2, 0x04, 0x32, 0x04, 0x31, 0xB3, 0x42, 0xCE, 0xE9, 0x0A, 0x12, 0x6D, 0xD8, 0xA2, 0x88, 0x32, 0xB1, 0xE3, 0x8B, -+0x1F, 0x07, 0x03, 0xD4, 0x5A, 0x4B, 0xDB, 0x6E, 0x41, 0xF8, 0x03, 0x3C, 0x23, 0x68, 0x2B, 0x60, 0x00, 0x2B, 0x36, 0xD0, -+0x11, 0x46, 0xDF, 0xF8, 0x70, 0xB1, 0x54, 0x4F, 0x32, 0x46, 0x00, 0x29, 0x2C, 0xD0, 0xE1, 0x8B, 0x0E, 0x07, 0x29, 0xD4, -+0x99, 0x88, 0x39, 0xB3, 0xD9, 0x8B, 0x08, 0x07, 0x24, 0xD4, 0x4D, 0x49, 0xDB, 0xF8, 0x00, 0x00, 0x09, 0x68, 0x90, 0xF8, -+0x3E, 0x60, 0x01, 0xF0, 0x3F, 0x01, 0x8E, 0x42, 0x1A, 0xD8, 0x5B, 0x6A, 0xBC, 0xF1, 0x00, 0x0F, 0x4C, 0xD1, 0x9B, 0x02, -+0x17, 0xD5, 0xCD, 0xF8, 0x00, 0x90, 0xD7, 0xF8, 0x54, 0x63, 0x03, 0x92, 0x53, 0x46, 0x29, 0x46, 0x20, 0x46, 0xB0, 0x47, -+0x03, 0x9A, 0x00, 0x28, 0x77, 0xD0, 0x2B, 0x68, 0x00, 0x2B, 0x74, 0xD0, 0x60, 0x6A, 0xA1, 0x88, 0x00, 0xF4, 0x00, 0x1C, -+0x00, 0x29, 0xD2, 0xD1, 0xBC, 0xF1, 0x00, 0x0F, 0x47, 0xD1, 0x63, 0x6C, 0xD3, 0xB9, 0x3B, 0x48, 0x11, 0xF0, 0x2C, 0xF8, -+0x3A, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x05, 0x46, 0x56, 0xDB, 0x54, 0x23, 0x1C, 0x22, 0x37, 0x48, -+0x13, 0xFB, 0x09, 0x29, 0x00, 0x22, 0x01, 0x23, 0xAA, 0x80, 0xEB, 0x72, 0x48, 0x44, 0x29, 0x46, 0x65, 0x64, 0x10, 0xF0, -+0xF7, 0xFF, 0x01, 0xE0, 0x4F, 0xF0, 0x00, 0x08, 0x40, 0x46, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xDE, 0xF8, 0x2C, 0x30, -+0x03, 0x33, 0x23, 0xF0, 0x03, 0x03, 0x04, 0x33, 0x9B, 0xB2, 0x9E, 0x42, 0x9A, 0xD2, 0x25, 0x4B, 0x40, 0x46, 0xD3, 0xF8, -+0xBC, 0x33, 0x49, 0x46, 0x98, 0x47, 0x4F, 0xF0, 0x00, 0x08, 0xE9, 0xE7, 0xCD, 0xF8, 0x00, 0x90, 0x99, 0x02, 0x54, 0xBF, -+0xD7, 0xF8, 0x50, 0x63, 0xD7, 0xF8, 0x4C, 0x63, 0xAF, 0xE7, 0xFE, 0xF7, 0xD1, 0xF9, 0xDB, 0xF8, 0x38, 0x31, 0x67, 0x6A, -+0x1B, 0x68, 0x2B, 0x60, 0x5B, 0xB3, 0xA2, 0x88, 0x07, 0xF4, 0x00, 0x1C, 0x80, 0xE7, 0x63, 0x6C, 0xD3, 0xF8, 0x38, 0x21, -+0x03, 0xF1, 0x0C, 0x08, 0xD2, 0x6C, 0x00, 0x21, 0x40, 0x46, 0xD1, 0x61, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xDE, 0xF8, -+0x2C, 0x30, 0x03, 0x33, 0x23, 0xF0, 0x03, 0x03, 0x04, 0x33, 0x9B, 0xB2, 0x9E, 0x42, 0xCC, 0xD3, 0x00, 0x29, 0x3F, 0xF4, -+0x65, 0xAF, 0xDE, 0xF8, 0x28, 0x10, 0x5D, 0xE7, 0x00, 0x28, 0xA6, 0xD1, 0x0C, 0x49, 0x0D, 0x48, 0x40, 0xF6, 0x92, 0x52, -+0x12, 0xF0, 0xD6, 0xFB, 0x9F, 0xE7, 0x67, 0x6A, 0x07, 0xF4, 0x00, 0x1C, 0x8C, 0xE7, 0x07, 0xF4, 0x00, 0x1C, 0x89, 0xE7, -+0x54, 0x83, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x94, 0x64, 0x17, 0x00, 0x8C, 0x64, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x3C, 0x90, 0x15, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x08, 0xB5, 0x04, 0x28, -+0x2C, 0xD8, 0xDF, 0xE8, 0x00, 0xF0, 0x0B, 0x23, 0x13, 0x1B, 0x03, 0x00, 0x1B, 0x4B, 0x1B, 0x68, 0x13, 0xF0, 0x03, 0x0F, -+0x0C, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x08, 0xBD, 0x17, 0x4B, 0x1B, 0x68, 0x13, 0xF0, 0x30, 0x0F, 0x0C, 0xBF, 0x01, 0x20, -+0x00, 0x20, 0x08, 0xBD, 0x13, 0x4B, 0x1B, 0x68, 0x13, 0xF4, 0x40, 0x5F, 0x0C, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x08, 0xBD, -+0x0F, 0x4B, 0x1B, 0x68, 0x13, 0xF4, 0x40, 0x3F, 0x0C, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x08, 0xBD, 0x0B, 0x4B, 0x1B, 0x68, -+0x13, 0xF4, 0x40, 0x7F, 0x0C, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x08, 0xBD, 0x08, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x01, 0xDB, 0x00, 0x20, 0x08, 0xBD, 0x05, 0x49, 0x06, 0x48, 0x40, 0xF2, 0xF3, 0x12, 0x12, 0xF0, 0x7E, 0xFB, -+0x00, 0x20, 0x08, 0xBD, 0x88, 0x81, 0x32, 0x40, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, -+0x90, 0xF8, 0x25, 0x30, 0xE3, 0xB1, 0x10, 0xB5, 0x0F, 0x4A, 0x10, 0x4B, 0x11, 0x69, 0xD3, 0xF8, 0xE0, 0x31, 0x01, 0xF5, -+0x9C, 0x51, 0x84, 0xB0, 0x04, 0x46, 0x08, 0x31, 0x0C, 0x48, 0x98, 0x47, 0x00, 0x21, 0x02, 0x22, 0x05, 0x23, 0x94, 0xF8, -+0x23, 0x00, 0xCD, 0xE9, 0x00, 0x32, 0xCD, 0xE9, 0x02, 0x11, 0x25, 0x23, 0x40, 0xF6, 0xC4, 0x12, 0xFD, 0xF7, 0x5E, 0xFF, -+0x04, 0xB0, 0x10, 0xBD, 0x03, 0x4A, 0xC2, 0xE9, 0x01, 0x33, 0x70, 0x47, 0x00, 0x10, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0x94, 0x64, 0x17, 0x00, 0x03, 0x68, 0x70, 0xB4, 0xC3, 0xF3, 0xC2, 0x24, 0x05, 0x2C, 0x01, 0xD0, 0x70, 0xBC, 0x70, 0x47, -+0xC3, 0xF3, 0x00, 0x26, 0x75, 0x00, 0x03, 0xF0, 0x7F, 0x04, 0x35, 0x44, 0x04, 0xEB, 0x44, 0x04, 0x05, 0xEB, 0x44, 0x04, -+0xC3, 0xF3, 0x41, 0x25, 0x2C, 0x44, 0x16, 0x4D, 0x35, 0xF8, 0x14, 0x50, 0xC3, 0xF3, 0xC0, 0x14, 0x05, 0xFA, 0x04, 0xF4, -+0x01, 0x3A, 0x02, 0xFB, 0x04, 0xF2, 0x8A, 0x42, 0xC3, 0xF3, 0xC1, 0x14, 0xE2, 0xD2, 0x13, 0xF4, 0xE0, 0x3F, 0x06, 0xD0, -+0x23, 0xF4, 0xE0, 0x33, 0x43, 0xF4, 0x00, 0x43, 0x70, 0xBC, 0x03, 0x60, 0x70, 0x47, 0x03, 0xF0, 0x0F, 0x02, 0x02, 0x2A, -+0x23, 0xF0, 0xFF, 0x53, 0x8C, 0xBF, 0x4F, 0xF4, 0x80, 0x12, 0x4F, 0xF4, 0x00, 0x22, 0x23, 0xF4, 0xFE, 0x13, 0x42, 0xEA, -+0x04, 0x62, 0x13, 0x43, 0x43, 0xF0, 0x80, 0x63, 0x43, 0xF4, 0x00, 0x43, 0xE8, 0xE7, 0x00, 0xBF, 0xE0, 0x94, 0x15, 0x00, -+0x70, 0xB5, 0x0C, 0x4D, 0x00, 0xEB, 0x40, 0x03, 0x05, 0xEB, 0x83, 0x03, 0x93, 0xF8, 0x2E, 0x20, 0x72, 0xB1, 0x04, 0x46, -+0x46, 0x00, 0x58, 0x6A, 0x00, 0x22, 0x83, 0xF8, 0x2E, 0x20, 0x10, 0xB1, 0x21, 0x46, 0xFB, 0xF7, 0x35, 0xFF, 0x34, 0x44, -+0x05, 0xEB, 0x84, 0x05, 0x00, 0x23, 0x6B, 0x62, 0x70, 0xBD, 0x00, 0xBF, 0x94, 0x64, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x83, 0xB0, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x41, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x41, 0x4F, -+0x41, 0x4E, 0x3B, 0x68, 0xDF, 0xF8, 0x0C, 0x81, 0x01, 0x33, 0x00, 0x24, 0x3B, 0x60, 0x35, 0x46, 0xA2, 0x46, 0x4F, 0xF0, -+0x01, 0x0B, 0x96, 0xF8, 0x60, 0x10, 0x0B, 0xFA, 0x04, 0xF3, 0x0B, 0x42, 0x5F, 0xFA, 0x83, 0xF9, 0x4D, 0xD1, 0x96, 0xF8, -+0x61, 0x10, 0x11, 0xEA, 0x09, 0x0F, 0x30, 0xD0, 0xA8, 0x6A, 0x21, 0xEA, 0x03, 0x03, 0x86, 0xF8, 0x61, 0x30, 0x03, 0x07, -+0x4F, 0xD0, 0x33, 0x4B, 0x43, 0xF8, 0x24, 0x00, 0xE0, 0xB2, 0xD8, 0xF8, 0xD0, 0x33, 0x98, 0x47, 0x95, 0xF8, 0x2C, 0x30, -+0x85, 0xF8, 0x2D, 0x30, 0x49, 0xEA, 0x0A, 0x0A, 0x01, 0x34, 0x04, 0x2C, 0x05, 0xF1, 0x0C, 0x05, 0xD9, 0xD1, 0xBA, 0xF1, -+0x00, 0x0F, 0x47, 0xD0, 0x29, 0x4A, 0x2A, 0x4B, 0x11, 0x69, 0xD3, 0xF8, 0xE0, 0x31, 0x29, 0x48, 0x01, 0xF5, 0x00, 0x51, -+0x98, 0x47, 0x3B, 0x68, 0x33, 0xB1, 0x20, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x3B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, -+0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x95, 0xF8, 0x2D, 0x30, 0x00, 0x2B, 0xDE, 0xD0, 0x01, 0x3B, 0xDB, 0xB2, 0x85, 0xF8, -+0x2D, 0x30, 0x5B, 0xB9, 0x32, 0x69, 0xA3, 0x1C, 0xE0, 0xB2, 0x52, 0xF8, 0x23, 0x30, 0x17, 0x4A, 0x42, 0xF8, 0x24, 0x30, -+0xD8, 0xF8, 0xD0, 0x33, 0x98, 0x47, 0xCD, 0xE7, 0x49, 0xEA, 0x0A, 0x0A, 0xCA, 0xE7, 0xE0, 0xB2, 0x01, 0x93, 0xFF, 0xF7, -+0xBD, 0xFE, 0x01, 0x9B, 0x00, 0x28, 0xF5, 0xD0, 0x96, 0xF8, 0x60, 0x10, 0x21, 0xEA, 0x03, 0x01, 0x86, 0xF8, 0x60, 0x10, -+0xA3, 0xE7, 0x95, 0xF8, 0x2E, 0x30, 0x00, 0x2B, 0xB2, 0xD1, 0x85, 0xF8, 0x2E, 0xB0, 0x96, 0xF8, 0x60, 0x30, 0x49, 0xEA, -+0x03, 0x03, 0x86, 0xF8, 0x60, 0x30, 0xA9, 0xE7, 0xC6, 0xF8, 0x18, 0xA0, 0xBD, 0xE7, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x94, 0x64, 0x17, 0x00, 0x00, 0x02, 0x32, 0x40, 0x00, 0x10, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0xA8, 0x64, 0x17, 0x00, 0x70, 0xB5, 0x14, 0x4C, 0x94, 0xF8, 0x62, 0x20, 0x4A, 0xB1, 0x94, 0xF8, 0x61, 0x20, 0xA5, 0x69, -+0x01, 0x21, 0x01, 0xFA, 0x00, 0xF3, 0x13, 0x43, 0x84, 0xF8, 0x61, 0x30, 0x05, 0xB1, 0x70, 0xBD, 0x0D, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x07, 0xDB, 0x0B, 0x4B, 0x0C, 0x48, 0xD3, 0xF8, 0xC8, 0x33, 0xA3, 0x61, 0xBD, 0xE8, -+0x70, 0x40, 0x18, 0x47, 0xFF, 0xF7, 0x74, 0xFE, 0x00, 0x28, 0xF3, 0xD1, 0xBD, 0xE8, 0x70, 0x40, 0x06, 0x49, 0x07, 0x48, -+0x4F, 0xF4, 0x22, 0x72, 0x12, 0xF0, 0xF4, 0xB9, 0x94, 0x64, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xA8, 0x64, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x90, 0x93, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x1D, 0x4D, 0x1E, 0x4E, -+0x1E, 0x4F, 0xDF, 0xF8, 0x80, 0x80, 0xDF, 0xF8, 0x80, 0x90, 0x2B, 0x68, 0x00, 0x24, 0x01, 0x2C, 0x11, 0xD0, 0x53, 0xF8, -+0x24, 0x30, 0x1B, 0xB9, 0x33, 0x69, 0xA2, 0x1C, 0x53, 0xF8, 0x22, 0x30, 0x47, 0xF8, 0x24, 0x30, 0xE0, 0xB2, 0xFF, 0xF7, -+0xFB, 0xFE, 0x03, 0x2C, 0x0D, 0xD0, 0x01, 0x34, 0x01, 0x2C, 0x2B, 0x68, 0xED, 0xD1, 0x5B, 0x68, 0x73, 0xB9, 0x33, 0x69, -+0xDB, 0x68, 0xC8, 0xF8, 0x00, 0x30, 0x01, 0x20, 0xFF, 0xF7, 0xEC, 0xFE, 0xF1, 0xE7, 0x0D, 0x48, 0x08, 0xF0, 0x3C, 0xFC, -+0x00, 0x23, 0xB3, 0x61, 0xBD, 0xE8, 0xF8, 0x83, 0xC3, 0xF3, 0x0B, 0x02, 0x00, 0x2A, 0xEE, 0xD1, 0x32, 0x69, 0xD2, 0x68, -+0x03, 0xEA, 0x09, 0x03, 0xC2, 0xF3, 0x0B, 0x02, 0x13, 0x43, 0xC8, 0xF8, 0x00, 0x30, 0xE6, 0xE7, 0xAC, 0x35, 0x17, 0x00, -+0x94, 0x64, 0x17, 0x00, 0x00, 0x02, 0x32, 0x40, 0xA8, 0x64, 0x17, 0x00, 0x04, 0x02, 0x32, 0x40, 0x00, 0xF0, 0xFF, 0xFF, -+0x1A, 0x4A, 0x1B, 0x4B, 0xF0, 0xB4, 0x02, 0xF1, 0x74, 0x04, 0x94, 0xE8, 0x03, 0x00, 0x16, 0x69, 0xC3, 0xF8, 0xE0, 0x03, -+0xF0, 0x6D, 0xA3, 0xF8, 0xE4, 0x13, 0xB6, 0xF8, 0x60, 0x10, 0xC3, 0xF8, 0xE6, 0x03, 0xA3, 0xF8, 0xEA, 0x13, 0x94, 0xE8, -+0x03, 0x00, 0xD3, 0xF8, 0xD4, 0x53, 0xA3, 0xF8, 0xF0, 0x13, 0xD1, 0x6E, 0xC3, 0xF8, 0xEC, 0x03, 0xC3, 0xF8, 0xF6, 0x13, -+0x0D, 0x4F, 0x0E, 0x48, 0x03, 0xF5, 0x88, 0x64, 0x00, 0x21, 0x82, 0xF8, 0x88, 0x10, 0xC3, 0xF8, 0xBC, 0x43, 0x05, 0xF4, -+0x7F, 0x45, 0x03, 0xF5, 0x66, 0x74, 0x4F, 0xF4, 0x00, 0x52, 0xC3, 0xF8, 0xD4, 0x53, 0xC3, 0xF8, 0x9C, 0x13, 0x3C, 0x60, -+0xF0, 0xBC, 0x02, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x94, 0x64, 0x17, 0x00, 0x60, 0x5D, 0x18, 0x00, 0xAC, 0x81, 0x32, 0x40, -+0x80, 0x81, 0x32, 0x40, 0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0x68, 0xB2, 0x03, 0x68, 0x90, 0x4C, 0xDB, 0xF8, 0x10, 0x20, -+0x80, 0x46, 0x53, 0xF8, 0x26, 0x0F, 0xA0, 0x64, 0xD0, 0x6D, 0x9D, 0x88, 0xC4, 0xF8, 0x4E, 0x00, 0x18, 0x68, 0xB8, 0xF8, -+0x12, 0x10, 0x9B, 0x88, 0xB2, 0xF8, 0x60, 0x20, 0x60, 0x65, 0x00, 0x27, 0x83, 0xB0, 0x04, 0xF1, 0x5C, 0x00, 0xA4, 0xF8, -+0x4C, 0x50, 0xA4, 0xF8, 0x52, 0x20, 0xA4, 0xF8, 0x58, 0x30, 0xA7, 0x61, 0xFE, 0xF7, 0x78, 0xFC, 0x63, 0x6F, 0xD8, 0xF8, -+0x00, 0x10, 0x80, 0x4A, 0x91, 0xF8, 0x23, 0xC0, 0xA5, 0x69, 0xDE, 0x1C, 0x42, 0xF2, 0x38, 0x0E, 0x26, 0xF0, 0x03, 0x06, -+0x24, 0x23, 0x39, 0x46, 0x04, 0x36, 0x13, 0xFB, 0x0C, 0xE7, 0x06, 0xEB, 0x80, 0x06, 0x4F, 0xEA, 0x40, 0x2E, 0x17, 0x44, -+0xB6, 0xB2, 0x89, 0x46, 0x04, 0xF1, 0x5C, 0x02, 0xA4, 0x46, 0x4F, 0xF4, 0x20, 0x10, 0xF2, 0x46, 0x01, 0x97, 0x1C, 0xE0, -+0x0F, 0x33, 0x1B, 0x09, 0x1B, 0x02, 0x43, 0xF0, 0x30, 0x03, 0x9B, 0xB2, 0x4A, 0xEA, 0x00, 0x00, 0x0B, 0x43, 0x90, 0x63, -+0xC2, 0xF8, 0x24, 0x90, 0xC2, 0xF8, 0x3C, 0x90, 0xA2, 0xF8, 0x58, 0x30, 0xCC, 0xF8, 0x08, 0x20, 0xA5, 0x69, 0x35, 0x44, -+0xA5, 0x61, 0x94, 0x46, 0x4F, 0xF4, 0x40, 0x10, 0x01, 0x31, 0x09, 0x29, 0x02, 0xF1, 0x5C, 0x02, 0x22, 0xD0, 0x01, 0x9F, -+0x57, 0xF8, 0x04, 0x3B, 0x01, 0x97, 0x00, 0x2B, 0xF4, 0xD0, 0xD8, 0xF8, 0x08, 0x70, 0x06, 0xEB, 0x05, 0x0E, 0xBE, 0x45, -+0x16, 0xD8, 0xB3, 0xF5, 0x7C, 0x7F, 0xD3, 0xD9, 0xB3, 0xF5, 0x80, 0x6F, 0x0D, 0xD9, 0xB3, 0xF5, 0x86, 0x4F, 0x45, 0xD8, -+0x6F, 0xF4, 0x7C, 0x75, 0x2B, 0x44, 0xC3, 0xF3, 0x07, 0x13, 0x1B, 0x02, 0x43, 0xF4, 0x80, 0x43, 0x43, 0xF0, 0x30, 0x03, -+0xC8, 0xE7, 0x44, 0xF2, 0x30, 0x03, 0xC5, 0xE7, 0x00, 0x2D, 0x3B, 0xD0, 0xDC, 0xF8, 0x38, 0x30, 0x03, 0xF4, 0x60, 0x11, -+0x00, 0x22, 0xB1, 0xF5, 0x20, 0x1F, 0xCC, 0xF8, 0x08, 0x20, 0x63, 0xD0, 0x4C, 0x49, 0x4D, 0x4A, 0x4D, 0x4E, 0x43, 0xF4, -+0x60, 0x13, 0xCC, 0xF8, 0x38, 0x30, 0x0D, 0x68, 0x10, 0x68, 0x04, 0x35, 0xC0, 0xF3, 0x05, 0x20, 0x06, 0xE0, 0x33, 0x68, -+0xDB, 0x04, 0x08, 0xD4, 0x0B, 0x68, 0x5B, 0x1B, 0x00, 0x2B, 0x04, 0xDA, 0x13, 0x68, 0x03, 0xF0, 0x3F, 0x03, 0x98, 0x42, -+0xF3, 0xD0, 0xE3, 0x6B, 0x42, 0x48, 0x43, 0x49, 0x43, 0x4A, 0x04, 0x60, 0x03, 0xF4, 0x7F, 0x43, 0xE3, 0x63, 0x4F, 0xF4, -+0x00, 0x50, 0x00, 0x23, 0x08, 0x60, 0x63, 0x60, 0x8B, 0xF8, 0x88, 0x30, 0x62, 0x62, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0xB3, 0xF5, 0x88, 0x4F, 0x1F, 0xD8, 0x48, 0xF2, 0x30, 0x03, 0x87, 0xE7, 0xD4, 0xF8, 0x98, 0x30, 0x37, 0x4A, 0x35, 0x4E, -+0x35, 0x49, 0xC4, 0xF8, 0x94, 0x50, 0x03, 0xF4, 0x7F, 0x43, 0xC4, 0xF8, 0x98, 0x30, 0xA2, 0xF5, 0x79, 0x73, 0xC4, 0xE9, -+0x18, 0x55, 0x8B, 0xF8, 0x88, 0x50, 0x4F, 0xF4, 0x00, 0x50, 0x33, 0x60, 0x30, 0x23, 0x08, 0x60, 0xA4, 0xF8, 0xB4, 0x30, -+0xC4, 0xF8, 0x80, 0x20, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xB3, 0xF5, 0x0F, 0x3F, 0x2A, 0xD9, 0xB3, 0xF5, 0x11, 0x3F, -+0x32, 0xD9, 0x28, 0x4D, 0xAB, 0x42, 0x32, 0xD8, 0xA3, 0xF1, 0x01, 0x13, 0xA3, 0xF5, 0x44, 0x43, 0xC3, 0xF3, 0xC7, 0x33, -+0x1B, 0x02, 0x43, 0xF4, 0x40, 0x43, 0x43, 0xF0, 0x30, 0x03, 0x55, 0xE7, 0xDC, 0xF8, 0x3C, 0x30, 0xCC, 0xF8, 0x38, 0x20, -+0xCC, 0xF8, 0x04, 0x20, 0x8B, 0xF8, 0x88, 0x20, 0x19, 0x48, 0x1A, 0x49, 0x1A, 0x4A, 0xCC, 0xF8, 0x24, 0x20, 0x03, 0xF4, -+0x7F, 0x43, 0xCC, 0xF8, 0x3C, 0x30, 0x4F, 0xF4, 0x00, 0x53, 0xC0, 0xF8, 0x00, 0xC0, 0x0B, 0x60, 0x03, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0xA3, 0xF5, 0x70, 0x53, 0x01, 0x3B, 0xC3, 0xF3, 0xC7, 0x23, 0x1B, 0x02, 0x43, 0xF4, 0x00, 0x43, 0x43, 0xF0, -+0x30, 0x03, 0x31, 0xE7, 0x4C, 0xF2, 0x30, 0x03, 0x2E, 0xE7, 0x4F, 0xF6, 0x30, 0x65, 0x4F, 0xF6, 0x30, 0x77, 0xB3, 0xF1, -+0xFF, 0x3F, 0x08, 0xBF, 0x3D, 0x46, 0x2B, 0x46, 0x24, 0xE7, 0x00, 0xBF, 0x60, 0x5D, 0x18, 0x00, 0x7C, 0x36, 0x17, 0x00, -+0x20, 0x01, 0x32, 0x40, 0x54, 0x83, 0x32, 0x40, 0x78, 0x80, 0x32, 0x40, 0xAC, 0x81, 0x32, 0x40, 0x80, 0x81, 0x32, 0x40, -+0xA0, 0x61, 0x18, 0x00, 0x00, 0xC4, 0x20, 0x00, 0x94, 0x64, 0x17, 0x00, 0x1C, 0x4A, 0x1D, 0x49, 0x13, 0x68, 0xF0, 0xB4, -+0x03, 0xF5, 0xDA, 0x53, 0x1B, 0x4F, 0x1C, 0x4E, 0x1C, 0x4C, 0x1D, 0x4D, 0x18, 0x33, 0x3B, 0x60, 0x40, 0x23, 0x33, 0x60, -+0x23, 0x68, 0x43, 0xF0, 0x40, 0x03, 0x23, 0x60, 0x17, 0x68, 0x0C, 0x68, 0x01, 0x23, 0x10, 0x3E, 0x04, 0x37, 0xC4, 0xF3, -+0x05, 0x24, 0x85, 0xF8, 0x8C, 0x30, 0x06, 0xE0, 0x33, 0x68, 0xDB, 0x04, 0x08, 0xD4, 0x13, 0x68, 0xDB, 0x1B, 0x00, 0x2B, -+0x04, 0xDA, 0x0B, 0x68, 0x03, 0xF0, 0x3F, 0x03, 0x9C, 0x42, 0xF3, 0xD0, 0xC3, 0x6B, 0x0E, 0x4C, 0x0E, 0x4A, 0x0F, 0x49, -+0x42, 0x62, 0x03, 0xF4, 0x7F, 0x43, 0xC3, 0x63, 0x00, 0x22, 0x4F, 0xF4, 0x00, 0x53, 0x42, 0x60, 0x85, 0xF8, 0x88, 0x20, -+0x20, 0x60, 0xF0, 0xBC, 0x0B, 0x60, 0x70, 0x47, 0x20, 0x01, 0x32, 0x40, 0x54, 0x83, 0x32, 0x40, 0x40, 0x01, 0x32, 0x40, -+0x88, 0x80, 0x32, 0x40, 0x8C, 0x80, 0x32, 0x40, 0x94, 0x64, 0x17, 0x00, 0xAC, 0x81, 0x32, 0x40, 0xA0, 0x61, 0x18, 0x00, -+0x80, 0x81, 0x32, 0x40, 0x2D, 0xE9, 0xF0, 0x41, 0x10, 0x4F, 0x0C, 0x23, 0x0E, 0x46, 0x54, 0x25, 0x04, 0x46, 0x15, 0xFB, -+0x01, 0x30, 0x05, 0xFB, 0x06, 0x75, 0x38, 0x44, 0xD4, 0xF8, 0x4C, 0x80, 0x10, 0xF0, 0xEC, 0xFB, 0x95, 0xF8, 0x50, 0x30, -+0xA2, 0x88, 0x01, 0x3B, 0x85, 0xF8, 0x50, 0x30, 0x22, 0xB9, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xFD, 0xF7, 0x22, 0xBA, -+0xD8, 0xF8, 0x50, 0x10, 0x32, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xFC, 0xF7, 0xF6, 0xBB, 0x20, 0x62, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x47, 0x00, 0x23, 0x2E, 0x4D, 0x03, 0x60, 0x95, 0xF8, 0x8C, 0x30, 0x82, 0xB0, 0x00, 0x2B, 0x37, 0xD1, -+0x95, 0xF8, 0x85, 0x30, 0x03, 0x2B, 0x33, 0xD8, 0x29, 0x4E, 0xDF, 0xF8, 0xB4, 0xA0, 0x81, 0x46, 0x4F, 0xF0, 0x03, 0x08, -+0x14, 0xE0, 0x95, 0xF8, 0x7E, 0x30, 0xDA, 0xF8, 0x64, 0x73, 0x00, 0x93, 0x2A, 0x6F, 0xB5, 0xF8, 0x7A, 0x30, 0x49, 0x46, -+0x20, 0x46, 0xB8, 0x47, 0x07, 0x46, 0x20, 0xBB, 0x95, 0xF8, 0x85, 0x30, 0x08, 0xF1, 0xFF, 0x38, 0x98, 0x45, 0xA6, 0xF1, -+0x54, 0x06, 0x17, 0xDB, 0x96, 0xF8, 0x16, 0x31, 0x5F, 0xFA, 0x88, 0xF7, 0x01, 0x2B, 0x85, 0xF8, 0x7E, 0x70, 0x0F, 0xD0, -+0xD6, 0xF8, 0x08, 0x41, 0x00, 0x2C, 0xEB, 0xD0, 0x63, 0x6A, 0x9B, 0x02, 0xDB, 0xD4, 0xE3, 0x6C, 0x1B, 0x6D, 0x00, 0x2B, -+0xD7, 0xDA, 0x20, 0x46, 0x39, 0x46, 0xFF, 0xF7, 0x99, 0xFF, 0xEF, 0xE7, 0x00, 0x27, 0x38, 0x46, 0x02, 0xB0, 0xBD, 0xE8, -+0xF0, 0x87, 0x0E, 0x4B, 0x64, 0x6C, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x07, 0xDB, 0xA3, 0x88, 0x38, 0x46, -+0x43, 0xF4, 0x00, 0x73, 0xA3, 0x80, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0x2C, 0xF5, 0xD1, 0x06, 0x49, 0x07, 0x48, -+0x40, 0xF2, 0xDF, 0x42, 0x11, 0xF0, 0x88, 0xFF, 0xEE, 0xE7, 0x00, 0xBF, 0x94, 0x64, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x3C, 0x90, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0xDF, 0xF8, 0x8C, 0x92, 0x99, 0xF8, 0x7E, 0x80, 0x83, 0xB0, 0x04, 0x46, 0x00, 0x27, 0x40, 0x46, 0x01, 0x97, 0xFB, 0xF7, -+0x0D, 0xFE, 0x99, 0xF8, 0x7E, 0x00, 0xFF, 0xF7, 0x15, 0xFA, 0x00, 0x2C, 0x00, 0xF0, 0xA4, 0x80, 0x63, 0x6A, 0x9E, 0x02, -+0x76, 0xD5, 0x03, 0xF4, 0x60, 0x10, 0xB0, 0xF5, 0x60, 0x1F, 0x65, 0x6C, 0x00, 0xF0, 0xE1, 0x80, 0xB0, 0xF5, 0x40, 0x1F, -+0x00, 0xF0, 0xCE, 0x80, 0xAA, 0x88, 0x02, 0xF0, 0x03, 0x02, 0x03, 0x2A, 0x8E, 0x4A, 0x12, 0x68, 0x92, 0xF8, 0x01, 0xC0, -+0x00, 0xF0, 0xFF, 0x80, 0x2A, 0x6B, 0x52, 0x69, 0x00, 0x21, 0xC2, 0xF3, 0xC1, 0x1E, 0xC5, 0xE9, 0x0E, 0x11, 0x69, 0x63, -+0x0E, 0x46, 0x0A, 0x46, 0x14, 0xE0, 0xD1, 0xF8, 0x4C, 0x31, 0x9A, 0x45, 0x02, 0xF1, 0x01, 0x03, 0x22, 0xD9, 0xDA, 0xB2, -+0x05, 0xEB, 0x82, 0x03, 0xB0, 0xF5, 0x60, 0x1F, 0x4E, 0x63, 0x56, 0x46, 0xC3, 0xF8, 0x3C, 0x41, 0x20, 0xD0, 0x24, 0x68, -+0x34, 0xB3, 0x63, 0x6A, 0x03, 0xF4, 0x60, 0x10, 0xE1, 0x6C, 0xD1, 0xF8, 0x2C, 0xA0, 0xC3, 0xF3, 0x49, 0x2B, 0x0A, 0xF1, -+0x03, 0x03, 0x23, 0xF0, 0x03, 0x03, 0x0B, 0xF1, 0x01, 0x0A, 0x03, 0xEB, 0x8A, 0x03, 0x9B, 0xB2, 0x96, 0x45, 0x05, 0xEB, -+0x82, 0x01, 0x03, 0xEB, 0x06, 0x0A, 0xD6, 0xD8, 0x05, 0xEB, 0x82, 0x03, 0xB0, 0xF5, 0x60, 0x1F, 0x56, 0x46, 0xC3, 0xF8, -+0x3C, 0x41, 0xDE, 0xD1, 0x6B, 0x6A, 0xB3, 0x42, 0x00, 0xF0, 0xCE, 0x80, 0x00, 0x23, 0xC5, 0xE9, 0x0D, 0x33, 0xEB, 0x63, -+0x00, 0x2F, 0x49, 0xD0, 0x08, 0xEB, 0x48, 0x03, 0x09, 0xEB, 0x83, 0x09, 0x01, 0x9A, 0xC9, 0xF8, 0x24, 0x70, 0xBC, 0xF1, -+0x00, 0x0F, 0x30, 0xD1, 0x93, 0x6B, 0x9B, 0x02, 0x00, 0xF1, 0x97, 0x80, 0x53, 0x68, 0x00, 0x2B, 0x4B, 0xD1, 0x61, 0x49, -+0x54, 0x23, 0x03, 0xFB, 0x08, 0xF8, 0x01, 0xEB, 0x08, 0x03, 0xC3, 0xE9, 0x01, 0xCC, 0x41, 0xF8, 0x08, 0x20, 0x40, 0xE0, -+0xA3, 0x6C, 0x3B, 0xB3, 0xE3, 0x8B, 0xE2, 0x6C, 0x13, 0xF4, 0x00, 0x5F, 0xE3, 0x6A, 0xDB, 0x6B, 0x02, 0xF1, 0x14, 0x07, -+0x14, 0xBF, 0xC3, 0xF3, 0x00, 0x13, 0xC3, 0xF3, 0xC0, 0x03, 0x01, 0x97, 0x93, 0xB3, 0x52, 0x4B, 0x1B, 0x68, 0x93, 0xF8, -+0x01, 0xC0, 0x3A, 0x46, 0x08, 0xEB, 0x48, 0x03, 0x09, 0xEB, 0x83, 0x09, 0xC9, 0xF8, 0x24, 0x70, 0xBC, 0xF1, 0x00, 0x0F, -+0xCE, 0xD0, 0x53, 0x68, 0xFB, 0xB9, 0x54, 0x23, 0x03, 0xFB, 0x08, 0xF8, 0x49, 0x4B, 0x43, 0xF8, 0x08, 0x20, 0x03, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0x45, 0x4B, 0x1B, 0x68, 0x93, 0xF8, 0x01, 0xC0, 0x44, 0x4B, 0x54, 0x22, 0x08, 0xEB, 0x48, 0x01, -+0x09, 0xEB, 0x81, 0x09, 0x02, 0xFB, 0x08, 0xF8, 0x00, 0x22, 0x43, 0xF8, 0x08, 0x20, 0xC9, 0xF8, 0x24, 0x20, 0x43, 0x44, -+0xBC, 0xF1, 0x00, 0x0F, 0x01, 0xD1, 0xC3, 0xE9, 0x01, 0xCC, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x50, 0x6A, 0x03, 0x88, -+0x1D, 0x04, 0x99, 0xB2, 0xC7, 0xD5, 0xC1, 0xF3, 0x0E, 0x01, 0x01, 0x80, 0x94, 0xF8, 0x33, 0x10, 0x94, 0xF8, 0x32, 0x30, -+0x32, 0x48, 0x04, 0x39, 0x04, 0x3B, 0x84, 0xF8, 0x33, 0x10, 0x84, 0xF8, 0x32, 0x30, 0xD2, 0xE9, 0x0A, 0x31, 0x04, 0x39, -+0x04, 0x3B, 0xC2, 0xE9, 0x0A, 0x31, 0x00, 0x68, 0x3A, 0x46, 0x90, 0xF8, 0x01, 0xC0, 0xB3, 0xE7, 0x2B, 0x4B, 0x01, 0xA9, -+0xD3, 0xF8, 0x6C, 0x33, 0x20, 0x46, 0x98, 0x47, 0x26, 0x4A, 0x63, 0x6A, 0x12, 0x68, 0x07, 0x46, 0x92, 0xF8, 0x01, 0xC0, -+0x03, 0xF4, 0x60, 0x10, 0x2C, 0xE7, 0x24, 0x4B, 0x21, 0x4E, 0xD3, 0xF8, 0x58, 0x33, 0x39, 0x46, 0x20, 0x46, 0x98, 0x47, -+0x33, 0x68, 0x01, 0x90, 0x5B, 0x78, 0x07, 0x46, 0xD3, 0xB1, 0x08, 0xB1, 0x6B, 0x6D, 0x43, 0x60, 0xD5, 0xF8, 0x48, 0x01, -+0x29, 0x46, 0x10, 0xF0, 0x13, 0xFA, 0x33, 0x68, 0x93, 0xF8, 0x01, 0xC0, 0x58, 0xE7, 0x7B, 0x68, 0x00, 0x2B, 0xB4, 0xD1, -+0x15, 0x49, 0x54, 0x23, 0x03, 0xFB, 0x08, 0xF8, 0x01, 0xEB, 0x08, 0x03, 0x01, 0x20, 0xC3, 0xE9, 0x01, 0x70, 0x41, 0xF8, -+0x08, 0x20, 0xA8, 0xE7, 0x00, 0x28, 0xE5, 0xD0, 0x2B, 0x69, 0x43, 0x60, 0xE2, 0xE7, 0x05, 0xF1, 0x0C, 0x07, 0xBC, 0xF1, -+0x00, 0x0F, 0x03, 0xD0, 0x05, 0xF1, 0x50, 0x02, 0x01, 0x92, 0xF7, 0xE6, 0xD5, 0xF8, 0x38, 0x21, 0xD2, 0x6C, 0x14, 0x32, -+0x01, 0x92, 0xF1, 0xE6, 0xD5, 0xF8, 0x38, 0x31, 0xA3, 0x42, 0x7F, 0xF4, 0x2D, 0xAF, 0x05, 0xEB, 0x82, 0x02, 0x56, 0x63, -+0x2C, 0xE7, 0x00, 0xBF, 0x34, 0x36, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x94, 0x64, 0x17, 0x00, -+0x70, 0xB5, 0x1E, 0x48, 0x82, 0xB0, 0x90, 0xF8, 0x88, 0x30, 0x00, 0x22, 0x01, 0x92, 0x93, 0xB1, 0x90, 0xF8, 0x7F, 0x30, -+0x04, 0x2B, 0x2A, 0xD0, 0x19, 0x4C, 0x01, 0xA8, 0xD4, 0xF8, 0xE8, 0x33, 0x98, 0x47, 0x08, 0xB3, 0xD4, 0xF8, 0xF8, 0x33, -+0x98, 0x47, 0xD4, 0xF8, 0xD4, 0x33, 0x01, 0x98, 0x98, 0x47, 0x02, 0xB0, 0x70, 0xBD, 0x13, 0x4A, 0x13, 0x4D, 0xD2, 0xF8, -+0x38, 0x14, 0x13, 0x4C, 0x80, 0xF8, 0x88, 0x30, 0xC2, 0xF8, 0x00, 0x34, 0x01, 0xF4, 0x7F, 0x41, 0x02, 0xF5, 0x88, 0x66, -+0x02, 0xF5, 0x7F, 0x70, 0x4F, 0xF4, 0x00, 0x53, 0xC2, 0xF8, 0x38, 0x14, 0xC2, 0xF8, 0x20, 0x64, 0x28, 0x60, 0x23, 0x60, -+0x02, 0xB0, 0x70, 0xBD, 0xFF, 0xF7, 0x28, 0xFC, 0xE1, 0xE7, 0x04, 0x4B, 0x68, 0x30, 0xD3, 0xF8, 0xF4, 0x33, 0x98, 0x47, -+0x02, 0xB0, 0x70, 0xBD, 0x94, 0x64, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x60, 0x5D, 0x18, 0x00, 0xAC, 0x81, 0x32, 0x40, -+0x80, 0x81, 0x32, 0x40, 0xF8, 0xB5, 0x2C, 0x4C, 0x2C, 0x4D, 0x40, 0xF2, 0x74, 0x42, 0x20, 0x46, 0x00, 0x21, 0x26, 0x46, -+0xED, 0xF7, 0xF4, 0xF8, 0x4F, 0xF4, 0xE4, 0x73, 0x28, 0x4A, 0x26, 0xF8, 0x44, 0x3F, 0x4F, 0xF6, 0x30, 0x70, 0x48, 0xF2, -+0xC8, 0x13, 0x04, 0xF5, 0x77, 0x77, 0x4F, 0xF0, 0x22, 0x0C, 0x04, 0xF2, 0xFD, 0x31, 0xC4, 0xF8, 0x40, 0x24, 0xA4, 0xF8, -+0xDC, 0x33, 0xA4, 0xF8, 0xF4, 0x03, 0x04, 0xF5, 0x88, 0x63, 0x00, 0x20, 0x4F, 0xF4, 0x00, 0x12, 0xDF, 0xF8, 0x74, 0xE0, -+0xC4, 0xF8, 0xB0, 0xC3, 0xC4, 0xE9, 0xEA, 0x71, 0xC4, 0xF8, 0xBC, 0x33, 0xC4, 0xF8, 0x20, 0x34, 0x63, 0x62, 0xA2, 0x63, -+0xC4, 0xF8, 0x98, 0x53, 0xC4, 0xF8, 0xFC, 0x53, 0x25, 0x60, 0xC4, 0xF8, 0xA4, 0x03, 0xC4, 0xF8, 0xCC, 0x03, 0xC4, 0xF8, -+0x30, 0x04, 0x04, 0xF1, 0x5B, 0x0C, 0x04, 0xF1, 0xB4, 0x03, 0x1E, 0x27, 0x04, 0xF5, 0x7C, 0x74, 0xA3, 0xF1, 0x14, 0x01, -+0x5A, 0x1C, 0x43, 0xF8, 0x58, 0x5C, 0x43, 0xF8, 0x40, 0x7C, 0x43, 0xF8, 0x24, 0x0C, 0x43, 0xF8, 0x14, 0xEC, 0x43, 0xF8, -+0x4C, 0x1C, 0x43, 0xF8, 0x08, 0x2C, 0x43, 0xE9, 0x12, 0x6C, 0x43, 0xF8, 0x0C, 0x3C, 0x5C, 0x33, 0x9C, 0x42, 0xE9, 0xD1, -+0xF8, 0xBD, 0x00, 0xBF, 0x60, 0x5D, 0x18, 0x00, 0xBE, 0xBA, 0xFE, 0xCA, 0x1E, 0xAB, 0xDC, 0xBA, 0xDE, 0xFA, 0xFE, 0xCA, -+0x2D, 0xE9, 0xF0, 0x41, 0x13, 0x4A, 0x14, 0x4B, 0x92, 0xF8, 0x7E, 0x40, 0xD3, 0xF8, 0xAC, 0x33, 0x12, 0x4F, 0x00, 0x22, -+0x0E, 0x46, 0x21, 0x46, 0x05, 0x46, 0x4F, 0xF0, 0x54, 0x08, 0x98, 0x47, 0x0C, 0x20, 0x18, 0xFB, 0x04, 0x00, 0x38, 0x44, -+0x10, 0xF0, 0x5E, 0xF9, 0x22, 0x46, 0x31, 0x46, 0x28, 0x46, 0xFC, 0xF7, 0x77, 0xF9, 0x6B, 0x6A, 0x03, 0xF4, 0x60, 0x13, -+0xB3, 0xF5, 0x60, 0x1F, 0x05, 0xD1, 0x08, 0xFB, 0x04, 0x74, 0x6B, 0x6C, 0x63, 0x62, 0x02, 0x23, 0xA3, 0x76, 0xBD, 0xE8, -+0xF0, 0x81, 0x00, 0xBF, 0x94, 0x64, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x90, 0xF8, 0x62, 0x40, 0x87, 0xB0, 0x84, 0xB9, 0x90, 0xF8, 0x64, 0x30, 0x6B, 0xB1, 0x90, 0xF8, 0x6C, 0x30, 0x58, 0x4A, -+0x01, 0x93, 0x4F, 0xF4, 0x1E, 0x75, 0x05, 0xFB, 0x03, 0x25, 0x95, 0xF8, 0x25, 0x30, 0x13, 0xB1, 0x6B, 0x68, 0x9B, 0x06, -+0x02, 0xD4, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x10, 0x22, 0x21, 0x46, 0x02, 0xA8, 0xED, 0xF7, 0x4D, 0xF8, 0x95, 0xF8, -+0x23, 0x30, 0x4E, 0x4A, 0x4E, 0x49, 0x00, 0x94, 0x42, 0xF2, 0x34, 0x06, 0x03, 0xEB, 0xC3, 0x03, 0x06, 0xEB, 0x83, 0x03, -+0x9E, 0x18, 0x01, 0xF1, 0x08, 0x0B, 0xA6, 0x46, 0x22, 0x46, 0xA2, 0x46, 0x20, 0x46, 0x56, 0xF8, 0x04, 0x3F, 0xB3, 0xF5, -+0xFE, 0x0F, 0x1F, 0x46, 0x04, 0xF1, 0x01, 0x08, 0x28, 0xBF, 0x4F, 0xF4, 0xFE, 0x07, 0xF3, 0xB1, 0x42, 0x4C, 0x0B, 0x78, -+0xE3, 0x5C, 0x06, 0xAC, 0x04, 0xEB, 0x83, 0x0C, 0x22, 0xFA, 0x03, 0xF9, 0x5C, 0xF8, 0x10, 0x5C, 0x3D, 0x44, 0x55, 0x45, -+0x84, 0xBF, 0xAA, 0x46, 0x00, 0x93, 0x19, 0xF0, 0x01, 0x0F, 0x5F, 0xFA, 0x88, 0xF4, 0x38, 0x44, 0x4C, 0xF8, 0x10, 0x5C, -+0x07, 0xD1, 0x01, 0x25, 0x05, 0xFA, 0x03, 0xF3, 0x1A, 0x43, 0xAE, 0x44, 0xD2, 0xB2, 0x5F, 0xFA, 0x8E, 0xFE, 0x01, 0x31, -+0x8B, 0x45, 0xD2, 0xD1, 0x08, 0x2C, 0x41, 0xD0, 0xA4, 0xEB, 0x0E, 0x04, 0xE4, 0xB2, 0xA4, 0x02, 0x92, 0x01, 0xB0, 0xF5, -+0x7D, 0x6F, 0x1E, 0xD8, 0x0F, 0x30, 0x0A, 0xF1, 0x0F, 0x0A, 0xC0, 0xF3, 0x07, 0x13, 0xCA, 0xF3, 0x07, 0x1A, 0x00, 0x21, -+0x00, 0x98, 0x1B, 0x06, 0x43, 0xEA, 0x00, 0x33, 0x13, 0x43, 0x23, 0x43, 0x0B, 0x43, 0x01, 0x99, 0x08, 0x46, 0x21, 0x49, -+0x4F, 0xF4, 0x1E, 0x72, 0x43, 0xEA, 0x0A, 0x43, 0x02, 0xFB, 0x00, 0x12, 0x43, 0xF0, 0x0F, 0x03, 0xC2, 0xF8, 0x04, 0x32, -+0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xB0, 0xF5, 0x7D, 0x4F, 0x0D, 0xD9, 0xB0, 0xF5, 0xFD, 0x2F, 0x18, 0xD8, 0x00, 0xF2, -+0xFF, 0x70, 0x0A, 0xF2, 0xFF, 0x7A, 0xC0, 0xF3, 0xC7, 0x23, 0xCA, 0xF3, 0xC7, 0x2A, 0x4F, 0xF4, 0x00, 0x41, 0xD7, 0xE7, -+0xFF, 0x30, 0x0A, 0xF1, 0xFF, 0x0A, 0xC0, 0xF3, 0x07, 0x23, 0xCA, 0xF3, 0x07, 0x2A, 0x4F, 0xF4, 0x80, 0x41, 0xCD, 0xE7, -+0x4F, 0xF4, 0x40, 0x64, 0x00, 0x22, 0xBE, 0xE7, 0x47, 0xF6, 0xFF, 0x73, 0xBA, 0xF5, 0xFE, 0x0F, 0x94, 0xBF, 0x9A, 0x44, -+0x03, 0xF5, 0xFE, 0x0A, 0xB0, 0xF5, 0xFE, 0x0F, 0x94, 0xBF, 0x18, 0x18, 0x03, 0xF5, 0xFE, 0x00, 0xC0, 0xF3, 0xC7, 0x33, -+0xCA, 0xF3, 0xC7, 0x3A, 0x4F, 0xF4, 0x40, 0x41, 0xB4, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x7C, 0x36, 0x17, 0x00, -+0xC0, 0xB2, 0x15, 0x00, 0xA0, 0xB2, 0x15, 0x00, 0x49, 0x4B, 0x4A, 0x4A, 0x4F, 0xF4, 0x80, 0x11, 0x2D, 0xE9, 0xF0, 0x47, -+0x19, 0x60, 0x13, 0x68, 0x13, 0xF4, 0x40, 0x1F, 0xFB, 0xD1, 0xDF, 0xF8, 0x34, 0x81, 0x45, 0x4A, 0x98, 0xF8, 0x8C, 0x30, -+0x4F, 0xF4, 0x80, 0x11, 0x11, 0x60, 0x00, 0x2B, 0x6E, 0xD0, 0x98, 0xF8, 0x7E, 0x60, 0xDF, 0xF8, 0x20, 0x91, 0x54, 0x23, -+0x03, 0xFB, 0x06, 0x93, 0x9A, 0x7E, 0x00, 0x2A, 0x38, 0xD0, 0x54, 0x20, 0x00, 0xFB, 0x06, 0x94, 0x20, 0x46, 0x62, 0x6A, -+0x93, 0x88, 0x43, 0xF0, 0x10, 0x03, 0x93, 0x80, 0x1C, 0x30, 0x10, 0xF0, 0x55, 0xF8, 0x37, 0x4B, 0x53, 0xF8, 0x26, 0x00, -+0x0F, 0xF0, 0x6A, 0xFF, 0x00, 0x23, 0xA3, 0x76, 0x63, 0x62, 0x06, 0xEB, 0x46, 0x04, 0x08, 0xEB, 0x84, 0x04, 0x94, 0xF8, -+0x2E, 0x50, 0x2D, 0xB9, 0x60, 0x6A, 0x18, 0xB1, 0x31, 0x46, 0xFB, 0xF7, 0x93, 0xF8, 0x65, 0x62, 0x2D, 0x4A, 0x2E, 0x49, -+0x13, 0x68, 0x23, 0xF0, 0x40, 0x03, 0x13, 0x60, 0x54, 0x23, 0x03, 0xFB, 0x06, 0x99, 0x40, 0x22, 0x0A, 0x60, 0x99, 0xF8, -+0x50, 0x30, 0x00, 0x22, 0x01, 0x3B, 0x30, 0x46, 0x89, 0xF8, 0x50, 0x30, 0x88, 0xF8, 0x8C, 0x20, 0xBD, 0xE8, 0xF0, 0x47, -+0xFE, 0xF7, 0x66, 0xBE, 0xDC, 0x68, 0x62, 0x6A, 0x92, 0x02, 0x2D, 0xD4, 0x54, 0x25, 0xDF, 0xF8, 0x98, 0xA0, 0x20, 0x4F, -+0x05, 0xFB, 0x06, 0x95, 0x11, 0xE0, 0xE3, 0x6C, 0x62, 0x6A, 0x19, 0x6D, 0x41, 0xF0, 0x00, 0x41, 0x41, 0xF4, 0x80, 0x01, -+0x19, 0x65, 0x93, 0x02, 0x20, 0x46, 0x17, 0xD5, 0xD7, 0xF8, 0xD8, 0x33, 0x98, 0x47, 0xAB, 0x7E, 0xEC, 0x68, 0x00, 0x2B, -+0xA9, 0xD1, 0xDA, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xE7, 0xDA, 0x00, 0x2C, 0xE5, 0xD1, 0x12, 0x49, -+0x12, 0x48, 0x40, 0xF2, 0xB3, 0x72, 0x11, 0xF0, 0x0D, 0xFC, 0xDE, 0xE7, 0xBD, 0xE8, 0xF0, 0x87, 0xD7, 0xF8, 0xE4, 0x33, -+0x98, 0x47, 0xA8, 0xE7, 0x5A, 0x69, 0x61, 0x6C, 0x52, 0x6C, 0x8A, 0x42, 0xCC, 0xD1, 0xD2, 0xF8, 0x38, 0x21, 0x12, 0x68, -+0x5A, 0x61, 0xC7, 0xE7, 0x80, 0x81, 0x32, 0x40, 0x88, 0x81, 0x32, 0x40, 0x84, 0x81, 0x32, 0x40, 0xC4, 0x90, 0x15, 0x00, -+0x8C, 0x80, 0x32, 0x40, 0x88, 0x80, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x3C, 0x91, 0x15, 0x00, -+0x94, 0x64, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x69, 0x4F, 0xDF, 0xF8, -+0xCC, 0x81, 0x97, 0xF8, 0x7E, 0x60, 0x54, 0x25, 0x05, 0xFB, 0x06, 0x85, 0xAB, 0x7E, 0x53, 0xBB, 0xDF, 0xF8, 0xA0, 0xA1, -+0xDF, 0xF8, 0xAC, 0x91, 0x15, 0xE0, 0xD4, 0xF8, 0x4C, 0xC0, 0xDF, 0xF8, 0xA0, 0xE1, 0xDC, 0xF8, 0x50, 0x30, 0x43, 0xF4, -+0x80, 0x02, 0x00, 0x2B, 0x20, 0x46, 0x11, 0x46, 0x26, 0xDA, 0x63, 0x6A, 0xCC, 0xF8, 0x50, 0x20, 0x9C, 0x02, 0x23, 0xD5, -+0xDE, 0xF8, 0xD8, 0x33, 0x98, 0x47, 0xAB, 0x7E, 0x7B, 0xB9, 0xDA, 0xF8, 0x00, 0x30, 0xEC, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xE2, 0xDA, 0x00, 0x2C, 0xE0, 0xD1, 0x53, 0x48, 0x4F, 0xF4, 0x02, 0x62, 0x49, 0x46, 0x11, 0xF0, 0xAE, 0xFB, -+0xD9, 0xE7, 0x54, 0x22, 0x02, 0xFB, 0x06, 0x82, 0x02, 0x2B, 0x54, 0x6A, 0x0C, 0xBF, 0x04, 0xF1, 0x0C, 0x03, 0x04, 0xF1, -+0x50, 0x03, 0xDB, 0x6B, 0x00, 0x2B, 0x29, 0xDB, 0xBD, 0xE8, 0xF0, 0x87, 0xDE, 0xF8, 0xE4, 0x33, 0x98, 0x47, 0x06, 0xEB, -+0x46, 0x04, 0x07, 0xEB, 0x84, 0x04, 0x94, 0xF8, 0x2E, 0x50, 0x2D, 0xB9, 0x60, 0x6A, 0x18, 0xB1, 0x31, 0x46, 0xFA, 0xF7, -+0xD1, 0xFF, 0x65, 0x62, 0x41, 0x4A, 0x42, 0x49, 0x13, 0x68, 0x23, 0xF0, 0x40, 0x03, 0x13, 0x60, 0x54, 0x23, 0x03, 0xFB, -+0x06, 0x88, 0x40, 0x22, 0x0A, 0x60, 0x98, 0xF8, 0x50, 0x30, 0x00, 0x22, 0x01, 0x3B, 0x30, 0x46, 0x88, 0xF8, 0x50, 0x30, -+0x87, 0xF8, 0x8C, 0x20, 0xBD, 0xE8, 0xF0, 0x47, 0xFE, 0xF7, 0xA4, 0xBD, 0x18, 0x02, 0x35, 0xD5, 0xA3, 0x88, 0x99, 0x06, -+0x13, 0xD4, 0xDF, 0xF8, 0xE0, 0x90, 0xD9, 0xF8, 0x9C, 0x32, 0x98, 0x47, 0x04, 0x25, 0xA3, 0x88, 0x9A, 0x06, 0x0A, 0xD4, -+0xD9, 0xF8, 0x9C, 0x32, 0x98, 0x47, 0x01, 0x3D, 0xF7, 0xD1, 0x2E, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0x42, 0xDB, 0x97, 0xF8, 0x87, 0x30, 0x00, 0x2B, 0x37, 0xD0, 0x2A, 0x49, 0x97, 0xF8, 0x64, 0x30, 0x0A, 0x68, 0x1B, 0x06, -+0x22, 0xF0, 0xE0, 0x62, 0x03, 0xF0, 0xE0, 0x63, 0x13, 0x43, 0x0B, 0x60, 0xA3, 0x88, 0x25, 0x4A, 0x43, 0xF0, 0x10, 0x03, -+0x52, 0xF8, 0x26, 0x00, 0xA3, 0x80, 0x0F, 0xF0, 0x4F, 0xFE, 0x54, 0x23, 0x03, 0xFB, 0x06, 0x83, 0x00, 0x22, 0x9A, 0x76, -+0x5A, 0x62, 0xA2, 0xE7, 0x54, 0x20, 0x00, 0xFB, 0x06, 0x80, 0x1C, 0x30, 0x0F, 0xF0, 0x28, 0xFF, 0x97, 0xF8, 0x87, 0x30, -+0x00, 0x2B, 0xE5, 0xD0, 0x17, 0x4A, 0x97, 0xF8, 0x65, 0x00, 0x13, 0x68, 0x11, 0x68, 0xC3, 0xF3, 0x02, 0x63, 0x01, 0x33, -+0x83, 0x42, 0x28, 0xBF, 0x03, 0x46, 0x1B, 0x06, 0x03, 0xF0, 0xE0, 0x63, 0x21, 0xF0, 0xE0, 0x61, 0x0B, 0x43, 0x13, 0x60, -+0xD2, 0xE7, 0x10, 0x4B, 0x97, 0xF8, 0x7E, 0x00, 0xD3, 0xF8, 0xC0, 0x33, 0x98, 0x47, 0xCB, 0xE7, 0xA3, 0x88, 0x9B, 0x06, -+0xB9, 0xD4, 0xBD, 0xE8, 0xF0, 0x47, 0x0B, 0x49, 0x0B, 0x48, 0x40, 0xF6, 0x6A, 0x02, 0x11, 0xF0, 0xDD, 0xBA, 0x00, 0xBF, -+0x94, 0x64, 0x17, 0x00, 0x3C, 0x91, 0x15, 0x00, 0x8C, 0x80, 0x32, 0x40, 0x88, 0x80, 0x32, 0x40, 0x38, 0x36, 0x17, 0x00, -+0x54, 0x83, 0x32, 0x40, 0xC4, 0x90, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xD4, 0x8E, 0x15, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x10, 0xB5, 0x0D, 0x4C, 0x90, 0x22, 0x00, 0x21, 0x20, 0x46, 0xEC, 0xF7, 0x09, 0xFE, 0xFF, 0xF7, -+0x09, 0xFD, 0x40, 0xF2, 0xD3, 0x13, 0xE3, 0x66, 0xED, 0xF7, 0xA4, 0xFE, 0x07, 0x4A, 0x13, 0x68, 0x23, 0xF0, 0x70, 0x43, -+0x18, 0xB1, 0x43, 0xF0, 0x30, 0x43, 0x13, 0x60, 0x10, 0xBD, 0x43, 0xF0, 0x10, 0x43, 0x13, 0x60, 0x10, 0xBD, 0x00, 0xBF, -+0x94, 0x64, 0x17, 0x00, 0x54, 0x83, 0x32, 0x40, 0x2D, 0xE9, 0xF0, 0x43, 0x2A, 0x4C, 0x65, 0x68, 0x95, 0xB0, 0x00, 0x2D, -+0x44, 0xD0, 0x29, 0x4E, 0xA7, 0x68, 0xD6, 0xF8, 0xD8, 0x31, 0x20, 0x46, 0x98, 0x47, 0xD4, 0xF8, 0x10, 0x80, 0xB8, 0xF1, -+0x00, 0x0F, 0x26, 0xD0, 0x01, 0x25, 0x24, 0x49, 0x68, 0x46, 0x50, 0x22, 0x23, 0xF0, 0x66, 0xFD, 0xA3, 0x69, 0x94, 0xF8, -+0x62, 0x90, 0x23, 0xB1, 0x1E, 0x4E, 0x1F, 0x48, 0xD6, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0xFF, 0xF7, 0xBD, 0xFF, 0xC4, 0xF8, -+0x10, 0x80, 0x84, 0xF8, 0x62, 0x90, 0x18, 0x4C, 0x6B, 0x46, 0x22, 0x46, 0x0C, 0xAE, 0x58, 0x69, 0x19, 0x7E, 0x90, 0x62, -+0x0C, 0x33, 0xB3, 0x42, 0x82, 0xF8, 0x2C, 0x10, 0x02, 0xF1, 0x0C, 0x02, 0xF5, 0xD1, 0xFD, 0xB9, 0x15, 0xB0, 0xBD, 0xE8, -+0xF0, 0x83, 0xFF, 0xF7, 0xA5, 0xFF, 0xC4, 0xF8, 0x10, 0x80, 0x10, 0x4B, 0x10, 0x4A, 0x19, 0x69, 0x0B, 0x48, 0xD6, 0xF8, -+0xE0, 0x31, 0xA7, 0x60, 0x01, 0xF5, 0x9C, 0x51, 0x08, 0x31, 0x62, 0x60, 0x15, 0xB0, 0xBD, 0xE8, 0xF0, 0x43, 0x18, 0x47, -+0xD4, 0xF8, 0x10, 0x80, 0xB8, 0xF1, 0x00, 0x0F, 0xC1, 0xD1, 0xFF, 0xF7, 0x8D, 0xFF, 0xC4, 0xF8, 0x10, 0x80, 0xDF, 0xE7, -+0x01, 0x4E, 0xE4, 0xE7, 0x94, 0x64, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xA8, 0x64, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, -+0x95, 0x24, 0x13, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x42, 0x6D, 0xC3, 0x69, 0x91, 0xF8, 0x09, 0xC0, 0x9D, 0x68, 0x03, 0x8E, -+0x88, 0x46, 0x91, 0x05, 0x02, 0xD5, 0x12, 0xF4, 0x80, 0x60, 0x3B, 0xD0, 0x12, 0x3B, 0x01, 0x2B, 0x05, 0xF1, 0x12, 0x05, -+0x3A, 0xDD, 0x28, 0x4A, 0xDF, 0xF8, 0xA0, 0x90, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x0C, 0x2C, 0x40, 0xF2, 0xFD, 0x7E, -+0x15, 0xE0, 0x03, 0x2B, 0x2A, 0xDD, 0x6A, 0x88, 0x12, 0xF0, 0x08, 0x06, 0xC2, 0xF3, 0x42, 0x01, 0x24, 0xD1, 0x19, 0xF8, -+0x01, 0x20, 0x04, 0x32, 0x9A, 0x42, 0x2B, 0xDC, 0xBC, 0xF8, 0x20, 0x10, 0xB9, 0x42, 0xA3, 0xEB, 0x02, 0x03, 0x11, 0xD0, -+0x01, 0x2B, 0x15, 0x44, 0x1A, 0xDD, 0x2C, 0x88, 0xC4, 0xF3, 0x0A, 0x07, 0x77, 0x45, 0x13, 0xD0, 0x14, 0xF4, 0x00, 0x60, -+0xE1, 0xD0, 0xBC, 0xF8, 0x20, 0x10, 0x02, 0x22, 0xB9, 0x42, 0xA3, 0xEB, 0x02, 0x03, 0xED, 0xD1, 0x14, 0xF4, 0x00, 0x60, -+0x0B, 0xD1, 0x98, 0xF8, 0x0A, 0x30, 0xB3, 0xEB, 0x14, 0x3F, 0x0D, 0xD0, 0xBD, 0xE8, 0xF8, 0x83, 0x0C, 0x22, 0xDB, 0xE7, -+0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0x23, 0xC8, 0xF8, 0xDC, 0x30, 0x01, 0x20, 0xF3, 0xE7, 0x30, 0x46, 0xF1, 0xE7, -+0x08, 0xF1, 0xE0, 0x04, 0x02, 0x3A, 0xA9, 0x1C, 0x20, 0x46, 0x23, 0xF0, 0xBD, 0xFC, 0xC8, 0xF8, 0xDC, 0x40, 0x01, 0x20, -+0xE6, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x00, 0x96, 0x15, 0x00, 0x85, 0x4B, 0x86, 0x4A, 0x19, 0x68, 0x43, 0x6D, -+0x2D, 0xE9, 0xF0, 0x4F, 0x00, 0x24, 0xC5, 0x69, 0x82, 0xF8, 0x88, 0x40, 0xB1, 0xF9, 0x00, 0x10, 0xA1, 0x42, 0x83, 0xB0, -+0xC0, 0xF2, 0xC6, 0x80, 0x9E, 0x01, 0x40, 0xF1, 0xAD, 0x80, 0x00, 0x29, 0xC3, 0xF3, 0xCF, 0x30, 0xC3, 0xF3, 0xC9, 0x33, -+0xC0, 0xF2, 0xB3, 0x80, 0x7A, 0x49, 0x10, 0x3B, 0xDB, 0xB2, 0x4F, 0xF4, 0x1E, 0x74, 0x04, 0xFB, 0x03, 0x14, 0x94, 0xF8, -+0x25, 0x00, 0x00, 0x28, 0x00, 0xF0, 0x9A, 0x80, 0x94, 0xF8, 0x22, 0x50, 0x54, 0xF8, 0x26, 0x0F, 0x50, 0x67, 0x73, 0x48, -+0x73, 0x4E, 0xA4, 0x88, 0x84, 0x80, 0x4F, 0xF4, 0xA4, 0x67, 0x10, 0x69, 0x07, 0xFB, 0x05, 0x65, 0xA8, 0x42, 0x40, 0xF0, -+0x93, 0x80, 0x6F, 0x48, 0x00, 0x68, 0x00, 0xF0, 0x3F, 0x00, 0x09, 0x28, 0x40, 0xF2, 0x8C, 0x80, 0x6C, 0x4C, 0x6D, 0x48, -+0x24, 0x68, 0x05, 0x68, 0xD2, 0xF8, 0x68, 0x80, 0xC4, 0xF3, 0x0B, 0x10, 0x04, 0xF0, 0x0F, 0x09, 0xC4, 0xF3, 0x01, 0x4E, -+0x24, 0x03, 0x00, 0x90, 0xA2, 0xF8, 0x7C, 0x00, 0x82, 0xF8, 0x7F, 0x90, 0x82, 0xF8, 0x83, 0xE0, 0xC5, 0xF3, 0x03, 0x10, -+0x05, 0xF0, 0x07, 0x06, 0x40, 0xF1, 0x8B, 0x80, 0x4F, 0xF0, 0x02, 0x0B, 0x4F, 0xF4, 0x80, 0x64, 0x5F, 0x46, 0x01, 0x94, -+0xC5, 0xF3, 0x00, 0x34, 0xC5, 0xF3, 0x42, 0x2C, 0x82, 0xF8, 0x80, 0x70, 0xF7, 0xB2, 0x82, 0xF8, 0x81, 0x00, 0x82, 0xF8, -+0x87, 0x40, 0x82, 0xF8, 0x82, 0xC0, 0x82, 0xF8, 0x84, 0x70, 0xB9, 0xF1, 0x00, 0x0F, 0x79, 0xD0, 0x92, 0xF8, 0x86, 0x50, -+0xDF, 0xF8, 0x64, 0x91, 0xD9, 0xF8, 0x00, 0x40, 0x00, 0x2C, 0xFB, 0xDA, 0xD9, 0xF8, 0x00, 0x90, 0x50, 0x4C, 0x02, 0x2E, -+0x09, 0xEA, 0x04, 0x04, 0x76, 0xD8, 0x4F, 0x4F, 0x00, 0xEB, 0x40, 0x09, 0x57, 0xF8, 0x26, 0x70, 0xD9, 0x44, 0x37, 0xF8, -+0x19, 0x90, 0xD8, 0xF8, 0x0C, 0x70, 0xDF, 0xF8, 0x3C, 0xA1, 0xBC, 0x42, 0x28, 0xBF, 0x3C, 0x46, 0x14, 0x67, 0xDA, 0xF8, -+0x00, 0xB0, 0x01, 0x9F, 0x98, 0xF8, 0x1C, 0x80, 0x4F, 0xF4, 0x1E, 0x7A, 0x0A, 0xFB, 0x03, 0x13, 0x07, 0x43, 0x01, 0x21, -+0x47, 0xEA, 0xCE, 0x1E, 0x01, 0xFA, 0x05, 0xF5, 0x4F, 0xEA, 0x1B, 0x67, 0xD3, 0xF8, 0x4C, 0x11, 0x93, 0x66, 0x00, 0x9B, -+0x27, 0x2C, 0x4E, 0xEA, 0x0C, 0x1C, 0x4F, 0xEA, 0x87, 0x17, 0x18, 0xFB, 0x05, 0xF8, 0x4C, 0xF4, 0x40, 0x5C, 0x46, 0xEA, -+0xC3, 0x06, 0x94, 0xBF, 0x00, 0x24, 0x01, 0x24, 0x47, 0xF0, 0x13, 0x07, 0x18, 0xFB, 0x09, 0xF9, 0x82, 0xF8, 0x88, 0x40, -+0xD7, 0x66, 0xA1, 0xF8, 0x82, 0xC0, 0xA1, 0xF8, 0x84, 0x60, 0xA2, 0xF8, 0x7A, 0x90, 0x09, 0xE0, 0xAB, 0x68, 0x59, 0x89, -+0xA2, 0xF8, 0x74, 0x10, 0x99, 0x89, 0xA2, 0xF8, 0x76, 0x10, 0xDB, 0x89, 0xA2, 0xF8, 0x78, 0x30, 0x03, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0x10, 0xF4, 0x7C, 0x7F, 0x7F, 0xF4, 0x49, 0xAF, 0x27, 0x49, 0x27, 0x48, 0x40, 0xF6, 0x53, 0x12, 0x07, 0xE0, -+0x00, 0x8E, 0x1C, 0x28, 0x3F, 0xF6, 0x36, 0xAF, 0x22, 0x49, 0x24, 0x48, 0x40, 0xF6, 0x46, 0x12, 0x03, 0xB0, 0xBD, 0xE8, -+0xF0, 0x4F, 0x11, 0xF0, 0xF9, 0xB8, 0x4F, 0xF0, 0x01, 0x0B, 0x4F, 0xF4, 0x00, 0x74, 0x5F, 0x46, 0x01, 0x94, 0x73, 0xE7, -+0xAC, 0x0F, 0xDF, 0xF8, 0x7C, 0x90, 0xC5, 0xF3, 0x01, 0x65, 0x19, 0xF8, 0x04, 0x40, 0x82, 0xF8, 0x85, 0x40, 0x82, 0xF8, -+0x86, 0x50, 0x7B, 0xE7, 0x03, 0x3F, 0x00, 0xEB, 0x40, 0x09, 0xC7, 0xF3, 0x46, 0x0A, 0x0B, 0xEB, 0x49, 0x09, 0x4F, 0xF0, -+0x03, 0x0B, 0x1B, 0xFB, 0x0A, 0x99, 0xDF, 0xF8, 0x54, 0xA0, 0x3A, 0xF8, 0x19, 0x90, 0x07, 0xF0, 0x01, 0x07, 0x09, 0xFA, -+0x07, 0xF9, 0x1F, 0xFA, 0x89, 0xF9, 0x7A, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x94, 0x64, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x08, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x54, 0x83, 0x32, 0x40, 0x58, 0x83, 0x32, 0x40, 0x5C, 0x83, 0x32, 0x40, -+0xFC, 0xFF, 0x0F, 0x00, 0x04, 0x96, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, 0x50, 0x90, 0x15, 0x00, 0xB0, 0x93, 0x15, 0x00, -+0x60, 0x83, 0x32, 0x40, 0x64, 0x83, 0x32, 0x40, 0xA8, 0xB2, 0x15, 0x00, 0x70, 0x95, 0x15, 0x00, 0x10, 0xB5, 0x04, 0x4C, -+0xD4, 0xF8, 0x9C, 0x32, 0x98, 0x47, 0xD4, 0xF8, 0xEC, 0x33, 0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0x88, 0x1A, 0x17, 0x00, -+0x10, 0xB5, 0x03, 0xF0, 0x85, 0xFB, 0x08, 0x4B, 0x1B, 0x68, 0x1B, 0x04, 0x03, 0xD4, 0x07, 0x4B, 0x00, 0x24, 0x1C, 0x61, -+0x10, 0xBD, 0x04, 0x46, 0xED, 0xF7, 0x62, 0xFC, 0x00, 0x28, 0xF6, 0xD0, 0x02, 0x4B, 0x1C, 0x61, 0x10, 0xBD, 0x00, 0xBF, -+0x04, 0x00, 0x32, 0x40, 0x94, 0x64, 0x17, 0x00, 0x18, 0x4B, 0x1B, 0x69, 0x63, 0xB3, 0x93, 0xF8, 0x64, 0x20, 0x4A, 0xB3, -+0x16, 0x4A, 0x93, 0xF8, 0x6C, 0x30, 0x10, 0x68, 0x15, 0x49, 0x40, 0xF0, 0x10, 0x00, 0x30, 0xB4, 0x10, 0x60, 0x10, 0x68, -+0x13, 0x4D, 0x14, 0x4C, 0x40, 0xF4, 0x00, 0x60, 0x10, 0x60, 0x10, 0x68, 0x40, 0xF4, 0x80, 0x50, 0x10, 0x60, 0x2A, 0x68, -+0x10, 0x48, 0xC4, 0xF8, 0x50, 0x04, 0x42, 0xF4, 0x00, 0x72, 0x2A, 0x60, 0x0A, 0x68, 0x42, 0xF4, 0x80, 0x32, 0x0A, 0x60, -+0x0A, 0x68, 0x10, 0x33, 0xDB, 0xB2, 0x43, 0xEA, 0x83, 0x23, 0x22, 0xF4, 0x00, 0x32, 0xC4, 0xF8, 0x4C, 0x34, 0x30, 0xBC, -+0x0A, 0x60, 0x70, 0x47, 0x70, 0x47, 0x00, 0xBF, 0x94, 0x64, 0x17, 0x00, 0x80, 0x80, 0x32, 0x40, 0x54, 0x83, 0x32, 0x40, -+0x24, 0x03, 0x32, 0x40, 0x60, 0x5D, 0x18, 0x00, 0x04, 0x07, 0xFF, 0xFF, 0x08, 0xB5, 0x0F, 0x4B, 0x1B, 0x69, 0x1B, 0xB1, -+0x0E, 0x4B, 0xD3, 0xF8, 0xC4, 0x33, 0x98, 0x47, 0x0D, 0x48, 0x0E, 0x4B, 0x02, 0x68, 0x0E, 0x49, 0x22, 0xF4, 0x00, 0x72, -+0x02, 0x60, 0x1A, 0x68, 0x22, 0xF0, 0x10, 0x02, 0x1A, 0x60, 0x1A, 0x68, 0x22, 0xF4, 0x00, 0x62, 0x1A, 0x60, 0x1A, 0x68, -+0x22, 0xF4, 0x80, 0x52, 0x1A, 0x60, 0x0B, 0x68, 0x23, 0xF4, 0x80, 0x33, 0x0B, 0x60, 0x08, 0xBD, 0x94, 0x64, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x24, 0x03, 0x32, 0x40, 0x80, 0x80, 0x32, 0x40, 0x54, 0x83, 0x32, 0x40, 0x43, 0x6C, 0x13, 0xB1, -+0x9B, 0x88, 0x9A, 0x05, 0x0C, 0xD4, 0xC3, 0x6A, 0xDB, 0x6B, 0x9B, 0x06, 0x43, 0xBF, 0x91, 0xF8, 0x2D, 0x31, 0x48, 0xF2, -+0x07, 0x00, 0x40, 0xEA, 0x43, 0x20, 0xD1, 0xF8, 0x04, 0x02, 0x70, 0x47, 0x01, 0x4B, 0xD8, 0x6E, 0x70, 0x47, 0x00, 0xBF, -+0x94, 0x64, 0x17, 0x00, 0x4B, 0x08, 0x03, 0x22, 0x02, 0xFB, 0x03, 0x00, 0x03, 0x4B, 0x33, 0xF8, 0x10, 0x00, 0x01, 0xF0, -+0x01, 0x01, 0x88, 0x40, 0x70, 0x47, 0x00, 0xBF, 0xE0, 0x94, 0x15, 0x00, 0x4B, 0x08, 0x03, 0x22, 0x02, 0xFB, 0x03, 0x00, -+0x03, 0x4B, 0x33, 0xF8, 0x10, 0x00, 0x01, 0xF0, 0x01, 0x01, 0x88, 0x40, 0x80, 0xB2, 0x70, 0x47, 0x70, 0x95, 0x15, 0x00, -+0x2D, 0xE9, 0xF8, 0x43, 0x2B, 0x4F, 0x84, 0x6A, 0x3D, 0x68, 0x90, 0xF8, 0x1D, 0x80, 0xB5, 0xF9, 0x00, 0xC0, 0xBC, 0xF1, -+0x00, 0x0F, 0x16, 0x46, 0x99, 0x46, 0xC4, 0xF3, 0x41, 0x25, 0x12, 0xDB, 0xC4, 0xF3, 0x02, 0x12, 0x01, 0x32, 0x1A, 0x60, -+0x04, 0xF0, 0x0F, 0x04, 0x22, 0x4A, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x08, 0x23, 0x04, 0xEB, 0x44, 0x04, 0xDB, 0x68, -+0x33, 0x60, 0x05, 0xEB, 0x44, 0x00, 0xBD, 0xE8, 0xF8, 0x83, 0x05, 0x29, 0x1E, 0xD0, 0x1C, 0x49, 0x1C, 0x48, 0x40, 0xF6, -+0xF5, 0x12, 0x10, 0xF0, 0xF5, 0xFF, 0x39, 0x68, 0xB1, 0xF9, 0x00, 0x10, 0xC4, 0xF3, 0x02, 0x12, 0x01, 0x32, 0x00, 0x29, -+0x4F, 0xEA, 0x14, 0x13, 0xC9, 0xF8, 0x00, 0x20, 0x04, 0xF0, 0x0F, 0x04, 0xDC, 0xDA, 0x5B, 0x07, 0x11, 0xD4, 0x0B, 0x2C, -+0xD8, 0xD9, 0x10, 0x49, 0x11, 0x48, 0x40, 0xF6, 0xFF, 0x12, 0x10, 0xF0, 0xDD, 0xFF, 0xD1, 0xE7, 0xC4, 0xF3, 0x02, 0x12, -+0x01, 0x32, 0x1A, 0x60, 0x23, 0x09, 0x5B, 0x07, 0x04, 0xF0, 0x0F, 0x04, 0xED, 0xD5, 0x08, 0x49, 0x0A, 0x48, 0x40, 0xF6, -+0xFE, 0x12, 0x10, 0xF0, 0xCD, 0xFF, 0x3B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xE2, 0xDB, 0xBC, 0xE7, 0x00, 0xBF, -+0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xD8, 0x93, 0x15, 0x00, 0xF8, 0x93, 0x15, 0x00, -+0xE0, 0x91, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x14, 0x4E, 0xDF, 0xF8, 0x54, 0xC0, 0x35, 0x69, 0x04, 0x38, 0x31, 0x46, -+0x05, 0xF1, 0x08, 0x04, 0x05, 0xF1, 0x18, 0x0E, 0x00, 0x27, 0x50, 0xF8, 0x04, 0x2F, 0x13, 0x09, 0x02, 0xF0, 0x0F, 0x08, -+0x03, 0xF4, 0x7F, 0x63, 0x43, 0xEA, 0x08, 0x03, 0x12, 0x0C, 0x8B, 0x62, 0x81, 0xF8, 0x2C, 0x20, 0x25, 0xB1, 0x22, 0x68, -+0x02, 0xEA, 0x0C, 0x02, 0x13, 0x43, 0x8B, 0x62, 0x04, 0x34, 0xA6, 0x45, 0x4F, 0x62, 0x01, 0xF1, 0x0C, 0x01, 0xE6, 0xD1, -+0x01, 0x23, 0x86, 0xF8, 0x62, 0x30, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0xBF, 0x94, 0x64, 0x17, 0x00, 0x00, 0xF0, 0xFF, 0xFF, -+0x03, 0x4B, 0x02, 0x78, 0x83, 0xF8, 0x64, 0x20, 0x42, 0x78, 0x83, 0xF8, 0x65, 0x20, 0x70, 0x47, 0x94, 0x64, 0x17, 0x00, -+0x0A, 0x4B, 0x9A, 0x69, 0x8A, 0xB1, 0x30, 0xB4, 0x01, 0xEB, 0x41, 0x02, 0x03, 0xEB, 0x82, 0x02, 0x4C, 0x00, 0x92, 0xF8, -+0x2E, 0x50, 0x05, 0xB1, 0x50, 0x62, 0x21, 0x44, 0x03, 0xEB, 0x81, 0x03, 0x01, 0x22, 0x30, 0xBC, 0x83, 0xF8, 0x2D, 0x20, -+0x70, 0x47, 0x70, 0x47, 0x94, 0x64, 0x17, 0x00, 0x08, 0x4A, 0x09, 0x4B, 0x11, 0x69, 0x09, 0x4A, 0x10, 0xB4, 0x01, 0xF5, -+0x9C, 0x51, 0x08, 0x4C, 0x5C, 0x60, 0x98, 0x60, 0x5D, 0xF8, 0x04, 0x4B, 0x18, 0x46, 0x08, 0x31, 0xD2, 0xF8, 0xE0, 0x31, -+0x18, 0x47, 0x00, 0xBF, 0x00, 0x10, 0x50, 0x40, 0x94, 0x64, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x95, 0x24, 0x13, 0x00, -+0x08, 0x4A, 0x03, 0x7F, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x23, 0x40, 0xF2, 0xFF, 0x31, 0xB3, 0xF8, 0xBE, 0x24, -+0x8A, 0x42, 0x00, 0xD1, 0x70, 0x47, 0x43, 0x6C, 0x28, 0x30, 0x59, 0x6A, 0xFE, 0xF7, 0xF2, 0xBB, 0x18, 0x88, 0x17, 0x00, -+0xF8, 0xB5, 0x0E, 0x4A, 0x03, 0x7F, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x23, 0x40, 0xF2, 0xFF, 0x31, 0xB3, 0xF8, -+0xBE, 0x24, 0x8A, 0x42, 0x0F, 0xD0, 0xD0, 0xE9, 0x12, 0x67, 0x1D, 0x46, 0x06, 0xF1, 0x3C, 0x04, 0x4C, 0x36, 0x20, 0x46, -+0xF9, 0x6A, 0x04, 0x34, 0xFE, 0xF7, 0xD8, 0xFB, 0xB4, 0x42, 0x02, 0xD0, 0xB5, 0xF8, 0xBE, 0x24, 0xF5, 0xE7, 0xF8, 0xBD, -+0x18, 0x88, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x9C, 0x4E, 0xD0, 0xF8, 0x44, 0xB0, 0xC7, 0x6C, 0x96, 0xF8, 0x7E, 0x50, -+0x96, 0xF8, 0x87, 0x30, 0x11, 0xF4, 0x00, 0x09, 0x83, 0xB0, 0x04, 0x46, 0x8A, 0x46, 0x3E, 0xD0, 0x7B, 0xBB, 0xDF, 0xF8, -+0x58, 0x82, 0x28, 0x46, 0xD8, 0xF8, 0xC0, 0x33, 0x98, 0x47, 0xD8, 0xF8, 0x9C, 0x32, 0x98, 0x47, 0xBB, 0xF8, 0x04, 0x30, -+0x99, 0x06, 0x49, 0xD5, 0x13, 0xF0, 0x40, 0x02, 0x69, 0xD0, 0x58, 0x46, 0xFD, 0xF7, 0x14, 0xFE, 0x00, 0x23, 0xDF, 0xF8, -+0x4C, 0x82, 0x63, 0x64, 0xB9, 0xF1, 0x00, 0x0F, 0x4D, 0xD0, 0x89, 0x4B, 0x00, 0x22, 0xD3, 0xF8, 0xAC, 0x33, 0x29, 0x46, -+0x20, 0x46, 0x98, 0x47, 0x54, 0x20, 0x00, 0xFB, 0x05, 0x80, 0x0C, 0x30, 0x0F, 0xF0, 0xD2, 0xFA, 0xA3, 0x88, 0x00, 0x2B, -+0x47, 0xD1, 0x20, 0x46, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0xFC, 0xF7, 0x0B, 0xB9, 0x7F, 0x48, 0x96, 0xF8, 0x64, 0x30, -+0x01, 0x68, 0xDF, 0xF8, 0xF0, 0x81, 0x1B, 0x06, 0x21, 0xF0, 0xE0, 0x61, 0x03, 0xF0, 0xE0, 0x63, 0x0B, 0x43, 0x03, 0x60, -+0xC7, 0xE7, 0x00, 0x2B, 0xC8, 0xD0, 0x77, 0x48, 0x96, 0xF8, 0x65, 0xE0, 0x01, 0x68, 0x02, 0x68, 0xC1, 0xF3, 0x02, 0x61, -+0x4B, 0x1C, 0x73, 0x45, 0x28, 0xBF, 0x73, 0x46, 0x1B, 0x06, 0x03, 0xF0, 0xE0, 0x63, 0x22, 0xF0, 0xE0, 0x6C, 0x43, 0xEA, -+0x0C, 0x03, 0x03, 0x60, 0xBB, 0xF8, 0x04, 0x30, 0x99, 0x06, 0xB5, 0xD4, 0x1C, 0x23, 0xDF, 0xF8, 0xC4, 0x81, 0x54, 0x20, -+0x10, 0xFB, 0x05, 0x30, 0x40, 0x44, 0x0F, 0xF0, 0x99, 0xFA, 0x58, 0x46, 0xFD, 0xF7, 0xC4, 0xFD, 0x00, 0x23, 0x63, 0x64, -+0xB9, 0xF1, 0x00, 0x0F, 0xB1, 0xD1, 0xCA, 0xF3, 0x07, 0x29, 0xB9, 0xF1, 0x04, 0x0F, 0x1F, 0xD9, 0x3B, 0x6D, 0x43, 0xF4, -+0x80, 0x33, 0x3B, 0x65, 0xA7, 0xE7, 0x2A, 0x46, 0x51, 0x46, 0x20, 0x46, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0xFB, 0xF7, -+0x9D, 0xBA, 0x3B, 0x6D, 0x00, 0x92, 0x23, 0xF4, 0x00, 0x03, 0x2A, 0xF4, 0x00, 0x0A, 0x58, 0x46, 0x3B, 0x65, 0xCA, 0xF3, -+0x07, 0x29, 0xFD, 0xF7, 0xA1, 0xFD, 0x00, 0x9A, 0xDF, 0xF8, 0x64, 0x81, 0x62, 0x64, 0xB9, 0xF1, 0x04, 0x0F, 0xDF, 0xD8, -+0xD4, 0xF8, 0x48, 0xA0, 0xB9, 0xF1, 0x00, 0x0F, 0x25, 0xD0, 0x0A, 0xF1, 0x28, 0x0B, 0x05, 0xEB, 0x45, 0x03, 0x06, 0xEB, -+0x83, 0x03, 0x09, 0xF1, 0x01, 0x09, 0x59, 0x6A, 0xDA, 0xE9, 0x17, 0x32, 0xBB, 0x64, 0x4F, 0xEA, 0x09, 0x23, 0xC7, 0xE9, -+0x0D, 0x2B, 0x3B, 0x65, 0x07, 0xF1, 0x14, 0x02, 0x6B, 0x00, 0x00, 0x29, 0x4B, 0xD0, 0xB9, 0x61, 0x54, 0x20, 0x00, 0xFB, -+0x05, 0x88, 0x1D, 0x44, 0x98, 0xF8, 0x50, 0x30, 0x06, 0xEB, 0x85, 0x06, 0x01, 0x33, 0x72, 0x62, 0x88, 0xF8, 0x50, 0x30, -+0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xE3, 0x6A, 0x0A, 0xF1, 0x28, 0x0B, 0x03, 0xF1, 0x40, 0x0C, 0x1A, 0x46, 0x0A, 0xF1, -+0x24, 0x01, 0x52, 0xF8, 0x04, 0x0B, 0x41, 0xF8, 0x04, 0x0F, 0x62, 0x45, 0xF9, 0xD1, 0xE2, 0x8B, 0x92, 0x04, 0x26, 0xD5, -+0x33, 0x4A, 0x34, 0x48, 0x11, 0x68, 0x62, 0x7F, 0xB1, 0xF9, 0x00, 0x10, 0x4F, 0xF4, 0x1E, 0x7C, 0x0C, 0xFB, 0x02, 0x02, -+0x00, 0x29, 0xD2, 0xF8, 0x4C, 0x21, 0x00, 0x92, 0x29, 0xDB, 0x00, 0x9A, 0x59, 0x69, 0xD2, 0xF8, 0x9C, 0x20, 0xCA, 0xF8, -+0x40, 0x10, 0x59, 0x6A, 0xCA, 0xF8, 0x50, 0x10, 0xC2, 0xF3, 0xC2, 0x21, 0x05, 0x29, 0xCA, 0xF8, 0x3C, 0x20, 0x25, 0xD0, -+0xDB, 0x6B, 0x5B, 0x07, 0x05, 0xD4, 0xDA, 0xF8, 0x2C, 0x30, 0x23, 0xF4, 0xC0, 0x73, 0xCA, 0xF8, 0x2C, 0x30, 0x20, 0x46, -+0xFF, 0xF7, 0xDC, 0xFE, 0x9F, 0xE7, 0x54, 0x21, 0x01, 0xFB, 0x05, 0xF1, 0x1E, 0x48, 0x48, 0xF8, 0x01, 0x20, 0x00, 0x68, -+0x40, 0x78, 0x41, 0x44, 0x00, 0x28, 0xA9, 0xD1, 0xC1, 0xE9, 0x01, 0x00, 0xA6, 0xE7, 0x00, 0x2A, 0xD3, 0xD1, 0x19, 0x49, -+0x19, 0x48, 0x01, 0x93, 0x40, 0xF2, 0x4B, 0x12, 0x10, 0xF0, 0xFE, 0xFD, 0x01, 0x9B, 0xCA, 0xE7, 0x00, 0x98, 0xDA, 0xF8, -+0x4C, 0x10, 0x90, 0xF8, 0xA1, 0x00, 0x02, 0xF4, 0xC0, 0x62, 0xB2, 0xF5, 0x80, 0x6F, 0x14, 0xBF, 0x4F, 0xF4, 0x80, 0x3C, -+0x4F, 0xF4, 0x00, 0x3C, 0x21, 0xF4, 0x40, 0x32, 0x42, 0xEA, 0x0C, 0x02, 0x20, 0xB1, 0x42, 0xF4, 0x80, 0x22, 0xCA, 0xF8, -+0x4C, 0x20, 0xC1, 0xE7, 0x22, 0xF4, 0x80, 0x22, 0xCA, 0xF8, 0x4C, 0x20, 0xBC, 0xE7, 0x00, 0xBF, 0x94, 0x64, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x54, 0x83, 0x32, 0x40, 0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x34, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x68, 0x8E, 0x15, 0x00, 0x20, 0x62, 0x17, 0x00, 0x10, 0xB5, 0x05, 0x4C, 0x20, 0x46, 0x0F, 0xF0, -+0x6F, 0xF9, 0x10, 0xF0, 0x25, 0xFE, 0x01, 0x38, 0xC0, 0xB2, 0xE0, 0x72, 0xA0, 0x72, 0x10, 0xBD, 0x24, 0x65, 0x17, 0x00, -+0xC2, 0x4B, 0x2D, 0xE9, 0xF0, 0x4F, 0x4F, 0xF4, 0xA4, 0x67, 0x07, 0xFB, 0x02, 0x38, 0x85, 0xB0, 0x98, 0xF8, 0x62, 0x30, -+0x02, 0x2B, 0x17, 0xD1, 0x4F, 0xF4, 0x1E, 0x79, 0x93, 0x46, 0x0C, 0x46, 0x09, 0xFB, 0x01, 0xF2, 0xBA, 0x49, 0x01, 0x92, -+0x8E, 0x18, 0xB0, 0xF8, 0x00, 0xA0, 0x96, 0xF8, 0x24, 0x90, 0xB9, 0xF1, 0x01, 0x0F, 0x05, 0x46, 0x41, 0xF2, 0x04, 0x42, -+0x07, 0xD0, 0x0A, 0xEA, 0x02, 0x0A, 0xBA, 0xF5, 0x80, 0x5F, 0x5A, 0xD0, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1A, 0xEA, -+0x02, 0x02, 0x00, 0xF0, 0x6B, 0x81, 0x0A, 0xF0, 0xFC, 0x03, 0xA4, 0x2B, 0x00, 0xF0, 0x75, 0x82, 0x0A, 0xF0, 0x8C, 0x03, -+0x88, 0x2B, 0xEF, 0xD1, 0x0A, 0xF4, 0x40, 0x7A, 0xBA, 0xF5, 0x40, 0x7F, 0x0C, 0xBF, 0xEF, 0x8B, 0x2F, 0x8B, 0xA7, 0x4B, -+0xA5, 0x49, 0xA7, 0x4A, 0x07, 0xF0, 0x07, 0x07, 0x4F, 0xF4, 0x1E, 0x75, 0xDB, 0x5D, 0x05, 0xFB, 0x04, 0x15, 0xD2, 0x5C, -+0x95, 0xF8, 0x2E, 0x31, 0x1A, 0x42, 0xD9, 0xD0, 0x95, 0xF8, 0x31, 0x30, 0x13, 0xF0, 0x0C, 0x0F, 0x00, 0xF0, 0x7E, 0x82, -+0x95, 0xF8, 0x32, 0x20, 0x12, 0xF0, 0x06, 0x0F, 0xCE, 0xD1, 0x18, 0x07, 0x95, 0xF8, 0x2F, 0x91, 0x40, 0xF1, 0x8A, 0x82, -+0x99, 0x4B, 0x02, 0x22, 0x85, 0xF8, 0x32, 0x20, 0xD3, 0xF8, 0x20, 0x33, 0x31, 0x46, 0x40, 0x46, 0x4A, 0x46, 0x98, 0x47, -+0xB9, 0xF1, 0x00, 0x0F, 0x00, 0xF0, 0x7A, 0x82, 0xA9, 0xEB, 0x00, 0x09, 0xB9, 0xF1, 0x00, 0x0F, 0x00, 0xF3, 0x74, 0x82, -+0x8C, 0x4A, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x04, 0x24, 0x00, 0x23, 0x1A, 0x46, 0x94, 0xF8, 0x23, 0x00, 0x47, 0xF0, -+0x10, 0x01, 0xFC, 0xF7, 0xA9, 0xF8, 0x00, 0x23, 0x84, 0xF8, 0x32, 0x30, 0xA4, 0xE7, 0x00, 0x22, 0x0C, 0x21, 0x49, 0x20, -+0x0E, 0xF0, 0x58, 0xFC, 0x4F, 0xF0, 0x01, 0x09, 0x86, 0xF8, 0x24, 0x90, 0x04, 0x70, 0x80, 0xF8, 0x01, 0x90, 0x0E, 0xF0, -+0x7F, 0xFC, 0x96, 0xF8, 0x24, 0x30, 0x00, 0x2B, 0x58, 0xD1, 0x96, 0xF8, 0x23, 0x30, 0x09, 0x2B, 0x54, 0xD8, 0x96, 0xF8, -+0x22, 0x20, 0x77, 0x48, 0x7B, 0x4D, 0xCD, 0xF8, 0x08, 0x90, 0x9E, 0x23, 0xA4, 0x21, 0x11, 0xFB, 0x02, 0x31, 0x07, 0xFB, -+0x02, 0x07, 0x4F, 0x23, 0x46, 0x22, 0x13, 0xFB, 0x04, 0x24, 0x71, 0x4A, 0x02, 0xF5, 0x16, 0x73, 0x02, 0xEB, 0xC4, 0x04, -+0x01, 0x9A, 0x1A, 0x44, 0x00, 0xEB, 0xC1, 0x0A, 0x91, 0x46, 0xD6, 0xF8, 0x08, 0x32, 0x1B, 0xB3, 0xEF, 0xF3, 0x10, 0x83, -+0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x6D, 0x4B, 0x02, 0x9A, 0x1A, 0x60, 0x2B, 0x68, 0xA4, 0xF1, 0x28, 0x00, 0x01, 0x33, -+0xAA, 0xF1, 0x28, 0x01, 0x01, 0x90, 0x2B, 0x60, 0x0F, 0xF0, 0x98, 0xF9, 0xD6, 0xE9, 0x82, 0x23, 0x01, 0x98, 0xC7, 0xF8, -+0xC8, 0x24, 0xC7, 0xF8, 0xCC, 0x34, 0x0F, 0xF0, 0x99, 0xF8, 0x2B, 0x68, 0x5A, 0x1E, 0x2B, 0xB1, 0x60, 0x4B, 0x2A, 0x60, -+0x1B, 0x68, 0x0A, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0xD6, 0xF8, 0x30, 0x32, 0x50, 0x46, 0x21, 0x46, 0x08, 0x36, 0x0A, 0xF1, -+0x08, 0x0A, 0x08, 0x37, 0x23, 0xB1, 0x0F, 0xF0, 0x7B, 0xF9, 0x20, 0x46, 0x0F, 0xF0, 0x82, 0xF8, 0x08, 0x34, 0x4C, 0x45, -+0xC7, 0xD1, 0x40, 0x20, 0x0E, 0xF0, 0xDE, 0xFF, 0x4D, 0x4B, 0x4F, 0xF4, 0xA4, 0x67, 0x07, 0xFB, 0x0B, 0x36, 0x96, 0xF8, -+0xDE, 0x20, 0x00, 0x2A, 0x40, 0xF0, 0x82, 0x80, 0x0B, 0xF1, 0x0A, 0x05, 0x48, 0x4B, 0xED, 0xB2, 0x4F, 0xF4, 0x1E, 0x79, -+0x09, 0xFB, 0x05, 0xF9, 0x03, 0xEB, 0x09, 0x04, 0x94, 0xF8, 0x24, 0x30, 0x01, 0x2B, 0x73, 0xD0, 0x02, 0x23, 0x0C, 0x21, -+0x49, 0x20, 0x0E, 0xF0, 0xD5, 0xFB, 0x4F, 0xF0, 0x01, 0x0A, 0x84, 0xF8, 0x24, 0xA0, 0x05, 0x70, 0x80, 0xF8, 0x01, 0xA0, -+0x0E, 0xF0, 0xFC, 0xFB, 0x94, 0xF8, 0x24, 0x30, 0x00, 0x2B, 0x40, 0xF0, 0xA9, 0x81, 0x94, 0xF8, 0x23, 0x30, 0x09, 0x2B, -+0x00, 0xF2, 0xA4, 0x81, 0x94, 0xF8, 0x22, 0x00, 0xCD, 0xF8, 0x08, 0xA0, 0xA4, 0x21, 0x9E, 0x23, 0x11, 0xFB, 0x00, 0x33, -+0x4F, 0xF0, 0x46, 0x0A, 0x4F, 0x21, 0x11, 0xFB, 0x05, 0xAA, 0x36, 0x4A, 0x2E, 0x4E, 0x2E, 0x49, 0x07, 0xFB, 0x00, 0x67, -+0x01, 0xEB, 0xC3, 0x05, 0x30, 0x4E, 0xA2, 0xF5, 0x16, 0x73, 0x03, 0xEB, 0xCA, 0x0A, 0x91, 0x44, 0xD4, 0xF8, 0x08, 0x32, -+0x1B, 0xB3, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x2A, 0x4B, 0x02, 0x9A, 0x1A, 0x60, 0x33, 0x68, -+0xAA, 0xF1, 0x28, 0x00, 0x01, 0x33, 0xA5, 0xF1, 0x28, 0x01, 0x01, 0x90, 0x33, 0x60, 0x0F, 0xF0, 0x13, 0xF9, 0xD4, 0xE9, -+0x82, 0x23, 0x01, 0x98, 0xC7, 0xF8, 0xC8, 0x24, 0xC7, 0xF8, 0xCC, 0x34, 0x0F, 0xF0, 0x14, 0xF8, 0x33, 0x68, 0x5A, 0x1E, -+0x2B, 0xB1, 0x1E, 0x4B, 0x32, 0x60, 0x1B, 0x68, 0x0A, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0xD4, 0xF8, 0x30, 0x32, 0x28, 0x46, -+0x51, 0x46, 0x08, 0x34, 0x08, 0x35, 0x08, 0x37, 0x23, 0xB1, 0x0F, 0xF0, 0xF7, 0xF8, 0x50, 0x46, 0x0E, 0xF0, 0xFE, 0xFF, -+0x0A, 0xF1, 0x08, 0x0A, 0xCA, 0x45, 0xC7, 0xD1, 0x40, 0x20, 0x0E, 0xF0, 0x59, 0xFF, 0x0B, 0x4A, 0x4F, 0xF4, 0xA4, 0x63, -+0x03, 0xFB, 0x0B, 0x23, 0x93, 0xF8, 0xDE, 0x20, 0x07, 0x48, 0x0B, 0x49, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x0B, 0x03, -+0x01, 0x32, 0x83, 0xF8, 0xDE, 0x20, 0xD1, 0xF8, 0x0C, 0x32, 0x40, 0x46, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x18, 0x47, -+0x18, 0x88, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0xC0, 0xB2, 0x15, 0x00, 0xA4, 0xB2, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0xC0, 0x67, 0x17, 0x00, 0x0C, 0x21, 0x49, 0x20, 0x02, 0x92, 0x0E, 0xF0, -+0x41, 0xFB, 0x02, 0x9A, 0x86, 0xF8, 0x24, 0x20, 0x04, 0x70, 0x42, 0x70, 0x0E, 0xF0, 0x6A, 0xFB, 0x96, 0xF8, 0x24, 0x30, -+0x00, 0x2B, 0x60, 0xD1, 0x96, 0xF8, 0x23, 0x30, 0x09, 0x2B, 0x5C, 0xD8, 0x96, 0xF8, 0x22, 0x20, 0xA8, 0x48, 0xCD, 0xF8, -+0x08, 0x90, 0xA4, 0x21, 0x9E, 0x23, 0x11, 0xFB, 0x02, 0x33, 0xA6, 0x49, 0xDF, 0xF8, 0xA0, 0xA2, 0x03, 0x94, 0x07, 0xFB, -+0x02, 0x19, 0x4F, 0x25, 0x01, 0xEB, 0xC3, 0x07, 0x46, 0x22, 0x01, 0x9B, 0x15, 0xFB, 0x04, 0x25, 0x00, 0xF5, 0x16, 0x72, -+0x13, 0x44, 0x3C, 0x46, 0x00, 0xEB, 0xC5, 0x05, 0x1F, 0x46, 0xD6, 0xF8, 0x08, 0x22, 0x3A, 0xB3, 0xEF, 0xF3, 0x10, 0x82, -+0xD2, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x99, 0x4B, 0x02, 0x9A, 0x1A, 0x60, 0xDA, 0xF8, 0x00, 0x20, 0xA5, 0xF1, 0x28, 0x00, -+0x01, 0x32, 0xA4, 0xF1, 0x28, 0x01, 0x01, 0x90, 0xCA, 0xF8, 0x00, 0x20, 0x0F, 0xF0, 0x7E, 0xF8, 0xD6, 0xE9, 0x82, 0x21, -+0x01, 0x98, 0xC9, 0xF8, 0xC8, 0x24, 0xC9, 0xF8, 0xCC, 0x14, 0x0E, 0xF0, 0x7F, 0xFF, 0xDA, 0xF8, 0x00, 0x20, 0x51, 0x1E, -+0x32, 0xB1, 0x8B, 0x4B, 0xCA, 0xF8, 0x00, 0x10, 0x1A, 0x68, 0x09, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xD6, 0xF8, 0x30, 0x22, -+0x20, 0x46, 0x29, 0x46, 0x08, 0x36, 0x08, 0x34, 0x09, 0xF1, 0x08, 0x09, 0x22, 0xB1, 0x0F, 0xF0, 0x5F, 0xF8, 0x28, 0x46, -+0x0E, 0xF0, 0x66, 0xFF, 0x08, 0x35, 0xBD, 0x42, 0xC3, 0xD1, 0x40, 0x20, 0x03, 0x9C, 0x0E, 0xF0, 0xC1, 0xFE, 0x7E, 0x4D, -+0x21, 0x46, 0xEB, 0x68, 0x40, 0x46, 0x98, 0x47, 0x79, 0x4B, 0x4F, 0xF4, 0xA4, 0x67, 0x07, 0xFB, 0x0B, 0x33, 0x93, 0xF8, -+0xDE, 0xA0, 0x0A, 0xF1, 0xFF, 0x3A, 0x5F, 0xFA, 0x8A, 0xFA, 0x83, 0xF8, 0xDE, 0xA0, 0xBA, 0xF1, 0x00, 0x0F, 0x40, 0xF0, -+0x84, 0x80, 0x0B, 0xF1, 0x0A, 0x06, 0x6F, 0x49, 0xF6, 0xB2, 0x4F, 0xF4, 0x1E, 0x79, 0x09, 0xFB, 0x06, 0xF9, 0x01, 0xEB, -+0x09, 0x04, 0x94, 0xF8, 0x24, 0x30, 0x00, 0x2B, 0x71, 0xD0, 0x02, 0x23, 0x52, 0x46, 0x0C, 0x21, 0x49, 0x20, 0x0E, 0xF0, -+0xAB, 0xFA, 0x84, 0xF8, 0x24, 0xA0, 0x06, 0x70, 0x80, 0xF8, 0x01, 0xA0, 0x0E, 0xF0, 0xD4, 0xFA, 0x94, 0xF8, 0x24, 0x30, -+0x00, 0x2B, 0x60, 0xD1, 0x94, 0xF8, 0x23, 0x30, 0x09, 0x2B, 0x5C, 0xD8, 0x94, 0xF8, 0x22, 0x10, 0x5E, 0x4A, 0xDF, 0xF8, -+0x88, 0xC1, 0xDF, 0xF8, 0x80, 0xA1, 0x02, 0x96, 0x9E, 0x23, 0xA4, 0x20, 0x10, 0xFB, 0x01, 0x30, 0x07, 0xFB, 0x01, 0x27, -+0x4F, 0x23, 0x46, 0x21, 0x13, 0xFB, 0x06, 0x13, 0xAC, 0xF5, 0x16, 0x71, 0x02, 0xEB, 0xC0, 0x0B, 0xE1, 0x44, 0x01, 0xEB, -+0xC3, 0x03, 0x5E, 0x46, 0xCB, 0x46, 0xB9, 0x46, 0x1F, 0x46, 0xD4, 0xF8, 0x08, 0x22, 0x3A, 0xB3, 0xEF, 0xF3, 0x10, 0x82, -+0xD3, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x4E, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xDA, 0xF8, 0x00, 0x20, 0xA7, 0xF1, 0x28, 0x00, -+0x01, 0x32, 0xA6, 0xF1, 0x28, 0x01, 0x01, 0x90, 0xCA, 0xF8, 0x00, 0x20, 0x0E, 0xF0, 0xE8, 0xFF, 0xD4, 0xE9, 0x82, 0x21, -+0x01, 0x98, 0xC9, 0xF8, 0xC8, 0x24, 0xC9, 0xF8, 0xCC, 0x14, 0x0E, 0xF0, 0xE9, 0xFE, 0xDA, 0xF8, 0x00, 0x20, 0x51, 0x1E, -+0x32, 0xB1, 0x40, 0x4B, 0xCA, 0xF8, 0x00, 0x10, 0x1A, 0x68, 0x09, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xD4, 0xF8, 0x30, 0x22, -+0x30, 0x46, 0x39, 0x46, 0x08, 0x34, 0x08, 0x36, 0x09, 0xF1, 0x08, 0x09, 0x22, 0xB1, 0x0E, 0xF0, 0xC9, 0xFF, 0x38, 0x46, -+0x0E, 0xF0, 0xD0, 0xFE, 0x08, 0x37, 0x5F, 0x45, 0xC3, 0xD1, 0x40, 0x20, 0x02, 0x9E, 0x0E, 0xF0, 0x2B, 0xFE, 0xEB, 0x68, -+0x31, 0x46, 0x40, 0x46, 0x98, 0x47, 0xD5, 0xF8, 0x0C, 0x32, 0x40, 0x46, 0xDC, 0xE6, 0x96, 0xF8, 0x31, 0x20, 0x12, 0xF0, -+0x02, 0x07, 0x16, 0xD0, 0x96, 0xF8, 0x32, 0x30, 0x2B, 0x49, 0x43, 0xF0, 0x01, 0x03, 0x86, 0xF8, 0x32, 0x30, 0x4A, 0x46, -+0xD1, 0xF8, 0x20, 0x33, 0x40, 0x46, 0x31, 0x46, 0x98, 0x47, 0x96, 0xF8, 0x32, 0x30, 0x23, 0xF0, 0x01, 0x03, 0x86, 0xF8, -+0x32, 0x30, 0x71, 0xE5, 0x96, 0xF8, 0xDE, 0x20, 0xB4, 0xE6, 0x04, 0x23, 0x3A, 0x46, 0x0C, 0x21, 0x4A, 0x20, 0x0E, 0xF0, -+0x15, 0xFA, 0x04, 0x70, 0x80, 0xF8, 0x01, 0x90, 0x87, 0x70, 0x0E, 0xF0, 0x3F, 0xFA, 0x61, 0xE5, 0x95, 0xF8, 0x32, 0x30, -+0x13, 0xF0, 0x06, 0x04, 0x7F, 0xF4, 0x50, 0xAD, 0x02, 0x26, 0x95, 0xF8, 0x23, 0x00, 0x85, 0xF8, 0x32, 0x60, 0x47, 0xF0, -+0x10, 0x01, 0x23, 0x46, 0x22, 0x46, 0xFB, 0xF7, 0x45, 0xFE, 0x85, 0xF8, 0x32, 0x40, 0x41, 0xE5, 0x95, 0xF8, 0x31, 0x30, -+0x59, 0x07, 0x7F, 0xF5, 0x87, 0xAD, 0x0B, 0x4B, 0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, 0x04, 0x30, 0x04, 0x23, 0x80, 0xF8, -+0x32, 0x30, 0x00, 0x22, 0x0C, 0x21, 0x4A, 0x20, 0x0E, 0xF0, 0xE8, 0xF9, 0x01, 0x22, 0x04, 0x70, 0x80, 0xF8, 0x01, 0x90, -+0x82, 0x70, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x0E, 0xF0, 0x0E, 0xBA, 0x68, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xC0, 0x67, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x05, 0x8E, 0x87, 0xB0, 0xAD, 0xB1, 0x7A, 0x4B, 0xC6, 0x69, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0x46, -+0x11, 0xDB, 0x77, 0x4A, 0x65, 0x6D, 0x12, 0x68, 0x12, 0x78, 0x92, 0x07, 0x03, 0xD5, 0x05, 0xF0, 0x3C, 0x02, 0x3C, 0x2A, -+0x77, 0xD0, 0x73, 0x4A, 0xAA, 0x43, 0x0E, 0xD0, 0x01, 0x25, 0x28, 0x46, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x2E, -+0xEB, 0xD1, 0x6F, 0x49, 0x6F, 0x48, 0x4F, 0xF4, 0xD4, 0x72, 0x35, 0x46, 0x10, 0xF0, 0x5A, 0xFA, 0xF1, 0xE7, 0x00, 0x2B, -+0xC5, 0xF3, 0xCF, 0x30, 0xC5, 0xF3, 0xC9, 0x31, 0x68, 0xDB, 0x6A, 0x4A, 0x10, 0x39, 0xC9, 0xB2, 0x4F, 0xF4, 0x1E, 0x73, -+0x03, 0xFB, 0x01, 0x23, 0x93, 0xF8, 0x25, 0x00, 0x00, 0x28, 0x68, 0xD0, 0xD6, 0xF8, 0x08, 0xB0, 0x0D, 0x29, 0xBB, 0xF8, -+0x00, 0x00, 0x00, 0x90, 0x69, 0xD9, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x01, 0x22, 0x13, 0x8C, 0xFF, 0x2B, 0x67, 0xD0, -+0x01, 0x92, 0x01, 0x9B, 0xDF, 0xF8, 0x88, 0x81, 0x93, 0xF8, 0x22, 0x90, 0xDF, 0xF8, 0x84, 0xA1, 0x02, 0x91, 0x4F, 0xF4, -+0xA4, 0x67, 0x07, 0xFB, 0x09, 0x87, 0xDA, 0xF8, 0xB8, 0x32, 0x97, 0xF8, 0x63, 0x20, 0x58, 0x46, 0x98, 0x47, 0x97, 0xF8, -+0x64, 0x30, 0x00, 0x2B, 0xBA, 0xD0, 0x00, 0x9B, 0x13, 0xF0, 0x04, 0x03, 0x03, 0x93, 0x05, 0xD1, 0x02, 0x99, 0x97, 0xF8, -+0x63, 0x00, 0x01, 0x22, 0x0C, 0xF0, 0x96, 0xFB, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x09, 0x88, 0x98, 0xF8, 0x62, 0x30, -+0x00, 0x2B, 0xA7, 0xD1, 0x00, 0x9A, 0x02, 0xF0, 0xFC, 0x07, 0x80, 0x2F, 0x4A, 0xD0, 0x50, 0x2F, 0x67, 0xD0, 0x03, 0x9B, -+0x00, 0x2B, 0x9D, 0xD1, 0xDA, 0xF8, 0x44, 0x32, 0x29, 0x46, 0x58, 0x46, 0x42, 0x46, 0x98, 0x47, 0x98, 0xF8, 0xC0, 0x34, -+0x00, 0x2B, 0x93, 0xD0, 0xD0, 0x2F, 0x91, 0xD1, 0xB1, 0x68, 0x63, 0x6B, 0x22, 0x8E, 0x40, 0x46, 0x0B, 0xF0, 0x5C, 0xFF, -+0x8A, 0xE7, 0x37, 0x4A, 0x25, 0xF0, 0x40, 0x05, 0x45, 0xF4, 0x00, 0x55, 0xAA, 0x43, 0x65, 0x65, 0x82, 0xD1, 0x90, 0xE7, -+0x10, 0xF4, 0x7C, 0x73, 0x93, 0xD1, 0x32, 0x49, 0x34, 0x48, 0x40, 0xF2, 0xE3, 0x12, 0x1D, 0x46, 0x10, 0xF0, 0xE0, 0xF9, -+0x77, 0xE7, 0x25, 0xF0, 0x00, 0x75, 0x65, 0x65, 0x01, 0x25, 0x28, 0x46, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x2E, 0x48, -+0x00, 0x69, 0xC3, 0xF8, 0x58, 0x02, 0x90, 0xE7, 0x00, 0x9B, 0x03, 0xF0, 0xFC, 0x03, 0x80, 0x2B, 0xED, 0xD1, 0xD3, 0x6A, -+0x01, 0x93, 0x93, 0xF8, 0x23, 0x20, 0x25, 0xF0, 0xFF, 0x73, 0x10, 0x32, 0x23, 0xF4, 0xC0, 0x33, 0x43, 0xEA, 0xC2, 0x33, -+0x63, 0x65, 0x86, 0xE7, 0x04, 0xF1, 0x14, 0x07, 0x01, 0x9A, 0xDA, 0xF8, 0x98, 0x51, 0x05, 0x93, 0x41, 0x46, 0x05, 0xAB, -+0x38, 0x46, 0xA8, 0x47, 0xDA, 0xF8, 0x40, 0x32, 0x21, 0x8E, 0x05, 0x46, 0x42, 0x46, 0x05, 0x98, 0x98, 0x47, 0xDA, 0xF8, -+0x4C, 0x34, 0x40, 0x46, 0x98, 0x47, 0x00, 0x2D, 0x3F, 0xF4, 0x41, 0xAF, 0xDA, 0xF8, 0xE4, 0x31, 0x3A, 0x46, 0x31, 0x46, -+0x40, 0x46, 0x98, 0x47, 0x39, 0xE7, 0x14, 0x4B, 0x5A, 0x7F, 0x07, 0x2A, 0x7F, 0xF4, 0x34, 0xAF, 0x93, 0xF8, 0x24, 0x00, -+0x00, 0x28, 0x7F, 0xF4, 0x2F, 0xAF, 0x10, 0x4C, 0x10, 0x4D, 0x58, 0x77, 0xD4, 0xE9, 0x00, 0x12, 0x22, 0xF4, 0x00, 0x72, -+0x01, 0x20, 0x11, 0x43, 0x62, 0x60, 0x29, 0x60, 0x83, 0xF8, 0x24, 0x00, 0x05, 0x46, 0x20, 0xE7, 0x38, 0x36, 0x17, 0x00, -+0x34, 0x36, 0x17, 0x00, 0x00, 0x20, 0x00, 0x02, 0x70, 0x79, 0x15, 0x00, 0x10, 0x96, 0x15, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x50, 0x90, 0x15, 0x00, 0x00, 0x10, 0x50, 0x40, 0x1C, 0x9E, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, 0x60, 0x00, 0x32, 0x40, -+0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x10, 0xB5, 0x07, 0x4C, 0xA3, 0x7A, 0xE2, 0x7A, 0x01, 0x33, 0xDB, 0xB2, -+0x9A, 0x42, 0xA3, 0x72, 0x00, 0xD3, 0x10, 0xBD, 0x10, 0xF0, 0xF6, 0xF9, 0x00, 0x23, 0xA3, 0x72, 0x10, 0xBD, 0x00, 0xBF, -+0x24, 0x65, 0x17, 0x00, 0x10, 0xB5, 0x10, 0x4C, 0xA3, 0x7A, 0xD3, 0xB9, 0xE3, 0x7A, 0xA3, 0x72, 0xEF, 0xF3, 0x10, 0x83, -+0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0C, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0B, 0x4A, 0x0C, 0x4C, 0x11, 0x68, 0x23, 0x68, -+0x48, 0x1C, 0x23, 0xF4, 0x80, 0x73, 0x10, 0x60, 0x23, 0x60, 0x28, 0xB1, 0x05, 0x4B, 0x11, 0x60, 0x1B, 0x68, 0x09, 0xB9, -+0x03, 0xB1, 0x62, 0xB6, 0x10, 0xBD, 0x10, 0xF0, 0xCF, 0xF9, 0xE1, 0xE7, 0x24, 0x65, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x8C, 0x80, 0x32, 0x40, 0x08, 0xB5, 0x00, 0xF0, 0x29, 0xFC, 0xFF, 0xF7, 0x93, 0xFB, 0xBD, 0xE8, -+0x08, 0x40, 0x1A, 0xF0, 0x9F, 0xB8, 0x00, 0xBF, 0x0A, 0x4A, 0x0B, 0x4B, 0x10, 0xB5, 0xD2, 0xE9, 0x20, 0x04, 0xD2, 0xE9, -+0x22, 0x12, 0x04, 0x44, 0x0A, 0x44, 0xC3, 0xE9, 0x01, 0x40, 0xC3, 0xE9, 0x03, 0x12, 0x18, 0x60, 0x59, 0x61, 0xFF, 0xF7, -+0x7D, 0xFB, 0xBD, 0xE8, 0x10, 0x40, 0x1A, 0xF0, 0x89, 0xB8, 0x00, 0xBF, 0x2C, 0x19, 0x17, 0x00, 0xEC, 0x34, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0x68, 0x81, 0xDF, 0xF8, 0x68, 0x91, 0xDF, 0xF8, 0x68, 0xA1, 0xDF, 0xF8, 0x68, 0xB1, -+0x4D, 0x4F, 0x87, 0xB0, 0x00, 0x25, 0x3C, 0xE0, 0xDA, 0xF8, 0x00, 0x30, 0xB3, 0xF5, 0x80, 0x1F, 0x4E, 0xD8, 0x20, 0x2D, -+0x4C, 0xD0, 0x10, 0xF0, 0x8D, 0xF9, 0x00, 0x28, 0x61, 0xD0, 0x1A, 0xF0, 0x81, 0xFC, 0x00, 0x28, 0x5D, 0xD0, 0x62, 0x69, -+0x5A, 0x45, 0x0E, 0xD0, 0x43, 0x4B, 0xB9, 0x68, 0x1E, 0x68, 0x53, 0xF8, 0x04, 0x0C, 0x7B, 0x68, 0xCD, 0xE9, 0x02, 0x60, -+0xCD, 0xE9, 0x00, 0x31, 0x3F, 0x48, 0x3B, 0x68, 0x21, 0x46, 0x0F, 0xF0, 0x97, 0xFE, 0x20, 0x46, 0x3D, 0x4E, 0x01, 0xF0, -+0x41, 0xF9, 0x00, 0x22, 0xD6, 0xF8, 0x94, 0x32, 0x8D, 0xF8, 0x17, 0x20, 0x0D, 0xF1, 0x17, 0x01, 0x20, 0x46, 0x98, 0x47, -+0x58, 0xBB, 0x9D, 0xF8, 0x17, 0x30, 0x73, 0xB3, 0x36, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x02, 0x2B, 0x31, 0xD0, 0x03, 0x2B, -+0x02, 0xD1, 0xD6, 0xF8, 0x8C, 0x32, 0x98, 0x47, 0x01, 0x35, 0x01, 0xF0, 0x09, 0xF9, 0x4F, 0xF4, 0x80, 0x33, 0xC9, 0xF8, -+0x00, 0x30, 0x04, 0x46, 0x4F, 0xF4, 0x80, 0x10, 0x0E, 0xF0, 0x18, 0xFC, 0x98, 0xF8, 0xB8, 0x30, 0x94, 0xB3, 0x00, 0x2B, -+0xB2, 0xD1, 0xDA, 0xF8, 0x00, 0x30, 0xB3, 0xF5, 0x80, 0x1F, 0x01, 0xD8, 0x03, 0x2D, 0xB2, 0xDD, 0x4F, 0xF4, 0x80, 0x10, -+0x0E, 0xF0, 0xE4, 0xFB, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xD6, 0xF8, 0xC8, 0x32, 0x20, 0x46, 0x98, 0x47, 0x00, 0x28, -+0xD0, 0xD1, 0x20, 0x46, 0x01, 0xF0, 0xC4, 0xF8, 0x1D, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x02, 0x2B, 0xCD, 0xD1, 0xD6, 0xF8, -+0x90, 0x32, 0x98, 0x47, 0xCE, 0xE7, 0x1A, 0x4B, 0x01, 0x22, 0x83, 0xF8, 0x45, 0x20, 0x1A, 0xF0, 0x1B, 0xFC, 0xB0, 0xFA, -+0x80, 0xF2, 0x17, 0x49, 0x52, 0x09, 0x4F, 0xF4, 0x80, 0x60, 0x0F, 0xF0, 0x8D, 0xFE, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0x1B, 0xB1, 0x13, 0x4D, 0x95, 0xF8, 0x21, 0x30, 0x3B, 0xB9, 0x12, 0x4A, 0x13, 0x68, 0x43, 0xF4, 0x80, 0x33, 0x13, 0x60, -+0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xD5, 0xE9, 0x05, 0x12, 0x28, 0x69, 0xF3, 0xF7, 0x5E, 0xFE, 0x6C, 0x61, 0xEC, 0x61, -+0x2C, 0x61, 0xAC, 0x61, 0x85, 0xF8, 0x21, 0x40, 0xEB, 0xE7, 0x00, 0xBF, 0xEC, 0x34, 0x17, 0x00, 0xD4, 0x81, 0x32, 0x40, -+0x3C, 0x96, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x78, 0x36, 0x17, 0x00, 0xB0, 0xDE, 0x17, 0x00, 0x28, 0x96, 0x15, 0x00, -+0x30, 0x65, 0x17, 0x00, 0x80, 0x80, 0x32, 0x40, 0x2C, 0x19, 0x17, 0x00, 0x7C, 0x80, 0x32, 0x40, 0x80, 0xB6, 0x17, 0x00, -+0x0D, 0xF0, 0xAD, 0xBA, 0x4F, 0xF4, 0x80, 0x00, 0x0E, 0xF0, 0x86, 0xBB, 0x2D, 0xE9, 0xF8, 0x43, 0x30, 0x4D, 0x2C, 0x68, -+0x4F, 0xF4, 0x80, 0x00, 0x0E, 0xF0, 0xA2, 0xFB, 0x00, 0x2C, 0x31, 0xD0, 0xDF, 0xF8, 0xC4, 0x90, 0x2C, 0x4F, 0x2E, 0x46, -+0x4F, 0xF0, 0x01, 0x08, 0x23, 0x7C, 0xD9, 0x07, 0x02, 0xD4, 0x2B, 0x89, 0x01, 0x33, 0x2B, 0x81, 0x30, 0x46, 0x0E, 0xF0, -+0x53, 0xFC, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x02, 0xD4, 0x72, 0xB6, 0xC7, 0xF8, 0x00, 0x80, 0xD9, 0xF8, 0x00, 0x30, -+0x62, 0x68, 0x01, 0x33, 0x00, 0x21, 0xC9, 0xF8, 0x00, 0x30, 0x21, 0x74, 0x0A, 0xB1, 0xA0, 0x68, 0x90, 0x47, 0xE0, 0x68, -+0x08, 0xB1, 0x00, 0xF0, 0x77, 0xFB, 0xD9, 0xF8, 0x00, 0x30, 0x33, 0xB1, 0x01, 0x3B, 0x3A, 0x68, 0xC9, 0xF8, 0x00, 0x30, -+0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x2C, 0x68, 0x00, 0x2C, 0xD3, 0xD1, 0xAA, 0x7A, 0xEB, 0x7A, 0x9A, 0x42, 0x20, 0xD0, -+0x13, 0x4B, 0x14, 0x48, 0x1B, 0x69, 0x14, 0x4A, 0xC8, 0x33, 0x4F, 0xF4, 0x80, 0x71, 0x03, 0x60, 0x11, 0x60, 0xEF, 0xF3, -+0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0B, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0E, 0x4A, 0x0E, 0x4C, 0x11, 0x68, -+0x23, 0x68, 0x48, 0x1C, 0x43, 0xF4, 0x80, 0x73, 0x10, 0x60, 0x23, 0x60, 0x28, 0xB1, 0x05, 0x4B, 0x11, 0x60, 0x1B, 0x68, -+0x09, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0xBF, 0x24, 0x65, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, -+0x00, 0x10, 0x50, 0x40, 0x48, 0x01, 0x32, 0x40, 0x88, 0x80, 0x32, 0x40, 0x6C, 0x28, 0x17, 0x00, 0x8C, 0x80, 0x32, 0x40, -+0x2D, 0xE9, 0xF8, 0x43, 0x27, 0x4D, 0x2C, 0x68, 0x4F, 0xF4, 0x80, 0x00, 0x0E, 0xF0, 0x30, 0xFB, 0x9C, 0xB3, 0xDF, 0xF8, -+0x9C, 0x80, 0xDF, 0xF8, 0x9C, 0x90, 0x00, 0x27, 0x2E, 0x46, 0x27, 0xE0, 0x01, 0x27, 0x30, 0x46, 0x0E, 0xF0, 0xE6, 0xFB, -+0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x01, 0x23, 0xC8, 0xF8, 0x00, 0x30, 0xD9, 0xF8, 0x00, 0x30, -+0x62, 0x68, 0x01, 0x33, 0x00, 0x21, 0xC9, 0xF8, 0x00, 0x30, 0x21, 0x74, 0x0A, 0xB1, 0xA0, 0x68, 0x90, 0x47, 0xE0, 0x68, -+0x08, 0xB1, 0x00, 0xF0, 0x09, 0xFB, 0xD9, 0xF8, 0x00, 0x30, 0x3B, 0xB1, 0x01, 0x3B, 0xD8, 0xF8, 0x00, 0x20, 0xC9, 0xF8, -+0x00, 0x30, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x2C, 0x68, 0x24, 0xB1, 0x23, 0x7C, 0xDA, 0x07, 0xD5, 0xD4, 0x00, 0x2F, -+0xD2, 0xD0, 0x0B, 0x4C, 0x94, 0xF8, 0x45, 0x30, 0x0B, 0xB9, 0xBD, 0xE8, 0xF8, 0x83, 0x4F, 0xF4, 0x80, 0x10, 0x0E, 0xF0, -+0xCD, 0xFA, 0x07, 0x49, 0x4F, 0xF4, 0x80, 0x60, 0x0F, 0xF0, 0x94, 0xFD, 0x00, 0x23, 0x84, 0xF8, 0x45, 0x30, 0xBD, 0xE8, -+0xF8, 0x83, 0x00, 0xBF, 0x24, 0x65, 0x17, 0x00, 0xB0, 0xDE, 0x17, 0x00, 0x88, 0x96, 0x15, 0x00, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x2B, 0x4E, 0x34, 0x68, 0x4F, 0xF4, 0x80, 0x00, 0x0E, 0xF0, 0xD4, 0xFA, -+0x00, 0x2C, 0x3F, 0xD0, 0x28, 0x4D, 0x2B, 0x88, 0x00, 0x2B, 0x3B, 0xD0, 0xDF, 0xF8, 0xA4, 0x80, 0xDF, 0xF8, 0xA4, 0x90, -+0x37, 0x46, 0x23, 0x7C, 0xD9, 0x07, 0x01, 0xD4, 0x2B, 0x88, 0x6B, 0xB3, 0x38, 0x46, 0x0E, 0xF0, 0x83, 0xFB, 0xEF, 0xF3, -+0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x01, 0x23, 0xC8, 0xF8, 0x00, 0x30, 0xD9, 0xF8, 0x00, 0x30, 0x22, 0x7C, -+0x01, 0x33, 0xC9, 0xF8, 0x00, 0x30, 0xD3, 0x07, 0x02, 0xD4, 0x2B, 0x88, 0x01, 0x3B, 0x2B, 0x80, 0x63, 0x68, 0x00, 0x22, -+0x22, 0x74, 0x0B, 0xB1, 0xA0, 0x68, 0x98, 0x47, 0xE0, 0x68, 0x08, 0xB1, 0x00, 0xF0, 0xA0, 0xFA, 0xD9, 0xF8, 0x00, 0x30, -+0x3B, 0xB1, 0x01, 0x3B, 0xD8, 0xF8, 0x00, 0x20, 0xC9, 0xF8, 0x00, 0x30, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x34, 0x68, -+0x00, 0x2C, 0xCC, 0xD1, 0x0B, 0x4C, 0x94, 0xF8, 0x45, 0x30, 0x0B, 0xB9, 0xBD, 0xE8, 0xF8, 0x83, 0x4F, 0xF4, 0x80, 0x10, -+0x0E, 0xF0, 0x68, 0xFA, 0x07, 0x49, 0x4F, 0xF4, 0x80, 0x60, 0x0F, 0xF0, 0x2F, 0xFD, 0x00, 0x23, 0x84, 0xF8, 0x45, 0x30, -+0xBD, 0xE8, 0xF8, 0x83, 0x24, 0x65, 0x17, 0x00, 0x54, 0x28, 0x17, 0x00, 0xB0, 0xDE, 0x17, 0x00, 0x88, 0x96, 0x15, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xF8, 0xB5, 0x0D, 0x4E, 0x35, 0x68, 0x95, 0xB1, 0x34, 0x89, 0x01, 0x34, -+0xA4, 0xB2, 0x37, 0x46, 0x38, 0x46, 0x0E, 0xF0, 0x2D, 0xFB, 0x6B, 0x68, 0x0B, 0xB1, 0xA8, 0x68, 0x98, 0x47, 0x0F, 0xF0, -+0x99, 0xFF, 0x35, 0x68, 0x34, 0x81, 0x01, 0x34, 0xA4, 0xB2, 0x00, 0x2D, 0xF0, 0xD1, 0xBD, 0xE8, 0xF8, 0x40, 0x00, 0xF0, -+0xF5, 0xB9, 0x00, 0xBF, 0x24, 0x65, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x44, 0x4F, 0x06, 0x68, 0x15, 0x88, 0xDF, 0xF8, -+0x20, 0x91, 0xDF, 0xF8, 0x20, 0xA1, 0xDF, 0xF8, 0x20, 0xB1, 0x85, 0xB0, 0x4F, 0xF0, 0x00, 0x08, 0xCD, 0xE9, 0x02, 0x02, -+0x87, 0xF8, 0x02, 0x80, 0xCD, 0xF8, 0x04, 0x80, 0x4A, 0xE0, 0xC4, 0x1A, 0x2C, 0x44, 0x0C, 0x44, 0x55, 0x1B, 0xA9, 0xB2, -+0xA4, 0xB2, 0x00, 0x25, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x36, 0x4A, 0x01, 0x23, 0x13, 0x60, -+0xBA, 0xF8, 0x00, 0x30, 0xDB, 0xF8, 0x00, 0x20, 0xD9, 0xF8, 0x00, 0xC0, 0x00, 0x92, 0x02, 0xEB, 0xC3, 0x00, 0xB2, 0x68, -+0x42, 0x60, 0x00, 0x9A, 0x0C, 0xF1, 0x01, 0x0E, 0xC9, 0xF8, 0x00, 0xE0, 0x42, 0xF8, 0x33, 0x10, 0xFA, 0x78, 0x01, 0x33, -+0x01, 0x32, 0x88, 0x44, 0xAA, 0xF8, 0x00, 0x30, 0xFA, 0x70, 0x64, 0xBB, 0xC3, 0x78, 0xA7, 0xF8, 0x00, 0x80, 0x43, 0xF0, -+0x04, 0x03, 0x01, 0x22, 0xC3, 0x70, 0xBA, 0x70, 0xB8, 0x60, 0xBE, 0xF1, 0x00, 0x0F, 0x38, 0xD0, 0x21, 0x4B, 0xC9, 0xF8, -+0x00, 0xC0, 0x1B, 0x68, 0xBC, 0xF1, 0x00, 0x0F, 0x31, 0xD1, 0x00, 0x2B, 0x2F, 0xD0, 0x62, 0xB6, 0x00, 0x2C, 0x2C, 0xD0, -+0x1C, 0x4B, 0x1A, 0x68, 0x73, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x1A, 0xDB, 0x01, 0x96, 0x21, 0x46, 0x1E, 0x46, -+0xF3, 0x68, 0x30, 0x89, 0x01, 0x33, 0x9B, 0xB2, 0x1A, 0x1A, 0x92, 0xB2, 0x4C, 0x19, 0x94, 0x42, 0xAB, 0xDA, 0x00, 0x24, -+0xB0, 0xE7, 0xBE, 0xF1, 0x00, 0x0F, 0xE7, 0xD0, 0x0F, 0x4B, 0xC9, 0xF8, 0x00, 0xC0, 0x1B, 0x68, 0xBC, 0xF1, 0x00, 0x0F, -+0xE0, 0xD1, 0x00, 0x2B, 0xDB, 0xD1, 0xDD, 0xE7, 0x00, 0x2B, 0xE2, 0xD1, 0x0B, 0x49, 0x0C, 0x48, 0x00, 0x93, 0x4F, 0xF4, -+0x17, 0x72, 0x0F, 0xF0, 0xA9, 0xFE, 0x00, 0x9B, 0xD9, 0xE7, 0x02, 0x9B, 0x01, 0x98, 0x1E, 0x60, 0x03, 0x9B, 0x1D, 0x80, -+0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0xBF, 0x54, 0x65, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xA0, 0x96, 0x15, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xB0, 0x56, 0x17, 0x00, 0x54, 0x60, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x4F, 0x41, 0x4F, 0xB2, 0xF8, 0x00, 0xA0, 0x06, 0x68, 0xDF, 0xF8, 0x0C, 0xB1, 0x87, 0xB0, 0x4F, 0xF0, -+0x00, 0x08, 0xCD, 0xE9, 0x04, 0x02, 0x01, 0x22, 0x0B, 0x46, 0x87, 0xF8, 0x20, 0x20, 0xC1, 0x46, 0xCD, 0xF8, 0x0C, 0x80, -+0x39, 0xE0, 0x05, 0x44, 0xAD, 0x1A, 0xA1, 0xEB, 0x0A, 0x03, 0xAD, 0xB2, 0x9B, 0xB2, 0x00, 0x2D, 0x02, 0x93, 0x08, 0xBF, -+0x4F, 0xF0, 0x01, 0x09, 0xF2, 0xF7, 0x3C, 0xFC, 0x4F, 0xF0, 0x00, 0x0A, 0x02, 0x9B, 0x04, 0x46, 0x00, 0x28, 0x3A, 0xD0, -+0x7A, 0x68, 0x02, 0xB9, 0x38, 0x60, 0xDB, 0xF8, 0x00, 0x00, 0xF9, 0x68, 0xB0, 0xF9, 0x00, 0x00, 0x19, 0x44, 0x01, 0x32, -+0x00, 0x28, 0xF9, 0x60, 0x7A, 0x60, 0xB1, 0x68, 0x36, 0xDB, 0xCD, 0xF8, 0x00, 0x90, 0x00, 0x22, 0x20, 0x46, 0xF3, 0xF7, -+0x6F, 0xFC, 0xB8, 0xF1, 0x00, 0x0F, 0x01, 0xD0, 0xC8, 0xF8, 0x04, 0x40, 0xBC, 0x60, 0x05, 0xB3, 0xDB, 0xF8, 0x00, 0x20, -+0x73, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x2E, 0xDB, 0x03, 0x96, 0xA0, 0x46, 0x1E, 0x46, 0x2B, 0x46, 0xF2, 0x68, -+0x35, 0x89, 0x01, 0x32, 0x92, 0xB2, 0x51, 0x1B, 0x89, 0xB2, 0x03, 0xEB, 0x0A, 0x00, 0x88, 0x42, 0xBB, 0xDA, 0x02, 0x93, -+0xF2, 0xF7, 0x02, 0xFC, 0x00, 0x25, 0x02, 0x9B, 0x4F, 0xF0, 0x01, 0x09, 0x04, 0x46, 0x00, 0x28, 0xC4, 0xD1, 0x87, 0xF8, -+0x20, 0x00, 0x04, 0x9B, 0x03, 0x98, 0x1E, 0x60, 0x05, 0x9B, 0xA3, 0xF8, 0x00, 0xA0, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0x00, 0x29, 0xC6, 0xD1, 0x0B, 0x49, 0x0C, 0x48, 0x02, 0x93, 0x40, 0xF2, 0x9E, 0x22, 0x0F, 0xF0, 0x17, 0xFE, 0xB1, 0x68, -+0x02, 0x9B, 0xBC, 0xE7, 0x00, 0x2B, 0xCE, 0xD1, 0x05, 0x49, 0x07, 0x48, 0x02, 0x93, 0x40, 0xF2, 0xB3, 0x22, 0x0F, 0xF0, -+0x0B, 0xFE, 0x02, 0x9B, 0xC5, 0xE7, 0x00, 0xBF, 0x30, 0x65, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xAC, 0x96, 0x15, 0x00, -+0xA0, 0x96, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0x08, 0x91, 0x07, 0x68, 0xD9, 0xF8, -+0x00, 0x40, 0x1D, 0x88, 0x94, 0xF8, 0x00, 0xC0, 0xDF, 0xF8, 0xFC, 0xA0, 0x85, 0xB0, 0xB1, 0xF5, 0xC8, 0x6F, 0x0E, 0x9E, -+0x03, 0x93, 0x06, 0xEB, 0x46, 0x06, 0x28, 0xBF, 0x4F, 0xF4, 0xC8, 0x61, 0xBC, 0xF1, 0x03, 0x0F, 0x08, 0xBF, 0x34, 0x4B, -+0x02, 0x90, 0x07, 0xEB, 0x06, 0x16, 0x06, 0xF1, 0x14, 0x06, 0x90, 0x46, 0x08, 0xBF, 0x1E, 0x60, 0x00, 0x20, 0x2C, 0xE0, -+0xAE, 0xEB, 0x03, 0x04, 0x2C, 0x44, 0x0C, 0x44, 0x52, 0x1B, 0xA4, 0xB2, 0x91, 0xB2, 0x00, 0x25, 0xBC, 0xF1, 0x03, 0x0F, -+0x0D, 0xD1, 0xB1, 0xF5, 0x00, 0x6F, 0x0B, 0x46, 0x28, 0xBF, 0x4F, 0xF4, 0x00, 0x63, 0x43, 0xF0, 0x23, 0x43, 0x4F, 0xF0, -+0x04, 0x12, 0xB3, 0x60, 0xF1, 0x60, 0x31, 0x61, 0x72, 0x61, 0x88, 0x44, 0xA4, 0xB3, 0xDA, 0xF8, 0x00, 0x20, 0x7B, 0x68, -+0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x03, 0xF1, 0x14, 0x0B, 0x1C, 0xDB, 0xBC, 0xF1, 0x03, 0x0F, 0x01, 0xD1, 0xC6, 0xF8, -+0x20, 0xB0, 0x38, 0x46, 0x5E, 0x46, 0x1F, 0x46, 0x21, 0x46, 0xD7, 0xE9, 0x02, 0x43, 0x01, 0x33, 0x1F, 0xFA, 0x84, 0xFE, -+0x9B, 0xB2, 0xA3, 0xEB, 0x0E, 0x02, 0x05, 0xEB, 0x04, 0x0B, 0x92, 0xB2, 0x4C, 0x19, 0x94, 0x42, 0xC6, 0xF8, 0x04, 0x80, -+0xC6, 0xF8, 0x00, 0xB0, 0xC0, 0xDA, 0x00, 0x24, 0xC6, 0xE7, 0x00, 0x2B, 0xE0, 0xD1, 0x4F, 0xF4, 0x4A, 0x72, 0x0D, 0x49, -+0x0D, 0x48, 0x01, 0x93, 0x0F, 0xF0, 0x90, 0xFD, 0xD9, 0xF8, 0x00, 0x20, 0x01, 0x9B, 0x92, 0xF8, 0x00, 0xC0, 0xD3, 0xE7, -+0xBC, 0xF1, 0x03, 0x0F, 0x02, 0xD1, 0x05, 0x4B, 0x34, 0x62, 0x5E, 0x60, 0x02, 0x9B, 0x1F, 0x60, 0x03, 0x9B, 0x1D, 0x80, -+0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0xBF, 0x60, 0x65, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xA0, 0x96, 0x15, 0x00, -+0x78, 0x36, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x61, 0xB3, 0x0B, 0x8A, 0xDA, 0x07, 0x12, 0xD4, 0x16, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x20, 0x02, 0xE0, 0x0B, 0x8A, 0xDB, 0x07, 0x0A, 0xD4, 0x00, 0x2A, 0x49, 0x68, 0xF9, 0xDA, 0x00, 0x29, -+0xF7, 0xD1, 0x11, 0x49, 0x11, 0x48, 0x40, 0xF2, 0xE6, 0x32, 0x0F, 0xF0, 0x29, 0xBD, 0xCB, 0x68, 0x23, 0xF0, 0x03, 0x03, -+0x04, 0x33, 0x0E, 0x49, 0x4A, 0x68, 0x9A, 0x42, 0x8A, 0x68, 0x08, 0xBF, 0x0B, 0x68, 0xC0, 0xF8, 0x98, 0x30, 0x22, 0xF0, -+0x00, 0x40, 0x83, 0x42, 0x02, 0xF0, 0x00, 0x42, 0x38, 0xBF, 0x02, 0xF1, 0x00, 0x42, 0x13, 0x43, 0x8B, 0x60, 0x70, 0x47, -+0x00, 0xF1, 0xA0, 0x03, 0xE9, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xA0, 0x96, 0x15, 0x00, -+0xEC, 0x34, 0x17, 0x00, 0x18, 0x4B, 0x19, 0x4A, 0x18, 0x68, 0x19, 0x49, 0xDF, 0xF8, 0x7C, 0xC0, 0xF0, 0xB5, 0xD0, 0xE9, -+0x00, 0x34, 0x17, 0x4D, 0x13, 0x60, 0x1C, 0x44, 0x2B, 0x60, 0x25, 0x1F, 0x0D, 0x60, 0x15, 0x4E, 0x15, 0x4D, 0x11, 0x68, -+0x31, 0x60, 0x29, 0x60, 0xD0, 0xE9, 0x02, 0x10, 0xDF, 0xF8, 0x5C, 0xE0, 0x12, 0x4F, 0x54, 0x60, 0x08, 0x44, 0x69, 0x60, -+0x11, 0x4C, 0x93, 0x60, 0x11, 0x4E, 0x03, 0x1F, 0xCE, 0xF8, 0x00, 0x30, 0xCC, 0xF8, 0x00, 0x10, 0x39, 0x60, 0x6E, 0x61, -+0x23, 0x68, 0x10, 0x61, 0x03, 0xF4, 0x00, 0x23, 0x43, 0xF4, 0xF0, 0x23, 0x43, 0xF0, 0x25, 0x03, 0xD1, 0x60, 0x51, 0x61, -+0x23, 0x60, 0xF0, 0xBD, 0x30, 0x36, 0x17, 0x00, 0xEC, 0x34, 0x17, 0x00, 0xCC, 0x81, 0x32, 0x40, 0xC8, 0x81, 0x32, 0x40, -+0xD0, 0x81, 0x32, 0x40, 0xD4, 0x81, 0x32, 0x40, 0xE4, 0x81, 0x32, 0x40, 0x0C, 0x01, 0x32, 0x40, 0x05, 0x12, 0x00, 0x0C, -+0xE0, 0x81, 0x32, 0x40, 0xDC, 0x81, 0x32, 0x40, 0x10, 0xB4, 0x0A, 0x4C, 0x0A, 0x49, 0x22, 0x68, 0x83, 0x02, 0x03, 0xF4, -+0x80, 0x63, 0x22, 0xF4, 0x80, 0x62, 0x13, 0x43, 0x23, 0x60, 0x0B, 0x68, 0x5D, 0xF8, 0x04, 0x4B, 0xC0, 0x04, 0x00, 0xF4, -+0x00, 0x20, 0x23, 0xF4, 0x00, 0x23, 0x18, 0x43, 0x08, 0x60, 0x70, 0x47, 0x24, 0x03, 0x32, 0x40, 0x0C, 0x01, 0x32, 0x40, -+0x90, 0xF8, 0x9C, 0x20, 0xD0, 0xF8, 0x98, 0x30, 0x6A, 0xB9, 0x0E, 0x4A, 0x12, 0x68, 0x22, 0xF0, 0x00, 0x41, 0x8B, 0x42, -+0x02, 0xF0, 0x00, 0x42, 0x0A, 0x49, 0x38, 0xBF, 0x02, 0xF1, 0x00, 0x42, 0x13, 0x43, 0x0B, 0x60, 0x70, 0x47, 0x08, 0x4A, -+0x12, 0x68, 0x22, 0xF0, 0x00, 0x41, 0x8B, 0x42, 0x02, 0xF0, 0x00, 0x42, 0x04, 0x49, 0x38, 0xBF, 0x02, 0xF1, 0x00, 0x42, -+0x13, 0x43, 0x0B, 0x60, 0x70, 0x47, 0x00, 0xBF, 0xD0, 0x81, 0x32, 0x40, 0xE0, 0x81, 0x32, 0x40, 0x10, 0xB5, 0x03, 0x8E, -+0x82, 0xB0, 0xC3, 0xB1, 0x2D, 0x4B, 0xC4, 0x69, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x38, 0xDB, 0xA3, 0x68, -+0x42, 0x6D, 0x1B, 0x88, 0x03, 0xF0, 0xFC, 0x03, 0x24, 0x2B, 0x43, 0xD0, 0x94, 0x2B, 0x03, 0xD1, 0x42, 0xF2, 0x02, 0x03, -+0x93, 0x43, 0x36, 0xD0, 0xE3, 0x68, 0x23, 0xF0, 0x03, 0x03, 0x04, 0x33, 0x07, 0xE0, 0x21, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x18, 0xDB, 0x00, 0xF1, 0xA0, 0x03, 0x1E, 0x49, 0x0A, 0x69, 0x9A, 0x42, 0x4A, 0x69, 0x08, 0xBF, -+0xCB, 0x68, 0xC0, 0xF8, 0x98, 0x30, 0x22, 0xF0, 0x00, 0x44, 0xA3, 0x42, 0x02, 0xF0, 0x00, 0x42, 0x38, 0xBF, 0x02, 0xF1, -+0x00, 0x42, 0x13, 0x43, 0x4B, 0x61, 0x02, 0xB0, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0x9E, 0xBF, 0xC3, 0x69, 0x00, 0x2B, -+0xE3, 0xD0, 0x12, 0x49, 0x12, 0x48, 0x4F, 0xF4, 0xD7, 0x72, 0x05, 0xE0, 0x00, 0x2C, 0xC4, 0xD1, 0x0E, 0x49, 0x10, 0x48, -+0x4F, 0xF4, 0xC2, 0x72, 0x02, 0xB0, 0xBD, 0xE8, 0x10, 0x40, 0x0F, 0xF0, 0x2F, 0xBC, 0x0D, 0x4B, 0x01, 0x90, 0xD3, 0xF8, -+0x74, 0x33, 0x98, 0x47, 0x01, 0x98, 0xC1, 0xE7, 0x93, 0x04, 0xBF, 0xD5, 0x08, 0x4B, 0x01, 0x90, 0xD3, 0xF8, 0xFC, 0x33, -+0x98, 0x47, 0x01, 0x98, 0xB8, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0xEC, 0x34, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xC8, 0x96, 0x15, 0x00, 0xA0, 0x96, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x00, 0x29, 0x46, 0xD0, 0x2D, 0xE9, 0xF8, 0x4F, -+0x07, 0x46, 0xDF, 0xF8, 0x8C, 0xA0, 0xDF, 0xF8, 0x8C, 0xB0, 0x08, 0x46, 0x1F, 0x49, 0x99, 0x46, 0x4F, 0xF0, 0x00, 0x08, -+0xD7, 0xE9, 0x02, 0x45, 0x01, 0x35, 0xAB, 0xB2, 0xA6, 0xB2, 0x9D, 0x1B, 0xAD, 0xB2, 0xAD, 0x1A, 0xA8, 0x42, 0x23, 0xDB, -+0xF6, 0x1A, 0x16, 0x44, 0x06, 0x44, 0xB6, 0xB2, 0xA8, 0xB2, 0xC5, 0x1C, 0x4F, 0xEA, 0x98, 0x03, 0xAD, 0x08, 0x14, 0x44, -+0x09, 0xEB, 0x83, 0x03, 0x08, 0xD0, 0x1A, 0x46, 0x03, 0xEB, 0x85, 0x05, 0xE3, 0x1A, 0xD4, 0x58, 0x42, 0xF8, 0x04, 0x4B, -+0xAA, 0x42, 0xFA, 0xD1, 0xBE, 0xB1, 0xDA, 0xF8, 0x00, 0x30, 0x7F, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x80, 0x44, 0x00, 0x2B, -+0x1F, 0xFA, 0x88, 0xF8, 0x04, 0xDB, 0x30, 0x46, 0x00, 0x22, 0xD1, 0xE7, 0x00, 0x26, 0xDE, 0xE7, 0x00, 0x2F, 0xF8, 0xD1, -+0x40, 0xF2, 0x2D, 0x42, 0x58, 0x46, 0x0F, 0xF0, 0xFF, 0xFB, 0x02, 0x49, 0xF1, 0xE7, 0xBD, 0xE8, 0xF8, 0x8F, 0x70, 0x47, -+0x70, 0x79, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0xEC, 0x96, 0x15, 0x00, 0x38, 0xB5, 0x13, 0x4C, 0x94, 0xF8, 0x21, 0x30, -+0xA3, 0xB9, 0x20, 0x61, 0x11, 0x48, 0xE3, 0x69, 0xE2, 0x68, 0x61, 0x69, 0x65, 0x68, 0x90, 0xF8, 0xB9, 0x00, 0x13, 0x44, -+0x29, 0x44, 0xA2, 0x68, 0x61, 0x61, 0x01, 0x25, 0xB3, 0xEB, 0x40, 0x2F, 0xE3, 0x61, 0x84, 0xF8, 0x21, 0x50, 0xA2, 0x61, -+0x03, 0xD2, 0x38, 0xBD, 0xA3, 0x69, 0x58, 0x60, 0xE8, 0xE7, 0x20, 0x69, 0xF3, 0xF7, 0x90, 0xF9, 0x00, 0x23, 0xC4, 0xE9, -+0x04, 0x33, 0xC4, 0xE9, 0x06, 0x33, 0x84, 0xF8, 0x21, 0x30, 0x38, 0xBD, 0x30, 0x65, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x47, 0xAB, 0x4E, 0xD0, 0xF8, 0x1C, 0xC0, 0x35, 0x68, 0x86, 0xB0, 0x04, 0x46, 0xCD, 0xF8, 0x14, 0xC0, -+0xAD, 0xF8, 0x0E, 0x30, 0x2B, 0x78, 0x02, 0x2B, 0x91, 0x46, 0x00, 0xF0, 0xAD, 0x80, 0x01, 0x2B, 0xDF, 0xF8, 0xC4, 0x82, -+0x22, 0xD0, 0x01, 0x20, 0x00, 0x23, 0xD8, 0xF8, 0xAC, 0x52, 0x4A, 0x46, 0xCD, 0xE9, 0x00, 0x30, 0x0D, 0xF1, 0x0E, 0x03, -+0x05, 0xA8, 0xA8, 0x47, 0x33, 0x68, 0x1B, 0x78, 0x02, 0x2B, 0x05, 0x46, 0x1F, 0xD0, 0x01, 0x2B, 0x59, 0xD0, 0xD8, 0xF8, -+0x98, 0x32, 0x05, 0x99, 0x20, 0x46, 0x2A, 0x46, 0x98, 0x47, 0x0E, 0x9B, 0x63, 0x60, 0x0F, 0x9B, 0x95, 0x48, 0xA3, 0x60, -+0x21, 0x46, 0x0D, 0xF0, 0x3F, 0xFF, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0xD8, 0xF8, 0xB0, 0x52, 0x00, 0x23, 0x00, 0x93, -+0x0D, 0xF1, 0x0E, 0x02, 0x05, 0xA8, 0xA8, 0x47, 0x33, 0x68, 0x1B, 0x78, 0x02, 0x2B, 0x05, 0x46, 0xDF, 0xD1, 0xDF, 0xF8, -+0x64, 0x92, 0x99, 0xF8, 0x02, 0x30, 0x00, 0x2B, 0xDB, 0xD0, 0xB9, 0xF8, 0x00, 0x30, 0x7A, 0x68, 0x3A, 0x33, 0xBB, 0x60, -+0xD3, 0x78, 0x6F, 0xF3, 0x87, 0x13, 0xD3, 0x70, 0x99, 0xF8, 0x03, 0x30, 0xBB, 0x73, 0x00, 0x23, 0x3B, 0x60, 0xEF, 0xF3, -+0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x7F, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xDF, 0xF8, 0x20, 0xA2, 0x7E, 0x48, -+0xDA, 0xF8, 0x00, 0x30, 0x39, 0x46, 0x01, 0x33, 0xCA, 0xF8, 0x00, 0x30, 0x0D, 0xF0, 0x08, 0xFF, 0xD8, 0xF8, 0x44, 0x34, -+0x98, 0x47, 0xDA, 0xF8, 0x00, 0x30, 0x3B, 0xB1, 0x75, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xCA, 0xF8, 0x00, 0x30, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x00, 0x23, 0xC9, 0xE9, 0x00, 0x33, 0x32, 0x68, 0x13, 0x78, 0x01, 0x2B, 0xA5, 0xD1, 0xF2, 0xF7, -+0x15, 0xF9, 0x07, 0x46, 0x00, 0x28, 0x00, 0xF0, 0x92, 0x80, 0x6D, 0x4E, 0x96, 0xF8, 0x20, 0x30, 0x00, 0x2B, 0x00, 0xF0, -+0x96, 0x80, 0x73, 0x68, 0x81, 0x68, 0x32, 0x68, 0x03, 0xF1, 0x01, 0x0C, 0x4F, 0xEA, 0x0C, 0x63, 0x21, 0xF0, 0xFE, 0x41, -+0x03, 0xF0, 0xFE, 0x43, 0x0B, 0x43, 0x00, 0x21, 0x83, 0x60, 0x00, 0x91, 0x3A, 0x23, 0x04, 0xF1, 0x30, 0x01, 0xC6, 0xF8, -+0x04, 0xC0, 0xF3, 0xF7, 0x43, 0xF9, 0x60, 0x4A, 0xF3, 0x68, 0x92, 0xF8, 0xB8, 0x20, 0x3A, 0x33, 0xF3, 0x60, 0x38, 0x46, -+0x00, 0x2A, 0x40, 0xF0, 0xA7, 0x80, 0xD6, 0xE9, 0x01, 0x12, 0xF3, 0xF7, 0xD3, 0xF8, 0x5A, 0x49, 0x0A, 0x78, 0x00, 0x23, -+0x42, 0xF0, 0x01, 0x02, 0x0A, 0x70, 0x73, 0x60, 0xF3, 0x60, 0x33, 0x60, 0xB3, 0x60, 0x86, 0xF8, 0x20, 0x30, 0x68, 0xE7, -+0x54, 0x4D, 0x42, 0xF2, 0x24, 0x03, 0xEA, 0x58, 0x00, 0x2A, 0x68, 0xD0, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, -+0x72, 0xB6, 0x4A, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x42, 0xF2, 0x34, 0x02, 0xDF, 0xF8, 0x44, 0x81, 0xA8, 0x5A, 0xD8, 0xF8, -+0x00, 0x30, 0x02, 0x91, 0x01, 0x33, 0xB0, 0xF5, 0xC3, 0x7F, 0xC8, 0xF8, 0x00, 0x30, 0x48, 0x48, 0xDF, 0xF8, 0x3C, 0xA1, -+0x84, 0xBF, 0x00, 0x23, 0xAB, 0x52, 0x0D, 0xF0, 0xD7, 0xFE, 0x45, 0x4A, 0x02, 0x99, 0xD2, 0xF8, 0x00, 0xC0, 0x42, 0xF2, -+0x34, 0x0E, 0x07, 0x46, 0x35, 0xF8, 0x0E, 0x30, 0xBB, 0x81, 0x0C, 0xEB, 0xC3, 0x00, 0x04, 0xF1, 0x30, 0x02, 0x42, 0x60, -+0x4C, 0xF8, 0x33, 0xA0, 0xDF, 0xF8, 0x08, 0xC1, 0x78, 0x60, 0x95, 0xF8, 0x02, 0xAC, 0x9C, 0xF8, 0x03, 0x00, 0xD8, 0xF8, -+0x00, 0x20, 0x01, 0x33, 0x0A, 0xF1, 0x01, 0x0A, 0x01, 0x30, 0x25, 0xF8, 0x0E, 0x30, 0x85, 0xF8, 0x02, 0xAC, 0x8C, 0xF8, -+0x03, 0x00, 0x3A, 0xB1, 0x2B, 0x4B, 0x01, 0x3A, 0x1B, 0x68, 0xC8, 0xF8, 0x00, 0x20, 0x0A, 0xB9, 0x00, 0x2B, 0x48, 0xD1, -+0x33, 0x68, 0x1B, 0x78, 0x02, 0x2B, 0x7F, 0xF4, 0xFE, 0xAE, 0xDF, 0xF8, 0xC4, 0x80, 0x00, 0x23, 0xD8, 0xF8, 0xB4, 0x52, -+0x21, 0xE7, 0x23, 0x7C, 0x29, 0x48, 0x43, 0xF0, 0x01, 0x03, 0x23, 0x74, 0x0F, 0xF0, 0x2E, 0xF8, 0x20, 0x4B, 0x83, 0xF8, -+0x20, 0x70, 0x26, 0x49, 0x4F, 0xF4, 0x80, 0x60, 0x0F, 0xF0, 0x76, 0xF8, 0x23, 0x7C, 0x43, 0xF0, 0x01, 0x03, 0x23, 0x74, -+0xF9, 0xE6, 0x03, 0x7C, 0xDF, 0xF8, 0x8C, 0x80, 0x43, 0xF0, 0x01, 0x03, 0x03, 0x74, 0xD8, 0xF8, 0x98, 0x32, 0x61, 0x46, -+0x98, 0x47, 0xEF, 0xF3, 0x10, 0x83, 0xD9, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x10, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x19, 0x4C, -+0xD8, 0xF8, 0x44, 0x24, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x90, 0x47, 0x23, 0x68, 0x01, 0x46, 0x33, 0xB1, 0x0A, 0x4A, -+0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x11, 0x48, 0xF0, 0xF7, 0x31, 0xFE, 0xE0, 0xE6, -+0xFF, 0xF7, 0x7E, 0xFE, 0x59, 0xE7, 0x62, 0xB6, 0xB4, 0xE7, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, 0x24, 0x65, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0xA8, 0x56, 0x17, 0x00, 0x30, 0x65, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x9C, 0x4E, 0x17, 0x00, -+0x7C, 0x36, 0x17, 0x00, 0xA0, 0x56, 0x17, 0x00, 0x54, 0x60, 0x17, 0x00, 0x0C, 0x97, 0x15, 0x00, 0x20, 0x97, 0x15, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0xF8, 0x96, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x54, 0x65, 0x17, 0x00, 0x3C, 0x00, 0x00, 0xC0, -+0x2D, 0xE9, 0xF0, 0x4F, 0xAE, 0x4B, 0xDF, 0xF8, 0x00, 0xA3, 0xC1, 0x69, 0x9A, 0xF8, 0x32, 0x20, 0x1B, 0x68, 0x87, 0xB0, -+0x04, 0x46, 0x05, 0x91, 0xAD, 0xF8, 0x12, 0x20, 0x1B, 0x78, 0x03, 0x2B, 0x00, 0xF0, 0x3F, 0x81, 0x02, 0x2B, 0x77, 0xD0, -+0xA6, 0x4A, 0x27, 0x8E, 0x12, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xC0, 0xF2, 0xBF, 0x80, 0x01, 0x2B, 0xA3, 0x4E, -+0x4F, 0xF0, 0x00, 0x03, 0x00, 0xF0, 0x3A, 0x81, 0xCD, 0xE9, 0x00, 0x33, 0x39, 0x46, 0xD6, 0xF8, 0xAC, 0x52, 0x0D, 0xF1, -+0x12, 0x03, 0x5A, 0x46, 0x05, 0xA8, 0xA8, 0x47, 0x07, 0xEB, 0x0B, 0x01, 0xCA, 0xF8, 0x1C, 0x10, 0x07, 0x46, 0x00, 0x21, -+0x04, 0xF1, 0x58, 0x00, 0xEB, 0xF7, 0x7E, 0xFD, 0x94, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0x00, 0xF0, 0xB8, 0x80, -+0x01, 0x2B, 0x00, 0xF0, 0x49, 0x81, 0x02, 0x2B, 0x41, 0xD1, 0xDF, 0xF8, 0x88, 0xA2, 0x9A, 0xF8, 0x02, 0x30, 0x00, 0x2B, -+0x3B, 0xD0, 0xBA, 0xF8, 0x00, 0x30, 0xD8, 0xF8, 0x04, 0x20, 0x3A, 0x33, 0xC8, 0xF8, 0x08, 0x30, 0xD3, 0x78, 0x6F, 0xF3, -+0x87, 0x13, 0xD3, 0x70, 0x9A, 0xF8, 0x03, 0x30, 0x88, 0xF8, 0x0E, 0x30, 0x00, 0x23, 0xC8, 0xF8, 0x00, 0x30, 0xEF, 0xF3, -+0x10, 0x83, 0xDD, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x83, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xDF, 0xF8, 0x14, 0xB2, 0x82, 0x48, -+0xDB, 0xF8, 0x00, 0x30, 0x41, 0x46, 0x01, 0x33, 0xCB, 0xF8, 0x00, 0x30, 0x0D, 0xF0, 0x8C, 0xFD, 0xD6, 0xF8, 0x44, 0x34, -+0x98, 0x47, 0xDB, 0xF8, 0x00, 0x30, 0x3B, 0xB1, 0x79, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xCB, 0xF8, 0x00, 0x30, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x72, 0x4B, 0x1A, 0x68, 0x00, 0x23, 0xCA, 0xE9, 0x00, 0x33, 0x13, 0x78, 0x03, 0x2B, 0x00, 0xF0, -+0x9E, 0x81, 0xD6, 0xF8, 0x98, 0x32, 0x05, 0x99, 0x3A, 0x46, 0x20, 0x46, 0x98, 0x47, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0x6E, 0x4E, 0x42, 0xF2, 0x24, 0x03, 0xF2, 0x58, 0x00, 0x2A, 0x00, 0xF0, 0x60, 0x81, 0xEF, 0xF3, 0x10, 0x83, 0xDF, 0x07, -+0x03, 0xD4, 0x72, 0xB6, 0x66, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x42, 0xF2, 0x34, 0x02, 0x67, 0x4F, 0xB1, 0x5A, 0x3B, 0x68, -+0x66, 0x48, 0x01, 0x33, 0xB1, 0xF5, 0xC3, 0x7F, 0x3B, 0x60, 0x84, 0xBF, 0x00, 0x23, 0xB3, 0x52, 0x0D, 0xF0, 0x92, 0xFD, -+0x62, 0x4A, 0x42, 0xF2, 0x34, 0x0E, 0xD2, 0xF8, 0x00, 0xC0, 0x36, 0xF8, 0x0E, 0x30, 0x83, 0x81, 0x0C, 0xEB, 0xC3, 0x01, -+0x04, 0xF1, 0x30, 0x02, 0x4A, 0x60, 0x5D, 0x4A, 0x4C, 0xF8, 0x33, 0x20, 0xDF, 0xF8, 0x94, 0xC1, 0x41, 0x60, 0x96, 0xF8, -+0x02, 0x1C, 0x9C, 0xF8, 0x03, 0x20, 0x80, 0x46, 0x38, 0x68, 0x01, 0x33, 0x01, 0x31, 0x01, 0x32, 0x26, 0xF8, 0x0E, 0x30, -+0x86, 0xF8, 0x02, 0x1C, 0x8C, 0xF8, 0x03, 0x20, 0x30, 0xB1, 0x4C, 0x4B, 0x01, 0x38, 0x1B, 0x68, 0x38, 0x60, 0x08, 0xB9, -+0x03, 0xB1, 0x62, 0xB6, 0x46, 0x4B, 0x27, 0x8E, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x06, 0xDA, 0x00, 0x2F, -+0x00, 0xF0, 0x07, 0x81, 0xB7, 0xF5, 0x40, 0x5F, 0x00, 0xF2, 0x0A, 0x81, 0x3E, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x02, 0x2B, -+0x7F, 0xF4, 0x34, 0xAF, 0x3D, 0x4E, 0x39, 0x46, 0xD6, 0xF8, 0xB4, 0x72, 0x00, 0x23, 0x00, 0x93, 0x0D, 0xF1, 0x12, 0x02, -+0x05, 0xA8, 0xB8, 0x47, 0x07, 0x46, 0x3C, 0xE7, 0x3F, 0x4A, 0x40, 0x48, 0x53, 0x68, 0x60, 0x66, 0x04, 0xF1, 0x30, 0x00, -+0xA0, 0x66, 0x04, 0xF1, 0x68, 0x00, 0x3D, 0x49, 0xC4, 0xF8, 0x6C, 0x90, 0x18, 0x62, 0x3A, 0x23, 0x21, 0x67, 0x63, 0x67, -+0x4F, 0xF0, 0x04, 0x11, 0xA3, 0x67, 0x00, 0x23, 0x03, 0x90, 0xE1, 0x67, 0xC4, 0xF8, 0x88, 0x30, 0x10, 0x68, 0x03, 0x99, -+0x05, 0x22, 0xF0, 0xF7, 0xC5, 0xF9, 0x34, 0x4A, 0x13, 0x68, 0x18, 0x05, 0xFC, 0xD5, 0x13, 0x68, 0x59, 0x03, 0x03, 0xD5, -+0x11, 0x68, 0x41, 0xF0, 0x80, 0x61, 0x11, 0x60, 0x1A, 0x05, 0x21, 0xD5, 0xEF, 0xF3, 0x05, 0x80, 0x2D, 0x49, 0x41, 0xF2, -+0x4C, 0x12, 0x8B, 0x58, 0x43, 0xF0, 0x00, 0x63, 0x8B, 0x50, 0x00, 0x28, 0x40, 0xF0, 0xF3, 0x80, 0xEF, 0xF3, 0x10, 0x83, -+0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x1B, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x1C, 0x4B, 0x25, 0x48, 0x19, 0x68, 0x00, 0x25, -+0x4A, 0x1C, 0x1A, 0x60, 0x45, 0x61, 0x2A, 0xB1, 0x15, 0x4A, 0x19, 0x60, 0x13, 0x68, 0x09, 0xB9, 0x03, 0xB1, 0x62, 0xB6, -+0x1F, 0x4D, 0x2B, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x1E, 0x4B, 0x18, 0x68, 0xA9, 0xF1, 0x14, 0x01, 0x00, 0xF5, 0x0B, 0x70, -+0x0D, 0xF0, 0xAC, 0xFC, 0x01, 0x23, 0x2B, 0x60, 0xEF, 0xF7, 0x2E, 0xFD, 0x31, 0xE7, 0x0A, 0xF1, 0x40, 0x00, 0x0F, 0xF0, -+0x67, 0xF9, 0x05, 0x4B, 0x1B, 0x68, 0x81, 0x46, 0x1B, 0x78, 0x00, 0xF1, 0x3C, 0x0B, 0xB5, 0xE6, 0x39, 0x46, 0xD6, 0xF8, -+0xB0, 0x72, 0x8C, 0xE7, 0x78, 0x36, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, -+0xA8, 0x56, 0x17, 0x00, 0x7C, 0x36, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xA0, 0x56, 0x17, 0x00, 0x54, 0x60, 0x17, 0x00, -+0x3C, 0x00, 0x00, 0xC0, 0x60, 0x65, 0x17, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0x3A, 0x00, 0x00, 0xA3, 0x4C, 0x11, 0x07, 0x40, -+0x00, 0x00, 0x07, 0x40, 0x48, 0x35, 0x17, 0x00, 0x54, 0x40, 0x04, 0x40, 0x00, 0x38, 0x18, 0x00, 0xB0, 0xDE, 0x17, 0x00, -+0x54, 0x65, 0x17, 0x00, 0xF1, 0xF7, 0x92, 0xFE, 0x83, 0x46, 0x00, 0x28, 0x3D, 0xD0, 0xDF, 0xF8, 0x38, 0xA1, 0x9A, 0xF8, -+0x20, 0x30, 0x00, 0x2B, 0x41, 0xD0, 0xDA, 0xF8, 0x04, 0x30, 0x81, 0x68, 0xDA, 0xF8, 0x00, 0x20, 0x03, 0xF1, 0x01, 0x0C, -+0x4F, 0xEA, 0x0C, 0x63, 0x21, 0xF0, 0xFE, 0x41, 0x03, 0xF0, 0xFE, 0x43, 0x0B, 0x43, 0x00, 0x21, 0x83, 0x60, 0x00, 0x91, -+0x3A, 0x23, 0x04, 0xF1, 0x30, 0x01, 0xCA, 0xF8, 0x04, 0xC0, 0xF2, 0xF7, 0xBF, 0xFE, 0x3C, 0x4A, 0xDA, 0xF8, 0x0C, 0x30, -+0x92, 0xF8, 0xB8, 0x20, 0x3A, 0x33, 0xCA, 0xF8, 0x0C, 0x30, 0x58, 0x46, 0x00, 0x2A, 0x63, 0xD1, 0xDA, 0xE9, 0x01, 0x12, -+0xF2, 0xF7, 0x4E, 0xFE, 0x35, 0x49, 0x0A, 0x78, 0x00, 0x23, 0x42, 0xF0, 0x01, 0x02, 0x0A, 0x70, 0xCA, 0xF8, 0x04, 0x30, -+0xCA, 0xF8, 0x0C, 0x30, 0xCA, 0xF8, 0x00, 0x30, 0xCA, 0xF8, 0x08, 0x30, 0x8A, 0xF8, 0x20, 0x30, 0x12, 0xE0, 0x23, 0x7C, -+0x2D, 0x48, 0x43, 0xF0, 0x01, 0x03, 0x23, 0x74, 0x0E, 0xF0, 0x00, 0xFE, 0x2B, 0x4B, 0x83, 0xF8, 0x20, 0xB0, 0x2B, 0x49, -+0x4F, 0xF4, 0x80, 0x60, 0x0E, 0xF0, 0x48, 0xFE, 0x23, 0x7C, 0x43, 0xF0, 0x01, 0x03, 0x23, 0x74, 0x27, 0x4B, 0x1B, 0x68, -+0x1B, 0x78, 0x02, 0x2B, 0x3F, 0xF4, 0x5D, 0xAE, 0x9A, 0xE6, 0x25, 0x49, 0x25, 0x48, 0x40, 0xF2, 0x21, 0x52, 0x0F, 0xF0, -+0x2F, 0xF8, 0x9C, 0xE6, 0x21, 0x49, 0x23, 0x48, 0x40, 0xF2, 0x23, 0x52, 0x0F, 0xF0, 0x28, 0xF8, 0x95, 0xE6, 0x23, 0x7C, -+0x20, 0x4E, 0x05, 0x99, 0x43, 0xF0, 0x01, 0x03, 0x23, 0x74, 0xD6, 0xF8, 0x98, 0x32, 0x20, 0x46, 0x98, 0x47, 0xEF, 0xF3, -+0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x1A, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x1A, 0x4C, 0xD6, 0xF8, 0x44, 0x24, -+0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x90, 0x47, 0x23, 0x68, 0x01, 0x46, 0x33, 0xB1, 0x14, 0x4A, 0x01, 0x3B, 0x12, 0x68, -+0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x12, 0x48, 0xF0, 0xF7, 0xEF, 0xFB, 0x6E, 0xE6, 0xFF, 0xF7, 0x3C, 0xFC, -+0x9C, 0xE7, 0x10, 0x4B, 0x00, 0x22, 0x5A, 0x61, 0x1E, 0xE7, 0x0F, 0x4A, 0xE8, 0xE6, 0x00, 0xBF, 0x2C, 0x19, 0x17, 0x00, -+0x9C, 0x4E, 0x17, 0x00, 0x0C, 0x97, 0x15, 0x00, 0x30, 0x65, 0x17, 0x00, 0x20, 0x97, 0x15, 0x00, 0x78, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x34, 0x97, 0x15, 0x00, 0x44, 0x97, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0xFC, 0x96, 0x15, 0x00, 0x48, 0x35, 0x17, 0x00, 0x60, 0x65, 0x17, 0x00, 0x0D, 0x4B, 0xC1, 0x69, -+0xD3, 0xF8, 0x98, 0x32, 0x10, 0xB5, 0x00, 0x22, 0x04, 0x46, 0x98, 0x47, 0x0A, 0x48, 0x03, 0x68, 0x53, 0xB1, 0x23, 0x7C, -+0x43, 0xF0, 0x01, 0x03, 0x00, 0x22, 0x23, 0x74, 0x62, 0x60, 0x21, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x0D, 0xF0, 0xA0, 0xBB, -+0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0x19, 0xBB, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x24, 0x65, 0x17, 0x00, -+0x0C, 0x4A, 0x0D, 0x49, 0x93, 0x68, 0x09, 0x68, 0x8B, 0x42, 0x11, 0xD0, 0x51, 0x68, 0x23, 0xF0, 0x00, 0x40, 0x09, 0x1A, -+0x9F, 0x29, 0x0C, 0xD8, 0x11, 0x68, 0x03, 0xF0, 0x00, 0x43, 0x88, 0x42, 0x88, 0xBF, 0x03, 0xF1, 0x00, 0x43, 0x0B, 0x43, -+0x93, 0x60, 0x23, 0xF0, 0x00, 0x40, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0xEC, 0x34, 0x17, 0x00, 0xD4, 0x81, 0x32, 0x40, -+0x1E, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x10, 0xB5, 0x04, 0x46, 0x21, 0xDB, 0x1B, 0x4B, 0x1B, 0x68, -+0x1B, 0x78, 0x9B, 0x07, 0x04, 0xD5, 0x63, 0x6D, 0x03, 0xF0, 0x3C, 0x03, 0x3C, 0x2B, 0x25, 0xD0, 0x23, 0x8E, 0x53, 0xB1, -+0x62, 0x6D, 0x02, 0xF0, 0x7C, 0x02, 0x08, 0x2A, 0x0D, 0xD0, 0x0C, 0x2A, 0x19, 0xD0, 0x04, 0x2A, 0x09, 0xD0, 0x04, 0x3B, -+0x23, 0x86, 0x00, 0x23, 0x10, 0x4A, 0x23, 0x74, 0x84, 0xF8, 0x9C, 0x30, 0xE4, 0x60, 0x62, 0x60, 0x10, 0xBD, 0x08, 0x3B, -+0x23, 0x86, 0xF4, 0xE7, 0x0C, 0x4B, 0x42, 0x69, 0x9A, 0x42, 0xD9, 0xD0, 0x0B, 0x49, 0x0C, 0x48, 0x40, 0xF2, 0x14, 0x62, -+0x0E, 0xF0, 0x98, 0xFF, 0xD2, 0xE7, 0x0C, 0x3B, 0x23, 0x86, 0xE6, 0xE7, 0x23, 0x8E, 0x04, 0x3B, 0x9B, 0xB2, 0x23, 0x86, -+0xD5, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x34, 0x36, 0x17, 0x00, 0x3D, 0x48, 0x13, 0x00, 0x0D, 0xF0, 0xAD, 0xBA, -+0x70, 0x79, 0x15, 0x00, 0x64, 0x97, 0x15, 0x00, 0x06, 0x4B, 0x07, 0x4A, 0x4F, 0xF4, 0x80, 0x31, 0x19, 0x60, 0x13, 0x68, -+0x23, 0xF4, 0x80, 0x33, 0x13, 0x60, 0x4F, 0xF4, 0x80, 0x10, 0x0D, 0xF0, 0x7F, 0xBA, 0x00, 0xBF, 0x7C, 0x80, 0x32, 0x40, -+0x80, 0x80, 0x32, 0x40, 0x2D, 0xE9, 0xF0, 0x47, 0x21, 0x4D, 0x22, 0x4E, 0x6B, 0x69, 0x32, 0x68, 0x93, 0x42, 0x84, 0xB0, -+0x38, 0xD0, 0xDF, 0xF8, 0x88, 0x80, 0x1F, 0x4F, 0xDF, 0xF8, 0x84, 0x90, 0x20, 0xE0, 0x6B, 0x69, 0x1D, 0x48, 0x23, 0xF0, -+0x00, 0x44, 0x21, 0x46, 0x62, 0x69, 0xBA, 0x42, 0x0A, 0xD0, 0xD6, 0xF8, 0x00, 0xE0, 0xD9, 0xF8, 0x00, 0xA0, 0xCD, 0xE9, -+0x00, 0xC3, 0xCD, 0xE9, 0x02, 0xEA, 0xEB, 0x68, 0x0E, 0xF0, 0xD4, 0xFC, 0x20, 0x46, 0xFF, 0xF7, 0x7F, 0xFF, 0x01, 0x23, -+0x84, 0xF8, 0x9C, 0x30, 0xD8, 0xF8, 0xC0, 0x32, 0x20, 0x46, 0x98, 0x47, 0x6B, 0x69, 0x32, 0x68, 0x93, 0x42, 0x11, 0xD0, -+0xD5, 0xF8, 0x10, 0xC0, 0x23, 0xF0, 0x00, 0x41, 0xAC, 0xEB, 0x01, 0x02, 0x9F, 0x2A, 0x03, 0xF0, 0x00, 0x43, 0xD4, 0xD8, -+0xEA, 0x68, 0x91, 0x42, 0x88, 0xBF, 0x03, 0xF1, 0x00, 0x43, 0x13, 0x43, 0x6B, 0x61, 0xCD, 0xE7, 0x04, 0xB0, 0xBD, 0xE8, -+0xF0, 0x87, 0x00, 0xBF, 0xEC, 0x34, 0x17, 0x00, 0xE4, 0x81, 0x32, 0x40, 0x0D, 0xF0, 0xAD, 0xBA, 0x90, 0x97, 0x15, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0xE0, 0x81, 0x32, 0x40, 0x00, 0xB5, 0x10, 0x4A, 0x10, 0x4B, 0x12, 0x68, 0x89, 0xB0, 0x08, 0x33, -+0x03, 0x92, 0x53, 0xF8, 0x08, 0x2C, 0x04, 0x92, 0x53, 0xF8, 0x04, 0x2C, 0x05, 0x92, 0x1B, 0x68, 0x06, 0x93, 0x01, 0xA8, -+0x00, 0x21, 0xEB, 0xF7, 0x73, 0xFA, 0x03, 0x9B, 0x03, 0xF0, 0x0F, 0x03, 0x02, 0x2B, 0x02, 0xD0, 0x09, 0xB0, 0x5D, 0xF8, -+0x04, 0xFB, 0x01, 0xA8, 0x0E, 0xF0, 0x8C, 0xFF, 0x09, 0xB0, 0x5D, 0xF8, 0x04, 0xFB, 0x00, 0xBF, 0xB0, 0x10, 0x34, 0x40, -+0xB4, 0x10, 0x34, 0x40, 0x38, 0xB5, 0xD0, 0xF8, 0xFC, 0x31, 0x04, 0x46, 0x00, 0xF5, 0xFE, 0x75, 0x4B, 0xB1, 0x28, 0x46, -+0x0D, 0xF0, 0xDE, 0xFA, 0x01, 0x21, 0xFA, 0xF7, 0x2B, 0xF9, 0xD4, 0xF8, 0xFC, 0x31, 0x00, 0x2B, 0xF5, 0xD1, 0x4F, 0xF4, -+0x1E, 0x72, 0x00, 0x21, 0x20, 0x46, 0xEA, 0xF7, 0xF9, 0xF9, 0x23, 0x46, 0x04, 0xF1, 0x48, 0x01, 0x21, 0x22, 0x83, 0xF8, -+0xA4, 0x21, 0x83, 0xF8, 0xA5, 0x21, 0x08, 0x33, 0x8B, 0x42, 0xF8, 0xD1, 0xFF, 0x23, 0x84, 0xF8, 0x22, 0x30, 0x38, 0xBD, -+0x2D, 0xE9, 0xF0, 0x43, 0x49, 0x48, 0x4A, 0x4F, 0x83, 0xB0, 0x81, 0x46, 0x0D, 0xF0, 0x72, 0xFA, 0x07, 0xF5, 0x0C, 0x75, -+0x00, 0x26, 0x40, 0xF2, 0x16, 0x38, 0xA5, 0xF5, 0x0C, 0x71, 0x08, 0x46, 0x01, 0x91, 0xFF, 0xF7, 0xC7, 0xFF, 0x01, 0x99, -+0x48, 0x46, 0x0D, 0xF0, 0x67, 0xFA, 0xA5, 0xF1, 0x28, 0x04, 0x20, 0x46, 0x0D, 0xF0, 0x5E, 0xFA, 0x04, 0xF1, 0x28, 0x00, -+0x08, 0x34, 0x0D, 0xF0, 0x59, 0xFA, 0xAC, 0x42, 0xF5, 0xD1, 0x4F, 0x36, 0x46, 0x45, 0x04, 0xF5, 0x1E, 0x75, 0xE4, 0xD1, -+0x38, 0x4D, 0x40, 0xF2, 0x52, 0x48, 0xA5, 0xF1, 0x28, 0x04, 0x20, 0x46, 0x0D, 0xF0, 0x4A, 0xFA, 0x04, 0xF1, 0x28, 0x00, -+0x08, 0x34, 0x0D, 0xF0, 0x45, 0xFA, 0xAC, 0x42, 0xF5, 0xD1, 0x4F, 0x36, 0x46, 0x45, 0x04, 0xF5, 0x1E, 0x75, 0xEE, 0xD1, -+0x2F, 0x48, 0x30, 0x4D, 0x30, 0x4C, 0x00, 0xF1, 0x30, 0x06, 0xFF, 0xF7, 0x97, 0xFF, 0x41, 0xF6, 0xF8, 0x12, 0x4F, 0xF0, -+0x00, 0x08, 0x41, 0xF6, 0x64, 0x11, 0x41, 0xF6, 0xD0, 0x03, 0xBD, 0x50, 0x06, 0xF5, 0x12, 0x70, 0x86, 0xF8, 0x00, 0x80, -+0x4F, 0xF0, 0x20, 0x62, 0x7C, 0x50, 0xFA, 0x50, 0xFF, 0xF7, 0x84, 0xFF, 0x41, 0xF6, 0x58, 0x30, 0x41, 0xF6, 0x70, 0x41, -+0x07, 0xF8, 0x00, 0x80, 0x41, 0xF6, 0xDC, 0x32, 0x05, 0xF1, 0x40, 0x00, 0x78, 0x50, 0x41, 0xF6, 0x48, 0x33, 0x04, 0xF5, -+0xA4, 0x61, 0xB9, 0x50, 0x06, 0xF5, 0x98, 0x60, 0x1C, 0x4A, 0xFA, 0x50, 0xFF, 0xF7, 0x6E, 0xFF, 0x41, 0xF6, 0xD0, 0x52, -+0x41, 0xF6, 0xE8, 0x61, 0x41, 0xF6, 0x54, 0x63, 0x18, 0x48, 0x07, 0xF8, 0x02, 0x80, 0xC6, 0xF8, 0xE0, 0x04, 0x04, 0xF5, -+0x24, 0x62, 0x06, 0xF5, 0xE7, 0x60, 0x05, 0xF1, 0x80, 0x06, 0x7E, 0x50, 0xFA, 0x50, 0xFF, 0xF7, 0x59, 0xFF, 0x42, 0xF2, -+0x60, 0x16, 0x11, 0x4A, 0x42, 0xF2, 0xCC, 0x00, 0x42, 0xF2, 0x48, 0x01, 0x42, 0xF2, 0x38, 0x03, 0xC0, 0x35, 0x04, 0xF5, -+0x76, 0x64, 0xBD, 0x51, 0x3C, 0x50, 0x07, 0xF8, 0x01, 0x80, 0xFA, 0x50, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x00, 0xBF, -+0xF8, 0x87, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x48, 0x80, 0x17, 0x00, 0x18, 0x7E, 0x17, 0x00, 0x04, 0x38, 0x18, 0x00, -+0xC0, 0x8C, 0x17, 0x00, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x00, 0x02, 0x0C, 0x00, 0x00, 0x03, 0x0D, 0x2D, 0xE9, 0xF0, 0x41, -+0x05, 0x46, 0x79, 0x48, 0x95, 0xF8, 0x19, 0x80, 0x0E, 0x46, 0x0D, 0xF0, 0x11, 0xFA, 0x00, 0x28, 0x00, 0xF0, 0xE1, 0x80, -+0x6B, 0x7F, 0x04, 0x46, 0x00, 0x2B, 0x40, 0xF0, 0xA5, 0x80, 0x73, 0x4F, 0x05, 0xF1, 0x12, 0x02, 0x11, 0x68, 0x2B, 0x68, -+0x92, 0x88, 0x62, 0x85, 0xC4, 0xF8, 0x26, 0x10, 0x63, 0x60, 0x28, 0x7E, 0x6E, 0x4B, 0x6F, 0x4A, 0x6F, 0x49, 0x10, 0x28, -+0x38, 0xBF, 0x10, 0x20, 0x20, 0x77, 0x28, 0x8A, 0xA0, 0x82, 0xA8, 0x68, 0x20, 0x61, 0x68, 0x68, 0xE0, 0x60, 0xE8, 0x68, -+0xA0, 0x61, 0xE0, 0x1B, 0xC0, 0x10, 0x03, 0xFB, 0x00, 0xF3, 0xDB, 0xB2, 0x68, 0x7E, 0x84, 0xF8, 0x22, 0x00, 0x33, 0x70, -+0x4F, 0xF4, 0x80, 0x70, 0x84, 0xF8, 0x23, 0x30, 0x0E, 0xF0, 0xC6, 0xFB, 0x62, 0x48, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, -+0x08, 0x03, 0x4F, 0xF4, 0xC8, 0x31, 0x93, 0xF8, 0xC0, 0x24, 0xA1, 0x60, 0x22, 0xB1, 0x93, 0xF8, 0xC2, 0x24, 0x01, 0x32, -+0x83, 0xF8, 0xC2, 0x24, 0x4F, 0xF6, 0xFF, 0x71, 0xA4, 0xF8, 0xE8, 0x11, 0x04, 0xF5, 0xF4, 0x72, 0x23, 0x46, 0x04, 0xF5, -+0xFD, 0x75, 0x22, 0xF8, 0x02, 0x1F, 0xAA, 0x42, 0xFB, 0xD1, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x08, 0xF8, 0x00, 0xEB, -+0x08, 0x05, 0x00, 0x22, 0x31, 0x78, 0x84, 0xF8, 0x30, 0x20, 0xD5, 0xF8, 0xB0, 0x54, 0x4F, 0x4A, 0x02, 0xEB, 0x81, 0x12, -+0x29, 0x07, 0xC4, 0xF8, 0x48, 0x21, 0x4D, 0x49, 0x56, 0xBF, 0x08, 0xF5, 0x95, 0x62, 0x04, 0xF1, 0xB0, 0x02, 0x12, 0x18, -+0xC4, 0xF8, 0xB4, 0x20, 0x0A, 0x69, 0xA2, 0xF5, 0x74, 0x22, 0xA2, 0xF5, 0x10, 0x72, 0x04, 0xF1, 0x48, 0x01, 0xC3, 0xF8, -+0xA0, 0x21, 0x08, 0x33, 0x8B, 0x42, 0xFA, 0xD1, 0xEA, 0x06, 0x03, 0xD5, 0x63, 0x68, 0x43, 0xF0, 0x08, 0x03, 0x63, 0x60, -+0x08, 0xF1, 0xE4, 0x08, 0x40, 0x44, 0x21, 0x46, 0x0D, 0xF0, 0x4C, 0xF9, 0x3D, 0x4B, 0xC4, 0xF8, 0x04, 0x32, 0xEF, 0xF3, -+0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x3A, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x3A, 0x4B, 0xE0, 0x6A, 0x1A, 0x68, -+0x01, 0x25, 0x51, 0x19, 0x19, 0x60, 0x84, 0xF8, 0x25, 0x50, 0x08, 0xB1, 0x80, 0xF8, 0x25, 0x50, 0x21, 0xB1, 0x33, 0x49, -+0x1A, 0x60, 0x0B, 0x68, 0x00, 0x2A, 0x42, 0xD0, 0xF6, 0xB2, 0x0D, 0x2E, 0x07, 0xD8, 0x4F, 0xF4, 0x1E, 0x73, 0x2C, 0x4A, -+0x06, 0xFB, 0x03, 0x76, 0x13, 0x69, 0xC6, 0xF8, 0x58, 0x32, 0x00, 0x20, 0x84, 0xF8, 0x5C, 0x02, 0xBD, 0xE8, 0xF0, 0x81, -+0x1F, 0x48, 0x0D, 0xF0, 0x61, 0xF9, 0x00, 0x28, 0x34, 0xD0, 0x2A, 0x46, 0xE0, 0x62, 0xC4, 0x62, 0xA9, 0x7F, 0x52, 0xF8, -+0x12, 0x3F, 0x95, 0xF8, 0x1D, 0xC0, 0xC0, 0xF8, 0x26, 0x30, 0x01, 0x23, 0x8B, 0x40, 0x91, 0x88, 0x41, 0x85, 0x01, 0x3B, -+0x41, 0x8D, 0x16, 0x4F, 0x1B, 0x02, 0x1B, 0xB2, 0x21, 0xEA, 0x03, 0x01, 0x09, 0xB2, 0x41, 0x85, 0xB5, 0xF8, 0x16, 0xE0, -+0xAE, 0xEB, 0x0C, 0x2C, 0x03, 0xEA, 0x0C, 0x03, 0xA0, 0xEB, 0x07, 0x0E, 0xDF, 0xF8, 0x3C, 0xC0, 0x4F, 0xEA, 0xEE, 0x0E, -+0x0B, 0x43, 0x0C, 0xFB, 0x0E, 0xF1, 0x4F, 0xF0, 0xFF, 0x0C, 0x43, 0x85, 0x80, 0xF8, 0x23, 0x10, 0xA0, 0xF8, 0x20, 0xC0, -+0x2A, 0xE7, 0x00, 0x2B, 0xBA, 0xD0, 0x62, 0xB6, 0xB8, 0xE7, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x48, 0x21, 0x46, -+0x0D, 0xF0, 0xE2, 0xF8, 0x01, 0x20, 0xBD, 0xE7, 0xF8, 0x87, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0xAF, 0x16, 0x37, 0x61, -+0xEC, 0x97, 0x15, 0x00, 0xDC, 0x97, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, 0x04, 0x39, 0x18, 0x00, 0x00, 0x10, 0x50, 0x40, -+0x0F, 0xCC, 0xFF, 0xFF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x33, 0x4F, 0xDF, 0xF8, -+0xE4, 0x80, 0x4F, 0xF4, 0x1E, 0x74, 0x04, 0xFB, 0x00, 0x74, 0x4F, 0xF4, 0xA4, 0x63, 0x94, 0xF8, 0x22, 0x60, 0x03, 0xFB, -+0x06, 0x83, 0x05, 0x46, 0x93, 0xF8, 0xC0, 0x24, 0x22, 0xB1, 0x93, 0xF8, 0xC2, 0x24, 0x01, 0x3A, 0x83, 0xF8, 0xC2, 0x24, -+0x29, 0x4A, 0x2A, 0x49, 0x2B, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0x0E, 0xF0, 0xD5, 0xFA, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, -+0x06, 0x80, 0xE4, 0x30, 0x21, 0x46, 0x0D, 0xF0, 0xF3, 0xF8, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x21, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x21, 0x4A, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x05, 0x73, 0x11, 0x68, 0xD8, 0x6A, -+0x4E, 0x1C, 0x4F, 0xF0, 0x00, 0x0C, 0x16, 0x60, 0x83, 0xF8, 0x25, 0xC0, 0xD8, 0xB1, 0x80, 0xF8, 0x25, 0xC0, 0x96, 0xB9, -+0xFF, 0xF7, 0xE4, 0xFD, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x05, 0x75, 0x16, 0x48, 0xE9, 0x6A, 0x0D, 0xF0, 0x80, 0xF8, -+0x20, 0x46, 0xFF, 0xF7, 0xD9, 0xFD, 0x21, 0x46, 0x12, 0x48, 0xBD, 0xE8, 0xF0, 0x41, 0x0D, 0xF0, 0x77, 0xB8, 0x0E, 0x48, -+0x11, 0x60, 0x02, 0x68, 0x41, 0xB1, 0xD8, 0x6A, 0xE6, 0xE7, 0x00, 0x2E, 0xEE, 0xD0, 0x0A, 0x4B, 0x11, 0x60, 0x1A, 0x68, -+0x00, 0x29, 0xE9, 0xD1, 0x02, 0xB1, 0x62, 0xB6, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x05, 0x73, 0xD8, 0x6A, 0x00, 0x28, -+0xE0, 0xD0, 0xD5, 0xE7, 0x68, 0x65, 0x17, 0x00, 0x00, 0x98, 0x15, 0x00, 0xDC, 0x97, 0x15, 0x00, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0xF8, 0x87, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x44, 0x78, 0xDF, 0xF8, -+0x14, 0x81, 0x4F, 0xF4, 0x1E, 0x76, 0x06, 0xFB, 0x04, 0xF6, 0x08, 0xEB, 0x06, 0x07, 0x38, 0x36, 0x87, 0xF8, 0x9A, 0x10, -+0x90, 0xF8, 0x28, 0x30, 0x87, 0xF8, 0x98, 0x30, 0x03, 0x78, 0x87, 0xF8, 0x99, 0x30, 0x46, 0x44, 0x05, 0x46, 0x48, 0x22, -+0x30, 0x46, 0x00, 0x21, 0x97, 0xF8, 0x22, 0x90, 0xE9, 0xF7, 0xA0, 0xFF, 0x97, 0xF8, 0x98, 0x30, 0x04, 0x2B, 0x55, 0xD8, -+0xDF, 0xE8, 0x03, 0xF0, 0x03, 0x3F, 0x54, 0x03, 0x27, 0x00, 0x21, 0xF0, 0x29, 0xF8, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, -+0x04, 0x83, 0x03, 0xF1, 0x80, 0x02, 0x20, 0xF0, 0x7F, 0x40, 0xC3, 0xF8, 0x80, 0x00, 0x00, 0x23, 0x53, 0x60, 0x4F, 0xF4, -+0x1E, 0x73, 0x03, 0xFB, 0x04, 0x83, 0x01, 0x22, 0xD5, 0xE9, 0x02, 0x40, 0x29, 0x69, 0x83, 0xF8, 0x9B, 0x20, 0x6A, 0x69, -+0xC3, 0xF8, 0xB0, 0x60, 0xC3, 0xE9, 0x27, 0x40, 0xC3, 0xE9, 0x29, 0x12, 0x2A, 0x79, 0x83, 0xF8, 0xAC, 0x20, 0xBD, 0xE8, -+0xF8, 0x83, 0x20, 0x4B, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x09, 0x39, 0x19, 0xA3, 0xD3, 0xE9, 0x00, 0x23, 0x99, 0xF8, -+0x62, 0x00, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x04, 0x81, 0x02, 0x28, 0xC1, 0xE9, 0x20, 0x23, 0xD7, 0xD1, 0x15, 0xA3, -+0xD3, 0xE9, 0x00, 0x23, 0xC1, 0xE9, 0x20, 0x23, 0xD1, 0xE7, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x04, 0x83, 0xAA, 0x69, -+0xC3, 0xF8, 0x88, 0x20, 0xEA, 0x69, 0xC3, 0xF8, 0x8C, 0x20, 0x2A, 0x6A, 0xC3, 0xF8, 0x90, 0x20, 0x00, 0x20, 0x6A, 0x6A, -+0xC3, 0xF8, 0x94, 0x20, 0x00, 0x21, 0xC3, 0xE9, 0x20, 0x01, 0xBC, 0xE7, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x04, 0x83, -+0x00, 0x20, 0x00, 0x21, 0xC3, 0xE9, 0x20, 0x01, 0xB3, 0xE7, 0x00, 0xBF, 0xAF, 0xF3, 0x00, 0x80, 0x36, 0x5C, 0x36, 0x5C, -+0x36, 0x5C, 0x36, 0x5C, 0x37, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x18, 0x88, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x00, 0x23, 0x01, 0x22, 0x80, 0xF8, 0x30, 0x20, 0x80, 0xF8, 0x9B, 0x30, 0xC0, 0xF8, 0xB0, 0x30, 0x70, 0x47, 0x00, 0xBF, -+0x2D, 0xE9, 0xF0, 0x47, 0xD1, 0xF8, 0xFC, 0xA1, 0x82, 0xB0, 0xBA, 0xF1, 0x00, 0x0F, 0x32, 0xD0, 0x00, 0x24, 0xDF, 0xF8, -+0x6C, 0x80, 0x0D, 0x46, 0x06, 0x46, 0x91, 0x46, 0x27, 0x46, 0x10, 0xE0, 0x80, 0xF8, 0x5D, 0x70, 0xD8, 0xF8, 0x98, 0x33, -+0xC1, 0x7E, 0x01, 0x34, 0x98, 0x47, 0xB9, 0xF1, 0x00, 0x0F, 0x01, 0xD0, 0x4C, 0x45, 0x1F, 0xD0, 0xD5, 0xF8, 0xFC, 0xA1, -+0xBA, 0xF1, 0x00, 0x0F, 0x1A, 0xD0, 0x30, 0x46, 0x01, 0x97, 0xF8, 0xF7, 0x6B, 0xFA, 0x03, 0x46, 0x50, 0x46, 0x9B, 0xB1, -+0x15, 0xF0, 0x34, 0xFC, 0x03, 0x46, 0x01, 0xAA, 0x29, 0x46, 0x30, 0x46, 0x63, 0xB1, 0xD8, 0xF8, 0x10, 0x30, 0x98, 0x47, -+0x01, 0x9B, 0x3B, 0xB9, 0x00, 0x28, 0xD9, 0xD1, 0x05, 0xF5, 0xFE, 0x70, 0x0C, 0xF0, 0xC2, 0xFF, 0xD4, 0xE7, 0x54, 0x46, -+0x20, 0x46, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x88, 0x1A, 0x17, 0x00, 0x0A, 0x4B, 0x9B, 0x68, 0x93, 0xF8, 0x62, 0x20, -+0x7A, 0xB9, 0x93, 0xF8, 0x64, 0x20, 0x62, 0xB1, 0x93, 0xF8, 0x6D, 0x20, 0x4A, 0xB1, 0x93, 0xF8, 0x6E, 0x20, 0x08, 0x2A, -+0x05, 0xD8, 0x01, 0x23, 0x93, 0x40, 0x01, 0x3B, 0x02, 0x4A, 0x1B, 0x02, 0x13, 0x60, 0x70, 0x47, 0x00, 0x88, 0x17, 0x00, -+0x2C, 0x00, 0x32, 0x40, 0x10, 0xB5, 0x90, 0xF8, 0xC0, 0x34, 0x04, 0x46, 0x00, 0x2B, 0x2D, 0xD1, 0x23, 0x6C, 0x1B, 0xB1, -+0x1B, 0x4B, 0x20, 0x46, 0x1B, 0x6B, 0x98, 0x47, 0x63, 0x68, 0xD8, 0x07, 0x1A, 0xD5, 0x19, 0x4A, 0x11, 0x68, 0x89, 0x01, -+0x17, 0xD5, 0x23, 0xF0, 0x01, 0x03, 0x63, 0x60, 0x16, 0x4A, 0x41, 0xF2, 0x14, 0x33, 0xD3, 0x5C, 0x01, 0x2B, 0x41, 0xF2, -+0x13, 0x33, 0x8C, 0xBF, 0x01, 0x21, 0x00, 0x21, 0xD1, 0x54, 0x12, 0x4B, 0x93, 0xF8, 0xB6, 0x30, 0x23, 0xB1, 0x11, 0x4B, -+0x1B, 0x68, 0x1B, 0x78, 0x02, 0x2B, 0x0C, 0xD0, 0x10, 0xBD, 0x12, 0x68, 0x92, 0x01, 0xFB, 0xD4, 0x0D, 0x4A, 0x92, 0xF8, -+0x24, 0x20, 0x00, 0x2A, 0xF6, 0xD0, 0xDE, 0xE7, 0x0A, 0xF0, 0x34, 0xF8, 0xCE, 0xE7, 0xF8, 0xF7, 0x1D, 0xFD, 0x09, 0x4A, -+0x13, 0x68, 0x23, 0xF0, 0x01, 0x03, 0x13, 0x60, 0x10, 0xBD, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, -+0x00, 0x40, 0x1E, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x74, 0x36, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, 0x8C, 0x00, 0x32, 0x40, -+0x19, 0x48, 0x2D, 0xE9, 0xF0, 0x41, 0x18, 0x22, 0x80, 0x46, 0x00, 0x21, 0xE9, 0xF7, 0x72, 0xFE, 0x40, 0x46, 0x0C, 0xF0, -+0xFF, 0xFE, 0x08, 0xF1, 0x08, 0x00, 0x14, 0x4C, 0x14, 0x4F, 0x0C, 0xF0, 0xF9, 0xFE, 0x04, 0xF5, 0xA4, 0x56, 0x45, 0x46, -+0x4F, 0xF4, 0xA4, 0x62, 0x00, 0x21, 0x20, 0x46, 0xE9, 0xF7, 0x60, 0xFE, 0x7F, 0x23, 0xD7, 0xF8, 0x50, 0x24, 0x24, 0x63, -+0x05, 0x21, 0x84, 0xF8, 0x62, 0x10, 0x84, 0xF8, 0x65, 0x30, 0x84, 0xF8, 0x66, 0x30, 0xE2, 0x62, 0x21, 0x46, 0x28, 0x46, -+0x04, 0xF5, 0xA4, 0x64, 0x0C, 0xF0, 0xE2, 0xFE, 0xB4, 0x42, 0xE5, 0xD1, 0xFF, 0x23, 0x88, 0xF8, 0x10, 0x30, 0xBD, 0xE8, -+0xF0, 0x81, 0x00, 0xBF, 0x00, 0x88, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0xB5, 0x06, 0x4B, -+0x9C, 0x68, 0x3C, 0xB1, 0x05, 0x4D, 0xD5, 0xF8, 0x5C, 0x34, 0x20, 0x46, 0x98, 0x47, 0x24, 0x68, 0x00, 0x2C, 0xF8, 0xD1, -+0x38, 0xBD, 0x00, 0xBF, 0x00, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xAC, 0x4D, 0x8D, 0xB0, -+0x2C, 0x68, 0x05, 0x90, 0x88, 0x46, 0x17, 0x46, 0x04, 0x93, 0x00, 0x2C, 0x00, 0xF0, 0xA4, 0x80, 0x00, 0x2A, 0x40, 0xF0, -+0x9E, 0x80, 0xAC, 0x68, 0x00, 0x2C, 0x00, 0xF0, 0x42, 0x81, 0x05, 0x9B, 0xA4, 0x48, 0x1A, 0x68, 0x9B, 0x88, 0x06, 0x92, -+0x4F, 0xF0, 0x00, 0x09, 0x07, 0x93, 0xCB, 0x46, 0xBA, 0x46, 0xE7, 0x6D, 0xB4, 0xF8, 0x60, 0x60, 0x94, 0xF8, 0xC0, 0x34, -+0x39, 0x46, 0x32, 0x46, 0x0E, 0xF0, 0x76, 0xF8, 0x94, 0xF8, 0xC0, 0x34, 0x9A, 0x48, 0x1B, 0xB9, 0x8B, 0xEA, 0x07, 0x0B, -+0x89, 0xEA, 0x06, 0x09, 0x24, 0x68, 0x00, 0x2C, 0xEB, 0xD1, 0x57, 0x46, 0x00, 0x2F, 0x00, 0xF0, 0x99, 0x80, 0x95, 0x4B, -+0x95, 0x48, 0x49, 0xF4, 0x40, 0x74, 0xDD, 0xE9, 0x06, 0x12, 0x1C, 0x60, 0xC0, 0xF8, 0x00, 0xB0, 0x5B, 0x46, 0xCD, 0xE9, -+0x00, 0x97, 0x91, 0x48, 0x0E, 0xF0, 0x58, 0xF8, 0x8B, 0x48, 0x0C, 0xF0, 0xBF, 0xFE, 0x05, 0x99, 0x8E, 0x4A, 0x80, 0xF8, -+0x62, 0x80, 0x04, 0x46, 0x8D, 0x4B, 0x82, 0x1A, 0x08, 0x68, 0xE0, 0x65, 0x52, 0x11, 0x89, 0x88, 0xA4, 0xF8, 0x60, 0x10, -+0x03, 0xFB, 0x02, 0xF2, 0xD3, 0xB2, 0x40, 0xF6, 0x47, 0x21, 0x40, 0xF6, 0x43, 0x22, 0xA1, 0x60, 0xE2, 0x60, 0x86, 0x49, -+0x86, 0x4A, 0x21, 0x61, 0x62, 0x61, 0x40, 0xF2, 0xFF, 0x31, 0x00, 0x22, 0x84, 0xF8, 0xC0, 0x74, 0xA4, 0xF8, 0xBE, 0x14, -+0x84, 0xF8, 0x63, 0x30, 0x84, 0xF8, 0x4C, 0x30, 0x22, 0x64, 0x84, 0xF8, 0x84, 0x20, 0x17, 0xB1, 0xEA, 0x7C, 0x01, 0x32, -+0xEA, 0x74, 0xB8, 0xF1, 0x02, 0x0F, 0x00, 0xF0, 0x89, 0x80, 0xB8, 0xF1, 0x04, 0x0F, 0x00, 0xF0, 0xC3, 0x80, 0xB8, 0xF1, -+0x00, 0x0F, 0x00, 0xF0, 0x9C, 0x80, 0x6B, 0x7C, 0xAA, 0x7C, 0x13, 0x44, 0x01, 0x2B, 0x78, 0xDD, 0x74, 0x48, 0x75, 0x4E, -+0xD0, 0xE9, 0x00, 0x12, 0x42, 0xF4, 0x80, 0x72, 0x11, 0x43, 0x42, 0x60, 0x31, 0x60, 0x01, 0x2B, 0x4D, 0xD0, 0x00, 0x2F, -+0x52, 0xD1, 0x04, 0x9A, 0x94, 0xF8, 0x63, 0x30, 0x6E, 0x48, 0x13, 0x70, 0x21, 0x46, 0x0C, 0xF0, 0x29, 0xFE, 0x04, 0xF5, -+0x99, 0x66, 0x04, 0xF5, 0x9E, 0x69, 0x30, 0x46, 0x0C, 0xF0, 0x1E, 0xFE, 0x06, 0xF1, 0x28, 0x00, 0x08, 0x36, 0x0C, 0xF0, -+0x19, 0xFE, 0x4E, 0x45, 0xF5, 0xD1, 0x04, 0xF5, 0xA3, 0x60, 0x0C, 0xF0, 0x13, 0xFE, 0x00, 0x24, 0x03, 0xE0, 0x63, 0x4B, -+0x1B, 0x78, 0x23, 0xB3, 0x01, 0x24, 0xAA, 0x7C, 0x6B, 0x7C, 0x61, 0x49, 0x13, 0x44, 0x00, 0x20, 0x01, 0x2B, 0x08, 0x60, -+0x04, 0xDC, 0xFF, 0xF7, 0x91, 0xFE, 0xAA, 0x7C, 0x6B, 0x7C, 0x13, 0x44, 0x04, 0x99, 0x09, 0x78, 0x4F, 0xF4, 0x80, 0x70, -+0xCD, 0xE9, 0x02, 0x71, 0xCD, 0xE9, 0x00, 0x28, 0x58, 0x49, 0x59, 0x4A, 0x0E, 0xF0, 0x22, 0xF8, 0x20, 0x46, 0x0D, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0x06, 0x9B, 0x8B, 0xEA, 0x03, 0x0B, 0x07, 0x9B, 0x89, 0xEA, 0x03, 0x09, 0x5F, 0xE7, 0xAC, 0x68, -+0x00, 0x2C, 0x7C, 0xD0, 0xEB, 0x7C, 0x02, 0x2B, 0x7F, 0xF4, 0x37, 0xAF, 0xD2, 0xE7, 0x4F, 0x4A, 0x13, 0x68, 0x43, 0xF0, -+0x01, 0x03, 0x13, 0x60, 0x00, 0x2F, 0xAC, 0xD0, 0xB8, 0xF1, 0x00, 0x01, 0x18, 0xBF, 0x01, 0x21, 0x94, 0xF8, 0x63, 0x00, -+0x09, 0xF0, 0x22, 0xFD, 0x48, 0x4B, 0x84, 0xF8, 0xC1, 0x04, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x9C, 0xDA, -+0xFF, 0x28, 0x9A, 0xD1, 0x44, 0x49, 0x45, 0x48, 0x40, 0xF2, 0x0B, 0x22, 0x0E, 0xF0, 0x1A, 0xFA, 0x93, 0xE7, 0x00, 0x2A, -+0x8D, 0xD0, 0x83, 0xE7, 0xAA, 0x7C, 0x00, 0x2A, 0x00, 0xF0, 0xA8, 0x80, 0x39, 0x46, 0x3F, 0x48, 0x0A, 0x33, 0x4F, 0xF4, -+0x1E, 0x76, 0x06, 0xFB, 0x03, 0x03, 0x01, 0x32, 0x01, 0x20, 0xAA, 0x74, 0x83, 0xF8, 0x25, 0x00, 0x11, 0xB1, 0x3A, 0x4B, -+0xC4, 0xE9, 0x07, 0x34, 0x39, 0x4B, 0x20, 0x46, 0xD3, 0xF8, 0x80, 0x31, 0x98, 0x47, 0x6B, 0x7C, 0x64, 0xE7, 0x36, 0x4B, -+0x36, 0x49, 0xD3, 0xF8, 0xCC, 0x31, 0xE3, 0x61, 0xFF, 0x23, 0x84, 0xF8, 0x6C, 0x30, 0x34, 0x4A, 0x6B, 0x7C, 0x24, 0x62, -+0xA4, 0xF8, 0x8A, 0x80, 0xC4, 0xF8, 0xB8, 0x40, 0xC4, 0xF8, 0xB4, 0x10, 0x01, 0x33, 0x92, 0xF8, 0x04, 0x21, 0xDB, 0xB2, -+0x6B, 0x74, 0x00, 0x2A, 0x3F, 0xF4, 0x4C, 0xAF, 0x2C, 0x4A, 0xC4, 0xF8, 0xA4, 0x40, 0xC4, 0xE9, 0x24, 0x88, 0xC4, 0xF8, -+0x98, 0x80, 0xC4, 0xF8, 0xA0, 0x20, 0x41, 0xE7, 0x2A, 0x7C, 0xFF, 0x2A, 0x17, 0xD1, 0xAA, 0x68, 0x2B, 0x74, 0x00, 0x2A, -+0x4C, 0xD0, 0x14, 0x49, 0x24, 0x4B, 0x4E, 0x68, 0x12, 0x6C, 0x13, 0x48, 0x0B, 0x60, 0x33, 0x43, 0x03, 0x60, 0x00, 0x2A, -+0x3F, 0xF4, 0x2F, 0xAF, 0x1B, 0x4B, 0x10, 0x7E, 0x1B, 0x6D, 0x98, 0x47, 0x29, 0xE7, 0x05, 0x98, 0x01, 0xF0, 0x4E, 0xFE, -+0xEA, 0xE6, 0x01, 0x24, 0x6E, 0xE7, 0x00, 0xBF, 0x00, 0x88, 0x17, 0x00, 0x14, 0x98, 0x15, 0x00, 0x1C, 0x00, 0x32, 0x40, -+0x18, 0x00, 0x32, 0x40, 0x2C, 0x98, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, 0x19, 0x9C, 0x8F, 0xC1, 0x32, 0xE4, 0x05, 0x00, -+0x22, 0xF3, 0x02, 0x00, 0x98, 0x9C, 0x17, 0x00, 0x60, 0x00, 0x32, 0x40, 0x08, 0x88, 0x17, 0x00, 0x44, 0x9E, 0x17, 0x00, -+0x2C, 0x00, 0x32, 0x40, 0x74, 0x98, 0x15, 0x00, 0xC8, 0x98, 0x15, 0x00, 0x94, 0x40, 0x04, 0x40, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x50, 0x98, 0x15, 0x00, 0x68, 0x65, 0x17, 0x00, 0xB1, 0x7F, 0x13, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xD5, 0x65, 0x12, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x81, 0x66, 0x12, 0x00, 0xDC, 0xFF, 0xFF, 0x7F, 0x10, 0x4E, 0x11, 0x4A, -+0x09, 0x92, 0x40, 0xF6, 0x85, 0x12, 0xD6, 0xF8, 0xE8, 0x30, 0x0A, 0x92, 0x98, 0x47, 0x73, 0x6C, 0x0D, 0xF1, 0x23, 0x01, -+0x09, 0xA8, 0x98, 0x47, 0x00, 0x28, 0xB6, 0xD1, 0x63, 0x68, 0x32, 0x6D, 0x9D, 0xF8, 0x23, 0x00, 0x43, 0xF0, 0x80, 0x03, -+0x63, 0x60, 0x90, 0x47, 0x6B, 0x7C, 0xD3, 0xE6, 0x01, 0xF0, 0x32, 0xFE, 0xAA, 0x7C, 0x94, 0xF8, 0x63, 0x30, 0x94, 0xF8, -+0xC0, 0x14, 0x50, 0xE7, 0x88, 0x1A, 0x17, 0x00, 0x00, 0x00, 0x85, 0x09, 0x2D, 0xE9, 0xF0, 0x4F, 0x02, 0x46, 0x6A, 0x4D, -+0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0xF3, 0x8B, 0xB0, 0xEF, 0x18, 0x04, 0x90, 0x39, 0x46, 0x66, 0x48, 0x06, 0x93, -+0x0C, 0xF0, 0x4A, 0xFD, 0x97, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0x00, 0xF0, 0xDD, 0x80, 0x04, 0x2B, 0x00, 0xF0, 0x98, 0x80, -+0xDF, 0xF8, 0x98, 0xA1, 0x60, 0x4C, 0x00, 0x2B, 0x00, 0xF0, 0x89, 0x80, 0x9A, 0xF8, 0x12, 0x30, 0x9A, 0xF8, 0x11, 0x20, -+0x1A, 0x44, 0x01, 0x2A, 0x5E, 0xD0, 0x0A, 0xB9, 0x5B, 0x4B, 0x1A, 0x60, 0x06, 0x9E, 0xD4, 0xF8, 0xD8, 0x31, 0x06, 0xF1, -+0x18, 0x00, 0x28, 0x44, 0x98, 0x47, 0x06, 0xF1, 0x28, 0x00, 0xD4, 0xF8, 0xD8, 0x31, 0x28, 0x44, 0x98, 0x47, 0x04, 0x9A, -+0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0x53, 0x93, 0xF8, 0xC0, 0x24, 0x00, 0x2A, 0x3A, 0xD1, 0x04, 0x9A, 0x4F, 0xF4, -+0xA4, 0x63, 0x03, 0xFB, 0x02, 0x53, 0x05, 0x26, 0x93, 0xF8, 0x63, 0x00, 0x0A, 0xF0, 0x02, 0xFA, 0x4B, 0x4B, 0x1A, 0x69, -+0xBA, 0x42, 0x04, 0xBF, 0x00, 0x22, 0x1A, 0x61, 0x00, 0x21, 0x4F, 0xF4, 0xA4, 0x62, 0x38, 0x46, 0xE9, 0xF7, 0x22, 0xFC, -+0x04, 0x99, 0x9A, 0xF8, 0x11, 0x20, 0x9A, 0xF8, 0x12, 0x30, 0xD4, 0xF8, 0x50, 0xC4, 0x01, 0x91, 0x4F, 0xF4, 0xA4, 0x60, -+0x00, 0xFB, 0x01, 0x55, 0x7F, 0x24, 0x00, 0x93, 0x3F, 0x49, 0xC5, 0xF8, 0x2C, 0xC0, 0x13, 0x44, 0x4F, 0xF4, 0x80, 0x70, -+0x3D, 0x4A, 0x2F, 0x63, 0x85, 0xF8, 0x62, 0x60, 0x85, 0xF8, 0x65, 0x40, 0x85, 0xF8, 0x66, 0x40, 0x0D, 0xF0, 0xC2, 0xFE, -+0x39, 0x48, 0x39, 0x46, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x0C, 0xF0, 0x91, 0xBC, 0x93, 0xF8, 0xC1, 0x04, 0x01, 0x21, -+0x09, 0xF0, 0x2E, 0xFC, 0x9A, 0xF8, 0x13, 0x30, 0x01, 0x3B, 0x8A, 0xF8, 0x13, 0x30, 0xB9, 0xE7, 0x31, 0x4A, 0xDA, 0xF8, -+0x08, 0x60, 0xDF, 0xF8, 0xC8, 0xE0, 0xDF, 0xF8, 0xC8, 0x90, 0xDF, 0xF8, 0xC8, 0x80, 0xD2, 0xE9, 0x00, 0x01, 0x21, 0xF0, -+0x10, 0x0C, 0x4C, 0xEA, 0x00, 0x00, 0xC2, 0xF8, 0x04, 0xC0, 0xCE, 0xF8, 0x00, 0x00, 0xB0, 0x6B, 0xB6, 0x8F, 0xC9, 0xF8, -+0x00, 0x00, 0xC8, 0xF8, 0x00, 0x60, 0x00, 0x2B, 0x88, 0xD1, 0x13, 0x68, 0x21, 0xF4, 0x88, 0x71, 0x0B, 0x43, 0x51, 0x60, -+0xCE, 0xF8, 0x00, 0x30, 0x80, 0xE7, 0x9A, 0xF8, 0x11, 0x20, 0x9A, 0xF8, 0x12, 0x30, 0x01, 0x3A, 0xD2, 0xB2, 0x8A, 0xF8, -+0x11, 0x20, 0x71, 0xE7, 0xEA, 0xF7, 0x50, 0xFC, 0x00, 0x28, 0x40, 0xF0, 0x28, 0x81, 0xDF, 0xF8, 0x60, 0xA0, 0x12, 0x4C, -+0x9A, 0xF8, 0x10, 0x00, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x00, 0x53, 0x5A, 0x68, 0x19, 0x6C, 0x22, 0xF0, 0x80, 0x02, -+0x5A, 0x60, 0x09, 0xB1, 0x63, 0x6D, 0x98, 0x47, 0x9A, 0xF8, 0x12, 0x30, 0x00, 0x2B, 0x40, 0xF0, 0x0D, 0x81, 0x0E, 0x48, -+0x0E, 0x49, 0x42, 0x68, 0x0E, 0x4E, 0x01, 0x60, 0x0A, 0x43, 0x32, 0x60, 0xFF, 0x21, 0x9A, 0xF8, 0x11, 0x20, 0x8A, 0xF8, -+0x10, 0x10, 0x49, 0xE7, 0x18, 0x88, 0x17, 0x00, 0x08, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x94, 0x40, 0x04, 0x40, -+0x94, 0x64, 0x17, 0x00, 0xB8, 0x98, 0x15, 0x00, 0xDC, 0x98, 0x15, 0x00, 0x00, 0x88, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, -+0x8C, 0x84, 0x03, 0x35, 0x60, 0x00, 0x32, 0x40, 0x20, 0x00, 0x32, 0x40, 0x24, 0x00, 0x32, 0x40, 0x04, 0x9E, 0xDF, 0xF8, -+0x28, 0xA2, 0x7F, 0x49, 0x9A, 0xF8, 0x12, 0x20, 0x7E, 0x4C, 0xDF, 0xF8, 0x20, 0xB2, 0x06, 0xF1, 0x0A, 0x08, 0x08, 0xEB, -+0x88, 0x03, 0x4F, 0xF4, 0x1E, 0x70, 0xC8, 0xEB, 0x03, 0x13, 0x4F, 0xF0, 0xA4, 0x0C, 0x00, 0xFB, 0x08, 0x18, 0x46, 0x33, -+0x9E, 0x20, 0xCD, 0xE9, 0x08, 0x7A, 0x1C, 0xFB, 0x06, 0x06, 0x01, 0x3A, 0x00, 0x20, 0x01, 0xEB, 0xC3, 0x03, 0x03, 0x93, -+0x8A, 0xF8, 0x12, 0x20, 0x88, 0xF8, 0x25, 0x00, 0x05, 0x90, 0x05, 0xEB, 0xC6, 0x06, 0xB9, 0x46, 0xD8, 0xF8, 0x08, 0x32, -+0x9D, 0xF8, 0x14, 0x70, 0x3B, 0xB1, 0x03, 0x99, 0xD4, 0xF8, 0x84, 0x33, 0x4F, 0xF0, 0x80, 0x42, 0x28, 0x39, 0x38, 0x46, -+0x98, 0x47, 0xD8, 0xF8, 0x30, 0x32, 0x33, 0xB1, 0xD4, 0xF8, 0x84, 0x33, 0x03, 0x99, 0x4F, 0xF0, 0x80, 0x42, 0x38, 0x46, -+0x98, 0x47, 0xD9, 0xF8, 0xF0, 0x34, 0x00, 0x2B, 0x00, 0xF0, 0x93, 0x80, 0x30, 0x46, 0x0C, 0xF0, 0x55, 0xFC, 0xA6, 0xF1, -+0x28, 0x0A, 0x07, 0x90, 0x50, 0x46, 0x0C, 0xF0, 0x4F, 0xFC, 0x07, 0x99, 0x02, 0x46, 0x5B, 0x48, 0x0D, 0xF0, 0xA0, 0xFD, -+0xEF, 0xF3, 0x10, 0x83, 0xD8, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x58, 0x4A, 0x01, 0x23, 0x13, 0x60, 0xDB, 0xF8, 0x00, 0x20, -+0xD4, 0xF8, 0x84, 0x33, 0x01, 0x32, 0xCB, 0xF8, 0x00, 0x20, 0x31, 0x46, 0x4F, 0xF0, 0x80, 0x42, 0x38, 0x46, 0x98, 0x47, -+0xD4, 0xF8, 0x84, 0x33, 0x51, 0x46, 0x38, 0x46, 0x4F, 0xF0, 0x80, 0x42, 0x98, 0x47, 0xDB, 0xF8, 0x00, 0x30, 0x3B, 0xB1, -+0x4B, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xCB, 0xF8, 0x00, 0x30, 0x0B, 0xB9, 0x00, 0x2A, 0x66, 0xD1, 0x05, 0x9B, 0x03, 0x9A, -+0x01, 0x33, 0x08, 0x32, 0x05, 0x2B, 0x05, 0x93, 0x08, 0xF1, 0x08, 0x08, 0x06, 0xF1, 0x08, 0x06, 0x09, 0xF1, 0x08, 0x09, -+0x03, 0x92, 0xA1, 0xD1, 0x04, 0x9A, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0x53, 0xDD, 0xE9, 0x08, 0x7A, 0xD3, 0xF8, -+0x18, 0x35, 0x00, 0x2B, 0x4F, 0xD0, 0x06, 0x9B, 0x03, 0xF5, 0xA3, 0x66, 0x2E, 0x44, 0x30, 0x46, 0x0C, 0xF0, 0x04, 0xFC, -+0x01, 0x46, 0x38, 0x48, 0x0D, 0xF0, 0x56, 0xFD, 0xEF, 0xF3, 0x10, 0x83, 0xD9, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x33, 0x4B, -+0x01, 0x22, 0x1A, 0x60, 0xDB, 0xF8, 0x00, 0x20, 0xD4, 0xF8, 0x84, 0x33, 0x01, 0x32, 0xCB, 0xF8, 0x00, 0x20, 0x31, 0x46, -+0x4F, 0xF0, 0x80, 0x42, 0x05, 0x20, 0x98, 0x47, 0xDB, 0xF8, 0x00, 0x30, 0x3B, 0xB1, 0x2A, 0x4A, 0x01, 0x3B, 0x12, 0x68, -+0xCB, 0xF8, 0x00, 0x30, 0x0B, 0xB9, 0x00, 0x2A, 0x43, 0xD1, 0x9A, 0xF8, 0x12, 0x20, 0x00, 0x2A, 0x3C, 0xD0, 0x9A, 0xF8, -+0x11, 0x30, 0x13, 0x44, 0x01, 0x2B, 0x7F, 0xF4, 0x71, 0xAE, 0x23, 0x49, 0xDA, 0xF8, 0x08, 0x00, 0x22, 0x4E, 0xD1, 0xE9, -+0x00, 0x23, 0x23, 0xF0, 0x10, 0x03, 0x4B, 0x60, 0x1A, 0x43, 0x20, 0x49, 0x20, 0x4B, 0x32, 0x60, 0x86, 0x6B, 0x82, 0x8F, -+0x0E, 0x60, 0x1A, 0x60, 0x5E, 0xE6, 0xD9, 0xF8, 0xC8, 0x34, 0x00, 0x2B, 0x7F, 0xF4, 0x68, 0xAF, 0xA6, 0xF1, 0x28, 0x0A, -+0x72, 0xE7, 0x62, 0xB6, 0x96, 0xE7, 0x06, 0x9B, 0x03, 0xF5, 0xA3, 0x66, 0x2E, 0x44, 0xB5, 0xE7, 0x01, 0xF0, 0x4E, 0xFC, -+0x9A, 0xF8, 0x12, 0x30, 0xF4, 0xE6, 0x00, 0x20, 0xEA, 0xF7, 0x2C, 0xFB, 0x12, 0x4B, 0x1A, 0x68, 0xD2, 0x05, 0x7F, 0xF5, -+0xD0, 0xAE, 0x4F, 0xF4, 0x80, 0x72, 0xC3, 0xF8, 0x80, 0x20, 0xBF, 0xF3, 0x4F, 0x8F, 0xBF, 0xF3, 0x6F, 0x8F, 0xC6, 0xE6, -+0x01, 0xF0, 0x5E, 0xFC, 0x2C, 0xE6, 0x62, 0xB6, 0xB9, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x88, 0x98, 0x15, 0x00, 0x38, 0x61, 0x17, 0x00, 0xA0, 0x98, 0x15, 0x00, 0x98, 0x9C, 0x17, 0x00, 0x60, 0x00, 0x32, 0x40, -+0x20, 0x00, 0x32, 0x40, 0x24, 0x00, 0x32, 0x40, 0x00, 0xE1, 0x00, 0xE0, 0x00, 0x88, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x47, 0x05, 0x46, 0x4F, 0xF4, 0xA4, 0x60, 0x2E, 0x78, 0x95, 0xF8, 0x29, 0x80, 0x4F, 0x4C, 0x00, 0xFB, -+0x08, 0xF0, 0xC6, 0xEB, 0x06, 0x17, 0x00, 0xEB, 0xC7, 0x07, 0x27, 0x44, 0x4F, 0xF0, 0x78, 0x0A, 0x1A, 0xFB, 0x06, 0x0A, -+0x87, 0xF8, 0x3A, 0x12, 0x0A, 0xF5, 0xEC, 0x79, 0x95, 0xF8, 0x28, 0x30, 0x87, 0xF8, 0x38, 0x32, 0xA1, 0x44, 0x87, 0xF8, -+0x39, 0x62, 0x48, 0x46, 0x48, 0x22, 0x00, 0x21, 0xE9, 0xF7, 0x46, 0xFA, 0x97, 0xF8, 0x38, 0x32, 0x37, 0x01, 0x05, 0x2B, -+0x0C, 0xD8, 0xDF, 0xE8, 0x03, 0xF0, 0x41, 0x51, 0x0B, 0x41, 0x6A, 0x03, 0x0A, 0xF5, 0x0A, 0x70, 0x20, 0x44, 0x10, 0x22, -+0x05, 0xF1, 0x08, 0x01, 0x20, 0xF0, 0xC2, 0xF9, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x08, 0xF3, 0xBA, 0x1B, 0x03, 0xEB, -+0xC2, 0x03, 0x23, 0x44, 0x00, 0x20, 0x00, 0x21, 0xC3, 0xE9, 0x88, 0x01, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x08, 0xF3, -+0xBA, 0x1B, 0x03, 0xEB, 0xC2, 0x02, 0x22, 0x44, 0x23, 0x44, 0x92, 0xF8, 0x38, 0x12, 0x05, 0x29, 0x4F, 0xF0, 0x01, 0x00, -+0x0C, 0xBF, 0xC3, 0xF8, 0xAC, 0x94, 0xC3, 0xF8, 0xA8, 0x94, 0x4F, 0xF4, 0xA4, 0x63, 0x82, 0xF8, 0x3B, 0x02, 0x03, 0xFB, -+0x08, 0xF8, 0xD5, 0xE9, 0x02, 0x01, 0xD5, 0xE9, 0x04, 0x23, 0xBF, 0x1B, 0x08, 0xEB, 0xC7, 0x07, 0x3C, 0x44, 0xC4, 0xE9, -+0x8F, 0x01, 0xC4, 0xE9, 0x91, 0x23, 0x2B, 0x79, 0x84, 0xF8, 0x4C, 0x32, 0xBD, 0xE8, 0xF0, 0x87, 0x20, 0xF0, 0x90, 0xFA, -+0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x08, 0xF3, 0xBA, 0x1B, 0x03, 0xEB, 0xC2, 0x03, 0x23, 0x44, 0x20, 0xF0, 0x7F, 0x40, -+0x00, 0x21, 0xC3, 0xE9, 0x88, 0x01, 0xC5, 0xE7, 0x4F, 0xF4, 0xA4, 0x60, 0xBB, 0x1B, 0x00, 0xFB, 0x08, 0xF0, 0x00, 0xEB, -+0xC3, 0x00, 0x20, 0x44, 0xA9, 0x69, 0xC0, 0xF8, 0x28, 0x12, 0xE9, 0x69, 0xC0, 0xF8, 0x2C, 0x12, 0x29, 0x6A, 0xC0, 0xF8, -+0x30, 0x12, 0x00, 0x22, 0x69, 0x6A, 0xC0, 0xF8, 0x34, 0x12, 0x00, 0x23, 0xC0, 0xE9, 0x88, 0x23, 0xAC, 0xE7, 0x4F, 0xF4, -+0xA4, 0x63, 0x03, 0xFB, 0x08, 0xF2, 0x05, 0xA1, 0xD1, 0xE9, 0x00, 0x01, 0xBB, 0x1B, 0x02, 0xEB, 0xC3, 0x03, 0x23, 0x44, -+0xC3, 0xE9, 0x88, 0x01, 0x9E, 0xE7, 0x00, 0xBF, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x18, 0x88, 0x17, 0x00, -+0x78, 0x22, 0x10, 0xB4, 0xC1, 0xEB, 0x01, 0x13, 0xD0, 0xF8, 0xA8, 0x44, 0x02, 0xFB, 0x01, 0x01, 0x00, 0xEB, 0xC3, 0x03, -+0x01, 0xF5, 0xEC, 0x71, 0x00, 0x22, 0x8C, 0x42, 0x83, 0xF8, 0x3B, 0x22, 0x06, 0xD0, 0xD0, 0xF8, 0xAC, 0x34, 0x8B, 0x42, -+0x1C, 0xD0, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x90, 0xF8, 0x3B, 0x32, 0xC0, 0xF8, 0xA8, 0x24, 0x00, 0xF5, 0xEC, 0x71, -+0x7B, 0xB9, 0x90, 0xF8, 0xB3, 0x32, 0x00, 0xF5, 0x14, 0x71, 0x53, 0xB9, 0x90, 0xF8, 0x2B, 0x33, 0x00, 0xF5, 0x32, 0x71, -+0x2B, 0xB9, 0x90, 0xF8, 0xA3, 0x33, 0x00, 0xF5, 0x50, 0x71, 0x00, 0x2B, 0xE1, 0xD0, 0xC0, 0xF8, 0xA8, 0x14, 0xE2, 0xE7, -+0x90, 0xF8, 0x1B, 0x34, 0x00, 0x22, 0xC0, 0xF8, 0xAC, 0x24, 0x43, 0xB9, 0x90, 0xF8, 0x93, 0x34, 0x00, 0x2B, 0xD8, 0xD0, -+0x00, 0xF5, 0x86, 0x63, 0xC0, 0xF8, 0xAC, 0x34, 0xD3, 0xE7, 0x00, 0xF5, 0x6E, 0x73, 0xF9, 0xE7, 0x70, 0xB5, 0xD0, 0xF8, -+0xE4, 0x40, 0x54, 0xB1, 0x05, 0x4E, 0x05, 0x46, 0x21, 0x46, 0xD6, 0xF8, 0x20, 0x33, 0x00, 0x22, 0x28, 0x46, 0x98, 0x47, -+0x24, 0x68, 0x00, 0x2C, 0xF6, 0xD1, 0x70, 0xBD, 0x88, 0x1A, 0x17, 0x00, 0x04, 0x4A, 0x05, 0x4B, 0x11, 0x69, 0xD3, 0xF8, -+0xE0, 0x31, 0x01, 0xF5, 0x1C, 0x51, 0x28, 0x30, 0x10, 0x31, 0x18, 0x47, 0x00, 0x10, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0x0B, 0x4B, 0x1A, 0x78, 0x02, 0xB9, 0x70, 0x47, 0x5B, 0x68, 0x1B, 0x07, 0xFB, 0xD4, 0x43, 0x68, 0x70, 0xB5, 0x04, 0x46, -+0x03, 0xB1, 0x70, 0xBD, 0x06, 0x4D, 0x28, 0x30, 0xD5, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0xD5, 0xF8, 0x50, 0x34, 0x20, 0x46, -+0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, 0x00, 0xBF, 0x1C, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xF0, 0xB4, 0xA0, 0xF8, -+0xD2, 0x10, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x1F, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x1F, 0x4D, -+0x1F, 0x4B, 0x2E, 0x68, 0x9A, 0x7C, 0x77, 0x1C, 0x01, 0x2A, 0x2F, 0x60, 0x2B, 0xD9, 0x1D, 0x4C, 0x1A, 0x7D, 0x4F, 0xF4, -+0xA4, 0x6C, 0x0C, 0xFB, 0x02, 0x42, 0xB2, 0xF8, 0xD2, 0x40, 0xA1, 0x42, 0x1C, 0xD3, 0x9B, 0x68, 0x5B, 0xB1, 0x01, 0x21, -+0xB3, 0xF8, 0xD2, 0x20, 0x83, 0xF8, 0xD5, 0x10, 0xB2, 0xFB, 0xF4, 0xF2, 0x83, 0xF8, 0xD4, 0x20, 0x1B, 0x68, 0x00, 0x2B, -+0xF4, 0xD1, 0x12, 0x4A, 0x13, 0x68, 0x1B, 0x0C, 0x1B, 0x04, 0x23, 0x43, 0x13, 0x60, 0x2F, 0xB1, 0x0A, 0x4B, 0x2E, 0x60, -+0x1B, 0x68, 0x0E, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0xF0, 0xBC, 0x70, 0x47, 0x90, 0xF8, 0x63, 0x20, 0x1A, 0x75, 0x0C, 0x46, -+0xDD, 0xE7, 0x90, 0xF8, 0x63, 0x20, 0x1A, 0x75, 0x40, 0xF2, 0x01, 0x13, 0x0C, 0x46, 0xA0, 0xF8, 0xD4, 0x30, 0xE2, 0xE7, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x64, 0x00, 0x32, 0x40, -+0x2D, 0xE9, 0xF0, 0x41, 0x0C, 0x21, 0x04, 0x46, 0x82, 0xB0, 0x03, 0x23, 0x00, 0x22, 0x58, 0x20, 0x0B, 0xF0, 0xEA, 0xFC, -+0x3B, 0x4F, 0xFF, 0x22, 0x7B, 0x6D, 0x8D, 0xF8, 0x07, 0x20, 0x05, 0x46, 0x94, 0xF8, 0x63, 0x00, 0x98, 0x47, 0xB4, 0xF8, -+0xB6, 0x14, 0x94, 0xF8, 0xB4, 0x04, 0x10, 0xF0, 0xED, 0xF9, 0x94, 0xF8, 0xB5, 0x24, 0xB4, 0xF8, 0xB8, 0x64, 0xB4, 0xF8, -+0xBA, 0x14, 0x84, 0xF8, 0xC5, 0x21, 0x04, 0x2A, 0x08, 0xBF, 0x03, 0x22, 0x03, 0x46, 0xC4, 0xF8, 0x90, 0x01, 0xA4, 0xF8, -+0x94, 0x61, 0xA4, 0xF8, 0x96, 0x11, 0x84, 0xF8, 0xC4, 0x21, 0x00, 0x28, 0x50, 0xD0, 0x1B, 0x79, 0x84, 0xF8, 0xBC, 0x34, -+0x7B, 0x6C, 0x0D, 0xF1, 0x07, 0x01, 0x04, 0xF2, 0xB4, 0x40, 0x98, 0x47, 0x9D, 0xF8, 0x07, 0x10, 0x68, 0x70, 0xA9, 0x70, -+0x06, 0x46, 0x94, 0xF8, 0x63, 0x00, 0x28, 0x70, 0x94, 0xF8, 0x62, 0x30, 0x2B, 0xBB, 0x84, 0xF8, 0x8A, 0x30, 0x7E, 0xBB, -+0xFB, 0x6C, 0x94, 0xF8, 0x6C, 0x80, 0x98, 0x47, 0xD7, 0xF8, 0xD8, 0x31, 0x04, 0xF1, 0x28, 0x00, 0x98, 0x47, 0x1A, 0x4A, -+0x1A, 0x49, 0xD7, 0xF8, 0xE0, 0x31, 0x09, 0x69, 0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, 0x08, 0x28, 0x04, 0xF1, 0x18, 0x00, -+0xD8, 0xF8, 0x08, 0x20, 0x11, 0x44, 0x98, 0x47, 0x01, 0x23, 0x84, 0xF8, 0x78, 0x60, 0x84, 0xF8, 0x8B, 0x30, 0x28, 0x46, -+0x0B, 0xF0, 0xBE, 0xFC, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x2B, 0xF7, 0xD1, 0x00, 0x23, 0x84, 0xF8, 0xDB, 0x30, -+0x00, 0x2E, 0xF2, 0xD1, 0xFB, 0x6C, 0x98, 0x47, 0x0A, 0x4B, 0x01, 0x22, 0x5A, 0x72, 0xEC, 0xE7, 0xD7, 0xF8, 0xBC, 0x31, -+0x20, 0x46, 0x98, 0x47, 0x28, 0x46, 0x0B, 0xF0, 0xA7, 0xFC, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x1B, 0x79, 0xFF, 0xDE, -+0x88, 0x1A, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0xD8, 0x9C, 0x17, 0x00, 0x07, 0x4A, 0x93, 0x7C, -+0x51, 0x7C, 0x0B, 0x44, 0x01, 0x2B, 0x06, 0xD1, 0x90, 0x68, 0x90, 0xF8, 0x62, 0x30, 0x00, 0x2B, 0x18, 0xBF, 0x00, 0x20, -+0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x88, 0x17, 0x00, 0x05, 0x4A, 0x06, 0x49, 0x93, 0x7C, 0x50, 0x7C, -+0x03, 0x44, 0x00, 0x22, 0x01, 0x2B, 0x0A, 0x60, 0x01, 0xDC, 0xFF, 0xF7, 0x65, 0xB9, 0x70, 0x47, 0x00, 0x88, 0x17, 0x00, -+0x2C, 0x00, 0x32, 0x40, 0x13, 0x4B, 0x00, 0x22, 0x02, 0x70, 0x9B, 0x68, 0x03, 0xB3, 0x10, 0xB4, 0x01, 0x46, 0x01, 0x24, -+0x10, 0x46, 0x08, 0xE0, 0x93, 0xF8, 0x64, 0x20, 0x1A, 0xB1, 0x93, 0xF8, 0xC0, 0x24, 0x72, 0xB9, 0x01, 0x30, 0x1B, 0x68, -+0x7B, 0xB1, 0x93, 0xF8, 0x62, 0x20, 0x00, 0x2A, 0xF2, 0xD0, 0x93, 0xF8, 0x64, 0x20, 0x00, 0x2A, 0xF5, 0xD0, 0x93, 0xF8, -+0xC0, 0x24, 0x00, 0x2A, 0xF1, 0xD0, 0x0C, 0x70, 0x1B, 0x68, 0x00, 0x2B, 0xEF, 0xD1, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, -+0x18, 0x46, 0x70, 0x47, 0x00, 0x88, 0x17, 0x00, 0x10, 0xB5, 0x04, 0x23, 0x04, 0x46, 0xFF, 0x22, 0x00, 0x21, 0x87, 0x20, -+0x0B, 0xF0, 0x16, 0xFC, 0x04, 0x60, 0xBD, 0xE8, 0x10, 0x40, 0x0B, 0xF0, 0x41, 0xBC, 0x00, 0xBF, 0x11, 0xF4, 0x00, 0x01, -+0x70, 0xB5, 0x04, 0x46, 0x16, 0xD0, 0x00, 0x25, 0x2A, 0x4B, 0x80, 0xF8, 0x78, 0x50, 0x19, 0x69, 0x29, 0x48, 0x2A, 0x4B, -+0x80, 0xF8, 0x24, 0x50, 0x40, 0xF2, 0x01, 0x72, 0x01, 0xF5, 0x1C, 0x51, 0x44, 0x61, 0x82, 0x83, 0xD3, 0xF8, 0xE0, 0x31, -+0x10, 0x31, 0x0C, 0x30, 0x98, 0x47, 0x84, 0xF8, 0x6B, 0x50, 0x70, 0xBD, 0x90, 0xF8, 0x6B, 0x30, 0x21, 0x4A, 0x01, 0x33, -+0xDB, 0xB2, 0x12, 0x68, 0x80, 0xF8, 0x6B, 0x30, 0x52, 0x78, 0x9A, 0x42, 0x25, 0xD0, 0x90, 0xF8, 0x64, 0x30, 0xC3, 0xB9, -+0x1C, 0x4B, 0x5B, 0x78, 0x23, 0xB1, 0x1C, 0x4A, 0x13, 0x68, 0x23, 0xF0, 0x00, 0x43, 0x13, 0x60, 0x15, 0x4B, 0x1A, 0x7A, -+0x0A, 0xB1, 0x01, 0x3A, 0x1A, 0x72, 0x14, 0x4A, 0x17, 0x48, 0xD2, 0xF8, 0xD8, 0x21, 0x01, 0x21, 0x99, 0x83, 0x90, 0x47, -+0x63, 0x68, 0x23, 0xF4, 0x00, 0x73, 0x63, 0x60, 0x70, 0xBD, 0x0E, 0x4B, 0x90, 0xF8, 0x63, 0x00, 0xD3, 0xF8, 0x94, 0x34, -+0x10, 0x49, 0x22, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, 0x80, 0xF8, 0x6B, 0x10, 0x4F, 0xF4, 0x80, 0x60, 0x0D, 0x49, -+0x0D, 0xF0, 0x74, 0xFA, 0x05, 0x4B, 0x20, 0x46, 0xD3, 0xF8, 0xBC, 0x31, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, 0x00, 0xBF, -+0x00, 0x10, 0x50, 0x40, 0x1C, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x4C, 0x36, 0x17, 0x00, -+0x34, 0x04, 0x32, 0x40, 0x28, 0x9E, 0x17, 0x00, 0x99, 0x71, 0x13, 0x00, 0xF0, 0x98, 0x15, 0x00, 0x30, 0xB4, 0x01, 0x25, -+0x00, 0x24, 0x1D, 0x70, 0x14, 0x70, 0x04, 0x28, 0x20, 0xD8, 0xDF, 0xE8, 0x00, 0xF0, 0x03, 0x18, 0x09, 0x05, 0x14, 0x00, -+0x00, 0x21, 0x19, 0x70, 0x01, 0x23, 0x13, 0x70, 0x30, 0xBC, 0x70, 0x47, 0x09, 0x78, 0x10, 0x29, 0x0F, 0xD0, 0x20, 0x29, -+0x01, 0xD1, 0x02, 0x21, 0x19, 0x70, 0x03, 0x23, 0x13, 0x70, 0x30, 0xBC, 0x70, 0x47, 0x04, 0x23, 0x13, 0x70, 0x30, 0xBC, -+0x70, 0x47, 0x02, 0x23, 0x13, 0x70, 0x30, 0xBC, 0x70, 0x47, 0x00, 0x21, 0x19, 0x70, 0xF0, 0xE7, 0x05, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xE1, 0xDA, 0x30, 0xBC, 0x03, 0x49, 0x03, 0x48, 0xAD, 0x22, 0x0D, 0xF0, 0x50, 0xBC, -+0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x22, 0x4A, 0x13, 0x68, 0xC3, 0xF3, 0x0F, 0x33, -+0x23, 0xB1, 0x13, 0x68, 0xC3, 0xF3, 0x0F, 0x33, 0x96, 0x2B, 0x36, 0xD9, 0x96, 0x20, 0x1E, 0x49, 0x1E, 0x4B, 0x0A, 0x68, -+0x18, 0x81, 0xC2, 0xF3, 0x0F, 0x32, 0x22, 0xB1, 0x0A, 0x68, 0xC2, 0xF3, 0x0F, 0x32, 0x96, 0x2A, 0x25, 0xD9, 0x96, 0x22, -+0x19, 0x49, 0x5A, 0x81, 0x0A, 0x68, 0xC2, 0xF3, 0x0F, 0x32, 0x22, 0xB1, 0x0A, 0x68, 0xC2, 0xF3, 0x0F, 0x32, 0x96, 0x2A, -+0x15, 0xD9, 0x96, 0x22, 0x14, 0x49, 0x9A, 0x81, 0x0A, 0x68, 0xC2, 0xF3, 0x0F, 0x32, 0x22, 0xB1, 0x0A, 0x68, 0xC2, 0xF3, -+0x0F, 0x32, 0x96, 0x2A, 0x03, 0xD9, 0x96, 0x22, 0xDA, 0x81, 0x1A, 0x82, 0x70, 0x47, 0x0A, 0x68, 0xC2, 0xF3, 0x0F, 0x32, -+0xDA, 0x81, 0x1A, 0x82, 0x70, 0x47, 0x0A, 0x68, 0xC2, 0xF3, 0x0F, 0x32, 0xE6, 0xE7, 0x0A, 0x68, 0xC2, 0xF3, 0x0F, 0x32, -+0xD6, 0xE7, 0x10, 0x68, 0xC0, 0xF3, 0x0F, 0x30, 0xC5, 0xE7, 0x00, 0xBF, 0x00, 0x02, 0x32, 0x40, 0x04, 0x02, 0x32, 0x40, -+0x98, 0x9C, 0x17, 0x00, 0x08, 0x02, 0x32, 0x40, 0x0C, 0x02, 0x32, 0x40, 0x38, 0xB5, 0x0B, 0x4C, 0x34, 0x22, 0x00, 0x21, -+0x20, 0x46, 0xE8, 0xF7, 0x0B, 0xFF, 0x09, 0x48, 0x09, 0x4A, 0x0A, 0x49, 0x22, 0x60, 0x01, 0x25, 0x00, 0x23, 0xE5, 0x77, -+0x02, 0x60, 0x63, 0x82, 0x63, 0x60, 0xD1, 0xF8, 0xA0, 0x31, 0x98, 0x47, 0x05, 0x4B, 0x63, 0x62, 0x38, 0xBD, 0x00, 0xBF, -+0x98, 0x9C, 0x17, 0x00, 0x60, 0x00, 0x32, 0x40, 0xDE, 0xFF, 0xFF, 0x7F, 0x88, 0x1A, 0x17, 0x00, 0x7D, 0x71, 0x13, 0x00, -+0x38, 0xB5, 0x51, 0x4D, 0x51, 0x4C, 0xAB, 0x78, 0x13, 0xB9, 0xD4, 0xF8, 0xE4, 0x30, 0x98, 0x47, 0xFF, 0xF7, 0xD4, 0xFF, -+0xFF, 0xF7, 0x6A, 0xF8, 0xFE, 0xF7, 0xF8, 0xFC, 0x09, 0xF0, 0xDC, 0xFC, 0x07, 0xF0, 0x78, 0xFD, 0x08, 0xF0, 0xAA, 0xFE, -+0xD4, 0xF8, 0x8C, 0x33, 0x98, 0x47, 0xAB, 0x78, 0x00, 0x2B, 0x00, 0xF0, 0x82, 0x80, 0xFD, 0xF7, 0x61, 0xFA, 0x45, 0x4D, -+0x2B, 0x68, 0x1B, 0x78, 0x9B, 0x07, 0x7D, 0xD4, 0x03, 0xF0, 0x70, 0xFD, 0x09, 0xF0, 0x7C, 0xFE, 0x63, 0x6E, 0x98, 0x47, -+0xD4, 0xF8, 0x7C, 0x31, 0x98, 0x47, 0xEF, 0xF7, 0x0D, 0xF8, 0xEF, 0xF7, 0x0D, 0xF8, 0xEF, 0xF7, 0x0D, 0xF8, 0x3C, 0x4B, -+0x93, 0xF8, 0xFA, 0x30, 0x00, 0x2B, 0x62, 0xD1, 0xD4, 0xF8, 0xE4, 0x34, 0x98, 0x47, 0x39, 0x4A, 0x29, 0x68, 0x13, 0x68, -+0x38, 0x48, 0x39, 0x4D, 0xC3, 0xF3, 0x15, 0x03, 0x43, 0xF0, 0x20, 0x73, 0x13, 0x60, 0x8B, 0x78, 0x02, 0x68, 0xDC, 0x06, -+0x4C, 0xBF, 0x22, 0xF0, 0x00, 0x42, 0x42, 0xF0, 0x00, 0x42, 0x02, 0x60, 0x32, 0x4A, 0x33, 0x4C, 0x33, 0x48, 0x13, 0xF0, -+0x01, 0x0F, 0x13, 0x68, 0x14, 0xBF, 0x43, 0xF4, 0x80, 0x23, 0x23, 0xF4, 0x80, 0x23, 0x13, 0x60, 0x22, 0x68, 0x2F, 0x4B, -+0x42, 0xF0, 0x00, 0x62, 0x22, 0x60, 0x02, 0x68, 0x2D, 0x4C, 0x22, 0xF4, 0x70, 0x02, 0x42, 0xF4, 0x00, 0x12, 0x02, 0x60, -+0x1A, 0x68, 0x22, 0xF4, 0xE0, 0x62, 0x42, 0xF4, 0xC0, 0x62, 0x1A, 0x60, 0x1A, 0x68, 0x22, 0xF4, 0x60, 0x52, 0x42, 0xF4, -+0x00, 0x52, 0x1A, 0x60, 0x1A, 0x68, 0x22, 0xF4, 0xE0, 0x32, 0x42, 0xF4, 0x40, 0x42, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF4, -+0x60, 0x22, 0x1A, 0x60, 0x2B, 0x68, 0x20, 0x4A, 0x23, 0x40, 0x43, 0xF4, 0xBB, 0x63, 0xA0, 0xF5, 0x66, 0x70, 0x43, 0xF0, -+0x04, 0x03, 0x2B, 0x60, 0x03, 0x68, 0xA5, 0xF1, 0xF6, 0x55, 0xA5, 0xF5, 0x32, 0x25, 0x23, 0x40, 0x43, 0xF0, 0x3F, 0x03, -+0xA5, 0xF6, 0xFF, 0x15, 0x03, 0x60, 0x15, 0x60, 0x4B, 0x78, 0x2B, 0xB1, 0xD2, 0xF8, 0x24, 0x31, 0x43, 0xF0, 0x40, 0x03, -+0xC2, 0xF8, 0x24, 0x31, 0x38, 0xBD, 0x12, 0x4B, 0x00, 0x22, 0x1A, 0x70, 0x9B, 0xE7, 0xFD, 0xF7, 0xD5, 0xF9, 0x7C, 0xE7, -+0x03, 0x20, 0xEE, 0xF7, 0x8B, 0xFC, 0x7D, 0xE7, 0x3C, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x34, 0x36, 0x17, 0x00, -+0x2C, 0x19, 0x17, 0x00, 0xF0, 0x00, 0x32, 0x40, 0x80, 0x04, 0x32, 0x40, 0x20, 0x04, 0x32, 0x40, 0x10, 0x03, 0x32, 0x40, -+0x40, 0x04, 0x32, 0x40, 0x34, 0x04, 0x32, 0x40, 0x2C, 0x04, 0x32, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x01, 0x32, 0x40, -+0x80, 0x35, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x1C, 0x46, 0x05, 0x8C, 0x93, 0xF8, 0x62, 0x30, 0xD2, 0xF8, 0x20, 0x90, -+0x87, 0x69, 0xD0, 0xF8, 0x1C, 0xB0, 0x89, 0xB0, 0x16, 0x46, 0xAD, 0x02, 0xDD, 0xE9, 0x12, 0x20, 0xD3, 0xB9, 0xB4, 0xF8, -+0x68, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x15, 0xD0, 0xD2, 0x8B, 0xB3, 0x6A, 0x0C, 0xFB, 0x02, 0xF2, 0x05, 0x92, 0x18, 0x07, -+0x05, 0xFB, 0x0C, 0xF2, 0x06, 0x92, 0x19, 0xD0, 0x00, 0x23, 0xB7, 0xEB, 0x09, 0x0A, 0x4F, 0xF4, 0xFA, 0x76, 0x07, 0x93, -+0x05, 0x9B, 0x03, 0xF5, 0xC8, 0x73, 0xC4, 0xE9, 0x1F, 0xA3, 0x74, 0xE0, 0x00, 0x28, 0x40, 0xF0, 0xC1, 0x80, 0x06, 0x95, -+0x4F, 0xF0, 0x01, 0x0A, 0xD0, 0x8B, 0xB2, 0x6A, 0x0A, 0xFB, 0x00, 0xF0, 0x12, 0x07, 0x05, 0x90, 0x40, 0xF0, 0x32, 0x81, -+0xF2, 0x6A, 0xDF, 0xF8, 0x94, 0xC2, 0xDF, 0xF8, 0xD4, 0x82, 0xDC, 0xF8, 0x00, 0x30, 0x9F, 0x48, 0xC2, 0xF3, 0x03, 0x12, -+0x23, 0xF0, 0x7F, 0x03, 0x18, 0xF8, 0x02, 0x20, 0x02, 0xF0, 0x7F, 0x02, 0x13, 0x43, 0xCC, 0xF8, 0x00, 0x30, 0xB3, 0x6A, -+0x99, 0x4A, 0xC3, 0xF3, 0xC0, 0x13, 0x41, 0xEA, 0x03, 0x51, 0x4F, 0xF0, 0x00, 0x43, 0x01, 0x60, 0x13, 0x60, 0xBF, 0xF3, -+0x4F, 0x8F, 0x00, 0xBF, 0x13, 0x68, 0x58, 0x00, 0xFC, 0xD5, 0x93, 0x4B, 0x19, 0x68, 0xB1, 0xF9, 0x00, 0x10, 0x00, 0x29, -+0xC0, 0xF2, 0xB4, 0x80, 0x8E, 0x4A, 0x12, 0x68, 0x1F, 0xFA, 0x82, 0xFA, 0xB2, 0x6A, 0x12, 0x07, 0x40, 0xF0, 0xA3, 0x80, -+0xF2, 0x6A, 0x8C, 0x49, 0x88, 0x48, 0xD1, 0xF8, 0x00, 0xC0, 0xC2, 0xF3, 0x03, 0x12, 0x2C, 0xF0, 0x7F, 0x0C, 0x18, 0xF8, -+0x02, 0x20, 0x02, 0xF0, 0x7F, 0x02, 0x42, 0xEA, 0x0C, 0x02, 0x0A, 0x60, 0xB2, 0x6A, 0xC2, 0xF3, 0xC0, 0x12, 0x08, 0x31, -+0x12, 0x05, 0x42, 0xF0, 0x18, 0x02, 0x4F, 0xF0, 0x00, 0x46, 0x02, 0x60, 0x0E, 0x60, 0xBF, 0xF3, 0x4F, 0x8F, 0x00, 0xBF, -+0x0A, 0x68, 0x56, 0x00, 0xFC, 0xD5, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x73, 0xDB, 0x77, 0x4A, 0x94, 0xF8, -+0x62, 0x30, 0x16, 0x68, 0x00, 0x22, 0xB6, 0xB2, 0xAA, 0xEB, 0x06, 0x0A, 0x07, 0x92, 0xB7, 0xEB, 0x09, 0x09, 0x19, 0xEB, -+0x0A, 0x0A, 0x00, 0x2B, 0x84, 0xD0, 0x4F, 0xEA, 0xE5, 0x79, 0x2A, 0x46, 0x4B, 0x46, 0x38, 0x46, 0x59, 0x46, 0x1F, 0xF0, -+0x67, 0xFB, 0xBA, 0x1B, 0x02, 0x92, 0x07, 0x9A, 0x00, 0xFB, 0x09, 0xF3, 0x6B, 0xEB, 0x02, 0x02, 0x05, 0xFB, 0x01, 0x33, -+0x03, 0x92, 0xA0, 0xFB, 0x05, 0x01, 0x19, 0x44, 0xDD, 0xE9, 0x02, 0x23, 0x99, 0x42, 0x08, 0xBF, 0x90, 0x42, 0x38, 0xBF, -+0xCD, 0xE9, 0x02, 0x01, 0x64, 0x4B, 0x06, 0x9A, 0x1B, 0x68, 0xDD, 0xE9, 0x02, 0x67, 0xB6, 0x18, 0x99, 0x01, 0x34, 0xD4, -+0x05, 0x9B, 0xF1, 0x1A, 0xA1, 0xF5, 0xC8, 0x71, 0x5F, 0x4F, 0x60, 0x4B, 0x3E, 0x69, 0x1B, 0x68, 0xF6, 0x1A, 0x0E, 0x44, -+0xE9, 0xF7, 0xDC, 0xFD, 0x3B, 0x69, 0xF3, 0x1A, 0xA3, 0xF5, 0x86, 0x53, 0x0C, 0x3B, 0x18, 0x1A, 0x00, 0x28, 0x63, 0x6A, -+0xB8, 0xBF, 0x76, 0x19, 0xB3, 0x42, 0x24, 0xD0, 0x57, 0x4B, 0x1A, 0x6A, 0xA2, 0x42, 0x43, 0xD0, 0x56, 0x4D, 0x31, 0x46, -+0xD5, 0xF8, 0xE0, 0x31, 0x04, 0xF1, 0x18, 0x00, 0x98, 0x47, 0xD5, 0xF8, 0xA8, 0x30, 0x20, 0x46, 0x09, 0xB0, 0xBD, 0xE8, -+0xF0, 0x4F, 0x18, 0x47, 0x90, 0xF8, 0x02, 0xA0, 0xBA, 0xF1, 0x00, 0x0F, 0x01, 0xD1, 0x90, 0xF8, 0x03, 0xA0, 0x05, 0xFB, -+0x0A, 0xF0, 0x06, 0x90, 0x36, 0xE7, 0x4B, 0x49, 0x05, 0x9B, 0xC9, 0x1A, 0xA1, 0xEB, 0x0A, 0x0A, 0x0A, 0xEB, 0x06, 0x01, -+0xC6, 0xE7, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x0B, 0x68, 0x58, 0x00, 0x88, 0xD4, 0x45, 0x49, 0x45, 0x48, 0x4F, 0xF4, -+0xBE, 0x72, 0x0D, 0xF0, 0xD7, 0xF9, 0x00, 0x22, 0x94, 0xF8, 0x62, 0x30, 0x07, 0x92, 0xAA, 0xF5, 0xFA, 0x7A, 0x4F, 0xF4, -+0xFA, 0x76, 0x82, 0xE7, 0x12, 0x68, 0x51, 0x00, 0x3F, 0xF5, 0x48, 0xAF, 0x3B, 0x49, 0x3C, 0x48, 0x4F, 0xF4, 0xBE, 0x72, -+0x0D, 0xF0, 0xC4, 0xF9, 0x4F, 0xF4, 0xFA, 0x7A, 0x2F, 0x4B, 0x41, 0xE7, 0x30, 0x4A, 0x66, 0x62, 0x12, 0x68, 0x92, 0x01, -+0xB6, 0xD4, 0x36, 0x4A, 0x36, 0x4D, 0x12, 0x68, 0x93, 0xF8, 0x24, 0x10, 0x41, 0xF2, 0x13, 0x30, 0xC2, 0xF3, 0x07, 0x42, -+0x2A, 0x54, 0x00, 0x29, 0x32, 0xD1, 0x32, 0x4A, 0x32, 0x49, 0x12, 0x68, 0x09, 0x68, 0x41, 0xF2, 0x14, 0x30, 0xD2, 0xB2, -+0x2A, 0x54, 0x01, 0x22, 0x83, 0xF8, 0x24, 0x20, 0x0B, 0x78, 0x93, 0x42, 0x06, 0xD1, 0x2D, 0x49, 0x2D, 0x4A, 0x0B, 0x60, -+0x13, 0x68, 0x43, 0xF0, 0x01, 0x03, 0x13, 0x60, 0x41, 0xF2, 0x13, 0x32, 0x41, 0xF2, 0x14, 0x33, 0xA8, 0x5C, 0xE9, 0x5C, -+0x88, 0x42, 0x1D, 0xD2, 0x17, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x0F, 0xDA, 0x41, 0xF2, 0x13, 0x32, -+0x41, 0xF2, 0x14, 0x33, 0xAA, 0x5C, 0xEB, 0x5C, 0x9A, 0x42, 0x07, 0xD3, 0x18, 0x49, 0x20, 0x48, 0x15, 0x4D, 0x40, 0xF2, -+0xD7, 0x12, 0x0D, 0xF0, 0xAF, 0xF9, 0x7E, 0xE7, 0x12, 0x4D, 0x7C, 0xE7, 0x00, 0x22, 0x4F, 0xF4, 0xFA, 0x76, 0x07, 0x92, -+0x92, 0x46, 0x28, 0xE7, 0x12, 0x4E, 0x14, 0x48, 0xA9, 0x5C, 0xEA, 0x5C, 0x33, 0x68, 0x06, 0x68, 0x16, 0x48, 0xF6, 0xB2, -+0x1B, 0x0C, 0x00, 0x96, 0x0C, 0xF0, 0x20, 0xFF, 0xD4, 0xE7, 0x00, 0xBF, 0x60, 0x81, 0x32, 0x40, 0x6C, 0x81, 0x32, 0x40, -+0x38, 0x36, 0x17, 0x00, 0x64, 0x81, 0x32, 0x40, 0x4C, 0x00, 0x32, 0x40, 0x00, 0x10, 0x50, 0x40, 0xA4, 0x80, 0x32, 0x40, -+0x1C, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0xFE, 0xFF, 0xFF, 0x70, 0x79, 0x15, 0x00, 0x04, 0x99, 0x15, 0x00, -+0x44, 0x80, 0x32, 0x40, 0x00, 0x40, 0x1E, 0x00, 0x90, 0x00, 0x32, 0x40, 0x74, 0x36, 0x17, 0x00, 0x70, 0x80, 0x32, 0x40, -+0x74, 0x80, 0x32, 0x40, 0x3C, 0x99, 0x15, 0x00, 0x28, 0x99, 0x15, 0x00, 0x40, 0xA9, 0x15, 0x00, 0x0B, 0x02, 0x10, 0xB5, -+0x04, 0x46, 0x03, 0xD5, 0x00, 0x23, 0x80, 0xF8, 0x78, 0x30, 0x10, 0xBD, 0x4F, 0xF4, 0x80, 0x60, 0x04, 0x49, 0x0C, 0xF0, -+0x37, 0xFF, 0x04, 0x4B, 0x20, 0x46, 0xD3, 0xF8, 0xBC, 0x31, 0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0xB0, 0x99, 0x15, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0x70, 0x93, 0xD9, 0xF8, 0x20, 0xB0, 0x83, 0xB0, 0x4F, 0xF4, -+0x00, 0x20, 0x0B, 0xF0, 0x79, 0xFC, 0xBB, 0xF1, 0x00, 0x0F, 0x00, 0xF0, 0xF5, 0x80, 0xBA, 0x4C, 0xDF, 0xF8, 0x58, 0xA3, -+0xA1, 0x7F, 0xB9, 0x4F, 0xDF, 0xF8, 0x54, 0x83, 0xB8, 0x4E, 0x00, 0x29, 0x00, 0xF0, 0xEA, 0x80, 0x08, 0x07, 0x0E, 0xD5, -+0xB6, 0x4B, 0xDB, 0xF8, 0x70, 0x00, 0x1B, 0x68, 0xDA, 0xF8, 0x10, 0x20, 0x5B, 0x68, 0x03, 0x44, 0x9B, 0x1A, 0x00, 0x2B, -+0xC0, 0xF2, 0xCB, 0x80, 0x01, 0xF0, 0xF7, 0x01, 0xA1, 0x77, 0x4A, 0x07, 0x00, 0xF1, 0x99, 0x80, 0x8B, 0x07, 0x15, 0xD5, -+0xDB, 0xF8, 0x04, 0x30, 0x23, 0xF0, 0x02, 0x03, 0xCB, 0xF8, 0x04, 0x30, 0x99, 0xF8, 0x1D, 0x30, 0x05, 0x2B, 0x08, 0xD1, -+0xA8, 0x4D, 0xA9, 0x48, 0xD5, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0x00, 0x23, 0xA1, 0x7F, 0x89, 0xF8, 0x1D, 0x30, 0x01, 0xF0, -+0xFD, 0x01, 0xA1, 0x77, 0xCD, 0x07, 0x2E, 0xD5, 0x33, 0x68, 0x58, 0x01, 0x40, 0xF1, 0xA3, 0x80, 0x31, 0x68, 0x09, 0x0C, -+0x11, 0xF4, 0x7C, 0x7F, 0x00, 0xF0, 0xAA, 0x80, 0x9E, 0x4A, 0x10, 0x39, 0x01, 0xF0, 0xFF, 0x01, 0x4F, 0xF4, 0x1E, 0x73, -+0x03, 0xFB, 0x01, 0x23, 0x93, 0xF8, 0x25, 0x20, 0x00, 0x2A, 0x00, 0xF0, 0xA1, 0x80, 0x99, 0x4A, 0x93, 0xF8, 0x22, 0x10, -+0x13, 0x68, 0x98, 0x4A, 0xB3, 0xF9, 0x00, 0x30, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x01, 0x22, 0x00, 0x2B, 0x00, 0x92, -+0xC0, 0xF2, 0x9F, 0x80, 0x3B, 0x68, 0x13, 0xF4, 0xE0, 0x2F, 0x00, 0xF0, 0xA8, 0x80, 0xA1, 0x7F, 0x01, 0xF0, 0xFE, 0x01, -+0xA1, 0x77, 0x8A, 0x06, 0x9D, 0xD5, 0x8E, 0x4E, 0x8E, 0x49, 0x35, 0x68, 0xC5, 0xF3, 0x41, 0x17, 0x3A, 0x46, 0x02, 0x20, -+0x0C, 0xF0, 0xAA, 0xFE, 0x00, 0x23, 0xC5, 0xF3, 0x47, 0x15, 0x8B, 0xF8, 0x78, 0x30, 0x00, 0x2F, 0x40, 0xF0, 0xB2, 0x80, -+0x87, 0x4B, 0x80, 0x4E, 0x5A, 0x78, 0x1A, 0x70, 0x86, 0x4A, 0x87, 0x4D, 0x13, 0x68, 0x23, 0xF4, 0x00, 0x73, 0x13, 0x60, -+0xDB, 0xF8, 0x04, 0x30, 0xD6, 0xF8, 0xD8, 0x21, 0x23, 0xF0, 0x01, 0x03, 0xCB, 0xF8, 0x04, 0x30, 0x0B, 0xF1, 0x28, 0x00, -+0x90, 0x47, 0x2A, 0x68, 0x13, 0x78, 0x02, 0x2B, 0x00, 0xF0, 0x24, 0x81, 0x78, 0x49, 0x0B, 0x68, 0x23, 0xF0, 0x01, 0x03, -+0x0B, 0x60, 0x13, 0x78, 0x01, 0x2B, 0x12, 0xD1, 0x01, 0xF5, 0xFF, 0x41, 0x34, 0x31, 0x78, 0x4A, 0xDA, 0xF8, 0x10, 0x30, -+0x08, 0x68, 0xB2, 0xF8, 0xB2, 0x10, 0xD6, 0xF8, 0xE0, 0x21, 0x03, 0xEB, 0x40, 0x13, 0x59, 0x1A, 0x0B, 0xF1, 0x18, 0x00, -+0x90, 0x47, 0x2B, 0x68, 0x1B, 0x78, 0x02, 0x2B, 0x00, 0xF0, 0x00, 0x81, 0xA1, 0x7F, 0x01, 0xF0, 0xDF, 0x01, 0xA1, 0x77, -+0x4B, 0xE7, 0x6D, 0x49, 0x61, 0x4D, 0x02, 0x20, 0x0C, 0xF0, 0x60, 0xFE, 0x6B, 0x49, 0x63, 0x68, 0x0A, 0x68, 0x22, 0xF0, -+0x04, 0x02, 0x0A, 0x60, 0x22, 0x68, 0x43, 0xF4, 0x00, 0x73, 0x1A, 0x43, 0x4A, 0x61, 0xD5, 0xF8, 0x98, 0x14, 0x63, 0x60, -+0x9B, 0xF8, 0x63, 0x00, 0xD5, 0xF8, 0x94, 0x34, 0x5A, 0x46, 0x98, 0x47, 0x3B, 0x68, 0xA1, 0x7F, 0x23, 0xF0, 0x7C, 0x73, -+0x3B, 0x60, 0xD8, 0xF8, 0x00, 0x30, 0x01, 0xF0, 0xFB, 0x01, 0x43, 0xF4, 0x80, 0x03, 0xC8, 0xF8, 0x00, 0x30, 0xA1, 0x77, -+0x3E, 0xE7, 0x5B, 0x48, 0x0C, 0xF0, 0xEA, 0xFD, 0x7F, 0xE7, 0x00, 0x22, 0x9B, 0xF8, 0x6C, 0x00, 0x11, 0x46, 0xF8, 0xF7, -+0x01, 0xFB, 0x60, 0xB1, 0xA1, 0x7F, 0x2B, 0xE7, 0x55, 0x48, 0x0C, 0xF0, 0xDD, 0xFD, 0x72, 0xE7, 0x54, 0x48, 0x0C, 0xF0, -+0xD9, 0xFD, 0x6E, 0xE7, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xDA, 0xF8, 0x10, 0x30, 0xA1, 0x7F, 0xCB, 0xF8, 0x70, 0x30, -+0x1A, 0xE7, 0x93, 0x45, 0x3F, 0xF4, 0x5E, 0xAF, 0x4D, 0x49, 0x4E, 0x48, 0x40, 0xF2, 0x22, 0x32, 0x0D, 0xF0, 0x40, 0xF8, -+0x3B, 0x68, 0x13, 0xF4, 0xE0, 0x2F, 0x7F, 0xF4, 0x58, 0xAF, 0x32, 0x68, 0x33, 0x68, 0x49, 0x49, 0xD0, 0x0F, 0xC3, 0xF3, -+0x80, 0x73, 0x05, 0x46, 0x02, 0x46, 0x02, 0x20, 0x01, 0x93, 0x0C, 0xF0, 0x05, 0xFE, 0x01, 0x9B, 0x53, 0xEA, 0x05, 0x02, -+0x28, 0x46, 0x3F, 0xF4, 0x46, 0xAF, 0x2F, 0x4D, 0x00, 0x9A, 0x19, 0x46, 0xD5, 0xF8, 0x3C, 0x32, 0x98, 0x47, 0x33, 0x68, -+0x23, 0xF0, 0x00, 0x43, 0x33, 0x60, 0x33, 0x68, 0x23, 0xF0, 0x80, 0x43, 0x33, 0x60, 0x36, 0xE7, 0xDA, 0xF8, 0x10, 0x10, -+0x01, 0xF5, 0x9C, 0x51, 0x32, 0x46, 0x08, 0x31, 0x05, 0xE0, 0xDA, 0xF8, 0x10, 0x30, 0xCB, 0x1A, 0x00, 0x2B, 0xC0, 0xF2, -+0xC2, 0x80, 0x13, 0x68, 0x1B, 0x07, 0xF6, 0xD5, 0xDF, 0xF8, 0x90, 0x80, 0xD8, 0xF8, 0x00, 0x30, 0x23, 0xF0, 0x08, 0x03, -+0xC8, 0xF8, 0x00, 0x30, 0xD8, 0xF8, 0x00, 0x30, 0xDE, 0x06, 0x19, 0xD5, 0x2C, 0x49, 0x19, 0x4E, 0x02, 0x20, 0x0C, 0xF0, -+0xCF, 0xFD, 0x2B, 0x4B, 0xDF, 0xF8, 0x74, 0xC0, 0x1A, 0x68, 0xD6, 0xF8, 0x3C, 0x32, 0x12, 0x0C, 0x8C, 0xF8, 0x00, 0x20, -+0x05, 0xF0, 0x01, 0x01, 0x78, 0x08, 0x5A, 0x46, 0x98, 0x47, 0xD8, 0xF8, 0x00, 0x30, 0x23, 0xF0, 0x10, 0x03, 0xC8, 0xF8, -+0x00, 0x30, 0x1B, 0xE7, 0x21, 0x4B, 0x22, 0x49, 0x0B, 0x4E, 0x01, 0x25, 0x1D, 0x60, 0x02, 0x20, 0x0C, 0xF0, 0xB2, 0xFD, -+0x0F, 0x4A, 0x1F, 0x49, 0x53, 0x78, 0x0D, 0x60, 0xAB, 0x42, 0x94, 0xBF, 0x00, 0x23, 0x01, 0x23, 0x13, 0x70, 0x09, 0xE7, -+0x98, 0x9C, 0x17, 0x00, 0x74, 0x00, 0x32, 0x40, 0x70, 0x00, 0x32, 0x40, 0xC8, 0x35, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x28, 0x9E, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x8C, 0x00, 0x32, 0x40, -+0x20, 0x9A, 0x15, 0x00, 0x13, 0x53, 0x1E, 0x00, 0x90, 0xB3, 0x33, 0x40, 0x74, 0x36, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, -+0xC0, 0x99, 0x15, 0x00, 0x4C, 0x00, 0x32, 0x40, 0xC4, 0x99, 0x15, 0x00, 0xDC, 0x99, 0x15, 0x00, 0xF0, 0x99, 0x15, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x04, 0x9A, 0x15, 0x00, 0x14, 0x9A, 0x15, 0x00, 0x40, 0x9A, 0x15, 0x00, 0x44, 0x80, 0x32, 0x40, -+0x64, 0x85, 0x32, 0x40, 0x4C, 0x9A, 0x15, 0x00, 0x68, 0x85, 0x32, 0x40, 0x1C, 0x9E, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, -+0x6C, 0x00, 0x32, 0x40, 0x36, 0x4B, 0x30, 0x22, 0x1A, 0x60, 0xF7, 0xF7, 0x35, 0xF9, 0xF9, 0xE6, 0xEF, 0xF3, 0x10, 0x83, -+0xD8, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x32, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x31, 0x4B, 0x2F, 0x4F, 0x1A, 0x68, 0x01, 0x32, -+0x1A, 0x60, 0x00, 0x21, 0x3A, 0x68, 0x39, 0x60, 0x02, 0xF0, 0x0F, 0x08, 0xDA, 0xF8, 0x10, 0x20, 0x31, 0x46, 0x16, 0x46, -+0x0A, 0x46, 0x47, 0xF2, 0x30, 0x50, 0x04, 0xE0, 0xDA, 0xF8, 0x10, 0x10, 0x89, 0x1B, 0x81, 0x42, 0x1B, 0xD8, 0x39, 0x68, -+0x09, 0x07, 0xF7, 0xD1, 0x25, 0x48, 0x26, 0x49, 0xD0, 0xF8, 0x00, 0xC0, 0x0F, 0x68, 0x16, 0x46, 0xDA, 0xF8, 0x10, 0x20, -+0xB8, 0xF1, 0x00, 0x0F, 0x1A, 0xD1, 0x22, 0x4A, 0x04, 0x21, 0x11, 0x60, 0x1A, 0x68, 0x32, 0xB1, 0x1B, 0x49, 0x01, 0x3A, -+0x1A, 0x60, 0x0B, 0x68, 0x0A, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x2A, 0x68, 0xA0, 0xE6, 0x1C, 0x49, 0x00, 0x92, 0x02, 0x20, -+0x0C, 0xF0, 0x24, 0xFD, 0x15, 0x4B, 0x00, 0x9A, 0xD3, 0xE7, 0x19, 0x49, 0x02, 0x20, 0x0C, 0xF0, 0x1D, 0xFD, 0x3B, 0xE7, -+0x07, 0xEA, 0x0C, 0x07, 0x7F, 0x07, 0xE0, 0xD4, 0xCD, 0xE9, 0x00, 0x16, 0x80, 0x46, 0x16, 0x46, 0x01, 0xE0, 0x7A, 0x07, -+0x12, 0xD4, 0x00, 0x9A, 0xD8, 0xF8, 0x00, 0x70, 0x12, 0x68, 0xDA, 0xF8, 0x10, 0x10, 0x47, 0xF2, 0x30, 0x50, 0x89, 0x1B, -+0x81, 0x42, 0x07, 0xEA, 0x02, 0x07, 0xF0, 0xD9, 0x0B, 0x49, 0x02, 0x20, 0x0C, 0xF0, 0x00, 0xFD, 0x03, 0x4B, 0xEA, 0xE7, -+0x01, 0x9E, 0xC4, 0xE7, 0x38, 0x00, 0x32, 0x40, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x6C, 0x80, 0x32, 0x40, -+0x74, 0x80, 0x32, 0x40, 0x70, 0x80, 0x32, 0x40, 0x5C, 0x9A, 0x15, 0x00, 0x2C, 0x9A, 0x15, 0x00, 0x68, 0x9A, 0x15, 0x00, -+0x10, 0xB5, 0x00, 0x20, 0x0B, 0xF0, 0xD0, 0xF8, 0x01, 0x28, 0x05, 0xD1, 0x05, 0x4B, 0xBD, 0xE8, 0x10, 0x40, 0xD3, 0xF8, -+0x60, 0x31, 0x18, 0x47, 0x00, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x08, 0x46, 0x0B, 0xF0, 0x1A, 0xB8, 0x88, 0x1A, 0x17, 0x00, -+0x03, 0x4B, 0x30, 0x22, 0x1A, 0x60, 0x01, 0x21, 0x00, 0x20, 0x0B, 0xF0, 0x11, 0xB8, 0x00, 0xBF, 0x38, 0x00, 0x32, 0x40, -+0xF8, 0xB5, 0x90, 0xF8, 0x64, 0x30, 0x00, 0x2B, 0x46, 0xD0, 0x90, 0xF8, 0x8A, 0x30, 0x04, 0x46, 0x00, 0x2B, 0x42, 0xD1, -+0x3D, 0x4E, 0x3E, 0x49, 0x94, 0xF8, 0x6C, 0x30, 0x3D, 0x4A, 0x67, 0x6A, 0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, 0x03, 0x13, -+0x9D, 0x68, 0x13, 0x6A, 0xA3, 0x42, 0x3D, 0x44, 0x54, 0xD0, 0xD6, 0xF8, 0xE0, 0x31, 0x29, 0x46, 0x04, 0xF1, 0x18, 0x00, -+0x98, 0x47, 0x20, 0x46, 0xFF, 0xF7, 0x82, 0xF8, 0xD4, 0xF8, 0x80, 0x10, 0xD6, 0xF8, 0x14, 0x32, 0x39, 0x44, 0x20, 0x46, -+0x98, 0x47, 0xD6, 0xF8, 0xA4, 0x30, 0x2A, 0x46, 0x39, 0x46, 0x20, 0x46, 0x98, 0x47, 0xD8, 0xB9, 0x94, 0xF8, 0x78, 0x30, -+0x62, 0x68, 0x2C, 0x49, 0x01, 0x33, 0xDB, 0xB2, 0x42, 0xF0, 0x01, 0x02, 0x09, 0x68, 0x84, 0xF8, 0x78, 0x30, 0x62, 0x60, -+0x0A, 0x78, 0x93, 0x42, 0x21, 0xD8, 0x39, 0xD0, 0xB3, 0xEB, 0x52, 0x0F, 0x26, 0xD0, 0xB3, 0xEB, 0x92, 0x0F, 0x4F, 0xEA, -+0x92, 0x01, 0x21, 0xD0, 0x01, 0xEB, 0x41, 0x01, 0x8B, 0x42, 0x1D, 0xD0, 0xF8, 0xBD, 0x90, 0xF8, 0x8C, 0x20, 0x00, 0x2A, -+0xB8, 0xD0, 0x01, 0x3B, 0xDB, 0xB2, 0x01, 0x2B, 0x80, 0xF8, 0x8A, 0x30, 0x29, 0xD9, 0x02, 0x2B, 0x16, 0x4E, 0xB0, 0xD1, -+0x90, 0xF8, 0x63, 0x00, 0xD6, 0xF8, 0xC0, 0x31, 0x00, 0x21, 0x98, 0x47, 0xA9, 0xE7, 0xD6, 0xF8, 0x64, 0x11, 0x94, 0xF8, -+0x6C, 0x00, 0x22, 0x46, 0xBD, 0xE8, 0xF8, 0x40, 0xF8, 0xF7, 0x30, 0xB9, 0xBD, 0xE8, 0xF8, 0x40, 0xEA, 0xF7, 0x5A, 0xBE, -+0x0F, 0x4B, 0x65, 0x62, 0x93, 0xF8, 0xB5, 0x30, 0x00, 0x2B, 0xAA, 0xD1, 0x0D, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x02, 0x2B, -+0x9F, 0xD1, 0xA4, 0xE7, 0xEA, 0xF7, 0x4C, 0xFE, 0x20, 0x46, 0xBD, 0xE8, 0xF8, 0x40, 0x06, 0xF0, 0x47, 0xBD, 0xBD, 0xE8, -+0xF8, 0x40, 0xFF, 0xF7, 0x9B, 0xB8, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, -+0xC8, 0x35, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x74, 0x36, 0x17, 0x00, 0x38, 0x4B, 0x2D, 0xE9, 0xF0, 0x47, 0x9C, 0x68, -+0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x35, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x34, 0x4D, 0x2B, 0x68, -+0x04, 0x20, 0x01, 0x33, 0x2B, 0x60, 0xF6, 0xF7, 0xF1, 0xFC, 0x4F, 0xF0, 0x80, 0x41, 0x04, 0x20, 0xF6, 0xF7, 0x8C, 0xFD, -+0x2B, 0x68, 0x2B, 0xB1, 0x2C, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x00, 0x2B, 0x4C, 0xD0, 0xDF, 0xF8, 0xB4, 0x80, -+0x00, 0x2C, 0x43, 0xD0, 0x29, 0x4F, 0x2A, 0x4E, 0x40, 0xF6, 0xE7, 0x35, 0x02, 0xE0, 0x24, 0x68, 0x00, 0x2C, 0x3B, 0xD0, -+0x94, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0xF8, 0xD1, 0x94, 0xF8, 0xD5, 0x30, 0x01, 0x3B, 0xDB, 0xB2, 0x84, 0xF8, 0xD5, 0x30, -+0x00, 0x2B, 0xF0, 0xD1, 0x94, 0xF8, 0xD4, 0x30, 0x84, 0xF8, 0xD5, 0x30, 0x20, 0x46, 0xFE, 0xF7, 0xD3, 0xFF, 0x61, 0x6A, -+0xD8, 0xF8, 0x14, 0x32, 0x01, 0xF6, 0xE8, 0x31, 0x20, 0x46, 0x98, 0x47, 0x3B, 0x68, 0xB4, 0xF8, 0xD2, 0x20, 0x59, 0x01, -+0xB5, 0xEB, 0x43, 0x1F, 0x28, 0xBF, 0x01, 0xEB, 0x82, 0x21, 0x32, 0x69, 0x23, 0x6C, 0xA2, 0xF6, 0xE8, 0x39, 0x89, 0x44, -+0x20, 0x46, 0x4A, 0x46, 0x1B, 0xB1, 0xD8, 0xF8, 0xA4, 0x30, 0x61, 0x6A, 0x98, 0x47, 0x94, 0xF8, 0xC0, 0x34, 0x04, 0xF1, -+0x18, 0x00, 0x49, 0x46, 0x00, 0x2B, 0xC6, 0xD0, 0xD8, 0xF8, 0xE0, 0x31, 0x98, 0x47, 0x24, 0x68, 0x00, 0x2C, 0xC3, 0xD1, -+0xD8, 0xF8, 0x84, 0x31, 0xBD, 0xE8, 0xF0, 0x47, 0x18, 0x47, 0x00, 0x2A, 0xB0, 0xD0, 0x62, 0xB6, 0xAE, 0xE7, 0x00, 0xBF, -+0x00, 0x88, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x40, 0x80, 0x32, 0x40, 0x00, 0x10, 0x50, 0x40, -+0x88, 0x1A, 0x17, 0x00, 0x08, 0xF0, 0x4A, 0xBE, 0x14, 0x4B, 0x15, 0x4A, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x10, 0xB5, -+0x14, 0x68, 0x00, 0x2B, 0x04, 0xF0, 0x40, 0x74, 0x14, 0xDB, 0x20, 0x46, 0x0B, 0xF0, 0x04, 0xF9, 0x0F, 0x4B, 0x9B, 0x7C, -+0x3B, 0xB9, 0x0F, 0x4A, 0x0F, 0x4B, 0x10, 0x6A, 0xD3, 0xF8, 0xCC, 0x31, 0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0x0C, 0x4B, -+0x20, 0x46, 0xD3, 0xF8, 0x68, 0x31, 0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0xB4, 0xF1, 0x40, 0x7F, 0xE7, 0xD1, 0x08, 0x49, -+0x08, 0x48, 0x4F, 0xF4, 0x9D, 0x62, 0x0C, 0xF0, 0xBB, 0xFD, 0xE0, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x80, 0xB6, 0x17, 0x00, -+0x00, 0x88, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x78, 0x9A, 0x15, 0x00, -+0xF0, 0xB5, 0x2D, 0x4E, 0x2D, 0x4B, 0xDF, 0xF8, 0xC8, 0xE0, 0xDF, 0xF8, 0xC8, 0xC0, 0x2C, 0x4F, 0x4F, 0xF4, 0x1E, 0x72, -+0x02, 0xFB, 0x00, 0x62, 0x15, 0x8D, 0xD4, 0x8C, 0x44, 0xEA, 0x05, 0x44, 0x1C, 0x60, 0x52, 0x8D, 0x27, 0x4D, 0x5A, 0x60, -+0x00, 0x24, 0x27, 0x4A, 0xCE, 0xF8, 0x00, 0x40, 0x4F, 0xF0, 0x00, 0x53, 0xCC, 0xF8, 0x00, 0x40, 0x2C, 0x60, 0x00, 0xF1, -+0x10, 0x05, 0x3C, 0x60, 0xEC, 0xB2, 0x13, 0x60, 0x13, 0x68, 0x9F, 0x00, 0xFC, 0xD4, 0xDD, 0x00, 0x26, 0xD4, 0x15, 0x68, -+0xC5, 0xF3, 0x07, 0x43, 0xA3, 0x42, 0x4F, 0xEA, 0x15, 0x45, 0x1F, 0xD0, 0xED, 0xB2, 0xDF, 0xF8, 0x5C, 0xE0, 0xDF, 0xF8, -+0x68, 0xC0, 0x18, 0x4F, 0x2D, 0x04, 0x4F, 0xF0, 0xFF, 0x33, 0x45, 0xF0, 0x80, 0x45, 0xCE, 0xF8, 0x00, 0x30, 0xCC, 0xF8, -+0x00, 0x30, 0x15, 0x60, 0x3B, 0x68, 0x5A, 0x00, 0xFC, 0xD4, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x00, 0x63, 0x0C, 0x48, -+0x1D, 0x8D, 0xDA, 0x8C, 0x42, 0xEA, 0x05, 0x42, 0x02, 0x60, 0x0D, 0x4A, 0x5B, 0x8D, 0x13, 0x60, 0x0B, 0x01, 0x43, 0xEA, -+0x04, 0x43, 0x09, 0x4A, 0x43, 0xF0, 0x80, 0x43, 0x43, 0xF0, 0x02, 0x03, 0x13, 0x60, 0x13, 0x68, 0x5B, 0x00, 0xFC, 0xD4, -+0x20, 0x46, 0xF0, 0xBD, 0x68, 0x65, 0x17, 0x00, 0xBC, 0x00, 0x32, 0x40, 0xB8, 0x00, 0x32, 0x40, 0xB4, 0x00, 0x32, 0x40, -+0xC4, 0x00, 0x32, 0x40, 0xC0, 0x00, 0x32, 0x40, 0xAC, 0x00, 0x32, 0x40, 0xB0, 0x00, 0x32, 0x40, 0x2D, 0xE9, 0xF0, 0x41, -+0x82, 0xB0, 0x47, 0x78, 0x90, 0xF8, 0x29, 0x60, 0x01, 0x23, 0x8D, 0xF8, 0x06, 0x30, 0xFF, 0x2F, 0x4F, 0xF0, 0x00, 0x03, -+0x04, 0x46, 0x00, 0xF1, 0x04, 0x08, 0x8D, 0xF8, 0x07, 0x30, 0x00, 0xF0, 0x83, 0x80, 0x74, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x73, 0xDB, 0x3A, 0x46, 0x94, 0xF8, 0x28, 0x30, 0x70, 0x49, 0x4F, 0xF4, 0x80, 0x70, 0x0C, 0xF0, -+0xF5, 0xFA, 0x07, 0xF1, 0x10, 0x05, 0x6E, 0x4B, 0xED, 0xB2, 0xD3, 0xF8, 0x18, 0x33, 0x29, 0x46, 0x20, 0x46, 0x98, 0x47, -+0x6B, 0x4A, 0x6C, 0x48, 0x6C, 0x49, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x07, 0x22, 0x17, 0x8D, 0xD3, 0x8C, 0x43, 0xEA, -+0x07, 0x43, 0x03, 0x60, 0x53, 0x8D, 0x0B, 0x60, 0x0D, 0xF1, 0x06, 0x03, 0x0D, 0xF1, 0x07, 0x02, 0x94, 0xF8, 0x28, 0x00, -+0x41, 0x46, 0xFF, 0xF7, 0x7B, 0xF8, 0x63, 0x4B, 0xA2, 0x68, 0x1A, 0x60, 0xE2, 0x68, 0x5A, 0x60, 0x22, 0x69, 0x9A, 0x60, -+0x62, 0x69, 0xDA, 0x60, 0x9D, 0xF8, 0x07, 0x30, 0x04, 0x2B, 0x65, 0xD0, 0x5D, 0x4A, 0x12, 0x68, 0x02, 0x2B, 0x12, 0x78, -+0x1F, 0xD1, 0xD1, 0x07, 0x00, 0xF1, 0x85, 0x80, 0x5A, 0x48, 0x01, 0x68, 0x21, 0xF0, 0x01, 0x01, 0x01, 0x60, 0x92, 0x07, -+0x17, 0xD5, 0x9D, 0xF8, 0x06, 0x00, 0x94, 0xF8, 0x2A, 0x10, 0x56, 0x4A, 0x2B, 0x04, 0x43, 0xEA, 0x00, 0x33, 0x43, 0xEA, -+0x06, 0x13, 0x43, 0xEA, 0x81, 0x03, 0x43, 0xF0, 0x80, 0x43, 0x13, 0x60, 0x13, 0x68, 0x5C, 0x00, 0xFC, 0xD4, 0x28, 0x46, -+0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x97, 0x07, 0x6F, 0xD4, 0x9D, 0xF8, 0x06, 0x00, 0x94, 0xF8, 0x2A, 0x10, 0x4A, 0x4A, -+0x1B, 0x02, 0x43, 0xEA, 0x00, 0x33, 0x43, 0xEA, 0x05, 0x43, 0x43, 0xEA, 0x06, 0x13, 0x43, 0xEA, 0x81, 0x03, 0x43, 0xF0, -+0x80, 0x43, 0x13, 0x60, 0x13, 0x68, 0x59, 0x00, 0xFC, 0xD4, 0x28, 0x46, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x0D, 0x2F, -+0x89, 0xD9, 0x40, 0x49, 0x40, 0x48, 0x40, 0xF2, 0x5C, 0x52, 0x0C, 0xF0, 0xAB, 0xFC, 0x82, 0xE7, 0x90, 0xF8, 0x28, 0x30, -+0x05, 0x2B, 0x4E, 0xD0, 0x34, 0x48, 0x35, 0x4A, 0x25, 0x78, 0x3B, 0x49, 0x4F, 0xF0, 0xFF, 0x33, 0x03, 0x60, 0x13, 0x60, -+0x94, 0xF8, 0x28, 0x30, 0x94, 0xF8, 0x29, 0x20, 0x4F, 0xF4, 0x80, 0x70, 0x0C, 0xF0, 0x6C, 0xFA, 0x05, 0xEB, 0x86, 0x05, -+0x29, 0x4B, 0xED, 0xB2, 0xD3, 0xF8, 0x48, 0x34, 0x29, 0x46, 0x20, 0x46, 0x98, 0x47, 0x83, 0xE7, 0x30, 0x4A, 0xA1, 0x69, -+0x11, 0x60, 0xE1, 0x69, 0x51, 0x60, 0x21, 0x6A, 0x91, 0x60, 0x27, 0x4A, 0x2D, 0x49, 0x60, 0x6A, 0x12, 0x68, 0x08, 0x60, -+0x12, 0x78, 0x90, 0x07, 0xB1, 0xD5, 0x9D, 0xF8, 0x06, 0x00, 0x94, 0xF8, 0x2A, 0x10, 0x23, 0x4A, 0x1B, 0x02, 0x43, 0xEA, -+0x00, 0x33, 0x43, 0xEA, 0x05, 0x43, 0x43, 0xEA, 0x06, 0x13, 0x43, 0xEA, 0x81, 0x03, 0x43, 0xF0, 0x80, 0x43, 0x13, 0x60, -+0x13, 0x68, 0x58, 0x00, 0xFC, 0xD4, 0x28, 0x46, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x1D, 0x49, 0xA0, 0x69, 0x08, 0x60, -+0xE0, 0x69, 0x48, 0x60, 0x20, 0x6A, 0x88, 0x60, 0x60, 0x6A, 0xC8, 0x60, 0x75, 0xE7, 0x5A, 0x1E, 0x01, 0x2A, 0xDA, 0xD8, -+0x73, 0xE7, 0x18, 0x4B, 0x05, 0x78, 0x1B, 0x68, 0x09, 0x4A, 0x1B, 0x0E, 0x03, 0x3B, 0x2B, 0x44, 0x03, 0xEB, 0x46, 0x03, -+0xDD, 0xB2, 0x29, 0x46, 0xD2, 0xF8, 0x48, 0x34, 0x98, 0x47, 0x28, 0x46, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0xBF, -+0x38, 0x36, 0x17, 0x00, 0xB4, 0x9A, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0xBC, 0x00, 0x32, 0x40, -+0xC0, 0x00, 0x32, 0x40, 0xAC, 0x00, 0x32, 0x40, 0x34, 0x36, 0x17, 0x00, 0x64, 0x05, 0x32, 0x40, 0xC4, 0x00, 0x32, 0x40, -+0x70, 0x79, 0x15, 0x00, 0xA0, 0x9A, 0x15, 0x00, 0x90, 0x9A, 0x15, 0x00, 0xC8, 0x00, 0x32, 0x40, 0xD4, 0x00, 0x32, 0x40, -+0xD8, 0x00, 0x32, 0x40, 0x33, 0x4A, 0x13, 0x68, 0xB0, 0xEB, 0x13, 0x6F, 0x70, 0xB5, 0x04, 0x46, 0x46, 0xD8, 0x0F, 0x28, -+0x24, 0xD8, 0x30, 0x4B, 0x30, 0x4D, 0x31, 0x49, 0x31, 0x48, 0x4F, 0xF0, 0xFF, 0x32, 0x1A, 0x60, 0xA3, 0x10, 0x2A, 0x60, -+0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x03, 0x00, 0xD1, 0xF8, 0x54, 0x34, 0x04, 0xF0, 0x03, 0x01, 0x98, 0x47, 0x2B, 0x4A, -+0x2B, 0x49, 0x2C, 0x4E, 0x2C, 0x4D, 0x2D, 0x48, 0x24, 0x04, 0x00, 0x23, 0x44, 0xF0, 0x80, 0x44, 0x33, 0x60, 0x2B, 0x60, -+0x13, 0x60, 0x03, 0x60, 0x0A, 0x46, 0x0C, 0x60, 0x13, 0x68, 0x5B, 0x00, 0xFC, 0xD4, 0x70, 0xBD, 0xA0, 0xF1, 0x10, 0x05, -+0x25, 0x48, 0x4F, 0xF4, 0x1E, 0x73, 0xED, 0xB2, 0x03, 0xFB, 0x05, 0x05, 0x28, 0x46, 0x95, 0xF8, 0x22, 0x60, 0xFD, 0xF7, -+0xD3, 0xFF, 0x1A, 0x4B, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x06, 0x36, 0x96, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0xE8, 0xD0, -+0x28, 0x8D, 0xEB, 0x8C, 0x11, 0x49, 0x12, 0x4A, 0x43, 0xEA, 0x00, 0x43, 0x0B, 0x60, 0x6B, 0x8D, 0x13, 0x60, 0xCC, 0xE7, -+0x13, 0x68, 0x15, 0x68, 0x0F, 0x48, 0x0E, 0x4A, 0x1B, 0x0E, 0x01, 0x33, 0xE3, 0x1A, 0x61, 0x1E, 0xA1, 0xEB, 0x15, 0x61, -+0x03, 0xEB, 0xD3, 0x73, 0x5B, 0x10, 0x4F, 0xF4, 0xA4, 0x64, 0x01, 0xF0, 0x01, 0x01, 0x04, 0xFB, 0x03, 0x00, 0x04, 0x31, -+0xBD, 0xE8, 0x70, 0x40, 0xD2, 0xF8, 0x54, 0x34, 0x18, 0x47, 0x00, 0xBF, 0xD8, 0x00, 0x32, 0x40, 0xBC, 0x00, 0x32, 0x40, -+0xC0, 0x00, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0xB4, 0x00, 0x32, 0x40, 0xC4, 0x00, 0x32, 0x40, -+0xAC, 0x00, 0x32, 0x40, 0xB0, 0x00, 0x32, 0x40, 0xB8, 0x00, 0x32, 0x40, 0x68, 0x65, 0x17, 0x00, 0xF0, 0xB4, 0x0E, 0x49, -+0x0E, 0x4F, 0x0F, 0x4E, 0x0F, 0x4D, 0x10, 0x4C, 0x4F, 0xF0, 0xFF, 0x32, 0x00, 0xF1, 0x10, 0x03, 0x0E, 0x48, 0x3A, 0x60, -+0xDB, 0xB2, 0x0A, 0x60, 0x00, 0x21, 0x01, 0x60, 0x1B, 0x04, 0x18, 0x30, 0x43, 0xF0, 0x80, 0x43, 0x31, 0x60, 0x02, 0x46, -+0x29, 0x60, 0x21, 0x60, 0x03, 0x60, 0x13, 0x68, 0x5B, 0x00, 0xFC, 0xD4, 0xF0, 0xBC, 0x70, 0x47, 0xC0, 0x00, 0x32, 0x40, -+0xBC, 0x00, 0x32, 0x40, 0xB0, 0x00, 0x32, 0x40, 0xB4, 0x00, 0x32, 0x40, 0xB8, 0x00, 0x32, 0x40, 0xAC, 0x00, 0x32, 0x40, -+0x08, 0xB5, 0x4F, 0xF0, 0x80, 0x60, 0x0A, 0xF0, 0xA5, 0xFE, 0x00, 0x21, 0xBD, 0xE8, 0x08, 0x40, 0x08, 0x46, 0x0A, 0xF0, -+0x89, 0xBC, 0x00, 0xBF, 0x14, 0x4B, 0x15, 0x49, 0x1A, 0x68, 0x22, 0xF0, 0x02, 0x02, 0xF0, 0xB4, 0x1A, 0x60, 0x1A, 0x68, -+0x12, 0x4F, 0x13, 0x4E, 0x13, 0x4D, 0x14, 0x4C, 0x42, 0xF0, 0x01, 0x02, 0x1A, 0x60, 0x4F, 0xF4, 0x40, 0x72, 0x3A, 0x60, -+0x07, 0x68, 0x82, 0x88, 0x00, 0x20, 0x30, 0x60, 0x28, 0x60, 0x27, 0x60, 0x0E, 0x4C, 0x0A, 0x60, 0x19, 0x68, 0x62, 0x68, -+0x0D, 0x4D, 0xA6, 0xF5, 0x00, 0x46, 0x44, 0x3E, 0x2A, 0x43, 0x21, 0xF4, 0xE0, 0x61, 0x19, 0x60, 0x25, 0x60, 0x32, 0x60, -+0xF0, 0xBC, 0xFC, 0xF7, 0x57, 0xBE, 0x00, 0xBF, 0x4C, 0x00, 0x32, 0x40, 0x14, 0x00, 0x32, 0x40, 0x1C, 0x00, 0x32, 0x40, -+0xA4, 0x80, 0x32, 0x40, 0xA8, 0x80, 0x32, 0x40, 0x10, 0x00, 0x32, 0x40, 0x98, 0x9C, 0x17, 0x00, 0x8C, 0x84, 0x03, 0x35, -+0x0B, 0x49, 0x0C, 0x48, 0x38, 0xB5, 0x02, 0x68, 0x4B, 0x68, 0x0B, 0x4C, 0x0B, 0x4D, 0x42, 0xF0, 0x02, 0x02, 0x23, 0x43, -+0x02, 0x60, 0x0C, 0x60, 0x00, 0x20, 0x2B, 0x60, 0xFC, 0xF7, 0x36, 0xFE, 0x07, 0x4B, 0x08, 0x49, 0x08, 0x4A, 0x19, 0x60, -+0x13, 0x68, 0x0B, 0x43, 0x13, 0x60, 0x38, 0xBD, 0x98, 0x9C, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, 0x8C, 0xA4, 0x07, 0x35, -+0x60, 0x00, 0x32, 0x40, 0x70, 0x80, 0x32, 0x40, 0x01, 0x00, 0x04, 0x00, 0x74, 0x80, 0x32, 0x40, 0x0D, 0x49, 0x0E, 0x48, -+0x38, 0xB5, 0x02, 0x68, 0x4B, 0x68, 0x0D, 0x4C, 0x0D, 0x4D, 0x22, 0xF0, 0x02, 0x02, 0x23, 0x43, 0x02, 0x60, 0x0C, 0x60, -+0x00, 0x20, 0x2B, 0x60, 0xFC, 0xF7, 0x10, 0xFE, 0x09, 0x4B, 0x0A, 0x4A, 0x0A, 0x49, 0x19, 0x60, 0x13, 0x68, 0x23, 0xF4, -+0x80, 0x23, 0x23, 0xF0, 0x01, 0x03, 0x13, 0x60, 0x38, 0xBD, 0x00, 0xBF, 0x98, 0x9C, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, -+0x8C, 0x84, 0x03, 0x35, 0x60, 0x00, 0x32, 0x40, 0x70, 0x80, 0x32, 0x40, 0x74, 0x80, 0x32, 0x40, 0x01, 0x00, 0x04, 0x00, -+0x00, 0xEB, 0x80, 0x03, 0xC0, 0xEB, 0x03, 0x10, 0x04, 0x4B, 0x08, 0x44, 0x03, 0xEB, 0xC0, 0x00, 0x90, 0xF8, 0xA5, 0x01, -+0x21, 0x38, 0x18, 0xBF, 0x01, 0x20, 0x70, 0x47, 0x68, 0x65, 0x17, 0x00, 0x00, 0xEB, 0x80, 0x03, 0xC0, 0xEB, 0x03, 0x10, -+0x04, 0x4B, 0x08, 0x44, 0x03, 0xEB, 0xC0, 0x00, 0x90, 0xF8, 0xA4, 0x01, 0x21, 0x38, 0x18, 0xBF, 0x01, 0x20, 0x70, 0x47, -+0x68, 0x65, 0x17, 0x00, 0xF8, 0xB5, 0x37, 0x4A, 0x37, 0x4B, 0x92, 0xF8, 0x30, 0x10, 0x1B, 0x68, 0x00, 0x29, 0x45, 0xD1, -+0x00, 0x28, 0x40, 0xD0, 0x9B, 0xB2, 0x01, 0x21, 0x80, 0xEA, 0xE0, 0x76, 0x00, 0x28, 0x4F, 0xEA, 0x83, 0x23, 0x82, 0xF8, -+0x30, 0x10, 0xA6, 0xEB, 0xE0, 0x76, 0x4E, 0xDD, 0xB6, 0xEB, 0x53, 0x0F, 0x23, 0xFA, 0x01, 0xF4, 0x98, 0xBF, 0x04, 0x46, -+0xEF, 0xF3, 0x10, 0x81, 0xC9, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x29, 0x49, 0x01, 0x20, 0x08, 0x60, 0x28, 0x4D, 0x29, 0x4F, -+0x29, 0x68, 0x29, 0x48, 0x01, 0x31, 0x00, 0x68, 0x29, 0x60, 0x39, 0x69, 0x00, 0x2C, 0x4F, 0xEA, 0x40, 0x17, 0x01, 0xEB, -+0x40, 0x11, 0x4F, 0xEA, 0x93, 0x00, 0x25, 0xDD, 0xB8, 0x42, 0x1A, 0xD8, 0x64, 0x36, 0xDB, 0x1B, 0x9E, 0x42, 0x31, 0xD9, -+0x20, 0x4B, 0x94, 0x62, 0x09, 0x1A, 0xD3, 0xF8, 0xE0, 0x31, 0x1F, 0x48, 0x98, 0x47, 0x2B, 0x68, 0x43, 0xB1, 0x18, 0x4A, -+0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x1B, 0xB9, 0x12, 0xB1, 0x62, 0xB6, 0x00, 0xE0, 0x04, 0x46, 0x20, 0x46, 0xF8, 0xBD, -+0x00, 0x24, 0x20, 0x46, 0xF8, 0xBD, 0x15, 0x4E, 0x94, 0x62, 0x19, 0x44, 0x09, 0x1A, 0xD6, 0xF8, 0xE0, 0x31, 0x13, 0x48, -+0x98, 0x47, 0xE6, 0xE7, 0x30, 0x44, 0xB8, 0x42, 0x0E, 0xD3, 0x0F, 0x4B, 0x0F, 0x48, 0xD3, 0xF8, 0xE0, 0x31, 0x94, 0x62, -+0x64, 0x31, 0x98, 0x47, 0xDB, 0xE7, 0x5C, 0x08, 0xB6, 0xEB, 0x53, 0x0F, 0x8C, 0xBF, 0x64, 0x42, 0x04, 0x46, 0xAF, 0xE7, -+0x20, 0x46, 0xFE, 0xF7, 0x57, 0xFD, 0xD0, 0xE7, 0x98, 0x9C, 0x17, 0x00, 0x64, 0x00, 0x32, 0x40, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x40, 0x80, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0xB8, 0x9C, 0x17, 0x00, -+0x13, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x10, 0xB5, 0x0E, 0xDB, 0x11, 0x4B, 0xDB, 0x7F, 0x2B, 0xB1, -+0x10, 0x4A, 0x93, 0x7C, 0x52, 0x7C, 0x13, 0x44, 0x01, 0x2B, 0x11, 0xDD, 0x0E, 0x4B, 0xBD, 0xE8, 0x10, 0x40, 0xD3, 0xF8, -+0x60, 0x31, 0x18, 0x47, 0x00, 0x20, 0x0A, 0xF0, 0xED, 0xFB, 0x03, 0x28, 0xEB, 0xD0, 0x0A, 0x49, 0x0A, 0x48, 0x40, 0xF2, -+0x06, 0x72, 0x0C, 0xF0, 0x25, 0xFA, 0xE4, 0xE7, 0x00, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x08, 0x46, 0x0A, 0xF0, 0x36, 0xBB, -+0x38, 0x36, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xC4, 0x9A, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x39, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x61, 0xDB, -+0x37, 0x49, 0x04, 0x20, 0x0B, 0xF0, 0xDC, 0xFF, 0xEF, 0xF3, 0x10, 0x83, 0xD8, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x34, 0x4B, -+0x01, 0x22, 0x1A, 0x60, 0xDF, 0xF8, 0xFC, 0x80, 0x32, 0x4C, 0xD8, 0xF8, 0x00, 0x30, 0x32, 0x4D, 0x01, 0x33, 0x00, 0x22, -+0xC8, 0xF8, 0x00, 0x30, 0x23, 0x68, 0x22, 0x60, 0x2F, 0x69, 0x03, 0xF0, 0x0F, 0x09, 0x47, 0xF2, 0x30, 0x56, 0x05, 0xE0, -+0xF6, 0xF7, 0x22, 0xFB, 0x2B, 0x69, 0xDB, 0x1B, 0xB3, 0x42, 0x2C, 0xD8, 0x23, 0x68, 0x19, 0x07, 0xF6, 0xD1, 0x28, 0x4A, -+0x28, 0x48, 0x53, 0x68, 0x28, 0x49, 0x04, 0x68, 0x23, 0xF0, 0x04, 0x03, 0x53, 0x60, 0x0B, 0x68, 0xB9, 0xF1, 0x00, 0x0F, -+0x22, 0xD1, 0x25, 0x4B, 0x25, 0x49, 0x04, 0x20, 0x18, 0x60, 0x0B, 0xF0, 0xA7, 0xFF, 0x24, 0x4B, 0x93, 0xF8, 0x5A, 0x30, -+0x0B, 0xBB, 0x03, 0x21, 0x00, 0x20, 0x0A, 0xF0, 0xE1, 0xFA, 0x21, 0x4A, 0xD8, 0xF8, 0x00, 0x30, 0x00, 0x21, 0x51, 0x82, -+0x3B, 0xB1, 0x15, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xC8, 0xF8, 0x00, 0x30, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xBD, 0xE8, -+0xF8, 0x83, 0x1A, 0x49, 0x04, 0x20, 0x0B, 0xF0, 0x8B, 0xFF, 0xC4, 0xE7, 0x23, 0x40, 0x5A, 0x07, 0xD9, 0xD4, 0x02, 0x68, -+0x0B, 0x68, 0x13, 0x40, 0x5B, 0x07, 0xFA, 0xD5, 0xD3, 0xE7, 0xF6, 0xF7, 0x07, 0xFB, 0xDA, 0xE7, 0x00, 0x20, 0x0A, 0xF0, -+0x65, 0xFB, 0x04, 0x28, 0x98, 0xD1, 0x10, 0x49, 0x10, 0x48, 0x40, 0xF2, 0x14, 0x72, 0x0C, 0xF0, 0x9D, 0xF9, 0x91, 0xE7, -+0x38, 0x36, 0x17, 0x00, 0x14, 0x9B, 0x15, 0x00, 0x38, 0x61, 0x17, 0x00, 0x38, 0x00, 0x32, 0x40, 0x00, 0x10, 0x50, 0x40, -+0x1C, 0x9E, 0x17, 0x00, 0x6C, 0x80, 0x32, 0x40, 0x74, 0x80, 0x32, 0x40, 0x70, 0x80, 0x32, 0x40, 0x28, 0x9B, 0x15, 0x00, -+0x30, 0x9D, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, 0x5C, 0x9A, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, 0xF0, 0x9A, 0x15, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x24, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x10, 0xB5, 0x31, 0xDB, 0x00, 0x20, -+0x0A, 0xF0, 0x32, 0xFB, 0x02, 0x28, 0x05, 0xD0, 0xBD, 0xE8, 0x10, 0x40, 0x04, 0x21, 0x00, 0x20, 0x0A, 0xF0, 0x82, 0xBA, -+0x1C, 0x4B, 0x30, 0x22, 0x1A, 0x60, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x19, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x19, 0x4C, 0x23, 0x68, 0x4F, 0xF0, 0x80, 0x60, 0x01, 0x33, 0x23, 0x60, 0x0A, 0xF0, 0x85, 0xFC, 0x16, 0x4B, -+0x1B, 0x68, 0x5B, 0x07, 0x02, 0xD5, 0x15, 0x4B, 0x04, 0x22, 0x1A, 0x60, 0x23, 0x68, 0x00, 0x2B, 0xDC, 0xD0, 0x0F, 0x4A, -+0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x00, 0x2B, 0xD6, 0xD1, 0x00, 0x2A, 0xD4, 0xD0, 0x62, 0xB6, 0xD2, 0xE7, 0x00, 0x20, -+0x0A, 0xF0, 0x00, 0xFB, 0x03, 0x28, 0x04, 0xD0, 0x00, 0x20, 0x0A, 0xF0, 0xFB, 0xFA, 0x00, 0x28, 0xC3, 0xD1, 0x09, 0x49, -+0x09, 0x48, 0x40, 0xF2, 0x4F, 0x72, 0x0C, 0xF0, 0x33, 0xF9, 0xBC, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x38, 0x00, 0x32, 0x40, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x6C, 0x80, 0x32, 0x40, 0x70, 0x80, 0x32, 0x40, 0x70, 0x79, 0x15, 0x00, -+0x3C, 0x9B, 0x15, 0x00, 0x08, 0xB5, 0x00, 0x20, 0x0A, 0xF0, 0xDE, 0xFA, 0x04, 0x28, 0x00, 0xD0, 0x08, 0xBD, 0xBD, 0xE8, -+0x08, 0x40, 0x01, 0x21, 0x00, 0x20, 0x0A, 0xF0, 0x2D, 0xBA, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0x78, 0xA0, -+0xDA, 0xF8, 0x1C, 0x33, 0x17, 0x46, 0x05, 0x46, 0x0E, 0x46, 0x98, 0x47, 0x04, 0x46, 0x60, 0xBB, 0x96, 0xF8, 0x00, 0x90, -+0x16, 0x4A, 0x95, 0xF8, 0x19, 0x80, 0xDA, 0xF8, 0xB0, 0x31, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x09, 0x29, 0x41, 0x46, -+0x89, 0xF8, 0x5D, 0x02, 0xA9, 0xF8, 0x5E, 0x02, 0x30, 0x78, 0x98, 0x47, 0x38, 0x70, 0xD9, 0xF8, 0x2C, 0x30, 0x2B, 0xB1, -+0xDA, 0xF8, 0xB0, 0x21, 0x93, 0xF8, 0x23, 0x00, 0x69, 0x7E, 0x90, 0x47, 0x0A, 0x49, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, -+0x08, 0x11, 0x91, 0xF8, 0x62, 0x30, 0x43, 0xB9, 0x33, 0x78, 0x81, 0xF8, 0x6C, 0x30, 0x6B, 0x7F, 0x81, 0xF8, 0x6D, 0x30, -+0xAB, 0x7F, 0x81, 0xF8, 0x6E, 0x30, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x87, 0x68, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x7C, 0x4E, 0x7D, 0x4C, 0x4F, 0xF4, 0x1E, 0x77, 0x07, 0xFB, 0x00, 0x67, -+0x4F, 0xF0, 0x4F, 0x08, 0x46, 0x23, 0x18, 0xFB, 0x00, 0x38, 0x97, 0xF8, 0x22, 0xB0, 0x85, 0xB0, 0x05, 0x46, 0x06, 0xEB, -+0xC8, 0x08, 0x4F, 0xF0, 0x00, 0x09, 0xD7, 0xF8, 0x08, 0x32, 0x5F, 0xFA, 0x89, 0xFA, 0xA8, 0xF1, 0x28, 0x01, 0x4F, 0xF0, -+0x80, 0x42, 0x09, 0xF1, 0x01, 0x09, 0x50, 0x46, 0x13, 0xB1, 0xD4, 0xF8, 0x84, 0x33, 0x98, 0x47, 0xD7, 0xF8, 0x30, 0x32, -+0x41, 0x46, 0x08, 0x37, 0x08, 0xF1, 0x08, 0x08, 0x4F, 0xF0, 0x80, 0x42, 0x50, 0x46, 0x13, 0xB1, 0xD4, 0xF8, 0x84, 0x33, -+0x98, 0x47, 0xB9, 0xF1, 0x05, 0x0F, 0xE0, 0xD1, 0x65, 0x4B, 0x4F, 0xF4, 0xA4, 0x67, 0x07, 0xFB, 0x0B, 0x33, 0x93, 0xF8, -+0x62, 0x10, 0xC1, 0xB9, 0xFF, 0x22, 0x83, 0xF8, 0x6C, 0x20, 0xD4, 0xF8, 0xAC, 0x31, 0x28, 0x46, 0x98, 0x47, 0x4F, 0xF4, -+0x1E, 0x73, 0x03, 0xFB, 0x05, 0x66, 0xF3, 0x6A, 0x23, 0xB1, 0x93, 0xF8, 0x23, 0x00, 0xD4, 0xF8, 0xAC, 0x31, 0x98, 0x47, -+0xD4, 0xF8, 0x24, 0x33, 0x28, 0x46, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x18, 0x47, 0x4F, 0xF4, 0x1E, 0x78, 0x08, 0xFB, -+0x05, 0x62, 0x92, 0xF8, 0x24, 0x90, 0xB9, 0xF1, 0x01, 0x0F, 0x02, 0xD0, 0x02, 0x29, 0xED, 0xD0, 0xDD, 0xE7, 0x93, 0xF8, -+0xDE, 0x20, 0x01, 0x3A, 0xD2, 0xB2, 0x83, 0xF8, 0xDE, 0x20, 0x00, 0x2A, 0xF4, 0xD1, 0x93, 0xF8, 0x63, 0xA0, 0x0A, 0xF1, -+0x0A, 0x0A, 0x5F, 0xFA, 0x8A, 0xFA, 0x08, 0xFB, 0x0A, 0xF3, 0x06, 0xEB, 0x03, 0x08, 0x00, 0x93, 0x98, 0xF8, 0x24, 0x30, -+0x73, 0xB9, 0x44, 0x4B, 0x4F, 0xF4, 0xA4, 0x67, 0x07, 0xFB, 0x0B, 0x37, 0x38, 0x46, 0x97, 0xF8, 0x63, 0x10, 0xE3, 0x68, -+0x0A, 0x31, 0xC9, 0xB2, 0x98, 0x47, 0x97, 0xF8, 0x62, 0x10, 0xD7, 0xE7, 0x02, 0x23, 0x0C, 0x21, 0x49, 0x20, 0x01, 0x92, -+0x09, 0xF0, 0x64, 0xFF, 0x01, 0x9A, 0x88, 0xF8, 0x24, 0x20, 0x80, 0xF8, 0x00, 0xA0, 0x42, 0x70, 0x09, 0xF0, 0x8C, 0xFF, -+0x98, 0xF8, 0x24, 0x30, 0x00, 0x2B, 0xDE, 0xD1, 0x98, 0xF8, 0x23, 0x30, 0x09, 0x2B, 0xDA, 0xD8, 0x98, 0xF8, 0x22, 0x00, -+0x31, 0x4B, 0xCD, 0xF8, 0x04, 0x90, 0x9E, 0x22, 0xA4, 0x21, 0x11, 0xFB, 0x00, 0x21, 0x2D, 0x4A, 0x03, 0x95, 0x07, 0xFB, -+0x00, 0x27, 0x2B, 0x48, 0x02, 0x97, 0x4F, 0xF0, 0x4F, 0x0C, 0x46, 0x27, 0x1C, 0xFB, 0x0A, 0x77, 0x00, 0xEB, 0xC1, 0x0A, -+0x00, 0x99, 0x28, 0x4A, 0x02, 0x9D, 0xC1, 0x46, 0x88, 0x46, 0x06, 0xEB, 0xC7, 0x07, 0x98, 0x44, 0xD9, 0xF8, 0x08, 0x12, -+0x31, 0xB3, 0xEF, 0xF3, 0x10, 0x81, 0xCB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x21, 0x4B, 0x01, 0x99, 0x19, 0x60, 0x11, 0x68, -+0xA7, 0xF1, 0x28, 0x00, 0x4B, 0x1C, 0xAA, 0xF1, 0x28, 0x01, 0x13, 0x60, 0x00, 0x90, 0x0A, 0xF0, 0xA1, 0xFC, 0xD9, 0xF8, -+0x08, 0x12, 0xD9, 0xF8, 0x0C, 0x32, 0x00, 0x98, 0xC5, 0xF8, 0xC8, 0x14, 0xC5, 0xF8, 0xCC, 0x34, 0x0A, 0xF0, 0xA0, 0xFB, -+0x14, 0x4A, 0x11, 0x68, 0x48, 0x1E, 0x29, 0xB1, 0x13, 0x4B, 0x10, 0x60, 0x19, 0x68, 0x08, 0xB9, 0x01, 0xB1, 0x62, 0xB6, -+0xD9, 0xF8, 0x30, 0x32, 0x50, 0x46, 0x39, 0x46, 0x09, 0xF1, 0x08, 0x09, 0x0A, 0xF1, 0x08, 0x0A, 0x08, 0x35, 0x2B, 0xB1, -+0x0A, 0xF0, 0x80, 0xFC, 0x38, 0x46, 0x0A, 0xF0, 0x87, 0xFB, 0x08, 0x4A, 0x08, 0x37, 0x47, 0x45, 0xC2, 0xD1, 0x40, 0x20, -+0x03, 0x9D, 0x0A, 0xF0, 0xE1, 0xFA, 0x7A, 0xE7, 0x68, 0x65, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0xC0, 0x67, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x10, 0xB5, 0x01, 0x23, 0x04, 0x46, 0x00, 0x22, -+0x06, 0x21, 0x43, 0x20, 0x09, 0xF0, 0xE0, 0xFE, 0x94, 0xF8, 0x63, 0x30, 0x03, 0x70, 0xBD, 0xE8, 0x10, 0x40, 0x09, 0xF0, -+0x09, 0xBF, 0x00, 0xBF, 0x70, 0xB5, 0x90, 0xF9, 0x87, 0x30, 0x04, 0x46, 0x90, 0xF9, 0x86, 0x00, 0x94, 0xF8, 0x88, 0x20, -+0x94, 0xF8, 0x89, 0x60, 0x84, 0xF8, 0x86, 0x10, 0xBB, 0xB1, 0x0D, 0x46, 0x52, 0xB2, 0xAE, 0xB9, 0x88, 0x42, 0x10, 0xDD, -+0x9B, 0x1A, 0x99, 0x42, 0x0D, 0xDA, 0x01, 0x26, 0x00, 0x22, 0x03, 0x23, 0x0C, 0x21, 0x57, 0x20, 0x09, 0xF0, 0xBC, 0xFE, -+0x94, 0xF8, 0x63, 0x20, 0x02, 0x70, 0x46, 0x70, 0x85, 0x70, 0x09, 0xF0, 0xE5, 0xFE, 0x84, 0xF8, 0x89, 0x60, 0x70, 0xBD, -+0x01, 0x2E, 0xFA, 0xD1, 0x88, 0x42, 0xF8, 0xDA, 0x13, 0x44, 0x99, 0x42, 0xF5, 0xDD, 0x00, 0x26, 0xE6, 0xE7, 0x00, 0xBF, -+0x14, 0x4B, 0x93, 0xF9, 0x00, 0x20, 0x22, 0xB3, 0x30, 0xB4, 0x9C, 0x78, 0x90, 0xF9, 0x86, 0x00, 0x93, 0xF9, 0x01, 0x50, -+0x6C, 0xB9, 0x88, 0x42, 0x08, 0xDD, 0x52, 0x1B, 0x91, 0x42, 0x05, 0xDA, 0x0D, 0x49, 0x0A, 0x68, 0x42, 0xF4, 0x00, 0x72, -+0x0A, 0x60, 0x01, 0x24, 0x9C, 0x70, 0x30, 0xBC, 0x70, 0x47, 0x01, 0x2C, 0xFA, 0xD1, 0x88, 0x42, 0xF8, 0xDA, 0x2A, 0x44, -+0x91, 0x42, 0xF5, 0xDD, 0x05, 0x49, 0x0A, 0x68, 0x00, 0x24, 0x22, 0xF4, 0x00, 0x72, 0x0A, 0x60, 0x9C, 0x70, 0x30, 0xBC, -+0x70, 0x47, 0x70, 0x47, 0xA4, 0x1F, 0x17, 0x00, 0xB0, 0xB3, 0x33, 0x40, 0x2D, 0xE9, 0xF0, 0x4F, 0x0C, 0x46, 0x06, 0x46, -+0x80, 0x68, 0x91, 0xF8, 0x8B, 0x10, 0xD0, 0xF8, 0x08, 0x80, 0x60, 0x6F, 0xB6, 0xF8, 0x1C, 0xB0, 0xDF, 0xF8, 0x1C, 0xA1, -+0x87, 0xB0, 0x00, 0x25, 0x05, 0x90, 0x03, 0x92, 0x1F, 0x46, 0x84, 0xF8, 0x78, 0x50, 0x49, 0xB1, 0x94, 0xF8, 0x63, 0x00, -+0xDA, 0xF8, 0xC0, 0x31, 0x01, 0x21, 0x98, 0x47, 0xA4, 0xF8, 0x8A, 0x50, 0x84, 0xF8, 0x8C, 0x50, 0x3A, 0x4B, 0x3B, 0x4D, -+0x1B, 0x68, 0x22, 0x6F, 0x5B, 0x68, 0x01, 0x21, 0x84, 0xF8, 0x85, 0x10, 0x29, 0x69, 0x5B, 0x1A, 0xD3, 0x42, 0x58, 0xD4, -+0x96, 0xF9, 0x2D, 0x10, 0x04, 0x91, 0xE8, 0xF7, 0x35, 0xFB, 0x34, 0x4B, 0x04, 0x99, 0x5B, 0x7C, 0x01, 0x2B, 0x59, 0xD0, -+0xDA, 0xF8, 0x9C, 0x31, 0x20, 0x46, 0xAB, 0xF1, 0x24, 0x05, 0x98, 0x47, 0xAD, 0xB2, 0x00, 0x22, 0x04, 0x21, 0x08, 0xF1, -+0x20, 0x00, 0x0A, 0xF0, 0x19, 0xFC, 0x00, 0x23, 0x01, 0x2D, 0x3B, 0x60, 0x08, 0xF1, 0x24, 0x02, 0x22, 0xD9, 0x04, 0x96, -+0x3E, 0x46, 0x27, 0x46, 0x2C, 0x46, 0x09, 0xE0, 0x32, 0x60, 0xC9, 0xF5, 0x7F, 0x42, 0xFE, 0x32, 0x14, 0x44, 0xA4, 0xB2, -+0x01, 0x2C, 0x05, 0xEB, 0x09, 0x02, 0x10, 0xD9, 0x92, 0xF8, 0x01, 0x90, 0x15, 0x46, 0x09, 0xF1, 0x01, 0x0C, 0xA4, 0x45, -+0x15, 0xF8, 0x02, 0x1B, 0x07, 0xDA, 0x05, 0x29, 0xEA, 0xD0, 0x02, 0x46, 0x49, 0x46, 0x28, 0x46, 0x0A, 0xF0, 0xF4, 0xFB, -+0xE5, 0xE7, 0x3C, 0x46, 0x37, 0x46, 0x04, 0x9E, 0x60, 0x67, 0x3B, 0x68, 0x01, 0x93, 0x03, 0x9B, 0x00, 0x93, 0x32, 0x46, -+0x59, 0x46, 0x40, 0x46, 0x23, 0x46, 0xDA, 0xF8, 0xD0, 0x51, 0xA8, 0x47, 0x04, 0x20, 0x0A, 0xF0, 0xA1, 0xF8, 0x01, 0x28, -+0x04, 0xD0, 0x60, 0x6F, 0x05, 0x9B, 0xC0, 0x1A, 0x18, 0xBF, 0x01, 0x20, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x22, -+0x94, 0xF8, 0x6C, 0x00, 0x11, 0x46, 0xF7, 0xF7, 0x75, 0xF9, 0x00, 0x28, 0x9E, 0xD1, 0x2B, 0x69, 0x23, 0x67, 0x9B, 0xE7, -+0x20, 0x46, 0xFF, 0xF7, 0x3F, 0xFF, 0x04, 0x99, 0xA0, 0xE7, 0x00, 0xBF, 0xC8, 0x35, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, -+0x00, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0xB5, 0x00, 0x22, 0x05, 0x46, 0x0C, 0x46, 0x02, 0x23, 0x0C, 0x21, -+0x59, 0x20, 0x09, 0xF0, 0xD3, 0xFD, 0x05, 0x70, 0x44, 0x70, 0xBD, 0xE8, 0x38, 0x40, 0x09, 0xF0, 0xFD, 0xBD, 0x00, 0xBF, -+0x08, 0xB5, 0x03, 0x4B, 0x08, 0x46, 0xD3, 0xF8, 0x74, 0x31, 0x98, 0x47, 0x01, 0x20, 0x08, 0xBD, 0x88, 0x1A, 0x17, 0x00, -+0x08, 0xB5, 0x04, 0x4A, 0x08, 0x78, 0xD2, 0xF8, 0x5C, 0x22, 0x19, 0x46, 0x90, 0x47, 0x00, 0x20, 0x08, 0xBD, 0x00, 0xBF, -+0x88, 0x1A, 0x17, 0x00, 0xF8, 0xB5, 0x0E, 0x46, 0x2F, 0x20, 0x19, 0x46, 0x02, 0x23, 0x34, 0x78, 0x09, 0xF0, 0xAE, 0xFD, -+0x0D, 0x49, 0x76, 0x78, 0x0D, 0x4B, 0x4F, 0xF4, 0xA4, 0x67, 0x05, 0x46, 0x07, 0xFB, 0x04, 0x10, 0x29, 0x46, 0x90, 0xF8, -+0x65, 0x20, 0x80, 0xF8, 0x66, 0x60, 0x01, 0xF8, 0x01, 0x2F, 0x7F, 0x22, 0xD3, 0xF8, 0x40, 0x33, 0x80, 0xF8, 0x65, 0x20, -+0x2A, 0x46, 0x98, 0x47, 0x28, 0x46, 0x09, 0xF0, 0xC5, 0xFD, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x18, 0x46, 0x38, 0xB5, 0x0D, 0x46, 0x03, 0x23, 0x01, 0x46, 0x0B, 0x20, 0x09, 0xF0, 0x86, 0xFD, -+0x06, 0x4B, 0x04, 0x46, 0xD3, 0xF8, 0xC4, 0x31, 0xA2, 0x1C, 0x61, 0x1C, 0x28, 0x46, 0x98, 0x47, 0x20, 0x70, 0x20, 0x46, -+0x09, 0xF0, 0xAA, 0xFD, 0x00, 0x20, 0x38, 0xBD, 0x88, 0x1A, 0x17, 0x00, 0xF8, 0xB5, 0x0E, 0x4E, 0x0D, 0x46, 0x1C, 0x46, -+0x19, 0x46, 0x28, 0x46, 0xD6, 0xF8, 0x80, 0x30, 0x17, 0x46, 0x98, 0x47, 0x0C, 0xB9, 0x00, 0x20, 0xF8, 0xBD, 0x06, 0x46, -+0x3A, 0x46, 0x21, 0x46, 0x03, 0x23, 0x47, 0x20, 0x09, 0xF0, 0x62, 0xFD, 0x2A, 0x78, 0x02, 0x70, 0x04, 0x22, 0x46, 0x70, -+0x82, 0x70, 0x09, 0xF0, 0x8B, 0xFD, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x38, 0xB5, 0x0C, 0x46, -+0x76, 0x20, 0x19, 0x46, 0x0C, 0x23, 0x09, 0xF0, 0x4F, 0xFD, 0x23, 0x78, 0x0C, 0x4A, 0x0D, 0x4C, 0x4F, 0xF4, 0x1E, 0x71, -+0x01, 0xFB, 0x03, 0x23, 0x4F, 0xF4, 0xA4, 0x65, 0x93, 0xF8, 0x22, 0x20, 0xD3, 0xF8, 0x48, 0x11, 0x05, 0xFB, 0x02, 0x42, -+0x49, 0x69, 0x92, 0xF8, 0x86, 0x20, 0x02, 0x72, 0x00, 0x24, 0xC0, 0xE9, 0x00, 0x14, 0x09, 0xF0, 0x67, 0xFD, 0x20, 0x46, -+0x38, 0xBD, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0xF0, 0xB5, 0x00, 0x22, 0x0D, 0x46, 0x85, 0xB0, -+0x01, 0x23, 0x0C, 0x21, 0x53, 0x20, 0x09, 0xF0, 0x27, 0xFD, 0x01, 0x22, 0x02, 0x70, 0x04, 0x46, 0x28, 0x78, 0x04, 0x28, -+0x28, 0xD8, 0x1D, 0x4B, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x00, 0x30, 0x90, 0xF8, 0xC0, 0x34, 0x03, 0xB3, 0xAB, 0x78, -+0x23, 0xB3, 0x19, 0x4A, 0x19, 0x49, 0x16, 0x68, 0x09, 0x69, 0x17, 0x68, 0xB0, 0xF8, 0xD2, 0x20, 0xC9, 0x1B, 0x92, 0x02, -+0xEF, 0x68, 0xB6, 0xFB, 0xF2, 0xF6, 0x06, 0xFB, 0x02, 0x22, 0x14, 0x4E, 0x39, 0x44, 0x6F, 0x68, 0xD6, 0xF8, 0x04, 0x62, -+0x01, 0x97, 0x0A, 0x44, 0xA9, 0x68, 0x00, 0x91, 0x02, 0x92, 0xEA, 0x78, 0x00, 0x21, 0xB0, 0x47, 0xFF, 0x28, 0x01, 0xD0, -+0x00, 0x23, 0x23, 0x70, 0x20, 0x46, 0x09, 0xF0, 0x25, 0xFD, 0x00, 0x20, 0x05, 0xB0, 0xF0, 0xBD, 0x08, 0x4B, 0x69, 0x78, -+0xD3, 0xF8, 0x08, 0x32, 0x98, 0x47, 0x20, 0x70, 0x20, 0x46, 0x09, 0xF0, 0x19, 0xFD, 0x00, 0x20, 0x05, 0xB0, 0xF0, 0xBD, -+0x18, 0x88, 0x17, 0x00, 0xA4, 0x80, 0x32, 0x40, 0x00, 0x10, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x38, 0xB5, 0x19, 0x46, -+0x05, 0x20, 0x1C, 0x23, 0x09, 0xF0, 0xD8, 0xFC, 0x2C, 0x4D, 0x2D, 0x4B, 0x03, 0x60, 0x2A, 0x68, 0x2C, 0x4B, 0x42, 0x60, -+0x1B, 0x68, 0x83, 0x60, 0x0A, 0x22, 0x04, 0x23, 0x83, 0x76, 0x02, 0x83, 0x04, 0x46, 0x00, 0xF1, 0x10, 0x01, 0x0C, 0x30, -+0xE8, 0xF7, 0x9E, 0xF8, 0x26, 0x4B, 0x63, 0x61, 0x2B, 0x68, 0x98, 0x03, 0x24, 0xD4, 0x21, 0x4B, 0x1B, 0x68, 0x99, 0x03, -+0x2C, 0xD4, 0x1F, 0x4B, 0x1B, 0x68, 0x9A, 0x04, 0x03, 0xD5, 0x63, 0x69, 0x43, 0xF4, 0x00, 0x23, 0x63, 0x61, 0xE8, 0xF7, -+0x2F, 0xF9, 0x18, 0xB1, 0x63, 0x69, 0x43, 0xF4, 0x80, 0x33, 0x63, 0x61, 0x17, 0x4B, 0x1B, 0x68, 0x1B, 0x04, 0x22, 0xD4, -+0xE8, 0xF7, 0x2E, 0xF9, 0x63, 0x69, 0x08, 0xB1, 0x43, 0xF0, 0x80, 0x63, 0x43, 0xF0, 0x40, 0x53, 0x20, 0x46, 0x63, 0x61, -+0x09, 0xF0, 0xCE, 0xFC, 0x00, 0x20, 0x38, 0xBD, 0xE8, 0xF7, 0x3E, 0xF9, 0x00, 0x28, 0xD6, 0xD0, 0x63, 0x69, 0x43, 0xF4, -+0x00, 0x33, 0x63, 0x61, 0x0A, 0x4B, 0x1B, 0x68, 0x99, 0x03, 0xD2, 0xD5, 0xE8, 0xF7, 0x3A, 0xF9, 0x00, 0x28, 0xCE, 0xD0, -+0x63, 0x69, 0x43, 0xF4, 0x00, 0x13, 0x63, 0x61, 0xC9, 0xE7, 0xE8, 0xF7, 0x03, 0xF9, 0x00, 0x28, 0xD8, 0xD0, 0x63, 0x69, -+0x43, 0xF0, 0x80, 0x43, 0x63, 0x61, 0xD3, 0xE7, 0x04, 0x00, 0x32, 0x40, 0x01, 0x03, 0x04, 0x06, 0x08, 0x00, 0x32, 0x40, -+0x5F, 0xFA, 0x10, 0x00, 0xF0, 0xB5, 0x23, 0x48, 0x4D, 0x79, 0x00, 0x68, 0x8C, 0x79, 0x50, 0xF8, 0x25, 0xC0, 0x21, 0x4F, -+0x0E, 0x68, 0x4F, 0xF4, 0xA4, 0x70, 0x00, 0xFB, 0x04, 0x50, 0x02, 0x30, 0x83, 0xB0, 0x47, 0xF8, 0x20, 0x60, 0x19, 0x46, -+0xBC, 0xF1, 0x00, 0x0F, 0x0A, 0xD0, 0xCC, 0xF3, 0x0B, 0x03, 0x1B, 0xBB, 0x2C, 0xF4, 0x7F, 0x6C, 0x2C, 0xF0, 0x0F, 0x0C, -+0xC6, 0xF3, 0x0B, 0x06, 0x4C, 0xEA, 0x06, 0x06, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x04, 0x74, 0x94, 0xF8, 0x64, 0x30, -+0x73, 0xB1, 0x01, 0x2D, 0x1A, 0xD0, 0x02, 0x2D, 0x12, 0xD0, 0xA5, 0xB1, 0x0F, 0x4B, 0x1E, 0x60, 0x0F, 0x4B, 0xD3, 0xF8, -+0xA0, 0x31, 0xCD, 0xE9, 0x00, 0x21, 0x98, 0x47, 0xDD, 0xE9, 0x00, 0x21, 0x1B, 0x20, 0x09, 0xF0, 0xA5, 0xFC, 0x00, 0x20, -+0x03, 0xB0, 0xF0, 0xBD, 0x66, 0x46, 0xE1, 0xE7, 0x08, 0x4B, 0x1E, 0x60, 0xEC, 0xE7, 0x08, 0x4B, 0x1E, 0x60, 0xE9, 0xE7, -+0x07, 0x4B, 0x1E, 0x60, 0xE6, 0xE7, 0x00, 0xBF, 0xAC, 0x35, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x0C, 0x02, 0x32, 0x40, -+0x88, 0x1A, 0x17, 0x00, 0x08, 0x02, 0x32, 0x40, 0x00, 0x02, 0x32, 0x40, 0x04, 0x02, 0x32, 0x40, 0x38, 0xB5, 0x07, 0x48, -+0x8C, 0x78, 0x0D, 0x88, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x04, 0x04, 0x19, 0x46, 0x70, 0x20, 0xA4, 0xF8, 0xBE, 0x54, -+0x09, 0xF0, 0x7A, 0xFC, 0x00, 0x20, 0x38, 0xBD, 0x18, 0x88, 0x17, 0x00, 0x10, 0xB5, 0x08, 0x4C, 0x08, 0x78, 0xD4, 0xF8, -+0xC8, 0x41, 0x82, 0xB0, 0x01, 0x92, 0x00, 0x93, 0xA0, 0x47, 0xDD, 0xE9, 0x00, 0x12, 0x0D, 0x20, 0x09, 0xF0, 0x68, 0xFC, -+0x00, 0x20, 0x02, 0xB0, 0x10, 0xBD, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x10, 0xB5, 0x07, 0x4C, 0x08, 0x78, 0x64, 0x6D, -+0x82, 0xB0, 0x01, 0x92, 0x00, 0x93, 0xA0, 0x47, 0xDD, 0xE9, 0x00, 0x12, 0x3A, 0x20, 0x09, 0xF0, 0x55, 0xFC, 0x00, 0x20, -+0x02, 0xB0, 0x10, 0xBD, 0x88, 0x1A, 0x17, 0x00, 0x70, 0xB5, 0x0C, 0x78, 0x08, 0x46, 0x19, 0x46, 0x24, 0xB1, 0x25, 0x4B, -+0x93, 0xF8, 0xA9, 0x30, 0x00, 0x2B, 0x36, 0xD1, 0x23, 0x4B, 0x24, 0x4E, 0x24, 0x4D, 0x00, 0x24, 0x1C, 0x70, 0x34, 0x68, -+0x24, 0xF0, 0x00, 0x74, 0x34, 0x60, 0x6C, 0x6F, 0x24, 0xF0, 0x10, 0x04, 0x6C, 0x67, 0x1E, 0x4D, 0x2C, 0x68, 0x24, 0xF4, -+0x00, 0x64, 0x2C, 0x60, 0xC4, 0x78, 0x9C, 0x70, 0x84, 0x78, 0x00, 0x25, 0x5D, 0x70, 0xC4, 0xB1, 0x1A, 0x4C, 0x23, 0x68, -+0x43, 0xF0, 0x00, 0x43, 0x23, 0x60, 0x03, 0x79, 0x63, 0xB1, 0x18, 0x4C, 0x85, 0x68, 0x18, 0x4B, 0x25, 0x60, 0x1C, 0x68, -+0xC4, 0xF3, 0x13, 0x04, 0x1C, 0x60, 0xC4, 0x68, 0x18, 0x68, 0x40, 0xEA, 0x04, 0x50, 0x18, 0x60, 0x66, 0x20, 0x09, 0xF0, -+0x17, 0xFC, 0x00, 0x20, 0x70, 0xBD, 0x0E, 0x4C, 0x23, 0x68, 0x23, 0xF0, 0x00, 0x43, 0x23, 0x60, 0xE5, 0xE7, 0x08, 0x4B, -+0x08, 0x4E, 0x09, 0x4D, 0x01, 0x24, 0x1C, 0x70, 0x34, 0x68, 0x44, 0xF0, 0x00, 0x74, 0x34, 0x60, 0x6C, 0x6F, 0x44, 0xF0, -+0x10, 0x04, 0x6C, 0x67, 0xC7, 0xE7, 0x00, 0xBF, 0x2C, 0x19, 0x17, 0x00, 0x4C, 0x36, 0x17, 0x00, 0xE0, 0x50, 0x34, 0x40, -+0x00, 0x00, 0x50, 0x40, 0x48, 0x30, 0x34, 0x40, 0xF4, 0x00, 0x60, 0x40, 0xF8, 0x00, 0x60, 0x40, 0x70, 0xB5, 0x08, 0x46, -+0x07, 0x4C, 0x09, 0x68, 0x46, 0x68, 0x05, 0x89, 0xC4, 0xF8, 0xBD, 0x10, 0x78, 0x20, 0x19, 0x46, 0xC4, 0xF8, 0xC1, 0x60, -+0xA4, 0xF8, 0xC5, 0x50, 0x09, 0xF0, 0xE2, 0xFB, 0x00, 0x20, 0x70, 0xBD, 0x2C, 0x19, 0x17, 0x00, 0x38, 0xB5, 0x08, 0x46, -+0x0E, 0x49, 0x44, 0x78, 0x0C, 0x70, 0x84, 0x78, 0x4C, 0x70, 0xC4, 0x78, 0x8C, 0x70, 0x0C, 0x4C, 0x05, 0x79, 0x41, 0x79, -+0x61, 0x70, 0x25, 0x70, 0xC1, 0x79, 0x85, 0x79, 0xA5, 0x70, 0xE1, 0x70, 0x08, 0x4C, 0x41, 0x68, 0x05, 0x68, 0xC4, 0xF8, -+0xCB, 0x10, 0x7A, 0x20, 0x19, 0x46, 0xC4, 0xF8, 0xC7, 0x50, 0x09, 0xF0, 0xC1, 0xFB, 0x00, 0x20, 0x38, 0xBD, 0x00, 0xBF, -+0x68, 0x25, 0x17, 0x00, 0x6C, 0x25, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x08, 0xB5, 0x04, 0x48, 0x09, 0x68, 0x01, 0x60, -+0x19, 0x46, 0x72, 0x20, 0x09, 0xF0, 0xB0, 0xFB, 0x00, 0x20, 0x08, 0xBD, 0x34, 0x00, 0x32, 0x40, 0x30, 0xB5, 0x19, 0x46, -+0x83, 0xB0, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x16, 0x4B, 0x01, 0x20, 0x18, 0x60, 0x16, 0x4C, -+0x16, 0x4D, 0x23, 0x68, 0x01, 0x33, 0xCD, 0xE9, 0x00, 0x21, 0x23, 0x60, 0x08, 0xF0, 0x12, 0xFA, 0xE7, 0xF7, 0x96, 0xFF, -+0x09, 0xF0, 0x02, 0xFB, 0x0E, 0xF0, 0x22, 0xF8, 0xD5, 0xF8, 0x10, 0x34, 0x98, 0x47, 0xD5, 0xF8, 0xA8, 0x31, 0x98, 0x47, -+0x23, 0x68, 0xDD, 0xE9, 0x00, 0x21, 0x33, 0xB1, 0x08, 0x48, 0x01, 0x3B, 0x00, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x00, 0xB1, -+0x62, 0xB6, 0x01, 0x20, 0x09, 0xF0, 0x7E, 0xFB, 0x00, 0x21, 0x08, 0x46, 0x09, 0xF0, 0x0C, 0xFD, 0x00, 0x20, 0x03, 0xB0, -+0x30, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0xB5, 0x18, 0x46, -+0x21, 0x4E, 0x02, 0x23, 0x0D, 0x46, 0x01, 0x46, 0x25, 0x20, 0x09, 0xF0, 0xFF, 0xFA, 0x33, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x04, 0x46, 0x0C, 0xDB, 0x1C, 0x4B, 0x28, 0x46, 0xD3, 0xF8, 0xB8, 0x31, 0x98, 0x47, 0x00, 0x25, 0x60, 0x70, -+0x25, 0x70, 0x20, 0x46, 0x09, 0xF0, 0x1E, 0xFB, 0x28, 0x46, 0x70, 0xBD, 0x2B, 0x78, 0x05, 0x2B, 0x19, 0xD8, 0x2B, 0x79, -+0x20, 0x2B, 0x0A, 0xD8, 0x95, 0xF8, 0x28, 0x30, 0x05, 0x2B, 0xE8, 0xD9, 0x11, 0x49, 0x12, 0x48, 0x40, 0xF2, 0xFB, 0x62, -+0x0B, 0xF0, 0xBE, 0xFB, 0xE1, 0xE7, 0x0E, 0x49, 0x0F, 0x48, 0x4F, 0xF4, 0xDF, 0x62, 0x0B, 0xF0, 0xB7, 0xFB, 0x33, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xE9, 0xDB, 0xD5, 0xE7, 0x08, 0x49, 0x0A, 0x48, 0x40, 0xF2, 0xF2, 0x62, 0x0B, 0xF0, -+0xAB, 0xFB, 0x33, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xDA, 0xDB, 0xC9, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xE4, 0x9B, 0x15, 0x00, 0xBC, 0x9B, 0x15, 0x00, 0x90, 0x9B, 0x15, 0x00, -+0x11, 0x48, 0x00, 0x68, 0xB0, 0xF9, 0x00, 0x00, 0x00, 0x28, 0x70, 0xB5, 0x0C, 0x46, 0x16, 0x46, 0x1D, 0x46, 0x0B, 0xDB, -+0x20, 0x78, 0x0D, 0x4B, 0xD3, 0xF8, 0xB4, 0x31, 0x98, 0x47, 0x32, 0x46, 0x29, 0x46, 0x27, 0x20, 0x09, 0xF0, 0x0A, 0xFB, -+0x00, 0x20, 0x70, 0xBD, 0x08, 0x4B, 0x08, 0x78, 0x1B, 0x68, 0x1B, 0x0E, 0x09, 0x33, 0x98, 0x42, 0xED, 0xDD, 0x06, 0x49, -+0x06, 0x48, 0x40, 0xF2, 0x22, 0x72, 0x0B, 0xF0, 0x75, 0xFB, 0xE5, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xD8, 0x00, 0x32, 0x40, 0x70, 0x79, 0x15, 0x00, 0x14, 0x9C, 0x15, 0x00, 0x16, 0x48, 0x2D, 0xE9, 0xF0, 0x41, 0x00, 0x68, -+0x15, 0x4F, 0x0C, 0x46, 0xB0, 0xF9, 0x00, 0x10, 0x25, 0x78, 0x00, 0x29, 0x16, 0x46, 0x98, 0x46, 0x11, 0xDB, 0x4F, 0xF4, -+0xA4, 0x60, 0x00, 0xFB, 0x05, 0x70, 0x62, 0x88, 0xA0, 0xF8, 0x68, 0x20, 0x23, 0x79, 0x80, 0xF8, 0x6A, 0x30, 0x32, 0x46, -+0x41, 0x46, 0x4C, 0x20, 0x09, 0xF0, 0xD4, 0xFA, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, -+0x05, 0x72, 0x92, 0xF8, 0x62, 0x20, 0x00, 0x2A, 0xE5, 0xD0, 0x05, 0x49, 0x05, 0x48, 0x40, 0xF6, 0x5B, 0x22, 0x0B, 0xF0, -+0x3D, 0xFB, 0xDE, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x40, 0x9C, 0x15, 0x00, -+0x13, 0x4B, 0x70, 0xB5, 0x1B, 0x68, 0x0C, 0x78, 0xB3, 0xF9, 0x00, 0x30, 0x11, 0x4E, 0x00, 0x2B, 0x0D, 0x46, 0x0D, 0xDB, -+0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x04, 0x63, 0x6A, 0x78, 0x83, 0xF8, 0x87, 0x20, 0xAA, 0x78, 0x83, 0xF8, 0x88, 0x20, -+0x00, 0x20, 0x83, 0xF8, 0x89, 0x00, 0x70, 0xBD, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x04, 0x63, 0x93, 0xF8, 0x62, 0x30, -+0x00, 0x2B, 0xE9, 0xD0, 0x05, 0x49, 0x06, 0x48, 0x40, 0xF6, 0x78, 0x52, 0x0B, 0xF0, 0x0E, 0xFB, 0xE2, 0xE7, 0x00, 0xBF, -+0x38, 0x36, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x40, 0x9C, 0x15, 0x00, 0x20, 0x48, 0x2D, 0xE9, -+0xF0, 0x41, 0x00, 0x68, 0xB0, 0xF9, 0x00, 0x00, 0x00, 0x28, 0x84, 0xB0, 0x0E, 0x46, 0x15, 0x46, 0x98, 0x46, 0x29, 0xDB, -+0x30, 0x46, 0xE7, 0xF7, 0xAB, 0xFD, 0x00, 0x24, 0x19, 0x4F, 0x00, 0x94, 0x40, 0xF6, 0xB4, 0x13, 0x21, 0x46, 0x1A, 0x46, -+0x20, 0x46, 0xCD, 0xE9, 0x01, 0x44, 0xE7, 0xF7, 0xEB, 0xFD, 0xD7, 0xF8, 0x3C, 0x33, 0x0F, 0x20, 0x98, 0x47, 0x13, 0x4B, -+0xB6, 0xF8, 0x44, 0x20, 0x9A, 0x83, 0x41, 0x46, 0x2A, 0x46, 0x03, 0x20, 0x09, 0xF0, 0x62, 0xFA, 0xD7, 0xF8, 0x60, 0x31, -+0x98, 0x47, 0xD7, 0xF8, 0xE0, 0x30, 0x98, 0x47, 0x28, 0x46, 0x02, 0x21, 0x09, 0xF0, 0xEA, 0xFB, 0x20, 0x46, 0x04, 0xB0, -+0xBD, 0xE8, 0xF0, 0x81, 0x10, 0x46, 0x09, 0xF0, 0x8B, 0xFC, 0x00, 0x28, 0xD0, 0xD0, 0x06, 0x49, 0x06, 0x48, 0x4F, 0xF4, -+0xA7, 0x72, 0x0B, 0xF0, 0xC3, 0xFA, 0xC9, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x58, 0x9C, 0x15, 0x00, 0x70, 0xB5, 0x0C, 0x46, 0x49, 0x78, 0x16, 0x46, 0x1D, 0x46, 0xE1, 0xB1, -+0x01, 0x29, 0x63, 0x88, 0x3C, 0xD0, 0x02, 0x29, 0x32, 0xD0, 0x03, 0x29, 0x0C, 0xBF, 0x20, 0x48, 0x20, 0x48, 0xA2, 0x88, -+0x18, 0x44, 0x04, 0xF1, 0x08, 0x01, 0x1D, 0xF0, 0x49, 0xFD, 0xE3, 0x88, 0x23, 0xB1, 0x1D, 0x4B, 0x20, 0x78, 0xD3, 0xF8, -+0x80, 0x34, 0x98, 0x47, 0x32, 0x46, 0x29, 0x46, 0x68, 0x20, 0x09, 0xF0, 0x1D, 0xFA, 0x00, 0x20, 0x70, 0xBD, 0x04, 0xF1, -+0x08, 0x01, 0x4F, 0xF4, 0x40, 0x72, 0x16, 0x48, 0x1D, 0xF0, 0x34, 0xFD, 0x04, 0xF5, 0x42, 0x71, 0x4F, 0xF4, 0x00, 0x72, -+0x13, 0x48, 0x1D, 0xF0, 0x2D, 0xFD, 0x04, 0xF5, 0xA1, 0x61, 0x80, 0x22, 0x0C, 0x48, 0x1D, 0xF0, 0x27, 0xFD, 0x40, 0x22, -+0x04, 0xF5, 0xB1, 0x61, 0x0A, 0x48, 0x1D, 0xF0, 0x21, 0xFD, 0xD6, 0xE7, 0x0B, 0x48, 0xA2, 0x88, 0x18, 0x44, 0x04, 0xF1, -+0x08, 0x01, 0x1D, 0xF0, 0x19, 0xFD, 0xCE, 0xE7, 0x06, 0x48, 0xA2, 0x88, 0x18, 0x44, 0x04, 0xF1, 0x08, 0x01, 0x1D, 0xF0, -+0x11, 0xFD, 0xC6, 0xE7, 0x1C, 0x18, 0x17, 0x00, 0x9C, 0x18, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x1C, 0x13, 0x17, 0x00, -+0x1C, 0x16, 0x17, 0x00, 0x38, 0xB5, 0x19, 0x46, 0x81, 0x20, 0x40, 0x23, 0x09, 0xF0, 0x78, 0xF9, 0x00, 0x25, 0x04, 0x46, -+0x08, 0x49, 0x00, 0xF8, 0x01, 0x5B, 0x24, 0x22, 0x1D, 0xF0, 0xF8, 0xFC, 0x23, 0x78, 0x24, 0x33, 0xDB, 0xB2, 0xE2, 0x18, -+0x23, 0x70, 0x20, 0x46, 0x55, 0x70, 0x09, 0xF0, 0x97, 0xF9, 0x28, 0x46, 0x38, 0xBD, 0x00, 0xBF, 0xDC, 0xD1, 0x15, 0x00, -+0x10, 0xB5, 0x82, 0xB0, 0x08, 0x46, 0x1C, 0x46, 0x01, 0x92, 0xFA, 0xF7, 0x83, 0xFA, 0x06, 0x49, 0x4F, 0xF4, 0x80, 0x70, -+0x0B, 0xF0, 0x0E, 0xF8, 0x01, 0x9A, 0x21, 0x46, 0x6C, 0x20, 0x09, 0xF0, 0xB9, 0xF9, 0x00, 0x20, 0x02, 0xB0, 0x10, 0xBD, -+0x7C, 0x9C, 0x15, 0x00, 0x25, 0x48, 0x2D, 0xE9, 0xF8, 0x43, 0x00, 0x68, 0xDF, 0xF8, 0xA0, 0x90, 0x0C, 0x46, 0xB0, 0xF9, -+0x00, 0x10, 0x65, 0x79, 0x00, 0x29, 0x17, 0x46, 0x1E, 0x46, 0x2D, 0xDB, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x05, 0xF0, -+0x09, 0xEB, 0x00, 0x08, 0x21, 0x79, 0x98, 0xF8, 0xAC, 0x20, 0x23, 0x68, 0xC8, 0xF8, 0xC4, 0x34, 0x01, 0x2A, 0x88, 0xF8, -+0xC3, 0x14, 0x0A, 0xD1, 0x17, 0x4B, 0xB0, 0x30, 0xD3, 0xF8, 0xD8, 0x31, 0x48, 0x44, 0x98, 0x47, 0x00, 0x22, 0xD8, 0xF8, -+0xC4, 0x34, 0x88, 0xF8, 0xAC, 0x20, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x05, 0x95, 0x11, 0x49, 0x95, 0xF8, 0xC3, 0x24, -+0x4F, 0xF4, 0x80, 0x70, 0x0A, 0xF0, 0xD0, 0xFF, 0x3A, 0x46, 0x31, 0x46, 0x62, 0x20, 0x09, 0xF0, 0x7B, 0xF9, 0x00, 0x20, -+0xBD, 0xE8, 0xF8, 0x83, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x05, 0x93, 0x93, 0xF8, 0x62, 0x30, 0x00, 0x2B, 0xC9, 0xD0, -+0x06, 0x49, 0x07, 0x48, 0x4F, 0xF4, 0x27, 0x62, 0x0B, 0xF0, 0xE4, 0xF9, 0xC2, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x8C, 0x9C, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, 0x40, 0x9C, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x00, 0xB5, 0x83, 0xB0, 0x08, 0x46, 0x01, 0x92, 0x00, 0x93, 0xFA, 0xF7, 0x45, 0xFA, 0xDD, 0xE9, 0x00, 0x12, 0x6E, 0x20, -+0x09, 0xF0, 0x50, 0xF9, 0x00, 0x20, 0x03, 0xB0, 0x5D, 0xF8, 0x04, 0xFB, 0xF0, 0xB5, 0x0C, 0x46, 0x0E, 0x78, 0x60, 0x78, -+0x89, 0x78, 0x83, 0xB0, 0x1D, 0x46, 0x01, 0x92, 0x9E, 0xB9, 0xFE, 0xF7, 0xD5, 0xFE, 0x01, 0x9A, 0x00, 0xBB, 0x03, 0x26, -+0x29, 0x46, 0x03, 0x23, 0x2B, 0x20, 0x09, 0xF0, 0xD1, 0xF8, 0x62, 0x78, 0x02, 0x70, 0xA2, 0x78, 0x42, 0x70, 0x86, 0x70, -+0x09, 0xF0, 0xFA, 0xF8, 0x00, 0x20, 0x03, 0xB0, 0xF0, 0xBD, 0xFE, 0xF7, 0xD1, 0xFE, 0x01, 0x9A, 0x00, 0x28, 0xEA, 0xD0, -+0x60, 0x78, 0x14, 0x4B, 0xA1, 0x78, 0x4F, 0xF4, 0x1E, 0x76, 0x06, 0xFB, 0x00, 0x30, 0x15, 0xF0, 0x9D, 0xFC, 0x02, 0x26, -+0x01, 0x9A, 0xDF, 0xE7, 0x61, 0x78, 0x94, 0xF8, 0x02, 0xC0, 0x0D, 0x48, 0x0D, 0x4F, 0x01, 0xEB, 0x81, 0x03, 0xC1, 0xEB, -+0x03, 0x13, 0x63, 0x44, 0x00, 0xEB, 0xC3, 0x03, 0x4F, 0xF0, 0x9E, 0x0E, 0x93, 0xF8, 0xA5, 0x31, 0x0E, 0xFB, 0x01, 0xC1, -+0x03, 0xEB, 0x43, 0x03, 0x00, 0xEB, 0x81, 0x01, 0x07, 0xEB, 0xC3, 0x03, 0x81, 0xF8, 0x5A, 0x61, 0x1E, 0x81, 0x02, 0x26, -+0xC2, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0xF4, 0xE4, 0x17, 0x00, 0x08, 0xB5, 0x08, 0x46, 0x02, 0xF0, 0x0C, 0xFA, -+0x01, 0x20, 0x08, 0xBD, 0x70, 0xB5, 0x48, 0x78, 0xFF, 0x28, 0x0C, 0x46, 0x16, 0x46, 0x1D, 0x46, 0x01, 0xD0, 0x17, 0xF0, -+0xB3, 0xF9, 0x21, 0x78, 0xA0, 0x78, 0x0A, 0x4B, 0x0A, 0x4A, 0x00, 0x39, 0x18, 0xBF, 0x01, 0x21, 0x00, 0x38, 0x18, 0xBF, -+0x01, 0x20, 0x18, 0x70, 0x11, 0x70, 0x02, 0x46, 0x06, 0x48, 0x0A, 0xF0, 0xDD, 0xFE, 0x32, 0x46, 0x29, 0x46, 0x64, 0x20, -+0x09, 0xF0, 0xD8, 0xF8, 0x00, 0x20, 0x70, 0xBD, 0xB9, 0x34, 0x17, 0x00, 0xB8, 0x34, 0x17, 0x00, 0x9C, 0x9C, 0x15, 0x00, -+0xF8, 0xB5, 0x19, 0x46, 0x74, 0x20, 0x06, 0x23, 0x09, 0xF0, 0x62, 0xF8, 0x4F, 0xF4, 0xD2, 0x77, 0x04, 0x46, 0x3B, 0x68, -+0x08, 0x20, 0x98, 0x47, 0x3B, 0x68, 0x06, 0x46, 0x09, 0x20, 0x98, 0x47, 0x36, 0x0C, 0x36, 0x04, 0x56, 0xEA, 0x00, 0x03, -+0x1A, 0xD1, 0x3B, 0x68, 0x07, 0x20, 0x98, 0x47, 0x3B, 0x68, 0x05, 0x46, 0x08, 0x20, 0x98, 0x47, 0x83, 0xB2, 0x19, 0x0A, -+0x28, 0x0A, 0x2A, 0x0C, 0x63, 0x70, 0x2B, 0x0E, 0x21, 0x70, 0x20, 0x71, 0xE2, 0x70, 0xA3, 0x70, 0xEA, 0xB2, 0x07, 0x48, -+0x65, 0x71, 0x0A, 0xF0, 0xA5, 0xFE, 0x20, 0x46, 0x09, 0xF0, 0x6A, 0xF8, 0x00, 0x20, 0xF8, 0xBD, 0x05, 0x04, 0x45, 0xEA, -+0x16, 0x45, 0x03, 0x0C, 0xE7, 0xE7, 0x00, 0xBF, 0xC0, 0x9C, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x0C, 0x46, 0x48, 0x7A, -+0x09, 0x7A, 0x16, 0x46, 0xE2, 0x88, 0x84, 0xB0, 0xCD, 0xE9, 0x00, 0x21, 0x02, 0x90, 0x62, 0x88, 0x5E, 0x48, 0x21, 0x88, -+0x1D, 0x46, 0xA3, 0x88, 0x0A, 0xF0, 0x86, 0xFE, 0xB4, 0xF8, 0x00, 0xC0, 0x67, 0x88, 0xA0, 0x88, 0xE2, 0x88, 0x5A, 0x4B, -+0xBC, 0xF1, 0x00, 0x0F, 0x00, 0xF0, 0x9E, 0x80, 0x19, 0x68, 0xDF, 0xF8, 0x70, 0x81, 0x0B, 0x68, 0xDF, 0xF8, 0x6C, 0xE1, -+0x03, 0xEA, 0x08, 0x03, 0x43, 0xEA, 0x0C, 0x33, 0x0B, 0x60, 0xDE, 0xF8, 0x00, 0x30, 0x03, 0xEA, 0x08, 0x03, 0x43, 0xEA, -+0x0C, 0x33, 0xCE, 0xF8, 0x00, 0x30, 0x00, 0x2F, 0x79, 0xD0, 0x4B, 0x68, 0xDF, 0xF8, 0x44, 0xE1, 0xDF, 0xF8, 0x48, 0xC1, -+0x03, 0xEA, 0x0E, 0x03, 0x43, 0xEA, 0x07, 0x33, 0x4B, 0x60, 0xDC, 0xF8, 0x00, 0x30, 0x03, 0xEA, 0x0E, 0x03, 0x43, 0xEA, -+0x07, 0x33, 0xCC, 0xF8, 0x00, 0x30, 0x00, 0x28, 0x3F, 0xD0, 0x8F, 0x68, 0xDF, 0xF8, 0x1C, 0xE1, 0xDF, 0xF8, 0x14, 0xC1, -+0x07, 0xEA, 0x0E, 0x07, 0x47, 0xEA, 0x00, 0x37, 0x8F, 0x60, 0xDC, 0xF8, 0x00, 0x30, 0x03, 0xEA, 0x0E, 0x03, 0x43, 0xEA, -+0x00, 0x33, 0xCC, 0xF8, 0x00, 0x30, 0x00, 0x2A, 0x38, 0xD0, 0xC8, 0x68, 0xDF, 0xF8, 0xF4, 0xC0, 0x38, 0x4F, 0x00, 0xEA, -+0x0C, 0x00, 0x40, 0xEA, 0x02, 0x30, 0xC8, 0x60, 0x3B, 0x68, 0x03, 0xEA, 0x0C, 0x03, 0x43, 0xEA, 0x02, 0x33, 0x3B, 0x60, -+0x23, 0x7A, 0x33, 0x4A, 0x00, 0x2B, 0x31, 0xD0, 0x13, 0x68, 0x43, 0xF0, 0x10, 0x03, 0x13, 0x60, 0x63, 0x7A, 0x2F, 0x4A, -+0x00, 0x2B, 0x31, 0xD0, 0x13, 0x68, 0x43, 0xF0, 0x02, 0x03, 0x13, 0x60, 0x2C, 0x4B, 0xD3, 0xF8, 0xA0, 0x31, 0x98, 0x47, -+0x32, 0x46, 0x29, 0x46, 0x7F, 0x20, 0x09, 0xF0, 0x17, 0xF8, 0x00, 0x20, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x88, 0x68, -+0xDF, 0xF8, 0x9C, 0xC0, 0x25, 0x4F, 0x00, 0xEA, 0x0C, 0x00, 0x88, 0x60, 0x3B, 0x68, 0x03, 0xEA, 0x0C, 0x03, 0x3B, 0x60, -+0x00, 0x2A, 0xC6, 0xD1, 0xCA, 0x68, 0x21, 0x4F, 0x1C, 0x48, 0x3A, 0x40, 0xCA, 0x60, 0x03, 0x68, 0x1B, 0x4A, 0x3B, 0x40, -+0x03, 0x60, 0x23, 0x7A, 0x00, 0x2B, 0xCD, 0xD1, 0x13, 0x68, 0x23, 0xF0, 0x10, 0x03, 0x13, 0x60, 0x63, 0x7A, 0x16, 0x4A, -+0x00, 0x2B, 0xCD, 0xD1, 0x13, 0x68, 0x23, 0xF0, 0x02, 0x03, 0x13, 0x60, 0xCC, 0xE7, 0x4F, 0x68, 0xDF, 0xF8, 0x50, 0xE0, -+0xDF, 0xF8, 0x54, 0xC0, 0x07, 0xEA, 0x0E, 0x07, 0x4F, 0x60, 0xDC, 0xF8, 0x00, 0x30, 0x03, 0xEA, 0x0E, 0x03, 0xCC, 0xF8, -+0x00, 0x30, 0x88, 0xE7, 0x19, 0x68, 0xDF, 0xF8, 0x34, 0xE0, 0x0B, 0x68, 0xDF, 0xF8, 0x30, 0xC0, 0x03, 0xEA, 0x0E, 0x03, -+0x0B, 0x60, 0xDC, 0xF8, 0x00, 0x30, 0x03, 0xEA, 0x0E, 0x03, 0xCC, 0xF8, 0x00, 0x30, 0x64, 0xE7, 0xD8, 0x9C, 0x15, 0x00, -+0xAC, 0x35, 0x17, 0x00, 0x0C, 0x02, 0x32, 0x40, 0x24, 0x02, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x08, 0x02, 0x32, 0x40, -+0xFF, 0x0F, 0x00, 0xF0, 0x00, 0x02, 0x32, 0x40, 0x04, 0x02, 0x32, 0x40, 0x2D, 0xE9, 0xF0, 0x4F, 0x8A, 0x46, 0x83, 0xB0, -+0x49, 0x7C, 0x28, 0x48, 0xDF, 0xF8, 0xBC, 0x90, 0x27, 0x4F, 0x16, 0x46, 0xDA, 0xF8, 0x0C, 0x20, 0x00, 0x92, 0x01, 0x91, -+0x9A, 0xF8, 0x10, 0xB0, 0xDA, 0xF8, 0x00, 0x10, 0x1D, 0x46, 0xDA, 0xE9, 0x01, 0x23, 0x0A, 0xF0, 0xA5, 0xFD, 0x21, 0x4A, -+0x21, 0x49, 0x9A, 0xF8, 0x11, 0x00, 0x82, 0xF8, 0x05, 0x01, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x0B, 0xF3, 0x03, 0xF1, -+0x08, 0x02, 0x01, 0xEB, 0x02, 0x08, 0x01, 0xEB, 0x03, 0x0B, 0xAA, 0xF1, 0x04, 0x0A, 0x00, 0x24, 0x5A, 0xF8, 0x04, 0x0F, -+0xE3, 0xB2, 0x90, 0xB1, 0x48, 0xF8, 0x24, 0x00, 0x16, 0x4A, 0x9B, 0xF8, 0x64, 0x10, 0x12, 0x68, 0x42, 0xF8, 0x24, 0x00, -+0x49, 0xB1, 0x01, 0x2C, 0x13, 0xD0, 0x02, 0x2B, 0x17, 0xD0, 0x9B, 0xB1, 0x38, 0x60, 0x11, 0x4B, 0xD3, 0xF8, 0xA0, 0x31, -+0x98, 0x47, 0x01, 0x34, 0x04, 0x2C, 0xE5, 0xD1, 0x32, 0x46, 0x29, 0x46, 0x83, 0x20, 0x08, 0xF0, 0x73, 0xFF, 0x00, 0x20, -+0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xC9, 0xF8, 0x00, 0x00, 0xEC, 0xE7, 0x08, 0x4B, 0x18, 0x60, 0xE9, 0xE7, 0x08, 0x4B, -+0x18, 0x60, 0xE6, 0xE7, 0x18, 0x9D, 0x15, 0x00, 0x0C, 0x02, 0x32, 0x40, 0x2C, 0x19, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0xAC, 0x35, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x00, 0x02, 0x32, 0x40, 0x08, 0x02, 0x32, 0x40, 0x04, 0x02, 0x32, 0x40, -+0xF8, 0xB5, 0x7C, 0x20, 0x0C, 0x46, 0x19, 0x46, 0x02, 0x23, 0x08, 0xF0, 0xE5, 0xFE, 0x23, 0x78, 0x05, 0x46, 0x00, 0x2B, -+0x5F, 0xD0, 0x35, 0x48, 0x0A, 0xF0, 0x46, 0xFD, 0x34, 0x4B, 0x1B, 0x68, 0x00, 0x22, 0x1A, 0x70, 0x4F, 0xF4, 0xD2, 0x73, -+0x0F, 0x20, 0x1B, 0x68, 0x98, 0x47, 0x68, 0x70, 0x62, 0x78, 0x06, 0x46, 0x00, 0x2A, 0x45, 0xD0, 0x2E, 0x4F, 0xC0, 0xF3, -+0x40, 0x11, 0x42, 0x06, 0x87, 0xF8, 0xB4, 0x10, 0x4F, 0xD4, 0x2C, 0x48, 0x0F, 0x22, 0x01, 0x21, 0xE8, 0xF7, 0x1C, 0xFC, -+0x02, 0x22, 0x11, 0x46, 0x29, 0x48, 0xE8, 0xF7, 0x17, 0xFC, 0x02, 0x22, 0x11, 0x46, 0x28, 0x48, 0xE8, 0xF7, 0x12, 0xFC, -+0x4F, 0xF4, 0x00, 0x52, 0x11, 0x46, 0x24, 0x48, 0xE8, 0xF7, 0x0C, 0xFC, 0x4F, 0xF4, 0x00, 0x52, 0x11, 0x46, 0x22, 0x48, -+0xE8, 0xF7, 0x06, 0xFC, 0x02, 0x22, 0x11, 0x46, 0x20, 0x48, 0xE8, 0xF7, 0x01, 0xFC, 0x4F, 0xF4, 0x00, 0x52, 0x00, 0x21, -+0x1D, 0x48, 0xE8, 0xF7, 0xFB, 0xFB, 0x97, 0xF8, 0xB4, 0x10, 0x01, 0x22, 0x23, 0x78, 0x6B, 0xB1, 0xE3, 0x78, 0x2B, 0xB1, -+0xB7, 0xF8, 0xAA, 0x30, 0x43, 0xF4, 0x80, 0x43, 0xA7, 0xF8, 0xAA, 0x30, 0x16, 0x48, 0xF3, 0xB2, 0x0A, 0xF0, 0xFA, 0xFC, -+0x97, 0xF8, 0xB4, 0x10, 0x29, 0x70, 0x28, 0x46, 0x08, 0xF0, 0xBC, 0xFE, 0x00, 0x20, 0xF8, 0xBD, 0xA3, 0x78, 0x0B, 0x4F, -+0xC3, 0xF3, 0x40, 0x11, 0x5B, 0x06, 0x87, 0xF8, 0xB4, 0x10, 0xB8, 0xD5, 0xE0, 0xE7, 0x0D, 0x48, 0x0A, 0xF0, 0xE6, 0xFC, -+0x04, 0x4B, 0x1B, 0x68, 0x03, 0x22, 0x1A, 0x70, 0x9E, 0xE7, 0x00, 0x22, 0xD6, 0xE7, 0x00, 0xBF, 0x48, 0x9D, 0x15, 0x00, -+0x74, 0x36, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x04, 0x20, 0x01, 0x50, 0x04, 0x10, 0x01, 0x50, 0x08, 0x10, 0x01, 0x50, -+0x00, 0x10, 0x01, 0x50, 0x68, 0x9D, 0x15, 0x00, 0x58, 0x9D, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x18, 0x46, 0xB1, 0xB0, -+0x0C, 0x46, 0x10, 0x23, 0x01, 0x46, 0x6A, 0x20, 0x04, 0x94, 0x08, 0xF0, 0x59, 0xFE, 0x4F, 0xF4, 0xD2, 0x73, 0x02, 0x46, -+0x1B, 0x68, 0x05, 0x92, 0x06, 0x20, 0x98, 0x47, 0x04, 0x46, 0x01, 0x46, 0x91, 0x48, 0x0A, 0xF0, 0xB5, 0xFC, 0x14, 0xF4, -+0x7F, 0x4F, 0xC4, 0xF3, 0x07, 0x25, 0x6F, 0xD1, 0x26, 0x0E, 0xE5, 0xB2, 0x6E, 0xD0, 0xF4, 0xB2, 0x00, 0x2D, 0x6F, 0xD1, -+0x04, 0x9B, 0x19, 0x7D, 0x00, 0x29, 0x40, 0xF0, 0x83, 0x80, 0x00, 0x2E, 0x40, 0xF0, 0x89, 0x80, 0x59, 0x7D, 0x31, 0xB1, -+0x86, 0x48, 0x0A, 0xF0, 0x9D, 0xFC, 0x04, 0x9B, 0x5C, 0x7D, 0x00, 0x2C, 0x7F, 0xD1, 0x04, 0x9B, 0xDB, 0x68, 0x00, 0x2B, -+0x40, 0xF0, 0x8D, 0x80, 0x04, 0x9B, 0xDF, 0xF8, 0x40, 0xB2, 0x99, 0x68, 0x1A, 0x68, 0x7F, 0x4B, 0xDF, 0xF8, 0x38, 0xA2, -+0xD3, 0xF8, 0x70, 0x32, 0x7D, 0x4C, 0xCD, 0xE9, 0x08, 0x21, 0x08, 0xA8, 0x0A, 0xA9, 0x98, 0x47, 0x1A, 0xAE, 0x6F, 0xF0, -+0x3F, 0x08, 0x09, 0xAF, 0x0A, 0xAB, 0x07, 0x97, 0xA8, 0xEB, 0x03, 0x08, 0x35, 0x46, 0x0D, 0xF1, 0x78, 0x09, 0x06, 0x96, -+0xE3, 0x79, 0x00, 0x93, 0x08, 0xEB, 0x05, 0x02, 0x23, 0x68, 0x03, 0x92, 0x59, 0x46, 0x4F, 0xF4, 0x00, 0x50, 0x0A, 0xF0, -+0xBD, 0xFC, 0x15, 0xF8, 0x01, 0x6B, 0x57, 0xF8, 0x04, 0x3F, 0x03, 0x9A, 0x00, 0x96, 0x51, 0x46, 0x23, 0x60, 0xE6, 0x71, -+0x4F, 0xF4, 0x00, 0x50, 0x0A, 0xF0, 0xB0, 0xFC, 0x4D, 0x45, 0x04, 0xF1, 0x10, 0x04, 0xE3, 0xD1, 0xDF, 0xF8, 0xD8, 0xB1, -+0x06, 0x9E, 0x9B, 0xF8, 0xB4, 0x30, 0x00, 0x2B, 0x52, 0xD1, 0xDF, 0xF8, 0xD0, 0xA1, 0x61, 0x4B, 0x00, 0x20, 0xD3, 0xF8, -+0xB0, 0x34, 0x98, 0x47, 0x05, 0x98, 0x5F, 0x4C, 0x5F, 0x4A, 0x60, 0x4B, 0x82, 0x60, 0xC0, 0xE9, 0x00, 0x4A, 0xC3, 0x60, -+0x08, 0xF0, 0x0C, 0xFE, 0x00, 0x20, 0x31, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x23, 0x0E, 0x0B, 0xD1, 0x26, 0x0C, 0xF4, 0xB2, -+0x00, 0x2D, 0x8F, 0xD0, 0x3C, 0xB9, 0x04, 0x9B, 0x59, 0x7D, 0x00, 0x29, 0x40, 0xF0, 0x99, 0x80, 0x00, 0x24, 0x00, 0xE0, -+0xDC, 0xB2, 0x1F, 0x2D, 0x28, 0xBF, 0x1F, 0x25, 0xE9, 0x06, 0x41, 0xEA, 0x85, 0x51, 0x51, 0x4A, 0x51, 0x48, 0xE8, 0xF7, -+0x17, 0xFB, 0x51, 0x48, 0x29, 0x46, 0x0A, 0xF0, 0x23, 0xFC, 0x86, 0xE7, 0x4F, 0x48, 0x0A, 0xF0, 0x1F, 0xFC, 0x04, 0x9B, -+0x1D, 0x7D, 0x00, 0x2E, 0x70, 0xD0, 0x00, 0x2D, 0xE7, 0xD1, 0x3F, 0x2C, 0x21, 0x46, 0x4B, 0x48, 0x28, 0xBF, 0x3F, 0x21, -+0x3F, 0x22, 0x03, 0x91, 0xE8, 0xF7, 0x00, 0xFB, 0x03, 0x99, 0x48, 0x48, 0x0A, 0xF0, 0x0C, 0xFC, 0x04, 0x9B, 0xDB, 0x68, -+0x00, 0x2B, 0x3F, 0xF4, 0x73, 0xAF, 0x04, 0x9B, 0x18, 0x69, 0xEB, 0xF7, 0x6F, 0xF8, 0x6D, 0xE7, 0x42, 0x4A, 0x38, 0x4D, -+0x93, 0x69, 0xD5, 0xF8, 0x28, 0x42, 0xDF, 0xF8, 0x20, 0xA1, 0x40, 0x4F, 0x43, 0xF0, 0x01, 0x03, 0x93, 0x61, 0x04, 0x9B, -+0x5B, 0x68, 0x08, 0x93, 0x41, 0xF2, 0x7C, 0x52, 0x00, 0x23, 0x11, 0x46, 0xCD, 0xE9, 0x00, 0x33, 0x01, 0x20, 0xA0, 0x47, -+0x39, 0x4A, 0x01, 0x23, 0x82, 0xF8, 0x2A, 0x30, 0x0A, 0xA9, 0xD5, 0xF8, 0x70, 0x32, 0x37, 0x4D, 0x08, 0xA8, 0x98, 0x47, -+0x54, 0x46, 0xCD, 0xF8, 0x10, 0xA0, 0xDD, 0xF8, 0x1C, 0xA0, 0xE3, 0x79, 0x00, 0x93, 0x06, 0xEB, 0x08, 0x02, 0x23, 0x68, -+0x03, 0x92, 0x39, 0x46, 0x4F, 0xF4, 0x00, 0x50, 0x0A, 0xF0, 0x22, 0xFC, 0x16, 0xF8, 0x01, 0xCB, 0x5A, 0xF8, 0x04, 0x3F, -+0x03, 0x9A, 0xCD, 0xF8, 0x00, 0xC0, 0x29, 0x46, 0x23, 0x60, 0x84, 0xF8, 0x07, 0xC0, 0x4F, 0xF4, 0x00, 0x50, 0x0A, 0xF0, -+0x13, 0xFC, 0x4E, 0x45, 0x04, 0xF1, 0x10, 0x04, 0xE1, 0xD1, 0x9B, 0xF8, 0xB4, 0x30, 0xDD, 0xF8, 0x10, 0xA0, 0x00, 0x2B, -+0x3F, 0xF4, 0x65, 0xAF, 0x13, 0x4B, 0x00, 0x20, 0xD3, 0xF8, 0x80, 0x34, 0x98, 0x47, 0x1D, 0x4B, 0x1E, 0x49, 0x93, 0xF8, -+0x2A, 0x20, 0x08, 0x20, 0x00, 0x23, 0x0A, 0xF0, 0xFB, 0xFB, 0x5B, 0xE7, 0x59, 0x7D, 0x1C, 0x46, 0x39, 0xB1, 0x0A, 0x48, -+0x0A, 0xF0, 0xA4, 0xFB, 0x64, 0x7D, 0x00, 0x2D, 0x3F, 0xF4, 0x05, 0xAF, 0x6D, 0xE7, 0x00, 0x2D, 0x3F, 0xF4, 0x03, 0xAF, -+0x66, 0xE7, 0x04, 0x48, 0x0A, 0xF0, 0x98, 0xFB, 0x04, 0x9B, 0x5C, 0x7D, 0x63, 0xE7, 0x00, 0xBF, 0x90, 0x9D, 0x15, 0x00, -+0xBC, 0x9D, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x1C, 0x13, 0x17, 0x00, 0x1C, 0x18, 0x17, 0x00, 0x9C, 0x18, 0x17, 0x00, -+0x00, 0x00, 0xC0, 0xFF, 0x04, 0x88, 0x01, 0x50, 0xD0, 0x9D, 0x15, 0x00, 0xAC, 0x9D, 0x15, 0x00, 0x28, 0x91, 0x01, 0x50, -+0xE4, 0x9D, 0x15, 0x00, 0x00, 0x80, 0x50, 0x40, 0x44, 0x9E, 0x15, 0x00, 0xBC, 0x34, 0x17, 0x00, 0x64, 0x9E, 0x15, 0x00, -+0x9C, 0x77, 0x15, 0x00, 0xFC, 0x9D, 0x15, 0x00, 0x20, 0x9E, 0x15, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x1C, 0x16, 0x17, 0x00, -+0x38, 0xB5, 0x00, 0x22, 0x0D, 0x46, 0x01, 0x23, 0x0C, 0x21, 0x54, 0x20, 0x08, 0xF0, 0xFA, 0xFC, 0x01, 0x23, 0x03, 0x70, -+0x04, 0x46, 0x28, 0x78, 0x04, 0x28, 0x0D, 0xD8, 0x0C, 0x4B, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x00, 0x30, 0x90, 0xF8, -+0xC0, 0x34, 0x2B, 0xB1, 0x00, 0x23, 0x23, 0x70, 0x69, 0x78, 0x31, 0xB1, 0x06, 0xF0, 0xA2, 0xFB, 0x20, 0x46, 0x08, 0xF0, -+0x13, 0xFD, 0x00, 0x20, 0x38, 0xBD, 0x06, 0xF0, 0xBD, 0xFB, 0x20, 0x46, 0x08, 0xF0, 0x0C, 0xFD, 0x00, 0x20, 0x38, 0xBD, -+0x18, 0x88, 0x17, 0x00, 0x70, 0xB5, 0x10, 0x46, 0x14, 0x46, 0x0D, 0x46, 0x1E, 0x46, 0x08, 0xF0, 0x73, 0xFF, 0x03, 0x28, -+0x25, 0xD0, 0x20, 0x46, 0x08, 0xF0, 0x6E, 0xFF, 0x04, 0x28, 0x20, 0xD0, 0x2A, 0x78, 0x1B, 0x4D, 0x20, 0x46, 0xEA, 0x77, -+0x72, 0xB9, 0x08, 0xF0, 0x65, 0xFF, 0x02, 0x28, 0x17, 0xD0, 0x18, 0x4B, 0xD3, 0xF8, 0x60, 0x31, 0x98, 0x47, 0x23, 0x20, -+0x22, 0x46, 0x31, 0x46, 0x08, 0xF0, 0x20, 0xFD, 0x00, 0x20, 0x70, 0xBD, 0x08, 0xF0, 0x56, 0xFF, 0x58, 0xB1, 0x02, 0x28, -+0xF9, 0xD0, 0x10, 0x4B, 0xD3, 0xF8, 0xE0, 0x30, 0x98, 0x47, 0x20, 0x46, 0x02, 0x21, 0x08, 0xF0, 0xA3, 0xFE, 0x02, 0x20, -+0x70, 0xBD, 0x0C, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x02, 0xDB, 0x00, 0x23, 0x6B, 0x82, 0xE0, 0xE7, -+0x08, 0x4B, 0x1B, 0x68, 0x1B, 0x07, 0xF8, 0xD0, 0x07, 0x49, 0x08, 0x48, 0x40, 0xF2, 0x31, 0x62, 0x0A, 0xF0, 0x76, 0xFD, -+0xF1, 0xE7, 0x00, 0xBF, 0x98, 0x9C, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x38, 0x00, 0x32, 0x40, -+0x70, 0x79, 0x15, 0x00, 0x84, 0x9E, 0x15, 0x00, 0x70, 0xB5, 0x1E, 0x4D, 0x2B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0x0E, 0x46, 0x14, 0x46, 0x1C, 0xDB, 0x20, 0x46, 0x08, 0xF0, 0x1C, 0xFF, 0x58, 0xB1, 0x02, 0x28, 0x08, 0xD0, 0x18, 0x4B, -+0xD3, 0xF8, 0xE0, 0x30, 0x98, 0x47, 0x20, 0x46, 0x02, 0x21, 0x08, 0xF0, 0x69, 0xFE, 0x02, 0x20, 0x70, 0xBD, 0x2B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x13, 0xDB, 0x20, 0x46, 0x03, 0x21, 0x08, 0xF0, 0x5E, 0xFE, 0x33, 0x68, 0x98, 0x47, -+0x00, 0x20, 0x70, 0xBD, 0x10, 0x46, 0x08, 0xF0, 0xFF, 0xFE, 0x04, 0x28, 0xDD, 0xD1, 0x0B, 0x49, 0x0B, 0x48, 0x40, 0xF2, -+0x71, 0x62, 0x0A, 0xF0, 0x37, 0xFD, 0xD6, 0xE7, 0x09, 0x4B, 0x1B, 0x68, 0x1B, 0x07, 0xE7, 0xD0, 0x05, 0x49, 0x08, 0x48, -+0x4F, 0xF4, 0xCF, 0x62, 0x0A, 0xF0, 0x2C, 0xFD, 0xE0, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xAC, 0x9E, 0x15, 0x00, 0x38, 0x00, 0x32, 0x40, 0x84, 0x9E, 0x15, 0x00, 0x70, 0xB5, 0x12, 0x4C, -+0x88, 0x78, 0x4F, 0xF4, 0xA4, 0x65, 0x05, 0xFB, 0x00, 0x40, 0x82, 0xB0, 0x90, 0xF8, 0x62, 0x40, 0x1E, 0x46, 0x84, 0xB9, -+0x90, 0xF8, 0x6C, 0x00, 0x0C, 0x4D, 0x0C, 0x88, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x00, 0x51, 0xA4, 0x02, 0x8C, 0x60, -+0x31, 0x46, 0x15, 0x20, 0x08, 0xF0, 0x8A, 0xFC, 0x00, 0x20, 0x02, 0xB0, 0x70, 0xBD, 0x06, 0x4C, 0x09, 0x88, 0xD4, 0xF8, -+0x60, 0x44, 0x01, 0x92, 0xA0, 0x47, 0x01, 0x9A, 0xF0, 0xE7, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x88, 0x79, 0x19, 0x4D, 0x4F, 0xF4, 0xA4, 0x66, 0x06, 0xFB, 0x00, 0xF6, -+0x06, 0xF1, 0x38, 0x00, 0x28, 0x44, 0x35, 0x44, 0x82, 0xB0, 0x90, 0x46, 0x06, 0x22, 0x1F, 0x46, 0x0C, 0x46, 0x1C, 0xF0, -+0x85, 0xFF, 0x95, 0xF8, 0xC0, 0x34, 0x73, 0xB9, 0x10, 0x49, 0x11, 0x4B, 0x20, 0x68, 0xA2, 0x88, 0x08, 0x60, 0x1A, 0x60, -+0x42, 0x46, 0x39, 0x46, 0x19, 0x20, 0x08, 0xF0, 0x57, 0xFC, 0x00, 0x20, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x0D, 0xF1, -+0x07, 0x00, 0xFC, 0xF7, 0x9F, 0xFF, 0x00, 0x28, 0xF0, 0xD1, 0x08, 0x49, 0x08, 0x48, 0xD1, 0xE9, 0x00, 0x23, 0x43, 0xF0, -+0x10, 0x03, 0x1A, 0x43, 0x4B, 0x60, 0x02, 0x60, 0xE6, 0xE7, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, 0x20, 0x00, 0x32, 0x40, -+0x24, 0x00, 0x32, 0x40, 0x98, 0x9C, 0x17, 0x00, 0x60, 0x00, 0x32, 0x40, 0x2D, 0xE9, 0xF0, 0x4F, 0x0D, 0x46, 0x9E, 0x4F, -+0x95, 0xF8, 0x03, 0xA0, 0x4F, 0xF4, 0xA4, 0x61, 0x89, 0xB0, 0x01, 0xFB, 0x0A, 0xFB, 0x07, 0xEB, 0x0B, 0x06, 0x00, 0x24, -+0x0D, 0xF1, 0x1F, 0x00, 0x90, 0x46, 0x99, 0x46, 0x8D, 0xF8, 0x1F, 0x40, 0xFC, 0xF7, 0x72, 0xFF, 0x96, 0xF8, 0x62, 0x30, -+0xAA, 0x78, 0x86, 0xF8, 0x64, 0x20, 0x04, 0x46, 0x00, 0x2B, 0x40, 0xF0, 0xED, 0x80, 0x96, 0xF8, 0x6C, 0x10, 0x02, 0x91, -+0x00, 0x2A, 0x00, 0xF0, 0x45, 0x81, 0x8E, 0x4A, 0x8E, 0x4B, 0x03, 0x92, 0x8C, 0x46, 0x8E, 0x49, 0x18, 0x69, 0xD2, 0xF8, -+0xE0, 0x31, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x0C, 0x12, 0x0B, 0xF1, 0x18, 0x01, 0x79, 0x18, 0x04, 0x91, 0x91, 0x68, -+0x05, 0x92, 0x41, 0x18, 0x04, 0x98, 0x98, 0x47, 0x05, 0x9A, 0x2B, 0x88, 0x13, 0x84, 0xFC, 0xF7, 0x39, 0xFF, 0x05, 0x9A, -+0x96, 0xF8, 0xC0, 0x14, 0x01, 0x94, 0x13, 0x8C, 0x92, 0xF8, 0x23, 0x20, 0x00, 0x91, 0x4F, 0xF4, 0x80, 0x70, 0x7F, 0x49, -+0x0A, 0xF0, 0x3C, 0xFA, 0x96, 0xF8, 0xC0, 0x34, 0x33, 0xB9, 0x7D, 0x4A, 0x29, 0x88, 0x13, 0x68, 0x9B, 0xB2, 0x43, 0xEA, -+0x01, 0x43, 0x13, 0x60, 0x7A, 0x4B, 0x1B, 0x68, 0x18, 0x04, 0x00, 0xF1, 0xD2, 0x81, 0x79, 0x49, 0x79, 0x4B, 0xB1, 0xF8, -+0x1C, 0xC0, 0x02, 0x99, 0x08, 0x46, 0x72, 0x49, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x00, 0x12, 0x4F, 0xF4, 0xA4, 0x6B, -+0x90, 0x68, 0x02, 0x92, 0x0B, 0xFB, 0x0A, 0x7B, 0x0C, 0xF1, 0x14, 0x0C, 0x00, 0xFB, 0x0C, 0xFC, 0xA3, 0xFB, 0x0C, 0x3C, -+0xDB, 0xF8, 0x04, 0x00, 0x4F, 0xEA, 0x9C, 0x4C, 0x00, 0x23, 0xA2, 0xF8, 0x1E, 0xC0, 0x40, 0xF0, 0x01, 0x00, 0xDF, 0xF8, -+0x90, 0xC1, 0xAB, 0xF8, 0x68, 0x30, 0x8B, 0xF8, 0x6A, 0x30, 0x8B, 0xF8, 0x8C, 0x30, 0x8B, 0xF8, 0x78, 0x30, 0xCB, 0xF8, -+0x74, 0x30, 0xCB, 0xF8, 0x04, 0x00, 0xDC, 0xF8, 0x10, 0x00, 0xCB, 0xF8, 0x70, 0x00, 0x30, 0x46, 0x04, 0xF0, 0xF4, 0xFA, -+0x9B, 0xF8, 0xC0, 0x04, 0x5D, 0x49, 0x00, 0x23, 0x00, 0x28, 0x40, 0xF0, 0x76, 0x81, 0x5D, 0x4B, 0x02, 0x9A, 0x9B, 0x7C, -+0x00, 0x2B, 0x40, 0xF0, 0x8B, 0x81, 0x00, 0x2C, 0x40, 0xF0, 0xD5, 0x81, 0xDF, 0xF8, 0x7C, 0xB1, 0xDB, 0xF8, 0x20, 0x30, -+0x00, 0x2B, 0x40, 0xF0, 0x81, 0x81, 0x9D, 0xF8, 0x1F, 0x30, 0x00, 0x2B, 0x40, 0xF0, 0x87, 0x82, 0x53, 0x49, 0x93, 0x68, -+0x0A, 0x68, 0xCB, 0xF8, 0x20, 0x60, 0x12, 0x0C, 0x12, 0x04, 0xC3, 0xF3, 0x8F, 0x23, 0x13, 0x43, 0x0B, 0x60, 0xDD, 0xE9, -+0x03, 0x30, 0xD3, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0x03, 0x9B, 0x8B, 0xF8, 0x24, 0x40, 0xD3, 0xF8, 0x60, 0x32, 0x98, 0x47, -+0xAA, 0x78, 0x11, 0x46, 0x30, 0x46, 0x05, 0xF0, 0x5B, 0xFF, 0xAB, 0x78, 0x00, 0x2B, 0x38, 0xD0, 0x45, 0x4B, 0x1B, 0x68, -+0x1A, 0x68, 0x00, 0x2A, 0x00, 0xF0, 0xE0, 0x80, 0x43, 0x49, 0x0A, 0x60, 0x5A, 0x68, 0x00, 0x2A, 0x00, 0xF0, 0xE5, 0x80, -+0xC2, 0xF3, 0x0B, 0x01, 0x00, 0x29, 0x40, 0xF0, 0x4F, 0x81, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x0A, 0x71, 0x22, 0xF4, -+0x7F, 0x62, 0xC9, 0x68, 0x3B, 0x48, 0x22, 0xF0, 0x0F, 0x02, 0xC1, 0xF3, 0x0B, 0x01, 0x0A, 0x43, 0x02, 0x60, 0x9A, 0x68, -+0x00, 0x2A, 0x40, 0xF0, 0xD9, 0x80, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x0A, 0x72, 0x35, 0x49, 0x12, 0x69, 0x0A, 0x60, -+0xDB, 0x68, 0x00, 0x2B, 0x40, 0xF0, 0xD4, 0x80, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x0A, 0x77, 0x30, 0x4B, 0x7A, 0x69, -+0x1A, 0x60, 0x21, 0x4B, 0xD3, 0xF8, 0xA0, 0x31, 0x98, 0x47, 0x42, 0x46, 0x49, 0x46, 0x1F, 0x20, 0x08, 0xF0, 0x30, 0xFB, -+0x00, 0x20, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x80, 0xB1, 0x22, 0x4B, 0x9C, 0x68, 0x6C, 0xB1, 0x94, 0xF8, 0x62, 0x30, -+0x3B, 0xB9, 0x94, 0xF8, 0x64, 0x30, 0x23, 0xB1, 0xA6, 0x42, 0x02, 0xD0, 0x94, 0xF8, 0xC0, 0x34, 0x13, 0xB1, 0x24, 0x68, -+0x00, 0x2C, 0xF1, 0xD1, 0x00, 0x2A, 0x00, 0xF0, 0xB2, 0x80, 0x1F, 0x4B, 0x19, 0x6A, 0xA1, 0x42, 0x9D, 0xD1, 0x0E, 0x49, -+0x1D, 0x4C, 0xD1, 0xF8, 0x64, 0x12, 0x00, 0x22, 0x1A, 0x62, 0x83, 0xF8, 0x24, 0x20, 0x88, 0x47, 0x0F, 0x4A, 0x1A, 0x48, -+0xD2, 0xE9, 0x00, 0x13, 0x43, 0xF0, 0x10, 0x03, 0x19, 0x43, 0x01, 0x60, 0x17, 0x48, 0x18, 0x49, 0x20, 0x60, 0x53, 0x60, -+0x0B, 0x68, 0x03, 0x43, 0x0B, 0x60, 0xAA, 0x78, 0x83, 0xE7, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x00, 0x10, 0x50, 0x40, 0x68, 0x65, 0x17, 0x00, 0xD0, 0x9E, 0x15, 0x00, 0x68, 0x00, 0x32, 0x40, 0x04, 0x00, 0x32, 0x40, -+0x98, 0x9C, 0x17, 0x00, 0x83, 0xDE, 0x1B, 0x43, 0x00, 0x88, 0x17, 0x00, 0x64, 0x00, 0x32, 0x40, 0xAC, 0x35, 0x17, 0x00, -+0x00, 0x02, 0x32, 0x40, 0x04, 0x02, 0x32, 0x40, 0x08, 0x02, 0x32, 0x40, 0x0C, 0x02, 0x32, 0x40, 0x1C, 0x9E, 0x17, 0x00, -+0x70, 0x80, 0x32, 0x40, 0x60, 0x00, 0x32, 0x40, 0x01, 0x00, 0x04, 0x00, 0x74, 0x80, 0x32, 0x40, 0xAC, 0x4B, 0x03, 0x93, -+0x0B, 0xF1, 0x18, 0x00, 0x38, 0x44, 0xD3, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0x03, 0x9B, 0xD3, 0xF8, 0xDC, 0x33, 0x98, 0x47, -+0xA7, 0x49, 0x96, 0xF8, 0xC0, 0x24, 0x23, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0x0A, 0xF0, 0x0A, 0xF9, 0xA4, 0x4B, 0x1B, 0x68, -+0x19, 0x04, 0x00, 0xF1, 0xD8, 0x80, 0xA3, 0x4B, 0x9B, 0x7F, 0x3B, 0xB9, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x0A, 0x72, -+0x82, 0xF8, 0xC3, 0x34, 0xC2, 0xF8, 0xC4, 0x34, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x0A, 0x73, 0x93, 0xF8, 0xC0, 0x34, -+0x00, 0x2B, 0x00, 0xF0, 0x8C, 0x80, 0x00, 0x2C, 0x00, 0xF0, 0x8E, 0x80, 0x98, 0x4B, 0x9C, 0x68, 0x00, 0x2C, 0x00, 0xF0, -+0x89, 0x80, 0x94, 0xF8, 0x62, 0x30, 0x4B, 0xB9, 0x94, 0xF8, 0x64, 0x30, 0x33, 0xB1, 0xA6, 0x42, 0x04, 0xD0, 0x94, 0xF8, -+0xC0, 0x34, 0x00, 0x2B, 0x00, 0xF0, 0x4A, 0x81, 0x24, 0x68, 0x00, 0x2C, 0xEF, 0xD1, 0x77, 0xE0, 0x4F, 0xF4, 0xA4, 0x62, -+0x02, 0xFB, 0x0A, 0x72, 0x8C, 0x49, 0x92, 0x68, 0x0A, 0x60, 0x5A, 0x68, 0x00, 0x2A, 0x7F, 0xF4, 0x1B, 0xAF, 0x4F, 0xF4, -+0xA4, 0x62, 0x02, 0xFB, 0x0A, 0x72, 0x88, 0x49, 0xD2, 0x68, 0x0A, 0x60, 0x9A, 0x68, 0x00, 0x2A, 0x3F, 0xF4, 0x27, 0xAF, -+0x85, 0x49, 0x0A, 0x60, 0xDB, 0x68, 0x00, 0x2B, 0x3F, 0xF4, 0x2C, 0xAF, 0x83, 0x4A, 0x13, 0x60, 0x7A, 0x4B, 0xD3, 0xF8, -+0xA0, 0x31, 0x98, 0x47, 0x2F, 0xE7, 0x81, 0x48, 0x81, 0x49, 0x03, 0x68, 0x1B, 0x0C, 0x1B, 0x04, 0x03, 0x60, 0x0B, 0x6A, -+0x00, 0x2B, 0x7F, 0xF4, 0xE6, 0xAE, 0x00, 0x2C, 0x3F, 0xF4, 0xE3, 0xAE, 0xDF, 0xF8, 0xC4, 0xB1, 0x0C, 0x62, 0x81, 0xF8, -+0x24, 0x20, 0x04, 0xF1, 0x18, 0x00, 0xDB, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0xDB, 0xF8, 0x60, 0x32, 0x98, 0x47, 0x76, 0x49, -+0xDF, 0xF8, 0xE4, 0xC1, 0x75, 0x48, 0xD4, 0xF8, 0x38, 0xE0, 0xA4, 0x8F, 0xD1, 0xE9, 0x00, 0x32, 0x22, 0xF0, 0x10, 0x02, -+0x13, 0x43, 0xCC, 0xF8, 0x00, 0x30, 0xC0, 0xF8, 0x00, 0xE0, 0x70, 0x4B, 0x4C, 0xF8, 0x3C, 0x4C, 0x00, 0xF5, 0x00, 0x40, -+0x54, 0x30, 0x6E, 0x4C, 0x1C, 0x60, 0x03, 0x68, 0x4A, 0x60, 0x23, 0xF4, 0x80, 0x23, 0x23, 0xF0, 0x01, 0x03, 0x03, 0x60, -+0x1A, 0xE0, 0xCC, 0xB1, 0x64, 0x4A, 0x10, 0x6A, 0xB0, 0xB1, 0x13, 0x62, 0x82, 0xF8, 0x24, 0x30, 0x03, 0x9B, 0xD3, 0xF8, -+0x64, 0x32, 0x98, 0x47, 0x60, 0x49, 0x64, 0x48, 0xD1, 0xE9, 0x00, 0x23, 0x43, 0xF0, 0x10, 0x03, 0x1A, 0x43, 0x4B, 0x60, -+0x02, 0x60, 0xAA, 0x78, 0x9F, 0xE6, 0x02, 0x2C, 0x65, 0xD0, 0x01, 0x2C, 0x00, 0xF0, 0xC0, 0x80, 0xAA, 0x78, 0x98, 0xE6, -+0x52, 0x49, 0x0A, 0x60, 0x94, 0xE7, 0xE6, 0xF7, 0x1F, 0xFE, 0x00, 0x28, 0x3F, 0xF4, 0x29, 0xAE, 0x02, 0x9A, 0x11, 0x46, -+0x57, 0x4A, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x01, 0x23, 0x5B, 0x68, 0x9A, 0x06, 0x7F, 0xF5, 0x1E, 0xAE, 0x28, 0x88, -+0xE6, 0xF7, 0x54, 0xFE, 0xF9, 0xF7, 0x9C, 0xF9, 0x51, 0x49, 0x4F, 0xF4, 0x80, 0x70, 0x0A, 0xF0, 0x41, 0xF8, 0x03, 0x9B, -+0xD3, 0xF8, 0xE0, 0x33, 0x98, 0x47, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x0A, 0x73, 0x93, 0xF8, 0x62, 0x20, 0x04, 0x2A, -+0x3F, 0xF4, 0x07, 0xAE, 0x93, 0xF8, 0x63, 0x00, 0x03, 0x9B, 0xD3, 0xF8, 0x30, 0x33, 0x98, 0x47, 0xFF, 0xE5, 0xE6, 0xF7, -+0xF1, 0xFD, 0x00, 0x28, 0x3F, 0xF4, 0x23, 0xAF, 0x41, 0x4B, 0x02, 0x99, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x01, 0x3B, -+0xDB, 0xF8, 0x04, 0x30, 0x9B, 0x06, 0x7F, 0xF5, 0x18, 0xAF, 0x96, 0xF8, 0x62, 0x30, 0x04, 0x2B, 0x3F, 0xF4, 0x13, 0xAF, -+0x96, 0xF8, 0x63, 0x00, 0x06, 0xF0, 0x2A, 0xFB, 0x0D, 0xE7, 0x01, 0x2C, 0xB0, 0xD1, 0x30, 0x4C, 0x22, 0x6A, 0xB2, 0x42, -+0xAC, 0xD0, 0x23, 0x62, 0x02, 0x93, 0xDD, 0xE9, 0x03, 0x30, 0xD3, 0xF8, 0xD8, 0x21, 0x90, 0x47, 0x02, 0x9B, 0x84, 0xF8, -+0x24, 0x30, 0x03, 0x9B, 0xD3, 0xF8, 0x64, 0x32, 0x98, 0x47, 0xAA, 0x78, 0x37, 0xE6, 0x26, 0x4C, 0x23, 0x6A, 0x00, 0x2B, -+0x98, 0xD1, 0x1E, 0x4B, 0x98, 0x68, 0x20, 0xB9, 0xA3, 0xE0, 0x00, 0x68, 0x00, 0x28, 0x00, 0xF0, 0xA0, 0x80, 0x90, 0xF8, -+0x62, 0x30, 0x00, 0x2B, 0xF7, 0xD1, 0x90, 0xF8, 0x64, 0x30, 0x00, 0x2B, 0xF3, 0xD0, 0x86, 0x42, 0xF1, 0xD0, 0x90, 0xF8, -+0xC0, 0x34, 0x00, 0x2B, 0xED, 0xD1, 0x1F, 0x49, 0x17, 0x4A, 0x20, 0x62, 0x9B, 0x46, 0x90, 0xF8, 0x6C, 0x30, 0x4F, 0xF4, -+0x1E, 0x7C, 0x0C, 0xFB, 0x03, 0x13, 0x11, 0x68, 0x9B, 0x68, 0x09, 0x0C, 0x09, 0x04, 0xC3, 0xF3, 0x8F, 0x23, 0x0B, 0x43, -+0x13, 0x60, 0x03, 0x9B, 0x18, 0x30, 0xD3, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0x03, 0x9B, 0x84, 0xF8, 0x24, 0xB0, 0xD3, 0xF8, -+0x60, 0x32, 0x98, 0x47, 0xAA, 0x78, 0xFE, 0xE5, 0x88, 0x1A, 0x17, 0x00, 0x00, 0x9F, 0x15, 0x00, 0x04, 0x00, 0x32, 0x40, -+0x64, 0xBA, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x00, 0x02, 0x32, 0x40, 0x04, 0x02, 0x32, 0x40, 0x08, 0x02, 0x32, 0x40, -+0x0C, 0x02, 0x32, 0x40, 0x64, 0x00, 0x32, 0x40, 0x1C, 0x9E, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, 0x20, 0x00, 0x32, 0x40, -+0x70, 0x80, 0x32, 0x40, 0x01, 0x00, 0x04, 0x00, 0x60, 0x00, 0x32, 0x40, 0x68, 0x65, 0x17, 0x00, 0xF0, 0x9E, 0x15, 0x00, -+0x29, 0x4A, 0x11, 0x6A, 0xB1, 0x42, 0x7F, 0xF4, 0x3B, 0xAF, 0x13, 0x62, 0x82, 0xF8, 0x24, 0x30, 0x03, 0x9B, 0xD3, 0xF8, -+0x64, 0x32, 0x98, 0x47, 0xAA, 0x78, 0xCC, 0xE5, 0xDF, 0xF8, 0x88, 0xB0, 0xDB, 0xF8, 0x20, 0x20, 0x00, 0x2A, 0x7F, 0xF4, -+0x2B, 0xAF, 0x94, 0xF8, 0x6C, 0x30, 0x1F, 0x48, 0x1F, 0x49, 0xCB, 0xF8, 0x20, 0x40, 0x4F, 0xF4, 0x1E, 0x7C, 0x0C, 0xFB, -+0x03, 0x03, 0x08, 0x68, 0x9B, 0x68, 0x02, 0x92, 0x00, 0x0C, 0x00, 0x04, 0xC3, 0xF3, 0x8F, 0x23, 0x03, 0x43, 0x0B, 0x60, -+0x03, 0x9B, 0x04, 0xF1, 0x18, 0x00, 0xD3, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0x03, 0x9B, 0x02, 0x9A, 0x8B, 0xF8, 0x24, 0x20, -+0xD3, 0xF8, 0x60, 0x32, 0xDF, 0xF8, 0x50, 0xB0, 0x98, 0x47, 0x11, 0x49, 0xDF, 0xF8, 0x4C, 0xC0, 0x10, 0x48, 0xD4, 0xF8, -+0x38, 0xE0, 0xA4, 0x8F, 0xD1, 0xE9, 0x00, 0x23, 0x23, 0xF0, 0x10, 0x03, 0x1A, 0x43, 0x4B, 0x60, 0xCB, 0xF8, 0x00, 0x20, -+0xCC, 0xF8, 0x00, 0xE0, 0x04, 0x60, 0xAA, 0x78, 0x8F, 0xE5, 0x01, 0x2B, 0x7F, 0xF4, 0xF2, 0xAE, 0xE1, 0xE6, 0x00, 0x23, -+0x93, 0xF8, 0x6C, 0x30, 0xFF, 0xDE, 0x00, 0xBF, 0x1C, 0x9E, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x64, 0x00, 0x32, 0x40, -+0x98, 0x9C, 0x17, 0x00, 0x24, 0x00, 0x32, 0x40, 0x60, 0x00, 0x32, 0x40, 0x20, 0x00, 0x32, 0x40, 0x38, 0xB5, 0x07, 0x20, -+0x0C, 0x46, 0x19, 0x46, 0x02, 0x23, 0x08, 0xF0, 0x7F, 0xF8, 0x23, 0x46, 0x07, 0x4D, 0x13, 0xF8, 0x02, 0x1B, 0x22, 0x7A, -+0xD5, 0xF8, 0x58, 0x54, 0x04, 0x46, 0x18, 0x46, 0x63, 0x1C, 0xA8, 0x47, 0x20, 0x70, 0x20, 0x46, 0x08, 0xF0, 0xA0, 0xF8, -+0x00, 0x20, 0x38, 0xBD, 0x88, 0x1A, 0x17, 0x00, 0x00, 0xB5, 0x08, 0x78, 0x03, 0x28, 0x83, 0xB0, 0x19, 0x46, 0x07, 0xD8, -+0xCD, 0xE9, 0x00, 0x23, 0x0C, 0x4B, 0xD3, 0xF8, 0x64, 0x34, 0x98, 0x47, 0xDD, 0xE9, 0x00, 0x21, 0x0A, 0x4B, 0x9B, 0x68, -+0x33, 0xB1, 0x09, 0x20, 0x08, 0xF0, 0xC0, 0xF8, 0x00, 0x20, 0x03, 0xB0, 0x5D, 0xF8, 0x04, 0xFB, 0x04, 0x4B, 0xD3, 0xF8, -+0xE8, 0x30, 0xCD, 0xE9, 0x00, 0x21, 0x98, 0x47, 0xDD, 0xE9, 0x00, 0x21, 0xEF, 0xE7, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, -+0x00, 0x88, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x0D, 0x78, 0x0C, 0x46, 0x16, 0x46, 0x98, 0x46, 0x00, 0x2D, 0x3B, 0xD1, -+0x91, 0xF8, 0x02, 0xC0, 0x26, 0x49, 0x27, 0x4A, 0x11, 0xF8, 0x0C, 0x00, 0xE1, 0x78, 0x52, 0xF8, 0x20, 0x20, 0x60, 0x78, -+0x24, 0x4F, 0x25, 0x4B, 0x91, 0x42, 0xB8, 0xBF, 0x4A, 0x08, 0x00, 0xEB, 0x80, 0x01, 0xC0, 0xEB, 0x01, 0x11, 0x61, 0x44, -+0x07, 0xEB, 0xC1, 0x01, 0x4F, 0xF0, 0x9E, 0x0E, 0x91, 0xF8, 0xA5, 0x11, 0x0E, 0xFB, 0x00, 0xC0, 0xA8, 0xBF, 0x02, 0xEB, -+0xD2, 0x72, 0x07, 0xEB, 0x80, 0x00, 0xA8, 0xBF, 0xC2, 0xF3, 0x47, 0x02, 0x01, 0xEB, 0x41, 0x01, 0x80, 0xF8, 0x5A, 0x21, -+0x03, 0xEB, 0xC1, 0x01, 0xA2, 0x88, 0x0A, 0x81, 0x32, 0x46, 0x41, 0x46, 0x03, 0x23, 0x29, 0x20, 0x08, 0xF0, 0x0C, 0xF8, -+0x62, 0x78, 0x02, 0x70, 0xA2, 0x78, 0x42, 0x70, 0x85, 0x70, 0x08, 0xF0, 0x35, 0xF8, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, -+0x48, 0x78, 0x0B, 0x49, 0xA2, 0x88, 0x4F, 0xF4, 0x1E, 0x75, 0x05, 0xFB, 0x00, 0x10, 0xA1, 0x78, 0x14, 0xF0, 0xA0, 0xFB, -+0x08, 0xB9, 0x04, 0x25, 0xE2, 0xE7, 0x07, 0x49, 0x0A, 0x68, 0x42, 0xF0, 0x80, 0x02, 0x0A, 0x60, 0x00, 0x25, 0xDB, 0xE7, -+0xC0, 0xB2, 0x15, 0x00, 0x7C, 0x28, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0xF4, 0xE4, 0x17, 0x00, 0x54, 0x00, 0x32, 0x40, -+0x2D, 0xE9, 0xF0, 0x43, 0x04, 0x46, 0x87, 0xB0, 0x10, 0x46, 0x15, 0x46, 0x0E, 0x46, 0x1F, 0x46, 0x08, 0xF0, 0x7C, 0xFA, -+0x40, 0xB1, 0x02, 0x38, 0x80, 0xB2, 0x02, 0x28, 0x4D, 0xD8, 0x02, 0x24, 0x20, 0x46, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, -+0xDF, 0xF8, 0x88, 0x83, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x65, 0xDB, 0x3B, 0x2C, 0x00, 0xF2, -+0xA7, 0x80, 0x05, 0x2C, 0x40, 0xF2, 0xE3, 0x80, 0x06, 0x3C, 0x35, 0x2C, 0x4A, 0xD8, 0xDF, 0xE8, 0x14, 0xF0, 0xBF, 0x01, -+0x49, 0x00, 0xB5, 0x01, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x88, 0x01, 0x49, 0x00, 0x6E, 0x01, -+0x49, 0x00, 0x5A, 0x01, 0x49, 0x00, 0x50, 0x01, 0x49, 0x00, 0x3A, 0x01, 0x49, 0x00, 0x30, 0x01, 0x49, 0x00, 0x49, 0x00, -+0x49, 0x00, 0x1D, 0x01, 0x49, 0x00, 0x13, 0x01, 0x49, 0x00, 0x00, 0x01, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, -+0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0xF6, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, -+0x49, 0x00, 0xEF, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, -+0x49, 0x00, 0x49, 0x00, 0xE2, 0x00, 0xB1, 0x4B, 0xB1, 0x4C, 0x1B, 0x68, 0x28, 0x46, 0x03, 0xF0, 0x0F, 0x03, 0xE3, 0x74, -+0x08, 0xF0, 0x20, 0xFA, 0xAE, 0x4B, 0xA0, 0x74, 0xD3, 0xF8, 0xE0, 0x30, 0x98, 0x47, 0x28, 0x46, 0x02, 0x21, 0x08, 0xF0, -+0x6F, 0xF9, 0x9E, 0xE7, 0xDF, 0xF8, 0xA0, 0x82, 0x02, 0x24, 0x98, 0xF8, 0x13, 0x30, 0xA5, 0x4A, 0x1B, 0x01, 0xDB, 0xB2, -+0x13, 0x60, 0x28, 0x46, 0x98, 0xF8, 0x12, 0x10, 0x08, 0xF0, 0x60, 0xF9, 0x20, 0x46, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, -+0x9E, 0x4B, 0x1B, 0x68, 0x1B, 0x07, 0x40, 0xF0, 0x6F, 0x81, 0x3B, 0x2C, 0x67, 0xD8, 0x05, 0x2C, 0x67, 0xD9, 0x06, 0x3C, -+0x35, 0x2C, 0x64, 0xD8, 0xDF, 0xE8, 0x14, 0xF0, 0x56, 0x01, 0x63, 0x00, 0x4C, 0x01, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, -+0x63, 0x00, 0x63, 0x00, 0x1F, 0x01, 0x63, 0x00, 0x05, 0x01, 0x63, 0x00, 0xF1, 0x00, 0x63, 0x00, 0xE7, 0x00, 0x63, 0x00, -+0xD1, 0x00, 0x63, 0x00, 0xC7, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0xB4, 0x00, 0x63, 0x00, 0xAA, 0x00, 0x63, 0x00, -+0x97, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x8D, 0x00, 0x63, 0x00, -+0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x86, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, -+0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, 0x79, 0x00, 0x87, 0x2C, 0x3C, 0xD1, -+0xDF, 0xF8, 0xF0, 0x81, 0xDF, 0xF8, 0xF0, 0x91, 0x00, 0x27, 0x88, 0xF8, 0x30, 0x70, 0x30, 0x68, 0xD9, 0xF8, 0xF8, 0x30, -+0x98, 0x47, 0x04, 0x46, 0x00, 0x28, 0x40, 0xF0, 0x19, 0x81, 0x98, 0xF8, 0x31, 0x30, 0x00, 0x2B, 0x97, 0xD0, 0x05, 0xA8, -+0x88, 0xF8, 0x31, 0x40, 0x01, 0xF0, 0x74, 0xFD, 0x00, 0x28, 0x90, 0xD0, 0x05, 0x9A, 0x71, 0x49, 0x92, 0xF8, 0x63, 0x30, -+0x92, 0xF8, 0xC1, 0x04, 0x03, 0xEB, 0xC3, 0x02, 0x03, 0xEB, 0x42, 0x03, 0x01, 0xEB, 0x43, 0x01, 0x05, 0xF0, 0x9C, 0xFF, -+0x81, 0xE7, 0x87, 0x2C, 0xD4, 0xD0, 0x6A, 0x49, 0x6A, 0x48, 0xDF, 0xF8, 0x98, 0x81, 0x40, 0xF6, 0x06, 0x22, 0x09, 0xF0, -+0xCB, 0xFF, 0x02, 0x24, 0x75, 0xE7, 0x87, 0x2C, 0xC8, 0xD0, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0xED, 0xDB, 0xDF, 0xF8, 0x78, 0x81, 0x02, 0x24, 0x69, 0xE7, 0x5D, 0x4B, 0xDF, 0xF8, 0x6C, 0x81, 0x9B, 0x6D, 0x30, 0x46, -+0x98, 0x47, 0x2A, 0x46, 0x39, 0x46, 0x3C, 0x20, 0x07, 0xF0, 0x38, 0xFF, 0x00, 0x24, 0x5C, 0xE7, 0x30, 0x46, 0x09, 0xF0, -+0xD3, 0xFF, 0xDF, 0xF8, 0x50, 0x81, 0x00, 0x24, 0x55, 0xE7, 0x3B, 0x46, 0x31, 0x46, 0x2A, 0x46, 0x28, 0x20, 0xFF, 0xF7, -+0x7B, 0xFE, 0xDF, 0xF8, 0x3C, 0x81, 0x04, 0x46, 0x4B, 0xE7, 0x52, 0x4B, 0x32, 0x78, 0x1B, 0x68, 0x51, 0x48, 0xDF, 0xF8, -+0x2C, 0x81, 0xDB, 0xB2, 0x03, 0xFB, 0x02, 0xF3, 0x42, 0xEA, 0x03, 0x23, 0x03, 0x60, 0x39, 0x46, 0x2A, 0x46, 0x21, 0x20, -+0x07, 0xF0, 0x14, 0xFF, 0x00, 0x24, 0x38, 0xE7, 0x3B, 0x46, 0x31, 0x46, 0x2A, 0x46, 0x1E, 0x20, 0xFF, 0xF7, 0xD4, 0xFA, -+0xDF, 0xF8, 0x00, 0x81, 0x04, 0x46, 0x2E, 0xE7, 0x45, 0x48, 0x33, 0x78, 0x02, 0x68, 0xDF, 0xF8, 0xF4, 0x80, 0x9B, 0x03, -+0x22, 0xF4, 0xE0, 0x32, 0x03, 0xF4, 0xE0, 0x33, 0x13, 0x43, 0x03, 0x60, 0x39, 0x46, 0x2A, 0x46, 0x1D, 0x20, 0x07, 0xF0, -+0xF7, 0xFE, 0x00, 0x24, 0x1B, 0xE7, 0x3B, 0x46, 0x31, 0x46, 0x2A, 0x46, 0x18, 0x20, 0xFF, 0xF7, 0x77, 0xFA, 0xDF, 0xF8, -+0xC8, 0x80, 0x04, 0x46, 0x11, 0xE7, 0x73, 0x79, 0xDF, 0xF8, 0xBC, 0x80, 0x36, 0x4A, 0x31, 0x68, 0x92, 0x6A, 0x08, 0xEB, -+0x83, 0x00, 0x41, 0x61, 0x22, 0xB1, 0x12, 0x79, 0x9A, 0x42, 0x04, 0xBF, 0x32, 0x4B, 0x19, 0x60, 0x39, 0x46, 0x2A, 0x46, -+0x17, 0x20, 0x07, 0xF0, 0xD7, 0xFE, 0x00, 0x24, 0xFB, 0xE6, 0x3B, 0x46, 0x31, 0x46, 0x2A, 0x46, 0x14, 0x20, 0xFF, 0xF7, -+0x2B, 0xFA, 0xDF, 0xF8, 0x88, 0x80, 0x04, 0x46, 0xF1, 0xE6, 0x2A, 0x4A, 0x31, 0x78, 0x13, 0x68, 0xDF, 0xF8, 0x78, 0x80, -+0x23, 0xF0, 0xFF, 0x03, 0x0B, 0x43, 0x13, 0x60, 0x13, 0x68, 0x43, 0xF0, 0x00, 0x43, 0x13, 0x60, 0x39, 0x46, 0x2A, 0x46, -+0x13, 0x20, 0x07, 0xF0, 0xB9, 0xFE, 0x00, 0x24, 0xDD, 0xE6, 0x39, 0x46, 0x02, 0x23, 0x2A, 0x46, 0x11, 0x20, 0x07, 0xF0, -+0x49, 0xFE, 0x72, 0x7A, 0xF3, 0x88, 0xB1, 0x7A, 0x02, 0x91, 0xCD, 0xE9, 0x00, 0x32, 0x04, 0x46, 0xB3, 0x88, 0x72, 0x88, -+0x71, 0x78, 0x30, 0x78, 0xDF, 0xF8, 0x34, 0x80, 0xE6, 0xF7, 0x1E, 0xFA, 0x20, 0x46, 0x07, 0xF0, 0x67, 0xFE, 0x00, 0x24, -+0xC3, 0xE6, 0xDF, 0xF8, 0x24, 0x80, 0x33, 0x68, 0xD8, 0xF8, 0x04, 0x10, 0x11, 0x4A, 0xC8, 0xF8, 0x00, 0x30, 0x0B, 0x43, -+0x13, 0x60, 0x39, 0x46, 0x2A, 0x46, 0x0F, 0x20, 0x07, 0xF0, 0x8E, 0xFE, 0x00, 0x24, 0xB2, 0xE6, 0x38, 0x00, 0x32, 0x40, -+0x98, 0x9C, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x64, 0x3E, 0x18, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, -+0xE4, 0x00, 0x32, 0x40, 0xE8, 0x00, 0x32, 0x40, 0x4C, 0x00, 0x32, 0x40, 0x30, 0x9D, 0x17, 0x00, 0xDC, 0x00, 0x32, 0x40, -+0x90, 0x00, 0x32, 0x40, 0x60, 0x00, 0x32, 0x40, 0x38, 0x36, 0x17, 0x00, 0x3B, 0x46, 0x31, 0x46, 0x2A, 0x46, 0x08, 0x20, -+0xFF, 0xF7, 0x96, 0xFD, 0xDF, 0xF8, 0x2C, 0x81, 0x04, 0x46, 0x8C, 0xE6, 0x3B, 0x46, 0x31, 0x46, 0x2A, 0x46, 0x06, 0x20, -+0xFF, 0xF7, 0x72, 0xFD, 0xDF, 0xF8, 0x18, 0x81, 0x04, 0x46, 0x82, 0xE6, 0xD9, 0xF8, 0x6C, 0x31, 0x30, 0x68, 0x98, 0x47, -+0x3C, 0x46, 0x7C, 0xE6, 0x3F, 0x49, 0x40, 0x48, 0x40, 0xF6, 0xC9, 0x12, 0x09, 0xF0, 0xCA, 0xFE, 0x3B, 0x2C, 0x3F, 0xF6, -+0xFE, 0xAE, 0x05, 0x2C, 0x7F, 0xF6, 0xFD, 0xAE, 0x06, 0x3C, 0x35, 0x2C, 0x3F, 0xF6, 0xF9, 0xAE, 0x01, 0xA3, 0x53, 0xF8, -+0x24, 0xF0, 0x00, 0xBF, 0xBD, 0xAD, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xA9, 0xAD, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, -+0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0x4F, 0xAD, 0x13, 0x00, -+0xEF, 0xAB, 0x13, 0x00, 0x1B, 0xAD, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xF3, 0xAC, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, -+0xDF, 0xAC, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xB3, 0xAC, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0x9F, 0xAC, 0x13, 0x00, -+0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0x79, 0xAC, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, -+0x65, 0xAC, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0x3F, 0xAC, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, -+0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, -+0x2B, 0xAC, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, -+0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0x1D, 0xAC, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, -+0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, -+0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0xEF, 0xAB, 0x13, 0x00, 0x03, 0xAC, 0x13, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x84, 0x9E, 0x15, 0x00, 0x98, 0x9C, 0x17, 0x00, 0xC0, 0x68, 0xCB, 0x68, 0xC0, 0x1A, 0xC0, 0x0F, -+0x70, 0x47, 0x00, 0xBF, 0x01, 0x48, 0x08, 0xF0, 0xE9, 0xB9, 0x00, 0xBF, 0xD0, 0x9C, 0x17, 0x00, 0x06, 0x4B, 0x38, 0xB1, -+0xC1, 0x68, 0x04, 0x22, 0x4F, 0xF4, 0x80, 0x20, 0x98, 0x60, 0x19, 0x63, 0x9A, 0x60, 0x70, 0x47, 0x4F, 0xF4, 0x80, 0x62, -+0x9A, 0x60, 0x70, 0x47, 0x00, 0x10, 0x50, 0x40, 0x33, 0x4A, 0xF8, 0xB5, 0x13, 0x69, 0xCB, 0x1A, 0x00, 0x2B, 0x0C, 0x46, -+0x05, 0x46, 0x57, 0xDB, 0x30, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x46, 0xDB, 0xEF, 0xF3, 0x10, 0x83, -+0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x2C, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x2B, 0x4F, 0x2C, 0x4E, 0x3B, 0x68, 0x32, 0x68, -+0x01, 0x33, 0x95, 0x42, 0x3B, 0x60, 0x19, 0xD0, 0x29, 0x46, 0x30, 0x46, 0x08, 0xF0, 0x08, 0xFA, 0x30, 0x46, 0x27, 0x4A, -+0xEC, 0x60, 0x29, 0x46, 0x08, 0xF0, 0x40, 0xFA, 0x30, 0x68, 0x85, 0x42, 0x16, 0xD0, 0x3B, 0x68, 0x23, 0xB1, 0x1F, 0x4A, -+0x01, 0x3B, 0x12, 0x68, 0x3B, 0x60, 0xA3, 0xB1, 0x1A, 0x4B, 0x19, 0x69, 0x64, 0x1A, 0x00, 0x2C, 0x17, 0xDB, 0xF8, 0xBD, -+0x30, 0x46, 0x08, 0xF0, 0xE3, 0xF9, 0x30, 0x46, 0x1A, 0x4A, 0xEC, 0x60, 0x29, 0x46, 0x08, 0xF0, 0x27, 0xFA, 0x30, 0x68, -+0x18, 0x4B, 0xD3, 0xF8, 0xDC, 0x31, 0x98, 0x47, 0xE3, 0xE7, 0x00, 0x2A, 0xE8, 0xD0, 0x62, 0xB6, 0x0E, 0x4B, 0x19, 0x69, -+0x64, 0x1A, 0x00, 0x2C, 0xE7, 0xDA, 0xBD, 0xE8, 0xF8, 0x40, 0x4F, 0xF0, 0x80, 0x40, 0x08, 0xF0, 0xE3, 0xB8, 0x09, 0x4B, -+0x1B, 0x69, 0xE3, 0x1A, 0x00, 0x2B, 0xB3, 0xDA, 0x0D, 0x49, 0x0E, 0x48, 0x7D, 0x22, 0x09, 0xF0, 0xCF, 0xFD, 0xAD, 0xE7, -+0x13, 0x69, 0x41, 0x68, 0x0B, 0x48, 0x22, 0x46, 0x09, 0xF0, 0x4E, 0xFB, 0xA0, 0xE7, 0x00, 0xBF, 0x00, 0x10, 0x50, 0x40, -+0x38, 0x36, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xD0, 0x9C, 0x17, 0x00, 0xE9, 0xAE, 0x13, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x74, 0x9F, 0x15, 0x00, 0x4C, 0x9F, 0x15, 0x00, 0x38, 0xB5, 0x01, 0x46, -+0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x10, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0F, 0x4C, 0x10, 0x4D, -+0x23, 0x68, 0x2A, 0x68, 0x01, 0x33, 0x8A, 0x42, 0x23, 0x60, 0x28, 0x46, 0x0B, 0xD0, 0x08, 0xF0, 0x99, 0xF9, 0x23, 0x68, -+0x33, 0xB1, 0x08, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x38, 0xBD, 0x08, 0xF0, -+0x81, 0xF9, 0x06, 0x4B, 0x28, 0x68, 0xD3, 0xF8, 0xDC, 0x31, 0x98, 0x47, 0xED, 0xE7, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0xD0, 0x9C, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x2C, 0x4F, 0x2D, 0x4D, -+0xDF, 0xF8, 0xC8, 0xA0, 0xDF, 0xF8, 0xC0, 0x80, 0x2B, 0x4E, 0xB9, 0x46, 0x01, 0xE0, 0xA0, 0x68, 0x98, 0x47, 0x4F, 0xF0, -+0x80, 0x40, 0x08, 0xF0, 0x9F, 0xF8, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x01, 0x23, 0xC8, 0xF8, -+0x00, 0x30, 0x2B, 0x68, 0x3C, 0x68, 0x01, 0x33, 0x2B, 0x60, 0x4C, 0xB3, 0x32, 0x69, 0xE3, 0x68, 0x9B, 0x1A, 0x32, 0x2B, -+0x08, 0xD4, 0xDA, 0xF8, 0xDC, 0x31, 0x20, 0x46, 0x98, 0x47, 0x32, 0x69, 0xE3, 0x68, 0x9B, 0x1A, 0x00, 0x2B, 0x2A, 0xDA, -+0x48, 0x46, 0x08, 0xF0, 0x43, 0xF9, 0x2B, 0x68, 0x33, 0xB1, 0x01, 0x3B, 0xD8, 0xF8, 0x00, 0x20, 0x2B, 0x60, 0x0B, 0xB9, -+0x02, 0xB1, 0x62, 0xB6, 0x14, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x63, 0x68, 0xCB, 0xDA, 0x00, 0x2B, -+0xC9, 0xD1, 0x11, 0x49, 0x11, 0x48, 0xEB, 0x22, 0x09, 0xF0, 0x3C, 0xFD, 0x63, 0x68, 0xC2, 0xE7, 0xDA, 0xF8, 0xDC, 0x31, -+0x20, 0x46, 0x98, 0x47, 0x2B, 0x68, 0x33, 0xB1, 0x0C, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0xBD, 0xE8, 0xF0, 0x87, 0x2B, 0x68, 0x00, 0x2B, 0xFA, 0xD0, 0xF2, 0xE7, 0x00, 0xBF, 0xD0, 0x9C, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x90, 0x9F, 0x15, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0xB5, 0x11, 0xF4, 0x00, 0x05, 0x04, 0x46, 0x0E, 0xD1, 0x90, 0xF8, -+0x5C, 0x22, 0x1E, 0x49, 0x1E, 0x48, 0x01, 0x32, 0xD2, 0xB2, 0x84, 0xF8, 0x5C, 0x22, 0x09, 0xF0, 0x8D, 0xFA, 0x94, 0xF8, -+0x5C, 0x32, 0x09, 0x2B, 0x15, 0xD8, 0x70, 0xBD, 0x17, 0x49, 0x19, 0x48, 0x09, 0xF0, 0x84, 0xFA, 0x94, 0xF8, 0x23, 0x30, -+0x00, 0x22, 0x0D, 0x2B, 0x84, 0xF8, 0x5C, 0x22, 0xF3, 0xD8, 0x15, 0x49, 0x15, 0x4A, 0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, -+0x03, 0x13, 0x12, 0x69, 0xC3, 0xF8, 0x58, 0x22, 0x70, 0xBD, 0x2A, 0x46, 0x08, 0x23, 0x0C, 0x21, 0x7D, 0x20, 0x07, 0xF0, -+0x05, 0xFC, 0x94, 0xF8, 0x23, 0x30, 0x03, 0x70, 0x94, 0xF8, 0x22, 0x30, 0x43, 0x70, 0x06, 0x46, 0x04, 0xF1, 0x26, 0x01, -+0x84, 0xF8, 0x5C, 0x52, 0x02, 0x30, 0x06, 0x22, 0x1B, 0xF0, 0x7E, 0xFF, 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x07, 0xF0, -+0x21, 0xBC, 0x00, 0xBF, 0x34, 0xA0, 0x15, 0x00, 0x9C, 0x9F, 0x15, 0x00, 0xB4, 0x9F, 0x15, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x00, 0x10, 0x50, 0x40, 0x2D, 0xE9, 0xF0, 0x4F, 0x90, 0xF8, 0x63, 0x30, 0x63, 0x4A, 0x4F, 0xF4, 0x1E, 0x74, 0x0A, 0x33, -+0x04, 0xFB, 0x03, 0xF3, 0x11, 0x46, 0x02, 0xF1, 0x28, 0x04, 0x1C, 0x44, 0x1A, 0x44, 0x83, 0xB0, 0x0B, 0x46, 0xD2, 0xF8, -+0x08, 0x12, 0x00, 0x29, 0x40, 0xF0, 0xA2, 0x80, 0xD2, 0xF8, 0x30, 0x12, 0x08, 0x32, 0x00, 0x29, 0x40, 0xF0, 0x9C, 0x80, -+0xA2, 0x42, 0xF2, 0xD1, 0x57, 0x4A, 0x58, 0x4C, 0xDF, 0xF8, 0x70, 0xB1, 0x4F, 0xF4, 0xA4, 0x61, 0x93, 0xF8, 0x25, 0x60, -+0x2E, 0xB1, 0x93, 0xF8, 0x22, 0x60, 0x01, 0xFB, 0x06, 0x46, 0xB0, 0x42, 0x06, 0xD0, 0x03, 0xF5, 0x1E, 0x73, 0x9A, 0x42, -+0xF2, 0xD1, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x93, 0xF8, 0x23, 0x60, 0x0D, 0x2E, 0x77, 0xD9, 0x4F, 0xF0, 0x00, 0x08, -+0xDB, 0xF8, 0x10, 0xE0, 0x1E, 0x46, 0x03, 0xF1, 0x28, 0x0C, 0xD6, 0xF8, 0x08, 0x72, 0x77, 0xB9, 0xD6, 0xF8, 0x30, 0x72, -+0x08, 0x36, 0x57, 0xB9, 0xB4, 0x45, 0xF6, 0xD1, 0xCE, 0xF5, 0x64, 0x0E, 0x0E, 0xF5, 0x61, 0x4E, 0x0E, 0xF1, 0xC0, 0x0E, -+0x1E, 0xEB, 0x08, 0x0F, 0xDB, 0xD5, 0x90, 0xF8, 0x63, 0x60, 0x93, 0xF8, 0x20, 0xE0, 0x00, 0x96, 0x35, 0x46, 0xC6, 0xEB, -+0x86, 0x17, 0x3C, 0x4E, 0x4F, 0xEA, 0xDE, 0x08, 0x06, 0xEB, 0x87, 0x07, 0x0E, 0xF0, 0x07, 0x0C, 0x01, 0x26, 0x18, 0xF8, -+0x07, 0x90, 0x06, 0xFA, 0x0C, 0xFC, 0x1C, 0xEA, 0x09, 0x0F, 0x07, 0xEB, 0xDE, 0x06, 0x01, 0x96, 0x5F, 0xFA, 0x8C, 0xFA, -+0x0F, 0xFA, 0x85, 0xFE, 0xBD, 0xD1, 0x4A, 0xEA, 0x09, 0x09, 0x08, 0xF8, 0x07, 0x90, 0xB0, 0xF8, 0xD0, 0x90, 0x90, 0xF8, -+0xD8, 0xC0, 0x09, 0xF1, 0x01, 0x09, 0xC4, 0x45, 0xA0, 0xF8, 0xD0, 0x90, 0x3E, 0xD8, 0xAF, 0x00, 0x90, 0xF8, 0xD9, 0x90, -+0xC1, 0x45, 0x0B, 0xD2, 0x00, 0x9D, 0x28, 0x4E, 0x80, 0xF8, 0xD9, 0x80, 0x07, 0xEB, 0x05, 0x0A, 0x06, 0xEB, 0xCA, 0x0A, -+0x01, 0x9E, 0xCA, 0xF8, 0x20, 0x60, 0xC1, 0x46, 0x23, 0x4E, 0x00, 0x9D, 0xCC, 0xF1, 0x06, 0x0C, 0xCC, 0x44, 0x06, 0xEB, -+0xCE, 0x0E, 0x1F, 0xFA, 0x8C, 0xFC, 0x1E, 0x4E, 0xA0, 0xF8, 0xCE, 0xC0, 0xAC, 0xF1, 0x02, 0x08, 0x8E, 0xF8, 0x01, 0x80, -+0x4F, 0xF0, 0x28, 0x0C, 0x2F, 0x44, 0x06, 0xEB, 0xC7, 0x07, 0x0C, 0xFB, 0x05, 0x66, 0x90, 0xF8, 0xD8, 0xC0, 0x8E, 0xF8, -+0x04, 0xC0, 0x14, 0x36, 0x0E, 0xF1, 0x04, 0x0E, 0xC7, 0xF8, 0x0C, 0xE0, 0x7E, 0x60, 0x7C, 0xE7, 0x0D, 0x4D, 0x4F, 0xF4, -+0x1E, 0x77, 0x07, 0xFB, 0x06, 0x56, 0xD6, 0xF8, 0x58, 0x82, 0x81, 0xE7, 0x0F, 0x4A, 0x01, 0x21, 0x11, 0x70, 0x61, 0xE7, -+0x00, 0x9D, 0x0B, 0x4E, 0x05, 0xEB, 0x85, 0x09, 0x08, 0xF0, 0x1E, 0x0C, 0x06, 0xEB, 0xC9, 0x09, 0x67, 0x44, 0x80, 0xF8, -+0xD8, 0xC0, 0xC9, 0xF8, 0x1C, 0x70, 0xAF, 0x00, 0xB2, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x18, 0x7E, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x3C, 0x4C, 0x18, 0x00, 0x9C, 0x4B, 0x18, 0x00, 0x2C, 0x50, 0x18, 0x00, 0x16, 0x2C, 0x17, 0x00, -+0x00, 0x10, 0x50, 0x40, 0x2D, 0xE9, 0xF8, 0x43, 0x02, 0x88, 0xC3, 0x78, 0x04, 0x46, 0xB2, 0xB9, 0x82, 0x78, 0x00, 0x2A, -+0x40, 0xF0, 0xAD, 0x80, 0x88, 0x48, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x03, 0x83, 0xF8, 0xDA, 0x20, 0x34, 0xF8, -+0x04, 0x1C, 0x42, 0x20, 0x00, 0x22, 0x07, 0xF0, 0x5B, 0xFB, 0xA4, 0xF1, 0x0C, 0x00, 0xBD, 0xE8, 0xF8, 0x43, 0x07, 0xF0, -+0x69, 0xBB, 0x80, 0x48, 0x80, 0x4D, 0x94, 0xF8, 0x02, 0xE0, 0xC3, 0xEB, 0x83, 0x11, 0x00, 0xEB, 0x81, 0x00, 0x01, 0x26, -+0xC2, 0xF3, 0xC7, 0x01, 0x02, 0xF0, 0x07, 0x02, 0x06, 0xFA, 0x02, 0xF2, 0x0F, 0x5C, 0x0E, 0x18, 0x5F, 0xFA, 0x82, 0xFC, -+0x05, 0xEB, 0xC3, 0x05, 0xBE, 0xF1, 0x00, 0x0F, 0x4D, 0xD0, 0x1C, 0xEA, 0x07, 0x0F, 0xD8, 0xD1, 0xDF, 0xF8, 0xC4, 0xE1, -+0x4F, 0xF4, 0xA4, 0x62, 0x4C, 0xEA, 0x07, 0x07, 0x02, 0xFB, 0x03, 0xE2, 0x37, 0x70, 0xB2, 0xF8, 0xD0, 0x70, 0x92, 0xF8, -+0xD8, 0xC0, 0x01, 0x37, 0x8C, 0x45, 0xA2, 0xF8, 0xD0, 0x70, 0x6C, 0x4F, 0x0A, 0xD9, 0x03, 0xEB, 0x83, 0x0C, 0x01, 0xF0, -+0xFE, 0x08, 0x07, 0xEB, 0xCC, 0x0C, 0x40, 0x44, 0xCC, 0xF8, 0x1C, 0x00, 0x82, 0xF8, 0xD8, 0x80, 0x4F, 0xF4, 0xA4, 0x60, -+0x00, 0xFB, 0x03, 0xE0, 0x4F, 0xEA, 0x83, 0x0C, 0x90, 0xF8, 0xD9, 0x80, 0x88, 0x45, 0x07, 0xD2, 0x0C, 0xEB, 0x03, 0x02, -+0x07, 0xEB, 0xC2, 0x02, 0x80, 0xF8, 0xD9, 0x10, 0x88, 0x46, 0x16, 0x62, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x03, 0xEE, -+0x0C, 0xEB, 0x03, 0x01, 0x9E, 0xF8, 0xD8, 0x20, 0x2A, 0x71, 0xC2, 0xF1, 0x06, 0x02, 0x28, 0x20, 0x42, 0x44, 0x07, 0xEB, -+0xC1, 0x01, 0x00, 0xFB, 0x03, 0x73, 0x92, 0xB2, 0x2E, 0x1D, 0x14, 0x33, 0x90, 0x1E, 0xCE, 0x60, 0x4B, 0x60, 0xAE, 0xF8, -+0xCE, 0x20, 0x68, 0x70, 0x8D, 0xE7, 0x1C, 0xEA, 0x07, 0x0F, 0x8A, 0xD0, 0xDF, 0xF8, 0x28, 0xE1, 0x4F, 0xF4, 0xA4, 0x68, -+0x08, 0xFB, 0x03, 0xF8, 0x27, 0xEA, 0x02, 0x02, 0x0E, 0xEB, 0x08, 0x0C, 0x32, 0x70, 0xBC, 0xF8, 0xD0, 0x70, 0x01, 0x3F, -+0xBF, 0xB2, 0xAC, 0xF8, 0xD0, 0x70, 0x00, 0x2F, 0x4D, 0xD0, 0x9C, 0xF8, 0xD8, 0x70, 0x01, 0xF0, 0xFE, 0x02, 0x97, 0x42, -+0x29, 0xD0, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x03, 0xE2, 0x92, 0xF8, 0xD9, 0x70, 0x8F, 0x42, 0x35, 0xD0, 0x4F, 0xF4, -+0xA4, 0x62, 0x02, 0xFB, 0x03, 0xE3, 0x93, 0xF8, 0xD8, 0x10, 0x29, 0x71, 0xC1, 0xF1, 0x06, 0x01, 0x39, 0x44, 0x89, 0xB2, -+0x8A, 0x1E, 0xA3, 0xF8, 0xCE, 0x10, 0x6A, 0x70, 0x59, 0xE7, 0x32, 0x49, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x03, 0x13, -+0x01, 0x22, 0x83, 0xF8, 0xDA, 0x20, 0x50, 0xE7, 0x3A, 0x5C, 0x07, 0xF1, 0x01, 0x08, 0x00, 0x2A, 0x51, 0xD1, 0x5F, 0xFA, -+0x88, 0xF7, 0x8C, 0xF8, 0xD8, 0x70, 0xFB, 0x2F, 0xF4, 0xD1, 0xFA, 0x22, 0x17, 0x46, 0xDF, 0xF8, 0xA8, 0x90, 0x03, 0xEB, -+0x83, 0x08, 0x4F, 0xF4, 0xA4, 0x6C, 0x09, 0xEB, 0xC8, 0x08, 0x0C, 0xFB, 0x03, 0xEC, 0x02, 0x44, 0xC8, 0xF8, 0x1C, 0x20, -+0x8C, 0xF8, 0xD8, 0x70, 0xC1, 0xE7, 0x41, 0xB3, 0x37, 0x78, 0x01, 0x39, 0xB4, 0x46, 0xC9, 0xB2, 0x01, 0x3E, 0x57, 0xBB, -+0x82, 0xF8, 0xD9, 0x10, 0xF5, 0xE7, 0x0E, 0xF1, 0xD8, 0x02, 0x06, 0x21, 0xAC, 0xF8, 0xCE, 0x10, 0xFF, 0x21, 0x28, 0xF8, -+0x02, 0x10, 0x19, 0x4A, 0x9C, 0xF8, 0xCE, 0x10, 0x2F, 0x71, 0x03, 0xEB, 0x83, 0x03, 0x02, 0xEB, 0xC3, 0x03, 0x6E, 0x1D, -+0x8A, 0x1E, 0xDE, 0x60, 0x6A, 0x70, 0xE2, 0x78, 0x9C, 0xF8, 0xD9, 0x50, 0x12, 0x49, 0x02, 0xEB, 0x82, 0x02, 0x28, 0x44, -+0x01, 0xEB, 0x82, 0x02, 0x18, 0x62, 0x5A, 0x60, 0x09, 0xE7, 0x0F, 0x46, 0x0C, 0x4A, 0x03, 0xEB, 0x83, 0x01, 0x02, 0xEB, -+0xC1, 0x02, 0x10, 0x62, 0x97, 0xE7, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x03, 0xE2, 0x60, 0x46, 0x92, 0xF8, 0xD9, 0x70, -+0xF0, 0xE7, 0x07, 0xF0, 0xFE, 0x07, 0x3A, 0x46, 0xB1, 0xE7, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, 0x3C, 0x4C, 0x18, 0x00, -+0x2C, 0x50, 0x18, 0x00, 0x9C, 0x4B, 0x18, 0x00, 0x4C, 0x40, 0x18, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0x89, 0x46, 0xD0, 0xF8, -+0xB8, 0x50, 0x89, 0x88, 0x99, 0xF8, 0x08, 0xA0, 0x90, 0xF8, 0x63, 0xB0, 0xD5, 0xF8, 0x24, 0x80, 0x2A, 0x4B, 0xB9, 0xF8, -+0x06, 0x70, 0xD3, 0xF8, 0x54, 0x31, 0x29, 0x4E, 0xA1, 0xEB, 0x0A, 0x0A, 0x04, 0x46, 0x42, 0x46, 0xA0, 0xF8, 0xCC, 0xA0, -+0x58, 0x46, 0x98, 0x47, 0xB9, 0xF8, 0x06, 0x30, 0x6A, 0x6A, 0x21, 0x6C, 0x23, 0x48, 0x03, 0xF1, 0xFF, 0x3C, 0x62, 0x44, -+0xAA, 0x62, 0x99, 0xF8, 0x08, 0xC0, 0x06, 0xEB, 0xCB, 0x06, 0xDB, 0x43, 0x0B, 0xEB, 0x8B, 0x0B, 0x0C, 0xF1, 0x01, 0x0C, -+0x00, 0xEB, 0x8B, 0x0B, 0x62, 0x44, 0x53, 0x44, 0x13, 0x44, 0x00, 0x20, 0xCB, 0xE9, 0x02, 0x23, 0x03, 0x37, 0xCB, 0xF8, -+0x10, 0x00, 0x31, 0xB3, 0x94, 0xF8, 0xC0, 0x34, 0x0A, 0x79, 0x16, 0x49, 0xE3, 0xB1, 0x16, 0x4A, 0x16, 0x48, 0x13, 0x68, -+0x12, 0x68, 0x1B, 0x02, 0xD2, 0xB2, 0x9B, 0xB2, 0x13, 0x43, 0x00, 0x22, 0x4B, 0x62, 0xC5, 0xE9, 0x0D, 0x21, 0xE8, 0x64, -+0x94, 0xF8, 0x63, 0x30, 0x10, 0x4A, 0x03, 0xEB, 0x83, 0x03, 0x02, 0xEB, 0xC3, 0x03, 0x01, 0x22, 0x2B, 0x62, 0x84, 0xF8, -+0xD6, 0x20, 0x18, 0xF8, 0x07, 0x30, 0xF3, 0x70, 0xBD, 0xE8, 0xF8, 0x8F, 0x0A, 0x4B, 0x82, 0x42, 0x08, 0xBF, 0x19, 0x46, -+0xDD, 0xE7, 0x04, 0x49, 0xDB, 0xE7, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x2C, 0x50, 0x18, 0x00, 0x4C, 0x40, 0x18, 0x00, -+0x84, 0x3C, 0x18, 0x00, 0xA0, 0x00, 0x32, 0x40, 0x41, 0x00, 0x00, 0x01, 0x9C, 0x4B, 0x18, 0x00, 0xC4, 0x3C, 0x18, 0x00, -+0x2D, 0xE9, 0xF8, 0x43, 0x4D, 0x4D, 0x90, 0xF8, 0x63, 0x30, 0xD0, 0xF8, 0xB8, 0x80, 0x05, 0xEB, 0xC3, 0x05, 0x04, 0x46, -+0x2F, 0x79, 0x00, 0xF1, 0x6C, 0x06, 0xFF, 0xF7, 0x7D, 0xFD, 0xB0, 0xF8, 0xCC, 0x30, 0xB0, 0xF8, 0xCE, 0x20, 0x13, 0x44, -+0x04, 0x33, 0xC8, 0xF8, 0x2C, 0x30, 0x90, 0xF8, 0xC0, 0x34, 0x00, 0x2B, 0x54, 0xD1, 0x42, 0x4A, 0xD8, 0xF8, 0x24, 0x10, -+0xB2, 0xF8, 0xFC, 0x31, 0x01, 0x33, 0x9B, 0xB2, 0x18, 0x01, 0xA2, 0xF8, 0xFC, 0x31, 0xC8, 0x82, 0x94, 0xF8, 0xD7, 0x30, -+0xAB, 0x70, 0x94, 0xF8, 0xDA, 0x90, 0xCB, 0xBB, 0xB9, 0xF1, 0x00, 0x0F, 0x31, 0xD1, 0x07, 0xF0, 0xFE, 0x07, 0x38, 0x4B, -+0x1B, 0x78, 0x0B, 0xB1, 0x47, 0xF0, 0x01, 0x07, 0xEB, 0x78, 0x84, 0xF8, 0xD7, 0x30, 0x2F, 0x71, 0x94, 0xF8, 0xD7, 0x30, -+0x94, 0xF8, 0xDB, 0x50, 0x01, 0x3B, 0x84, 0xF8, 0xD7, 0x30, 0xBD, 0xB1, 0x01, 0x3D, 0x94, 0xF8, 0xDC, 0x30, 0xED, 0xB2, -+0x84, 0xF8, 0xDB, 0x50, 0x63, 0xB1, 0xD8, 0xF8, 0x24, 0x20, 0xD5, 0x54, 0x94, 0xF8, 0xDD, 0x30, 0x23, 0xB1, 0xD8, 0xF8, -+0x24, 0x20, 0x94, 0xF8, 0xDB, 0x10, 0xD1, 0x54, 0x94, 0xF8, 0xDB, 0x50, 0x7D, 0xBB, 0x01, 0x23, 0x84, 0xF8, 0xDB, 0x30, -+0x20, 0x46, 0x31, 0x46, 0x06, 0xF0, 0xE0, 0xFC, 0x48, 0x46, 0xBD, 0xE8, 0xF8, 0x83, 0x47, 0xF0, 0x01, 0x07, 0x4F, 0xF0, -+0x01, 0x09, 0xCA, 0xE7, 0x19, 0xF0, 0x02, 0x09, 0x1A, 0xBF, 0x47, 0xF0, 0x01, 0x07, 0x4F, 0xF0, 0x01, 0x09, 0x07, 0xF0, -+0xFE, 0x07, 0xC8, 0xE7, 0x90, 0xF8, 0xC1, 0x04, 0x05, 0xF0, 0x7E, 0xF9, 0x00, 0x28, 0xA4, 0xD0, 0x94, 0xF8, 0x63, 0x10, -+0x15, 0x4A, 0xD8, 0xF8, 0x2C, 0x30, 0x01, 0xEB, 0x81, 0x01, 0x02, 0xEB, 0x81, 0x02, 0x19, 0x18, 0x93, 0x68, 0xC8, 0xF8, -+0x2C, 0x10, 0x01, 0x3B, 0x18, 0x44, 0xD0, 0x60, 0x93, 0xE7, 0x02, 0x23, 0x00, 0x22, 0x0C, 0x21, 0x4E, 0x20, 0x94, 0xF8, -+0x63, 0x70, 0x07, 0xF0, 0xE3, 0xF8, 0x07, 0x70, 0x45, 0x70, 0x07, 0xF0, 0x0F, 0xF9, 0x94, 0xF8, 0xDB, 0x30, 0x00, 0x2B, -+0xBF, 0xD0, 0x20, 0x46, 0x31, 0x46, 0x06, 0xF0, 0xA3, 0xFC, 0x48, 0x46, 0xBD, 0xE8, 0xF8, 0x83, 0x2C, 0x50, 0x18, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x16, 0x2C, 0x17, 0x00, 0xFC, 0x3E, 0x18, 0x00, 0xF8, 0xB5, 0x18, 0x4D, 0x18, 0x4F, 0x2E, 0x68, -+0x04, 0x46, 0x36, 0xF8, 0x04, 0x1C, 0x00, 0x22, 0x40, 0x20, 0x07, 0xF0, 0x29, 0xF9, 0xD7, 0xF8, 0x78, 0x31, 0x29, 0x68, -+0x20, 0x46, 0x98, 0x47, 0x2A, 0x68, 0x00, 0x23, 0x84, 0xF8, 0xDB, 0x30, 0x93, 0x7A, 0x84, 0xF8, 0xDC, 0x30, 0xD2, 0x7A, -+0x84, 0xF8, 0xDD, 0x20, 0x0C, 0x3E, 0xD4, 0xF8, 0xB8, 0x20, 0x23, 0xB1, 0x52, 0x6A, 0xD3, 0x5C, 0x01, 0x33, 0x84, 0xF8, -+0xDB, 0x30, 0x2B, 0x7A, 0x00, 0x22, 0x6A, 0x72, 0x13, 0xB1, 0xD7, 0xF8, 0x84, 0x31, 0x98, 0x47, 0x00, 0x23, 0x30, 0x46, -+0x2B, 0x60, 0xBD, 0xE8, 0xF8, 0x40, 0x07, 0xF0, 0x17, 0xB9, 0x00, 0xBF, 0xD8, 0x9C, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x70, 0xB5, 0x0E, 0x4D, 0x44, 0x7A, 0x0E, 0x4A, 0x0E, 0x49, 0x03, 0x46, 0x4F, 0xF4, 0x1A, 0x70, 0x00, 0xFB, 0x04, 0x50, -+0x01, 0x25, 0x55, 0x72, 0x00, 0x25, 0x95, 0x72, 0x9A, 0x88, 0x68, 0x30, 0x1B, 0xF0, 0x0C, 0xFC, 0x08, 0x4A, 0x09, 0x4B, -+0x4F, 0xF4, 0xA4, 0x60, 0x29, 0x46, 0x00, 0xFB, 0x04, 0x20, 0xD3, 0xF8, 0x94, 0x31, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, -+0xFC, 0x41, 0x18, 0x00, 0xD8, 0x9C, 0x17, 0x00, 0x14, 0x2A, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x7E, 0x4B, 0x2D, 0xE9, 0xF0, 0x4F, 0x1B, 0x68, 0x7D, 0x4D, 0xB3, 0xF9, 0x00, 0x30, 0x6E, 0x68, 0x00, 0x2B, 0x83, 0xB0, -+0x04, 0x46, 0x44, 0xDB, 0x01, 0x3E, 0x6E, 0x60, 0x00, 0x2E, 0x4D, 0xD0, 0xDF, 0xF8, 0xE0, 0x91, 0x77, 0x4D, 0x78, 0x4E, -+0x78, 0x4F, 0xDF, 0xF8, 0x00, 0xA2, 0xDF, 0xF8, 0x00, 0x82, 0x03, 0xE0, 0x05, 0xF5, 0x1E, 0x75, 0xB5, 0x42, 0x2F, 0xD0, -+0x95, 0xF8, 0x25, 0x20, 0x4F, 0xF4, 0xA4, 0x61, 0x00, 0x2A, 0xF5, 0xD0, 0x95, 0xF8, 0x22, 0x30, 0x01, 0xFB, 0x03, 0x73, -+0x9C, 0x42, 0xEF, 0xD1, 0x95, 0xF8, 0x23, 0x30, 0x0D, 0x2B, 0x9B, 0xBF, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x03, 0x93, -+0x00, 0x22, 0xD3, 0xF8, 0x58, 0x22, 0xDA, 0xF8, 0x10, 0x30, 0xA8, 0xEB, 0x03, 0x03, 0xD3, 0x42, 0xDE, 0xD5, 0x20, 0x46, -+0xF2, 0xF7, 0x96, 0xFF, 0x00, 0x28, 0xD9, 0xD0, 0x63, 0x49, 0x95, 0xF8, 0x23, 0x00, 0x2A, 0x46, 0xF4, 0xF7, 0xAE, 0xFB, -+0x00, 0x28, 0xD1, 0xD1, 0x95, 0xF8, 0x23, 0x10, 0x5F, 0x48, 0x08, 0xF0, 0x89, 0xFE, 0xCB, 0xE7, 0x03, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0x00, 0x2E, 0xB8, 0xD1, 0x5C, 0x49, 0x5C, 0x48, 0x4F, 0xF4, 0x3F, 0x72, 0x09, 0xF0, 0xF7, 0xF8, 0x6E, 0x68, -+0x01, 0x3E, 0x6E, 0x60, 0x00, 0x2E, 0xB1, 0xD1, 0xDF, 0xF8, 0x74, 0xB1, 0xFC, 0xF7, 0xCC, 0xFF, 0x94, 0xF8, 0x63, 0x30, -+0x9B, 0xF8, 0x00, 0x20, 0x03, 0xF1, 0x0A, 0x08, 0x00, 0x2A, 0x58, 0xD1, 0xDF, 0xF8, 0x2C, 0x91, 0x51, 0x4B, 0x1B, 0x78, -+0x53, 0xB3, 0x08, 0xEB, 0x88, 0x02, 0x4F, 0xF4, 0x1E, 0x73, 0xC8, 0xEB, 0x02, 0x12, 0x4E, 0x4F, 0x01, 0x92, 0x03, 0xFB, -+0x08, 0x9B, 0x4F, 0xF0, 0x00, 0x0A, 0xDB, 0xF8, 0x08, 0x32, 0x5F, 0xFA, 0x8A, 0xF6, 0x0B, 0xF5, 0x02, 0x78, 0x53, 0xB1, -+0x40, 0x46, 0x07, 0xF0, 0xBB, 0xFC, 0xD7, 0xF8, 0x24, 0x34, 0x31, 0x46, 0x98, 0x47, 0xDB, 0xF8, 0x08, 0x32, 0x00, 0x2B, -+0xF4, 0xD1, 0xDB, 0xF8, 0x30, 0x22, 0x00, 0x2A, 0x5B, 0xD1, 0x0A, 0xF1, 0x01, 0x0A, 0xBA, 0xF1, 0x04, 0x0F, 0x0B, 0xF1, -+0x08, 0x0B, 0xE2, 0xD1, 0x3B, 0x4B, 0x1A, 0x70, 0xAB, 0x7A, 0x03, 0xBB, 0xEB, 0x68, 0x63, 0xB1, 0x39, 0x4F, 0xDF, 0xF8, -+0xF8, 0x80, 0xD7, 0xF8, 0xD4, 0x61, 0x40, 0x46, 0x07, 0xF0, 0x9A, 0xFC, 0x0C, 0x30, 0xB0, 0x47, 0xEB, 0x68, 0x00, 0x2B, -+0xF5, 0xD1, 0x94, 0xF8, 0x63, 0x00, 0x05, 0x44, 0x29, 0x7D, 0x19, 0xB1, 0x30, 0x4B, 0xD3, 0xF8, 0x90, 0x31, 0x98, 0x47, -+0x94, 0xF8, 0xDB, 0x30, 0x01, 0x2B, 0x7F, 0xF4, 0x59, 0xAF, 0x20, 0x46, 0xFB, 0xF7, 0xBE, 0xFA, 0x54, 0xE7, 0x2A, 0x4F, -+0x28, 0x68, 0xD7, 0xF8, 0x8C, 0x31, 0x98, 0x47, 0xD8, 0xE7, 0x04, 0x23, 0x32, 0x46, 0x0C, 0x21, 0x4A, 0x20, 0x06, 0xF0, -+0xA5, 0xFF, 0x80, 0xF8, 0x00, 0x80, 0x46, 0x70, 0x86, 0x70, 0x06, 0xF0, 0xCF, 0xFF, 0x9B, 0xF8, 0x00, 0x30, 0xDF, 0xF8, -+0x60, 0x90, 0x00, 0x2B, 0x96, 0xD0, 0x4F, 0xF4, 0x1E, 0x7A, 0x0A, 0xFB, 0x08, 0x9A, 0x9A, 0xF8, 0x31, 0x30, 0x9B, 0x07, -+0x0B, 0xD5, 0x1A, 0x4F, 0x09, 0x22, 0x8A, 0xF8, 0x32, 0x20, 0xD7, 0xF8, 0x20, 0x33, 0x32, 0x46, 0x51, 0x46, 0x20, 0x46, -+0x98, 0x47, 0x8A, 0xF8, 0x32, 0x60, 0x00, 0x23, 0x8B, 0xF8, 0x00, 0x30, 0x7E, 0xE7, 0x01, 0x98, 0x46, 0x30, 0x50, 0x44, -+0x09, 0xEB, 0xC0, 0x00, 0x07, 0xF0, 0x4C, 0xFC, 0x0E, 0x4B, 0x31, 0x46, 0xD3, 0xF8, 0x24, 0x34, 0x98, 0x47, 0x0D, 0x48, -+0x08, 0xF0, 0xDA, 0xFD, 0xFE, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0xD8, 0x9C, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x18, 0x7E, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x51, 0xB1, 0x13, 0x00, 0xF8, 0x9F, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xC8, 0x9F, 0x15, 0x00, 0x16, 0x2C, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xDC, 0x9F, 0x15, 0x00, 0x00, 0x10, 0x50, 0x40, -+0xC0, 0xE1, 0xE4, 0x00, 0x10, 0x2A, 0x17, 0x00, 0xE4, 0x9C, 0x17, 0x00, 0x38, 0xB5, 0x0E, 0x4D, 0x0E, 0x4C, 0x18, 0x22, -+0x00, 0x21, 0x28, 0x46, 0xE4, 0xF7, 0x42, 0xFB, 0x05, 0xF1, 0x0C, 0x00, 0x07, 0xF0, 0xCE, 0xFB, 0x20, 0x46, 0x04, 0xF0, -+0xD9, 0xFF, 0x04, 0xF1, 0x26, 0x00, 0x04, 0xF0, 0xD5, 0xFF, 0x04, 0xF1, 0x4C, 0x00, 0x04, 0xF0, 0xD1, 0xFF, 0x04, 0xF1, -+0x72, 0x00, 0xBD, 0xE8, 0x38, 0x40, 0x04, 0xF0, 0xCB, 0xBF, 0x00, 0xBF, 0xD8, 0x9C, 0x17, 0x00, 0x64, 0x3E, 0x18, 0x00, -+0x2D, 0xE9, 0xF8, 0x43, 0x90, 0xF8, 0x63, 0x30, 0x3F, 0x4D, 0x40, 0x49, 0x40, 0x4F, 0xDF, 0xF8, 0x1C, 0x91, 0x04, 0x46, -+0x03, 0xEB, 0x83, 0x02, 0x3E, 0x48, 0x4F, 0xF4, 0x1A, 0x76, 0x03, 0xEB, 0x42, 0x02, 0x06, 0xFB, 0x03, 0x11, 0x05, 0xEB, -+0xC2, 0x02, 0x00, 0xEB, 0x83, 0x13, 0x04, 0xF1, 0x6C, 0x00, 0xF4, 0xF7, 0xFD, 0xF8, 0x94, 0xF8, 0x63, 0x30, 0x37, 0x49, -+0xDF, 0xF8, 0xF0, 0xC0, 0x36, 0x48, 0x06, 0x22, 0xA4, 0xF8, 0xCE, 0x20, 0x00, 0x25, 0x01, 0xEB, 0xC3, 0x02, 0x4F, 0xF0, -+0x05, 0x0E, 0xFF, 0x26, 0xA4, 0xF8, 0xD8, 0x60, 0x84, 0xF8, 0xD7, 0x50, 0xA4, 0xF8, 0xD0, 0x50, 0x84, 0xF8, 0xDA, 0x50, -+0x04, 0x26, 0x01, 0xF8, 0x33, 0xE0, 0x56, 0x70, 0x94, 0xF8, 0xD7, 0x10, 0x91, 0x70, 0x01, 0x21, 0x15, 0x71, 0x55, 0x71, -+0xD1, 0x70, 0x94, 0xF8, 0xD9, 0x10, 0x03, 0xEB, 0x83, 0x08, 0xC3, 0xEB, 0x83, 0x16, 0x00, 0xEB, 0x86, 0x00, 0x0C, 0xEB, -+0xC8, 0x06, 0x01, 0x44, 0x07, 0xEB, 0x88, 0x03, 0x31, 0x62, 0x02, 0xEB, 0x0E, 0x01, 0xC6, 0xE9, 0x03, 0x15, 0x4C, 0xF8, -+0x38, 0x90, 0xB2, 0x60, 0x73, 0x60, 0xB3, 0x61, 0x29, 0x46, 0xFC, 0x22, 0xC6, 0xF8, 0x14, 0x90, 0xE4, 0xF7, 0xCE, 0xFA, -+0x07, 0xEB, 0x88, 0x03, 0x47, 0xF8, 0x28, 0x90, 0x5D, 0x60, 0x1D, 0x61, 0x94, 0xF8, 0xC0, 0x34, 0x93, 0xB1, 0x94, 0xF8, -+0x63, 0x30, 0x15, 0x48, 0x15, 0x49, 0x03, 0xEB, 0xC3, 0x02, 0x03, 0xEB, 0x42, 0x02, 0x03, 0xEB, 0x83, 0x03, 0x01, 0xEB, -+0x42, 0x01, 0x00, 0xEB, 0x83, 0x02, 0xC2, 0xE9, 0x01, 0x51, 0x40, 0xF8, 0x23, 0x90, 0x15, 0x61, 0xD4, 0xF8, 0xB8, 0x30, -+0x0D, 0x49, 0x00, 0x22, 0x5A, 0x63, 0xDA, 0x64, 0x1A, 0x62, 0xD1, 0xF8, 0x88, 0x31, 0xC4, 0xE9, 0x30, 0x34, 0xBD, 0xE8, -+0xF8, 0x83, 0x00, 0xBF, 0x9C, 0x40, 0x18, 0x00, 0xFC, 0x41, 0x18, 0x00, 0x4C, 0x40, 0x18, 0x00, 0x4C, 0x3F, 0x18, 0x00, -+0x2C, 0x50, 0x18, 0x00, 0x3C, 0x4C, 0x18, 0x00, 0xFC, 0x3E, 0x18, 0x00, 0x64, 0x3E, 0x18, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xDE, 0xFA, 0xFE, 0xCA, 0x9C, 0x4B, 0x18, 0x00, 0x05, 0x4B, 0x5A, 0x68, 0x18, 0x60, 0x12, 0xB1, 0x01, 0x22, 0x9A, 0x72, -+0x70, 0x47, 0x03, 0x4B, 0xD3, 0xF8, 0x8C, 0x31, 0x18, 0x47, 0x00, 0xBF, 0xD8, 0x9C, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x06, 0x4B, 0x5A, 0x68, 0x1A, 0xB9, 0x06, 0x4B, 0xD3, 0xF8, 0xD4, 0x31, 0x18, 0x47, 0xA0, 0xF1, 0x0C, 0x01, 0x03, 0xF1, -+0x0C, 0x00, 0x07, 0xF0, 0x05, 0xBB, 0x00, 0xBF, 0xD8, 0x9C, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, -+0x40, 0x4B, 0x41, 0x4A, 0x1B, 0x68, 0x94, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x3F, 0x4E, 0x00, 0x2B, 0x41, 0xDB, 0x75, 0x7A, -+0x00, 0x2D, 0x4A, 0xD1, 0x3D, 0x4A, 0x35, 0x72, 0x17, 0x68, 0x7F, 0x01, 0x6C, 0xB1, 0xDF, 0xF8, 0xF8, 0x90, 0xDF, 0xF8, -+0xF8, 0x80, 0xAA, 0x46, 0x4F, 0xF0, 0x01, 0x0B, 0x94, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0x04, 0xD0, 0x24, 0x68, 0x00, 0x2C, -+0xF8, 0xD1, 0xBD, 0xE8, 0xF8, 0x8F, 0x94, 0xF8, 0xD6, 0x30, 0x00, 0x2B, 0xF6, 0xD0, 0x94, 0xF8, 0x64, 0x30, 0x00, 0x2B, -+0xF2, 0xD0, 0x94, 0xF8, 0xD5, 0x20, 0x94, 0xF8, 0xD4, 0x30, 0x9A, 0x42, 0xEC, 0xD1, 0xD9, 0xF8, 0x70, 0x31, 0x20, 0x46, -+0x98, 0x47, 0x20, 0xB1, 0x98, 0xF8, 0x00, 0x30, 0x01, 0x33, 0x88, 0xF8, 0x00, 0x30, 0xBB, 0xF1, 0x00, 0x0F, 0x05, 0xD0, -+0xA7, 0xF1, 0x32, 0x02, 0x40, 0xF6, 0xB6, 0x33, 0x9A, 0x42, 0x18, 0xD8, 0xD5, 0xB9, 0x20, 0x46, 0x02, 0xF0, 0x7A, 0xFE, -+0x83, 0x46, 0xF0, 0xB9, 0x88, 0xF8, 0x00, 0x50, 0xD0, 0xE7, 0x73, 0x68, 0x00, 0x2B, 0xBA, 0xD0, 0x1D, 0x49, 0x1E, 0x48, -+0x40, 0xF2, 0x2F, 0x42, 0x08, 0xF0, 0xFE, 0xFE, 0x75, 0x7A, 0x00, 0x2D, 0xB4, 0xD0, 0x01, 0x23, 0x33, 0x72, 0xBD, 0xE8, -+0xF8, 0x8F, 0x20, 0x46, 0x02, 0xF0, 0x62, 0xFE, 0x88, 0xF8, 0x00, 0xA0, 0x24, 0x68, 0x4F, 0xF0, 0x00, 0x0B, 0x01, 0x25, -+0x00, 0x2C, 0xB1, 0xD1, 0xB7, 0xE7, 0x94, 0xF8, 0x63, 0x30, 0x84, 0xF8, 0x88, 0x30, 0xFF, 0x23, 0x84, 0xF8, 0x89, 0x30, -+0x04, 0x21, 0x04, 0xF1, 0x6C, 0x00, 0xF4, 0xF7, 0xDB, 0xF8, 0x73, 0x68, 0x08, 0xB1, 0x01, 0x33, 0x73, 0x60, 0x01, 0x2B, -+0x02, 0xD0, 0x4F, 0xF0, 0x00, 0x0B, 0x9F, 0xE7, 0xFC, 0xF7, 0x58, 0xFD, 0x4F, 0xF0, 0x00, 0x0B, 0x9A, 0xE7, 0x00, 0xBF, -+0x38, 0x36, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0xD8, 0x9C, 0x17, 0x00, 0x40, 0x80, 0x32, 0x40, 0x70, 0x79, 0x15, 0x00, -+0x20, 0xA0, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x10, 0x2A, 0x17, 0x00, 0xF8, 0xB5, 0x27, 0x4F, 0x7B, 0x68, 0x04, 0x46, -+0x0E, 0x46, 0x13, 0xB1, 0x3C, 0x44, 0x21, 0x75, 0xF8, 0xBD, 0x02, 0x29, 0x34, 0xD0, 0x03, 0x29, 0x21, 0xD0, 0x01, 0x29, -+0x14, 0xD0, 0x21, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x32, 0xDB, 0x1F, 0x4D, 0x4F, 0xF4, 0xA4, 0x63, -+0x03, 0xFB, 0x04, 0x53, 0x3C, 0x44, 0x00, 0x22, 0x22, 0x75, 0x93, 0xF8, 0xC1, 0x04, 0x31, 0x46, 0xBD, 0xE8, 0xF8, 0x40, -+0x04, 0xF0, 0xC6, 0xBE, 0x18, 0x4B, 0x19, 0x4A, 0x16, 0x4D, 0x00, 0xEB, 0x80, 0x01, 0x03, 0xEB, 0x81, 0x03, 0x02, 0xEB, -+0x81, 0x02, 0x5A, 0x60, 0xE6, 0xE7, 0x12, 0x4D, 0x14, 0x49, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x00, 0x52, 0x00, 0xEB, -+0xC0, 0x03, 0x00, 0xEB, 0x43, 0x03, 0x01, 0xEB, 0x43, 0x01, 0x92, 0xF8, 0xC1, 0x04, 0x04, 0xF0, 0x47, 0xFE, 0xD5, 0xE7, -+0x0A, 0x4A, 0x09, 0x4D, 0x00, 0xEB, 0x80, 0x01, 0x02, 0xEB, 0x81, 0x02, 0x53, 0x60, 0xCD, 0xE7, 0x09, 0x49, 0x0A, 0x48, -+0x04, 0x4D, 0x40, 0xF2, 0xC6, 0x42, 0x08, 0xF0, 0x71, 0xFE, 0xC5, 0xE7, 0xD8, 0x9C, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x4C, 0x40, 0x18, 0x00, 0xFC, 0x3E, 0x18, 0x00, 0x64, 0x3E, 0x18, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x64, 0x7D, 0x15, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x04, 0x23, 0x00, 0x22, 0x0C, 0x21, 0x44, 0x20, 0x06, 0xF0, 0x76, 0xFD, -+0x23, 0x7E, 0x03, 0x70, 0x04, 0x2B, 0x09, 0xD0, 0x00, 0x23, 0x00, 0x22, 0x43, 0x70, 0xC2, 0x70, 0xA3, 0x7E, 0x83, 0x70, -+0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0, 0x98, 0xBD, 0xE3, 0x89, 0x00, 0x3B, 0x18, 0xBF, 0x01, 0x23, 0xF1, 0xE7, 0x00, 0xBF, -+0x38, 0xB5, 0x05, 0xF0, 0xE1, 0xFA, 0x0C, 0x23, 0x05, 0x46, 0x19, 0x46, 0x00, 0x22, 0x4F, 0x20, 0x06, 0xF0, 0x58, 0xFD, -+0x2B, 0x88, 0x03, 0x80, 0x04, 0x46, 0x28, 0x46, 0x05, 0xF0, 0xDE, 0xFA, 0x10, 0x4A, 0x11, 0x4D, 0x11, 0x49, 0xA2, 0xFB, -+0x00, 0x03, 0x9B, 0x09, 0x63, 0x60, 0x2B, 0x68, 0xA2, 0xFB, 0x03, 0x23, 0x9B, 0x09, 0x00, 0x22, 0xA3, 0x60, 0xA2, 0x70, -+0x0A, 0x23, 0x0A, 0x68, 0x52, 0xB2, 0x01, 0x3B, 0x3A, 0xB9, 0x13, 0xF0, 0xFF, 0x03, 0xF8, 0xD1, 0x20, 0x46, 0xBD, 0xE8, -+0x38, 0x40, 0x06, 0xF0, 0x67, 0xBD, 0xA2, 0x70, 0x20, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x06, 0xF0, 0x61, 0xBD, 0x00, 0xBF, -+0xD3, 0x4D, 0x62, 0x10, 0x20, 0x02, 0x32, 0x40, 0x0C, 0xB2, 0x33, 0x40, 0x10, 0xB5, 0xC1, 0x89, 0x04, 0x46, 0x02, 0x23, -+0x00, 0x22, 0x48, 0x20, 0x06, 0xF0, 0x22, 0xFD, 0x22, 0x7E, 0x42, 0x70, 0xA1, 0x7E, 0x05, 0x4A, 0x01, 0x70, 0x13, 0x68, -+0x23, 0xF0, 0x04, 0x03, 0xBD, 0xE8, 0x10, 0x40, 0x13, 0x60, 0x06, 0xF0, 0x45, 0xBD, 0x00, 0xBF, 0x94, 0x40, 0x04, 0x40, -+0xF0, 0xB5, 0x04, 0x68, 0x0E, 0x68, 0xA5, 0x1B, 0x32, 0xD4, 0x8E, 0x46, 0xAB, 0x42, 0x0C, 0xD2, 0xDE, 0xE9, 0x00, 0x76, -+0xDC, 0x19, 0xF6, 0x1B, 0xED, 0x1A, 0xAB, 0x42, 0x06, 0xEB, 0x04, 0x07, 0xA4, 0x46, 0x1C, 0x44, 0xF8, 0xD3, 0xCE, 0xE9, -+0x00, 0xC7, 0xB5, 0xEB, 0x53, 0x0F, 0x05, 0xD9, 0xDE, 0xE9, 0x00, 0x54, 0x1D, 0x44, 0x23, 0x44, 0xCE, 0xE9, 0x00, 0x53, -+0x43, 0x68, 0x4C, 0x68, 0x1D, 0x1B, 0x00, 0x2D, 0x09, 0xDB, 0xB2, 0xB1, 0x05, 0x68, 0x09, 0x68, 0x53, 0x60, 0x68, 0x1A, -+0x00, 0x28, 0x17, 0xDA, 0x58, 0x1B, 0x15, 0x60, 0xF0, 0xBD, 0xAA, 0xB1, 0x05, 0x68, 0x09, 0x68, 0x54, 0x60, 0x6B, 0x1A, -+0x00, 0x2B, 0xA8, 0xBF, 0x60, 0x1A, 0x18, 0xDB, 0x11, 0x60, 0xF0, 0xBD, 0x35, 0x1B, 0x86, 0x46, 0xCA, 0xE7, 0x00, 0x68, -+0x0A, 0x68, 0x81, 0x1A, 0x00, 0x29, 0x0C, 0xDA, 0x18, 0x1A, 0xF0, 0xBD, 0x58, 0x1A, 0xF1, 0xE7, 0x00, 0x68, 0x0B, 0x68, -+0xC1, 0x1A, 0x00, 0x29, 0xA8, 0xBF, 0xE0, 0x1A, 0xE0, 0xDA, 0x20, 0x1A, 0xF0, 0xBD, 0x98, 0x1A, 0xF0, 0xBD, 0x60, 0x1B, -+0xD9, 0xE7, 0x00, 0xBF, 0x70, 0xB5, 0x19, 0x4E, 0x90, 0xF8, 0xC1, 0x44, 0x8C, 0x23, 0x03, 0xFB, 0x04, 0x63, 0x05, 0x46, -+0x93, 0xF8, 0x20, 0x20, 0x0A, 0xB9, 0x1B, 0x7C, 0xFB, 0xB9, 0x8C, 0x23, 0x03, 0xFB, 0x04, 0x64, 0x94, 0xF8, 0x50, 0x20, -+0x12, 0xB9, 0x94, 0xF8, 0x40, 0x30, 0x7B, 0xB9, 0x0F, 0x4B, 0x9B, 0x68, 0x5B, 0xB1, 0x95, 0xF8, 0x63, 0x10, 0xFF, 0x20, -+0x93, 0xF8, 0x4E, 0x20, 0x8A, 0x42, 0x08, 0xBF, 0x83, 0xF8, 0x4E, 0x00, 0x1B, 0x68, 0x00, 0x2B, 0xF6, 0xD1, 0x70, 0xBD, -+0x08, 0x4B, 0x01, 0x21, 0xD3, 0xF8, 0x08, 0x32, 0x28, 0x46, 0x98, 0x47, 0xE8, 0xE7, 0x05, 0x4B, 0x11, 0x46, 0xD3, 0xF8, -+0x08, 0x32, 0x98, 0x47, 0xD9, 0xE7, 0x00, 0xBF, 0x48, 0x9E, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x4F, 0x48, 0x4B, 0x93, 0xF8, 0x5A, 0x30, 0x9B, 0xB0, 0x01, 0x2B, 0x08, 0x90, 0x40, 0xF2, 0x93, 0x81, -+0xDF, 0xF8, 0x20, 0x91, 0xD9, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xB7, 0x81, 0x08, 0x9C, -+0x40, 0x4B, 0x20, 0x46, 0xD3, 0xF8, 0x94, 0x30, 0x98, 0x47, 0x23, 0x6C, 0x94, 0xF8, 0x63, 0x20, 0xDA, 0x76, 0x94, 0xF8, -+0x62, 0x20, 0x00, 0x2A, 0x00, 0xF0, 0xB9, 0x81, 0x02, 0x2A, 0x08, 0xBF, 0x08, 0x9A, 0x39, 0x48, 0x0A, 0xBF, 0xB2, 0xF8, -+0xD2, 0x20, 0x4F, 0xF4, 0xC8, 0x32, 0x92, 0x02, 0x0A, 0x92, 0x1A, 0x7E, 0x02, 0x2A, 0x02, 0xF1, 0x01, 0x03, 0x00, 0xF0, -+0xB9, 0x81, 0xC3, 0xEB, 0xC3, 0x04, 0x00, 0xEB, 0x84, 0x04, 0xD9, 0x00, 0x24, 0x7E, 0xFF, 0x2C, 0x0D, 0xD1, 0x01, 0x2A, -+0x02, 0xF1, 0x02, 0x03, 0x08, 0xBF, 0x00, 0x23, 0xC3, 0xEB, 0xC3, 0x02, 0x00, 0xEB, 0x82, 0x02, 0xD9, 0x00, 0x12, 0x7E, -+0xFF, 0x2A, 0x00, 0xF0, 0x98, 0x82, 0x28, 0x4A, 0xCB, 0x1A, 0x00, 0xEB, 0x83, 0x03, 0x96, 0x68, 0x5B, 0x7E, 0x06, 0x93, -+0x00, 0x2E, 0x00, 0xF0, 0x4A, 0x81, 0x0A, 0x9B, 0x4F, 0xF0, 0x00, 0x0B, 0x5B, 0x00, 0x0B, 0x93, 0x5F, 0x46, 0x03, 0xE0, -+0x36, 0x68, 0x00, 0x2E, 0x00, 0xF0, 0x9A, 0x80, 0x33, 0x6C, 0x00, 0x2B, 0xF8, 0xD0, 0x08, 0x9A, 0x12, 0x6C, 0x93, 0x42, -+0xF4, 0xD0, 0x96, 0xF8, 0x62, 0x30, 0x00, 0x2B, 0x00, 0xF0, 0x93, 0x81, 0x02, 0x2B, 0x0A, 0xBF, 0xB6, 0xF8, 0xD2, 0x30, -+0x4F, 0xF4, 0xC8, 0x3B, 0x4F, 0xEA, 0x83, 0x2B, 0x0B, 0x9B, 0x5B, 0x45, 0x04, 0xD8, 0x0A, 0x9B, 0xBB, 0xFB, 0xF3, 0xF2, -+0xBB, 0xFB, 0xF2, 0xFB, 0x06, 0x9B, 0x4F, 0xEA, 0x5B, 0x00, 0xB0, 0xFB, 0xF3, 0xF5, 0x09, 0x95, 0xE5, 0xF7, 0x7C, 0xF8, -+0x43, 0xF2, 0xB0, 0x64, 0x20, 0x44, 0xA8, 0x42, 0x00, 0xF2, 0x18, 0x81, 0x00, 0x2F, 0x00, 0xF0, 0x1C, 0x81, 0x06, 0x9B, -+0x09, 0x9A, 0x03, 0xFB, 0x02, 0xF3, 0x07, 0x93, 0x10, 0xAC, 0x00, 0x25, 0x10, 0xE0, 0x00, 0xBF, 0x30, 0x9D, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x90, 0x9D, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x01, 0x35, 0xAF, 0x42, -+0x04, 0xF1, 0x14, 0x04, 0x00, 0xF0, 0x03, 0x81, 0x22, 0x68, 0x5A, 0x45, 0xF6, 0xD1, 0x72, 0x6A, 0x0C, 0x92, 0xD4, 0xE9, -+0x02, 0x01, 0x0D, 0xF1, 0x38, 0x0C, 0x0D, 0xF1, 0x30, 0x0A, 0x02, 0xF5, 0x1C, 0x5E, 0x8C, 0xE8, 0x03, 0x00, 0x0E, 0xF1, -+0x10, 0x0E, 0x52, 0x46, 0x61, 0x46, 0x50, 0x46, 0x5B, 0x46, 0xCD, 0xF8, 0x34, 0xE0, 0xFF, 0xF7, 0xB7, 0xFE, 0xD9, 0xF8, -+0x00, 0x20, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x80, 0x46, 0xC0, 0xF2, 0x2D, 0x81, 0x06, 0x9B, 0x5A, 0x1E, 0x07, 0x9B, -+0xB3, 0xFB, 0xF2, 0xF2, 0x05, 0x92, 0xE5, 0xF7, 0x31, 0xF8, 0x05, 0x9A, 0x61, 0x68, 0xA2, 0xF5, 0x7A, 0x62, 0x12, 0x1A, -+0x8A, 0x42, 0x38, 0xBF, 0x0A, 0x46, 0x42, 0x45, 0xC6, 0xD9, 0x05, 0x92, 0x05, 0xEB, 0x85, 0x05, 0xE5, 0xF7, 0x22, 0xF8, -+0x1A, 0xAB, 0x03, 0xEB, 0x85, 0x05, 0x96, 0xF8, 0x63, 0x10, 0x05, 0x9A, 0x55, 0xF8, 0x18, 0x3C, 0x36, 0x68, 0x01, 0x24, -+0x8C, 0x40, 0x02, 0x44, 0x9A, 0xE8, 0x03, 0x00, 0x23, 0x43, 0x02, 0xF5, 0x7A, 0x62, 0xA5, 0xF1, 0x20, 0x04, 0x84, 0xE8, -+0x03, 0x00, 0x45, 0xF8, 0x24, 0x2C, 0x45, 0xF8, 0x18, 0x3C, 0x00, 0x2E, 0x7F, 0xF4, 0x66, 0xAF, 0x00, 0x2F, 0x00, 0xF0, -+0xA2, 0x80, 0xDF, 0xF8, 0x88, 0xA3, 0xDD, 0xF8, 0x20, 0xB0, 0x05, 0x96, 0x09, 0x96, 0x0B, 0x96, 0x07, 0x96, 0x12, 0xAC, -+0x06, 0x97, 0x54, 0xF8, 0x08, 0x7C, 0x0A, 0x9B, 0xB7, 0xFB, 0xF3, 0xF2, 0x03, 0xFB, 0x12, 0x72, 0x00, 0x2A, 0x00, 0xF0, -+0x3A, 0x81, 0xE4, 0xF7, 0xED, 0xFF, 0x54, 0xE9, 0x01, 0x63, 0xA3, 0xF5, 0xBB, 0x53, 0x10, 0x3B, 0x1D, 0x1A, 0xE4, 0xF7, -+0xE5, 0xFF, 0xDA, 0xF8, 0x10, 0x30, 0x54, 0xF8, 0x08, 0x1C, 0xEB, 0x1A, 0x06, 0xF5, 0x7A, 0x66, 0x00, 0x2B, 0x06, 0xEB, -+0x00, 0x07, 0xC0, 0xF2, 0xEA, 0x80, 0xDA, 0xF8, 0x10, 0x20, 0x6B, 0x1A, 0x9A, 0x1A, 0x00, 0x2A, 0x80, 0xF2, 0xDB, 0x80, -+0xCD, 0xE9, 0x01, 0x75, 0xBE, 0x4B, 0x00, 0x91, 0xD3, 0xF8, 0x04, 0x32, 0xDF, 0xF8, 0x1C, 0x83, 0x1E, 0x46, 0x00, 0x22, -+0xFF, 0x23, 0x01, 0x21, 0x58, 0x46, 0xB0, 0x47, 0xEB, 0x19, 0xB9, 0x4E, 0x25, 0x60, 0x63, 0x60, 0x07, 0x46, 0x00, 0x25, -+0xA3, 0x68, 0xEB, 0x40, 0xDB, 0x07, 0x22, 0xD5, 0x72, 0x6A, 0x54, 0xF8, 0x08, 0x3C, 0x0E, 0x92, 0x02, 0xF5, 0x1C, 0x5C, -+0x0C, 0xF1, 0x10, 0x0C, 0x00, 0x22, 0x0E, 0xA9, 0x20, 0x46, 0xCD, 0xF8, 0x3C, 0xC0, 0xFF, 0xF7, 0x21, 0xFE, 0xD9, 0xF8, -+0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xC3, 0x80, 0x0E, 0x9A, 0x63, 0x68, 0x9B, 0xF8, 0x63, 0x10, -+0x86, 0xF8, 0x4E, 0x10, 0x9B, 0x1A, 0x00, 0x22, 0x73, 0x65, 0x86, 0xF8, 0x4F, 0x70, 0xA6, 0xF8, 0x58, 0x20, 0x01, 0x35, -+0x04, 0x2D, 0x06, 0xF5, 0xA4, 0x66, 0xD3, 0xD1, 0x05, 0x9B, 0x06, 0x9A, 0x01, 0x33, 0x9A, 0x42, 0x05, 0x93, 0x04, 0xF1, -+0x14, 0x04, 0x90, 0xD1, 0x07, 0x9B, 0x33, 0xB3, 0x0B, 0x9B, 0x0A, 0x99, 0x03, 0xF5, 0x9C, 0x50, 0x09, 0x9B, 0x08, 0x30, -+0x83, 0x42, 0xA8, 0xBF, 0x03, 0x46, 0x18, 0x46, 0x01, 0xEB, 0xD1, 0x73, 0xB0, 0xEB, 0x63, 0x0F, 0x4F, 0xEA, 0x63, 0x02, -+0x00, 0xF3, 0x18, 0x81, 0x52, 0x42, 0x82, 0x42, 0xC4, 0xBF, 0x0A, 0x9B, 0xC0, 0x18, 0x8F, 0x4B, 0xD3, 0xF8, 0x6C, 0x31, -+0x98, 0x47, 0x08, 0x9C, 0x8E, 0x4A, 0x94, 0xF8, 0x4D, 0x30, 0x20, 0x65, 0x43, 0xF0, 0x20, 0x03, 0x01, 0x21, 0x84, 0xF8, -+0x4D, 0x30, 0x82, 0xF8, 0x31, 0x10, 0x1B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xE4, 0xF7, 0x5C, 0xFF, 0x03, 0x19, 0x09, 0x93, -+0x00, 0x2F, 0x7F, 0xF4, 0xE4, 0xAE, 0xD9, 0xF8, 0x00, 0x20, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x7B, 0xDB, 0x1A, 0xAB, -+0x07, 0xEB, 0x87, 0x02, 0x70, 0x6A, 0x03, 0xEB, 0x82, 0x02, 0x09, 0x9B, 0x42, 0xF8, 0x28, 0xBC, 0x00, 0xF5, 0x1C, 0x51, -+0x42, 0xE9, 0x09, 0x30, 0x10, 0x31, 0x42, 0xF8, 0x1C, 0x1C, 0xBC, 0x00, 0x96, 0xF8, 0x63, 0x20, 0x3C, 0x44, 0x1A, 0xAB, -+0x03, 0xEB, 0x84, 0x04, 0x01, 0x23, 0x93, 0x40, 0x01, 0x37, 0x44, 0xF8, 0x18, 0x3C, 0x8F, 0xE6, 0x03, 0x6C, 0xDB, 0x7E, -+0xFF, 0x2B, 0x3F, 0xF4, 0x44, 0xAE, 0x90, 0xF8, 0x63, 0x20, 0x9A, 0x42, 0x3F, 0xF4, 0x3F, 0xAE, 0x6E, 0x49, 0x6F, 0x48, -+0x40, 0xF2, 0xA7, 0x22, 0x08, 0xF0, 0x8E, 0xFB, 0x37, 0xE6, 0x08, 0x9A, 0x6C, 0x49, 0x92, 0xF8, 0x6C, 0x20, 0x4F, 0xF4, -+0x1E, 0x70, 0x00, 0xFB, 0x02, 0x12, 0x6A, 0x48, 0x92, 0x68, 0x0A, 0x92, 0x1A, 0x7E, 0x02, 0x2A, 0x02, 0xF1, 0x01, 0x03, -+0x7F, 0xF4, 0x47, 0xAE, 0x03, 0x7E, 0xFF, 0x2B, 0x40, 0xF0, 0xEE, 0x80, 0x01, 0x23, 0x4D, 0xE6, 0x06, 0x9B, 0x01, 0x2B, -+0x3F, 0xF6, 0xCF, 0xAE, 0x5D, 0x49, 0x61, 0x48, 0x40, 0xF2, 0xD3, 0x22, 0x08, 0xF0, 0x6C, 0xFB, 0xC7, 0xE6, 0x5C, 0x4A, -+0x96, 0xF8, 0x6C, 0x30, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x03, 0x23, 0xD3, 0xF8, 0x08, 0xB0, 0x6A, 0xE6, 0xDA, 0xF8, -+0x10, 0x20, 0x1D, 0x46, 0x5B, 0x1A, 0x9A, 0x1A, 0x00, 0x2A, 0xF8, 0xDA, 0x1C, 0xE7, 0xDA, 0xF8, 0x10, 0x30, 0x0D, 0x44, -+0xEB, 0x1A, 0x00, 0x2B, 0xBF, 0xF6, 0x16, 0xAF, 0xDA, 0xF8, 0x10, 0x30, 0x0D, 0x44, 0xEB, 0x1A, 0x00, 0x2B, 0xF2, 0xDB, -+0x0E, 0xE7, 0x96, 0xF8, 0x4E, 0x30, 0xFF, 0x2B, 0x3F, 0xF4, 0x38, 0xAF, 0x47, 0x49, 0x4F, 0xF4, 0x58, 0x72, 0x40, 0x46, -+0x08, 0xF0, 0x40, 0xFB, 0x30, 0xE7, 0x02, 0x2F, 0x00, 0xF0, 0x98, 0x80, 0x1A, 0xAB, 0x07, 0xEB, 0x87, 0x02, 0x70, 0x6A, -+0x03, 0xEB, 0x82, 0x02, 0x09, 0x9B, 0x42, 0xF8, 0x28, 0xBC, 0x00, 0xF5, 0x1C, 0x51, 0x42, 0xE9, 0x09, 0x30, 0x10, 0x31, -+0x42, 0xF8, 0x1C, 0x1C, 0xBC, 0x00, 0x96, 0xF8, 0x63, 0x20, 0x1F, 0x2A, 0x7F, 0xF6, 0x7E, 0xAF, 0x37, 0x49, 0x3C, 0x48, -+0x40, 0xF2, 0xED, 0x22, 0x08, 0xF0, 0x20, 0xFB, 0x74, 0xE7, 0x3A, 0x4B, 0xDA, 0xF8, 0x10, 0x00, 0x19, 0x68, 0x0A, 0x9B, -+0x00, 0xEB, 0x41, 0x10, 0x9F, 0x42, 0x28, 0xBF, 0x1F, 0x46, 0x00, 0xF5, 0x1C, 0x55, 0x10, 0x35, 0x3B, 0x46, 0x0E, 0xA9, -+0x0E, 0x90, 0x20, 0x46, 0x0F, 0x95, 0xFF, 0xF7, 0x17, 0xFD, 0x0E, 0x9E, 0x23, 0x68, 0x54, 0xF8, 0x04, 0x5C, 0x9A, 0x1B, -+0x00, 0x2A, 0x1D, 0x44, 0x62, 0x68, 0xA5, 0xF5, 0xFA, 0x65, 0xB4, 0xBF, 0xB6, 0x1A, 0x3E, 0x1A, 0xAD, 0x1A, 0xE4, 0xF7, -+0x91, 0xFE, 0x00, 0xF5, 0x7A, 0x60, 0xA8, 0x42, 0x34, 0xDC, 0x54, 0xE9, 0x02, 0x78, 0xE4, 0xF7, 0x89, 0xFE, 0xA7, 0xF5, -+0x5A, 0x53, 0x30, 0x3B, 0xA3, 0xEB, 0x08, 0x03, 0x07, 0x9A, 0xAD, 0x1B, 0x1B, 0x1A, 0x2B, 0x44, 0xDA, 0xB1, 0x09, 0x9A, -+0xAA, 0x42, 0x1F, 0xDB, 0x0B, 0x9A, 0x9A, 0x42, 0x0A, 0xDD, 0x0A, 0x9A, 0x13, 0x44, 0x15, 0x44, 0x09, 0x9A, 0xAA, 0x42, -+0xFF, 0xF6, 0x83, 0xAE, 0x0B, 0x9A, 0x9A, 0x42, 0x3F, 0xF7, 0x7F, 0xAE, 0x0B, 0x9A, 0xAA, 0x42, 0xB8, 0xBF, 0x2A, 0x46, -+0x0B, 0x92, 0x09, 0x9A, 0x9A, 0x42, 0xA8, 0xBF, 0x1A, 0x46, 0x09, 0x92, 0x73, 0xE6, 0x09, 0x93, 0x01, 0x23, 0x0B, 0x95, -+0x07, 0x93, 0x6E, 0xE6, 0x40, 0x1A, 0xEA, 0xE6, 0x0A, 0x9A, 0xAD, 0x1A, 0x9B, 0x1A, 0xE1, 0xE7, 0xE4, 0xF7, 0x56, 0xFE, -+0x00, 0xF5, 0x7A, 0x65, 0xC5, 0xE7, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x48, 0xA0, 0x15, 0x00, 0x68, 0x65, 0x17, 0x00, 0x90, 0x9D, 0x17, 0x00, 0xD0, 0xA0, 0x15, 0x00, -+0x00, 0xA1, 0x15, 0x00, 0x40, 0x80, 0x32, 0x40, 0x00, 0x10, 0x50, 0x40, 0x10, 0xA1, 0x15, 0x00, 0x40, 0xF2, 0xE7, 0x22, -+0x14, 0x49, 0x15, 0x48, 0x08, 0xF0, 0x9E, 0xFA, 0xD9, 0xF8, 0x00, 0x20, 0x09, 0x9B, 0xB2, 0xF9, 0x00, 0x20, 0xCD, 0xF8, -+0x68, 0xB0, 0x1B, 0x93, 0x73, 0x6A, 0x1C, 0x93, 0x03, 0xF5, 0x1C, 0x53, 0x10, 0x33, 0x00, 0x2A, 0x1D, 0x93, 0x4F, 0xF0, -+0x08, 0x04, 0xFF, 0xF6, 0x60, 0xAF, 0xDF, 0xE6, 0x00, 0x23, 0x19, 0x46, 0x67, 0xE5, 0xD9, 0xF8, 0x00, 0x30, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x05, 0xDA, 0x04, 0x49, 0x05, 0x48, 0x40, 0xF2, 0xAE, 0x22, 0x08, 0xF0, 0x7B, 0xFA, 0x00, 0x23, -+0x5B, 0x7E, 0xFF, 0xDE, 0x70, 0x79, 0x15, 0x00, 0xE4, 0xA0, 0x15, 0x00, 0xC4, 0xA0, 0x15, 0x00, 0x0A, 0x4B, 0x03, 0xF1, -+0x54, 0x01, 0x1A, 0x7E, 0xFF, 0x2A, 0x02, 0xD0, 0xDA, 0x7E, 0xFF, 0x2A, 0x04, 0xD1, 0x1C, 0x33, 0x8B, 0x42, 0xF6, 0xD1, -+0x00, 0x20, 0x70, 0x47, 0x04, 0x4B, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x02, 0x32, 0x02, 0x60, 0x01, 0x20, 0x70, 0x47, -+0x90, 0x9D, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x0E, 0x46, 0x85, 0xB0, 0x14, 0x46, 0x05, 0x46, -+0x00, 0x28, 0x54, 0xD0, 0x07, 0x46, 0x00, 0x2C, 0x3A, 0xD0, 0xA3, 0x7A, 0xFF, 0x2B, 0x37, 0xD0, 0x3D, 0x4A, 0x23, 0x7A, -+0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, 0x62, 0x20, 0x00, 0x2A, 0x5E, 0xD0, 0x02, 0x2A, 0x52, 0xD0, -+0x4F, 0xF4, 0x48, 0x4A, 0x4F, 0xF4, 0xC8, 0x39, 0x60, 0x68, 0xDF, 0xF8, 0xE0, 0x80, 0x00, 0xF5, 0x1C, 0x5B, 0xE4, 0xF7, -+0xC9, 0xFD, 0x0B, 0xF1, 0x10, 0x0B, 0x03, 0x46, 0xE1, 0x7A, 0xD8, 0xF8, 0xFC, 0x21, 0x28, 0x46, 0x9B, 0x44, 0x90, 0x47, -+0x83, 0x1B, 0x13, 0xEB, 0x0A, 0x0F, 0x05, 0xD5, 0xAA, 0xEB, 0x06, 0x03, 0x48, 0x44, 0xC3, 0x42, 0xFC, 0xD4, 0x83, 0x1B, -+0x00, 0x2B, 0x0B, 0xF5, 0x0C, 0x53, 0xB8, 0xBF, 0x00, 0xF1, 0xFF, 0x36, 0x28, 0x33, 0x9B, 0x1B, 0x00, 0x2B, 0x31, 0xDB, -+0x0B, 0xF5, 0x7A, 0x60, 0x80, 0x1B, 0x06, 0xE0, 0xE4, 0xF7, 0xA6, 0xFD, 0xDF, 0xF8, 0x8C, 0x80, 0x00, 0xF5, 0x5A, 0x50, -+0x30, 0x30, 0x00, 0x22, 0x01, 0x23, 0xCD, 0xE9, 0x01, 0x06, 0xD8, 0xF8, 0x04, 0x42, 0x00, 0x92, 0x38, 0x46, 0x19, 0x46, -+0xA0, 0x47, 0xFF, 0x38, 0x18, 0xBF, 0x01, 0x20, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x17, 0x4B, 0x03, 0xF1, 0x54, 0x01, -+0x1A, 0x7E, 0xFF, 0x2A, 0x02, 0xD0, 0xDF, 0x7E, 0xFF, 0x2F, 0x1C, 0xD1, 0x1C, 0x33, 0x99, 0x42, 0xF6, 0xD1, 0x00, 0x20, -+0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xB3, 0xF8, 0xD2, 0x30, 0x4F, 0xEA, 0x83, 0x29, 0x4F, 0xEA, 0x43, 0x2A, 0xA9, 0xE7, -+0x41, 0xF2, 0x88, 0x30, 0xD5, 0xE7, 0x93, 0xF8, 0x6C, 0x30, 0x0A, 0x4A, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x03, 0x23, -+0xD3, 0xF8, 0x08, 0x90, 0x4F, 0xEA, 0x59, 0x0A, 0x9A, 0xE7, 0x03, 0x4B, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x07, 0x37, -+0x7F, 0xE7, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, 0x90, 0x9D, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x70, 0xB5, 0x0C, 0x46, 0x02, 0x7A, 0x17, 0x49, 0x23, 0x7A, 0x4F, 0xF4, 0xA4, 0x65, 0x05, 0xFB, 0x02, 0x12, 0x05, 0xFB, -+0x03, 0x13, 0x12, 0x6C, 0x1B, 0x6C, 0x9A, 0x42, 0x0D, 0xD0, 0x45, 0x68, 0xE4, 0xF7, 0x4A, 0xFD, 0x64, 0x68, 0x06, 0x46, -+0xE4, 0xF7, 0x46, 0xFD, 0x2A, 0x1B, 0x06, 0xD4, 0x63, 0x1B, 0x00, 0x2B, 0x0C, 0xDB, 0xA5, 0x42, 0x08, 0xD0, 0x00, 0x20, -+0x70, 0xBD, 0xA4, 0xF5, 0x5A, 0x53, 0x30, 0x3B, 0x5B, 0x1B, 0x9E, 0x1B, 0x00, 0x2E, 0xF1, 0xDA, 0x01, 0x20, 0x70, 0xBD, -+0xA2, 0xF5, 0x5A, 0x53, 0x30, 0x3B, 0x1B, 0x1A, 0x00, 0x2B, 0xF7, 0xDB, 0xA5, 0x42, 0xEC, 0xD1, 0xF4, 0xE7, 0x00, 0xBF, -+0x18, 0x88, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x07, 0x46, 0x83, 0xB0, 0x0D, 0x46, 0x00, 0xF1, 0x44, 0x08, 0x91, 0x46, -+0x22, 0xB9, 0x90, 0xF8, 0x4D, 0x30, 0xDB, 0x07, 0x00, 0xF1, 0xA3, 0x80, 0xDF, 0xF8, 0x64, 0xA1, 0xD7, 0xF8, 0x40, 0xB0, -+0xDA, 0xF8, 0x20, 0x30, 0x00, 0x2B, 0x79, 0xD1, 0xDA, 0xF8, 0x50, 0x30, 0x0B, 0xB1, 0x9B, 0x45, 0x2E, 0xD1, 0xBD, 0x64, -+0xE4, 0xF7, 0x0A, 0xFD, 0x05, 0xF5, 0x5A, 0x53, 0xDA, 0xF8, 0x10, 0x40, 0x2F, 0x33, 0x1E, 0x18, 0x00, 0x2C, 0x00, 0xF0, -+0x88, 0x80, 0xDF, 0xF8, 0x38, 0xA1, 0x0B, 0xE0, 0xDA, 0xF8, 0xA0, 0x30, 0x98, 0x47, 0xD3, 0x46, 0x40, 0xBB, 0x63, 0x68, -+0xEB, 0x1A, 0x00, 0x2B, 0x08, 0xDB, 0x24, 0x68, 0x00, 0x2C, 0x78, 0xD0, 0x63, 0x68, 0xF3, 0x1A, 0x00, 0x2B, 0x21, 0x46, -+0x40, 0x46, 0xED, 0xDA, 0x3F, 0x48, 0x42, 0x46, 0x21, 0x46, 0x06, 0xF0, 0xD9, 0xFD, 0x97, 0xF8, 0x4D, 0x30, 0x43, 0xF0, -+0x01, 0x03, 0x87, 0xF8, 0x4D, 0x30, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xDA, 0xF8, 0x54, 0x60, 0xE4, 0xF7, 0xDA, 0xFC, -+0xAE, 0x1B, 0xA6, 0xF5, 0x7A, 0x66, 0x30, 0x1A, 0xC4, 0x0F, 0x00, 0x2C, 0xC5, 0xD0, 0xDF, 0xF8, 0xDC, 0xB0, 0x00, 0x24, -+0x97, 0xF8, 0xC0, 0x34, 0x4B, 0xB1, 0x31, 0x4A, 0x97, 0xF8, 0xC1, 0x34, 0x8C, 0x21, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, -+0x70, 0x30, 0x01, 0x2B, 0x1D, 0xD0, 0x97, 0xF8, 0x62, 0x30, 0xDB, 0xF8, 0x2C, 0x40, 0x7B, 0xB1, 0x02, 0x2B, 0x0A, 0xBF, -+0xB7, 0xF8, 0xD2, 0x10, 0x4F, 0xF4, 0xC8, 0x31, 0x89, 0x02, 0x09, 0xF1, 0x01, 0x02, 0x29, 0x44, 0x38, 0x46, 0x23, 0x46, -+0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x18, 0x47, 0x22, 0x4A, 0x97, 0xF8, 0x6C, 0x30, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, -+0x03, 0x23, 0x99, 0x68, 0xED, 0xE7, 0xDB, 0xF8, 0x90, 0x30, 0x22, 0x46, 0x29, 0x46, 0x38, 0x46, 0x98, 0x47, 0x97, 0xF8, -+0x62, 0x30, 0xDB, 0xF8, 0x2C, 0x40, 0x00, 0x2B, 0xDA, 0xD1, 0xE9, 0xE7, 0xDA, 0xF8, 0x24, 0x20, 0x01, 0x92, 0x56, 0x68, -+0xE4, 0xF7, 0x92, 0xFC, 0x01, 0x9A, 0x93, 0x68, 0x06, 0xF5, 0x7A, 0x66, 0x9B, 0x45, 0x06, 0xEB, 0x00, 0x04, 0x0A, 0xD0, -+0xE4, 0xF7, 0x88, 0xFC, 0x01, 0x9A, 0xD3, 0x68, 0x04, 0xF5, 0x7A, 0x64, 0x04, 0x44, 0x13, 0xB1, 0x04, 0xF5, 0x1C, 0x54, -+0x10, 0x34, 0x2C, 0x1B, 0xE4, 0x0F, 0x00, 0x2C, 0x3F, 0xF4, 0x6D, 0xAF, 0xA5, 0xE7, 0x00, 0x24, 0x8A, 0xE7, 0x05, 0x48, -+0x41, 0x46, 0x06, 0xF0, 0xD9, 0xFC, 0x97, 0xF8, 0x4D, 0x30, 0x23, 0xF0, 0x01, 0x03, 0x87, 0xF8, 0x4D, 0x30, 0x51, 0xE7, -+0x40, 0x9D, 0x17, 0x00, 0x48, 0x9E, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x47, 0x81, 0x46, 0x1A, 0x48, 0x88, 0x46, 0x17, 0x46, 0x06, 0xF0, 0xB4, 0xFC, 0x18, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0x46, 0x0C, 0xDB, 0x16, 0x4D, 0x28, 0x46, 0x21, 0x46, 0x50, 0xF8, 0x20, 0x6F, -+0xE7, 0x60, 0xC4, 0xE9, 0x01, 0x98, 0x06, 0xF0, 0x5F, 0xFC, 0x4E, 0xB1, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0x28, 0xF0, 0xD1, -+0x0F, 0x49, 0x10, 0x48, 0xD6, 0x22, 0x08, 0xF0, 0xA9, 0xF8, 0xEA, 0xE7, 0x0E, 0x4B, 0x61, 0x68, 0x1B, 0x69, 0xAC, 0x64, -+0xCB, 0x1A, 0x14, 0x2B, 0x07, 0xD4, 0x0C, 0x4B, 0x05, 0xF1, 0x40, 0x00, 0xD3, 0xF8, 0xE0, 0x31, 0xBD, 0xE8, 0xF0, 0x47, -+0x18, 0x47, 0x6B, 0x6C, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x18, 0x47, 0x48, 0x9D, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x30, 0x9D, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x48, 0xA1, 0x15, 0x00, 0x00, 0x10, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x4F, 0xC1, 0x4B, 0xDF, 0xF8, 0x0C, 0x83, 0x1D, 0x69, 0xD0, 0xF8, 0x40, 0x90, 0x2F, 0x7A, 0x6B, 0x68, -+0x89, 0xB0, 0x4F, 0xF4, 0xA4, 0x6A, 0xA3, 0xF5, 0x7A, 0x63, 0x0A, 0xFB, 0x07, 0x8B, 0x0C, 0x46, 0x03, 0x92, 0x01, 0x93, -+0x06, 0x46, 0xE4, 0xF7, 0x05, 0xFC, 0x01, 0x9B, 0xDB, 0xF8, 0x40, 0x20, 0x1B, 0x1B, 0x1B, 0x1A, 0x4A, 0x45, 0x01, 0x93, -+0x66, 0xD0, 0x6B, 0x68, 0x02, 0x93, 0xE4, 0xF7, 0xF9, 0xFB, 0x02, 0x9B, 0x99, 0xF8, 0x1B, 0x20, 0x04, 0x90, 0xA3, 0xF5, -+0x7A, 0x63, 0x19, 0x1A, 0xFF, 0x2A, 0x02, 0x91, 0x20, 0xD1, 0x96, 0xF8, 0x4E, 0x60, 0x05, 0x93, 0xFF, 0x2E, 0x40, 0xF0, -+0x8F, 0x80, 0x01, 0x9B, 0x03, 0x9A, 0x18, 0x46, 0x10, 0x44, 0xB2, 0xEB, 0x50, 0x0F, 0x4F, 0xEA, 0x50, 0x03, 0x00, 0xF2, -+0xA9, 0x80, 0x03, 0x9A, 0xA4, 0x4E, 0xA4, 0x1A, 0x1C, 0x44, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x07, 0x87, 0x2A, 0x46, -+0xD6, 0xF8, 0x88, 0x30, 0x39, 0x6C, 0x20, 0x46, 0x98, 0x47, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x0A, 0xFB, 0x02, 0x8A, -+0x50, 0x46, 0x07, 0xAA, 0x06, 0xA9, 0xDB, 0xF8, 0x40, 0x90, 0x01, 0x93, 0x03, 0xF0, 0xE8, 0xFB, 0x83, 0x46, 0x00, 0x28, -+0x00, 0xF0, 0x8C, 0x80, 0x07, 0x9C, 0x02, 0x99, 0x01, 0x9B, 0x0A, 0x1B, 0x00, 0x2A, 0xC0, 0xF2, 0x41, 0x81, 0x06, 0x9A, -+0xD1, 0x1A, 0x04, 0x9B, 0xD9, 0x42, 0x7D, 0xD5, 0x14, 0x1B, 0xE4, 0xF7, 0xB1, 0xFB, 0x00, 0xF5, 0x0C, 0x50, 0x28, 0x30, -+0x84, 0x42, 0x40, 0xF2, 0x3B, 0x81, 0x8B, 0x4E, 0x07, 0x98, 0xD6, 0xF8, 0x88, 0x30, 0x49, 0x46, 0x00, 0x22, 0x98, 0x47, -+0x06, 0x9C, 0xD6, 0xF8, 0x88, 0x90, 0xE4, 0xF7, 0x9F, 0xFB, 0xA4, 0xF5, 0x7A, 0x64, 0x20, 0x1A, 0xDA, 0xF8, 0x40, 0x10, -+0x02, 0x9C, 0x00, 0x22, 0xC8, 0x47, 0xBA, 0xE7, 0xE4, 0xF7, 0x94, 0xFB, 0x01, 0x9B, 0xA3, 0xF5, 0x7A, 0x62, 0x12, 0x1A, -+0x41, 0xF2, 0x87, 0x33, 0x9A, 0x42, 0x01, 0x92, 0xB9, 0xDD, 0x6F, 0x68, 0xE4, 0xF7, 0x88, 0xFB, 0x99, 0xF8, 0x1B, 0xB0, -+0x02, 0x97, 0x3B, 0x1A, 0xBB, 0xF1, 0xFF, 0x0F, 0x01, 0x9A, 0x04, 0x90, 0xA3, 0xF5, 0x7A, 0x67, 0x70, 0xD0, 0x0A, 0xFB, -+0x0B, 0x80, 0x07, 0xAA, 0x06, 0xA9, 0x03, 0xF0, 0x9B, 0xFB, 0x00, 0x28, 0x40, 0xF0, 0xE6, 0x80, 0xE4, 0xF7, 0x72, 0xFB, -+0x06, 0x9E, 0xC6, 0xF5, 0x9C, 0x52, 0x08, 0x32, 0x00, 0xF5, 0x7A, 0x60, 0x22, 0x44, 0x12, 0xEB, 0x40, 0x03, 0x00, 0xF1, -+0xF9, 0x80, 0xE4, 0xF7, 0x65, 0xFB, 0x07, 0x9C, 0x04, 0xF5, 0x0C, 0x53, 0x28, 0x33, 0xDB, 0x1B, 0xC3, 0x42, 0x8C, 0xD5, -+0x64, 0x4E, 0xDF, 0xF8, 0x98, 0xA1, 0x5F, 0xE0, 0x07, 0xAA, 0x0A, 0xFB, 0x06, 0x80, 0x06, 0xA9, 0x03, 0xF0, 0x78, 0xFB, -+0x83, 0x46, 0xE4, 0xF7, 0x51, 0xFB, 0x06, 0x9A, 0xA2, 0xF5, 0x7A, 0x62, 0x10, 0x1A, 0xDD, 0xE9, 0x04, 0x23, 0x06, 0x90, -+0xA2, 0xEB, 0x03, 0x0A, 0xBB, 0xF1, 0x00, 0x0F, 0x05, 0xD1, 0x02, 0x9B, 0x10, 0xEB, 0x0A, 0x0F, 0x54, 0xBF, 0x1C, 0x46, -+0x04, 0x46, 0xE4, 0xF7, 0x3D, 0xFB, 0x07, 0x9B, 0x03, 0xF5, 0x0C, 0x53, 0x28, 0x33, 0x53, 0x44, 0xC3, 0x42, 0x65, 0xD4, -+0x50, 0x4E, 0x58, 0xE7, 0x06, 0x9E, 0x02, 0x9B, 0x9A, 0x1B, 0x00, 0x2A, 0xF8, 0xDB, 0xE4, 0xF7, 0x2D, 0xFB, 0x00, 0xF5, -+0x0C, 0x50, 0x36, 0x1B, 0x28, 0x30, 0x86, 0x42, 0x49, 0x4E, 0x11, 0xD9, 0x49, 0x46, 0x20, 0x46, 0x5A, 0x46, 0xD6, 0xF8, -+0x88, 0x30, 0x98, 0x47, 0x06, 0x9C, 0xD6, 0xF8, 0x88, 0x90, 0xE4, 0xF7, 0x1B, 0xFB, 0xA4, 0xF5, 0x7A, 0x64, 0xDA, 0xF8, -+0x40, 0x10, 0x20, 0x1A, 0x5A, 0x46, 0xC8, 0x47, 0x07, 0x9C, 0x02, 0x9B, 0x1B, 0x1B, 0x00, 0x2B, 0xBF, 0xF6, 0x33, 0xAF, -+0x02, 0x9C, 0x30, 0xE7, 0x96, 0xF8, 0x4E, 0x00, 0x01, 0x93, 0xFF, 0x28, 0x51, 0xD1, 0x03, 0x99, 0x0A, 0x44, 0xB1, 0xEB, -+0x52, 0x0F, 0x4F, 0xEA, 0x52, 0x03, 0xA1, 0xD8, 0x03, 0x9A, 0x35, 0x4E, 0xDF, 0xF8, 0xD8, 0xA0, 0xA4, 0x1A, 0x1C, 0x44, -+0x99, 0xF8, 0x18, 0x30, 0xD6, 0xF8, 0x88, 0x80, 0x02, 0x2B, 0x03, 0xF1, 0x01, 0x01, 0x7B, 0xD0, 0xC1, 0xEB, 0xC1, 0x01, -+0x0A, 0xEB, 0x81, 0x01, 0x0A, 0x7E, 0xFF, 0x2A, 0x0E, 0xD1, 0x01, 0x2B, 0x03, 0xF1, 0x02, 0x03, 0x08, 0xBF, 0x00, 0x23, -+0xC3, 0xEB, 0xC3, 0x03, 0x0A, 0xEB, 0x83, 0x0A, 0x9A, 0xF8, 0x18, 0x30, 0xFF, 0x2B, 0x14, 0xBF, 0x51, 0x46, 0x00, 0x21, -+0x20, 0x46, 0x00, 0x22, 0xC0, 0x47, 0xD6, 0xF8, 0x88, 0x30, 0x2A, 0x46, 0x49, 0x46, 0x38, 0x46, 0x98, 0x47, 0x09, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x06, 0x83, 0x1B, 0x4E, 0x19, 0x6C, 0xD6, 0xF8, 0x88, 0x30, -+0x20, 0x46, 0x00, 0x22, 0x98, 0x47, 0xD6, 0xF8, 0x88, 0x30, 0x07, 0x98, 0x49, 0x46, 0x00, 0x22, 0x98, 0x47, 0xBB, 0xF1, -+0x00, 0x0F, 0xAD, 0xD0, 0x06, 0x9C, 0x02, 0x9B, 0x1A, 0xEB, 0x04, 0x0F, 0x58, 0xBF, 0x1C, 0x46, 0xD9, 0xE6, 0x07, 0xAA, -+0x06, 0xA9, 0x0A, 0xFB, 0x00, 0x80, 0x03, 0xF0, 0xD3, 0xFA, 0x06, 0x9C, 0xE4, 0xF7, 0xAC, 0xFA, 0x01, 0x9B, 0x1B, 0x1B, -+0xC3, 0x42, 0x3F, 0xF5, 0xD6, 0xAE, 0x06, 0x9C, 0x08, 0x4E, 0xDF, 0xF8, 0x28, 0xA0, 0xE4, 0xF7, 0xA1, 0xFA, 0x07, 0x9B, -+0xA4, 0xF5, 0x7A, 0x64, 0xFA, 0x1A, 0x24, 0x1A, 0x17, 0xEA, 0x22, 0x07, 0x38, 0xBF, 0x1F, 0x46, 0x9C, 0xE7, 0x00, 0xBF, -+0x30, 0x9D, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x90, 0x9D, 0x17, 0x00, 0xDD, 0xE9, 0x06, 0x64, -+0xE4, 0xF7, 0x8A, 0xFA, 0x02, 0x9B, 0x04, 0x9A, 0xF6, 0x1A, 0x32, 0x44, 0x13, 0x1A, 0x00, 0x2B, 0x5B, 0xDB, 0xE4, 0xF7, -+0x81, 0xFA, 0x3B, 0x1B, 0xA3, 0xF5, 0x0C, 0x53, 0x28, 0x3B, 0x18, 0x1A, 0x00, 0x28, 0xBF, 0xF6, 0x1B, 0xAF, 0xA6, 0xE6, -+0x37, 0x4E, 0x67, 0xE7, 0x9A, 0xF8, 0x18, 0x30, 0xFF, 0x2B, 0x5F, 0xD1, 0x01, 0x23, 0x89, 0xE7, 0x02, 0x9C, 0x37, 0xE7, -+0xE4, 0xF7, 0x6C, 0xFA, 0x02, 0x9B, 0xF6, 0x1A, 0x04, 0x9B, 0x33, 0x44, 0x1B, 0x1A, 0x00, 0x2B, 0x4A, 0xDB, 0x01, 0x97, -+0xE4, 0xF7, 0x62, 0xFA, 0x07, 0x9B, 0x03, 0xF5, 0x0C, 0x53, 0x28, 0x33, 0xDB, 0x1B, 0xC3, 0x42, 0x4A, 0xD5, 0x4F, 0xF4, -+0xA4, 0x63, 0x03, 0xFB, 0x0B, 0x83, 0x27, 0x4E, 0x1A, 0x6C, 0xDF, 0xF8, 0x9C, 0xA0, 0x11, 0x7E, 0xD6, 0xF8, 0x88, 0x30, -+0x02, 0x29, 0x01, 0xF1, 0x01, 0x02, 0x2B, 0xD0, 0xC2, 0xEB, 0xC2, 0x00, 0x0A, 0xEB, 0x80, 0x00, 0x00, 0x7E, 0xFF, 0x28, -+0x37, 0xD1, 0x01, 0x29, 0x01, 0xF1, 0x02, 0x02, 0x08, 0xBF, 0x00, 0x22, 0xC2, 0xEB, 0xC2, 0x01, 0x0A, 0xEB, 0x81, 0x01, -+0x09, 0x7E, 0xFF, 0x29, 0x08, 0xBF, 0x00, 0x21, 0x29, 0xD1, 0x20, 0x46, 0x00, 0x22, 0x98, 0x47, 0x4F, 0xF4, 0xA4, 0x63, -+0x03, 0xFB, 0x0B, 0x88, 0x01, 0x98, 0xD8, 0xF8, 0x40, 0x10, 0xD6, 0xF8, 0x88, 0x30, 0x00, 0x22, 0x98, 0x47, 0x07, 0x9C, -+0x2C, 0xE7, 0x06, 0x9E, 0xE4, 0xF7, 0x24, 0xFA, 0xA6, 0xF5, 0x7A, 0x66, 0x37, 0x1A, 0x9C, 0xE7, 0x9A, 0xF8, 0x18, 0x20, -+0xFF, 0x2A, 0x0D, 0xD1, 0x01, 0x22, 0xD9, 0xE7, 0x06, 0x9E, 0xE4, 0xF7, 0x17, 0xFA, 0xA6, 0xF5, 0x7A, 0x66, 0x33, 0x1A, -+0x01, 0x93, 0xAD, 0xE7, 0x05, 0x49, 0x33, 0xE7, 0x01, 0x9F, 0xAF, 0xE6, 0x00, 0x22, 0x1C, 0x21, 0x01, 0xFB, 0x02, 0xA1, -+0xD1, 0xE7, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x90, 0x9D, 0x17, 0x00, 0x30, 0xB5, 0x0E, 0x48, 0x83, 0xB0, 0x06, 0xF0, -+0x59, 0xFA, 0x01, 0x90, 0xA0, 0xB1, 0x0C, 0x4B, 0x0C, 0x4C, 0xD3, 0xF8, 0xD8, 0x31, 0x0C, 0x48, 0x98, 0x47, 0x00, 0x23, -+0x01, 0x99, 0xA3, 0x64, 0x04, 0xF1, 0x18, 0x05, 0x20, 0x34, 0x28, 0x46, 0x06, 0xF0, 0x04, 0xFA, 0x20, 0x46, 0x06, 0xF0, -+0x45, 0xFA, 0x01, 0x46, 0x00, 0x28, 0xF6, 0xD1, 0x03, 0xB0, 0x30, 0xBD, 0x50, 0x9D, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x30, 0x9D, 0x17, 0x00, 0x70, 0x9D, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x4C, 0x4B, 0x42, 0x69, 0x1F, 0x69, 0x4C, 0x4B, -+0x4C, 0x4C, 0x98, 0x42, 0x83, 0xB0, 0x05, 0x46, 0x17, 0x44, 0x6F, 0xD0, 0xA3, 0x6A, 0xAB, 0x42, 0x04, 0xD0, 0xE4, 0xF7, -+0xCD, 0xF9, 0x07, 0xF5, 0x7A, 0x67, 0x07, 0x44, 0x94, 0xF8, 0x5B, 0x80, 0x94, 0xF8, 0x58, 0x30, 0xC4, 0xE9, 0x14, 0x57, -+0xB8, 0xF1, 0x00, 0x0F, 0x57, 0xD1, 0x42, 0x4E, 0x23, 0xF0, 0x40, 0x03, 0x84, 0xF8, 0x58, 0x30, 0x73, 0x6B, 0x98, 0x47, -+0xD6, 0xF8, 0x88, 0x30, 0x42, 0x46, 0x41, 0x46, 0x38, 0x46, 0x98, 0x47, 0xD4, 0xF8, 0x10, 0xB0, 0xBB, 0xF1, 0x00, 0x0F, -+0x3A, 0xD0, 0x3A, 0x4B, 0xDF, 0xF8, 0xF8, 0x90, 0xDB, 0x1B, 0x01, 0x93, 0x4F, 0xF4, 0xA4, 0x68, 0x0C, 0xE0, 0x02, 0x2A, -+0x04, 0xBF, 0xB0, 0xF8, 0xD2, 0x20, 0x91, 0x02, 0x61, 0x44, 0x00, 0x22, 0x98, 0x47, 0xD4, 0xF8, 0x10, 0xB0, 0xBB, 0xF1, -+0x00, 0x0F, 0x25, 0xD0, 0xDB, 0xF8, 0x04, 0xA0, 0xE4, 0xF7, 0x96, 0xF9, 0x01, 0x9B, 0xAA, 0xEB, 0x00, 0x00, 0xD8, 0x42, -+0x1C, 0xD5, 0x9B, 0xF8, 0x08, 0x00, 0xDB, 0xF8, 0x04, 0xC0, 0xF3, 0x6A, 0x08, 0xFB, 0x00, 0x90, 0x4F, 0xF4, 0xC8, 0x31, -+0x90, 0xF8, 0x62, 0x20, 0x00, 0x2A, 0xDC, 0xD1, 0x90, 0xF8, 0x6C, 0x20, 0x24, 0x4F, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, -+0x02, 0x72, 0x91, 0x68, 0x00, 0x22, 0x61, 0x44, 0x98, 0x47, 0xD4, 0xF8, 0x10, 0xB0, 0xBB, 0xF1, 0x00, 0x0F, 0xD9, 0xD1, -+0xE3, 0x6A, 0xD3, 0xB1, 0x1D, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x1B, 0xDB, 0x03, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0x43, 0xF0, 0x40, 0x03, 0x84, 0xF8, 0x58, 0x30, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x94, 0xF8, 0x58, 0x30, -+0x5A, 0x07, 0x8B, 0xD4, 0x23, 0xF0, 0x40, 0x03, 0x84, 0xF8, 0x58, 0x30, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xD6, 0xF8, -+0x9C, 0x30, 0x28, 0x46, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x18, 0x47, 0x94, 0xF8, 0x58, 0x30, 0x13, 0xF0, 0x0C, 0x0F, -+0xDE, 0xD1, 0x0B, 0x49, 0x0B, 0x48, 0x40, 0xF2, 0x86, 0x62, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x07, 0xF0, 0xAC, 0xBD, -+0x00, 0x10, 0x50, 0x40, 0x00, 0x9E, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x60, 0xF0, 0xFF, 0xFF, -+0x68, 0x65, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x5C, 0xA1, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x10, 0xB5, 0x22, 0x4C, 0x94, 0xF8, 0x58, 0x30, 0xD8, 0x07, 0x11, 0xD5, 0x20, 0x4A, 0x12, 0x68, 0xB2, 0xF9, 0x00, 0x20, -+0x00, 0x2A, 0x22, 0xDB, 0x23, 0xF0, 0x01, 0x03, 0x43, 0xF0, 0x04, 0x03, 0x84, 0xF8, 0x58, 0x30, 0x1B, 0x4B, 0x1C, 0x48, -+0xDB, 0x6D, 0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0x03, 0xF0, 0x06, 0x02, 0x02, 0x2A, 0x11, 0xD1, 0x15, 0x4A, 0x12, 0x68, -+0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x17, 0xDB, 0x23, 0xF0, 0x02, 0x03, 0x43, 0xF0, 0x08, 0x03, 0x84, 0xF8, 0x58, 0x30, -+0x10, 0x4B, 0x12, 0x48, 0xDB, 0x6D, 0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0x10, 0xBD, 0x59, 0x07, 0xDA, 0xD5, 0x0F, 0x49, -+0x0F, 0x48, 0x40, 0xF2, 0x9B, 0x62, 0x07, 0xF0, 0x61, 0xFD, 0x94, 0xF8, 0x58, 0x30, 0xD1, 0xE7, 0x1A, 0x07, 0xE5, 0xD5, -+0x09, 0x49, 0x0B, 0x48, 0x40, 0xF2, 0xA6, 0x62, 0x07, 0xF0, 0x56, 0xFD, 0x94, 0xF8, 0x58, 0x30, 0xDC, 0xE7, 0x00, 0xBF, -+0x30, 0x9D, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x00, 0x9E, 0x17, 0x00, 0xE4, 0x9D, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x8C, 0xA1, 0x15, 0x00, 0xC0, 0xA1, 0x15, 0x00, 0x0D, 0x4A, 0x92, 0xF8, 0x58, 0x30, 0xD9, 0x06, -+0x14, 0xD4, 0x92, 0xF8, 0x5A, 0x00, 0x43, 0xF0, 0x10, 0x03, 0x82, 0xF8, 0x58, 0x30, 0x50, 0xB1, 0x08, 0x49, 0x09, 0x4B, -+0x09, 0x69, 0xD3, 0xF8, 0xE0, 0x31, 0x01, 0xF5, 0xEA, 0x41, 0x02, 0xF1, 0x30, 0x00, 0x30, 0x31, 0x18, 0x47, 0x04, 0x4B, -+0xDB, 0x6B, 0x18, 0x47, 0x70, 0x47, 0x00, 0xBF, 0x30, 0x9D, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0x70, 0xB5, 0x32, 0x4C, 0x00, 0x23, 0x05, 0x46, 0xA3, 0x62, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x2E, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x2E, 0x4A, 0x2E, 0x4E, 0x11, 0x68, 0x73, 0x68, 0x48, 0x1C, 0x23, 0xF0, 0x02, 0x03, -+0x10, 0x60, 0x73, 0x60, 0x18, 0xB1, 0x28, 0x4B, 0x11, 0x60, 0x1B, 0x68, 0xF9, 0xB1, 0x29, 0x49, 0x94, 0xF8, 0x5C, 0x30, -+0x0A, 0x68, 0x9B, 0x00, 0x22, 0xF0, 0x04, 0x02, 0x03, 0xF0, 0x04, 0x03, 0x13, 0x43, 0x0B, 0x60, 0x2B, 0x7E, 0x03, 0x2B, -+0x26, 0xD0, 0x04, 0x2B, 0x94, 0xF8, 0x58, 0x30, 0x19, 0xD0, 0x23, 0xF0, 0x10, 0x02, 0xFF, 0x21, 0x9B, 0x07, 0x29, 0x76, -+0x84, 0xF8, 0x58, 0x20, 0x02, 0xD0, 0x1D, 0x4B, 0x1B, 0x6C, 0x98, 0x47, 0xE3, 0x6A, 0x23, 0xB1, 0x70, 0xBD, 0x00, 0x2B, -+0xDD, 0xD0, 0x62, 0xB6, 0xDB, 0xE7, 0x18, 0x4B, 0xD3, 0xF8, 0xA4, 0x31, 0x98, 0x47, 0xBD, 0xE8, 0x70, 0x40, 0xFB, 0xF7, -+0x93, 0xBA, 0x23, 0xF0, 0x04, 0x02, 0x84, 0xF8, 0x58, 0x20, 0xEA, 0x89, 0x92, 0xB9, 0x03, 0xF0, 0xDB, 0x03, 0xDC, 0xE7, -+0x94, 0xF8, 0x58, 0x30, 0x23, 0xF0, 0x08, 0x03, 0x84, 0xF8, 0x58, 0x30, 0xFE, 0xF7, 0x84, 0xFE, 0xFF, 0x22, 0x02, 0x21, -+0x86, 0x20, 0x05, 0xF0, 0x49, 0xFC, 0x94, 0xF8, 0x58, 0x30, 0xCC, 0xE7, 0x28, 0x46, 0xFE, 0xF7, 0xB1, 0xFE, 0x94, 0xF8, -+0x58, 0x30, 0xC6, 0xE7, 0x30, 0x9D, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, -+0x4C, 0x00, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x6B, 0x4F, 0x6C, 0x4E, 0x04, 0x46, 0x6C, 0x48, -+0x06, 0xF0, 0x96, 0xF8, 0x3B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x05, 0x46, 0xC0, 0xF2, 0x85, 0x80, 0x33, 0x78, -+0x00, 0x2B, 0x44, 0xD0, 0x66, 0x4C, 0x01, 0x2B, 0x42, 0xD1, 0x94, 0xF8, 0x58, 0x30, 0x19, 0x07, 0x00, 0xF1, 0x9D, 0x80, -+0x5A, 0x07, 0x40, 0xF1, 0xB0, 0x80, 0x62, 0x4F, 0xE3, 0x6A, 0xBB, 0x42, 0x02, 0xD0, 0x0B, 0xB1, 0x01, 0x22, 0x1A, 0x74, -+0xA3, 0x6A, 0x0B, 0xB1, 0x01, 0x22, 0x1A, 0x74, 0x00, 0x23, 0xC4, 0xE9, 0x0A, 0x73, 0x39, 0x7E, 0x04, 0x23, 0x03, 0x29, -+0x3B, 0x74, 0x00, 0xF0, 0xA0, 0x80, 0x02, 0x29, 0x24, 0xD9, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x55, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x55, 0x4A, 0x55, 0x48, 0x17, 0x68, 0x43, 0x68, 0x79, 0x1C, 0x43, 0xF0, 0x02, 0x03, -+0x11, 0x60, 0x43, 0x60, 0x29, 0xB1, 0x4F, 0x4B, 0x17, 0x60, 0x1B, 0x68, 0x0F, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x4F, 0x4A, -+0xA3, 0x6A, 0x11, 0x68, 0xC1, 0xF3, 0x80, 0x01, 0x84, 0xF8, 0x5C, 0x10, 0x11, 0x68, 0x21, 0xF0, 0x04, 0x01, 0x11, 0x60, -+0x01, 0xE0, 0x44, 0x4C, 0xA3, 0x6A, 0x01, 0x22, 0x1A, 0x74, 0x22, 0x6D, 0x00, 0x23, 0x33, 0x70, 0x00, 0x2A, 0x31, 0xD0, -+0x94, 0xF8, 0x5A, 0x20, 0x23, 0x65, 0x00, 0x2A, 0x53, 0xD0, 0x01, 0x2A, 0x53, 0xD0, 0x23, 0x69, 0x00, 0x2B, 0x50, 0xD0, -+0x1B, 0x7A, 0x40, 0x4A, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x23, 0x18, 0x6C, 0xA8, 0x60, 0x18, 0xB1, 0x3D, 0x4B, -+0xD3, 0xF8, 0x9C, 0x30, 0x98, 0x47, 0x3C, 0x48, 0x29, 0x46, 0x05, 0xF0, 0xDF, 0xFF, 0xA0, 0x6A, 0x03, 0x7E, 0x02, 0x2B, -+0x02, 0xD9, 0x37, 0x4B, 0x9B, 0x6B, 0x98, 0x47, 0x20, 0x6A, 0xA0, 0x64, 0x58, 0xB3, 0x36, 0x4B, 0x41, 0x68, 0x1B, 0x69, -+0xCB, 0x1A, 0x14, 0x2B, 0x27, 0xD4, 0x31, 0x4B, 0x33, 0x48, 0xD3, 0xF8, 0xE0, 0x31, 0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, -+0xA8, 0x68, 0xDD, 0xE7, 0x84, 0x42, 0x32, 0xD0, 0x2F, 0x49, 0x30, 0x48, 0x40, 0xF2, 0x4F, 0x72, 0x07, 0xF0, 0x12, 0xFC, -+0x33, 0x78, 0x00, 0x2B, 0x7F, 0xF4, 0x72, 0xAF, 0x3B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xB1, 0xDA, 0x1D, 0x4C, -+0xA3, 0x6A, 0x00, 0x2B, 0xAF, 0xD1, 0x26, 0x49, 0x27, 0x48, 0x40, 0xF2, 0x51, 0x72, 0x07, 0xF0, 0xFF, 0xFB, 0x33, 0x78, -+0x61, 0xE7, 0xBD, 0xE8, 0xF0, 0x81, 0x63, 0x6C, 0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0x22, 0x4F, 0x64, 0xE7, 0xAA, 0x60, -+0xBB, 0xE7, 0x21, 0x48, 0x02, 0x7E, 0xFF, 0x2A, 0xB1, 0xD1, 0x90, 0xF8, 0x34, 0x20, 0xFF, 0x2A, 0x12, 0xD1, 0x90, 0xF8, -+0x50, 0x20, 0xFF, 0x2A, 0x10, 0xD1, 0xAB, 0x60, 0xAD, 0xE7, 0x33, 0x78, 0x00, 0x2B, 0xD8, 0xD0, 0x44, 0xE7, 0xE7, 0x6A, -+0x00, 0x2F, 0x87, 0xD0, 0x52, 0xE7, 0x02, 0x20, 0x05, 0xF0, 0xF2, 0xFC, 0x39, 0x7E, 0x5A, 0xE7, 0x1C, 0x30, 0x98, 0xE7, -+0x38, 0x30, 0x96, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x17, 0x2C, 0x17, 0x00, 0x50, 0x9D, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, -+0x00, 0x9E, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, -+0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x48, 0x9D, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x70, 0x9D, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xF4, 0xA1, 0x15, 0x00, 0x10, 0xA2, 0x15, 0x00, 0xE4, 0x9D, 0x17, 0x00, 0x90, 0x9D, 0x17, 0x00, -+0x0D, 0x4B, 0x93, 0xF8, 0x58, 0x20, 0x11, 0x07, 0x03, 0xD4, 0x52, 0x07, 0x0D, 0xD5, 0x0B, 0x49, 0x00, 0xE0, 0x0B, 0x49, -+0xDA, 0x6A, 0x8A, 0x42, 0x03, 0xD0, 0x0A, 0xB1, 0x01, 0x20, 0x10, 0x74, 0xD9, 0x62, 0x08, 0x4B, 0xD3, 0xF8, 0x98, 0x30, -+0x18, 0x47, 0xDB, 0x6A, 0x00, 0x2B, 0xF8, 0xD1, 0x05, 0x49, 0x08, 0x20, 0x07, 0xF0, 0x68, 0xB9, 0x30, 0x9D, 0x17, 0x00, -+0x00, 0x9E, 0x17, 0x00, 0xE4, 0x9D, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x28, 0xA2, 0x15, 0x00, 0x0B, 0x4A, 0x92, 0xF8, -+0x59, 0x30, 0x43, 0xB1, 0x01, 0x3B, 0xDB, 0xB2, 0x82, 0xF8, 0x59, 0x30, 0x1B, 0xB9, 0x08, 0x4A, 0x11, 0x78, 0x01, 0x29, -+0x00, 0xD0, 0x70, 0x47, 0x10, 0xB5, 0x06, 0x4C, 0x13, 0x70, 0xD4, 0xF8, 0xA4, 0x31, 0x98, 0x47, 0xE3, 0x6F, 0xBD, 0xE8, -+0x10, 0x40, 0x18, 0x47, 0x30, 0x9D, 0x17, 0x00, 0x17, 0x2C, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xF8, 0xB5, 0x1D, 0x4B, -+0x1D, 0x49, 0x1E, 0x4A, 0xD3, 0xF8, 0xE0, 0x33, 0x8C, 0x68, 0x95, 0x6A, 0x98, 0x47, 0x1C, 0x4B, 0x5B, 0x78, 0x23, 0xB1, -+0x1B, 0x4A, 0x13, 0x68, 0x23, 0xF0, 0x00, 0x43, 0x13, 0x60, 0x1A, 0x4A, 0x13, 0x68, 0x23, 0xF0, 0x04, 0x03, 0x13, 0x60, -+0x1C, 0xB3, 0x18, 0x4F, 0x8C, 0x26, 0x01, 0xE0, 0x24, 0x68, 0xF4, 0xB1, 0x23, 0x6C, 0xAB, 0x42, 0xFA, 0xD1, 0x94, 0xF8, -+0x62, 0x30, 0x00, 0x2B, 0xF6, 0xD1, 0x94, 0xF8, 0x64, 0x30, 0x00, 0x2B, 0xF2, 0xD0, 0x94, 0xF8, 0xC0, 0x34, 0x00, 0x22, -+0x11, 0x46, 0x3B, 0xB1, 0x94, 0xF8, 0xC1, 0x34, 0x06, 0xFB, 0x03, 0x73, 0x93, 0xF8, 0x85, 0x30, 0x00, 0x2B, 0xE5, 0xD0, -+0x94, 0xF8, 0x6C, 0x00, 0xF2, 0xF7, 0xD6, 0xFD, 0x24, 0x68, 0x00, 0x2C, 0xE0, 0xD1, 0xF8, 0xBD, 0x88, 0x1A, 0x17, 0x00, -+0x00, 0x88, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, 0x4C, 0x36, 0x17, 0x00, 0x34, 0x04, 0x32, 0x40, 0x4C, 0x00, 0x32, 0x40, -+0x48, 0x9E, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0x08, 0x81, 0x3D, 0x4A, 0x3E, 0x4E, 0xD8, 0xF8, 0xDC, 0x33, -+0x94, 0x68, 0x96, 0xF8, 0x59, 0x90, 0x83, 0xB0, 0x98, 0x47, 0xB5, 0x6A, 0x00, 0x2D, 0x5E, 0xD0, 0x39, 0x4A, 0x3A, 0x49, -+0x13, 0x68, 0x43, 0xF0, 0x04, 0x03, 0x13, 0x60, 0x4B, 0x78, 0x4F, 0x46, 0x00, 0x2B, 0x4D, 0xD1, 0x00, 0x2C, 0x3A, 0xD0, -+0xDF, 0xF8, 0xD8, 0xB0, 0xDF, 0xF8, 0xD8, 0xA0, 0x4F, 0xF0, 0x06, 0x09, 0x01, 0xE0, 0x24, 0x68, 0x7C, 0xB3, 0x23, 0x6C, -+0x9D, 0x42, 0xFA, 0xD1, 0x94, 0xF8, 0x62, 0x30, 0x00, 0x2B, 0xF6, 0xD1, 0x94, 0xF8, 0x64, 0x30, 0x00, 0x2B, 0xF2, 0xD0, -+0x94, 0xF8, 0x6C, 0x00, 0xFF, 0x28, 0x4F, 0xF0, 0x8C, 0x01, 0x4F, 0xF0, 0x00, 0x02, 0xEA, 0xD0, 0x94, 0xF8, 0xC0, 0x34, -+0x3B, 0xB1, 0x94, 0xF8, 0xC1, 0x34, 0x01, 0xFB, 0x03, 0xA3, 0x93, 0xF8, 0x85, 0x30, 0x00, 0x2B, 0xDF, 0xD0, 0x2B, 0x7C, -+0x85, 0xF8, 0x10, 0x90, 0xD8, 0xF8, 0xB0, 0x10, 0x01, 0x93, 0xF2, 0xF7, 0x79, 0xFD, 0x01, 0x9B, 0x00, 0xB9, 0x01, 0x37, -+0x01, 0x22, 0x2B, 0x74, 0x8B, 0xF8, 0x00, 0x20, 0x24, 0x68, 0x00, 0x2C, 0xCF, 0xD1, 0x5F, 0xFA, 0x87, 0xF9, 0x96, 0xF8, -+0x59, 0x40, 0xF5, 0x6A, 0x86, 0xF8, 0x59, 0x90, 0x3C, 0x1B, 0xAD, 0xB1, 0x27, 0xB1, 0x03, 0x23, 0x2B, 0x74, 0xD8, 0xF8, -+0x60, 0x31, 0x98, 0x47, 0x20, 0x46, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xD2, 0xF8, 0xE8, 0x33, 0x43, 0xF0, 0x00, 0x43, -+0xC2, 0xF8, 0xE8, 0x33, 0xAA, 0xE7, 0x00, 0x24, 0x20, 0x46, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xD8, 0xF8, 0x60, 0x31, -+0x98, 0x47, 0x00, 0x2F, 0xF5, 0xD0, 0x96, 0xF8, 0x59, 0x30, 0x01, 0x3B, 0x2C, 0x46, 0x86, 0xF8, 0x59, 0x30, 0xE3, 0xE7, -+0x00, 0x88, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, 0x4C, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x17, 0x2C, 0x17, 0x00, 0x48, 0x9E, 0x17, 0x00, 0x10, 0xB5, 0x06, 0x4C, 0xD4, 0xF8, 0xA4, 0x31, 0x98, 0x47, 0xA3, 0x6E, -+0x98, 0x47, 0x18, 0xB9, 0xE3, 0x6F, 0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0x10, 0xBD, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x43, 0x4D, 0x4E, 0x4E, 0x4F, 0xF4, 0x6A, 0x85, 0xB0, 0x00, 0x25, 0xE2, 0x88, 0x61, 0x79, 0x23, 0x89, -+0x20, 0x79, 0x02, 0x95, 0x65, 0x7B, 0x01, 0x95, 0x65, 0x89, 0x00, 0x95, 0xE3, 0xF7, 0x72, 0xFD, 0xD7, 0xF8, 0x3C, 0x33, -+0x94, 0xF9, 0x0C, 0x00, 0x98, 0x47, 0x21, 0x79, 0x44, 0x4B, 0x45, 0x4A, 0x03, 0xEB, 0x81, 0x03, 0x5B, 0x69, 0x13, 0x60, -+0x23, 0x7E, 0x03, 0x2B, 0x02, 0xD0, 0x20, 0x46, 0xFE, 0xF7, 0xFE, 0xFB, 0xB3, 0x6A, 0x0B, 0xB1, 0x01, 0x22, 0x1A, 0x74, -+0x00, 0x23, 0xC6, 0xE9, 0x0A, 0x43, 0x23, 0x7E, 0x04, 0x22, 0x02, 0x2B, 0x22, 0x74, 0x4E, 0xD9, 0x96, 0xF8, 0x5A, 0x20, -+0x00, 0x2A, 0x4A, 0xD0, 0x03, 0x2B, 0x52, 0xD0, 0x04, 0x2B, 0x24, 0xD0, 0xFB, 0x6E, 0x98, 0x47, 0x23, 0x7E, 0x02, 0x2B, -+0x1F, 0xD8, 0x34, 0x4B, 0x9D, 0x68, 0x00, 0x2D, 0x37, 0xD0, 0xDF, 0xF8, 0xE4, 0x90, 0x4F, 0xF0, 0x01, 0x08, 0x01, 0xE0, -+0x2D, 0x68, 0x8D, 0xB1, 0x2B, 0x6C, 0xA3, 0x42, 0xFA, 0xD1, 0x95, 0xF8, 0x63, 0x30, 0xD7, 0xF8, 0x5C, 0x24, 0xC3, 0xEB, -+0xC3, 0x03, 0x09, 0xEB, 0x83, 0x03, 0x28, 0x46, 0x83, 0xF8, 0x1B, 0x80, 0x90, 0x47, 0x2D, 0x68, 0x00, 0x2D, 0xED, 0xD1, -+0x23, 0x7E, 0x02, 0x2B, 0x1B, 0xD9, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x22, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x22, 0x4A, 0x22, 0x4C, 0x11, 0x68, 0x63, 0x68, 0x48, 0x1C, 0x43, 0xF0, 0x02, 0x03, 0x10, 0x60, 0x63, 0x60, -+0x28, 0xBB, 0x1F, 0x4B, 0x19, 0x68, 0x1A, 0x68, 0xC1, 0xF3, 0x80, 0x01, 0x22, 0xF0, 0x04, 0x02, 0x86, 0xF8, 0x5C, 0x10, -+0x1A, 0x60, 0xD7, 0xF8, 0x60, 0x31, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x43, 0x18, 0x47, 0x18, 0x4A, 0x92, 0xF8, 0xFF, 0x21, -+0x00, 0x2A, 0xAF, 0xD0, 0xF1, 0xF7, 0xA2, 0xFB, 0x23, 0x7E, 0x03, 0x2B, 0xAC, 0xD1, 0x14, 0x4B, 0x00, 0x22, 0x1A, 0x60, -+0x02, 0x21, 0xFF, 0x22, 0x85, 0x20, 0x05, 0xF0, 0x77, 0xF9, 0x23, 0x7E, 0x02, 0x2B, 0xE4, 0xD9, 0xC7, 0xE7, 0x09, 0x4B, -+0x11, 0x60, 0x1B, 0x68, 0x00, 0x29, 0xD4, 0xD1, 0x00, 0x2B, 0xD2, 0xD0, 0x62, 0xB6, 0xD0, 0xE7, 0x30, 0x9D, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, 0xDC, 0x00, 0x32, 0x40, 0x00, 0x88, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, 0x20, 0x62, 0x17, 0x00, 0x20, 0x02, 0x32, 0x40, -+0x80, 0x9F, 0x17, 0x00, 0x70, 0xB5, 0x25, 0x4D, 0xEA, 0x6A, 0x04, 0x46, 0x0A, 0xB1, 0xE8, 0x62, 0x70, 0xBD, 0xAE, 0x6A, -+0x86, 0x42, 0x3D, 0xD0, 0x5E, 0xB1, 0x33, 0x7E, 0x03, 0x2B, 0x08, 0xD0, 0x01, 0x23, 0x0C, 0x21, 0x45, 0x20, 0x05, 0xF0, -+0xD7, 0xF8, 0x33, 0x7E, 0x03, 0x70, 0x05, 0xF0, 0x03, 0xF9, 0x1B, 0x4B, 0x5B, 0x68, 0x00, 0x2B, 0x1C, 0xDD, 0xEF, 0xF3, -+0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x17, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x17, 0x4E, 0x33, 0x68, 0x04, 0x20, -+0x01, 0x33, 0x33, 0x60, 0xF1, 0xF7, 0x42, 0xF8, 0x4F, 0xF0, 0x80, 0x41, 0x04, 0x20, 0xF1, 0xF7, 0xDD, 0xF8, 0x33, 0x68, -+0x33, 0xB1, 0x0F, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x33, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x02, 0x22, 0xEC, 0x62, -+0x04, 0x23, 0x22, 0x74, 0x00, 0x21, 0xFF, 0x22, 0x84, 0x20, 0x05, 0xF0, 0xA9, 0xF8, 0x09, 0x4B, 0x1B, 0x6E, 0x03, 0x60, -+0xBD, 0xE8, 0x70, 0x40, 0x05, 0xF0, 0xD2, 0xB8, 0x04, 0x23, 0x33, 0x74, 0x70, 0xBD, 0x00, 0xBF, 0x30, 0x9D, 0x17, 0x00, -+0xD8, 0x9C, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0xB5, 0x0A, 0x4D, -+0x04, 0x46, 0xD5, 0xF8, 0x6C, 0x31, 0x00, 0x6D, 0x98, 0x47, 0xD5, 0xF8, 0x00, 0x32, 0x20, 0x65, 0x01, 0x46, 0x20, 0x46, -+0x98, 0x47, 0x94, 0xF8, 0x4D, 0x30, 0x23, 0xF0, 0x40, 0x03, 0x43, 0xF0, 0x20, 0x03, 0x84, 0xF8, 0x4D, 0x30, 0x38, 0xBD, -+0x88, 0x1A, 0x17, 0x00, 0x02, 0x6D, 0x41, 0x6A, 0x70, 0xB5, 0x17, 0x4D, 0x04, 0x46, 0xD5, 0xF8, 0xE0, 0x31, 0x11, 0x44, -+0x18, 0x30, 0x98, 0x47, 0x94, 0xF8, 0x4D, 0x30, 0x23, 0xF0, 0x20, 0x02, 0xDB, 0x07, 0x84, 0xF8, 0x4D, 0x20, 0x0E, 0xD5, -+0x10, 0x4B, 0x5B, 0x6A, 0x23, 0xB1, 0xDA, 0x68, 0x04, 0xF1, 0x44, 0x03, 0x9A, 0x42, 0x07, 0xD0, 0xEB, 0x6A, 0x61, 0x6A, -+0x20, 0x46, 0x00, 0x22, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, 0x70, 0xBD, 0x6B, 0x6B, 0x98, 0x47, 0xEB, 0x6A, 0x61, 0x6A, -+0x20, 0x46, 0x00, 0x22, 0x98, 0x47, 0x06, 0x4A, 0xD5, 0xF8, 0x84, 0x30, 0x11, 0x69, 0x20, 0x46, 0x00, 0x22, 0xBD, 0xE8, -+0x70, 0x40, 0x18, 0x47, 0x88, 0x1A, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x2D, 0xE9, 0xF8, 0x43, -+0xDF, 0xF8, 0xB8, 0x80, 0x90, 0xF8, 0x4E, 0x70, 0x4F, 0xF4, 0xA4, 0x65, 0x05, 0xFB, 0x07, 0x85, 0x95, 0xF8, 0x4D, 0x60, -+0x16, 0xF0, 0x60, 0x06, 0x1F, 0xD1, 0x26, 0x4B, 0x04, 0x46, 0xD3, 0xF8, 0xFC, 0x31, 0x89, 0x46, 0x90, 0xF8, 0x4F, 0x10, -+0x28, 0x46, 0x98, 0x47, 0x63, 0x6D, 0xA0, 0xEB, 0x09, 0x01, 0x58, 0x1A, 0x00, 0xB2, 0x80, 0xEA, 0xE0, 0x73, 0xA3, 0xEB, -+0xE0, 0x73, 0x9B, 0xB2, 0xB3, 0xF5, 0xFA, 0x6F, 0xA4, 0xF8, 0x58, 0x00, 0x09, 0xD9, 0x95, 0xF8, 0x4D, 0x30, 0x23, 0xF0, -+0x40, 0x03, 0x43, 0xF0, 0x10, 0x03, 0x85, 0xF8, 0x4D, 0x30, 0xBD, 0xE8, 0xF8, 0x83, 0xC8, 0x2B, 0xFB, 0xD9, 0x15, 0x4B, -+0x9B, 0x68, 0x9B, 0xB1, 0x95, 0xF8, 0x63, 0x10, 0x30, 0x46, 0x93, 0xF8, 0x4E, 0x20, 0x8A, 0x42, 0x07, 0xD1, 0xB3, 0xF9, -+0x58, 0x20, 0x90, 0x42, 0xA8, 0xBF, 0x10, 0x46, 0x96, 0x42, 0xB8, 0xBF, 0x16, 0x46, 0x1B, 0x68, 0x00, 0x2B, 0xF0, 0xD1, -+0x60, 0xB9, 0x73, 0x10, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x07, 0x87, 0x97, 0xF8, 0x4D, 0x20, 0x3B, 0x65, 0x42, 0xF0, -+0x40, 0x03, 0x87, 0xF8, 0x4D, 0x30, 0xD8, 0xE7, 0x00, 0x2E, 0xD6, 0xD1, 0x00, 0xEB, 0xD0, 0x73, 0x5B, 0x10, 0xED, 0xE7, -+0x88, 0x1A, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x23, 0x48, 0x2D, 0xE9, 0xF0, 0x41, 0x60, 0x22, -+0x00, 0x21, 0x22, 0x4F, 0x06, 0x46, 0xE2, 0xF7, 0xD3, 0xFB, 0x00, 0x25, 0x3C, 0x46, 0xA8, 0x46, 0x00, 0x21, 0x1C, 0x22, -+0x20, 0x46, 0xE2, 0xF7, 0xCB, 0xFB, 0xFF, 0x23, 0x02, 0x2D, 0xE3, 0x81, 0x23, 0x76, 0xE3, 0x76, 0x21, 0x46, 0x30, 0x46, -+0x04, 0xD8, 0x05, 0xF0, 0x55, 0xFC, 0x01, 0x35, 0x1C, 0x34, 0xED, 0xE7, 0x03, 0x2D, 0x22, 0xD0, 0x04, 0x2D, 0xF8, 0xD1, -+0x14, 0x48, 0x05, 0xF0, 0x47, 0xFC, 0x14, 0x48, 0x05, 0xF0, 0x44, 0xFC, 0x13, 0x49, 0x11, 0x48, 0x05, 0xF0, 0x44, 0xFC, -+0x12, 0x49, 0x0F, 0x48, 0x05, 0xF0, 0x40, 0xFC, 0x11, 0x49, 0x0D, 0x48, 0x05, 0xF0, 0x3C, 0xFC, 0x10, 0x49, 0x0B, 0x48, -+0x05, 0xF0, 0x38, 0xFC, 0x0F, 0x4A, 0x07, 0x4B, 0xD2, 0xF8, 0xAC, 0x10, 0xD0, 0x6B, 0x58, 0x63, 0x00, 0x22, 0xC3, 0xE9, -+0x11, 0x12, 0xBD, 0xE8, 0xF0, 0x81, 0xA7, 0xF8, 0x5E, 0x80, 0x87, 0xF8, 0x59, 0x80, 0xD2, 0xE7, 0x30, 0x9D, 0x17, 0x00, -+0x90, 0x9D, 0x17, 0x00, 0x48, 0x9D, 0x17, 0x00, 0x50, 0x9D, 0x17, 0x00, 0xF0, 0x9C, 0x17, 0x00, 0x00, 0x9D, 0x17, 0x00, -+0x10, 0x9D, 0x17, 0x00, 0x20, 0x9D, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x21, 0x4C, 0x24, 0x68, -+0xB4, 0xF9, 0x00, 0x40, 0x83, 0xB0, 0x00, 0x2C, 0x9D, 0xF8, 0x28, 0x90, 0x9D, 0xF8, 0x2C, 0x80, 0x1D, 0x4C, 0x07, 0x46, -+0x0D, 0x46, 0x16, 0x46, 0x27, 0xDB, 0x1C, 0x49, 0x84, 0xF8, 0x58, 0x70, 0x91, 0xF8, 0x58, 0x20, 0xA4, 0xF8, 0x5C, 0x50, -+0xA4, 0xF8, 0x5A, 0x50, 0x42, 0xF0, 0x02, 0x07, 0x84, 0xF8, 0x60, 0x60, 0xFF, 0x25, 0x03, 0x26, 0x01, 0x20, 0xA3, 0x66, -+0xD3, 0x06, 0x84, 0xF8, 0x61, 0x90, 0x84, 0xF8, 0x6E, 0x80, 0x81, 0xF8, 0x58, 0x70, 0x84, 0xF8, 0x6C, 0x60, 0xA4, 0xF8, -+0x62, 0x50, 0x84, 0xF8, 0x64, 0x00, 0x05, 0xD4, 0x0D, 0x4B, 0x1B, 0x6C, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x43, 0x18, 0x47, -+0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x94, 0xF8, 0x6C, 0x20, 0xFF, 0x2A, 0xD3, 0xD0, 0x08, 0x49, 0x08, 0x48, 0x01, 0x93, -+0x40, 0xF6, 0x8C, 0x22, 0x07, 0xF0, 0x26, 0xF8, 0x01, 0x9B, 0xCA, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x90, 0x9D, 0x17, 0x00, -+0x30, 0x9D, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x48, 0xA2, 0x15, 0x00, 0xF0, 0xB5, 0x65, 0x4F, -+0x04, 0x46, 0x83, 0xB0, 0x97, 0xF8, 0x80, 0x00, 0xE3, 0x68, 0x22, 0x78, 0x00, 0x90, 0x0E, 0x46, 0x08, 0x20, 0x61, 0x49, -+0x06, 0xF0, 0xE0, 0xFD, 0x25, 0x78, 0x25, 0xB3, 0x01, 0x2D, 0x2F, 0xD1, 0x97, 0xF8, 0x88, 0x30, 0xFF, 0x2B, 0x1A, 0xD0, -+0x97, 0xF8, 0x80, 0x30, 0x03, 0x2B, 0x2B, 0xD8, 0x01, 0x2B, 0x5A, 0x4C, 0x44, 0xD8, 0x09, 0xD1, 0x94, 0xF8, 0x58, 0x30, -+0x07, 0xF1, 0x70, 0x00, 0x23, 0xF0, 0x05, 0x03, 0x84, 0xF8, 0x58, 0x30, 0xFE, 0xF7, 0xE4, 0xF9, 0x94, 0xF8, 0x58, 0x30, -+0x03, 0xF0, 0x12, 0x02, 0xFF, 0x21, 0x10, 0x2A, 0x87, 0xF8, 0x88, 0x10, 0x24, 0xD0, 0x00, 0x25, 0x28, 0x46, 0x03, 0xB0, -+0xF0, 0xBD, 0x97, 0xF8, 0x88, 0x30, 0xFF, 0x2B, 0x3A, 0xD0, 0x4B, 0x4A, 0x92, 0xF8, 0x58, 0x30, 0x99, 0x06, 0x03, 0xD5, -+0x23, 0xF0, 0x20, 0x03, 0x82, 0xF8, 0x58, 0x30, 0x01, 0x25, 0x28, 0x46, 0x03, 0xB0, 0xF0, 0xBD, 0x04, 0x2B, 0x17, 0xD1, -+0x44, 0x48, 0x45, 0x4D, 0xA0, 0xF1, 0x40, 0x04, 0xD5, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0x00, 0x22, 0xD5, 0xF8, 0xAC, 0x30, -+0x20, 0x6A, 0xA2, 0x64, 0x98, 0x47, 0xD1, 0xE7, 0x3E, 0x4A, 0x3F, 0x48, 0xD2, 0xF8, 0xD8, 0x21, 0x23, 0xF0, 0x10, 0x03, -+0x84, 0xF8, 0x58, 0x30, 0x90, 0x47, 0xD0, 0xE7, 0x37, 0x4C, 0xC5, 0xE7, 0x94, 0xF8, 0x58, 0x30, 0xE2, 0x6A, 0x23, 0xF0, -+0x04, 0x03, 0x84, 0xF8, 0x58, 0x30, 0x2A, 0xB1, 0x07, 0xF1, 0x70, 0x03, 0x9A, 0x42, 0x50, 0xD0, 0x00, 0x23, 0xE3, 0x62, -+0x33, 0x48, 0xFE, 0xF7, 0x99, 0xF9, 0xB3, 0xE7, 0x97, 0xF8, 0x80, 0x30, 0x04, 0x2B, 0xC0, 0xD0, 0x04, 0x20, 0x05, 0xF0, -+0x5D, 0xF9, 0x01, 0x28, 0xBB, 0xD0, 0x04, 0x23, 0x87, 0xF8, 0x88, 0x30, 0xA3, 0x78, 0x87, 0xF8, 0x74, 0x30, 0xE3, 0x78, -+0x87, 0xF8, 0x75, 0x30, 0xA3, 0x88, 0xE2, 0x88, 0xA7, 0xF8, 0x76, 0x30, 0x01, 0x21, 0x23, 0x89, 0x87, 0xF8, 0x80, 0x10, -+0xA7, 0xF8, 0x78, 0x20, 0xE2, 0x68, 0xA7, 0xF8, 0x7A, 0x30, 0x4F, 0xF4, 0x7A, 0x73, 0x03, 0xFB, 0x02, 0xF3, 0x23, 0x2A, -+0x84, 0xBF, 0xA3, 0xF5, 0x08, 0x43, 0xB8, 0x3B, 0xA7, 0xF8, 0x7E, 0x60, 0xC7, 0xF8, 0x84, 0x30, 0x63, 0x78, 0x17, 0x4A, -+0x87, 0xF8, 0x8A, 0x30, 0x23, 0x7C, 0x87, 0xF8, 0x7C, 0x30, 0x16, 0x49, 0x92, 0xF8, 0x58, 0x30, 0x66, 0xB9, 0x43, 0xF0, -+0x04, 0x03, 0xC9, 0x6D, 0x14, 0x48, 0x82, 0xF8, 0x58, 0x30, 0x88, 0x47, 0x13, 0x4A, 0x13, 0x68, 0x43, 0xF0, 0x04, 0x03, -+0x13, 0x60, 0x8A, 0xE7, 0x43, 0xF0, 0x01, 0x03, 0x09, 0x6C, 0x82, 0xF8, 0x58, 0x30, 0x88, 0x47, 0xF2, 0xE7, 0x23, 0x6D, -+0x93, 0x42, 0xAB, 0xD1, 0x08, 0x4B, 0x04, 0xF1, 0x40, 0x00, 0xD3, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0x00, 0x23, 0xA3, 0x64, -+0xA2, 0xE7, 0x00, 0xBF, 0x90, 0x9D, 0x17, 0x00, 0x68, 0xA2, 0x15, 0x00, 0x30, 0x9D, 0x17, 0x00, 0x70, 0x9D, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x60, 0x9D, 0x17, 0x00, 0x00, 0x9E, 0x17, 0x00, 0x94, 0x40, 0x04, 0x40, 0x2D, 0xE9, 0xF0, 0x41, -+0x36, 0x4E, 0x84, 0xB0, 0x04, 0x46, 0x0F, 0x46, 0x33, 0x46, 0x00, 0x25, 0x1A, 0x7E, 0xFF, 0x2A, 0x03, 0xD0, 0x1A, 0x79, -+0x20, 0x78, 0x90, 0x42, 0x1B, 0xD0, 0x01, 0x35, 0x03, 0x2D, 0x03, 0xF1, 0x1C, 0x03, 0xF3, 0xD1, 0x2E, 0x48, 0x05, 0xF0, -+0x15, 0xFB, 0x03, 0x46, 0x70, 0xB3, 0x2D, 0x4A, 0x86, 0x1B, 0xB6, 0x10, 0x02, 0xFB, 0x06, 0xF6, 0xF6, 0xB2, 0x06, 0x76, -+0x3E, 0x70, 0x20, 0x68, 0x61, 0x68, 0x04, 0x33, 0x03, 0xC3, 0x22, 0x89, 0x1A, 0x80, 0x00, 0x20, 0x04, 0xB0, 0xBD, 0xE8, -+0xF0, 0x81, 0xD9, 0x88, 0x62, 0x88, 0x8A, 0x42, 0xDF, 0xD1, 0x93, 0xF8, 0x05, 0xC0, 0x61, 0x78, 0x8C, 0x45, 0x08, 0xD0, -+0x02, 0xD2, 0xBC, 0xF1, 0x03, 0x0F, 0x13, 0xD1, 0x8C, 0x45, 0xD4, 0xD9, 0x03, 0x29, 0xD2, 0xD0, 0x07, 0xE0, 0x19, 0x89, -+0xA2, 0x88, 0x91, 0x42, 0xCD, 0xD1, 0x59, 0x89, 0xE2, 0x88, 0x91, 0x42, 0xC9, 0xD1, 0x3D, 0x70, 0x00, 0x20, 0xDF, 0xE7, -+0x01, 0x20, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0xDF, 0xF8, 0x48, 0xE0, 0xB4, 0xF8, 0x04, 0x80, 0xB4, 0xF8, 0x06, 0xC0, -+0xDE, 0xF8, 0x28, 0x30, 0xC5, 0xEB, 0xC5, 0x04, 0x06, 0xEB, 0x84, 0x04, 0xA3, 0x42, 0x61, 0x71, 0xA4, 0xF8, 0x08, 0x80, -+0xA4, 0xF8, 0x0A, 0xC0, 0xE5, 0xD1, 0x9E, 0xF8, 0x5A, 0x40, 0x01, 0x2C, 0xE1, 0xD1, 0x1C, 0x24, 0x04, 0xFB, 0x05, 0x66, -+0x00, 0x24, 0x76, 0x7B, 0xCD, 0xF8, 0x00, 0xC0, 0xCD, 0xE9, 0x01, 0x64, 0x43, 0x46, 0xE3, 0xF7, 0xCF, 0xF9, 0xD4, 0xE7, -+0x90, 0x9D, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, 0xB7, 0x6D, 0xDB, 0xB6, 0x2D, 0xE9, 0xF0, 0x41, 0xDF, 0xF8, 0x98, 0x80, -+0x20, 0x4D, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0xC0, 0xEB, 0xC0, 0x06, 0x00, 0x2B, 0x04, 0x46, 0x05, 0xEB, -+0x86, 0x06, 0x12, 0xDB, 0xC7, 0x00, 0x1B, 0x48, 0x31, 0x46, 0x3C, 0x1B, 0x05, 0xF0, 0x5C, 0xFA, 0x05, 0xEB, 0x84, 0x04, -+0x30, 0x46, 0x1C, 0x22, 0x00, 0x21, 0xE2, 0xF7, 0xC1, 0xF9, 0xFF, 0x23, 0xE3, 0x81, 0x23, 0x76, 0xE3, 0x76, 0xBD, 0xE8, -+0xF0, 0x81, 0xC0, 0xEB, 0xC0, 0x03, 0x05, 0xEB, 0x83, 0x03, 0xC7, 0x00, 0x1B, 0x7E, 0xFF, 0x2B, 0x0C, 0xD0, 0x3B, 0x1B, -+0x05, 0xEB, 0x83, 0x03, 0x5B, 0x7E, 0x00, 0x2B, 0xDF, 0xD0, 0x0C, 0x49, 0x0C, 0x48, 0x40, 0xF6, 0x5C, 0x32, 0x06, 0xF0, -+0x8F, 0xFE, 0xD8, 0xE7, 0x08, 0x49, 0x0A, 0x48, 0x40, 0xF6, 0x5A, 0x32, 0x06, 0xF0, 0x88, 0xFE, 0xD8, 0xF8, 0x00, 0x30, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xE6, 0xDB, 0xCB, 0xE7, 0x00, 0xBF, 0x90, 0x9D, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x84, 0xA2, 0x15, 0x00, 0xA4, 0x88, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0xDF, 0xF8, 0x4C, 0x82, 0xDF, 0xF8, 0x24, 0xA2, 0xD8, 0xF8, 0x00, 0x20, 0x84, 0x4F, 0xB2, 0xF9, 0x00, 0x30, 0xC1, 0xEB, -+0xC1, 0x06, 0x00, 0x2B, 0x85, 0xB0, 0x0C, 0x46, 0x05, 0x46, 0x0A, 0xEB, 0x86, 0x06, 0x5F, 0xDB, 0x4F, 0xEA, 0xC4, 0x0B, -+0xAB, 0xEB, 0x04, 0x01, 0x0A, 0xEB, 0x81, 0x01, 0x4F, 0xF4, 0xA4, 0x63, 0x4A, 0x7E, 0xDF, 0xF8, 0x1C, 0x92, 0x01, 0x32, -+0x03, 0xFB, 0x05, 0x73, 0xD2, 0xB2, 0x00, 0x20, 0x01, 0x2A, 0x4A, 0x76, 0x1E, 0x64, 0x83, 0xF8, 0x4D, 0x00, 0x6B, 0xD0, -+0xDF, 0xF8, 0x04, 0x82, 0x99, 0xF8, 0x5B, 0x10, 0x99, 0xF8, 0x5A, 0x30, 0x4F, 0xF4, 0x80, 0x70, 0xCD, 0xE9, 0x00, 0x31, -+0x6F, 0x49, 0x23, 0x46, 0x06, 0xF0, 0x12, 0xFC, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x05, 0x73, 0xFF, 0x21, 0x93, 0xF8, -+0xC0, 0x24, 0x83, 0xF8, 0x4E, 0x10, 0x4A, 0xB1, 0x69, 0x49, 0x93, 0xF8, 0xC1, 0x24, 0x8C, 0x20, 0x00, 0xFB, 0x02, 0x12, -+0x92, 0xF8, 0x70, 0x20, 0x01, 0x2A, 0x20, 0xD0, 0x65, 0x4B, 0x03, 0xF1, 0x54, 0x01, 0x1A, 0x7E, 0xFF, 0x2A, 0x03, 0xD0, -+0xDA, 0x7E, 0xFF, 0x2A, 0x40, 0xF0, 0xAA, 0x80, 0x1C, 0x33, 0x99, 0x42, 0xF5, 0xD1, 0xD8, 0xF8, 0xB4, 0x30, 0x30, 0x46, -+0x98, 0x47, 0x5E, 0x4B, 0x1B, 0x7C, 0xAB, 0x42, 0x08, 0xD0, 0xFF, 0x2B, 0x06, 0xD0, 0xD8, 0xF8, 0x50, 0x30, 0x20, 0x46, -+0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x18, 0x47, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x93, 0xF8, 0x4D, 0x20, 0x42, 0xF0, -+0x10, 0x02, 0x83, 0xF8, 0x4D, 0x20, 0xE4, 0xE7, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x00, 0x73, 0x1B, 0x6C, 0x5B, 0xB1, -+0x50, 0x49, 0x51, 0x48, 0x40, 0xF6, 0x6B, 0x32, 0x06, 0xF0, 0xF4, 0xFD, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x8D, 0xDA, 0xC4, 0xEB, 0xC4, 0x03, 0x0A, 0xEB, 0x83, 0x03, 0x4F, 0xEA, 0xC4, 0x0B, 0x1B, 0x7E, 0xFF, 0x2B, -+0x86, 0xD1, 0x46, 0x49, 0x47, 0x48, 0x40, 0xF6, 0x6C, 0x32, 0x06, 0xF0, 0xDF, 0xFD, 0x7F, 0xE7, 0x99, 0xF8, 0x5A, 0x00, -+0x0A, 0x74, 0x42, 0x1C, 0xD8, 0xF8, 0x00, 0x30, 0xD2, 0xB2, 0x89, 0xF8, 0x5A, 0x20, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0x28, 0xDB, 0x02, 0x2A, 0x3C, 0xD0, 0x3E, 0x48, 0x31, 0x46, 0x05, 0xF0, 0x77, 0xF9, 0x99, 0xF8, 0x58, 0x30, 0x13, 0xF0, -+0x0C, 0x0F, 0x0F, 0xD0, 0xD8, 0xF8, 0x00, 0x20, 0xD9, 0xF8, 0x20, 0x30, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x20, 0xDB, -+0xAB, 0xEB, 0x04, 0x0B, 0x0A, 0xEB, 0x8B, 0x0A, 0x9E, 0x60, 0x9A, 0xF8, 0x19, 0x20, 0x6B, 0xE7, 0xD9, 0xF8, 0x2C, 0x30, -+0x8B, 0xB3, 0xAB, 0xEB, 0x04, 0x0B, 0x0A, 0xEB, 0x8B, 0x0A, 0xDF, 0xF8, 0xD0, 0x80, 0x9A, 0xF8, 0x19, 0x20, 0xC9, 0xF8, -+0x2C, 0x60, 0x5F, 0xE7, 0x02, 0x2A, 0xD4, 0xD9, 0x40, 0xF6, 0x81, 0x32, 0x25, 0x49, 0x29, 0x48, 0x06, 0xF0, 0xA0, 0xFD, -+0x99, 0xF8, 0x5A, 0x20, 0xCB, 0xE7, 0x00, 0x2B, 0xDC, 0xD1, 0x21, 0x49, 0x25, 0x48, 0x03, 0x93, 0x4F, 0xF4, 0x39, 0x62, -+0x06, 0xF0, 0x94, 0xFD, 0x03, 0x9B, 0xD3, 0xE7, 0x22, 0x48, 0x05, 0xF0, 0x37, 0xF9, 0x16, 0x4B, 0x03, 0xF5, 0xA4, 0x51, -+0x93, 0xF8, 0x4D, 0x20, 0x22, 0xF0, 0x01, 0x02, 0x83, 0xF8, 0x4D, 0x20, 0x03, 0xF5, 0xA4, 0x63, 0x99, 0x42, 0xF5, 0xD1, -+0xB1, 0xE7, 0xDF, 0xF8, 0x74, 0x80, 0xAB, 0xEB, 0x04, 0x0B, 0x0A, 0xEB, 0x8B, 0x0A, 0xD8, 0xF8, 0x9C, 0x30, 0x30, 0x46, -+0x98, 0x47, 0x9A, 0xF8, 0x19, 0x20, 0x2B, 0xE7, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0x72, 0x12, 0x6C, 0xB2, 0x42, -+0x3F, 0xF4, 0x51, 0xAF, 0x03, 0xFB, 0x05, 0x77, 0x97, 0xF8, 0x4D, 0x30, 0x43, 0xF0, 0x10, 0x03, 0x87, 0xF8, 0x4D, 0x30, -+0x47, 0xE7, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, 0xE0, 0xA2, 0x15, 0x00, 0x48, 0x9E, 0x17, 0x00, 0x90, 0x9D, 0x17, 0x00, -+0x00, 0x88, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xA0, 0xA2, 0x15, 0x00, 0xA4, 0x88, 0x15, 0x00, 0x38, 0x9D, 0x17, 0x00, -+0xB8, 0xA2, 0x15, 0x00, 0xD4, 0xA2, 0x15, 0x00, 0x40, 0x9D, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0xBC, 0xA2, 0xDF, 0xF8, 0xB4, 0x82, 0xDA, 0xF8, 0x00, 0x30, -+0x4F, 0xF4, 0xA4, 0x69, 0xB3, 0xF9, 0x00, 0x30, 0x09, 0xFB, 0x00, 0xF9, 0x08, 0xEB, 0x09, 0x02, 0x00, 0x2B, 0x14, 0x6C, -+0x85, 0xB0, 0x05, 0x46, 0xC0, 0xF2, 0x99, 0x80, 0x4F, 0xF4, 0xA4, 0x66, 0x06, 0xFB, 0x05, 0x86, 0x9A, 0x4F, 0x96, 0xF8, -+0x4D, 0x00, 0x21, 0x7C, 0x97, 0xF8, 0x5A, 0x30, 0x62, 0x7E, 0x00, 0x93, 0xCD, 0xE9, 0x01, 0x01, 0x97, 0xF8, 0x5B, 0x30, -+0x95, 0x49, 0x4F, 0xF4, 0x80, 0x70, 0x06, 0xF0, 0xEF, 0xFA, 0x09, 0xF1, 0x44, 0x01, 0x07, 0xF1, 0x10, 0x00, 0x41, 0x44, -+0x05, 0xF0, 0x0E, 0xF9, 0x96, 0xF8, 0x4D, 0x30, 0x23, 0xF0, 0x01, 0x02, 0x86, 0xF8, 0x4D, 0x20, 0x9A, 0x07, 0x09, 0xD5, -+0x97, 0xF8, 0x5B, 0x30, 0x97, 0xF8, 0x5A, 0x20, 0x01, 0x3B, 0xDB, 0xB2, 0x01, 0x2A, 0x87, 0xF8, 0x5B, 0x30, 0x5D, 0xD9, -+0xDF, 0xF8, 0x3C, 0xB2, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x05, 0x85, 0x00, 0x23, 0x85, 0xF8, 0x4D, 0x30, 0x2B, 0x64, -+0x66, 0x7E, 0x23, 0x7C, 0x01, 0x3E, 0xF6, 0xB2, 0x66, 0x76, 0x00, 0x2B, 0x45, 0xD0, 0x95, 0xF8, 0x63, 0x30, 0xE2, 0x7E, -+0x9A, 0x42, 0x00, 0xF0, 0x85, 0x80, 0x7C, 0x4B, 0x03, 0xF1, 0x54, 0x01, 0x1A, 0x7E, 0xFF, 0x2A, 0x03, 0xD0, 0xD8, 0x7E, -+0xFF, 0x28, 0x40, 0xF0, 0xBD, 0x80, 0x1C, 0x33, 0x99, 0x42, 0xF5, 0xD1, 0x00, 0x2E, 0x4E, 0xD0, 0xDB, 0xF8, 0xB4, 0x30, -+0x20, 0x46, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x18, 0x47, 0x97, 0xF8, 0x5A, 0x30, 0x00, 0x20, 0xB8, 0x62, 0x00, 0x2B, -+0x59, 0xD0, 0x21, 0x7E, 0xDB, 0xF8, 0x9C, 0x50, 0x6C, 0x4A, 0x02, 0x29, 0x01, 0xF1, 0x01, 0x03, 0x00, 0xF0, 0xC0, 0x80, -+0xC3, 0xEB, 0xC3, 0x06, 0x02, 0xEB, 0x86, 0x06, 0xD8, 0x00, 0x36, 0x7E, 0xFF, 0x2E, 0x40, 0xF0, 0xC3, 0x80, 0x01, 0x29, -+0x01, 0xF1, 0x02, 0x03, 0x08, 0xBF, 0x00, 0x23, 0xC3, 0xEB, 0xC3, 0x01, 0x02, 0xEB, 0x81, 0x01, 0xD8, 0x00, 0x09, 0x7E, -+0xFF, 0x29, 0x08, 0xBF, 0x00, 0x20, 0x40, 0xF0, 0xB3, 0x80, 0xA8, 0x47, 0x66, 0x7E, 0x00, 0x2E, 0xCC, 0xD1, 0xDB, 0xF8, -+0x48, 0x30, 0x20, 0x7E, 0x98, 0x47, 0xC7, 0xE7, 0x00, 0x2B, 0x9F, 0xD1, 0x97, 0xF8, 0x58, 0x30, 0xDF, 0xF8, 0x78, 0xB1, -+0x5B, 0x06, 0x9B, 0xD5, 0x38, 0x6D, 0xDB, 0xF8, 0x5C, 0x30, 0x98, 0x47, 0x96, 0xE7, 0x00, 0x2C, 0x7F, 0xF4, 0x64, 0xAF, -+0x51, 0x49, 0x52, 0x48, 0x40, 0xF6, 0xC4, 0x32, 0x06, 0xF0, 0x8C, 0xFC, 0x5C, 0xE7, 0x50, 0x48, 0x21, 0x46, 0x05, 0xF0, -+0x83, 0xF8, 0x26, 0x74, 0x97, 0xF8, 0x5A, 0x30, 0xDA, 0xF8, 0x00, 0x20, 0x01, 0x3B, 0xDB, 0xB2, 0x87, 0xF8, 0x5A, 0x30, -+0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x0A, 0xDB, 0x03, 0xBB, 0xBB, 0x6A, 0xA3, 0x42, 0xA2, 0xD0, 0xFB, 0x6A, 0xA3, 0x42, -+0x31, 0xD0, 0x66, 0x7E, 0x00, 0x2E, 0xC8, 0xD0, 0x94, 0xE7, 0x01, 0x2B, 0xF2, 0xD9, 0x3F, 0x49, 0x41, 0x48, 0x4F, 0xF4, -+0x40, 0x62, 0x06, 0xF0, 0x67, 0xFC, 0x97, 0xF8, 0x5A, 0x30, 0xE9, 0xE7, 0xDB, 0xF8, 0x94, 0x30, 0x08, 0xEB, 0x09, 0x00, -+0x98, 0x47, 0x66, 0x7E, 0xFF, 0x23, 0xE3, 0x76, 0x00, 0x2E, 0x7F, 0xF4, 0x7F, 0xAF, 0xCC, 0xE7, 0x38, 0x48, 0x04, 0xF0, -+0xFD, 0xFF, 0x38, 0x4B, 0x03, 0xF5, 0xA4, 0x51, 0x93, 0xF8, 0x4D, 0x20, 0x22, 0xF0, 0x01, 0x02, 0x83, 0xF8, 0x4D, 0x20, -+0x03, 0xF5, 0xA4, 0x63, 0x99, 0x42, 0xF5, 0xD1, 0x3B, 0x6D, 0x00, 0x2B, 0xCB, 0xD1, 0xDB, 0xF8, 0x34, 0x30, 0x98, 0x47, -+0xC7, 0xE7, 0x21, 0x7E, 0x27, 0x4A, 0x02, 0x29, 0x01, 0xF1, 0x01, 0x03, 0x29, 0xD0, 0xC3, 0xEB, 0xC3, 0x05, 0x02, 0xEB, -+0x85, 0x05, 0xD8, 0x00, 0x2D, 0x7E, 0xFF, 0x2D, 0x35, 0xD1, 0x01, 0x29, 0x01, 0xF1, 0x02, 0x03, 0x08, 0xBF, 0x00, 0x23, -+0xC3, 0xEB, 0xC3, 0x01, 0x02, 0xEB, 0x81, 0x01, 0xD8, 0x00, 0x09, 0x7E, 0xFF, 0x29, 0x08, 0xBF, 0x00, 0x22, 0x26, 0xD1, -+0xFA, 0x62, 0xAE, 0xE7, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x00, 0x80, 0x03, 0x6C, 0xA3, 0x42, 0x3F, 0xF4, 0x3E, 0xAF, -+0x66, 0xB1, 0xDB, 0xF8, 0x8C, 0x30, 0x98, 0x47, 0x66, 0x7E, 0x00, 0x2E, 0x7F, 0xF4, 0x38, 0xAF, 0x85, 0xE7, 0x13, 0x7E, -+0xFF, 0x2B, 0x0E, 0xD1, 0x01, 0x23, 0xDD, 0xE7, 0xDB, 0xF8, 0x94, 0x30, 0x98, 0x47, 0x66, 0x7E, 0x00, 0x2E, 0x7F, 0xF4, -+0x2B, 0xAF, 0x78, 0xE7, 0x13, 0x7E, 0xFF, 0x2B, 0x07, 0xD1, 0x01, 0x23, 0x48, 0xE7, 0x00, 0x23, 0x18, 0x46, 0xC3, 0x1A, -+0x02, 0xEB, 0x83, 0x02, 0xD4, 0xE7, 0x03, 0x46, 0xC0, 0x1A, 0x02, 0xEB, 0x80, 0x00, 0x48, 0xE7, 0x30, 0x9D, 0x17, 0x00, -+0x08, 0xA3, 0x15, 0x00, 0x90, 0x9D, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xF8, 0xA2, 0x15, 0x00, 0x38, 0x9D, 0x17, 0x00, -+0x28, 0xA3, 0x15, 0x00, 0x40, 0x9D, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x43, 0x03, 0x46, 0x05, 0x78, 0x29, 0x4E, 0x2A, 0x4A, 0x04, 0x46, 0x53, 0xF8, 0x02, 0x0F, 0x97, 0x6A, -+0x59, 0x68, 0xB3, 0xF8, 0x08, 0xC0, 0xC5, 0xEB, 0xC5, 0x03, 0x06, 0xEB, 0x83, 0x03, 0x04, 0x33, 0x03, 0xC3, 0xC5, 0xEB, -+0xC5, 0x02, 0x06, 0xEB, 0x82, 0x02, 0x97, 0x42, 0x85, 0xB0, 0xA3, 0xF8, 0x00, 0xC0, 0x02, 0xD0, 0x05, 0xB0, 0xBD, 0xE8, -+0xF0, 0x83, 0x4F, 0xEA, 0xC5, 0x08, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x1A, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x1A, 0x4F, 0xDF, 0xF8, 0x68, 0x90, 0x3B, 0x68, 0xD9, 0xF8, 0xA0, 0x22, 0x01, 0x33, 0x3B, 0x60, 0x90, 0x47, -+0xD9, 0xF8, 0x88, 0x32, 0x00, 0x20, 0x98, 0x47, 0x3B, 0x68, 0x33, 0xB1, 0x11, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x3B, 0x60, -+0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xE2, 0x7A, 0x23, 0x89, 0x00, 0x93, 0x00, 0x21, 0xCD, 0xE9, 0x01, 0x21, 0xA8, 0xEB, -+0x05, 0x05, 0xE3, 0x88, 0xA0, 0x78, 0xA2, 0x88, 0xE1, 0x78, 0x06, 0xEB, 0x85, 0x06, 0xE2, 0xF7, 0x91, 0xFE, 0xD9, 0xF8, -+0x3C, 0x33, 0x96, 0xF9, 0x0C, 0x00, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x43, 0x18, 0x47, 0x00, 0xBF, 0x90, 0x9D, 0x17, 0x00, -+0x30, 0x9D, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0xB5, 0x12, 0x4D, -+0x12, 0x4A, 0x2B, 0x7C, 0x4F, 0xF4, 0xA4, 0x64, 0x04, 0xFB, 0x03, 0x24, 0x06, 0x46, 0x22, 0x6C, 0x4A, 0xB1, 0x0F, 0x4C, -+0x18, 0x46, 0x63, 0x6D, 0x98, 0x47, 0xE3, 0x6C, 0x28, 0x7C, 0x31, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, 0x05, 0x22, -+0x11, 0x46, 0x02, 0x23, 0x41, 0xF2, 0x17, 0x40, 0x04, 0xF0, 0x7E, 0xFA, 0x01, 0x22, 0x02, 0x70, 0x94, 0xF8, 0x63, 0x20, -+0x42, 0x70, 0x04, 0xF0, 0xA7, 0xFA, 0x03, 0x4C, 0xE9, 0xE7, 0x00, 0xBF, 0x00, 0x88, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0x6B, 0x4D, 0x2C, 0x69, 0x07, 0x46, 0x8B, 0x46, 0x91, 0x46, 0x8C, 0xB3, -+0x63, 0x68, 0xD0, 0xF8, 0x40, 0xA0, 0xD5, 0xF8, 0x28, 0x80, 0x8B, 0x42, 0x12, 0xD0, 0x05, 0xF1, 0x10, 0x06, 0xA3, 0xEB, -+0x0B, 0x03, 0x00, 0x2B, 0x21, 0x46, 0x30, 0x46, 0x26, 0xDA, 0x04, 0xF0, 0x33, 0xFF, 0x63, 0x7A, 0x23, 0xF0, 0x01, 0x03, -+0x63, 0x72, 0x2C, 0x69, 0xF4, 0xB1, 0x63, 0x68, 0x5B, 0x45, 0xEE, 0xD1, 0x95, 0xF8, 0x5A, 0x30, 0x01, 0x2B, 0x4F, 0xF0, -+0x00, 0x04, 0x1B, 0xD8, 0x97, 0xF8, 0x4D, 0x30, 0x43, 0xF0, 0x02, 0x03, 0x87, 0xF8, 0x4D, 0x30, 0x95, 0xF8, 0x5B, 0x30, -+0xB8, 0xEB, 0x0A, 0x00, 0x03, 0xF1, 0x01, 0x03, 0x18, 0xBF, 0x01, 0x20, 0x85, 0xF8, 0x5B, 0x30, 0xBD, 0xE8, 0xF8, 0x8F, -+0xD0, 0xF8, 0x40, 0xA0, 0xD5, 0xF8, 0x28, 0x80, 0x95, 0xF8, 0x5A, 0x30, 0x01, 0x2B, 0x4F, 0xF0, 0x01, 0x04, 0xE3, 0xD9, -+0x97, 0xF8, 0x4E, 0x30, 0xFF, 0x2B, 0x26, 0xD0, 0x49, 0x4E, 0x59, 0x46, 0x73, 0x6F, 0x38, 0x46, 0x98, 0x47, 0x00, 0x2C, -+0x41, 0xD0, 0x97, 0xF8, 0x4D, 0x30, 0x97, 0xF8, 0xC0, 0x24, 0x43, 0xF0, 0x04, 0x03, 0x87, 0xF8, 0x4D, 0x30, 0x82, 0xB1, -+0x42, 0x4A, 0x97, 0xF8, 0xC1, 0x34, 0x8C, 0x21, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, 0x70, 0x30, 0x01, 0x2B, 0x06, 0xD1, -+0xBB, 0x6C, 0x4B, 0x45, 0x03, 0xD0, 0xA3, 0xEB, 0x09, 0x02, 0x32, 0x2A, 0x5D, 0xD4, 0xB8, 0xEB, 0x0A, 0x00, 0x18, 0xBF, -+0x01, 0x20, 0xBD, 0xE8, 0xF8, 0x8F, 0x97, 0xF8, 0xC0, 0x34, 0xB3, 0xB3, 0x35, 0x4A, 0x97, 0xF8, 0xC1, 0x34, 0x8C, 0x21, -+0x01, 0xFB, 0x03, 0x21, 0x91, 0xF8, 0x70, 0x10, 0x01, 0x29, 0x35, 0xD0, 0x00, 0x2C, 0x4F, 0xD1, 0x30, 0x48, 0x07, 0xF1, -+0x44, 0x01, 0x04, 0xF0, 0xC9, 0xFE, 0x97, 0xF8, 0x4D, 0x30, 0x03, 0xF0, 0xFE, 0x03, 0x43, 0xF0, 0x02, 0x03, 0x87, 0xF8, -+0x4D, 0x30, 0x95, 0xF8, 0x5B, 0x30, 0x01, 0x33, 0x85, 0xF8, 0x5B, 0x30, 0xD7, 0xE7, 0x97, 0xF8, 0xC0, 0x34, 0x00, 0x2B, -+0xE8, 0xD0, 0x24, 0x4A, 0x97, 0xF8, 0xC1, 0x34, 0x8C, 0x21, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, 0x70, 0x30, 0x01, 0x2B, -+0xDE, 0xD1, 0xF3, 0x6A, 0x49, 0x46, 0x00, 0x22, 0x38, 0x46, 0x98, 0x47, 0x97, 0xF8, 0x4D, 0x30, 0x43, 0xF0, 0x08, 0x03, -+0xDD, 0xE7, 0x00, 0x2C, 0xD2, 0xD0, 0x97, 0xF8, 0x4D, 0x30, 0x43, 0xF0, 0x04, 0x03, 0x87, 0xF8, 0x4D, 0x30, 0xB6, 0xE7, -+0x97, 0xF8, 0x4D, 0x10, 0xC8, 0x06, 0x0B, 0xD5, 0x12, 0x4E, 0x38, 0x46, 0xD6, 0xF8, 0x8C, 0x30, 0x98, 0x47, 0x97, 0xF8, -+0x4D, 0x30, 0x23, 0xF0, 0x10, 0x03, 0x87, 0xF8, 0x4D, 0x30, 0x8A, 0xE7, 0x4E, 0x06, 0x10, 0xD4, 0x54, 0xB9, 0x0B, 0x4E, -+0xD7, 0xE7, 0xA9, 0xEB, 0x03, 0x03, 0x32, 0x2B, 0x9D, 0xD5, 0xC7, 0xF8, 0x48, 0x90, 0x9A, 0xE7, 0x97, 0xF8, 0x4D, 0x10, -+0x41, 0xF0, 0x04, 0x01, 0x87, 0xF8, 0x4D, 0x10, 0x85, 0xE7, 0x03, 0x4E, 0x38, 0x46, 0x33, 0x6F, 0x98, 0x47, 0x72, 0xE7, -+0x30, 0x9D, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x48, 0x9E, 0x17, 0x00, 0x40, 0x9D, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, -+0x4D, 0x4D, 0x95, 0xF8, 0x5A, 0x30, 0x01, 0x2B, 0x2B, 0xD9, 0x90, 0xF8, 0x4D, 0x20, 0x04, 0x46, 0xD0, 0x06, 0x0F, 0xD5, -+0x49, 0x4B, 0x03, 0xF1, 0x54, 0x00, 0x19, 0x7E, 0xFF, 0x29, 0x02, 0xD0, 0xD9, 0x7E, 0xFF, 0x29, 0x3B, 0xD1, 0x1C, 0x33, -+0x98, 0x42, 0xF6, 0xD1, 0x02, 0xF0, 0xEF, 0x02, 0x84, 0xF8, 0x4D, 0x20, 0x91, 0x07, 0x14, 0xD4, 0x53, 0x07, 0x6E, 0x6A, -+0x44, 0xBF, 0x22, 0xF0, 0x04, 0x02, 0x84, 0xF8, 0x4D, 0x20, 0x26, 0xB1, 0xF2, 0x68, 0x04, 0xF1, 0x44, 0x03, 0x9A, 0x42, -+0x09, 0xD0, 0x3B, 0x4B, 0x61, 0x6A, 0xDB, 0x6A, 0x20, 0x46, 0x00, 0x22, 0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0xBD, 0xE8, -+0xF0, 0x81, 0xD4, 0xF8, 0x48, 0x80, 0x67, 0x6A, 0xA8, 0xEB, 0x07, 0x03, 0x00, 0x2B, 0x20, 0xDB, 0xA7, 0xEB, 0x08, 0x03, -+0x00, 0x2B, 0x29, 0xDB, 0x30, 0x4D, 0x6B, 0x6B, 0x98, 0x47, 0xEB, 0x6A, 0x61, 0x6A, 0x20, 0x46, 0x00, 0x22, 0x98, 0x47, -+0x2D, 0x4A, 0xD5, 0xF8, 0x84, 0x30, 0x11, 0x69, 0x20, 0x46, 0x00, 0x22, 0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0x2A, 0x4A, -+0x27, 0x4B, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x01, 0x20, 0xD3, 0xF8, 0x8C, 0x30, 0x98, 0x47, 0x94, 0xF8, 0x4D, 0x20, -+0xBA, 0xE7, 0xE2, 0xF7, 0xA5, 0xFD, 0xA7, 0xF5, 0x7A, 0x67, 0xA7, 0xEB, 0x08, 0x07, 0x38, 0x1A, 0x00, 0x28, 0x0C, 0xDB, -+0x67, 0x6A, 0xD4, 0xF8, 0x48, 0x80, 0xD1, 0xE7, 0xE2, 0xF7, 0x98, 0xFD, 0xA8, 0xF5, 0x7A, 0x68, 0xA8, 0xEB, 0x07, 0x07, -+0x3F, 0x1A, 0x00, 0x2F, 0xCC, 0xDA, 0x67, 0x6A, 0xA7, 0x64, 0xE2, 0xF7, 0x8D, 0xFD, 0x73, 0x68, 0xFF, 0x1A, 0x3F, 0x1A, -+0xB7, 0xF5, 0x7A, 0x6F, 0xB5, 0xD5, 0xA4, 0x6C, 0xE2, 0xF7, 0x84, 0xFD, 0xAB, 0x6C, 0xA4, 0xF5, 0x7A, 0x64, 0x24, 0x1A, -+0xB3, 0x42, 0x74, 0x60, 0xAB, 0xD1, 0x0D, 0x4C, 0x0F, 0x48, 0xD4, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0x0B, 0x4B, 0x71, 0x68, -+0x1B, 0x69, 0xAE, 0x64, 0xCB, 0x1A, 0x14, 0x2B, 0x05, 0xD4, 0xD4, 0xF8, 0xE0, 0x31, 0x09, 0x48, 0xBD, 0xE8, 0xF0, 0x41, -+0x18, 0x47, 0x6B, 0x6C, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0x30, 0x9D, 0x17, 0x00, 0x90, 0x9D, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x18, 0x88, 0x17, 0x00, 0x70, 0x9D, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, -+0x45, 0x4D, 0x95, 0xF8, 0x5A, 0x30, 0x01, 0x2B, 0x04, 0x46, 0x90, 0xF8, 0x4D, 0x30, 0x51, 0xD9, 0x9E, 0x06, 0x04, 0xD5, -+0x41, 0x4B, 0x9B, 0x6F, 0x98, 0x47, 0x94, 0xF8, 0x4D, 0x30, 0x67, 0x6A, 0x13, 0xF0, 0x04, 0x06, 0x3D, 0xD1, 0x99, 0x07, -+0x42, 0xD5, 0x03, 0xF0, 0xFD, 0x03, 0x84, 0xF8, 0x4D, 0x30, 0x95, 0xF8, 0x5B, 0x20, 0x01, 0x3A, 0xD2, 0xB2, 0x85, 0xF8, -+0x5B, 0x20, 0x4A, 0xB9, 0x95, 0xF8, 0x58, 0x20, 0x52, 0x06, 0x5B, 0xD5, 0x34, 0x4B, 0x28, 0x6D, 0xDB, 0x6D, 0x98, 0x47, -+0x94, 0xF8, 0x4D, 0x30, 0xD4, 0xF8, 0x48, 0x80, 0x13, 0xF0, 0x08, 0x02, 0x42, 0xD0, 0x94, 0xF8, 0x62, 0x20, 0x23, 0xF0, -+0x08, 0x03, 0x84, 0xF8, 0x4D, 0x30, 0x00, 0x2A, 0x4A, 0xD0, 0x02, 0x2A, 0x0A, 0xBF, 0xB4, 0xF8, 0xD2, 0x30, 0x4F, 0xF4, -+0xC8, 0x33, 0x9B, 0x02, 0xA8, 0xEB, 0x03, 0x08, 0xB6, 0xB1, 0xEB, 0x6A, 0x26, 0x4A, 0x15, 0x69, 0x93, 0xB9, 0x24, 0x4E, -+0x73, 0x6B, 0x98, 0x47, 0xD6, 0xF8, 0x84, 0x30, 0xA5, 0xEB, 0x08, 0x02, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, -+0x18, 0x47, 0x13, 0xF0, 0x01, 0x02, 0x23, 0xD0, 0x23, 0xF0, 0x04, 0x03, 0x84, 0xF8, 0x4D, 0x30, 0xBD, 0xE8, 0xF0, 0x81, -+0x9A, 0x07, 0xFB, 0xD5, 0x23, 0xF0, 0x02, 0x03, 0x80, 0xF8, 0x4D, 0x30, 0x95, 0xF8, 0x5B, 0x30, 0x01, 0x3B, 0xDB, 0xB2, -+0x85, 0xF8, 0x5B, 0x30, 0x00, 0x2B, 0xEF, 0xD1, 0x95, 0xF8, 0x58, 0x30, 0x5F, 0x06, 0xEB, 0xD5, 0x10, 0x4B, 0x28, 0x6D, -+0xDB, 0x6D, 0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0x0D, 0x4B, 0x39, 0x46, 0xDB, 0x6A, 0x20, 0x46, 0x98, 0x47, 0xC7, 0xE7, -+0x0A, 0x4B, 0x39, 0x46, 0xDB, 0x6A, 0x20, 0x46, 0x98, 0x47, 0x94, 0xF8, 0x4D, 0x30, 0xD3, 0xE7, 0x01, 0x26, 0xA7, 0xE7, -+0x07, 0x4A, 0x94, 0xF8, 0x6C, 0x30, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x03, 0x23, 0x9B, 0x68, 0xB2, 0xE7, 0x00, 0xBF, -+0x30, 0x9D, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x68, 0x65, 0x17, 0x00, 0x28, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x2D, 0xE9, 0xF0, 0x41, 0x07, 0x6C, 0x05, 0x46, 0x3E, 0xDB, 0x24, 0x4E, 0x96, 0xF8, -+0x58, 0x20, 0x12, 0xF0, 0x20, 0x04, 0x03, 0xD1, 0x96, 0xF8, 0x5A, 0x30, 0x01, 0x2B, 0x01, 0xD8, 0xBD, 0xE8, 0xF0, 0x81, -+0x14, 0x23, 0x22, 0x46, 0x21, 0x46, 0x46, 0x20, 0x95, 0xF8, 0x6C, 0x80, 0x04, 0xF0, 0x2E, 0xF8, 0x04, 0x70, 0x95, 0xF8, -+0x63, 0x10, 0x41, 0x70, 0x39, 0x79, 0x19, 0x4A, 0x81, 0x70, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x08, 0x28, 0x7A, 0x79, -+0xC2, 0x70, 0xD8, 0xF8, 0x08, 0x20, 0x15, 0x4D, 0xB7, 0xF8, 0x06, 0xC0, 0x3C, 0x89, 0x79, 0x89, 0x01, 0x81, 0xA2, 0xF5, -+0x9C, 0x52, 0x08, 0x3A, 0xA5, 0xFB, 0x02, 0x52, 0x92, 0x09, 0xA0, 0xF8, 0x04, 0xC0, 0xC4, 0x80, 0xC2, 0x60, 0x3A, 0x7B, -+0x02, 0x74, 0x04, 0xF0, 0x3B, 0xF8, 0x96, 0xF8, 0x58, 0x30, 0x43, 0xF0, 0x20, 0x03, 0x86, 0xF8, 0x58, 0x30, 0xBD, 0xE8, -+0xF0, 0x81, 0x00, 0x2F, 0xBE, 0xD1, 0x07, 0x49, 0x07, 0x48, 0x40, 0xF6, 0x71, 0x52, 0x06, 0xF0, 0xDD, 0xF8, 0xB7, 0xE7, -+0x38, 0x36, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0xD3, 0x4D, 0x62, 0x10, 0x70, 0x79, 0x15, 0x00, -+0xC8, 0xA0, 0x15, 0x00, 0x70, 0x47, 0x00, 0xBF, 0x0A, 0x4B, 0x9B, 0x6A, 0x83, 0xB1, 0x1A, 0x7E, 0x02, 0x2A, 0x05, 0xD8, -+0x00, 0x6C, 0xC0, 0x1A, 0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x70, 0x47, 0x9B, 0x7E, 0x90, 0xF8, 0x63, 0x00, 0x18, 0x1A, -+0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x70, 0x47, 0x18, 0x46, 0x70, 0x47, 0x30, 0x9D, 0x17, 0x00, 0x10, 0x4A, 0x93, 0x6A, -+0xDB, 0xB1, 0x19, 0x7E, 0x02, 0x29, 0x0E, 0xD8, 0x00, 0x6C, 0xC0, 0x1A, 0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x88, 0xB1, -+0xD2, 0x6A, 0x7A, 0xB1, 0x18, 0x7C, 0xA0, 0xF1, 0x06, 0x00, 0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x70, 0x47, 0x90, 0xF8, -+0x63, 0x10, 0x98, 0x7E, 0x40, 0x1A, 0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x00, 0x28, 0xED, 0xD1, 0x70, 0x47, 0x18, 0x46, -+0x70, 0x47, 0x00, 0xBF, 0x30, 0x9D, 0x17, 0x00, 0x0E, 0x4B, 0x9B, 0x6A, 0x23, 0xB1, 0x02, 0x6C, 0x98, 0x88, 0x91, 0x88, -+0x88, 0x42, 0x01, 0xD0, 0x00, 0x20, 0x70, 0x47, 0x58, 0x7B, 0x51, 0x7B, 0x88, 0x42, 0xF9, 0xD1, 0xD8, 0x88, 0xD1, 0x88, -+0x88, 0x42, 0xF5, 0xD1, 0x18, 0x89, 0x11, 0x89, 0x88, 0x42, 0xF1, 0xD1, 0x5B, 0x89, 0x50, 0x89, 0x18, 0x1A, 0xB0, 0xFA, -+0x80, 0xF0, 0x40, 0x09, 0x70, 0x47, 0x00, 0xBF, 0x30, 0x9D, 0x17, 0x00, 0x43, 0x7E, 0xDB, 0xB1, 0x0E, 0x4B, 0x30, 0xB4, -+0x7F, 0x21, 0x03, 0xF5, 0xA4, 0x54, 0x1A, 0x6C, 0x82, 0x42, 0x08, 0xD0, 0x03, 0xF5, 0xA4, 0x63, 0xA3, 0x42, 0xF8, 0xD1, -+0x7F, 0x29, 0x30, 0xBC, 0x18, 0xBF, 0x01, 0x73, 0x70, 0x47, 0x93, 0xF9, 0x66, 0x20, 0x93, 0xF9, 0x65, 0x50, 0xAA, 0x42, -+0xA8, 0xBF, 0x2A, 0x46, 0x91, 0x42, 0xA8, 0xBF, 0x11, 0x46, 0xEB, 0xE7, 0x70, 0x47, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, -+0x70, 0xB5, 0x11, 0x4E, 0x11, 0x4A, 0xD6, 0xF8, 0x4C, 0x32, 0x04, 0x46, 0x98, 0x47, 0xD0, 0xB1, 0x0F, 0x4B, 0x10, 0x4D, -+0x5B, 0x78, 0x00, 0x22, 0x2A, 0x77, 0x23, 0xB1, 0x0E, 0x4A, 0x13, 0x68, 0x43, 0xF0, 0x00, 0x43, 0x13, 0x60, 0x2B, 0x7A, -+0x0B, 0xB1, 0x01, 0x3B, 0x2B, 0x72, 0xD6, 0xF8, 0xD8, 0x31, 0x0A, 0x48, 0x98, 0x47, 0x00, 0x23, 0x6B, 0x77, 0x63, 0x68, -+0x23, 0xF4, 0x01, 0x73, 0x23, 0xF0, 0x02, 0x03, 0x63, 0x60, 0x70, 0xBD, 0x88, 0x1A, 0x17, 0x00, 0xDD, 0xEA, 0x13, 0x00, -+0x4C, 0x36, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, 0x34, 0x04, 0x32, 0x40, 0x28, 0x9E, 0x17, 0x00, 0x70, 0xB5, 0x14, 0x4D, -+0x14, 0x4A, 0xD5, 0xF8, 0x4C, 0x32, 0x04, 0x46, 0x98, 0x47, 0xF8, 0xB1, 0x12, 0x4A, 0x13, 0x4B, 0x52, 0x78, 0x01, 0x21, -+0x19, 0x77, 0x22, 0xB1, 0x11, 0x49, 0x0A, 0x68, 0x22, 0xF0, 0x00, 0x42, 0x0A, 0x60, 0x1A, 0x7A, 0x0A, 0xB1, 0x01, 0x3A, -+0x1A, 0x72, 0x0E, 0x4A, 0x0E, 0x49, 0x12, 0x68, 0x09, 0x69, 0xD0, 0x8E, 0x5C, 0x61, 0x04, 0x26, 0x5E, 0x77, 0x01, 0x44, -+0xD5, 0xF8, 0xE0, 0x21, 0x0A, 0x48, 0x90, 0x47, 0x63, 0x68, 0x43, 0xF4, 0x00, 0x73, 0x63, 0x60, 0x70, 0xBD, 0x00, 0xBF, -+0x88, 0x1A, 0x17, 0x00, 0x3D, 0xEB, 0x13, 0x00, 0x4C, 0x36, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, 0x34, 0x04, 0x32, 0x40, -+0xC8, 0x35, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x28, 0x9E, 0x17, 0x00, 0x38, 0xB5, 0x10, 0x4A, 0x0B, 0x46, 0x0C, 0x46, -+0x05, 0x46, 0x0F, 0x49, 0x02, 0x20, 0x05, 0xF0, 0xB3, 0xFD, 0x0E, 0x4B, 0x0E, 0x4A, 0xD3, 0xF8, 0x4C, 0x32, 0x21, 0x46, -+0x28, 0x46, 0x98, 0x47, 0x30, 0xB1, 0x0C, 0x4A, 0x13, 0x7A, 0x23, 0xB1, 0x01, 0x3B, 0xDB, 0xB2, 0x13, 0x72, 0x03, 0xB1, -+0x38, 0xBD, 0x01, 0x23, 0x13, 0x70, 0x51, 0x88, 0xBD, 0xE8, 0x38, 0x40, 0x00, 0x22, 0x32, 0x20, 0x03, 0xF0, 0x4A, 0xBF, -+0x68, 0xA3, 0x15, 0x00, 0x44, 0xA3, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xB1, 0xEB, 0x13, 0x00, 0x1C, 0x9E, 0x17, 0x00, -+0x38, 0xB5, 0x18, 0x4A, 0x0B, 0x46, 0x0C, 0x46, 0x05, 0x46, 0x17, 0x49, 0x02, 0x20, 0x05, 0xF0, 0x87, 0xFD, 0x16, 0x4B, -+0x16, 0x4A, 0xD3, 0xF8, 0x4C, 0x32, 0x21, 0x46, 0x28, 0x46, 0x98, 0x47, 0xF8, 0xB1, 0x14, 0x48, 0x03, 0x7A, 0xBB, 0xB9, -+0x13, 0x4B, 0x9B, 0x68, 0x63, 0xB1, 0x93, 0xF8, 0x62, 0x20, 0x32, 0xB9, 0x93, 0xF8, 0x64, 0x20, 0x1A, 0xB1, 0x5A, 0x68, -+0x22, 0xF0, 0x0E, 0x02, 0x5A, 0x60, 0x1B, 0x68, 0x00, 0x2B, 0xF2, 0xD1, 0x00, 0x22, 0x02, 0x70, 0x41, 0x88, 0xBD, 0xE8, -+0x38, 0x40, 0x32, 0x20, 0x03, 0xF0, 0x14, 0xBF, 0x01, 0x3B, 0xDB, 0xB2, 0x03, 0x72, 0x00, 0x2B, 0xE2, 0xD0, 0x38, 0xBD, -+0x78, 0xA3, 0x15, 0x00, 0x44, 0xA3, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x09, 0xEC, 0x13, 0x00, 0x1C, 0x9E, 0x17, 0x00, -+0x00, 0x88, 0x17, 0x00, 0x38, 0xB5, 0x11, 0xF4, 0x00, 0x03, 0x04, 0x46, 0x2A, 0xD1, 0x90, 0xF8, 0x6B, 0x00, 0x25, 0x49, -+0x01, 0x30, 0xC0, 0xB2, 0x09, 0x68, 0x84, 0xF8, 0x6B, 0x00, 0x49, 0x78, 0x81, 0x42, 0x29, 0xD0, 0x94, 0xF8, 0x64, 0x50, -+0x00, 0x2D, 0x34, 0xD1, 0x1F, 0x4A, 0x20, 0x4B, 0x52, 0x78, 0x01, 0x21, 0x19, 0x77, 0x22, 0xB1, 0x1E, 0x49, 0x0A, 0x68, -+0x22, 0xF0, 0x00, 0x42, 0x0A, 0x60, 0x1A, 0x7A, 0x0A, 0xB1, 0x01, 0x3A, 0x1A, 0x72, 0x1B, 0x4A, 0x1B, 0x48, 0xD2, 0xF8, -+0xD8, 0x21, 0x00, 0x21, 0x59, 0x77, 0x90, 0x47, 0x63, 0x68, 0x23, 0xF4, 0x00, 0x73, 0x63, 0x60, 0x28, 0x46, 0x38, 0xBD, -+0x28, 0xB1, 0x00, 0x23, 0x01, 0x25, 0x80, 0xF8, 0x6B, 0x30, 0x28, 0x46, 0x38, 0xBD, 0x01, 0x25, 0x28, 0x46, 0x38, 0xBD, -+0x11, 0x49, 0x84, 0xF8, 0x6B, 0x30, 0x4F, 0xF4, 0x80, 0x60, 0x05, 0xF0, 0x11, 0xFD, 0x0C, 0x4B, 0x20, 0x46, 0xD3, 0xF8, -+0xBC, 0x31, 0x01, 0x25, 0x98, 0x47, 0x28, 0x46, 0x38, 0xBD, 0x11, 0x46, 0x1D, 0x46, 0x94, 0xF8, 0x6C, 0x00, 0x22, 0x46, -+0xF1, 0xF7, 0xD0, 0xF9, 0x28, 0x46, 0x38, 0xBD, 0xC8, 0x35, 0x17, 0x00, 0x4C, 0x36, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, -+0x34, 0x04, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x28, 0x9E, 0x17, 0x00, 0x4C, 0xA3, 0x15, 0x00, 0x70, 0xB5, 0x13, 0x4D, -+0x2B, 0x78, 0x13, 0xB3, 0x2B, 0x7F, 0x03, 0xB3, 0x11, 0x4A, 0x12, 0x49, 0x13, 0x68, 0x8C, 0x68, 0x43, 0xF0, 0x04, 0x03, -+0x00, 0x21, 0x13, 0x60, 0x29, 0x72, 0xB4, 0xB1, 0x0E, 0x4E, 0x94, 0xF8, 0x62, 0x30, 0x7B, 0xB9, 0x94, 0xF8, 0x64, 0x30, -+0x63, 0xB1, 0x94, 0xF8, 0x6C, 0x00, 0xFF, 0x28, 0x22, 0x46, 0x07, 0xD0, 0xD6, 0xF8, 0x34, 0x12, 0xF1, 0xF7, 0xA0, 0xF9, -+0x10, 0xB9, 0x2B, 0x7A, 0x01, 0x33, 0x2B, 0x72, 0x24, 0x68, 0x00, 0x2C, 0xE9, 0xD1, 0x70, 0xBD, 0x1C, 0x9E, 0x17, 0x00, -+0x4C, 0x00, 0x32, 0x40, 0x00, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0xB5, 0x12, 0x4D, 0x2B, 0x7F, 0xFB, 0xB9, -+0x11, 0x49, 0x12, 0x48, 0x0A, 0x68, 0x84, 0x68, 0x2B, 0x72, 0x22, 0xF0, 0x04, 0x02, 0x0A, 0x60, 0xB4, 0xB1, 0x0F, 0x4E, -+0x94, 0xF8, 0x62, 0x30, 0x7B, 0xB9, 0x94, 0xF8, 0x64, 0x30, 0x63, 0xB1, 0x94, 0xF8, 0x6C, 0x00, 0xFF, 0x28, 0x22, 0x46, -+0x07, 0xD0, 0xD6, 0xF8, 0x58, 0x12, 0xF1, 0xF7, 0x73, 0xF9, 0x10, 0xB9, 0x2B, 0x7A, 0x01, 0x33, 0x2B, 0x72, 0x24, 0x68, -+0x00, 0x2C, 0xE9, 0xD1, 0x70, 0xBD, 0x00, 0xBF, 0x1C, 0x9E, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, 0x00, 0x88, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x70, 0xB5, 0x2E, 0x4B, 0x2E, 0x4D, 0x1B, 0x68, 0x2E, 0x4A, 0x1B, 0x78, 0xD2, 0xF8, 0xF8, 0x21, -+0x01, 0x2B, 0x6B, 0x68, 0x04, 0x46, 0x03, 0xF0, 0x20, 0x03, 0x44, 0xD0, 0x13, 0x43, 0x0C, 0xBF, 0x01, 0x20, 0x00, 0x20, -+0x94, 0xF8, 0xAC, 0x30, 0x53, 0xB1, 0x27, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x13, 0xB1, 0x94, 0xF8, 0x64, 0x30, 0x33, 0xBB, -+0x00, 0x23, 0x6B, 0x77, 0x63, 0x60, 0x70, 0xBD, 0x21, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x00, 0x2B, 0xF6, 0xD0, 0x94, 0xF8, -+0x64, 0x30, 0x00, 0x2B, 0xF2, 0xD0, 0xC0, 0xB1, 0x1D, 0x4B, 0x1A, 0x68, 0x92, 0x01, 0x05, 0xD4, 0x1B, 0x68, 0x9B, 0x01, -+0x11, 0xD4, 0x95, 0xF8, 0x24, 0x30, 0x73, 0xB1, 0x6B, 0x7F, 0x05, 0x2B, 0x05, 0xD1, 0x63, 0x68, 0x00, 0x22, 0x23, 0xF0, -+0x02, 0x03, 0x63, 0x60, 0x6A, 0x77, 0x15, 0x4B, 0xBD, 0xE8, 0x70, 0x40, 0xD3, 0xF8, 0x50, 0x32, 0x18, 0x47, 0x13, 0x4B, -+0x13, 0x4A, 0x19, 0x68, 0x10, 0x4B, 0xC9, 0x8E, 0x6C, 0x61, 0x01, 0x20, 0x68, 0x77, 0x12, 0x69, 0xD3, 0xF8, 0xE0, 0x31, -+0x0F, 0x48, 0xBD, 0xE8, 0x70, 0x40, 0x11, 0x44, 0x18, 0x47, 0x13, 0x43, 0x01, 0xD0, 0x00, 0x20, 0xBA, 0xE7, 0xE9, 0xF7, -+0x37, 0xFD, 0x00, 0x38, 0x18, 0xBF, 0x01, 0x20, 0xB4, 0xE7, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x74, 0x36, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, -+0x00, 0x10, 0x50, 0x40, 0x28, 0x9E, 0x17, 0x00, 0x10, 0xB5, 0x06, 0x4C, 0x28, 0x22, 0x20, 0x46, 0x00, 0x21, 0xE1, 0xF7, -+0x5F, 0xF9, 0x04, 0x4A, 0x01, 0x23, 0xD2, 0xF8, 0x38, 0x22, 0x22, 0x61, 0x23, 0x77, 0x10, 0xBD, 0x1C, 0x9E, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x10, 0xB5, 0x0C, 0x4C, 0x23, 0x78, 0x33, 0xB9, 0x0B, 0x4B, 0xD3, 0xF8, 0xF8, 0x31, 0x98, 0x47, -+0x08, 0xB9, 0x00, 0x20, 0x10, 0xBD, 0x63, 0x68, 0x00, 0x2B, 0xFA, 0xD1, 0x07, 0x4B, 0x9B, 0x68, 0x13, 0xB9, 0x05, 0xE0, -+0x1B, 0x68, 0x1B, 0xB1, 0x5A, 0x68, 0x00, 0x2A, 0xFA, 0xD0, 0xF0, 0xE7, 0x01, 0x20, 0x10, 0xBD, 0x1C, 0x9E, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x08, 0x4B, 0x09, 0x4A, 0x1B, 0x68, 0x51, 0x80, 0x1B, 0x78, 0x02, 0x2B, -+0x07, 0x4B, 0x03, 0xD0, 0x07, 0x49, 0x00, 0x28, 0x18, 0xBF, 0x0B, 0x46, 0x00, 0x20, 0x10, 0x72, 0x4F, 0xF4, 0x00, 0x01, -+0x18, 0x47, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, 0x09, 0xEC, 0x13, 0x00, 0xB1, 0xEB, 0x13, 0x00, -+0x2D, 0xE9, 0xF0, 0x47, 0x92, 0xF8, 0x6C, 0x30, 0x42, 0x4C, 0x43, 0x4E, 0x51, 0x68, 0x4F, 0xF4, 0x1E, 0x75, 0x91, 0x46, -+0x05, 0xFB, 0x03, 0x43, 0x32, 0x78, 0x1D, 0x8C, 0x21, 0xF0, 0x01, 0x07, 0xC9, 0xF8, 0x04, 0x70, 0x00, 0x2A, 0x49, 0xD0, -+0x04, 0x46, 0x00, 0x28, 0x46, 0xD0, 0x99, 0xF8, 0x6A, 0x30, 0x00, 0x2B, 0x44, 0xD0, 0x00, 0xF1, 0x04, 0x08, 0x98, 0xF8, -+0x00, 0x30, 0x03, 0xF0, 0xFE, 0x03, 0xB3, 0xEB, 0xD5, 0x0F, 0x4F, 0xEA, 0xD5, 0x00, 0x31, 0xD8, 0x61, 0x78, 0x04, 0x39, -+0x19, 0x44, 0x88, 0x42, 0x2C, 0xD8, 0x20, 0x44, 0xC3, 0x1A, 0x05, 0xF0, 0x07, 0x05, 0x59, 0x79, 0x01, 0x23, 0x03, 0xFA, -+0x05, 0xF5, 0x29, 0x42, 0x22, 0xD0, 0x2C, 0x4B, 0x19, 0x68, 0x8A, 0x05, 0x03, 0xD5, 0x19, 0x68, 0x21, 0xF4, 0x00, 0x71, -+0x19, 0x60, 0x29, 0x4C, 0xD4, 0xF8, 0x54, 0x32, 0x98, 0x47, 0x28, 0x48, 0xD9, 0xF8, 0x04, 0x30, 0x00, 0x68, 0x27, 0x49, -+0xD4, 0xF8, 0xE0, 0x41, 0x40, 0x8F, 0x43, 0xF0, 0x04, 0x03, 0xC9, 0xF8, 0x04, 0x30, 0x09, 0x69, 0xC6, 0xF8, 0x14, 0x90, -+0x06, 0x23, 0x73, 0x77, 0x01, 0x44, 0x23, 0x46, 0x20, 0x48, 0xBD, 0xE8, 0xF0, 0x47, 0x18, 0x47, 0xD9, 0xF8, 0x04, 0x30, -+0x23, 0xF0, 0x04, 0x03, 0xC9, 0xF8, 0x04, 0x30, 0xBD, 0xE8, 0xF0, 0x87, 0x03, 0x79, 0x00, 0xF1, 0x04, 0x08, 0xD8, 0x07, -+0x1E, 0xD5, 0x14, 0x4B, 0x47, 0xF0, 0x02, 0x07, 0xC9, 0xF8, 0x04, 0x70, 0x19, 0x68, 0x89, 0x05, 0x03, 0xD5, 0x19, 0x68, -+0x21, 0xF4, 0x00, 0x71, 0x19, 0x60, 0x73, 0x7F, 0x00, 0x2B, 0xA8, 0xD1, 0x0E, 0x4B, 0x0F, 0x49, 0x1B, 0x68, 0x09, 0x69, -+0x1F, 0x8F, 0x0B, 0x4B, 0xC6, 0xF8, 0x14, 0x90, 0x05, 0x20, 0x70, 0x77, 0xD3, 0xF8, 0xE0, 0x31, 0x0A, 0x48, 0x39, 0x44, -+0x98, 0x47, 0x98, 0xE7, 0x21, 0xF0, 0x03, 0x01, 0xC9, 0xF8, 0x04, 0x10, 0x93, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, -+0x1C, 0x9E, 0x17, 0x00, 0x90, 0xB3, 0x33, 0x40, 0x88, 0x1A, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, -+0x28, 0x9E, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x21, 0x4E, 0x14, 0x46, 0x52, 0x68, 0x35, 0x78, 0x22, 0xF0, 0x01, 0x03, -+0x63, 0x60, 0x00, 0x2D, 0x32, 0xD0, 0x0F, 0x46, 0x94, 0xF8, 0x6A, 0x10, 0xA1, 0xB9, 0x00, 0x28, 0x2E, 0xD0, 0x1B, 0x4A, -+0x1B, 0x49, 0x10, 0x68, 0x1B, 0x4A, 0x00, 0x8F, 0xD2, 0xF8, 0xE0, 0x21, 0x43, 0xF0, 0x02, 0x03, 0x63, 0x60, 0x09, 0x69, -+0x74, 0x61, 0x05, 0x23, 0x01, 0x44, 0x73, 0x77, 0x06, 0xF1, 0x0C, 0x00, 0x90, 0x47, 0x63, 0x68, 0xAF, 0xB1, 0x13, 0x4D, -+0x43, 0xF0, 0x04, 0x03, 0x63, 0x60, 0xD5, 0xF8, 0x54, 0x32, 0x98, 0x47, 0x0D, 0x4B, 0x0E, 0x4A, 0x1B, 0x68, 0x11, 0x69, -+0x58, 0x8F, 0x74, 0x61, 0x06, 0x22, 0xD5, 0xF8, 0xE0, 0x31, 0x72, 0x77, 0x01, 0x44, 0xBD, 0xE8, 0xF0, 0x41, 0x0A, 0x48, -+0x18, 0x47, 0x23, 0xF0, 0x04, 0x03, 0x63, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0x22, 0xF0, 0x03, 0x03, 0x00, 0x2F, 0xF6, 0xD0, -+0xDF, 0xE7, 0x00, 0xBF, 0x1C, 0x9E, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0x28, 0x9E, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x21, 0x4D, 0x2B, 0x78, 0xAB, 0xB1, 0x03, 0x79, 0x06, 0x88, 0xDF, 0x07, -+0x14, 0x46, 0x12, 0xD5, 0x6B, 0x7F, 0x05, 0x2B, 0x07, 0xD1, 0x1D, 0x4B, 0x05, 0xF1, 0x0C, 0x00, 0xD3, 0xF8, 0xD8, 0x31, -+0x98, 0x47, 0x00, 0x23, 0x6B, 0x77, 0xB5, 0x04, 0x23, 0xD4, 0x63, 0x68, 0x23, 0xF0, 0x02, 0x03, 0x63, 0x60, 0xBD, 0xE8, -+0xF0, 0x81, 0x88, 0x05, 0xFB, 0xD4, 0x15, 0x4A, 0x15, 0x4B, 0x12, 0x68, 0x1B, 0x69, 0xD1, 0x8E, 0x11, 0x4F, 0x6C, 0x61, -+0x02, 0x22, 0x19, 0x44, 0x6A, 0x77, 0xD7, 0xF8, 0xE0, 0x31, 0x05, 0xF1, 0x0C, 0x00, 0x98, 0x47, 0xB1, 0x04, 0x63, 0x68, -+0x0E, 0xD5, 0x5A, 0x07, 0x5C, 0xBF, 0x43, 0xF0, 0x04, 0x03, 0x63, 0x60, 0xD7, 0xF8, 0x54, 0x32, 0xBD, 0xE8, 0xF0, 0x41, -+0x18, 0x47, 0x94, 0xF8, 0x6A, 0x30, 0x00, 0x2B, 0xDB, 0xD0, 0xD6, 0xE7, 0x23, 0xF0, 0x04, 0x03, 0x63, 0x60, 0xBD, 0xE8, -+0xF0, 0x81, 0x00, 0xBF, 0x1C, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, -+0x38, 0xB5, 0x23, 0x4B, 0x1A, 0x78, 0x00, 0x2A, 0x3F, 0xD0, 0xFF, 0x28, 0x3D, 0xD0, 0xFF, 0x29, 0x3B, 0xD0, 0x20, 0x4A, -+0x20, 0x49, 0x4F, 0xF4, 0x1E, 0x74, 0x04, 0xFB, 0x00, 0x20, 0x4F, 0xF4, 0xA4, 0x64, 0x90, 0xF8, 0x22, 0x20, 0x04, 0xFB, -+0x02, 0x12, 0x92, 0xF8, 0x62, 0x10, 0x00, 0x29, 0x2B, 0xD1, 0x92, 0xF8, 0x64, 0x10, 0x41, 0xB3, 0x18, 0x48, 0x19, 0x49, -+0x00, 0x68, 0x09, 0x69, 0xC5, 0x8E, 0x18, 0x4C, 0x5A, 0x61, 0x03, 0x20, 0x58, 0x77, 0xD4, 0xF8, 0xE0, 0x21, 0x03, 0xF1, -+0x0C, 0x00, 0x29, 0x44, 0x90, 0x47, 0x14, 0x4B, 0x1B, 0x68, 0x5B, 0x07, 0x15, 0xD5, 0x13, 0x4B, 0x93, 0xF8, 0xB6, 0x30, -+0x73, 0xB1, 0x12, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x02, 0x2B, 0x09, 0xD1, 0x10, 0x49, 0x11, 0x4A, 0x0B, 0x68, 0x23, 0xF4, -+0x00, 0x73, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF0, 0x01, 0x03, 0x13, 0x60, 0xD4, 0xF8, 0x54, 0x32, 0x98, 0x47, 0x00, 0x20, -+0x38, 0xBD, 0x00, 0xBF, 0x1C, 0x9E, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, -+0x00, 0x10, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, 0x2C, 0x19, 0x17, 0x00, 0x74, 0x36, 0x17, 0x00, -+0x90, 0xB3, 0x33, 0x40, 0x8C, 0x00, 0x32, 0x40, 0x3B, 0x4A, 0xDF, 0xF8, 0x1C, 0xC1, 0x13, 0x68, 0x3A, 0x49, 0xF0, 0xB5, -+0x3A, 0x4F, 0x3B, 0x4C, 0xB7, 0xF8, 0xB2, 0x00, 0x3A, 0x4D, 0x3B, 0x4E, 0x43, 0xF0, 0x80, 0x43, 0x13, 0x60, 0x23, 0x68, -+0x39, 0x4A, 0x43, 0xF0, 0x80, 0x53, 0x23, 0x60, 0xDC, 0xF8, 0x00, 0x30, 0x23, 0xF4, 0x70, 0x23, 0xCC, 0xF8, 0x00, 0x30, -+0xDC, 0xF8, 0x00, 0x30, 0x23, 0xF0, 0xFF, 0x03, 0x43, 0xF0, 0x10, 0x03, 0xCC, 0xF8, 0x00, 0x30, 0x2B, 0x68, 0x23, 0xF0, -+0xFC, 0x03, 0x43, 0xF0, 0x10, 0x03, 0x2B, 0x60, 0x0B, 0x68, 0x40, 0x09, 0x00, 0xF1, 0x20, 0x0C, 0xC3, 0xF3, 0x15, 0x03, -+0x43, 0xEA, 0x8C, 0x53, 0x0B, 0x60, 0x83, 0xB0, 0x33, 0x68, 0x29, 0x49, 0x1B, 0x78, 0xCD, 0xF8, 0x00, 0xC0, 0x02, 0x20, -+0x05, 0xF0, 0x0A, 0xFA, 0x32, 0x68, 0x13, 0x78, 0x01, 0x2B, 0x15, 0xD0, 0x02, 0x2B, 0x11, 0xD1, 0x23, 0x48, 0x24, 0x49, -+0x03, 0x68, 0x24, 0x4C, 0x1D, 0x4A, 0x43, 0xF4, 0x80, 0x33, 0x03, 0x60, 0x0B, 0x68, 0x3F, 0x20, 0x23, 0xF0, 0x00, 0x73, -+0x0B, 0x60, 0x20, 0x60, 0x13, 0x68, 0x23, 0xF0, 0x01, 0x03, 0x13, 0x60, 0x03, 0xB0, 0xF0, 0xBD, 0x97, 0xF8, 0xB5, 0x10, -+0x69, 0xB1, 0x19, 0x49, 0x19, 0x48, 0x0B, 0x68, 0x23, 0xF0, 0x00, 0x73, 0x0B, 0x60, 0x2B, 0x68, 0x24, 0x21, 0x43, 0xF4, -+0x00, 0x13, 0x2B, 0x60, 0x01, 0x60, 0x13, 0x78, 0xD8, 0xE7, 0x12, 0x48, 0x12, 0x4E, 0x01, 0x68, 0x12, 0x4D, 0x41, 0xF0, -+0x00, 0x71, 0x01, 0x60, 0x04, 0x21, 0x31, 0x60, 0x2B, 0x60, 0x23, 0x68, 0x23, 0xF4, 0x80, 0x23, 0x23, 0xF0, 0x01, 0x03, -+0x23, 0x60, 0x13, 0x78, 0xC6, 0xE7, 0x00, 0xBF, 0x90, 0x00, 0x32, 0x40, 0xF0, 0x00, 0x32, 0x40, 0x2C, 0x19, 0x17, 0x00, -+0x74, 0x80, 0x32, 0x40, 0x6C, 0x00, 0x32, 0x40, 0x74, 0x36, 0x17, 0x00, 0x88, 0xA3, 0x15, 0x00, 0x5C, 0xA3, 0x15, 0x00, -+0x44, 0x00, 0x32, 0x40, 0x4C, 0x00, 0x32, 0x40, 0x98, 0x80, 0x32, 0x40, 0x70, 0x80, 0x32, 0x40, 0x78, 0x00, 0x32, 0x40, -+0x15, 0x48, 0x16, 0x4A, 0x16, 0x49, 0x38, 0xB5, 0x03, 0x68, 0x43, 0xF0, 0x00, 0x73, 0x03, 0x60, 0x02, 0x20, 0x05, 0xF0, -+0xA7, 0xF9, 0x13, 0x4B, 0x9B, 0x7C, 0x23, 0xB9, 0x12, 0x4A, 0x13, 0x68, 0x23, 0xF0, 0x01, 0x03, 0x13, 0x60, 0x11, 0x4C, -+0x11, 0x48, 0x23, 0x68, 0x0E, 0x49, 0x11, 0x4D, 0x11, 0x4A, 0x23, 0xF4, 0x80, 0x33, 0x23, 0x60, 0x03, 0x68, 0x23, 0xF0, -+0x80, 0x43, 0x03, 0x60, 0x0B, 0x68, 0x00, 0x20, 0x23, 0xF0, 0x80, 0x53, 0x0B, 0x60, 0x28, 0x60, 0x13, 0x68, 0x23, 0xF0, -+0x01, 0x03, 0x13, 0x60, 0x38, 0xBD, 0x00, 0xBF, 0x4C, 0x00, 0x32, 0x40, 0x98, 0xA3, 0x15, 0x00, 0xCC, 0xB5, 0x15, 0x00, -+0x00, 0x88, 0x17, 0x00, 0x74, 0x80, 0x32, 0x40, 0x44, 0x00, 0x32, 0x40, 0x90, 0x00, 0x32, 0x40, 0x98, 0x80, 0x32, 0x40, -+0x6C, 0x00, 0x32, 0x40, 0x70, 0xB5, 0x90, 0xF8, 0x72, 0x30, 0x01, 0x2B, 0x04, 0x46, 0x11, 0xD0, 0x02, 0x2B, 0x00, 0xD0, -+0x70, 0xBD, 0x0C, 0x4D, 0x41, 0x6F, 0x01, 0x23, 0x80, 0xF8, 0x72, 0x30, 0xD5, 0xF8, 0xE0, 0x31, 0x60, 0x30, 0x98, 0x47, -+0xD5, 0xF8, 0x18, 0x32, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, 0x04, 0x4B, 0x00, 0x22, 0x80, 0xF8, 0x72, 0x20, -+0xBD, 0xE8, 0x70, 0x40, 0xD3, 0xF8, 0x18, 0x32, 0x18, 0x47, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x4F, 0xF0, 0x00, 0x0C, 0x4F, 0xF0, 0x01, 0x0E, 0x83, 0xB0, 0x06, 0x46, 0x04, 0x46, 0x00, 0xF1, 0x60, 0x05, 0x03, 0x46, -+0x67, 0x46, 0x71, 0x46, 0x1A, 0x7C, 0x02, 0x2A, 0x13, 0xD1, 0xDA, 0x7C, 0x01, 0x2A, 0x10, 0xD8, 0x96, 0xF8, 0x87, 0x20, -+0x32, 0xB1, 0x93, 0xF8, 0x21, 0x20, 0x1A, 0xB1, 0x93, 0xF8, 0x20, 0x20, 0x01, 0x2A, 0x06, 0xD0, 0xDA, 0x68, 0x00, 0x29, -+0x00, 0xF0, 0xC0, 0x80, 0x01, 0x37, 0x94, 0x46, 0x00, 0x21, 0x30, 0x33, 0x9D, 0x42, 0xE5, 0xD1, 0x01, 0x22, 0x8E, 0x46, -+0x33, 0x46, 0x4F, 0xF0, 0x00, 0x09, 0x00, 0x92, 0xA0, 0x46, 0x1A, 0x7C, 0x02, 0x2A, 0x1D, 0xD1, 0xD9, 0x7C, 0x01, 0x29, -+0x1A, 0xD9, 0x96, 0xF8, 0x87, 0x20, 0x32, 0xB1, 0x93, 0xF8, 0x21, 0x20, 0x1A, 0xB1, 0x93, 0xF8, 0x20, 0x20, 0x01, 0x2A, -+0x10, 0xD0, 0xD3, 0xE9, 0x06, 0x04, 0xDA, 0x68, 0x04, 0xEB, 0x02, 0x0A, 0xAA, 0xEB, 0x00, 0x00, 0xBE, 0xF1, 0x00, 0x0F, -+0x42, 0xD0, 0x00, 0x21, 0x00, 0x91, 0x01, 0x37, 0x81, 0x46, 0x94, 0x46, 0x4F, 0xF0, 0x00, 0x0E, 0x30, 0x33, 0x9D, 0x42, -+0xDB, 0xD1, 0x01, 0x96, 0x44, 0x46, 0x00, 0x9E, 0x18, 0xE0, 0x00, 0x2F, 0x5F, 0xD1, 0xA1, 0xEB, 0x09, 0x02, 0x00, 0x2A, -+0x58, 0xDB, 0xAC, 0xEB, 0x03, 0x02, 0x00, 0x2A, 0x0B, 0xDB, 0xA3, 0xEB, 0x09, 0x00, 0xAC, 0xEB, 0x01, 0x02, 0x39, 0xEA, -+0x20, 0x09, 0x28, 0xBF, 0x99, 0x46, 0x3C, 0xEA, 0x22, 0x0C, 0x28, 0xBF, 0x8C, 0x46, 0x30, 0x34, 0xA5, 0x42, 0x0F, 0xD0, -+0x23, 0x7C, 0x01, 0x2B, 0xF9, 0xD1, 0xE3, 0x68, 0xA1, 0x69, 0x19, 0x44, 0xBE, 0xF1, 0x00, 0x0F, 0xDD, 0xD0, 0x30, 0x34, -+0x00, 0x26, 0xA5, 0x42, 0x99, 0x46, 0x8C, 0x46, 0xB6, 0x46, 0xEF, 0xD1, 0x33, 0x46, 0x01, 0x9E, 0xC6, 0xF8, 0x80, 0xC0, -+0x0B, 0xB1, 0x0C, 0xF1, 0x0A, 0x09, 0xC6, 0xF8, 0x7C, 0x90, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xA0, 0xEB, 0x0C, 0x0A, -+0xBA, 0xF1, 0x00, 0x0F, 0x80, 0xF2, 0x88, 0x80, 0xA4, 0xEB, 0x02, 0x0B, 0x02, 0xEB, 0x0C, 0x0A, 0x01, 0x39, 0x83, 0x44, -+0xA0, 0xEB, 0x0A, 0x0A, 0x01, 0xE0, 0x01, 0x39, 0xB2, 0xD0, 0x0B, 0xEB, 0x02, 0x00, 0x22, 0x44, 0x1A, 0xEB, 0x02, 0x0F, -+0xF7, 0xD4, 0xAC, 0xEB, 0x02, 0x04, 0x3C, 0xEA, 0x24, 0x0C, 0x28, 0xBF, 0x94, 0x46, 0x01, 0x29, 0x3D, 0xD0, 0x62, 0x46, -+0x00, 0x99, 0x00, 0x29, 0x99, 0xD1, 0xA0, 0xEB, 0x09, 0x01, 0x10, 0xEA, 0x21, 0x00, 0x38, 0xBF, 0x48, 0x46, 0x94, 0xE7, -+0x99, 0x46, 0x8C, 0x46, 0xB3, 0xE7, 0xA1, 0xEB, 0x0C, 0x02, 0x00, 0x2A, 0x94, 0xF8, 0x13, 0x80, 0x61, 0xDA, 0x08, 0xF1, -+0xFF, 0x30, 0xB8, 0xF1, 0x00, 0x0F, 0xA8, 0xD0, 0xD4, 0xF8, 0x1C, 0xB0, 0x9A, 0x46, 0x03, 0xE0, 0x42, 0x1E, 0x00, 0x28, -+0xA1, 0xD0, 0x10, 0x46, 0xDA, 0x44, 0x01, 0xEB, 0x0A, 0x08, 0xA8, 0xEB, 0x0C, 0x02, 0xD2, 0x1A, 0x00, 0x2A, 0xA8, 0xEB, -+0x03, 0x08, 0xF1, 0xDB, 0xA6, 0xB1, 0xAC, 0xEB, 0x0A, 0x03, 0x00, 0x2B, 0x29, 0xDB, 0x58, 0xB3, 0xE3, 0x69, 0xC4, 0x46, -+0x0A, 0xEB, 0x03, 0x09, 0x00, 0x26, 0x8A, 0xE7, 0xAC, 0xEB, 0x02, 0x01, 0x12, 0xEA, 0x21, 0x02, 0x38, 0xBF, 0x62, 0x46, -+0x38, 0xE7, 0x48, 0x46, 0x62, 0x46, 0x5E, 0xE7, 0xA9, 0xEB, 0x0A, 0x03, 0x00, 0x2B, 0x11, 0xDB, 0xAC, 0xEB, 0x0A, 0x03, -+0x00, 0x2B, 0x15, 0xDB, 0xA8, 0xEB, 0x09, 0x03, 0x00, 0x2B, 0x14, 0xDB, 0x1B, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x29, 0xDB, 0xE3, 0x69, 0xC4, 0x46, 0x0A, 0xEB, 0x03, 0x09, 0x4F, 0xF0, 0x00, 0x0E, 0x67, 0xE7, 0xD1, 0x46, -+0x00, 0x26, 0x64, 0xE7, 0xC4, 0x46, 0x62, 0xE7, 0xD1, 0x46, 0xB6, 0x46, 0x5F, 0xE7, 0x01, 0x28, 0x15, 0xDD, 0xE3, 0x69, -+0x9A, 0x44, 0xAA, 0xEB, 0x09, 0x03, 0xC4, 0x46, 0x39, 0xEA, 0x23, 0x09, 0x28, 0xBF, 0xD1, 0x46, 0xB6, 0x46, 0x52, 0xE7, -+0xAC, 0xEB, 0x02, 0x01, 0x12, 0xEA, 0x21, 0x02, 0x38, 0xBF, 0x62, 0x46, 0x8A, 0xE7, 0x40, 0x46, 0x9A, 0x46, 0x88, 0x46, -+0xB0, 0xE7, 0xC4, 0x46, 0xB6, 0x46, 0x44, 0xE7, 0x04, 0x49, 0x05, 0x48, 0x40, 0xF2, 0x4D, 0x12, 0x05, 0xF0, 0x64, 0xFA, -+0xCE, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x03, 0x7C, 0x02, 0x2B, 0x83, 0xB0, 0x04, 0x46, 0x69, 0xD0, 0x90, 0xF8, 0x40, 0x30, 0x02, 0x2B, 0x54, 0xD0, 0x94, 0xF8, -+0x73, 0xA0, 0xBA, 0xF1, 0x00, 0x0F, 0x18, 0xD1, 0x94, 0xF8, 0x85, 0x30, 0x01, 0x2B, 0x40, 0xF0, 0xD2, 0x80, 0x94, 0xF8, -+0x70, 0x30, 0x00, 0x2B, 0x40, 0xF0, 0xB8, 0x80, 0xDF, 0xF8, 0x24, 0x93, 0xC3, 0x4B, 0x94, 0xF8, 0x71, 0x20, 0xD3, 0xF8, -+0x5C, 0x34, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x02, 0x90, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x18, 0x47, 0x94, 0xF8, -+0x72, 0x30, 0x01, 0x2B, 0x00, 0xF0, 0x54, 0x81, 0x94, 0xF8, 0x70, 0x30, 0x01, 0x2B, 0x00, 0xF0, 0xB9, 0x81, 0xB9, 0x4A, -+0x92, 0xF8, 0x00, 0xA0, 0xBA, 0xF1, 0x00, 0x0F, 0x00, 0xF0, 0xA8, 0x80, 0x52, 0x68, 0x11, 0x07, 0x00, 0xF1, 0xD4, 0x81, -+0x94, 0xF8, 0x85, 0x30, 0x00, 0x2B, 0x00, 0xF0, 0x8F, 0x80, 0x94, 0xF8, 0x71, 0x80, 0xDF, 0xF8, 0xD0, 0x92, 0x02, 0x23, -+0x0C, 0x21, 0x00, 0x22, 0x4D, 0x20, 0x03, 0xF0, 0x15, 0xF9, 0x01, 0x25, 0x94, 0xF8, 0x71, 0x20, 0x02, 0x70, 0x45, 0x70, -+0x03, 0xF0, 0x3E, 0xF9, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x08, 0x93, 0x00, 0x22, 0x84, 0xF8, 0x85, 0x20, 0x18, 0x6C, -+0x29, 0x46, 0xFF, 0xF7, 0x15, 0xF9, 0x55, 0xE0, 0x90, 0xF8, 0x87, 0x30, 0x00, 0x2B, 0x7B, 0xD0, 0xFF, 0x23, 0x00, 0x21, -+0x94, 0xF8, 0x51, 0x20, 0x00, 0x2A, 0x6F, 0xD0, 0x94, 0xF8, 0x50, 0x20, 0x01, 0x2A, 0x6B, 0xD1, 0x00, 0x29, 0x9A, 0xD0, -+0x11, 0xE0, 0x90, 0xF8, 0x87, 0x30, 0x00, 0x2B, 0x5F, 0xD0, 0x90, 0xF8, 0x21, 0x30, 0x23, 0xB1, 0x90, 0xF8, 0x20, 0x30, -+0x01, 0x2B, 0x00, 0xF0, 0xA6, 0x81, 0x94, 0xF8, 0x40, 0x20, 0x23, 0x7D, 0x02, 0x2A, 0x00, 0xF0, 0x9E, 0x81, 0x01, 0x2B, -+0xB8, 0xD0, 0x94, 0xF8, 0x86, 0xA0, 0xBA, 0xF1, 0x00, 0x0F, 0x40, 0xF0, 0x0D, 0x81, 0x94, 0xF8, 0x72, 0x50, 0x94, 0xF8, -+0x85, 0x30, 0xA5, 0xF1, 0x01, 0x06, 0xB6, 0xFA, 0x86, 0xF6, 0x76, 0x09, 0xB3, 0x42, 0x00, 0xF0, 0x4C, 0x81, 0x02, 0x23, -+0x0C, 0x21, 0x52, 0x46, 0x4D, 0x20, 0x94, 0xF8, 0x71, 0x80, 0xDF, 0xF8, 0x20, 0x92, 0x03, 0xF0, 0xC1, 0xF8, 0x6F, 0x1E, -+0x18, 0xBF, 0x01, 0x27, 0x94, 0xF8, 0x71, 0x20, 0x02, 0x70, 0x47, 0x70, 0x03, 0xF0, 0xE8, 0xF8, 0x4F, 0xF4, 0xA4, 0x63, -+0x03, 0xFB, 0x08, 0x93, 0x84, 0xF8, 0x85, 0x60, 0x18, 0x6C, 0x39, 0x46, 0xFF, 0xF7, 0xC0, 0xF8, 0x01, 0x2D, 0x4C, 0xD0, -+0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x08, 0x93, 0x93, 0xF8, 0x62, 0x20, 0x02, 0x2A, 0x00, 0xF0, 0xF1, 0x80, 0x94, 0xF8, -+0x70, 0x30, 0x7B, 0xB9, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x08, 0x98, 0x98, 0xF8, 0x6C, 0x30, 0xFF, 0x2B, 0x07, 0xD0, -+0x6E, 0x4A, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x03, 0x23, 0x01, 0x22, 0x83, 0xF8, 0x24, 0x20, 0x03, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0x90, 0xF8, 0x40, 0x20, 0x03, 0x7D, 0x02, 0x2A, 0xA8, 0xD1, 0x94, 0xF8, 0x44, 0x20, 0x93, 0x42, 0x28, 0xBF, -+0x13, 0x46, 0xA2, 0xE7, 0xFF, 0x23, 0xF7, 0xE7, 0x94, 0xF8, 0x85, 0x20, 0x01, 0x2A, 0x3F, 0xF4, 0x30, 0xAF, 0x94, 0xF8, -+0x71, 0x80, 0xDF, 0xF8, 0x88, 0x91, 0x02, 0x23, 0x0C, 0x21, 0x00, 0x22, 0x4D, 0x20, 0x03, 0xF0, 0x71, 0xF8, 0x00, 0x25, -+0x94, 0xF8, 0x71, 0x20, 0x02, 0x70, 0x45, 0x70, 0x03, 0xF0, 0x9A, 0xF8, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x08, 0x93, -+0x01, 0x22, 0x84, 0xF8, 0x85, 0x20, 0x18, 0x6C, 0x29, 0x46, 0xFF, 0xF7, 0x71, 0xF8, 0x94, 0xF8, 0x70, 0xE0, 0xBE, 0xF1, -+0x00, 0x0F, 0x40, 0xF0, 0xD4, 0x80, 0x4F, 0xF4, 0xA4, 0x67, 0x07, 0xFB, 0x08, 0x97, 0x97, 0xF8, 0x6C, 0x10, 0xFF, 0x29, -+0x00, 0xF0, 0xF0, 0x80, 0x4A, 0x4D, 0x01, 0x94, 0x4F, 0xF4, 0x1E, 0x7B, 0xA4, 0x23, 0x0B, 0xFB, 0x01, 0xF0, 0x03, 0xFB, -+0x08, 0xF3, 0x05, 0xF5, 0x16, 0x7B, 0x2E, 0x18, 0x9E, 0x33, 0x58, 0x44, 0x00, 0x90, 0x09, 0xEB, 0xC3, 0x0B, 0x4F, 0xF0, -+0x4F, 0x0C, 0x46, 0x20, 0x1C, 0xFB, 0x01, 0x01, 0x5C, 0x46, 0x40, 0x4A, 0xDD, 0xF8, 0x00, 0xB0, 0x86, 0xF8, 0x24, 0xE0, -+0x05, 0xEB, 0xC1, 0x05, 0xD6, 0xF8, 0x08, 0x12, 0x39, 0xB3, 0xEF, 0xF3, 0x10, 0x81, 0xCB, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x39, 0x4B, 0x01, 0x21, 0x19, 0x60, 0x11, 0x68, 0xA5, 0xF1, 0x28, 0x00, 0x4B, 0x1C, 0xA4, 0xF1, 0x28, 0x01, 0x13, 0x60, -+0x00, 0x90, 0x03, 0xF0, 0x9D, 0xFD, 0xD6, 0xF8, 0x08, 0x12, 0xD6, 0xF8, 0x0C, 0x32, 0x00, 0x98, 0xC7, 0xF8, 0xC8, 0x14, -+0xC7, 0xF8, 0xCC, 0x34, 0x03, 0xF0, 0x9C, 0xFC, 0x2C, 0x4A, 0x11, 0x68, 0x48, 0x1E, 0x31, 0xB1, 0x2B, 0x4B, 0x10, 0x60, -+0x19, 0x68, 0x10, 0xB9, 0x00, 0x29, 0x40, 0xF0, 0xB5, 0x80, 0xD6, 0xF8, 0x30, 0x32, 0x20, 0x46, 0x29, 0x46, 0x08, 0x36, -+0x08, 0x34, 0x08, 0x37, 0x2B, 0xB1, 0x03, 0xF0, 0x7D, 0xFD, 0x28, 0x46, 0x03, 0xF0, 0x84, 0xFC, 0x20, 0x4A, 0x08, 0x35, -+0x5D, 0x45, 0xC3, 0xD1, 0x01, 0x9C, 0x40, 0x20, 0x03, 0xF0, 0xDE, 0xFB, 0x94, 0xF8, 0x70, 0x20, 0x4F, 0xF4, 0xA4, 0x63, -+0x03, 0xFB, 0x08, 0x98, 0x98, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0x13, 0xD0, 0x00, 0x2A, 0x7F, 0xF4, 0x55, 0xAF, 0xBA, 0xF1, -+0x00, 0x0F, 0x7F, 0xF4, 0x51, 0xAF, 0x99, 0xE6, 0x94, 0xF8, 0x85, 0x30, 0x01, 0x2B, 0x3F, 0xF4, 0x8E, 0xAE, 0x94, 0xF8, -+0x71, 0x80, 0xDF, 0xF8, 0x48, 0x90, 0x4F, 0xF0, 0x00, 0x0A, 0x5C, 0xE7, 0xD8, 0xF8, 0x04, 0x30, 0x43, 0xF0, 0x20, 0x03, -+0xC8, 0xF8, 0x04, 0x30, 0x00, 0x2A, 0x7F, 0xF4, 0x3B, 0xAF, 0xE4, 0xE7, 0x94, 0xF8, 0x85, 0x30, 0x01, 0x2B, 0x3F, 0xF4, -+0x35, 0xAF, 0x94, 0xF8, 0x71, 0x80, 0xDF, 0xF8, 0x1C, 0x90, 0x4F, 0xF0, 0x01, 0x0A, 0x46, 0xE7, 0x88, 0x1A, 0x17, 0x00, -+0x1C, 0x9E, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x3C, 0x49, 0x5A, 0x68, 0x49, 0x68, 0x22, 0xF0, 0x20, 0x02, 0x00, 0x29, 0x5A, 0x60, 0x7F, 0xF7, 0x06, 0xAF, 0xEF, 0xF3, -+0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x36, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x36, 0x4D, 0x2B, 0x68, 0x04, 0x20, -+0x01, 0x33, 0x2B, 0x60, 0xEE, 0xF7, 0x1C, 0xFF, 0x4F, 0xF0, 0x80, 0x41, 0x04, 0x20, 0xEE, 0xF7, 0xB7, 0xFF, 0x2B, 0x68, -+0x00, 0x2B, 0x3F, 0xF4, 0xEE, 0xAE, 0x2D, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x00, 0x2B, 0x7F, 0xF4, 0xE7, 0xAE, -+0x00, 0x2A, 0x3F, 0xF4, 0xE4, 0xAE, 0x62, 0xB6, 0xE1, 0xE6, 0x40, 0x20, 0x03, 0xF0, 0x6E, 0xFB, 0x94, 0xF8, 0x70, 0x20, -+0x8E, 0xE7, 0x94, 0xF8, 0x70, 0x30, 0x00, 0x2B, 0x7F, 0xF4, 0xEA, 0xAE, 0x01, 0x2D, 0x7F, 0xF4, 0xE7, 0xAE, 0x2D, 0xE6, -+0x94, 0xF8, 0x71, 0x80, 0xDF, 0xF8, 0x80, 0x90, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x08, 0x93, 0x93, 0xF8, 0xDE, 0x20, -+0x93, 0xF8, 0xC2, 0x34, 0x9A, 0x42, 0x20, 0xD0, 0x94, 0xF8, 0x85, 0x30, 0x01, 0x2B, 0x3F, 0xF4, 0xD3, 0xAE, 0x4F, 0xF0, -+0x00, 0x0A, 0xE8, 0xE6, 0x97, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0x7F, 0xF4, 0x76, 0xAF, 0x7B, 0x68, 0x43, 0xF0, 0x20, 0x03, -+0x7B, 0x60, 0xBA, 0xF1, 0x00, 0x0F, 0x7F, 0xF4, 0xC3, 0xAE, 0x0B, 0xE6, 0x62, 0xB6, 0x48, 0xE7, 0x94, 0xF8, 0x85, 0x20, -+0x01, 0x2A, 0x7F, 0xF4, 0x70, 0xAF, 0x00, 0x2B, 0x3F, 0xF4, 0x00, 0xAE, 0xB6, 0xE6, 0x94, 0xF8, 0x85, 0x30, 0x00, 0x2B, -+0x7F, 0xF4, 0x27, 0xAE, 0xB0, 0xE6, 0x01, 0x21, 0x42, 0xE6, 0x90, 0xF8, 0x40, 0x30, 0x02, 0x2B, 0x7F, 0xF4, 0xE3, 0xAD, -+0x3A, 0xE6, 0x00, 0xBF, 0xD8, 0x9C, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0xF4, 0x92, 0x47, 0x7C, 0xB6, 0x49, 0x90, 0xF8, 0x10, 0xB0, 0x8C, 0x23, 0x03, 0xFB, -+0x07, 0x93, 0x83, 0xB0, 0x93, 0xF8, 0x71, 0x20, 0x93, 0xF8, 0x70, 0x30, 0x00, 0x92, 0x07, 0xEB, 0x87, 0x06, 0x4F, 0xF4, -+0xA4, 0x6A, 0xC6, 0xEB, 0xC6, 0x06, 0x01, 0x2B, 0x05, 0x46, 0x0A, 0xFB, 0x02, 0x1A, 0x09, 0xEB, 0x86, 0x06, 0x00, 0xF0, -+0x0B, 0x81, 0xAA, 0x4B, 0xC4, 0x6A, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xD3, 0x80, 0xDA, 0xF8, -+0x7C, 0x30, 0xE4, 0x1A, 0xA4, 0x4B, 0xA5, 0x49, 0xDF, 0xF8, 0x94, 0x82, 0xBB, 0xF1, 0x01, 0x0F, 0x17, 0xD0, 0xBB, 0xF1, -+0x02, 0x0F, 0x00, 0xF0, 0x82, 0x80, 0x1A, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x7F, 0xDB, 0xD8, 0xF8, 0x10, 0x20, -+0xA2, 0x1A, 0xA2, 0xF5, 0x9C, 0x52, 0x08, 0x3A, 0x00, 0x2A, 0x80, 0xF2, 0xE9, 0x80, 0xBB, 0xF1, 0x00, 0x0F, 0xE7, 0xD1, -+0xDF, 0xF8, 0x70, 0x82, 0x20, 0xE0, 0xA8, 0x69, 0xDF, 0xF8, 0x68, 0x82, 0x95, 0x4B, 0x1B, 0x69, 0x04, 0x44, 0xE3, 0x1A, -+0xA3, 0xF5, 0x9C, 0x53, 0x08, 0x3B, 0x00, 0x2B, 0x80, 0xF2, 0xFA, 0x80, 0xEA, 0x7C, 0xFF, 0x2A, 0x1B, 0xD0, 0x01, 0x3A, -+0xD2, 0xB2, 0xEA, 0x74, 0xBA, 0xB9, 0x8C, 0x23, 0x03, 0xFB, 0x07, 0x97, 0x97, 0xF8, 0x70, 0x30, 0x01, 0x2B, 0x5D, 0xD0, -+0xD8, 0xF8, 0xE8, 0x31, 0x28, 0x46, 0x98, 0x47, 0x87, 0x4B, 0x1B, 0x69, 0xD8, 0xF8, 0x1C, 0x32, 0x30, 0x46, 0x98, 0x47, -+0xD8, 0xF8, 0x18, 0x32, 0x30, 0x46, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x18, 0x47, 0x4F, 0xF0, 0x8C, 0x0E, 0x0E, 0xFB, -+0x07, 0x9E, 0xD5, 0xE9, 0x06, 0x0B, 0x9E, 0xF8, 0x70, 0x30, 0xAB, 0xEB, 0x00, 0x01, 0x01, 0x2B, 0x0C, 0x44, 0x47, 0xD0, -+0x7A, 0x4A, 0x12, 0x69, 0xA2, 0x1A, 0xA2, 0xF5, 0x9C, 0x52, 0x08, 0x3A, 0x00, 0x2A, 0xA8, 0xBF, 0x4F, 0xF0, 0x01, 0x0B, -+0xBE, 0xDB, 0x53, 0xB9, 0x72, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xB0, 0x80, 0xDA, 0xF8, -+0x7C, 0x30, 0x23, 0x44, 0xEB, 0x62, 0x21, 0x46, 0xD8, 0xF8, 0xE0, 0x31, 0x28, 0x46, 0x98, 0x47, 0x85, 0xF8, 0x10, 0xB0, -+0xD8, 0xF8, 0x1C, 0x32, 0x30, 0x46, 0x98, 0x47, 0xD8, 0xF8, 0x18, 0x32, 0x30, 0x46, 0x98, 0x47, 0x00, 0x9A, 0x11, 0x46, -+0x63, 0x4A, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x01, 0x23, 0x93, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0x00, 0xF0, 0xA4, 0x80, -+0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xDF, 0xF8, 0x90, 0x81, 0x9B, 0xE7, 0x5F, 0x48, 0x4F, 0xF4, 0x31, 0x72, 0x04, 0xF0, -+0x53, 0xFF, 0x5A, 0x4B, 0x5A, 0x49, 0x77, 0xE7, 0xD8, 0xF8, 0x08, 0x32, 0xA9, 0x7C, 0x50, 0x46, 0x98, 0x47, 0x58, 0x4B, -+0x1B, 0x69, 0x9F, 0xE7, 0x9E, 0xF8, 0x84, 0x10, 0x00, 0x29, 0x36, 0xD0, 0xA9, 0x6A, 0x01, 0x91, 0x69, 0x6A, 0x01, 0xEB, -+0x0B, 0x0C, 0x01, 0x99, 0x01, 0x39, 0xC5, 0xE9, 0x09, 0xC1, 0x00, 0x29, 0x5E, 0xD1, 0x2A, 0x75, 0xBB, 0xF1, 0x00, 0x0F, -+0x05, 0xD0, 0x4F, 0xF0, 0x00, 0x43, 0xB3, 0xFB, 0xFB, 0xF3, 0x01, 0x3B, 0xAB, 0x62, 0x00, 0x9B, 0x19, 0x46, 0x46, 0x4B, -+0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x01, 0x32, 0xD8, 0xF8, 0x90, 0x31, 0x92, 0xF8, 0x63, 0x00, 0x03, 0x21, 0x98, 0x47, -+0x43, 0x4B, 0x1B, 0x69, 0xE3, 0x1A, 0xA3, 0xF5, 0x9C, 0x53, 0x08, 0x3B, 0x00, 0x2B, 0x71, 0xDA, 0xA8, 0x69, 0x51, 0xE7, -+0x9A, 0xF8, 0x62, 0x30, 0x00, 0x2B, 0x3F, 0xF4, 0x28, 0xAF, 0x3B, 0x49, 0x3D, 0x48, 0x58, 0x22, 0x04, 0xF0, 0x0E, 0xFF, -+0x21, 0xE7, 0x39, 0x4A, 0x12, 0x69, 0xA2, 0x1A, 0xA2, 0xF5, 0x9C, 0x52, 0x08, 0x3A, 0x00, 0x2A, 0xFF, 0xF6, 0x3E, 0xAF, -+0xD8, 0xF8, 0xE0, 0x21, 0x01, 0x93, 0x21, 0x46, 0x28, 0x46, 0x90, 0x47, 0x01, 0x9B, 0x2B, 0x74, 0xD8, 0xF8, 0x1C, 0x32, -+0x30, 0x46, 0x98, 0x47, 0xD8, 0xF8, 0x18, 0x32, 0x30, 0x46, 0x98, 0x47, 0x00, 0x9A, 0x11, 0x46, 0x28, 0x4A, 0x4F, 0xF4, -+0xA4, 0x63, 0x03, 0xFB, 0x01, 0x23, 0x93, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0x8A, 0xD1, 0x31, 0xE0, 0xC4, 0x68, 0xFD, 0xE6, -+0xBB, 0xF1, 0x00, 0x0F, 0x3F, 0xF4, 0x16, 0xAF, 0x8C, 0x23, 0x03, 0xFB, 0x07, 0x97, 0xDF, 0xF8, 0x98, 0x80, 0x97, 0xF8, -+0x70, 0x30, 0x54, 0xE7, 0x1F, 0x4A, 0x12, 0x69, 0xA2, 0x1A, 0xA2, 0xF5, 0x9C, 0x52, 0x08, 0x3A, 0x00, 0x2A, 0xFF, 0xF6, -+0x0B, 0xAF, 0x9B, 0x46, 0x9E, 0xF8, 0x70, 0x30, 0x47, 0xE7, 0x9A, 0xF8, 0x62, 0x30, 0x00, 0x2B, 0x3F, 0xF4, 0x4B, 0xAF, -+0x15, 0x49, 0x18, 0x48, 0x49, 0x22, 0x04, 0xF0, 0xC3, 0xFE, 0x44, 0xE7, 0x8C, 0x23, 0x03, 0xFB, 0x07, 0x97, 0x4F, 0xF0, -+0x02, 0x0B, 0x97, 0xF8, 0x70, 0x30, 0x34, 0xE7, 0xBB, 0xF1, 0x01, 0x0F, 0x7F, 0xF4, 0x58, 0xAF, 0x00, 0x9A, 0x11, 0x46, -+0x09, 0x4A, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x01, 0x23, 0x5A, 0x68, 0x42, 0xF0, 0x20, 0x02, 0x5A, 0x60, 0x03, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0x8C, 0x23, 0x03, 0xFB, 0x07, 0x97, 0x4F, 0xF0, 0x01, 0x0B, 0x97, 0xF8, 0x70, 0x30, 0x1A, 0xE7, -+0x18, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x00, 0x10, 0x50, 0x40, 0x64, 0x7D, 0x15, 0x00, -+0x40, 0x9C, 0x15, 0x00, 0x48, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0xB5, 0x00, 0x22, 0x04, 0x46, 0x0D, 0x46, -+0x10, 0x23, 0x0C, 0x21, 0x55, 0x20, 0x02, 0xF0, 0xA5, 0xFD, 0x05, 0xEB, 0x45, 0x03, 0x94, 0xF8, 0x71, 0x20, 0x02, 0x70, -+0x04, 0xEB, 0x03, 0x13, 0x45, 0x70, 0x1A, 0x7C, 0x22, 0xB9, 0xC2, 0x70, 0xBD, 0xE8, 0x38, 0x40, 0x02, 0xF0, 0xC6, 0xBD, -+0x1A, 0x7D, 0xC2, 0x70, 0x00, 0x2A, 0xF7, 0xD0, 0x93, 0xF8, 0x20, 0x20, 0x82, 0x70, 0xD3, 0xE9, 0x06, 0x12, 0x5B, 0x6A, -+0xC3, 0x60, 0xC0, 0xE9, 0x01, 0x12, 0xBD, 0xE8, 0x38, 0x40, 0x02, 0xF0, 0xB5, 0xBD, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x41, -+0x16, 0x46, 0x2D, 0x4D, 0x4F, 0xF4, 0xA4, 0x62, 0xB3, 0x42, 0x04, 0x46, 0x02, 0xFB, 0x01, 0x58, 0x0B, 0xD3, 0xC2, 0x7C, -+0x01, 0x2A, 0x30, 0xD0, 0xC5, 0x69, 0x9B, 0x1B, 0xB3, 0xFB, 0xF5, 0xF3, 0x03, 0xFB, 0x05, 0x55, 0x2E, 0x44, 0x5F, 0x1C, -+0x00, 0xE0, 0x00, 0x27, 0x23, 0x4B, 0xE6, 0x62, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x28, 0xDB, 0xE3, 0x7C, -+0xD8, 0xF8, 0x7C, 0x00, 0xFF, 0x2B, 0xA6, 0xEB, 0x00, 0x00, 0x31, 0xD0, 0xBB, 0x42, 0x94, 0xBF, 0xDB, 0x1A, 0xDB, 0x1B, -+0x1B, 0x4A, 0xDB, 0xB2, 0xE3, 0x74, 0x12, 0x69, 0x82, 0x1A, 0x00, 0x2A, 0x0C, 0xDA, 0x18, 0x49, 0x5B, 0xB1, 0xE5, 0x69, -+0xFF, 0x2B, 0x28, 0x44, 0x0A, 0xD0, 0x01, 0x3B, 0xDB, 0xB2, 0xE3, 0x74, 0x0A, 0x69, 0x82, 0x1A, 0x00, 0x2A, 0xF3, 0xDB, -+0x03, 0xB9, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x0A, 0x69, 0x82, 0x1A, 0x00, 0x2A, 0xED, 0xDB, 0xBD, 0xE8, 0xF0, 0x81, -+0x98, 0xF8, 0x62, 0x30, 0x00, 0x2B, 0xD2, 0xD0, 0x0B, 0x48, 0x0C, 0x49, 0x58, 0x22, 0x04, 0xF0, 0x15, 0xFE, 0xE3, 0x7C, -+0xD8, 0xF8, 0x7C, 0x00, 0xFF, 0x2B, 0xA6, 0xEB, 0x00, 0x00, 0xCD, 0xD1, 0x04, 0x4A, 0x12, 0x69, 0x82, 0x1A, 0x00, 0x2A, -+0xD3, 0xDB, 0xE1, 0xE7, 0x18, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x40, 0x9C, 0x15, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x70, 0xB5, 0x08, 0x4E, 0xD6, 0xF8, 0xEC, 0x41, 0x05, 0x46, 0xA0, 0x47, 0x04, 0x46, 0x30, 0xB1, -+0xD6, 0xF8, 0xE0, 0x31, 0x01, 0x46, 0x28, 0x46, 0x98, 0x47, 0x01, 0x23, 0x2B, 0x74, 0xE0, 0xB2, 0x70, 0xBD, 0x00, 0xBF, -+0x88, 0x1A, 0x17, 0x00, 0x03, 0x7C, 0x43, 0xB1, 0x10, 0xB5, 0x04, 0x4B, 0x04, 0x46, 0xD3, 0xF8, 0xD8, 0x31, 0x98, 0x47, -+0x00, 0x23, 0x23, 0x74, 0x10, 0xBD, 0x70, 0x47, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x5C, 0x4F, 0x00, 0xEB, -+0x80, 0x04, 0xC4, 0xEB, 0xC4, 0x04, 0x4F, 0xEA, 0x84, 0x0A, 0x83, 0xB0, 0x05, 0x46, 0x07, 0xEB, 0x84, 0x04, 0x0E, 0x46, -+0x00, 0x29, 0x74, 0xD0, 0x8C, 0x23, 0x03, 0xFB, 0x00, 0x73, 0x91, 0x46, 0xCA, 0x78, 0x93, 0xF8, 0x84, 0x10, 0x00, 0x29, -+0x40, 0xF0, 0x8A, 0x80, 0x4F, 0xF0, 0x8C, 0x08, 0x08, 0xFB, 0x05, 0x78, 0x01, 0x21, 0x98, 0xF8, 0x79, 0x30, 0x88, 0xF8, -+0x78, 0x20, 0x88, 0xF8, 0x84, 0x10, 0xAB, 0xB1, 0xDF, 0xF8, 0x30, 0xB1, 0x20, 0x46, 0xDB, 0xF8, 0xE8, 0x31, 0x98, 0x47, -+0x00, 0x22, 0x0A, 0xF1, 0x30, 0x00, 0xDB, 0xF8, 0xE8, 0x31, 0x88, 0xF8, 0x79, 0x20, 0x38, 0x44, 0x98, 0x47, 0x00, 0x22, -+0xDB, 0xF8, 0x18, 0x32, 0x88, 0xF8, 0x79, 0x20, 0x20, 0x46, 0x98, 0x47, 0xB6, 0xF8, 0x01, 0x20, 0x3F, 0x49, 0x02, 0x3A, -+0x81, 0xFB, 0x02, 0x31, 0xD3, 0x17, 0xC3, 0xEB, 0xA1, 0x03, 0x13, 0xF0, 0xFF, 0x0B, 0x2E, 0xD0, 0x8C, 0x23, 0x03, 0xFB, -+0x05, 0x73, 0x00, 0x93, 0x06, 0xF1, 0x05, 0x08, 0x4F, 0xF0, 0x00, 0x0A, 0x01, 0x95, 0x98, 0xF8, 0x00, 0x20, 0x36, 0x49, -+0x22, 0x75, 0x0A, 0xF1, 0x01, 0x0A, 0x20, 0x46, 0x4B, 0x46, 0x9A, 0xB1, 0x01, 0x2A, 0xD8, 0xF8, 0x05, 0x50, 0x00, 0xD9, -+0x75, 0xB1, 0xD8, 0xF8, 0x01, 0xC0, 0xE2, 0x74, 0xC4, 0xE9, 0x06, 0xC5, 0x00, 0x9A, 0xD1, 0xF8, 0xF4, 0x51, 0x92, 0xF8, -+0x71, 0x10, 0xD8, 0xF8, 0x09, 0x20, 0xA8, 0x47, 0x00, 0x28, 0x45, 0xD1, 0x5F, 0xFA, 0x8A, 0xF3, 0x5B, 0x45, 0x08, 0xF1, -+0x0D, 0x08, 0x04, 0xF1, 0x30, 0x04, 0xDA, 0xD3, 0x01, 0x9D, 0x96, 0xF9, 0x04, 0x20, 0x33, 0x79, 0x00, 0x2A, 0x2D, 0xDB, -+0x8C, 0x20, 0x00, 0xFB, 0x05, 0x75, 0x00, 0x23, 0x85, 0xF8, 0x73, 0x30, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x4F, 0xF0, -+0x8C, 0x08, 0x08, 0xFB, 0x00, 0x78, 0x98, 0xF8, 0x79, 0x30, 0x88, 0xF8, 0x84, 0x10, 0x00, 0x2B, 0xEC, 0xD0, 0xDF, 0xF8, -+0x60, 0x90, 0x20, 0x46, 0xD9, 0xF8, 0xE8, 0x31, 0x98, 0x47, 0x0A, 0xF1, 0x30, 0x00, 0xD9, 0xF8, 0xE8, 0x31, 0x88, 0xF8, -+0x79, 0x60, 0x38, 0x44, 0x98, 0x47, 0xD9, 0xF8, 0x18, 0x32, 0x88, 0xF8, 0x79, 0x60, 0x20, 0x46, 0x98, 0x47, 0xD7, 0xE7, -+0x93, 0xF8, 0x78, 0x30, 0x93, 0x42, 0x7F, 0xF4, 0x71, 0xAF, 0xD7, 0xE7, 0x8C, 0x20, 0x00, 0xFB, 0x05, 0x75, 0x03, 0xF0, -+0x7F, 0x03, 0x85, 0xF8, 0x73, 0x30, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x9A, 0x92, 0xF8, 0x79, 0x30, 0x01, 0x33, -+0x82, 0xF8, 0x79, 0x30, 0xB2, 0xE7, 0x00, 0xBF, 0x48, 0x9E, 0x17, 0x00, 0x4F, 0xEC, 0xC4, 0x4E, 0x88, 0x1A, 0x17, 0x00, -+0x08, 0xB5, 0x01, 0x22, 0x05, 0x48, 0x00, 0x21, 0xE0, 0xF7, 0x2C, 0xF8, 0x04, 0x4B, 0xFF, 0x22, 0x83, 0xF8, 0x71, 0x20, -+0x83, 0xF8, 0xFD, 0x20, 0x08, 0xBD, 0x00, 0xBF, 0x44, 0x9E, 0x17, 0x00, 0x48, 0x9E, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, -+0x25, 0x4C, 0x94, 0xF8, 0x71, 0x30, 0xFF, 0x2B, 0x07, 0x46, 0x0E, 0x46, 0x08, 0xD0, 0x94, 0xF8, 0xFD, 0x30, 0xFF, 0x2B, -+0x18, 0xBF, 0xFF, 0x25, 0x36, 0xD0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0x25, 0xA8, 0x46, 0x4F, 0xF0, 0x30, 0x0A, -+0xA1, 0x46, 0x8C, 0x22, 0x00, 0x21, 0x48, 0x46, 0xE0, 0xF7, 0x04, 0xF8, 0x8C, 0x23, 0x03, 0xFB, 0x08, 0x43, 0x01, 0x2E, -+0x83, 0xF8, 0x71, 0x70, 0x83, 0xF8, 0x70, 0x60, 0x03, 0xD1, 0x15, 0x4A, 0x13, 0x78, 0x01, 0x33, 0x13, 0x70, 0x8C, 0x23, -+0x03, 0xFB, 0x08, 0x43, 0x12, 0x4A, 0xC3, 0xF8, 0x08, 0x90, 0x54, 0x44, 0x00, 0x21, 0x01, 0x26, 0x9C, 0x63, 0x99, 0x74, -+0x0F, 0x4C, 0xD2, 0xF8, 0x10, 0x12, 0x5D, 0x74, 0x83, 0xF8, 0x41, 0x50, 0xC3, 0xF8, 0x68, 0x90, 0x83, 0xF8, 0x42, 0x60, -+0x5C, 0x66, 0x59, 0x60, 0x59, 0x63, 0x48, 0x46, 0xD2, 0xF8, 0x18, 0x32, 0x98, 0x47, 0xC8, 0xE7, 0x01, 0x25, 0xA8, 0x46, -+0x4F, 0xF0, 0xBC, 0x0A, 0x04, 0xF1, 0x8C, 0x09, 0xC9, 0xE7, 0x00, 0xBF, 0x48, 0x9E, 0x17, 0x00, 0x44, 0x9E, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x41, 0xF4, 0x13, 0x00, 0x0E, 0x4A, 0x8C, 0x23, 0x03, 0xFB, 0x00, 0x23, 0x10, 0xB4, 0x93, 0xF8, -+0x71, 0x40, 0xFF, 0x2C, 0x0A, 0xD0, 0x93, 0xF8, 0x70, 0x30, 0x01, 0x2B, 0x09, 0xD0, 0x29, 0xB1, 0x8C, 0x23, 0x03, 0xFB, -+0x00, 0x20, 0xFF, 0x23, 0x80, 0xF8, 0x71, 0x30, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x04, 0x4C, 0x23, 0x78, 0x01, 0x3B, -+0x23, 0x70, 0x00, 0x29, 0xF6, 0xD0, 0xEF, 0xE7, 0x48, 0x9E, 0x17, 0x00, 0x44, 0x9E, 0x17, 0x00, 0x90, 0xF8, 0xC0, 0x34, -+0xBB, 0xB3, 0x2D, 0xE9, 0xF0, 0x47, 0x90, 0xF8, 0x62, 0x40, 0x0C, 0x43, 0x2F, 0xD1, 0x90, 0xF8, 0xC1, 0x54, 0xDF, 0xF8, -+0x64, 0x80, 0x17, 0x4F, 0x05, 0xEB, 0x85, 0x00, 0xC0, 0xEB, 0xC0, 0x00, 0x08, 0xEB, 0x80, 0x09, 0xD7, 0xF8, 0xE8, 0x31, -+0x86, 0x00, 0x48, 0x46, 0x98, 0x47, 0x06, 0xF1, 0x30, 0x00, 0xD7, 0xF8, 0xE8, 0x31, 0x40, 0x44, 0x98, 0x47, 0x8C, 0x23, -+0x03, 0xFB, 0x05, 0x85, 0x95, 0xF8, 0x72, 0x30, 0x85, 0xF8, 0x73, 0x40, 0x85, 0xF8, 0x78, 0x40, 0x85, 0xF8, 0x84, 0x40, -+0x3B, 0xB1, 0x06, 0xF1, 0x60, 0x00, 0xD7, 0xF8, 0xD8, 0x31, 0x40, 0x44, 0x98, 0x47, 0x85, 0xF8, 0x72, 0x40, 0xD7, 0xF8, -+0x18, 0x32, 0x48, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x18, 0x47, 0xBD, 0xE8, 0xF0, 0x87, 0x70, 0x47, 0x88, 0x1A, 0x17, 0x00, -+0x48, 0x9E, 0x17, 0x00, 0x03, 0x4B, 0x8C, 0x22, 0x02, 0xFB, 0x00, 0x30, 0x90, 0xF8, 0x85, 0x00, 0x70, 0x47, 0x00, 0xBF, -+0x48, 0x9E, 0x17, 0x00, 0x11, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x70, 0xB5, 0x05, 0x46, 0x0C, 0x46, -+0x16, 0x46, 0x0E, 0xDB, 0x95, 0xF8, 0xC1, 0x34, 0x0C, 0x4A, 0x8C, 0x21, 0x01, 0xFB, 0x03, 0x23, 0xD3, 0xF8, 0x80, 0x20, -+0x22, 0x60, 0xD8, 0x6F, 0x30, 0x60, 0x23, 0x68, 0xC0, 0x1A, 0xC0, 0x0F, 0x70, 0xBD, 0x90, 0xF8, 0xC0, 0x34, 0x00, 0x2B, -+0xEC, 0xD1, 0x05, 0x49, 0x05, 0x48, 0x40, 0xF2, 0x06, 0x52, 0x04, 0xF0, 0x23, 0xFC, 0xE5, 0xE7, 0x38, 0x36, 0x17, 0x00, -+0x48, 0x9E, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xA4, 0xA3, 0x15, 0x00, 0x70, 0xB5, 0x35, 0x4E, 0x33, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x05, 0x46, 0x0C, 0x46, 0x12, 0xDB, 0x90, 0xF8, 0xC1, 0x24, 0x31, 0x48, 0x8C, 0x23, 0x01, 0xEB, -+0x41, 0x01, 0x03, 0xFB, 0x02, 0xF3, 0x03, 0xEB, 0x01, 0x13, 0x03, 0x44, 0x61, 0x00, 0x1B, 0x7C, 0x01, 0x2B, 0x28, 0xD0, -+0x02, 0x2B, 0x1D, 0xD0, 0x00, 0x20, 0x70, 0xBD, 0x90, 0xF8, 0xC0, 0x34, 0x0B, 0xB1, 0x01, 0x29, 0x30, 0xD9, 0x27, 0x49, -+0x27, 0x48, 0x40, 0xF2, 0x14, 0x52, 0x04, 0xF0, 0xF3, 0xFB, 0x95, 0xF8, 0xC1, 0x24, 0x22, 0x48, 0x8C, 0x23, 0x04, 0xEB, -+0x44, 0x01, 0x03, 0xFB, 0x02, 0xF3, 0x03, 0xEB, 0x01, 0x13, 0x03, 0x44, 0x61, 0x00, 0x1B, 0x7C, 0x01, 0x2B, 0x0A, 0xD0, -+0x02, 0x2B, 0x13, 0xD1, 0x8C, 0x23, 0x0C, 0x44, 0x03, 0xFB, 0x02, 0xF1, 0x01, 0xEB, 0x04, 0x11, 0x01, 0x44, 0xC8, 0x68, -+0x70, 0xBD, 0x8C, 0x23, 0x0C, 0x44, 0x03, 0xFB, 0x02, 0xF1, 0x01, 0xEB, 0x04, 0x14, 0x01, 0x19, 0xC8, 0x68, 0x8B, 0x69, -+0x18, 0x44, 0x70, 0xBD, 0x33, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC8, 0xDA, 0x10, 0xE0, 0x90, 0xF8, 0xC1, 0x24, -+0x0C, 0x48, 0x8C, 0x23, 0x01, 0xEB, 0x41, 0x01, 0x03, 0xFB, 0x02, 0xF3, 0x03, 0xEB, 0x01, 0x13, 0x03, 0x44, 0x61, 0x00, -+0x1B, 0x7C, 0x01, 0x2B, 0xDF, 0xD0, 0x02, 0x2B, 0xD4, 0xD0, 0x06, 0x49, 0x07, 0x48, 0x4F, 0xF4, 0xA4, 0x62, 0x04, 0xF0, -+0xC9, 0xFB, 0x00, 0x20, 0x70, 0xBD, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x48, 0x9E, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xB0, 0xA3, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x90, 0xF8, 0xC0, 0x34, 0x00, 0x2B, 0x43, 0xD0, 0x2D, 0xE9, 0xF0, 0x41, -+0x28, 0x4F, 0x90, 0xF8, 0xC1, 0x24, 0x44, 0x68, 0x8C, 0x26, 0x06, 0xFB, 0x02, 0x76, 0x02, 0xEB, 0x82, 0x03, 0x96, 0xF8, -+0x73, 0xC0, 0x01, 0x25, 0xC3, 0xEB, 0xC3, 0x03, 0x24, 0xF0, 0x40, 0x04, 0x86, 0xF8, 0x86, 0x50, 0x4F, 0xEA, 0x83, 0x0E, -+0x07, 0xEB, 0x83, 0x05, 0x44, 0x60, 0xBC, 0xF1, 0x00, 0x0F, 0x06, 0xD1, 0x1C, 0x4E, 0x28, 0x46, 0xD6, 0xF8, 0x18, 0x32, -+0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0x96, 0xF8, 0x70, 0x30, 0x01, 0xEB, 0x8C, 0x24, 0x3B, 0xB9, 0x17, 0x4B, 0x18, 0x69, -+0x01, 0xF5, 0x96, 0x73, 0xC1, 0x1A, 0x11, 0xF1, 0x32, 0x0F, 0x14, 0xD4, 0x8C, 0x23, 0x03, 0xFB, 0x02, 0x72, 0x11, 0x4E, -+0x0E, 0xF1, 0x60, 0x00, 0x01, 0x23, 0x38, 0x44, 0x21, 0x46, 0x82, 0xF8, 0x72, 0x30, 0xD6, 0xF8, 0xE0, 0x31, 0x98, 0x47, -+0xD6, 0xF8, 0x18, 0x32, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0x70, 0x47, 0x08, 0x4D, 0x74, 0x67, 0x0E, 0xF1, -+0x60, 0x00, 0x02, 0x22, 0x38, 0x44, 0x19, 0x46, 0x86, 0xF8, 0x72, 0x20, 0xD5, 0xF8, 0xE0, 0x31, 0xBD, 0xE8, 0xF0, 0x41, -+0x18, 0x47, 0x00, 0xBF, 0x48, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x30, 0xB4, 0x0A, 0x49, -+0x90, 0xF8, 0xC1, 0x34, 0x09, 0x4C, 0x8C, 0x20, 0x03, 0xEB, 0x83, 0x02, 0x00, 0xFB, 0x03, 0x13, 0x00, 0x25, 0xC2, 0xEB, -+0xC2, 0x02, 0x83, 0xF8, 0x86, 0x50, 0x01, 0xEB, 0x82, 0x00, 0xD4, 0xF8, 0x18, 0x32, 0x30, 0xBC, 0x18, 0x47, 0x00, 0xBF, -+0x48, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x90, 0xF8, 0xC0, 0x44, 0x00, 0x2C, 0x3E, 0xD0, -+0x90, 0xF8, 0x62, 0x30, 0x05, 0x46, 0x00, 0x2B, 0x3C, 0xD1, 0x27, 0x4B, 0x90, 0xF8, 0xC1, 0x74, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x88, 0x46, 0x16, 0x46, 0x36, 0xDB, 0xD8, 0xF8, 0x08, 0x00, 0xB2, 0x8B, 0x00, 0xF1, 0x24, 0x03, -+0x10, 0x44, 0x83, 0x42, 0x02, 0xD3, 0x38, 0xE0, 0x98, 0x42, 0x36, 0xD9, 0x5D, 0x78, 0x1A, 0x78, 0xA9, 0x1C, 0xDD, 0x2A, -+0x1C, 0x46, 0x0B, 0x44, 0xF6, 0xD1, 0x62, 0x79, 0x09, 0x2A, 0xF3, 0xD1, 0x06, 0x34, 0x04, 0x3D, 0x14, 0xFA, 0x85, 0xF5, -+0xAC, 0x42, 0x06, 0xD3, 0xEC, 0xE7, 0xB4, 0xF8, 0x01, 0x10, 0x03, 0x31, 0x0C, 0x44, 0xA5, 0x42, 0xE6, 0xD9, 0x22, 0x78, -+0x0C, 0x2A, 0xF6, 0xD1, 0x00, 0x2C, 0xE1, 0xD0, 0xB2, 0x68, 0x0F, 0x4B, 0x92, 0x68, 0xD3, 0xF8, 0xF0, 0x31, 0x92, 0x69, -+0x38, 0x46, 0x21, 0x46, 0x98, 0x47, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x24, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, -+0x01, 0x2F, 0xC6, 0xD9, 0x07, 0x49, 0x08, 0x48, 0x40, 0xF2, 0x73, 0x52, 0x04, 0xF0, 0xD8, 0xFA, 0x95, 0xF8, 0xC1, 0x74, -+0xBD, 0xE7, 0x00, 0x24, 0xE2, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xD8, 0xA3, 0x15, 0x00, 0xF0, 0xB5, 0x0C, 0x7E, 0x7F, 0x2C, 0x83, 0xB0, 0x23, 0xD1, 0x4A, 0x7F, 0x0A, 0xBB, 0xCA, 0x7F, -+0xDD, 0x2A, 0x1E, 0xD1, 0x91, 0xF8, 0x24, 0x20, 0x09, 0x2A, 0x1A, 0xD1, 0x91, 0xF8, 0x25, 0x20, 0x0C, 0x2A, 0x01, 0xF1, -+0x25, 0x04, 0x14, 0xD1, 0x11, 0x4A, 0x12, 0x49, 0x12, 0x68, 0xD1, 0xF8, 0xF0, 0x61, 0xB2, 0xF9, 0x00, 0x20, 0x90, 0xF8, -+0xC1, 0x74, 0x00, 0x2A, 0x05, 0x46, 0x0A, 0xDB, 0xEA, 0x6F, 0x21, 0x46, 0x1A, 0x44, 0x38, 0x46, 0x33, 0x46, 0x03, 0xB0, -+0xBD, 0xE8, 0xF0, 0x40, 0x18, 0x47, 0x03, 0xB0, 0xF0, 0xBD, 0x90, 0xF8, 0x62, 0x20, 0x00, 0x2A, 0xF0, 0xD0, 0x06, 0x49, -+0x06, 0x48, 0x01, 0x93, 0x49, 0x22, 0x04, 0xF0, 0x95, 0xFA, 0x01, 0x9B, 0xE8, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x40, 0x9C, 0x15, 0x00, 0x12, 0x4B, 0x18, 0x78, 0xF8, 0xB1, 0x12, 0x4B, -+0x58, 0x7C, 0xD8, 0xB9, 0x9A, 0x7C, 0x01, 0x2A, 0x19, 0xD8, 0x9B, 0x68, 0x13, 0xB9, 0x16, 0xE0, 0x1B, 0x68, 0xAB, 0xB1, -+0x93, 0xF8, 0x62, 0x20, 0x02, 0x2A, 0xF9, 0xD1, 0x93, 0xF8, 0xC0, 0x24, 0x00, 0x2A, 0xF5, 0xD0, 0x93, 0xF8, 0xC1, 0x34, -+0x08, 0x4A, 0x8C, 0x21, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, 0x85, 0x00, 0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x70, 0x47, -+0x00, 0x20, 0x70, 0x47, 0x70, 0x47, 0x00, 0xBF, 0x44, 0x9E, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x48, 0x9E, 0x17, 0x00, -+0x18, 0x4B, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x00, 0x30, 0x90, 0xF8, 0xC0, 0x34, 0x1B, 0xB1, 0x90, 0xF8, 0x62, 0x30, -+0x02, 0x2B, 0x00, 0xD0, 0x70, 0x47, 0x70, 0xB5, 0x90, 0xF8, 0xC1, 0x34, 0x11, 0x4C, 0x8C, 0x22, 0x02, 0xFB, 0x03, 0x42, -+0x00, 0x39, 0x03, 0xEB, 0x83, 0x03, 0x92, 0xF8, 0x84, 0x50, 0x18, 0xBF, 0x01, 0x21, 0xC3, 0xEB, 0xC3, 0x03, 0x82, 0xF8, -+0x87, 0x10, 0x04, 0xEB, 0x83, 0x04, 0x35, 0xB9, 0x09, 0x4D, 0xD5, 0xF8, 0x18, 0x32, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, -+0x18, 0x47, 0x06, 0x4D, 0x92, 0xF8, 0x71, 0x00, 0xD5, 0xF8, 0x90, 0x31, 0x03, 0x21, 0x98, 0x47, 0xF1, 0xE7, 0x00, 0xBF, -+0x18, 0x88, 0x17, 0x00, 0x48, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0xB5, 0x0E, 0x4E, 0x90, 0xF8, 0xC1, 0x44, -+0x0D, 0x4D, 0x8C, 0x23, 0x03, 0xFB, 0x04, 0x63, 0x01, 0x22, 0x04, 0xEB, 0x84, 0x04, 0x93, 0xF8, 0x71, 0x00, 0x83, 0xF8, -+0x73, 0x10, 0x83, 0xF8, 0x72, 0x20, 0xC4, 0xEB, 0xC4, 0x04, 0xD5, 0xF8, 0x90, 0x31, 0x03, 0x21, 0x98, 0x47, 0xD5, 0xF8, -+0x18, 0x32, 0x06, 0xEB, 0x84, 0x00, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, 0x48, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x47, 0x1D, 0x4F, 0x90, 0xF8, 0xC1, 0x44, 0x8C, 0x26, 0x06, 0xFB, 0x04, 0x76, 0x04, 0xEB, 0x84, 0x00, -+0x96, 0xF8, 0x72, 0x20, 0xC0, 0xEB, 0xC0, 0x00, 0x4F, 0xF0, 0x00, 0x09, 0x07, 0xEB, 0x80, 0x05, 0x86, 0xF8, 0x73, 0x90, -+0x9A, 0xB9, 0xDF, 0xF8, 0x54, 0x80, 0xD8, 0xF8, 0x18, 0x32, 0x28, 0x46, 0x98, 0x47, 0x8C, 0x23, 0x03, 0xFB, 0x04, 0x74, -+0x94, 0xF8, 0x79, 0x30, 0x9B, 0xB9, 0xD8, 0xF8, 0x90, 0x31, 0x94, 0xF8, 0x71, 0x00, 0x02, 0x21, 0xBD, 0xE8, 0xF0, 0x47, -+0x18, 0x47, 0x83, 0x00, 0xDF, 0xF8, 0x28, 0x80, 0x03, 0xF1, 0x60, 0x00, 0x38, 0x44, 0xD8, 0xF8, 0xD8, 0x31, 0x98, 0x47, -+0x86, 0xF8, 0x72, 0x90, 0xE1, 0xE7, 0xD8, 0xF8, 0x90, 0x31, 0x94, 0xF8, 0x71, 0x00, 0x03, 0x21, 0xBD, 0xE8, 0xF0, 0x47, -+0x18, 0x47, 0x00, 0xBF, 0x48, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x90, 0xF8, 0xC0, 0x34, 0x63, 0xB1, 0x90, 0xF8, -+0xC1, 0x34, 0x06, 0x4A, 0x06, 0x48, 0x03, 0xEB, 0x83, 0x03, 0xC3, 0xEB, 0xC3, 0x03, 0x00, 0xEB, 0x83, 0x00, 0xD2, 0xF8, -+0x18, 0x32, 0x18, 0x47, 0x70, 0x47, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x48, 0x9E, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, -+0x42, 0x4E, 0x90, 0xF8, 0xC1, 0x84, 0xDD, 0xF8, 0x30, 0xC0, 0x8C, 0x24, 0x04, 0xFB, 0x08, 0x64, 0x94, 0xF8, 0x70, 0x70, -+0x01, 0x2F, 0x0F, 0xD1, 0x08, 0xEB, 0x88, 0x05, 0x94, 0xF8, 0x10, 0x90, 0xC5, 0xEB, 0xC5, 0x05, 0xA8, 0x00, 0x06, 0xEB, -+0x85, 0x05, 0xB9, 0xF1, 0x00, 0x0F, 0x08, 0xD0, 0x94, 0xF8, 0x40, 0x40, 0x00, 0x2C, 0x64, 0xD0, 0x4F, 0xF0, 0xFF, 0x09, -+0x48, 0x46, 0xBD, 0xE8, 0xF8, 0x8F, 0x28, 0x46, 0xCA, 0x46, 0x8C, 0x24, 0x4F, 0xEA, 0x4A, 0x07, 0x04, 0xFB, 0x08, 0xF4, -+0x07, 0xEB, 0x0A, 0x0B, 0x06, 0xEB, 0x04, 0x0E, 0x04, 0xEB, 0x0B, 0x14, 0x00, 0x29, 0x06, 0xEB, 0x04, 0x01, 0x9E, 0xF8, -+0x79, 0xB0, 0xCB, 0x74, 0x0B, 0x75, 0x0A, 0x9B, 0xCB, 0x61, 0x0B, 0xF1, 0x01, 0x0B, 0x0B, 0x9B, 0x8B, 0x61, 0x0C, 0xBF, -+0x01, 0x24, 0x00, 0x24, 0xC1, 0xF8, 0x24, 0xC0, 0x81, 0xF8, 0x21, 0x20, 0x81, 0xF8, 0x20, 0x40, 0x8E, 0xF8, 0x79, 0xB0, -+0x04, 0xD0, 0x9E, 0xF8, 0x7A, 0x30, 0x01, 0x33, 0x8E, 0xF8, 0x7A, 0x30, 0x0A, 0x9B, 0x73, 0xB1, 0x8C, 0x23, 0x07, 0xEB, -+0x0A, 0x02, 0x03, 0xFB, 0x08, 0xF3, 0x03, 0xEB, 0x02, 0x13, 0x33, 0x44, 0x0A, 0x99, 0x4F, 0xF0, 0x00, 0x42, 0xB2, 0xFB, -+0xF1, 0xF2, 0x01, 0x3A, 0x9A, 0x62, 0x15, 0x4C, 0x61, 0x46, 0xD4, 0xF8, 0xE0, 0x31, 0x98, 0x47, 0x8C, 0x23, 0x03, 0xFB, -+0x08, 0xF8, 0x57, 0x44, 0x08, 0xEB, 0x07, 0x17, 0x37, 0x44, 0x46, 0x44, 0x01, 0x23, 0x96, 0xF8, 0x71, 0x00, 0x3B, 0x74, -+0x03, 0x21, 0xD4, 0xF8, 0x90, 0x31, 0x98, 0x47, 0x49, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0xA4, 0xFA, 0xD4, 0xF8, 0x1C, 0x32, -+0x28, 0x46, 0x98, 0x47, 0x28, 0x46, 0xD4, 0xF8, 0x18, 0x32, 0x98, 0x47, 0x48, 0x46, 0xBD, 0xE8, 0xF8, 0x8F, 0x30, 0x30, -+0xB9, 0x46, 0x30, 0x44, 0xBA, 0x46, 0x9C, 0xE7, 0x48, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, -+0x90, 0xF8, 0xC1, 0x64, 0x37, 0x4D, 0x8C, 0x23, 0x03, 0xFB, 0x06, 0xF3, 0xE8, 0x18, 0x90, 0xF8, 0x70, 0x00, 0x01, 0x28, -+0x5C, 0xD1, 0x01, 0x29, 0x0C, 0x46, 0x57, 0xD8, 0x01, 0xEB, 0x41, 0x01, 0x03, 0xEB, 0x01, 0x13, 0x2B, 0x44, 0x4F, 0xEA, -+0x44, 0x08, 0x19, 0x7C, 0x00, 0x29, 0x4D, 0xD0, 0x1A, 0xB1, 0x93, 0xF8, 0x20, 0x30, 0x00, 0x2B, 0x48, 0xD0, 0x06, 0xEB, -+0x86, 0x07, 0x04, 0xEB, 0x44, 0x00, 0xDF, 0xF8, 0xA4, 0x90, 0xC7, 0xEB, 0xC7, 0x07, 0x00, 0x01, 0x00, 0xEB, 0x87, 0x00, -+0xD9, 0xF8, 0xD8, 0x31, 0x28, 0x44, 0x98, 0x47, 0x8C, 0x23, 0x03, 0xFB, 0x06, 0xFA, 0xA0, 0x44, 0x0A, 0xEB, 0x08, 0x18, -+0xA8, 0x44, 0x00, 0x23, 0x05, 0xEB, 0x87, 0x07, 0x88, 0xF8, 0x10, 0x30, 0xD9, 0xF8, 0x1C, 0x22, 0x38, 0x46, 0x90, 0x47, -+0xD9, 0xF8, 0x18, 0x22, 0x38, 0x46, 0x90, 0x47, 0x05, 0xEB, 0x0A, 0x03, 0x98, 0xF8, 0x20, 0x10, 0x93, 0xF8, 0x79, 0x20, -+0x01, 0x3A, 0xD2, 0xB2, 0x01, 0x29, 0x83, 0xF8, 0x79, 0x20, 0x04, 0xD1, 0x93, 0xF8, 0x7A, 0x10, 0x01, 0x39, 0x83, 0xF8, -+0x7A, 0x10, 0x8C, 0x23, 0x03, 0xFB, 0x06, 0x53, 0x93, 0xF8, 0x73, 0x10, 0x01, 0xB9, 0x92, 0xB1, 0x8C, 0x23, 0x03, 0xFB, -+0x06, 0x55, 0x03, 0x21, 0xD9, 0xF8, 0x90, 0x31, 0x95, 0xF8, 0x71, 0x00, 0x98, 0x47, 0x38, 0x46, 0x21, 0x46, 0xFF, 0xF7, -+0x29, 0xFA, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0xD9, 0xF8, 0x90, 0x21, 0x93, 0xF8, -+0x71, 0x00, 0x02, 0x21, 0x90, 0x47, 0xEE, 0xE7, 0x48, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, -+0x1F, 0x4F, 0x90, 0xF8, 0xC1, 0x84, 0x8C, 0x25, 0x05, 0xFB, 0x08, 0x75, 0x08, 0xEB, 0x88, 0x03, 0x95, 0xF8, 0x20, 0x20, -+0xC3, 0xEB, 0xC3, 0x03, 0x0E, 0x46, 0x9C, 0x00, 0xAA, 0xB9, 0x2B, 0x7C, 0x9B, 0xB1, 0xE9, 0x68, 0xDF, 0xF8, 0x5C, 0x90, -+0x31, 0x44, 0xD9, 0xF8, 0xE0, 0x31, 0x38, 0x19, 0x98, 0x47, 0x95, 0xF8, 0x50, 0x30, 0x13, 0xB9, 0x95, 0xF8, 0x40, 0x30, -+0x6B, 0xB9, 0xD9, 0xF8, 0x1C, 0x32, 0x38, 0x19, 0xBD, 0xE8, 0xF0, 0x47, 0x18, 0x47, 0x95, 0xF8, 0x50, 0x30, 0xAB, 0xB9, -+0x95, 0xF8, 0x40, 0x30, 0x93, 0xB1, 0xDF, 0xF8, 0x2C, 0x90, 0x8C, 0x23, 0x03, 0xFB, 0x08, 0x73, 0x04, 0xF1, 0x30, 0x00, -+0xD9, 0x6B, 0xD9, 0xF8, 0xE0, 0x31, 0x38, 0x44, 0x31, 0x44, 0x98, 0x47, 0xD9, 0xF8, 0x1C, 0x32, 0x38, 0x19, 0xBD, 0xE8, -+0xF0, 0x47, 0x18, 0x47, 0xBD, 0xE8, 0xF0, 0x87, 0x48, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x0A, 0x4B, 0x8C, 0x22, -+0x02, 0xFB, 0x00, 0x33, 0x93, 0xF8, 0x71, 0x20, 0xFF, 0x2A, 0x0B, 0xD0, 0x93, 0xF8, 0x84, 0x00, 0x48, 0xB1, 0x93, 0xF8, -+0x88, 0x00, 0x00, 0xEB, 0x40, 0x03, 0x00, 0xEB, 0x83, 0x00, 0x0B, 0x30, 0xC0, 0xB2, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, -+0x48, 0x9E, 0x17, 0x00, 0x30, 0xB4, 0xDD, 0x23, 0x50, 0x25, 0x6F, 0x24, 0x9A, 0x21, 0x09, 0x22, 0x03, 0x70, 0x0C, 0x23, -+0x85, 0x70, 0xC4, 0x70, 0x01, 0x71, 0x42, 0x71, 0x83, 0x71, 0x30, 0xBC, 0x70, 0x47, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x43, -+0x2D, 0x4E, 0x8C, 0x23, 0x03, 0xFB, 0x00, 0x63, 0x93, 0xF8, 0x78, 0x20, 0x4A, 0x72, 0x93, 0xF8, 0x73, 0x40, 0x01, 0x32, -+0x83, 0xF8, 0x78, 0x20, 0x00, 0x2C, 0x46, 0xD0, 0x64, 0xF0, 0x7F, 0x04, 0x8C, 0x72, 0x00, 0xEB, 0x80, 0x03, 0xC3, 0xEB, -+0xC3, 0x03, 0x4F, 0xF0, 0x8C, 0x0C, 0xDF, 0xF8, 0x8C, 0x90, 0xDF, 0xF8, 0x8C, 0x80, 0x06, 0xEB, 0x83, 0x03, 0x0C, 0xFB, -+0x00, 0x6C, 0x01, 0xF1, 0x0B, 0x02, 0x01, 0xF1, 0x25, 0x0E, 0x00, 0x24, 0x1D, 0x7C, 0xC5, 0xB1, 0x9C, 0xF8, 0x87, 0x50, -+0x15, 0xB1, 0x93, 0xF8, 0x21, 0x50, 0x55, 0xBB, 0x1D, 0x7D, 0x15, 0x70, 0xD3, 0xE9, 0x06, 0x57, 0xC2, 0xF8, 0x01, 0x50, -+0xC2, 0xF8, 0x05, 0x70, 0xD9, 0xF8, 0x00, 0x50, 0xD8, 0xF8, 0x10, 0x70, 0xED, 0x1B, 0x5F, 0x6A, 0x01, 0x34, 0x3D, 0x44, -+0xE4, 0xB2, 0xC2, 0xF8, 0x09, 0x50, 0x0D, 0x32, 0x72, 0x45, 0x03, 0xF1, 0x30, 0x03, 0xDF, 0xD1, 0x8C, 0x22, 0x04, 0xEB, -+0x44, 0x03, 0x04, 0xEB, 0x83, 0x03, 0x02, 0xFB, 0x00, 0x60, 0x03, 0xF1, 0x09, 0x02, 0x80, 0xF8, 0x88, 0x40, 0x02, 0x33, -+0x4A, 0x70, 0xA1, 0xF8, 0x07, 0x30, 0xBD, 0xE8, 0xF0, 0x83, 0x8C, 0x72, 0xB9, 0xE7, 0x93, 0xF8, 0x20, 0x50, 0x01, 0x2D, -+0xD0, 0xD1, 0xE2, 0xE7, 0x48, 0x9E, 0x17, 0x00, 0xA4, 0x80, 0x32, 0x40, 0x00, 0x10, 0x50, 0x40, 0x02, 0x29, 0x20, 0xD0, -+0x03, 0x29, 0x0F, 0xD0, 0x01, 0x29, 0x06, 0xD0, 0x15, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x1E, 0xDB, -+0x70, 0x47, 0x13, 0x4B, 0x8C, 0x22, 0x02, 0xFB, 0x00, 0x30, 0x80, 0xF8, 0x84, 0x10, 0x70, 0x47, 0x0F, 0x4B, 0x8C, 0x22, -+0x02, 0xFB, 0x00, 0x30, 0x90, 0xF8, 0x84, 0x30, 0x00, 0x2B, 0xEF, 0xD1, 0x0C, 0x4B, 0x90, 0xF8, 0x71, 0x00, 0xD3, 0xF8, -+0x90, 0x31, 0x01, 0x21, 0x18, 0x47, 0x08, 0x4B, 0x8C, 0x22, 0x02, 0xFB, 0x00, 0x30, 0x00, 0x23, 0x80, 0xF8, 0x84, 0x30, -+0x70, 0x47, 0x06, 0x49, 0x06, 0x48, 0x4F, 0xF4, 0xEA, 0x62, 0x03, 0xF0, 0xA5, 0xBF, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0x48, 0x9E, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x90, 0xF8, 0xC0, 0x34, -+0x33, 0xB1, 0x90, 0xF8, 0x64, 0x30, 0x1B, 0xB1, 0x43, 0x68, 0x43, 0xF0, 0x40, 0x03, 0x43, 0x60, 0x70, 0x47, 0x00, 0xBF, -+0x2D, 0xE9, 0xF0, 0x47, 0x36, 0x4F, 0x02, 0x7E, 0xDF, 0xF8, 0xE0, 0x80, 0x35, 0x49, 0xD8, 0xF8, 0xB0, 0x33, 0x0E, 0x69, -+0x05, 0x46, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x02, 0x70, 0x98, 0x47, 0xEB, 0x7E, 0x00, 0x2B, 0x3A, 0xD0, 0xD5, 0xE9, -+0x04, 0x43, 0x02, 0x2C, 0x8C, 0xBF, 0x01, 0x24, 0x00, 0x24, 0x02, 0x2B, 0x6B, 0x7E, 0x95, 0xF8, 0x18, 0xA0, 0x88, 0xBF, -+0x44, 0xF0, 0x02, 0x04, 0x63, 0x40, 0x9B, 0x07, 0x44, 0xD1, 0xD1, 0x46, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x0A, 0x7A, -+0x6C, 0x76, 0xDA, 0xF8, 0xE4, 0x00, 0x18, 0xB3, 0xDF, 0xF8, 0x94, 0xC0, 0x4F, 0xF0, 0x00, 0x0E, 0x90, 0xF8, 0x23, 0x10, -+0x00, 0x68, 0x01, 0xEB, 0x41, 0x04, 0x64, 0x44, 0x4B, 0x00, 0x62, 0x78, 0xA4, 0x78, 0x02, 0x2A, 0x0B, 0x44, 0x88, 0xBF, -+0x01, 0x22, 0x0C, 0xEB, 0x03, 0x01, 0x98, 0xBF, 0x00, 0x22, 0x02, 0x2C, 0x88, 0xBF, 0x42, 0xF0, 0x02, 0x02, 0x0C, 0xF8, -+0x03, 0x20, 0x81, 0xF8, 0x01, 0xE0, 0x81, 0xF8, 0x02, 0xE0, 0x00, 0x28, 0xE2, 0xD1, 0x01, 0xE0, 0x95, 0xF8, 0x18, 0x90, -+0x11, 0x4B, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x09, 0x77, 0x9B, 0x6A, 0x39, 0x6C, 0x00, 0x22, 0x5B, 0x1A, 0xC5, 0xE9, -+0x04, 0x22, 0xB3, 0xFA, 0x83, 0xF3, 0x5B, 0x09, 0x06, 0xF5, 0xC3, 0x31, 0xEB, 0x76, 0xD8, 0xF8, 0xE0, 0x31, 0x28, 0x46, -+0xA0, 0x31, 0xBD, 0xE8, 0xF0, 0x47, 0x18, 0x47, 0x21, 0x46, 0x50, 0x46, 0xFF, 0xF7, 0xC4, 0xFC, 0x95, 0xF8, 0x18, 0x90, -+0xB4, 0xE7, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x30, 0x9D, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x60, 0x9F, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x10, 0x4D, 0xDF, 0xF8, 0x44, 0x80, 0xC0, 0xEB, 0xC0, 0x03, 0x05, 0xEB, -+0x83, 0x03, 0xC0, 0xEB, 0xC0, 0x06, 0x9B, 0x7E, 0x04, 0x46, 0x05, 0xEB, 0x86, 0x06, 0xC7, 0x00, 0x1B, 0xB1, 0xD8, 0xF8, -+0xD8, 0x31, 0x30, 0x46, 0x98, 0x47, 0x3F, 0x1B, 0x05, 0xEB, 0x87, 0x05, 0x1C, 0x22, 0x00, 0x21, 0x30, 0x46, 0xDF, 0xF7, -+0x0F, 0xFA, 0xD8, 0xF8, 0x34, 0x33, 0xAE, 0x60, 0x2C, 0x76, 0x6B, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0x80, 0x9F, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x08, 0xB5, 0x00, 0x20, 0xFF, 0xF7, 0xD4, 0xFF, 0x01, 0x20, 0xFF, 0xF7, 0xD1, 0xFF, 0x02, 0x20, -+0xFF, 0xF7, 0xCE, 0xFF, 0x03, 0x20, 0xFF, 0xF7, 0xCB, 0xFF, 0x05, 0x4B, 0x00, 0x22, 0x03, 0xF1, 0x1E, 0x01, 0x5A, 0x70, -+0x9A, 0x70, 0x03, 0xF8, 0x03, 0x2B, 0x8B, 0x42, 0xF9, 0xD1, 0x08, 0xBD, 0x60, 0x9F, 0x17, 0x00, 0x0B, 0x4A, 0xC0, 0xEB, -+0xC0, 0x03, 0x02, 0xEB, 0x83, 0x03, 0x99, 0x7E, 0x71, 0xB9, 0x30, 0xB4, 0x08, 0x49, 0x09, 0x4C, 0x09, 0x69, 0xD4, 0xF8, -+0xE0, 0x41, 0x01, 0x25, 0x01, 0xF5, 0xC3, 0x31, 0x9D, 0x76, 0x18, 0x46, 0xA0, 0x31, 0x23, 0x46, 0x30, 0xBC, 0x18, 0x47, -+0x70, 0x47, 0x00, 0xBF, 0x80, 0x9F, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x09, 0x29, 0x08, 0xB5, -+0x09, 0xD9, 0x6A, 0xBB, 0x21, 0x4B, 0xC0, 0xEB, 0xC0, 0x00, 0x03, 0xEB, 0x80, 0x00, 0x03, 0x69, 0x01, 0x33, 0x03, 0x61, -+0x08, 0xBD, 0x8A, 0xB1, 0x1C, 0x4B, 0x1D, 0x4A, 0xC0, 0xEB, 0xC0, 0x00, 0x01, 0xEB, 0x41, 0x01, 0x03, 0xEB, 0x80, 0x00, -+0x11, 0x44, 0x42, 0x69, 0x8B, 0x78, 0x01, 0x32, 0x02, 0x2B, 0x42, 0x61, 0xEE, 0xD8, 0x01, 0x33, 0x8B, 0x70, 0x08, 0xBD, -+0x13, 0x4B, 0x14, 0x4A, 0xC0, 0xEB, 0xC0, 0x00, 0x01, 0xEB, 0x41, 0x01, 0x03, 0xEB, 0x80, 0x00, 0x11, 0x44, 0x03, 0x69, -+0x4A, 0x78, 0x01, 0x33, 0x02, 0x2A, 0x03, 0x61, 0xDC, 0xD8, 0x01, 0x32, 0x4A, 0x70, 0x08, 0xBD, 0x0A, 0x4A, 0x0C, 0x4B, -+0x1C, 0x21, 0x01, 0xFB, 0x00, 0x20, 0x1A, 0x68, 0x43, 0x69, 0xB2, 0xF9, 0x00, 0x20, 0x01, 0x33, 0x00, 0x2A, 0x43, 0x61, -+0x05, 0xDA, 0x07, 0x49, 0x07, 0x48, 0x40, 0xF2, 0x69, 0x12, 0x03, 0xF0, 0x6F, 0xFE, 0x00, 0x23, 0x9B, 0x78, 0xFF, 0xDE, -+0x80, 0x9F, 0x17, 0x00, 0x60, 0x9F, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xF8, 0xA3, 0x15, 0x00, -+0x70, 0xB5, 0x1E, 0x46, 0x0D, 0x46, 0x01, 0x23, 0x31, 0x46, 0x40, 0xF6, 0x01, 0x00, 0x01, 0xF0, 0x77, 0xFD, 0x04, 0x46, -+0x02, 0x20, 0x02, 0xF0, 0x15, 0xF8, 0x18, 0x4A, 0x18, 0x49, 0x03, 0x46, 0x04, 0x20, 0x03, 0xF0, 0x25, 0xFC, 0x02, 0x20, -+0x02, 0xF0, 0x0C, 0xF8, 0xA0, 0xB9, 0x15, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x16, 0xDB, 0x13, 0x4A, -+0x00, 0x23, 0x23, 0x70, 0x28, 0x46, 0x15, 0x60, 0x93, 0x72, 0x16, 0x81, 0x01, 0x25, 0x00, 0xF0, 0x7D, 0xF9, 0x20, 0x46, -+0x01, 0xF0, 0x86, 0xFD, 0x28, 0x46, 0x70, 0xBD, 0x08, 0x23, 0x20, 0x46, 0x23, 0x70, 0x00, 0x25, 0x01, 0xF0, 0x7E, 0xFD, -+0x28, 0x46, 0x70, 0xBD, 0x95, 0xF8, 0x6F, 0x31, 0x00, 0x2B, 0xE4, 0xD1, 0x06, 0x49, 0x07, 0x48, 0x46, 0x22, 0x03, 0xF0, -+0x25, 0xFE, 0xDE, 0xE7, 0x84, 0xA4, 0x15, 0x00, 0x00, 0xA4, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0xF4, 0x9F, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x08, 0xA4, 0x15, 0x00, 0x17, 0x4A, 0x18, 0x4B, 0x12, 0x68, 0x70, 0xB5, 0xB2, 0xF9, 0x00, 0x20, -+0x1D, 0x68, 0x9C, 0x7A, 0x00, 0x2A, 0x19, 0xDB, 0x14, 0x4A, 0x15, 0x48, 0xD2, 0xE9, 0x00, 0x63, 0x04, 0xEB, 0x44, 0x04, -+0x05, 0xEB, 0x44, 0x04, 0x43, 0xF4, 0x08, 0x53, 0xE1, 0x78, 0x53, 0x60, 0x33, 0x43, 0x03, 0x60, 0xCB, 0x07, 0x03, 0xD4, -+0x0E, 0x4B, 0xD3, 0xF8, 0xEC, 0x32, 0x98, 0x47, 0x03, 0x21, 0x02, 0x20, 0x01, 0xF0, 0x0E, 0xFF, 0x00, 0x20, 0x70, 0xBD, -+0x02, 0x20, 0x01, 0xF0, 0xB1, 0xFF, 0x02, 0x28, 0xE0, 0xD0, 0x08, 0x49, 0x08, 0x48, 0x9C, 0x22, 0x03, 0xF0, 0xEA, 0xFD, -+0xDA, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0xF4, 0x9F, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, 0x60, 0x00, 0x32, 0x40, -+0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x1C, 0xA4, 0x15, 0x00, 0x38, 0xB5, 0x22, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x32, 0xDB, 0x20, 0x49, 0x20, 0x48, 0x21, 0x4C, 0xD1, 0xE9, 0x00, 0x32, 0x22, 0xF4, 0x08, 0x52, -+0x13, 0x43, 0x03, 0x60, 0xA3, 0x7A, 0x20, 0x68, 0x4A, 0x60, 0x90, 0xF8, 0x6F, 0x51, 0x01, 0x33, 0xDB, 0xB2, 0x9D, 0x42, -+0xA3, 0x72, 0x01, 0xD9, 0xE3, 0x7A, 0x93, 0xB1, 0x0C, 0x38, 0x01, 0xF0, 0x55, 0xFD, 0xE3, 0x7A, 0x8B, 0xB1, 0x16, 0x4B, -+0x21, 0x89, 0xD3, 0xF8, 0xF0, 0x32, 0x00, 0x20, 0x98, 0x47, 0x00, 0x23, 0xE3, 0x72, 0x00, 0x21, 0x02, 0x20, 0x01, 0xF0, -+0xC5, 0xFE, 0x00, 0x20, 0x38, 0xBD, 0x00, 0xF0, 0x8D, 0xF8, 0x00, 0x20, 0x38, 0xBD, 0x21, 0x89, 0x02, 0x22, 0x40, 0xF6, -+0x02, 0x00, 0x01, 0xF0, 0x27, 0xFD, 0xEE, 0xE7, 0x02, 0x20, 0x01, 0xF0, 0x5D, 0xFF, 0x03, 0x28, 0xC7, 0xD0, 0x08, 0x49, -+0x08, 0x48, 0xC2, 0x22, 0x03, 0xF0, 0x96, 0xFD, 0xC1, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x98, 0x9C, 0x17, 0x00, -+0x60, 0x00, 0x32, 0x40, 0xF4, 0x9F, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x4C, 0xA4, 0x15, 0x00, -+0x38, 0xB5, 0x02, 0x20, 0x1D, 0x46, 0x01, 0xF0, 0x41, 0xFF, 0x0A, 0x4A, 0x0A, 0x49, 0x04, 0x46, 0x03, 0x46, 0x04, 0x20, -+0x03, 0xF0, 0x50, 0xFB, 0x24, 0xB1, 0x08, 0x4B, 0x01, 0x22, 0xDA, 0x72, 0x00, 0x20, 0x38, 0xBD, 0x06, 0x4B, 0x29, 0x46, -+0xD3, 0xF8, 0xF0, 0x32, 0x01, 0x20, 0x98, 0x47, 0x00, 0x20, 0x38, 0xBD, 0x9C, 0xA4, 0x15, 0x00, 0x00, 0xA4, 0x15, 0x00, -+0xF4, 0x9F, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x15, 0x4A, 0x03, 0x88, 0x11, 0x68, 0x40, 0xF6, 0x6C, 0x12, 0x93, 0x42, -+0x08, 0x69, 0x1F, 0xD0, 0x40, 0xF6, 0x85, 0x12, 0x93, 0x42, 0x1B, 0xD0, 0x40, 0xF6, 0x9E, 0x12, 0x93, 0x42, 0x17, 0xD0, -+0x40, 0xF6, 0xA8, 0x12, 0x93, 0x42, 0x13, 0xD0, 0x41, 0xF2, 0x3C, 0x42, 0x93, 0x42, 0x0F, 0xD0, 0x41, 0xF2, 0x64, 0x42, -+0x93, 0x42, 0x0B, 0xD0, 0x41, 0xF2, 0x85, 0x62, 0x93, 0x42, 0x07, 0xD0, 0x41, 0xF2, 0x99, 0x62, 0x93, 0x42, 0x03, 0xD0, -+0x41, 0xF2, 0xAD, 0x62, 0x93, 0x42, 0x02, 0xD1, 0x00, 0xF5, 0x9C, 0x40, 0x20, 0x30, 0x70, 0x47, 0xC8, 0x35, 0x17, 0x00, -+0x08, 0xB5, 0x0C, 0x22, 0x00, 0x21, 0x08, 0x48, 0xDF, 0xF7, 0x48, 0xF8, 0x00, 0x21, 0x02, 0x20, 0x01, 0xF0, 0x44, 0xFE, -+0x05, 0x4B, 0x06, 0x4A, 0x1A, 0x60, 0x03, 0xF1, 0x14, 0x01, 0x00, 0x22, 0x99, 0x60, 0x1A, 0x61, 0x5A, 0x60, 0x08, 0xBD, -+0xF4, 0x9F, 0x17, 0x00, 0xD4, 0x61, 0x18, 0x00, 0xDE, 0xFA, 0xFE, 0xCA, 0x2D, 0xE9, 0xF0, 0x41, 0x2A, 0x4F, 0xBB, 0x7A, -+0x3E, 0x68, 0x03, 0xEB, 0x43, 0x03, 0x06, 0xEB, 0x43, 0x05, 0x82, 0xB0, 0x95, 0xF8, 0x03, 0x80, 0x18, 0xF0, 0x05, 0x0F, -+0x4F, 0xEA, 0x43, 0x04, 0x28, 0xD0, 0x24, 0x4B, 0x1B, 0x68, 0x5B, 0x69, 0x96, 0xF8, 0x6E, 0xC1, 0x95, 0xF9, 0x04, 0x20, -+0x31, 0x5B, 0xA8, 0x78, 0xCD, 0xE9, 0x00, 0x8C, 0xFC, 0xF7, 0x94, 0xFC, 0x7B, 0x68, 0x93, 0xB1, 0xAA, 0x78, 0x31, 0x5B, -+0xDA, 0xB9, 0xA1, 0xF6, 0x6C, 0x10, 0x48, 0x28, 0x0A, 0xD8, 0x40, 0xF6, 0xB4, 0x12, 0x91, 0x42, 0x28, 0xD0, 0x18, 0x48, -+0xA1, 0xF6, 0x67, 0x12, 0xA0, 0xFB, 0x02, 0x12, 0xC2, 0xF3, 0x87, 0x02, 0x9A, 0x70, 0x02, 0x21, 0x08, 0x46, 0x02, 0xB0, -+0xBD, 0xE8, 0xF0, 0x41, 0x01, 0xF0, 0xFA, 0xBD, 0x28, 0x46, 0xFF, 0xF7, 0x7B, 0xFF, 0x03, 0x46, 0xD4, 0xE7, 0x01, 0x2A, -+0x02, 0xD0, 0x00, 0x22, 0x9A, 0x70, 0xEE, 0xE7, 0xA1, 0xF5, 0x9C, 0x51, 0xA1, 0xF1, 0x0D, 0x02, 0x92, 0xB2, 0xB2, 0xF5, -+0x4D, 0x7F, 0xF4, 0xD8, 0x07, 0x4A, 0x08, 0x39, 0xA2, 0xFB, 0x01, 0x12, 0xC2, 0xF3, 0x87, 0x02, 0x9A, 0x70, 0xDE, 0xE7, -+0x0E, 0x22, 0x9A, 0x70, 0xDB, 0xE7, 0x00, 0xBF, 0xF4, 0x9F, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, 0xCD, 0xCC, 0xCC, 0xCC, -+0x70, 0xB5, 0x0B, 0x4E, 0x0B, 0x4C, 0x33, 0x68, 0x05, 0x46, 0xB3, 0xF8, 0x6C, 0x11, 0x20, 0x46, 0x02, 0xF0, 0x7A, 0xFB, -+0x70, 0x60, 0xFF, 0xF7, 0x95, 0xFF, 0x54, 0xF8, 0x0C, 0x2C, 0xB5, 0xF8, 0x6C, 0x11, 0x01, 0x3A, 0x0A, 0x44, 0x00, 0x21, -+0x44, 0xE9, 0x02, 0x21, 0x70, 0xBD, 0x00, 0xBF, 0xF4, 0x9F, 0x17, 0x00, 0xE8, 0x61, 0x18, 0x00, 0x2D, 0xE9, 0xF8, 0x43, -+0xDF, 0xF8, 0xD8, 0x90, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x00, 0x93, 0x06, 0x46, 0x93, 0xF8, 0xC0, 0x04, 0x93, 0xF8, -+0x6C, 0x50, 0x88, 0x46, 0x17, 0x46, 0x00, 0x28, 0x52, 0xD1, 0x1B, 0x6C, 0x18, 0x79, 0x00, 0x38, 0x18, 0xBF, 0x01, 0x20, -+0x1A, 0x21, 0xEE, 0xF7, 0x75, 0xFE, 0x04, 0x46, 0x00, 0x28, 0x4E, 0xD0, 0x28, 0x4A, 0xDF, 0xF8, 0xA8, 0xE0, 0x4F, 0xF4, -+0x1E, 0x71, 0x01, 0xFB, 0x05, 0x21, 0xD0, 0xE9, 0x12, 0x3C, 0x0A, 0x46, 0xBE, 0xF8, 0xFC, 0x51, 0x52, 0xF8, 0x26, 0x0F, -+0xD8, 0x66, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x06, 0x99, 0x40, 0x20, 0x83, 0xF8, 0x68, 0x00, 0x90, 0x88, 0xA3, 0xF8, -+0x70, 0x00, 0xD9, 0xF8, 0x5C, 0x00, 0xB9, 0xF8, 0x60, 0x90, 0xC3, 0xF8, 0x72, 0x00, 0x01, 0x35, 0x90, 0x88, 0xA3, 0xF8, -+0x76, 0x90, 0xAD, 0xB2, 0xD2, 0xF8, 0x00, 0x90, 0xA3, 0xF8, 0x7C, 0x00, 0x00, 0x20, 0x83, 0xF8, 0x69, 0x00, 0x83, 0xF8, -+0x6A, 0x00, 0x83, 0xF8, 0x6B, 0x00, 0xC3, 0xF8, 0x78, 0x90, 0xAE, 0xF8, 0xFC, 0x51, 0x2D, 0x01, 0x83, 0xF8, 0x80, 0x00, -+0x83, 0xF8, 0x81, 0x00, 0xA3, 0xF8, 0x7E, 0x50, 0xCC, 0xF8, 0x20, 0x00, 0x26, 0x77, 0x91, 0xF8, 0x23, 0x30, 0x63, 0x77, -+0xC4, 0xE9, 0x15, 0x87, 0x20, 0x46, 0x05, 0x21, 0xBD, 0xE8, 0xF8, 0x43, 0xEE, 0xF7, 0x3A, 0xBE, 0x01, 0x20, 0x1A, 0x21, -+0xEE, 0xF7, 0x26, 0xFE, 0x04, 0x46, 0x00, 0x28, 0xB0, 0xD1, 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x52, 0x4B, 0x83, 0xB0, 0x1D, 0x68, 0x9B, 0x7A, -+0x01, 0x93, 0x95, 0xF8, 0x70, 0x31, 0x95, 0xF8, 0x6E, 0x81, 0x00, 0x2B, 0x00, 0xF0, 0x8B, 0x80, 0x4D, 0x4B, 0x4F, 0xF4, -+0xA4, 0x62, 0x02, 0xFB, 0x08, 0x38, 0x08, 0xF1, 0x5C, 0x07, 0x05, 0xF1, 0xFD, 0x09, 0x00, 0x26, 0x98, 0xF8, 0xC0, 0x34, -+0x00, 0x2B, 0x7F, 0xD1, 0x01, 0x9B, 0x03, 0xEB, 0x43, 0x03, 0x05, 0xEB, 0x43, 0x03, 0x9B, 0x78, 0x00, 0x2B, 0x77, 0xD1, -+0x95, 0xF8, 0x71, 0x01, 0x00, 0x38, 0x18, 0xBF, 0x01, 0x20, 0x19, 0xF8, 0x01, 0x3C, 0xB5, 0xF8, 0x6C, 0x11, 0x1A, 0x33, -+0x19, 0x44, 0xEE, 0xF7, 0xE9, 0xFD, 0x4A, 0x46, 0x01, 0x46, 0x00, 0x28, 0x63, 0xD0, 0xD0, 0xE9, 0x12, 0x3C, 0x40, 0x24, -+0x00, 0x20, 0x83, 0xF8, 0x68, 0x40, 0x83, 0xF8, 0x69, 0x00, 0x83, 0xF8, 0x6A, 0x00, 0x83, 0xF8, 0x6B, 0x00, 0x95, 0xF8, -+0x60, 0x01, 0xC0, 0x07, 0x58, 0xD4, 0xD5, 0xF8, 0x60, 0x01, 0xB5, 0xF8, 0x64, 0x41, 0xA3, 0xF8, 0x70, 0x40, 0xD8, 0x66, -+0x05, 0xF5, 0xB0, 0x7A, 0xDF, 0xF8, 0xC0, 0xE0, 0x38, 0x68, 0xBE, 0xF8, 0xFC, 0x41, 0xB7, 0xF8, 0x04, 0xB0, 0xC3, 0xF8, -+0x72, 0x00, 0x01, 0x34, 0xDA, 0xF8, 0x00, 0x00, 0xBA, 0xF8, 0x04, 0xA0, 0xA3, 0xF8, 0x76, 0xB0, 0xA4, 0xB2, 0x4F, 0xF0, -+0x00, 0x0B, 0x98, 0x67, 0xA3, 0xF8, 0x7C, 0xA0, 0xAE, 0xF8, 0xFC, 0x41, 0x83, 0xF8, 0x80, 0xB0, 0x19, 0xF8, 0x01, 0x0C, -+0x83, 0xF8, 0x81, 0x00, 0x19, 0xF8, 0x01, 0x0C, 0x24, 0x01, 0xA3, 0xF8, 0x7E, 0x40, 0x40, 0xB1, 0x81, 0x33, 0x09, 0xEB, -+0x00, 0x04, 0x12, 0xF8, 0x01, 0x0B, 0x03, 0xF8, 0x01, 0x0F, 0xA2, 0x42, 0xF9, 0xD1, 0xB5, 0xF8, 0x6C, 0x21, 0xDC, 0xF8, -+0x28, 0x30, 0x16, 0x48, 0xCC, 0xF8, 0x20, 0x00, 0x9B, 0x1A, 0x00, 0x22, 0xCC, 0xF8, 0x28, 0x30, 0xC1, 0xE9, 0x15, 0x22, -+0x95, 0xF8, 0x6E, 0x31, 0x0B, 0x77, 0xFF, 0x23, 0x4B, 0x77, 0x08, 0x46, 0x05, 0x21, 0xEE, 0xF7, 0x99, 0xFD, 0x95, 0xF8, -+0x70, 0x31, 0x01, 0x36, 0xB3, 0x42, 0x09, 0xF1, 0x21, 0x09, 0x3F, 0xF7, 0x7F, 0xAF, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0x01, 0x20, 0x8A, 0xE7, 0x07, 0x48, 0x04, 0x68, 0x80, 0x88, 0xDC, 0x66, 0xA3, 0xF8, 0x70, 0x00, 0x05, 0xF5, 0xB0, 0x7A, -+0xA6, 0xE7, 0x00, 0xBF, 0xF4, 0x9F, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0xD4, 0x61, 0x18, 0x00, 0xAC, 0xB2, 0x15, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x38, 0xB5, 0x02, 0x22, 0x05, 0x46, 0x01, 0x23, 0x40, 0xF6, 0x04, 0x00, 0x01, 0xF0, 0x92, 0xFA, -+0x04, 0x46, 0x02, 0x20, 0x01, 0xF0, 0x30, 0xFD, 0x05, 0x4A, 0x06, 0x49, 0x03, 0x46, 0x04, 0x20, 0x03, 0xF0, 0x40, 0xF9, -+0x25, 0x70, 0x20, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x01, 0xF0, 0xB2, 0xBA, 0xBC, 0xA4, 0x15, 0x00, 0x00, 0xA4, 0x15, 0x00, -+0x03, 0x4A, 0x93, 0x7A, 0x10, 0x68, 0x03, 0xEB, 0x43, 0x03, 0x00, 0xEB, 0x43, 0x00, 0x70, 0x47, 0xF4, 0x9F, 0x17, 0x00, -+0xC3, 0x78, 0x13, 0xF0, 0x05, 0x0F, 0x03, 0xD0, 0x02, 0x4B, 0x1B, 0x68, 0x58, 0x69, 0x70, 0x47, 0xFF, 0xF7, 0xE8, 0xBD, -+0xC8, 0x35, 0x17, 0x00, 0x0E, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x03, 0xDA, 0x0C, 0x4B, 0x1B, 0x68, -+0x1B, 0x07, 0x0D, 0xD1, 0x0B, 0x48, 0x0C, 0x49, 0x02, 0x68, 0x4B, 0x68, 0x22, 0xF0, 0x80, 0x02, 0x02, 0x60, 0x23, 0xF0, -+0x04, 0x03, 0x4F, 0xF0, 0x80, 0x60, 0x4B, 0x60, 0x01, 0xF0, 0x3C, 0xBE, 0x06, 0x49, 0x07, 0x48, 0x84, 0x22, 0x03, 0xF0, -+0xFB, 0xBA, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x38, 0x00, 0x32, 0x40, 0x8C, 0x80, 0x32, 0x40, 0x1C, 0x9E, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x84, 0x9E, 0x15, 0x00, 0x5A, 0x4A, 0x5B, 0x49, 0x13, 0x68, 0xF0, 0xB4, 0x14, 0x68, 0x5A, 0x4E, -+0x5A, 0x4D, 0x24, 0xF0, 0xFF, 0x04, 0x04, 0x43, 0x14, 0x60, 0x14, 0x68, 0x17, 0x68, 0xC4, 0xF3, 0x09, 0x24, 0x27, 0xF4, -+0x7F, 0x37, 0xDB, 0xB2, 0x00, 0xFB, 0x04, 0xF4, 0x27, 0xF4, 0x40, 0x77, 0xB4, 0xFB, 0xF3, 0xF4, 0x01, 0xEA, 0x04, 0x24, -+0x3C, 0x43, 0x14, 0x60, 0x11, 0x68, 0x14, 0x68, 0xC1, 0xF3, 0x89, 0x41, 0x2C, 0x40, 0x00, 0xFB, 0x01, 0xF1, 0xB1, 0xFB, -+0xF3, 0xF1, 0x06, 0xEA, 0x81, 0x41, 0x21, 0x43, 0x11, 0x60, 0x11, 0x68, 0x49, 0x4E, 0x4A, 0x4C, 0x0D, 0x40, 0x45, 0xF0, -+0x89, 0x65, 0x15, 0x60, 0x32, 0x68, 0x35, 0x68, 0x47, 0x49, 0xC2, 0xF3, 0x0F, 0x22, 0x25, 0xF4, 0x7F, 0x05, 0x25, 0xF4, -+0x7F, 0x45, 0x00, 0xFB, 0x02, 0xF2, 0xB2, 0xFB, 0xF3, 0xF2, 0x04, 0xEA, 0x02, 0x22, 0x2A, 0x43, 0x32, 0x60, 0x0A, 0x68, -+0x0D, 0x68, 0x40, 0x4C, 0xC2, 0xF3, 0x09, 0x52, 0x25, 0xF0, 0x7F, 0x55, 0x00, 0xFB, 0x02, 0xF2, 0x25, 0xF4, 0x40, 0x15, -+0xB2, 0xFB, 0xF3, 0xF2, 0x04, 0xEA, 0x02, 0x52, 0x2A, 0x43, 0x0A, 0x60, 0x0A, 0x68, 0x0C, 0x68, 0xC2, 0xF3, 0x09, 0x02, -+0x24, 0xF4, 0x7F, 0x74, 0x00, 0xFB, 0x02, 0xF2, 0x24, 0xF0, 0x03, 0x04, 0xB2, 0xFB, 0xF3, 0xF2, 0xC2, 0xF3, 0x09, 0x02, -+0x22, 0x43, 0x1D, 0x28, 0x0A, 0x60, 0x44, 0xD8, 0x4A, 0x68, 0x42, 0xF0, 0x03, 0x02, 0x4A, 0x60, 0x2E, 0x49, 0x2B, 0x4C, -+0x0A, 0x68, 0x2E, 0x4E, 0x0F, 0x68, 0x2E, 0x4D, 0xC2, 0xF3, 0x0F, 0x22, 0x37, 0x40, 0x00, 0xFB, 0x02, 0xF2, 0xB2, 0xFB, -+0xF3, 0xF2, 0x04, 0xEA, 0x02, 0x22, 0x3A, 0x43, 0x0A, 0x60, 0x2A, 0x68, 0x2F, 0x68, 0xC2, 0xF3, 0x0F, 0x22, 0x00, 0xFB, -+0x02, 0xF2, 0x3E, 0x40, 0xB2, 0xFB, 0xF3, 0xF2, 0x04, 0xEA, 0x02, 0x22, 0x32, 0x43, 0x2A, 0x60, 0x0A, 0x69, 0x0D, 0x69, -+0x1D, 0x4C, 0xC2, 0xF3, 0x09, 0x52, 0x25, 0xF0, 0x7F, 0x55, 0x00, 0xFB, 0x02, 0xF2, 0x25, 0xF4, 0x40, 0x15, 0xB2, 0xFB, -+0xF3, 0xF2, 0x04, 0xEA, 0x02, 0x52, 0x2A, 0x43, 0x0A, 0x61, 0x0C, 0x69, 0x0A, 0x69, 0xC4, 0xF3, 0x09, 0x04, 0x22, 0xF4, -+0x7F, 0x72, 0x00, 0xFB, 0x04, 0xF0, 0x22, 0xF0, 0x03, 0x02, 0xB0, 0xFB, 0xF3, 0xF0, 0xC0, 0xF3, 0x09, 0x00, 0x10, 0x43, -+0xF0, 0xBC, 0x08, 0x61, 0x70, 0x47, 0x11, 0x49, 0x0A, 0x68, 0x3B, 0x28, 0x22, 0xF0, 0x03, 0x02, 0x94, 0xBF, 0x42, 0xF0, -+0x02, 0x02, 0x42, 0xF0, 0x01, 0x02, 0x0A, 0x60, 0xB2, 0xE7, 0x00, 0xBF, 0xE4, 0x00, 0x32, 0x40, 0x00, 0xFF, 0x03, 0x00, -+0x00, 0x00, 0xFC, 0x0F, 0xFF, 0xFF, 0x03, 0xF0, 0xE8, 0x00, 0x32, 0x40, 0x00, 0xFF, 0xFF, 0x00, 0xEC, 0x00, 0x32, 0x40, -+0x00, 0x00, 0xF0, 0x3F, 0xF4, 0x00, 0x32, 0x40, 0xFF, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x32, 0x40, 0xF0, 0x00, 0x32, 0x40, -+0x1D, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x2C, 0xDB, 0xF0, 0xB4, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, -+0x03, 0xD4, 0x72, 0xB6, 0x18, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x18, 0x4B, 0x18, 0x49, 0x1B, 0x68, 0x0E, 0x68, 0x18, 0x4C, -+0x18, 0x4A, 0x19, 0x4D, 0x19, 0x4F, 0x03, 0xF5, 0xC3, 0x43, 0x28, 0x33, 0x70, 0x1C, 0x08, 0x60, 0x23, 0x60, 0x17, 0x4C, -+0x80, 0x23, 0x13, 0x60, 0x2A, 0x68, 0x63, 0x68, 0x42, 0xF0, 0x80, 0x02, 0x43, 0xF0, 0x04, 0x03, 0x2A, 0x60, 0x63, 0x60, -+0x00, 0x23, 0x3B, 0x60, 0x28, 0xB1, 0x09, 0x4B, 0x0E, 0x60, 0x1B, 0x68, 0x0E, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0xF0, 0xBC, -+0x70, 0x47, 0x0B, 0x4B, 0x1B, 0x68, 0x1A, 0x07, 0xCE, 0xD1, 0x0B, 0x49, 0x0B, 0x48, 0xD9, 0x22, 0x03, 0xF0, 0xE4, 0xB9, -+0x38, 0x36, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x20, 0x01, 0x32, 0x40, 0x6C, 0x28, 0x17, 0x00, 0x44, 0x01, 0x32, 0x40, -+0x88, 0x80, 0x32, 0x40, 0x8C, 0x80, 0x32, 0x40, 0x38, 0x00, 0x32, 0x40, 0x1C, 0x9E, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xD4, 0xA4, 0x15, 0x00, 0x03, 0x4A, 0x01, 0x23, 0x13, 0x60, 0x13, 0x68, 0x13, 0xF0, 0xFF, 0x0F, 0xFB, 0xD1, 0x70, 0x47, -+0x50, 0x80, 0x32, 0x40, 0x70, 0xB5, 0x76, 0x4A, 0x01, 0x23, 0x82, 0xB0, 0x13, 0x60, 0x13, 0x68, 0x13, 0xF0, 0xFF, 0x0F, -+0xFB, 0xD1, 0x73, 0x4B, 0xD3, 0xF8, 0xF0, 0x40, 0xDE, 0xF7, 0x66, 0xFF, 0xA0, 0x47, 0x71, 0x4B, 0x71, 0x49, 0x72, 0x4A, -+0x19, 0x60, 0x13, 0x68, 0x71, 0x49, 0x23, 0xF4, 0x00, 0x63, 0x13, 0x60, 0x0B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0xC0, 0xF2, 0x86, 0x80, 0x6D, 0x48, 0x6E, 0x4B, 0x6A, 0x49, 0x6E, 0x4C, 0x6E, 0x4A, 0x04, 0x60, 0x1A, 0x60, 0x0A, 0x68, -+0x6D, 0x4C, 0x6E, 0x4D, 0x42, 0xF0, 0x80, 0x62, 0x42, 0xF4, 0xF8, 0x62, 0x0A, 0x60, 0x0A, 0x68, 0x22, 0xF0, 0x80, 0x62, -+0x0A, 0x60, 0x50, 0xF8, 0x84, 0x2C, 0x69, 0x49, 0xA3, 0xF5, 0x00, 0x43, 0x1C, 0x3B, 0x42, 0xF4, 0x80, 0x32, 0x40, 0xF8, -+0x84, 0x2C, 0x25, 0x60, 0x1A, 0x68, 0x42, 0xF0, 0x7F, 0x42, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF4, 0x00, 0x02, 0x1A, 0x60, -+0x1A, 0x68, 0x22, 0xF4, 0xFE, 0x02, 0x42, 0xF4, 0x80, 0x12, 0x1A, 0x60, 0x8A, 0x78, 0x2A, 0xB9, 0x1A, 0x68, 0x12, 0x0C, -+0x12, 0x04, 0x42, 0xF0, 0x64, 0x02, 0x1A, 0x60, 0x5A, 0x4B, 0x5B, 0x49, 0x50, 0x4C, 0x5B, 0x4E, 0x5B, 0x4D, 0x00, 0x22, -+0x4F, 0xF4, 0x40, 0x50, 0x08, 0x60, 0x1A, 0x60, 0x0D, 0xF1, 0x06, 0x01, 0x0D, 0xF1, 0x07, 0x00, 0xE0, 0xF7, 0x1C, 0xF9, -+0x9D, 0xF8, 0x07, 0x20, 0x9D, 0xF8, 0x06, 0x00, 0x54, 0x49, 0x13, 0x02, 0x43, 0xEA, 0x00, 0x43, 0x13, 0x43, 0x0B, 0x60, -+0x23, 0x68, 0x52, 0x4A, 0x43, 0xF4, 0x80, 0x53, 0x23, 0x60, 0x23, 0x68, 0x41, 0xF6, 0x25, 0x40, 0x43, 0xF4, 0x00, 0x53, -+0x23, 0x60, 0xC1, 0xF8, 0x70, 0x04, 0x13, 0x68, 0x23, 0xF0, 0x80, 0x03, 0x13, 0x60, 0xDF, 0xF7, 0x77, 0xFD, 0x32, 0x68, -+0x49, 0x49, 0x43, 0x1C, 0x9B, 0x06, 0x22, 0xF0, 0xE0, 0x52, 0x03, 0xF0, 0xE0, 0x53, 0x13, 0x43, 0x33, 0x60, 0x23, 0x68, -+0x45, 0x4A, 0x43, 0xF0, 0x20, 0x03, 0x23, 0x60, 0x0B, 0x68, 0x23, 0xF0, 0x01, 0x03, 0x0B, 0x60, 0x13, 0x68, 0x43, 0xF0, -+0x02, 0x03, 0x13, 0x60, 0x23, 0x68, 0x43, 0xF0, 0x00, 0x73, 0x23, 0x60, 0x2B, 0x68, 0x99, 0x03, 0x13, 0xD4, 0x3D, 0x4A, -+0x13, 0x68, 0x43, 0xF0, 0x01, 0x03, 0x13, 0x60, 0x02, 0xB0, 0x70, 0xBD, 0x2A, 0x4B, 0x1B, 0x68, 0xB3, 0xF1, 0xC8, 0x5F, -+0xBF, 0xF4, 0x74, 0xAF, 0x37, 0x49, 0x38, 0x48, 0x40, 0xF2, 0x21, 0x12, 0x03, 0xF0, 0x46, 0xF9, 0x6C, 0xE7, 0xDF, 0xF7, -+0x05, 0xFD, 0x00, 0x28, 0xE7, 0xD0, 0xDF, 0xF7, 0x35, 0xFD, 0x33, 0x4E, 0x32, 0x68, 0x00, 0x02, 0x00, 0xF4, 0xE0, 0x63, -+0x22, 0xF4, 0xE0, 0x62, 0x13, 0x43, 0x33, 0x60, 0x33, 0x68, 0x23, 0xF0, 0xE0, 0x03, 0x43, 0xF0, 0x60, 0x03, 0x33, 0x60, -+0x33, 0x68, 0x43, 0xF0, 0x04, 0x03, 0x33, 0x60, 0x33, 0x68, 0x43, 0xF0, 0x01, 0x03, 0x33, 0x60, 0x2B, 0x68, 0x1B, 0x04, -+0x0D, 0xD4, 0x1E, 0x4B, 0x1B, 0x68, 0x9A, 0x03, 0xC7, 0xD5, 0xDF, 0xF7, 0xE9, 0xFC, 0x00, 0x28, 0xC3, 0xD0, 0x22, 0x4A, -+0x13, 0x68, 0x43, 0xF0, 0x02, 0x03, 0x13, 0x60, 0xBD, 0xE7, 0xDF, 0xF7, 0xB1, 0xFC, 0x00, 0x28, 0xED, 0xD0, 0x23, 0x68, -+0x43, 0xF4, 0x00, 0x23, 0x23, 0x60, 0x33, 0x68, 0x23, 0xF0, 0x60, 0x63, 0x43, 0xF0, 0x80, 0x63, 0x33, 0x60, 0xE2, 0xE7, -+0x50, 0x80, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x74, 0x80, 0x32, 0x40, 0x4C, 0xF1, 0x73, 0x8B, 0x4C, 0x00, 0x32, 0x40, -+0x38, 0x36, 0x17, 0x00, 0xD8, 0x00, 0x32, 0x40, 0x80, 0x80, 0x32, 0x40, 0x10, 0x19, 0x04, 0x00, 0xC0, 0x07, 0xF9, 0x80, -+0x60, 0x00, 0x32, 0x40, 0xDE, 0xFF, 0xFF, 0x7F, 0x3C, 0x36, 0x17, 0x00, 0x24, 0x02, 0x32, 0x40, 0x58, 0x01, 0x32, 0x40, -+0x9C, 0x00, 0x32, 0x40, 0x04, 0x00, 0x32, 0x40, 0xA0, 0x00, 0x32, 0x40, 0x10, 0x03, 0x32, 0x40, 0x48, 0x80, 0x32, 0x40, -+0x6C, 0x00, 0x32, 0x40, 0x00, 0x04, 0x32, 0x40, 0x70, 0x79, 0x15, 0x00, 0x40, 0x88, 0x15, 0x00, 0x50, 0x03, 0x32, 0x40, -+0x05, 0x49, 0x06, 0x4A, 0x0B, 0x68, 0x23, 0xF0, 0x00, 0x43, 0x0B, 0x60, 0x13, 0x68, 0x23, 0xF0, 0x00, 0x43, 0x13, 0x60, -+0x70, 0x47, 0x00, 0xBF, 0x74, 0x80, 0x32, 0x40, 0x80, 0x80, 0x32, 0x40, 0x1D, 0x4A, 0x1E, 0x49, 0x13, 0x68, 0x1E, 0x48, -+0x30, 0xB4, 0x23, 0xF0, 0x80, 0x03, 0x00, 0x25, 0x3C, 0x24, 0x13, 0x60, 0x0D, 0x60, 0x0A, 0x46, 0x04, 0x60, 0x13, 0x68, -+0x1B, 0x07, 0xFC, 0xD1, 0x17, 0x4A, 0x18, 0x49, 0x13, 0x68, 0x18, 0x4D, 0x18, 0x48, 0x19, 0x4C, 0x43, 0xF4, 0x80, 0x33, -+0x13, 0x60, 0x0B, 0x68, 0x02, 0xF5, 0x00, 0x42, 0x23, 0xF0, 0xFF, 0x03, 0x0B, 0x60, 0x20, 0x32, 0x4F, 0xF0, 0xFF, 0x33, -+0x2B, 0x60, 0x04, 0x60, 0x13, 0x68, 0x12, 0x4C, 0x12, 0x49, 0x43, 0xF0, 0x00, 0x43, 0x13, 0x60, 0x22, 0x68, 0x4B, 0x68, -+0xA0, 0xF5, 0x00, 0x40, 0x24, 0x38, 0x42, 0xF0, 0x00, 0x42, 0x22, 0x60, 0x02, 0x68, 0x23, 0xF0, 0x04, 0x03, 0x42, 0xF0, -+0x80, 0x02, 0x02, 0x60, 0x30, 0xBC, 0x4B, 0x60, 0x70, 0x47, 0x00, 0xBF, 0x4C, 0x00, 0x32, 0x40, 0x38, 0x00, 0x32, 0x40, -+0x54, 0x00, 0x32, 0x40, 0x8C, 0x80, 0x32, 0x40, 0x7C, 0x80, 0x32, 0x40, 0x70, 0x80, 0x32, 0x40, 0x44, 0xF1, 0x73, 0x0B, -+0x80, 0x80, 0x32, 0x40, 0x1C, 0x9E, 0x17, 0x00, 0x0B, 0x49, 0x0C, 0x4A, 0x0C, 0x4B, 0x10, 0xB4, 0x04, 0x68, 0x80, 0x88, -+0x0C, 0x60, 0x4F, 0xF0, 0x00, 0x51, 0x10, 0x60, 0x1A, 0x46, 0x19, 0x60, 0x10, 0x68, 0x81, 0x00, 0xFC, 0xD4, 0xC3, 0x00, -+0x5D, 0xBF, 0x00, 0x0C, 0x10, 0x38, 0xC0, 0xB2, 0xFF, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0xBC, 0x00, 0x32, 0x40, -+0xC0, 0x00, 0x32, 0x40, 0xC4, 0x00, 0x32, 0x40, 0x38, 0xB5, 0x11, 0x4B, 0x11, 0x48, 0x19, 0x68, 0x42, 0x68, 0x11, 0x4C, -+0x11, 0x4D, 0x21, 0xF0, 0x01, 0x01, 0x19, 0x60, 0x19, 0x68, 0x21, 0xF0, 0x02, 0x01, 0x19, 0x60, 0x23, 0x68, 0x0E, 0x49, -+0x43, 0xF4, 0xE0, 0x63, 0x2A, 0x43, 0x23, 0x60, 0x05, 0x60, 0x01, 0x20, 0x0A, 0x60, 0xF3, 0xF7, 0x51, 0xFB, 0x23, 0x68, -+0x23, 0xF4, 0xE0, 0x33, 0x43, 0xF4, 0x80, 0x33, 0x23, 0x60, 0x23, 0x68, 0x43, 0xF4, 0x00, 0x53, 0x23, 0x60, 0x38, 0xBD, -+0x74, 0x80, 0x32, 0x40, 0x98, 0x9C, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, 0xDE, 0xFF, 0xFF, 0x7F, 0x60, 0x00, 0x32, 0x40, -+0x80, 0xEA, 0xE0, 0x72, 0xF0, 0xB4, 0xA2, 0xEB, 0xE0, 0x72, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x16, 0x4B, 0x01, 0x21, 0x19, 0x60, 0x16, 0x4D, 0x16, 0x4B, 0x2E, 0x68, 0x1B, 0x68, 0x16, 0x49, 0x77, 0x1C, 0x00, 0x28, -+0x09, 0x68, 0x2F, 0x60, 0x43, 0xF0, 0x80, 0x73, 0x15, 0xDD, 0x8A, 0x42, 0x18, 0xD8, 0x11, 0x49, 0x0F, 0x4C, 0x0A, 0x68, -+0x10, 0x1A, 0x08, 0x60, 0x23, 0x60, 0x08, 0x60, 0x23, 0x60, 0x08, 0x60, 0x00, 0x20, 0x23, 0x60, 0x2F, 0xB1, 0x08, 0x4B, -+0x2E, 0x60, 0x1B, 0x68, 0x0E, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0xF0, 0xBC, 0x70, 0x47, 0xEA, 0xD0, 0xC9, 0x43, 0x20, 0x32, -+0x91, 0x42, 0xE6, 0xD2, 0x4F, 0xF0, 0xFF, 0x30, 0xEE, 0xE7, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x4C, 0x00, 0x32, 0x40, 0xA4, 0x80, 0x32, 0x40, 0x35, 0x4B, 0x1B, 0x68, 0x70, 0xB5, 0xC3, 0xF3, 0x40, 0x64, 0x9B, 0x01, -+0x12, 0xD4, 0x33, 0x49, 0x33, 0x48, 0x0B, 0x69, 0x33, 0x4A, 0x05, 0x68, 0x08, 0x69, 0xB2, 0xF8, 0xB0, 0x10, 0xB2, 0xF8, -+0xB2, 0x20, 0xA3, 0xF5, 0xFA, 0x63, 0x03, 0xEB, 0x45, 0x13, 0x1B, 0x1A, 0x5B, 0x1A, 0x9B, 0x1A, 0x00, 0x2B, 0x17, 0xDB, -+0x2C, 0x4B, 0x1D, 0x68, 0x9D, 0xB1, 0x28, 0x48, 0x29, 0x4E, 0xEA, 0x68, 0x03, 0x69, 0xB6, 0xF8, 0xB0, 0x40, 0xB6, 0xF8, -+0xB2, 0x10, 0xD3, 0x1A, 0xA3, 0xF5, 0xFA, 0x63, 0x1B, 0x1B, 0x5B, 0x1A, 0x00, 0x2B, 0x07, 0xDB, 0x24, 0x4B, 0x1B, 0x68, -+0x1C, 0x78, 0x01, 0x2C, 0x0B, 0xD0, 0x01, 0x24, 0x20, 0x46, 0x70, 0xBD, 0x21, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x12, 0xDB, 0x00, 0x24, 0x20, 0x46, 0x70, 0xBD, 0x1D, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0x18, 0xDB, 0x15, 0x4B, 0x52, 0x1A, 0x4F, 0xF4, 0x80, 0x20, 0x04, 0x21, 0x98, 0x60, 0x1A, 0x63, 0x20, 0x46, 0x99, 0x60, -+0x70, 0xBD, 0x03, 0x69, 0xD2, 0x1A, 0x02, 0xF5, 0x9C, 0x52, 0x08, 0x32, 0x00, 0x2A, 0xE5, 0xDA, 0x12, 0x49, 0x13, 0x48, -+0x40, 0xF2, 0x3E, 0x22, 0x02, 0xF0, 0x92, 0xFF, 0x00, 0x24, 0xD5, 0xE7, 0x03, 0x69, 0xD3, 0x1A, 0x5B, 0x1A, 0x00, 0x2B, -+0xE1, 0xDA, 0x0C, 0x49, 0x0D, 0x48, 0x40, 0xF2, 0x43, 0x22, 0x02, 0xF0, 0x85, 0xFF, 0xEA, 0x68, 0xB6, 0xF8, 0xB2, 0x10, -+0xD7, 0xE7, 0x00, 0xBF, 0x4C, 0x00, 0x32, 0x40, 0x00, 0x10, 0x50, 0x40, 0x40, 0x80, 0x32, 0x40, 0x2C, 0x19, 0x17, 0x00, -+0xD0, 0x9C, 0x17, 0x00, 0x74, 0x36, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xFC, 0xA4, 0x15, 0x00, -+0x80, 0x8D, 0x15, 0x00, 0x70, 0xB4, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0B, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x0B, 0x4B, 0x0B, 0x49, 0x0C, 0x4D, 0x0E, 0x68, 0x1A, 0x68, 0x28, 0x68, 0x09, 0x68, 0x54, 0x1C, 0xB1, 0x42, -+0x18, 0xBF, 0x28, 0x68, 0x1C, 0x60, 0x2C, 0xB1, 0x03, 0x4C, 0x1A, 0x60, 0x23, 0x68, 0x0A, 0xB9, 0x03, 0xB1, 0x62, 0xB6, -+0x70, 0xBC, 0x70, 0x47, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xA8, 0x80, 0x32, 0x40, 0xA4, 0x80, 0x32, 0x40, -+0x3B, 0x4A, 0x3C, 0x4B, 0x10, 0xB5, 0x14, 0x68, 0x1C, 0x60, 0x61, 0x05, 0x1D, 0xD4, 0xE2, 0x05, 0x16, 0xD4, 0xA3, 0x05, -+0x10, 0xD4, 0xE0, 0x06, 0x31, 0xD4, 0x37, 0x4B, 0x1A, 0x78, 0x22, 0xB1, 0x14, 0xF0, 0x2F, 0x0F, 0x1C, 0xBF, 0x01, 0x22, -+0x9A, 0x71, 0x34, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x0D, 0xDB, 0x10, 0xBD, 0x31, 0x48, 0x02, 0xF0, -+0xAD, 0xFC, 0xFE, 0xE7, 0xF2, 0xF7, 0x96, 0xFD, 0xA3, 0x05, 0xE6, 0xD5, 0xF6, 0xE7, 0x2E, 0x48, 0x02, 0xF0, 0xA4, 0xFC, -+0xFE, 0xE7, 0xE1, 0x07, 0x1C, 0xD4, 0xA2, 0x07, 0x42, 0xD4, 0x63, 0x07, 0x38, 0xD4, 0x20, 0x07, 0x2E, 0xD4, 0x21, 0x06, -+0x24, 0xD4, 0x62, 0x06, 0x1A, 0xD4, 0xA3, 0x06, 0xE3, 0xD5, 0xBD, 0xE8, 0x10, 0x40, 0x25, 0x49, 0x25, 0x48, 0x40, 0xF2, -+0xB5, 0x22, 0x02, 0xF0, 0xD5, 0xBE, 0x04, 0x20, 0xEC, 0xF7, 0xA4, 0xFD, 0x4F, 0xF0, 0x80, 0x41, 0x04, 0x20, 0xEC, 0xF7, -+0x3F, 0xFE, 0xC4, 0xE7, 0xBD, 0xE8, 0x10, 0x40, 0x1C, 0x49, 0x1E, 0x48, 0x4F, 0xF4, 0x2B, 0x72, 0x02, 0xF0, 0xC4, 0xBE, -+0xBD, 0xE8, 0x10, 0x40, 0x18, 0x49, 0x1B, 0x48, 0x40, 0xF2, 0xB3, 0x22, 0x02, 0xF0, 0xBC, 0xBE, 0xBD, 0xE8, 0x10, 0x40, -+0x14, 0x49, 0x18, 0x48, 0x40, 0xF2, 0xB1, 0x22, 0x02, 0xF0, 0xB4, 0xBE, 0xBD, 0xE8, 0x10, 0x40, 0x10, 0x49, 0x15, 0x48, -+0x40, 0xF2, 0xAF, 0x22, 0x02, 0xF0, 0xAC, 0xBE, 0xBD, 0xE8, 0x10, 0x40, 0x0C, 0x49, 0x12, 0x48, 0x40, 0xF2, 0xAE, 0x22, -+0x02, 0xF0, 0xA4, 0xBE, 0xBD, 0xE8, 0x10, 0x40, 0x08, 0x49, 0x0F, 0x48, 0x40, 0xF2, 0xAD, 0x22, 0x02, 0xF0, 0x9C, 0xBE, -+0x84, 0x80, 0x32, 0x40, 0x88, 0x80, 0x32, 0x40, 0x80, 0x35, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x5C, 0xA5, 0x15, 0x00, -+0x28, 0xA5, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, 0x80, 0xA6, 0x15, 0x00, 0x90, 0xA5, 0x15, 0x00, 0x58, 0xA6, 0x15, 0x00, -+0x30, 0xA6, 0x15, 0x00, 0x08, 0xA6, 0x15, 0x00, 0xE0, 0xA5, 0x15, 0x00, 0xB8, 0xA5, 0x15, 0x00, 0x38, 0xB5, 0x62, 0x4A, -+0x62, 0x4B, 0x11, 0x68, 0x1C, 0x68, 0x62, 0x4B, 0x0C, 0x40, 0x23, 0x40, 0x54, 0x60, 0x00, 0x2B, 0x54, 0xD1, 0x60, 0x4B, -+0x23, 0x40, 0x00, 0x2B, 0x4B, 0xD1, 0x62, 0x07, 0x03, 0xD5, 0x5E, 0x4B, 0xD3, 0xF8, 0xDC, 0x30, 0x98, 0x47, 0x23, 0x07, -+0x03, 0xD5, 0x5B, 0x4B, 0xD3, 0xF8, 0xD4, 0x30, 0x98, 0x47, 0xE5, 0x00, 0x2E, 0xD4, 0xE0, 0x05, 0x28, 0xD4, 0x58, 0x4B, -+0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x00, 0xDB, 0x38, 0xBD, 0x61, 0x02, 0x3C, 0xD4, 0xA2, 0x02, 0x42, 0xD4, -+0x63, 0x06, 0x48, 0xD4, 0xE5, 0x04, 0x4E, 0xD4, 0xA0, 0x04, 0x54, 0xD4, 0x61, 0x04, 0x5A, 0xD4, 0x22, 0x04, 0x60, 0xD4, -+0xE3, 0x03, 0x66, 0xD4, 0xA5, 0x03, 0x6C, 0xD4, 0xE0, 0x01, 0x72, 0xD4, 0xA1, 0x01, 0x78, 0xD4, 0xE2, 0x02, 0x7E, 0xD4, -+0x23, 0x01, 0xE4, 0xD5, 0xBD, 0xE8, 0x38, 0x40, 0x47, 0x49, 0x48, 0x48, 0x40, 0xF2, 0x19, 0x32, 0x02, 0xF0, 0x38, 0xBE, -+0x46, 0x48, 0x02, 0xF0, 0xED, 0xFB, 0xD2, 0xE7, 0x45, 0x4B, 0x46, 0x4A, 0x1D, 0x68, 0x93, 0x7F, 0x05, 0xF0, 0x3F, 0x01, -+0x0B, 0x43, 0x4F, 0xF4, 0x00, 0x20, 0x93, 0x77, 0x01, 0xF0, 0x64, 0xF9, 0x41, 0x4B, 0x1D, 0x60, 0xC1, 0xE7, 0x4F, 0xF0, -+0x80, 0x70, 0x01, 0xF0, 0x5D, 0xF9, 0xAE, 0xE7, 0x4F, 0xF0, 0x00, 0x70, 0x01, 0xF0, 0x58, 0xF9, 0xA5, 0xE7, 0xBD, 0xE8, -+0x38, 0x40, 0x35, 0x49, 0x3A, 0x48, 0x40, 0xF2, 0x0B, 0x32, 0x02, 0xF0, 0x13, 0xBE, 0xBD, 0xE8, 0x38, 0x40, 0x31, 0x49, -+0x37, 0x48, 0x4F, 0xF4, 0x43, 0x72, 0x02, 0xF0, 0x0B, 0xBE, 0xBD, 0xE8, 0x38, 0x40, 0x2D, 0x49, 0x34, 0x48, 0x40, 0xF2, -+0x0D, 0x32, 0x02, 0xF0, 0x03, 0xBE, 0xBD, 0xE8, 0x38, 0x40, 0x29, 0x49, 0x31, 0x48, 0x4F, 0xF4, 0x44, 0x72, 0x02, 0xF0, -+0xFB, 0xBD, 0xBD, 0xE8, 0x38, 0x40, 0x25, 0x49, 0x2E, 0x48, 0x40, 0xF2, 0x11, 0x32, 0x02, 0xF0, 0xF3, 0xBD, 0xBD, 0xE8, -+0x38, 0x40, 0x21, 0x49, 0x2B, 0x48, 0x40, 0xF2, 0x12, 0x32, 0x02, 0xF0, 0xEB, 0xBD, 0xBD, 0xE8, 0x38, 0x40, 0x1D, 0x49, -+0x28, 0x48, 0x40, 0xF2, 0x13, 0x32, 0x02, 0xF0, 0xE3, 0xBD, 0xBD, 0xE8, 0x38, 0x40, 0x19, 0x49, 0x25, 0x48, 0x4F, 0xF4, -+0x45, 0x72, 0x02, 0xF0, 0xDB, 0xBD, 0xBD, 0xE8, 0x38, 0x40, 0x15, 0x49, 0x22, 0x48, 0x40, 0xF2, 0x15, 0x32, 0x02, 0xF0, -+0xD3, 0xBD, 0xBD, 0xE8, 0x38, 0x40, 0x11, 0x49, 0x1F, 0x48, 0x40, 0xF2, 0x16, 0x32, 0x02, 0xF0, 0xCB, 0xBD, 0xBD, 0xE8, -+0x38, 0x40, 0x0D, 0x49, 0x1C, 0x48, 0x40, 0xF2, 0x17, 0x32, 0x02, 0xF0, 0xC3, 0xBD, 0xBD, 0xE8, 0x38, 0x40, 0x09, 0x49, -+0x19, 0x48, 0x4F, 0xF4, 0x46, 0x72, 0x02, 0xF0, 0xBB, 0xBD, 0x00, 0xBF, 0x6C, 0x80, 0x32, 0x40, 0x74, 0x80, 0x32, 0x40, -+0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x08, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x10, 0xA9, 0x15, 0x00, 0xA8, 0xA6, 0x15, 0x00, 0x90, 0x80, 0x32, 0x40, 0x98, 0x9C, 0x17, 0x00, 0x94, 0x80, 0x32, 0x40, -+0xD8, 0xA6, 0x15, 0x00, 0x00, 0xA7, 0x15, 0x00, 0x34, 0xA7, 0x15, 0x00, 0x68, 0xA7, 0x15, 0x00, 0x90, 0xA7, 0x15, 0x00, -+0xC0, 0xA7, 0x15, 0x00, 0xF0, 0xA7, 0x15, 0x00, 0x20, 0xA8, 0x15, 0x00, 0x50, 0xA8, 0x15, 0x00, 0x80, 0xA8, 0x15, 0x00, -+0xB4, 0xA8, 0x15, 0x00, 0xE8, 0xA8, 0x15, 0x00, 0x10, 0xB5, 0x18, 0x4B, 0x84, 0xB0, 0xD3, 0xF8, 0x20, 0x32, 0x8D, 0xF8, -+0x07, 0x00, 0x0D, 0xF1, 0x0F, 0x02, 0x0D, 0xF1, 0x0E, 0x01, 0x0D, 0xF1, 0x07, 0x00, 0x98, 0x47, 0x12, 0x4A, 0x13, 0x49, -+0x13, 0x68, 0x9D, 0xF8, 0x0E, 0x40, 0x91, 0xF8, 0xBA, 0x00, 0x23, 0xF4, 0x7F, 0x43, 0x43, 0xEA, 0x04, 0x23, 0x13, 0x60, -+0x18, 0xB1, 0x0E, 0x4B, 0x93, 0xF8, 0x2A, 0x30, 0x4B, 0xB1, 0x0A, 0x4A, 0x9D, 0xF8, 0x0F, 0x10, 0x13, 0x68, 0x23, 0xF0, -+0xFF, 0x03, 0x0B, 0x43, 0x13, 0x60, 0x04, 0xB0, 0x10, 0xBD, 0x13, 0x68, 0x91, 0xF8, 0xBB, 0x10, 0x23, 0xF0, 0xFF, 0x03, -+0x0B, 0x43, 0x13, 0x60, 0x04, 0xB0, 0x10, 0xBD, 0x88, 0x1A, 0x17, 0x00, 0xA0, 0x00, 0x32, 0x40, 0x2C, 0x19, 0x17, 0x00, -+0xBC, 0x34, 0x17, 0x00, 0x30, 0xB5, 0x90, 0xF9, 0x65, 0x50, 0x7F, 0x2D, 0x83, 0xB0, 0x0E, 0xD0, 0x90, 0xF9, 0x66, 0x30, -+0x0B, 0x48, 0x9D, 0x42, 0xA8, 0xBF, 0x1D, 0x46, 0x8D, 0xF8, 0x07, 0x50, 0xD0, 0xF8, 0x20, 0x32, 0x0D, 0xF1, 0x07, 0x00, -+0x98, 0x47, 0x03, 0xB0, 0x30, 0xBD, 0x0C, 0x46, 0x05, 0x49, 0x13, 0x46, 0x0A, 0x68, 0x12, 0x0A, 0x22, 0x70, 0x0A, 0x68, -+0x1A, 0x70, 0x03, 0xB0, 0x30, 0xBD, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0xA0, 0x00, 0x32, 0x40, 0x91, 0xF9, 0x00, 0x30, -+0x7F, 0x2B, 0x40, 0xD0, 0xF0, 0xB5, 0x20, 0x4E, 0x90, 0xF9, 0x65, 0x70, 0xD6, 0xF8, 0x20, 0x32, 0x85, 0xB0, 0x0C, 0x46, -+0x05, 0x46, 0x11, 0x46, 0x20, 0x46, 0x0D, 0xF1, 0x0F, 0x02, 0x01, 0x91, 0x98, 0x47, 0x94, 0xF9, 0x00, 0x30, 0x95, 0xF9, -+0x66, 0x20, 0x85, 0xF8, 0x65, 0x30, 0x93, 0x42, 0x20, 0xDC, 0x94, 0xF9, 0x00, 0x30, 0xBB, 0x42, 0x1A, 0xD0, 0xD5, 0xF8, -+0xE4, 0x30, 0x43, 0xB1, 0x93, 0xF8, 0x56, 0x21, 0x42, 0xF0, 0x10, 0x02, 0x83, 0xF8, 0x56, 0x21, 0x1B, 0x68, 0x00, 0x2B, -+0xF6, 0xD1, 0x28, 0x6C, 0x60, 0xB1, 0xD6, 0xF8, 0xB4, 0x30, 0x98, 0x47, 0x28, 0x46, 0xFC, 0xF7, 0x5D, 0xFC, 0x28, 0xB1, -+0x2A, 0x6C, 0xD6, 0xF8, 0x3C, 0x33, 0x92, 0xF9, 0x0C, 0x00, 0x98, 0x47, 0x05, 0xB0, 0xF0, 0xBD, 0x22, 0x70, 0x01, 0x99, -+0xD6, 0xF8, 0x20, 0x32, 0x0D, 0xF1, 0x0F, 0x02, 0x20, 0x46, 0x98, 0x47, 0xD5, 0xE7, 0x70, 0x47, 0x88, 0x1A, 0x17, 0x00, -+0x10, 0xB5, 0x15, 0x4B, 0x82, 0xB0, 0x0C, 0x46, 0xD3, 0xF8, 0x38, 0x33, 0x0D, 0xF1, 0x07, 0x02, 0x0D, 0xF1, 0x06, 0x01, -+0x98, 0x47, 0xE2, 0x6C, 0x10, 0x4B, 0x94, 0x6B, 0x93, 0xF8, 0xBD, 0x30, 0x61, 0x69, 0xC1, 0xF3, 0xC2, 0x20, 0xC9, 0xB2, -+0x6B, 0xB9, 0x01, 0xF0, 0x7C, 0x01, 0x50, 0xEA, 0x01, 0x03, 0x0C, 0xBF, 0x9D, 0xF8, 0x06, 0x30, 0x9D, 0xF8, 0x07, 0x30, -+0x43, 0xEA, 0x03, 0x23, 0x63, 0x62, 0x02, 0xB0, 0x10, 0xBD, 0x01, 0xF0, 0x7F, 0x01, 0xDF, 0xF7, 0xB1, 0xFA, 0x40, 0xEA, -+0x00, 0x20, 0x60, 0x62, 0x02, 0xB0, 0x10, 0xBD, 0x88, 0x1A, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x00, 0x29, 0x11, 0xDD, -+0x10, 0xB4, 0x01, 0x39, 0x00, 0x23, 0x01, 0x24, 0x10, 0xF0, 0x01, 0x0F, 0x1C, 0xBF, 0x04, 0xFA, 0x01, 0xF2, 0x13, 0x43, -+0x01, 0x39, 0x4F, 0xEA, 0x50, 0x00, 0xF5, 0xD2, 0x18, 0x46, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x23, 0x18, 0x46, -+0x70, 0x47, 0x00, 0xBF, 0x0B, 0x1F, 0x03, 0x44, 0x01, 0x44, 0x03, 0xF8, 0x01, 0x2B, 0x8B, 0x42, 0x4F, 0xEA, 0x12, 0x22, -+0xF9, 0xD1, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x4F, 0x89, 0xB0, 0x8D, 0x88, 0x0C, 0x7D, 0x00, 0x95, 0x0D, 0x68, 0x01, 0x95, -+0x03, 0x93, 0x1C, 0xB1, 0x0B, 0x69, 0xAB, 0x42, 0x00, 0xF0, 0xAC, 0x81, 0x01, 0x9B, 0xD9, 0x4F, 0x9C, 0xB2, 0x4F, 0xEA, -+0x13, 0x4C, 0xCC, 0x80, 0xA1, 0xF8, 0x08, 0xC0, 0x53, 0x78, 0x16, 0x78, 0x46, 0xEA, 0x03, 0x26, 0x4E, 0x81, 0xD3, 0x78, -+0x95, 0x78, 0x45, 0xEA, 0x03, 0x25, 0x8D, 0x81, 0x92, 0xF8, 0x05, 0xE0, 0x13, 0x79, 0x43, 0xEA, 0x0E, 0x23, 0xCB, 0x81, -+0x4F, 0xF0, 0x00, 0x09, 0x09, 0xF0, 0x01, 0x0A, 0x00, 0xEB, 0x4A, 0x02, 0x10, 0xF8, 0x1A, 0x80, 0x92, 0xF8, 0x01, 0xE0, -+0x02, 0x92, 0x48, 0xEA, 0x0E, 0x22, 0x5A, 0x40, 0x4F, 0xEA, 0x12, 0x2E, 0xD2, 0xB2, 0x37, 0xF8, 0x1E, 0xE0, 0x37, 0xF8, -+0x12, 0x80, 0x4F, 0xEA, 0x1E, 0x22, 0x42, 0xEA, 0x0E, 0x22, 0x82, 0xEA, 0x08, 0x02, 0x4F, 0xEA, 0x4A, 0x08, 0x14, 0x44, -+0x08, 0xF1, 0x04, 0x02, 0xA4, 0xB2, 0x00, 0xEB, 0x02, 0x0E, 0xCC, 0x80, 0x82, 0x5C, 0x9E, 0xF8, 0x01, 0xE0, 0x42, 0xEA, -+0x0E, 0x2E, 0x84, 0xEA, 0x0E, 0x0E, 0xCE, 0xF3, 0x0F, 0x22, 0x5F, 0xFA, 0x8E, 0xFE, 0x37, 0xF8, 0x12, 0x20, 0x37, 0xF8, -+0x1E, 0xB0, 0x4F, 0xEA, 0x12, 0x2E, 0x4E, 0xEA, 0x02, 0x2E, 0x8E, 0xEA, 0x0B, 0x0B, 0xDC, 0x44, 0x08, 0xF1, 0x08, 0x0E, -+0x1F, 0xFA, 0x8C, 0xFC, 0x00, 0xEB, 0x0E, 0x02, 0xA1, 0xF8, 0x08, 0xC0, 0x10, 0xF8, 0x0E, 0xE0, 0x52, 0x78, 0x4E, 0xEA, -+0x02, 0x22, 0x8C, 0xEA, 0x02, 0x02, 0xC2, 0xF3, 0x0F, 0x2E, 0xD2, 0xB2, 0x37, 0xF8, 0x1E, 0xE0, 0x37, 0xF8, 0x12, 0xB0, -+0x4F, 0xEA, 0x1E, 0x22, 0x42, 0xEA, 0x0E, 0x22, 0x82, 0xEA, 0x0B, 0x0B, 0x08, 0xF1, 0x0C, 0x08, 0x5E, 0x44, 0x00, 0xEB, -+0x08, 0x02, 0xB6, 0xB2, 0x4E, 0x81, 0x92, 0xF8, 0x01, 0xE0, 0x10, 0xF8, 0x08, 0x20, 0x42, 0xEA, 0x0E, 0x22, 0x72, 0x40, -+0xC2, 0xF3, 0x0F, 0x2E, 0xD2, 0xB2, 0x37, 0xF8, 0x1E, 0xE0, 0x37, 0xF8, 0x12, 0x80, 0x4F, 0xEA, 0x1E, 0x22, 0x42, 0xEA, -+0x0E, 0x22, 0x82, 0xEA, 0x08, 0x02, 0x15, 0x44, 0xAD, 0xB2, 0x02, 0x9A, 0x8D, 0x81, 0x92, 0xF8, 0x01, 0xE0, 0x10, 0xF8, -+0x1A, 0x20, 0x42, 0xEA, 0x0E, 0x22, 0x6A, 0x40, 0xC2, 0xF3, 0x0F, 0x2E, 0xD2, 0xB2, 0x37, 0xF8, 0x1E, 0xE0, 0x37, 0xF8, -+0x12, 0x80, 0x4F, 0xEA, 0x1E, 0x22, 0x42, 0xEA, 0x0E, 0x22, 0x82, 0xEA, 0x08, 0x02, 0x19, 0xFA, 0x82, 0xF2, 0x13, 0x44, -+0x09, 0xF1, 0x01, 0x09, 0x9B, 0xB2, 0xB9, 0xF1, 0x08, 0x0F, 0xCB, 0x81, 0x7F, 0xF4, 0x6E, 0xAF, 0x01, 0x9A, 0x0A, 0x61, -+0x4F, 0xF0, 0x01, 0x0E, 0x81, 0xF8, 0x14, 0xE0, 0x00, 0x9A, 0x90, 0xF8, 0x01, 0x80, 0x90, 0xF8, 0x00, 0xE0, 0x90, 0xF8, -+0x03, 0x90, 0x1A, 0x44, 0x4E, 0xEA, 0x08, 0x2E, 0x92, 0xB2, 0x82, 0xEA, 0x0E, 0x0E, 0x4F, 0xEA, 0x1E, 0x28, 0x5F, 0xFA, -+0x8E, 0xFE, 0x37, 0xF8, 0x18, 0xA0, 0x37, 0xF8, 0x1E, 0x80, 0x4F, 0xEA, 0x1A, 0x2E, 0x4E, 0xEA, 0x0A, 0x2A, 0x8A, 0xEA, -+0x08, 0x0A, 0x90, 0xF8, 0x02, 0x80, 0x90, 0xF8, 0x05, 0xE0, 0x54, 0x44, 0xA4, 0xB2, 0x48, 0xEA, 0x09, 0x28, 0x84, 0xEA, -+0x08, 0x08, 0x4F, 0xEA, 0x18, 0x2A, 0x5F, 0xFA, 0x88, 0xF8, 0x37, 0xF8, 0x1A, 0xA0, 0x37, 0xF8, 0x18, 0x90, 0x4F, 0xEA, -+0x1A, 0x28, 0x48, 0xEA, 0x0A, 0x2A, 0x8A, 0xEA, 0x09, 0x0A, 0x90, 0xF8, 0x04, 0x90, 0x90, 0xF8, 0x07, 0x80, 0xD4, 0x44, -+0x1F, 0xFA, 0x8C, 0xFC, 0x49, 0xEA, 0x0E, 0x2E, 0x8C, 0xEA, 0x0E, 0x0E, 0x4F, 0xEA, 0x1E, 0x2A, 0x5F, 0xFA, 0x8E, 0xFE, -+0x37, 0xF8, 0x1A, 0xA0, 0x37, 0xF8, 0x1E, 0x90, 0x4F, 0xEA, 0x1A, 0x2E, 0x4E, 0xEA, 0x0A, 0x2A, 0x8A, 0xEA, 0x09, 0x0A, -+0x90, 0xF8, 0x06, 0x90, 0x90, 0xF8, 0x09, 0xE0, 0x56, 0x44, 0xB6, 0xB2, 0x49, 0xEA, 0x08, 0x28, 0x86, 0xEA, 0x08, 0x08, -+0x4F, 0xEA, 0x18, 0x2A, 0x5F, 0xFA, 0x88, 0xF8, 0x37, 0xF8, 0x1A, 0xA0, 0x37, 0xF8, 0x18, 0x90, 0x4F, 0xEA, 0x1A, 0x28, -+0x48, 0xEA, 0x0A, 0x2A, 0x8A, 0xEA, 0x09, 0x0A, 0x90, 0xF8, 0x08, 0x90, 0x90, 0xF8, 0x0B, 0x80, 0x55, 0x44, 0xAD, 0xB2, -+0x49, 0xEA, 0x0E, 0x2E, 0x85, 0xEA, 0x0E, 0x0E, 0x4F, 0xEA, 0x1E, 0x2A, 0x5F, 0xFA, 0x8E, 0xFE, 0x37, 0xF8, 0x1A, 0xA0, -+0x37, 0xF8, 0x1E, 0x90, 0x4F, 0xEA, 0x1A, 0x2E, 0x4E, 0xEA, 0x0A, 0x2A, 0x8A, 0xEA, 0x09, 0x0A, 0x90, 0xF8, 0x0A, 0xE0, -+0x90, 0xF8, 0x0D, 0x90, 0x53, 0x44, 0x9B, 0xB2, 0x4E, 0xEA, 0x08, 0x2E, 0x83, 0xEA, 0x0E, 0x0E, 0x4F, 0xEA, 0x1E, 0x2A, -+0x5F, 0xFA, 0x8E, 0xFE, 0x37, 0xF8, 0x1A, 0xA0, 0x37, 0xF8, 0x1E, 0x80, 0x07, 0x7B, 0x4F, 0xEA, 0x1A, 0x2E, 0x4E, 0xEA, -+0x0A, 0x2E, 0x8E, 0xEA, 0x08, 0x08, 0x42, 0x44, 0x92, 0xB2, 0x47, 0xEA, 0x09, 0x29, 0x82, 0xEA, 0x09, 0x07, 0xFF, 0x03, -+0x82, 0xEA, 0x09, 0x09, 0x90, 0xF8, 0x0F, 0xE0, 0x47, 0xEA, 0x59, 0x09, 0x87, 0x7B, 0x4C, 0x44, 0xA4, 0xB2, 0x47, 0xEA, -+0x0E, 0x27, 0x84, 0xEA, 0x07, 0x0E, 0x4F, 0xEA, 0xCE, 0x3E, 0x67, 0x40, 0x4E, 0xEA, 0x57, 0x07, 0x67, 0x44, 0xBF, 0xB2, -+0x4F, 0xEA, 0xC7, 0x3C, 0x4C, 0xEA, 0x57, 0x0C, 0x66, 0x44, 0xB6, 0xB2, 0x4F, 0xEA, 0xC6, 0x3C, 0x4C, 0xEA, 0x56, 0x0C, -+0x65, 0x44, 0xAD, 0xB2, 0x4F, 0xEA, 0xC5, 0x3C, 0x4C, 0xEA, 0x55, 0x0C, 0x63, 0x44, 0x1F, 0xFA, 0x83, 0xF9, 0x00, 0x9B, -+0xAD, 0xF8, 0x18, 0x60, 0x4F, 0xEA, 0x13, 0x2E, 0x0E, 0xF0, 0x7F, 0x0C, 0xAD, 0xF8, 0x16, 0x70, 0xAD, 0xF8, 0x1A, 0x50, -+0x03, 0x9E, 0x00, 0x9D, 0xB5, 0x70, 0x4C, 0xF0, 0x20, 0x0C, 0x86, 0xF8, 0x00, 0xE0, 0x86, 0xF8, 0x01, 0xC0, 0x4F, 0xEA, -+0xC9, 0x38, 0x45, 0x78, 0x03, 0x78, 0xAD, 0xF8, 0x1C, 0x90, 0x48, 0xEA, 0x59, 0x08, 0x42, 0x44, 0x92, 0xB2, 0x43, 0xEA, -+0x05, 0x23, 0xAD, 0xF8, 0x1E, 0x20, 0x5A, 0x40, 0x52, 0x08, 0xF2, 0x70, 0x33, 0x46, 0x06, 0xF1, 0x0C, 0x00, 0x05, 0xAA, -+0x01, 0xE0, 0x32, 0xF8, 0x02, 0x4F, 0x1C, 0x71, 0x25, 0x0A, 0x5D, 0x71, 0x02, 0x33, 0x98, 0x42, 0xF7, 0xD1, 0x00, 0x23, -+0x0B, 0x75, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xCC, 0x88, 0xB1, 0xF8, 0x08, 0xC0, 0x4E, 0x89, 0x8D, 0x89, 0xCB, 0x89, -+0x00, 0x4F, 0xFD, 0xE6, 0x50, 0xA9, 0x15, 0x00, 0xF0, 0xB4, 0x13, 0x4F, 0x01, 0x22, 0x3C, 0x1F, 0x00, 0x23, 0xC7, 0xF8, -+0x00, 0x24, 0xC7, 0xF8, 0x04, 0x34, 0x22, 0x46, 0x42, 0xF8, 0x04, 0x3F, 0x01, 0x33, 0xB3, 0xF5, 0x80, 0x7F, 0xF9, 0xD1, -+0x00, 0x23, 0xDF, 0xF8, 0x30, 0xC0, 0x1D, 0x46, 0xC2, 0x5C, 0x54, 0xF8, 0x04, 0x6F, 0x2A, 0x44, 0x32, 0x44, 0xD5, 0xB2, -+0x01, 0x33, 0x57, 0xF8, 0x25, 0x20, 0x22, 0x60, 0x8B, 0x42, 0xA8, 0xBF, 0x00, 0x23, 0xA4, 0x45, 0x47, 0xF8, 0x25, 0x60, -+0xEE, 0xD1, 0x00, 0x20, 0xF0, 0xBC, 0x70, 0x47, 0x18, 0x2C, 0x17, 0x00, 0x14, 0x30, 0x17, 0x00, 0x71, 0xB3, 0x18, 0x4B, -+0xF0, 0xB5, 0xD3, 0xF8, 0x00, 0x54, 0xD3, 0xF8, 0x04, 0x24, 0x53, 0xF8, 0x25, 0x60, 0x32, 0x44, 0x01, 0x39, 0xD2, 0xB2, -+0x89, 0xB2, 0x01, 0x31, 0x53, 0xF8, 0x22, 0x40, 0x01, 0x44, 0x6F, 0x1C, 0x43, 0xF8, 0x22, 0x60, 0x43, 0xF8, 0x25, 0x40, -+0xFD, 0xB2, 0x34, 0x44, 0xE4, 0xB2, 0x53, 0xF8, 0x25, 0x60, 0x53, 0xF8, 0x24, 0x70, 0x10, 0xF8, 0x01, 0x4B, 0x02, 0xEB, -+0x06, 0x0C, 0x96, 0x46, 0x5F, 0xFA, 0x8C, 0xF2, 0x67, 0x40, 0x88, 0x42, 0x53, 0xF8, 0x22, 0x40, 0x00, 0xF8, 0x01, 0x7C, -+0xE5, 0xD1, 0xC3, 0xF8, 0x00, 0x54, 0xC3, 0xF8, 0x04, 0xE4, 0xF0, 0xBD, 0x70, 0x47, 0x00, 0xBF, 0x18, 0x2C, 0x17, 0x00, -+0xFF, 0xF7, 0xCA, 0xBF, 0x83, 0x68, 0x8A, 0x68, 0x03, 0x48, 0x9B, 0x1A, 0x83, 0x42, 0x94, 0xBF, 0x00, 0x20, 0x01, 0x20, -+0x70, 0x47, 0x00, 0xBF, 0x00, 0xA3, 0xE1, 0x11, 0x83, 0x88, 0xB3, 0xEB, 0x11, 0x4F, 0x01, 0xD0, 0x00, 0x20, 0x70, 0x47, -+0xC0, 0x88, 0x89, 0xB2, 0x40, 0x1A, 0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x70, 0x47, 0x00, 0xBF, 0x2D, 0xE9, 0xF8, 0x4F, -+0xDF, 0xF8, 0x4C, 0xB1, 0xDB, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x07, 0x46, 0x89, 0x46, 0x15, 0x46, -+0x5E, 0xDB, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x3F, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xDF, 0xF8, -+0x2C, 0x81, 0xDF, 0xF8, 0x2C, 0xA1, 0xD8, 0xF8, 0x00, 0x30, 0xDA, 0xF8, 0x14, 0x60, 0x01, 0x33, 0xC8, 0xF8, 0x00, 0x30, -+0x1E, 0xB1, 0xB3, 0x88, 0xBB, 0x42, 0x40, 0xD0, 0x00, 0x26, 0x37, 0x49, 0x37, 0x48, 0x49, 0xEA, 0x07, 0x42, 0x00, 0xF0, -+0xF5, 0xF9, 0x04, 0x46, 0x00, 0x28, 0x47, 0xD0, 0x34, 0x4B, 0x35, 0x4A, 0x1B, 0x69, 0x32, 0x48, 0x1D, 0x44, 0xA5, 0x60, -+0x21, 0x46, 0x00, 0xF0, 0x87, 0xFE, 0x9E, 0xB9, 0xDA, 0xF8, 0x14, 0x30, 0xA3, 0x42, 0x13, 0xD0, 0xD8, 0xF8, 0x00, 0x30, -+0x2B, 0xB1, 0x29, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xC8, 0xF8, 0x00, 0x30, 0x8B, 0xB1, 0x29, 0x4B, 0x1A, 0x69, 0xAD, 0x1A, -+0x00, 0x2D, 0x14, 0xDB, 0xBD, 0xE8, 0xF8, 0x8F, 0xDA, 0xF8, 0x14, 0x40, 0x00, 0x2C, 0xEB, 0xD0, 0x25, 0x4B, 0xA1, 0x68, -+0xD3, 0xF8, 0xE0, 0x31, 0x24, 0x48, 0x98, 0x47, 0xE4, 0xE7, 0x00, 0x2A, 0xEB, 0xD0, 0x62, 0xB6, 0x1E, 0x4B, 0x1A, 0x69, -+0xAD, 0x1A, 0x00, 0x2D, 0xEA, 0xDA, 0xBD, 0xE8, 0xF8, 0x4F, 0x4F, 0xF0, 0x00, 0x50, 0x00, 0xF0, 0x29, 0xBD, 0xF6, 0x88, -+0xA6, 0xEB, 0x09, 0x06, 0xB6, 0xFA, 0x86, 0xF6, 0x76, 0x09, 0xB8, 0xE7, 0xB2, 0xB1, 0x19, 0x4B, 0x9A, 0x42, 0x9C, 0xD9, -+0x18, 0x49, 0x19, 0x48, 0x94, 0x22, 0x02, 0xF0, 0x0F, 0xFA, 0x96, 0xE7, 0x0C, 0x20, 0x00, 0xF0, 0xFB, 0xF9, 0xDB, 0xF8, -+0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0x46, 0x09, 0xDB, 0xA7, 0x80, 0xA4, 0xF8, 0x06, 0x90, 0xA9, 0xE7, -+0x0E, 0x49, 0x10, 0x48, 0x93, 0x22, 0x02, 0xF0, 0xFB, 0xF9, 0x82, 0xE7, 0x00, 0x28, 0xF3, 0xD1, 0x0A, 0x49, 0x0D, 0x48, -+0xA5, 0x22, 0x02, 0xF0, 0xF3, 0xF9, 0xED, 0xE7, 0x38, 0x61, 0x17, 0x00, 0x59, 0x26, 0x14, 0x00, 0x94, 0xB6, 0x17, 0x00, -+0x00, 0x10, 0x50, 0x40, 0x41, 0x26, 0x14, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xA0, 0xB6, 0x17, 0x00, 0xFF, 0xA2, 0xE1, 0x11, -+0x70, 0x79, 0x15, 0x00, 0x5C, 0xAB, 0x15, 0x00, 0x50, 0xAB, 0x15, 0x00, 0x78, 0xAB, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x80, 0xB6, 0x17, 0x00, 0xF8, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x25, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x25, 0x4D, 0x25, 0x4E, 0x2B, 0x68, 0x74, 0x69, 0x01, 0x33, 0x2B, 0x60, 0x74, 0xB1, -+0xA3, 0x88, 0x83, 0x42, 0x02, 0xD1, 0xE3, 0x88, 0x8B, 0x42, 0x11, 0xD0, 0x41, 0xEA, 0x00, 0x42, 0x1F, 0x49, 0x20, 0x48, -+0x00, 0xF0, 0x54, 0xF9, 0x04, 0x46, 0x38, 0xBB, 0x2B, 0x68, 0x33, 0xB1, 0x18, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, -+0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xF8, 0xBD, 0x06, 0xF1, 0x14, 0x00, 0x00, 0xF0, 0x98, 0xFD, 0x77, 0x69, 0x17, 0x4B, -+0xDF, 0xB1, 0xD3, 0xF8, 0xE0, 0x31, 0xB9, 0x68, 0x06, 0xF1, 0x20, 0x00, 0x98, 0x47, 0x14, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x0A, 0xDA, 0x12, 0x4A, 0xBB, 0x68, 0x12, 0x69, 0x9B, 0x1A, 0x00, 0x2B, 0x04, 0xDA, 0x10, 0x49, -+0x10, 0x48, 0xE7, 0x22, 0x02, 0xF0, 0x8E, 0xF9, 0x20, 0x46, 0x00, 0xF0, 0xED, 0xF9, 0x2B, 0x68, 0xD3, 0xE7, 0xD3, 0xF8, -+0xD8, 0x31, 0x06, 0xF1, 0x20, 0x00, 0x98, 0x47, 0xF4, 0xE7, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x80, 0xB6, 0x17, 0x00, 0x59, 0x26, 0x14, 0x00, 0x94, 0xB6, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x00, 0x10, 0x50, 0x40, 0x70, 0x79, 0x15, 0x00, 0x80, 0xAB, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x28, 0x4D, 0x29, 0x4F, -+0xDF, 0xF8, 0xB0, 0x80, 0x28, 0x4E, 0xDF, 0xF8, 0xB0, 0x90, 0x21, 0xE0, 0xA1, 0x68, 0x33, 0x69, 0xCB, 0x1A, 0x32, 0x2B, -+0x07, 0xD4, 0xD9, 0xF8, 0xE0, 0x31, 0x98, 0x47, 0xA3, 0x68, 0x32, 0x69, 0x9B, 0x1A, 0x00, 0x2B, 0x30, 0xDA, 0x21, 0x48, -+0x00, 0xF0, 0x44, 0xFD, 0x2B, 0x68, 0x04, 0x46, 0x5A, 0x1E, 0x2B, 0xB1, 0xD8, 0xF8, 0x00, 0x30, 0x2A, 0x60, 0x0A, 0xB9, -+0x03, 0xB1, 0x62, 0xB6, 0xA0, 0x88, 0xE1, 0x88, 0xFF, 0x22, 0x00, 0xF0, 0xCB, 0xF8, 0x20, 0x46, 0x00, 0xF0, 0xA4, 0xF9, -+0x4F, 0xF0, 0x00, 0x50, 0x00, 0xF0, 0x6C, 0xFC, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x01, 0x23, -+0xC8, 0xF8, 0x00, 0x30, 0x2A, 0x68, 0x7C, 0x69, 0x10, 0x48, 0x53, 0x1C, 0x2B, 0x60, 0x00, 0x2C, 0xCA, 0xD1, 0x2B, 0xB1, -+0x0E, 0x4B, 0x2A, 0x60, 0x1B, 0x68, 0x0A, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0xBD, 0xE8, 0xF8, 0x83, 0x2B, 0x68, 0x00, 0x2B, -+0xFA, 0xD0, 0x09, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x00, 0x2B, 0xF4, 0xD1, 0x00, 0x2A, 0xF2, 0xD0, 0xF0, 0xE7, -+0x6C, 0x28, 0x17, 0x00, 0x80, 0xB6, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x94, 0xB6, 0x17, 0x00, 0xA0, 0xB6, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x0E, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0E, 0x4D, 0x0E, 0x4C, 0x2B, 0x68, 0x4F, 0xF0, 0x00, 0x50, 0x01, 0x33, 0x2B, 0x60, -+0x00, 0xF0, 0x28, 0xFC, 0x01, 0xE0, 0x00, 0xF0, 0x59, 0xF9, 0x20, 0x46, 0x00, 0xF0, 0xE4, 0xFC, 0x00, 0x28, 0xF8, 0xD1, -+0x2B, 0x68, 0x33, 0xB1, 0x03, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x38, 0xBD, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x94, 0xB6, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x80, 0x46, 0x03, 0xF1, -+0x0C, 0x00, 0x1D, 0x46, 0x0F, 0x46, 0x16, 0x46, 0x00, 0xF0, 0xC8, 0xF8, 0x0F, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x04, 0x46, 0x0F, 0xDB, 0x00, 0x21, 0xA4, 0xF8, 0x04, 0x80, 0x04, 0xF1, 0x0C, 0x08, 0xE7, 0x80, 0x26, 0x81, -+0x65, 0x81, 0x2A, 0x46, 0x21, 0x60, 0x40, 0x46, 0xDD, 0xF7, 0xDC, 0xFB, 0x40, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x28, -+0xED, 0xD1, 0x04, 0x49, 0x04, 0x48, 0x52, 0x22, 0x02, 0xF0, 0xBA, 0xF8, 0xE7, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xA8, 0xAB, 0x15, 0x00, 0x16, 0x4B, 0x1A, 0x68, 0x30, 0xF8, 0x06, 0x3C, 0xB2, 0xF9, 0x00, 0x10, -+0x00, 0x29, 0x10, 0xB5, 0xDA, 0xB2, 0x04, 0x46, 0x0C, 0xDB, 0x0B, 0x2A, 0x13, 0xD8, 0x11, 0x48, 0xA4, 0xF1, 0x0C, 0x01, -+0x00, 0xF0, 0x4C, 0xFC, 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF0, 0x00, 0x60, 0x00, 0xF0, 0xA4, 0xBB, 0x0D, 0x2A, 0xF0, 0xD9, -+0x0B, 0x49, 0x0C, 0x48, 0xBB, 0x22, 0x02, 0xF0, 0x93, 0xF8, 0x34, 0xF8, 0x06, 0x3C, 0x34, 0xF8, 0x04, 0x2C, 0x34, 0xF8, -+0x08, 0x1C, 0x08, 0x48, 0x01, 0xF0, 0x10, 0xFE, 0xA4, 0xF1, 0x0C, 0x00, 0xBD, 0xE8, 0x10, 0x40, 0x02, 0xF0, 0xDE, 0xB8, -+0x38, 0x36, 0x17, 0x00, 0x84, 0xB6, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x10, 0x7D, 0x15, 0x00, 0xB4, 0xAB, 0x15, 0x00, -+0x08, 0xB5, 0x00, 0x23, 0xFF, 0xF7, 0x94, 0xFF, 0xBD, 0xE8, 0x08, 0x40, 0xFF, 0xF7, 0xC0, 0xBF, 0x10, 0xB4, 0x5D, 0xF8, -+0x04, 0x4B, 0x20, 0xF8, 0x08, 0x1C, 0x20, 0xF8, 0x06, 0x2C, 0x20, 0xF8, 0x04, 0x3C, 0xFF, 0xF7, 0xB5, 0xBF, 0x00, 0xBF, -+0x00, 0xF0, 0xC6, 0xB8, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x68, 0xD4, 0xB1, 0x07, 0x46, 0x0D, 0x46, 0x16, 0x46, 0x4F, 0xF0, -+0x00, 0x08, 0x02, 0xE0, 0xA0, 0x46, 0x93, 0xB1, 0x1C, 0x46, 0x31, 0x46, 0x20, 0x46, 0xA8, 0x47, 0x23, 0x68, 0x00, 0x28, -+0xF6, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0x0C, 0xD0, 0xC8, 0xF8, 0x00, 0x30, 0x23, 0x68, 0x5B, 0xB1, 0x00, 0x23, 0x23, 0x60, -+0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x24, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x3B, 0x60, 0x00, 0x2B, 0xF3, 0xD1, -+0xC7, 0xF8, 0x04, 0x80, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0xBF, 0x0F, 0x48, 0x30, 0xB4, 0x20, 0xF0, 0x03, 0x00, -+0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x0C, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0B, 0x4A, 0x0C, 0x4B, -+0x11, 0x68, 0x23, 0xF0, 0x03, 0x03, 0x4C, 0x1C, 0x1B, 0x1A, 0x00, 0x25, 0x14, 0x60, 0xC0, 0xE9, 0x00, 0x53, 0x2C, 0xB1, -+0x04, 0x4B, 0x11, 0x60, 0x1B, 0x68, 0x09, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x30, 0xBC, 0x70, 0x47, 0x03, 0xA0, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x80, 0xB6, 0x17, 0x00, 0xF8, 0xB5, 0x31, 0x4F, 0x3B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x03, 0x30, 0x20, 0xF0, 0x03, 0x04, 0x00, 0x2B, 0x04, 0xF1, 0x04, 0x06, 0x48, 0xDB, 0x2C, 0x4B, 0xDB, 0x69, -+0xEF, 0xF3, 0x10, 0x82, 0xD2, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x2A, 0x4A, 0x01, 0x21, 0x11, 0x60, 0x29, 0x4D, 0x2A, 0x68, -+0x02, 0xF1, 0x01, 0x0C, 0xC5, 0xF8, 0x00, 0xC0, 0x00, 0x2B, 0x3E, 0xD0, 0x04, 0xF1, 0x0C, 0x00, 0x00, 0x21, 0x05, 0xE0, -+0x4C, 0x68, 0xA2, 0x42, 0x38, 0xBF, 0x19, 0x46, 0x1B, 0x68, 0x43, 0xB1, 0x5A, 0x68, 0x82, 0x42, 0xFA, 0xD3, 0x00, 0x29, -+0xF4, 0xD1, 0x19, 0x46, 0x1B, 0x68, 0x00, 0x2B, 0xF6, 0xD1, 0x3B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x12, 0xDB, -+0x0A, 0x46, 0x4B, 0x68, 0x9B, 0x1B, 0x98, 0x18, 0x4B, 0x60, 0x04, 0x30, 0x9E, 0x50, 0xBC, 0xF1, 0x00, 0x0F, 0x07, 0xD0, -+0x13, 0x4A, 0x0C, 0xF1, 0xFF, 0x33, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xF8, 0xBD, 0x00, 0x29, -+0xEA, 0xD1, 0x10, 0x49, 0x10, 0x48, 0x97, 0x22, 0x01, 0xF0, 0xC0, 0xFF, 0x00, 0x22, 0xD5, 0xF8, 0x00, 0xC0, 0x11, 0x46, -+0xE1, 0xE7, 0x07, 0x2E, 0xB4, 0xD8, 0x0A, 0x49, 0x0B, 0x48, 0x7B, 0x22, 0x01, 0xF0, 0xB4, 0xFF, 0xAE, 0xE7, 0x3A, 0x68, -+0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xE8, 0xDB, 0x5B, 0x68, 0xFF, 0xDE, 0x38, 0x36, 0x17, 0x00, 0x80, 0xB6, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x08, 0xAC, 0x15, 0x00, 0xE0, 0xAB, 0x15, 0x00, -+0x2D, 0xE9, 0xF8, 0x43, 0xDF, 0xF8, 0xF4, 0x90, 0x36, 0x4A, 0xD9, 0xF8, 0x00, 0x30, 0xD4, 0x69, 0xB3, 0xF9, 0x00, 0x30, -+0x50, 0xF8, 0x04, 0x8C, 0x00, 0x2B, 0x06, 0x46, 0xA0, 0xF1, 0x04, 0x05, 0x2F, 0xDB, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, -+0x03, 0xD4, 0x72, 0xB6, 0x2E, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x2E, 0x48, 0xD0, 0xF8, 0x00, 0xC0, 0x0C, 0xF1, 0x01, 0x07, -+0x07, 0x60, 0x00, 0x2C, 0x47, 0xD0, 0x63, 0x68, 0x1A, 0x19, 0xAA, 0x42, 0x23, 0xD0, 0xAC, 0x42, 0x06, 0xD9, 0x37, 0xE0, -+0x63, 0x68, 0x1A, 0x19, 0xAA, 0x42, 0x1C, 0xD0, 0xAC, 0x42, 0x26, 0xD8, 0x21, 0x46, 0x24, 0x68, 0x00, 0x2C, 0xF5, 0xD1, -+0x0D, 0x60, 0x46, 0xE9, 0x01, 0x48, 0x47, 0xB1, 0x1E, 0x4B, 0xC0, 0xF8, 0x00, 0xC0, 0x1B, 0x68, 0xBC, 0xF1, 0x00, 0x0F, -+0x01, 0xD1, 0x03, 0xB1, 0x62, 0xB6, 0xBD, 0xE8, 0xF8, 0x83, 0xA0, 0x42, 0xCD, 0xD8, 0x1A, 0x49, 0x1A, 0x48, 0xC7, 0x22, -+0x01, 0xF0, 0x56, 0xFF, 0xC7, 0xE7, 0x43, 0x44, 0x22, 0x68, 0x63, 0x60, 0xE1, 0x18, 0x8A, 0x42, 0xE5, 0xD1, 0xD2, 0xE9, -+0x00, 0x21, 0x0B, 0x44, 0x22, 0x60, 0x63, 0x60, 0xDF, 0xE7, 0x05, 0xEB, 0x08, 0x03, 0x9C, 0x42, 0x0D, 0x60, 0xD8, 0xD1, -+0x23, 0x68, 0x46, 0xF8, 0x04, 0x3C, 0x52, 0x1B, 0x32, 0x60, 0xD4, 0xE7, 0xD9, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x04, 0xDB, 0x00, 0x23, 0x1D, 0x60, 0xFF, 0xDE, 0x25, 0x60, 0xFF, 0xDE, 0x06, 0x49, 0x07, 0x48, 0xE2, 0x22, -+0x01, 0xF0, 0x2E, 0xFF, 0xF4, 0xE7, 0x00, 0xBF, 0x80, 0xB6, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x18, 0xAC, 0x15, 0x00, 0x3C, 0xAC, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0xC0, 0x88, 0x40, 0x1A, -+0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x70, 0x47, 0x2A, 0xB3, 0xF8, 0xB5, 0x53, 0x1E, 0x0F, 0x46, 0x0A, 0x68, 0x01, 0xE0, -+0x59, 0x1C, 0x11, 0xD0, 0x32, 0xF8, 0x33, 0x40, 0x84, 0x42, 0x4F, 0xEA, 0xC3, 0x06, 0x02, 0xEB, 0xC3, 0x05, 0x03, 0xF1, -+0xFF, 0x33, 0xF3, 0xD1, 0x0B, 0x4B, 0x68, 0x68, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x02, 0xDB, 0xF8, 0xBD, -+0x00, 0x20, 0xF8, 0xBD, 0x00, 0x28, 0xFA, 0xD1, 0x06, 0x49, 0x07, 0x48, 0xF4, 0x22, 0x01, 0xF0, 0xF5, 0xFE, 0x3B, 0x68, -+0x1E, 0x44, 0x70, 0x68, 0xF8, 0xBD, 0x00, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x50, 0xAC, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x44, 0x4F, 0x3B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0x46, -+0x0D, 0x46, 0x4F, 0xEA, 0x10, 0x29, 0xC6, 0xB2, 0x3B, 0xDB, 0x40, 0x4B, 0x03, 0xEB, 0x06, 0x16, 0xB3, 0x68, 0x03, 0xEB, -+0x49, 0x09, 0x3E, 0x48, 0x2A, 0x46, 0x21, 0x46, 0x01, 0xF0, 0x56, 0xFC, 0xB9, 0xF8, 0x00, 0x30, 0xAB, 0x42, 0x01, 0xD1, -+0xBD, 0xE8, 0xF8, 0x83, 0xDF, 0xF8, 0x0C, 0x81, 0x38, 0x4F, 0x39, 0x4E, 0xA9, 0xF8, 0x00, 0x50, 0x19, 0xE0, 0xEF, 0xF3, -+0x10, 0x83, 0xDB, 0x07, 0x02, 0xD4, 0x72, 0xB6, 0x01, 0x23, 0x33, 0x60, 0x34, 0x4D, 0x35, 0x48, 0x2B, 0x68, 0x01, 0x33, -+0x2B, 0x60, 0x00, 0xF0, 0x61, 0xFA, 0x2A, 0x68, 0x53, 0x1E, 0x22, 0xB1, 0x32, 0x68, 0x2B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0x4F, 0xF0, 0x00, 0x60, 0x00, 0xF0, 0xB3, 0xF9, 0x41, 0x46, 0x22, 0x46, 0x38, 0x46, 0xFF, 0xF7, 0x40, 0xFE, -+0x01, 0x46, 0x00, 0x28, 0xDD, 0xD1, 0xBD, 0xE8, 0xF8, 0x83, 0x0C, 0x2E, 0x23, 0xD8, 0x33, 0xD0, 0x20, 0x4B, 0x03, 0xEB, -+0x06, 0x16, 0xF3, 0x89, 0x4B, 0x45, 0x0B, 0xD9, 0xB3, 0x68, 0x03, 0xEB, 0x49, 0x09, 0xB9, 0xF1, 0x00, 0x0F, 0xBA, 0xD1, -+0x20, 0x49, 0x21, 0x48, 0xB9, 0x22, 0x01, 0xF0, 0x8B, 0xFE, 0xB4, 0xE7, 0xB4, 0x22, 0x1D, 0x49, 0x1E, 0x48, 0x01, 0xF0, -+0x85, 0xFE, 0x3A, 0x68, 0xB3, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x03, 0xEB, 0x49, 0x09, 0xA7, 0xDA, 0xB9, 0xF1, -+0x00, 0x0F, 0xA4, 0xD1, 0xE8, 0xE7, 0x15, 0x49, 0x17, 0x48, 0xB2, 0x22, 0x01, 0xF0, 0x74, 0xFE, 0x3B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x93, 0xDA, 0x0D, 0x2E, 0x04, 0xD0, 0x0F, 0x49, 0x12, 0x48, 0xBB, 0x22, 0x01, 0xF0, 0x68, 0xFE, -+0x0C, 0x49, 0x11, 0x48, 0xB3, 0x22, 0x01, 0xF0, 0x63, 0xFE, 0x3B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC1, 0xDB, -+0x81, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x14, 0xAD, 0x15, 0x00, 0xC8, 0xAC, 0x15, 0x00, 0x8C, 0xB6, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x84, 0xB6, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xB8, 0xAC, 0x15, 0x00, -+0x98, 0xAC, 0x15, 0x00, 0x74, 0xAC, 0x15, 0x00, 0x10, 0x7D, 0x15, 0x00, 0x84, 0xAC, 0x15, 0x00, 0x41, 0x2D, 0x14, 0x00, -+0x70, 0xB5, 0x20, 0x4D, 0x2B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x4F, 0xEA, 0x10, 0x26, 0xC4, 0xB2, 0x06, 0xDB, -+0x1C, 0x4D, 0x24, 0x01, 0x25, 0x44, 0xAB, 0x68, 0x33, 0xF8, 0x16, 0x00, 0x70, 0xBD, 0x0C, 0x2C, 0x11, 0xD8, 0x21, 0xD0, -+0x17, 0x4D, 0x05, 0xEB, 0x04, 0x13, 0x24, 0x01, 0xDB, 0x89, 0xB3, 0x42, 0xF0, 0xD8, 0x25, 0x44, 0x14, 0x49, 0x15, 0x48, -+0xD9, 0x22, 0x01, 0xF0, 0x1F, 0xFE, 0xAB, 0x68, 0x33, 0xF8, 0x16, 0x00, 0x70, 0xBD, 0x10, 0x49, 0x11, 0x48, 0xD7, 0x22, -+0x01, 0xF0, 0x16, 0xFE, 0x2B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xDA, 0xDA, 0x0D, 0x2C, 0x04, 0xD0, 0x0A, 0x49, -+0x0C, 0x48, 0xBB, 0x22, 0x01, 0xF0, 0x0A, 0xFE, 0x07, 0x49, 0x0B, 0x48, 0xD8, 0x22, 0x01, 0xF0, 0x05, 0xFE, 0x2B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xD3, 0xDB, 0xC8, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x14, 0xAD, 0x15, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x98, 0xAC, 0x15, 0x00, 0x74, 0xAC, 0x15, 0x00, 0x10, 0x7D, 0x15, 0x00, 0x84, 0xAC, 0x15, 0x00, -+0x2D, 0xE9, 0xF0, 0x47, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x68, 0x4B, 0x01, 0x22, 0x1A, 0x60, -+0x67, 0x4D, 0x68, 0x48, 0x2B, 0x68, 0x01, 0x33, 0x2B, 0x60, 0x00, 0xF0, 0xCF, 0xF9, 0x2B, 0x68, 0x04, 0x46, 0x2B, 0xB1, -+0x61, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x00, 0x2B, 0x54, 0xD0, 0x00, 0x2C, 0x39, 0xD0, 0x60, 0x4F, 0xB4, 0xF8, -+0x06, 0xA0, 0x3B, 0x68, 0xB4, 0xF8, 0x04, 0x80, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x5F, 0xFA, 0x8A, 0xF6, 0x4F, 0xEA, -+0x1A, 0x2A, 0x48, 0xDB, 0xDF, 0xF8, 0x90, 0x91, 0x36, 0x01, 0x59, 0xF8, 0x06, 0x10, 0xB1, 0x44, 0x00, 0x29, 0x52, 0xD0, -+0xD9, 0xF8, 0x08, 0x30, 0x33, 0xF8, 0x1A, 0x30, 0x01, 0xEB, 0xC3, 0x01, 0x40, 0x46, 0x8A, 0x88, 0xFF, 0xF7, 0x9C, 0xFE, -+0x06, 0x46, 0x00, 0x28, 0x45, 0xD0, 0xE3, 0x88, 0x22, 0x89, 0xA1, 0x88, 0x4E, 0x48, 0x01, 0xF0, 0x31, 0xFB, 0x23, 0x89, -+0xE2, 0x88, 0xA0, 0x88, 0x04, 0xF1, 0x0C, 0x01, 0xB0, 0x47, 0x01, 0x28, 0x08, 0xD0, 0x02, 0x28, 0x7B, 0xD0, 0x00, 0x28, -+0x50, 0xD0, 0x3B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x79, 0xDB, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, -+0x72, 0xB6, 0x3E, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x41, 0x4A, 0x2B, 0x68, 0x52, 0x68, 0x01, 0x33, 0x2B, 0x60, 0x00, 0x2A, -+0x40, 0xD0, 0x33, 0xB1, 0x38, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xBD, 0xE8, -+0xF0, 0x87, 0x00, 0x2A, 0xA8, 0xD0, 0x62, 0xB6, 0xA6, 0xE7, 0x0C, 0x2E, 0x36, 0xD8, 0x48, 0xD0, 0xDF, 0xF8, 0xF8, 0x90, -+0x09, 0xEB, 0x06, 0x13, 0x36, 0x01, 0xDB, 0x89, 0x53, 0x45, 0xAE, 0xD8, 0x32, 0x49, 0x33, 0x48, 0x4F, 0xF4, 0x89, 0x72, -+0x01, 0xF0, 0x6C, 0xFD, 0xA7, 0xE7, 0xD9, 0xF8, 0x04, 0x10, 0x69, 0xB1, 0x8A, 0x88, 0x40, 0x46, 0xFF, 0xF7, 0x4C, 0xFE, -+0xE3, 0x88, 0x22, 0x89, 0xA1, 0x88, 0x06, 0x46, 0x27, 0x48, 0x01, 0xF0, 0xE3, 0xFA, 0x00, 0x2E, 0xAF, 0xD1, 0x05, 0xE0, -+0xE3, 0x88, 0x22, 0x89, 0xA1, 0x88, 0x23, 0x48, 0x01, 0xF0, 0xDA, 0xFA, 0xE3, 0x88, 0x22, 0x89, 0xA1, 0x88, 0x24, 0x48, -+0x01, 0xF0, 0xD4, 0xFA, 0x20, 0x46, 0xFF, 0xF7, 0xE5, 0xFC, 0xAF, 0xE7, 0x4F, 0xF0, 0x00, 0x60, 0x00, 0xF0, 0x74, 0xF8, -+0x2B, 0x68, 0xB8, 0xE7, 0x1B, 0x49, 0x1E, 0x48, 0x4F, 0xF4, 0x88, 0x72, 0x01, 0xF0, 0x3E, 0xFD, 0x3B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0xBF, 0xF6, 0x72, 0xAF, 0x0D, 0x2E, 0x04, 0xD0, 0x14, 0x49, 0x18, 0x48, 0xBB, 0x22, 0x01, 0xF0, -+0x31, 0xFD, 0x12, 0x49, 0x16, 0x48, 0x40, 0xF2, 0x11, 0x12, 0x01, 0xF0, 0x2B, 0xFD, 0x3B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xAB, 0xDB, 0x5E, 0xE7, 0x12, 0x48, 0x21, 0x46, 0x00, 0xF0, 0xCD, 0xF8, 0x85, 0xE7, 0x09, 0x49, 0x10, 0x48, -+0x40, 0xF2, 0x6D, 0x12, 0x01, 0xF0, 0x1A, 0xFD, 0x7E, 0xE7, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x84, 0xB6, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0xB4, 0xAB, 0x15, 0x00, 0x80, 0xB6, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x98, 0xAC, 0x15, 0x00, 0xDC, 0xAC, 0x15, 0x00, 0x74, 0xAC, 0x15, 0x00, 0x10, 0x7D, 0x15, 0x00, 0x84, 0xAC, 0x15, 0x00, -+0x8C, 0xB6, 0x17, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x14, 0xAD, 0x15, 0x00, 0x00, 0x20, 0x70, 0x47, 0x02, 0x20, 0x70, 0x47, -+0x30, 0xB4, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x09, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x09, 0x4A, -+0x09, 0x4D, 0x11, 0x68, 0x2B, 0x68, 0x4C, 0x1C, 0x18, 0x43, 0x14, 0x60, 0x28, 0x60, 0x2C, 0xB1, 0x03, 0x4B, 0x11, 0x60, -+0x1B, 0x68, 0x09, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x30, 0xBC, 0x70, 0x47, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x80, 0xB6, 0x17, 0x00, 0x4F, 0xF0, 0x00, 0x50, 0xFF, 0xF7, 0xDC, 0xBF, 0x30, 0xB4, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, -+0x03, 0xD4, 0x72, 0xB6, 0x0A, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0A, 0x4A, 0x0A, 0x4D, 0x11, 0x68, 0x2B, 0x68, 0x4C, 0x1C, -+0x23, 0xEA, 0x00, 0x00, 0x14, 0x60, 0x28, 0x60, 0x2C, 0xB1, 0x04, 0x4B, 0x11, 0x60, 0x1B, 0x68, 0x09, 0xB9, 0x03, 0xB1, -+0x62, 0xB6, 0x30, 0xBC, 0x70, 0x47, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x80, 0xB6, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x47, 0x18, 0x4E, 0x34, 0x68, 0xDC, 0xB1, 0xDF, 0xF8, 0x68, 0x80, 0x17, 0x4D, 0x17, 0x4F, 0xDF, 0xF8, -+0x64, 0xA0, 0xDF, 0xF8, 0x64, 0x90, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xB4, 0xFA, 0x84, 0xF4, -+0x12, 0xDB, 0x55, 0xF8, 0x34, 0x30, 0x05, 0xEB, 0xC4, 0x04, 0x60, 0x68, 0x98, 0x47, 0x3B, 0x68, 0x34, 0x68, 0xDB, 0x78, -+0x1B, 0xB9, 0x00, 0x2C, 0xEB, 0xD1, 0xBD, 0xE8, 0xF0, 0x87, 0xE9, 0xF7, 0x09, 0xFA, 0x00, 0x2C, 0xE5, 0xD1, 0xF8, 0xE7, -+0x1D, 0x2C, 0x03, 0xDC, 0x55, 0xF8, 0x34, 0x30, 0x00, 0x2B, 0xE8, 0xD1, 0xDC, 0x22, 0x51, 0x46, 0x48, 0x46, 0x01, 0xF0, -+0x7D, 0xFC, 0xE0, 0xE7, 0x80, 0xB6, 0x17, 0x00, 0x70, 0x21, 0x17, 0x00, 0x34, 0x36, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xE4, 0xAD, 0x15, 0x00, 0x08, 0xB5, 0xFF, 0xF7, 0x35, 0xFC, 0x08, 0x4B, 0x08, 0x49, 0xD8, 0x61, -+0x00, 0x22, 0xC3, 0xE9, 0x03, 0x22, 0xC3, 0xE9, 0x01, 0x22, 0xC3, 0xE9, 0x05, 0x22, 0x59, 0x62, 0x4F, 0xF0, 0xFF, 0x30, -+0xBD, 0xE8, 0x08, 0x40, 0xFF, 0xF7, 0x8A, 0xBF, 0x80, 0xB6, 0x17, 0x00, 0xD1, 0x31, 0x14, 0x00, 0x00, 0x23, 0xC0, 0xE9, -+0x00, 0x33, 0x70, 0x47, 0x38, 0xB5, 0x0E, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x05, 0x46, 0x0C, 0x46, -+0x07, 0xDB, 0x2B, 0x68, 0x6B, 0xB1, 0x6B, 0x68, 0x1C, 0x60, 0x00, 0x23, 0x6C, 0x60, 0x23, 0x60, 0x38, 0xBD, 0x00, 0x29, -+0xF5, 0xD1, 0x06, 0x49, 0x06, 0x48, 0x48, 0x22, 0x01, 0xF0, 0x3C, 0xFC, 0xEF, 0xE7, 0x00, 0x23, 0x2C, 0x60, 0x6C, 0x60, -+0x23, 0x60, 0x38, 0xBD, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x14, 0xAE, 0x15, 0x00, 0x38, 0xB5, 0x0C, 0x4B, -+0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x05, 0x46, 0x0C, 0x46, 0x04, 0xDB, 0x2B, 0x68, 0x53, 0xB1, 0x23, 0x60, -+0x2C, 0x60, 0x38, 0xBD, 0x00, 0x29, 0xF8, 0xD1, 0x05, 0x49, 0x06, 0x48, 0x5F, 0x22, 0x01, 0xF0, 0x1B, 0xFC, 0xF2, 0xE7, -+0x6C, 0x60, 0x23, 0x60, 0x2C, 0x60, 0x38, 0xBD, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x14, 0xAE, 0x15, 0x00, -+0x03, 0x68, 0x33, 0xB1, 0x42, 0x68, 0x19, 0x68, 0x01, 0x60, 0x9A, 0x42, 0x04, 0xBF, 0x00, 0x22, 0x42, 0x60, 0x18, 0x46, -+0x70, 0x47, 0x00, 0xBF, 0x38, 0xB5, 0x16, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x05, 0x46, 0x0C, 0x46, -+0x0B, 0xDB, 0x2B, 0x68, 0x43, 0xB1, 0xA3, 0x42, 0x02, 0xD1, 0x14, 0xE0, 0xA3, 0x42, 0x0C, 0xD0, 0x1A, 0x46, 0x1B, 0x68, -+0x00, 0x2B, 0xF9, 0xD1, 0x38, 0xBD, 0x00, 0x28, 0xF1, 0xD1, 0x0C, 0x49, 0x0C, 0x48, 0x84, 0x22, 0x01, 0xF0, 0xE8, 0xFB, -+0xEB, 0xE7, 0x6B, 0x68, 0xA3, 0x42, 0x0A, 0xD0, 0x23, 0x68, 0x13, 0x60, 0x38, 0xBD, 0x6B, 0x68, 0x22, 0x68, 0x2A, 0x60, -+0xA3, 0x42, 0xEB, 0xD1, 0x00, 0x23, 0x6B, 0x60, 0x38, 0xBD, 0x6A, 0x60, 0xF2, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x28, 0xAE, 0x15, 0x00, 0x03, 0x68, 0x2B, 0xB1, 0x00, 0x20, 0x1B, 0x68, 0x01, 0x30, 0x00, 0x2B, -+0xFB, 0xD1, 0x70, 0x47, 0x18, 0x46, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x41, 0xD0, 0xE9, 0x00, 0x47, 0x80, 0x46, 0x0D, 0x46, -+0x16, 0x46, 0x1F, 0xB1, 0x39, 0x46, 0x28, 0x46, 0x90, 0x47, 0x88, 0xB1, 0x00, 0x27, 0x24, 0xB9, 0x1A, 0xE0, 0x23, 0x68, -+0x27, 0x46, 0x8B, 0xB1, 0x1C, 0x46, 0x21, 0x46, 0x28, 0x46, 0xB0, 0x47, 0x00, 0x28, 0xF6, 0xD0, 0x2C, 0x60, 0x67, 0xB9, -+0xC8, 0xF8, 0x00, 0x50, 0xBD, 0xE8, 0xF0, 0x81, 0x3D, 0x60, 0xC8, 0xF8, 0x04, 0x50, 0x28, 0x60, 0xBD, 0xE8, 0xF0, 0x81, -+0xC8, 0xF8, 0x04, 0x50, 0x2B, 0x60, 0x3D, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x23, 0xC8, 0xF8, 0x04, 0x50, 0x2B, 0x60, -+0xEA, 0xE7, 0x00, 0xBF, 0x03, 0x68, 0xB9, 0xB1, 0xCB, 0xB1, 0x8B, 0x42, 0x10, 0xB4, 0x04, 0x46, 0x02, 0xD1, 0x07, 0xE0, -+0x99, 0x42, 0x05, 0xD0, 0x1B, 0x68, 0x00, 0x2B, 0xFA, 0xD1, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x63, 0x68, 0x08, 0x68, -+0x10, 0x60, 0x8B, 0x42, 0x0A, 0x60, 0xF6, 0xD1, 0x62, 0x60, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x11, 0x46, 0xFF, 0xF7, -+0x49, 0xBF, 0x70, 0x47, 0x81, 0xB1, 0x03, 0x68, 0x8B, 0x42, 0x0A, 0xD0, 0x2B, 0xB1, 0x18, 0x68, 0x88, 0x42, 0x03, 0xD0, -+0x03, 0x46, 0x00, 0x2B, 0xF9, 0xD1, 0x70, 0x47, 0x11, 0x60, 0x1A, 0x60, 0x70, 0x47, 0x11, 0x46, 0xFF, 0xF7, 0x36, 0xBF, -+0x11, 0x46, 0xFF, 0xF7, 0x0F, 0xBF, 0x00, 0xBF, 0x0B, 0x46, 0x09, 0x68, 0x99, 0xB1, 0x02, 0x46, 0x00, 0x68, 0x48, 0xB1, -+0x10, 0xB4, 0x54, 0x68, 0x58, 0x68, 0x21, 0x60, 0x50, 0x60, 0x00, 0x22, 0x5D, 0xF8, 0x04, 0x4B, 0x1A, 0x60, 0x70, 0x47, -+0x93, 0xE8, 0x03, 0x00, 0x82, 0xE8, 0x03, 0x00, 0x00, 0x22, 0x1A, 0x60, 0x70, 0x47, 0x70, 0x47, 0xF8, 0xB5, 0x1F, 0x4F, -+0x3B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x06, 0x46, 0x0D, 0x46, 0x14, 0x46, 0x0A, 0xDB, 0x25, 0xB3, 0x23, 0x68, -+0x2B, 0x60, 0x73, 0x68, 0xA3, 0x42, 0x4F, 0xF0, 0x00, 0x03, 0x08, 0xBF, 0x75, 0x60, 0x23, 0x60, 0xF8, 0xBD, 0xE0, 0xB1, -+0xB5, 0xB1, 0x2B, 0x68, 0xA3, 0x42, 0x0A, 0xD0, 0x13, 0x49, 0x14, 0x48, 0x40, 0xF2, 0x75, 0x12, 0x01, 0xF0, 0x2A, 0xFB, -+0x3B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xE5, 0xDA, 0x00, 0x2C, 0xE3, 0xD1, 0x0D, 0x49, 0x0E, 0x48, 0x4F, 0xF4, -+0xBB, 0x72, 0x01, 0xF0, 0x1D, 0xFB, 0xDB, 0xE7, 0x00, 0x2C, 0xF6, 0xD0, 0x23, 0x68, 0x33, 0x60, 0xD9, 0xE7, 0x07, 0x49, -+0x09, 0x48, 0x4F, 0xF4, 0xBA, 0x72, 0x01, 0xF0, 0x11, 0xFB, 0x3B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xD7, 0xDB, -+0xCA, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x38, 0xAE, 0x15, 0x00, 0x74, 0xAE, 0x15, 0x00, -+0x28, 0xAE, 0x15, 0x00, 0x81, 0xB1, 0x10, 0xB4, 0x08, 0x4C, 0x01, 0x44, 0x10, 0xF8, 0x01, 0x3B, 0x83, 0xEA, 0x12, 0x63, -+0x81, 0x42, 0x54, 0xF8, 0x23, 0x30, 0x83, 0xEA, 0x02, 0x22, 0xF5, 0xD1, 0x10, 0x46, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, -+0x10, 0x46, 0x70, 0x47, 0x84, 0xAE, 0x15, 0x00, 0xF8, 0xB5, 0x0F, 0x18, 0xB8, 0x42, 0xBC, 0x46, 0x06, 0xD3, 0x1D, 0xE0, -+0x44, 0x78, 0x2E, 0x78, 0x02, 0x34, 0xFF, 0x2E, 0x20, 0x44, 0x06, 0xD0, 0x46, 0x1C, 0xB7, 0x42, 0x05, 0x46, 0xF5, 0xD8, -+0x00, 0x25, 0x28, 0x46, 0xF8, 0xBD, 0x87, 0x42, 0xFA, 0xD3, 0x1C, 0x80, 0x00, 0x2D, 0xF7, 0xD0, 0xEE, 0x1C, 0x66, 0x45, -+0xF4, 0xD8, 0xAE, 0x78, 0x96, 0x42, 0xF2, 0xD0, 0x0C, 0x1B, 0x84, 0x45, 0xA1, 0xB2, 0x01, 0xD9, 0x0F, 0x18, 0xE7, 0xE7, -+0x06, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xE5, 0xDA, 0x84, 0x45, 0xE3, 0xD0, 0x03, 0x49, 0x04, 0x48, -+0x7F, 0x22, 0x01, 0xF0, 0xB9, 0xFA, 0xDD, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x84, 0xB2, 0x15, 0x00, -+0x2D, 0xE9, 0xF8, 0x43, 0x01, 0xEB, 0x00, 0x08, 0x40, 0x45, 0xC6, 0x46, 0x2D, 0xD2, 0x02, 0xF1, 0x05, 0x0C, 0xC2, 0xF1, -+0x02, 0x07, 0x05, 0xE0, 0x44, 0x78, 0x35, 0x78, 0x02, 0x34, 0xDD, 0x2D, 0x20, 0x44, 0x07, 0xD0, 0x45, 0x1C, 0xA8, 0x45, -+0x06, 0x46, 0xF5, 0xD8, 0x00, 0x26, 0x30, 0x46, 0xBD, 0xE8, 0xF8, 0x83, 0x80, 0x45, 0xF9, 0xD3, 0x1C, 0x80, 0x00, 0x2E, -+0xF6, 0xD0, 0xF5, 0x1D, 0xAE, 0x45, 0xF3, 0xD3, 0x15, 0x46, 0x01, 0xE0, 0x65, 0x45, 0xF0, 0xD0, 0x05, 0xEB, 0x06, 0x08, -+0x15, 0xF8, 0x01, 0x9B, 0x18, 0xF8, 0x07, 0x80, 0xC1, 0x45, 0xF5, 0xD0, 0x0C, 0x1B, 0x86, 0x45, 0xA1, 0xB2, 0x02, 0xD9, -+0x01, 0xEB, 0x00, 0x08, 0xDC, 0xE7, 0x07, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xDA, 0xDA, 0x86, 0x45, -+0xD8, 0xD0, 0x04, 0x49, 0x04, 0x48, 0xB4, 0x22, 0x01, 0xF0, 0x70, 0xFA, 0xD2, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x84, 0xB2, 0x15, 0x00, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, 0x70, 0xB4, 0x03, 0xE0, -+0x6B, 0x1C, 0x99, 0x42, 0x28, 0x46, 0x10, 0xD9, 0x44, 0x78, 0x06, 0x78, 0xA3, 0x1C, 0x01, 0x2E, 0x03, 0xEB, 0x00, 0x05, -+0xF4, 0xD1, 0xA9, 0x42, 0x07, 0xD3, 0x38, 0xB1, 0x0A, 0x2B, 0x04, 0xD8, 0x02, 0x2B, 0x02, 0xD0, 0x14, 0x70, 0x70, 0xBC, -+0x70, 0x47, 0x00, 0x20, 0x70, 0xBC, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x17, 0xD9, -+0x70, 0xB4, 0x03, 0xE0, 0x6B, 0x1C, 0x99, 0x42, 0x28, 0x46, 0x0E, 0xD9, 0x44, 0x78, 0x06, 0x78, 0xA3, 0x1C, 0x32, 0x2E, -+0x03, 0xEB, 0x00, 0x05, 0xF4, 0xD1, 0xA9, 0x42, 0x05, 0xD3, 0x28, 0xB1, 0x02, 0x2B, 0x02, 0xD0, 0x14, 0x70, 0x70, 0xBC, -+0x70, 0x47, 0x00, 0x20, 0x70, 0xBC, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, -+0x70, 0xB4, 0x03, 0xE0, 0x73, 0x1C, 0x99, 0x42, 0x30, 0x46, 0x10, 0xD9, 0x45, 0x78, 0x04, 0x78, 0xAB, 0x1C, 0x1E, 0x18, -+0x00, 0x2C, 0xF5, 0xD1, 0xB1, 0x42, 0x05, 0xD3, 0x10, 0xB1, 0x22, 0x2B, 0x02, 0xD8, 0x15, 0x70, 0x70, 0xBC, 0x70, 0x47, -+0x20, 0x46, 0x70, 0xBC, 0x70, 0x47, 0x00, 0x20, 0x70, 0xBC, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, -+0x99, 0x42, 0x17, 0xD9, 0x70, 0xB4, 0x03, 0xE0, 0x6B, 0x1C, 0x99, 0x42, 0x28, 0x46, 0x0E, 0xD9, 0x44, 0x78, 0x06, 0x78, -+0xA3, 0x1C, 0x07, 0x2E, 0x03, 0xEB, 0x00, 0x05, 0xF4, 0xD1, 0xA9, 0x42, 0x05, 0xD3, 0x28, 0xB1, 0x07, 0x2B, 0x02, 0xD9, -+0x14, 0x70, 0x70, 0xBC, 0x70, 0x47, 0x00, 0x20, 0x70, 0xBC, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, -+0x99, 0x42, 0x17, 0xD9, 0x70, 0xB4, 0x03, 0xE0, 0x6B, 0x1C, 0x99, 0x42, 0x28, 0x46, 0x0E, 0xD9, 0x44, 0x78, 0x06, 0x78, -+0xA3, 0x1C, 0x30, 0x2E, 0x03, 0xEB, 0x00, 0x05, 0xF4, 0xD1, 0xA9, 0x42, 0x05, 0xD3, 0x28, 0xB1, 0x13, 0x2B, 0x02, 0xD9, -+0x14, 0x70, 0x70, 0xBC, 0x70, 0x47, 0x00, 0x20, 0x70, 0xBC, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, -+0x99, 0x42, 0x19, 0xD9, 0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, -+0x02, 0x33, 0x25, 0x2C, 0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, 0x05, 0x2B, 0x18, 0xBF, -+0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, -+0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, 0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, -+0x43, 0x78, 0x04, 0x78, 0x02, 0x33, 0x3C, 0x2C, 0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, -+0x06, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, -+0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x1A, 0xD9, 0x30, 0xB4, 0x03, 0xE0, 0x63, 0x1C, 0x99, 0x42, -+0x20, 0x46, 0x11, 0xD9, 0x43, 0x78, 0x05, 0x78, 0x02, 0x33, 0x3E, 0x2D, 0x03, 0xEB, 0x00, 0x04, 0xF4, 0xD1, 0xA1, 0x42, -+0x08, 0xD3, 0x40, 0xB1, 0xA3, 0xF1, 0x03, 0x03, 0xB3, 0xFA, 0x83, 0xF3, 0x5B, 0x09, 0x30, 0xBC, 0x13, 0x70, 0x70, 0x47, -+0x00, 0x20, 0x30, 0xBC, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x2B, 0xD9, -+0x30, 0xB4, 0x03, 0xE0, 0x18, 0x46, 0x01, 0x33, 0x99, 0x42, 0x16, 0xD9, 0x44, 0x78, 0x05, 0x78, 0xA3, 0x1C, 0xC4, 0x2D, -+0x03, 0x44, 0xF5, 0xD1, 0x99, 0x42, 0x0E, 0xD3, 0x70, 0xB1, 0x02, 0x30, 0x04, 0x44, 0x07, 0xE0, 0x43, 0x78, 0x05, 0x78, -+0x02, 0x33, 0xC2, 0x2D, 0x03, 0xEB, 0x00, 0x01, 0x06, 0xD0, 0x08, 0x46, 0x43, 0x1C, 0x9C, 0x42, 0xF4, 0xD8, 0x00, 0x20, -+0x30, 0xBC, 0x70, 0x47, 0x8C, 0x42, 0xFA, 0xD3, 0x00, 0x28, 0xF9, 0xD0, 0xA3, 0xF1, 0x05, 0x03, 0xB3, 0xFA, 0x83, 0xF3, -+0x5B, 0x09, 0x30, 0xBC, 0x13, 0x70, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, -+0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, 0x02, 0x33, 0x03, 0x2C, -+0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, 0x03, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x5D, 0xF8, -+0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, -+0x99, 0x42, 0x19, 0xD9, 0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, -+0x02, 0x33, 0x4C, 0x2C, 0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, 0x12, 0x2B, 0x18, 0xBF, -+0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, -+0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, 0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, -+0x43, 0x78, 0x04, 0x78, 0x02, 0x33, 0x2A, 0x2C, 0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, -+0x03, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, -+0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, 0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, -+0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, 0x02, 0x33, 0xC7, 0x2C, 0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, -+0x06, 0xD3, 0x30, 0xB1, 0x03, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, -+0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, 0x10, 0xB4, 0x03, 0xE0, -+0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, 0x02, 0x33, 0x20, 0x2C, 0x03, 0xEB, 0x00, 0x02, -+0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, 0x03, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, -+0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, -+0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, 0x02, 0x33, 0x36, 0x2C, -+0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, 0x05, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x5D, 0xF8, -+0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0xB5, 0x83, 0xB0, -+0x06, 0x4A, 0x0D, 0xF1, 0x06, 0x03, 0xFF, 0xF7, 0xC1, 0xFD, 0x20, 0xB1, 0xBD, 0xF8, 0x06, 0x30, 0x1A, 0x2B, 0x18, 0xBF, -+0x00, 0x20, 0x03, 0xB0, 0x5D, 0xF8, 0x04, 0xFB, 0x98, 0xB2, 0x15, 0x00, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, -+0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, 0x02, 0x33, 0x2D, 0x2C, -+0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, 0x1C, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x5D, 0xF8, -+0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, -+0x99, 0x42, 0x19, 0xD9, 0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, -+0x02, 0x33, 0x47, 0x2C, 0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, 0x06, 0x2B, 0x38, 0xBF, -+0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, -+0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x1D, 0xD9, 0x10, 0xB4, 0x03, 0xE0, 0x63, 0x1C, 0x99, 0x42, 0x20, 0x46, 0x13, 0xD9, -+0x43, 0x78, 0x02, 0x78, 0x02, 0x33, 0x1C, 0x18, 0x00, 0x2A, 0xF5, 0xD1, 0xA1, 0x42, 0x03, 0xD2, 0x10, 0x46, 0x5D, 0xF8, -+0x04, 0x4B, 0x70, 0x47, 0x00, 0x28, 0xFA, 0xD0, 0x06, 0x2B, 0x38, 0xBF, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, -+0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, -+0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, 0x02, 0x33, 0x53, 0x2C, -+0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, 0x04, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x5D, 0xF8, -+0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, -+0x99, 0x42, 0x19, 0xD9, 0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, -+0x02, 0x33, 0x55, 0x2C, 0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, 0x02, 0x2B, 0x08, 0xBF, -+0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, -+0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, 0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, -+0x43, 0x78, 0x04, 0x78, 0x02, 0x33, 0xBF, 0x2C, 0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, -+0x0E, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, -+0x00, 0x20, 0x70, 0x47, 0x10, 0xB5, 0x82, 0xB0, 0x14, 0x46, 0x0D, 0xF1, 0x06, 0x03, 0x23, 0x22, 0xFF, 0xF7, 0xB2, 0xFC, -+0x40, 0xB1, 0xBD, 0xF8, 0x06, 0x30, 0xA3, 0xF1, 0x18, 0x02, 0x21, 0x2A, 0x9A, 0xBF, 0x03, 0x3B, 0x23, 0x70, 0x00, 0x20, -+0x02, 0xB0, 0x10, 0xBD, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, 0x10, 0xB4, 0x03, 0xE0, 0x53, 0x1C, 0x99, 0x42, -+0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, 0x02, 0x33, 0x3D, 0x2C, 0x03, 0xEB, 0x00, 0x02, 0xF4, 0xD1, 0x91, 0x42, -+0x06, 0xD3, 0x30, 0xB1, 0x18, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x5D, 0xF8, -+0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x44, 0x43, 0x1C, 0x99, 0x42, 0x19, 0xD9, 0x10, 0xB4, 0x03, 0xE0, -+0x53, 0x1C, 0x99, 0x42, 0x10, 0x46, 0x0F, 0xD9, 0x43, 0x78, 0x04, 0x78, 0x02, 0x33, 0xC0, 0x2C, 0x03, 0xEB, 0x00, 0x02, -+0xF4, 0xD1, 0x91, 0x42, 0x06, 0xD3, 0x30, 0xB1, 0x07, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, -+0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x10, 0xB5, 0x82, 0xB0, 0x14, 0x46, 0x0D, 0xF1, -+0x06, 0x03, 0x24, 0x22, 0xFF, 0xF7, 0x5E, 0xFC, 0x40, 0xB1, 0xBD, 0xF8, 0x06, 0x30, 0xA3, 0xF1, 0x09, 0x02, 0x09, 0x2A, -+0x9A, 0xBF, 0x03, 0x3B, 0x23, 0x70, 0x00, 0x20, 0x02, 0xB0, 0x10, 0xBD, 0x00, 0xB5, 0x83, 0xB0, 0x0D, 0xF1, 0x06, 0x03, -+0x26, 0x22, 0xFF, 0xF7, 0x4B, 0xFC, 0x20, 0xB1, 0xBD, 0xF8, 0x06, 0x30, 0x10, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x03, 0xB0, -+0x5D, 0xF8, 0x04, 0xFB, 0x00, 0xB5, 0x83, 0xB0, 0x0D, 0xF1, 0x06, 0x03, 0x25, 0x22, 0xFF, 0xF7, 0x3B, 0xFC, 0x20, 0xB1, -+0xBD, 0xF8, 0x06, 0x30, 0x04, 0x2B, 0x18, 0xBF, 0x00, 0x20, 0x03, 0xB0, 0x5D, 0xF8, 0x04, 0xFB, 0x43, 0x79, 0x02, 0x79, -+0x58, 0x00, 0x40, 0xEA, 0xD2, 0x10, 0x80, 0x05, 0x70, 0x47, 0x00, 0xBF, 0x43, 0x79, 0x07, 0x48, 0x83, 0xEA, 0x13, 0x13, -+0x5B, 0x01, 0xC1, 0xF3, 0x08, 0x01, 0x03, 0xF4, 0xF0, 0x73, 0x0B, 0x44, 0x00, 0xEA, 0x83, 0x50, 0x40, 0xF4, 0x7C, 0x10, -+0x70, 0x47, 0x00, 0xBF, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x28, 0x08, 0xDA, 0x10, 0xF1, 0x6D, 0x0F, 0x01, 0xDA, 0x00, 0x20, -+0x70, 0x47, 0x6E, 0x30, 0x40, 0x00, 0xC0, 0xB2, 0x70, 0x47, 0xDC, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x4F, -+0x1D, 0x46, 0x95, 0xB0, 0x90, 0x46, 0xDD, 0xF8, 0x78, 0xB0, 0x15, 0xF8, 0x01, 0x2B, 0x03, 0x91, 0x07, 0x46, 0x00, 0x28, -+0x00, 0xF0, 0x7F, 0x81, 0x00, 0x2A, 0x00, 0xF0, 0x91, 0x83, 0x00, 0x24, 0xCD, 0xE9, 0x00, 0x44, 0x03, 0x9E, 0x02, 0x94, -+0xA1, 0x46, 0xA2, 0x46, 0xA2, 0xF1, 0x20, 0x03, 0x58, 0x2B, 0x5A, 0xD8, 0xDF, 0xE8, 0x13, 0xF0, 0x35, 0x01, 0x59, 0x00, -+0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x34, 0x03, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x17, 0x03, 0x35, 0x01, -+0x59, 0x00, 0x35, 0x01, 0x36, 0x03, 0x59, 0x00, 0x12, 0x01, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, -+0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, -+0x59, 0x00, 0x6E, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, -+0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x6E, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, -+0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x6E, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, -+0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x6E, 0x00, 0x6E, 0x00, 0x6E, 0x00, 0x6E, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, -+0x10, 0x01, 0x6E, 0x00, 0x59, 0x00, 0x59, 0x00, 0x10, 0x01, 0x6E, 0x00, 0x59, 0x00, 0x59, 0x00, 0x6E, 0x00, 0x59, 0x00, -+0x59, 0x00, 0x6E, 0x00, 0x59, 0x00, 0x6E, 0x00, 0x59, 0x00, 0x59, 0x00, 0x6E, 0x00, 0xA2, 0xF1, 0x31, 0x01, 0x08, 0x29, -+0x40, 0xF2, 0xE2, 0x80, 0x00, 0x21, 0x9E, 0x48, 0x00, 0xEB, 0xCA, 0x0A, 0x1A, 0xF8, 0x01, 0xA0, 0xBA, 0xF1, 0x07, 0x0F, -+0x00, 0xF2, 0xD8, 0x83, 0xDF, 0xE8, 0x0A, 0xF0, 0x75, 0x5B, 0x45, 0x9A, 0x70, 0x8E, 0x80, 0x06, 0x07, 0x21, 0xEE, 0xE7, -+0xA2, 0xF1, 0x41, 0x03, 0x37, 0x2B, 0x00, 0xF2, 0x05, 0x82, 0xDF, 0xE8, 0x13, 0xF0, 0x05, 0x02, 0x03, 0x02, 0x03, 0x02, -+0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x54, 0x02, -+0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, -+0x29, 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x05, 0x02, -+0x29, 0x01, 0x5E, 0x01, 0x29, 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0xA3, 0x01, 0x03, 0x02, 0x03, 0x02, -+0x03, 0x02, 0x54, 0x02, 0x03, 0x02, 0x03, 0x02, 0x29, 0x01, 0x03, 0x02, 0x03, 0x02, 0xF8, 0x01, 0x03, 0x02, 0x29, 0x01, -+0x03, 0x02, 0x03, 0x02, 0x29, 0x01, 0x10, 0x2B, 0x00, 0xF2, 0xCA, 0x80, 0xDF, 0xE8, 0x13, 0xF0, 0xD2, 0x00, 0xC8, 0x00, -+0xC8, 0x00, 0xC8, 0x00, 0xC8, 0x00, 0xC8, 0x00, 0xC8, 0x00, 0xC8, 0x00, 0xC8, 0x00, 0xC8, 0x00, 0xC8, 0x00, 0xD9, 0x00, -+0xC8, 0x00, 0xE0, 0x00, 0xC8, 0x00, 0xC8, 0x00, 0xC1, 0x00, 0x00, 0x23, 0x00, 0x93, 0x02, 0x93, 0x4F, 0xF0, 0xFF, 0x33, -+0x01, 0x93, 0x4F, 0xF0, 0x01, 0x0A, 0x15, 0xF8, 0x01, 0x2B, 0x00, 0x2A, 0x7F, 0xF4, 0x28, 0xAF, 0x00, 0x2E, 0x62, 0xD0, -+0x00, 0x23, 0x3B, 0x70, 0x20, 0x46, 0x15, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x23, 0x01, 0x93, 0x4F, 0xF0, 0x04, 0x0A, -+0xED, 0xE7, 0x2E, 0xB1, 0xA0, 0x45, 0x9C, 0xBF, 0x07, 0xF8, 0x01, 0x2B, 0x06, 0xF1, 0xFF, 0x36, 0x01, 0x34, 0x4F, 0xF0, -+0x00, 0x0A, 0xE2, 0xE7, 0x68, 0x2A, 0x7B, 0xD0, 0x6C, 0x2A, 0x3F, 0xD0, 0x57, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xC0, 0xF2, 0x92, 0x82, 0x4F, 0xF0, 0x06, 0x0A, 0xD4, 0xE7, 0x2A, 0x2A, 0x61, 0xD0, 0x01, 0x9B, 0x30, 0x3A, -+0x03, 0xEB, 0x83, 0x03, 0x02, 0xEB, 0x43, 0x03, 0x01, 0x93, 0x4F, 0xF0, 0x05, 0x0A, 0xC8, 0xE7, 0x2A, 0x2A, 0x5B, 0xD0, -+0x02, 0x9B, 0x30, 0x3A, 0x03, 0xEB, 0x83, 0x03, 0x02, 0xEB, 0x43, 0x03, 0x02, 0x93, 0x4F, 0xF0, 0x03, 0x0A, 0xBC, 0xE7, -+0x06, 0x21, 0x4C, 0xE7, 0x44, 0x4B, 0x03, 0xEB, 0xCA, 0x0A, 0x9A, 0xF8, 0x03, 0xA0, 0xBA, 0xF1, 0x07, 0x0F, 0x00, 0xF2, -+0x25, 0x83, 0x01, 0xA3, 0x53, 0xF8, 0x2A, 0xF0, 0x8F, 0x3F, 0x14, 0x00, 0x5B, 0x3F, 0x14, 0x00, 0xBB, 0x40, 0x14, 0x00, -+0xD9, 0x3F, 0x14, 0x00, 0x85, 0x3F, 0x14, 0x00, 0xC1, 0x3F, 0x14, 0x00, 0xA5, 0x3F, 0x14, 0x00, 0xB1, 0x3E, 0x14, 0x00, -+0x00, 0x9B, 0x43, 0xF0, 0x02, 0x03, 0x00, 0x93, 0x4F, 0xF0, 0x06, 0x0A, 0x97, 0xE7, 0x05, 0x21, 0x27, 0xE7, 0x03, 0x9B, -+0x00, 0x2B, 0x9B, 0xD0, 0x20, 0x46, 0x07, 0xF8, 0x01, 0x6C, 0x15, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x2D, 0x49, 0x01, 0xEB, -+0xCA, 0x0A, 0x9A, 0xF8, 0x04, 0xA0, 0xBA, 0xF1, 0x07, 0x0F, 0x00, 0xF2, 0xF7, 0x82, 0x01, 0xA1, 0x51, 0xF8, 0x2A, 0xF0, -+0x8F, 0x3F, 0x14, 0x00, 0x5B, 0x3F, 0x14, 0x00, 0x2F, 0x3F, 0x14, 0x00, 0xDD, 0x3F, 0x14, 0x00, 0x85, 0x3F, 0x14, 0x00, -+0xC1, 0x3F, 0x14, 0x00, 0xA5, 0x3F, 0x14, 0x00, 0xB1, 0x3E, 0x14, 0x00, 0x5B, 0xF8, 0x04, 0x3B, 0x01, 0x93, 0x4F, 0xF0, -+0x05, 0x0A, 0x6A, 0xE7, 0x5B, 0xF8, 0x04, 0x3B, 0x02, 0x93, 0x4F, 0xF0, 0x03, 0x0A, 0x64, 0xE7, 0x00, 0x9B, 0x43, 0xF0, -+0x01, 0x03, 0x00, 0x93, 0x4F, 0xF0, 0x06, 0x0A, 0x5D, 0xE7, 0x14, 0x46, 0x00, 0x2A, 0x3F, 0xF4, 0x63, 0xAF, 0x03, 0x90, -+0x7D, 0xE6, 0x00, 0x9B, 0x43, 0xF0, 0x40, 0x03, 0x00, 0x93, 0x4F, 0xF0, 0x02, 0x0A, 0x50, 0xE7, 0x10, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0x9E, 0x82, 0x4F, 0xF0, 0x02, 0x0A, 0x46, 0xE7, 0x00, 0x9B, 0x43, 0xF0, -+0x10, 0x03, 0x00, 0x93, 0x4F, 0xF0, 0x02, 0x0A, 0x3F, 0xE7, 0x00, 0x9B, 0x43, 0xF0, 0x08, 0x03, 0x00, 0x93, 0x4F, 0xF0, -+0x02, 0x0A, 0x38, 0xE7, 0x00, 0x9B, 0x43, 0xF0, 0x20, 0x03, 0x00, 0x93, 0x4F, 0xF0, 0x02, 0x0A, 0x31, 0xE7, 0x00, 0xBF, -+0x24, 0xB3, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x00, 0x9B, 0x9B, 0x07, 0x00, 0xF1, 0x94, 0x81, 0x00, 0x9B, 0xD8, 0x07, -+0x40, 0xF1, 0x90, 0x81, 0x64, 0x2A, 0x00, 0xF0, 0x32, 0x82, 0x5B, 0xF8, 0x04, 0x1B, 0x58, 0x3A, 0x89, 0xB2, 0x20, 0x2A, -+0x00, 0xF2, 0x24, 0x82, 0xDF, 0xE8, 0x12, 0xF0, 0x5A, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, -+0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x4E, 0x02, 0x22, 0x02, 0x72, 0x00, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, -+0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x36, 0x02, 0x22, 0x02, -+0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x72, 0x00, 0x22, 0x02, 0x22, 0x02, 0x69, 0x02, 0x02, 0x9B, 0x59, 0x1E, 0x5B, 0xF8, -+0x04, 0x3B, 0x8D, 0xF8, 0x10, 0x30, 0x00, 0x9B, 0x04, 0xAA, 0x03, 0xF0, 0x40, 0x00, 0x01, 0x23, 0x00, 0x28, 0x70, 0xD1, -+0x00, 0x98, 0x80, 0x06, 0x40, 0xF1, 0x15, 0x81, 0x00, 0x2B, 0x00, 0xF0, 0xEA, 0x81, 0x10, 0x46, 0x02, 0xEB, 0x03, 0x09, -+0xA4, 0xEB, 0x02, 0x0E, 0x09, 0xE0, 0xE0, 0x45, 0x04, 0xD8, 0x07, 0x78, 0x02, 0xF8, 0x01, 0x7B, 0x01, 0x3E, 0x17, 0x46, -+0x01, 0x30, 0x48, 0x45, 0x07, 0xD0, 0x00, 0xEB, 0x0E, 0x0C, 0x3A, 0x46, 0x00, 0x2E, 0xF0, 0xD1, 0x01, 0x30, 0x48, 0x45, -+0xF4, 0xD1, 0x23, 0x44, 0x00, 0x29, 0x40, 0xF3, 0xCA, 0x81, 0xCC, 0x18, 0x20, 0x21, 0x08, 0xE0, 0x98, 0x45, 0x03, 0xD8, -+0x02, 0xF8, 0x01, 0x1B, 0x01, 0x3E, 0x17, 0x46, 0x01, 0x33, 0xA3, 0x42, 0x05, 0xD0, 0x3A, 0x46, 0x00, 0x2E, 0xF3, 0xD1, -+0x01, 0x33, 0xA3, 0x42, 0xF6, 0xD1, 0x4F, 0xF0, 0x07, 0x0A, 0xB2, 0xE6, 0x00, 0x9B, 0x99, 0x07, 0x03, 0xD4, 0x00, 0x9B, -+0xDA, 0x07, 0x00, 0xF1, 0xBC, 0x81, 0x5B, 0xF8, 0x04, 0x1B, 0x00, 0x29, 0xC0, 0xF2, 0xBE, 0x81, 0xDF, 0xF8, 0x5C, 0xA4, -+0x00, 0x23, 0x0D, 0xF1, 0x50, 0x0E, 0xAA, 0xFB, 0x01, 0x2C, 0x4F, 0xEA, 0xDC, 0x0C, 0x0C, 0xEB, 0x8C, 0x00, 0xA1, 0xEB, -+0x40, 0x00, 0x89, 0x46, 0x30, 0x30, 0xB9, 0xF1, 0x09, 0x0F, 0x72, 0x46, 0x61, 0x46, 0x0E, 0xF8, 0x01, 0x0D, 0x18, 0x46, -+0x03, 0xF1, 0x01, 0x03, 0xEB, 0xD8, 0x00, 0x99, 0x09, 0x06, 0x00, 0xF1, 0x9E, 0x81, 0x00, 0x99, 0x09, 0x07, 0x40, 0xF1, -+0xE7, 0x81, 0x83, 0x1C, 0x2B, 0x20, 0x0E, 0xF8, 0x01, 0x0C, 0x00, 0x98, 0x02, 0x99, 0x00, 0xF0, 0x40, 0x00, 0x02, 0x3A, -+0xC9, 0x1A, 0x00, 0x28, 0x8E, 0xD0, 0x00, 0x29, 0x14, 0xDD, 0x0C, 0x44, 0x4F, 0xF0, 0x30, 0x0E, 0x08, 0xE0, 0xE0, 0x45, -+0x03, 0xD8, 0x00, 0xF8, 0x01, 0xEB, 0x01, 0x3E, 0x07, 0x46, 0x01, 0x39, 0x00, 0xF0, 0xB0, 0x80, 0xA4, 0xEB, 0x01, 0x0C, -+0x38, 0x46, 0x00, 0x2E, 0xF1, 0xD1, 0x01, 0x39, 0xF5, 0xD1, 0x00, 0x21, 0x00, 0x2B, 0x7F, 0xF4, 0x7C, 0xAF, 0x91, 0x46, -+0xA7, 0xE7, 0x5B, 0xF8, 0x04, 0x2B, 0x00, 0x2A, 0x40, 0xF0, 0x2C, 0x81, 0x00, 0x9B, 0x02, 0x99, 0x03, 0xF0, 0x40, 0x00, -+0x00, 0x23, 0x65, 0xE7, 0x4A, 0x46, 0xF7, 0xE7, 0x5B, 0xF8, 0x04, 0x3B, 0x02, 0x9A, 0xDF, 0xF8, 0xB0, 0xE3, 0x9C, 0x46, -+0x1C, 0xF8, 0x01, 0x3B, 0x00, 0x2A, 0x00, 0xF0, 0x09, 0x81, 0x19, 0x11, 0x15, 0x2A, 0x03, 0xF0, 0x0F, 0x03, 0x1E, 0xF8, -+0x01, 0x10, 0x1E, 0xF8, 0x03, 0x30, 0x8D, 0xF8, 0x10, 0x10, 0x28, 0xBF, 0x15, 0x22, 0x02, 0xEB, 0x42, 0x01, 0x01, 0x3A, -+0x8D, 0xF8, 0x11, 0x30, 0x01, 0xF1, 0xFF, 0x33, 0xC1, 0xF1, 0x01, 0x01, 0x1D, 0xD0, 0x0C, 0xEB, 0x02, 0x0A, 0x0D, 0xF1, -+0x13, 0x02, 0x1C, 0xF0, 0x03, 0x0F, 0x1C, 0xF8, 0x01, 0x0B, 0x4F, 0xEA, 0x20, 0x19, 0x00, 0xF0, 0x0F, 0x00, 0x1E, 0xF8, -+0x09, 0x90, 0x82, 0xF8, 0x00, 0x90, 0x1E, 0xF8, 0x00, 0x00, 0x50, 0x70, 0x0C, 0xBF, 0x4F, 0xF0, 0x3A, 0x09, 0x4F, 0xF0, -+0x2E, 0x09, 0xE2, 0x45, 0x02, 0xF8, 0x01, 0x9C, 0x02, 0xF1, 0x03, 0x02, 0xE5, 0xD1, 0x00, 0x9A, 0x02, 0xF0, 0x40, 0x02, -+0x00, 0x2A, 0x40, 0xF0, 0x69, 0x81, 0x00, 0x98, 0x02, 0x92, 0x80, 0x06, 0x04, 0xAA, 0x3F, 0xF5, 0x1F, 0xAF, 0x00, 0x2B, -+0x7F, 0xF4, 0x1F, 0xAF, 0xA1, 0xE7, 0x5B, 0xF8, 0x04, 0x1B, 0xDF, 0xF8, 0x14, 0xE3, 0x8C, 0x46, 0x4F, 0xF0, 0x3A, 0x09, -+0x1C, 0xF8, 0x06, 0x3B, 0x1A, 0x11, 0x03, 0xF0, 0x0F, 0x03, 0x1E, 0xF8, 0x02, 0x20, 0x1E, 0xF8, 0x03, 0x30, 0x8D, 0xF8, -+0x11, 0x30, 0x8D, 0xF8, 0x10, 0x20, 0x01, 0x31, 0x04, 0xAB, 0x11, 0xF8, 0x01, 0x2B, 0x83, 0xF8, 0x02, 0x90, 0x10, 0x11, -+0x02, 0xF0, 0x0F, 0x02, 0x1E, 0xF8, 0x00, 0x00, 0x1E, 0xF8, 0x02, 0x20, 0xD8, 0x70, 0x8C, 0x45, 0x1A, 0x71, 0x03, 0xF1, -+0x03, 0x03, 0xEE, 0xD1, 0x02, 0x9B, 0xA3, 0xF1, 0x11, 0x01, 0x00, 0x9B, 0x04, 0xAA, 0x03, 0xF0, 0x40, 0x00, 0x11, 0x23, -+0xE4, 0xE6, 0x00, 0x29, 0x7F, 0xF7, 0x6C, 0xAF, 0x21, 0x44, 0x4F, 0xF0, 0x20, 0x0C, 0x08, 0xE0, 0xA0, 0x45, 0x03, 0xD8, -+0x00, 0xF8, 0x01, 0xCB, 0x01, 0x3E, 0x07, 0x46, 0x01, 0x34, 0xA1, 0x42, 0x05, 0xD0, 0x38, 0x46, 0x00, 0x2E, 0xF3, 0xD1, -+0x01, 0x34, 0xA1, 0x42, 0xF6, 0xD1, 0x0C, 0x46, 0x00, 0x21, 0x00, 0x2B, 0x7F, 0xF4, 0xD3, 0xAE, 0x55, 0xE7, 0x04, 0x23, -+0x9A, 0x49, 0x01, 0xEB, 0xCA, 0x0A, 0x1A, 0xF8, 0x03, 0xA0, 0xBA, 0xF1, 0x07, 0x0F, 0x00, 0xF2, 0x1F, 0x81, 0x01, 0xA3, -+0x53, 0xF8, 0x2A, 0xF0, 0x8F, 0x3F, 0x14, 0x00, 0x5B, 0x3F, 0x14, 0x00, 0xC9, 0x40, 0x14, 0x00, 0xD9, 0x3F, 0x14, 0x00, -+0x85, 0x3F, 0x14, 0x00, 0xC1, 0x3F, 0x14, 0x00, 0xA5, 0x3F, 0x14, 0x00, 0xB1, 0x3E, 0x14, 0x00, 0x01, 0x23, 0xE1, 0xE7, -+0x02, 0x21, 0x26, 0xE5, 0x58, 0x3A, 0x5B, 0xF8, 0x04, 0x1B, 0x20, 0x2A, 0x00, 0xF2, 0x98, 0x80, 0x01, 0xA3, 0x53, 0xF8, -+0x22, 0xF0, 0x00, 0xBF, 0xED, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, -+0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, -+0x7D, 0x45, 0x14, 0x00, 0xD5, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x17, 0x42, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, -+0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, -+0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, -+0xA5, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, -+0x1D, 0x42, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x7D, 0x45, 0x14, 0x00, 0x0B, 0x46, 0x14, 0x00, 0x03, 0x9E, 0x14, 0x46, -+0x4A, 0xE5, 0x64, 0x49, 0x64, 0x48, 0x4F, 0xF4, 0xA2, 0x72, 0x00, 0xF0, 0x49, 0xFB, 0x4F, 0xF0, 0x06, 0x0A, 0x3C, 0xE5, -+0x1A, 0x11, 0x03, 0xF0, 0x0F, 0x03, 0x1E, 0xF8, 0x02, 0x20, 0x1E, 0xF8, 0x03, 0x30, 0x8D, 0xF8, 0x10, 0x20, 0x8D, 0xF8, -+0x11, 0x30, 0x6F, 0xF0, 0x2E, 0x01, 0x2F, 0x23, 0x0F, 0x22, 0xFC, 0xE6, 0x13, 0x78, 0x00, 0x2B, 0x00, 0xF0, 0x97, 0x80, -+0x01, 0x9B, 0x00, 0x2B, 0x3F, 0xF4, 0xCC, 0xAE, 0x01, 0x9B, 0x11, 0x46, 0xC2, 0xF1, 0x01, 0x00, 0x00, 0x2B, 0x00, 0xEB, -+0x01, 0x0C, 0x0F, 0xDD, 0x11, 0xF8, 0x01, 0xEF, 0x01, 0x3B, 0xBE, 0xF1, 0x00, 0x0F, 0x10, 0xD0, 0x00, 0x2B, 0xF3, 0xD1, -+0x02, 0x99, 0x00, 0x98, 0x01, 0x93, 0x63, 0x46, 0xC9, 0x1A, 0x00, 0xF0, 0x40, 0x00, 0x1F, 0xE6, 0x00, 0xEB, 0x01, 0x0C, -+0x11, 0xF8, 0x01, 0xEF, 0xBE, 0xF1, 0x00, 0x0F, 0xE4, 0xD1, 0x01, 0x93, 0x63, 0x46, 0x02, 0x99, 0x00, 0x98, 0xC9, 0x1A, -+0x00, 0xF0, 0x40, 0x00, 0x10, 0xE6, 0x1C, 0x46, 0x4F, 0xF0, 0x07, 0x0A, 0xF9, 0xE4, 0x23, 0x46, 0x91, 0x46, 0x2B, 0xE6, -+0x00, 0x9B, 0x02, 0x99, 0x03, 0xF0, 0x40, 0x00, 0x14, 0xAA, 0x00, 0x23, 0x02, 0xE6, 0x5B, 0xF8, 0x04, 0x1B, 0x09, 0xB2, -+0x41, 0xE6, 0x83, 0x1C, 0x2D, 0x20, 0x64, 0xE6, 0x00, 0x9B, 0x43, 0xF0, 0x80, 0x03, 0x49, 0x42, 0x00, 0x93, 0x3B, 0xE6, -+0x00, 0x9B, 0x43, 0xF0, 0x40, 0x03, 0x00, 0x93, 0x08, 0x23, 0x40, 0x20, 0x02, 0x93, 0xDF, 0xF8, 0xD0, 0xC0, 0x14, 0xAA, -+0x01, 0xF0, 0x0F, 0x03, 0x09, 0x09, 0x1C, 0xF8, 0x03, 0x30, 0x02, 0xF8, 0x01, 0x3D, 0x14, 0xAB, 0xA3, 0xEB, 0x02, 0x03, -+0xF4, 0xD1, 0x02, 0x99, 0xC9, 0x1A, 0xDD, 0xE5, 0x14, 0xAA, 0x01, 0xF0, 0x01, 0x03, 0x30, 0x33, 0x02, 0xF8, 0x01, 0x3D, -+0x49, 0x08, 0x14, 0xAB, 0xA3, 0xEB, 0x02, 0x03, 0xF5, 0xD1, 0xBA, 0xE7, 0xDF, 0xF8, 0x90, 0xE0, 0x14, 0xAA, 0x01, 0xF0, -+0x0F, 0x03, 0x09, 0x09, 0x1E, 0xF8, 0x03, 0x30, 0x02, 0xF8, 0x01, 0x3D, 0x14, 0xAB, 0xA3, 0xEB, 0x02, 0x03, 0xF4, 0xD1, -+0xAB, 0xE7, 0x00, 0x9B, 0x03, 0xF0, 0x40, 0x00, 0xCF, 0xE7, 0x17, 0x49, 0x17, 0x48, 0x40, 0xF2, 0x11, 0x12, 0x00, 0xF0, -+0xAF, 0xFA, 0x4F, 0xF0, 0x02, 0x0A, 0xA2, 0xE4, 0x00, 0x22, 0x02, 0x92, 0x04, 0xAA, 0xBA, 0xE5, 0x00, 0x99, 0xC9, 0x06, -+0x06, 0xD4, 0x02, 0x98, 0xC1, 0x1A, 0x00, 0x98, 0x72, 0x46, 0x00, 0xF0, 0x40, 0x00, 0xA7, 0xE5, 0x83, 0x1C, 0x20, 0x20, -+0x0D, 0xE6, 0x00, 0x99, 0x01, 0xF0, 0x40, 0x00, 0x02, 0x99, 0x9F, 0xE5, 0x09, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xBF, 0xF6, 0x86, 0xAC, 0x04, 0x49, 0x04, 0x48, 0x4F, 0xF4, 0x12, 0x72, 0x00, 0xF0, 0x89, 0xFA, 0x7E, 0xE4, -+0x24, 0xB3, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0xCD, 0xCC, 0xCC, 0xCC, -+0x10, 0xB3, 0x15, 0x00, 0xFC, 0xB2, 0x15, 0x00, 0x0F, 0xB4, 0x2D, 0xE9, 0xF0, 0x47, 0x21, 0x4E, 0xD6, 0xF8, 0x04, 0x31, -+0x82, 0xB0, 0xFB, 0xB1, 0x0A, 0x9C, 0xDF, 0xF8, 0x80, 0x80, 0xDF, 0xF8, 0x80, 0xA0, 0xDF, 0xF8, 0x80, 0x90, 0xA7, 0x1C, -+0x20, 0x46, 0x14, 0xF8, 0x01, 0x5B, 0x29, 0x06, 0xA5, 0xF1, 0x80, 0x02, 0x0A, 0xD5, 0x88, 0x2D, 0x13, 0xD8, 0xD6, 0xF8, -+0x00, 0x31, 0xDB, 0x43, 0xD3, 0x40, 0xDB, 0x07, 0x08, 0xD4, 0xA7, 0x42, 0x20, 0x46, 0xED, 0xD1, 0x12, 0x4B, 0x0B, 0xA9, -+0xD3, 0xF8, 0x30, 0x34, 0x01, 0x91, 0x98, 0x47, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x47, 0x04, 0xB0, 0x70, 0x47, 0xD8, 0xF8, -+0x00, 0x30, 0xB3, 0xF9, 0x00, 0x20, 0x05, 0xF1, 0x66, 0x03, 0x00, 0x2A, 0xDB, 0xB2, 0x05, 0xDB, 0xD6, 0xF8, 0x04, 0x31, -+0x9A, 0x3D, 0xAB, 0x42, 0xE3, 0xD8, 0xEB, 0xE7, 0x05, 0x2B, 0xF7, 0xD9, 0x40, 0xF2, 0xA9, 0x22, 0x51, 0x46, 0x48, 0x46, -+0x00, 0xF0, 0x36, 0xFA, 0xF0, 0xE7, 0x00, 0xBF, 0xB0, 0xB6, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xCC, 0xB2, 0x15, 0x00, 0x0E, 0xB4, 0x09, 0x4B, 0x00, 0xB5, 0x1B, 0x68, 0x1B, 0x88, 0x18, 0x42, -+0x82, 0xB0, 0x06, 0xD0, 0x06, 0x4B, 0x03, 0x98, 0xD3, 0xF8, 0x30, 0x34, 0x04, 0xA9, 0x01, 0x91, 0x98, 0x47, 0x02, 0xB0, -+0x5D, 0xF8, 0x04, 0xEB, 0x03, 0xB0, 0x70, 0x47, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x08, 0xB5, 0x05, 0x48, -+0xFF, 0xF7, 0x94, 0xFF, 0x01, 0x21, 0x40, 0xF2, 0x1F, 0x40, 0xFE, 0xF7, 0x35, 0xF8, 0xE0, 0xF7, 0x0F, 0xFC, 0xFE, 0xE7, -+0x64, 0xB3, 0x15, 0x00, 0x08, 0xB5, 0x05, 0x48, 0xFF, 0xF7, 0x86, 0xFF, 0x01, 0x21, 0x40, 0xF2, 0x1E, 0x40, 0xFE, 0xF7, -+0x27, 0xF8, 0xE0, 0xF7, 0x01, 0xFC, 0xFE, 0xE7, 0x7C, 0xB3, 0x15, 0x00, 0x30, 0xB5, 0x17, 0x48, 0x00, 0x68, 0x00, 0x78, -+0x02, 0x28, 0x83, 0xB0, 0x1D, 0x46, 0x06, 0xD1, 0x48, 0x78, 0x83, 0x1E, 0x01, 0x2B, 0x0C, 0x46, 0x0E, 0xD9, 0x05, 0x28, -+0x0C, 0xD0, 0x11, 0x48, 0x01, 0x92, 0xFF, 0xF7, 0x69, 0xFF, 0x01, 0x9A, 0x29, 0x46, 0x40, 0xF2, 0x1C, 0x40, 0xFE, 0xF7, -+0x63, 0xF9, 0x00, 0x20, 0x03, 0xB0, 0x30, 0xBD, 0x23, 0x78, 0x53, 0xB9, 0xA3, 0x78, 0x01, 0x92, 0x1B, 0xB1, 0xE1, 0xF7, -+0x17, 0xFE, 0x01, 0x9A, 0xEE, 0xE7, 0xE1, 0xF7, 0x1D, 0xFE, 0x01, 0x9A, 0xEA, 0xE7, 0x01, 0x21, 0x01, 0x92, 0xE1, 0xF7, -+0xE1, 0xFD, 0x60, 0x78, 0x01, 0x9A, 0xED, 0xE7, 0x78, 0x36, 0x17, 0x00, 0x88, 0xB3, 0x15, 0x00, 0x30, 0xB5, 0x83, 0xB0, -+0x0C, 0x46, 0x09, 0x48, 0x09, 0x68, 0x01, 0x92, 0x1D, 0x46, 0xFF, 0xF7, 0x3F, 0xFF, 0x07, 0x4B, 0x21, 0x68, 0xC3, 0xF8, -+0x04, 0x11, 0x01, 0x9A, 0x29, 0x46, 0x40, 0xF2, 0x07, 0x40, 0xFE, 0xF7, 0x35, 0xF9, 0x00, 0x20, 0x03, 0xB0, 0x30, 0xBD, -+0xA0, 0xB3, 0x15, 0x00, 0xB0, 0xB6, 0x17, 0x00, 0x30, 0xB5, 0x83, 0xB0, 0x0C, 0x46, 0x09, 0x48, 0x09, 0x68, 0x01, 0x92, -+0x1D, 0x46, 0xFF, 0xF7, 0x25, 0xFF, 0x07, 0x4B, 0x21, 0x68, 0xC3, 0xF8, 0x00, 0x11, 0x01, 0x9A, 0x29, 0x46, 0x40, 0xF2, -+0x05, 0x40, 0xFE, 0xF7, 0x1B, 0xF9, 0x00, 0x20, 0x03, 0xB0, 0x30, 0xBD, 0xC8, 0xB3, 0x15, 0x00, 0xB0, 0xB6, 0x17, 0x00, -+0x18, 0x46, 0x38, 0xB5, 0x0D, 0x46, 0x04, 0x23, 0x01, 0x46, 0x4F, 0xF4, 0x82, 0x60, 0xFE, 0xF7, 0xA3, 0xF8, 0x22, 0x4B, -+0xA9, 0x88, 0x93, 0xF8, 0xA9, 0x30, 0x04, 0x46, 0xEB, 0xB1, 0x4B, 0x1E, 0x01, 0x2B, 0x0D, 0xD9, 0x02, 0x29, 0x2A, 0xD0, -+0x03, 0x29, 0x2F, 0xD0, 0x04, 0x29, 0x1C, 0xD1, 0x1B, 0x4B, 0x2A, 0x68, 0xDA, 0x65, 0x4F, 0xF0, 0x80, 0x72, 0xC3, 0xF8, -+0x34, 0x21, 0x14, 0xE0, 0x18, 0x48, 0x17, 0x4A, 0x03, 0x68, 0x43, 0xF0, 0x00, 0x73, 0x03, 0x60, 0x53, 0x6F, 0x16, 0x48, -+0x43, 0xF0, 0x10, 0x03, 0x53, 0x67, 0x01, 0x23, 0x03, 0x70, 0x01, 0x29, 0xE2, 0xD1, 0x10, 0x4B, 0x2A, 0x68, 0xDA, 0x63, -+0x40, 0x22, 0xC3, 0xF8, 0x24, 0x21, 0x00, 0x25, 0x0F, 0x48, 0x25, 0x60, 0xFF, 0xF7, 0xDA, 0xFE, 0x20, 0x46, 0xFE, 0xF7, -+0x9F, 0xF8, 0x28, 0x46, 0x38, 0xBD, 0x08, 0x4B, 0x2A, 0x68, 0x9A, 0x65, 0x20, 0x22, 0xC3, 0xF8, 0x24, 0x21, 0xEE, 0xE7, -+0x04, 0x4B, 0x2A, 0x68, 0x1A, 0x64, 0x80, 0x22, 0xC3, 0xF8, 0x24, 0x21, 0xE7, 0xE7, 0x00, 0xBF, 0x2C, 0x19, 0x17, 0x00, -+0x00, 0x00, 0x50, 0x40, 0xE0, 0x50, 0x34, 0x40, 0x4C, 0x36, 0x17, 0x00, 0xF0, 0xB3, 0x15, 0x00, 0x30, 0xB5, 0x18, 0x46, -+0x0C, 0x46, 0x08, 0x23, 0x01, 0x46, 0x85, 0xB0, 0x40, 0xF2, 0x12, 0x40, 0xFE, 0xF7, 0x4A, 0xF8, 0x18, 0x4B, 0x22, 0x68, -+0x1B, 0x68, 0x1B, 0x78, 0x01, 0x3B, 0x01, 0x2B, 0x05, 0x46, 0x19, 0xD9, 0x11, 0x68, 0xA3, 0x68, 0x60, 0x68, 0x4B, 0x40, -+0x03, 0x40, 0x4B, 0x40, 0x13, 0x60, 0x22, 0x68, 0x2A, 0x60, 0x11, 0x68, 0xA3, 0x68, 0x69, 0x60, 0xCD, 0xE9, 0x01, 0x11, -+0x00, 0x92, 0x61, 0x68, 0x0D, 0x48, 0x1A, 0x46, 0xFF, 0xF7, 0x96, 0xFE, 0x28, 0x46, 0xFE, 0xF7, 0x5B, 0xF8, 0x00, 0x20, -+0x05, 0xB0, 0x30, 0xBD, 0x09, 0x4B, 0x9A, 0x42, 0x07, 0xD1, 0xD4, 0xE9, 0x01, 0x03, 0x11, 0x68, 0x4B, 0x40, 0x03, 0x40, -+0x4B, 0x40, 0x13, 0x60, 0x22, 0x68, 0xA3, 0x68, 0xC5, 0xE9, 0x00, 0x23, 0x19, 0x46, 0xE1, 0xE7, 0x78, 0x36, 0x17, 0x00, -+0x04, 0xB4, 0x15, 0x00, 0x58, 0x40, 0x34, 0x40, 0x10, 0xB5, 0x19, 0x46, 0x40, 0xF2, 0x0A, 0x40, 0x0C, 0x23, 0xFE, 0xF7, -+0x0B, 0xF8, 0x00, 0x24, 0xC0, 0xE9, 0x00, 0x44, 0x84, 0x60, 0xFE, 0xF7, 0x35, 0xF8, 0x20, 0x46, 0x10, 0xBD, 0x00, 0xBF, -+0x30, 0xB5, 0x18, 0x46, 0x83, 0xB0, 0x08, 0x23, 0x0C, 0x46, 0x01, 0x46, 0x40, 0xF2, 0x03, 0x40, 0xFD, 0xF7, 0xF8, 0xFF, -+0x10, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x3B, 0x01, 0x2B, 0x05, 0x46, 0x13, 0xD9, 0xD4, 0xE9, 0x00, 0x32, 0x1A, 0x60, -+0x23, 0x68, 0x03, 0x60, 0x19, 0x68, 0x62, 0x68, 0x41, 0x60, 0xCD, 0xE9, 0x00, 0x11, 0x09, 0x48, 0x11, 0x46, 0xFF, 0xF7, -+0x4B, 0xFE, 0x28, 0x46, 0xFE, 0xF7, 0x10, 0xF8, 0x00, 0x20, 0x03, 0xB0, 0x30, 0xBD, 0xD4, 0xE9, 0x00, 0x32, 0xC0, 0xE9, -+0x00, 0x32, 0x11, 0x46, 0xED, 0xE7, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, 0x58, 0xB4, 0x15, 0x00, 0x38, 0xB5, 0x0D, 0x46, -+0x40, 0xF2, 0x01, 0x40, 0x19, 0x46, 0x08, 0x23, 0xFD, 0xF7, 0xCA, 0xFF, 0x29, 0x68, 0x0B, 0x68, 0x04, 0x46, 0xC4, 0xE9, -+0x00, 0x13, 0x1A, 0x46, 0x03, 0x48, 0xFF, 0xF7, 0x29, 0xFE, 0x20, 0x46, 0xFD, 0xF7, 0xEE, 0xFF, 0x00, 0x20, 0x38, 0xBD, -+0x98, 0xB4, 0x15, 0x00, 0x38, 0xB5, 0x0C, 0x46, 0x40, 0xF2, 0x0E, 0x40, 0x19, 0x46, 0x04, 0x23, 0xFD, 0xF7, 0xB2, 0xFF, -+0x61, 0x68, 0x02, 0x29, 0x05, 0x46, 0x20, 0xD9, 0x03, 0x29, 0x11, 0xD0, 0x13, 0x48, 0xFF, 0xF7, 0x11, 0xFE, 0x4F, 0xF4, -+0xD2, 0x73, 0x0F, 0x20, 0x1B, 0x68, 0x98, 0x47, 0xC0, 0xB2, 0x28, 0x60, 0x0F, 0x48, 0xFF, 0xF7, 0x07, 0xFE, 0x28, 0x46, -+0xFD, 0xF7, 0xCC, 0xFF, 0x00, 0x20, 0x38, 0xBD, 0x24, 0x68, 0x0C, 0x48, 0x21, 0x46, 0xFF, 0xF7, 0xFD, 0xFD, 0x5C, 0xB1, -+0xA2, 0x02, 0x01, 0x21, 0x40, 0xF2, 0x1E, 0x40, 0xFD, 0xF7, 0xEC, 0xFD, 0xE3, 0xE7, 0x22, 0x68, 0x06, 0x48, 0xFF, 0xF7, -+0xF1, 0xFD, 0xDE, 0xE7, 0xE0, 0xF7, 0x70, 0xFA, 0xFE, 0xE7, 0x00, 0xBF, 0xF4, 0xB4, 0x15, 0x00, 0x08, 0xB5, 0x15, 0x00, -+0xE8, 0xB4, 0x15, 0x00, 0xC8, 0xB4, 0x15, 0x00, 0x30, 0xB5, 0x40, 0xF2, 0x0C, 0x40, 0x83, 0xB0, 0x0C, 0x46, 0x19, 0x46, -+0x04, 0x23, 0xFD, 0xF7, 0x73, 0xFF, 0x05, 0x46, 0x20, 0x68, 0x00, 0x23, 0x82, 0x07, 0x62, 0x68, 0x2B, 0x60, 0x1C, 0xBF, -+0xFF, 0x23, 0x2B, 0x60, 0x93, 0x07, 0x1C, 0xBF, 0x01, 0x23, 0x2B, 0x60, 0x04, 0xF1, 0x08, 0x01, 0x12, 0xF0, 0xEA, 0xFA, -+0xD4, 0xE9, 0x00, 0x12, 0x28, 0x68, 0xA3, 0x68, 0x00, 0x90, 0x0A, 0x44, 0x04, 0x48, 0xFF, 0xF7, 0xC1, 0xFD, 0x28, 0x46, -+0xFD, 0xF7, 0x86, 0xFF, 0x00, 0x20, 0x03, 0xB0, 0x30, 0xBD, 0x00, 0xBF, 0x1C, 0xB5, 0x15, 0x00, 0x70, 0xB5, 0x06, 0x46, -+0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x11, 0x4B, 0x01, 0x20, 0x18, 0x60, 0x10, 0x4C, 0x11, 0x48, -+0x25, 0x68, 0x22, 0xF0, 0x7F, 0x43, 0x01, 0x35, 0x0A, 0x46, 0x31, 0x46, 0x25, 0x60, 0xFF, 0xF7, 0xA3, 0xFD, 0x0D, 0x4B, -+0x1B, 0x68, 0x00, 0x2B, 0x05, 0xDB, 0xFC, 0xF7, 0x41, 0xFF, 0x4F, 0xF0, 0x00, 0x40, 0xFE, 0xF7, 0x1D, 0xFB, 0x23, 0x68, -+0x33, 0xB1, 0x04, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x70, 0xBD, 0x00, 0xBF, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x78, 0xB5, 0x15, 0x00, 0x80, 0xB6, 0x17, 0x00, 0x70, 0xB5, 0x04, 0x46, -+0x72, 0xB6, 0x07, 0x4D, 0x07, 0x48, 0x00, 0x26, 0x22, 0xF0, 0x7F, 0x43, 0x2E, 0x60, 0x0A, 0x46, 0x21, 0x46, 0xFF, 0xF7, -+0x79, 0xFD, 0x04, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0xFD, 0xD1, 0x70, 0xBD, 0x38, 0x00, 0x32, 0x40, 0x78, 0xB5, 0x15, 0x00, -+0xD0, 0x22, 0x17, 0x00, 0x10, 0xB4, 0x0C, 0x46, 0x22, 0xF0, 0x7F, 0x43, 0x01, 0x46, 0x22, 0x46, 0x02, 0x48, 0x5D, 0xF8, -+0x04, 0x4B, 0xFF, 0xF7, 0x63, 0xBD, 0x00, 0xBF, 0x90, 0xB5, 0x15, 0x00, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, -+0x72, 0xB6, 0x07, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x06, 0x4B, 0x1A, 0x68, 0x51, 0x1C, 0x19, 0x60, 0x29, 0xB1, 0x03, 0x49, -+0x1A, 0x60, 0x0B, 0x68, 0x0A, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x70, 0x47, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, -+0x10, 0xB5, 0x06, 0x4C, 0x4F, 0xF4, 0x84, 0x72, 0x20, 0x46, 0x00, 0x21, 0xDB, 0xF7, 0xD2, 0xFA, 0x4F, 0xF0, 0xFF, 0x32, -+0x02, 0x23, 0xC4, 0xE9, 0x40, 0x23, 0x10, 0xBD, 0xB0, 0xB6, 0x17, 0x00, 0x08, 0xB5, 0x08, 0x22, 0x00, 0x21, 0x02, 0x48, -+0xDB, 0xF7, 0xC4, 0xFA, 0x00, 0x20, 0x08, 0xBD, 0xB8, 0xB7, 0x17, 0x00, 0xE0, 0xF7, 0xB4, 0xBC, 0x01, 0x4B, 0xD3, 0xF8, -+0x24, 0x31, 0x18, 0x47, 0x88, 0x1A, 0x17, 0x00, 0x02, 0x20, 0x70, 0x47, 0xE0, 0xF7, 0xCC, 0xBB, 0x04, 0x4B, 0x1B, 0x68, -+0x1B, 0x78, 0x03, 0x2B, 0x01, 0xD0, 0x01, 0x20, 0x70, 0x47, 0xE0, 0xF7, 0x5F, 0xBB, 0x00, 0xBF, 0x78, 0x36, 0x17, 0x00, -+0xE0, 0xF7, 0x6E, 0xBB, 0x70, 0xB5, 0x04, 0x68, 0x9C, 0xB1, 0x0A, 0x4E, 0x05, 0x46, 0x03, 0xE0, 0xFE, 0xF7, 0x32, 0xFB, -+0x2C, 0x68, 0x64, 0xB1, 0x28, 0x46, 0xFE, 0xF7, 0x71, 0xFB, 0xE3, 0x68, 0x21, 0x46, 0x30, 0x46, 0x00, 0x2B, 0xF3, 0xD1, -+0xA2, 0x68, 0x2C, 0x68, 0x13, 0x81, 0x00, 0x2C, 0xF2, 0xD1, 0x70, 0xBD, 0x24, 0x65, 0x17, 0x00, 0x38, 0xB5, 0x14, 0x4B, -+0x1B, 0x68, 0x1B, 0x78, 0x03, 0x2B, 0x00, 0xD0, 0x38, 0xBD, 0x04, 0x46, 0xE0, 0xF7, 0x80, 0xFB, 0x05, 0x46, 0xB8, 0xB1, -+0x4C, 0xF2, 0xDE, 0x03, 0xA3, 0x61, 0x21, 0x46, 0x1C, 0x22, 0x12, 0xF0, 0x07, 0xFA, 0x0C, 0x4C, 0x23, 0x68, 0x00, 0x2B, -+0xFC, 0xD0, 0x0B, 0x4B, 0x18, 0x68, 0x29, 0x1F, 0x00, 0xF5, 0x07, 0x70, 0xFE, 0xF7, 0x02, 0xFB, 0x01, 0x23, 0x23, 0x60, -+0xBD, 0xE8, 0x38, 0x40, 0xE0, 0xF7, 0x90, 0xBB, 0xBD, 0xE8, 0x38, 0x40, 0x04, 0x48, 0xFF, 0xF7, 0xD1, 0xBC, 0x00, 0xBF, -+0x78, 0x36, 0x17, 0x00, 0x58, 0x40, 0x04, 0x40, 0x00, 0x38, 0x18, 0x00, 0xA8, 0xB5, 0x15, 0x00, 0x01, 0x4B, 0xD3, 0xF8, -+0x28, 0x31, 0x18, 0x47, 0x88, 0x1A, 0x17, 0x00, 0x38, 0xB5, 0x04, 0x46, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, -+0x72, 0xB6, 0x10, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0F, 0x4D, 0x10, 0x48, 0x2B, 0x68, 0x01, 0x33, 0x2B, 0x60, 0xFE, 0xF7, -+0xD7, 0xFA, 0x05, 0x2C, 0x03, 0xD8, 0x0D, 0x4A, 0x13, 0x5D, 0x01, 0x3B, 0x13, 0x55, 0x2B, 0x68, 0x33, 0xB1, 0x07, 0x4A, -+0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x07, 0x4A, 0xD2, 0xF8, 0xF8, 0x31, 0x01, 0x3B, -+0xC2, 0xF8, 0xF8, 0x31, 0x38, 0xBD, 0x00, 0xBF, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x20, 0x58, 0x17, 0x00, -+0x74, 0x28, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x0C, 0x4C, 0xDF, 0xF8, 0x3C, 0x80, 0x0C, 0x4F, -+0x0C, 0x4E, 0x04, 0xF5, 0x7C, 0x75, 0x62, 0x69, 0x30, 0x46, 0x13, 0x46, 0x3A, 0xB1, 0x12, 0x78, 0x21, 0x69, 0x20, 0x2A, -+0x0C, 0xBF, 0x42, 0x46, 0x3A, 0x46, 0xE1, 0xF7, 0xB1, 0xFA, 0x10, 0x34, 0xAC, 0x42, 0xF0, 0xD1, 0x00, 0x20, 0xBD, 0xE8, -+0xF0, 0x81, 0x00, 0xBF, 0x24, 0x30, 0x17, 0x00, 0xC4, 0xB5, 0x15, 0x00, 0xC8, 0xB5, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xF8, 0xB5, 0x10, 0xF8, 0x01, 0x3C, 0x09, 0x2B, 0x00, 0xF1, 0xFF, 0x36, 0x30, 0xD1, 0x1C, 0x4C, 0x23, 0x68, 0x99, 0x42, -+0x0D, 0x46, 0x08, 0xDA, 0x1A, 0x4F, 0x38, 0x46, 0x00, 0xF0, 0x64, 0xFD, 0x23, 0x68, 0x01, 0x3B, 0xAB, 0x42, 0x23, 0x60, -+0xF7, 0xDC, 0x17, 0x4D, 0xAE, 0x42, 0x19, 0xD9, 0x16, 0x4F, 0x06, 0xE0, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0x00, 0xF0, -+0x53, 0xFD, 0xAE, 0x42, 0x10, 0xD0, 0x15, 0xF8, 0x01, 0x0B, 0x09, 0x28, 0xF4, 0xD1, 0x20, 0x68, 0x00, 0xF0, 0x07, 0x00, -+0x38, 0x44, 0x00, 0xF0, 0x49, 0xFD, 0x23, 0x68, 0x23, 0xF0, 0x07, 0x03, 0x08, 0x33, 0xAE, 0x42, 0x23, 0x60, 0xEE, 0xD1, -+0x0A, 0x4A, 0x13, 0x68, 0x01, 0x3B, 0x30, 0x46, 0x13, 0x60, 0xF8, 0xBD, 0x04, 0x48, 0x00, 0xF0, 0x39, 0xFD, 0x02, 0x4A, -+0x13, 0x68, 0x01, 0x3B, 0x13, 0x60, 0xF1, 0xE7, 0x24, 0x34, 0x17, 0x00, 0x1C, 0xB8, 0x15, 0x00, 0x28, 0x34, 0x17, 0x00, -+0x20, 0xB8, 0x15, 0x00, 0x68, 0x34, 0x17, 0x00, 0x61, 0xB3, 0x2D, 0xE9, 0xF8, 0x43, 0xDF, 0xF8, 0x64, 0x90, 0x16, 0x4F, -+0xDF, 0xF8, 0x58, 0x80, 0x0E, 0x46, 0x45, 0x1E, 0x00, 0x24, 0x08, 0xE0, 0x15, 0xF8, 0x01, 0x1F, 0x38, 0x46, 0xFF, 0xF7, -+0x11, 0xFC, 0x23, 0x07, 0x10, 0xD0, 0xB4, 0x42, 0x13, 0xD0, 0x14, 0xF0, 0x07, 0x0F, 0x04, 0xF1, 0x01, 0x04, 0xF1, 0xD1, -+0x48, 0x46, 0xFF, 0xF7, 0x05, 0xFC, 0x15, 0xF8, 0x01, 0x1F, 0x38, 0x46, 0xFF, 0xF7, 0x00, 0xFC, 0x23, 0x07, 0xEE, 0xD1, -+0x40, 0x46, 0xFF, 0xF7, 0xFB, 0xFB, 0xB4, 0x42, 0xEB, 0xD1, 0xBD, 0xE8, 0xF8, 0x43, 0x04, 0x48, 0xFF, 0xF7, 0xF4, 0xBB, -+0x02, 0x48, 0xFF, 0xF7, 0xF1, 0xBB, 0x00, 0xBF, 0xD8, 0xB5, 0x15, 0x00, 0xB4, 0x79, 0x15, 0x00, 0xD4, 0xB5, 0x15, 0x00, -+0x2D, 0xE9, 0xF0, 0x4F, 0x87, 0xB0, 0x04, 0x93, 0x00, 0x29, 0x7E, 0xD0, 0x04, 0x2A, 0x14, 0x46, 0x02, 0xD0, 0x53, 0x1E, -+0x01, 0x2B, 0x78, 0xD8, 0x65, 0x42, 0x04, 0xFB, 0x01, 0xF3, 0xDF, 0xF8, 0x8C, 0x91, 0x03, 0x93, 0x05, 0x40, 0x5C, 0x48, -+0x29, 0x46, 0xE1, 0xF7, 0x09, 0xFA, 0x03, 0x9A, 0x2B, 0x0E, 0x10, 0x2A, 0x17, 0x46, 0x28, 0xBF, 0x10, 0x27, 0x01, 0x2B, -+0x68, 0xD0, 0x2B, 0x0D, 0xB3, 0xF5, 0xA0, 0x6F, 0x64, 0xD0, 0x00, 0x2A, 0x00, 0xF0, 0x9C, 0x80, 0xDF, 0xF8, 0x60, 0x81, -+0xDF, 0xF8, 0x60, 0xA1, 0x2E, 0x46, 0x4F, 0xF0, 0x00, 0x0B, 0x0A, 0xE0, 0x02, 0x2C, 0x0A, 0xBF, 0x31, 0x88, 0x31, 0x78, -+0x50, 0x46, 0xA3, 0x44, 0xE1, 0xF7, 0xEA, 0xF9, 0x5F, 0x45, 0x26, 0x44, 0x0A, 0xD9, 0x04, 0x2C, 0x40, 0x46, 0xF1, 0xD1, -+0x31, 0x68, 0x48, 0x48, 0xA3, 0x44, 0xE1, 0xF7, 0xDF, 0xF9, 0x5F, 0x45, 0x26, 0x44, 0xF4, 0xD8, 0x04, 0x9B, 0xB3, 0xB3, -+0x03, 0x9B, 0x0F, 0x2B, 0x7D, 0xD8, 0x4F, 0xF0, 0x00, 0x08, 0xC7, 0xF1, 0x10, 0x03, 0x04, 0xF1, 0xFF, 0x3A, 0x05, 0x94, -+0xDF, 0xF8, 0x14, 0xB1, 0x44, 0x46, 0x98, 0x46, 0x04, 0xE0, 0x58, 0x46, 0x00, 0xF0, 0x9A, 0xFC, 0xA0, 0x45, 0x0C, 0xD0, -+0x1A, 0xEA, 0x04, 0x0F, 0x04, 0xF1, 0x01, 0x04, 0xF5, 0xD1, 0x20, 0x20, 0x00, 0xF0, 0x8E, 0xFC, 0x58, 0x46, 0x00, 0xF0, -+0x8D, 0xFC, 0xA0, 0x45, 0xF2, 0xD1, 0x34, 0x48, 0x05, 0x9C, 0x00, 0xF0, 0x87, 0xFC, 0x03, 0x9B, 0x00, 0x2B, 0x4D, 0xD0, -+0x4F, 0xF0, 0x00, 0x08, 0x15, 0xF8, 0x08, 0x00, 0xA0, 0xF1, 0x1F, 0x03, 0x5F, 0x2B, 0x88, 0xBF, 0x2E, 0x20, 0x08, 0xF1, -+0x01, 0x08, 0x00, 0xF0, 0x75, 0xFC, 0x47, 0x45, 0xF2, 0xD8, 0x35, 0x46, 0x29, 0x48, 0x00, 0xF0, 0x71, 0xFC, 0x03, 0x9B, -+0xDB, 0x1B, 0x03, 0x93, 0x8D, 0xD1, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x03, 0x9B, 0x8B, 0xB3, 0xDF, 0xF8, 0x84, 0xA0, -+0x4F, 0xF0, 0x00, 0x08, 0x09, 0xE0, 0xCD, 0xF8, 0x00, 0xC0, 0xE1, 0xF7, 0x8D, 0xF9, 0x08, 0xF1, 0x04, 0x08, 0x47, 0x45, -+0x05, 0xF1, 0x04, 0x05, 0x1A, 0xD9, 0x28, 0x46, 0xDD, 0xF7, 0xEE, 0xF9, 0x04, 0x2C, 0x06, 0x46, 0x4F, 0xEA, 0x10, 0x6C, -+0xC0, 0xF3, 0x07, 0x43, 0xC0, 0xF3, 0x07, 0x22, 0xC1, 0xB2, 0x48, 0x46, 0x0F, 0xD0, 0x02, 0x2C, 0xE5, 0xD1, 0x15, 0x48, -+0x32, 0x0C, 0xB1, 0xB2, 0x08, 0xF1, 0x04, 0x08, 0xE1, 0xF7, 0x70, 0xF9, 0x47, 0x45, 0x05, 0xF1, 0x04, 0x05, 0xE4, 0xD8, -+0x00, 0x23, 0x04, 0x93, 0xC6, 0xE7, 0x31, 0x46, 0x50, 0x46, 0xE1, 0xF7, 0x65, 0xF9, 0xD6, 0xE7, 0x0A, 0x48, 0x07, 0xB0, -+0xBD, 0xE8, 0xF0, 0x4F, 0x00, 0xF0, 0x30, 0xBC, 0x04, 0x9B, 0x00, 0x2B, 0xB8, 0xD0, 0x2E, 0x46, 0x81, 0xE7, 0x04, 0x48, -+0x00, 0xF0, 0x28, 0xFC, 0xA2, 0xE7, 0x00, 0xBF, 0xE0, 0xB5, 0x15, 0x00, 0xB8, 0x89, 0x15, 0x00, 0x1C, 0xB6, 0x15, 0x00, -+0xD0, 0x79, 0x15, 0x00, 0xE8, 0xB5, 0x15, 0x00, 0xF4, 0xB5, 0x15, 0x00, 0x14, 0xB6, 0x15, 0x00, 0x0C, 0xB6, 0x15, 0x00, -+0xD4, 0xB5, 0x15, 0x00, 0x10, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x22, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x22, 0x4C, 0x22, 0x48, 0x23, 0x68, 0x01, 0x33, 0x23, 0x60, 0xFE, 0xF7, 0x1E, 0xF9, 0x20, 0x48, 0xFE, 0xF7, -+0x1B, 0xF9, 0x20, 0x49, 0x1D, 0x48, 0xFE, 0xF7, 0x1B, 0xF9, 0x1F, 0x49, 0x1B, 0x48, 0xFE, 0xF7, 0x17, 0xF9, 0x1E, 0x49, -+0x19, 0x48, 0xFE, 0xF7, 0x13, 0xF9, 0x1D, 0x49, 0x17, 0x48, 0xFE, 0xF7, 0x0F, 0xF9, 0x23, 0x68, 0x33, 0xB1, 0x13, 0x4A, -+0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x17, 0x4B, 0x18, 0x49, 0x18, 0x48, 0x01, 0x22, -+0x00, 0xF0, 0xFC, 0xFB, 0x17, 0x4B, 0x18, 0x49, 0x18, 0x48, 0x04, 0x22, 0x00, 0xF0, 0xF6, 0xFB, 0x17, 0x4B, 0x18, 0x49, -+0x18, 0x48, 0x03, 0x22, 0x00, 0xF0, 0xF0, 0xFB, 0x17, 0x4B, 0x18, 0x49, 0x18, 0x48, 0x04, 0x22, 0x00, 0xF0, 0xEA, 0xFB, -+0xBD, 0xE8, 0x10, 0x40, 0x16, 0x4B, 0x17, 0x49, 0x17, 0x48, 0x02, 0x22, 0x00, 0xF0, 0xE2, 0xBB, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0xD8, 0xB8, 0x17, 0x00, 0xC0, 0xB7, 0x17, 0x00, 0xC8, 0xB7, 0x17, 0x00, 0x0C, 0xB8, 0x17, 0x00, -+0x50, 0xB8, 0x17, 0x00, 0x94, 0xB8, 0x17, 0x00, 0x69, 0x4D, 0x14, 0x00, 0x24, 0xB6, 0x15, 0x00, 0x30, 0xB6, 0x15, 0x00, -+0x61, 0x56, 0x14, 0x00, 0x38, 0xB6, 0x15, 0x00, 0x7C, 0xAB, 0x15, 0x00, 0x2D, 0x57, 0x14, 0x00, 0x4C, 0xB6, 0x15, 0x00, -+0x58, 0xB6, 0x15, 0x00, 0xED, 0x55, 0x14, 0x00, 0x5C, 0xB6, 0x15, 0x00, 0x68, 0xB6, 0x15, 0x00, 0x99, 0x57, 0x14, 0x00, -+0x6C, 0xB6, 0x15, 0x00, 0x7C, 0xB6, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x54, 0x4D, 0x55, 0x4E, 0x29, 0x68, 0x31, 0x60, -+0x17, 0x28, 0x04, 0x46, 0x10, 0xD8, 0x17, 0x28, 0x00, 0xF2, 0x8E, 0x80, 0xDF, 0xE8, 0x00, 0xF0, 0x15, 0x8C, 0x8C, 0x71, -+0x8C, 0x8C, 0x8C, 0x8C, 0x48, 0x8C, 0x1A, 0x8C, 0x8C, 0x1A, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x55, 0x8C, 0x60, -+0x7F, 0x28, 0x39, 0xD0, 0x49, 0x4F, 0x3B, 0x68, 0x3D, 0x2B, 0x65, 0xDD, 0x07, 0x20, 0x00, 0xF0, 0x75, 0xFB, 0x4F, 0xF0, -+0xFF, 0x34, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x44, 0x4E, 0x45, 0x48, 0x33, 0x68, 0xDF, 0xF8, 0x20, 0x81, 0x00, 0x22, -+0x1A, 0x70, 0x00, 0xF0, 0x69, 0xFB, 0x34, 0x68, 0xA4, 0xEB, 0x08, 0x04, 0x00, 0x2C, 0xEE, 0xDB, 0x0F, 0xD1, 0x3F, 0x48, -+0x00, 0xF0, 0x60, 0xFB, 0x00, 0x24, 0x3D, 0x48, 0x12, 0xF0, 0x70, 0xF9, 0x38, 0x4B, 0x28, 0x60, 0x00, 0x22, 0xC6, 0xF8, -+0x00, 0x80, 0x1A, 0x60, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x38, 0x48, 0xFE, 0xF7, 0xB2, 0xF8, 0x07, 0x46, 0x00, 0x28, -+0x48, 0xD0, 0x41, 0x46, 0x04, 0x30, 0x12, 0xF0, 0xED, 0xF8, 0x34, 0x48, 0x39, 0x46, 0xFE, 0xF7, 0x63, 0xF8, 0xE4, 0xE7, -+0x2C, 0x4B, 0x2D, 0x4E, 0x1B, 0x68, 0x30, 0x68, 0x0B, 0xB1, 0xFF, 0xF7, 0xC9, 0xFD, 0x4F, 0xF0, 0xFF, 0x34, 0x30, 0x60, -+0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x27, 0x4A, 0x25, 0x4B, 0x2B, 0x49, 0x11, 0x60, 0x4F, 0xF0, 0xFF, 0x34, 0x00, 0x22, -+0x1A, 0x60, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x20, 0x4F, 0x21, 0x4E, 0x3B, 0x68, 0x30, 0x68, 0x0B, 0xB9, 0xAE, 0xE7, -+0x29, 0x68, 0xFF, 0xF7, 0xAF, 0xFD, 0x3B, 0x68, 0x30, 0x60, 0x00, 0x2B, 0xA7, 0xDD, 0x03, 0x78, 0x20, 0x2B, 0xF5, 0xD1, -+0xA3, 0xE7, 0xDF, 0xF8, 0x78, 0x80, 0x18, 0x4E, 0x00, 0x23, 0x88, 0xF8, 0x00, 0x30, 0xB0, 0xE7, 0x01, 0x31, 0x20, 0x46, -+0x31, 0x60, 0x00, 0xF0, 0x0D, 0xFB, 0x13, 0x49, 0x0B, 0x68, 0x1C, 0x70, 0x3A, 0x68, 0x01, 0x33, 0x01, 0x32, 0x0B, 0x60, -+0x3A, 0x60, 0x4F, 0xF0, 0xFF, 0x34, 0x8E, 0xE7, 0x13, 0x48, 0x00, 0xF0, 0x01, 0xFB, 0xA0, 0xE7, 0x0A, 0x4F, 0x3B, 0x68, -+0x3D, 0x2B, 0x81, 0xDC, 0x09, 0x28, 0xE5, 0xD1, 0x0F, 0x48, 0x01, 0xF0, 0x07, 0x01, 0x08, 0x44, 0x00, 0xF0, 0xF4, 0xFA, -+0x33, 0x68, 0x23, 0xF0, 0x07, 0x03, 0x08, 0x33, 0x33, 0x60, 0xDE, 0xE7, 0x6C, 0x34, 0x17, 0x00, 0x24, 0x34, 0x17, 0x00, -+0x68, 0x34, 0x17, 0x00, 0xD4, 0x22, 0x17, 0x00, 0xD0, 0x79, 0x15, 0x00, 0xA0, 0xB6, 0x15, 0x00, 0xD8, 0xB8, 0x17, 0x00, -+0xC0, 0xB7, 0x17, 0x00, 0x28, 0x34, 0x17, 0x00, 0x84, 0xB6, 0x15, 0x00, 0x20, 0xB8, 0x15, 0x00, 0xF8, 0xB5, 0x0C, 0x4D, -+0x2C, 0x68, 0x3F, 0x2C, 0x0D, 0xD8, 0x0B, 0x4F, 0x4F, 0xEA, 0x04, 0x1C, 0x07, 0xEB, 0x04, 0x16, 0x01, 0x34, 0x47, 0xF8, -+0x0C, 0x00, 0xC6, 0xE9, 0x01, 0x12, 0xF3, 0x60, 0x2C, 0x60, 0x00, 0x20, 0xF8, 0xBD, 0x05, 0x48, 0xE0, 0xF7, 0xF0, 0xFF, -+0x4F, 0xF0, 0xFF, 0x30, 0xF8, 0xBD, 0x00, 0xBF, 0x20, 0x30, 0x17, 0x00, 0x24, 0x30, 0x17, 0x00, 0xA8, 0xB6, 0x15, 0x00, -+0x2D, 0xE9, 0xF0, 0x4F, 0x95, 0xB0, 0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x76, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0xDF, 0xF8, 0xFC, 0xB1, 0x75, 0x48, 0xDB, 0xF8, 0x00, 0x30, 0x01, 0x33, 0xCB, 0xF8, 0x00, 0x30, 0xFE, 0xF7, -+0x05, 0xF8, 0xDB, 0xF8, 0x00, 0x30, 0x06, 0x46, 0x3B, 0xB1, 0x6E, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0xCB, 0xF8, 0x00, 0x30, -+0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x00, 0x2E, 0x00, 0xF0, 0x94, 0x80, 0x33, 0x1D, 0x03, 0xAC, 0x01, 0x22, 0x4F, 0xF0, -+0x00, 0x0C, 0x57, 0x1E, 0x3D, 0x46, 0x19, 0x46, 0x13, 0xF8, 0x01, 0x0B, 0x20, 0x28, 0xFA, 0xD0, 0x09, 0x28, 0xF8, 0xD0, -+0x00, 0x28, 0x00, 0xF0, 0xA0, 0x80, 0x22, 0x28, 0x00, 0xF0, 0x83, 0x80, 0x21, 0x60, 0x08, 0x78, 0x15, 0x46, 0x00, 0x28, -+0x00, 0xF0, 0xAC, 0x80, 0x0B, 0x46, 0x06, 0xE0, 0x09, 0x28, 0x06, 0xD0, 0x13, 0xF8, 0x01, 0x0F, 0x00, 0x28, 0x00, 0xF0, -+0xA3, 0x80, 0x20, 0x28, 0xF6, 0xD1, 0x19, 0x78, 0x00, 0x29, 0x00, 0xF0, 0x9D, 0x80, 0x01, 0x32, 0x11, 0x2A, 0x03, 0xF8, -+0x01, 0xCB, 0x04, 0xF1, 0x04, 0x04, 0xD4, 0xD1, 0x52, 0x48, 0x10, 0x21, 0xE0, 0xF7, 0x8E, 0xFF, 0x10, 0x25, 0xDD, 0xF8, -+0x0C, 0x90, 0x2E, 0x21, 0x48, 0x46, 0x11, 0xF0, 0x95, 0xFF, 0x00, 0x28, 0x00, 0xF0, 0x83, 0x80, 0xA0, 0xEB, 0x09, 0x04, -+0x4B, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x28, 0xDD, 0x4A, 0x4F, 0x01, 0x95, 0x4F, 0xF0, 0x00, 0x08, 0xC2, 0x46, 0x3D, 0x46, -+0x05, 0xE0, 0x46, 0x4B, 0x1A, 0x68, 0x92, 0x45, 0x07, 0xF1, 0x10, 0x07, 0x16, 0xDA, 0x39, 0x68, 0x22, 0x46, 0x48, 0x46, -+0x0A, 0xF1, 0x01, 0x0A, 0x12, 0xF0, 0xBE, 0xF8, 0x00, 0x28, 0xF0, 0xD1, 0x38, 0x68, 0x12, 0xF0, 0x4B, 0xF8, 0x84, 0x42, -+0x43, 0xD0, 0x3C, 0x4B, 0x1A, 0x68, 0x92, 0x45, 0x3D, 0x46, 0x08, 0xF1, 0x01, 0x08, 0x07, 0xF1, 0x10, 0x07, 0xE8, 0xDB, -+0xB8, 0xF1, 0x01, 0x0F, 0x2B, 0x46, 0x01, 0x9D, 0x37, 0xD0, 0x03, 0x99, 0x36, 0x48, 0xE0, 0xF7, 0x51, 0xFF, 0x36, 0x48, -+0x00, 0xF0, 0x20, 0xFA, 0x35, 0x48, 0x00, 0xF0, 0x1D, 0xFA, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x2A, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xDB, 0xF8, 0x00, 0x30, 0x30, 0x48, 0x01, 0x33, 0x31, 0x46, 0xCB, 0xF8, 0x00, 0x30, -+0xFD, 0xF7, 0x2A, 0xFF, 0x25, 0x48, 0xFD, 0xF7, 0x6B, 0xFF, 0xDB, 0xF8, 0x00, 0x30, 0x06, 0x46, 0x00, 0x2B, 0x7F, 0xF4, -+0x64, 0xAF, 0x00, 0x2E, 0x7F, 0xF4, 0x6C, 0xAF, 0x15, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x4B, 0x1C, 0x23, 0x60, 0x49, 0x78, -+0x15, 0x46, 0x19, 0xB9, 0x28, 0xE0, 0x13, 0xF8, 0x01, 0x1F, 0x29, 0xB3, 0x22, 0x29, 0xFA, 0xD1, 0x81, 0xE7, 0x01, 0x9D, -+0x3B, 0x46, 0x9A, 0x68, 0xAA, 0x42, 0x24, 0xDB, 0xDB, 0x68, 0x00, 0x2B, 0xC8, 0xD0, 0x28, 0x46, 0x03, 0xA9, 0x98, 0x47, -+0x00, 0x28, 0xC3, 0xD0, 0xBF, 0xE7, 0x14, 0xAB, 0x03, 0xEB, 0x87, 0x03, 0x43, 0xF8, 0x44, 0x0C, 0x00, 0x2F, 0xB8, 0xD0, -+0xDD, 0xF8, 0x0C, 0x90, 0x2E, 0x21, 0x48, 0x46, 0x11, 0xF0, 0x12, 0xFF, 0x00, 0x28, 0x7F, 0xF4, 0x7D, 0xAF, 0x48, 0x46, -+0x11, 0xF0, 0xE4, 0xFF, 0x04, 0x46, 0x79, 0xE7, 0x14, 0xAB, 0x03, 0xEB, 0x82, 0x02, 0x00, 0x23, 0x42, 0xF8, 0x44, 0x3C, -+0x67, 0xE7, 0x59, 0x68, 0x0A, 0x48, 0xE0, 0xF7, 0xF1, 0xFE, 0x9E, 0xE7, 0x38, 0x61, 0x17, 0x00, 0xC0, 0xB7, 0x17, 0x00, -+0xC4, 0xB6, 0x15, 0x00, 0x20, 0x30, 0x17, 0x00, 0x24, 0x30, 0x17, 0x00, 0xE4, 0xB6, 0x15, 0x00, 0x08, 0xB7, 0x15, 0x00, -+0xA0, 0xB6, 0x15, 0x00, 0xD8, 0xB8, 0x17, 0x00, 0xFC, 0xB6, 0x15, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xF0, 0xB4, 0x05, 0x78, -+0x30, 0x2D, 0x2B, 0xD0, 0x00, 0x2A, 0x08, 0xBF, 0x0A, 0x22, 0x2D, 0x2D, 0x32, 0xD0, 0x00, 0x27, 0x00, 0x26, 0xA5, 0xF1, -+0x30, 0x03, 0x5F, 0xFA, 0x83, 0xFC, 0x25, 0xF0, 0x20, 0x04, 0xBC, 0xF1, 0x09, 0x0F, 0xA4, 0xF1, 0x41, 0x04, 0x12, 0xD9, -+0x05, 0x2C, 0x06, 0xD9, 0x07, 0xB1, 0x76, 0x42, 0x01, 0xB1, 0x08, 0x60, 0x30, 0x46, 0xF0, 0xBC, 0x70, 0x47, 0xA5, 0xF1, -+0x61, 0x04, 0xA5, 0xF1, 0x20, 0x03, 0x19, 0x2C, 0xDB, 0xB2, 0x94, 0xBF, 0x37, 0x3B, 0xA5, 0xF1, 0x37, 0x03, 0x93, 0x42, -+0xEC, 0xD2, 0x10, 0xF8, 0x01, 0x5F, 0x02, 0xFB, 0x06, 0x36, 0xDA, 0xE7, 0x45, 0x78, 0x78, 0x2D, 0x00, 0xF1, 0x01, 0x03, -+0x0A, 0xD0, 0x18, 0x46, 0x00, 0x2A, 0xCE, 0xD1, 0x2D, 0x2D, 0x4F, 0xF0, 0x08, 0x02, 0xCC, 0xD1, 0x01, 0x27, 0x45, 0x78, -+0x38, 0x44, 0xC9, 0xE7, 0x84, 0x78, 0xA4, 0xF1, 0x30, 0x06, 0x09, 0x2E, 0x09, 0xD9, 0x24, 0xF0, 0x20, 0x06, 0x41, 0x3E, -+0x05, 0x2E, 0x04, 0xD9, 0x3A, 0xB9, 0x17, 0x46, 0x18, 0x46, 0x08, 0x22, 0xBA, 0xE7, 0x02, 0x30, 0x25, 0x46, 0x10, 0x22, -+0xB3, 0xE7, 0x18, 0x46, 0xB3, 0xE7, 0x00, 0xBF, 0x38, 0xB5, 0x0A, 0x22, 0x0C, 0x46, 0x05, 0x46, 0x48, 0x68, 0x00, 0x21, -+0xFF, 0xF7, 0xA2, 0xFF, 0xC0, 0xB1, 0x01, 0x28, 0x10, 0xD1, 0x02, 0x2D, 0x1C, 0xDD, 0x10, 0x22, 0xA0, 0x68, 0x00, 0x21, -+0xFF, 0xF7, 0x98, 0xFF, 0x0E, 0x4B, 0x1B, 0x68, 0x01, 0x46, 0x19, 0x80, 0x0D, 0x48, 0x89, 0xB2, 0xFF, 0xF7, 0x34, 0xF8, -+0x00, 0x20, 0x38, 0xBD, 0x01, 0x46, 0x0B, 0x48, 0xFF, 0xF7, 0x2E, 0xF8, 0x00, 0x20, 0x38, 0xBD, 0x06, 0x4B, 0x09, 0x48, -+0x1B, 0x68, 0x19, 0x88, 0xFF, 0xF7, 0x26, 0xF8, 0x00, 0x20, 0x38, 0xBD, 0x06, 0x48, 0xFF, 0xF7, 0x21, 0xF8, 0x00, 0x20, -+0x38, 0xBD, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x2C, 0xB7, 0x15, 0x00, 0x50, 0xB7, 0x15, 0x00, 0x18, 0xB7, 0x15, 0x00, -+0x40, 0xB7, 0x15, 0x00, 0x01, 0x28, 0xF8, 0xB5, 0x2A, 0xDD, 0x0D, 0x46, 0x04, 0x46, 0x10, 0x22, 0x68, 0x68, 0x00, 0x21, -+0xFF, 0xF7, 0x66, 0xFF, 0x02, 0x2C, 0x06, 0x46, 0x0D, 0xD1, 0x03, 0x0E, 0x01, 0x2B, 0x22, 0xD0, 0x03, 0x0D, 0xB3, 0xF5, -+0xA0, 0x6F, 0x1E, 0xD0, 0x32, 0x68, 0x24, 0x48, 0x31, 0x46, 0xFE, 0xF7, 0xFB, 0xFF, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0x22, -+0xA8, 0x68, 0x11, 0x46, 0x00, 0xF0, 0x18, 0xF9, 0x03, 0x2C, 0x07, 0x46, 0x19, 0xD1, 0x04, 0x20, 0x01, 0x2F, 0x1C, 0xD0, -+0xC2, 0xB2, 0x39, 0x46, 0x30, 0x46, 0x00, 0x23, 0xFF, 0xF7, 0xFE, 0xFB, 0x00, 0x20, 0xF8, 0xBD, 0x18, 0x48, 0xFE, 0xF7, -+0xE3, 0xFF, 0x01, 0x20, 0xF8, 0xBD, 0x30, 0x46, 0xDC, 0xF7, 0x7E, 0xFE, 0x31, 0x46, 0x02, 0x46, 0x12, 0x48, 0xFE, 0xF7, -+0xD9, 0xFF, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0x22, 0xE8, 0x68, 0x11, 0x46, 0xFF, 0xF7, 0x2E, 0xFF, 0xE0, 0xE7, 0x33, 0x0E, -+0x01, 0x2B, 0xEC, 0xD0, 0x33, 0x0D, 0xB3, 0xF5, 0xA0, 0x6F, 0xE8, 0xD0, 0x01, 0x28, 0x06, 0xD1, 0x32, 0x78, 0x0A, 0x48, -+0x31, 0x46, 0xFE, 0xF7, 0xC3, 0xFF, 0x00, 0x20, 0xF8, 0xBD, 0x02, 0x28, 0xBE, 0xD1, 0x32, 0x88, 0x06, 0x48, 0x92, 0xB2, -+0x31, 0x46, 0xFE, 0xF7, 0xB9, 0xFF, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0xBF, 0x7C, 0xB7, 0x15, 0x00, 0x64, 0xB7, 0x15, 0x00, -+0x90, 0xB7, 0x15, 0x00, 0xA4, 0xB7, 0x15, 0x00, 0x02, 0x28, 0x38, 0xB5, 0x21, 0xDD, 0x0D, 0x46, 0x10, 0x22, 0x68, 0x68, -+0x00, 0x21, 0xFF, 0xF7, 0x01, 0xFF, 0x10, 0x22, 0x04, 0x46, 0x00, 0x21, 0xA8, 0x68, 0xFF, 0xF7, 0xFB, 0xFE, 0x21, 0x46, -+0x02, 0x46, 0x05, 0x46, 0x0F, 0x48, 0xFE, 0xF7, 0x99, 0xFF, 0x23, 0x0E, 0x01, 0x2B, 0x06, 0xD0, 0x23, 0x0D, 0xB3, 0xF5, -+0xA0, 0x6F, 0x0D, 0xD0, 0x25, 0x60, 0x00, 0x20, 0x38, 0xBD, 0x20, 0x46, 0x29, 0x46, 0xDC, 0xF7, 0x53, 0xFE, 0x00, 0x20, -+0x38, 0xBD, 0x07, 0x48, 0xFE, 0xF7, 0x86, 0xFF, 0x01, 0x20, 0x38, 0xBD, 0xB4, 0xF1, 0xA0, 0x4F, 0xF1, 0xD1, 0x28, 0x46, -+0xDC, 0xF7, 0xF6, 0xFD, 0x00, 0x20, 0x38, 0xBD, 0x7C, 0xB7, 0x15, 0x00, 0xB8, 0xB7, 0x15, 0x00, 0x02, 0x28, 0x38, 0xB5, -+0x46, 0xDC, 0x01, 0x28, 0x32, 0xD0, 0x00, 0x22, 0x48, 0x68, 0x11, 0x46, 0xFF, 0xF7, 0xCA, 0xFE, 0x25, 0x4A, 0x26, 0x4B, -+0x02, 0xFB, 0x00, 0xF2, 0x9A, 0x42, 0x04, 0x46, 0x3E, 0xD8, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, -+0x21, 0x4B, 0x01, 0x21, 0x19, 0x60, 0x21, 0x4D, 0x21, 0x49, 0x2B, 0x68, 0x0A, 0x60, 0x01, 0x33, 0x2B, 0x60, 0x82, 0xB1, -+0x1F, 0x49, 0x09, 0x78, 0xF9, 0xB9, 0x33, 0xB1, 0x1A, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0x1B, 0x48, 0x21, 0x46, 0xFE, 0xF7, 0x49, 0xFF, 0x00, 0x20, 0x38, 0xBD, 0x01, 0x21, 0x40, 0xF2, 0x1F, 0x40, -+0xFC, 0xF7, 0xE8, 0xFF, 0x2B, 0x68, 0xEA, 0xE7, 0x12, 0x4A, 0x15, 0x4B, 0x11, 0x68, 0x15, 0x48, 0xA3, 0xFB, 0x01, 0x31, -+0x89, 0x0C, 0xFE, 0xF7, 0x37, 0xFF, 0x00, 0x20, 0x38, 0xBD, 0x01, 0x21, 0x40, 0xF2, 0x1F, 0x40, 0xFC, 0xF7, 0x26, 0xFF, -+0x2B, 0x68, 0xD8, 0xE7, 0x0E, 0x48, 0xFE, 0xF7, 0x2B, 0xFF, 0x4F, 0xF0, 0xFF, 0x30, 0x38, 0xBD, 0x0C, 0x48, 0xFE, 0xF7, -+0x25, 0xFF, 0x4F, 0xF0, 0xFF, 0x30, 0x38, 0xBD, 0x40, 0x42, 0x0F, 0x00, 0xFF, 0xA2, 0xE1, 0x11, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x6C, 0x60, 0x17, 0x00, 0x64, 0x28, 0x17, 0x00, 0xF8, 0xB7, 0x15, 0x00, 0x83, 0xDE, 0x1B, 0x43, -+0xE8, 0xB7, 0x15, 0x00, 0xD0, 0xB7, 0x15, 0x00, 0x08, 0xB8, 0x15, 0x00, 0x10, 0xB5, 0x07, 0x4C, 0x01, 0xE0, 0x04, 0x2A, -+0x05, 0xD0, 0x23, 0x68, 0x03, 0xF0, 0x0F, 0x02, 0xDB, 0x07, 0xF8, 0xD5, 0x10, 0xBD, 0xE0, 0xF7, 0x1D, 0xFC, 0xFF, 0xF7, -+0x6B, 0xFC, 0xF4, 0xE7, 0x08, 0x10, 0x04, 0x40, 0xE0, 0xF7, 0x0A, 0xBC, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x78, 0x28, 0xB1, -+0xE0, 0xF7, 0x04, 0xFC, 0x14, 0xF8, 0x01, 0x0F, 0x00, 0x28, 0xF9, 0xD1, 0x10, 0xBD, 0x00, 0xBF, 0x10, 0xB5, 0x04, 0x4C, -+0xD4, 0xF8, 0xB8, 0x30, 0x98, 0x47, 0xD4, 0xF8, 0x28, 0x33, 0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0x88, 0x1A, 0x17, 0x00, -+0xFF, 0xF7, 0x2E, 0xBD, 0xFF, 0xF7, 0x0C, 0xBD, 0xFF, 0xF7, 0x36, 0xBE, 0x70, 0xB4, 0x02, 0x68, 0x1C, 0x4C, 0x2D, 0x21, -+0xA3, 0x89, 0x11, 0x70, 0x02, 0x68, 0x1A, 0x21, 0x51, 0x70, 0x23, 0xF0, 0x1C, 0x03, 0x02, 0x68, 0x9B, 0xB2, 0x43, 0xF0, -+0x0C, 0x03, 0x53, 0x80, 0xA3, 0x7B, 0x13, 0x71, 0x06, 0x68, 0x04, 0xF1, 0x0F, 0x03, 0x04, 0xF1, 0x1F, 0x05, 0x13, 0xF8, -+0x01, 0x1B, 0x1A, 0x1B, 0x32, 0x44, 0xAB, 0x42, 0x02, 0xF8, 0x0B, 0x1C, 0xF7, 0xD1, 0x01, 0x68, 0x0E, 0x4A, 0x00, 0x23, -+0xCB, 0x73, 0x01, 0x68, 0x0B, 0x74, 0x05, 0x68, 0x23, 0x8C, 0xA5, 0xF8, 0x15, 0x30, 0x05, 0xF1, 0x17, 0x03, 0x1B, 0x35, -+0x12, 0xF8, 0x01, 0x1B, 0x03, 0xF8, 0x01, 0x1B, 0xAB, 0x42, 0xF9, 0xD1, 0x03, 0x68, 0x94, 0xF8, 0x28, 0x20, 0xDA, 0x76, -+0x03, 0x68, 0x1C, 0x33, 0x03, 0x60, 0x70, 0xBC, 0x1C, 0x20, 0x70, 0x47, 0xE4, 0xB8, 0x17, 0x00, 0x08, 0xB9, 0x17, 0x00, -+0x03, 0x68, 0x28, 0x4A, 0xFF, 0x21, 0x70, 0xB4, 0x19, 0x70, 0x03, 0x68, 0x23, 0x21, 0x99, 0x70, 0x05, 0x68, 0xEB, 0x1C, -+0x05, 0xF1, 0x09, 0x04, 0x12, 0xF8, 0x01, 0x1F, 0x03, 0xF8, 0x01, 0x1B, 0xA3, 0x42, 0xF9, 0xD1, 0x20, 0x4A, 0xA2, 0xF1, -+0x41, 0x01, 0x02, 0xF1, 0x0B, 0x06, 0xA2, 0xF1, 0x38, 0x03, 0x12, 0xF8, 0x01, 0x4F, 0x5B, 0x1A, 0xB2, 0x42, 0x5C, 0x55, -+0xF7, 0xD1, 0x91, 0xF8, 0x42, 0x30, 0xB1, 0xF8, 0x50, 0x40, 0xB1, 0xF8, 0x4E, 0x20, 0xEC, 0x82, 0x1C, 0x07, 0xAA, 0x82, -+0x05, 0xF1, 0x18, 0x06, 0x4F, 0xEA, 0x63, 0x02, 0x07, 0xD5, 0xB1, 0xF8, 0x52, 0x40, 0xB1, 0xF8, 0x54, 0x30, 0x6B, 0x83, -+0x2C, 0x83, 0x05, 0xF1, 0x1C, 0x06, 0x13, 0x07, 0x04, 0xD5, 0xB1, 0xF8, 0x56, 0x30, 0x33, 0x80, 0x73, 0x80, 0x04, 0x36, -+0x0C, 0x4C, 0x32, 0x46, 0x14, 0xF8, 0x01, 0x5F, 0x15, 0x70, 0x91, 0xF8, 0x75, 0x51, 0x93, 0x1B, 0x9D, 0x42, 0x02, 0xF1, -+0x01, 0x02, 0xF5, 0xDA, 0x03, 0x68, 0xD2, 0x1A, 0x91, 0x1E, 0x59, 0x70, 0x03, 0x68, 0x13, 0x44, 0x03, 0x60, 0x70, 0xBC, -+0x10, 0x46, 0x70, 0x47, 0x1F, 0xB9, 0x17, 0x00, 0x25, 0xB9, 0x17, 0x00, 0x3D, 0xB9, 0x17, 0x00, 0x70, 0xB4, 0x0F, 0x4C, -+0x03, 0x46, 0x22, 0x6B, 0x09, 0xB1, 0x22, 0xF4, 0xC0, 0x52, 0x19, 0x68, 0xBF, 0x20, 0x08, 0x70, 0x19, 0x68, 0x0C, 0x20, -+0x48, 0x70, 0x18, 0x68, 0xA1, 0x8E, 0xC0, 0xF8, 0x02, 0x20, 0x1A, 0x68, 0x60, 0x8F, 0xE6, 0x8E, 0x25, 0x8F, 0xD1, 0x80, -+0x02, 0xF1, 0x0E, 0x01, 0x16, 0x81, 0x55, 0x81, 0x90, 0x81, 0x70, 0xBC, 0x0E, 0x20, 0x19, 0x60, 0x70, 0x47, 0x00, 0xBF, -+0xE4, 0xB8, 0x17, 0x00, 0x03, 0x68, 0x10, 0xB4, 0xC7, 0x24, 0x1C, 0x70, 0x03, 0x68, 0x01, 0x24, 0x5C, 0x70, 0x03, 0x68, -+0x42, 0xEA, 0x01, 0x11, 0x99, 0x70, 0x03, 0x68, 0x5D, 0xF8, 0x04, 0x4B, 0x03, 0x33, 0x03, 0x60, 0x03, 0x20, 0x70, 0x47, -+0x03, 0x68, 0x46, 0x22, 0x1A, 0x70, 0x03, 0x68, 0x05, 0x22, 0x5A, 0x70, 0x03, 0x68, 0x70, 0x22, 0x9A, 0x70, 0x02, 0x68, -+0x00, 0x23, 0xD3, 0x70, 0x02, 0x68, 0x13, 0x71, 0x02, 0x68, 0x53, 0x71, 0x02, 0x68, 0x93, 0x71, 0x03, 0x68, 0x07, 0x33, -+0x03, 0x60, 0x07, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x30, 0xB4, 0x02, 0x9C, 0x01, 0x80, 0x42, 0x80, 0x83, 0x80, 0x84, 0xB1, -+0x10, 0x22, 0x80, 0x23, 0x82, 0x71, 0xC3, 0x71, 0xE5, 0x18, 0x22, 0x46, 0x13, 0x46, 0x08, 0x33, 0x12, 0xF8, 0x01, 0x1B, -+0x1B, 0x1B, 0xAA, 0x42, 0x19, 0x54, 0xF7, 0xD1, 0x88, 0x20, 0x30, 0xBC, 0x70, 0x47, 0x06, 0x20, 0x30, 0xBC, 0x70, 0x47, -+0x01, 0x80, 0x02, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x4F, 0x8F, 0xB0, 0x1F, 0x46, 0x1A, 0x9E, 0x03, 0x93, -+0x34, 0x8F, 0xB6, 0xF8, 0x36, 0x80, 0x0D, 0x46, 0x03, 0x46, 0x01, 0x2C, 0x38, 0x46, 0x38, 0xBF, 0x01, 0x24, 0x07, 0x93, -+0x17, 0x46, 0x01, 0xF0, 0xC1, 0xFE, 0xB5, 0xF8, 0xAE, 0x90, 0x07, 0x9B, 0x09, 0xF0, 0x10, 0x09, 0x40, 0xEA, 0x09, 0x00, -+0x06, 0xF1, 0x40, 0x02, 0x5C, 0x80, 0x02, 0x92, 0x18, 0x80, 0x1F, 0xFA, 0x80, 0xF9, 0x14, 0x46, 0x00, 0x2F, 0x00, 0xF0, -+0xDE, 0x81, 0x3A, 0x88, 0x9A, 0x80, 0x7A, 0x88, 0xDA, 0x80, 0xBA, 0x88, 0x1A, 0x81, 0x0A, 0x22, 0x17, 0x46, 0x18, 0x99, -+0x98, 0x18, 0x08, 0x60, 0x00, 0x21, 0x07, 0x90, 0x95, 0xF8, 0x7E, 0x00, 0x99, 0x54, 0x07, 0x9B, 0x00, 0xF1, 0x02, 0x0E, -+0x58, 0x70, 0x00, 0x28, 0x40, 0xF0, 0xC7, 0x80, 0x07, 0x9B, 0x95, 0xF8, 0xB0, 0x10, 0x0E, 0xEB, 0x03, 0x00, 0x01, 0x22, -+0x07, 0x90, 0x0E, 0xF8, 0x03, 0x20, 0x07, 0x9B, 0x08, 0x29, 0x8C, 0x46, 0x28, 0xBF, 0x4F, 0xF0, 0x08, 0x0C, 0x83, 0xF8, -+0x01, 0xC0, 0x07, 0x9B, 0x1F, 0xFA, 0x8E, 0xFE, 0x0C, 0xF1, 0x02, 0x0A, 0x05, 0xF1, 0xB1, 0x02, 0x51, 0xB1, 0x0C, 0xF1, -+0xB1, 0x0C, 0xAC, 0x44, 0x12, 0xF8, 0x01, 0x0B, 0xD1, 0x18, 0x49, 0x1B, 0x94, 0x45, 0x01, 0xF8, 0xB0, 0x0C, 0xF7, 0xD1, -+0x95, 0xF8, 0xB0, 0x20, 0xD6, 0x44, 0x0A, 0xEB, 0x03, 0x01, 0x08, 0x2A, 0x77, 0x44, 0x07, 0x91, 0x1A, 0xD9, 0x32, 0x21, -+0x0A, 0xF8, 0x03, 0x10, 0x07, 0x9B, 0xA2, 0xF1, 0x08, 0x01, 0x59, 0x70, 0x02, 0xF1, 0xB1, 0x0C, 0x07, 0x9B, 0xA2, 0xF1, -+0x06, 0x0E, 0xAC, 0x44, 0x05, 0xF1, 0xB9, 0x02, 0x12, 0xF8, 0x01, 0x0B, 0xD1, 0x18, 0x49, 0x1B, 0x94, 0x45, 0x01, 0xF8, -+0xB8, 0x0C, 0xF7, 0xD1, 0x73, 0x44, 0x77, 0x44, 0x07, 0x93, 0xBF, 0xB2, 0x19, 0xF4, 0x80, 0x7F, 0x40, 0xF0, 0xB5, 0x80, -+0x07, 0xA8, 0xFF, 0xF7, 0x3F, 0xFF, 0x47, 0x44, 0x07, 0x9B, 0x80, 0xB2, 0xBF, 0xB2, 0xB8, 0xF1, 0x00, 0x0F, 0x0A, 0xD0, -+0x02, 0x9A, 0x42, 0x44, 0x94, 0x46, 0x14, 0xF8, 0x01, 0x1B, 0xE2, 0x18, 0x92, 0x1B, 0x64, 0x45, 0x02, 0xF8, 0x41, 0x1C, -+0xF7, 0xD1, 0xD5, 0xF8, 0xE0, 0x40, 0x07, 0x44, 0x43, 0x44, 0xE2, 0x07, 0xBF, 0xB2, 0x07, 0x93, 0x1A, 0xD5, 0xB4, 0x4A, -+0x07, 0xCA, 0x0A, 0xAE, 0x03, 0xC6, 0x00, 0x20, 0x0A, 0xA9, 0x32, 0x80, 0xAD, 0xF8, 0x36, 0x00, 0xCD, 0xF8, 0x32, 0x00, -+0x8D, 0xF8, 0x30, 0x00, 0x5B, 0x1A, 0x0C, 0xA8, 0xDD, 0x22, 0x01, 0xE0, 0x11, 0xF8, 0x01, 0x2F, 0x5A, 0x54, 0x88, 0x42, -+0xFA, 0xD1, 0x07, 0x9B, 0x09, 0x37, 0x09, 0x33, 0xBF, 0xB2, 0x07, 0x93, 0xA6, 0x07, 0x04, 0xD5, 0xA6, 0x4B, 0x93, 0xF8, -+0x76, 0x31, 0xDC, 0x07, 0x53, 0xD4, 0xA5, 0x4B, 0x9B, 0x7D, 0x01, 0x2B, 0x5A, 0xD0, 0xD5, 0xF8, 0xE0, 0x30, 0x18, 0x07, -+0x04, 0xD5, 0xA0, 0x4A, 0x92, 0xF8, 0x76, 0x21, 0x51, 0x07, 0x3C, 0xD4, 0x5A, 0x07, 0x22, 0xD5, 0x9C, 0x4D, 0x95, 0xF8, -+0x76, 0x31, 0x9B, 0x07, 0x1D, 0xD5, 0x03, 0x99, 0x9B, 0x4B, 0x9C, 0x4C, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x01, 0x33, -+0x07, 0xA8, 0x93, 0xF8, 0xC0, 0x14, 0xD4, 0xF8, 0x50, 0x21, 0x90, 0x47, 0x07, 0x44, 0x28, 0x8F, 0xD4, 0xF8, 0x4C, 0x61, -+0x01, 0xF0, 0x9A, 0xFC, 0x95, 0xF8, 0x75, 0x21, 0x04, 0x2A, 0x01, 0x46, 0x08, 0xBF, 0x03, 0x22, 0x07, 0xA8, 0xB0, 0x47, -+0xBF, 0xB2, 0x38, 0x44, 0x87, 0xB2, 0x18, 0x9B, 0x1A, 0x68, 0x07, 0x9B, 0x9B, 0x1A, 0x19, 0x9A, 0x38, 0x46, 0x13, 0x80, -+0x0F, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x7F, 0x30, 0x07, 0x9B, 0x28, 0x44, 0x05, 0xF1, 0x7F, 0x02, 0x12, 0xF8, 0x01, 0xCB, -+0xD1, 0x18, 0x49, 0x1B, 0x90, 0x42, 0x01, 0xF8, 0x7E, 0xCC, 0xF7, 0xD1, 0x2B, 0xE7, 0x82, 0x4B, 0x07, 0xA8, 0xD3, 0xF8, -+0x44, 0x31, 0x98, 0x47, 0x38, 0x44, 0xD5, 0xF8, 0xE0, 0x30, 0x87, 0xB2, 0xB8, 0xE7, 0x7D, 0x4B, 0x07, 0xA8, 0xD3, 0xF8, -+0x48, 0x31, 0x98, 0x47, 0x78, 0x4B, 0x9B, 0x7D, 0x38, 0x44, 0x01, 0x2B, 0x87, 0xB2, 0xA4, 0xD1, 0xB5, 0xF8, 0xE4, 0x30, -+0x00, 0x2B, 0xA0, 0xD0, 0x07, 0x9B, 0x36, 0x22, 0x1A, 0x70, 0x07, 0x9B, 0x03, 0x22, 0x5A, 0x70, 0x07, 0x9B, 0xB5, 0xF8, -+0xE4, 0x20, 0x5A, 0x80, 0x95, 0xF8, 0xE6, 0x20, 0x1A, 0x71, 0x07, 0x9B, 0x05, 0x37, 0x05, 0x33, 0xBF, 0xB2, 0x07, 0x93, -+0x8D, 0xE7, 0x07, 0x9B, 0x21, 0x22, 0x59, 0x1C, 0x07, 0x91, 0x1A, 0x70, 0x07, 0x9B, 0x02, 0x22, 0x59, 0x1C, 0x07, 0x91, -+0x0A, 0xA8, 0x1A, 0x70, 0x0D, 0xF1, 0x27, 0x01, 0xDB, 0xF7, 0x8E, 0xFE, 0xD5, 0xF8, 0xA4, 0x30, 0x9D, 0xF9, 0x28, 0x20, -+0x93, 0xF9, 0x04, 0x30, 0x9A, 0x42, 0xC8, 0xBF, 0x8D, 0xF8, 0x28, 0x30, 0x07, 0x9B, 0x9D, 0xF8, 0x27, 0x20, 0x59, 0x1C, -+0x07, 0x91, 0x1A, 0x70, 0x07, 0x9B, 0x9D, 0xF8, 0x28, 0x20, 0x59, 0x1C, 0x07, 0x91, 0x1A, 0x70, 0x07, 0x9B, 0x24, 0x22, -+0x59, 0x1C, 0x07, 0x91, 0x1A, 0x70, 0x07, 0x9B, 0x04, 0x93, 0x1A, 0x46, 0x02, 0xF1, 0x01, 0x0B, 0xD5, 0xF8, 0xA4, 0x30, -+0xCD, 0xF8, 0x1C, 0xB0, 0x9B, 0x78, 0x4F, 0x4A, 0x00, 0x2B, 0x52, 0xD1, 0x01, 0x23, 0x92, 0xF8, 0x72, 0xA1, 0x05, 0x93, -+0x76, 0x32, 0xBA, 0xF1, 0x00, 0x0F, 0x00, 0xF0, 0x8C, 0x80, 0x00, 0x21, 0x06, 0x95, 0x01, 0x91, 0x08, 0x46, 0x8E, 0x46, -+0xA1, 0x46, 0x0D, 0x46, 0x1A, 0x96, 0xD3, 0x78, 0x13, 0xF0, 0x02, 0x03, 0x1F, 0xD1, 0x94, 0x78, 0xB2, 0xF8, 0x00, 0xC0, -+0x00, 0x2C, 0x43, 0xD1, 0xAC, 0xF6, 0x6C, 0x14, 0x48, 0x2C, 0x3A, 0xD8, 0x40, 0xF6, 0xB4, 0x13, 0x9C, 0x45, 0x6F, 0xD0, -+0x40, 0x4C, 0xAC, 0xF6, 0x67, 0x13, 0xA4, 0xFB, 0x03, 0x43, 0x9C, 0x08, 0xC3, 0xF3, 0x87, 0x03, 0x00, 0x28, 0x45, 0xD0, -+0xA4, 0xEB, 0x0E, 0x0E, 0x05, 0x9C, 0xA6, 0x45, 0x44, 0xD1, 0x01, 0x30, 0xC0, 0xB2, 0x9E, 0x46, 0x06, 0x32, 0x01, 0x31, -+0xCB, 0xB2, 0x9A, 0x45, 0xD7, 0xD8, 0x01, 0x9B, 0x1A, 0x9E, 0x03, 0xF1, 0x02, 0x0E, 0x29, 0x46, 0x5F, 0xFA, 0x8E, 0xF3, -+0x06, 0x9D, 0x4C, 0x46, 0x9E, 0x46, 0x0B, 0xF1, 0x01, 0x02, 0x07, 0x92, 0x8B, 0xF8, 0x00, 0x10, 0x07, 0x9A, 0x51, 0x1C, -+0x07, 0x91, 0x06, 0x37, 0x10, 0x70, 0x04, 0x9A, 0x1E, 0xFA, 0x87, 0xF7, 0xBF, 0xB2, 0x13, 0x70, 0xC0, 0xE6, 0x04, 0x23, -+0x92, 0xF8, 0x73, 0xA1, 0x05, 0x93, 0xCA, 0x32, 0xAB, 0xE7, 0xD8, 0xB9, 0x86, 0x46, 0x05, 0x46, 0x01, 0x20, 0xD5, 0xE7, -+0x01, 0x2C, 0xF8, 0xD1, 0xAC, 0xF5, 0x9C, 0x5C, 0xAC, 0xF1, 0x0D, 0x04, 0xA4, 0xB2, 0xB4, 0xF5, 0x4D, 0x7F, 0xF0, 0xD8, -+0x1D, 0x4B, 0xAC, 0xF1, 0x08, 0x0C, 0xA3, 0xFB, 0x0C, 0x43, 0x9C, 0x08, 0xC3, 0xF3, 0x87, 0x03, 0x00, 0x28, 0xB9, 0xD1, -+0x9E, 0x46, 0x1D, 0x46, 0x01, 0x20, 0xBD, 0xE7, 0x0B, 0xF1, 0x01, 0x04, 0x07, 0x94, 0x8B, 0xF8, 0x00, 0x50, 0x07, 0x9C, -+0x01, 0x9E, 0x04, 0xF1, 0x01, 0x0C, 0x06, 0xF1, 0x02, 0x0E, 0xCD, 0xF8, 0x1C, 0xC0, 0x00, 0xF1, 0x02, 0x0C, 0x20, 0x70, -+0x5F, 0xFA, 0x8E, 0xF0, 0x01, 0x90, 0xDD, 0xF8, 0x1C, 0xB0, 0x9E, 0x46, 0x5F, 0xFA, 0x8C, 0xF0, 0xA4, 0xE7, 0x04, 0x22, -+0x17, 0x46, 0x26, 0xE6, 0x0E, 0x23, 0x1C, 0x46, 0x94, 0xE7, 0x02, 0x23, 0x50, 0x46, 0x51, 0x46, 0x9E, 0x46, 0xA8, 0xE7, -+0x2C, 0xB8, 0x15, 0x00, 0xE4, 0xB8, 0x17, 0x00, 0x64, 0xBA, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xCD, 0xCC, 0xCC, 0xCC, 0x03, 0x22, 0x00, 0x23, 0x30, 0xB4, 0x02, 0x70, 0x43, 0x70, 0x4B, 0x7C, 0x83, 0x70, 0x0B, 0x7C, -+0x8C, 0x7B, 0xCA, 0x7B, 0x4D, 0x89, 0xA0, 0xF8, 0x05, 0x50, 0x9B, 0x00, 0x43, 0xEA, 0x44, 0x03, 0x43, 0xEA, 0x82, 0x13, -+0xA0, 0xF8, 0x03, 0x30, 0x0B, 0x89, 0x1B, 0x01, 0xA0, 0xF8, 0x07, 0x30, 0x30, 0xBC, 0x09, 0x20, 0x70, 0x47, 0x00, 0xBF, -+0x30, 0xB4, 0x22, 0xF0, 0x01, 0x02, 0xBD, 0xF8, 0x08, 0x40, 0xA0, 0xF8, 0x05, 0x20, 0x03, 0x25, 0x01, 0x22, 0xA0, 0xF8, -+0x03, 0x40, 0x83, 0x70, 0x05, 0x70, 0x42, 0x70, 0x2C, 0xB1, 0x00, 0x23, 0xC3, 0x71, 0x03, 0x72, 0x30, 0xBC, 0x09, 0x20, -+0x70, 0x47, 0x4B, 0x89, 0xA0, 0xF8, 0x07, 0x30, 0x30, 0xBC, 0x09, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x10, 0xB4, 0x02, 0x23, -+0x03, 0x24, 0x04, 0x70, 0x43, 0x70, 0x0B, 0x7C, 0x49, 0x7B, 0x5D, 0xF8, 0x04, 0x4B, 0x82, 0x80, 0x1B, 0x03, 0x9B, 0xB2, -+0x01, 0x29, 0x08, 0xBF, 0x43, 0xF4, 0x00, 0x63, 0x43, 0x80, 0x06, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x41, -+0x82, 0xB0, 0x16, 0x46, 0x0D, 0xF1, 0x07, 0x02, 0x07, 0x46, 0x88, 0x46, 0xFD, 0xF7, 0x7A, 0xFB, 0xA8, 0xB3, 0x9D, 0xF8, -+0x07, 0x40, 0x83, 0x1C, 0x7C, 0xB1, 0x02, 0x34, 0x20, 0x44, 0x00, 0x24, 0x1D, 0x78, 0x25, 0xF0, 0x81, 0x02, 0x7E, 0x2A, -+0x03, 0xF1, 0x01, 0x03, 0x03, 0xD0, 0x32, 0x19, 0x01, 0x34, 0x55, 0x70, 0xE4, 0xB2, 0x98, 0x42, 0xF2, 0xD1, 0x0D, 0xF1, -+0x07, 0x02, 0x41, 0x46, 0x38, 0x46, 0xFD, 0xF7, 0x7F, 0xFB, 0xB0, 0xB1, 0x9D, 0xF8, 0x07, 0x30, 0x81, 0x1C, 0x93, 0xB1, -+0x02, 0x33, 0x1F, 0x18, 0x0A, 0x78, 0x22, 0xF0, 0x81, 0x00, 0x63, 0x1C, 0x7E, 0x28, 0x06, 0xEB, 0x04, 0x05, 0x01, 0xF1, -+0x01, 0x01, 0xDB, 0xB2, 0x03, 0xD0, 0x0B, 0x2B, 0x6A, 0x70, 0x1C, 0x46, 0x01, 0xD8, 0x8F, 0x42, 0xEE, 0xD1, 0x34, 0x70, -+0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x04, 0x46, 0x34, 0x70, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x10, 0xB5, 0x14, 0x46, -+0xFD, 0xF7, 0xE8, 0xFC, 0x00, 0xB1, 0x80, 0x78, 0x84, 0xF8, 0xDA, 0x00, 0x10, 0xBD, 0x00, 0xBF, 0xF0, 0xB5, 0x83, 0xB0, -+0x14, 0x46, 0x0D, 0xF1, 0x07, 0x02, 0xFD, 0xF7, 0x8B, 0xFB, 0x60, 0xB3, 0xD4, 0xF8, 0xA4, 0xE0, 0x9E, 0xF8, 0x02, 0x40, -+0x4C, 0xB3, 0x01, 0x2C, 0xBE, 0xF8, 0x00, 0x30, 0x40, 0xD0, 0x00, 0x24, 0x04, 0x25, 0x9D, 0xF8, 0x07, 0x70, 0x02, 0x37, -+0xFF, 0xB2, 0x08, 0x2F, 0x8D, 0xF8, 0x07, 0x70, 0x19, 0xD9, 0x05, 0x26, 0x06, 0xEB, 0x00, 0x0C, 0x33, 0x5C, 0x9C, 0xF8, -+0x01, 0x10, 0x69, 0xB1, 0x9C, 0x42, 0x25, 0xD0, 0x01, 0x39, 0xC9, 0xB2, 0x00, 0x22, 0x01, 0xE0, 0x9C, 0x42, 0x1F, 0xD0, -+0x2B, 0x44, 0x8A, 0x42, 0xDB, 0xB2, 0x02, 0xF1, 0x01, 0x02, 0xF7, 0xD1, 0x03, 0x36, 0xF6, 0xB2, 0xF3, 0x1C, 0x9F, 0x42, -+0xE6, 0xDC, 0x03, 0xB0, 0xF0, 0xBD, 0xBE, 0xF8, 0x00, 0x30, 0xA3, 0xF6, 0x6C, 0x12, 0x48, 0x2A, 0x12, 0xD8, 0x40, 0xF6, -+0xB4, 0x12, 0x93, 0x42, 0x20, 0xD0, 0x12, 0x4A, 0xA3, 0xF6, 0x67, 0x14, 0xA2, 0xFB, 0x04, 0x34, 0xC4, 0xF3, 0x87, 0x04, -+0x01, 0x25, 0xC8, 0xE7, 0x9C, 0xF8, 0x02, 0x30, 0x8E, 0xF8, 0x04, 0x30, 0x03, 0xB0, 0xF0, 0xBD, 0x01, 0x25, 0xC0, 0xE7, -+0xA3, 0xF5, 0x9C, 0x53, 0xA3, 0xF1, 0x0D, 0x02, 0x92, 0xB2, 0xB2, 0xF5, 0x4D, 0x7F, 0xB6, 0xD8, 0x05, 0x4C, 0x08, 0x3B, -+0xA4, 0xFB, 0x03, 0x34, 0xC4, 0xF3, 0x87, 0x04, 0x04, 0x25, 0xB0, 0xE7, 0x0E, 0x24, 0x01, 0x25, 0xAD, 0xE7, 0x00, 0xBF, -+0xCD, 0xCC, 0xCC, 0xCC, 0x10, 0xB5, 0x14, 0x46, 0xFD, 0xF7, 0x96, 0xFC, 0x48, 0xB1, 0x83, 0x78, 0xC2, 0x78, 0x43, 0xEA, -+0x02, 0x23, 0xA4, 0xF8, 0xE4, 0x30, 0x03, 0x79, 0x84, 0xF8, 0xE6, 0x30, 0x10, 0xBD, 0x84, 0xF8, 0xE6, 0x00, 0xA4, 0xF8, -+0xE4, 0x00, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, 0x82, 0xB0, 0x1C, 0x46, 0x05, 0x46, 0x0E, 0x46, 0x91, 0x46, 0xFD, 0xF7, -+0x49, 0xFB, 0x31, 0x46, 0x07, 0x46, 0x28, 0x46, 0xFD, 0xF7, 0x64, 0xFB, 0x57, 0xEA, 0x00, 0x03, 0x72, 0xD0, 0x80, 0x46, -+0x0D, 0xF1, 0x07, 0x02, 0x31, 0x46, 0x28, 0x46, 0xFD, 0xF7, 0x7A, 0xFB, 0x82, 0x46, 0x18, 0xB1, 0x9D, 0xF8, 0x07, 0x30, -+0x00, 0x2B, 0x65, 0xD0, 0x31, 0x46, 0x0D, 0xF1, 0x07, 0x02, 0x28, 0x46, 0xFD, 0xF7, 0x90, 0xFB, 0x01, 0x46, 0x00, 0x28, -+0x58, 0xD1, 0x00, 0x2F, 0x7A, 0xD0, 0xBB, 0x78, 0x38, 0x79, 0x89, 0xF8, 0x00, 0x30, 0x97, 0xF8, 0x03, 0xC0, 0x00, 0x28, -+0x08, 0xBF, 0x02, 0x20, 0xBC, 0xF1, 0x0E, 0x0F, 0x0C, 0xF1, 0xFF, 0x33, 0x8C, 0xBF, 0x01, 0x27, 0x00, 0x27, 0x4D, 0xD8, -+0x0D, 0x2B, 0x70, 0xD8, 0xBC, 0xF1, 0x0E, 0x0F, 0x00, 0xF0, 0x97, 0x80, 0x0C, 0xEB, 0x8C, 0x06, 0x06, 0xF6, 0x67, 0x16, -+0x00, 0x29, 0x4A, 0xD0, 0x8D, 0x78, 0xCA, 0x78, 0x91, 0xF8, 0x04, 0xE0, 0x05, 0xF1, 0xFF, 0x38, 0xB8, 0xF1, 0x02, 0x0F, -+0x9A, 0xBF, 0x01, 0x35, 0xED, 0xB2, 0x01, 0x25, 0xBC, 0xF1, 0x0E, 0x0F, 0x93, 0xB2, 0x1F, 0xFA, 0x8E, 0xF1, 0x57, 0xD8, -+0x02, 0xF1, 0xFF, 0x3C, 0xBC, 0xF1, 0x0D, 0x0F, 0x72, 0xD8, 0x0E, 0x2A, 0x00, 0xF0, 0x90, 0x80, 0x03, 0xEB, 0x83, 0x03, -+0x03, 0xF6, 0x67, 0x13, 0x61, 0xB1, 0x0E, 0xF1, 0xFF, 0x32, 0x0D, 0x2A, 0x60, 0xD8, 0xBE, 0xF1, 0x0E, 0x0F, 0x00, 0xF0, -+0x9A, 0x80, 0x01, 0xEB, 0x81, 0x01, 0x01, 0xF6, 0x67, 0x11, 0x89, 0xB2, 0x4B, 0x4A, 0x92, 0xF8, 0x75, 0x21, 0xAA, 0x42, -+0x24, 0xD2, 0x01, 0x2A, 0x67, 0xD0, 0x02, 0x2A, 0x5E, 0xD0, 0x00, 0x2A, 0x08, 0xBF, 0x33, 0x46, 0x15, 0x46, 0x1B, 0xE0, -+0x9D, 0xF8, 0x07, 0x30, 0x00, 0x2B, 0xA2, 0xD1, 0x00, 0x20, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0xA4, 0x2B, 0x22, 0xD8, -+0x0C, 0xEB, 0x8C, 0x06, 0x06, 0xF5, 0x9C, 0x56, 0x08, 0x36, 0x00, 0x29, 0xB4, 0xD1, 0xBA, 0xF1, 0x00, 0x0F, 0x31, 0xD0, -+0x9A, 0xF8, 0x02, 0x50, 0x01, 0x2D, 0x3A, 0xD0, 0x03, 0x2D, 0x50, 0xD0, 0x0D, 0x46, 0x33, 0x46, 0x27, 0x70, 0x65, 0x70, -+0x66, 0x80, 0xA3, 0x80, 0xE1, 0x80, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x98, 0xF8, 0x02, 0x30, 0x98, 0xF8, 0x05, 0x00, -+0x89, 0xF8, 0x00, 0x30, 0x98, 0xF8, 0x04, 0xC0, 0x81, 0xE7, 0x4F, 0xF6, 0xFF, 0x76, 0x93, 0xE7, 0x01, 0x3A, 0xA4, 0x2A, -+0x19, 0xD8, 0x03, 0xEB, 0x83, 0x03, 0x03, 0xF5, 0x9C, 0x53, 0x08, 0x33, 0x00, 0x29, 0xB7, 0xD0, 0x0E, 0xF1, 0xFF, 0x3E, -+0xBE, 0xF1, 0xA4, 0x0F, 0x0A, 0xD8, 0x01, 0xEB, 0x81, 0x01, 0x01, 0xF5, 0x9C, 0x51, 0x08, 0x31, 0x89, 0xB2, 0xAB, 0xE7, -+0x51, 0x46, 0x55, 0x46, 0x33, 0x46, 0xD1, 0xE7, 0x4F, 0xF6, 0xFF, 0x71, 0xA4, 0xE7, 0x4F, 0xF6, 0xFF, 0x73, 0xE7, 0xE7, -+0x4F, 0xF6, 0xFF, 0x73, 0x90, 0xE7, 0x06, 0xF1, 0x0A, 0x03, 0x9B, 0xB2, 0xC4, 0xE7, 0x40, 0xF6, 0xB4, 0x16, 0x69, 0xE7, -+0x9E, 0x42, 0x94, 0xBF, 0x28, 0x3B, 0x28, 0x33, 0x9B, 0xB2, 0x15, 0x46, 0xBA, 0xE7, 0x02, 0x2D, 0x0F, 0xD0, 0x03, 0xF1, -+0x28, 0x05, 0xB5, 0x42, 0x15, 0xDA, 0x3C, 0x33, 0x9B, 0xB2, 0x15, 0x46, 0xB0, 0xE7, 0xA6, 0xF1, 0x0A, 0x03, 0x9B, 0xB2, -+0x01, 0x25, 0xAB, 0xE7, 0x40, 0xF6, 0xB4, 0x13, 0x70, 0xE7, 0x9E, 0x42, 0x03, 0xD8, 0x14, 0x3B, 0x9B, 0xB2, 0x15, 0x46, -+0xA2, 0xE7, 0x14, 0x33, 0x9B, 0xB2, 0x15, 0x46, 0x9E, 0xE7, 0x9E, 0x42, 0xF9, 0xD8, 0xA3, 0xF1, 0x27, 0x05, 0xAE, 0x42, -+0xF1, 0xDA, 0x3C, 0x3B, 0x9B, 0xB2, 0x15, 0x46, 0x94, 0xE7, 0x40, 0xF6, 0xB4, 0x11, 0x67, 0xE7, 0xE4, 0xB8, 0x17, 0x00, -+0x70, 0xB5, 0x1D, 0x46, 0x14, 0x46, 0xFD, 0xF7, 0x95, 0xFB, 0x00, 0x23, 0x2B, 0x70, 0x00, 0x28, 0x48, 0xD0, 0x02, 0x7A, -+0xA1, 0x7C, 0x02, 0xF0, 0x0F, 0x03, 0x99, 0x42, 0x40, 0xD0, 0x01, 0x21, 0x29, 0x70, 0xA3, 0x74, 0x22, 0x74, 0xD0, 0xF8, -+0x0A, 0x20, 0x13, 0x0A, 0xD1, 0x08, 0x02, 0xF0, 0x0F, 0x02, 0x52, 0xEA, 0x03, 0x12, 0x04, 0xBF, 0x40, 0xF6, 0x43, 0x23, -+0x63, 0x60, 0xD0, 0xF8, 0x0E, 0x30, 0x18, 0xBF, 0x62, 0x60, 0x1D, 0x0A, 0x03, 0xF0, 0x0F, 0x02, 0x52, 0xEA, 0x05, 0x12, -+0x08, 0xBF, 0x40, 0xF6, 0x47, 0x22, 0x22, 0x60, 0xD0, 0xF8, 0x12, 0x20, 0x95, 0x08, 0x16, 0x0A, 0x02, 0xF0, 0x0F, 0x02, -+0x52, 0xEA, 0x06, 0x12, 0x08, 0xBF, 0x12, 0x4A, 0xA2, 0x60, 0xD0, 0xF8, 0x16, 0x20, 0xC3, 0xF3, 0x00, 0x13, 0x50, 0x08, -+0x05, 0xF0, 0x04, 0x05, 0x01, 0xF0, 0x02, 0x01, 0x2B, 0x43, 0x00, 0xF0, 0x08, 0x00, 0x49, 0xB2, 0x03, 0x43, 0x0B, 0x43, -+0x11, 0x0A, 0x02, 0xF0, 0x0F, 0x02, 0x52, 0xEA, 0x01, 0x12, 0x63, 0x74, 0x0A, 0xBF, 0x07, 0x4B, 0xE2, 0x60, 0xE3, 0x60, -+0x01, 0x20, 0x70, 0xBD, 0x40, 0xF6, 0x43, 0x23, 0xC4, 0xE9, 0x00, 0x33, 0xC4, 0xE9, 0x02, 0x33, 0x70, 0xBD, 0x00, 0xBF, -+0x32, 0xE4, 0x05, 0x00, 0x22, 0xF3, 0x02, 0x00, 0x38, 0xB5, 0x14, 0x46, 0xFD, 0xF7, 0x4A, 0xFB, 0xE8, 0xB1, 0xC2, 0x78, -+0x83, 0x78, 0x43, 0xEA, 0x02, 0x23, 0x23, 0x80, 0x23, 0x46, 0x02, 0x79, 0x03, 0xF8, 0x02, 0x2F, 0x04, 0xF1, 0x12, 0x05, -+0xC4, 0xF1, 0x03, 0x02, 0xC1, 0x18, 0x89, 0x5C, 0x03, 0xF8, 0x01, 0x1F, 0xAB, 0x42, 0xF9, 0xD1, 0x43, 0x7D, 0x82, 0x7D, -+0xB0, 0xF8, 0x17, 0x10, 0xA1, 0x61, 0x43, 0xEA, 0x02, 0x23, 0xA3, 0x82, 0xC3, 0x7E, 0x23, 0x77, 0x01, 0x20, 0x38, 0xBD, -+0xF8, 0xB5, 0x14, 0x46, 0xFD, 0xF7, 0xCA, 0xFB, 0xB8, 0xB1, 0xC7, 0x79, 0x43, 0x7A, 0x85, 0x79, 0x02, 0x7A, 0x81, 0x7A, -+0xC6, 0x7A, 0x45, 0xEA, 0x07, 0x25, 0x42, 0xEA, 0x03, 0x22, 0xD0, 0xF8, 0x02, 0x70, 0x03, 0x7B, 0x40, 0x7B, 0x27, 0x60, -+0x43, 0xEA, 0x00, 0x23, 0x41, 0xEA, 0x06, 0x21, 0xA5, 0x80, 0x21, 0x81, 0xE2, 0x80, 0x63, 0x81, 0x01, 0x20, 0xF8, 0xBD, -+0xF0, 0xB5, 0x83, 0xB0, 0x15, 0x46, 0x0D, 0xF1, 0x07, 0x02, 0xFD, 0xF7, 0xC9, 0xFB, 0x00, 0x28, 0x45, 0xD0, 0x9D, 0xF8, -+0x07, 0x30, 0xC6, 0x1C, 0xC5, 0xF1, 0x04, 0x04, 0x1E, 0x44, 0x04, 0x44, 0x6B, 0x1E, 0x69, 0x1D, 0x1A, 0x5D, 0x03, 0xF8, -+0x01, 0x2F, 0x8B, 0x42, 0xFA, 0xD1, 0x05, 0xF1, 0x10, 0x02, 0x19, 0x5D, 0x03, 0xF8, 0x01, 0x1F, 0x93, 0x42, 0xFA, 0xD1, -+0x02, 0x7D, 0x47, 0x7D, 0x83, 0x7D, 0xC4, 0x7D, 0xA9, 0x79, 0x42, 0xEA, 0x07, 0x22, 0x43, 0xEA, 0x04, 0x23, 0x6A, 0x82, -+0x4A, 0x10, 0x09, 0x07, 0xAB, 0x82, 0x00, 0xF1, 0x18, 0x03, 0x0E, 0xD5, 0x00, 0xF1, 0x1C, 0x01, 0xB1, 0x42, 0x1C, 0xD8, -+0x5F, 0x78, 0x04, 0x7E, 0x83, 0x7E, 0xC0, 0x7E, 0x44, 0xEA, 0x07, 0x24, 0x43, 0xEA, 0x00, 0x20, 0xEC, 0x82, 0x0B, 0x46, -+0x28, 0x83, 0x12, 0x07, 0x12, 0xD5, 0x1A, 0x1D, 0xB2, 0x42, 0x0C, 0xD8, 0x58, 0x78, 0x19, 0x78, 0x9A, 0x78, 0xDB, 0x78, -+0x41, 0xEA, 0x00, 0x21, 0x42, 0xEA, 0x03, 0x23, 0x01, 0x20, 0x69, 0x83, 0xAB, 0x83, 0x03, 0xB0, 0xF0, 0xBD, 0x00, 0x20, -+0x03, 0xB0, 0xF0, 0xBD, 0x01, 0x20, 0x03, 0xB0, 0xF0, 0xBD, 0x00, 0xBF, 0x10, 0xB5, 0x82, 0xB0, 0x14, 0x46, 0x0D, 0xF1, -+0x07, 0x02, 0xFD, 0xF7, 0xC7, 0xFB, 0x40, 0xB1, 0xD0, 0xF8, 0x03, 0x30, 0xC4, 0xF8, 0xDC, 0x30, 0x00, 0x38, 0x18, 0xBF, -+0x01, 0x20, 0x02, 0xB0, 0x10, 0xBD, 0x01, 0x4B, 0xF6, 0xE7, 0x00, 0xBF, 0x00, 0x00, 0x01, 0x80, 0xF8, 0xB5, 0x1D, 0x46, -+0x14, 0x46, 0xFD, 0xF7, 0xC7, 0xFB, 0x00, 0x23, 0x2B, 0x70, 0x00, 0xB3, 0xC2, 0x78, 0x61, 0x7C, 0x02, 0xF0, 0x0F, 0x03, -+0x99, 0x42, 0x1B, 0xD0, 0x01, 0x26, 0x2E, 0x70, 0x22, 0x74, 0x63, 0x74, 0xB0, 0xF8, 0x05, 0x10, 0x03, 0x79, 0x02, 0x89, -+0xB0, 0xF8, 0x0B, 0x70, 0xC5, 0x89, 0x43, 0xEA, 0x01, 0x23, 0x63, 0x60, 0xC1, 0x79, 0x41, 0xEA, 0x02, 0x21, 0x21, 0x60, -+0x82, 0x7A, 0x42, 0xEA, 0x07, 0x22, 0xA2, 0x60, 0x43, 0x7B, 0x43, 0xEA, 0x05, 0x23, 0x30, 0x46, 0xE3, 0x60, 0xF8, 0xBD, -+0x01, 0x20, 0xF8, 0xBD, 0x10, 0xB5, 0x14, 0x46, 0xFD, 0xF7, 0xAC, 0xFB, 0x40, 0xB1, 0xC3, 0x78, 0x03, 0xF0, 0x07, 0x02, -+0xC3, 0xF3, 0xC2, 0x03, 0x22, 0x70, 0x63, 0x70, 0x01, 0x20, 0x10, 0xBD, 0x03, 0x22, 0x05, 0x23, 0x22, 0x70, 0x63, 0x70, -+0x10, 0xBD, 0x00, 0xBF, 0x38, 0xB5, 0x07, 0x48, 0x1C, 0x46, 0x15, 0x46, 0xFE, 0x22, 0x10, 0xF0, 0x67, 0xFD, 0x2A, 0x46, -+0x21, 0x46, 0x41, 0xF2, 0x03, 0x40, 0xFC, 0xF7, 0x41, 0xFA, 0x00, 0x20, 0x38, 0xBD, 0x00, 0xBF, 0x5A, 0xB9, 0x17, 0x00, -+0x70, 0xB5, 0x32, 0x4C, 0x08, 0x78, 0x24, 0x68, 0x01, 0x28, 0x19, 0x46, 0x20, 0x70, 0x29, 0xD0, 0x02, 0x28, 0x05, 0xD0, -+0x41, 0xF2, 0x16, 0x40, 0xFC, 0xF7, 0x2E, 0xFA, 0x00, 0x20, 0x70, 0xBD, 0x2B, 0x4C, 0x2C, 0x48, 0x23, 0x68, 0x2C, 0x4E, -+0x2C, 0x4D, 0x43, 0xF4, 0x80, 0x33, 0x23, 0x60, 0x03, 0x68, 0x2B, 0x4C, 0x23, 0xF0, 0x00, 0x73, 0x03, 0x60, 0x3F, 0x23, -+0x33, 0x60, 0x2B, 0x68, 0x28, 0x48, 0x23, 0xF0, 0x01, 0x03, 0x2B, 0x60, 0x23, 0x6D, 0x23, 0xF4, 0x80, 0x23, 0x23, 0x65, -+0x03, 0x69, 0x43, 0xF0, 0x80, 0x03, 0x03, 0x61, 0x41, 0xF2, 0x16, 0x40, 0xFC, 0xF7, 0x0C, 0xFA, 0x00, 0x20, 0x70, 0xBD, -+0x20, 0x4B, 0x1B, 0x4C, 0x93, 0xF8, 0xB5, 0x30, 0x0B, 0xBB, 0x23, 0x68, 0x19, 0x4E, 0x1E, 0x4D, 0x43, 0xF0, 0x00, 0x73, -+0x23, 0x60, 0x04, 0xF5, 0x00, 0x44, 0x04, 0x23, 0x28, 0x34, 0x33, 0x60, 0x28, 0x60, 0x23, 0x68, 0x23, 0xF4, 0x80, 0x23, -+0x23, 0xF0, 0x01, 0x03, 0x23, 0x60, 0x13, 0x4C, 0x13, 0x48, 0x23, 0x6D, 0x43, 0xF4, 0x80, 0x23, 0x23, 0x65, 0x03, 0x69, -+0x23, 0xF0, 0x80, 0x03, 0x03, 0x61, 0x41, 0xF2, 0x16, 0x40, 0xFC, 0xF7, 0xE5, 0xF9, 0x00, 0x20, 0x70, 0xBD, 0x23, 0x68, -+0x09, 0x48, 0x08, 0x4D, 0x23, 0xF0, 0x00, 0x73, 0x23, 0x60, 0x03, 0x68, 0x24, 0x24, 0x43, 0xF4, 0x00, 0x13, 0x03, 0x60, -+0x2C, 0x60, 0xE2, 0xE7, 0x74, 0x36, 0x17, 0x00, 0x44, 0x00, 0x32, 0x40, 0x4C, 0x00, 0x32, 0x40, 0x98, 0x80, 0x32, 0x40, -+0x6C, 0x00, 0x32, 0x40, 0x00, 0x60, 0x50, 0x40, 0x00, 0x00, 0x50, 0x40, 0x2C, 0x19, 0x17, 0x00, 0x70, 0x80, 0x32, 0x40, -+0xF8, 0xB5, 0x4C, 0x78, 0x08, 0x78, 0x16, 0x46, 0x1D, 0x46, 0x2C, 0xB3, 0x17, 0x4C, 0x18, 0x4B, 0x4F, 0xF4, 0x1E, 0x72, -+0x02, 0xFB, 0x00, 0x44, 0x4F, 0xF4, 0xA4, 0x61, 0x94, 0xF8, 0x22, 0x20, 0x01, 0xFB, 0x02, 0x32, 0x02, 0x23, 0x92, 0xF8, -+0x62, 0x70, 0x84, 0xF8, 0x30, 0x30, 0x5F, 0xB9, 0x06, 0x22, 0x05, 0x21, 0x41, 0xF2, 0x19, 0x40, 0xFC, 0xF7, 0x3E, 0xF9, -+0x07, 0x70, 0x94, 0xF8, 0x22, 0x20, 0x42, 0x70, 0xFC, 0xF7, 0x68, 0xF9, 0x32, 0x46, 0x29, 0x46, 0x41, 0xF2, 0x05, 0x40, -+0xFC, 0xF7, 0x9A, 0xF9, 0x00, 0x20, 0xF8, 0xBD, 0x04, 0x4B, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x00, 0x30, 0x01, 0x23, -+0x80, 0xF8, 0x30, 0x30, 0xEE, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x43, -+0x0C, 0x20, 0x0C, 0x46, 0x17, 0x46, 0x00, 0x21, 0x05, 0x22, 0x1E, 0x46, 0x01, 0x23, 0xFC, 0xF7, 0x17, 0xF9, 0xDF, 0xF8, -+0x6C, 0x90, 0xDF, 0xF8, 0x6C, 0x80, 0xD9, 0xF8, 0x24, 0x30, 0x05, 0x46, 0x20, 0x78, 0x98, 0x47, 0x23, 0x78, 0x2B, 0x70, -+0x28, 0x46, 0xFC, 0xF7, 0x39, 0xF9, 0x20, 0x78, 0xD9, 0xF8, 0xD8, 0x31, 0x4F, 0xF4, 0x1E, 0x75, 0x05, 0xFB, 0x00, 0xF0, -+0x00, 0xF5, 0x18, 0x70, 0x40, 0x44, 0x98, 0x47, 0x63, 0x78, 0x43, 0xB9, 0x3A, 0x46, 0x31, 0x46, 0x41, 0xF2, 0x0A, 0x40, -+0xFC, 0xF7, 0x5E, 0xF9, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x02, 0x23, 0x06, 0x22, 0x05, 0x21, 0x41, 0xF2, 0x19, 0x40, -+0xFC, 0xF7, 0xEC, 0xF8, 0x00, 0x22, 0x02, 0x70, 0x22, 0x78, 0x05, 0xFB, 0x02, 0x88, 0x98, 0xF8, 0x22, 0x20, 0x42, 0x70, -+0xFC, 0xF7, 0x12, 0xF9, 0xE4, 0xE7, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, -+0x0C, 0x46, 0x89, 0x78, 0x25, 0x78, 0xDF, 0xF8, 0xAC, 0x80, 0x1E, 0x46, 0x17, 0x46, 0x63, 0x78, 0xA1, 0xB1, 0x00, 0x2B, -+0x44, 0xD1, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x05, 0x83, 0x93, 0xF8, 0x31, 0x20, 0x02, 0xF0, 0xFB, 0x02, 0x4F, 0xF4, -+0x1E, 0x73, 0x03, 0xFB, 0x05, 0x83, 0x93, 0xF8, 0x2E, 0x11, 0x83, 0xF8, 0x31, 0x20, 0x0F, 0x29, 0x1E, 0xD1, 0x0A, 0xE0, -+0x2B, 0xBB, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x05, 0x83, 0x93, 0xF8, 0x31, 0x20, 0x22, 0xF0, 0x01, 0x02, 0x83, 0xF8, -+0x31, 0x20, 0x04, 0x23, 0x05, 0x22, 0x00, 0x21, 0x41, 0x20, 0xFC, 0xF7, 0xAB, 0xF8, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, -+0x05, 0x85, 0x95, 0xF8, 0x22, 0x30, 0x2A, 0x8C, 0x02, 0x80, 0xC3, 0x70, 0x63, 0x78, 0x83, 0x70, 0xFC, 0xF7, 0xCE, 0xF8, -+0x3A, 0x46, 0x31, 0x46, 0x41, 0xF2, 0x0D, 0x40, 0xFC, 0xF7, 0x00, 0xF9, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x4F, 0xF4, -+0x1E, 0x73, 0x03, 0xFB, 0x05, 0x83, 0x93, 0xF8, 0x31, 0x20, 0x42, 0xF0, 0x01, 0x02, 0x83, 0xF8, 0x31, 0x20, 0xD8, 0xE7, -+0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x05, 0x83, 0x93, 0xF8, 0x31, 0x20, 0x42, 0xF0, 0x04, 0x02, 0xB9, 0xE7, 0x00, 0xBF, -+0x68, 0x65, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x31, 0x20, 0x0D, 0x46, 0x4B, 0x4C, 0x91, 0x46, 0x98, 0x46, 0x05, 0x22, -+0x01, 0x23, 0x00, 0x21, 0xFC, 0xF7, 0x72, 0xF8, 0x00, 0x23, 0x84, 0xF8, 0x76, 0x31, 0x95, 0xF8, 0x67, 0x30, 0x82, 0x46, -+0x5B, 0xB1, 0x01, 0x23, 0x84, 0xF8, 0x76, 0x31, 0x2F, 0x46, 0x0F, 0xCF, 0x04, 0xF1, 0x0C, 0x06, 0x0F, 0xC6, 0x97, 0xE8, -+0x0F, 0x00, 0x86, 0xE8, 0x0F, 0x00, 0x95, 0xF8, 0x68, 0x30, 0x5B, 0xB1, 0x94, 0xF8, 0x76, 0x21, 0x3C, 0x4B, 0x42, 0xF0, -+0x02, 0x02, 0x84, 0xF8, 0x76, 0x21, 0x05, 0xF1, 0x20, 0x02, 0x07, 0xCA, 0x83, 0xE8, 0x07, 0x00, 0x95, 0xF8, 0x69, 0x30, -+0x93, 0xB1, 0x94, 0xF8, 0x76, 0x31, 0x36, 0x4E, 0x43, 0xF0, 0x04, 0x03, 0x84, 0xF8, 0x76, 0x31, 0x05, 0xF1, 0x2C, 0x07, -+0x0F, 0xCF, 0x0F, 0xC6, 0x0F, 0xCF, 0x0F, 0xC6, 0x0F, 0xCF, 0x0F, 0xC6, 0x97, 0xE8, 0x03, 0x00, 0x86, 0xE8, 0x03, 0x00, -+0x95, 0xF8, 0x6A, 0x30, 0x2B, 0xB1, 0x94, 0xF8, 0x76, 0x31, 0x43, 0xF0, 0x08, 0x03, 0x84, 0xF8, 0x76, 0x31, 0x95, 0xF8, -+0x66, 0x30, 0x84, 0xF8, 0x75, 0x31, 0x4A, 0x46, 0x41, 0x46, 0x41, 0xF2, 0x01, 0x40, 0xFC, 0xF7, 0x8F, 0xF8, 0x94, 0xF8, -+0x76, 0x31, 0x13, 0xF0, 0x01, 0x03, 0x14, 0xD1, 0x84, 0xF8, 0x74, 0x31, 0x95, 0xF8, 0x6B, 0x30, 0xB5, 0xF8, 0x64, 0x10, -+0x84, 0xF8, 0x77, 0x31, 0x95, 0xF8, 0x6D, 0x20, 0xA1, 0x85, 0x00, 0x2A, 0x14, 0xBF, 0x02, 0x22, 0x01, 0x22, 0x84, 0xF8, -+0x78, 0x21, 0xF3, 0xB9, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0xDA, 0xF7, 0xE3, 0xFC, 0x94, 0xF8, 0x76, 0x31, 0x01, 0x30, -+0x40, 0x10, 0x5B, 0x07, 0x84, 0xF8, 0x74, 0x01, 0xE2, 0xD5, 0x94, 0xF8, 0x75, 0x21, 0x94, 0xF8, 0x44, 0x30, 0x02, 0x2A, -+0x88, 0xBF, 0x94, 0xF8, 0x49, 0x20, 0x4F, 0xEA, 0x93, 0x03, 0x88, 0xBF, 0x03, 0xEA, 0x92, 0x13, 0x03, 0xF0, 0x01, 0x03, -+0x84, 0xF8, 0x74, 0x30, 0xD0, 0xE7, 0xFF, 0x23, 0x23, 0x81, 0x50, 0x46, 0x8A, 0xF8, 0x00, 0x20, 0xFC, 0xF7, 0x1A, 0xF8, -+0x01, 0x21, 0x05, 0x20, 0xFC, 0xF7, 0xE0, 0xF9, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0xBF, 0xE4, 0xB8, 0x17, 0x00, -+0x14, 0xB9, 0x17, 0x00, 0x20, 0xB9, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x41, 0xF2, 0x08, 0x40, 0x97, 0xB0, 0x0C, 0x46, -+0x19, 0x46, 0x03, 0x23, 0xFB, 0xF7, 0xD2, 0xFF, 0x4F, 0xF0, 0x00, 0x0A, 0xCD, 0xE9, 0x0C, 0xAA, 0x05, 0x46, 0xAD, 0xF8, -+0x2E, 0xA0, 0x8D, 0xF8, 0x2C, 0xA0, 0x08, 0xF0, 0xEB, 0xFB, 0x94, 0xF8, 0x81, 0x70, 0xA2, 0x6F, 0x06, 0x90, 0x4F, 0xF4, -+0xA4, 0x61, 0x01, 0xFB, 0x07, 0xF1, 0x12, 0xF0, 0x02, 0x06, 0x07, 0x91, 0x1B, 0xD0, 0x12, 0xF0, 0x04, 0x06, 0x04, 0xF1, -+0x14, 0x08, 0x40, 0xF0, 0xDC, 0x81, 0xB1, 0x46, 0x0B, 0xAB, 0x12, 0xF0, 0x20, 0x02, 0x0D, 0xF1, 0x34, 0x0C, 0x02, 0x93, -+0x0C, 0xAB, 0xCD, 0xE9, 0x00, 0x3C, 0x18, 0xBF, 0x04, 0xF1, 0x40, 0x02, 0x0D, 0xF1, 0x2E, 0x03, 0x49, 0x46, 0x40, 0x46, -+0x00, 0xF0, 0x00, 0xFE, 0x94, 0xF8, 0x81, 0x30, 0x00, 0xE0, 0x3B, 0x46, 0x00, 0x22, 0xDF, 0xF8, 0xC4, 0x93, 0x20, 0x68, -+0x0C, 0x99, 0xB4, 0xF8, 0x04, 0xE0, 0xBD, 0xF8, 0x2E, 0xC0, 0x0E, 0x92, 0x8D, 0xF8, 0x55, 0x20, 0x8D, 0xF8, 0x56, 0x20, -+0x9D, 0xF8, 0x2C, 0x20, 0x8D, 0xF8, 0x51, 0x30, 0xCD, 0xF8, 0x4A, 0x00, 0x10, 0x91, 0x8D, 0xF8, 0x50, 0x20, 0xD9, 0xF8, -+0xC4, 0x31, 0x11, 0x96, 0xAD, 0xF8, 0x4E, 0xE0, 0xAD, 0xF8, 0x48, 0xC0, 0x0D, 0xF1, 0x2D, 0x02, 0x29, 0x46, 0x0E, 0xA8, -+0x98, 0x47, 0x83, 0x46, 0x68, 0x70, 0x00, 0x28, 0x40, 0xF0, 0x1C, 0x81, 0x23, 0x46, 0x2E, 0x78, 0x53, 0xF8, 0x06, 0x0F, -+0xDF, 0xF8, 0x70, 0x83, 0x59, 0x68, 0x9A, 0x68, 0x93, 0xF8, 0x0C, 0xE0, 0xD4, 0xF8, 0x78, 0xC0, 0x04, 0x96, 0x4F, 0xF4, -+0x1E, 0x73, 0x03, 0xFB, 0x06, 0xF3, 0x08, 0xEB, 0x03, 0x0A, 0x08, 0x93, 0x0A, 0xF1, 0xB8, 0x03, 0x07, 0xC3, 0x1C, 0xF0, -+0x01, 0x0F, 0x83, 0xF8, 0x00, 0xE0, 0x40, 0xF0, 0x06, 0x81, 0xC7, 0x4B, 0x05, 0x93, 0x1C, 0xF0, 0x08, 0x0F, 0x08, 0xD0, -+0x04, 0x9A, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x02, 0x83, 0x5A, 0x68, 0x42, 0xF0, 0x08, 0x02, 0x5A, 0x60, 0x04, 0x9A, -+0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x02, 0x83, 0x94, 0xF8, 0x7E, 0x20, 0x83, 0xF8, 0x2E, 0x21, 0x94, 0xF8, 0x7F, 0x10, -+0xB4, 0xF8, 0x7C, 0x20, 0x1A, 0x84, 0x83, 0xF8, 0x2F, 0x11, 0x50, 0x46, 0x09, 0x93, 0x00, 0xF0, 0xBB, 0xFE, 0xA2, 0x6F, -+0xD2, 0x06, 0x06, 0xD5, 0x94, 0xF9, 0x80, 0x20, 0x94, 0xF8, 0x80, 0x10, 0x00, 0x2A, 0x80, 0xF2, 0x77, 0x81, 0xBB, 0xF1, -+0x00, 0x0F, 0x40, 0xF0, 0x7F, 0x81, 0x05, 0x9B, 0xAF, 0x48, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x07, 0x34, 0x04, 0x9B, -+0xB4, 0xF8, 0xE0, 0x20, 0x4F, 0xF4, 0x1E, 0x7B, 0x0B, 0xFB, 0x03, 0x86, 0xD4, 0xF8, 0xB0, 0x34, 0x96, 0xF8, 0x56, 0x11, -+0xC6, 0xF8, 0x68, 0xA2, 0x03, 0xF0, 0x01, 0x03, 0xC3, 0xF1, 0x02, 0x03, 0x86, 0xF8, 0x30, 0x30, 0x41, 0xF0, 0x10, 0x01, -+0xA3, 0x4B, 0x86, 0xF8, 0x56, 0x11, 0x52, 0xBA, 0x4F, 0xF0, 0x01, 0x0A, 0xC6, 0xF8, 0x64, 0x02, 0xB2, 0x86, 0x08, 0x98, -+0x86, 0xF8, 0x70, 0xA2, 0x1A, 0x69, 0x9E, 0x49, 0xD9, 0xF8, 0xE0, 0x31, 0x00, 0xF5, 0x18, 0x70, 0x40, 0x44, 0x11, 0x44, -+0x98, 0x47, 0x06, 0x9B, 0xAB, 0x70, 0x00, 0x2B, 0x00, 0xF0, 0x9A, 0x80, 0x94, 0xF8, 0xDE, 0x20, 0x86, 0xF8, 0x24, 0x30, -+0x00, 0x2A, 0x40, 0xF0, 0x85, 0x80, 0x94, 0xF8, 0x63, 0x60, 0x0A, 0x36, 0xF6, 0xB2, 0x0B, 0xFB, 0x06, 0xF3, 0x08, 0xEB, -+0x03, 0x0B, 0x04, 0x93, 0x9B, 0xF8, 0x24, 0x30, 0x53, 0x45, 0x77, 0xD0, 0x02, 0x23, 0x0C, 0x21, 0x49, 0x20, 0xFB, 0xF7, -+0xDB, 0xFE, 0x8B, 0xF8, 0x24, 0xA0, 0x06, 0x70, 0x80, 0xF8, 0x01, 0xA0, 0xFB, 0xF7, 0x04, 0xFF, 0x9B, 0xF8, 0x24, 0x30, -+0x00, 0x2B, 0x40, 0xF0, 0x48, 0x81, 0x9B, 0xF8, 0x23, 0x30, 0x09, 0x2B, 0x00, 0xF2, 0x43, 0x81, 0x9B, 0xF8, 0x22, 0x00, -+0x05, 0x9C, 0xCD, 0xF8, 0x18, 0xA0, 0x9E, 0x23, 0xA4, 0x21, 0x4F, 0xF4, 0xA4, 0x6C, 0x11, 0xFB, 0x00, 0x31, 0x0C, 0xFB, -+0x00, 0x4A, 0x4F, 0x23, 0x46, 0x20, 0x13, 0xFB, 0x06, 0x03, 0x7B, 0x4A, 0x05, 0x98, 0x7B, 0x4C, 0x08, 0x95, 0x08, 0xEB, -+0xC3, 0x08, 0x04, 0x9B, 0x00, 0xEB, 0xC1, 0x06, 0x13, 0x44, 0x35, 0x46, 0x1E, 0x46, 0xDB, 0xF8, 0x08, 0x22, 0x1A, 0xB3, -+0xEF, 0xF3, 0x10, 0x82, 0xD3, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x73, 0x4B, 0x06, 0x9A, 0x1A, 0x60, 0x22, 0x68, 0xA8, 0xF1, -+0x28, 0x00, 0x01, 0x32, 0xA5, 0xF1, 0x28, 0x01, 0x04, 0x90, 0x22, 0x60, 0xFC, 0xF7, 0x18, 0xFC, 0xDB, 0xE9, 0x82, 0x21, -+0x04, 0x98, 0xCA, 0xF8, 0xC8, 0x24, 0xCA, 0xF8, 0xCC, 0x14, 0xFC, 0xF7, 0x19, 0xFB, 0x22, 0x68, 0x51, 0x1E, 0x2A, 0xB1, -+0x66, 0x4B, 0x21, 0x60, 0x1A, 0x68, 0x09, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0xDB, 0xF8, 0x30, 0x22, 0x28, 0x46, 0x41, 0x46, -+0x0B, 0xF1, 0x08, 0x0B, 0x08, 0x35, 0x0A, 0xF1, 0x08, 0x0A, 0x22, 0xB1, 0xFC, 0xF7, 0xFA, 0xFB, 0x40, 0x46, 0xFC, 0xF7, -+0x01, 0xFB, 0x08, 0xF1, 0x08, 0x08, 0x46, 0x45, 0xC5, 0xD1, 0x40, 0x20, 0x08, 0x9D, 0xFC, 0xF7, 0x5B, 0xFA, 0x05, 0x9A, -+0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x07, 0x23, 0x93, 0xF8, 0xDE, 0x20, 0x05, 0x9C, 0xD9, 0xF8, 0x0C, 0x32, 0x4F, 0xF4, -+0xA4, 0x61, 0x01, 0xFB, 0x07, 0x47, 0x07, 0x99, 0x01, 0x32, 0x21, 0x44, 0x08, 0x46, 0x87, 0xF8, 0xDE, 0x20, 0x98, 0x47, -+0x28, 0x46, 0xFB, 0xF7, 0x87, 0xFE, 0x00, 0x20, 0x17, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xDA, 0xF8, 0x04, 0x30, 0x05, 0x93, -+0x1C, 0xF0, 0x02, 0x0F, 0x43, 0xF0, 0x01, 0x03, 0xCA, 0xF8, 0x04, 0x30, 0x3F, 0xF4, 0xEF, 0xAE, 0x45, 0x4B, 0x93, 0xF8, -+0x76, 0x31, 0x09, 0x93, 0x13, 0xF0, 0x01, 0x0B, 0x3F, 0xF4, 0xE7, 0xAE, 0x04, 0xF1, 0x14, 0x0E, 0xBE, 0xE8, 0x0F, 0x00, -+0x0A, 0xF1, 0xC8, 0x0B, 0xAB, 0xE8, 0x0F, 0x00, 0x9E, 0xE8, 0x0F, 0x00, 0x05, 0x9E, 0x1C, 0xF0, 0x20, 0x0F, 0x46, 0xF0, -+0x03, 0x0E, 0x8B, 0xE8, 0x0F, 0x00, 0xCA, 0xF8, 0x04, 0xE0, 0x22, 0xD0, 0x09, 0x9B, 0x58, 0x07, 0x1F, 0xD5, 0x04, 0xF1, -+0x40, 0x0E, 0xBE, 0xE8, 0x0F, 0x00, 0x0A, 0xF1, 0xF4, 0x0B, 0xAB, 0xE8, 0x0F, 0x00, 0xBE, 0xE8, 0x0F, 0x00, 0xAB, 0xE8, -+0x0F, 0x00, 0xBE, 0xE8, 0x0F, 0x00, 0xAB, 0xE8, 0x0F, 0x00, 0x9E, 0xE8, 0x03, 0x00, 0x46, 0xF0, 0x23, 0x03, 0xCA, 0xF8, -+0x04, 0x30, 0x09, 0x9B, 0x8B, 0xE8, 0x03, 0x00, 0x19, 0x07, 0x04, 0xD5, 0x50, 0x46, 0xEC, 0xF7, 0x85, 0xFF, 0xD4, 0xF8, -+0x78, 0xC0, 0x1C, 0xF0, 0x04, 0x0F, 0x1F, 0xD0, 0x24, 0x4B, 0x04, 0x9A, 0x93, 0xF8, 0x76, 0x31, 0x13, 0xF0, 0x02, 0x0F, -+0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x02, 0x83, 0xD3, 0xF8, 0x04, 0xC0, 0x02, 0xD1, 0x1C, 0xF0, 0x20, 0x0F, 0x0F, 0xD0, -+0x04, 0xF1, 0x34, 0x03, 0x93, 0xE8, 0x07, 0x00, 0x04, 0x9E, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x06, 0x83, 0x03, 0xF1, -+0xE8, 0x0E, 0x8E, 0xE8, 0x07, 0x00, 0x4C, 0xF0, 0x04, 0x02, 0x5A, 0x60, 0x07, 0x9A, 0x0D, 0x4B, 0x05, 0x93, 0x02, 0xF1, -+0xEC, 0x01, 0x19, 0x44, 0x50, 0x46, 0x00, 0xF0, 0x53, 0xFB, 0xD4, 0xF8, 0x78, 0xC0, 0x83, 0x46, 0x81, 0xE6, 0x07, 0x4B, -+0x05, 0x93, 0x0B, 0x44, 0x04, 0xF1, 0x34, 0x09, 0x93, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0x43, 0xD0, 0x03, 0x2B, 0x2F, 0xD0, -+0xA3, 0xB3, 0x56, 0x46, 0x16, 0xE6, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, 0x1D, 0x66, 0x12, 0x00, 0x00, 0x10, 0x50, 0x40, -+0x40, 0x4B, 0x4C, 0x00, 0xC0, 0x67, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0xE4, 0xB8, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x09, 0x9B, 0x0A, 0x09, 0x93, 0xF8, 0x23, 0x00, 0x01, 0xF0, 0x03, 0x01, -+0x01, 0xF0, 0x34, 0xF8, 0xBB, 0xF1, 0x00, 0x0F, 0x3F, 0xF4, 0x81, 0xAE, 0x04, 0x9A, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, -+0x02, 0x83, 0xFF, 0x21, 0x93, 0xF8, 0x23, 0x00, 0x00, 0x22, 0x01, 0xF0, 0x25, 0xF8, 0x74, 0xE6, 0x20, 0x46, 0xFC, 0xF7, -+0x61, 0xFF, 0xA2, 0x6F, 0x06, 0x46, 0xE3, 0xE5, 0x09, 0x4B, 0x01, 0xF5, 0xB2, 0x70, 0x03, 0x44, 0xB4, 0xF8, 0x7C, 0x10, -+0x18, 0x46, 0xFC, 0xF7, 0x5D, 0xFF, 0xA2, 0x6F, 0x06, 0x46, 0xD7, 0xE5, 0x07, 0x9B, 0x03, 0xF1, 0x5C, 0x00, 0x05, 0x9B, -+0xF1, 0xE7, 0x94, 0xF8, 0xDE, 0x20, 0x1B, 0xE7, 0x18, 0x88, 0x17, 0x00, 0xF0, 0xB5, 0x0C, 0x46, 0x21, 0x4D, 0x09, 0x78, -+0x6F, 0x68, 0x1E, 0x46, 0x63, 0x78, 0x01, 0x20, 0x83, 0xB0, 0x98, 0x40, 0xC1, 0xB1, 0x38, 0x43, 0x95, 0xF8, 0x77, 0x31, -+0x68, 0x60, 0x5B, 0xB1, 0x05, 0x20, 0x01, 0x92, 0xFC, 0xF7, 0x10, 0xF8, 0x01, 0x28, 0x2C, 0xD0, 0x17, 0xF0, 0xFF, 0x0F, -+0x23, 0x78, 0x01, 0x9A, 0x0B, 0xD0, 0x63, 0xB1, 0x41, 0xF2, 0x1A, 0x40, 0x31, 0x46, 0xFB, 0xF7, 0xC9, 0xFD, 0x00, 0x20, -+0x03, 0xB0, 0xF0, 0xBD, 0x27, 0xEA, 0x00, 0x00, 0xE4, 0xE7, 0x00, 0x2B, 0xF2, 0xD0, 0x01, 0x23, 0x00, 0x21, 0x31, 0x20, -+0x01, 0x92, 0xFB, 0xF7, 0x53, 0xFD, 0x6B, 0x68, 0x01, 0x9A, 0x2E, 0x81, 0x63, 0xB1, 0x00, 0x23, 0x03, 0x70, 0x01, 0x92, -+0xFB, 0xF7, 0x7A, 0xFD, 0x01, 0x9A, 0x01, 0x21, 0x10, 0x46, 0xFB, 0xF7, 0x3F, 0xFF, 0x00, 0x20, 0x03, 0xB0, 0xF0, 0xBD, -+0x95, 0xF8, 0x78, 0x31, 0xF0, 0xE7, 0x02, 0x20, 0xDC, 0xE7, 0x00, 0xBF, 0xE4, 0xB8, 0x17, 0x00, 0x11, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x10, 0xB5, 0x14, 0x46, 0x0E, 0xDB, 0x0E, 0x4B, 0x19, 0x89, 0xFF, 0x29, 0x04, 0xD0, -+0x22, 0x46, 0x41, 0xF2, 0x18, 0x40, 0xFB, 0xF7, 0x91, 0xFD, 0x20, 0x46, 0x00, 0x21, 0xFB, 0xF7, 0x1F, 0xFF, 0x00, 0x20, -+0x10, 0xBD, 0x10, 0x46, 0xFB, 0xF7, 0xC2, 0xFF, 0x01, 0x28, 0xEB, 0xD0, 0x05, 0x49, 0x06, 0x48, 0x40, 0xF2, 0x7F, 0x22, -+0xFD, 0xF7, 0xFA, 0xFD, 0xE4, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0xE4, 0xB8, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x3C, 0xB8, 0x15, 0x00, 0x11, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x10, 0xB5, 0x14, 0x46, 0x0E, 0xDB, -+0x0E, 0x4B, 0x19, 0x89, 0xFF, 0x29, 0x04, 0xD0, 0x22, 0x46, 0x41, 0xF2, 0x1A, 0x40, 0xFB, 0xF7, 0x65, 0xFD, 0x20, 0x46, -+0x00, 0x21, 0xFB, 0xF7, 0xF3, 0xFE, 0x00, 0x20, 0x10, 0xBD, 0x10, 0x46, 0xFB, 0xF7, 0x96, 0xFF, 0x01, 0x28, 0xEB, 0xD0, -+0x05, 0x49, 0x06, 0x48, 0x40, 0xF2, 0x15, 0x32, 0xFD, 0xF7, 0xCE, 0xFD, 0xE4, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0xE4, 0xB8, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x3C, 0xB8, 0x15, 0x00, 0x70, 0xB5, 0x0C, 0x46, 0x41, 0xF2, 0x0F, 0x40, -+0x19, 0x46, 0xC8, 0x23, 0xFB, 0xF7, 0xDA, 0xFC, 0x22, 0x78, 0x37, 0x49, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x02, 0x13, -+0x06, 0x46, 0xD3, 0xF8, 0x4C, 0x51, 0x02, 0x70, 0x00, 0x2D, 0x5C, 0xD0, 0xB5, 0xF8, 0xB4, 0x00, 0xB5, 0xF8, 0x90, 0x10, -+0xB5, 0xF8, 0x92, 0x20, 0xD5, 0xF8, 0x94, 0x30, 0xB3, 0x60, 0x70, 0x80, 0xB1, 0x80, 0xF2, 0x80, 0x95, 0xF8, 0xA4, 0x30, -+0x33, 0x73, 0xB5, 0xF8, 0x98, 0x30, 0x73, 0x73, 0x08, 0x22, 0x05, 0xF1, 0x88, 0x01, 0x06, 0xF1, 0x0E, 0x00, 0x10, 0xF0, -+0x3D, 0xF8, 0x78, 0x22, 0x29, 0x1D, 0x06, 0xF1, 0x16, 0x00, 0x10, 0xF0, 0x37, 0xF8, 0xB5, 0xF8, 0xB4, 0x30, 0x83, 0xB1, -+0x00, 0x24, 0x00, 0x22, 0xE1, 0xB2, 0x28, 0x46, 0x0C, 0xF0, 0x2C, 0xFE, 0xA3, 0xB2, 0x06, 0xEB, 0x83, 0x03, 0xB5, 0xF8, -+0xB4, 0x20, 0xC3, 0xF8, 0x9C, 0x00, 0x01, 0x34, 0xA3, 0xB2, 0x9A, 0x42, 0xEF, 0xD8, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, -+0x03, 0xD4, 0x72, 0xB6, 0x16, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x05, 0xF1, 0x7C, 0x03, 0x07, 0xCB, 0x14, 0x4C, 0xC6, 0xF8, -+0x8E, 0x00, 0x23, 0x68, 0xC6, 0xF8, 0x92, 0x10, 0x01, 0x33, 0xC6, 0xF8, 0x96, 0x20, 0x28, 0x46, 0x00, 0x22, 0x0A, 0x21, -+0x23, 0x60, 0x0C, 0xF0, 0x07, 0xFE, 0x23, 0x68, 0xC6, 0xF8, 0xC4, 0x00, 0x33, 0xB1, 0x0A, 0x4A, 0x01, 0x3B, 0x12, 0x68, -+0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x30, 0x46, 0xFB, 0xF7, 0xA3, 0xFC, 0x00, 0x20, 0x70, 0xBD, 0x45, 0x80, -+0x30, 0x46, 0xFB, 0xF7, 0x9D, 0xFC, 0x00, 0x20, 0x70, 0xBD, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, -+0x6C, 0x28, 0x17, 0x00, 0x70, 0xB5, 0x23, 0x4A, 0x0B, 0x78, 0x12, 0x68, 0x0C, 0x46, 0x22, 0x49, 0xB2, 0xF9, 0x00, 0x20, -+0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, 0x03, 0x13, 0x00, 0x2A, 0xD3, 0xF8, 0x4C, 0x51, 0x22, 0xDB, 0x66, 0x88, 0x4F, 0xF6, -+0xFF, 0x73, 0x9E, 0x42, 0x0B, 0xD1, 0x95, 0xF8, 0xA2, 0x30, 0xA5, 0xF8, 0xBA, 0x60, 0x03, 0xF0, 0xCF, 0x03, 0x85, 0xF8, -+0xA2, 0x30, 0x1B, 0x06, 0x1C, 0xD4, 0x00, 0x20, 0x70, 0xBD, 0x31, 0x46, 0x28, 0x46, 0x0C, 0xF0, 0x65, 0xFD, 0x00, 0x28, -+0xF7, 0xD0, 0x95, 0xF8, 0xA2, 0x30, 0xA5, 0xF8, 0xBA, 0x60, 0x23, 0xF0, 0x30, 0x03, 0x43, 0xF0, 0x10, 0x03, 0x85, 0xF8, -+0xA2, 0x30, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x2D, 0xDA, 0xD1, 0x0B, 0x49, 0x0B, 0x48, 0x40, 0xF2, 0xAF, 0x32, 0xFD, 0xF7, -+0x0B, 0xFD, 0xD3, 0xE7, 0x20, 0x78, 0x0C, 0xF0, 0xC9, 0xFB, 0x95, 0xF8, 0xA2, 0x30, 0x03, 0xF0, 0x7F, 0x03, 0x85, 0xF8, -+0xA2, 0x30, 0x00, 0x20, 0x70, 0xBD, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x68, 0x8E, 0x15, 0x00, 0xF8, 0xB5, 0x05, 0x20, 0x0E, 0x46, 0x15, 0x46, 0x1C, 0x46, 0xFB, 0xF7, 0xAF, 0xFE, 0x01, 0x28, -+0x4F, 0xD0, 0x2A, 0x46, 0x0C, 0x23, 0x21, 0x46, 0x41, 0xF2, 0x12, 0x40, 0xFB, 0xF7, 0x04, 0xFC, 0x37, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x05, 0x46, 0x2A, 0xDB, 0x35, 0x4B, 0x1C, 0x7C, 0xDA, 0xF7, 0x7F, 0xF8, 0x00, 0x28, -+0x30, 0xD1, 0xF3, 0x7A, 0x53, 0xB1, 0x32, 0x4B, 0x32, 0x49, 0x9A, 0x68, 0xD1, 0xF8, 0x2C, 0x12, 0x11, 0x66, 0xA3, 0xF5, -+0x40, 0x63, 0x4F, 0xF4, 0x80, 0x72, 0x1A, 0x60, 0x2E, 0x4F, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x04, 0x77, 0x3C, 0x6C, -+0x4C, 0xB3, 0x23, 0x7E, 0x2B, 0x70, 0xB3, 0x7A, 0xE3, 0xB9, 0x23, 0x1D, 0x03, 0xCB, 0x1B, 0x88, 0x6B, 0x81, 0xC5, 0xF8, -+0x02, 0x00, 0xC5, 0xF8, 0x06, 0x10, 0x28, 0x46, 0xFB, 0xF7, 0x04, 0xFC, 0x00, 0x20, 0xF8, 0xBD, 0x1F, 0x4F, 0x3C, 0x7C, -+0xFF, 0x2C, 0xD2, 0xD1, 0x21, 0x49, 0x22, 0x48, 0x40, 0xF2, 0xEB, 0x32, 0xFD, 0xF7, 0xAA, 0xFC, 0x3C, 0x7C, 0xCA, 0xE7, -+0xF0, 0x7A, 0xDA, 0xF7, 0x53, 0xF8, 0xCA, 0xE7, 0x1D, 0x48, 0xFC, 0xF7, 0xD1, 0xF8, 0x01, 0x28, 0x0A, 0xD0, 0x3C, 0x6C, -+0xDB, 0xE7, 0x02, 0x20, 0xF8, 0xBD, 0xFF, 0x23, 0x28, 0x46, 0x2B, 0x70, 0xFB, 0xF7, 0xE4, 0xFB, 0x20, 0x46, 0xF8, 0xBD, -+0x05, 0x22, 0x0C, 0x23, 0x00, 0x21, 0x3B, 0x20, 0xFB, 0xF7, 0xAC, 0xFB, 0x39, 0x6C, 0x03, 0x46, 0x09, 0x7E, 0x03, 0xF8, -+0x02, 0x1B, 0x31, 0x89, 0x37, 0x68, 0x74, 0x68, 0xC0, 0xF8, 0x02, 0x70, 0x19, 0x81, 0x5C, 0x60, 0xFB, 0xF7, 0xCE, 0xFB, -+0x31, 0x68, 0x72, 0x68, 0x33, 0x89, 0x6B, 0x81, 0xC5, 0xF8, 0x02, 0x10, 0xC5, 0xF8, 0x06, 0x20, 0xBD, 0xE7, 0x00, 0xBF, -+0x38, 0x36, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x00, 0xED, 0x00, 0xE0, 0x88, 0x1A, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x60, 0xB8, 0x15, 0x00, 0x08, 0x88, 0x17, 0x00, 0xF8, 0xB5, 0x05, 0x20, 0x0C, 0x46, 0x15, 0x46, -+0x1E, 0x46, 0xFB, 0xF7, 0x1F, 0xFE, 0x01, 0x28, 0x3C, 0xD0, 0x1F, 0x4F, 0x3B, 0x68, 0x73, 0xB1, 0x22, 0x78, 0xB2, 0xB1, -+0x61, 0x78, 0x01, 0x22, 0x8A, 0x40, 0x13, 0x43, 0x31, 0x46, 0x2A, 0x46, 0x41, 0xF2, 0x18, 0x40, 0x3B, 0x60, 0xFB, 0xF7, -+0xD3, 0xFB, 0x00, 0x20, 0xF8, 0xBD, 0x23, 0x78, 0x3B, 0xB9, 0x2A, 0x46, 0x31, 0x46, 0x41, 0xF2, 0x18, 0x40, 0xFB, 0xF7, -+0xC9, 0xFB, 0x00, 0x20, 0xF8, 0xBD, 0x01, 0x23, 0x00, 0x21, 0x2A, 0x46, 0x22, 0x20, 0xFB, 0xF7, 0x59, 0xFB, 0x23, 0x78, -+0x61, 0x78, 0x8B, 0xB1, 0x3A, 0x68, 0x01, 0x23, 0x8B, 0x40, 0x13, 0x43, 0xB3, 0xFA, 0x83, 0xF2, 0x52, 0x09, 0x3B, 0x60, -+0x3E, 0x81, 0x02, 0x70, 0xFB, 0xF7, 0x7A, 0xFB, 0x28, 0x46, 0x01, 0x21, 0xFB, 0xF7, 0x40, 0xFD, 0x00, 0x20, 0xF8, 0xBD, -+0x3B, 0x68, 0x01, 0x22, 0x8A, 0x40, 0x23, 0xEA, 0x02, 0x03, 0xEB, 0xE7, 0x02, 0x20, 0xF8, 0xBD, 0xE4, 0xB8, 0x17, 0x00, -+0xF8, 0xB5, 0x05, 0x20, 0x0D, 0x46, 0x17, 0x46, 0x1E, 0x46, 0xFB, 0xF7, 0xD5, 0xFD, 0x01, 0x28, 0x24, 0xD0, 0x13, 0x4C, -+0x2B, 0x78, 0x61, 0x68, 0x00, 0x3B, 0x18, 0xBF, 0x01, 0x23, 0x84, 0xF8, 0x77, 0x31, 0x81, 0xB9, 0x01, 0x23, 0x05, 0x22, -+0x31, 0x20, 0xFB, 0xF7, 0x23, 0xFB, 0x94, 0xF8, 0x77, 0x31, 0xFF, 0x22, 0x22, 0x81, 0x73, 0xB9, 0x03, 0x70, 0xFB, 0xF7, -+0x4B, 0xFB, 0x01, 0x21, 0x05, 0x20, 0xFB, 0xF7, 0x11, 0xFD, 0x3A, 0x46, 0x31, 0x46, 0x41, 0xF2, 0x14, 0x40, 0xFB, 0xF7, -+0x79, 0xFB, 0x00, 0x20, 0xF8, 0xBD, 0x94, 0xF8, 0x78, 0x31, 0xED, 0xE7, 0x02, 0x20, 0xF8, 0xBD, 0xE4, 0xB8, 0x17, 0x00, -+0x08, 0xB5, 0x4F, 0xF4, 0xBE, 0x72, 0x00, 0x21, 0x09, 0x48, 0xD8, 0xF7, 0xFB, 0xFE, 0x00, 0x21, 0x05, 0x20, 0xFB, 0xF7, -+0xF7, 0xFC, 0x04, 0xF0, 0xFB, 0xFF, 0x04, 0xF0, 0x7D, 0xFA, 0x02, 0xF0, 0x25, 0xF9, 0x09, 0xF0, 0x41, 0xF9, 0xBD, 0xE8, -+0x08, 0x40, 0x0E, 0xF0, 0xD5, 0xB8, 0x00, 0xBF, 0xE4, 0xB8, 0x17, 0x00, 0xA8, 0xB9, 0x10, 0x4B, 0x93, 0xF8, 0x72, 0x01, -+0x76, 0x33, 0xC8, 0xB1, 0x00, 0xEB, 0x40, 0x00, 0x10, 0xB4, 0x03, 0xEB, 0x40, 0x04, 0x01, 0xE0, 0xA3, 0x42, 0x0D, 0xD0, -+0x1A, 0x88, 0x8A, 0x42, 0x18, 0x46, 0x03, 0xF1, 0x06, 0x03, 0xF7, 0xD1, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x05, 0x4B, -+0x93, 0xF8, 0x73, 0x01, 0xCA, 0x33, 0xE8, 0xE7, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x70, 0x47, 0x00, 0xBF, -+0xE4, 0xB8, 0x17, 0x00, 0xF0, 0xB9, 0x4B, 0x1E, 0x0D, 0x2B, 0x31, 0xD8, 0x0E, 0x29, 0x32, 0xD0, 0x01, 0xEB, 0x81, 0x01, -+0x01, 0xF6, 0x67, 0x11, 0x19, 0x4B, 0x93, 0xF8, 0x72, 0x01, 0x76, 0x33, 0x60, 0xB3, 0x00, 0xEB, 0x40, 0x00, 0x10, 0xB4, -+0x03, 0xEB, 0x40, 0x04, 0x01, 0xE0, 0xA3, 0x42, 0x1A, 0xD0, 0x1A, 0x88, 0x8A, 0x42, 0x18, 0x46, 0x03, 0xF1, 0x06, 0x03, -+0xF7, 0xD1, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x01, 0x28, 0x06, 0xD0, 0x4F, 0xF6, 0xFF, 0x71, 0x0C, 0x4B, 0x93, 0xF8, -+0x73, 0x01, 0xCA, 0x33, 0xE4, 0xE7, 0x4B, 0x1E, 0xA4, 0x2B, 0xF5, 0xD8, 0x01, 0xEB, 0x81, 0x01, 0x01, 0xF5, 0x9C, 0x51, -+0x08, 0x31, 0xF1, 0xE7, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x4F, 0xF6, 0xFF, 0x71, 0xD0, 0xE7, 0x40, 0xF6, -+0xB4, 0x11, 0xCD, 0xE7, 0x70, 0x47, 0x00, 0xBF, 0xE4, 0xB8, 0x17, 0x00, 0xF0, 0xB4, 0x03, 0x46, 0x42, 0x48, 0x5C, 0x68, -+0x90, 0xF8, 0x75, 0x21, 0xA5, 0x06, 0x2E, 0xD5, 0x93, 0xF8, 0xFA, 0x70, 0x93, 0xF8, 0xFC, 0x50, 0x93, 0xF8, 0x01, 0x61, -+0x7C, 0x10, 0xFF, 0x06, 0x4F, 0xEA, 0xD5, 0x05, 0x55, 0xD5, 0x04, 0x24, 0x05, 0xEA, 0xD6, 0x16, 0x90, 0xF8, 0x74, 0x50, -+0xB3, 0xF8, 0xC8, 0x00, 0xB5, 0x42, 0x28, 0xBF, 0x35, 0x46, 0x94, 0x42, 0x28, 0xBF, 0x14, 0x46, 0x83, 0xF8, 0x2C, 0x41, -+0x91, 0xF8, 0xD9, 0x20, 0x04, 0x2A, 0x46, 0xD0, 0xA2, 0x42, 0x28, 0xBF, 0x22, 0x46, 0x04, 0x2A, 0x43, 0xD0, 0xD2, 0xB2, -+0x00, 0xF0, 0x0C, 0x00, 0x0C, 0x38, 0x83, 0xF8, 0x2D, 0x21, 0x83, 0xF8, 0x30, 0x51, 0x18, 0xBF, 0x01, 0x20, 0xF0, 0xBC, -+0x70, 0x47, 0x90, 0xF8, 0x74, 0x51, 0x60, 0x07, 0x13, 0xD5, 0xD3, 0xF8, 0xE8, 0x00, 0x00, 0xF0, 0x0C, 0x04, 0x04, 0x2C, -+0x44, 0xD0, 0x08, 0x2C, 0x0C, 0xBF, 0x04, 0x24, 0x02, 0x24, 0xC0, 0xF3, 0x02, 0x20, 0x04, 0x28, 0x27, 0xD8, 0x85, 0x42, -+0x28, 0xBF, 0x05, 0x46, 0xB3, 0xF8, 0xC8, 0x00, 0xCD, 0xE7, 0xB3, 0xF8, 0xC8, 0x00, 0x10, 0xF0, 0x02, 0x04, 0xC0, 0xF3, -+0x01, 0x26, 0x28, 0xD0, 0x01, 0x2A, 0x28, 0xBF, 0x01, 0x22, 0x83, 0xF8, 0x2C, 0x21, 0x14, 0x46, 0x91, 0xF8, 0xD9, 0x20, -+0xB5, 0x42, 0x28, 0xBF, 0x35, 0x46, 0x04, 0x2A, 0xC2, 0xD1, 0x02, 0x2C, 0x22, 0x46, 0x28, 0xBF, 0x02, 0x22, 0xD2, 0xB2, -+0xC2, 0xE7, 0x67, 0x07, 0x09, 0xD5, 0x03, 0x24, 0xA6, 0xE7, 0x04, 0x2C, 0xF3, 0xD1, 0x03, 0x22, 0xBA, 0xE7, 0xB3, 0xF8, -+0xC8, 0x00, 0x00, 0x25, 0xA7, 0xE7, 0xA6, 0x07, 0x47, 0xBF, 0x05, 0xF0, 0x01, 0x06, 0x02, 0x24, 0x04, 0xF0, 0x01, 0x04, -+0x05, 0xF0, 0x01, 0x06, 0x96, 0xE7, 0xB5, 0x42, 0x83, 0xF8, 0x2C, 0x41, 0x28, 0xBF, 0x35, 0x46, 0x22, 0x46, 0xA5, 0xE7, -+0x03, 0x24, 0xBC, 0xE7, 0xE4, 0xB8, 0x17, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x01, 0x28, 0x04, 0xD0, 0x02, 0x28, 0x14, 0xBF, -+0x07, 0x20, 0x09, 0x20, 0x70, 0x47, 0x08, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x00, 0xF0, 0x03, 0x00, 0x01, 0x28, 0x04, 0xD0, -+0x02, 0x28, 0x14, 0xBF, 0x07, 0x20, 0x0B, 0x20, 0x70, 0x47, 0x09, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x10, 0xB4, 0x0E, 0x22, -+0x04, 0x46, 0x07, 0x20, 0x44, 0xFA, 0x02, 0xF3, 0x03, 0xF0, 0x03, 0x03, 0x03, 0x2B, 0x00, 0xF1, 0xFF, 0x31, 0xA2, 0xF1, -+0x02, 0x02, 0x02, 0xD1, 0x11, 0xF0, 0xFF, 0x00, 0xF2, 0xD1, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0xC3, 0x78, 0x33, 0xB9, -+0x83, 0x78, 0x33, 0xB9, 0x40, 0x78, 0x00, 0x28, 0x18, 0xBF, 0x01, 0x20, 0x70, 0x47, 0x03, 0x20, 0x70, 0x47, 0x02, 0x20, -+0x70, 0x47, 0x00, 0xBF, 0x00, 0x23, 0x40, 0xFA, 0x03, 0xF2, 0x12, 0xF0, 0x01, 0x0F, 0xD9, 0xB2, 0x03, 0xF1, 0x01, 0x03, -+0x02, 0xD1, 0x0C, 0x2B, 0xF5, 0xD1, 0x19, 0x46, 0x08, 0x46, 0x70, 0x47, 0x68, 0xB1, 0x00, 0x23, 0xC3, 0xF1, 0x0B, 0x02, -+0x40, 0xFA, 0x02, 0xF2, 0xD2, 0x07, 0xD9, 0xB2, 0x03, 0xF1, 0x01, 0x03, 0x05, 0xD4, 0x0C, 0x2B, 0xF4, 0xD1, 0xFF, 0x20, -+0x70, 0x47, 0x0C, 0x20, 0x70, 0x47, 0xC1, 0xF1, 0x0B, 0x01, 0xC8, 0xB2, 0x70, 0x47, 0x00, 0xBF, 0xF0, 0xB5, 0xDD, 0xE9, -+0x05, 0x56, 0x00, 0x24, 0x1C, 0x80, 0x2C, 0x60, 0x34, 0x60, 0x50, 0xB3, 0x84, 0x78, 0xC4, 0xF3, 0x82, 0x0C, 0xBC, 0xF1, -+0x02, 0x0F, 0x04, 0xF0, 0x03, 0x04, 0x23, 0xDC, 0x4F, 0xF0, 0x01, 0x0C, 0x04, 0xF1, 0x0D, 0x00, 0x4F, 0xF0, 0x01, 0x0E, -+0x0E, 0xFA, 0x00, 0xF0, 0x07, 0x9F, 0x01, 0x38, 0x80, 0xB2, 0x87, 0xF8, 0x00, 0xC0, 0x18, 0x80, 0xF9, 0xB1, 0x09, 0x68, -+0xC1, 0xF3, 0xC2, 0x51, 0x01, 0xF1, 0x0D, 0x03, 0x0E, 0xFA, 0x03, 0xF3, 0x01, 0x3B, 0x2B, 0x60, 0x4A, 0xB1, 0x07, 0x29, -+0x11, 0xD1, 0xD3, 0x78, 0xC3, 0xF3, 0xC1, 0x03, 0x14, 0x33, 0x0E, 0xFA, 0x03, 0xF7, 0x01, 0x3F, 0x37, 0x60, 0xF0, 0xBD, -+0xAC, 0xF1, 0x03, 0x00, 0x4F, 0xF0, 0x01, 0x0C, 0x0C, 0xFA, 0x00, 0xFC, 0x5F, 0xFA, 0x8C, 0xFC, 0xD4, 0xE7, 0x33, 0x60, -+0xF0, 0xBD, 0x00, 0x2A, 0xF1, 0xD0, 0x03, 0x2C, 0x01, 0xD0, 0x30, 0x60, 0xF0, 0xBD, 0xD3, 0x78, 0xC3, 0xF3, 0xC1, 0x03, -+0x10, 0x33, 0x0E, 0xFA, 0x03, 0xF7, 0x01, 0x3F, 0x37, 0x60, 0xF0, 0xBD, 0x00, 0xF0, 0x7F, 0x03, 0x48, 0x2B, 0x31, 0xD8, -+0x10, 0xF0, 0x7E, 0x0F, 0x2C, 0xD0, 0x02, 0x3B, 0x46, 0x2B, 0x29, 0xD8, 0xDF, 0xE8, 0x03, 0xF0, 0x26, 0x28, 0x24, 0x28, -+0x28, 0x28, 0x28, 0x28, 0x28, 0x35, 0x37, 0x28, 0x28, 0x28, 0x28, 0x28, 0x39, 0x28, 0x28, 0x28, 0x3B, 0x28, 0x3D, 0x28, -+0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x3F, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, -+0x28, 0x28, 0x41, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, -+0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x33, 0x00, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0xFF, 0x20, 0x70, 0x47, -+0x60, 0x2B, 0x04, 0xD0, 0x6C, 0x2B, 0x14, 0xBF, 0xFF, 0x20, 0x0B, 0x20, 0x70, 0x47, 0x0A, 0x20, 0x70, 0x47, 0x09, 0x20, -+0x70, 0x47, 0x02, 0x20, 0x70, 0x47, 0x04, 0x20, 0x70, 0x47, 0x05, 0x20, 0x70, 0x47, 0x03, 0x20, 0x70, 0x47, 0x06, 0x20, -+0x70, 0x47, 0x07, 0x20, 0x70, 0x47, 0x08, 0x20, 0x70, 0x47, 0x00, 0xBF, 0x2D, 0xE9, 0xF8, 0x4F, 0x90, 0xF8, 0x00, 0xB0, -+0xBB, 0xF1, 0x00, 0x0F, 0x34, 0xD0, 0xDF, 0xF8, 0x70, 0x80, 0xDF, 0xF8, 0x70, 0xA0, 0xDF, 0xF8, 0x70, 0x90, 0x05, 0x46, -+0x0E, 0x46, 0x04, 0x46, 0x00, 0x27, 0x9E, 0xB9, 0x60, 0x78, 0xFF, 0xF7, 0x9B, 0xFF, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x4F, 0xF0, 0x01, 0x03, 0x0E, 0xDB, 0x0B, 0x28, 0x0E, 0xDD, 0x01, 0x34, 0x63, 0x1B, 0x5B, 0x45, -+0xED, 0xDB, 0x38, 0x46, 0xBD, 0xE8, 0xF8, 0x8F, 0x94, 0xF9, 0x01, 0x30, 0x60, 0x78, 0x00, 0x2B, 0xE7, 0xDB, 0xF2, 0xE7, -+0x0B, 0x28, 0x04, 0xDC, 0x03, 0xFA, 0x00, 0xF0, 0x07, 0x43, 0xBF, 0xB2, 0xEB, 0xE7, 0x4F, 0xF4, 0x15, 0x72, 0x51, 0x46, -+0x48, 0x46, 0xFD, 0xF7, 0xC5, 0xF9, 0x95, 0xF8, 0x00, 0xB0, 0xE2, 0xE7, 0x5F, 0x46, 0x38, 0x46, 0xBD, 0xE8, 0xF8, 0x8F, -+0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x94, 0xB8, 0x15, 0x00, 0xF0, 0xB4, 0x00, 0x24, 0x4F, 0xF6, 0xFF, 0x77, -+0x03, 0x26, 0x40, 0xFA, 0x04, 0xF3, 0x03, 0xF0, 0x03, 0x03, 0x06, 0xFA, 0x04, 0xF2, 0x41, 0xFA, 0x04, 0xF5, 0x03, 0x2B, -+0x27, 0xEA, 0x02, 0x02, 0x05, 0xF0, 0x03, 0x05, 0x0A, 0xD0, 0x03, 0x2D, 0x08, 0xD0, 0xAB, 0x42, 0x28, 0xBF, 0x2B, 0x46, -+0xA3, 0x40, 0x02, 0x34, 0x1A, 0x43, 0x10, 0x2C, 0x97, 0xB2, 0xE6, 0xD1, 0x38, 0x46, 0xF0, 0xBC, 0x70, 0x47, 0x00, 0xBF, -+0x08, 0x4B, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x00, 0x30, 0x41, 0xF2, 0x21, 0x42, 0xD0, 0xF8, 0x90, 0x31, 0x98, 0x78, -+0x41, 0xF2, 0x21, 0x53, 0x01, 0x28, 0x14, 0xBF, 0x10, 0x46, 0x18, 0x46, 0x70, 0x47, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, -+0xD0, 0xF8, 0xDC, 0x30, 0xC3, 0xF3, 0x05, 0x60, 0x5B, 0x00, 0x54, 0xBF, 0x40, 0xF4, 0x80, 0x70, 0x40, 0xF4, 0x40, 0x70, -+0x70, 0x47, 0x00, 0xBF, 0x10, 0xB5, 0x04, 0x46, 0x0C, 0xF0, 0x86, 0xFB, 0x03, 0x4B, 0x20, 0x46, 0xD3, 0xF8, 0x5C, 0x31, -+0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x38, 0xB5, 0x16, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x05, 0x46, 0x90, 0xF8, 0xB8, 0x00, 0x18, 0xDB, 0x68, 0xB1, 0x05, 0xF1, 0xB8, 0x03, 0x1C, 0x18, -+0x00, 0x20, 0x13, 0xF8, 0x01, 0x2F, 0x22, 0xF0, 0x80, 0x01, 0x81, 0x42, 0xC8, 0xBF, 0x02, 0xF0, 0x7F, 0x00, 0xA3, 0x42, -+0xF5, 0xD1, 0xFF, 0xF7, 0xFF, 0xFE, 0x01, 0x46, 0x28, 0x46, 0x0C, 0xF0, 0x5F, 0xF9, 0x00, 0x23, 0x85, 0xF8, 0x56, 0x31, -+0x38, 0xBD, 0x00, 0x28, 0xE5, 0xD1, 0x05, 0x48, 0x05, 0x49, 0x40, 0xF2, 0xC1, 0x22, 0xFD, 0xF7, 0x25, 0xF9, 0x95, 0xF8, -+0xB8, 0x00, 0xDB, 0xE7, 0x38, 0x36, 0x17, 0x00, 0xB0, 0xB8, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x90, 0xF8, 0x56, 0x31, 0xD0, 0xF8, 0x48, 0x71, 0x99, 0xB0, 0x00, 0x2B, 0x00, 0xF0, 0xDB, 0x80, 0xFA, 0x6B, 0x09, 0x92, -+0x7A, 0x68, 0x05, 0x92, 0x07, 0xF1, 0x14, 0x04, 0xBA, 0x68, 0x07, 0x92, 0x10, 0xAE, 0x0D, 0xF1, 0x50, 0x08, 0x05, 0x46, -+0x22, 0x46, 0xB4, 0x46, 0x40, 0x46, 0x07, 0xF1, 0x24, 0x0B, 0x52, 0xF8, 0x04, 0x1B, 0x4C, 0xF8, 0x04, 0x1B, 0x5A, 0x45, -+0xD1, 0x68, 0x40, 0xF8, 0x04, 0x1B, 0xF6, 0xD1, 0x13, 0xF0, 0x01, 0x02, 0x06, 0x92, 0x40, 0xF0, 0xC0, 0x80, 0x09, 0x9A, -+0xC2, 0xF3, 0xC0, 0x02, 0x06, 0x92, 0x9A, 0x06, 0x00, 0xF1, 0x16, 0x81, 0x98, 0x07, 0x1A, 0xD5, 0xDF, 0xF8, 0x64, 0x93, -+0x06, 0xF1, 0x10, 0x0E, 0x31, 0x46, 0x51, 0xF8, 0x04, 0x2B, 0xC2, 0xF3, 0xC2, 0x2A, 0x02, 0xF0, 0x7C, 0x00, 0x5A, 0xEA, -+0x00, 0x00, 0xC2, 0xF3, 0xC1, 0x1C, 0x02, 0xEA, 0x09, 0x02, 0x06, 0xD0, 0xD5, 0xF8, 0x50, 0x01, 0x02, 0x43, 0x42, 0xEA, -+0x0C, 0x62, 0x41, 0xF8, 0x04, 0x2C, 0x8E, 0x45, 0xE9, 0xD1, 0xD9, 0x06, 0x5C, 0xD5, 0x95, 0xF8, 0x22, 0x10, 0xC3, 0x4A, -+0xC3, 0x4B, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x01, 0x20, 0xD3, 0xF8, 0x38, 0x33, 0x0D, 0xF1, 0x3F, 0x02, 0x0D, 0xF1, -+0x3E, 0x01, 0x98, 0x47, 0x06, 0xF1, 0x10, 0x03, 0x06, 0x94, 0x08, 0x95, 0x0D, 0xF1, 0x50, 0x09, 0x1C, 0x46, 0x35, 0x46, -+0xBA, 0x4B, 0x59, 0xF8, 0x04, 0xAB, 0x55, 0xF8, 0x04, 0x1B, 0x93, 0xF8, 0xBD, 0x30, 0x4F, 0xEA, 0x1A, 0x4A, 0xC1, 0xF3, -+0xC7, 0x22, 0xC1, 0xF3, 0xC2, 0x20, 0x5F, 0xFA, 0x81, 0xFC, 0x4F, 0xEA, 0x0A, 0x4A, 0x01, 0xF0, 0x7F, 0x01, 0xD3, 0xB9, -+0x0C, 0xF0, 0x7C, 0x0C, 0x50, 0xEA, 0x0C, 0x03, 0x00, 0xF0, 0x29, 0x81, 0xAD, 0x4B, 0x93, 0xF8, 0xBA, 0x30, 0x00, 0x2B, -+0x00, 0xF0, 0xF3, 0x80, 0xAB, 0x4B, 0x93, 0xF8, 0x2A, 0x30, 0x00, 0x2B, 0x40, 0xF0, 0xED, 0x80, 0x00, 0x28, 0x40, 0xF0, -+0x2F, 0x81, 0x09, 0x29, 0x00, 0xF2, 0x2C, 0x81, 0x02, 0xF0, 0x06, 0x02, 0x2D, 0xE1, 0xD9, 0xF7, 0x47, 0xFE, 0xA4, 0x4B, -+0x1A, 0x7D, 0x00, 0x2A, 0x00, 0xF0, 0x06, 0x81, 0x5A, 0x7D, 0x00, 0x2A, 0x00, 0xF0, 0x02, 0x81, 0x4A, 0xEA, 0x00, 0x20, -+0x40, 0xF0, 0xA8, 0x00, 0x49, 0xF8, 0x04, 0x0C, 0xAC, 0x42, 0xBD, 0xD1, 0x08, 0x9D, 0x06, 0x9C, 0x95, 0xF8, 0x56, 0x31, -+0x5A, 0x06, 0x13, 0xD5, 0x94, 0x4A, 0x95, 0xF8, 0x22, 0x30, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x23, 0x07, 0x9A, -+0xD3, 0xF8, 0xC8, 0x31, 0x22, 0xF0, 0x7C, 0x72, 0x00, 0x2B, 0x07, 0x92, 0x04, 0xDB, 0xC3, 0xF3, 0x05, 0x63, 0x42, 0xEA, -+0x03, 0x53, 0x07, 0x93, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x8D, 0x4B, 0x01, 0x22, 0x1A, 0x60, -+0x8C, 0x4A, 0x05, 0x9B, 0x11, 0x68, 0x7B, 0x60, 0x48, 0x1C, 0x07, 0x9B, 0xBB, 0x60, 0x10, 0x60, 0x56, 0xF8, 0x04, 0x3B, -+0x44, 0xF8, 0x04, 0x3B, 0x58, 0xF8, 0x04, 0x3B, 0xE3, 0x60, 0xA3, 0x45, 0xF6, 0xD1, 0x28, 0xB1, 0x82, 0x4B, 0x11, 0x60, -+0x1B, 0x68, 0x09, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x00, 0x23, 0x85, 0xF8, 0x56, 0x31, 0x38, 0x46, 0x19, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0xD5, 0xF8, 0x4C, 0x01, 0x95, 0xF8, 0x30, 0x21, 0x0D, 0x92, 0xCD, 0xE9, 0x0B, 0x34, 0x00, 0x22, 0x08, 0x92, -+0x00, 0xF1, 0x88, 0x0E, 0x0A, 0x92, 0x31, 0x46, 0x82, 0x46, 0x3E, 0xF8, 0x02, 0x3B, 0x03, 0xEB, 0x43, 0x03, 0x0A, 0xEB, -+0x83, 0x03, 0x58, 0x89, 0xC0, 0xF3, 0x0D, 0x03, 0x43, 0xF0, 0x80, 0x43, 0x4F, 0xEA, 0xD3, 0x29, 0x19, 0xF0, 0x06, 0x0C, -+0x00, 0xF0, 0x8E, 0x80, 0x09, 0xF0, 0x07, 0x09, 0xB9, 0xF1, 0x04, 0x0F, 0x03, 0xF0, 0x7F, 0x0C, 0x00, 0xF0, 0xE5, 0x80, -+0xB9, 0xF1, 0x05, 0x0F, 0x00, 0xF0, 0xE4, 0x80, 0xCC, 0xF3, 0xC1, 0x0C, 0x00, 0x2A, 0x00, 0xF0, 0xD1, 0x80, 0x08, 0x98, -+0x00, 0x28, 0x40, 0xF0, 0x95, 0x80, 0x08, 0x68, 0x20, 0xF0, 0x60, 0x40, 0x20, 0xF4, 0x7F, 0x50, 0x20, 0xF0, 0x3F, 0x00, -+0x18, 0x43, 0x08, 0x60, 0x01, 0x32, 0x04, 0x2A, 0x01, 0xF1, 0x04, 0x01, 0xCB, 0xD1, 0x05, 0x9A, 0x22, 0xF4, 0xC0, 0x71, -+0x08, 0x9A, 0x05, 0x91, 0xDD, 0xE9, 0x0B, 0x34, 0x22, 0xB1, 0x0A, 0x9A, 0x01, 0x32, 0x41, 0xEA, 0xC2, 0x12, 0x05, 0x92, -+0x06, 0x9A, 0x00, 0x2A, 0x7E, 0xD1, 0x09, 0x9A, 0x22, 0xF0, 0x08, 0x02, 0x43, 0xF0, 0x02, 0x03, 0xFA, 0x63, 0x9A, 0x06, -+0x85, 0xF8, 0x56, 0x31, 0x7F, 0xF5, 0xEA, 0xAE, 0xD5, 0xF8, 0x4C, 0x01, 0x7A, 0x69, 0x90, 0xF8, 0xA0, 0x30, 0xDF, 0xF8, -+0x38, 0xE1, 0x05, 0x99, 0x03, 0xEB, 0x43, 0x03, 0x00, 0xEB, 0x83, 0x03, 0x0E, 0xEA, 0x02, 0x0E, 0xB3, 0xF8, 0x0A, 0xC0, -+0xCC, 0xF3, 0x0D, 0x02, 0xC1, 0xF3, 0xC1, 0x13, 0x42, 0xF0, 0x80, 0x42, 0x11, 0xF4, 0xC0, 0x7F, 0xCC, 0xF3, 0x80, 0x3C, -+0x4E, 0xEA, 0x02, 0x01, 0x03, 0xF1, 0xFF, 0x33, 0xDB, 0xB2, 0x80, 0xF8, 0xA1, 0xC0, 0xC0, 0xF8, 0x9C, 0x10, 0x4F, 0xF0, -+0x00, 0x02, 0x06, 0x98, 0x00, 0x93, 0x03, 0x90, 0x14, 0xBF, 0x01, 0x23, 0x13, 0x46, 0xCD, 0xE9, 0x01, 0x22, 0x38, 0x46, -+0x0C, 0xF0, 0x56, 0xFF, 0x95, 0xF8, 0x56, 0x31, 0xB6, 0xE6, 0x9D, 0xF8, 0x3F, 0x00, 0x40, 0xEA, 0x00, 0x20, 0x40, 0xEA, -+0x0A, 0x00, 0x02, 0xF0, 0x06, 0x02, 0x49, 0xF8, 0x04, 0x0C, 0x00, 0x2A, 0x3F, 0xF4, 0x20, 0xAF, 0x09, 0x29, 0x7F, 0xF6, -+0x1D, 0xAF, 0x29, 0x4B, 0x59, 0xF8, 0x04, 0x2C, 0x93, 0xF8, 0xAF, 0x10, 0x12, 0x0C, 0x41, 0xEA, 0x01, 0x21, 0x12, 0x04, -+0x0A, 0x43, 0x49, 0xF8, 0x04, 0x2C, 0x0F, 0xE7, 0x08, 0x68, 0xCD, 0xF8, 0x18, 0xC0, 0x20, 0xF0, 0x60, 0x40, 0x20, 0xF4, -+0x7F, 0x50, 0x20, 0xF0, 0x3F, 0x00, 0x18, 0x43, 0x08, 0x60, 0x83, 0xE7, 0x40, 0xEA, 0x00, 0x20, 0x40, 0xEA, 0x0A, 0x00, -+0x49, 0xF8, 0x04, 0x0C, 0xFC, 0xE6, 0x9D, 0xF8, 0x3E, 0x20, 0x42, 0xEA, 0x02, 0x22, 0x42, 0xEA, 0x0A, 0x02, 0x49, 0xF8, -+0x04, 0x2C, 0xF3, 0xE6, 0x0A, 0x98, 0xAC, 0xEB, 0x00, 0x00, 0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x08, 0x90, 0x62, 0xE7, -+0x09, 0x9A, 0x42, 0xF0, 0x08, 0x02, 0x7F, 0xE7, 0x12, 0xF0, 0x06, 0x02, 0x0B, 0xD0, 0x04, 0x29, 0x09, 0xD8, 0x0C, 0x4B, -+0x93, 0xF8, 0xBB, 0x00, 0x40, 0xEA, 0x00, 0x20, 0x40, 0xEA, 0x0A, 0x00, 0x49, 0xF8, 0x04, 0x0C, 0xB5, 0xE7, 0x07, 0x4B, -+0xB3, 0xF8, 0xBB, 0x00, 0x40, 0xBA, 0x80, 0xB2, 0x40, 0xEA, 0x0A, 0x00, 0x49, 0xF8, 0x04, 0x0C, 0xAB, 0xE7, 0x00, 0xBF, -+0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0xBC, 0x34, 0x17, 0x00, 0x4C, 0x36, 0x17, 0x00, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0xFF, 0x3F, 0x00, 0xE0, 0x00, 0xC0, 0xFF, 0x1F, 0x0D, 0x98, 0x84, 0x45, -+0x0A, 0x98, 0x38, 0xBF, 0x60, 0x46, 0x0A, 0x90, 0x08, 0x98, 0x38, 0xBF, 0x01, 0x20, 0x08, 0x90, 0x27, 0xE7, 0x4F, 0xEA, -+0x1C, 0x1C, 0x1D, 0xE7, 0x14, 0xAC, 0x03, 0xF4, 0xC0, 0x69, 0x54, 0xF8, 0x22, 0x40, 0xB9, 0xF5, 0x80, 0x6F, 0x0C, 0xBF, -+0x4F, 0xF4, 0x00, 0x39, 0x4F, 0xF4, 0x80, 0x39, 0x24, 0xF4, 0x40, 0x34, 0x44, 0xEA, 0x09, 0x09, 0x40, 0x04, 0x14, 0xAC, -+0x4C, 0xBF, 0x49, 0xF4, 0x80, 0x20, 0x29, 0xF4, 0x80, 0x20, 0x44, 0xF8, 0x22, 0x00, 0x4F, 0xEA, 0x1C, 0x1C, 0x01, 0xE7, -+0xF0, 0xB4, 0xD2, 0xF8, 0xA4, 0x50, 0x2C, 0x88, 0x30, 0xBB, 0x00, 0x29, 0x44, 0xD0, 0x51, 0x4E, 0x03, 0x46, 0x96, 0xF8, -+0x75, 0x01, 0x26, 0x46, 0x01, 0x28, 0x4F, 0xD9, 0x8F, 0x78, 0x17, 0xF0, 0x03, 0x07, 0x3C, 0xD0, 0xAD, 0x78, 0xCB, 0x78, -+0x09, 0x79, 0x00, 0x2D, 0x41, 0xD1, 0x5E, 0x1E, 0x0D, 0x2E, 0x40, 0xD8, 0x0E, 0x2B, 0x00, 0xF0, 0x86, 0x80, 0x03, 0xEB, -+0x83, 0x03, 0x03, 0xF6, 0x67, 0x13, 0x00, 0x29, 0x47, 0xD0, 0x03, 0x2F, 0x60, 0xD0, 0x02, 0x2F, 0x57, 0xD0, 0x02, 0x20, -+0x1C, 0x46, 0x00, 0x21, 0x03, 0x46, 0x05, 0xE0, 0x3E, 0x4B, 0x93, 0xF8, 0x75, 0x31, 0x5B, 0xB9, 0x18, 0x46, 0x00, 0x21, -+0xA2, 0xF8, 0xA8, 0x40, 0x82, 0xF8, 0xD8, 0x30, 0xF0, 0xBC, 0x82, 0xF8, 0xD9, 0x00, 0xA2, 0xF8, 0xAA, 0x10, 0x70, 0x47, -+0xC0, 0x78, 0x10, 0xF0, 0x03, 0x00, 0x12, 0xD0, 0x01, 0x28, 0x4F, 0xF6, 0xF6, 0x76, 0x08, 0xBF, 0x0A, 0x26, 0x26, 0x44, -+0xB6, 0xB2, 0x51, 0xBB, 0x01, 0x23, 0x34, 0x46, 0x18, 0x46, 0xE5, 0xE7, 0x08, 0x46, 0x0B, 0x46, 0xE2, 0xE7, 0x34, 0x46, -+0x39, 0x46, 0x18, 0x46, 0xDE, 0xE7, 0x99, 0xB1, 0x1F, 0x46, 0x26, 0x46, 0x03, 0x46, 0x38, 0x46, 0xB2, 0xE7, 0x01, 0x2D, -+0x1A, 0xD0, 0x4F, 0xF6, 0xFF, 0x73, 0xC2, 0xE7, 0x34, 0x46, 0xCF, 0xE7, 0x4F, 0xF6, 0xD8, 0x71, 0x9C, 0x42, 0x94, 0xBF, -+0x0C, 0x46, 0x28, 0x24, 0x23, 0x44, 0x9C, 0xB2, 0x03, 0x46, 0x00, 0x21, 0xC6, 0xE7, 0x02, 0x2F, 0x11, 0xD0, 0x03, 0x2F, -+0x20, 0xD0, 0x02, 0x20, 0x1C, 0x46, 0x03, 0x46, 0xBE, 0xE7, 0x18, 0x46, 0x01, 0x23, 0x95, 0xE7, 0x5E, 0x1E, 0xA4, 0x2E, -+0xE1, 0xD8, 0x03, 0xEB, 0x83, 0x03, 0x03, 0xF5, 0x9C, 0x53, 0x08, 0x33, 0xA1, 0xE7, 0x02, 0x28, 0xDE, 0xD0, 0x03, 0x20, -+0x1C, 0x46, 0x00, 0x21, 0x03, 0x46, 0xAB, 0xE7, 0x85, 0xB9, 0x4C, 0x1E, 0x0D, 0x2C, 0x0A, 0xD8, 0x0E, 0x29, 0x19, 0xD0, -+0x01, 0xEB, 0x81, 0x01, 0x01, 0xF6, 0x67, 0x11, 0x04, 0x28, 0x94, 0xD1, 0x1C, 0x46, 0x03, 0x23, 0x9C, 0xE7, 0x4F, 0xF6, -+0xFF, 0x71, 0xF7, 0xE7, 0x01, 0x2D, 0xFA, 0xD1, 0x4C, 0x1E, 0xA4, 0x2C, 0xF7, 0xD8, 0x01, 0xEB, 0x81, 0x01, 0x01, 0xF5, -+0x9C, 0x51, 0x08, 0x31, 0xEC, 0xE7, 0x40, 0xF6, 0xB4, 0x13, 0x7A, 0xE7, 0x40, 0xF6, 0xB4, 0x11, 0xE6, 0xE7, 0x00, 0xBF, -+0xE4, 0xB8, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0x7B, 0x4F, 0xDF, 0xF8, 0x08, 0x92, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, -+0x00, 0x73, 0x04, 0x46, 0x93, 0xF8, 0x22, 0x60, 0x58, 0x68, 0x77, 0x4B, 0x1B, 0x68, 0x10, 0xF0, 0x20, 0x0A, 0xB3, 0xF9, -+0x00, 0x30, 0x0D, 0x46, 0x90, 0x46, 0x4F, 0xD0, 0x00, 0x2B, 0xC0, 0xF2, 0x9F, 0x80, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, -+0x04, 0x73, 0x0E, 0x21, 0xB3, 0xF8, 0x06, 0xC1, 0x07, 0x22, 0x4C, 0xFA, 0x01, 0xF3, 0x03, 0xF0, 0x03, 0x03, 0x03, 0x2B, -+0x02, 0xF1, 0xFF, 0x30, 0xA1, 0xF1, 0x02, 0x01, 0x40, 0xF0, 0xB3, 0x80, 0x10, 0xF0, 0xFF, 0x02, 0xF1, 0xD1, 0x90, 0x46, -+0xB9, 0xF8, 0x50, 0xC0, 0x0E, 0x21, 0x07, 0x22, 0x4C, 0xFA, 0x01, 0xF3, 0x03, 0xF0, 0x03, 0x03, 0x03, 0x2B, 0x02, 0xF1, -+0xFF, 0x30, 0xA1, 0xF1, 0x02, 0x01, 0x40, 0xF0, 0x9B, 0x80, 0x10, 0xF0, 0xFF, 0x02, 0xF1, 0xD1, 0x5D, 0x4B, 0x4F, 0xF4, -+0x1E, 0x70, 0x00, 0xFB, 0x04, 0x74, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x06, 0x36, 0x94, 0xF8, 0x2C, 0x31, 0x96, 0xF8, -+0xC4, 0x11, 0x94, 0xF8, 0x23, 0x00, 0x04, 0x2B, 0x08, 0xBF, 0x03, 0x23, 0xA9, 0x42, 0x28, 0xBF, 0x29, 0x46, 0x99, 0x42, -+0x28, 0xBF, 0x19, 0x46, 0x84, 0xF8, 0x2D, 0x11, 0x0B, 0xF0, 0x22, 0xFD, 0x94, 0xF8, 0x56, 0x31, 0x43, 0xF0, 0x08, 0x03, -+0x84, 0xF8, 0x56, 0x31, 0xBD, 0xE8, 0xF8, 0x8F, 0x10, 0xF0, 0x04, 0x0B, 0x28, 0xD0, 0x00, 0x2B, 0x58, 0xDB, 0x4F, 0xF4, -+0x1E, 0x73, 0x03, 0xFB, 0x04, 0x73, 0x0E, 0x22, 0xB3, 0xF8, 0xEC, 0xC0, 0x07, 0x20, 0x4C, 0xFA, 0x02, 0xF3, 0x03, 0xF0, -+0x03, 0x03, 0x03, 0x2B, 0x00, 0xF1, 0xFF, 0x31, 0xA2, 0xF1, 0x02, 0x02, 0x6A, 0xD1, 0x11, 0xF0, 0xFF, 0x00, 0xF2, 0xD1, -+0xB9, 0xF8, 0x38, 0xC0, 0x0E, 0x21, 0x07, 0x22, 0x4C, 0xFA, 0x01, 0xF3, 0x03, 0xF0, 0x03, 0x03, 0x03, 0x2B, 0x02, 0xF1, -+0xFF, 0x30, 0xA1, 0xF1, 0x02, 0x01, 0x54, 0xD1, 0x10, 0xF0, 0xFF, 0x02, 0xF2, 0xD1, 0xAF, 0xE7, 0x00, 0x2B, 0x3A, 0xDB, -+0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x04, 0x73, 0x03, 0xF1, 0xCB, 0x02, 0x93, 0xF8, 0xCE, 0x30, 0x00, 0x2B, 0x54, 0xD1, -+0x93, 0x78, 0x00, 0x2B, 0x4B, 0xD1, 0x53, 0x78, 0x01, 0x20, 0x00, 0x2B, 0x48, 0xD1, 0x99, 0xF8, 0x12, 0x30, 0x00, 0x2B, -+0x4B, 0xD1, 0x99, 0xF8, 0x11, 0x30, 0x00, 0x2B, 0x49, 0xD1, 0x99, 0xF8, 0x10, 0x20, 0x00, 0x3A, 0x18, 0xBF, 0x01, 0x22, -+0x93, 0x45, 0x58, 0x46, 0x28, 0xBF, 0x10, 0x46, 0xC2, 0xB2, 0x89, 0xE7, 0x99, 0xF8, 0x76, 0x31, 0x59, 0x07, 0x3F, 0xF5, -+0x5C, 0xAF, 0x21, 0x49, 0x21, 0x48, 0x40, 0xF2, 0x55, 0x52, 0xFC, 0xF7, 0x99, 0xFD, 0x54, 0xE7, 0x99, 0xF8, 0x76, 0x31, -+0x9A, 0x07, 0xA2, 0xD4, 0x1B, 0x49, 0x1D, 0x48, 0x40, 0xF2, 0x62, 0x52, 0xFC, 0xF7, 0x8E, 0xFD, 0x9B, 0xE7, 0x99, 0xF8, -+0x76, 0x31, 0xDB, 0x07, 0xC0, 0xD4, 0x16, 0x49, 0x18, 0x48, 0x40, 0xF2, 0x6D, 0x52, 0xFC, 0xF7, 0x83, 0xFD, 0xB9, 0xE7, -+0x42, 0x45, 0x28, 0xBF, 0x42, 0x46, 0xD2, 0xB2, 0x62, 0xE7, 0x90, 0x45, 0x28, 0xBF, 0x90, 0x46, 0x4C, 0xE7, 0x52, 0x45, -+0x28, 0xBF, 0x52, 0x46, 0xD2, 0xB2, 0x59, 0xE7, 0x40, 0x45, 0x28, 0xBF, 0x40, 0x46, 0x82, 0x46, 0x92, 0xE7, 0x02, 0x20, -+0x80, 0x45, 0x28, 0xBF, 0x80, 0x46, 0xC3, 0x46, 0xB1, 0xE7, 0x03, 0x20, 0xF8, 0xE7, 0x03, 0x22, 0xBA, 0xE7, 0x02, 0x22, -+0xB8, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xC4, 0xB8, 0x15, 0x00, 0xD4, 0xB8, 0x15, 0x00, 0xE4, 0xB8, 0x15, 0x00, 0xE4, 0xB8, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x2D, 0xED, 0x02, 0x8B, 0xDF, 0xF8, 0xE4, 0xA3, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x00, 0xF3, 0x0A, 0xEB, 0x03, 0x06, -+0x8B, 0xB0, 0xB6, 0xF8, 0xC2, 0x41, 0x02, 0x93, 0x01, 0x90, 0xD6, 0xF8, 0x90, 0x31, 0x96, 0xF8, 0xC6, 0x51, 0x04, 0x95, -+0x00, 0x20, 0xA6, 0xF8, 0xC2, 0x01, 0x98, 0x78, 0x02, 0x9D, 0xD6, 0xF8, 0xC8, 0x31, 0x03, 0x94, 0x03, 0xF0, 0x7F, 0x43, -+0x05, 0xF1, 0xEC, 0x0C, 0x24, 0x32, 0x05, 0x93, 0x0A, 0xEB, 0x0C, 0x03, 0xD6, 0xF8, 0xE4, 0x40, 0x96, 0xF8, 0xC5, 0x71, -+0x08, 0xEE, 0x10, 0x2A, 0x08, 0xEE, 0x90, 0x3A, 0xA1, 0xF1, 0x24, 0x09, 0x00, 0x28, 0x00, 0xF0, 0xDD, 0x81, 0x1F, 0xFA, -+0x89, 0xF8, 0x01, 0x9B, 0x4F, 0xF4, 0xA4, 0x69, 0x09, 0xFB, 0x03, 0xA9, 0xD9, 0xF8, 0xCC, 0x31, 0xDD, 0x07, 0x05, 0xD5, -+0x99, 0xF8, 0x62, 0xB0, 0xBB, 0xF1, 0x00, 0x0F, 0x00, 0xF0, 0x5C, 0x82, 0xD2, 0x4B, 0x93, 0xF8, 0x76, 0xB1, 0x1B, 0xF0, -+0x01, 0x0B, 0x40, 0xF0, 0xE9, 0x81, 0xD9, 0x46, 0x48, 0x46, 0x18, 0xEE, 0x90, 0x2A, 0x59, 0x46, 0xFF, 0xF7, 0xF8, 0xFD, -+0x02, 0x9B, 0x03, 0xF2, 0xB4, 0x43, 0x18, 0xEE, 0x10, 0x0A, 0x53, 0x44, 0x0D, 0xF1, 0x25, 0x02, 0x41, 0x46, 0xFD, 0xF7, -+0xD5, 0xFF, 0x10, 0xF0, 0xFF, 0x09, 0x1F, 0xD0, 0x01, 0x9B, 0x4F, 0xF4, 0xA4, 0x6B, 0x0B, 0xFB, 0x03, 0xAB, 0x9B, 0xF8, -+0x62, 0x30, 0x00, 0x2B, 0x40, 0xF0, 0x9D, 0x81, 0x9B, 0xF8, 0x8A, 0x10, 0x00, 0x29, 0x00, 0xF0, 0x6F, 0x82, 0x89, 0x45, -+0x07, 0xD0, 0x01, 0x9A, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0xA3, 0x01, 0x22, 0x83, 0xF8, 0x8C, 0x20, 0x01, 0x9A, -+0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0xA3, 0x83, 0xF8, 0x8A, 0x90, 0x18, 0xEE, 0x90, 0x2A, 0x41, 0x46, 0x18, 0xEE, -+0x10, 0x0A, 0xFD, 0xF7, 0x25, 0xFF, 0x01, 0x9A, 0x04, 0x99, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0xA3, 0x93, 0xF8, -+0xC6, 0x21, 0x8A, 0x42, 0x0E, 0xD0, 0xD3, 0xF8, 0x90, 0x11, 0xAC, 0x4B, 0x09, 0x79, 0xD3, 0xF8, 0x40, 0x33, 0x8A, 0x1A, -+0x8D, 0xF8, 0x26, 0x20, 0x0D, 0xF1, 0x26, 0x01, 0x0D, 0xF1, 0x27, 0x02, 0x30, 0x46, 0x98, 0x47, 0x01, 0x9B, 0x4F, 0xF4, -+0xA4, 0x68, 0x08, 0xFB, 0x03, 0xA8, 0x98, 0xF8, 0xC5, 0x31, 0xBB, 0x42, 0x00, 0xF2, 0x01, 0x81, 0x00, 0x2C, 0x00, 0xF0, -+0x8E, 0x80, 0x01, 0x9B, 0x9F, 0x4E, 0x03, 0x9D, 0xDD, 0xF8, 0x14, 0x90, 0x4F, 0xF4, 0xA4, 0x68, 0x08, 0xFB, 0x03, 0xA8, -+0xB8, 0xF8, 0xC2, 0x21, 0xAA, 0x42, 0x1D, 0xD0, 0x29, 0x46, 0x30, 0x46, 0xFC, 0xF7, 0x1A, 0xFA, 0x94, 0xF8, 0x56, 0x31, -+0xB8, 0xF8, 0xC2, 0x21, 0x94, 0xF8, 0x23, 0x00, 0x43, 0xF0, 0x02, 0x03, 0x84, 0xF8, 0x56, 0x31, 0x53, 0x07, 0x4F, 0xF0, -+0x00, 0x01, 0x58, 0xBF, 0x4F, 0xF4, 0x80, 0x63, 0xC4, 0xF8, 0x50, 0x11, 0x4E, 0xBF, 0xA4, 0xF8, 0x54, 0x11, 0xA4, 0xF8, -+0x54, 0x31, 0x01, 0x21, 0x0B, 0xF0, 0x02, 0xFC, 0x98, 0xF8, 0xC5, 0x31, 0xBB, 0x42, 0x4B, 0xD0, 0x04, 0x2B, 0x94, 0xF8, -+0x2C, 0xA1, 0x5F, 0xD0, 0x53, 0x45, 0x28, 0xBF, 0x53, 0x46, 0x04, 0x2B, 0x00, 0xF0, 0x93, 0x80, 0x5F, 0xFA, 0x83, 0xFA, -+0x94, 0xF8, 0x2D, 0x31, 0x53, 0x45, 0x3B, 0xD0, 0x63, 0x68, 0x13, 0xF0, 0x20, 0x0B, 0x58, 0xD0, 0x7F, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xA7, 0x80, 0xB4, 0xF8, 0x06, 0xC1, 0x0E, 0x22, 0x07, 0x20, 0x4C, 0xFA, -+0x02, 0xF3, 0x03, 0xF0, 0x03, 0x03, 0x03, 0x2B, 0x00, 0xF1, 0xFF, 0x31, 0xA2, 0xF1, 0x02, 0x02, 0x02, 0xD1, 0x11, 0xF0, -+0xFF, 0x00, 0xF2, 0xD1, 0x70, 0x4B, 0x07, 0x22, 0xB3, 0xF8, 0x50, 0xE0, 0x0E, 0x23, 0x4E, 0xFA, 0x03, 0xF1, 0x01, 0xF0, -+0x03, 0x01, 0x03, 0x29, 0x02, 0xF1, 0xFF, 0x3C, 0xA3, 0xF1, 0x02, 0x03, 0x40, 0xF0, 0xF4, 0x80, 0x1C, 0xF0, 0xFF, 0x02, -+0xF1, 0xD1, 0x94, 0xF8, 0x23, 0x00, 0x84, 0xF8, 0x2D, 0xA1, 0x51, 0x46, 0x0B, 0xF0, 0x54, 0xFB, 0x94, 0xF8, 0x56, 0x31, -+0x43, 0xF0, 0x08, 0x03, 0x84, 0xF8, 0x56, 0x31, 0xD8, 0xF8, 0xC8, 0x31, 0x03, 0xF0, 0x7F, 0x43, 0x4B, 0x45, 0x08, 0xD0, -+0x63, 0x68, 0x9B, 0x06, 0x05, 0xD5, 0x94, 0xF8, 0x56, 0x31, 0x43, 0xF0, 0x40, 0x03, 0x84, 0xF8, 0x56, 0x31, 0x24, 0x68, -+0x00, 0x2C, 0x7F, 0xF4, 0x7B, 0xAF, 0x0B, 0xB0, 0xBD, 0xEC, 0x02, 0x8B, 0xBD, 0xE8, 0xF0, 0x8F, 0xBA, 0xF1, 0x03, 0x0F, -+0x35, 0xD8, 0xBA, 0xF1, 0x02, 0x0F, 0x28, 0xBF, 0x4F, 0xF0, 0x02, 0x0A, 0x9E, 0xE7, 0x13, 0xF0, 0x04, 0x0F, 0x52, 0x4B, -+0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x2B, 0xD0, 0x00, 0x2B, 0xC0, 0xF2, 0xA7, 0x80, 0xB4, 0xF8, 0xEC, 0xC0, 0x0E, 0x22, -+0x07, 0x20, 0x4C, 0xFA, 0x02, 0xF3, 0x03, 0xF0, 0x03, 0x03, 0x03, 0x2B, 0x00, 0xF1, 0xFF, 0x31, 0xA2, 0xF1, 0x02, 0x02, -+0x40, 0xF0, 0x97, 0x81, 0x11, 0xF0, 0xFF, 0x00, 0xF1, 0xD1, 0x42, 0x4B, 0xB3, 0xF8, 0x38, 0xC0, 0x0E, 0x21, 0x07, 0x22, -+0x4C, 0xFA, 0x01, 0xF3, 0x03, 0xF0, 0x03, 0x03, 0x03, 0x2B, 0x02, 0xF1, 0xFF, 0x30, 0xA1, 0xF1, 0x02, 0x01, 0x40, 0xF0, -+0x7F, 0x81, 0x10, 0xF0, 0xFF, 0x02, 0xF1, 0xD1, 0xA1, 0xE7, 0x4F, 0xF0, 0x03, 0x0A, 0x6B, 0xE7, 0x00, 0x2B, 0x5E, 0xDB, -+0x94, 0xF8, 0xCE, 0x30, 0x00, 0x2B, 0x40, 0xF0, 0xDF, 0x81, 0x94, 0xF8, 0xCD, 0x30, 0x00, 0x2B, 0x40, 0xF0, 0xE0, 0x81, -+0x94, 0xF8, 0xCC, 0x20, 0x11, 0x1E, 0x18, 0xBF, 0x01, 0x21, 0x2E, 0x4A, 0x93, 0x7C, 0x00, 0x2B, 0x40, 0xF0, 0xD2, 0x81, -+0x53, 0x7C, 0x00, 0x2B, 0x40, 0xF0, 0xD0, 0x81, 0x13, 0x7C, 0x1A, 0x1E, 0x18, 0xBF, 0x01, 0x22, 0x8A, 0x42, 0x28, 0xBF, -+0x0A, 0x46, 0x7C, 0xE7, 0x25, 0x4B, 0x93, 0xF8, 0x76, 0x31, 0x58, 0x07, 0x3F, 0xF5, 0x53, 0xAF, 0x26, 0x49, 0x27, 0x48, -+0x40, 0xF2, 0xCD, 0x12, 0xFC, 0xF7, 0xA8, 0xFB, 0x4B, 0xE7, 0x0C, 0x23, 0x05, 0x22, 0x00, 0x21, 0x3B, 0x20, 0xFA, 0xF7, -+0xBF, 0xFA, 0x1F, 0x4B, 0xD8, 0xF8, 0x40, 0x20, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x81, 0x46, 0xC0, 0xF2, -+0x18, 0x81, 0x13, 0x7E, 0x89, 0xF8, 0x00, 0x30, 0xD6, 0xF8, 0x90, 0x31, 0x99, 0x78, 0x89, 0xF8, 0x02, 0x10, 0x96, 0xF8, -+0xC5, 0x11, 0x89, 0xF8, 0x03, 0x10, 0xB3, 0xF8, 0x00, 0xC0, 0xB6, 0xF8, 0x94, 0x01, 0xB6, 0xF8, 0x96, 0x11, 0xA9, 0xF8, -+0x08, 0x10, 0xA9, 0xF8, 0x06, 0x00, 0xA9, 0xF8, 0x04, 0xC0, 0x12, 0x7B, 0x89, 0xF8, 0x0A, 0x20, 0xDB, 0x78, 0x89, 0xF8, -+0x0B, 0x30, 0x48, 0x46, 0xFA, 0xF7, 0xC4, 0xFA, 0xCC, 0xE6, 0x06, 0x4B, 0x93, 0xF8, 0x76, 0x31, 0xDA, 0x07, 0x9B, 0xD4, -+0x07, 0x49, 0x09, 0x48, 0x40, 0xF2, 0xE5, 0x12, 0xFC, 0xF7, 0x6A, 0xFB, 0x94, 0xE7, 0x00, 0xBF, 0xE4, 0xB8, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x0C, 0xB9, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xC4, 0xB8, 0x15, 0x00, -+0xE4, 0xB8, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, 0xB9, 0x4B, 0x93, 0xF8, 0x76, 0x31, 0x99, 0x07, 0x3F, 0xF5, 0x53, 0xAF, -+0xB7, 0x49, 0xB8, 0x48, 0x4F, 0xF4, 0xED, 0x72, 0xFC, 0xF7, 0x4C, 0xFB, 0x4B, 0xE7, 0x02, 0x2B, 0x08, 0xBF, 0x8B, 0xF8, -+0xDB, 0x90, 0x73, 0xE6, 0x82, 0x42, 0x28, 0xBF, 0x02, 0x46, 0x0A, 0xE7, 0x1F, 0xFA, 0x89, 0xF8, 0x41, 0x46, 0x10, 0x46, -+0xFB, 0xF7, 0x42, 0xFA, 0x00, 0x28, 0x3F, 0xF4, 0x1A, 0xAE, 0xB6, 0xF8, 0xC2, 0x31, 0x82, 0x78, 0x23, 0xF0, 0x07, 0x03, -+0x9B, 0xB2, 0xD1, 0x07, 0x48, 0xBF, 0x43, 0xF0, 0x01, 0x03, 0xA6, 0xF8, 0xC2, 0x31, 0x53, 0x07, 0x7F, 0xF5, 0x0B, 0xAE, -+0x01, 0x9A, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0xA3, 0xB3, 0xF8, 0xC2, 0x21, 0x42, 0xF0, 0x04, 0x02, 0xA3, 0xF8, -+0xC2, 0x21, 0x00, 0xE6, 0x18, 0xEE, 0x10, 0x0A, 0x41, 0x46, 0xFB, 0xF7, 0x89, 0xFB, 0x9A, 0x4B, 0x93, 0xF8, 0x76, 0xB1, -+0x1B, 0xF0, 0x06, 0x0B, 0x81, 0x46, 0x3F, 0xF4, 0x0B, 0xAE, 0x18, 0xEE, 0x10, 0x0A, 0x41, 0x46, 0xFB, 0xF7, 0x9C, 0xFB, -+0x01, 0x9A, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0xA3, 0x83, 0x46, 0x93, 0xF8, 0x62, 0x20, 0x00, 0x2A, 0x00, 0xF0, -+0xAA, 0x80, 0x8E, 0x4B, 0x93, 0xF8, 0x76, 0x31, 0x59, 0x07, 0x7F, 0xF5, 0xF5, 0xAD, 0x18, 0xEE, 0x90, 0x2A, 0x18, 0xEE, -+0x10, 0x0A, 0x41, 0x46, 0xFD, 0xF7, 0xD6, 0xFF, 0x00, 0x28, 0x00, 0xF0, 0x09, 0x81, 0x01, 0x9A, 0x4F, 0xF4, 0xA4, 0x63, -+0x03, 0xFB, 0x02, 0xA3, 0xD3, 0xF8, 0xC8, 0x31, 0xC3, 0xF3, 0x09, 0x12, 0x15, 0x46, 0xA2, 0xB1, 0x04, 0x23, 0x05, 0x22, -+0x00, 0x21, 0x6F, 0x20, 0xFA, 0xF7, 0xFE, 0xF9, 0x01, 0x9B, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x03, 0xA2, 0x06, 0x92, -+0x92, 0xF8, 0x63, 0x10, 0x81, 0x70, 0x05, 0x80, 0xFA, 0xF7, 0x22, 0xFA, 0x06, 0x9A, 0xD2, 0xF8, 0xC8, 0x31, 0x05, 0x9A, -+0x03, 0xF0, 0x7F, 0x43, 0x93, 0x42, 0x3F, 0xF4, 0xC5, 0xAD, 0x04, 0x23, 0x05, 0x22, 0x00, 0x21, 0x71, 0x20, 0xFA, 0xF7, -+0xE3, 0xF9, 0x01, 0x9A, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0xA3, 0xD3, 0xF8, 0xC8, 0x21, 0xC2, 0xF3, 0x05, 0x63, -+0x52, 0x00, 0x54, 0xBF, 0x43, 0xF4, 0x80, 0x73, 0x43, 0xF4, 0x40, 0x73, 0x03, 0x60, 0xFA, 0xF7, 0x01, 0xFA, 0xAB, 0xE5, -+0x02, 0x9B, 0x03, 0xF5, 0xD6, 0x72, 0x52, 0x44, 0x0D, 0xF1, 0x27, 0x03, 0x18, 0xEE, 0x10, 0x0A, 0x41, 0x46, 0x06, 0x92, -+0xFD, 0xF7, 0x92, 0xFE, 0x9D, 0xF8, 0x27, 0x30, 0x00, 0x2B, 0x3F, 0xF4, 0x93, 0xAD, 0x06, 0x9A, 0x06, 0x97, 0x03, 0x9F, -+0x25, 0x46, 0x4C, 0x46, 0x91, 0x46, 0x08, 0x23, 0x05, 0x22, 0x00, 0x21, 0x1A, 0x20, 0xFA, 0xF7, 0xB3, 0xF9, 0x59, 0xF8, -+0x04, 0x1B, 0x80, 0xF8, 0x05, 0xB0, 0x94, 0xF8, 0x63, 0x20, 0x82, 0x71, 0x4F, 0xF0, 0x00, 0x02, 0x01, 0x60, 0x0B, 0xF1, -+0x01, 0x0B, 0x02, 0x71, 0xFA, 0xF7, 0xD4, 0xF9, 0xBB, 0xF1, 0x04, 0x0F, 0xE7, 0xD1, 0x03, 0x97, 0x2C, 0x46, 0x06, 0x9F, -+0x70, 0xE5, 0x00, 0x2A, 0x7F, 0xF4, 0xE5, 0xAE, 0x45, 0x22, 0x4C, 0x49, 0x4D, 0x48, 0xFC, 0xF7, 0x77, 0xFA, 0xD8, 0xF8, -+0x40, 0x20, 0xDC, 0xE6, 0x9B, 0xF8, 0x8C, 0x30, 0x00, 0x2B, 0x3F, 0xF4, 0x96, 0xAD, 0x9D, 0xF8, 0x25, 0x30, 0x01, 0x2B, -+0x7F, 0xF4, 0x91, 0xAD, 0x46, 0x4B, 0x9B, 0xF8, 0x63, 0x00, 0xD3, 0xF8, 0xC0, 0x31, 0x98, 0x47, 0x9B, 0xF8, 0x8A, 0x10, -+0x00, 0x29, 0x3F, 0xF4, 0x86, 0xAD, 0x7A, 0xE5, 0x5A, 0x45, 0x28, 0xBF, 0x5A, 0x46, 0xD2, 0xB2, 0x21, 0xE6, 0x83, 0x46, -+0x69, 0xE6, 0x18, 0xEE, 0x10, 0x0A, 0x41, 0x46, 0x06, 0x93, 0xFB, 0xF7, 0x77, 0xF9, 0xB0, 0xB1, 0x06, 0x9B, 0x3A, 0x49, -+0x93, 0xF8, 0x6C, 0x20, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x02, 0x13, 0x5B, 0x68, 0x13, 0xF0, 0x24, 0x0F, 0x0A, 0xD0, -+0x90, 0xF9, 0x02, 0x30, 0x81, 0x78, 0x00, 0x2B, 0x05, 0xDB, 0x10, 0x46, 0x0A, 0x09, 0x01, 0xF0, 0x03, 0x01, 0xFF, 0xF7, -+0xDD, 0xFB, 0x01, 0x9A, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0xA3, 0x06, 0x93, 0xD3, 0xF8, 0xCC, 0x31, 0x18, 0x07, -+0x7F, 0xF5, 0x2D, 0xAF, 0x02, 0x23, 0x05, 0x22, 0x00, 0x21, 0x6D, 0x20, 0xFA, 0xF7, 0x46, 0xF9, 0x41, 0x46, 0x02, 0x46, -+0x07, 0x90, 0x18, 0xEE, 0x10, 0x0A, 0xFD, 0xF7, 0x45, 0xFF, 0x07, 0x9A, 0x10, 0x46, 0xFA, 0xF7, 0x6B, 0xF9, 0x22, 0x4B, -+0x1B, 0x69, 0x00, 0x2B, 0x3F, 0xF4, 0x17, 0xAF, 0x02, 0x9B, 0x03, 0xF5, 0xA8, 0x72, 0x18, 0xEE, 0x10, 0x0A, 0x0D, 0xF1, -+0x27, 0x03, 0x52, 0x44, 0x41, 0x46, 0xFD, 0xF7, 0x05, 0xFF, 0x9D, 0xF8, 0x27, 0x30, 0x00, 0x2B, 0x3F, 0xF4, 0x07, 0xAF, -+0x10, 0x23, 0x05, 0x22, 0x00, 0x21, 0x6B, 0x20, 0xFA, 0xF7, 0x20, 0xF9, 0x06, 0x9A, 0x11, 0x46, 0x15, 0x46, 0xD2, 0xF8, -+0x50, 0xE1, 0xD2, 0xF8, 0x54, 0x21, 0xD1, 0xF8, 0x58, 0x11, 0xD5, 0xF8, 0x5C, 0x51, 0xC5, 0x60, 0xC0, 0xE9, 0x00, 0xE2, -+0x81, 0x60, 0xFA, 0xF7, 0x3F, 0xF9, 0xEE, 0xE6, 0x03, 0x21, 0x28, 0xE6, 0x03, 0x22, 0x33, 0xE6, 0x02, 0x22, 0x31, 0xE6, -+0x02, 0x21, 0x22, 0xE6, 0x40, 0xF2, 0xFF, 0x33, 0x1D, 0x46, 0xFD, 0xE6, 0xE4, 0xB8, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xD4, 0xB8, 0x15, 0x00, 0xF4, 0xB8, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x94, 0x64, 0x17, 0x00, -+0x70, 0xB5, 0x0C, 0x46, 0x84, 0xB0, 0x89, 0x78, 0x0C, 0x4D, 0x26, 0x79, 0x8D, 0xF8, 0x04, 0x10, 0xAD, 0xF8, 0x08, 0x20, -+0x01, 0x46, 0x9D, 0xF8, 0x20, 0x20, 0x20, 0x88, 0xE4, 0x78, 0xAD, 0xF8, 0x0A, 0x30, 0xAD, 0xF8, 0x06, 0x00, 0x6B, 0x6C, -+0x8D, 0xF8, 0x0C, 0x60, 0x8D, 0xF8, 0x0D, 0x40, 0x8D, 0xF8, 0x05, 0x20, 0x01, 0xA8, 0x98, 0x47, 0x04, 0xB0, 0x70, 0xBD, -+0x88, 0x1A, 0x17, 0x00, 0x03, 0x68, 0x30, 0xB4, 0x0C, 0x68, 0x5A, 0x40, 0x84, 0xEA, 0xF2, 0x34, 0x22, 0x44, 0x13, 0x0A, -+0x15, 0x02, 0x05, 0xF0, 0xFF, 0x25, 0x03, 0xF0, 0xFF, 0x13, 0x2B, 0x43, 0x63, 0x40, 0x1A, 0x44, 0x83, 0xEA, 0x72, 0x73, -+0x1A, 0x44, 0x83, 0xEA, 0xB2, 0x03, 0x1A, 0x44, 0x0B, 0x60, 0x30, 0xBC, 0x02, 0x60, 0x70, 0x47, 0xF8, 0xB5, 0x1F, 0x88, -+0xD3, 0xF8, 0x02, 0x50, 0x0B, 0x68, 0x96, 0x88, 0x12, 0x68, 0x03, 0x60, 0x9D, 0xF8, 0x18, 0x40, 0x4B, 0x68, 0x43, 0x60, -+0x00, 0x23, 0xFF, 0x2C, 0x83, 0x60, 0x03, 0x73, 0x00, 0xF1, 0x04, 0x01, 0x46, 0xEA, 0x07, 0x46, 0x14, 0xBF, 0x04, 0xF0, -+0x07, 0x04, 0x00, 0x24, 0xFF, 0xF7, 0xCC, 0xFF, 0x32, 0x46, 0xFF, 0xF7, 0xC9, 0xFF, 0x2A, 0x46, 0xFF, 0xF7, 0xC6, 0xFF, -+0x22, 0x46, 0xBD, 0xE8, 0xF8, 0x40, 0xFF, 0xF7, 0xC1, 0xBF, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x4F, 0x21, 0xF0, 0x03, 0x06, -+0x01, 0xF0, 0x03, 0x01, 0xC1, 0xF1, 0x04, 0x03, 0x37, 0x68, 0x90, 0xF8, 0x0C, 0xC0, 0x85, 0x68, 0xDB, 0xB2, 0x04, 0x36, -+0xC9, 0x00, 0x9A, 0x42, 0x83, 0xB0, 0x27, 0xFA, 0x01, 0xF1, 0xB1, 0x46, 0x78, 0xD2, 0xC2, 0xF1, 0x04, 0x04, 0xE3, 0x00, -+0x4F, 0xF0, 0xFF, 0x34, 0x4F, 0xF0, 0x00, 0x0B, 0xDC, 0x40, 0x21, 0x40, 0xD8, 0x46, 0x5F, 0x46, 0x0C, 0xEB, 0x02, 0x04, -+0x03, 0x2C, 0x52, 0xD8, 0x4F, 0xEA, 0xCC, 0x0C, 0x01, 0xFA, 0x0C, 0xF1, 0x0D, 0x43, 0xB8, 0xF1, 0x00, 0x0F, 0x22, 0xD0, -+0xE3, 0x00, 0xC4, 0xF1, 0x04, 0x0A, 0x00, 0x93, 0x4F, 0xEA, 0x88, 0x03, 0x4F, 0xEA, 0xCA, 0x0A, 0x01, 0x1D, 0x01, 0x93, -+0x06, 0xEB, 0x88, 0x08, 0xB1, 0x46, 0xD9, 0xF8, 0x00, 0x30, 0x00, 0x9A, 0x03, 0xFA, 0x02, 0xF2, 0xBA, 0xF1, 0x20, 0x0F, -+0x42, 0xEA, 0x05, 0x02, 0x09, 0xF1, 0x04, 0x09, 0x14, 0xBF, 0x23, 0xFA, 0x0A, 0xF5, 0x00, 0x25, 0xFF, 0xF7, 0x76, 0xFF, -+0xC1, 0x45, 0xEC, 0xD1, 0x01, 0x9B, 0x33, 0x44, 0x99, 0x46, 0x5F, 0x45, 0x20, 0xD9, 0x07, 0xF0, 0x03, 0x07, 0xC7, 0xF1, -+0x04, 0x03, 0xDA, 0x00, 0x20, 0x2A, 0xD9, 0xF8, 0x00, 0x10, 0x40, 0xD0, 0x4F, 0xF0, 0xFF, 0x33, 0xD3, 0x40, 0x0B, 0x40, -+0xE2, 0x00, 0x03, 0xFA, 0x02, 0xF2, 0x15, 0x43, 0x27, 0x44, 0x03, 0x2F, 0x2F, 0xD9, 0xC4, 0xF1, 0x04, 0x04, 0xE4, 0x00, -+0x20, 0x2C, 0x14, 0xBF, 0xE3, 0x40, 0x00, 0x23, 0x2A, 0x46, 0x01, 0x1D, 0x3C, 0x1F, 0x1D, 0x46, 0xFF, 0xF7, 0x4E, 0xFF, -+0x85, 0x60, 0x04, 0x73, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x4F, 0xEA, 0xCC, 0x02, 0xCC, 0xF1, 0x04, 0x0C, 0x4F, 0xEA, -+0xCC, 0x0C, 0xBC, 0xF1, 0x20, 0x0F, 0x01, 0xFA, 0x02, 0xF2, 0x42, 0xEA, 0x05, 0x02, 0x18, 0xBF, 0x21, 0xFA, 0x0C, 0xF5, -+0x00, 0xF1, 0x04, 0x01, 0x08, 0xBF, 0x00, 0x25, 0x04, 0x3C, 0xFF, 0xF7, 0x33, 0xFF, 0x9A, 0xE7, 0xD7, 0x1A, 0x4F, 0xEA, -+0x97, 0x08, 0x1A, 0x46, 0x27, 0xF0, 0x03, 0x0B, 0x8A, 0xE7, 0x3C, 0x46, 0x85, 0x60, 0x04, 0x73, 0x03, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0x00, 0x23, 0xC4, 0xE7, 0x00, 0xBF, 0x38, 0xB5, 0x10, 0x4B, 0x85, 0x68, 0x1B, 0x68, 0x02, 0x7B, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x04, 0x46, 0x0D, 0xDB, 0x5A, 0x23, 0xD2, 0x00, 0x03, 0xFA, 0x02, 0xF2, 0x2A, 0x43, 0x21, 0x1D, -+0x20, 0x46, 0xFF, 0xF7, 0x0F, 0xFF, 0xBD, 0xE8, 0x38, 0x40, 0x00, 0x22, 0xFF, 0xF7, 0x0A, 0xBF, 0x03, 0x2A, 0xEF, 0xD9, -+0x40, 0xF2, 0x41, 0x12, 0x03, 0x49, 0x04, 0x48, 0xFC, 0xF7, 0xB8, 0xF8, 0x22, 0x7B, 0xE7, 0xE7, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x20, 0xB9, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x06, 0x20, 0x83, 0xB0, 0x00, 0x24, 0xCD, 0xE9, -+0x00, 0x44, 0x91, 0xF8, 0x3D, 0x90, 0x0D, 0x46, 0x17, 0x46, 0x1E, 0x46, 0xFA, 0xF7, 0x62, 0xFA, 0x09, 0x28, 0x79, 0xD0, -+0x01, 0x23, 0x3A, 0x46, 0x31, 0x46, 0x41, 0xF6, 0x01, 0x00, 0xF9, 0xF7, 0xB7, 0xFF, 0x80, 0x46, 0x06, 0x20, 0xFA, 0xF7, -+0x55, 0xFA, 0x48, 0xB1, 0x08, 0x26, 0x40, 0x46, 0x88, 0xF8, 0x00, 0x60, 0xF9, 0xF7, 0xDC, 0xFF, 0x20, 0x46, 0x03, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0xDF, 0xF8, 0xAC, 0xA1, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x09, 0xA3, 0x93, 0xF8, 0x62, 0x20, -+0x00, 0x2A, 0x4F, 0xD1, 0x93, 0xF8, 0x64, 0x30, 0x00, 0x2B, 0x4B, 0xD1, 0xDF, 0xF8, 0x94, 0xB1, 0x5A, 0x4A, 0x5B, 0x49, -+0x13, 0x68, 0x43, 0xF0, 0x10, 0x03, 0x13, 0x60, 0x95, 0xF8, 0x3B, 0x30, 0x01, 0x22, 0x02, 0x2B, 0xCA, 0x75, 0x0E, 0xD0, -+0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x09, 0xA2, 0x92, 0xF8, 0x64, 0x10, 0x29, 0xB9, 0x53, 0x4C, 0x21, 0x68, 0xB1, 0xF9, -+0x00, 0x10, 0x00, 0x29, 0x7F, 0xDB, 0x03, 0x2B, 0x57, 0xD0, 0x3A, 0x46, 0x4F, 0xF4, 0x55, 0x73, 0x31, 0x46, 0x41, 0xF6, -+0x02, 0x00, 0xCB, 0xF8, 0x00, 0x50, 0xF9, 0xF7, 0x73, 0xFF, 0x95, 0xF8, 0x3B, 0x30, 0xCB, 0xF8, 0x04, 0x00, 0x00, 0x27, -+0x02, 0x2B, 0x8B, 0xF8, 0x16, 0x70, 0x4F, 0xD0, 0x9B, 0xF8, 0x1E, 0x60, 0x3E, 0xB3, 0x95, 0xF8, 0x3D, 0x10, 0x44, 0x48, -+0x4F, 0xF4, 0xA4, 0x64, 0x04, 0xFB, 0x01, 0xA1, 0x06, 0x22, 0x38, 0x31, 0x0E, 0xF0, 0xE4, 0xFA, 0x09, 0x21, 0x06, 0x20, -+0xFA, 0xF7, 0x52, 0xF9, 0x95, 0xF8, 0x3D, 0x00, 0x39, 0x46, 0x04, 0xFB, 0x00, 0xA0, 0x01, 0xF0, 0xCB, 0xF8, 0x3E, 0x46, -+0x01, 0x24, 0x9C, 0xE7, 0x95, 0xF8, 0x3B, 0x30, 0x02, 0x2B, 0xAF, 0xD0, 0x2C, 0x6B, 0x14, 0xF0, 0x20, 0x04, 0x17, 0xD1, -+0x09, 0x26, 0x92, 0xE7, 0x02, 0x24, 0x20, 0x46, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x01, 0xA9, 0x68, 0x46, 0x00, 0xF0, -+0x75, 0xFD, 0xDD, 0xE9, 0x00, 0x01, 0x28, 0xB1, 0x21, 0xB1, 0x32, 0x46, 0x00, 0xF0, 0x14, 0xFE, 0x01, 0x24, 0x80, 0xE7, -+0x00, 0xF0, 0x90, 0xFD, 0x01, 0x24, 0x7C, 0xE7, 0xDF, 0xF8, 0xBC, 0xB0, 0x28, 0x48, 0x01, 0x23, 0x8B, 0xF8, 0x1E, 0x30, -+0xFB, 0xF7, 0x8E, 0xFD, 0x8C, 0xE7, 0xE9, 0x8E, 0x05, 0xF1, 0x40, 0x00, 0x02, 0xF0, 0x32, 0xF8, 0x00, 0x28, 0xC4, 0xBF, -+0x00, 0x23, 0x85, 0xF8, 0x3B, 0x30, 0x9C, 0xE7, 0x95, 0xF8, 0x3D, 0x10, 0x1F, 0x48, 0x4F, 0xF4, 0xA4, 0x66, 0x06, 0xFB, -+0x01, 0xA1, 0x06, 0x22, 0x38, 0x31, 0x01, 0x24, 0x8B, 0xF8, 0x16, 0x40, 0x0E, 0xF0, 0x94, 0xFA, 0x09, 0x21, 0x06, 0x20, -+0xFA, 0xF7, 0x02, 0xF9, 0x95, 0xF8, 0x3D, 0x00, 0x39, 0x46, 0x06, 0xFB, 0x00, 0xA0, 0x01, 0xF0, 0x7B, 0xF8, 0x3E, 0x46, -+0x4D, 0xE7, 0x92, 0xF8, 0x6C, 0x30, 0xFF, 0x2B, 0x09, 0xD0, 0x12, 0x49, 0x12, 0x48, 0x64, 0x22, 0xFB, 0xF7, 0xD8, 0xFF, -+0x23, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x0B, 0xDA, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x09, 0xA9, 0xD9, 0xF8, -+0x40, 0x30, 0x23, 0xB1, 0x09, 0x49, 0x0B, 0x48, 0x65, 0x22, 0xFB, 0xF7, 0xC7, 0xFF, 0x95, 0xF8, 0x3B, 0x30, 0x62, 0xE7, -+0x94, 0x40, 0x04, 0x40, 0x4C, 0x36, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x84, 0xBA, 0x17, 0x00, 0x40, 0xB9, 0x15, 0x00, -+0x7C, 0xBA, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x4C, 0xB9, 0x15, 0x00, 0xA0, 0xA2, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x64, 0xBA, 0x17, 0x00, 0x38, 0xB5, 0x0B, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0x0F, 0x49, 0x1C, 0x78, 0xFB, 0xF7, 0x7C, 0xFD, -+0x06, 0x20, 0xFA, 0xF7, 0x63, 0xF9, 0xA8, 0xB9, 0x0C, 0x4B, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x04, 0x34, 0x94, 0xF8, -+0x62, 0x50, 0x15, 0xB9, 0x94, 0xF8, 0x64, 0x00, 0x00, 0xB9, 0x38, 0xBD, 0x09, 0x21, 0x06, 0x20, 0xFA, 0xF7, 0xAA, 0xF8, -+0x20, 0x46, 0x01, 0x21, 0x01, 0xF0, 0x26, 0xF8, 0x28, 0x46, 0x38, 0xBD, 0x02, 0x20, 0x38, 0xBD, 0x70, 0xB9, 0x15, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x08, 0xB5, 0x06, 0x20, 0xFA, 0xF7, 0x42, 0xF9, 0x05, 0x28, 0x04, 0xD0, 0x06, 0x20, 0xFA, 0xF7, -+0x3D, 0xF9, 0x06, 0x28, 0x04, 0xD1, 0x01, 0x20, 0x01, 0xF0, 0x9C, 0xF9, 0x00, 0x20, 0x08, 0xBD, 0x06, 0x20, 0xFA, 0xF7, -+0x33, 0xF9, 0x07, 0x28, 0xF5, 0xD0, 0x00, 0x20, 0x08, 0xBD, 0x00, 0xBF, 0x16, 0x4B, 0x00, 0xB5, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x20, 0x00, 0x23, 0x83, 0xB0, 0x9A, 0x42, 0xCD, 0xE9, 0x00, 0x33, 0x15, 0xDB, 0x68, 0x46, 0x01, 0xA9, 0x00, 0xF0, -+0xB7, 0xFC, 0x00, 0x98, 0x40, 0xB1, 0x01, 0x99, 0x31, 0xB1, 0x00, 0x22, 0x00, 0xF0, 0x56, 0xFD, 0x00, 0x20, 0x03, 0xB0, -+0x5D, 0xF8, 0x04, 0xFB, 0x01, 0x20, 0x01, 0xF0, 0x75, 0xF9, 0x00, 0x20, 0x03, 0xB0, 0x5D, 0xF8, 0x04, 0xFB, 0x06, 0x20, -+0xFA, 0xF7, 0x0A, 0xF9, 0x01, 0x28, 0xE4, 0xD0, 0x04, 0x49, 0x05, 0x48, 0x4F, 0xF4, 0x8F, 0x72, 0xFB, 0xF7, 0x42, 0xFF, -+0xDD, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x80, 0xB9, 0x15, 0x00, 0x93, 0x4B, 0x2D, 0xE9, -+0xF0, 0x4F, 0x1B, 0x68, 0x92, 0x4D, 0xB3, 0xF9, 0x00, 0x30, 0x2F, 0x68, 0x00, 0x2B, 0x89, 0xB0, 0xC0, 0xF2, 0x91, 0x80, -+0x97, 0xF8, 0x3D, 0x80, 0x8E, 0x4E, 0x4F, 0xF4, 0xA4, 0x64, 0x04, 0xFB, 0x08, 0x64, 0xD4, 0xF8, 0xCC, 0x31, 0x00, 0x2B, -+0x18, 0xDB, 0x6B, 0x7D, 0x33, 0xB9, 0x01, 0x20, 0x01, 0xF0, 0x42, 0xF9, 0x00, 0x20, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0x00, 0x23, 0x07, 0xA9, 0x06, 0xA8, 0xCD, 0xE9, 0x06, 0x33, 0x00, 0xF0, 0x6B, 0xFC, 0xDD, 0xE9, 0x06, 0x01, 0x01, 0x22, -+0x00, 0xF0, 0x0C, 0xFD, 0x00, 0x20, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x07, 0xA8, 0x00, 0xF0, 0xE1, 0xFD, 0x00, 0x28, -+0x74, 0xD1, 0x01, 0x46, 0x20, 0x23, 0x06, 0x22, 0x0A, 0x20, 0xF9, 0xF7, 0x1D, 0xFE, 0x94, 0xF8, 0xC0, 0x34, 0x05, 0x46, -+0x2B, 0xB1, 0xD4, 0xF8, 0xCC, 0x21, 0x22, 0xF0, 0x08, 0x02, 0xC4, 0xF8, 0xCC, 0x21, 0x74, 0x4A, 0x92, 0xF8, 0x04, 0x21, -+0x4A, 0xB1, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x08, 0xF2, 0xB1, 0x18, 0xD1, 0xF8, 0x90, 0x01, 0x80, 0x78, 0x01, 0x28, -+0x6D, 0xD0, 0x6E, 0x4B, 0x97, 0xF8, 0x3D, 0x00, 0xDB, 0x6C, 0x9D, 0xF8, 0x1C, 0x10, 0x98, 0x47, 0x4F, 0xF4, 0xA4, 0x6B, -+0x00, 0x23, 0x2B, 0x60, 0x0B, 0xFB, 0x08, 0xFB, 0x97, 0xF8, 0x3D, 0x20, 0x6A, 0x76, 0x06, 0xEB, 0x0B, 0x0A, 0xDA, 0xF8, -+0x64, 0x01, 0xBA, 0xF8, 0x68, 0x21, 0xAB, 0x76, 0x9A, 0xF8, 0x8B, 0x31, 0x6B, 0x77, 0x9A, 0xF8, 0x8C, 0x31, 0xAB, 0x77, -+0xDA, 0xF8, 0xCC, 0x31, 0xC5, 0xF8, 0x12, 0x00, 0x13, 0xF0, 0x02, 0x04, 0xEA, 0x82, 0x1B, 0xD0, 0x0B, 0xF1, 0xEC, 0x09, -+0x13, 0xF0, 0x04, 0x04, 0xB1, 0x44, 0x6E, 0xD1, 0x21, 0x46, 0x13, 0xF0, 0x08, 0x02, 0x05, 0xF1, 0x18, 0x03, 0x18, 0xBF, -+0x0B, 0xF5, 0x8C, 0x72, 0x05, 0xF1, 0x04, 0x0C, 0x02, 0x93, 0x05, 0xF1, 0x08, 0x03, 0xCD, 0xE9, 0x00, 0x3C, 0x18, 0xBF, -+0x92, 0x19, 0x48, 0x46, 0x05, 0xF1, 0x10, 0x03, 0xFE, 0xF7, 0x22, 0xFC, 0x28, 0x46, 0xEC, 0x60, 0xF9, 0xF7, 0xF0, 0xFD, -+0x03, 0x21, 0x06, 0x20, 0xF9, 0xF7, 0xB6, 0xFF, 0x0F, 0xE0, 0x06, 0x20, 0xFA, 0xF7, 0x5A, 0xF8, 0x02, 0x28, 0x3F, 0xF4, -+0x69, 0xAF, 0x47, 0x49, 0x47, 0x48, 0x4F, 0xF4, 0xA3, 0x72, 0xFB, 0xF7, 0x91, 0xFE, 0x61, 0xE7, 0x01, 0x20, 0x01, 0xF0, -+0xB1, 0xF8, 0x3A, 0x6B, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x08, 0x66, 0x53, 0x07, 0xC6, 0xF8, 0xB0, 0x24, 0x7F, 0xF5, -+0x65, 0xAF, 0xD6, 0xF8, 0xCC, 0x31, 0x00, 0x20, 0x23, 0xF0, 0x0E, 0x03, 0xC6, 0xF8, 0xCC, 0x31, 0x09, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0xD1, 0xF8, 0xCC, 0x11, 0x11, 0xF0, 0x0C, 0x0F, 0x8C, 0xD0, 0x00, 0x2B, 0x8A, 0xD1, 0xDF, 0xF8, 0xD8, 0x90, -+0x02, 0xF5, 0xB2, 0x72, 0xB4, 0x18, 0x9A, 0x46, 0xCB, 0x46, 0x58, 0x46, 0x06, 0x22, 0x21, 0x46, 0x0E, 0xF0, 0xDC, 0xF8, -+0x0B, 0xF1, 0x14, 0x0B, 0x18, 0xB3, 0x0A, 0xF1, 0x01, 0x0A, 0xBA, 0xF1, 0x05, 0x0F, 0xF2, 0xD1, 0x2C, 0x49, 0x50, 0x22, -+0x01, 0xF1, 0x14, 0x00, 0x0E, 0xF0, 0xFE, 0xF8, 0x29, 0x48, 0x21, 0x46, 0x06, 0x22, 0x0E, 0xF0, 0xF9, 0xF8, 0x01, 0x23, -+0xA9, 0xF8, 0x06, 0x30, 0x89, 0xF8, 0x08, 0x30, 0x65, 0xE7, 0x0B, 0xF5, 0xB2, 0x70, 0x0B, 0xF5, 0x86, 0x71, 0x31, 0x44, -+0x30, 0x44, 0x05, 0x91, 0xFA, 0xF7, 0x28, 0xFF, 0xDA, 0xF8, 0xCC, 0x31, 0x05, 0x99, 0x04, 0x46, 0x83, 0xE7, 0x0A, 0xEB, -+0x8A, 0x03, 0x09, 0xEB, 0x83, 0x03, 0x4F, 0xEA, 0x8A, 0x0B, 0x9A, 0x79, 0x14, 0x23, 0x03, 0xFB, 0x0A, 0x93, 0x4A, 0xB1, -+0xDB, 0x79, 0x53, 0xB1, 0x0B, 0xEB, 0x0A, 0x03, 0x09, 0xEB, 0x83, 0x09, 0x01, 0x23, 0x89, 0xF8, 0x08, 0x30, 0x42, 0xE7, -+0x01, 0x22, 0x9A, 0x71, 0xF4, 0xE7, 0x4F, 0xF4, 0xA4, 0x64, 0x04, 0xFB, 0x08, 0x64, 0x00, 0x92, 0xB4, 0xF8, 0x68, 0x31, -+0xB4, 0xF8, 0x66, 0x21, 0xB4, 0xF8, 0x64, 0x11, 0x0C, 0x48, 0xFB, 0xF7, 0x9F, 0xFB, 0xD4, 0xF8, 0xCC, 0x31, 0x23, 0xF0, -+0x0C, 0x03, 0xC4, 0xF8, 0xCC, 0x31, 0xDF, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x64, 0xBA, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x2C, 0x19, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xA8, 0xB9, 0x15, 0x00, 0xCC, 0x35, 0x17, 0x00, -+0xCC, 0xB9, 0x15, 0x00, 0x08, 0xB5, 0x16, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x0F, 0xDB, 0x06, 0x20, -+0xF9, 0xF7, 0xB6, 0xFF, 0x04, 0x28, 0x06, 0xD0, 0x06, 0x20, 0xF9, 0xF7, 0xB1, 0xFF, 0x09, 0x28, 0x01, 0xD0, 0x00, 0x20, -+0x08, 0xBD, 0x00, 0xF0, 0xF5, 0xFC, 0x00, 0x20, 0x08, 0xBD, 0x06, 0x20, 0xF9, 0xF7, 0xA6, 0xFF, 0x04, 0x28, 0xEA, 0xD0, -+0x06, 0x20, 0xF9, 0xF7, 0xA1, 0xFF, 0x00, 0x28, 0xE5, 0xD0, 0x06, 0x20, 0xF9, 0xF7, 0x9C, 0xFF, 0x09, 0x28, 0xE0, 0xD0, -+0x04, 0x49, 0x05, 0x48, 0x4F, 0xF4, 0x16, 0x72, 0xFB, 0xF7, 0xD4, 0xFD, 0xD9, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xE4, 0xB9, 0x15, 0x00, 0x08, 0xB5, 0x0C, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0x03, 0xDB, 0x00, 0xF0, 0xCD, 0xFC, 0x00, 0x20, 0x08, 0xBD, 0x06, 0x20, 0xF9, 0xF7, 0x7E, 0xFF, 0x04, 0x28, 0xF6, 0xD0, -+0x05, 0x49, 0x06, 0x48, 0x40, 0xF2, 0x79, 0x22, 0xFB, 0xF7, 0xB6, 0xFD, 0x00, 0xF0, 0xBE, 0xFC, 0x00, 0x20, 0x08, 0xBD, -+0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x6C, 0xBA, 0x15, 0x00, 0x08, 0xB5, 0x0C, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x03, 0xDB, 0x00, 0xF0, 0xAD, 0xFC, 0x00, 0x20, 0x08, 0xBD, 0x06, 0x20, 0xF9, 0xF7, 0x5E, 0xFF, -+0x09, 0x28, 0xF6, 0xD0, 0x05, 0x49, 0x06, 0x48, 0x40, 0xF2, 0x29, 0x32, 0xFB, 0xF7, 0x96, 0xFD, 0x00, 0xF0, 0x9E, 0xFC, -+0x00, 0x20, 0x08, 0xBD, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x9C, 0xBA, 0x15, 0x00, 0x08, 0xB5, 0x0C, 0x4B, -+0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x03, 0xDB, 0x00, 0xF0, 0x8D, 0xFC, 0x00, 0x20, 0x08, 0xBD, 0x06, 0x20, -+0xF9, 0xF7, 0x3E, 0xFF, 0x09, 0x28, 0xF6, 0xD0, 0x05, 0x49, 0x06, 0x48, 0x40, 0xF2, 0x43, 0x32, 0xFB, 0xF7, 0x76, 0xFD, -+0x00, 0xF0, 0x7E, 0xFC, 0x00, 0x20, 0x08, 0xBD, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x9C, 0xBA, 0x15, 0x00, -+0x37, 0x4B, 0x30, 0xB5, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x83, 0xB0, 0x37, 0xDB, 0x06, 0x20, 0xF9, 0xF7, -+0x21, 0xFF, 0x09, 0x28, 0x10, 0xD0, 0x32, 0x4B, 0x9A, 0x7D, 0x01, 0x2A, 0x50, 0xD0, 0x1B, 0x68, 0x93, 0xF8, 0x3B, 0x30, -+0x02, 0x2B, 0x3A, 0xD9, 0x03, 0x2B, 0x3F, 0xD1, 0x2D, 0x48, 0x01, 0xF0, 0xF5, 0xFC, 0x00, 0x20, 0x03, 0xB0, 0x30, 0xBD, -+0x29, 0x4C, 0xA2, 0x6A, 0x23, 0x7D, 0x00, 0x25, 0xC2, 0xF8, 0xCC, 0x51, 0x00, 0x2B, 0x40, 0xD1, 0xA0, 0x68, 0x0C, 0x30, -+0xF9, 0xF7, 0x90, 0xFC, 0xA3, 0x7D, 0x00, 0x22, 0x01, 0x2B, 0xA2, 0x60, 0x01, 0xD0, 0xA1, 0x7F, 0x61, 0xB3, 0x00, 0x24, -+0x01, 0xA9, 0x68, 0x46, 0xCD, 0xE9, 0x00, 0x44, 0x00, 0xF0, 0x8C, 0xFA, 0xDD, 0xE9, 0x00, 0x01, 0x22, 0x46, 0x00, 0xF0, -+0x2D, 0xFB, 0x00, 0x20, 0x03, 0xB0, 0x30, 0xBD, 0x06, 0x20, 0xF9, 0xF7, 0xE9, 0xFE, 0x04, 0x28, 0xC2, 0xD0, 0x06, 0x20, -+0xF9, 0xF7, 0xE4, 0xFE, 0x09, 0x28, 0xBD, 0xD0, 0x15, 0x49, 0x16, 0x48, 0x40, 0xF2, 0x93, 0x22, 0xFB, 0xF7, 0x1C, 0xFD, -+0xB6, 0xE7, 0x00, 0x21, 0x01, 0x20, 0x01, 0xF0, 0x2B, 0xF8, 0x00, 0x20, 0x03, 0xB0, 0x30, 0xBD, 0x01, 0x20, 0x00, 0xF0, -+0x35, 0xFF, 0x00, 0x20, 0x03, 0xB0, 0x30, 0xBD, 0x06, 0x20, 0xF9, 0xF7, 0x23, 0xFE, 0xDA, 0xE7, 0x01, 0xF0, 0x48, 0xF9, -+0x00, 0x20, 0x03, 0xB0, 0x30, 0xBD, 0x06, 0x22, 0x0C, 0x21, 0x41, 0xF6, 0x04, 0x00, 0xF9, 0xF7, 0x85, 0xFC, 0x25, 0x75, -+0xB6, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x64, 0xBA, 0x17, 0x00, 0x08, 0xAC, 0x0F, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xC8, 0xBA, 0x15, 0x00, 0x4B, 0x88, 0x03, 0xF0, 0xFC, 0x03, 0xB0, 0x2B, 0x10, 0xB5, 0x0C, 0x46, 0x13, 0xD0, 0x10, 0x2B, -+0x0A, 0xD0, 0x30, 0x2B, 0x08, 0xD0, 0xC0, 0x2B, 0x01, 0xD0, 0xA0, 0x2B, 0x14, 0xD1, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, -+0x01, 0xF0, 0x78, 0xBB, 0x06, 0x20, 0xF9, 0xF7, 0x9B, 0xFE, 0x07, 0x28, 0x13, 0xD0, 0x00, 0x20, 0x10, 0xBD, 0x06, 0x20, -+0xF9, 0xF7, 0x94, 0xFE, 0x05, 0x28, 0xF8, 0xD1, 0x20, 0x46, 0x01, 0xF0, 0x37, 0xFA, 0xF4, 0xE7, 0xD0, 0x2B, 0xF2, 0xD1, -+0x23, 0x7B, 0x08, 0x2B, 0xEF, 0xD1, 0x20, 0x46, 0x01, 0xF0, 0xD4, 0xFB, 0xEB, 0xE7, 0x20, 0x46, 0x01, 0xF0, 0x70, 0xFA, -+0xE7, 0xE7, 0x00, 0xBF, 0x10, 0xB5, 0x06, 0x20, 0x0C, 0x46, 0xF9, 0xF7, 0x7B, 0xFE, 0x06, 0x28, 0x01, 0xD0, 0x00, 0x20, -+0x10, 0xBD, 0x60, 0x88, 0x01, 0xF0, 0xC8, 0xFC, 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, -+0x03, 0xD4, 0x72, 0xB6, 0x0D, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x0D, 0x4C, 0x0D, 0x4A, 0x23, 0x68, 0xD2, 0x7D, 0x01, 0x33, -+0x01, 0x2A, 0x23, 0x60, 0x0C, 0xD0, 0x33, 0xB1, 0x07, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x23, 0x60, 0x0B, 0xB9, 0x02, 0xB1, -+0x62, 0xB6, 0x07, 0x48, 0xFB, 0xF7, 0x1C, 0xFA, 0x00, 0x20, 0x10, 0xBD, 0x00, 0xF0, 0x16, 0xFB, 0x23, 0x68, 0xEE, 0xE7, -+0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x4C, 0x36, 0x17, 0x00, 0x28, 0xBB, 0x15, 0x00, 0x38, 0xB5, 0x06, 0x20, -+0x0D, 0x46, 0xF9, 0xF7, 0x43, 0xFE, 0x30, 0xB9, 0x04, 0x46, 0x29, 0x88, 0xA8, 0x78, 0x00, 0xF0, 0xB7, 0xFD, 0x20, 0x46, -+0x38, 0xBD, 0x02, 0x20, 0x38, 0xBD, 0x00, 0xBF, 0x8B, 0x4B, 0x2D, 0xE9, 0xF0, 0x4F, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x89, 0xB0, 0x0C, 0x46, 0xC0, 0xF2, 0xFD, 0x80, 0x25, 0x78, 0x00, 0x2D, 0x40, 0xF0, 0xF2, 0x80, 0x63, 0x78, -+0x00, 0x93, 0x4F, 0xF4, 0x1E, 0x74, 0x04, 0xFB, 0x03, 0xF4, 0x82, 0x4B, 0xDF, 0xF8, 0x18, 0xA2, 0x1F, 0x19, 0x4F, 0xF4, -+0xA4, 0x6C, 0x97, 0xF8, 0x22, 0xE0, 0x0C, 0xFB, 0x0E, 0xAC, 0x0C, 0xF5, 0xCE, 0x73, 0x0F, 0xCB, 0x07, 0xF1, 0xB8, 0x06, -+0x07, 0xC6, 0xDC, 0xF8, 0xCC, 0x81, 0x33, 0x70, 0x18, 0xF0, 0x01, 0x0F, 0x03, 0xD0, 0x7B, 0x68, 0x43, 0xF0, 0x01, 0x03, -+0x7B, 0x60, 0x18, 0xF0, 0x02, 0x0F, 0x58, 0xD0, 0x4F, 0xF4, 0xA4, 0x66, 0x06, 0xFB, 0x0E, 0xA3, 0x03, 0xF1, 0xEC, 0x0B, -+0x00, 0x9E, 0x01, 0x93, 0xBB, 0xE8, 0x0F, 0x00, 0xB4, 0x46, 0x6E, 0x4E, 0x4F, 0xF4, 0x1E, 0x79, 0x09, 0xFB, 0x0C, 0x69, -+0x09, 0xF1, 0xC8, 0x0C, 0xAC, 0xE8, 0x0F, 0x00, 0x9B, 0xE8, 0x0F, 0x00, 0xD9, 0xF8, 0x04, 0xB0, 0x18, 0xF0, 0x08, 0x0F, -+0x4B, 0xF0, 0x02, 0x06, 0x8C, 0xE8, 0x0F, 0x00, 0xC9, 0xF8, 0x04, 0x60, 0x15, 0xD0, 0x01, 0x9B, 0x03, 0xF5, 0x8C, 0x76, -+0x0F, 0xCE, 0x09, 0xF1, 0xF4, 0x0C, 0xAC, 0xE8, 0x0F, 0x00, 0x0F, 0xCE, 0xAC, 0xE8, 0x0F, 0x00, 0x0F, 0xCE, 0xAC, 0xE8, -+0x0F, 0x00, 0x96, 0xE8, 0x03, 0x00, 0x8C, 0xE8, 0x03, 0x00, 0x4B, 0xF0, 0x22, 0x03, 0xC9, 0xF8, 0x04, 0x30, 0x18, 0xF0, -+0x04, 0x0F, 0x16, 0xD0, 0x4F, 0xF4, 0xA4, 0x63, 0x00, 0x9E, 0x03, 0xFB, 0x0E, 0xA3, 0x03, 0xF5, 0x86, 0x73, 0x93, 0xE8, -+0x07, 0x00, 0xB4, 0x46, 0x51, 0x4E, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x0C, 0x63, 0x03, 0xF1, 0xE8, 0x06, 0x86, 0xE8, -+0x07, 0x00, 0x5A, 0x68, 0x42, 0xF0, 0x04, 0x02, 0x5A, 0x60, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x0E, 0xA1, 0xEC, 0x31, -+0x38, 0x46, 0xFE, 0xF7, 0x81, 0xF8, 0x48, 0x4B, 0xD3, 0xF8, 0x14, 0x33, 0x98, 0x47, 0x47, 0x4B, 0x1B, 0x78, 0x00, 0x2B, -+0x66, 0xD0, 0x00, 0x9A, 0x42, 0x49, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x02, 0x13, 0x93, 0xF8, 0xB8, 0x20, 0x00, 0x23, -+0xCD, 0xE9, 0x02, 0x33, 0xCD, 0xE9, 0x05, 0x33, 0x04, 0x93, 0x07, 0x93, 0x00, 0x2A, 0x70, 0xD0, 0x01, 0x3A, 0xD2, 0xB2, -+0xB8, 0x34, 0x02, 0xAE, 0x0D, 0xF1, 0x14, 0x0C, 0x9B, 0x46, 0x0D, 0xF1, 0x09, 0x03, 0x01, 0x92, 0x0C, 0x44, 0x03, 0xEB, -+0x02, 0x09, 0x31, 0x46, 0x62, 0x46, 0x4F, 0xF0, 0x01, 0x08, 0x40, 0xF2, 0x05, 0x2A, 0x07, 0xE0, 0x01, 0xF8, 0x01, 0x0B, -+0x49, 0x45, 0x82, 0xF8, 0x00, 0x80, 0x02, 0xF1, 0x01, 0x02, 0x14, 0xD0, 0x14, 0xF8, 0x01, 0x0F, 0x00, 0xF0, 0x7F, 0x03, -+0x02, 0x3B, 0xDB, 0xB2, 0x09, 0x2B, 0x08, 0xFA, 0x03, 0xFE, 0xED, 0xD8, 0x1E, 0xEA, 0x0A, 0x0F, 0xEA, 0xD0, 0x01, 0xF8, -+0x01, 0x0B, 0x49, 0x45, 0x82, 0xF8, 0x00, 0xB0, 0x02, 0xF1, 0x01, 0x02, 0xEA, 0xD1, 0x01, 0x9A, 0x0C, 0xF1, 0x01, 0x03, -+0x1A, 0x44, 0x11, 0x46, 0x00, 0x9A, 0x10, 0x46, 0x1E, 0x4A, 0x4F, 0xF4, 0x1E, 0x74, 0x04, 0xFB, 0x00, 0x24, 0x00, 0xE0, -+0x01, 0x33, 0x9C, 0xF8, 0x00, 0x20, 0x9C, 0x46, 0x2A, 0xB1, 0x62, 0x19, 0x30, 0x78, 0x82, 0xF8, 0xB9, 0x00, 0x01, 0x35, -+0xED, 0xB2, 0x8B, 0x42, 0x06, 0xF1, 0x01, 0x06, 0xF0, 0xD1, 0x00, 0x9A, 0x11, 0x46, 0x13, 0x4A, 0x4F, 0xF4, 0x1E, 0x73, -+0x03, 0xFB, 0x01, 0x23, 0x83, 0xF8, 0xB8, 0x50, 0x38, 0x46, 0xFE, 0xF7, 0x1D, 0xFA, 0x00, 0x20, 0x09, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0x01, 0x20, 0x00, 0xF0, 0x98, 0xFD, 0x00, 0x20, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x06, 0x20, 0xF9, 0xF7, -+0x2D, 0xFD, 0x03, 0x28, 0x3F, 0xF4, 0xFD, 0xAE, 0x08, 0x49, 0x09, 0x48, 0x40, 0xF2, 0xF1, 0x12, 0xFB, 0xF7, 0x64, 0xFB, -+0xF5, 0xE6, 0x15, 0x46, 0xD9, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xB8, 0x34, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x40, 0xBB, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, 0x70, 0xB5, 0x06, 0x20, -+0xF9, 0xF7, 0x0E, 0xFD, 0x08, 0x28, 0x06, 0xD0, 0x06, 0x20, 0xF9, 0xF7, 0x09, 0xFD, 0x09, 0x28, 0x33, 0xD0, 0x00, 0x20, -+0x70, 0xBD, 0x22, 0x4A, 0x22, 0x4B, 0x14, 0x68, 0x94, 0xF8, 0x3D, 0x60, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x06, 0x36, -+0x06, 0x23, 0x1A, 0x46, 0x00, 0x21, 0x4B, 0x20, 0x96, 0xF8, 0x6C, 0x50, 0xF9, 0xF7, 0x52, 0xFA, 0x94, 0xF8, 0x3A, 0x20, -+0x02, 0x71, 0x22, 0x8F, 0x42, 0x80, 0x94, 0xF8, 0x3D, 0x20, 0x02, 0x70, 0xF9, 0xF7, 0x78, 0xFA, 0xD6, 0xF8, 0xB0, 0x34, -+0x15, 0x4A, 0xA1, 0x8E, 0x4F, 0xF4, 0x1E, 0x70, 0x03, 0xF0, 0x01, 0x03, 0x00, 0xFB, 0x05, 0x22, 0xC3, 0xF1, 0x02, 0x03, -+0x49, 0xBA, 0x02, 0x2B, 0x82, 0xF8, 0x30, 0x30, 0x91, 0x86, 0x08, 0xD0, 0x00, 0x20, 0x00, 0xF0, 0x39, 0xFD, 0x00, 0x20, -+0x70, 0xBD, 0x00, 0xF0, 0x1B, 0xFA, 0x00, 0x20, 0x70, 0xBD, 0x06, 0x22, 0x05, 0x21, 0x41, 0xF2, 0x19, 0x40, 0xF9, 0xF7, -+0x27, 0xFA, 0x00, 0x22, 0x02, 0x70, 0x94, 0xF8, 0x3D, 0x20, 0x42, 0x70, 0xF9, 0xF7, 0x50, 0xFA, 0xE8, 0xE7, 0x00, 0xBF, -+0x64, 0xBA, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x70, 0xB5, 0x06, 0x46, 0x06, 0x20, 0x0D, 0x46, -+0xF9, 0xF7, 0xB4, 0xFC, 0x2B, 0x46, 0x02, 0x46, 0x0A, 0x49, 0x04, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0xFB, 0xF7, 0xC2, 0xF8, -+0x08, 0x4B, 0x1D, 0x42, 0x04, 0xD0, 0x24, 0xF0, 0x02, 0x01, 0x89, 0xB2, 0x05, 0x29, 0x00, 0xD0, 0x70, 0xBD, 0x30, 0x46, -+0xE6, 0xF7, 0xDC, 0xFC, 0x01, 0x23, 0x86, 0xF8, 0x5E, 0x30, 0x70, 0xBD, 0x70, 0xBB, 0x15, 0x00, 0x00, 0x00, 0x03, 0x40, -+0x08, 0xB5, 0x0C, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0xDB, 0xBD, 0xE8, 0x08, 0x40, 0x09, 0x48, -+0xF9, 0xF7, 0x74, 0xBE, 0x08, 0x4B, 0xDB, 0x68, 0x00, 0x2B, 0xF6, 0xD0, 0x07, 0x48, 0x08, 0x49, 0x70, 0x22, 0xFB, 0xF7, -+0xC3, 0xFA, 0xBD, 0xE8, 0x08, 0x40, 0x02, 0x48, 0xF9, 0xF7, 0x66, 0xBE, 0x38, 0x36, 0x17, 0x00, 0x70, 0xBA, 0x17, 0x00, -+0x64, 0xBA, 0x17, 0x00, 0x80, 0xBB, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, 0x03, 0x4A, 0x04, 0x4B, 0x00, 0x21, 0x06, 0x20, -+0xD1, 0x75, 0x19, 0x60, 0xF9, 0xF7, 0xC4, 0xBB, 0x4C, 0x36, 0x17, 0x00, 0x64, 0xBA, 0x17, 0x00, 0x70, 0xB5, 0x11, 0x4B, -+0x1E, 0x68, 0x00, 0x23, 0x03, 0x60, 0x0B, 0x60, 0x96, 0xF8, 0x22, 0x30, 0xDB, 0x07, 0x05, 0x46, 0x0C, 0x46, 0x08, 0xD5, -+0x30, 0x46, 0x03, 0xF0, 0x57, 0xFB, 0x58, 0xB1, 0x83, 0x1C, 0x2B, 0x60, 0xC3, 0x6A, 0x23, 0x60, 0x70, 0xBD, 0x06, 0xF1, -+0x22, 0x00, 0x28, 0x60, 0x03, 0xF0, 0x46, 0xFB, 0x00, 0x28, 0xF5, 0xD1, 0x32, 0x8D, 0x4F, 0xF6, 0xFF, 0x73, 0x9A, 0x42, -+0x1C, 0xBF, 0x28, 0x36, 0x26, 0x60, 0x70, 0xBD, 0x64, 0xBA, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x3B, 0x4C, 0x4F, 0xF4, -+0xBA, 0x73, 0x06, 0x22, 0x84, 0xB0, 0x80, 0x46, 0x0F, 0x46, 0x4F, 0xF4, 0x80, 0x50, 0x04, 0x21, 0x25, 0x68, 0xF9, 0xF7, -+0x91, 0xF9, 0x95, 0xF8, 0x3D, 0x30, 0x80, 0xF8, 0x6E, 0x31, 0x04, 0x46, 0x0F, 0xCD, 0x4F, 0xF0, 0x00, 0x0C, 0x04, 0xF1, -+0xFC, 0x06, 0xC4, 0xF8, 0x68, 0xC1, 0xA4, 0xF8, 0x6C, 0xC1, 0x0F, 0xC6, 0x0F, 0xCD, 0x0F, 0xC6, 0x01, 0x23, 0x2A, 0x68, -+0x32, 0x70, 0x84, 0xF8, 0x70, 0x31, 0xB8, 0xF1, 0x00, 0x0F, 0x19, 0xD0, 0xD8, 0xF8, 0x00, 0x00, 0xC4, 0xF8, 0x60, 0x01, -+0xB8, 0xF8, 0x04, 0x30, 0xA4, 0xF8, 0x64, 0x31, 0xCF, 0xB1, 0x38, 0x68, 0x20, 0x60, 0xBB, 0x88, 0xA3, 0x80, 0x01, 0x23, -+0x84, 0xF8, 0x6F, 0x31, 0x20, 0x46, 0xF9, 0xF7, 0x95, 0xF9, 0x01, 0x21, 0x06, 0x20, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x41, -+0xF9, 0xF7, 0x58, 0xBB, 0x1C, 0x4B, 0x18, 0x68, 0x9B, 0x88, 0xC4, 0xF8, 0x60, 0x01, 0xA4, 0xF8, 0x64, 0x31, 0x00, 0x2F, -+0xE5, 0xD1, 0x19, 0x4B, 0x02, 0x93, 0x93, 0xF8, 0xFD, 0x50, 0x93, 0xF8, 0xFC, 0x00, 0x8D, 0xF8, 0x05, 0x50, 0x03, 0xF1, -+0x54, 0x02, 0x03, 0x92, 0x84, 0xF8, 0x6F, 0x71, 0x0D, 0xF1, 0x08, 0x0C, 0x06, 0x26, 0xB8, 0xB1, 0x5C, 0xF8, 0x27, 0x30, -+0x16, 0xFB, 0x00, 0x30, 0xDA, 0x78, 0x92, 0x07, 0x0D, 0xD4, 0x94, 0xF8, 0x6F, 0x21, 0x51, 0x1C, 0x84, 0xF8, 0x6F, 0x11, -+0x02, 0xEB, 0x42, 0x02, 0x19, 0x68, 0x44, 0xF8, 0x12, 0x10, 0x04, 0xEB, 0x42, 0x02, 0x99, 0x88, 0x91, 0x80, 0x06, 0x33, -+0x83, 0x42, 0xEB, 0xD1, 0x00, 0x2F, 0xC1, 0xD1, 0x28, 0x46, 0x01, 0x27, 0xE1, 0xE7, 0x00, 0xBF, 0x64, 0xBA, 0x17, 0x00, -+0xAC, 0xB2, 0x15, 0x00, 0x5A, 0xB9, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0x8B, 0x78, 0x0D, 0x46, 0x80, 0x46, 0x17, 0x46, -+0x1B, 0xB9, 0x37, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x49, 0xDB, 0x36, 0x4C, 0xDF, 0xF8, 0xEC, 0xA0, 0x4F, 0xF0, 0x00, 0x09, -+0x4F, 0xF4, 0xBA, 0x73, 0x06, 0x22, 0x04, 0x21, 0x41, 0xF2, 0x02, 0x00, 0xDA, 0xF8, 0x00, 0xB0, 0x84, 0xF8, 0x17, 0x90, -+0xF9, 0xF7, 0x04, 0xF9, 0x04, 0x46, 0x28, 0x68, 0x20, 0x60, 0x4F, 0xF0, 0x01, 0x0C, 0xB5, 0xF8, 0x04, 0xE0, 0x84, 0xF8, -+0x6F, 0xC1, 0x5E, 0x46, 0x0F, 0xCE, 0x04, 0xF1, 0xFC, 0x05, 0xA4, 0xF8, 0x04, 0xE0, 0x0F, 0xC5, 0x0F, 0xCE, 0x0F, 0xC5, -+0x33, 0x68, 0x2B, 0x70, 0x84, 0xF8, 0x70, 0xC1, 0xA4, 0xF8, 0x6C, 0x91, 0xC4, 0xF8, 0x68, 0x91, 0x9B, 0xF8, 0x3D, 0x30, -+0x84, 0xF8, 0x6E, 0x31, 0xD8, 0xF8, 0x00, 0x00, 0xC4, 0xF8, 0x60, 0x01, 0xB8, 0xF8, 0x04, 0x30, 0xA4, 0xF8, 0x64, 0x31, -+0x1F, 0xB1, 0xE3, 0x78, 0x43, 0xEA, 0x0C, 0x03, 0xE3, 0x70, 0xB7, 0xFA, 0x87, 0xF2, 0x20, 0x46, 0x52, 0x09, 0x8A, 0xF8, -+0x15, 0x20, 0xF9, 0xF7, 0x01, 0xF9, 0xBD, 0xE8, 0xF8, 0x4F, 0x02, 0x21, 0x06, 0x20, 0xF9, 0xF7, 0xC5, 0xBA, 0x12, 0x4B, -+0x10, 0x4C, 0xD3, 0xF8, 0x24, 0x31, 0x5B, 0x06, 0xB0, 0xD5, 0xE3, 0x7D, 0x01, 0x2B, 0xAD, 0xD1, 0x0E, 0x4A, 0x63, 0x70, -+0x13, 0x68, 0x0E, 0x49, 0x0E, 0x48, 0x23, 0xF0, 0x00, 0x43, 0x13, 0x60, 0x08, 0x60, 0x0D, 0x4A, 0xC4, 0xF8, 0x0C, 0x80, -+0x06, 0x21, 0x41, 0xF6, 0x09, 0x00, 0x25, 0x61, 0xA7, 0x75, 0xF8, 0xF7, 0x0D, 0xFF, 0xBD, 0xE8, 0xF8, 0x4F, 0xDC, 0xF7, -+0xF9, 0xB8, 0x00, 0xBF, 0x48, 0x30, 0x34, 0x40, 0x4C, 0x36, 0x17, 0x00, 0x00, 0x00, 0x50, 0x40, 0x34, 0x04, 0x32, 0x40, -+0x20, 0x04, 0x32, 0x40, 0x40, 0x1F, 0xDC, 0x05, 0xA0, 0x86, 0x01, 0x00, 0x64, 0xBA, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, -+0x27, 0x4D, 0xDF, 0xF8, 0xA0, 0x80, 0xAF, 0x7D, 0xD8, 0xF8, 0x00, 0x90, 0x4F, 0xF4, 0xBA, 0x73, 0x06, 0x22, 0x04, 0x21, -+0x41, 0xF2, 0x02, 0x00, 0xF9, 0xF7, 0x8A, 0xF8, 0x06, 0x21, 0x04, 0x46, 0x41, 0xF6, 0x09, 0x00, 0xF8, 0xF7, 0x92, 0xFF, -+0xD5, 0xE9, 0x03, 0x23, 0x4F, 0xF0, 0x00, 0x0C, 0x85, 0xF8, 0x17, 0xC0, 0x10, 0x68, 0xC4, 0xF8, 0x60, 0x01, 0x18, 0x68, -+0x95, 0x88, 0x20, 0x60, 0x4F, 0xF0, 0x01, 0x0E, 0xB3, 0xF8, 0x04, 0xA0, 0x84, 0xF8, 0x6F, 0xE1, 0x4E, 0x46, 0x0F, 0xCE, -+0xA4, 0xF8, 0x64, 0x51, 0x04, 0xF1, 0xFC, 0x05, 0xA4, 0xF8, 0x04, 0xA0, 0x0F, 0xC5, 0x0F, 0xCE, 0x0F, 0xC5, 0x33, 0x68, -+0x2B, 0x70, 0x84, 0xF8, 0x70, 0xE1, 0xA4, 0xF8, 0x6C, 0xC1, 0xC4, 0xF8, 0x68, 0xC1, 0x99, 0xF8, 0x3D, 0x30, 0x84, 0xF8, -+0x6E, 0x31, 0x1F, 0xB1, 0xE3, 0x78, 0x43, 0xEA, 0x0E, 0x03, 0xE3, 0x70, 0xB7, 0xFA, 0x87, 0xF3, 0x20, 0x46, 0x5B, 0x09, -+0x88, 0xF8, 0x15, 0x30, 0xF9, 0xF7, 0x7E, 0xF8, 0xBD, 0xE8, 0xF0, 0x47, 0x02, 0x21, 0x06, 0x20, 0xF9, 0xF7, 0x42, 0xBA, -+0x4C, 0x36, 0x17, 0x00, 0x64, 0xBA, 0x17, 0x00, 0x30, 0xB5, 0x14, 0x4A, 0x14, 0x4B, 0x11, 0x68, 0x14, 0x4A, 0x91, 0xF8, -+0x3D, 0x10, 0x54, 0x6C, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x01, 0xF2, 0x99, 0x18, 0x85, 0xB0, 0xD1, 0xF8, 0x90, 0x31, -+0x91, 0xF8, 0xC5, 0x51, 0x8D, 0xF8, 0x05, 0x50, 0x0A, 0x46, 0x99, 0x78, 0xD2, 0xF8, 0x94, 0x21, 0x8D, 0xF8, 0x04, 0x10, -+0x19, 0x88, 0x02, 0x92, 0x1A, 0x79, 0xAD, 0xF8, 0x06, 0x10, 0x8D, 0xF8, 0x0C, 0x20, 0xDB, 0x78, 0x8D, 0xF8, 0x0D, 0x30, -+0x01, 0x46, 0x01, 0xA8, 0xA0, 0x47, 0x05, 0xB0, 0x30, 0xBD, 0x00, 0xBF, 0x64, 0xBA, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x10, 0xB5, 0x0C, 0x48, 0xF9, 0xF7, 0xE2, 0xFC, 0x0B, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x04, 0x46, 0x05, 0xDB, 0x04, 0xF1, 0x0C, 0x00, 0xBD, 0xE8, 0x10, 0x40, 0xF9, 0xF7, 0x33, 0xB8, 0x00, 0x28, -+0xF7, 0xD1, 0x05, 0x49, 0x05, 0x48, 0x40, 0xF2, 0x0D, 0x22, 0xFB, 0xF7, 0xDD, 0xF8, 0xF0, 0xE7, 0x70, 0xBA, 0x17, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xA8, 0xAB, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x02, 0x23, 0x04, 0x46, -+0x06, 0x22, 0x05, 0x21, 0x41, 0xF2, 0x19, 0x40, 0xF8, 0xF7, 0xE8, 0xFF, 0x06, 0x22, 0x02, 0x23, 0x06, 0x46, 0x05, 0x21, -+0x41, 0xF2, 0x17, 0x40, 0xF8, 0xF7, 0xE0, 0xFF, 0x38, 0x4F, 0x39, 0x49, 0x05, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0xFA, 0xF7, -+0x91, 0xFE, 0xFF, 0xF7, 0xE1, 0xFD, 0x20, 0x46, 0xE5, 0xF7, 0x4A, 0xF8, 0x4F, 0xF0, 0x00, 0x08, 0x94, 0xF8, 0x6C, 0x00, -+0x7B, 0x6A, 0x98, 0x47, 0x86, 0xF8, 0x00, 0x80, 0x94, 0xF8, 0x63, 0x30, 0x73, 0x70, 0x2F, 0x48, 0xA6, 0xF1, 0x0C, 0x01, -+0xF9, 0xF7, 0x52, 0xFC, 0x94, 0xF8, 0x64, 0x30, 0x00, 0x2B, 0x3F, 0xD1, 0x94, 0xF8, 0x6C, 0x30, 0xFF, 0x2B, 0x0D, 0xD0, -+0x01, 0x23, 0x00, 0x21, 0x06, 0x22, 0x0C, 0x20, 0xF8, 0xF7, 0xB6, 0xFF, 0x01, 0x46, 0x94, 0xF8, 0x6C, 0x30, 0x01, 0xF8, -+0x0C, 0x39, 0x23, 0x48, 0xF9, 0xF7, 0x3C, 0xFC, 0x23, 0x6C, 0x6B, 0xB1, 0x01, 0x23, 0x00, 0x21, 0x06, 0x22, 0x39, 0x20, -+0xF8, 0xF7, 0xA6, 0xFF, 0x01, 0x46, 0x94, 0xF8, 0x63, 0x30, 0x01, 0xF8, 0x0C, 0x39, 0x1B, 0x48, 0xF9, 0xF7, 0x2C, 0xFC, -+0x00, 0x26, 0x2E, 0x70, 0x94, 0xF8, 0x63, 0x20, 0x18, 0x4B, 0x6A, 0x70, 0x93, 0xF8, 0x04, 0x31, 0x43, 0xB1, 0xD7, 0xF8, -+0xD8, 0x31, 0x04, 0xF1, 0x9C, 0x00, 0x98, 0x47, 0xC4, 0xE9, 0x24, 0x66, 0xC4, 0xF8, 0x98, 0x60, 0x00, 0x23, 0xA5, 0xF1, -+0x0C, 0x01, 0xC4, 0xF8, 0xCC, 0x31, 0x0E, 0x48, 0xF9, 0xF7, 0x12, 0xFC, 0xBD, 0xE8, 0xF0, 0x41, 0xFF, 0xF7, 0x6C, 0xBF, -+0x41, 0x46, 0x04, 0x23, 0x06, 0x22, 0x1E, 0x20, 0xF8, 0xF7, 0x7A, 0xFF, 0x80, 0xF8, 0x02, 0x80, 0x94, 0xF8, 0x63, 0x30, -+0xC3, 0x70, 0xA0, 0xF1, 0x0C, 0x01, 0x04, 0x48, 0xF9, 0xF7, 0xFE, 0xFB, 0xAE, 0xE7, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, -+0xA8, 0xBB, 0x15, 0x00, 0x70, 0xBA, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x6A, 0x4B, 0xDF, 0xF8, -+0xB4, 0xA1, 0x1D, 0x68, 0x83, 0xB0, 0x95, 0xF8, 0x3D, 0x20, 0x00, 0x92, 0x16, 0x46, 0x02, 0x23, 0x06, 0x22, 0x05, 0x21, -+0x41, 0xF2, 0x19, 0x40, 0xF8, 0xF7, 0x54, 0xFF, 0x08, 0x23, 0x81, 0x46, 0x06, 0x22, 0x00, 0x21, 0x18, 0x20, 0xF8, 0xF7, -+0x4D, 0xFF, 0x08, 0x23, 0x07, 0x46, 0x06, 0x22, 0x00, 0x21, 0x16, 0x20, 0xF8, 0xF7, 0x46, 0xFF, 0x4F, 0xF4, 0xA4, 0x64, -+0x04, 0xFB, 0x06, 0xF4, 0x04, 0x23, 0x06, 0x46, 0x06, 0x22, 0x00, 0x21, 0x14, 0x20, 0xF8, 0xF7, 0x3B, 0xFF, 0x02, 0x23, -+0x06, 0x22, 0x05, 0x21, 0x83, 0x46, 0x41, 0xF2, 0x17, 0x40, 0xF8, 0xF7, 0x33, 0xFF, 0x80, 0x46, 0xFF, 0xF7, 0x3A, 0xFD, -+0x4F, 0xF0, 0x01, 0x02, 0x89, 0xF8, 0x00, 0x20, 0x95, 0xF8, 0x3D, 0x30, 0x89, 0xF8, 0x01, 0x30, 0x0A, 0xEB, 0x04, 0x03, -+0x01, 0x93, 0x4B, 0x4B, 0xA9, 0xF1, 0x0C, 0x01, 0x03, 0xF1, 0x0C, 0x00, 0xF9, 0xF7, 0xAC, 0xFB, 0x01, 0x9B, 0xD3, 0xF8, -+0x64, 0x01, 0xB3, 0xF8, 0x68, 0x21, 0xBA, 0x80, 0x44, 0x4B, 0x38, 0x60, 0x95, 0xF8, 0x3D, 0x20, 0xBA, 0x71, 0x03, 0xF1, -+0x0C, 0x00, 0xA7, 0xF1, 0x0C, 0x01, 0xF9, 0xF7, 0x9B, 0xFB, 0x01, 0x9B, 0xD3, 0xF8, 0x90, 0x31, 0x04, 0xF5, 0xCE, 0x70, -+0x9B, 0x78, 0x73, 0x71, 0x01, 0x21, 0x50, 0x44, 0xFD, 0xF7, 0xFE, 0xFD, 0x73, 0x79, 0x30, 0x60, 0x95, 0xF8, 0x3D, 0x20, -+0x32, 0x71, 0x2B, 0xB9, 0xC1, 0x07, 0x4F, 0xD5, 0x36, 0x4B, 0x4F, 0xF4, 0x80, 0x62, 0x5A, 0x61, 0xA6, 0xF1, 0x0C, 0x01, -+0x34, 0x48, 0xF9, 0xF7, 0x7F, 0xFB, 0x00, 0x9B, 0x32, 0x48, 0x4F, 0xF4, 0xA4, 0x66, 0x06, 0xFB, 0x03, 0xA6, 0xAB, 0xF1, -+0x0C, 0x01, 0xB6, 0xF8, 0x98, 0x31, 0xAB, 0xF8, 0x00, 0x30, 0x95, 0xF8, 0x3D, 0x30, 0x8B, 0xF8, 0x02, 0x30, 0xF9, 0xF7, -+0x6D, 0xFB, 0xD6, 0xF8, 0xCC, 0x31, 0x1B, 0x07, 0x36, 0xD4, 0x04, 0xF5, 0xD6, 0x74, 0x00, 0x26, 0x26, 0x4F, 0xA2, 0x44, -+0x34, 0x46, 0x08, 0x23, 0x06, 0x22, 0x00, 0x21, 0x1A, 0x20, 0xF8, 0xF7, 0xCF, 0xFE, 0x5A, 0xF8, 0x04, 0x3B, 0x03, 0x60, -+0x46, 0x71, 0x95, 0xF8, 0x3D, 0x30, 0x83, 0x71, 0x04, 0x71, 0xA0, 0xF1, 0x0C, 0x01, 0x01, 0x36, 0x38, 0x46, 0xF9, 0xF7, -+0x4F, 0xFB, 0x04, 0x2E, 0xE9, 0xD1, 0x01, 0x23, 0x88, 0xF8, 0x00, 0x30, 0x95, 0xF8, 0x3D, 0x30, 0x17, 0x48, 0x88, 0xF8, -+0x01, 0x30, 0xA8, 0xF1, 0x0C, 0x01, 0xF9, 0xF7, 0x41, 0xFB, 0xFF, 0xF7, 0x9D, 0xFE, 0x31, 0x46, 0x06, 0x20, 0x03, 0xB0, -+0xBD, 0xE8, 0xF0, 0x4F, 0xF9, 0xF7, 0xA4, 0xB8, 0xC2, 0x06, 0xB1, 0xD5, 0x0D, 0x4B, 0x04, 0x22, 0x5A, 0x61, 0xAD, 0xE7, -+0x06, 0x22, 0x00, 0x21, 0x04, 0x23, 0x71, 0x20, 0xF8, 0xF7, 0x9E, 0xFE, 0x04, 0xF1, 0xEC, 0x03, 0x06, 0x46, 0x0A, 0xEB, -+0x03, 0x00, 0xFD, 0xF7, 0x0F, 0xFE, 0x31, 0x46, 0x03, 0x46, 0x41, 0xF8, 0x0C, 0x39, 0x04, 0x48, 0xF9, 0xF7, 0x1E, 0xFB, -+0xB3, 0xE7, 0x00, 0xBF, 0x64, 0xBA, 0x17, 0x00, 0xC4, 0x3C, 0x18, 0x00, 0x70, 0xBA, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0x06, 0x23, 0x2D, 0xE9, 0xF0, 0x41, 0x1A, 0x46, 0x04, 0x46, 0x0F, 0x46, 0x41, 0xF6, 0x05, 0x00, 0x0C, 0x21, 0xF8, 0xF7, -+0x7B, 0xFE, 0x38, 0x4E, 0x94, 0xF8, 0xC0, 0x34, 0xB4, 0x62, 0x05, 0x46, 0x00, 0x2B, 0x3F, 0xD0, 0x35, 0x4B, 0x9B, 0x68, -+0x00, 0x2B, 0x61, 0xD0, 0x93, 0xF8, 0x62, 0x20, 0x7A, 0xB9, 0x33, 0x49, 0x33, 0x4A, 0xD8, 0x6D, 0x08, 0x60, 0xB3, 0xF8, -+0x60, 0x10, 0x11, 0x60, 0x93, 0xF8, 0x64, 0x20, 0x2A, 0xB1, 0x30, 0x49, 0x98, 0x6B, 0x30, 0x4A, 0x08, 0x60, 0x99, 0x8F, -+0x11, 0x60, 0x2F, 0x4A, 0x12, 0x68, 0x00, 0x2A, 0x2C, 0xDB, 0xDF, 0xF8, 0xC4, 0x80, 0x00, 0x20, 0xDB, 0xF7, 0x86, 0xFE, -+0x00, 0x22, 0xD8, 0xF8, 0xD8, 0x31, 0x84, 0xF8, 0xAC, 0x20, 0x04, 0xF1, 0xB0, 0x00, 0x98, 0x47, 0xD8, 0xF8, 0x10, 0x33, -+0x20, 0x46, 0x98, 0x47, 0x2F, 0x80, 0x94, 0xF8, 0x63, 0x30, 0xAB, 0x70, 0xB3, 0x7D, 0x01, 0x2B, 0x08, 0xBF, 0xEB, 0x70, -+0xB3, 0x7F, 0xA3, 0xF1, 0x01, 0x03, 0xB3, 0xFA, 0x83, 0xF3, 0x5B, 0x09, 0xA5, 0xF1, 0x0C, 0x02, 0x2B, 0x71, 0xB2, 0x60, -+0xBD, 0xE8, 0xF0, 0x81, 0x1A, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0xD6, 0xDA, 0x13, 0x4B, 0x9B, 0x68, 0x00, 0x2B, 0xD2, 0xD0, -+0x00, 0x21, 0x93, 0xF8, 0x62, 0x20, 0x1A, 0xB9, 0x93, 0xF8, 0x64, 0x20, 0x02, 0xB1, 0x01, 0x31, 0x1B, 0x68, 0x00, 0x2B, -+0xF5, 0xD1, 0x01, 0x29, 0xC5, 0xD1, 0x11, 0x4A, 0x11, 0x49, 0x53, 0x70, 0x0B, 0x68, 0x11, 0x4A, 0x43, 0xF0, 0x00, 0x43, -+0x0B, 0x60, 0x13, 0x68, 0x1B, 0x0C, 0x1B, 0x04, 0x43, 0xF4, 0xBB, 0x63, 0x43, 0xF0, 0x04, 0x03, 0x13, 0x60, 0xB4, 0xE7, -+0x07, 0x4B, 0x1B, 0x68, 0xB1, 0xE7, 0x00, 0xBF, 0x64, 0xBA, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x10, 0x00, 0x32, 0x40, -+0x14, 0x00, 0x32, 0x40, 0x20, 0x00, 0x32, 0x40, 0x24, 0x00, 0x32, 0x40, 0x48, 0x30, 0x34, 0x40, 0x4C, 0x36, 0x17, 0x00, -+0x34, 0x04, 0x32, 0x40, 0x20, 0x04, 0x32, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x10, 0xB5, 0x0A, 0x46, 0x04, 0x46, 0x05, 0x49, -+0x4F, 0xF4, 0x80, 0x70, 0xFA, 0xF7, 0xA4, 0xFC, 0x20, 0x46, 0x00, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0x60, 0xBF, -+0xBC, 0xBB, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0xDF, 0xF8, 0xC8, 0x81, 0x4F, 0xF4, 0xA4, 0x64, 0x04, 0xFB, 0x00, 0x84, -+0x0B, 0x46, 0x02, 0x46, 0x06, 0x46, 0x0F, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0x66, 0x49, 0x94, 0xF8, 0x6C, 0x90, 0xFA, 0xF7, -+0x89, 0xFC, 0x94, 0xF8, 0x62, 0x50, 0x15, 0xB9, 0x94, 0xF8, 0x64, 0x30, 0x3B, 0xB9, 0xBD, 0xE8, 0xF8, 0x43, 0x06, 0x22, -+0x0C, 0x21, 0x41, 0xF6, 0x04, 0x00, 0xF8, 0xF7, 0x2B, 0xBE, 0x5E, 0x4B, 0x01, 0x25, 0x09, 0x21, 0x06, 0x20, 0x1D, 0x75, -+0xF8, 0xF7, 0xB6, 0xFF, 0x94, 0xF8, 0xC0, 0x34, 0x00, 0x2B, 0x79, 0xD1, 0xD4, 0xF8, 0x90, 0x31, 0x9D, 0x78, 0x2C, 0x1E, -+0x4F, 0xF4, 0xA4, 0x65, 0x05, 0xFB, 0x06, 0x85, 0x28, 0x46, 0x18, 0xBF, 0x01, 0x24, 0xE4, 0xF7, 0x11, 0xFD, 0x00, 0x28, -+0x74, 0xD0, 0x20, 0x46, 0x4F, 0xF4, 0xC0, 0x71, 0xE6, 0xF7, 0x72, 0xF8, 0x04, 0x46, 0x01, 0x46, 0x28, 0x46, 0x00, 0x2C, -+0x6C, 0xD0, 0xF8, 0xF7, 0x69, 0xF9, 0x4C, 0x4B, 0xD4, 0xF8, 0x48, 0x80, 0x4B, 0x49, 0xE8, 0x6D, 0x4F, 0xF4, 0x1E, 0x72, -+0x02, 0xFB, 0x09, 0x39, 0xB1, 0xF8, 0xFC, 0x31, 0x59, 0xF8, 0x26, 0x2F, 0xC8, 0xF8, 0x6C, 0x20, 0x6F, 0xF0, 0x3F, 0x02, -+0x88, 0xF8, 0x68, 0x20, 0xB9, 0xF8, 0x04, 0x20, 0xA8, 0xF8, 0x70, 0x20, 0xB5, 0xF8, 0x60, 0x20, 0xA8, 0xF8, 0x76, 0x20, -+0x01, 0x33, 0xD9, 0xF8, 0x00, 0x20, 0xC8, 0xF8, 0x72, 0x00, 0x9B, 0xB2, 0xB9, 0xF8, 0x04, 0x00, 0xC8, 0xF8, 0x78, 0x20, -+0x00, 0x22, 0xA8, 0xF8, 0x7C, 0x00, 0x88, 0xF8, 0x69, 0x20, 0x88, 0xF8, 0x6A, 0x20, 0x88, 0xF8, 0x6B, 0x20, 0x18, 0x01, -+0xA1, 0xF8, 0xFC, 0x31, 0x35, 0x4B, 0xA8, 0xF8, 0x7E, 0x00, 0x26, 0x77, 0xA5, 0x65, 0x63, 0x65, 0x95, 0xF8, 0x6C, 0x30, -+0x63, 0x77, 0x84, 0xF8, 0x33, 0x20, 0x84, 0xF8, 0x35, 0x20, 0xC0, 0x21, 0x20, 0x46, 0x07, 0xF0, 0x5F, 0xF9, 0x01, 0x28, -+0x06, 0x46, 0x08, 0xF1, 0x68, 0x09, 0x34, 0xD0, 0x39, 0x46, 0x08, 0xF1, 0x80, 0x00, 0xFB, 0xF7, 0xDD, 0xFD, 0x02, 0x2E, -+0x00, 0xF1, 0x18, 0x05, 0x3D, 0xD0, 0xE2, 0x6C, 0x53, 0x6A, 0x01, 0x3B, 0x2B, 0x44, 0x04, 0x35, 0xC2, 0xE9, 0x0A, 0x35, -+0x05, 0x21, 0x20, 0x46, 0xE6, 0xF7, 0x20, 0xF8, 0x05, 0x46, 0x88, 0xB1, 0xBD, 0xE8, 0xF8, 0x83, 0x2C, 0x46, 0x4F, 0xF4, -+0xA4, 0x65, 0x05, 0xFB, 0x06, 0x85, 0x28, 0x46, 0xE4, 0xF7, 0x9C, 0xFC, 0x00, 0x28, 0x8A, 0xD1, 0x01, 0x46, 0x28, 0x46, -+0xBD, 0xE8, 0xF8, 0x43, 0xFF, 0xF7, 0xA8, 0xBE, 0xA4, 0x6D, 0x17, 0x49, 0x02, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0xFA, 0xF7, -+0xDF, 0xFB, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF8, 0x43, 0xFF, 0xF7, 0x9B, 0xBE, 0x18, 0x22, 0x49, 0x46, 0x20, 0x46, -+0x05, 0xF0, 0x84, 0xFF, 0x94, 0xF8, 0x33, 0x50, 0x18, 0x35, 0x09, 0xEB, 0x05, 0x00, 0x39, 0x46, 0xFB, 0xF7, 0xA0, 0xFD, -+0x94, 0xF8, 0x35, 0x20, 0x15, 0x44, 0x05, 0x44, 0xC1, 0xE7, 0x2A, 0x46, 0x49, 0x46, 0x20, 0x46, 0x07, 0xF0, 0x4A, 0xF9, -+0x05, 0x44, 0xBA, 0xE7, 0xD4, 0xBB, 0x15, 0x00, 0x64, 0xBA, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, -+0xD1, 0x9D, 0x14, 0x00, 0xBC, 0xBB, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x66, 0x4D, 0x67, 0x49, -+0xD5, 0xE9, 0x00, 0x34, 0x93, 0xF8, 0x3D, 0x70, 0x67, 0x72, 0x0A, 0x68, 0x20, 0x80, 0x22, 0xF0, 0x10, 0x02, 0x4F, 0xF4, -+0xA4, 0x66, 0x83, 0xB0, 0x80, 0x46, 0x06, 0xFB, 0x07, 0xF6, 0x0A, 0x60, 0x00, 0x28, 0x6C, 0xD1, 0xDF, 0xF8, 0x98, 0x91, -+0x09, 0xEB, 0x06, 0x01, 0x91, 0xF8, 0x6C, 0x20, 0xD1, 0xF8, 0x64, 0x01, 0xB1, 0xF8, 0x68, 0xC1, 0xA2, 0x72, 0x0A, 0x6C, -+0xA4, 0xF8, 0x06, 0xC0, 0xC4, 0xF8, 0x02, 0x00, 0x10, 0x7E, 0xE0, 0x72, 0x10, 0x79, 0x84, 0xF8, 0x36, 0x03, 0xD0, 0x88, -+0xB2, 0xF8, 0x08, 0xC0, 0xA4, 0xF8, 0x38, 0x03, 0x50, 0x89, 0xC4, 0xE9, 0xCF, 0xC0, 0x52, 0x79, 0x84, 0xF8, 0x3A, 0x23, -+0xD1, 0xF8, 0xCC, 0x21, 0x02, 0xF0, 0x01, 0x02, 0x22, 0x73, 0x00, 0x2A, 0x6D, 0xD1, 0x42, 0x46, 0x62, 0x73, 0x1A, 0x6B, -+0x4F, 0xF4, 0xA4, 0x63, 0x02, 0xF0, 0x20, 0x02, 0x03, 0xFB, 0x07, 0x93, 0x22, 0x72, 0x93, 0xF8, 0xC0, 0x24, 0xA2, 0xB1, -+0xB3, 0xF8, 0x5E, 0x00, 0xB3, 0xF8, 0x5C, 0x20, 0x42, 0x49, 0x42, 0xEA, 0x00, 0x42, 0x0A, 0x60, 0x41, 0x4A, 0xB3, 0xF8, -+0x60, 0x10, 0x11, 0x60, 0x58, 0x8F, 0x1A, 0x8F, 0x3F, 0x49, 0x42, 0xEA, 0x00, 0x42, 0x0A, 0x60, 0x3E, 0x4A, 0x9B, 0x8F, -+0x13, 0x60, 0x20, 0x46, 0xF8, 0xF7, 0xC8, 0xFC, 0x94, 0xF8, 0x3A, 0x33, 0xB4, 0xF8, 0x3C, 0x03, 0x40, 0xEA, 0x03, 0x40, -+0x40, 0xF0, 0x00, 0x40, 0xDB, 0xF7, 0xC0, 0xFC, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x07, 0x97, 0x01, 0x22, 0x35, 0x4B, -+0x87, 0xF8, 0xAC, 0x20, 0x1A, 0x69, 0x34, 0x49, 0x34, 0x4B, 0x06, 0xF1, 0xB0, 0x00, 0x48, 0x44, 0x11, 0x44, 0xD3, 0xF8, -+0xE0, 0x31, 0x98, 0x47, 0x00, 0x21, 0x06, 0x20, 0xF8, 0xF7, 0x72, 0xFE, 0x12, 0xE0, 0x2F, 0x4B, 0x1B, 0x68, 0x00, 0x2B, -+0x26, 0xDB, 0x2E, 0x4B, 0x06, 0x20, 0x09, 0x21, 0x1E, 0x44, 0xF8, 0xF7, 0x67, 0xFE, 0x29, 0x4A, 0xAE, 0x62, 0xA4, 0xF1, -+0x0C, 0x03, 0xD2, 0xF8, 0x10, 0x23, 0xAB, 0x60, 0x30, 0x46, 0x90, 0x47, 0xB4, 0xF8, 0x34, 0x33, 0x62, 0x7A, 0x26, 0x49, -+0x00, 0x93, 0x4F, 0xF4, 0x80, 0x70, 0x43, 0x46, 0xFA, 0xF7, 0x12, 0xFB, 0x28, 0x68, 0x0C, 0x38, 0xF8, 0xF7, 0xD2, 0xFC, -+0x00, 0x23, 0x2B, 0x60, 0xAB, 0x75, 0xAB, 0x77, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x91, 0xF8, 0xBD, 0x21, 0x8F, 0xE7, -+0x1C, 0x4B, 0x9A, 0x68, 0x62, 0xB1, 0x00, 0x21, 0x92, 0xF8, 0x62, 0x30, 0x1B, 0xB9, 0x92, 0xF8, 0x64, 0x30, 0x03, 0xB1, -+0x01, 0x31, 0x12, 0x68, 0x00, 0x2A, 0xF5, 0xD1, 0x00, 0x29, 0xC8, 0xD1, 0x15, 0x4B, 0x16, 0x49, 0x00, 0x22, 0x5A, 0x70, -+0x0B, 0x68, 0x15, 0x4A, 0x43, 0xF0, 0x00, 0x43, 0x0B, 0x60, 0x13, 0x68, 0x1B, 0x0C, 0x1B, 0x04, 0x43, 0xF4, 0xBB, 0x63, -+0x43, 0xF0, 0x04, 0x03, 0x13, 0x60, 0xB6, 0xE7, 0x64, 0xBA, 0x17, 0x00, 0x94, 0x40, 0x04, 0x40, 0x10, 0x00, 0x32, 0x40, -+0x14, 0x00, 0x32, 0x40, 0x20, 0x00, 0x32, 0x40, 0x24, 0x00, 0x32, 0x40, 0x00, 0x10, 0x50, 0x40, 0x40, 0x4B, 0x4C, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x48, 0x30, 0x34, 0x40, 0x18, 0x88, 0x17, 0x00, 0xE8, 0xBB, 0x15, 0x00, 0x00, 0x88, 0x17, 0x00, -+0x4C, 0x36, 0x17, 0x00, 0x34, 0x04, 0x32, 0x40, 0x20, 0x04, 0x32, 0x40, 0x2D, 0xE9, 0xF0, 0x4F, 0x8B, 0x4B, 0x8C, 0x4E, -+0xD3, 0xF8, 0x00, 0x90, 0x8B, 0x4A, 0x99, 0xF8, 0x3D, 0x50, 0x4F, 0xF4, 0xA4, 0x64, 0x04, 0xFB, 0x05, 0x64, 0x89, 0xB0, -+0x07, 0x46, 0x88, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0x86, 0x49, 0x94, 0xF8, 0x6C, 0xA0, 0xFA, 0xF7, 0xAB, 0xFA, 0x94, 0xF8, -+0xC0, 0x34, 0x00, 0x2B, 0x40, 0xF0, 0x82, 0x80, 0xD4, 0xF8, 0x90, 0x31, 0x98, 0x78, 0x00, 0x38, 0x18, 0xBF, 0x01, 0x20, -+0x4F, 0xF4, 0xC0, 0x71, 0xE5, 0xF7, 0xB2, 0xFE, 0x04, 0x46, 0x00, 0x28, 0x7C, 0xD0, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, -+0x05, 0x65, 0x28, 0x46, 0x21, 0x46, 0xF7, 0xF7, 0xA5, 0xFF, 0x78, 0x4B, 0xA2, 0x6C, 0x78, 0x49, 0x4F, 0xF4, 0x1E, 0x70, -+0x00, 0xFB, 0x0A, 0x3A, 0x53, 0x46, 0xB1, 0xF8, 0xFC, 0x61, 0x53, 0xF8, 0x26, 0x0F, 0xD0, 0x66, 0x6F, 0xF0, 0x4F, 0x00, -+0x82, 0xF8, 0x68, 0x00, 0x98, 0x88, 0xA2, 0xF8, 0x70, 0x00, 0xE8, 0x6D, 0xC2, 0xF8, 0x72, 0x00, 0x01, 0x36, 0xB5, 0xF8, -+0x60, 0x00, 0xA2, 0xF8, 0x76, 0x00, 0x4F, 0xF0, 0x00, 0x0B, 0x18, 0x68, 0x9B, 0x88, 0xA2, 0xF8, 0x7C, 0x30, 0xB6, 0xB2, -+0x90, 0x67, 0x82, 0xF8, 0x69, 0xB0, 0x82, 0xF8, 0x6A, 0xB0, 0x82, 0xF8, 0x6B, 0xB0, 0x65, 0x4B, 0xA1, 0xF8, 0xFC, 0x61, -+0x30, 0x01, 0x95, 0xF8, 0x63, 0x10, 0xA2, 0xF8, 0x7E, 0x00, 0x21, 0x77, 0x95, 0xF8, 0x6C, 0x10, 0x1B, 0x68, 0x61, 0x77, -+0x84, 0xF8, 0x33, 0xB0, 0x84, 0xF8, 0x35, 0xB0, 0x1B, 0x78, 0x99, 0xF8, 0x3B, 0x10, 0x9B, 0x07, 0x02, 0xF1, 0x68, 0x05, -+0x38, 0xD4, 0x01, 0x29, 0x44, 0xD0, 0x18, 0x26, 0xCD, 0xF8, 0x00, 0x80, 0x3A, 0x46, 0xA8, 0x19, 0x00, 0x23, 0xFB, 0xF7, -+0xFF, 0xFB, 0x30, 0x44, 0xE1, 0x6C, 0x94, 0xF8, 0x35, 0x30, 0x4A, 0x6A, 0xA4, 0x65, 0x18, 0x44, 0x01, 0x3A, 0x02, 0x44, -+0x03, 0x1D, 0x50, 0x48, 0x60, 0x65, 0xC1, 0xE9, 0x0A, 0x23, 0x20, 0x46, 0x05, 0x21, 0xE5, 0xF7, 0x59, 0xFE, 0x4D, 0x4B, -+0x1B, 0x68, 0x06, 0x21, 0xDA, 0x68, 0x41, 0xF6, 0x08, 0x00, 0xF8, 0xF7, 0xD1, 0xF9, 0x05, 0x21, 0x06, 0x20, 0xF8, 0xF7, -+0x69, 0xFD, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x01, 0x20, 0x4F, 0xF4, 0xC0, 0x71, 0xE5, 0xF7, 0x35, 0xFE, 0x04, 0x46, -+0x00, 0x28, 0x82, 0xD1, 0x01, 0x20, 0xFF, 0xF7, 0x67, 0xFE, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x01, 0x29, 0x01, 0xD1, -+0x03, 0x2F, 0x17, 0xD0, 0xCD, 0xF8, 0x00, 0x80, 0x3A, 0x46, 0x05, 0xF1, 0x18, 0x00, 0x00, 0x23, 0xFB, 0xF7, 0xC4, 0xFB, -+0x18, 0x30, 0xC3, 0xE7, 0x03, 0x2F, 0xB8, 0xD1, 0x29, 0x46, 0x20, 0x46, 0x18, 0x22, 0x05, 0xF0, 0xB1, 0xFD, 0x94, 0xF8, -+0x33, 0x00, 0x99, 0xF8, 0x3B, 0x10, 0x00, 0xF1, 0x18, 0x06, 0xAD, 0xE7, 0xDA, 0xF8, 0xB4, 0x30, 0x29, 0x46, 0x18, 0x22, -+0x20, 0x46, 0x1E, 0x68, 0x05, 0xF0, 0xA2, 0xFD, 0x94, 0xF8, 0x33, 0x00, 0x99, 0xF8, 0x3B, 0x10, 0xCD, 0xF8, 0x00, 0x80, -+0x00, 0xF1, 0x18, 0x08, 0x05, 0xEB, 0x08, 0x09, 0x5B, 0x46, 0x3A, 0x46, 0x48, 0x46, 0xFB, 0xF7, 0x9D, 0xFB, 0x05, 0x46, -+0x3A, 0x46, 0x29, 0x46, 0x4F, 0xF0, 0xFF, 0x33, 0x48, 0x46, 0xDB, 0xF7, 0x67, 0xFD, 0x96, 0xF8, 0x60, 0x30, 0x21, 0x8F, -+0x62, 0x8F, 0xAD, 0xF8, 0x10, 0x10, 0x8D, 0xF8, 0x12, 0x20, 0x06, 0xF1, 0x64, 0x01, 0x93, 0xB1, 0x03, 0x2B, 0x1A, 0xD0, -+0x03, 0x20, 0xDB, 0xF7, 0x8F, 0xFD, 0x29, 0x1D, 0x02, 0x46, 0x89, 0xB2, 0x48, 0x46, 0x03, 0x91, 0xF7, 0xF7, 0x20, 0xFF, -+0x48, 0x46, 0x03, 0x99, 0xF8, 0xF7, 0x16, 0xF9, 0x05, 0xEB, 0x08, 0x00, 0x78, 0xE7, 0x05, 0x22, 0x0D, 0xF1, 0x13, 0x00, -+0x0C, 0xF0, 0x88, 0xFE, 0x04, 0xA8, 0x08, 0x21, 0xF8, 0xF7, 0xDE, 0xF8, 0xE4, 0xE7, 0x0D, 0x22, 0x0D, 0xF1, 0x13, 0x00, -+0x0C, 0xF0, 0x7E, 0xFE, 0x04, 0xA8, 0x10, 0x21, 0xF8, 0xF7, 0xD4, 0xF8, 0xDA, 0xE7, 0x00, 0xBF, 0x64, 0xBA, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x9C, 0xBC, 0x15, 0x00, 0xCC, 0xB5, 0x15, 0x00, 0x68, 0x65, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, -+0x34, 0x36, 0x17, 0x00, 0x89, 0x95, 0x14, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x77, 0x4F, 0x78, 0x4E, -+0xD7, 0xF8, 0x00, 0x80, 0x77, 0x4A, 0x98, 0xF8, 0x3D, 0x50, 0x77, 0x49, 0x4F, 0xF4, 0xA4, 0x64, 0x04, 0xFB, 0x05, 0x64, -+0x87, 0xB0, 0x4F, 0xF4, 0x80, 0x70, 0x94, 0xF8, 0x6C, 0xA0, 0xFA, 0xF7, 0x81, 0xF9, 0x94, 0xF8, 0xC0, 0x34, 0x00, 0x2B, -+0x40, 0xF0, 0xAA, 0x80, 0xD4, 0xF8, 0x90, 0x31, 0x98, 0x78, 0x00, 0x38, 0x18, 0xBF, 0x01, 0x20, 0x4F, 0xF4, 0xC0, 0x71, -+0xE5, 0xF7, 0x88, 0xFD, 0x04, 0x46, 0x00, 0x28, 0x00, 0xF0, 0xA5, 0x80, 0x4F, 0xF4, 0xA4, 0x6B, 0x0B, 0xFB, 0x05, 0xFB, -+0x06, 0xEB, 0x0B, 0x00, 0x21, 0x46, 0xD7, 0xF8, 0x04, 0x90, 0xF7, 0xF7, 0x77, 0xFE, 0xBA, 0x7D, 0xA3, 0x6C, 0x01, 0x2A, -+0x03, 0xF1, 0x68, 0x0C, 0x00, 0xF0, 0x99, 0x80, 0xBA, 0x7F, 0x00, 0x2A, 0x00, 0xF0, 0xA7, 0x80, 0x20, 0x22, 0x00, 0x21, -+0x83, 0xF8, 0x68, 0x20, 0x5B, 0x4A, 0x83, 0xF8, 0x69, 0x10, 0x5B, 0x49, 0x5B, 0x4F, 0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, -+0x0A, 0x10, 0xB7, 0xF8, 0xFC, 0xE1, 0x50, 0xF8, 0x26, 0xAF, 0xC3, 0xF8, 0x6C, 0xA0, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, -+0x05, 0x65, 0xB0, 0xF8, 0x04, 0xA0, 0xA3, 0xF8, 0x70, 0xA0, 0x0B, 0xF1, 0xEC, 0x01, 0x0E, 0xF1, 0x01, 0x0E, 0xD0, 0xF8, -+0x00, 0xA0, 0xB0, 0xF8, 0x04, 0xB0, 0xE8, 0x6D, 0xC3, 0xF8, 0x72, 0x00, 0x1F, 0xFA, 0x8E, 0xFE, 0x31, 0x44, 0x00, 0x26, -+0xB5, 0xF8, 0x60, 0x00, 0xC3, 0xF8, 0x78, 0xA0, 0x83, 0xF8, 0x6A, 0x60, 0x83, 0xF8, 0x6B, 0x60, 0x4F, 0xEA, 0x0E, 0x1A, -+0x46, 0x4E, 0xA3, 0xF8, 0x76, 0x00, 0xA3, 0xF8, 0x7C, 0xB0, 0x0C, 0xF1, 0x18, 0x00, 0xA7, 0xF8, 0xFC, 0xE1, 0x0D, 0xF1, -+0x12, 0x0C, 0xA3, 0xF8, 0x7E, 0xA0, 0x05, 0xAF, 0x95, 0xF8, 0x63, 0x30, 0xCD, 0xF8, 0x08, 0x80, 0xD6, 0xF8, 0x58, 0x61, -+0xCD, 0xE9, 0x00, 0x7C, 0xB0, 0x47, 0x95, 0xF8, 0x63, 0x30, 0x23, 0x77, 0x95, 0xF8, 0x6C, 0x30, 0xE1, 0x6C, 0x63, 0x77, -+0x4B, 0x6A, 0xBD, 0xF8, 0x12, 0x20, 0x37, 0x4D, 0xA4, 0x65, 0x17, 0x33, 0x03, 0x44, 0xB2, 0xF5, 0x48, 0x7F, 0x00, 0xF1, -+0x1C, 0x00, 0x65, 0x65, 0xC1, 0xE9, 0x0A, 0x30, 0x3B, 0xD8, 0x05, 0x98, 0x6A, 0xB1, 0x4A, 0x44, 0x13, 0x38, 0x13, 0x32, -+0xA0, 0xEB, 0x09, 0x00, 0x09, 0xF1, 0x13, 0x03, 0xC1, 0x5C, 0x03, 0xF8, 0x01, 0x1F, 0x93, 0x42, 0xFA, 0xD1, 0xBD, 0xF8, -+0x12, 0x20, 0xA9, 0xF8, 0x0E, 0x20, 0x20, 0x46, 0x05, 0x21, 0xE5, 0xF7, 0x07, 0xFD, 0x27, 0x4B, 0x1B, 0x68, 0x06, 0x21, -+0x9A, 0x68, 0x41, 0xF6, 0x08, 0x00, 0xF8, 0xF7, 0x7F, 0xF8, 0x07, 0x21, 0x06, 0x20, 0xF8, 0xF7, 0x17, 0xFC, 0x07, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0x01, 0x20, 0x4F, 0xF4, 0xC0, 0x71, 0xE5, 0xF7, 0xE3, 0xFC, 0x04, 0x46, 0x00, 0x28, 0x7F, 0xF4, -+0x5B, 0xAF, 0x01, 0x20, 0xFF, 0xF7, 0x14, 0xFD, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x20, 0x22, 0x00, 0x21, 0x83, 0xF8, -+0x68, 0x20, 0x83, 0xF8, 0x69, 0x10, 0x16, 0x4A, 0x69, 0xE7, 0x16, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0x08, 0xDB, 0x00, 0x23, 0xA9, 0xF8, 0x0E, 0x30, 0xCB, 0xE7, 0x83, 0xF8, 0x68, 0x20, 0x83, 0xF8, 0x69, 0x20, 0x5A, 0xE7, -+0x0F, 0x49, 0x10, 0x48, 0x4F, 0xF4, 0x82, 0x62, 0xFA, 0xF7, 0xE8, 0xFA, 0xEF, 0xE7, 0x00, 0xBF, 0x64, 0xBA, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0xAC, 0xBC, 0x15, 0x00, 0xCC, 0xB5, 0x15, 0x00, 0x84, 0xBA, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x20, 0x62, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x89, 0x95, 0x14, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x7C, 0xBA, 0x17, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x38, 0xB5, 0x0B, 0x4D, 0x04, 0x46, 0x04, 0x23, -+0x00, 0x21, 0x06, 0x22, 0x1E, 0x20, 0x2D, 0x68, 0xF8, 0xF7, 0xC6, 0xF9, 0x01, 0x22, 0x04, 0x80, 0x82, 0x70, 0x95, 0xF8, -+0x3D, 0x20, 0xC2, 0x70, 0xF8, 0xF7, 0xEE, 0xF9, 0xBD, 0xE8, 0x38, 0x40, 0x08, 0x21, 0x06, 0x20, 0xF8, 0xF7, 0xB2, 0xBB, -+0x64, 0xBA, 0x17, 0x00, 0x70, 0xB5, 0x00, 0xF1, 0x0C, 0x06, 0x06, 0x21, 0x04, 0x46, 0x41, 0xF6, 0x08, 0x00, 0xF8, 0xF7, -+0xBB, 0xF8, 0xB5, 0x88, 0x19, 0x49, 0x2A, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0xFA, 0xF7, 0x5E, 0xF8, 0x45, 0xB9, 0xA3, 0x89, -+0x13, 0xB1, 0x01, 0x2B, 0x09, 0xD0, 0x70, 0xBD, 0xBD, 0xE8, 0x70, 0x40, 0xFF, 0xF7, 0xBE, 0xBE, 0x28, 0x46, 0xBD, 0xE8, -+0x70, 0x40, 0xFF, 0xF7, 0x9D, 0xBC, 0x73, 0x88, 0x04, 0x2B, 0xF3, 0xD0, 0x02, 0x2B, 0x11, 0xD0, 0x0D, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0xDB, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0x20, 0xFF, 0xF7, 0x8D, 0xBC, 0x09, 0x49, -+0x09, 0x48, 0x4F, 0xF4, 0x8C, 0x62, 0xFA, 0xF7, 0x7B, 0xFA, 0xF3, 0xE7, 0x04, 0xF1, 0x14, 0x01, 0x03, 0x20, 0xBD, 0xE8, -+0x70, 0x40, 0xFF, 0xF7, 0x6F, 0xBD, 0x00, 0xBF, 0x00, 0xBC, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x64, 0x7D, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x69, 0x4B, 0xD3, 0xE9, 0x00, 0x2A, 0x05, 0x46, 0x83, 0xB0, 0x06, 0x21, -+0x00, 0x24, 0x41, 0xF6, 0x08, 0x00, 0x92, 0xF8, 0x3D, 0x80, 0x8D, 0xF8, 0x06, 0x40, 0xF8, 0xF7, 0x6D, 0xF8, 0x29, 0x88, -+0xEE, 0x89, 0x4F, 0xF4, 0xA4, 0x67, 0x05, 0x29, 0x05, 0xF1, 0x0C, 0x09, 0x07, 0xFB, 0x08, 0xF7, 0x34, 0xD9, 0xBA, 0xF8, -+0x0E, 0x30, 0x06, 0x39, 0x89, 0xB2, 0xCA, 0x18, 0x05, 0xF1, 0x12, 0x0B, 0xB2, 0xF5, 0x48, 0x7F, 0x5C, 0x46, 0x09, 0xDD, -+0x58, 0x4A, 0x12, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xC0, 0xF2, 0x81, 0x80, 0xC3, 0xF5, 0x48, 0x71, 0x89, 0xB2, -+0x0A, 0xF1, 0x14, 0x00, 0x18, 0x44, 0x8B, 0x44, 0x39, 0xB1, 0xA4, 0xF1, 0x12, 0x03, 0x14, 0xF8, 0x01, 0x2B, 0x5B, 0x1B, -+0x5C, 0x45, 0x1A, 0x54, 0xF7, 0xD1, 0xAA, 0xF8, 0x10, 0x10, 0x32, 0x46, 0x4C, 0x49, 0x4F, 0xF4, 0x80, 0x70, 0xF9, 0xF7, -+0xE3, 0xFF, 0x9E, 0xB1, 0x4A, 0x4B, 0x93, 0xF8, 0x04, 0x31, 0x2B, 0xBB, 0x30, 0x46, 0xFF, 0xF7, 0x29, 0xFC, 0x03, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0x44, 0x49, 0xAA, 0xF8, 0x10, 0x40, 0x32, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0xF9, 0xF7, 0xD0, 0xFF, -+0x00, 0x2E, 0xEB, 0xD1, 0xB9, 0xF8, 0x04, 0x00, 0x40, 0x4C, 0xC0, 0xF3, 0x0D, 0x00, 0xFF, 0xF7, 0x3F, 0xFF, 0x3D, 0x4B, -+0x93, 0xF8, 0x04, 0x31, 0x63, 0xB3, 0x4F, 0xF4, 0xA4, 0x65, 0x05, 0xFB, 0x08, 0x45, 0xD5, 0xF8, 0x90, 0x31, 0x9A, 0x78, -+0x01, 0x2A, 0x48, 0xD0, 0x38, 0x4E, 0x28, 0xE0, 0x12, 0x2E, 0xD7, 0xD1, 0x35, 0x4B, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, -+0x08, 0x38, 0xD8, 0xF8, 0x90, 0x21, 0x92, 0x78, 0x01, 0x2A, 0xCD, 0xD1, 0x98, 0xF8, 0xC0, 0x44, 0x00, 0x2C, 0xC9, 0xD1, -+0x30, 0x4D, 0x07, 0xF5, 0xB2, 0x77, 0x1F, 0x44, 0xA8, 0x46, 0x40, 0x46, 0x06, 0x22, 0x39, 0x46, 0x0C, 0xF0, 0x3E, 0xFC, -+0x08, 0xF1, 0x14, 0x08, 0x00, 0x28, 0x3F, 0xD0, 0x01, 0x34, 0x05, 0x2C, 0xF3, 0xD1, 0xB7, 0xE7, 0x4F, 0xF4, 0xA4, 0x63, -+0x03, 0xFB, 0x08, 0x43, 0x24, 0x4E, 0xD3, 0xF8, 0x90, 0x31, 0x1B, 0x79, 0xD6, 0xF8, 0x40, 0x53, 0x4F, 0xF4, 0xA4, 0x62, -+0x02, 0xFB, 0x08, 0x48, 0xE0, 0x19, 0x98, 0xF8, 0xC6, 0x21, 0x9B, 0x1A, 0x8D, 0xF8, 0x07, 0x30, 0x0D, 0xF1, 0x06, 0x02, -+0x0D, 0xF1, 0x07, 0x01, 0xA8, 0x47, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1A, 0x49, 0x1B, 0x48, 0x40, 0xF2, 0x8B, 0x42, -+0xFA, 0xF7, 0xB6, 0xF9, 0xBA, 0xF8, 0x0E, 0x30, 0x75, 0xE7, 0xD5, 0xF8, 0xCC, 0x21, 0x12, 0xF0, 0x0C, 0x0F, 0xB1, 0xD0, -+0x95, 0xF8, 0xC0, 0x24, 0x00, 0x2A, 0xAD, 0xD1, 0x13, 0x4B, 0x14, 0x49, 0x1B, 0x69, 0x0E, 0x4E, 0x07, 0xF1, 0x9C, 0x00, -+0x19, 0x44, 0x20, 0x44, 0xD6, 0xF8, 0xE0, 0x31, 0x98, 0x47, 0xD5, 0xF8, 0x90, 0x31, 0xCA, 0xE7, 0x04, 0xEB, 0x84, 0x04, -+0x05, 0xEB, 0x84, 0x04, 0x01, 0x23, 0xE3, 0x71, 0x74, 0xE7, 0x00, 0xBF, 0x64, 0xBA, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x14, 0xBC, 0x15, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xCC, 0x35, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x00, 0x10, 0x50, 0x40, 0x80, 0x96, 0x98, 0x00, 0x2D, 0xE9, 0xF0, 0x47, -+0x04, 0x46, 0x06, 0x20, 0x25, 0x7A, 0xF8, 0xF7, 0x1F, 0xFB, 0x09, 0x28, 0x0A, 0xD0, 0x06, 0x20, 0xF8, 0xF7, 0x1A, 0xFB, -+0x48, 0xB1, 0x2D, 0x4A, 0x23, 0x7A, 0x12, 0x68, 0x92, 0xF8, 0x3D, 0x20, 0x9A, 0x42, 0x0D, 0xD0, 0x02, 0x20, 0xBD, 0xE8, -+0xF0, 0x87, 0x29, 0x4F, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x05, 0xF5, 0x7E, 0x19, 0x96, 0xF8, 0x64, 0x00, 0x60, 0xB9, -+0xBD, 0xE8, 0xF0, 0x87, 0x24, 0x49, 0x4F, 0xF4, 0x80, 0x70, 0xF9, 0xF7, 0x15, 0xFF, 0x01, 0x20, 0xFF, 0xF7, 0x60, 0xFB, -+0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0xA4, 0x89, 0x1F, 0x49, 0x22, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0xF9, 0xF7, 0x08, 0xFF, -+0x1D, 0x4B, 0x93, 0xF8, 0x04, 0x31, 0x0B, 0xB1, 0x08, 0x2C, 0x0A, 0xD0, 0x09, 0x21, 0x06, 0x20, 0xF8, 0xF7, 0x40, 0xFA, -+0x78, 0x19, 0x21, 0x46, 0xFF, 0xF7, 0xBC, 0xF9, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0xD6, 0xF8, 0x90, 0x31, 0x9B, 0x78, -+0x01, 0x2B, 0xEF, 0xD1, 0x96, 0xF8, 0xC0, 0x64, 0x00, 0x2E, 0xEB, 0xD1, 0xDF, 0xF8, 0x44, 0x90, 0x05, 0xF5, 0xB2, 0x7A, -+0xC8, 0x46, 0xBA, 0x44, 0x40, 0x46, 0x06, 0x22, 0x51, 0x46, 0x0C, 0xF0, 0x83, 0xFB, 0x08, 0xF1, 0x14, 0x08, 0x18, 0xB1, -+0x01, 0x36, 0x05, 0x2E, 0xF4, 0xD1, 0xD9, 0xE7, 0x06, 0xEB, 0x86, 0x06, 0x09, 0xEB, 0x86, 0x06, 0x01, 0x23, 0xB3, 0x71, -+0xD2, 0xE7, 0x00, 0xBF, 0x64, 0xBA, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x2C, 0xBC, 0x15, 0x00, 0x50, 0xBC, 0x15, 0x00, -+0x2C, 0x19, 0x17, 0x00, 0xCC, 0x35, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x46, 0x4B, 0x04, 0x7A, 0x4F, 0xF4, 0xA4, 0x62, -+0x02, 0xFB, 0x04, 0x34, 0x94, 0xF8, 0x64, 0x30, 0xC3, 0xB1, 0x94, 0xF8, 0x62, 0x30, 0xAB, 0xB9, 0xC3, 0x79, 0xFF, 0x2B, -+0x05, 0x46, 0x11, 0xD0, 0x94, 0xF8, 0x6C, 0x20, 0x9A, 0x42, 0x0D, 0xD1, 0x3D, 0x4E, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, -+0x02, 0x66, 0x96, 0xF8, 0x30, 0x30, 0x02, 0x2B, 0x04, 0xD1, 0x90, 0xF8, 0x0D, 0x90, 0xB9, 0xF1, 0x00, 0x0F, 0x01, 0xD0, -+0xBD, 0xE8, 0xF8, 0x83, 0x80, 0x79, 0xB5, 0xF8, 0x0E, 0x80, 0x00, 0x38, 0x18, 0xBF, 0x01, 0x20, 0x4F, 0xF4, 0xC0, 0x71, -+0xE5, 0xF7, 0xAE, 0xFA, 0x07, 0x46, 0x00, 0x28, 0xF0, 0xD0, 0x01, 0x46, 0x20, 0x46, 0xF7, 0xF7, 0xA5, 0xFB, 0x32, 0x46, -+0xDF, 0xF8, 0xB4, 0xC0, 0xBB, 0x6C, 0x52, 0xF8, 0x26, 0x0F, 0xBC, 0xF8, 0xFC, 0x11, 0xD8, 0x66, 0x6F, 0xF0, 0x2F, 0x00, -+0x83, 0xF8, 0x68, 0x00, 0x01, 0x31, 0x90, 0x88, 0xA3, 0xF8, 0x70, 0x00, 0x89, 0xB2, 0xE0, 0x6D, 0xB4, 0xF8, 0x60, 0x40, -+0xA3, 0xF8, 0x76, 0x40, 0xC3, 0xF8, 0x72, 0x00, 0x14, 0x68, 0x90, 0x88, 0x83, 0xF8, 0x69, 0x90, 0x0A, 0x01, 0x83, 0xF8, -+0x6A, 0x90, 0x83, 0xF8, 0x6B, 0x90, 0x9C, 0x67, 0xA3, 0xF8, 0x7C, 0x00, 0xAC, 0xF8, 0xFC, 0x11, 0xA3, 0xF8, 0x7E, 0x20, -+0x2A, 0x7A, 0x3A, 0x77, 0xEA, 0x79, 0x7A, 0x77, 0x03, 0xF1, 0x68, 0x04, 0x87, 0xF8, 0x33, 0x90, 0x87, 0xF8, 0x35, 0x90, -+0x08, 0x22, 0xD0, 0x21, 0x38, 0x46, 0x06, 0xF0, 0xA5, 0xFB, 0x21, 0x46, 0x38, 0x46, 0x18, 0x22, 0x05, 0xF0, 0x04, 0xFA, -+0x97, 0xF8, 0x33, 0x30, 0x18, 0x33, 0x1A, 0x19, 0x08, 0x21, 0x19, 0x55, 0x01, 0x21, 0x51, 0x70, 0xF9, 0x6C, 0xA2, 0xF8, -+0x02, 0x80, 0x97, 0xF8, 0x35, 0x00, 0x4A, 0x6A, 0x04, 0x30, 0x03, 0x44, 0x01, 0x3A, 0x1A, 0x44, 0x04, 0x33, 0xC1, 0xE9, -+0x0A, 0x23, 0x38, 0x46, 0x05, 0x21, 0xBD, 0xE8, 0xF8, 0x43, 0xE5, 0xF7, 0x5F, 0xBA, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, -+0x68, 0x65, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x31, 0x4B, 0x32, 0x4A, 0x1B, 0x68, 0x2D, 0xE9, 0xF0, 0x41, 0xB3, 0xF9, -+0x00, 0x30, 0xD2, 0xF8, 0x00, 0x80, 0x2F, 0x4F, 0x98, 0xF8, 0x3D, 0x50, 0x00, 0x2B, 0x06, 0x46, 0x45, 0xDB, 0x2C, 0x23, -+0x06, 0x22, 0x0C, 0x21, 0x41, 0xF6, 0x06, 0x00, 0xF7, 0xF7, 0x64, 0xFF, 0x4F, 0xF4, 0xA4, 0x61, 0x03, 0x46, 0x98, 0xF8, -+0x3D, 0x20, 0x03, 0xF8, 0x01, 0x2B, 0x01, 0xFB, 0x05, 0x71, 0x01, 0xF5, 0xB5, 0x72, 0x04, 0x46, 0x01, 0xF5, 0xC5, 0x71, -+0xD2, 0xF8, 0x00, 0xE0, 0xD2, 0xF8, 0x04, 0xC0, 0x90, 0x68, 0xD2, 0xF8, 0x0C, 0x80, 0xC3, 0xF8, 0x0C, 0x80, 0x10, 0x32, -+0x8A, 0x42, 0xC3, 0xF8, 0x00, 0xE0, 0xC3, 0xF8, 0x04, 0xC0, 0x98, 0x60, 0x03, 0xF1, 0x10, 0x03, 0xEC, 0xD1, 0x4F, 0xF4, -+0xA4, 0x61, 0x12, 0x78, 0x1A, 0x70, 0x01, 0xFB, 0x05, 0x75, 0x36, 0xBA, 0xD5, 0xF8, 0x64, 0x01, 0xB5, 0xF8, 0x68, 0x31, -+0xE3, 0x84, 0x06, 0x21, 0xC4, 0xF8, 0x22, 0x00, 0xA6, 0x62, 0x08, 0x46, 0xF8, 0xF7, 0x2A, 0xF9, 0x41, 0xF6, 0x08, 0x00, -+0x0E, 0x4A, 0x06, 0x21, 0xF7, 0xF7, 0x88, 0xFD, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xF7, 0xF7, 0x55, 0xBF, 0x4F, 0xF4, -+0xA4, 0x63, 0x03, 0xFB, 0x05, 0x73, 0xD3, 0xF8, 0xCC, 0x31, 0x00, 0x2B, 0xB1, 0xDB, 0x07, 0x49, 0x07, 0x48, 0x4F, 0xF4, -+0xAB, 0x62, 0xF9, 0xF7, 0xF9, 0xFF, 0xAA, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x64, 0xBA, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0xC0, 0x27, 0x09, 0x00, 0x70, 0x79, 0x15, 0x00, 0x74, 0xBC, 0x15, 0x00, 0x10, 0xB5, 0x06, 0x21, 0x04, 0x46, 0x41, 0xF6, -+0x08, 0x00, 0xF7, 0xF7, 0x11, 0xFE, 0x1C, 0xB9, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0x20, 0xBC, 0x20, 0x46, 0xBD, 0xE8, -+0x10, 0x40, 0xFF, 0xF7, 0xFF, 0xB9, 0x00, 0xBF, 0x08, 0xB5, 0x06, 0x20, 0xF8, 0xF7, 0x96, 0xF9, 0xA0, 0xF1, 0x06, 0x00, -+0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x08, 0xBD, 0x00, 0xB5, 0x83, 0xB0, 0x0D, 0xF1, 0x07, 0x02, 0xF8, 0xF7, 0xDE, 0xFD, -+0xB8, 0xB1, 0x9D, 0xF8, 0x07, 0x30, 0x1D, 0x2B, 0x16, 0xD9, 0x02, 0x89, 0x92, 0x00, 0x0A, 0x3B, 0x92, 0xB2, 0x9B, 0x1A, -+0xDB, 0xB2, 0x15, 0x2B, 0x0E, 0xD9, 0x0A, 0x30, 0x02, 0x3B, 0x81, 0x5A, 0x89, 0x00, 0x89, 0xB2, 0x5B, 0x1A, 0xDB, 0xB2, -+0x13, 0x2B, 0x10, 0x44, 0x04, 0xD9, 0x04, 0x30, 0x40, 0x5A, 0x03, 0xB0, 0x5D, 0xF8, 0x04, 0xFB, 0x00, 0x20, 0x03, 0xB0, -+0x5D, 0xF8, 0x04, 0xFB, 0x2D, 0xE9, 0xF0, 0x4F, 0x4F, 0xF4, 0xA4, 0x68, 0x95, 0xB0, 0xDF, 0xF8, 0x50, 0x93, 0xDF, 0xF8, -+0x50, 0xB3, 0x08, 0xFB, 0x00, 0xF3, 0x07, 0x93, 0x4B, 0x44, 0x05, 0x46, 0xD3, 0xF8, 0x90, 0x01, 0x93, 0xF8, 0x6C, 0x40, -+0x80, 0x78, 0x02, 0x93, 0x17, 0x46, 0x4F, 0xF4, 0x1E, 0x78, 0x00, 0x38, 0x08, 0xFB, 0x04, 0xB6, 0x0A, 0x46, 0x3B, 0x78, -+0xD6, 0xF8, 0xB0, 0xA0, 0x04, 0x94, 0x18, 0xBF, 0x01, 0x20, 0x4F, 0xF4, 0xC0, 0x71, 0x05, 0x92, 0x06, 0x93, 0xE5, 0xF7, -+0x6F, 0xF9, 0x00, 0x28, 0x00, 0xF0, 0xED, 0x80, 0x02, 0x9B, 0x04, 0x46, 0x21, 0x46, 0x18, 0x46, 0xF7, 0xF7, 0x64, 0xFA, -+0xB9, 0x4B, 0x96, 0xF8, 0x23, 0x00, 0xD3, 0xF8, 0x34, 0x21, 0xA3, 0x6C, 0x02, 0x93, 0x00, 0x21, 0x90, 0x47, 0x02, 0x9B, -+0x03, 0x90, 0x03, 0xF1, 0x68, 0x02, 0x08, 0x92, 0x00, 0x28, 0x40, 0xF0, 0xD9, 0x80, 0xB2, 0x49, 0xB1, 0xF8, 0xFC, 0x21, -+0x01, 0x32, 0x92, 0xB2, 0x08, 0x20, 0x83, 0xF8, 0x68, 0x00, 0x10, 0x01, 0x01, 0x26, 0x80, 0xB2, 0x83, 0xF8, 0x69, 0x60, -+0x09, 0x90, 0xA1, 0xF8, 0xFC, 0x21, 0x04, 0x99, 0x02, 0x93, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x01, 0xB2, 0x4F, 0xF4, -+0xA4, 0x66, 0x52, 0xF8, 0x26, 0x1F, 0xD9, 0x66, 0x06, 0xFB, 0x05, 0x96, 0x91, 0x88, 0xF0, 0x6D, 0xB6, 0xF8, 0x60, 0x20, -+0xA3, 0xF8, 0x76, 0x20, 0x4F, 0xF0, 0x00, 0x08, 0xA3, 0xF8, 0x70, 0x10, 0xC3, 0xF8, 0x72, 0x00, 0x05, 0x99, 0x83, 0xF8, -+0x6A, 0x80, 0x83, 0xF8, 0x6B, 0x80, 0x06, 0x22, 0x03, 0xF1, 0x78, 0x00, 0x0C, 0xF0, 0xDC, 0xF9, 0x09, 0x9B, 0x96, 0xF8, -+0x63, 0x20, 0x19, 0x01, 0x02, 0x9B, 0xA3, 0xF8, 0x7E, 0x10, 0x22, 0x77, 0x96, 0xF8, 0x6C, 0x20, 0x62, 0x77, 0x03, 0x9A, -+0x00, 0x2A, 0x00, 0xF0, 0xE1, 0x80, 0x1A, 0x22, 0x83, 0xF8, 0x80, 0x80, 0x83, 0xF8, 0x81, 0x80, 0x02, 0x92, 0x7A, 0x78, -+0x00, 0x21, 0x12, 0xF0, 0x40, 0x02, 0xCD, 0xE9, 0x0A, 0x11, 0x40, 0xF0, 0xB5, 0x80, 0x84, 0xF8, 0x33, 0x20, 0x84, 0xF8, -+0x35, 0x20, 0x89, 0x4B, 0x02, 0x9A, 0x93, 0xE8, 0x03, 0x00, 0x08, 0x9B, 0x13, 0x44, 0x1E, 0x46, 0x0D, 0xF1, 0x30, 0x0C, -+0x07, 0x9B, 0x8C, 0xE8, 0x03, 0x00, 0x08, 0x22, 0x61, 0x46, 0x30, 0x46, 0x03, 0xF1, 0x5C, 0x08, 0x0C, 0xF0, 0xA8, 0xF9, -+0x7F, 0x4B, 0xD3, 0xE9, 0x02, 0x01, 0x08, 0x22, 0x0E, 0xAB, 0x83, 0xE8, 0x03, 0x00, 0xC8, 0x44, 0x19, 0x46, 0xB0, 0x18, -+0x0C, 0xF0, 0x9C, 0xF9, 0x06, 0x22, 0x41, 0x46, 0x06, 0xF1, 0x10, 0x00, 0x0C, 0xF0, 0x96, 0xF9, 0x4F, 0xF4, 0xA4, 0x60, -+0x00, 0xFB, 0x05, 0x95, 0x9D, 0xF9, 0x18, 0x20, 0xD5, 0xF8, 0xC4, 0x34, 0xB3, 0x75, 0xD5, 0xF8, 0xC4, 0x34, 0x1B, 0x0A, -+0xF3, 0x75, 0xB5, 0xF8, 0xC6, 0x34, 0x33, 0x76, 0x95, 0xF8, 0xC7, 0x34, 0x73, 0x76, 0x7B, 0x78, 0x58, 0x06, 0x67, 0xD4, -+0x00, 0x2A, 0xB8, 0xBF, 0x07, 0xF1, 0x2A, 0x01, 0x4F, 0xF0, 0x0A, 0x02, 0xA8, 0xBF, 0x07, 0xF1, 0x28, 0x01, 0x06, 0xF1, -+0x1A, 0x00, 0x0C, 0xF0, 0x73, 0xF9, 0xE2, 0x6C, 0x94, 0xF8, 0x35, 0x50, 0x53, 0x6A, 0x02, 0x99, 0xA4, 0x65, 0x24, 0x35, -+0x0D, 0x44, 0x01, 0x3B, 0x2B, 0x44, 0x00, 0x20, 0x29, 0x1D, 0x60, 0x65, 0xC2, 0xE9, 0x0A, 0x31, 0x03, 0x9B, 0x6B, 0xB1, -+0x04, 0x9B, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x03, 0xB3, 0x93, 0xF8, 0x23, 0x30, 0x02, 0xFB, 0x03, 0xBB, 0x9B, 0xF8, -+0xA5, 0x91, 0xB9, 0xF1, 0x21, 0x0F, 0x6A, 0xD1, 0x7B, 0x78, 0x59, 0x06, 0x2F, 0xD5, 0x9A, 0xF8, 0x60, 0x30, 0x01, 0x2B, -+0x00, 0xF0, 0x53, 0x81, 0x52, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x9B, 0x07, 0x09, 0xD5, 0x9A, 0xF8, 0x60, 0x30, 0x01, 0x2B, -+0x0A, 0xF1, 0x64, 0x09, 0x40, 0xF2, 0x36, 0x81, 0x03, 0x2B, 0x00, 0xF0, 0x34, 0x81, 0x20, 0x46, 0x05, 0x21, 0xE5, 0xF7, -+0x8F, 0xF8, 0x15, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x96, 0xF8, 0x23, 0x20, 0x08, 0xFB, 0x02, 0xB8, 0x6F, 0xF0, 0x77, 0x02, -+0xB8, 0xF8, 0x34, 0x11, 0x83, 0xF8, 0x68, 0x20, 0x4A, 0x1C, 0x01, 0x20, 0xC2, 0xF3, 0x0B, 0x02, 0x83, 0xF8, 0x69, 0x00, -+0x09, 0x91, 0x03, 0x90, 0xA8, 0xF8, 0x34, 0x21, 0x21, 0xE7, 0x3D, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x9A, 0x07, 0xDE, 0xD5, -+0xBA, 0xF1, 0x00, 0x0F, 0xDB, 0xD0, 0xD0, 0xE7, 0x00, 0x2A, 0xB8, 0xBF, 0x07, 0xF1, 0x32, 0x01, 0x4F, 0xF0, 0x0A, 0x02, -+0xA8, 0xBF, 0x07, 0xF1, 0x30, 0x01, 0x06, 0xF1, 0x1A, 0x00, 0x0C, 0xF0, 0x0B, 0xF9, 0x96, 0xE7, 0xE2, 0x6C, 0xB3, 0xF8, -+0x68, 0x10, 0x90, 0x6B, 0x41, 0xF4, 0x80, 0x41, 0xC2, 0x68, 0xA3, 0xF8, 0x68, 0x10, 0x22, 0xF4, 0x7F, 0x73, 0x9A, 0xF8, -+0x62, 0x20, 0x08, 0x99, 0x23, 0xF0, 0x03, 0x03, 0x13, 0x43, 0xC3, 0x60, 0x9A, 0xF8, 0x60, 0x30, 0x02, 0x98, 0x0E, 0x18, -+0x04, 0x2B, 0x00, 0xF2, 0xD3, 0x81, 0xDF, 0xE8, 0x03, 0xF0, 0x1E, 0x51, 0xBA, 0x1E, 0x85, 0x00, 0x18, 0x22, 0x02, 0x92, -+0x21, 0xE7, 0x4F, 0xEA, 0x09, 0x20, 0x40, 0xF0, 0x08, 0x00, 0xF7, 0xF7, 0xFD, 0xFF, 0x01, 0x28, 0x8C, 0xD1, 0x1E, 0x4B, -+0x09, 0x99, 0x09, 0xEB, 0x49, 0x09, 0x03, 0xEB, 0xC9, 0x09, 0x02, 0x22, 0xD9, 0xF8, 0x14, 0x00, 0x02, 0x90, 0x05, 0xF0, -+0x1D, 0xFB, 0x02, 0x98, 0x05, 0xF0, 0xF8, 0xFA, 0x7C, 0xE7, 0x04, 0x23, 0x84, 0xF8, 0x33, 0x30, 0x84, 0xF8, 0x35, 0x30, -+0xDA, 0xE9, 0x12, 0x32, 0x01, 0x33, 0x42, 0xF1, 0x00, 0x02, 0x18, 0x46, 0x11, 0x46, 0x53, 0x46, 0xE3, 0xE9, 0x12, 0x01, -+0x06, 0x22, 0x19, 0x46, 0x0A, 0xA8, 0x0C, 0xF0, 0xBD, 0xF8, 0x02, 0x99, 0x08, 0x9A, 0xBD, 0xF8, 0x28, 0x30, 0x53, 0x52, -+0xBD, 0xF8, 0x2A, 0x30, 0x9A, 0xF8, 0x61, 0x20, 0x43, 0xEA, 0x82, 0x33, 0x73, 0x80, 0x94, 0xF8, 0x33, 0x30, 0xCB, 0x18, -+0x02, 0x93, 0xF0, 0xE6, 0x88, 0x1A, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x8C, 0xBC, 0x15, 0x00, 0x34, 0x36, 0x17, 0x00, -+0xF4, 0xE4, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x08, 0x22, 0x0C, 0x23, 0x84, 0xF8, 0x33, 0x20, -+0x84, 0xF8, 0x35, 0x30, 0xDA, 0xE9, 0x12, 0x32, 0x01, 0x33, 0x42, 0xF1, 0x00, 0x02, 0x18, 0x46, 0x11, 0x46, 0x53, 0x46, -+0xE3, 0xE9, 0x12, 0x01, 0x06, 0x22, 0x19, 0x46, 0x0A, 0xA8, 0x0C, 0xF0, 0x89, 0xF8, 0xBD, 0xF8, 0x28, 0x20, 0x02, 0x99, -+0x42, 0xF4, 0x00, 0x53, 0x03, 0xF4, 0xFE, 0x43, 0x43, 0xEA, 0x12, 0x23, 0x08, 0x9A, 0x53, 0x52, 0x9D, 0xF8, 0x28, 0x30, -+0x9A, 0xF8, 0x61, 0x20, 0x43, 0xEA, 0x82, 0x33, 0x43, 0xF4, 0x00, 0x53, 0x73, 0x80, 0xBD, 0xF8, 0x2A, 0x30, 0xB3, 0x80, -+0xBD, 0xF8, 0x2C, 0x30, 0xF3, 0x80, 0x94, 0xF8, 0x33, 0x30, 0xCB, 0x18, 0x02, 0x93, 0xAE, 0xE6, 0x10, 0x23, 0x12, 0x21, -+0x84, 0xF8, 0x33, 0x10, 0x84, 0xF8, 0x35, 0x30, 0x0F, 0x2A, 0xDA, 0xF8, 0x48, 0x30, 0xDA, 0xF8, 0x4C, 0x20, 0x40, 0xF2, -+0x00, 0x81, 0x02, 0x33, 0x42, 0xF1, 0x00, 0x02, 0x18, 0x46, 0x11, 0x46, 0x53, 0x46, 0xE3, 0xE9, 0x12, 0x01, 0x08, 0x22, -+0x19, 0x46, 0x0A, 0xA8, 0x0C, 0xF0, 0x50, 0xF8, 0x9A, 0xF8, 0x61, 0x30, 0x33, 0x80, 0xBD, 0xF8, 0x28, 0x30, 0x73, 0x80, -+0xBD, 0xF8, 0x2A, 0x30, 0xB3, 0x80, 0xBD, 0xF8, 0x2C, 0x30, 0xF3, 0x80, 0xBD, 0xF8, 0x2E, 0x30, 0x33, 0x81, 0x45, 0xF6, -+0x36, 0x43, 0x73, 0x81, 0xB3, 0x81, 0xF3, 0x81, 0x33, 0x82, 0x02, 0x9A, 0x94, 0xF8, 0x33, 0x30, 0x1A, 0x44, 0x02, 0x92, -+0x79, 0xE6, 0x08, 0x23, 0x84, 0xF8, 0x33, 0x30, 0x84, 0xF8, 0x35, 0x30, 0xDA, 0xE9, 0x12, 0x32, 0x01, 0x33, 0x42, 0xF1, -+0x00, 0x02, 0x18, 0x46, 0x11, 0x46, 0x53, 0x46, 0xE3, 0xE9, 0x12, 0x01, 0x06, 0x22, 0x19, 0x46, 0x0A, 0xA8, 0x0C, 0xF0, -+0x21, 0xF8, 0x08, 0x9A, 0xBD, 0xF8, 0x28, 0x30, 0x10, 0x46, 0x02, 0x9A, 0x83, 0x52, 0x9A, 0xF8, 0x61, 0x30, 0x9B, 0x03, -+0x43, 0xF4, 0x00, 0x53, 0x73, 0x80, 0xBD, 0xF8, 0x2A, 0x30, 0xB3, 0x80, 0xBD, 0xF8, 0x2C, 0x30, 0xF3, 0x80, 0x94, 0xF8, -+0x33, 0x30, 0xD3, 0x18, 0x02, 0x93, 0x4E, 0xE6, 0x31, 0xD0, 0x03, 0x9B, 0x0D, 0xF1, 0x40, 0x0B, 0x00, 0x2B, 0x5D, 0xD1, -+0x94, 0xF8, 0x33, 0x70, 0x94, 0xF8, 0x35, 0x30, 0x1F, 0x44, 0xC7, 0xF5, 0x7F, 0x47, 0xEC, 0x37, 0x2F, 0x44, 0xBF, 0xB2, -+0x5C, 0xE0, 0x05, 0x99, 0x06, 0x22, 0x04, 0xF1, 0x0C, 0x00, 0x0B, 0xF0, 0xF3, 0xFF, 0x06, 0x22, 0x41, 0x46, 0x04, 0xF1, -+0x12, 0x00, 0x0B, 0xF0, 0xED, 0xFF, 0x03, 0x9B, 0x00, 0x22, 0xE2, 0x76, 0x00, 0x2B, 0x78, 0xD0, 0x94, 0xF8, 0x35, 0x10, -+0x94, 0xF8, 0x33, 0x30, 0x69, 0x48, 0x0B, 0x44, 0xEB, 0x1A, 0xD0, 0xF8, 0x7C, 0x73, 0x00, 0x92, 0x1A, 0x3B, 0x32, 0x46, -+0x0A, 0xF1, 0x50, 0x01, 0x20, 0x46, 0xB8, 0x47, 0x8A, 0xE6, 0x03, 0x9B, 0x94, 0xF8, 0x33, 0x70, 0x00, 0x2B, 0x00, 0xF0, -+0x82, 0x80, 0x94, 0xF8, 0x35, 0x30, 0x1F, 0x44, 0xC7, 0xF5, 0x7F, 0x47, 0xF2, 0x37, 0x2F, 0x44, 0xBF, 0xB2, 0x39, 0x1F, -+0x4F, 0xF0, 0xFF, 0x33, 0x03, 0x22, 0x30, 0x46, 0xDA, 0xF7, 0x7E, 0xFE, 0xDA, 0xF8, 0x48, 0xC0, 0xDA, 0xF8, 0x4C, 0x00, -+0x57, 0x49, 0x4F, 0xEA, 0x1C, 0x43, 0x43, 0xEA, 0x00, 0x43, 0x0D, 0xF1, 0x40, 0x0B, 0x0B, 0x60, 0x42, 0x46, 0x5B, 0x46, -+0x48, 0x46, 0xA1, 0xF8, 0x04, 0xC0, 0xF7, 0xF7, 0x45, 0xF8, 0x58, 0x46, 0x10, 0x21, 0xF7, 0xF7, 0x05, 0xFA, 0x9A, 0xF8, -+0x60, 0x30, 0x00, 0x2B, 0x40, 0xF0, 0x85, 0x80, 0x94, 0xF8, 0x33, 0x70, 0x94, 0xF8, 0x35, 0x30, 0x1F, 0x44, 0xC7, 0xF5, -+0x7F, 0x47, 0xEA, 0x37, 0x2F, 0x44, 0xBF, 0xB2, 0x4F, 0xF0, 0xFF, 0x33, 0x03, 0x22, 0x39, 0x1F, 0x30, 0x46, 0xDA, 0xF7, -+0x51, 0xFE, 0x9A, 0xF8, 0x60, 0x30, 0xBA, 0xF8, 0x48, 0x10, 0xBA, 0xF8, 0x4A, 0x20, 0xAD, 0xF8, 0x40, 0x10, 0x8D, 0xF8, -+0x42, 0x20, 0x49, 0x46, 0x7B, 0xBB, 0x05, 0x22, 0x0D, 0xF1, 0x43, 0x00, 0x0B, 0xF0, 0x84, 0xFF, 0x58, 0x46, 0x08, 0x21, -+0xF7, 0xF7, 0xDA, 0xF9, 0x03, 0x20, 0xDA, 0xF7, 0x71, 0xFE, 0x39, 0x46, 0x02, 0x46, 0x30, 0x46, 0xF7, 0xF7, 0x04, 0xF8, -+0x39, 0x46, 0x30, 0x46, 0xF7, 0xF7, 0xFA, 0xF9, 0x20, 0x46, 0x05, 0x21, 0xE4, 0xF7, 0xC6, 0xFE, 0x35, 0xE6, 0x94, 0xF8, -+0x35, 0x20, 0x94, 0xF8, 0x33, 0x30, 0x2D, 0x49, 0x13, 0x44, 0xD1, 0xF8, 0x7C, 0x73, 0x03, 0x99, 0x00, 0x91, 0xEB, 0x1A, -+0x18, 0x3B, 0x32, 0x46, 0x0A, 0xF1, 0x50, 0x01, 0x20, 0x46, 0xB8, 0x47, 0x10, 0xE6, 0x01, 0x33, 0x42, 0xF1, 0x00, 0x02, -+0xFE, 0xE6, 0x0D, 0x22, 0x0D, 0xF1, 0x43, 0x00, 0x0B, 0xF0, 0x54, 0xFF, 0x58, 0x46, 0x10, 0x21, 0xF7, 0xF7, 0xAA, 0xF9, -+0xCE, 0xE7, 0x94, 0xF8, 0x35, 0x30, 0x1F, 0x44, 0xC7, 0xF5, 0x7F, 0x47, 0xF4, 0x37, 0x2F, 0x44, 0xBF, 0xB2, 0x39, 0x1F, -+0x4F, 0xF0, 0xFF, 0x33, 0x03, 0x22, 0x30, 0x46, 0xDA, 0xF7, 0xFC, 0xFD, 0xDA, 0xF8, 0x48, 0xC0, 0xDA, 0xF8, 0x4C, 0x00, -+0x16, 0x49, 0x4F, 0xEA, 0x1C, 0x43, 0x43, 0xEA, 0x00, 0x43, 0x0D, 0xF1, 0x40, 0x0B, 0x0B, 0x60, 0x42, 0x46, 0x5B, 0x46, -+0x48, 0x46, 0xA1, 0xF8, 0x04, 0xC0, 0xF6, 0xF7, 0xC3, 0xFF, 0x58, 0x46, 0x10, 0x21, 0xF7, 0xF7, 0x83, 0xF9, 0x9A, 0xF8, -+0x60, 0x30, 0x00, 0x2B, 0x3F, 0xF4, 0x20, 0xAF, 0x03, 0x2B, 0xA1, 0xD1, 0x1C, 0xE7, 0x03, 0x2B, 0x9E, 0xD1, 0x77, 0xE7, -+0x08, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xBF, 0xF6, 0xDC, 0xAE, 0x06, 0x49, 0x06, 0x48, 0x40, 0xF2, -+0x2C, 0x62, 0xF9, 0xF7, 0x6B, 0xFC, 0xD4, 0xE6, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x34, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x08, 0xB5, 0x0C, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0x05, 0xDB, 0x0A, 0x4B, 0x00, 0x20, 0x5B, 0x68, 0x98, 0x47, 0x00, 0x20, 0x08, 0xBD, 0x07, 0x20, 0xF7, 0xF7, 0x10, 0xFE, -+0x02, 0x28, 0xF4, 0xD0, 0x05, 0x49, 0x06, 0x48, 0x40, 0xF2, 0x31, 0x12, 0xF9, 0xF7, 0x48, 0xFC, 0xED, 0xE7, 0x00, 0xBF, -+0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xC0, 0xBC, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x41, -+0x0C, 0x46, 0x36, 0x49, 0x60, 0x7C, 0x4F, 0xF4, 0xA4, 0x65, 0x05, 0xFB, 0x00, 0x10, 0x86, 0xB0, 0x90, 0xF8, 0x62, 0x10, -+0x00, 0x25, 0x02, 0x29, 0x98, 0x46, 0x8D, 0xF8, 0x0B, 0x50, 0x10, 0xD0, 0x04, 0x25, 0x41, 0x46, 0x02, 0x23, 0x41, 0xF6, -+0x05, 0x40, 0xF7, 0xF7, 0x43, 0xFB, 0x05, 0x70, 0x9D, 0xF8, 0x0B, 0x20, 0x42, 0x70, 0xF7, 0xF7, 0x6D, 0xFB, 0x00, 0x20, -+0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x90, 0xF8, 0x64, 0x10, 0x09, 0xB1, 0x08, 0x25, 0xEA, 0xE7, 0x07, 0x20, 0x01, 0x92, -+0xF7, 0xF7, 0xD2, 0xFD, 0x01, 0x9A, 0x00, 0x28, 0xF6, 0xD1, 0xA7, 0x78, 0x20, 0x7C, 0x21, 0x88, 0x1F, 0x4E, 0x8D, 0xF8, -+0x0C, 0x70, 0x8D, 0xF8, 0x0D, 0x00, 0xA7, 0x68, 0xE0, 0x68, 0xAD, 0xF8, 0x0E, 0x10, 0x21, 0x79, 0x75, 0x6C, 0xAD, 0xF8, -+0x12, 0x00, 0x8D, 0xF8, 0x14, 0x10, 0xAD, 0xF8, 0x10, 0x70, 0x0D, 0xF1, 0x0B, 0x01, 0x03, 0xA8, 0xA8, 0x47, 0x01, 0x9A, -+0x05, 0x46, 0x10, 0xBB, 0xF6, 0x6C, 0x60, 0x7C, 0x9D, 0xF8, 0x0B, 0x10, 0xB0, 0x47, 0xEF, 0xF3, 0x10, 0x81, 0x11, 0xF0, -+0x01, 0x0F, 0x01, 0x9A, 0x03, 0xD1, 0x72, 0xB6, 0x0E, 0x49, 0x01, 0x20, 0x08, 0x60, 0x0E, 0x48, 0x0E, 0x4F, 0x04, 0x68, -+0x79, 0x68, 0x66, 0x1C, 0x41, 0xF0, 0x10, 0x01, 0x06, 0x60, 0x79, 0x60, 0x00, 0x2E, 0xAE, 0xD0, 0x07, 0x49, 0x04, 0x60, -+0x09, 0x68, 0x00, 0x2C, 0xA9, 0xD1, 0x00, 0x29, 0xA7, 0xD0, 0x62, 0xB6, 0xA5, 0xE7, 0x01, 0x25, 0xA3, 0xE7, 0x00, 0xBF, -+0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x43, 0x0C, 0x46, 0x85, 0xB0, 0x90, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0x4A, 0x69, 0x4D, 0x49, 0x4E, 0x4F, -+0x99, 0x46, 0xF9, 0xF7, 0x8D, 0xF9, 0x94, 0xF8, 0x33, 0x60, 0x4F, 0xF4, 0xA4, 0x65, 0x05, 0xFB, 0x06, 0x75, 0x95, 0xF8, -+0x62, 0x10, 0x02, 0x29, 0x11, 0xD0, 0x04, 0x25, 0x42, 0x46, 0x49, 0x46, 0x04, 0x23, 0x41, 0xF6, 0x01, 0x40, 0xF7, 0xF7, -+0xC3, 0xFA, 0x05, 0x70, 0x94, 0xF8, 0x33, 0x20, 0x42, 0x70, 0xF7, 0xF7, 0xED, 0xFA, 0x00, 0x20, 0x05, 0xB0, 0xBD, 0xE8, -+0xF0, 0x83, 0x07, 0x20, 0xF7, 0xF7, 0x58, 0xFD, 0xC0, 0xB9, 0x95, 0xF8, 0x64, 0x30, 0xBB, 0xB9, 0x3B, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x13, 0xDB, 0x23, 0x7F, 0x39, 0x49, 0x00, 0x93, 0xD4, 0xE9, 0x05, 0x23, 0x0C, 0x60, -+0x0D, 0xF1, 0x0D, 0x00, 0x04, 0xF1, 0x0E, 0x01, 0xFD, 0xF7, 0xAC, 0xF9, 0x05, 0x46, 0x70, 0xB1, 0x01, 0x25, 0xD1, 0xE7, -+0x08, 0x25, 0xCF, 0xE7, 0x09, 0x25, 0xCD, 0xE7, 0x2B, 0x6C, 0x00, 0x2B, 0xE8, 0xD0, 0x2F, 0x49, 0x2F, 0x48, 0x56, 0x22, -+0xF9, 0xF7, 0x72, 0xFB, 0xE2, 0xE7, 0xE1, 0x89, 0x20, 0x7C, 0xDF, 0xF8, 0xB4, 0x80, 0xFB, 0xF7, 0x9B, 0xFF, 0x4F, 0xF4, -+0xA4, 0x62, 0x02, 0xFB, 0x06, 0xF2, 0x07, 0xEB, 0x02, 0x09, 0xC9, 0xF8, 0x90, 0x01, 0x94, 0xF9, 0x12, 0x30, 0x03, 0x71, -+0xD4, 0xE9, 0x05, 0x31, 0xA9, 0xF8, 0x96, 0x11, 0xA9, 0xF8, 0x94, 0x31, 0x23, 0x7F, 0x89, 0xF8, 0xC5, 0x31, 0x04, 0x2B, -+0x08, 0xBF, 0x03, 0x23, 0x89, 0xF8, 0xC4, 0x31, 0x89, 0xF8, 0xC6, 0x51, 0xD8, 0xF8, 0x4C, 0x30, 0x94, 0xF8, 0x33, 0x00, -+0x9D, 0xF8, 0x0D, 0x10, 0x15, 0x46, 0x98, 0x47, 0x23, 0x7C, 0xA3, 0xB1, 0x00, 0xF0, 0x8C, 0xFA, 0x4F, 0xF4, 0xA4, 0x63, -+0x03, 0xFB, 0x06, 0x73, 0x78, 0x19, 0xD3, 0xF8, 0x90, 0x31, 0xD8, 0xF8, 0x40, 0x43, 0x1B, 0x79, 0x8D, 0xF8, 0x0E, 0x30, -+0x0D, 0xF1, 0x0F, 0x02, 0x0D, 0xF1, 0x0E, 0x01, 0xA0, 0x47, 0x01, 0x20, 0x92, 0xE7, 0x05, 0xF5, 0xCE, 0x70, 0x38, 0x44, -+0x01, 0x21, 0xFC, 0xF7, 0x45, 0xF9, 0x10, 0xF0, 0x0F, 0x00, 0x1A, 0xBF, 0xB0, 0xFA, 0x80, 0xF0, 0xC0, 0xF1, 0x1F, 0x03, -+0x01, 0x23, 0x89, 0xF8, 0xC1, 0x31, 0xD9, 0xE7, 0xEC, 0xBC, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x94, 0xBA, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xA0, 0xA2, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xF8, 0xB5, 0x4F, 0x88, -+0x0D, 0x48, 0x0C, 0x46, 0x16, 0x46, 0x04, 0x31, 0x3A, 0x46, 0x1D, 0x46, 0x0B, 0xF0, 0xAE, 0xFD, 0xDF, 0xF8, 0x28, 0xC0, -+0x32, 0x46, 0x29, 0x46, 0x02, 0x23, 0x41, 0xF6, 0x09, 0x40, 0xAC, 0xF8, 0x00, 0x70, 0xF7, 0xF7, 0x1B, 0xFA, 0x01, 0x22, -+0x02, 0x70, 0x22, 0x78, 0x42, 0x70, 0xF7, 0xF7, 0x45, 0xFA, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0xBF, 0x14, 0x2A, 0x17, 0x00, -+0x14, 0x2C, 0x17, 0x00, 0x08, 0xB5, 0x15, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x0F, 0xDB, 0x07, 0x20, -+0xF7, 0xF7, 0xA6, 0xFC, 0x01, 0x28, 0x06, 0xD0, 0x07, 0x20, 0xF7, 0xF7, 0xA1, 0xFC, 0x03, 0x28, 0x01, 0xD0, 0x00, 0x20, -+0x08, 0xBD, 0x00, 0xF0, 0x01, 0xFA, 0x00, 0x20, 0x08, 0xBD, 0x07, 0x20, 0xF7, 0xF7, 0x96, 0xFC, 0x01, 0x28, 0xEA, 0xD0, -+0x07, 0x20, 0xF7, 0xF7, 0x91, 0xFC, 0x00, 0x28, 0xE5, 0xD0, 0x07, 0x20, 0xF7, 0xF7, 0x8C, 0xFC, 0x03, 0x28, 0xE0, 0xD0, -+0x03, 0x49, 0x04, 0x48, 0xC2, 0x22, 0xF9, 0xF7, 0xC5, 0xFA, 0xDA, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0xFC, 0xBC, 0x15, 0x00, 0x08, 0xB5, 0x0C, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x03, 0xDB, 0x00, 0xF0, -+0xDB, 0xF9, 0x00, 0x20, 0x08, 0xBD, 0x07, 0x20, 0xF7, 0xF7, 0x70, 0xFC, 0x01, 0x28, 0xF6, 0xD0, 0x05, 0x49, 0x06, 0x48, -+0xE6, 0x22, 0xF9, 0xF7, 0xA9, 0xFA, 0x00, 0xF0, 0xCD, 0xF9, 0x00, 0x20, 0x08, 0xBD, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x84, 0xBD, 0x15, 0x00, 0x08, 0xB5, 0x0C, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0x03, 0xDB, 0x00, 0xF0, 0xBB, 0xF9, 0x00, 0x20, 0x08, 0xBD, 0x07, 0x20, 0xF7, 0xF7, 0x50, 0xFC, 0x03, 0x28, 0xF6, 0xD0, -+0x05, 0x49, 0x06, 0x48, 0x40, 0xF2, 0x4B, 0x12, 0xF9, 0xF7, 0x88, 0xFA, 0x00, 0xF0, 0xAC, 0xF9, 0x00, 0x20, 0x08, 0xBD, -+0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xB4, 0xBD, 0x15, 0x00, 0x08, 0xB5, 0x11, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x06, 0xDB, 0x07, 0x20, 0xF7, 0xF7, 0x34, 0xFC, 0x03, 0x28, 0x12, 0xD0, 0x00, 0x20, 0x08, 0xBD, -+0x07, 0x20, 0xF7, 0xF7, 0x2D, 0xFC, 0x03, 0x28, 0xF3, 0xD0, 0x07, 0x20, 0xF7, 0xF7, 0x28, 0xFC, 0x00, 0x28, 0xEE, 0xD0, -+0x06, 0x49, 0x07, 0x48, 0x40, 0xF2, 0x65, 0x12, 0xF9, 0xF7, 0x60, 0xFA, 0xE7, 0xE7, 0x00, 0xF0, 0x83, 0xF9, 0x00, 0x20, -+0x08, 0xBD, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xDC, 0xBD, 0x15, 0x00, 0xF8, 0xB5, 0x0C, 0x46, -+0x4F, 0xF4, 0x80, 0x70, 0x13, 0x49, 0x16, 0x46, 0x1D, 0x46, 0xF9, 0xF7, 0x21, 0xF8, 0x24, 0x78, 0x11, 0x4B, 0x4F, 0xF4, -+0xA4, 0x62, 0x02, 0xFB, 0x04, 0x34, 0x94, 0xF8, 0x62, 0x70, 0x02, 0x2F, 0x02, 0xD1, 0x94, 0xF8, 0x64, 0x30, 0x3B, 0xB9, -+0x32, 0x46, 0x29, 0x46, 0x41, 0xF6, 0x03, 0x40, 0xF7, 0xF7, 0xBE, 0xF9, 0x00, 0x20, 0xF8, 0xBD, 0x07, 0x20, 0xF7, 0xF7, -+0xF3, 0xFB, 0x05, 0x46, 0x28, 0xB9, 0x06, 0x4B, 0x20, 0x46, 0x9B, 0x68, 0x98, 0x47, 0x28, 0x46, 0xF8, 0xBD, 0x38, 0x46, -+0xF8, 0xBD, 0x00, 0xBF, 0x30, 0xBE, 0x15, 0x00, 0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0xB5, 0x0C, 0x46, -+0x21, 0x49, 0x20, 0x78, 0x4F, 0xF4, 0xA4, 0x65, 0x05, 0xFB, 0x00, 0x10, 0x82, 0xB0, 0x90, 0xF8, 0x62, 0x50, 0x02, 0x2D, -+0x19, 0x46, 0x06, 0xD0, 0x41, 0xF6, 0x07, 0x40, 0xF7, 0xF7, 0x96, 0xF9, 0x00, 0x20, 0x02, 0xB0, 0x70, 0xBD, 0x90, 0xF8, -+0x64, 0x30, 0x00, 0x2B, 0xF4, 0xD1, 0x07, 0x20, 0xCD, 0xE9, 0x00, 0x21, 0xF7, 0xF7, 0xC4, 0xFB, 0xDD, 0xE9, 0x00, 0x21, -+0x00, 0x28, 0xEB, 0xD1, 0x12, 0x4B, 0x20, 0x78, 0x5B, 0x6D, 0x98, 0x47, 0xEF, 0xF3, 0x10, 0x83, 0x13, 0xF0, 0x01, 0x0F, -+0xDD, 0xE9, 0x00, 0x21, 0x03, 0xD1, 0x72, 0xB6, 0x0D, 0x4B, 0x01, 0x20, 0x18, 0x60, 0x0D, 0x48, 0x0D, 0x4E, 0x04, 0x68, -+0x73, 0x68, 0x65, 0x1C, 0x23, 0xF0, 0x10, 0x03, 0x05, 0x60, 0x73, 0x60, 0x00, 0x2D, 0xD1, 0xD0, 0x06, 0x4B, 0x04, 0x60, -+0x1B, 0x68, 0x00, 0x2C, 0xCC, 0xD1, 0x00, 0x2B, 0xCA, 0xD0, 0x62, 0xB6, 0xC8, 0xE7, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, 0x10, 0xB5, 0x22, 0x4C, -+0x23, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x28, 0xDB, 0x07, 0x20, 0xF7, 0xF7, 0x88, 0xFB, 0x01, 0x28, 0x13, 0xD1, -+0x23, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x03, 0xDB, 0x00, 0xF0, 0x9B, 0xF9, 0x00, 0x20, 0x10, 0xBD, 0x19, 0x4B, -+0x5B, 0x68, 0x00, 0x2B, 0xF7, 0xD0, 0x18, 0x49, 0x18, 0x48, 0x40, 0xF2, 0x0B, 0x12, 0xF9, 0xF7, 0xB3, 0xF9, 0xF0, 0xE7, -+0x07, 0x20, 0xF7, 0xF7, 0x6F, 0xFB, 0x03, 0x28, 0xED, 0xD1, 0x07, 0x22, 0x0C, 0x21, 0x41, 0xF6, 0x03, 0x40, 0xF7, 0xF7, -+0x2D, 0xF9, 0x00, 0x21, 0x07, 0x20, 0xF7, 0xF7, 0xBB, 0xFA, 0xE2, 0xE7, 0x07, 0x20, 0xF7, 0xF7, 0x5F, 0xFB, 0x01, 0x28, -+0xD1, 0xD0, 0x07, 0x20, 0xF7, 0xF7, 0x5A, 0xFB, 0x00, 0x28, 0xCC, 0xD0, 0x07, 0x20, 0xF7, 0xF7, 0x55, 0xFB, 0x03, 0x28, -+0xC7, 0xD0, 0x05, 0x49, 0x06, 0x48, 0x40, 0xF2, 0x03, 0x12, 0xF9, 0xF7, 0x8D, 0xF9, 0xC0, 0xE7, 0x38, 0x36, 0x17, 0x00, -+0x94, 0xBA, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x3C, 0xBE, 0x15, 0x00, 0xFC, 0xBC, 0x15, 0x00, 0x08, 0xB5, 0x0C, 0x4B, -+0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0xDB, 0xBD, 0xE8, 0x08, 0x40, 0x09, 0x48, 0xF7, 0xF7, 0x1E, 0xBD, -+0x08, 0x4B, 0x5B, 0x68, 0x00, 0x2B, 0xF6, 0xD0, 0x07, 0x48, 0x08, 0x49, 0x2D, 0x22, 0xF9, 0xF7, 0x6D, 0xF9, 0xBD, 0xE8, -+0x08, 0x40, 0x02, 0x48, 0xF7, 0xF7, 0x10, 0xBD, 0x38, 0x36, 0x17, 0x00, 0x98, 0xBA, 0x17, 0x00, 0x94, 0xBA, 0x17, 0x00, -+0x3C, 0xBE, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, 0x10, 0xB5, 0x06, 0x4C, 0x00, 0x21, 0x20, 0x46, 0x10, 0x22, 0xD4, 0xF7, -+0x6F, 0xFC, 0x00, 0x21, 0x21, 0x73, 0x07, 0x20, 0xBD, 0xE8, 0x10, 0x40, 0xF7, 0xF7, 0x68, 0xBA, 0x94, 0xBA, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0xD8, 0x80, 0x05, 0x46, 0x04, 0x23, 0x07, 0x22, 0x0C, 0x21, 0x41, 0xF6, 0x01, 0x40, -+0xD8, 0xF8, 0x00, 0x60, 0xF7, 0xF7, 0x5E, 0xF8, 0x04, 0x46, 0x95, 0xB1, 0x96, 0xF8, 0x33, 0x30, 0x63, 0x70, 0x20, 0x46, -+0x25, 0x70, 0xF7, 0xF7, 0x85, 0xF8, 0xA6, 0xF1, 0x0C, 0x00, 0xF7, 0xF7, 0xCD, 0xF8, 0x00, 0x21, 0xC8, 0xF8, 0x00, 0x10, -+0x07, 0x20, 0xBD, 0xE8, 0xF0, 0x47, 0xF7, 0xF7, 0x43, 0xBA, 0x04, 0x23, 0x29, 0x46, 0x07, 0x22, 0x1E, 0x20, 0x96, 0xF8, -+0x33, 0x70, 0xF7, 0xF7, 0x41, 0xF8, 0x21, 0x4A, 0x4F, 0xF4, 0xA4, 0x69, 0x09, 0xFB, 0x07, 0x29, 0x4F, 0xF0, 0x01, 0x0A, -+0x80, 0xF8, 0x02, 0xA0, 0x99, 0xF8, 0x63, 0x20, 0xC2, 0x70, 0xF7, 0xF7, 0x63, 0xF8, 0xF1, 0x6A, 0x32, 0x8E, 0xD9, 0xF8, -+0x40, 0x30, 0xC9, 0xF8, 0xB0, 0x14, 0xA9, 0xF8, 0xE0, 0x20, 0x89, 0xF8, 0xDE, 0x50, 0x1B, 0x7E, 0xA3, 0x70, 0x96, 0xF8, -+0x33, 0x30, 0xDF, 0xF8, 0x54, 0xC0, 0x0A, 0x33, 0xE3, 0x70, 0x96, 0xE8, 0x0F, 0x00, 0x4F, 0xF4, 0x1E, 0x7E, 0x0A, 0x37, -+0x0E, 0xFB, 0x07, 0xC7, 0x07, 0xF1, 0xB8, 0x0C, 0xAC, 0xE8, 0x07, 0x00, 0x02, 0x22, 0x87, 0xF8, 0x30, 0x20, 0x8C, 0xF8, -+0x00, 0x30, 0x38, 0x46, 0xFB, 0xF7, 0xA0, 0xFF, 0x97, 0xF8, 0x56, 0x31, 0xA7, 0xF8, 0x26, 0xA0, 0x43, 0xF0, 0x10, 0x03, -+0x87, 0xF8, 0x56, 0x31, 0x96, 0xF8, 0x33, 0x30, 0x03, 0xF1, 0x0A, 0x02, 0x87, 0xF8, 0x23, 0x20, 0xA4, 0xE7, 0x00, 0xBF, -+0x18, 0x88, 0x17, 0x00, 0x94, 0xBA, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x10, 0xB5, 0x0C, 0x48, 0xF7, 0xF7, 0xC6, 0xFC, -+0x0B, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0x46, 0x05, 0xDB, 0x04, 0xF1, 0x0C, 0x00, 0xBD, 0xE8, -+0x10, 0x40, 0xF7, 0xF7, 0x17, 0xB8, 0x00, 0x28, 0xF7, 0xD1, 0x05, 0x49, 0x05, 0x48, 0xCB, 0x22, 0xF9, 0xF7, 0xC2, 0xF8, -+0xF1, 0xE7, 0x00, 0xBF, 0x98, 0xBA, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xA8, 0xAB, 0x15, 0x00, -+0x2D, 0xE9, 0xF8, 0x4F, 0x44, 0x4B, 0xDF, 0xF8, 0x1C, 0xB1, 0x1C, 0x68, 0x07, 0x22, 0x08, 0x23, 0x00, 0x21, 0x18, 0x20, -+0x94, 0xF8, 0x33, 0x90, 0xF6, 0xF7, 0xC8, 0xFF, 0x08, 0x23, 0x07, 0x22, 0x00, 0x21, 0x06, 0x46, 0x16, 0x20, 0xF6, 0xF7, -+0xC1, 0xFF, 0x04, 0x23, 0x07, 0x22, 0x00, 0x21, 0x05, 0x46, 0x14, 0x20, 0xF6, 0xF7, 0xBA, 0xFF, 0x02, 0x23, 0x07, 0x22, -+0x05, 0x21, 0x80, 0x46, 0x41, 0xF2, 0x17, 0x40, 0xF6, 0xF7, 0xB2, 0xFF, 0x4F, 0xF4, 0xA4, 0x6A, 0x0A, 0xFB, 0x09, 0xBA, -+0x07, 0x46, 0xFF, 0xF7, 0x0B, 0xFF, 0x9A, 0xF8, 0xC0, 0x34, 0x00, 0x2B, 0x49, 0xD0, 0x2F, 0x4A, 0x13, 0x68, 0x23, 0xF0, -+0x04, 0x03, 0x13, 0x60, 0xDA, 0xF8, 0x04, 0x30, 0x43, 0xF0, 0x20, 0x03, 0xCA, 0xF8, 0x04, 0x30, 0x4F, 0xF4, 0xA4, 0x63, -+0x03, 0xFB, 0x09, 0xB9, 0xA6, 0xF1, 0x0C, 0x01, 0xD9, 0xF8, 0x5C, 0x00, 0xB9, 0xF8, 0x60, 0x30, 0xB3, 0x80, 0x30, 0x60, -+0x94, 0xF8, 0x33, 0x30, 0xB3, 0x71, 0x23, 0x48, 0xF7, 0xF7, 0x18, 0xFC, 0x23, 0x7C, 0x6B, 0x71, 0x01, 0x21, 0x20, 0x46, -+0xFB, 0xF7, 0x80, 0xFE, 0x28, 0x60, 0x94, 0xF8, 0x33, 0x30, 0x2B, 0x71, 0xA5, 0xF1, 0x0C, 0x01, 0x1B, 0x48, 0xF7, 0xF7, -+0x09, 0xFC, 0x23, 0x8D, 0xA8, 0xF8, 0x00, 0x30, 0x94, 0xF8, 0x33, 0x30, 0x88, 0xF8, 0x02, 0x30, 0xA8, 0xF1, 0x0C, 0x01, -+0x01, 0x25, 0x15, 0x48, 0xF7, 0xF7, 0xFC, 0xFB, 0x3D, 0x70, 0x94, 0xF8, 0x33, 0x30, 0x12, 0x48, 0x7B, 0x70, 0xA7, 0xF1, -+0x0C, 0x01, 0xF7, 0xF7, 0xF3, 0xFB, 0xFF, 0xF7, 0x6B, 0xFF, 0x29, 0x46, 0x07, 0x20, 0xBD, 0xE8, 0xF8, 0x4F, 0xF7, 0xF7, -+0x57, 0xB9, 0x02, 0x23, 0x07, 0x22, 0x05, 0x21, 0x41, 0xF2, 0x19, 0x40, 0xF6, 0xF7, 0x56, 0xFF, 0x01, 0x23, 0x03, 0x70, -+0x9A, 0xF8, 0x63, 0x30, 0x43, 0x70, 0x03, 0x4B, 0x01, 0x46, 0x0C, 0x39, 0x18, 0x1D, 0xF7, 0xF7, 0xD9, 0xFB, 0xAD, 0xE7, -+0x94, 0xBA, 0x17, 0x00, 0x4C, 0x00, 0x32, 0x40, 0x98, 0xBA, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x38, 0xB5, 0x0E, 0x4C, -+0x0C, 0x23, 0x07, 0x22, 0x00, 0x21, 0x3F, 0x20, 0x24, 0x68, 0xF6, 0xF7, 0x39, 0xFF, 0xA1, 0x8C, 0xE2, 0x8C, 0x25, 0x6A, -+0x05, 0x60, 0x81, 0x80, 0xC2, 0x80, 0x94, 0xF8, 0x32, 0x20, 0x02, 0x72, 0x94, 0xF8, 0x33, 0x20, 0x42, 0x72, 0xF6, 0xF7, -+0x5B, 0xFF, 0xBD, 0xE8, 0x38, 0x40, 0x02, 0x21, 0x07, 0x20, 0xF7, 0xF7, 0x1F, 0xB9, 0x00, 0xBF, 0x94, 0xBA, 0x17, 0x00, -+0xF8, 0xB5, 0x07, 0x22, 0x04, 0x46, 0x02, 0x23, 0x05, 0x21, 0x41, 0xF2, 0x19, 0x40, 0xF6, 0xF7, 0x19, 0xFF, 0x02, 0x23, -+0x06, 0x46, 0x07, 0x22, 0x05, 0x21, 0x41, 0xF2, 0x17, 0x40, 0xF6, 0xF7, 0x11, 0xFF, 0x00, 0x27, 0x05, 0x46, 0xFF, 0xF7, -+0x6D, 0xFE, 0x37, 0x70, 0x94, 0xF8, 0x63, 0x30, 0x73, 0x70, 0x1D, 0x48, 0xA6, 0xF1, 0x0C, 0x01, 0xF7, 0xF7, 0x92, 0xFB, -+0x94, 0xF8, 0x64, 0x30, 0x0B, 0xBB, 0x23, 0x6C, 0x6B, 0xB1, 0x01, 0x23, 0x00, 0x21, 0x07, 0x22, 0x39, 0x20, 0xF6, 0xF7, -+0xF9, 0xFE, 0x01, 0x46, 0x94, 0xF8, 0x63, 0x30, 0x01, 0xF8, 0x0C, 0x39, 0x12, 0x48, 0xF7, 0xF7, 0x7F, 0xFB, 0x00, 0x23, -+0x2B, 0x70, 0x94, 0xF8, 0x63, 0x30, 0x0F, 0x48, 0x6B, 0x70, 0xA5, 0xF1, 0x0C, 0x01, 0xF7, 0xF7, 0x75, 0xFB, 0xFF, 0xF7, -+0xED, 0xFE, 0xBD, 0xE8, 0xF8, 0x40, 0x03, 0x21, 0x07, 0x20, 0xF7, 0xF7, 0xD9, 0xB8, 0x39, 0x46, 0x04, 0x23, 0x07, 0x22, -+0x1E, 0x20, 0xF6, 0xF7, 0xD9, 0xFE, 0x87, 0x70, 0x94, 0xF8, 0x63, 0x30, 0xC3, 0x70, 0xA0, 0xF1, 0x0C, 0x01, 0x02, 0x48, -+0xF7, 0xF7, 0x5E, 0xFB, 0xCD, 0xE7, 0x00, 0xBF, 0x98, 0xBA, 0x17, 0x00, 0x15, 0x4A, 0x03, 0x7F, 0x4F, 0xF4, 0xA4, 0x61, -+0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0x13, 0xD1, 0x43, 0x7F, 0x0D, 0x2B, 0x10, 0xD8, 0x82, 0x88, -+0x2A, 0xB9, 0x82, 0x6C, 0xB2, 0xF8, 0x68, 0x20, 0xB2, 0xF5, 0x12, 0x7F, 0x08, 0xD0, 0x0C, 0x4A, 0x4F, 0xF4, 0x1E, 0x71, -+0x01, 0xFB, 0x03, 0x22, 0x92, 0xF8, 0x24, 0x30, 0x01, 0x2B, 0x02, 0xD0, 0x01, 0x23, 0x18, 0x46, 0x70, 0x47, 0x92, 0xF8, -+0x32, 0x20, 0x12, 0xF0, 0x03, 0x02, 0xF8, 0xD1, 0xC1, 0x8B, 0x41, 0xF4, 0x80, 0x51, 0x13, 0x46, 0xC1, 0x83, 0xF2, 0xE7, -+0x18, 0x88, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0xC3, 0x8B, 0xDB, 0x04, 0x00, 0xD4, 0x70, 0x47, 0x10, 0xB5, 0x0C, 0x46, -+0xC2, 0x7E, 0x15, 0x49, 0x94, 0xF8, 0x2E, 0x31, 0x8A, 0x5C, 0x13, 0x42, 0x1A, 0xD0, 0x94, 0xF8, 0x31, 0x20, 0x11, 0x07, -+0x1A, 0xD4, 0x42, 0xF0, 0x08, 0x02, 0x0F, 0x2B, 0x84, 0xF8, 0x31, 0x20, 0x14, 0xD1, 0x05, 0x22, 0x04, 0x23, 0x00, 0x21, -+0x41, 0x20, 0xF6, 0xF7, 0x7F, 0xFE, 0x22, 0x8C, 0x02, 0x80, 0x94, 0xF8, 0x22, 0x20, 0xC2, 0x70, 0x01, 0x22, 0x82, 0x70, -+0xBD, 0xE8, 0x10, 0x40, 0xF6, 0xF7, 0xA4, 0xBE, 0x94, 0xF8, 0x31, 0x30, 0x9A, 0x07, 0x00, 0xD5, 0x10, 0xBD, 0x43, 0xF0, -+0x02, 0x03, 0x84, 0xF8, 0x31, 0x30, 0xE4, 0xE7, 0xA4, 0xB2, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x90, 0xF8, 0x62, 0x70, -+0x02, 0x2F, 0x91, 0x46, 0x5A, 0xD1, 0x91, 0xF8, 0x32, 0x20, 0x0E, 0x46, 0x00, 0x2A, 0x55, 0xD0, 0x12, 0xF0, 0x01, 0x08, -+0x91, 0xF8, 0x31, 0x30, 0x04, 0xBF, 0x08, 0x27, 0x4F, 0xF0, 0x04, 0x08, 0x1F, 0x42, 0x78, 0xD0, 0xD1, 0xF8, 0xFC, 0x41, -+0x00, 0x2C, 0x68, 0xD0, 0xA2, 0xF1, 0x02, 0x02, 0xB2, 0xFA, 0x82, 0xF2, 0x91, 0xF8, 0x2E, 0x11, 0x3C, 0x4D, 0x52, 0x09, -+0x4F, 0xF0, 0x00, 0x0A, 0x04, 0xE0, 0x23, 0x68, 0xA2, 0x46, 0x00, 0x2B, 0x59, 0xD0, 0x1C, 0x46, 0xE3, 0x7E, 0xEB, 0x5C, -+0x19, 0x42, 0x0C, 0xBF, 0x01, 0x23, 0x00, 0x23, 0x93, 0x42, 0xF2, 0xD0, 0x51, 0x46, 0x22, 0x46, 0x06, 0xF5, 0xFE, 0x70, -+0xF7, 0xF7, 0xC8, 0xFB, 0x96, 0xF8, 0x32, 0x10, 0x11, 0xF0, 0x08, 0x0F, 0x0C, 0xBF, 0x03, 0x23, 0x04, 0x23, 0xE3, 0x76, -+0xBA, 0xF1, 0x00, 0x0F, 0x52, 0xD0, 0xDA, 0xF8, 0x00, 0x30, 0x0B, 0xB3, 0xA1, 0xF1, 0x02, 0x01, 0xB1, 0xFA, 0x81, 0xF1, -+0x96, 0xF8, 0x2E, 0x01, 0x49, 0x09, 0x01, 0xE0, 0x1B, 0x68, 0xBB, 0xB1, 0xDA, 0x7E, 0xAA, 0x5C, 0x10, 0x42, 0x0C, 0xBF, -+0x01, 0x22, 0x00, 0x22, 0x8A, 0x42, 0xF5, 0xD0, 0xA2, 0x6C, 0xB2, 0xF8, 0x68, 0x30, 0x43, 0xF4, 0x00, 0x53, 0xA2, 0xF8, -+0x68, 0x30, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0x24, 0xC9, 0xF8, 0x00, 0x40, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x87, -+0x96, 0xF8, 0x31, 0x10, 0x21, 0xEA, 0x07, 0x07, 0x17, 0xEA, 0x08, 0x01, 0x86, 0xF8, 0x31, 0x70, 0x07, 0xEA, 0x08, 0x05, -+0xE4, 0xD1, 0x04, 0x23, 0x05, 0x22, 0x41, 0x20, 0xF6, 0xF7, 0xF0, 0xFD, 0x32, 0x8C, 0x02, 0x80, 0x96, 0xF8, 0x22, 0x20, -+0xC2, 0x70, 0x85, 0x70, 0xF6, 0xF7, 0x18, 0xFE, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x87, 0x0C, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x05, 0xDA, 0x0A, 0x49, 0x0A, 0x48, 0x40, 0xF2, 0x91, 0x12, 0xF8, 0xF7, 0xD3, 0xFE, 0x01, 0x23, -+0x00, 0x24, 0xC9, 0xF8, 0x00, 0x30, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x87, 0xD6, 0xF8, 0xFC, 0x31, 0xAB, 0xE7, 0x00, 0xBF, -+0xA4, 0xB2, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x38, 0xB5, 0x90, 0xF8, -+0x62, 0x30, 0x02, 0x2B, 0x14, 0xD1, 0x13, 0x4C, 0x13, 0x4B, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x01, 0x44, 0x21, 0x46, -+0xD3, 0xF8, 0x20, 0x33, 0x00, 0x22, 0x98, 0x47, 0x94, 0xF8, 0x31, 0x10, 0x11, 0xF0, 0x0A, 0x0F, 0x04, 0xD0, 0x01, 0xF0, -+0xF5, 0x05, 0x84, 0xF8, 0x31, 0x50, 0x05, 0xB1, 0x38, 0xBD, 0x29, 0x46, 0x04, 0x23, 0x05, 0x22, 0x41, 0x20, 0xF6, 0xF7, -+0xA5, 0xFD, 0x94, 0xF8, 0x22, 0x20, 0x21, 0x8C, 0xC2, 0x70, 0x85, 0x70, 0xBD, 0xE8, 0x38, 0x40, 0x01, 0x80, 0xF6, 0xF7, -+0xCB, 0xBD, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x03, 0x6C, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, -+0x88, 0x46, 0x00, 0x2B, 0x6C, 0xD0, 0x3A, 0x4A, 0x1B, 0x79, 0x12, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x53, 0xDB, -+0x94, 0xF8, 0xC0, 0x24, 0x13, 0x43, 0x14, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x4F, 0xF4, 0xC0, 0x71, 0xE4, 0xF7, 0x4C, 0xF8, -+0x05, 0x46, 0x00, 0x28, 0x56, 0xD0, 0x01, 0x46, 0x20, 0x46, 0xF6, 0xF7, 0x43, 0xF9, 0xAE, 0x6C, 0x00, 0x27, 0x6F, 0xF0, -+0x3F, 0x03, 0x41, 0x46, 0x86, 0xF8, 0x68, 0x30, 0x86, 0xF8, 0x69, 0x70, 0x86, 0xF8, 0x6A, 0x70, 0x86, 0xF8, 0x6B, 0x70, -+0x06, 0xF1, 0x6C, 0x00, 0x06, 0x22, 0x0B, 0xF0, 0xED, 0xF8, 0x26, 0x4A, 0xE0, 0x6D, 0xB2, 0xF8, 0xFC, 0x31, 0xB4, 0xF8, -+0x60, 0x10, 0xB4, 0xF8, 0x60, 0xC0, 0xC6, 0xF8, 0x72, 0x00, 0x01, 0x33, 0x9B, 0xB2, 0xE0, 0x6D, 0xA6, 0xF8, 0x76, 0x10, -+0x19, 0x01, 0xB0, 0x67, 0xA6, 0xF8, 0x7C, 0xC0, 0xA2, 0xF8, 0xFC, 0x31, 0xA6, 0xF8, 0x7E, 0x10, 0xC5, 0xE9, 0x15, 0x74, -+0x94, 0xF8, 0x63, 0x30, 0x2B, 0x77, 0xFF, 0x23, 0x6B, 0x77, 0x06, 0xF1, 0x80, 0x00, 0x07, 0x21, 0xF9, 0xF7, 0xCE, 0xFD, -+0xE9, 0x6C, 0x4B, 0x6A, 0x17, 0x33, 0x1A, 0x18, 0x00, 0xF1, 0x1C, 0x03, 0xC1, 0xE9, 0x0A, 0x23, 0x28, 0x46, 0x05, 0x21, -+0xBD, 0xE8, 0xF0, 0x41, 0xE4, 0xF7, 0x12, 0xB8, 0x02, 0x2B, 0xA9, 0xD1, 0x0D, 0x49, 0x0E, 0x48, 0x4F, 0xF4, 0x09, 0x72, -+0xF8, 0xF7, 0x0E, 0xFE, 0x01, 0x20, 0x4F, 0xF4, 0xC0, 0x71, 0xE3, 0xF7, 0xF5, 0xFF, 0x05, 0x46, 0x00, 0x28, 0xA8, 0xD1, -+0xBD, 0xE8, 0xF0, 0x81, 0x03, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xEF, 0xDA, 0xE8, 0xE7, 0x00, 0xBF, -+0x38, 0x36, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xFC, 0x90, 0x15, 0x00, 0xF8, 0xB5, 0x14, 0x4A, -+0x14, 0x4D, 0x41, 0xF2, 0x0A, 0x00, 0x41, 0xF2, 0x08, 0x07, 0x00, 0x26, 0x16, 0x52, 0x0C, 0x46, 0xD3, 0x53, 0x41, 0xF2, -+0x0C, 0x06, 0xD1, 0xF8, 0x64, 0x11, 0xD4, 0xF8, 0x60, 0x01, 0x90, 0x51, 0x0B, 0x2B, 0x14, 0x60, 0xA9, 0x80, 0x0D, 0xD0, -+0x19, 0x46, 0x04, 0x22, 0x02, 0x23, 0x41, 0xF2, 0x09, 0x00, 0xF6, 0xF7, 0xF5, 0xFC, 0x01, 0x22, 0x42, 0x70, 0x94, 0xF8, -+0x6E, 0x21, 0x02, 0x70, 0xF6, 0xF7, 0x1E, 0xFD, 0x04, 0x4B, 0xD3, 0xF8, 0xF4, 0x32, 0x98, 0x47, 0x01, 0x20, 0xF8, 0xBD, -+0xA8, 0xBA, 0x17, 0x00, 0xB4, 0xCA, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x1A, 0x46, 0x70, 0xB5, 0x40, 0x23, 0x14, 0x4C, -+0x0D, 0x46, 0x41, 0xF2, 0x06, 0x00, 0x11, 0x46, 0x04, 0x22, 0xF6, 0xF7, 0xD7, 0xFC, 0xA3, 0x88, 0x06, 0x46, 0x13, 0xB1, -+0x2A, 0x78, 0x93, 0x42, 0x06, 0xD8, 0x00, 0x23, 0x30, 0x46, 0x33, 0x70, 0xF6, 0xF7, 0xFC, 0xFC, 0x00, 0x20, 0x70, 0xBD, -+0x04, 0xEB, 0x82, 0x14, 0x08, 0x34, 0x0F, 0xCC, 0x35, 0x46, 0x0F, 0xC5, 0x0F, 0xCC, 0x0F, 0xC5, 0x0F, 0xCC, 0x0F, 0xC5, -+0x94, 0xE8, 0x0F, 0x00, 0x85, 0xE8, 0x0F, 0x00, 0x30, 0x46, 0xF6, 0xF7, 0xE9, 0xFC, 0x00, 0x20, 0x70, 0xBD, 0x00, 0xBF, -+0xA8, 0xBA, 0x17, 0x00, 0x08, 0xB5, 0x04, 0x22, 0x01, 0x23, 0x02, 0x21, 0x40, 0xF6, 0x03, 0x00, 0xF6, 0xF7, 0xAC, 0xFC, -+0xF6, 0xF7, 0xDA, 0xFC, 0x04, 0x20, 0xF6, 0xF7, 0x49, 0xFF, 0x03, 0x49, 0x02, 0x46, 0x08, 0x20, 0xF8, 0xF7, 0x5A, 0xFB, -+0x00, 0x20, 0x08, 0xBD, 0x6C, 0xBE, 0x15, 0x00, 0x08, 0xB5, 0x19, 0x46, 0x04, 0x22, 0x01, 0x23, 0x41, 0xF2, 0x0B, 0x00, -+0xF6, 0xF7, 0x96, 0xFC, 0xF6, 0xF7, 0xC4, 0xFC, 0x02, 0x49, 0x08, 0x20, 0xF8, 0xF7, 0x48, 0xFB, 0x00, 0x20, 0x08, 0xBD, -+0x80, 0xBE, 0x15, 0x00, 0x1A, 0x46, 0x38, 0xB5, 0x41, 0xF2, 0x08, 0x00, 0x0D, 0x46, 0x02, 0x23, 0x11, 0x46, 0x04, 0x22, -+0xF6, 0xF7, 0x82, 0xFC, 0x06, 0x49, 0x04, 0x46, 0x08, 0x20, 0xF8, 0xF7, 0x35, 0xFB, 0x01, 0x23, 0x23, 0x70, 0xAB, 0x78, -+0x63, 0x70, 0x20, 0x46, 0xF6, 0xF7, 0xA6, 0xFC, 0x00, 0x20, 0x38, 0xBD, 0x98, 0xBE, 0x15, 0x00, 0x10, 0xB5, 0x41, 0xF2, -+0x08, 0x00, 0x04, 0x4C, 0x04, 0x49, 0x1A, 0x46, 0x23, 0x5A, 0x08, 0x20, 0xF8, 0xF7, 0x20, 0xFB, 0x02, 0x20, 0x10, 0xBD, -+0xA8, 0xBA, 0x17, 0x00, 0xB4, 0xBE, 0x15, 0x00, 0xF8, 0xB5, 0x36, 0x4C, 0x91, 0xF8, 0x6E, 0x21, 0x35, 0x4E, 0x21, 0x60, -+0x0D, 0x46, 0x41, 0xF2, 0x08, 0x00, 0x4F, 0xF4, 0xA4, 0x67, 0x41, 0xF2, 0x0A, 0x01, 0x07, 0xFB, 0x02, 0x62, 0x01, 0x26, -+0x23, 0x52, 0x66, 0x52, 0x00, 0x23, 0xC2, 0xF8, 0xCC, 0x31, 0x05, 0xF5, 0xB0, 0x77, 0x97, 0xE8, 0x03, 0x00, 0xDF, 0xF8, -+0xC4, 0xC0, 0x41, 0xF2, 0x0C, 0x02, 0xAC, 0xF8, 0x04, 0x10, 0x41, 0xF2, 0x3B, 0x01, 0xA0, 0x50, 0x63, 0x54, 0x38, 0x46, -+0x1A, 0x46, 0x19, 0x46, 0x00, 0xF0, 0x4A, 0xF9, 0x18, 0xB1, 0x90, 0xF8, 0x3D, 0x10, 0x03, 0x46, 0x91, 0xB9, 0x97, 0xE8, -+0x03, 0x00, 0x21, 0x4B, 0x41, 0xF2, 0x34, 0x02, 0x99, 0x80, 0x20, 0x4B, 0xA0, 0x50, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x28, 0xDB, 0x1D, 0x4B, 0xD3, 0xF8, 0xF4, 0x32, 0x98, 0x47, 0x01, 0x20, 0xF8, 0xBD, 0x02, 0x46, 0x41, 0xF2, -+0x34, 0x0C, 0x52, 0xF8, 0x02, 0x0F, 0x93, 0xF8, 0x3E, 0x70, 0x44, 0xF8, 0x0C, 0x00, 0x14, 0x48, 0x92, 0x88, 0x82, 0x80, -+0xBE, 0x40, 0x41, 0xF2, 0x38, 0x00, 0x01, 0x3E, 0x22, 0x5A, 0x36, 0x02, 0x36, 0xB2, 0x22, 0xEA, 0x06, 0x02, 0x12, 0xB2, -+0x22, 0x52, 0xDB, 0x88, 0xA3, 0xEB, 0x01, 0x21, 0x0E, 0x40, 0x0C, 0x4B, 0x16, 0x43, 0x26, 0x52, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0xD6, 0xDA, 0x95, 0xF8, 0x60, 0x31, 0xDB, 0x07, 0xD2, 0xD5, 0x08, 0x49, 0x08, 0x48, 0xA1, 0x22, -+0xF8, 0xF7, 0xD8, 0xFC, 0xCC, 0xE7, 0x00, 0xBF, 0xA8, 0xBA, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0xDC, 0xCA, 0x17, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xD0, 0xBE, 0x15, 0x00, 0xB4, 0xCA, 0x17, 0x00, -+0x1A, 0x46, 0x38, 0xB5, 0x41, 0xF2, 0x08, 0x00, 0x0D, 0x46, 0x02, 0x23, 0x11, 0x46, 0x04, 0x22, 0xF6, 0xF7, 0xDA, 0xFB, -+0x0A, 0x49, 0x04, 0x46, 0x08, 0x20, 0xF8, 0xF7, 0x8D, 0xFA, 0x29, 0x46, 0x08, 0x48, 0x31, 0xF8, 0x03, 0x2B, 0x20, 0xF8, -+0x03, 0x2B, 0x0A, 0xF0, 0x55, 0xFF, 0x01, 0x23, 0x23, 0x70, 0xAB, 0x78, 0x63, 0x70, 0x20, 0x46, 0xF6, 0xF7, 0xF6, 0xFB, -+0x00, 0x20, 0x38, 0xBD, 0xF0, 0xBE, 0x15, 0x00, 0x68, 0xCB, 0x17, 0x00, 0x08, 0x78, 0x08, 0xB9, 0x00, 0x20, 0x70, 0x47, -+0x08, 0xB5, 0x00, 0xF0, 0x31, 0xF8, 0x00, 0x20, 0x08, 0xBD, 0x00, 0xBF, 0x70, 0xB5, 0x0B, 0x4E, 0x41, 0xF2, 0x08, 0x05, -+0x01, 0x23, 0x0C, 0x46, 0x04, 0x22, 0x71, 0x5B, 0x41, 0xF2, 0x0B, 0x00, 0xF6, 0xF7, 0xAA, 0xFB, 0xF6, 0xF7, 0xD8, 0xFB, -+0x72, 0x5B, 0x05, 0x49, 0x08, 0x20, 0xF8, 0xF7, 0x5B, 0xFA, 0x20, 0x78, 0x00, 0xF0, 0x18, 0xF8, 0x00, 0x20, 0x70, 0xBD, -+0xA8, 0xBA, 0x17, 0x00, 0x00, 0xBF, 0x15, 0x00, 0x08, 0xB5, 0x05, 0x49, 0x41, 0xF2, 0x0B, 0x02, 0x8B, 0x5C, 0x01, 0x33, -+0x8B, 0x54, 0x00, 0xF0, 0x65, 0xFD, 0x00, 0x20, 0x08, 0xBD, 0x00, 0xBF, 0xA8, 0xBA, 0x17, 0x00, 0x08, 0x46, 0x00, 0xF0, -+0x19, 0xB9, 0x00, 0xBF, 0xF0, 0xB5, 0x39, 0x4C, 0x41, 0xF2, 0x0A, 0x05, 0x83, 0xB0, 0x63, 0x5D, 0x06, 0x46, 0x00, 0x2B, -+0x43, 0xD0, 0x41, 0xF2, 0x08, 0x02, 0x03, 0x23, 0xA1, 0x5A, 0x41, 0xF2, 0x03, 0x00, 0x04, 0x22, 0xF6, 0xF7, 0x76, 0xFB, -+0x05, 0x46, 0x23, 0x68, 0x30, 0x49, 0x93, 0xF8, 0x6E, 0x21, 0x00, 0x96, 0x41, 0xF2, 0x0A, 0x07, 0x08, 0x20, 0xE3, 0x5D, -+0xF8, 0xF7, 0x22, 0xFA, 0xE3, 0x5D, 0x63, 0xB9, 0x2B, 0x49, 0x2C, 0x4A, 0x0B, 0x68, 0x2C, 0x48, 0x23, 0xF0, 0x04, 0x03, -+0x0B, 0x60, 0x13, 0x68, 0x01, 0x88, 0x1B, 0x0C, 0x1B, 0x04, 0x0B, 0x43, 0x13, 0x60, 0x20, 0x68, 0x27, 0x4B, 0x90, 0xF8, -+0x6E, 0x21, 0x2A, 0x70, 0x6E, 0x70, 0xA2, 0x88, 0xAA, 0x70, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x20, 0xD0, 0x0C, 0x38, -+0xF6, 0xF7, 0xC8, 0xFB, 0x00, 0x26, 0x28, 0x46, 0x26, 0x60, 0xF6, 0xF7, 0x77, 0xFB, 0x1F, 0x4A, 0x53, 0x68, 0x31, 0x46, -+0x23, 0xF0, 0x20, 0x03, 0x04, 0x20, 0x53, 0x60, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x40, 0xF6, 0xF7, 0x35, 0xBD, 0xA3, 0x88, -+0xF3, 0xB1, 0x41, 0xF2, 0x08, 0x02, 0x03, 0x23, 0xA1, 0x5A, 0x41, 0xF2, 0x01, 0x00, 0x04, 0x22, 0xF6, 0xF7, 0x30, 0xFB, -+0x05, 0x46, 0xB8, 0xE7, 0x13, 0x4B, 0x93, 0xF8, 0xB5, 0x30, 0x00, 0x2B, 0xD9, 0xD0, 0x12, 0x49, 0x12, 0x4B, 0x0A, 0x68, -+0x22, 0xF0, 0x7C, 0x72, 0x0A, 0x60, 0x1A, 0x68, 0x42, 0xF4, 0x80, 0x02, 0x1A, 0x60, 0x1A, 0x68, 0x42, 0xF4, 0x00, 0x12, -+0x1A, 0x60, 0xCA, 0xE7, 0xD6, 0xF7, 0xCC, 0xFB, 0x63, 0x5D, 0x00, 0x2B, 0xDB, 0xD0, 0x94, 0xE7, 0xA8, 0xBA, 0x17, 0x00, -+0x30, 0xBF, 0x15, 0x00, 0x94, 0x40, 0x04, 0x40, 0x20, 0x04, 0x32, 0x40, 0x28, 0x25, 0x17, 0x00, 0x74, 0x36, 0x17, 0x00, -+0x1C, 0x9E, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x74, 0x00, 0x32, 0x40, 0x6C, 0x00, 0x32, 0x40, 0x08, 0xB5, 0x00, 0x21, -+0x04, 0x20, 0xF6, 0xF7, 0xF5, 0xFC, 0xBD, 0xE8, 0x08, 0x40, 0x03, 0x48, 0x4F, 0xF4, 0x86, 0x52, 0x00, 0x21, 0xD3, 0xF7, -+0xED, 0xBE, 0x00, 0xBF, 0xA8, 0xBA, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x3C, 0x4D, 0x83, 0xB0, 0xA8, 0x46, 0x2B, 0x46, -+0x00, 0x22, 0x08, 0xE0, 0x5F, 0x89, 0x04, 0x88, 0xA7, 0x42, 0x14, 0xD0, 0x01, 0x32, 0x40, 0x2A, 0x03, 0xF1, 0x40, 0x03, -+0x1C, 0xD0, 0x1C, 0x7A, 0x03, 0xF1, 0x08, 0x06, 0x00, 0x2C, 0xF1, 0xD1, 0x00, 0x29, 0xF3, 0xD0, 0x08, 0xEB, 0x82, 0x12, -+0x80, 0x23, 0x82, 0xF8, 0x44, 0x30, 0x30, 0x46, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x9F, 0x89, 0x44, 0x88, 0xA7, 0x42, -+0xE6, 0xD1, 0xDF, 0x89, 0x84, 0x88, 0xA7, 0x42, 0xF3, 0xD0, 0x01, 0x32, 0x40, 0x2A, 0x03, 0xF1, 0x40, 0x03, 0xE2, 0xD1, -+0x00, 0x29, 0x46, 0xD0, 0x26, 0x4F, 0x4F, 0xF0, 0x00, 0x0B, 0x4F, 0xF0, 0x21, 0x0A, 0x06, 0xE0, 0x0B, 0xF1, 0x01, 0x0B, -+0xBB, 0xF1, 0x40, 0x0F, 0x05, 0xF1, 0x40, 0x05, 0x39, 0xD0, 0x2B, 0x7A, 0x05, 0xF1, 0x08, 0x06, 0x00, 0x2B, 0xF3, 0xD0, -+0x95, 0xF8, 0x45, 0x40, 0x00, 0x2C, 0xEF, 0xD1, 0x38, 0x68, 0x30, 0xB3, 0x90, 0xF8, 0x70, 0x31, 0x1B, 0xB3, 0x05, 0xF1, -+0x11, 0x01, 0x4F, 0xF0, 0xFD, 0x09, 0x06, 0xE0, 0x38, 0x68, 0x01, 0x34, 0x90, 0xF8, 0x70, 0x31, 0xE4, 0xB2, 0xA3, 0x42, -+0x15, 0xD9, 0x04, 0xEB, 0x44, 0x13, 0x03, 0x44, 0x93, 0xF8, 0xFC, 0x30, 0x00, 0x2B, 0xF1, 0xD0, 0x2A, 0x7C, 0x9A, 0x42, -+0xEE, 0xD1, 0x1A, 0xFB, 0x04, 0x93, 0x18, 0x44, 0x01, 0x91, 0x0A, 0xF0, 0xE1, 0xFD, 0x01, 0x99, 0x00, 0x28, 0xE5, 0xD1, -+0x3B, 0x68, 0x93, 0xF8, 0x70, 0x31, 0x9C, 0x42, 0xC6, 0xD1, 0x08, 0xEB, 0x8B, 0x11, 0x80, 0x20, 0x00, 0x23, 0x81, 0xF8, -+0x44, 0x00, 0x0B, 0x72, 0xA5, 0xE7, 0x00, 0x26, 0x30, 0x46, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xA8, 0xBA, 0x17, 0x00, -+0xF4, 0x9F, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x2D, 0xED, 0x02, 0x8B, 0x61, 0x4B, 0x99, 0xB0, 0x1C, 0x68, 0x03, 0x46, -+0x04, 0x93, 0x04, 0x20, 0x94, 0xF8, 0x6E, 0x31, 0x07, 0x93, 0xF6, 0xF7, 0x03, 0xFD, 0x01, 0x28, 0x05, 0xD0, 0x00, 0x20, -+0x19, 0xB0, 0xBD, 0xEC, 0x02, 0x8B, 0xBD, 0xE8, 0xF0, 0x8F, 0x58, 0x49, 0x41, 0xF2, 0x0C, 0x03, 0xCA, 0x5C, 0xD2, 0x07, -+0x19, 0xD4, 0xCA, 0x5A, 0x04, 0x9B, 0x9B, 0x8B, 0x9A, 0x42, 0x00, 0xF0, 0x85, 0x80, 0x52, 0x49, 0x41, 0xF2, 0x34, 0x02, -+0x8A, 0x5A, 0x9A, 0x42, 0xE7, 0xD1, 0x04, 0x9A, 0x41, 0xF2, 0x36, 0x03, 0xD2, 0x8B, 0xCB, 0x5A, 0x9A, 0x42, 0xE0, 0xD1, -+0x04, 0x9A, 0x41, 0xF2, 0x38, 0x03, 0x12, 0x8C, 0xCB, 0x5A, 0x9A, 0x42, 0xD9, 0xD1, 0x04, 0x98, 0x30, 0xF8, 0x30, 0x3B, -+0x0B, 0x90, 0x24, 0x3B, 0x9B, 0xB2, 0x0D, 0xF1, 0x37, 0x02, 0x19, 0x46, 0x08, 0xEE, 0x10, 0x3A, 0xF7, 0xF7, 0xE4, 0xF8, -+0x00, 0x28, 0x73, 0xD0, 0x9D, 0xF8, 0x37, 0x60, 0x10, 0xAD, 0x4E, 0xB1, 0xAF, 0x19, 0x2B, 0x46, 0xC5, 0xF1, 0x02, 0x01, -+0xC2, 0x18, 0x52, 0x5C, 0x03, 0xF8, 0x01, 0x2B, 0xBB, 0x42, 0xF9, 0xD1, 0x04, 0x9F, 0x38, 0x46, 0x01, 0x21, 0x2B, 0x46, -+0x32, 0x46, 0x1C, 0x30, 0xFF, 0xF7, 0x24, 0xFF, 0x01, 0x46, 0x0A, 0x90, 0x00, 0x28, 0xB0, 0xD0, 0xBB, 0x8B, 0x43, 0x80, -+0xFB, 0x8B, 0x83, 0x80, 0x3B, 0x8C, 0xC3, 0x80, 0x97, 0xF8, 0x2C, 0x30, 0x97, 0xF8, 0x2D, 0x20, 0x43, 0xEA, 0x02, 0x23, -+0x03, 0x86, 0xFB, 0x8D, 0x43, 0x86, 0x03, 0xF0, 0x01, 0x03, 0xC3, 0xF1, 0x02, 0x03, 0x43, 0x85, 0x00, 0x2E, 0x46, 0xD1, -+0x0A, 0x9B, 0x1E, 0x72, 0x27, 0x4A, 0x41, 0xF2, 0x3A, 0x03, 0xD3, 0x5C, 0x00, 0x2B, 0x40, 0xF0, 0xA5, 0x82, 0x24, 0x4A, -+0x41, 0xF2, 0x0A, 0x03, 0xD5, 0x5C, 0x00, 0x2D, 0x48, 0xD1, 0x94, 0xF8, 0x70, 0x11, 0x00, 0x29, 0x44, 0xD0, 0x0A, 0x9B, -+0x26, 0x46, 0x03, 0xF1, 0x09, 0x07, 0x98, 0x46, 0x08, 0x46, 0x05, 0xE0, 0x01, 0x35, 0xA8, 0x42, 0x06, 0xF1, 0x21, 0x06, -+0x03, 0x46, 0x34, 0xDD, 0x96, 0xF8, 0xFC, 0x30, 0x83, 0xB3, 0x98, 0xF8, 0x08, 0x20, 0x9A, 0x42, 0xF2, 0xD1, 0x39, 0x46, -+0x06, 0xF1, 0xFD, 0x00, 0x0A, 0xF0, 0x26, 0xFD, 0x00, 0x28, 0x00, 0xF0, 0x2C, 0x83, 0x94, 0xF8, 0x70, 0x01, 0xE7, 0xE7, -+0x04, 0x99, 0x0F, 0x48, 0xC9, 0x8B, 0x41, 0xF2, 0x0E, 0x02, 0x82, 0x5A, 0x91, 0x42, 0x7F, 0xF4, 0x72, 0xAF, 0x04, 0x99, -+0x41, 0xF2, 0x10, 0x02, 0x09, 0x8C, 0x82, 0x5A, 0x91, 0x42, 0x7F, 0xF4, 0x6A, 0xAF, 0x7C, 0xE7, 0x06, 0x46, 0x10, 0xAD, -+0x96, 0xE7, 0x0B, 0x46, 0x03, 0xF8, 0x08, 0x6F, 0x2E, 0x44, 0x15, 0xF8, 0x01, 0x2B, 0x03, 0xF8, 0x01, 0x2F, 0xAE, 0x42, -+0xF9, 0xD1, 0xAF, 0xE7, 0xA8, 0xBA, 0x17, 0x00, 0x03, 0x46, 0x9D, 0x42, 0x3F, 0xF4, 0x43, 0xAF, 0x18, 0xEE, 0x10, 0x1A, -+0x0B, 0x98, 0xF7, 0xF7, 0x45, 0xF9, 0x00, 0x28, 0x00, 0xF0, 0x3A, 0x82, 0x04, 0x9B, 0x9A, 0x79, 0x83, 0x78, 0x00, 0x2A, -+0x40, 0xF0, 0x56, 0x82, 0x59, 0x1E, 0x0D, 0x29, 0x00, 0xF2, 0x4F, 0x82, 0x0E, 0x2B, 0x00, 0xF0, 0xEB, 0x82, 0x03, 0xEB, -+0x83, 0x03, 0x03, 0xF6, 0x67, 0x11, 0x10, 0x46, 0xFA, 0xF7, 0x98, 0xFE, 0x0A, 0x99, 0x04, 0x9B, 0xC8, 0x62, 0x91, 0xF9, -+0x3C, 0x20, 0x93, 0xF9, 0x09, 0x30, 0x9A, 0x42, 0xB8, 0xBF, 0x81, 0xF8, 0x3C, 0x30, 0x04, 0x99, 0x03, 0x88, 0x8A, 0x88, -+0x9A, 0x42, 0x00, 0xD0, 0x8B, 0x80, 0x41, 0xF2, 0xBD, 0x03, 0xB4, 0x4A, 0x00, 0x25, 0xD5, 0x54, 0x18, 0xEE, 0x10, 0x3A, -+0x00, 0x2B, 0x6C, 0xD0, 0x0B, 0x9B, 0x8D, 0xED, 0x05, 0x8A, 0x2C, 0x46, 0xA8, 0x46, 0x06, 0x93, 0xDD, 0xE9, 0x05, 0x10, -+0xF7, 0xF7, 0xFC, 0xF9, 0x08, 0x90, 0x00, 0x28, 0x5F, 0xD0, 0x43, 0x78, 0xAA, 0x4A, 0x81, 0x78, 0x11, 0x70, 0x5E, 0x1E, -+0x02, 0x33, 0xB6, 0xB2, 0x09, 0x93, 0x00, 0xF1, 0x03, 0x0A, 0x00, 0x2E, 0x44, 0xD0, 0x31, 0x46, 0x50, 0x46, 0xF7, 0xF7, -+0x09, 0xFA, 0x07, 0x46, 0x00, 0x28, 0x3D, 0xD0, 0x90, 0xF8, 0x01, 0x90, 0x00, 0xF1, 0x02, 0x0B, 0x09, 0xF1, 0x02, 0x03, -+0xF6, 0x1A, 0x58, 0x46, 0x04, 0x21, 0xB6, 0xB2, 0x9A, 0x44, 0xF7, 0xF7, 0x1D, 0xFA, 0x00, 0x28, 0x00, 0xF0, 0x81, 0x81, -+0x49, 0x46, 0x58, 0x46, 0xF7, 0xF7, 0x36, 0xFA, 0x07, 0xF1, 0x04, 0x08, 0x04, 0x46, 0x49, 0x46, 0x58, 0x46, 0x0E, 0xAA, -+0xF6, 0xF7, 0xE8, 0xFF, 0x05, 0x46, 0x00, 0x2C, 0xD7, 0xD0, 0x00, 0x2D, 0xD5, 0xD0, 0x92, 0x4B, 0x98, 0xF8, 0x00, 0xC0, -+0x1A, 0x78, 0xA7, 0x78, 0xA3, 0xF1, 0x81, 0x00, 0x81, 0x1D, 0x98, 0xF8, 0x01, 0x30, 0x01, 0xF8, 0x32, 0x70, 0x4C, 0xEA, -+0x03, 0x21, 0x53, 0x1C, 0xDB, 0xB2, 0x07, 0x1D, 0x10, 0x2B, 0x40, 0xF8, 0x32, 0x50, 0x80, 0xF8, 0x81, 0x30, 0x27, 0xF8, -+0x32, 0x10, 0x12, 0xD0, 0x4F, 0xF0, 0x00, 0x08, 0x00, 0x2E, 0xBA, 0xD1, 0x06, 0x9B, 0x08, 0x9A, 0x05, 0x99, 0x9B, 0x1A, -+0x19, 0x44, 0x09, 0x9B, 0xA1, 0xEB, 0x03, 0x0B, 0x1F, 0xFA, 0x8B, 0xF1, 0xD3, 0x18, 0x05, 0x91, 0x06, 0x93, 0x00, 0x29, -+0x98, 0xD1, 0x0A, 0x99, 0x00, 0x23, 0x4B, 0x63, 0x8B, 0x63, 0x41, 0xF2, 0x0A, 0x02, 0x77, 0x4B, 0x9B, 0x5C, 0x00, 0x2B, -+0x00, 0xF0, 0xB4, 0x80, 0x0A, 0x9A, 0x07, 0x9F, 0x76, 0x4C, 0x56, 0x8D, 0x51, 0x8E, 0x13, 0x46, 0x4F, 0xF4, 0xA4, 0x65, -+0x53, 0xF8, 0x02, 0x0F, 0x12, 0x8E, 0x9B, 0x88, 0x05, 0xFB, 0x07, 0xF5, 0x67, 0x19, 0xA7, 0xF8, 0x68, 0x31, 0xA7, 0xF8, -+0x98, 0x21, 0xFF, 0x23, 0x0A, 0x9A, 0xA7, 0xF8, 0x8E, 0x61, 0xC7, 0xF8, 0x64, 0x01, 0xA7, 0xF8, 0x9A, 0x11, 0x87, 0xF8, -+0x61, 0x31, 0x87, 0xF8, 0xBE, 0x31, 0x13, 0x7A, 0x05, 0xF1, 0xEC, 0x06, 0x26, 0x44, 0x00, 0x2B, 0x40, 0xF0, 0xA2, 0x81, -+0x0A, 0x9A, 0xD2, 0x6A, 0xC7, 0xF8, 0x90, 0x21, 0xA7, 0xF8, 0xC2, 0x31, 0x07, 0x9B, 0x0A, 0x9A, 0x0B, 0x98, 0x4F, 0xF4, -+0xA4, 0x67, 0x07, 0xFB, 0x03, 0x47, 0x92, 0xF8, 0x3D, 0x30, 0x87, 0xF8, 0x8B, 0x31, 0x92, 0xF8, 0x3E, 0x30, 0x87, 0xF8, -+0x8C, 0x31, 0x05, 0xF5, 0xCE, 0x78, 0x00, 0x23, 0xA0, 0x44, 0xC7, 0xF8, 0xCC, 0x31, 0x18, 0xEE, 0x10, 0x1A, 0x42, 0x46, -+0xF9, 0xF7, 0xA4, 0xFB, 0x0A, 0x9B, 0xDB, 0x6A, 0x9B, 0x78, 0x00, 0x2B, 0x00, 0xF0, 0xB3, 0x81, 0x05, 0xF5, 0xD6, 0x72, -+0x18, 0xEE, 0x10, 0x1A, 0x0B, 0x98, 0x22, 0x44, 0x0E, 0xAB, 0xF9, 0xF7, 0x6D, 0xFD, 0x80, 0xB1, 0x07, 0x9A, 0x4F, 0xF4, -+0xA4, 0x63, 0x03, 0xFB, 0x02, 0x43, 0xB3, 0xF8, 0x9A, 0x11, 0xD3, 0xF8, 0xCC, 0x21, 0x41, 0xF4, 0x00, 0x71, 0x42, 0xF0, -+0x01, 0x02, 0xA3, 0xF8, 0x9A, 0x11, 0xC3, 0xF8, 0xCC, 0x21, 0x45, 0x4F, 0x97, 0xF8, 0x76, 0x31, 0xDB, 0x07, 0x09, 0xD5, -+0x07, 0x9B, 0x4F, 0xF4, 0xA4, 0x69, 0x09, 0xFB, 0x03, 0x49, 0xD9, 0xF8, 0xCC, 0x31, 0xD8, 0x07, 0x00, 0xF1, 0x98, 0x81, -+0x00, 0x21, 0x88, 0x46, 0x40, 0x46, 0x32, 0x46, 0xFB, 0xF7, 0x52, 0xFA, 0x0B, 0x9D, 0x18, 0xEE, 0x10, 0x1A, 0x28, 0x46, -+0x32, 0x46, 0xF9, 0xF7, 0xAD, 0xFB, 0x28, 0x46, 0x18, 0xEE, 0x10, 0x1A, 0x32, 0x46, 0xF9, 0xF7, 0xB1, 0xFB, 0x28, 0x46, -+0x18, 0xEE, 0x10, 0x1A, 0x32, 0x46, 0xF9, 0xF7, 0x13, 0xFC, 0x07, 0x9A, 0x31, 0x4D, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, -+0x02, 0x44, 0x29, 0x6D, 0xD4, 0xF8, 0xCC, 0x31, 0x43, 0xF0, 0x00, 0x43, 0x41, 0xF2, 0x3B, 0x02, 0xC4, 0xF8, 0xCC, 0x31, -+0x25, 0x4B, 0x01, 0x20, 0x98, 0x54, 0x2A, 0x6A, 0x00, 0x29, 0x00, 0xF0, 0x1C, 0x81, 0x00, 0x2A, 0x00, 0xF0, 0x19, 0x81, -+0x0B, 0x7E, 0x03, 0x2B, 0x08, 0xD1, 0x25, 0x4B, 0x05, 0xF1, 0x40, 0x00, 0xD3, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0xD5, 0xE9, -+0x11, 0x30, 0x98, 0x47, 0x0A, 0x9A, 0x14, 0x78, 0xDC, 0xB9, 0x19, 0x48, 0x1F, 0x4B, 0x81, 0x88, 0x1B, 0x68, 0x01, 0x31, -+0x89, 0xB2, 0x81, 0x80, 0x1B, 0x88, 0x5B, 0x07, 0x11, 0xD5, 0x13, 0x7A, 0x00, 0x2B, 0x40, 0xF0, 0x7A, 0x81, 0x1A, 0x4D, -+0x0A, 0x9A, 0x04, 0x9C, 0xD2, 0x6A, 0x94, 0xF9, 0x09, 0x00, 0x12, 0x88, 0x00, 0x90, 0xCD, 0xE9, 0x01, 0x35, 0x16, 0x48, -+0x23, 0x7B, 0xF7, 0xF7, 0x89, 0xFE, 0x0A, 0x99, 0x00, 0x25, 0x01, 0x22, 0x0A, 0x70, 0x81, 0xF8, 0x3D, 0x50, 0x81, 0xF8, -+0x3E, 0x50, 0x41, 0xF2, 0xBD, 0x03, 0x08, 0x46, 0x05, 0x49, 0xCB, 0x5C, 0x00, 0x2B, 0x4D, 0xD0, 0x0D, 0x4C, 0x83, 0x46, -+0x04, 0xF1, 0x80, 0x0A, 0x04, 0xF1, 0x81, 0x09, 0x43, 0xE0, 0x00, 0xBF, 0xA8, 0xBA, 0x17, 0x00, 0x64, 0xCB, 0x17, 0x00, -+0x65, 0xCB, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0xE4, 0xB8, 0x17, 0x00, 0x30, 0x9D, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x48, 0xBF, 0x15, 0x00, 0x84, 0xBF, 0x15, 0x00, 0xE4, 0xCA, 0x17, 0x00, 0x9A, 0xF8, 0x00, 0x70, -+0x08, 0x2F, 0x2B, 0xD8, 0x5A, 0x46, 0x21, 0x68, 0x52, 0xF8, 0x02, 0x0F, 0x4E, 0x78, 0x0E, 0x90, 0x92, 0x88, 0xAD, 0xF8, -+0x3C, 0x20, 0xBB, 0xF8, 0x06, 0x20, 0xBD, 0xF9, 0x3C, 0x10, 0x4F, 0xF0, 0x01, 0x08, 0x02, 0xEB, 0x03, 0x22, 0x08, 0xFA, -+0x07, 0xF3, 0x4A, 0x40, 0x01, 0x3B, 0x02, 0xEA, 0x03, 0x22, 0x00, 0x23, 0x81, 0xEA, 0x02, 0x0C, 0x0E, 0xA8, 0x1A, 0x46, -+0x19, 0x46, 0xAD, 0xF8, 0x3C, 0xC0, 0xFF, 0xF7, 0xDF, 0xFC, 0x68, 0xB3, 0x99, 0xF8, 0x00, 0x30, 0x01, 0x35, 0x9D, 0x42, -+0x04, 0xF1, 0x08, 0x04, 0x02, 0xDA, 0xA3, 0x79, 0x00, 0x2B, 0xCF, 0xD1, 0x04, 0x98, 0x04, 0x23, 0x0C, 0x22, 0x41, 0xF2, -+0x04, 0x01, 0xF6, 0xF7, 0x2D, 0xF8, 0x01, 0x20, 0x5C, 0xE5, 0xB8, 0xF1, 0x00, 0x0F, 0x3F, 0xF4, 0x62, 0xAE, 0x4C, 0xB1, -+0x00, 0x2D, 0x7F, 0xF4, 0x88, 0xAE, 0x49, 0x46, 0x58, 0x46, 0x0E, 0xAA, 0xF6, 0xF7, 0x66, 0xFE, 0x05, 0x46, 0x7E, 0xE6, -+0x49, 0x46, 0x58, 0x46, 0xF7, 0xF7, 0xA6, 0xF8, 0x04, 0x46, 0x00, 0x2D, 0x3F, 0xF4, 0x6F, 0xAE, 0x00, 0x28, 0x3F, 0xF4, -+0x4C, 0xAE, 0x74, 0xE6, 0x23, 0x68, 0x41, 0x46, 0x02, 0x33, 0x32, 0x46, 0x0E, 0xA8, 0xFF, 0xF7, 0xA9, 0xFC, 0x86, 0x46, -+0x00, 0x28, 0xD1, 0xD0, 0xD8, 0x46, 0xB8, 0xE8, 0x0F, 0x00, 0xF4, 0x46, 0xAC, 0xE8, 0x0F, 0x00, 0xB8, 0xE8, 0x0F, 0x00, -+0xAC, 0xE8, 0x0F, 0x00, 0xB8, 0xE8, 0x0F, 0x00, 0xAC, 0xE8, 0x0F, 0x00, 0x98, 0xE8, 0x0F, 0x00, 0x8C, 0xE8, 0x0F, 0x00, -+0x0E, 0x98, 0xCE, 0xF8, 0x02, 0x00, 0xBD, 0xF8, 0x3C, 0x30, 0x8E, 0xF8, 0x08, 0x60, 0x21, 0x68, 0xAE, 0xF8, 0x06, 0x30, -+0x5E, 0xB1, 0x08, 0x36, 0x06, 0x39, 0x76, 0x44, 0xA1, 0xEB, 0x0E, 0x01, 0x0E, 0xF1, 0x08, 0x03, 0xCA, 0x5C, 0x03, 0xF8, -+0x01, 0x2F, 0x9E, 0x42, 0xFA, 0xD1, 0x7E, 0x49, 0x8E, 0xF8, 0x3E, 0x70, 0x8B, 0x88, 0xA2, 0x79, 0x8E, 0xF8, 0x3D, 0x20, -+0x01, 0x33, 0x01, 0x22, 0x8B, 0x80, 0x8E, 0xF8, 0x00, 0x20, 0x91, 0xE7, 0x04, 0x9B, 0x93, 0xF9, 0x09, 0x20, 0x0A, 0x9B, -+0x93, 0xF9, 0x3C, 0x30, 0x9A, 0x42, 0x7F, 0xF7, 0xE2, 0xAD, 0x04, 0x9C, 0xA1, 0x88, 0xA0, 0x79, 0xFA, 0xF7, 0x64, 0xFC, -+0x0A, 0x9A, 0xD0, 0x62, 0x63, 0x7A, 0x82, 0xF8, 0x3C, 0x30, 0xD6, 0xE5, 0x0A, 0x9B, 0x6E, 0x49, 0x07, 0x22, 0x03, 0xF1, -+0x09, 0x00, 0x0A, 0xF0, 0x9D, 0xFA, 0x00, 0x28, 0x7F, 0xF4, 0xE3, 0xAC, 0x9E, 0xE5, 0x4F, 0xF6, 0xFF, 0x71, 0xB4, 0xE5, -+0x01, 0x2A, 0xFA, 0xD1, 0x59, 0x1E, 0xA4, 0x29, 0xF7, 0xD8, 0x03, 0xEB, 0x83, 0x03, 0x03, 0xF5, 0x9C, 0x51, 0x08, 0x31, -+0xA9, 0xE5, 0xB2, 0xFA, 0x82, 0xF2, 0x62, 0x48, 0x52, 0x09, 0xF7, 0xF7, 0x95, 0xFD, 0xEB, 0xE6, 0x02, 0xF1, 0x09, 0x00, -+0x0A, 0xF0, 0xAC, 0xFC, 0xA8, 0xB1, 0x0A, 0x9B, 0x07, 0xF5, 0xB5, 0x77, 0x03, 0xF1, 0x08, 0x08, 0x03, 0xF1, 0x28, 0x0E, -+0xC4, 0x46, 0xBC, 0xE8, 0x0F, 0x00, 0xF4, 0x45, 0x38, 0x60, 0x79, 0x60, 0xBA, 0x60, 0xFB, 0x60, 0xE0, 0x46, 0x07, 0xF1, -+0x10, 0x07, 0xF3, 0xD1, 0x9C, 0xF8, 0x00, 0x30, 0x3B, 0x70, 0x0A, 0x9B, 0x07, 0x98, 0x19, 0x7A, 0x0A, 0x9B, 0xDA, 0x6A, -+0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x00, 0x43, 0x00, 0x27, 0xC3, 0xF8, 0x90, 0x21, 0xA3, 0xF8, 0xC2, 0x71, 0x00, 0x29, -+0x3F, 0xF4, 0x38, 0xAE, 0x0B, 0x44, 0x05, 0xF2, 0x6B, 0x11, 0x12, 0x88, 0x48, 0x48, 0x83, 0xF8, 0x6B, 0x71, 0x21, 0x44, -+0xF7, 0xF7, 0x5E, 0xFD, 0x2C, 0xE6, 0x40, 0x46, 0x01, 0x21, 0xFA, 0xF7, 0xED, 0xFD, 0x10, 0xF0, 0x0F, 0x00, 0x1A, 0xBF, -+0xB0, 0xFA, 0x80, 0xF0, 0xC0, 0xF1, 0x1F, 0x03, 0x01, 0x23, 0x87, 0xF8, 0xC1, 0x31, 0x3D, 0xE6, 0x18, 0xEE, 0x10, 0x1A, -+0x0B, 0x98, 0x32, 0x46, 0xF9, 0xF7, 0x0C, 0xFC, 0x00, 0x28, 0x3F, 0xF4, 0x5F, 0xAE, 0xD9, 0xF8, 0xCC, 0x31, 0x0B, 0x98, -+0x43, 0xF0, 0x02, 0x03, 0x18, 0xEE, 0x10, 0x1A, 0xC9, 0xF8, 0xCC, 0x31, 0xF7, 0xF7, 0x24, 0xF8, 0x97, 0xF8, 0x76, 0x31, -+0x59, 0x07, 0x80, 0x46, 0x30, 0xD4, 0x9A, 0x07, 0x0A, 0xD4, 0x07, 0x9A, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0x43, -+0xD3, 0xF8, 0xCC, 0x11, 0x11, 0xF0, 0x08, 0x01, 0x3F, 0xF4, 0x44, 0xAE, 0x05, 0xF5, 0x86, 0x72, 0x18, 0xEE, 0x10, 0x1A, -+0x0B, 0x98, 0x22, 0x44, 0xF9, 0xF7, 0x08, 0xFC, 0x30, 0xBB, 0x01, 0x46, 0x38, 0xE6, 0x02, 0xF1, 0x09, 0x05, 0x28, 0x46, -+0x16, 0x46, 0x0A, 0xF0, 0x33, 0xFC, 0x20, 0xB9, 0x1E, 0x4B, 0x22, 0x4D, 0x99, 0x88, 0x33, 0x7A, 0x7A, 0xE6, 0x0A, 0x9A, -+0x1B, 0x49, 0x13, 0x7A, 0x89, 0x88, 0x1A, 0x44, 0x54, 0x72, 0x73, 0xE6, 0x40, 0xF6, 0xB4, 0x11, 0x15, 0xE5, 0x94, 0xF8, -+0x70, 0x31, 0xF6, 0xE4, 0x05, 0xF5, 0x8C, 0x72, 0x18, 0xEE, 0x10, 0x1A, 0x0B, 0x98, 0x22, 0x44, 0xF9, 0xF7, 0x02, 0xFC, -+0xA0, 0xB9, 0x97, 0xF8, 0x76, 0x31, 0xC2, 0xE7, 0x07, 0x9A, 0x0B, 0x98, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0x43, -+0x18, 0xEE, 0x10, 0x1A, 0xD3, 0xF8, 0xCC, 0x21, 0x42, 0xF0, 0x04, 0x02, 0xC3, 0xF8, 0xCC, 0x21, 0xF6, 0xF7, 0xF2, 0xFF, -+0x01, 0x46, 0x01, 0xE6, 0xD9, 0xF8, 0xCC, 0x31, 0x0B, 0x98, 0x43, 0xF0, 0x08, 0x03, 0x18, 0xEE, 0x10, 0x1A, 0x32, 0x46, -+0xC9, 0xF8, 0xCC, 0x31, 0xF9, 0xF7, 0x36, 0xFC, 0xDD, 0xE7, 0x00, 0xBF, 0xA8, 0xBA, 0x17, 0x00, 0x54, 0xBF, 0x15, 0x00, -+0x68, 0xBF, 0x15, 0x00, 0x5C, 0xBF, 0x15, 0x00, 0x48, 0xBF, 0x15, 0x00, 0x00, 0x23, 0x1A, 0x46, 0x19, 0x46, 0xFF, 0xF7, -+0x71, 0xBB, 0x00, 0xBF, 0x2D, 0xE9, 0xF8, 0x43, 0x03, 0x78, 0x43, 0xB3, 0x16, 0x4C, 0x07, 0x46, 0x4F, 0xF0, 0x00, 0x08, -+0x04, 0xF5, 0x80, 0x56, 0x6F, 0xF0, 0x7F, 0x05, 0x00, 0xF1, 0x01, 0x09, 0x02, 0xE0, 0x40, 0x34, 0xB4, 0x42, 0x17, 0xD0, -+0x23, 0x7A, 0xAB, 0xB1, 0x94, 0xF9, 0x44, 0x30, 0xAB, 0x42, 0xF6, 0xDD, 0x23, 0x7C, 0x3A, 0x78, 0x9A, 0x42, 0xF2, 0xD1, -+0x49, 0x46, 0x04, 0xF1, 0x11, 0x00, 0x0A, 0xF0, 0x97, 0xF9, 0x00, 0x28, 0xEB, 0xD1, 0x94, 0xF9, 0x44, 0x50, 0x04, 0xF1, -+0x08, 0x08, 0x40, 0x34, 0xB4, 0x42, 0xE7, 0xD1, 0x40, 0x46, 0xBD, 0xE8, 0xF8, 0x83, 0x98, 0x46, 0x40, 0x46, 0xBD, 0xE8, -+0xF8, 0x83, 0x00, 0xBF, 0xA8, 0xBA, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x41, 0xF2, 0x0B, 0x03, 0xC2, 0x4D, 0xE9, 0x5C, -+0x2E, 0x68, 0x01, 0x29, 0x82, 0xB0, 0x00, 0xF2, 0xB8, 0x81, 0x96, 0xF8, 0x6F, 0x01, 0x00, 0x27, 0x00, 0x28, 0x00, 0xF0, -+0x57, 0x81, 0x33, 0x46, 0x00, 0x24, 0x03, 0xE0, 0x01, 0x34, 0x84, 0x42, 0x00, 0xF0, 0x50, 0x81, 0x9A, 0x78, 0x8A, 0x42, -+0x03, 0xF1, 0x06, 0x03, 0xF6, 0xD1, 0x17, 0xB1, 0x41, 0xF2, 0x0B, 0x03, 0xE9, 0x54, 0x4F, 0xF4, 0xBA, 0x73, 0x02, 0x21, -+0x04, 0x22, 0x4F, 0xF4, 0x00, 0x60, 0xF5, 0xF7, 0x03, 0xFE, 0x96, 0xF8, 0x6E, 0x31, 0x80, 0xF8, 0x6E, 0x31, 0x07, 0x46, -+0xD6, 0xE9, 0x58, 0x01, 0xC7, 0xF8, 0x60, 0x01, 0xA7, 0xF8, 0x64, 0x11, 0x96, 0xF8, 0x70, 0x01, 0x87, 0xF8, 0x70, 0x01, -+0x96, 0xF8, 0x71, 0x31, 0x87, 0xF8, 0x71, 0x31, 0x96, 0xF8, 0x6F, 0x31, 0x9C, 0x42, 0x80, 0xF2, 0x79, 0x81, 0x41, 0xF2, -+0x0B, 0x02, 0x04, 0xEB, 0x44, 0x04, 0x06, 0x21, 0x15, 0xF8, 0x02, 0x80, 0x06, 0xEB, 0x44, 0x04, 0x11, 0xFB, 0x03, 0x61, -+0xA3, 0x78, 0x43, 0x45, 0x10, 0xD1, 0x97, 0xF8, 0x6F, 0x31, 0xD4, 0xF8, 0x00, 0xC0, 0x03, 0xEB, 0x43, 0x02, 0x01, 0x33, -+0x47, 0xF8, 0x12, 0xC0, 0x07, 0xEB, 0x42, 0x02, 0xB4, 0xF8, 0x04, 0xC0, 0xA2, 0xF8, 0x04, 0xC0, 0x87, 0xF8, 0x6F, 0x31, -+0x06, 0x34, 0xA1, 0x42, 0xE8, 0xD1, 0xF0, 0xB1, 0x4F, 0xF0, 0x21, 0x0A, 0xFC, 0x21, 0x1A, 0xFB, 0x00, 0x1A, 0x73, 0x18, -+0x03, 0xF1, 0x20, 0x09, 0x7A, 0x18, 0xD3, 0xF8, 0x00, 0xC0, 0x5C, 0x68, 0x98, 0x68, 0xD3, 0xF8, 0x0C, 0xE0, 0xC2, 0xF8, -+0x0C, 0xE0, 0x10, 0x33, 0x4B, 0x45, 0xC2, 0xF8, 0x00, 0xC0, 0x54, 0x60, 0x90, 0x60, 0x02, 0xF1, 0x10, 0x02, 0xEE, 0xD1, -+0x21, 0x31, 0x1B, 0x78, 0x13, 0x70, 0x51, 0x45, 0xE5, 0xD1, 0x2B, 0x68, 0xDF, 0xF8, 0x2C, 0xC2, 0xB3, 0xF8, 0x6C, 0x91, -+0x81, 0x4C, 0xB9, 0xF1, 0xC9, 0x0F, 0x28, 0xBF, 0x4F, 0xF0, 0x00, 0x09, 0xB8, 0xF1, 0x01, 0x0F, 0x66, 0x46, 0x00, 0xF0, -+0xE5, 0x80, 0x93, 0xF8, 0x71, 0x21, 0x7C, 0x4B, 0x00, 0x2A, 0xA3, 0xF1, 0x04, 0x02, 0x0A, 0xBF, 0x13, 0x46, 0x4F, 0xF0, -+0x08, 0x0E, 0x4F, 0xF0, 0x0C, 0x0E, 0x78, 0x4A, 0x01, 0x20, 0x08, 0x21, 0x10, 0x75, 0x15, 0x32, 0x61, 0x70, 0x58, 0x18, -+0x13, 0xF8, 0x01, 0x1B, 0x02, 0xF8, 0x01, 0x1F, 0x98, 0x42, 0xF9, 0xD1, 0x72, 0x4B, 0x01, 0x93, 0xB9, 0xF1, 0x00, 0x0F, -+0x40, 0xF0, 0x99, 0x80, 0xBE, 0xF1, 0x08, 0x0F, 0x19, 0xD0, 0x01, 0x9B, 0x6E, 0x4A, 0x58, 0x1C, 0x32, 0x21, 0x01, 0x90, -+0x19, 0x70, 0x01, 0x9B, 0xAE, 0xF1, 0x08, 0x0E, 0x59, 0x1C, 0x5F, 0xFA, 0x8E, 0xFE, 0x01, 0x91, 0x83, 0xF8, 0x00, 0xE0, -+0x01, 0x9B, 0x18, 0x1D, 0x12, 0xF8, 0x01, 0x1B, 0x03, 0xF8, 0x01, 0x1B, 0x98, 0x42, 0xF9, 0xD1, 0x01, 0x9B, 0x73, 0x44, -+0x01, 0x93, 0x41, 0xF2, 0x0B, 0x03, 0xEB, 0x5C, 0x63, 0xB9, 0x01, 0x9B, 0x03, 0x22, 0x59, 0x1C, 0x01, 0x91, 0x1A, 0x70, -+0x01, 0x9B, 0x01, 0x22, 0x59, 0x1C, 0x01, 0x91, 0x1A, 0x70, 0x01, 0x9B, 0x13, 0x44, 0x01, 0x93, 0xB9, 0xF1, 0x00, 0x0F, -+0x36, 0xD1, 0xDF, 0xF8, 0x7C, 0x81, 0x98, 0xF8, 0x76, 0x31, 0xD8, 0x07, 0x06, 0xD5, 0x56, 0x4B, 0x01, 0xA8, 0xD3, 0xF8, -+0x48, 0x31, 0x98, 0x47, 0x98, 0xF8, 0x76, 0x31, 0x41, 0xF2, 0x0B, 0x02, 0xAA, 0x5C, 0x01, 0x2A, 0x4A, 0xD0, 0x5D, 0x07, -+0x04, 0xD5, 0x4F, 0x4B, 0x01, 0xA8, 0xD3, 0xF8, 0x44, 0x31, 0x98, 0x47, 0x4D, 0x4D, 0x01, 0x98, 0x29, 0x46, 0x31, 0xF8, -+0x03, 0x2B, 0x0A, 0xF0, 0xB1, 0xF8, 0x4B, 0x4A, 0x01, 0x99, 0x12, 0x68, 0x2B, 0x88, 0xB2, 0xF9, 0x00, 0x20, 0x0B, 0x44, -+0x00, 0x2A, 0x01, 0x93, 0xA3, 0xEB, 0x04, 0x03, 0x5D, 0xDB, 0x00, 0x22, 0xA7, 0xF8, 0x6C, 0x31, 0xC7, 0xF8, 0x68, 0x21, -+0x38, 0x46, 0xF5, 0xF7, 0x45, 0xFD, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x32, 0x78, 0x3B, 0x2A, 0x60, 0xD0, 0xDF, 0xF8, -+0x08, 0x81, 0x98, 0xF8, 0x76, 0x31, 0xD9, 0x07, 0x58, 0xD5, 0x39, 0x4B, 0x01, 0xA8, 0xD3, 0xF8, 0x48, 0x31, 0x98, 0x47, -+0xB9, 0xF1, 0x00, 0x0F, 0xC2, 0xD0, 0x01, 0x99, 0x32, 0x78, 0x0B, 0x46, 0x76, 0x1A, 0x49, 0x44, 0x00, 0xE0, 0xF2, 0x5C, -+0x03, 0xF8, 0x01, 0x2B, 0x99, 0x42, 0xFA, 0xD1, 0x01, 0x9A, 0x98, 0xF8, 0x76, 0x31, 0x4A, 0x44, 0x01, 0x92, 0x41, 0xF2, -+0x0B, 0x02, 0xAA, 0x5C, 0x01, 0x2A, 0xB4, 0xD1, 0x9E, 0x07, 0xB2, 0xD5, 0x29, 0x4B, 0x00, 0x21, 0xD3, 0xF8, 0x50, 0x31, -+0x01, 0xA8, 0x98, 0x47, 0x98, 0xF8, 0x76, 0x31, 0xA9, 0xE7, 0x9C, 0xF8, 0x00, 0x20, 0x0A, 0x2A, 0x7F, 0xF4, 0x62, 0xAF, -+0x9C, 0xF8, 0x01, 0x60, 0x02, 0x36, 0x16, 0xF0, 0xFF, 0x06, 0x09, 0xD0, 0x22, 0x49, 0x98, 0x19, 0x01, 0xE0, 0x11, 0xF8, -+0x01, 0x2F, 0x03, 0xF8, 0x01, 0x2B, 0x83, 0x42, 0xF9, 0xD1, 0x01, 0x9B, 0x33, 0x44, 0xA9, 0xEB, 0x06, 0x09, 0x01, 0x93, -+0x1F, 0xFA, 0x89, 0xF9, 0x66, 0x44, 0x49, 0xE7, 0x01, 0x27, 0xB9, 0x42, 0x53, 0xD0, 0x39, 0x46, 0xA0, 0xE6, 0xB3, 0xF5, -+0x96, 0x7F, 0x9E, 0xD9, 0x16, 0x49, 0x17, 0x48, 0xB4, 0x22, 0xF7, 0xF7, 0x99, 0xFD, 0x01, 0x9B, 0x1B, 0x1B, 0x96, 0xE7, -+0x0A, 0x4B, 0x4F, 0xF0, 0x08, 0x0E, 0x22, 0xE7, 0x01, 0x99, 0xAE, 0xE7, 0x70, 0x78, 0x01, 0x99, 0x02, 0x30, 0x10, 0xF0, -+0xFF, 0x00, 0x42, 0xD0, 0x0B, 0x46, 0xA6, 0xEB, 0x03, 0x0C, 0x01, 0x44, 0x1C, 0xE0, 0x00, 0xBF, 0xA8, 0xBA, 0x17, 0x00, -+0xE8, 0x61, 0x18, 0x00, 0xB8, 0xB2, 0x15, 0x00, 0xD4, 0x61, 0x18, 0x00, 0xF2, 0x61, 0x18, 0x00, 0xBC, 0xB2, 0x15, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x68, 0xCB, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x18, 0x63, 0x18, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x9C, 0xBF, 0x15, 0x00, 0xE4, 0xB8, 0x17, 0x00, 0x1C, 0xF8, 0x03, 0x20, 0x03, 0xF8, 0x01, 0x2B, 0x99, 0x42, 0xF9, 0xD1, -+0xDF, 0xF8, 0x48, 0x80, 0x01, 0x9B, 0x98, 0xF8, 0x76, 0x21, 0x03, 0x44, 0xA9, 0xEB, 0x00, 0x09, 0x01, 0x93, 0xD3, 0x07, -+0x1F, 0xFA, 0x89, 0xF9, 0x06, 0x44, 0x7F, 0xF5, 0x6F, 0xAF, 0x68, 0xE7, 0x41, 0xF2, 0x0B, 0x03, 0x15, 0xF8, 0x03, 0x80, -+0xA3, 0xE6, 0x41, 0xF2, 0x0B, 0x03, 0x02, 0x22, 0xEA, 0x54, 0x00, 0x20, 0xFF, 0xF7, 0xDE, 0xF8, 0x4F, 0xE7, 0xDF, 0xF8, -+0x10, 0x80, 0x98, 0xF8, 0x76, 0x31, 0xDB, 0x07, 0x3F, 0xF5, 0x55, 0xAF, 0x5D, 0xE7, 0x00, 0xBF, 0xE4, 0xB8, 0x17, 0x00, -+0xF0, 0xB5, 0x4C, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x83, 0xB0, 0x04, 0xD1, 0x4A, 0x4A, 0x13, 0x68, 0x23, 0xF4, -+0x00, 0x13, 0x13, 0x60, 0x48, 0x4C, 0x49, 0x4D, 0x23, 0x68, 0x5B, 0x07, 0x4E, 0xD4, 0x48, 0x4E, 0x41, 0xF2, 0x0A, 0x03, -+0xEB, 0x5C, 0x5B, 0xB9, 0x44, 0x4A, 0x19, 0x46, 0x02, 0xF5, 0x80, 0x54, 0x80, 0x20, 0x11, 0x72, 0x82, 0xF8, 0x44, 0x00, -+0x40, 0x32, 0x94, 0x42, 0xF9, 0xD1, 0xA9, 0x80, 0x29, 0x68, 0x91, 0xF8, 0x70, 0x21, 0x01, 0x2A, 0x5F, 0xD0, 0x00, 0x24, -+0x20, 0x46, 0x41, 0xF2, 0x3A, 0x02, 0xA8, 0x54, 0x91, 0xF8, 0x6E, 0x21, 0x91, 0xF8, 0x6F, 0x11, 0x08, 0x20, 0xCD, 0xE9, -+0x00, 0x41, 0x38, 0x49, 0xF7, 0xF7, 0xDC, 0xFA, 0x41, 0xF2, 0x0A, 0x03, 0xEB, 0x5C, 0x83, 0xB9, 0x35, 0x49, 0x36, 0x4A, -+0x0B, 0x68, 0x36, 0x48, 0x43, 0xF0, 0x04, 0x03, 0x0B, 0x60, 0x13, 0x68, 0x03, 0x80, 0x13, 0x68, 0x1B, 0x0C, 0x1B, 0x04, -+0x43, 0xF4, 0xBB, 0x63, 0x43, 0xF0, 0x04, 0x03, 0x13, 0x60, 0x73, 0x68, 0x01, 0x21, 0x43, 0xF0, 0x20, 0x03, 0x04, 0x20, -+0x73, 0x60, 0xF5, 0xF7, 0x01, 0xFE, 0x2B, 0x68, 0xD3, 0xF8, 0x68, 0x11, 0x19, 0xB1, 0xB3, 0xF8, 0x6C, 0x21, 0xC8, 0x2A, -+0x23, 0xD9, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x40, 0xFF, 0xF7, 0xCE, 0xBD, 0x2B, 0x68, 0x25, 0x4A, 0x93, 0xF8, 0x6E, 0x31, -+0x24, 0x49, 0x1E, 0x4E, 0x10, 0x68, 0x24, 0x4A, 0xC0, 0x8E, 0x4F, 0xF4, 0xA4, 0x67, 0x07, 0xFB, 0x03, 0x13, 0x03, 0x21, -+0x71, 0x77, 0x11, 0x69, 0x20, 0x4A, 0x73, 0x61, 0x01, 0x44, 0xD2, 0xF8, 0xE0, 0x31, 0x06, 0xF1, 0x0C, 0x00, 0x98, 0x47, -+0x01, 0x23, 0x33, 0x77, 0x23, 0x68, 0x23, 0xF0, 0x04, 0x03, 0x23, 0x60, 0x92, 0xE7, 0x1A, 0x48, 0x09, 0xF0, 0x60, 0xFF, -+0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x40, 0xFF, 0xF7, 0xA7, 0xBD, 0x91, 0xF8, 0xFC, 0x20, 0x07, 0x2A, 0x9B, 0xD1, 0x01, 0xF1, -+0xFD, 0x00, 0x14, 0x49, 0x09, 0xF0, 0x22, 0xFF, 0x41, 0xF2, 0x0A, 0x03, 0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0xEB, 0x5C, -+0x29, 0x68, 0x04, 0x46, 0x8F, 0xE7, 0x00, 0xBF, 0x74, 0x36, 0x17, 0x00, 0x6C, 0x00, 0x32, 0x40, 0x4C, 0x00, 0x32, 0x40, -+0xA8, 0xBA, 0x17, 0x00, 0x1C, 0x9E, 0x17, 0x00, 0xCC, 0xBF, 0x15, 0x00, 0x94, 0x40, 0x04, 0x40, 0x20, 0x04, 0x32, 0x40, -+0x28, 0x25, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, -+0x18, 0x63, 0x18, 0x00, 0x54, 0xBF, 0x15, 0x00, 0x00, 0x22, 0x02, 0x81, 0xE7, 0xF7, 0xE0, 0xBA, 0x2D, 0xE9, 0xF0, 0x41, -+0x14, 0x46, 0x52, 0x78, 0x00, 0x2B, 0x18, 0xBF, 0x02, 0x23, 0x52, 0x06, 0x44, 0xBF, 0x08, 0x33, 0xDB, 0xB2, 0x23, 0x44, -+0x06, 0x46, 0x9A, 0x7F, 0x08, 0x2A, 0x0D, 0x46, 0x03, 0xD0, 0x00, 0x27, 0x38, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0xDA, 0x7F, -+0x06, 0x2A, 0xF8, 0xD1, 0x93, 0xF8, 0x26, 0x70, 0x00, 0x2F, 0xF4, 0xD1, 0x93, 0xF8, 0x27, 0x80, 0xB8, 0xF1, 0x01, 0x0F, -+0x07, 0xD0, 0xB8, 0xF1, 0x02, 0x0F, 0xED, 0xD1, 0x13, 0x49, 0x80, 0x20, 0xF7, 0xF7, 0x2E, 0xFA, 0xE8, 0xE7, 0x93, 0xF8, -+0x3A, 0x70, 0x93, 0xF8, 0x3B, 0xC0, 0x93, 0xF8, 0x38, 0x00, 0x93, 0xF8, 0x39, 0x20, 0x0B, 0x68, 0x0D, 0x49, 0x3F, 0x04, -+0x47, 0xEA, 0x0C, 0x67, 0x07, 0x43, 0x47, 0xEA, 0x02, 0x27, 0x3A, 0x46, 0x80, 0x20, 0xF7, 0xF7, 0x19, 0xFA, 0x2B, 0x68, -+0x9F, 0x42, 0x01, 0xD0, 0x47, 0x46, 0xCF, 0xE7, 0x06, 0x4B, 0x30, 0x78, 0x9B, 0x69, 0x22, 0x46, 0x04, 0xF1, 0x10, 0x01, -+0x47, 0x46, 0x98, 0x47, 0xC6, 0xE7, 0x00, 0xBF, 0x08, 0xC0, 0x15, 0x00, 0xE8, 0xBF, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xF8, 0xB5, 0x21, 0x4B, 0x21, 0x4D, 0x1E, 0x68, 0x95, 0xF8, 0x44, 0x40, 0xB6, 0xF9, 0x00, 0x70, 0x1F, 0x4B, 0x04, 0xEB, -+0x84, 0x06, 0x00, 0x2F, 0x8E, 0x46, 0x03, 0xEB, 0x06, 0x16, 0x23, 0xDB, 0xA7, 0x00, 0x07, 0xEB, 0x04, 0x0C, 0x03, 0xEB, -+0x0C, 0x1C, 0xCC, 0xF8, 0x0C, 0x00, 0x10, 0xB1, 0x01, 0x7C, 0x8C, 0xF8, 0x10, 0x10, 0x3C, 0x44, 0x03, 0xEB, 0x04, 0x13, -+0x31, 0x46, 0x5A, 0x64, 0xA3, 0xF8, 0x4C, 0xE0, 0x13, 0x48, 0xF5, 0xF7, 0xB5, 0xFF, 0x95, 0xF8, 0x44, 0x20, 0x12, 0x4B, -+0x01, 0x32, 0xA3, 0xFB, 0x02, 0x13, 0xDB, 0x09, 0x03, 0xEB, 0x43, 0x03, 0xA2, 0xEB, 0x83, 0x13, 0x85, 0xF8, 0x44, 0x30, -+0x30, 0x46, 0xF8, 0xBD, 0x04, 0xEB, 0x84, 0x01, 0x03, 0xEB, 0x01, 0x11, 0xA7, 0x00, 0xB1, 0xF8, 0x4C, 0x10, 0x00, 0x29, -+0xD3, 0xD0, 0x08, 0x49, 0x08, 0x48, 0xC6, 0x22, 0xF7, 0xF7, 0xBA, 0xFB, 0x00, 0x26, 0xED, 0xE7, 0x38, 0x36, 0x17, 0x00, -+0xB0, 0xDE, 0x17, 0x00, 0xE0, 0x63, 0x18, 0x00, 0xE8, 0xDE, 0x17, 0x00, 0xAB, 0xAA, 0xAA, 0xAA, 0x70, 0x79, 0x15, 0x00, -+0x14, 0xC0, 0x15, 0x00, 0x70, 0xB5, 0x0C, 0x4D, 0x42, 0x69, 0x04, 0x46, 0x04, 0x21, 0x00, 0x20, 0xFF, 0xF7, 0xA6, 0xFF, -+0x21, 0x46, 0x28, 0x46, 0xF5, 0xF7, 0xCC, 0xFF, 0xA5, 0xF1, 0x08, 0x00, 0x21, 0x46, 0xF5, 0xF7, 0x77, 0xFF, 0x05, 0x4B, -+0xA5, 0xF1, 0x20, 0x00, 0xD3, 0xF8, 0x38, 0x31, 0xBD, 0xE8, 0x70, 0x40, 0x18, 0x47, 0x00, 0xBF, 0x08, 0xDF, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0xB3, 0x4B, 0x01, 0xF0, 0x7C, 0x04, 0x1A, 0x7A, 0x04, 0x3C, 0x00, 0xEB, -+0x02, 0x0C, 0x01, 0xF4, 0x80, 0x6E, 0x18, 0x2C, 0x0E, 0xD8, 0xDF, 0xE8, 0x04, 0xF0, 0x54, 0x0D, 0x0D, 0x0D, 0x58, 0x0D, -+0x0D, 0x0D, 0x8D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0xB5, 0x00, -+0x00, 0x24, 0xA7, 0x4D, 0x2D, 0x68, 0x2D, 0x78, 0xAD, 0x07, 0x03, 0xD5, 0x01, 0xF0, 0x3C, 0x01, 0x3C, 0x29, 0x02, 0xD0, -+0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x87, 0xBE, 0xF1, 0x00, 0x0F, 0x00, 0xF0, 0xD1, 0x80, 0xBC, 0xF8, 0x02, 0x10, 0x9E, 0x7A, -+0x9E, 0x4C, 0x8D, 0x0B, 0x4F, 0xF4, 0xA4, 0x61, 0xC5, 0xEB, 0x05, 0x17, 0x01, 0xFB, 0x06, 0xF1, 0x01, 0xEB, 0xC7, 0x01, -+0x21, 0x44, 0x2F, 0x01, 0x91, 0xF8, 0x3B, 0xE2, 0xBE, 0xF1, 0x00, 0x0F, 0x00, 0xF0, 0xCC, 0x80, 0x91, 0xF8, 0x38, 0x12, -+0x01, 0x29, 0x00, 0xF0, 0xEB, 0x80, 0x02, 0x29, 0x00, 0xF0, 0xC1, 0x80, 0x0A, 0x1F, 0x01, 0x2A, 0x40, 0xF2, 0xBD, 0x80, -+0x1A, 0x7A, 0x04, 0x32, 0x1A, 0x72, 0xDC, 0xF8, 0x00, 0x00, 0xC1, 0x17, 0xC3, 0xE9, 0x04, 0x01, 0x4F, 0xF4, 0xA4, 0x62, -+0x02, 0xFB, 0x06, 0xF2, 0x79, 0x1B, 0x02, 0xF5, 0xEC, 0x72, 0x02, 0xEB, 0xC1, 0x02, 0x22, 0x44, 0x1A, 0x62, 0x01, 0x24, -+0xC2, 0xE7, 0x14, 0x1D, 0x1C, 0x72, 0x01, 0x24, 0xB5, 0xE7, 0x02, 0xF1, 0x08, 0x04, 0x1C, 0x72, 0x30, 0xF8, 0x02, 0x80, -+0xBC, 0xF8, 0x06, 0x40, 0x9C, 0xF8, 0x02, 0xA0, 0x93, 0xF8, 0x30, 0x90, 0x4F, 0xEA, 0x08, 0x28, 0x1F, 0xFA, 0x88, 0xF8, -+0x46, 0x46, 0xF7, 0x17, 0x44, 0xEA, 0x07, 0x06, 0xBC, 0xF8, 0x04, 0x40, 0x4A, 0xEA, 0x04, 0x44, 0x44, 0xEA, 0x08, 0x04, -+0x49, 0xF0, 0x03, 0x09, 0xC3, 0xE9, 0x04, 0x46, 0x83, 0xF8, 0x30, 0x90, 0xBE, 0xF1, 0x00, 0x0F, 0x5F, 0xD0, 0x9E, 0x7A, -+0xBC, 0xF8, 0x02, 0x50, 0x4F, 0xF4, 0xA4, 0x64, 0x04, 0xFB, 0x06, 0xF4, 0xAD, 0x0B, 0x6E, 0x4E, 0x04, 0xF5, 0xEC, 0x74, -+0xC5, 0xEB, 0x05, 0x15, 0x04, 0xEB, 0xC5, 0x04, 0x34, 0x44, 0x1C, 0x62, 0x01, 0x24, 0x80, 0xE7, 0xBE, 0xF1, 0x00, 0x0F, -+0x50, 0xD0, 0x9E, 0x7A, 0xBC, 0xF8, 0x02, 0x50, 0x4F, 0xF4, 0xA4, 0x64, 0x04, 0xFB, 0x06, 0xF4, 0xAD, 0x0B, 0x63, 0x4E, -+0x04, 0xF5, 0xEC, 0x74, 0xC5, 0xEB, 0x05, 0x15, 0x04, 0xEB, 0xC5, 0x04, 0x34, 0x44, 0x02, 0xF1, 0x08, 0x05, 0x1D, 0x72, -+0xBC, 0xF8, 0x04, 0x60, 0x93, 0xF8, 0x30, 0x80, 0x1C, 0x62, 0x84, 0x5A, 0xBC, 0xF8, 0x06, 0x50, 0x5D, 0x61, 0x44, 0xEA, -+0x06, 0x44, 0x48, 0xF0, 0x02, 0x05, 0x1C, 0x61, 0x83, 0xF8, 0x30, 0x50, 0x01, 0x24, 0x58, 0xE7, 0xBE, 0xF1, 0x00, 0x0F, -+0x2F, 0xD0, 0x9E, 0x7A, 0xBC, 0xF8, 0x02, 0x50, 0x4F, 0xF4, 0xA4, 0x64, 0x04, 0xFB, 0x06, 0xF4, 0xAD, 0x0B, 0x4F, 0x4E, -+0x04, 0xF5, 0xEC, 0x74, 0xC5, 0xEB, 0x05, 0x15, 0x04, 0xEB, 0xC5, 0x04, 0x34, 0x44, 0x02, 0xF1, 0x12, 0x05, 0x66, 0x46, -+0x1D, 0x72, 0x56, 0xF8, 0x02, 0x7F, 0x93, 0xF8, 0x30, 0x50, 0x76, 0x68, 0x1C, 0x62, 0x45, 0xF0, 0x02, 0x04, 0x83, 0xF8, -+0x30, 0x40, 0xC3, 0xE9, 0x04, 0x76, 0x01, 0x24, 0x33, 0xE7, 0x5C, 0x7A, 0x42, 0x4D, 0x4F, 0xF4, 0x1E, 0x76, 0x06, 0xFB, -+0x04, 0x54, 0xA8, 0xE7, 0x5C, 0x7A, 0x3F, 0x4D, 0x4F, 0xF4, 0x1E, 0x76, 0x06, 0xFB, 0x04, 0x54, 0xB7, 0xE7, 0x5C, 0x7A, -+0x3B, 0x4D, 0x4F, 0xF4, 0x1E, 0x76, 0x06, 0xFB, 0x04, 0x54, 0xD8, 0xE7, 0x59, 0x7A, 0x39, 0x4D, 0x4F, 0xF4, 0x1E, 0x74, -+0x04, 0xFB, 0x01, 0xF4, 0x29, 0x19, 0x91, 0xF8, 0x98, 0x10, 0x01, 0x29, 0x43, 0xD0, 0x02, 0x29, 0x04, 0xD1, 0x34, 0x48, -+0xF7, 0xF7, 0x36, 0xF8, 0x00, 0x24, 0x15, 0xE7, 0x0A, 0x1F, 0x01, 0x2A, 0xF7, 0xD9, 0x18, 0x7A, 0xBC, 0xF8, 0x02, 0x10, -+0x9D, 0x7A, 0x2B, 0x4E, 0x04, 0x30, 0x18, 0x72, 0xDC, 0xF8, 0x00, 0x40, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x05, 0xF2, -+0x89, 0x0B, 0xE5, 0x17, 0xC1, 0xEB, 0x01, 0x11, 0x02, 0xF5, 0xEC, 0x72, 0xC3, 0xE9, 0x04, 0x45, 0x02, 0xEB, 0xC1, 0x02, -+0x32, 0x44, 0x92, 0xF8, 0x63, 0x10, 0x00, 0x29, 0xDE, 0xD0, 0x1A, 0x62, 0x01, 0x24, 0xF3, 0xE6, 0x19, 0x7A, 0x93, 0xF8, -+0x30, 0xE0, 0x08, 0x31, 0x19, 0x72, 0x82, 0x5A, 0x9C, 0xF8, 0x02, 0x80, 0xBC, 0xF8, 0x04, 0x00, 0xBC, 0xF8, 0x06, 0x90, -+0x12, 0x02, 0x92, 0xB2, 0xD1, 0x17, 0x48, 0xEA, 0x00, 0x40, 0x49, 0xEA, 0x01, 0x09, 0x02, 0x43, 0x4E, 0xF0, 0x03, 0x0E, -+0xC3, 0xE9, 0x04, 0x29, 0x83, 0xF8, 0x30, 0xE0, 0x08, 0xE7, 0x19, 0x7A, 0x93, 0xF8, 0x30, 0x70, 0x08, 0x31, 0x19, 0x72, -+0x81, 0x5A, 0xBC, 0xF8, 0x04, 0x80, 0x9C, 0xF8, 0x02, 0x00, 0xBC, 0xF8, 0x06, 0x60, 0x09, 0x02, 0x89, 0xB2, 0x04, 0xF1, -+0x38, 0x02, 0x40, 0xEA, 0x08, 0x44, 0x0C, 0x43, 0xC9, 0x17, 0x47, 0xF0, 0x03, 0x07, 0x0E, 0x43, 0xC3, 0xE9, 0x04, 0x46, -+0x2A, 0x44, 0x83, 0xF8, 0x30, 0x70, 0xC0, 0xE7, 0xB0, 0xDE, 0x17, 0x00, 0x34, 0x36, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, -+0xA0, 0x65, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x34, 0xC0, 0x15, 0x00, 0x70, 0xB5, 0x18, 0x4E, 0x18, 0x4A, 0xB3, 0x7A, -+0x75, 0x7A, 0x12, 0x7C, 0x1B, 0x02, 0x43, 0xEA, 0x05, 0x43, 0xF5, 0x7A, 0x04, 0x46, 0x00, 0x6E, 0x43, 0xEA, 0x05, 0x63, -+0xFF, 0x2A, 0x0D, 0x46, 0x43, 0xEA, 0x00, 0x03, 0x17, 0xD0, 0x41, 0xF0, 0x80, 0x05, 0x43, 0xF0, 0x80, 0x03, 0xEA, 0x07, -+0x48, 0xBF, 0x43, 0xF0, 0x40, 0x03, 0x0D, 0x4A, 0x58, 0xBF, 0x23, 0xF0, 0x40, 0x03, 0x23, 0x66, 0x20, 0x46, 0xD2, 0xF8, -+0xA8, 0x32, 0x98, 0x47, 0x32, 0x6C, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xFF, 0xF7, 0xEF, 0xBD, 0x29, 0x06, -+0x58, 0xBF, 0x23, 0xF0, 0x80, 0x03, 0xE6, 0xD5, 0xE3, 0xE7, 0x00, 0xBF, 0xB0, 0xDE, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0xF8, 0xB5, 0x21, 0x4B, 0x21, 0x4E, 0x1B, 0x7C, 0xFF, 0x2B, 0x04, 0x46, 0x0D, 0x46, 0x21, 0xD0, -+0xB2, 0x7A, 0xFF, 0x2A, 0x32, 0xD0, 0x01, 0xF0, 0x01, 0x01, 0x45, 0xF0, 0x80, 0x05, 0x77, 0x7A, 0x20, 0x6E, 0x13, 0x02, -+0x43, 0xEA, 0x07, 0x43, 0x03, 0x43, 0x43, 0xF0, 0x82, 0x03, 0x11, 0xB3, 0x43, 0xF0, 0x40, 0x03, 0x16, 0x49, 0x23, 0x66, -+0x00, 0x22, 0xD1, 0xF8, 0xA8, 0x32, 0x86, 0xF8, 0x32, 0x20, 0x20, 0x46, 0x98, 0x47, 0x32, 0x6C, 0x29, 0x46, 0x20, 0x46, -+0xBD, 0xE8, 0xF8, 0x40, 0xFF, 0xF7, 0xB8, 0xBD, 0xB3, 0x7A, 0x71, 0x7A, 0x02, 0x6E, 0x1B, 0x02, 0x43, 0xEA, 0x01, 0x43, -+0x13, 0x43, 0x2A, 0x06, 0x0D, 0xD4, 0x23, 0xF0, 0x80, 0x03, 0x05, 0xF0, 0x01, 0x01, 0x43, 0xF0, 0x02, 0x03, 0x00, 0x29, -+0xDC, 0xD1, 0x23, 0xF0, 0x40, 0x03, 0xDB, 0xE7, 0x00, 0x21, 0x80, 0x25, 0xCD, 0xE7, 0x05, 0xF0, 0x01, 0x01, 0xD0, 0xE7, -+0x00, 0x88, 0x17, 0x00, 0xB0, 0xDE, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x32, 0x4B, 0x01, 0x88, 0x70, 0xB4, 0x19, 0x80, -+0xC2, 0x8A, 0x5A, 0x80, 0x01, 0xF0, 0x88, 0x06, 0xC2, 0xF3, 0x0B, 0x14, 0x00, 0x25, 0x02, 0xF0, 0x0F, 0x02, 0x88, 0x2E, -+0x9C, 0x80, 0x9A, 0x71, 0x8C, 0xB2, 0x83, 0xF8, 0x30, 0x50, 0x45, 0xD0, 0xDD, 0x71, 0x04, 0xF4, 0x40, 0x72, 0xB2, 0xF5, -+0x40, 0x7F, 0x04, 0xF0, 0xFC, 0x05, 0x0C, 0xBF, 0x1E, 0x22, 0x18, 0x22, 0x88, 0x2D, 0x08, 0xBF, 0x02, 0x32, 0x0E, 0x04, -+0x44, 0xBF, 0x04, 0x32, 0xD2, 0xB2, 0x1A, 0x72, 0x02, 0x79, 0xD5, 0x07, 0x44, 0xBF, 0x08, 0x22, 0x83, 0xF8, 0x30, 0x20, -+0xE4, 0x05, 0x12, 0xD5, 0x02, 0x8A, 0x9A, 0x84, 0x42, 0x8A, 0xDA, 0x84, 0x82, 0x8A, 0x1A, 0x85, 0x02, 0x88, 0x91, 0x05, -+0x12, 0xD5, 0xD2, 0x05, 0x18, 0xD5, 0x02, 0x8B, 0x5A, 0x85, 0x42, 0x8B, 0x9A, 0x85, 0x82, 0x8B, 0xDA, 0x85, 0x70, 0xBC, -+0x70, 0x47, 0x82, 0x88, 0x9A, 0x84, 0xC2, 0x88, 0xDA, 0x84, 0x02, 0x89, 0x1A, 0x85, 0x02, 0x88, 0x91, 0x05, 0xEC, 0xD4, -+0x42, 0x89, 0x5A, 0x85, 0x82, 0x89, 0x9A, 0x85, 0xC2, 0x89, 0xDA, 0x85, 0x70, 0xBC, 0x70, 0x47, 0x02, 0x8A, 0x5A, 0x85, -+0x42, 0x8A, 0x9A, 0x85, 0x82, 0x8A, 0xDA, 0x85, 0x70, 0xBC, 0x70, 0x47, 0x04, 0xF4, 0x40, 0x72, 0xB2, 0xF5, 0x40, 0x7F, -+0x0C, 0xBF, 0xC5, 0x8B, 0x05, 0x8B, 0x05, 0xF0, 0x07, 0x05, 0xDD, 0x71, 0xB1, 0xE7, 0x00, 0xBF, 0xB0, 0xDE, 0x17, 0x00, -+0xF8, 0xB5, 0x05, 0x22, 0x18, 0x23, 0x0C, 0x21, 0x41, 0xF2, 0x06, 0x40, 0xF5, 0xF7, 0x74, 0xF8, 0x0F, 0x4A, 0x03, 0x46, -+0x51, 0x7A, 0x0F, 0x48, 0x94, 0x69, 0x4F, 0xF4, 0x1E, 0x75, 0x05, 0xFB, 0x01, 0x01, 0xD2, 0xE9, 0x04, 0x67, 0x51, 0xF8, -+0x26, 0x0F, 0x89, 0x88, 0x99, 0x80, 0xC3, 0xE9, 0x02, 0x67, 0x18, 0x60, 0x91, 0x7A, 0x99, 0x74, 0xC4, 0xF3, 0x80, 0x24, -+0x1C, 0x74, 0x12, 0x6A, 0x92, 0xF8, 0x61, 0x20, 0x5A, 0x74, 0x18, 0x46, 0xBD, 0xE8, 0xF8, 0x40, 0xF5, 0xF7, 0x84, 0xB8, -+0xB0, 0xDE, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0x3C, 0x82, 0xD8, 0xF8, 0x00, 0x40, -+0x27, 0x78, 0x87, 0xB0, 0x17, 0xF0, 0x01, 0x07, 0x04, 0x46, 0x03, 0x93, 0x08, 0xD0, 0x43, 0x6D, 0x03, 0xF0, 0x07, 0x03, -+0x02, 0x2B, 0x7F, 0xD0, 0x38, 0x46, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x80, 0x4D, 0x89, 0x46, 0x00, 0x2A, 0x40, 0xF0, -+0xA2, 0x80, 0x02, 0x8E, 0x2B, 0x7A, 0xC6, 0x69, 0xD4, 0x1A, 0x03, 0x9A, 0xA4, 0xB2, 0x10, 0x31, 0x12, 0xB1, 0x07, 0x2C, -+0x40, 0xF2, 0xA9, 0x80, 0x08, 0x22, 0x48, 0x46, 0xFA, 0xF7, 0x92, 0xFF, 0x29, 0x7A, 0x8A, 0xB2, 0xD6, 0xE9, 0x02, 0x03, -+0x08, 0x3C, 0x01, 0x33, 0xA5, 0xB2, 0x1C, 0x1A, 0xA4, 0xB2, 0x4B, 0x19, 0x9C, 0x42, 0x01, 0x44, 0x80, 0xF2, 0x82, 0x80, -+0xDF, 0xF8, 0xD4, 0xA1, 0x13, 0x1B, 0x1D, 0x44, 0xA2, 0x1A, 0x92, 0xB2, 0x48, 0x46, 0xAD, 0xB2, 0xFA, 0xF7, 0x7A, 0xFF, -+0x00, 0x22, 0x95, 0xB1, 0xDA, 0xF8, 0x00, 0x30, 0x76, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x93, 0x42, 0x4D, 0xDB, 0xD6, 0xE9, -+0x02, 0x14, 0x01, 0x34, 0x64, 0x1A, 0xA4, 0xB2, 0xAC, 0x42, 0xE7, 0xD3, 0x2C, 0x46, 0x2A, 0x46, 0x48, 0x46, 0xFA, 0xF7, -+0x65, 0xFF, 0xDF, 0xF8, 0x98, 0xE1, 0x0D, 0xF1, 0x10, 0x0C, 0x08, 0x25, 0xD6, 0xE9, 0x02, 0x32, 0x01, 0x32, 0x98, 0xB2, -+0x92, 0xB2, 0xA2, 0xEB, 0x00, 0x0A, 0x1F, 0xFA, 0x8A, 0xFA, 0x29, 0x19, 0x51, 0x45, 0x23, 0x44, 0x3B, 0xDD, 0xAA, 0xEB, -+0x04, 0x0A, 0x1F, 0xFA, 0x8A, 0xFA, 0x0A, 0xF1, 0xFF, 0x3B, 0xBA, 0xF1, 0x00, 0x0F, 0x37, 0xD0, 0x82, 0x1A, 0x14, 0x44, -+0x25, 0x44, 0xAD, 0xB2, 0x59, 0x1C, 0x59, 0x44, 0xAC, 0xEB, 0x03, 0x00, 0x1A, 0x78, 0xC2, 0x54, 0x01, 0x33, 0x8B, 0x42, -+0xFA, 0xD1, 0xD4, 0x44, 0x65, 0xB3, 0xDE, 0xF8, 0x00, 0x30, 0x76, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x24, 0xA3, 0x42, -+0xD2, 0xDA, 0x00, 0x2E, 0xD0, 0xD1, 0x47, 0x49, 0x47, 0x48, 0x40, 0xF2, 0x66, 0x42, 0xF7, 0xF7, 0x6F, 0xF8, 0x7F, 0xE7, -+0xFF, 0xF7, 0x40, 0xFF, 0x00, 0x27, 0x38, 0x46, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x2E, 0xAF, 0xD1, 0x3F, 0x49, -+0x3F, 0x48, 0x40, 0xF2, 0x3C, 0x42, 0xF7, 0xF7, 0x5F, 0xF8, 0x38, 0x46, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xAA, 0x46, -+0x05, 0xF1, 0xFF, 0x3B, 0x00, 0x25, 0xCB, 0xE7, 0x01, 0x44, 0x8A, 0x1A, 0x95, 0xB2, 0xD2, 0xE7, 0x03, 0x9B, 0x00, 0x2B, -+0x3C, 0xD1, 0xDD, 0xE9, 0x04, 0x23, 0xC9, 0xE9, 0x04, 0x23, 0x01, 0x27, 0x38, 0x46, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0x2A, 0x44, 0x94, 0xB2, 0x95, 0xE7, 0x29, 0x6A, 0xEB, 0x79, 0x00, 0x93, 0x58, 0x31, 0x05, 0xF1, 0x2A, 0x03, 0x05, 0xF1, -+0x24, 0x02, 0x48, 0x46, 0xFA, 0xF7, 0xCE, 0xFE, 0x29, 0x7A, 0x23, 0x8E, 0xE6, 0x69, 0x5C, 0x1A, 0xA4, 0xB2, 0x8A, 0xB2, -+0x5C, 0xE7, 0xB5, 0x68, 0x03, 0x91, 0x22, 0x46, 0x48, 0x46, 0x1D, 0x44, 0xFA, 0xF7, 0xE6, 0xFE, 0x03, 0x99, 0xC4, 0xF1, -+0x08, 0x06, 0x04, 0xAB, 0xF6, 0xB2, 0x21, 0x44, 0xF2, 0x18, 0xC9, 0x1A, 0xC8, 0x5C, 0x03, 0xF8, 0x01, 0x0B, 0x9A, 0x42, -+0xFA, 0xD1, 0xD6, 0xF1, 0x08, 0x06, 0x07, 0xD0, 0x2B, 0x46, 0xD2, 0x1A, 0x35, 0x44, 0x19, 0x78, 0xD1, 0x54, 0x01, 0x33, -+0x9D, 0x42, 0xFA, 0xD1, 0x48, 0x46, 0xFA, 0xF7, 0x69, 0xFF, 0x04, 0x9A, 0xD9, 0xF8, 0x00, 0x30, 0x9A, 0x42, 0x0D, 0xD0, -+0xD8, 0xF8, 0x00, 0x30, 0x1B, 0x78, 0x9B, 0x07, 0x05, 0xD5, 0x03, 0x20, 0xD8, 0xF7, 0xCE, 0xF9, 0x0F, 0x4B, 0x98, 0x42, -+0x12, 0xD1, 0xFF, 0xF7, 0xD1, 0xFE, 0x0D, 0xE7, 0xD9, 0xF8, 0x04, 0x30, 0x05, 0x9A, 0x9A, 0x42, 0xEC, 0xD1, 0xD8, 0xF8, -+0x00, 0x30, 0x1B, 0x78, 0x9A, 0x07, 0xA6, 0xD5, 0x03, 0x20, 0xD8, 0xF7, 0xBB, 0xF9, 0x06, 0x4B, 0x98, 0x42, 0xA0, 0xD0, -+0x05, 0x48, 0xF6, 0xF7, 0xA1, 0xFD, 0xF9, 0xE6, 0xB0, 0xDE, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xA0, 0x96, 0x15, 0x00, -+0x1C, 0xDF, 0x44, 0x21, 0x44, 0xC0, 0x15, 0x00, 0x34, 0x36, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x10, 0xB5, 0x10, 0x48, -+0xF5, 0xF7, 0xF8, 0xFB, 0x10, 0xB1, 0x04, 0x46, 0x20, 0x46, 0x10, 0xBD, 0x0D, 0x48, 0xF5, 0xF7, 0xF1, 0xFB, 0x0D, 0x4B, -+0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0x46, 0x06, 0xDB, 0x62, 0x69, 0x04, 0x21, 0x00, 0x20, 0xFF, 0xF7, -+0xC7, 0xFB, 0x20, 0x46, 0x10, 0xBD, 0x00, 0x28, 0xF6, 0xD1, 0x06, 0x49, 0x06, 0x48, 0x40, 0xF2, 0xEA, 0x42, 0xF6, 0xF7, -+0xEB, 0xFF, 0xEF, 0xE7, 0x00, 0xDF, 0x17, 0x00, 0x08, 0xDF, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x54, 0xC0, 0x15, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x20, 0x63, 0x79, 0x62, 0x69, 0x83, 0x42, 0x14, 0xBF, 0x18, 0x21, -+0x08, 0x21, 0xFF, 0xF7, 0xA7, 0xFB, 0x08, 0xB1, 0xA3, 0x89, 0x83, 0x64, 0x10, 0xBD, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x47, -+0xA3, 0x4F, 0x8A, 0xB0, 0x05, 0x46, 0x14, 0x46, 0x1A, 0xB3, 0x3E, 0x88, 0x97, 0xF8, 0x07, 0x80, 0x16, 0xF4, 0x80, 0x66, -+0x22, 0xD1, 0x97, 0xF8, 0x06, 0xA0, 0xBA, 0xF1, 0x00, 0x0F, 0x6A, 0xD0, 0xBC, 0x6D, 0xBA, 0x88, 0x14, 0xB9, 0x31, 0xE1, -+0x24, 0x68, 0xEC, 0xB1, 0xA3, 0x79, 0x8B, 0x42, 0xFA, 0xD1, 0xE3, 0x79, 0x43, 0x45, 0xF7, 0xD1, 0x63, 0x89, 0x93, 0x42, -+0xF4, 0xD1, 0x23, 0x7A, 0x53, 0x45, 0x00, 0xF0, 0x90, 0x80, 0x4F, 0xF0, 0x00, 0x0A, 0x50, 0x46, 0x0A, 0xB0, 0xBD, 0xE8, -+0xF0, 0x87, 0x3E, 0x88, 0x16, 0xF4, 0x80, 0x66, 0x90, 0x46, 0xDC, 0xD0, 0xBC, 0x6D, 0xBA, 0x88, 0x97, 0xF8, 0x06, 0xA0, -+0x00, 0x2C, 0xE1, 0xD1, 0xBA, 0xF1, 0x00, 0x0F, 0xEB, 0xD1, 0x03, 0x91, 0xFF, 0xF7, 0x88, 0xFF, 0x01, 0x26, 0x03, 0x99, -+0x81, 0x71, 0x80, 0xF8, 0x07, 0x80, 0x06, 0x72, 0xBA, 0x88, 0x80, 0xF8, 0x04, 0xA0, 0x39, 0x7A, 0x82, 0x4B, 0xC0, 0xF8, -+0x10, 0xA0, 0x41, 0x72, 0x19, 0x69, 0xDF, 0xF8, 0x0C, 0x92, 0x80, 0x4B, 0x42, 0x81, 0x01, 0xF5, 0xC3, 0x31, 0x83, 0x63, -+0xC0, 0x63, 0xD9, 0xF8, 0xE0, 0x31, 0x04, 0x46, 0xA0, 0x31, 0x34, 0x30, 0x98, 0x47, 0x97, 0xF8, 0x30, 0x30, 0xDA, 0x07, -+0x00, 0xF1, 0xC9, 0x80, 0x2B, 0x6E, 0x23, 0xF0, 0x20, 0x03, 0x2B, 0x66, 0xD9, 0xF8, 0xE8, 0x32, 0x01, 0x21, 0x28, 0x46, -+0x98, 0x47, 0x3B, 0x6C, 0xFA, 0x69, 0x73, 0x48, 0xC4, 0xE9, 0x04, 0x23, 0x97, 0xF8, 0x31, 0x30, 0x63, 0x71, 0x2B, 0x8E, -+0xA3, 0x81, 0x21, 0x46, 0xF5, 0xF7, 0x08, 0xFB, 0x6B, 0x4B, 0x4F, 0xF0, 0x01, 0x0A, 0x1B, 0x69, 0xA3, 0x61, 0x50, 0x46, -+0x0A, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x97, 0xF8, 0x30, 0x30, 0xD8, 0x07, 0x1D, 0xD5, 0x68, 0x4A, 0x01, 0x23, 0xD2, 0xF8, -+0xCC, 0x62, 0x04, 0xA9, 0x1A, 0x46, 0x28, 0x46, 0xB0, 0x47, 0x00, 0x28, 0x9B, 0xD0, 0x2B, 0x8E, 0x63, 0x4A, 0x08, 0x3B, -+0x12, 0x68, 0x2B, 0x86, 0x13, 0x78, 0x99, 0x07, 0x0B, 0xD5, 0x6B, 0x6D, 0x03, 0xF0, 0x3C, 0x02, 0x3C, 0x2A, 0x06, 0xD1, -+0x23, 0xF0, 0x7C, 0x03, 0x43, 0xF4, 0x00, 0x53, 0x43, 0xF0, 0x08, 0x03, 0x6B, 0x65, 0x5B, 0x4B, 0xB8, 0x7A, 0x4F, 0xF4, -+0xA4, 0x62, 0x02, 0xFB, 0x00, 0x30, 0x90, 0xF8, 0xC3, 0x34, 0x00, 0x2B, 0x6D, 0xD1, 0x54, 0x4B, 0x28, 0x46, 0xD3, 0xF8, -+0xE8, 0x32, 0x03, 0x21, 0x98, 0x47, 0x4F, 0xF0, 0x01, 0x0A, 0x50, 0x46, 0x0A, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x29, 0x8E, -+0x94, 0xF8, 0x09, 0x80, 0xA3, 0x89, 0xDF, 0xF8, 0x30, 0x91, 0xA1, 0xEB, 0x08, 0x08, 0x1F, 0xFA, 0x88, 0xF8, 0x43, 0x44, -+0x0A, 0xF1, 0x01, 0x0A, 0x84, 0xF8, 0x08, 0xA0, 0xA3, 0x81, 0x97, 0xF8, 0x30, 0x30, 0xDB, 0x07, 0x22, 0xD5, 0xB6, 0xFA, -+0x86, 0xF3, 0xD9, 0xF8, 0xCC, 0x72, 0x5B, 0x09, 0x00, 0x22, 0x04, 0xF1, 0x1C, 0x01, 0x28, 0x46, 0xB8, 0x47, 0x00, 0x28, -+0x4C, 0xD0, 0x2B, 0x6E, 0x00, 0x2E, 0x57, 0xD0, 0x61, 0x7A, 0x22, 0x69, 0x23, 0xF0, 0x20, 0x03, 0x43, 0xF0, 0x40, 0x03, -+0x2B, 0x66, 0x41, 0x44, 0x00, 0x23, 0x01, 0x93, 0x00, 0x93, 0xD9, 0xF8, 0xA4, 0x62, 0x89, 0xB2, 0x28, 0x46, 0xB0, 0x47, -+0x23, 0x69, 0x43, 0x44, 0x23, 0x61, 0x87, 0xE7, 0x01, 0x27, 0x2B, 0x6E, 0x22, 0x69, 0x23, 0xF0, 0x20, 0x03, 0x43, 0xF0, -+0x40, 0x03, 0x2B, 0x66, 0x00, 0x23, 0xCD, 0xE9, 0x00, 0x33, 0x28, 0x46, 0xD9, 0xF8, 0xA4, 0x52, 0xA8, 0x47, 0x23, 0x69, -+0x43, 0x44, 0x23, 0x61, 0x00, 0x2E, 0x7F, 0xF4, 0x73, 0xAF, 0x20, 0x46, 0xFF, 0xF7, 0xEC, 0xFE, 0x62, 0x69, 0x39, 0x46, -+0x00, 0x20, 0xFF, 0xF7, 0x99, 0xFA, 0xD9, 0xF8, 0xD8, 0x31, 0x04, 0xF1, 0x34, 0x00, 0x98, 0x47, 0x21, 0x46, 0x20, 0x48, -+0xF5, 0xF7, 0xBA, 0xFA, 0x22, 0x48, 0x21, 0x46, 0xF5, 0xF7, 0x66, 0xFA, 0x5C, 0xE7, 0xEA, 0x69, 0x00, 0xF2, 0xC4, 0x41, -+0x92, 0x68, 0x23, 0x46, 0x63, 0x30, 0xFF, 0xF7, 0x31, 0xFA, 0x01, 0x28, 0x87, 0xD1, 0x04, 0xE7, 0x61, 0x7A, 0x41, 0x44, -+0x89, 0xB2, 0x04, 0x27, 0xC5, 0xE7, 0x32, 0x46, 0x53, 0x46, 0xD9, 0xF8, 0xCC, 0x62, 0x04, 0xF1, 0x1C, 0x01, 0x28, 0x46, -+0xB0, 0x47, 0x2D, 0xE7, 0xA0, 0x89, 0x61, 0x7A, 0x22, 0x69, 0x23, 0xF0, 0x20, 0x03, 0x43, 0xF0, 0x40, 0x03, 0x08, 0x38, -+0xA0, 0x81, 0x41, 0x44, 0x2B, 0x66, 0x28, 0x46, 0x33, 0x46, 0xCD, 0xE9, 0x00, 0x66, 0xD9, 0xF8, 0xA4, 0x52, 0x89, 0xB2, -+0xA8, 0x47, 0x23, 0x69, 0x43, 0x44, 0x23, 0x61, 0x01, 0x27, 0xB8, 0xE7, 0xA2, 0x46, 0xDC, 0xE6, 0xB0, 0xDE, 0x17, 0x00, -+0x00, 0x10, 0x50, 0x40, 0xC5, 0xD3, 0x14, 0x00, 0x08, 0xDF, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x34, 0x36, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x00, 0xDF, 0x17, 0x00, 0xF8, 0xB5, 0x03, 0x88, 0x13, 0x4D, 0x13, 0xF4, 0x00, 0x6F, 0x04, 0x46, -+0xC3, 0x8A, 0x0B, 0xD1, 0x05, 0xF1, 0x60, 0x07, 0x00, 0xF1, 0x0A, 0x06, 0x30, 0x68, 0xB2, 0x88, 0xBA, 0x80, 0x28, 0x66, -+0xA5, 0xF8, 0x66, 0x30, 0x01, 0x20, 0xF8, 0xBD, 0xB5, 0xF8, 0x66, 0x20, 0x9A, 0x42, 0x04, 0xD0, 0x00, 0xF1, 0x0A, 0x06, -+0x05, 0xF1, 0x60, 0x07, 0xEE, 0xE7, 0x05, 0xF1, 0x60, 0x07, 0x00, 0xF1, 0x0A, 0x06, 0x39, 0x46, 0x30, 0x46, 0x06, 0x22, -+0x09, 0xF0, 0xC6, 0xF8, 0x00, 0x28, 0xEA, 0xD0, 0xE3, 0x8A, 0xE1, 0xE7, 0xB0, 0xDE, 0x17, 0x00, 0xF0, 0xB4, 0x01, 0xB3, -+0x00, 0x22, 0x87, 0x7A, 0x94, 0x46, 0x07, 0xE0, 0x1E, 0x69, 0x1E, 0xB1, 0x01, 0x3C, 0xC3, 0xF8, 0x10, 0xC0, 0xC4, 0x72, -+0x8D, 0x42, 0x09, 0xD2, 0xBB, 0x18, 0xC4, 0x7A, 0x03, 0xF0, 0x3F, 0x03, 0x01, 0x32, 0x00, 0xEB, 0x83, 0x03, 0x95, 0xB2, -+0x00, 0x2C, 0xED, 0xD1, 0x03, 0x89, 0x0F, 0x44, 0x19, 0x44, 0x07, 0xF0, 0x3F, 0x07, 0xC1, 0xF3, 0x0B, 0x01, 0x87, 0x72, -+0x01, 0x81, 0xF0, 0xBC, 0x70, 0x47, 0x87, 0x7A, 0xF2, 0xE7, 0x00, 0xBF, 0xF8, 0xB5, 0x83, 0x7A, 0x04, 0x33, 0x50, 0xF8, -+0x23, 0x30, 0x53, 0xB3, 0xC1, 0x7A, 0x15, 0x4D, 0x15, 0x4F, 0x16, 0x4E, 0x04, 0x46, 0x15, 0xE0, 0xA3, 0x7A, 0x22, 0x89, -+0x18, 0x1D, 0x01, 0x33, 0x03, 0xF0, 0x3F, 0x03, 0x01, 0x39, 0x4F, 0xF0, 0x00, 0x0C, 0x44, 0xF8, 0x20, 0xC0, 0xC9, 0xB2, -+0x18, 0x1D, 0xA3, 0x72, 0xE1, 0x72, 0x54, 0xF8, 0x20, 0x00, 0x53, 0x1C, 0xC3, 0xF3, 0x0B, 0x03, 0x23, 0x81, 0x70, 0xB1, -+0x2B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xE4, 0xDA, 0x00, 0x29, 0xE2, 0xD1, 0x39, 0x46, 0x4F, 0xF4, 0xD6, 0x62, -+0x30, 0x46, 0xF6, 0xF7, 0xF5, 0xFD, 0xE1, 0x7A, 0xDA, 0xE7, 0xF8, 0xBD, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x64, 0xC0, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x9E, 0x23, 0x0C, 0x8A, 0x38, 0x4A, 0x03, 0xFB, 0x00, 0xF0, 0x00, 0xEB, -+0x14, 0x30, 0x02, 0xEB, 0x80, 0x00, 0xD0, 0xF8, 0x7C, 0x41, 0x4C, 0xB3, 0x94, 0xF8, 0x21, 0x31, 0x49, 0x8A, 0xC3, 0xB1, -+0xEF, 0xF3, 0x10, 0x83, 0xDA, 0x07, 0x30, 0xD5, 0x30, 0x48, 0x31, 0x4D, 0x03, 0x68, 0x2E, 0x68, 0x03, 0xF0, 0x60, 0x42, -+0x77, 0x1C, 0xB2, 0xF1, 0xC0, 0x4F, 0x2F, 0x60, 0x31, 0xD0, 0x2D, 0x4B, 0x80, 0x22, 0x1A, 0x60, 0x2F, 0xB1, 0x2C, 0x4B, -+0x2E, 0x60, 0x1B, 0x68, 0x0E, 0xB9, 0x03, 0xB1, 0x62, 0xB6, 0x22, 0x89, 0xB2, 0xEB, 0x11, 0x1F, 0x4F, 0xEA, 0x11, 0x13, -+0x06, 0xD0, 0x9B, 0x1A, 0x99, 0xB2, 0x1B, 0x05, 0x04, 0xD5, 0x94, 0xF8, 0x21, 0x31, 0x9B, 0xB1, 0xBD, 0xE8, 0xF0, 0x81, -+0x22, 0x4D, 0x20, 0x46, 0xD5, 0xF8, 0xD8, 0x32, 0xC1, 0xF3, 0x0B, 0x01, 0x98, 0x47, 0xD5, 0xF8, 0x38, 0x31, 0x1F, 0x48, -+0xBD, 0xE8, 0xF0, 0x41, 0x18, 0x47, 0x72, 0xB6, 0x1A, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0xC9, 0xE7, 0x1B, 0x48, 0xF6, 0xF7, -+0x23, 0xFB, 0x01, 0x23, 0x84, 0xF8, 0x21, 0x31, 0xE4, 0xE7, 0x19, 0x4A, 0x03, 0xF4, 0xF0, 0x33, 0xD2, 0xF8, 0x00, 0xC0, -+0xB3, 0xF5, 0xF0, 0x3F, 0x0C, 0xF1, 0x10, 0x0C, 0xC3, 0xD0, 0x96, 0x46, 0x03, 0x68, 0x03, 0xF0, 0x60, 0x42, 0xB2, 0xF1, -+0xC0, 0x4F, 0x02, 0xD0, 0x10, 0x4B, 0x1B, 0x68, 0xB9, 0xE7, 0x03, 0xF4, 0xF0, 0x33, 0xB3, 0xF5, 0xF0, 0x3F, 0xF7, 0xD0, -+0xDE, 0xF8, 0x00, 0x30, 0xA3, 0xEB, 0x0C, 0x03, 0x00, 0x2B, 0xEB, 0xDB, 0x00, 0x2F, 0xB6, 0xD0, 0xAF, 0xE7, 0x00, 0xBF, -+0x68, 0x65, 0x17, 0x00, 0x04, 0x05, 0x32, 0x40, 0x6C, 0x28, 0x17, 0x00, 0x54, 0x00, 0x32, 0x40, 0x38, 0x61, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0xE8, 0xDE, 0x17, 0x00, 0x7C, 0xC0, 0x15, 0x00, 0x20, 0x01, 0x32, 0x40, 0x2D, 0xE9, 0xF8, 0x43, -+0x8D, 0x4F, 0x8E, 0x4B, 0xBC, 0x7A, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x04, 0x34, 0x80, 0x46, 0x94, 0xF8, 0xC3, 0x54, -+0x89, 0x46, 0x00, 0x2D, 0x40, 0xF0, 0x90, 0x80, 0xF8, 0x79, 0x88, 0x49, 0xBA, 0x88, 0x9E, 0x23, 0x03, 0xFB, 0x09, 0x03, -+0x01, 0xEB, 0x83, 0x03, 0xD3, 0xF8, 0x7C, 0x41, 0x23, 0x89, 0x9A, 0x42, 0x00, 0xF0, 0xA5, 0x80, 0xD2, 0x1A, 0x12, 0xF4, -+0x7C, 0x6F, 0xC2, 0xF3, 0x0B, 0x03, 0x38, 0xD1, 0xA6, 0x7A, 0x1E, 0x44, 0x06, 0xF0, 0x3F, 0x06, 0x01, 0x23, 0x04, 0xEB, -+0x86, 0x06, 0x84, 0xF8, 0x20, 0x31, 0x33, 0x69, 0x00, 0x2B, 0x6B, 0xD1, 0x8D, 0xB9, 0xD8, 0xF8, 0x60, 0x20, 0xB8, 0xF8, -+0x32, 0x30, 0x77, 0x49, 0x42, 0xF0, 0x20, 0x02, 0xC8, 0xF8, 0x60, 0x20, 0x23, 0xF0, 0xFF, 0x03, 0xD1, 0xF8, 0xE8, 0x22, -+0xA8, 0xF8, 0x32, 0x30, 0x40, 0x46, 0x03, 0x21, 0x90, 0x47, 0x71, 0x4B, 0x33, 0x61, 0xE3, 0x7A, 0x70, 0x4A, 0x01, 0x33, -+0x12, 0x68, 0xDB, 0xB2, 0xE3, 0x72, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xC0, 0xF2, 0xB1, 0x80, 0x01, 0x2B, 0x00, 0xF0, -+0xB9, 0x80, 0xC5, 0xF1, 0x01, 0x05, 0xED, 0xB2, 0xF9, 0x79, 0x48, 0x46, 0x02, 0xF0, 0xFE, 0xFE, 0x28, 0x46, 0xBD, 0xE8, -+0xF8, 0x83, 0x40, 0xF2, 0xFE, 0x72, 0x93, 0x42, 0x40, 0xF2, 0x91, 0x80, 0x94, 0xF8, 0x20, 0x31, 0x13, 0xB1, 0x94, 0xF8, -+0x21, 0x31, 0x9B, 0xB3, 0x3B, 0x88, 0x1B, 0x05, 0x21, 0xD4, 0x7A, 0x88, 0x4F, 0xF4, 0x9E, 0x73, 0x03, 0xFB, 0x09, 0x03, -+0x01, 0xEB, 0x43, 0x03, 0xA3, 0xF8, 0xEA, 0x21, 0x15, 0xBB, 0xD8, 0xF8, 0x60, 0x20, 0xB8, 0xF8, 0x32, 0x30, 0x55, 0x49, -+0x42, 0xF0, 0x20, 0x02, 0x23, 0xF0, 0xFF, 0x03, 0xC8, 0xF8, 0x60, 0x20, 0xD1, 0xF8, 0xE8, 0x22, 0xA8, 0xF8, 0x32, 0x30, -+0x40, 0x46, 0x03, 0x21, 0x90, 0x47, 0xF9, 0x79, 0x48, 0x46, 0x02, 0xF0, 0xCD, 0xFE, 0x01, 0x25, 0xCC, 0xE7, 0x4F, 0xF4, -+0x9E, 0x73, 0x03, 0xFB, 0x09, 0x03, 0x01, 0xEB, 0x43, 0x03, 0x7A, 0x88, 0xB3, 0xF8, 0xEA, 0x31, 0x93, 0x42, 0xD3, 0xD1, -+0xF9, 0x79, 0x48, 0x46, 0x02, 0xF0, 0xBC, 0xFE, 0x00, 0x25, 0x28, 0x46, 0xBD, 0xE8, 0xF8, 0x83, 0xC2, 0x69, 0x04, 0xF2, -+0xC4, 0x41, 0x92, 0x68, 0x01, 0x23, 0x04, 0xF1, 0x63, 0x00, 0xFF, 0xF7, 0x3B, 0xF8, 0x05, 0x46, 0xF8, 0x79, 0x3B, 0x49, -+0xBA, 0x88, 0x9E, 0x23, 0x03, 0xFB, 0x09, 0x03, 0x01, 0xEB, 0x83, 0x03, 0x01, 0x2D, 0xD3, 0xF8, 0x7C, 0x41, 0x23, 0x89, -+0x60, 0xD0, 0x9A, 0x42, 0x09, 0xD0, 0xD2, 0x1A, 0x12, 0xF4, 0x7C, 0x6F, 0x4F, 0xF0, 0x00, 0x05, 0xC2, 0xF3, 0x0B, 0x03, -+0x3F, 0xF4, 0x62, 0xAF, 0x99, 0xE7, 0xD8, 0xF8, 0x60, 0x20, 0xB8, 0xF8, 0x32, 0x30, 0x2E, 0x49, 0x42, 0xF0, 0x20, 0x02, -+0x23, 0xF0, 0xFF, 0x03, 0xC8, 0xF8, 0x60, 0x20, 0xD1, 0xF8, 0xE8, 0x22, 0xA8, 0xF8, 0x32, 0x30, 0x40, 0x46, 0x03, 0x21, -+0x90, 0x47, 0x23, 0x89, 0x01, 0x25, 0x01, 0x20, 0x28, 0x4A, 0xA1, 0x7A, 0x84, 0xF8, 0x20, 0x01, 0x12, 0x69, 0x62, 0x60, -+0x04, 0xEB, 0x81, 0x00, 0x02, 0x69, 0x12, 0xB1, 0xE2, 0x7A, 0x01, 0x3A, 0xE2, 0x72, 0x5A, 0x1C, 0x01, 0x31, 0xC2, 0xF3, -+0x0B, 0x02, 0x01, 0xF0, 0x3F, 0x01, 0x00, 0x23, 0x03, 0x61, 0x20, 0x46, 0x22, 0x81, 0xA1, 0x72, 0xFF, 0xF7, 0x4E, 0xFE, -+0x62, 0xE7, 0x18, 0x4A, 0xA3, 0xF1, 0x3F, 0x01, 0x89, 0xB2, 0xD2, 0xF8, 0xD8, 0x32, 0x20, 0x46, 0x98, 0x47, 0xBB, 0x88, -+0x21, 0x89, 0x5B, 0x1A, 0xC3, 0xF3, 0x0B, 0x03, 0x22, 0xE7, 0x40, 0x2B, 0x7F, 0xF6, 0x4C, 0xAF, 0x13, 0x49, 0x14, 0x48, -+0x40, 0xF2, 0xDB, 0x72, 0xF6, 0xF7, 0x5A, 0xFC, 0xE3, 0x7A, 0x43, 0xE7, 0x0E, 0x4A, 0x0B, 0x4B, 0x11, 0x69, 0xD3, 0xF8, -+0xE0, 0x31, 0x01, 0xF5, 0x43, 0x41, 0x04, 0xF5, 0x88, 0x70, 0x50, 0x31, 0x98, 0x47, 0x3A, 0xE7, 0x9A, 0x42, 0x7F, 0xF4, -+0x03, 0xAF, 0x00, 0x25, 0xB9, 0xE7, 0x00, 0xBF, 0xB0, 0xDE, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x87, 0xA9, 0xDC, 0xFE, 0x38, 0x36, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x70, 0x79, 0x15, 0x00, -+0x90, 0xC0, 0x15, 0x00, 0xC3, 0x7A, 0x03, 0xB9, 0x70, 0x47, 0x1A, 0x4B, 0x42, 0x68, 0x1B, 0x69, 0xC3, 0xF5, 0x43, 0x43, -+0x50, 0x33, 0xD3, 0x42, 0x10, 0xB5, 0x04, 0x46, 0x00, 0xD4, 0x10, 0xBD, 0x83, 0x7A, 0x1A, 0x1D, 0x50, 0xF8, 0x22, 0x20, -+0x42, 0xB9, 0x02, 0x89, 0x01, 0x33, 0x01, 0x32, 0x03, 0xF0, 0x3F, 0x03, 0xC2, 0xF3, 0x0B, 0x02, 0x83, 0x72, 0x02, 0x81, -+0x20, 0x46, 0xFF, 0xF7, 0xF1, 0xFD, 0xE3, 0x7A, 0x53, 0xB9, 0x0B, 0x4A, 0x0B, 0x4B, 0x11, 0x69, 0xD3, 0xF8, 0xE0, 0x31, -+0x01, 0xF5, 0x43, 0x41, 0x04, 0xF5, 0x88, 0x70, 0x50, 0x31, 0x98, 0x47, 0x07, 0x48, 0x83, 0x6B, 0x00, 0x2B, 0xDC, 0xD0, -+0x04, 0x4B, 0xBD, 0xE8, 0x10, 0x40, 0xD3, 0xF8, 0x38, 0x31, 0x38, 0x30, 0x18, 0x47, 0x00, 0xBF, 0x00, 0x10, 0x50, 0x40, -+0x88, 0x1A, 0x17, 0x00, 0xB0, 0xDE, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x19, 0x4B, 0x1B, 0x7C, 0xFF, 0x2B, 0x05, 0x46, -+0x04, 0xD0, 0x03, 0x88, 0x03, 0xF0, 0xEC, 0x03, 0xC4, 0x2B, 0x11, 0xD0, 0x15, 0x4F, 0x05, 0xF1, 0x04, 0x08, 0x07, 0xF5, -+0xA4, 0x56, 0xB9, 0x46, 0x3C, 0x46, 0x94, 0xF8, 0x64, 0x30, 0x1B, 0xB1, 0x94, 0xF8, 0x62, 0x30, 0x02, 0x2B, 0x06, 0xD0, -+0x04, 0xF5, 0xA4, 0x64, 0xA6, 0x42, 0xF4, 0xD1, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x06, 0x22, 0x04, 0xF1, 0x5C, 0x01, -+0x40, 0x46, 0x08, 0xF0, 0x45, 0xFE, 0xA4, 0xEB, 0x07, 0x0A, 0x00, 0x28, 0xEE, 0xD1, 0x07, 0x49, 0x07, 0x48, 0xF6, 0xF7, -+0x4D, 0xF9, 0x05, 0xF1, 0x0A, 0x01, 0x09, 0xEB, 0x0A, 0x00, 0xFD, 0xF7, 0x49, 0xFD, 0xE7, 0xE7, 0x00, 0x88, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x20, 0xC1, 0x15, 0x00, 0xA8, 0xC0, 0x15, 0x00, 0x13, 0x4B, 0x93, 0xF8, 0x73, 0x20, 0x12, 0xB1, -+0x11, 0xF4, 0x00, 0x71, 0x00, 0xD0, 0x70, 0x47, 0x10, 0xB4, 0x42, 0x89, 0xB3, 0xF8, 0x6C, 0x40, 0x94, 0x42, 0x02, 0xD0, -+0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0xB3, 0xF8, 0x6E, 0x40, 0x82, 0x89, 0x94, 0x42, 0xF7, 0xD1, 0xB3, 0xF8, 0x70, 0x40, -+0xC2, 0x89, 0x94, 0x42, 0xF2, 0xD1, 0x02, 0x88, 0x02, 0xF4, 0xA0, 0x52, 0xB2, 0xF5, 0x80, 0x5F, 0x06, 0xBF, 0x01, 0x22, -+0x83, 0xF8, 0x72, 0x20, 0x83, 0xF8, 0x72, 0x10, 0xE6, 0xE7, 0x00, 0xBF, 0xB0, 0xDE, 0x17, 0x00, 0xF8, 0xB5, 0xBD, 0xF8, -+0x1C, 0x60, 0x06, 0x9D, 0xFF, 0x2A, 0x00, 0xEB, 0x06, 0x07, 0x2E, 0xD0, 0x14, 0x46, 0x82, 0x5D, 0x03, 0x3A, 0x12, 0x2A, -+0x18, 0xD8, 0xDF, 0xE8, 0x02, 0xF0, 0x2B, 0x17, 0x0A, 0x17, 0x30, 0x49, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -+0x17, 0x17, 0x17, 0x17, 0x5C, 0x00, 0x1B, 0x78, 0x4B, 0x4A, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, -+0x62, 0x30, 0x02, 0x2B, 0x02, 0xD0, 0x7B, 0x78, 0x00, 0x2B, 0x6A, 0xD0, 0x01, 0x26, 0x2B, 0x88, 0xFF, 0x2B, 0x0A, 0xD0, -+0x44, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x57, 0xDB, 0x6F, 0xF0, 0xFF, 0x03, 0x2A, 0x88, 0x13, 0x43, -+0x2B, 0x80, 0x30, 0x46, 0xF8, 0xBD, 0x01, 0x26, 0x30, 0x46, 0xF8, 0xBD, 0x08, 0x23, 0x2B, 0x80, 0x00, 0x26, 0x00, 0x23, -+0xF2, 0xE7, 0x7E, 0x78, 0x00, 0x2E, 0x52, 0xD0, 0x01, 0x2E, 0xE1, 0xD1, 0x38, 0x4A, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, -+0x04, 0x23, 0x5E, 0x68, 0x16, 0xF0, 0x02, 0x06, 0xD9, 0xD0, 0xBE, 0x78, 0x16, 0xF0, 0x01, 0x06, 0x5A, 0xD0, 0x20, 0x46, -+0x00, 0x22, 0xFF, 0x21, 0xF9, 0xF7, 0xDC, 0xFC, 0x00, 0x26, 0xCE, 0xE7, 0x89, 0x1B, 0x03, 0x29, 0x2A, 0xDD, 0x1B, 0x78, -+0xFF, 0x2B, 0xC7, 0xD0, 0x29, 0x4A, 0x7E, 0x78, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x23, 0x93, 0xF8, 0x62, 0x30, -+0x1E, 0x43, 0xBD, 0xD1, 0x06, 0x23, 0x2B, 0x80, 0xD1, 0xE7, 0x7B, 0x78, 0x01, 0x2B, 0x36, 0xD0, 0x02, 0x2B, 0xB5, 0xD1, -+0x22, 0x4A, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x04, 0x23, 0x5E, 0x68, 0x16, 0xF0, 0x24, 0x06, 0xAD, 0xD0, 0x97, 0xF9, -+0x02, 0x30, 0xB9, 0x78, 0x00, 0x2B, 0x07, 0xDB, 0x0A, 0x09, 0x20, 0x46, 0x01, 0xF0, 0x03, 0x01, 0xF9, 0xF7, 0xAE, 0xFC, -+0x00, 0x26, 0xA0, 0xE7, 0x00, 0x26, 0x9E, 0xE7, 0x17, 0x49, 0x18, 0x48, 0x40, 0xF6, 0x78, 0x12, 0xF6, 0xF7, 0x00, 0xFB, -+0x6F, 0xF0, 0xFF, 0x03, 0xA0, 0xE7, 0x0B, 0x23, 0x2B, 0x80, 0x01, 0x26, 0xA7, 0xE7, 0x10, 0x4A, 0x4F, 0xF4, 0x1E, 0x73, -+0x03, 0xFB, 0x04, 0x23, 0x5B, 0x68, 0x9B, 0x07, 0x89, 0xD5, 0xB9, 0x78, 0x01, 0x29, 0x86, 0xD8, 0x20, 0x46, 0xFF, 0x22, -+0xF9, 0xF7, 0x8E, 0xFC, 0x81, 0xE7, 0x07, 0xF1, 0x0A, 0x01, 0xB8, 0x1C, 0xD2, 0xF7, 0xB6, 0xFE, 0x00, 0x26, 0x7A, 0xE7, -+0xFF, 0x22, 0x20, 0x46, 0x11, 0x46, 0xF9, 0xF7, 0x81, 0xFC, 0x74, 0xE7, 0x18, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x68, 0x65, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xBC, 0xC0, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x89, 0xB0, 0x1F, 0x46, -+0x10, 0x9E, 0x34, 0x78, 0xFF, 0x2C, 0x47, 0xD0, 0x69, 0x4D, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x04, 0x55, 0x00, 0xF0, -+0xFC, 0x04, 0x80, 0x2C, 0x95, 0xF8, 0x62, 0x80, 0x46, 0xD0, 0x0F, 0xD8, 0x40, 0x2C, 0x6B, 0xD0, 0x2C, 0xD9, 0x50, 0x2C, -+0x4F, 0xF0, 0x01, 0x04, 0x04, 0xD1, 0x13, 0x9A, 0x14, 0x70, 0x12, 0x9A, 0x04, 0x23, 0x13, 0x80, 0x20, 0x46, 0x09, 0xB0, -+0xBD, 0xE8, 0xF0, 0x83, 0xC0, 0x2C, 0x21, 0xD0, 0x10, 0xD9, 0xD0, 0x2C, 0x15, 0xD1, 0x13, 0x9B, 0x11, 0x98, 0xCD, 0xE9, -+0x01, 0x23, 0x12, 0x9B, 0x00, 0x93, 0x3A, 0x46, 0x33, 0x46, 0xFF, 0xF7, 0x11, 0xFF, 0x04, 0x46, 0x20, 0x46, 0x09, 0xB0, -+0xBD, 0xE8, 0xF0, 0x83, 0xA0, 0x2C, 0x0D, 0xD0, 0xB0, 0x2C, 0x02, 0xD1, 0xFC, 0xF7, 0xBA, 0xFA, 0x40, 0xB1, 0x01, 0x24, -+0x20, 0x46, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x00, 0xF0, 0xDC, 0x00, 0x10, 0x28, 0xF6, 0xD1, 0xB8, 0xF1, 0x00, 0x0F, -+0xF3, 0xD1, 0x12, 0x9A, 0x06, 0x23, 0x13, 0x80, 0x01, 0x24, 0xCF, 0xE7, 0x00, 0xF0, 0xFC, 0x00, 0xB0, 0x28, 0x72, 0xD0, -+0x28, 0xD8, 0x40, 0x28, 0x2A, 0xD0, 0x80, 0x28, 0xE5, 0xD1, 0x00, 0x25, 0x04, 0x20, 0x05, 0x91, 0xF4, 0xF7, 0x34, 0xFC, -+0x01, 0x28, 0x05, 0x99, 0x0E, 0xD1, 0x13, 0x9A, 0x3D, 0x4B, 0x10, 0x70, 0x12, 0x98, 0x1B, 0x68, 0x3A, 0x4D, 0x04, 0x22, -+0x02, 0x80, 0x93, 0xF8, 0x6E, 0x41, 0x34, 0x70, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x04, 0x55, 0xFF, 0x2F, 0xCC, 0xD0, -+0x95, 0xF8, 0x64, 0x30, 0x00, 0x2B, 0xC8, 0xD0, 0x34, 0x4B, 0x30, 0x78, 0xD3, 0xF8, 0x54, 0x31, 0x11, 0x9A, 0x98, 0x47, -+0x01, 0x24, 0xA1, 0xE7, 0xD0, 0x28, 0xA8, 0xD0, 0x01, 0x24, 0xBD, 0xE7, 0x2F, 0x4B, 0x9A, 0x7C, 0x00, 0x2A, 0xB8, 0xD0, -+0x2E, 0x4A, 0x12, 0x68, 0x12, 0x78, 0x01, 0x3A, 0x01, 0x2A, 0xB2, 0xD8, 0x9D, 0x68, 0x00, 0x2D, 0xAF, 0xD0, 0x18, 0x39, -+0x2A, 0x4F, 0x1F, 0xFA, 0x81, 0xF8, 0x01, 0x24, 0x02, 0xE0, 0x2D, 0x68, 0x00, 0x2D, 0x87, 0xD0, 0x95, 0xF8, 0x62, 0x30, -+0x02, 0x2B, 0xF8, 0xD1, 0x95, 0xF8, 0x64, 0x30, 0x00, 0x2B, 0xF4, 0xD0, 0x95, 0xF8, 0xC0, 0x34, 0x00, 0x2B, 0xF0, 0xD1, -+0x11, 0x9B, 0xB7, 0xF8, 0x00, 0x90, 0x03, 0xF1, 0x18, 0x00, 0x0D, 0xF1, 0x1E, 0x02, 0x41, 0x46, 0xF4, 0xF7, 0xFA, 0xFF, -+0xA9, 0xF1, 0x24, 0x01, 0x06, 0x46, 0x89, 0xB2, 0x0D, 0xF1, 0x1F, 0x02, 0x19, 0x48, 0xF4, 0xF7, 0xF1, 0xFF, 0x9D, 0xF8, -+0x1E, 0x30, 0x18, 0x49, 0x02, 0x36, 0x81, 0x46, 0x07, 0x22, 0x30, 0x46, 0x53, 0xB9, 0x11, 0x9B, 0x28, 0x46, 0x03, 0xF1, -+0x0A, 0x01, 0xE1, 0xF7, 0xED, 0xFE, 0x00, 0x24, 0xCD, 0xE7, 0xFC, 0xF7, 0x2F, 0xFA, 0x74, 0xE7, 0x08, 0xF0, 0x7C, 0xFC, -+0x00, 0x28, 0xC6, 0xD0, 0x9D, 0xF8, 0x1F, 0x30, 0x9D, 0xF8, 0x1E, 0x20, 0x9A, 0x42, 0xC0, 0xD1, 0x09, 0xF1, 0x02, 0x01, -+0x30, 0x46, 0x08, 0xF0, 0x6F, 0xFC, 0x00, 0x28, 0xE3, 0xD0, 0xB8, 0xE7, 0x18, 0x88, 0x17, 0x00, 0xA8, 0xBA, 0x17, 0x00, -+0x88, 0x1A, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0x78, 0x36, 0x17, 0x00, 0x14, 0x2C, 0x17, 0x00, 0x38, 0x2A, 0x17, 0x00, -+0x54, 0xBF, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xC6, 0x69, 0x8D, 0xB0, 0xD6, 0xF8, 0x08, 0x90, 0x01, 0x23, 0x8D, 0xF8, -+0x24, 0x30, 0x04, 0x46, 0xB9, 0xF8, 0x00, 0x00, 0x10, 0xF4, 0x80, 0x60, 0x40, 0xF0, 0x8B, 0x80, 0xB9, 0xF8, 0x16, 0x70, -+0x17, 0xF0, 0x0F, 0x07, 0x00, 0xF0, 0x89, 0x80, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xB9, 0xF8, 0x00, 0x30, 0x98, 0xF8, -+0x08, 0x20, 0x04, 0x92, 0xDF, 0xF8, 0x08, 0xE2, 0xB4, 0xF8, 0x30, 0xA0, 0xBD, 0xF8, 0x10, 0x10, 0xAD, 0xF8, 0x16, 0x30, -+0x4F, 0xF0, 0xFF, 0x0C, 0x18, 0x46, 0xAD, 0xF8, 0x26, 0xC0, 0xB3, 0x68, 0xDE, 0xF8, 0xE0, 0x92, 0x07, 0x93, 0x0D, 0xF1, -+0x25, 0x0C, 0x01, 0x93, 0xCD, 0xF8, 0x0C, 0xC0, 0x72, 0x4B, 0x06, 0x91, 0x0D, 0xF1, 0x26, 0x0C, 0x0A, 0x46, 0x00, 0x93, -+0x51, 0x46, 0x8D, 0xF8, 0x25, 0xB0, 0x80, 0xB2, 0xCD, 0xF8, 0x08, 0xC0, 0x2B, 0x46, 0xC8, 0x47, 0xBD, 0xF8, 0x26, 0x10, -+0xFF, 0x29, 0x00, 0xF0, 0x90, 0x80, 0x0A, 0xF1, 0x0C, 0x03, 0x9B, 0xB2, 0x0A, 0x22, 0x4F, 0xF4, 0x20, 0x50, 0xF4, 0xF7, -+0xB5, 0xF8, 0x59, 0x46, 0x81, 0x46, 0x0A, 0xA8, 0xD2, 0xF7, 0xFA, 0xFC, 0x9D, 0xF8, 0x25, 0x30, 0xD3, 0x46, 0x63, 0xB9, -+0x61, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xAE, 0x80, 0x04, 0x9B, 0x06, 0x9F, 0xAA, 0xEB, -+0x03, 0x0B, 0x1F, 0xFA, 0x8B, 0xFA, 0x4B, 0x46, 0x3A, 0x46, 0x51, 0x46, 0x23, 0xF8, 0x0C, 0xAB, 0x30, 0x46, 0xE6, 0xF7, -+0x35, 0xFD, 0x98, 0xF8, 0x0A, 0x30, 0x89, 0xF8, 0x08, 0x30, 0xBD, 0xF8, 0x16, 0x30, 0x89, 0xF8, 0x07, 0x50, 0xA9, 0xF8, -+0x02, 0x30, 0x94, 0xF9, 0x41, 0x50, 0xD2, 0xF7, 0x75, 0xFD, 0x0A, 0x9B, 0x89, 0xF8, 0x06, 0x30, 0x1A, 0x0C, 0x89, 0xF8, -+0x09, 0x50, 0xA9, 0xF8, 0x04, 0x20, 0x48, 0x46, 0xF4, 0xF7, 0xAE, 0xF8, 0xBD, 0xF8, 0x26, 0x30, 0x04, 0x2B, 0x10, 0xD1, -+0xE1, 0x6B, 0xB9, 0xF8, 0x04, 0x30, 0x62, 0x6B, 0x07, 0x98, 0xC1, 0xF3, 0x03, 0x11, 0x02, 0x91, 0x99, 0xF9, 0x09, 0x10, -+0x01, 0x91, 0x99, 0xF8, 0x06, 0x10, 0x00, 0x91, 0x59, 0x46, 0x07, 0xF0, 0x15, 0xFB, 0x00, 0x20, 0x0D, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0x0D, 0x46, 0xD2, 0xF7, 0x4E, 0xFD, 0xFF, 0x2D, 0x38, 0xD0, 0x3C, 0x4B, 0x1B, 0x7C, 0xFF, 0x2B, 0x31, 0xD0, -+0x99, 0xF8, 0x04, 0x30, 0xDF, 0xF8, 0xEC, 0x80, 0xDA, 0x07, 0x10, 0xD4, 0x98, 0xF8, 0x0A, 0x00, 0x37, 0x4A, 0xB9, 0xF8, -+0x04, 0x10, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x00, 0xF3, 0x5C, 0x33, 0x98, 0x18, 0x9B, 0x5A, 0x8B, 0x42, 0x45, 0xD0, -+0xFF, 0x23, 0x88, 0xF8, 0x0A, 0x30, 0x22, 0x8E, 0x30, 0x48, 0x09, 0xAB, 0x49, 0x46, 0x02, 0xF0, 0x81, 0xFB, 0x83, 0x46, -+0x00, 0x28, 0x3F, 0xF4, 0x50, 0xAF, 0x9D, 0xF8, 0x24, 0x00, 0x00, 0x28, 0x3F, 0xF4, 0x48, 0xAF, 0x2A, 0x4B, 0x20, 0x46, -+0xD3, 0xF8, 0xE4, 0x32, 0x03, 0x21, 0x98, 0x47, 0x9D, 0xF8, 0x24, 0x00, 0x3E, 0xE7, 0x8D, 0xF8, 0x24, 0x00, 0xF0, 0xE7, -+0xDF, 0xF8, 0x8C, 0x80, 0xE1, 0xE7, 0x63, 0x6D, 0x13, 0xF4, 0xC0, 0x6F, 0x1E, 0xD1, 0x1E, 0x4B, 0x9B, 0x68, 0x9B, 0xB3, -+0xB9, 0xF8, 0x04, 0x10, 0x01, 0xE0, 0x1B, 0x68, 0xB3, 0xB1, 0xB3, 0xF8, 0x5C, 0x20, 0x8A, 0x42, 0xF9, 0xD1, 0xB3, 0xF8, -+0x5E, 0x00, 0xB9, 0xF8, 0x06, 0x20, 0x90, 0x42, 0xF3, 0xD1, 0xB3, 0xF8, 0x60, 0x00, 0xB9, 0xF8, 0x08, 0x20, 0x90, 0x42, -+0xED, 0xD1, 0x93, 0xF8, 0x63, 0x30, 0xDF, 0xF8, 0x4C, 0x80, 0x88, 0xF8, 0x0A, 0x30, 0xBE, 0xE7, 0xFF, 0x23, 0xF8, 0xE7, -+0x42, 0x88, 0xB9, 0xF8, 0x06, 0x30, 0x9A, 0x42, 0xB4, 0xD1, 0x82, 0x88, 0xB9, 0xF8, 0x08, 0x30, 0x9A, 0x42, 0xAF, 0xD1, -+0xB1, 0xE7, 0x04, 0x9A, 0x93, 0x07, 0x3F, 0xF4, 0x4E, 0xAF, 0x0A, 0x49, 0x0A, 0x48, 0x40, 0xF6, 0x97, 0x22, 0xF6, 0xF7, -+0xE7, 0xF8, 0x46, 0xE7, 0x2B, 0x46, 0xE0, 0xE7, 0xBA, 0xDE, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0xB0, 0xDE, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xD0, 0xC0, 0x15, 0x00, -+0x1D, 0x48, 0x70, 0xB5, 0x00, 0xF1, 0x10, 0x06, 0xF4, 0xF7, 0x5E, 0xFC, 0x30, 0x46, 0x1B, 0x4C, 0xF4, 0xF7, 0x5A, 0xFC, -+0x04, 0xF5, 0x92, 0x55, 0x21, 0x46, 0x30, 0x46, 0x04, 0xF5, 0x92, 0x74, 0xF4, 0xF7, 0x56, 0xFC, 0xAC, 0x42, 0xF7, 0xD1, -+0x15, 0x48, 0xF4, 0xF7, 0x4D, 0xFC, 0x15, 0x48, 0xF4, 0xF7, 0x4A, 0xFC, 0x14, 0x49, 0x12, 0x48, 0xF4, 0xF7, 0x4A, 0xFC, -+0x13, 0x49, 0x10, 0x48, 0xF4, 0xF7, 0x46, 0xFC, 0x12, 0x49, 0x0E, 0x48, 0xF4, 0xF7, 0x42, 0xFC, 0x11, 0x4A, 0x12, 0x4B, -+0x12, 0x48, 0x4F, 0xF6, 0xFF, 0x71, 0xA2, 0xF8, 0x66, 0x10, 0x03, 0xF5, 0x70, 0x51, 0x00, 0x22, 0x03, 0xF8, 0x34, 0x2C, -+0x1A, 0x81, 0x43, 0xE9, 0x10, 0x03, 0x43, 0xF8, 0x30, 0x3C, 0x50, 0x33, 0x99, 0x42, 0xF5, 0xD1, 0x70, 0xBD, 0x00, 0xBF, -+0xE8, 0xDE, 0x17, 0x00, 0x70, 0xCC, 0x17, 0x00, 0x00, 0xDF, 0x17, 0x00, 0x08, 0xDF, 0x17, 0x00, 0x28, 0xDF, 0x17, 0x00, -+0x6C, 0xDF, 0x17, 0x00, 0xB0, 0xDF, 0x17, 0x00, 0xB0, 0xDE, 0x17, 0x00, 0x24, 0x64, 0x18, 0x00, 0x75, 0xD2, 0x14, 0x00, -+0x70, 0xB5, 0x90, 0xF9, 0x00, 0x30, 0x82, 0xB0, 0x00, 0x2B, 0x01, 0xF0, 0x78, 0x02, 0x05, 0x46, 0xB8, 0xBF, 0x1A, 0x23, -+0x4F, 0xF0, 0x00, 0x00, 0xA8, 0xBF, 0x18, 0x23, 0x08, 0x2A, 0xAD, 0xF8, 0x06, 0x00, 0x19, 0xD0, 0x01, 0xF0, 0x7C, 0x01, -+0x04, 0x29, 0x1F, 0xD0, 0x06, 0x33, 0xDC, 0xB2, 0x2E, 0x19, 0x31, 0x46, 0x02, 0x22, 0x0D, 0xF1, 0x06, 0x00, 0x08, 0xF0, -+0xF3, 0xFA, 0x28, 0x79, 0x10, 0xF0, 0x01, 0x00, 0x0B, 0xD0, 0xBD, 0xF8, 0x06, 0x00, 0xA0, 0xF5, 0xC1, 0x60, 0xB0, 0xFA, -+0x80, 0xF0, 0x40, 0x09, 0x02, 0xB0, 0x70, 0xBD, 0x08, 0x33, 0xDB, 0xB2, 0xE6, 0xE7, 0xBD, 0xF8, 0x06, 0x30, 0x08, 0x2B, -+0x04, 0xD0, 0x01, 0x20, 0x02, 0xB0, 0x70, 0xBD, 0x04, 0x33, 0xDD, 0xE7, 0xF3, 0x7A, 0x02, 0x2B, 0xEE, 0xD0, 0x11, 0x2B, -+0xF5, 0xD1, 0xB2, 0x78, 0xA3, 0x1C, 0x02, 0xF0, 0x0F, 0x04, 0x03, 0xEB, 0x84, 0x04, 0x2C, 0x44, 0x14, 0xF8, 0x04, 0x3C, -+0xEF, 0x2B, 0xEA, 0xD1, 0x14, 0xF8, 0x03, 0x3C, 0xFF, 0x2B, 0xE6, 0xD1, 0x14, 0xF8, 0x02, 0x3C, 0xFF, 0x2B, 0xE2, 0xD1, -+0x14, 0xF8, 0x01, 0x0C, 0xFA, 0x38, 0x18, 0xBF, 0x01, 0x20, 0xD3, 0xE7, 0x70, 0xB5, 0x90, 0xF9, 0x00, 0x30, 0x82, 0xB0, -+0x00, 0x2B, 0x01, 0xF0, 0x78, 0x05, 0x4F, 0xF0, 0x00, 0x06, 0xB4, 0xBF, 0x1A, 0x23, 0x18, 0x23, 0x08, 0x2D, 0x14, 0x46, -+0xAD, 0xF8, 0x06, 0x60, 0x13, 0xD0, 0x01, 0xF0, 0x7C, 0x01, 0x04, 0x29, 0x12, 0xD0, 0x99, 0x1D, 0x50, 0xFA, 0x81, 0xF1, -+0x02, 0x22, 0x0D, 0xF1, 0x06, 0x00, 0x08, 0xF0, 0x9F, 0xFA, 0xBD, 0xF8, 0x06, 0x10, 0x48, 0xF6, 0x88, 0x63, 0x99, 0x42, -+0x06, 0xD0, 0x02, 0xB0, 0x70, 0xBD, 0x08, 0x33, 0xDB, 0xB2, 0xEC, 0xE7, 0x04, 0x33, 0xEA, 0xE7, 0x02, 0x48, 0x22, 0x46, -+0xF5, 0xF7, 0x6E, 0xFD, 0x02, 0xB0, 0x70, 0xBD, 0xEC, 0xC0, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x45, 0x6D, 0x2D, 0xED, -+0x02, 0x8B, 0xAF, 0x04, 0x87, 0xB0, 0x04, 0x46, 0x1F, 0xD4, 0xC1, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x9E, 0x07, 0x03, 0xD5, -+0x05, 0xF0, 0x3C, 0x03, 0x3C, 0x2B, 0x16, 0xD0, 0xBD, 0x4B, 0x1B, 0x7C, 0xFF, 0x2B, 0x71, 0xD0, 0xBC, 0x4E, 0xBD, 0x4D, -+0xB3, 0x72, 0x20, 0x46, 0xD5, 0xF8, 0xE4, 0x32, 0x80, 0x21, 0x98, 0x47, 0x01, 0x27, 0xD5, 0xF8, 0x38, 0x31, 0xB9, 0x48, -+0x98, 0x47, 0x38, 0x46, 0x07, 0xB0, 0xBD, 0xEC, 0x02, 0x8B, 0xBD, 0xE8, 0xF0, 0x8F, 0xD4, 0xF8, 0x1C, 0xA0, 0xB2, 0x4E, -+0xDA, 0xF8, 0x08, 0x80, 0x00, 0x23, 0xB8, 0xF8, 0x00, 0x90, 0x23, 0x66, 0x40, 0x46, 0xFF, 0x23, 0x73, 0x72, 0xB3, 0x72, -+0xFE, 0xF7, 0xE6, 0xFD, 0xA8, 0x01, 0x50, 0xD5, 0xC5, 0xF3, 0xC9, 0x37, 0xDF, 0xF8, 0xBC, 0xB2, 0x10, 0x3F, 0xFF, 0xB2, -+0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x07, 0xB3, 0x93, 0xF8, 0x25, 0x20, 0x00, 0x2A, 0x39, 0xD0, 0x93, 0xF8, 0x22, 0x10, -+0xA5, 0x48, 0xD3, 0xF8, 0xB0, 0x30, 0x77, 0x72, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x01, 0x02, 0xB5, 0x61, 0x92, 0xF8, -+0x62, 0x20, 0xB1, 0x72, 0x02, 0x2A, 0x00, 0x93, 0x52, 0xD0, 0x09, 0xF4, 0x40, 0x73, 0xB3, 0xF5, 0x40, 0x7F, 0x03, 0xD1, -+0x23, 0x6E, 0x43, 0xF0, 0x04, 0x03, 0x23, 0x66, 0x33, 0x88, 0x5B, 0x04, 0x00, 0xF1, 0x90, 0x80, 0x98, 0x4B, 0x1B, 0x68, -+0x1B, 0x78, 0x01, 0x2B, 0x09, 0xF0, 0x0C, 0x03, 0x00, 0xF0, 0x90, 0x80, 0x08, 0x2B, 0x00, 0xF0, 0x97, 0x80, 0x4F, 0xF4, -+0x1E, 0x72, 0x02, 0xFB, 0x07, 0xB2, 0x92, 0xF8, 0x5D, 0x22, 0x01, 0x2A, 0x40, 0xF2, 0xE7, 0x80, 0x04, 0x2B, 0x00, 0xF0, -+0xFA, 0x80, 0x08, 0x2B, 0x00, 0xF0, 0x97, 0x80, 0x00, 0x2B, 0x33, 0xD0, 0x85, 0x4B, 0x1B, 0x7C, 0xFF, 0x2B, 0x01, 0xD0, -+0x85, 0x4D, 0x8F, 0xE7, 0x84, 0x4D, 0x00, 0x27, 0x93, 0xE7, 0x29, 0x46, 0x40, 0x46, 0xFF, 0xF7, 0x9D, 0xFB, 0x19, 0xF0, -+0x0C, 0x0F, 0x0B, 0xD1, 0xFF, 0xF7, 0xDA, 0xF8, 0x00, 0x28, 0xEB, 0xD0, 0x33, 0x88, 0x59, 0x04, 0x55, 0xD5, 0x05, 0xF0, -+0x7C, 0x03, 0x04, 0x2B, 0x4B, 0xD0, 0x40, 0x46, 0x21, 0x46, 0xFF, 0xF7, 0x4D, 0xFB, 0x78, 0x4D, 0x07, 0x46, 0x75, 0x4B, -+0x1B, 0x7C, 0xFF, 0x2B, 0x3F, 0xF4, 0x77, 0xAF, 0x00, 0x2F, 0x7F, 0xF4, 0x74, 0xAF, 0x6B, 0xE7, 0x96, 0xF8, 0x24, 0x30, -+0xDA, 0x07, 0xA8, 0xD4, 0x06, 0xF1, 0x24, 0x00, 0xF2, 0xF7, 0xB8, 0xFE, 0xF0, 0x72, 0xA2, 0xE7, 0x19, 0xF4, 0x00, 0x6F, -+0x00, 0xF0, 0xCF, 0x80, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x07, 0xB3, 0x72, 0x88, 0xB3, 0xF8, 0xE8, 0x31, 0x93, 0x42, -+0xBE, 0xD0, 0x96, 0xF8, 0x30, 0x10, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x07, 0xB7, 0x8D, 0x07, 0xA7, 0xF8, 0xE8, 0x21, -+0x0A, 0xD5, 0x35, 0x6A, 0xD6, 0xE9, 0x04, 0x01, 0xD5, 0xE9, 0x10, 0x23, 0x8B, 0x42, 0x08, 0xBF, 0x82, 0x42, 0xAB, 0xD2, -+0xC5, 0xE9, 0x10, 0x01, 0x5F, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x01, 0x2B, 0x04, 0xD1, 0x98, 0xF8, 0x00, 0x30, 0x80, 0x2B, -+0x00, 0xF0, 0xCF, 0x80, 0x71, 0x7A, 0x57, 0x4D, 0x20, 0x46, 0xFF, 0xF7, 0x17, 0xFD, 0x07, 0x46, 0xB9, 0xE7, 0x29, 0x46, -+0x40, 0x46, 0xFE, 0xF7, 0x39, 0xFB, 0x00, 0x28, 0xAD, 0xD0, 0xFF, 0x21, 0x20, 0x46, 0xFF, 0xF7, 0x0B, 0xFD, 0x4F, 0x4D, -+0x07, 0x46, 0xAC, 0xE7, 0xB1, 0x69, 0x40, 0x46, 0xFE, 0xF7, 0x2C, 0xFB, 0x00, 0x28, 0x7F, 0xF4, 0x69, 0xAF, 0x83, 0xE7, -+0x08, 0x2B, 0x7F, 0xF4, 0x70, 0xAF, 0x29, 0x46, 0x40, 0x46, 0xFF, 0xF7, 0x73, 0xFE, 0x00, 0x28, 0x3F, 0xF4, 0x7A, 0xAF, -+0x3B, 0x46, 0x22, 0x8E, 0x29, 0x46, 0x40, 0x46, 0xFF, 0xF7, 0xC0, 0xFE, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x07, 0xB3, -+0x93, 0xF8, 0x5D, 0x32, 0x01, 0x2B, 0x40, 0xF2, 0x87, 0x80, 0x41, 0x4B, 0x93, 0xF8, 0x04, 0x31, 0x73, 0xB1, 0xB3, 0x7A, -+0x3C, 0x49, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x03, 0x13, 0x93, 0xF8, 0x62, 0x20, 0x2A, 0xB9, 0xD3, 0xF8, 0x90, 0x21, -+0x92, 0x78, 0x01, 0x2A, 0x00, 0xF0, 0x8D, 0x80, 0x19, 0xF0, 0x40, 0x03, 0x00, 0x93, 0x7F, 0xF4, 0x53, 0xAF, 0x09, 0xF0, -+0x80, 0x03, 0x00, 0x2B, 0x14, 0xBF, 0x4F, 0xF0, 0x01, 0x08, 0x4F, 0xF0, 0x00, 0x08, 0x71, 0xD0, 0x96, 0xF8, 0x30, 0x30, -+0x1A, 0x07, 0x40, 0xF1, 0x9A, 0x80, 0xF2, 0x79, 0x4F, 0xF4, 0x9E, 0x73, 0xF5, 0x32, 0x03, 0xFB, 0x07, 0x23, 0x0B, 0xEB, -+0x43, 0x03, 0x19, 0xF4, 0x00, 0x6F, 0x72, 0x88, 0x03, 0xD0, 0x19, 0x88, 0x91, 0x42, 0x3F, 0xF4, 0x35, 0xAF, 0x1F, 0x49, -+0x1A, 0x80, 0x0B, 0x68, 0x1B, 0x78, 0x9B, 0x07, 0x04, 0xD5, 0x05, 0xF0, 0x3C, 0x05, 0x3C, 0x2D, 0x00, 0xF0, 0x8E, 0x80, -+0x1C, 0x4D, 0x39, 0x46, 0xD5, 0xF8, 0xC4, 0x32, 0x42, 0x46, 0x20, 0x46, 0x98, 0x47, 0x07, 0x46, 0x41, 0xE7, 0x00, 0x9A, -+0x00, 0x2A, 0x3F, 0xF4, 0x15, 0xAF, 0x92, 0xF8, 0x60, 0x20, 0x01, 0x3A, 0x01, 0x2A, 0x3F, 0xF6, 0x0F, 0xAF, 0x19, 0xF4, -+0x80, 0x4F, 0x3F, 0xF4, 0x0B, 0xAF, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x07, 0xB2, 0x02, 0x21, 0x82, 0xF8, 0x5D, 0x12, -+0x02, 0xE7, 0x09, 0xF0, 0xFC, 0x09, 0xB9, 0xF1, 0x84, 0x0F, 0x7F, 0xF4, 0x05, 0xAF, 0x0A, 0x4D, 0x41, 0x46, 0xD5, 0xF8, -+0xD0, 0x32, 0x38, 0x46, 0x98, 0x47, 0x05, 0x4B, 0x1B, 0x7C, 0xFF, 0x2B, 0x7F, 0xF4, 0x90, 0xAE, 0xFF, 0xE6, 0x72, 0x88, -+0x37, 0xE7, 0x00, 0xBF, 0x34, 0x36, 0x17, 0x00, 0x00, 0x88, 0x17, 0x00, 0xB0, 0xDE, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0xE8, 0xDE, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x74, 0x36, 0x17, 0x00, 0x2C, 0x19, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x00, 0x9B, 0x00, 0x2B, 0x3F, 0xF4, 0x75, 0xAF, 0x93, 0xF8, 0x60, 0x30, 0x01, 0x3B, 0x01, 0x2B, 0x3F, 0xF6, 0x6F, 0xAF, -+0x08, 0x23, 0xC0, 0xE7, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x07, 0xB3, 0x03, 0xF5, 0xF4, 0x73, 0x93, 0xE7, 0x98, 0xF8, -+0x01, 0x30, 0x00, 0x2B, 0x7F, 0xF4, 0x2C, 0xAF, 0xCA, 0xE6, 0xD3, 0xF8, 0xCC, 0x21, 0x12, 0xF0, 0x0C, 0x0F, 0x3F, 0xF4, -+0x6D, 0xAF, 0x98, 0xF8, 0x04, 0x20, 0xD0, 0x07, 0x3F, 0xF5, 0x68, 0xAF, 0xE2, 0x6B, 0x12, 0xF0, 0x0C, 0x0F, 0x3F, 0xF4, -+0x63, 0xAF, 0xD3, 0xF8, 0x90, 0x20, 0x01, 0x32, 0xC3, 0xF8, 0x90, 0x20, 0x98, 0xF8, 0x01, 0x20, 0x11, 0x07, 0x7F, 0xF5, -+0x59, 0xAF, 0xD3, 0xF8, 0x94, 0x20, 0x01, 0x32, 0xC3, 0xF8, 0x94, 0x20, 0x52, 0xE7, 0xF1, 0x79, 0x38, 0x46, 0xE9, 0xF7, -+0x33, 0xFB, 0x00, 0x28, 0x3F, 0xF4, 0x5F, 0xAF, 0x61, 0x4D, 0x39, 0x46, 0xD5, 0xF8, 0xD4, 0x32, 0x20, 0x46, 0x98, 0x47, -+0x07, 0x46, 0xBC, 0xE6, 0x33, 0x6A, 0x01, 0x93, 0x93, 0xF8, 0x60, 0x10, 0x01, 0x29, 0x03, 0xF1, 0x64, 0x09, 0x64, 0xD0, -+0x00, 0x29, 0x40, 0xF0, 0x97, 0x80, 0x08, 0xF1, 0x0E, 0x03, 0x5B, 0x00, 0xDA, 0xE9, 0x01, 0x25, 0x58, 0x19, 0x08, 0xEE, -+0x10, 0x0A, 0x00, 0x2A, 0x52, 0xD0, 0xDA, 0xF8, 0x0C, 0x20, 0x20, 0x8E, 0x01, 0x32, 0x52, 0x1B, 0x04, 0x30, 0xD2, 0x1A, -+0xC0, 0x1A, 0x93, 0xB2, 0x82, 0xB2, 0x9A, 0x42, 0x00, 0x92, 0x28, 0xBF, 0x1A, 0x46, 0x15, 0x46, 0x01, 0x29, 0x2F, 0xD0, -+0x00, 0x29, 0x50, 0xD0, 0x03, 0x29, 0x66, 0xD0, 0x18, 0xEE, 0x10, 0x0A, 0x29, 0x46, 0xF3, 0xF7, 0x2F, 0xFB, 0x4F, 0xF0, -+0xFF, 0x33, 0x18, 0xEE, 0x10, 0x0A, 0x03, 0x22, 0x29, 0x46, 0xD6, 0xF7, 0x29, 0xFF, 0xDA, 0xF8, 0x04, 0x30, 0x23, 0xB1, -+0x00, 0x9A, 0x55, 0x1B, 0xAD, 0xB2, 0x00, 0x2D, 0x67, 0xD1, 0x01, 0x9B, 0x93, 0xF8, 0x60, 0x30, 0x13, 0xB1, 0x03, 0x2B, -+0x7F, 0xF4, 0x2C, 0xAF, 0x03, 0x20, 0xD6, 0xF7, 0x4F, 0xFF, 0x3A, 0x4B, 0x98, 0x42, 0x01, 0x46, 0x3F, 0xD1, 0x63, 0x6D, -+0x23, 0xF0, 0x7C, 0x03, 0x43, 0xF4, 0x00, 0x53, 0x43, 0xF0, 0x04, 0x03, 0x63, 0x65, 0x1B, 0xE7, 0x4F, 0xF4, 0x1E, 0x72, -+0x02, 0xFB, 0x07, 0xB2, 0x02, 0xAB, 0x32, 0x49, 0x26, 0x32, 0x48, 0x46, 0xF3, 0xF7, 0xDA, 0xF8, 0x10, 0x21, 0x02, 0xA8, -+0xF3, 0xF7, 0x9A, 0xFA, 0x01, 0x9B, 0x93, 0xF8, 0x60, 0x10, 0xBD, 0xE7, 0x22, 0x8E, 0x04, 0x32, 0xD3, 0x1A, 0x9D, 0xB2, -+0xB6, 0xE7, 0xD6, 0xE9, 0x04, 0x53, 0x28, 0x48, 0x2A, 0x0C, 0x42, 0xEA, 0x03, 0x42, 0x08, 0xF1, 0x10, 0x03, 0x02, 0x60, -+0x85, 0x80, 0x5B, 0x00, 0x94, 0xE7, 0x32, 0x8A, 0x73, 0x8A, 0xAD, 0xF8, 0x08, 0x20, 0x49, 0x46, 0x05, 0x22, 0x0D, 0xF1, -+0x0B, 0x00, 0x8D, 0xF8, 0x0A, 0x30, 0x08, 0xF0, 0x1F, 0xF8, 0x08, 0x21, 0x02, 0xA8, 0xF3, 0xF7, 0x75, 0xFA, 0x01, 0x9B, -+0x93, 0xF8, 0x60, 0x10, 0x9A, 0xE7, 0x1A, 0x48, 0xF5, 0xF7, 0xF4, 0xFA, 0x0A, 0xE6, 0x32, 0x8A, 0x73, 0x8A, 0xAD, 0xF8, -+0x08, 0x20, 0x49, 0x46, 0x0D, 0x22, 0x0D, 0xF1, 0x0B, 0x00, 0x8D, 0xF8, 0x0A, 0x30, 0x08, 0xF0, 0x07, 0xF8, 0x02, 0xA8, -+0x10, 0x21, 0xF3, 0xF7, 0x5D, 0xFA, 0x87, 0xE7, 0x03, 0x29, 0x3F, 0xF4, 0x66, 0xAF, 0x00, 0x23, 0x66, 0xE7, 0xD3, 0xF8, -+0x08, 0x90, 0x29, 0x46, 0x48, 0x46, 0xF3, 0xF7, 0xB1, 0xFA, 0x03, 0x20, 0xD6, 0xF7, 0xE8, 0xFE, 0x20, 0x21, 0xC0, 0x43, -+0xF3, 0xF7, 0x64, 0xF8, 0x29, 0x46, 0x03, 0x46, 0x03, 0x22, 0x48, 0x46, 0xD6, 0xF7, 0xA6, 0xFE, 0x83, 0xE7, 0x00, 0xBF, -+0x88, 0x1A, 0x17, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x88, 0x34, 0x17, 0x00, 0x00, 0xC1, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x41, -+0x00, 0xEB, 0x81, 0x04, 0xD4, 0xF8, 0x7C, 0x61, 0x16, 0xB1, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x15, 0x48, 0x0D, 0x46, -+0x17, 0x46, 0xF4, 0xF7, 0x1B, 0xF9, 0x80, 0x46, 0x00, 0x28, 0xF4, 0xD0, 0x31, 0x46, 0x4F, 0xF4, 0x92, 0x72, 0xD1, 0xF7, -+0x3B, 0xF8, 0x07, 0xF0, 0x3F, 0x02, 0x0F, 0x4B, 0x88, 0xF8, 0x0C, 0x50, 0x88, 0xF8, 0x0A, 0x20, 0x19, 0x69, 0x0D, 0x4B, -+0xC8, 0xF8, 0x04, 0x10, 0xD3, 0xF8, 0xDC, 0x22, 0xA8, 0xF8, 0x08, 0x70, 0xC8, 0xE9, 0x45, 0x28, 0x01, 0xF5, 0x43, 0x41, -+0xC4, 0xF8, 0x7C, 0x81, 0x08, 0xF5, 0x88, 0x70, 0xD3, 0xF8, 0xE0, 0x31, 0x50, 0x31, 0x98, 0x47, 0x01, 0x20, 0xBD, 0xE8, -+0xF0, 0x81, 0x00, 0xBF, 0xF8, 0xDE, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x88, 0x1A, 0x17, 0x00, 0x38, 0xB5, 0x10, 0x4B, -+0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0xEB, 0x81, 0x04, 0x00, 0x2B, 0xD4, 0xF8, 0x7C, 0x51, 0x0D, 0xDB, 0x0C, 0x4B, -+0x05, 0xF5, 0x88, 0x70, 0xD3, 0xF8, 0xD8, 0x31, 0x98, 0x47, 0x0A, 0x48, 0x29, 0x46, 0xF4, 0xF7, 0x95, 0xF8, 0x00, 0x23, -+0xC4, 0xF8, 0x7C, 0x31, 0x38, 0xBD, 0x00, 0x2D, 0xEF, 0xD1, 0x06, 0x49, 0x06, 0x48, 0x40, 0xF6, 0x7F, 0x52, 0xF5, 0xF7, -+0xDD, 0xFC, 0xE8, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xF8, 0xDE, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x10, 0xC1, 0x15, 0x00, 0x08, 0x4B, 0x93, 0xF8, 0x73, 0x20, 0x62, 0xB9, 0x02, 0x88, 0xA3, 0xF8, 0x6C, 0x20, 0x42, 0x88, -+0xA3, 0xF8, 0x6E, 0x20, 0x82, 0x88, 0xA3, 0xF8, 0x70, 0x20, 0x4F, 0xF4, 0x80, 0x72, 0xA3, 0xF8, 0x72, 0x20, 0x70, 0x47, -+0xB0, 0xDE, 0x17, 0x00, 0x03, 0x4B, 0x00, 0x22, 0x93, 0xF8, 0x72, 0x00, 0xA3, 0xF8, 0x72, 0x20, 0x70, 0x47, 0x00, 0xBF, -+0xB0, 0xDE, 0x17, 0x00, 0x10, 0xB5, 0x4F, 0xF4, 0x00, 0x10, 0xF3, 0xF7, 0xDD, 0xFF, 0x03, 0x4B, 0x03, 0x48, 0xD3, 0xF8, -+0x38, 0x31, 0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0x88, 0x1A, 0x17, 0x00, 0xE8, 0xDE, 0x17, 0x00, 0x06, 0x4B, 0x07, 0x4A, -+0x93, 0xF8, 0x44, 0x30, 0x03, 0xEB, 0x83, 0x03, 0x02, 0xEB, 0x03, 0x13, 0xB3, 0xF8, 0x4C, 0x00, 0xB0, 0xFA, 0x80, 0xF0, -+0x40, 0x09, 0x70, 0x47, 0xB0, 0xDE, 0x17, 0x00, 0xE0, 0x63, 0x18, 0x00, 0xF8, 0xB5, 0x55, 0x4F, 0x46, 0x7F, 0x05, 0x7F, -+0x54, 0x4A, 0x4F, 0xF4, 0x1E, 0x74, 0x04, 0xFB, 0x06, 0x74, 0xD4, 0xE9, 0x2C, 0xC3, 0x4F, 0xF4, 0xA4, 0x6E, 0x0E, 0xFB, -+0x05, 0x25, 0x1B, 0x68, 0xD5, 0xF8, 0xA8, 0xE4, 0x00, 0x22, 0x0A, 0x60, 0x4B, 0xB3, 0xBE, 0xF1, 0x00, 0x0F, 0x26, 0xD0, -+0xD5, 0xF8, 0xB0, 0x54, 0xAA, 0x07, 0x06, 0xD5, 0x05, 0x8B, 0xB4, 0xF8, 0x34, 0xE0, 0x6C, 0xBA, 0xA4, 0xB2, 0xA6, 0x45, -+0x1B, 0xD0, 0xBC, 0xF1, 0x00, 0x0F, 0x04, 0xD0, 0x9C, 0xF8, 0x60, 0x20, 0x01, 0x3A, 0x01, 0x2A, 0x1C, 0xD9, 0x93, 0xF8, -+0x60, 0x20, 0x04, 0x2A, 0x04, 0xD8, 0xDF, 0xE8, 0x02, 0xF0, 0x10, 0x20, 0x27, 0x10, 0x3C, 0x00, 0x3D, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x04, 0xDA, 0x3B, 0x49, 0x3C, 0x48, 0xC4, 0x22, 0xF5, 0xF7, 0x53, 0xFC, 0x00, 0x20, -+0xF8, 0xBD, 0xC2, 0x8B, 0x04, 0x24, 0xD5, 0x07, 0x0C, 0x60, 0x54, 0xD5, 0x20, 0x46, 0xF8, 0xBD, 0x4F, 0xF4, 0x1E, 0x72, -+0x02, 0xFB, 0x06, 0x76, 0x96, 0xF8, 0x5D, 0x22, 0x01, 0x2A, 0xDA, 0xD8, 0xED, 0xE7, 0xC2, 0x8B, 0x0C, 0x24, 0x0C, 0x60, -+0xD4, 0x07, 0x35, 0xD5, 0x08, 0x20, 0xF8, 0xBD, 0xC2, 0x8B, 0x08, 0x24, 0x0C, 0x60, 0xD1, 0x07, 0xF8, 0xD4, 0xD3, 0xE9, -+0x12, 0x21, 0x01, 0x32, 0x41, 0xF1, 0x00, 0x01, 0x16, 0x46, 0x0F, 0x46, 0x19, 0x46, 0xE1, 0xE9, 0x12, 0x67, 0x06, 0x22, -+0x38, 0x30, 0x07, 0xF0, 0xCD, 0xFE, 0x20, 0x46, 0xF8, 0xBD, 0xC2, 0x8B, 0x10, 0x24, 0xD2, 0x07, 0x0C, 0x60, 0x13, 0xD4, -+0x93, 0xF8, 0x62, 0x20, 0x0F, 0x2A, 0xD3, 0xE9, 0x12, 0x21, 0x0F, 0xD9, 0x02, 0x32, 0x41, 0xF1, 0x00, 0x01, 0x14, 0x46, -+0x0D, 0x46, 0x19, 0x46, 0xE1, 0xE9, 0x12, 0x45, 0x08, 0x22, 0x38, 0x30, 0x07, 0xF0, 0xB4, 0xFE, 0x12, 0x20, 0xF8, 0xBD, -+0x12, 0x20, 0xF8, 0xBD, 0x01, 0x32, 0x41, 0xF1, 0x00, 0x01, 0xEE, 0xE7, 0xD3, 0xE9, 0x12, 0x21, 0x01, 0x32, 0x41, 0xF1, -+0x00, 0x01, 0x14, 0x46, 0x0D, 0x46, 0x19, 0x46, 0xE1, 0xE9, 0x12, 0x45, 0x06, 0x22, 0x38, 0x30, 0x07, 0xF0, 0x9E, 0xFE, -+0xBA, 0xE7, 0xD3, 0xE9, 0x12, 0x21, 0x01, 0x32, 0x41, 0xF1, 0x00, 0x01, 0x16, 0x46, 0x0F, 0x46, 0x19, 0x46, 0xE1, 0xE9, -+0x12, 0x67, 0x22, 0x46, 0x38, 0x30, 0x07, 0xF0, 0x8F, 0xFE, 0x20, 0x46, 0xF8, 0xBD, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0xF0, 0xB5, 0xC3, 0x8B, -+0x04, 0x46, 0xD8, 0x07, 0x83, 0xB0, 0x44, 0xD4, 0xE0, 0x7E, 0x66, 0x7F, 0x22, 0x7F, 0xFF, 0x28, 0x44, 0xD0, 0x4F, 0xF4, -+0x9E, 0x71, 0x01, 0xFB, 0x06, 0x01, 0x21, 0x48, 0x98, 0x31, 0x00, 0xEB, 0x41, 0x01, 0x1A, 0x25, 0x8F, 0x88, 0x78, 0x1C, -+0xC0, 0xF3, 0x0B, 0x00, 0x88, 0x80, 0x27, 0x84, 0xD9, 0x05, 0x1C, 0x4B, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x02, 0x33, -+0x48, 0xBF, 0x06, 0x35, 0x93, 0xF8, 0x62, 0x30, 0x43, 0xB9, 0x16, 0x4B, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x06, 0x36, -+0x73, 0x68, 0x9B, 0x06, 0x48, 0xBF, 0x04, 0x35, 0x01, 0xA9, 0x84, 0xF8, 0x32, 0x50, 0x20, 0x46, 0xFF, 0xF7, 0x16, 0xFF, -+0x23, 0x8B, 0xA2, 0x88, 0x22, 0x86, 0x5B, 0xBA, 0x9B, 0xB2, 0xB3, 0xF5, 0xC0, 0x6F, 0x28, 0x44, 0x88, 0xBF, 0x08, 0x30, -+0xC0, 0xB2, 0x01, 0x9B, 0x84, 0xF8, 0x33, 0x00, 0x8C, 0xBF, 0x08, 0x21, 0x00, 0x21, 0x84, 0xF8, 0x42, 0x00, 0x84, 0xF8, -+0x34, 0x10, 0x84, 0xF8, 0x35, 0x30, 0x00, 0x23, 0xC4, 0xE9, 0x09, 0x33, 0x03, 0xB0, 0xF0, 0xBD, 0x18, 0x25, 0xC7, 0xE7, -+0x68, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x90, 0xF8, 0x1D, 0xA0, 0xDF, 0xF8, 0x58, 0x92, -+0x90, 0xF8, 0x1C, 0x80, 0x92, 0x4F, 0x4F, 0xF4, 0x1E, 0x76, 0x06, 0xFB, 0x0A, 0xF6, 0x09, 0xEB, 0x06, 0x02, 0x4F, 0xF4, -+0xA4, 0x64, 0x04, 0xFB, 0x08, 0x74, 0xD2, 0xF8, 0xB4, 0x30, 0x94, 0xF8, 0x62, 0xC0, 0xD3, 0xF8, 0x00, 0xB0, 0xD2, 0xF8, -+0xB0, 0x30, 0x83, 0xB0, 0x05, 0x46, 0x01, 0x93, 0xD4, 0xF8, 0xA8, 0x34, 0x00, 0x93, 0x0C, 0x46, 0xBC, 0xF1, 0x00, 0x0F, -+0x40, 0xF0, 0x8D, 0x80, 0x53, 0x68, 0x13, 0xF0, 0x20, 0x03, 0x40, 0xF0, 0x9F, 0x80, 0xE9, 0x7E, 0xB5, 0xF8, 0x1E, 0xC0, -+0xFF, 0x29, 0x0C, 0xBF, 0xA4, 0xF1, 0x18, 0x00, 0xA4, 0xF1, 0x1A, 0x00, 0x1C, 0xF4, 0x80, 0x72, 0x1D, 0xBF, 0x06, 0x38, -+0x00, 0xF1, 0x1E, 0x04, 0x02, 0x46, 0x00, 0xF1, 0x18, 0x04, 0xFF, 0x29, 0x00, 0xF0, 0x94, 0x80, 0x6F, 0xF0, 0x7F, 0x0C, -+0x4F, 0xF0, 0x00, 0x0E, 0x80, 0xF8, 0x00, 0xC0, 0x80, 0xF8, 0x01, 0xE0, 0x21, 0x80, 0x29, 0x8C, 0xB5, 0xF8, 0x1E, 0xC0, -+0x09, 0x01, 0x1C, 0xF4, 0x00, 0x7F, 0xC1, 0x82, 0x63, 0xD1, 0x01, 0x88, 0x0B, 0x43, 0x43, 0xF0, 0x08, 0x01, 0x1C, 0xF4, -+0x00, 0x6F, 0x01, 0x80, 0x69, 0xD0, 0x23, 0xF4, 0x40, 0x71, 0x41, 0xF0, 0x08, 0x01, 0x89, 0xB2, 0x01, 0x80, 0x4F, 0xF4, -+0xA4, 0x64, 0x1C, 0xF0, 0x04, 0x0F, 0x04, 0xFB, 0x08, 0xF4, 0x18, 0xBF, 0x41, 0xF4, 0x00, 0x51, 0x04, 0xF1, 0x5C, 0x03, -+0x18, 0xBF, 0x01, 0x80, 0x07, 0xEB, 0x03, 0x0C, 0xFB, 0x5A, 0x43, 0x81, 0xBC, 0xF8, 0x02, 0x30, 0x83, 0x81, 0x01, 0xF4, -+0x40, 0x71, 0xBC, 0xF8, 0x04, 0x30, 0xC3, 0x81, 0xB1, 0xF5, 0x80, 0x7F, 0x5C, 0xD0, 0xB1, 0xF5, 0x00, 0x7F, 0x76, 0xD0, -+0x00, 0x29, 0x40, 0xF0, 0x81, 0x80, 0xAB, 0x89, 0x83, 0x80, 0xEB, 0x89, 0xC3, 0x80, 0x2B, 0x8A, 0x03, 0x81, 0x04, 0xF5, -+0xB2, 0x74, 0x3B, 0x5B, 0x03, 0x82, 0x3C, 0x44, 0x63, 0x88, 0x43, 0x82, 0xA3, 0x88, 0x83, 0x82, 0xBB, 0xF1, 0x00, 0x0F, -+0x1C, 0xD0, 0x00, 0x9B, 0xD3, 0xB1, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x08, 0x77, 0xD7, 0xF8, 0xB0, 0x34, 0x9B, 0x07, -+0x0A, 0xD5, 0x6A, 0x7F, 0x2B, 0x8B, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x02, 0x92, 0x5B, 0xBA, 0x92, 0x8E, 0x9B, 0xB2, -+0x9A, 0x42, 0x07, 0xD0, 0x01, 0x9B, 0x00, 0x2B, 0x7B, 0xD0, 0x93, 0xF8, 0x60, 0x30, 0x01, 0x3B, 0x01, 0x2B, 0x6E, 0xD9, -+0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x23, 0x75, 0xE7, 0x21, 0x88, 0x41, 0xF0, 0x10, 0x01, 0x21, 0x80, 0x01, 0x88, -+0xB5, 0xF8, 0x1E, 0xC0, 0x0B, 0x43, 0x43, 0xF0, 0x08, 0x01, 0x1C, 0xF4, 0x00, 0x6F, 0x01, 0x80, 0x95, 0xD1, 0x1C, 0xF4, -+0x80, 0x7F, 0x22, 0xD0, 0x43, 0xF4, 0x42, 0x71, 0x01, 0x80, 0x94, 0xE7, 0x32, 0x4B, 0x11, 0x46, 0xD3, 0xF8, 0xB8, 0x33, -+0x98, 0x47, 0x4F, 0xF4, 0x00, 0x43, 0x44, 0xF8, 0x04, 0x0D, 0x56, 0xE7, 0x00, 0x21, 0x81, 0x75, 0xC1, 0x75, 0x7A, 0xE7, -+0x26, 0x36, 0x09, 0xEB, 0x06, 0x03, 0x39, 0xF8, 0x06, 0x20, 0x82, 0x80, 0x5A, 0x88, 0xC2, 0x80, 0x9B, 0x88, 0x03, 0x81, -+0xAB, 0x89, 0x03, 0x82, 0xEB, 0x89, 0x43, 0x82, 0x2B, 0x8A, 0x83, 0x82, 0xA6, 0xE7, 0x4F, 0xF4, 0xA4, 0x64, 0x04, 0xFB, -+0x08, 0x74, 0x94, 0xF8, 0x62, 0x40, 0x00, 0x2C, 0x27, 0xD1, 0x43, 0xF4, 0x84, 0x71, 0x01, 0x80, 0x69, 0xE7, 0xAB, 0x89, -+0x83, 0x80, 0xEB, 0x89, 0xC3, 0x80, 0x2B, 0x8A, 0x03, 0x81, 0x6B, 0x8A, 0x03, 0x82, 0xAB, 0x8A, 0x43, 0x82, 0xEB, 0x8A, -+0x83, 0x82, 0x8D, 0xE7, 0x26, 0x36, 0x09, 0xEB, 0x06, 0x03, 0x39, 0xF8, 0x06, 0x10, 0x91, 0x80, 0x59, 0x88, 0xD1, 0x80, -+0x9B, 0x88, 0x13, 0x81, 0xAB, 0x89, 0x13, 0x82, 0xEB, 0x89, 0x53, 0x82, 0x2B, 0x8A, 0x93, 0x82, 0x6B, 0x8A, 0x13, 0x83, -+0xAB, 0x8A, 0x53, 0x83, 0xEB, 0x8A, 0x93, 0x83, 0x76, 0xE7, 0x02, 0x2C, 0x04, 0xBF, 0x43, 0xF4, 0x02, 0x71, 0x01, 0x80, -+0x3F, 0xE7, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x0A, 0x99, 0x99, 0xF8, 0x5D, 0x32, 0x01, 0x2B, 0x88, 0xD9, 0x03, 0x88, -+0x43, 0xF4, 0x80, 0x43, 0x03, 0x80, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, -+0x68, 0x65, 0x17, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x06, 0x46, 0x54, 0x48, 0x75, 0x7F, 0x34, 0x7F, 0x4F, 0xF4, 0x1E, 0x73, -+0x03, 0xFB, 0x05, 0x03, 0x89, 0x46, 0xD3, 0xF8, 0xB4, 0x70, 0xD7, 0xF8, 0x00, 0x80, 0xB8, 0xF1, 0x00, 0x0F, 0x4C, 0xD0, -+0x17, 0x46, 0x4D, 0x4A, 0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x04, 0x24, 0xD4, 0xF8, 0xA8, 0x24, 0x00, 0x2A, 0x42, 0xD0, -+0xD4, 0xF8, 0xB0, 0x24, 0x92, 0x07, 0x05, 0xD5, 0x32, 0x8B, 0x99, 0x8E, 0x53, 0xBA, 0x9B, 0xB2, 0x99, 0x42, 0x38, 0xD0, -+0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x05, 0x05, 0xD5, 0xF8, 0xB0, 0x30, 0x23, 0xB1, 0x93, 0xF8, 0x60, 0x30, 0x01, 0x3B, -+0x01, 0x2B, 0x40, 0xD9, 0x98, 0xF8, 0x60, 0x30, 0x04, 0x2B, 0x67, 0xD8, 0xDF, 0xE8, 0x03, 0xF0, 0x2A, 0x03, 0x40, 0x2A, -+0x49, 0x00, 0x32, 0x8F, 0x42, 0xF4, 0x00, 0x53, 0x03, 0xF4, 0xFE, 0x43, 0x43, 0xEA, 0x12, 0x23, 0x29, 0xF8, 0x08, 0x3C, -+0x96, 0xF8, 0x38, 0x30, 0x98, 0xF8, 0x61, 0x20, 0xA9, 0xF1, 0x08, 0x09, 0x43, 0xEA, 0x82, 0x33, 0x43, 0xF4, 0x00, 0x53, -+0xA9, 0xF8, 0x02, 0x30, 0x73, 0x8F, 0xA9, 0xF8, 0x04, 0x30, 0xB3, 0x8F, 0xA9, 0xF8, 0x06, 0x30, 0xC7, 0xB1, 0xF2, 0x6A, -+0xD4, 0x68, 0x2B, 0x4B, 0x98, 0xF8, 0x62, 0x00, 0x23, 0x40, 0x03, 0x43, 0xD3, 0x60, 0x48, 0x46, 0xBD, 0xE8, 0xF8, 0x83, -+0x33, 0x8F, 0x29, 0xF8, 0x04, 0x3C, 0x98, 0xF8, 0x61, 0x20, 0x73, 0x8F, 0xA9, 0xF1, 0x04, 0x09, 0x43, 0xEA, 0x82, 0x33, -+0xA9, 0xF8, 0x02, 0x30, 0x00, 0x2F, 0xE6, 0xD1, 0xB2, 0x6C, 0x28, 0x32, 0xE4, 0xE7, 0x95, 0xF8, 0x5D, 0x32, 0x01, 0x2B, -+0xBA, 0xD8, 0xE6, 0xE7, 0x33, 0x8F, 0x29, 0xF8, 0x08, 0x3C, 0x98, 0xF8, 0x61, 0x30, 0xA9, 0xF1, 0x08, 0x09, 0x9B, 0x03, -+0xCA, 0xE7, 0x98, 0xF8, 0x61, 0x30, 0x29, 0xF8, 0x12, 0x3C, 0xA9, 0xF1, 0x12, 0x09, 0x33, 0x8F, 0xA9, 0xF8, 0x02, 0x30, -+0x73, 0x8F, 0xA9, 0xF8, 0x04, 0x30, 0xB3, 0x8F, 0xA9, 0xF8, 0x06, 0x30, 0xF3, 0x8F, 0xA9, 0xF8, 0x08, 0x30, 0x45, 0xF6, -+0x36, 0x43, 0xA9, 0xF8, 0x0A, 0x30, 0xA9, 0xF8, 0x0C, 0x30, 0xA9, 0xF8, 0x0E, 0x30, 0xA9, 0xF8, 0x10, 0x30, 0xB7, 0xE7, -+0x09, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xB1, 0xDA, 0x07, 0x49, 0x08, 0x48, 0x40, 0xF2, 0xD9, 0x22, -+0xF5, 0xF7, 0xA8, 0xF9, 0xAA, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x00, 0xFC, 0x0F, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x70, 0xB5, 0x1A, 0x4D, 0x1A, 0x4E, 0xD5, 0xF8, -+0x68, 0x32, 0x04, 0x46, 0x98, 0x47, 0x60, 0x7F, 0xD5, 0xF8, 0x5C, 0x31, 0x4F, 0xF4, 0x1E, 0x75, 0x05, 0xFB, 0x00, 0x60, -+0x98, 0x47, 0xE3, 0x8B, 0xE0, 0x62, 0x99, 0x04, 0x11, 0xD5, 0x63, 0x7F, 0x05, 0xFB, 0x03, 0x66, 0xD6, 0xF8, 0x4C, 0x31, -+0xD3, 0xF8, 0x9C, 0x20, 0xA2, 0x62, 0x93, 0xF8, 0xA1, 0x30, 0x2B, 0xB1, 0x94, 0xF8, 0x36, 0x30, 0x43, 0xF0, 0x20, 0x03, -+0x84, 0xF8, 0x36, 0x30, 0x70, 0xBD, 0x94, 0xF8, 0x36, 0x30, 0x03, 0xF0, 0x03, 0x02, 0x00, 0xEB, 0x82, 0x00, 0x42, 0x6A, -+0x41, 0x69, 0xA1, 0x62, 0x52, 0x03, 0x44, 0xBF, 0x43, 0xF0, 0x20, 0x03, 0x84, 0xF8, 0x36, 0x30, 0x70, 0xBD, 0x00, 0xBF, -+0x88, 0x1A, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0xF0, 0xB5, 0x83, 0xB0, 0xC3, 0x7E, 0x00, 0x93, 0x04, 0x46, 0xC3, 0x8B, -+0x0F, 0x46, 0x16, 0x46, 0x16, 0x49, 0x02, 0x8C, 0x20, 0x20, 0xF4, 0xF7, 0x29, 0xFF, 0xE3, 0x8B, 0xD9, 0x07, 0x1E, 0xD5, -+0x13, 0x48, 0xF4, 0xF7, 0xD3, 0xFE, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x03, 0xD4, 0x72, 0xB6, 0x10, 0x4B, 0x01, 0x22, -+0x1A, 0x60, 0x10, 0x4D, 0x2B, 0x68, 0x3A, 0x46, 0x01, 0x33, 0x31, 0x46, 0x20, 0x46, 0x2B, 0x60, 0xDF, 0xF7, 0x4A, 0xFD, -+0x2B, 0x68, 0x33, 0xB1, 0x09, 0x4A, 0x01, 0x3B, 0x12, 0x68, 0x2B, 0x60, 0x0B, 0xB9, 0x02, 0xB1, 0x62, 0xB6, 0x03, 0xB0, -+0xF0, 0xBD, 0xDF, 0xF7, 0x61, 0xF9, 0xE3, 0x8B, 0xDA, 0x07, 0xDB, 0xD4, 0xDD, 0xE7, 0x00, 0xBF, 0x3C, 0xC1, 0x15, 0x00, -+0x58, 0xC1, 0x15, 0x00, 0x38, 0x61, 0x17, 0x00, 0x6C, 0x28, 0x17, 0x00, 0x02, 0x8B, 0x53, 0xBA, 0x9B, 0xB2, 0xB3, 0xF5, -+0xC0, 0x6F, 0x10, 0xB5, 0x04, 0x46, 0x08, 0xD3, 0x4A, 0xF6, 0xAA, 0x23, 0x21, 0xF8, 0x08, 0x3D, 0x03, 0x20, 0x00, 0x23, -+0xCA, 0x80, 0x48, 0x80, 0x8B, 0x80, 0x20, 0x46, 0x01, 0x22, 0xFF, 0xF7, 0xBB, 0xFE, 0x04, 0x4B, 0x01, 0x46, 0xD3, 0xF8, -+0x20, 0x34, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x18, 0x47, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0xC5, 0x8B, 0xDF, 0xF8, 0x7C, 0x82, 0x07, 0x7F, 0x4F, 0xF4, 0xA4, 0x6A, 0x0E, 0x46, 0x29, 0x07, 0x83, 0xB0, 0x04, 0x46, -+0x0A, 0xFB, 0x07, 0x8A, 0x6B, 0xD4, 0x41, 0x7F, 0xDF, 0xF8, 0x64, 0xB2, 0x03, 0x8B, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, -+0x01, 0xB1, 0x5B, 0xBA, 0x88, 0x8E, 0x91, 0xF8, 0x30, 0x20, 0x9B, 0xB2, 0x98, 0x42, 0x0F, 0xD0, 0x02, 0x2A, 0x16, 0xD0, -+0x8B, 0x49, 0x20, 0x20, 0xF4, 0xF7, 0xB4, 0xFE, 0x20, 0x46, 0x31, 0x46, 0x4F, 0xF0, 0x00, 0x42, 0xFF, 0xF7, 0x78, 0xFF, -+0x00, 0x20, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x01, 0x3A, 0x25, 0xF4, 0x80, 0x75, 0x01, 0x2A, 0xE5, 0x83, 0x02, 0xD9, -+0x91, 0xF8, 0x30, 0x20, 0xE8, 0xE7, 0xDF, 0xF8, 0x1C, 0x92, 0x20, 0x46, 0xD9, 0xF8, 0x2C, 0x34, 0x98, 0x47, 0x63, 0x7F, -+0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, 0x03, 0xBB, 0x9B, 0xF8, 0x30, 0x30, 0x02, 0x2B, 0x00, 0xF0, 0xA2, 0x80, 0x4F, 0xF4, -+0xA4, 0x63, 0x03, 0xFB, 0x07, 0x87, 0x77, 0x4A, 0x3B, 0x6C, 0x77, 0x49, 0x1F, 0x79, 0x77, 0x4B, 0x00, 0x2F, 0x0C, 0xBF, -+0x0F, 0x46, 0x17, 0x46, 0xE7, 0x62, 0x7D, 0x69, 0x93, 0xF8, 0xBD, 0x20, 0xC5, 0xF3, 0xC2, 0x28, 0xED, 0xB2, 0x00, 0x2A, -+0x40, 0xF0, 0xB4, 0x80, 0xD9, 0xF8, 0x38, 0x33, 0x50, 0x46, 0x01, 0xAA, 0x0D, 0xF1, 0x03, 0x01, 0x98, 0x47, 0x05, 0xF0, -+0x7C, 0x03, 0x58, 0xEA, 0x03, 0x03, 0x0C, 0xBF, 0x9D, 0xF8, 0x03, 0x30, 0x9D, 0xF8, 0x04, 0x30, 0x43, 0xEA, 0x03, 0x23, -+0x7B, 0x62, 0xE3, 0x8B, 0xDB, 0x07, 0x4C, 0xD4, 0xA1, 0x6C, 0xD9, 0xF8, 0x1C, 0x34, 0xA8, 0x31, 0x20, 0x46, 0x98, 0x47, -+0x45, 0xE0, 0x00, 0x23, 0xEA, 0x06, 0x01, 0x93, 0x5B, 0xD5, 0x5D, 0x4B, 0xE3, 0x62, 0x15, 0xF0, 0x80, 0x05, 0x7D, 0xD1, -+0xA8, 0x46, 0xDF, 0xF8, 0x80, 0x91, 0x5B, 0x4F, 0xD9, 0xF8, 0x38, 0x33, 0x50, 0x46, 0x0D, 0xF1, 0x03, 0x02, 0x0D, 0xF1, -+0x02, 0x01, 0x98, 0x47, 0xE2, 0x6A, 0x4F, 0xF0, 0x00, 0x0A, 0xA3, 0x68, 0x02, 0xEB, 0x8A, 0x00, 0x23, 0xF0, 0x60, 0x41, -+0x13, 0xF0, 0x80, 0x4F, 0x41, 0xF0, 0x00, 0x51, 0x14, 0xBF, 0x41, 0x61, 0x43, 0x69, 0x97, 0xF8, 0xBD, 0x10, 0xC3, 0xF3, -+0xC2, 0x20, 0x03, 0xF0, 0x7F, 0x03, 0x51, 0xBB, 0x08, 0xBB, 0x03, 0x2B, 0x02, 0xEB, 0x8A, 0x01, 0x1D, 0xD8, 0x9D, 0xF8, -+0x02, 0x30, 0x43, 0xEA, 0x03, 0x23, 0x4B, 0x62, 0x0A, 0xF1, 0x01, 0x0A, 0xBA, 0xF1, 0x04, 0x0F, 0xDD, 0xD1, 0x00, 0x23, -+0xC4, 0xE9, 0x09, 0x33, 0x01, 0x9A, 0x84, 0xF8, 0x32, 0x80, 0x84, 0xF8, 0x33, 0x50, 0x84, 0xF8, 0x42, 0x50, 0x84, 0xF8, -+0x35, 0x20, 0xD9, 0xF8, 0x94, 0x33, 0x31, 0x46, 0x20, 0x46, 0x98, 0x47, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x9D, 0xF8, -+0x03, 0x30, 0x02, 0xEB, 0x8A, 0x01, 0x43, 0xEA, 0x03, 0x23, 0x4B, 0x62, 0xDE, 0xE7, 0x19, 0x46, 0xD1, 0xF7, 0xF0, 0xFD, -+0xE2, 0x6A, 0x02, 0xEB, 0x8A, 0x03, 0x40, 0xEA, 0x00, 0x20, 0x58, 0x62, 0xD4, 0xE7, 0x9A, 0xF8, 0xC0, 0x34, 0x00, 0x2B, -+0x9F, 0xD1, 0xDA, 0xF8, 0x40, 0x20, 0x2D, 0x4B, 0x11, 0x79, 0x2B, 0x4A, 0x00, 0x29, 0x18, 0xBF, 0x13, 0x46, 0xC3, 0x62, -+0x97, 0xE7, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x07, 0x83, 0x93, 0xF8, 0x62, 0x20, 0x52, 0xB3, 0x02, 0x2A, 0x04, 0xD1, -+0x9B, 0xF8, 0x70, 0x32, 0x00, 0x2B, 0x7F, 0xF4, 0x50, 0xAF, 0x24, 0x4B, 0x1B, 0x78, 0x1B, 0xB9, 0xD9, 0xF8, 0x1C, 0x30, -+0x20, 0x46, 0x98, 0x47, 0x20, 0x46, 0xFF, 0xF7, 0x67, 0xFE, 0x6E, 0xE7, 0x00, 0x22, 0xC0, 0x21, 0x20, 0x46, 0x01, 0xF0, -+0x1D, 0xFB, 0x01, 0x28, 0x1C, 0xD0, 0x02, 0x28, 0x15, 0xD0, 0xE3, 0x8B, 0x00, 0x25, 0x23, 0xF0, 0x80, 0x03, 0xE3, 0x83, -+0xA8, 0x46, 0x72, 0xE7, 0x05, 0xF0, 0x7F, 0x01, 0x40, 0x46, 0xD1, 0xF7, 0xAD, 0xFD, 0x40, 0xEA, 0x00, 0x20, 0x78, 0x62, -+0x55, 0xE7, 0x93, 0xF8, 0xAC, 0x30, 0x00, 0x2B, 0x7F, 0xF4, 0x27, 0xAF, 0xD5, 0xE7, 0x12, 0x23, 0x00, 0x25, 0x01, 0x93, -+0xA8, 0x46, 0x5E, 0xE7, 0x01, 0xA9, 0x20, 0x46, 0xFF, 0xF7, 0x46, 0xFB, 0xA3, 0x6C, 0x05, 0x46, 0x03, 0xF1, 0xA8, 0x01, -+0x03, 0xF1, 0xA0, 0x00, 0x18, 0x22, 0x07, 0xF0, 0x75, 0xFA, 0xED, 0xB2, 0x4F, 0xF0, 0x18, 0x08, 0x4D, 0xE7, 0x00, 0xBF, -+0x70, 0xC1, 0x15, 0x00, 0x84, 0x3C, 0x18, 0x00, 0xC4, 0x3C, 0x18, 0x00, 0x2C, 0x19, 0x17, 0x00, 0xB8, 0x34, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x51, 0x4A, 0x43, 0x7F, -+0x4F, 0xF4, 0x1E, 0x75, 0x05, 0xFB, 0x03, 0x23, 0x86, 0xB0, 0xD3, 0xF8, 0xB4, 0x30, 0x1E, 0x68, 0x8E, 0xB1, 0x90, 0xF8, -+0x35, 0x30, 0x04, 0x46, 0x6B, 0xB1, 0x90, 0xF8, 0x34, 0x30, 0x85, 0x6C, 0x96, 0xF8, 0x60, 0x20, 0xED, 0x1A, 0x01, 0x2A, -+0x05, 0xF1, 0xA8, 0x05, 0x06, 0xD0, 0x03, 0x2A, 0x51, 0xD0, 0x00, 0x2A, 0x4F, 0xD0, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, -+0x07, 0x8E, 0x42, 0x4A, 0x00, 0x91, 0x3B, 0x44, 0x06, 0xF1, 0x50, 0x01, 0xD2, 0xF8, 0x7C, 0x73, 0x2A, 0x46, 0xB8, 0x47, -+0x3E, 0x4B, 0x1B, 0x68, 0x1B, 0x78, 0x9A, 0x07, 0xED, 0xD5, 0x96, 0xF8, 0x60, 0x20, 0x01, 0x2A, 0x06, 0xF1, 0x64, 0x08, -+0x3E, 0xD1, 0x23, 0x8E, 0x94, 0xF8, 0x34, 0x70, 0x0C, 0x33, 0x1F, 0x44, 0xBF, 0xB2, 0x39, 0x1F, 0x4F, 0xF0, 0xFF, 0x33, -+0x03, 0x22, 0x28, 0x46, 0xD6, 0xF7, 0xD8, 0xF8, 0xD6, 0xE9, 0x12, 0x03, 0x32, 0x49, 0x94, 0xF8, 0x1C, 0xC0, 0x88, 0x80, -+0x31, 0x4A, 0x00, 0x0C, 0x4F, 0xF4, 0xA4, 0x6E, 0x40, 0xEA, 0x03, 0x40, 0x0E, 0xFB, 0x0C, 0x22, 0x08, 0x60, 0x02, 0xAB, -+0x40, 0x46, 0xF2, 0xF7, 0x9F, 0xFA, 0x02, 0xA8, 0x10, 0x21, 0xF2, 0xF7, 0x5F, 0xFC, 0x96, 0xF8, 0x60, 0x20, 0xCA, 0xB1, -+0x03, 0x2A, 0x17, 0xD0, 0x03, 0x20, 0xD6, 0xF7, 0xF1, 0xF8, 0x39, 0x46, 0x02, 0x46, 0x28, 0x46, 0xF2, 0xF7, 0x84, 0xFA, -+0x39, 0x46, 0x28, 0x46, 0xF2, 0xF7, 0x7A, 0xFC, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x1D, 0x4B, 0x1B, 0x68, 0x1B, 0x78, -+0x9B, 0x07, 0xAA, 0xD5, 0x06, 0xF1, 0x64, 0x08, 0x00, 0x27, 0xE4, 0xE7, 0x23, 0x8E, 0x94, 0xF8, 0x34, 0x70, 0x04, 0x33, -+0x1F, 0x44, 0xBF, 0xB2, 0x39, 0x1F, 0x4F, 0xF0, 0xFF, 0x33, 0x03, 0x22, 0x28, 0x46, 0xD6, 0xF7, 0x97, 0xF8, 0x96, 0xF8, -+0x60, 0x30, 0xB6, 0xF8, 0x48, 0x10, 0xB6, 0xF8, 0x4A, 0x20, 0xAD, 0xF8, 0x08, 0x10, 0x8D, 0xF8, 0x0A, 0x20, 0x41, 0x46, -+0x4B, 0xB9, 0x05, 0x22, 0x0D, 0xF1, 0x0B, 0x00, 0x07, 0xF0, 0xCA, 0xF9, 0x02, 0xA8, 0x08, 0x21, 0xF2, 0xF7, 0x20, 0xFC, -+0xC4, 0xE7, 0x0D, 0x22, 0x0D, 0xF1, 0x0B, 0x00, 0x07, 0xF0, 0xC0, 0xF9, 0x02, 0xA8, 0x10, 0x21, 0xF2, 0xF7, 0x16, 0xFC, -+0xBA, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x34, 0x36, 0x17, 0x00, 0xA0, 0x34, 0x17, 0x00, -+0x74, 0x88, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0xC5, 0x6C, 0xC3, 0x8B, 0x2F, 0x69, 0x02, 0x8C, 0x2A, 0x81, 0x00, 0x26, -+0x13, 0xF0, 0x08, 0x02, 0x2E, 0x61, 0x04, 0x46, 0x07, 0xF4, 0x00, 0x06, 0x88, 0x46, 0x07, 0xF0, 0x40, 0x47, 0x1C, 0xD0, -+0x99, 0x06, 0x01, 0xD5, 0x00, 0x2E, 0x6C, 0xD0, 0x9A, 0x05, 0x3E, 0xD4, 0xB7, 0xF1, 0x40, 0x4F, 0x20, 0xD0, 0xE3, 0x7E, -+0xFF, 0x2B, 0x22, 0xD1, 0x2B, 0x69, 0x62, 0x6A, 0x01, 0x20, 0x02, 0xF4, 0x00, 0x12, 0x16, 0xB1, 0x43, 0xF0, 0x08, 0x03, -+0x2B, 0x61, 0x00, 0x2A, 0x47, 0xD0, 0x43, 0xF0, 0x01, 0x03, 0x28, 0x73, 0x2B, 0x61, 0xBD, 0xE8, 0xF0, 0x81, 0x9B, 0x05, -+0xE6, 0xD5, 0x43, 0x7F, 0x2A, 0x49, 0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, 0x03, 0x13, 0xB7, 0xF1, 0x40, 0x4F, 0x83, 0xF8, -+0x32, 0x20, 0xDE, 0xD1, 0x2B, 0x69, 0x43, 0xF0, 0x04, 0x03, 0x2B, 0x61, 0xDD, 0xE7, 0x31, 0x1E, 0x42, 0x46, 0x18, 0xBF, -+0x01, 0x21, 0x20, 0x46, 0x01, 0xF0, 0x3A, 0xF8, 0x63, 0x6A, 0x13, 0xF4, 0x00, 0x12, 0x20, 0xD0, 0x03, 0xF4, 0x60, 0x13, -+0xB3, 0xF5, 0x60, 0x1F, 0x01, 0xD0, 0x00, 0x23, 0x6B, 0x73, 0x2B, 0x69, 0x00, 0x2E, 0xD2, 0xD0, 0xCC, 0xE7, 0x19, 0x4B, -+0x60, 0x7F, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x1A, 0xDB, 0x00, 0x23, 0x1A, 0x46, 0x17, 0x21, 0xE0, 0xF7, -+0x0D, 0xFA, 0x12, 0x4A, 0x63, 0x7F, 0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x03, 0x23, 0x00, 0x22, 0x83, 0xF8, 0x32, 0x20, -+0xAA, 0xE7, 0x2B, 0x69, 0x0E, 0xB1, 0x43, 0xF0, 0x08, 0x03, 0x01, 0x22, 0x43, 0xF0, 0x01, 0x03, 0x6A, 0x73, 0x28, 0x73, -+0x2B, 0x61, 0xBD, 0xE8, 0xF0, 0x81, 0xFF, 0x28, 0xE2, 0xD1, 0x08, 0x48, 0x08, 0x49, 0x4F, 0xF4, 0xA4, 0x62, 0xF4, 0xF7, -+0x89, 0xFE, 0x60, 0x7F, 0xDA, 0xE7, 0xFF, 0xF7, 0xC7, 0xF9, 0xE3, 0x8B, 0x8E, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x84, 0xC1, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, 0x70, 0xB5, 0x90, 0xF8, 0x33, 0x30, 0x82, 0xB0, -+0x04, 0x46, 0x0D, 0x46, 0x16, 0x46, 0x7B, 0xB1, 0x90, 0xF8, 0x35, 0x20, 0x01, 0x92, 0x18, 0x46, 0x2B, 0x88, 0x2E, 0x44, -+0x43, 0xF4, 0x80, 0x43, 0x31, 0x18, 0x2B, 0x80, 0x20, 0x46, 0x00, 0x22, 0xFF, 0xF7, 0x12, 0xFC, 0x02, 0xB0, 0x70, 0xBD, -+0x01, 0xA9, 0xFF, 0xF7, 0xCD, 0xF9, 0x01, 0x9B, 0x84, 0xF8, 0x33, 0x00, 0x84, 0xF8, 0x35, 0x30, 0xEA, 0xE7, 0x00, 0xBF, -+0x10, 0xB4, 0x0C, 0x88, 0x0B, 0x46, 0x44, 0xF4, 0x80, 0x44, 0x11, 0x44, 0x1C, 0x80, 0x00, 0x22, 0x5D, 0xF8, 0x04, 0x4B, -+0xFF, 0xF7, 0xFA, 0xBB, 0xF0, 0xB5, 0x00, 0x22, 0x18, 0x4C, 0x85, 0xB0, 0x05, 0x46, 0x0F, 0x46, 0x02, 0xE0, 0x01, 0x32, -+0x20, 0x2A, 0x26, 0xD0, 0xA5, 0x42, 0x96, 0xB2, 0x04, 0xF1, 0x18, 0x04, 0xF7, 0xD1, 0x12, 0x02, 0x02, 0xF4, 0x7F, 0x42, -+0x42, 0xF0, 0x08, 0x00, 0xF2, 0xF7, 0xF6, 0xFF, 0x04, 0x28, 0x18, 0xD1, 0x17, 0xF4, 0x00, 0x03, 0x02, 0xD1, 0xEA, 0x7C, -+0x02, 0x2A, 0x06, 0xD9, 0x28, 0x7B, 0x31, 0x46, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0xF0, 0x65, 0xBC, 0x08, 0x49, -+0x01, 0x32, 0xEA, 0x74, 0x27, 0x22, 0xCD, 0xE9, 0x01, 0x21, 0x00, 0x93, 0x28, 0x7B, 0x02, 0x22, 0x29, 0x46, 0x00, 0xF0, -+0xBB, 0xFC, 0x05, 0xB0, 0xF0, 0xBD, 0x00, 0xBF, 0xF4, 0xE4, 0x17, 0x00, 0xE5, 0xFE, 0x14, 0x00, 0x2D, 0xE9, 0xF0, 0x43, -+0x10, 0x46, 0x85, 0xB0, 0x14, 0x46, 0x0F, 0x46, 0xF2, 0xF7, 0xCC, 0xFF, 0x03, 0x28, 0x09, 0xD0, 0x50, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x72, 0xDB, 0x00, 0x20, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x4C, 0x4E, 0x4F, 0xEA, -+0x14, 0x28, 0x08, 0xEB, 0x48, 0x03, 0x06, 0xEB, 0xC3, 0x06, 0x96, 0xF8, 0x0D, 0x90, 0xB9, 0xF1, 0x00, 0x0F, 0x39, 0xD0, -+0xB9, 0xF1, 0x01, 0x0F, 0x29, 0xD1, 0xBB, 0x78, 0x00, 0x2B, 0x7C, 0xD1, 0x05, 0x46, 0x30, 0x46, 0x96, 0xF8, 0x0F, 0x90, -+0x00, 0xF0, 0xA0, 0xFF, 0x41, 0x4B, 0x1B, 0x69, 0x73, 0x60, 0x05, 0x22, 0x2B, 0x46, 0x0C, 0x21, 0x41, 0xF2, 0x0B, 0x40, -+0x3D, 0x78, 0x7F, 0x78, 0xF2, 0xF7, 0xFA, 0xFC, 0xA9, 0xF1, 0x04, 0x09, 0x4F, 0xFA, 0x89, 0xF9, 0x80, 0xF8, 0x02, 0x90, -+0x05, 0x70, 0x47, 0x70, 0xF2, 0xF7, 0x20, 0xFD, 0x73, 0x89, 0x00, 0x2B, 0x39, 0xD1, 0x20, 0x46, 0x01, 0x21, 0xF2, 0xF7, -+0xE3, 0xFE, 0x00, 0x20, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x2F, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0xBC, 0xDA, 0x2F, 0x49, 0x2F, 0x48, 0x40, 0xF2, 0x29, 0x12, 0xF4, 0xF7, 0xD3, 0xFD, 0xB5, 0xE7, 0xBA, 0x78, 0x33, 0x7C, -+0x72, 0xBB, 0xB0, 0x7B, 0xF1, 0x7B, 0x02, 0x92, 0x9B, 0x00, 0x43, 0xEA, 0x40, 0x03, 0x43, 0xEA, 0x81, 0x13, 0xCD, 0xE9, -+0x00, 0x32, 0x31, 0x46, 0x73, 0x7C, 0x30, 0x7B, 0x01, 0x22, 0x00, 0xF0, 0x47, 0xFC, 0x3B, 0x78, 0x7D, 0x78, 0x23, 0x4A, -+0x1F, 0x48, 0x71, 0x89, 0x03, 0xEB, 0x83, 0x07, 0xC3, 0xEB, 0x07, 0x13, 0x2B, 0x44, 0x02, 0xEB, 0xC3, 0x03, 0x83, 0xF8, -+0xA4, 0x81, 0x03, 0x69, 0x73, 0x60, 0x00, 0x29, 0xC5, 0xD0, 0x40, 0x46, 0x00, 0xF0, 0x9A, 0xFB, 0xC1, 0xE7, 0x17, 0x49, -+0x17, 0x48, 0xC8, 0x22, 0xF4, 0xF7, 0xA4, 0xFD, 0x00, 0x20, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0xB1, 0x7B, 0xF2, 0x7B, -+0xCD, 0xF8, 0x08, 0x90, 0x9B, 0x00, 0x43, 0xEA, 0x41, 0x03, 0x43, 0xEA, 0x82, 0x13, 0x25, 0x22, 0xCD, 0xE9, 0x00, 0x32, -+0x31, 0x46, 0x30, 0x7B, 0x73, 0x7C, 0x01, 0x22, 0x00, 0xF0, 0x16, 0xFC, 0x49, 0x46, 0x20, 0x46, 0xF2, 0xF7, 0x8A, 0xFE, -+0x6C, 0xE7, 0x40, 0x46, 0x00, 0xF0, 0xF8, 0xFA, 0x20, 0x46, 0x00, 0x21, 0xF2, 0xF7, 0x82, 0xFE, 0x64, 0xE7, 0x00, 0xBF, -+0x38, 0x36, 0x17, 0x00, 0xF4, 0xE4, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, -+0x68, 0x65, 0x17, 0x00, 0xF8, 0xB5, 0x8B, 0x78, 0x02, 0x2B, 0x01, 0xD0, 0x00, 0x20, 0xF8, 0xBD, 0x02, 0xF4, 0x7F, 0x40, -+0x40, 0xF0, 0x08, 0x00, 0x0C, 0x46, 0x15, 0x0A, 0xF2, 0xF7, 0x0E, 0xFF, 0x04, 0x28, 0xF3, 0xD1, 0x11, 0x4E, 0x05, 0xEB, -+0x45, 0x03, 0x06, 0xEB, 0xC3, 0x06, 0x73, 0x7B, 0x01, 0x2B, 0x04, 0xD0, 0x0E, 0x4B, 0x28, 0x46, 0x9B, 0x6A, 0x98, 0x47, -+0xE6, 0xE7, 0x70, 0x69, 0x00, 0xF0, 0x1E, 0xFF, 0xF3, 0x7B, 0x67, 0x78, 0x26, 0x78, 0xC3, 0xF1, 0x04, 0x03, 0x1C, 0x18, -+0x05, 0x22, 0x03, 0x23, 0x0C, 0x21, 0x41, 0xF2, 0x0B, 0x40, 0xF2, 0xF7, 0x4D, 0xFC, 0x64, 0xB2, 0x84, 0x70, 0x06, 0x70, -+0x47, 0x70, 0xF2, 0xF7, 0x77, 0xFC, 0xE3, 0xE7, 0xF4, 0xE4, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0xB7, 0x4F, 0xCE, 0x79, 0xB7, 0x4A, 0x4F, 0xF4, 0x1E, 0x75, 0x05, 0xFB, 0x06, 0x75, 0x0C, 0x46, 0x95, 0xF8, 0x22, 0x30, -+0x4F, 0xF4, 0xA4, 0x61, 0x01, 0xFB, 0x03, 0x23, 0x85, 0xB0, 0x93, 0xF8, 0x64, 0x30, 0x1B, 0xB9, 0x00, 0x20, 0x05, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0x06, 0x20, 0x94, 0xF8, 0x0D, 0x80, 0xF2, 0xF7, 0xC7, 0xFE, 0x09, 0x28, 0x04, 0xF1, 0x0C, 0x09, -+0xF2, 0xD0, 0xB8, 0xF1, 0x01, 0x0F, 0x5B, 0xD0, 0xB8, 0xF1, 0x02, 0x0F, 0x1B, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0xE9, 0xD1, -+0xB9, 0xF8, 0x03, 0x80, 0x99, 0xF8, 0x02, 0xB0, 0xC8, 0xF3, 0x83, 0x0A, 0xBA, 0xF1, 0x08, 0x0F, 0x04, 0xD8, 0xA1, 0x4B, -+0x1B, 0x78, 0x00, 0x2B, 0x00, 0xF0, 0x87, 0x80, 0x25, 0x23, 0x00, 0x21, 0xCD, 0xE9, 0x00, 0x83, 0x30, 0x46, 0x5B, 0x46, -+0x02, 0x91, 0x01, 0x22, 0x00, 0xF0, 0x82, 0xFB, 0xD0, 0xE7, 0xB9, 0xF8, 0x02, 0x10, 0xB1, 0xF5, 0x10, 0x4F, 0x4F, 0xEA, -+0x11, 0x35, 0xC9, 0xD2, 0xE3, 0x79, 0xFF, 0x2B, 0xC6, 0xD0, 0x09, 0x05, 0x2A, 0x46, 0x40, 0xF1, 0xBA, 0x80, 0x93, 0x49, -+0x4F, 0xF4, 0x00, 0x60, 0xF4, 0xF7, 0xA4, 0xFA, 0xE3, 0x79, 0x03, 0xEB, 0x83, 0x02, 0xC3, 0xEB, 0x02, 0x13, 0x2B, 0x44, -+0x07, 0xEB, 0xC3, 0x07, 0x97, 0xF8, 0xA4, 0x51, 0x21, 0x2D, 0xB1, 0xD0, 0x2E, 0x02, 0x46, 0xF0, 0x08, 0x06, 0x30, 0x46, -+0xF2, 0xF7, 0x7C, 0xFE, 0x04, 0x28, 0xA9, 0xD0, 0x31, 0x46, 0x42, 0xF2, 0x01, 0x00, 0xF2, 0xF7, 0xE1, 0xFA, 0x30, 0x46, -+0xF2, 0xF7, 0x72, 0xFE, 0x01, 0x28, 0x00, 0xF0, 0xD2, 0x80, 0x30, 0x46, 0xF2, 0xF7, 0x6C, 0xFE, 0x03, 0x28, 0x00, 0xF0, -+0xCC, 0x80, 0x7F, 0x4B, 0x28, 0x46, 0x9B, 0x6A, 0x98, 0x47, 0x93, 0xE7, 0xB9, 0xF8, 0x05, 0x50, 0xC5, 0xF3, 0x83, 0x06, -+0x08, 0x2E, 0x8D, 0xD8, 0xE3, 0x79, 0x7A, 0x49, 0x03, 0xEB, 0x83, 0x02, 0xC3, 0xEB, 0x02, 0x13, 0x33, 0x44, 0x07, 0xEB, -+0xC3, 0x07, 0x32, 0x46, 0x97, 0xF8, 0xA5, 0x71, 0x4F, 0xF4, 0x00, 0x60, 0x3B, 0x46, 0xF4, 0xF7, 0x63, 0xFA, 0x21, 0x2F, -+0x3F, 0xF4, 0x7A, 0xAF, 0x4F, 0xEA, 0x07, 0x28, 0x48, 0xF0, 0x08, 0x08, 0x40, 0x46, 0xF2, 0xF7, 0x43, 0xFE, 0x02, 0x28, -+0x7F, 0xF4, 0x70, 0xAF, 0x41, 0x46, 0x4F, 0xF4, 0x00, 0x50, 0xF2, 0xF7, 0xA7, 0xFA, 0x6A, 0x4A, 0x99, 0xF8, 0x02, 0x10, -+0x07, 0xEB, 0x47, 0x03, 0x02, 0xEB, 0xC3, 0x03, 0x58, 0x7C, 0x88, 0x42, 0x03, 0xD1, 0x1B, 0x7C, 0xB3, 0x42, 0x00, 0xF0, -+0x9B, 0x80, 0x38, 0x46, 0x00, 0xF0, 0xF4, 0xF9, 0x40, 0x46, 0x00, 0x21, 0xF2, 0xF7, 0x7E, 0xFD, 0x54, 0xE7, 0x60, 0x49, -+0x4F, 0xF4, 0x00, 0x60, 0x52, 0x46, 0xF4, 0xF7, 0x35, 0xFA, 0x51, 0x46, 0x30, 0x46, 0xE8, 0xF7, 0x85, 0xF9, 0x00, 0x28, -+0x4F, 0xD1, 0x95, 0xF8, 0x24, 0x30, 0x01, 0x2B, 0x3F, 0xF4, 0x68, 0xAF, 0x00, 0xF0, 0x04, 0xFA, 0x21, 0x28, 0x04, 0x46, -+0x3F, 0xF4, 0x62, 0xAF, 0x53, 0x4D, 0x55, 0x4A, 0x00, 0xEB, 0x40, 0x01, 0x05, 0xEB, 0xC1, 0x03, 0xC8, 0xF3, 0x40, 0x00, -+0x12, 0x68, 0x83, 0xF8, 0x10, 0xA0, 0x00, 0x27, 0x1E, 0x73, 0x83, 0xF8, 0x11, 0xB0, 0x98, 0x73, 0x5F, 0x73, 0x90, 0x6B, -+0xB9, 0xF8, 0x05, 0x20, 0x5A, 0x81, 0x4F, 0xEA, 0x98, 0x18, 0x80, 0x45, 0x28, 0xBF, 0x80, 0x46, 0x83, 0xF8, 0x0F, 0x80, -+0xB9, 0xF8, 0x07, 0x00, 0xC9, 0x00, 0x00, 0x09, 0x92, 0xB2, 0x6F, 0x50, 0x18, 0x81, 0x1A, 0xB9, 0x44, 0x4A, 0x12, 0x68, -+0x52, 0x88, 0x5A, 0x81, 0x30, 0x46, 0x21, 0x46, 0x00, 0xF0, 0x3C, 0xFA, 0x20, 0x02, 0x00, 0xF4, 0x7F, 0x40, 0x40, 0xF0, -+0x08, 0x00, 0x03, 0x21, 0xF2, 0xF7, 0x32, 0xFD, 0x08, 0xE7, 0x3D, 0x49, 0x4F, 0xF4, 0x00, 0x60, 0xF4, 0xF7, 0xEA, 0xF9, -+0xE3, 0x79, 0x03, 0xEB, 0x83, 0x02, 0xC3, 0xEB, 0x02, 0x13, 0x2B, 0x44, 0x07, 0xEB, 0xC3, 0x07, 0x97, 0xF8, 0xA5, 0x51, -+0x44, 0xE7, 0x06, 0xEB, 0x86, 0x03, 0xC6, 0xEB, 0x03, 0x13, 0x53, 0x44, 0x07, 0xEB, 0xC3, 0x07, 0x97, 0xF8, 0xA4, 0x71, -+0x3D, 0x02, 0x45, 0xF0, 0x08, 0x05, 0x28, 0x46, 0xF2, 0xF7, 0xBA, 0xFD, 0x01, 0x28, 0x7F, 0xF4, 0x0B, 0xAF, 0x2A, 0x4B, -+0x27, 0x4A, 0x1B, 0x68, 0x07, 0xEB, 0x47, 0x01, 0x02, 0xEB, 0xC1, 0x02, 0x99, 0x6B, 0xD2, 0x7B, 0x4F, 0xEA, 0x98, 0x13, -+0x8B, 0x42, 0x28, 0xBF, 0x0B, 0x46, 0x9A, 0x42, 0x12, 0xD0, 0x28, 0x46, 0x04, 0x21, 0xF2, 0xF7, 0xFB, 0xFC, 0xE0, 0x79, -+0x39, 0x46, 0x00, 0xF0, 0x1D, 0xFA, 0x25, 0x23, 0xF1, 0xE6, 0x30, 0x46, 0x04, 0x21, 0xF2, 0xF7, 0xF1, 0xFC, 0xE0, 0x79, -+0x29, 0x46, 0x00, 0xF0, 0x13, 0xFA, 0xC3, 0xE6, 0x00, 0x23, 0xE6, 0xE6, 0xB9, 0xF8, 0x03, 0x30, 0x00, 0x2B, 0x7F, 0xF4, -+0x60, 0xAF, 0x18, 0x23, 0x03, 0xFB, 0x07, 0x23, 0xA9, 0x09, 0xDB, 0x7B, 0xB3, 0xEB, 0x95, 0x1F, 0x03, 0xD9, 0x18, 0x23, -+0x03, 0xFB, 0x07, 0x23, 0xD9, 0x73, 0x18, 0x23, 0x03, 0xFB, 0x07, 0x22, 0x05, 0xF0, 0x01, 0x05, 0x95, 0x74, 0xE0, 0x79, -+0x39, 0x46, 0x00, 0xF0, 0xD1, 0xF9, 0x40, 0x46, 0x03, 0x21, 0xF2, 0xF7, 0xCB, 0xFC, 0xA1, 0xE6, 0x68, 0x65, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0xB9, 0x34, 0x17, 0x00, 0xE4, 0xC1, 0x15, 0x00, 0x88, 0x1A, 0x17, 0x00, 0xC0, 0xC1, 0x15, 0x00, -+0xF4, 0xE4, 0x17, 0x00, 0xA4, 0xC1, 0x15, 0x00, 0x78, 0x36, 0x17, 0x00, 0xC8, 0x35, 0x17, 0x00, 0x08, 0xC2, 0x15, 0x00, -+0x10, 0xB5, 0x10, 0x46, 0x14, 0x46, 0xF2, 0xF7, 0x57, 0xFD, 0x02, 0x28, 0x01, 0xD0, 0x00, 0x20, 0x10, 0xBD, 0x20, 0x0A, -+0x00, 0xF0, 0x1A, 0xF9, 0x20, 0x46, 0x00, 0x21, 0xF2, 0xF7, 0xA4, 0xFC, 0x00, 0x20, 0x10, 0xBD, 0x70, 0xB5, 0x10, 0x46, -+0x84, 0xB0, 0x14, 0x46, 0xF2, 0xF7, 0x44, 0xFD, 0x01, 0x28, 0x02, 0xD0, 0x00, 0x20, 0x04, 0xB0, 0x70, 0xBD, 0x20, 0x0A, -+0x13, 0x4A, 0x00, 0xEB, 0x40, 0x05, 0x52, 0xF8, 0x35, 0x60, 0x02, 0xEB, 0xC5, 0x05, 0x3E, 0xB9, 0x10, 0x4B, 0x6A, 0x68, -+0x19, 0x69, 0x6B, 0x89, 0x52, 0x1A, 0x12, 0xEB, 0x83, 0x23, 0x04, 0xD4, 0x00, 0xF0, 0x74, 0xF9, 0x00, 0x20, 0x04, 0xB0, -+0x70, 0xBD, 0x20, 0x46, 0x04, 0x21, 0x2C, 0x7B, 0xF2, 0xF7, 0x7C, 0xFC, 0x08, 0x4B, 0x02, 0x93, 0x27, 0x22, 0x01, 0x92, -+0x00, 0x96, 0x20, 0x46, 0x33, 0x46, 0x29, 0x46, 0x02, 0x22, 0xEE, 0x74, 0x00, 0xF0, 0xF8, 0xF9, 0xD4, 0xE7, 0x00, 0xBF, -+0xF4, 0xE4, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0xE5, 0xFE, 0x14, 0x00, 0x90, 0xF8, 0x46, 0x30, 0x90, 0xF8, 0x47, 0x20, -+0x19, 0x44, 0xB1, 0xFB, 0xF2, 0xF0, 0x02, 0xFB, 0x10, 0x10, 0x70, 0x47, 0x90, 0xF8, 0x46, 0x30, 0x90, 0xF8, 0x48, 0x00, -+0x19, 0x44, 0x08, 0x40, 0x70, 0x47, 0x00, 0xBF, 0x03, 0x4B, 0x1B, 0x69, 0xA0, 0xEB, 0x93, 0x20, 0xC0, 0xF3, 0xC0, 0x30, -+0x70, 0x47, 0x00, 0xBF, 0x00, 0x10, 0x50, 0x40, 0x70, 0xB5, 0x90, 0xF8, 0x46, 0x30, 0x03, 0x44, 0x9A, 0x79, 0x02, 0x2A, -+0x17, 0xD1, 0x00, 0x26, 0x04, 0x46, 0x35, 0x46, 0x9D, 0x71, 0xA3, 0x88, 0x22, 0x68, 0x01, 0x33, 0xC3, 0xF3, 0x0B, 0x03, -+0xA3, 0x80, 0x01, 0x21, 0x20, 0x46, 0x90, 0x47, 0x54, 0xFA, 0x80, 0xF3, 0x84, 0xF8, 0x46, 0x00, 0x9A, 0x79, 0x01, 0x36, -+0x02, 0x2A, 0x76, 0xB2, 0xEC, 0xD0, 0x30, 0x46, 0x70, 0xBD, 0x00, 0x26, 0x30, 0x46, 0x70, 0xBD, 0x38, 0xB5, 0x85, 0x88, -+0x03, 0x68, 0x49, 0x1B, 0xC1, 0xF3, 0x0B, 0x01, 0x04, 0x46, 0x15, 0x46, 0x98, 0x47, 0x20, 0x44, 0x85, 0x71, 0x38, 0xBD, -+0xF8, 0xB5, 0x05, 0x46, 0x33, 0x48, 0x6F, 0x6A, 0x01, 0xEB, 0x41, 0x01, 0x00, 0xEB, 0xC1, 0x00, 0xBF, 0x02, 0x44, 0x69, -+0x03, 0xD5, 0x11, 0x46, 0x4B, 0xB3, 0x00, 0x2A, 0x49, 0xD0, 0xA2, 0x88, 0x29, 0x8C, 0x23, 0x68, 0x89, 0x1A, 0xC1, 0xF3, -+0x0B, 0x01, 0x20, 0x46, 0x98, 0x47, 0x20, 0x44, 0x02, 0x23, 0x83, 0x71, 0x94, 0xF8, 0x46, 0x30, 0x23, 0x44, 0x00, 0x26, -+0x9A, 0x79, 0x02, 0x2A, 0x13, 0xD1, 0x35, 0x46, 0x9D, 0x71, 0xA3, 0x88, 0x22, 0x68, 0x01, 0x33, 0xC3, 0xF3, 0x0B, 0x03, -+0xA3, 0x80, 0x01, 0x21, 0x20, 0x46, 0x90, 0x47, 0x54, 0xFA, 0x80, 0xF3, 0x84, 0xF8, 0x46, 0x00, 0x9A, 0x79, 0x01, 0x36, -+0x02, 0x2A, 0x76, 0xB2, 0xEC, 0xD0, 0x30, 0x46, 0xF8, 0xBD, 0x00, 0x2A, 0xD5, 0xD1, 0x19, 0x4B, 0xB5, 0xF8, 0x40, 0x00, -+0x1B, 0x69, 0xA0, 0xEB, 0x93, 0x23, 0x1B, 0x04, 0xCD, 0xD4, 0xEA, 0x8B, 0xEB, 0x6C, 0x6F, 0xEA, 0x42, 0x42, 0x1C, 0x69, -+0x6F, 0xEA, 0x52, 0x42, 0xEA, 0x83, 0x44, 0xF0, 0x02, 0x04, 0x6A, 0x8F, 0x0E, 0x46, 0x29, 0x8F, 0x19, 0x80, 0x1C, 0x61, -+0xE9, 0x8F, 0xAC, 0x8F, 0x5A, 0x80, 0x2A, 0x8C, 0x1A, 0x81, 0x9C, 0x80, 0xD9, 0x80, 0x58, 0x81, 0xDB, 0xE7, 0x09, 0x48, -+0xB5, 0xF8, 0x40, 0x20, 0x03, 0x69, 0xA2, 0xEB, 0x93, 0x23, 0x1E, 0x04, 0xAD, 0xD4, 0x03, 0x69, 0x05, 0x48, 0xA2, 0xEB, -+0x93, 0x22, 0xC2, 0xF3, 0xC0, 0x32, 0xF4, 0xF7, 0x23, 0xF8, 0xA4, 0xE7, 0xF4, 0xE4, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, -+0x34, 0xC2, 0x15, 0x00, 0xF8, 0xB5, 0x0D, 0x4D, 0x0D, 0x4E, 0xFF, 0x27, 0x2F, 0x73, 0x00, 0x24, 0x08, 0xE0, 0x0F, 0x2C, -+0x85, 0xF8, 0x24, 0x70, 0x03, 0xDD, 0x4C, 0x23, 0x03, 0xFB, 0x04, 0x63, 0xEB, 0x62, 0x18, 0x35, 0x20, 0x02, 0x00, 0xF4, -+0x7F, 0x40, 0x40, 0xF0, 0x08, 0x00, 0x01, 0x34, 0x00, 0x21, 0xF2, 0xF7, 0x95, 0xFB, 0x20, 0x2C, 0xEB, 0xD1, 0xF8, 0xBD, -+0xF4, 0xE4, 0x17, 0x00, 0x74, 0xDB, 0x17, 0x00, 0x11, 0x4B, 0x00, 0xEB, 0x40, 0x00, 0x03, 0xEB, 0xC0, 0x00, 0x42, 0x7B, -+0x03, 0x7B, 0x01, 0x7C, 0x72, 0xB1, 0x01, 0x2A, 0x0B, 0xD1, 0x03, 0xEB, 0x83, 0x02, 0xC3, 0xEB, 0x02, 0x13, 0x0B, 0x4A, -+0x0B, 0x44, 0x02, 0xEB, 0xC3, 0x03, 0x21, 0x22, 0x83, 0xF8, 0xA5, 0x21, 0x70, 0x47, 0x70, 0x47, 0x03, 0xEB, 0x83, 0x02, -+0xC3, 0xEB, 0x02, 0x13, 0x04, 0x4A, 0x0B, 0x44, 0x02, 0xEB, 0xC3, 0x03, 0x21, 0x22, 0x83, 0xF8, 0xA4, 0x21, 0x70, 0x47, -+0xF4, 0xE4, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0x00, 0x28, 0x09, 0x4B, 0x14, 0xBF, 0x10, 0x20, 0x00, 0x20, 0x03, 0xEB, -+0x40, 0x03, 0x14, 0xBF, 0x20, 0x21, 0x10, 0x21, 0x33, 0xF8, 0x02, 0x2F, 0x22, 0xB1, 0x01, 0x30, 0x88, 0x42, 0xF9, 0xDB, -+0x21, 0x20, 0x70, 0x47, 0x80, 0xB2, 0x70, 0x47, 0xF2, 0xDF, 0x17, 0x00, 0x38, 0xB5, 0x05, 0x02, 0x45, 0xF0, 0x08, 0x05, -+0x04, 0x46, 0x29, 0x46, 0x4F, 0xF4, 0x00, 0x50, 0xF2, 0xF7, 0x5A, 0xF8, 0x29, 0x46, 0x42, 0xF2, 0x01, 0x00, 0xF2, 0xF7, -+0x55, 0xF8, 0x16, 0x48, 0x04, 0xEB, 0x44, 0x04, 0x00, 0xEB, 0xC4, 0x04, 0x62, 0x7B, 0x23, 0x7B, 0x21, 0x7C, 0x92, 0xB1, -+0x01, 0x2A, 0x0A, 0xD1, 0x03, 0xEB, 0x83, 0x02, 0xC3, 0xEB, 0x02, 0x13, 0x0F, 0x4A, 0x0B, 0x44, 0x02, 0xEB, 0xC3, 0x03, -+0x21, 0x22, 0x83, 0xF8, 0xA5, 0x21, 0x28, 0x46, 0x00, 0x21, 0xBD, 0xE8, 0x38, 0x40, 0xF2, 0xF7, 0x25, 0xBB, 0x03, 0xEB, -+0x83, 0x02, 0xC3, 0xEB, 0x02, 0x13, 0x07, 0x4A, 0x0B, 0x44, 0x02, 0xEB, 0xC3, 0x03, 0x21, 0x22, 0x83, 0xF8, 0xA4, 0x21, -+0x28, 0x46, 0x00, 0x21, 0xBD, 0xE8, 0x38, 0x40, 0xF2, 0xF7, 0x14, 0xBB, 0xF4, 0xE4, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x07, 0x4B, 0x00, 0xEB, 0x40, 0x02, 0x03, 0xEB, 0xC2, 0x03, 0x00, 0x02, 0x5A, 0x89, 0x00, 0xF4, 0x7F, 0x41, 0x41, 0xF0, -+0x08, 0x01, 0x92, 0x02, 0x42, 0xF2, 0x01, 0x00, 0xF1, 0xF7, 0x64, 0xBF, 0xF4, 0xE4, 0x17, 0x00, 0x0A, 0x02, 0x02, 0xF4, -+0x7F, 0x42, 0x38, 0xB5, 0x42, 0xF0, 0x08, 0x02, 0x05, 0x46, 0x0C, 0x46, 0x06, 0x23, 0x00, 0x21, 0x28, 0x20, 0xF2, 0xF7, -+0xF7, 0xF8, 0x0A, 0x49, 0x04, 0xEB, 0x44, 0x04, 0x01, 0xEB, 0xC4, 0x04, 0x62, 0x7B, 0x45, 0x70, 0x01, 0x3A, 0x18, 0xBF, -+0x01, 0x22, 0x02, 0x70, 0x22, 0x7C, 0x82, 0x70, 0xE2, 0x7B, 0xC2, 0x70, 0x22, 0x89, 0x82, 0x80, 0xBD, 0xE8, 0x38, 0x40, -+0xF2, 0xF7, 0x12, 0xB9, 0xF4, 0xE4, 0x17, 0x00, 0xF8, 0xB5, 0x0D, 0x02, 0x45, 0xF0, 0x08, 0x05, 0xAD, 0xB2, 0x03, 0x23, -+0x0C, 0x46, 0x07, 0x46, 0x2A, 0x46, 0x00, 0x21, 0x2A, 0x20, 0xF2, 0xF7, 0xD3, 0xF8, 0x12, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0x06, 0x46, 0x11, 0xDB, 0x0F, 0x49, 0x04, 0xEB, 0x44, 0x04, 0x01, 0xEB, 0xC4, 0x04, 0x30, 0x46, -+0x63, 0x7B, 0x77, 0x70, 0x01, 0x3B, 0x18, 0xBF, 0x01, 0x23, 0x33, 0x70, 0x23, 0x7C, 0xB3, 0x70, 0xBD, 0xE8, 0xF8, 0x40, -+0xF2, 0xF7, 0xEA, 0xB8, 0x28, 0x46, 0xF2, 0xF7, 0x59, 0xFB, 0x04, 0x28, 0xE8, 0xD0, 0x05, 0x49, 0x05, 0x48, 0x40, 0xF2, -+0x05, 0x22, 0xF4, 0xF7, 0x91, 0xF9, 0xE1, 0xE7, 0x38, 0x36, 0x17, 0x00, 0xF4, 0xE4, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x60, 0xC2, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x10, 0x4E, 0x11, 0x4D, 0x80, 0x46, 0x87, 0xB2, 0x00, 0x24, 0x36, 0xF8, -+0x02, 0x3F, 0x8B, 0xB1, 0x2B, 0x7B, 0x43, 0x45, 0x0E, 0xD1, 0x1F, 0xFA, 0x84, 0xF9, 0x4F, 0xEA, 0x09, 0x23, 0x03, 0xF4, -+0x7F, 0x43, 0x43, 0xF0, 0x08, 0x00, 0x04, 0x21, 0xF2, 0xF7, 0x88, 0xFA, 0x49, 0x46, 0x38, 0x46, 0xFF, 0xF7, 0xAA, 0xFF, -+0x01, 0x34, 0x20, 0x2C, 0x05, 0xF1, 0x18, 0x05, 0xE5, 0xD1, 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0xBF, 0xF2, 0xDF, 0x17, 0x00, -+0xF4, 0xE4, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x8B, 0xB0, 0xDF, 0xF8, 0x50, 0x92, 0xBD, 0xF8, 0x50, 0x40, 0x09, 0x94, -+0xBD, 0xF8, 0x54, 0x40, 0x07, 0x94, 0x16, 0x9C, 0x04, 0x94, 0x4F, 0xF4, 0x1E, 0x74, 0x04, 0xFB, 0x00, 0x94, 0x87, 0x4F, -+0x94, 0xF8, 0x22, 0x80, 0xDF, 0xF8, 0x30, 0xA2, 0x03, 0x91, 0x06, 0x46, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x08, 0x70, -+0x93, 0x46, 0x00, 0x6C, 0x08, 0x93, 0x00, 0x28, 0x00, 0xF0, 0xC4, 0x80, 0xDA, 0xF8, 0x00, 0x30, 0x02, 0x79, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0x9B, 0x80, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x08, 0x73, 0x4F, 0xF4, 0xC0, 0x71, -+0x93, 0xF8, 0xC0, 0x34, 0x13, 0x43, 0x14, 0xBF, 0x01, 0x20, 0x00, 0x20, 0xDF, 0xF7, 0x14, 0xFB, 0x04, 0x46, 0x00, 0x28, -+0x00, 0xF0, 0x9B, 0x80, 0x4F, 0xF4, 0xA4, 0x65, 0x05, 0xFB, 0x08, 0xF5, 0x78, 0x19, 0x21, 0x46, 0x05, 0x90, 0xF1, 0xF7, -+0x05, 0xFC, 0x4F, 0xF4, 0x1E, 0x72, 0xA3, 0x6C, 0x02, 0xFB, 0x06, 0xF2, 0x00, 0x21, 0x26, 0x32, 0x6F, 0xF0, 0x2F, 0x0C, -+0x83, 0xF8, 0x68, 0xC0, 0x83, 0xF8, 0x69, 0x10, 0x83, 0xF8, 0x6A, 0x10, 0x83, 0xF8, 0x6B, 0x10, 0x39, 0xF8, 0x02, 0x10, -+0xA3, 0xF8, 0x6C, 0x10, 0x09, 0xEB, 0x02, 0x01, 0x5C, 0x35, 0xB1, 0xF8, 0x02, 0xC0, 0xA3, 0xF8, 0x6E, 0xC0, 0xB1, 0xF8, -+0x04, 0xC0, 0xA3, 0xF8, 0x70, 0xC0, 0x37, 0xF8, 0x05, 0xC0, 0xA3, 0xF8, 0x72, 0xC0, 0x07, 0xEB, 0x05, 0x0C, 0x03, 0xF1, -+0x68, 0x00, 0xBC, 0xF8, 0x02, 0xE0, 0xA3, 0xF8, 0x74, 0xE0, 0xBC, 0xF8, 0x04, 0xE0, 0x06, 0x90, 0x05, 0x98, 0xA3, 0xF8, -+0x76, 0xE0, 0x90, 0xF8, 0x62, 0x00, 0x02, 0x28, 0x5E, 0xD0, 0x39, 0xF8, 0x02, 0x20, 0xA3, 0xF8, 0x78, 0x20, 0x4A, 0x88, -+0xA3, 0xF8, 0x7A, 0x20, 0x8A, 0x88, 0xA3, 0xF8, 0x7C, 0x20, 0x4E, 0x49, 0xB1, 0xF8, 0xFC, 0x21, 0x01, 0x32, 0x92, 0xB2, -+0xA1, 0xF8, 0xFC, 0x21, 0x10, 0x01, 0x00, 0x21, 0xA3, 0xF8, 0x7E, 0x00, 0x03, 0x22, 0x84, 0xF8, 0x33, 0x10, 0x84, 0xF8, -+0x35, 0x10, 0x84, 0xF8, 0x1C, 0x80, 0x66, 0x77, 0xD0, 0x21, 0x20, 0x46, 0x00, 0xF0, 0xE6, 0xFB, 0x01, 0x28, 0x70, 0xD0, -+0x18, 0x25, 0xBB, 0xF1, 0x01, 0x0F, 0x4A, 0xD0, 0xBB, 0xF1, 0x02, 0x0F, 0x54, 0xD0, 0xBB, 0xF1, 0x00, 0x0F, 0x5C, 0xD0, -+0xDA, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x69, 0xDB, 0x03, 0x26, 0xE1, 0x6C, 0x94, 0xF8, 0x35, 0x30, -+0x4A, 0x6A, 0x1D, 0x44, 0x01, 0x3A, 0x04, 0x9B, 0x2A, 0x44, 0x04, 0x35, 0xC1, 0xE9, 0x0A, 0x25, 0x13, 0xB1, 0x63, 0x65, -+0x03, 0x9B, 0xA3, 0x65, 0x31, 0x46, 0x20, 0x46, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0xDF, 0xF7, 0x97, 0xBA, 0x02, 0x2A, -+0x7F, 0xF4, 0x62, 0xAF, 0x2D, 0x49, 0x2E, 0x48, 0x4F, 0xF4, 0x09, 0x72, 0xF4, 0xF7, 0x92, 0xF8, 0x01, 0x20, 0x4F, 0xF4, -+0xC0, 0x71, 0xDF, 0xF7, 0x79, 0xFA, 0x04, 0x46, 0x00, 0x28, 0x7F, 0xF4, 0x65, 0xAF, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0x7A, 0x5B, 0xA3, 0xF8, 0x78, 0x20, 0xBC, 0xF8, 0x02, 0x20, 0xA3, 0xF8, 0x7A, 0x20, 0xBC, 0xF8, 0x04, 0x20, 0xA3, 0xF8, -+0x7C, 0x20, 0x9E, 0xE7, 0xDA, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xE1, 0xDA, 0xDA, 0xE7, 0x06, 0x99, -+0x07, 0x9B, 0x00, 0x93, 0x29, 0x44, 0x08, 0x46, 0xDD, 0xE9, 0x08, 0x32, 0x03, 0x99, 0xF5, 0xF7, 0x4D, 0xFA, 0x03, 0x26, -+0x05, 0x44, 0xB4, 0xE7, 0xDD, 0xE9, 0x06, 0x02, 0x03, 0x99, 0x15, 0x4E, 0x0B, 0x7C, 0x28, 0x44, 0xF6, 0x5C, 0xF5, 0xF7, -+0x5D, 0xFA, 0x05, 0x44, 0xA9, 0xE7, 0x03, 0x99, 0x06, 0x98, 0x10, 0x4A, 0x0B, 0x7C, 0x28, 0x44, 0xD6, 0x5C, 0xF5, 0xF7, -+0x1B, 0xFA, 0x05, 0x44, 0x9F, 0xE7, 0x06, 0x99, 0x18, 0x22, 0x20, 0x46, 0xFF, 0xF7, 0xD2, 0xF9, 0x94, 0xF8, 0x33, 0x50, -+0x18, 0x35, 0x86, 0xE7, 0x05, 0x49, 0x08, 0x48, 0x40, 0xF2, 0x6E, 0x22, 0xF4, 0xF7, 0x5A, 0xF8, 0x03, 0x26, 0x8E, 0xE7, -+0x18, 0x88, 0x17, 0x00, 0x20, 0x62, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0xFC, 0x90, 0x15, 0x00, 0xC0, 0xB2, 0x15, 0x00, -+0x64, 0x7D, 0x15, 0x00, 0x68, 0x65, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x35, 0x4B, 0x87, 0xB0, -+0x81, 0x46, 0x8A, 0x46, 0x93, 0x46, 0x10, 0x24, 0x33, 0xF8, 0x02, 0x5F, 0x35, 0xB1, 0x01, 0x34, 0x20, 0x2C, 0xF9, 0xD1, -+0x03, 0x20, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x2E, 0x4A, 0xDF, 0xF8, 0xCC, 0x80, 0x04, 0xEB, 0x44, 0x03, 0x02, 0xEB, -+0xC3, 0x06, 0xDB, 0x00, 0x86, 0xF8, 0x0C, 0x90, 0x86, 0xF8, 0x10, 0xA0, 0x05, 0x93, 0x06, 0xF0, 0xBB, 0xFB, 0x28, 0x49, -+0x70, 0x74, 0x09, 0x68, 0x27, 0x48, 0xB1, 0xF8, 0x02, 0xC0, 0x10, 0xF8, 0x0A, 0x00, 0x05, 0x9B, 0x25, 0x49, 0x22, 0x4A, -+0x02, 0x95, 0x09, 0xEB, 0x89, 0x07, 0xC9, 0xEB, 0x07, 0x17, 0x57, 0x44, 0x00, 0x95, 0x34, 0x37, 0x51, 0xF8, 0x20, 0xE0, -+0xD5, 0x50, 0x08, 0xEB, 0xC7, 0x00, 0x27, 0x23, 0x01, 0x93, 0xA6, 0xF8, 0x0A, 0xC0, 0x4F, 0xF0, 0x01, 0x0C, 0x86, 0xF8, -+0x0F, 0xE0, 0x86, 0xF8, 0x0E, 0xC0, 0x86, 0xF8, 0x0D, 0xC0, 0x31, 0x46, 0x2B, 0x46, 0x44, 0x71, 0xA6, 0xF8, 0x08, 0xB0, -+0x48, 0x46, 0x02, 0x22, 0xFF, 0xF7, 0x82, 0xFE, 0x24, 0x02, 0x31, 0x46, 0x48, 0x46, 0x2B, 0x46, 0x2A, 0x46, 0xCD, 0xE9, -+0x01, 0x55, 0x00, 0x95, 0xFF, 0xF7, 0x78, 0xFE, 0x44, 0xF0, 0x08, 0x04, 0x0E, 0x4B, 0xA4, 0xB2, 0x1B, 0x69, 0x48, 0xF8, -+0x37, 0x30, 0x21, 0x46, 0x4F, 0xF4, 0xFA, 0x22, 0x4F, 0xF4, 0x00, 0x50, 0xF1, 0xF7, 0x46, 0xFD, 0x20, 0x46, 0x02, 0x21, -+0xF2, 0xF7, 0xDE, 0xF8, 0x28, 0x46, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x12, 0xE0, 0x17, 0x00, 0xF4, 0xE4, 0x17, 0x00, -+0xC8, 0x35, 0x17, 0x00, 0xC0, 0xB2, 0x15, 0x00, 0x7C, 0x28, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x68, 0x65, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x47, 0x19, 0x4C, 0x1A, 0x4D, 0xDF, 0xF8, 0x68, 0xA0, 0xC4, 0xEB, 0x44, 0x29, 0x4F, 0xEA, 0xC9, 0x19, -+0x84, 0xB0, 0x07, 0x46, 0x1F, 0xFA, 0x89, 0xF9, 0x04, 0xF1, 0x40, 0x06, 0x4F, 0xF0, 0x00, 0x08, 0x34, 0xF8, 0x02, 0x3F, -+0xCB, 0xB1, 0x2B, 0x7B, 0xBB, 0x42, 0x16, 0xD1, 0x09, 0xEB, 0xC4, 0x10, 0xA0, 0xF5, 0x80, 0x70, 0x40, 0xF0, 0x08, 0x00, -+0x80, 0xB2, 0x04, 0x21, 0xF2, 0xF7, 0xAA, 0xF8, 0x27, 0x23, 0xCD, 0xE9, 0x00, 0x83, 0xCD, 0xF8, 0x08, 0xA0, 0x00, 0x23, -+0x02, 0x22, 0x29, 0x46, 0x38, 0x46, 0x85, 0xF8, 0x13, 0x80, 0xFF, 0xF7, 0x25, 0xFE, 0xB4, 0x42, 0x05, 0xF1, 0x18, 0x05, -+0xDE, 0xD1, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0xF2, 0xDF, 0x17, 0x00, 0xF4, 0xE4, 0x17, 0x00, 0xE5, 0xFE, 0x14, 0x00, -+0xFF, 0x29, 0x2F, 0xD0, 0xF8, 0xB5, 0xC3, 0xB2, 0x03, 0xEB, 0x83, 0x02, 0x16, 0x4F, 0xC3, 0xEB, 0x02, 0x13, 0x53, 0xFA, -+0x81, 0xF3, 0x07, 0xEB, 0xC3, 0x03, 0x0C, 0x46, 0x93, 0xF8, 0xA5, 0x61, 0x21, 0x2E, 0x05, 0x46, 0x1C, 0xD0, 0x30, 0x02, -+0x40, 0xF0, 0x08, 0x00, 0xF2, 0xF7, 0x20, 0xF9, 0x01, 0x28, 0x15, 0xD1, 0x0D, 0x4B, 0x06, 0xEB, 0x46, 0x06, 0x03, 0xEB, -+0xC6, 0x06, 0x4F, 0xF4, 0x9E, 0x71, 0x01, 0xFB, 0x05, 0x44, 0x73, 0x69, 0x07, 0xEB, 0x44, 0x04, 0x9A, 0x88, 0xB4, 0xF8, -+0x34, 0x31, 0x9B, 0x1A, 0x13, 0xF4, 0x7C, 0x6F, 0x0C, 0xBF, 0x01, 0x20, 0x00, 0x20, 0xF8, 0xBD, 0x01, 0x20, 0xF8, 0xBD, -+0x02, 0x20, 0x70, 0x47, 0x68, 0x65, 0x17, 0x00, 0xF4, 0xE4, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x04, 0x46, 0x50, 0x48, -+0xE1, 0x7E, 0xD0, 0xF8, 0x10, 0x90, 0xFF, 0x29, 0x23, 0xD0, 0x65, 0x7F, 0x4D, 0x4E, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, -+0x05, 0x63, 0x5A, 0x68, 0x97, 0x07, 0x1A, 0xD5, 0x05, 0xEB, 0x85, 0x07, 0xC5, 0xEB, 0x07, 0x17, 0x7A, 0x18, 0x34, 0x32, -+0x06, 0xEB, 0xC2, 0x0C, 0x9C, 0xF8, 0x07, 0xE0, 0x9C, 0xF8, 0x05, 0x80, 0x0E, 0xF1, 0x01, 0x0E, 0xB8, 0xF1, 0x21, 0x0F, -+0x8C, 0xF8, 0x07, 0xE0, 0x09, 0xD1, 0x00, 0x69, 0x56, 0xF8, 0x32, 0x20, 0xDF, 0xF8, 0x14, 0xC1, 0x82, 0x1A, 0x62, 0x45, -+0x48, 0xD8, 0xBD, 0xE8, 0xF0, 0x87, 0xDF, 0xF8, 0x0C, 0xA1, 0x08, 0xEB, 0x48, 0x07, 0x0A, 0xEB, 0xC7, 0x07, 0x4F, 0xEA, -+0x08, 0x20, 0xC7, 0xF8, 0x04, 0x90, 0x40, 0xF0, 0x08, 0x00, 0xF2, 0xF7, 0xC3, 0xF8, 0x01, 0x28, 0x4F, 0xEA, 0x48, 0x09, -+0xEB, 0xD1, 0x7F, 0x69, 0xE3, 0x8B, 0xB8, 0x88, 0x60, 0x84, 0xD9, 0x07, 0x57, 0xD4, 0x4F, 0xF4, 0x1E, 0x72, 0x02, 0xFB, -+0x05, 0x65, 0xD5, 0xF8, 0x4C, 0x21, 0x92, 0xF8, 0xA2, 0x20, 0x52, 0x07, 0x03, 0xD5, 0x62, 0x6A, 0x42, 0xF4, 0x00, 0x12, -+0x62, 0x62, 0x21, 0x8C, 0x3A, 0x68, 0x43, 0xF0, 0x02, 0x03, 0x09, 0x1A, 0xE3, 0x83, 0xC1, 0xF3, 0x0B, 0x01, 0x38, 0x46, -+0x90, 0x47, 0x38, 0x44, 0x01, 0x23, 0x83, 0x71, 0xE3, 0x8B, 0xDB, 0x07, 0x07, 0xD4, 0x1F, 0x4A, 0x20, 0x4B, 0x12, 0x69, -+0x9B, 0x8D, 0x03, 0xEB, 0x92, 0x23, 0xA4, 0xF8, 0x40, 0x30, 0xC8, 0x44, 0x4F, 0xEA, 0xC8, 0x08, 0x5A, 0xF8, 0x08, 0x30, -+0x01, 0x33, 0x4A, 0xF8, 0x08, 0x30, 0xB6, 0xE7, 0x93, 0xF8, 0x24, 0x30, 0x01, 0x2B, 0xB2, 0xD0, 0x17, 0x4B, 0x18, 0x48, -+0x5A, 0x5C, 0x54, 0x23, 0x03, 0xFB, 0x02, 0xF3, 0xC3, 0x58, 0x00, 0x2B, 0xA9, 0xD1, 0x15, 0x4B, 0x53, 0xF8, 0x32, 0x30, -+0x00, 0x2B, 0xA4, 0xD1, 0xBB, 0x18, 0x46, 0x33, 0x56, 0xF8, 0x33, 0x30, 0x00, 0x2B, 0x9E, 0xD1, 0x23, 0x7F, 0x10, 0x48, -+0xA4, 0x26, 0x06, 0xFB, 0x03, 0x23, 0x9E, 0x33, 0x50, 0xF8, 0x33, 0x30, 0x00, 0x2B, 0x94, 0xD1, 0x0C, 0x4B, 0x22, 0x8C, -+0x1B, 0x6A, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x18, 0x47, 0x03, 0xF0, 0x03, 0x02, 0x03, 0x2A, 0x89, 0xD1, 0xA2, 0xE7, -+0x00, 0x10, 0x50, 0x40, 0x68, 0x65, 0x17, 0x00, 0xE4, 0xB8, 0x17, 0x00, 0xC0, 0xB2, 0x15, 0x00, 0x20, 0x62, 0x17, 0x00, -+0x24, 0x64, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x88, 0x1A, 0x17, 0x00, 0x40, 0x42, 0x0F, 0x00, 0xF4, 0xE4, 0x17, 0x00, -+0x2D, 0xE9, 0xF0, 0x47, 0x05, 0x46, 0x1C, 0x48, 0x6C, 0x7F, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x04, 0x03, 0x5E, 0x68, -+0xB6, 0x07, 0x0E, 0xD5, 0xEB, 0x7E, 0x04, 0xEB, 0x84, 0x06, 0xC4, 0xEB, 0x06, 0x14, 0x1C, 0x44, 0x34, 0x34, 0x00, 0xEB, -+0xC4, 0x04, 0xE3, 0x79, 0x01, 0x3B, 0xE3, 0x71, 0xEB, 0x8B, 0x9B, 0x07, 0x02, 0xD4, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x87, -+0x66, 0x79, 0x21, 0x2E, 0xF9, 0xD0, 0x30, 0x02, 0x40, 0xF0, 0x08, 0x00, 0x88, 0x46, 0x91, 0x46, 0xF2, 0xF7, 0x20, 0xF8, -+0x01, 0x28, 0xF0, 0xD1, 0x06, 0xEB, 0x46, 0x07, 0xFF, 0x00, 0xDF, 0xF8, 0x20, 0xC0, 0x5C, 0xF8, 0x07, 0x40, 0x01, 0x3C, -+0x4C, 0xF8, 0x07, 0x40, 0x4B, 0x46, 0x42, 0x46, 0x28, 0x46, 0x31, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0xFF, 0xF7, 0x46, 0xBB, -+0x68, 0x65, 0x17, 0x00, 0xF4, 0xE4, 0x17, 0x00, 0x38, 0xB5, 0x45, 0x69, 0x04, 0x46, 0x40, 0x22, 0x00, 0x21, 0xA8, 0x1D, -+0xCF, 0xF7, 0x58, 0xF9, 0x22, 0x7B, 0x21, 0x7C, 0x0C, 0x4B, 0x4F, 0xF4, 0x9E, 0x70, 0x00, 0xFB, 0x02, 0x12, 0x03, 0xEB, -+0x42, 0x03, 0x00, 0x22, 0xB3, 0xF8, 0x34, 0x31, 0xAB, 0x80, 0x85, 0xF8, 0x46, 0x20, 0xE3, 0x7B, 0x85, 0xF8, 0x47, 0x30, -+0x5A, 0x1E, 0x1A, 0x42, 0x12, 0xBF, 0x04, 0x4B, 0x04, 0x4B, 0x85, 0xF8, 0x48, 0x20, 0x2B, 0x60, 0x38, 0xBD, 0x00, 0xBF, -+0x68, 0x65, 0x17, 0x00, 0xDD, 0x04, 0x15, 0x00, 0xF1, 0x04, 0x15, 0x00, 0x90, 0xF8, 0x47, 0x10, 0x59, 0xB1, 0x43, 0x1D, -+0x19, 0x44, 0x00, 0x20, 0x13, 0xF8, 0x01, 0x2F, 0x02, 0x2A, 0x04, 0xBF, 0x01, 0x30, 0x40, 0xB2, 0x8B, 0x42, 0xF7, 0xD1, -+0x70, 0x47, 0x08, 0x46, 0x70, 0x47, 0x00, 0xBF, 0x11, 0x4A, 0x12, 0x4B, 0x12, 0x68, 0x10, 0xB5, 0x00, 0xEB, 0x80, 0x04, -+0xC0, 0xEB, 0x04, 0x10, 0x08, 0x44, 0x03, 0xEB, 0xC0, 0x00, 0xB2, 0xF9, 0x00, 0x30, 0x90, 0xF8, 0xA4, 0x41, 0x00, 0x2B, -+0x08, 0xDB, 0x0B, 0x4B, 0x0B, 0x4A, 0x04, 0xEB, 0x44, 0x04, 0x03, 0xEB, 0xC4, 0x04, 0x13, 0x69, 0x63, 0x60, 0x10, 0xBD, -+0x20, 0x2C, 0xF4, 0xD9, 0x07, 0x49, 0x08, 0x48, 0x40, 0xF2, 0x52, 0x32, 0xF3, 0xF7, 0xEA, 0xFD, 0xED, 0xE7, 0x00, 0xBF, -+0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0xF4, 0xE4, 0x17, 0x00, 0x00, 0x10, 0x50, 0x40, 0x70, 0x79, 0x15, 0x00, -+0x9C, 0xC2, 0x15, 0x00, 0x10, 0xF0, 0x0C, 0x0F, 0x11, 0xD1, 0x00, 0xF0, 0xF0, 0x03, 0xC0, 0x2B, 0x0B, 0xD0, 0xD0, 0x2B, -+0x05, 0xD0, 0xA3, 0xF1, 0xA0, 0x00, 0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, 0x70, 0x47, 0x0F, 0x29, 0x24, 0xD8, 0x03, 0x29, -+0x03, 0xD8, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x04, 0x39, 0x0B, 0x29, 0xF8, 0xD8, 0x01, 0xA3, 0x53, 0xF8, -+0x21, 0xF0, 0x00, 0xBF, 0xEF, 0x0F, 0x15, 0x00, 0xEB, 0x0F, 0x15, 0x00, 0xEB, 0x0F, 0x15, 0x00, 0xEF, 0x0F, 0x15, 0x00, -+0xEB, 0x0F, 0x15, 0x00, 0xEB, 0x0F, 0x15, 0x00, 0xEB, 0x0F, 0x15, 0x00, 0xEF, 0x0F, 0x15, 0x00, 0xEB, 0x0F, 0x15, 0x00, -+0xEB, 0x0F, 0x15, 0x00, 0xEB, 0x0F, 0x15, 0x00, 0xEF, 0x0F, 0x15, 0x00, 0xB1, 0xF1, 0x7F, 0x00, 0x18, 0xBF, 0x01, 0x20, -+0x70, 0x47, 0x00, 0xBF, 0x2D, 0xE9, 0xF0, 0x4F, 0x90, 0xF8, 0x08, 0xB0, 0xB0, 0xF8, 0x00, 0x90, 0x1B, 0xF8, 0x01, 0xA0, -+0x0C, 0x46, 0x85, 0xB0, 0x80, 0x46, 0x51, 0x46, 0x48, 0x46, 0x1D, 0x46, 0xFF, 0xF7, 0xB4, 0xFF, 0x0B, 0xEB, 0x04, 0x0C, -+0x00, 0x28, 0x00, 0xF0, 0x81, 0x80, 0x98, 0xF8, 0x09, 0x30, 0xFF, 0x2B, 0x24, 0xD0, 0x98, 0xF8, 0x0A, 0x70, 0xFF, 0x2F, -+0x20, 0xD0, 0x50, 0x49, 0x16, 0x46, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x07, 0x12, 0xD2, 0xF8, 0xA8, 0x24, 0x00, 0x2A, -+0x6E, 0xD0, 0x98, 0xF8, 0x30, 0x20, 0x12, 0x07, 0x6E, 0xD5, 0x09, 0xF0, 0xFC, 0x03, 0xD0, 0x2B, 0x00, 0xF0, 0x84, 0x80, -+0x46, 0x4B, 0x4F, 0xF4, 0xA4, 0x68, 0x08, 0xFB, 0x07, 0xF8, 0x43, 0x44, 0xD3, 0xF8, 0xAC, 0x34, 0x00, 0x2B, 0x5B, 0xD0, -+0x0B, 0xF1, 0x13, 0x03, 0xB3, 0x42, 0x05, 0xDB, 0x00, 0x23, 0x01, 0x20, 0x2B, 0x70, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0xB1, 0x1E, 0xA1, 0xEB, 0x0B, 0x01, 0x0C, 0xF1, 0x02, 0x00, 0x89, 0xB2, 0xF2, 0xF7, 0x3A, 0xFC, 0x1F, 0xFA, 0x8B, 0xF3, -+0x00, 0x28, 0xED, 0xD0, 0xB0, 0xF8, 0x02, 0xC0, 0xAC, 0xF1, 0x04, 0x02, 0x01, 0x2A, 0xE7, 0xD8, 0x33, 0x4A, 0xCC, 0xEB, -+0x0C, 0x11, 0x08, 0xEB, 0xC1, 0x01, 0x11, 0x44, 0x4F, 0xEA, 0x0C, 0x12, 0x03, 0x92, 0x91, 0xF8, 0x3B, 0x22, 0x00, 0x2A, -+0xDA, 0xD0, 0xD1, 0xE9, 0x76, 0xAB, 0x42, 0x68, 0x4F, 0xF0, 0x00, 0x0E, 0x22, 0xF0, 0x7F, 0x48, 0xF3, 0x45, 0x08, 0xBF, -+0xC2, 0x45, 0xF1, 0x46, 0xCE, 0xD2, 0x82, 0x46, 0xDD, 0xF8, 0x0C, 0xB0, 0x5A, 0xF8, 0x0A, 0x2F, 0x00, 0x92, 0xDA, 0xF8, -+0x04, 0x20, 0x01, 0x92, 0xC1, 0xE9, 0x76, 0x89, 0x12, 0x30, 0x52, 0x46, 0x02, 0xF8, 0x01, 0xEB, 0x82, 0x42, 0xFB, 0xD1, -+0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x07, 0xF0, 0xAB, 0xEB, 0x0C, 0x0C, 0x21, 0x46, 0x00, 0xF5, 0xEC, 0x70, 0x1A, 0x4C, -+0x00, 0xEB, 0xCC, 0x00, 0x20, 0x44, 0x32, 0x46, 0x00, 0xF0, 0xD2, 0xFA, 0xDD, 0xE9, 0x00, 0x34, 0x8C, 0x42, 0x08, 0xBF, -+0x83, 0x42, 0xA7, 0xD1, 0x00, 0x20, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x12, 0x4A, 0x4F, 0xF4, 0x1E, 0x70, 0x00, 0xFB, -+0x03, 0x23, 0x5B, 0x68, 0x1B, 0x07, 0xF3, 0xD5, 0x19, 0xF4, 0x80, 0x4F, 0xF0, 0xD1, 0x09, 0xF0, 0xFC, 0x09, 0xB9, 0xF1, -+0xC0, 0x0F, 0x02, 0xD0, 0xB9, 0xF1, 0xA0, 0x0F, 0x90, 0xD1, 0xAA, 0xF1, 0x06, 0x01, 0x01, 0x29, 0x8C, 0xD8, 0x01, 0x20, -+0x28, 0x70, 0xE2, 0xE7, 0xAA, 0xF1, 0x0D, 0x01, 0x01, 0x29, 0x3F, 0xF6, 0x77, 0xAF, 0x89, 0xF4, 0x80, 0x40, 0xC0, 0xF3, -+0x80, 0x30, 0xD8, 0xE7, 0x18, 0x88, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0xF8, 0xB5, 0x45, 0x7F, 0x06, 0x7F, 0xFF, 0x2D, -+0x2B, 0xD0, 0x19, 0x4F, 0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x06, 0x73, 0xD3, 0xF8, 0xA8, 0x04, 0xE0, 0xB1, 0x0C, 0x46, -+0x20, 0x46, 0x11, 0x46, 0xFF, 0xF7, 0xF0, 0xFE, 0xB0, 0xB1, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x05, 0xF5, 0x11, 0x4B, -+0xE8, 0x5C, 0x10, 0xF0, 0x01, 0x00, 0x0E, 0xD0, 0x04, 0xF0, 0xFC, 0x04, 0xD0, 0x2C, 0x12, 0xD0, 0x4F, 0xF4, 0xA4, 0x63, -+0x03, 0xFB, 0x06, 0x76, 0xD6, 0xF8, 0xAC, 0x34, 0x00, 0x2B, 0x0C, 0xBF, 0x00, 0x20, 0x02, 0x20, 0xF8, 0xBD, 0x1D, 0x44, -+0x55, 0xF8, 0x22, 0x0C, 0xC0, 0xF3, 0xC0, 0x00, 0xF8, 0xBD, 0x00, 0x20, 0xF8, 0xBD, 0x0D, 0x3A, 0x01, 0x2A, 0xE9, 0xD8, -+0xF2, 0xE7, 0x00, 0xBF, 0x18, 0x88, 0x17, 0x00, 0x8E, 0x65, 0x17, 0x00, 0xF8, 0xB5, 0x2A, 0x4C, 0x03, 0x7F, 0x4F, 0xF4, -+0xA4, 0x60, 0x00, 0xFB, 0x03, 0x43, 0x02, 0xEB, 0x01, 0x0C, 0xD3, 0xF8, 0xAC, 0x04, 0x00, 0x28, 0x47, 0xD0, 0x4C, 0x23, -+0x53, 0x54, 0x10, 0x23, 0x8C, 0xF8, 0x01, 0x30, 0xD0, 0xE9, 0x12, 0x37, 0x01, 0x33, 0x90, 0xF8, 0x61, 0x40, 0xAC, 0xF8, -+0x02, 0x40, 0x47, 0xF1, 0x00, 0x07, 0xC0, 0xE9, 0x12, 0x37, 0x0C, 0xF1, 0x04, 0x0E, 0x00, 0x24, 0x01, 0xE0, 0xD0, 0xE9, -+0x12, 0x37, 0xC4, 0xF1, 0x20, 0x06, 0xE3, 0x40, 0xA4, 0xF1, 0x20, 0x05, 0x07, 0xFA, 0x06, 0xF6, 0x33, 0x43, 0x27, 0xFA, -+0x05, 0xF5, 0x08, 0x34, 0x2B, 0x43, 0x30, 0x2C, 0x0E, 0xF8, 0x01, 0x3B, 0xED, 0xD1, 0x0C, 0xF1, 0x0A, 0x06, 0x0C, 0xF1, -+0x12, 0x04, 0x33, 0x46, 0x00, 0x25, 0x03, 0xF8, 0x01, 0x5B, 0xA3, 0x42, 0xFB, 0xD1, 0x12, 0x32, 0x18, 0x23, 0x92, 0xB2, -+0x00, 0xF0, 0x22, 0xFA, 0x00, 0x23, 0xC3, 0xF1, 0x20, 0x05, 0x20, 0xFA, 0x03, 0xF2, 0xA3, 0xF1, 0x20, 0x04, 0x01, 0xFA, -+0x05, 0xF5, 0x2A, 0x43, 0x21, 0xFA, 0x04, 0xF4, 0x08, 0x33, 0x22, 0x43, 0x40, 0x2B, 0x06, 0xF8, 0x01, 0x2B, 0xEE, 0xD1, -+0x12, 0x20, 0xF8, 0xBD, 0x18, 0x88, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x0A, 0x68, 0x05, 0x68, 0x4B, 0x68, 0xAE, 0x4C, -+0xDF, 0xF8, 0xBC, 0x82, 0x8F, 0xB0, 0x0E, 0x46, 0x6A, 0x40, 0x01, 0x92, 0x32, 0x46, 0x07, 0x46, 0x0D, 0x90, 0xF0, 0x68, -+0x01, 0x9E, 0x04, 0x91, 0x89, 0x68, 0x16, 0x60, 0x7E, 0x68, 0x07, 0x97, 0x83, 0xEA, 0x06, 0x05, 0x55, 0x60, 0x13, 0x46, -+0xBA, 0x68, 0x00, 0x95, 0x81, 0xEA, 0x02, 0x09, 0xC3, 0xF8, 0x08, 0x90, 0xFB, 0x68, 0xCD, 0xF8, 0x0C, 0x90, 0x43, 0x40, -+0x02, 0x93, 0x07, 0xF1, 0x90, 0x03, 0x0C, 0x93, 0x00, 0x9E, 0x01, 0x98, 0x02, 0x99, 0x03, 0x9D, 0xF3, 0xB2, 0x5F, 0xFA, -+0x80, 0xFC, 0xC6, 0xF3, 0x07, 0x2A, 0x4F, 0xEA, 0x10, 0x69, 0xE0, 0x5C, 0x06, 0x90, 0x0A, 0x0E, 0x96, 0x48, 0x08, 0x93, -+0x14, 0xF8, 0x0A, 0x30, 0x87, 0x5C, 0x18, 0xF8, 0x02, 0x10, 0x05, 0x93, 0xC5, 0xF3, 0x07, 0x26, 0xA3, 0x5C, 0x03, 0x9A, -+0x0A, 0x97, 0xC2, 0xF3, 0x07, 0x4E, 0xA7, 0x5D, 0x10, 0xF8, 0x0E, 0x20, 0x18, 0xF8, 0x09, 0xB0, 0x14, 0xF8, 0x0C, 0x50, -+0x38, 0x46, 0x06, 0x9F, 0x09, 0x90, 0x87, 0xEA, 0x0B, 0x0B, 0x05, 0x9F, 0x80, 0xEA, 0x0B, 0x0B, 0x69, 0x40, 0x87, 0x48, -+0x79, 0x40, 0x51, 0x40, 0x10, 0xF8, 0x0A, 0x20, 0x5D, 0x40, 0x6A, 0x40, 0x18, 0xF8, 0x0E, 0x50, 0x14, 0xF8, 0x0E, 0xE0, -+0x6A, 0x40, 0x09, 0x04, 0x41, 0xEA, 0x02, 0x21, 0x7F, 0x4A, 0x02, 0x9D, 0x12, 0xF8, 0x0C, 0x20, 0x5F, 0x46, 0x18, 0xF8, -+0x0A, 0xB0, 0x14, 0xF8, 0x09, 0xA0, 0x10, 0xF8, 0x09, 0x90, 0xCD, 0xF8, 0x2C, 0x90, 0x53, 0x40, 0xC5, 0xF3, 0x07, 0x49, -+0x06, 0x98, 0x18, 0xF8, 0x0C, 0x50, 0x76, 0x4A, 0x83, 0xEA, 0x0B, 0x0B, 0x0A, 0x9B, 0x18, 0xF8, 0x06, 0xC0, 0x5D, 0x40, -+0x12, 0xF8, 0x09, 0x30, 0x92, 0x5D, 0x71, 0x4E, 0x8A, 0xEA, 0x00, 0x00, 0x50, 0x40, 0x08, 0x9A, 0xB6, 0x5C, 0x18, 0xF8, -+0x02, 0x20, 0x8A, 0xEA, 0x06, 0x0A, 0x7B, 0x40, 0x0B, 0x9E, 0x05, 0x9F, 0x8A, 0xEA, 0x0C, 0x0A, 0x18, 0xF8, 0x09, 0xC0, -+0x14, 0xF8, 0x09, 0x90, 0x8E, 0xEA, 0x05, 0x05, 0x56, 0x40, 0x7D, 0x40, 0x1B, 0x04, 0x09, 0x9F, 0x80, 0xEA, 0x0C, 0x00, -+0x8E, 0xEA, 0x0B, 0x0B, 0x43, 0xEA, 0x00, 0x20, 0x89, 0xEA, 0x06, 0x03, 0x41, 0xEA, 0x0B, 0x02, 0x02, 0x99, 0x00, 0x9E, -+0x83, 0xEA, 0x07, 0x0B, 0x03, 0x9B, 0x89, 0xEA, 0x0A, 0x0A, 0x40, 0xEA, 0x0A, 0x0C, 0x5F, 0xFA, 0x83, 0xFE, 0x4F, 0xEA, -+0x13, 0x69, 0xC1, 0xF3, 0x07, 0x20, 0xCB, 0xB2, 0x01, 0x99, 0x02, 0x93, 0x42, 0xEA, 0x05, 0x67, 0x04, 0x9A, 0x03, 0x97, -+0xC1, 0xF3, 0x07, 0x4A, 0x4C, 0xEA, 0x0B, 0x65, 0x17, 0x60, 0x27, 0x5C, 0x55, 0x60, 0x36, 0x0E, 0x05, 0x95, 0x01, 0x97, -+0x4F, 0x4D, 0x14, 0xF8, 0x0A, 0x70, 0x06, 0x97, 0x18, 0xF8, 0x0A, 0x70, 0x15, 0xF8, 0x00, 0xB0, 0xA2, 0x5D, 0x18, 0xF8, -+0x06, 0x30, 0x08, 0x97, 0xC1, 0xF3, 0x07, 0x2C, 0x14, 0xF8, 0x0E, 0x10, 0x15, 0xF8, 0x0A, 0xA0, 0x18, 0xF8, 0x00, 0x00, -+0x01, 0x9F, 0x09, 0x90, 0xA8, 0x5D, 0x0A, 0x90, 0x4B, 0x40, 0x02, 0x98, 0x00, 0x9E, 0x25, 0x5C, 0x18, 0xF8, 0x09, 0x00, -+0x7B, 0x40, 0x83, 0xEA, 0x0A, 0x03, 0x14, 0xF8, 0x0C, 0xA0, 0x51, 0x40, 0x57, 0x46, 0x68, 0x40, 0x8B, 0xEA, 0x01, 0x0B, -+0x00, 0x97, 0x3B, 0x49, 0x14, 0xF8, 0x09, 0xA0, 0x11, 0xF8, 0x09, 0x90, 0xCD, 0xF8, 0x2C, 0x90, 0x78, 0x40, 0x08, 0x9F, -+0x8B, 0xEA, 0x07, 0x01, 0x35, 0x4F, 0x08, 0x91, 0x17, 0xF8, 0x0E, 0x90, 0x09, 0x99, 0x18, 0xF8, 0x0E, 0xE0, 0xC6, 0xF3, -+0x07, 0x46, 0x82, 0xEA, 0x09, 0x02, 0x17, 0xF8, 0x06, 0xB0, 0x17, 0xF8, 0x0C, 0x90, 0x02, 0x9F, 0x18, 0xF8, 0x0C, 0xC0, -+0x4A, 0x40, 0x2C, 0x49, 0x80, 0xEA, 0x0B, 0x00, 0x11, 0xF8, 0x07, 0xB0, 0x0A, 0x99, 0x8A, 0xEA, 0x05, 0x05, 0x89, 0xEA, -+0x05, 0x05, 0x8E, 0xEA, 0x01, 0x0E, 0x18, 0xF8, 0x07, 0x90, 0x0B, 0x99, 0x89, 0xEA, 0x01, 0x09, 0x08, 0x99, 0x1B, 0x04, -+0x43, 0xEA, 0x01, 0x21, 0x06, 0x9B, 0x8A, 0xEA, 0x0B, 0x0A, 0x18, 0xF8, 0x06, 0xB0, 0xA6, 0x5D, 0x01, 0x9F, 0x83, 0xEA, -+0x0E, 0x0E, 0x85, 0xEA, 0x0B, 0x05, 0x87, 0xEA, 0x0E, 0x0E, 0x00, 0x04, 0x00, 0x9F, 0x8A, 0xEA, 0x0C, 0x0A, 0x5A, 0x40, -+0x40, 0xEA, 0x05, 0x20, 0x86, 0xEA, 0x0A, 0x0A, 0x86, 0xEA, 0x09, 0x09, 0x11, 0x43, 0x87, 0xEA, 0x09, 0x09, 0x04, 0x9A, -+0x07, 0x9E, 0x03, 0x9F, 0x05, 0x9B, 0x40, 0xEA, 0x0A, 0x00, 0x41, 0xEA, 0x0E, 0x61, 0x40, 0xEA, 0x09, 0x60, 0xC2, 0xE9, -+0x02, 0x10, 0x35, 0x69, 0x6F, 0x40, 0x17, 0x60, 0x35, 0x46, 0x76, 0x69, 0x01, 0x97, 0x5E, 0x40, 0x56, 0x60, 0x00, 0x96, -+0x2E, 0x46, 0xAD, 0x69, 0x69, 0x40, 0x91, 0x60, 0xF3, 0x69, 0x03, 0x91, 0x43, 0x40, 0x02, 0x93, 0xD3, 0x60, 0x0C, 0x9B, -+0x06, 0xF1, 0x10, 0x01, 0x8B, 0x42, 0x07, 0x91, 0x7F, 0xF4, 0xC8, 0xAE, 0x06, 0xE0, 0x00, 0xBF, 0xE4, 0xC2, 0x15, 0x00, -+0xE4, 0xC3, 0x15, 0x00, 0xE4, 0xC4, 0x15, 0x00, 0xDD, 0xF8, 0x00, 0xE0, 0x3E, 0x0E, 0x5F, 0xFA, 0x8E, 0xF2, 0xDD, 0xE9, -+0x02, 0x39, 0x14, 0xF8, 0x06, 0xC0, 0xA2, 0x5C, 0x70, 0x46, 0x42, 0xEA, 0x0C, 0x62, 0x00, 0x92, 0x1D, 0x0E, 0x02, 0x9A, -+0x65, 0x5D, 0xF9, 0xB2, 0x5F, 0xFA, 0x89, 0xF3, 0x00, 0x0E, 0x61, 0x5C, 0x20, 0x5C, 0xE3, 0x5C, 0xB8, 0x46, 0x5F, 0xFA, -+0x82, 0xFC, 0x4F, 0xEA, 0x19, 0x67, 0x43, 0xEA, 0x00, 0x63, 0xE7, 0x5D, 0x14, 0xF8, 0x0C, 0x00, 0x41, 0xEA, 0x05, 0x61, -+0xCE, 0xF3, 0x07, 0x25, 0x40, 0xEA, 0x07, 0x67, 0x65, 0x5D, 0xC9, 0xF3, 0x07, 0x20, 0x41, 0xEA, 0x05, 0x21, 0x14, 0xF8, -+0x00, 0xB0, 0xC8, 0xF3, 0x07, 0x25, 0xC2, 0xF3, 0x07, 0x20, 0xCE, 0xF3, 0x07, 0x46, 0xC9, 0xF3, 0x07, 0x4A, 0xC2, 0xF3, -+0x07, 0x4C, 0xC8, 0xF3, 0x07, 0x48, 0x65, 0x5D, 0x00, 0x9A, 0x20, 0x5C, 0x14, 0xF8, 0x0A, 0xE0, 0x14, 0xF8, 0x0C, 0xC0, -+0x14, 0xF8, 0x08, 0x80, 0xA6, 0x5D, 0x47, 0xEA, 0x05, 0x27, 0x42, 0xEA, 0x0B, 0x24, 0x43, 0xEA, 0x00, 0x20, 0x04, 0x9A, -+0x0D, 0x9D, 0x41, 0xEA, 0x0E, 0x41, 0x44, 0xEA, 0x0C, 0x44, 0x40, 0xEA, 0x08, 0x40, 0x47, 0xEA, 0x06, 0x46, 0xC2, 0xE9, -+0x00, 0x14, 0xC2, 0xE9, 0x02, 0x06, 0xD5, 0xF8, 0xA0, 0x30, 0x59, 0x40, 0x11, 0x60, 0xD5, 0xF8, 0xA4, 0x30, 0x5C, 0x40, -+0x54, 0x60, 0xD5, 0xF8, 0xA8, 0x30, 0x58, 0x40, 0x90, 0x60, 0xD5, 0xF8, 0xAC, 0x30, 0x5E, 0x40, 0xD6, 0x60, 0x0F, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0xD0, 0xE9, 0x01, 0x23, 0xF0, 0xB5, 0x19, 0x49, 0x05, 0x68, 0xC7, 0x68, 0x54, 0x04, 0x04, 0xF0, -+0x80, 0x76, 0x01, 0xEA, 0xD5, 0x34, 0x34, 0x43, 0x6E, 0x00, 0x06, 0xF0, 0xFE, 0x36, 0x34, 0x43, 0x4F, 0xEA, 0x43, 0x4E, -+0x7E, 0x04, 0x0E, 0xF0, 0x80, 0x7E, 0x04, 0x60, 0x01, 0xEA, 0xD2, 0x34, 0x52, 0x00, 0x06, 0xF0, 0x80, 0x7C, 0x44, 0xEA, -+0x0E, 0x04, 0x01, 0xEA, 0xD3, 0x36, 0x02, 0xF0, 0xFE, 0x32, 0x5B, 0x00, 0x22, 0x43, 0x46, 0xEA, 0x0C, 0x06, 0x03, 0xF0, -+0xFE, 0x33, 0x7C, 0x00, 0x33, 0x43, 0x01, 0xEA, 0xD7, 0x31, 0x04, 0xF0, 0xFE, 0x34, 0x21, 0x43, 0xC0, 0xE9, 0x01, 0x23, -+0x2B, 0x06, 0x48, 0xBF, 0x81, 0xF0, 0x07, 0x41, 0xC1, 0x60, 0xF0, 0xBD, 0x01, 0x01, 0x01, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x29, 0x2A, 0xBD, 0xB0, 0x0B, 0xD8, 0x8B, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0x00, 0x81, -+0x00, 0x20, 0x01, 0x46, 0x3D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x88, 0x46, 0x1D, 0x46, 0x31, 0xF8, 0x04, 0x3B, 0x06, 0x46, -+0x23, 0xF4, 0x60, 0x53, 0x14, 0x46, 0x0D, 0xF1, 0x2E, 0x00, 0x12, 0x22, 0xAD, 0xF8, 0x2C, 0x30, 0x05, 0xF0, 0xC4, 0xFC, -+0xD6, 0xE9, 0x14, 0x13, 0xD6, 0xE9, 0x16, 0x72, 0xC5, 0xF5, 0x7F, 0x40, 0xF4, 0x30, 0x80, 0xB2, 0x01, 0x90, 0xCD, 0xE9, -+0x11, 0x37, 0xDF, 0xF8, 0xEC, 0xE1, 0xDF, 0xF8, 0xEC, 0xC1, 0x10, 0x91, 0x13, 0x92, 0x10, 0xAE, 0x0D, 0xF1, 0xD0, 0x0A, -+0x01, 0x20, 0x02, 0xE0, 0x5E, 0xF8, 0x04, 0x0F, 0x10, 0x36, 0xC2, 0xF3, 0x07, 0x2B, 0x5F, 0xFA, 0x82, 0xF9, 0x1C, 0xF8, -+0x0B, 0xB0, 0x1C, 0xF8, 0x09, 0x90, 0x8B, 0xEA, 0x00, 0x00, 0x4F, 0xEA, 0x12, 0x6B, 0x40, 0xEA, 0x09, 0x60, 0xC2, 0xF3, -+0x07, 0x49, 0x1C, 0xF8, 0x0B, 0xB0, 0x1C, 0xF8, 0x09, 0x90, 0x40, 0xEA, 0x0B, 0x40, 0x40, 0xEA, 0x09, 0x20, 0x41, 0x40, -+0x4B, 0x40, 0x5F, 0x40, 0x7A, 0x40, 0x56, 0x45, 0xC6, 0xE9, 0x06, 0x72, 0xC6, 0xE9, 0x04, 0x13, 0xDA, 0xD1, 0x10, 0x22, -+0x00, 0x21, 0x03, 0xA8, 0xCE, 0xF7, 0xF6, 0xFC, 0x0D, 0xF1, 0x0A, 0x06, 0x00, 0x21, 0x07, 0xA8, 0x10, 0x22, 0xCE, 0xF7, -+0xEF, 0xFC, 0x0D, 0xF1, 0x1A, 0x07, 0x33, 0x46, 0x0D, 0xF1, 0x2A, 0x01, 0x33, 0xF8, 0x02, 0x2F, 0x31, 0xF8, 0x02, 0x0F, -+0x9F, 0x42, 0x82, 0xEA, 0x00, 0x02, 0x1A, 0x80, 0xF6, 0xD1, 0x03, 0xA9, 0x10, 0xA8, 0xFF, 0xF7, 0x7B, 0xFD, 0x03, 0x9B, -+0x0F, 0x9A, 0x6D, 0x08, 0x08, 0xEB, 0x45, 0x08, 0x53, 0x40, 0xA8, 0xF1, 0x02, 0x01, 0x08, 0xF1, 0x0A, 0x05, 0x03, 0x93, -+0x0D, 0xF1, 0x0E, 0x02, 0x32, 0xF8, 0x02, 0x3F, 0x31, 0xF8, 0x02, 0x0F, 0x43, 0x40, 0x8D, 0x42, 0x13, 0x80, 0xF7, 0xD1, -+0x03, 0xA9, 0x10, 0xA8, 0xFF, 0xF7, 0x62, 0xFD, 0x01, 0x9B, 0x1C, 0x44, 0xA4, 0xB2, 0x10, 0x2C, 0x08, 0xF1, 0x0C, 0x09, -+0x26, 0xD9, 0xA4, 0xF1, 0x11, 0x0A, 0xCA, 0xF3, 0x0B, 0x1A, 0x08, 0xEB, 0x0A, 0x18, 0x08, 0xF1, 0x1C, 0x08, 0x4D, 0x46, -+0xAA, 0x1E, 0x33, 0x46, 0x05, 0xF1, 0x0E, 0x00, 0x33, 0xF8, 0x02, 0x1F, 0x32, 0xF8, 0x02, 0xCF, 0x81, 0xEA, 0x0C, 0x01, -+0x90, 0x42, 0x19, 0x80, 0xF6, 0xD1, 0x10, 0x35, 0x03, 0xA9, 0x10, 0xA8, 0xFF, 0xF7, 0x40, 0xFD, 0x45, 0x45, 0xEB, 0xD1, -+0xCA, 0xEB, 0x0A, 0x33, 0x10, 0x3C, 0x04, 0xEB, 0x03, 0x14, 0x0A, 0xF1, 0x01, 0x0A, 0xA4, 0xB2, 0x09, 0xEB, 0x0A, 0x19, -+0x07, 0xA9, 0x10, 0xA8, 0xFF, 0xF7, 0x30, 0xFD, 0x07, 0xA8, 0xFF, 0xF7, 0x01, 0xFF, 0x10, 0x2C, 0x34, 0xD0, 0x65, 0x08, -+0x07, 0xA8, 0xFF, 0xF7, 0xFB, 0xFE, 0x65, 0xB1, 0xA9, 0xF1, 0x02, 0x02, 0x02, 0xEB, 0x45, 0x0C, 0x39, 0x46, 0x31, 0xF8, -+0x02, 0x3F, 0x32, 0xF8, 0x02, 0x0F, 0x43, 0x40, 0x94, 0x45, 0x0B, 0x80, 0xF7, 0xD1, 0xE3, 0x07, 0x39, 0xD4, 0x80, 0x23, -+0xA4, 0x08, 0x05, 0xF0, 0x01, 0x05, 0x3C, 0xAA, 0x05, 0xEB, 0x44, 0x04, 0x02, 0xEB, 0x44, 0x04, 0x34, 0xF8, 0xD4, 0x2C, -+0x53, 0x40, 0x24, 0xF8, 0xD4, 0x3C, 0x3A, 0x46, 0x36, 0xF8, 0x02, 0x3F, 0x32, 0xF8, 0x02, 0x1F, 0xB7, 0x42, 0x83, 0xEA, -+0x01, 0x03, 0x33, 0x80, 0xF6, 0xD1, 0x03, 0xA9, 0x10, 0xA8, 0xFF, 0xF7, 0xFB, 0xFC, 0xDD, 0xE9, 0x03, 0x01, 0x3D, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0xA9, 0xF1, 0x02, 0x02, 0x39, 0x46, 0x09, 0xF1, 0x0E, 0x09, 0x31, 0xF8, 0x02, 0x3F, 0x32, 0xF8, -+0x02, 0x0F, 0x43, 0x40, 0x91, 0x45, 0x0B, 0x80, 0xF7, 0xD1, 0xDE, 0xE7, 0x08, 0x49, 0x09, 0x48, 0x4F, 0xF4, 0xD6, 0x72, -+0xF3, 0xF7, 0x44, 0xF9, 0x00, 0x20, 0x01, 0x46, 0x3D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x19, 0xF8, 0x15, 0x30, 0x43, 0xF4, -+0x00, 0x43, 0xC1, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0xBC, 0xC2, 0x15, 0x00, -+0xE4, 0xC2, 0x15, 0x00, 0x81, 0x04, 0x4F, 0xEA, 0xD0, 0x23, 0xC0, 0xF3, 0xC2, 0x22, 0x0C, 0xD4, 0x13, 0xF0, 0x06, 0x0F, -+0x03, 0xF0, 0x06, 0x02, 0x11, 0xD1, 0x00, 0xF0, 0x7F, 0x00, 0x62, 0xB9, 0x03, 0x28, 0x8C, 0xBF, 0x00, 0x20, 0x01, 0x20, -+0x70, 0x47, 0x07, 0x2A, 0x0C, 0xD0, 0x03, 0xF0, 0x06, 0x02, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x2A, 0xF2, 0xD0, 0x00, 0x20, -+0x70, 0x47, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x2A, 0xF9, 0xD1, 0xEB, 0xE7, 0x13, 0xF0, 0x06, 0x0F, 0x0C, 0xBF, 0x01, 0x20, -+0x00, 0x20, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x4F, 0x07, 0x46, 0x40, 0x7F, 0x87, 0xB0, 0x4F, 0xF0, 0xFF, 0x34, 0x09, 0x28, -+0x05, 0x94, 0x02, 0xD9, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x89, 0x46, 0xF9, 0x6C, 0xC9, 0x4E, 0x8C, 0x6C, 0x0D, 0x6D, -+0x4F, 0xF4, 0x1E, 0x71, 0x01, 0xFB, 0x00, 0x60, 0x90, 0x46, 0x90, 0xF8, 0x22, 0x10, 0xFA, 0x8B, 0x14, 0xF4, 0x00, 0x5F, -+0x08, 0xBF, 0x01, 0x23, 0x22, 0xF4, 0x00, 0x54, 0x05, 0xF4, 0x80, 0x05, 0x02, 0xF4, 0x00, 0x52, 0xFF, 0x29, 0x01, 0x95, -+0xFC, 0x83, 0x02, 0x92, 0xE0, 0xD0, 0xBD, 0x4A, 0xD0, 0xF8, 0x4C, 0xA1, 0x12, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, -+0x50, 0xDB, 0xBA, 0xF8, 0xB4, 0x10, 0xBA, 0x6C, 0x48, 0x1E, 0x05, 0xAC, 0xC0, 0xB2, 0x01, 0xEB, 0x41, 0x0E, 0x00, 0x90, -+0x03, 0x94, 0x0A, 0xEB, 0x8E, 0x0E, 0x02, 0xF1, 0x3C, 0x00, 0x02, 0xF1, 0x4C, 0x0B, 0xA4, 0x46, 0x50, 0xF8, 0x04, 0x6B, -+0xC6, 0xF3, 0x0D, 0x06, 0x79, 0xB1, 0x74, 0x46, 0x00, 0x22, 0x02, 0xE0, 0x01, 0x32, 0x8A, 0x42, 0x09, 0xD0, 0x34, 0xF8, -+0x02, 0x5C, 0xB5, 0x42, 0xA4, 0xF1, 0x0C, 0x04, 0xF6, 0xD1, 0x00, 0x9C, 0xA2, 0x1A, 0x8C, 0xF8, 0x00, 0x20, 0x00, 0x2B, -+0x40, 0xF0, 0xAD, 0x80, 0x83, 0x45, 0x0C, 0xF1, 0x01, 0x0C, 0xE3, 0xD1, 0x97, 0xF8, 0x36, 0x30, 0x9A, 0xF8, 0xA3, 0x20, -+0xC3, 0xF3, 0x82, 0x03, 0x93, 0x42, 0x27, 0xD0, 0x01, 0x9B, 0x00, 0x2B, 0x64, 0xD0, 0xBA, 0xF8, 0x92, 0x20, 0xBA, 0xF8, -+0x90, 0x30, 0x01, 0x32, 0x01, 0x33, 0xAA, 0xF8, 0x92, 0x20, 0xAA, 0xF8, 0x90, 0x30, 0xBA, 0xF8, 0x7E, 0x10, 0xBA, 0xF8, -+0x7C, 0x20, 0x1F, 0xFA, 0x89, 0xF9, 0xA9, 0xEB, 0x08, 0x03, 0x0B, 0x44, 0x91, 0x44, 0xAA, 0xF8, 0x7E, 0x30, 0xAA, 0xF8, -+0x7C, 0x90, 0x87, 0xE7, 0xBA, 0xF1, 0x00, 0x0F, 0xAB, 0xD1, 0x90, 0x49, 0x90, 0x48, 0x00, 0x93, 0x4F, 0xF4, 0x18, 0x62, -+0xF3, 0xF7, 0x64, 0xF8, 0x00, 0x9B, 0xA2, 0xE7, 0xBA, 0xF8, 0x90, 0x30, 0xBA, 0xF8, 0x92, 0x20, 0x01, 0x33, 0xAA, 0xF8, -+0x90, 0x30, 0x01, 0x9B, 0x01, 0x32, 0xAA, 0xF8, 0x92, 0x20, 0x00, 0x2B, 0xD7, 0xD1, 0x02, 0x9B, 0x00, 0x2B, 0x3A, 0xD0, -+0x83, 0x4E, 0x85, 0x4D, 0x03, 0x9F, 0x00, 0x24, 0xB9, 0xF1, 0x00, 0x0F, 0x24, 0xD0, 0x17, 0xF8, 0x01, 0x3B, 0xFF, 0x2B, -+0x00, 0xF0, 0xEC, 0x80, 0x00, 0x2C, 0x00, 0xF0, 0x41, 0x81, 0x03, 0xEB, 0x43, 0x02, 0xB8, 0xF1, 0x01, 0x0F, 0x0A, 0xEB, -+0x82, 0x02, 0x40, 0xF2, 0x7A, 0x81, 0x92, 0x88, 0x59, 0x00, 0x19, 0x44, 0x0A, 0xEB, 0x81, 0x01, 0x02, 0x32, 0x8A, 0x80, -+0xA9, 0xF1, 0x02, 0x09, 0xA8, 0xF1, 0x02, 0x08, 0x71, 0x4A, 0x12, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xC0, 0xF2, -+0x02, 0x81, 0x01, 0x34, 0x04, 0x2C, 0xD7, 0xD1, 0x00, 0x23, 0x8A, 0xF8, 0x9B, 0x30, 0x3B, 0xE7, 0xBA, 0xF8, 0x92, 0x20, -+0xBA, 0xF8, 0x90, 0x30, 0x01, 0x32, 0x01, 0x33, 0xAA, 0xF8, 0x92, 0x20, 0xAA, 0xF8, 0x90, 0x30, 0xC1, 0xE7, 0x66, 0x4E, -+0x67, 0x4D, 0x03, 0x9F, 0x1C, 0x46, 0xB9, 0xF1, 0x00, 0x0F, 0x3F, 0xF4, 0x29, 0xAF, 0x17, 0xF8, 0x01, 0x3B, 0xFF, 0x2B, -+0x00, 0xF0, 0xA5, 0x80, 0x00, 0x2C, 0x00, 0xF0, 0xF0, 0x80, 0x03, 0xEB, 0x43, 0x02, 0xB8, 0xF1, 0x01, 0x0F, 0x0A, 0xEB, -+0x82, 0x02, 0x40, 0xF2, 0x43, 0x81, 0x92, 0x88, 0x59, 0x00, 0x19, 0x44, 0x0A, 0xEB, 0x81, 0x01, 0x02, 0x32, 0x8A, 0x80, -+0xA9, 0xF1, 0x02, 0x09, 0xA8, 0xF1, 0x02, 0x08, 0x53, 0x4A, 0x12, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xC0, 0xF2, -+0xB6, 0x80, 0x01, 0x34, 0x04, 0x2C, 0xD6, 0xD1, 0x02, 0xE7, 0x97, 0xF8, 0x36, 0x30, 0x9A, 0xF8, 0xA3, 0x20, 0xC3, 0xF3, -+0x82, 0x03, 0x93, 0x42, 0x38, 0xD0, 0x01, 0x9B, 0x00, 0x2B, 0x69, 0xD1, 0xBA, 0xF8, 0x92, 0x30, 0xBA, 0xF8, 0x90, 0x20, -+0x01, 0x33, 0x1F, 0xFA, 0x89, 0xF0, 0xAA, 0xF8, 0x92, 0x30, 0x02, 0x9B, 0x02, 0x44, 0xAA, 0xF8, 0x90, 0x20, 0x00, 0x2B, -+0x40, 0xF0, 0x8A, 0x80, 0x9D, 0xF8, 0x14, 0x30, 0xFF, 0x2B, 0x3F, 0xF4, 0xE3, 0xAE, 0x0C, 0x22, 0x02, 0xFB, 0x03, 0xA3, -+0x04, 0x33, 0x3C, 0x4A, 0x5D, 0x88, 0x19, 0x88, 0x14, 0x68, 0xA0, 0xEB, 0x08, 0x02, 0x2A, 0x44, 0x01, 0x44, 0x92, 0xB2, -+0x89, 0xB2, 0x5A, 0x80, 0x19, 0x80, 0xB4, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xBF, 0xF6, 0xCE, 0xAE, 0x91, 0x42, 0xBF, 0xF4, -+0xCB, 0xAE, 0x33, 0x49, 0x34, 0x48, 0x4F, 0xF4, 0x1F, 0x62, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0xF2, 0xF7, 0xA8, 0xBF, -+0xBA, 0xF8, 0x90, 0x30, 0xBA, 0xF8, 0x92, 0x20, 0x1F, 0xFA, 0x89, 0xF0, 0x03, 0x44, 0xAA, 0xF8, 0x90, 0x30, 0x01, 0x9B, -+0x01, 0x32, 0xAA, 0xF8, 0x92, 0x20, 0x8B, 0xBB, 0x02, 0x9B, 0x00, 0x2B, 0x52, 0xD1, 0x9D, 0xF8, 0x14, 0x30, 0xFF, 0x2B, -+0x00, 0xF0, 0xFD, 0x80, 0x0C, 0x22, 0x02, 0xFB, 0x03, 0xA3, 0x04, 0x33, 0xB9, 0xEB, 0x48, 0x0F, 0x9A, 0xF8, 0xA4, 0x20, -+0x80, 0xF0, 0xE9, 0x80, 0x01, 0x2A, 0x40, 0xF2, 0xF8, 0x80, 0x02, 0x2A, 0x03, 0xD0, 0x00, 0x2B, 0x3F, 0xF4, 0x9A, 0xAE, -+0xB9, 0xE7, 0xDA, 0xF8, 0x00, 0x20, 0xA2, 0xF5, 0x92, 0x32, 0xF8, 0x3A, 0xCA, 0xF8, 0x00, 0x20, 0x00, 0x2B, 0x3F, 0xF4, -+0x8F, 0xAE, 0xAE, 0xE7, 0xBA, 0xF8, 0x90, 0x20, 0xBA, 0xF8, 0x92, 0x30, 0x1F, 0xFA, 0x89, 0xF0, 0x02, 0x44, 0x01, 0x33, -+0xAA, 0xF8, 0x90, 0x20, 0xAA, 0xF8, 0x92, 0x30, 0x0A, 0xF1, 0x7C, 0x03, 0x9F, 0xE7, 0x00, 0x2C, 0x75, 0xD0, 0xB8, 0xF1, -+0x01, 0x0F, 0x7F, 0xF6, 0x79, 0xAE, 0xA9, 0xF1, 0x02, 0x09, 0xA8, 0xF1, 0x02, 0x08, 0x6C, 0xE7, 0x00, 0x2C, 0x00, 0xF0, -+0x8C, 0x80, 0xB8, 0xF1, 0x01, 0x0F, 0x7F, 0xF6, 0x2D, 0xAF, 0xA9, 0xF1, 0x02, 0x09, 0xA8, 0xF1, 0x02, 0x08, 0x24, 0xE7, -+0x68, 0x65, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x68, 0x8E, 0x15, 0x00, 0xE4, 0xC5, 0x15, 0x00, -+0x9D, 0xF8, 0x14, 0x30, 0xFF, 0x2B, 0x3F, 0xF4, 0x19, 0xAF, 0x0C, 0x22, 0x02, 0xFB, 0x03, 0xA3, 0x00, 0x22, 0x04, 0x33, -+0x8A, 0xF8, 0x9B, 0x20, 0x71, 0xE7, 0x03, 0xEB, 0x43, 0x03, 0x0A, 0xEB, 0x83, 0x03, 0x9A, 0x88, 0xDB, 0x88, 0x9A, 0x42, -+0xBF, 0xF4, 0x41, 0xAF, 0x40, 0xF6, 0x61, 0x22, 0x31, 0x46, 0x28, 0x46, 0xF2, 0xF7, 0x28, 0xFF, 0x39, 0xE7, 0x03, 0xEB, -+0x43, 0x03, 0x0A, 0xEB, 0x83, 0x03, 0x9A, 0x88, 0xDB, 0x88, 0x9A, 0x42, 0xBF, 0xF4, 0xF5, 0xAE, 0x40, 0xF6, 0x33, 0x22, -+0x31, 0x46, 0x28, 0x46, 0xF2, 0xF7, 0x18, 0xFF, 0xED, 0xE6, 0xB8, 0xF1, 0x00, 0x0F, 0x6C, 0xD0, 0x03, 0xEB, 0x43, 0x01, -+0x0A, 0xEB, 0x81, 0x01, 0x08, 0xF1, 0xFF, 0x38, 0x8A, 0x88, 0x01, 0x32, 0x92, 0xB2, 0xB8, 0xF1, 0x01, 0x0F, 0x8A, 0x80, -+0x09, 0xF1, 0xFF, 0x39, 0x19, 0xB2, 0x73, 0xD9, 0x59, 0x00, 0x04, 0xE7, 0xB8, 0xF1, 0x00, 0x0F, 0x1B, 0xD0, 0x03, 0xEB, -+0x43, 0x01, 0x0A, 0xEB, 0x81, 0x01, 0x08, 0xF1, 0xFF, 0x38, 0x8A, 0x88, 0x01, 0x32, 0x92, 0xB2, 0xB8, 0xF1, 0x01, 0x0F, -+0x8A, 0x80, 0x09, 0xF1, 0xFF, 0x39, 0x19, 0xB2, 0x5B, 0xD9, 0x59, 0x00, 0xB3, 0xE6, 0xB8, 0xF1, 0x02, 0x0F, 0x7F, 0xF6, -+0x03, 0xAE, 0xA9, 0xF1, 0x03, 0x09, 0xA8, 0xF1, 0x03, 0x08, 0x01, 0x24, 0xCF, 0xE6, 0x03, 0xEB, 0x43, 0x02, 0x0A, 0xEB, -+0x82, 0x02, 0xA0, 0x46, 0x92, 0x88, 0x19, 0xB2, 0x01, 0xEB, 0x41, 0x01, 0x0A, 0xEB, 0x81, 0x01, 0x1F, 0xFA, 0x89, 0xF9, -+0xC8, 0x88, 0xA9, 0xEB, 0x08, 0x08, 0x4A, 0x44, 0x40, 0x44, 0x4F, 0xF0, 0x00, 0x09, 0x8A, 0x80, 0xC8, 0x80, 0xC8, 0x46, -+0x9A, 0xE6, 0xB8, 0xF1, 0x02, 0x0F, 0x7F, 0xF6, 0xA1, 0xAE, 0xA9, 0xF1, 0x03, 0x09, 0xA8, 0xF1, 0x03, 0x08, 0x01, 0x24, -+0x72, 0xE6, 0x92, 0x88, 0x1F, 0xFA, 0x88, 0xF8, 0x19, 0xB2, 0xDF, 0xE7, 0x92, 0x88, 0x1F, 0xFA, 0x88, 0xF8, 0x19, 0xB2, -+0x01, 0xEB, 0x41, 0x01, 0x0A, 0xEB, 0x81, 0x01, 0x1F, 0xFA, 0x89, 0xF9, 0xC8, 0x88, 0xA9, 0xEB, 0x08, 0x08, 0x4A, 0x44, -+0x40, 0x44, 0x4F, 0xF0, 0x00, 0x09, 0x8A, 0x80, 0xC8, 0x80, 0xC8, 0x46, 0xB2, 0xE6, 0x03, 0xEB, 0x43, 0x02, 0x0A, 0xEB, -+0x82, 0x02, 0xA0, 0x46, 0x92, 0x88, 0x19, 0xB2, 0xE6, 0xE7, 0x00, 0x2A, 0x3F, 0xF4, 0x19, 0xAF, 0x01, 0x3A, 0x8A, 0xF8, -+0xA4, 0x20, 0x00, 0x2B, 0x3F, 0xF4, 0xB0, 0xAD, 0xCF, 0xE6, 0x02, 0x9B, 0x04, 0xE7, 0x1F, 0xFA, 0x88, 0xF8, 0xB3, 0xE7, -+0x1F, 0xFA, 0x88, 0xF8, 0xD4, 0xE7, 0x01, 0x32, 0x8A, 0xF8, 0xA4, 0x20, 0x00, 0x2B, 0x3F, 0xF4, 0xA1, 0xAD, 0xC0, 0xE6, -+0x03, 0x88, 0xA3, 0xB1, 0x10, 0xB4, 0x42, 0x88, 0x44, 0x7A, 0x00, 0x21, 0x12, 0x04, 0x01, 0x72, 0xB2, 0xFB, 0xF3, 0xF1, -+0x8C, 0xB1, 0x83, 0x88, 0x5D, 0xF8, 0x04, 0x4B, 0x03, 0xEB, 0x43, 0x03, 0x0B, 0x44, 0xC3, 0xF3, 0x98, 0x03, 0x83, 0x80, -+0x01, 0x23, 0x43, 0x72, 0x70, 0x47, 0x03, 0x7A, 0xFF, 0x2B, 0x1C, 0xBF, 0x01, 0x33, 0x03, 0x72, 0x70, 0x47, 0x9A, 0x42, -+0x24, 0xBF, 0x01, 0xF1, 0xFF, 0x33, 0x83, 0x80, 0x4F, 0xF0, 0x01, 0x03, 0x38, 0xBF, 0x84, 0x80, 0x43, 0x72, 0x5D, 0xF8, -+0x04, 0x4B, 0x70, 0x47, 0xF8, 0xB5, 0x06, 0x46, 0x88, 0x04, 0x0C, 0x46, 0xC1, 0xF3, 0xC2, 0x25, 0x19, 0xD4, 0xCB, 0x0A, -+0x13, 0xF0, 0x06, 0x0F, 0x40, 0xD1, 0xCF, 0xB2, 0x01, 0xF0, 0x7F, 0x05, 0x05, 0xF0, 0xF8, 0xF9, 0x17, 0xF0, 0x7C, 0x0F, -+0x5B, 0xD1, 0x96, 0xF8, 0xAD, 0x20, 0x04, 0xE0, 0xB6, 0xF8, 0xAA, 0x30, 0xEB, 0x40, 0xD9, 0x07, 0x59, 0xD4, 0x6B, 0x1E, -+0x95, 0x42, 0xDD, 0xB2, 0xF6, 0xD8, 0x20, 0x46, 0xF8, 0xBD, 0x07, 0x2D, 0x47, 0xD0, 0x04, 0x3D, 0x05, 0xF0, 0xE2, 0xF9, -+0x04, 0xF0, 0x0F, 0x02, 0x01, 0x2D, 0xF4, 0xD8, 0xDF, 0xE8, 0x05, 0xF0, 0x01, 0x0E, 0x72, 0xB3, 0x53, 0x1E, 0x24, 0xF0, -+0x0F, 0x04, 0x96, 0xF8, 0xB1, 0x20, 0x23, 0x43, 0x98, 0xB2, 0x00, 0x2A, 0xE8, 0xD0, 0x40, 0xF4, 0x00, 0x70, 0xF8, 0xBD, -+0x0A, 0xB3, 0x24, 0xF0, 0x0F, 0x03, 0x51, 0x1E, 0x0B, 0x43, 0x98, 0xB2, 0x63, 0x04, 0xDD, 0xD5, 0x03, 0x2A, 0x03, 0xD0, -+0x96, 0xF8, 0xBD, 0x30, 0x99, 0x42, 0xD7, 0xDD, 0x20, 0xF4, 0x80, 0x43, 0x98, 0xB2, 0xF8, 0xBD, 0xC4, 0xF3, 0xC1, 0x05, -+0x05, 0xF0, 0xB8, 0xF9, 0x35, 0x44, 0x04, 0xF0, 0x07, 0x03, 0x05, 0xE0, 0x95, 0xF8, 0xA6, 0x20, 0xCB, 0xB2, 0xDA, 0x40, -+0xD2, 0x07, 0x24, 0xD4, 0x59, 0x1E, 0x00, 0x2B, 0xF6, 0xD1, 0x96, 0xF8, 0xAE, 0x30, 0x03, 0x2B, 0xBD, 0xD8, 0x43, 0xB3, -+0x96, 0xF8, 0xB2, 0x20, 0x00, 0xF4, 0x80, 0x60, 0x43, 0xEA, 0x82, 0x23, 0x03, 0x43, 0x98, 0xB2, 0xF8, 0xBD, 0x05, 0xF0, -+0x9B, 0xF9, 0x20, 0x46, 0xB0, 0xE7, 0x96, 0xF8, 0xAD, 0x20, 0x04, 0x2A, 0x38, 0xBF, 0x04, 0x22, 0xA5, 0xE7, 0x24, 0xF0, -+0x7F, 0x04, 0x44, 0xEA, 0x05, 0x00, 0x00, 0x2D, 0xA4, 0xD1, 0x40, 0xF4, 0x80, 0x63, 0x98, 0xB2, 0xF8, 0xBD, 0x96, 0xF8, -+0xB1, 0x20, 0x24, 0xF0, 0x07, 0x04, 0x44, 0xEA, 0x03, 0x00, 0x00, 0x2A, 0x98, 0xD0, 0x40, 0xF4, 0x00, 0x73, 0x98, 0xB2, -+0xF8, 0xBD, 0x4F, 0xF4, 0x80, 0x60, 0xF8, 0xBD, 0x8A, 0x04, 0x30, 0xB4, 0xC1, 0xF3, 0xC2, 0x23, 0x20, 0xD4, 0xCA, 0x0A, -+0x12, 0xF0, 0x06, 0x0F, 0x26, 0xD1, 0x11, 0xF0, 0x7C, 0x0F, 0x01, 0xF0, 0x7F, 0x03, 0x71, 0xD1, 0x90, 0xF8, 0xAE, 0x40, -+0x03, 0x2C, 0x28, 0xBF, 0x03, 0x24, 0x04, 0xE0, 0xB0, 0xF8, 0xAA, 0x20, 0xDA, 0x40, 0xD5, 0x07, 0x74, 0xD4, 0x5A, 0x1C, -+0xA3, 0x42, 0xD3, 0xB2, 0xF6, 0xD3, 0x90, 0xF8, 0xA5, 0x30, 0x01, 0x2B, 0x01, 0xD9, 0xD9, 0x02, 0x89, 0xB2, 0x08, 0x46, -+0x30, 0xBC, 0x70, 0x47, 0x07, 0x2B, 0xFA, 0xD0, 0x04, 0x3B, 0x01, 0xF0, 0x0F, 0x02, 0x01, 0x2B, 0xF5, 0xD8, 0xDF, 0xE8, -+0x03, 0xF0, 0x15, 0x30, 0xC1, 0xF3, 0xC1, 0x04, 0x90, 0xF8, 0xAC, 0x50, 0x04, 0x44, 0x01, 0xF0, 0x07, 0x03, 0x04, 0xE0, -+0x94, 0xF8, 0xA6, 0x20, 0xDA, 0x40, 0xD2, 0x07, 0x45, 0xD4, 0x5A, 0x1C, 0x9D, 0x42, 0xD3, 0xB2, 0xF6, 0xD8, 0x08, 0x46, -+0x30, 0xBC, 0x70, 0x47, 0x90, 0xF8, 0xAC, 0x30, 0x93, 0x42, 0xDA, 0xD9, 0xB0, 0xF8, 0xA6, 0x30, 0xC1, 0xF3, 0x02, 0x14, -+0x64, 0x00, 0x23, 0x41, 0x03, 0xF0, 0x03, 0x03, 0x07, 0x33, 0x93, 0x42, 0xCF, 0xD9, 0x21, 0xF0, 0x0F, 0x01, 0x01, 0x32, -+0x90, 0xF8, 0xB1, 0x30, 0x11, 0x43, 0x89, 0xB2, 0x00, 0x2B, 0xC6, 0xD0, 0x41, 0xF4, 0x00, 0x71, 0xC3, 0xE7, 0x90, 0xF8, -+0xAC, 0x30, 0x93, 0x42, 0xBF, 0xD9, 0xB0, 0xF8, 0xA6, 0x30, 0xC1, 0xF3, 0x02, 0x14, 0x64, 0x00, 0x23, 0x41, 0x03, 0xF0, -+0x03, 0x03, 0x5B, 0x00, 0x07, 0x33, 0x93, 0x42, 0xB3, 0xD9, 0x21, 0xF0, 0x0F, 0x01, 0x53, 0x1C, 0x0B, 0x43, 0x99, 0xB2, -+0x5B, 0x04, 0xAC, 0xD5, 0x01, 0x2A, 0x03, 0xD0, 0x90, 0xF8, 0xBD, 0x30, 0x93, 0x42, 0xA6, 0xD8, 0x21, 0xF4, 0x80, 0x41, -+0x89, 0xB2, 0xA2, 0xE7, 0x90, 0xF8, 0xAE, 0x40, 0x95, 0xE7, 0x90, 0xF8, 0xB1, 0x20, 0x21, 0xF0, 0x07, 0x01, 0x19, 0x43, -+0x00, 0x2A, 0x98, 0xD0, 0x41, 0xF4, 0x00, 0x71, 0x89, 0xB2, 0x94, 0xE7, 0x21, 0xF0, 0x7F, 0x01, 0x19, 0x43, 0x90, 0xE7, -+0x2D, 0xE9, 0xF0, 0x4F, 0x01, 0xEB, 0x41, 0x01, 0x00, 0xEB, 0x81, 0x01, 0x85, 0xB0, 0x4C, 0x89, 0xE6, 0x0A, 0xC4, 0xF3, -+0x80, 0x22, 0x01, 0x92, 0x71, 0x07, 0x4F, 0xEA, 0x54, 0x22, 0x05, 0x46, 0x06, 0xF0, 0x04, 0x03, 0xC4, 0xF3, 0xC2, 0x27, -+0x02, 0x92, 0xC4, 0xF3, 0x40, 0x2B, 0xC4, 0xF3, 0xC1, 0x1A, 0x23, 0xD5, 0x07, 0x2F, 0x50, 0xD0, 0xC4, 0xF3, 0x02, 0x19, -+0x04, 0xF0, 0x0F, 0x04, 0xDF, 0xF8, 0x70, 0x83, 0xD8, 0xF8, 0x00, 0x20, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x22, 0xDA, -+0x05, 0x2F, 0x27, 0xD9, 0x40, 0xF2, 0xB5, 0x22, 0xCA, 0x49, 0xCB, 0x48, 0x03, 0x93, 0xF2, 0xF7, 0x0B, 0xFD, 0x95, 0xF8, -+0xA5, 0x20, 0x03, 0x9B, 0x05, 0x2A, 0x14, 0xD8, 0xDF, 0xE8, 0x12, 0xF0, 0xD6, 0x00, 0xD6, 0x00, 0x31, 0x01, 0x31, 0x01, -+0xF4, 0x00, 0x45, 0x01, 0x16, 0xF0, 0x06, 0x09, 0x26, 0xD1, 0x04, 0xF0, 0x7F, 0x04, 0xDF, 0xF8, 0x2C, 0x83, 0xD8, 0xF8, -+0x00, 0x20, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x06, 0xDB, 0x05, 0x2F, 0x17, 0xD8, 0xDF, 0xE8, 0x07, 0xF0, 0x22, 0x22, -+0x0F, 0x0F, 0x50, 0x91, 0x95, 0xF8, 0xA5, 0x10, 0x05, 0x29, 0xF4, 0xD8, 0xDF, 0xE8, 0x11, 0xF0, 0xBD, 0x00, 0xBD, 0x00, -+0x15, 0x01, 0x15, 0x01, 0xD8, 0x00, 0x29, 0x01, 0xD8, 0xF8, 0x00, 0x20, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xC0, 0xF2, -+0xDF, 0x80, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xC4, 0xF3, 0xC1, 0x09, 0x04, 0xF0, 0x07, 0x04, 0xD5, 0xE7, 0x4F, 0xF0, -+0x00, 0x09, 0x4C, 0x46, 0xAE, 0xE7, 0xD8, 0xF8, 0x00, 0x20, 0xB2, 0xF9, 0x00, 0x20, 0x03, 0x2C, 0x04, 0xD8, 0x95, 0xF8, -+0xB2, 0x10, 0x01, 0x29, 0x00, 0xF0, 0x7B, 0x81, 0x00, 0x2A, 0xE6, 0xDA, 0xBB, 0xF1, 0x00, 0x0F, 0x40, 0xF0, 0x2E, 0x81, -+0xBA, 0xF1, 0x00, 0x0F, 0x40, 0xF0, 0x1C, 0x81, 0xB9, 0xF1, 0x00, 0x0F, 0x40, 0xF0, 0xDC, 0x81, 0x95, 0xF8, 0xAD, 0x30, -+0xA3, 0x42, 0x00, 0xF2, 0xC9, 0x81, 0x95, 0xF8, 0xAE, 0x30, 0xA3, 0x42, 0xC0, 0xF0, 0xEE, 0x81, 0xB5, 0xF8, 0xAA, 0x30, -+0x23, 0xFA, 0x04, 0xF4, 0xE2, 0x07, 0xCA, 0xD4, 0x93, 0x49, 0x95, 0x48, 0x40, 0xF2, 0x06, 0x32, 0x3B, 0xE0, 0xD8, 0xF8, -+0x00, 0x20, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xBF, 0xDA, 0x01, 0x9B, 0x00, 0x2B, 0x40, 0xF0, 0xCB, 0x81, 0x95, 0xF8, -+0xB1, 0x30, 0x5B, 0x45, 0xC0, 0xF0, 0x52, 0x82, 0x95, 0xF8, 0xAF, 0x30, 0x53, 0x45, 0xC0, 0xF0, 0x3F, 0x82, 0x95, 0xF8, -+0xB0, 0x30, 0x4B, 0x45, 0xC0, 0xF0, 0x2C, 0x82, 0x95, 0xF8, 0xAC, 0x30, 0xA3, 0x42, 0xC0, 0xF0, 0x19, 0x82, 0xB5, 0xF8, -+0xA6, 0x30, 0x4F, 0xEA, 0x49, 0x02, 0x13, 0x41, 0x03, 0xF0, 0x03, 0x03, 0x07, 0x33, 0x9C, 0x42, 0x00, 0xF3, 0x82, 0x81, -+0x06, 0x2C, 0x00, 0xF0, 0x3E, 0x81, 0x09, 0x2C, 0x97, 0xD1, 0xBA, 0xF1, 0x00, 0x0F, 0x40, 0xF0, 0x4B, 0x82, 0xB9, 0xF1, -+0x02, 0x0F, 0x90, 0xD0, 0xB9, 0xF1, 0x05, 0x0F, 0x8D, 0xD0, 0x75, 0x49, 0x77, 0x48, 0x4F, 0xF4, 0x48, 0x72, 0x05, 0xB0, -+0xBD, 0xE8, 0xF0, 0x4F, 0xF2, 0xF7, 0x5C, 0xBC, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xBF, 0xF6, -+0x7E, 0xAF, 0x02, 0x9B, 0x03, 0xF0, 0x03, 0x03, 0x03, 0x2B, 0x00, 0xF0, 0x21, 0x82, 0x95, 0xF8, 0xAF, 0x30, 0x53, 0x45, -+0xC0, 0xF0, 0x9E, 0x81, 0x95, 0xF8, 0xB0, 0x30, 0x4B, 0x45, 0xC0, 0xF0, 0xD1, 0x81, 0x95, 0xF8, 0xAC, 0x30, 0xA3, 0x42, -+0xC0, 0xF0, 0xBE, 0x81, 0xB5, 0xF8, 0xA6, 0x30, 0x4F, 0xEA, 0x49, 0x09, 0x43, 0xFA, 0x09, 0xF3, 0x03, 0xF0, 0x03, 0x03, -+0x5B, 0x00, 0x07, 0x33, 0x9C, 0x42, 0x7F, 0xF7, 0x5C, 0xAF, 0x5C, 0x49, 0x5F, 0x48, 0x40, 0xF2, 0x2F, 0x32, 0xCC, 0xE7, -+0xD8, 0xF8, 0x00, 0x20, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xBF, 0xF6, 0x36, 0xAF, 0x16, 0xF0, 0x06, 0x0F, 0x40, 0xF0, -+0x2A, 0x81, 0x05, 0x2F, 0x3F, 0xF6, 0x49, 0xAF, 0x01, 0xA3, 0x53, 0xF8, 0x27, 0xF0, 0x00, 0xBF, 0xE7, 0x21, 0x15, 0x00, -+0xE7, 0x21, 0x15, 0x00, 0x8D, 0x23, 0x15, 0x00, 0x8D, 0x23, 0x15, 0x00, 0x43, 0x22, 0x15, 0x00, 0xC5, 0x22, 0x15, 0x00, -+0xD8, 0xF8, 0x00, 0x20, 0xB2, 0xF9, 0x00, 0x20, 0x95, 0xF8, 0xAD, 0x10, 0x03, 0x29, 0x60, 0xD8, 0x00, 0x2A, 0xBF, 0xF6, -+0x14, 0xAF, 0x04, 0x2F, 0x3F, 0xF4, 0x6B, 0xAF, 0x00, 0x2F, 0x3F, 0xF4, 0x38, 0xAF, 0x42, 0x49, 0x46, 0x48, 0x4F, 0xF4, -+0x36, 0x72, 0xF2, 0xF7, 0xF9, 0xFB, 0x06, 0xE7, 0x01, 0x9B, 0x00, 0x2B, 0x40, 0xF0, 0x64, 0x81, 0x95, 0xF8, 0xB1, 0x30, -+0x5B, 0x45, 0xC0, 0xF0, 0x51, 0x81, 0x95, 0xF8, 0xAF, 0x30, 0x53, 0x45, 0xC0, 0xF0, 0xD5, 0x80, 0x95, 0xF8, 0xB0, 0x30, -+0x4B, 0x45, 0xC0, 0xF0, 0xC2, 0x80, 0x95, 0xF8, 0xAC, 0x30, 0xA3, 0x42, 0xC0, 0xF0, 0xD9, 0x80, 0x4D, 0x44, 0x95, 0xF8, -+0xA6, 0x30, 0x23, 0xFA, 0x04, 0xF4, 0xE3, 0x07, 0x3F, 0xF5, 0x01, 0xAF, 0x2E, 0x49, 0x34, 0x48, 0x40, 0xF2, 0x12, 0x32, -+0x71, 0xE7, 0xD8, 0xF8, 0x00, 0x20, 0xB2, 0xF9, 0x00, 0x20, 0x95, 0xF8, 0xAD, 0x10, 0x03, 0x29, 0x77, 0xD8, 0x00, 0x2A, -+0xBF, 0xF6, 0xD7, 0xAE, 0x00, 0x2B, 0xA2, 0xD0, 0x25, 0x49, 0x2C, 0x48, 0x40, 0xF2, 0xCA, 0x22, 0xF2, 0xF7, 0xC0, 0xFB, -+0xCD, 0xE6, 0xD8, 0xF8, 0x00, 0x20, 0xB2, 0xF9, 0x00, 0x20, 0x95, 0xF8, 0xAD, 0x10, 0x03, 0x29, 0x56, 0xD8, 0x00, 0x2A, -+0xBF, 0xF6, 0xC3, 0xAE, 0x05, 0x2F, 0x3F, 0xF4, 0x5C, 0xAF, 0x00, 0x2F, 0x3F, 0xF4, 0xE7, 0xAE, 0x19, 0x49, 0x21, 0x48, -+0x40, 0xF2, 0xE7, 0x22, 0xF2, 0xF7, 0xA8, 0xFB, 0xB5, 0xE6, 0x00, 0x2A, 0xBF, 0xF6, 0xB3, 0xAE, 0x04, 0x2F, 0x3F, 0xF4, -+0x0A, 0xAF, 0x13, 0x49, 0x1B, 0x48, 0x4F, 0xF4, 0x37, 0x72, 0xF2, 0xF7, 0x9B, 0xFB, 0xA8, 0xE6, 0x0F, 0x49, 0x19, 0x48, -+0x40, 0xF2, 0x02, 0x32, 0xF2, 0xF7, 0x94, 0xFB, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, -+0xD7, 0xAE, 0xB4, 0xE6, 0x08, 0x49, 0x13, 0x48, 0x40, 0xF2, 0x01, 0x32, 0xF2, 0xF7, 0x86, 0xFB, 0xD8, 0xF8, 0x00, 0x30, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xBF, 0xF6, 0xA8, 0xAE, 0xBA, 0xF1, 0x00, 0x0F, 0x3F, 0xF4, 0xC5, 0xAE, 0xDF, 0xE7, -+0x70, 0x79, 0x15, 0x00, 0x08, 0xC6, 0x15, 0x00, 0xB0, 0xC7, 0x15, 0x00, 0xF0, 0xC8, 0x15, 0x00, 0xA8, 0xC9, 0x15, 0x00, -+0xA8, 0xC6, 0x15, 0x00, 0x3C, 0xC8, 0x15, 0x00, 0x48, 0xC6, 0x15, 0x00, 0x04, 0xC7, 0x15, 0x00, 0xE8, 0xC6, 0x15, 0x00, -+0x64, 0xC7, 0x15, 0x00, 0x58, 0xC7, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x00, 0x2A, 0xBF, 0xF6, 0x6C, 0xAE, 0x05, 0x2F, -+0x3F, 0xF4, 0x05, 0xAF, 0xA9, 0x49, 0xAA, 0x48, 0x40, 0xF2, 0xEB, 0x22, 0xF2, 0xF7, 0x54, 0xFB, 0x61, 0xE6, 0x00, 0x2A, -+0xBF, 0xF6, 0x5F, 0xAE, 0xBA, 0x1E, 0x01, 0x2A, 0x7F, 0xF6, 0x54, 0xAF, 0xA2, 0x49, 0xA4, 0x48, 0x40, 0xF2, 0xCE, 0x22, -+0xF2, 0xF7, 0x46, 0xFB, 0x53, 0xE6, 0x00, 0x2A, 0xBF, 0xF6, 0x6B, 0xAE, 0x01, 0x9B, 0x00, 0x2B, 0x7F, 0xF4, 0x80, 0xAE, -+0x40, 0xF2, 0xFB, 0x22, 0x9A, 0x49, 0x9D, 0x48, 0xF2, 0xF7, 0x38, 0xFB, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x20, -+0x72, 0xE6, 0xBA, 0xF1, 0x02, 0x0F, 0x7F, 0xF4, 0x58, 0xAE, 0xB9, 0xF1, 0x03, 0x0F, 0x03, 0xD0, 0xB9, 0xF1, 0x06, 0x0F, -+0x7F, 0xF4, 0x51, 0xAE, 0x90, 0x49, 0x94, 0x48, 0x40, 0xF2, 0x1F, 0x32, 0xC1, 0xE6, 0x8E, 0x49, 0x92, 0x48, 0x4F, 0xF4, -+0x44, 0x72, 0xF2, 0xF7, 0x1D, 0xFB, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0x31, 0xAF, -+0x3D, 0xE6, 0x87, 0x49, 0x8C, 0x48, 0x40, 0xF2, 0x0F, 0x32, 0xF2, 0xF7, 0x0F, 0xFB, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0x1E, 0xAF, 0x2F, 0xE6, 0x80, 0x49, 0x86, 0x48, 0x40, 0xF2, 0x11, 0x32, 0xF2, 0xF7, -+0x01, 0xFB, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0x1A, 0xAF, 0x21, 0xE6, 0x79, 0x49, -+0x80, 0x48, 0x40, 0xF2, 0xC2, 0x22, 0xF2, 0xF7, 0xF3, 0xFA, 0x00, 0xE6, 0x75, 0x49, 0x7E, 0x48, 0x40, 0xF2, 0x1E, 0x32, -+0xF2, 0xF7, 0xEC, 0xFA, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0x71, 0xAE, 0x0C, 0xE6, -+0x6E, 0x49, 0x78, 0x48, 0x4F, 0xF4, 0x41, 0x72, 0xF2, 0xF7, 0xDE, 0xFA, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xFF, 0xF6, 0x2A, 0xAE, 0xFE, 0xE5, 0x67, 0x49, 0x72, 0x48, 0x40, 0xF2, 0x03, 0x32, 0xF2, 0xF7, 0xD0, 0xFA, -+0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0x17, 0xAE, 0xF0, 0xE5, 0x60, 0x49, 0x6C, 0x48, -+0x40, 0xF2, 0x19, 0x32, 0xF2, 0xF7, 0xC2, 0xFA, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, -+0x28, 0xAE, 0xE2, 0xE5, 0x59, 0x49, 0x66, 0x48, 0x40, 0xF2, 0x05, 0x32, 0xF2, 0xF7, 0xB4, 0xFA, 0xD8, 0xF8, 0x00, 0x30, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0x05, 0xAE, 0xD4, 0xE5, 0x52, 0x49, 0x58, 0x48, 0x4F, 0xF4, 0x4B, 0x72, -+0xF2, 0xF7, 0xA6, 0xFA, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0x55, 0xAE, 0xC6, 0xE5, -+0x4B, 0x49, 0x59, 0x48, 0x40, 0xF2, 0x0E, 0x32, 0xF2, 0xF7, 0x98, 0xFA, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xFF, 0xF6, 0xA2, 0xAE, 0xB8, 0xE5, 0x44, 0x49, 0x50, 0x48, 0x40, 0xF2, 0x0D, 0x32, 0xF2, 0xF7, 0x8A, 0xFA, -+0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0x8F, 0xAE, 0xAA, 0xE5, 0x3D, 0x49, 0x44, 0x48, -+0x40, 0xF2, 0x2E, 0x32, 0xF2, 0xF7, 0x7C, 0xFA, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, -+0x35, 0xAE, 0x9C, 0xE5, 0x36, 0x49, 0x3B, 0x48, 0x40, 0xF2, 0x2D, 0x32, 0xF2, 0xF7, 0x6E, 0xFA, 0xD8, 0xF8, 0x00, 0x30, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0x22, 0xAE, 0x8E, 0xE5, 0x2F, 0x49, 0x36, 0x48, 0x40, 0xF2, 0x1D, 0x32, -+0xF2, 0xF7, 0x60, 0xFA, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0xDA, 0xAD, 0x80, 0xE5, -+0x28, 0x49, 0x2D, 0x48, 0x4F, 0xF4, 0x47, 0x72, 0xF2, 0xF7, 0x52, 0xFA, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xFF, 0xF6, 0xC7, 0xAD, 0x72, 0xE5, 0x21, 0x49, 0x27, 0x48, 0x40, 0xF2, 0x1B, 0x32, 0xF2, 0xF7, 0x44, 0xFA, -+0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0xB4, 0xAD, 0x64, 0xE5, 0x1A, 0x49, 0x28, 0x48, -+0x40, 0xF2, 0x1A, 0x32, 0xF2, 0xF7, 0x36, 0xFA, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, -+0xA1, 0xAD, 0x56, 0xE5, 0x13, 0x49, 0x22, 0x48, 0x40, 0xF2, 0x2B, 0x32, 0xF2, 0xF7, 0x28, 0xFA, 0xD8, 0xF8, 0x00, 0x30, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xFF, 0xF6, 0xD2, 0xAD, 0x48, 0xE5, 0xBA, 0xF1, 0x02, 0x0F, 0x08, 0xD1, 0xB9, 0xF1, -+0x05, 0x0F, 0x7F, 0xF4, 0x42, 0xAD, 0x09, 0x49, 0x18, 0x48, 0x40, 0xF2, 0x21, 0x32, 0xB2, 0xE5, 0xBA, 0xF1, 0x03, 0x0F, -+0x7F, 0xF4, 0x39, 0xAD, 0xB9, 0xF1, 0x02, 0x0F, 0x7F, 0xF4, 0x35, 0xAD, 0x02, 0x49, 0x13, 0x48, 0x40, 0xF2, 0x22, 0x32, -+0xA5, 0xE5, 0x00, 0xBF, 0x70, 0x79, 0x15, 0x00, 0xD8, 0x93, 0x15, 0x00, 0x64, 0xC6, 0x15, 0x00, 0x48, 0xC7, 0x15, 0x00, -+0xAC, 0xC8, 0x15, 0x00, 0x10, 0xC8, 0x15, 0x00, 0xFC, 0xC7, 0x15, 0x00, 0x24, 0xC8, 0x15, 0x00, 0x28, 0xC6, 0x15, 0x00, -+0x64, 0xC8, 0x15, 0x00, 0x80, 0xC7, 0x15, 0x00, 0x74, 0xC7, 0x15, 0x00, 0xD4, 0xC7, 0x15, 0x00, 0x98, 0xC7, 0x15, 0x00, -+0xE4, 0xC7, 0x15, 0x00, 0xA0, 0xC9, 0x15, 0x00, 0x34, 0xC9, 0x15, 0x00, 0x68, 0xC9, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x41, -+0x04, 0x46, 0x04, 0xF0, 0x89, 0xFD, 0x94, 0xF8, 0xA5, 0x10, 0x94, 0xF8, 0xAF, 0x20, 0xCB, 0x02, 0x9B, 0xB2, 0x92, 0xB3, -+0x55, 0x1E, 0xED, 0xB2, 0x05, 0x29, 0x2B, 0xD8, 0xDF, 0xE8, 0x01, 0xF0, 0x6D, 0x6D, 0x2F, 0x2F, 0x94, 0x03, 0x94, 0xF8, -+0xAD, 0x10, 0x03, 0x29, 0x00, 0xF2, 0xD1, 0x80, 0x06, 0x05, 0x40, 0xF1, 0xCE, 0x80, 0x94, 0xF8, 0xAE, 0x60, 0xB4, 0xF8, -+0xAA, 0x20, 0x73, 0x1A, 0x01, 0x33, 0x00, 0xF0, 0x7F, 0x07, 0x97, 0xFB, 0xF3, 0xF5, 0x03, 0xFB, 0x15, 0x73, 0x19, 0x44, -+0xC9, 0xB2, 0x22, 0xFA, 0x01, 0xF3, 0x13, 0xF0, 0x01, 0x0F, 0x08, 0xBF, 0x31, 0x46, 0x00, 0x29, 0x00, 0xF0, 0x3F, 0x81, -+0x94, 0xF8, 0xB2, 0x20, 0x00, 0xF4, 0x80, 0x63, 0x43, 0xEA, 0x82, 0x23, 0x0B, 0x43, 0x9B, 0xB2, 0x18, 0x46, 0xBD, 0xE8, -+0xF0, 0x81, 0x15, 0x46, 0xCC, 0xE7, 0x94, 0xF8, 0xAD, 0x10, 0x03, 0x29, 0x01, 0xD8, 0x06, 0x05, 0xD5, 0xD4, 0x94, 0xF8, -+0xB0, 0x70, 0x94, 0xF8, 0xAC, 0x60, 0x94, 0xF8, 0xB1, 0xC0, 0x01, 0x37, 0xC0, 0xF3, 0xC1, 0x01, 0xB1, 0xFB, 0xF7, 0xFE, -+0x07, 0xFB, 0x1E, 0x11, 0x0C, 0x44, 0x06, 0xF1, 0x01, 0x0E, 0x00, 0xF0, 0x07, 0x08, 0x94, 0xF8, 0xA6, 0x70, 0xB8, 0xFB, -+0xFE, 0xF4, 0x0E, 0xFB, 0x14, 0x84, 0xE7, 0x40, 0xFF, 0x07, 0x48, 0xBF, 0xE6, 0xB2, 0x52, 0x1B, 0x0C, 0xF1, 0x01, 0x04, -+0xC0, 0xF3, 0x40, 0x2C, 0x01, 0x32, 0xC0, 0xF3, 0xC1, 0x10, 0xBC, 0xFB, 0xF4, 0xF7, 0xC9, 0x00, 0x04, 0xFB, 0x17, 0xC4, -+0x41, 0xEA, 0x44, 0x21, 0x90, 0xFB, 0xF2, 0xF4, 0x02, 0xFB, 0x14, 0x00, 0x05, 0x44, 0x0B, 0x43, 0x43, 0xEA, 0xC5, 0x13, -+0x9B, 0xB2, 0x33, 0x43, 0x18, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x94, 0xF8, 0xAE, 0x70, 0x94, 0xF8, 0xAD, 0x20, 0xB4, 0xF8, -+0xAA, 0x50, 0xB9, 0x1A, 0x01, 0x31, 0x00, 0xF0, 0x7F, 0x0C, 0x9C, 0xFB, 0xF1, 0xF6, 0x01, 0xFB, 0x16, 0xC1, 0x0A, 0x44, -+0xD2, 0xB2, 0x25, 0xFA, 0x02, 0xF1, 0x11, 0xF0, 0x01, 0x0F, 0x08, 0xBF, 0x3A, 0x46, 0x13, 0x43, 0x00, 0x2A, 0x00, 0xF0, -+0xA2, 0x80, 0x01, 0x3A, 0xD2, 0xB2, 0x02, 0x2A, 0x9E, 0xD8, 0x94, 0xF8, 0xB2, 0x20, 0x00, 0xF4, 0x80, 0x60, 0x40, 0xEA, -+0x82, 0x20, 0x03, 0x43, 0x9B, 0xB2, 0x95, 0xE7, 0x94, 0xF8, 0xAD, 0x10, 0x03, 0x29, 0x40, 0xF2, 0x8C, 0x80, 0x94, 0xF8, -+0xB0, 0x10, 0xB4, 0xF8, 0xA6, 0x70, 0x94, 0xF8, 0xAC, 0xC0, 0x94, 0xF8, 0xB1, 0x40, 0x4E, 0x1C, 0xC0, 0xF3, 0x02, 0x11, -+0xB1, 0xFB, 0xF6, 0xFE, 0x06, 0xFB, 0x1E, 0x11, 0x4E, 0x00, 0x37, 0x41, 0x07, 0xF0, 0x03, 0x07, 0x0C, 0xF1, 0x01, 0x06, -+0x00, 0xF0, 0x0F, 0x0C, 0x07, 0x37, 0xBC, 0xFB, 0xF6, 0xFE, 0x06, 0xFB, 0x1E, 0xCC, 0xBC, 0x45, 0xCE, 0xB2, 0xA2, 0xEB, -+0x05, 0x02, 0x40, 0xF3, 0x81, 0x80, 0x02, 0xF1, 0x01, 0x0C, 0xC0, 0xF3, 0xC1, 0x1E, 0x9E, 0xFB, 0xFC, 0xF2, 0x0C, 0xFB, -+0x12, 0xE2, 0x15, 0x44, 0xFF, 0xB2, 0xED, 0xB2, 0x09, 0x2F, 0x40, 0xF0, 0xAE, 0x80, 0x00, 0x2D, 0x40, 0xF0, 0x98, 0x80, -+0x02, 0x29, 0x00, 0xF0, 0xC0, 0x80, 0x05, 0x2E, 0x14, 0xBF, 0x4F, 0xF0, 0x08, 0x0C, 0x4F, 0xF0, 0x09, 0x0C, 0x09, 0x01, -+0x09, 0xB2, 0x00, 0x25, 0x76, 0xE0, 0x94, 0xF8, 0xB0, 0x70, 0xB4, 0xF8, 0xA6, 0x60, 0x94, 0xF8, 0xAC, 0xC0, 0x79, 0x1C, -+0xC0, 0xF3, 0x02, 0x17, 0xB7, 0xFB, 0xF1, 0xFE, 0x01, 0xFB, 0x1E, 0x77, 0x79, 0x00, 0x0E, 0x41, 0x06, 0xF0, 0x03, 0x06, -+0x0C, 0xF1, 0x01, 0x0C, 0x00, 0xF0, 0x0F, 0x01, 0x76, 0x00, 0x07, 0x36, 0xB1, 0xFB, 0xFC, 0xFE, 0x0C, 0xFB, 0x1E, 0x11, -+0xB1, 0x42, 0xC0, 0xF3, 0x41, 0x2C, 0xA2, 0xEB, 0x05, 0x02, 0xC8, 0xBF, 0xF1, 0xB2, 0x02, 0xF1, 0x01, 0x02, 0xC0, 0xF3, -+0xC1, 0x1E, 0xD8, 0xBF, 0xC9, 0xB2, 0xBC, 0xF1, 0x03, 0x0F, 0x18, 0xBF, 0x4F, 0xEA, 0x4C, 0x26, 0x9E, 0xFB, 0xF2, 0xFC, -+0x02, 0xFB, 0x1C, 0xEC, 0x94, 0xF8, 0xBC, 0x20, 0x65, 0x44, 0x08, 0xBF, 0x4F, 0xF4, 0x80, 0x66, 0xED, 0xB2, 0xEA, 0xB1, -+0x02, 0x29, 0x1A, 0xD0, 0x94, 0xF8, 0xBD, 0x20, 0x8A, 0x42, 0x16, 0xD3, 0x94, 0xF8, 0xBE, 0xC0, 0xFA, 0xB2, 0x94, 0x45, -+0x11, 0xD3, 0x94, 0xF8, 0xBF, 0x20, 0xAA, 0x42, 0x0D, 0xD3, 0x00, 0xF4, 0x80, 0x42, 0x12, 0xB2, 0x0A, 0xE0, 0x07, 0x05, -+0x7F, 0xF5, 0x71, 0xAF, 0xE1, 0xE6, 0x43, 0xF4, 0x80, 0x63, 0x9B, 0xB2, 0x18, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x22, -+0x43, 0xEA, 0x07, 0x13, 0x43, 0xEA, 0xC5, 0x15, 0x29, 0x43, 0x31, 0x43, 0x42, 0xEA, 0x01, 0x03, 0x9B, 0xB2, 0x18, 0x46, -+0xBD, 0xE8, 0xF0, 0x81, 0x57, 0x1C, 0xC0, 0xF3, 0xC1, 0x1E, 0x9E, 0xFB, 0xF7, 0xF2, 0x07, 0xFB, 0x12, 0xE2, 0x15, 0x44, -+0xBC, 0xF1, 0x06, 0x0F, 0xED, 0xB2, 0x5F, 0xFA, 0x8C, 0xF7, 0x7F, 0xF4, 0x7B, 0xAF, 0x02, 0x2D, 0x20, 0xD0, 0x09, 0x01, -+0x09, 0xB2, 0xED, 0x01, 0x01, 0x34, 0xC0, 0xF3, 0x40, 0x20, 0xB0, 0xFB, 0xF4, 0xF2, 0x04, 0xFB, 0x12, 0x00, 0x43, 0xEA, -+0x40, 0x23, 0x2B, 0x43, 0x0B, 0x43, 0x4C, 0xEA, 0x03, 0x03, 0x9B, 0xB2, 0x18, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x4F, 0xF4, -+0x80, 0x63, 0xC5, 0xE6, 0x02, 0x2D, 0x16, 0xD1, 0x05, 0x29, 0x2D, 0xD0, 0x09, 0x01, 0x09, 0xB2, 0xBC, 0x46, 0x4F, 0xF4, -+0x80, 0x75, 0xE1, 0xE7, 0x03, 0x29, 0x16, 0xD0, 0x06, 0x29, 0x14, 0xD0, 0x09, 0x01, 0x09, 0xB2, 0x4F, 0xF4, 0x80, 0x75, -+0xD8, 0xE7, 0x09, 0x01, 0x09, 0xB2, 0xED, 0x01, 0x0F, 0xFA, 0x87, 0xFC, 0xD2, 0xE7, 0x03, 0x2D, 0x1B, 0xD1, 0x02, 0x29, -+0x0F, 0xD0, 0x09, 0x01, 0x09, 0xB2, 0xBC, 0x46, 0x4F, 0xF4, 0xC0, 0x75, 0xC8, 0xE7, 0x71, 0x1E, 0xC9, 0xB2, 0x09, 0x01, -+0x4F, 0xF0, 0x06, 0x0C, 0x4F, 0xF4, 0x80, 0x75, 0xC0, 0xE7, 0xBC, 0x46, 0x43, 0xE7, 0xBC, 0x46, 0x10, 0x21, 0x4F, 0xF4, -+0xC0, 0x75, 0xB9, 0xE7, 0xBC, 0x46, 0x40, 0x21, 0x4F, 0xF4, 0x80, 0x75, 0xB4, 0xE7, 0x09, 0x01, 0x09, 0xB2, 0xED, 0x01, -+0xBC, 0x46, 0xAF, 0xE7, 0xB0, 0xF8, 0xB4, 0x30, 0x00, 0x2B, 0x4A, 0xD0, 0x2D, 0xE9, 0xF0, 0x4F, 0x03, 0xF1, 0xFF, 0x3B, -+0x1F, 0xFA, 0x8B, 0xFB, 0xBB, 0xF1, 0x01, 0x0F, 0x85, 0xB0, 0x8A, 0x46, 0x00, 0xF1, 0x10, 0x09, 0x3A, 0xD9, 0x01, 0x25, -+0x2F, 0x46, 0x0A, 0xF1, 0x04, 0x04, 0x4E, 0x46, 0x00, 0x21, 0x0D, 0xE0, 0x13, 0x43, 0x04, 0xD1, 0x73, 0x7A, 0x13, 0xB9, -+0x73, 0x7D, 0x01, 0x2B, 0x0B, 0xD0, 0x01, 0x35, 0xAF, 0xB2, 0x06, 0xF1, 0x0C, 0x08, 0x5F, 0x45, 0x46, 0x46, 0x20, 0xD2, -+0x22, 0x68, 0x54, 0xF8, 0x04, 0x3F, 0x9A, 0x42, 0xEC, 0xD9, 0x0C, 0x22, 0x06, 0xEB, 0x02, 0x08, 0x31, 0x46, 0x01, 0xA8, -+0x04, 0xF0, 0x3E, 0xFB, 0x30, 0x46, 0x41, 0x46, 0x0C, 0x22, 0x04, 0xF0, 0x39, 0xFB, 0x0C, 0x22, 0x01, 0xA9, 0x40, 0x46, -+0x04, 0xF0, 0x34, 0xFB, 0x01, 0x35, 0x54, 0xE9, 0x01, 0x32, 0x39, 0x46, 0xAF, 0xB2, 0x5F, 0x45, 0x44, 0xF8, 0x04, 0x2C, -+0x23, 0x60, 0x46, 0x46, 0xDE, 0xD3, 0x19, 0xB1, 0x8B, 0x46, 0xBB, 0xF1, 0x01, 0x0F, 0xC4, 0xD8, 0x05, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x4F, 0xB0, 0xF8, 0xB4, 0x50, 0x83, 0xB0, 0x06, 0x46, 0x89, 0x46, 0x00, 0x2D, -+0x00, 0xF0, 0xE2, 0x80, 0x6F, 0x1E, 0x1F, 0xFA, 0x87, 0xF8, 0x08, 0xEB, 0x48, 0x08, 0x00, 0xF1, 0x0C, 0x03, 0x03, 0xEB, -+0x88, 0x08, 0x04, 0x46, 0x4F, 0xF0, 0x00, 0x0A, 0x41, 0xF6, 0x98, 0x1B, 0x60, 0x89, 0xFE, 0xF7, 0xAD, 0xFE, 0x30, 0xB9, -+0x63, 0x7B, 0x23, 0xB1, 0x23, 0x89, 0x5B, 0x45, 0x07, 0xD8, 0x4F, 0xF0, 0x01, 0x0A, 0x0C, 0x34, 0x44, 0x45, 0xF1, 0xD1, -+0x4F, 0xEA, 0xCA, 0x00, 0x40, 0xB2, 0x96, 0xF8, 0xA2, 0x40, 0x24, 0xF0, 0x08, 0x04, 0x04, 0x43, 0xE4, 0xB2, 0x86, 0xF8, -+0xA2, 0x40, 0x14, 0xF0, 0x02, 0x04, 0x09, 0xD1, 0x05, 0xF1, 0x80, 0x43, 0x01, 0x3B, 0xD9, 0xF8, 0x00, 0x20, 0x59, 0xF8, -+0x23, 0x30, 0x9A, 0x42, 0x00, 0xF2, 0x9C, 0x80, 0x1F, 0xFA, 0x87, 0xFB, 0xCD, 0xF8, 0x00, 0xB0, 0x4F, 0xF0, 0x02, 0x08, -+0x00, 0x9C, 0xA6, 0xF8, 0x88, 0xB0, 0x04, 0xEB, 0x44, 0x03, 0x06, 0xEB, 0x83, 0x03, 0x58, 0x89, 0xFE, 0xF7, 0x7A, 0xFE, -+0x63, 0x00, 0x01, 0x93, 0xE0, 0xB9, 0x00, 0x2F, 0x13, 0xDD, 0x82, 0x46, 0x84, 0x46, 0x0C, 0xEB, 0x4C, 0x0C, 0x06, 0xEB, -+0x8C, 0x04, 0x60, 0x89, 0xFE, 0xF7, 0x6C, 0xFE, 0x0A, 0xF1, 0x01, 0x03, 0x1F, 0xFA, 0x83, 0xFA, 0xD4, 0x46, 0x10, 0xB1, -+0x4F, 0xF0, 0x00, 0x03, 0xA3, 0x73, 0xBA, 0x45, 0xED, 0xDB, 0xDD, 0xE9, 0x00, 0x23, 0x13, 0x44, 0x06, 0xEB, 0x83, 0x04, -+0x01, 0x23, 0xA3, 0x73, 0xA8, 0x45, 0xA6, 0xF8, 0x8A, 0xB0, 0x76, 0xD2, 0xA5, 0xEB, 0x08, 0x03, 0x03, 0xEB, 0x43, 0x03, -+0x06, 0xEB, 0x83, 0x03, 0x03, 0xE0, 0x1F, 0xFA, 0x80, 0xF8, 0xA8, 0x45, 0x6B, 0xD0, 0x99, 0x7B, 0x08, 0xF1, 0x01, 0x00, -+0x0C, 0x3B, 0x00, 0x29, 0xF5, 0xD0, 0xA5, 0xEB, 0x08, 0x00, 0x08, 0xF1, 0x01, 0x08, 0x1F, 0xFA, 0x88, 0xF8, 0x80, 0xB2, -+0x45, 0x45, 0xA6, 0xF8, 0x8A, 0x00, 0x58, 0xD9, 0xA5, 0xEB, 0x08, 0x05, 0xA7, 0xEB, 0x08, 0x08, 0x4F, 0xEA, 0x18, 0x48, -+0x05, 0xEB, 0x45, 0x03, 0x4F, 0xEA, 0x08, 0x48, 0x06, 0xEB, 0x83, 0x03, 0x02, 0xE0, 0x01, 0x3D, 0x45, 0x45, 0x48, 0xD0, -+0x99, 0x7B, 0x0C, 0x3B, 0x00, 0x29, 0xF8, 0xD0, 0x05, 0xEB, 0x45, 0x03, 0x06, 0xEB, 0x83, 0x03, 0x59, 0xF8, 0x25, 0x20, -+0xB3, 0xF8, 0x08, 0xE0, 0x30, 0xB3, 0x31, 0x46, 0x00, 0x23, 0x4F, 0xF2, 0x32, 0x38, 0x0C, 0xE0, 0x59, 0xF8, 0x23, 0x70, -+0x97, 0x42, 0x02, 0xD3, 0xA6, 0x46, 0x3A, 0x46, 0x1D, 0x46, 0x01, 0x33, 0x9C, 0xB2, 0xA0, 0x42, 0x01, 0xF1, 0x0C, 0x01, -+0x14, 0xD9, 0x8C, 0x7B, 0x9F, 0xB2, 0x00, 0x2C, 0xF5, 0xD0, 0x5F, 0x45, 0xF3, 0xD0, 0x0C, 0x89, 0x44, 0x45, 0xE9, 0xD8, -+0x74, 0x45, 0xEE, 0xD3, 0x59, 0xF8, 0x23, 0x20, 0x1D, 0x46, 0x01, 0x33, 0xA6, 0x46, 0x9C, 0xB2, 0xA0, 0x42, 0x01, 0xF1, -+0x0C, 0x01, 0xEA, 0xD8, 0x00, 0x23, 0xA6, 0xF8, 0x8C, 0x50, 0xA6, 0xF8, 0x8E, 0x30, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0x07, 0xEB, 0x47, 0x03, 0x06, 0xEB, 0x83, 0x03, 0x5B, 0x7B, 0x00, 0x2B, 0x3F, 0xF4, 0x5C, 0xAF, 0x00, 0x94, 0xA3, 0x46, -+0x4F, 0xF0, 0x01, 0x08, 0x5C, 0xE7, 0x05, 0x46, 0xB8, 0xE7, 0x5D, 0x46, 0x58, 0x46, 0xB5, 0xE7, 0x28, 0x46, 0x4F, 0xF0, -+0xFF, 0x37, 0x38, 0xE7, 0xC1, 0xF3, 0xC2, 0x23, 0x05, 0x2B, 0x5B, 0xD8, 0xDF, 0xE8, 0x03, 0xF0, 0x03, 0x03, 0x27, 0x27, -+0x0B, 0x32, 0xB0, 0xF8, 0xAA, 0x00, 0x01, 0xF0, 0x7F, 0x01, 0xC8, 0x40, 0x00, 0xF0, 0x01, 0x00, 0x70, 0x47, 0xC1, 0xF3, -+0x02, 0x12, 0xB0, 0xF8, 0xA6, 0x00, 0x53, 0x00, 0x18, 0x41, 0x00, 0xF0, 0x03, 0x00, 0x07, 0x30, 0x01, 0xF0, 0x0F, 0x03, -+0x83, 0x42, 0xCC, 0xBF, 0x00, 0x20, 0x01, 0x20, 0x06, 0x2B, 0xC1, 0xF3, 0xC1, 0x11, 0x24, 0xD0, 0x09, 0x2B, 0x24, 0xD1, -+0x21, 0xBB, 0x02, 0x2A, 0x21, 0xD0, 0x05, 0x2A, 0x18, 0xBF, 0x00, 0x20, 0x70, 0x47, 0xC1, 0xF3, 0xC1, 0x03, 0x18, 0x44, -+0x01, 0xF0, 0x07, 0x01, 0x90, 0xF8, 0xA6, 0x00, 0xC8, 0x40, 0x00, 0xF0, 0x01, 0x00, 0x70, 0x47, 0xB0, 0xF8, 0xA6, 0x00, -+0xC1, 0xF3, 0x02, 0x13, 0x5B, 0x00, 0x18, 0x41, 0x00, 0xF0, 0x03, 0x00, 0x40, 0x00, 0x07, 0x30, 0x01, 0xF0, 0x0F, 0x01, -+0x81, 0x42, 0xCC, 0xBF, 0x00, 0x20, 0x01, 0x20, 0x70, 0x47, 0x02, 0x29, 0x06, 0xD0, 0x70, 0x47, 0x02, 0x29, 0x09, 0xD1, -+0x05, 0x2A, 0x08, 0xBF, 0x00, 0x20, 0x70, 0x47, 0x03, 0x2A, 0x09, 0xD0, 0x06, 0x2A, 0x08, 0xBF, 0x00, 0x20, 0x70, 0x47, -+0x03, 0x29, 0xF0, 0xD1, 0x02, 0x2A, 0x08, 0xBF, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0xEA, 0xE7, 0x01, 0x20, 0x70, 0x47, -+0x2D, 0xE9, 0xF0, 0x4F, 0x82, 0x46, 0xB0, 0xF8, 0x88, 0x70, 0xB0, 0xF8, 0x8A, 0x00, 0x9A, 0xF8, 0xAD, 0x30, 0x9A, 0xF8, -+0xAE, 0x60, 0x00, 0xEB, 0x40, 0x00, 0x07, 0xEB, 0x47, 0x07, 0x83, 0xB0, 0x0A, 0xEB, 0x80, 0x0C, 0x0A, 0xEB, 0x87, 0x07, -+0x14, 0x46, 0x0D, 0x46, 0x08, 0x46, 0x52, 0x00, 0x4F, 0xF0, 0xFF, 0x31, 0x7F, 0x89, 0xBC, 0xF8, 0x0A, 0x80, 0x00, 0x93, -+0xCD, 0xF7, 0x86, 0xF9, 0x00, 0x2C, 0x7E, 0xD0, 0x00, 0x9B, 0xA6, 0xEB, 0x03, 0x09, 0x01, 0x3C, 0x09, 0xF1, 0x01, 0x03, -+0xE4, 0xB2, 0x01, 0x93, 0x4F, 0xF0, 0x00, 0x0B, 0x5F, 0xFA, 0x8B, 0xF3, 0x05, 0x2B, 0x5E, 0xD8, 0xDF, 0xE8, 0x03, 0xF0, -+0x59, 0x41, 0x32, 0x23, 0x13, 0x03, 0x41, 0x46, 0x50, 0x46, 0xFE, 0xF7, 0xF9, 0xFF, 0x80, 0x45, 0x81, 0x46, 0x52, 0xD0, -+0x01, 0x46, 0x50, 0x46, 0xFF, 0xF7, 0x5E, 0xFF, 0x00, 0x28, 0x4C, 0xD0, 0xA5, 0xF8, 0x0A, 0x90, 0x49, 0xE0, 0x41, 0x46, -+0x50, 0x46, 0xFF, 0xF7, 0x77, 0xF8, 0x80, 0x45, 0x81, 0x46, 0x42, 0xD0, 0x01, 0x46, 0x50, 0x46, 0xFF, 0xF7, 0x4E, 0xFF, -+0x00, 0x28, 0x3C, 0xD0, 0xA5, 0xF8, 0x08, 0x90, 0x39, 0xE0, 0x39, 0x46, 0x50, 0x46, 0xFE, 0xF7, 0xD9, 0xFF, 0xB8, 0x42, -+0x81, 0x46, 0x32, 0xD0, 0x01, 0x46, 0x50, 0x46, 0xFF, 0xF7, 0x3E, 0xFF, 0x68, 0xB3, 0xA5, 0xF8, 0x06, 0x90, 0x2A, 0xE0, -+0x39, 0x46, 0x50, 0x46, 0xFF, 0xF7, 0x58, 0xF8, 0xB8, 0x42, 0x81, 0x46, 0x23, 0xD0, 0x01, 0x46, 0x50, 0x46, 0xFF, 0xF7, -+0x2F, 0xFF, 0xF0, 0xB1, 0xA5, 0xF8, 0x04, 0x90, 0x1B, 0xE0, 0x00, 0x9B, 0x03, 0x2B, 0x03, 0xD8, 0x9A, 0xF8, 0xA2, 0x30, -+0x19, 0x07, 0x3B, 0xD4, 0xC7, 0xF3, 0xC2, 0x23, 0x05, 0x2B, 0x4F, 0xEA, 0xD7, 0x22, 0x23, 0xD0, 0x12, 0xF0, 0x06, 0x0F, -+0x0B, 0xD0, 0x9A, 0xF8, 0xB1, 0x30, 0x01, 0x2B, 0x07, 0xD1, 0x87, 0xF4, 0x00, 0x73, 0x6B, 0x80, 0x03, 0xE0, 0x50, 0x46, -+0xFF, 0xF7, 0x1E, 0xFC, 0x28, 0x80, 0x03, 0x2E, 0x09, 0xD8, 0x35, 0xF8, 0x1B, 0x20, 0x4F, 0xF6, 0xFF, 0x73, 0x9A, 0x42, -+0x04, 0xBF, 0x46, 0xF4, 0x80, 0x63, 0x25, 0xF8, 0x1B, 0x30, 0x5C, 0x45, 0x0B, 0xF1, 0x01, 0x03, 0x01, 0xD0, 0x9B, 0x46, -+0x8A, 0xE7, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1A, 0x4A, 0xC7, 0xF3, 0x41, 0x23, 0x01, 0x33, 0xA2, 0xFB, 0x03, 0x21, -+0x21, 0xF0, 0x01, 0x02, 0x02, 0xEB, 0x51, 0x02, 0x27, 0xF4, 0xC0, 0x67, 0x9B, 0x1A, 0x47, 0xEA, 0x43, 0x23, 0x6B, 0x80, -+0xBF, 0xB2, 0xD8, 0xE7, 0x04, 0xF0, 0x82, 0xF9, 0x01, 0x99, 0x00, 0xF0, 0x7F, 0x02, 0x92, 0xFB, 0xF1, 0xF3, 0x01, 0xFB, -+0x13, 0x23, 0x00, 0x9A, 0x13, 0x44, 0xBA, 0xF8, 0xAA, 0x20, 0xDB, 0xB2, 0xDA, 0x40, 0xD2, 0x07, 0x0F, 0xD5, 0x00, 0x2B, -+0x08, 0xBF, 0x33, 0x46, 0x5A, 0x1E, 0x02, 0x2A, 0x6B, 0x80, 0xCC, 0xD8, 0x9A, 0xF8, 0xB2, 0x10, 0x00, 0xF4, 0x80, 0x62, -+0x42, 0xEA, 0x81, 0x22, 0x13, 0x43, 0x6B, 0x80, 0xC3, 0xE7, 0x33, 0x46, 0xF0, 0xE7, 0x00, 0xBF, 0xAB, 0xAA, 0xAA, 0xAA, -+0x2D, 0xE9, 0xF0, 0x47, 0x05, 0x46, 0x84, 0xB0, 0x01, 0xA9, 0x06, 0x22, 0xFF, 0xF7, 0x1C, 0xFF, 0xB5, 0xF8, 0xB4, 0x10, -+0x01, 0x29, 0x30, 0xD9, 0x00, 0x26, 0x01, 0x24, 0xB0, 0x46, 0xA1, 0x46, 0x4F, 0xF6, 0xFF, 0x77, 0x18, 0xE0, 0xB5, 0xF8, -+0x88, 0x20, 0xA2, 0x42, 0x21, 0xD0, 0xB5, 0xF8, 0x8A, 0x20, 0xA2, 0x42, 0x1D, 0xD0, 0xB5, 0xF8, 0x8C, 0x20, 0xA2, 0x42, -+0x19, 0xD0, 0x05, 0x2E, 0x17, 0xD8, 0x04, 0xAA, 0x02, 0xEB, 0x46, 0x02, 0x32, 0xF8, 0x0C, 0xEC, 0xBE, 0x45, 0x17, 0xD1, -+0xA1, 0x42, 0x06, 0xF1, 0x01, 0x06, 0x10, 0xD9, 0x04, 0xEB, 0x44, 0x03, 0x05, 0xEB, 0x83, 0x03, 0x4F, 0xEA, 0x44, 0x0C, -+0xB3, 0xF9, 0x08, 0x20, 0x00, 0x2A, 0xDC, 0xDA, 0x1A, 0x7B, 0x0A, 0x2A, 0xD9, 0xD8, 0x01, 0x34, 0xA4, 0xB2, 0xA1, 0x42, -+0xEE, 0xD8, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x59, 0xB1, 0x2A, 0x46, 0x00, 0x20, 0xB2, 0xF8, 0x0A, 0xA0, 0xF2, 0x45, -+0x00, 0xF1, 0x01, 0x00, 0x02, 0xF1, 0x0C, 0x02, 0xDC, 0xD0, 0x88, 0x42, 0xF5, 0xD1, 0x0C, 0xEB, 0x04, 0x02, 0x05, 0xEB, -+0x82, 0x02, 0xA3, 0xF8, 0x0A, 0xE0, 0xA3, 0xF8, 0x08, 0x80, 0x21, 0x46, 0x82, 0xF8, 0x0D, 0x80, 0x28, 0x46, 0xA3, 0xF8, -+0x04, 0x80, 0xA3, 0xF8, 0x06, 0x80, 0x01, 0x34, 0x82, 0xF8, 0x0C, 0x80, 0x82, 0xF8, 0x0E, 0x90, 0xFF, 0xF7, 0x12, 0xF8, -+0xA4, 0xB2, 0xB5, 0xF8, 0xB4, 0x10, 0xBF, 0xE7, 0x30, 0xB4, 0x90, 0xF8, 0xA5, 0x30, 0x05, 0x2B, 0x00, 0xF2, 0x8C, 0x80, -+0xDF, 0xE8, 0x03, 0xF0, 0x36, 0x36, 0x03, 0x03, 0x70, 0x57, 0x90, 0xF8, 0xAF, 0x50, 0x90, 0xF8, 0xB1, 0x20, 0x90, 0xF8, -+0xB0, 0x30, 0x90, 0xF8, 0xA6, 0x40, 0x01, 0x35, 0x95, 0x40, 0x03, 0xFB, 0x05, 0x55, 0xAD, 0xB2, 0x08, 0x21, 0x00, 0x23, -+0x04, 0xF0, 0x01, 0x02, 0x12, 0xFB, 0x05, 0xF2, 0x13, 0x44, 0x01, 0x39, 0x9B, 0xB2, 0x4F, 0xEA, 0x54, 0x04, 0xF5, 0xD1, -+0xB0, 0xF8, 0xAA, 0x20, 0x90, 0xF8, 0xB2, 0x10, 0xC2, 0xF3, 0x80, 0x04, 0xC2, 0xF3, 0x40, 0x00, 0xC1, 0xF1, 0x01, 0x01, -+0x20, 0x44, 0x88, 0x40, 0x02, 0xF0, 0x01, 0x04, 0xC2, 0xF3, 0xC0, 0x02, 0x20, 0x44, 0x8A, 0x40, 0x10, 0x44, 0x18, 0x44, -+0x80, 0xB2, 0x0A, 0x28, 0x28, 0xBF, 0x0A, 0x20, 0x30, 0xBC, 0x70, 0x47, 0xB0, 0xF8, 0xAA, 0x10, 0x90, 0xF8, 0xB2, 0x30, -+0xC1, 0xF3, 0x80, 0x02, 0xC1, 0xF3, 0x40, 0x00, 0xC3, 0xF1, 0x01, 0x03, 0x10, 0x44, 0x98, 0x40, 0x01, 0xF0, 0x01, 0x04, -+0xC1, 0xF3, 0xC0, 0x02, 0x02, 0xFA, 0x03, 0xF3, 0x20, 0x44, 0x13, 0xFA, 0x80, 0xF0, 0x80, 0xB2, 0x04, 0x23, 0x41, 0xFA, -+0x03, 0xF2, 0x02, 0xF0, 0x01, 0x02, 0x01, 0x33, 0x10, 0x44, 0x0C, 0x2B, 0x80, 0xB2, 0xF6, 0xD1, 0xD9, 0xE7, 0x90, 0xF8, -+0xB1, 0x30, 0xB0, 0xF8, 0xA6, 0x20, 0x90, 0xF8, 0xAF, 0x40, 0x90, 0xF8, 0xB0, 0x10, 0x58, 0x1C, 0x02, 0xF0, 0x03, 0x03, -+0x04, 0xFB, 0x00, 0x00, 0x01, 0x2B, 0x01, 0xFB, 0x00, 0x00, 0x1F, 0xD0, 0x02, 0x2B, 0x14, 0xBF, 0x08, 0x23, 0x0A, 0x23, -+0x10, 0xFB, 0x03, 0xF0, 0x80, 0xB2, 0xC0, 0xE7, 0xB0, 0xF8, 0xA6, 0x20, 0x90, 0xF8, 0xAF, 0x30, 0x90, 0xF8, 0xB1, 0x40, -+0x90, 0xF8, 0xB0, 0x10, 0x02, 0xF0, 0x03, 0x02, 0x01, 0x33, 0x01, 0x3A, 0x03, 0xFA, 0x04, 0xF0, 0x01, 0x2A, 0x8C, 0xBF, -+0x08, 0x23, 0x09, 0x23, 0x01, 0xFB, 0x00, 0x00, 0x10, 0xFB, 0x03, 0xF0, 0x80, 0xB2, 0xA8, 0xE7, 0x09, 0x23, 0xE1, 0xE7, -+0x00, 0x20, 0xA7, 0xE7, 0x2D, 0xE9, 0xF8, 0x4F, 0xB0, 0xF8, 0xB4, 0x40, 0x05, 0x46, 0x00, 0x2C, 0x00, 0xF0, 0xF4, 0x80, -+0x04, 0xF1, 0xFF, 0x38, 0x1F, 0xFA, 0x88, 0xF1, 0x01, 0xEB, 0x41, 0x03, 0x00, 0xF1, 0x0C, 0x01, 0x01, 0xEB, 0x83, 0x01, -+0x4F, 0xF6, 0xFF, 0x76, 0x03, 0x46, 0x00, 0x22, 0x01, 0x20, 0x5E, 0x81, 0x9A, 0x80, 0xDA, 0x80, 0x1A, 0x81, 0x1A, 0x73, -+0x5A, 0x73, 0x98, 0x73, 0x0C, 0x33, 0x99, 0x42, 0xF5, 0xD1, 0xC1, 0x46, 0x95, 0xF8, 0xA5, 0x30, 0x05, 0x2B, 0x00, 0xF2, -+0xD9, 0x80, 0xDF, 0xE8, 0x03, 0xF0, 0x4E, 0x4E, 0x03, 0x03, 0x8A, 0x5E, 0x95, 0xF8, 0xAD, 0x20, 0xDB, 0x02, 0x00, 0x2A, -+0x00, 0xF0, 0xC7, 0x80, 0x99, 0xB2, 0x95, 0xF8, 0xB0, 0x20, 0x69, 0x81, 0xA9, 0x18, 0x95, 0xF8, 0xB1, 0x60, 0x91, 0xF8, -+0xA6, 0x70, 0x95, 0xF8, 0xAF, 0x00, 0x43, 0xEA, 0x46, 0x23, 0xB7, 0xFA, 0x87, 0xF7, 0xC7, 0xF1, 0x1F, 0x07, 0x43, 0xEA, -+0xC0, 0x13, 0xFF, 0xB2, 0x43, 0xEA, 0xC2, 0x03, 0x3B, 0x43, 0x9F, 0xB2, 0x09, 0xEB, 0x49, 0x09, 0x05, 0xEB, 0x89, 0x03, -+0x01, 0x26, 0x46, 0x45, 0x5F, 0x81, 0x80, 0xF2, 0x9B, 0x80, 0x28, 0x46, 0xFF, 0xF7, 0x7E, 0xFA, 0xB5, 0xF8, 0xB4, 0x40, -+0x00, 0x2C, 0x00, 0xF0, 0x87, 0x80, 0x2B, 0x46, 0x00, 0x22, 0x02, 0xE0, 0xA2, 0x42, 0x00, 0xF0, 0x81, 0x80, 0x59, 0x89, -+0x81, 0x42, 0x02, 0xF1, 0x01, 0x02, 0x03, 0xF1, 0x0C, 0x03, 0xF5, 0xD1, 0x01, 0x3C, 0xA6, 0x42, 0xE7, 0xDB, 0x00, 0x24, -+0xA1, 0xB2, 0x28, 0x46, 0xFE, 0xF7, 0x0A, 0xFF, 0xB5, 0xF8, 0xB4, 0x30, 0x01, 0x34, 0x9C, 0x42, 0xF6, 0xD3, 0xBD, 0xE8, -+0xF8, 0x8F, 0x95, 0xF8, 0xAD, 0x20, 0x00, 0x2A, 0x7A, 0xD0, 0x92, 0xB2, 0x95, 0xF8, 0xB2, 0x10, 0x95, 0xF8, 0xAE, 0x70, -+0x6A, 0x81, 0xDB, 0x02, 0x43, 0xEA, 0x81, 0x23, 0x3B, 0x43, 0x9F, 0xB2, 0xC2, 0xE7, 0x95, 0xF8, 0xAD, 0x30, 0x00, 0x2B, -+0x67, 0xD0, 0x95, 0xF8, 0xBC, 0x30, 0x00, 0x2B, 0x0C, 0xBF, 0x4F, 0xF4, 0x28, 0x52, 0x4F, 0xF4, 0xD4, 0x42, 0x95, 0xF8, -+0xB0, 0x30, 0xB5, 0xF8, 0xA6, 0x60, 0x6A, 0x81, 0x5A, 0x00, 0x16, 0x41, 0x95, 0xF8, 0xAF, 0xA0, 0x06, 0xF0, 0x03, 0x06, -+0x1B, 0x01, 0x76, 0x00, 0x07, 0x36, 0x43, 0xEA, 0xCA, 0x1A, 0x4A, 0xEA, 0x06, 0x07, 0x47, 0xF4, 0x20, 0x57, 0x39, 0x46, -+0x28, 0x46, 0xFF, 0xF7, 0x1B, 0xFD, 0x01, 0x3E, 0xF3, 0xB2, 0xB6, 0xB2, 0x00, 0x28, 0x99, 0xD1, 0x06, 0x2B, 0xF0, 0xD1, -+0x96, 0xE7, 0x95, 0xF8, 0xB0, 0xA0, 0xB5, 0xF8, 0xA6, 0xB0, 0x95, 0xF8, 0xAF, 0x60, 0x95, 0xF8, 0xB1, 0x30, 0x4F, 0xEA, -+0x4A, 0x02, 0x4B, 0xFA, 0x02, 0xFB, 0xF6, 0x01, 0x46, 0xEA, 0x43, 0x26, 0x0B, 0xF0, 0x03, 0x0B, 0x4F, 0xF4, 0x00, 0x53, -+0x4F, 0xEA, 0x0A, 0x1A, 0x0B, 0xF1, 0x07, 0x0B, 0x36, 0xB2, 0x6B, 0x81, 0x4A, 0xEA, 0x0B, 0x07, 0x37, 0x43, 0x47, 0xF4, -+0x00, 0x57, 0xBF, 0xB2, 0x39, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0xF0, 0xFC, 0x0B, 0xF1, 0xFF, 0x3B, 0x5F, 0xFA, 0x8B, 0xF3, -+0x1F, 0xFA, 0x8B, 0xFB, 0x00, 0x28, 0x7F, 0xF4, 0x6B, 0xAF, 0x06, 0x2B, 0xEA, 0xD1, 0x67, 0xE7, 0x06, 0xEB, 0x46, 0x03, -+0x01, 0x36, 0x05, 0xEB, 0x83, 0x03, 0xB6, 0xB2, 0x04, 0xF1, 0xFF, 0x38, 0x46, 0x45, 0x58, 0x81, 0xFF, 0xF6, 0x65, 0xAF, -+0x00, 0x2C, 0x7F, 0xF4, 0x7A, 0xAF, 0xBD, 0xE8, 0xF8, 0x8F, 0x4F, 0xF4, 0x80, 0x62, 0x9C, 0xE7, 0x4F, 0xF4, 0x80, 0x62, -+0x82, 0xE7, 0x4F, 0xF4, 0x80, 0x61, 0x36, 0xE7, 0x4F, 0xF0, 0xFF, 0x39, 0xC8, 0x46, 0x21, 0xE7, 0x00, 0x27, 0x6F, 0x81, -+0x46, 0xE7, 0x00, 0xBF, 0x90, 0xF8, 0xAD, 0x30, 0x0B, 0x2B, 0xF0, 0xB4, 0x0C, 0xD9, 0x90, 0xF8, 0xA2, 0x20, 0x04, 0x23, -+0x01, 0x24, 0x22, 0xF0, 0x04, 0x02, 0x13, 0x43, 0x80, 0xF8, 0xA2, 0x30, 0x01, 0xB1, 0x0C, 0x70, 0xF0, 0xBC, 0x70, 0x47, -+0xB0, 0xF8, 0x88, 0x30, 0x03, 0xEB, 0x43, 0x03, 0x00, 0xEB, 0x83, 0x03, 0x5B, 0x89, 0xDB, 0x12, 0x13, 0xF0, 0x06, 0x0F, -+0x04, 0xD1, 0x00, 0x23, 0x90, 0xF8, 0xA2, 0x20, 0x1C, 0x46, 0xE6, 0xE7, 0xB0, 0xF8, 0x8A, 0x30, 0x03, 0xEB, 0x43, 0x03, -+0x00, 0xEB, 0x83, 0x03, 0x5B, 0x89, 0xDB, 0x12, 0x13, 0xF0, 0x06, 0x0F, 0xEF, 0xD0, 0xB0, 0xF8, 0x8C, 0x30, 0x03, 0xEB, -+0x43, 0x03, 0x00, 0xEB, 0x83, 0x03, 0x5B, 0x89, 0xDB, 0x12, 0x13, 0xF0, 0x06, 0x0F, 0xE4, 0xD0, 0x90, 0xF8, 0xA2, 0x20, -+0x12, 0xF0, 0x20, 0x04, 0x20, 0xD1, 0x90, 0xF8, 0xA4, 0x30, 0x44, 0x33, 0x30, 0xF8, 0x13, 0x30, 0x03, 0xEB, 0x43, 0x03, -+0x00, 0xEB, 0x83, 0x05, 0x6B, 0x89, 0x13, 0xF4, 0x00, 0x5F, 0x4F, 0xEA, 0xD3, 0x27, 0xC3, 0xF3, 0xC2, 0x26, 0x12, 0xD1, -+0x17, 0xF0, 0x06, 0x0F, 0x1D, 0xD1, 0x03, 0xF0, 0x7F, 0x03, 0x02, 0x2B, 0x15, 0xD9, 0x2D, 0x89, 0x40, 0xF2, 0x8E, 0x23, -+0x9D, 0x42, 0x86, 0xBF, 0x01, 0x24, 0x04, 0x23, 0x00, 0x23, 0xAA, 0xE7, 0x04, 0x23, 0x01, 0x24, 0xA7, 0xE7, 0x07, 0x2E, -+0x07, 0xD0, 0x03, 0xF0, 0x0F, 0x06, 0xC3, 0xF3, 0x02, 0x13, 0x02, 0x2E, 0xEB, 0xD8, 0x00, 0x2B, 0xE9, 0xD1, 0x2D, 0x89, -+0x41, 0xF6, 0x98, 0x13, 0xE8, 0xE7, 0x03, 0xF0, 0x07, 0x06, 0xC3, 0xF3, 0xC1, 0x03, 0xF2, 0xE7, 0xF8, 0xB5, 0x90, 0xF8, -+0xA2, 0x60, 0x16, 0xF0, 0x10, 0x05, 0x04, 0x46, 0x35, 0xD0, 0xB0, 0xF8, 0xB4, 0x00, 0x00, 0x28, 0x5F, 0xD0, 0xB4, 0xF8, -+0xBA, 0x70, 0x00, 0x23, 0x02, 0xE0, 0x82, 0x42, 0xCB, 0xB2, 0x46, 0xD2, 0x03, 0xEB, 0x43, 0x02, 0x04, 0xEB, 0x82, 0x02, -+0x59, 0x1C, 0x55, 0x89, 0xBD, 0x42, 0xCA, 0xB2, 0xF3, 0xD1, 0x9A, 0xB2, 0xA4, 0xF8, 0x88, 0x20, 0xA4, 0xF8, 0x8A, 0x20, -+0xA4, 0xF8, 0x8C, 0x20, 0x01, 0x38, 0x80, 0xB2, 0x04, 0xF1, 0x0C, 0x03, 0x00, 0xEB, 0x40, 0x00, 0x03, 0xEB, 0x80, 0x00, -+0x00, 0x22, 0x23, 0x46, 0x9A, 0x80, 0xDA, 0x80, 0x0C, 0x33, 0x98, 0x42, 0xFA, 0xD1, 0x26, 0xF0, 0x30, 0x06, 0x46, 0xF0, -+0x20, 0x06, 0x00, 0x23, 0x84, 0xF8, 0xA2, 0x60, 0x84, 0xF8, 0x9B, 0x30, 0x01, 0x25, 0x28, 0x46, 0xF8, 0xBD, 0x90, 0xF8, -+0x88, 0x00, 0x0C, 0x23, 0x03, 0xFB, 0x00, 0x40, 0x04, 0x30, 0xFE, 0xF7, 0x73, 0xFC, 0xB4, 0xF8, 0xB4, 0x30, 0x00, 0x2B, -+0xF1, 0xD0, 0x01, 0x3B, 0x9A, 0xB2, 0x02, 0xEB, 0x42, 0x03, 0x04, 0xF1, 0x0C, 0x02, 0x02, 0xEB, 0x83, 0x02, 0x2B, 0x46, -+0xA3, 0x80, 0xE3, 0x80, 0x0C, 0x34, 0x94, 0x42, 0xFA, 0xD1, 0x28, 0x46, 0xF8, 0xBD, 0xC1, 0xD1, 0x01, 0x38, 0xC3, 0xB2, -+0x03, 0xEB, 0x43, 0x03, 0x04, 0xEB, 0x83, 0x03, 0xC2, 0xB2, 0x00, 0x21, 0x5F, 0x81, 0x19, 0x81, 0xA4, 0xF8, 0x88, 0x20, -+0xA4, 0xF8, 0x8A, 0x20, 0xA4, 0xF8, 0x8C, 0x20, 0xB7, 0xE7, 0xB4, 0xF8, 0xBA, 0x20, 0xA4, 0xF8, 0xFE, 0x2B, 0x4F, 0xF0, -+0xFF, 0x11, 0xFF, 0x22, 0xA4, 0xF8, 0xFC, 0x0B, 0xC4, 0xF8, 0x88, 0x10, 0xA4, 0xF8, 0x8C, 0x20, 0xB7, 0xE7, 0x00, 0xBF, -+0xC2, 0x6C, 0x12, 0x69, 0xC2, 0xF3, 0x07, 0x21, 0xC2, 0xF3, 0x00, 0x42, 0x0A, 0x44, 0x00, 0x23, 0x01, 0x31, 0xFE, 0xF7, -+0xC9, 0xB9, 0x00, 0xBF, 0x8A, 0x1A, 0x01, 0x23, 0xFE, 0xF7, 0xC4, 0xB9, 0xC3, 0x88, 0x99, 0x04, 0x30, 0xB4, 0xC3, 0xF3, -+0xC2, 0x22, 0x11, 0xD4, 0xD9, 0x0A, 0x11, 0xF0, 0x06, 0x0F, 0x4A, 0xD1, 0x13, 0xF0, 0x7C, 0x0F, 0x03, 0xF0, 0x7F, 0x02, -+0x5D, 0xD1, 0xC3, 0xF3, 0x80, 0x23, 0x43, 0xEA, 0x42, 0x02, 0x3D, 0x4B, 0x30, 0xBC, 0x53, 0xF8, 0x22, 0x00, 0x70, 0x47, -+0x07, 0x2A, 0x37, 0xD0, 0x51, 0x1F, 0x03, 0xF0, 0x0F, 0x04, 0x01, 0x29, 0x37, 0xD8, 0xDF, 0xE8, 0x01, 0xF0, 0x01, 0x1B, -+0xC3, 0xF3, 0x00, 0x21, 0x4A, 0x00, 0x11, 0x44, 0x06, 0x22, 0x12, 0xFB, 0x04, 0x12, 0xC3, 0xF3, 0x41, 0x21, 0x0A, 0x44, -+0x31, 0x49, 0x51, 0xF8, 0x22, 0x00, 0xC3, 0xF3, 0xC0, 0x11, 0xC3, 0xF3, 0x02, 0x12, 0xC3, 0xF3, 0x80, 0x33, 0xC8, 0x40, -+0x01, 0x32, 0x30, 0xBC, 0xB0, 0xFB, 0xF2, 0xF0, 0x98, 0x40, 0x70, 0x47, 0x00, 0x7A, 0x00, 0xF0, 0x07, 0x00, 0x02, 0x28, -+0x31, 0xD8, 0x28, 0x49, 0xC3, 0xF3, 0x41, 0x25, 0x03, 0x22, 0x51, 0xF8, 0x20, 0x10, 0x12, 0xFB, 0x04, 0x52, 0xC3, 0xF3, -+0x02, 0x10, 0x01, 0x30, 0x51, 0xF8, 0x22, 0x30, 0xB3, 0xFB, 0xF0, 0xF0, 0x30, 0xBC, 0x70, 0x47, 0x00, 0x20, 0x30, 0xBC, -+0x70, 0x47, 0x03, 0xF0, 0x07, 0x04, 0xC3, 0xF3, 0x40, 0x20, 0xC3, 0xF3, 0xC1, 0x11, 0x40, 0xEA, 0x41, 0x01, 0x41, 0xEA, -+0xC4, 0x04, 0x04, 0x2A, 0x19, 0x49, 0x14, 0xBF, 0xC3, 0xF3, 0xC1, 0x03, 0xC3, 0xF3, 0x02, 0x13, 0x51, 0xF8, 0x24, 0x00, -+0x01, 0x33, 0x30, 0xBC, 0xB0, 0xFB, 0xF3, 0xF0, 0x70, 0x47, 0x14, 0x4B, 0x04, 0x3A, 0x30, 0xBC, 0x53, 0xF8, 0x22, 0x00, -+0x70, 0x47, 0xC2, 0x1E, 0xC2, 0xF3, 0x46, 0x01, 0x02, 0xF0, 0xFE, 0x00, 0x08, 0x44, 0x06, 0x21, 0x11, 0xFB, 0x04, 0x04, -+0xC3, 0xF3, 0x41, 0x21, 0x0C, 0x44, 0x08, 0x49, 0x51, 0xF8, 0x24, 0x00, 0xC3, 0xF3, 0x02, 0x13, 0x02, 0xF0, 0x01, 0x02, -+0x59, 0x1C, 0x30, 0xBC, 0x20, 0xFA, 0x02, 0xF3, 0xB3, 0xFB, 0xF1, 0xF0, 0x70, 0x47, 0x00, 0xBF, 0x54, 0xCC, 0x15, 0x00, -+0x74, 0xCC, 0x15, 0x00, 0xA4, 0xD0, 0x15, 0x00, 0x44, 0xCF, 0x15, 0x00, 0x84, 0xD0, 0x15, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, -+0xB0, 0xF8, 0x96, 0x30, 0x90, 0xF8, 0xA2, 0x80, 0x90, 0xF8, 0xA5, 0x60, 0x03, 0xEB, 0x83, 0x03, 0x5B, 0x00, 0xA0, 0xF8, -+0x98, 0x30, 0x07, 0x46, 0x03, 0xF0, 0xB8, 0xFD, 0xB7, 0xF8, 0xB4, 0x10, 0x80, 0xB2, 0xB0, 0xFB, 0xF1, 0xF3, 0x01, 0xFB, -+0x13, 0x00, 0x00, 0x29, 0x77, 0xD0, 0xB7, 0xF8, 0x88, 0xC0, 0x83, 0xB2, 0x08, 0xF0, 0x02, 0x08, 0x00, 0x20, 0x4F, 0xF2, -+0x33, 0x3E, 0x03, 0x44, 0xB3, 0xFB, 0xF1, 0xF5, 0x01, 0xFB, 0x15, 0x35, 0x05, 0xEB, 0x45, 0x02, 0x92, 0x00, 0xAB, 0xB2, -+0x07, 0xEB, 0x02, 0x0A, 0x9C, 0x45, 0x02, 0xF1, 0x04, 0x02, 0x00, 0xF1, 0x01, 0x00, 0x07, 0xEB, 0x02, 0x04, 0x4F, 0xEA, -+0x45, 0x09, 0x58, 0xD0, 0xBA, 0xF8, 0x08, 0x20, 0x72, 0x45, 0x54, 0xD8, 0xB8, 0xF1, 0x00, 0x0F, 0x05, 0xD0, 0xBA, 0xF8, -+0x0A, 0x20, 0xD2, 0x12, 0x12, 0xF0, 0x06, 0x0F, 0x4B, 0xD0, 0x01, 0x2E, 0x42, 0xD9, 0x0C, 0xEB, 0x4C, 0x0C, 0x07, 0xEB, -+0x8C, 0x0C, 0xBC, 0xF8, 0x0A, 0x30, 0x98, 0x04, 0x4F, 0xEA, 0xD3, 0x26, 0xC3, 0xF3, 0xC2, 0x22, 0x47, 0xD4, 0x16, 0xF0, -+0x06, 0x06, 0x01, 0xD0, 0xC3, 0xF3, 0xC1, 0x06, 0xE3, 0x88, 0x99, 0x04, 0x4F, 0xEA, 0xD3, 0x28, 0xC3, 0xF3, 0xC2, 0x22, -+0x36, 0xD4, 0x18, 0xF0, 0x06, 0x08, 0x01, 0xD0, 0xC3, 0xF3, 0xC1, 0x08, 0xB7, 0xF8, 0x8A, 0x00, 0x00, 0xEB, 0x40, 0x00, -+0x07, 0xEB, 0x80, 0x00, 0xA9, 0x44, 0x04, 0x30, 0x07, 0xEB, 0x89, 0x09, 0xFF, 0xF7, 0xFA, 0xFE, 0x99, 0xF8, 0x0D, 0x30, -+0x82, 0x46, 0x5B, 0xBB, 0xB7, 0xF8, 0x96, 0xB0, 0x20, 0x46, 0xFF, 0xF7, 0xF1, 0xFE, 0x50, 0x45, 0x81, 0x46, 0x0D, 0xD3, -+0x01, 0x3E, 0x46, 0x45, 0x23, 0xD2, 0x23, 0x7A, 0x5B, 0x45, 0x10, 0xD3, 0x97, 0xF8, 0x9A, 0x30, 0x01, 0x33, 0xDB, 0xB2, -+0x02, 0x2B, 0x87, 0xF8, 0x9A, 0x30, 0x29, 0xD8, 0x01, 0x20, 0x87, 0xF8, 0xA0, 0x50, 0x87, 0xF8, 0x9B, 0x00, 0xBD, 0xE8, -+0xF8, 0x8F, 0x88, 0x42, 0x8F, 0xD1, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x8F, 0x07, 0x2A, 0x18, 0xD0, 0xC3, 0xF3, 0x02, 0x18, -+0xC8, 0xE7, 0x07, 0x2A, 0x11, 0xD0, 0xC3, 0xF3, 0x02, 0x16, 0xB7, 0xE7, 0x4F, 0xF0, 0x20, 0x0B, 0xD2, 0xE7, 0xB7, 0xF8, -+0x8C, 0x00, 0x00, 0xEB, 0x40, 0x00, 0x07, 0xEB, 0x80, 0x00, 0x04, 0x30, 0xFF, 0xF7, 0xBE, 0xFE, 0x81, 0x45, 0xDB, 0xD3, -+0xCF, 0xE7, 0x00, 0x26, 0xA6, 0xE7, 0x4F, 0xF0, 0x00, 0x08, 0xAF, 0xE7, 0x0F, 0x2B, 0x84, 0xBF, 0x0F, 0x23, 0x87, 0xF8, -+0x9A, 0x30, 0xD8, 0xE7, 0x90, 0xF8, 0xA2, 0x30, 0x99, 0x06, 0x1F, 0xD4, 0x10, 0xB5, 0x90, 0xF8, 0x9B, 0x20, 0x04, 0x46, -+0xC2, 0xB9, 0xB0, 0xF8, 0x98, 0x20, 0x92, 0xB9, 0x5A, 0x06, 0x0B, 0xD5, 0xB0, 0xF8, 0xB4, 0x20, 0x09, 0x2A, 0x03, 0xD9, -+0xFF, 0xF7, 0x9E, 0xFB, 0x94, 0xF8, 0xA2, 0x30, 0x23, 0xF0, 0x40, 0x03, 0x84, 0xF8, 0xA2, 0x30, 0x20, 0x46, 0xBD, 0xE8, -+0x10, 0x40, 0xFF, 0xF7, 0x29, 0xBF, 0x01, 0x3A, 0xA0, 0xF8, 0x98, 0x20, 0x00, 0x20, 0x10, 0xBD, 0x00, 0x20, 0x70, 0x47, -+0x2D, 0xE9, 0xF0, 0x41, 0x29, 0x4F, 0x2A, 0x4E, 0xD7, 0xF8, 0x00, 0x80, 0x4F, 0xF4, 0x1E, 0x73, 0xB8, 0xF9, 0x00, 0x20, -+0x03, 0xFB, 0x00, 0x63, 0x00, 0x2A, 0xD3, 0xF8, 0x4C, 0x51, 0x8A, 0xB0, 0x04, 0x46, 0x20, 0xDB, 0x28, 0x46, 0xFF, 0xF7, -+0xDF, 0xFB, 0xA5, 0xF8, 0xB4, 0x00, 0xB8, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x22, 0xDB, 0x28, 0x46, 0xFF, 0xF7, 0x6A, 0xFC, -+0x69, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0x3C, 0xF9, 0x28, 0x46, 0x00, 0x21, 0xFF, 0xF7, 0x66, 0xFD, 0x4F, 0xF4, 0x1E, 0x70, -+0x00, 0xFB, 0x04, 0x64, 0x94, 0xF8, 0x56, 0x31, 0x43, 0xF0, 0x01, 0x03, 0x84, 0xF8, 0x56, 0x31, 0x0A, 0xB0, 0xBD, 0xE8, -+0xF0, 0x81, 0x00, 0x2D, 0xDC, 0xD1, 0x12, 0x49, 0x12, 0x48, 0x40, 0xF6, 0xAF, 0x42, 0xF1, 0xF7, 0x03, 0xF9, 0xD7, 0xF8, -+0x00, 0x80, 0xD3, 0xE7, 0x40, 0xB1, 0x0A, 0x28, 0xD9, 0xD9, 0x0C, 0x49, 0x0D, 0x48, 0x40, 0xF6, 0xB4, 0x42, 0xF1, 0xF7, -+0xF7, 0xF8, 0xD2, 0xE7, 0x08, 0x49, 0x0B, 0x48, 0x40, 0xF6, 0xB3, 0x42, 0xF1, 0xF7, 0xF0, 0xF8, 0x3B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0xC7, 0xDA, 0xB5, 0xF8, 0xB4, 0x00, 0xE8, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x68, 0x8E, 0x15, 0x00, 0x0C, 0xCA, 0x15, 0x00, 0xF4, 0xC9, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x41, -+0xDF, 0xF8, 0xBC, 0x80, 0x29, 0x4D, 0xD8, 0xF8, 0x00, 0x40, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x00, 0x53, 0x07, 0x46, -+0xB4, 0xF9, 0x00, 0x00, 0xD3, 0xF8, 0x4C, 0x41, 0x00, 0x28, 0x0D, 0x46, 0x16, 0x46, 0x20, 0xDB, 0x94, 0xF8, 0xAF, 0x30, -+0xAB, 0x42, 0x39, 0xD0, 0xD8, 0xF8, 0x00, 0x30, 0x84, 0xF8, 0xAF, 0x50, 0xB3, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x26, 0xDB, -+0x84, 0xF8, 0xB0, 0x60, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x17, 0xDB, 0x94, 0xF8, 0xA2, 0x30, 0x9A, 0x06, 0x05, 0xD5, -+0x63, 0xF0, 0x7F, 0x03, 0x84, 0xF8, 0xA2, 0x30, 0xBD, 0xE8, 0xF0, 0x81, 0x38, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xFF, 0xF7, -+0x69, 0xBF, 0x00, 0x2C, 0xDC, 0xD1, 0x11, 0x49, 0x11, 0x48, 0x40, 0xF6, 0xCC, 0x42, 0xF1, 0xF7, 0x9F, 0xF8, 0xD5, 0xE7, -+0x07, 0x2E, 0xE5, 0xD9, 0x0C, 0x49, 0x0E, 0x48, 0x40, 0xF6, 0xD4, 0x42, 0xF1, 0xF7, 0x96, 0xF8, 0xDE, 0xE7, 0x03, 0x2D, -+0xD6, 0xD9, 0x08, 0x49, 0x0A, 0x48, 0x40, 0xF6, 0xD2, 0x42, 0xF1, 0xF7, 0x8D, 0xF8, 0xD8, 0xF8, 0x00, 0x30, 0xCD, 0xE7, -+0x94, 0xF8, 0xB0, 0x30, 0xB3, 0x42, 0xC1, 0xD1, 0xD6, 0xE7, 0x00, 0xBF, 0x68, 0x65, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x68, 0x8E, 0x15, 0x00, 0x50, 0xCA, 0x15, 0x00, 0x34, 0xCA, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x4D, 0x4B, 0x8D, 0xB0, 0x1A, 0x68, 0x01, 0x90, 0x04, 0x46, 0x4C, 0x48, 0xB2, 0xF9, 0x00, 0x20, 0x4F, 0xF4, 0x1E, 0x73, -+0x03, 0xFB, 0x04, 0x03, 0x00, 0x2A, 0xD3, 0xF8, 0x4C, 0xB1, 0x0C, 0x46, 0x79, 0xDB, 0x9B, 0xF8, 0xB2, 0x20, 0xA2, 0x42, -+0x72, 0xD0, 0x8B, 0xF8, 0xB2, 0x40, 0x00, 0x2C, 0x6E, 0xD0, 0x9B, 0xF8, 0xA2, 0x20, 0x12, 0xF0, 0x20, 0x07, 0x76, 0xD1, -+0xBB, 0xF8, 0xB4, 0x90, 0xB8, 0x46, 0xB9, 0xF1, 0x00, 0x0F, 0x15, 0xD1, 0x4D, 0xE0, 0x25, 0x44, 0x0C, 0xAB, 0x01, 0x37, -+0x0B, 0xEB, 0x85, 0x05, 0x03, 0xEB, 0x84, 0x04, 0xB8, 0xB2, 0x4F, 0xF0, 0x01, 0x03, 0x81, 0x45, 0xAB, 0x73, 0xA6, 0xF8, -+0x0A, 0xA0, 0xA6, 0xF8, 0x08, 0x80, 0x85, 0xF8, 0x0D, 0x80, 0x44, 0xF8, 0x28, 0x8C, 0x38, 0xD9, 0xBC, 0xB2, 0x04, 0xEB, -+0x44, 0x06, 0x0B, 0xEB, 0x86, 0x06, 0x65, 0x00, 0xB6, 0xF8, 0x0A, 0xA0, 0x50, 0x46, 0xFD, 0xF7, 0x19, 0xFF, 0x00, 0x28, -+0xDD, 0xD0, 0x4A, 0xF4, 0x80, 0x6A, 0xB9, 0xF1, 0x00, 0x0F, 0x16, 0xD0, 0x58, 0x46, 0x4F, 0xF0, 0x00, 0x0C, 0x01, 0xE0, -+0xCC, 0x45, 0xD2, 0xD0, 0xB0, 0xF8, 0x0A, 0xE0, 0xD6, 0x45, 0x0C, 0xF1, 0x01, 0x0C, 0x00, 0xF1, 0x0C, 0x00, 0xF5, 0xD1, -+0x58, 0x46, 0xFE, 0xF7, 0x37, 0xFE, 0xBB, 0xF8, 0xB4, 0x90, 0x82, 0x46, 0xB9, 0xF1, 0x00, 0x0F, 0xE8, 0xD1, 0x28, 0x19, -+0x0C, 0xAB, 0x0B, 0xEB, 0x80, 0x00, 0x03, 0xEB, 0x84, 0x04, 0x01, 0x25, 0x85, 0x73, 0xA6, 0xF8, 0x0A, 0xA0, 0xA6, 0xF8, -+0x08, 0x90, 0x80, 0xF8, 0x0D, 0x90, 0x44, 0xF8, 0x28, 0x9C, 0x02, 0xA9, 0x58, 0x46, 0xFE, 0xF7, 0xCF, 0xFF, 0x02, 0xA9, -+0x58, 0x46, 0xFF, 0xF7, 0x1B, 0xF8, 0x01, 0x9A, 0x11, 0x46, 0x10, 0x4A, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x01, 0x29, -+0x99, 0xF8, 0x56, 0x31, 0x43, 0xF0, 0x01, 0x03, 0x89, 0xF8, 0x56, 0x31, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xBB, 0xF1, -+0x00, 0x0F, 0x82, 0xD1, 0x08, 0x49, 0x09, 0x48, 0x40, 0xF6, 0xEA, 0x42, 0xF0, 0xF7, 0xE2, 0xFF, 0x7B, 0xE7, 0x62, 0xF0, -+0x7F, 0x02, 0x8B, 0xF8, 0xA2, 0x20, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x68, 0x8E, 0x15, 0x00, 0xB0, 0xF8, 0x54, 0x21, 0x03, 0x29, 0x9A, 0xBF, 0x02, 0xF4, 0x80, 0x62, -+0x12, 0xB2, 0x00, 0x22, 0x10, 0xB4, 0x42, 0xEA, 0x01, 0x03, 0xD0, 0xF8, 0x48, 0x41, 0x43, 0xF0, 0x00, 0x53, 0xC4, 0xE9, -+0x05, 0x33, 0xC4, 0xE9, 0x07, 0x33, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x90, 0xF8, 0xA5, 0x30, 0xC1, 0xF3, 0xC2, 0x22, -+0x93, 0x42, 0x13, 0xD3, 0x05, 0x2B, 0x70, 0xB5, 0x4F, 0xEA, 0xD1, 0x24, 0x11, 0xD0, 0x04, 0x2B, 0x29, 0xD0, 0x02, 0x3B, -+0x01, 0x2B, 0x12, 0xD8, 0x14, 0xF0, 0x06, 0x03, 0x04, 0xF0, 0x06, 0x05, 0x26, 0xD1, 0x90, 0xF8, 0xAD, 0x20, 0x03, 0x2A, -+0x1B, 0xD8, 0x0D, 0xE0, 0x00, 0x23, 0x18, 0x46, 0x70, 0x47, 0x05, 0x2A, 0x03, 0xD0, 0x90, 0xF8, 0xAD, 0x30, 0x03, 0x2B, -+0x15, 0xD8, 0x14, 0xF0, 0x06, 0x0F, 0x04, 0xF0, 0x06, 0x05, 0x13, 0xD1, 0x4A, 0x05, 0xC1, 0xF3, 0x80, 0x23, 0x03, 0xD4, -+0x90, 0xF8, 0xB2, 0x20, 0x01, 0x2A, 0x04, 0xD0, 0xFF, 0xF7, 0x9A, 0xF8, 0x03, 0x1E, 0x18, 0xBF, 0x01, 0x23, 0x18, 0x46, -+0x70, 0xBD, 0x04, 0x2A, 0x1A, 0xD0, 0x00, 0x23, 0x18, 0x46, 0x70, 0xBD, 0x04, 0x2A, 0x1A, 0xD9, 0x90, 0xF8, 0xAF, 0x60, -+0xC1, 0xF3, 0xC1, 0x13, 0x9E, 0x42, 0xF4, 0xD3, 0x63, 0x07, 0x08, 0xD5, 0x07, 0x2A, 0xE7, 0xD0, 0xC1, 0xF3, 0x02, 0x13, -+0x90, 0xF8, 0xB0, 0x20, 0x9A, 0x42, 0xEA, 0xD3, 0xE0, 0xE7, 0x00, 0x2D, 0xDE, 0xD0, 0xC1, 0xF3, 0xC1, 0x03, 0xF5, 0xE7, -+0x14, 0xF0, 0x06, 0x0F, 0x04, 0xF0, 0x06, 0x05, 0xCE, 0xD0, 0x8E, 0x05, 0xE2, 0xD5, 0x90, 0xF8, 0xB1, 0x30, 0x00, 0x2B, -+0xD5, 0xD0, 0xDD, 0xE7, 0x01, 0xEB, 0x41, 0x01, 0x00, 0xEB, 0x81, 0x03, 0x2D, 0xE9, 0xF0, 0x47, 0x1F, 0x89, 0x80, 0x46, -+0x41, 0xF6, 0x98, 0x10, 0x87, 0x42, 0x38, 0xD9, 0xB3, 0xF8, 0x0A, 0x90, 0xD8, 0xF8, 0x94, 0xA0, 0x48, 0x46, 0x15, 0x46, -+0x8C, 0x00, 0xFD, 0xF7, 0x2F, 0xFE, 0x08, 0xB3, 0x00, 0x26, 0x20, 0x1D, 0x40, 0x44, 0xFF, 0xF7, 0x8D, 0xFC, 0x2D, 0x4A, -+0x4F, 0xF4, 0x7A, 0x73, 0x30, 0x44, 0x03, 0xFB, 0x07, 0xF3, 0xB3, 0xFB, 0xF0, 0xF3, 0x02, 0xFB, 0x03, 0xF3, 0x18, 0x0C, -+0x75, 0xB1, 0x43, 0xF2, 0x32, 0x33, 0x9F, 0x42, 0x1C, 0xD9, 0x44, 0xF6, 0xCB, 0x43, 0x9F, 0x42, 0x21, 0xD8, 0x24, 0x4B, -+0x5A, 0x78, 0xA2, 0xFB, 0x00, 0x34, 0xD8, 0x09, 0x40, 0xEA, 0x44, 0x60, 0xBD, 0xE8, 0xF0, 0x87, 0x20, 0x4E, 0x21, 0x4B, -+0xC9, 0xF3, 0xC2, 0x29, 0x4F, 0xEA, 0x1A, 0x4A, 0xB9, 0xF1, 0x06, 0x0F, 0x08, 0xBF, 0x1E, 0x46, 0xB6, 0xFB, 0xFA, 0xF6, -+0xD1, 0xE7, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x17, 0x4B, 0x1A, 0x78, 0xA2, 0xFB, 0x00, 0x34, 0xD8, 0x09, 0x40, 0xEA, -+0x44, 0x60, 0xBD, 0xE8, 0xF0, 0x87, 0x46, 0xF2, 0x65, 0x63, 0x9F, 0x42, 0x0A, 0xD9, 0xB7, 0xF5, 0x00, 0x4F, 0x0F, 0xD2, -+0x0F, 0x4B, 0xDA, 0x78, 0xA2, 0xFB, 0x00, 0x34, 0xD8, 0x09, 0x40, 0xEA, 0x44, 0x60, 0xD5, 0xE7, 0x0B, 0x4B, 0x9A, 0x78, -+0xA2, 0xFB, 0x00, 0x34, 0xD8, 0x09, 0x40, 0xEA, 0x44, 0x60, 0xCD, 0xE7, 0x49, 0xF6, 0x98, 0x13, 0x9F, 0x42, 0x06, 0x4B, -+0x94, 0xBF, 0x1A, 0x79, 0x5A, 0x79, 0xA2, 0xFB, 0x00, 0x34, 0xD8, 0x09, 0x40, 0xEA, 0x44, 0x60, 0xC0, 0xE7, 0x00, 0xBF, -+0xB0, 0xE2, 0x0D, 0x00, 0x54, 0x25, 0x17, 0x00, 0x90, 0x53, 0x03, 0x00, 0x10, 0x09, 0x05, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, -+0x8F, 0xB0, 0x00, 0xF1, 0x88, 0x09, 0x02, 0xAD, 0x01, 0x91, 0x04, 0x46, 0x4A, 0x46, 0x07, 0x46, 0x00, 0xF1, 0x90, 0x06, -+0x29, 0x46, 0x32, 0xF8, 0x02, 0x3B, 0x03, 0xEB, 0x43, 0x03, 0x04, 0xEB, 0x83, 0x03, 0xB2, 0x42, 0x5B, 0x89, 0x21, 0xF8, -+0x02, 0x3B, 0xF4, 0xD1, 0xB4, 0xF8, 0x92, 0x10, 0x71, 0xB1, 0xD4, 0xF8, 0x94, 0x20, 0xB4, 0xF8, 0x90, 0x30, 0x02, 0xEB, -+0x42, 0x02, 0x1B, 0x04, 0x93, 0xFB, 0xF1, 0xF3, 0x13, 0x44, 0xC3, 0xF3, 0x98, 0x03, 0x00, 0x22, 0xC4, 0xE9, 0x24, 0x23, -+0x04, 0xF1, 0x7C, 0x00, 0xFE, 0xF7, 0x2A, 0xF8, 0xB4, 0xF8, 0xB4, 0x00, 0x00, 0x21, 0xA4, 0xF8, 0x7C, 0x10, 0xA4, 0xF8, -+0x7E, 0x10, 0x84, 0xF8, 0x9A, 0x10, 0x00, 0x28, 0x74, 0xD0, 0x01, 0x38, 0x05, 0xAB, 0x80, 0xB2, 0x0D, 0xF1, 0x10, 0x0A, -+0x03, 0xEB, 0x80, 0x00, 0x52, 0x46, 0x23, 0x46, 0x4F, 0xF0, 0x01, 0x0C, 0x42, 0xF8, 0x04, 0x1B, 0x82, 0x42, 0x83, 0xF8, -+0x0E, 0xC0, 0x03, 0xF1, 0x0C, 0x03, 0xF7, 0xD1, 0xB4, 0xF8, 0xBA, 0x20, 0x4F, 0xF6, 0xFF, 0x73, 0x9A, 0x42, 0x14, 0xD0, -+0x32, 0x4B, 0x20, 0x46, 0xD3, 0xF8, 0x6C, 0x32, 0x98, 0x47, 0x39, 0xF8, 0x02, 0x3B, 0x35, 0xF8, 0x02, 0x2B, 0x03, 0xEB, -+0x43, 0x03, 0x04, 0xEB, 0x83, 0x03, 0x5B, 0x89, 0x93, 0x42, 0x47, 0xD1, 0xB1, 0x45, 0xF2, 0xD1, 0x0F, 0xB0, 0xBD, 0xE8, -+0xF0, 0x8F, 0x4F, 0xF0, 0x00, 0x08, 0x1F, 0xFA, 0x88, 0xFB, 0x0B, 0xEB, 0x4B, 0x00, 0x04, 0xEB, 0x80, 0x00, 0x04, 0x30, -+0xFD, 0xF7, 0xE6, 0xFF, 0x01, 0x22, 0x5F, 0xFA, 0x88, 0xF1, 0x20, 0x46, 0x90, 0x44, 0xFF, 0xF7, 0x09, 0xFF, 0xB4, 0xF8, -+0xB4, 0x10, 0x0E, 0xAB, 0x03, 0xEB, 0x8B, 0x0B, 0x1F, 0xFA, 0x88, 0xF2, 0x91, 0x42, 0x4B, 0xF8, 0x28, 0x0C, 0xE4, 0xD8, -+0x51, 0x46, 0x20, 0x46, 0xFE, 0xF7, 0x26, 0xFE, 0x51, 0x46, 0x20, 0x46, 0xFE, 0xF7, 0x72, 0xFE, 0x01, 0x9B, 0xCB, 0xB9, -+0x94, 0xF8, 0xA2, 0x20, 0xB4, 0xF8, 0xB4, 0x30, 0x42, 0xF0, 0x40, 0x02, 0x84, 0xF8, 0xA2, 0x20, 0x83, 0xB1, 0x01, 0x3B, -+0x9B, 0xB2, 0x03, 0xEB, 0x43, 0x02, 0xDD, 0xF8, 0x04, 0x80, 0x04, 0xF1, 0x0C, 0x03, 0x03, 0xEB, 0x82, 0x03, 0xA7, 0xF8, -+0x04, 0x80, 0xA7, 0xF8, 0x06, 0x80, 0x0C, 0x37, 0x9F, 0x42, 0xF8, 0xD1, 0x00, 0x20, 0xAC, 0xE7, 0x01, 0x20, 0x0F, 0xB0, -+0xBD, 0xE8, 0xF0, 0x8F, 0xB4, 0xF8, 0xBA, 0x20, 0x4F, 0xF6, 0xFF, 0x73, 0x9A, 0x42, 0x9D, 0xD1, 0x0D, 0xF1, 0x10, 0x0A, -+0xCC, 0xE7, 0x00, 0xBF, 0x88, 0x1A, 0x17, 0x00, 0x38, 0xB5, 0x23, 0x4B, 0x23, 0x4A, 0x1B, 0x68, 0x4F, 0xF4, 0x1E, 0x71, -+0xB3, 0xF9, 0x00, 0x30, 0x01, 0xFB, 0x00, 0x20, 0x00, 0x2B, 0xD0, 0xF8, 0x4C, 0x41, 0x2F, 0xDB, 0x20, 0x46, 0xFF, 0xF7, -+0x5D, 0xF9, 0xB4, 0xF8, 0xB4, 0x30, 0x59, 0x1E, 0x9A, 0x1E, 0x21, 0xEA, 0xE1, 0x71, 0x03, 0x3B, 0x22, 0xEA, 0xE2, 0x72, -+0x23, 0xEA, 0xE3, 0x73, 0x00, 0x25, 0x4F, 0xF4, 0x80, 0x30, 0xA4, 0xF8, 0x88, 0x10, 0x4F, 0xF6, 0xFF, 0x71, 0xA4, 0xF8, -+0x8A, 0x20, 0xA4, 0xF8, 0x8C, 0x30, 0xC4, 0xF8, 0x94, 0x00, 0xA4, 0xF8, 0xBA, 0x10, 0xA4, 0xF8, 0x8E, 0x50, 0x84, 0xF8, -+0xA2, 0x50, 0x01, 0x21, 0x20, 0x46, 0xFF, 0xF7, 0x13, 0xFF, 0x94, 0xF8, 0xB4, 0x30, 0x84, 0xF8, 0x9B, 0x50, 0x04, 0x3B, -+0x05, 0x22, 0x84, 0xF8, 0xA0, 0x30, 0xA4, 0xF8, 0x98, 0x20, 0x38, 0xBD, 0x00, 0x2C, 0xCD, 0xD1, 0x05, 0x49, 0x06, 0x48, -+0x40, 0xF6, 0x76, 0x02, 0xF0, 0xF7, 0xDE, 0xFD, 0xC6, 0xE7, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x68, 0x8E, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0xC4, 0xA3, 0x90, 0xF8, 0x23, 0x70, -+0xDA, 0xF8, 0x00, 0x30, 0xD0, 0xF8, 0x48, 0x81, 0xB3, 0xF9, 0x00, 0x30, 0x8B, 0xB0, 0x07, 0xF1, 0x10, 0x02, 0xD2, 0xB2, -+0x00, 0x2B, 0x04, 0x46, 0x06, 0x92, 0xC0, 0xF2, 0xA9, 0x81, 0xDA, 0x4D, 0x07, 0xEB, 0x47, 0x03, 0x05, 0xEB, 0x83, 0x1B, -+0xC4, 0xF8, 0x4C, 0xB1, 0x9B, 0x01, 0x04, 0x93, 0xCD, 0xF7, 0xB4, 0xF9, 0x83, 0x03, 0x05, 0x93, 0xCD, 0xF7, 0xB0, 0xF9, -+0x4F, 0xF0, 0x01, 0x09, 0x01, 0x30, 0x09, 0xFA, 0x00, 0xF9, 0x00, 0x21, 0x58, 0x46, 0xC0, 0x22, 0xCC, 0xF7, 0xBE, 0xF8, -+0x61, 0x68, 0x11, 0xF0, 0x02, 0x01, 0x09, 0xF1, 0xFF, 0x39, 0x00, 0xF0, 0x9D, 0x80, 0x00, 0x21, 0x04, 0xF1, 0xB8, 0x00, -+0xF3, 0xF7, 0xB4, 0xFB, 0x63, 0x68, 0xAB, 0xF8, 0xAA, 0x00, 0x98, 0x06, 0x4F, 0xEA, 0x47, 0x06, 0x00, 0xF1, 0x30, 0x82, -+0x58, 0x07, 0x40, 0xF1, 0xA3, 0x81, 0xC3, 0x4B, 0x07, 0x93, 0x04, 0x23, 0xB4, 0xF8, 0xEC, 0x00, 0x8B, 0xF8, 0xA5, 0x30, -+0xCD, 0xF8, 0x24, 0xB0, 0xF3, 0xF7, 0xBA, 0xFA, 0x07, 0x9A, 0x03, 0x46, 0x10, 0x8F, 0x08, 0x93, 0xF3, 0xF7, 0xB4, 0xFA, -+0x08, 0x9B, 0x09, 0x9A, 0x98, 0x42, 0x28, 0xBF, 0x18, 0x46, 0xDA, 0xF8, 0x00, 0x30, 0x82, 0xF8, 0xB0, 0x00, 0xB3, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xC0, 0x83, 0x07, 0x9B, 0xB4, 0xF8, 0xEC, 0x00, 0x19, 0x8F, 0xF3, 0xF7, 0xCA, 0xFB, -+0xF2, 0x19, 0x05, 0xEB, 0x82, 0x12, 0x03, 0x46, 0xB4, 0xF8, 0xEC, 0x00, 0xA2, 0xF8, 0xA6, 0x30, 0x09, 0x92, 0xF3, 0xF7, -+0x7D, 0xFA, 0x07, 0x9A, 0x03, 0x46, 0x10, 0x8F, 0x08, 0x93, 0xF3, 0xF7, 0x77, 0xFA, 0x08, 0x9B, 0x09, 0x9A, 0x98, 0x42, -+0x28, 0xBF, 0x18, 0x46, 0xDA, 0xF8, 0x00, 0x30, 0x82, 0xF8, 0xAC, 0x00, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, -+0x91, 0x83, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0x08, 0x93, 0xB3, 0xF8, 0xAA, 0x00, 0x20, 0xF4, 0x7F, 0x60, 0x80, 0xB2, -+0xA3, 0xF8, 0xAA, 0x00, 0xF3, 0xF7, 0x96, 0xFA, 0x08, 0x9B, 0xDA, 0xF8, 0x00, 0x20, 0x83, 0xF8, 0xAD, 0x00, 0xB2, 0xF9, -+0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0x6D, 0x83, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0x08, 0x93, 0xB3, 0xF8, 0xAA, 0x00, -+0xF3, 0xF7, 0x92, 0xFA, 0x08, 0x9B, 0xDA, 0xF8, 0x00, 0x20, 0x83, 0xF8, 0xAE, 0x00, 0xB2, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0xC0, 0xF2, 0x4E, 0x83, 0xB4, 0xF8, 0x54, 0x21, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0xC2, 0xF3, 0x80, 0x22, 0x83, 0xF8, -+0xB2, 0x20, 0xCD, 0xF7, 0xD1, 0xF8, 0x00, 0x28, 0x40, 0xF0, 0x04, 0x83, 0xD4, 0xF8, 0xE8, 0x30, 0x03, 0xF0, 0x03, 0x03, -+0x01, 0x2B, 0x00, 0xF0, 0xD4, 0x83, 0x02, 0x2B, 0x00, 0xF0, 0xD9, 0x83, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0x40, 0xF6, -+0xED, 0x62, 0xA3, 0xF8, 0xB6, 0x20, 0x88, 0xE1, 0x04, 0xF1, 0xB8, 0x00, 0xF3, 0xF7, 0x18, 0xFB, 0x07, 0xEB, 0x47, 0x03, -+0x05, 0xEB, 0x83, 0x13, 0x07, 0x93, 0xA3, 0xF8, 0xAA, 0x00, 0xF3, 0xF7, 0x4D, 0xFA, 0x07, 0x9B, 0xDA, 0xF8, 0x00, 0x20, -+0x83, 0xF8, 0xAD, 0x00, 0xB2, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x4F, 0xEA, 0x47, 0x06, 0xC0, 0xF2, 0xBC, 0x80, 0xF3, 0x19, -+0x05, 0xEB, 0x83, 0x13, 0x07, 0x93, 0xB3, 0xF8, 0xAA, 0x00, 0xF3, 0xF7, 0x47, 0xFA, 0x07, 0x9B, 0xDA, 0xF8, 0x00, 0x20, -+0x83, 0xF8, 0xAE, 0x00, 0xB2, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0x9E, 0x80, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, -+0xFF, 0x21, 0x83, 0xF8, 0xAC, 0x10, 0x94, 0xF8, 0x2D, 0x11, 0x83, 0xF8, 0xAF, 0x10, 0xB2, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0xC0, 0xF2, 0x83, 0x80, 0xB4, 0xF8, 0x54, 0x11, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0xC1, 0xF3, 0x80, 0x21, 0x83, 0xF8, -+0xB2, 0x10, 0x58, 0x46, 0x07, 0x92, 0xFE, 0xF7, 0x71, 0xFF, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0x07, 0x9A, 0xA3, 0xF8, -+0xB4, 0x00, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0xC0, 0xF2, 0x8D, 0x80, 0x3E, 0x44, 0x05, 0xEB, 0x86, 0x1A, 0x94, 0xF8, -+0x23, 0x30, 0x9A, 0xF8, 0xAF, 0x70, 0x9A, 0xF8, 0xB1, 0x00, 0x9A, 0xF8, 0xB2, 0x10, 0x9A, 0xF8, 0xA5, 0x20, 0xCD, 0xE9, -+0x02, 0x07, 0xCD, 0xE9, 0x00, 0x21, 0x4F, 0xF4, 0x80, 0x50, 0x4B, 0x4A, 0x4B, 0x49, 0xF0, 0xF7, 0x6F, 0xFA, 0xBA, 0xF8, -+0xB4, 0x00, 0x9A, 0xF8, 0xAE, 0x10, 0x9A, 0xF8, 0xAD, 0x20, 0x9A, 0xF8, 0xAC, 0x30, 0xCD, 0xE9, 0x02, 0x10, 0xCD, 0xE9, -+0x00, 0x32, 0x45, 0x49, 0x42, 0x4A, 0x9A, 0xF8, 0xB0, 0x30, 0x4F, 0xF4, 0x80, 0x50, 0xF0, 0xF7, 0x5B, 0xFA, 0x94, 0xF8, -+0x23, 0x00, 0xFF, 0xF7, 0x5D, 0xFE, 0x04, 0x99, 0x88, 0x31, 0xB0, 0x01, 0x29, 0x44, 0x08, 0xF1, 0x14, 0x02, 0x08, 0xF1, -+0x24, 0x07, 0x31, 0xF8, 0x02, 0x3B, 0xDB, 0xB2, 0x03, 0xEB, 0x43, 0x03, 0x00, 0xEB, 0x83, 0x03, 0x2B, 0x44, 0x5B, 0x89, -+0x43, 0xF0, 0x80, 0x43, 0x42, 0xF8, 0x04, 0x3B, 0x97, 0x42, 0xF0, 0xD1, 0x58, 0x46, 0x00, 0x21, 0xFF, 0xF7, 0xB4, 0xF8, -+0x32, 0x4A, 0x06, 0x99, 0x12, 0x69, 0xD4, 0xF8, 0x48, 0x31, 0x31, 0x4F, 0x31, 0x48, 0xB6, 0x01, 0x89, 0x02, 0xAA, 0x51, -+0xA2, 0x69, 0x05, 0x9D, 0xC8, 0xF8, 0x0C, 0x10, 0x4F, 0xF4, 0x08, 0x51, 0xC8, 0xE9, 0x01, 0x59, 0xC8, 0xF8, 0x00, 0x70, -+0xC8, 0xF8, 0x10, 0x00, 0xC3, 0xE9, 0x0D, 0x12, 0x94, 0xF8, 0x56, 0x31, 0x43, 0xF0, 0x11, 0x03, 0x84, 0xF8, 0x56, 0x31, -+0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x29, 0x3F, 0xF4, 0x7A, 0xAF, 0x40, 0xF6, 0x21, 0x42, 0x22, 0x49, 0x23, 0x48, -+0xF0, 0xF7, 0x3C, 0xFC, 0xDA, 0xF8, 0x00, 0x20, 0x70, 0xE7, 0x0B, 0x28, 0x7F, 0xF6, 0x5F, 0xAF, 0x40, 0xF6, 0x1E, 0x42, -+0x1C, 0x49, 0x1E, 0x48, 0xF0, 0xF7, 0x30, 0xFC, 0xDA, 0xF8, 0x00, 0x20, 0x55, 0xE7, 0x0B, 0x28, 0x7F, 0xF6, 0x41, 0xAF, -+0x17, 0x49, 0x1A, 0x48, 0x40, 0xF6, 0x1C, 0x42, 0xF0, 0xF7, 0x24, 0xFC, 0x39, 0xE7, 0x00, 0x28, 0x00, 0xF0, 0xFE, 0x81, -+0x0A, 0x28, 0x7F, 0xF6, 0x6D, 0xAF, 0x11, 0x49, 0x14, 0x48, 0x40, 0xF6, 0x28, 0x42, 0xF0, 0xF7, 0x17, 0xFC, 0x65, 0xE7, -+0x09, 0x2F, 0x7F, 0xF6, 0x54, 0xAE, 0x0C, 0x49, 0x10, 0x48, 0x40, 0xF6, 0xEB, 0x22, 0xF0, 0xF7, 0x0D, 0xFC, 0x94, 0xF8, -+0x23, 0x70, 0x4A, 0xE6, 0xF4, 0xE7, 0x17, 0x00, 0xE4, 0xB8, 0x17, 0x00, 0x4C, 0xCC, 0x15, 0x00, 0xC4, 0xCB, 0x15, 0x00, -+0x08, 0xCC, 0x15, 0x00, 0x00, 0x10, 0x50, 0x40, 0x1E, 0xAB, 0xDC, 0xBA, 0x04, 0x07, 0xFF, 0xFF, 0x70, 0x79, 0x15, 0x00, -+0xA8, 0xCB, 0x15, 0x00, 0x84, 0xCB, 0x15, 0x00, 0x60, 0xCB, 0x15, 0x00, 0x0C, 0xCA, 0x15, 0x00, 0x64, 0xCA, 0x15, 0x00, -+0x38, 0x36, 0x17, 0x00, 0x04, 0xF1, 0xCB, 0x03, 0x02, 0x21, 0x18, 0x46, 0x8B, 0xF8, 0xA5, 0x10, 0x09, 0x93, 0xCD, 0xF8, -+0x20, 0xB0, 0xF3, 0xF7, 0x2B, 0xF9, 0x01, 0x46, 0xD9, 0x48, 0x07, 0x91, 0xF3, 0xF7, 0x26, 0xF9, 0x07, 0x99, 0x08, 0x9A, -+0x09, 0x9B, 0x88, 0x42, 0x28, 0xBF, 0x08, 0x46, 0xDA, 0xF8, 0x00, 0x10, 0x82, 0xF8, 0xB0, 0x00, 0xB1, 0xF9, 0x00, 0x20, -+0x00, 0x2A, 0xC0, 0xF2, 0x41, 0x82, 0x04, 0x9A, 0x02, 0xF1, 0xA6, 0x00, 0x19, 0x46, 0x04, 0x22, 0x28, 0x44, 0x02, 0xF0, -+0x6B, 0xFE, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0xFF, 0x22, 0xB3, 0xF8, 0xAA, 0x00, 0x83, 0xF8, 0xA6, 0x20, 0x20, 0xF4, -+0x7F, 0x60, 0x07, 0x22, 0x80, 0xB2, 0x83, 0xF8, 0xAC, 0x20, 0xA3, 0xF8, 0xAA, 0x00, 0x07, 0x93, 0xF3, 0xF7, 0x0A, 0xF9, -+0x07, 0x9B, 0xDA, 0xF8, 0x00, 0x20, 0x83, 0xF8, 0xAD, 0x00, 0xB2, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0x0F, 0x82, -+0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0x07, 0x93, 0xB3, 0xF8, 0xAA, 0x00, 0xF3, 0xF7, 0x06, 0xF9, 0x07, 0x9B, 0xDA, 0xF8, -+0x00, 0x20, 0x83, 0xF8, 0xAE, 0x00, 0xB2, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xF0, 0x81, 0xB4, 0xF8, 0x54, 0x21, -+0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0xC2, 0xF3, 0x80, 0x22, 0x83, 0xF8, 0xB2, 0x20, 0xCC, 0xF7, 0x45, 0xFF, 0x00, 0x28, -+0x40, 0xF0, 0x88, 0x81, 0xB4, 0xF8, 0xC8, 0x30, 0x13, 0xF4, 0x00, 0x6F, 0x06, 0xEB, 0x07, 0x03, 0x05, 0xEB, 0x83, 0x13, -+0x14, 0xBF, 0x40, 0xF6, 0xB5, 0x72, 0x40, 0xF6, 0xFF, 0x62, 0xA3, 0xF8, 0xB6, 0x20, 0xF1, 0x19, 0x05, 0xEB, 0x81, 0x11, -+0x94, 0xF8, 0x2D, 0x31, 0xDA, 0xF8, 0x00, 0x20, 0x81, 0xF8, 0xAF, 0x30, 0xB2, 0xF9, 0x00, 0x10, 0x00, 0x29, 0xC0, 0xF2, -+0x31, 0x81, 0x03, 0x2B, 0x3F, 0xF6, 0xA9, 0xAE, 0xDF, 0xE8, 0x13, 0xF0, 0x26, 0x01, 0x20, 0x01, 0x15, 0x01, 0x04, 0x01, -+0x05, 0x23, 0x94, 0xF8, 0x22, 0x10, 0xB4, 0xF8, 0x06, 0x01, 0x8B, 0xF8, 0xA5, 0x30, 0x07, 0x91, 0xCD, 0xF8, 0x24, 0xB0, -+0xF3, 0xF7, 0x8C, 0xF8, 0x95, 0x4A, 0x03, 0x46, 0xB2, 0xF8, 0x50, 0x00, 0x08, 0x93, 0xF3, 0xF7, 0x85, 0xF8, 0x08, 0x9B, -+0x09, 0x9A, 0x98, 0x42, 0x28, 0xBF, 0x18, 0x46, 0xDA, 0xF8, 0x00, 0x30, 0x82, 0xF8, 0xB0, 0x00, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xC0, 0xF2, 0xE5, 0x81, 0x8B, 0x4B, 0xB4, 0xF8, 0x06, 0x01, 0xB3, 0xF8, 0x50, 0x10, 0xF3, 0xF7, 0x9A, 0xF9, -+0xF2, 0x19, 0x05, 0xEB, 0x82, 0x12, 0x03, 0x46, 0xB4, 0xF8, 0x06, 0x01, 0xA2, 0xF8, 0xA6, 0x30, 0x09, 0x92, 0xF3, 0xF7, -+0x59, 0xF8, 0x82, 0x4A, 0x03, 0x46, 0xB2, 0xF8, 0x50, 0x00, 0x08, 0x93, 0xF3, 0xF7, 0x52, 0xF8, 0x08, 0x9B, 0x09, 0x9A, -+0x98, 0x42, 0x28, 0xBF, 0x18, 0x46, 0xDA, 0xF8, 0x00, 0x30, 0x82, 0xF8, 0xAC, 0x00, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0xC0, 0xF2, 0xB4, 0x81, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0x08, 0x93, 0xB3, 0xF8, 0xAA, 0x00, 0x20, 0xF4, 0x7F, 0x60, -+0x80, 0xB2, 0xA3, 0xF8, 0xAA, 0x00, 0xF3, 0xF7, 0x65, 0xF8, 0x08, 0x9B, 0xDA, 0xF8, 0x00, 0x20, 0x83, 0xF8, 0xAD, 0x00, -+0xB2, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0x90, 0x81, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0x08, 0x93, 0xB3, 0xF8, -+0xAA, 0x00, 0xF3, 0xF7, 0x61, 0xF8, 0x08, 0x9B, 0xDA, 0xF8, 0x00, 0x20, 0x83, 0xF8, 0xAE, 0x00, 0xB2, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0xC0, 0xF2, 0x71, 0x81, 0xB4, 0xF8, 0x54, 0x21, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0xC2, 0xF3, 0x80, 0x22, -+0x83, 0xF8, 0xB2, 0x20, 0xCC, 0xF7, 0xA0, 0xFE, 0x28, 0xB1, 0x5D, 0x4B, 0x93, 0xF8, 0x43, 0x30, 0x99, 0x06, 0x00, 0xF1, -+0x99, 0x81, 0x63, 0x68, 0x5B, 0x07, 0x40, 0xF1, 0xEB, 0x80, 0xD4, 0xF8, 0xE8, 0x30, 0x03, 0xF0, 0x03, 0x03, 0x01, 0x2B, -+0x00, 0xF0, 0xBD, 0x81, 0x02, 0x2B, 0x00, 0xF0, 0xB2, 0x81, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0x40, 0xF6, 0xED, 0x62, -+0xA3, 0xF8, 0xB6, 0x20, 0x50, 0x4B, 0x07, 0x99, 0x4F, 0xF4, 0xA4, 0x62, 0x02, 0xFB, 0x01, 0x33, 0x93, 0xF8, 0x62, 0x20, -+0x00, 0x2A, 0x40, 0xF0, 0xDF, 0x80, 0xD3, 0xF8, 0xC8, 0x31, 0xD4, 0xF8, 0x48, 0x01, 0x13, 0xF4, 0x80, 0x3F, 0xC1, 0x6B, -+0x40, 0xF0, 0x69, 0x81, 0x41, 0xF0, 0x20, 0x01, 0x00, 0x2B, 0xC1, 0x63, 0x06, 0xDB, 0xC3, 0xF3, 0x05, 0x63, 0x49, 0xEA, -+0x03, 0x59, 0x02, 0x2A, 0x00, 0xF0, 0x58, 0x81, 0x49, 0xF0, 0x80, 0x59, 0x49, 0xF4, 0xC0, 0x29, 0x3D, 0x4B, 0x93, 0xF8, -+0x45, 0x10, 0x94, 0xF8, 0xFD, 0x30, 0x01, 0xF0, 0x03, 0x00, 0xC3, 0xF3, 0xC1, 0x03, 0x83, 0x42, 0x06, 0xEB, 0x07, 0x02, -+0x28, 0xBF, 0x03, 0x46, 0x05, 0xEB, 0x82, 0x12, 0x01, 0x20, 0x83, 0x42, 0x82, 0xF8, 0xBC, 0x00, 0x00, 0xF0, 0x6A, 0x81, -+0x02, 0x2B, 0x00, 0xF0, 0x64, 0x81, 0x00, 0x2B, 0x00, 0xF0, 0x68, 0x81, 0x04, 0x23, 0x82, 0xF8, 0xBD, 0x30, 0x2E, 0x4B, -+0x94, 0xF8, 0xFD, 0xC0, 0x93, 0xF8, 0x4B, 0x00, 0x93, 0xF8, 0x4A, 0x20, 0x8B, 0x08, 0xF1, 0x19, 0x03, 0xEA, 0x5C, 0x13, -+0x05, 0xEB, 0x81, 0x11, 0x03, 0xF0, 0x01, 0x03, 0x81, 0xF8, 0xBE, 0x30, 0x94, 0xF8, 0x03, 0xC1, 0x94, 0xF8, 0x02, 0x31, -+0x0C, 0xF0, 0x01, 0x0C, 0x9B, 0x11, 0x00, 0xF0, 0x01, 0x00, 0x92, 0x11, 0x43, 0xEA, 0x8C, 0x03, 0x42, 0xEA, 0x80, 0x02, -+0x93, 0x42, 0x28, 0xBF, 0x13, 0x46, 0x81, 0xF8, 0xBF, 0x30, 0xE8, 0xE6, 0xD4, 0xF8, 0xE8, 0x30, 0x59, 0x06, 0x7F, 0xF5, -+0x9E, 0xAD, 0x19, 0x4B, 0x9B, 0x89, 0x5B, 0x06, 0x7F, 0xF5, 0x99, 0xAD, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0x01, 0x21, -+0x83, 0xF8, 0xB1, 0x10, 0x91, 0xE5, 0xD4, 0xF8, 0xE8, 0x30, 0x9B, 0x06, 0x7F, 0xF5, 0x8D, 0xAD, 0x10, 0x4B, 0x9B, 0x89, -+0x98, 0x06, 0x7F, 0xF5, 0x88, 0xAD, 0xED, 0xE7, 0xB4, 0xF8, 0xC8, 0x30, 0x59, 0x06, 0x7F, 0xF5, 0x82, 0xAD, 0xE2, 0xE7, -+0xB4, 0xF8, 0xC8, 0x30, 0x98, 0x06, 0x7F, 0xF5, 0x7C, 0xAD, 0xED, 0xE7, 0x03, 0x2B, 0x7F, 0xF6, 0xCC, 0xAE, 0x40, 0xF6, -+0xF9, 0x32, 0x07, 0x49, 0x07, 0x48, 0xF0, 0xF7, 0x31, 0xFA, 0x94, 0xF8, 0x2D, 0x31, 0xDA, 0xF8, 0x00, 0x20, 0xC0, 0xE6, -+0xF3, 0xB8, 0x17, 0x00, 0xE4, 0xB8, 0x17, 0x00, 0x18, 0x88, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x34, 0xCA, 0x15, 0x00, -+0x40, 0xF6, 0x27, 0x42, 0x88, 0x49, 0x89, 0x48, 0x07, 0x93, 0xF0, 0xF7, 0x1B, 0xFA, 0xDA, 0xF8, 0x00, 0x20, 0xB2, 0xF9, -+0x00, 0x20, 0x00, 0x2A, 0xBF, 0xF6, 0x64, 0xAD, 0x07, 0x9B, 0xB3, 0xF8, 0xB4, 0x00, 0xEF, 0xE5, 0x07, 0x9B, 0x1B, 0x6B, -+0x13, 0xF0, 0x10, 0x0F, 0xD4, 0xF8, 0xE8, 0x30, 0x3F, 0xF4, 0xF6, 0xAC, 0xD9, 0x06, 0x7F, 0xF5, 0xF3, 0xAC, 0x05, 0x9A, -+0x42, 0xF0, 0x40, 0x02, 0x05, 0x92, 0xED, 0xE4, 0x7A, 0x4B, 0x9B, 0x89, 0x13, 0xF0, 0x01, 0x0F, 0xB4, 0xF8, 0xC8, 0x30, -+0x3F, 0xF4, 0x72, 0xAE, 0xDA, 0x07, 0x7F, 0xF5, 0x6F, 0xAE, 0x05, 0x9A, 0x42, 0xF0, 0x40, 0x02, 0x05, 0x92, 0x69, 0xE6, -+0xB4, 0xF8, 0xC8, 0x30, 0x13, 0xF4, 0x00, 0x6F, 0x06, 0xEB, 0x07, 0x03, 0x05, 0xEB, 0x83, 0x13, 0x14, 0xBF, 0x41, 0xF6, -+0xFF, 0x62, 0x40, 0xF6, 0xFF, 0x62, 0xA3, 0xF8, 0xB6, 0x20, 0x15, 0xE7, 0xD4, 0xF8, 0x48, 0x01, 0xD3, 0xF8, 0xC8, 0x31, -+0xC1, 0x6B, 0x00, 0x2B, 0x21, 0xF0, 0x20, 0x01, 0xC1, 0x63, 0xBF, 0xF6, 0x24, 0xAF, 0x26, 0xE7, 0x03, 0x28, 0x7F, 0xF6, -+0xAF, 0xAC, 0x0C, 0x28, 0x3F, 0xF4, 0xAC, 0xAC, 0x5F, 0x49, 0x62, 0x48, 0x40, 0xF6, 0xA2, 0x32, 0xF0, 0xF7, 0xC8, 0xF9, -+0xA4, 0xE4, 0x03, 0x28, 0x7F, 0xF6, 0x90, 0xAC, 0x0C, 0x28, 0x3F, 0xF4, 0x8D, 0xAC, 0x59, 0x49, 0x5C, 0x48, 0x4F, 0xF4, -+0x3A, 0x62, 0xF0, 0xF7, 0xBB, 0xF9, 0x85, 0xE4, 0x09, 0x28, 0x7F, 0xF6, 0x6C, 0xAC, 0x54, 0x49, 0x58, 0x48, 0x40, 0xF6, -+0x94, 0x32, 0xF0, 0xF7, 0xB1, 0xF9, 0x64, 0xE4, 0x07, 0x28, 0x7F, 0xF6, 0x3D, 0xAC, 0x4F, 0x49, 0x54, 0x48, 0x40, 0xF6, -+0x8E, 0x32, 0xF0, 0xF7, 0xA7, 0xF9, 0x35, 0xE4, 0x03, 0x28, 0x7F, 0xF6, 0x0D, 0xAE, 0x0C, 0x28, 0x3F, 0xF4, 0x0A, 0xAE, -+0x48, 0x49, 0x4B, 0x48, 0x40, 0xF6, 0xD9, 0x32, 0xF0, 0xF7, 0x9A, 0xF9, 0x02, 0xE6, 0x03, 0x28, 0x7F, 0xF6, 0xEE, 0xAD, -+0x0C, 0x28, 0x3F, 0xF4, 0xEB, 0xAD, 0x42, 0x49, 0x45, 0x48, 0x40, 0xF6, 0xD7, 0x32, 0xF0, 0xF7, 0x8D, 0xF9, 0xE3, 0xE5, -+0x03, 0x28, 0x7F, 0xF6, 0xBC, 0xAD, 0x3D, 0x49, 0x43, 0x48, 0x07, 0x93, 0x40, 0xF6, 0xCC, 0x32, 0xF0, 0xF7, 0x82, 0xF9, -+0x07, 0x9B, 0xB2, 0xE5, 0x03, 0x28, 0x7F, 0xF6, 0x8C, 0xAE, 0x0C, 0x28, 0x3F, 0xF4, 0x89, 0xAE, 0x35, 0x49, 0x38, 0x48, -+0x40, 0xF6, 0x22, 0x32, 0xF0, 0xF7, 0x74, 0xF9, 0x81, 0xE6, 0x03, 0x28, 0x7F, 0xF6, 0x6D, 0xAE, 0x0C, 0x28, 0x3F, 0xF4, -+0x6A, 0xAE, 0x2F, 0x49, 0x32, 0x48, 0x4F, 0xF4, 0x32, 0x62, 0xF0, 0xF7, 0x67, 0xF9, 0x62, 0xE6, 0x0B, 0x28, 0x7F, 0xF6, -+0x49, 0xAE, 0x2A, 0x49, 0x31, 0x48, 0x40, 0xF6, 0x1C, 0x32, 0xF0, 0xF7, 0x5D, 0xF9, 0x41, 0xE6, 0x07, 0x28, 0x7F, 0xF6, -+0x18, 0xAE, 0x25, 0x49, 0x2A, 0x48, 0x40, 0xF6, 0x16, 0x32, 0xF0, 0xF7, 0x53, 0xF9, 0x10, 0xE6, 0x49, 0xF0, 0x80, 0x59, -+0x49, 0xF4, 0x00, 0x39, 0xA6, 0xE6, 0x21, 0xF0, 0x20, 0x01, 0x00, 0x2B, 0xC1, 0x63, 0xBF, 0xF6, 0x96, 0xAE, 0x9B, 0xE6, -+0x94, 0xF8, 0x2D, 0x31, 0x23, 0xB9, 0x94, 0xF8, 0xFB, 0x30, 0x9A, 0x06, 0x7F, 0xF5, 0x5F, 0xAE, 0x05, 0x9B, 0x43, 0xF0, -+0x40, 0x03, 0x05, 0x93, 0x59, 0xE6, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0x41, 0xF6, 0xED, 0x62, 0xA3, 0xF8, 0xB6, 0x20, -+0xB7, 0xE5, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, 0x42, 0xF6, 0x74, 0x42, 0xA3, 0xF8, 0xB6, 0x20, 0xAF, 0xE5, 0x82, 0xF8, -+0xBD, 0x00, 0x9E, 0xE6, 0x00, 0x23, 0x82, 0xF8, 0xBD, 0x30, 0x9A, 0xE6, 0x82, 0xF8, 0xBC, 0x30, 0xA5, 0xE5, 0xF3, 0x19, -+0x05, 0xEB, 0x83, 0x13, 0x42, 0xF6, 0x74, 0x42, 0xA3, 0xF8, 0xB6, 0x20, 0x4C, 0xE6, 0xF3, 0x19, 0x05, 0xEB, 0x83, 0x13, -+0x41, 0xF6, 0xED, 0x62, 0xA3, 0xF8, 0xB6, 0x20, 0x44, 0xE6, 0x00, 0xBF, 0x70, 0x79, 0x15, 0x00, 0xF4, 0xC9, 0x15, 0x00, -+0xE4, 0xB8, 0x17, 0x00, 0xE8, 0xCA, 0x15, 0x00, 0x98, 0xCA, 0x15, 0x00, 0x38, 0xCB, 0x15, 0x00, 0x50, 0xCA, 0x15, 0x00, -+0x4C, 0xCB, 0x15, 0x00, 0x84, 0xCA, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x46, 0x7F, 0x09, 0x2E, 0x83, 0xB0, 0x04, 0x46, -+0x00, 0xF2, 0x8D, 0x80, 0x4B, 0x4B, 0x4C, 0x4F, 0x1A, 0x68, 0x4F, 0xF4, 0x1E, 0x73, 0xB2, 0xF9, 0x00, 0x20, 0x03, 0xFB, -+0x06, 0x73, 0x00, 0x2A, 0xD3, 0xF8, 0x4C, 0x51, 0x40, 0xDB, 0x95, 0xF8, 0xA2, 0x30, 0x59, 0x07, 0x34, 0xD4, 0x03, 0xF0, -+0xFD, 0x03, 0x4F, 0xF0, 0x00, 0x08, 0xDF, 0xF8, 0x18, 0x91, 0x85, 0xF8, 0xA2, 0x30, 0xD9, 0xF8, 0x10, 0x30, 0x2A, 0x68, -+0x3F, 0x49, 0x9B, 0x1A, 0x8B, 0x42, 0x36, 0xD8, 0x95, 0xF8, 0xA3, 0x20, 0x95, 0xF8, 0xA4, 0x30, 0x43, 0xEA, 0x82, 0x03, -+0x84, 0xF8, 0x36, 0x30, 0x28, 0x46, 0xFE, 0xF7, 0x65, 0xFF, 0xB0, 0xB1, 0xE2, 0x8B, 0x94, 0xF8, 0x36, 0x30, 0x42, 0xF4, -+0x00, 0x52, 0x23, 0xF0, 0x03, 0x03, 0xE2, 0x83, 0x84, 0xF8, 0x36, 0x30, 0xB8, 0xF1, 0x00, 0x0F, 0x59, 0xD1, 0x4F, 0xF4, -+0x1E, 0x73, 0x03, 0xFB, 0x06, 0x76, 0x96, 0xF8, 0x56, 0x31, 0x43, 0xF0, 0x20, 0x03, 0x86, 0xF8, 0x56, 0x31, 0x03, 0xB0, -+0xBD, 0xE8, 0xF0, 0x83, 0x62, 0x6A, 0x92, 0x02, 0xC7, 0xD5, 0x43, 0xF0, 0x02, 0x03, 0x4F, 0xF0, 0x01, 0x08, 0xC6, 0xE7, -+0x00, 0x2D, 0xBC, 0xD1, 0x26, 0x49, 0x27, 0x48, 0x40, 0xF6, 0x9A, 0x22, 0xF0, 0xF7, 0x9E, 0xF8, 0xB5, 0xE7, 0x00, 0x21, -+0x28, 0x46, 0xFF, 0xF7, 0xBB, 0xF9, 0x95, 0xF8, 0xA3, 0x30, 0x01, 0x33, 0x00, 0x22, 0x03, 0xF0, 0x07, 0x03, 0x85, 0xF8, -+0xA3, 0x30, 0x85, 0xF8, 0x9B, 0x20, 0x85, 0xF8, 0xA4, 0x20, 0xD9, 0xF8, 0x10, 0x20, 0x2A, 0x60, 0x9B, 0x00, 0x84, 0xF8, -+0x36, 0x30, 0x00, 0x28, 0xB8, 0xD0, 0x0D, 0xF1, 0x07, 0x01, 0x28, 0x46, 0xFE, 0xF7, 0xCE, 0xFC, 0x9D, 0xF8, 0x07, 0x30, -+0x53, 0xB9, 0x62, 0x6A, 0x22, 0xF4, 0x00, 0x12, 0x62, 0x62, 0x95, 0xF8, 0xA2, 0x20, 0x22, 0xF0, 0x02, 0x02, 0x98, 0x46, -+0x85, 0xF8, 0xA2, 0x20, 0x4F, 0xF4, 0x1E, 0x73, 0x03, 0xFB, 0x06, 0x73, 0x93, 0xF8, 0x56, 0x21, 0x42, 0xF0, 0x11, 0x02, -+0x83, 0xF8, 0x56, 0x21, 0x9A, 0xE7, 0x00, 0x23, 0x80, 0xF8, 0x36, 0x30, 0x03, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x63, 0x6A, -+0x43, 0xF4, 0x20, 0x13, 0x63, 0x62, 0xA0, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x68, 0x65, 0x17, 0x00, 0xA0, 0x86, 0x01, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x68, 0x8E, 0x15, 0x00, 0x00, 0x10, 0x50, 0x40, 0x30, 0xB4, 0xCA, 0x0A, 0x12, 0xF0, 0x06, 0x0F, -+0x9D, 0xF8, 0x08, 0x50, 0x9D, 0xF8, 0x14, 0x40, 0x20, 0xD0, 0x02, 0xF0, 0x07, 0x02, 0x01, 0xF0, 0x7F, 0x01, 0x04, 0x2A, -+0x0C, 0xBF, 0x09, 0x09, 0xC1, 0xF3, 0xC1, 0x01, 0x4B, 0xB9, 0xC3, 0x6B, 0x23, 0xF0, 0x04, 0x03, 0xC3, 0x63, 0x64, 0xB1, -+0x43, 0xF0, 0x10, 0x03, 0x30, 0xBC, 0xC3, 0x63, 0x70, 0x47, 0xA9, 0x42, 0xF3, 0xD1, 0xC3, 0x6B, 0x43, 0xF0, 0x04, 0x03, -+0xC3, 0x63, 0x00, 0x2C, 0xF2, 0xD1, 0x23, 0xF0, 0x10, 0x03, 0x30, 0xBC, 0xC3, 0x63, 0x70, 0x47, 0xC3, 0x6B, 0x23, 0xF0, -+0x10, 0x03, 0xF8, 0xE7, 0x0B, 0x7B, 0x05, 0x2B, 0x0E, 0xD1, 0x2D, 0xE9, 0xF0, 0x41, 0x4B, 0x7B, 0x84, 0xB0, 0x0C, 0x46, -+0x01, 0xF1, 0x0C, 0x07, 0x13, 0xB9, 0x0D, 0x88, 0x09, 0x2D, 0x05, 0xDC, 0x00, 0x20, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, -+0x00, 0x20, 0x70, 0x47, 0x0B, 0x20, 0x97, 0xF8, 0x02, 0x80, 0x7E, 0x7A, 0xEE, 0xF7, 0xC8, 0xF9, 0x08, 0xBB, 0xFB, 0x78, -+0x3B, 0xBB, 0x69, 0x1F, 0x04, 0xF1, 0x11, 0x00, 0x1D, 0x46, 0x01, 0x22, 0x07, 0x78, 0x43, 0x78, 0x26, 0x2F, 0x03, 0xF1, -+0x02, 0x03, 0x14, 0xD1, 0x8B, 0x42, 0xA1, 0xEB, 0x03, 0x01, 0x10, 0xDC, 0x05, 0xB9, 0x03, 0x90, 0x02, 0x29, 0x18, 0x44, -+0x4F, 0xF0, 0x01, 0x05, 0xEE, 0xDC, 0x00, 0x92, 0xE1, 0x79, 0x20, 0x7A, 0x42, 0x46, 0x03, 0xAB, 0x00, 0xF0, 0x1A, 0xFD, -+0x01, 0xF0, 0x52, 0xF8, 0xD0, 0xE7, 0x00, 0x96, 0xE1, 0x79, 0x20, 0x7A, 0x42, 0x46, 0x04, 0x23, 0x00, 0xF0, 0xF4, 0xFC, -+0xC8, 0xE7, 0x00, 0x96, 0xE1, 0x79, 0x20, 0x7A, 0x42, 0x46, 0x02, 0x23, 0x00, 0xF0, 0xEC, 0xFC, 0xC0, 0xE7, 0x00, 0xBF, -+0x08, 0xB5, 0x0B, 0x20, 0xEE, 0xF7, 0x90, 0xF9, 0x01, 0x28, 0x07, 0xD0, 0x09, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, -+0x00, 0x2B, 0x05, 0xDB, 0x00, 0x20, 0x08, 0xBD, 0x01, 0xF0, 0xEA, 0xF8, 0x00, 0x20, 0x08, 0xBD, 0x04, 0x49, 0x05, 0x48, -+0x9D, 0x22, 0xEF, 0xF7, 0xD5, 0xFF, 0x00, 0x20, 0x08, 0xBD, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x64, 0x7D, 0x15, 0x00, 0x08, 0xB5, 0x0B, 0x20, 0xEE, 0xF7, 0x70, 0xF9, 0x04, 0x28, 0x07, 0xD0, 0x09, 0x4B, 0x1B, 0x68, -+0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x05, 0xDB, 0x00, 0x20, 0x08, 0xBD, 0x01, 0xF0, 0x3E, 0xF8, 0x00, 0x20, 0x08, 0xBD, -+0x04, 0x49, 0x05, 0x48, 0x81, 0x22, 0xEF, 0xF7, 0xB5, 0xFF, 0x00, 0x20, 0x08, 0xBD, 0x00, 0xBF, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x3A, 0xB3, 0x93, 0x68, 0x10, 0xB4, 0x93, 0xB9, 0x54, 0x69, 0x64, 0xB1, -+0xFF, 0x28, 0x22, 0xD1, 0x00, 0x2C, 0x1A, 0xDD, 0x18, 0x32, 0x10, 0x19, 0x01, 0xE0, 0x82, 0x42, 0x15, 0xD0, 0x12, 0xF8, -+0x01, 0x3B, 0x99, 0x42, 0xF9, 0xD1, 0x01, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0xFF, 0x28, 0x13, 0xD0, 0x00, 0x2B, -+0x09, 0xDD, 0x0C, 0x32, 0x13, 0x44, 0x01, 0xE0, 0x9A, 0x42, 0x04, 0xD0, 0x12, 0xF8, 0x01, 0x1B, 0x81, 0x42, 0xF9, 0xD1, -+0xED, 0xE7, 0x00, 0x20, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x18, 0x46, 0xE6, 0xE7, 0x54, 0x69, -+0xD8, 0xE7, 0x00, 0xBF, 0x38, 0xB5, 0x0A, 0x4D, 0x41, 0xF2, 0x98, 0x74, 0x2B, 0x59, 0x63, 0xB1, 0x0B, 0x20, 0xEE, 0xF7, -+0x1B, 0xF9, 0x03, 0x28, 0x01, 0xD0, 0x00, 0x20, 0x38, 0xBD, 0x2B, 0x59, 0x18, 0x68, 0xB0, 0xFA, 0x80, 0xF0, 0x40, 0x09, -+0x38, 0xBD, 0x01, 0x20, 0x38, 0xBD, 0x00, 0xBF, 0x78, 0xEF, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x83, 0x46, 0x80, 0x6C, -+0x89, 0xB0, 0x14, 0x46, 0x99, 0x46, 0x00, 0xF1, 0x68, 0x05, 0x00, 0x29, 0x3B, 0xD1, 0xB0, 0xF8, 0x68, 0x10, 0xBE, 0x4A, -+0xB2, 0xF8, 0xFC, 0x31, 0x01, 0x33, 0x9B, 0xB2, 0x1E, 0x01, 0xA2, 0xF8, 0xFC, 0x31, 0xA0, 0xF8, 0x7E, 0x60, 0x05, 0x22, -+0x58, 0x46, 0xFC, 0xF7, 0x53, 0xFA, 0x01, 0x28, 0x00, 0xF0, 0xC8, 0x80, 0x1B, 0x23, 0x03, 0x93, 0x18, 0x23, 0xE9, 0x18, -+0x05, 0x22, 0xEA, 0x54, 0x01, 0x22, 0x4A, 0x70, 0x99, 0xF8, 0x00, 0x20, 0x8A, 0x70, 0x01, 0xF1, 0x03, 0x0A, 0x00, 0x2C, -+0x7B, 0xD0, 0x03, 0x22, 0x27, 0x20, 0xC8, 0x70, 0x0A, 0x71, 0x99, 0xF8, 0x01, 0x20, 0x4A, 0x71, 0x8C, 0x71, 0x99, 0xF8, -+0x02, 0x20, 0xCA, 0x71, 0x08, 0x33, 0xDB, 0xF8, 0x4C, 0x00, 0x9B, 0xF8, 0x35, 0x20, 0x41, 0x6A, 0x13, 0x44, 0x01, 0x39, -+0x19, 0x44, 0x04, 0x33, 0xC0, 0xE9, 0x0A, 0x13, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xA2, 0x4B, 0xA2, 0x4E, 0x00, 0x22, -+0x41, 0xF2, 0xA8, 0x7C, 0x6F, 0xF0, 0x2F, 0x01, 0x80, 0xF8, 0x69, 0x20, 0x80, 0xF8, 0x6A, 0x20, 0x80, 0xF8, 0x6B, 0x20, -+0x80, 0xF8, 0x68, 0x10, 0x13, 0xF8, 0x0C, 0x10, 0x9B, 0x4A, 0x4F, 0xF4, 0x1E, 0x77, 0x07, 0xFB, 0x01, 0xF1, 0x41, 0xF2, -+0xA9, 0x78, 0x89, 0x5B, 0xA0, 0xF8, 0x6C, 0x10, 0x13, 0xF8, 0x0C, 0x10, 0x07, 0xFB, 0x01, 0x61, 0x4F, 0xF4, 0xA4, 0x6E, -+0x49, 0x88, 0xA0, 0xF8, 0x6E, 0x10, 0x13, 0xF8, 0x0C, 0x10, 0x07, 0xFB, 0x01, 0x61, 0x89, 0x88, 0xA0, 0xF8, 0x70, 0x10, -+0x13, 0xF8, 0x08, 0x10, 0x0E, 0xFB, 0x01, 0xF1, 0x89, 0x5A, 0xA0, 0xF8, 0x72, 0x10, 0x13, 0xF8, 0x08, 0x10, 0x0E, 0xFB, -+0x01, 0x21, 0x49, 0x88, 0xA0, 0xF8, 0x74, 0x10, 0x13, 0xF8, 0x08, 0x10, 0x0E, 0xFB, 0x01, 0x21, 0x89, 0x88, 0xA0, 0xF8, -+0x76, 0x10, 0x13, 0xF8, 0x08, 0x10, 0x0E, 0xFB, 0x01, 0xF1, 0x02, 0xEB, 0x01, 0x0A, 0x9A, 0xF8, 0x06, 0xA0, 0xBA, 0xF1, -+0x02, 0x0F, 0x5F, 0xD0, 0x13, 0xF8, 0x0C, 0x20, 0x07, 0xFB, 0x02, 0xF2, 0xD0, 0x21, 0x92, 0x5B, 0xA0, 0xF8, 0x78, 0x20, -+0x13, 0xF8, 0x0C, 0x20, 0x07, 0xFB, 0x02, 0x62, 0x52, 0x88, 0xA0, 0xF8, 0x7A, 0x20, 0x13, 0xF8, 0x0C, 0x30, 0x07, 0xFB, -+0x03, 0x66, 0xB3, 0x88, 0xA0, 0xF8, 0x7C, 0x30, 0x63, 0xE7, 0x03, 0x9B, 0x01, 0x94, 0xC3, 0xF5, 0xC0, 0x73, 0x9B, 0xB2, -+0x02, 0x93, 0xCD, 0xF8, 0x14, 0xB0, 0x99, 0xF8, 0x02, 0x30, 0x02, 0x9A, 0x05, 0x2B, 0xA2, 0xF1, 0x05, 0x04, 0xA4, 0xB2, -+0x00, 0xF0, 0xE2, 0x80, 0x27, 0x23, 0x8A, 0xF8, 0x00, 0x30, 0x99, 0xF8, 0x01, 0x30, 0x8A, 0xF8, 0x02, 0x30, 0x00, 0x23, -+0x8A, 0xF8, 0x03, 0x30, 0x99, 0xF8, 0x02, 0x30, 0x8A, 0xF8, 0x04, 0x30, 0x05, 0x2B, 0x3A, 0xD0, 0x03, 0x23, 0x8A, 0xF8, -+0x01, 0x30, 0x02, 0x94, 0x0A, 0xF1, 0x05, 0x0A, 0x05, 0x25, 0xFF, 0xF7, 0x15, 0xFF, 0x01, 0x9B, 0x2B, 0x44, 0x01, 0x93, -+0x08, 0xB9, 0x04, 0x2C, 0xD7, 0xD8, 0x5C, 0x4B, 0xDD, 0xF8, 0x14, 0xB0, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0xC0, 0xF2, 0x9D, 0x80, 0x01, 0x9B, 0x03, 0x9A, 0x13, 0x44, 0x52, 0xE7, 0x18, 0x22, 0x29, 0x46, 0x58, 0x46, 0xFA, 0xF7, -+0xE7, 0xFF, 0x9B, 0xF8, 0x33, 0x20, 0x02, 0xF1, 0x18, 0x03, 0x1B, 0x32, 0x03, 0x92, 0x2E, 0xE7, 0x89, 0x5A, 0xA0, 0xF8, -+0x78, 0x10, 0x13, 0xF8, 0x08, 0x60, 0x0E, 0xFB, 0x06, 0x26, 0xD0, 0x21, 0x76, 0x88, 0xA0, 0xF8, 0x7A, 0x60, 0x13, 0xF8, -+0x08, 0x30, 0x0E, 0xFB, 0x03, 0x22, 0x93, 0x88, 0xA0, 0xF8, 0x7C, 0x30, 0x07, 0xE7, 0xD9, 0xF8, 0x5C, 0x20, 0x46, 0x49, -+0x01, 0x32, 0x0D, 0x68, 0xC9, 0xF8, 0x5C, 0x20, 0x0A, 0xF1, 0x05, 0x02, 0x04, 0x92, 0x00, 0x2D, 0x00, 0xF0, 0x45, 0x81, -+0xEB, 0x7C, 0x8A, 0xF8, 0x05, 0x30, 0x2B, 0x7C, 0x8A, 0xF8, 0x06, 0x30, 0xD9, 0xE9, 0x0A, 0x12, 0xB9, 0xF8, 0x30, 0x30, -+0xAA, 0xF8, 0x0F, 0x30, 0xCA, 0xF8, 0x07, 0x10, 0xCA, 0xF8, 0x0B, 0x20, 0xAB, 0x7C, 0x8A, 0xF8, 0x11, 0x30, 0x95, 0xF9, -+0x14, 0x00, 0xEE, 0xF7, 0x21, 0xFF, 0xFF, 0x23, 0x8A, 0xF8, 0x12, 0x00, 0x8A, 0xF8, 0x13, 0x30, 0x05, 0xF1, 0x0C, 0x00, -+0xAB, 0x1D, 0x13, 0xF8, 0x01, 0x1B, 0x03, 0xF1, 0x0D, 0x02, 0x52, 0x1B, 0x83, 0x42, 0x02, 0xF8, 0x0A, 0x10, 0xF6, 0xD1, -+0x6B, 0x7C, 0x8A, 0xF8, 0x1A, 0x30, 0x02, 0x9A, 0xEB, 0x68, 0xCA, 0xF8, 0x1B, 0x30, 0x40, 0xF2, 0x01, 0x14, 0x94, 0x42, -+0x99, 0xF8, 0x20, 0x30, 0x28, 0xBF, 0x14, 0x46, 0x0A, 0xF1, 0x1F, 0x02, 0xA4, 0xB2, 0x04, 0x92, 0x00, 0x2B, 0x40, 0xF0, -+0x05, 0x81, 0x1F, 0x3C, 0xA4, 0xB2, 0x99, 0xF8, 0x04, 0x30, 0x00, 0x2B, 0x6D, 0xD1, 0x6B, 0x8B, 0x2B, 0x83, 0x03, 0x23, -+0x1D, 0x48, 0xAB, 0x80, 0x29, 0x46, 0xEE, 0xF7, 0xEB, 0xF9, 0x99, 0xF8, 0x20, 0x30, 0x00, 0x2B, 0x40, 0xF0, 0x12, 0x81, -+0x04, 0x9B, 0x02, 0x9A, 0xA3, 0xEB, 0x0A, 0x05, 0xAB, 0x1E, 0x8A, 0xF8, 0x01, 0x30, 0x14, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, -+0x00, 0x30, 0x54, 0x1B, 0x00, 0x2B, 0xA4, 0xB2, 0x80, 0xF2, 0xF9, 0x80, 0xAA, 0x42, 0x80, 0xF0, 0xF6, 0x80, 0x10, 0x49, -+0x10, 0x48, 0xDD, 0xF8, 0x10, 0xA0, 0x40, 0xF2, 0x07, 0x52, 0xEF, 0xF7, 0xCF, 0xFD, 0x02, 0x94, 0x51, 0xE7, 0x01, 0x9B, -+0x00, 0x2B, 0x7F, 0xF4, 0x5F, 0xAF, 0x09, 0x49, 0x0A, 0x48, 0x40, 0xF2, 0x12, 0x52, 0xEF, 0xF7, 0xDB, 0xFD, 0x57, 0xE7, -+0x20, 0x62, 0x17, 0x00, 0x78, 0xEF, 0x17, 0x00, 0x8E, 0x65, 0x17, 0x00, 0x74, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x10, 0x07, 0x18, 0x00, 0x70, 0x79, 0x15, 0x00, 0xF4, 0xD0, 0x15, 0x00, 0x0C, 0xD1, 0x15, 0x00, 0x94, 0x4B, 0x1A, 0x68, -+0x00, 0x2A, 0x3F, 0xF4, 0x19, 0xAF, 0x19, 0x2C, 0x7F, 0xF6, 0x35, 0xAF, 0x02, 0x98, 0x99, 0xF8, 0x20, 0x10, 0xA0, 0xF1, -+0x1F, 0x03, 0x9B, 0xB2, 0x29, 0xB1, 0x02, 0x2B, 0x7F, 0xF6, 0x2B, 0xAF, 0xA0, 0xF1, 0x22, 0x03, 0x9B, 0xB2, 0x99, 0xF8, -+0x04, 0x10, 0x00, 0x29, 0x3F, 0xF4, 0x04, 0xAF, 0x03, 0x2B, 0x7F, 0xF6, 0x20, 0xAF, 0x10, 0x8B, 0x04, 0x3B, 0x9D, 0xB2, -+0x00, 0x28, 0x40, 0xF0, 0xCF, 0x80, 0x0D, 0x2D, 0x3F, 0xF6, 0xF8, 0xAE, 0x15, 0xE7, 0x04, 0x9A, 0x01, 0x23, 0x13, 0x70, -+0x2B, 0x8B, 0xA2, 0x1F, 0x92, 0xB2, 0x0A, 0xF1, 0x21, 0x01, 0x0B, 0x2B, 0x06, 0x92, 0x8C, 0x46, 0x1B, 0xD8, 0x7C, 0x4B, -+0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xC0, 0xF2, 0xAE, 0x80, 0x05, 0xF1, 0x1C, 0x02, 0x05, 0xF1, 0x28, 0x00, -+0x13, 0x46, 0x05, 0x33, 0x12, 0xF8, 0x01, 0x1B, 0x5B, 0x1B, 0x82, 0x42, 0x03, 0xF8, 0x0A, 0x10, 0xF6, 0xD1, 0x0C, 0x23, -+0x12, 0x3C, 0xA2, 0xB2, 0x2B, 0x83, 0x0A, 0xF1, 0x2D, 0x03, 0x06, 0x92, 0x9C, 0x46, 0x99, 0xF8, 0x04, 0x30, 0x01, 0x2B, -+0x3A, 0xD0, 0x2B, 0x8B, 0x6E, 0x8B, 0xF6, 0x1A, 0x05, 0xF1, 0x1C, 0x07, 0xB6, 0xB2, 0x1F, 0x44, 0x00, 0x2E, 0x3B, 0xD0, -+0xCD, 0xF8, 0x1C, 0xA0, 0xE3, 0x46, 0xAA, 0x46, 0x09, 0xE0, 0xBA, 0xF8, 0x18, 0x10, 0x36, 0x1B, 0xB6, 0xB2, 0x0C, 0x44, -+0x2F, 0x44, 0xAA, 0xF8, 0x18, 0x40, 0x00, 0x2E, 0x5D, 0xD0, 0x97, 0xF8, 0x00, 0x80, 0xB9, 0x78, 0x7C, 0x78, 0x40, 0x46, -+0x4A, 0x46, 0xFF, 0xF7, 0xA9, 0xFD, 0xA5, 0x1C, 0x02, 0x34, 0xED, 0xB2, 0xE4, 0xB2, 0x00, 0x28, 0xE7, 0xD0, 0xD9, 0x2D, -+0xE5, 0xD8, 0x06, 0x9B, 0x9C, 0x42, 0x4A, 0xD8, 0x4D, 0xB1, 0x59, 0x46, 0x78, 0x1A, 0xAB, 0x44, 0x01, 0xE0, 0x10, 0xF8, -+0x01, 0x80, 0x01, 0xF8, 0x01, 0x8B, 0x8B, 0x45, 0xF9, 0xD1, 0x06, 0x9B, 0x1B, 0x1B, 0x9B, 0xB2, 0x06, 0x93, 0xD2, 0xE7, -+0xD9, 0xF8, 0x08, 0x30, 0x00, 0x2B, 0xC0, 0xD1, 0xD9, 0xF8, 0x14, 0x30, 0x00, 0x2B, 0xBC, 0xD1, 0x6B, 0x8B, 0x2B, 0x83, -+0x04, 0x9B, 0xC3, 0xF1, 0xFE, 0x0B, 0xE3, 0x44, 0x02, 0x23, 0x8A, 0xF8, 0x20, 0xB0, 0x8C, 0xF8, 0x00, 0x30, 0x8C, 0xF8, -+0x01, 0x30, 0xEA, 0x7D, 0x28, 0x8B, 0x69, 0x8B, 0x99, 0xF8, 0x01, 0x30, 0x54, 0x1C, 0x88, 0x42, 0x66, 0x46, 0xEC, 0x75, -+0x43, 0xEA, 0x02, 0x23, 0x23, 0xD2, 0x6F, 0xEA, 0x43, 0x43, 0x6F, 0xEA, 0x53, 0x43, 0xAC, 0xF8, 0x02, 0x30, 0x33, 0x1D, -+0x04, 0x93, 0x08, 0xE7, 0x22, 0x3C, 0xA4, 0xB2, 0xF9, 0xE6, 0x03, 0x22, 0x8A, 0xF8, 0x01, 0x20, 0x36, 0x4A, 0x12, 0x68, -+0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x09, 0xDB, 0xDD, 0xF8, 0x10, 0xA0, 0x02, 0x94, 0x1D, 0x46, 0x6B, 0xE6, 0x55, 0x46, -+0xDC, 0x46, 0xDD, 0xF8, 0x1C, 0xA0, 0xC9, 0xE7, 0x1D, 0x46, 0xDD, 0xF8, 0x10, 0xA0, 0x02, 0x94, 0x61, 0xE6, 0xAC, 0xF8, -+0x02, 0x30, 0x33, 0x1D, 0x04, 0x93, 0xE2, 0xE6, 0x04, 0x9D, 0xA4, 0x23, 0x01, 0x24, 0x2B, 0x70, 0x6C, 0x70, 0xFF, 0xF7, -+0x6D, 0xFD, 0x20, 0xB1, 0xAC, 0x70, 0x04, 0x9B, 0x03, 0x33, 0x04, 0x93, 0xE0, 0xE6, 0x04, 0x9B, 0x98, 0x70, 0xF8, 0xE7, -+0x0B, 0x2A, 0x3F, 0xF6, 0x4F, 0xAF, 0x21, 0x49, 0x21, 0x48, 0x40, 0xF2, 0x7D, 0x42, 0xEF, 0xF7, 0xBF, 0xFC, 0x47, 0xE7, -+0xB2, 0xF8, 0x1A, 0x80, 0x01, 0x29, 0x02, 0xF1, 0x1C, 0x02, 0xA8, 0xEB, 0x00, 0x08, 0x02, 0xEB, 0x00, 0x07, 0x08, 0xD0, -+0xB8, 0xF1, 0x00, 0x0F, 0x1B, 0xD0, 0x7B, 0x78, 0x03, 0x33, 0xAB, 0x42, 0xFF, 0xF6, 0x1A, 0xAE, 0x37, 0xE6, 0x7E, 0x78, -+0x10, 0x5C, 0x97, 0xF8, 0x02, 0xB0, 0x02, 0x36, 0xF6, 0xB2, 0x03, 0xE0, 0x7E, 0x78, 0x38, 0x78, 0x02, 0x36, 0xF6, 0xB2, -+0x4A, 0x46, 0x59, 0x46, 0xFF, 0xF7, 0x08, 0xFD, 0x08, 0xB1, 0xD9, 0x2E, 0xE4, 0xD9, 0xB8, 0xEB, 0x06, 0x08, 0x37, 0x44, -+0xF0, 0xD1, 0x08, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xBF, 0xF6, 0xFC, 0xAD, 0x05, 0x49, 0x07, 0x48, -+0x40, 0xF2, 0x13, 0x42, 0xEF, 0xF7, 0xA0, 0xFC, 0xF4, 0xE5, 0x00, 0xBF, 0x10, 0x07, 0x18, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x70, 0x79, 0x15, 0x00, 0xD0, 0xD0, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0xF8, 0xB5, 0x2D, 0x4E, 0x41, 0xF2, 0xA9, 0x73, -+0xF2, 0x5C, 0x03, 0x2A, 0x42, 0xD8, 0x41, 0xF2, 0xA8, 0x73, 0xF3, 0x5C, 0x09, 0x2B, 0x3D, 0xD8, 0x0D, 0x46, 0x28, 0x49, -+0x4F, 0xF4, 0xA4, 0x63, 0x03, 0xFB, 0x02, 0x13, 0x07, 0x46, 0x1B, 0x6C, 0x00, 0x2B, 0x3E, 0xD0, 0x24, 0x48, 0x1B, 0x79, -+0x00, 0x68, 0xB0, 0xF9, 0x00, 0x00, 0x00, 0x28, 0x2D, 0xDB, 0x4F, 0xF4, 0xA4, 0x60, 0x00, 0xFB, 0x02, 0x12, 0x92, 0xF8, -+0xC0, 0x24, 0x13, 0x43, 0x14, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x4F, 0xF4, 0xC0, 0x71, 0xDA, 0xF7, 0x3D, 0xFE, 0x04, 0x46, -+0xE0, 0xB1, 0x41, 0xF2, 0xA9, 0x72, 0x41, 0xF2, 0xA8, 0x73, 0xB2, 0x5C, 0x02, 0x77, 0xF3, 0x5C, 0x43, 0x77, 0x00, 0x23, -+0x80, 0xF8, 0x33, 0x30, 0x80, 0xF8, 0x35, 0x30, 0x15, 0xB9, 0x13, 0x4B, 0xC0, 0xE9, 0x15, 0x30, 0x20, 0x46, 0x3B, 0x46, -+0x2A, 0x46, 0x01, 0x21, 0xFF, 0xF7, 0xEC, 0xFC, 0x20, 0x46, 0x03, 0x21, 0xBD, 0xE8, 0xF8, 0x40, 0xDA, 0xF7, 0x2E, 0xBE, -+0xF8, 0xBD, 0x02, 0x2B, 0xCF, 0xD1, 0x0B, 0x49, 0x0B, 0x48, 0x4F, 0xF4, 0x09, 0x72, 0xEF, 0xF7, 0x29, 0xFC, 0x01, 0x20, -+0xD1, 0xE7, 0x05, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xF7, 0xDA, 0xF0, 0xE7, 0x78, 0xEF, 0x17, 0x00, -+0x18, 0x88, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0xA1, 0x5E, 0x15, 0x00, 0x70, 0x79, 0x15, 0x00, 0xFC, 0x90, 0x15, 0x00, -+0x00, 0x2A, 0x35, 0xD0, 0x70, 0xB5, 0x04, 0x46, 0x92, 0xF8, 0x32, 0x00, 0x8A, 0xB0, 0x13, 0x46, 0x58, 0xB9, 0x95, 0x8E, -+0x22, 0x88, 0x95, 0x42, 0x28, 0xD1, 0xDD, 0x8E, 0x62, 0x88, 0x95, 0x42, 0x24, 0xD1, 0xA2, 0x88, 0x1C, 0x8F, 0x94, 0x42, -+0x20, 0xD1, 0x93, 0xF8, 0x3A, 0x20, 0xE2, 0xB1, 0xD9, 0xB1, 0x4D, 0x78, 0x8D, 0xF8, 0x04, 0x50, 0x6D, 0xB1, 0x01, 0xA8, -+0x05, 0x44, 0xC0, 0xF1, 0x02, 0x06, 0x44, 0x18, 0xA4, 0x5D, 0x00, 0xF8, 0x01, 0x4F, 0xA8, 0x42, 0xF9, 0xD1, 0x9D, 0xF8, -+0x04, 0x10, 0x91, 0x42, 0x01, 0xD0, 0x00, 0x20, 0x08, 0xE0, 0x03, 0xF1, 0x3B, 0x00, 0x0D, 0xF1, 0x05, 0x01, 0x01, 0xF0, -+0x57, 0xFE, 0x00, 0x28, 0xF5, 0xD1, 0x01, 0x20, 0x0A, 0xB0, 0x70, 0xBD, 0x01, 0x20, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x47, -+0x04, 0x46, 0xB1, 0xB1, 0x64, 0x48, 0x65, 0x4D, 0xA0, 0xF1, 0x82, 0x07, 0xED, 0xF7, 0x78, 0xFF, 0x00, 0x26, 0x25, 0xF8, -+0x02, 0x6C, 0x28, 0x46, 0x06, 0x22, 0x00, 0x21, 0x05, 0xF5, 0xF6, 0x75, 0xCA, 0xF7, 0xDE, 0xFE, 0xBD, 0x42, 0xF4, 0xD1, -+0xEC, 0xF7, 0x56, 0xFC, 0xC4, 0xE9, 0x0A, 0x01, 0x26, 0x66, 0x5B, 0x4E, 0xDF, 0xF8, 0x6C, 0x81, 0x06, 0xF1, 0x88, 0x07, -+0x0B, 0x20, 0xED, 0xF7, 0x77, 0xFD, 0x01, 0x28, 0x39, 0xD1, 0x57, 0x4D, 0x4F, 0xF0, 0x00, 0x09, 0x4F, 0xF0, 0x02, 0x0A, -+0x03, 0xE0, 0x05, 0xF5, 0xF6, 0x75, 0xB5, 0x42, 0x1A, 0xD0, 0xAB, 0x88, 0x01, 0x2B, 0xF8, 0xD1, 0x6B, 0x7D, 0x05, 0xF1, -+0x1C, 0x01, 0x19, 0x44, 0x22, 0x46, 0xA8, 0x1D, 0xFF, 0xF7, 0x8C, 0xFF, 0x00, 0x28, 0xEE, 0xD0, 0x29, 0x46, 0xA5, 0xF8, -+0x18, 0x90, 0x85, 0xF8, 0x17, 0x90, 0xA5, 0xF8, 0x04, 0xA0, 0x38, 0x46, 0x05, 0xF5, 0xF6, 0x75, 0xED, 0xF7, 0x3E, 0xFF, -+0xB5, 0x42, 0xE4, 0xD1, 0x23, 0x6E, 0x94, 0xF8, 0x65, 0x20, 0x01, 0x33, 0x93, 0x42, 0x23, 0x66, 0x5D, 0xDA, 0x03, 0x21, -+0x0B, 0x20, 0xED, 0xF7, 0x9D, 0xFC, 0xFF, 0xF7, 0x1F, 0xFC, 0x00, 0x28, 0xC6, 0xD1, 0x20, 0x46, 0x00, 0x21, 0xBD, 0xE8, -+0xF0, 0x47, 0xFF, 0xF7, 0xFF, 0xBE, 0x01, 0x21, 0x0B, 0x20, 0xED, 0xF7, 0x8F, 0xFC, 0x23, 0x6E, 0x06, 0xE0, 0x23, 0x6E, -+0x94, 0xF8, 0x65, 0x20, 0x01, 0x33, 0x93, 0x42, 0x23, 0x66, 0xB3, 0xDA, 0x23, 0x44, 0x94, 0xF8, 0x64, 0x00, 0x93, 0xF8, -+0x66, 0x10, 0xF1, 0xF7, 0xBB, 0xFF, 0x05, 0x46, 0x00, 0x28, 0xEE, 0xD0, 0xC3, 0x78, 0x9B, 0x07, 0xEB, 0xD4, 0x4F, 0xF4, -+0xBA, 0x73, 0x0B, 0x22, 0x04, 0x21, 0x4F, 0xF4, 0x80, 0x50, 0xED, 0xF7, 0x77, 0xFA, 0x06, 0x46, 0x28, 0x68, 0x30, 0x60, -+0xAB, 0x88, 0xB3, 0x80, 0xE3, 0x78, 0x1B, 0xB9, 0xF3, 0x78, 0x43, 0xF0, 0x01, 0x03, 0xF3, 0x70, 0x01, 0x25, 0x86, 0xF8, -+0x6F, 0x51, 0x94, 0xF8, 0x3A, 0x20, 0x86, 0xF8, 0xFC, 0x20, 0x04, 0xF1, 0x3B, 0x01, 0x06, 0xF1, 0xFD, 0x00, 0x01, 0xF0, -+0xE7, 0xFD, 0x86, 0xF8, 0x70, 0x51, 0xA3, 0x8E, 0xA6, 0xF8, 0x60, 0x31, 0xE3, 0x8E, 0xA6, 0xF8, 0x62, 0x31, 0x23, 0x8F, -+0xA6, 0xF8, 0x64, 0x31, 0x41, 0xF2, 0xA9, 0x73, 0x30, 0x46, 0x18, 0xF8, 0x03, 0x30, 0x86, 0xF8, 0x6E, 0x31, 0xBD, 0xE8, -+0xF0, 0x47, 0xED, 0xF7, 0x79, 0xBA, 0x13, 0x4B, 0x1B, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x09, 0xDB, 0x02, 0x21, -+0x0B, 0x20, 0xED, 0xF7, 0x39, 0xFC, 0x20, 0x46, 0x00, 0x21, 0xBD, 0xE8, 0xF0, 0x47, 0xFF, 0xF7, 0x9F, 0xBE, 0xFF, 0xF7, -+0xB5, 0xFB, 0x00, 0x28, 0xF1, 0xD0, 0xE3, 0x6D, 0x00, 0x2B, 0xEE, 0xD0, 0x08, 0x49, 0x09, 0x48, 0x40, 0xF2, 0x22, 0x62, -+0xEF, 0xF7, 0x0E, 0xFB, 0xE7, 0xE7, 0x00, 0xBF, 0x10, 0x07, 0x18, 0x00, 0x7E, 0xEF, 0x17, 0x00, 0x88, 0x06, 0x18, 0x00, -+0x78, 0xEF, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x1C, 0xD1, 0x15, 0x00, 0x10, 0xB5, 0x08, 0x4C, -+0x00, 0x21, 0x0B, 0x20, 0xED, 0xF7, 0x10, 0xFC, 0x20, 0x46, 0x41, 0xF2, 0xB0, 0x72, 0x00, 0x21, 0x04, 0xF5, 0xBD, 0x54, -+0xCA, 0xF7, 0x08, 0xFE, 0x4F, 0xF0, 0xFF, 0x33, 0x23, 0x60, 0x10, 0xBD, 0x78, 0xEF, 0x17, 0x00, 0xF0, 0xB5, 0xA3, 0xB0, -+0x0B, 0x4C, 0x9D, 0xF8, 0xA0, 0x50, 0x8D, 0xF8, 0x02, 0x50, 0x41, 0xF2, 0xA8, 0x75, 0x84, 0x46, 0x41, 0xF2, 0xA9, 0x77, -+0x08, 0x46, 0x66, 0x5B, 0x60, 0x55, 0x19, 0x46, 0x68, 0x46, 0x04, 0xF8, 0x07, 0xC0, 0x8D, 0xF8, 0x00, 0x20, 0xFF, 0xF7, -+0x57, 0xFE, 0x66, 0x53, 0x23, 0xB0, 0xF0, 0xBD, 0x78, 0xEF, 0x17, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xAB, 0xB0, 0x41, 0xF2, -+0xA8, 0x76, 0x00, 0x92, 0xC4, 0x4A, 0x41, 0xF2, 0xA9, 0x75, 0x91, 0x55, 0xCD, 0xE9, 0x01, 0x01, 0x02, 0xF5, 0xBD, 0x51, -+0x50, 0x55, 0x4F, 0xF0, 0xFF, 0x30, 0x08, 0x60, 0x34, 0x99, 0x16, 0x46, 0x41, 0xF2, 0xA4, 0x74, 0x00, 0x22, 0x91, 0x42, -+0x32, 0x51, 0x34, 0xDD, 0xDF, 0xF8, 0xF0, 0x82, 0x1F, 0x46, 0x91, 0x46, 0xBA, 0x46, 0x57, 0xF8, 0x04, 0x4B, 0x65, 0x78, -+0xAB, 0x1C, 0x04, 0x2B, 0x37, 0xD9, 0x88, 0x22, 0x00, 0x21, 0x40, 0x46, 0xCA, 0xF7, 0xBC, 0xFD, 0xA3, 0x78, 0x88, 0xF8, -+0x01, 0x30, 0xE3, 0x78, 0x22, 0x79, 0x88, 0xF8, 0x02, 0x20, 0xD9, 0x07, 0x03, 0xD4, 0x9B, 0x07, 0x1C, 0xD4, 0x05, 0x2A, -+0x73, 0xD0, 0xDA, 0xF8, 0x00, 0x40, 0x02, 0x21, 0x00, 0x9A, 0x23, 0x79, 0x8D, 0xF8, 0x20, 0x20, 0xA8, 0x4A, 0x02, 0x98, -+0x8D, 0xF8, 0x22, 0x30, 0x41, 0xF2, 0xA8, 0x75, 0x41, 0xF2, 0xA9, 0x73, 0x16, 0x46, 0x54, 0x5B, 0x01, 0x9F, 0x50, 0x55, -+0x08, 0xA8, 0xD7, 0x54, 0xFF, 0xF7, 0x04, 0xFE, 0x74, 0x53, 0x2B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x98, 0xF8, 0x00, 0x30, -+0x00, 0x9A, 0x93, 0x42, 0x4C, 0xD0, 0x34, 0x9B, 0x09, 0xF1, 0x01, 0x09, 0x4B, 0x45, 0xC1, 0xD1, 0xF1, 0xE7, 0x04, 0x21, -+0xDA, 0xE7, 0xA3, 0x2C, 0x00, 0xF0, 0x25, 0x81, 0xA4, 0x2C, 0x40, 0xF0, 0x18, 0x81, 0x98, 0x78, 0x88, 0xF8, 0x20, 0x00, -+0x52, 0x1A, 0x92, 0xB2, 0x02, 0x2A, 0x0B, 0x44, 0x00, 0xF2, 0x82, 0x80, 0x98, 0xF8, 0x03, 0x30, 0x01, 0x2B, 0x3E, 0x46, -+0x03, 0x9F, 0x2C, 0xD8, 0x04, 0x9C, 0x72, 0x2C, 0x23, 0x46, 0x94, 0xBF, 0x00, 0x23, 0x01, 0x23, 0x88, 0xF8, 0x64, 0x30, -+0x00, 0x2E, 0x00, 0xF0, 0x2B, 0x81, 0xB6, 0xF8, 0x03, 0x20, 0xB1, 0x78, 0xB0, 0x88, 0x88, 0xF8, 0x66, 0x40, 0x41, 0xF2, -+0x88, 0x33, 0x9A, 0x42, 0x94, 0xBF, 0x00, 0x22, 0x01, 0x22, 0x01, 0x23, 0x88, 0xF8, 0x64, 0x20, 0x88, 0xF8, 0x65, 0x30, -+0x00, 0x29, 0x40, 0xF0, 0x03, 0x81, 0x05, 0x9A, 0x88, 0xF8, 0x64, 0x10, 0x94, 0x42, 0x06, 0xD0, 0x80, 0xF0, 0x59, 0x81, -+0x04, 0x9B, 0x04, 0x33, 0x88, 0xF8, 0x67, 0x30, 0x02, 0x23, 0x88, 0xF8, 0x65, 0x30, 0x00, 0x9B, 0x88, 0xF8, 0x00, 0x30, -+0x76, 0x4A, 0x13, 0x68, 0x01, 0x33, 0x08, 0xF1, 0x88, 0x08, 0x13, 0x60, 0xAB, 0xE7, 0xEB, 0x1E, 0x0C, 0x2B, 0x40, 0xF2, -+0xDD, 0x80, 0xE3, 0x7A, 0x88, 0xF8, 0x03, 0x30, 0x02, 0x2B, 0x82, 0xD8, 0x62, 0x79, 0x63, 0x7A, 0x04, 0x92, 0xA2, 0x79, -+0x05, 0x92, 0xA8, 0xF8, 0x30, 0x30, 0x08, 0xF1, 0x3A, 0x0E, 0x08, 0xF1, 0x34, 0x03, 0xA4, 0xEB, 0x08, 0x01, 0x5A, 0x18, -+0x12, 0xF8, 0x28, 0x2C, 0x03, 0xF8, 0x01, 0x2B, 0x73, 0x45, 0xF8, 0xD1, 0xB8, 0xF8, 0x34, 0x20, 0x4F, 0xF6, 0xFF, 0x73, -+0x9A, 0x42, 0xA5, 0xF1, 0x10, 0x02, 0x08, 0xBF, 0x01, 0x23, 0x4F, 0xF0, 0x02, 0x01, 0x92, 0xB2, 0x08, 0xBF, 0x88, 0xF8, -+0x32, 0x30, 0x8A, 0x42, 0x04, 0xF1, 0x12, 0x03, 0x88, 0xF8, 0x04, 0x10, 0x40, 0xF2, 0x47, 0x81, 0x00, 0x21, 0x6F, 0xF0, -+0x13, 0x00, 0x0C, 0x46, 0x6F, 0xF0, 0x08, 0x06, 0x6F, 0xF0, 0x37, 0x0C, 0x0D, 0x46, 0xA0, 0xEB, 0x08, 0x01, 0x03, 0x97, -+0x06, 0x91, 0xA6, 0xEB, 0x08, 0x06, 0xAC, 0xEB, 0x08, 0x0C, 0x27, 0x46, 0x58, 0x78, 0x1C, 0x78, 0x81, 0x1C, 0x91, 0x42, -+0x00, 0xF2, 0x96, 0x80, 0x0B, 0x2C, 0x3F, 0xF6, 0x66, 0xAF, 0x0B, 0x2C, 0x3F, 0xF6, 0x6C, 0xAF, 0x0F, 0xF2, 0x04, 0x0B, -+0x5B, 0xF8, 0x24, 0xF0, 0xA9, 0x58, 0x15, 0x00, 0xB1, 0x56, 0x15, 0x00, 0x97, 0x58, 0x15, 0x00, 0xB1, 0x56, 0x15, 0x00, -+0xB1, 0x56, 0x15, 0x00, 0xB1, 0x56, 0x15, 0x00, 0xB1, 0x56, 0x15, 0x00, 0xB1, 0x56, 0x15, 0x00, 0xB1, 0x56, 0x15, 0x00, -+0xB1, 0x56, 0x15, 0x00, 0x65, 0x58, 0x15, 0x00, 0x11, 0x58, 0x15, 0x00, 0x02, 0x29, 0x71, 0xD0, 0x9C, 0x78, 0xFF, 0x2C, -+0x7F, 0xF4, 0x4A, 0xAF, 0x00, 0xF1, 0xFF, 0x3B, 0x5F, 0xFA, 0x8B, 0xFB, 0xBB, 0xF1, 0x08, 0x0F, 0x28, 0xBF, 0x4F, 0xF0, -+0x08, 0x0B, 0x01, 0x28, 0xC8, 0xF8, 0x14, 0xB0, 0x3F, 0xF4, 0x3C, 0xAF, 0x08, 0xF1, 0x17, 0x00, 0xCD, 0xF8, 0x1C, 0xA0, -+0xDD, 0xF8, 0x18, 0xA0, 0x83, 0x44, 0x1C, 0x18, 0x14, 0xF8, 0x0A, 0x40, 0x00, 0xF8, 0x01, 0x4F, 0x58, 0x45, 0xF8, 0xD1, -+0x52, 0x1A, 0x92, 0xB2, 0x02, 0x2A, 0xDD, 0xF8, 0x1C, 0xA0, 0x0B, 0x44, 0xAE, 0xD8, 0x2B, 0xE7, 0x8C, 0x1E, 0x08, 0x2C, -+0xA8, 0xBF, 0x08, 0x24, 0x02, 0x29, 0xC8, 0xF8, 0x08, 0x40, 0x3F, 0xF4, 0x1D, 0xAF, 0x08, 0xF1, 0x0B, 0x00, 0x00, 0xEB, -+0x04, 0x0B, 0x1C, 0x18, 0xA4, 0x5D, 0x00, 0xF8, 0x01, 0x4F, 0x83, 0x45, 0xF9, 0xD1, 0x52, 0x1A, 0x92, 0xB2, 0x02, 0x2A, -+0x0B, 0x44, 0x95, 0xD8, 0x12, 0xE7, 0x52, 0x1A, 0x92, 0xB2, 0x98, 0x78, 0x88, 0xF8, 0x04, 0x00, 0x02, 0x2A, 0x0B, 0x44, -+0x8C, 0xD8, 0x09, 0xE7, 0x22, 0x29, 0x25, 0xD8, 0x88, 0xF8, 0x3A, 0x00, 0x00, 0x28, 0x3F, 0xF4, 0xFD, 0xAE, 0x00, 0xEB, -+0x0E, 0x04, 0x70, 0x46, 0x00, 0xEB, 0x03, 0x0B, 0x1B, 0xF8, 0x0C, 0xB0, 0x00, 0xF8, 0x01, 0xBF, 0xA0, 0x42, 0xF7, 0xD1, -+0x52, 0x1A, 0x92, 0xB2, 0x02, 0x2A, 0x0B, 0x44, 0x3F, 0xF6, 0x74, 0xAF, 0xF0, 0xE6, 0x52, 0x1A, 0x92, 0xB2, 0x33, 0x2C, -+0x08, 0xBF, 0x1D, 0x46, 0x02, 0x2A, 0x0B, 0x44, 0x3F, 0xF6, 0x6A, 0xAF, 0xE6, 0xE6, 0x1F, 0x46, 0xDE, 0xE6, 0x00, 0x23, -+0x88, 0xF8, 0x65, 0x30, 0xDA, 0xF8, 0x00, 0x40, 0x04, 0x21, 0xA9, 0xE6, 0x78, 0xEF, 0x17, 0x00, 0x1C, 0x07, 0x18, 0x00, -+0x88, 0x06, 0x18, 0x00, 0x01, 0x29, 0x08, 0xF1, 0x66, 0x03, 0x00, 0xF0, 0x47, 0x81, 0x04, 0x9A, 0x41, 0x2A, 0x35, 0xBF, -+0x40, 0x20, 0x80, 0x20, 0x24, 0x22, 0x64, 0x22, 0x11, 0x1D, 0x03, 0xF8, 0x01, 0x2B, 0xCA, 0xB2, 0x90, 0x42, 0xF9, 0xD2, -+0x08, 0x23, 0xF4, 0xE6, 0x05, 0x9B, 0xFF, 0x2B, 0x4E, 0xD0, 0x05, 0x9B, 0x00, 0x2B, 0x00, 0xF0, 0x85, 0x80, 0x05, 0x9A, -+0x88, 0xF8, 0x66, 0x20, 0x01, 0x23, 0x88, 0xF8, 0x65, 0x30, 0x04, 0x9B, 0xA3, 0xF1, 0x53, 0x02, 0x08, 0xF1, 0x66, 0x03, -+0x2E, 0x2A, 0x30, 0xD8, 0xDF, 0xE8, 0x12, 0xF0, 0x39, 0x00, 0x31, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, -+0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, -+0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, -+0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x39, 0x00, 0x31, 0x00, 0x2F, 0x00, -+0x39, 0x00, 0x31, 0x00, 0x2F, 0x00, 0x39, 0x00, 0x31, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x39, 0x00, 0x31, 0x00, 0x71, 0x01, -+0x6E, 0x01, 0x01, 0x23, 0xAD, 0xE6, 0x05, 0x9B, 0x04, 0x93, 0x04, 0x9B, 0x04, 0x3B, 0x88, 0xF8, 0x67, 0x30, 0x02, 0x23, -+0xA5, 0xE6, 0x05, 0x9B, 0x04, 0x93, 0x9D, 0xE6, 0x00, 0x2D, 0x8D, 0xD0, 0xAB, 0x78, 0x04, 0x9A, 0x93, 0x42, 0x89, 0xD1, -+0x68, 0x78, 0x43, 0x1E, 0xDB, 0xB2, 0x1C, 0x2B, 0x28, 0xBF, 0x1C, 0x23, 0x59, 0x1E, 0x01, 0x28, 0x05, 0xF1, 0x03, 0x05, -+0xC9, 0xB2, 0x3F, 0xF4, 0x7D, 0xAF, 0x32, 0x46, 0x08, 0xEB, 0x02, 0x04, 0xAE, 0x5C, 0x84, 0xF8, 0x66, 0x60, 0x91, 0x42, -+0x02, 0xF1, 0x01, 0x02, 0xF6, 0xD1, 0x01, 0x28, 0x3F, 0xF4, 0x70, 0xAF, 0x88, 0xF8, 0x65, 0x30, 0x01, 0x2B, 0x7F, 0xF4, -+0x80, 0xAE, 0x98, 0xF8, 0x66, 0x30, 0x05, 0x93, 0x91, 0xE7, 0x98, 0xF8, 0x03, 0x30, 0x01, 0x2B, 0x3F, 0xF6, 0x77, 0xAE, -+0x04, 0x9B, 0x72, 0x2B, 0x94, 0xBF, 0x00, 0x23, 0x01, 0x23, 0x88, 0xF8, 0x64, 0x30, 0x05, 0x9B, 0xFF, 0x2B, 0x7F, 0xF4, -+0x78, 0xAF, 0x55, 0xE7, 0x04, 0x9A, 0x08, 0xF1, 0x66, 0x03, 0x51, 0x3A, 0x1E, 0x46, 0x30, 0x2A, 0x3F, 0xF6, 0x4B, 0xAF, -+0x01, 0xA1, 0x51, 0xF8, 0x22, 0xF0, 0x00, 0xBF, 0x9B, 0x5B, 0x15, 0x00, 0x27, 0x5C, 0x15, 0x00, 0x9B, 0x5B, 0x15, 0x00, -+0x9B, 0x5B, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, -+0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, -+0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, -+0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, -+0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, -+0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, 0xF3, 0x58, 0x15, 0x00, -+0xF3, 0x58, 0x15, 0x00, 0x91, 0x5B, 0x15, 0x00, 0x91, 0x5B, 0x15, 0x00, 0x91, 0x5B, 0x15, 0x00, 0x87, 0x5B, 0x15, 0x00, -+0x87, 0x5B, 0x15, 0x00, 0x87, 0x5B, 0x15, 0x00, 0x7D, 0x5B, 0x15, 0x00, 0x7D, 0x5B, 0x15, 0x00, 0x7D, 0x5B, 0x15, 0x00, -+0x29, 0x5B, 0x15, 0x00, 0x03, 0x5C, 0x15, 0x00, 0x29, 0x5B, 0x15, 0x00, 0x29, 0x5B, 0x15, 0x00, 0xE9, 0x5B, 0x15, 0x00, -+0x0D, 0x5C, 0x15, 0x00, 0x00, 0x25, 0x04, 0x20, 0xA2, 0x24, 0x95, 0x22, 0x71, 0x1E, 0x0B, 0x46, 0x02, 0x33, 0x01, 0xF8, -+0x01, 0x2F, 0x02, 0x44, 0x2B, 0x44, 0x94, 0x42, 0xA3, 0xEB, 0x06, 0x03, 0xF5, 0xDC, 0x40, 0x4A, 0xDB, 0xB2, 0x12, 0x68, -+0x88, 0xF8, 0x65, 0x30, 0xB2, 0xF9, 0x00, 0x20, 0x00, 0x2A, 0x03, 0xDB, 0x00, 0x2B, 0x7F, 0xF4, 0x5F, 0xAF, 0xCB, 0xE6, -+0x1C, 0x2B, 0xF9, 0xD9, 0x39, 0x49, 0x3A, 0x48, 0x40, 0xF2, 0x01, 0x32, 0xEF, 0xF7, 0x06, 0xF8, 0x98, 0xF8, 0x65, 0x30, -+0x00, 0x2B, 0x7F, 0xF4, 0x51, 0xAF, 0xBD, 0xE6, 0x00, 0x25, 0x04, 0x20, 0x91, 0x24, 0x64, 0x22, 0xD4, 0xE7, 0x00, 0x25, -+0x04, 0x20, 0x41, 0x24, 0x34, 0x22, 0xCF, 0xE7, 0x00, 0x25, 0x04, 0x20, 0x31, 0x24, 0x24, 0x22, 0xCA, 0xE7, 0x01, 0x20, -+0x02, 0x46, 0x00, 0x25, 0x0E, 0x24, 0xC5, 0xE7, 0x00, 0x28, 0x7F, 0xF4, 0xB6, 0xAE, 0x04, 0x9A, 0x23, 0x2A, 0x7F, 0xF6, -+0x06, 0xAF, 0x30, 0x2A, 0x15, 0xD9, 0x40, 0x2A, 0x10, 0xD9, 0x70, 0x2A, 0x3B, 0xD9, 0x80, 0x2A, 0x36, 0xD9, 0x90, 0x2A, -+0x3F, 0xF6, 0xFB, 0xAE, 0x90, 0x21, 0x84, 0x22, 0x10, 0x1D, 0x03, 0xF8, 0x01, 0x2B, 0xC2, 0xB2, 0x91, 0x42, 0xF9, 0xD2, -+0x04, 0x23, 0xA0, 0xE5, 0x40, 0x21, 0x34, 0x22, 0xF4, 0xE7, 0x30, 0x21, 0x24, 0x22, 0xF1, 0xE7, 0x24, 0x22, 0x03, 0xF8, -+0x01, 0x2B, 0x04, 0x32, 0x44, 0x2A, 0xFA, 0xD1, 0x08, 0xF1, 0x6E, 0x06, 0x08, 0x25, 0x04, 0x20, 0x91, 0x24, 0x64, 0x22, -+0x96, 0xE7, 0x00, 0x25, 0x04, 0x20, 0xAA, 0x24, 0x95, 0x22, 0x91, 0xE7, 0x24, 0x22, 0x03, 0xF8, 0x01, 0x2B, 0x04, 0x32, -+0x44, 0x2A, 0xFA, 0xD1, 0x08, 0xF1, 0x6E, 0x06, 0x08, 0x25, 0x04, 0x20, 0x81, 0x24, 0x64, 0x22, 0x84, 0xE7, 0x0F, 0x24, -+0x01, 0x20, 0x00, 0x25, 0x0E, 0x22, 0x7F, 0xE7, 0x80, 0x21, 0x74, 0x22, 0xCA, 0xE7, 0x70, 0x21, 0x64, 0x22, 0xC7, 0xE7, -+0x05, 0x9A, 0x04, 0x92, 0x69, 0xE6, 0x05, 0x9A, 0x04, 0x92, 0xB0, 0xE7, 0x38, 0x36, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, -+0x5C, 0xD1, 0x15, 0x00, 0x70, 0xB5, 0x15, 0x4D, 0x2C, 0x68, 0xA5, 0xF5, 0xBD, 0x56, 0x01, 0x34, 0xA5, 0xF1, 0x90, 0x01, -+0x2C, 0x60, 0x33, 0x46, 0x01, 0x20, 0x9A, 0x88, 0x01, 0x2A, 0x88, 0xBF, 0x98, 0x80, 0x03, 0xF5, 0xF6, 0x73, 0x8B, 0x42, -+0xF7, 0xD1, 0x41, 0xF2, 0xA4, 0x73, 0xF3, 0x58, 0x9C, 0x42, 0x0B, 0xDA, 0x04, 0x21, 0x0B, 0x20, 0xED, 0xF7, 0x90, 0xF8, -+0x0B, 0x22, 0xBD, 0xE8, 0x70, 0x40, 0x11, 0x46, 0x4F, 0xF4, 0x30, 0x50, 0xEC, 0xF7, 0xF6, 0xBE, 0x00, 0x21, 0x0B, 0x20, -+0xED, 0xF7, 0x84, 0xF8, 0x4F, 0xF0, 0xFF, 0x33, 0x2B, 0x60, 0x70, 0xBD, 0x18, 0x07, 0x18, 0x00, 0x2D, 0xE9, 0xF8, 0x43, -+0x3E, 0x4C, 0x3F, 0x4E, 0x04, 0xF5, 0xBD, 0x53, 0x31, 0x68, 0x1B, 0x68, 0xB1, 0xF9, 0x00, 0x10, 0x03, 0xEB, 0x03, 0x13, -+0x04, 0xEB, 0xC3, 0x05, 0x05, 0xF5, 0xB8, 0x55, 0x00, 0x29, 0x05, 0xF1, 0x10, 0x05, 0x4F, 0xEA, 0xC3, 0x03, 0x3A, 0xDB, -+0x23, 0x44, 0x41, 0xF2, 0x13, 0x72, 0x9B, 0x5C, 0x01, 0x2B, 0x45, 0xD9, 0x02, 0x2B, 0x50, 0xD1, 0x02, 0x21, 0x0B, 0x20, -+0xED, 0xF7, 0x5C, 0xF8, 0x30, 0x48, 0x2E, 0x4C, 0xA0, 0xF1, 0x88, 0x06, 0x06, 0xF1, 0x88, 0x09, 0xED, 0xF7, 0xE4, 0xFA, -+0x00, 0x27, 0x4F, 0xF0, 0x02, 0x08, 0x03, 0xE0, 0x04, 0xF5, 0xF6, 0x74, 0xB4, 0x42, 0x18, 0xD0, 0xA3, 0x88, 0x01, 0x2B, -+0xF8, 0xD1, 0x63, 0x7D, 0x04, 0xF1, 0x1C, 0x01, 0x19, 0x44, 0x2A, 0x46, 0xA0, 0x1D, 0xFF, 0xF7, 0x15, 0xFB, 0x00, 0x28, -+0xEE, 0xD0, 0x21, 0x46, 0x27, 0x83, 0xE7, 0x75, 0xA4, 0xF8, 0x04, 0x80, 0x48, 0x46, 0x04, 0xF5, 0xF6, 0x74, 0xED, 0xF7, -+0xC9, 0xFA, 0xB4, 0x42, 0xE6, 0xD1, 0x28, 0x46, 0x00, 0x21, 0xBD, 0xE8, 0xF8, 0x43, 0xFF, 0xF7, 0x99, 0xBA, 0x1C, 0x44, -+0x41, 0xF2, 0x12, 0x73, 0xE3, 0x5C, 0x05, 0x2B, 0x19, 0xD0, 0x17, 0x49, 0x17, 0x48, 0x40, 0xF2, 0xA3, 0x62, 0xEE, 0xF7, -+0x09, 0xFF, 0x41, 0xF2, 0x13, 0x73, 0xE3, 0x5C, 0x01, 0x2B, 0x05, 0xD8, 0x28, 0x46, 0x01, 0x21, 0xBD, 0xE8, 0xF8, 0x43, -+0xFF, 0xF7, 0x24, 0xBB, 0x02, 0x2B, 0xB3, 0xD0, 0x33, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x08, 0xDB, 0xBD, 0xE8, -+0xF8, 0x83, 0x41, 0xF2, 0x13, 0x73, 0xE3, 0x5C, 0x01, 0x2B, 0xEB, 0xD9, 0x02, 0x2B, 0xA5, 0xD0, 0xBD, 0xE8, 0xF8, 0x43, -+0x05, 0x49, 0x07, 0x48, 0x40, 0xF2, 0xAF, 0x62, 0xEE, 0xF7, 0xE6, 0xBE, 0x78, 0xEF, 0x17, 0x00, 0x38, 0x36, 0x17, 0x00, -+0x10, 0x07, 0x18, 0x00, 0x70, 0x79, 0x15, 0x00, 0x94, 0xD1, 0x15, 0x00, 0x64, 0x7D, 0x15, 0x00, 0x2D, 0xE9, 0xF0, 0x41, -+0xDF, 0xF8, 0xCC, 0x80, 0x2C, 0x4A, 0xD8, 0xF8, 0x00, 0x30, 0x14, 0x68, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x0C, 0xDB, -+0x29, 0x4F, 0x04, 0xEB, 0x04, 0x13, 0x07, 0xEB, 0xC3, 0x03, 0x41, 0xF2, 0x13, 0x72, 0x25, 0x01, 0x9B, 0x5C, 0x01, 0x2B, -+0x19, 0xD9, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x2C, 0x35, 0xDB, 0x22, 0x4F, 0x04, 0xEB, 0x04, 0x16, 0x07, 0xEB, 0xC6, 0x06, -+0x41, 0xF2, 0x12, 0x73, 0x25, 0x01, 0xF3, 0x5C, 0x05, 0x2B, 0x15, 0xD0, 0x1D, 0x49, 0x1E, 0x48, 0x4F, 0xF4, 0xD7, 0x62, -+0xEE, 0xF7, 0xAE, 0xFE, 0x41, 0xF2, 0x13, 0x73, 0xF3, 0x5C, 0x01, 0x2B, 0x17, 0xD8, 0x2C, 0x44, 0x07, 0xEB, 0xC4, 0x00, -+0x00, 0xF5, 0xB8, 0x50, 0xBD, 0xE8, 0xF0, 0x41, 0x10, 0x30, 0x00, 0x21, 0xFF, 0xF7, 0xC4, 0xBA, 0x41, 0xF2, 0x13, 0x73, -+0xF3, 0x5C, 0x01, 0x2B, 0xEF, 0xD9, 0xBD, 0xE8, 0xF0, 0x41, 0x0F, 0x49, 0x10, 0x48, 0x40, 0xF2, 0xC1, 0x62, 0xEE, 0xF7, -+0x91, 0xBE, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0xF1, 0xDB, 0xBD, 0xE8, 0xF0, 0x81, 0x08, 0x49, -+0x0A, 0x48, 0x40, 0xF2, 0xB7, 0x62, 0xEE, 0xF7, 0x83, 0xFE, 0xD8, 0xF8, 0x00, 0x30, 0xB3, 0xF9, 0x00, 0x30, 0x00, 0x2B, -+0xBD, 0xDB, 0xAD, 0xE7, 0x18, 0x07, 0x18, 0x00, 0x78, 0xEF, 0x17, 0x00, 0x70, 0x79, 0x15, 0x00, 0x94, 0xD1, 0x15, 0x00, -+0x64, 0x7D, 0x15, 0x00, 0xC0, 0xD1, 0x15, 0x00, 0x38, 0x36, 0x17, 0x00, 0x70, 0xB5, 0x29, 0xB3, 0x18, 0x4C, 0x04, 0xF5, -+0xBD, 0x53, 0x05, 0x46, 0x1E, 0x68, 0xFE, 0xF7, 0x01, 0xFF, 0x02, 0x46, 0x40, 0xB1, 0x0B, 0x20, 0xED, 0xF7, 0x20, 0xF8, -+0x03, 0x28, 0x1F, 0xD0, 0xBD, 0xE8, 0x70, 0x40, 0xFF, 0xF7, 0xC6, 0xBE, 0x06, 0xEB, 0x06, 0x16, 0x04, 0xEB, 0xC6, 0x03, -+0x01, 0x21, 0x03, 0xF5, 0xB8, 0x53, 0x85, 0xF8, 0x5E, 0x10, 0x10, 0x33, 0x01, 0x46, 0x28, 0x46, 0xFE, 0xF7, 0x00, 0xFF, -+0x28, 0x46, 0x03, 0x21, 0xBD, 0xE8, 0x70, 0x40, 0xDA, 0xF7, 0x42, 0xB8, 0x0B, 0x20, 0xEC, 0xF7, 0x5B, 0xFF, 0x05, 0x4B, -+0x4F, 0xF0, 0xFF, 0x32, 0x1A, 0x60, 0x70, 0xBD, 0xBD, 0xE8, 0x70, 0x40, 0xFF, 0xF7, 0x60, 0xBF, 0x78, 0xEF, 0x17, 0x00, -+0x18, 0x07, 0x18, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x8B, 0xB0, 0xB6, 0x4F, 0x9D, 0xF8, 0x50, 0x40, 0x03, 0x94, 0x9D, 0xF9, -+0x54, 0x40, 0x04, 0x94, 0x07, 0xF5, 0xBD, 0x55, 0x04, 0x46, 0x28, 0x68, 0x25, 0x7C, 0x8D, 0xF8, 0x20, 0x50, 0x65, 0x7C, -+0x8D, 0xF8, 0x21, 0x50, 0xA5, 0x7C, 0x8D, 0xF8, 0x22, 0x50, 0xE5, 0x7C, 0x8D, 0xF8, 0x23, 0x50, 0x25, 0x7D, 0x8D, 0xF8, -+0x24, 0x50, 0x00, 0x28, 0x65, 0x7D, 0x9D, 0xF8, 0x58, 0x90, 0x8D, 0xF8, 0x25, 0x50, 0x0E, 0x46, 0x90, 0x46, 0x05, 0x93, -+0xC0, 0xF2, 0x1A, 0x81, 0x00, 0xEB, 0x00, 0x10, 0x07, 0xEB, 0xC0, 0x00, 0x00, 0xF5, 0xB8, 0x57, 0x10, 0x37, 0x3A, 0x46, -+0x00, 0x21, 0x08, 0xA8, 0xFF, 0xF7, 0xEE, 0xF9, 0x10, 0xB9, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xBD, 0xF8, 0x20, 0x00, -+0xBD, 0xF8, 0x24, 0x30, 0x01, 0x93, 0x00, 0x21, 0xBD, 0xF8, 0x22, 0xE0, 0x97, 0x4B, 0x98, 0x4A, 0x02, 0x94, 0x8C, 0x46, -+0x0D, 0x46, 0x83, 0x46, 0x0B, 0xE0, 0x98, 0x88, 0x01, 0x28, 0x00, 0xF0, 0xC1, 0x80, 0x03, 0x28, 0x00, 0xF0, 0xB4, 0x80, -+0x88, 0xB1, 0x03, 0xF5, 0xF6, 0x73, 0x93, 0x42, 0x14, 0xD0, 0xB3, 0xF8, 0x06, 0xA0, 0xDA, 0x45, 0xEF, 0xD1, 0x18, 0x89, -+0x70, 0x45, 0xEC, 0xD1, 0x58, 0x89, 0x01, 0x9C, 0xA0, 0x42, 0xE8, 0xD1, 0x02, 0x9C, 0x1D, 0x46, 0x10, 0xE0, 0x00, 0x2D, -+0x08, 0xBF, 0x1D, 0x46, 0x03, 0xF5, 0xF6, 0x73, 0x93, 0x42, 0xEA, 0xD1, 0x02, 0x9C, 0x00, 0x2D, 0x00, 0xF0, 0x42, 0x81, -+0x4F, 0xF4, 0xF6, 0x72, 0x00, 0x21, 0x28, 0x46, 0xCA, 0xF7, 0xDC, 0xF8, 0xAB, 0x88, 0x03, 0x2B, 0xBF, 0xD0, 0x03, 0x9B, -+0xBD, 0xF8, 0x20, 0x10, 0xBD, 0xF8, 0x22, 0x20, 0xC5, 0xF8, 0x0C, 0x80, 0x00, 0x2B, 0xBD, 0xF8, 0x24, 0x30, 0x6B, 0x81, -+0x08, 0xBF, 0x05, 0x20, 0x05, 0xF1, 0x1C, 0x03, 0x18, 0xBF, 0x04, 0x20, 0x02, 0x93, 0x04, 0xF1, 0x24, 0x08, 0x85, 0xF8, -+0x11, 0x90, 0xA8, 0x74, 0xE9, 0x80, 0x2A, 0x81, 0x18, 0x34, 0x05, 0xF1, 0x1B, 0x03, 0x14, 0xF8, 0x01, 0x2B, 0x03, 0xF8, -+0x01, 0x2F, 0x44, 0x45, 0xF9, 0xD1, 0x02, 0x9B, 0xA6, 0xF1, 0x24, 0x09, 0x03, 0xF1, 0x0C, 0x0B, 0xB9, 0xF1, 0x02, 0x0F, -+0x4F, 0xF0, 0x00, 0x03, 0xCD, 0xE9, 0x06, 0x33, 0x40, 0xF3, 0x56, 0x81, 0x4F, 0xF4, 0xE2, 0x7A, 0x3A, 0x46, 0x98, 0xF8, -+0x01, 0x40, 0x98, 0xF8, 0x00, 0x60, 0x98, 0xF8, 0x02, 0x70, 0x02, 0x34, 0x08, 0xF1, 0x02, 0x00, 0x00, 0x2E, 0x71, 0xD0, -+0x03, 0x2E, 0x7D, 0xD0, 0xA9, 0x7C, 0x05, 0x29, 0x00, 0xF2, 0x81, 0x80, 0x2A, 0x2E, 0x00, 0xF0, 0x8D, 0x80, 0x3D, 0x2E, -+0x00, 0xF0, 0x8D, 0x80, 0xC0, 0x2E, 0x00, 0xF0, 0x9A, 0x80, 0xFF, 0x2E, 0x02, 0xD1, 0x08, 0x2C, 0x00, 0xF2, 0xCD, 0x80, -+0x54, 0x45, 0x07, 0xDC, 0x39, 0x46, 0x30, 0x46, 0x01, 0x92, 0xFE, 0xF7, 0xD5, 0xFD, 0x01, 0x9A, 0x00, 0x28, 0x46, 0xD1, -+0xA0, 0x44, 0xA9, 0xEB, 0x04, 0x09, 0xB9, 0xF1, 0x02, 0x0F, 0xD0, 0xDC, 0xCA, 0xF5, 0xE8, 0x7A, 0x1F, 0xFA, 0x8A, 0xFA, -+0xAB, 0x7D, 0xA5, 0xF8, 0x1A, 0xA0, 0x00, 0x2B, 0x00, 0xF0, 0x94, 0x80, 0x04, 0x9B, 0x2B, 0x75, 0x2B, 0x7C, 0x06, 0x9A, -+0x04, 0x2A, 0x00, 0xF0, 0x06, 0x81, 0x03, 0x2A, 0x00, 0xF0, 0x05, 0x81, 0x02, 0x2A, 0x00, 0xF0, 0x04, 0x81, 0x03, 0x99, -+0x00, 0x29, 0x40, 0xF0, 0xC0, 0x80, 0x0E, 0x2B, 0x00, 0xF0, 0x14, 0x81, 0x00, 0x2A, 0x00, 0xF0, 0x06, 0x81, 0x07, 0x9B, -+0x01, 0x2B, 0x0C, 0xBF, 0x54, 0x23, 0x53, 0x23, 0x01, 0x22, 0xEB, 0x74, 0xAA, 0x80, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, -+0x00, 0x29, 0x41, 0xD0, 0x93, 0xF9, 0x14, 0xA0, 0x91, 0xF9, 0x14, 0x00, 0x82, 0x45, 0xB8, 0xBF, 0x19, 0x46, 0x42, 0xE7, -+0xBC, 0xF1, 0x00, 0x0F, 0x34, 0xD0, 0x93, 0xF9, 0x14, 0xA0, 0x9C, 0xF9, 0x14, 0x00, 0x82, 0x45, 0xB8, 0xBF, 0x9C, 0x46, -+0x37, 0xE7, 0x43, 0x46, 0xAB, 0xEB, 0x03, 0x00, 0xA0, 0x44, 0x19, 0x78, 0xC1, 0x54, 0x01, 0x33, 0x98, 0x45, 0xFA, 0xD1, -+0xA3, 0x44, 0xAA, 0xEB, 0x04, 0x0A, 0xAC, 0xE7, 0x02, 0x9B, 0x01, 0x92, 0xAB, 0xEB, 0x03, 0x01, 0x69, 0x75, 0xA8, 0x1D, -+0x41, 0x46, 0xFF, 0xF7, 0xF5, 0xF8, 0x01, 0x9A, 0x00, 0x28, 0x95, 0xD1, 0xA8, 0x80, 0x02, 0xE7, 0x02, 0x9B, 0xAB, 0xEB, -+0x03, 0x01, 0xA9, 0x75, 0x01, 0x78, 0x29, 0x74, 0x8C, 0xE7, 0x06, 0x29, 0x3F, 0xF4, 0x7F, 0xAF, 0x08, 0x29, 0x7F, 0xF6, -+0x7F, 0xAF, 0x0D, 0x29, 0x84, 0xD8, 0x7E, 0xE7, 0x00, 0x27, 0xEA, 0xE6, 0x9C, 0x46, 0x08, 0xE7, 0x19, 0x46, 0x06, 0xE7, -+0x06, 0x21, 0xA9, 0x74, 0x7A, 0xE7, 0x18, 0x2C, 0x7F, 0xF4, 0x78, 0xAF, 0x4F, 0xF0, 0x07, 0x03, 0xAB, 0x74, 0x98, 0xF8, -+0x03, 0x10, 0x11, 0xF0, 0x03, 0x03, 0x07, 0x93, 0x06, 0x9B, 0x18, 0xBF, 0x01, 0x23, 0x06, 0x93, 0x6A, 0xE7, 0x07, 0x2C, -+0x7F, 0xF4, 0x68, 0xAF, 0x4F, 0xF0, 0x09, 0x03, 0xAB, 0x74, 0x01, 0x78, 0x00, 0x29, 0x3F, 0xF4, 0x61, 0xAF, 0x01, 0x29, -+0x76, 0xD0, 0x02, 0x29, 0x00, 0xF0, 0x97, 0x80, 0x03, 0x29, 0x06, 0x9B, 0x08, 0xBF, 0x04, 0x23, 0x06, 0x93, 0x55, 0xE7, -+0x78, 0xEF, 0x17, 0x00, 0x88, 0x06, 0x18, 0x00, 0xAA, 0x88, 0x22, 0xB1, 0x95, 0xF9, 0x14, 0x20, 0x04, 0x99, 0x8A, 0x42, -+0x60, 0xDA, 0x04, 0x9A, 0x2A, 0x75, 0x03, 0x9A, 0x00, 0x2A, 0x42, 0xD1, 0x05, 0x99, 0xA1, 0xF6, 0x6C, 0x13, 0x48, 0x2B, -+0x6D, 0xD8, 0x40, 0xF6, 0xB4, 0x13, 0x99, 0x42, 0x00, 0xF0, 0x82, 0x80, 0x48, 0x4A, 0xA1, 0xF6, 0x67, 0x13, 0xA2, 0xFB, -+0x03, 0x23, 0xC3, 0xF3, 0x87, 0x03, 0x2B, 0x74, 0x4F, 0xE7, 0x24, 0x2F, 0x7F, 0xF4, 0x30, 0xAF, 0x09, 0x29, 0x11, 0xD0, -+0x0B, 0x2C, 0x0F, 0xD9, 0xD8, 0xF8, 0x03, 0x10, 0x4B, 0x04, 0x0B, 0xD5, 0x98, 0xF8, 0x09, 0x10, 0x41, 0xB1, 0x01, 0x29, -+0x71, 0xD0, 0x02, 0x29, 0x72, 0xD0, 0x03, 0x29, 0x06, 0x9B, 0x08, 0xBF, 0x04, 0x23, 0x06, 0x93, 0x4F, 0xF0, 0x0E, 0x03, -+0xAB, 0x74, 0x17, 0xE7, 0x89, 0xB3, 0x0D, 0x46, 0xBA, 0xE6, 0x30, 0x2B, 0x24, 0xD9, 0x40, 0x2B, 0x40, 0xD9, 0x90, 0x2B, -+0x4C, 0xD9, 0xA4, 0x2B, 0x59, 0xD8, 0x06, 0x9B, 0x00, 0x2B, 0x54, 0xD0, 0x0A, 0x23, 0x07, 0x9A, 0x01, 0x2A, 0x0C, 0xBF, -+0x74, 0x33, 0x75, 0x33, 0x38, 0xE7, 0x03, 0x9A, 0x01, 0x2A, 0xCA, 0xD1, 0x05, 0x9A, 0xA2, 0xF5, 0x9C, 0x51, 0xA1, 0xF1, -+0x0D, 0x02, 0x92, 0xB2, 0xB2, 0xF5, 0x4D, 0x7F, 0xC1, 0xD8, 0x26, 0x4A, 0xA1, 0xF1, 0x08, 0x03, 0xA2, 0xFB, 0x03, 0x23, -+0xC3, 0xF3, 0x87, 0x03, 0x2B, 0x74, 0x0A, 0xE7, 0x06, 0x9B, 0x23, 0xB3, 0x00, 0x23, 0xE0, 0xE7, 0x2B, 0x7C, 0x04, 0xE7, -+0x02, 0x23, 0x06, 0x93, 0xE4, 0xE6, 0xBC, 0xF1, 0x00, 0x0F, 0x3F, 0xF4, 0x50, 0xAE, 0x9C, 0xF9, 0x14, 0x30, 0x04, 0x9A, -+0x93, 0x42, 0xBF, 0xF6, 0x4A, 0xAE, 0x65, 0x46, 0x7E, 0xE6, 0x82, 0x23, 0x0C, 0xE7, 0x81, 0x23, 0x0A, 0xE7, 0x80, 0x23, -+0x08, 0xE7, 0x03, 0x9B, 0x2B, 0x74, 0xEC, 0xE6, 0x06, 0x9B, 0x8B, 0xB1, 0x03, 0x23, 0xC2, 0xE7, 0x4F, 0xF0, 0x0C, 0x0A, -+0xDC, 0xE6, 0x51, 0x23, 0xFC, 0xE6, 0x73, 0x23, 0xFA, 0xE6, 0x03, 0x23, 0x06, 0x93, 0xC1, 0xE6, 0x06, 0x9B, 0x43, 0xB1, -+0x06, 0x23, 0xB4, 0xE7, 0x52, 0x23, 0xF1, 0xE6, 0x76, 0x23, 0xEF, 0xE6, 0x0E, 0x23, 0x2B, 0x74, 0xD3, 0xE6, 0x79, 0x23, -+0xEA, 0xE6, 0x7C, 0x23, 0xE8, 0xE6, 0x7D, 0x23, 0xE6, 0xE6, 0x02, 0x23, 0x06, 0x93, 0x91, 0xE7, 0x03, 0x23, 0x06, 0x93, -+0x8E, 0xE7, 0x00, 0xBF, 0xCD, 0xCC, 0xCC, 0xCC, 0x2D, 0xE9, 0xF0, 0x48, 0xC1, 0xF3, 0x0A, 0x57, 0xA7, 0xF2, 0xFF, 0x34, -+0x13, 0x2C, 0x0B, 0x46, 0x0D, 0x46, 0x02, 0x46, 0x0F, 0xDC, 0x00, 0x2C, 0x2A, 0xDB, 0x1D, 0x49, 0x21, 0x41, 0x03, 0xEA, -+0x01, 0x00, 0x10, 0x43, 0x2F, 0xD0, 0x4F, 0xF4, 0x00, 0x23, 0x23, 0x41, 0x1D, 0x44, 0x25, 0xEA, 0x01, 0x05, 0x00, 0x23, -+0x25, 0xE0, 0x33, 0x2C, 0x07, 0xDD, 0xB4, 0xF5, 0x80, 0x6F, 0x22, 0xD1, 0x00, 0xF0, 0x2E, 0xF8, 0x02, 0x46, 0x0B, 0x46, -+0x1D, 0xE0, 0xA7, 0xF2, 0x13, 0x47, 0x4F, 0xF0, 0xFF, 0x31, 0x21, 0xFA, 0x07, 0xF7, 0x38, 0x42, 0x15, 0xD0, 0x01, 0x22, -+0xC4, 0xF1, 0x33, 0x03, 0x02, 0xFA, 0x03, 0xF3, 0xC3, 0x18, 0x28, 0xBF, 0xAD, 0x18, 0x23, 0xEA, 0x07, 0x03, 0x08, 0xE0, -+0x01, 0xF0, 0x00, 0x45, 0x01, 0x34, 0x04, 0xBF, 0x45, 0xF0, 0x7F, 0x55, 0x45, 0xF4, 0x40, 0x15, 0x00, 0x23, 0x1A, 0x46, -+0x2B, 0x46, 0x10, 0x46, 0x19, 0x46, 0xBD, 0xE8, 0xF0, 0x88, 0x00, 0xBF, 0xFF, 0xFF, 0x0F, 0x00, 0x81, 0xF0, 0x00, 0x41, -+0x02, 0xE0, 0x00, 0xBF, 0x83, 0xF0, 0x00, 0x43, 0x30, 0xB5, 0x4F, 0xEA, 0x41, 0x04, 0x4F, 0xEA, 0x43, 0x05, 0x94, 0xEA, -+0x05, 0x0F, 0x08, 0xBF, 0x90, 0xEA, 0x02, 0x0F, 0x1F, 0xBF, 0x54, 0xEA, 0x00, 0x0C, 0x55, 0xEA, 0x02, 0x0C, 0x7F, 0xEA, -+0x64, 0x5C, 0x7F, 0xEA, 0x65, 0x5C, 0x00, 0xF0, 0xE2, 0x80, 0x4F, 0xEA, 0x54, 0x54, 0xD4, 0xEB, 0x55, 0x55, 0xB8, 0xBF, -+0x6D, 0x42, 0x0C, 0xDD, 0x2C, 0x44, 0x80, 0xEA, 0x02, 0x02, 0x81, 0xEA, 0x03, 0x03, 0x82, 0xEA, 0x00, 0x00, 0x83, 0xEA, -+0x01, 0x01, 0x80, 0xEA, 0x02, 0x02, 0x81, 0xEA, 0x03, 0x03, 0x36, 0x2D, 0x88, 0xBF, 0x30, 0xBD, 0x11, 0xF0, 0x00, 0x4F, -+0x4F, 0xEA, 0x01, 0x31, 0x4F, 0xF4, 0x80, 0x1C, 0x4C, 0xEA, 0x11, 0x31, 0x02, 0xD0, 0x40, 0x42, 0x61, 0xEB, 0x41, 0x01, -+0x13, 0xF0, 0x00, 0x4F, 0x4F, 0xEA, 0x03, 0x33, 0x4C, 0xEA, 0x13, 0x33, 0x02, 0xD0, 0x52, 0x42, 0x63, 0xEB, 0x43, 0x03, -+0x94, 0xEA, 0x05, 0x0F, 0x00, 0xF0, 0xA7, 0x80, 0xA4, 0xF1, 0x01, 0x04, 0xD5, 0xF1, 0x20, 0x0E, 0x0D, 0xDB, 0x02, 0xFA, -+0x0E, 0xFC, 0x22, 0xFA, 0x05, 0xF2, 0x80, 0x18, 0x41, 0xF1, 0x00, 0x01, 0x03, 0xFA, 0x0E, 0xF2, 0x80, 0x18, 0x43, 0xFA, -+0x05, 0xF3, 0x59, 0x41, 0x0E, 0xE0, 0xA5, 0xF1, 0x20, 0x05, 0x0E, 0xF1, 0x20, 0x0E, 0x01, 0x2A, 0x03, 0xFA, 0x0E, 0xFC, -+0x28, 0xBF, 0x4C, 0xF0, 0x02, 0x0C, 0x43, 0xFA, 0x05, 0xF3, 0xC0, 0x18, 0x51, 0xEB, 0xE3, 0x71, 0x01, 0xF0, 0x00, 0x45, -+0x07, 0xD5, 0x4F, 0xF0, 0x00, 0x0E, 0xDC, 0xF1, 0x00, 0x0C, 0x7E, 0xEB, 0x00, 0x00, 0x6E, 0xEB, 0x01, 0x01, 0xB1, 0xF5, -+0x80, 0x1F, 0x1B, 0xD3, 0xB1, 0xF5, 0x00, 0x1F, 0x0C, 0xD3, 0x49, 0x08, 0x5F, 0xEA, 0x30, 0x00, 0x4F, 0xEA, 0x3C, 0x0C, -+0x04, 0xF1, 0x01, 0x04, 0x4F, 0xEA, 0x44, 0x52, 0x12, 0xF5, 0x80, 0x0F, 0x80, 0xF0, 0x9A, 0x80, 0xBC, 0xF1, 0x00, 0x4F, -+0x08, 0xBF, 0x5F, 0xEA, 0x50, 0x0C, 0x50, 0xF1, 0x00, 0x00, 0x41, 0xEB, 0x04, 0x51, 0x41, 0xEA, 0x05, 0x01, 0x30, 0xBD, -+0x5F, 0xEA, 0x4C, 0x0C, 0x40, 0x41, 0x41, 0xEB, 0x01, 0x01, 0x01, 0x3C, 0x28, 0xBF, 0xB1, 0xF5, 0x80, 0x1F, 0xE9, 0xD2, -+0x91, 0xF0, 0x00, 0x0F, 0x04, 0xBF, 0x01, 0x46, 0x00, 0x20, 0xB1, 0xFA, 0x81, 0xF3, 0x08, 0xBF, 0x20, 0x33, 0xA3, 0xF1, -+0x0B, 0x03, 0xB3, 0xF1, 0x20, 0x02, 0x0C, 0xDA, 0x0C, 0x32, 0x08, 0xDD, 0x02, 0xF1, 0x14, 0x0C, 0xC2, 0xF1, 0x0C, 0x02, -+0x01, 0xFA, 0x0C, 0xF0, 0x21, 0xFA, 0x02, 0xF1, 0x0C, 0xE0, 0x02, 0xF1, 0x14, 0x02, 0xD8, 0xBF, 0xC2, 0xF1, 0x20, 0x0C, -+0x01, 0xFA, 0x02, 0xF1, 0x20, 0xFA, 0x0C, 0xFC, 0xDC, 0xBF, 0x41, 0xEA, 0x0C, 0x01, 0x90, 0x40, 0xE4, 0x1A, 0xA2, 0xBF, -+0x01, 0xEB, 0x04, 0x51, 0x29, 0x43, 0x30, 0xBD, 0x6F, 0xEA, 0x04, 0x04, 0x1F, 0x3C, 0x1C, 0xDA, 0x0C, 0x34, 0x0E, 0xDC, -+0x04, 0xF1, 0x14, 0x04, 0xC4, 0xF1, 0x20, 0x02, 0x20, 0xFA, 0x04, 0xF0, 0x01, 0xFA, 0x02, 0xF3, 0x40, 0xEA, 0x03, 0x00, -+0x21, 0xFA, 0x04, 0xF3, 0x45, 0xEA, 0x03, 0x01, 0x30, 0xBD, 0xC4, 0xF1, 0x0C, 0x04, 0xC4, 0xF1, 0x20, 0x02, 0x20, 0xFA, -+0x02, 0xF0, 0x01, 0xFA, 0x04, 0xF3, 0x40, 0xEA, 0x03, 0x00, 0x29, 0x46, 0x30, 0xBD, 0x21, 0xFA, 0x04, 0xF0, 0x29, 0x46, -+0x30, 0xBD, 0x94, 0xF0, 0x00, 0x0F, 0x83, 0xF4, 0x80, 0x13, 0x06, 0xBF, 0x81, 0xF4, 0x80, 0x11, 0x01, 0x34, 0x01, 0x3D, -+0x4E, 0xE7, 0x7F, 0xEA, 0x64, 0x5C, 0x18, 0xBF, 0x7F, 0xEA, 0x65, 0x5C, 0x29, 0xD0, 0x94, 0xEA, 0x05, 0x0F, 0x08, 0xBF, -+0x90, 0xEA, 0x02, 0x0F, 0x05, 0xD0, 0x54, 0xEA, 0x00, 0x0C, 0x04, 0xBF, 0x19, 0x46, 0x10, 0x46, 0x30, 0xBD, 0x91, 0xEA, -+0x03, 0x0F, 0x1E, 0xBF, 0x00, 0x21, 0x00, 0x20, 0x30, 0xBD, 0x5F, 0xEA, 0x54, 0x5C, 0x05, 0xD1, 0x40, 0x00, 0x49, 0x41, -+0x28, 0xBF, 0x41, 0xF0, 0x00, 0x41, 0x30, 0xBD, 0x14, 0xF5, 0x80, 0x04, 0x3C, 0xBF, 0x01, 0xF5, 0x80, 0x11, 0x30, 0xBD, -+0x01, 0xF0, 0x00, 0x45, 0x45, 0xF0, 0xFE, 0x41, 0x41, 0xF4, 0x70, 0x01, 0x4F, 0xF0, 0x00, 0x00, 0x30, 0xBD, 0x7F, 0xEA, -+0x64, 0x5C, 0x1A, 0xBF, 0x19, 0x46, 0x10, 0x46, 0x7F, 0xEA, 0x65, 0x5C, 0x1C, 0xBF, 0x0B, 0x46, 0x02, 0x46, 0x50, 0xEA, -+0x01, 0x34, 0x06, 0xBF, 0x52, 0xEA, 0x03, 0x35, 0x91, 0xEA, 0x03, 0x0F, 0x41, 0xF4, 0x00, 0x21, 0x30, 0xBD, 0x00, 0xBF, -+0x90, 0xF0, 0x00, 0x0F, 0x04, 0xBF, 0x00, 0x21, 0x70, 0x47, 0x30, 0xB5, 0x4F, 0xF4, 0x80, 0x64, 0x04, 0xF1, 0x32, 0x04, -+0x4F, 0xF0, 0x00, 0x05, 0x4F, 0xF0, 0x00, 0x01, 0x50, 0xE7, 0x00, 0xBF, 0x90, 0xF0, 0x00, 0x0F, 0x04, 0xBF, 0x00, 0x21, -+0x70, 0x47, 0x30, 0xB5, 0x4F, 0xF4, 0x80, 0x64, 0x04, 0xF1, 0x32, 0x04, 0x10, 0xF0, 0x00, 0x45, 0x48, 0xBF, 0x40, 0x42, -+0x4F, 0xF0, 0x00, 0x01, 0x3E, 0xE7, 0x00, 0xBF, 0x42, 0x00, 0x4F, 0xEA, 0xE2, 0x01, 0x4F, 0xEA, 0x31, 0x01, 0x4F, 0xEA, -+0x02, 0x70, 0x1F, 0xBF, 0x12, 0xF0, 0x7F, 0x43, 0x93, 0xF0, 0x7F, 0x4F, 0x81, 0xF0, 0x60, 0x51, 0x70, 0x47, 0x32, 0xF0, -+0x7F, 0x42, 0x08, 0xBF, 0x70, 0x47, 0x93, 0xF0, 0x7F, 0x4F, 0x04, 0xBF, 0x41, 0xF4, 0x00, 0x21, 0x70, 0x47, 0x30, 0xB5, -+0x4F, 0xF4, 0x60, 0x74, 0x01, 0xF0, 0x00, 0x45, 0x21, 0xF0, 0x00, 0x41, 0x1C, 0xE7, 0x00, 0xBF, 0x50, 0xEA, 0x01, 0x02, -+0x08, 0xBF, 0x70, 0x47, 0x30, 0xB5, 0x4F, 0xF0, 0x00, 0x05, 0x0A, 0xE0, 0x50, 0xEA, 0x01, 0x02, 0x08, 0xBF, 0x70, 0x47, -+0x30, 0xB5, 0x11, 0xF0, 0x00, 0x45, 0x02, 0xD5, 0x40, 0x42, 0x61, 0xEB, 0x41, 0x01, 0x4F, 0xF4, 0x80, 0x64, 0x04, 0xF1, -+0x32, 0x04, 0x5F, 0xEA, 0x91, 0x5C, 0x3F, 0xF4, 0xD8, 0xAE, 0x4F, 0xF0, 0x03, 0x02, 0x5F, 0xEA, 0xDC, 0x0C, 0x18, 0xBF, -+0x03, 0x32, 0x5F, 0xEA, 0xDC, 0x0C, 0x18, 0xBF, 0x03, 0x32, 0x02, 0xEB, 0xDC, 0x02, 0xC2, 0xF1, 0x20, 0x03, 0x00, 0xFA, -+0x03, 0xFC, 0x20, 0xFA, 0x02, 0xF0, 0x01, 0xFA, 0x03, 0xFE, 0x40, 0xEA, 0x0E, 0x00, 0x21, 0xFA, 0x02, 0xF1, 0x14, 0x44, -+0xBD, 0xE6, 0x00, 0xBF, 0x70, 0xB5, 0x4F, 0xF0, 0xFF, 0x0C, 0x4C, 0xF4, 0xE0, 0x6C, 0x1C, 0xEA, 0x11, 0x54, 0x1D, 0xBF, -+0x1C, 0xEA, 0x13, 0x55, 0x94, 0xEA, 0x0C, 0x0F, 0x95, 0xEA, 0x0C, 0x0F, 0x00, 0xF0, 0xDE, 0xF8, 0x2C, 0x44, 0x81, 0xEA, -+0x03, 0x06, 0x21, 0xEA, 0x4C, 0x51, 0x23, 0xEA, 0x4C, 0x53, 0x50, 0xEA, 0x01, 0x35, 0x18, 0xBF, 0x52, 0xEA, 0x03, 0x35, -+0x41, 0xF4, 0x80, 0x11, 0x43, 0xF4, 0x80, 0x13, 0x38, 0xD0, 0xA0, 0xFB, 0x02, 0xCE, 0x4F, 0xF0, 0x00, 0x05, 0xE1, 0xFB, -+0x02, 0xE5, 0x06, 0xF0, 0x00, 0x42, 0xE0, 0xFB, 0x03, 0xE5, 0x4F, 0xF0, 0x00, 0x06, 0xE1, 0xFB, 0x03, 0x56, 0x9C, 0xF0, -+0x00, 0x0F, 0x18, 0xBF, 0x4E, 0xF0, 0x01, 0x0E, 0xA4, 0xF1, 0xFF, 0x04, 0xB6, 0xF5, 0x00, 0x7F, 0x64, 0xF5, 0x40, 0x74, -+0x04, 0xD2, 0x5F, 0xEA, 0x4E, 0x0E, 0x6D, 0x41, 0x46, 0xEB, 0x06, 0x06, 0x42, 0xEA, 0xC6, 0x21, 0x41, 0xEA, 0x55, 0x51, -+0x4F, 0xEA, 0xC5, 0x20, 0x40, 0xEA, 0x5E, 0x50, 0x4F, 0xEA, 0xCE, 0x2E, 0xB4, 0xF1, 0xFD, 0x0C, 0x88, 0xBF, 0xBC, 0xF5, -+0xE0, 0x6F, 0x1E, 0xD8, 0xBE, 0xF1, 0x00, 0x4F, 0x08, 0xBF, 0x5F, 0xEA, 0x50, 0x0E, 0x50, 0xF1, 0x00, 0x00, 0x41, 0xEB, -+0x04, 0x51, 0x70, 0xBD, 0x06, 0xF0, 0x00, 0x46, 0x46, 0xEA, 0x01, 0x01, 0x40, 0xEA, 0x02, 0x00, 0x81, 0xEA, 0x03, 0x01, -+0xB4, 0xEB, 0x5C, 0x04, 0xC2, 0xBF, 0xD4, 0xEB, 0x0C, 0x05, 0x41, 0xEA, 0x04, 0x51, 0x70, 0xBD, 0x41, 0xF4, 0x80, 0x11, -+0x4F, 0xF0, 0x00, 0x0E, 0x01, 0x3C, 0x00, 0xF3, 0xAB, 0x80, 0x14, 0xF1, 0x36, 0x0F, 0xDE, 0xBF, 0x00, 0x20, 0x01, 0xF0, -+0x00, 0x41, 0x70, 0xBD, 0xC4, 0xF1, 0x00, 0x04, 0x20, 0x3C, 0x35, 0xDA, 0x0C, 0x34, 0x1B, 0xDC, 0x04, 0xF1, 0x14, 0x04, -+0xC4, 0xF1, 0x20, 0x05, 0x00, 0xFA, 0x05, 0xF3, 0x20, 0xFA, 0x04, 0xF0, 0x01, 0xFA, 0x05, 0xF2, 0x40, 0xEA, 0x02, 0x00, -+0x01, 0xF0, 0x00, 0x42, 0x21, 0xF0, 0x00, 0x41, 0x10, 0xEB, 0xD3, 0x70, 0x21, 0xFA, 0x04, 0xF6, 0x42, 0xEB, 0x06, 0x01, -+0x5E, 0xEA, 0x43, 0x0E, 0x08, 0xBF, 0x20, 0xEA, 0xD3, 0x70, 0x70, 0xBD, 0xC4, 0xF1, 0x0C, 0x04, 0xC4, 0xF1, 0x20, 0x05, -+0x00, 0xFA, 0x04, 0xF3, 0x20, 0xFA, 0x05, 0xF0, 0x01, 0xFA, 0x04, 0xF2, 0x40, 0xEA, 0x02, 0x00, 0x01, 0xF0, 0x00, 0x41, -+0x10, 0xEB, 0xD3, 0x70, 0x41, 0xF1, 0x00, 0x01, 0x5E, 0xEA, 0x43, 0x0E, 0x08, 0xBF, 0x20, 0xEA, 0xD3, 0x70, 0x70, 0xBD, -+0xC4, 0xF1, 0x20, 0x05, 0x00, 0xFA, 0x05, 0xF2, 0x4E, 0xEA, 0x02, 0x0E, 0x20, 0xFA, 0x04, 0xF3, 0x01, 0xFA, 0x05, 0xF2, -+0x43, 0xEA, 0x02, 0x03, 0x21, 0xFA, 0x04, 0xF0, 0x01, 0xF0, 0x00, 0x41, 0x21, 0xFA, 0x04, 0xF2, 0x20, 0xEA, 0x02, 0x00, -+0x00, 0xEB, 0xD3, 0x70, 0x5E, 0xEA, 0x43, 0x0E, 0x08, 0xBF, 0x20, 0xEA, 0xD3, 0x70, 0x70, 0xBD, 0x94, 0xF0, 0x00, 0x0F, -+0x0F, 0xD1, 0x01, 0xF0, 0x00, 0x46, 0x40, 0x00, 0x41, 0xEB, 0x01, 0x01, 0x11, 0xF4, 0x80, 0x1F, 0x08, 0xBF, 0x01, 0x3C, -+0xF7, 0xD0, 0x41, 0xEA, 0x06, 0x01, 0x95, 0xF0, 0x00, 0x0F, 0x18, 0xBF, 0x70, 0x47, 0x03, 0xF0, 0x00, 0x46, 0x52, 0x00, -+0x43, 0xEB, 0x03, 0x03, 0x13, 0xF4, 0x80, 0x1F, 0x08, 0xBF, 0x01, 0x3D, 0xF7, 0xD0, 0x43, 0xEA, 0x06, 0x03, 0x70, 0x47, -+0x94, 0xEA, 0x0C, 0x0F, 0x0C, 0xEA, 0x13, 0x55, 0x18, 0xBF, 0x95, 0xEA, 0x0C, 0x0F, 0x0C, 0xD0, 0x50, 0xEA, 0x41, 0x06, -+0x18, 0xBF, 0x52, 0xEA, 0x43, 0x06, 0xD1, 0xD1, 0x81, 0xEA, 0x03, 0x01, 0x01, 0xF0, 0x00, 0x41, 0x4F, 0xF0, 0x00, 0x00, -+0x70, 0xBD, 0x50, 0xEA, 0x41, 0x06, 0x06, 0xBF, 0x10, 0x46, 0x19, 0x46, 0x52, 0xEA, 0x43, 0x06, 0x19, 0xD0, 0x94, 0xEA, -+0x0C, 0x0F, 0x02, 0xD1, 0x50, 0xEA, 0x01, 0x36, 0x13, 0xD1, 0x95, 0xEA, 0x0C, 0x0F, 0x05, 0xD1, 0x52, 0xEA, 0x03, 0x36, -+0x1C, 0xBF, 0x10, 0x46, 0x19, 0x46, 0x0A, 0xD1, 0x81, 0xEA, 0x03, 0x01, 0x01, 0xF0, 0x00, 0x41, 0x41, 0xF0, 0xFE, 0x41, -+0x41, 0xF4, 0x70, 0x01, 0x4F, 0xF0, 0x00, 0x00, 0x70, 0xBD, 0x41, 0xF0, 0xFE, 0x41, 0x41, 0xF4, 0x78, 0x01, 0x70, 0xBD, -+0x70, 0xB5, 0x4F, 0xF0, 0xFF, 0x0C, 0x4C, 0xF4, 0xE0, 0x6C, 0x1C, 0xEA, 0x11, 0x54, 0x1D, 0xBF, 0x1C, 0xEA, 0x13, 0x55, -+0x94, 0xEA, 0x0C, 0x0F, 0x95, 0xEA, 0x0C, 0x0F, 0x00, 0xF0, 0xA7, 0xF8, 0xA4, 0xEB, 0x05, 0x04, 0x81, 0xEA, 0x03, 0x0E, -+0x52, 0xEA, 0x03, 0x35, 0x4F, 0xEA, 0x01, 0x31, 0x00, 0xF0, 0x88, 0x80, 0x4F, 0xEA, 0x03, 0x33, 0x4F, 0xF0, 0x80, 0x55, -+0x45, 0xEA, 0x13, 0x13, 0x43, 0xEA, 0x12, 0x63, 0x4F, 0xEA, 0x02, 0x22, 0x45, 0xEA, 0x11, 0x15, 0x45, 0xEA, 0x10, 0x65, -+0x4F, 0xEA, 0x00, 0x26, 0x0E, 0xF0, 0x00, 0x41, 0x9D, 0x42, 0x08, 0xBF, 0x96, 0x42, 0x44, 0xF1, 0xFD, 0x04, 0x04, 0xF5, -+0x40, 0x74, 0x02, 0xD2, 0x5B, 0x08, 0x4F, 0xEA, 0x32, 0x02, 0xB6, 0x1A, 0x65, 0xEB, 0x03, 0x05, 0x5B, 0x08, 0x4F, 0xEA, -+0x32, 0x02, 0x4F, 0xF4, 0x80, 0x10, 0x4F, 0xF4, 0x00, 0x2C, 0xB6, 0xEB, 0x02, 0x0E, 0x75, 0xEB, 0x03, 0x0E, 0x22, 0xBF, -+0xB6, 0x1A, 0x75, 0x46, 0x40, 0xEA, 0x0C, 0x00, 0x5B, 0x08, 0x4F, 0xEA, 0x32, 0x02, 0xB6, 0xEB, 0x02, 0x0E, 0x75, 0xEB, -+0x03, 0x0E, 0x22, 0xBF, 0xB6, 0x1A, 0x75, 0x46, 0x40, 0xEA, 0x5C, 0x00, 0x5B, 0x08, 0x4F, 0xEA, 0x32, 0x02, 0xB6, 0xEB, -+0x02, 0x0E, 0x75, 0xEB, 0x03, 0x0E, 0x22, 0xBF, 0xB6, 0x1A, 0x75, 0x46, 0x40, 0xEA, 0x9C, 0x00, 0x5B, 0x08, 0x4F, 0xEA, -+0x32, 0x02, 0xB6, 0xEB, 0x02, 0x0E, 0x75, 0xEB, 0x03, 0x0E, 0x22, 0xBF, 0xB6, 0x1A, 0x75, 0x46, 0x40, 0xEA, 0xDC, 0x00, -+0x55, 0xEA, 0x06, 0x0E, 0x18, 0xD0, 0x4F, 0xEA, 0x05, 0x15, 0x45, 0xEA, 0x16, 0x75, 0x4F, 0xEA, 0x06, 0x16, 0x4F, 0xEA, -+0xC3, 0x03, 0x43, 0xEA, 0x52, 0x73, 0x4F, 0xEA, 0xC2, 0x02, 0x5F, 0xEA, 0x1C, 0x1C, 0xC0, 0xD1, 0x11, 0xF4, 0x80, 0x1F, -+0x0B, 0xD1, 0x41, 0xEA, 0x00, 0x01, 0x4F, 0xF0, 0x00, 0x00, 0x4F, 0xF0, 0x00, 0x4C, 0xB6, 0xE7, 0x11, 0xF4, 0x80, 0x1F, -+0x04, 0xBF, 0x01, 0x43, 0x00, 0x20, 0xB4, 0xF1, 0xFD, 0x0C, 0x88, 0xBF, 0xBC, 0xF5, 0xE0, 0x6F, 0x3F, 0xF6, 0xAF, 0xAE, -+0xB5, 0xEB, 0x03, 0x0C, 0x04, 0xBF, 0xB6, 0xEB, 0x02, 0x0C, 0x5F, 0xEA, 0x50, 0x0C, 0x50, 0xF1, 0x00, 0x00, 0x41, 0xEB, -+0x04, 0x51, 0x70, 0xBD, 0x0E, 0xF0, 0x00, 0x4E, 0x4E, 0xEA, 0x11, 0x31, 0x14, 0xEB, 0x5C, 0x04, 0xC2, 0xBF, 0xD4, 0xEB, -+0x0C, 0x05, 0x41, 0xEA, 0x04, 0x51, 0x70, 0xBD, 0x41, 0xF4, 0x80, 0x11, 0x4F, 0xF0, 0x00, 0x0E, 0x01, 0x3C, 0x90, 0xE6, -+0x45, 0xEA, 0x06, 0x0E, 0x8D, 0xE6, 0x0C, 0xEA, 0x13, 0x55, 0x94, 0xEA, 0x0C, 0x0F, 0x08, 0xBF, 0x95, 0xEA, 0x0C, 0x0F, -+0x3F, 0xF4, 0x3B, 0xAF, 0x94, 0xEA, 0x0C, 0x0F, 0x0A, 0xD1, 0x50, 0xEA, 0x01, 0x34, 0x7F, 0xF4, 0x34, 0xAF, 0x95, 0xEA, -+0x0C, 0x0F, 0x7F, 0xF4, 0x25, 0xAF, 0x10, 0x46, 0x19, 0x46, 0x2C, 0xE7, 0x95, 0xEA, 0x0C, 0x0F, 0x06, 0xD1, 0x52, 0xEA, -+0x03, 0x35, 0x3F, 0xF4, 0xFD, 0xAE, 0x10, 0x46, 0x19, 0x46, 0x22, 0xE7, 0x50, 0xEA, 0x41, 0x06, 0x18, 0xBF, 0x52, 0xEA, -+0x43, 0x06, 0x7F, 0xF4, 0xC5, 0xAE, 0x50, 0xEA, 0x41, 0x04, 0x7F, 0xF4, 0x0D, 0xAF, 0x52, 0xEA, 0x43, 0x05, 0x7F, 0xF4, -+0xEB, 0xAE, 0x12, 0xE7, 0x4F, 0xF0, 0xFF, 0x3C, 0x06, 0xE0, 0x00, 0xBF, 0x4F, 0xF0, 0x01, 0x0C, 0x02, 0xE0, 0x00, 0xBF, -+0x4F, 0xF0, 0x01, 0x0C, 0x4D, 0xF8, 0x04, 0xCD, 0x4F, 0xEA, 0x41, 0x0C, 0x7F, 0xEA, 0x6C, 0x5C, 0x4F, 0xEA, 0x43, 0x0C, -+0x18, 0xBF, 0x7F, 0xEA, 0x6C, 0x5C, 0x1B, 0xD0, 0x01, 0xB0, 0x50, 0xEA, 0x41, 0x0C, 0x0C, 0xBF, 0x52, 0xEA, 0x43, 0x0C, -+0x91, 0xEA, 0x03, 0x0F, 0x02, 0xBF, 0x90, 0xEA, 0x02, 0x0F, 0x00, 0x20, 0x70, 0x47, 0x10, 0xF1, 0x00, 0x0F, 0x91, 0xEA, -+0x03, 0x0F, 0x58, 0xBF, 0x99, 0x42, 0x08, 0xBF, 0x90, 0x42, 0x2C, 0xBF, 0xD8, 0x17, 0x6F, 0xEA, 0xE3, 0x70, 0x40, 0xF0, -+0x01, 0x00, 0x70, 0x47, 0x4F, 0xEA, 0x41, 0x0C, 0x7F, 0xEA, 0x6C, 0x5C, 0x02, 0xD1, 0x50, 0xEA, 0x01, 0x3C, 0x07, 0xD1, -+0x4F, 0xEA, 0x43, 0x0C, 0x7F, 0xEA, 0x6C, 0x5C, 0xD6, 0xD1, 0x52, 0xEA, 0x03, 0x3C, 0xD3, 0xD0, 0x5D, 0xF8, 0x04, 0x0B, -+0x70, 0x47, 0x00, 0xBF, 0x84, 0x46, 0x10, 0x46, 0x62, 0x46, 0x8C, 0x46, 0x19, 0x46, 0x63, 0x46, 0x00, 0xE0, 0x00, 0xBF, -+0x01, 0xB5, 0xFF, 0xF7, 0xB7, 0xFF, 0x00, 0x28, 0x48, 0xBF, 0x10, 0xF1, 0x00, 0x0F, 0x01, 0xBD, 0x4D, 0xF8, 0x08, 0xED, -+0xFF, 0xF7, 0xF4, 0xFF, 0x0C, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x5D, 0xF8, 0x08, 0xFB, 0x00, 0xBF, 0x4D, 0xF8, 0x08, 0xED, -+0xFF, 0xF7, 0xEA, 0xFF, 0x34, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x5D, 0xF8, 0x08, 0xFB, 0x00, 0xBF, 0x4D, 0xF8, 0x08, 0xED, -+0xFF, 0xF7, 0xE0, 0xFF, 0x94, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x5D, 0xF8, 0x08, 0xFB, 0x00, 0xBF, 0x4D, 0xF8, 0x08, 0xED, -+0xFF, 0xF7, 0xCE, 0xFF, 0x94, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x5D, 0xF8, 0x08, 0xFB, 0x00, 0xBF, 0x4D, 0xF8, 0x08, 0xED, -+0xFF, 0xF7, 0xC4, 0xFF, 0x34, 0xBF, 0x01, 0x20, 0x00, 0x20, 0x5D, 0xF8, 0x08, 0xFB, 0x00, 0xBF, 0x4A, 0x00, 0x11, 0xD2, -+0x12, 0xF5, 0x00, 0x12, 0x11, 0xD2, 0x0D, 0xD5, 0x6F, 0xF4, 0x78, 0x73, 0xB3, 0xEB, 0x62, 0x52, 0x0E, 0xD4, 0x4F, 0xEA, -+0xC1, 0x23, 0x43, 0xF0, 0x00, 0x43, 0x43, 0xEA, 0x50, 0x53, 0x23, 0xFA, 0x02, 0xF0, 0x70, 0x47, 0x4F, 0xF0, 0x00, 0x00, -+0x70, 0x47, 0x50, 0xEA, 0x01, 0x30, 0x02, 0xD1, 0x4F, 0xF0, 0xFF, 0x30, 0x70, 0x47, 0x4F, 0xF0, 0x00, 0x00, 0x70, 0x47, -+0x4F, 0xEA, 0x41, 0x02, 0xB2, 0xF1, 0xE0, 0x43, 0x24, 0xBF, 0xB3, 0xF5, 0x00, 0x1C, 0xDC, 0xF1, 0xFE, 0x5C, 0x0D, 0xD9, -+0x01, 0xF0, 0x00, 0x4C, 0x4F, 0xEA, 0xC0, 0x02, 0x4C, 0xEA, 0x50, 0x70, 0xB2, 0xF1, 0x00, 0x4F, 0x40, 0xEB, 0x83, 0x00, -+0x08, 0xBF, 0x20, 0xF0, 0x01, 0x00, 0x70, 0x47, 0x11, 0xF0, 0x80, 0x4F, 0x21, 0xD1, 0x13, 0xF1, 0x38, 0x72, 0xBC, 0xBF, -+0x01, 0xF0, 0x00, 0x40, 0x70, 0x47, 0x41, 0xF4, 0x80, 0x11, 0x4F, 0xEA, 0x52, 0x52, 0xC2, 0xF1, 0x18, 0x02, 0xC2, 0xF1, -+0x20, 0x0C, 0x10, 0xFA, 0x0C, 0xF3, 0x20, 0xFA, 0x02, 0xF0, 0x18, 0xBF, 0x40, 0xF0, 0x01, 0x00, 0x4F, 0xEA, 0xC1, 0x23, -+0x4F, 0xEA, 0xD3, 0x23, 0x03, 0xFA, 0x0C, 0xFC, 0x40, 0xEA, 0x0C, 0x00, 0x23, 0xFA, 0x02, 0xF3, 0x4F, 0xEA, 0x43, 0x03, -+0xCC, 0xE7, 0x7F, 0xEA, 0x62, 0x53, 0x07, 0xD1, 0x50, 0xEA, 0x01, 0x33, 0x1E, 0xBF, 0x4F, 0xF0, 0xFE, 0x40, 0x40, 0xF4, -+0x40, 0x00, 0x70, 0x47, 0x01, 0xF0, 0x00, 0x40, 0x40, 0xF0, 0xFE, 0x40, 0x40, 0xF4, 0x00, 0x00, 0x70, 0x47, 0x00, 0xBF, -+0x53, 0xB9, 0x4A, 0xB9, 0x00, 0x29, 0x08, 0xBF, 0x00, 0x28, 0x1C, 0xBF, 0x4F, 0xF0, 0xFF, 0x31, 0x4F, 0xF0, 0xFF, 0x30, -+0x00, 0xF0, 0x6C, 0xB9, 0xAD, 0xF1, 0x08, 0x0C, 0x6D, 0xE9, 0x04, 0xCE, 0x00, 0xF0, 0x06, 0xF8, 0xDD, 0xF8, 0x04, 0xE0, -+0xDD, 0xE9, 0x02, 0x23, 0x04, 0xB0, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x47, 0x08, 0x9E, 0x0D, 0x46, 0x04, 0x46, 0x8E, 0x46, -+0x00, 0x2B, 0x40, 0xF0, 0x82, 0x80, 0x8A, 0x42, 0x17, 0x46, 0x46, 0xD9, 0xB2, 0xFA, 0x82, 0xF2, 0x4A, 0xB1, 0xC2, 0xF1, -+0x20, 0x01, 0x05, 0xFA, 0x02, 0xF3, 0x20, 0xFA, 0x01, 0xF1, 0x97, 0x40, 0x41, 0xEA, 0x03, 0x0E, 0x94, 0x40, 0x4F, 0xEA, -+0x17, 0x48, 0x23, 0x0C, 0xBE, 0xFB, 0xF8, 0xFC, 0xB9, 0xB2, 0x08, 0xFB, 0x1C, 0xEE, 0x43, 0xEA, 0x0E, 0x43, 0x0C, 0xFB, -+0x01, 0xF0, 0x98, 0x42, 0x0A, 0xD9, 0xFB, 0x18, 0x0C, 0xF1, 0xFF, 0x35, 0x80, 0xF0, 0x16, 0x81, 0x98, 0x42, 0x40, 0xF2, -+0x13, 0x81, 0xAC, 0xF1, 0x02, 0x0C, 0x3B, 0x44, 0x1B, 0x1A, 0xA4, 0xB2, 0xB3, 0xFB, 0xF8, 0xF0, 0x08, 0xFB, 0x10, 0x33, -+0x44, 0xEA, 0x03, 0x44, 0x00, 0xFB, 0x01, 0xF1, 0xA1, 0x42, 0x09, 0xD9, 0x3C, 0x19, 0x00, 0xF1, 0xFF, 0x33, 0x80, 0xF0, -+0x01, 0x81, 0xA1, 0x42, 0x40, 0xF2, 0xFE, 0x80, 0x02, 0x38, 0x3C, 0x44, 0x64, 0x1A, 0x40, 0xEA, 0x0C, 0x40, 0x00, 0x21, -+0x1E, 0xB1, 0xD4, 0x40, 0x00, 0x23, 0xC6, 0xE9, 0x00, 0x43, 0xBD, 0xE8, 0xF0, 0x87, 0x02, 0xB9, 0xFF, 0xDE, 0xB2, 0xFA, -+0x82, 0xF2, 0x00, 0x2A, 0x4F, 0xD1, 0xCB, 0x1B, 0x4F, 0xEA, 0x17, 0x4E, 0x1F, 0xFA, 0x87, 0xF8, 0x01, 0x21, 0xB3, 0xFB, -+0xFE, 0xFC, 0x25, 0x0C, 0x0E, 0xFB, 0x1C, 0x33, 0x45, 0xEA, 0x03, 0x45, 0x08, 0xFB, 0x0C, 0xF3, 0xAB, 0x42, 0x07, 0xD9, -+0x7D, 0x19, 0x0C, 0xF1, 0xFF, 0x30, 0x02, 0xD2, 0xAB, 0x42, 0x00, 0xF2, 0xE7, 0x80, 0x84, 0x46, 0xED, 0x1A, 0xA3, 0xB2, -+0xB5, 0xFB, 0xFE, 0xF0, 0x0E, 0xFB, 0x10, 0x55, 0x43, 0xEA, 0x05, 0x44, 0x08, 0xFB, 0x00, 0xF8, 0xA0, 0x45, 0x07, 0xD9, -+0x3C, 0x19, 0x00, 0xF1, 0xFF, 0x33, 0x02, 0xD2, 0xA0, 0x45, 0x00, 0xF2, 0xD7, 0x80, 0x18, 0x46, 0xA4, 0xEB, 0x08, 0x04, -+0x40, 0xEA, 0x0C, 0x40, 0xC0, 0xE7, 0x8B, 0x42, 0x08, 0xD9, 0x00, 0x2E, 0x00, 0xF0, 0xAF, 0x80, 0x00, 0x21, 0xC6, 0xE9, -+0x00, 0x05, 0x08, 0x46, 0xBD, 0xE8, 0xF0, 0x87, 0xB3, 0xFA, 0x83, 0xF1, 0x00, 0x29, 0x4B, 0xD1, 0xAB, 0x42, 0x02, 0xD3, -+0x82, 0x42, 0x00, 0xF2, 0xB7, 0x80, 0x84, 0x1A, 0x65, 0xEB, 0x03, 0x03, 0x01, 0x20, 0x9E, 0x46, 0x00, 0x2E, 0xAA, 0xD0, -+0xC6, 0xE9, 0x00, 0x4E, 0xA7, 0xE7, 0xC2, 0xF1, 0x20, 0x0C, 0x01, 0xFA, 0x02, 0xF3, 0x97, 0x40, 0x20, 0xFA, 0x0C, 0xF0, -+0x4F, 0xEA, 0x17, 0x4E, 0x21, 0xFA, 0x0C, 0xFC, 0x18, 0x43, 0xBC, 0xFB, 0xFE, 0xF1, 0x05, 0x0C, 0x0E, 0xFB, 0x11, 0xCC, -+0x1F, 0xFA, 0x87, 0xF8, 0x45, 0xEA, 0x0C, 0x45, 0x01, 0xFB, 0x08, 0xF3, 0xAB, 0x42, 0x04, 0xFA, 0x02, 0xF4, 0x09, 0xD9, -+0x7D, 0x19, 0x01, 0xF1, 0xFF, 0x3C, 0x80, 0xF0, 0x8B, 0x80, 0xAB, 0x42, 0x40, 0xF2, 0x88, 0x80, 0x02, 0x39, 0x3D, 0x44, -+0xEB, 0x1A, 0x85, 0xB2, 0xB3, 0xFB, 0xFE, 0xF0, 0x0E, 0xFB, 0x10, 0x33, 0x45, 0xEA, 0x03, 0x45, 0x00, 0xFB, 0x08, 0xF3, -+0xAB, 0x42, 0x07, 0xD9, 0x7D, 0x19, 0x00, 0xF1, 0xFF, 0x3C, 0x71, 0xD2, 0xAB, 0x42, 0x6F, 0xD9, 0x02, 0x38, 0x3D, 0x44, -+0xEB, 0x1A, 0x40, 0xEA, 0x01, 0x41, 0x78, 0xE7, 0xC1, 0xF1, 0x20, 0x0C, 0x8B, 0x40, 0x22, 0xFA, 0x0C, 0xF7, 0x1F, 0x43, -+0x20, 0xFA, 0x0C, 0xF4, 0x05, 0xFA, 0x01, 0xF3, 0x4F, 0xEA, 0x17, 0x4E, 0x25, 0xFA, 0x0C, 0xF5, 0x1C, 0x43, 0x23, 0x0C, -+0xB5, 0xFB, 0xFE, 0xF9, 0x1F, 0xFA, 0x87, 0xF8, 0x0E, 0xFB, 0x19, 0x55, 0x43, 0xEA, 0x05, 0x45, 0x09, 0xFB, 0x08, 0xFA, -+0xAA, 0x45, 0x02, 0xFA, 0x01, 0xF2, 0x00, 0xFA, 0x01, 0xF3, 0x08, 0xD9, 0x7D, 0x19, 0x09, 0xF1, 0xFF, 0x30, 0x47, 0xD2, -+0xAA, 0x45, 0x45, 0xD9, 0xA9, 0xF1, 0x02, 0x09, 0x3D, 0x44, 0xA5, 0xEB, 0x0A, 0x05, 0xA4, 0xB2, 0xB5, 0xFB, 0xFE, 0xF0, -+0x0E, 0xFB, 0x10, 0x55, 0x44, 0xEA, 0x05, 0x44, 0x00, 0xFB, 0x08, 0xF8, 0xA0, 0x45, 0x07, 0xD9, 0x3C, 0x19, 0x00, 0xF1, -+0xFF, 0x35, 0x2D, 0xD2, 0xA0, 0x45, 0x2B, 0xD9, 0x02, 0x38, 0x3C, 0x44, 0x40, 0xEA, 0x09, 0x40, 0xA4, 0xEB, 0x08, 0x04, -+0xA0, 0xFB, 0x02, 0x89, 0x4C, 0x45, 0xC6, 0x46, 0x4D, 0x46, 0x19, 0xD3, 0x16, 0xD0, 0x5E, 0xB1, 0xB3, 0xEB, 0x0E, 0x02, -+0x64, 0xEB, 0x05, 0x04, 0x04, 0xFA, 0x0C, 0xFC, 0xCA, 0x40, 0x4C, 0xEA, 0x02, 0x02, 0xCC, 0x40, 0xC6, 0xE9, 0x00, 0x24, -+0x00, 0x21, 0xBD, 0xE8, 0xF0, 0x87, 0x31, 0x46, 0x30, 0x46, 0x0E, 0xE7, 0xAC, 0x46, 0xED, 0xE6, 0x18, 0x46, 0x01, 0xE7, -+0x43, 0x45, 0xE6, 0xD2, 0xB8, 0xEB, 0x02, 0x0E, 0x69, 0xEB, 0x07, 0x05, 0x01, 0x38, 0xE0, 0xE7, 0x28, 0x46, 0xD3, 0xE7, -+0x60, 0x46, 0x8F, 0xE7, 0x81, 0x46, 0xBA, 0xE7, 0x61, 0x46, 0x77, 0xE7, 0x08, 0x46, 0x4B, 0xE7, 0xAC, 0xF1, 0x02, 0x0C, -+0x3D, 0x44, 0x15, 0xE7, 0x02, 0x38, 0x3C, 0x44, 0x26, 0xE7, 0x00, 0xBF, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x28, 0xB8, 0xBF, -+0x40, 0x42, 0x70, 0x47, 0x03, 0x2A, 0x70, 0xB4, 0x12, 0xD9, 0x40, 0xEA, 0x01, 0x05, 0xAD, 0x07, 0x04, 0x46, 0x0B, 0x46, -+0x1E, 0xD1, 0x19, 0x46, 0x20, 0x46, 0x53, 0xF8, 0x04, 0x5B, 0x54, 0xF8, 0x04, 0x6B, 0xAE, 0x42, 0x16, 0xD1, 0x04, 0x3A, -+0x03, 0x2A, 0x20, 0x46, 0x19, 0x46, 0xF2, 0xD8, 0x56, 0x1E, 0xA2, 0xB1, 0x01, 0x39, 0x44, 0x1E, 0x01, 0xE0, 0xC3, 0x18, -+0x0C, 0xD0, 0x14, 0xF8, 0x01, 0x5F, 0x11, 0xF8, 0x01, 0x2F, 0x95, 0x42, 0xA6, 0xEB, 0x04, 0x03, 0xF5, 0xD0, 0xA8, 0x1A, -+0x70, 0xBC, 0x70, 0x47, 0x56, 0x1E, 0xED, 0xE7, 0x18, 0x46, 0x70, 0xBC, 0x70, 0x47, 0x10, 0x46, 0xF6, 0xE7, 0x00, 0xBF, -+0x84, 0x46, 0x41, 0xEA, 0x00, 0x03, 0x13, 0xF0, 0x03, 0x03, 0x6D, 0xD1, 0x40, 0x3A, 0x41, 0xD3, 0x51, 0xF8, 0x04, 0x3B, -+0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, -+0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, -+0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, -+0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, -+0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, -+0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, -+0x40, 0xF8, 0x04, 0x3B, 0x40, 0x3A, 0xBD, 0xD2, 0x30, 0x32, 0x11, 0xD3, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, -+0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x51, 0xF8, 0x04, 0x3B, -+0x40, 0xF8, 0x04, 0x3B, 0x10, 0x3A, 0xED, 0xD2, 0x0C, 0x32, 0x05, 0xD3, 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, -+0x04, 0x3A, 0xF9, 0xD2, 0x04, 0x32, 0x08, 0xD0, 0xD2, 0x07, 0x1C, 0xBF, 0x11, 0xF8, 0x01, 0x3B, 0x00, 0xF8, 0x01, 0x3B, -+0x01, 0xD3, 0x0B, 0x88, 0x03, 0x80, 0x60, 0x46, 0x70, 0x47, 0x00, 0xBF, 0x08, 0x2A, 0x13, 0xD3, 0x8B, 0x07, 0x8D, 0xD0, -+0x10, 0xF0, 0x03, 0x03, 0x8A, 0xD0, 0xC3, 0xF1, 0x04, 0x03, 0xD2, 0x1A, 0xDB, 0x07, 0x1C, 0xBF, 0x11, 0xF8, 0x01, 0x3B, -+0x00, 0xF8, 0x01, 0x3B, 0x80, 0xD3, 0x31, 0xF8, 0x02, 0x3B, 0x20, 0xF8, 0x02, 0x3B, 0x7B, 0xE7, 0x04, 0x3A, 0xD9, 0xD3, -+0x01, 0x3A, 0x11, 0xF8, 0x01, 0x3B, 0x00, 0xF8, 0x01, 0x3B, 0xF9, 0xD2, 0x0B, 0x78, 0x03, 0x70, 0x4B, 0x78, 0x43, 0x70, -+0x8B, 0x78, 0x83, 0x70, 0x60, 0x46, 0x70, 0x47, 0x88, 0x42, 0xF0, 0xB4, 0x0D, 0xD9, 0x8B, 0x18, 0x83, 0x42, 0x0A, 0xD9, -+0x84, 0x18, 0x32, 0xB1, 0x22, 0x46, 0x13, 0xF8, 0x01, 0x4D, 0x02, 0xF8, 0x01, 0x4D, 0x99, 0x42, 0xF9, 0xD1, 0xF0, 0xBC, -+0x70, 0x47, 0x0F, 0x2A, 0x0E, 0xD8, 0x03, 0x46, 0x54, 0x1E, 0x00, 0x2A, 0xF7, 0xD0, 0x01, 0x34, 0x0C, 0x44, 0x01, 0x3B, -+0x11, 0xF8, 0x01, 0x2B, 0x03, 0xF8, 0x01, 0x2F, 0xA1, 0x42, 0xF9, 0xD1, 0xF0, 0xBC, 0x70, 0x47, 0x40, 0xEA, 0x01, 0x03, -+0x9B, 0x07, 0x3F, 0xD1, 0xA2, 0xF1, 0x10, 0x03, 0x23, 0xF0, 0x0F, 0x04, 0x01, 0xF1, 0x20, 0x07, 0x27, 0x44, 0x1B, 0x09, -+0x01, 0xF1, 0x10, 0x04, 0x00, 0xF1, 0x10, 0x05, 0x54, 0xF8, 0x10, 0x6C, 0x45, 0xF8, 0x10, 0x6C, 0x54, 0xF8, 0x0C, 0x6C, -+0x45, 0xF8, 0x0C, 0x6C, 0x54, 0xF8, 0x08, 0x6C, 0x45, 0xF8, 0x08, 0x6C, 0x54, 0xF8, 0x04, 0x6C, 0x45, 0xF8, 0x04, 0x6C, -+0x10, 0x34, 0xBC, 0x42, 0x05, 0xF1, 0x10, 0x05, 0xEA, 0xD1, 0x01, 0x33, 0x12, 0xF0, 0x0C, 0x0F, 0x01, 0xEB, 0x03, 0x11, -+0x02, 0xF0, 0x0F, 0x04, 0x00, 0xEB, 0x03, 0x13, 0x17, 0xD0, 0x04, 0x3C, 0x24, 0xF0, 0x03, 0x0C, 0xA5, 0x08, 0x9C, 0x44, -+0x1C, 0x1F, 0x0E, 0x46, 0x56, 0xF8, 0x04, 0x7B, 0x44, 0xF8, 0x04, 0x7F, 0x64, 0x45, 0xF9, 0xD1, 0x6C, 0x1C, 0x03, 0xEB, -+0x84, 0x03, 0x01, 0xEB, 0x84, 0x01, 0x02, 0xF0, 0x03, 0x02, 0xAD, 0xE7, 0x54, 0x1E, 0x03, 0x46, 0xAD, 0xE7, 0x22, 0x46, -+0xA8, 0xE7, 0x00, 0xBF, 0x0B, 0x4B, 0x0C, 0x48, 0x19, 0x68, 0xD1, 0xE9, 0x2A, 0x23, 0x10, 0xB4, 0x0A, 0x4C, 0x00, 0xFB, -+0x02, 0xF0, 0x04, 0xFB, 0x03, 0x00, 0xA2, 0xFB, 0x04, 0x34, 0x04, 0x44, 0x5A, 0x1C, 0x44, 0xF1, 0x00, 0x00, 0xC1, 0xE9, -+0x2A, 0x20, 0x10, 0xBC, 0x20, 0xF0, 0x00, 0x40, 0x70, 0x47, 0x00, 0xBF, 0x80, 0x01, 0x17, 0x00, 0x2D, 0xF4, 0x51, 0x58, -+0x2D, 0x7F, 0x95, 0x4C, 0x11, 0xF0, 0xFF, 0x01, 0x03, 0x46, 0x44, 0xD0, 0x82, 0x07, 0x32, 0xD1, 0x70, 0xB4, 0x04, 0x68, -+0x41, 0xEA, 0x01, 0x26, 0x46, 0xEA, 0x06, 0x46, 0x86, 0xEA, 0x04, 0x05, 0xA5, 0xF1, 0x01, 0x33, 0xA4, 0xF1, 0x01, 0x32, -+0x23, 0xEA, 0x05, 0x03, 0x22, 0xEA, 0x04, 0x02, 0x13, 0x43, 0x13, 0xF0, 0x80, 0x3F, 0x0F, 0xD1, 0x50, 0xF8, 0x04, 0x4F, -+0x84, 0xEA, 0x06, 0x05, 0xA5, 0xF1, 0x01, 0x32, 0xA4, 0xF1, 0x01, 0x33, 0x22, 0xEA, 0x05, 0x02, 0x23, 0xEA, 0x04, 0x03, -+0x13, 0x43, 0x13, 0xF0, 0x80, 0x3F, 0xEF, 0xD0, 0x03, 0x78, 0x23, 0xB9, 0x36, 0xE0, 0x10, 0xF8, 0x01, 0x3F, 0x00, 0x2B, -+0x32, 0xD0, 0x99, 0x42, 0xF9, 0xD1, 0x30, 0xE0, 0x8A, 0x42, 0x11, 0xD0, 0x9A, 0x07, 0x18, 0x46, 0xCC, 0xD0, 0x18, 0x46, -+0x13, 0xF8, 0x01, 0x2B, 0x00, 0x2A, 0xF5, 0xD1, 0x10, 0x46, 0x70, 0x47, 0x99, 0x07, 0x18, 0x46, 0x07, 0xD0, 0x18, 0x46, -+0x01, 0x33, 0x02, 0x78, 0x00, 0x2A, 0xF7, 0xD1, 0x70, 0x47, 0x82, 0x07, 0xF7, 0xD1, 0x02, 0x68, 0xA2, 0xF1, 0x01, 0x33, -+0x23, 0xEA, 0x02, 0x03, 0x13, 0xF0, 0x80, 0x3F, 0x08, 0xD1, 0x50, 0xF8, 0x04, 0x2F, 0xA2, 0xF1, 0x01, 0x33, 0x23, 0xEA, -+0x02, 0x03, 0x13, 0xF0, 0x80, 0x3F, 0xF6, 0xD0, 0x03, 0x78, 0x00, 0x2B, 0xE8, 0xD0, 0x10, 0xF8, 0x01, 0x3F, 0x00, 0x2B, -+0xFB, 0xD1, 0x70, 0x47, 0x18, 0x46, 0x70, 0xBC, 0x70, 0x47, 0x00, 0xBF, 0x80, 0xEA, 0x01, 0x02, 0x84, 0x46, 0x12, 0xF0, -+0x03, 0x0F, 0x4F, 0xD1, 0x11, 0xF0, 0x03, 0x0F, 0x32, 0xD1, 0x4D, 0xF8, 0x04, 0x4D, 0x11, 0xF0, 0x04, 0x0F, 0x51, 0xF8, -+0x04, 0x3B, 0x0B, 0xD0, 0xA3, 0xF1, 0x01, 0x32, 0x9A, 0x43, 0x12, 0xF0, 0x80, 0x3F, 0x04, 0xBF, 0x4C, 0xF8, 0x04, 0x3B, -+0x51, 0xF8, 0x04, 0x3B, 0x16, 0xD1, 0x00, 0xBF, 0x51, 0xF8, 0x04, 0x4B, 0xA3, 0xF1, 0x01, 0x32, 0x9A, 0x43, 0x12, 0xF0, -+0x80, 0x3F, 0xA4, 0xF1, 0x01, 0x32, 0x0B, 0xD1, 0x4C, 0xF8, 0x04, 0x3B, 0xA2, 0x43, 0x12, 0xF0, 0x80, 0x3F, 0x04, 0xBF, -+0x51, 0xF8, 0x04, 0x3B, 0x4C, 0xF8, 0x04, 0x4B, 0xEA, 0xD0, 0x23, 0x46, 0x0C, 0xF8, 0x01, 0x3B, 0x13, 0xF0, 0xFF, 0x0F, -+0x4F, 0xEA, 0x33, 0x23, 0xF8, 0xD1, 0x5D, 0xF8, 0x04, 0x4B, 0x70, 0x47, 0x11, 0xF0, 0x01, 0x0F, 0x06, 0xD0, 0x11, 0xF8, -+0x01, 0x2B, 0x0C, 0xF8, 0x01, 0x2B, 0x00, 0x2A, 0x08, 0xBF, 0x70, 0x47, 0x11, 0xF0, 0x02, 0x0F, 0xBF, 0xD0, 0x31, 0xF8, -+0x02, 0x2B, 0x12, 0xF0, 0xFF, 0x0F, 0x16, 0xBF, 0x2C, 0xF8, 0x02, 0x2B, 0x8C, 0xF8, 0x00, 0x20, 0x12, 0xF4, 0x7F, 0x4F, -+0xB3, 0xD1, 0x70, 0x47, 0x11, 0xF8, 0x01, 0x2B, 0x0C, 0xF8, 0x01, 0x2B, 0x00, 0x2A, 0xF9, 0xD1, 0x70, 0x47, 0x00, 0xBF, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xF8, 0x00, 0xF0, -+0x6D, 0xE9, 0x02, 0x45, 0x20, 0xF0, 0x07, 0x01, 0x6F, 0xF0, 0x00, 0x0C, 0x10, 0xF0, 0x07, 0x04, 0x91, 0xF8, 0x20, 0xF0, -+0x40, 0xF0, 0x49, 0x80, 0x4F, 0xF0, 0x00, 0x04, 0x6F, 0xF0, 0x07, 0x00, 0xD1, 0xE9, 0x00, 0x23, 0x91, 0xF8, 0x40, 0xF0, -+0x00, 0xF1, 0x08, 0x00, 0x82, 0xFA, 0x4C, 0xF2, 0xA4, 0xFA, 0x8C, 0xF2, 0x83, 0xFA, 0x4C, 0xF3, 0xA2, 0xFA, 0x8C, 0xF3, -+0x4B, 0xBB, 0xD1, 0xE9, 0x02, 0x23, 0x82, 0xFA, 0x4C, 0xF2, 0x00, 0xF1, 0x08, 0x00, 0xA4, 0xFA, 0x8C, 0xF2, 0x83, 0xFA, -+0x4C, 0xF3, 0xA2, 0xFA, 0x8C, 0xF3, 0xE3, 0xB9, 0xD1, 0xE9, 0x04, 0x23, 0x82, 0xFA, 0x4C, 0xF2, 0x00, 0xF1, 0x08, 0x00, -+0xA4, 0xFA, 0x8C, 0xF2, 0x83, 0xFA, 0x4C, 0xF3, 0xA2, 0xFA, 0x8C, 0xF3, 0x7B, 0xB9, 0xD1, 0xE9, 0x06, 0x23, 0x01, 0xF1, -+0x20, 0x01, 0x82, 0xFA, 0x4C, 0xF2, 0x00, 0xF1, 0x08, 0x00, 0xA4, 0xFA, 0x8C, 0xF2, 0x83, 0xFA, 0x4C, 0xF3, 0xA2, 0xFA, -+0x8C, 0xF3, 0x00, 0x2B, 0xC6, 0xD0, 0x00, 0x2A, 0x04, 0xBF, 0x04, 0x30, 0x1A, 0x46, 0x12, 0xBA, 0xB2, 0xFA, 0x82, 0xF2, -+0xFD, 0xE8, 0x02, 0x45, 0x00, 0xEB, 0xD2, 0x00, 0x70, 0x47, 0xD1, 0xE9, 0x00, 0x23, 0x04, 0xF0, 0x03, 0x05, 0xC4, 0xF1, -+0x00, 0x00, 0x4F, 0xEA, 0xC5, 0x05, 0x14, 0xF0, 0x04, 0x0F, 0x91, 0xF8, 0x40, 0xF0, 0x0C, 0xFA, 0x05, 0xF5, 0x62, 0xEA, -+0x05, 0x02, 0x1C, 0xBF, 0x63, 0xEA, 0x05, 0x03, 0x62, 0x46, 0x4F, 0xF0, 0x00, 0x04, 0xA9, 0xE7, 0x9A, 0xB3, 0xF0, 0xB4, -+0x40, 0xEA, 0x01, 0x05, 0xAD, 0x07, 0x04, 0x46, 0x03, 0x46, 0x08, 0x46, 0x28, 0xD0, 0x20, 0x78, 0x0E, 0x78, 0x86, 0x42, -+0x29, 0xD1, 0x01, 0x2A, 0x2A, 0xD0, 0x25, 0x46, 0x50, 0xB1, 0x15, 0xF8, 0x01, 0x0F, 0x11, 0xF8, 0x01, 0x6F, 0xEB, 0x43, -+0xB0, 0x42, 0x13, 0x44, 0x1D, 0xD1, 0xE3, 0x18, 0xF4, 0xD1, 0x18, 0x46, 0xF0, 0xBC, 0x70, 0x47, 0x07, 0x68, 0x1C, 0x46, -+0x53, 0xF8, 0x04, 0x5B, 0xA5, 0xF1, 0x01, 0x36, 0xBD, 0x42, 0x01, 0x46, 0x26, 0xEA, 0x05, 0x06, 0x00, 0xF1, 0x04, 0x00, -+0xDD, 0xD1, 0x04, 0x3A, 0x1C, 0x46, 0x01, 0x46, 0x0A, 0xD0, 0x16, 0xF0, 0x80, 0x3F, 0x07, 0xD1, 0x03, 0x2A, 0xE9, 0xD8, -+0xD3, 0xE7, 0x10, 0x46, 0x70, 0x47, 0x80, 0x1B, 0xF0, 0xBC, 0x70, 0x47, 0x00, 0x20, 0xF0, 0xBC, 0x70, 0x47, 0x00, 0xBF, -+0x6D, 0x65, 0x6D, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x6C, 0x61, 0x70, 0x73, 0x3A, 0x20, 0x73, 0x74, 0x6B, 0x5F, 0x73, 0x74, -+0x61, 0x72, 0x74, 0x3D, 0x25, 0x78, 0x2C, 0x20, 0x62, 0x73, 0x73, 0x5F, 0x65, 0x6E, 0x64, 0x3D, 0x25, 0x78, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x6D, 0x65, 0x6D, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x6C, 0x61, 0x70, 0x73, 0x3A, 0x20, 0x73, 0x74, -+0x6B, 0x5F, 0x65, 0x6E, 0x64, 0x3D, 0x25, 0x78, 0x2C, 0x20, 0x68, 0x6F, 0x73, 0x74, 0x5F, 0x62, 0x61, 0x73, 0x65, 0x3D, -+0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x68, 0x6F, 0x73, 0x74, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x25, 0x64, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x77, 0x61, 0x6B, 0x65, 0x75, 0x70, 0x21, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x77, 0x69, 0x66, 0x69, -+0x6D, 0x61, 0x69, 0x6E, 0x21, 0x0D, 0x0A, 0x00, 0x10, 0x14, 0x08, 0x12, 0x3C, 0x00, 0x8A, 0x12, 0x07, 0x12, 0x0C, 0x13, -+0x08, 0x12, 0xC7, 0x11, 0x10, 0x14, 0x08, 0x12, 0x3C, 0x00, 0x8A, 0x12, 0x07, 0x12, 0x0C, 0x13, 0x08, 0x12, 0x45, 0x11, -+0x08, 0x12, 0x04, 0x11, 0x78, 0x00, 0x8A, 0x12, 0x07, 0x12, 0x86, 0x11, 0x04, 0x11, 0x03, 0x11, 0x08, 0x12, 0x04, 0x11, -+0x78, 0x00, 0x8A, 0x12, 0x07, 0x12, 0x86, 0x11, 0x04, 0x11, 0xC2, 0x10, 0x08, 0x12, 0x04, 0x11, 0x78, 0x00, 0x8A, 0x12, -+0x07, 0x12, 0xC3, 0x10, 0x04, 0x11, 0xC2, 0x10, 0x04, 0x11, 0x04, 0x11, 0x78, 0x00, 0x8A, 0x12, 0x86, 0x11, 0xC3, 0x10, -+0x04, 0x11, 0xC2, 0x10, 0x04, 0x11, 0x04, 0x11, 0x78, 0x00, 0x8A, 0x12, 0x86, 0x11, 0xC3, 0x10, 0x04, 0x11, 0xC2, 0x10, -+0x04, 0x11, 0x04, 0x11, 0x78, 0x00, 0x8A, 0x12, 0x07, 0x12, 0xC3, 0x10, 0x04, 0x11, 0xC2, 0x10, 0x08, 0x12, 0x04, 0x11, -+0x78, 0x00, 0x8A, 0x12, 0x07, 0x12, 0x0C, 0x13, 0x08, 0x12, 0x03, 0x11, 0x04, 0x11, 0x04, 0x11, 0x78, 0x00, 0x8A, 0x12, -+0x07, 0x12, 0x86, 0x11, 0x04, 0x11, 0xC2, 0x10, 0x04, 0x11, 0x04, 0x11, 0x78, 0x00, 0x8A, 0x12, 0x8A, 0x12, 0x0C, 0x13, -+0x04, 0x11, 0x03, 0x11, 0x04, 0x11, 0x04, 0x11, 0x78, 0x00, 0x8A, 0x12, 0x8A, 0x12, 0x86, 0x11, 0x04, 0x11, 0x03, 0x11, -+0x9D, 0x87, 0x25, 0x73, 0x3A, 0x20, 0x62, 0x61, 0x6E, 0x64, 0x3D, 0x25, 0x64, 0x20, 0x66, 0x72, 0x65, 0x71, 0x3D, 0x25, -+0x64, 0x20, 0x66, 0x72, 0x65, 0x71, 0x31, 0x3D, 0x25, 0x64, 0x20, 0x63, 0x68, 0x61, 0x6E, 0x74, 0x79, 0x70, 0x65, 0x3D, -+0x25, 0x64, 0x20, 0x73, 0x78, 0x3D, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x63, 0x68, 0x61, 0x6E, 0x3A, -+0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x62, 0x61, 0x6E, 0x64, 0x20, -+0x25, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x62, 0x61, 0x6E, 0x64, 0x20, 0x3C, 0x20, 0x50, -+0x48, 0x59, 0x5F, 0x42, 0x41, 0x4E, 0x44, 0x5F, 0x4D, 0x41, 0x58, 0x00, 0x28, 0x6D, 0x64, 0x6D, 0x5F, 0x6D, 0x61, 0x6A, -+0x6F, 0x72, 0x5F, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x20, 0x2B, 0x20, -+0x32, 0x29, 0x20, 0x2A, 0x20, 0x31, 0x30, 0x20, 0x2B, 0x20, 0x6D, 0x64, 0x6D, 0x5F, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x5F, -+0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x4E, 0x58, -+0x5F, 0x4D, 0x44, 0x4D, 0x5F, 0x56, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x87, 0x25, 0x73, 0x3A, 0x20, 0x72, 0x61, -+0x64, 0x69, 0x6F, 0x20, 0x25, 0x64, 0x20, 0x64, 0x6F, 0x65, 0x73, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x65, 0x78, 0x69, 0x73, -+0x74, 0x0A, 0x00, 0x00, 0x9D, 0x87, 0x25, 0x73, 0x3A, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x61, -+0x6D, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x2C, 0x20, 0x64, 0x6F, 0x20, 0x6E, 0x6F, 0x74, 0x68, 0x69, -+0x6E, 0x67, 0x0A, 0x00, 0x9B, 0x25, 0x73, 0x20, 0x4D, 0x41, 0x43, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x21, 0x3D, -+0x20, 0x49, 0x44, 0x4C, 0x45, 0x0A, 0x00, 0x00, 0x70, 0x68, 0x79, 0x5F, 0x68, 0x77, 0x5F, 0x73, 0x65, 0x74, 0x5F, 0x63, -+0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x00, 0x00, 0x70, 0x68, 0x79, 0x5F, 0x73, 0x65, 0x74, 0x5F, 0x63, 0x68, 0x61, 0x6E, -+0x6E, 0x65, 0x6C, 0x00, 0x70, 0x68, 0x79, 0x5F, 0x67, 0x65, 0x74, 0x5F, 0x63, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x00, -+0x70, 0x68, 0x79, 0x5F, 0x73, 0x74, 0x6F, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x03, 0x0D, 0xFE, 0x11, 0xFE, 0x0D, 0x02, -+0x0E, 0xFF, 0x13, 0xFE, 0x0B, 0x02, 0x0C, 0xFD, 0x12, 0xFD, 0x0C, 0x03, 0x0D, 0xFE, 0x13, 0xFD, 0x0B, 0x03, 0x0C, 0xFD, -+0x14, 0xFD, 0x0A, 0x03, 0x0B, 0xFC, 0x11, 0xFF, 0x0D, 0x01, 0x0E, 0xFF, 0x13, 0xFD, 0x0B, 0x03, 0x0C, 0xFD, 0x12, 0xFE, -+0x0C, 0x02, 0x0D, 0xFE, 0x12, 0xFE, 0x0C, 0x02, 0x0D, 0xFE, 0x12, 0xFE, 0x0C, 0x02, 0x0D, 0xFE, 0x13, 0xFE, 0x0B, 0x02, -+0x0C, 0xFD, 0x1F, 0x00, 0x0C, 0x02, 0x0D, 0xFE, 0x11, 0x00, 0x0D, 0x00, 0x0E, 0xFF, 0x13, 0x03, 0x0B, 0x03, 0x0C, 0xFD, -+0x14, 0xFC, 0x0A, 0x04, 0x0B, 0xFC, 0x12, 0xFF, 0x0C, 0x01, 0x0D, 0xFE, 0x11, 0xFE, 0x0D, 0x02, 0x0E, 0xFF, 0x13, 0xFE, -+0x0B, 0x02, 0x0C, 0xFD, 0x13, 0xFD, 0x0B, 0x03, 0x0C, 0xFD, 0x12, 0xFF, 0x0C, 0x01, 0x0D, 0xFE, 0x12, 0xFD, 0x0C, 0x03, -+0x0D, 0xFE, 0x12, 0xFF, 0x0C, 0x01, 0x0D, 0xFE, 0x13, 0xFD, 0x0B, 0x03, 0x0C, 0xFD, 0x13, 0xFE, 0x0B, 0x02, 0x0C, 0xFD, -+0x1F, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x74, 0x63, 0x5F, 0x73, 0x70, 0x75, 0x72, 0x69, 0x6F, 0x75, 0x73, 0x00, 0x00, 0x00, -+0x18, 0x10, 0x0C, 0x08, 0x07, 0x06, 0x8B, 0x05, 0x89, 0x04, 0x87, 0x03, 0x85, 0x02, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, -+0x73, 0x65, 0x74, 0x20, 0x74, 0x78, 0x67, 0x61, 0x69, 0x6E, 0x20, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x32, 0x2E, 0x34, -+0x67, 0x28, 0x70, 0x61, 0x5F, 0x64, 0x72, 0x76, 0x5F, 0x69, 0x62, 0x69, 0x74, 0x29, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, -+0x77, 0x66, 0x20, 0x64, 0x66, 0x65, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x72, 0x66, 0x69, 0x6E, 0x74, 0x66, 0x20, 0x52, 0x58, -+0x4F, 0x4E, 0x21, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x77, 0x66, 0x20, 0x64, 0x66, 0x65, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x72, -+0x66, 0x69, 0x6E, 0x74, 0x66, 0x20, 0x52, 0x58, 0x4F, 0x46, 0x46, 0x21, 0x0D, 0x0A, 0x00, 0x00, 0x64, 0x65, 0x74, 0x65, -+0x63, 0x74, 0x20, 0x64, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x62, 0x79, 0x20, 0x7A, 0x65, 0x72, 0x6F, 0x20, -+0x69, 0x6E, 0x20, 0x63, 0x61, 0x6C, 0x5F, 0x6C, 0x73, 0x20, 0x64, 0x65, 0x74, 0x20, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0x73, 0x6C, 0x6F, 0x70, 0x65, 0x20, 0x74, 0x6F, 0x6F, 0x20, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x0D, 0x0A, 0x00, 0x00, 0x00, -+0x67, 0x61, 0x69, 0x6E, 0x20, 0x25, 0x78, 0x20, 0x3A, 0x20, 0x66, 0x69, 0x74, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, -+0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x67, 0x61, 0x69, 0x6E, 0x20, 0x25, 0x78, 0x20, 0x3A, 0x20, 0x66, 0x69, -+0x74, 0x5F, 0x66, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x21, 0x0D, 0x0A, 0x00, 0x63, 0x6F, 0x65, 0x66, 0x5F, 0x49, 0x51, 0x20, -+0x20, 0x69, 0x73, 0x20, 0x25, 0x64, 0x2E, 0x00, 0x25, 0x30, 0x33, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x63, 0x61, 0x6C, 0x20, -+0x73, 0x64, 0x6D, 0x20, 0x20, 0x69, 0x73, 0x20, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x63, 0x61, 0x6C, 0x20, -+0x66, 0x72, 0x65, 0x71, 0x20, 0x69, 0x73, 0x20, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x63, 0x61, 0x6C, 0x20, -+0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x69, 0x73, 0x20, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x72, 0x66, 0x65, 0x6E, -+0x20, 0x72, 0x65, 0x67, 0x20, 0x69, 0x73, 0x20, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x77, 0x66, 0x20, 0x64, -+0x63, 0x63, 0x61, 0x6C, 0x69, 0x62, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6E, 0x21, 0x0D, 0x0A, 0x00, 0x66, 0x69, 0x74, 0x2D, -+0x69, 0x6E, 0x2D, 0x49, 0x20, 0x25, 0x78, 0x3A, 0x20, 0x5B, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x3B, 0x25, 0x64, 0x2C, 0x25, -+0x64, 0x3B, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x3B, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x5D, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0x66, 0x69, 0x74, 0x2D, 0x69, 0x6E, 0x2D, 0x51, 0x20, 0x25, 0x78, 0x3A, 0x20, 0x5B, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x3B, -+0x25, 0x64, 0x2C, 0x25, 0x64, 0x3B, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x3B, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x5D, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x67, 0x61, 0x69, 0x6E, 0x20, 0x25, 0x78, 0x20, 0x3A, 0x20, 0x63, 0x61, 0x6C, 0x49, 0x20, 0x25, -+0x78, 0x2C, 0x20, 0x63, 0x61, 0x6C, 0x51, 0x20, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x77, 0x66, 0x20, 0x64, -+0x63, 0x63, 0x61, 0x6C, 0x69, 0x62, 0x20, 0x65, 0x6E, 0x64, 0x21, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x63, 0x61, 0x6C, 0x5F, -+0x63, 0x66, 0x67, 0x3A, 0x25, 0x78, 0x2C, 0x20, 0x61, 0x6C, 0x70, 0x68, 0x61, 0x3D, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, -+0x70, 0x6C, 0x6C, 0x20, 0x75, 0x6E, 0x6C, 0x6F, 0x63, 0x6B, 0x3A, 0x20, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0x77, 0x66, 0x72, 0x66, 0x20, 0x6F, 0x6E, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x77, 0x66, 0x72, 0x66, 0x20, 0x6F, 0x66, 0x66, -+0x0D, 0x0A, 0x00, 0x00, 0x20, 0x2A, 0x20, 0x63, 0x61, 0x6C, 0x20, 0x74, 0x69, 0x61, 0x5F, 0x69, 0x71, 0x3A, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x49, 0x69, 0x30, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x49, 0x71, 0x30, 0x3D, 0x25, 0x64, -+0x2C, 0x20, 0x56, 0x69, 0x30, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x56, 0x71, 0x30, 0x3D, 0x25, 0x64, 0x3B, 0x0D, 0x0A, 0x00, -+0x20, 0x20, 0x49, 0x69, 0x31, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x49, 0x71, 0x31, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x56, 0x69, -+0x31, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x56, 0x71, 0x31, 0x3D, 0x25, 0x64, 0x3B, 0x0D, 0x0A, 0x00, 0x20, 0x61, 0x64, 0x6A, -+0x49, 0x69, 0x20, 0x3D, 0x20, 0x25, 0x64, 0x2C, 0x20, 0x61, 0x64, 0x6A, 0x49, 0x71, 0x20, 0x3D, 0x20, 0x25, 0x64, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x2D, 0x3E, 0x20, 0x49, 0x69, 0x30, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x49, 0x71, 0x30, 0x3D, 0x25, -+0x64, 0x2C, 0x20, 0x56, 0x69, 0x30, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x56, 0x71, 0x30, 0x3D, 0x25, 0x64, 0x3B, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x2A, 0x6C, 0x6E, 0x61, 0x5F, 0x76, 0x63, 0x6D, 0x70, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x6C, 0x6E, -+0x61, 0x5F, 0x76, 0x63, 0x6D, 0x6E, 0x3D, 0x25, 0x64, 0x3B, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x20, -+0x67, 0x61, 0x69, 0x6E, 0x20, 0x3D, 0x20, 0x25, 0x64, 0x3B, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x77, 0x66, 0x72, 0x66, -+0x20, 0x63, 0x61, 0x6C, 0x69, 0x62, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x69, 0x64, 0x78, 0x5F, 0x6D, 0x61, 0x78, 0x20, -+0x3C, 0x3D, 0x20, 0x33, 0x00, 0x00, 0x00, 0x00, 0x69, 0x64, 0x78, 0x5F, 0x6D, 0x69, 0x6E, 0x20, 0x3C, 0x3D, 0x20, 0x69, -+0x64, 0x78, 0x5F, 0x6D, 0x61, 0x78, 0x00, 0x00, 0x73, 0x66, 0x74, 0x20, 0x64, 0x69, 0x73, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0x73, 0x66, 0x74, 0x72, 0x73, 0x74, 0x20, 0x64, 0x6F, 0x6E, 0x65, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x6F, 0x61, 0x64, -+0x5F, 0x76, 0x61, 0x6C, 0x20, 0x3D, 0x20, 0x30, 0x78, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x72, 0x78, 0x75, 0x73, -+0x65, 0x64, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x74, 0x6F, 0x74, 0x61, 0x6C, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, -+0x68, 0x6F, 0x73, 0x74, 0x5F, 0x62, 0x75, 0x66, 0x5F, 0x64, 0x6D, 0x61, 0x5F, 0x61, 0x64, 0x64, 0x72, 0x20, 0x21, 0x3D, -+0x20, 0x30, 0x00, 0x00, 0x6B, 0x6D, 0x73, 0x67, 0x5F, 0x64, 0x73, 0x74, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, -+0x00, 0x00, 0x00, 0x00, 0x69, 0x64, 0x20, 0x3C, 0x3D, 0x20, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x4D, 0x41, 0x58, 0x00, 0x00, -+0x6B, 0x65, 0x5F, 0x74, 0x61, 0x73, 0x6B, 0x5F, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x28, 0x6B, 0x6D, 0x73, 0x67, 0x5F, 0x64, -+0x73, 0x74, 0x2D, 0x3E, 0x64, 0x65, 0x73, 0x74, 0x5F, 0x69, 0x64, 0x29, 0x00, 0x00, 0x00, 0x00, 0x68, 0x6F, 0x73, 0x74, -+0x6D, 0x73, 0x67, 0x62, 0x75, 0x66, 0x20, 0x21, 0x3D, 0x20, 0x30, 0x00, 0x68, 0x6F, 0x73, 0x74, 0x5F, 0x6D, 0x73, 0x67, -+0x5F, 0x62, 0x75, 0x66, 0x20, 0x21, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x00, 0x69, 0x70, 0x63, 0x5F, 0x65, 0x6D, 0x62, 0x5F, -+0x6B, 0x6D, 0x73, 0x67, 0x5F, 0x66, 0x77, 0x64, 0x3A, 0x20, 0x6E, 0x6F, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, -+0x6D, 0x73, 0x67, 0x69, 0x64, 0x3D, 0x25, 0x78, 0x2C, 0x73, 0x72, 0x63, 0x69, 0x64, 0x3D, 0x25, 0x78, 0x2C, 0x64, 0x73, -+0x74, 0x69, 0x64, 0x3D, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x21, 0x21, 0x21, 0x20, 0x69, -+0x70, 0x63, 0x20, 0x6D, 0x73, 0x67, 0x20, 0x6E, 0x6F, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x66, 0x6F, 0x72, -+0x20, 0x75, 0x73, 0x62, 0x20, 0x69, 0x6E, 0x20, 0x25, 0x64, 0x2C, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x25, 0x64, 0x2C, -+0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x6B, 0x6D, 0x73, 0x67, 0x5F, 0x73, 0x72, 0x63, 0x2D, 0x3E, 0x70, 0x61, -+0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x65, 0x6E, 0x20, 0x3C, 0x3D, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x6F, 0x66, 0x28, 0x6D, 0x73, -+0x67, 0x2D, 0x3E, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x29, 0x00, 0x00, 0x00, 0x73, 0x65, 0x6E, 0x64, 0x20, 0x6D, 0x73, 0x67, -+0x20, 0x63, 0x66, 0x67, 0x20, 0x74, 0x6F, 0x20, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6E, 0x6F, 0x20, -+0x64, 0x73, 0x63, 0x72, 0x21, 0x0D, 0x0A, 0x00, 0x63, 0x68, 0x61, 0x6E, 0x20, 0x6E, 0x6F, 0x74, 0x69, 0x66, 0x79, 0x3A, -+0x20, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x42, 0x54, 0x20, 0x77, 0x61, 0x6B, 0x65, 0x75, 0x70, 0x20, 0x68, 0x6F, -+0x73, 0x74, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x70, 0x6D, 0x69, 0x63, 0x20, 0x67, 0x70, 0x69, 0x6F, 0x0A, 0x00, 0x00, -+0x77, 0x6B, 0x62, 0x74, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x50, 0x4D, 0x49, 0x43, 0x5F, 0x45, 0x52, 0x52, -+0x49, 0x52, 0x51, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x63, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x5F, -+0x69, 0x64, 0x78, 0x20, 0x3C, 0x20, 0x49, 0x50, 0x43, 0x5F, 0x44, 0x4D, 0x41, 0x5F, 0x43, 0x48, 0x41, 0x4E, 0x4E, 0x45, -+0x4C, 0x5F, 0x4D, 0x41, 0x58, 0x00, 0x00, 0x00, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x23, 0x20, 0x3D, 0x25, 0x64, 0x20, -+0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x66, 0x2D, 0x3E, 0x75, 0x2E, 0x73, 0x74, 0x61, 0x2E, 0x6C, -+0x61, 0x73, 0x74, 0x65, 0x73, 0x74, 0x5F, 0x63, 0x6F, 0x6E, 0x6E, 0x5F, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x3D, 0x3D, -+0x20, 0x31, 0x00, 0x00, 0x73, 0x74, 0x61, 0x2D, 0x3E, 0x6C, 0x61, 0x73, 0x74, 0x65, 0x73, 0x74, 0x5F, 0x63, 0x6F, 0x6E, -+0x6E, 0x5F, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x3D, 0x3D, 0x20, 0x31, 0x00, 0x00, 0x00, 0x00, 0x61, 0x70, 0x6D, 0x20, -+0x73, 0x74, 0x61, 0x3A, 0x25, 0x64, 0x0A, 0x00, 0x74, 0x3A, 0x25, 0x64, 0x2C, 0x20, 0x72, 0x3A, 0x25, 0x64, 0x2C, 0x20, -+0x72, 0x72, 0x3A, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x73, 0x74, 0x61, 0x74, 0x20, 0x6C, 0x6F, 0x73, 0x73, 0x31, 0x0A, 0x00, -+0x63, 0x6C, 0x65, 0x61, 0x72, 0x0A, 0x00, 0x00, 0x73, 0x74, 0x61, 0x74, 0x20, 0x6C, 0x6F, 0x73, 0x73, 0x0A, 0x00, 0x00, -+0x74, 0x78, 0x64, 0x65, 0x73, 0x63, 0x5F, 0x74, 0x6D, 0x70, 0x2D, 0x3E, 0x68, 0x6F, 0x73, 0x74, 0x2E, 0x73, 0x74, 0x61, -+0x69, 0x64, 0x20, 0x3C, 0x20, 0x4E, 0x58, 0x5F, 0x52, 0x45, 0x4D, 0x4F, 0x54, 0x45, 0x5F, 0x53, 0x54, 0x41, 0x5F, 0x4D, -+0x41, 0x58, 0x00, 0x00, 0x73, 0x74, 0x61, 0x20, 0x69, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x3A, 0x25, 0x64, 0x0A, 0x00, -+0x74, 0x78, 0x64, 0x65, 0x73, 0x63, 0x5F, 0x74, 0x6D, 0x70, 0x2D, 0x3E, 0x68, 0x6F, 0x73, 0x74, 0x2E, 0x66, 0x6C, 0x61, -+0x67, 0x73, 0x20, 0x26, 0x20, 0x54, 0x58, 0x55, 0x5F, 0x43, 0x4E, 0x54, 0x52, 0x4C, 0x5F, 0x52, 0x45, 0x54, 0x52, 0x59, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0xD9, 0x67, 0x12, 0x00, 0xF9, 0x67, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x5F, 0x6E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5F, 0x70, 0x6F, 0x6F, 0x6C, 0x5F, -+0x69, 0x64, 0x3A, 0x20, 0x49, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x70, -+0x61, 0x73, 0x73, 0x65, 0x64, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x73, 0x65, 0x74, 0x5F, 0x70, 0x61, 0x74, 0x74, -+0x65, 0x72, 0x6E, 0x3A, 0x20, 0x49, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, -+0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x73, 0x65, 0x74, 0x5F, 0x6E, 0x75, 0x6D, 0x5F, -+0x75, 0x73, 0x65, 0x72, 0x73, 0x3A, 0x20, 0x49, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, -+0x72, 0x20, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x5F, -+0x6E, 0x65, 0x78, 0x74, 0x5F, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5F, 0x61, 0x64, 0x64, 0x72, 0x3A, 0x20, 0x49, 0x6E, -+0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x3A, -+0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x65, 0x6D, 0x4D, 0x67, 0x72, 0x45, 0x72, 0x72, 0x3A, 0x20, 0x53, -+0x75, 0x62, 0x70, 0x6F, 0x6F, 0x6C, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x53, 0x77, 0x45, 0x72, -+0x3A, 0x4E, 0x6F, 0x53, 0x69, 0x7A, 0x65, 0x41, 0x6C, 0x6C, 0x6F, 0x63, 0x20, 0x3A, 0x20, 0x25, 0x64, 0x0A, 0x0D, 0x00, -+0x67, 0x65, 0x74, 0x5F, 0x6E, 0x65, 0x78, 0x74, 0x5F, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5F, 0x61, 0x64, 0x64, 0x72, -+0x3A, 0x20, 0x49, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x70, 0x61, 0x73, -+0x73, 0x65, 0x64, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x67, 0x65, 0x74, 0x5F, 0x70, 0x61, 0x74, 0x74, -+0x65, 0x72, 0x6E, 0x3A, 0x20, 0x49, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, -+0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x53, 0x77, 0x45, 0x72, 0x3A, 0x41, 0x6C, 0x6C, -+0x63, 0x45, 0x72, 0x72, 0x50, 0x74, 0x72, 0x6E, 0x20, 0x3A, 0x20, 0x25, 0x64, 0x2C, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, -+0x72, 0x3A, 0x20, 0x30, 0x78, 0x25, 0x78, 0x0A, 0x0D, 0x00, 0x00, 0x00, 0x67, 0x65, 0x74, 0x5F, 0x6E, 0x61, 0x74, 0x69, -+0x76, 0x65, 0x5F, 0x70, 0x6F, 0x6F, 0x6C, 0x5F, 0x69, 0x64, 0x3A, 0x20, 0x49, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, -+0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, -+0x64, 0x65, 0x63, 0x72, 0x5F, 0x6E, 0x75, 0x6D, 0x5F, 0x75, 0x73, 0x65, 0x72, 0x73, 0x3A, 0x20, 0x49, 0x6E, 0x76, 0x61, -+0x6C, 0x69, 0x64, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x3A, 0x20, 0x25, -+0x78, 0x0A, 0x00, 0x00, 0x73, 0x65, 0x74, 0x5F, 0x75, 0x73, 0x65, 0x72, 0x5F, 0x69, 0x64, 0x3A, 0x20, 0x49, 0x6E, 0x76, -+0x61, 0x6C, 0x69, 0x64, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x3A, 0x20, -+0x25, 0x78, 0x0A, 0x00, 0x6E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5F, 0x69, 0x64, 0x20, 0x3D, 0x3D, 0x20, 0x32, 0x00, 0x00, -+0x67, 0x65, 0x74, 0x5F, 0x75, 0x73, 0x65, 0x72, 0x5F, 0x69, 0x64, 0x3A, 0x20, 0x49, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, -+0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, -+0x72, 0x65, 0x70, 0x3A, 0x20, 0x6E, 0x6F, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x2C, 0x20, 0x25, 0x64, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x72, 0x65, 0x70, 0x3A, 0x20, 0x6E, 0x6F, 0x20, 0x64, 0x65, 0x73, 0x63, 0x0D, 0x0A, 0x00, 0x00, -+0x70, 0x61, 0x72, 0x61, 0x6D, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x63, 0x6E, 0x74, 0x20, -+0x65, 0x72, 0x72, 0x6F, 0x72, 0x0D, 0x0A, 0x00, 0x69, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x6E, 0x75, 0x6D, 0x3D, 0x25, 0x64, -+0x2C, 0x20, 0x72, 0x78, 0x64, 0x65, 0x73, 0x63, 0x3D, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x61, 0x63, 0x3E, 0x3D, 0x4E, 0x58, 0x5F, 0x54, 0x58, 0x51, 0x5F, 0x43, 0x4E, 0x54, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x20, 0x3C, 0x20, 0x4E, 0x58, 0x5F, 0x54, 0x58, 0x51, 0x5F, 0x43, 0x4E, 0x54, 0x20, -+0x2B, 0x20, 0x31, 0x00, 0x74, 0x78, 0x64, 0x65, 0x73, 0x63, 0x5F, 0x6E, 0x65, 0x77, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, -+0x4C, 0x4C, 0x00, 0x00, 0x6D, 0x73, 0x67, 0x20, 0x63, 0x72, 0x63, 0x20, 0x65, 0x72, 0x72, 0x0D, 0x0A, 0x00, 0x00, 0x00, -+0x69, 0x6E, 0x74, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x21, 0x3D, 0x20, 0x30, 0x00, 0x73, 0x6F, 0x66, 0x74, -+0x77, 0x6B, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x64, 0x6D, 0x61, 0x20, 0x69, 0x6E, 0x74, 0x20, 0x25, 0x78, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x73, 0x64, 0x69, 0x6F, 0x20, 0x69, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x3A, 0x20, 0x73, 0x74, -+0x61, 0x74, 0x75, 0x73, 0x3D, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x73, 0x64, 0x69, 0x6F, 0x20, 0x68, 0x6F, 0x73, -+0x74, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x61, 0x68, 0x62, 0x32, 0x73, 0x64, 0x69, 0x6F, -+0x20, 0x74, 0x78, 0x20, 0x61, 0x62, 0x6F, 0x72, 0x74, 0x0D, 0x0A, 0x00, 0x53, 0x44, 0x49, 0x4F, 0x32, 0x41, 0x48, 0x42, -+0x5F, 0x4C, 0x4C, 0x53, 0x54, 0x5F, 0x48, 0x44, 0x52, 0x5F, 0x45, 0x52, 0x52, 0x0D, 0x0A, 0x00, 0x73, 0x64, 0x69, 0x6F, -+0x20, 0x65, 0x72, 0x72, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3D, 0x25, 0x78, 0x2C, 0x30, 0x78, 0x34, 0x35, 0x3D, -+0x25, 0x78, 0x0A, 0x00, 0x6D, 0x73, 0x67, 0x72, 0x78, 0x75, 0x73, 0x65, 0x64, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x74, 0x6F, -+0x74, 0x61, 0x6C, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x74, 0x78, 0x63, 0x75, 0x73, 0x65, 0x64, 0x3D, -+0x25, 0x64, 0x2C, 0x20, 0x74, 0x6F, 0x74, 0x61, 0x6C, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x74, 0x78, 0x63, 0x6D, -+0x73, 0x67, 0x75, 0x73, 0x65, 0x64, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x6D, 0x73, 0x67, 0x74, 0x6F, 0x74, 0x61, 0x6C, 0x3D, -+0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x77, 0x61, 0x69, 0x74, 0x20, 0x69, 0x6F, 0x20, 0x65, 0x6E, 0x61, 0x62, -+0x6C, 0x65, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x69, 0x6F, 0x20, 0x65, 0x6E, 0x61, 0x62, 0x6C, 0x65, 0x0D, 0x0A, 0x00, -+0x65, 0x72, 0x72, 0x3A, 0x20, 0x6E, 0x6F, 0x20, 0x6D, 0x73, 0x67, 0x20, 0x70, 0x6B, 0x74, 0x21, 0x0D, 0x0A, 0x00, 0x00, -+0x65, 0x72, 0x72, 0x3A, 0x20, 0x6E, 0x6F, 0x20, 0x64, 0x73, 0x63, 0x72, 0x21, 0x0D, 0x0A, 0x00, 0x6F, 0x70, 0x65, 0x6E, -+0x3A, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x55, 0x4C, 0x50, 0x49, 0x20, 0x63, 0x6C, 0x6B, 0x20, 0x64, 0x65, 0x74, -+0x65, 0x63, 0x74, 0x65, 0x64, 0x0D, 0x0A, 0x00, 0x65, 0x72, 0x72, 0x21, 0x21, 0x20, 0x6E, 0x6F, 0x20, 0x75, 0x73, 0x62, -+0x20, 0x75, 0x6C, 0x70, 0x69, 0x20, 0x63, 0x6C, 0x6B, 0x0D, 0x0A, 0x00, 0x77, 0x61, 0x69, 0x74, 0x20, 0x63, 0x66, 0x67, -+0x0A, 0x00, 0x00, 0x00, 0x46, 0x49, 0x46, 0x4F, 0x20, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x3A, 0x20, 0x6F, 0x76, 0x65, 0x72, -+0x66, 0x6C, 0x6F, 0x77, 0x2C, 0x20, 0x61, 0x64, 0x64, 0x72, 0x20, 0x69, 0x73, 0x20, 0x25, 0x64, 0x2C, 0x20, 0x73, 0x69, -+0x7A, 0x65, 0x20, 0x69, 0x73, 0x20, 0x25, 0x64, 0x2C, 0x20, 0x54, 0x6F, 0x74, 0x61, 0x6C, 0x20, 0x52, 0x41, 0x4D, 0x20, -+0x69, 0x73, 0x20, 0x25, 0x64, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x21, 0x21, 0x21, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, -+0x6D, 0x65, 0x6E, 0x74, 0x20, 0x65, 0x72, 0x72, 0x0D, 0x0A, 0x00, 0x00, 0x45, 0x50, 0x30, 0x20, 0x53, 0x45, 0x54, 0x55, -+0x50, 0x20, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x2C, 0x20, 0x64, 0x69, 0x72, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x00, 0x00, -+0x45, 0x50, 0x30, 0x20, 0x53, 0x45, 0x54, 0x55, 0x50, 0x20, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x2C, 0x20, 0x77, 0x4C, 0x65, -+0x6E, 0x67, 0x74, 0x68, 0x20, 0x69, 0x73, 0x20, 0x7A, 0x65, 0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x55, 0x6E, 0x6B, 0x6E, -+0x6F, 0x77, 0x6E, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6F, 0x72, 0x3A, 0x20, 0x25, 0x64, 0x00, 0x00, -+0x45, 0x70, 0x30, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x20, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x65, 0x72, 0x72, 0x20, -+0x25, 0x75, 0x2D, 0x25, 0x75, 0x00, 0x00, 0x00, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x72, 0x65, 0x62, 0x6F, 0x6F, 0x74, -+0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x72, 0x65, 0x73, 0x65, 0x74, 0x0D, 0x0A, 0x00, 0x65, 0x78, 0x69, 0x74, -+0x0D, 0x0A, 0x00, 0x00, 0x75, 0x73, 0x62, 0x20, 0x77, 0x61, 0x6B, 0x65, 0x75, 0x70, 0x0A, 0x00, 0x77, 0x61, 0x6B, 0x65, -+0x75, 0x70, 0x20, 0x75, 0x73, 0x62, 0x0A, 0x00, 0x69, 0x72, 0x71, 0x20, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0x77, 0x6C, 0x61, 0x6E, 0x5F, 0x75, 0x73, 0x62, 0x5F, 0x73, 0x75, 0x73, 0x70, 0x65, 0x6E, 0x64, 0x00, 0x00, 0x00, 0x00, -+0x52, 0x3A, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x77, 0x64, 0x6C, 0x20, 0x65, 0x72, 0x72, 0x20, 0x25, 0x58, 0x20, 0x25, -+0x64, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x77, 0x6D, 0x6C, 0x20, 0x65, 0x72, 0x72, 0x20, 0x25, 0x58, 0x20, 0x25, -+0x64, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x21, 0x21, 0x21, 0x20, 0x6E, 0x6F, 0x20, 0x72, 0x78, -+0x20, 0x6D, 0x73, 0x67, 0x20, 0x65, 0x6C, 0x65, 0x6D, 0x0D, 0x0A, 0x00, 0x74, 0x79, 0x70, 0x65, 0x20, 0x65, 0x72, 0x72, -+0x20, 0x25, 0x58, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x6C, 0x65, 0x6E, 0x20, 0x65, 0x72, 0x72, 0x20, 0x25, 0x58, 0x20, 0x25, -+0x64, 0x0A, 0x00, 0x00, 0x75, 0x73, 0x62, 0x20, 0x77, 0x6C, 0x61, 0x6E, 0x20, 0x72, 0x65, 0x63, 0x76, 0x20, 0x65, 0x72, -+0x72, 0x21, 0x21, 0x21, 0x20, 0x25, 0x64, 0x2C, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x23, 0x23, 0x23, 0x65, -+0x72, 0x72, 0x23, 0x23, 0x23, 0x20, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x75, 0x73, 0x62, 0x20, 0x77, 0x6C, 0x61, 0x6E, -+0x20, 0x73, 0x65, 0x6E, 0x64, 0x20, 0x65, 0x72, 0x72, 0x21, 0x21, 0x21, 0x20, 0x25, 0x64, 0x2C, 0x20, 0x25, 0x64, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x6F, 0x70, 0x65, 0x6E, 0x20, 0x72, 0x65, 0x73, 0x3A, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0x65, 0x72, 0x72, 0x21, 0x21, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x65, 0x72, 0x72, 0x20, 0x25, 0x64, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x72, 0x65, 0x74, 0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x20, 0x00, -+0x01, 0x01, 0x00, 0xA0, 0xFA, 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0x00, 0x07, 0x05, 0x01, 0x02, 0x00, 0x02, -+0x00, 0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00, 0x05, 0x0F, 0x0C, 0x00, 0x01, 0x07, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, -+0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x9C, 0xA6, 0x00, 0x88, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, -+0x0A, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, -+0x0A, 0x03, 0x77, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x10, 0x03, 0x61, 0x00, 0x69, 0x00, 0x63, 0x00, -+0x73, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x12, 0x03, 0x41, 0x00, 0x49, 0x00, 0x43, 0x00, 0x20, 0x00, 0x57, 0x00, -+0x6C, 0x00, 0x61, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x12, 0x03, 0x32, 0x00, 0x30, 0x00, 0x31, 0x00, 0x39, 0x00, 0x30, 0x00, -+0x32, 0x00, 0x32, 0x00, 0x37, 0x00, 0x00, 0x00, 0x04, 0x03, 0x09, 0x04, 0x75, 0x73, 0x62, 0x5F, 0x77, 0x6C, 0x61, 0x6E, -+0x5F, 0x72, 0x78, 0x5F, 0x70, 0x6B, 0x74, 0x5F, 0x66, 0x72, 0x65, 0x65, 0x5F, 0x6C, 0x69, 0x73, 0x74, 0x5F, 0x69, 0x6E, -+0x69, 0x74, 0x20, 0x61, 0x6C, 0x6C, 0x6F, 0x63, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x3A, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, -+0x77, 0x66, 0x72, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x75, 0x73, 0x62, 0x20, 0x73, 0x74, 0x61, -+0x72, 0x74, 0x20, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x20, 0x3C, 0x3D, 0x20, 0x68, 0x6F, 0x73, -+0x74, 0x5F, 0x69, 0x66, 0x5F, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x2D, 0x3E, 0x64, 0x65, 0x73, 0x63, 0x5F, 0x73, 0x69, 0x7A, -+0x65, 0x00, 0x00, 0x00, 0x20, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x72, 0x78, 0x3A, 0x20, 0x64, 0x73, 0x63, 0x72, 0x20, 0x75, -+0x73, 0x65, 0x64, 0x20, 0x3D, 0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x23, 0x77, 0x66, 0x3A, 0x25, 0x58, 0x0A, 0x00, -+0x23, 0x77, 0x65, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x77, 0x64, 0x20, 0x72, 0x78, 0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, -+0x65, 0x72, 0x72, 0x21, 0x20, 0x77, 0x64, 0x20, 0x6E, 0x6F, 0x20, 0x72, 0x78, 0x20, 0x62, 0x75, 0x66, 0x0A, 0x00, 0x00, -+0x77, 0x64, 0x20, 0x72, 0x78, 0x20, 0x6D, 0x61, 0x78, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, -+0x68, 0x6F, 0x73, 0x74, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x79, 0x0A, 0x00, 0x77, 0x6C, 0x61, 0x6E, 0x20, 0x64, 0x61, 0x74, -+0x61, 0x20, 0x72, 0x65, 0x63, 0x76, 0x20, 0x72, 0x65, 0x74, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x65, 0x72, 0x72, 0x3A, -+0x20, 0x6E, 0x6F, 0x20, 0x77, 0x6C, 0x61, 0x6E, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x62, 0x75, 0x66, 0x0A, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x69, 0x70, 0x63, -+0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x20, 0x69, 0x70, 0x63, 0x20, 0x68, 0x6F, 0x73, -+0x74, 0x20, 0x72, 0x78, 0x3A, 0x20, 0x6E, 0x6F, 0x62, 0x75, 0x66, 0x66, 0x2C, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x3D, -+0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x4D, 0x4D, 0x5F, 0x53, 0x54, 0x41, 0x5F, 0x54, 0x4F, 0x5F, 0x4B, 0x45, -+0x59, 0x28, 0x4E, 0x58, 0x5F, 0x52, 0x45, 0x4D, 0x4F, 0x54, 0x45, 0x5F, 0x53, 0x54, 0x41, 0x5F, 0x4D, 0x41, 0x58, 0x20, -+0x2D, 0x20, 0x31, 0x29, 0x20, 0x3C, 0x3D, 0x20, 0x6E, 0x78, 0x6D, 0x61, 0x63, 0x5F, 0x73, 0x74, 0x61, 0x5F, 0x6B, 0x65, -+0x79, 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x5F, 0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x00, 0x00, -+0x6C, 0x70, 0x20, 0x25, 0x64, 0x2C, 0x20, 0x61, 0x63, 0x74, 0x73, 0x6C, 0x70, 0x3A, 0x25, 0x64, 0x2C, 0x20, 0x74, 0x69, -+0x6D, 0x65, 0x3D, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x63, 0x74, 0x78, 0x74, 0x2D, 0x3E, 0x69, 0x64, 0x78, 0x20, 0x21, 0x3D, -+0x20, 0x43, 0x48, 0x41, 0x4E, 0x5F, 0x43, 0x54, 0x58, 0x54, 0x5F, 0x55, 0x4E, 0x55, 0x53, 0x45, 0x44, 0x00, 0x00, 0x00, -+0x73, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x6B, 0x65, 0x75, 0x70, 0x20, 0x69, 0x73, 0x20, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, -+0x67, 0x3A, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x0D, 0x0A, 0x00, 0x00, 0x74, 0x69, 0x6D, 0x65, -+0x72, 0x3A, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x20, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, -+0x6C, 0x61, 0x73, 0x74, 0x20, 0x3C, 0x20, 0x31, 0x30, 0x6D, 0x73, 0x2C, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x61, 0x6C, 0x6C, -+0x6F, 0x77, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x6F, 0x74, 0x20, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x0D, 0x0A, 0x00, -+0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x0A, 0x43, 0x4F, 0x4E, 0x54, 0x52, 0x4F, 0x4C, 0x3D, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x78, -+0x50, 0x53, 0x52, 0x20, 0x20, 0x20, 0x3D, 0x25, 0x30, 0x38, 0x78, 0x0A, 0x50, 0x53, 0x50, 0x20, 0x20, 0x20, 0x20, 0x3D, -+0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x4D, 0x53, 0x50, 0x20, 0x20, 0x20, 0x20, 0x3D, 0x25, 0x30, 0x38, 0x78, 0x0A, 0x50, -+0x52, 0x49, 0x4D, 0x41, 0x53, 0x4B, 0x3D, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x4C, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, -+0x3D, 0x25, 0x30, 0x38, 0x78, 0x0A, 0x00, 0x00, 0x0A, 0x57, 0x72, 0x6F, 0x6E, 0x67, 0x20, 0x50, 0x53, 0x50, 0x21, 0x00, -+0x0A, 0x44, 0x75, 0x6D, 0x70, 0x4D, 0x53, 0x50, 0x3A, 0x00, 0x00, 0x00, 0x0A, 0x5B, 0x25, 0x30, 0x38, 0x78, 0x5D, 0x3A, -+0x00, 0x00, 0x00, 0x00, 0x20, 0x25, 0x30, 0x38, 0x58, 0x00, 0x00, 0x00, 0x0A, 0x52, 0x25, 0x2D, 0x34, 0x64, 0x3A, 0x20, -+0x25, 0x30, 0x38, 0x58, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x53, 0x50, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, -+0x0A, 0x4C, 0x52, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x0A, 0x50, 0x43, 0x20, 0x20, 0x20, 0x3A, 0x20, -+0x25, 0x30, 0x38, 0x58, 0x0A, 0x78, 0x50, 0x53, 0x52, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x0A, 0x50, 0x53, 0x50, -+0x20, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x0A, 0x4D, 0x53, 0x50, 0x20, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, -+0x00, 0x00, 0x00, 0x00, 0x0A, 0x43, 0x50, 0x55, 0x49, 0x44, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x0A, 0x49, 0x43, 0x53, -+0x52, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x0A, 0x56, 0x54, 0x4F, 0x52, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, -+0x0A, 0x41, 0x49, 0x52, 0x43, 0x52, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x53, 0x48, 0x43, -+0x53, 0x52, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x0A, 0x43, 0x46, 0x53, 0x52, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, -+0x0A, 0x48, 0x46, 0x53, 0x52, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x0A, 0x44, 0x46, 0x53, 0x52, 0x20, 0x3A, 0x20, -+0x25, 0x30, 0x38, 0x58, 0x0A, 0x41, 0x46, 0x53, 0x52, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x00, 0x00, 0x00, 0x00, -+0x0A, 0x4D, 0x4D, 0x46, 0x53, 0x52, 0x3A, 0x20, 0x25, 0x30, 0x32, 0x58, 0x0A, 0x20, 0x20, 0x49, 0x41, 0x43, 0x43, 0x56, -+0x49, 0x4F, 0x4C, 0x20, 0x3A, 0x25, 0x64, 0x09, 0x44, 0x41, 0x43, 0x43, 0x56, 0x49, 0x4F, 0x4C, 0x20, 0x3A, 0x25, 0x64, -+0x0A, 0x20, 0x20, 0x4D, 0x55, 0x4E, 0x53, 0x54, 0x4B, 0x45, 0x52, 0x52, 0x3A, 0x25, 0x64, 0x09, 0x4D, 0x53, 0x54, 0x4B, -+0x45, 0x52, 0x52, 0x20, 0x20, 0x3A, 0x25, 0x64, 0x0A, 0x20, 0x20, 0x4D, 0x4C, 0x53, 0x50, 0x45, 0x52, 0x52, 0x20, 0x20, -+0x3A, 0x25, 0x64, 0x09, 0x4D, 0x4D, 0x41, 0x52, 0x56, 0x41, 0x4C, 0x49, 0x44, 0x3A, 0x25, 0x64, 0x00, 0x00, 0x00, 0x00, -+0x0A, 0x4D, 0x4D, 0x46, 0x41, 0x52, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x42, 0x46, 0x53, -+0x52, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x32, 0x58, 0x0A, 0x20, 0x20, 0x49, 0x42, 0x55, 0x53, 0x45, 0x52, 0x52, 0x20, 0x20, -+0x20, 0x20, 0x3A, 0x25, 0x64, 0x09, 0x50, 0x52, 0x45, 0x43, 0x49, 0x53, 0x45, 0x52, 0x52, 0x3A, 0x25, 0x64, 0x0A, 0x20, -+0x20, 0x49, 0x4D, 0x50, 0x52, 0x45, 0x43, 0x49, 0x53, 0x45, 0x52, 0x52, 0x3A, 0x25, 0x64, 0x09, 0x55, 0x4E, 0x53, 0x54, -+0x4B, 0x45, 0x52, 0x52, 0x20, 0x3A, 0x25, 0x64, 0x0A, 0x20, 0x20, 0x53, 0x54, 0x4B, 0x45, 0x52, 0x52, 0x20, 0x20, 0x20, -+0x20, 0x20, 0x3A, 0x25, 0x64, 0x09, 0x4C, 0x53, 0x50, 0x45, 0x52, 0x52, 0x20, 0x20, 0x20, 0x3A, 0x25, 0x64, 0x0A, 0x20, -+0x20, 0x42, 0x46, 0x41, 0x52, 0x56, 0x41, 0x4C, 0x49, 0x44, 0x20, 0x20, 0x3A, 0x25, 0x64, 0x00, 0x0A, 0x42, 0x46, 0x41, -+0x52, 0x20, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x55, 0x46, 0x53, 0x52, 0x20, 0x3A, 0x20, -+0x25, 0x30, 0x34, 0x58, 0x0A, 0x20, 0x20, 0x55, 0x4E, 0x44, 0x45, 0x46, 0x49, 0x4E, 0x53, 0x54, 0x52, 0x3A, 0x25, 0x64, -+0x09, 0x49, 0x4E, 0x56, 0x53, 0x54, 0x41, 0x54, 0x45, 0x20, 0x3A, 0x25, 0x64, 0x0A, 0x20, 0x20, 0x49, 0x4E, 0x56, 0x50, -+0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x25, 0x64, 0x09, 0x4E, 0x4F, 0x43, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, -+0x25, 0x64, 0x0A, 0x20, 0x20, 0x55, 0x4E, 0x41, 0x4C, 0x49, 0x47, 0x4E, 0x45, 0x44, 0x20, 0x3A, 0x25, 0x64, 0x09, 0x44, -+0x49, 0x56, 0x42, 0x59, 0x5A, 0x45, 0x52, 0x4F, 0x3A, 0x25, 0x64, 0x00, 0x0A, 0x4D, 0x6F, 0x64, 0x65, 0x20, 0x3A, 0x20, -+0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, 0x0A, 0x50, 0x72, 0x69, 0x76, 0x20, 0x3A, 0x20, 0x55, 0x73, 0x65, 0x72, -+0x00, 0x00, 0x00, 0x00, 0x0A, 0x50, 0x72, 0x69, 0x76, 0x20, 0x3A, 0x20, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6C, 0x65, 0x67, -+0x65, 0x64, 0x00, 0x00, 0x0A, 0x4D, 0x6F, 0x64, 0x65, 0x20, 0x3A, 0x20, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00, -+0x0A, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x3A, 0x20, 0x50, 0x53, 0x50, 0x00, 0x0A, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x3A, 0x20, -+0x4D, 0x53, 0x50, 0x00, 0x0A, 0x43, 0x4E, 0x54, 0x52, 0x4C, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x0A, 0x50, 0x4D, 0x41, -+0x53, 0x4B, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x0A, 0x46, 0x4D, 0x41, 0x53, 0x4B, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, -+0x0A, 0x42, 0x41, 0x53, 0x45, 0x50, 0x3A, 0x20, 0x25, 0x30, 0x38, 0x58, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x44, 0x75, 0x6D, -+0x70, 0x50, 0x53, 0x50, 0x3A, 0x00, 0x00, 0x00, 0x50, 0x61, 0x6E, 0x69, 0x63, 0x2E, 0x2E, 0x2E, 0x0A, 0x00, 0x00, 0x00, -+0x0A, 0x2B, 0x2B, 0x20, 0x43, 0x4D, 0x34, 0x20, 0x46, 0x61, 0x75, 0x6C, 0x74, 0x20, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, -+0x72, 0x20, 0x2B, 0x2B, 0x0A, 0x0A, 0x46, 0x61, 0x75, 0x6C, 0x74, 0x54, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x00, 0x00, 0x00, -+0x4D, 0x65, 0x6D, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6C, 0x74, 0x00, 0x00, 0x42, 0x75, 0x73, 0x46, -+0x61, 0x75, 0x6C, 0x74, 0x00, 0x00, 0x00, 0x00, 0x55, 0x73, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6C, 0x74, 0x00, 0x00, -+0x48, 0x61, 0x72, 0x64, 0x46, 0x61, 0x75, 0x6C, 0x74, 0x00, 0x00, 0x00, 0x0A, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x78, -+0x74, 0x3A, 0x00, 0x00, 0x0A, 0x0A, 0x2D, 0x2D, 0x20, 0x43, 0x4D, 0x34, 0x20, 0x46, 0x61, 0x75, 0x6C, 0x74, 0x20, 0x48, -+0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x20, 0x2D, 0x2D, 0x0A, 0x0A, 0x00, 0x9A, 0x25, 0x73, 0x20, 0x2D, 0x20, 0x62, 0x75, -+0x69, 0x6C, 0x64, 0x3A, 0x20, 0x25, 0x73, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x25, -+0x64, 0x2C, 0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x72, 0x65, 0x73, 0x65, 0x74, 0x20, 0x64, 0x6F, 0x6E, 0x65, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x64, 0x2C, 0x00, 0x00, 0x74, 0x3D, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x6E, 0x6F, 0x74, 0x20, -+0x70, 0x61, 0x73, 0x74, 0x3A, 0x20, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x70, 0x61, 0x73, 0x73, -+0x3A, 0x20, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x68, 0x61, 0x6C, 0x5F, 0x6D, 0x61, 0x63, -+0x68, 0x77, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x5F, 0x70, 0x61, 0x73, 0x74, 0x28, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x2D, 0x3E, -+0x74, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x67, 0x5F, 0x77, 0x69, 0x66, 0x69, 0x5F, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, -+0x67, 0x73, 0x2E, 0x70, 0x77, 0x72, 0x5F, 0x6F, 0x70, 0x65, 0x6E, 0x5F, 0x73, 0x79, 0x73, 0x64, 0x65, 0x6C, 0x61, 0x79, -+0x29, 0x00, 0x00, 0x00, 0x73, 0x6C, 0x70, 0x3A, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x62, 0x74, 0x0A, 0x00, -+0x6C, 0x70, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x69, 0x67, 0x6E, 0x6F, 0x72, 0x65, 0x3D, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, -+0x77, 0x2C, 0x20, 0x00, 0x72, 0x77, 0x6E, 0x78, 0x5F, 0x65, 0x6E, 0x76, 0x2E, 0x70, 0x72, 0x65, 0x76, 0x5F, 0x68, 0x77, -+0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3D, 0x3D, 0x20, 0x6E, 0x78, 0x6D, 0x61, 0x63, 0x5F, 0x63, 0x75, 0x72, 0x72, -+0x65, 0x6E, 0x74, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x00, 0x00, 0x00, 0x00, -+0x77, 0x65, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x72, 0x77, 0x6E, 0x78, 0x6C, 0x5F, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5F, -+0x65, 0x76, 0x74, 0x00, 0x74, 0x78, 0x64, 0x65, 0x73, 0x63, 0x5F, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5B, 0x30, 0x5D, 0x20, -+0x26, 0x26, 0x20, 0x74, 0x78, 0x5F, 0x68, 0x77, 0x5F, 0x64, 0x65, 0x73, 0x63, 0x5F, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5B, -+0x30, 0x5D, 0x00, 0x00, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, -+0x74, 0x78, 0x6C, 0x20, 0x3A, 0x25, 0x78, 0x2C, 0x20, 0x6C, 0x65, 0x6E, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, -+0x74, 0x78, 0x6C, 0x5F, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x74, 0x78, 0x64, 0x65, 0x73, -+0x63, 0x29, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x74, 0x68, 0x64, 0x2D, 0x3E, 0x66, 0x69, 0x72, -+0x73, 0x74, 0x5F, 0x70, 0x62, 0x64, 0x5F, 0x70, 0x74, 0x72, 0x00, 0x00, 0x6E, 0x65, 0x78, 0x74, 0x64, 0x65, 0x73, 0x63, -+0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x61, 0x67, 0x67, 0x5F, 0x64, 0x65, 0x73, 0x63, -+0x2D, 0x3E, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x26, 0x20, 0x41, 0x47, 0x47, 0x5F, 0x42, 0x41, 0x5F, 0x52, 0x45, -+0x43, 0x45, 0x49, 0x56, 0x45, 0x44, 0x00, 0x00, 0x6E, 0x78, 0x6D, 0x61, 0x63, 0x5F, 0x74, 0x78, 0x5F, 0x62, 0x63, 0x6E, -+0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x20, 0x21, 0x3D, 0x20, 0x32, 0x00, 0x00, -+0x6E, 0x78, 0x6D, 0x61, 0x63, 0x5F, 0x74, 0x78, 0x5F, 0x61, 0x63, 0x5F, 0x33, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, -+0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x20, 0x21, 0x3D, 0x20, 0x32, 0x00, 0x6E, 0x78, 0x6D, 0x61, 0x63, 0x5F, 0x74, 0x78, -+0x5F, 0x61, 0x63, 0x5F, 0x32, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x20, 0x21, -+0x3D, 0x20, 0x32, 0x00, 0x6E, 0x78, 0x6D, 0x61, 0x63, 0x5F, 0x74, 0x78, 0x5F, 0x61, 0x63, 0x5F, 0x31, 0x5F, 0x73, 0x74, -+0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x20, 0x21, 0x3D, 0x20, 0x32, 0x00, 0x6E, 0x78, 0x6D, 0x61, -+0x63, 0x5F, 0x74, 0x78, 0x5F, 0x61, 0x63, 0x5F, 0x30, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x66, -+0x28, 0x29, 0x20, 0x21, 0x3D, 0x20, 0x32, 0x00, 0x6E, 0x78, 0x6D, 0x61, 0x63, 0x5F, 0x74, 0x78, 0x5F, 0x68, 0x69, 0x5F, -+0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x20, 0x21, 0x3D, 0x20, 0x32, 0x00, 0x00, 0x00, -+0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5F, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6F, 0x72, 0x79, 0x20, 0x3C, 0x20, 0x28, 0x4E, -+0x58, 0x5F, 0x54, 0x58, 0x51, 0x5F, 0x43, 0x4E, 0x54, 0x2B, 0x32, 0x29, 0x00, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x21, -+0x21, 0x21, 0x20, 0x74, 0x78, 0x6C, 0x20, 0x63, 0x66, 0x6D, 0x20, 0x6E, 0x6F, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, -+0x20, 0x66, 0x6F, 0x72, 0x20, 0x75, 0x73, 0x62, 0x0D, 0x0A, 0x00, 0x00, 0x63, 0x66, 0x6D, 0x20, 0x66, 0x6C, 0x75, 0x73, -+0x68, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x73, 0x6E, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x73, 0x74, 0x3D, 0x25, 0x64, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x63, 0x66, 0x6D, 0x73, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x73, 0x6E, 0x3D, 0x25, 0x64, 0x2C, -+0x20, 0x73, 0x74, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x61, 0x67, 0x67, 0x5F, 0x64, 0x65, 0x73, 0x63, -+0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x79, 0x5F, 0x69, 0x64, 0x78, 0x5F, -+0x68, 0x77, 0x20, 0x3E, 0x3D, 0x20, 0x4D, 0x4D, 0x5F, 0x53, 0x45, 0x43, 0x5F, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4C, 0x54, -+0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x43, 0x4F, 0x55, 0x4E, 0x54, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x65, 0x76, 0x74, 0x5F, 0x67, -+0x65, 0x74, 0x28, 0x29, 0x20, 0x26, 0x20, 0x65, 0x76, 0x74, 0x5F, 0x62, 0x69, 0x74, 0x00, 0x00, 0x74, 0x78, 0x64, 0x65, -+0x73, 0x63, 0x5F, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, 0x00, -+0x62, 0x75, 0x67, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x73, 0x64, 0x69, 0x6F, 0x20, 0x74, 0x61, 0x69, 0x6C, 0x20, 0x65, 0x72, -+0x72, 0x6F, 0x72, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, -+0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x28, 0x74, 0x68, 0x64, 0x2D, 0x3E, 0x64, 0x61, -+0x74, 0x61, 0x73, 0x74, 0x61, 0x72, 0x74, 0x70, 0x74, 0x72, 0x20, 0x26, 0x20, 0x30, 0x78, 0x30, 0x31, 0x29, 0x20, 0x3D, -+0x3D, 0x20, 0x30, 0x00, 0x62, 0x61, 0x6E, 0x64, 0x20, 0x21, 0x3D, 0x20, 0x50, 0x48, 0x59, 0x5F, 0x42, 0x41, 0x4E, 0x44, -+0x5F, 0x4D, 0x41, 0x58, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x65, 0x72, 0x72, -+0x6F, 0x72, 0x3A, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x6E, 0x6F, 0x20, 0x70, 0x72, 0x6F, 0x62, 0x65, 0x20, 0x62, 0x75, 0x66, -+0x3A, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x74, 0x78, 0x64, 0x65, 0x73, 0x63, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, -+0x4C, 0x4C, 0x00, 0x00, 0x61, 0x67, 0x67, 0x5F, 0x64, 0x65, 0x73, 0x63, 0x5F, 0x6E, 0x65, 0x77, 0x20, 0x21, 0x3D, 0x20, -+0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6F, 0x5F, 0x6C, 0x69, 0x73, 0x74, 0x5F, 0x70, 0x69, 0x63, 0x6B, -+0x28, 0x26, 0x74, 0x78, 0x6C, 0x69, 0x73, 0x74, 0x2D, 0x3E, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x73, -+0x29, 0x20, 0x3D, 0x3D, 0x20, 0x26, 0x61, 0x67, 0x67, 0x5F, 0x64, 0x65, 0x73, 0x63, 0x5F, 0x6F, 0x6C, 0x64, 0x2D, 0x3E, -+0x6C, 0x69, 0x73, 0x74, 0x5F, 0x68, 0x64, 0x72, 0x00, 0x00, 0x00, 0x00, 0x74, 0x78, 0x64, 0x65, 0x73, 0x63, 0x5F, 0x6E, -+0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x5F, 0x6D, -+0x6F, 0x64, 0x20, 0x3E, 0x20, 0x46, 0x4F, 0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, 0x5F, 0x4E, 0x4F, 0x4E, 0x5F, 0x48, -+0x54, 0x5F, 0x44, 0x55, 0x50, 0x5F, 0x4F, 0x46, 0x44, 0x4D, 0x00, 0x00, 0x28, 0x2A, 0x6E, 0x73, 0x73, 0x20, 0x3E, 0x20, -+0x30, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x2A, 0x6E, 0x73, 0x73, 0x20, 0x3C, 0x3D, 0x20, 0x34, 0x29, 0x00, 0x00, 0x00, -+0x6D, 0x63, 0x73, 0x5F, 0x69, 0x64, 0x78, 0x20, 0x3C, 0x3D, 0x20, 0x39, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x63, 0x73, 0x5F, -+0x69, 0x64, 0x78, 0x20, 0x3C, 0x3D, 0x20, 0x33, 0x31, 0x00, 0x00, 0x00, 0x69, 0x73, 0x5F, 0x6D, 0x70, 0x64, 0x75, 0x5F, -+0x66, 0x69, 0x72, 0x73, 0x74, 0x28, 0x74, 0x78, 0x64, 0x65, 0x73, 0x63, 0x29, 0x00, 0x00, 0x00, 0x21, 0x69, 0x73, 0x5F, -+0x6D, 0x70, 0x64, 0x75, 0x5F, 0x6C, 0x61, 0x73, 0x74, 0x28, 0x74, 0x78, 0x64, 0x65, 0x73, 0x63, 0x29, 0x00, 0x00, 0x00, -+0x74, 0x78, 0x64, 0x65, 0x73, 0x63, 0x5F, 0x70, 0x72, 0x65, 0x76, 0x20, 0x3D, 0x3D, 0x20, 0x61, 0x67, 0x67, 0x5F, 0x64, -+0x65, 0x73, 0x63, 0x5F, 0x6F, 0x6C, 0x64, 0x2D, 0x3E, 0x74, 0x78, 0x64, 0x65, 0x73, 0x63, 0x5F, 0x6C, 0x61, 0x73, 0x74, -+0x00, 0x00, 0x00, 0x00, 0x61, 0x5F, 0x74, 0x68, 0x64, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x26, 0x20, 0x52, -+0x45, 0x54, 0x52, 0x59, 0x5F, 0x4C, 0x49, 0x4D, 0x49, 0x54, 0x5F, 0x52, 0x45, 0x41, 0x43, 0x48, 0x45, 0x44, 0x5F, 0x42, -+0x49, 0x54, 0x00, 0x00, 0x1A, 0x00, 0x1C, 0x00, 0x36, 0x00, 0x3C, 0x00, 0x75, 0x00, 0x82, 0x00, 0xEA, 0x00, 0x04, 0x01, -+0x34, 0x00, 0x39, 0x00, 0x6C, 0x00, 0x78, 0x00, 0xEA, 0x00, 0x04, 0x01, 0xD4, 0x01, 0x08, 0x02, 0x4E, 0x00, 0x56, 0x00, -+0xA2, 0x00, 0xB4, 0x00, 0x5F, 0x01, 0x86, 0x01, 0xBE, 0x02, 0x0C, 0x03, 0x68, 0x00, 0x73, 0x00, 0xD8, 0x00, 0xF0, 0x00, -+0xD4, 0x01, 0x08, 0x02, 0xA8, 0x03, 0x10, 0x04, 0x9C, 0x00, 0xAD, 0x00, 0x44, 0x01, 0x68, 0x01, 0xBE, 0x02, 0x0C, 0x03, -+0x7C, 0x05, 0x18, 0x06, 0xD0, 0x00, 0xE7, 0x00, 0xB0, 0x01, 0xE0, 0x01, 0xA8, 0x03, 0x10, 0x04, 0x50, 0x07, 0x20, 0x08, -+0xEA, 0x00, 0x04, 0x01, 0xE6, 0x01, 0x1C, 0x02, 0x1D, 0x04, 0x92, 0x04, 0x3A, 0x08, 0x24, 0x09, 0x04, 0x01, 0x20, 0x01, -+0x1C, 0x02, 0x58, 0x02, 0x92, 0x04, 0x14, 0x05, 0x24, 0x09, 0x28, 0x0A, 0x38, 0x01, 0x5A, 0x01, 0x88, 0x02, 0xD0, 0x02, -+0x7C, 0x05, 0x18, 0x06, 0xF8, 0x0A, 0x30, 0x0C, 0x5A, 0x01, 0x81, 0x01, 0xD0, 0x02, 0x20, 0x03, 0x18, 0x06, 0xC5, 0x06, -+0x30, 0x0C, 0x8A, 0x0D, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x08, 0x09, 0x02, 0x02, 0x04, 0x04, 0x08, 0x09, 0x0F, 0x11, -+0x03, 0x03, 0x06, 0x06, 0x0B, 0x0D, 0x16, 0x19, 0x04, 0x04, 0x07, 0x08, 0x0F, 0x11, 0x1E, 0x21, 0x05, 0x06, 0x0B, 0x0C, -+0x16, 0x19, 0x2C, 0x31, 0x07, 0x08, 0x0E, 0x0F, 0x1E, 0x21, 0x3B, 0x41, 0x08, 0x09, 0x10, 0x11, 0x21, 0x25, 0x42, 0x4A, -+0x09, 0x0A, 0x11, 0x13, 0x25, 0x29, 0x4A, 0x52, 0x0A, 0x0B, 0x15, 0x17, 0x2C, 0x31, 0x58, 0x62, 0x0B, 0x0D, 0x17, 0x19, -+0x31, 0x37, 0x62, 0x6D, 0x74, 0x78, 0x6C, 0x5F, 0x68, 0x65, 0x5F, 0x65, 0x64, 0x63, 0x61, 0x5F, 0x71, 0x75, 0x65, 0x75, -+0x65, 0x5F, 0x68, 0x61, 0x6C, 0x74, 0x65, 0x64, 0x28, 0x61, 0x63, 0x29, 0x00, 0x00, 0x00, 0x00, 0x68, 0x64, 0x72, 0x64, -+0x65, 0x73, 0x63, 0x2D, 0x3E, 0x66, 0x72, 0x6D, 0x6C, 0x65, 0x6E, 0x20, 0x3E, 0x3D, 0x20, 0x48, 0x45, 0x5F, 0x54, 0x52, -+0x49, 0x47, 0x5F, 0x46, 0x52, 0x4D, 0x5F, 0x4D, 0x49, 0x4E, 0x5F, 0x4C, 0x45, 0x4E, 0x00, 0x00, 0x66, 0x6F, 0x72, 0x6D, -+0x61, 0x74, 0x5F, 0x6D, 0x6F, 0x64, 0x20, 0x3D, 0x3D, 0x20, 0x46, 0x4F, 0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, 0x5F, -+0x48, 0x45, 0x5F, 0x53, 0x55, 0x00, 0x00, 0x00, 0x6D, 0x63, 0x73, 0x5F, 0x69, 0x64, 0x78, 0x20, 0x3C, 0x3D, 0x20, 0x31, -+0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, -+0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, -+0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x07, 0x00, -+0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x07, 0x00, 0x01, 0x00, 0x01, 0x00, -+0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, -+0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, -+0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, -+0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, -+0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, -+0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, -+0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, -+0x22, 0x00, 0x20, 0x00, 0x1D, 0x00, 0x90, 0x00, 0x88, 0x00, 0x7A, 0x00, 0x44, 0x00, 0x41, 0x00, 0x3A, 0x00, 0x20, 0x01, -+0x10, 0x01, 0xF5, 0x00, 0x67, 0x00, 0x61, 0x00, 0x57, 0x00, 0xB0, 0x01, 0x98, 0x01, 0x6F, 0x01, 0x89, 0x00, 0x82, 0x00, -+0x75, 0x00, 0x40, 0x02, 0x20, 0x02, 0xEA, 0x01, 0xCE, 0x00, 0xC3, 0x00, 0xAF, 0x00, 0x60, 0x03, 0x30, 0x03, 0xDF, 0x02, -+0x13, 0x01, 0x04, 0x01, 0xEA, 0x00, 0x80, 0x04, 0x40, 0x04, 0xD4, 0x03, 0x35, 0x01, 0x24, 0x01, 0x07, 0x01, 0x11, 0x05, -+0xC9, 0x04, 0x4E, 0x04, 0x58, 0x01, 0x45, 0x01, 0x24, 0x01, 0xA1, 0x05, 0x51, 0x05, 0xC9, 0x04, 0x9C, 0x01, 0x86, 0x01, -+0x5F, 0x01, 0xC1, 0x06, 0x61, 0x06, 0xBE, 0x05, 0xCA, 0x01, 0xB1, 0x01, 0x86, 0x01, 0x81, 0x07, 0x16, 0x07, 0x61, 0x06, -+0x04, 0x02, 0xE7, 0x01, 0xB6, 0x01, 0x71, 0x08, 0xF9, 0x07, 0x2D, 0x07, 0x3D, 0x02, 0x1D, 0x02, 0xE7, 0x01, 0x61, 0x09, -+0xDC, 0x08, 0xF9, 0x07, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, -+0x02, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x0C, 0x00, -+0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x13, 0x00, 0x12, 0x00, 0x10, 0x00, 0x07, 0x00, 0x07, 0x00, 0x06, 0x00, 0x1C, 0x00, -+0x1A, 0x00, 0x17, 0x00, 0x09, 0x00, 0x09, 0x00, 0x08, 0x00, 0x25, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x0A, 0x00, 0x0A, 0x00, -+0x09, 0x00, 0x29, 0x00, 0x27, 0x00, 0x23, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x2E, 0x00, 0x2B, 0x00, 0x27, 0x00, -+0x0D, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x37, 0x00, 0x34, 0x00, 0x2E, 0x00, 0x0F, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x3D, 0x00, -+0x39, 0x00, 0x34, 0x00, 0x11, 0x00, 0x10, 0x00, 0x0E, 0x00, 0x44, 0x00, 0x40, 0x00, 0x3A, 0x00, 0x12, 0x00, 0x11, 0x00, -+0x10, 0x00, 0x4C, 0x00, 0x47, 0x00, 0x40, 0x00, 0x08, 0x10, 0x20, 0x04, 0x50, 0x94, 0x15, 0x00, 0x98, 0x94, 0x15, 0x00, -+0x08, 0x94, 0x15, 0x00, 0x72, 0x68, 0x64, 0x2D, 0x3E, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5F, 0x70, 0x62, 0x64, 0x5F, 0x70, -+0x74, 0x72, 0x20, 0x21, 0x3D, 0x20, 0x30, 0x00, 0x6E, 0x6F, 0x20, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x62, 0x75, 0x66, 0x66, -+0x65, 0x72, 0x3A, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x72, 0x78, 0x62, 0x75, 0x66, 0x31, 0x20, 0x25, 0x30, 0x38, 0x78, 0x2C, -+0x25, 0x30, 0x38, 0x78, 0x3A, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x65, 0x6E, -+0x64, 0x20, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x77, -+0x72, 0x70, 0x74, 0x72, 0x20, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x72, 0x64, 0x70, 0x74, 0x72, 0x20, 0x25, 0x30, 0x38, -+0x78, 0x0D, 0x0A, 0x00, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x72, 0x65, 0x63, 0x6F, -+0x76, 0x65, 0x72, 0x79, 0x0D, 0x0A, 0x00, 0x00, 0x70, 0x64, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, -+0x70, 0x64, 0x2D, 0x3E, 0x70, 0x62, 0x64, 0x2E, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x61, 0x72, 0x74, 0x70, 0x74, 0x72, -+0x20, 0x21, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x00, 0x64, 0x6D, 0x61, 0x5F, 0x68, 0x64, 0x72, 0x64, 0x65, 0x73, 0x63, 0x2D, -+0x3E, 0x68, 0x64, 0x2E, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5F, 0x70, 0x62, 0x64, 0x5F, 0x70, 0x74, 0x72, 0x20, 0x3D, 0x3D, -+0x20, 0x30, 0x00, 0x00, 0x70, 0x62, 0x64, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x72, 0x78, 0x6C, 0x20, -+0x65, 0x72, 0x72, 0x2C, 0x20, 0x6E, 0x6F, 0x20, 0x62, 0x75, 0x66, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x6E, 0x6F, 0x20, 0x74, -+0x78, 0x5F, 0x64, 0x73, 0x63, 0x72, 0x5F, 0x68, 0x64, 0x72, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x6F, 0x20, 0x74, -+0x78, 0x5F, 0x64, 0x73, 0x63, 0x72, 0x5F, 0x68, 0x64, 0x72, 0x21, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x6D, 0x70, 0x64, 0x75, -+0x5F, 0x6C, 0x65, 0x6E, 0x20, 0x21, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x00, 0x6D, 0x70, 0x64, 0x75, 0x5F, 0x6C, 0x65, 0x6E, -+0x20, 0x3C, 0x3D, 0x20, 0x52, 0x57, 0x4E, 0x58, 0x5F, 0x4D, 0x41, 0x58, 0x5F, 0x41, 0x4D, 0x53, 0x44, 0x55, 0x5F, 0x52, -+0x58, 0x00, 0x00, 0x00, 0x72, 0x68, 0x64, 0x2D, 0x3E, 0x75, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6E, 0x72, 0x78, 0x20, -+0x3D, 0x3D, 0x20, 0x52, 0x58, 0x5F, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x5F, 0x44, 0x45, 0x53, 0x43, 0x5F, 0x50, 0x41, -+0x54, 0x54, 0x45, 0x52, 0x4E, 0x00, 0x00, 0x00, 0x72, 0x78, 0x62, 0x75, 0x66, 0x32, 0x20, 0x25, 0x30, 0x38, 0x78, 0x2C, -+0x25, 0x30, 0x38, 0x78, 0x3A, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x65, 0x6E, -+0x64, 0x20, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x77, -+0x72, 0x70, 0x74, 0x72, 0x20, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x72, 0x64, 0x70, 0x74, 0x72, 0x20, 0x25, 0x30, 0x38, -+0x78, 0x0D, 0x0A, 0x00, 0x25, 0x73, 0x3A, 0x20, 0x73, 0x74, 0x61, 0x5F, 0x69, 0x64, 0x78, 0x3D, 0x25, 0x64, 0x0A, 0x00, -+0x73, 0x74, 0x61, 0x5F, 0x6D, 0x67, 0x6D, 0x74, 0x5F, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x00, 0x00, 0x00, -+0x73, 0x74, 0x61, 0x5F, 0x6D, 0x67, 0x6D, 0x74, 0x5F, 0x75, 0x6E, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x00, -+0x6D, 0x61, 0x63, 0x20, 0x69, 0x73, 0x3A, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x70, 0x32, 0x70, 0x3D, 0x25, -+0x64, 0x0D, 0x0A, 0x00, 0x73, 0x65, 0x74, 0x20, 0x6D, 0x61, 0x63, 0x3A, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x2C, 0x20, 0x6D, -+0x61, 0x73, 0x6B, 0x3A, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x2C, 0x70, 0x32, 0x70, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, -+0x76, 0x69, 0x66, 0x2D, 0x3E, 0x70, 0x32, 0x70, 0x5F, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x20, 0x21, 0x3D, 0x20, 0x50, 0x32, -+0x50, 0x5F, 0x49, 0x4E, 0x56, 0x41, 0x4C, 0x49, 0x44, 0x5F, 0x49, 0x44, 0x58, 0x00, 0x00, 0x00, 0x25, 0x73, 0x3A, 0x25, -+0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x76, 0x69, 0x66, 0x20, -+0x75, 0x6E, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x3A, 0x25, 0x64, 0x2C, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, -+0x76, 0x69, 0x66, 0x20, 0x75, 0x6E, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x6D, 0x67, 0x6D, 0x74, 0x3A, -+0x25, 0x64, 0x0A, 0x00, 0x25, 0x73, 0x3A, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, -+0x76, 0x69, 0x66, 0x5F, 0x6D, 0x67, 0x6D, 0x74, 0x5F, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x00, 0x00, 0x00, -+0x76, 0x69, 0x66, 0x5F, 0x6D, 0x67, 0x6D, 0x74, 0x5F, 0x75, 0x6E, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x00, -+0x73, 0x6C, 0x65, 0x65, 0x70, 0x3A, 0x6C, 0x69, 0x6E, 0x6B, 0x6C, 0x6F, 0x73, 0x73, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0x6E, 0x78, 0x6D, 0x61, 0x63, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x5F, 0x6F, 0x6E, 0x5F, 0x61, 0x69, 0x72, 0x5F, 0x76, 0x61, -+0x6C, 0x69, 0x64, 0x5F, 0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x20, 0x21, 0x3D, 0x20, 0x30, 0x00, 0x64, 0x74, 0x69, 0x6D, -+0x3A, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x2A, 0x28, 0x76, 0x6F, -+0x6C, 0x61, 0x74, 0x69, 0x6C, 0x65, 0x20, 0x75, 0x69, 0x6E, 0x74, 0x38, 0x5F, 0x74, 0x20, 0x2A, 0x29, 0x26, 0x67, 0x5F, -+0x61, 0x6F, 0x6E, 0x5F, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2E, 0x64, 0x74, 0x69, 0x6D, 0x5F, 0x63, 0x6E, 0x74, 0x5F, -+0x61, 0x6F, 0x6E, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x20, 0x3C, 0x20, 0x2A, 0x28, 0x76, 0x6F, 0x6C, 0x61, 0x74, 0x69, -+0x6C, 0x65, 0x20, 0x75, 0x69, 0x6E, 0x74, 0x38, 0x5F, 0x74, 0x20, 0x2A, 0x29, 0x26, 0x67, 0x5F, 0x61, 0x6F, 0x6E, 0x5F, -+0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2E, 0x64, 0x74, 0x69, 0x6D, 0x5F, 0x70, 0x65, 0x72, 0x69, 0x6F, 0x64, 0x5F, 0x61, -+0x6F, 0x6E, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x62, 0x63, 0x6E, 0x3A, 0x6C, 0x69, 0x6E, 0x6B, -+0x6C, 0x6F, 0x73, 0x73, 0x0D, 0x0A, 0x00, 0x00, 0x4C, 0x2C, 0x00, 0x00, 0x9B, 0x84, 0x4B, 0x65, 0x79, 0x69, 0x64, 0x78, -+0x20, 0x69, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x2C, 0x25, 0x30, 0x32, 0x58, 0x0A, 0x00, 0x00, 0x9B, 0x84, 0x49, 0x6E, -+0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x6B, 0x65, 0x79, 0x69, 0x64, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x9B, 0x84, 0x49, 0x6E, -+0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x53, 0x54, 0x41, 0x3A, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x76, 0x69, 0x66, 0x5F, -+0x73, 0x74, 0x61, 0x20, 0x3D, 0x3D, 0x20, 0x76, 0x69, 0x66, 0x00, 0x00, 0x54, 0x3D, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x42, 0x43, 0x4E, 0x3A, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x62, 0x63, 0x6E, 0x20, -+0x64, 0x6F, 0x6E, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x0D, 0x0A, 0x00, 0x00, 0x66, 0x63, 0x73, 0x20, -+0x6F, 0x6B, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x66, 0x63, 0x73, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x6F, 0x6B, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x69, 0x64, 0x6C, 0x65, 0x20, 0x65, 0x72, 0x72, 0x0D, 0x0A, 0x00, 0x00, 0x69, 0x64, 0x6C, 0x65, -+0x20, 0x69, 0x6E, 0x74, 0x20, 0x65, 0x72, 0x72, 0x0D, 0x0A, 0x00, 0x00, 0x65, 0x76, 0x74, 0x20, 0x21, 0x3D, 0x20, 0x4D, -+0x4D, 0x5F, 0x54, 0x42, 0x54, 0x54, 0x5F, 0x45, 0x56, 0x54, 0x5F, 0x4D, 0x41, 0x53, 0x4B, 0x00, 0x61, 0x64, 0x64, 0x20, -+0x67, 0x74, 0x6B, 0x3A, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x73, 0x74, 0x61, 0x5F, 0x69, 0x64, 0x78, 0x20, -+0x3C, 0x20, 0x53, 0x54, 0x41, 0x5F, 0x4D, 0x41, 0x58, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x20, 0x70, 0x74, 0x6B, 0x3A, -+0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, -+0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x4D, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x4D, 0x4D, 0x5F, 0x48, 0x4F, 0x53, 0x54, -+0x5F, 0x42, 0x59, 0x50, 0x41, 0x53, 0x53, 0x45, 0x44, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, -+0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x4D, 0x4D, 0x29, 0x20, 0x21, 0x3D, 0x20, 0x4D, 0x4D, 0x5F, -+0x4E, 0x4F, 0x5F, 0x49, 0x44, 0x4C, 0x45, 0x00, 0x66, 0x6F, 0x72, 0x63, 0x65, 0x20, 0x69, 0x64, 0x6C, 0x65, 0x20, 0x72, -+0x65, 0x71, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6F, 0x72, 0x63, 0x65, 0x20, 0x69, 0x64, 0x6C, 0x65, 0x20, 0x65, -+0x78, 0x69, 0x74, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x28, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, -+0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x4D, 0x4D, 0x29, 0x20, 0x21, 0x3D, 0x20, 0x4D, 0x4D, 0x5F, 0x48, 0x4F, 0x53, -+0x54, 0x5F, 0x42, 0x59, 0x50, 0x41, 0x53, 0x53, 0x45, 0x44, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x6B, 0x65, 0x5F, 0x73, -+0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x4D, 0x4D, 0x29, 0x20, 0x21, 0x3D, -+0x20, 0x4D, 0x4D, 0x5F, 0x49, 0x44, 0x4C, 0x45, 0x29, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x2D, 0x3E, 0x6B, -+0x65, 0x79, 0x5F, 0x69, 0x64, 0x78, 0x20, 0x3C, 0x20, 0x4D, 0x41, 0x43, 0x5F, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4C, 0x54, -+0x5F, 0x4D, 0x46, 0x50, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x43, 0x4F, 0x55, 0x4E, 0x54, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, -+0x6D, 0x2D, 0x3E, 0x6B, 0x65, 0x79, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x3C, 0x3D, 0x20, 0x4D, 0x41, 0x43, -+0x5F, 0x53, 0x45, 0x43, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x45, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, -+0x6D, 0x2D, 0x3E, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5F, 0x73, 0x75, 0x69, 0x74, 0x65, 0x20, 0x3C, 0x3D, 0x20, 0x4D, -+0x41, 0x43, 0x5F, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x5F, 0x42, 0x49, 0x50, 0x5F, 0x43, 0x4D, 0x41, 0x43, 0x5F, 0x31, -+0x32, 0x38, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x2D, 0x3E, 0x68, 0x77, 0x5F, 0x6B, 0x65, 0x79, 0x5F, 0x69, 0x64, -+0x78, 0x20, 0x3C, 0x3D, 0x20, 0x4D, 0x4D, 0x5F, 0x53, 0x45, 0x43, 0x5F, 0x4D, 0x41, 0x58, 0x5F, 0x4D, 0x46, 0x50, 0x5F, -+0x4B, 0x45, 0x59, 0x5F, 0x4E, 0x42, 0x52, 0x00, 0x76, 0x69, 0x66, 0x2D, 0x3E, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3D, 0x3D, -+0x20, 0x56, 0x49, 0x46, 0x5F, 0x53, 0x54, 0x41, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, -+0x5F, 0x67, 0x65, 0x74, 0x28, 0x64, 0x65, 0x73, 0x74, 0x5F, 0x69, 0x64, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x4D, 0x4D, 0x5F, -+0x49, 0x44, 0x4C, 0x45, 0x00, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x20, 0x6D, 0x75, 0x20, 0x65, 0x64, 0x63, 0x61, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x44, 0x48, 0x43, 0x50, 0x65, 0x64, 0x3A, 0x25, 0x64, 0x2C, 0x25, 0x78, 0x2E, 0x0D, 0x0A, 0x00, -+0x73, 0x65, 0x74, 0x20, 0x61, 0x67, 0x67, 0x20, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x3D, 0x25, 0x64, 0x2C, 0x20, -+0x64, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x5F, 0x72, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x67, 0x65, 0x74, 0x20, -+0x6D, 0x61, 0x63, 0x61, 0x64, 0x64, 0x72, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, -+0x73, 0x65, 0x74, 0x20, 0x74, 0x78, 0x6F, 0x70, 0x20, 0x72, 0x65, 0x71, 0x3A, 0x20, 0x62, 0x6B, 0x3A, 0x25, 0x78, 0x2C, -+0x20, 0x62, 0x65, 0x3A, 0x25, 0x78, 0x2C, 0x20, 0x76, 0x69, 0x3A, 0x25, 0x78, 0x2C, 0x20, 0x76, 0x6F, 0x3A, 0x25, 0x78, -+0x2C, 0x20, 0x6C, 0x6F, 0x6E, 0x67, 0x6E, 0x61, 0x76, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x63, 0x66, 0x65, 0x3D, 0x25, 0x64, -+0x0A, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x20, 0x76, 0x65, 0x6E, 0x64, 0x6F, 0x72, 0x20, 0x74, 0x72, 0x78, 0x3A, 0x20, -+0x30, 0x78, 0x25, 0x78, 0x2C, 0x20, 0x30, 0x78, 0x25, 0x78, 0x2C, 0x20, 0x30, 0x78, 0x25, 0x78, 0x2C, 0x20, 0x30, 0x78, -+0x25, 0x78, 0x2C, 0x20, 0x30, 0x78, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x20, 0x73, -+0x74, 0x61, 0x72, 0x74, 0x0D, 0x0A, 0x00, 0x00, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x20, 0x73, 0x74, 0x6F, 0x70, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x69, 0x73, 0x20, 0x35, 0x67, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x73, 0x77, 0x5F, 0x65, 0x6E, 0x3D, -+0x25, 0x64, 0x2C, 0x20, 0x76, 0x65, 0x6E, 0x64, 0x6F, 0x72, 0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x3D, 0x30, 0x78, 0x25, 0x78, -+0x0D, 0x0A, 0x00, 0x00, 0x72, 0x65, 0x61, 0x64, 0x20, 0x78, 0x74, 0x61, 0x6C, 0x5F, 0x63, 0x61, 0x70, 0x20, 0x65, 0x66, -+0x75, 0x73, 0x65, 0x3D, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x75, 0x73, 0x65, 0x72, 0x20, 0x63, 0x61, 0x70, -+0x3A, 0x30, 0x78, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x75, 0x73, 0x65, 0x72, 0x20, 0x63, 0x61, 0x70, 0x5F, 0x66, 0x69, 0x6E, -+0x65, 0x3A, 0x30, 0x78, 0x25, 0x78, 0x0A, 0x00, 0x73, 0x65, 0x74, 0x20, 0x78, 0x74, 0x61, 0x6C, 0x5F, 0x63, 0x61, 0x70, -+0x20, 0x30, 0x78, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x73, 0x65, 0x74, 0x20, 0x78, 0x74, 0x61, 0x6C, 0x5F, 0x63, 0x61, 0x70, -+0x5F, 0x66, 0x69, 0x6E, 0x65, 0x20, 0x30, 0x78, 0x25, 0x78, 0x0A, 0x00, 0x32, 0x2E, 0x34, 0x67, 0x3A, 0x62, 0x65, 0x66, -+0x6F, 0x72, 0x65, 0x20, 0x25, 0x64, 0x3A, 0x20, 0x64, 0x63, 0x3D, 0x25, 0x34, 0x78, 0x2C, 0x20, 0x76, 0x63, 0x6D, 0x3D, -+0x25, 0x34, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x32, 0x2E, 0x34, 0x67, 0x3A, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x20, -+0x25, 0x64, 0x3A, 0x20, 0x64, 0x63, 0x3D, 0x25, 0x34, 0x78, 0x2C, 0x20, 0x76, 0x63, 0x6D, 0x3D, 0x25, 0x34, 0x78, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x35, 0x67, 0x3A, 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x20, 0x25, 0x64, 0x3A, 0x20, 0x64, 0x63, -+0x3D, 0x25, 0x34, 0x78, 0x2C, 0x20, 0x76, 0x63, 0x6D, 0x3D, 0x25, 0x34, 0x78, 0x0D, 0x0A, 0x00, 0x35, 0x67, 0x3A, 0x61, -+0x66, 0x74, 0x65, 0x72, 0x20, 0x20, 0x25, 0x64, 0x3A, 0x20, 0x64, 0x63, 0x3D, 0x25, 0x34, 0x78, 0x2C, 0x20, 0x76, 0x63, -+0x6D, 0x3D, 0x25, 0x34, 0x78, 0x0D, 0x0A, 0x00, 0x6E, 0x78, 0x6D, 0x61, 0x63, 0x5F, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, -+0x74, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x48, 0x57, -+0x5F, 0x49, 0x44, 0x4C, 0x45, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, -+0x28, 0x64, 0x65, 0x73, 0x74, 0x5F, 0x69, 0x64, 0x29, 0x20, 0x21, 0x3D, 0x20, 0x4D, 0x4D, 0x5F, 0x4E, 0x4F, 0x5F, 0x49, -+0x44, 0x4C, 0x45, 0x00, 0x76, 0x69, 0x66, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, -+0x3A, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x68, 0x65, 0x20, 0x65, -+0x6E, 0x61, 0x62, 0x6C, 0x65, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x66, 0x20, 0x73, 0x74, 0x61, 0x74, -+0x65, 0x20, 0x69, 0x6E, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3A, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, -+0xA8, 0x1F, 0x17, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x20, 0x70, 0x61, 0x73, 0x74, 0x3A, 0x20, -+0x63, 0x62, 0x3D, 0x25, 0x78, 0x2C, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x3D, 0x25, 0x78, 0x2C, 0x20, 0x63, 0x75, 0x72, 0x72, -+0x3D, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x68, 0x61, 0x6C, 0x5F, 0x6D, 0x61, 0x63, 0x68, 0x77, 0x5F, 0x74, -+0x69, 0x6D, 0x65, 0x5F, 0x70, 0x61, 0x73, 0x74, 0x28, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x29, 0x00, 0x74, 0x69, 0x6D, 0x65, -+0x72, 0x2D, 0x3E, 0x63, 0x62, 0x00, 0x00, 0x00, 0x25, 0x73, 0x3A, 0x20, 0x73, 0x74, 0x61, 0x20, 0x70, 0x72, 0x6F, 0x62, -+0x65, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x3A, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x25, 0x73, 0x3A, 0x20, 0x73, 0x74, 0x61, 0x20, -+0x70, 0x72, 0x6F, 0x62, 0x65, 0x20, 0x73, 0x75, 0x63, 0x63, 0x0A, 0x00, 0x6D, 0x6D, 0x5F, 0x62, 0x63, 0x6E, 0x5F, 0x65, -+0x6E, 0x76, 0x2E, 0x74, 0x78, 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x00, 0x00, 0x74, 0x68, 0x69, 0x73, 0x20, 0x77, 0x69, 0x6C, -+0x6C, 0x65, 0x20, 0x6E, 0x65, 0x76, 0x65, 0x72, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x0D, 0x0A, 0x00, 0x00, 0x00, -+0x61, 0x70, 0x6D, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x20, 0x6E, 0x75, 0x6C, 0x6C, 0x20, 0x74, 0x6F, 0x20, 0x70, 0x72, 0x6F, -+0x62, 0x65, 0x20, 0x73, 0x74, 0x61, 0x3A, 0x20, 0x73, 0x74, 0x61, 0x5F, 0x69, 0x64, 0x78, 0x3D, 0x25, 0x64, 0x0A, 0x00, -+0x21, 0x6D, 0x6D, 0x5F, 0x62, 0x63, 0x6E, 0x5F, 0x65, 0x6E, 0x76, 0x2E, 0x74, 0x78, 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x00, -+0x61, 0x70, 0x6D, 0x5F, 0x70, 0x72, 0x6F, 0x62, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x00, 0x00, -+0x28, 0x70, 0x32, 0x70, 0x67, 0x6F, 0x5F, 0x76, 0x69, 0x66, 0x2D, 0x3E, 0x63, 0x68, 0x61, 0x6E, 0x5F, 0x63, 0x74, 0x78, -+0x74, 0x2D, 0x3E, 0x70, 0x32, 0x70, 0x67, 0x6F, 0x5F, 0x76, 0x69, 0x66, 0x5F, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x20, 0x3D, -+0x3D, 0x20, 0x49, 0x4E, 0x56, 0x41, 0x4C, 0x49, 0x44, 0x5F, 0x56, 0x49, 0x46, 0x5F, 0x49, 0x44, 0x58, 0x29, 0x20, 0x7C, -+0x7C, 0x20, 0x28, 0x70, 0x32, 0x70, 0x67, 0x6F, 0x5F, 0x76, 0x69, 0x66, 0x2D, 0x3E, 0x63, 0x68, 0x61, 0x6E, 0x5F, 0x63, -+0x74, 0x78, 0x74, 0x2D, 0x3E, 0x70, 0x32, 0x70, 0x67, 0x6F, 0x5F, 0x76, 0x69, 0x66, 0x5F, 0x69, 0x6E, 0x64, 0x65, 0x78, -+0x20, 0x3D, 0x3D, 0x20, 0x70, 0x32, 0x70, 0x67, 0x6F, 0x5F, 0x76, 0x69, 0x66, 0x2D, 0x3E, 0x69, 0x6E, 0x64, 0x65, 0x78, -+0x29, 0x00, 0x00, 0x00, 0x6F, 0x74, 0x68, 0x5F, 0x63, 0x74, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x62, 0x5F, 0x76, -+0x69, 0x66, 0x5F, 0x6F, 0x74, 0x68, 0x5F, 0x63, 0x74, 0x78, 0x74, 0x20, 0x3E, 0x20, 0x31, 0x00, 0x6E, 0x6F, 0x61, 0x5F, -+0x69, 0x64, 0x78, 0x20, 0x3C, 0x20, 0x50, 0x32, 0x50, 0x5F, 0x4E, 0x4F, 0x41, 0x5F, 0x4E, 0x42, 0x5F, 0x4D, 0x41, 0x58, -+0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x66, 0x2D, 0x3E, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x20, 0x3C, 0x20, 0x33, 0x32, 0x00, -+0x76, 0x69, 0x66, 0x2D, 0x3E, 0x74, 0x62, 0x74, 0x74, 0x5F, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x2E, 0x70, 0x32, 0x70, -+0x5F, 0x6E, 0x6F, 0x61, 0x5F, 0x76, 0x69, 0x66, 0x5F, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x20, 0x3D, 0x3D, 0x20, 0x49, 0x4E, -+0x56, 0x41, 0x4C, 0x49, 0x44, 0x5F, 0x56, 0x49, 0x46, 0x5F, 0x49, 0x44, 0x58, 0x00, 0x00, 0x00, 0x63, 0x68, 0x5F, 0x73, -+0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, 0x63, 0x68, 0x61, 0x6E, -+0x5F, 0x65, 0x6E, 0x76, 0x2E, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x26, 0x20, 0x43, 0x48, 0x41, 0x4E, 0x5F, 0x52, -+0x4F, 0x43, 0x5F, 0x53, 0x43, 0x41, 0x4E, 0x5F, 0x50, 0x45, 0x4E, 0x44, 0x49, 0x4E, 0x47, 0x5F, 0x4D, 0x41, 0x53, 0x4B, -+0x00, 0x00, 0x00, 0x00, 0x28, 0x63, 0x68, 0x61, 0x6E, 0x5F, 0x65, 0x6E, 0x76, 0x2E, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, -+0x20, 0x26, 0x20, 0x43, 0x4F, 0x5F, 0x42, 0x49, 0x54, 0x28, 0x43, 0x48, 0x41, 0x4E, 0x5F, 0x45, 0x4E, 0x56, 0x5F, 0x52, -+0x4F, 0x43, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x00, 0x28, 0x63, 0x68, 0x61, -+0x6E, 0x5F, 0x65, 0x6E, 0x76, 0x2E, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x26, 0x20, 0x43, 0x4F, 0x5F, 0x42, 0x49, -+0x54, 0x28, 0x43, 0x48, 0x41, 0x4E, 0x5F, 0x45, 0x4E, 0x56, 0x5F, 0x53, 0x43, 0x41, 0x4E, 0x5F, 0x42, 0x49, 0x54, 0x29, -+0x29, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x28, 0x76, 0x6F, 0x69, 0x64, 0x20, 0x2A, 0x29, 0x63, 0x68, 0x5F, 0x73, -+0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x3D, 0x3D, 0x20, 0x65, 0x6E, 0x76, 0x00, 0x00, 0x00, 0x00, 0x63, 0x68, 0x61, 0x6E, -+0x5F, 0x65, 0x6E, 0x76, 0x2E, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x5F, 0x63, 0x74, 0x78, 0x74, 0x00, 0x00, 0x00, -+0x4E, 0x6F, 0x20, 0x63, 0x74, 0x78, 0x74, 0x20, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6C, 0x65, 0x64, 0x20, 0x70, 0x72, -+0x65, 0x5F, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x0A, 0x00, 0x00, 0x00, 0x63, 0x74, 0x78, 0x74, 0x2D, 0x3E, 0x69, 0x64, -+0x78, 0x20, 0x3D, 0x3D, 0x20, 0x43, 0x48, 0x41, 0x4E, 0x5F, 0x43, 0x54, 0x58, 0x54, 0x5F, 0x55, 0x4E, 0x55, 0x53, 0x45, -+0x44, 0x00, 0x00, 0x00, 0x72, 0x6F, 0x63, 0x3A, 0x20, 0x25, 0x64, 0x2C, 0x20, 0x64, 0x75, 0x72, 0x3D, 0x25, 0x64, 0x2C, -+0x20, 0x73, 0x74, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x63, 0x74, 0x78, 0x74, 0x2D, 0x3E, 0x6E, 0x62, -+0x5F, 0x6C, 0x69, 0x6E, 0x6B, 0x65, 0x64, 0x5F, 0x76, 0x69, 0x66, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, -+0x76, 0x69, 0x66, 0x2D, 0x3E, 0x63, 0x68, 0x61, 0x6E, 0x5F, 0x63, 0x74, 0x78, 0x74, 0x20, 0x3D, 0x3D, 0x20, 0x4E, 0x55, -+0x4C, 0x4C, 0x00, 0x00, 0x63, 0x68, 0x61, 0x6E, 0x5F, 0x65, 0x6E, 0x76, 0x2E, 0x6E, 0x62, 0x5F, 0x73, 0x63, 0x68, 0x65, -+0x64, 0x5F, 0x63, 0x74, 0x78, 0x74, 0x20, 0x3C, 0x3D, 0x20, 0x32, 0x00, 0x63, 0x68, 0x5F, 0x73, 0x77, 0x69, 0x74, 0x63, -+0x68, 0x00, 0x00, 0x00, 0x63, 0x68, 0x61, 0x6E, 0x20, 0x6C, 0x69, 0x6E, 0x6B, 0x3A, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, -+0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x63, 0x74, 0x78, 0x74, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, -+0x00, 0x00, 0x00, 0x00, 0x63, 0x68, 0x61, 0x6E, 0x20, 0x75, 0x6E, 0x6C, 0x69, 0x6E, 0x6B, 0x3A, 0x20, 0x25, 0x64, 0x2C, -+0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x63, 0x68, 0x61, 0x6E, -+0x5F, 0x65, 0x6E, 0x76, 0x2E, 0x6E, 0x62, 0x5F, 0x73, 0x63, 0x68, 0x65, 0x64, 0x5F, 0x63, 0x74, 0x78, 0x74, 0x20, 0x3C, -+0x3D, 0x20, 0x31, 0x00, 0x25, 0x73, 0x3A, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x70, 0x73, 0x3A, 0x6C, 0x69, 0x6E, 0x6B, 0x6C, -+0x6F, 0x73, 0x73, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x25, 0x73, 0x3A, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, -+0x70, 0x73, 0x5F, 0x65, 0x6E, 0x61, 0x62, 0x6C, 0x65, 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5F, 0x64, -+0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x00, 0x70, 0x73, 0x5F, 0x75, 0x70, 0x6D, 0x5F, 0x65, -+0x6E, 0x74, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5F, 0x75, 0x70, 0x6D, 0x5F, 0x65, 0x78, 0x69, 0x74, 0x00, -+0x76, 0x69, 0x66, 0x2D, 0x3E, 0x70, 0x32, 0x70, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x66, 0x2D, 0x3E, 0x70, 0x32, 0x70, -+0x20, 0x26, 0x26, 0x20, 0x28, 0x6E, 0x6F, 0x61, 0x5F, 0x69, 0x6E, 0x73, 0x74, 0x20, 0x3C, 0x20, 0x50, 0x32, 0x50, 0x5F, -+0x4E, 0x4F, 0x41, 0x5F, 0x4E, 0x42, 0x5F, 0x4D, 0x41, 0x58, 0x29, 0x00, 0x76, 0x69, 0x66, 0x2D, 0x3E, 0x70, 0x32, 0x70, -+0x5F, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x20, 0x3C, 0x20, 0x4E, 0x58, 0x5F, 0x50, 0x32, 0x50, 0x5F, 0x56, 0x49, 0x46, 0x5F, -+0x4D, 0x41, 0x58, 0x00, 0x74, 0x64, 0x73, 0x5F, 0x65, 0x6E, 0x76, 0x00, 0x25, 0x73, 0x3A, 0x25, 0x64, 0x0D, 0x0A, 0x00, -+0x70, 0x61, 0x72, 0x61, 0x6D, 0x2D, 0x3E, 0x63, 0x68, 0x61, 0x6E, 0x5F, 0x63, 0x6E, 0x74, 0x20, 0x3E, 0x20, 0x30, 0x00, -+0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x53, 0x43, -+0x41, 0x4E, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x53, 0x43, 0x41, 0x4E, 0x5F, 0x57, 0x41, 0x49, 0x54, 0x5F, 0x43, 0x48, 0x41, -+0x4E, 0x4E, 0x45, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, -+0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x53, 0x43, 0x41, 0x4E, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x53, 0x43, 0x41, 0x4E, 0x5F, -+0x57, 0x41, 0x49, 0x54, 0x5F, 0x42, 0x45, 0x41, 0x43, 0x4F, 0x4E, 0x5F, 0x50, 0x52, 0x4F, 0x42, 0x45, 0x5F, 0x52, 0x53, -+0x50, 0x00, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6E, 0x5F, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5F, 0x72, 0x65, 0x71, 0x5F, 0x68, -+0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6E, 0x5F, 0x63, 0x61, 0x6E, 0x63, 0x65, 0x6C, 0x5F, -+0x72, 0x65, 0x71, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00, 0x50, 0x21, 0x17, 0x00, 0x04, 0x00, 0x00, 0x00, -+0x73, 0x63, 0x61, 0x6E, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x63, 0x61, 0x6E, 0x63, 0x65, 0x6C, 0x5F, 0x63, 0x66, 0x6D, -+0x00, 0x00, 0x00, 0x00, 0x6E, 0x78, 0x6D, 0x61, 0x63, 0x5F, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x5F, 0x73, 0x74, -+0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x66, 0x28, 0x29, 0x20, 0x21, 0x3D, 0x20, 0x48, 0x57, 0x5F, 0x49, 0x44, 0x4C, -+0x45, 0x00, 0x00, 0x00, 0x21, 0x68, 0x61, 0x6C, 0x5F, 0x61, 0x6F, 0x6E, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x5F, 0x74, 0x69, -+0x6D, 0x65, 0x5F, 0x70, 0x61, 0x73, 0x74, 0x28, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x2D, 0x3E, 0x74, 0x69, 0x6D, 0x65, 0x20, -+0x2B, 0x20, 0x35, 0x30, 0x30, 0x30, 0x29, 0x00, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x3A, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, -+0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x20, 0x6B, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x20, 0x69, 0x6E, 0x20, 0x67, -+0x65, 0x6E, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x20, 0x61, 0x6E, 0x79, 0x6D, 0x6F, 0x72, 0x65, 0x0D, 0x0A, 0x00, 0x00, -+0x65, 0x72, 0x72, 0x6F, 0x72, 0x3A, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x20, 0x6D, -+0x6D, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x20, 0x69, 0x6E, 0x20, 0x67, 0x65, 0x6E, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x72, -+0x20, 0x61, 0x6E, 0x79, 0x6D, 0x6F, 0x72, 0x65, 0x0D, 0x0A, 0x00, 0x00, 0x21, 0x28, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x5F, -+0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x48, 0x41, 0x4C, 0x5F, 0x41, 0x43, 0x30, 0x5F, 0x54, 0x49, -+0x4D, 0x45, 0x52, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x5F, -+0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x48, 0x41, 0x4C, 0x5F, 0x41, 0x43, 0x31, 0x5F, 0x54, 0x49, -+0x4D, 0x45, 0x52, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x5F, -+0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x48, 0x41, 0x4C, 0x5F, 0x41, 0x43, 0x32, 0x5F, 0x54, 0x49, -+0x4D, 0x45, 0x52, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x5F, -+0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x48, 0x41, 0x4C, 0x5F, 0x41, 0x43, 0x33, 0x5F, 0x54, 0x49, -+0x4D, 0x45, 0x52, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x5F, -+0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x48, 0x41, 0x4C, 0x5F, 0x49, 0x44, 0x4C, 0x45, 0x5F, 0x54, -+0x49, 0x4D, 0x45, 0x52, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, 0x21, 0x28, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x5F, -+0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x48, 0x41, 0x4C, 0x5F, 0x48, 0x45, 0x5F, 0x54, 0x42, 0x5F, -+0x54, 0x49, 0x4D, 0x45, 0x52, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x21, 0x28, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x5F, -+0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x48, 0x41, 0x4C, 0x5F, 0x48, 0x49, 0x51, 0x5F, 0x54, 0x49, -+0x4D, 0x45, 0x52, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x52, 0x58, 0x5F, 0x46, 0x49, 0x46, 0x4F, 0x5F, -+0x4F, 0x56, 0x45, 0x52, 0x5F, 0x46, 0x4C, 0x4F, 0x57, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6E, 0x2C, 0x20, 0x68, 0x77, -+0x20, 0x72, 0x65, 0x63, 0x6F, 0x76, 0x65, 0x72, 0x79, 0x20, 0x69, 0x74, 0x73, 0x65, 0x6C, 0x66, 0x0D, 0x0A, 0x00, 0x00, -+0x21, 0x28, 0x67, 0x65, 0x6E, 0x69, 0x72, 0x71, 0x5F, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x4E, -+0x58, 0x4D, 0x41, 0x43, 0x5F, 0x50, 0x48, 0x59, 0x5F, 0x45, 0x52, 0x52, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, -+0x21, 0x28, 0x67, 0x65, 0x6E, 0x69, 0x72, 0x71, 0x5F, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x4E, -+0x58, 0x4D, 0x41, 0x43, 0x5F, 0x4D, 0x41, 0x43, 0x5F, 0x50, 0x48, 0x59, 0x49, 0x46, 0x5F, 0x55, 0x4E, 0x44, 0x45, 0x52, -+0x5F, 0x52, 0x55, 0x4E, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, 0x21, 0x28, 0x67, 0x65, 0x6E, 0x69, 0x72, 0x71, -+0x5F, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x4E, 0x58, 0x4D, 0x41, 0x43, 0x5F, 0x4D, 0x41, 0x43, -+0x5F, 0x50, 0x48, 0x59, 0x49, 0x46, 0x5F, 0x4F, 0x56, 0x45, 0x52, 0x46, 0x4C, 0x4F, 0x57, 0x5F, 0x42, 0x49, 0x54, 0x29, -+0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x67, 0x65, 0x6E, 0x69, 0x72, 0x71, 0x5F, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, -+0x20, 0x26, 0x20, 0x4E, 0x58, 0x4D, 0x41, 0x43, 0x5F, 0x50, 0x54, 0x5F, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x5F, 0x42, 0x49, -+0x54, 0x29, 0x00, 0x00, 0x21, 0x28, 0x67, 0x65, 0x6E, 0x69, 0x72, 0x71, 0x5F, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, -+0x20, 0x26, 0x20, 0x4E, 0x58, 0x4D, 0x41, 0x43, 0x5F, 0x41, 0x43, 0x5F, 0x30, 0x5F, 0x54, 0x58, 0x5F, 0x44, 0x4D, 0x41, -+0x5F, 0x44, 0x45, 0x41, 0x44, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x21, 0x28, 0x67, 0x65, 0x6E, 0x69, 0x72, 0x71, -+0x5F, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x4E, 0x58, 0x4D, 0x41, 0x43, 0x5F, 0x41, 0x43, 0x5F, -+0x31, 0x5F, 0x54, 0x58, 0x5F, 0x44, 0x4D, 0x41, 0x5F, 0x44, 0x45, 0x41, 0x44, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, -+0x21, 0x28, 0x67, 0x65, 0x6E, 0x69, 0x72, 0x71, 0x5F, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x4E, -+0x58, 0x4D, 0x41, 0x43, 0x5F, 0x41, 0x43, 0x5F, 0x32, 0x5F, 0x54, 0x58, 0x5F, 0x44, 0x4D, 0x41, 0x5F, 0x44, 0x45, 0x41, -+0x44, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x21, 0x28, 0x67, 0x65, 0x6E, 0x69, 0x72, 0x71, 0x5F, 0x70, 0x65, 0x6E, -+0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x4E, 0x58, 0x4D, 0x41, 0x43, 0x5F, 0x41, 0x43, 0x5F, 0x33, 0x5F, 0x54, 0x58, -+0x5F, 0x44, 0x4D, 0x41, 0x5F, 0x44, 0x45, 0x41, 0x44, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x21, 0x28, 0x67, 0x65, -+0x6E, 0x69, 0x72, 0x71, 0x5F, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x4E, 0x58, 0x4D, 0x41, 0x43, -+0x5F, 0x42, 0x43, 0x4E, 0x5F, 0x54, 0x58, 0x5F, 0x44, 0x4D, 0x41, 0x5F, 0x44, 0x45, 0x41, 0x44, 0x5F, 0x42, 0x49, 0x54, -+0x29, 0x00, 0x00, 0x00, 0x21, 0x28, 0x67, 0x65, 0x6E, 0x69, 0x72, 0x71, 0x5F, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, -+0x20, 0x26, 0x20, 0x4E, 0x58, 0x4D, 0x41, 0x43, 0x5F, 0x52, 0x58, 0x5F, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x5F, 0x44, -+0x4D, 0x41, 0x5F, 0x44, 0x45, 0x41, 0x44, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x67, 0x65, -+0x6E, 0x69, 0x72, 0x71, 0x5F, 0x70, 0x65, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x4E, 0x58, 0x4D, 0x41, 0x43, -+0x5F, 0x52, 0x58, 0x5F, 0x50, 0x41, 0x59, 0x4C, 0x4F, 0x41, 0x44, 0x5F, 0x44, 0x4D, 0x41, 0x5F, 0x44, 0x45, 0x41, 0x44, -+0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, 0x21, 0x28, 0x67, 0x65, 0x6E, 0x69, 0x72, 0x71, 0x5F, 0x70, 0x65, 0x6E, -+0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x4E, 0x58, 0x4D, 0x41, 0x43, 0x5F, 0x48, 0x57, 0x5F, 0x45, 0x52, 0x52, 0x5F, -+0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x67, 0x65, 0x6E, 0x69, 0x72, 0x71, 0x5F, 0x70, 0x65, 0x6E, -+0x64, 0x69, 0x6E, 0x67, 0x20, 0x26, 0x20, 0x4E, 0x58, 0x4D, 0x41, 0x43, 0x5F, 0x48, 0x49, 0x5F, 0x54, 0x58, 0x5F, 0x44, -+0x4D, 0x41, 0x5F, 0x44, 0x45, 0x41, 0x44, 0x5F, 0x42, 0x49, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, -+0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x08, 0x06, 0x04, 0x0B, 0x09, 0x07, 0x05, 0xA5, 0xC6, 0x84, 0xF8, 0x99, 0xEE, 0x8D, 0xF6, -+0x0D, 0xFF, 0xBD, 0xD6, 0xB1, 0xDE, 0x54, 0x91, 0x50, 0x60, 0x03, 0x02, 0xA9, 0xCE, 0x7D, 0x56, 0x19, 0xE7, 0x62, 0xB5, -+0xE6, 0x4D, 0x9A, 0xEC, 0x45, 0x8F, 0x9D, 0x1F, 0x40, 0x89, 0x87, 0xFA, 0x15, 0xEF, 0xEB, 0xB2, 0xC9, 0x8E, 0x0B, 0xFB, -+0xEC, 0x41, 0x67, 0xB3, 0xFD, 0x5F, 0xEA, 0x45, 0xBF, 0x23, 0xF7, 0x53, 0x96, 0xE4, 0x5B, 0x9B, 0xC2, 0x75, 0x1C, 0xE1, -+0xAE, 0x3D, 0x6A, 0x4C, 0x5A, 0x6C, 0x41, 0x7E, 0x02, 0xF5, 0x4F, 0x83, 0x5C, 0x68, 0xF4, 0x51, 0x34, 0xD1, 0x08, 0xF9, -+0x93, 0xE2, 0x73, 0xAB, 0x53, 0x62, 0x3F, 0x2A, 0x0C, 0x08, 0x52, 0x95, 0x65, 0x46, 0x5E, 0x9D, 0x28, 0x30, 0xA1, 0x37, -+0x0F, 0x0A, 0xB5, 0x2F, 0x09, 0x0E, 0x36, 0x24, 0x9B, 0x1B, 0x3D, 0xDF, 0x26, 0xCD, 0x69, 0x4E, 0xCD, 0x7F, 0x9F, 0xEA, -+0x1B, 0x12, 0x9E, 0x1D, 0x74, 0x58, 0x2E, 0x34, 0x2D, 0x36, 0xB2, 0xDC, 0xEE, 0xB4, 0xFB, 0x5B, 0xF6, 0xA4, 0x4D, 0x76, -+0x61, 0xB7, 0xCE, 0x7D, 0x7B, 0x52, 0x3E, 0xDD, 0x71, 0x5E, 0x97, 0x13, 0xF5, 0xA6, 0x68, 0xB9, 0x00, 0x00, 0x2C, 0xC1, -+0x60, 0x40, 0x1F, 0xE3, 0xC8, 0x79, 0xED, 0xB6, 0xBE, 0xD4, 0x46, 0x8D, 0xD9, 0x67, 0x4B, 0x72, 0xDE, 0x94, 0xD4, 0x98, -+0xE8, 0xB0, 0x4A, 0x85, 0x6B, 0xBB, 0x2A, 0xC5, 0xE5, 0x4F, 0x16, 0xED, 0xC5, 0x86, 0xD7, 0x9A, 0x55, 0x66, 0x94, 0x11, -+0xCF, 0x8A, 0x10, 0xE9, 0x06, 0x04, 0x81, 0xFE, 0xF0, 0xA0, 0x44, 0x78, 0xBA, 0x25, 0xE3, 0x4B, 0xF3, 0xA2, 0xFE, 0x5D, -+0xC0, 0x80, 0x8A, 0x05, 0xAD, 0x3F, 0xBC, 0x21, 0x48, 0x70, 0x04, 0xF1, 0xDF, 0x63, 0xC1, 0x77, 0x75, 0xAF, 0x63, 0x42, -+0x30, 0x20, 0x1A, 0xE5, 0x0E, 0xFD, 0x6D, 0xBF, 0x4C, 0x81, 0x14, 0x18, 0x35, 0x26, 0x2F, 0xC3, 0xE1, 0xBE, 0xA2, 0x35, -+0xCC, 0x88, 0x39, 0x2E, 0x57, 0x93, 0xF2, 0x55, 0x82, 0xFC, 0x47, 0x7A, 0xAC, 0xC8, 0xE7, 0xBA, 0x2B, 0x32, 0x95, 0xE6, -+0xA0, 0xC0, 0x98, 0x19, 0xD1, 0x9E, 0x7F, 0xA3, 0x66, 0x44, 0x7E, 0x54, 0xAB, 0x3B, 0x83, 0x0B, 0xCA, 0x8C, 0x29, 0xC7, -+0xD3, 0x6B, 0x3C, 0x28, 0x79, 0xA7, 0xE2, 0xBC, 0x1D, 0x16, 0x76, 0xAD, 0x3B, 0xDB, 0x56, 0x64, 0x4E, 0x74, 0x1E, 0x14, -+0xDB, 0x92, 0x0A, 0x0C, 0x6C, 0x48, 0xE4, 0xB8, 0x5D, 0x9F, 0x6E, 0xBD, 0xEF, 0x43, 0xA6, 0xC4, 0xA8, 0x39, 0xA4, 0x31, -+0x37, 0xD3, 0x8B, 0xF2, 0x32, 0xD5, 0x43, 0x8B, 0x59, 0x6E, 0xB7, 0xDA, 0x8C, 0x01, 0x64, 0xB1, 0xD2, 0x9C, 0xE0, 0x49, -+0xB4, 0xD8, 0xFA, 0xAC, 0x07, 0xF3, 0x25, 0xCF, 0xAF, 0xCA, 0x8E, 0xF4, 0xE9, 0x47, 0x18, 0x10, 0xD5, 0x6F, 0x88, 0xF0, -+0x6F, 0x4A, 0x72, 0x5C, 0x24, 0x38, 0xF1, 0x57, 0xC7, 0x73, 0x51, 0x97, 0x23, 0xCB, 0x7C, 0xA1, 0x9C, 0xE8, 0x21, 0x3E, -+0xDD, 0x96, 0xDC, 0x61, 0x86, 0x0D, 0x85, 0x0F, 0x90, 0xE0, 0x42, 0x7C, 0xC4, 0x71, 0xAA, 0xCC, 0xD8, 0x90, 0x05, 0x06, -+0x01, 0xF7, 0x12, 0x1C, 0xA3, 0xC2, 0x5F, 0x6A, 0xF9, 0xAE, 0xD0, 0x69, 0x91, 0x17, 0x58, 0x99, 0x27, 0x3A, 0xB9, 0x27, -+0x38, 0xD9, 0x13, 0xEB, 0xB3, 0x2B, 0x33, 0x22, 0xBB, 0xD2, 0x70, 0xA9, 0x89, 0x07, 0xA7, 0x33, 0xB6, 0x2D, 0x22, 0x3C, -+0x92, 0x15, 0x20, 0xC9, 0x49, 0x87, 0xFF, 0xAA, 0x78, 0x50, 0x7A, 0xA5, 0x8F, 0x03, 0xF8, 0x59, 0x80, 0x09, 0x17, 0x1A, -+0xDA, 0x65, 0x31, 0xD7, 0xC6, 0x84, 0xB8, 0xD0, 0xC3, 0x82, 0xB0, 0x29, 0x77, 0x5A, 0x11, 0x1E, 0xCB, 0x7B, 0xFC, 0xA8, -+0xD6, 0x6D, 0x3A, 0x2C, 0x64, 0x65, 0x6C, 0x61, 0x79, 0x20, 0x3E, 0x20, 0x30, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6C, 0x61, -+0x79, 0x20, 0x3C, 0x20, 0x4B, 0x45, 0x5F, 0x54, 0x49, 0x4D, 0x45, 0x52, 0x5F, 0x44, 0x45, 0x4C, 0x41, 0x59, 0x5F, 0x4D, -+0x41, 0x58, 0x00, 0x00, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x00, 0x00, 0x00, 0x21, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x7C, -+0x7C, 0x20, 0x21, 0x6B, 0x65, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x5F, 0x70, 0x61, 0x73, 0x74, 0x28, 0x66, 0x69, 0x72, 0x73, -+0x74, 0x2D, 0x3E, 0x74, 0x69, 0x6D, 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x73, 0x67, 0x20, 0x21, 0x3D, 0x20, 0x4E, -+0x55, 0x4C, 0x4C, 0x00, 0x9D, 0x80, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x6D, 0x73, -+0x67, 0x3A, 0x25, 0x78, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x73, 0x6B, 0x3A, 0x25, 0x78, 0x20, 0x74, 0x6F, 0x20, -+0x74, 0x73, 0x6B, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x74, 0x6F, 0x74, 0x61, 0x6C, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x3E, 0x3D, -+0x20, 0x73, 0x69, 0x7A, 0x65, 0x6F, 0x66, 0x28, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x6D, 0x62, 0x6C, 0x6F, 0x63, -+0x6B, 0x5F, 0x66, 0x72, 0x65, 0x65, 0x29, 0x00, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, -+0x4C, 0x00, 0x00, 0x00, 0x28, 0x75, 0x69, 0x6E, 0x74, 0x33, 0x32, 0x5F, 0x74, 0x29, 0x6D, 0x65, 0x6D, 0x5F, 0x70, 0x74, -+0x72, 0x20, 0x3E, 0x20, 0x28, 0x75, 0x69, 0x6E, 0x74, 0x33, 0x32, 0x5F, 0x74, 0x29, 0x6E, 0x6F, 0x64, 0x65, 0x00, 0x00, -+0x70, 0x72, 0x65, 0x76, 0x5F, 0x6E, 0x6F, 0x64, 0x65, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, -+0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x2D, 0x3E, 0x6D, 0x73, 0x67, 0x5F, 0x74, -+0x61, 0x62, 0x6C, 0x65, 0x5B, 0x69, 0x5D, 0x2E, 0x66, 0x75, 0x6E, 0x63, 0x00, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, -+0x20, 0x3C, 0x20, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x4D, 0x41, 0x58, 0x00, 0x6B, 0x65, 0x5F, 0x74, 0x61, 0x73, 0x6B, 0x5F, -+0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x00, 0x69, 0x64, 0x78, 0x20, 0x3C, 0x20, 0x54, 0x41, -+0x53, 0x4B, 0x5F, 0x44, 0x45, 0x53, 0x43, 0x5B, 0x74, 0x79, 0x70, 0x65, 0x5D, 0x2E, 0x69, 0x64, 0x78, 0x5F, 0x6D, 0x61, -+0x78, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x69, 0x64, 0x5F, 0x70, 0x74, 0x72, 0x00, 0x00, -+0x80, 0x9D, 0x73, 0x65, 0x74, 0x20, 0x74, 0x73, 0x6B, 0x3A, 0x25, 0x78, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0x9A, 0x80, 0x4E, 0x6F, 0x20, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x20, 0x66, -+0x6F, 0x72, 0x20, 0x6D, 0x73, 0x67, 0x3A, 0x25, 0x78, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x73, 0x6B, 0x3A, 0x25, -+0x78, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x73, 0x6B, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x24, 0x9F, 0x15, 0x00, -+0x1C, 0x9F, 0x15, 0x00, 0xCC, 0x9C, 0x17, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xB5, 0x15, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0xA4, 0x15, 0x00, 0xF0, 0x9F, 0x17, 0x00, -+0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x20, 0xBF, 0x15, 0x00, 0x18, 0xBF, 0x15, 0x00, 0xA4, 0xBA, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x8C, 0xB8, 0x15, 0x00, 0xE0, 0xB8, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xBB, 0x15, 0x00, -+0x60, 0xBA, 0x17, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xBE, 0x15, 0x00, 0x90, 0xBA, 0x17, 0x00, -+0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xC2, 0x15, 0x00, 0xF4, 0xDF, 0x17, 0x00, 0x05, 0x00, 0x20, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xD0, 0x15, 0x00, -+0x74, 0xEF, 0x17, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x28, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x20, 0x3C, 0x20, 0x4B, 0x45, 0x5F, 0x45, 0x56, 0x54, 0x5F, -+0x4D, 0x41, 0x58, 0x29, 0x20, 0x26, 0x26, 0x20, 0x6B, 0x65, 0x5F, 0x65, 0x76, 0x74, 0x5F, 0x68, 0x64, 0x6C, 0x72, 0x5B, -+0x65, 0x76, 0x65, 0x6E, 0x74, 0x5D, 0x2E, 0x66, 0x75, 0x6E, 0x63, 0x00, 0x6C, 0x69, 0x73, 0x74, 0x5F, 0x68, 0x64, 0x72, -+0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x21, 0x3D, 0x20, -+0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x70, 0x72, 0x65, 0x76, 0x5F, 0x65, 0x6C, 0x65, 0x6D, 0x65, 0x6E, -+0x74, 0x20, 0x3D, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x28, 0x70, 0x72, 0x65, 0x76, 0x5F, -+0x65, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x2D, 0x3E, 0x6E, 0x65, 0x78, 0x74, 0x20, 0x3D, 0x3D, 0x20, 0x65, 0x6C, 0x65, -+0x6D, 0x65, 0x6E, 0x74, 0x29, 0x00, 0x00, 0x00, 0x65, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x21, 0x3D, 0x20, 0x4E, -+0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x30, 0x07, 0x77, 0x2C, 0x61, 0x0E, 0xEE, 0xBA, 0x51, 0x09, 0x99, -+0x19, 0xC4, 0x6D, 0x07, 0x8F, 0xF4, 0x6A, 0x70, 0x35, 0xA5, 0x63, 0xE9, 0xA3, 0x95, 0x64, 0x9E, 0x32, 0x88, 0xDB, 0x0E, -+0xA4, 0xB8, 0xDC, 0x79, 0x1E, 0xE9, 0xD5, 0xE0, 0x88, 0xD9, 0xD2, 0x97, 0x2B, 0x4C, 0xB6, 0x09, 0xBD, 0x7C, 0xB1, 0x7E, -+0x07, 0x2D, 0xB8, 0xE7, 0x91, 0x1D, 0xBF, 0x90, 0x64, 0x10, 0xB7, 0x1D, 0xF2, 0x20, 0xB0, 0x6A, 0x48, 0x71, 0xB9, 0xF3, -+0xDE, 0x41, 0xBE, 0x84, 0x7D, 0xD4, 0xDA, 0x1A, 0xEB, 0xE4, 0xDD, 0x6D, 0x51, 0xB5, 0xD4, 0xF4, 0xC7, 0x85, 0xD3, 0x83, -+0x56, 0x98, 0x6C, 0x13, 0xC0, 0xA8, 0x6B, 0x64, 0x7A, 0xF9, 0x62, 0xFD, 0xEC, 0xC9, 0x65, 0x8A, 0x4F, 0x5C, 0x01, 0x14, -+0xD9, 0x6C, 0x06, 0x63, 0x63, 0x3D, 0x0F, 0xFA, 0xF5, 0x0D, 0x08, 0x8D, 0xC8, 0x20, 0x6E, 0x3B, 0x5E, 0x10, 0x69, 0x4C, -+0xE4, 0x41, 0x60, 0xD5, 0x72, 0x71, 0x67, 0xA2, 0xD1, 0xE4, 0x03, 0x3C, 0x47, 0xD4, 0x04, 0x4B, 0xFD, 0x85, 0x0D, 0xD2, -+0x6B, 0xB5, 0x0A, 0xA5, 0xFA, 0xA8, 0xB5, 0x35, 0x6C, 0x98, 0xB2, 0x42, 0xD6, 0xC9, 0xBB, 0xDB, 0x40, 0xF9, 0xBC, 0xAC, -+0xE3, 0x6C, 0xD8, 0x32, 0x75, 0x5C, 0xDF, 0x45, 0xCF, 0x0D, 0xD6, 0xDC, 0x59, 0x3D, 0xD1, 0xAB, 0xAC, 0x30, 0xD9, 0x26, -+0x3A, 0x00, 0xDE, 0x51, 0x80, 0x51, 0xD7, 0xC8, 0x16, 0x61, 0xD0, 0xBF, 0xB5, 0xF4, 0xB4, 0x21, 0x23, 0xC4, 0xB3, 0x56, -+0x99, 0x95, 0xBA, 0xCF, 0x0F, 0xA5, 0xBD, 0xB8, 0x9E, 0xB8, 0x02, 0x28, 0x08, 0x88, 0x05, 0x5F, 0xB2, 0xD9, 0x0C, 0xC6, -+0x24, 0xE9, 0x0B, 0xB1, 0x87, 0x7C, 0x6F, 0x2F, 0x11, 0x4C, 0x68, 0x58, 0xAB, 0x1D, 0x61, 0xC1, 0x3D, 0x2D, 0x66, 0xB6, -+0x90, 0x41, 0xDC, 0x76, 0x06, 0x71, 0xDB, 0x01, 0xBC, 0x20, 0xD2, 0x98, 0x2A, 0x10, 0xD5, 0xEF, 0x89, 0x85, 0xB1, 0x71, -+0x1F, 0xB5, 0xB6, 0x06, 0xA5, 0xE4, 0xBF, 0x9F, 0x33, 0xD4, 0xB8, 0xE8, 0xA2, 0xC9, 0x07, 0x78, 0x34, 0xF9, 0x00, 0x0F, -+0x8E, 0xA8, 0x09, 0x96, 0x18, 0x98, 0x0E, 0xE1, 0xBB, 0x0D, 0x6A, 0x7F, 0x2D, 0x3D, 0x6D, 0x08, 0x97, 0x6C, 0x64, 0x91, -+0x01, 0x5C, 0x63, 0xE6, 0xF4, 0x51, 0x6B, 0x6B, 0x62, 0x61, 0x6C, 0x1C, 0xD8, 0x30, 0x65, 0x85, 0x4E, 0x00, 0x62, 0xF2, -+0xED, 0x95, 0x06, 0x6C, 0x7B, 0xA5, 0x01, 0x1B, 0xC1, 0xF4, 0x08, 0x82, 0x57, 0xC4, 0x0F, 0xF5, 0xC6, 0xD9, 0xB0, 0x65, -+0x50, 0xE9, 0xB7, 0x12, 0xEA, 0xB8, 0xBE, 0x8B, 0x7C, 0x88, 0xB9, 0xFC, 0xDF, 0x1D, 0xDD, 0x62, 0x49, 0x2D, 0xDA, 0x15, -+0xF3, 0x7C, 0xD3, 0x8C, 0x65, 0x4C, 0xD4, 0xFB, 0x58, 0x61, 0xB2, 0x4D, 0xCE, 0x51, 0xB5, 0x3A, 0x74, 0x00, 0xBC, 0xA3, -+0xE2, 0x30, 0xBB, 0xD4, 0x41, 0xA5, 0xDF, 0x4A, 0xD7, 0x95, 0xD8, 0x3D, 0x6D, 0xC4, 0xD1, 0xA4, 0xFB, 0xF4, 0xD6, 0xD3, -+0x6A, 0xE9, 0x69, 0x43, 0xFC, 0xD9, 0x6E, 0x34, 0x46, 0x88, 0x67, 0xAD, 0xD0, 0xB8, 0x60, 0xDA, 0x73, 0x2D, 0x04, 0x44, -+0xE5, 0x1D, 0x03, 0x33, 0x5F, 0x4C, 0x0A, 0xAA, 0xC9, 0x7C, 0x0D, 0xDD, 0x3C, 0x71, 0x05, 0x50, 0xAA, 0x41, 0x02, 0x27, -+0x10, 0x10, 0x0B, 0xBE, 0x86, 0x20, 0x0C, 0xC9, 0x25, 0xB5, 0x68, 0x57, 0xB3, 0x85, 0x6F, 0x20, 0x09, 0xD4, 0x66, 0xB9, -+0x9F, 0xE4, 0x61, 0xCE, 0x0E, 0xF9, 0xDE, 0x5E, 0x98, 0xC9, 0xD9, 0x29, 0x22, 0x98, 0xD0, 0xB0, 0xB4, 0xA8, 0xD7, 0xC7, -+0x17, 0x3D, 0xB3, 0x59, 0x81, 0x0D, 0xB4, 0x2E, 0x3B, 0x5C, 0xBD, 0xB7, 0xAD, 0x6C, 0xBA, 0xC0, 0x20, 0x83, 0xB8, 0xED, -+0xB6, 0xB3, 0xBF, 0x9A, 0x0C, 0xE2, 0xB6, 0x03, 0x9A, 0xD2, 0xB1, 0x74, 0x39, 0x47, 0xD5, 0xEA, 0xAF, 0x77, 0xD2, 0x9D, -+0x15, 0x26, 0xDB, 0x04, 0x83, 0x16, 0xDC, 0x73, 0x12, 0x0B, 0x63, 0xE3, 0x84, 0x3B, 0x64, 0x94, 0x3E, 0x6A, 0x6D, 0x0D, -+0xA8, 0x5A, 0x6A, 0x7A, 0x0B, 0xCF, 0x0E, 0xE4, 0x9D, 0xFF, 0x09, 0x93, 0x27, 0xAE, 0x00, 0x0A, 0xB1, 0x9E, 0x07, 0x7D, -+0x44, 0x93, 0x0F, 0xF0, 0xD2, 0xA3, 0x08, 0x87, 0x68, 0xF2, 0x01, 0x1E, 0xFE, 0xC2, 0x06, 0x69, 0x5D, 0x57, 0x62, 0xF7, -+0xCB, 0x67, 0x65, 0x80, 0x71, 0x36, 0x6C, 0x19, 0xE7, 0x06, 0x6B, 0x6E, 0x76, 0x1B, 0xD4, 0xFE, 0xE0, 0x2B, 0xD3, 0x89, -+0x5A, 0x7A, 0xDA, 0x10, 0xCC, 0x4A, 0xDD, 0x67, 0x6F, 0xDF, 0xB9, 0xF9, 0xF9, 0xEF, 0xBE, 0x8E, 0x43, 0xBE, 0xB7, 0x17, -+0xD5, 0x8E, 0xB0, 0x60, 0xE8, 0xA3, 0xD6, 0xD6, 0x7E, 0x93, 0xD1, 0xA1, 0xC4, 0xC2, 0xD8, 0x38, 0x52, 0xF2, 0xDF, 0x4F, -+0xF1, 0x67, 0xBB, 0xD1, 0x67, 0x57, 0xBC, 0xA6, 0xDD, 0x06, 0xB5, 0x3F, 0x4B, 0x36, 0xB2, 0x48, 0xDA, 0x2B, 0x0D, 0xD8, -+0x4C, 0x1B, 0x0A, 0xAF, 0xF6, 0x4A, 0x03, 0x36, 0x60, 0x7A, 0x04, 0x41, 0xC3, 0xEF, 0x60, 0xDF, 0x55, 0xDF, 0x67, 0xA8, -+0xEF, 0x8E, 0x6E, 0x31, 0x79, 0xBE, 0x69, 0x46, 0x8C, 0xB3, 0x61, 0xCB, 0x1A, 0x83, 0x66, 0xBC, 0xA0, 0xD2, 0x6F, 0x25, -+0x36, 0xE2, 0x68, 0x52, 0x95, 0x77, 0x0C, 0xCC, 0x03, 0x47, 0x0B, 0xBB, 0xB9, 0x16, 0x02, 0x22, 0x2F, 0x26, 0x05, 0x55, -+0xBE, 0x3B, 0xBA, 0xC5, 0x28, 0x0B, 0xBD, 0xB2, 0x92, 0x5A, 0xB4, 0x2B, 0x04, 0x6A, 0xB3, 0x5C, 0xA7, 0xFF, 0xD7, 0xC2, -+0x31, 0xCF, 0xD0, 0xB5, 0x8B, 0x9E, 0xD9, 0x2C, 0x1D, 0xAE, 0xDE, 0x5B, 0xB0, 0xC2, 0x64, 0x9B, 0x26, 0xF2, 0x63, 0xEC, -+0x9C, 0xA3, 0x6A, 0x75, 0x0A, 0x93, 0x6D, 0x02, 0xA9, 0x06, 0x09, 0x9C, 0x3F, 0x36, 0x0E, 0xEB, 0x85, 0x67, 0x07, 0x72, -+0x13, 0x57, 0x00, 0x05, 0x82, 0x4A, 0xBF, 0x95, 0x14, 0x7A, 0xB8, 0xE2, 0xAE, 0x2B, 0xB1, 0x7B, 0x38, 0x1B, 0xB6, 0x0C, -+0x9B, 0x8E, 0xD2, 0x92, 0x0D, 0xBE, 0xD5, 0xE5, 0xB7, 0xEF, 0xDC, 0x7C, 0x21, 0xDF, 0xDB, 0x0B, 0xD4, 0xD2, 0xD3, 0x86, -+0x42, 0xE2, 0xD4, 0xF1, 0xF8, 0xB3, 0xDD, 0x68, 0x6E, 0x83, 0xDA, 0x1F, 0xCD, 0x16, 0xBE, 0x81, 0x5B, 0x26, 0xB9, 0xF6, -+0xE1, 0x77, 0xB0, 0x6F, 0x77, 0x47, 0xB7, 0x18, 0xE6, 0x5A, 0x08, 0x88, 0x70, 0x6A, 0x0F, 0xFF, 0xCA, 0x3B, 0x06, 0x66, -+0x5C, 0x0B, 0x01, 0x11, 0xFF, 0x9E, 0x65, 0x8F, 0x69, 0xAE, 0x62, 0xF8, 0xD3, 0xFF, 0x6B, 0x61, 0x45, 0xCF, 0x6C, 0x16, -+0x78, 0xE2, 0x0A, 0xA0, 0xEE, 0xD2, 0x0D, 0xD7, 0x54, 0x83, 0x04, 0x4E, 0xC2, 0xB3, 0x03, 0x39, 0x61, 0x26, 0x67, 0xA7, -+0xF7, 0x16, 0x60, 0xD0, 0x4D, 0x47, 0x69, 0x49, 0xDB, 0x77, 0x6E, 0x3E, 0x4A, 0x6A, 0xD1, 0xAE, 0xDC, 0x5A, 0xD6, 0xD9, -+0x66, 0x0B, 0xDF, 0x40, 0xF0, 0x3B, 0xD8, 0x37, 0x53, 0xAE, 0xBC, 0xA9, 0xC5, 0x9E, 0xBB, 0xDE, 0x7F, 0xCF, 0xB2, 0x47, -+0xE9, 0xFF, 0xB5, 0x30, 0x1C, 0xF2, 0xBD, 0xBD, 0x8A, 0xC2, 0xBA, 0xCA, 0x30, 0x93, 0xB3, 0x53, 0xA6, 0xA3, 0xB4, 0x24, -+0x05, 0x36, 0xD0, 0xBA, 0x93, 0x06, 0xD7, 0xCD, 0x29, 0x57, 0xDE, 0x54, 0xBF, 0x67, 0xD9, 0x23, 0x2E, 0x7A, 0x66, 0xB3, -+0xB8, 0x4A, 0x61, 0xC4, 0x02, 0x1B, 0x68, 0x5D, 0x94, 0x2B, 0x6F, 0x2A, 0x37, 0xBE, 0x0B, 0xB4, 0xA1, 0x8E, 0x0C, 0xC3, -+0x1B, 0xDF, 0x05, 0x5A, 0x8D, 0xEF, 0x02, 0x2D, 0x61, 0x64, 0x64, 0x72, 0x20, 0x3D, 0x3D, 0x20, 0x65, 0x6E, 0x64, 0x00, -+0x00, 0x50, 0xF2, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xF2, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x03, -+0x04, 0x08, 0x02, 0x01, 0x01, 0x00, 0x02, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0x04, 0x0B, 0x16, -+0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x01, 0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, -+0x44, 0x42, 0x47, 0x5F, 0x53, 0x45, 0x56, 0x5F, 0x4D, 0x49, 0x4E, 0x20, 0x3C, 0x3D, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, -+0x78, 0x20, 0x26, 0x26, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x20, 0x3C, 0x20, 0x44, 0x42, 0x47, 0x5F, 0x53, 0x45, -+0x56, 0x5F, 0x4D, 0x41, 0x58, 0x00, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, -+0x63, 0x64, 0x65, 0x66, 0x00, 0x00, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, -+0x43, 0x44, 0x45, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, -+0x03, 0x02, 0x06, 0x07, 0x00, 0x00, 0x04, 0x02, 0x03, 0x02, 0x06, 0x07, 0x00, 0x00, 0x04, 0x03, 0x03, 0x00, 0x06, 0x07, -+0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x06, 0x07, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x2C, 0x20, 0x77, 0x6C, 0x61, -+0x6E, 0x20, 0x66, 0x63, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x0A, 0x00, 0x00, 0x00, 0x72, 0x65, 0x62, 0x6F, -+0x6F, 0x74, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x67, 0x70, 0x69, 0x6F, 0x77, 0x72, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, -+0x74, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6F, 0x72, 0x74, 0x0A, 0x00, 0x00, 0x9D, 0x81, 0x44, 0x42, 0x47, 0x3A, 0x20, 0x53, -+0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x20, 0x66, 0x69, 0x6C, 0x74, -+0x65, 0x72, 0x3A, 0x20, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x0A, 0x00, 0x9D, 0x81, 0x44, 0x42, 0x47, 0x3A, 0x20, 0x53, -+0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x6D, 0x6F, 0x64, 0x75, 0x6C, 0x65, 0x20, 0x66, 0x69, 0x6C, 0x74, 0x65, 0x72, -+0x3A, 0x20, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x9D, 0x81, 0x44, 0x42, 0x47, 0x3A, 0x20, 0x42, -+0x6F, 0x6F, 0x74, 0x20, 0x4E, 0x50, 0x43, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x9D, 0x81, 0x44, 0x42, 0x47, 0x3A, 0x20, 0x57, -+0x72, 0x69, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6D, -+0x61, 0x73, 0x6B, 0x3A, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x64, 0x61, 0x74, 0x61, 0x3A, 0x30, 0x78, 0x25, -+0x30, 0x38, 0x78, 0x20, 0x2F, 0x20, 0x25, 0x64, 0x3A, 0x20, 0x5B, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x5D, 0x20, 0x3D, -+0x20, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x20, 0x2F, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x9D, 0x81, 0x44, 0x42, -+0x47, 0x3A, 0x20, 0x57, 0x72, 0x69, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x20, 0x77, 0x69, -+0x74, 0x68, 0x20, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x20, 0x2F, 0x20, 0x25, 0x64, 0x3A, 0x20, 0x5B, 0x30, 0x78, 0x25, -+0x30, 0x38, 0x78, 0x5D, 0x20, 0x3D, 0x20, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x20, 0x2F, 0x20, 0x25, 0x64, 0x0A, 0x00, -+0x9D, 0x81, 0x44, 0x42, 0x47, 0x3A, 0x20, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x6D, 0x65, 0x6D, 0x6F, 0x72, -+0x79, 0x3A, 0x20, 0x5B, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x5D, 0x20, 0x3D, 0x20, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, -+0x20, 0x2F, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x9D, 0x81, 0x42, 0x6F, 0x6F, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, -+0x25, 0x78, 0x2C, 0x20, 0x61, 0x64, 0x64, 0x72, 0x3D, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, -+0x64, 0x65, 0x6C, 0x61, 0x79, 0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x49, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, -+0x62, 0x6F, 0x6F, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0D, 0x0A, 0x00, 0x9D, 0x81, 0x44, 0x42, 0x47, 0x3A, 0x20, 0x46, -+0x57, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x0A, 0x00, 0x00, 0x9D, 0x81, 0x44, 0x42, 0x47, 0x3A, 0x20, 0x57, -+0x72, 0x69, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x20, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x20, -+0x5B, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x20, 0x7E, 0x20, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x5D, 0x20, 0x77, 0x69, -+0x74, 0x68, 0x20, 0x7B, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x2C, 0x20, 0x2E, 0x2E, 0x2E, 0x7D, 0x2C, 0x20, 0x77, 0x73, -+0x74, 0x61, 0x74, 0x75, 0x73, 0x3A, 0x20, 0x25, 0x30, 0x32, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x70, 0x22, 0x17, 0x00, -+0x0C, 0x00, 0x00, 0x00, 0x9B, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x20, 0x28, 0x25, 0x73, 0x29, 0x20, 0x61, 0x74, 0x20, -+0x25, 0x73, 0x3A, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x9B, 0x57, 0x41, 0x52, 0x4E, 0x49, 0x4E, 0x47, 0x20, 0x28, 0x25, 0x73, -+0x29, 0x20, 0x61, 0x74, 0x20, 0x25, 0x73, 0x3A, 0x25, 0x64, 0x0A, 0x00, 0x45, 0x72, 0x72, 0x3A, 0x20, 0x55, 0x46, 0x20, -+0x68, 0x6F, 0x73, 0x74, 0x20, 0x72, 0x78, 0x20, 0x62, 0x75, 0x66, 0x66, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x0D, 0x0A, 0x00, -+0x09, 0x2D, 0x20, 0x00, 0x25, 0x73, 0x25, 0x73, 0x25, 0x73, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, -+0x25, 0x30, 0x32, 0x78, 0x20, 0x00, 0x00, 0x00, 0x25, 0x30, 0x38, 0x78, 0x3A, 0x00, 0x00, 0x00, 0x20, 0x25, 0x30, 0x34, -+0x58, 0x20, 0x25, 0x30, 0x34, 0x58, 0x00, 0x00, 0x20, 0x25, 0x30, 0x32, 0x58, 0x20, 0x25, 0x30, 0x32, 0x58, 0x20, 0x25, -+0x30, 0x32, 0x58, 0x20, 0x25, 0x30, 0x32, 0x58, 0x00, 0x00, 0x00, 0x00, 0x20, 0x25, 0x30, 0x34, 0x58, 0x00, 0x00, 0x00, -+0x20, 0x25, 0x30, 0x32, 0x58, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x68, 0x65, 0x6C, -+0x70, 0x20, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x00, 0x68, 0x65, 0x6C, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x72, 0x20, 0x61, -+0x64, 0x64, 0x72, 0x20, 0x3C, 0x63, 0x6E, 0x74, 0x3E, 0x20, 0x3C, 0x73, 0x7A, 0x3E, 0x00, 0x00, 0x20, 0x77, 0x20, 0x61, -+0x64, 0x64, 0x72, 0x20, 0x76, 0x61, 0x6C, 0x00, 0x77, 0x00, 0x00, 0x00, 0x20, 0x64, 0x62, 0x67, 0x20, 0x6D, 0x73, 0x6B, -+0x00, 0x00, 0x00, 0x00, 0x64, 0x6D, 0x00, 0x00, 0x20, 0x77, 0x66, 0x63, 0x74, 0x20, 0x76, 0x61, 0x6C, 0x28, 0x69, 0x6E, -+0x20, 0x73, 0x29, 0x00, 0x77, 0x66, 0x63, 0x74, 0x00, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x3A, 0x20, 0x63, 0x6D, 0x64, -+0x5F, 0x66, 0x72, 0x65, 0x65, 0x5F, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x65, 0x6D, 0x70, 0x74, 0x79, 0x0D, 0x0A, 0x00, 0x00, -+0x61, 0x69, 0x63, 0x3E, 0x20, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x20, 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x63, 0x6D, 0x64, 0x73, -+0x20, 0x73, 0x75, 0x70, 0x70, 0x6F, 0x72, 0x74, 0x65, 0x64, 0x2E, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x2A, 0x20, 0x54, -+0x6F, 0x6F, 0x20, 0x6D, 0x61, 0x6E, 0x79, 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, 0x28, 0x6D, 0x61, 0x78, 0x2E, 0x20, 0x25, -+0x64, 0x29, 0x20, 0x2A, 0x2A, 0x0A, 0x00, 0x00, 0x55, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, -+0x61, 0x6E, 0x64, 0x20, 0x27, 0x25, 0x73, 0x27, 0x0A, 0x00, 0x00, 0x00, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x0A, 0x25, -+0x73, 0x0A, 0x00, 0x00, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x0D, 0x0A, 0x00, 0x00, -+0x63, 0x75, 0x72, 0x20, 0x64, 0x62, 0x67, 0x5F, 0x6D, 0x73, 0x6B, 0x3A, 0x20, 0x30, 0x78, 0x25, 0x78, 0x0A, 0x00, 0x00, -+0x63, 0x66, 0x67, 0x20, 0x64, 0x62, 0x67, 0x5F, 0x6D, 0x73, 0x6B, 0x3A, 0x20, 0x30, 0x78, 0x25, 0x78, 0x0A, 0x00, 0x00, -+0x69, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x61, 0x72, 0x67, 0x73, 0x0A, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x76, 0x61, -+0x6C, 0x69, 0x64, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x3A, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x55, 0x73, 0x61, 0x67, -+0x65, 0x3A, 0x0A, 0x20, 0x20, 0x72, 0x20, 0x61, 0x64, 0x64, 0x72, 0x20, 0x3C, 0x63, 0x6E, 0x74, 0x3E, 0x0A, 0x00, 0x00, -+0x5B, 0x30, 0x78, 0x25, 0x30, 0x38, 0x58, 0x5D, 0x20, 0x3D, 0x20, 0x30, 0x78, 0x25, 0x30, 0x38, 0x58, 0x0D, 0x0A, 0x00, -+0x5B, 0x30, 0x78, 0x25, 0x30, 0x38, 0x58, 0x5D, 0x20, 0x3D, 0x20, 0x30, 0x78, 0x25, 0x30, 0x32, 0x58, 0x0D, 0x0A, 0x00, -+0x5B, 0x30, 0x78, 0x25, 0x30, 0x38, 0x58, 0x5D, 0x20, 0x3D, 0x20, 0x30, 0x78, 0x25, 0x30, 0x34, 0x58, 0x0D, 0x0A, 0x00, -+0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x0A, 0x20, 0x20, 0x77, 0x20, 0x61, 0x64, 0x64, 0x72, 0x20, 0x76, 0x61, 0x6C, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3A, 0x0A, 0x20, 0x77, 0x66, 0x63, 0x74, 0x20, 0x76, 0x61, 0x6C, -+0x28, 0x69, 0x6E, 0x20, 0x73, 0x29, 0x0A, 0x00, 0x63, 0x75, 0x72, 0x20, 0x77, 0x66, 0x63, 0x74, 0x3A, 0x20, 0x25, 0x75, -+0x73, 0x0A, 0x00, 0x00, 0x63, 0x66, 0x67, 0x20, 0x77, 0x66, 0x63, 0x74, 0x20, 0x25, 0x75, 0x73, 0x0A, 0x00, 0x00, 0x00, -+0x77, 0x66, 0x63, 0x74, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x6F, 0x66, 0x20, 0x72, 0x61, 0x6E, 0x67, 0x65, 0x0A, 0x00, 0x00, -+0x08, 0x20, 0x08, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x07, 0x00, 0x50, -+0xF2, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, -+0x5F, 0x67, 0x65, 0x74, 0x28, 0x64, 0x65, 0x73, 0x74, 0x5F, 0x69, 0x64, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x4D, 0x45, 0x5F, -+0x42, 0x55, 0x53, 0x59, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x66, 0x5F, 0x6D, 0x67, 0x6D, 0x74, 0x5F, 0x65, 0x6E, 0x76, -+0x2E, 0x6D, 0x6F, 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x5F, 0x76, 0x69, 0x66, 0x20, 0x21, 0x3D, 0x20, 0x49, 0x4E, 0x56, 0x41, -+0x4C, 0x49, 0x44, 0x5F, 0x56, 0x49, 0x46, 0x5F, 0x49, 0x44, 0x58, 0x00, 0xD8, 0x22, 0x17, 0x00, 0x18, 0x00, 0x00, 0x00, -+0x62, 0x69, 0x74, 0x5F, 0x70, 0x6F, 0x73, 0x20, 0x3C, 0x20, 0x4D, 0x41, 0x43, 0x5F, 0x52, 0x41, 0x54, 0x45, 0x53, 0x45, -+0x54, 0x5F, 0x4C, 0x45, 0x4E, 0x00, 0x00, 0x00, 0x72, 0x61, 0x74, 0x65, 0x73, 0x2D, 0x3E, 0x6C, 0x65, 0x6E, 0x67, 0x74, -+0x68, 0x20, 0x21, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x4C, 0x4F, 0x43, 0x41, 0x4C, 0x5F, 0x43, 0x41, 0x50, 0x41, 0x28, 0x48, -+0x45, 0x29, 0x00, 0x00, 0x4C, 0x4F, 0x43, 0x41, 0x4C, 0x5F, 0x43, 0x41, 0x50, 0x41, 0x28, 0x56, 0x48, 0x54, 0x29, 0x00, -+0x4C, 0x4F, 0x43, 0x41, 0x4C, 0x5F, 0x43, 0x41, 0x50, 0x41, 0x28, 0x48, 0x54, 0x29, 0x00, 0x00, 0x76, 0x69, 0x66, 0x2D, -+0x3E, 0x63, 0x68, 0x61, 0x6E, 0x5F, 0x63, 0x74, 0x78, 0x74, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, -+0x63, 0x75, 0x72, 0x72, 0x3D, 0x25, 0x78, 0x2C, 0x20, 0x62, 0x73, 0x73, 0x3D, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, -+0x6D, 0x69, 0x63, 0x5F, 0x63, 0x61, 0x6C, 0x63, 0x5F, 0x70, 0x74, 0x72, 0x2D, 0x3E, 0x6C, 0x61, 0x73, 0x74, 0x5F, 0x6D, -+0x5F, 0x69, 0x5F, 0x6C, 0x65, 0x6E, 0x20, 0x3C, 0x20, 0x34, 0x00, 0x00, 0x72, 0x65, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x76, 0x69, 0x66, 0x2D, 0x3E, 0x75, 0x2E, 0x73, 0x74, 0x61, 0x2E, 0x61, 0x70, 0x5F, 0x69, 0x64, -+0x20, 0x3D, 0x3D, 0x20, 0x49, 0x4E, 0x56, 0x41, 0x4C, 0x49, 0x44, 0x5F, 0x53, 0x54, 0x41, 0x5F, 0x49, 0x44, 0x58, 0x00, -+0x63, 0x6F, 0x6E, 0x6E, 0x20, 0x6C, 0x6F, 0x73, 0x73, 0x20, 0x69, 0x6E, 0x64, 0x0D, 0x0A, 0x00, 0x6B, 0x65, 0x5F, 0x73, -+0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x53, 0x4D, 0x29, 0x20, 0x3D, 0x3D, -+0x20, 0x53, 0x4D, 0x5F, 0x53, 0x43, 0x41, 0x4E, 0x4E, 0x49, 0x4E, 0x47, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x73, -+0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x53, 0x4D, 0x29, 0x20, 0x3D, 0x3D, -+0x20, 0x53, 0x4D, 0x5F, 0x4A, 0x4F, 0x49, 0x4E, 0x49, 0x4E, 0x47, 0x00, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x3A, 0x20, 0x25, -+0x34, 0x78, 0x3A, 0x25, 0x34, 0x78, 0x3A, 0x25, 0x34, 0x78, 0x2C, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x28, 0x6B, 0x65, 0x5F, -+0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x53, 0x4D, 0x29, 0x20, 0x3D, -+0x3D, 0x20, 0x53, 0x4D, 0x5F, 0x42, 0x53, 0x53, 0x5F, 0x50, 0x41, 0x52, 0x41, 0x4D, 0x5F, 0x53, 0x45, 0x54, 0x54, 0x49, -+0x4E, 0x47, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x28, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, -+0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x53, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x53, 0x4D, 0x5F, 0x49, 0x44, 0x4C, 0x45, -+0x29, 0x20, 0x7C, 0x7C, 0x20, 0x28, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, -+0x41, 0x53, 0x4B, 0x5F, 0x53, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x53, 0x4D, 0x5F, 0x44, 0x49, 0x53, 0x43, 0x4F, 0x4E, -+0x4E, 0x45, 0x43, 0x54, 0x49, 0x4E, 0x47, 0x29, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, -+0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x53, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x53, 0x4D, 0x5F, -+0x42, 0x53, 0x53, 0x5F, 0x50, 0x41, 0x52, 0x41, 0x4D, 0x5F, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4E, 0x47, 0x00, 0x00, 0x00, -+0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x53, 0x4D, -+0x29, 0x20, 0x3D, 0x3D, 0x20, 0x53, 0x4D, 0x5F, 0x44, 0x49, 0x53, 0x43, 0x4F, 0x4E, 0x4E, 0x45, 0x43, 0x54, 0x49, 0x4E, -+0x47, 0x00, 0x00, 0x00, 0x28, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, -+0x53, 0x4B, 0x5F, 0x53, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x53, 0x4D, 0x5F, 0x42, 0x53, 0x53, 0x5F, 0x50, 0x41, 0x52, -+0x41, 0x4D, 0x5F, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4E, 0x47, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x28, 0x6B, 0x65, 0x5F, 0x73, -+0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x53, 0x4D, 0x29, 0x20, 0x3D, 0x3D, -+0x20, 0x53, 0x4D, 0x5F, 0x44, 0x49, 0x53, 0x43, 0x4F, 0x4E, 0x4E, 0x45, 0x43, 0x54, 0x49, 0x4E, 0x47, 0x29, 0x00, 0x00, -+0x73, 0x6D, 0x20, 0x63, 0x6F, 0x65, 0x78, 0x20, 0x74, 0x73, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x0D, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, -+0x4B, 0x5F, 0x53, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x53, 0x4D, 0x5F, 0x53, 0x54, 0x41, 0x5F, 0x41, 0x44, 0x44, 0x49, -+0x4E, 0x47, 0x00, 0x00, 0x98, 0x23, 0x17, 0x00, 0x15, 0x00, 0x00, 0x00, 0x74, 0x78, 0x20, 0x63, 0x66, 0x6D, 0x3A, 0x25, -+0x64, 0x2C, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x63, 0x6F, 0x5F, 0x6C, 0x69, 0x73, 0x74, 0x5F, 0x69, 0x73, 0x5F, 0x65, -+0x6D, 0x70, 0x74, 0x79, 0x28, 0x26, 0x73, 0x6D, 0x5F, 0x65, 0x6E, 0x76, 0x2E, 0x62, 0x73, 0x73, 0x5F, 0x63, 0x6F, 0x6E, -+0x66, 0x69, 0x67, 0x29, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x20, 0x72, 0x65, 0x6F, 0x75, 0x72, -+0x63, 0x65, 0x73, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x2F, 0x64, 0x69, 0x73, 0x61, 0x73, -+0x73, 0x6F, 0x63, 0x3A, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x64, 0x69, 0x73, 0x63, 0x6F, 0x6E, 0x6E, 0x63, -+0x74, 0x3A, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x3A, -+0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x61, 0x69, 0x64, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x61, 0x75, 0x74, 0x68, -+0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x3A, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x61, 0x73, 0x73, 0x6F, -+0x63, 0x5F, 0x72, 0x73, 0x70, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x3A, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, -+0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x20, 0x69, 0x6E, 0x20, 0x61, 0x20, -+0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x61, 0x75, -+0x74, 0x68, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x3A, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6F, 0x6E, 0x20, 0x63, -+0x6F, 0x64, 0x65, 0x20, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x42, 0x53, 0x53, 0x5F, 0x43, 0x41, 0x50, 0x41, -+0x28, 0x62, 0x73, 0x73, 0x2C, 0x20, 0x56, 0x41, 0x4C, 0x49, 0x44, 0x29, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0x03, 0x00, -+0x00, 0x00, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x73, 0x6D, 0x5F, 0x61, 0x75, 0x74, 0x68, 0x5F, -+0x73, 0x65, 0x6E, 0x64, 0x00, 0x00, 0x00, 0x00, 0x73, 0x6D, 0x5F, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x5F, 0x72, 0x65, 0x71, -+0x5F, 0x73, 0x65, 0x6E, 0x64, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, -+0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x41, 0x50, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x41, 0x50, 0x4D, 0x5F, 0x42, 0x43, -+0x4E, 0x5F, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4E, 0x47, 0x00, 0x00, 0x00, 0x61, 0x70, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, -+0x3A, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x28, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, -+0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x41, 0x50, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x41, 0x50, 0x4D, 0x5F, 0x42, -+0x53, 0x53, 0x5F, 0x50, 0x41, 0x52, 0x41, 0x4D, 0x5F, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4E, 0x47, 0x29, 0x20, 0x7C, 0x7C, -+0x20, 0x28, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, -+0x41, 0x50, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x41, 0x50, 0x4D, 0x5F, 0x49, 0x44, 0x4C, 0x45, 0x29, 0x20, 0x7C, 0x7C, -+0x20, 0x28, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, -+0x41, 0x50, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x41, 0x50, 0x4D, 0x5F, 0x53, 0x54, 0x4F, 0x50, 0x50, 0x49, 0x4E, 0x47, -+0x29, 0x00, 0x00, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, -+0x4B, 0x5F, 0x41, 0x50, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x41, 0x50, 0x4D, 0x5F, 0x42, 0x53, 0x53, 0x5F, 0x50, 0x41, -+0x52, 0x41, 0x4D, 0x5F, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4E, 0x47, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, -+0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x41, 0x50, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x41, 0x50, -+0x4D, 0x5F, 0x53, 0x54, 0x4F, 0x50, 0x50, 0x49, 0x4E, 0x47, 0x00, 0x00, 0x28, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, -+0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x41, 0x50, 0x4D, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x41, -+0x50, 0x4D, 0x5F, 0x53, 0x54, 0x4F, 0x50, 0x50, 0x49, 0x4E, 0x47, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x28, 0x6B, 0x65, 0x5F, -+0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x41, 0x50, 0x4D, 0x29, 0x20, -+0x3D, 0x3D, 0x20, 0x41, 0x50, 0x4D, 0x5F, 0x49, 0x44, 0x4C, 0x45, 0x29, 0x00, 0x00, 0x00, 0x00, 0x61, 0x70, 0x20, 0x73, -+0x74, 0x6F, 0x70, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x63, 0x6F, 0x5F, 0x6C, 0x69, 0x73, 0x74, 0x5F, 0x69, 0x73, 0x5F, 0x65, -+0x6D, 0x70, 0x74, 0x79, 0x28, 0x26, 0x61, 0x70, 0x6D, 0x5F, 0x65, 0x6E, 0x76, 0x2E, 0x62, 0x73, 0x73, 0x5F, 0x63, 0x6F, -+0x6E, 0x66, 0x69, 0x67, 0x29, 0x00, 0x00, 0x00, 0x40, 0x24, 0x17, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6E, -+0x75, 0x20, 0x63, 0x61, 0x6E, 0x63, 0x65, 0x6C, 0x3A, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6E, -+0x75, 0x20, 0x69, 0x64, 0x6C, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x63, 0x65, 0x6C, 0x20, 0x63, 0x66, 0x6D, 0x0D, 0x0A, 0x00, -+0x73, 0x63, 0x61, 0x6E, 0x75, 0x20, 0x73, 0x63, 0x61, 0x6E, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x76, 0x6E, 0x64, 0x72, 0x20, -+0x69, 0x65, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6E, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x63, 0x61, -+0x6E, 0x75, 0x20, 0x72, 0x65, 0x71, 0x3A, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x4D, 0x41, 0x43, -+0x5F, 0x41, 0x44, 0x44, 0x52, 0x5F, 0x47, 0x52, 0x4F, 0x55, 0x50, 0x28, 0x26, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x2D, 0x3E, -+0x62, 0x73, 0x73, 0x69, 0x64, 0x29, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6E, 0x75, 0x20, 0x76, 0x6E, 0x64, 0x72, 0x20, 0x69, -+0x65, 0x0D, 0x0A, 0x00, 0x73, 0x63, 0x61, 0x6E, 0x20, 0x63, 0x61, 0x6E, 0x63, 0x65, 0x6C, 0x20, 0x63, 0x66, 0x6D, 0x20, -+0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x24, 0x17, 0x00, 0x04, 0x00, 0x00, 0x00, 0xC8, 0x24, 0x17, 0x00, -+0x05, 0x00, 0x00, 0x00, 0xF0, 0x24, 0x17, 0x00, 0x07, 0x00, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6E, 0x75, 0x5F, 0x63, 0x6F, -+0x6E, 0x66, 0x69, 0x72, 0x6D, 0x3A, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0A, 0x00, 0x5B, 0x48, 0x49, 0x44, -+0x44, 0x45, 0x4E, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x2D, 0x00, 0x6A, 0x6F, 0x69, 0x6E, -+0x3A, 0x25, 0x73, 0x2C, 0x25, 0x64, 0x0A, 0x00, 0x66, 0x69, 0x78, 0x3D, 0x25, 0x78, 0x2C, 0x20, 0x6E, 0x6F, 0x5F, 0x73, -+0x63, 0x68, 0x65, 0x64, 0x75, 0x6C, 0x65, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x20, 0x25, 0x64, 0x20, -+0x25, 0x64, 0x20, 0x30, 0x78, 0x25, 0x78, 0x20, 0x25, 0x64, 0x20, 0x25, 0x78, 0x20, 0x25, 0x73, 0x0A, 0x00, 0x00, 0x00, -+0x28, 0x69, 0x65, 0x5F, 0x62, 0x75, 0x66, 0x20, 0x2D, 0x20, 0x43, 0x50, 0x55, 0x32, 0x48, 0x57, 0x28, 0x69, 0x65, 0x2D, -+0x3E, 0x62, 0x75, 0x66, 0x29, 0x29, 0x20, 0x3C, 0x3D, 0x20, 0x53, 0x43, 0x41, 0x4E, 0x5F, 0x4D, 0x41, 0x58, 0x5F, 0x49, -+0x45, 0x5F, 0x4C, 0x45, 0x4E, 0x00, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6E, 0x75, 0x5F, 0x73, 0x74, 0x61, 0x72, 0x74, 0x3A, -+0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x2C, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x72, 0x78, 0x20, 0x61, -+0x72, 0x70, 0x72, 0x65, 0x71, 0x3A, 0x20, 0x69, 0x70, 0x3D, 0x25, 0x78, 0x2E, 0x20, 0x76, 0x69, 0x66, 0x20, 0x69, 0x70, -+0x3D, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x72, 0x78, 0x20, 0x61, 0x72, 0x70, 0x72, 0x65, 0x73, 0x70, 0x0A, 0x00, -+0x72, 0x78, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x5F, 0x64, 0x65, 0x73, 0x63, 0x2D, 0x3E, 0x76, 0x61, 0x6C, 0x2E, 0x73, 0x74, -+0x61, 0x74, 0x75, 0x73, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x00, 0x75, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x20, 0x73, -+0x74, 0x61, 0x74, 0x3A, 0x25, 0x64, 0x00, 0x00, 0x54, 0x4B, 0x49, 0x50, 0x20, 0x49, 0x43, 0x56, 0x20, 0x45, 0x52, 0x52, -+0x0A, 0x00, 0x00, 0x00, 0x64, 0x65, 0x66, 0x72, 0x61, 0x67, 0x20, 0x21, 0x3D, 0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, -+0x72, 0x78, 0x5F, 0x72, 0x65, 0x6F, 0x72, 0x64, 0x2D, 0x3E, 0x6F, 0x6F, 0x6F, 0x5F, 0x70, 0x6B, 0x74, 0x5F, 0x63, 0x6E, -+0x74, 0x00, 0x00, 0x00, 0x6F, 0x6C, 0x64, 0x5F, 0x77, 0x69, 0x6E, 0x5F, 0x62, 0x61, 0x72, 0x20, 0x64, 0x65, 0x74, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x72, 0x65, 0x6F, 0x72, 0x64, 0x2D, 0x3E, 0x6F, 0x6F, 0x6F, 0x5F, 0x70, 0x6B, 0x74, 0x5F, 0x63, -+0x6E, 0x74, 0x3C, 0x3D, 0x36, 0x34, 0x00, 0x00, 0x25, 0x73, 0x3A, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x64, 0x65, 0x61, -+0x75, 0x74, 0x68, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x74, 0x61, 0x73, 0x6B, 0x5F, 0x69, 0x64, 0x78, 0x20, 0x21, 0x3D, 0x20, -+0x30, 0x78, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6D, 0x61, 0x63, 0x68, 0x64, 0x72, 0x5F, 0x6C, 0x65, 0x6E, 0x67, -+0x74, 0x68, 0x20, 0x26, 0x20, 0x30, 0x78, 0x33, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x72, 0x78, 0x20, 0x65, -+0x61, 0x70, 0x6F, 0x6C, 0x3A, 0x25, 0x78, 0x2C, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x57, 0x45, 0x50, 0x20, -+0x49, 0x43, 0x56, 0x20, 0x45, 0x52, 0x52, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x72, 0x65, 0x6F, 0x72, 0x64, 0x20, 0x21, 0x3D, -+0x20, 0x4E, 0x55, 0x4C, 0x4C, 0x00, 0x00, 0x00, 0x72, 0x78, 0x75, 0x5F, 0x63, 0x6E, 0x74, 0x72, 0x6C, 0x5F, 0x73, 0x70, -+0x75, 0x72, 0x69, 0x6F, 0x75, 0x73, 0x5F, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x74, 0x78, 0x75, 0x20, -+0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x3A, 0x20, 0x25, 0x64, 0x2C, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x64, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x72, 0x65, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x6D, 0x69, 0x74, 0x20, 0x74, 0x78, 0x75, 0x20, 0x64, -+0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x0A, 0x00, 0x70, 0x6F, 0x72, 0x74, 0x20, 0x66, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3A, -+0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x68, 0x6F, 0x73, 0x74, 0x2D, 0x3E, 0x73, 0x74, 0x61, 0x69, 0x64, 0x20, -+0x21, 0x3D, 0x20, 0x49, 0x4E, 0x56, 0x41, 0x4C, 0x49, 0x44, 0x5F, 0x53, 0x54, 0x41, 0x5F, 0x49, 0x44, 0x58, 0x00, 0x00, -+0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x20, 0x61, 0x64, 0x64, 0x62, 0x61, 0x5F, 0x72, 0x65, 0x71, 0x3A, 0x74, 0x69, 0x64, -+0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x20, 0x61, 0x64, 0x64, 0x62, 0x61, -+0x5F, 0x72, 0x73, 0x70, 0x3A, 0x74, 0x69, 0x64, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x69, 0x64, 0x78, 0x3D, 0x25, 0x64, 0x0D, -+0x0A, 0x00, 0x00, 0x00, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x20, 0x72, 0x78, 0x5F, 0x64, 0x65, 0x6C, 0x62, 0x61, 0x3A, -+0x74, 0x69, 0x64, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x73, 0x74, 0x61, 0x69, 0x64, 0x78, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, -+0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x20, 0x74, 0x78, 0x5F, 0x64, 0x65, 0x6C, 0x62, 0x61, 0x3A, 0x74, 0x69, 0x64, 0x3D, -+0x25, 0x64, 0x2C, 0x20, 0x73, 0x74, 0x61, 0x69, 0x64, 0x78, 0x3D, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x2C, 0x25, 0x17, 0x00, -+0x05, 0x00, 0x00, 0x00, 0x6D, 0x6F, 0x76, 0x65, 0x20, 0x77, 0x69, 0x6E, 0x20, 0x73, 0x69, 0x6E, 0x63, 0x65, 0x20, 0x66, -+0x6C, 0x75, 0x73, 0x68, 0x3A, 0x20, 0x73, 0x75, 0x63, 0x63, 0x3D, 0x25, 0x64, 0x2C, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x70, -+0x61, 0x73, 0x74, 0x3D, 0x25, 0x64, 0x0A, 0x00, 0x6B, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5F, 0x67, 0x65, 0x74, -+0x28, 0x4B, 0x45, 0x5F, 0x42, 0x55, 0x49, 0x4C, 0x44, 0x5F, 0x49, 0x44, 0x28, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x42, 0x41, -+0x4D, 0x2C, 0x20, 0x62, 0x61, 0x6D, 0x5F, 0x69, 0x64, 0x78, 0x29, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x42, 0x41, 0x4D, 0x5F, -+0x44, 0x45, 0x4C, 0x45, 0x54, 0x45, 0x00, 0x00, 0x62, 0x61, 0x6D, 0x5F, 0x69, 0x64, 0x78, 0x20, 0x3C, 0x20, 0x42, 0x41, -+0x4D, 0x5F, 0x49, 0x4E, 0x56, 0x41, 0x4C, 0x49, 0x44, 0x5F, 0x54, 0x41, 0x53, 0x4B, 0x5F, 0x49, 0x44, 0x58, 0x00, 0x00, -+0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, -+0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, -+0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, -+0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, -+0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, -+0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, -+0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, -+0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, -+0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, -+0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, -+0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, -+0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, -+0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, -+0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, -+0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16, 0xC6, 0xF8, 0xEE, 0xF6, -+0xFF, 0xD6, 0xDE, 0x91, 0x60, 0x02, 0xCE, 0x56, 0xE7, 0xB5, 0x4D, 0xEC, 0x8F, 0x1F, 0x89, 0xFA, 0xEF, 0xB2, 0x8E, 0xFB, -+0x41, 0xB3, 0x5F, 0x45, 0x23, 0x53, 0xE4, 0x9B, 0x75, 0xE1, 0x3D, 0x4C, 0x6C, 0x7E, 0xF5, 0x83, 0x68, 0x51, 0xD1, 0xF9, -+0xE2, 0xAB, 0x62, 0x2A, 0x08, 0x95, 0x46, 0x9D, 0x30, 0x37, 0x0A, 0x2F, 0x0E, 0x24, 0x1B, 0xDF, 0xCD, 0x4E, 0x7F, 0xEA, -+0x12, 0x1D, 0x58, 0x34, 0x36, 0xDC, 0xB4, 0x5B, 0xA4, 0x76, 0xB7, 0x7D, 0x52, 0xDD, 0x5E, 0x13, 0xA6, 0xB9, 0x00, 0xC1, -+0x40, 0xE3, 0x79, 0xB6, 0xD4, 0x8D, 0x67, 0x72, 0x94, 0x98, 0xB0, 0x85, 0xBB, 0xC5, 0x4F, 0xED, 0x86, 0x9A, 0x66, 0x11, -+0x8A, 0xE9, 0x04, 0xFE, 0xA0, 0x78, 0x25, 0x4B, 0xA2, 0x5D, 0x80, 0x05, 0x3F, 0x21, 0x70, 0xF1, 0x63, 0x77, 0xAF, 0x42, -+0x20, 0xE5, 0xFD, 0xBF, 0x81, 0x18, 0x26, 0xC3, 0xBE, 0x35, 0x88, 0x2E, 0x93, 0x55, 0xFC, 0x7A, 0xC8, 0xBA, 0x32, 0xE6, -+0xC0, 0x19, 0x9E, 0xA3, 0x44, 0x54, 0x3B, 0x0B, 0x8C, 0xC7, 0x6B, 0x28, 0xA7, 0xBC, 0x16, 0xAD, 0xDB, 0x64, 0x74, 0x14, -+0x92, 0x0C, 0x48, 0xB8, 0x9F, 0xBD, 0x43, 0xC4, 0x39, 0x31, 0xD3, 0xF2, 0xD5, 0x8B, 0x6E, 0xDA, 0x01, 0xB1, 0x9C, 0x49, -+0xD8, 0xAC, 0xF3, 0xCF, 0xCA, 0xF4, 0x47, 0x10, 0x6F, 0xF0, 0x4A, 0x5C, 0x38, 0x57, 0x73, 0x97, 0xCB, 0xA1, 0xE8, 0x3E, -+0x96, 0x61, 0x0D, 0x0F, 0xE0, 0x7C, 0x71, 0xCC, 0x90, 0x06, 0xF7, 0x1C, 0xC2, 0x6A, 0xAE, 0x69, 0x17, 0x99, 0x3A, 0x27, -+0xD9, 0xEB, 0x2B, 0x22, 0xD2, 0xA9, 0x07, 0x33, 0x2D, 0x3C, 0x15, 0xC9, 0x87, 0xAA, 0x50, 0xA5, 0x03, 0x59, 0x09, 0x1A, -+0x65, 0xD7, 0x84, 0xD0, 0x82, 0x29, 0x5A, 0x1E, 0x7B, 0xA8, 0x6D, 0x2C, 0xA5, 0x84, 0x99, 0x8D, 0x0D, 0xBD, 0xB1, 0x54, -+0x50, 0x03, 0xA9, 0x7D, 0x19, 0x62, 0xE6, 0x9A, 0x45, 0x9D, 0x40, 0x87, 0x15, 0xEB, 0xC9, 0x0B, 0xEC, 0x67, 0xFD, 0xEA, -+0xBF, 0xF7, 0x96, 0x5B, 0xC2, 0x1C, 0xAE, 0x6A, 0x5A, 0x41, 0x02, 0x4F, 0x5C, 0xF4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3F, -+0x0C, 0x52, 0x65, 0x5E, 0x28, 0xA1, 0x0F, 0xB5, 0x09, 0x36, 0x9B, 0x3D, 0x26, 0x69, 0xCD, 0x9F, 0x1B, 0x9E, 0x74, 0x2E, -+0x2D, 0xB2, 0xEE, 0xFB, 0xF6, 0x4D, 0x61, 0xCE, 0x7B, 0x3E, 0x71, 0x97, 0xF5, 0x68, 0x00, 0x2C, 0x60, 0x1F, 0xC8, 0xED, -+0xBE, 0x46, 0xD9, 0x4B, 0xDE, 0xD4, 0xE8, 0x4A, 0x6B, 0x2A, 0xE5, 0x16, 0xC5, 0xD7, 0x55, 0x94, 0xCF, 0x10, 0x06, 0x81, -+0xF0, 0x44, 0xBA, 0xE3, 0xF3, 0xFE, 0xC0, 0x8A, 0xAD, 0xBC, 0x48, 0x04, 0xDF, 0xC1, 0x75, 0x63, 0x30, 0x1A, 0x0E, 0x6D, -+0x4C, 0x14, 0x35, 0x2F, 0xE1, 0xA2, 0xCC, 0x39, 0x57, 0xF2, 0x82, 0x47, 0xAC, 0xE7, 0x2B, 0x95, 0xA0, 0x98, 0xD1, 0x7F, -+0x66, 0x7E, 0xAB, 0x83, 0xCA, 0x29, 0xD3, 0x3C, 0x79, 0xE2, 0x1D, 0x76, 0x3B, 0x56, 0x4E, 0x1E, 0xDB, 0x0A, 0x6C, 0xE4, -+0x5D, 0x6E, 0xEF, 0xA6, 0xA8, 0xA4, 0x37, 0x8B, 0x32, 0x43, 0x59, 0xB7, 0x8C, 0x64, 0xD2, 0xE0, 0xB4, 0xFA, 0x07, 0x25, -+0xAF, 0x8E, 0xE9, 0x18, 0xD5, 0x88, 0x6F, 0x72, 0x24, 0xF1, 0xC7, 0x51, 0x23, 0x7C, 0x9C, 0x21, 0xDD, 0xDC, 0x86, 0x85, -+0x90, 0x42, 0xC4, 0xAA, 0xD8, 0x05, 0x01, 0x12, 0xA3, 0x5F, 0xF9, 0xD0, 0x91, 0x58, 0x27, 0xB9, 0x38, 0x13, 0xB3, 0x33, -+0xBB, 0x70, 0x89, 0xA7, 0xB6, 0x22, 0x92, 0x20, 0x49, 0xFF, 0x78, 0x7A, 0x8F, 0xF8, 0x80, 0x17, 0xDA, 0x31, 0xC6, 0xB8, -+0xC3, 0xB0, 0x77, 0x11, 0xCB, 0xFC, 0xD6, 0x3A, 0x72, 0x63, 0x5F, 0x72, 0x73, 0x2D, 0x3E, 0x61, 0x74, 0x74, 0x65, 0x6D, -+0x70, 0x74, 0x73, 0x20, 0x3E, 0x3D, 0x20, 0x72, 0x63, 0x5F, 0x72, 0x73, 0x2D, 0x3E, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, -+0x73, 0x00, 0x00, 0x00, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x5F, 0x6D, 0x6F, 0x64, 0x20, 0x3C, 0x3D, 0x20, 0x46, 0x4F, -+0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, 0x5F, 0x48, 0x45, 0x5F, 0x53, 0x55, 0x00, 0x00, 0x00, 0x66, 0x6F, 0x72, 0x6D, -+0x61, 0x74, 0x5F, 0x6D, 0x6F, 0x64, 0x20, 0x3C, 0x20, 0x46, 0x4F, 0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, 0x5F, 0x48, -+0x54, 0x5F, 0x4D, 0x46, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x5F, 0x6D, 0x6F, 0x64, 0x20, 0x3C, -+0x20, 0x46, 0x4F, 0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, 0x5F, 0x56, 0x48, 0x54, 0x00, 0x00, 0x28, 0x66, 0x6F, 0x72, -+0x6D, 0x61, 0x74, 0x5F, 0x6D, 0x6F, 0x64, 0x20, 0x3D, 0x3D, 0x20, 0x46, 0x4F, 0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, -+0x5F, 0x48, 0x54, 0x5F, 0x4D, 0x46, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x28, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x5F, 0x6D, -+0x6F, 0x64, 0x20, 0x3D, 0x3D, 0x20, 0x46, 0x4F, 0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, 0x5F, 0x48, 0x54, 0x5F, 0x47, -+0x46, 0x29, 0x00, 0x00, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x5F, 0x6D, 0x6F, 0x64, 0x20, 0x3D, 0x3D, 0x20, 0x46, 0x4F, -+0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, 0x5F, 0x56, 0x48, 0x54, 0x20, 0x7C, 0x7C, 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x61, -+0x74, 0x5F, 0x6D, 0x6F, 0x64, 0x20, 0x3D, 0x3D, 0x20, 0x46, 0x4F, 0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, 0x5F, 0x4E, -+0x4F, 0x4E, 0x5F, 0x48, 0x54, 0x00, 0x00, 0x00, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x5F, 0x6D, 0x6F, 0x64, 0x20, 0x3D, -+0x3D, 0x20, 0x46, 0x4F, 0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, 0x5F, 0x56, 0x48, 0x54, 0x00, 0x28, 0x66, 0x6F, 0x72, -+0x6D, 0x61, 0x74, 0x5F, 0x6D, 0x6F, 0x64, 0x20, 0x3D, 0x3D, 0x20, 0x46, 0x4F, 0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, -+0x5F, 0x48, 0x45, 0x5F, 0x53, 0x55, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x28, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x5F, 0x6D, -+0x6F, 0x64, 0x20, 0x3D, 0x3D, 0x20, 0x46, 0x4F, 0x52, 0x4D, 0x41, 0x54, 0x4D, 0x4F, 0x44, 0x5F, 0x4E, 0x4F, 0x4E, 0x5F, -+0x48, 0x54, 0x29, 0x00, 0x70, 0x72, 0x65, 0x5F, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3D, 0x3D, 0x20, 0x31, 0x00, 0x00, 0x00, -+0x73, 0x67, 0x69, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, 0x62, 0x77, 0x20, 0x3D, 0x3D, 0x20, 0x42, 0x57, -+0x5F, 0x32, 0x30, 0x4D, 0x48, 0x5A, 0x00, 0x00, 0x6E, 0x73, 0x73, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, -+0x6D, 0x63, 0x73, 0x20, 0x3E, 0x3D, 0x20, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x72, 0x5F, 0x69, 0x64, 0x78, 0x5F, -+0x6D, 0x69, 0x6E, 0x00, 0x6D, 0x63, 0x73, 0x20, 0x3C, 0x3D, 0x20, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x72, 0x5F, -+0x69, 0x64, 0x78, 0x5F, 0x6D, 0x61, 0x78, 0x00, 0x28, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x72, 0x61, 0x74, 0x65, -+0x5F, 0x6D, 0x61, 0x70, 0x5F, 0x6C, 0x20, 0x26, 0x20, 0x43, 0x4F, 0x5F, 0x42, 0x49, 0x54, 0x28, 0x6D, 0x63, 0x73, 0x29, -+0x29, 0x00, 0x00, 0x00, 0x70, 0x72, 0x65, 0x5F, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x00, -+0x73, 0x67, 0x69, 0x20, 0x3C, 0x3D, 0x20, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x73, 0x68, 0x6F, 0x72, 0x74, 0x5F, -+0x67, 0x69, 0x00, 0x00, 0x62, 0x77, 0x20, 0x3C, 0x3D, 0x20, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x62, 0x77, 0x5F, -+0x6D, 0x61, 0x78, 0x00, 0x6E, 0x73, 0x73, 0x20, 0x3C, 0x3D, 0x20, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x6E, 0x6F, -+0x5F, 0x73, 0x73, 0x00, 0x6D, 0x63, 0x73, 0x20, 0x3C, 0x3D, 0x20, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x6D, 0x63, -+0x73, 0x5F, 0x6D, 0x61, 0x78, 0x00, 0x00, 0x00, 0x28, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x72, 0x61, 0x74, 0x65, -+0x5F, 0x6D, 0x61, 0x70, 0x2E, 0x68, 0x74, 0x5B, 0x6E, 0x73, 0x73, 0x5D, 0x20, 0x26, 0x20, 0x43, 0x4F, 0x5F, 0x42, 0x49, -+0x54, 0x28, 0x6D, 0x63, 0x73, 0x29, 0x29, 0x00, 0x6D, 0x63, 0x73, 0x20, 0x3C, 0x3D, 0x20, 0x28, 0x37, 0x20, 0x2B, 0x20, -+0x28, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x72, 0x61, 0x74, 0x65, 0x5F, 0x6D, 0x61, 0x70, 0x2E, 0x76, 0x68, 0x74, -+0x20, 0x3E, 0x3E, 0x20, 0x28, 0x6E, 0x73, 0x73, 0x20, 0x3C, 0x3C, 0x20, 0x31, 0x29, 0x20, 0x26, 0x20, 0x4D, 0x41, 0x43, -+0x5F, 0x56, 0x48, 0x54, 0x5F, 0x4D, 0x43, 0x53, 0x5F, 0x4D, 0x41, 0x50, 0x5F, 0x4D, 0x53, 0x4B, 0x29, 0x29, 0x00, 0x00, -+0x28, 0x28, 0x6D, 0x63, 0x73, 0x20, 0x3D, 0x3D, 0x20, 0x36, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x62, 0x77, 0x20, 0x3D, -+0x3D, 0x20, 0x42, 0x57, 0x5F, 0x38, 0x30, 0x4D, 0x48, 0x5A, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x28, 0x6E, 0x73, 0x73, -+0x20, 0x3D, 0x3D, 0x20, 0x33, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x28, 0x6E, 0x73, 0x73, 0x20, 0x3D, 0x3D, 0x20, 0x36, 0x29, -+0x29, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x00, 0x28, 0x28, 0x6D, 0x63, 0x73, 0x20, 0x3D, 0x3D, 0x20, 0x39, 0x29, 0x20, -+0x26, 0x26, 0x20, 0x28, 0x62, 0x77, 0x20, 0x3D, 0x3D, 0x20, 0x42, 0x57, 0x5F, 0x32, 0x30, 0x4D, 0x48, 0x5A, 0x29, 0x20, -+0x26, 0x26, 0x20, 0x28, 0x6E, 0x73, 0x73, 0x20, 0x21, 0x3D, 0x20, 0x32, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x6E, 0x73, -+0x73, 0x20, 0x21, 0x3D, 0x20, 0x35, 0x29, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x00, 0x28, 0x28, 0x6D, 0x63, -+0x73, 0x20, 0x3D, 0x3D, 0x20, 0x39, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x62, 0x77, 0x20, 0x3D, 0x3D, 0x20, 0x42, 0x57, -+0x5F, 0x38, 0x30, 0x4D, 0x48, 0x5A, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x6E, 0x73, 0x73, 0x20, 0x3D, 0x3D, 0x20, 0x35, -+0x29, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x00, 0x28, 0x28, 0x6D, 0x63, 0x73, 0x20, 0x3D, 0x3D, 0x20, 0x39, 0x29, 0x20, -+0x26, 0x26, 0x20, 0x28, 0x62, 0x77, 0x20, 0x3D, 0x3D, 0x20, 0x42, 0x57, 0x5F, 0x31, 0x36, 0x30, 0x4D, 0x48, 0x5A, 0x29, -+0x20, 0x26, 0x26, 0x20, 0x28, 0x6E, 0x73, 0x73, 0x20, 0x3D, 0x3D, 0x20, 0x32, 0x29, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x30, -+0x00, 0x00, 0x00, 0x00, 0x67, 0x69, 0x20, 0x3C, 0x3D, 0x20, 0x32, 0x00, 0x6D, 0x63, 0x73, 0x20, 0x3C, 0x3D, 0x20, 0x28, -+0x37, 0x20, 0x2B, 0x20, 0x32, 0x20, 0x2A, 0x20, 0x28, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x72, 0x61, 0x74, 0x65, -+0x5F, 0x6D, 0x61, 0x70, 0x2E, 0x68, 0x65, 0x20, 0x3E, 0x3E, 0x20, 0x28, 0x6E, 0x73, 0x73, 0x20, 0x3C, 0x3C, 0x20, 0x31, -+0x29, 0x20, 0x26, 0x20, 0x4D, 0x41, 0x43, 0x5F, 0x48, 0x45, 0x5F, 0x4D, 0x43, 0x53, 0x5F, 0x4D, 0x41, 0x50, 0x5F, 0x4D, -+0x53, 0x4B, 0x29, 0x29, 0x00, 0x00, 0x00, 0x00, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x6E, 0x6F, 0x5F, 0x73, 0x61, -+0x6D, 0x70, 0x6C, 0x65, 0x73, 0x20, 0x3E, 0x3D, 0x20, 0x31, 0x00, 0x00, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x6E, -+0x6F, 0x5F, 0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x73, 0x20, 0x3C, 0x3D, 0x20, 0x52, 0x43, 0x5F, 0x4D, 0x41, 0x58, 0x5F, -+0x4E, 0x5F, 0x53, 0x41, 0x4D, 0x50, 0x4C, 0x45, 0x00, 0x00, 0x00, 0x00, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x62, -+0x77, 0x5F, 0x6D, 0x61, 0x78, 0x20, 0x3C, 0x3D, 0x20, 0x42, 0x57, 0x5F, 0x31, 0x36, 0x30, 0x4D, 0x48, 0x5A, 0x00, 0x00, -+0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x6E, 0x6F, 0x5F, 0x73, 0x73, 0x20, 0x3C, 0x20, 0x38, 0x00, 0x00, 0x00, 0x00, -+0x73, 0x74, 0x61, 0x2D, 0x3E, 0x73, 0x74, 0x61, 0x69, 0x64, 0x20, 0x3C, 0x20, 0x4E, 0x58, 0x5F, 0x52, 0x45, 0x4D, 0x4F, -+0x54, 0x45, 0x5F, 0x53, 0x54, 0x41, 0x5F, 0x4D, 0x41, 0x58, 0x00, 0x00, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x6D, -+0x63, 0x73, 0x5F, 0x6D, 0x61, 0x78, 0x20, 0x3C, 0x20, 0x31, 0x32, 0x00, 0x28, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, -+0x72, 0x5F, 0x69, 0x64, 0x78, 0x5F, 0x6D, 0x69, 0x6E, 0x20, 0x3C, 0x3D, 0x20, 0x48, 0x57, 0x5F, 0x52, 0x41, 0x54, 0x45, -+0x5F, 0x31, 0x31, 0x4D, 0x42, 0x50, 0x53, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x28, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, -+0x72, 0x5F, 0x69, 0x64, 0x78, 0x5F, 0x6D, 0x69, 0x6E, 0x20, 0x3D, 0x3D, 0x20, 0x4D, 0x41, 0x43, 0x5F, 0x52, 0x41, 0x54, -+0x45, 0x53, 0x45, 0x54, 0x5F, 0x4C, 0x45, 0x4E, 0x29, 0x00, 0x00, 0x00, 0x28, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, -+0x72, 0x5F, 0x69, 0x64, 0x78, 0x5F, 0x6D, 0x61, 0x78, 0x20, 0x3C, 0x3D, 0x20, 0x48, 0x57, 0x5F, 0x52, 0x41, 0x54, 0x45, -+0x5F, 0x31, 0x31, 0x4D, 0x42, 0x50, 0x53, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x28, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, -+0x72, 0x5F, 0x69, 0x64, 0x78, 0x5F, 0x6D, 0x61, 0x78, 0x20, 0x3D, 0x3D, 0x20, 0x4D, 0x41, 0x43, 0x5F, 0x52, 0x41, 0x54, -+0x45, 0x53, 0x45, 0x54, 0x5F, 0x4C, 0x45, 0x4E, 0x29, 0x00, 0x00, 0x00, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x6D, -+0x63, 0x73, 0x5F, 0x6D, 0x61, 0x78, 0x20, 0x3C, 0x20, 0x31, 0x30, 0x00, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x6E, -+0x6F, 0x5F, 0x73, 0x73, 0x20, 0x3C, 0x3D, 0x20, 0x33, 0x00, 0x00, 0x00, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x72, -+0x5F, 0x69, 0x64, 0x78, 0x5F, 0x6D, 0x69, 0x6E, 0x20, 0x3C, 0x20, 0x4D, 0x41, 0x43, 0x5F, 0x52, 0x41, 0x54, 0x45, 0x53, -+0x45, 0x54, 0x5F, 0x4C, 0x45, 0x4E, 0x00, 0x00, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x72, 0x5F, 0x69, 0x64, 0x78, -+0x5F, 0x6D, 0x61, 0x78, 0x20, 0x3C, 0x20, 0x4D, 0x41, 0x43, 0x5F, 0x52, 0x41, 0x54, 0x45, 0x53, 0x45, 0x54, 0x5F, 0x4C, -+0x45, 0x4E, 0x00, 0x00, 0x72, 0x63, 0x5F, 0x73, 0x73, 0x2D, 0x3E, 0x62, 0x77, 0x5F, 0x6D, 0x61, 0x78, 0x20, 0x3D, 0x3D, -+0x20, 0x42, 0x57, 0x5F, 0x32, 0x30, 0x4D, 0x48, 0x5A, 0x00, 0x00, 0x00, 0x25, 0x73, 0x3A, 0x20, 0x73, 0x74, 0x61, 0x74, -+0x69, 0x6F, 0x6E, 0x5F, 0x69, 0x64, 0x3D, 0x25, 0x69, 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x5F, 0x6D, 0x6F, 0x64, -+0x3D, 0x25, 0x69, 0x20, 0x70, 0x72, 0x65, 0x5F, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x25, 0x69, 0x20, 0x73, 0x68, 0x6F, 0x72, -+0x74, 0x5F, 0x67, 0x69, 0x3D, 0x25, 0x69, 0x20, 0x6D, 0x61, 0x78, 0x5F, 0x62, 0x77, 0x3D, 0x25, 0x69, 0x0A, 0x00, 0x00, -+0x25, 0x73, 0x3A, 0x20, 0x6E, 0x73, 0x73, 0x5F, 0x6D, 0x61, 0x78, 0x3D, 0x25, 0x69, 0x20, 0x6D, 0x63, 0x73, 0x5F, 0x6D, -+0x61, 0x78, 0x3D, 0x25, 0x69, 0x20, 0x72, 0x5F, 0x69, 0x64, 0x78, 0x5F, 0x6D, 0x69, 0x6E, 0x3D, 0x25, 0x69, 0x20, 0x72, -+0x5F, 0x69, 0x64, 0x78, 0x5F, 0x6D, 0x61, 0x78, 0x3D, 0x25, 0x69, 0x20, 0x6E, 0x6F, 0x5F, 0x73, 0x61, 0x6D, 0x70, 0x6C, -+0x65, 0x73, 0x3D, 0x25, 0x69, 0x0A, 0x00, 0x00, 0x72, 0x63, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x20, 0x7C, 0x9F, 0x00, -+0x20, 0xF3, 0xA0, 0x00, 0xA0, 0x17, 0x52, 0x00, 0xA0, 0x8E, 0x53, 0x00, 0xF8, 0x52, 0x23, 0x00, 0xF8, 0xC9, 0x24, 0x00, -+0x18, 0xF5, 0x15, 0x00, 0x18, 0x6C, 0x17, 0x00, 0xF9, 0x06, 0x11, 0x00, 0x62, 0x07, 0x12, 0x00, 0x35, 0x08, 0x14, 0x00, -+0xD1, 0x10, 0x04, 0x00, 0x0A, 0x4E, 0x04, 0x00, 0x7D, 0xC8, 0x04, 0x00, 0x7D, 0x83, 0x08, 0x00, 0xB1, 0x03, 0x09, 0x00, -+0x1A, 0x04, 0x0A, 0x00, 0x68, 0x08, 0x02, 0x00, 0x05, 0x27, 0x02, 0x00, 0x3F, 0x64, 0x02, 0x00, 0xFE, 0xAC, 0x05, 0x00, -+0x76, 0x02, 0x06, 0x00, 0x67, 0xAD, 0x06, 0x00, 0xF0, 0x5A, 0x01, 0x00, 0x59, 0x6F, 0x01, 0x00, 0x2A, 0x98, 0x01, 0x00, -+0xBE, 0x41, 0x04, 0x00, 0xD9, 0x81, 0x04, 0x00, 0x0D, 0x02, 0x05, 0x00, 0x34, 0x04, 0x01, 0x00, 0x83, 0x13, 0x01, 0x00, -+0x1F, 0x32, 0x01, 0x00, 0x7F, 0xD6, 0x02, 0x00, 0x3B, 0x01, 0x03, 0x00, 0xB3, 0x56, 0x03, 0x00, 0x78, 0xAD, 0x00, 0x00, -+0xAC, 0xB7, 0x00, 0x00, 0x15, 0xCC, 0x00, 0x00, 0xDF, 0x20, 0x02, 0x00, 0xEC, 0x40, 0x02, 0x00, 0x07, 0x81, 0x02, 0x00, -+0x1A, 0x82, 0x00, 0x00, 0xC1, 0x89, 0x00, 0x00, 0x10, 0x99, 0x00, 0x00, 0x55, 0xE4, 0x01, 0x00, 0xD2, 0x00, 0x02, 0x00, -+0xCD, 0x39, 0x02, 0x00, 0xA5, 0x73, 0x00, 0x00, 0x73, 0x7A, 0x00, 0x00, 0x0E, 0x88, 0x00, 0x00, 0xE6, 0xB3, 0x01, 0x00, -+0x8A, 0xCD, 0x01, 0x00, 0xD2, 0x00, 0x02, 0x00, 0x15, 0x68, 0x00, 0x00, 0x34, 0x6E, 0x00, 0x00, 0x73, 0x7A, 0x00, 0x00, -+0x3F, 0x6B, 0x01, 0x00, 0x9E, 0x80, 0x01, 0x00, 0x5A, 0xAB, 0x01, 0x00, 0xBC, 0x56, 0x00, 0x00, 0xD6, 0x5B, 0x00, 0x00, -+0x0A, 0x66, 0x00, 0x00, 0xEC, 0x46, 0x01, 0x00, 0x27, 0x5A, 0x01, 0x00, 0x9E, 0x80, 0x01, 0x00, 0x11, 0x4E, 0x00, 0x00, -+0xA8, 0x52, 0x00, 0x00, 0xD7, 0x5B, 0x00, 0x00, 0x99, 0x22, 0x01, 0x00, 0xB1, 0x33, 0x01, 0x00, 0xE1, 0x55, 0x01, 0x00, -+0x63, 0x45, 0x00, 0x00, 0x78, 0x49, 0x00, 0x00, 0xA2, 0x51, 0x00, 0x00, 0x8A, 0x05, 0x01, 0x00, 0xEC, 0x14, 0x01, 0x00, -+0xB1, 0x33, 0x01, 0x00, 0x74, 0x3E, 0x00, 0x00, 0x21, 0x42, 0x00, 0x00, 0x7A, 0x49, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, -+0x3C, 0x5C, 0x29, 0x00, 0xB4, 0xF4, 0x2D, 0x00, 0x00, 0x88, 0x13, 0x00, 0x1E, 0xAE, 0x14, 0x00, 0x5A, 0xFA, 0x16, 0x00, -+0x55, 0x05, 0x0D, 0x00, 0x69, 0xC9, 0x0D, 0x00, 0x91, 0x51, 0x0F, 0x00, 0x00, 0xC4, 0x09, 0x00, 0x0F, 0x57, 0x0A, 0x00, -+0x2D, 0x7D, 0x0B, 0x00, 0xAA, 0x82, 0x06, 0x00, 0xB4, 0xE4, 0x06, 0x00, 0xC8, 0xA8, 0x07, 0x00, 0x00, 0xE2, 0x04, 0x00, -+0x87, 0x2B, 0x05, 0x00, 0x96, 0xBE, 0x05, 0x00, 0x1C, 0x57, 0x04, 0x00, 0x78, 0x98, 0x04, 0x00, 0x30, 0x1B, 0x05, 0x00, -+0x00, 0xE8, 0x03, 0x00, 0xD2, 0x22, 0x04, 0x00, 0x78, 0x98, 0x04, 0x00, 0x55, 0x41, 0x03, 0x00, 0x5A, 0x72, 0x03, 0x00, -+0x64, 0xD4, 0x03, 0x00, 0x00, 0xEE, 0x02, 0x00, 0x1E, 0x1A, 0x03, 0x00, 0x5A, 0x72, 0x03, 0x00, 0xAA, 0x9A, 0x02, 0x00, -+0xE1, 0xC1, 0x02, 0x00, 0x50, 0x10, 0x03, 0x00, 0x00, 0x58, 0x02, 0x00, 0x4B, 0x7B, 0x02, 0x00, 0xE1, 0xC1, 0x02, 0x00, -+0x00, 0x04, 0xA6, 0x00, 0x00, 0xC8, 0xAF, 0x00, 0x00, 0x50, 0xC3, 0x00, 0x00, 0x02, 0x53, 0x00, 0x00, 0xE4, 0x57, 0x00, -+0x00, 0xA8, 0x61, 0x00, 0xAA, 0x56, 0x37, 0x00, 0x00, 0x98, 0x3A, 0x00, 0xAA, 0x1A, 0x41, 0x00, 0x00, 0x81, 0x29, 0x00, -+0x00, 0xF2, 0x2B, 0x00, 0x00, 0xD4, 0x30, 0x00, 0x55, 0xAB, 0x1B, 0x00, 0x00, 0x4C, 0x1D, 0x00, 0x55, 0x8D, 0x20, 0x00, -+0x80, 0xC0, 0x14, 0x00, 0x00, 0xF9, 0x15, 0x00, 0x00, 0x6A, 0x18, 0x00, 0x38, 0x72, 0x12, 0x00, 0x00, 0x88, 0x13, 0x00, -+0x8E, 0xB3, 0x15, 0x00, 0x00, 0x9A, 0x10, 0x00, 0x00, 0x94, 0x11, 0x00, 0x00, 0x88, 0x13, 0x00, 0xAA, 0xD5, 0x0D, 0x00, -+0x00, 0xA6, 0x0E, 0x00, 0xAA, 0x46, 0x10, 0x00, 0x80, 0x73, 0x0C, 0x00, 0x00, 0x2F, 0x0D, 0x00, 0x00, 0xA6, 0x0E, 0x00, -+0x55, 0x11, 0x0B, 0x00, 0x00, 0xB8, 0x0B, 0x00, 0x55, 0x05, 0x0D, 0x00, 0x00, 0xF6, 0x09, 0x00, 0x00, 0x8C, 0x0A, 0x00, -+0x00, 0xB8, 0x0B, 0x00, 0x00, 0x02, 0x53, 0x00, 0x00, 0xE4, 0x57, 0x00, 0x00, 0xA8, 0x61, 0x00, 0x00, 0x81, 0x29, 0x00, -+0x00, 0xF2, 0x2B, 0x00, 0x00, 0xD4, 0x30, 0x00, 0x55, 0xAB, 0x1B, 0x00, 0x00, 0x4C, 0x1D, 0x00, 0x55, 0x8D, 0x20, 0x00, -+0x80, 0xC0, 0x14, 0x00, 0x00, 0xF9, 0x15, 0x00, 0x00, 0x6A, 0x18, 0x00, 0xAA, 0xD5, 0x0D, 0x00, 0x00, 0xA6, 0x0E, 0x00, -+0xAA, 0x46, 0x10, 0x00, 0x40, 0x60, 0x0A, 0x00, 0x80, 0xFC, 0x0A, 0x00, 0x00, 0x35, 0x0C, 0x00, 0x1C, 0x39, 0x09, 0x00, -+0x00, 0xC4, 0x09, 0x00, 0xC7, 0xD9, 0x0A, 0x00, 0x00, 0x4D, 0x08, 0x00, 0x00, 0xCA, 0x08, 0x00, 0x00, 0xC4, 0x09, 0x00, -+0xD5, 0xEA, 0x06, 0x00, 0x00, 0x53, 0x07, 0x00, 0x55, 0x23, 0x08, 0x00, 0xC0, 0x39, 0x06, 0x00, 0x80, 0x97, 0x06, 0x00, -+0x00, 0x53, 0x07, 0x00, 0xAA, 0x88, 0x05, 0x00, 0x00, 0xDC, 0x05, 0x00, 0xAA, 0x82, 0x06, 0x00, 0x00, 0xFB, 0x04, 0x00, -+0x00, 0x46, 0x05, 0x00, 0x00, 0xDC, 0x05, 0x00, 0x3B, 0x89, 0x16, 0x00, 0x4F, 0x48, 0x14, 0x00, 0xC7, 0xD9, 0x0A, 0x00, -+0x00, 0xC4, 0x09, 0x00, 0x0D, 0x02, 0x05, 0x00, 0xD9, 0x81, 0x04, 0x00, 0x07, 0x81, 0x02, 0x00, 0xEC, 0x40, 0x02, 0x00, -+0x9E, 0x44, 0x0B, 0x00, 0x27, 0x24, 0x0A, 0x00, 0xE4, 0x6C, 0x05, 0x00, 0x00, 0xE2, 0x04, 0x00, 0x07, 0x81, 0x02, 0x00, -+0xEC, 0x40, 0x02, 0x00, 0x83, 0x40, 0x01, 0x00, 0x76, 0x20, 0x01, 0x00, 0x14, 0x83, 0x07, 0x00, 0xC5, 0xC2, 0x06, 0x00, -+0xED, 0x9D, 0x03, 0x00, 0x55, 0x41, 0x03, 0x00, 0x5A, 0xAB, 0x01, 0x00, 0x9E, 0x80, 0x01, 0x00, 0xAD, 0xD5, 0x00, 0x00, -+0x4F, 0xC0, 0x00, 0x00, 0x4F, 0xA2, 0x05, 0x00, 0x14, 0x12, 0x05, 0x00, 0x72, 0xB6, 0x02, 0x00, 0x00, 0x71, 0x02, 0x00, -+0x83, 0x40, 0x01, 0x00, 0x76, 0x20, 0x01, 0x00, 0x42, 0xA0, 0x00, 0x00, 0x3B, 0x90, 0x00, 0x00, 0x8A, 0xC1, 0x03, 0x00, -+0x62, 0x61, 0x03, 0x00, 0xF7, 0xCE, 0x01, 0x00, 0xAB, 0xA0, 0x01, 0x00, 0xAD, 0xD5, 0x00, 0x00, 0x4F, 0xC0, 0x00, 0x00, -+0xD6, 0x6A, 0x00, 0x00, 0x27, 0x60, 0x00, 0x00, 0x27, 0xD1, 0x02, 0x00, 0x0A, 0x89, 0x02, 0x00, 0x39, 0x5B, 0x01, 0x00, -+0x80, 0x38, 0x01, 0x00, 0x42, 0xA0, 0x00, 0x00, 0x3B, 0x90, 0x00, 0x00, 0x21, 0x50, 0x00, 0x00, 0x1E, 0x48, 0x00, 0x00, -+0x07, 0x81, 0x02, 0x00, 0xEC, 0x40, 0x02, 0x00, 0xA4, 0x34, 0x01, 0x00, 0xC7, 0x15, 0x01, 0x00, 0x73, 0x8E, 0x00, 0x00, -+0x35, 0x80, 0x00, 0x00, 0x3A, 0x47, 0x00, 0x00, 0x1A, 0x40, 0x00, 0x00, 0xEC, 0x40, 0x02, 0x00, 0x3B, 0x07, 0x02, 0x00, -+0xC7, 0x15, 0x01, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x35, 0x80, 0x00, 0x00, 0x62, 0x73, 0x00, 0x00, 0x1A, 0x40, 0x00, 0x00, -+0xB1, 0x39, 0x00, 0x00, 0xC5, 0xE0, 0x01, 0x00, 0xB1, 0xB0, 0x01, 0x00, 0x7B, 0xE7, 0x00, 0x00, 0x55, 0xD0, 0x00, 0x00, -+0xD6, 0x6A, 0x00, 0x00, 0x27, 0x60, 0x00, 0x00, 0x6B, 0x35, 0x00, 0x00, 0x14, 0x30, 0x00, 0x00, 0xB1, 0xB0, 0x01, 0x00, -+0x6C, 0x85, 0x01, 0x00, 0x55, 0xD0, 0x00, 0x00, 0x80, 0xBB, 0x00, 0x00, 0x27, 0x60, 0x00, 0x00, 0x8A, 0x56, 0x00, 0x00, -+0x14, 0x30, 0x00, 0x00, 0x45, 0x2B, 0x00, 0x00, 0x00, 0x6A, 0x18, 0x00, 0xE0, 0x4B, 0x10, 0x00, 0x00, 0x35, 0x0C, 0x00, -+0xC0, 0x2D, 0x08, 0x00, 0x80, 0x1A, 0x06, 0x00, 0xE0, 0x16, 0x04, 0x00, 0x40, 0x0D, 0x03, 0x00, 0x20, 0xBF, 0x02, 0x00, -+0x24, 0xCE, 0x15, 0x00, 0xB4, 0xCE, 0x15, 0x00, 0x94, 0xCD, 0x15, 0x00, 0xB8, 0xD0, 0x15, 0x00, 0x03, 0x00, 0x00, 0x00, -+0x00, 0x28, 0x00, 0x00, 0x39, 0x4B, 0x15, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x15, 0x4C, 0x15, 0x00, 0x01, 0x10, 0x00, 0x00, -+0xD5, 0x4B, 0x15, 0x00, 0x61, 0x76, 0x61, 0x69, 0x6C, 0x20, 0x3E, 0x3D, 0x20, 0x42, 0x43, 0x4E, 0x5F, 0x46, 0x49, 0x58, -+0x45, 0x44, 0x5F, 0x53, 0x49, 0x5A, 0x45, 0x5F, 0x46, 0x49, 0x45, 0x4C, 0x44, 0x53, 0x5F, 0x4C, 0x45, 0x4E, 0x00, 0x00, -+0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x5F, 0x6C, 0x65, 0x6E, 0x20, 0x3C, 0x3D, 0x20, 0x62, 0x75, 0x66, 0x5F, 0x6C, 0x65, -+0x6E, 0x00, 0x00, 0x00, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x73, 0x5F, 0x6C, 0x65, 0x6E, 0x20, 0x3E, 0x20, 0x30, 0x00, -+0x21, 0x72, 0x6D, 0x5F, 0x6E, 0x6F, 0x5F, 0x6D, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x5F, -+0x74, 0x6F, 0x5F, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x28, 0x29, 0x20, 0x7C, 0x7C, 0x20, 0x28, 0x72, 0x65, 0x71, 0x75, -+0x65, 0x73, 0x74, 0x2D, 0x3E, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x3D, 0x20, -+0x30, 0x29, 0x00, 0x00, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2D, 0x3E, 0x63, 0x68, 0x61, 0x6E, 0x5F, 0x63, 0x6E, -+0x74, 0x20, 0x3C, 0x3D, 0x20, 0x43, 0x4F, 0x5F, 0x41, 0x52, 0x52, 0x41, 0x59, 0x5F, 0x53, 0x49, 0x5A, 0x45, 0x28, 0x72, -+0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2D, 0x3E, 0x63, 0x68, 0x61, 0x6E, 0x5F, 0x6C, 0x69, 0x73, 0x74, 0x29, 0x00, 0x00, -+0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2D, 0x3E, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3D, 0x3D, 0x20, 0x4D, 0x41, 0x43, -+0x5F, 0x4D, 0x45, 0x41, 0x53, 0x5F, 0x52, 0x45, 0x51, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x42, 0x45, 0x41, 0x43, 0x4F, -+0x4E, 0x00, 0x00, 0x00, 0x72, 0x6D, 0x5F, 0x65, 0x6E, 0x76, 0x2E, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5F, 0x72, 0x65, -+0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x3E, 0x3D, 0x20, 0x30, 0x00, 0x00, 0x64, 0x69, 0x20, 0x53, 0x65, 0x70, 0x20, 0x31, -+0x33, 0x20, 0x32, 0x30, 0x32, 0x32, 0x20, 0x31, 0x30, 0x3A, 0x34, 0x37, 0x3A, 0x31, 0x34, 0x20, 0x2D, 0x20, 0x67, 0x37, -+0x34, 0x32, 0x30, 0x33, 0x31, 0x37, 0x31, 0x00, 0x76, 0x36, 0x2E, 0x34, 0x2E, 0x33, 0x2E, 0x31, 0x00, 0x00, 0x00, 0x00, -+0xF8, 0xB5, 0x00, 0xBF, 0xF8, 0xBC, 0x08, 0xBC, 0x9E, 0x46, 0x70, 0x47, 0xF8, 0xB5, 0x00, 0xBF, 0xF8, 0xBC, 0x08, 0xBC, -+0x9E, 0x46, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x74, 0x04, 0x17, 0x00, 0xDC, 0x04, 0x17, 0x00, 0x44, 0x05, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x33, 0xCD, 0xAB, -+0x34, 0x12, 0x6D, 0xE6, 0xEC, 0xDE, 0x05, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x04, 0x0E, 0x20, 0x00, 0x30, 0x00, 0x00, 0x00, 0x5B, -+0x4B, 0x00, 0x00, 0x04, 0x8E, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x32, 0x7B, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, -+0x26, 0x00, 0x00, 0xF8, 0x11, 0x00, 0x00, 0x04, 0x8E, 0x00, 0x19, 0x48, 0x20, 0x00, 0x00, 0x9C, 0x91, 0x01, 0x00, 0x08, -+0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x44, 0x10, 0x08, 0x00, 0x80, 0x01, 0x38, 0x41, 0x46, 0x00, 0x0C, -+0x14, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x17, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x30, -+0x00, 0x00, 0x00, 0x3C, 0x1A, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x38, 0x01, 0x00, 0x00, 0x40, 0x1D, 0x00, 0x00, 0x08, -+0x8E, 0x00, 0x08, 0x38, 0x50, 0x00, 0x00, 0x14, 0x20, 0x00, 0x00, 0x08, 0x8E, 0x00, 0x00, 0x40, 0x7B, 0x00, 0x00, 0xA4, -+0x01, 0x01, 0x00, 0x00, 0x9F, 0x33, 0x00, 0x30, 0x00, 0x07, 0x00, 0x41, 0x20, 0x44, 0x10, 0x04, 0x00, 0x00, 0x00, 0x90, -+0x00, 0x00, 0x00, 0x49, 0x2F, 0x84, 0x0E, 0xF0, 0x2C, 0x84, 0x0E, 0xEC, 0x2C, 0x84, 0x0E, 0xEC, 0x32, 0x00, 0x00, 0x04, -+0x00, 0x00, 0x00, 0x30, 0x01, 0x01, 0x00, 0x48, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x30, 0x02, 0x02, 0x00, 0x48, -+0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x46, 0x11, 0x00, 0x00, 0x04, 0x06, 0x00, 0x01, 0x58, -+0x72, 0x04, 0x04, 0x3D, 0x39, 0x44, 0x20, 0xDC, 0xD2, 0xD4, 0x1D, 0x08, 0x06, 0x00, 0x0A, 0x48, 0xDC, 0x44, 0x20, 0xDC, -+0x3C, 0xD4, 0x1D, 0x08, 0x04, 0x00, 0x05, 0x38, 0xC3, 0xF1, 0xF1, 0x0E, 0xDC, 0x44, 0x20, 0x34, 0x00, 0x00, 0x00, 0x30, -+0x00, 0x00, 0x00, 0x01, 0x42, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x33, 0x45, 0x44, 0x10, 0x04, -+0x00, 0x80, 0x00, 0x38, 0x9C, 0x10, 0x00, 0x22, 0x48, 0x44, 0x10, 0x08, 0x00, 0x80, 0x00, 0x38, 0x9C, 0x50, 0xD4, 0x23, -+0x17, 0x44, 0x10, 0x08, 0x00, 0xA0, 0x00, 0x90, 0x00, 0x00, 0x00, 0x32, 0x63, 0x00, 0x00, 0x18, 0x60, 0x00, 0x00, 0x14, -+0x51, 0x00, 0x00, 0x1C, 0x57, 0x00, 0x00, 0x10, 0x00, 0x80, 0x02, 0x38, 0x01, 0x00, 0x00, 0x0C, 0x66, 0x44, 0xD0, 0x08, -+0x0F, 0x20, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x38, 0x01, 0x26, 0x00, 0x0C, -+0x5A, 0x44, 0xD0, 0x08, 0x00, 0x00, 0x00, 0x30, 0x30, 0x02, 0x02, 0x3D, 0x5D, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x30, -+0x00, 0x01, 0x00, 0x3E, 0x66, 0x00, 0x00, 0x04, 0x00, 0x80, 0x02, 0x38, 0x01, 0x16, 0x00, 0x0C, 0x66, 0x44, 0x20, 0x34, -+0x00, 0x80, 0x02, 0x38, 0x01, 0x0A, 0x00, 0x0C, 0x66, 0x44, 0x20, 0x34, 0x04, 0x80, 0x00, 0x38, 0x00, 0x00, 0x00, 0xFF, -+0x7B, 0x00, 0x00, 0x08, 0x2F, 0x80, 0x00, 0x38, 0x00, 0x00, 0x00, 0x26, 0x6C, 0x00, 0x00, 0x08, 0xAF, 0x04, 0x04, 0x38, -+0x10, 0x10, 0x19, 0x1F, 0x6F, 0x00, 0x00, 0x08, 0xAF, 0x0C, 0x00, 0x20, 0x71, 0x00, 0x00, 0x04, 0xAF, 0x0C, 0x00, 0x60, -+0x79, 0x00, 0x70, 0x18, 0x77, 0x00, 0x00, 0x14, 0x75, 0x00, 0x00, 0x10, 0xAF, 0x0C, 0x14, 0x28, 0x84, 0x00, 0xB0, 0x09, -+0xAF, 0x0C, 0x0A, 0x28, 0x84, 0x00, 0xB0, 0x09, 0xAF, 0x0C, 0x06, 0x28, 0x84, 0x00, 0xB0, 0x09, 0x86, 0x80, 0x04, 0x28, -+0x7D, 0x00, 0x00, 0x08, 0x86, 0x00, 0x00, 0x38, 0x00, 0x00, 0x80, 0x22, 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x30, -+0x01, 0xF1, 0xF1, 0x0E, 0x83, 0x48, 0x00, 0x36, 0x00, 0x00, 0x02, 0x28, 0x85, 0x00, 0x00, 0x08, 0x8E, 0x00, 0x02, 0x38, -+0x31, 0x04, 0x04, 0x3D, 0x88, 0x00, 0x00, 0x08, 0x8E, 0x00, 0x05, 0x38, 0x21, 0x18, 0x24, 0x1F, 0x8B, 0x00, 0x00, 0x08, -+0x8E, 0x00, 0x00, 0x30, 0x21, 0x30, 0x16, 0xA0, 0x8E, 0x00, 0x00, 0x04, 0x8E, 0x00, 0x00, 0x30, 0x12, 0x00, 0xF1, 0x0E, -+0x91, 0x00, 0x00, 0x34, 0xCC, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x50, 0x94, 0x00, 0x00, 0x04, 0xFE, 0x95, 0x00, 0x38, -+0x00, 0x00, 0x01, 0x32, 0x97, 0x00, 0x00, 0x04, 0xFE, 0x1F, 0x00, 0x50, 0x00, 0x00, 0x01, 0x5A, 0x9B, 0x98, 0xC9, 0x6D, -+0xB9, 0xD4, 0x19, 0xFC, 0x86, 0x01, 0x00, 0x30, 0x73, 0x03, 0x84, 0x3D, 0x9E, 0x00, 0x00, 0x04, 0x8E, 0x00, 0x00, 0x30, -+0x00, 0x00, 0x00, 0x0A, 0xA1, 0x00, 0x00, 0x04, 0x8E, 0x00, 0x00, 0x30, 0x00, 0x00, 0xC0, 0x22, 0xA4, 0x00, 0x00, 0x04, -+0x8E, 0x02, 0x00, 0x90, 0x01, 0x00, 0x01, 0x32, 0xAA, 0x00, 0x40, 0x8E, 0xB0, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x30, 0x01, 0x00, 0x01, 0x32, 0xCB, 0x00, 0x00, 0x04, 0x8E, 0x00, 0x00, 0x30, -+0x00, 0x00, 0x00, 0x29, 0x11, 0x50, 0x04, 0x94, 0xB6, 0x19, 0x00, 0x30, 0x00, 0x00, 0x01, 0x32, 0xB3, 0x00, 0x00, 0x04, -+0xB6, 0x19, 0x00, 0x30, 0x31, 0x04, 0x04, 0x3D, 0xB6, 0x00, 0x00, 0x04, 0xB6, 0x19, 0x00, 0x30, 0x00, 0x00, 0x80, 0x22, -+0x97, 0x00, 0x00, 0x04, 0x86, 0x01, 0x00, 0x30, 0x73, 0x04, 0x84, 0x3D, 0xBC, 0x00, 0x00, 0x04, 0x8E, 0x00, 0x00, 0x30, -+0x00, 0x00, 0x03, 0x29, 0xBF, 0x00, 0x00, 0x04, 0x8E, 0x02, 0xEE, 0x9A, 0x00, 0x01, 0x01, 0x32, 0xC5, 0x00, 0x00, 0x7C, -+0xB0, 0x00, 0x00, 0xCC, 0xB0, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x30, 0x00, 0x01, 0x01, 0x32, -+0xC8, 0x00, 0x00, 0x04, 0x8E, 0x02, 0x00, 0x30, 0x00, 0x00, 0x00, 0x29, 0x11, 0x50, 0x04, 0x94, 0x8E, 0x03, 0x00, 0x50, -+0x00, 0x00, 0x00, 0x29, 0x11, 0x50, 0x04, 0x94, 0x35, 0x00, 0x00, 0xC0, 0x06, 0x00, 0x01, 0x38, 0x72, 0x04, 0x04, 0x3D, -+0xD2, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x30, 0x41, 0xF1, 0xF1, 0x0E, 0xD5, 0x00, 0x00, 0x34, 0x04, 0x00, 0x04, 0x28, -+0xD7, 0x00, 0x00, 0x08, 0x0E, 0x00, 0x08, 0x28, 0xD9, 0x00, 0x00, 0x08, 0x8E, 0x01, 0x00, 0x30, 0x52, 0x00, 0xF1, 0x0E, -+0xDC, 0x00, 0x00, 0x34, 0x8E, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x29, 0x11, 0x50, 0x04, 0x94, 0x00, 0x00, 0x02, 0x38, -+0x00, 0x00, 0x00, 0x32, 0xE2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x60, 0xE6, 0x00, 0x00, 0xD8, 0xE9, 0x00, 0x00, 0xD4, -+0xEC, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x30, 0x21, 0xF1, 0xF1, 0x0E, 0xEF, 0x48, 0x00, 0x36, 0x00, 0x00, 0x00, 0x30, -+0x21, 0x24, 0x00, 0x0C, 0xEF, 0x48, 0x00, 0x36, 0x00, 0x00, 0x00, 0x30, 0x21, 0x00, 0x00, 0x0C, 0xEF, 0x48, 0x00, 0x36, -+0x00, 0x00, 0x02, 0x28, 0x7B, 0x00, 0x00, 0x08, 0xFE, 0x1E, 0x00, 0x50, 0x00, 0x00, 0x01, 0x5A, 0xF5, 0x98, 0xC9, 0x6D, -+0xF8, 0xD4, 0x19, 0xFC, 0x8E, 0x02, 0x00, 0x30, 0x40, 0x00, 0x00, 0x32, 0xFB, 0x00, 0x00, 0x04, 0x8E, 0x02, 0xEE, 0x3A, -+0x80, 0x00, 0x00, 0x32, 0xFB, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x30, 0x01, 0xF1, 0xF1, 0x0E, 0xFE, 0x48, 0x00, 0x36, -+0x00, 0x00, 0x02, 0x28, 0x00, 0x01, 0x00, 0x08, 0x8E, 0x00, 0x02, 0x38, 0x31, 0x04, 0x04, 0x3D, 0x03, 0x01, 0x00, 0x08, -+0x8E, 0x00, 0x05, 0x38, 0x21, 0x18, 0x24, 0x1F, 0x06, 0x01, 0x00, 0x08, 0x8E, 0x00, 0x00, 0x30, 0x21, 0x30, 0x16, 0xA0, -+0x09, 0x01, 0x00, 0x04, 0x8E, 0x00, 0x00, 0x30, 0x12, 0x00, 0xF1, 0x0E, 0x0C, 0x01, 0x00, 0x34, 0xF6, 0x14, 0x00, 0x30, -+0x00, 0x00, 0x01, 0x32, 0x14, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x11, 0x01, 0x00, 0x04, 0xEC, 0x00, 0x00, 0x30, -+0x00, 0x00, 0x00, 0x50, 0xF1, 0x00, 0x00, 0x04, 0xF6, 0x14, 0x00, 0x30, 0x00, 0x00, 0x03, 0x32, 0x17, 0x01, 0x00, 0x04, -+0x86, 0x10, 0x00, 0x30, 0x73, 0x04, 0x84, 0x3D, 0x1A, 0x01, 0x00, 0x04, 0x8E, 0x10, 0x00, 0x50, 0x00, 0x00, 0xC0, 0x22, -+0xCB, 0xC0, 0x47, 0x8E, 0x1E, 0x01, 0x30, 0xCB, 0xB6, 0x19, 0x00, 0x30, 0x00, 0x00, 0x04, 0x32, 0x21, 0x01, 0x00, 0x04, -+0xB6, 0x19, 0x00, 0x30, 0x31, 0x04, 0x04, 0x3D, 0x24, 0x01, 0x00, 0x04, 0xB6, 0x19, 0x00, 0x30, 0x00, 0x00, 0x80, 0x22, -+0x11, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x01, 0x00, 0x30, -+0x73, 0x04, 0x84, 0x3D, 0x2D, 0x01, 0x00, 0x04, 0x8E, 0x03, 0x00, 0x50, 0x00, 0x00, 0x00, 0x29, 0x11, 0x50, 0x04, 0x94, -+0x31, 0x01, 0x00, 0xC0, 0x0E, 0x80, 0x0C, 0x38, 0x00, 0x00, 0x00, 0xFF, 0x34, 0x01, 0x00, 0x08, 0x04, 0x00, 0x00, 0x30, -+0x03, 0xF1, 0xF1, 0x0F, 0x37, 0x01, 0x00, 0x34, 0x00, 0x00, 0x02, 0x28, 0x39, 0x01, 0x00, 0x08, 0x8E, 0x03, 0x00, 0x30, -+0x00, 0x00, 0x00, 0x29, 0x11, 0x50, 0x04, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x06, 0x00, 0x01, 0x58, 0x72, 0x04, 0x04, 0x3D, 0x43, 0x45, 0x20, 0xDC, 0xD2, 0xD4, 0x1D, 0x08, 0x06, 0x00, 0x0A, 0x48, -+0xDC, 0x44, 0x20, 0xDC, 0x46, 0xD5, 0x1D, 0x08, 0x04, 0x00, 0x05, 0x38, 0x41, 0xF1, 0xF1, 0x0E, 0xDC, 0x44, 0x20, 0x34, -+0x0E, 0x80, 0x02, 0x28, 0xDC, 0x00, 0x00, 0x08, 0x35, 0x00, 0x00, 0x48, 0x4A, 0x01, 0x00, 0x04, 0x8F, 0x63, 0x96, 0x78, -+0x0F, 0x00, 0x00, 0x41, 0x4F, 0x01, 0x00, 0x8C, 0xC4, 0x50, 0x04, 0x08, 0x74, 0x45, 0x10, 0x90, 0x0F, 0x62, 0xC8, 0x88, -+0x5A, 0x01, 0x00, 0xC0, 0x74, 0x45, 0x10, 0x90, 0x54, 0x45, 0x10, 0x08, 0x57, 0x45, 0x10, 0x94, 0x8F, 0x62, 0x00, 0x30, -+0x00, 0x00, 0x00, 0x29, 0x7A, 0x51, 0x04, 0x94, 0x8F, 0x63, 0x00, 0x30, 0x00, 0x00, 0x00, 0x29, 0x7A, 0x45, 0x10, 0x04, -+0x05, 0xE0, 0x00, 0x38, 0x31, 0x01, 0x01, 0x3D, 0x5D, 0x45, 0x10, 0x08, 0x0F, 0x60, 0x32, 0xA8, 0x74, 0x45, 0x10, 0x90, -+0x54, 0x01, 0x00, 0x08, 0x57, 0x45, 0x10, 0x94, 0x67, 0x45, 0x10, 0xC6, 0x63, 0x55, 0x18, 0xC4, 0x0F, 0xE0, 0x02, 0x58, -+0x07, 0xEA, 0xEE, 0x0F, 0x74, 0x01, 0x00, 0x80, 0x6B, 0x45, 0x20, 0x34, 0x0F, 0xE0, 0x02, 0x58, 0x07, 0xEA, 0xEE, 0x0E, -+0x74, 0x01, 0x00, 0x80, 0x6B, 0x45, 0x20, 0x34, 0x00, 0x40, 0x00, 0x30, 0x01, 0x00, 0x00, 0x33, 0x6E, 0x01, 0x00, 0x04, -+0x05, 0x40, 0x03, 0x38, 0x73, 0x03, 0x03, 0x3D, 0x71, 0x01, 0x00, 0x08, 0x07, 0x60, 0x00, 0x30, 0x00, 0x00, 0x00, 0x33, -+0x74, 0x01, 0x00, 0x04, 0x8F, 0x60, 0x00, 0x30, 0x00, 0x00, 0x00, 0x29, 0x77, 0x51, 0x04, 0x94, 0x8F, 0x60, 0x00, 0x40, -+0x7D, 0x45, 0x10, 0xA0, 0x7A, 0x45, 0x10, 0x04, 0x8F, 0x60, 0x00, 0x30, 0x01, 0x01, 0x00, 0x64, 0x11, 0x44, 0x10, 0x04, -+0x8F, 0x60, 0x00, 0x30, 0x01, 0x01, 0x00, 0x64, 0x80, 0x45, 0x10, 0x04, 0x8F, 0x61, 0x00, 0x30, 0x01, 0x00, 0x00, 0x42, -+0x83, 0x01, 0x00, 0x04, 0x00, 0x80, 0x02, 0x38, 0x00, 0x00, 0x00, 0x32, 0x86, 0x45, 0x10, 0x08, 0x8F, 0x61, 0x0A, 0x28, -+0x88, 0x01, 0x00, 0x08, 0x8F, 0x61, 0x0A, 0x48, 0x8B, 0x01, 0x00, 0xBC, 0x8E, 0x01, 0x00, 0x08, 0x8F, 0x61, 0x00, 0x30, -+0x01, 0x00, 0x00, 0x34, 0x05, 0x00, 0x00, 0x04, 0x8F, 0x61, 0x00, 0x30, 0x00, 0x00, 0x00, 0x34, 0x08, 0x00, 0x00, 0x04, -+0x8F, 0x00, 0x00, 0x30, 0x0F, 0xED, 0xEA, 0x0E, 0x94, 0x01, 0x00, 0x36, 0x00, 0x80, 0x03, 0x38, 0x00, 0x00, 0x00, 0x34, -+0x97, 0x01, 0x00, 0x08, 0x05, 0x80, 0x02, 0x38, 0x02, 0x00, 0x01, 0x29, 0x9A, 0x01, 0x00, 0x08, 0x8F, 0x02, 0x00, 0x30, -+0x9C, 0x20, 0x00, 0x22, 0x9D, 0x01, 0x00, 0x04, 0x8F, 0x02, 0x00, 0x30, 0x9C, 0x50, 0xD4, 0x23, 0xA0, 0x01, 0x00, 0x04, -+0x8F, 0x02, 0x14, 0x28, 0xA2, 0x01, 0x00, 0x08, 0x8F, 0x02, 0x00, 0x30, 0x01, 0x02, 0x01, 0x43, 0xA5, 0x01, 0x00, 0x04, -+0x8F, 0x12, 0x00, 0x30, 0x00, 0x01, 0x00, 0x32, 0xA8, 0x01, 0x00, 0x04, 0x8F, 0x13, 0xEE, 0x5A, 0x0F, 0x00, 0x00, 0x41, -+0xAC, 0x01, 0x00, 0x7C, 0xF9, 0x00, 0x00, 0x08, 0x8F, 0x13, 0x2C, 0x59, 0x00, 0x00, 0x00, 0x29, 0xB0, 0x01, 0x00, 0x8C, -+0xF9, 0x00, 0x00, 0x08, 0x8F, 0x13, 0x00, 0x20, 0x11, 0x50, 0x04, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x76, 0x76, 0x00, 0x70, 0xF8, 0xF8, 0x1D, -+0x70, 0xF8, 0xF8, 0x1D, 0x70, 0xF8, 0xF8, 0x1D, 0x70, 0xF8, 0xF8, 0x1D, 0x72, 0x6E, 0x6E, 0x00, 0x69, 0xF8, 0xF8, 0x1D, -+0x69, 0xF8, 0xF8, 0x1D, 0x69, 0xF8, 0xF8, 0x1D, 0x69, 0xF8, 0xF8, 0x1D, 0x7B, 0x76, 0x76, 0x00, 0x70, 0xF8, 0xF8, 0x1D, -+0x70, 0xF8, 0xF8, 0x1D, 0x70, 0xF8, 0xF8, 0x1D, 0x70, 0xF8, 0xF8, 0x1D, 0x85, 0x7E, 0x7E, 0x00, 0x76, 0xF8, 0xF4, 0x1D, -+0x76, 0xF8, 0xF4, 0x1D, 0x76, 0xF8, 0xF4, 0x1D, 0x76, 0xF8, 0xF8, 0x1D, 0x8A, 0x81, 0x81, 0x00, 0x7B, 0xF8, 0xF8, 0x1D, -+0x7B, 0xF8, 0xF8, 0x1D, 0x7B, 0xF8, 0xF8, 0x1D, 0x7B, 0xF8, 0xF8, 0x1D, 0x8D, 0x81, 0x81, 0x00, 0x7B, 0xF8, 0xF8, 0x1D, -+0x7B, 0xF8, 0xF8, 0x1D, 0x7B, 0xF8, 0xF8, 0x1D, 0x7B, 0xF8, 0xF8, 0x1D, 0x8A, 0x81, 0x81, 0x00, 0x7B, 0xF8, 0xF8, 0x1D, -+0x7C, 0xF8, 0xF8, 0x1D, 0x7B, 0xF8, 0xF8, 0x1D, 0x7B, 0xF8, 0xF8, 0x1D, 0x40, 0x7E, 0x7E, 0x00, 0x7B, 0xF8, 0xF8, 0x1D, -+0x7B, 0xF8, 0xF8, 0x1D, 0x7B, 0xF8, 0xF8, 0x1D, 0x7B, 0xF8, 0xF8, 0x1D, 0x92, 0x8B, 0x8B, 0x00, 0x87, 0xF8, 0xF8, 0x1D, -+0x89, 0xF8, 0xF8, 0x1D, 0x87, 0xF8, 0xF8, 0x1D, 0x87, 0xF8, 0xF8, 0x1D, 0x55, 0x51, 0x51, 0x00, 0x4C, 0xF8, 0xF8, 0x1D, -+0x4C, 0xF8, 0xF8, 0x1D, 0x89, 0xF8, 0xF8, 0x1D, 0x89, 0xF8, 0xF8, 0x1D, 0x54, 0x51, 0x51, 0x00, 0x4C, 0xF8, 0xF8, 0x1D, -+0x4C, 0xF8, 0xF8, 0x1D, 0x88, 0xF8, 0xF8, 0x1D, 0x88, 0xF8, 0xF8, 0x1D, 0x53, 0x4F, 0x4F, 0x00, 0x4A, 0xF8, 0xF8, 0x1D, -+0x4A, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x53, 0x4F, 0x4F, 0x00, 0x4A, 0xF8, 0xF8, 0x1D, -+0x4A, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x53, 0x4F, 0x4F, 0x00, 0x4A, 0xF8, 0xF8, 0x1D, -+0x4A, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x53, 0x4E, 0x4E, 0x00, 0x49, 0xF8, 0xF8, 0x1D, -+0x48, 0xF8, 0xF8, 0x1D, 0x48, 0xF8, 0xF8, 0x1D, 0x48, 0xF8, 0xF8, 0x1D, 0x52, 0x4D, 0x4D, 0x00, 0x47, 0xF8, 0xF8, 0x1D, -+0x47, 0xF8, 0xF8, 0x1D, 0x47, 0xF8, 0xF8, 0x1D, 0x47, 0xF8, 0xF8, 0x1D, 0x55, 0x4F, 0x4F, 0x00, 0x4B, 0xF8, 0xF8, 0x1D, -+0x4A, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x53, 0x4E, 0x4E, 0x00, 0x49, 0xF8, 0xF8, 0x1D, -+0x48, 0xF8, 0xF8, 0x1D, 0x48, 0xF8, 0xF8, 0x1D, 0x48, 0xF8, 0xF8, 0x1D, 0x4D, 0x49, 0x49, 0x00, 0x44, 0xF8, 0xF8, 0x1D, -+0x44, 0xF8, 0xF8, 0x1D, 0x44, 0xF8, 0xF8, 0x1D, 0x44, 0xF8, 0xF8, 0x1D, 0x8F, 0x51, 0x51, 0x00, 0x49, 0xF8, 0xF8, 0x1D, -+0x48, 0xF8, 0xF8, 0x1D, 0x48, 0xF8, 0xF8, 0x1D, 0x48, 0xF8, 0xF8, 0x1D, 0x77, 0x42, 0x42, 0x00, 0x3F, 0xF8, 0xF8, 0x1D, -+0x3C, 0xF8, 0xF8, 0x1D, 0x3C, 0xF8, 0xF8, 0x1D, 0x3C, 0xF8, 0xF8, 0x1D, 0x75, 0x42, 0x42, 0x00, 0x9E, 0xF8, 0xF8, 0x1D, -+0x3C, 0xF8, 0xF8, 0x1D, 0x3C, 0xF8, 0xF8, 0x1D, 0x3C, 0xF8, 0xF8, 0x1D, 0x5C, 0x55, 0x55, 0x00, 0x4C, 0xF8, 0xF8, 0x1D, -+0x4C, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0x5C, 0x53, 0x53, 0x00, 0x4C, 0xF8, 0xF8, 0x1D, -+0x4B, 0xF8, 0xF8, 0x1D, 0x4B, 0xF8, 0xF8, 0x1D, 0x4B, 0xF8, 0xF8, 0x1D, 0x9E, 0xF8, 0xF8, 0x00, 0x8C, 0xF8, 0xF8, 0x1D, -+0x4A, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x40, 0x89, 0x89, 0x00, 0x46, 0xF8, 0xF8, 0x18, -+0x45, 0xF8, 0xCF, 0x18, 0x44, 0xF8, 0xCF, 0x18, 0x44, 0xF8, 0xCF, 0x18, 0x5F, 0x56, 0x56, 0x00, 0x4F, 0xF8, 0xF8, 0x1D, -+0x4F, 0xF8, 0xF8, 0x1D, 0x4F, 0xF8, 0xF8, 0x1D, 0x4F, 0xF8, 0xF8, 0x1D, 0x5E, 0x55, 0x55, 0x00, 0x4E, 0xF8, 0xF8, 0x1D, -+0x4E, 0xF8, 0xF8, 0x1D, 0x4E, 0xF8, 0xF8, 0x1D, 0x4E, 0xF8, 0xF8, 0x1D, 0x5F, 0x56, 0x56, 0x00, 0x4F, 0xF8, 0xF8, 0x1D, -+0x4F, 0xF8, 0xF8, 0x1D, 0x4F, 0xF8, 0xF8, 0x1D, 0x4F, 0xF8, 0xF8, 0x1D, 0x61, 0x55, 0x55, 0x00, 0x50, 0xF8, 0xF8, 0x1D, -+0x4E, 0xF8, 0xF8, 0x1D, 0x4E, 0xF8, 0xF8, 0x1D, 0x4E, 0xF8, 0xF8, 0x1D, 0x5F, 0x53, 0x53, 0x00, 0x4D, 0xF8, 0xF8, 0x1D, -+0x4C, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0x5F, 0x55, 0x55, 0x00, 0x4F, 0xF8, 0xF8, 0x1D, -+0x4E, 0xF8, 0xF8, 0x1D, 0x4E, 0xF8, 0xF8, 0x1D, 0x4E, 0xF8, 0xF8, 0x1D, 0xAA, 0x55, 0x55, 0x00, 0x54, 0xF8, 0xF8, 0x1D, -+0x4E, 0xF8, 0xF8, 0x1D, 0x4E, 0xF8, 0xF8, 0x1D, 0x4E, 0xF8, 0xF8, 0x1D, 0xA6, 0x59, 0x59, 0x00, 0x4D, 0xF8, 0xF8, 0x1D, -+0x4C, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0x9B, 0x4F, 0x4F, 0x00, 0x4E, 0xF8, 0xF8, 0x1D, -+0x46, 0xF8, 0xF8, 0x1D, 0x46, 0xF8, 0xF8, 0x1D, 0x46, 0xF8, 0xF8, 0x1D, 0xA5, 0xF8, 0xF8, 0x00, 0x94, 0xF8, 0xF8, 0x1D, -+0x4C, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0xA4, 0x98, 0x98, 0x00, 0x4D, 0xF8, 0xF8, 0x1D, -+0x4C, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0x86, 0x46, 0x46, 0x00, 0xB3, 0xF8, 0xF8, 0x1D, -+0x3D, 0xF8, 0xF8, 0x1D, 0x3D, 0xF8, 0xF8, 0x1D, 0x3D, 0xF8, 0xF8, 0x1D, 0x40, 0x8E, 0x8E, 0x00, 0x48, 0xF8, 0xF8, 0x1A, -+0x48, 0xF8, 0xDF, 0x1A, 0x46, 0xF8, 0xDF, 0x1A, 0x46, 0xF8, 0xDF, 0x1A, 0x40, 0x7F, 0x7F, 0x00, 0x75, 0xD2, 0xD2, 0x18, -+0x3A, 0xD2, 0xD2, 0x18, 0x3A, 0xD2, 0xD2, 0x18, 0x39, 0xD2, 0xD2, 0x18, 0x40, 0x45, 0x45, 0x00, 0x64, 0x86, 0x86, 0x0F, -+0x3E, 0x86, 0x86, 0x0F, 0x3D, 0x86, 0x86, 0x0F, 0x3D, 0x86, 0x86, 0x0F, 0x64, 0x5C, 0x5C, 0x00, 0x56, 0xF8, 0xF8, 0x1D, -+0x55, 0xF8, 0xF8, 0x1D, 0x55, 0xF8, 0xF8, 0x1D, 0x55, 0xF8, 0xF8, 0x1D, 0x68, 0x5B, 0x5B, 0x00, 0x58, 0xF8, 0xF8, 0x1D, -+0x55, 0xF8, 0xF8, 0x1D, 0x55, 0xF8, 0xF8, 0x1D, 0x55, 0xF8, 0xF8, 0x1D, 0x64, 0x5A, 0x5A, 0x00, 0x55, 0xF8, 0xF8, 0x1D, -+0x54, 0xF8, 0xF8, 0x1D, 0x54, 0xF8, 0xF8, 0x1D, 0x54, 0xF8, 0xF8, 0x1D, 0xB5, 0x5A, 0x5A, 0x00, 0x5B, 0xF8, 0xF8, 0x1D, -+0x55, 0xF8, 0xF8, 0x1D, 0x54, 0xF8, 0xF8, 0x1D, 0x54, 0xF8, 0xF8, 0x1D, 0xB0, 0xF8, 0xF8, 0x00, 0xA3, 0xF8, 0xF8, 0x1D, -+0x52, 0xF8, 0xF8, 0x1D, 0x52, 0xF8, 0xF8, 0x1D, 0x52, 0xF8, 0xF8, 0x1D, 0xAE, 0xA4, 0xA4, 0x00, 0x54, 0xF8, 0xF8, 0x1D, -+0x52, 0xF8, 0xF8, 0x1D, 0x52, 0xF8, 0xF8, 0x1D, 0x52, 0xF8, 0xF8, 0x1D, 0x40, 0x9A, 0x9A, 0x00, 0x4E, 0xF8, 0xF8, 0x1D, -+0x4D, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0x4C, 0xF8, 0xF8, 0x1D, 0x40, 0x9C, 0x9C, 0x00, 0x95, 0xF8, 0xF8, 0x1D, -+0x49, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x4A, 0xF8, 0xF8, 0x1D, 0x40, 0x49, 0x49, 0x00, 0x6F, 0x97, 0x97, 0x11, -+0x42, 0x97, 0x97, 0x11, 0x41, 0x97, 0x97, 0x11, 0x41, 0x97, 0x97, 0x11, 0x74, 0x6E, 0x6E, 0x00, 0x69, 0xF8, 0xF8, 0x1D, -+0x69, 0xF8, 0xF8, 0x1D, 0x69, 0xF8, 0xF8, 0x1D, 0x69, 0xF8, 0xF8, 0x1D, 0x40, 0x6E, 0x6E, 0x00, 0x69, 0xF8, 0xDE, 0x1A, -+0x69, 0xF8, 0xDE, 0x1A, 0x69, 0xF8, 0xDE, 0x1A, 0x69, 0xF8, 0xDE, 0x1A, 0x40, 0x75, 0x75, 0x00, 0x6E, 0xF8, 0x78, 0x0D, -+0x6E, 0xF8, 0x78, 0x0D, 0x6E, 0xF8, 0x78, 0x0D, 0x6E, 0xF8, 0x79, 0x0D, 0x85, 0x78, 0x78, 0x00, 0x73, 0xF8, 0xF8, 0x1D, -+0x73, 0xF8, 0xF8, 0x1D, 0x73, 0xF8, 0xF8, 0x1D, 0x73, 0xF8, 0xF8, 0x1D, 0x40, 0x78, 0x78, 0x00, 0x73, 0xF8, 0xF8, 0x1D, -+0x73, 0xF8, 0xF8, 0x1D, 0x73, 0xF8, 0xF8, 0x1D, 0x73, 0xF8, 0xF8, 0x1D, 0x40, 0x78, 0x78, 0x00, 0x73, 0xF8, 0x81, 0x0E, -+0x73, 0xF8, 0x81, 0x0E, 0x73, 0xF8, 0x81, 0x0E, 0x73, 0xF8, 0x82, 0x0E, 0x40, 0x40, 0x40, 0x00, 0x73, 0xF8, 0x82, 0x0E, -+0x73, 0xF8, 0x82, 0x0E, 0x73, 0xF8, 0x82, 0x0E, 0x73, 0xF8, 0x82, 0x0E, 0x40, 0x81, 0x81, 0x00, 0x7E, 0xF8, 0x92, 0x10, -+0x7E, 0xF8, 0x92, 0x10, 0x7E, 0xF8, 0x92, 0x10, 0x7E, 0xF8, 0x92, 0x10, 0x40, 0x40, 0x40, 0x00, 0x7E, 0xF8, 0x92, 0x10, -+0x7E, 0xF8, 0x92, 0x10, 0x7E, 0xF8, 0x92, 0x10, 0x7E, 0xF8, 0x92, 0x10, 0x40, 0x73, 0x73, 0x00, 0x6B, 0xB2, 0xB2, 0x14, -+0x35, 0xB2, 0xB2, 0x14, 0x35, 0xB2, 0xB2, 0x14, 0x35, 0xB2, 0xB2, 0x14, 0x40, 0x40, 0x40, 0x00, 0x60, 0x82, 0x82, 0x0E, -+0x3D, 0x82, 0x82, 0x0E, 0x3C, 0x82, 0x82, 0x0E, 0x3C, 0x82, 0x82, 0x0E, 0x40, 0x40, 0x40, 0x00, 0x66, 0x8B, 0x8B, 0x0F, -+0x3F, 0x8B, 0x8B, 0x0F, 0x3D, 0x8B, 0x8B, 0x0F, 0x3D, 0x8B, 0x8B, 0x0F, 0x40, 0x40, 0x40, 0x00, 0x3D, 0x68, 0x68, 0x0B, -+0x1E, 0x68, 0x68, 0x0B, 0x1E, 0x68, 0x68, 0x0B, 0x1E, 0x68, 0x68, 0x0B, 0x40, 0x22, 0x22, 0x00, 0x18, 0x43, 0x43, 0x06, -+0x29, 0x43, 0x43, 0x06, 0x18, 0x43, 0x43, 0x06, 0x18, 0x43, 0x43, 0x06, 0x40, 0x40, 0x40, 0x00, 0x72, 0x9D, 0x9D, 0x12, -+0x43, 0x9D, 0x9D, 0x12, 0x41, 0x9D, 0x9D, 0x12, 0x41, 0x9D, 0x9D, 0x12, 0x40, 0x40, 0x40, 0x00, 0x42, 0x75, 0x75, 0x0D, -+0x20, 0x75, 0x75, 0x0D, 0x20, 0x75, 0x75, 0x0D, 0x20, 0x75, 0x75, 0x0D, 0x40, 0x23, 0x23, 0x00, 0x19, 0x4C, 0x4C, 0x08, -+0x2C, 0x4C, 0x4C, 0x08, 0x19, 0x4C, 0x4C, 0x08, 0x19, 0x4C, 0x4C, 0x08, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xA8, -+0xB8, 0xC8, 0xD8, 0xF8, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0x08, 0x58, 0x68, 0x78, 0x88, -+0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, 0x09, 0x01, 0x03, 0x1E, 0x00, 0x00, 0x75, 0x19, 0x03, 0x00, 0x75, 0x19, 0x03, -+0x80, 0x80, 0x80, 0x80, 0x22, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x04, 0x63, 0xA3, 0xAC, 0x0F, 0x80, 0x80, 0x80, 0x80, -+0x22, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x04, 0x63, 0xA3, 0x8C, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x22, 0x3E, 0x39, 0x00, -+0xB4, 0x00, 0x0F, 0x04, 0x62, 0x03, 0x8D, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x44, -+0x61, 0x03, 0x8D, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x46, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x84, 0x60, 0x23, 0x8D, 0x0F, -+0x80, 0x80, 0x80, 0x80, 0x58, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0xC4, 0x60, 0xE3, 0x0C, 0x0F, 0x80, 0x80, 0x80, 0x80, -+0xB4, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x44, 0x60, 0xE3, 0x8C, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x46, 0x3E, 0x39, 0x00, -+0xB4, 0x00, 0x0F, 0x84, 0x60, 0xC3, 0x0C, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x22, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x04, -+0x60, 0xCB, 0x0C, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x44, 0x60, 0xB3, 0x0C, 0x0E, -+0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x2A, 0x00, 0xB5, 0x5A, 0x2F, 0x44, 0x60, 0xD3, 0x0C, 0x0E, 0x80, 0x80, 0x80, 0x80, -+0x34, 0x3E, 0x2A, 0x00, 0xB5, 0x5A, 0x2F, 0x44, 0x60, 0x1B, 0x0F, 0x0E, 0x80, 0x80, 0x80, 0x80, 0xA2, 0x3E, 0x2A, 0x00, -+0xB5, 0x5A, 0x3F, 0x04, 0x60, 0x9B, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, 0xD8, 0x3E, 0x2A, 0x00, 0xB5, 0x5A, 0x3F, 0xC4, -+0x60, 0xFB, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x58, 0x3F, 0x2A, 0x00, 0xB5, 0x5A, 0x3F, 0xC4, 0x60, 0xFB, 0x11, 0x0E, -+0x80, 0x80, 0x80, 0x80, 0xD8, 0x3F, 0x2A, 0x00, 0xB5, 0x5A, 0x3F, 0xC4, 0x60, 0xFB, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, -+0x22, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x04, 0x63, 0xA3, 0xAC, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x22, 0x2E, 0x39, 0x00, -+0xB4, 0x00, 0x0F, 0x04, 0x63, 0xA3, 0x8C, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x22, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x04, -+0x62, 0x03, 0x8D, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x34, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x44, 0x61, 0x03, 0x8D, 0x0F, -+0x80, 0x80, 0x80, 0x80, 0x46, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x84, 0x60, 0x23, 0x8D, 0x0F, 0x80, 0x80, 0x80, 0x80, -+0x58, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0xC4, 0x60, 0xE3, 0x0C, 0x0F, 0x80, 0x80, 0x80, 0x80, 0xB4, 0x2E, 0x39, 0x00, -+0xB4, 0x00, 0x0F, 0x44, 0x60, 0xE3, 0x8C, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x46, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x84, -+0x60, 0xC3, 0x0C, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x22, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x04, 0x60, 0xCB, 0x0C, 0x0E, -+0x80, 0x80, 0x80, 0x80, 0x34, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x44, 0x60, 0xB3, 0x0C, 0x0E, 0x80, 0x80, 0x80, 0x80, -+0x34, 0x2E, 0x2A, 0x00, 0xB5, 0x5A, 0x2F, 0x44, 0x60, 0xD3, 0x0C, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x34, 0x2E, 0x2A, 0x00, -+0xB5, 0x5A, 0x2F, 0x44, 0x60, 0x1B, 0x0F, 0x0E, 0x80, 0x80, 0x80, 0x80, 0xA2, 0x2E, 0x2A, 0x00, 0xB5, 0x5A, 0x2F, 0x04, -+0x60, 0x9B, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, 0xD8, 0x2E, 0x2A, 0x00, 0xB5, 0x5A, 0x2F, 0xC4, 0x60, 0xFB, 0x11, 0x0E, -+0x80, 0x80, 0x80, 0x80, 0x58, 0x2F, 0x2A, 0x00, 0xB5, 0x5A, 0x2F, 0xC4, 0x60, 0xFB, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, -+0xD8, 0x2F, 0x2A, 0x00, 0xB5, 0x5A, 0x2F, 0xC4, 0x60, 0xFB, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x00, 0xBE, 0x7F, 0x00, -+0x6C, 0x00, 0x0F, 0x03, 0x60, 0xE7, 0x0C, 0xE8, 0x80, 0x80, 0x80, 0x80, 0x00, 0xBE, 0x7F, 0x00, 0x6C, 0x00, 0x2F, 0x03, -+0x60, 0xD7, 0x0C, 0xE8, 0x80, 0x80, 0x80, 0x80, 0x00, 0xBE, 0x7F, 0x00, 0x6C, 0x00, 0xEF, 0x03, 0x60, 0x9F, 0x0D, 0xE8, -+0x80, 0x80, 0x80, 0x80, 0x6D, 0xBE, 0x7F, 0x00, 0x6C, 0x00, 0xEF, 0x83, 0x60, 0x9F, 0x0D, 0xE8, 0x80, 0x80, 0x80, 0x80, -+0x00, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0x6F, 0x1B, 0x60, 0x07, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, -+0xFC, 0x00, 0x6F, 0x1B, 0x60, 0x17, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x12, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0xEF, 0x5B, -+0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x6D, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0xEF, 0x9B, 0x60, 0x9F, 0x0D, 0x68, -+0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0x2F, 0x1B, 0x60, 0x87, 0xEC, 0x79, 0x80, 0x80, 0x80, 0x80, -+0x00, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0x6F, 0x1B, 0x60, 0x87, 0xEC, 0x79, 0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, -+0xFC, 0x00, 0x6F, 0x1B, 0x60, 0x07, 0xAD, 0x79, 0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0x6F, 0x1B, -+0x60, 0x07, 0x0D, 0x79, 0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0x6F, 0x1B, 0x60, 0x07, 0x0D, 0x78, -+0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0x6F, 0x1B, 0x60, 0x17, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, -+0x12, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0xEF, 0x5B, 0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x6D, 0x3E, 0x55, 0x00, -+0xFC, 0x00, 0xEF, 0x9B, 0x60, 0x9F, 0x0D, 0x68, 0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x19, 0x44, -+0x70, 0xE3, 0xAC, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x46, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x19, 0x84, 0x70, 0x63, 0x8C, 0x0F, -+0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x19, 0x44, 0x70, 0x03, 0x11, 0x0F, 0x80, 0x80, 0x80, 0x80, -+0x46, 0x3E, 0x39, 0x00, 0xB4, 0x00, 0x19, 0x84, 0x70, 0x43, 0x8D, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x39, 0x00, -+0xB4, 0x00, 0x19, 0x44, 0x70, 0xE3, 0x10, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x58, 0x3E, 0xB9, 0x00, 0xB4, 0x00, 0x19, 0xC4, -+0x70, 0xE3, 0x0C, 0x0F, 0x80, 0x80, 0x80, 0x80, 0xB4, 0x3E, 0xB9, 0x00, 0xB4, 0x00, 0x19, 0x44, 0x70, 0xC3, 0x8C, 0x0E, -+0x80, 0x80, 0x80, 0x80, 0x46, 0x3E, 0xB9, 0x00, 0xB4, 0x00, 0x19, 0x84, 0x70, 0x03, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, -+0x34, 0x3E, 0xB9, 0x00, 0xB4, 0x00, 0x19, 0x44, 0x70, 0xEB, 0x0C, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x46, 0x3E, 0xB9, 0x00, -+0xB4, 0x00, 0x19, 0x84, 0x70, 0xD3, 0x0C, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x46, 0x3E, 0xAA, 0x00, 0xB5, 0x5A, 0x39, 0x84, -+0x70, 0xF3, 0x0C, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x46, 0x3E, 0xAA, 0x00, 0xB5, 0x5A, 0x39, 0x84, 0x70, 0x3B, 0x0D, 0x0E, -+0x80, 0x80, 0x80, 0x80, 0xB4, 0x3E, 0xAA, 0x00, 0xB5, 0x5A, 0x39, 0x44, 0x70, 0xBB, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, -+0xEB, 0x3E, 0xAA, 0x00, 0xB5, 0x5A, 0x39, 0x04, 0x70, 0xFB, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x6B, 0x3F, 0xAA, 0x00, -+0xB5, 0x5A, 0x39, 0x04, 0x70, 0xFB, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, 0xEB, 0x3F, 0xAA, 0x00, 0xB5, 0x5A, 0x39, 0x04, -+0x70, 0xFB, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x34, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x44, 0x70, 0xE3, 0xAC, 0x0F, -+0x80, 0x80, 0x80, 0x80, 0x46, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x84, 0x70, 0x63, 0x8C, 0x0F, 0x80, 0x80, 0x80, 0x80, -+0x34, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x44, 0x70, 0x03, 0x11, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x46, 0x2E, 0x39, 0x00, -+0xB4, 0x00, 0x0F, 0x84, 0x70, 0x43, 0x8D, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x34, 0x2E, 0x39, 0x00, 0xB4, 0x00, 0x0F, 0x44, -+0x70, 0xE3, 0x10, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x58, 0x2E, 0xB9, 0x00, 0xB4, 0x00, 0x0F, 0xC4, 0x70, 0xE3, 0x0C, 0x0F, -+0x80, 0x80, 0x80, 0x80, 0xB4, 0x2E, 0xB9, 0x00, 0xB4, 0x00, 0x0F, 0x44, 0x70, 0xC3, 0x8C, 0x0E, 0x80, 0x80, 0x80, 0x80, -+0x46, 0x2E, 0xB9, 0x00, 0xB4, 0x00, 0x0F, 0x84, 0x70, 0x03, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x34, 0x2E, 0xB9, 0x00, -+0xB4, 0x00, 0x0F, 0x44, 0x70, 0xEB, 0x0C, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x46, 0x2E, 0xB9, 0x00, 0xB4, 0x00, 0x0F, 0x84, -+0x70, 0xD3, 0x0C, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x46, 0x2E, 0xAA, 0x00, 0xB5, 0x5A, 0x2F, 0x84, 0x70, 0xF3, 0x0C, 0x0E, -+0x80, 0x80, 0x80, 0x80, 0x46, 0x2E, 0xAA, 0x00, 0xB5, 0x5A, 0x2F, 0x84, 0x70, 0x3B, 0x0D, 0x0E, 0x80, 0x80, 0x80, 0x80, -+0xB4, 0x2E, 0xAA, 0x00, 0xB5, 0x5A, 0x2F, 0x44, 0x70, 0xBB, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, 0xEB, 0x2E, 0xAA, 0x00, -+0xB5, 0x5A, 0x2F, 0x04, 0x70, 0xFB, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, 0x6B, 0x2F, 0xAA, 0x00, 0xB5, 0x5A, 0x2F, 0x04, -+0x70, 0xFB, 0x11, 0x0E, 0x80, 0x80, 0x80, 0x80, 0xEB, 0x2F, 0xAA, 0x00, 0xB5, 0x5A, 0x2F, 0x04, 0x70, 0xFB, 0x11, 0x0E, -+0x7F, 0xC1, 0x9F, 0x00, 0x0A, 0x01, 0x82, 0x00, 0x0C, 0x81, 0x82, 0x00, 0x10, 0x81, 0x82, 0x00, 0x10, 0x01, 0x83, 0x00, -+0x16, 0x01, 0x83, 0x00, 0x16, 0x01, 0x84, 0x00, 0x60, 0x01, 0x84, 0x00, 0x67, 0x01, 0x93, 0x00, 0x67, 0x41, 0x99, 0x00, -+0x7F, 0x41, 0x99, 0x00, 0x7F, 0xC1, 0x99, 0x00, 0x7F, 0x81, 0x9A, 0x00, 0x7F, 0x81, 0x9B, 0x00, 0x3F, 0xC1, 0x9C, 0x00, -+0x3F, 0xC1, 0x8F, 0x00, 0x08, 0x01, 0x82, 0x00, 0x0A, 0x01, 0x82, 0x00, 0x0C, 0x81, 0x82, 0x00, 0x10, 0x81, 0x82, 0x00, -+0x10, 0x01, 0x83, 0x00, 0x16, 0x01, 0x83, 0x00, 0x16, 0x01, 0x84, 0x00, 0x20, 0x01, 0x84, 0x00, 0x20, 0x01, 0x85, 0x00, -+0x20, 0x01, 0x8C, 0x00, 0x27, 0x81, 0x8C, 0x00, 0x27, 0x01, 0x8E, 0x00, 0x27, 0x01, 0x9B, 0x00, 0x3F, 0x01, 0x9B, 0x00, -+0x3F, 0xC1, 0x9C, 0x00, 0x3F, 0xC1, 0x8F, 0x00, 0x00, 0xC6, 0xFF, 0x00, 0x00, 0xC6, 0x40, 0x00, 0x00, 0x06, 0x41, 0x00, -+0x00, 0x46, 0x41, 0x00, 0x00, 0x86, 0x90, 0x00, 0x00, 0xC6, 0x90, 0x00, 0x00, 0x06, 0xB1, 0x00, 0x00, 0x46, 0xB1, 0x00, -+0x00, 0x86, 0xB1, 0x00, 0x00, 0x06, 0xB2, 0x00, 0x00, 0xC6, 0xB2, 0x00, 0x00, 0x46, 0xB9, 0x00, 0x00, 0xC6, 0xB9, 0x00, -+0x00, 0x46, 0xBA, 0x00, 0x00, 0x46, 0xBB, 0x00, 0x00, 0xC6, 0xBC, 0x00, 0x82, 0x01, 0x83, 0x01, 0x40, 0x02, 0x41, 0x02, -+0x80, 0x02, 0x81, 0x02, 0x82, 0x02, 0x83, 0x02, 0x40, 0x03, 0x41, 0x03, 0x80, 0x03, 0x81, 0x03, 0x00, 0x04, 0x01, 0x04, -+0x40, 0x04, 0x41, 0x04, 0x60, 0x60, 0x00, 0x00, 0x3B, 0x18, 0xB3, 0x03, 0x68, 0x51, 0x2E, 0x1A, 0x48, 0x51, 0x2E, 0x1A, -+0x00, 0x00, 0x00, 0x00, 0x84, 0x18, 0x20, 0x56, 0x84, 0x18, 0x20, 0x56, 0x00, 0x00, 0x00, 0x00, 0x08, 0x50, 0x2A, 0x7A, -+0xC8, 0x50, 0x1B, 0x79, 0xC8, 0xD0, 0x2A, 0x7A, 0x40, 0x40, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x64, 0x32, 0x00, 0x00, -+0x00, 0x87, 0x93, 0x03, 0x00, 0x20, 0x03, 0x00, 0x00, 0x20, 0x03, 0x00, 0x30, 0x75, 0x00, 0x00, 0xB0, 0xAD, 0x01, 0x00, -+0x20, 0xA1, 0x07, 0x00, 0x20, 0xA1, 0x07, 0x00, 0x20, 0xA1, 0x07, 0x00, 0x20, 0xA1, 0x07, 0x00, 0x10, 0x27, 0x00, 0x00, -+0x40, 0x0D, 0x03, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x27, 0x50, 0xC3, 0xA0, 0x0F, 0x40, 0x1F, 0x84, 0x03, 0x05, 0x08, -+0x01, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x1A, 0x00, 0x20, 0x20, 0x00, 0x00, 0x20, 0x20, 0x1A, 0x00, 0xE0, 0x57, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, -+0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x19, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x19, 0x00, 0xF4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0xE0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0x71, 0x04, 0x00, 0x10, 0x0E, 0x00, -+0x03, 0x01, 0x08, 0x8F, 0x03, 0xE6, 0xE0, 0xD0, 0xD6, 0x06, 0xD6, 0x06, 0x00, 0x00, 0x01, 0xF3, 0x01, 0x0A, 0x00, 0x0F, -+0x08, 0x01, 0x09, 0x08, 0x08, 0x08, 0x08, 0x0A, 0x09, 0x09, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -+0x03, 0x01, 0x00, 0x00, 0xBC, 0x06, 0x04, 0x04, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x0A, 0x02, 0x04, -+0x01, 0x00, 0xF0, 0x00, 0x08, 0x04, 0x00, 0x04, 0x04, 0x04, 0x09, 0x06, 0x04, 0x01, 0x04, 0x01, 0x05, 0x14, 0x38, 0x01, -+0x38, 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, -+0x7D, 0xA6, 0x12, 0x00, 0x91, 0xA1, 0x12, 0x00, 0xA5, 0xA6, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x99, 0xA1, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xA1, 0x12, 0x00, 0xD1, 0xA1, 0x12, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xA3, 0x12, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x6D, 0x12, 0x00, 0x88, 0x00, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, -+0x05, 0xC7, 0x12, 0x00, 0xE1, 0xB8, 0x14, 0x00, 0x75, 0xBB, 0x14, 0x00, 0x2D, 0xBE, 0x14, 0x00, 0xE9, 0xBC, 0x14, 0x00, -+0x81, 0xBC, 0x14, 0x00, 0x29, 0xAC, 0x14, 0x00, 0xFD, 0x0C, 0x15, 0x00, 0x1D, 0x0B, 0x15, 0x00, 0x6D, 0x08, 0x15, 0x00, -+0x0D, 0x07, 0x15, 0x00, 0x59, 0xC8, 0x13, 0x00, 0xF5, 0xE7, 0x13, 0x00, 0xA1, 0xCE, 0x13, 0x00, 0x3D, 0xD1, 0x13, 0x00, -+0x4D, 0xD0, 0x13, 0x00, 0xF9, 0xD0, 0x13, 0x00, 0x05, 0xDD, 0x13, 0x00, 0xF1, 0xDD, 0x13, 0x00, 0x95, 0xDE, 0x13, 0x00, -+0x85, 0xE4, 0x13, 0x00, 0xF5, 0xE0, 0x13, 0x00, 0xC1, 0xE3, 0x13, 0x00, 0xED, 0xCE, 0x13, 0x00, 0x59, 0xD6, 0x13, 0x00, -+0xF5, 0xD9, 0x13, 0x00, 0x3D, 0xD5, 0x13, 0x00, 0xA9, 0xD4, 0x13, 0x00, 0x91, 0xD8, 0x13, 0x00, 0x31, 0xD9, 0x13, 0x00, -+0xC1, 0xD8, 0x13, 0x00, 0x21, 0xD4, 0x13, 0x00, 0x4D, 0xDB, 0x13, 0x00, 0x71, 0xCA, 0x13, 0x00, 0xE5, 0xC9, 0x13, 0x00, -+0xAD, 0xC0, 0x13, 0x00, 0xCD, 0xC6, 0x13, 0x00, 0x39, 0xC0, 0x13, 0x00, 0x79, 0xD6, 0x13, 0x00, 0xE5, 0xD7, 0x13, 0x00, -+0xF1, 0xC7, 0x13, 0x00, 0xDD, 0xE4, 0x13, 0x00, 0xA1, 0xE6, 0x13, 0x00, 0x21, 0xD2, 0x13, 0x00, 0x6D, 0xD4, 0x13, 0x00, -+0x99, 0xEA, 0x13, 0x00, 0x71, 0x50, 0x14, 0x00, 0x71, 0x58, 0x14, 0x00, 0x25, 0x06, 0x12, 0x00, 0x7D, 0x4B, 0x14, 0x00, -+0x19, 0x4B, 0x14, 0x00, 0xF9, 0x5E, 0x12, 0x00, 0xD1, 0x5E, 0x12, 0x00, 0xF1, 0x1C, 0x14, 0x00, 0x19, 0x1E, 0x14, 0x00, -+0xE9, 0x14, 0x14, 0x00, 0xD9, 0x16, 0x14, 0x00, 0x91, 0x17, 0x14, 0x00, 0xC9, 0x1A, 0x14, 0x00, 0xF1, 0x19, 0x14, 0x00, -+0x3D, 0x15, 0x14, 0x00, 0xA5, 0x1B, 0x14, 0x00, 0x25, 0x1B, 0x14, 0x00, 0x1D, 0x90, 0x12, 0x00, 0x7D, 0x93, 0x12, 0x00, -+0xD1, 0x9E, 0x12, 0x00, 0x71, 0x8E, 0x12, 0x00, 0xF5, 0xAA, 0x12, 0x00, 0xC5, 0x78, 0x12, 0x00, 0x05, 0x69, 0x12, 0x00, -+0x39, 0x69, 0x12, 0x00, 0x8D, 0x52, 0x12, 0x00, 0x7D, 0x50, 0x12, 0x00, 0xD9, 0x55, 0x12, 0x00, 0xC1, 0x51, 0x12, 0x00, -+0x79, 0x51, 0x12, 0x00, 0x5D, 0xB2, 0x12, 0x00, 0x8D, 0x0C, 0x15, 0x00, 0x61, 0x4C, 0x14, 0x00, 0xF9, 0x0E, 0x12, 0x00, -+0x49, 0x07, 0x12, 0x00, 0x55, 0x59, 0x14, 0x00, 0xD5, 0x58, 0x14, 0x00, 0x49, 0x5A, 0x14, 0x00, 0x05, 0x5A, 0x14, 0x00, -+0xD9, 0x80, 0x14, 0x00, 0xD9, 0x5A, 0x14, 0x00, 0x45, 0x79, 0x14, 0x00, 0x7D, 0x7D, 0x13, 0x00, 0xA1, 0x78, 0x13, 0x00, -+0xB5, 0x7E, 0x13, 0x00, 0xF1, 0x85, 0x13, 0x00, 0xD5, 0xB6, 0x13, 0x00, 0x91, 0xBC, 0x13, 0x00, 0xF1, 0xB5, 0x13, 0x00, -+0x19, 0xBB, 0x13, 0x00, 0x5D, 0xBB, 0x13, 0x00, 0xD5, 0xBC, 0x13, 0x00, 0xDD, 0xB8, 0x13, 0x00, 0x8D, 0xB8, 0x13, 0x00, -+0xFD, 0xBD, 0x13, 0x00, 0x21, 0xB8, 0x13, 0x00, 0xC5, 0x8C, 0x13, 0x00, 0x09, 0x8C, 0x13, 0x00, 0xE9, 0x72, 0x13, 0x00, -+0x59, 0x87, 0x13, 0x00, 0xCD, 0x73, 0x13, 0x00, 0x31, 0x84, 0x13, 0x00, 0x25, 0x80, 0x13, 0x00, 0x35, 0x83, 0x13, 0x00, -+0xFD, 0x80, 0x13, 0x00, 0xE9, 0x8B, 0x13, 0x00, 0x01, 0x8E, 0x13, 0x00, 0x55, 0x89, 0x13, 0x00, 0xD9, 0x89, 0x13, 0x00, -+0x91, 0x7D, 0x13, 0x00, 0x4D, 0x75, 0x13, 0x00, 0xA5, 0xB3, 0x13, 0x00, 0x19, 0xB0, 0x13, 0x00, 0x01, 0xAF, 0x13, 0x00, -+0x21, 0xAF, 0x13, 0x00, 0x25, 0x05, 0x14, 0x00, 0xA9, 0xFF, 0x13, 0x00, 0xB1, 0xFE, 0x13, 0x00, 0xC5, 0xFF, 0x13, 0x00, -+0x81, 0xFF, 0x13, 0x00, 0x69, 0x06, 0x14, 0x00, 0x49, 0x03, 0x14, 0x00, 0x2D, 0x0A, 0x14, 0x00, 0x25, 0x08, 0x14, 0x00, -+0x3D, 0x09, 0x14, 0x00, 0xF9, 0x07, 0x14, 0x00, 0x59, 0xFB, 0x13, 0x00, 0x35, 0x04, 0x14, 0x00, 0xF5, 0xF6, 0x13, 0x00, -+0x89, 0xF4, 0x13, 0x00, 0xA5, 0x13, 0x12, 0x00, 0x5D, 0x10, 0x12, 0x00, 0xC1, 0x0B, 0x12, 0x00, 0x49, 0x11, 0x12, 0x00, -+0x4D, 0x02, 0x12, 0x00, 0xDD, 0xEA, 0x13, 0x00, 0x01, 0xEE, 0x13, 0x00, 0xA9, 0xF0, 0x13, 0x00, 0x79, 0xEF, 0x13, 0x00, -+0x49, 0xF1, 0x13, 0x00, 0xE5, 0xF1, 0x13, 0x00, 0x85, 0xEC, 0x13, 0x00, 0x45, 0xED, 0x13, 0x00, 0xA5, 0xED, 0x13, 0x00, -+0x3D, 0xEB, 0x13, 0x00, 0x45, 0xEF, 0x13, 0x00, 0xA1, 0xF2, 0x13, 0x00, 0xC5, 0xF3, 0x13, 0x00, 0x85, 0x49, 0x15, 0x00, -+0x01, 0x35, 0x15, 0x00, 0xCD, 0x42, 0x12, 0x00, 0x71, 0xCB, 0x12, 0x00, 0x35, 0xCF, 0x12, 0x00, 0xAD, 0xD3, 0x12, 0x00, -+0x9D, 0xCB, 0x12, 0x00, 0xFD, 0xD4, 0x12, 0x00, 0xFD, 0x48, 0x13, 0x00, 0x69, 0x4B, 0x13, 0x00, 0x21, 0x4C, 0x13, 0x00, -+0x15, 0x46, 0x13, 0x00, 0x99, 0x50, 0x13, 0x00, 0x9D, 0x5C, 0x13, 0x00, 0x79, 0x5C, 0x13, 0x00, 0xED, 0x53, 0x13, 0x00, -+0xE5, 0x56, 0x13, 0x00, 0x81, 0x4F, 0x13, 0x00, 0x61, 0x4E, 0x13, 0x00, 0x29, 0x4D, 0x13, 0x00, 0x01, 0x40, 0x13, 0x00, -+0xED, 0x4C, 0x13, 0x00, 0x1D, 0x52, 0x13, 0x00, 0xDD, 0xDB, 0x14, 0x00, 0xB5, 0xEB, 0x14, 0x00, 0x19, 0xD9, 0x14, 0x00, -+0xA5, 0xDF, 0x14, 0x00, 0xB5, 0xE0, 0x14, 0x00, 0xE9, 0xDE, 0x14, 0x00, 0x15, 0xE3, 0x14, 0x00, 0xD9, 0xE5, 0x14, 0x00, -+0x5D, 0xD7, 0x14, 0x00, 0xED, 0xD6, 0x14, 0x00, 0x21, 0x13, 0x14, 0x00, 0x85, 0x14, 0x14, 0x00, 0x05, 0xD1, 0x14, 0x00, -+0x8D, 0x85, 0x12, 0x00, 0xD1, 0x80, 0x12, 0x00, 0xCD, 0x7D, 0x12, 0x00, 0xED, 0x7F, 0x12, 0x00, 0x45, 0x7A, 0x12, 0x00, -+0x01, 0x7F, 0x12, 0x00, 0xD5, 0x99, 0x14, 0x00, 0xED, 0x9A, 0x14, 0x00, 0x31, 0x62, 0x13, 0x00, 0x29, 0x5F, 0x13, 0x00, -+0x65, 0x63, 0x13, 0x00, 0x41, 0x61, 0x13, 0x00, 0x71, 0x5F, 0x12, 0x00, 0xB9, 0x24, 0x12, 0x00, 0xD9, 0x0D, 0x14, 0x00, -+0x61, 0x0C, 0x14, 0x00, 0x79, 0x20, 0x14, 0x00, 0x05, 0x20, 0x14, 0x00, 0xC1, 0x20, 0x14, 0x00, 0x55, 0xD6, 0x12, 0x00, -+0x4D, 0x1B, 0x13, 0x00, 0x99, 0x0E, 0x13, 0x00, 0x11, 0x0C, 0x13, 0x00, 0x65, 0x0D, 0x13, 0x00, 0xD1, 0x19, 0x13, 0x00, -+0x5D, 0x13, 0x13, 0x00, 0x79, 0x0A, 0x13, 0x00, 0x8D, 0x21, 0x13, 0x00, 0x2D, 0x15, 0x13, 0x00, 0x19, 0x21, 0x13, 0x00, -+0x79, 0x07, 0x13, 0x00, 0xCD, 0xF3, 0x12, 0x00, 0x31, 0xD7, 0x12, 0x00, 0x41, 0xD8, 0x12, 0x00, 0xA1, 0xD8, 0x12, 0x00, -+0x69, 0xFC, 0x12, 0x00, 0x15, 0xFD, 0x12, 0x00, 0xF5, 0xE7, 0x12, 0x00, 0xB5, 0xE2, 0x12, 0x00, 0xE5, 0xEA, 0x12, 0x00, -+0xF5, 0xEB, 0x12, 0x00, 0xED, 0xE6, 0x12, 0x00, 0xF9, 0xDD, 0x12, 0x00, 0x89, 0xE2, 0x12, 0x00, 0xD1, 0xFD, 0x12, 0x00, -+0xD5, 0xE7, 0x12, 0x00, 0xD5, 0x30, 0x13, 0x00, 0x91, 0x36, 0x13, 0x00, 0xD5, 0x3A, 0x13, 0x00, 0x7D, 0x3C, 0x13, 0x00, -+0xDD, 0x26, 0x13, 0x00, 0x49, 0x27, 0x13, 0x00, 0xA9, 0x25, 0x13, 0x00, 0xCD, 0x35, 0x13, 0x00, 0x71, 0x25, 0x13, 0x00, -+0x89, 0x2C, 0x13, 0x00, 0x75, 0x30, 0x13, 0x00, 0x81, 0x3A, 0x13, 0x00, 0x05, 0x3A, 0x13, 0x00, 0x49, 0x3D, 0x13, 0x00, -+0xB1, 0x2B, 0x13, 0x00, 0x21, 0x2F, 0x13, 0x00, 0xBD, 0x39, 0x13, 0x00, 0x59, 0x28, 0x13, 0x00, 0xCD, 0x2A, 0x13, 0x00, -+0x61, 0x37, 0x13, 0x00, 0x01, 0xDB, 0x12, 0x00, 0xF1, 0xE2, 0x12, 0x00, 0x81, 0xD9, 0x12, 0x00, 0x35, 0xEE, 0x12, 0x00, -+0xC5, 0xEF, 0x12, 0x00, 0x49, 0xED, 0x12, 0x00, 0x69, 0xFD, 0x14, 0x00, 0x39, 0xF9, 0x14, 0x00, 0x71, 0xF4, 0x14, 0x00, -+0x79, 0xF9, 0x14, 0x00, 0x09, 0xFC, 0x14, 0x00, 0xC5, 0xF3, 0x14, 0x00, 0xDD, 0x60, 0x12, 0x00, 0xB1, 0xAD, 0x12, 0x00, -+0xBD, 0xAE, 0x12, 0x00, 0x29, 0xAF, 0x12, 0x00, 0xA5, 0xA4, 0x12, 0x00, 0xD1, 0xA5, 0x12, 0x00, 0xD9, 0x6C, 0x13, 0x00, -+0xF5, 0x6E, 0x13, 0x00, 0x1D, 0x64, 0x13, 0x00, 0x2D, 0x6E, 0x13, 0x00, 0x51, 0x65, 0x13, 0x00, 0xB5, 0x6E, 0x13, 0x00, -+0x2D, 0x6F, 0x13, 0x00, 0xC1, 0x68, 0x13, 0x00, 0x91, 0xBE, 0x12, 0x00, 0x29, 0xC4, 0x12, 0x00, 0x95, 0xBB, 0x12, 0x00, -+0xDD, 0x03, 0x12, 0x00, 0x19, 0xC5, 0x12, 0x00, 0xCD, 0xC6, 0x12, 0x00, 0x2D, 0x1E, 0x12, 0x00, 0x61, 0x1B, 0x12, 0x00, -+0x69, 0x1D, 0x12, 0x00, 0x7D, 0x9D, 0x12, 0x00, 0xA9, 0x9D, 0x12, 0x00, 0x39, 0x12, 0x14, 0x00, 0x99, 0x71, 0x13, 0x00, -+0xC1, 0x21, 0x12, 0x00, 0x51, 0x09, 0x12, 0x00, 0x9D, 0x0A, 0x12, 0x00, 0xA1, 0x0A, 0x12, 0x00, 0xBD, 0x0B, 0x12, 0x00, -+0x41, 0x1C, 0x12, 0x00, 0xD5, 0xCF, 0x12, 0x00, 0x21, 0xD1, 0x12, 0x00, 0xD1, 0x3C, 0x12, 0x00, 0xC5, 0x4B, 0x12, 0x00, -+0xA1, 0x4D, 0x12, 0x00, 0x6D, 0x4C, 0x12, 0x00, 0xAD, 0x4A, 0x12, 0x00, 0x71, 0xC0, 0x12, 0x00, 0x19, 0xC2, 0x12, 0x00, -+0x79, 0xB8, 0x12, 0x00, 0x29, 0x9A, 0x12, 0x00, 0x39, 0x93, 0x12, 0x00, 0xA1, 0x65, 0x12, 0x00, 0xCD, 0xB1, 0x12, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x58, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xC2, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x75, 0x95, 0x13, 0x00, -+0x04, 0x00, 0x00, 0x00, 0xFD, 0x8F, 0x13, 0x00, 0x06, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, 0x08, 0x00, 0x00, 0x00, -+0xF1, 0xA9, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x93, 0x13, 0x00, 0x10, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, -+0x16, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, 0x12, 0x00, 0x00, 0x00, -+0xF1, 0xA9, 0x13, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, 0x18, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, -+0x1A, 0x00, 0x00, 0x00, 0xCD, 0x90, 0x13, 0x00, 0x6B, 0x00, 0x00, 0x00, 0xF5, 0x96, 0x13, 0x00, 0x6D, 0x00, 0x00, 0x00, -+0xD1, 0x97, 0x13, 0x00, 0x71, 0x00, 0x00, 0x00, 0x19, 0x93, 0x13, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x79, 0x91, 0x13, 0x00, -+0x20, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, 0x1E, 0x00, 0x00, 0x00, -+0xF1, 0xA9, 0x13, 0x00, 0x30, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, 0x22, 0x00, 0x00, 0x00, 0x09, 0xA0, 0x13, 0x00, -+0x84, 0x00, 0x00, 0x00, 0xAD, 0xA0, 0x13, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x4D, 0x8E, 0x13, 0x00, 0x24, 0x00, 0x00, 0x00, -+0xA9, 0x93, 0x13, 0x00, 0x26, 0x00, 0x00, 0x00, 0x4D, 0x94, 0x13, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x9D, 0x8E, 0x13, 0x00, -+0x0C, 0x00, 0x00, 0x00, 0x9D, 0x91, 0x13, 0x00, 0x28, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, 0x2A, 0x00, 0x00, 0x00, -+0xF1, 0x97, 0x13, 0x00, 0x39, 0x00, 0x00, 0x00, 0xC5, 0x91, 0x13, 0x00, 0x3B, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, -+0x46, 0x00, 0x00, 0x00, 0xCD, 0x8E, 0x13, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x21, 0x8E, 0x13, 0x00, 0x41, 0x00, 0x00, 0x00, -+0x91, 0x98, 0x13, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x8E, 0x13, 0x00, 0x4B, 0x00, 0x00, 0x00, 0xA9, 0x94, 0x13, 0x00, -+0x51, 0x00, 0x00, 0x00, 0x59, 0x8F, 0x13, 0x00, 0x52, 0x00, 0x00, 0x00, 0xB5, 0x9F, 0x13, 0x00, 0x56, 0x00, 0x00, 0x00, -+0x15, 0x95, 0x13, 0x00, 0x87, 0x00, 0x00, 0x00, 0xF1, 0xA9, 0x13, 0x00, 0x61, 0x00, 0x00, 0x00, 0x21, 0x97, 0x13, 0x00, -+0x63, 0x00, 0x00, 0x00, 0x9D, 0x98, 0x13, 0x00, 0x65, 0x00, 0x00, 0x00, 0xE9, 0x91, 0x13, 0x00, 0x67, 0x00, 0x00, 0x00, -+0x0D, 0x96, 0x13, 0x00, 0x69, 0x00, 0x00, 0x00, 0xF1, 0x9C, 0x13, 0x00, 0x73, 0x00, 0x00, 0x00, 0xE9, 0x98, 0x13, 0x00, -+0x75, 0x00, 0x00, 0x00, 0x0D, 0x8F, 0x13, 0x00, 0x77, 0x00, 0x00, 0x00, 0xA5, 0x92, 0x13, 0x00, 0x79, 0x00, 0x00, 0x00, -+0xCD, 0x92, 0x13, 0x00, 0x7B, 0x00, 0x00, 0x00, 0xE1, 0x9B, 0x13, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x59, 0x99, 0x13, 0x00, -+0x80, 0x00, 0x00, 0x00, 0xBD, 0x96, 0x13, 0x00, 0x82, 0x00, 0x00, 0x00, 0x11, 0x9B, 0x13, 0x00, 0x00, 0x08, 0x00, 0x00, -+0xB9, 0x0E, 0x14, 0x00, 0x85, 0x00, 0x00, 0x00, 0x4D, 0x0F, 0x14, 0x00, 0x86, 0x00, 0x00, 0x00, 0xC9, 0x0F, 0x14, 0x00, -+0x03, 0x08, 0x00, 0x00, 0x71, 0x10, 0x14, 0x00, 0x0D, 0xCD, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xB0, 0x13, 0x00, -+0x00, 0x00, 0x00, 0x00, 0xA1, 0x28, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x4C, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x9D, 0x2F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x84, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5, 0x7F, 0x13, 0x00, -+0x00, 0x00, 0x00, 0x00, 0xB5, 0x7F, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x6D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x85, 0x4A, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xF2, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x48, 0x13, 0x00, -+0x00, 0x00, 0x00, 0x00, 0xD1, 0x78, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, -+0xD1, 0xF4, 0x12, 0x00, 0x04, 0x00, 0x00, 0x00, 0xD1, 0xF4, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0xD1, 0xF4, 0x12, 0x00, -+0x02, 0x00, 0x00, 0x00, 0xD1, 0xF4, 0x12, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD1, 0xF4, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, -+0xF9, 0x4C, 0x14, 0x00, 0x04, 0x00, 0x00, 0x00, 0xD1, 0xF4, 0x12, 0x00, 0x05, 0x00, 0x00, 0x00, 0xF9, 0x4C, 0x14, 0x00, -+0x03, 0x00, 0x00, 0x00, 0xF9, 0x4C, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0xF9, 0x4C, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, -+0xF9, 0x4C, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x69, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x6D, 0x12, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x69, 0x6D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x6D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, -+0xBD, 0x6D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x15, 0x4A, 0x14, 0x00, 0x02, 0x04, 0x00, 0x00, 0xB5, 0x49, 0x14, 0x00, -+0x04, 0x04, 0x00, 0x00, 0x2D, 0x48, 0x14, 0x00, 0x06, 0x04, 0x00, 0x00, 0xF9, 0x47, 0x14, 0x00, 0x09, 0x04, 0x00, 0x00, -+0x95, 0x49, 0x14, 0x00, 0x11, 0x04, 0x00, 0x00, 0x11, 0x49, 0x14, 0x00, 0x0B, 0x04, 0x00, 0x00, 0xC1, 0x4A, 0x14, 0x00, -+0x0D, 0x04, 0x00, 0x00, 0x45, 0x4A, 0x14, 0x00, 0x0F, 0x04, 0x00, 0x00, 0x61, 0x48, 0x14, 0x00, 0x1B, 0x04, 0x00, 0x00, -+0x91, 0x47, 0x14, 0x00, 0x1E, 0x04, 0x00, 0x00, 0x75, 0x47, 0x14, 0x00, 0x1F, 0x04, 0x00, 0x00, 0x59, 0x47, 0x14, 0x00, -+0x01, 0x00, 0x00, 0x00, 0x28, 0x34, 0x17, 0x00, 0x00, 0x14, 0x00, 0x00, 0xBD, 0x68, 0x14, 0x00, 0x02, 0x14, 0x00, 0x00, -+0xED, 0x65, 0x14, 0x00, 0x04, 0x14, 0x00, 0x00, 0x01, 0x67, 0x14, 0x00, 0x07, 0x14, 0x00, 0x00, 0x01, 0x6A, 0x14, 0x00, -+0x09, 0x14, 0x00, 0x00, 0x75, 0x67, 0x14, 0x00, 0x17, 0x14, 0x00, 0x00, 0xB1, 0x72, 0x14, 0x00, 0x19, 0x14, 0x00, 0x00, -+0xB5, 0x6E, 0x14, 0x00, 0x0C, 0x14, 0x00, 0x00, 0x01, 0x68, 0x14, 0x00, 0x18, 0x14, 0x00, 0x00, 0x89, 0x31, 0x14, 0x00, -+0x23, 0x00, 0x00, 0x00, 0x45, 0x6F, 0x14, 0x00, 0x13, 0x14, 0x00, 0x00, 0x45, 0x73, 0x14, 0x00, 0x32, 0x00, 0x00, 0x00, -+0x9D, 0x6F, 0x14, 0x00, 0x15, 0x14, 0x00, 0x00, 0x11, 0x66, 0x14, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x89, 0x31, 0x14, 0x00, -+0x3C, 0x00, 0x00, 0x00, 0x89, 0x31, 0x14, 0x00, 0x42, 0x00, 0x00, 0x00, 0x89, 0x31, 0x14, 0x00, 0x1B, 0x00, 0x00, 0x00, -+0x89, 0x31, 0x14, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x89, 0x31, 0x14, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x89, 0x31, 0x14, 0x00, -+0x70, 0x00, 0x00, 0x00, 0x89, 0x31, 0x14, 0x00, 0x72, 0x00, 0x00, 0x00, 0x89, 0x31, 0x14, 0x00, 0x0E, 0x14, 0x00, 0x00, -+0xF5, 0x6F, 0x14, 0x00, 0x10, 0x14, 0x00, 0x00, 0xF1, 0x70, 0x14, 0x00, 0x11, 0x14, 0x00, 0x00, 0x91, 0x71, 0x14, 0x00, -+0x00, 0x18, 0x00, 0x00, 0x1D, 0x8A, 0x14, 0x00, 0x03, 0x18, 0x00, 0x00, 0x6D, 0x92, 0x14, 0x00, 0x01, 0x10, 0x00, 0x00, -+0xA1, 0x8C, 0x14, 0x00, 0x03, 0x10, 0x00, 0x00, 0x09, 0x8D, 0x14, 0x00, 0x08, 0x18, 0x00, 0x00, 0x71, 0x8C, 0x14, 0x00, -+0x43, 0x00, 0x00, 0x00, 0x21, 0x8C, 0x14, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x8D, 0x92, 0x14, 0x00, 0x18, 0x14, 0x00, 0x00, -+0xA5, 0x90, 0x14, 0x00, 0x19, 0x00, 0x00, 0x00, 0xE5, 0x8F, 0x14, 0x00, 0x17, 0x00, 0x00, 0x00, 0xE5, 0x8F, 0x14, 0x00, -+0x15, 0x00, 0x00, 0x00, 0xE5, 0x8F, 0x14, 0x00, 0x72, 0x00, 0x00, 0x00, 0xE5, 0x8F, 0x14, 0x00, 0x1B, 0x00, 0x00, 0x00, -+0xE5, 0x8F, 0x14, 0x00, 0x1F, 0x00, 0x00, 0x00, 0xD9, 0x94, 0x14, 0x00, 0x1A, 0x14, 0x00, 0x00, 0x7D, 0x8F, 0x14, 0x00, -+0x4C, 0x00, 0x00, 0x00, 0x89, 0x31, 0x14, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x90, 0x14, 0x00, 0x3A, 0x00, 0x00, 0x00, -+0x65, 0x90, 0x14, 0x00, 0x00, 0x28, 0x00, 0x00, 0x99, 0x91, 0x14, 0x00, 0x07, 0x18, 0x00, 0x00, 0xFD, 0x91, 0x14, 0x00, -+0x09, 0x18, 0x00, 0x00, 0x19, 0x92, 0x14, 0x00, 0x00, 0x1C, 0x00, 0x00, 0xF5, 0xB3, 0x14, 0x00, 0x02, 0x1C, 0x00, 0x00, -+0xD5, 0xB6, 0x14, 0x00, 0x18, 0x14, 0x00, 0x00, 0xD9, 0xB7, 0x14, 0x00, 0x40, 0x00, 0x00, 0x00, 0xBD, 0xB2, 0x14, 0x00, -+0x19, 0x00, 0x00, 0x00, 0x01, 0xB6, 0x14, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0xB6, 0x14, 0x00, 0x15, 0x00, 0x00, 0x00, -+0x01, 0xB6, 0x14, 0x00, 0x1A, 0x14, 0x00, 0x00, 0x9D, 0xB5, 0x14, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x81, 0xB6, 0x14, 0x00, -+0x3A, 0x00, 0x00, 0x00, 0x41, 0xB6, 0x14, 0x00, 0x04, 0x1C, 0x00, 0x00, 0x01, 0xB3, 0x14, 0x00, 0x06, 0x1C, 0x00, 0x00, -+0x39, 0xB7, 0x14, 0x00, 0x08, 0x1C, 0x00, 0x00, 0x59, 0xB5, 0x14, 0x00, 0x00, 0x10, 0x00, 0x00, 0x8D, 0x31, 0x14, 0x00, -+0x02, 0x10, 0x00, 0x00, 0x8D, 0x31, 0x14, 0x00, 0x05, 0x10, 0x00, 0x00, 0x8D, 0x31, 0x14, 0x00, 0x00, 0x28, 0x00, 0x00, -+0x89, 0x31, 0x14, 0x00, 0x00, 0x10, 0x00, 0x00, 0x95, 0xBF, 0x14, 0x00, 0x02, 0x10, 0x00, 0x00, 0xF5, 0xC0, 0x14, 0x00, -+0x05, 0x10, 0x00, 0x00, 0xF5, 0xBF, 0x14, 0x00, 0x07, 0x10, 0x00, 0x00, 0xF1, 0xC1, 0x14, 0x00, 0x0A, 0x10, 0x00, 0x00, -+0x7D, 0xC0, 0x14, 0x00, 0x01, 0x08, 0x00, 0x00, 0x39, 0xC2, 0x14, 0x00, 0x02, 0x08, 0x00, 0x00, 0x85, 0xC2, 0x14, 0x00, -+0x00, 0x28, 0x00, 0x00, 0xA1, 0xC2, 0x14, 0x00, 0x0A, 0x10, 0x00, 0x00, 0x51, 0xC0, 0x14, 0x00, 0x04, 0x08, 0x00, 0x00, -+0x4D, 0xC2, 0x14, 0x00, 0x00, 0x10, 0x00, 0x00, 0xD5, 0xC0, 0x14, 0x00, 0x07, 0x10, 0x00, 0x00, 0xA1, 0xC0, 0x14, 0x00, -+0xDC, 0x05, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x45, 0x04, 0x15, 0x00, 0x01, 0x20, 0x00, 0x00, 0x69, 0x04, 0x15, 0x00, -+0x2B, 0x00, 0x00, 0x00, 0xC5, 0x00, 0x15, 0x00, 0x29, 0x00, 0x00, 0x00, 0x55, 0xFF, 0x14, 0x00, 0x00, 0x28, 0x00, 0x00, -+0x35, 0x01, 0x15, 0x00, 0x0D, 0x26, 0x40, 0x80, 0x80, 0x80, 0x80, 0x80, -+}; -+ -+char fw_adid_u03[1208] = { -+0x61, 0xBD, 0x08, 0x00, 0xFD, 0x7D, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0x03, 0x08, 0x00, -+0x71, 0x02, 0x08, 0x00, 0x21, 0x04, 0x08, 0x00, 0xD9, 0x0A, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x0F, 0x08, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x15, 0x08, 0x00, -+0x6D, 0x18, 0x08, 0x00, 0xD1, 0x18, 0x08, 0x00, 0x15, 0x19, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x1D, 0x08, 0x00, -+0xA1, 0x24, 0x08, 0x00, 0x05, 0x26, 0x08, 0x00, 0x3D, 0x2A, 0x08, 0x00, 0x9D, 0x55, 0x08, 0x00, 0x39, 0x76, 0x08, 0x00, -+0x91, 0x76, 0x08, 0x00, 0x9D, 0x7C, 0x08, 0x00, 0xE5, 0x7C, 0x08, 0x00, 0x5D, 0x80, 0x08, 0x00, 0x75, 0xA9, 0x08, 0x00, -+0x9D, 0xBE, 0x08, 0x00, 0xD5, 0xBE, 0x08, 0x00, 0x39, 0xC0, 0x08, 0x00, 0x6D, 0xC2, 0x08, 0x00, 0x3D, 0x05, 0x09, 0x00, -+0xF1, 0x3B, 0x09, 0x00, 0x31, 0x3E, 0x09, 0x00, 0xFD, 0x40, 0x09, 0x00, 0x65, 0x9D, 0x09, 0x00, 0x25, 0xC0, 0x09, 0x00, -+0xF9, 0xBB, 0x09, 0x00, 0x05, 0xA2, 0x09, 0x00, 0x91, 0xD7, 0x09, 0x00, 0x4D, 0xB2, 0x0A, 0x00, 0x25, 0xB6, 0x0A, 0x00, -+0x75, 0xB8, 0x0A, 0x00, 0x2D, 0xB9, 0x0A, 0x00, 0x8D, 0xBB, 0x0A, 0x00, 0x99, 0xBC, 0x0A, 0x00, 0xA1, 0xC5, 0x0A, 0x00, -+0x31, 0xCD, 0x0A, 0x00, 0x09, 0xDE, 0x0A, 0x00, 0xB9, 0xEE, 0x0A, 0x00, 0x35, 0x58, 0x09, 0x00, 0xB1, 0x58, 0x09, 0x00, -+0x15, 0x54, 0x09, 0x00, 0xBD, 0x56, 0x09, 0x00, 0x11, 0x5B, 0x09, 0x00, 0xED, 0x5C, 0x09, 0x00, 0x15, 0x6C, 0x09, 0x00, -+0xB9, 0x60, 0x09, 0x00, 0xDD, 0x29, 0x0B, 0x00, 0x05, 0x76, 0x09, 0x00, 0x75, 0x76, 0x09, 0x00, 0x3D, 0x7A, 0x09, 0x00, -+0x5D, 0x7E, 0x09, 0x00, 0x69, 0x78, 0x09, 0x00, 0x61, 0x79, 0x09, 0x00, 0xD9, 0x7E, 0x09, 0x00, 0x35, 0x41, 0x0B, 0x00, -+0xB5, 0x08, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCD, 0x0C, 0x0B, 0x00, 0x85, 0x6F, 0x09, 0x00, 0xD5, 0x7B, 0x0B, 0x00, -+0x75, 0x7C, 0x0B, 0x00, 0xDD, 0x6C, 0x09, 0x00, 0xA9, 0x6D, 0x09, 0x00, 0x75, 0x6E, 0x09, 0x00, 0xE9, 0x1F, 0x0B, 0x00, -+0x35, 0x23, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0x1B, 0x0B, 0x00, 0x45, 0x27, 0x0B, 0x00, 0x85, 0x1A, 0x0B, 0x00, -+0x69, 0x17, 0x0B, 0x00, 0xDD, 0x27, 0x0B, 0x00, 0x31, 0x2B, 0x0B, 0x00, 0x25, 0x78, 0x0B, 0x00, 0x15, 0x65, 0x0B, 0x00, -+0x3D, 0x6B, 0x0B, 0x00, 0x9D, 0x67, 0x0B, 0x00, 0x99, 0x6B, 0x0B, 0x00, 0xC5, 0x6C, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x2D, 0xAF, 0x0B, 0x00, 0x3D, 0x99, 0x0C, 0x00, 0xC5, 0xD9, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x95, 0x0C, 0x00, 0x3D, 0xD5, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0xF5, 0xA4, 0x08, 0x00, 0xB5, 0xA5, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0xFD, 0x50, 0x08, 0x00, 0x9D, 0x7D, 0x08, 0x00, 0xBD, 0x7D, 0x08, 0x00, 0xDD, 0x7D, 0x08, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x91, 0x08, 0x00, -+0xAB, 0x91, 0x08, 0x00, 0xAD, 0x91, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x71, 0xD5, 0x09, 0x00, 0x6D, 0x0E, 0x08, 0x00, -+}; -+ -+char fw_patch_table_u03[1256] = { -+0x41, 0x49, 0x43, 0x42, 0x54, 0x5F, 0x50, 0x54, 0x5F, 0x54, 0x41, 0x47, 0x00, 0x00, 0x00, 0x00, 0x41, 0x49, 0x43, 0x42, -+0x54, 0x5F, 0x54, 0x52, 0x41, 0x50, 0x5F, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, -+0x00, 0xF0, 0x16, 0x00, 0x04, 0x23, 0xA3, 0x55, 0x00, 0x10, 0x08, 0x40, 0x88, 0x48, 0x0C, 0x00, 0x04, 0xF0, 0x16, 0x00, -+0x00, 0x2B, 0x05, 0xE0, 0x04, 0x10, 0x08, 0x40, 0x58, 0x58, 0x0B, 0x00, 0x08, 0xF0, 0x16, 0x00, 0x00, 0x2B, 0xB1, 0xE7, -+0x08, 0x10, 0x08, 0x40, 0x30, 0x5A, 0x0B, 0x00, 0x14, 0xEA, 0x16, 0x00, 0x02, 0x49, 0x8E, 0x46, 0x18, 0xEA, 0x16, 0x00, -+0x00, 0xB5, 0x02, 0x4B, 0x1C, 0xEA, 0x16, 0x00, 0xDB, 0x6E, 0x00, 0xBD, 0x20, 0xEA, 0x16, 0x00, 0xD7, 0xCB, 0x0A, 0x00, -+0x24, 0xEA, 0x16, 0x00, 0xAC, 0x2B, 0x16, 0x00, 0x0C, 0xF0, 0x16, 0x00, 0xC1, 0xF0, 0x1F, 0xFF, 0x0C, 0x10, 0x08, 0x40, -+0xD2, 0xCB, 0x0A, 0x00, 0x00, 0xEA, 0x16, 0x00, 0x02, 0x49, 0x8E, 0x46, 0x04, 0xEA, 0x16, 0x00, 0x00, 0xB5, 0x02, 0x4B, -+0x08, 0xEA, 0x16, 0x00, 0xDA, 0x6E, 0x00, 0xBD, 0x0C, 0xEA, 0x16, 0x00, 0xC1, 0xE6, 0x0A, 0x00, 0x10, 0xEA, 0x16, 0x00, -+0xAC, 0x2B, 0x16, 0x00, 0x10, 0xF0, 0x16, 0x00, 0xC0, 0xF0, 0xA0, 0xF9, 0x10, 0x10, 0x08, 0x40, 0xBC, 0xE6, 0x0A, 0x00, -+0x14, 0xF0, 0x16, 0x00, 0x43, 0x1C, 0x05, 0xE0, 0x14, 0x10, 0x08, 0x40, 0x1C, 0xFD, 0x0C, 0x00, 0x30, 0xEA, 0x16, 0x00, -+0x01, 0x4B, 0x98, 0x47, 0x34, 0xEA, 0x16, 0x00, 0x01, 0x4B, 0x9F, 0x46, 0x38, 0xEA, 0x16, 0x00, 0xD9, 0x97, 0x10, 0x00, -+0x3C, 0xEA, 0x16, 0x00, 0x59, 0x1E, 0x0D, 0x00, 0x18, 0xF0, 0x16, 0x00, 0x9C, 0xF0, 0x92, 0xFF, 0x18, 0x10, 0x08, 0x40, -+0x08, 0x1B, 0x0D, 0x00, 0x1C, 0xF0, 0x16, 0x00, 0xEC, 0xE1, 0x10, 0x00, 0x1C, 0x10, 0x08, 0x40, 0x30, 0xB8, 0x0B, 0x00, -+0x84, 0x10, 0x08, 0x40, 0x00, 0xF0, 0x16, 0x00, 0x80, 0x10, 0x08, 0x40, 0xFF, 0x00, 0x00, 0x00, 0x58, 0x00, 0x10, 0x40, -+0x00, 0x00, 0x00, 0x00, 0x41, 0x49, 0x43, 0x42, 0x54, 0x5F, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5F, 0x54, 0x42, 0x34, 0x00, -+0x02, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x38, 0x1B, 0x16, 0x00, 0x99, 0x12, 0x10, 0x00, 0x98, 0x19, 0x16, 0x00, -+0xA9, 0x23, 0x10, 0x00, 0x18, 0x1B, 0x16, 0x00, 0x81, 0x07, 0x10, 0x00, 0x20, 0x1B, 0x16, 0x00, 0xCD, 0x09, 0x10, 0x00, -+0x28, 0x1B, 0x16, 0x00, 0xF1, 0x0B, 0x10, 0x00, 0xB0, 0x19, 0x16, 0x00, 0x21, 0x25, 0x10, 0x00, 0x70, 0x1A, 0x16, 0x00, -+0xB9, 0x30, 0x10, 0x00, 0x6C, 0x1A, 0x16, 0x00, 0x19, 0x64, 0x10, 0x00, 0xE0, 0x1A, 0x16, 0x00, 0xB9, 0x69, 0x10, 0x00, -+0xE0, 0x19, 0x16, 0x00, 0xCB, 0x09, 0x10, 0x00, 0xDC, 0x19, 0x16, 0x00, 0xC9, 0x09, 0x10, 0x00, 0x38, 0x19, 0x16, 0x00, -+0x89, 0x54, 0x10, 0x00, 0x1C, 0x1B, 0x16, 0x00, 0x69, 0x56, 0x10, 0x00, 0x24, 0x1B, 0x16, 0x00, 0x75, 0x58, 0x10, 0x00, -+0x7C, 0x1D, 0x16, 0x00, 0xDD, 0x5B, 0x10, 0x00, 0xB0, 0x1A, 0x16, 0x00, 0xB9, 0x5A, 0x10, 0x00, 0xB0, 0x1D, 0x16, 0x00, -+0x31, 0x6D, 0x10, 0x00, 0x8C, 0x1D, 0x16, 0x00, 0x19, 0x6E, 0x10, 0x00, 0x88, 0x1D, 0x16, 0x00, 0x49, 0x6E, 0x10, 0x00, -+0x40, 0x19, 0x16, 0x00, 0xF5, 0x6E, 0x10, 0x00, 0x2C, 0x1B, 0x16, 0x00, 0x51, 0x6F, 0x10, 0x00, 0x80, 0x1D, 0x16, 0x00, -+0xC1, 0x5F, 0x10, 0x00, 0xF4, 0x19, 0x16, 0x00, 0x89, 0x6F, 0x10, 0x00, 0xEC, 0x19, 0x16, 0x00, 0x0D, 0x70, 0x10, 0x00, -+0x54, 0x19, 0x16, 0x00, 0x31, 0x93, 0x10, 0x00, 0x14, 0x1B, 0x16, 0x00, 0x35, 0x94, 0x10, 0x00, 0x8C, 0x19, 0x16, 0x00, -+0xE9, 0x71, 0x10, 0x00, 0x88, 0x19, 0x16, 0x00, 0xB9, 0x7A, 0x10, 0x00, 0x04, 0x1B, 0x16, 0x00, 0x35, 0x97, 0x10, 0x00, -+0x90, 0x19, 0x16, 0x00, 0xFD, 0x9E, 0x10, 0x00, 0x94, 0x19, 0x16, 0x00, 0x5D, 0x9F, 0x10, 0x00, 0xE8, 0x19, 0x16, 0x00, -+0x3D, 0xA2, 0x10, 0x00, 0xE4, 0x1A, 0x16, 0x00, 0x35, 0x02, 0x10, 0x00, 0xD4, 0x1A, 0x16, 0x00, 0x69, 0xA2, 0x10, 0x00, -+0x64, 0x1A, 0x16, 0x00, 0x29, 0x33, 0x10, 0x00, 0x08, 0x1B, 0x16, 0x00, 0x55, 0x91, 0x10, 0x00, 0xBC, 0x19, 0x16, 0x00, -+0x31, 0x38, 0x10, 0x00, 0x68, 0x1A, 0x16, 0x00, 0x79, 0x61, 0x10, 0x00, 0x40, 0x1A, 0x16, 0x00, 0x8D, 0x40, 0x10, 0x00, -+0x3C, 0x1A, 0x16, 0x00, 0x41, 0x07, 0x10, 0x00, 0x4C, 0x1A, 0x16, 0x00, 0x85, 0x54, 0x10, 0x00, 0xB8, 0x19, 0x16, 0x00, -+0x9D, 0x3B, 0x10, 0x00, 0x7C, 0x1A, 0x16, 0x00, 0x41, 0x2A, 0x10, 0x00, 0x68, 0xAD, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x41, 0x49, 0x43, 0x42, 0x54, 0x5F, 0x4D, 0x4F, 0x44, 0x45, 0x5F, 0x54, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, -+0x09, 0x00, 0x00, 0x00, 0xA4, 0xE5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x54, 0xE0, 0x10, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x50, 0xE0, 0x10, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xA8, 0xE5, 0x10, 0x00, -+0x02, 0x00, 0x00, 0x00, 0xB8, 0xE5, 0x10, 0x00, 0x60, 0xE3, 0x16, 0x00, 0xBC, 0xE5, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, -+0xAC, 0xE5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xE5, 0x10, 0x00, 0x20, 0x60, 0x00, 0x00, 0x41, 0x49, 0x43, 0x42, -+0x54, 0x5F, 0x50, 0x4F, 0x57, 0x45, 0x52, 0x5F, 0x4F, 0x4E, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, -+0x3C, 0x00, 0x50, 0x40, 0x00, 0x00, 0x08, 0x00, 0x24, 0x01, 0x50, 0x40, 0x40, 0x00, 0x00, 0x00, 0x41, 0x49, 0x43, 0x42, -+0x54, 0x5F, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5F, 0x54, 0x41, 0x46, 0x00, 0x05, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, -+0x24, 0x0A, 0x16, 0x00, 0x65, 0x7E, 0x10, 0x00, 0xA4, 0x12, 0x16, 0x00, 0x1D, 0x84, 0x10, 0x00, 0xBC, 0x12, 0x16, 0x00, -+0xFD, 0xA3, 0x10, 0x00, 0xC4, 0x12, 0x16, 0x00, 0xE9, 0xB2, 0x10, 0x00, 0x0C, 0x08, 0x16, 0x00, 0x1D, 0xA3, 0x10, 0x00, -+0x5C, 0x07, 0x16, 0x00, 0x45, 0xA3, 0x10, 0x00, 0x84, 0x15, 0x16, 0x00, 0xB9, 0x89, 0x10, 0x00, 0x4C, 0x18, 0x16, 0x00, -+0x65, 0x8B, 0x10, 0x00, 0x6C, 0x18, 0x16, 0x00, 0xE9, 0x8B, 0x10, 0x00, 0xDC, 0x18, 0x16, 0x00, 0x35, 0x8C, 0x10, 0x00, -+0xF4, 0x1A, 0x16, 0x00, 0x99, 0x05, 0x10, 0x00, 0xAC, 0x12, 0x16, 0x00, 0x35, 0x76, 0x10, 0x00, 0x04, 0x10, 0x16, 0x00, -+0xD1, 0x8E, 0x10, 0x00, 0x0C, 0x10, 0x16, 0x00, 0x25, 0x90, 0x10, 0x00, 0x84, 0x10, 0x16, 0x00, 0x41, 0xAA, 0x10, 0x00, -+0x9C, 0x10, 0x16, 0x00, 0xB1, 0xAA, 0x10, 0x00, 0xA4, 0x10, 0x16, 0x00, 0x71, 0xAB, 0x10, 0x00, 0x4C, 0x10, 0x16, 0x00, -+0x5D, 0xAC, 0x10, 0x00, 0xE4, 0x0F, 0x16, 0x00, 0x65, 0x90, 0x10, 0x00, 0xEC, 0x13, 0x16, 0x00, 0xC5, 0xA7, 0x10, 0x00, -+0x0C, 0x13, 0x16, 0x00, 0x55, 0xB3, 0x10, 0x00, 0xFC, 0x12, 0x16, 0x00, 0x1D, 0x26, 0x10, 0x00, 0x74, 0x0A, 0x16, 0x00, -+0xED, 0x27, 0x10, 0x00, 0x74, 0x13, 0x16, 0x00, 0x35, 0xA8, 0x10, 0x00, 0x04, 0x14, 0x16, 0x00, 0xD9, 0xA8, 0x10, 0x00, -+0x4C, 0x14, 0x16, 0x00, 0xB1, 0xAE, 0x10, 0x00, 0x3C, 0x0A, 0x16, 0x00, 0x05, 0xAF, 0x10, 0x00, 0x44, 0x0A, 0x16, 0x00, -+0xF1, 0xAF, 0x10, 0x00, 0x04, 0x15, 0x16, 0x00, 0x51, 0x91, 0x10, 0x00, 0x2C, 0x13, 0x16, 0x00, 0xA1, 0x42, 0x10, 0x00, -+0xD4, 0x0A, 0x16, 0x00, 0xED, 0xAD, 0x10, 0x00, 0x44, 0x11, 0x16, 0x00, 0x51, 0xAD, 0x10, 0x00, 0xE4, 0x12, 0x16, 0x00, -+0x09, 0xA7, 0x10, 0x00, 0x7C, 0x09, 0x16, 0x00, 0x15, 0xCD, 0x10, 0x00, 0x8C, 0x09, 0x16, 0x00, 0x4D, 0xCD, 0x10, 0x00, -+0x94, 0x09, 0x16, 0x00, 0xC1, 0xCD, 0x10, 0x00, 0x6C, 0x14, 0x16, 0x00, 0x71, 0xCD, 0x10, 0x00, 0x70, 0x30, 0x50, 0x40, -+0x00, 0x00, 0x00, 0x00, 0x74, 0x30, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, 0x78, 0x30, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, -+0x7C, 0x30, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, 0x41, 0x49, 0x43, 0x42, 0x54, 0x5F, 0x56, 0x45, 0x52, 0x5F, 0x49, 0x4E, -+0x46, 0x4F, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2D, 0x20, 0x53, 0x65, 0x70, 0x20, 0x31, 0x33, -+0x20, 0x32, 0x30, 0x32, 0x32, 0x20, 0x31, 0x30, 0x3A, 0x33, 0x38, 0x3A, 0x33, 0x39, 0x20, 0x2D, 0x20, 0x67, 0x69, 0x74, -+0x20, 0x30, 0x61, 0x61, 0x62, 0x66, 0x62, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+}; -+ -+char fw_patch_u03[59704] = { -+0x10, 0xB5, 0x15, 0x4B, 0x1B, 0x68, 0x02, 0x2B, 0x02, 0xD0, 0x14, 0x4B, 0x98, 0x47, 0x10, 0xBD, 0x13, 0x4B, 0x1B, 0x68, -+0x3F, 0x22, 0x9A, 0x5C, 0x00, 0x2A, 0xF6, 0xD1, 0x3D, 0x32, 0x9C, 0x5C, 0x10, 0x4B, 0x1A, 0x78, 0x01, 0x32, 0xD2, 0xB2, -+0x10, 0x2A, 0x10, 0xD8, 0x1A, 0x70, 0x0D, 0x49, 0x0A, 0x78, 0x12, 0x03, 0x92, 0xB2, 0x62, 0x23, 0x63, 0x43, 0x0B, 0x4C, -+0x1C, 0x19, 0x22, 0x80, 0x0A, 0x78, 0x12, 0x09, 0x09, 0x49, 0x8C, 0x46, 0x63, 0x44, 0x1A, 0x80, 0xDD, 0xE7, 0x05, 0x4B, -+0x00, 0x22, 0x1A, 0x70, 0xEB, 0xE7, 0xC0, 0x46, 0x50, 0xE0, 0x10, 0x00, 0xC1, 0xE9, 0x0A, 0x00, 0x28, 0x27, 0x16, 0x00, -+0xB0, 0xE6, 0x10, 0x00, 0xFA, 0x64, 0x61, 0x40, 0xFC, 0x64, 0x61, 0x40, 0x10, 0xB5, 0x04, 0x00, 0x0B, 0x4B, 0x1B, 0x68, -+0x00, 0x2B, 0x03, 0xD0, 0x3A, 0x22, 0x9B, 0x5C, 0x01, 0x2B, 0x06, 0xD0, 0x20, 0x00, 0x08, 0x4B, 0x98, 0x47, 0x62, 0x68, -+0x07, 0x4B, 0x1A, 0x60, 0x10, 0xBD, 0x07, 0x49, 0x0B, 0x68, 0x07, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0x9B, 0x03, 0x13, 0x43, -+0x0B, 0x60, 0xEF, 0xE7, 0x18, 0x27, 0x16, 0x00, 0x25, 0xC3, 0x0C, 0x00, 0x30, 0xE6, 0x10, 0x00, 0x00, 0x04, 0x60, 0x40, -+0xFF, 0xFF, 0xDF, 0xFF, 0x10, 0xB5, 0x18, 0x4A, 0x00, 0x23, 0x00, 0x24, 0x14, 0x57, 0x84, 0x42, 0x04, 0xDA, 0x01, 0x33, -+0xDB, 0xB2, 0x01, 0x32, 0x08, 0x2B, 0xF6, 0xD1, 0x12, 0x4A, 0xD2, 0x56, 0x82, 0x42, 0x05, 0xD0, 0x00, 0x29, 0x03, 0xD1, -+0x00, 0x2B, 0x01, 0xD0, 0x01, 0x3B, 0xDB, 0xB2, 0x1A, 0x1C, 0x07, 0x2B, 0x00, 0xD9, 0x07, 0x22, 0xD2, 0xB2, 0x0C, 0x4B, -+0x99, 0x5C, 0x0C, 0x4A, 0x95, 0x23, 0x9B, 0x00, 0xD3, 0x5C, 0x1A, 0x1C, 0xDB, 0xB2, 0x8B, 0x42, 0x00, 0xD9, 0x0A, 0x1C, -+0x07, 0x49, 0x08, 0x4B, 0xCB, 0x5C, 0x18, 0x1C, 0xDB, 0xB2, 0xD1, 0xB2, 0x8B, 0x42, 0x00, 0xD2, 0x10, 0x1C, 0xC0, 0xB2, -+0x10, 0xBD, 0xC0, 0x46, 0x28, 0xE0, 0x10, 0x00, 0xBC, 0xDF, 0x10, 0x00, 0x7C, 0x1E, 0x16, 0x00, 0x55, 0x02, 0x00, 0x00, -+0x10, 0xB5, 0x62, 0x22, 0x42, 0x43, 0x0F, 0x4B, 0x9C, 0x46, 0x62, 0x44, 0x13, 0x88, 0xDB, 0xB2, 0x1E, 0x2B, 0x13, 0xD0, -+0x0C, 0x49, 0x0D, 0x48, 0x0C, 0x5C, 0x0D, 0x48, 0x09, 0x5C, 0x09, 0x19, 0x01, 0x20, 0x8B, 0x42, 0x09, 0xDB, 0x1B, 0x1B, -+0xDB, 0xB2, 0x10, 0x2B, 0x08, 0xD0, 0x11, 0x88, 0xFF, 0x20, 0x81, 0x43, 0x0B, 0x43, 0x13, 0x80, 0x00, 0x20, 0x10, 0xBD, -+0x0E, 0x3B, 0xE9, 0xE7, 0x0E, 0x33, 0xF4, 0xE7, 0x0C, 0x65, 0x61, 0x40, 0x7C, 0x1E, 0x16, 0x00, 0x57, 0x02, 0x00, 0x00, -+0x55, 0x02, 0x00, 0x00, 0x30, 0xB5, 0x62, 0x22, 0x42, 0x43, 0x0F, 0x4B, 0x9C, 0x46, 0x62, 0x44, 0x13, 0x88, 0xDB, 0xB2, -+0x1E, 0x2B, 0x12, 0xD0, 0x0C, 0x49, 0x0D, 0x48, 0x0C, 0x5C, 0x1D, 0x19, 0x03, 0x38, 0x09, 0x5C, 0x01, 0x20, 0x8D, 0x42, -+0x08, 0xDC, 0xEB, 0xB2, 0x10, 0x2B, 0x08, 0xD0, 0x11, 0x88, 0xFF, 0x20, 0x81, 0x43, 0x0B, 0x43, 0x13, 0x80, 0x00, 0x20, -+0x30, 0xBD, 0x0E, 0x3B, 0xEA, 0xE7, 0x0E, 0x33, 0xF4, 0xE7, 0xC0, 0x46, 0x0C, 0x65, 0x61, 0x40, 0x7C, 0x1E, 0x16, 0x00, -+0x57, 0x02, 0x00, 0x00, 0x70, 0x47, 0x70, 0x47, 0x70, 0xB5, 0x00, 0x28, 0x1C, 0xD0, 0x12, 0x4B, 0x1D, 0x68, 0x00, 0x2D, -+0x18, 0xD0, 0xE9, 0x78, 0x09, 0x02, 0x01, 0x23, 0x19, 0x43, 0x03, 0x33, 0xFF, 0x22, 0x0E, 0x48, 0x81, 0xF7, 0xFA, 0xFE, -+0x04, 0x1E, 0x0E, 0xD0, 0x20, 0x00, 0x81, 0xF7, 0x1F, 0xFF, 0xAB, 0xF7, 0x23, 0xFB, 0x03, 0x00, 0x09, 0x48, 0x6A, 0x68, -+0x9B, 0x18, 0x1B, 0x01, 0x1B, 0x09, 0x43, 0x60, 0xD6, 0xF7, 0x9E, 0xFE, 0x70, 0xBD, 0x06, 0x4B, 0x9B, 0x6E, 0x00, 0x22, -+0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xE9, 0xE7, 0xD8, 0xE5, 0x10, 0x00, 0x3F, 0x06, 0x00, 0x00, 0xFC, 0xE6, 0x10, 0x00, -+0x28, 0x19, 0x16, 0x00, 0xF8, 0xB5, 0x05, 0x00, 0x22, 0x4B, 0x23, 0x4A, 0x13, 0x60, 0x02, 0x22, 0xFF, 0x32, 0x9C, 0x5C, -+0x21, 0x4B, 0xE2, 0x18, 0x12, 0x01, 0x13, 0x88, 0x9B, 0x06, 0x5B, 0x0F, 0x01, 0x2B, 0x04, 0xD0, 0x13, 0x88, 0x9B, 0x06, -+0x5B, 0x0F, 0x02, 0x2B, 0x0F, 0xD1, 0x23, 0x01, 0x18, 0x49, 0x8C, 0x46, 0x63, 0x44, 0x1B, 0x7B, 0x00, 0x2B, 0x05, 0xD1, -+0x13, 0x88, 0x38, 0x21, 0x8B, 0x43, 0x20, 0x39, 0x0B, 0x43, 0x13, 0x80, 0x15, 0x48, 0x83, 0xF7, 0xB9, 0xFF, 0x15, 0x4B, -+0x2A, 0x68, 0x9A, 0x42, 0x0F, 0xD0, 0x14, 0x4F, 0xDE, 0x26, 0x76, 0x00, 0x00, 0x23, 0xBB, 0x51, 0x28, 0x00, 0xD7, 0xF7, -+0x4B, 0xF9, 0x11, 0x4B, 0xBB, 0x51, 0xAB, 0xF7, 0xD5, 0xFA, 0xA4, 0x00, 0x0F, 0x4B, 0x18, 0x51, 0xF8, 0xBD, 0x0F, 0x4B, -+0x1B, 0x68, 0x02, 0x2B, 0xEB, 0xD1, 0x2B, 0x7C, 0x9B, 0x00, 0x0D, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x68, 0x0C, 0x4A, -+0x12, 0x68, 0x1A, 0x66, 0x1A, 0x61, 0xE0, 0xE7, 0x80, 0x2A, 0x16, 0x00, 0x0C, 0xE7, 0x10, 0x00, 0x00, 0x10, 0x06, 0x04, -+0xF8, 0xCD, 0x10, 0x00, 0xD1, 0x1F, 0x0D, 0x00, 0x28, 0x19, 0x16, 0x00, 0x35, 0x02, 0x10, 0x00, 0xE0, 0xE5, 0x10, 0x00, -+0x50, 0xE0, 0x10, 0x00, 0xF4, 0x29, 0x16, 0x00, 0xE8, 0xE1, 0x10, 0x00, 0x30, 0xB5, 0x89, 0xB0, 0x04, 0x1E, 0x32, 0xD0, -+0x9E, 0x23, 0xC5, 0x5C, 0x1B, 0x4B, 0x00, 0x93, 0x43, 0x68, 0x01, 0x93, 0x83, 0x68, 0x02, 0x93, 0x6B, 0x46, 0x1D, 0x76, -+0x04, 0x95, 0x18, 0x4B, 0x03, 0x93, 0x83, 0x7D, 0x6A, 0x46, 0x13, 0x75, 0x01, 0x33, 0x53, 0x75, 0x00, 0x23, 0x93, 0x75, -+0xB0, 0x22, 0x82, 0x5C, 0x69, 0x46, 0xCA, 0x75, 0x8B, 0x76, 0xCB, 0x76, 0x01, 0x33, 0x4B, 0x76, 0x68, 0x46, 0xD7, 0xF7, -+0xFB, 0xF8, 0xA9, 0x22, 0xA3, 0x5C, 0x01, 0x33, 0xA3, 0x54, 0x47, 0x3A, 0x6A, 0x43, 0x0C, 0x4B, 0x9C, 0x46, 0x62, 0x44, -+0x13, 0x88, 0xFF, 0x21, 0x8B, 0x43, 0x01, 0x21, 0x0B, 0x43, 0x9B, 0xB2, 0x13, 0x80, 0xA0, 0x23, 0xE1, 0x54, 0x09, 0xB0, -+0x30, 0xBD, 0x06, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xF6, 0xE7, 0xD1, 0xBD, 0x10, 0x00, -+0xDE, 0x05, 0x00, 0x00, 0x1E, 0x65, 0x61, 0x40, 0x28, 0x19, 0x16, 0x00, 0x30, 0xB5, 0x89, 0xB0, 0x03, 0x00, 0x0D, 0x00, -+0x89, 0x00, 0x2B, 0x4A, 0x8C, 0x58, 0x00, 0x2C, 0x36, 0xD0, 0xA6, 0x22, 0xA2, 0x5C, 0x12, 0x1A, 0x03, 0x20, 0x10, 0x40, -+0xC0, 0x18, 0x00, 0x01, 0x00, 0x09, 0x63, 0x68, 0xC3, 0x1A, 0x1A, 0x01, 0x12, 0x09, 0x80, 0x21, 0x09, 0x05, 0x8A, 0x42, -+0x26, 0xD8, 0x1B, 0x01, 0x20, 0x2B, 0x23, 0xD9, 0x20, 0x4B, 0x00, 0x93, 0x01, 0x90, 0xA3, 0x68, 0x02, 0x93, 0x6B, 0x46, -+0x1D, 0x76, 0x04, 0x95, 0x1D, 0x4B, 0x03, 0x93, 0xA3, 0x7D, 0x6A, 0x46, 0x13, 0x75, 0x01, 0x33, 0x53, 0x75, 0x00, 0x23, -+0x93, 0x75, 0xB0, 0x22, 0xA2, 0x5C, 0x69, 0x46, 0xCA, 0x75, 0x8B, 0x76, 0xCB, 0x76, 0x01, 0x33, 0x4B, 0x76, 0x68, 0x46, -+0xD7, 0xF7, 0xA0, 0xF8, 0xA9, 0x22, 0xA3, 0x5C, 0x01, 0x33, 0xA3, 0x54, 0x9F, 0x23, 0xE3, 0x5C, 0x01, 0x2B, 0x01, 0xD0, -+0x09, 0xB0, 0x30, 0xBD, 0xA3, 0x6F, 0x9B, 0xB2, 0x62, 0x21, 0x4D, 0x43, 0x0D, 0x4A, 0xAA, 0x18, 0x13, 0x80, 0xA3, 0x6F, -+0x1B, 0x0C, 0x0C, 0x4A, 0xAA, 0x18, 0x13, 0x80, 0x0B, 0x4B, 0x9C, 0x46, 0x65, 0x44, 0x0B, 0x4B, 0x1B, 0x68, 0xDB, 0x03, -+0xFF, 0x22, 0xD2, 0x03, 0x1A, 0x40, 0x23, 0x6D, 0x13, 0x43, 0x9B, 0xB2, 0x2B, 0x80, 0xE3, 0xE7, 0x38, 0xE6, 0x10, 0x00, -+0x39, 0xCB, 0x10, 0x00, 0xDE, 0x05, 0x00, 0x00, 0xFA, 0x64, 0x61, 0x40, 0xFC, 0x64, 0x61, 0x40, 0x10, 0x65, 0x61, 0x40, -+0xC8, 0xE6, 0x10, 0x00, 0x10, 0xB5, 0x00, 0x28, 0x08, 0xD0, 0x08, 0x4B, 0x98, 0x47, 0x08, 0x4B, 0x1B, 0x68, 0xD9, 0x6A, -+0x05, 0x20, 0xD7, 0xF7, 0x5B, 0xFF, 0x10, 0xBD, 0x05, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, -+0xF7, 0xE7, 0xC0, 0x46, 0x85, 0xC0, 0x0A, 0x00, 0x18, 0x27, 0x16, 0x00, 0x28, 0x19, 0x16, 0x00, 0x10, 0xB5, 0x04, 0x4B, -+0x98, 0x47, 0x04, 0x4B, 0x1B, 0x68, 0x59, 0x6B, 0x06, 0x20, 0xD7, 0xF7, 0x43, 0xFF, 0x10, 0xBD, 0xA5, 0xD7, 0x0A, 0x00, -+0x24, 0x27, 0x16, 0x00, 0x30, 0xB5, 0x89, 0xB0, 0x04, 0x1E, 0x5A, 0xD0, 0x9F, 0x23, 0xC3, 0x5C, 0x01, 0x2B, 0x04, 0xD0, -+0xA0, 0x23, 0x01, 0x22, 0xE2, 0x54, 0x09, 0xB0, 0x30, 0xBD, 0x9D, 0x33, 0xC5, 0x5C, 0x2B, 0x4B, 0x00, 0x93, 0x43, 0x68, -+0x01, 0x93, 0x83, 0x68, 0x02, 0x93, 0x6B, 0x46, 0x1D, 0x76, 0x04, 0x95, 0x27, 0x4B, 0x03, 0x93, 0x83, 0x7D, 0x6A, 0x46, -+0x13, 0x75, 0x01, 0x33, 0x53, 0x75, 0x00, 0x23, 0x93, 0x75, 0xB0, 0x22, 0x82, 0x5C, 0x69, 0x46, 0xCA, 0x75, 0x8B, 0x76, -+0xCB, 0x76, 0x01, 0x33, 0x4B, 0x76, 0x68, 0x46, 0xD7, 0xF7, 0x1A, 0xF8, 0xA9, 0x22, 0xA3, 0x5C, 0x01, 0x33, 0xA3, 0x54, -+0x9F, 0x23, 0xE3, 0x5C, 0x01, 0x2B, 0xD3, 0xD1, 0x23, 0x6D, 0x01, 0x33, 0x5B, 0x08, 0xA2, 0x6F, 0x91, 0xB2, 0x62, 0x22, -+0x55, 0x43, 0x17, 0x4A, 0xAA, 0x18, 0x11, 0x80, 0xA2, 0x6F, 0x12, 0x0C, 0x15, 0x49, 0x69, 0x18, 0x0A, 0x80, 0x15, 0x4A, -+0x94, 0x46, 0x65, 0x44, 0x01, 0x33, 0x5B, 0x08, 0x13, 0x4A, 0x13, 0x43, 0x9B, 0xB2, 0x2B, 0x80, 0x9F, 0x23, 0xE3, 0x5C, -+0x01, 0x2B, 0xB7, 0xD1, 0xA5, 0x33, 0xE2, 0x5C, 0x01, 0x32, 0xA3, 0x3B, 0x13, 0x40, 0x9E, 0x22, 0xA1, 0x5C, 0x9C, 0x3A, -+0x0C, 0x48, 0xD7, 0xF7, 0x3D, 0xF9, 0xAA, 0x23, 0x01, 0x22, 0xE2, 0x54, 0xA8, 0xE7, 0x0A, 0x4B, 0x9B, 0x6E, 0x00, 0x22, -+0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xA4, 0xE7, 0x39, 0xCB, 0x10, 0x00, 0xDE, 0x05, 0x00, 0x00, 0xFA, 0x64, 0x61, 0x40, -+0xFC, 0x64, 0x61, 0x40, 0x10, 0x65, 0x61, 0x40, 0x00, 0x80, 0xFF, 0xFF, 0x7D, 0x03, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, -+0x00, 0x09, 0x01, 0x4B, 0x18, 0x56, 0x70, 0x47, 0x28, 0xE0, 0x10, 0x00, 0xF0, 0xB5, 0xD6, 0x46, 0x4F, 0x46, 0x46, 0x46, -+0xC0, 0xB5, 0x8A, 0x46, 0x5B, 0x49, 0x09, 0x78, 0x06, 0x29, 0x23, 0xD0, 0x5A, 0x49, 0x0C, 0x78, 0x01, 0x2C, 0x07, 0xD0, -+0x20, 0x21, 0x55, 0x46, 0x69, 0x5C, 0x1E, 0x29, 0x08, 0xD8, 0x56, 0x49, 0x01, 0x25, 0x0D, 0x70, 0x20, 0x21, 0x55, 0x46, -+0x69, 0x5C, 0x1F, 0x29, 0x00, 0xD9, 0x9B, 0xE0, 0x52, 0x4F, 0xE6, 0x25, 0x6D, 0x00, 0x00, 0x21, 0x79, 0x51, 0x51, 0x46, -+0x50, 0x4E, 0xB0, 0x47, 0x50, 0x4B, 0x7B, 0x51, 0x4C, 0x4B, 0x1C, 0x70, 0x00, 0x20, 0x1C, 0xBC, 0x90, 0x46, 0x99, 0x46, -+0xA2, 0x46, 0xF0, 0xBD, 0x00, 0x21, 0xE5, 0x20, 0x81, 0xF7, 0xC8, 0xFD, 0x80, 0x46, 0x00, 0x28, 0x14, 0xD0, 0x20, 0x23, -+0x52, 0x46, 0xD7, 0x5C, 0x04, 0x33, 0xD1, 0x5C, 0x53, 0x8C, 0xC9, 0x18, 0x89, 0xB2, 0x45, 0x4B, 0x9C, 0x46, 0x61, 0x44, -+0x3A, 0x00, 0x40, 0x46, 0xD8, 0xF7, 0xDC, 0xFB, 0x00, 0x2F, 0x64, 0xD0, 0x45, 0x46, 0x41, 0x4B, 0x99, 0x46, 0x14, 0xE0, -+0x3B, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xE3, 0xE7, 0x05, 0x2C, 0x27, 0xD0, 0x4B, 0x46, -+0x1A, 0x88, 0x3B, 0x4B, 0x9A, 0x42, 0x36, 0xD0, 0xE2, 0x43, 0xBF, 0x18, 0xFF, 0xB2, 0x01, 0x34, 0x2D, 0x19, 0x00, 0x2F, -+0x4B, 0xD0, 0x2C, 0x78, 0x6E, 0x78, 0x16, 0x2E, 0xED, 0xD0, 0xFF, 0x2E, 0xED, 0xD1, 0x0D, 0x2C, 0xEB, 0xD1, 0xAB, 0x78, -+0x5D, 0x2B, 0xE8, 0xD1, 0xEB, 0x78, 0x00, 0x2B, 0xE5, 0xD1, 0x2B, 0x79, 0x03, 0x2B, 0xE2, 0xD1, 0x6B, 0x79, 0x00, 0x2B, -+0xDF, 0xD1, 0x2D, 0x48, 0x83, 0xF7, 0xB6, 0xFD, 0x2C, 0x4B, 0x80, 0x22, 0x12, 0x04, 0x1A, 0x60, 0xD7, 0xE7, 0xAB, 0x78, -+0x01, 0x2B, 0xD4, 0xD1, 0xEB, 0x78, 0xFD, 0x2B, 0xD1, 0xD1, 0x2B, 0x79, 0x00, 0x2B, 0xCE, 0xD1, 0x6B, 0x79, 0x01, 0x2B, -+0xCB, 0xD1, 0x25, 0x48, 0x83, 0xF7, 0xA2, 0xFD, 0x22, 0x4B, 0x80, 0x22, 0x12, 0x04, 0x1A, 0x60, 0xC3, 0xE7, 0x1D, 0x4B, -+0x5B, 0x88, 0xB3, 0x42, 0xC4, 0xD1, 0x1B, 0x4B, 0x9B, 0x68, 0x00, 0x2B, 0x0C, 0xD0, 0x19, 0x4B, 0x9A, 0x79, 0xA9, 0x1C, -+0x98, 0x68, 0xD8, 0xF7, 0x5F, 0xFB, 0x00, 0x28, 0xB8, 0xD1, 0x18, 0x4B, 0x80, 0x22, 0x12, 0x04, 0x1A, 0x60, 0xB3, 0xE7, -+0x0E, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xEB, 0xE7, 0x20, 0x23, 0x52, 0x46, 0xD3, 0x5C, -+0x00, 0x2B, 0x03, 0xD1, 0x40, 0x46, 0x81, 0xF7, 0xEB, 0xFD, 0x73, 0xE7, 0x50, 0x8C, 0xBA, 0xF7, 0xAD, 0xFD, 0xF7, 0xE7, -+0x53, 0x46, 0x58, 0x8C, 0xBA, 0xF7, 0xA8, 0xFD, 0x6A, 0xE7, 0xC0, 0x46, 0xD0, 0xE5, 0x10, 0x00, 0x59, 0xA9, 0x16, 0x00, -+0x28, 0x19, 0x16, 0x00, 0x45, 0xF8, 0x0B, 0x00, 0x99, 0x05, 0x10, 0x00, 0x00, 0x00, 0x61, 0x40, 0xC4, 0xE5, 0x10, 0x00, -+0x88, 0xAC, 0x00, 0x00, 0x10, 0xCE, 0x10, 0x00, 0x00, 0x41, 0x04, 0x40, 0x00, 0xCE, 0x10, 0x00, 0x70, 0xB5, 0x0C, 0x00, -+0x07, 0x4E, 0x8A, 0x25, 0x6D, 0x00, 0x00, 0x21, 0x71, 0x51, 0x21, 0x00, 0xB3, 0xF7, 0xF0, 0xFC, 0xA4, 0x00, 0x04, 0x4B, -+0xE3, 0x58, 0x04, 0x4A, 0xDA, 0x61, 0x04, 0x4B, 0x73, 0x51, 0x70, 0xBD, 0x28, 0x19, 0x16, 0x00, 0x54, 0x27, 0x16, 0x00, -+0x21, 0x61, 0x10, 0x00, 0x41, 0x07, 0x10, 0x00, 0x10, 0xB5, 0xD2, 0x23, 0x5B, 0x00, 0x1B, 0x68, 0x98, 0x47, 0x10, 0xBD, -+0xF0, 0xB5, 0xCE, 0x46, 0x47, 0x46, 0x80, 0xB5, 0xE3, 0xB0, 0x01, 0xAC, 0xC2, 0x25, 0x6D, 0x00, 0x2A, 0x00, 0x00, 0x21, -+0x20, 0x00, 0x7F, 0xF7, 0xAB, 0xFC, 0x7A, 0x4E, 0x2A, 0x00, 0x00, 0x21, 0x30, 0x68, 0x7F, 0xF7, 0xA5, 0xFC, 0x31, 0x68, -+0x2A, 0x00, 0x01, 0xA8, 0xD8, 0xF7, 0x14, 0xFB, 0x75, 0x48, 0x83, 0xF7, 0x1D, 0xFD, 0x50, 0x22, 0x00, 0x21, 0x4E, 0xA8, -+0x7F, 0xF7, 0x98, 0xFC, 0x00, 0x26, 0x9A, 0x23, 0x5B, 0x00, 0xE6, 0x54, 0x4E, 0xA9, 0x00, 0x20, 0x8B, 0xF7, 0x3A, 0xF8, -+0x86, 0x3D, 0xC0, 0x23, 0x5B, 0x00, 0xE5, 0x54, 0x80, 0x3B, 0xFF, 0x3B, 0x98, 0x46, 0x82, 0x33, 0xFF, 0x33, 0x42, 0x46, -+0xE2, 0x54, 0x03, 0x27, 0x82, 0x23, 0xFF, 0x33, 0xE7, 0x54, 0x0D, 0x3B, 0xE7, 0x54, 0x36, 0x23, 0xFF, 0x33, 0x99, 0x46, -+0xE6, 0x54, 0x4E, 0xA9, 0x00, 0x20, 0x87, 0xF7, 0x6B, 0xFE, 0x4B, 0x46, 0xE0, 0x5C, 0x4E, 0xA9, 0x8B, 0xF7, 0x6A, 0xF8, -+0x50, 0x22, 0x00, 0x21, 0x3A, 0xA8, 0x7F, 0xF7, 0x6D, 0xFC, 0xE4, 0x23, 0xE6, 0x54, 0x3A, 0xA9, 0x00, 0x20, 0x8B, 0xF7, -+0x11, 0xF8, 0x32, 0x23, 0xFF, 0x33, 0xE5, 0x54, 0x30, 0x3B, 0xFF, 0x3B, 0x99, 0x22, 0x52, 0x00, 0xA3, 0x54, 0x02, 0x3A, -+0xA3, 0x54, 0x0C, 0x3A, 0xA3, 0x54, 0x19, 0x3D, 0x43, 0x46, 0x63, 0x55, 0x3A, 0xA9, 0x01, 0x20, 0x87, 0xF7, 0x48, 0xFE, -+0x60, 0x5D, 0x3A, 0xA9, 0x8B, 0xF7, 0x48, 0xF8, 0x4E, 0x4B, 0x1E, 0x60, 0x4E, 0x4D, 0x2E, 0x60, 0x4E, 0x4B, 0x42, 0x46, -+0x1A, 0x60, 0x4E, 0x49, 0x0B, 0x68, 0x4E, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0x5B, 0x00, 0x13, 0x43, 0x0B, 0x60, 0x4C, 0x4C, -+0x27, 0x60, 0x4C, 0x4B, 0x19, 0x68, 0x4C, 0x48, 0xD7, 0xF7, 0x60, 0xFE, 0x0F, 0x23, 0x03, 0x40, 0x22, 0x68, 0x80, 0x21, -+0x8A, 0x43, 0x0A, 0x43, 0x22, 0x60, 0x06, 0x09, 0xFF, 0x22, 0x16, 0x40, 0x46, 0x4F, 0x3E, 0x60, 0x00, 0x0B, 0x10, 0x40, -+0x28, 0x60, 0x5A, 0x08, 0x9B, 0x1A, 0x1B, 0x01, 0x9B, 0x18, 0x43, 0x4A, 0x13, 0x60, 0x23, 0x68, 0x8B, 0x43, 0x23, 0x60, -+0x41, 0x4B, 0x1B, 0x6F, 0x1B, 0x07, 0x06, 0xD1, 0x3F, 0x4A, 0x13, 0x6F, 0x71, 0x39, 0x8B, 0x43, 0x0D, 0x39, 0x0B, 0x43, -+0x13, 0x67, 0x3C, 0x4B, 0x5B, 0x6F, 0x1B, 0x07, 0x06, 0xD1, 0x3A, 0x4A, 0x53, 0x6F, 0x0F, 0x21, 0x8B, 0x43, 0x0D, 0x39, -+0x0B, 0x43, 0x53, 0x67, 0x36, 0x4B, 0x9B, 0x6F, 0x1B, 0x07, 0x06, 0xD1, 0x34, 0x4A, 0x93, 0x6F, 0x0F, 0x21, 0x8B, 0x43, -+0x0D, 0x39, 0x0B, 0x43, 0x93, 0x67, 0x31, 0x4B, 0xDB, 0x6F, 0x1B, 0x07, 0x06, 0xD1, 0x2F, 0x4A, 0xD3, 0x6F, 0x0F, 0x21, -+0x8B, 0x43, 0x0D, 0x39, 0x0B, 0x43, 0xD3, 0x67, 0x2B, 0x4B, 0x19, 0x69, 0x0F, 0x24, 0xA1, 0x43, 0x03, 0x20, 0x01, 0x43, -+0x19, 0x61, 0x59, 0x69, 0xA1, 0x43, 0x01, 0x43, 0x59, 0x61, 0x99, 0x69, 0xA1, 0x43, 0x01, 0x43, 0x99, 0x61, 0xDA, 0x69, -+0xA2, 0x43, 0x02, 0x43, 0xDA, 0x61, 0x18, 0x4B, 0x07, 0x22, 0x1A, 0x60, 0x01, 0xAA, 0x00, 0x23, 0x20, 0x21, 0x53, 0x54, -+0x06, 0x93, 0x05, 0x93, 0x02, 0x93, 0x01, 0x93, 0x15, 0x4A, 0x13, 0x68, 0x1E, 0x39, 0x0B, 0x43, 0x13, 0x60, 0x1B, 0x4B, -+0x1B, 0x68, 0x00, 0x2B, 0x03, 0xD0, 0x13, 0x68, 0x1E, 0x31, 0x0B, 0x43, 0x13, 0x60, 0x18, 0x4B, 0x9A, 0x68, 0x84, 0x23, -+0x17, 0x49, 0xD1, 0x50, 0x17, 0x4B, 0x80, 0x22, 0x92, 0x01, 0x1A, 0x60, 0xC2, 0x22, 0x05, 0x4B, 0x18, 0x68, 0x52, 0x00, -+0x01, 0xA9, 0xD8, 0xF7, 0x2F, 0xFA, 0x63, 0xB0, 0x0C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xF0, 0xBD, 0xFC, 0xE1, 0x10, 0x00, -+0x20, 0xCE, 0x10, 0x00, 0x08, 0x20, 0x04, 0x40, 0x04, 0x20, 0x04, 0x40, 0x24, 0x20, 0x04, 0x40, 0x10, 0x20, 0x04, 0x40, -+0xFF, 0xFE, 0xFF, 0xFF, 0x0C, 0x20, 0x04, 0x40, 0xB8, 0xE5, 0x10, 0x00, 0x00, 0x75, 0x19, 0x03, 0x00, 0x20, 0x04, 0x40, -+0x28, 0x20, 0x04, 0x40, 0x00, 0x30, 0x50, 0x40, 0xBC, 0xE5, 0x10, 0x00, 0x00, 0xED, 0x00, 0xE0, 0xC5, 0x88, 0x08, 0x00, -+0x00, 0xE1, 0x00, 0xE0, 0x70, 0x47, 0x70, 0x47, 0x3D, 0x4B, 0x3E, 0x4A, 0x1A, 0x60, 0x3E, 0x4B, 0x8D, 0x22, 0x12, 0x03, -+0x1A, 0x60, 0x3D, 0x4B, 0x3D, 0x4A, 0x1A, 0x60, 0x3D, 0x4B, 0x3E, 0x4A, 0x1A, 0x60, 0x3E, 0x4B, 0x3E, 0x4A, 0x1A, 0x60, -+0x3E, 0x4B, 0x3F, 0x4A, 0x1A, 0x60, 0x3F, 0x4B, 0x3F, 0x4A, 0x1A, 0x60, 0x3F, 0x4B, 0x40, 0x4A, 0x1A, 0x60, 0x40, 0x4B, -+0x40, 0x4A, 0x1A, 0x60, 0x40, 0x4B, 0x41, 0x4A, 0x1A, 0x60, 0x41, 0x4B, 0x41, 0x4A, 0x1A, 0x60, 0x41, 0x4B, 0x42, 0x4A, -+0x1A, 0x60, 0x42, 0x4B, 0x42, 0x4A, 0x1A, 0x60, 0x42, 0x4B, 0x43, 0x4A, 0x1A, 0x60, 0x43, 0x4B, 0x43, 0x4A, 0x1A, 0x60, -+0x43, 0x4B, 0x44, 0x4A, 0x1A, 0x60, 0x44, 0x4B, 0x44, 0x4A, 0x1A, 0x60, 0x44, 0x4B, 0x45, 0x4A, 0x1A, 0x60, 0x45, 0x4B, -+0x45, 0x4A, 0x1A, 0x60, 0x45, 0x4B, 0x46, 0x4A, 0x1A, 0x60, 0x46, 0x4B, 0x46, 0x4A, 0x1A, 0x60, 0x46, 0x4B, 0x88, 0x22, -+0x52, 0x01, 0x1A, 0x60, 0x45, 0x4B, 0x46, 0x4A, 0x1A, 0x60, 0x46, 0x4B, 0x46, 0x4A, 0x13, 0x60, 0x46, 0x4A, 0x47, 0x49, -+0x11, 0x60, 0x47, 0x4A, 0x13, 0x60, 0x47, 0x4A, 0x13, 0x60, 0x47, 0x4A, 0x13, 0x60, 0x47, 0x4B, 0x47, 0x4A, 0x1A, 0x60, -+0x47, 0x4B, 0x48, 0x4A, 0x1A, 0x60, 0x48, 0x4B, 0x48, 0x4A, 0x1A, 0x60, 0x48, 0x4B, 0x49, 0x4A, 0x1A, 0x60, 0x49, 0x4B, -+0x49, 0x4A, 0x1A, 0x60, 0x49, 0x4B, 0x4A, 0x4A, 0x1A, 0x60, 0x4A, 0x4B, 0x4A, 0x4A, 0x1A, 0x60, 0x4A, 0x4B, 0xFF, 0x22, -+0x12, 0x02, 0x1A, 0x60, 0x49, 0x4B, 0x4A, 0x4A, 0x1A, 0x60, 0x4A, 0x4B, 0x4A, 0x4A, 0x1A, 0x60, 0x4A, 0x4B, 0x74, 0x22, -+0x1A, 0x60, 0x4A, 0x4B, 0x4A, 0x4A, 0x1A, 0x60, 0x4A, 0x4B, 0x4B, 0x4A, 0x1A, 0x60, 0x70, 0x47, 0x04, 0x01, 0x58, 0x40, -+0xFB, 0x33, 0x09, 0x00, 0x1C, 0x20, 0x62, 0x40, 0x28, 0x20, 0x62, 0x40, 0x20, 0x20, 0x91, 0x48, 0x14, 0x20, 0x62, 0x40, -+0x83, 0x89, 0x01, 0x00, 0x54, 0x20, 0x62, 0x40, 0x34, 0x8F, 0x00, 0x00, 0x48, 0x07, 0x62, 0x40, 0xA0, 0x01, 0x1A, 0x02, -+0x28, 0x07, 0x62, 0x40, 0x20, 0x00, 0x01, 0x00, 0x38, 0x07, 0x62, 0x40, 0xD4, 0x0F, 0x80, 0x04, 0x3C, 0x07, 0x62, 0x40, -+0x64, 0x00, 0xC8, 0x00, 0x2C, 0x20, 0x62, 0x40, 0x20, 0xB2, 0x0C, 0x00, 0x0C, 0x20, 0x62, 0x40, 0x45, 0x2B, 0xAD, 0xE9, -+0x30, 0x20, 0x62, 0x40, 0xD2, 0x30, 0x0C, 0x14, 0x34, 0x20, 0x62, 0x40, 0x02, 0x16, 0x00, 0x00, 0x54, 0x07, 0x62, 0x40, -+0xFD, 0x20, 0x42, 0x21, 0x58, 0x07, 0x62, 0x40, 0x1E, 0xF0, 0x07, 0x00, 0x1C, 0x07, 0x62, 0x40, 0x33, 0x0A, 0x00, 0x00, -+0x18, 0x20, 0x62, 0x40, 0x24, 0x41, 0x12, 0x00, 0x0C, 0x00, 0x62, 0x40, 0x00, 0x00, 0x04, 0x04, 0x90, 0x00, 0x62, 0x40, -+0x82, 0x90, 0x06, 0x00, 0x34, 0x10, 0x62, 0x40, 0x80, 0x30, 0x00, 0x02, 0x14, 0x10, 0x62, 0x40, 0x7A, 0x11, 0x45, 0x04, -+0x24, 0x20, 0x62, 0x40, 0x04, 0x20, 0x62, 0x40, 0xC0, 0xA9, 0x01, 0x00, 0x34, 0x08, 0x50, 0x00, 0x8C, 0x04, 0x60, 0x40, -+0x10, 0x01, 0x60, 0x40, 0x58, 0x00, 0x7E, 0x02, 0x80, 0x08, 0x60, 0x40, 0x84, 0x08, 0x60, 0x40, 0x88, 0x08, 0x60, 0x40, -+0x8C, 0x08, 0x60, 0x40, 0x34, 0x08, 0x00, 0x00, 0x18, 0x05, 0x62, 0x40, 0x0A, 0x88, 0x92, 0x36, 0x14, 0x05, 0x62, 0x40, -+0x10, 0x1A, 0x0C, 0xA8, 0x2C, 0x05, 0x62, 0x40, 0x03, 0x14, 0x0C, 0x9C, 0x0C, 0x05, 0x62, 0x40, 0x13, 0x20, 0x20, 0x20, -+0xA0, 0x05, 0x62, 0x40, 0x00, 0x0C, 0x15, 0x14, 0xA4, 0x05, 0x62, 0x40, 0x24, 0x36, 0x2D, 0x36, 0xF0, 0x05, 0x62, 0x40, -+0x08, 0x05, 0x62, 0x40, 0x32, 0x31, 0x55, 0x54, 0x30, 0x05, 0x62, 0x40, 0x00, 0x12, 0x17, 0x13, 0x34, 0x05, 0x62, 0x40, -+0xB0, 0x05, 0x62, 0x40, 0x55, 0x53, 0x00, 0x00, 0x1C, 0x05, 0x62, 0x40, 0x66, 0x57, 0x4B, 0x96, 0x2A, 0x49, 0x0B, 0x68, -+0x2A, 0x4A, 0x1A, 0x40, 0xFC, 0x23, 0x9B, 0x05, 0x13, 0x43, 0x0B, 0x60, 0x28, 0x4B, 0x29, 0x4A, 0x1A, 0x60, 0x29, 0x4B, -+0x29, 0x4A, 0x1A, 0x60, 0x29, 0x4B, 0x2A, 0x4A, 0x1A, 0x60, 0x2A, 0x4B, 0x2A, 0x4A, 0x1A, 0x60, 0x2A, 0x4B, 0x2B, 0x4A, -+0x1A, 0x60, 0x2B, 0x4B, 0x2B, 0x4A, 0x1A, 0x60, 0x2B, 0x4B, 0x2C, 0x4A, 0x13, 0x60, 0x2C, 0x4A, 0x2C, 0x49, 0x11, 0x60, -+0x2C, 0x4A, 0x13, 0x60, 0x2C, 0x4A, 0x13, 0x60, 0x2C, 0x4A, 0x13, 0x60, 0x2C, 0x4B, 0x2D, 0x4A, 0x1A, 0x60, 0x2D, 0x4B, -+0x2D, 0x4A, 0x1A, 0x60, 0x2D, 0x4B, 0x2E, 0x4A, 0x1A, 0x60, 0x2E, 0x4B, 0x2E, 0x4A, 0x1A, 0x60, 0x2E, 0x4B, 0x2F, 0x4A, -+0x1A, 0x60, 0x2F, 0x4B, 0x2F, 0x4A, 0x1A, 0x60, 0x2F, 0x4B, 0x30, 0x4A, 0x1A, 0x60, 0x30, 0x4B, 0x30, 0x4A, 0x1A, 0x60, -+0x30, 0x4B, 0xFF, 0x22, 0x12, 0x02, 0x1A, 0x60, 0x2F, 0x4B, 0x30, 0x4A, 0x1A, 0x60, 0x30, 0x4B, 0x76, 0x22, 0x1A, 0x60, -+0x2F, 0x4B, 0x30, 0x4A, 0x1A, 0x60, 0x30, 0x4B, 0x30, 0x4A, 0x1A, 0x60, 0x30, 0x4B, 0x31, 0x4A, 0x1A, 0x60, 0x31, 0x4B, -+0x31, 0x4A, 0x1A, 0x60, 0x70, 0x47, 0xC0, 0x46, 0x0C, 0x00, 0x58, 0x40, 0xFF, 0xFF, 0xFF, 0xC0, 0x04, 0x01, 0x58, 0x40, -+0xFB, 0x33, 0x09, 0x00, 0x20, 0x40, 0x34, 0x40, 0x77, 0x0B, 0x00, 0x00, 0x24, 0x40, 0x34, 0x40, 0x94, 0xC5, 0x6E, 0x00, -+0x28, 0x40, 0x34, 0x40, 0x02, 0x94, 0x00, 0x00, 0x2C, 0x40, 0x34, 0x40, 0x84, 0x18, 0x20, 0x56, 0x30, 0x40, 0x34, 0x40, -+0x68, 0x51, 0x2E, 0x1A, 0x34, 0x08, 0x50, 0x00, 0x8C, 0x04, 0x60, 0x40, 0x10, 0x01, 0x60, 0x40, 0x58, 0x00, 0x7E, 0x02, -+0x80, 0x08, 0x60, 0x40, 0x84, 0x08, 0x60, 0x40, 0x88, 0x08, 0x60, 0x40, 0x8C, 0x08, 0x60, 0x40, 0x34, 0x08, 0x00, 0x00, -+0x18, 0x05, 0x62, 0x40, 0x0A, 0x88, 0x92, 0x36, 0x14, 0x05, 0x62, 0x40, 0x10, 0x1A, 0x0C, 0xA8, 0x2C, 0x05, 0x62, 0x40, -+0x03, 0x14, 0x0C, 0x9C, 0x0C, 0x05, 0x62, 0x40, 0x13, 0x20, 0x20, 0x20, 0x08, 0x05, 0x62, 0x40, 0x32, 0x31, 0x55, 0x54, -+0xA0, 0x05, 0x62, 0x40, 0x00, 0x16, 0x17, 0x0F, 0xA4, 0x05, 0x62, 0x40, 0x36, 0x36, 0x28, 0x36, 0xF0, 0x05, 0x62, 0x40, -+0x30, 0x05, 0x62, 0x40, 0x00, 0x1A, 0x17, 0x13, 0x34, 0x05, 0x62, 0x40, 0xB0, 0x05, 0x62, 0x40, 0x55, 0x53, 0x00, 0x00, -+0x1C, 0x05, 0x62, 0x40, 0x66, 0x57, 0x4B, 0x96, 0x90, 0x00, 0x62, 0x40, 0x32, 0x00, 0x05, 0x00, 0x10, 0x10, 0x62, 0x40, -+0x43, 0x01, 0x00, 0x12, 0x10, 0xB5, 0x01, 0x28, 0x03, 0xD0, 0x02, 0x38, 0x01, 0x28, 0x05, 0xD9, 0x10, 0xBD, 0x87, 0xF7, -+0x99, 0xFF, 0xFF, 0xF7, 0x2B, 0xFE, 0xF9, 0xE7, 0x88, 0xF7, 0x96, 0xF8, 0x0A, 0x4A, 0x11, 0x68, 0x80, 0x23, 0xDB, 0x05, -+0x0B, 0x43, 0x13, 0x60, 0xFF, 0xF7, 0x32, 0xFF, 0x07, 0x4B, 0x1B, 0x68, 0x9B, 0x02, 0xEB, 0xD4, 0x05, 0x49, 0x0B, 0x68, -+0x05, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0x1B, 0x04, 0x13, 0x43, 0x0B, 0x60, 0xE2, 0xE7, 0xC0, 0x46, 0x1C, 0x20, 0x34, 0x40, -+0x58, 0x40, 0x34, 0x40, 0xFF, 0xFF, 0x7F, 0xFF, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, -+0x83, 0xB0, 0x01, 0x90, 0x0D, 0x00, 0x00, 0x24, 0x25, 0x4A, 0x26, 0x4B, 0x9B, 0x46, 0xE0, 0x23, 0xDB, 0x04, 0x9A, 0x46, -+0xC0, 0x23, 0x9B, 0x05, 0x99, 0x46, 0x23, 0x4B, 0x98, 0x46, 0x23, 0x4B, 0x00, 0x93, 0x23, 0x4F, 0x23, 0x4E, 0x13, 0x68, -+0x58, 0x46, 0x03, 0x40, 0x50, 0x46, 0x20, 0x40, 0x03, 0x43, 0x13, 0x60, 0x13, 0x68, 0x48, 0x46, 0x03, 0x43, 0x13, 0x60, -+0x43, 0x46, 0x1B, 0x68, 0x00, 0x98, 0x00, 0x68, 0x1B, 0x04, 0x3B, 0x40, 0x40, 0x04, 0x40, 0x0C, 0x03, 0x43, 0x08, 0xC5, -+0x13, 0x68, 0x33, 0x40, 0x13, 0x60, 0x80, 0x23, 0x5B, 0x04, 0x9C, 0x46, 0x64, 0x44, 0x80, 0x23, 0xDB, 0x04, 0x9C, 0x42, -+0xDF, 0xD1, 0x04, 0x20, 0x01, 0x9B, 0x01, 0x2B, 0x06, 0xD0, 0x03, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, -+0xAB, 0x46, 0xF0, 0xBD, 0x0E, 0x4B, 0x1B, 0x68, 0x0B, 0x61, 0x0E, 0x4B, 0x1B, 0x68, 0x4B, 0x61, 0x0D, 0x4B, 0x1B, 0x68, -+0x8B, 0x61, 0x0D, 0x4B, 0x1B, 0x68, 0xCB, 0x61, 0x0C, 0x4B, 0x1B, 0x68, 0x0B, 0x62, 0x05, 0x30, 0xE7, 0xE7, 0xC0, 0x46, -+0x28, 0x05, 0x62, 0x40, 0xFF, 0xFF, 0xFF, 0xF8, 0x8C, 0x08, 0x62, 0x40, 0x90, 0x08, 0x62, 0x40, 0x00, 0x00, 0xFF, 0x7F, -+0xFF, 0xFF, 0xFF, 0xCF, 0x30, 0x07, 0x62, 0x40, 0x34, 0x07, 0x62, 0x40, 0x5C, 0x07, 0x62, 0x40, 0x60, 0x07, 0x62, 0x40, -+0x20, 0x20, 0x62, 0x40, 0x12, 0x04, 0x12, 0x4B, 0x1A, 0x40, 0x49, 0x04, 0x49, 0x0C, 0x0A, 0x43, 0x10, 0x4B, 0x1A, 0x60, -+0x10, 0x4B, 0x1A, 0x68, 0x00, 0x06, 0xE0, 0x21, 0xC9, 0x04, 0x08, 0x40, 0x0E, 0x49, 0x0A, 0x40, 0x10, 0x43, 0x18, 0x60, -+0x19, 0x68, 0x80, 0x22, 0x12, 0x06, 0x0A, 0x43, 0x1A, 0x60, 0x19, 0x68, 0x80, 0x22, 0xD2, 0x05, 0x0A, 0x43, 0x1A, 0x60, -+0x1A, 0x68, 0x08, 0x49, 0x0A, 0x40, 0x1A, 0x60, 0x1A, 0x68, 0x52, 0x00, 0x52, 0x08, 0x1A, 0x60, 0x70, 0x47, 0xC0, 0x46, -+0x00, 0x00, 0xFF, 0x7F, 0x44, 0x05, 0x62, 0x40, 0x28, 0x05, 0x62, 0x40, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xBF, -+0xF0, 0xB5, 0xD6, 0x46, 0x4F, 0x46, 0x46, 0x46, 0xC0, 0xB5, 0x82, 0xB0, 0x1C, 0x49, 0x0B, 0x68, 0x99, 0x46, 0x1C, 0x4A, -+0x1A, 0x40, 0x1C, 0x4B, 0x13, 0x43, 0x0B, 0x60, 0x1B, 0x4B, 0x1B, 0x68, 0x98, 0x46, 0x1B, 0x4B, 0x1B, 0x68, 0x9A, 0x46, -+0x00, 0x24, 0xF0, 0x23, 0x47, 0x46, 0x9F, 0x43, 0x16, 0x4E, 0xE5, 0xB2, 0x00, 0x22, 0x00, 0x21, 0x28, 0x00, 0xFF, 0xF7, -+0xB1, 0xFF, 0x23, 0x01, 0x3B, 0x43, 0x33, 0x60, 0x88, 0xF7, 0x3D, 0xF9, 0x69, 0x46, 0x01, 0xA8, 0x88, 0xF7, 0x4A, 0xF9, -+0x00, 0x9A, 0x01, 0x99, 0x28, 0x00, 0xFF, 0xF7, 0xA3, 0xFF, 0x01, 0x34, 0x04, 0x2C, 0xE8, 0xD1, 0x07, 0x4B, 0x4A, 0x46, -+0x1A, 0x60, 0x09, 0x4B, 0x42, 0x46, 0x1A, 0x60, 0x08, 0x4B, 0x52, 0x46, 0x1A, 0x60, 0x02, 0xB0, 0x1C, 0xBC, 0x90, 0x46, -+0x99, 0x46, 0xA2, 0x46, 0xF0, 0xBD, 0xC0, 0x46, 0x1C, 0x05, 0x62, 0x40, 0xFF, 0xFF, 0x8F, 0x7F, 0x0A, 0x00, 0x20, 0x00, -+0x08, 0x05, 0x62, 0x40, 0x04, 0x00, 0x62, 0x40, 0x70, 0xB5, 0x0C, 0x4D, 0x2C, 0x68, 0x2A, 0x68, 0x0B, 0x4E, 0x32, 0x40, -+0x80, 0x23, 0x5B, 0x00, 0x13, 0x43, 0x2B, 0x60, 0x26, 0x20, 0x88, 0xF7, 0x3F, 0xFF, 0xFF, 0xF7, 0xA7, 0xFF, 0x88, 0xF7, -+0x81, 0xFF, 0x2B, 0x68, 0xE4, 0x05, 0xE4, 0x0F, 0x24, 0x02, 0x33, 0x40, 0x1C, 0x43, 0x2C, 0x60, 0x70, 0xBD, 0xC0, 0x46, -+0x00, 0x04, 0x60, 0x40, 0xFF, 0xFE, 0xFF, 0xFF, 0x10, 0xB5, 0x26, 0x20, 0x88, 0xF7, 0x62, 0xF9, 0xFF, 0xF7, 0x92, 0xFF, -+0x88, 0xF7, 0xBA, 0xF9, 0x10, 0xBD, 0x00, 0x00, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, -+0x8B, 0xB0, 0x82, 0x46, 0x0C, 0x00, 0x03, 0x68, 0x7F, 0x22, 0x1A, 0x40, 0x93, 0x46, 0x1E, 0x09, 0x0F, 0x25, 0x2E, 0x40, -+0x1D, 0x40, 0x01, 0x95, 0x0C, 0x22, 0x13, 0x42, 0x05, 0xD0, 0x35, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, -+0x98, 0x47, 0x01, 0x9B, 0x9E, 0x42, 0x05, 0xD9, 0x30, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, -+0x2E, 0x4B, 0x98, 0x46, 0x1F, 0x68, 0x1A, 0x68, 0x2D, 0x4B, 0x99, 0x46, 0x1A, 0x40, 0x80, 0x23, 0x5B, 0x00, 0x13, 0x43, -+0x42, 0x46, 0x13, 0x60, 0x58, 0x46, 0x88, 0xF7, 0xF1, 0xFE, 0x53, 0x46, 0x19, 0x68, 0x03, 0xA8, 0x89, 0xF7, 0x0E, 0xF9, -+0x88, 0xF7, 0x30, 0xFF, 0x43, 0x46, 0x1B, 0x68, 0xFF, 0x05, 0xFF, 0x0F, 0x3F, 0x02, 0x4A, 0x46, 0x13, 0x40, 0x1F, 0x43, -+0x43, 0x46, 0x1F, 0x60, 0x01, 0x9B, 0x9E, 0x42, 0x30, 0xD8, 0x37, 0x00, 0x20, 0x36, 0x36, 0x01, 0x1D, 0x4B, 0xF6, 0x18, -+0x03, 0xA9, 0x1D, 0x4B, 0x98, 0x46, 0xF0, 0x23, 0x1B, 0x05, 0x9C, 0x46, 0x23, 0x1D, 0x99, 0x46, 0x05, 0xE0, 0x01, 0x37, -+0x10, 0x36, 0xFB, 0xB2, 0x01, 0x9A, 0x9A, 0x42, 0x1C, 0xD3, 0x7B, 0x18, 0x1A, 0x7D, 0x12, 0x02, 0xDB, 0x7B, 0x1A, 0x43, -+0x43, 0x46, 0x1A, 0x43, 0x32, 0x60, 0x7B, 0x5C, 0x18, 0x05, 0x65, 0x46, 0x28, 0x40, 0x1B, 0x07, 0x5B, 0x0F, 0x5B, 0x07, -+0x03, 0x43, 0x70, 0x68, 0x00, 0x02, 0x00, 0x0A, 0x03, 0x43, 0x73, 0x60, 0x00, 0x2C, 0xE2, 0xD0, 0xFB, 0x00, 0xE2, 0x50, -+0x4A, 0x46, 0x70, 0x68, 0xD0, 0x50, 0xDC, 0xE7, 0x0B, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, -+0xF0, 0xBD, 0xC0, 0x46, 0x28, 0x19, 0x16, 0x00, 0x00, 0x04, 0x60, 0x40, 0xFF, 0xFE, 0xFF, 0xFF, 0xD8, 0x99, 0x16, 0x00, -+0x00, 0x00, 0x80, 0x80, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x87, 0xB0, 0x05, 0x00, -+0x01, 0x91, 0x03, 0x68, 0x5A, 0x02, 0x52, 0x0E, 0x90, 0x46, 0x1C, 0x09, 0x0F, 0x26, 0x34, 0x40, 0x1E, 0x40, 0x0C, 0x22, -+0x13, 0x42, 0x05, 0xD0, 0x38, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xB4, 0x42, 0x2F, 0xD9, -+0x34, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x40, 0x46, 0x88, 0xF7, 0xAD, 0xF8, 0x29, 0x68, -+0x02, 0xA8, 0x88, 0xF7, 0x09, 0xFB, 0x88, 0xF7, 0x03, 0xF9, 0x80, 0x22, 0x52, 0x00, 0x2D, 0x49, 0x2D, 0x48, 0xD7, 0xF7, -+0x49, 0xFE, 0x07, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0x01, 0x35, 0xEB, 0xB2, -+0x9E, 0x42, 0xEE, 0xD3, 0x2B, 0x01, 0xA8, 0x00, 0x63, 0x44, 0x1A, 0x68, 0x22, 0x40, 0x02, 0xA9, 0x41, 0x58, 0x00, 0x91, -+0xC9, 0x01, 0x0A, 0x43, 0x1A, 0x60, 0x01, 0x9B, 0x00, 0x2B, 0xED, 0xD0, 0x1A, 0x50, 0xEB, 0xE7, 0x40, 0x46, 0x88, 0xF7, -+0x83, 0xF8, 0x29, 0x68, 0x02, 0xA8, 0x88, 0xF7, 0xDF, 0xFA, 0x25, 0x00, 0xA2, 0x00, 0x02, 0xAB, 0x9C, 0x46, 0x62, 0x44, -+0xFC, 0x23, 0x1B, 0x01, 0x98, 0x46, 0xF8, 0x23, 0x5B, 0x02, 0x9C, 0x46, 0x3F, 0x20, 0xF8, 0x23, 0x9B, 0x03, 0x9B, 0x46, -+0x13, 0x68, 0x1F, 0x0A, 0x41, 0x46, 0x0F, 0x40, 0xB9, 0x46, 0xD9, 0x00, 0x0F, 0x00, 0x61, 0x46, 0x0F, 0x40, 0xBA, 0x46, -+0x4F, 0x46, 0x51, 0x46, 0x0F, 0x43, 0xB9, 0x46, 0x19, 0x0D, 0x0F, 0x00, 0x07, 0x40, 0xBA, 0x46, 0x4F, 0x46, 0x51, 0x46, -+0x0F, 0x43, 0x5B, 0x03, 0x59, 0x46, 0x0B, 0x40, 0x3B, 0x43, 0x08, 0xC2, 0x01, 0x34, 0xE4, 0xB2, 0xA6, 0x42, 0xE1, 0xD2, -+0x88, 0xF7, 0xAC, 0xF8, 0x02, 0x4B, 0x9C, 0x46, 0x03, 0x4C, 0xB5, 0xE7, 0x28, 0x19, 0x16, 0x00, 0xD8, 0x97, 0x16, 0x00, -+0x00, 0x50, 0x1E, 0x00, 0x7F, 0x00, 0x00, 0xE0, 0x70, 0xB5, 0x8E, 0xB0, 0x87, 0xF7, 0x76, 0xFF, 0x04, 0x00, 0x01, 0x28, -+0x05, 0xD0, 0x83, 0x1E, 0xDB, 0xB2, 0x01, 0x2B, 0x24, 0xD9, 0x0E, 0xB0, 0x70, 0xBD, 0x1C, 0x4B, 0x00, 0x93, 0x1C, 0x4C, -+0x25, 0x68, 0xF0, 0x23, 0x2A, 0x00, 0x9A, 0x43, 0x13, 0x00, 0x70, 0x22, 0x13, 0x43, 0x23, 0x60, 0x01, 0xA9, 0x68, 0x46, -+0xFF, 0xF7, 0x56, 0xFF, 0x25, 0x60, 0x16, 0x4B, 0x00, 0x93, 0x00, 0x21, 0x68, 0x46, 0x88, 0xF7, 0xE9, 0xFC, 0x00, 0x20, -+0x88, 0xF7, 0xD0, 0xFB, 0x05, 0xA9, 0x01, 0x20, 0xFF, 0xF7, 0xB0, 0xFD, 0x01, 0x20, 0x89, 0xF7, 0x43, 0xFA, 0xFF, 0xF7, -+0xAF, 0xFE, 0xDA, 0xE7, 0x0A, 0x4B, 0x00, 0x93, 0x0A, 0x4D, 0x2E, 0x68, 0xF0, 0x23, 0x32, 0x00, 0x9A, 0x43, 0x13, 0x00, -+0x70, 0x22, 0x13, 0x43, 0x2B, 0x60, 0x01, 0xA9, 0x68, 0x46, 0xFF, 0xF7, 0xA9, 0xFE, 0x2E, 0x60, 0x20, 0x00, 0x89, 0xF7, -+0x2D, 0xFA, 0xFF, 0xF7, 0x7B, 0xFE, 0xC4, 0xE7, 0x03, 0x42, 0x26, 0x00, 0x08, 0x05, 0x62, 0x40, 0x0F, 0x30, 0x02, 0x00, -+0x30, 0xB5, 0x83, 0xB0, 0x41, 0x4B, 0x18, 0x78, 0x87, 0xF7, 0x12, 0xFF, 0x40, 0x4A, 0x80, 0x23, 0x5B, 0x00, 0x06, 0x21, -+0xD1, 0x50, 0x3F, 0x4B, 0x5A, 0x68, 0x3F, 0x49, 0x0A, 0x40, 0x5A, 0x60, 0x59, 0x68, 0x80, 0x22, 0x92, 0x02, 0x0A, 0x43, -+0x5A, 0x60, 0x19, 0x00, 0x44, 0x22, 0x0B, 0x6B, 0x13, 0x40, 0x04, 0x2B, 0xFB, 0xD1, 0x39, 0x4B, 0x18, 0x68, 0x39, 0x49, -+0xD7, 0xF7, 0x32, 0xF9, 0xA0, 0x23, 0x5B, 0x03, 0x03, 0x43, 0x37, 0x4A, 0x13, 0x60, 0x37, 0x49, 0x08, 0x43, 0x10, 0x60, -+0x13, 0x60, 0x30, 0x4B, 0x59, 0x68, 0x35, 0x4A, 0x0A, 0x43, 0x5A, 0x60, 0x2C, 0x49, 0x9A, 0x22, 0x52, 0x00, 0x80, 0x20, -+0x40, 0x01, 0x88, 0x50, 0x1A, 0x68, 0x40, 0x20, 0x02, 0x43, 0x1A, 0x60, 0x18, 0x68, 0x02, 0x24, 0x20, 0x43, 0x18, 0x60, -+0x48, 0x6F, 0x01, 0x22, 0x10, 0x43, 0x48, 0x67, 0x59, 0x6D, 0x2B, 0x4A, 0x11, 0x40, 0x59, 0x65, 0x5A, 0x6D, 0x22, 0x43, -+0x5A, 0x65, 0x5A, 0x6D, 0x28, 0x49, 0x0A, 0x40, 0x5A, 0x65, 0x87, 0xF7, 0xE1, 0xFE, 0x04, 0x00, 0x80, 0x22, 0x52, 0x00, -+0x25, 0x49, 0x26, 0x48, 0xD7, 0xF7, 0x4C, 0xFD, 0x80, 0x22, 0x25, 0x49, 0x25, 0x48, 0xD7, 0xF7, 0x47, 0xFD, 0x01, 0x2C, -+0x05, 0xD1, 0x17, 0x4B, 0xDB, 0x6D, 0x9B, 0x07, 0x0D, 0xD5, 0x03, 0xB0, 0x30, 0xBD, 0xC0, 0x22, 0x92, 0x00, 0x20, 0x49, -+0x20, 0x48, 0xD7, 0xF7, 0x39, 0xFD, 0x80, 0x22, 0x1F, 0x49, 0x20, 0x48, 0xD7, 0xF7, 0x34, 0xFD, 0xED, 0xE7, 0x20, 0x00, -+0x87, 0xF7, 0xD2, 0xFE, 0x20, 0x00, 0xFF, 0xF7, 0xF1, 0xFC, 0x00, 0x23, 0x01, 0x93, 0x00, 0x93, 0x00, 0x22, 0x00, 0x21, -+0x00, 0x20, 0xFF, 0xF7, 0x39, 0xFF, 0x05, 0x4B, 0x1B, 0x78, 0x01, 0x2B, 0xDF, 0xD1, 0x16, 0x4A, 0x13, 0x68, 0x01, 0x21, -+0x8B, 0x43, 0x13, 0x60, 0xD9, 0xE7, 0xC0, 0x46, 0xB4, 0xE5, 0x10, 0x00, 0x00, 0x00, 0x50, 0x40, 0x00, 0x60, 0x50, 0x40, -+0xFF, 0xFF, 0xFB, 0xFF, 0xB0, 0x06, 0x16, 0x00, 0x40, 0x42, 0x0F, 0x00, 0x08, 0x00, 0x58, 0x40, 0x00, 0x00, 0x14, 0x80, -+0x02, 0x88, 0x01, 0x00, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x58, 0xE0, 0x10, 0x00, 0xD8, 0x97, 0x16, 0x00, -+0x58, 0xE1, 0x10, 0x00, 0xD8, 0x98, 0x16, 0x00, 0x18, 0xE2, 0x10, 0x00, 0xD8, 0x99, 0x16, 0x00, 0x18, 0xE5, 0x10, 0x00, -+0x58, 0x99, 0x16, 0x00, 0x04, 0x30, 0x34, 0x40, 0x80, 0x00, 0x01, 0x4B, 0xC0, 0x58, 0x70, 0x47, 0x38, 0x27, 0x16, 0x00, -+0x80, 0x00, 0x01, 0x4B, 0xC0, 0x58, 0x70, 0x47, 0x54, 0x27, 0x16, 0x00, 0x80, 0x00, 0x01, 0x4B, 0x19, 0x50, 0x70, 0x47, -+0x54, 0x27, 0x16, 0x00, 0x03, 0x23, 0x03, 0x40, 0x8B, 0x42, 0x05, 0xD8, 0x03, 0x23, 0x98, 0x43, 0x40, 0x18, 0x00, 0x01, -+0x00, 0x09, 0x70, 0x47, 0x03, 0x30, 0x03, 0x23, 0x98, 0x43, 0x40, 0x18, 0xF7, 0xE7, 0x00, 0x00, 0xF0, 0xB5, 0xC6, 0x46, -+0x00, 0xB5, 0x05, 0x00, 0x0F, 0x00, 0x14, 0x00, 0x06, 0xAB, 0x04, 0xCB, 0x90, 0x46, 0x1A, 0x78, 0x1B, 0x4B, 0x1B, 0x78, -+0x00, 0x2B, 0x01, 0xD0, 0x00, 0x2A, 0x06, 0xD0, 0x18, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0x00, 0x21, 0x99, 0x70, 0xD9, 0x70, -+0x5A, 0x70, 0xAB, 0x68, 0x2A, 0x69, 0x94, 0x46, 0x63, 0x44, 0x18, 0x00, 0x13, 0x49, 0xD7, 0xF7, 0x63, 0xF8, 0x06, 0x00, -+0x10, 0x4B, 0x5D, 0x60, 0x9F, 0x60, 0xDC, 0x60, 0x18, 0x61, 0x00, 0x2C, 0x05, 0xD1, 0x0F, 0x4B, 0x9B, 0x6E, 0x00, 0x22, -+0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x0A, 0x4D, 0x21, 0x00, 0x38, 0x00, 0xD7, 0xF7, 0xD6, 0xF8, 0x29, 0x77, 0x43, 0x46, -+0x6B, 0x61, 0xA4, 0x1B, 0x62, 0x01, 0x12, 0x1B, 0x92, 0x00, 0x12, 0x19, 0x90, 0x00, 0x12, 0x18, 0x78, 0x3A, 0xAA, 0x61, -+0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0xC0, 0x46, 0x74, 0xE6, 0x10, 0x00, 0x71, 0x02, 0x00, 0x00, 0x28, 0x19, 0x16, 0x00, -+0xF0, 0xB5, 0xDE, 0x46, 0x4F, 0x46, 0x46, 0x46, 0xC0, 0xB5, 0x82, 0xB0, 0x80, 0x46, 0x00, 0x91, 0x01, 0x92, 0x99, 0x46, -+0x40, 0x4B, 0x1B, 0x78, 0x01, 0x2B, 0x05, 0xD0, 0x02, 0xB0, 0x1C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA3, 0x46, 0xF0, 0xBD, -+0x3C, 0x4B, 0x1E, 0x68, 0xB4, 0x68, 0x00, 0x2C, 0xF4, 0xD0, 0x00, 0x25, 0x1F, 0x23, 0x9B, 0x46, 0x01, 0x27, 0x03, 0xE0, -+0x3B, 0x00, 0x83, 0x40, 0x9C, 0x43, 0x0D, 0xD0, 0x20, 0x00, 0xD7, 0xF7, 0x8B, 0xF9, 0x5B, 0x46, 0x18, 0x1A, 0x43, 0x1C, -+0xDB, 0x00, 0xF3, 0x18, 0x5B, 0x68, 0x00, 0x2B, 0xF0, 0xD0, 0x01, 0x35, 0xED, 0xB2, 0xED, 0xE7, 0x01, 0x2D, 0xDB, 0xD1, -+0x2C, 0x4B, 0x5C, 0x68, 0xA3, 0x68, 0x22, 0x69, 0x94, 0x46, 0x63, 0x44, 0x1E, 0x00, 0x2B, 0x49, 0x18, 0x00, 0xD6, 0xF7, -+0xFD, 0xFF, 0x05, 0x00, 0x64, 0x68, 0x04, 0x19, 0x27, 0x49, 0x30, 0x00, 0xD7, 0xF7, 0x7C, 0xF8, 0x4B, 0x46, 0x9B, 0x68, -+0x9C, 0x46, 0x8C, 0x45, 0x89, 0x41, 0x49, 0x42, 0x64, 0x18, 0x4B, 0x46, 0x99, 0x8A, 0x89, 0x04, 0x49, 0x0F, 0x04, 0x29, -+0x03, 0xD0, 0x20, 0x00, 0xFF, 0xF7, 0x54, 0xFF, 0x04, 0x00, 0x43, 0x46, 0x1B, 0x68, 0xE1, 0x1A, 0x0A, 0x01, 0x12, 0x09, -+0x80, 0x20, 0x00, 0x05, 0x82, 0x42, 0x11, 0xD8, 0x09, 0x01, 0x0F, 0xD0, 0x15, 0x4A, 0xD1, 0x68, 0xCB, 0x18, 0xE2, 0x1A, -+0x12, 0x01, 0x12, 0x09, 0x82, 0x42, 0x07, 0xD8, 0x1B, 0x01, 0x1B, 0x09, 0xE3, 0x1A, 0x1B, 0x01, 0x02, 0xD0, 0x64, 0x1A, -+0x24, 0x01, 0x24, 0x09, 0x43, 0x46, 0x1C, 0x60, 0x0C, 0x4B, 0xDA, 0x68, 0x55, 0x1B, 0x68, 0x01, 0x40, 0x1B, 0x80, 0x00, -+0x40, 0x19, 0x82, 0x00, 0x80, 0x18, 0x0B, 0x4A, 0x94, 0x46, 0x60, 0x44, 0x00, 0x9A, 0x10, 0x60, 0xD8, 0x68, 0x60, 0x28, -+0x02, 0xD8, 0x01, 0x9B, 0x18, 0x60, 0x87, 0xE7, 0x24, 0x21, 0xD6, 0xF7, 0xB1, 0xFF, 0x01, 0x9B, 0x18, 0x60, 0x81, 0xE7, -+0x74, 0xE6, 0x10, 0x00, 0xF4, 0xE1, 0x10, 0x00, 0x71, 0x02, 0x00, 0x00, 0x1E, 0xFB, 0xFF, 0xFF, 0x03, 0x4B, 0x1B, 0x78, -+0x00, 0x2B, 0x02, 0xD0, 0x01, 0x4B, 0x00, 0x22, 0x1A, 0x70, 0x70, 0x47, 0x74, 0xE6, 0x10, 0x00, 0xF0, 0xB5, 0xDE, 0x46, -+0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x83, 0xB0, 0x06, 0x00, 0x01, 0x92, 0x38, 0x4B, 0x38, 0x4A, 0x13, 0x60, -+0x9C, 0x68, 0x00, 0x2C, 0x08, 0xD0, 0x43, 0x68, 0x9B, 0x46, 0x36, 0x4B, 0x99, 0x46, 0x36, 0x4B, 0x98, 0x46, 0x33, 0x4B, -+0x9A, 0x46, 0x0F, 0xE0, 0xD5, 0xF7, 0x8C, 0xF9, 0x04, 0x1E, 0x5B, 0xD0, 0x73, 0x68, 0x9B, 0x46, 0xF1, 0xE7, 0x75, 0x60, -+0x53, 0x46, 0x1B, 0x68, 0x9B, 0x68, 0xA3, 0x42, 0x46, 0xD0, 0x24, 0x68, 0x00, 0x2C, 0x47, 0xD0, 0x21, 0x00, 0x30, 0x00, -+0xC8, 0x47, 0x00, 0x28, 0x43, 0xD0, 0x05, 0x28, 0xF0, 0xD0, 0xA3, 0x68, 0x22, 0x69, 0x94, 0x46, 0x63, 0x44, 0x1F, 0x00, -+0x41, 0x46, 0x18, 0x00, 0xD6, 0xF7, 0x64, 0xFF, 0x63, 0x68, 0xC5, 0x18, 0x41, 0x46, 0x38, 0x00, 0xD6, 0xF7, 0xE4, 0xFF, -+0xB3, 0x68, 0x9C, 0x46, 0x8C, 0x45, 0x89, 0x41, 0x49, 0x42, 0x6D, 0x18, 0xB1, 0x8A, 0x89, 0x04, 0x49, 0x0F, 0x04, 0x29, -+0x03, 0xD0, 0x28, 0x00, 0xFF, 0xF7, 0xBE, 0xFE, 0x05, 0x00, 0x5B, 0x46, 0xEB, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x80, 0x22, -+0x12, 0x05, 0x93, 0x42, 0x04, 0xD9, 0x5B, 0x46, 0x5B, 0x1B, 0x1B, 0x01, 0x1B, 0x09, 0x5B, 0x42, 0x01, 0x9A, 0x93, 0x42, -+0xC1, 0xD9, 0x63, 0x7E, 0x0B, 0x2B, 0x03, 0xD8, 0x10, 0x4A, 0xDA, 0x40, 0xD3, 0x07, 0xBA, 0xD4, 0xA3, 0x7D, 0xB2, 0x7D, -+0x01, 0x20, 0x9A, 0x42, 0x07, 0xD8, 0x01, 0x33, 0xB3, 0x75, 0x04, 0xE0, 0xD5, 0xF7, 0x38, 0xF9, 0x04, 0x00, 0xB5, 0xE7, -+0x00, 0x20, 0x03, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0x00, 0x20, 0xF6, 0xE7, -+0x64, 0x2A, 0x16, 0x00, 0x10, 0xE7, 0x10, 0x00, 0x51, 0x62, 0x0D, 0x00, 0x71, 0x02, 0x00, 0x00, 0x6A, 0x0C, 0x00, 0x00, -+0x01, 0x4B, 0x18, 0x68, 0x70, 0x47, 0xC0, 0x46, 0x94, 0x40, 0x04, 0x40, 0x02, 0x4B, 0x1B, 0x68, 0x01, 0x20, 0x18, 0x40, -+0x70, 0x47, 0xC0, 0x46, 0x94, 0x40, 0x04, 0x40, 0x02, 0x4B, 0x18, 0x68, 0x80, 0x07, 0xC0, 0x0F, 0x70, 0x47, 0xC0, 0x46, -+0x94, 0x40, 0x04, 0x40, 0x02, 0x4B, 0x18, 0x68, 0xC0, 0x0F, 0xC0, 0x07, 0x70, 0x47, 0xC0, 0x46, 0x48, 0x30, 0x34, 0x40, -+0x01, 0x4B, 0x18, 0x68, 0xC0, 0x0F, 0x70, 0x47, 0x48, 0x30, 0x34, 0x40, 0x02, 0x4B, 0x18, 0x68, 0x40, 0x07, 0xC0, 0x0F, -+0x70, 0x47, 0xC0, 0x46, 0x94, 0x40, 0x04, 0x40, 0x03, 0x4B, 0x1B, 0x68, 0x14, 0x20, 0x18, 0x40, 0x43, 0x1E, 0x98, 0x41, -+0xC0, 0xB2, 0x70, 0x47, 0x94, 0x40, 0x04, 0x40, 0x02, 0x4B, 0x18, 0x68, 0xC0, 0x06, 0xC0, 0x0F, 0x70, 0x47, 0xC0, 0x46, -+0x94, 0x40, 0x04, 0x40, 0x01, 0x4B, 0x18, 0x68, 0xC0, 0x0F, 0x70, 0x47, 0x98, 0x40, 0x04, 0x40, 0x10, 0xB5, 0x10, 0x4B, -+0x1A, 0x68, 0x00, 0x23, 0x01, 0x2A, 0x02, 0xD9, 0x01, 0x20, 0x18, 0x40, 0x10, 0xBD, 0xFF, 0xF7, 0xCF, 0xFF, 0x00, 0x23, -+0x00, 0x28, 0xF7, 0xD0, 0xFF, 0xF7, 0xE2, 0xFF, 0x00, 0x28, 0x03, 0xD1, 0x08, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x05, 0xDA, -+0xFF, 0xF7, 0xB2, 0xFF, 0x01, 0x23, 0x43, 0x40, 0xDB, 0xB2, 0xE9, 0xE7, 0xFF, 0xF7, 0xC2, 0xFF, 0x00, 0x23, 0x00, 0x28, -+0xE4, 0xD0, 0xF3, 0xE7, 0x50, 0xE0, 0x10, 0x00, 0x98, 0x40, 0x04, 0x40, 0x10, 0xB5, 0xFF, 0xF7, 0xB7, 0xFF, 0x00, 0x23, -+0x00, 0x28, 0x02, 0xD1, 0x01, 0x20, 0x18, 0x40, 0x10, 0xBD, 0xFF, 0xF7, 0x99, 0xFF, 0x01, 0x23, 0x43, 0x40, 0xDB, 0xB2, -+0xF6, 0xE7, 0x00, 0x00, 0x05, 0x4B, 0x1B, 0x68, 0x00, 0x28, 0x04, 0xD0, 0x08, 0x22, 0x13, 0x43, 0x02, 0x4A, 0x13, 0x60, -+0x70, 0x47, 0x08, 0x22, 0x93, 0x43, 0xF9, 0xE7, 0x94, 0x40, 0x04, 0x40, 0x04, 0x4A, 0x13, 0x68, 0x40, 0x01, 0x04, 0x49, -+0x0B, 0x40, 0x04, 0x49, 0x08, 0x40, 0x18, 0x43, 0x10, 0x60, 0x70, 0x47, 0x94, 0x40, 0x04, 0x40, 0x1F, 0x00, 0xFE, 0xFF, -+0xE0, 0xFF, 0x01, 0x00, 0x03, 0x4B, 0x1B, 0x68, 0x00, 0x20, 0x01, 0x22, 0x9A, 0x42, 0x40, 0x41, 0xC0, 0xB2, 0x70, 0x47, -+0x50, 0xE0, 0x10, 0x00, 0x02, 0x4B, 0x18, 0x68, 0x43, 0x42, 0x58, 0x41, 0xC0, 0xB2, 0x70, 0x47, 0x50, 0xE0, 0x10, 0x00, -+0x70, 0xB5, 0x01, 0x28, 0x02, 0xD0, 0x02, 0x28, 0x0F, 0xD0, 0x70, 0xBD, 0x0E, 0x4C, 0xEA, 0x25, 0x6D, 0x00, 0x02, 0x22, -+0x02, 0x21, 0x20, 0x00, 0x2B, 0x68, 0x98, 0x47, 0x80, 0x22, 0x2B, 0x68, 0x92, 0x01, 0x00, 0x21, 0x20, 0x00, 0x98, 0x47, -+0xEF, 0xE7, 0x80, 0x21, 0x89, 0x01, 0x06, 0x4C, 0xEA, 0x25, 0x6D, 0x00, 0x0A, 0x00, 0x20, 0x00, 0x2B, 0x68, 0x98, 0x47, -+0x2B, 0x68, 0x02, 0x22, 0x00, 0x21, 0x20, 0x00, 0x98, 0x47, 0xE0, 0xE7, 0x00, 0x10, 0x01, 0x50, 0x70, 0xB5, 0x05, 0x00, -+0x0C, 0x00, 0x39, 0x4B, 0x1B, 0x68, 0x01, 0x20, 0x00, 0x2B, 0x45, 0xD1, 0x00, 0x29, 0x43, 0xD0, 0x00, 0x2D, 0x1A, 0xD0, -+0xEF, 0xF3, 0x10, 0x83, 0x01, 0x22, 0x16, 0x00, 0x1E, 0x40, 0x1A, 0x42, 0x4E, 0xD1, 0x72, 0xB6, 0x31, 0x4B, 0x1B, 0x68, -+0x00, 0x2B, 0x41, 0xD1, 0x00, 0x20, 0x00, 0x2E, 0x4A, 0xD1, 0x62, 0xB6, 0x27, 0xE0, 0x20, 0x00, 0xFF, 0xF7, 0xBA, 0xFF, -+0x2B, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x28, 0x00, 0x00, 0x2E, 0x20, 0xD1, 0xF3, 0xE7, 0xEF, 0xF3, 0x10, 0x83, 0x01, 0x22, -+0x16, 0x00, 0x1E, 0x40, 0x1A, 0x42, 0x00, 0xD1, 0x72, 0xB6, 0x24, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x1B, 0xD1, 0x01, 0x20, -+0x87, 0xF7, 0x51, 0xFC, 0x20, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x14, 0xD1, 0x01, 0x20, 0x87, 0xF7, 0x4A, 0xFC, 0x28, 0x00, -+0x00, 0x2E, 0x00, 0xD1, 0x62, 0xB6, 0x1C, 0x4A, 0x13, 0x68, 0x01, 0x33, 0x13, 0x60, 0x00, 0x28, 0x1E, 0xD0, 0x00, 0x23, -+0x19, 0x4A, 0x13, 0x60, 0x19, 0x4A, 0x13, 0x60, 0x16, 0x4A, 0x13, 0x60, 0x70, 0xBD, 0x20, 0x00, 0xFF, 0xF7, 0x88, 0xFF, -+0x12, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x01, 0x20, 0x87, 0xF7, 0x2F, 0xFC, 0x01, 0x20, 0xE3, 0xE7, 0x08, 0x00, 0xFF, 0xF7, -+0x7D, 0xFF, 0x0D, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x28, 0x00, 0xB8, 0xE7, 0x0A, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0xB6, 0xD1, -+0x09, 0x4B, 0x1B, 0x68, 0x00, 0x20, 0x05, 0x2B, 0xDB, 0xD8, 0x08, 0x4B, 0x1C, 0x60, 0x08, 0x4B, 0x01, 0x22, 0x1A, 0x60, -+0x07, 0x48, 0x82, 0xF7, 0x2F, 0xFC, 0x00, 0x20, 0xD8, 0xE7, 0xC0, 0x46, 0x50, 0xE0, 0x10, 0x00, 0x5C, 0x40, 0x04, 0x40, -+0x54, 0xE6, 0x10, 0x00, 0x58, 0xE6, 0x10, 0x00, 0x5C, 0xE6, 0x10, 0x00, 0x2C, 0xCE, 0x10, 0x00, 0xF0, 0xB5, 0xCE, 0x46, -+0x00, 0xB5, 0x86, 0xB0, 0x2A, 0x4B, 0x1C, 0x68, 0x21, 0x00, 0x2A, 0x48, 0x82, 0xF7, 0x16, 0xFC, 0x03, 0xAA, 0x29, 0x4B, -+0x03, 0xCB, 0x03, 0xC2, 0x1B, 0x88, 0x13, 0x80, 0x00, 0x2C, 0x0D, 0xDB, 0x0A, 0x22, 0x03, 0xA9, 0x25, 0x48, 0xD7, 0xF7, -+0xFD, 0xF9, 0x0A, 0x22, 0x03, 0xA9, 0x24, 0x48, 0xD7, 0xF7, 0xF8, 0xF9, 0x06, 0xB0, 0x04, 0xBC, 0x91, 0x46, 0xF0, 0xBD, -+0xFF, 0x23, 0x1B, 0x04, 0x23, 0x40, 0x80, 0x22, 0x52, 0x02, 0x93, 0x42, 0x11, 0xD0, 0x24, 0x04, 0x24, 0x0C, 0x1D, 0x4B, -+0xE7, 0x18, 0x1D, 0x4B, 0x9C, 0x46, 0x64, 0x44, 0xFB, 0x43, 0xDB, 0x17, 0x1F, 0x40, 0x4E, 0x2C, 0x00, 0xDD, 0x4E, 0x24, -+0x03, 0xAD, 0x00, 0x26, 0x00, 0x23, 0x01, 0x93, 0x1B, 0xE0, 0x24, 0x04, 0x24, 0x0C, 0x16, 0x4B, 0xE7, 0x18, 0x16, 0x4B, -+0x9C, 0x46, 0x64, 0x44, 0xEC, 0xE7, 0x8B, 0x40, 0x1A, 0x43, 0xD2, 0xB2, 0x01, 0x31, 0x08, 0x29, 0x07, 0xD0, 0x88, 0x19, -+0x01, 0x23, 0xB8, 0x42, 0xF5, 0xDB, 0xA0, 0x42, 0xF3, 0xDC, 0x01, 0x9B, 0xF1, 0xE7, 0x4B, 0x46, 0x1A, 0x70, 0x01, 0x35, -+0x08, 0x36, 0x50, 0x2E, 0xBC, 0xD0, 0xA9, 0x46, 0x00, 0x22, 0x00, 0x21, 0xED, 0xE7, 0xC0, 0x46, 0x98, 0x40, 0x04, 0x40, -+0x34, 0xCE, 0x10, 0x00, 0x48, 0xCE, 0x10, 0x00, 0xD8, 0xE1, 0x10, 0x00, 0xC0, 0x9F, 0x16, 0x00, 0x94, 0xF6, 0xFF, 0xFF, -+0xA7, 0xF6, 0xFF, 0xFF, 0x8A, 0xF6, 0xFF, 0xFF, 0xB1, 0xF6, 0xFF, 0xFF, 0x10, 0xB5, 0x84, 0xB0, 0x98, 0x4B, 0x1C, 0x68, -+0x21, 0x00, 0x98, 0x48, 0x82, 0xF7, 0xAC, 0xFB, 0x01, 0xAA, 0x97, 0x4B, 0x03, 0xCB, 0x03, 0xC2, 0x1B, 0x88, 0x13, 0x80, -+0x00, 0x2C, 0x0B, 0xDB, 0x0A, 0x22, 0x01, 0xA9, 0x93, 0x48, 0xD7, 0xF7, 0x93, 0xF9, 0x0A, 0x22, 0x01, 0xA9, 0x92, 0x48, -+0xD7, 0xF7, 0x8E, 0xF9, 0x04, 0xB0, 0x10, 0xBD, 0xFF, 0x23, 0x1B, 0x04, 0x23, 0x40, 0x80, 0x22, 0x52, 0x02, 0x93, 0x42, -+0x00, 0xD1, 0x02, 0xE1, 0x24, 0x04, 0x24, 0x0C, 0x8B, 0x4B, 0x9C, 0x46, 0x64, 0x44, 0x3C, 0x2C, 0xE4, 0xD8, 0xA4, 0x00, -+0x89, 0x4B, 0x1B, 0x59, 0x9F, 0x46, 0x01, 0xAB, 0x00, 0x22, 0x1A, 0x70, 0x5A, 0x70, 0x9A, 0x70, 0xFC, 0x32, 0xDA, 0x70, -+0xD8, 0xE7, 0x0A, 0x21, 0x01, 0xAB, 0x3F, 0x22, 0x1A, 0x70, 0x00, 0x22, 0x5A, 0x70, 0x9A, 0x70, 0xFC, 0x32, 0xDA, 0x70, -+0x14, 0x29, 0xCD, 0xD1, 0x00, 0x22, 0x1A, 0x70, 0xDA, 0x70, 0x1A, 0x71, 0xC8, 0xE7, 0x14, 0x21, 0xEE, 0xE7, 0x0A, 0x21, -+0x01, 0xAB, 0x03, 0x22, 0x5A, 0x70, 0x00, 0x22, 0x9A, 0x70, 0xC0, 0x32, 0xDA, 0x70, 0x14, 0x29, 0xBC, 0xD1, 0x00, 0x22, -+0x1A, 0x70, 0x5A, 0x70, 0xDA, 0x70, 0x1A, 0x71, 0xF0, 0x32, 0x5A, 0x71, 0xB4, 0xE7, 0x14, 0x21, 0xEC, 0xE7, 0x0A, 0x21, -+0x01, 0xAB, 0x00, 0x22, 0x9A, 0x70, 0xDA, 0x70, 0xF0, 0x32, 0x1A, 0x71, 0x14, 0x29, 0xA9, 0xD1, 0xED, 0x3A, 0x1A, 0x70, -+0x00, 0x22, 0x5A, 0x70, 0x1A, 0x71, 0x5A, 0x71, 0xA2, 0xE7, 0x14, 0x21, 0xEE, 0xE7, 0x0A, 0x21, 0x01, 0xAB, 0x3F, 0x22, -+0x9A, 0x70, 0x00, 0x22, 0xDA, 0x70, 0x1A, 0x71, 0xFC, 0x32, 0x5A, 0x71, 0x14, 0x29, 0x95, 0xD1, 0x00, 0x22, 0x5A, 0x70, -+0x9A, 0x70, 0x5A, 0x71, 0xF0, 0x32, 0x9A, 0x71, 0x8E, 0xE7, 0x14, 0x21, 0xEC, 0xE7, 0x0A, 0x21, 0x01, 0xAB, 0x03, 0x22, -+0xDA, 0x70, 0x00, 0x22, 0x1A, 0x71, 0xC0, 0x32, 0x5A, 0x71, 0x14, 0x29, 0x00, 0xD0, 0x81, 0xE7, 0x81, 0x3A, 0x5A, 0x70, -+0x00, 0x22, 0x9A, 0x70, 0xDA, 0x70, 0x5A, 0x71, 0xFC, 0x32, 0x9A, 0x71, 0x78, 0xE7, 0x14, 0x21, 0xEA, 0xE7, 0x0A, 0x21, -+0x01, 0xAB, 0x3F, 0x22, 0xDA, 0x70, 0x00, 0x22, 0x1A, 0x71, 0x5A, 0x71, 0xFC, 0x32, 0x9A, 0x71, 0x14, 0x29, 0x00, 0xD0, -+0x6A, 0xE7, 0xF9, 0x3A, 0x9A, 0x70, 0x00, 0x22, 0xDA, 0x70, 0x9A, 0x71, 0xC0, 0x32, 0xDA, 0x71, 0x62, 0xE7, 0x14, 0x21, -+0xEA, 0xE7, 0x0A, 0x21, 0x01, 0xAB, 0x0F, 0x22, 0x1A, 0x71, 0x00, 0x22, 0x5A, 0x71, 0x9A, 0x71, 0x14, 0x29, 0x00, 0xD0, -+0x56, 0xE7, 0x3F, 0x32, 0x9A, 0x70, 0x00, 0x22, 0xDA, 0x70, 0x1A, 0x71, 0xDA, 0x71, 0x4F, 0xE7, 0x14, 0x21, 0xED, 0xE7, -+0x0A, 0x21, 0x01, 0xAB, 0x00, 0x22, 0x5A, 0x71, 0x9A, 0x71, 0xF0, 0x32, 0xDA, 0x71, 0x14, 0x29, 0x00, 0xD0, 0x43, 0xE7, -+0xE1, 0x3A, 0xDA, 0x70, 0x00, 0x22, 0x1A, 0x71, 0xDA, 0x71, 0x1A, 0x72, 0x3C, 0xE7, 0x14, 0x21, 0xED, 0xE7, 0x0A, 0x21, -+0x01, 0xAB, 0x3F, 0x22, 0x5A, 0x71, 0x00, 0x22, 0x9A, 0x71, 0xDA, 0x71, 0xFC, 0x32, 0x1A, 0x72, 0x14, 0x29, 0x00, 0xD0, -+0x2E, 0xE7, 0xED, 0x3A, 0x1A, 0x71, 0x00, 0x22, 0x5A, 0x71, 0x1A, 0x72, 0x5A, 0x72, 0x27, 0xE7, 0x14, 0x21, 0xEB, 0xE7, -+0x0A, 0x21, 0x01, 0xAB, 0x03, 0x22, 0x9A, 0x71, 0x00, 0x22, 0xDA, 0x71, 0xC0, 0x32, 0x1A, 0x72, 0x14, 0x29, 0x00, 0xD0, -+0x1A, 0xE7, 0x00, 0x22, 0x5A, 0x71, 0x9A, 0x71, 0x1A, 0x72, 0x5A, 0x72, 0x14, 0xE7, 0x14, 0x21, 0xED, 0xE7, 0x0A, 0x21, -+0x01, 0xAB, 0x00, 0x22, 0xDA, 0x71, 0x1A, 0x72, 0xF0, 0x32, 0x5A, 0x72, 0x14, 0x29, 0x00, 0xD0, 0x08, 0xE7, 0x00, 0x22, -+0x9A, 0x71, 0x5A, 0x72, 0x04, 0xE7, 0x14, 0x21, 0xF0, 0xE7, 0x0A, 0x21, 0x01, 0xAB, 0x3F, 0x22, 0xDA, 0x71, 0x00, 0x22, -+0x1A, 0x72, 0x5A, 0x72, 0x14, 0x29, 0x00, 0xD0, 0xF8, 0xE6, 0x0F, 0x32, 0x9A, 0x71, 0x00, 0x22, 0xDA, 0x71, 0xF3, 0xE6, -+0x14, 0x21, 0xEF, 0xE7, 0x01, 0xAB, 0x00, 0x22, 0x1A, 0x70, 0x5A, 0x70, 0x9A, 0x70, 0xDA, 0x70, 0xFC, 0x32, 0x1A, 0x71, -+0xE8, 0xE6, 0x24, 0x04, 0x24, 0x0C, 0x0A, 0x4B, 0x9C, 0x46, 0x64, 0x44, 0x3C, 0x2C, 0x00, 0xD9, 0xE0, 0xE6, 0xA4, 0x00, -+0x08, 0x4B, 0x1B, 0x59, 0x9F, 0x46, 0xC0, 0x46, 0x98, 0x40, 0x04, 0x40, 0x34, 0xCE, 0x10, 0x00, 0x48, 0xCE, 0x10, 0x00, -+0xD8, 0xE1, 0x10, 0x00, 0xC0, 0x9F, 0x16, 0x00, 0x94, 0xF6, 0xFF, 0xFF, 0x54, 0xCE, 0x10, 0x00, 0x48, 0xCF, 0x10, 0x00, -+0x10, 0xB5, 0x08, 0x4B, 0x1B, 0x78, 0x01, 0x2B, 0x00, 0xD0, 0x10, 0xBD, 0x06, 0x4B, 0x1A, 0x6B, 0x06, 0x4B, 0x19, 0x68, -+0x01, 0x20, 0x81, 0x43, 0x19, 0x60, 0x19, 0x68, 0x04, 0x48, 0x82, 0xF7, 0x5F, 0xFA, 0xF2, 0xE7, 0xB4, 0xE5, 0x10, 0x00, -+0x00, 0x60, 0x50, 0x40, 0x04, 0x30, 0x34, 0x40, 0x3C, 0xD0, 0x10, 0x00, 0x70, 0xB5, 0x05, 0x00, 0x0C, 0x00, 0x4C, 0x4B, -+0x1B, 0x68, 0x01, 0x2B, 0x02, 0xD0, 0x4B, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0x4A, 0x4A, 0x13, 0x68, 0x04, 0x21, 0x8B, 0x43, -+0x13, 0x60, 0xA9, 0xF7, 0x71, 0xFD, 0x48, 0x4B, 0x18, 0x60, 0x5C, 0x60, 0x0C, 0x2D, 0x38, 0xD8, 0xAD, 0x00, 0x46, 0x4B, -+0x5B, 0x59, 0x9F, 0x46, 0x80, 0x23, 0xDB, 0x01, 0x00, 0x21, 0x9C, 0x42, 0x1B, 0xD3, 0x43, 0x4A, 0x13, 0x68, 0x43, 0x49, -+0x19, 0x40, 0x80, 0x23, 0x9B, 0x02, 0x0B, 0x43, 0x13, 0x60, 0x11, 0x68, 0xE3, 0x08, 0xC0, 0x20, 0x40, 0x01, 0x03, 0x40, -+0x76, 0x20, 0x03, 0x43, 0x09, 0x0C, 0x09, 0x04, 0x0B, 0x43, 0x13, 0x60, 0x13, 0x68, 0x3B, 0x49, 0x19, 0x40, 0x80, 0x23, -+0x1B, 0x03, 0x0B, 0x43, 0x13, 0x60, 0x80, 0x21, 0xC9, 0x01, 0x35, 0x4B, 0x1A, 0x68, 0x35, 0x48, 0x02, 0x40, 0x1A, 0x60, -+0x1A, 0x68, 0xA4, 0x04, 0xA4, 0x0C, 0x0C, 0x43, 0x12, 0x0C, 0x12, 0x04, 0x14, 0x43, 0x1C, 0x60, 0x1A, 0x68, 0x30, 0x49, -+0x11, 0x40, 0x80, 0x22, 0x12, 0x03, 0x0A, 0x43, 0x1A, 0x60, 0x70, 0xBD, 0x2D, 0x4B, 0x1B, 0x68, 0x9A, 0x6A, 0x5B, 0x6B, -+0xD2, 0x1A, 0xD5, 0x00, 0x55, 0x19, 0x6D, 0x00, 0x55, 0x19, 0xAD, 0xB2, 0x2A, 0x00, 0x21, 0x00, 0x28, 0x48, 0x82, 0xF7, -+0xF7, 0xF9, 0x23, 0x4B, 0x19, 0x68, 0x23, 0x4E, 0x31, 0x40, 0x80, 0x22, 0x92, 0x02, 0x0A, 0x43, 0x1A, 0x60, 0x1A, 0x68, -+0x12, 0x0C, 0x12, 0x04, 0x6D, 0x05, 0x6D, 0x0D, 0x2A, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x1D, 0x48, 0x02, 0x40, 0x80, 0x21, -+0x09, 0x03, 0x0A, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x16, 0x40, 0x1E, 0x60, 0x1A, 0x68, 0xA4, 0x04, 0xA4, 0x0C, 0x80, 0x25, -+0x2D, 0x02, 0x2C, 0x43, 0x12, 0x0C, 0x12, 0x04, 0x14, 0x43, 0x1C, 0x60, 0x1A, 0x68, 0x10, 0x40, 0x01, 0x43, 0x19, 0x60, -+0xC7, 0xE7, 0x0F, 0x4A, 0x13, 0x68, 0x0F, 0x49, 0x0B, 0x40, 0x13, 0x60, 0x13, 0x68, 0x1B, 0x0C, 0x1B, 0x04, 0x10, 0x49, -+0x0C, 0x43, 0xA4, 0xB2, 0x1C, 0x43, 0x14, 0x60, 0x13, 0x68, 0x0A, 0x49, 0x19, 0x40, 0x80, 0x23, 0x1B, 0x03, 0x0B, 0x43, -+0x13, 0x60, 0xB2, 0xE7, 0x50, 0xE0, 0x10, 0x00, 0xB2, 0xE6, 0x10, 0x00, 0xFC, 0x00, 0x60, 0x40, 0x6C, 0xE6, 0x10, 0x00, -+0x5C, 0xD0, 0x10, 0x00, 0xF8, 0x00, 0x60, 0x40, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xF8, 0xE6, 0x10, 0x00, -+0x50, 0xD0, 0x10, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xF0, 0xB5, 0xD6, 0x46, 0x4F, 0x46, 0x46, 0x46, 0xC0, 0xB5, 0x82, 0xB0, -+0x07, 0x00, 0xD4, 0xF7, 0x4B, 0xFD, 0x04, 0x00, 0x00, 0x23, 0x01, 0x93, 0x00, 0x93, 0x3B, 0x4A, 0x13, 0x70, 0x01, 0x21, -+0x01, 0x20, 0xFF, 0xF7, 0xEF, 0xFC, 0x80, 0x46, 0x38, 0x4B, 0x1E, 0x78, 0x02, 0x3E, 0x73, 0x1E, 0x9E, 0x41, 0x76, 0x42, -+0x19, 0x23, 0x1E, 0x40, 0x02, 0x36, 0x00, 0x2C, 0x21, 0xD0, 0x65, 0x68, 0xFB, 0x7D, 0x9A, 0x46, 0xA3, 0x68, 0x99, 0x46, -+0x69, 0x46, 0x01, 0xA8, 0xA9, 0xF7, 0xB0, 0xFC, 0x01, 0x9B, 0x53, 0x44, 0xEB, 0x1A, 0x1B, 0x01, 0x1A, 0x09, 0x5B, 0x00, -+0x9C, 0x1A, 0xA4, 0x00, 0xA4, 0x18, 0xA3, 0x00, 0xE4, 0x18, 0x4B, 0x46, 0x00, 0x9A, 0x9B, 0x1A, 0xE4, 0x18, 0xA4, 0x09, -+0xA6, 0x42, 0x00, 0xD8, 0xA4, 0x1B, 0x80, 0x23, 0x5B, 0x02, 0x9C, 0x42, 0x02, 0xD9, 0x24, 0x4C, 0x00, 0xE0, 0x23, 0x4C, -+0xFF, 0xF7, 0xFC, 0xFB, 0x05, 0x00, 0x43, 0x46, 0x00, 0x2B, 0x12, 0xD0, 0x20, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0x03, 0xD0, -+0x1F, 0x4B, 0x1B, 0x78, 0x01, 0x2B, 0x0F, 0xD0, 0x0A, 0x2C, 0x16, 0xD8, 0x4F, 0x23, 0x00, 0x22, 0xFA, 0x54, 0x02, 0xB0, -+0x1C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xF0, 0xBD, 0x01, 0x21, 0x00, 0x20, 0xFF, 0xF7, 0xA3, 0xFC, 0xE7, 0xE7, -+0x16, 0x4B, 0x80, 0x22, 0x12, 0x05, 0x1A, 0x60, 0x13, 0x4B, 0x02, 0x22, 0x1A, 0x70, 0x00, 0x25, 0xE6, 0xE7, 0xFF, 0xF7, -+0x0B, 0xFC, 0x00, 0x28, 0xE4, 0xD0, 0xB2, 0xF7, 0xC9, 0xFD, 0x06, 0x23, 0x00, 0x28, 0x05, 0xD1, 0x4A, 0x33, 0xFB, 0x5C, -+0x01, 0x3B, 0x58, 0x42, 0x43, 0x41, 0x05, 0x33, 0x00, 0x2D, 0xD7, 0xD1, 0xCF, 0x2C, 0x01, 0xD8, 0x06, 0x2B, 0xD3, 0xD1, -+0x21, 0x00, 0x18, 0x00, 0xFF, 0xF7, 0xCC, 0xFE, 0xCE, 0xE7, 0xC0, 0x46, 0xB2, 0xE6, 0x10, 0x00, 0xB4, 0xE5, 0x10, 0x00, -+0xFF, 0xFF, 0x00, 0x00, 0xB4, 0xE6, 0x10, 0x00, 0xB3, 0xE6, 0x10, 0x00, 0x00, 0x41, 0x04, 0x40, 0x70, 0xB5, 0x4E, 0x23, -+0x01, 0x22, 0xC2, 0x54, 0x2A, 0x4B, 0x1D, 0x68, 0x2A, 0x4B, 0x1C, 0x68, 0x2A, 0x4B, 0x19, 0x68, 0x2A, 0x4B, 0x1A, 0x68, -+0x2A, 0x4B, 0x00, 0x26, 0x1E, 0x70, 0x00, 0x23, 0x00, 0x2D, 0x05, 0xD0, 0x42, 0x33, 0xEB, 0x5C, 0x01, 0x3B, 0x5D, 0x42, -+0x6B, 0x41, 0xDB, 0xB2, 0x00, 0x2C, 0x03, 0xD0, 0x3A, 0x25, 0x64, 0x5D, 0x01, 0x2C, 0x23, 0xD0, 0x00, 0x24, 0x00, 0x29, -+0x04, 0xD0, 0x3E, 0x34, 0x0D, 0x5D, 0x00, 0x24, 0x01, 0x2D, 0x1D, 0xD0, 0x00, 0x2A, 0x03, 0xD0, 0x2F, 0x21, 0x51, 0x5C, -+0x01, 0x29, 0x1A, 0xD0, 0x00, 0x2B, 0x1D, 0xD0, 0x1A, 0x49, 0x0B, 0x68, 0x1A, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0x9B, 0x03, -+0x13, 0x43, 0x0B, 0x60, 0x18, 0x4B, 0x19, 0x4A, 0x13, 0x60, 0x81, 0x22, 0x52, 0x00, 0x9B, 0x5C, 0x00, 0x2B, 0x18, 0xD0, -+0x4F, 0x23, 0x01, 0x22, 0xC2, 0x54, 0x70, 0xBD, 0x01, 0x23, 0xD9, 0xE7, 0x8C, 0x62, 0x01, 0x34, 0xDE, 0xE7, 0x00, 0x21, -+0x91, 0x62, 0x00, 0x2B, 0xE2, 0xD1, 0x01, 0xE0, 0x00, 0x2C, 0xE7, 0xD0, 0x0A, 0x49, 0x0B, 0x68, 0x0D, 0x4A, 0x1A, 0x40, -+0x80, 0x23, 0x1B, 0x04, 0x13, 0x43, 0x0B, 0x60, 0xDE, 0xE7, 0xFF, 0xF7, 0x17, 0xFF, 0xE6, 0xE7, 0x24, 0x27, 0x16, 0x00, -+0x18, 0x27, 0x16, 0x00, 0x28, 0x27, 0x16, 0x00, 0x20, 0x27, 0x16, 0x00, 0xB1, 0xE6, 0x10, 0x00, 0x00, 0x04, 0x60, 0x40, -+0xFF, 0xFF, 0xDF, 0xFF, 0x80, 0x2A, 0x16, 0x00, 0x0C, 0xE7, 0x10, 0x00, 0xFF, 0xFF, 0x7F, 0xFF, 0x02, 0x4B, 0x1B, 0x68, -+0x04, 0x20, 0x18, 0x40, 0x70, 0x47, 0xC0, 0x46, 0x80, 0x40, 0x34, 0x40, 0x10, 0xB5, 0x04, 0x00, 0x01, 0x00, 0x12, 0x48, -+0x82, 0xF7, 0x98, 0xF8, 0x00, 0x2C, 0x1E, 0xD0, 0x10, 0x4B, 0x1A, 0x68, 0x10, 0x48, 0x02, 0x40, 0xD0, 0x21, 0x89, 0x03, -+0x0A, 0x43, 0x1A, 0x60, 0x1C, 0x68, 0x04, 0x40, 0xA0, 0x22, 0x52, 0x03, 0x22, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x02, 0x40, -+0x11, 0x43, 0x19, 0x60, 0x09, 0x49, 0x04, 0x22, 0x0B, 0x68, 0x1A, 0x42, 0xFC, 0xD0, 0x05, 0x49, 0x0B, 0x68, 0x05, 0x4A, -+0x1A, 0x40, 0x80, 0x23, 0x9B, 0x03, 0x13, 0x43, 0x0B, 0x60, 0x10, 0xBD, 0x90, 0xD0, 0x10, 0x00, 0x58, 0x40, 0x34, 0x40, -+0xFF, 0xFF, 0xC1, 0xFF, 0x80, 0x40, 0x34, 0x40, 0xF8, 0xB5, 0x04, 0x00, 0x83, 0x7D, 0x02, 0x33, 0x83, 0x75, 0x03, 0x6C, -+0x03, 0x61, 0xB2, 0xF7, 0xF9, 0xFC, 0x00, 0x28, 0x24, 0xD1, 0x20, 0x4E, 0x4C, 0x25, 0x20, 0x4F, 0x20, 0x00, 0xD4, 0xF7, -+0x19, 0xFA, 0x00, 0x28, 0x33, 0xD0, 0x31, 0x00, 0x20, 0x69, 0xD6, 0xF7, 0xFD, 0xF9, 0x63, 0x68, 0x9C, 0x46, 0x60, 0x44, -+0x00, 0x01, 0x00, 0x09, 0x60, 0x60, 0x63, 0x5B, 0x5B, 0x00, 0xE2, 0x68, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x01, 0x1B, 0x09, -+0xE3, 0x60, 0xA3, 0x7D, 0x14, 0x4A, 0x52, 0x78, 0x9B, 0x18, 0xA3, 0x75, 0x10, 0x4B, 0x9C, 0x46, 0x66, 0x44, 0xBE, 0x42, -+0xDE, 0xD1, 0xF8, 0xBD, 0x63, 0x68, 0x18, 0x33, 0x1B, 0x01, 0x1B, 0x09, 0x63, 0x60, 0x18, 0x26, 0x65, 0x68, 0x00, 0x22, -+0x21, 0x69, 0x20, 0x00, 0xFF, 0xF7, 0x3C, 0xFA, 0x63, 0x68, 0xAB, 0x42, 0xCB, 0xD0, 0x75, 0x19, 0x2D, 0x01, 0x2D, 0x09, -+0x65, 0x60, 0x18, 0x36, 0x90, 0x2E, 0xEF, 0xD1, 0xC3, 0xE7, 0x4E, 0x23, 0x00, 0x22, 0xE2, 0x54, 0xE3, 0xE7, 0xC0, 0x46, -+0xE2, 0x04, 0x00, 0x00, 0x6A, 0x18, 0x00, 0x00, 0x7C, 0x91, 0x0D, 0x00, 0x10, 0xB5, 0xFF, 0xF7, 0xAB, 0xFF, 0x10, 0xBD, -+0xF8, 0xB5, 0x04, 0x00, 0x4E, 0x23, 0xC3, 0x5C, 0x00, 0x2B, 0x00, 0xD0, 0xF8, 0xBD, 0x00, 0x21, 0xD4, 0xF7, 0x6E, 0xFB, -+0xA9, 0xF7, 0x38, 0xFB, 0x23, 0x6C, 0x23, 0x61, 0x60, 0x60, 0x04, 0x26, 0x4C, 0x27, 0x10, 0x4D, 0x20, 0x00, 0xD4, 0xF7, -+0xBF, 0xF9, 0x00, 0x28, 0x15, 0xD0, 0x63, 0x68, 0x04, 0x33, 0x1B, 0x01, 0x1B, 0x09, 0x63, 0x60, 0xE3, 0x5B, 0x5B, 0x00, -+0xE2, 0x68, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x01, 0x1B, 0x09, 0xE3, 0x60, 0xA3, 0x7D, 0x6A, 0x78, 0x9B, 0x18, 0xA3, 0x75, -+0x01, 0x3E, 0xF6, 0xB2, 0x00, 0x2E, 0xE5, 0xD1, 0xD8, 0xE7, 0x4E, 0x23, 0x00, 0x22, 0xE2, 0x54, 0xD4, 0xE7, 0xC0, 0x46, -+0x7C, 0x91, 0x0D, 0x00, 0x70, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0x01, 0x22, 0x14, 0x00, 0x1C, 0x40, 0x1A, 0x42, 0x1C, 0xD1, -+0x72, 0xB6, 0x10, 0x4B, 0x18, 0x68, 0x00, 0x28, 0x07, 0xD0, 0x4E, 0x23, 0xC3, 0x5C, 0x00, 0x2B, 0x05, 0xD0, 0x01, 0x2B, -+0x0D, 0xD0, 0x00, 0x2C, 0x00, 0xD1, 0x62, 0xB6, 0x70, 0xBD, 0x00, 0x21, 0xD4, 0xF7, 0x2A, 0xFB, 0x07, 0x4D, 0x28, 0x68, -+0x80, 0xF7, 0x38, 0xF8, 0x00, 0x23, 0x2B, 0x60, 0xF1, 0xE7, 0x4E, 0x23, 0x02, 0x22, 0xC2, 0x54, 0xED, 0xE7, 0x02, 0x4B, -+0x18, 0x68, 0x00, 0x28, 0xE3, 0xD1, 0xEB, 0xE7, 0xF8, 0xE6, 0x10, 0x00, 0xF8, 0xB5, 0x05, 0x00, 0x36, 0x4B, 0x1B, 0x68, -+0x0C, 0x20, 0x00, 0x2B, 0x00, 0xD0, 0xF8, 0xBD, 0x00, 0x21, 0x48, 0x30, 0x7F, 0xF7, 0x7A, 0xFF, 0x31, 0x4B, 0x18, 0x60, -+0x00, 0x28, 0x56, 0xD0, 0xA9, 0xF7, 0xD2, 0xFA, 0x06, 0x00, 0x00, 0x27, 0x2E, 0x4B, 0x1F, 0x60, 0x2E, 0x4B, 0x1F, 0x60, -+0x2B, 0x4B, 0x1C, 0x68, 0x54, 0x22, 0x00, 0x21, 0x20, 0x00, 0x7D, 0xF7, 0x19, 0xFF, 0x2B, 0x68, 0xA3, 0x62, 0x6A, 0x68, -+0x22, 0x63, 0xEA, 0x68, 0xE2, 0x63, 0x2A, 0x68, 0xE2, 0x62, 0xAA, 0x68, 0xA2, 0x63, 0x62, 0x63, 0x1B, 0x01, 0x4C, 0x22, -+0xA3, 0x52, 0x24, 0x4A, 0x22, 0x64, 0x24, 0x4B, 0x63, 0x62, 0x24, 0x4B, 0xE3, 0x61, 0x24, 0x4B, 0x23, 0x62, 0x03, 0x23, -+0x23, 0x76, 0x23, 0x4B, 0x9B, 0x78, 0x02, 0x33, 0xA3, 0x75, 0x22, 0x61, 0xE7, 0x75, 0x05, 0x23, 0x63, 0x76, 0xEF, 0xF3, -+0x10, 0x83, 0x01, 0x22, 0x15, 0x00, 0x1D, 0x40, 0x1A, 0x42, 0x00, 0xD1, 0x72, 0xB6, 0x66, 0x60, 0x00, 0x23, 0xA3, 0x60, -+0x1A, 0x4B, 0xA3, 0x82, 0x4C, 0x23, 0xE0, 0x5A, 0x40, 0x00, 0x80, 0x19, 0x00, 0x01, 0x00, 0x09, 0xE0, 0x60, 0x20, 0x00, -+0xD4, 0xF7, 0x1E, 0xF9, 0x00, 0x28, 0x06, 0xD1, 0x4E, 0x23, 0x00, 0x22, 0xE2, 0x54, 0x00, 0x2D, 0xA9, 0xD1, 0x62, 0xB6, -+0xA7, 0xE7, 0x11, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x0C, 0x20, 0xF3, 0xE7, 0x0D, 0x4B, -+0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x0C, 0x20, 0x97, 0xE7, 0xC0, 0x46, 0xF8, 0xE6, 0x10, 0x00, -+0x58, 0xE6, 0x10, 0x00, 0x5C, 0xE6, 0x10, 0x00, 0xE8, 0xFD, 0x00, 0x00, 0xB9, 0x21, 0x10, 0x00, 0xC9, 0x1F, 0x10, 0x00, -+0x05, 0x4B, 0x10, 0x00, 0x7C, 0x91, 0x0D, 0x00, 0x00, 0xA0, 0xFF, 0xFF, 0x28, 0x19, 0x16, 0x00, 0x10, 0xB5, 0x06, 0x4B, -+0x18, 0x68, 0x00, 0x28, 0x03, 0xD0, 0x4F, 0x23, 0xC3, 0x5C, 0x01, 0x2B, 0x00, 0xD0, 0x10, 0xBD, 0xFF, 0xF7, 0x84, 0xFD, -+0xFB, 0xE7, 0xC0, 0x46, 0xF8, 0xE6, 0x10, 0x00, 0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x85, 0xF7, 0x55, 0xFE, 0x4C, 0x4B, -+0x1B, 0x68, 0x01, 0x2B, 0x02, 0xD0, 0x4A, 0x4B, 0x02, 0x22, 0x1A, 0x60, 0x49, 0x4A, 0x48, 0x4B, 0x19, 0x68, 0x49, 0x4B, -+0xD1, 0x54, 0x00, 0x21, 0x42, 0x3B, 0xD1, 0x54, 0x0B, 0x23, 0x47, 0x48, 0x13, 0x54, 0x01, 0x30, 0x13, 0x54, 0x46, 0x4B, -+0x1B, 0x68, 0x1C, 0x0A, 0x50, 0x38, 0x14, 0x54, 0x44, 0x48, 0x13, 0x54, 0x44, 0x4B, 0x20, 0x20, 0xD0, 0x54, 0x44, 0x4B, -+0x10, 0x38, 0xD0, 0x54, 0x43, 0x4B, 0x19, 0x60, 0x00, 0x24, 0x00, 0x23, 0x98, 0x46, 0x00, 0x27, 0x01, 0x34, 0xE4, 0xB2, -+0x01, 0x2C, 0x0B, 0xD0, 0x02, 0x2C, 0x3E, 0xD0, 0x03, 0x2C, 0x4C, 0xD0, 0x3D, 0x4A, 0x13, 0x78, 0x20, 0x21, 0x8B, 0x43, -+0x13, 0x70, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0x0C, 0x20, 0xFE, 0xF7, 0xA7, 0xF9, 0x06, 0x00, 0x0D, 0x20, 0xFE, 0xF7, -+0xA3, 0xF9, 0x05, 0x04, 0x2D, 0x0C, 0x2A, 0x00, 0x31, 0x00, 0x35, 0x48, 0x81, 0xF7, 0xDA, 0xFE, 0x2B, 0x00, 0x33, 0x43, -+0xDE, 0xD0, 0x43, 0x46, 0x00, 0x2B, 0x41, 0xD0, 0x27, 0x4B, 0x2A, 0x0A, 0x1A, 0x70, 0x5D, 0x70, 0x32, 0x0E, 0x9A, 0x70, -+0x32, 0x0C, 0xDA, 0x70, 0x32, 0x0A, 0x1A, 0x71, 0x5E, 0x71, 0x00, 0x2F, 0x0A, 0xD0, 0x21, 0x4A, 0x11, 0x1D, 0x13, 0x78, -+0x01, 0x33, 0xDB, 0xB2, 0x13, 0x70, 0x00, 0x2B, 0x02, 0xD1, 0x01, 0x32, 0x8A, 0x42, 0xF6, 0xD1, 0x1B, 0x4C, 0x20, 0x68, -+0x61, 0x68, 0xA9, 0xF7, 0xD1, 0xFC, 0x20, 0x00, 0xB9, 0xF7, 0x0E, 0xFB, 0xC2, 0xE7, 0x07, 0x20, 0xFE, 0xF7, 0x72, 0xF9, -+0x06, 0x00, 0x08, 0x20, 0xFE, 0xF7, 0x6E, 0xF9, 0x05, 0x04, 0x2D, 0x0C, 0x2A, 0x00, 0x31, 0x00, 0x1B, 0x48, 0x81, 0xF7, -+0xA5, 0xFE, 0x01, 0x27, 0xC8, 0xE7, 0x1A, 0x4B, 0x1E, 0x88, 0x58, 0x88, 0x00, 0x04, 0x06, 0x43, 0x18, 0x4B, 0x1D, 0x88, -+0x5B, 0x88, 0x2A, 0x00, 0x31, 0x00, 0x17, 0x48, 0x81, 0xF7, 0x96, 0xFE, 0x01, 0x23, 0x98, 0x46, 0x00, 0x27, 0xB7, 0xE7, -+0x06, 0x4B, 0x2A, 0x0A, 0x5A, 0x71, 0x1D, 0x71, 0x32, 0x0E, 0xDA, 0x70, 0x32, 0x0C, 0x9A, 0x70, 0x32, 0x0A, 0x5A, 0x70, -+0x1E, 0x70, 0xBC, 0xE7, 0xA8, 0xE5, 0x10, 0x00, 0x7C, 0x1E, 0x16, 0x00, 0x9A, 0x02, 0x00, 0x00, 0xA3, 0x02, 0x00, 0x00, -+0xB0, 0xE5, 0x10, 0x00, 0x55, 0x02, 0x00, 0x00, 0x56, 0x02, 0x00, 0x00, 0x57, 0x02, 0x00, 0x00, 0xF8, 0xE6, 0x10, 0x00, -+0xEC, 0xE1, 0x10, 0x00, 0xA0, 0xD0, 0x10, 0x00, 0xB0, 0xD0, 0x10, 0x00, 0x12, 0xC0, 0x1F, 0x08, 0x16, 0xC0, 0x1F, 0x08, -+0xC4, 0xD0, 0x10, 0x00, 0x30, 0xB5, 0x89, 0xB0, 0x05, 0x00, 0x14, 0x00, 0x00, 0x28, 0x14, 0xD1, 0x1F, 0x4B, 0x20, 0x48, -+0x1A, 0x5C, 0x04, 0x35, 0xAA, 0x43, 0x1A, 0x54, 0x02, 0x30, 0x1A, 0x5C, 0x3E, 0x35, 0xAA, 0x43, 0x1A, 0x54, 0x22, 0x00, -+0x00, 0x20, 0x8D, 0xF7, 0xF9, 0xFF, 0x1A, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x0E, 0xD0, 0x09, 0xB0, 0x30, 0xBD, 0x8D, 0xF7, -+0xF1, 0xFF, 0x02, 0x2D, 0xF5, 0xD1, 0x23, 0x78, 0x0C, 0x22, 0x93, 0x43, 0x23, 0x70, 0x63, 0x78, 0x0B, 0x3A, 0x93, 0x43, -+0x63, 0x70, 0xEC, 0xE7, 0x11, 0x4B, 0x1B, 0x68, 0x01, 0x2B, 0xEC, 0xD8, 0x00, 0x23, 0x07, 0x93, 0x0F, 0x4B, 0x1B, 0x68, -+0x03, 0x93, 0x0F, 0x4B, 0x1B, 0x68, 0x01, 0x93, 0x04, 0x93, 0x0E, 0x4B, 0x18, 0x68, 0x0E, 0x49, 0xD5, 0xF7, 0xD4, 0xFF, -+0x05, 0x90, 0x0D, 0x4B, 0x18, 0x68, 0x0B, 0x49, 0xD5, 0xF7, 0xCE, 0xFF, 0x06, 0x90, 0x03, 0xA8, 0xFF, 0xF7, 0x6C, 0xFE, -+0xD3, 0xE7, 0xC0, 0x46, 0x7C, 0x1E, 0x16, 0x00, 0x9E, 0x02, 0x00, 0x00, 0xF8, 0xE6, 0x10, 0x00, 0x50, 0xE0, 0x10, 0x00, -+0x0C, 0xE2, 0x10, 0x00, 0x10, 0xE2, 0x10, 0x00, 0x04, 0xE2, 0x10, 0x00, 0x71, 0x02, 0x00, 0x00, 0x08, 0xE2, 0x10, 0x00, -+0x80, 0x00, 0x08, 0x4B, 0xC3, 0x58, 0x88, 0x22, 0xFF, 0x32, 0x9A, 0x5C, 0x00, 0x20, 0x01, 0x2A, 0x00, 0xD0, 0x70, 0x47, -+0x8A, 0x22, 0xFF, 0x32, 0x98, 0x5C, 0x01, 0x38, 0x43, 0x42, 0x58, 0x41, 0xF7, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, -+0x00, 0x23, 0x00, 0x20, 0x06, 0x49, 0x02, 0xE0, 0x01, 0x33, 0x07, 0x2B, 0x06, 0xD0, 0x9A, 0x00, 0x52, 0x58, 0x00, 0x2A, -+0xF8, 0xD0, 0x01, 0x30, 0xC0, 0xB2, 0xF5, 0xE7, 0x70, 0x47, 0xC0, 0x46, 0x38, 0x27, 0x16, 0x00, 0x70, 0xB5, 0x82, 0xB0, -+0x14, 0x00, 0x15, 0x0A, 0xAA, 0x00, 0x30, 0x4B, 0xD6, 0x58, 0x20, 0x00, 0x80, 0xF7, 0xB2, 0xF8, 0x03, 0x00, 0x02, 0x00, -+0x01, 0x28, 0x12, 0xD0, 0x00, 0x20, 0x01, 0x2B, 0x05, 0xD9, 0x19, 0x2B, 0x05, 0xD8, 0x15, 0x23, 0x93, 0x42, 0x40, 0x41, -+0x40, 0x00, 0x02, 0xB0, 0x70, 0xBD, 0x58, 0x3B, 0xDB, 0xB2, 0x01, 0x20, 0x98, 0x42, 0x80, 0x41, 0x40, 0x42, 0x40, 0x00, -+0xF5, 0xE7, 0x4C, 0x23, 0xF3, 0x5C, 0x00, 0x2B, 0x3A, 0xD1, 0x4B, 0x33, 0xF3, 0x5C, 0x00, 0x2B, 0x02, 0xD0, 0x4B, 0x23, -+0x00, 0x22, 0xF2, 0x54, 0x4F, 0x23, 0xF3, 0x5C, 0x00, 0x2B, 0x16, 0xD1, 0x36, 0x33, 0xF2, 0x5C, 0x35, 0x3B, 0x13, 0x40, -+0x3E, 0x22, 0x13, 0x43, 0x6A, 0x46, 0x13, 0x71, 0x00, 0x23, 0x53, 0x71, 0xE8, 0xB2, 0x01, 0xA9, 0xA7, 0xF7, 0x98, 0xF9, -+0x14, 0x48, 0x81, 0xF7, 0xA9, 0xFD, 0x59, 0x21, 0x20, 0x00, 0x80, 0xF7, 0x17, 0xF8, 0x00, 0x20, 0xCF, 0xE7, 0x01, 0xA9, -+0x36, 0x23, 0xF2, 0x5C, 0x38, 0x3B, 0x13, 0x43, 0x0B, 0x70, 0x1F, 0x23, 0x4B, 0x70, 0x1E, 0x3B, 0x8B, 0x70, 0xE8, 0xB2, -+0xA7, 0xF7, 0x82, 0xF9, 0x0A, 0x48, 0x81, 0xF7, 0x93, 0xFD, 0x20, 0x00, 0x97, 0xF7, 0x72, 0xFD, 0x58, 0x21, 0x20, 0x00, -+0x7F, 0xF7, 0xFE, 0xFF, 0x00, 0x20, 0xB6, 0xE7, 0x05, 0x48, 0x81, 0xF7, 0x87, 0xFD, 0x00, 0x20, 0xB1, 0xE7, 0xC0, 0x46, -+0x64, 0xA2, 0x16, 0x00, 0xDC, 0xD0, 0x10, 0x00, 0xEC, 0xD0, 0x10, 0x00, 0xFC, 0xD0, 0x10, 0x00, 0xF0, 0xB5, 0x05, 0xAC, -+0x24, 0x78, 0x4E, 0x28, 0x3C, 0xD8, 0xFF, 0x2C, 0x08, 0xD0, 0x10, 0x2C, 0x0B, 0xD9, 0x18, 0x2C, 0x37, 0xD9, 0x20, 0x2C, -+0x38, 0xD9, 0x03, 0x26, 0x00, 0x25, 0x06, 0xE0, 0x32, 0x4C, 0x24, 0x18, 0xED, 0x34, 0x24, 0x78, 0xF1, 0xE7, 0x00, 0x26, -+0x03, 0x25, 0x00, 0x29, 0x36, 0xD0, 0x2E, 0x4F, 0x39, 0x18, 0x0E, 0x00, 0x4F, 0x36, 0x33, 0x70, 0x3E, 0x56, 0xF3, 0x18, -+0x5B, 0x10, 0x3B, 0x54, 0x0B, 0x00, 0xED, 0x33, 0x1C, 0x70, 0x0E, 0x00, 0x9E, 0x36, 0x33, 0x78, 0x1C, 0x19, 0x64, 0x10, -+0x34, 0x70, 0x8C, 0x31, 0xFF, 0x31, 0x00, 0x23, 0x0B, 0x70, 0x24, 0x4B, 0x1B, 0x18, 0x49, 0x33, 0xFF, 0x33, 0x1B, 0x78, -+0xED, 0x18, 0x6D, 0xB2, 0x06, 0x2D, 0x10, 0xDC, 0x1F, 0x4B, 0x1B, 0x18, 0x49, 0x33, 0xFF, 0x33, 0x1D, 0x70, 0x02, 0x30, -+0x80, 0x00, 0x1C, 0x4B, 0x18, 0x18, 0x42, 0x60, 0xF0, 0xBD, 0x01, 0x26, 0x02, 0x25, 0xD0, 0xE7, 0x02, 0x26, 0x01, 0x25, -+0xCD, 0xE7, 0x17, 0x4B, 0x1B, 0x18, 0x49, 0x33, 0xFF, 0x33, 0x06, 0x21, 0x19, 0x70, 0xEC, 0xE7, 0x12, 0x4B, 0x1B, 0x18, -+0x8C, 0x33, 0xFF, 0x33, 0x1B, 0x78, 0x01, 0x2B, 0x14, 0xD0, 0x0F, 0x49, 0x09, 0x18, 0x8C, 0x31, 0xFF, 0x31, 0x01, 0x23, -+0x0B, 0x70, 0x0D, 0x49, 0x09, 0x18, 0x49, 0x31, 0xFF, 0x31, 0x0B, 0x78, 0x9B, 0x1B, 0x5B, 0xB2, 0x99, 0x1D, 0x08, 0xDB, -+0x08, 0x49, 0x09, 0x18, 0x49, 0x31, 0xFF, 0x31, 0x0B, 0x70, 0xD0, 0xE7, 0x02, 0x36, 0xF6, 0xB2, 0xE7, 0xE7, 0x04, 0x4B, -+0x1B, 0x18, 0x49, 0x33, 0xFF, 0x33, 0xFA, 0x21, 0x19, 0x70, 0xC6, 0xE7, 0x1C, 0xE7, 0x10, 0x00, 0x20, 0xA3, 0x16, 0x00, -+0xF8, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x8B, 0x4C, 0x00, 0x25, 0x00, 0x22, 0x01, 0x26, -+0xC1, 0x27, 0xFF, 0x00, 0x03, 0xE0, 0x01, 0x35, 0x09, 0x34, 0x07, 0x2D, 0x0E, 0xD0, 0x23, 0x78, 0x03, 0x2B, 0xF8, 0xD1, -+0x63, 0x78, 0x00, 0x2B, 0xF5, 0xD1, 0x29, 0x02, 0x31, 0x43, 0x89, 0xB2, 0x00, 0x22, 0x38, 0x00, 0x7F, 0xF7, 0x20, 0xFC, -+0x01, 0x22, 0xEC, 0xE7, 0x00, 0x2A, 0x0B, 0xD1, 0x7E, 0x4A, 0xD9, 0x23, 0x5B, 0x00, 0x00, 0x21, 0xD1, 0x54, 0x00, 0x20, -+0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF8, 0xBD, 0xA8, 0xF7, 0xFE, 0xFF, 0x82, 0x46, 0x8E, 0xF7, -+0x09, 0xF8, 0x80, 0x46, 0xA9, 0xF7, 0x18, 0xFB, 0x81, 0x46, 0x00, 0x24, 0x73, 0x4B, 0x9B, 0x46, 0x63, 0xE0, 0x8D, 0xF7, -+0xF3, 0xFF, 0x00, 0x28, 0x19, 0xD0, 0xA3, 0x00, 0x4A, 0x46, 0xD3, 0x58, 0x52, 0x46, 0xD3, 0x1A, 0x1B, 0x01, 0x1B, 0x09, -+0xC8, 0x22, 0x92, 0x01, 0x93, 0x42, 0x3D, 0xD2, 0x4B, 0x46, 0x3D, 0x33, 0xFF, 0x33, 0x1B, 0x57, 0x01, 0x33, 0x2D, 0xDB, -+0xD4, 0x20, 0x40, 0x00, 0x66, 0x4B, 0x5B, 0x19, 0x01, 0x21, 0xB1, 0x40, 0x1A, 0x5C, 0x0A, 0x43, 0x1A, 0x54, 0x2A, 0x00, -+0x63, 0x32, 0xFF, 0x32, 0x5A, 0x44, 0x00, 0x21, 0x06, 0x20, 0x38, 0x40, 0x03, 0x27, 0x13, 0x78, 0x03, 0x41, 0x3B, 0x40, -+0x03, 0x2B, 0x27, 0xD0, 0x01, 0x31, 0x0A, 0x32, 0x07, 0x29, 0xF6, 0xD1, 0xB3, 0x1E, 0x01, 0x2B, 0x00, 0xD8, 0x98, 0xE0, -+0x73, 0x1F, 0x01, 0x2B, 0x00, 0xD8, 0x94, 0xE0, 0xA3, 0x00, 0x4A, 0x46, 0xD3, 0x58, 0x52, 0x46, 0xD3, 0x1A, 0x1B, 0x01, -+0x1B, 0x09, 0xFA, 0x22, 0x12, 0x02, 0x93, 0x42, 0x1E, 0xD9, 0x93, 0xE0, 0xD4, 0x21, 0x49, 0x00, 0x4F, 0x4B, 0x5D, 0x19, -+0x01, 0x22, 0xB2, 0x40, 0x6B, 0x5C, 0x93, 0x43, 0x6B, 0x54, 0x13, 0xE0, 0x4B, 0x46, 0x3D, 0x33, 0xFF, 0x33, 0x00, 0x22, -+0x1A, 0x55, 0xCA, 0xE7, 0xD4, 0x20, 0x40, 0x00, 0x47, 0x4B, 0x9C, 0x46, 0xAC, 0x44, 0x01, 0x22, 0xB2, 0x40, 0x63, 0x46, -+0x1B, 0x5C, 0x93, 0x43, 0x62, 0x46, 0x13, 0x54, 0x07, 0x29, 0xCD, 0xD0, 0x01, 0x34, 0x4F, 0x2C, 0x13, 0xD0, 0xE7, 0xB2, -+0x07, 0x26, 0x26, 0x40, 0x65, 0x05, 0x2D, 0x0E, 0x43, 0x46, 0x5B, 0x5D, 0x33, 0x41, 0xDB, 0x07, 0x91, 0xD4, 0xD4, 0x21, -+0x49, 0x00, 0x3A, 0x4B, 0x5D, 0x19, 0x01, 0x22, 0xB2, 0x40, 0x6B, 0x5C, 0x93, 0x43, 0x6B, 0x54, 0xE8, 0xE7, 0x37, 0x48, -+0x81, 0xF7, 0xB0, 0xFC, 0x13, 0x28, 0x41, 0xD8, 0x14, 0x23, 0x1B, 0x1A, 0xDB, 0xB2, 0x9B, 0x46, 0x14, 0x25, 0x2D, 0x1A, -+0x00, 0x23, 0x99, 0x46, 0x00, 0x24, 0x2F, 0x4E, 0x0E, 0xE0, 0x48, 0x46, 0x13, 0x28, 0x09, 0xD9, 0x2C, 0x48, 0x84, 0x46, -+0x62, 0x44, 0x01, 0x20, 0x98, 0x40, 0x01, 0x43, 0xD4, 0x23, 0x5B, 0x00, 0xD1, 0x54, 0x01, 0x34, 0xAC, 0x42, 0x27, 0xDA, -+0xD6, 0xF7, 0xDA, 0xFA, 0x7F, 0x23, 0x18, 0x40, 0x4E, 0x28, 0x00, 0xD9, 0x4F, 0x38, 0xC2, 0x08, 0xB1, 0x18, 0xD4, 0x23, -+0x5B, 0x00, 0xC9, 0x5C, 0xA2, 0x3B, 0xFF, 0x3B, 0x03, 0x40, 0x0F, 0x00, 0x1F, 0x41, 0xFF, 0x07, 0xEA, 0xD4, 0x47, 0x46, -+0xBF, 0x5C, 0x1F, 0x41, 0xFF, 0x07, 0xE5, 0xD5, 0x4F, 0x46, 0x01, 0x37, 0xFF, 0xB2, 0xB9, 0x46, 0x1A, 0x4F, 0xBC, 0x46, -+0x60, 0x44, 0x9E, 0x30, 0x00, 0x78, 0x18, 0x28, 0xD0, 0xD9, 0xCB, 0x45, 0xCB, 0xD8, 0x20, 0x28, 0xCC, 0xD9, 0xC8, 0xE7, -+0x13, 0x48, 0x81, 0xF7, 0x69, 0xFC, 0x01, 0x00, 0x13, 0x48, 0x81, 0xF7, 0x01, 0xFC, 0xC8, 0x22, 0x00, 0x21, 0x12, 0x48, -+0x7F, 0xF7, 0x38, 0xFA, 0x1F, 0xE7, 0xA3, 0x00, 0x4A, 0x46, 0xD3, 0x58, 0x52, 0x46, 0xD3, 0x1A, 0x1B, 0x01, 0x1B, 0x09, -+0xFA, 0x22, 0xD2, 0x01, 0x93, 0x42, 0x89, 0xD9, 0xD4, 0x21, 0x49, 0x00, 0x05, 0x4B, 0x9C, 0x46, 0x65, 0x44, 0x01, 0x22, -+0xB2, 0x40, 0x6B, 0x5C, 0x13, 0x43, 0x6B, 0x54, 0x7E, 0xE7, 0xC0, 0x46, 0xA4, 0x9E, 0x16, 0x00, 0x68, 0x9E, 0x16, 0x00, -+0x10, 0xA0, 0x16, 0x00, 0x1C, 0xE7, 0x10, 0x00, 0x0C, 0xD1, 0x10, 0x00, 0x0A, 0x05, 0x00, 0x00, 0xF0, 0xB5, 0xDE, 0x46, -+0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x87, 0xB0, 0x07, 0x00, 0x08, 0x00, 0x00, 0x91, 0xBA, 0x00, 0xA4, 0x4B, -+0xD5, 0x58, 0xA6, 0x23, 0xEB, 0x5C, 0x9B, 0x46, 0x2B, 0x6D, 0x98, 0x46, 0x62, 0x23, 0x7B, 0x43, 0xA0, 0x4A, 0x9A, 0x18, -+0x16, 0x88, 0xA0, 0x4A, 0x9A, 0x18, 0x14, 0x88, 0x36, 0x04, 0x26, 0x43, 0x9E, 0x4A, 0x9A, 0x18, 0x12, 0x88, 0x92, 0x05, -+0x92, 0x0D, 0x91, 0x46, 0x9C, 0x4A, 0x9A, 0x18, 0x14, 0x88, 0x9C, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x88, 0x24, 0x04, -+0x1C, 0x19, 0x9A, 0x4B, 0x98, 0x45, 0x1A, 0xD8, 0x73, 0x1A, 0x19, 0x01, 0x09, 0x09, 0x80, 0x22, 0x12, 0x05, 0x91, 0x42, -+0x4A, 0xD9, 0x83, 0x1B, 0x1B, 0x01, 0x1B, 0x09, 0x5B, 0x42, 0xA1, 0x22, 0xAA, 0x5C, 0x00, 0x2A, 0x49, 0xD0, 0x00, 0x2B, -+0x09, 0xDB, 0x89, 0x08, 0x00, 0x29, 0x06, 0xDD, 0x89, 0x00, 0x00, 0x9B, 0x9C, 0x46, 0x61, 0x44, 0x09, 0x01, 0x0B, 0x09, -+0x00, 0x93, 0xA4, 0x1B, 0x00, 0x9B, 0x9C, 0x46, 0x64, 0x44, 0x24, 0x01, 0x24, 0x09, 0xF4, 0x26, 0x76, 0x00, 0x4B, 0x46, -+0xF6, 0x1A, 0x3B, 0xD4, 0xAC, 0x67, 0x82, 0x23, 0xEE, 0x52, 0x62, 0x42, 0x7F, 0x3B, 0x13, 0x40, 0xA6, 0x22, 0xAB, 0x54, -+0x72, 0x3A, 0x2A, 0x65, 0x01, 0x96, 0xAE, 0x60, 0x42, 0x46, 0x34, 0x2A, 0x09, 0xD9, 0xEA, 0x7D, 0x00, 0x2A, 0x06, 0xD0, -+0xC8, 0x22, 0x52, 0x00, 0xB2, 0x42, 0x92, 0x41, 0x52, 0x42, 0x05, 0x32, 0xEA, 0x75, 0x5B, 0x45, 0x00, 0xD1, 0x9F, 0xE0, -+0xA1, 0x23, 0xEB, 0x5C, 0x03, 0x2B, 0x21, 0xD0, 0x3B, 0x02, 0x01, 0x22, 0x13, 0x43, 0x02, 0x93, 0x01, 0x23, 0x98, 0x46, -+0xFE, 0x33, 0x9A, 0x46, 0xA9, 0x46, 0x45, 0x46, 0xA0, 0x46, 0x4D, 0xE0, 0x1B, 0x01, 0x1B, 0x09, 0xA1, 0x22, 0xAA, 0x5C, -+0x00, 0x2A, 0xB8, 0xD0, 0xB5, 0xE7, 0x00, 0x2B, 0xB5, 0xDA, 0x6C, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, -+0x98, 0x47, 0xB8, 0xE7, 0x69, 0x4E, 0xF6, 0x1A, 0x01, 0x34, 0x24, 0x01, 0x24, 0x09, 0xBD, 0xE7, 0xC1, 0x33, 0x99, 0x46, -+0xEB, 0x58, 0x6A, 0x6F, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x1B, 0x1B, 0x01, 0x1B, 0x09, 0x4A, 0x46, 0xAB, 0x50, 0x3B, 0x02, -+0x01, 0x21, 0x19, 0x43, 0x02, 0x23, 0x3B, 0x32, 0x5F, 0x48, 0x7F, 0xF7, 0x2B, 0xFA, 0x80, 0x46, 0x4B, 0x46, 0xEB, 0x58, -+0x5B, 0x08, 0x99, 0x46, 0xCC, 0x23, 0xEB, 0x5A, 0x9A, 0x46, 0x00, 0x2B, 0x05, 0xD1, 0x57, 0x4B, 0x9B, 0x6E, 0x00, 0x22, -+0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x51, 0x46, 0x48, 0x46, 0xD5, 0xF7, 0x47, 0xFD, 0x43, 0x46, 0x19, 0x80, 0x40, 0x46, -+0x7F, 0xF7, 0x3C, 0xFA, 0xB0, 0xE7, 0x21, 0x00, 0x03, 0x98, 0xD5, 0xF7, 0x3D, 0xFD, 0x04, 0x9B, 0x59, 0x80, 0x18, 0x00, -+0x7F, 0xF7, 0x32, 0xFA, 0x01, 0x3D, 0x3F, 0xD3, 0x53, 0x46, 0x2B, 0x40, 0x9B, 0x00, 0x4B, 0x4A, 0x9C, 0x58, 0x00, 0x2C, -+0xF6, 0xD0, 0x46, 0x23, 0xE3, 0x5C, 0xBB, 0x42, 0xF2, 0xD1, 0x63, 0x6B, 0x42, 0x46, 0x9B, 0x1A, 0x1B, 0x01, 0x1B, 0x09, -+0x63, 0x63, 0x4A, 0x46, 0x52, 0x6F, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x01, 0x1B, 0x09, 0x63, 0x63, 0x63, 0x68, 0x42, 0x46, -+0x9B, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x63, 0x60, 0x4A, 0x46, 0x52, 0x6F, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x01, 0x1B, 0x09, -+0x63, 0x60, 0x01, 0x9B, 0xA3, 0x60, 0x04, 0x23, 0x52, 0x46, 0x02, 0x99, 0x38, 0x48, 0x7F, 0xF7, 0xD9, 0xF9, 0x04, 0x90, -+0x47, 0x23, 0xE3, 0x5C, 0x03, 0x70, 0x63, 0x6B, 0x5B, 0x08, 0x03, 0x93, 0x42, 0x23, 0xE4, 0x5C, 0x00, 0x2C, 0xBC, 0xD1, -+0x2D, 0x4B, 0x9B, 0x6E, 0x05, 0x93, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xB4, 0xE7, 0x44, 0x46, 0x4D, 0x46, -+0x6C, 0x67, 0x84, 0x23, 0xEE, 0x52, 0x1D, 0x33, 0xEB, 0x5C, 0x04, 0x2B, 0x0D, 0xD0, 0xA6, 0x23, 0xE8, 0x5C, 0x5B, 0x46, -+0xC0, 0x1A, 0x43, 0x1E, 0x98, 0x41, 0xC0, 0xB2, 0x07, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, -+0xF0, 0xBD, 0x7C, 0x33, 0xEB, 0x5A, 0x9E, 0x1B, 0xF3, 0x17, 0xF6, 0x18, 0x5E, 0x40, 0x33, 0xB2, 0x9D, 0x22, 0x52, 0x00, -+0x93, 0x42, 0x02, 0xDB, 0x1D, 0x4B, 0x9B, 0x1B, 0x1B, 0xB2, 0x03, 0x2B, 0xE1, 0xDD, 0xE8, 0x23, 0xEB, 0x58, 0x1A, 0x68, -+0x00, 0x9B, 0xA8, 0x6F, 0x84, 0x46, 0x63, 0x44, 0x19, 0x00, 0xD3, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x80, 0x20, 0x00, 0x05, -+0x83, 0x42, 0xD2, 0xD8, 0x09, 0x01, 0x09, 0x09, 0x51, 0x1A, 0x09, 0x01, 0x09, 0x09, 0x64, 0x29, 0xCB, 0xDD, 0x3F, 0x02, -+0x01, 0x21, 0x39, 0x43, 0xFF, 0x22, 0x0F, 0x48, 0x7F, 0xF7, 0xC2, 0xF9, 0xC3, 0xE7, 0xC0, 0x46, 0x38, 0x27, 0x16, 0x00, -+0x4C, 0x65, 0x61, 0x40, 0x4A, 0x65, 0x61, 0x40, 0x4E, 0x65, 0x61, 0x40, 0xFC, 0x64, 0x61, 0x40, 0xFA, 0x64, 0x61, 0x40, -+0xE1, 0x04, 0x00, 0x00, 0x28, 0x19, 0x16, 0x00, 0x59, 0x04, 0x00, 0x00, 0x33, 0x06, 0x00, 0x00, 0x54, 0x27, 0x16, 0x00, -+0x34, 0x06, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x2E, 0x06, 0x00, 0x00, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, -+0x45, 0x46, 0xE0, 0xB5, 0x89, 0xB0, 0x03, 0x90, 0x89, 0x46, 0x81, 0x00, 0xC9, 0x4B, 0xCF, 0x58, 0x53, 0x1E, 0xDB, 0xB2, -+0x9B, 0x46, 0x00, 0x2A, 0x00, 0xD1, 0x26, 0xE1, 0x03, 0x02, 0x01, 0x22, 0x13, 0x43, 0x07, 0x93, 0xC4, 0x4B, 0x98, 0x46, -+0x9A, 0x46, 0x5C, 0x46, 0x83, 0xE0, 0x6B, 0x46, 0x10, 0x21, 0x5B, 0x5E, 0x00, 0x2B, 0x06, 0xDB, 0xA7, 0x21, 0x79, 0x5C, -+0x77, 0x29, 0x02, 0xD8, 0x01, 0x31, 0xA7, 0x20, 0x39, 0x54, 0xE9, 0x06, 0x00, 0xD5, 0xD7, 0xE0, 0xA4, 0x21, 0x29, 0x42, -+0x5B, 0xD1, 0x29, 0x07, 0x54, 0xD4, 0x00, 0x2B, 0x00, 0xDA, 0xCF, 0xE0, 0xA7, 0x23, 0xFB, 0x5C, 0x77, 0x2B, 0x02, 0xD8, -+0xA7, 0x23, 0x02, 0x21, 0xF9, 0x54, 0x0F, 0x23, 0x1A, 0x40, 0x03, 0x25, 0x05, 0x9B, 0x1D, 0x40, 0x03, 0x2A, 0x01, 0xD0, -+0x08, 0x2A, 0x02, 0xD1, 0x03, 0x2D, 0x00, 0xD1, 0xCE, 0xE0, 0xEC, 0x23, 0xFB, 0x58, 0x00, 0x2B, 0x00, 0xD0, 0xB7, 0xE0, -+0x6B, 0x1E, 0x01, 0x2B, 0x00, 0xD9, 0xB3, 0xE0, 0x05, 0x9B, 0xDE, 0x04, 0xB6, 0x0D, 0x00, 0xD1, 0xAE, 0xE0, 0x04, 0x23, -+0xFF, 0x22, 0x07, 0x99, 0xA5, 0x48, 0x7F, 0xF7, 0x0B, 0xF9, 0xA5, 0x4A, 0xD5, 0x23, 0x5B, 0x00, 0xD2, 0x5C, 0xD3, 0x00, -+0x9B, 0x1A, 0x5B, 0x00, 0xA2, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x88, 0x03, 0x80, 0x43, 0x88, 0x9B, 0x0A, 0x9B, 0x02, -+0x33, 0x43, 0x9F, 0x4E, 0x33, 0x40, 0x2D, 0x03, 0x1D, 0x43, 0xAA, 0x04, 0x92, 0x0C, 0x06, 0x9B, 0x59, 0x42, 0x4B, 0x41, -+0x9B, 0x03, 0x13, 0x43, 0x43, 0x80, 0x7F, 0xF7, 0x17, 0xF9, 0x96, 0x4A, 0xD5, 0x23, 0x5B, 0x00, 0xD2, 0x5C, 0xD3, 0x00, -+0x9B, 0x1A, 0x5B, 0x00, 0x93, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x00, 0x22, 0x1A, 0x80, 0x7D, 0xE0, 0xFF, 0x22, 0x07, 0x99, -+0x91, 0x48, 0x7F, 0xF7, 0x1B, 0xF9, 0xA8, 0xF7, 0x3F, 0xFA, 0x90, 0x4B, 0x1D, 0x68, 0x58, 0x46, 0x43, 0x46, 0xDB, 0x69, -+0x98, 0x47, 0x03, 0x00, 0x2D, 0x0A, 0xED, 0xB2, 0x00, 0x95, 0x4A, 0x46, 0x00, 0x21, 0x02, 0x98, 0xFF, 0xF7, 0x52, 0xFC, -+0x01, 0x3C, 0xE4, 0xB2, 0xFF, 0x2C, 0x00, 0xD1, 0x99, 0xE0, 0x03, 0x98, 0xA8, 0xF7, 0x54, 0xFA, 0x00, 0x28, 0x00, 0xD1, -+0x93, 0xE0, 0xD5, 0x23, 0x5B, 0x00, 0x7E, 0x4A, 0xD2, 0x5C, 0xD3, 0x00, 0x9B, 0x1A, 0x5B, 0x00, 0x80, 0x4A, 0x9A, 0x18, -+0x15, 0x88, 0xAD, 0xB2, 0x7F, 0x4A, 0x9A, 0x18, 0x16, 0x88, 0xB6, 0xB2, 0x7E, 0x4A, 0x9A, 0x18, 0x12, 0x88, 0x92, 0xB2, -+0x05, 0x92, 0x7D, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x88, 0x9A, 0xB2, 0x04, 0x92, 0xDA, 0xB2, 0x93, 0x46, 0x5B, 0x04, -+0x5B, 0x0E, 0x02, 0x93, 0x4B, 0x46, 0xFA, 0x6E, 0x9B, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0xC8, 0x2B, 0x0A, 0xD9, 0xA7, 0x23, -+0xFB, 0x5C, 0x77, 0x2B, 0x06, 0xD8, 0xA1, 0x22, 0xBA, 0x5C, 0x00, 0x2A, 0x02, 0xD1, 0x01, 0x33, 0xA7, 0x32, 0xBB, 0x54, -+0xEB, 0x07, 0xB0, 0xD4, 0x07, 0x23, 0x1A, 0x00, 0x32, 0x40, 0x06, 0x92, 0x4A, 0x46, 0xFA, 0x66, 0x33, 0x42, 0x0B, 0xD0, -+0x5F, 0x4B, 0xDB, 0x69, 0x58, 0x46, 0x98, 0x47, 0x98, 0x22, 0xBB, 0x5A, 0x1B, 0x18, 0xBB, 0x52, 0x02, 0x32, 0xBB, 0x5C, -+0x01, 0x33, 0xBB, 0x54, 0xAB, 0x07, 0x9A, 0xD4, 0x4B, 0x46, 0x3B, 0x67, 0x6B, 0x06, 0x02, 0xD5, 0x06, 0x9B, 0x00, 0x2B, -+0x0C, 0xD1, 0xF6, 0x10, 0xF2, 0xB2, 0x0E, 0x23, 0x1E, 0x42, 0x00, 0xD0, 0x1F, 0xE7, 0x99, 0x33, 0xFB, 0x5C, 0x00, 0x2B, -+0x02, 0xD0, 0x01, 0x3B, 0xA7, 0x22, 0xBB, 0x54, 0xA8, 0xF7, 0xC6, 0xF9, 0x53, 0x4B, 0x1D, 0x68, 0x58, 0x46, 0x53, 0x46, -+0xDB, 0x69, 0x98, 0x47, 0x03, 0x00, 0x2D, 0x0A, 0xED, 0xB2, 0x00, 0x95, 0x4A, 0x46, 0x01, 0x21, 0x02, 0x98, 0xFF, 0xF7, -+0xD9, 0xFB, 0x85, 0xE7, 0x47, 0x4A, 0xD5, 0x23, 0x5B, 0x00, 0xD2, 0x5C, 0xD3, 0x00, 0x9B, 0x1A, 0x5B, 0x00, 0x4D, 0x4A, -+0x94, 0x46, 0x63, 0x44, 0x19, 0x88, 0x8B, 0xB2, 0x04, 0x93, 0x05, 0x9A, 0xD5, 0x04, 0xAD, 0x0D, 0x6B, 0x1C, 0xFF, 0x22, -+0x07, 0x99, 0x48, 0x48, 0x7F, 0xF7, 0x3A, 0xF8, 0x06, 0x00, 0x05, 0x70, 0x04, 0x9B, 0x46, 0x4A, 0x94, 0x46, 0x63, 0x44, -+0x19, 0x00, 0x01, 0x30, 0x2A, 0x00, 0xD5, 0xF7, 0x27, 0xFF, 0x30, 0x00, 0x7F, 0xF7, 0x56, 0xF8, 0xC8, 0xE7, 0x62, 0x24, -+0x03, 0x9B, 0x5C, 0x43, 0x3F, 0x4B, 0x9C, 0x46, 0x64, 0x44, 0x23, 0x88, 0x80, 0x22, 0x93, 0x43, 0x23, 0x80, 0x89, 0xF7, -+0x59, 0xF9, 0x00, 0x28, 0x18, 0xD0, 0x2F, 0x4B, 0x1B, 0x88, 0x9B, 0xB2, 0x00, 0x2B, 0x13, 0xD1, 0x38, 0x4B, 0x1B, 0x88, -+0x9B, 0xB2, 0x00, 0x2B, 0x0E, 0xD1, 0x37, 0x4B, 0x1B, 0x88, 0x9B, 0xB2, 0x00, 0x2B, 0x09, 0xD1, 0x35, 0x4B, 0x1B, 0x88, -+0x9B, 0xB2, 0x00, 0x2B, 0x04, 0xD1, 0x23, 0x88, 0x80, 0x22, 0x93, 0x43, 0x13, 0x43, 0x23, 0x80, 0x9A, 0x23, 0xFB, 0x5C, -+0x96, 0x2B, 0x03, 0xD9, 0xEC, 0x23, 0xFB, 0x58, 0x00, 0x2B, 0x06, 0xD0, 0x09, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, -+0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0xAC, 0x33, 0xFB, 0x5C, 0x00, 0x2B, 0xF4, 0xD0, 0x9B, 0x23, 0x00, 0x22, 0xFA, 0x54, -+0x26, 0x4A, 0x27, 0x4B, 0xD3, 0x5C, 0x5B, 0x07, 0x03, 0xD5, 0x26, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0x05, 0xD1, 0x00, 0x23, -+0x9A, 0x22, 0xBB, 0x54, 0x02, 0x3A, 0xBB, 0x52, 0xE2, 0xE7, 0x03, 0x9B, 0x19, 0x02, 0x01, 0x23, 0x19, 0x43, 0xFF, 0x22, -+0x1F, 0x48, 0x7F, 0xF7, 0x17, 0xF8, 0x98, 0x23, 0xF8, 0x5E, 0x9A, 0x23, 0xF9, 0x5C, 0xD5, 0xF7, 0x05, 0xFB, 0x06, 0x4A, -+0x2F, 0x23, 0xD3, 0x5C, 0xC0, 0x1A, 0x9B, 0x23, 0xF8, 0x54, 0x17, 0x4A, 0x13, 0x78, 0x01, 0x3B, 0x13, 0x70, 0xE0, 0xE7, -+0x38, 0x27, 0x16, 0x00, 0x60, 0x92, 0x16, 0x00, 0x29, 0x06, 0x00, 0x00, 0x20, 0xA3, 0x16, 0x00, 0x9A, 0x69, 0x61, 0x40, -+0xFF, 0xCF, 0xFF, 0xFF, 0x2A, 0x06, 0x00, 0x00, 0x0C, 0x01, 0x60, 0x40, 0x92, 0x69, 0x61, 0x40, 0x94, 0x69, 0x61, 0x40, -+0x96, 0x69, 0x61, 0x40, 0x98, 0x69, 0x61, 0x40, 0x9C, 0x69, 0x61, 0x40, 0x27, 0x06, 0x00, 0x00, 0x00, 0x00, 0x61, 0x40, -+0x0E, 0x65, 0x61, 0x40, 0xA8, 0x69, 0x61, 0x40, 0xB6, 0x69, 0x61, 0x40, 0xC4, 0x69, 0x61, 0x40, 0x7C, 0x1E, 0x16, 0x00, -+0x9D, 0x02, 0x00, 0x00, 0x24, 0xE6, 0x10, 0x00, 0x2F, 0x06, 0x00, 0x00, 0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x04, 0x00, -+0x88, 0x46, 0x16, 0x00, 0xFF, 0xF7, 0x84, 0xFA, 0x00, 0x28, 0x3F, 0xD1, 0x22, 0x4D, 0x23, 0x4F, 0xEB, 0x5D, 0x04, 0x22, -+0x93, 0x43, 0xEB, 0x55, 0x32, 0x00, 0x41, 0x46, 0x20, 0x00, 0xFF, 0xF7, 0x1F, 0xFE, 0xEB, 0x5D, 0x04, 0x22, 0x13, 0x43, -+0xEB, 0x55, 0xA4, 0x00, 0x1C, 0x4B, 0xE4, 0x58, 0xA7, 0x23, 0xE3, 0x5C, 0x04, 0x2B, 0x02, 0xD9, 0xA7, 0x23, 0x04, 0x22, -+0xE2, 0x54, 0xFE, 0xF7, 0x49, 0xFB, 0x00, 0x28, 0x02, 0xD1, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0xB1, 0xF7, 0x04, 0xFD, -+0x00, 0x28, 0xF8, 0xD1, 0x9F, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x0A, 0xD1, 0xA7, 0x33, 0xE3, 0x5C, 0x00, 0x2B, 0x06, 0xD1, -+0xAA, 0x33, 0xE3, 0x5C, 0x00, 0x2B, 0x02, 0xD0, 0xA7, 0x23, 0x01, 0x22, 0xE2, 0x54, 0xA8, 0x23, 0xE3, 0x5C, 0x00, 0x2B, -+0x03, 0xD1, 0x62, 0x68, 0x09, 0x4B, 0x1A, 0x60, 0xE1, 0xE7, 0xA8, 0xF7, 0x81, 0xFB, 0x08, 0x4B, 0x18, 0x60, 0xF6, 0xE7, -+0x32, 0x00, 0x41, 0x46, 0x20, 0x00, 0xFF, 0xF7, 0xE5, 0xFD, 0xC8, 0xE7, 0x7C, 0x1E, 0x16, 0x00, 0x9D, 0x02, 0x00, 0x00, -+0x38, 0x27, 0x16, 0x00, 0x28, 0xE6, 0x10, 0x00, 0x2C, 0xE6, 0x10, 0x00, 0x03, 0x4B, 0x04, 0x4A, 0x1A, 0x60, 0x04, 0x4B, -+0x04, 0x4A, 0x1A, 0x60, 0x70, 0x47, 0xC0, 0x46, 0x04, 0x30, 0x34, 0x40, 0xC1, 0x00, 0xA0, 0x00, 0x0C, 0x00, 0x58, 0x40, -+0x14, 0x00, 0x7F, 0x30, 0x01, 0x4B, 0x02, 0x4A, 0x1A, 0x60, 0x70, 0x47, 0x04, 0x30, 0x34, 0x40, 0xC0, 0x00, 0xA0, 0x00, -+0x10, 0xB5, 0x30, 0x4B, 0x1B, 0x78, 0x01, 0x2B, 0x09, 0xD0, 0x01, 0x28, 0x08, 0xD0, 0x02, 0x28, 0x47, 0xD0, 0x2D, 0x4B, -+0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x10, 0xBD, 0xA8, 0xF7, 0x44, 0xFB, 0x27, 0x4B, 0x5B, 0x78, -+0x00, 0x2B, 0x11, 0xD1, 0x25, 0x4B, 0x01, 0x22, 0x5A, 0x70, 0x58, 0x60, 0x9B, 0x78, 0x01, 0x2B, 0xF1, 0xD0, 0xFE, 0xF7, -+0xA7, 0xFA, 0x00, 0x28, 0xED, 0xD1, 0xFE, 0xF7, 0xC1, 0xFA, 0x00, 0x28, 0xE9, 0xD1, 0xFF, 0xF7, 0xC1, 0xFF, 0xE6, 0xE7, -+0x1C, 0x4A, 0x53, 0x68, 0xC3, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x92, 0x78, 0x00, 0x2A, 0x0B, 0xD1, 0x23, 0x2B, 0xDC, 0xD9, -+0x17, 0x4B, 0x01, 0x32, 0x9A, 0x70, 0x00, 0x22, 0x5A, 0x70, 0x58, 0x60, 0x16, 0x4B, 0x17, 0x4A, 0x1A, 0x60, 0xD2, 0xE7, -+0x01, 0x2A, 0xD0, 0xD1, 0x3B, 0x2B, 0xCE, 0xD9, 0x10, 0x4B, 0x00, 0x22, 0x9A, 0x70, 0x01, 0x32, 0x5A, 0x70, 0x58, 0x60, -+0xFE, 0xF7, 0x7E, 0xFA, 0x00, 0x28, 0xC4, 0xD1, 0xFE, 0xF7, 0x98, 0xFA, 0x00, 0x28, 0xC0, 0xD1, 0xFF, 0xF7, 0x98, 0xFF, -+0xBD, 0xE7, 0x08, 0x4B, 0x5B, 0x78, 0x01, 0x2B, 0x01, 0xD0, 0x00, 0x29, 0xB7, 0xD0, 0x05, 0x4B, 0x00, 0x22, 0x5A, 0x70, -+0x9A, 0x70, 0x01, 0x3A, 0x5A, 0x60, 0x04, 0x4B, 0x04, 0x4A, 0x1A, 0x60, 0xAD, 0xE7, 0xC0, 0x46, 0xDC, 0xE6, 0x10, 0x00, -+0x28, 0x19, 0x16, 0x00, 0x04, 0x30, 0x34, 0x40, 0xC0, 0x00, 0xA0, 0x00, 0xF0, 0xB5, 0x80, 0x00, 0x26, 0x4B, 0xC3, 0x58, -+0xAB, 0x20, 0x18, 0x5C, 0x00, 0x28, 0x27, 0xD0, 0x0D, 0x1C, 0xAA, 0x20, 0x80, 0x00, 0x81, 0x42, 0x01, 0xD3, 0x22, 0x49, -+0x0D, 0x1C, 0xAD, 0xB2, 0x9D, 0x21, 0x5F, 0x5C, 0x00, 0x23, 0x00, 0x24, 0x01, 0x26, 0x02, 0xE0, 0x01, 0x33, 0x07, 0x2B, -+0x0C, 0xD0, 0xD8, 0xB2, 0x39, 0x00, 0x19, 0x41, 0x0E, 0x42, 0xF7, 0xD0, 0x59, 0x00, 0x1A, 0x4C, 0x61, 0x5A, 0xA9, 0x42, -+0x01, 0xD2, 0x04, 0x00, 0xF0, 0xE7, 0x04, 0x00, 0x17, 0x4B, 0x18, 0x5D, 0x64, 0x00, 0x15, 0x4B, 0xE3, 0x5A, 0xAB, 0x42, -+0x00, 0xD9, 0x2B, 0x00, 0x13, 0x80, 0xF0, 0xBD, 0x9C, 0x20, 0x1F, 0x5C, 0x00, 0x23, 0x00, 0x25, 0x01, 0x26, 0x02, 0xE0, -+0x01, 0x33, 0x06, 0x2B, 0x0C, 0xD0, 0xDC, 0xB2, 0x38, 0x00, 0x18, 0x41, 0x06, 0x42, 0xF7, 0xD0, 0x58, 0x00, 0x0C, 0x4D, -+0x28, 0x5A, 0x88, 0x42, 0x01, 0xD2, 0x25, 0x00, 0xF0, 0xE7, 0x25, 0x00, 0x09, 0x4B, 0x58, 0x5D, 0x6D, 0x00, 0x07, 0x4B, -+0xEB, 0x5A, 0x8B, 0x42, 0x00, 0xD9, 0x0B, 0x00, 0x13, 0x80, 0xDE, 0xE7, 0x38, 0x27, 0x16, 0x00, 0xA7, 0x02, 0x00, 0x00, -+0x40, 0xC9, 0x0D, 0x00, 0x50, 0xC9, 0x0D, 0x00, 0x2C, 0xC9, 0x0D, 0x00, 0x38, 0xC9, 0x0D, 0x00, 0xF0, 0xB5, 0xDE, 0x46, -+0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x85, 0xB0, 0x00, 0x90, 0x88, 0x46, 0x82, 0x00, 0x95, 0x4B, 0xD4, 0x58, -+0xAF, 0x23, 0xE3, 0x5C, 0x01, 0x2B, 0x00, 0xD9, 0x0D, 0xE1, 0x03, 0x02, 0x01, 0x27, 0x1F, 0x43, 0x88, 0x23, 0x99, 0x46, -+0xBB, 0x46, 0x2A, 0xE0, 0xAB, 0x00, 0x5D, 0x19, 0x6D, 0x00, 0x8E, 0x4B, 0xEA, 0x18, 0x13, 0x88, 0x78, 0x21, 0x8B, 0x43, -+0x60, 0x39, 0x0B, 0x43, 0x13, 0x80, 0x8B, 0x4B, 0xEA, 0x18, 0x83, 0x79, 0xDB, 0x00, 0x11, 0x39, 0x0B, 0x43, 0x13, 0x80, -+0x82, 0x88, 0x88, 0x4B, 0xEB, 0x18, 0x1A, 0x80, 0x87, 0x4B, 0x9C, 0x46, 0x65, 0x44, 0x2B, 0x88, 0x5B, 0x04, 0x5B, 0x0C, -+0x2B, 0x80, 0xAE, 0x22, 0xA3, 0x5C, 0x59, 0x42, 0x4B, 0x41, 0xA3, 0x54, 0x01, 0x32, 0xA3, 0x5C, 0x01, 0x33, 0xA3, 0x54, -+0xAF, 0x23, 0xE3, 0x5C, 0x01, 0x2B, 0x00, 0xD9, 0xDB, 0xE0, 0x9E, 0x23, 0xE5, 0x5C, 0x6D, 0x00, 0x10, 0x33, 0xE3, 0x5C, -+0xED, 0x18, 0xED, 0xB2, 0x20, 0x00, 0x40, 0x30, 0x81, 0xF7, 0x84, 0xFA, 0x00, 0x28, 0xC7, 0xD1, 0xEC, 0x23, 0xE3, 0x58, -+0x00, 0x2B, 0x39, 0xD0, 0x9A, 0x7A, 0x00, 0x2A, 0x36, 0xD1, 0xAC, 0x32, 0xA2, 0x5C, 0x00, 0x2A, 0x00, 0xD1, 0xC2, 0xE0, -+0x9A, 0x78, 0x05, 0x3A, 0x03, 0x2A, 0x00, 0xD8, 0xBD, 0xE0, 0x1A, 0x88, 0xA9, 0x00, 0x4D, 0x19, 0x6D, 0x00, 0x69, 0x49, -+0x68, 0x18, 0x01, 0x88, 0xDE, 0x79, 0x0F, 0x23, 0x33, 0x40, 0xDB, 0x00, 0x78, 0x26, 0xB1, 0x43, 0x0B, 0x43, 0x03, 0x80, -+0x64, 0x4B, 0xE9, 0x18, 0xD3, 0x00, 0x05, 0x22, 0x13, 0x43, 0x9B, 0xB2, 0x0B, 0x80, 0xEC, 0x23, 0xE3, 0x58, 0x1A, 0x89, -+0x62, 0x4B, 0xEB, 0x18, 0x1A, 0x80, 0x60, 0x4B, 0x9C, 0x46, 0x65, 0x44, 0x2B, 0x88, 0x5B, 0x04, 0x5B, 0x0C, 0x2B, 0x80, -+0xAE, 0x22, 0xA3, 0x5C, 0x59, 0x42, 0x4B, 0x41, 0xA3, 0x54, 0x01, 0x32, 0xA3, 0x5C, 0x01, 0x33, 0xA3, 0x54, 0xAF, 0xE7, -+0xAC, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x00, 0xD1, 0x8B, 0xE0, 0x96, 0x23, 0xE1, 0x5A, 0x01, 0x27, 0x00, 0x29, 0x39, 0xD0, -+0x02, 0xAB, 0x9A, 0x1D, 0x00, 0x98, 0xFF, 0xF7, 0x07, 0xFF, 0xAB, 0x00, 0x5D, 0x19, 0x6D, 0x00, 0x4B, 0x4B, 0xEA, 0x18, -+0x13, 0x88, 0x78, 0x21, 0x8B, 0x43, 0xC0, 0x00, 0x03, 0x43, 0x9B, 0xB2, 0x13, 0x80, 0x48, 0x4B, 0xEA, 0x18, 0x02, 0xAB, -+0xDB, 0x88, 0xDB, 0x00, 0x1F, 0x43, 0x04, 0x23, 0x1F, 0x43, 0xBF, 0xB2, 0x17, 0x80, 0x94, 0x22, 0xA1, 0x5A, 0x45, 0x4B, -+0xEB, 0x18, 0x19, 0x80, 0x42, 0x4B, 0x9C, 0x46, 0x65, 0x44, 0x2B, 0x88, 0x5B, 0x04, 0x5B, 0x0C, 0x2B, 0x80, 0x02, 0xAB, -+0xDB, 0x88, 0x96, 0x20, 0x21, 0x5A, 0xC9, 0x1A, 0x21, 0x52, 0xA1, 0x5A, 0x5B, 0x18, 0xA3, 0x52, 0x1A, 0x32, 0xA3, 0x5C, -+0x59, 0x42, 0x4B, 0x41, 0xA3, 0x54, 0x01, 0x32, 0xA3, 0x5C, 0x01, 0x33, 0xA3, 0x54, 0x6B, 0xE7, 0x27, 0x00, 0x48, 0x37, -+0x80, 0x23, 0x1B, 0x05, 0x9A, 0x46, 0x0F, 0xE0, 0x52, 0x00, 0x8A, 0x42, 0x1E, 0xDA, 0x01, 0x23, 0xFF, 0x22, 0x59, 0x46, -+0x31, 0x48, 0x7E, 0xF7, 0x7F, 0xFD, 0x01, 0x23, 0x03, 0x70, 0x7E, 0xF7, 0xA5, 0xFD, 0x30, 0x89, 0x88, 0xF7, 0x98, 0xFE, -+0x38, 0x00, 0x81, 0xF7, 0xE7, 0xF9, 0x06, 0x1E, 0x46, 0xD0, 0x4B, 0x46, 0xE2, 0x5A, 0x00, 0x2A, 0x08, 0xD0, 0x43, 0x68, -+0x59, 0x1C, 0x05, 0xD0, 0x41, 0x46, 0xCB, 0x1A, 0x19, 0x01, 0x09, 0x09, 0x51, 0x45, 0xDD, 0xD9, 0x73, 0x89, 0x9F, 0x04, -+0xBF, 0x0F, 0x9B, 0x05, 0x9B, 0x0D, 0x9A, 0x46, 0x90, 0x23, 0xE3, 0x58, 0x00, 0x2B, 0x2C, 0xD0, 0x8C, 0x23, 0xE3, 0x58, -+0x00, 0x2B, 0x06, 0xD0, 0x1D, 0x4B, 0x9B, 0x6E, 0x01, 0x93, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x8C, 0x23, -+0xE6, 0x50, 0x96, 0x23, 0x52, 0x46, 0xE2, 0x52, 0x32, 0x89, 0x02, 0x3B, 0xE2, 0x52, 0x01, 0x2F, 0x00, 0xD0, 0x02, 0x27, -+0x96, 0x23, 0xE1, 0x5A, 0x00, 0x29, 0x00, 0xD0, 0x78, 0xE7, 0xAF, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x06, 0xD0, 0xA8, 0x23, -+0xE3, 0x5C, 0x00, 0x2B, 0x02, 0xD1, 0xA8, 0x33, 0x01, 0x22, 0xE2, 0x54, 0x05, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, -+0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0x90, 0x33, 0xE6, 0x50, 0xDC, 0xE7, 0x01, 0x27, 0xE3, 0xE7, 0x38, 0x27, 0x16, 0x00, -+0xCA, 0x69, 0x61, 0x40, 0xCC, 0x69, 0x61, 0x40, 0xD0, 0x69, 0x61, 0x40, 0xC8, 0x69, 0x61, 0x40, 0xCE, 0x69, 0x61, 0x40, -+0x2B, 0x06, 0x00, 0x00, 0x28, 0x19, 0x16, 0x00, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, -+0x83, 0xB0, 0x82, 0x00, 0x4B, 0x4B, 0xD4, 0x58, 0x90, 0x23, 0xE2, 0x58, 0x00, 0x2A, 0x00, 0xD1, 0x84, 0xE0, 0x49, 0x4B, -+0x59, 0x88, 0x49, 0x4B, 0x1B, 0x78, 0x99, 0x42, 0x73, 0xD9, 0x9E, 0x23, 0xE3, 0x5C, 0x5B, 0x00, 0xAD, 0x21, 0x61, 0x5C, -+0x5B, 0x18, 0xDB, 0xB2, 0x56, 0x89, 0xB6, 0x05, 0xB2, 0x0D, 0x90, 0x46, 0x02, 0x22, 0x90, 0x26, 0x41, 0x49, 0x01, 0x91, -+0xAF, 0x21, 0x8A, 0x46, 0x01, 0x39, 0x89, 0x46, 0x10, 0x39, 0x8C, 0x46, 0x00, 0x90, 0x0C, 0xE0, 0x63, 0x46, 0xE5, 0x5C, -+0x6D, 0x00, 0xAD, 0x23, 0xE1, 0x5C, 0x4B, 0x42, 0x4B, 0x41, 0x5B, 0x19, 0xDB, 0xB2, 0x01, 0x3A, 0xD2, 0xB2, 0x00, 0x2A, -+0x31, 0xD0, 0x99, 0x00, 0xCB, 0x18, 0x5B, 0x00, 0x35, 0x49, 0x5F, 0x18, 0x39, 0x88, 0x89, 0xB2, 0xA5, 0x59, 0x2D, 0x89, -+0x8D, 0x42, 0xE7, 0xD8, 0x45, 0x44, 0xA9, 0x42, 0xE4, 0xDA, 0x31, 0x49, 0x5D, 0x18, 0x29, 0x88, 0x01, 0x98, 0x01, 0x40, -+0x29, 0x80, 0x2F, 0x49, 0x5D, 0x18, 0x29, 0x88, 0x49, 0x04, 0x49, 0x0C, 0x2D, 0x48, 0x01, 0x43, 0x89, 0xB2, 0x29, 0x80, -+0x2C, 0x49, 0x8B, 0x46, 0x5B, 0x44, 0x19, 0x88, 0x78, 0x20, 0x81, 0x43, 0x19, 0x80, 0x00, 0x23, 0x3B, 0x80, 0x53, 0x46, -+0xE3, 0x5C, 0x01, 0x3B, 0x51, 0x46, 0x63, 0x54, 0x4B, 0x46, 0xE3, 0x5C, 0x59, 0x42, 0x4B, 0x41, 0x49, 0x46, 0x63, 0x54, -+0xC0, 0xE7, 0x00, 0x98, 0x00, 0x02, 0x01, 0x25, 0x28, 0x43, 0x81, 0xB2, 0x01, 0x23, 0xFF, 0x32, 0x1F, 0x48, 0x7E, 0xF7, -+0xA5, 0xFC, 0x05, 0x70, 0x7E, 0xF7, 0xCC, 0xFC, 0x1D, 0x48, 0x80, 0xF7, 0xA3, 0xFD, 0x90, 0x23, 0xE3, 0x58, 0x18, 0x89, -+0x88, 0xF7, 0xBA, 0xFD, 0x8C, 0x23, 0xE3, 0x58, 0x00, 0x2B, 0x0B, 0xD0, 0x90, 0x22, 0xA3, 0x50, 0x8C, 0x23, 0x00, 0x22, -+0xE2, 0x50, 0x03, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0x96, 0x22, 0x00, 0x21, -+0xA1, 0x52, 0xEF, 0xE7, 0x8C, 0x23, 0xE3, 0x58, 0x00, 0x2B, 0xF0, 0xD0, 0x0E, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, -+0x00, 0x20, 0x98, 0x47, 0xE9, 0xE7, 0xC0, 0x46, 0x38, 0x27, 0x16, 0x00, 0x9C, 0xE5, 0x10, 0x00, 0xF8, 0xE1, 0x10, 0x00, -+0x07, 0xE0, 0xFF, 0xFF, 0xCE, 0x69, 0x61, 0x40, 0xCC, 0x69, 0x61, 0x40, 0xC8, 0x69, 0x61, 0x40, 0x00, 0x80, 0xFF, 0xFF, -+0xCA, 0x69, 0x61, 0x40, 0x2B, 0x06, 0x00, 0x00, 0x18, 0xD1, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, 0x03, 0x00, 0x00, 0x20, -+0x9A, 0x6C, 0x00, 0x2A, 0x00, 0xD0, 0x70, 0x47, 0xA7, 0x32, 0x9A, 0x5C, 0x00, 0x2A, 0xFA, 0xD1, 0xA8, 0x32, 0x98, 0x5C, -+0x43, 0x42, 0x58, 0x41, 0xC0, 0xB2, 0xF4, 0xE7, 0x04, 0x4B, 0x18, 0x68, 0x04, 0x4B, 0x1B, 0x68, 0x18, 0x43, 0x43, 0x1E, -+0x98, 0x41, 0xC0, 0xB2, 0x70, 0x47, 0xC0, 0x46, 0x24, 0x27, 0x16, 0x00, 0x18, 0x27, 0x16, 0x00, 0x70, 0xB5, 0x84, 0xB0, -+0x82, 0x00, 0x12, 0x4B, 0xD5, 0x58, 0x01, 0xA9, 0x11, 0x4C, 0x02, 0x01, 0x13, 0x1A, 0x9B, 0x00, 0xE3, 0x18, 0xDE, 0x88, -+0x4E, 0x80, 0x1E, 0x7B, 0x4E, 0x70, 0x1E, 0x89, 0xCE, 0x80, 0x5E, 0x89, 0x0E, 0x81, 0x9B, 0x88, 0x8B, 0x80, 0x12, 0x1A, -+0x92, 0x00, 0xA2, 0x18, 0x53, 0x7B, 0x01, 0x22, 0x53, 0x40, 0x36, 0x22, 0xAA, 0x5C, 0x5A, 0x40, 0x01, 0x23, 0x13, 0x40, -+0x2E, 0x22, 0x13, 0x43, 0x0B, 0x70, 0xA6, 0xF7, 0x0F, 0xF9, 0x04, 0xB0, 0x70, 0xBD, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, -+0xC0, 0xA0, 0x16, 0x00, 0xF8, 0xB5, 0x06, 0x00, 0x0C, 0x00, 0x05, 0x0A, 0xAA, 0x00, 0x18, 0x4B, 0xD7, 0x58, 0x36, 0x23, -+0xFB, 0x5C, 0x00, 0x2B, 0x0C, 0xD0, 0x2B, 0x01, 0x5B, 0x1B, 0x9B, 0x00, 0x14, 0x4A, 0xD3, 0x18, 0x5B, 0x7B, 0x00, 0x2B, -+0x08, 0xD1, 0x01, 0x21, 0x30, 0x00, 0x7E, 0xF7, 0x77, 0xFF, 0xF8, 0xBD, 0xE8, 0xB2, 0xB2, 0xF7, 0x73, 0xF9, 0xEE, 0xE7, -+0x08, 0x23, 0x14, 0x22, 0x00, 0x21, 0x0D, 0x48, 0x7E, 0xF7, 0xF6, 0xFB, 0x04, 0x70, 0x2B, 0x00, 0x80, 0x33, 0x43, 0x80, -+0x00, 0x23, 0xC3, 0x80, 0x3C, 0x33, 0xFB, 0x5C, 0x03, 0x71, 0xD0, 0xF7, 0x4B, 0xFA, 0x2B, 0x01, 0x5D, 0x1B, 0xAD, 0x00, -+0x03, 0x4B, 0x5D, 0x19, 0x00, 0x23, 0x6B, 0x73, 0xDD, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, 0xC0, 0xA0, 0x16, 0x00, -+0x03, 0x11, 0x00, 0x00, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x93, 0xB0, 0x05, 0x00, -+0x03, 0x91, 0x93, 0x46, 0x1E, 0x00, 0x1C, 0xAB, 0x1B, 0x88, 0x99, 0x46, 0x1D, 0xAB, 0x1B, 0x88, 0x9A, 0x46, 0x04, 0x0A, -+0xA2, 0x00, 0xCB, 0x4B, 0xD7, 0x58, 0x01, 0x00, 0xCA, 0x48, 0x7E, 0xF7, 0x7B, 0xFB, 0xB3, 0x1F, 0xC9, 0x4A, 0x9B, 0xB2, -+0x93, 0x42, 0x03, 0xD8, 0x5B, 0x46, 0x33, 0x43, 0xDB, 0x07, 0x0D, 0xD5, 0x39, 0x23, 0xFB, 0x5C, 0xE0, 0xB2, 0x12, 0x22, -+0x17, 0x21, 0xA6, 0xF7, 0xF6, 0xF8, 0x13, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, -+0x5E, 0x45, 0xEF, 0xD9, 0x4B, 0x46, 0x00, 0x2B, 0xEC, 0xD0, 0x73, 0x08, 0x4B, 0x45, 0xE9, 0xD3, 0x53, 0x46, 0x28, 0x2B, -+0xE6, 0xD8, 0x4B, 0x44, 0x5B, 0x00, 0xB3, 0x42, 0xE2, 0xD2, 0x28, 0x00, 0x7E, 0xF7, 0x70, 0xFF, 0x01, 0x28, 0x00, 0xD1, -+0x85, 0xE0, 0xB5, 0x4B, 0x22, 0x01, 0x11, 0x1B, 0x89, 0x00, 0xCE, 0x52, 0x5B, 0x18, 0x5E, 0x80, 0x4A, 0x46, 0x1A, 0x81, -+0x9E, 0x80, 0x5A, 0x46, 0xDA, 0x80, 0x52, 0x46, 0x5A, 0x81, 0x03, 0x9A, 0x1A, 0x73, 0x36, 0x23, 0xFB, 0x5C, 0x00, 0x22, -+0x04, 0x92, 0x01, 0x2B, 0x77, 0xD0, 0x0A, 0x96, 0x0B, 0x96, 0x36, 0x23, 0xF8, 0x5C, 0x4A, 0x46, 0x02, 0x2A, 0x00, 0xD9, -+0x02, 0x22, 0x90, 0x46, 0x80, 0x44, 0x0A, 0xAB, 0x42, 0x46, 0x0C, 0x92, 0x49, 0x46, 0x49, 0x00, 0x0D, 0x91, 0x00, 0x21, -+0x99, 0x74, 0x80, 0x31, 0x8C, 0x46, 0xA4, 0x44, 0x61, 0x46, 0x19, 0x82, 0x01, 0x21, 0x04, 0x9A, 0x11, 0x40, 0xD9, 0x74, -+0x06, 0xAB, 0x06, 0x96, 0x42, 0x46, 0x07, 0x92, 0x62, 0x46, 0x9A, 0x81, 0x00, 0x28, 0x5A, 0xD1, 0x58, 0x46, 0x08, 0x90, -+0x36, 0x23, 0xFB, 0x5C, 0x01, 0x2B, 0x5A, 0xD0, 0x08, 0x9B, 0x10, 0x93, 0x11, 0x93, 0x06, 0x9B, 0x0F, 0x93, 0x06, 0xA8, -+0xD4, 0xF7, 0x5A, 0xFA, 0x80, 0x46, 0x00, 0x28, 0x72, 0xD1, 0x0A, 0xAA, 0x10, 0x98, 0x23, 0x01, 0x1B, 0x1B, 0x9B, 0x00, -+0x8D, 0x49, 0xCB, 0x18, 0x98, 0x62, 0x0F, 0x99, 0x8C, 0x46, 0x59, 0x62, 0x0C, 0x99, 0xD9, 0x62, 0x0D, 0x99, 0x19, 0x63, -+0x12, 0x8A, 0x9A, 0x86, 0x00, 0x22, 0x9A, 0x63, 0x36, 0x33, 0x1A, 0x70, 0x36, 0x23, 0xFB, 0x5C, 0x00, 0x2B, 0x6B, 0xD1, -+0x80, 0xB2, 0x23, 0x01, 0x1B, 0x1B, 0x9B, 0x00, 0x81, 0x4A, 0xD3, 0x18, 0xD8, 0x80, 0x36, 0x23, 0xFB, 0x5C, 0x01, 0x2B, -+0x67, 0xD0, 0xD9, 0x23, 0x9B, 0x00, 0xFB, 0x18, 0x1A, 0x88, 0x7D, 0x4B, 0x9A, 0x42, 0x79, 0xD1, 0x43, 0x46, 0x01, 0x2B, -+0x00, 0xD1, 0xDF, 0xE0, 0x02, 0x2B, 0x00, 0xD1, 0xBC, 0xE0, 0x00, 0x2B, 0x00, 0xD1, 0xAE, 0xE0, 0x77, 0x4B, 0x9B, 0x6E, -+0x00, 0x22, 0x11, 0x00, 0x10, 0x00, 0x98, 0x47, 0x5D, 0xE7, 0x23, 0x01, 0x1B, 0x1B, 0x9B, 0x00, 0x70, 0x4A, 0xD3, 0x18, -+0x00, 0x22, 0x5A, 0x73, 0x71, 0xE7, 0xE0, 0xB2, 0xAF, 0xF7, 0xAE, 0xFE, 0x43, 0x08, 0x04, 0x93, 0x81, 0xE7, 0x04, 0x9A, -+0x31, 0x00, 0x58, 0x46, 0xA5, 0xF7, 0x2E, 0xFD, 0x9F, 0xE7, 0x06, 0x9B, 0x9B, 0x46, 0x01, 0x3B, 0x98, 0x46, 0x80, 0x44, -+0x5B, 0x46, 0x00, 0x2B, 0x05, 0xD1, 0x66, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x11, 0x00, 0x10, 0x00, 0x98, 0x47, 0x59, 0x46, -+0x40, 0x46, 0xD4, 0xF7, 0x1B, 0xFE, 0x08, 0x91, 0x0A, 0xAB, 0xDA, 0x7C, 0x01, 0x21, 0x4A, 0x40, 0xDA, 0x74, 0x0C, 0x9A, -+0x03, 0x32, 0x0C, 0x92, 0x0D, 0x9A, 0x03, 0x32, 0x0D, 0x92, 0x07, 0x9B, 0x05, 0x93, 0x03, 0x33, 0x07, 0x93, 0x81, 0xE7, -+0x28, 0x00, 0x7E, 0xF7, 0xAD, 0xFE, 0x80, 0x46, 0x01, 0x28, 0x02, 0xD0, 0x01, 0x23, 0x98, 0x46, 0x83, 0xE7, 0x0A, 0xA8, -+0xD4, 0xF7, 0x6A, 0xF9, 0x00, 0x28, 0x00, 0xD0, 0x7D, 0xE7, 0x02, 0x23, 0x98, 0x46, 0x7A, 0xE7, 0x63, 0x46, 0x99, 0xB2, -+0x80, 0xB2, 0x04, 0x9A, 0xA5, 0xF7, 0x0A, 0xFD, 0x8D, 0xE7, 0x43, 0x1C, 0x04, 0x93, 0x0F, 0x9B, 0x9B, 0x46, 0x00, 0x2B, -+0x05, 0xD1, 0x49, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x11, 0x00, 0x10, 0x00, 0x98, 0x47, 0x23, 0x01, 0x1B, 0x1B, 0x9B, 0x00, -+0x42, 0x4A, 0xD3, 0x18, 0x05, 0x93, 0x59, 0x46, 0x04, 0x98, 0xD4, 0xF7, 0xDB, 0xFD, 0x05, 0x9B, 0xD9, 0x80, 0x7E, 0xE7, -+0xE3, 0xB2, 0x9B, 0x46, 0x18, 0x00, 0x95, 0xF7, 0x71, 0xFF, 0x05, 0x90, 0x0F, 0x9B, 0x04, 0x93, 0x00, 0x28, 0x05, 0xD1, -+0x3A, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x11, 0x00, 0x10, 0x00, 0x98, 0x47, 0x05, 0x99, 0x04, 0x98, 0xD4, 0xF7, 0xC4, 0xFD, -+0x00, 0x29, 0x00, 0xD0, 0x6E, 0xE7, 0x3C, 0x22, 0x62, 0x43, 0x31, 0x4B, 0x9B, 0x18, 0xD9, 0x88, 0x11, 0x9B, 0x04, 0x93, -+0x10, 0x9B, 0x05, 0x93, 0x04, 0x9B, 0x05, 0x9A, 0x9A, 0x1A, 0x8A, 0x18, 0x92, 0xB2, 0x58, 0x46, 0x95, 0xF7, 0x9C, 0xFF, -+0x04, 0x90, 0x0F, 0x9B, 0x9B, 0x46, 0x00, 0x2B, 0x05, 0xD1, 0x29, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x11, 0x00, 0x10, 0x00, -+0x98, 0x47, 0x3C, 0x23, 0x63, 0x43, 0x23, 0x4A, 0xD3, 0x18, 0x05, 0x93, 0x59, 0x46, 0x04, 0x98, 0xD4, 0xF7, 0x9C, 0xFD, -+0x05, 0x9B, 0xD9, 0x80, 0x46, 0xE7, 0x39, 0x33, 0xFA, 0x5C, 0xE0, 0xB2, 0x17, 0x21, 0xA5, 0xF7, 0x87, 0xFF, 0x2F, 0x21, -+0x28, 0x00, 0x7E, 0xF7, 0xD5, 0xFD, 0xAA, 0xE6, 0x36, 0x23, 0xFB, 0x5C, 0x00, 0x2B, 0x0A, 0xD0, 0xE0, 0xB2, 0xFF, 0xF7, -+0x13, 0xFE, 0x28, 0x00, 0x96, 0xF7, 0x3A, 0xFB, 0x2E, 0x21, 0x28, 0x00, 0x7E, 0xF7, 0xC6, 0xFD, 0x9B, 0xE6, 0x3C, 0x22, -+0x62, 0x43, 0x10, 0x4B, 0x9B, 0x18, 0xD9, 0x88, 0xE0, 0xB2, 0x03, 0x9B, 0x9F, 0x07, 0xFF, 0x0F, 0x01, 0x97, 0x53, 0x46, -+0x00, 0x93, 0x4B, 0x46, 0x32, 0x00, 0xAF, 0xF7, 0x5F, 0xFC, 0xE3, 0xE7, 0x39, 0x23, 0xFB, 0x5C, 0xE0, 0xB2, 0x20, 0x22, -+0x17, 0x21, 0xA5, 0xF7, 0x7A, 0xFF, 0x20, 0x21, 0x28, 0x00, 0xFF, 0xF7, 0x1B, 0xFE, 0x7E, 0xE6, 0x64, 0xA2, 0x16, 0x00, -+0x05, 0x06, 0x00, 0x00, 0x3A, 0x05, 0x00, 0x00, 0xC0, 0xA0, 0x16, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x19, 0x16, 0x00, -+0xF0, 0xB5, 0xD6, 0x46, 0x4F, 0x46, 0x46, 0x46, 0xC0, 0xB5, 0x8A, 0xB0, 0x06, 0x00, 0x88, 0x46, 0x91, 0x46, 0x1D, 0x00, -+0x12, 0xAB, 0x1B, 0x88, 0x9C, 0x46, 0x04, 0x0A, 0xA2, 0x00, 0x9C, 0x4B, 0xD7, 0x58, 0x9C, 0x4B, 0x22, 0x01, 0x11, 0x1B, -+0x89, 0x00, 0x40, 0x46, 0xC8, 0x52, 0x5B, 0x18, 0x4A, 0x46, 0x5A, 0x80, 0x1D, 0x81, 0x62, 0x46, 0x5A, 0x81, 0x36, 0x23, -+0xFB, 0x5C, 0x00, 0x22, 0x92, 0x46, 0x01, 0x2B, 0x00, 0xD1, 0x87, 0xE0, 0x23, 0x01, 0x1B, 0x1B, 0x9B, 0x00, 0x91, 0x4A, -+0xD3, 0x18, 0x00, 0x22, 0x1A, 0x73, 0xA7, 0xF7, 0x29, 0xFE, 0x50, 0x44, 0x03, 0x01, 0x06, 0xD5, 0x23, 0x01, 0x1B, 0x1B, -+0x9B, 0x00, 0x8B, 0x4A, 0xD3, 0x18, 0x02, 0x22, 0x1A, 0x73, 0x02, 0xAB, 0x4A, 0x46, 0x02, 0x92, 0x42, 0x46, 0x5A, 0x60, -+0x2A, 0x00, 0x02, 0x2D, 0x00, 0xD9, 0x02, 0x22, 0x9A, 0x60, 0x6D, 0x00, 0x05, 0x95, 0x00, 0x23, 0x02, 0xAA, 0x93, 0x74, -+0x25, 0x00, 0x80, 0x35, 0x15, 0x82, 0x53, 0x46, 0x5B, 0x08, 0x9A, 0x46, 0x01, 0x23, 0x52, 0x46, 0x13, 0x40, 0x02, 0xAA, -+0xD3, 0x74, 0xD9, 0x23, 0x9B, 0x00, 0xFB, 0x18, 0x1A, 0x88, 0x7B, 0x4B, 0x9A, 0x42, 0x58, 0xD1, 0x36, 0x23, 0xFB, 0x5C, -+0x01, 0x2B, 0x6A, 0xD0, 0x02, 0xA8, 0xD4, 0xF7, 0x63, 0xF8, 0x00, 0x28, 0x00, 0xD0, 0x72, 0xE0, 0x08, 0x98, 0x22, 0x01, -+0x12, 0x1B, 0x92, 0x00, 0x71, 0x4B, 0x9B, 0x18, 0x98, 0x62, 0x07, 0x99, 0x59, 0x62, 0x04, 0x9A, 0xDA, 0x62, 0x05, 0x9A, -+0x00, 0x92, 0x1A, 0x63, 0x02, 0xAA, 0x12, 0x8A, 0x9A, 0x86, 0x00, 0x22, 0x9A, 0x63, 0x36, 0x33, 0x1A, 0x70, 0x36, 0x23, -+0xFB, 0x5C, 0x00, 0x2B, 0x6A, 0xD1, 0x80, 0xB2, 0x23, 0x01, 0x1B, 0x1B, 0x9B, 0x00, 0x65, 0x4A, 0xD3, 0x18, 0xD8, 0x80, -+0x07, 0x9D, 0x9D, 0x80, 0x36, 0x23, 0xFB, 0x5C, 0x01, 0x2B, 0x63, 0xD0, 0xD9, 0x23, 0x9B, 0x00, 0xFB, 0x18, 0x1A, 0x88, -+0x5F, 0x4B, 0x9A, 0x42, 0x00, 0xD0, 0x72, 0xE0, 0x23, 0x01, 0x1B, 0x1B, 0x9B, 0x00, 0x5B, 0x4A, 0xD3, 0x18, 0x01, 0x22, -+0x5A, 0x73, 0x36, 0x23, 0xFB, 0x5C, 0x00, 0x2B, 0x00, 0xD1, 0xA4, 0xE0, 0xE0, 0xB2, 0xFF, 0xF7, 0x43, 0xFD, 0x30, 0x00, -+0x96, 0xF7, 0x6A, 0xFA, 0x2E, 0x21, 0x30, 0x00, 0x7E, 0xF7, 0xF6, 0xFC, 0x0A, 0xB0, 0x1C, 0xBC, 0x90, 0x46, 0x99, 0x46, -+0xA2, 0x46, 0xF0, 0xBD, 0xE0, 0xB2, 0xAF, 0xF7, 0x1F, 0xFD, 0x82, 0x46, 0x72, 0xE7, 0xE0, 0xB2, 0x95, 0xF7, 0x40, 0xFE, -+0x02, 0x00, 0x03, 0x00, 0x02, 0x98, 0x82, 0x42, 0x07, 0xD2, 0x00, 0x92, 0x11, 0x00, 0xD4, 0xF7, 0x13, 0xFC, 0x43, 0x1C, -+0x00, 0x9A, 0x5A, 0x43, 0x93, 0xB2, 0x03, 0x9A, 0x93, 0x42, 0x93, 0xD8, 0x02, 0x93, 0x03, 0x93, 0x90, 0xE7, 0x02, 0xAB, -+0xDB, 0x7C, 0x01, 0x22, 0x53, 0x40, 0x02, 0xAA, 0xD3, 0x74, 0x04, 0x9B, 0x03, 0x33, 0x04, 0x93, 0x05, 0x9B, 0x00, 0x93, -+0x03, 0x33, 0x05, 0x93, 0x86, 0xE7, 0x08, 0x23, 0x14, 0x22, 0x00, 0x21, 0x3A, 0x48, 0x7E, 0xF7, 0x4B, 0xF9, 0x20, 0x23, -+0x03, 0x70, 0x45, 0x80, 0x00, 0x23, 0xC3, 0x80, 0x3C, 0x33, 0xFB, 0x5C, 0x03, 0x71, 0xCF, 0xF7, 0xA1, 0xFF, 0xBF, 0xE7, -+0x89, 0xB2, 0x80, 0xB2, 0x52, 0x46, 0xA5, 0xF7, 0x83, 0xFB, 0x8F, 0xE7, 0x43, 0x1C, 0x98, 0x46, 0x00, 0x2D, 0x05, 0xD1, -+0x2F, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x23, 0x01, 0x1B, 0x1B, 0x9B, 0x00, 0x28, 0x4A, -+0x91, 0x46, 0x99, 0x44, 0x29, 0x00, 0x40, 0x46, 0xD4, 0xF7, 0x56, 0xFC, 0x4B, 0x46, 0xD9, 0x80, 0x84, 0xE7, 0xE3, 0xB2, -+0x98, 0x46, 0x18, 0x00, 0x95, 0xF7, 0xEC, 0xFD, 0x05, 0x1E, 0x07, 0x9B, 0x99, 0x46, 0x05, 0xD1, 0x21, 0x4B, 0x9B, 0x6E, -+0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x29, 0x00, 0x48, 0x46, 0xD4, 0xF7, 0x40, 0xFC, 0x00, 0x29, 0x00, 0xD0, -+0x76, 0xE7, 0x23, 0x01, 0x1B, 0x1B, 0x9B, 0x00, 0x16, 0x4A, 0xD3, 0x18, 0xD9, 0x88, 0x09, 0x9B, 0x00, 0x93, 0x08, 0x9B, -+0x01, 0x93, 0x00, 0x9B, 0x01, 0x9A, 0x9A, 0x1A, 0x8A, 0x18, 0x92, 0xB2, 0x40, 0x46, 0x95, 0xF7, 0x17, 0xFE, 0x81, 0x46, -+0x07, 0x9B, 0x98, 0x46, 0x00, 0x2B, 0x05, 0xD1, 0x0F, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, -+0x23, 0x01, 0x1B, 0x1B, 0x9B, 0x00, 0x08, 0x4D, 0xED, 0x18, 0x41, 0x46, 0x48, 0x46, 0xD4, 0xF7, 0x17, 0xFC, 0xE9, 0x80, -+0x4E, 0xE7, 0xE0, 0xB2, 0x01, 0x33, 0x00, 0x22, 0x17, 0x21, 0x95, 0xF7, 0x89, 0xFC, 0x53, 0xE7, 0x64, 0xA2, 0x16, 0x00, -+0xC0, 0xA0, 0x16, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0x11, 0x00, 0x00, 0x28, 0x19, 0x16, 0x00, 0xF0, 0xB5, 0xC6, 0x46, -+0x00, 0xB5, 0x00, 0x24, 0x00, 0x20, 0x0E, 0x4E, 0xA1, 0x27, 0xAF, 0x23, 0x98, 0x46, 0x0C, 0xE0, 0x42, 0x46, 0x9D, 0x5C, -+0x45, 0x19, 0xED, 0xB2, 0x48, 0x33, 0x18, 0x00, 0x80, 0xF7, 0x18, 0xFE, 0x28, 0x18, 0xC0, 0xB2, 0x01, 0x34, 0x07, 0x2C, -+0x07, 0xD0, 0xA3, 0x00, 0x9B, 0x59, 0x00, 0x2B, 0xF8, 0xD0, 0xDA, 0x5D, 0x00, 0x2A, 0xF5, 0xD1, 0xEA, 0xE7, 0x04, 0xBC, -+0x90, 0x46, 0xF0, 0xBD, 0x38, 0x27, 0x16, 0x00, 0xF0, 0xB5, 0x85, 0xB0, 0x40, 0x4B, 0x1A, 0x78, 0x01, 0x2A, 0x01, 0xD0, -+0x05, 0xB0, 0xF0, 0xBD, 0x3E, 0x4B, 0x1D, 0x78, 0x3E, 0x4B, 0x1B, 0x68, 0x00, 0x24, 0x5B, 0x05, 0x08, 0xD5, 0x3C, 0x48, -+0x03, 0x68, 0x3C, 0x49, 0x19, 0x40, 0x80, 0x23, 0x1B, 0x01, 0x0B, 0x43, 0x03, 0x60, 0x80, 0x34, 0x39, 0x4B, 0x1B, 0x68, -+0x9B, 0x05, 0x09, 0xD4, 0x37, 0x48, 0x03, 0x68, 0x37, 0x49, 0x19, 0x40, 0x80, 0x23, 0x9B, 0x00, 0x0B, 0x43, 0x03, 0x60, -+0x40, 0x23, 0x1C, 0x43, 0x34, 0x4B, 0x18, 0x68, 0x34, 0x4B, 0x19, 0x68, 0x34, 0x4B, 0x1E, 0x68, 0x8B, 0x07, 0x31, 0xD4, -+0xF0, 0x23, 0x03, 0x40, 0x30, 0x2B, 0x0E, 0xD0, 0x20, 0x2B, 0x1F, 0xD0, 0x10, 0x2B, 0x29, 0xD1, 0x2F, 0x4B, 0xDB, 0x69, -+0xB3, 0x42, 0x25, 0xD0, 0xF0, 0x23, 0x07, 0x00, 0x9F, 0x43, 0x3B, 0x00, 0x20, 0x27, 0x3B, 0x43, 0x0A, 0xE0, 0x2A, 0x4B, -+0xDB, 0x6B, 0xB3, 0x42, 0x1A, 0xD0, 0xF0, 0x23, 0x02, 0x00, 0x9A, 0x43, 0x13, 0x00, 0x20, 0x22, 0x13, 0x43, 0x1D, 0x3A, -+0x22, 0x4F, 0x3F, 0x68, 0xBF, 0x07, 0x1F, 0xD4, 0x1F, 0x4F, 0x3B, 0x60, 0x14, 0x43, 0x1D, 0xE0, 0x20, 0x4B, 0xDB, 0x6A, -+0xB3, 0x42, 0x07, 0xD0, 0xF0, 0x23, 0x02, 0x00, 0x9A, 0x43, 0x13, 0x00, 0x10, 0x22, 0x13, 0x43, 0x0E, 0x3A, 0xEB, 0xE7, -+0x01, 0x2D, 0xA3, 0xD1, 0x17, 0x4B, 0x1B, 0x68, 0x02, 0x93, 0x00, 0x23, 0x01, 0x93, 0x00, 0x90, 0x33, 0x00, 0x00, 0x22, -+0x16, 0x48, 0x80, 0xF7, 0x47, 0xF9, 0x00, 0x2C, 0x96, 0xD0, 0x0D, 0xE0, 0x04, 0x27, 0x3C, 0x43, 0x01, 0x2D, 0x00, 0xD0, -+0x90, 0xE7, 0x0E, 0x4D, 0x2D, 0x68, 0x02, 0x95, 0x01, 0x93, 0x00, 0x90, 0x33, 0x00, 0x0E, 0x48, 0x80, 0xF7, 0x36, 0xF9, -+0x32, 0x00, 0x21, 0x00, 0x0C, 0x48, 0x80, 0xF7, 0x31, 0xF9, 0x81, 0xE7, 0xB4, 0xE5, 0x10, 0x00, 0xBC, 0xE6, 0x10, 0x00, -+0x4C, 0x20, 0x62, 0x40, 0xFF, 0xF3, 0xFF, 0xFF, 0x58, 0x20, 0x62, 0x40, 0xFF, 0xFD, 0xFF, 0xFF, 0x08, 0x05, 0x62, 0x40, -+0x74, 0x20, 0x62, 0x40, 0x78, 0x20, 0x62, 0x40, 0xD8, 0x97, 0x16, 0x00, 0x24, 0xD1, 0x10, 0x00, 0x3C, 0xD1, 0x10, 0x00, -+0x70, 0x47, 0x00, 0x00, 0x03, 0x4B, 0x04, 0x4A, 0x13, 0x60, 0x81, 0x22, 0x52, 0x00, 0x98, 0x5C, 0x70, 0x47, 0xC0, 0x46, -+0x80, 0x2A, 0x16, 0x00, 0x0C, 0xE7, 0x10, 0x00, 0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x17, 0x4B, 0x17, 0x4A, 0x1A, 0x60, -+0x17, 0x48, 0x80, 0xF7, 0x53, 0xFD, 0x45, 0x1E, 0x6D, 0xB2, 0x40, 0xB2, 0x00, 0x28, 0x1F, 0xDD, 0x11, 0x4F, 0x14, 0x4B, -+0x98, 0x46, 0x14, 0x4E, 0x0A, 0xE0, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x43, 0x46, 0x9B, 0x6E, 0x98, 0x47, 0x09, 0xE0, -+0x01, 0x3D, 0x6D, 0xB2, 0x6B, 0x1C, 0x0F, 0xD0, 0x38, 0x68, 0x0C, 0x30, 0x80, 0xF7, 0x56, 0xFC, 0x04, 0x1E, 0xEE, 0xD0, -+0x61, 0x6A, 0x30, 0x00, 0x80, 0xF7, 0xE2, 0xF8, 0x63, 0x6A, 0x00, 0x2B, 0xEE, 0xD0, 0x20, 0x00, 0x98, 0x47, 0xEB, 0xE7, -+0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0xC0, 0x46, 0x10, 0xE7, 0x10, 0x00, 0x64, 0x2A, 0x16, 0x00, 0x70, 0x2A, 0x16, 0x00, -+0x28, 0x19, 0x16, 0x00, 0xC0, 0xD3, 0x10, 0x00, 0x70, 0xB5, 0x04, 0x00, 0x78, 0x21, 0x88, 0xF7, 0xAB, 0xF9, 0x05, 0x00, -+0x08, 0x4B, 0xC0, 0x18, 0x78, 0x22, 0x55, 0x21, 0x7C, 0xF7, 0x42, 0xF8, 0x29, 0x00, 0x20, 0x00, 0x88, 0xF7, 0xBA, 0xF9, -+0x01, 0x00, 0x20, 0x00, 0xB0, 0xF7, 0x1E, 0xFD, 0x02, 0x48, 0x80, 0xF7, 0xB7, 0xF8, 0x70, 0xBD, 0x00, 0x00, 0x61, 0x40, -+0x4C, 0xD1, 0x10, 0x00, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x83, 0xB0, 0x04, 0x00, -+0x83, 0x00, 0x76, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1D, 0x68, 0x00, 0x2D, 0x00, 0xD1, 0xDE, 0xE0, 0x4B, 0x23, 0xEB, 0x5C, -+0x00, 0x2B, 0x05, 0xD0, 0x71, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x28, 0x00, 0x50, 0x30, -+0x80, 0xF7, 0x02, 0xFC, 0x07, 0x00, 0x00, 0x21, 0x20, 0x00, 0x88, 0xF7, 0xDF, 0xF9, 0x63, 0x01, 0x6A, 0x4A, 0x9A, 0x18, -+0x12, 0x68, 0xD2, 0x0F, 0x49, 0x21, 0x69, 0x5C, 0x01, 0x26, 0x71, 0x40, 0x91, 0x42, 0x4F, 0xD0, 0x66, 0x49, 0x8A, 0x46, -+0x9A, 0x44, 0x51, 0x46, 0x09, 0x68, 0x89, 0xB2, 0x8B, 0x46, 0x64, 0x4E, 0xB1, 0x46, 0x99, 0x44, 0x4E, 0x46, 0x36, 0x68, -+0xB6, 0xB2, 0xB0, 0x46, 0x61, 0x4E, 0x9E, 0x19, 0x36, 0x68, 0xB6, 0x03, 0xB1, 0x0F, 0x01, 0x91, 0x56, 0x46, 0x36, 0x68, -+0x36, 0x0C, 0x36, 0x04, 0xB4, 0x46, 0x56, 0x46, 0x61, 0x46, 0x31, 0x60, 0x49, 0x46, 0x09, 0x68, 0x09, 0x0C, 0x09, 0x04, -+0x8C, 0x46, 0x49, 0x46, 0x66, 0x46, 0x0E, 0x60, 0x00, 0x2F, 0x67, 0xD0, 0x00, 0x2A, 0x4C, 0xD1, 0x52, 0x4A, 0x94, 0x46, -+0x9C, 0x44, 0x62, 0x46, 0x12, 0x68, 0x91, 0x46, 0xBA, 0x88, 0x12, 0x04, 0x49, 0x46, 0x0F, 0x04, 0x3F, 0x0C, 0x3A, 0x43, -+0x61, 0x46, 0x0A, 0x60, 0x00, 0x28, 0x0A, 0xD0, 0x4B, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1F, 0x68, 0x82, 0x88, 0x04, 0x32, -+0x12, 0x04, 0x38, 0x04, 0x00, 0x0C, 0x02, 0x43, 0x1A, 0x60, 0x5B, 0x46, 0x00, 0x2B, 0x4C, 0xD1, 0x43, 0x46, 0x00, 0x2B, -+0x4E, 0xD1, 0x03, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0x3E, 0x49, 0x8A, 0x46, -+0x9A, 0x44, 0x51, 0x46, 0x09, 0x68, 0x09, 0x0C, 0x8B, 0x46, 0x3C, 0x49, 0x89, 0x46, 0x99, 0x44, 0x49, 0x46, 0x0E, 0x68, -+0x31, 0x0C, 0x88, 0x46, 0x39, 0x49, 0x5E, 0x18, 0x36, 0x68, 0x36, 0x03, 0xB1, 0x0F, 0x01, 0x91, 0x51, 0x46, 0x09, 0x68, -+0x09, 0x04, 0x09, 0x0C, 0x8C, 0x46, 0x51, 0x46, 0x66, 0x46, 0x0E, 0x60, 0x49, 0x46, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0C, -+0x8C, 0x46, 0x49, 0x46, 0x66, 0x46, 0x0E, 0x60, 0xAE, 0xE7, 0x2C, 0x4A, 0x94, 0x46, 0x9C, 0x44, 0x62, 0x46, 0x12, 0x68, -+0x12, 0x0C, 0x12, 0x04, 0xBF, 0x88, 0x3A, 0x43, 0x61, 0x46, 0x0A, 0x60, 0x00, 0x28, 0xC0, 0xD0, 0x26, 0x4A, 0x94, 0x46, -+0x63, 0x44, 0x1F, 0x68, 0x82, 0x88, 0x04, 0x32, 0x92, 0xB2, 0x38, 0x0C, 0x00, 0x04, 0x02, 0x43, 0x1A, 0x60, 0xB4, 0xE7, -+0x00, 0x28, 0xB2, 0xD0, 0x00, 0x2A, 0xEF, 0xD1, 0xA4, 0xE7, 0x59, 0x46, 0x20, 0x00, 0x88, 0xF7, 0x17, 0xF9, 0xAD, 0xE7, -+0x46, 0x23, 0xE9, 0x5C, 0x09, 0x02, 0x45, 0x3B, 0x19, 0x43, 0x05, 0x33, 0xFF, 0x22, 0x1A, 0x48, 0x7D, 0xF7, 0xDE, 0xFE, -+0x07, 0x00, 0x43, 0x46, 0x03, 0x80, 0x58, 0x23, 0xEA, 0x5C, 0x01, 0x32, 0x2B, 0x8F, 0x53, 0x43, 0x83, 0x70, 0x01, 0x99, -+0xC1, 0x70, 0x14, 0x4B, 0x1A, 0x68, 0x01, 0x32, 0x1A, 0x60, 0x00, 0x29, 0x04, 0xD1, 0x3C, 0x71, 0x38, 0x00, 0x7D, 0xF7, -+0xF3, 0xFE, 0x90, 0xE7, 0x0F, 0x49, 0x0B, 0x68, 0x01, 0x33, 0x0B, 0x60, 0x01, 0x99, 0x0E, 0x48, 0x7F, 0xF7, 0xC4, 0xFF, -+0xF1, 0xE7, 0x04, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x80, 0xE7, 0x54, 0x27, 0x16, 0x00, -+0x28, 0x19, 0x16, 0x00, 0xD0, 0x05, 0x60, 0x40, 0xD8, 0x05, 0x60, 0x40, 0xDC, 0x05, 0x60, 0x40, 0xD4, 0x05, 0x60, 0x40, -+0x35, 0x06, 0x00, 0x00, 0xC4, 0xE6, 0x10, 0x00, 0xC0, 0xE6, 0x10, 0x00, 0x54, 0xD1, 0x10, 0x00, 0x70, 0xB5, 0x0C, 0x00, -+0x15, 0x00, 0x10, 0x00, 0x7E, 0xF7, 0x74, 0xFA, 0x00, 0x28, 0x03, 0xD0, 0x16, 0x38, 0xC0, 0xB2, 0x03, 0x28, 0x07, 0xD8, -+0x21, 0x88, 0x04, 0x39, 0x89, 0xB2, 0x20, 0x79, 0x88, 0xF7, 0xFA, 0xF8, 0x00, 0x20, 0x70, 0xBD, 0x2E, 0x0A, 0x06, 0x23, -+0x2A, 0x00, 0x31, 0x00, 0x1B, 0x48, 0x7D, 0xF7, 0x89, 0xFE, 0x05, 0x00, 0x23, 0x88, 0x83, 0x80, 0xA3, 0x78, 0x83, 0x70, -+0x21, 0x79, 0x01, 0x31, 0x09, 0x02, 0x80, 0x36, 0x89, 0x19, 0x01, 0x80, 0xE1, 0x78, 0x0A, 0x03, 0x14, 0x4B, 0x1A, 0x42, -+0x06, 0xD0, 0xC0, 0x20, 0x13, 0x4B, 0xDE, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x80, 0x01, 0xB0, 0x47, 0x2B, 0x88, 0x0F, 0x4A, -+0x13, 0x40, 0xE2, 0x78, 0x12, 0x03, 0x13, 0x43, 0x2B, 0x80, 0xE3, 0x78, 0x00, 0x2B, 0x03, 0xD1, 0x28, 0x00, 0xCF, 0xF7, -+0xC5, 0xFC, 0xD1, 0xE7, 0xA2, 0x78, 0x20, 0x88, 0x09, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0x00, 0x21, 0x7B, 0xF7, 0xE0, 0xFE, -+0xE1, 0x78, 0x00, 0x29, 0xF0, 0xD0, 0x06, 0x48, 0x7F, 0xF7, 0x5A, 0xFF, 0xEC, 0xE7, 0xC0, 0x46, 0x07, 0x11, 0x00, 0x00, -+0xFF, 0xCF, 0xFF, 0xFF, 0x28, 0x19, 0x16, 0x00, 0x00, 0x00, 0x61, 0x40, 0x6C, 0xD1, 0x10, 0x00, 0xF0, 0xB5, 0x89, 0xB0, -+0x04, 0x1E, 0x00, 0xD1, 0xAB, 0xE0, 0x46, 0x23, 0xC6, 0x5C, 0xB2, 0x00, 0x5A, 0x4B, 0xD5, 0x58, 0x00, 0x2D, 0x00, 0xD1, -+0xA9, 0xE0, 0x43, 0x68, 0x02, 0x3B, 0x1B, 0x01, 0x1B, 0x09, 0xC3, 0x62, 0x28, 0x30, 0xD2, 0xF7, 0xE9, 0xFD, 0x62, 0x68, -+0x61, 0x6B, 0x8A, 0x42, 0x13, 0xD0, 0x45, 0x23, 0xE3, 0x5C, 0x5B, 0x00, 0x5B, 0x18, 0x1B, 0x01, 0x1B, 0x09, 0x9A, 0x42, -+0x0B, 0xD0, 0x4F, 0x4B, 0x9B, 0x7A, 0xA3, 0x75, 0x4A, 0x23, 0xE3, 0x5C, 0x03, 0x2B, 0x00, 0xD0, 0x8D, 0xE0, 0x47, 0x33, -+0x00, 0x22, 0xE2, 0x54, 0x89, 0xE0, 0x4A, 0x4B, 0x00, 0x93, 0x01, 0x92, 0xA3, 0x68, 0x02, 0x93, 0x6B, 0x46, 0x1E, 0x76, -+0x47, 0x23, 0xE0, 0x5C, 0x03, 0x01, 0x33, 0x43, 0x04, 0x93, 0x00, 0x23, 0x9C, 0x46, 0x03, 0x93, 0xA7, 0x7D, 0x6B, 0x46, -+0x1F, 0x75, 0x67, 0x46, 0x5F, 0x75, 0x9F, 0x75, 0x8A, 0x42, 0x00, 0xD1, 0x73, 0xE0, 0x10, 0x23, 0x6A, 0x46, 0xD3, 0x75, -+0x0C, 0x3B, 0x6A, 0x46, 0x93, 0x76, 0xD0, 0x76, 0x01, 0x23, 0x53, 0x76, 0x68, 0x46, 0xD3, 0xF7, 0x9B, 0xF8, 0x48, 0x22, -+0xA3, 0x5C, 0x01, 0x33, 0xA3, 0x54, 0x01, 0x21, 0x63, 0x68, 0x62, 0x6B, 0x93, 0x42, 0x35, 0xD0, 0x47, 0x23, 0xE3, 0x5C, -+0x33, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x5B, 0x01, 0x1A, 0x68, 0x32, 0x48, 0x02, 0x40, 0x09, 0x04, 0x0A, 0x43, 0x1A, 0x60, -+0x9F, 0x23, 0xEB, 0x5C, 0x01, 0x2B, 0xB6, 0xD1, 0x2B, 0x6D, 0x5F, 0x1C, 0x7F, 0x08, 0xAB, 0x6F, 0x9B, 0xB2, 0x62, 0x22, -+0x56, 0x43, 0x2B, 0x4A, 0xB2, 0x18, 0x13, 0x80, 0xAB, 0x6F, 0x1B, 0x0C, 0x29, 0x4A, 0xB2, 0x18, 0x13, 0x80, 0x80, 0x23, -+0x9B, 0x01, 0x9F, 0x42, 0x2B, 0xD3, 0x27, 0x49, 0x38, 0x00, 0xD4, 0xF7, 0xF9, 0xF8, 0x00, 0x29, 0x19, 0xD0, 0x25, 0x4B, -+0x9C, 0x46, 0x66, 0x44, 0x22, 0x49, 0x38, 0x00, 0xD4, 0xF7, 0x6A, 0xF8, 0x01, 0x30, 0x22, 0x4B, 0x03, 0x43, 0x9B, 0xB2, -+0x33, 0x80, 0x90, 0xE7, 0x20, 0x4B, 0x2A, 0x6D, 0x9A, 0x42, 0xC5, 0xD8, 0x4A, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0xC1, 0xD1, -+0x44, 0x33, 0xE1, 0x5C, 0x01, 0x31, 0xC9, 0xB2, 0xBC, 0xE7, 0x18, 0x4B, 0x9C, 0x46, 0x66, 0x44, 0x15, 0x49, 0x38, 0x00, -+0xD4, 0xF7, 0x50, 0xF8, 0x15, 0x4B, 0x03, 0x43, 0x9B, 0xB2, 0x33, 0x80, 0x77, 0xE7, 0x01, 0x37, 0x7F, 0x08, 0xBF, 0xB2, -+0x10, 0x4B, 0x9C, 0x46, 0x66, 0x44, 0x37, 0x80, 0x6F, 0xE7, 0x11, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, -+0x98, 0x47, 0x09, 0xB0, 0xF0, 0xBD, 0x0F, 0x23, 0x6A, 0x46, 0xD3, 0x75, 0x0D, 0x3B, 0x8A, 0xE7, 0x38, 0x27, 0x16, 0x00, -+0x7C, 0x91, 0x0D, 0x00, 0x5D, 0x74, 0x0B, 0x00, 0x2F, 0x00, 0x03, 0x02, 0xFF, 0xFF, 0x00, 0xFF, 0xFA, 0x64, 0x61, 0x40, -+0xFC, 0x64, 0x61, 0x40, 0x71, 0x02, 0x00, 0x00, 0x10, 0x65, 0x61, 0x40, 0x00, 0x80, 0xFF, 0xFF, 0xE1, 0x04, 0x00, 0x00, -+0x28, 0x19, 0x16, 0x00, 0xF8, 0xB5, 0x06, 0x00, 0x14, 0x4B, 0x1D, 0x68, 0x00, 0x2D, 0x05, 0xD1, 0x5D, 0x68, 0x00, 0x2D, -+0x02, 0xD1, 0x00, 0x24, 0x20, 0x00, 0xF8, 0xBD, 0xAB, 0x68, 0x2A, 0x69, 0x94, 0x46, 0x63, 0x44, 0x1F, 0x00, 0x0E, 0x49, -+0x18, 0x00, 0xD4, 0xF7, 0x09, 0xF8, 0x6C, 0x6B, 0x04, 0x19, 0x0B, 0x49, 0x38, 0x00, 0xD4, 0xF7, 0x89, 0xF8, 0xB3, 0x68, -+0x9C, 0x46, 0x8C, 0x45, 0x89, 0x41, 0x49, 0x42, 0x64, 0x18, 0xB1, 0x8A, 0x89, 0x04, 0x49, 0x0F, 0x04, 0x29, 0xE3, 0xD0, -+0x20, 0x00, 0xFC, 0xF7, 0x63, 0xFF, 0x04, 0x00, 0xDE, 0xE7, 0xC0, 0x46, 0x54, 0x27, 0x16, 0x00, 0x71, 0x02, 0x00, 0x00, -+0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x8B, 0xB0, 0xBD, 0x4B, 0x1C, 0x68, 0xA1, 0x46, -+0xBC, 0x4B, 0xA3, 0x82, 0x4C, 0x23, 0xE3, 0x5A, 0x5B, 0x00, 0x62, 0x6C, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x01, 0x1B, 0x09, -+0xE3, 0x60, 0xA7, 0xF7, 0x5D, 0xF9, 0x04, 0x90, 0xB6, 0x4B, 0x1B, 0x68, 0x01, 0x93, 0xB6, 0x4B, 0x1B, 0x68, 0x02, 0x93, -+0xB5, 0x4B, 0x1B, 0x68, 0x07, 0x93, 0xB5, 0x4B, 0x1B, 0x68, 0x06, 0x93, 0x00, 0x25, 0x00, 0x20, 0x00, 0x27, 0x00, 0x23, -+0x03, 0x93, 0x00, 0x26, 0xB1, 0x4B, 0x98, 0x46, 0xA1, 0x23, 0x9A, 0x46, 0x02, 0x3B, 0x9B, 0x46, 0x0F, 0xE0, 0x01, 0x37, -+0xFF, 0xB2, 0xAF, 0x22, 0x9E, 0x5C, 0x86, 0x19, 0xF6, 0xB2, 0x48, 0x33, 0x18, 0x00, 0x80, 0xF7, 0x5F, 0xFA, 0x30, 0x18, -+0xC0, 0xB2, 0x01, 0x26, 0x01, 0x35, 0x07, 0x2D, 0x0E, 0xD0, 0xAB, 0x00, 0x42, 0x46, 0x9B, 0x58, 0x00, 0x2B, 0xF7, 0xD0, -+0x52, 0x46, 0x9A, 0x5C, 0x00, 0x2A, 0xF3, 0xD1, 0x5A, 0x46, 0x9A, 0x5C, 0x01, 0x2A, 0xE2, 0xD1, 0x03, 0x92, 0xE0, 0xE7, -+0x9F, 0x4B, 0x00, 0x22, 0x1A, 0x70, 0x00, 0x23, 0x01, 0x32, 0xBA, 0x42, 0x5B, 0x41, 0x02, 0x33, 0x9C, 0x4A, 0x13, 0x70, -+0x83, 0x42, 0x08, 0xD8, 0x00, 0x22, 0x03, 0x28, 0x01, 0xD9, 0xC2, 0x1E, 0xD2, 0xB2, 0xC0, 0x1A, 0x10, 0x18, 0x96, 0x4B, -+0x18, 0x70, 0x50, 0x23, 0x00, 0x22, 0xE2, 0x54, 0x95, 0x4B, 0x19, 0x00, 0x41, 0x31, 0xFF, 0x31, 0x00, 0x25, 0x04, 0xE0, -+0x01, 0x35, 0xED, 0xB2, 0x40, 0x33, 0x8B, 0x42, 0x07, 0xD0, 0x1A, 0x78, 0x09, 0x2A, 0xF9, 0xD1, 0x00, 0x2F, 0xF5, 0xD0, -+0x01, 0x37, 0xFF, 0xB2, 0xF2, 0xE7, 0xB0, 0xF7, 0x5F, 0xFA, 0x05, 0x90, 0x80, 0x46, 0x02, 0x9B, 0x01, 0x9A, 0x13, 0x43, -+0x5A, 0x1E, 0x93, 0x41, 0xDB, 0xB2, 0x9B, 0x46, 0x87, 0x4B, 0x1B, 0x78, 0x9A, 0x46, 0x00, 0x2B, 0x00, 0xD1, 0x79, 0xE0, -+0x85, 0x4B, 0x1B, 0x78, 0x01, 0x2B, 0x28, 0xD9, 0x02, 0x2B, 0x64, 0xD0, 0x8C, 0xF7, 0xDC, 0xF8, 0x82, 0x46, 0x00, 0x28, -+0x00, 0xD1, 0x1B, 0xE2, 0x00, 0x23, 0x9A, 0x46, 0x7F, 0x4B, 0x23, 0x64, 0x02, 0x22, 0x62, 0x63, 0xFA, 0x22, 0x92, 0x01, -+0xA2, 0x62, 0x19, 0x00, 0x23, 0x61, 0x43, 0x46, 0x00, 0x2B, 0x00, 0xD0, 0x77, 0xE0, 0xA3, 0x6A, 0x62, 0x6B, 0x98, 0x1A, -+0x40, 0x00, 0x04, 0x9B, 0x9C, 0x46, 0x60, 0x44, 0x00, 0x01, 0x00, 0x09, 0x60, 0x60, 0x01, 0x2D, 0x00, 0xD1, 0x84, 0xE1, -+0x00, 0x22, 0x20, 0x00, 0xFC, 0xF7, 0x9A, 0xFF, 0x11, 0xE0, 0x71, 0x4B, 0x23, 0x64, 0x80, 0x22, 0x62, 0x63, 0xA2, 0x62, -+0x6C, 0x4A, 0x01, 0x21, 0x11, 0x70, 0x16, 0x22, 0xA2, 0x75, 0x23, 0x61, 0x04, 0x98, 0x2C, 0x30, 0x00, 0x01, 0x00, 0x09, -+0x60, 0x60, 0x00, 0x23, 0x9A, 0x46, 0x69, 0x4E, 0x4C, 0x25, 0x69, 0x4F, 0x48, 0x46, 0xD1, 0xF7, 0x33, 0xFF, 0x00, 0x28, -+0x00, 0xD1, 0xB0, 0xE1, 0x31, 0x00, 0x20, 0x69, 0xD3, 0xF7, 0x16, 0xFF, 0x63, 0x68, 0x9C, 0x46, 0x60, 0x44, 0x00, 0x01, -+0x00, 0x09, 0x60, 0x60, 0x63, 0x5B, 0x5B, 0x00, 0xE2, 0x68, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x01, 0x1B, 0x09, 0xE3, 0x60, -+0xA3, 0x7D, 0x5D, 0x4A, 0xD2, 0x78, 0x9B, 0x18, 0xA3, 0x75, 0x59, 0x4B, 0x9C, 0x46, 0x66, 0x44, 0xBE, 0x42, 0xDD, 0xD1, -+0x0B, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0x56, 0x4B, 0x1B, 0x68, 0x5B, 0x00, -+0x23, 0x64, 0x02, 0x23, 0x63, 0x63, 0x4E, 0x33, 0xA3, 0x62, 0x4C, 0x4B, 0x03, 0x22, 0x1A, 0x70, 0x49, 0x4B, 0x00, 0x22, -+0x1A, 0x70, 0x8B, 0xE7, 0xFD, 0xF7, 0x12, 0xF8, 0x00, 0x28, 0x04, 0xD1, 0x4D, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0x00, 0xD1, -+0x11, 0xE1, 0x43, 0x46, 0x00, 0x2B, 0x2C, 0xD0, 0x4A, 0x4B, 0x23, 0x64, 0x04, 0x23, 0x63, 0x63, 0x08, 0x33, 0xA3, 0x62, -+0x8C, 0xF7, 0x56, 0xF8, 0x00, 0x28, 0x00, 0xD0, 0x7C, 0xE7, 0x23, 0x6C, 0x23, 0x61, 0x20, 0x00, 0xFF, 0xF7, 0xAE, 0xFE, -+0x53, 0x46, 0x00, 0x2B, 0x00, 0xD1, 0x95, 0xE1, 0xC0, 0x30, 0x00, 0x01, 0x00, 0x09, 0x60, 0x60, 0x18, 0x26, 0x4F, 0x46, -+0x65, 0x68, 0x00, 0x22, 0x21, 0x69, 0x38, 0x00, 0xFC, 0xF7, 0x20, 0xFF, 0x63, 0x68, 0xAB, 0x42, 0x00, 0xD1, 0x4A, 0xE1, -+0x75, 0x19, 0x2D, 0x01, 0x2D, 0x09, 0x65, 0x60, 0x18, 0x36, 0x90, 0x2E, 0xEE, 0xD1, 0xB9, 0x46, 0x8B, 0xE7, 0x5B, 0x46, -+0x00, 0x2B, 0x21, 0xD0, 0x33, 0x4B, 0x1B, 0x68, 0x5B, 0x00, 0x23, 0x64, 0xE3, 0x6B, 0x63, 0x63, 0x23, 0x6B, 0xA3, 0x62, -+0x03, 0x9B, 0x00, 0x2B, 0x05, 0xD0, 0x2F, 0x4B, 0x23, 0x64, 0x1A, 0x23, 0x63, 0x63, 0x46, 0x33, 0xA3, 0x62, 0xB2, 0x46, -+0x00, 0x2E, 0x00, 0xD1, 0xD4, 0xE0, 0x05, 0x9A, 0x92, 0x46, 0x01, 0x9B, 0x00, 0x2B, 0x00, 0xD1, 0xCE, 0xE0, 0x28, 0x4B, -+0x1B, 0x68, 0xA1, 0x6A, 0x8C, 0x46, 0x63, 0x44, 0xA3, 0x62, 0xC7, 0xE0, 0x15, 0x4B, 0x1B, 0x78, 0x5A, 0x00, 0x9B, 0x18, -+0x5B, 0x00, 0xDB, 0xB2, 0x01, 0x2F, 0x49, 0xD9, 0x21, 0x4A, 0x22, 0x64, 0x1A, 0x22, 0x62, 0x63, 0x2C, 0x32, 0xA2, 0x62, -+0x00, 0x2B, 0x03, 0xD0, 0x1E, 0x4B, 0x23, 0x64, 0x14, 0x23, 0x63, 0x63, 0x00, 0x2D, 0x03, 0xD0, 0x1C, 0x4B, 0x23, 0x64, -+0x10, 0x23, 0x63, 0x63, 0x63, 0x6B, 0xA3, 0x62, 0xDA, 0x46, 0xA9, 0xE0, 0xF8, 0xE6, 0x10, 0x00, 0x00, 0xA0, 0xFF, 0xFF, -+0x24, 0x27, 0x16, 0x00, 0x18, 0x27, 0x16, 0x00, 0x28, 0x27, 0x16, 0x00, 0x20, 0x27, 0x16, 0x00, 0x38, 0x27, 0x16, 0x00, -+0xB1, 0xE6, 0x10, 0x00, 0xD1, 0xE6, 0x10, 0x00, 0x70, 0xA6, 0x16, 0x00, 0xB4, 0xE6, 0x10, 0x00, 0xB3, 0xE6, 0x10, 0x00, -+0xC4, 0x09, 0x00, 0x00, 0x00, 0x71, 0x02, 0x00, 0xE2, 0x04, 0x00, 0x00, 0x6A, 0x18, 0x00, 0x00, 0x7C, 0x91, 0x0D, 0x00, -+0x04, 0xE2, 0x10, 0x00, 0xB2, 0xE6, 0x10, 0x00, 0xF9, 0x15, 0x00, 0x00, 0x08, 0xE2, 0x10, 0x00, 0xDC, 0x82, 0x00, 0x00, -+0x14, 0xE2, 0x10, 0x00, 0xE8, 0x80, 0x00, 0x00, 0xF6, 0x54, 0x00, 0x00, 0xF2, 0x2B, 0x00, 0x00, 0x85, 0x4A, 0x5A, 0x43, -+0x03, 0x99, 0x00, 0x29, 0x33, 0xD0, 0x84, 0x49, 0x09, 0x68, 0x49, 0x00, 0x8A, 0x42, 0x29, 0xD8, 0x8A, 0x1A, 0x22, 0x64, -+0x28, 0x22, 0xD3, 0x1A, 0x63, 0x63, 0xE3, 0x6A, 0xA3, 0x62, 0x7F, 0x4B, 0x22, 0x6C, 0x9A, 0x42, 0x4B, 0xD9, 0xDA, 0x46, -+0x00, 0x2F, 0x5D, 0xD0, 0x07, 0x9B, 0x00, 0x2B, 0x00, 0xD1, 0xC4, 0xE0, 0x59, 0x68, 0x06, 0x9A, 0x00, 0x2A, 0x00, 0xD1, -+0xC4, 0xE0, 0x78, 0x4B, 0x99, 0x42, 0x00, 0xD1, 0xBE, 0xE0, 0x52, 0x68, 0x53, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x80, 0x20, -+0x00, 0x05, 0x83, 0x42, 0x00, 0xD8, 0xBA, 0xE0, 0x8B, 0x1A, 0x1B, 0x01, 0x00, 0xD1, 0xB6, 0xE0, 0x11, 0x00, 0xB1, 0xE0, -+0x6F, 0x4B, 0x23, 0x64, 0x1A, 0x23, 0x63, 0x63, 0xD5, 0xE7, 0x00, 0x2D, 0x0D, 0xD0, 0x6D, 0x4B, 0x23, 0x64, 0x10, 0x23, -+0x63, 0x63, 0xA3, 0x62, 0x01, 0x2D, 0x02, 0xD0, 0x01, 0x23, 0x9A, 0x46, 0xD0, 0xE7, 0x40, 0x33, 0x01, 0x22, 0xE2, 0x54, -+0xF8, 0xE7, 0x67, 0x49, 0x09, 0x68, 0x49, 0x00, 0x8A, 0x42, 0x0D, 0xD8, 0x8A, 0x1A, 0x22, 0x64, 0xA2, 0x6B, 0xD3, 0x1A, -+0x63, 0x63, 0xE3, 0x6A, 0xA3, 0x62, 0x5D, 0x4B, 0x22, 0x6C, 0x9A, 0x42, 0x09, 0xD9, 0x03, 0x9B, 0x9A, 0x46, 0xB9, 0xE7, -+0x5B, 0x4B, 0x23, 0x64, 0x1A, 0x23, 0x63, 0x63, 0xF1, 0xE7, 0x00, 0x2D, 0x05, 0xD1, 0x58, 0x4B, 0x23, 0x64, 0x1A, 0x23, -+0x63, 0x63, 0xDA, 0x46, 0xAC, 0xE7, 0xDA, 0x46, 0xAA, 0xE7, 0x50, 0x4B, 0x23, 0x64, 0x02, 0x23, 0x63, 0x63, 0x43, 0x46, -+0x00, 0x2B, 0x0B, 0xD1, 0x30, 0x33, 0xA3, 0x62, 0x2F, 0x3B, 0x9A, 0x46, 0x8B, 0xF7, 0x42, 0xFF, 0x00, 0x28, 0x00, 0xD0, -+0x68, 0xE6, 0x21, 0x6C, 0x21, 0x61, 0x72, 0xE6, 0xC0, 0x23, 0xA3, 0x62, 0x05, 0x9B, 0x9A, 0x46, 0xDE, 0xE6, 0x00, 0x23, -+0x08, 0x93, 0x09, 0x93, 0x20, 0x1D, 0x23, 0x00, 0x08, 0xAA, 0x09, 0xA9, 0xFC, 0xF7, 0x72, 0xFD, 0x09, 0x9B, 0x00, 0x2B, -+0x04, 0xD0, 0x22, 0x69, 0x9A, 0x42, 0x00, 0xD9, 0x1A, 0x00, 0x22, 0x61, 0x00, 0x2F, 0x07, 0xD0, 0x08, 0x9B, 0x5B, 0x00, -+0x62, 0x68, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x01, 0x1B, 0x09, 0x63, 0x60, 0x63, 0x6B, 0x02, 0x2B, 0x1E, 0xD0, 0x53, 0x46, -+0x00, 0x2B, 0x04, 0xD1, 0x3A, 0x4B, 0x08, 0x9A, 0x53, 0x43, 0x23, 0x61, 0x23, 0x64, 0x03, 0x26, 0x4F, 0x46, 0x65, 0x68, -+0x00, 0x22, 0x21, 0x69, 0x38, 0x00, 0xFC, 0xF7, 0xEB, 0xFD, 0x63, 0x68, 0xAB, 0x42, 0x18, 0xD0, 0x08, 0x9B, 0x9C, 0x46, -+0x65, 0x44, 0x2D, 0x01, 0x2D, 0x09, 0x65, 0x60, 0x01, 0x3E, 0xF6, 0xB2, 0x00, 0x2E, 0xEC, 0xD1, 0xB9, 0x46, 0x54, 0xE6, -+0x08, 0x9A, 0x53, 0x00, 0x9B, 0x18, 0x5B, 0x00, 0x62, 0x68, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x01, 0x1B, 0x09, 0x63, 0x60, -+0xD5, 0xE7, 0xB9, 0x46, 0x47, 0xE6, 0xB9, 0x46, 0x45, 0xE6, 0x4E, 0x23, 0x00, 0x22, 0xE2, 0x54, 0xA3, 0x7D, 0x10, 0x2B, -+0x00, 0xD9, 0x63, 0xE6, 0x43, 0x46, 0x00, 0x2B, 0x00, 0xD0, 0x5F, 0xE6, 0x53, 0x46, 0x00, 0x2B, 0x00, 0xD0, 0x5B, 0xE6, -+0x11, 0x33, 0xA3, 0x75, 0x58, 0xE6, 0x06, 0x9B, 0x00, 0x2B, 0x91, 0xD0, 0x06, 0x9B, 0x59, 0x68, 0x15, 0x4B, 0x99, 0x42, -+0x8C, 0xD0, 0x63, 0x6B, 0x1A, 0x00, 0x28, 0x32, 0x52, 0x00, 0xA0, 0x6A, 0xC3, 0x1A, 0x5B, 0x00, 0x04, 0x98, 0x84, 0x46, -+0x63, 0x44, 0x1B, 0x01, 0x1B, 0x09, 0x5B, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x9A, 0x42, 0x00, 0xD2, 0x7A, 0xE7, 0x0C, 0x4B, -+0x23, 0x64, 0x77, 0xE7, 0x21, 0x6C, 0x21, 0x61, 0x43, 0x46, 0x00, 0x2B, 0x04, 0xD0, 0x20, 0x00, 0xFF, 0xF7, 0x14, 0xFD, -+0x60, 0x60, 0x6B, 0xE6, 0x05, 0x9B, 0x9A, 0x46, 0xE5, 0xE5, 0xC0, 0x46, 0xE2, 0x04, 0x00, 0x00, 0x00, 0xE2, 0x10, 0x00, -+0xE7, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0xE8, 0x80, 0x00, 0x00, 0xF2, 0x2B, 0x00, 0x00, 0x04, 0xE2, 0x10, 0x00, -+0xA9, 0x03, 0x00, 0x00, 0x70, 0xB5, 0x04, 0x00, 0x1A, 0x4A, 0x13, 0x68, 0x04, 0x21, 0x0B, 0x43, 0x13, 0x60, 0x19, 0x4B, -+0x9B, 0x78, 0x83, 0x75, 0xFC, 0xF7, 0x06, 0xFE, 0x05, 0x00, 0x02, 0x21, 0x01, 0x20, 0xFC, 0xF7, 0xC3, 0xFE, 0x06, 0x00, -+0x00, 0x2D, 0x04, 0xD0, 0x11, 0x4A, 0x13, 0x68, 0x04, 0x21, 0x8B, 0x43, 0x13, 0x60, 0x4E, 0x23, 0xE3, 0x5C, 0x02, 0x2B, -+0x0E, 0xD0, 0xA6, 0xF7, 0x83, 0xFE, 0x60, 0x64, 0xFF, 0xF7, 0x0C, 0xFD, 0x00, 0x2E, 0x0E, 0xD0, 0x00, 0x2D, 0x04, 0xD0, -+0x08, 0x4A, 0x13, 0x68, 0x04, 0x21, 0x0B, 0x43, 0x13, 0x60, 0x70, 0xBD, 0x07, 0x4C, 0x20, 0x68, 0x7D, 0xF7, 0xB8, 0xFB, -+0x00, 0x23, 0x23, 0x60, 0xEE, 0xE7, 0x02, 0x21, 0x00, 0x20, 0xFC, 0xF7, 0x9D, 0xFE, 0xEB, 0xE7, 0xFC, 0x00, 0x60, 0x40, -+0x7C, 0x91, 0x0D, 0x00, 0xF8, 0xE6, 0x10, 0x00, 0x10, 0xB5, 0x4E, 0x23, 0xC3, 0x5C, 0x00, 0x2B, 0x00, 0xD0, 0x10, 0xBD, -+0x00, 0x21, 0xD1, 0xF7, 0x8F, 0xFE, 0xFF, 0xF7, 0xE5, 0xFC, 0xF8, 0xE7, 0x10, 0xB5, 0xA6, 0xF7, 0x55, 0xFE, 0x22, 0x4B, -+0x5A, 0x68, 0x92, 0x01, 0x1B, 0x68, 0xC0, 0x1A, 0x00, 0x01, 0x01, 0x09, 0x40, 0x00, 0x43, 0x1A, 0x9B, 0x00, 0x5B, 0x18, -+0x99, 0x00, 0x5B, 0x18, 0x9A, 0x42, 0x20, 0xD3, 0xD3, 0x1A, 0x1B, 0x4C, 0x9C, 0x42, 0xA4, 0x41, 0x64, 0x42, 0x1A, 0x4B, -+0x1A, 0x4A, 0x1A, 0x60, 0xD1, 0xF7, 0xC0, 0xFE, 0x00, 0x28, 0x0A, 0xD0, 0x00, 0x2C, 0x19, 0xD0, 0x17, 0x4B, 0x80, 0x22, -+0x12, 0x05, 0x1A, 0x60, 0x16, 0x48, 0x7F, 0xF7, 0x05, 0xFB, 0x10, 0xBD, 0x00, 0x24, 0x11, 0x4B, 0x1B, 0x68, 0x9B, 0x68, -+0x00, 0x2B, 0xF1, 0xD0, 0x12, 0x4A, 0xDB, 0x69, 0x93, 0x42, 0xEB, 0xD1, 0xEC, 0xE7, 0x0C, 0x4B, 0x0C, 0x4A, 0x1A, 0x60, -+0xD1, 0xF7, 0xA4, 0xFE, 0x00, 0x28, 0xED, 0xD0, 0x0D, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0x0D, 0x4B, 0x00, 0x22, 0x1A, 0x70, -+0x0C, 0x4B, 0x18, 0x68, 0x00, 0x28, 0xE2, 0xD0, 0xFF, 0xF7, 0xAE, 0xFF, 0xDF, 0xE7, 0xC0, 0x46, 0x6C, 0xE6, 0x10, 0x00, -+0xFF, 0x70, 0x02, 0x00, 0x10, 0xE7, 0x10, 0x00, 0x64, 0x2A, 0x16, 0x00, 0x00, 0x41, 0x04, 0x40, 0x74, 0xD1, 0x10, 0x00, -+0xC9, 0x1F, 0x10, 0x00, 0xB4, 0xE6, 0x10, 0x00, 0xB3, 0xE6, 0x10, 0x00, 0xF8, 0xE6, 0x10, 0x00, 0xF8, 0xB5, 0xDE, 0x46, -+0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x06, 0x00, 0x0D, 0x00, 0x17, 0x00, 0x49, 0x4B, 0x1C, 0x68, 0xA4, 0x04, -+0xA4, 0x0E, 0x20, 0x00, 0x50, 0x43, 0x43, 0x01, 0x1B, 0x1A, 0x9B, 0x00, 0x1B, 0x18, 0x98, 0x00, 0x18, 0x18, 0x00, 0x02, -+0xD3, 0xF7, 0x5E, 0xFC, 0x81, 0x46, 0x03, 0x0A, 0x9B, 0x46, 0x29, 0x00, 0x80, 0x20, 0xC0, 0x00, 0xD3, 0xF7, 0x56, 0xFC, -+0x03, 0x00, 0x6B, 0x43, 0x9A, 0x46, 0xFF, 0x21, 0x4B, 0x46, 0x19, 0x40, 0x69, 0x43, 0x09, 0x0A, 0x48, 0x43, 0x53, 0x46, -+0x1B, 0x1A, 0x98, 0x46, 0x23, 0x01, 0x1B, 0x19, 0x9B, 0x00, 0x99, 0x46, 0xA1, 0x44, 0x53, 0x46, 0x00, 0x2B, 0x05, 0xD1, -+0x34, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x78, 0x01, 0xC0, 0x1B, 0x80, 0x00, 0xC7, 0x19, -+0xB8, 0x00, 0x38, 0x18, 0x29, 0x00, 0xD3, 0xF7, 0x33, 0xFC, 0x44, 0x43, 0x27, 0x00, 0x65, 0x09, 0x73, 0x01, 0x2C, 0x4A, -+0x9A, 0x18, 0x11, 0x68, 0x2B, 0x4A, 0x11, 0x60, 0x2B, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1A, 0x68, 0x2A, 0x4B, 0x1A, 0x60, -+0x2A, 0x4B, 0x5A, 0x46, 0x1A, 0x60, 0x51, 0x46, 0x48, 0x46, 0xD3, 0xF7, 0xA3, 0xFC, 0x09, 0x05, 0x43, 0x46, 0x19, 0x43, -+0x26, 0x4B, 0x19, 0x60, 0x26, 0x4B, 0x52, 0x46, 0x1A, 0x60, 0x26, 0x4B, 0x00, 0x22, 0x1A, 0x60, 0x25, 0x4B, 0x9E, 0x22, -+0xFF, 0x32, 0x99, 0x5C, 0x09, 0x02, 0x01, 0x3A, 0x9A, 0x5C, 0x0A, 0x43, 0x12, 0x04, 0x9C, 0x21, 0xFF, 0x31, 0x58, 0x5C, -+0x00, 0x02, 0x01, 0x39, 0x59, 0x5C, 0x01, 0x43, 0x0A, 0x43, 0x1E, 0x49, 0x0A, 0x60, 0xA0, 0x22, 0xFF, 0x32, 0x98, 0x5C, -+0x00, 0x02, 0x01, 0x3A, 0x9C, 0x5C, 0x04, 0x43, 0x24, 0x04, 0x20, 0x00, 0x28, 0x43, 0x01, 0x35, 0x6D, 0x01, 0xEC, 0x1B, -+0x24, 0x04, 0x04, 0x43, 0x16, 0x4A, 0x14, 0x60, 0x9A, 0x22, 0xFF, 0x32, 0x98, 0x5C, 0x00, 0x02, 0x01, 0x3A, 0x9B, 0x5C, -+0x03, 0x43, 0x36, 0x02, 0x1E, 0x43, 0x01, 0x20, 0x06, 0x43, 0x11, 0x4B, 0x1E, 0x60, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, -+0xA2, 0x46, 0xAB, 0x46, 0xF8, 0xBD, 0xC0, 0x46, 0x08, 0x04, 0x60, 0x40, 0x28, 0x19, 0x16, 0x00, 0xDC, 0x05, 0x60, 0x40, -+0x5C, 0x06, 0x60, 0x40, 0xD8, 0x05, 0x60, 0x40, 0x60, 0x06, 0x60, 0x40, 0x50, 0x06, 0x60, 0x40, 0x54, 0x06, 0x60, 0x40, -+0x58, 0x06, 0x60, 0x40, 0x4C, 0x06, 0x60, 0x40, 0x20, 0xA3, 0x16, 0x00, 0x44, 0x06, 0x60, 0x40, 0x48, 0x06, 0x60, 0x40, -+0x40, 0x06, 0x60, 0x40, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x8F, 0xB0, 0x80, 0x46, -+0x0E, 0x00, 0x15, 0x00, 0x03, 0x93, 0xEF, 0xF3, 0x10, 0x83, 0x01, 0x22, 0x17, 0x00, 0x1F, 0x40, 0x1A, 0x42, 0x00, 0xD0, -+0xF6, 0xE2, 0x72, 0xB6, 0x00, 0x21, 0x5C, 0x20, 0x7D, 0xF7, 0xCE, 0xF9, 0x04, 0x1E, 0x00, 0xD1, 0x25, 0xE3, 0x00, 0x20, -+0x00, 0x2F, 0x00, 0xD0, 0xF1, 0xE2, 0x62, 0xB6, 0x00, 0x28, 0x00, 0xD1, 0xED, 0xE2, 0x0F, 0xB0, 0x3C, 0xBC, 0x90, 0x46, -+0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0xDE, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, -+0x0C, 0x20, 0x00, 0x2F, 0xEF, 0xD1, 0xEA, 0xE7, 0x00, 0x23, 0x06, 0x93, 0xEC, 0xE2, 0x01, 0x23, 0x06, 0x93, 0xE9, 0xE2, -+0x00, 0x23, 0x5B, 0x00, 0xD6, 0x4A, 0xD3, 0x18, 0x5F, 0x78, 0xBA, 0x46, 0xBF, 0xE0, 0x2F, 0x7B, 0xD4, 0x4B, 0x19, 0x00, -+0x00, 0x22, 0x08, 0x78, 0xB8, 0x42, 0x00, 0xD1, 0xAD, 0xE0, 0x01, 0x32, 0x02, 0x31, 0x08, 0x2A, 0xF7, 0xD1, 0x02, 0x27, -+0x68, 0x7B, 0x00, 0x22, 0x19, 0x78, 0x81, 0x42, 0x00, 0xD1, 0xA7, 0xE0, 0x01, 0x32, 0x02, 0x33, 0x08, 0x2A, 0xF7, 0xD1, -+0x02, 0x23, 0x9A, 0x46, 0x09, 0x2F, 0x05, 0xD9, 0xC5, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, -+0x07, 0x97, 0xD3, 0x46, 0xC4, 0x4A, 0x7B, 0x00, 0xDF, 0x19, 0xD7, 0x19, 0x53, 0x46, 0x5B, 0x00, 0x53, 0x44, 0xD2, 0x18, -+0xBF, 0x78, 0x93, 0x78, 0xFF, 0x18, 0xFB, 0xB2, 0x1F, 0x00, 0x05, 0x93, 0x28, 0x7C, 0x19, 0x00, 0xD3, 0xF7, 0x48, 0xFB, -+0xC0, 0xB2, 0xBC, 0x4B, 0x63, 0x62, 0xBC, 0x4B, 0xE3, 0x61, 0xBC, 0x4B, 0x23, 0x62, 0x03, 0x23, 0x23, 0x76, 0xBB, 0x4B, -+0x9B, 0x7A, 0xA3, 0x75, 0xBA, 0x4A, 0x9F, 0x23, 0x9B, 0x00, 0xD2, 0x5C, 0x00, 0x23, 0x00, 0x2A, 0x02, 0xD1, 0x7B, 0x00, -+0x03, 0x33, 0xDB, 0xB2, 0xE3, 0x75, 0x00, 0x23, 0xA3, 0x82, 0x06, 0x33, 0x63, 0x76, 0x40, 0x33, 0x42, 0x46, 0xE2, 0x54, -+0x01, 0x33, 0xE6, 0x54, 0xEB, 0x88, 0x23, 0x87, 0x2B, 0x89, 0x63, 0x87, 0xAA, 0x7A, 0x3D, 0x23, 0xE2, 0x54, 0xEA, 0x7A, -+0x01, 0x33, 0xE2, 0x54, 0x2A, 0x7B, 0x01, 0x33, 0xE2, 0x54, 0x6A, 0x7B, 0x01, 0x33, 0xE2, 0x54, 0xAA, 0x7B, 0x01, 0x33, -+0xE2, 0x54, 0xEA, 0x7B, 0x01, 0x33, 0xE2, 0x54, 0x6A, 0x7C, 0x01, 0x33, 0xE2, 0x54, 0x01, 0x33, 0xE0, 0x54, 0x9B, 0x4A, -+0xB0, 0x33, 0xD3, 0x58, 0x23, 0x63, 0xAA, 0x78, 0x4B, 0x23, 0xE2, 0x54, 0x2B, 0x7C, 0x05, 0x99, 0x8C, 0x46, 0x63, 0x44, -+0xEA, 0x7B, 0x9B, 0x1A, 0x5A, 0x42, 0x53, 0x41, 0x49, 0x22, 0xA3, 0x54, 0x45, 0x23, 0xE1, 0x54, 0x13, 0x33, 0x08, 0x9A, -+0xE2, 0x54, 0x01, 0x22, 0x31, 0x00, 0x01, 0x20, 0xA6, 0xF7, 0xF8, 0xF9, 0x03, 0x9B, 0x00, 0x2B, 0x00, 0xD0, 0x98, 0xE1, -+0x06, 0x99, 0x01, 0x31, 0x2A, 0x89, 0x4A, 0x43, 0xD3, 0xB2, 0x0C, 0x93, 0xEB, 0x88, 0x4B, 0x43, 0xDB, 0xB2, 0x0D, 0x93, -+0x2B, 0x79, 0x00, 0x22, 0x92, 0x46, 0x00, 0x2B, 0x02, 0xD0, 0xEA, 0x78, 0x04, 0x2A, 0x26, 0xD0, 0x68, 0x78, 0x03, 0x28, -+0x33, 0xD8, 0x2B, 0x78, 0x04, 0x2B, 0x30, 0xD8, 0x9B, 0x00, 0x88, 0x4A, 0xD3, 0x18, 0x1A, 0x5C, 0x0F, 0x23, 0x13, 0x40, -+0x0A, 0x93, 0x53, 0x11, 0x01, 0x21, 0x0B, 0x40, 0x03, 0x93, 0x12, 0x11, 0x11, 0x40, 0x0B, 0x91, 0x2C, 0xE0, 0x52, 0x00, -+0x79, 0x49, 0x8A, 0x18, 0x57, 0x78, 0x51, 0xE7, 0x52, 0x00, 0x77, 0x4B, 0x9A, 0x18, 0x53, 0x78, 0x9A, 0x46, 0x09, 0x2F, -+0x00, 0xD9, 0x57, 0xE7, 0x53, 0x46, 0x09, 0x2B, 0x00, 0xD9, 0x53, 0xE7, 0x58, 0xE7, 0x01, 0x2B, 0x0A, 0xD0, 0x02, 0x3B, -+0x5A, 0x42, 0x53, 0x41, 0x5B, 0x42, 0x76, 0x4A, 0x13, 0x40, 0x9A, 0x46, 0x75, 0x4B, 0x9C, 0x46, 0xE2, 0x44, 0xCB, 0xE7, -+0x74, 0x4B, 0x9A, 0x46, 0xC8, 0xE7, 0x29, 0x78, 0x66, 0x4B, 0xDB, 0x6E, 0x98, 0x46, 0x00, 0x23, 0x00, 0x22, 0xC0, 0x47, -+0x03, 0x9B, 0x0B, 0x93, 0x00, 0x23, 0x0A, 0x93, 0x2B, 0x79, 0x0E, 0x2B, 0x00, 0xD1, 0xBC, 0xE0, 0x00, 0xD9, 0xAC, 0xE0, -+0x00, 0x22, 0x06, 0x92, 0x08, 0x2B, 0x04, 0xD0, 0x01, 0x32, 0x06, 0x92, 0x0D, 0x2B, 0x00, 0xD0, 0xA8, 0xE0, 0xEB, 0x78, -+0x5A, 0x1E, 0x03, 0x2A, 0x00, 0xD9, 0xE3, 0xE0, 0xD3, 0xB2, 0x08, 0x93, 0x63, 0x4A, 0x13, 0x68, 0x63, 0x49, 0x19, 0x40, -+0x80, 0x23, 0x9B, 0x02, 0x0B, 0x43, 0x13, 0x60, 0x13, 0x68, 0x61, 0x49, 0x0B, 0x40, 0x80, 0x21, 0x49, 0x02, 0x8C, 0x46, -+0x0B, 0x43, 0x13, 0x60, 0x73, 0x01, 0x98, 0x46, 0x5D, 0x4A, 0x42, 0x44, 0x85, 0x23, 0x1B, 0x04, 0x51, 0x46, 0x0B, 0x43, -+0x13, 0x60, 0x5B, 0x4B, 0x43, 0x44, 0x9A, 0x46, 0x4B, 0x4A, 0x5B, 0x46, 0x59, 0x00, 0x59, 0x44, 0x53, 0x18, 0x5B, 0x78, -+0x1B, 0x01, 0xA8, 0x7A, 0x03, 0x43, 0xE8, 0x7A, 0x02, 0x38, 0x07, 0x00, 0x78, 0x42, 0x78, 0x41, 0xC0, 0x00, 0x03, 0x43, -+0x07, 0x9F, 0x78, 0x00, 0xBB, 0x46, 0x58, 0x44, 0x17, 0x18, 0x7F, 0x78, 0x7F, 0x01, 0x3B, 0x43, 0x67, 0x46, 0x3B, 0x43, -+0x57, 0x46, 0x3B, 0x60, 0x4C, 0x4B, 0x43, 0x44, 0x9A, 0x46, 0x2B, 0x89, 0x1B, 0x05, 0x9C, 0x46, 0xEB, 0x88, 0x1B, 0x01, -+0x67, 0x46, 0x3B, 0x43, 0x80, 0x5C, 0x03, 0x43, 0x88, 0x5C, 0x00, 0x04, 0x03, 0x43, 0x52, 0x46, 0x13, 0x60, 0x03, 0x9B, -+0xDB, 0x03, 0x0A, 0x9A, 0x12, 0x02, 0x13, 0x43, 0x0B, 0x9A, 0xD2, 0x01, 0x13, 0x43, 0x06, 0x9A, 0x12, 0x05, 0x13, 0x43, -+0x08, 0x9A, 0x12, 0x04, 0x13, 0x43, 0x3E, 0x4A, 0xB2, 0x18, 0x92, 0x00, 0x13, 0x60, 0xB3, 0x00, 0x3C, 0x4A, 0x9C, 0x50, -+0x4B, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x00, 0xD1, 0x87, 0xE0, 0x32, 0x01, 0xB2, 0x18, 0xD3, 0x01, 0x9B, 0x1A, 0xF3, 0x18, -+0x37, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x9B, 0xB2, 0x36, 0x49, 0x41, 0x44, 0x0C, 0x98, 0xC2, 0x18, 0x12, 0x04, 0x13, 0x43, -+0x0B, 0x60, 0x87, 0x23, 0xDB, 0x00, 0x73, 0x43, 0x84, 0x46, 0x63, 0x44, 0x31, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x5B, 0x00, -+0x9B, 0xB2, 0x30, 0x49, 0x41, 0x44, 0x0D, 0x9A, 0x9A, 0x18, 0x92, 0xB2, 0x1B, 0x04, 0x13, 0x43, 0x0B, 0x60, 0x2D, 0x4B, -+0x43, 0x44, 0xE9, 0x7B, 0x80, 0x22, 0xD2, 0x01, 0x0A, 0x43, 0x1A, 0x60, 0x29, 0x89, 0x00, 0x29, 0x04, 0xD1, 0xEB, 0x88, -+0x01, 0x31, 0x00, 0x2B, 0x00, 0xD0, 0x19, 0x00, 0x00, 0x2E, 0x00, 0xD0, 0xDA, 0xE0, 0xEA, 0x7B, 0x89, 0xB2, 0x00, 0x20, -+0xFF, 0xF7, 0x72, 0xFD, 0xD4, 0xE0, 0x03, 0x22, 0x06, 0x92, 0x10, 0x2B, 0x00, 0xD1, 0x56, 0xE7, 0x05, 0x4B, 0x9B, 0x6E, -+0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x00, 0x23, 0x06, 0x93, 0x4D, 0xE7, 0x02, 0x23, 0x06, 0x93, 0x4A, 0xE7, -+0x28, 0x19, 0x16, 0x00, 0xE4, 0xDF, 0x10, 0x00, 0xD4, 0xDF, 0x10, 0x00, 0xE8, 0xDF, 0x10, 0x00, 0x69, 0xF5, 0x0A, 0x00, -+0x21, 0x61, 0x10, 0x00, 0x4D, 0xF3, 0x0A, 0x00, 0x7C, 0x91, 0x0D, 0x00, 0x7C, 0x1E, 0x16, 0x00, 0x08, 0xE0, 0x10, 0x00, -+0x00, 0xA0, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0xD0, 0x04, 0x60, 0x40, 0xFF, 0xFF, 0xFD, 0xFF, -+0xFF, 0xFF, 0xFE, 0xFF, 0xD4, 0x05, 0x60, 0x40, 0xE0, 0x05, 0x60, 0x40, 0xE4, 0x05, 0x60, 0x40, 0x8C, 0x01, 0x18, 0x10, -+0x54, 0x27, 0x16, 0x00, 0x5C, 0xAB, 0xFF, 0xFF, 0xD8, 0x05, 0x60, 0x40, 0xAE, 0x55, 0x00, 0x00, 0xDC, 0x05, 0x60, 0x40, -+0xD0, 0x05, 0x60, 0x40, 0x96, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x00, 0x23, 0x08, 0x93, -+0x14, 0xE7, 0x42, 0x33, 0xE3, 0x5C, 0x5F, 0x1E, 0x20, 0x00, 0x50, 0x30, 0x7F, 0xF7, 0xF0, 0xFA, 0x49, 0x23, 0xE1, 0x5C, -+0xCB, 0x1C, 0xDB, 0xB2, 0x04, 0x31, 0xC9, 0xB2, 0x8B, 0x4A, 0x92, 0x46, 0x0D, 0x9A, 0x04, 0x32, 0xD2, 0xB2, 0x00, 0x92, -+0x84, 0x22, 0x50, 0x46, 0x82, 0x58, 0x93, 0x46, 0x0C, 0x9A, 0x30, 0x00, 0xD8, 0x47, 0x86, 0x4A, 0x42, 0x44, 0x00, 0x23, -+0x13, 0x60, 0x85, 0x4A, 0x42, 0x44, 0x13, 0x60, 0x19, 0x33, 0xFF, 0x33, 0x52, 0x46, 0xD0, 0x58, 0x31, 0x00, 0xD2, 0xF7, -+0x47, 0xFB, 0x81, 0x4A, 0x11, 0x68, 0x80, 0x23, 0x9B, 0x01, 0xB3, 0x40, 0x0B, 0x43, 0x13, 0x60, 0x7E, 0x4A, 0x42, 0x44, -+0xFF, 0x23, 0x3B, 0x40, 0x1F, 0x2B, 0x00, 0xD9, 0x1F, 0x23, 0x1B, 0x02, 0xE9, 0x7B, 0x0B, 0x43, 0x09, 0x99, 0x03, 0x39, -+0x48, 0x42, 0x41, 0x41, 0xC9, 0x03, 0x0B, 0x43, 0xC0, 0x21, 0xC9, 0x01, 0x0B, 0x43, 0x13, 0x60, 0x42, 0xE0, 0x75, 0x4B, -+0xF2, 0x18, 0x52, 0x01, 0x74, 0x49, 0x5B, 0x46, 0x58, 0x00, 0x58, 0x44, 0x0B, 0x18, 0x5B, 0x78, 0x1B, 0x01, 0xAF, 0x7A, -+0x1F, 0x43, 0xBC, 0x46, 0xEB, 0x7A, 0x02, 0x3B, 0x1F, 0x00, 0x7B, 0x42, 0x7B, 0x41, 0xDB, 0x00, 0x67, 0x46, 0x3B, 0x43, -+0x9A, 0x46, 0x07, 0x9F, 0x7B, 0x00, 0x98, 0x46, 0xBC, 0x46, 0xE0, 0x44, 0x8C, 0x46, 0xC4, 0x44, 0x63, 0x46, 0x5B, 0x78, -+0x5B, 0x01, 0x1F, 0x00, 0x53, 0x46, 0x1F, 0x43, 0x80, 0x23, 0x5B, 0x02, 0x3B, 0x43, 0x13, 0x60, 0x2B, 0x89, 0x1B, 0x05, -+0xED, 0x88, 0x2D, 0x01, 0x2B, 0x43, 0x45, 0x46, 0x6D, 0x5C, 0x2B, 0x43, 0x41, 0x5C, 0x09, 0x04, 0x0B, 0x43, 0x53, 0x60, -+0x31, 0x01, 0x71, 0x18, 0xCB, 0x01, 0x5B, 0x1A, 0xF3, 0x18, 0x5B, 0x49, 0x8C, 0x46, 0x63, 0x44, 0x98, 0xB2, 0x11, 0x00, -+0x08, 0x39, 0x1B, 0x04, 0x03, 0x43, 0x0B, 0x60, 0x04, 0x3A, 0x13, 0x60, 0xEF, 0xF3, 0x10, 0x83, 0x01, 0x22, 0x11, 0x00, -+0x19, 0x40, 0x88, 0x46, 0x1A, 0x42, 0x00, 0xD1, 0x72, 0xB6, 0x52, 0x4B, 0x05, 0x9A, 0x53, 0x43, 0x9B, 0xB2, 0x42, 0x22, -+0xA2, 0x5C, 0x52, 0x00, 0x44, 0x21, 0x61, 0x5C, 0x48, 0x1E, 0x81, 0x41, 0x00, 0x91, 0x31, 0x00, 0x0B, 0x20, 0xD3, 0xF7, -+0x41, 0xF8, 0x4B, 0x46, 0xDB, 0x07, 0x33, 0xD4, 0x4B, 0x46, 0x1F, 0x01, 0x3F, 0x09, 0x41, 0x23, 0xE5, 0x5C, 0x02, 0x33, -+0xE3, 0x5C, 0x9B, 0x06, 0x7F, 0x08, 0x5F, 0x40, 0x42, 0x23, 0xE3, 0x5C, 0x99, 0x46, 0x00, 0x2B, 0x05, 0xD1, 0x39, 0x4B, -+0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x49, 0x46, 0x38, 0x00, 0xD3, 0xF7, 0x63, 0xF9, 0x69, 0x1A, -+0x00, 0x29, 0x21, 0xDD, 0x42, 0x23, 0xE3, 0x5C, 0xC9, 0x1A, 0x49, 0x00, 0x58, 0x00, 0x04, 0x9A, 0x94, 0x46, 0x60, 0x44, -+0x09, 0x18, 0x09, 0x01, 0x09, 0x09, 0x61, 0x63, 0x02, 0x2B, 0x02, 0xD9, 0x30, 0x00, 0x34, 0x4B, 0x98, 0x47, 0x00, 0x20, -+0x43, 0x46, 0x00, 0x2B, 0x00, 0xD0, 0x28, 0xE5, 0x62, 0xB6, 0x26, 0xE5, 0x30, 0x4F, 0x4B, 0x46, 0x3B, 0x40, 0x1F, 0x00, -+0x04, 0x98, 0x01, 0x38, 0x00, 0x01, 0x03, 0x09, 0x04, 0x93, 0xC4, 0xE7, 0x42, 0x23, 0xE3, 0x5C, 0xC9, 0x18, 0xD9, 0xE7, -+0x00, 0x21, 0x5C, 0x20, 0x7C, 0xF7, 0xD8, 0xFE, 0x04, 0x1E, 0x00, 0xD1, 0x18, 0xE5, 0x43, 0x46, 0x9B, 0x00, 0x26, 0x4A, -+0x9F, 0x58, 0x6B, 0x78, 0x09, 0x93, 0x03, 0x2B, 0x00, 0xD1, 0x19, 0xE5, 0xAB, 0x78, 0x01, 0x2B, 0x00, 0xD1, 0x18, 0xE5, -+0x2A, 0x79, 0x08, 0x23, 0x93, 0x42, 0x9B, 0x41, 0x5B, 0x42, 0x06, 0x93, 0x06, 0x9B, 0x08, 0x93, 0xA6, 0xF7, 0x1C, 0xFA, -+0x04, 0x90, 0xBB, 0x6F, 0x81, 0x46, 0x99, 0x44, 0x5C, 0x22, 0x00, 0x21, 0x20, 0x00, 0x7A, 0xF7, 0x67, 0xFE, 0xEB, 0x7A, -+0x00, 0x2B, 0x00, 0xD0, 0x0B, 0xE5, 0x2B, 0x7B, 0x00, 0x2B, 0x00, 0xD1, 0x00, 0xE5, 0x02, 0x22, 0x92, 0x46, 0x02, 0x27, -+0x02, 0x2B, 0x00, 0xD0, 0x22, 0xE5, 0x01, 0x3B, 0xF9, 0xE4, 0x04, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, -+0x98, 0x47, 0x0C, 0x20, 0xD5, 0xE4, 0xC0, 0x46, 0x28, 0x19, 0x16, 0x00, 0xD8, 0x05, 0x60, 0x40, 0xDC, 0x05, 0x60, 0x40, -+0x0C, 0x04, 0x60, 0x40, 0xD0, 0x05, 0x60, 0x40, 0x2F, 0x00, 0x03, 0x02, 0xE8, 0xDF, 0x10, 0x00, 0x5C, 0xAB, 0xFF, 0xFF, -+0xE2, 0x04, 0x00, 0x00, 0x3D, 0xF4, 0x0A, 0x00, 0xFE, 0xFF, 0xFF, 0x0F, 0x38, 0x27, 0x16, 0x00, 0x00, 0x20, 0x70, 0x47, -+0x10, 0xB5, 0xEF, 0xF3, 0x10, 0x83, 0x01, 0x22, 0x14, 0x00, 0x1C, 0x40, 0x1A, 0x42, 0x00, 0xD1, 0x72, 0xB6, 0x5A, 0x4B, -+0x1B, 0x68, 0xDB, 0x05, 0x0B, 0xD5, 0x58, 0x49, 0x0B, 0x68, 0x5B, 0x00, 0x5B, 0x08, 0x80, 0x22, 0x12, 0x06, 0x13, 0x43, -+0x0B, 0x60, 0x0A, 0x00, 0x13, 0x68, 0x00, 0x2B, 0xFC, 0xDB, 0x53, 0x4B, 0x1B, 0x68, 0xDB, 0x05, 0x0B, 0xD5, 0x51, 0x49, -+0x0B, 0x68, 0x5B, 0x00, 0x5B, 0x08, 0x80, 0x22, 0x12, 0x06, 0x13, 0x43, 0x0B, 0x60, 0x0A, 0x00, 0x13, 0x68, 0x00, 0x2B, -+0xFC, 0xDB, 0x7A, 0xF7, 0x4F, 0xFF, 0x4B, 0x4B, 0x18, 0x68, 0x00, 0x28, 0x09, 0xD0, 0x7C, 0xF7, 0xF5, 0xFE, 0x48, 0x4B, -+0x00, 0x22, 0x1A, 0x60, 0x47, 0x4A, 0x13, 0x68, 0x04, 0x21, 0x8B, 0x43, 0x13, 0x60, 0x46, 0x4B, 0x11, 0x22, 0x44, 0x21, -+0x5A, 0x54, 0x40, 0x31, 0x5A, 0x54, 0x40, 0x31, 0x5A, 0x54, 0x40, 0x31, 0x5A, 0x54, 0x40, 0x31, 0x5A, 0x54, 0x10, 0x3A, -+0x40, 0x49, 0x5A, 0x54, 0x40, 0x49, 0x5A, 0x54, 0x40, 0x4A, 0x00, 0x21, 0x99, 0x54, 0x40, 0x4B, 0x1B, 0x68, 0x01, 0x2B, -+0x47, 0xD9, 0x39, 0x4B, 0x1A, 0x68, 0x08, 0x21, 0x8A, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x01, 0x20, 0x82, 0x43, 0x1A, 0x60, -+0x1A, 0x68, 0x06, 0x39, 0x8A, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x38, 0x49, 0x0A, 0x40, 0x1A, 0x60, 0x1A, 0x68, 0x12, 0x04, -+0x12, 0x0C, 0xB0, 0x21, 0x49, 0x03, 0x0A, 0x43, 0x1A, 0x60, 0x34, 0x4A, 0xA0, 0x23, 0x9B, 0x00, 0xD0, 0x54, 0x29, 0x4A, -+0x13, 0x68, 0x0F, 0x21, 0x0B, 0x43, 0x13, 0x60, 0x30, 0x4A, 0x13, 0x68, 0x30, 0x49, 0x19, 0x40, 0xA0, 0x23, 0xDB, 0x03, -+0x0B, 0x43, 0x13, 0x60, 0x13, 0x68, 0xFF, 0x21, 0x8B, 0x43, 0xAF, 0x39, 0x0B, 0x43, 0x13, 0x60, 0x2B, 0x4B, 0x2C, 0x4A, -+0x9A, 0x60, 0x2C, 0x4A, 0xDA, 0x60, 0x2C, 0x4A, 0x5A, 0x61, 0x2C, 0x4A, 0x9A, 0x61, 0x00, 0x2C, 0x00, 0xD1, 0x62, 0xB6, -+0x00, 0x23, 0x2A, 0x4A, 0x13, 0x60, 0x2A, 0x4A, 0x13, 0x60, 0x2A, 0x4A, 0x13, 0x60, 0x0A, 0x22, 0x29, 0x49, 0x2A, 0x48, -+0xD3, 0xF7, 0x10, 0xFC, 0x10, 0xBD, 0x15, 0x4B, 0x1A, 0x68, 0x08, 0x31, 0x0A, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x07, 0x39, -+0x8A, 0x43, 0x0A, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x02, 0x20, 0x02, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x13, 0x48, 0x10, 0x40, -+0x80, 0x22, 0x92, 0x01, 0x02, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x12, 0x04, 0x12, 0x0C, 0xB0, 0x20, 0x40, 0x03, 0x02, 0x43, -+0x1A, 0x60, 0x0E, 0x4A, 0xA0, 0x23, 0x9B, 0x00, 0xD1, 0x54, 0x19, 0x4B, 0x19, 0x4A, 0x1A, 0x60, 0xAF, 0xE7, 0xC0, 0x46, -+0x00, 0x04, 0x60, 0x40, 0x00, 0x08, 0x60, 0x40, 0xF8, 0xE6, 0x10, 0x00, 0xFC, 0x00, 0x60, 0x40, 0xEC, 0xA4, 0x16, 0x00, -+0x1E, 0x03, 0x00, 0x00, 0x6F, 0x04, 0x00, 0x00, 0x6D, 0x04, 0x00, 0x00, 0x50, 0xE0, 0x10, 0x00, 0xFF, 0xDF, 0xFF, 0xFF, -+0x7C, 0x1E, 0x16, 0x00, 0x8C, 0x04, 0x60, 0x40, 0xFF, 0xFF, 0x00, 0xFF, 0x60, 0x92, 0x16, 0x00, 0x2D, 0x01, 0x10, 0x00, -+0x81, 0x01, 0x10, 0x00, 0x8D, 0x05, 0x10, 0x00, 0xB9, 0x00, 0x10, 0x00, 0x58, 0xE6, 0x10, 0x00, 0x5C, 0xE6, 0x10, 0x00, -+0x54, 0xE6, 0x10, 0x00, 0xD8, 0xE1, 0x10, 0x00, 0xC0, 0x9F, 0x16, 0x00, 0x30, 0x10, 0x62, 0x40, 0x15, 0x1C, 0x20, 0x00, -+0xF8, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x70, 0x4B, 0x1B, 0x68, 0x1B, 0x07, 0x0B, 0xD5, -+0x6F, 0x4A, 0x13, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x6C, 0x4A, 0x13, 0x68, 0x08, 0x21, 0x8B, 0x43, 0x13, 0x60, 0x6B, 0x4B, -+0x01, 0x22, 0x1A, 0x60, 0x6A, 0x4C, 0x23, 0x68, 0x6A, 0x4E, 0x33, 0x40, 0x23, 0x60, 0x6A, 0x4D, 0x2B, 0x68, 0x6A, 0x4F, -+0x3B, 0x40, 0x2B, 0x60, 0x83, 0xF7, 0xEE, 0xFA, 0x23, 0x68, 0x68, 0x4A, 0x13, 0x40, 0x23, 0x60, 0x2B, 0x68, 0x33, 0x40, -+0x2B, 0x60, 0x23, 0x68, 0x1F, 0x40, 0x80, 0x23, 0x5B, 0x00, 0x3B, 0x43, 0x23, 0x60, 0x23, 0x68, 0x1E, 0x40, 0x80, 0x23, -+0x9B, 0x00, 0x33, 0x43, 0x23, 0x60, 0x60, 0x4B, 0x99, 0x46, 0xFF, 0x23, 0x9B, 0x46, 0x22, 0x00, 0xC0, 0x3B, 0x98, 0x46, -+0x5D, 0x4B, 0x9C, 0x46, 0x40, 0x25, 0x80, 0x21, 0x09, 0x01, 0x5F, 0x46, 0x5E, 0x46, 0x04, 0x36, 0xF3, 0xB2, 0x9B, 0x46, -+0x4C, 0x46, 0x18, 0x00, 0x13, 0x68, 0x46, 0x46, 0xB3, 0x43, 0x03, 0x43, 0x13, 0x60, 0x63, 0x46, 0x26, 0x68, 0x1E, 0x60, -+0x13, 0x68, 0xAB, 0x43, 0x2B, 0x43, 0x13, 0x60, 0xC0, 0x46, 0xC0, 0x46, 0xC0, 0x46, 0xC0, 0x46, 0x13, 0x68, 0x0B, 0x42, -+0xFC, 0xD0, 0x01, 0x38, 0xC0, 0xB2, 0x04, 0x34, 0xB8, 0x42, 0xE7, 0xD1, 0x10, 0x23, 0x9A, 0x46, 0xD1, 0x44, 0x5B, 0x46, -+0x0F, 0x2B, 0xDA, 0xD1, 0x42, 0x4C, 0x23, 0x68, 0x44, 0x4D, 0x2B, 0x40, 0x23, 0x60, 0x83, 0xF7, 0xAA, 0xFA, 0x23, 0x68, -+0x3F, 0x4A, 0x13, 0x40, 0x23, 0x60, 0x3F, 0x4B, 0x1A, 0x68, 0x80, 0x21, 0x0A, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x15, 0x40, -+0x80, 0x22, 0x52, 0x00, 0x2A, 0x43, 0x1A, 0x60, 0x3E, 0x4B, 0x9A, 0x46, 0xFF, 0x24, 0x38, 0x4A, 0x1F, 0x23, 0x99, 0x46, -+0x3C, 0x4B, 0x98, 0x46, 0x20, 0x26, 0x80, 0x21, 0xC9, 0x00, 0x04, 0xE0, 0x08, 0x23, 0x9C, 0x46, 0xE2, 0x44, 0x1F, 0x2C, -+0x1D, 0xD0, 0xA4, 0x46, 0x02, 0x34, 0xE4, 0xB2, 0x55, 0x46, 0x20, 0x00, 0x13, 0x68, 0x4F, 0x46, 0xBB, 0x43, 0x03, 0x43, -+0x13, 0x60, 0x43, 0x46, 0x2F, 0x68, 0x1F, 0x60, 0x13, 0x68, 0xB3, 0x43, 0x33, 0x43, 0x13, 0x60, 0xC0, 0x46, 0xC0, 0x46, -+0xC0, 0x46, 0xC0, 0x46, 0x13, 0x68, 0x0B, 0x42, 0xFC, 0xD0, 0x01, 0x38, 0xC0, 0xB2, 0x04, 0x35, 0x60, 0x45, 0xE7, 0xD1, -+0xDC, 0xE7, 0x22, 0x4C, 0x23, 0x68, 0x80, 0x22, 0x93, 0x43, 0x23, 0x60, 0x83, 0xF7, 0x65, 0xFA, 0x23, 0x68, 0x1F, 0x4D, -+0x2B, 0x40, 0x23, 0x60, 0x23, 0x49, 0x0B, 0x68, 0x23, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0x5B, 0x02, 0x13, 0x43, 0x0B, 0x60, -+0x83, 0xF7, 0x50, 0xFA, 0x15, 0x49, 0x0B, 0x68, 0x18, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0xDB, 0x00, 0x13, 0x43, 0x0B, 0x60, -+0x0B, 0x68, 0x12, 0x48, 0x03, 0x40, 0x80, 0x22, 0x92, 0x00, 0x13, 0x43, 0x0B, 0x60, 0x23, 0x68, 0x03, 0x40, 0x1A, 0x43, -+0x22, 0x60, 0x23, 0x68, 0x1D, 0x40, 0x80, 0x23, 0x5B, 0x00, 0x2B, 0x43, 0x23, 0x60, 0x14, 0x49, 0x0B, 0x68, 0x14, 0x4A, -+0x1A, 0x40, 0x80, 0x23, 0x5B, 0x03, 0x13, 0x43, 0x0B, 0x60, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, -+0xF8, 0xBD, 0xC0, 0x46, 0x18, 0x00, 0x58, 0x40, 0x40, 0x42, 0x04, 0x40, 0x58, 0x20, 0x62, 0x40, 0xFF, 0xFD, 0xFF, 0xFF, -+0x64, 0x20, 0x62, 0x40, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xD8, 0x97, 0x16, 0x00, 0x5C, 0x20, 0x62, 0x40, -+0xD8, 0x98, 0x16, 0x00, 0x68, 0x20, 0x62, 0x40, 0x4C, 0x20, 0x62, 0x40, 0xFF, 0xFF, 0xFE, 0xFF, 0x30, 0x20, 0x62, 0x40, -+0xFF, 0xFF, 0xEF, 0xFF, 0xF8, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x6E, 0x4C, 0x23, 0x68, -+0x6E, 0x4E, 0x33, 0x40, 0x23, 0x60, 0x6E, 0x4D, 0x2B, 0x68, 0x6E, 0x4A, 0x13, 0x40, 0x2B, 0x60, 0x83, 0xF7, 0xF8, 0xF9, -+0x23, 0x68, 0x6C, 0x4A, 0x13, 0x40, 0x23, 0x60, 0x2B, 0x68, 0x6B, 0x4A, 0x13, 0x40, 0x2B, 0x60, 0x23, 0x68, 0x6A, 0x4A, -+0x1A, 0x40, 0x80, 0x23, 0xDB, 0x00, 0x13, 0x43, 0x23, 0x60, 0x23, 0x68, 0x1E, 0x40, 0x80, 0x23, 0x1B, 0x01, 0x33, 0x43, -+0x23, 0x60, 0x65, 0x4B, 0x9A, 0x46, 0x7F, 0x25, 0x22, 0x00, 0xFF, 0x23, 0x99, 0x46, 0x63, 0x4B, 0x98, 0x46, 0x5D, 0x4B, -+0x9C, 0x46, 0x80, 0x21, 0x89, 0x01, 0x2E, 0x00, 0x04, 0x35, 0xED, 0xB2, 0x54, 0x46, 0x28, 0x00, 0x13, 0x68, 0x4F, 0x46, -+0xBB, 0x43, 0x03, 0x43, 0x13, 0x60, 0x43, 0x46, 0x27, 0x68, 0x1F, 0x60, 0x13, 0x68, 0x67, 0x46, 0x3B, 0x40, 0x80, 0x27, -+0x7F, 0x00, 0x3B, 0x43, 0x13, 0x60, 0xC0, 0x46, 0xC0, 0x46, 0xC0, 0x46, 0xC0, 0x46, 0x13, 0x68, 0x0B, 0x42, 0xFC, 0xD0, -+0x01, 0x38, 0xC0, 0xB2, 0x04, 0x34, 0x86, 0x42, 0xE4, 0xD1, 0x10, 0x23, 0x9B, 0x46, 0xDA, 0x44, 0x8F, 0x2D, 0xDA, 0xD1, -+0x45, 0x4C, 0x23, 0x68, 0x4A, 0x4A, 0x13, 0x40, 0x23, 0x60, 0x83, 0xF7, 0xB2, 0xF9, 0x23, 0x68, 0x42, 0x4A, 0x13, 0x40, -+0x23, 0x60, 0x42, 0x4B, 0x1A, 0x68, 0x80, 0x21, 0x0A, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x40, 0x49, 0x11, 0x40, 0x80, 0x22, -+0x52, 0x00, 0x0A, 0x43, 0x1A, 0x60, 0x10, 0x20, 0x1A, 0x00, 0x1F, 0x27, 0x41, 0x4E, 0x42, 0x4D, 0x20, 0x24, 0x80, 0x21, -+0xC9, 0x00, 0x13, 0x68, 0xBB, 0x43, 0x03, 0x43, 0x13, 0x60, 0x83, 0x00, 0xF3, 0x58, 0x2B, 0x60, 0x13, 0x68, 0xA3, 0x43, -+0x23, 0x43, 0x13, 0x60, 0xC0, 0x46, 0xC0, 0x46, 0xC0, 0x46, 0xC0, 0x46, 0x13, 0x68, 0x0B, 0x42, 0xFC, 0xD0, 0x01, 0x30, -+0x20, 0x28, 0xEA, 0xD1, 0x2D, 0x4C, 0x23, 0x68, 0x80, 0x22, 0x93, 0x43, 0x23, 0x60, 0x83, 0xF7, 0x7E, 0xF9, 0x23, 0x68, -+0x2A, 0x4A, 0x13, 0x40, 0x23, 0x60, 0x31, 0x4A, 0x13, 0x68, 0x00, 0x2B, 0xFC, 0xD0, 0x30, 0x4A, 0x13, 0x68, 0x02, 0x21, -+0x8B, 0x43, 0x13, 0x60, 0x2C, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x2D, 0x4A, 0x13, 0x68, 0x2D, 0x49, 0x0B, 0x40, 0x13, 0x60, -+0x2C, 0x4B, 0x00, 0x22, 0x1A, 0x60, 0x83, 0xF7, 0x5D, 0xF9, 0x1B, 0x49, 0x0B, 0x68, 0x1E, 0x4A, 0x13, 0x40, 0x80, 0x22, -+0x52, 0x01, 0x13, 0x43, 0x0B, 0x60, 0x0B, 0x68, 0x17, 0x48, 0x18, 0x40, 0x80, 0x23, 0x1B, 0x01, 0x03, 0x43, 0x0B, 0x60, -+0x15, 0x4B, 0x19, 0x68, 0x17, 0x48, 0x08, 0x40, 0x80, 0x21, 0x89, 0x00, 0x01, 0x43, 0x19, 0x60, 0x19, 0x68, 0x12, 0x48, -+0x08, 0x40, 0x80, 0x21, 0x49, 0x00, 0x01, 0x43, 0x19, 0x60, 0x1C, 0x4B, 0x19, 0x68, 0x0A, 0x43, 0x1A, 0x60, 0x1B, 0x4A, -+0x13, 0x68, 0x1B, 0x49, 0x0B, 0x40, 0x13, 0x60, 0x1A, 0x4B, 0x1A, 0x68, 0x1A, 0x49, 0x0A, 0x40, 0x1A, 0x60, 0x19, 0x68, -+0x80, 0x22, 0xD2, 0x05, 0x0A, 0x43, 0x1A, 0x60, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF8, 0xBD, -+0x60, 0x40, 0x34, 0x40, 0xFF, 0xF7, 0xFF, 0xFF, 0x6C, 0x40, 0x34, 0x40, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, -+0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xD8, 0x9B, 0x16, 0x00, 0x64, 0x40, 0x34, 0x40, 0x58, 0x99, 0x16, 0x00, -+0x70, 0x40, 0x34, 0x40, 0x40, 0x42, 0x04, 0x40, 0x18, 0x00, 0x58, 0x40, 0x58, 0x40, 0x34, 0x40, 0xFF, 0xFF, 0xFF, 0xFB, -+0x08, 0x40, 0x34, 0x40, 0x14, 0x20, 0x34, 0x40, 0x18, 0x20, 0x34, 0x40, 0xFF, 0xFF, 0xFB, 0xFF, 0x1C, 0x20, 0x34, 0x40, -+0xFF, 0xFF, 0xFF, 0xDF, 0x10, 0xB5, 0x07, 0x49, 0x0A, 0x69, 0x0F, 0x24, 0xA2, 0x43, 0x03, 0x20, 0x02, 0x43, 0x0A, 0x61, -+0xCB, 0x69, 0xA3, 0x43, 0x03, 0x43, 0xCB, 0x61, 0x02, 0x48, 0x7E, 0xF7, 0xA1, 0xFB, 0x10, 0xBD, 0x00, 0x30, 0x50, 0x40, -+0x94, 0xD1, 0x10, 0x00, 0x70, 0xB5, 0x1B, 0x4B, 0x9B, 0x69, 0xDB, 0x05, 0x1F, 0xD4, 0x0C, 0x38, 0xEF, 0xF3, 0x10, 0x83, -+0x01, 0x22, 0x14, 0x00, 0x1C, 0x40, 0x1A, 0x42, 0x00, 0xD1, 0x72, 0xB6, 0x15, 0x4B, 0x1B, 0x7F, 0x01, 0x2B, 0x1C, 0xD0, -+0xCF, 0xF7, 0x62, 0xF8, 0x12, 0x4B, 0x1B, 0x7F, 0xFF, 0x2B, 0x1A, 0xD0, 0x02, 0x20, 0x7B, 0xF7, 0xCB, 0xF9, 0xFF, 0xF7, -+0xCF, 0xFF, 0x0F, 0x4B, 0x80, 0x22, 0x12, 0x04, 0x1A, 0x60, 0x00, 0x2C, 0x00, 0xD1, 0x62, 0xB6, 0x70, 0xBD, 0x0C, 0x4D, -+0xC4, 0x24, 0x64, 0x00, 0x00, 0x23, 0x2B, 0x51, 0xCE, 0xF7, 0xCC, 0xF8, 0x09, 0x4B, 0x2B, 0x51, 0xF4, 0xE7, 0x05, 0x4B, -+0xFF, 0x22, 0x1A, 0x77, 0xDE, 0xE7, 0x03, 0x4B, 0x01, 0x22, 0x1A, 0x77, 0xE0, 0xE7, 0xC0, 0x46, 0x3C, 0x95, 0x16, 0x00, -+0x24, 0x2A, 0x16, 0x00, 0x00, 0x41, 0x04, 0x40, 0x28, 0x19, 0x16, 0x00, 0xB9, 0x5A, 0x10, 0x00, 0x01, 0x28, 0x02, 0xD0, -+0x02, 0x28, 0x05, 0xD0, 0x70, 0x47, 0x05, 0x4B, 0x80, 0x22, 0x92, 0x04, 0x1A, 0x60, 0xF9, 0xE7, 0x02, 0x4B, 0x80, 0x22, -+0x52, 0x04, 0x1A, 0x60, 0xF4, 0xE7, 0xC0, 0x46, 0x00, 0x41, 0x04, 0x40, 0x15, 0x4B, 0x16, 0x4A, 0x13, 0x60, 0x16, 0x4A, -+0x13, 0x60, 0x16, 0x4B, 0x1A, 0x68, 0x30, 0x21, 0x8A, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x90, 0x31, 0x8A, 0x43, 0x1A, 0x60, -+0x1A, 0x68, 0x12, 0x49, 0x0A, 0x40, 0x1A, 0x60, 0x1A, 0x68, 0x11, 0x49, 0x0A, 0x40, 0x1A, 0x60, 0x1A, 0x68, 0x10, 0x49, -+0x0A, 0x40, 0x1A, 0x60, 0x1A, 0x68, 0x0F, 0x49, 0x0A, 0x40, 0x1A, 0x60, 0x0E, 0x4A, 0xC4, 0x20, 0x80, 0x00, 0x13, 0x58, -+0x1B, 0x02, 0x1B, 0x0A, 0xC0, 0x21, 0x09, 0x06, 0x0B, 0x43, 0x13, 0x50, 0x80, 0x23, 0x1B, 0x03, 0x13, 0x60, 0x70, 0x47, -+0x00, 0x00, 0x7C, 0x07, 0x08, 0x41, 0x04, 0x40, 0x0C, 0x41, 0x04, 0x40, 0x18, 0x41, 0x04, 0x40, 0xFF, 0xFC, 0xFF, 0xFF, -+0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0xE1, 0x00, 0xE0, 0x70, 0xB5, 0x82, 0xB0, -+0x04, 0x00, 0x64, 0x4B, 0x18, 0x68, 0x04, 0x28, 0x04, 0xD8, 0x49, 0xD8, 0x80, 0x00, 0x62, 0x4B, 0x1B, 0x58, 0x9F, 0x46, -+0xFF, 0x28, 0x43, 0xD1, 0x60, 0x4B, 0x80, 0x22, 0xD2, 0x00, 0x1A, 0x60, 0x5F, 0x4B, 0x00, 0x22, 0x1A, 0x70, 0x5F, 0x4B, -+0x1B, 0x68, 0x00, 0x2B, 0x40, 0xD1, 0x5E, 0x4B, 0x19, 0x68, 0x41, 0x29, 0x57, 0xD0, 0x43, 0xD8, 0x01, 0x29, 0x49, 0xD0, -+0x21, 0x29, 0x00, 0xD0, 0x81, 0xE0, 0x5A, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0x52, 0x4B, 0x00, 0x22, 0x1A, 0x60, 0x58, 0x4B, -+0x1B, 0x68, 0x01, 0x2B, 0x54, 0xD1, 0x50, 0xE0, 0x54, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0x4F, 0x4B, 0x80, 0x22, 0xD2, 0x00, -+0x1A, 0x60, 0x4E, 0x4B, 0x00, 0x22, 0x1A, 0x70, 0x50, 0x4B, 0x1B, 0x68, 0x01, 0x2B, 0x00, 0xD1, 0x7D, 0xE0, 0x47, 0x4B, -+0x1B, 0x68, 0x02, 0x2B, 0x40, 0xD1, 0x00, 0x25, 0x4C, 0x4B, 0x1D, 0x70, 0x01, 0x20, 0xFB, 0xF7, 0xCB, 0xFD, 0x4B, 0x4B, -+0x1D, 0x70, 0x3D, 0xE0, 0x46, 0x4B, 0x02, 0x22, 0x1A, 0x70, 0xE2, 0xE7, 0x44, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0xDE, 0xE7, -+0x42, 0x4B, 0x19, 0x78, 0x45, 0x4B, 0xDD, 0x6E, 0x00, 0x23, 0x00, 0x22, 0xA8, 0x47, 0xD6, 0xE7, 0x0F, 0x20, 0xFA, 0xF7, -+0x6F, 0xFD, 0xFF, 0x23, 0x03, 0x40, 0x3B, 0x4A, 0x13, 0x60, 0xB6, 0xE7, 0x61, 0x29, 0x10, 0xD0, 0xFF, 0x29, 0x3E, 0xD1, -+0x3D, 0x48, 0x7E, 0xF7, 0xA1, 0xFA, 0xCD, 0xE7, 0x36, 0x4B, 0x02, 0x22, 0x1A, 0x70, 0x2F, 0x4B, 0x01, 0x3A, 0x1A, 0x60, -+0x34, 0x4B, 0x1B, 0x68, 0x01, 0x2B, 0x0D, 0xD1, 0x4C, 0xE0, 0x31, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0x29, 0x4B, 0x01, 0x32, -+0x1A, 0x60, 0x2F, 0x4B, 0x1B, 0x68, 0x01, 0x2B, 0xC1, 0xD1, 0x26, 0x4B, 0x03, 0x22, 0x1A, 0x60, 0x2D, 0x4B, 0x01, 0x22, -+0x1A, 0x70, 0x00, 0x20, 0xFB, 0xF7, 0x8A, 0xFD, 0x2D, 0x4B, 0x03, 0x22, 0x1A, 0x70, 0xFF, 0xF7, 0x35, 0xFF, 0x2C, 0x4B, -+0x1B, 0x68, 0x24, 0x4A, 0x12, 0x78, 0x1D, 0x49, 0x09, 0x68, 0x2A, 0x48, 0x00, 0x68, 0x01, 0x90, 0x1E, 0x48, 0x00, 0x68, -+0x00, 0x90, 0x28, 0x48, 0x7E, 0xF7, 0x6E, 0xFA, 0x00, 0x2C, 0x27, 0xD0, 0x26, 0x4A, 0x13, 0x68, 0x20, 0x21, 0x0B, 0x43, -+0x13, 0x60, 0x02, 0xB0, 0x70, 0xBD, 0x24, 0x48, 0x7E, 0xF7, 0x62, 0xFA, 0x17, 0x4E, 0x31, 0x78, 0x10, 0x4D, 0x00, 0x23, -+0x00, 0x22, 0x28, 0x68, 0x81, 0xF7, 0xFE, 0xFF, 0x02, 0x23, 0x33, 0x70, 0x01, 0x3B, 0x2B, 0x60, 0x12, 0x4B, 0x1B, 0x68, -+0x01, 0x2B, 0xC9, 0xD1, 0x0F, 0x4B, 0x1B, 0x78, 0x03, 0xE0, 0x0E, 0x4B, 0x1B, 0x78, 0x01, 0x2B, 0xBF, 0xD0, 0x02, 0x2B, -+0x00, 0xD0, 0x7A, 0xE7, 0x04, 0x4B, 0x04, 0x22, 0x1A, 0x60, 0xBB, 0xE7, 0x12, 0x4A, 0x13, 0x68, 0x20, 0x21, 0x8B, 0x43, -+0x13, 0x60, 0xD6, 0xE7, 0x50, 0xE0, 0x10, 0x00, 0xE0, 0xD1, 0x10, 0x00, 0xE4, 0xE1, 0x10, 0x00, 0xB2, 0xE6, 0x10, 0x00, -+0xA4, 0xE5, 0x10, 0x00, 0xC0, 0xE5, 0x10, 0x00, 0xB4, 0xE5, 0x10, 0x00, 0x54, 0xE0, 0x10, 0x00, 0x60, 0xE6, 0x10, 0x00, -+0xDC, 0xE6, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, 0x9C, 0xD1, 0x10, 0x00, 0xD1, 0xE6, 0x10, 0x00, 0xA8, 0xE5, 0x10, 0x00, -+0xBC, 0xE5, 0x10, 0x00, 0xC8, 0xD1, 0x10, 0x00, 0x84, 0x40, 0x04, 0x40, 0xB0, 0xD1, 0x10, 0x00, 0xF0, 0xB5, 0xC6, 0x46, -+0x00, 0xB5, 0x38, 0x4B, 0x38, 0x4A, 0x1A, 0x60, 0x38, 0x4B, 0x39, 0x4A, 0x1A, 0x60, 0x40, 0x23, 0x38, 0x4A, 0x13, 0x60, -+0x28, 0x22, 0x38, 0x49, 0x0A, 0x80, 0xC8, 0x21, 0x49, 0x00, 0x37, 0x48, 0x01, 0x80, 0x37, 0x48, 0x01, 0x80, 0x03, 0x20, -+0x36, 0x49, 0x08, 0x80, 0x02, 0x21, 0x36, 0x4C, 0x21, 0x80, 0x36, 0x4C, 0x20, 0x80, 0x36, 0x48, 0x01, 0x80, 0x36, 0x49, -+0x0A, 0x80, 0x80, 0x25, 0xAD, 0x00, 0x35, 0x49, 0x0D, 0x80, 0x14, 0x21, 0x34, 0x48, 0x01, 0x80, 0x34, 0x48, 0x15, 0x24, -+0x04, 0x80, 0x34, 0x48, 0x01, 0x80, 0x20, 0x26, 0x33, 0x49, 0x0E, 0x60, 0x0D, 0x3C, 0x33, 0x49, 0x0C, 0x60, 0x33, 0x49, -+0x01, 0x20, 0x40, 0x42, 0x08, 0x60, 0x00, 0x20, 0x31, 0x49, 0x08, 0x60, 0x31, 0x49, 0x88, 0x46, 0x31, 0x4F, 0x39, 0x60, -+0x31, 0x4F, 0x14, 0x21, 0xFF, 0x31, 0x39, 0x60, 0x30, 0x4F, 0x31, 0x49, 0x39, 0x60, 0x31, 0x4F, 0x07, 0x21, 0x39, 0x80, -+0x30, 0x4F, 0x3B, 0x80, 0x30, 0x4F, 0x41, 0x31, 0x39, 0x80, 0x30, 0x4F, 0x01, 0x39, 0x39, 0x80, 0x2F, 0x4F, 0x3E, 0x80, -+0x2F, 0x4E, 0x35, 0x80, 0x2F, 0x4D, 0xD2, 0x26, 0x76, 0x00, 0x2E, 0x80, 0x64, 0x25, 0x2E, 0x4E, 0x35, 0x80, 0x2E, 0x4E, -+0x35, 0x80, 0x2E, 0x4D, 0x2C, 0x80, 0x2E, 0x4C, 0x18, 0x25, 0x25, 0x80, 0x2D, 0x4C, 0x22, 0x80, 0x2D, 0x4A, 0x8C, 0x24, -+0x14, 0x80, 0x2D, 0x4A, 0x10, 0x80, 0x2D, 0x4A, 0x13, 0x60, 0x2D, 0x4B, 0x42, 0x46, 0x1A, 0x60, 0x2C, 0x4B, 0x32, 0x22, -+0x1A, 0x80, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0xA0, 0x06, 0x16, 0x00, 0x00, 0xD7, 0x18, 0x00, 0x9C, 0x06, 0x16, 0x00, -+0x00, 0xF7, 0x18, 0x00, 0x78, 0x06, 0x16, 0x00, 0x5C, 0x06, 0x16, 0x00, 0x8E, 0x06, 0x16, 0x00, 0x8C, 0x06, 0x16, 0x00, -+0x5A, 0x06, 0x16, 0x00, 0x4A, 0x06, 0x16, 0x00, 0x56, 0x06, 0x16, 0x00, 0x54, 0x06, 0x16, 0x00, 0x5E, 0x06, 0x16, 0x00, -+0x58, 0x06, 0x16, 0x00, 0x64, 0x06, 0x16, 0x00, 0x66, 0x06, 0x16, 0x00, 0x62, 0x06, 0x16, 0x00, 0x68, 0x06, 0x16, 0x00, -+0x6C, 0x06, 0x16, 0x00, 0x44, 0x1E, 0x16, 0x00, 0x40, 0x1E, 0x16, 0x00, 0x20, 0x4E, 0x00, 0x00, 0x7C, 0x06, 0x16, 0x00, -+0x38, 0x1E, 0x16, 0x00, 0x3C, 0x1E, 0x16, 0x00, 0x02, 0x73, 0x06, 0x20, 0x4C, 0x06, 0x16, 0x00, 0x4E, 0x06, 0x16, 0x00, -+0x50, 0x06, 0x16, 0x00, 0x52, 0x06, 0x16, 0x00, 0x90, 0x06, 0x16, 0x00, 0x94, 0x06, 0x16, 0x00, 0x92, 0x06, 0x16, 0x00, -+0x8A, 0x06, 0x16, 0x00, 0x88, 0x06, 0x16, 0x00, 0x82, 0x06, 0x16, 0x00, 0x80, 0x06, 0x16, 0x00, 0x86, 0x06, 0x16, 0x00, -+0x84, 0x06, 0x16, 0x00, 0x48, 0x1E, 0x16, 0x00, 0x70, 0x06, 0x16, 0x00, 0x74, 0x06, 0x16, 0x00, 0x60, 0x06, 0x16, 0x00, -+0x0F, 0x4B, 0x02, 0x22, 0x9A, 0x77, 0x0F, 0x4A, 0x11, 0x6D, 0x80, 0x23, 0xDB, 0x01, 0x0B, 0x43, 0x13, 0x65, 0x0D, 0x4B, -+0x1B, 0x78, 0x02, 0x2B, 0x0B, 0xD0, 0x0A, 0x4B, 0x19, 0x6D, 0x80, 0x22, 0x12, 0x02, 0x0A, 0x43, 0x1A, 0x65, 0x19, 0x6D, -+0x80, 0x22, 0x92, 0x02, 0x0A, 0x43, 0x1A, 0x65, 0x70, 0x47, 0x11, 0x6D, 0x80, 0x23, 0xDB, 0x02, 0x0B, 0x43, 0x13, 0x65, -+0xED, 0xE7, 0xC0, 0x46, 0x3C, 0x95, 0x16, 0x00, 0x00, 0x60, 0x50, 0x40, 0xB4, 0xE5, 0x10, 0x00, 0x01, 0x4B, 0x01, 0x22, -+0xDA, 0x77, 0x70, 0x47, 0x3C, 0x95, 0x16, 0x00, 0x10, 0xB5, 0x01, 0x20, 0x7F, 0xF7, 0x48, 0xF9, 0x10, 0xBD, 0x10, 0xB5, -+0x80, 0x20, 0x40, 0x00, 0x7B, 0xF7, 0x3A, 0xFC, 0x10, 0xBD, 0x00, 0x00, 0x10, 0xB5, 0x04, 0x00, 0x20, 0x4B, 0x1B, 0x68, -+0x01, 0x2B, 0x03, 0xD0, 0x1F, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x22, 0xD1, 0x00, 0x2C, 0x2C, 0xD0, 0x1D, 0x4A, 0x13, 0x68, -+0x08, 0x21, 0x0B, 0x43, 0x13, 0x60, 0x00, 0x23, 0x1B, 0x4A, 0x13, 0x60, 0x1B, 0x4A, 0x13, 0x60, 0x1B, 0x4A, 0x13, 0x60, -+0x1B, 0x4B, 0x1B, 0x68, 0x01, 0x2B, 0x22, 0xD9, 0x1A, 0x4A, 0x0F, 0x21, 0x11, 0x70, 0x03, 0x3B, 0x01, 0x2B, 0x05, 0xD8, -+0x18, 0x4A, 0x80, 0x23, 0x1B, 0x02, 0x91, 0x69, 0x0B, 0x43, 0x93, 0x61, 0x16, 0x49, 0x17, 0x48, 0x7E, 0xF7, 0xEC, 0xF8, -+0x10, 0xBD, 0xFF, 0xF7, 0xCF, 0xFE, 0xFF, 0xF7, 0x97, 0xFF, 0x11, 0x4B, 0x01, 0x22, 0xDA, 0x77, 0xFF, 0xF7, 0xBE, 0xFF, -+0xFF, 0xF7, 0xC1, 0xFF, 0xD0, 0xE7, 0x07, 0x4A, 0x13, 0x68, 0x08, 0x21, 0x8B, 0x43, 0x13, 0x60, 0xD1, 0xE7, 0x09, 0x4B, -+0x0B, 0x22, 0x1A, 0x70, 0xE4, 0xE7, 0xC0, 0x46, 0xA8, 0xE5, 0x10, 0x00, 0xAC, 0xE5, 0x10, 0x00, 0x84, 0x40, 0x04, 0x40, -+0x58, 0xE6, 0x10, 0x00, 0x5C, 0xE6, 0x10, 0x00, 0x54, 0xE6, 0x10, 0x00, 0x50, 0xE0, 0x10, 0x00, 0xE2, 0xE1, 0x10, 0x00, -+0x3C, 0x95, 0x16, 0x00, 0xF8, 0xE8, 0x10, 0x00, 0xF4, 0xD1, 0x10, 0x00, 0x02, 0x4B, 0x80, 0x22, 0x12, 0x04, 0x1A, 0x60, -+0x70, 0x47, 0xC0, 0x46, 0x00, 0x41, 0x04, 0x40, 0x02, 0x4B, 0x80, 0x22, 0x12, 0x05, 0x1A, 0x60, 0x70, 0x47, 0xC0, 0x46, -+0x00, 0x41, 0x04, 0x40, 0x02, 0x4B, 0x80, 0x22, 0xD2, 0x05, 0x1A, 0x60, 0x70, 0x47, 0xC0, 0x46, 0x00, 0x41, 0x04, 0x40, -+0x04, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0x03, 0xD0, 0x03, 0x4B, 0x80, 0x22, 0x52, 0x05, 0x1A, 0x60, 0x70, 0x47, 0xC0, 0x46, -+0xD0, 0xE6, 0x10, 0x00, 0x00, 0x41, 0x04, 0x40, 0x10, 0xB5, 0x04, 0x00, 0x13, 0x4B, 0x1B, 0x68, 0x02, 0x2B, 0x07, 0xD0, -+0x11, 0x4B, 0x1B, 0x68, 0x01, 0x2B, 0x16, 0xD9, 0x20, 0x00, 0x10, 0x4B, 0x98, 0x47, 0x10, 0xBD, 0xAD, 0x33, 0xC3, 0x5C, -+0x00, 0x2B, 0xF7, 0xD0, 0x0D, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0x04, 0xD0, 0x00, 0x21, 0x01, 0x20, 0xFD, 0xF7, 0x54, 0xF8, -+0xEA, 0xE7, 0xFF, 0xF7, 0xD5, 0xFF, 0x08, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0xF4, 0xE7, 0xAE, 0xF7, 0x09, 0xFD, 0x00, 0x28, -+0xE4, 0xD1, 0xA7, 0x23, 0x04, 0x22, 0xE2, 0x54, 0xE0, 0xE7, 0xC0, 0x46, 0x50, 0xE0, 0x10, 0x00, 0xD5, 0x0D, 0x0B, 0x00, -+0xD8, 0xE6, 0x10, 0x00, 0x10, 0xB5, 0x04, 0x00, 0x0B, 0x4B, 0x1B, 0x68, 0x02, 0x2B, 0x03, 0xD0, 0x20, 0x00, 0xFE, 0xF7, -+0x11, 0xF9, 0x10, 0xBD, 0x08, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0x04, 0xD0, 0x00, 0x21, 0x01, 0x20, 0xFD, 0xF7, 0x2C, 0xF8, -+0xF2, 0xE7, 0xFF, 0xF7, 0xAD, 0xFF, 0x03, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0xF4, 0xE7, 0xC0, 0x46, 0x50, 0xE0, 0x10, 0x00, -+0xD8, 0xE6, 0x10, 0x00, 0x04, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0x03, 0xD0, 0x03, 0x4B, 0x80, 0x22, 0x92, 0x05, 0x1A, 0x60, -+0x70, 0x47, 0xC0, 0x46, 0xD2, 0xE6, 0x10, 0x00, 0x00, 0x41, 0x04, 0x40, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, -+0x45, 0x46, 0xE0, 0xB5, 0x83, 0xB0, 0x80, 0x46, 0x00, 0x91, 0x82, 0x00, 0x93, 0x4B, 0xD5, 0x58, 0x9E, 0x23, 0xEC, 0x5C, -+0x64, 0x00, 0x0F, 0x33, 0xEB, 0x5C, 0xE4, 0x18, 0xE4, 0xB2, 0xAF, 0x23, 0xEB, 0x5C, 0x00, 0x2B, 0x00, 0xD1, 0xAF, 0xE0, -+0xA8, 0x23, 0xEB, 0x5C, 0x77, 0x2B, 0x02, 0xD8, 0x01, 0x33, 0xA8, 0x22, 0xAB, 0x54, 0x43, 0x46, 0x1B, 0x02, 0x01, 0x27, -+0x3B, 0x43, 0x9B, 0x46, 0x87, 0x4B, 0x99, 0x46, 0x47, 0xE0, 0xC5, 0x20, 0x02, 0x23, 0xFF, 0x22, 0x59, 0x46, 0xC0, 0x00, -+0x7B, 0xF7, 0x0A, 0xFF, 0x06, 0x00, 0x3B, 0x88, 0x03, 0x80, 0x7B, 0xF7, 0x2F, 0xFF, 0x30, 0x88, 0x43, 0x1C, 0x9B, 0xB2, -+0x7F, 0x49, 0x5A, 0x5C, 0x41, 0x5C, 0x49, 0x10, 0x7E, 0x48, 0x7D, 0xF7, 0xFF, 0xFF, 0x00, 0x23, 0x3B, 0x80, 0x7D, 0x4B, -+0xE2, 0x18, 0x13, 0x88, 0x78, 0x21, 0x8B, 0x43, 0x13, 0x80, 0x7B, 0x4B, 0x9C, 0x46, 0x64, 0x44, 0x23, 0x88, 0x7A, 0x4A, -+0x13, 0x40, 0x23, 0x80, 0xAF, 0x22, 0xAB, 0x5C, 0x01, 0x3B, 0xDB, 0xB2, 0xAB, 0x54, 0x35, 0x31, 0x6A, 0x5C, 0x50, 0x42, -+0x42, 0x41, 0x6A, 0x54, 0x5A, 0x1E, 0x93, 0x41, 0xA8, 0x22, 0xAB, 0x54, 0x8C, 0x23, 0xEB, 0x58, 0x00, 0x2B, 0x05, 0xD0, -+0x6A, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x9E, 0x23, 0xEC, 0x5C, 0x64, 0x00, 0x0F, 0x33, -+0xEB, 0x5C, 0xE4, 0x18, 0xE4, 0xB2, 0xAF, 0x23, 0xEB, 0x5C, 0x00, 0x2B, 0x58, 0xD0, 0xA3, 0x00, 0x1C, 0x19, 0x64, 0x00, -+0x66, 0x4B, 0xE3, 0x18, 0x1B, 0x88, 0xDB, 0x0B, 0x50, 0xD0, 0x65, 0x4B, 0xE7, 0x18, 0x3B, 0x88, 0x9B, 0xB2, 0x00, 0x2B, -+0xA9, 0xD1, 0x63, 0x4B, 0xE7, 0x18, 0x3B, 0x88, 0x9B, 0xB2, 0x00, 0x2B, 0x38, 0xD0, 0xEC, 0x23, 0xEB, 0x58, 0x00, 0x2B, -+0xB7, 0xD1, 0x5A, 0x4B, 0xE3, 0x18, 0x1B, 0x88, 0xDB, 0x04, 0x9B, 0x0D, 0x0A, 0xD0, 0x3A, 0x88, 0x90, 0x21, 0x69, 0x58, -+0xD3, 0x18, 0x4A, 0x89, 0x92, 0x05, 0x92, 0x0D, 0x09, 0x89, 0x52, 0x18, 0x93, 0x42, 0x0D, 0xDA, 0x8C, 0x23, 0xEB, 0x58, -+0x00, 0x2B, 0x06, 0xD0, 0x4B, 0x4B, 0x9B, 0x6E, 0x01, 0x93, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x00, 0x23, -+0x3B, 0x80, 0x98, 0xE7, 0x01, 0x23, 0xFF, 0x22, 0x59, 0x46, 0x4E, 0x48, 0x7B, 0xF7, 0x8C, 0xFE, 0x00, 0x23, 0x9A, 0x46, -+0x03, 0x70, 0x7B, 0xF7, 0xB1, 0xFE, 0x90, 0x26, 0xAB, 0x59, 0x18, 0x89, 0x85, 0xF7, 0xA2, 0xFF, 0x8C, 0x23, 0xEA, 0x58, -+0xAA, 0x51, 0x52, 0x46, 0xEA, 0x50, 0xE6, 0xE7, 0xEC, 0x23, 0xEB, 0x58, 0x00, 0x2B, 0x00, 0xD0, 0x7D, 0xE7, 0x00, 0x22, -+0x00, 0x21, 0x00, 0x20, 0x4B, 0x46, 0x9B, 0x6E, 0x98, 0x47, 0x76, 0xE7, 0x00, 0x99, 0x40, 0x46, 0xFD, 0xF7, 0x0C, 0xF8, -+0x3D, 0x4B, 0x1B, 0x68, 0x02, 0x2B, 0x0A, 0xD0, 0xFC, 0xF7, 0x6E, 0xF9, 0x01, 0x28, 0x28, 0xD0, 0x03, 0xB0, 0x3C, 0xBC, -+0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0xAD, 0x33, 0xEB, 0x5C, 0x00, 0x2B, 0x0E, 0xD1, 0x35, 0x4B, -+0x1B, 0x78, 0x01, 0x2B, 0x04, 0xD0, 0x00, 0x21, 0x02, 0x20, 0xFC, 0xF7, 0x2B, 0xFF, 0xE7, 0xE7, 0xFF, 0xF7, 0x08, 0xFF, -+0x2F, 0x4B, 0x00, 0x22, 0x1A, 0x70, 0xF4, 0xE7, 0x2D, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0x04, 0xD0, 0x00, 0x21, 0x01, 0x20, -+0xFC, 0xF7, 0x1C, 0xFF, 0xD8, 0xE7, 0xFF, 0xF7, 0x9D, 0xFE, 0x28, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0xF4, 0xE7, 0xFB, 0xF7, -+0x0F, 0xFA, 0x00, 0x28, 0xD2, 0xD0, 0xAE, 0xF7, 0xCD, 0xFB, 0x00, 0x28, 0xCE, 0xD1, 0x8A, 0xF7, 0x5D, 0xFA, 0x00, 0x28, -+0xCA, 0xD1, 0xAF, 0x23, 0xEB, 0x5C, 0x00, 0x2B, 0xC6, 0xD1, 0xA7, 0x33, 0xEB, 0x5C, 0x01, 0x2B, 0xC2, 0xD8, 0xD0, 0xF7, -+0xD9, 0xFA, 0x04, 0x1E, 0xBE, 0xD0, 0x1B, 0x4B, 0xC2, 0x69, 0x9A, 0x42, 0xBA, 0xD1, 0xA5, 0xF7, 0x4D, 0xFA, 0x63, 0x68, -+0x05, 0x3B, 0x1B, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0xAA, 0x22, 0xAA, 0x5C, 0x00, 0x2A, 0xAF, 0xD0, 0x0B, 0x2B, 0xAD, 0xD9, -+0x13, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0x9E, 0x23, 0xE8, 0x5C, 0xD1, 0xF7, 0x35, 0xFA, 0xAA, 0x23, 0x00, 0x22, 0xEA, 0x54, -+0xA2, 0xE7, 0xC0, 0x46, 0x38, 0x27, 0x16, 0x00, 0x28, 0x19, 0x16, 0x00, 0x00, 0x00, 0x61, 0x40, 0xFC, 0xD1, 0x10, 0x00, -+0xCA, 0x69, 0x61, 0x40, 0xCC, 0x69, 0x61, 0x40, 0x07, 0xE0, 0xFF, 0xFF, 0xC8, 0x69, 0x61, 0x40, 0xD0, 0x69, 0x61, 0x40, -+0xCE, 0x69, 0x61, 0x40, 0x2B, 0x06, 0x00, 0x00, 0x50, 0xE0, 0x10, 0x00, 0xD8, 0xE6, 0x10, 0x00, 0xC9, 0x1F, 0x10, 0x00, -+0x98, 0xE5, 0x10, 0x00, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x87, 0xB0, 0x81, 0x46, -+0x82, 0x00, 0xBA, 0x4B, 0xD4, 0x58, 0x01, 0x94, 0xB0, 0x23, 0x15, 0x22, 0xE2, 0x54, 0x2A, 0x3B, 0xFA, 0x22, 0x52, 0x01, -+0xE2, 0x52, 0xB6, 0x4B, 0x1B, 0x68, 0x02, 0x2B, 0x15, 0xD0, 0xB4, 0x4B, 0x1B, 0x68, 0x01, 0x2B, 0x26, 0xD9, 0xB3, 0x4B, -+0x00, 0x22, 0x1A, 0x70, 0xA1, 0x23, 0xE3, 0x5C, 0x04, 0x2B, 0x2C, 0xD0, 0x86, 0x23, 0xE3, 0x5A, 0x00, 0x2B, 0x6B, 0xD0, -+0x5B, 0x00, 0x22, 0x6F, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x01, 0x1F, 0x09, 0x29, 0xE0, 0xAB, 0x4B, 0xE3, 0x61, 0xAF, 0x23, -+0xE3, 0x5C, 0x00, 0x2B, 0x03, 0xD1, 0xA9, 0x4B, 0x1B, 0x78, 0x01, 0x2B, 0x04, 0xD0, 0x01, 0x21, 0x02, 0x20, 0xFC, 0xF7, -+0x87, 0xFE, 0xDA, 0xE7, 0xFF, 0xF7, 0x64, 0xFE, 0xA3, 0x4B, 0x00, 0x22, 0x1A, 0x70, 0xF4, 0xE7, 0xA0, 0x4B, 0xE3, 0x61, -+0x9E, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0xD2, 0xD0, 0x9F, 0x4B, 0x18, 0x68, 0x00, 0x28, 0xCE, 0xD0, 0xFB, 0xF7, 0x86, 0xFE, -+0xCB, 0xE7, 0xE4, 0x33, 0xE3, 0x58, 0x19, 0x68, 0xA3, 0x6F, 0xC9, 0x1A, 0x14, 0x39, 0x09, 0x01, 0x0F, 0x09, 0xA6, 0x23, -+0xE3, 0x5C, 0xDB, 0x02, 0xE0, 0x22, 0x92, 0x01, 0x1A, 0x40, 0x96, 0x4B, 0x59, 0x78, 0x0F, 0x23, 0x0B, 0x40, 0x13, 0x43, -+0x94, 0x4A, 0x13, 0x43, 0xA3, 0x82, 0xE7, 0x60, 0xFB, 0xF7, 0x56, 0xF9, 0x02, 0x90, 0xFD, 0xF7, 0x2B, 0xF9, 0x03, 0x90, -+0xAE, 0xF7, 0x12, 0xFB, 0x06, 0x00, 0xA1, 0x23, 0xE3, 0x5C, 0x04, 0x2B, 0x00, 0xD1, 0x38, 0xE2, 0x00, 0x25, 0x00, 0x28, -+0x2B, 0xD0, 0x8B, 0x4B, 0xA2, 0x6F, 0x1A, 0x60, 0x9F, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x00, 0xD1, 0x5C, 0xE1, 0x88, 0x4A, -+0xD2, 0x88, 0x22, 0x61, 0x01, 0x2B, 0x00, 0xD0, 0xDA, 0xE1, 0xA7, 0x33, 0xE3, 0x5C, 0xA7, 0x21, 0x61, 0x5C, 0x5B, 0x18, -+0x1B, 0x11, 0x83, 0x49, 0x4B, 0x43, 0x93, 0x42, 0x00, 0xD2, 0x13, 0x00, 0x23, 0x61, 0xCD, 0xE1, 0xA6, 0x23, 0xE3, 0x5C, -+0xDB, 0x02, 0xE0, 0x22, 0x92, 0x01, 0x1A, 0x40, 0x78, 0x4B, 0x59, 0x78, 0x0F, 0x23, 0x0B, 0x40, 0x13, 0x43, 0x7B, 0x4A, -+0x13, 0x43, 0xA3, 0x82, 0x01, 0x27, 0x7F, 0x42, 0xC2, 0xE7, 0xA5, 0xF7, 0x73, 0xF9, 0x60, 0x60, 0x03, 0x9B, 0x00, 0x2B, -+0x52, 0xD0, 0x76, 0x4B, 0x23, 0x61, 0x11, 0x23, 0xA3, 0x75, 0x8E, 0x33, 0xE3, 0x5C, 0x01, 0x2B, 0x47, 0xD0, 0x00, 0x25, -+0x48, 0x23, 0x9B, 0x46, 0xAF, 0x23, 0xE3, 0x5C, 0x98, 0x46, 0x20, 0x00, 0x48, 0x30, 0x7E, 0xF7, 0x83, 0xFA, 0x6E, 0x4A, -+0x12, 0x68, 0x92, 0x68, 0x00, 0x2A, 0x00, 0xD0, 0xE0, 0xE0, 0x9F, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x01, 0xD1, 0x6A, 0x4B, -+0x23, 0x61, 0x40, 0x44, 0xC3, 0xB2, 0xA7, 0x22, 0xA2, 0x5C, 0x11, 0x00, 0x19, 0x43, 0x06, 0xD0, 0xD3, 0x18, 0x65, 0x4A, -+0x53, 0x43, 0x22, 0x69, 0x94, 0x46, 0x63, 0x44, 0x23, 0x61, 0x23, 0x69, 0x62, 0x4A, 0x93, 0x42, 0x00, 0xD9, 0x13, 0x00, -+0x23, 0x61, 0x5A, 0x46, 0x21, 0x69, 0x20, 0x00, 0xFB, 0xF7, 0x16, 0xF8, 0x9F, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x04, 0xD1, -+0x63, 0x68, 0x03, 0x33, 0x03, 0x22, 0x93, 0x43, 0x63, 0x60, 0xA7, 0x23, 0x01, 0x22, 0xE2, 0x54, 0x50, 0x4B, 0xA2, 0x6F, -+0x1A, 0x60, 0x20, 0x00, 0xCF, 0xF7, 0xB6, 0xFF, 0x00, 0x28, 0x00, 0xD0, 0xAE, 0xE1, 0xA0, 0x23, 0x00, 0x22, 0xE2, 0x54, -+0x49, 0xE1, 0x37, 0x33, 0x9B, 0x46, 0xB7, 0xE7, 0x02, 0x9B, 0x00, 0x2B, 0x6B, 0xD0, 0x00, 0x23, 0x00, 0x25, 0x3E, 0x4A, -+0x90, 0x46, 0xA1, 0x22, 0x94, 0x46, 0x02, 0xE0, 0x01, 0x33, 0x07, 0x2B, 0x0B, 0xD0, 0x9A, 0x00, 0x41, 0x46, 0x52, 0x58, -+0x00, 0x2A, 0xF7, 0xD0, 0x61, 0x46, 0x52, 0x5C, 0x00, 0x2A, 0xF3, 0xD1, 0x01, 0x35, 0xED, 0xB2, 0xF0, 0xE7, 0x01, 0x2D, -+0x08, 0xD9, 0xA0, 0x33, 0x00, 0x22, 0xE2, 0x54, 0x41, 0x4B, 0x1B, 0x68, 0x23, 0x61, 0x28, 0x23, 0x9B, 0x46, 0x93, 0xE7, -+0x9F, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x23, 0xD1, 0xA7, 0x33, 0x00, 0x22, 0xE2, 0x54, 0x01, 0x33, 0xE2, 0x5C, 0x53, 0x42, -+0x5A, 0x41, 0x53, 0x42, 0x08, 0x22, 0x1A, 0x40, 0x68, 0x32, 0x38, 0x4B, 0x1B, 0x68, 0x98, 0x46, 0xC3, 0x1A, 0x1B, 0x01, -+0x1B, 0x09, 0x80, 0x21, 0x09, 0x05, 0x8B, 0x42, 0x04, 0xD9, 0x43, 0x46, 0x1B, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x5B, 0x42, -+0x00, 0x21, 0x8B, 0x46, 0x9A, 0x42, 0x01, 0xD3, 0xD3, 0x1A, 0x9B, 0x46, 0x2C, 0x4B, 0x1B, 0x68, 0x23, 0x61, 0x6B, 0xE7, -+0x01, 0x2B, 0x00, 0xD0, 0x65, 0xE1, 0xA7, 0x33, 0xE2, 0x5C, 0x53, 0x42, 0x5A, 0x41, 0x53, 0x42, 0x0C, 0x22, 0x1A, 0x40, -+0x44, 0x32, 0xE3, 0x6E, 0x98, 0x46, 0xC3, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x80, 0x21, 0x09, 0x05, 0x8B, 0x42, 0x04, 0xD9, -+0x43, 0x46, 0x1B, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x5B, 0x42, 0x00, 0x21, 0x8B, 0x46, 0x9A, 0x42, 0x01, 0xD3, 0xD3, 0x1A, -+0x9B, 0x46, 0x1B, 0x4B, 0x1B, 0x68, 0x23, 0x61, 0x48, 0xE7, 0x0A, 0x4B, 0x1B, 0x68, 0x00, 0x25, 0x01, 0x2B, 0x00, 0xD9, -+0x05, 0xE7, 0x13, 0x4B, 0x1B, 0x68, 0x9B, 0x68, 0x00, 0x2B, 0x00, 0xD1, 0x37, 0xE1, 0x13, 0x4B, 0x1B, 0x68, 0x23, 0x61, -+0x00, 0x23, 0x9B, 0x46, 0x36, 0xE7, 0xC0, 0x46, 0x38, 0x27, 0x16, 0x00, 0x50, 0xE0, 0x10, 0x00, 0x98, 0xE5, 0x10, 0x00, -+0xC1, 0x60, 0x10, 0x00, 0xD8, 0xE6, 0x10, 0x00, 0xF8, 0xE6, 0x10, 0x00, 0x7C, 0x91, 0x0D, 0x00, 0x40, 0x80, 0xFF, 0xFF, -+0xCC, 0xE6, 0x10, 0x00, 0x5C, 0xAB, 0x16, 0x00, 0xE2, 0x04, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0xE4, 0x57, 0x00, 0x00, -+0xF4, 0xE1, 0x10, 0x00, 0x5C, 0x1C, 0x00, 0x00, 0x70, 0x71, 0x00, 0x00, 0x40, 0xE0, 0x10, 0x00, 0x2C, 0xE6, 0x10, 0x00, -+0x00, 0x23, 0x04, 0x93, 0x05, 0x93, 0x20, 0x1D, 0x23, 0x00, 0x05, 0xAA, 0x04, 0xA9, 0xFA, 0xF7, 0xAD, 0xFE, 0x04, 0x9B, -+0x00, 0x2B, 0x28, 0xD0, 0x22, 0x69, 0x9A, 0x42, 0x00, 0xD9, 0x1A, 0x00, 0x22, 0x61, 0x03, 0x26, 0x63, 0x68, 0x9A, 0x46, -+0x5A, 0x46, 0x21, 0x69, 0x01, 0x98, 0xFA, 0xF7, 0x3B, 0xFF, 0x63, 0x68, 0x53, 0x45, 0x08, 0xD0, 0x05, 0x9B, 0x53, 0x44, -+0x1B, 0x01, 0x1B, 0x09, 0x63, 0x60, 0x01, 0x3E, 0xF6, 0xB2, 0x00, 0x2E, 0xEC, 0xD1, 0x9F, 0x23, 0xE3, 0x5C, 0x00, 0x2B, -+0x00, 0xD0, 0x0E, 0xE7, 0x63, 0x68, 0x03, 0x33, 0x03, 0x22, 0x93, 0x43, 0x63, 0x60, 0x23, 0x69, 0x70, 0x4A, 0x94, 0x46, -+0x63, 0x44, 0x23, 0x61, 0x03, 0xE7, 0x02, 0x9B, 0x00, 0x2B, 0x00, 0xD1, 0x9B, 0xE6, 0xEA, 0xE7, 0xA7, 0x23, 0xE3, 0x5C, -+0x00, 0x2B, 0x00, 0xD0, 0x7B, 0xE0, 0xA8, 0x33, 0xE3, 0x5C, 0x00, 0x2B, 0x00, 0xD0, 0x76, 0xE0, 0xB3, 0x33, 0xE3, 0x5C, -+0x00, 0x2B, 0x00, 0xD0, 0x71, 0xE0, 0x65, 0x4B, 0x23, 0x61, 0x73, 0x42, 0x73, 0x41, 0x5B, 0x42, 0x4B, 0x22, 0x93, 0x43, -+0x60, 0x33, 0x5B, 0x00, 0x62, 0x68, 0x94, 0x46, 0x63, 0x44, 0x60, 0x4A, 0x13, 0x40, 0x63, 0x60, 0xB0, 0x23, 0x09, 0x22, -+0xE2, 0x54, 0x20, 0x00, 0xCF, 0xF7, 0xA8, 0xFE, 0x00, 0x28, 0x00, 0xD0, 0xA0, 0xE0, 0xA0, 0x23, 0x00, 0x22, 0xE2, 0x54, -+0x00, 0x2E, 0x3A, 0xD0, 0xA5, 0xF7, 0x0E, 0xF8, 0x57, 0x4B, 0x18, 0x60, 0x07, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, -+0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0x66, 0x60, 0x80, 0xE0, 0x00, 0x2E, 0x00, 0xD1, 0x86, 0xE0, 0x51, 0x4B, 0x23, 0x61, -+0x20, 0x00, 0xFD, 0xF7, 0x57, 0xFE, 0x60, 0x60, 0x18, 0x26, 0x65, 0x68, 0x00, 0x22, 0x21, 0x69, 0x01, 0x98, 0xFA, 0xF7, -+0xD1, 0xFE, 0x63, 0x68, 0xAB, 0x42, 0x06, 0xD0, 0x75, 0x19, 0x2D, 0x01, 0x2D, 0x09, 0x65, 0x60, 0x18, 0x36, 0x60, 0x2E, -+0xEF, 0xD1, 0x20, 0x00, 0xCF, 0xF7, 0x76, 0xFE, 0x00, 0x28, 0x6F, 0xD1, 0xA0, 0x23, 0x00, 0x22, 0xE2, 0x54, 0xCF, 0xE7, -+0x39, 0x00, 0x14, 0x31, 0x09, 0x01, 0x09, 0x09, 0x48, 0x46, 0x40, 0x4B, 0x98, 0x47, 0xCB, 0xE7, 0xA0, 0x23, 0x00, 0x22, -+0xE2, 0x54, 0xA3, 0x7D, 0x10, 0x2B, 0x01, 0xD8, 0x11, 0x23, 0xA3, 0x75, 0x02, 0x9B, 0x00, 0x2B, 0xBC, 0xD0, 0x01, 0x2D, -+0xBA, 0xD1, 0x39, 0x4B, 0x1B, 0x68, 0x9B, 0x68, 0x00, 0x2B, 0xB5, 0xD1, 0x37, 0x4B, 0x1B, 0x68, 0x23, 0x61, 0x9F, 0x23, -+0xE3, 0x5C, 0x01, 0x2B, 0xAE, 0xD1, 0x35, 0x4B, 0x1B, 0x68, 0x23, 0x61, 0xAA, 0xE7, 0x34, 0x4B, 0xDB, 0x88, 0x23, 0x61, -+0xA1, 0x23, 0xE3, 0x5C, 0x04, 0x2B, 0xB0, 0xD0, 0x00, 0x2E, 0xB1, 0xD1, 0x30, 0x4B, 0x23, 0x61, 0xA7, 0x23, 0xE3, 0x5C, -+0x00, 0x2B, 0x03, 0xD1, 0xA8, 0x22, 0xA2, 0x5C, 0x00, 0x2A, 0x2E, 0xD0, 0xA8, 0x22, 0xA1, 0x5C, 0xCB, 0x18, 0x2A, 0x49, -+0x59, 0x43, 0x29, 0x4B, 0x9C, 0x46, 0x61, 0x44, 0x21, 0x61, 0x23, 0x4B, 0x1A, 0x68, 0x53, 0x6F, 0x58, 0x42, 0x43, 0x41, -+0x5B, 0x42, 0x1B, 0x48, 0x03, 0x40, 0x24, 0x48, 0x84, 0x46, 0x63, 0x44, 0x92, 0x68, 0x00, 0x2A, 0x02, 0xD0, 0x22, 0x4A, -+0x12, 0x68, 0x9B, 0x1A, 0x99, 0x42, 0x00, 0xD9, 0x19, 0x00, 0x21, 0x61, 0x66, 0x68, 0x28, 0x22, 0x20, 0x00, 0xFA, 0xF7, -+0x63, 0xFE, 0x01, 0x28, 0x00, 0xD1, 0x7C, 0xE7, 0x9F, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x04, 0xD1, 0x63, 0x68, 0x03, 0x33, -+0x03, 0x22, 0x93, 0x43, 0x63, 0x60, 0x20, 0x00, 0xCF, 0xF7, 0x06, 0xFE, 0x00, 0x28, 0x9B, 0xD0, 0xA1, 0x23, 0xE3, 0x5C, -+0x04, 0x2B, 0x8F, 0xD0, 0x08, 0x21, 0x48, 0x46, 0x11, 0x4B, 0x98, 0x47, 0x5E, 0xE7, 0x00, 0x25, 0xC7, 0xE5, 0x00, 0x25, -+0xC5, 0xE5, 0x00, 0x23, 0x9B, 0x46, 0xFF, 0xE5, 0xAA, 0xF8, 0xFF, 0xFF, 0x98, 0x12, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, -+0x34, 0xE6, 0x10, 0x00, 0x88, 0x13, 0x00, 0x00, 0xB9, 0x4C, 0x0B, 0x00, 0xF4, 0xE1, 0x10, 0x00, 0x40, 0xE0, 0x10, 0x00, -+0x44, 0xE0, 0x10, 0x00, 0x5C, 0xAB, 0x16, 0x00, 0x5C, 0x1C, 0x00, 0x00, 0x7C, 0x42, 0x00, 0x00, 0xE8, 0xE1, 0x10, 0x00, -+0x95, 0x0F, 0x0B, 0x00, 0xF0, 0xB5, 0xD6, 0x46, 0x4F, 0x46, 0x46, 0x46, 0xC0, 0xB5, 0x82, 0xB0, 0xB7, 0x4B, 0xB8, 0x4A, -+0x13, 0x60, 0x80, 0x22, 0x52, 0x00, 0x9C, 0x5C, 0xFD, 0xF7, 0x5A, 0xFA, 0xB5, 0x4B, 0x1B, 0x68, 0x9B, 0x68, 0x00, 0x2B, -+0x09, 0xD0, 0xB2, 0x4B, 0x1D, 0x68, 0x02, 0x23, 0xFF, 0x33, 0xEB, 0x5C, 0xA3, 0x42, 0x00, 0xD1, 0x42, 0xE1, 0xB0, 0x4F, -+0x84, 0xE0, 0xFA, 0xF7, 0xFD, 0xFD, 0xF2, 0xE7, 0xAE, 0x4A, 0x93, 0x42, 0x46, 0xD1, 0xAE, 0x4B, 0x4B, 0x60, 0x43, 0xE0, -+0xAD, 0x49, 0x8B, 0x42, 0x00, 0xD1, 0xE5, 0xE0, 0xAC, 0x49, 0x8B, 0x42, 0x16, 0xD1, 0xAC, 0x4B, 0x1A, 0x68, 0x00, 0x2A, -+0x38, 0xD0, 0x23, 0x01, 0xED, 0x18, 0xA9, 0x68, 0x8B, 0x00, 0x9B, 0x58, 0x00, 0x9A, 0x48, 0x46, 0x02, 0x43, 0xD2, 0xB2, -+0x00, 0x2A, 0x04, 0xD0, 0x00, 0x29, 0x00, 0xD0, 0xCC, 0xE0, 0xD8, 0x22, 0x1A, 0x86, 0x00, 0x22, 0x9A, 0x62, 0x25, 0xE0, -+0xA1, 0x49, 0x8B, 0x42, 0x22, 0xD1, 0x02, 0x2A, 0x20, 0xD1, 0x00, 0x21, 0x02, 0x20, 0xFC, 0xF7, 0xA5, 0xFB, 0x1B, 0xE0, -+0x9D, 0x4B, 0x1D, 0x68, 0x00, 0x9B, 0x4A, 0x46, 0x13, 0x43, 0xDB, 0xB2, 0x00, 0x2B, 0x04, 0xD0, 0x00, 0x23, 0xAB, 0x62, -+0x34, 0x33, 0x01, 0x22, 0xEA, 0x54, 0xAE, 0xF7, 0x53, 0xF8, 0x43, 0x1E, 0x98, 0x41, 0x43, 0x42, 0xC0, 0x22, 0x92, 0x01, -+0x13, 0x40, 0x80, 0x22, 0x52, 0x01, 0x94, 0x46, 0x63, 0x44, 0x2B, 0x86, 0x12, 0x23, 0x6B, 0x86, 0x86, 0x4B, 0x1B, 0x68, -+0x52, 0x46, 0x98, 0x18, 0x45, 0x68, 0x00, 0x2D, 0x00, 0xD1, 0xD1, 0xE0, 0x42, 0x46, 0x04, 0x3A, 0x51, 0x42, 0x4A, 0x41, -+0xD2, 0xB2, 0x31, 0x01, 0x5B, 0x18, 0x99, 0x68, 0x00, 0x68, 0xA8, 0x47, 0x7D, 0x4B, 0x1D, 0x68, 0x33, 0x01, 0xEB, 0x18, -+0x85, 0x4A, 0x5B, 0x68, 0x93, 0x42, 0x00, 0xD1, 0xC5, 0xE0, 0x33, 0x01, 0xEB, 0x18, 0x00, 0x22, 0x1A, 0x73, 0x03, 0x32, -+0xFF, 0x32, 0xAB, 0x5C, 0x01, 0x3B, 0xAB, 0x54, 0x02, 0x23, 0xFF, 0x33, 0xEA, 0x5C, 0x0F, 0x21, 0xA2, 0x42, 0x00, 0xD1, -+0xC5, 0xE0, 0x01, 0x34, 0x0C, 0x40, 0x23, 0x01, 0xEB, 0x18, 0x1B, 0x7B, 0x00, 0x2B, 0xF5, 0xD0, 0x80, 0x23, 0x5B, 0x00, -+0xEC, 0x54, 0xA2, 0x42, 0x00, 0xD1, 0xBB, 0xE0, 0x26, 0x00, 0x75, 0x4B, 0xE3, 0x18, 0x1B, 0x01, 0x1B, 0x88, 0x9B, 0x06, -+0x5B, 0x0F, 0x98, 0x46, 0x03, 0x3B, 0x02, 0x2B, 0x00, 0xD9, 0xAF, 0xE0, 0xFB, 0xF7, 0x70, 0xFD, 0x00, 0x90, 0x01, 0x90, -+0x3A, 0x68, 0x00, 0x23, 0x01, 0x21, 0x91, 0x42, 0x5B, 0x41, 0xDB, 0xB2, 0x99, 0x46, 0x23, 0x01, 0x9A, 0x46, 0xE9, 0x18, -+0x4B, 0x68, 0x69, 0x48, 0x83, 0x42, 0x62, 0xD0, 0x00, 0xD9, 0x63, 0xE7, 0x67, 0x4A, 0x93, 0x42, 0x88, 0xD0, 0x63, 0x4A, -+0x93, 0x42, 0x00, 0xD0, 0x56, 0xE7, 0x65, 0x4B, 0x1D, 0x68, 0x00, 0x23, 0xAB, 0x62, 0x51, 0x33, 0x01, 0x22, 0xEA, 0x54, -+0xAD, 0xF7, 0xDE, 0xFF, 0x00, 0x28, 0x05, 0xD0, 0x80, 0x23, 0x9B, 0x01, 0xAB, 0x85, 0x06, 0x23, 0xEB, 0x85, 0x8F, 0xE7, -+0x50, 0x4B, 0x1B, 0x68, 0x02, 0x2B, 0x0B, 0xD0, 0x00, 0x9B, 0x4A, 0x46, 0x13, 0x43, 0xDB, 0xB2, 0x00, 0x2B, 0x1C, 0xD1, -+0x80, 0x23, 0x1B, 0x01, 0xAB, 0x85, 0x12, 0x23, 0xEB, 0x85, 0x7F, 0xE7, 0x55, 0x4B, 0xEB, 0x61, 0x01, 0x9B, 0x00, 0x2B, -+0x03, 0xD1, 0xFD, 0xF7, 0x13, 0xFA, 0x01, 0x28, 0x07, 0xD9, 0x00, 0x9A, 0xD3, 0x02, 0xAB, 0x85, 0x09, 0x23, 0x9B, 0x1A, -+0x5B, 0x00, 0xEB, 0x85, 0x6E, 0xE7, 0x80, 0x23, 0x5B, 0x00, 0xAB, 0x85, 0xEE, 0x3B, 0xEB, 0x85, 0x68, 0xE7, 0xFD, 0xF7, -+0x41, 0xF9, 0x01, 0x28, 0x00, 0xD8, 0x63, 0xE7, 0x80, 0x23, 0xDB, 0x01, 0xAB, 0x85, 0x08, 0x23, 0xEB, 0x85, 0x5D, 0xE7, -+0xC8, 0x22, 0x92, 0x00, 0x1A, 0x86, 0x30, 0xE7, 0x01, 0x2A, 0x00, 0xD9, 0x56, 0xE7, 0x01, 0x9B, 0x00, 0x2B, 0x00, 0xD1, -+0x52, 0xE7, 0x23, 0x01, 0xED, 0x18, 0xAB, 0x68, 0x9B, 0x00, 0x3E, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x68, 0xC0, 0x22, -+0x12, 0x01, 0xDA, 0x66, 0x46, 0xE7, 0x02, 0x2A, 0x00, 0xD0, 0x43, 0xE7, 0x23, 0x01, 0xED, 0x18, 0x2B, 0x7A, 0x9B, 0x00, -+0x37, 0x4A, 0x9D, 0x58, 0xAF, 0x23, 0xEB, 0x5C, 0x00, 0x2B, 0x03, 0xD1, 0x35, 0x4B, 0x1B, 0x78, 0x01, 0x2B, 0x09, 0xD0, -+0xA0, 0x23, 0xEB, 0x5C, 0x02, 0x2B, 0x00, 0xD0, 0x30, 0xE7, 0x01, 0x21, 0x02, 0x20, 0xFC, 0xF7, 0xB5, 0xFA, 0x2B, 0xE7, -+0xFF, 0xF7, 0x92, 0xFA, 0x00, 0x23, 0x2D, 0x4A, 0x13, 0x70, 0xEF, 0xE7, 0x2C, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, -+0x00, 0x20, 0x98, 0x47, 0x30, 0xE7, 0x24, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x00, 0xD1, 0x34, 0xE7, 0x11, 0x22, 0x9A, 0x75, -+0x31, 0xE7, 0xFB, 0xF7, 0x93, 0xFB, 0x11, 0xE0, 0x80, 0x20, 0x80, 0x00, 0x7A, 0xF7, 0xE2, 0xFD, 0x13, 0xE0, 0x80, 0x23, -+0x5B, 0x00, 0xEC, 0x54, 0x81, 0x23, 0x5B, 0x00, 0xEB, 0x5C, 0x00, 0x2B, 0x04, 0xD1, 0x05, 0x33, 0xFF, 0x33, 0xEB, 0x58, -+0x00, 0x2B, 0xEA, 0xD0, 0x07, 0x4B, 0x1A, 0x68, 0x81, 0x23, 0x5B, 0x00, 0xD3, 0x5C, 0x00, 0x2B, 0xE6, 0xD0, 0x02, 0xB0, -+0x1C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xF0, 0xBD, 0xC0, 0x46, 0x80, 0x2A, 0x16, 0x00, 0x0C, 0xE7, 0x10, 0x00, -+0xF4, 0xE1, 0x10, 0x00, 0x50, 0xE0, 0x10, 0x00, 0x31, 0xC3, 0x0A, 0x00, 0xE1, 0xA1, 0x10, 0x00, 0xE9, 0x8F, 0x0C, 0x00, -+0xCD, 0x05, 0x0D, 0x00, 0xF0, 0x29, 0x16, 0x00, 0x5D, 0x74, 0x0B, 0x00, 0x20, 0x27, 0x16, 0x00, 0xD9, 0xEA, 0x0A, 0x00, -+0x00, 0x10, 0x06, 0x04, 0x11, 0x6F, 0x0B, 0x00, 0x99, 0xCA, 0x0A, 0x00, 0x28, 0x27, 0x16, 0x00, 0x01, 0x00, 0x10, 0x00, -+0x84, 0x29, 0x16, 0x00, 0x38, 0x27, 0x16, 0x00, 0xD8, 0xE6, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, 0x10, 0xB5, 0x04, 0x4B, -+0x1B, 0x7F, 0x01, 0x2B, 0x00, 0xD0, 0x10, 0xBD, 0x02, 0x4B, 0x98, 0x47, 0xFB, 0xE7, 0xC0, 0x46, 0x24, 0x2A, 0x16, 0x00, -+0x69, 0x44, 0x0D, 0x00, 0x10, 0xB5, 0x05, 0x4B, 0x80, 0x22, 0xD2, 0x03, 0x1A, 0x60, 0x80, 0x20, 0x40, 0x00, 0x7A, 0xF7, -+0xAF, 0xF8, 0xFF, 0xF7, 0xE7, 0xFF, 0x10, 0xBD, 0x08, 0x41, 0x04, 0x40, 0x70, 0xB5, 0x2D, 0x4B, 0x1B, 0x68, 0xC0, 0x22, -+0x92, 0x02, 0x13, 0x42, 0x16, 0xD1, 0x5A, 0x03, 0x1E, 0xD4, 0x1A, 0x03, 0x2D, 0xD4, 0xDA, 0x02, 0x34, 0xD4, 0x9A, 0x02, -+0x36, 0xD4, 0x5A, 0x02, 0x38, 0xD4, 0xDA, 0x01, 0x39, 0xD4, 0x9A, 0x01, 0x3E, 0xD4, 0x5B, 0x01, 0x0F, 0xD5, 0xFD, 0xF7, -+0x1B, 0xFF, 0x22, 0x4B, 0x80, 0x22, 0xD2, 0x04, 0x1A, 0x60, 0x08, 0xE0, 0x20, 0x4D, 0x91, 0x24, 0xE4, 0x00, 0x00, 0x23, -+0x2B, 0x51, 0x84, 0xF7, 0x7F, 0xFB, 0x1E, 0x4B, 0x2B, 0x51, 0x70, 0xBD, 0x1D, 0x4B, 0x1C, 0x78, 0xFE, 0xF7, 0x84, 0xFE, -+0x02, 0x2C, 0x04, 0xD0, 0x17, 0x4B, 0x80, 0x22, 0xD2, 0x02, 0x1A, 0x60, 0xF3, 0xE7, 0x19, 0x4B, 0x01, 0x22, 0x1A, 0x70, -+0x84, 0xF7, 0x32, 0xFB, 0xED, 0xE7, 0x12, 0x4B, 0x80, 0x22, 0x12, 0x03, 0x1A, 0x60, 0x80, 0x20, 0x40, 0x00, 0x7A, 0xF7, -+0x3F, 0xFD, 0xE4, 0xE7, 0x01, 0x20, 0x84, 0xF7, 0x3D, 0xFB, 0xE0, 0xE7, 0x02, 0x20, 0x84, 0xF7, 0x39, 0xFB, 0xDC, 0xE7, -+0xFF, 0xF7, 0xA6, 0xFF, 0xD9, 0xE7, 0xFA, 0xF7, 0xF1, 0xFD, 0x07, 0x4B, 0x80, 0x22, 0x52, 0x04, 0x1A, 0x60, 0xD2, 0xE7, -+0xFA, 0xF7, 0x9A, 0xFF, 0x03, 0x4B, 0x80, 0x22, 0x92, 0x04, 0x1A, 0x60, 0xCB, 0xE7, 0xC0, 0x46, 0x1C, 0x41, 0x04, 0x40, -+0x08, 0x41, 0x04, 0x40, 0x28, 0x19, 0x16, 0x00, 0x31, 0x6D, 0x10, 0x00, 0xE0, 0x1D, 0x16, 0x00, 0xE1, 0x1D, 0x16, 0x00, -+0x10, 0xB5, 0x04, 0x4B, 0x80, 0x22, 0x12, 0x03, 0x1A, 0x60, 0x80, 0x20, 0x40, 0x00, 0x7A, 0xF7, 0x0F, 0xFD, 0x10, 0xBD, -+0x08, 0x41, 0x04, 0x40, 0x10, 0xB5, 0x09, 0x4B, 0xDB, 0x7F, 0x00, 0x2B, 0x08, 0xD0, 0x00, 0x28, 0x01, 0xD1, 0x00, 0x29, -+0x04, 0xD0, 0x01, 0x20, 0x80, 0xF7, 0xD6, 0xFF, 0x84, 0xF7, 0x00, 0xFD, 0x03, 0x49, 0x40, 0x22, 0x0B, 0x6B, 0x1A, 0x42, -+0xFC, 0xD0, 0x10, 0xBD, 0x3C, 0x95, 0x16, 0x00, 0x00, 0x60, 0x50, 0x40, 0x70, 0xB5, 0x82, 0xB0, 0x27, 0x4A, 0xD3, 0x69, -+0x0F, 0x24, 0xA3, 0x43, 0xD3, 0x61, 0x26, 0x4B, 0x99, 0x68, 0x80, 0x20, 0x01, 0x43, 0x99, 0x60, 0x59, 0x68, 0x01, 0x43, -+0x59, 0x60, 0x19, 0x68, 0x01, 0x43, 0x19, 0x60, 0x13, 0x69, 0xA3, 0x43, 0x13, 0x61, 0x69, 0x46, 0x01, 0xA8, 0xA4, 0xF7, -+0xEF, 0xFC, 0x01, 0x9C, 0x00, 0x9B, 0x1E, 0x00, 0x7A, 0x36, 0x9C, 0x22, 0x92, 0x00, 0x96, 0x42, 0x19, 0xD9, 0xF8, 0x3B, -+0xFF, 0x3B, 0x1E, 0x00, 0x01, 0x34, 0x24, 0x01, 0x24, 0x09, 0x80, 0x25, 0x2D, 0x05, 0x69, 0x46, 0x01, 0xA8, 0xA4, 0xF7, -+0xDB, 0xFC, 0x01, 0x9A, 0xA3, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0xAB, 0x42, 0xF5, 0xD9, 0x12, 0x1B, 0x12, 0x01, 0xF2, 0xD0, -+0x00, 0x9B, 0xB3, 0x42, 0xEF, 0xD3, 0x02, 0xB0, 0x70, 0xBD, 0xB3, 0x42, 0xE9, 0xD2, 0x80, 0x25, 0x2D, 0x05, 0x02, 0xE0, -+0x00, 0x9B, 0xB3, 0x42, 0xF5, 0xD2, 0x69, 0x46, 0x01, 0xA8, 0xA4, 0xF7, 0xC1, 0xFC, 0x01, 0x9A, 0xA3, 0x1A, 0x1B, 0x01, -+0x1B, 0x09, 0xAB, 0x42, 0xF2, 0xD9, 0x12, 0x1B, 0x12, 0x01, 0xEF, 0xD0, 0xE7, 0xE7, 0xC0, 0x46, 0x00, 0x30, 0x50, 0x40, -+0x00, 0x40, 0x50, 0x40, 0x70, 0xB5, 0x10, 0x4B, 0x9A, 0x69, 0x10, 0x4B, 0x1A, 0x42, 0x0A, 0xD1, 0x0F, 0x4D, 0x10, 0x4C, -+0x29, 0x68, 0x00, 0x20, 0xFA, 0xF7, 0xD0, 0xFC, 0x7B, 0xF7, 0x96, 0xFD, 0x23, 0x68, 0x01, 0x2B, 0xF6, 0xD0, 0x0C, 0x4A, -+0x13, 0x68, 0x01, 0x33, 0x13, 0x60, 0x0B, 0x4B, 0x1B, 0x68, 0x03, 0x3B, 0x01, 0x2B, 0x00, 0xD9, 0x70, 0xBD, 0x03, 0x4A, -+0x80, 0x23, 0x1B, 0x02, 0x91, 0x69, 0x0B, 0x43, 0x93, 0x61, 0xF7, 0xE7, 0x3C, 0x95, 0x16, 0x00, 0x01, 0x20, 0x00, 0x00, -+0x58, 0xE6, 0x10, 0x00, 0x5C, 0xE6, 0x10, 0x00, 0x20, 0xE6, 0x10, 0x00, 0x50, 0xE0, 0x10, 0x00, 0x02, 0x38, 0x01, 0x28, -+0x11, 0xD8, 0x09, 0x4A, 0x80, 0x23, 0x5B, 0x00, 0x08, 0x21, 0xD1, 0x50, 0x07, 0x49, 0x8B, 0x68, 0x07, 0x4A, 0x1A, 0x40, -+0x80, 0x23, 0x9B, 0x02, 0x13, 0x43, 0x8B, 0x60, 0x22, 0x22, 0x0B, 0x6B, 0x13, 0x40, 0x02, 0x2B, 0xFB, 0xD1, 0x70, 0x47, -+0x00, 0x00, 0x50, 0x40, 0x00, 0x60, 0x50, 0x40, 0xFF, 0xFF, 0xFB, 0xFF, 0x70, 0xB5, 0xA6, 0xF7, 0x3D, 0xFF, 0x04, 0x1E, -+0x0D, 0xD1, 0x1A, 0x4B, 0x18, 0x68, 0x00, 0x28, 0x09, 0xD0, 0xEF, 0xF3, 0x10, 0x83, 0xDB, 0x07, 0x17, 0xD4, 0x72, 0xB6, -+0x3E, 0x23, 0xC3, 0x5C, 0x00, 0x2B, 0x02, 0xD0, 0x62, 0xB6, 0x20, 0x00, 0x70, 0xBD, 0x13, 0x4B, 0x1D, 0x68, 0x00, 0x21, -+0xCF, 0xF7, 0x7A, 0xFC, 0x2B, 0x6B, 0x5B, 0x00, 0x6A, 0x68, 0x9B, 0x18, 0x1B, 0x01, 0x1B, 0x09, 0x0E, 0x4A, 0x13, 0x60, -+0x0E, 0x4B, 0x98, 0x47, 0xEC, 0xE7, 0x3E, 0x23, 0xC3, 0x5C, 0x00, 0x2B, 0xE9, 0xD1, 0x09, 0x4B, 0x1D, 0x68, 0x00, 0x21, -+0xCF, 0xF7, 0x66, 0xFC, 0x2B, 0x6B, 0x5B, 0x00, 0x6A, 0x68, 0x9B, 0x18, 0x1B, 0x01, 0x1B, 0x09, 0x04, 0x4A, 0x13, 0x60, -+0x04, 0x4B, 0x98, 0x47, 0xD9, 0xE7, 0xC0, 0x46, 0x28, 0x27, 0x16, 0x00, 0x24, 0x27, 0x16, 0x00, 0x18, 0x2C, 0x16, 0x00, -+0x15, 0xE6, 0x0A, 0x00, 0x10, 0xB5, 0xA5, 0xF7, 0xC7, 0xFA, 0x00, 0x28, 0x0F, 0xD1, 0x0B, 0x4B, 0x19, 0x68, 0x00, 0x29, -+0x0B, 0xD0, 0x0A, 0x4B, 0xCB, 0x61, 0x0A, 0x4B, 0x1C, 0x00, 0x41, 0x34, 0xFF, 0x34, 0x1A, 0x78, 0x09, 0x2A, 0x03, 0xD0, -+0x40, 0x33, 0xA3, 0x42, 0xF9, 0xD1, 0x10, 0xBD, 0x0B, 0x69, 0x05, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x0B, 0x61, 0xF8, 0xE7, -+0x18, 0x27, 0x16, 0x00, 0x51, 0x04, 0x10, 0x00, 0x70, 0xA6, 0x16, 0x00, 0x78, 0xEC, 0xFF, 0xFF, 0x10, 0xB5, 0x02, 0x00, -+0x0C, 0x00, 0x01, 0x23, 0x00, 0x21, 0x03, 0x48, 0x7A, 0xF7, 0xC2, 0xFF, 0x04, 0x70, 0xCC, 0xF7, 0x1F, 0xFE, 0x10, 0xBD, -+0x01, 0x11, 0x00, 0x00, 0x10, 0xB5, 0x02, 0x00, 0x0C, 0x00, 0x01, 0x23, 0x00, 0x21, 0x03, 0x48, 0x7A, 0xF7, 0xB4, 0xFF, -+0x04, 0x70, 0xCC, 0xF7, 0x11, 0xFE, 0x10, 0xBD, 0x02, 0x11, 0x00, 0x00, 0x10, 0xB5, 0x06, 0x23, 0x13, 0x4A, 0x00, 0x21, -+0x13, 0x48, 0x7A, 0xF7, 0xA7, 0xFF, 0x13, 0x4A, 0x2D, 0x23, 0xD3, 0x5C, 0x1B, 0x09, 0x12, 0x4A, 0x12, 0x78, 0x02, 0x2A, -+0x0B, 0xD0, 0x01, 0x2A, 0x10, 0xD0, 0x0E, 0x4A, 0x2D, 0x23, 0xD3, 0x5C, 0x03, 0x71, 0x00, 0x23, 0x03, 0x70, 0xCC, 0xF7, -+0xF5, 0xFD, 0x00, 0x20, 0x10, 0xBD, 0x0B, 0x4A, 0xD2, 0x5C, 0x80, 0x23, 0x9B, 0x00, 0x13, 0x43, 0x43, 0x80, 0xEE, 0xE7, -+0x08, 0x4A, 0xD2, 0x5C, 0x80, 0x23, 0x5B, 0x00, 0x13, 0x43, 0x43, 0x80, 0xE7, 0xE7, 0xC0, 0x46, 0x2D, 0x0C, 0x00, 0x00, -+0x01, 0x11, 0x00, 0x00, 0x60, 0x92, 0x16, 0x00, 0xB4, 0xE5, 0x10, 0x00, 0x30, 0xE0, 0x10, 0x00, 0x28, 0xE0, 0x10, 0x00, -+0x10, 0xB5, 0x03, 0x00, 0x08, 0x00, 0x19, 0x78, 0x03, 0x4A, 0x2D, 0x23, 0xD1, 0x54, 0x00, 0x21, 0xFF, 0xF7, 0xB2, 0xFF, -+0x00, 0x20, 0x10, 0xBD, 0x60, 0x92, 0x16, 0x00, 0x70, 0xB5, 0x82, 0xB0, 0x04, 0x00, 0x0D, 0x00, 0xD1, 0xF7, 0x96, 0xFF, -+0x06, 0x00, 0x2C, 0x4B, 0x99, 0x6F, 0x00, 0x29, 0x15, 0xD0, 0xF8, 0x22, 0x20, 0x00, 0xD1, 0xF7, 0xBB, 0xFF, 0x00, 0x21, -+0x00, 0x28, 0x0A, 0xD1, 0x26, 0x4A, 0x30, 0x23, 0xD3, 0x5C, 0x01, 0x2B, 0x21, 0xD0, 0x28, 0x00, 0xFF, 0xF7, 0x86, 0xFF, -+0x00, 0x20, 0x02, 0xB0, 0x70, 0xBD, 0x21, 0x4B, 0x98, 0x6F, 0x7B, 0xF7, 0xBF, 0xF8, 0xFF, 0x20, 0x06, 0x40, 0xF8, 0x2E, -+0x00, 0xD9, 0xF8, 0x26, 0x70, 0x1C, 0x00, 0x21, 0x7B, 0xF7, 0x12, 0xF8, 0x1A, 0x4B, 0x98, 0x67, 0x07, 0x21, 0x00, 0x28, -+0xE2, 0xD0, 0x32, 0x00, 0x21, 0x00, 0xD1, 0xF7, 0x2F, 0xFE, 0x16, 0x4B, 0x9B, 0x6F, 0x00, 0x22, 0x9A, 0x55, 0x00, 0x21, -+0xD8, 0xE7, 0x7F, 0x33, 0x5B, 0x00, 0x2F, 0x22, 0x00, 0x21, 0x12, 0x48, 0x7A, 0xF7, 0x2A, 0xFF, 0x06, 0x00, 0x01, 0xA9, -+0x0D, 0x70, 0x2D, 0x0A, 0x4D, 0x70, 0xF8, 0x23, 0x8B, 0x70, 0x03, 0x22, 0xD1, 0xF7, 0x18, 0xFE, 0xF0, 0x1C, 0xF8, 0x22, -+0x21, 0x00, 0xD1, 0xF7, 0x13, 0xFE, 0x0A, 0x4B, 0x01, 0x22, 0x1A, 0x70, 0x30, 0x00, 0x0C, 0x38, 0x08, 0x4B, 0x98, 0x47, -+0x08, 0x4B, 0x5B, 0x7F, 0x5B, 0xB2, 0x04, 0x2B, 0xBE, 0xDC, 0x01, 0x33, 0x05, 0x4A, 0x53, 0x77, 0xBA, 0xE7, 0xC0, 0x46, -+0x68, 0x9E, 0x16, 0x00, 0x03, 0x11, 0x00, 0x00, 0x68, 0xE6, 0x10, 0x00, 0xA5, 0x4B, 0x0D, 0x00, 0x24, 0x2A, 0x16, 0x00, -+0xF8, 0xB5, 0x04, 0x00, 0x0D, 0x00, 0x16, 0x00, 0x1F, 0x00, 0x02, 0x20, 0x79, 0xF7, 0x46, 0xFE, 0x6B, 0x1E, 0x1C, 0x70, -+0x63, 0x1E, 0x03, 0x2B, 0x22, 0xD8, 0x04, 0x2C, 0x10, 0xD0, 0x68, 0x1E, 0x16, 0x4B, 0x18, 0x61, 0x1E, 0x83, 0x5F, 0x61, -+0x1B, 0x7F, 0xFF, 0x2B, 0x25, 0xD1, 0x13, 0x4B, 0x00, 0x22, 0x1A, 0x77, 0x71, 0x1C, 0x1A, 0x68, 0x54, 0x68, 0x11, 0x4A, -+0xA0, 0x47, 0x1C, 0xE0, 0x2B, 0x78, 0x2F, 0x2B, 0xEB, 0xD1, 0x0F, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0xE7, 0xD0, 0x19, 0x23, -+0x2B, 0x70, 0xE2, 0x33, 0x6B, 0x70, 0x0B, 0x4B, 0x00, 0x22, 0x1A, 0x70, 0xFD, 0x26, 0xDE, 0xE7, 0x09, 0x4D, 0x00, 0x23, -+0x00, 0x22, 0x01, 0x21, 0x20, 0x00, 0xEE, 0x6E, 0xB0, 0x47, 0xED, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x01, 0x21, 0x20, 0x00, -+0xA8, 0x47, 0xF8, 0xBD, 0x58, 0x1E, 0x16, 0x00, 0x19, 0x74, 0x08, 0x00, 0x68, 0xE6, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, -+0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0xC0, 0xB5, 0x86, 0xB0, 0x04, 0x00, 0x0E, 0x00, 0x03, 0x92, 0xCE, 0xF7, -+0x93, 0xFE, 0x07, 0x00, 0xB8, 0x4B, 0x1D, 0x25, 0x5D, 0x57, 0x2B, 0x00, 0x80, 0x33, 0x00, 0xD1, 0x61, 0xE1, 0x01, 0x3D, -+0x6D, 0xB2, 0xB4, 0x4B, 0x5D, 0x77, 0x00, 0x28, 0x00, 0xD1, 0x18, 0xE1, 0x00, 0x2D, 0x00, 0xDA, 0x59, 0xE1, 0x80, 0x78, -+0x0F, 0x23, 0x18, 0x40, 0x08, 0x28, 0x5F, 0xD8, 0x83, 0x00, 0xAE, 0x4A, 0xD3, 0x58, 0x9F, 0x46, 0x05, 0x23, 0x99, 0x46, -+0x67, 0xE0, 0x06, 0x28, 0x1E, 0xD0, 0x01, 0x2E, 0x00, 0xD8, 0x3B, 0xE1, 0x03, 0x9A, 0x53, 0x78, 0x1B, 0x02, 0x12, 0x78, -+0x13, 0x43, 0x0B, 0x2B, 0x00, 0xD9, 0x22, 0xE1, 0xA5, 0x4A, 0xD2, 0x18, 0x12, 0x7E, 0x00, 0x2A, 0x00, 0xD1, 0x2D, 0xE1, -+0xA2, 0x04, 0x37, 0xD4, 0xA2, 0x4A, 0x94, 0x42, 0x34, 0xD0, 0x27, 0xD8, 0xA1, 0x4A, 0x94, 0x42, 0x30, 0xD0, 0xA1, 0x4A, -+0x94, 0x42, 0x00, 0xD0, 0x20, 0xE1, 0x2B, 0xE0, 0x05, 0x2E, 0x00, 0xD8, 0x1C, 0xE1, 0x9E, 0x4D, 0x00, 0x23, 0x99, 0x46, -+0x07, 0xE0, 0x01, 0x23, 0x9C, 0x46, 0xE1, 0x44, 0x07, 0x35, 0x4B, 0x46, 0x07, 0x2B, 0x00, 0xD1, 0x10, 0xE1, 0x2B, 0x78, -+0x00, 0x2B, 0xF4, 0xD0, 0x69, 0x1C, 0x06, 0x22, 0x03, 0x98, 0xD1, 0xF7, 0x2D, 0xFD, 0x00, 0x28, 0xED, 0xD1, 0x4B, 0x46, -+0x1B, 0x02, 0x01, 0x22, 0x13, 0x43, 0x9B, 0xB2, 0x99, 0x46, 0x26, 0xE0, 0x90, 0x4A, 0x94, 0x42, 0x04, 0xD8, 0x90, 0x4A, -+0x94, 0x42, 0x00, 0xD8, 0xF8, 0xE0, 0x03, 0xE0, 0x8E, 0x4A, 0x94, 0x42, 0x00, 0xD0, 0xF3, 0xE0, 0x1B, 0x02, 0x04, 0x22, -+0x13, 0x43, 0x9B, 0xB2, 0x99, 0x46, 0x14, 0xE0, 0x1B, 0x02, 0x01, 0x22, 0x13, 0x43, 0x9B, 0xB2, 0x99, 0x46, 0x0E, 0xE0, -+0x87, 0x4B, 0xDD, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x21, 0x00, 0xA8, 0x47, 0xAF, 0xE0, 0x03, 0x23, 0x99, 0x46, 0x04, 0xE0, -+0x02, 0x23, 0x99, 0x46, 0x01, 0xE0, 0x00, 0x23, 0x99, 0x46, 0x0E, 0x23, 0x02, 0xAA, 0x94, 0x46, 0x63, 0x44, 0x00, 0x22, -+0x1A, 0x80, 0x7E, 0x4B, 0x92, 0x46, 0x9C, 0x42, 0x59, 0xD0, 0x00, 0x2E, 0x00, 0xD1, 0xAD, 0xE0, 0x7D, 0x68, 0x00, 0x2D, -+0x00, 0xD1, 0x9C, 0xE0, 0xBB, 0x78, 0x5B, 0x06, 0x65, 0xD5, 0xB3, 0xB2, 0x0E, 0x22, 0x02, 0xA9, 0x8C, 0x46, 0x62, 0x44, -+0x03, 0x99, 0x00, 0x20, 0xA8, 0x47, 0xC5, 0xB2, 0x01, 0x2D, 0x66, 0xD0, 0x0E, 0x23, 0x02, 0xAA, 0x94, 0x46, 0x63, 0x44, -+0x1B, 0x88, 0x22, 0x00, 0x49, 0x46, 0x6F, 0x48, 0x7A, 0xF7, 0x00, 0xFE, 0x81, 0x46, 0x00, 0x2D, 0x07, 0xD0, 0x6A, 0x4B, -+0xDB, 0x6E, 0x9B, 0x46, 0x00, 0x23, 0x00, 0x22, 0x21, 0x00, 0x28, 0x00, 0xD8, 0x47, 0x4B, 0x46, 0x00, 0x2B, 0x59, 0xD0, -+0x0E, 0x23, 0x02, 0xAA, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x88, 0x00, 0x2B, 0x0F, 0xD0, 0x7B, 0x68, 0x9B, 0x46, 0x00, 0x2B, -+0x0B, 0xD0, 0xBB, 0x78, 0x5B, 0x06, 0x51, 0xD5, 0xB3, 0xB2, 0x0E, 0x22, 0x02, 0xA9, 0x8C, 0x46, 0x62, 0x44, 0x03, 0x99, -+0x48, 0x46, 0xD8, 0x47, 0xC5, 0xB2, 0x00, 0x2D, 0x06, 0xD0, 0x58, 0x4B, 0xDE, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x21, 0x00, -+0x28, 0x00, 0xB0, 0x47, 0x48, 0x46, 0x7A, 0xF7, 0xF9, 0xFD, 0x54, 0x4B, 0x9C, 0x42, 0x4A, 0xD1, 0x53, 0x46, 0x00, 0x2B, -+0x47, 0xD0, 0x50, 0x46, 0x7A, 0xF7, 0x3C, 0xFF, 0x43, 0xE0, 0x75, 0x1C, 0x01, 0x21, 0x28, 0x00, 0x7A, 0xF7, 0x92, 0xFE, -+0x82, 0x46, 0x03, 0x99, 0x0B, 0x78, 0x03, 0x70, 0x72, 0x1E, 0x42, 0x70, 0x01, 0x31, 0x02, 0x30, 0xD1, 0xF7, 0xAE, 0xFC, -+0xEE, 0xB2, 0x49, 0x48, 0x7C, 0xF7, 0xB6, 0xFE, 0x53, 0x46, 0x03, 0x93, 0x8F, 0xE7, 0xB3, 0xB2, 0x00, 0x95, 0x0E, 0x22, -+0x02, 0xA9, 0x8C, 0x46, 0x62, 0x44, 0x03, 0x99, 0x00, 0x20, 0x7D, 0xF7, 0x57, 0xF8, 0x05, 0x00, 0x96, 0xE7, 0x21, 0x00, -+0x40, 0x48, 0x7C, 0xF7, 0xA3, 0xFE, 0x00, 0x23, 0x12, 0x22, 0x21, 0x00, 0x38, 0x00, 0x3E, 0x4D, 0xA8, 0x47, 0xC8, 0xE7, -+0x07, 0x22, 0x21, 0x00, 0x38, 0x00, 0x3B, 0x4D, 0xA8, 0x47, 0xC2, 0xE7, 0xB3, 0xB2, 0x5A, 0x46, 0x00, 0x92, 0x0E, 0x22, -+0x62, 0x44, 0x03, 0x99, 0x48, 0x46, 0x7D, 0xF7, 0x3B, 0xF8, 0x05, 0x00, 0xAB, 0xE7, 0x00, 0x23, 0x01, 0x22, 0x21, 0x00, -+0x00, 0x20, 0x32, 0x4C, 0xA0, 0x47, 0x06, 0xB0, 0x1C, 0xBC, 0x91, 0x46, 0x9A, 0x46, 0xA3, 0x46, 0xF0, 0xBD, 0x0E, 0x23, -+0x02, 0xAA, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x88, 0x22, 0x00, 0x49, 0x46, 0x27, 0x48, 0x7A, 0xF7, 0x71, 0xFD, 0x81, 0x46, -+0x04, 0x25, 0x70, 0xE7, 0x0E, 0x23, 0x02, 0xAA, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x88, 0x22, 0x00, 0x49, 0x46, 0x21, 0x48, -+0x7A, 0xF7, 0x64, 0xFD, 0x81, 0x46, 0x35, 0x00, 0x6B, 0xE7, 0x22, 0x4A, 0x13, 0x40, 0x1A, 0x00, 0x80, 0x3A, 0x92, 0xB2, -+0x06, 0x2A, 0x09, 0xD8, 0x80, 0x3B, 0xD9, 0x00, 0xC9, 0x1A, 0x0F, 0x4A, 0x52, 0x18, 0x24, 0x32, 0x12, 0x78, 0x02, 0x2A, -+0x00, 0xD1, 0x11, 0xE7, 0x21, 0x00, 0x1A, 0x48, 0x7C, 0xF7, 0x50, 0xFE, 0x03, 0x9B, 0x02, 0x22, 0x21, 0x00, 0x38, 0x00, -+0x14, 0x4C, 0xA0, 0x47, 0xC3, 0xE7, 0x00, 0x28, 0xBB, 0xD0, 0x00, 0x23, 0x07, 0x22, 0x21, 0x00, 0x38, 0x00, 0x10, 0x4C, -+0xA0, 0x47, 0xBA, 0xE7, 0x24, 0x2A, 0x16, 0x00, 0x2C, 0xD2, 0x10, 0x00, 0xCC, 0xAA, 0x16, 0x00, 0x2D, 0x0C, 0x00, 0x00, -+0x06, 0x04, 0x00, 0x00, 0x1D, 0x04, 0x00, 0x00, 0xF0, 0xAA, 0x16, 0x00, 0x7C, 0x0C, 0x00, 0x00, 0x7A, 0x0C, 0x00, 0x00, -+0x05, 0x14, 0x00, 0x00, 0x28, 0x19, 0x16, 0x00, 0x57, 0xFD, 0x00, 0x00, 0x05, 0x11, 0x00, 0x00, 0x14, 0xD2, 0x10, 0x00, -+0x20, 0xD2, 0x10, 0x00, 0x7D, 0x4A, 0x0D, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0x08, 0xD2, 0x10, 0x00, 0x10, 0xB5, 0x07, 0x20, -+0x7B, 0xF7, 0x10, 0xFA, 0x08, 0x4C, 0xA1, 0x7A, 0x20, 0x89, 0x62, 0x68, 0xFF, 0xF7, 0x54, 0xFE, 0x60, 0x68, 0x00, 0x28, -+0x03, 0xD0, 0x7A, 0xF7, 0x7F, 0xFE, 0x00, 0x22, 0x62, 0x60, 0x02, 0x48, 0x02, 0x4B, 0x98, 0x47, 0x10, 0xBD, 0xC0, 0x46, -+0x58, 0x1E, 0x16, 0x00, 0xA5, 0x73, 0x08, 0x00, 0x30, 0xB5, 0x0C, 0x4C, 0x25, 0x68, 0x29, 0x60, 0x24, 0x68, 0x60, 0x60, -+0xA2, 0x60, 0xE3, 0x60, 0x09, 0x4B, 0x0A, 0x4A, 0x98, 0x50, 0x0A, 0x48, 0x1A, 0x58, 0x0A, 0x43, 0x1A, 0x50, 0x04, 0x30, -+0x1A, 0x58, 0x11, 0x43, 0x19, 0x50, 0x07, 0x49, 0x5A, 0x58, 0x01, 0x20, 0x02, 0x43, 0x5A, 0x50, 0x30, 0xBD, 0xC0, 0x46, -+0xFC, 0xE1, 0x10, 0x00, 0x00, 0x00, 0x07, 0x40, 0x10, 0x10, 0x00, 0x00, 0x1C, 0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, -+0x70, 0xB5, 0x0D, 0x00, 0x1A, 0x4C, 0x30, 0x21, 0x61, 0x5C, 0x01, 0x29, 0x04, 0xD0, 0x29, 0x00, 0x18, 0x4C, 0xA0, 0x47, -+0x00, 0x20, 0x70, 0xBD, 0x14, 0x0A, 0x84, 0xF7, 0x99, 0xFD, 0x06, 0x1E, 0x1F, 0xD0, 0x6A, 0x88, 0xA9, 0x88, 0x14, 0x4B, -+0x9C, 0x46, 0x61, 0x44, 0x00, 0x89, 0x60, 0x44, 0xD1, 0xF7, 0xB8, 0xFB, 0x08, 0x23, 0x00, 0x22, 0x21, 0x00, 0x10, 0x48, -+0x7A, 0xF7, 0xBA, 0xFC, 0x33, 0x89, 0x43, 0x60, 0x2B, 0x88, 0x03, 0x80, 0x6B, 0x88, 0x43, 0x80, 0xCC, 0xF7, 0x12, 0xFB, -+0x20, 0x00, 0x80, 0x30, 0x01, 0x21, 0x0A, 0x4B, 0x98, 0x47, 0xA8, 0x88, 0x84, 0xF7, 0xCA, 0xFD, 0xD8, 0xE7, 0x08, 0x4B, -+0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xEF, 0xE7, 0x68, 0x9E, 0x16, 0x00, 0x49, 0x86, 0x0A, 0x00, -+0x00, 0x00, 0x61, 0x40, 0x06, 0x11, 0x00, 0x00, 0xC1, 0xDC, 0x09, 0x00, 0x28, 0x19, 0x16, 0x00, 0x42, 0x7A, 0x12, 0x02, -+0x03, 0x7A, 0x13, 0x43, 0x0B, 0x80, 0x83, 0x7A, 0x8B, 0x70, 0x70, 0x47, 0xC2, 0x7A, 0x12, 0x02, 0x83, 0x7A, 0x13, 0x43, -+0x4B, 0x80, 0x42, 0x7A, 0x12, 0x02, 0x03, 0x7A, 0x13, 0x43, 0x0B, 0x80, 0x70, 0x47, 0x83, 0x7A, 0x8B, 0x70, 0x42, 0x7A, -+0x12, 0x02, 0x03, 0x7A, 0x13, 0x43, 0x0B, 0x80, 0x70, 0x47, 0x00, 0x00, 0x10, 0xB5, 0x03, 0x00, 0x00, 0x22, 0x02, 0x73, -+0x0B, 0x30, 0x1A, 0x68, 0x14, 0x68, 0x03, 0x4A, 0x01, 0x21, 0xA0, 0x47, 0x04, 0x20, 0x7A, 0xF7, 0x91, 0xF8, 0x10, 0xBD, -+0x59, 0x78, 0x10, 0x00, 0x10, 0xB5, 0x03, 0x00, 0x01, 0x22, 0x02, 0x73, 0x08, 0x30, 0x1A, 0x68, 0x14, 0x68, 0x03, 0x4A, -+0xA0, 0x47, 0x04, 0x20, 0x79, 0xF7, 0xAC, 0xFB, 0x10, 0xBD, 0xC0, 0x46, 0x59, 0x78, 0x10, 0x00, 0x10, 0xB5, 0x03, 0x00, -+0x02, 0x22, 0x02, 0x73, 0x40, 0x68, 0x1A, 0x68, 0x14, 0x68, 0x01, 0x4A, 0xA0, 0x47, 0x10, 0xBD, 0x59, 0x78, 0x10, 0x00, -+0x10, 0xB5, 0x03, 0x00, 0x03, 0x22, 0x02, 0x73, 0x0B, 0x30, 0x1A, 0x68, 0x14, 0x68, 0x02, 0x4A, 0x01, 0x21, 0xA0, 0x47, -+0x10, 0xBD, 0xC0, 0x46, 0x59, 0x78, 0x10, 0x00, 0x10, 0xB5, 0x04, 0x00, 0x01, 0x23, 0x10, 0x22, 0x00, 0x21, 0x0B, 0x48, -+0x7A, 0xF7, 0x38, 0xFC, 0x00, 0x23, 0x03, 0x70, 0xCC, 0xF7, 0x94, 0xFA, 0x20, 0x00, 0x08, 0x30, 0x02, 0x22, 0x00, 0x21, -+0x78, 0xF7, 0xB2, 0xFC, 0xE3, 0x7A, 0xA3, 0x72, 0x20, 0x00, 0xFF, 0xF7, 0xDB, 0xFF, 0x04, 0x20, 0x7A, 0xF7, 0x4A, 0xF8, -+0x10, 0xBD, 0xC0, 0x46, 0x03, 0x11, 0x00, 0x00, 0x10, 0xB5, 0x06, 0x20, 0x7B, 0xF7, 0x1A, 0xF9, 0x16, 0x4C, 0x17, 0x49, -+0x20, 0x00, 0xFF, 0xF7, 0x83, 0xFF, 0xA4, 0x7A, 0x00, 0x2C, 0x09, 0xD1, 0x12, 0x4C, 0x20, 0x89, 0x00, 0x22, 0x00, 0x21, -+0xFF, 0xF7, 0x56, 0xFD, 0x20, 0x00, 0xFF, 0xF7, 0x93, 0xFF, 0x10, 0xBD, 0x0D, 0x4B, 0x18, 0x89, 0xCD, 0xF7, 0x9C, 0xFA, -+0x84, 0x42, 0x03, 0xD9, 0x0A, 0x48, 0xFF, 0xF7, 0xC3, 0xFF, 0xF4, 0xE7, 0x08, 0x4C, 0xA0, 0x7A, 0x01, 0x21, 0x7A, 0xF7, -+0xCF, 0xFC, 0x60, 0x60, 0x00, 0x28, 0x04, 0xD0, 0x20, 0x00, 0xA1, 0x7A, 0xFF, 0xF7, 0x9C, 0xFF, 0xE7, 0xE7, 0x02, 0x48, -+0xFF, 0xF7, 0xB2, 0xFF, 0xE3, 0xE7, 0xC0, 0x46, 0x58, 0x1E, 0x16, 0x00, 0x60, 0x1E, 0x16, 0x00, 0x10, 0xB5, 0x82, 0xB0, -+0x04, 0x00, 0x0E, 0x4B, 0x01, 0x93, 0x01, 0x00, 0x08, 0x31, 0x04, 0x22, 0x01, 0xA8, 0xD1, 0xF7, 0xB5, 0xFA, 0x00, 0x28, -+0x0B, 0xD0, 0x04, 0x20, 0x79, 0xF7, 0x2A, 0xFB, 0x63, 0x7A, 0x23, 0x72, 0xA3, 0x7A, 0x63, 0x72, 0xE3, 0x7A, 0xA3, 0x72, -+0x00, 0x20, 0x02, 0xB0, 0x10, 0xBD, 0x00, 0x22, 0x00, 0x21, 0x03, 0x48, 0xCD, 0xF7, 0x6C, 0xFA, 0x01, 0x20, 0xF6, 0xE7, -+0x01, 0x03, 0x0C, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x10, 0xB5, 0x04, 0x00, 0x00, 0x29, 0x0B, 0xD0, 0x01, 0x29, 0x02, 0xD0, -+0x03, 0x7B, 0x00, 0x2B, 0x03, 0xD0, 0x20, 0x00, 0xFF, 0xF7, 0x7C, 0xFF, 0x10, 0xBD, 0xFF, 0xF7, 0x3F, 0xFF, 0xFB, 0xE7, -+0x03, 0x7B, 0x02, 0x2B, 0x44, 0xD0, 0x0F, 0xD8, 0x00, 0x2B, 0x17, 0xD0, 0x40, 0x7B, 0x02, 0x28, 0x25, 0xD0, 0x03, 0x28, -+0x27, 0xD0, 0x01, 0x28, 0x1D, 0xD0, 0xA1, 0x7B, 0x34, 0x4B, 0xDC, 0x6E, 0x00, 0x23, 0x00, 0x22, 0xA0, 0x47, 0xE7, 0xE7, -+0x03, 0x2B, 0x59, 0xD1, 0xFF, 0xF7, 0xB4, 0xFF, 0x00, 0x28, 0x51, 0xD0, 0x20, 0x00, 0xFF, 0xF7, 0x21, 0xFF, 0xDD, 0xE7, -+0xC3, 0x7A, 0x43, 0x73, 0x5A, 0x1E, 0x02, 0x2A, 0x04, 0xD8, 0x2B, 0x4A, 0xD1, 0x5C, 0xFF, 0xF7, 0x27, 0xFF, 0xD3, 0xE7, -+0xFF, 0xF7, 0x4E, 0xFF, 0xD0, 0xE7, 0x05, 0x30, 0x7B, 0xF7, 0x5E, 0xF8, 0xCC, 0xE7, 0x08, 0x20, 0x7B, 0xF7, 0x5A, 0xF8, -+0xC8, 0xE7, 0x21, 0x00, 0x08, 0x31, 0x20, 0x00, 0xFF, 0xF7, 0xFD, 0xFE, 0xA1, 0x7A, 0x20, 0x89, 0xCD, 0xF7, 0x2E, 0xFC, -+0x60, 0x60, 0x00, 0x28, 0x04, 0xD0, 0xA1, 0x7A, 0x20, 0x00, 0xFF, 0xF7, 0x1B, 0xFF, 0xB7, 0xE7, 0x20, 0x00, 0xFF, 0xF7, -+0x31, 0xFF, 0xB3, 0xE7, 0x40, 0x7B, 0x02, 0x28, 0x0E, 0xD0, 0x03, 0x28, 0x15, 0xD0, 0x01, 0x28, 0x06, 0xD0, 0xA1, 0x7B, -+0x13, 0x4B, 0xDC, 0x6E, 0x00, 0x23, 0x00, 0x22, 0xA0, 0x47, 0xA5, 0xE7, 0x06, 0x30, 0x7B, 0xF7, 0x33, 0xF8, 0xA1, 0xE7, -+0x61, 0x89, 0x20, 0x89, 0x62, 0x68, 0xCD, 0xF7, 0xB9, 0xFB, 0x20, 0x00, 0xFF, 0xF7, 0xDC, 0xFE, 0x98, 0xE7, 0xA1, 0x7A, -+0x20, 0x89, 0x62, 0x68, 0xCD, 0xF7, 0x2E, 0xFC, 0x20, 0x00, 0xFF, 0xF7, 0xD3, 0xFE, 0x8F, 0xE7, 0x20, 0x00, 0xFF, 0xF7, -+0xFB, 0xFE, 0x8B, 0xE7, 0x03, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x84, 0xE7, 0xC0, 0x46, -+0x28, 0x19, 0x16, 0x00, 0xC8, 0xDF, 0x10, 0x00, 0x70, 0xB5, 0x0C, 0x00, 0x03, 0x05, 0x1B, 0x0D, 0x82, 0x0B, 0x0B, 0x2B, -+0x1C, 0xD8, 0x00, 0x2A, 0x4C, 0xD1, 0x19, 0x02, 0x04, 0x22, 0x0A, 0x43, 0x92, 0xB2, 0xF8, 0x21, 0x09, 0x01, 0x08, 0x42, -+0x1F, 0xD1, 0xFB, 0x21, 0xFF, 0x2A, 0x46, 0xD0, 0x8C, 0x42, 0x44, 0xD8, 0xFF, 0x23, 0x13, 0x40, 0x02, 0x2B, 0x26, 0xD9, -+0x04, 0x2B, 0x26, 0xD1, 0xB3, 0xF7, 0x8A, 0xFC, 0x00, 0x28, 0x3A, 0xD0, 0x25, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0x46, 0xE0, -+0x01, 0x2A, 0x31, 0xD0, 0x00, 0x2A, 0x32, 0xD1, 0xF8, 0x22, 0x12, 0x01, 0x10, 0x42, 0x2E, 0xD0, 0x00, 0x21, 0xFF, 0x22, -+0x86, 0x2B, 0xE1, 0xD8, 0x00, 0xE0, 0xFB, 0x21, 0x80, 0x3B, 0xDD, 0x00, 0xED, 0x1A, 0x1C, 0x48, 0x40, 0x19, 0x24, 0x30, -+0x00, 0x78, 0x02, 0x28, 0xD6, 0xD1, 0x1B, 0x02, 0x01, 0x22, 0x1A, 0x43, 0x92, 0xB2, 0x18, 0x49, 0xD2, 0xE7, 0x00, 0x2B, -+0x06, 0xD1, 0x17, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x10, 0xE0, 0x84, 0xF7, 0xE0, 0xFB, -+0x00, 0x28, 0x03, 0xD0, 0x0E, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0x18, 0xE0, 0x10, 0x48, 0x7C, 0xF7, 0xEB, 0xFB, 0x04, 0xE0, -+0x01, 0x2A, 0x02, 0xD1, 0x0B, 0x4B, 0x9C, 0x42, 0xEE, 0xD9, 0x01, 0x23, 0x1A, 0x22, 0x00, 0x21, 0x0B, 0x48, 0x7A, 0xF7, -+0xDB, 0xFA, 0x01, 0x25, 0x05, 0x70, 0xCC, 0xF7, 0x37, 0xF9, 0x01, 0x21, 0x20, 0x00, 0x7A, 0xF7, 0xA5, 0xFB, 0x07, 0x4B, -+0x9D, 0x77, 0x70, 0xBD, 0x00, 0x00, 0x61, 0x40, 0xCC, 0xAA, 0x16, 0x00, 0xFD, 0x03, 0x00, 0x00, 0x28, 0x19, 0x16, 0x00, -+0x50, 0xD2, 0x10, 0x00, 0x03, 0x11, 0x00, 0x00, 0x24, 0x2A, 0x16, 0x00, 0x10, 0xB5, 0x08, 0x20, 0x7A, 0xF7, 0xBA, 0xFF, -+0x10, 0x4C, 0x11, 0x49, 0x20, 0x00, 0xFF, 0xF7, 0x2B, 0xFE, 0x61, 0x89, 0x00, 0x29, 0x0E, 0xD0, 0x20, 0x89, 0xFF, 0xF7, -+0x77, 0xFF, 0x60, 0x60, 0x00, 0x28, 0x04, 0xD0, 0x09, 0x48, 0x41, 0x89, 0xFF, 0xF7, 0x52, 0xFE, 0x0C, 0xE0, 0x20, 0x00, -+0xFF, 0xF7, 0x68, 0xFE, 0x08, 0xE0, 0x05, 0x4C, 0x20, 0x89, 0x00, 0x22, 0x00, 0x21, 0xCD, 0xF7, 0x01, 0xFB, 0x20, 0x00, -+0xFF, 0xF7, 0x24, 0xFE, 0x10, 0xBD, 0xC0, 0x46, 0x58, 0x1E, 0x16, 0x00, 0x60, 0x1E, 0x16, 0x00, 0x10, 0xB5, 0x7F, 0xF7, -+0xBD, 0xFD, 0x06, 0x49, 0x06, 0x20, 0x7A, 0xF7, 0x47, 0xFF, 0x05, 0x49, 0x07, 0x20, 0x7A, 0xF7, 0x43, 0xFF, 0x04, 0x49, -+0x08, 0x20, 0x7A, 0xF7, 0x3F, 0xFF, 0x10, 0xBD, 0xA5, 0x77, 0x10, 0x00, 0xB9, 0x75, 0x10, 0x00, 0x65, 0x7A, 0x10, 0x00, -+0x10, 0xB5, 0x0A, 0x00, 0x41, 0x23, 0x00, 0x21, 0x0C, 0x48, 0x7A, 0xF7, 0x7B, 0xFA, 0x04, 0x00, 0x01, 0x30, 0x28, 0x22, -+0x0A, 0x49, 0xD1, 0xF7, 0x6D, 0xF9, 0xE2, 0x79, 0x2F, 0x23, 0x13, 0x40, 0xE3, 0x71, 0x20, 0x00, 0x29, 0x30, 0x18, 0x22, -+0x00, 0x21, 0x78, 0xF7, 0xEF, 0xFA, 0x00, 0x23, 0x23, 0x70, 0x20, 0x00, 0xCC, 0xF7, 0xC6, 0xF8, 0x00, 0x20, 0x10, 0xBD, -+0x01, 0x11, 0x00, 0x00, 0xA4, 0xB5, 0x0D, 0x00, 0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x0D, 0x00, 0x90, 0x46, 0x06, 0x0A, -+0xB2, 0x00, 0x11, 0x4B, 0xD7, 0x58, 0x0C, 0x23, 0x03, 0x22, 0x00, 0x21, 0x0F, 0x48, 0x7A, 0xF7, 0x51, 0xFA, 0x04, 0x00, -+0x43, 0x46, 0x03, 0x70, 0x2D, 0x02, 0x81, 0x35, 0xFF, 0x35, 0x75, 0x19, 0x45, 0x80, 0x00, 0x23, 0x83, 0x72, 0x88, 0x23, -+0xFF, 0x33, 0xFB, 0x5C, 0xC3, 0x72, 0x39, 0x00, 0x72, 0x31, 0x04, 0x30, 0x06, 0x22, 0xD1, 0xF7, 0x35, 0xF9, 0x20, 0x00, -+0xCC, 0xF7, 0x9A, 0xF8, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, 0x03, 0x11, 0x00, 0x00, -+0x70, 0xB5, 0x05, 0x00, 0x0E, 0x00, 0x04, 0x78, 0x02, 0x2C, 0x21, 0xD8, 0x00, 0x2C, 0x04, 0xD1, 0x14, 0x4A, 0x30, 0x23, -+0x00, 0x21, 0xD1, 0x54, 0x1B, 0xE0, 0x03, 0x20, 0x88, 0xF7, 0x2E, 0xFC, 0x04, 0x1E, 0x1C, 0xD1, 0x2B, 0x78, 0x0F, 0x49, -+0x30, 0x22, 0x8B, 0x54, 0x01, 0x2B, 0x10, 0xD1, 0xDF, 0x20, 0x00, 0x21, 0x80, 0x00, 0x7A, 0xF7, 0xE7, 0xFA, 0x0B, 0x4B, -+0x18, 0x60, 0x0B, 0x4A, 0x24, 0x23, 0x01, 0x21, 0xD1, 0x54, 0x00, 0x21, 0x00, 0x20, 0x92, 0xF7, 0xA1, 0xF8, 0x00, 0xE0, -+0x12, 0x24, 0x21, 0x00, 0x30, 0x00, 0xFF, 0xF7, 0x3B, 0xFA, 0x00, 0x20, 0x70, 0xBD, 0x0C, 0x24, 0xF7, 0xE7, 0xC0, 0x46, -+0x68, 0x9E, 0x16, 0x00, 0x64, 0xA2, 0x16, 0x00, 0xCC, 0xAA, 0x16, 0x00, 0x70, 0xB5, 0x04, 0x00, 0x0D, 0x00, 0x0F, 0x4B, -+0x5B, 0x68, 0x02, 0x00, 0x06, 0x21, 0x01, 0x20, 0x98, 0x47, 0x20, 0x78, 0x63, 0x78, 0x1B, 0x02, 0x03, 0x43, 0xA0, 0x78, -+0x00, 0x04, 0x03, 0x43, 0xE0, 0x78, 0x00, 0x06, 0x18, 0x43, 0x23, 0x79, 0x61, 0x79, 0x09, 0x02, 0x19, 0x43, 0xA4, 0xF7, -+0xFF, 0xF8, 0x20, 0x00, 0xB3, 0xF7, 0x3C, 0xFF, 0x00, 0x21, 0x28, 0x00, 0xFF, 0xF7, 0x10, 0xFA, 0x00, 0x20, 0x70, 0xBD, -+0x94, 0x92, 0x16, 0x00, 0x10, 0x4A, 0xFF, 0x21, 0x13, 0x68, 0x8B, 0x43, 0x0F, 0x48, 0x00, 0x78, 0x03, 0x43, 0x80, 0x20, -+0x03, 0x43, 0x0E, 0x48, 0x03, 0x60, 0x0E, 0x4B, 0x1B, 0x78, 0x1B, 0x01, 0x0B, 0x40, 0xD0, 0x68, 0x88, 0x43, 0x03, 0x43, -+0x0B, 0x49, 0x0B, 0x60, 0x0B, 0x4B, 0x00, 0x21, 0x19, 0x60, 0x13, 0x69, 0x0A, 0x4A, 0x13, 0x40, 0x0A, 0x4A, 0x13, 0x60, -+0x0A, 0x4B, 0x0B, 0x4A, 0x1A, 0x60, 0x0B, 0x4A, 0x1A, 0x60, 0x70, 0x47, 0xE4, 0xE6, 0x10, 0x00, 0x14, 0xE7, 0x10, 0x00, -+0x08, 0x01, 0x60, 0x40, 0xF7, 0xE8, 0x10, 0x00, 0x28, 0x10, 0x62, 0x40, 0x1C, 0x10, 0x62, 0x40, 0xFF, 0x0F, 0xF0, 0xFF, -+0x34, 0x08, 0x62, 0x40, 0x00, 0x00, 0x62, 0x40, 0x00, 0x01, 0x0A, 0x01, 0x00, 0x01, 0x0F, 0x01, 0x0B, 0x4B, 0x1B, 0x78, -+0x00, 0x2B, 0x11, 0xD1, 0x0A, 0x4B, 0x1B, 0x68, 0x03, 0x60, 0x0A, 0x4B, 0x1B, 0x68, 0x43, 0x60, 0x09, 0x4B, 0x1B, 0x68, -+0x83, 0x60, 0x09, 0x4B, 0x1B, 0x68, 0xC3, 0x60, 0x08, 0x4B, 0x1B, 0x68, 0x03, 0x61, 0x02, 0x4B, 0x01, 0x22, 0x1A, 0x70, -+0x70, 0x47, 0xC0, 0x46, 0xD3, 0xE6, 0x10, 0x00, 0x08, 0x01, 0x60, 0x40, 0x00, 0x00, 0x62, 0x40, 0x1C, 0x10, 0x62, 0x40, -+0x28, 0x10, 0x62, 0x40, 0x34, 0x08, 0x62, 0x40, 0x09, 0x4B, 0x02, 0x68, 0x1A, 0x60, 0x09, 0x4B, 0x42, 0x68, 0x1A, 0x60, -+0x08, 0x4B, 0x82, 0x68, 0x1A, 0x60, 0x08, 0x4B, 0xC2, 0x68, 0x1A, 0x60, 0x02, 0x69, 0x07, 0x4B, 0x1A, 0x60, 0x07, 0x4B, -+0x00, 0x22, 0x1A, 0x70, 0x70, 0x47, 0xC0, 0x46, 0x08, 0x01, 0x60, 0x40, 0x00, 0x00, 0x62, 0x40, 0x1C, 0x10, 0x62, 0x40, -+0x28, 0x10, 0x62, 0x40, 0x34, 0x08, 0x62, 0x40, 0xD3, 0xE6, 0x10, 0x00, 0x70, 0xB5, 0x04, 0x00, 0x0D, 0x00, 0x03, 0x78, -+0x00, 0x2B, 0x17, 0xD0, 0x02, 0x20, 0xF9, 0xF7, 0x8D, 0xFD, 0x0E, 0x48, 0xFF, 0xF7, 0xB0, 0xFF, 0x62, 0x78, 0x0D, 0x4B, -+0x1A, 0x70, 0xA2, 0x78, 0x0C, 0x4B, 0x1A, 0x70, 0xFF, 0xF7, 0x70, 0xFF, 0x21, 0x78, 0x0B, 0x48, 0x7C, 0xF7, 0x46, 0xFA, -+0x00, 0x21, 0x28, 0x00, 0xFF, 0xF7, 0x82, 0xF9, 0x00, 0x20, 0x70, 0xBD, 0x03, 0x48, 0xFF, 0xF7, 0xBF, 0xFF, 0x01, 0x20, -+0xF9, 0xF7, 0x72, 0xFD, 0xEE, 0xE7, 0xC0, 0x46, 0xE4, 0xE6, 0x10, 0x00, 0x14, 0xE7, 0x10, 0x00, 0xF7, 0xE8, 0x10, 0x00, -+0x5C, 0xD2, 0x10, 0x00, 0x00, 0x23, 0x03, 0x73, 0x00, 0x20, 0x70, 0x47, 0x10, 0xB5, 0x03, 0x00, 0x08, 0x00, 0x1B, 0x88, -+0x12, 0x21, 0x15, 0x2B, 0x04, 0xD9, 0x04, 0x4B, 0x80, 0x22, 0xD2, 0x01, 0x9A, 0x82, 0x00, 0x21, 0xFF, 0xF7, 0x50, 0xF9, -+0x00, 0x20, 0x10, 0xBD, 0x68, 0x9E, 0x16, 0x00, 0x70, 0xB5, 0x04, 0x00, 0x0D, 0x00, 0x0F, 0x4B, 0x1B, 0x68, 0x02, 0x2B, -+0x0B, 0xD0, 0x29, 0x00, 0x20, 0x00, 0x0D, 0x4B, 0x98, 0x47, 0x0D, 0x4B, 0x80, 0x22, 0x12, 0x01, 0x1A, 0x83, 0x12, 0x22, -+0x5A, 0x83, 0x00, 0x20, 0x70, 0xBD, 0xFA, 0xF7, 0x09, 0xFC, 0x00, 0x28, 0xEF, 0xD1, 0x23, 0x78, 0x9B, 0x07, 0xEC, 0xD5, -+0x05, 0x4B, 0x80, 0x22, 0x92, 0x00, 0x1A, 0x83, 0xEF, 0x3A, 0xFF, 0x3A, 0x5A, 0x83, 0xE4, 0xE7, 0x50, 0xE0, 0x10, 0x00, -+0x15, 0x28, 0x09, 0x00, 0x68, 0x9E, 0x16, 0x00, 0x70, 0xB5, 0x0C, 0x00, 0x0B, 0x4A, 0x8C, 0x23, 0xD3, 0x5C, 0x0C, 0x25, -+0x01, 0x2B, 0x05, 0xD0, 0x29, 0x00, 0x20, 0x00, 0xFF, 0xF7, 0x18, 0xF9, 0x00, 0x20, 0x70, 0xBD, 0xA4, 0xF7, 0xB8, 0xFC, -+0x05, 0x1E, 0xF5, 0xD0, 0x04, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xEE, 0xE7, 0xC0, 0x46, -+0x68, 0x9E, 0x16, 0x00, 0x28, 0x19, 0x16, 0x00, 0x10, 0xB5, 0x03, 0x00, 0x08, 0x00, 0x1B, 0x78, 0x01, 0x21, 0x99, 0x42, -+0x9B, 0x41, 0x11, 0x31, 0x19, 0x40, 0xFF, 0xF7, 0xFB, 0xF8, 0x00, 0x20, 0x10, 0xBD, 0x00, 0x00, 0x70, 0xB5, 0x05, 0x00, -+0x08, 0x00, 0x1C, 0x00, 0x47, 0x4B, 0x9C, 0x42, 0x43, 0xD0, 0x23, 0xD8, 0x46, 0x4B, 0x9C, 0x42, 0x51, 0xD0, 0x13, 0xD8, -+0x45, 0x4B, 0x9C, 0x42, 0x45, 0xD0, 0x45, 0x4B, 0x9C, 0x42, 0x04, 0xD1, 0x43, 0x49, 0xFF, 0xF7, 0x43, 0xF9, 0x00, 0x25, -+0x6A, 0xE0, 0x42, 0x4B, 0x9C, 0x42, 0x00, 0xD0, 0x70, 0xE0, 0x40, 0x49, 0xFF, 0xF7, 0xB6, 0xFF, 0x00, 0x25, 0x61, 0xE0, -+0x3E, 0x4B, 0x9C, 0x42, 0x3E, 0xD0, 0x3E, 0x4B, 0x9C, 0x42, 0x65, 0xD1, 0x3C, 0x49, 0x00, 0x20, 0xFF, 0xF7, 0x16, 0xFE, -+0x00, 0x25, 0x55, 0xE0, 0x3A, 0x4B, 0x9C, 0x42, 0x20, 0xD0, 0x0A, 0xD9, 0x39, 0x4B, 0x9C, 0x42, 0x12, 0xD0, 0x39, 0x4B, -+0x9C, 0x42, 0x55, 0xD1, 0x19, 0x00, 0xFF, 0xF7, 0xDB, 0xF8, 0x00, 0x25, 0x46, 0xE0, 0x36, 0x4B, 0x9C, 0x42, 0x28, 0xD0, -+0x35, 0x4B, 0x9C, 0x42, 0x2A, 0xD1, 0x34, 0x49, 0xFF, 0xF7, 0x84, 0xFE, 0x00, 0x25, 0x3B, 0xE0, 0x2E, 0x49, 0xFF, 0xF7, -+0x01, 0xF9, 0x00, 0x25, 0x36, 0xE0, 0x24, 0x49, 0xFF, 0xF7, 0x42, 0xFE, 0x00, 0x25, 0x31, 0xE0, 0x28, 0x49, 0xFF, 0xF7, -+0x15, 0xFF, 0x00, 0x25, 0x2C, 0xE0, 0x00, 0x23, 0x0B, 0x73, 0x20, 0x4B, 0x28, 0x00, 0x29, 0x4D, 0xA8, 0x47, 0x05, 0x00, -+0x24, 0xE0, 0x1C, 0x49, 0xFF, 0xF7, 0x3A, 0xFF, 0x00, 0x25, 0x1F, 0xE0, 0x1D, 0x49, 0xFF, 0xF7, 0x47, 0xFF, 0x00, 0x25, -+0x1A, 0xE0, 0x20, 0x49, 0xFF, 0xF7, 0x88, 0xFF, 0x00, 0x25, 0x15, 0xE0, 0x23, 0x00, 0x28, 0x00, 0x1E, 0x4D, 0xA8, 0x47, -+0x05, 0x00, 0x1E, 0x4B, 0x9C, 0x42, 0x05, 0xD0, 0x1D, 0x4B, 0x08, 0x22, 0x21, 0x00, 0x91, 0x43, 0x99, 0x42, 0x04, 0xD1, -+0x02, 0x20, 0xF9, 0xF7, 0x81, 0xFC, 0xFA, 0xF7, 0x63, 0xF9, 0x19, 0x4B, 0x9C, 0x42, 0x05, 0xD0, 0x21, 0x00, 0x18, 0x48, -+0x7C, 0xF7, 0x40, 0xF9, 0x28, 0x00, 0x70, 0xBD, 0x01, 0x20, 0xF9, 0xF7, 0x73, 0xFC, 0xF5, 0xE7, 0x23, 0x00, 0x01, 0x00, -+0x28, 0x00, 0x0E, 0x4D, 0xA8, 0x47, 0x05, 0x00, 0xE0, 0xE7, 0xC0, 0x46, 0x02, 0x18, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, -+0x05, 0x04, 0x00, 0x00, 0x13, 0x0C, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x1A, 0x0C, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, -+0xC6, 0xFC, 0x00, 0x00, 0xC7, 0xFC, 0x00, 0x00, 0xC9, 0xFC, 0x00, 0x00, 0x04, 0x18, 0x00, 0x00, 0x70, 0xFC, 0x00, 0x00, -+0x1D, 0x0C, 0x09, 0x00, 0x06, 0x18, 0x00, 0x00, 0x03, 0x18, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x6C, 0xD2, 0x10, 0x00, -+0x70, 0xB5, 0x0D, 0x00, 0x14, 0x00, 0x04, 0x23, 0x02, 0x00, 0x00, 0x21, 0x03, 0x48, 0x7A, 0xF7, 0x03, 0xF8, 0x05, 0x70, -+0x44, 0x80, 0xCB, 0xF7, 0x5F, 0xFE, 0x70, 0xBD, 0x01, 0x11, 0x00, 0x00, 0x10, 0xB5, 0x03, 0x00, 0x10, 0x00, 0x1A, 0x88, -+0x0C, 0x21, 0xFF, 0xF7, 0xE9, 0xFF, 0x00, 0x20, 0x10, 0xBD, 0x00, 0x00, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, -+0x45, 0x46, 0xE0, 0xB5, 0x83, 0xB0, 0x80, 0x46, 0x0C, 0x00, 0x91, 0x46, 0x0F, 0x0A, 0xBA, 0x00, 0x2E, 0x4B, 0xD5, 0x58, -+0x08, 0x00, 0x7A, 0xF7, 0xB7, 0xFB, 0x02, 0x26, 0x00, 0x28, 0x19, 0xD0, 0x36, 0x23, 0xEB, 0x5C, 0x01, 0x2B, 0x4F, 0xD0, -+0x3C, 0x23, 0xEE, 0x5C, 0x02, 0x2E, 0x03, 0xD1, 0x43, 0x46, 0x5B, 0x88, 0x00, 0x2B, 0x1B, 0xD1, 0xFA, 0x21, 0x49, 0x01, -+0xA9, 0x83, 0xFF, 0xB2, 0x36, 0x23, 0xEA, 0x5C, 0x38, 0x00, 0xA1, 0xF7, 0x6D, 0xFE, 0xA9, 0x8B, 0x38, 0x00, 0xAB, 0xF7, -+0x31, 0xFC, 0x00, 0x26, 0x43, 0x46, 0x1A, 0x88, 0x31, 0x00, 0x48, 0x46, 0xFF, 0xF7, 0xB2, 0xFF, 0x00, 0x20, 0x03, 0xB0, -+0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0xFB, 0xB2, 0x9B, 0x46, 0x06, 0x23, 0x6B, 0x44, -+0x9A, 0x46, 0x6B, 0x46, 0x5A, 0x1D, 0x51, 0x46, 0x58, 0x46, 0x8B, 0xF7, 0x65, 0xFE, 0x43, 0x46, 0x5A, 0x88, 0x53, 0x46, -+0x19, 0x88, 0x8A, 0x42, 0x13, 0xD9, 0x6B, 0x46, 0x05, 0x33, 0x1B, 0x78, 0x00, 0x2B, 0xCD, 0xD0, 0x4B, 0x43, 0x9A, 0x42, -+0xCA, 0xD8, 0x00, 0x23, 0x00, 0x22, 0x00, 0x21, 0x58, 0x46, 0xAB, 0xF7, 0x73, 0xFA, 0x22, 0x00, 0x21, 0x00, 0x07, 0x48, -+0x79, 0xF7, 0xD2, 0xFF, 0xBE, 0xE7, 0x43, 0x46, 0x1A, 0x88, 0x12, 0x21, 0x48, 0x46, 0xFF, 0xF7, 0x7F, 0xFF, 0xC5, 0xE7, -+0x0C, 0x26, 0xC3, 0xE7, 0x64, 0xA2, 0x16, 0x00, 0x22, 0x06, 0x00, 0x00, 0xF0, 0xB5, 0x93, 0xB0, 0x01, 0x90, 0x0C, 0x00, -+0x16, 0x00, 0x0F, 0x0A, 0xBA, 0x00, 0x37, 0x4B, 0xD5, 0x58, 0x08, 0x00, 0x7A, 0xF7, 0x4E, 0xFB, 0x04, 0x28, 0x06, 0xD0, -+0x09, 0x28, 0x18, 0xD0, 0x0C, 0x21, 0x30, 0x00, 0x91, 0xF7, 0x42, 0xFB, 0x10, 0xE0, 0x3C, 0x22, 0x30, 0x49, 0x03, 0xA8, -+0xD0, 0xF7, 0x62, 0xFE, 0x00, 0x21, 0x30, 0x00, 0x91, 0xF7, 0x38, 0xFB, 0x2D, 0x4A, 0xE8, 0x23, 0xD5, 0x58, 0x03, 0xAB, -+0x01, 0x22, 0x01, 0x21, 0x20, 0x00, 0xA8, 0x47, 0x00, 0x20, 0x13, 0xB0, 0xF0, 0xBD, 0x21, 0x00, 0x28, 0x48, 0x79, 0xF7, -+0x0F, 0xFF, 0x01, 0x21, 0x20, 0x00, 0x7A, 0xF7, 0xC9, 0xFA, 0x00, 0x21, 0x30, 0x00, 0x91, 0xF7, 0x21, 0xFB, 0xBC, 0x23, -+0x5B, 0x00, 0xEB, 0x5C, 0xDB, 0x43, 0x9B, 0x07, 0x21, 0xD1, 0x00, 0x23, 0x01, 0x9A, 0x93, 0x71, 0xFF, 0xB2, 0x29, 0x00, -+0x38, 0x31, 0x38, 0x00, 0x88, 0xF7, 0x70, 0xF9, 0x00, 0x28, 0x1C, 0xD0, 0x1B, 0x48, 0x7C, 0xF7, 0x3F, 0xF8, 0x01, 0x23, -+0xAF, 0x22, 0x92, 0x00, 0xAB, 0x54, 0x43, 0x22, 0xAB, 0x54, 0x20, 0x00, 0x93, 0xF7, 0xA0, 0xF9, 0x88, 0xF7, 0x64, 0xFA, -+0x00, 0x28, 0x19, 0xD1, 0xC4, 0x20, 0x22, 0x00, 0x21, 0x00, 0xC0, 0x00, 0x79, 0xF7, 0x68, 0xFF, 0xC8, 0xE7, 0x22, 0x00, -+0x21, 0x00, 0x10, 0x48, 0x79, 0xF7, 0x62, 0xFF, 0xD7, 0xE7, 0x0F, 0x48, 0x7C, 0xF7, 0x22, 0xF8, 0x44, 0x23, 0x01, 0x22, -+0xEA, 0x54, 0x0B, 0x3B, 0xEA, 0x5C, 0x33, 0x21, 0x38, 0x00, 0xA1, 0xF7, 0x39, 0xFC, 0xE1, 0xE7, 0x22, 0x00, 0x21, 0x00, -+0x08, 0x48, 0x79, 0xF7, 0x4F, 0xFF, 0xDF, 0xE7, 0x64, 0xA2, 0x16, 0x00, 0x80, 0xD6, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, -+0x06, 0x06, 0x00, 0x00, 0x74, 0xD2, 0x10, 0x00, 0x14, 0x06, 0x00, 0x00, 0x7C, 0xD2, 0x10, 0x00, 0x1D, 0x06, 0x00, 0x00, -+0x70, 0xB5, 0x04, 0x00, 0x0E, 0x00, 0x15, 0x00, 0x41, 0x88, 0x80, 0x23, 0x1B, 0x01, 0x99, 0x42, 0x06, 0xD3, 0x22, 0x88, -+0x0C, 0x21, 0x28, 0x00, 0xFF, 0xF7, 0xE4, 0xFE, 0x00, 0x20, 0x70, 0xBD, 0x03, 0x48, 0x7B, 0xF7, 0xEF, 0xFF, 0x30, 0x0A, -+0x00, 0x21, 0xAB, 0xF7, 0xA7, 0xF8, 0xF0, 0xE7, 0x84, 0xD2, 0x10, 0x00, 0x70, 0xB5, 0x0E, 0x00, 0x15, 0x00, 0x07, 0x23, -+0x02, 0x00, 0x00, 0x21, 0x06, 0x48, 0x79, 0xF7, 0xDB, 0xFE, 0x04, 0x00, 0x06, 0x70, 0x01, 0x30, 0x06, 0x22, 0x29, 0x00, -+0xD0, 0xF7, 0xCC, 0xFD, 0x20, 0x00, 0xCB, 0xF7, 0x31, 0xFD, 0x70, 0xBD, 0x01, 0x11, 0x00, 0x00, 0xF0, 0xB5, 0x83, 0xB0, -+0x01, 0x90, 0x0D, 0x00, 0x16, 0x00, 0x0F, 0x0A, 0xBA, 0x00, 0x22, 0x4B, 0xD4, 0x58, 0x08, 0x00, 0x7A, 0xF7, 0x98, 0xFA, -+0x00, 0x28, 0x1A, 0xD0, 0x16, 0x38, 0xC0, 0xB2, 0x03, 0x28, 0x16, 0xD9, 0x88, 0x23, 0xFF, 0x33, 0xE3, 0x5C, 0x00, 0x2B, -+0x03, 0xD1, 0x36, 0x33, 0xE3, 0x5C, 0x00, 0x2B, 0x14, 0xD0, 0x00, 0x21, 0x30, 0x00, 0x91, 0xF7, 0x81, 0xFA, 0x36, 0x23, -+0xE3, 0x5C, 0x00, 0x2B, 0x11, 0xD1, 0x2A, 0x00, 0x29, 0x00, 0x14, 0x48, 0x79, 0xF7, 0xE6, 0xFE, 0x03, 0xE0, 0x02, 0x21, -+0x30, 0x00, 0x91, 0xF7, 0x73, 0xFA, 0x00, 0x20, 0x03, 0xB0, 0xF0, 0xBD, 0x0C, 0x21, 0x30, 0x00, 0x91, 0xF7, 0x6C, 0xFA, -+0xF7, 0xE7, 0x06, 0x23, 0x1C, 0x22, 0x00, 0x21, 0x0B, 0x48, 0x79, 0xF7, 0x93, 0xFE, 0x05, 0x00, 0x00, 0x23, 0x03, 0x70, -+0x01, 0x9B, 0x1B, 0x88, 0x43, 0x80, 0xF8, 0xB2, 0xAB, 0xF7, 0x32, 0xFA, 0xC0, 0x03, 0x40, 0x0C, 0xA8, 0x80, 0x28, 0x00, -+0xCB, 0xF7, 0xE4, 0xFC, 0xE1, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, 0x16, 0x06, 0x00, 0x00, 0x03, 0x11, 0x00, 0x00, -+0xF0, 0xB5, 0x83, 0xB0, 0x01, 0x90, 0x0D, 0x00, 0x16, 0x00, 0x0B, 0x0A, 0x9B, 0x00, 0x31, 0x4A, 0x9F, 0x58, 0x08, 0x00, -+0x7A, 0xF7, 0x46, 0xFA, 0x00, 0x28, 0x53, 0xD0, 0x16, 0x38, 0xC0, 0xB2, 0x02, 0x24, 0x03, 0x28, 0x4F, 0xD9, 0x01, 0x99, -+0x4B, 0x88, 0xA8, 0x22, 0xD2, 0x00, 0x10, 0x34, 0x93, 0x42, 0x48, 0xD8, 0xDA, 0x07, 0x46, 0xD4, 0x8A, 0x88, 0x05, 0x2A, -+0x43, 0xD9, 0xD0, 0x07, 0x41, 0xD4, 0x08, 0x00, 0xC9, 0x88, 0x00, 0x29, 0x3D, 0xD0, 0x00, 0x89, 0x84, 0x46, 0x28, 0x28, -+0x39, 0xD8, 0x58, 0x08, 0x81, 0x42, 0x36, 0xD8, 0x93, 0x42, 0x34, 0xD3, 0x61, 0x44, 0x49, 0x00, 0x99, 0x42, 0x30, 0xD2, -+0x7B, 0x8C, 0x06, 0x3C, 0x5B, 0x07, 0x2C, 0xD5, 0x3C, 0x23, 0xFC, 0x5C, 0x00, 0x2C, 0x01, 0xD0, 0x0C, 0x24, 0x26, 0xE0, -+0x38, 0x00, 0x54, 0x30, 0x07, 0x21, 0xA1, 0xF7, 0x47, 0xFA, 0x00, 0x28, 0x01, 0xD1, 0x1A, 0x24, 0x1D, 0xE0, 0x08, 0x23, -+0x2A, 0x00, 0x29, 0x00, 0x11, 0x48, 0x79, 0xF7, 0x31, 0xFE, 0x01, 0x9B, 0x5A, 0x88, 0x02, 0x80, 0x9B, 0x88, 0x43, 0x80, -+0xC0, 0x21, 0x49, 0x00, 0x8A, 0x42, 0x00, 0xD9, 0x01, 0x80, 0xC0, 0x22, 0x52, 0x00, 0x93, 0x42, 0x00, 0xD9, 0x42, 0x80, -+0x01, 0x9A, 0xD3, 0x88, 0x83, 0x80, 0x13, 0x89, 0xC3, 0x80, 0x79, 0xF7, 0x45, 0xFE, 0x00, 0xE0, 0x02, 0x24, 0x21, 0x00, -+0x30, 0x00, 0x91, 0xF7, 0xE7, 0xF9, 0x00, 0x20, 0x03, 0xB0, 0xF0, 0xBD, 0x64, 0xA2, 0x16, 0x00, 0x0D, 0x06, 0x00, 0x00, -+0x70, 0xB5, 0x04, 0x00, 0x08, 0x00, 0x15, 0x00, 0x0B, 0x0A, 0x9B, 0x00, 0x0F, 0x4A, 0x9E, 0x58, 0x7A, 0xF7, 0xDA, 0xF9, -+0x02, 0x21, 0x00, 0x28, 0x10, 0xD0, 0x63, 0x88, 0xF0, 0x22, 0x10, 0x31, 0x1A, 0x42, 0x0B, 0xD1, 0xE6, 0x3A, 0x01, 0x39, -+0x1A, 0x42, 0x07, 0xD1, 0x73, 0x84, 0x2C, 0x32, 0xB1, 0x5C, 0x00, 0x29, 0x08, 0xD1, 0x35, 0x3A, 0x93, 0x43, 0x73, 0x84, -+0x22, 0x88, 0x28, 0x00, 0xFF, 0xF7, 0xE0, 0xFD, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x21, 0xF7, 0xE7, 0x64, 0xA2, 0x16, 0x00, -+0xF0, 0xB5, 0xD6, 0x46, 0x4F, 0x46, 0x80, 0xB5, 0x83, 0xB0, 0x01, 0x90, 0x0E, 0x00, 0x17, 0x00, 0x1C, 0x00, 0x4B, 0x4B, -+0x9C, 0x42, 0x5D, 0xD0, 0x0E, 0xD9, 0x4A, 0x4B, 0x9C, 0x42, 0x67, 0xD0, 0x42, 0xD9, 0x49, 0x4B, 0x9C, 0x42, 0x00, 0xD0, -+0x81, 0xE0, 0x47, 0x4A, 0x39, 0x00, 0x30, 0x00, 0xFF, 0xF7, 0xDA, 0xFD, 0x00, 0x25, 0x43, 0xE0, 0x44, 0x4B, 0x9C, 0x42, -+0x69, 0xD0, 0x01, 0x33, 0x9C, 0x42, 0x13, 0xD3, 0x42, 0x4B, 0xE3, 0x18, 0x9B, 0xB2, 0x03, 0x2B, 0x00, 0xD9, 0x6E, 0xE0, -+0x10, 0x00, 0x7A, 0xF7, 0x91, 0xF9, 0x43, 0x28, 0x51, 0xD8, 0x41, 0x28, 0x51, 0xD8, 0x32, 0x00, 0x0C, 0x21, 0x20, 0x00, -+0xFF, 0xF7, 0xCE, 0xFE, 0x00, 0x25, 0x29, 0xE0, 0x39, 0x4B, 0x9C, 0x42, 0x37, 0xD0, 0x39, 0x4B, 0x9C, 0x42, 0x5A, 0xD1, -+0x38, 0x48, 0x7B, 0xF7, 0xAB, 0xFE, 0xB5, 0x1D, 0x16, 0x23, 0x9A, 0x46, 0xB2, 0x44, 0x36, 0x4B, 0x99, 0x46, 0x29, 0x78, -+0x48, 0x46, 0x7B, 0xF7, 0xA1, 0xFE, 0x01, 0x35, 0x55, 0x45, 0xF8, 0xD1, 0x2F, 0x4B, 0x3A, 0x00, 0x31, 0x00, 0x01, 0x98, -+0x30, 0x4D, 0xA8, 0x47, 0x05, 0x00, 0x0B, 0xE0, 0x2F, 0x4B, 0x9C, 0x42, 0x38, 0xD0, 0x2F, 0x4B, 0x9C, 0x42, 0x3C, 0xD1, -+0x2D, 0x4A, 0x39, 0x00, 0x30, 0x00, 0xFF, 0xF7, 0x8B, 0xFD, 0x00, 0x25, 0x21, 0x00, 0x2B, 0x48, 0x7B, 0xF7, 0x86, 0xFE, -+0x28, 0x00, 0x03, 0xB0, 0x0C, 0xBC, 0x91, 0x46, 0x9A, 0x46, 0xF0, 0xBD, 0x1A, 0x4A, 0x39, 0x00, 0x30, 0x00, 0xFF, 0xF7, -+0xFB, 0xFE, 0x00, 0x25, 0xEE, 0xE7, 0x1C, 0x4A, 0x39, 0x00, 0x30, 0x00, 0xFF, 0xF7, 0xEC, 0xFD, 0x05, 0x00, 0xE7, 0xE7, -+0x14, 0x4A, 0x39, 0x00, 0x30, 0x00, 0xFF, 0xF7, 0x6B, 0xFE, 0x05, 0x00, 0xE0, 0xE7, 0x4A, 0x28, 0xAD, 0xD1, 0x23, 0x00, -+0x3A, 0x00, 0x31, 0x00, 0x01, 0x98, 0x16, 0x4D, 0xA8, 0x47, 0x05, 0x00, 0xD6, 0xE7, 0x0E, 0x4A, 0x39, 0x00, 0x30, 0x00, -+0xFF, 0xF7, 0x8A, 0xFE, 0x05, 0x00, 0xCF, 0xE7, 0x11, 0x4A, 0x39, 0x00, 0x30, 0x00, 0xFF, 0xF7, 0x43, 0xFF, 0x05, 0x00, -+0xC8, 0xE7, 0x23, 0x00, 0x3A, 0x00, 0x31, 0x00, 0x01, 0x98, 0x0B, 0x4D, 0xA8, 0x47, 0x05, 0x00, 0xC0, 0xE7, 0xC0, 0x46, -+0x03, 0x08, 0x00, 0x00, 0x28, 0x0C, 0x00, 0x00, 0x37, 0x0C, 0x00, 0x00, 0x1F, 0x04, 0x00, 0x00, 0xD4, 0xFB, 0xFF, 0xFF, -+0x09, 0x04, 0x00, 0x00, 0x0B, 0x04, 0x00, 0x00, 0x90, 0xD2, 0x10, 0x00, 0x98, 0xD2, 0x10, 0x00, 0xC1, 0xDB, 0x09, 0x00, -+0x0D, 0x08, 0x00, 0x00, 0x11, 0x08, 0x00, 0x00, 0x9C, 0xD2, 0x10, 0x00, 0x10, 0xB5, 0x03, 0x00, 0x08, 0x00, 0x1B, 0x78, -+0x00, 0x21, 0x01, 0x2B, 0x00, 0xD9, 0x12, 0x31, 0xB2, 0xF7, 0x7C, 0xFF, 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x08, 0x00, -+0x00, 0x21, 0xB2, 0xF7, 0x75, 0xFF, 0x00, 0x20, 0x10, 0xBD, 0x00, 0x00, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, -+0x45, 0x46, 0xE0, 0xB5, 0xAD, 0xB0, 0x04, 0x00, 0x0D, 0x00, 0x02, 0xAB, 0x00, 0x22, 0xDA, 0x71, 0x60, 0x32, 0x00, 0x21, -+0x14, 0xA8, 0x77, 0xF7, 0x8B, 0xFD, 0x9B, 0x4A, 0x9B, 0x4B, 0xD3, 0x5C, 0x01, 0x2B, 0x00, 0xD1, 0xC8, 0xE1, 0x99, 0x4B, -+0x02, 0x21, 0xD1, 0x54, 0x02, 0xAB, 0x00, 0x21, 0xD9, 0x71, 0x44, 0x32, 0x00, 0x20, 0x00, 0x23, 0x01, 0x26, 0x11, 0x78, -+0x05, 0x29, 0x26, 0xD0, 0x01, 0x33, 0xDB, 0xB2, 0x40, 0x32, 0x30, 0x00, 0x0C, 0x2B, 0xF6, 0xD1, 0x02, 0xAB, 0x0C, 0x22, -+0xDA, 0x71, 0x27, 0x78, 0x00, 0x2F, 0x24, 0xD0, 0x60, 0x7A, 0x07, 0x23, 0x07, 0x00, 0x9F, 0x43, 0x00, 0x97, 0x00, 0xD0, -+0xB5, 0xE1, 0x8A, 0x49, 0x0F, 0x22, 0x02, 0x40, 0x03, 0x09, 0x8E, 0x5C, 0xCB, 0x5C, 0xF6, 0x18, 0xF6, 0xB2, 0x00, 0x2E, -+0x61, 0xDD, 0x23, 0x00, 0x0A, 0x33, 0x3A, 0x00, 0x02, 0x37, 0x07, 0x40, 0x01, 0x21, 0x01, 0x40, 0xA4, 0x46, 0x0C, 0x00, -+0x1E, 0xE0, 0x00, 0x28, 0x01, 0xD0, 0x02, 0xAA, 0xD3, 0x71, 0x0C, 0x21, 0x00, 0x27, 0x0B, 0x2B, 0x00, 0xD8, 0x8D, 0xE1, -+0xD7, 0xE7, 0xA1, 0x78, 0xE0, 0x1C, 0xB2, 0xF7, 0x35, 0xFF, 0x0B, 0x21, 0x00, 0x28, 0x00, 0xD0, 0x84, 0xE1, 0xD1, 0xE7, -+0x59, 0x88, 0x18, 0x88, 0x81, 0x42, 0x46, 0xD8, 0x03, 0x29, 0x44, 0xD9, 0x03, 0x28, 0x42, 0xD9, 0x01, 0x32, 0x10, 0x33, -+0xB2, 0x42, 0x04, 0xDA, 0x00, 0x2F, 0xF1, 0xD0, 0x94, 0x42, 0xEF, 0xD1, 0xF6, 0xE7, 0x64, 0x46, 0x23, 0x00, 0x0E, 0x33, -+0x00, 0x98, 0xC8, 0x22, 0x12, 0x01, 0x91, 0x46, 0x6B, 0x4A, 0x92, 0x46, 0xFA, 0x22, 0x52, 0x00, 0x93, 0x46, 0xA4, 0x46, -+0xA8, 0x46, 0x1F, 0x88, 0x5A, 0x88, 0x97, 0x42, 0x2D, 0xD8, 0x1D, 0x89, 0x59, 0x89, 0x8D, 0x42, 0x29, 0xD8, 0xD9, 0x88, -+0x05, 0x2F, 0x26, 0xD9, 0x4A, 0x45, 0x24, 0xD8, 0x0F, 0x00, 0x0A, 0x3F, 0xBF, 0xB2, 0x57, 0x45, 0x1F, 0xD8, 0x9F, 0x88, -+0x5F, 0x45, 0x1C, 0xD2, 0x8C, 0x00, 0x61, 0x18, 0x49, 0x00, 0x01, 0x37, 0x57, 0x43, 0xBA, 0x00, 0xD2, 0x19, 0x01, 0x32, -+0x52, 0x10, 0x91, 0x42, 0x11, 0xDB, 0x01, 0x30, 0x10, 0x33, 0xB0, 0x42, 0xDB, 0xDB, 0x64, 0x46, 0x45, 0x46, 0xA3, 0x78, -+0x01, 0x2B, 0x0F, 0xD9, 0x12, 0x21, 0x00, 0x27, 0x38, 0xE1, 0x64, 0x46, 0x96, 0x42, 0xC3, 0xDD, 0x12, 0x21, 0x00, 0x27, -+0x32, 0xE1, 0x64, 0x46, 0x45, 0x46, 0x86, 0x42, 0xEF, 0xDD, 0x12, 0x21, 0x00, 0x27, 0x2B, 0xE1, 0x63, 0x78, 0x03, 0x2B, -+0x00, 0xD9, 0x35, 0xE1, 0xDB, 0x07, 0x06, 0xD5, 0x49, 0x49, 0x4A, 0x48, 0x7B, 0xF7, 0x98, 0xFD, 0x00, 0x28, 0x00, 0xD0, -+0x2F, 0xE1, 0x02, 0xAB, 0xD8, 0x1D, 0xB3, 0xF7, 0x71, 0xF9, 0x01, 0x00, 0x01, 0x90, 0x00, 0x27, 0x00, 0x28, 0x00, 0xD0, -+0x14, 0xE1, 0x00, 0x2E, 0x00, 0xDC, 0x25, 0xE1, 0x0E, 0x23, 0x99, 0x46, 0xA1, 0x44, 0x14, 0xAF, 0x00, 0x9B, 0x9A, 0x46, -+0x00, 0x23, 0x9B, 0x46, 0xA0, 0x46, 0x4C, 0x46, 0xA9, 0x46, 0x55, 0x46, 0x13, 0xE0, 0x78, 0x60, 0x39, 0x60, 0xBA, 0x60, -+0xFB, 0x60, 0x5B, 0x46, 0xBB, 0x74, 0xFB, 0x74, 0x02, 0xAB, 0xDB, 0x79, 0x3B, 0x82, 0x38, 0x00, 0xCF, 0xF7, 0xCA, 0xFA, -+0x00, 0x28, 0x18, 0xD1, 0x01, 0x35, 0x10, 0x34, 0x20, 0x37, 0xB5, 0x42, 0x24, 0xDA, 0x23, 0x00, 0x21, 0x88, 0x49, 0x00, -+0x22, 0x89, 0x8A, 0x42, 0x00, 0xD9, 0x0A, 0x00, 0x02, 0x2A, 0x00, 0xD2, 0x02, 0x22, 0x58, 0x88, 0x40, 0x00, 0x5B, 0x89, -+0x83, 0x42, 0x00, 0xD9, 0x03, 0x00, 0x93, 0x42, 0xD9, 0xD2, 0x13, 0x00, 0xD7, 0xE7, 0xAA, 0x46, 0x44, 0x46, 0x4D, 0x46, -+0x51, 0x46, 0x25, 0x48, 0x7B, 0xF7, 0x10, 0xFD, 0x51, 0x46, 0x24, 0x48, 0x7B, 0xF7, 0x0C, 0xFD, 0x01, 0x9F, 0x3B, 0x21, -+0x56, 0x45, 0x00, 0xDD, 0xCC, 0xE0, 0x06, 0xE0, 0xAA, 0x46, 0x44, 0x46, 0x4D, 0x46, 0x51, 0x46, 0x1D, 0x48, 0x7B, 0xF7, -+0xFF, 0xFC, 0x02, 0xAB, 0xDA, 0x79, 0x92, 0x01, 0x13, 0x4B, 0x9B, 0x18, 0x9B, 0x68, 0x00, 0x2B, 0x05, 0xD0, 0x19, 0x4B, -+0x9B, 0x6E, 0x00, 0x22, 0x11, 0x00, 0x10, 0x00, 0x98, 0x47, 0x60, 0x78, 0x02, 0x28, 0x2D, 0xD0, 0x0E, 0xD8, 0x00, 0x28, -+0x2A, 0xD0, 0x0B, 0x49, 0x02, 0xAB, 0xD8, 0x79, 0x80, 0x01, 0x08, 0x18, 0x0C, 0x30, 0x11, 0x4B, 0x9C, 0x46, 0x61, 0x44, -+0x06, 0x22, 0xD0, 0xF7, 0xD3, 0xFA, 0x2B, 0xE0, 0x03, 0x28, 0xF0, 0xD0, 0x0B, 0x4B, 0xDF, 0x6E, 0x00, 0x23, 0x1A, 0x00, -+0x19, 0x00, 0xB8, 0x47, 0x22, 0xE0, 0xC0, 0x46, 0xEC, 0xA4, 0x16, 0x00, 0x6D, 0x04, 0x00, 0x00, 0xE4, 0x98, 0x0D, 0x00, -+0x76, 0x0C, 0x00, 0x00, 0xB4, 0x98, 0x0D, 0x00, 0xFA, 0xA7, 0x16, 0x00, 0xA4, 0xD2, 0x10, 0x00, 0xB0, 0xD2, 0x10, 0x00, -+0x28, 0x19, 0x16, 0x00, 0x0E, 0x03, 0x00, 0x00, 0x4E, 0x4A, 0x02, 0xAB, 0x07, 0x33, 0x1B, 0x78, 0x9B, 0x01, 0xD3, 0x18, -+0xC2, 0x21, 0x89, 0x00, 0x8C, 0x46, 0x62, 0x44, 0x11, 0x68, 0xD9, 0x60, 0x92, 0x88, 0x1A, 0x82, 0x02, 0xAB, 0x07, 0x33, -+0x1B, 0x78, 0x46, 0x4F, 0x9A, 0x01, 0xBA, 0x18, 0x94, 0x60, 0x01, 0x33, 0x9B, 0x01, 0xFB, 0x18, 0x05, 0x22, 0x1A, 0x71, -+0xE1, 0x1C, 0x01, 0x32, 0x0E, 0x20, 0x02, 0xAB, 0x9C, 0x46, 0x60, 0x44, 0xD0, 0xF7, 0x92, 0xFA, 0x3E, 0x4B, 0xF9, 0x18, -+0x05, 0x22, 0x07, 0xA8, 0xD0, 0xF7, 0x8C, 0xFA, 0x67, 0x7A, 0x04, 0xAB, 0x9F, 0x74, 0x00, 0x2E, 0x17, 0xDD, 0x22, 0x00, -+0x0A, 0x32, 0x14, 0xA9, 0x10, 0x88, 0x18, 0x83, 0x50, 0x88, 0x58, 0x83, 0x48, 0x69, 0x40, 0x08, 0x98, 0x83, 0x88, 0x69, -+0xD8, 0x83, 0x10, 0x89, 0x18, 0x84, 0x50, 0x89, 0x58, 0x84, 0x00, 0x98, 0x01, 0x30, 0x00, 0x90, 0x10, 0x32, 0x0C, 0x33, -+0x20, 0x31, 0xB0, 0x42, 0xEA, 0xDB, 0x05, 0x23, 0x3B, 0x40, 0x05, 0x2B, 0x20, 0xD0, 0x02, 0xAB, 0x07, 0x33, 0x1B, 0x78, -+0x04, 0xA8, 0xC3, 0x74, 0x62, 0x78, 0x02, 0x75, 0xA2, 0x78, 0x42, 0x75, 0x22, 0x78, 0x82, 0x75, 0x24, 0x4A, 0x9B, 0x01, -+0xD3, 0x18, 0xD9, 0x68, 0x04, 0x91, 0x1B, 0x8A, 0x83, 0x80, 0x01, 0x23, 0x43, 0x74, 0x22, 0x4B, 0xD2, 0x5C, 0x3C, 0x23, -+0xC2, 0x54, 0xC7, 0xF7, 0x29, 0xFF, 0x01, 0x00, 0x01, 0x27, 0x00, 0x28, 0x1E, 0xD0, 0x03, 0x21, 0x01, 0x27, 0x1B, 0xE0, -+0x01, 0x3E, 0x04, 0xA8, 0x43, 0x8B, 0x0C, 0x22, 0x72, 0x43, 0x82, 0x18, 0x51, 0x8B, 0x5F, 0x18, 0x02, 0x8B, 0xBA, 0x42, -+0x00, 0xD2, 0x07, 0x83, 0x0C, 0x22, 0x72, 0x43, 0x04, 0xA8, 0x84, 0x46, 0x62, 0x44, 0x12, 0x8B, 0xBA, 0x42, 0xCA, 0xD2, -+0x0C, 0x22, 0x72, 0x43, 0x62, 0x44, 0x5B, 0x18, 0x13, 0x83, 0xC4, 0xE7, 0x0C, 0x21, 0x00, 0x27, 0x28, 0x00, 0xB2, 0xF7, -+0x9B, 0xFD, 0x38, 0x00, 0x2D, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0x12, 0x21, -+0x00, 0x27, 0xF1, 0xE7, 0x12, 0x21, 0x00, 0x27, 0xEE, 0xE7, 0x12, 0x21, 0x00, 0x27, 0xEB, 0xE7, 0x00, 0x9B, 0x9A, 0x46, -+0x1F, 0xE7, 0xC0, 0x46, 0xEC, 0xA4, 0x16, 0x00, 0x19, 0x03, 0x00, 0x00, 0xD6, 0x03, 0x00, 0x00, 0xF0, 0xB5, 0xC6, 0x46, -+0x00, 0xB5, 0x80, 0x46, 0x0D, 0x00, 0x17, 0x00, 0x1C, 0x00, 0x58, 0x4B, 0xE3, 0x18, 0x9A, 0xB2, 0x39, 0x2A, 0x00, 0xD9, -+0x90, 0xE0, 0x93, 0x00, 0x55, 0x4A, 0xD3, 0x58, 0x9F, 0x46, 0x02, 0x20, 0xF8, 0xF7, 0x40, 0xFF, 0x53, 0x4B, 0x00, 0x22, -+0x44, 0x21, 0x5A, 0x54, 0x40, 0x31, 0x5A, 0x54, 0x40, 0x31, 0x5A, 0x54, 0x40, 0x31, 0x5A, 0x54, 0x40, 0x31, 0x5A, 0x54, -+0x00, 0x26, 0x7C, 0xE0, 0x01, 0x20, 0xF8, 0xF7, 0x2F, 0xFF, 0x4B, 0x4B, 0x11, 0x22, 0x44, 0x21, 0x5A, 0x54, 0x40, 0x31, -+0x5A, 0x54, 0x40, 0x31, 0x5A, 0x54, 0x40, 0x31, 0x5A, 0x54, 0x40, 0x31, 0x5A, 0x54, 0x00, 0x26, 0x6B, 0xE0, 0x45, 0x4B, -+0x1B, 0x78, 0x00, 0x26, 0x00, 0x2B, 0x66, 0xD0, 0x43, 0x49, 0x28, 0x00, 0xFF, 0xF7, 0xB0, 0xFD, 0x05, 0x00, 0x21, 0x00, -+0x41, 0x48, 0x7B, 0xF7, 0xDB, 0xFB, 0x41, 0x4B, 0x9C, 0x42, 0x6E, 0xD1, 0x00, 0x26, 0x3B, 0x4A, 0x3F, 0x4B, 0x00, 0x21, -+0xD1, 0x54, 0x62, 0xE0, 0x39, 0x4B, 0x1B, 0x78, 0x00, 0x26, 0x00, 0x2B, 0x4F, 0xD0, 0x00, 0x21, 0x3B, 0x48, 0xB2, 0xF7, -+0x1F, 0xFD, 0x00, 0x25, 0xE7, 0xE7, 0x4B, 0x78, 0x02, 0x2B, 0x27, 0xD0, 0x38, 0x4E, 0x05, 0x22, 0xFF, 0x21, 0x30, 0x00, -+0x77, 0xF7, 0x3E, 0xFB, 0x36, 0x4B, 0xF3, 0x18, 0x36, 0x49, 0x58, 0x5C, 0x1F, 0x22, 0x02, 0x40, 0x5A, 0x54, 0x35, 0x4B, -+0x1B, 0x78, 0xEB, 0x81, 0x2B, 0x82, 0x12, 0x23, 0xAB, 0x81, 0x6B, 0x7A, 0x9A, 0x07, 0x07, 0xD5, 0x02, 0x22, 0x93, 0x43, -+0x6B, 0x72, 0x12, 0x23, 0xAB, 0x83, 0x6B, 0x8B, 0x9B, 0x00, 0x6B, 0x83, 0x6B, 0x7A, 0x00, 0x26, 0x5B, 0x07, 0x24, 0xD5, -+0x12, 0x23, 0xAB, 0x85, 0x6B, 0x8D, 0x5B, 0x00, 0x6B, 0x85, 0x1E, 0xE0, 0x00, 0x23, 0x4B, 0x70, 0xD4, 0xE7, 0x23, 0x4E, -+0x05, 0x22, 0xFF, 0x21, 0x30, 0x00, 0x77, 0xF7, 0x13, 0xFB, 0x21, 0x4B, 0xF0, 0x18, 0x21, 0x4A, 0x81, 0x5C, 0x1F, 0x23, -+0x0B, 0x40, 0x83, 0x54, 0x20, 0x4B, 0xC6, 0x5C, 0x00, 0x2E, 0x0A, 0xD0, 0x13, 0x4A, 0x00, 0x21, 0xD1, 0x54, 0x06, 0xE0, -+0x11, 0x4A, 0x16, 0x4B, 0x00, 0x21, 0xD1, 0x54, 0x00, 0x26, 0x00, 0xE0, 0x00, 0x26, 0x23, 0x00, 0x3A, 0x00, 0x29, 0x00, -+0x40, 0x46, 0x18, 0x4D, 0xA8, 0x47, 0x05, 0x00, 0x21, 0x00, 0x0D, 0x48, 0x7B, 0xF7, 0x72, 0xFB, 0x0C, 0x4B, 0x9C, 0x42, -+0x97, 0xD0, 0x00, 0x2E, 0x03, 0xD0, 0x06, 0x4A, 0x10, 0x4B, 0x01, 0x21, 0xD1, 0x54, 0x28, 0x00, 0x04, 0xBC, 0x90, 0x46, -+0xF0, 0xBD, 0xC0, 0x46, 0xF6, 0xDF, 0xFF, 0xFF, 0xC4, 0xD2, 0x10, 0x00, 0xEC, 0xA4, 0x16, 0x00, 0x60, 0xE6, 0x10, 0x00, -+0x0A, 0x20, 0x00, 0x00, 0xB8, 0xD2, 0x10, 0x00, 0x3B, 0x20, 0x00, 0x00, 0x6D, 0x04, 0x00, 0x00, 0x39, 0x20, 0x00, 0x00, -+0x05, 0xA8, 0x16, 0x00, 0xE7, 0xFC, 0xFF, 0xFF, 0x1D, 0x03, 0x00, 0x00, 0xE2, 0xE1, 0x10, 0x00, 0xD6, 0x03, 0x00, 0x00, -+0x15, 0xC9, 0x0B, 0x00, 0xF0, 0xB5, 0x83, 0xB0, 0x06, 0x00, 0x0D, 0x00, 0x17, 0x00, 0x1C, 0x00, 0x17, 0x4B, 0x9C, 0x42, -+0x24, 0xD0, 0x17, 0x4B, 0x9C, 0x42, 0x13, 0xD1, 0xCB, 0x88, 0x10, 0x2B, 0x01, 0xD9, 0x10, 0x23, 0xCB, 0x80, 0x14, 0x4B, -+0x1B, 0x78, 0x6A, 0x88, 0x9A, 0x42, 0x01, 0xD8, 0x6B, 0x80, 0xAB, 0x80, 0xEB, 0x88, 0xAA, 0x88, 0x69, 0x88, 0x28, 0x89, -+0x00, 0x90, 0x0F, 0x48, 0x7B, 0xF7, 0x26, 0xFB, 0x23, 0x00, 0x3A, 0x00, 0x29, 0x00, 0x30, 0x00, 0x0C, 0x4D, 0xA8, 0x47, -+0x05, 0x00, 0x21, 0x00, 0x0B, 0x48, 0x7B, 0xF7, 0x1B, 0xFB, 0x28, 0x00, 0x03, 0xB0, 0xF0, 0xBD, 0x0A, 0x88, 0x00, 0x21, -+0x02, 0x48, 0xFF, 0xF7, 0x03, 0xFA, 0x00, 0x25, 0xF1, 0xE7, 0xC0, 0x46, 0x0D, 0x08, 0x00, 0x00, 0x13, 0x20, 0x00, 0x00, -+0xE2, 0xE1, 0x10, 0x00, 0xAC, 0xD3, 0x10, 0x00, 0x09, 0x1C, 0x0C, 0x00, 0xBC, 0xD3, 0x10, 0x00, 0xF8, 0xB5, 0xCE, 0x46, -+0x47, 0x46, 0x80, 0xB5, 0x14, 0x0A, 0xA4, 0x00, 0x0E, 0x4D, 0x65, 0x59, 0x44, 0x24, 0x2C, 0x5D, 0x03, 0x27, 0x3E, 0x00, -+0x26, 0x40, 0x27, 0x42, 0x11, 0xD0, 0xB9, 0x46, 0xBC, 0x43, 0xA4, 0x46, 0x44, 0x24, 0x67, 0x46, 0x2F, 0x55, 0xB9, 0xF7, -+0x7F, 0xF8, 0x2B, 0x5D, 0x4A, 0x46, 0x93, 0x43, 0x1E, 0x43, 0x2E, 0x55, 0x00, 0x20, 0x0C, 0xBC, 0x90, 0x46, 0x99, 0x46, -+0xF8, 0xBD, 0xB9, 0xF7, 0x73, 0xF8, 0xF7, 0xE7, 0x5C, 0xA9, 0x16, 0x00, 0x70, 0xB5, 0x0D, 0x00, 0x14, 0x0A, 0xA2, 0x00, -+0x29, 0x4B, 0xD6, 0x58, 0x0B, 0x2C, 0x06, 0xD8, 0x00, 0x2E, 0x04, 0xD0, 0x44, 0x23, 0xF3, 0x5C, 0xDB, 0x43, 0x9B, 0x07, -+0x11, 0xD1, 0x2D, 0x23, 0xEB, 0x5C, 0x00, 0x2B, 0x06, 0xD0, 0x2A, 0x00, 0x16, 0x21, 0x20, 0x00, 0x21, 0x4B, 0x98, 0x47, -+0x00, 0x20, 0x70, 0xBD, 0x45, 0x22, 0xB1, 0x5C, 0x7F, 0x23, 0x0B, 0x40, 0xB3, 0x54, 0x00, 0x20, 0xF7, 0xE7, 0x00, 0x21, -+0x20, 0x00, 0xB8, 0xF7, 0x83, 0xFC, 0x00, 0x28, 0x2C, 0xD1, 0x42, 0x23, 0xF3, 0x5A, 0xDB, 0x06, 0x04, 0xD5, 0x28, 0x00, -+0xB8, 0xF7, 0x92, 0xFC, 0x00, 0x28, 0x25, 0xD0, 0x28, 0x00, 0xB8, 0xF7, 0x8D, 0xFC, 0x00, 0x28, 0x0E, 0xD1, 0x2A, 0x00, -+0x00, 0x21, 0x20, 0x00, 0xB8, 0xF7, 0x20, 0xFC, 0x28, 0x00, 0xB8, 0xF7, 0x83, 0xFC, 0x01, 0x00, 0x00, 0x22, 0x20, 0x00, -+0x0D, 0x4B, 0x98, 0x47, 0x01, 0x20, 0xD4, 0xE7, 0x28, 0x00, 0xB8, 0xF7, 0x79, 0xFC, 0x01, 0x28, 0xEB, 0xD0, 0x0A, 0x4B, -+0xDE, 0x6E, 0x28, 0x00, 0xB8, 0xF7, 0x72, 0xFC, 0x01, 0x00, 0x00, 0x23, 0x00, 0x22, 0x20, 0x00, 0xB0, 0x47, 0xE0, 0xE7, -+0x02, 0x20, 0xC2, 0xE7, 0x02, 0x20, 0xC0, 0xE7, 0x5C, 0xA9, 0x16, 0x00, 0x81, 0x45, 0x0C, 0x00, 0xF5, 0x46, 0x0C, 0x00, -+0x28, 0x19, 0x16, 0x00, 0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x82, 0xB0, 0x06, 0x00, 0x0D, 0x00, 0x14, 0x00, 0x1F, 0x00, -+0x13, 0x0A, 0x9B, 0x00, 0x0E, 0x4A, 0x9B, 0x58, 0x00, 0x2B, 0x0E, 0xD0, 0x89, 0x88, 0x0D, 0x4B, 0x9C, 0x46, 0x61, 0x44, -+0x01, 0xAB, 0x98, 0x46, 0x01, 0x22, 0x18, 0x00, 0xD0, 0xF7, 0x5A, 0xF8, 0x43, 0x46, 0x19, 0x78, 0x08, 0x48, 0x7B, 0xF7, -+0x61, 0xFA, 0x3B, 0x00, 0x22, 0x00, 0x29, 0x00, 0x30, 0x00, 0xB9, 0xF7, 0x91, 0xF9, 0x02, 0xB0, 0x04, 0xBC, 0x90, 0x46, -+0xF0, 0xBD, 0xC0, 0x46, 0x5C, 0xA9, 0x16, 0x00, 0x00, 0x00, 0x61, 0x40, 0xC8, 0xD3, 0x10, 0x00, 0xF8, 0xB5, 0x05, 0x00, -+0x0E, 0x00, 0x14, 0x00, 0x1F, 0x00, 0x13, 0x0A, 0x9B, 0x00, 0x08, 0x4A, 0x9B, 0x58, 0x9B, 0x6A, 0x00, 0x2B, 0x03, 0xD0, -+0x59, 0x7A, 0x06, 0x48, 0x7B, 0xF7, 0x40, 0xFA, 0x3B, 0x00, 0x22, 0x00, 0x31, 0x00, 0x28, 0x00, 0xB9, 0xF7, 0x50, 0xFA, -+0xF8, 0xBD, 0xC0, 0x46, 0x5C, 0xA9, 0x16, 0x00, 0xD4, 0xD3, 0x10, 0x00, 0xF8, 0xB5, 0x04, 0x00, 0x06, 0x0A, 0xB2, 0x00, -+0x28, 0x4B, 0xD5, 0x58, 0x28, 0x00, 0x54, 0x30, 0x2A, 0x21, 0xA0, 0xF7, 0x31, 0xFD, 0x00, 0x28, 0x3C, 0xD0, 0xF6, 0xB2, -+0x30, 0x00, 0xAA, 0xF7, 0xB5, 0xF8, 0x20, 0x00, 0x91, 0xF7, 0x02, 0xFA, 0x43, 0x23, 0xEB, 0x5C, 0x00, 0x2B, 0x23, 0xD0, -+0x1F, 0x4B, 0xEB, 0x5C, 0x00, 0x2B, 0x14, 0xD0, 0x95, 0x23, 0x9B, 0x00, 0xEF, 0x18, 0x38, 0x00, 0x86, 0xF7, 0x80, 0xFA, -+0x36, 0x23, 0xE9, 0x5C, 0x3A, 0x00, 0x30, 0x00, 0xA1, 0xF7, 0x42, 0xF8, 0x36, 0x23, 0xEB, 0x5C, 0x01, 0x2B, 0x0A, 0xD0, -+0x2D, 0x21, 0x20, 0x00, 0x79, 0xF7, 0x76, 0xFC, 0x22, 0xE0, 0x36, 0x23, 0xE9, 0x5C, 0x30, 0x00, 0xA1, 0xF7, 0x4B, 0xF8, -+0xF0, 0xE7, 0x2B, 0x21, 0x20, 0x00, 0x79, 0xF7, 0x6B, 0xFC, 0x17, 0xE0, 0x36, 0x23, 0xEB, 0x5C, 0x01, 0x2B, 0x04, 0xD0, -+0x60, 0x21, 0x20, 0x00, 0x79, 0xF7, 0x62, 0xFC, 0x0E, 0xE0, 0x61, 0x21, 0x20, 0x00, 0x79, 0xF7, 0x5D, 0xFC, 0x09, 0xE0, -+0x00, 0x23, 0xAC, 0x22, 0x92, 0x00, 0xAB, 0x54, 0x05, 0x4A, 0xAB, 0x54, 0x00, 0x21, 0x20, 0x00, 0x93, 0xF7, 0xA6, 0xFB, -+0xF8, 0xBD, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, 0xAF, 0x02, 0x00, 0x00, 0xB3, 0x02, 0x00, 0x00, 0xF8, 0xB5, 0x05, 0x00, -+0x0E, 0x00, 0x07, 0x0A, 0xBA, 0x00, 0x1D, 0x4B, 0xD4, 0x58, 0x1D, 0x4B, 0xE3, 0x5C, 0x00, 0x2B, 0x0A, 0xD1, 0x1B, 0x4B, -+0x00, 0x22, 0xE2, 0x54, 0x09, 0x3B, 0xE3, 0x5C, 0x00, 0x2B, 0x27, 0xD0, 0x28, 0x00, 0xFF, 0xF7, 0x8F, 0xFF, 0xF8, 0xBD, -+0x93, 0xF7, 0xCC, 0xF8, 0x00, 0x28, 0x03, 0xD0, 0x14, 0x4B, 0xE3, 0x5C, 0x00, 0x2B, 0x0C, 0xD0, 0x11, 0x4B, 0xE3, 0x5C, -+0x00, 0x2B, 0xE8, 0xD0, 0x88, 0x23, 0xFF, 0x33, 0xE3, 0x5C, 0x00, 0x2B, 0xE3, 0xD0, 0x43, 0x23, 0x01, 0x22, 0xE2, 0x54, -+0xDF, 0xE7, 0x04, 0x33, 0x06, 0x22, 0x00, 0x21, 0x0B, 0x48, 0x79, 0xF7, 0xA3, 0xF8, 0x06, 0x70, 0x80, 0x37, 0x47, 0x80, -+0xCA, 0xF7, 0xFE, 0xFE, 0x43, 0x23, 0x00, 0x22, 0xE2, 0x54, 0xE3, 0xE7, 0x31, 0x00, 0x28, 0x00, 0x93, 0xF7, 0x60, 0xFB, -+0xD5, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, 0xB9, 0x02, 0x00, 0x00, 0xC5, 0x02, 0x00, 0x00, 0x03, 0x11, 0x00, 0x00, -+0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x8C, 0xB0, 0x05, 0x00, 0x0C, 0x00, 0x0F, 0x0A, 0xBA, 0x00, 0x4A, 0x4B, 0xD6, 0x58, -+0x08, 0x00, 0x79, 0xF7, 0x55, 0xFC, 0x20, 0x28, 0x07, 0xD0, 0x21, 0x00, 0x28, 0x00, 0x47, 0x4B, 0x98, 0x47, 0x0C, 0xB0, -+0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0x2A, 0x78, 0x01, 0x23, 0x13, 0x40, 0x39, 0x22, 0xB3, 0x54, 0x69, 0x1C, 0x29, 0x3A, -+0x30, 0x00, 0xCB, 0x30, 0xFF, 0x30, 0xCF, 0xF7, 0x61, 0xFF, 0xFD, 0x23, 0x5B, 0x00, 0x98, 0x46, 0xB0, 0x44, 0x09, 0xAB, -+0x07, 0x93, 0x43, 0x46, 0x06, 0x93, 0x02, 0xA8, 0x10, 0x22, 0x31, 0x00, 0xCB, 0x31, 0xFF, 0x31, 0xCF, 0xF7, 0x52, 0xFF, -+0x6A, 0x46, 0x33, 0x00, 0x6C, 0x33, 0xF1, 0x6E, 0x00, 0x91, 0x9B, 0x88, 0x93, 0x80, 0xCD, 0x23, 0x5B, 0x00, 0xF3, 0x5A, -+0x35, 0x00, 0x9B, 0x35, 0xFF, 0x35, 0x68, 0x88, 0x00, 0x04, 0x18, 0x43, 0xAB, 0x88, 0xE9, 0x88, 0x09, 0x04, 0x19, 0x43, -+0x2B, 0x89, 0x6A, 0x89, 0x12, 0x04, 0x1A, 0x43, 0xAB, 0x89, 0x9C, 0x46, 0xEB, 0x89, 0x1B, 0x04, 0x65, 0x46, 0x2B, 0x43, -+0x83, 0xF7, 0xDA, 0xFD, 0x27, 0x4B, 0xF3, 0x5C, 0x00, 0x2B, 0x1F, 0xD0, 0x39, 0x23, 0xF2, 0x5C, 0xF8, 0xB2, 0x41, 0x46, -+0xA0, 0xF7, 0x93, 0xFE, 0xBE, 0x23, 0x5B, 0x00, 0xF3, 0x5C, 0x00, 0x2B, 0x1B, 0xD0, 0x88, 0x23, 0xFF, 0x33, 0xF3, 0x5C, -+0x00, 0x2B, 0x05, 0xD0, 0x01, 0x23, 0xAC, 0x22, 0x92, 0x00, 0xB3, 0x54, 0x1C, 0x4A, 0xB3, 0x54, 0x37, 0x23, 0xF3, 0x5C, -+0x05, 0x2B, 0x27, 0xD0, 0x00, 0x21, 0x20, 0x00, 0xFF, 0xF7, 0x44, 0xFF, 0x00, 0x20, 0x9C, 0xE7, 0x0C, 0x22, 0x09, 0xA9, -+0x16, 0x4B, 0xF0, 0x18, 0xCF, 0xF7, 0x08, 0xFF, 0xD8, 0xE7, 0x17, 0x33, 0x18, 0x22, 0x00, 0x21, 0x13, 0x48, 0x79, 0xF7, -+0x09, 0xF8, 0x05, 0x00, 0xC0, 0x23, 0x5B, 0x00, 0xF3, 0x5C, 0x83, 0x75, 0x06, 0x22, 0x31, 0x00, 0x72, 0x31, 0xCF, 0xF7, -+0xF7, 0xFE, 0xA8, 0x1D, 0x10, 0x22, 0x31, 0x00, 0x9B, 0x31, 0xFF, 0x31, 0xCF, 0xF7, 0xF0, 0xFE, 0x28, 0x00, 0xCA, 0xF7, -+0x55, 0xFE, 0xC8, 0xE7, 0x05, 0x21, 0x20, 0x00, 0x93, 0xF7, 0x2E, 0xFB, 0x00, 0x20, 0x74, 0xE7, 0x64, 0xA2, 0x16, 0x00, -+0x01, 0x4A, 0x0A, 0x00, 0xC5, 0x02, 0x00, 0x00, 0xB3, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x03, 0x11, 0x00, 0x00, -+0x70, 0xB5, 0x05, 0x00, 0x0C, 0x00, 0x0B, 0x0A, 0x9B, 0x00, 0x0B, 0x4A, 0x9E, 0x58, 0x08, 0x00, 0x79, 0xF7, 0xAE, 0xFB, -+0x24, 0x28, 0x04, 0xD0, 0x21, 0x00, 0x28, 0x00, 0x07, 0x4B, 0x98, 0x47, 0x70, 0xBD, 0xBE, 0x23, 0x5B, 0x00, 0xF3, 0x5C, -+0x00, 0x2B, 0xF5, 0xD1, 0x7D, 0x33, 0xFF, 0x33, 0x01, 0x22, 0xF2, 0x54, 0xF0, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, -+0x55, 0x45, 0x0A, 0x00, 0xF8, 0xB5, 0xCE, 0x46, 0x47, 0x46, 0x80, 0xB5, 0x05, 0x00, 0x0C, 0x00, 0x0F, 0x0A, 0xBA, 0x00, -+0x2F, 0x4B, 0xD6, 0x58, 0x02, 0x78, 0x01, 0x23, 0x13, 0x40, 0x39, 0x22, 0xB3, 0x54, 0x42, 0x78, 0x37, 0x23, 0xF2, 0x54, -+0x08, 0x00, 0x79, 0xF7, 0x83, 0xFB, 0x18, 0x28, 0x04, 0xD8, 0x01, 0x23, 0x83, 0x40, 0x28, 0x4A, 0x13, 0x42, 0x2B, 0xD1, -+0xFB, 0xB2, 0x99, 0x46, 0x18, 0x00, 0xAA, 0xF7, 0x81, 0xF9, 0x80, 0x46, 0x24, 0x4B, 0x01, 0x22, 0xF2, 0x54, 0x21, 0x00, -+0x23, 0x48, 0x78, 0xF7, 0x51, 0xFF, 0x23, 0x4B, 0xF3, 0x5C, 0x00, 0x2B, 0x1F, 0xD1, 0x3C, 0x23, 0xF3, 0x5C, 0x02, 0x2B, -+0x2D, 0xD0, 0x48, 0x46, 0xA9, 0xF7, 0x24, 0xFF, 0x36, 0x23, 0xF3, 0x5C, 0x00, 0x2B, 0x2A, 0xD1, 0x43, 0x46, 0x58, 0x00, -+0x40, 0x44, 0x40, 0x00, 0x80, 0xB2, 0x7B, 0xF7, 0xE7, 0xF8, 0x02, 0x00, 0x21, 0x00, 0x16, 0x48, 0x78, 0xF7, 0xBE, 0xFE, -+0x19, 0x21, 0x20, 0x00, 0x79, 0xF7, 0xF0, 0xFA, 0x00, 0x20, 0x0C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xF8, 0xBD, 0x04, 0x23, -+0x06, 0x22, 0x00, 0x21, 0x10, 0x48, 0x78, 0xF7, 0x6F, 0xFF, 0x6B, 0x78, 0x03, 0x70, 0x80, 0x37, 0x47, 0x80, 0xCA, 0xF7, -+0xC9, 0xFD, 0x00, 0x23, 0x0A, 0x4A, 0xB3, 0x54, 0x43, 0x22, 0xB3, 0x54, 0xCD, 0xE7, 0x20, 0x00, 0x09, 0x4B, 0x98, 0x47, -+0xCD, 0xE7, 0x43, 0x46, 0x58, 0x00, 0x40, 0x44, 0x80, 0xB2, 0xD4, 0xE7, 0x64, 0xA2, 0x16, 0x00, 0x01, 0x00, 0x40, 0x01, -+0xC2, 0x02, 0x00, 0x00, 0x05, 0x06, 0x00, 0x00, 0xB9, 0x02, 0x00, 0x00, 0x03, 0x11, 0x00, 0x00, 0xF5, 0x3A, 0x09, 0x00, -+0x00, 0x20, 0x70, 0x47, 0xF0, 0xB5, 0x83, 0xB0, 0x0C, 0x00, 0x04, 0x23, 0x5B, 0x4A, 0x00, 0x21, 0x5B, 0x48, 0x78, 0xF7, -+0x41, 0xFF, 0x05, 0x00, 0x21, 0x78, 0x5A, 0x48, 0x7B, 0xF7, 0x40, 0xF8, 0x23, 0x78, 0x01, 0x2B, 0x65, 0xD0, 0x06, 0x2B, -+0x00, 0xD1, 0x80, 0xE0, 0x00, 0x2B, 0x05, 0xD0, 0x28, 0x00, 0xCA, 0xF7, 0x91, 0xFD, 0x00, 0x20, 0x03, 0xB0, 0xF0, 0xBD, -+0xA2, 0x78, 0x52, 0x4B, 0x1A, 0x70, 0x00, 0x23, 0x2B, 0x70, 0x6B, 0x70, 0xA3, 0x78, 0xAB, 0x70, 0x4F, 0x4B, 0x1B, 0x78, -+0xEB, 0x70, 0x63, 0x78, 0x01, 0x2B, 0xEB, 0xD1, 0x4D, 0x4B, 0x1B, 0x68, 0x02, 0x2B, 0xE7, 0xD1, 0x49, 0x4B, 0x1B, 0x78, -+0x06, 0x2B, 0xE3, 0xD1, 0xFC, 0xF7, 0x66, 0xF9, 0x49, 0x4C, 0x4A, 0x4B, 0x02, 0x22, 0xE2, 0x54, 0x6B, 0x46, 0xDF, 0x1D, -+0x38, 0x00, 0xB2, 0xF7, 0x2D, 0xFC, 0x3E, 0x78, 0x10, 0x23, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x78, 0xF7, 0x06, 0xFF, -+0xB6, 0x01, 0xA6, 0x19, 0xB0, 0x60, 0x3B, 0x78, 0x9B, 0x01, 0xE3, 0x18, 0x9B, 0x68, 0x01, 0x22, 0x9A, 0x70, 0x00, 0x26, -+0x1E, 0x71, 0x80, 0x22, 0x92, 0x01, 0xDA, 0x80, 0x1A, 0x81, 0x1E, 0x70, 0x5E, 0x70, 0x38, 0x78, 0x43, 0x1C, 0x9B, 0x01, -+0xE3, 0x18, 0x06, 0x22, 0x1A, 0x71, 0x38, 0x4A, 0xA3, 0x5C, 0x03, 0x21, 0x8B, 0x43, 0xA3, 0x54, 0x83, 0x01, 0xE3, 0x18, -+0x1E, 0x86, 0x5E, 0x86, 0x34, 0x4B, 0x98, 0x47, 0x3B, 0x78, 0x5A, 0x1C, 0x92, 0x01, 0xA2, 0x18, 0x07, 0x21, 0x11, 0x71, -+0x9B, 0x01, 0xE3, 0x18, 0x98, 0x68, 0x0C, 0x38, 0x78, 0xF7, 0x27, 0xFF, 0x3B, 0x78, 0x9B, 0x01, 0xE4, 0x18, 0xA6, 0x60, -+0x9E, 0xE7, 0xA3, 0x78, 0x00, 0x2B, 0x0C, 0xD1, 0x24, 0x4B, 0x1B, 0x78, 0x01, 0x33, 0xDB, 0xB2, 0x10, 0x2B, 0x02, 0xD8, -+0x21, 0x4A, 0x13, 0x70, 0x07, 0xE0, 0x20, 0x4B, 0x10, 0x22, 0x1A, 0x70, 0x03, 0xE0, 0x1E, 0x4A, 0x13, 0x78, 0x01, 0x3B, -+0x13, 0x70, 0x00, 0x23, 0x2B, 0x70, 0x01, 0x33, 0x6B, 0x70, 0xA3, 0x78, 0xAB, 0x70, 0x19, 0x4B, 0x1B, 0x78, 0xEB, 0x70, -+0x80, 0xE7, 0xE2, 0x78, 0x12, 0x02, 0xA3, 0x78, 0x13, 0x43, 0x1B, 0x4A, 0x1B, 0xB2, 0x93, 0x42, 0x00, 0xD0, 0x77, 0xE7, -+0x19, 0x4B, 0x1A, 0x80, 0x61, 0x79, 0x09, 0x02, 0x22, 0x79, 0x0A, 0x43, 0x5A, 0x80, 0xE1, 0x79, 0x09, 0x02, 0xA2, 0x79, -+0x0A, 0x43, 0x9A, 0x80, 0x98, 0x68, 0x00, 0x28, 0x01, 0xD0, 0x79, 0xF7, 0x11, 0xF8, 0x20, 0x7A, 0x10, 0x4E, 0xB0, 0x71, -+0x01, 0x21, 0x78, 0xF7, 0x67, 0xFF, 0xB0, 0x60, 0xB2, 0x79, 0x21, 0x00, 0x09, 0x31, 0xCF, 0xF7, 0x87, 0xFD, 0x59, 0xE7, -+0x57, 0xFD, 0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0xE0, 0xD3, 0x10, 0x00, 0xD0, 0xE5, 0x10, 0x00, 0x48, 0x06, 0x16, 0x00, -+0xA8, 0xE5, 0x10, 0x00, 0xEC, 0xA4, 0x16, 0x00, 0x6D, 0x04, 0x00, 0x00, 0x6A, 0x04, 0x00, 0x00, 0xE1, 0xEA, 0x0B, 0x00, -+0x88, 0xAC, 0xFF, 0xFF, 0xC4, 0xE5, 0x10, 0x00, 0x09, 0x4B, 0x1B, 0x68, 0xDA, 0x6E, 0x53, 0x1C, 0x0C, 0xD0, 0x08, 0x4B, -+0x19, 0x68, 0x4B, 0x68, 0x9B, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x06, 0x48, 0x83, 0x42, 0x03, 0xD9, 0x04, 0x32, 0x12, 0x01, -+0x12, 0x09, 0x4A, 0x60, 0x70, 0x47, 0xC0, 0x46, 0xF4, 0xE1, 0x10, 0x00, 0x28, 0x27, 0x16, 0x00, 0xFE, 0xFF, 0xFF, 0x07, -+0x30, 0xB5, 0x83, 0xB0, 0x68, 0x46, 0x77, 0xF7, 0xE5, 0xFC, 0x00, 0x9D, 0x34, 0x4C, 0x23, 0x68, 0x01, 0x22, 0x93, 0x43, -+0x23, 0x60, 0x82, 0xF7, 0x51, 0xFE, 0xB1, 0xF7, 0x69, 0xFE, 0x22, 0x68, 0x8C, 0x23, 0x5B, 0x01, 0x13, 0x43, 0x23, 0x60, -+0x2E, 0x4B, 0x1B, 0x68, 0x5A, 0x1C, 0x09, 0xD0, 0xAB, 0x42, 0x41, 0xD0, 0x2A, 0x49, 0x0B, 0x68, 0x2B, 0x4A, 0x1A, 0x40, -+0x80, 0x23, 0xDB, 0x00, 0x13, 0x43, 0x0B, 0x60, 0x27, 0x4B, 0x5B, 0x68, 0x5A, 0x1C, 0x09, 0xD0, 0xAB, 0x42, 0x36, 0xD0, -+0x23, 0x49, 0x0B, 0x68, 0x25, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0x1B, 0x01, 0x13, 0x43, 0x0B, 0x60, 0x20, 0x4B, 0x9B, 0x68, -+0x5A, 0x1C, 0x09, 0xD0, 0xAB, 0x42, 0x2B, 0xD0, 0x1C, 0x49, 0x0B, 0x68, 0x1F, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0x9B, 0x00, -+0x13, 0x43, 0x0B, 0x60, 0x1D, 0x48, 0x78, 0xF7, 0x3F, 0xFA, 0x18, 0x4B, 0x5B, 0x7F, 0x00, 0x2B, 0x1F, 0xD1, 0x7F, 0xF7, -+0x9B, 0xFE, 0x02, 0x28, 0x21, 0xD1, 0x19, 0x49, 0x0B, 0x68, 0x19, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0x9B, 0x03, 0x13, 0x43, -+0x0B, 0x60, 0x17, 0x4B, 0x1A, 0x68, 0x01, 0x21, 0x0A, 0x43, 0x1A, 0x60, 0x1A, 0x68, 0x01, 0x31, 0x8A, 0x43, 0x1A, 0x60, -+0x03, 0xB0, 0x30, 0xBD, 0x77, 0xF7, 0x4E, 0xFB, 0xC2, 0xE7, 0x77, 0xF7, 0x5F, 0xFB, 0xCD, 0xE7, 0x77, 0xF7, 0x70, 0xFB, -+0xD8, 0xE7, 0xFC, 0xF7, 0x49, 0xFB, 0x05, 0x4B, 0x00, 0x22, 0x5A, 0x77, 0xD9, 0xE7, 0x7F, 0xF7, 0x75, 0xFE, 0x03, 0x28, -+0xEA, 0xD1, 0xD8, 0xE7, 0x0C, 0x00, 0x60, 0x40, 0x3C, 0x95, 0x16, 0x00, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, -+0xFF, 0xFD, 0xFF, 0xFF, 0x01, 0x20, 0x00, 0x00, 0x58, 0x40, 0x34, 0x40, 0xFF, 0xFF, 0xDF, 0xFF, 0x18, 0x00, 0x58, 0x40, -+0xF0, 0xB5, 0xCE, 0x46, 0x47, 0x46, 0x80, 0xB5, 0x83, 0xB0, 0x91, 0x46, 0x9C, 0x4B, 0x1E, 0x68, 0x80, 0x00, 0x84, 0x59, -+0x3C, 0x23, 0xE3, 0x5C, 0x98, 0x46, 0x9A, 0x4B, 0xE3, 0x61, 0xBD, 0xF7, 0x4D, 0xFA, 0x01, 0x90, 0x00, 0x23, 0xA3, 0x62, -+0x00, 0x20, 0xCE, 0xF7, 0x51, 0xFF, 0x96, 0x4B, 0x1D, 0x68, 0xEB, 0x6E, 0x5A, 0x1C, 0x16, 0xD0, 0x63, 0x60, 0x00, 0x23, -+0xA3, 0x60, 0xE7, 0x8E, 0xA7, 0x62, 0x92, 0x49, 0x9A, 0x00, 0x52, 0x58, 0x00, 0x2A, 0x25, 0xD1, 0x01, 0x33, 0x07, 0x2B, -+0xF8, 0xD1, 0x00, 0x23, 0x9C, 0x46, 0x8E, 0x4B, 0x18, 0x00, 0x41, 0x30, 0xFF, 0x30, 0x00, 0x22, 0x00, 0x21, 0x00, 0x91, -+0x1E, 0xE0, 0x8B, 0x4B, 0x1B, 0x68, 0x01, 0x33, 0x09, 0xD0, 0x8A, 0x4B, 0x1B, 0x68, 0x5B, 0x00, 0x01, 0x9A, 0x94, 0x46, -+0x63, 0x44, 0x88, 0x4A, 0x13, 0x40, 0x63, 0x60, 0xDB, 0xE7, 0xA3, 0x8E, 0xE2, 0x8E, 0x9B, 0x1A, 0x5B, 0x00, 0x01, 0x9A, -+0x94, 0x46, 0x63, 0x44, 0x82, 0x4A, 0x13, 0x40, 0x63, 0x60, 0xD0, 0xE7, 0x01, 0x23, 0x9C, 0x46, 0xDB, 0xE7, 0x40, 0x33, -+0x83, 0x42, 0x07, 0xD0, 0x19, 0x78, 0x09, 0x29, 0xF9, 0xD1, 0x01, 0x32, 0xD2, 0xB2, 0x08, 0x39, 0x00, 0x91, 0xF4, 0xE7, -+0xEB, 0x6E, 0x59, 0x1C, 0x21, 0xD0, 0x63, 0x60, 0x75, 0x4B, 0x9A, 0x88, 0x77, 0x4B, 0x9A, 0x42, 0x02, 0xD9, 0x77, 0x4B, -+0x9C, 0x46, 0x62, 0x44, 0x76, 0x4B, 0x7B, 0x43, 0x93, 0x42, 0x00, 0xD9, 0x13, 0x00, 0x75, 0x4A, 0x93, 0x42, 0x00, 0xD2, -+0x13, 0x00, 0x23, 0x61, 0xB3, 0x68, 0x80, 0x22, 0x52, 0x05, 0x93, 0x42, 0x3B, 0xD2, 0x62, 0x68, 0xD3, 0x1A, 0x1B, 0x01, -+0x1B, 0x09, 0x6F, 0x4A, 0x93, 0x42, 0x34, 0xD8, 0x6E, 0x4B, 0x98, 0x47, 0xAF, 0xE0, 0x65, 0x4B, 0x1B, 0x68, 0x01, 0x33, -+0x07, 0xD0, 0x64, 0x4B, 0x18, 0x68, 0x01, 0x9B, 0x1D, 0x18, 0x63, 0x48, 0x05, 0x40, 0x65, 0x60, 0xD2, 0xE7, 0x63, 0x46, -+0x00, 0x2B, 0x03, 0xD1, 0x66, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x08, 0xD0, 0x5C, 0x4B, 0x18, 0x68, 0x80, 0x00, 0x01, 0x9B, -+0xC5, 0x18, 0x5B, 0x4B, 0x1D, 0x40, 0x65, 0x60, 0xC2, 0xE7, 0x00, 0x9B, 0x00, 0x2B, 0xBF, 0xD0, 0x5F, 0x4B, 0x1B, 0x68, -+0x01, 0x2B, 0x06, 0xD9, 0xD3, 0x01, 0x01, 0x9A, 0x9D, 0x18, 0x54, 0x4B, 0x1D, 0x40, 0x65, 0x60, 0xB4, 0xE7, 0x51, 0x4B, -+0x1B, 0x68, 0x01, 0x9A, 0xD5, 0x18, 0x50, 0x4B, 0x1D, 0x40, 0x65, 0x60, 0xAC, 0xE7, 0x4B, 0x46, 0x00, 0x2B, 0x05, 0xD1, -+0x55, 0x4A, 0x26, 0x33, 0xD3, 0x5C, 0xA3, 0x75, 0x63, 0x68, 0xE3, 0x62, 0x52, 0x4A, 0x27, 0x23, 0xD2, 0x5C, 0x18, 0x3B, -+0x1A, 0x40, 0xC0, 0x23, 0xDB, 0x01, 0x13, 0x43, 0xA3, 0x82, 0x3F, 0x23, 0xE1, 0x5C, 0x1B, 0x33, 0x42, 0x46, 0x53, 0x43, -+0x4C, 0x4A, 0x98, 0x18, 0x8A, 0x00, 0x11, 0x43, 0x80, 0x22, 0x52, 0x01, 0x0A, 0x43, 0x02, 0x80, 0x21, 0x8D, 0x49, 0x4A, -+0x9A, 0x18, 0x11, 0x80, 0x3E, 0x22, 0xA2, 0x5C, 0x0A, 0x3A, 0x01, 0x2A, 0x5A, 0xD9, 0x46, 0x4A, 0x98, 0x18, 0xA1, 0x6A, -+0x80, 0x22, 0xD2, 0x01, 0x91, 0x42, 0x00, 0xD3, 0x43, 0x49, 0x44, 0x4A, 0x0A, 0x43, 0x92, 0xB2, 0x02, 0x80, 0x00, 0x21, -+0x42, 0x4A, 0x9A, 0x18, 0x11, 0x80, 0x32, 0x7D, 0x92, 0x07, 0x14, 0xD5, 0xF1, 0x7B, 0x09, 0x02, 0xB2, 0x7B, 0x0A, 0x43, -+0x3E, 0x49, 0x59, 0x18, 0x0A, 0x80, 0x71, 0x7C, 0x09, 0x02, 0x32, 0x7C, 0x0A, 0x43, 0x3C, 0x49, 0x59, 0x18, 0x0A, 0x80, -+0xF1, 0x7C, 0x09, 0x02, 0xB2, 0x7C, 0x0A, 0x43, 0x39, 0x49, 0x59, 0x18, 0x0A, 0x80, 0x71, 0x7D, 0xB5, 0x7D, 0x38, 0x4A, -+0x97, 0x78, 0x7A, 0x1E, 0x97, 0x41, 0x30, 0x7D, 0x80, 0x07, 0xC0, 0x0F, 0x01, 0x22, 0x94, 0x46, 0x00, 0x2D, 0x00, 0xD1, -+0x84, 0x46, 0x33, 0x4A, 0x9E, 0x18, 0x09, 0x02, 0xAA, 0x01, 0x0A, 0x43, 0xFF, 0x00, 0x3A, 0x43, 0x80, 0x00, 0x02, 0x43, -+0x61, 0x46, 0x0A, 0x43, 0x32, 0x80, 0x2E, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1A, 0x88, 0x1F, 0x21, 0x8A, 0x43, 0x11, 0x00, -+0x3E, 0x22, 0xA2, 0x5C, 0x0A, 0x43, 0x1A, 0x80, 0x20, 0x00, 0xCC, 0xF7, 0x71, 0xFF, 0x00, 0x28, 0x0D, 0xD1, 0x00, 0x23, -+0x47, 0x22, 0xA3, 0x54, 0x63, 0x87, 0x03, 0xB0, 0x0C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xF0, 0xBD, 0x22, 0x49, 0x23, 0x4A, -+0x9A, 0x18, 0x11, 0x80, 0x9F, 0xE7, 0x22, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xEE, 0xE7, -+0xE4, 0x29, 0x16, 0x00, 0x71, 0x00, 0x10, 0x00, 0xF4, 0xE1, 0x10, 0x00, 0x38, 0x27, 0x16, 0x00, 0x70, 0xA6, 0x16, 0x00, -+0x5C, 0xAB, 0x16, 0x00, 0xE4, 0xE1, 0x10, 0x00, 0xFE, 0xFF, 0xFF, 0x0F, 0xC4, 0x09, 0x00, 0x00, 0x3C, 0xF6, 0xFF, 0xFF, -+0xE2, 0x04, 0x00, 0x00, 0xA6, 0x0E, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x07, 0x39, 0xC2, 0x0C, 0x00, 0xF0, 0x29, 0x16, 0x00, -+0x50, 0xE0, 0x10, 0x00, 0x7C, 0x91, 0x0D, 0x00, 0x7A, 0x01, 0x61, 0x40, 0x96, 0x01, 0x61, 0x40, 0x90, 0x01, 0x61, 0x40, -+0xFF, 0x3F, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xBC, 0x01, 0x61, 0x40, 0x7C, 0x01, 0x61, 0x40, 0x7E, 0x01, 0x61, 0x40, -+0x80, 0x01, 0x61, 0x40, 0xE8, 0x29, 0x16, 0x00, 0x8A, 0x01, 0x61, 0x40, 0x76, 0x01, 0x61, 0x40, 0x72, 0x3E, 0x00, 0x00, -+0x9E, 0x01, 0x61, 0x40, 0x28, 0x19, 0x16, 0x00, 0x10, 0xB5, 0x10, 0x23, 0x0F, 0x4A, 0x00, 0x21, 0x0F, 0x48, 0x78, 0xF7, -+0x53, 0xFC, 0x00, 0x22, 0x02, 0x70, 0x05, 0x23, 0x43, 0x70, 0x04, 0x3B, 0x83, 0x70, 0x80, 0x21, 0x89, 0x00, 0x81, 0x80, -+0xFE, 0x39, 0xFF, 0x39, 0x81, 0x71, 0xC3, 0x71, 0x0B, 0x31, 0x01, 0x72, 0x43, 0x72, 0x53, 0x31, 0x41, 0x81, 0x57, 0x39, -+0x81, 0x81, 0x83, 0x73, 0xC2, 0x73, 0xCA, 0xF7, 0x9B, 0xFA, 0x00, 0x20, 0x10, 0xBD, 0xC0, 0x46, 0x53, 0xFD, 0x00, 0x00, -+0x01, 0x11, 0x00, 0x00, 0x10, 0xB5, 0x10, 0x4A, 0x11, 0x68, 0xA0, 0x23, 0x5B, 0x03, 0x0B, 0x43, 0x13, 0x60, 0x0E, 0x4C, -+0x01, 0x23, 0x23, 0x60, 0x05, 0x20, 0x7F, 0xF7, 0x10, 0xFD, 0x00, 0x23, 0x23, 0x60, 0x0B, 0x49, 0x04, 0x22, 0x0B, 0x68, -+0x1A, 0x42, 0xFC, 0xD0, 0x06, 0x4A, 0x13, 0x68, 0x08, 0x49, 0x0B, 0x40, 0x13, 0x60, 0x08, 0x4C, 0x01, 0x23, 0x23, 0x60, -+0x05, 0x20, 0x7F, 0xF7, 0xFE, 0xFC, 0x00, 0x23, 0x23, 0x60, 0x10, 0xBD, 0x58, 0x40, 0x34, 0x40, 0x54, 0x40, 0x34, 0x40, -+0x80, 0x40, 0x34, 0x40, 0xFF, 0xFF, 0xEB, 0xFF, 0x48, 0x20, 0x62, 0x40, 0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, -+0x45, 0x46, 0xE0, 0xB5, 0x87, 0xB0, 0x04, 0x90, 0x0F, 0x00, 0x16, 0x00, 0xEF, 0xF3, 0x10, 0x83, 0x01, 0x22, 0x11, 0x00, -+0x19, 0x40, 0x05, 0x91, 0x1A, 0x42, 0x00, 0xD1, 0x72, 0xB6, 0x04, 0x9A, 0x93, 0x00, 0xA3, 0x49, 0x8C, 0x46, 0x63, 0x44, -+0x1C, 0x68, 0xA2, 0x46, 0xA1, 0x4B, 0x63, 0x62, 0xE5, 0x6C, 0x84, 0x23, 0xE3, 0x5A, 0xDB, 0x07, 0x00, 0xD5, 0x4F, 0xE2, -+0x93, 0x00, 0x9E, 0x4A, 0x9B, 0x58, 0x1A, 0x8A, 0x00, 0x2A, 0x0E, 0xD0, 0x84, 0x23, 0xE3, 0x5A, 0x5B, 0x07, 0x00, 0xD5, -+0x36, 0xE2, 0x9A, 0x4B, 0x23, 0x61, 0xA2, 0x6E, 0x99, 0x4B, 0x1B, 0x68, 0x9A, 0x42, 0x00, 0xD1, 0x3C, 0xE2, 0x96, 0x4B, -+0x2F, 0xE2, 0x06, 0x32, 0x1A, 0x82, 0x96, 0x48, 0x7A, 0xF7, 0xD0, 0xFC, 0xEA, 0xE7, 0x96, 0x23, 0x00, 0x22, 0xE2, 0x54, -+0x00, 0x2E, 0x00, 0xD1, 0x34, 0xE2, 0x20, 0x3B, 0xE3, 0x5A, 0x00, 0x2B, 0x00, 0xD1, 0x2F, 0xE2, 0x80, 0x21, 0xC9, 0x00, -+0x8E, 0x4A, 0x02, 0x40, 0x8A, 0x42, 0x00, 0xD0, 0x28, 0xE2, 0x02, 0x07, 0x00, 0xD5, 0x25, 0xE2, 0x4A, 0x22, 0xA2, 0x5C, -+0x00, 0x2A, 0x00, 0xD0, 0x20, 0xE2, 0xA2, 0x6E, 0x5A, 0x43, 0x55, 0x19, 0x2D, 0x01, 0x2D, 0x09, 0x7E, 0x22, 0xA1, 0x5A, -+0x5B, 0x18, 0xA3, 0x52, 0x96, 0x23, 0x7D, 0x3A, 0xE2, 0x54, 0x7B, 0x1B, 0x1B, 0x01, 0x1B, 0x09, 0x81, 0x4A, 0x93, 0x42, -+0x00, 0xD8, 0x13, 0xE2, 0xE7, 0x6D, 0x2B, 0xE2, 0x46, 0x33, 0xE3, 0x5C, 0x00, 0x2B, 0x00, 0xD0, 0x26, 0xE2, 0x7C, 0x33, -+0xE3, 0x5A, 0x7E, 0x22, 0xA2, 0x5A, 0x9B, 0x18, 0x48, 0x22, 0xA2, 0x5A, 0x9B, 0x1A, 0x79, 0x4A, 0x9B, 0xB2, 0x93, 0x42, -+0x00, 0xD9, 0x19, 0xE2, 0x46, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x21, 0xD1, 0x40, 0x33, 0xE3, 0x5A, 0x5D, 0x19, 0x2D, 0x01, -+0x2D, 0x09, 0xC3, 0x07, 0x00, 0xD4, 0xCA, 0xE1, 0x44, 0x23, 0xE3, 0x5A, 0x5B, 0x08, 0x5D, 0x19, 0x2D, 0x01, 0x2D, 0x09, -+0xA3, 0x6B, 0xA3, 0x66, 0x42, 0x23, 0xE2, 0x5A, 0x34, 0x33, 0xE2, 0x52, 0xE3, 0x6B, 0xE3, 0x66, 0x46, 0x23, 0x01, 0x22, -+0xE2, 0x54, 0x48, 0x33, 0xE0, 0x5C, 0x68, 0x4B, 0x98, 0x47, 0x84, 0x23, 0xE3, 0x5A, 0xDB, 0x07, 0x00, 0xD4, 0xBB, 0xE1, -+0x7C, 0x23, 0xE2, 0x5A, 0x02, 0x33, 0xE3, 0x5A, 0xD2, 0x18, 0x48, 0x23, 0xE3, 0x5A, 0xD2, 0x1A, 0x92, 0xB2, 0x53, 0x1E, -+0x9B, 0xB2, 0x00, 0x2A, 0x0A, 0xD0, 0xA1, 0x6E, 0x2F, 0x00, 0x5E, 0x4A, 0x7F, 0x1A, 0x3F, 0x01, 0x3F, 0x09, 0x01, 0x3B, -+0x9B, 0xB2, 0x93, 0x42, 0xF8, 0xD1, 0xDB, 0xE1, 0x2F, 0x00, 0xD9, 0xE1, 0x00, 0x2B, 0x00, 0xD1, 0x5F, 0xE1, 0x68, 0xE1, -+0x01, 0x3B, 0x1B, 0x01, 0x1B, 0x09, 0x56, 0x4A, 0x94, 0x46, 0xE0, 0x44, 0x78, 0xE1, 0x2B, 0x00, 0x63, 0x60, 0x50, 0x46, -+0xCC, 0xF7, 0xFA, 0xFD, 0x00, 0x28, 0x00, 0xD1, 0x2E, 0xE1, 0xA3, 0x7D, 0x50, 0x49, 0x2F, 0x22, 0x8A, 0x5C, 0x9B, 0x18, -+0xA3, 0x75, 0x84, 0x23, 0xE3, 0x5A, 0x9B, 0x07, 0x02, 0xD5, 0x03, 0x9B, 0x00, 0x2B, 0x4C, 0xD0, 0xA3, 0x6E, 0x9C, 0x46, -+0x65, 0x44, 0x2D, 0x01, 0x2D, 0x09, 0x7E, 0x22, 0xA3, 0x5A, 0x01, 0x33, 0xA3, 0x52, 0xA3, 0x7D, 0x01, 0x33, 0xA3, 0x75, -+0x4A, 0x23, 0xE3, 0x5C, 0x01, 0x2B, 0x00, 0xD1, 0x8C, 0xE0, 0xEB, 0x1B, 0x1B, 0x01, 0x1B, 0x09, 0x99, 0x45, 0x00, 0xD8, -+0xF5, 0xE0, 0x84, 0x23, 0xE3, 0x5A, 0xDB, 0x07, 0xCF, 0xD5, 0x72, 0x23, 0xE3, 0x5E, 0x98, 0x46, 0x63, 0x6D, 0xEE, 0x1A, -+0x36, 0x01, 0x36, 0x09, 0x77, 0xF7, 0x3C, 0xFF, 0x14, 0x23, 0x00, 0x28, 0x02, 0xD1, 0xC4, 0x33, 0x37, 0x4A, 0xD3, 0x5A, -+0x7A, 0x22, 0xA0, 0x5A, 0xC0, 0x18, 0x70, 0x43, 0xC8, 0x21, 0xC9, 0x00, 0xCE, 0xF7, 0xA2, 0xFD, 0x20, 0x30, 0x46, 0x00, -+0x84, 0x23, 0xE3, 0x5A, 0x9B, 0x07, 0x00, 0xD5, 0x04, 0xE1, 0x74, 0x23, 0xE2, 0x5A, 0x53, 0x01, 0x9B, 0x1A, 0x9B, 0x00, -+0x9B, 0x18, 0x9A, 0x00, 0x9B, 0x18, 0xF6, 0x18, 0x4A, 0x23, 0xE3, 0x5C, 0x01, 0x2B, 0x00, 0xD0, 0x05, 0xE1, 0x46, 0x23, -+0xE3, 0x5C, 0x00, 0x2B, 0x00, 0xD0, 0x8E, 0xE1, 0xFF, 0xE0, 0xF7, 0xF7, 0xB1, 0xFE, 0x00, 0x28, 0xAE, 0xD0, 0x24, 0x4B, -+0x1A, 0x78, 0x01, 0x23, 0x00, 0x2A, 0x08, 0xD0, 0x22, 0x4B, 0x1B, 0x78, 0x01, 0x3B, 0x5A, 0x1E, 0x93, 0x41, 0x5B, 0x42, -+0x06, 0x22, 0x93, 0x43, 0x08, 0x33, 0xA0, 0x6E, 0x02, 0x00, 0x5A, 0x43, 0x80, 0x21, 0x49, 0x00, 0x8A, 0x42, 0x0C, 0xD9, -+0x5A, 0x1E, 0xD2, 0xB2, 0x42, 0x43, 0x8C, 0x46, 0x00, 0xE0, 0x0A, 0x00, 0x01, 0x3B, 0xDB, 0xB2, 0x62, 0x45, 0x02, 0xD9, -+0x11, 0x1A, 0x00, 0x2B, 0xF7, 0xD1, 0x55, 0x19, 0x2D, 0x01, 0x2D, 0x09, 0x7E, 0x21, 0x62, 0x5A, 0xD3, 0x18, 0x63, 0x52, -+0x01, 0x23, 0x03, 0x93, 0x8B, 0xE7, 0xC0, 0x46, 0xF4, 0x29, 0x16, 0x00, 0x95, 0x9D, 0x10, 0x00, 0x5C, 0xA9, 0x16, 0x00, -+0xDE, 0x0D, 0x00, 0x00, 0x64, 0xE6, 0x10, 0x00, 0xEC, 0xD3, 0x10, 0x00, 0x04, 0x04, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x07, -+0xFE, 0x7F, 0x00, 0x00, 0xF1, 0x12, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x7C, 0x91, 0x0D, 0x00, -+0x8C, 0xA9, 0x16, 0x00, 0xB4, 0xE6, 0x10, 0x00, 0xB3, 0xE6, 0x10, 0x00, 0x46, 0x33, 0xE3, 0x5C, 0x00, 0x2B, 0x00, 0xD0, -+0x6D, 0xE7, 0x7C, 0x33, 0xE3, 0x5A, 0x7E, 0x22, 0xA2, 0x5A, 0x9B, 0x18, 0x48, 0x22, 0xA2, 0x5A, 0x9B, 0x1A, 0x9F, 0x4A, -+0x9B, 0xB2, 0x93, 0x42, 0x00, 0xD9, 0x60, 0xE7, 0x46, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x26, 0xD1, 0x40, 0x33, 0xE3, 0x5A, -+0x5D, 0x19, 0x2D, 0x01, 0x2D, 0x09, 0x84, 0x23, 0xE3, 0x5A, 0xDB, 0x07, 0x00, 0xD4, 0x76, 0xE0, 0x44, 0x23, 0xE3, 0x5A, -+0x5B, 0x08, 0x5D, 0x19, 0x2D, 0x01, 0x2D, 0x09, 0xA3, 0x6B, 0xA3, 0x66, 0x42, 0x23, 0xE2, 0x5A, 0x34, 0x33, 0xE2, 0x52, -+0xE3, 0x6B, 0xE3, 0x66, 0x8E, 0x23, 0xE0, 0x5C, 0x8E, 0x4B, 0x98, 0x47, 0x46, 0x23, 0x01, 0x22, 0xE2, 0x54, 0xE3, 0x6E, -+0x99, 0x46, 0x84, 0x23, 0xE3, 0x5A, 0xDB, 0x07, 0x01, 0xD4, 0x47, 0x23, 0xE2, 0x54, 0x7C, 0x23, 0xE2, 0x5A, 0x02, 0x33, -+0xE3, 0x5A, 0xD2, 0x18, 0x48, 0x23, 0xE3, 0x5A, 0xD2, 0x1A, 0x92, 0xB2, 0x53, 0x1E, 0x9B, 0xB2, 0x00, 0x2A, 0x0A, 0xD0, -+0xA1, 0x6E, 0x2F, 0x00, 0x81, 0x4A, 0x7F, 0x1A, 0x3F, 0x01, 0x3F, 0x09, 0x01, 0x3B, 0x9B, 0xB2, 0x93, 0x42, 0xF8, 0xD1, -+0x1D, 0xE7, 0x2F, 0x00, 0x1B, 0xE7, 0x7D, 0x4B, 0x00, 0x22, 0x1A, 0x70, 0x7C, 0x4B, 0x1B, 0x68, 0x00, 0x21, 0x1B, 0x02, -+0x0A, 0xD5, 0x7B, 0x48, 0x7A, 0xF7, 0x2E, 0xFB, 0x84, 0x23, 0xE2, 0x5A, 0x92, 0x07, 0xD2, 0x17, 0x4F, 0x3B, 0x9A, 0x43, -+0x3E, 0x32, 0x0A, 0xE0, 0x01, 0x20, 0xF8, 0xF7, 0x85, 0xFA, 0x01, 0x21, 0xEF, 0xE7, 0x84, 0x23, 0xE3, 0x5A, 0x08, 0x22, -+0x9B, 0x07, 0x00, 0xD4, 0xB6, 0xE0, 0x01, 0x21, 0x04, 0x98, 0x70, 0x4B, 0x98, 0x47, 0x05, 0x9B, 0x00, 0x2B, 0x00, 0xD1, -+0x62, 0xB6, 0x07, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0x8F, 0x23, 0x00, 0x22, -+0xE2, 0x54, 0xE5, 0x64, 0x0B, 0x3B, 0xE3, 0x5A, 0x9A, 0x07, 0x02, 0xD5, 0x62, 0x4A, 0x00, 0x21, 0x11, 0x70, 0xDB, 0x07, -+0xE7, 0xD5, 0x70, 0x23, 0x42, 0x46, 0xE2, 0x52, 0x1C, 0x36, 0x26, 0x65, 0xE1, 0xE7, 0xA3, 0x6B, 0xA3, 0x66, 0x42, 0x23, -+0xE2, 0x5A, 0x34, 0x33, 0xE2, 0x52, 0xE3, 0x6B, 0xE3, 0x66, 0x91, 0xE7, 0x4A, 0x23, 0xE3, 0x5C, 0x01, 0x2B, 0x00, 0xD1, -+0x91, 0xE0, 0xA2, 0x6E, 0x53, 0x01, 0x9B, 0x1A, 0x9B, 0x00, 0x9B, 0x18, 0x9A, 0x00, 0x9B, 0x18, 0x5B, 0x08, 0xB3, 0x42, -+0xBF, 0xD9, 0x73, 0x08, 0x9B, 0x46, 0x54, 0x49, 0x18, 0x00, 0xCE, 0xF7, 0x81, 0xFC, 0x01, 0x00, 0x2B, 0x1A, 0x1B, 0x01, -+0x1B, 0x09, 0x40, 0x01, 0x40, 0x1A, 0x80, 0x00, 0x40, 0x18, 0x82, 0x00, 0x80, 0x18, 0x42, 0x46, 0x59, 0x46, 0x52, 0x1A, -+0x82, 0x18, 0x90, 0x46, 0x00, 0xD5, 0x7F, 0xE6, 0x42, 0x46, 0xA2, 0x60, 0x22, 0x6E, 0x92, 0x19, 0x22, 0x61, 0x81, 0xE6, -+0xE3, 0x6E, 0x99, 0x46, 0xEB, 0x1B, 0x1B, 0x01, 0x1B, 0x09, 0x08, 0x22, 0x99, 0x45, 0xA0, 0xD9, 0x00, 0x23, 0x03, 0x93, -+0x1C, 0x26, 0x98, 0x46, 0x9F, 0xE6, 0xA3, 0x6B, 0xA3, 0x66, 0x42, 0x23, 0xE2, 0x5A, 0x34, 0x33, 0xE2, 0x52, 0xE3, 0x6B, -+0xE3, 0x66, 0x46, 0x23, 0x01, 0x22, 0xE2, 0x54, 0x47, 0x23, 0x01, 0x22, 0xE2, 0x54, 0x3F, 0xE6, 0x39, 0x4B, 0x23, 0x61, -+0xA2, 0x6E, 0xA1, 0x6D, 0x00, 0x20, 0x01, 0x90, 0x00, 0x93, 0x00, 0x23, 0x20, 0x00, 0xF7, 0xF7, 0xC1, 0xFB, 0x35, 0x4B, -+0xA2, 0x6E, 0x1A, 0x60, 0x84, 0x23, 0xE0, 0x5A, 0xC3, 0x43, 0x9B, 0x07, 0x00, 0xD1, 0xC4, 0xE5, 0x7B, 0x1B, 0x1B, 0x01, -+0x1B, 0x09, 0x30, 0x4A, 0x93, 0x42, 0x13, 0xD8, 0xA1, 0x6E, 0x7E, 0x23, 0xE2, 0x5A, 0x01, 0x32, 0x92, 0xB2, 0x2C, 0x4E, -+0x4D, 0x19, 0x2D, 0x01, 0x2D, 0x09, 0x03, 0x92, 0x01, 0x32, 0x92, 0xB2, 0x7B, 0x1B, 0x1B, 0x01, 0x1B, 0x09, 0xB3, 0x42, -+0xF4, 0xD9, 0x7E, 0x23, 0x03, 0x9A, 0xE2, 0x52, 0xE7, 0x6D, 0x4A, 0x23, 0xE3, 0x5C, 0x01, 0x2B, 0x00, 0xD1, 0xD3, 0xE5, -+0x84, 0x23, 0xE3, 0x5A, 0x9B, 0x07, 0xAB, 0xD4, 0x14, 0x23, 0xA3, 0x75, 0xA2, 0x6E, 0x53, 0x00, 0x9B, 0x18, 0x5B, 0x00, -+0x99, 0x46, 0xEB, 0x1B, 0x1B, 0x01, 0x1B, 0x09, 0x4B, 0x45, 0xA7, 0xD3, 0x12, 0x4B, 0x1B, 0x78, 0x01, 0x33, 0xDB, 0xB2, -+0x03, 0x2B, 0x00, 0xD9, 0x23, 0xE7, 0x0F, 0x4A, 0x13, 0x70, 0x3E, 0x22, 0x3D, 0xE7, 0x46, 0x23, 0xE3, 0x5C, 0x00, 0x2B, -+0x00, 0xD1, 0x68, 0xE7, 0x00, 0x23, 0x47, 0x22, 0xA2, 0x5C, 0x00, 0x2A, 0x00, 0xD0, 0xFF, 0xE5, 0x44, 0x23, 0xE2, 0x5A, -+0x53, 0x01, 0x9B, 0x1A, 0x9B, 0x00, 0x9B, 0x18, 0x9A, 0x00, 0x9B, 0x18, 0xF6, 0x18, 0x62, 0xE7, 0xFE, 0x7F, 0x00, 0x00, -+0xF1, 0x12, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x61, 0xE6, 0x10, 0x00, 0x58, 0x40, 0x34, 0x40, 0xF8, 0xD3, 0x10, 0x00, -+0x65, 0x17, 0x0D, 0x00, 0x71, 0x02, 0x00, 0x00, 0x42, 0x0E, 0x00, 0x00, 0x64, 0xE6, 0x10, 0x00, 0xFE, 0xFF, 0xFF, 0x07, -+0xF8, 0xB5, 0x04, 0x1E, 0x32, 0xD0, 0xA1, 0xF7, 0x55, 0xFD, 0x05, 0x00, 0x8F, 0x23, 0xE6, 0x5C, 0x00, 0x2E, 0x17, 0xD1, -+0xE3, 0x6C, 0xA2, 0x6E, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x01, 0x1B, 0x09, 0xE3, 0x64, 0x7E, 0x22, 0xA3, 0x5A, 0x01, 0x33, -+0xA3, 0x52, 0xA3, 0x7D, 0x13, 0x49, 0x4F, 0x3A, 0x8A, 0x5C, 0x9B, 0x18, 0xA3, 0x75, 0x8E, 0x23, 0xE0, 0x5C, 0x00, 0x22, -+0x29, 0x00, 0xFF, 0xF7, 0x01, 0xFD, 0xF8, 0xBD, 0x67, 0x68, 0xA1, 0xF7, 0x35, 0xFD, 0x03, 0x00, 0x3A, 0x00, 0x31, 0x00, -+0x0B, 0x48, 0x7A, 0xF7, 0x03, 0xFA, 0x8F, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0xDA, 0xD0, 0x09, 0x4B, 0x9B, 0x6E, 0x00, 0x22, -+0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xD3, 0xE7, 0x05, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, -+0xE3, 0xE7, 0xC0, 0x46, 0x7C, 0x91, 0x0D, 0x00, 0x08, 0xD4, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, 0xF0, 0xB5, 0xC6, 0x46, -+0x00, 0xB5, 0x80, 0x46, 0x0F, 0x00, 0x16, 0x00, 0x1D, 0x00, 0x02, 0x21, 0x10, 0x20, 0x78, 0xF7, 0xAD, 0xF9, 0x04, 0x00, -+0x04, 0x23, 0x03, 0x70, 0xFB, 0x33, 0x43, 0x70, 0xF2, 0x3B, 0x83, 0x70, 0x43, 0x46, 0xC3, 0x70, 0x47, 0x60, 0x86, 0x60, -+0xC5, 0x60, 0x1F, 0x4B, 0x1B, 0x68, 0x02, 0x2B, 0x1A, 0xD0, 0x01, 0x2B, 0x30, 0xD1, 0x1D, 0x4B, 0x1B, 0x68, 0x00, 0x2B, -+0x0D, 0xD0, 0x0A, 0x25, 0x1B, 0x4F, 0x80, 0x26, 0xB6, 0x02, 0xE8, 0x20, 0x7F, 0xF7, 0xA7, 0xF9, 0x3B, 0x68, 0x33, 0x42, -+0x25, 0xD1, 0x01, 0x3D, 0xED, 0xB2, 0x00, 0x2D, 0xF5, 0xD1, 0x00, 0x23, 0x15, 0x4A, 0x10, 0x21, 0x20, 0x00, 0x81, 0xF7, -+0x6D, 0xFC, 0x17, 0xE0, 0x13, 0x48, 0x14, 0x49, 0x01, 0x22, 0x43, 0x58, 0x1A, 0x42, 0xFC, 0xD1, 0x10, 0x4B, 0x12, 0x4A, -+0x9C, 0x50, 0x12, 0x4A, 0x99, 0x58, 0x10, 0x20, 0x01, 0x43, 0x99, 0x50, 0x81, 0x21, 0x49, 0x01, 0x5A, 0x58, 0x02, 0x43, -+0x5A, 0x50, 0x0B, 0x49, 0x5A, 0x58, 0x0F, 0x38, 0x02, 0x43, 0x5A, 0x50, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0x0A, 0x4B, -+0x80, 0x22, 0x92, 0x02, 0x1A, 0x60, 0xD8, 0xE7, 0xA8, 0xE5, 0x10, 0x00, 0x28, 0x25, 0x16, 0x00, 0x1C, 0x41, 0x04, 0x40, -+0x19, 0x74, 0x08, 0x00, 0x00, 0x00, 0x07, 0x40, 0x08, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x1C, 0x10, 0x00, 0x00, -+0x08, 0x41, 0x04, 0x40, 0x02, 0x4B, 0x80, 0x22, 0xD2, 0x04, 0x1A, 0x60, 0x70, 0x47, 0xC0, 0x46, 0x00, 0x41, 0x04, 0x40, -+0x10, 0xB5, 0x01, 0x00, 0x13, 0x00, 0xEF, 0xF3, 0x10, 0x82, 0xD2, 0x07, 0x00, 0xD4, 0x72, 0xB6, 0x74, 0x46, 0x0E, 0x4A, -+0x94, 0x42, 0x0F, 0xD0, 0x22, 0x00, 0x0D, 0x48, 0x7A, 0xF7, 0x6A, 0xF9, 0x23, 0x00, 0x00, 0x22, 0x00, 0x21, 0x57, 0x20, -+0xFF, 0xF7, 0x7A, 0xFF, 0x09, 0x4B, 0x1B, 0x68, 0x01, 0x2B, 0x05, 0xD0, 0x72, 0xB6, 0xFE, 0xE7, 0x07, 0x48, 0x7A, 0xF7, -+0x5B, 0xF9, 0x10, 0xBD, 0x06, 0x4B, 0x80, 0x22, 0xD2, 0x04, 0x1A, 0x60, 0xF4, 0xE7, 0xC0, 0x46, 0xB9, 0x25, 0x0D, 0x00, -+0x40, 0xD4, 0x10, 0x00, 0xA8, 0xE5, 0x10, 0x00, 0x18, 0xD4, 0x10, 0x00, 0x00, 0x41, 0x04, 0x40, 0x70, 0xB5, 0x82, 0xB0, -+0x04, 0x00, 0x0D, 0x00, 0xEF, 0xF3, 0x10, 0x82, 0xD2, 0x07, 0x00, 0xD4, 0x72, 0xB6, 0x76, 0x46, 0x00, 0x93, 0x33, 0x00, -+0x2A, 0x00, 0x21, 0x00, 0x09, 0x48, 0x7A, 0xF7, 0x39, 0xF9, 0x33, 0x00, 0x2A, 0x00, 0x21, 0x00, 0x57, 0x20, 0xFF, 0xF7, -+0x49, 0xFF, 0x06, 0x4B, 0x1B, 0x68, 0x01, 0x2B, 0x01, 0xD0, 0x72, 0xB6, 0xFE, 0xE7, 0x04, 0x4B, 0x80, 0x22, 0xD2, 0x04, -+0x1A, 0x60, 0xF8, 0xE7, 0x64, 0xD4, 0x10, 0x00, 0xA8, 0xE5, 0x10, 0x00, 0x00, 0x41, 0x04, 0x40, 0xF0, 0xB5, 0xDE, 0x46, -+0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x87, 0xB0, 0x65, 0x4B, 0x1E, 0x68, 0x07, 0x20, 0xA1, 0xF7, 0xA4, 0xF9, -+0x00, 0x28, 0x06, 0xD1, 0x07, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0x5F, 0x4A, -+0xD5, 0x23, 0x5B, 0x00, 0xD3, 0x5C, 0xDC, 0x00, 0xE4, 0x1A, 0x64, 0x00, 0x5C, 0x4B, 0xE3, 0x18, 0x1D, 0x88, 0xAD, 0xB2, -+0xA1, 0xF7, 0x62, 0xF9, 0x6B, 0x07, 0xE9, 0xD1, 0x3A, 0x23, 0xF3, 0x5C, 0x02, 0x2B, 0x52, 0xD0, 0x57, 0x4B, 0xE3, 0x18, -+0x1B, 0x88, 0x9B, 0xB2, 0x98, 0x46, 0x56, 0x4B, 0xE2, 0x18, 0x13, 0x88, 0x5B, 0x06, 0x1B, 0x0F, 0x02, 0x2B, 0x08, 0xD0, -+0x10, 0x88, 0x40, 0x06, 0x00, 0x0F, 0x52, 0x4B, 0xDF, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x00, 0x21, 0xB8, 0x47, 0x39, 0x23, -+0xF3, 0x5C, 0x00, 0x2B, 0x01, 0xD0, 0xEB, 0x05, 0x53, 0xD4, 0x10, 0x23, 0xFF, 0x22, 0x00, 0x21, 0x4B, 0x48, 0x77, 0xF7, -+0xD5, 0xFF, 0x07, 0x00, 0x00, 0x23, 0x83, 0x73, 0xFB, 0x1D, 0xBA, 0x1D, 0x02, 0x92, 0x05, 0xAA, 0x01, 0x92, 0x00, 0x22, -+0x00, 0x92, 0x3A, 0x00, 0x00, 0x21, 0x40, 0x46, 0xB0, 0xF7, 0x7C, 0xFC, 0x43, 0x4B, 0x19, 0x88, 0x43, 0x4B, 0x1B, 0x88, -+0x05, 0x9A, 0x92, 0x00, 0x09, 0x04, 0x0B, 0x43, 0xD3, 0x1A, 0x6A, 0xD4, 0xDB, 0x03, 0x5B, 0x0C, 0x7B, 0x81, 0x3F, 0x4B, -+0x9C, 0x46, 0x64, 0x44, 0x23, 0x88, 0x3B, 0x73, 0xED, 0x05, 0xED, 0x0F, 0x7D, 0x73, 0x38, 0x00, 0x77, 0xF7, 0xD8, 0xFF, -+0x3C, 0x23, 0xF3, 0x5C, 0x3B, 0x22, 0xB2, 0x5C, 0x9A, 0x42, 0x00, 0xD8, 0x96, 0xE7, 0x01, 0x33, 0x3C, 0x22, 0xB3, 0x54, -+0x92, 0xE7, 0x37, 0x33, 0xF3, 0x5C, 0x00, 0x2B, 0x00, 0xD1, 0x8D, 0xE7, 0xEB, 0x05, 0x00, 0xD4, 0x8A, 0xE7, 0x07, 0x20, -+0xA1, 0xF7, 0x2A, 0xF9, 0x00, 0x28, 0x00, 0xD1, 0x84, 0xE7, 0x25, 0x4A, 0xD5, 0x23, 0x5B, 0x00, 0xD2, 0x5C, 0xD3, 0x00, -+0x9B, 0x1A, 0x5B, 0x00, 0x22, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x88, 0xA1, 0xF7, 0xEE, 0xF8, 0x76, 0xE7, 0x07, 0x20, -+0xA1, 0xF7, 0x16, 0xF9, 0x00, 0x28, 0xA6, 0xD0, 0x1B, 0x4A, 0xD5, 0x23, 0x5B, 0x00, 0xD2, 0x5C, 0xD3, 0x00, 0x9B, 0x1A, -+0x5B, 0x00, 0x19, 0x4A, 0x9A, 0x18, 0x12, 0x88, 0x52, 0x07, 0x02, 0xD0, 0xA1, 0xF7, 0xDA, 0xF8, 0x97, 0xE7, 0x1D, 0x4A, -+0x9A, 0x18, 0x11, 0x88, 0x8A, 0xB2, 0x91, 0x46, 0x1B, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x88, 0xDB, 0x08, 0x9B, 0x46, -+0xFF, 0x23, 0x5A, 0x46, 0x1A, 0x40, 0x92, 0x46, 0x13, 0x00, 0x10, 0x33, 0xFF, 0x22, 0x00, 0x21, 0x0F, 0x48, 0x77, 0xF7, -+0x5D, 0xFF, 0x07, 0x00, 0x5B, 0x46, 0x83, 0x73, 0x12, 0x49, 0x49, 0x44, 0x0F, 0x30, 0x52, 0x46, 0xCE, 0xF7, 0x4C, 0xFE, -+0xA1, 0xF7, 0xB8, 0xF8, 0x7E, 0xE7, 0x80, 0x22, 0x52, 0x05, 0x94, 0x46, 0x63, 0x44, 0x8F, 0xE7, 0x18, 0x27, 0x16, 0x00, -+0x20, 0xA3, 0x16, 0x00, 0x92, 0x69, 0x61, 0x40, 0x9C, 0x69, 0x61, 0x40, 0x94, 0x69, 0x61, 0x40, 0x28, 0x19, 0x16, 0x00, -+0x01, 0x05, 0x00, 0x00, 0xFA, 0x67, 0x61, 0x40, 0xF8, 0x67, 0x61, 0x40, 0x98, 0x69, 0x61, 0x40, 0x9A, 0x69, 0x61, 0x40, -+0x96, 0x69, 0x61, 0x40, 0x00, 0x00, 0x61, 0x40, 0x70, 0xB5, 0xA1, 0xF7, 0x5F, 0xFB, 0x05, 0x00, 0x0F, 0x4B, 0x1C, 0x68, -+0x00, 0x2C, 0x06, 0xD1, 0x0E, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x70, 0xBD, 0xFF, 0xF7, -+0x03, 0xFF, 0x01, 0x21, 0x20, 0x00, 0xCC, 0xF7, 0x81, 0xFB, 0x3A, 0x23, 0xE3, 0x5C, 0x02, 0x2B, 0x06, 0xD0, 0x07, 0x4B, -+0x1B, 0x7D, 0xA3, 0x75, 0x65, 0x60, 0x06, 0x4B, 0x98, 0x47, 0xED, 0xE7, 0x05, 0x4B, 0x98, 0x47, 0xEA, 0xE7, 0xC0, 0x46, -+0x18, 0x27, 0x16, 0x00, 0x28, 0x19, 0x16, 0x00, 0x7C, 0x91, 0x0D, 0x00, 0xE5, 0xC1, 0x0A, 0x00, 0x99, 0xC1, 0x0A, 0x00, -+0x70, 0xB5, 0x0D, 0x00, 0x14, 0x00, 0x07, 0x29, 0x06, 0xD0, 0x11, 0x4B, 0xDE, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x21, 0x00, -+0x28, 0x00, 0xB0, 0x47, 0x01, 0x2C, 0x0E, 0xD9, 0x04, 0x2C, 0x0F, 0xD1, 0x0C, 0x4B, 0x1C, 0x68, 0x01, 0x21, 0x20, 0x00, -+0xCC, 0xF7, 0x52, 0xFB, 0x3A, 0x23, 0x00, 0x22, 0xE2, 0x54, 0x20, 0x00, 0x08, 0x4B, 0x98, 0x47, 0x01, 0xE0, 0xFF, 0xF7, -+0xB3, 0xFF, 0x70, 0xBD, 0x03, 0x4B, 0xDE, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x21, 0x00, 0x28, 0x00, 0xB0, 0x47, 0xF6, 0xE7, -+0x28, 0x19, 0x16, 0x00, 0x18, 0x27, 0x16, 0x00, 0xD1, 0xC2, 0x0A, 0x00, 0x10, 0xB5, 0x01, 0x28, 0x00, 0xD0, 0x10, 0xBD, -+0x00, 0x29, 0xFC, 0xD0, 0x04, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0xF8, 0xD0, 0x03, 0x4A, 0xDA, 0x61, 0x03, 0x48, 0x79, 0xF7, -+0xCB, 0xFF, 0xF2, 0xE7, 0x24, 0x27, 0x16, 0x00, 0x85, 0x04, 0x10, 0x00, 0x94, 0xD4, 0x10, 0x00, 0x70, 0xB5, 0x1E, 0x4B, -+0x1E, 0x4A, 0x13, 0x60, 0x80, 0x22, 0x52, 0x00, 0x9C, 0x5C, 0x1D, 0x4B, 0xE3, 0x18, 0x1B, 0x01, 0x1A, 0x88, 0xD2, 0x08, -+0x06, 0x21, 0x11, 0x42, 0x08, 0xD1, 0x19, 0x88, 0x89, 0x06, 0x49, 0x0F, 0x18, 0x4B, 0xDD, 0x6E, 0x00, 0x23, 0x00, 0x22, -+0x20, 0x00, 0xA8, 0x47, 0x13, 0x4B, 0x1A, 0x68, 0x81, 0x23, 0x5B, 0x00, 0xD3, 0x5C, 0x00, 0x2B, 0x05, 0xD1, 0x12, 0x4B, -+0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x0D, 0x4B, 0x1B, 0x68, 0x22, 0x01, 0x9B, 0x18, 0x1B, 0x7B, -+0x00, 0x2B, 0x05, 0xD1, 0x0B, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x06, 0x4B, 0x1A, 0x68, -+0x23, 0x01, 0xD3, 0x18, 0x5D, 0x68, 0x00, 0x2D, 0x03, 0xD0, 0x99, 0x68, 0x18, 0x68, 0x02, 0x22, 0xA8, 0x47, 0x70, 0xBD, -+0x80, 0x2A, 0x16, 0x00, 0x0C, 0xE7, 0x10, 0x00, 0x00, 0x10, 0x06, 0x04, 0x28, 0x19, 0x16, 0x00, 0x10, 0xB5, 0xFF, 0x23, -+0x9B, 0x00, 0x98, 0x42, 0x08, 0xD9, 0x05, 0x4B, 0x59, 0x80, 0x00, 0x24, 0x21, 0x00, 0x04, 0x48, 0x79, 0xF7, 0x72, 0xFF, -+0x20, 0x00, 0x10, 0xBD, 0x11, 0x24, 0xF7, 0xE7, 0x54, 0x2A, 0x16, 0x00, 0xA0, 0xD4, 0x10, 0x00, 0x70, 0xB5, 0x04, 0x00, -+0x0D, 0x00, 0x81, 0x88, 0x00, 0x88, 0xFF, 0xF7, 0xE5, 0xFF, 0x01, 0x1E, 0x04, 0xD0, 0x28, 0x00, 0xFC, 0xF7, 0x90, 0xFE, -+0x00, 0x20, 0x70, 0xBD, 0xE1, 0x88, 0xA0, 0x78, 0xCB, 0xF7, 0xB6, 0xFE, 0x01, 0x00, 0xF4, 0xE7, 0xF0, 0xB5, 0xCE, 0x46, -+0x47, 0x46, 0x80, 0xB5, 0x89, 0xB0, 0x06, 0x00, 0x0A, 0x00, 0x04, 0x23, 0x00, 0x21, 0x26, 0x48, 0x77, 0xF7, 0x46, 0xFE, -+0x80, 0x46, 0x00, 0x23, 0x43, 0x80, 0xB1, 0x79, 0x23, 0x48, 0x79, 0xF7, 0x43, 0xFF, 0xB3, 0x79, 0x00, 0x2B, 0x2A, 0xD1, -+0x60, 0x24, 0x6B, 0x46, 0xDD, 0x1D, 0x16, 0x23, 0x99, 0x46, 0x1F, 0x4F, 0x07, 0xE0, 0x03, 0x23, 0x42, 0x46, 0x13, 0x70, -+0x24, 0xE0, 0x01, 0x34, 0xE4, 0xB2, 0x68, 0x2C, 0x20, 0xD0, 0x4B, 0x46, 0x2B, 0x70, 0x02, 0xAA, 0x29, 0x00, 0x20, 0x00, -+0x3B, 0x68, 0x98, 0x47, 0x00, 0x28, 0xF2, 0xD1, 0x06, 0x22, 0x02, 0xA9, 0x30, 0x00, 0xCE, 0xF7, 0xF3, 0xFC, 0x00, 0x28, -+0xEB, 0xD1, 0x12, 0x4B, 0x9B, 0x68, 0x20, 0x00, 0x98, 0x47, 0x00, 0x28, 0xE1, 0xD1, 0x43, 0x46, 0x5B, 0x88, 0x01, 0x33, -+0x42, 0x46, 0x53, 0x80, 0x04, 0xE0, 0x01, 0x2B, 0x0B, 0xD0, 0x12, 0x23, 0x42, 0x46, 0x13, 0x70, 0x40, 0x46, 0xC9, 0xF7, -+0x69, 0xFC, 0x00, 0x20, 0x09, 0xB0, 0x0C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xF0, 0xBD, 0x43, 0x46, 0x5B, 0x88, 0x08, 0x33, -+0x42, 0x46, 0x53, 0x80, 0xF0, 0xE7, 0xC0, 0x46, 0x01, 0x11, 0x00, 0x00, 0xAC, 0xD4, 0x10, 0x00, 0x94, 0x92, 0x16, 0x00, -+0xF0, 0xB5, 0xDE, 0x46, 0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x85, 0xB0, 0x0C, 0x00, 0x16, 0x00, 0x17, 0x0A, -+0xBA, 0x00, 0x91, 0x4B, 0xD5, 0x58, 0x50, 0x23, 0xEB, 0x5C, 0x00, 0x2B, 0x00, 0xD0, 0xD6, 0xE0, 0x4B, 0x78, 0x5B, 0x08, -+0x98, 0x46, 0x7F, 0x2B, 0x11, 0xD0, 0x01, 0x93, 0x00, 0x22, 0x19, 0x00, 0x8A, 0x48, 0x79, 0xF7, 0xDD, 0xFE, 0x43, 0x46, -+0x7E, 0x2B, 0x56, 0xD1, 0x36, 0x3B, 0xEB, 0x5C, 0x00, 0x2B, 0x43, 0xD0, 0x00, 0x23, 0x9B, 0x46, 0x7E, 0x33, 0x01, 0x93, -+0x0C, 0xE0, 0x8B, 0x78, 0x9B, 0x46, 0x1A, 0x00, 0x7F, 0x21, 0x81, 0x48, 0x79, 0xF7, 0xCA, 0xFE, 0x7F, 0x23, 0x01, 0x93, -+0x48, 0x23, 0xEB, 0x5C, 0x00, 0x2B, 0x43, 0xD0, 0xFB, 0xB2, 0x99, 0x46, 0x61, 0x78, 0x4F, 0x08, 0x59, 0x29, 0x00, 0xD8, -+0xE0, 0xE0, 0x7F, 0x2F, 0x05, 0xD1, 0xA3, 0x78, 0x9A, 0x46, 0x0D, 0x2B, 0x55, 0xD8, 0x0B, 0x2B, 0x55, 0xD8, 0x07, 0x23, -+0x02, 0xAA, 0x94, 0x46, 0x63, 0x44, 0x9A, 0x46, 0x23, 0x78, 0x52, 0x46, 0x13, 0x70, 0x14, 0x23, 0x32, 0x00, 0x31, 0x00, -+0x70, 0x48, 0x77, 0xF7, 0xA3, 0xFD, 0x07, 0x00, 0x61, 0x1C, 0x52, 0x46, 0x82, 0xF7, 0x30, 0xF9, 0x02, 0x28, 0x75, 0xD0, -+0x00, 0x28, 0x00, 0xD1, 0xA9, 0xE0, 0x04, 0x28, 0x00, 0xD0, 0x99, 0xE0, 0xFB, 0x22, 0x43, 0x46, 0x15, 0x3B, 0x13, 0x42, -+0x00, 0xD1, 0xB1, 0xE0, 0x19, 0x24, 0x6F, 0xE0, 0x36, 0x33, 0xEB, 0x5C, 0x5A, 0x42, 0x53, 0x41, 0xDB, 0xB2, 0xF8, 0xB2, -+0x0C, 0x22, 0x7E, 0x21, 0x9F, 0xF7, 0xC7, 0xFA, 0x00, 0x23, 0x9B, 0x46, 0x7E, 0x33, 0x01, 0x93, 0xBE, 0xE7, 0x00, 0x23, -+0x9B, 0x46, 0xB7, 0xE7, 0x59, 0x46, 0x40, 0x46, 0x82, 0xF7, 0x96, 0xF8, 0x00, 0x28, 0xB5, 0xD1, 0x43, 0x46, 0x7F, 0x2B, -+0x0A, 0xD0, 0x36, 0x23, 0xEB, 0x5C, 0x5A, 0x42, 0x53, 0x41, 0xDB, 0xB2, 0xF8, 0xB2, 0x0C, 0x22, 0x41, 0x46, 0x9F, 0xF7, -+0xAC, 0xFA, 0x5A, 0xE0, 0x49, 0x3B, 0xEB, 0x5C, 0x5A, 0x42, 0x53, 0x41, 0xDB, 0xB2, 0xF8, 0xB2, 0x0C, 0x22, 0x59, 0x46, -+0x9F, 0xF7, 0xB0, 0xFA, 0x4F, 0xE0, 0x15, 0x2B, 0xA9, 0xD1, 0x4B, 0x46, 0x9B, 0x00, 0x48, 0x4A, 0x9B, 0x58, 0xB2, 0x22, -+0x92, 0x00, 0x9A, 0x5C, 0x00, 0x2A, 0xA0, 0xD0, 0xCA, 0x07, 0x9E, 0xD5, 0x46, 0x4A, 0x9A, 0x5C, 0xBA, 0x42, 0x14, 0xD1, -+0x7F, 0x2F, 0x98, 0xD1, 0x44, 0x4A, 0x9B, 0x5C, 0x53, 0x45, 0x94, 0xD0, 0x4B, 0x46, 0x1B, 0x02, 0x01, 0x20, 0x18, 0x43, -+0x78, 0xF7, 0x16, 0xF9, 0x00, 0x28, 0x30, 0xD0, 0x01, 0x23, 0x2A, 0x22, 0x51, 0x46, 0x48, 0x46, 0x9F, 0xF7, 0x8A, 0xFA, -+0x29, 0xE0, 0x4B, 0x46, 0x1B, 0x02, 0x01, 0x20, 0x18, 0x43, 0x78, 0xF7, 0x07, 0xF9, 0x00, 0x28, 0x21, 0xD0, 0x7F, 0x2F, -+0xEE, 0xD0, 0x01, 0x23, 0x2A, 0x22, 0x39, 0x00, 0x48, 0x46, 0x9F, 0xF7, 0x6A, 0xFA, 0x18, 0xE0, 0x33, 0x4B, 0xDC, 0x6E, -+0x00, 0x23, 0x00, 0x22, 0x01, 0x99, 0x08, 0x00, 0xA0, 0x47, 0x1E, 0x24, 0x38, 0x00, 0x0C, 0x38, 0x77, 0xF7, 0x69, 0xFD, -+0x43, 0x46, 0x7F, 0x2B, 0x1C, 0xD0, 0x36, 0x23, 0xEB, 0x5C, 0x5A, 0x42, 0x53, 0x41, 0xDB, 0xB2, 0x22, 0x00, 0x41, 0x46, -+0x48, 0x46, 0x9F, 0xF7, 0x50, 0xFA, 0x8A, 0x23, 0xFF, 0x33, 0xEB, 0x5C, 0x00, 0x2B, 0x03, 0xD0, 0x25, 0x4B, 0xEB, 0x5C, -+0x00, 0x2B, 0x18, 0xD1, 0x00, 0x20, 0x05, 0xB0, 0x3C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, -+0x1E, 0x24, 0xDB, 0xE7, 0x49, 0x3B, 0xEB, 0x5C, 0x5A, 0x42, 0x53, 0x41, 0xDB, 0xB2, 0x22, 0x00, 0x59, 0x46, 0x48, 0x46, -+0x9F, 0xF7, 0x42, 0xFA, 0xE1, 0xE7, 0x38, 0x00, 0x77, 0xF7, 0x16, 0xFD, 0xDD, 0xE7, 0xAA, 0x8D, 0xEB, 0x8D, 0xD2, 0x1A, -+0x31, 0x00, 0x16, 0x48, 0x77, 0xF7, 0x24, 0xFC, 0xAA, 0x8D, 0x31, 0x00, 0x14, 0x48, 0x77, 0xF7, 0x1F, 0xFC, 0xD9, 0xE7, -+0x38, 0x00, 0x0C, 0x38, 0x77, 0xF7, 0x29, 0xFD, 0x1A, 0x24, 0xC0, 0xE7, 0x12, 0x2F, 0x00, 0xD8, 0x23, 0xE7, 0x3A, 0x00, -+0x13, 0x3A, 0xD2, 0xB2, 0x01, 0x23, 0x93, 0x40, 0x0C, 0x4A, 0x13, 0x42, 0x00, 0xD1, 0x1A, 0xE7, 0x00, 0x23, 0x9A, 0x46, -+0x6D, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, 0xBC, 0xD4, 0x10, 0x00, 0x01, 0x06, 0x00, 0x00, 0xC6, 0x02, 0x00, 0x00, -+0xC7, 0x02, 0x00, 0x00, 0x28, 0x19, 0x16, 0x00, 0xAF, 0x02, 0x00, 0x00, 0x09, 0x06, 0x00, 0x00, 0x0A, 0x06, 0x00, 0x00, -+0x31, 0x00, 0x00, 0x03, 0x30, 0xB5, 0x87, 0xB0, 0x1E, 0x4C, 0x23, 0x7B, 0x03, 0x22, 0x13, 0x43, 0x23, 0x73, 0x03, 0xAD, -+0x21, 0x00, 0x27, 0x31, 0x03, 0x22, 0x28, 0x00, 0xCE, 0xF7, 0x9E, 0xFB, 0xE3, 0x89, 0xAB, 0x80, 0x23, 0x8A, 0xEB, 0x80, -+0xA3, 0x7C, 0x2B, 0x72, 0x23, 0x7F, 0x6B, 0x72, 0x28, 0x00, 0xA2, 0xF7, 0x3F, 0xFB, 0x23, 0x00, 0x3C, 0x33, 0x00, 0x24, -+0x1A, 0x78, 0x00, 0x2A, 0x06, 0xD0, 0x01, 0x34, 0xE4, 0xB2, 0x09, 0x33, 0x07, 0x2C, 0xF7, 0xD1, 0x07, 0xB0, 0x30, 0xBD, -+0x06, 0x2C, 0xFB, 0xD8, 0x01, 0xA8, 0x0B, 0x4B, 0x1A, 0x8B, 0x02, 0x80, 0x5A, 0x8B, 0x42, 0x80, 0x5B, 0x7F, 0x03, 0x71, -+0x44, 0x71, 0x08, 0x4A, 0xD0, 0x23, 0xD3, 0x58, 0x98, 0x47, 0x00, 0x28, 0xEC, 0xD1, 0xE3, 0x00, 0x1B, 0x19, 0x03, 0x4C, -+0xE4, 0x18, 0x3C, 0x34, 0x02, 0x23, 0x23, 0x70, 0xE4, 0xE7, 0xC0, 0x46, 0x68, 0x9E, 0x16, 0x00, 0x28, 0x19, 0x16, 0x00, -+0x10, 0xB5, 0x07, 0x4C, 0xA0, 0x47, 0x86, 0xF7, 0x97, 0xF8, 0x00, 0x28, 0x01, 0xD1, 0x00, 0x20, 0x10, 0xBD, 0xFF, 0xF7, -+0xB1, 0xFF, 0x03, 0x48, 0x79, 0xF7, 0x66, 0xFD, 0xF7, 0xE7, 0xC0, 0x46, 0xDD, 0x90, 0x0A, 0x00, 0xCC, 0xD4, 0x10, 0x00, -+0x00, 0xB5, 0x83, 0xB0, 0x01, 0xAA, 0x01, 0x23, 0x0B, 0x40, 0x30, 0x21, 0x0B, 0x43, 0x13, 0x70, 0x11, 0x00, 0x9F, 0xF7, -+0x41, 0xF9, 0x03, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x30, 0xB5, 0x83, 0xB0, 0x04, 0x00, 0x00, 0x0A, 0x82, 0x00, 0x0E, 0x4B, -+0xD2, 0x58, 0x3C, 0x23, 0xD3, 0x5C, 0x02, 0x2B, 0x07, 0xD0, 0x96, 0x22, 0x52, 0x00, 0x21, 0x00, 0x0A, 0x48, 0x77, 0xF7, -+0x7D, 0xFB, 0x03, 0xB0, 0x30, 0xBD, 0x6B, 0x46, 0x9D, 0x1D, 0xC0, 0xB2, 0x00, 0x22, 0x29, 0x00, 0x89, 0xF7, 0xEE, 0xFA, -+0x28, 0x88, 0x79, 0xF7, 0x95, 0xFD, 0x40, 0x00, 0x02, 0x00, 0x2D, 0x32, 0xFF, 0x32, 0xEA, 0xE7, 0x64, 0xA2, 0x16, 0x00, -+0x05, 0x06, 0x00, 0x00, 0x10, 0xB5, 0x04, 0x00, 0x00, 0x0A, 0x82, 0x00, 0x07, 0x4B, 0xD2, 0x58, 0x36, 0x23, 0xD1, 0x5C, -+0xC0, 0xB2, 0xFF, 0xF7, 0xC1, 0xFF, 0x20, 0x00, 0xFF, 0xF7, 0xCC, 0xFF, 0x32, 0x21, 0x20, 0x00, 0x77, 0xF7, 0x8C, 0xFF, -+0x10, 0xBD, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, 0x70, 0xB5, 0x14, 0x00, 0x15, 0x0A, 0xAA, 0x00, 0x17, 0x4B, 0xD6, 0x58, -+0x20, 0x00, 0x77, 0xF7, 0xDF, 0xFF, 0x03, 0x00, 0x19, 0x28, 0x1D, 0xD8, 0x01, 0x38, 0xC0, 0xB2, 0x14, 0x28, 0x06, 0xD8, -+0x02, 0x20, 0x01, 0x2B, 0x15, 0xD1, 0x3C, 0x23, 0xF3, 0x5C, 0x02, 0x2B, 0x16, 0xD0, 0x08, 0x23, 0x14, 0x22, 0x00, 0x21, -+0x0D, 0x48, 0x77, 0xF7, 0xF5, 0xFB, 0x0C, 0x23, 0x03, 0x70, 0x80, 0x35, 0x45, 0x80, 0x00, 0x23, 0xC3, 0x80, 0x3C, 0x33, -+0xF3, 0x5C, 0x03, 0x71, 0xC9, 0xF7, 0x4A, 0xFA, 0x00, 0x20, 0x70, 0xBD, 0x02, 0x20, 0x66, 0x2B, 0xFB, 0xD1, 0xE4, 0xE7, -+0x20, 0x00, 0xFF, 0xF7, 0xB9, 0xFF, 0x00, 0x20, 0xF5, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, 0x03, 0x11, 0x00, 0x00, -+0x70, 0xB5, 0x82, 0xB0, 0x14, 0x00, 0x15, 0x0A, 0xAA, 0x00, 0x24, 0x4B, 0xD6, 0x58, 0x20, 0x00, 0x77, 0xF7, 0xA6, 0xFF, -+0x01, 0x28, 0x16, 0xD0, 0x04, 0xD9, 0x16, 0x38, 0xC3, 0xB2, 0x02, 0x20, 0x03, 0x2B, 0x0E, 0xD8, 0x06, 0x23, 0x1C, 0x22, -+0x00, 0x21, 0x1D, 0x48, 0x77, 0xF7, 0xC2, 0xFB, 0x02, 0x23, 0x03, 0x70, 0x80, 0x35, 0x45, 0x80, 0x00, 0x23, 0x83, 0x80, -+0xC9, 0xF7, 0x1A, 0xFA, 0x00, 0x20, 0x02, 0xB0, 0x70, 0xBD, 0x36, 0x23, 0xF3, 0x5C, 0x00, 0x2B, 0x0E, 0xD1, 0x01, 0xA9, -+0x0A, 0x33, 0x0B, 0x70, 0xE8, 0xB2, 0x9F, 0xF7, 0x9D, 0xF8, 0x20, 0x00, 0xFF, 0xF7, 0x5C, 0xFF, 0x06, 0x21, 0x20, 0x00, -+0x77, 0xF7, 0x1C, 0xFF, 0x00, 0x20, 0xEA, 0xE7, 0x06, 0x23, 0x1C, 0x22, 0x00, 0x21, 0x0B, 0x48, 0x77, 0xF7, 0x9E, 0xFB, -+0x04, 0x00, 0x00, 0x23, 0x03, 0x70, 0x2B, 0x00, 0x80, 0x33, 0x43, 0x80, 0xE8, 0xB2, 0xA8, 0xF7, 0x3D, 0xFF, 0x00, 0x04, -+0x40, 0x0C, 0xA0, 0x80, 0x20, 0x00, 0xC9, 0xF7, 0xEF, 0xF9, 0x00, 0x20, 0xD3, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, -+0x03, 0x11, 0x00, 0x00, 0x70, 0xB5, 0x14, 0x00, 0x13, 0x0A, 0x9B, 0x00, 0x14, 0x4A, 0x9D, 0x58, 0x20, 0x00, 0x77, 0xF7, -+0x55, 0xFF, 0x00, 0x28, 0x1E, 0xD0, 0x16, 0x38, 0xC3, 0xB2, 0x00, 0x20, 0x03, 0x2B, 0x13, 0xD9, 0x43, 0x23, 0x01, 0x22, -+0xEA, 0x54, 0x07, 0x3B, 0xEB, 0x5C, 0x02, 0x2B, 0x0D, 0xD0, 0x37, 0x23, 0xE9, 0x5C, 0x20, 0x00, 0x8B, 0xF7, 0x32, 0xF8, -+0x00, 0x28, 0x0D, 0xD0, 0x37, 0x23, 0xE9, 0x5C, 0x20, 0x00, 0x90, 0xF7, 0x57, 0xFF, 0x00, 0x20, 0x70, 0xBD, 0x20, 0x00, -+0x89, 0xF7, 0xFE, 0xFD, 0x02, 0x20, 0xF9, 0xE7, 0x00, 0x20, 0xF7, 0xE7, 0x02, 0x20, 0xF5, 0xE7, 0x64, 0xA2, 0x16, 0x00, -+0x10, 0xB5, 0x80, 0x00, 0x0F, 0x4B, 0xC4, 0x58, 0x8E, 0xF7, 0xD4, 0xFC, 0x03, 0x00, 0x01, 0x20, 0x0B, 0x2B, 0x13, 0xD9, -+0x11, 0x2B, 0x06, 0xD8, 0x20, 0x00, 0x54, 0x30, 0x00, 0x21, 0x9E, 0xF7, 0x53, 0xFF, 0x00, 0x28, 0x0B, 0xD1, 0x20, 0x00, -+0x54, 0x30, 0x01, 0x21, 0x9E, 0xF7, 0x4C, 0xFF, 0x43, 0x42, 0x58, 0x41, 0x40, 0x42, 0x03, 0x23, 0x98, 0x43, 0x05, 0x30, -+0x10, 0xBD, 0x03, 0x20, 0xFC, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, 0x02, 0x00, 0x00, 0x29, 0x16, 0xD1, 0x01, 0x23, -+0x03, 0x40, 0x58, 0x42, 0x43, 0x41, 0x58, 0x42, 0x20, 0x4B, 0x18, 0x40, 0x20, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0x06, 0x23, -+0x1A, 0x40, 0x04, 0x2A, 0x02, 0xD0, 0x02, 0x2A, 0x03, 0xD0, 0x70, 0x47, 0x80, 0x04, 0x80, 0x0C, 0xFB, 0xE7, 0x1B, 0x4B, -+0x18, 0x40, 0xF8, 0xE7, 0x18, 0x23, 0x19, 0x00, 0x01, 0x40, 0x03, 0x42, 0x21, 0xD0, 0x08, 0x29, 0x0E, 0xD0, 0x60, 0x23, -+0x03, 0x40, 0x40, 0x2B, 0x21, 0xD0, 0x20, 0x3B, 0x18, 0x00, 0x43, 0x1E, 0x98, 0x41, 0x40, 0x42, 0x12, 0x4B, 0x18, 0x40, -+0x12, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0xE2, 0xE7, 0x48, 0x33, 0x03, 0x40, 0x60, 0x2B, 0x0E, 0xD0, 0x40, 0x2B, 0x0E, 0xD0, -+0x20, 0x3B, 0x18, 0x00, 0x43, 0x1E, 0x98, 0x41, 0x40, 0x42, 0x0C, 0x4B, 0x18, 0x40, 0x0C, 0x4B, 0x9C, 0x46, 0x60, 0x44, -+0xD1, 0xE7, 0x0B, 0x48, 0xCF, 0xE7, 0x0B, 0x48, 0xCD, 0xE7, 0x0B, 0x48, 0xCB, 0xE7, 0x0B, 0x48, 0xC9, 0xE7, 0xC0, 0x46, -+0xF0, 0x77, 0xFF, 0xFF, 0x1E, 0xFF, 0x00, 0x00, 0xFF, 0x33, 0x00, 0x00, 0x00, 0xCD, 0xFF, 0xFF, 0x08, 0x33, 0x00, 0x00, -+0x00, 0xEF, 0xFF, 0xFF, 0x0C, 0x33, 0x00, 0x00, 0x0E, 0x33, 0x00, 0x00, 0x0C, 0x22, 0x00, 0x00, 0x0C, 0x32, 0x00, 0x00, -+0x08, 0x30, 0x00, 0x00, 0x70, 0xB5, 0x05, 0x00, 0x0C, 0x00, 0x08, 0x00, 0x77, 0xF7, 0xA4, 0xFE, 0x03, 0x00, 0x01, 0x28, -+0x0A, 0xD0, 0x00, 0x20, 0x01, 0x2B, 0x06, 0xD9, 0x16, 0x3B, 0xDB, 0xB2, 0x03, 0x30, 0x98, 0x42, 0x80, 0x41, 0x40, 0x42, -+0x40, 0x00, 0x70, 0xBD, 0x24, 0x0A, 0xA2, 0x00, 0x0F, 0x4B, 0xD6, 0x58, 0x3F, 0x23, 0xF1, 0x5C, 0x68, 0x78, 0xFF, 0xF7, -+0x83, 0xFF, 0x70, 0x85, 0xE4, 0xB2, 0x20, 0x00, 0xFF, 0xF7, 0x5A, 0xFF, 0x9E, 0xF7, 0x5C, 0xFF, 0x71, 0x8D, 0x01, 0x22, -+0x9E, 0xF7, 0x08, 0xFD, 0x31, 0x8C, 0x01, 0x22, 0x9E, 0xF7, 0x04, 0xFD, 0x01, 0x00, 0x33, 0x8C, 0x00, 0x20, 0x8B, 0x42, -+0xE1, 0xD0, 0x20, 0x00, 0xA8, 0xF7, 0xA2, 0xFF, 0x00, 0x20, 0xDC, 0xE7, 0x64, 0xA2, 0x16, 0x00, 0xF0, 0xB5, 0xC6, 0x46, -+0x00, 0xB5, 0x05, 0x00, 0x08, 0x00, 0x0E, 0x0A, 0xB2, 0x00, 0x29, 0x4B, 0xD4, 0x58, 0x77, 0xF7, 0x67, 0xFE, 0x00, 0x28, -+0x03, 0xD0, 0x16, 0x38, 0xC0, 0xB2, 0x03, 0x28, 0x03, 0xD8, 0x00, 0x20, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0x2B, 0x78, -+0x01, 0x27, 0x3B, 0x40, 0x39, 0x22, 0xA3, 0x54, 0x54, 0x23, 0x98, 0x46, 0xA0, 0x44, 0x69, 0x1C, 0x31, 0x3A, 0x40, 0x46, -+0xCE, 0xF7, 0x72, 0xF9, 0x57, 0x22, 0xA3, 0x5C, 0x04, 0x21, 0x8B, 0x43, 0xA3, 0x54, 0x02, 0x32, 0xA3, 0x5C, 0x3E, 0x31, -+0x8B, 0x43, 0xA3, 0x54, 0x29, 0x78, 0x39, 0x40, 0xF0, 0xB2, 0x9F, 0xF7, 0x2D, 0xF9, 0x09, 0x21, 0x40, 0x46, 0x9E, 0xF7, -+0x73, 0xFE, 0x00, 0x28, 0x0D, 0xD1, 0x85, 0xF7, 0x8F, 0xFE, 0x00, 0x28, 0x02, 0xD0, 0x4F, 0x23, 0x01, 0x22, 0xE2, 0x54, -+0xBC, 0x22, 0x52, 0x00, 0xA3, 0x5C, 0x01, 0x21, 0x0B, 0x43, 0xA3, 0x54, 0xCB, 0xE7, 0x3A, 0x21, 0x40, 0x46, 0x9E, 0xF7, -+0x5F, 0xFE, 0x02, 0x00, 0x53, 0x1E, 0x9A, 0x41, 0x4F, 0x23, 0xE2, 0x54, 0x00, 0x23, 0x00, 0x28, 0x04, 0xD0, 0x05, 0x4A, -+0x05, 0x4B, 0xD3, 0x5C, 0x5B, 0x07, 0xDB, 0x0F, 0x4F, 0x22, 0xA3, 0x54, 0xDD, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, -+0x7C, 0x1E, 0x16, 0x00, 0xA2, 0x02, 0x00, 0x00, 0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x06, 0x00, 0x0D, 0x00, 0x0B, 0x0A, -+0x98, 0x46, 0x9A, 0x00, 0x32, 0x4B, 0xD4, 0x58, 0x27, 0x00, 0x54, 0x37, 0x41, 0x1C, 0x08, 0x22, 0x38, 0x00, 0xCE, 0xF7, -+0x23, 0xF9, 0x57, 0x22, 0xA3, 0x5C, 0x04, 0x21, 0x8B, 0x43, 0xA3, 0x54, 0x02, 0x32, 0xA3, 0x5C, 0x3E, 0x31, 0x8B, 0x43, -+0xA3, 0x54, 0x28, 0x00, 0x77, 0xF7, 0xF4, 0xFD, 0x14, 0x28, 0x13, 0xD0, 0x07, 0xD9, 0x16, 0x38, 0xC0, 0xB2, 0x03, 0x28, -+0x05, 0xD8, 0x00, 0x20, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0x00, 0x28, 0xF9, 0xD0, 0x28, 0x00, 0x77, 0xF7, 0xE4, 0xFD, -+0x00, 0x23, 0x00, 0x22, 0x00, 0x21, 0x7D, 0xF7, 0xB1, 0xF8, 0xF0, 0xE7, 0x29, 0x00, 0x1D, 0x48, 0x77, 0xF7, 0xBC, 0xF9, -+0x32, 0x78, 0x01, 0x23, 0x13, 0x40, 0x3A, 0x22, 0xA3, 0x54, 0x09, 0x21, 0x38, 0x00, 0x9E, 0xF7, 0x07, 0xFE, 0x00, 0x28, -+0x11, 0xD1, 0xBC, 0x22, 0x52, 0x00, 0xA3, 0x5C, 0x01, 0x21, 0x0B, 0x43, 0xA3, 0x54, 0x3F, 0x21, 0x38, 0x00, 0x9E, 0xF7, -+0xFB, 0xFD, 0x00, 0x28, 0x19, 0xD0, 0x01, 0x22, 0x41, 0x46, 0x28, 0x00, 0x91, 0xF7, 0xE6, 0xF8, 0xCF, 0xE7, 0x3A, 0x21, -+0x38, 0x00, 0x9E, 0xF7, 0xEF, 0xFD, 0x02, 0x00, 0x53, 0x1E, 0x9A, 0x41, 0x4F, 0x23, 0xE2, 0x54, 0x00, 0x23, 0x00, 0x28, -+0x04, 0xD0, 0x08, 0x4A, 0x08, 0x4B, 0xD3, 0x5C, 0x5B, 0x07, 0xDB, 0x0F, 0x4F, 0x22, 0xA3, 0x54, 0xD9, 0xE7, 0x01, 0x21, -+0x28, 0x00, 0x77, 0xF7, 0x45, 0xFD, 0xB6, 0xE7, 0x64, 0xA2, 0x16, 0x00, 0x05, 0x06, 0x00, 0x00, 0x7C, 0x1E, 0x16, 0x00, -+0xA2, 0x02, 0x00, 0x00, 0xF0, 0xB5, 0xCE, 0x46, 0x47, 0x46, 0x80, 0xB5, 0x83, 0xB0, 0x04, 0x00, 0x0D, 0x00, 0x0E, 0x0A, -+0xB2, 0x00, 0x35, 0x4B, 0xD7, 0x58, 0x02, 0x78, 0x01, 0x23, 0x13, 0x40, 0x39, 0x22, 0xBB, 0x54, 0x36, 0x23, 0xFB, 0x5C, -+0x98, 0x46, 0x33, 0x01, 0x9B, 0x1B, 0x9B, 0x00, 0x2F, 0x4A, 0xD3, 0x18, 0x5B, 0x7B, 0x99, 0x46, 0x08, 0x00, 0x77, 0xF7, -+0x7F, 0xFD, 0x02, 0x00, 0x19, 0x28, 0x1B, 0xD8, 0x01, 0x38, 0xC0, 0xB2, 0x14, 0x28, 0x47, 0xD8, 0x02, 0x20, 0x01, 0x2A, -+0x47, 0xD1, 0x3C, 0x23, 0xFB, 0x5C, 0x00, 0x2B, 0x36, 0xD1, 0x7B, 0x8C, 0x5B, 0x07, 0x33, 0xD5, 0xA3, 0x88, 0x62, 0x88, -+0x61, 0x78, 0x20, 0x89, 0x01, 0x90, 0xE0, 0x88, 0x00, 0x90, 0x21, 0x4C, 0x94, 0x20, 0x24, 0x58, 0x28, 0x00, 0xA0, 0x47, -+0x00, 0x20, 0x32, 0xE0, 0x2E, 0x28, 0x2F, 0xD1, 0x01, 0x23, 0x4A, 0x46, 0x5A, 0x40, 0x13, 0x00, 0x42, 0x46, 0x5A, 0x40, -+0x13, 0x00, 0x39, 0x22, 0xBA, 0x5C, 0xDB, 0xB2, 0x9A, 0x42, 0x0D, 0xD1, 0xA3, 0x88, 0x62, 0x88, 0x61, 0x78, 0x20, 0x89, -+0x01, 0x90, 0xE0, 0x88, 0x00, 0x90, 0x13, 0x4C, 0x94, 0x20, 0x24, 0x58, 0x28, 0x00, 0xA0, 0x47, 0x00, 0x20, 0x16, 0xE0, -+0x22, 0x78, 0x01, 0x23, 0x13, 0x40, 0xF0, 0xB2, 0x23, 0x22, 0x17, 0x21, 0x9E, 0xF7, 0xA9, 0xFE, 0x00, 0x20, 0x0C, 0xE0, -+0x22, 0x78, 0x01, 0x23, 0x13, 0x40, 0xF0, 0xB2, 0x24, 0x22, 0x17, 0x21, 0x9E, 0xF7, 0x9F, 0xFE, 0x00, 0x20, 0x02, 0xE0, -+0x00, 0x20, 0x00, 0xE0, 0x02, 0x20, 0x03, 0xB0, 0x0C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xF0, 0xBD, 0x64, 0xA2, 0x16, 0x00, -+0xC0, 0xA0, 0x16, 0x00, 0x28, 0x19, 0x16, 0x00, 0xF8, 0xB5, 0x04, 0x00, 0x08, 0x00, 0x0D, 0x0A, 0xAA, 0x00, 0x22, 0x4B, -+0xD6, 0x58, 0x77, 0xF7, 0x19, 0xFD, 0x00, 0x28, 0x3B, 0xD0, 0x16, 0x38, 0xC0, 0xB2, 0x03, 0x28, 0x37, 0xD9, 0x22, 0x78, -+0x01, 0x23, 0x13, 0x40, 0x39, 0x22, 0xB3, 0x54, 0x36, 0x23, 0xF3, 0x5C, 0x01, 0x2B, 0x27, 0xD1, 0x23, 0x7A, 0x1B, 0x3A, -+0x01, 0x2B, 0x24, 0xD8, 0x27, 0x00, 0x09, 0x37, 0x38, 0x00, 0x79, 0xF7, 0x93, 0xFA, 0x01, 0x00, 0x13, 0x28, 0x16, 0xD9, -+0x8B, 0x23, 0x9B, 0x00, 0xF0, 0x18, 0x0A, 0x22, 0x39, 0x00, 0xCE, 0xF7, 0x19, 0xF8, 0x22, 0x7A, 0x53, 0x1E, 0x9A, 0x41, -+0xD2, 0xB2, 0xE8, 0xB2, 0x3B, 0x00, 0x61, 0x68, 0xA9, 0xF7, 0x2E, 0xF8, 0x23, 0x7A, 0x5A, 0x1E, 0x93, 0x41, 0x91, 0x22, -+0x92, 0x00, 0xB3, 0x54, 0x0B, 0xE0, 0x08, 0x48, 0x79, 0xF7, 0x12, 0xFA, 0x1E, 0x22, 0x00, 0xE0, 0x24, 0x22, 0x39, 0x23, -+0xF3, 0x5C, 0xE8, 0xB2, 0x3C, 0x21, 0x9E, 0xF7, 0x48, 0xFE, 0x00, 0x20, 0xF8, 0xBD, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, -+0xD8, 0xD4, 0x10, 0x00, 0x70, 0xB5, 0x82, 0xB0, 0x04, 0x00, 0x08, 0x00, 0x0D, 0x0A, 0xAA, 0x00, 0x2B, 0x4B, 0xD6, 0x58, -+0x77, 0xF7, 0xCA, 0xFC, 0x00, 0x28, 0x20, 0xD0, 0x16, 0x38, 0xC0, 0xB2, 0x03, 0x28, 0x1C, 0xD9, 0x22, 0x78, 0x01, 0x23, -+0x13, 0x40, 0x39, 0x22, 0xB3, 0x54, 0x4F, 0x23, 0xF3, 0x5C, 0x00, 0x2B, 0x16, 0xD0, 0xA3, 0x78, 0x01, 0x2B, 0x31, 0xD0, -+0x02, 0x2B, 0x39, 0xD0, 0x00, 0x20, 0x00, 0x2B, 0x22, 0xD0, 0x01, 0xA9, 0x39, 0x23, 0xF2, 0x5C, 0x3B, 0x3B, 0x13, 0x43, -+0x0B, 0x70, 0x20, 0x23, 0x4B, 0x70, 0x88, 0x70, 0xE8, 0xB2, 0x9E, 0xF7, 0xC1, 0xFD, 0x00, 0x20, 0x02, 0xB0, 0x70, 0xBD, -+0x85, 0xF7, 0xF8, 0xFC, 0x00, 0x28, 0x03, 0xD0, 0x4F, 0x23, 0x01, 0x22, 0xF2, 0x54, 0xE0, 0xE7, 0x4F, 0x23, 0xF3, 0x5C, -+0x00, 0x2B, 0xDC, 0xD1, 0x39, 0x23, 0xF3, 0x5C, 0xE8, 0xB2, 0x1A, 0x22, 0x1F, 0x21, 0x9E, 0xF7, 0x0D, 0xFE, 0xE8, 0xE7, -+0xE8, 0xB2, 0xF5, 0xF7, 0x59, 0xF9, 0x43, 0x1E, 0x98, 0x41, 0x43, 0x42, 0x2A, 0x20, 0x18, 0x40, 0x15, 0x30, 0xD2, 0xE7, -+0xE8, 0xB2, 0xF5, 0xF7, 0x79, 0xF9, 0x43, 0x1E, 0x98, 0x41, 0x43, 0x42, 0x15, 0x20, 0x18, 0x40, 0x15, 0x30, 0xC8, 0xE7, -+0xE8, 0xB2, 0x03, 0x4B, 0x1B, 0x69, 0x98, 0x47, 0x2A, 0x20, 0xC2, 0xE7, 0x64, 0xA2, 0x16, 0x00, 0x60, 0x92, 0x16, 0x00, -+0x70, 0xB5, 0x14, 0x00, 0x13, 0x0A, 0x9B, 0x00, 0x11, 0x4A, 0x9D, 0x58, 0x20, 0x00, 0x77, 0xF7, 0x69, 0xFC, 0x03, 0x00, -+0x01, 0x28, 0x0A, 0xD0, 0x00, 0x20, 0x01, 0x2B, 0x06, 0xD9, 0x16, 0x3B, 0xDB, 0xB2, 0x03, 0x30, 0x98, 0x42, 0x80, 0x41, -+0x40, 0x42, 0x40, 0x00, 0x70, 0xBD, 0x36, 0x23, 0xEB, 0x5C, 0x00, 0x20, 0x00, 0x2B, 0xF9, 0xD1, 0x91, 0x23, 0x9B, 0x00, -+0xEB, 0x5C, 0x00, 0x2B, 0xF4, 0xD0, 0x00, 0x21, 0x20, 0x00, 0x8E, 0xF7, 0xDB, 0xFC, 0x00, 0x20, 0xEE, 0xE7, 0xC0, 0x46, -+0x64, 0xA2, 0x16, 0x00, 0xF0, 0xB5, 0x83, 0xB0, 0x00, 0x90, 0x0F, 0x00, 0x16, 0x00, 0x01, 0x93, 0x0B, 0x78, 0xDC, 0x00, -+0xE3, 0x18, 0x32, 0x4C, 0xE4, 0x18, 0x3C, 0x34, 0x23, 0x78, 0x01, 0x2B, 0x02, 0xD0, 0x00, 0x20, 0x03, 0xB0, 0xF0, 0xBD, -+0x4B, 0x78, 0x00, 0x2B, 0x4B, 0xD1, 0x2C, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x4D, 0xD0, 0x2B, 0x4D, 0x2C, 0x00, 0x3F, 0x34, -+0x02, 0xE0, 0x09, 0x35, 0xA5, 0x42, 0x43, 0xD0, 0xAB, 0x79, 0x02, 0x2B, 0xF9, 0xD9, 0x3B, 0x78, 0xD9, 0x00, 0xC9, 0x18, -+0x36, 0x31, 0x23, 0x4B, 0x9C, 0x46, 0x61, 0x44, 0x06, 0x22, 0x28, 0x00, 0xCD, 0xF7, 0x18, 0xFF, 0x00, 0x28, 0xEC, 0xD1, -+0x0C, 0x23, 0x03, 0x22, 0x00, 0x21, 0x1F, 0x48, 0x77, 0xF7, 0x3C, 0xF8, 0x04, 0x00, 0x0B, 0x23, 0x03, 0x70, 0x3B, 0x78, -+0xD9, 0x00, 0xC9, 0x18, 0x36, 0x31, 0x18, 0x4D, 0x49, 0x19, 0x04, 0x30, 0x06, 0x22, 0xCD, 0xF7, 0x27, 0xFF, 0x01, 0x23, -+0x5B, 0x42, 0x63, 0x80, 0x02, 0x33, 0xA3, 0x72, 0x00, 0x26, 0xE6, 0x72, 0x20, 0x00, 0xC8, 0xF7, 0x85, 0xFE, 0x3A, 0x78, -+0xD3, 0x00, 0x9B, 0x18, 0xEB, 0x18, 0x3E, 0x33, 0x18, 0x78, 0x85, 0xF7, 0x0F, 0xFA, 0x3A, 0x78, 0xD3, 0x00, 0x9B, 0x18, -+0xEB, 0x18, 0x3C, 0x33, 0x1E, 0x70, 0x28, 0x68, 0x0C, 0x38, 0x77, 0xF7, 0x62, 0xF8, 0x2E, 0x60, 0xAD, 0xE7, 0x16, 0x2B, -+0xAB, 0xD0, 0x02, 0xE0, 0x7B, 0x78, 0x16, 0x2B, 0xA7, 0xD0, 0x01, 0x9B, 0x32, 0x00, 0x39, 0x00, 0x00, 0x98, 0x04, 0x4C, -+0xA0, 0x47, 0xA0, 0xE7, 0x68, 0x9E, 0x16, 0x00, 0x9E, 0x9E, 0x16, 0x00, 0x03, 0x11, 0x00, 0x00, 0xED, 0x33, 0x09, 0x00, -+0xF0, 0xB5, 0x87, 0xB0, 0x01, 0x90, 0x0D, 0x00, 0x02, 0x92, 0x03, 0x93, 0x0A, 0x78, 0xD3, 0x00, 0x9A, 0x18, 0x29, 0x4B, -+0x9B, 0x18, 0x3C, 0x33, 0x1B, 0x78, 0x02, 0x2B, 0x02, 0xD0, 0x00, 0x20, 0x07, 0xB0, 0xF0, 0xBD, 0x25, 0x4C, 0x27, 0x00, -+0x3F, 0x37, 0x4E, 0x1C, 0x02, 0xE0, 0x09, 0x34, 0xBC, 0x42, 0x39, 0xD0, 0xA3, 0x79, 0x02, 0x2B, 0xF9, 0xD9, 0x06, 0x22, -+0x31, 0x00, 0x20, 0x00, 0xCD, 0xF7, 0xAE, 0xFE, 0x00, 0x28, 0xF2, 0xD1, 0x1B, 0x4A, 0x29, 0x78, 0xCB, 0x00, 0x5B, 0x18, -+0xD3, 0x18, 0x3C, 0x33, 0x00, 0x21, 0x19, 0x70, 0x13, 0x7B, 0x9B, 0x07, 0xDF, 0xD5, 0x18, 0x4B, 0x00, 0x24, 0x1A, 0x78, -+0x00, 0x2A, 0x05, 0xD0, 0x01, 0x34, 0xE4, 0xB2, 0x09, 0x33, 0x07, 0x2C, 0xF7, 0xD1, 0xD4, 0xE7, 0x06, 0x2C, 0xD2, 0xD8, -+0x0F, 0x4B, 0x1A, 0x8B, 0x04, 0xA9, 0x0A, 0x80, 0x5A, 0x8B, 0x4A, 0x80, 0x5B, 0x7F, 0x0B, 0x71, 0x4C, 0x71, 0x0E, 0x4A, -+0xD0, 0x23, 0xD3, 0x58, 0x08, 0x00, 0x98, 0x47, 0x00, 0x28, 0xC2, 0xD1, 0xE3, 0x00, 0x1C, 0x19, 0x06, 0x4B, 0x1C, 0x19, -+0x3C, 0x34, 0x02, 0x22, 0x22, 0x70, 0xBA, 0xE7, 0x03, 0x9B, 0x02, 0x9A, 0x29, 0x00, 0x01, 0x98, 0x05, 0x4C, 0xA0, 0x47, -+0xB3, 0xE7, 0xC0, 0x46, 0x68, 0x9E, 0x16, 0x00, 0x9E, 0x9E, 0x16, 0x00, 0xA4, 0x9E, 0x16, 0x00, 0x28, 0x19, 0x16, 0x00, -+0xDD, 0x32, 0x09, 0x00, 0x00, 0x09, 0x70, 0x47, 0x00, 0x28, 0x14, 0xD0, 0x0E, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x03, 0xD0, -+0x0D, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x06, 0xD1, 0x0C, 0x4B, 0x0A, 0x4A, 0x99, 0x68, 0x11, 0x60, 0xDA, 0x68, 0x09, 0x4B, -+0x1A, 0x60, 0x09, 0x4B, 0x09, 0x4A, 0x9A, 0x60, 0x09, 0x4A, 0xDA, 0x60, 0x70, 0x47, 0x06, 0x4B, 0x03, 0x4A, 0x12, 0x68, -+0x9A, 0x60, 0x03, 0x4A, 0x12, 0x68, 0xDA, 0x60, 0xF6, 0xE7, 0xC0, 0x46, 0xB8, 0xE6, 0x10, 0x00, 0xD4, 0xE6, 0x10, 0x00, -+0x60, 0x92, 0x16, 0x00, 0x2D, 0x01, 0x10, 0x00, 0x81, 0x01, 0x10, 0x00, 0x70, 0xB5, 0x04, 0x00, 0x01, 0x00, 0x2F, 0x48, -+0x79, 0xF7, 0x68, 0xF8, 0x7D, 0xF7, 0xE8, 0xFF, 0x01, 0x28, 0x00, 0xD0, 0x70, 0xBD, 0xFF, 0xF7, 0xC9, 0xFF, 0x2B, 0x4A, -+0x95, 0x23, 0x9B, 0x00, 0xD2, 0x5C, 0x2A, 0x4B, 0x1A, 0x70, 0x2A, 0x4B, 0x1A, 0x68, 0x2A, 0x4B, 0x1A, 0x60, 0xE6, 0x23, -+0x5B, 0x00, 0x1B, 0x68, 0x28, 0x48, 0x98, 0x47, 0x28, 0x4B, 0x18, 0x60, 0x01, 0x2C, 0x27, 0xD0, 0x02, 0x23, 0x22, 0x00, -+0x9A, 0x43, 0x05, 0xD0, 0x25, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x1C, 0x4E, 0x95, 0x25, -+0xAD, 0x00, 0x40, 0x23, 0x73, 0x55, 0x1C, 0x4B, 0x20, 0x4A, 0x1A, 0x60, 0x8C, 0x21, 0xE8, 0x23, 0x5B, 0x00, 0x1B, 0x68, -+0x49, 0x00, 0x1A, 0x48, 0x98, 0x47, 0x73, 0x5D, 0x1C, 0x49, 0x2D, 0x22, 0x8B, 0x54, 0x01, 0x2C, 0x1B, 0xD9, 0x02, 0x2C, -+0xC8, 0xD1, 0x1A, 0x49, 0x0A, 0x88, 0xFF, 0x20, 0x82, 0x43, 0x13, 0x43, 0x0B, 0x80, 0xC1, 0xE7, 0x0D, 0x4D, 0x95, 0x24, -+0xA4, 0x00, 0x30, 0x23, 0x2B, 0x55, 0x0D, 0x4B, 0x11, 0x4A, 0x1A, 0x60, 0x8C, 0x21, 0xE8, 0x23, 0x5B, 0x00, 0x1B, 0x68, -+0x49, 0x00, 0x0B, 0x48, 0x98, 0x47, 0x2B, 0x5D, 0x0D, 0x49, 0x2D, 0x22, 0x8B, 0x54, 0x0E, 0x49, 0x0A, 0x88, 0xFF, 0x20, -+0x82, 0x43, 0x13, 0x43, 0x0B, 0x80, 0xA7, 0xE7, 0xE4, 0xD4, 0x10, 0x00, 0x7C, 0x1E, 0x16, 0x00, 0xF6, 0xE8, 0x10, 0x00, -+0x54, 0x07, 0x62, 0x40, 0x08, 0xE7, 0x10, 0x00, 0x58, 0x00, 0x01, 0x50, 0x18, 0xE7, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, -+0xFD, 0x20, 0x22, 0x21, 0x60, 0x92, 0x16, 0x00, 0x8E, 0x01, 0x61, 0x40, 0x0C, 0x65, 0x61, 0x40, 0x70, 0xB5, 0x04, 0x00, -+0x01, 0x00, 0x1A, 0x48, 0x78, 0xF7, 0xEE, 0xFF, 0x7D, 0xF7, 0x6E, 0xFF, 0x01, 0x28, 0x00, 0xD0, 0x70, 0xBD, 0x00, 0x20, -+0xFF, 0xF7, 0x4E, 0xFF, 0x15, 0x4E, 0x95, 0x25, 0xAD, 0x00, 0x15, 0x4B, 0x1B, 0x78, 0x73, 0x55, 0x14, 0x4B, 0x1A, 0x68, -+0x14, 0x4B, 0x1A, 0x60, 0x14, 0x4B, 0x1B, 0x68, 0x80, 0x21, 0x49, 0x00, 0x19, 0x43, 0xE8, 0x23, 0x5B, 0x00, 0x1B, 0x68, -+0x11, 0x48, 0x98, 0x47, 0x73, 0x5D, 0x11, 0x49, 0x2D, 0x22, 0x8B, 0x54, 0x01, 0x2C, 0x08, 0xD9, 0x02, 0x2C, 0xDF, 0xD1, -+0x0E, 0x49, 0x0A, 0x88, 0xFF, 0x20, 0x82, 0x43, 0x13, 0x43, 0x0B, 0x80, 0xD8, 0xE7, 0x0C, 0x49, 0x0A, 0x88, 0xFF, 0x20, -+0x82, 0x43, 0x13, 0x43, 0x0B, 0x80, 0xD1, 0xE7, 0xF8, 0xD4, 0x10, 0x00, 0x7C, 0x1E, 0x16, 0x00, 0xF6, 0xE8, 0x10, 0x00, -+0x08, 0xE7, 0x10, 0x00, 0x54, 0x07, 0x62, 0x40, 0x18, 0xE7, 0x10, 0x00, 0x58, 0x00, 0x01, 0x50, 0x60, 0x92, 0x16, 0x00, -+0x8E, 0x01, 0x61, 0x40, 0x0C, 0x65, 0x61, 0x40, 0x10, 0xB5, 0x09, 0x28, 0x0B, 0xD9, 0xFF, 0x28, 0x0B, 0xD1, 0x0B, 0x09, -+0x1F, 0x29, 0x0D, 0xD9, 0x02, 0x3B, 0x01, 0x2B, 0x05, 0xD8, 0x01, 0x20, 0xFF, 0xF7, 0xA6, 0xFF, 0x01, 0xE0, 0x00, 0x28, -+0x08, 0xD1, 0x10, 0xBD, 0x00, 0x20, 0xFF, 0xF7, 0x25, 0xFF, 0xFA, 0xE7, 0x00, 0x20, 0xFF, 0xF7, 0x9B, 0xFF, 0xF6, 0xE7, -+0x0B, 0x09, 0x1F, 0x29, 0xF4, 0xD9, 0x02, 0x3B, 0x01, 0x2B, 0xF0, 0xD8, 0x01, 0x20, 0xFF, 0xF7, 0x17, 0xFF, 0xEC, 0xE7, -+0xF8, 0xB5, 0xCE, 0x46, 0x47, 0x46, 0x80, 0xB5, 0x06, 0x00, 0x0D, 0x00, 0x14, 0x00, 0x1F, 0x00, 0x13, 0x0A, 0x9B, 0x00, -+0x11, 0x4A, 0x9B, 0x58, 0x99, 0x46, 0x0A, 0x88, 0x10, 0x4B, 0xD3, 0x5C, 0x98, 0x46, 0x20, 0x00, 0x77, 0xF7, 0x42, 0xFA, -+0x0A, 0x28, 0x0A, 0xD0, 0x3B, 0x00, 0x22, 0x00, 0x29, 0x00, 0x30, 0x00, 0x0B, 0x4C, 0xA0, 0x47, 0x00, 0x20, 0x0C, 0xBC, -+0x90, 0x46, 0x99, 0x46, 0xF8, 0xBD, 0x43, 0x46, 0x5B, 0x08, 0x03, 0x2B, 0xF0, 0xD1, 0x07, 0x4B, 0x4A, 0x46, 0xD1, 0x5C, -+0x06, 0x3B, 0xD0, 0x5C, 0xFF, 0xF7, 0xB0, 0xFF, 0xE8, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, 0x00, 0x00, 0x61, 0x40, -+0x05, 0x87, 0x0A, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x70, 0xB5, 0x82, 0xB0, 0x14, 0x00, 0x15, 0x0A, 0xAA, 0x00, 0x20, 0x4B, -+0xD6, 0x58, 0x20, 0x00, 0x77, 0xF7, 0x16, 0xFA, 0x03, 0x00, 0x01, 0x28, 0x10, 0xD0, 0x00, 0x20, 0x01, 0x2B, 0x05, 0xD9, -+0x19, 0x2B, 0x05, 0xD8, 0x15, 0x22, 0x9A, 0x42, 0x40, 0x41, 0x40, 0x00, 0x02, 0xB0, 0x70, 0xBD, 0x58, 0x3B, 0x18, 0x00, -+0x43, 0x1E, 0x98, 0x41, 0x40, 0x00, 0xF7, 0xE7, 0x4C, 0x23, 0xF3, 0x5C, 0x00, 0x20, 0x00, 0x2B, 0xF2, 0xD1, 0x4B, 0x33, -+0xF3, 0x5C, 0x00, 0x2B, 0x02, 0xD0, 0x4B, 0x23, 0x00, 0x22, 0xF2, 0x54, 0x4F, 0x23, 0xF3, 0x5C, 0x00, 0x20, 0x00, 0x2B, -+0xE6, 0xD0, 0x01, 0xA9, 0x36, 0x23, 0xF2, 0x5C, 0x38, 0x3B, 0x13, 0x43, 0x0B, 0x70, 0x1F, 0x23, 0x4B, 0x70, 0x1D, 0x3B, -+0x8B, 0x70, 0xE8, 0xB2, 0x9E, 0xF7, 0xFE, 0xFA, 0x20, 0x00, 0x8E, 0xF7, 0xF1, 0xFE, 0x58, 0x21, 0x20, 0x00, 0x77, 0xF7, -+0x7D, 0xF9, 0x00, 0x20, 0xD0, 0xE7, 0xC0, 0x46, 0x64, 0xA2, 0x16, 0x00, 0x05, 0x4B, 0x00, 0x20, 0x1A, 0x78, 0x00, 0x2A, -+0x04, 0xD0, 0x01, 0x30, 0xC0, 0xB2, 0x09, 0x33, 0x07, 0x28, 0xF7, 0xD1, 0x70, 0x47, 0xC0, 0x46, 0xA4, 0x9E, 0x16, 0x00, -+0x70, 0xB5, 0x80, 0x00, 0x28, 0x4B, 0xC2, 0x58, 0x28, 0x49, 0xD5, 0x23, 0x5B, 0x00, 0xC9, 0x5C, 0xCB, 0x00, 0x5B, 0x1A, -+0x5B, 0x00, 0x26, 0x49, 0x8C, 0x46, 0x63, 0x44, 0x19, 0x88, 0xC9, 0x0B, 0x0B, 0xD0, 0x19, 0x88, 0x49, 0x04, 0x49, 0x0C, -+0x19, 0x80, 0x20, 0x4C, 0xD5, 0x20, 0x40, 0x00, 0x21, 0x5C, 0x01, 0x31, 0x03, 0x23, 0x0B, 0x40, 0x23, 0x54, 0x9E, 0x23, -+0xD3, 0x5C, 0x5B, 0x00, 0xAE, 0x21, 0x51, 0x5C, 0x5B, 0x18, 0xDB, 0xB2, 0x99, 0x00, 0xCB, 0x18, 0x5B, 0x00, 0x19, 0x49, -+0x5C, 0x18, 0x21, 0x88, 0x89, 0xB2, 0x00, 0x29, 0x19, 0xD1, 0x9C, 0x31, 0x50, 0x5C, 0x00, 0x28, 0x01, 0xD1, 0x01, 0x31, -+0x50, 0x5C, 0x14, 0x49, 0x5D, 0x18, 0x29, 0x88, 0x78, 0x26, 0xB1, 0x43, 0xC0, 0x00, 0x01, 0x43, 0x29, 0x80, 0x96, 0x21, -+0x51, 0x5A, 0xC9, 0x00, 0x06, 0x20, 0x01, 0x43, 0x89, 0xB2, 0x0E, 0x48, 0x18, 0x18, 0x01, 0x80, 0x94, 0x21, 0x51, 0x5A, -+0x21, 0x80, 0x0C, 0x49, 0x8C, 0x46, 0x63, 0x44, 0x19, 0x88, 0x49, 0x04, 0x49, 0x0C, 0x19, 0x80, 0xAE, 0x21, 0x53, 0x5C, -+0x58, 0x42, 0x43, 0x41, 0x53, 0x54, 0x70, 0xBD, 0x38, 0xE6, 0x10, 0x00, 0x20, 0xA3, 0x16, 0x00, 0x90, 0x69, 0x61, 0x40, -+0xCE, 0x69, 0x61, 0x40, 0xCA, 0x69, 0x61, 0x40, 0xCC, 0x69, 0x61, 0x40, 0xC8, 0x69, 0x61, 0x40, 0x70, 0xB5, 0x35, 0x4B, -+0x1C, 0x68, 0x00, 0x2C, 0x14, 0xD0, 0xE3, 0x78, 0x9B, 0x00, 0x33, 0x4A, 0x9D, 0x58, 0xA0, 0x23, 0xEB, 0x5C, 0x02, 0x2B, -+0x0E, 0xD0, 0x31, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0x05, 0xD0, 0x30, 0x4A, 0x11, 0x68, 0x80, 0x23, 0xDB, 0x03, 0x0B, 0x43, -+0x13, 0x60, 0xA0, 0x23, 0x02, 0x22, 0xEA, 0x54, 0x00, 0x20, 0x70, 0xBD, 0x94, 0x23, 0xE8, 0x5A, 0x00, 0x28, 0x07, 0xD0, -+0x63, 0x78, 0x00, 0x2B, 0x42, 0xD0, 0x01, 0x2B, 0x43, 0xD0, 0x94, 0x23, 0x00, 0x22, 0xEA, 0x52, 0xE2, 0x78, 0x62, 0x23, -+0x53, 0x43, 0x24, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x18, 0x88, 0x40, 0x05, 0x40, 0x0F, 0x84, 0xF7, 0x51, 0xFF, 0x1D, 0x4D, -+0xE3, 0x78, 0x9B, 0x00, 0x58, 0x59, 0x76, 0xF7, 0xCF, 0xFE, 0xE3, 0x78, 0x9B, 0x00, 0x00, 0x24, 0x5C, 0x51, 0x1C, 0x48, -+0xCB, 0xF7, 0x56, 0xFD, 0x1B, 0x48, 0x78, 0xF7, 0x53, 0xFE, 0x14, 0x4D, 0x2B, 0x68, 0xD8, 0x68, 0x76, 0xF7, 0xC0, 0xFE, -+0x2B, 0x68, 0xDC, 0x60, 0x98, 0x68, 0x00, 0x28, 0x05, 0xD0, 0x76, 0xF7, 0xB9, 0xFE, 0x0E, 0x4B, 0x1B, 0x68, 0x00, 0x22, -+0x9A, 0x60, 0x0C, 0x4C, 0x20, 0x68, 0x76, 0xF7, 0xB1, 0xFE, 0x00, 0x23, 0x23, 0x60, 0x0B, 0x4B, 0x1B, 0x78, 0x00, 0x2B, -+0xBC, 0xD0, 0x0E, 0x4A, 0x13, 0x68, 0x0E, 0x49, 0x0B, 0x40, 0x13, 0x60, 0x06, 0x4B, 0x00, 0x22, 0x1A, 0x70, 0xB3, 0xE7, -+0x80, 0xF7, 0x4A, 0xFE, 0xBB, 0xE7, 0x80, 0xF7, 0xFD, 0xFD, 0xB8, 0xE7, 0xD8, 0xE5, 0x10, 0x00, 0x38, 0xE6, 0x10, 0x00, -+0xDC, 0xE5, 0x10, 0x00, 0x00, 0x04, 0x60, 0x40, 0xFE, 0x64, 0x61, 0x40, 0xFC, 0xE6, 0x10, 0x00, 0x0C, 0xD5, 0x10, 0x00, -+0xD0, 0x04, 0x60, 0x40, 0xFF, 0x7F, 0xFF, 0xFF, 0x70, 0xB5, 0x13, 0x4B, 0x1C, 0x68, 0xA5, 0x78, 0x00, 0x2D, 0x1D, 0xD1, -+0x23, 0x78, 0x03, 0x2B, 0x1C, 0xD0, 0x63, 0x78, 0x00, 0x2B, 0x08, 0xD0, 0x01, 0x2B, 0x0F, 0xD0, 0x0D, 0x4B, 0x9B, 0x6E, -+0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x04, 0xE0, 0x0E, 0x22, 0x01, 0x00, 0xE0, 0x68, 0xCD, 0xF7, 0xF2, 0xFB, -+0x01, 0x23, 0xA3, 0x70, 0x28, 0x00, 0x70, 0xBD, 0x0E, 0x22, 0x01, 0x00, 0xE0, 0x68, 0xCD, 0xF7, 0xE9, 0xFB, 0xF5, 0xE7, -+0x0C, 0x25, 0xF5, 0xE7, 0x0C, 0x25, 0xF3, 0xE7, 0xD8, 0xE5, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, 0xF0, 0xB5, 0xDE, 0x46, -+0x57, 0x46, 0x4E, 0x46, 0x45, 0x46, 0xE0, 0xB5, 0x8B, 0xB0, 0x05, 0x00, 0x0E, 0x00, 0x14, 0x00, 0x01, 0x93, 0x00, 0x23, -+0x08, 0x93, 0x09, 0x93, 0x06, 0x93, 0x06, 0xAA, 0x93, 0x80, 0x82, 0x00, 0xBB, 0x4B, 0xD3, 0x58, 0x00, 0x2B, 0x00, 0xD1, -+0x10, 0xE1, 0xAB, 0x00, 0xB8, 0x4A, 0x9F, 0x58, 0x21, 0x00, 0xB8, 0x48, 0x78, 0xF7, 0xCE, 0xFD, 0x00, 0x2C, 0x00, 0xD1, -+0x0D, 0xE1, 0x01, 0x2C, 0x00, 0xD1, 0x6D, 0xE2, 0xB4, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, -+0x00, 0x23, 0x00, 0x93, 0x98, 0x46, 0x99, 0x46, 0x02, 0x93, 0x00, 0x21, 0x00, 0x26, 0x01, 0x9B, 0x00, 0x2B, 0x63, 0xD0, -+0x62, 0x23, 0x6B, 0x43, 0xAC, 0x4A, 0x98, 0x18, 0x02, 0x88, 0x1F, 0x24, 0xA2, 0x43, 0x32, 0x43, 0x02, 0x80, 0xAA, 0x4A, -+0x9A, 0x18, 0x10, 0x88, 0xA9, 0x4E, 0x06, 0x40, 0x80, 0x20, 0x40, 0x00, 0x30, 0x43, 0x10, 0x80, 0x10, 0x88, 0x40, 0x04, -+0x40, 0x0C, 0x10, 0x80, 0x10, 0x88, 0xA5, 0x4E, 0x30, 0x40, 0x10, 0x80, 0xA4, 0x4A, 0x94, 0x46, 0x9C, 0x44, 0x62, 0x46, -+0x16, 0x88, 0xFF, 0x20, 0x86, 0x43, 0xA2, 0x4A, 0x93, 0x46, 0x2D, 0x22, 0x5C, 0x46, 0xA2, 0x5C, 0x32, 0x43, 0x64, 0x46, -+0x22, 0x80, 0x9F, 0x4A, 0x9E, 0x18, 0x00, 0x22, 0x94, 0x46, 0x32, 0x80, 0x9D, 0x4A, 0x93, 0x46, 0x9B, 0x44, 0x5A, 0x46, -+0x12, 0x88, 0x52, 0x04, 0x52, 0x0C, 0x5C, 0x46, 0x22, 0x80, 0x9A, 0x4A, 0x9A, 0x18, 0x11, 0x80, 0x99, 0x4A, 0x9A, 0x18, -+0x61, 0x46, 0x11, 0x80, 0x98, 0x4A, 0x9A, 0x18, 0x11, 0x80, 0x98, 0x4A, 0x99, 0x18, 0x02, 0x22, 0xFF, 0x32, 0x0A, 0x80, -+0x32, 0x88, 0x40, 0x24, 0xA2, 0x43, 0x22, 0x43, 0x32, 0x80, 0x0A, 0x88, 0x82, 0x43, 0xFE, 0x38, 0x02, 0x43, 0x0A, 0x80, -+0x9E, 0x22, 0xBA, 0x5C, 0x14, 0x21, 0x4A, 0x43, 0x8F, 0x49, 0x8C, 0x46, 0x62, 0x44, 0x92, 0xB2, 0x8E, 0x49, 0x59, 0x18, -+0x0A, 0x80, 0x8E, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1A, 0x88, 0x3F, 0x21, 0x0A, 0x40, 0x8C, 0x49, 0x0A, 0x43, 0x1A, 0x80, -+0x08, 0xAE, 0x31, 0x00, 0x06, 0xA8, 0xAF, 0xF7, 0x9D, 0xF9, 0x06, 0xAB, 0x5A, 0x78, 0x12, 0x02, 0x1B, 0x78, 0x13, 0x43, -+0x62, 0x27, 0x6F, 0x43, 0x85, 0x4A, 0xBA, 0x18, 0x13, 0x80, 0x06, 0xAB, 0xDA, 0x78, 0x12, 0x02, 0x9B, 0x78, 0x13, 0x43, -+0x82, 0x4A, 0xBA, 0x18, 0x13, 0x80, 0x06, 0xAB, 0x5A, 0x79, 0x12, 0x02, 0x1B, 0x79, 0x13, 0x43, 0x7F, 0x4A, 0xBA, 0x18, -+0x13, 0x80, 0x72, 0x78, 0x12, 0x02, 0x33, 0x78, 0x13, 0x43, 0x7D, 0x4A, 0xBA, 0x18, 0x13, 0x80, 0xF2, 0x78, 0x12, 0x02, -+0xB3, 0x78, 0x13, 0x43, 0x7A, 0x4A, 0xBA, 0x18, 0x13, 0x80, 0x00, 0x22, 0x06, 0x2D, 0x01, 0xD8, 0x6A, 0x1C, 0xD2, 0xB2, -+0x08, 0xAB, 0x19, 0x79, 0x03, 0x23, 0x0B, 0x40, 0x92, 0x00, 0x13, 0x43, 0x6E, 0x4A, 0x13, 0x43, 0x6C, 0x4A, 0xBA, 0x18, -+0x13, 0x80, 0x72, 0x48, 0x03, 0x68, 0x72, 0x49, 0x0B, 0x40, 0x80, 0x22, 0x52, 0x01, 0x1A, 0x43, 0x02, 0x60, 0x5A, 0x4B, -+0xFE, 0x18, 0x33, 0x88, 0x02, 0x9A, 0x14, 0x03, 0x24, 0xB2, 0x0B, 0x40, 0x23, 0x43, 0x9B, 0xB2, 0x33, 0x80, 0x4B, 0x46, -+0x00, 0x2B, 0x00, 0xD1, 0xDE, 0xE1, 0x56, 0x4B, 0xFA, 0x18, 0x13, 0x88, 0x5B, 0x04, 0x5B, 0x0C, 0x80, 0x21, 0x09, 0x02, -+0x0B, 0x43, 0x13, 0x80, 0x33, 0x88, 0x64, 0x4A, 0x13, 0x40, 0x00, 0x9A, 0xD2, 0x02, 0x13, 0x43, 0x9B, 0xB2, 0x33, 0x80, -+0x61, 0x49, 0x0B, 0x68, 0x61, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0x1B, 0x02, 0x13, 0x43, 0x0B, 0x60, 0x4C, 0x4B, 0xFB, 0x18, -+0x00, 0x22, 0x1A, 0x80, 0x49, 0x4B, 0xFB, 0x18, 0x1A, 0x88, 0x08, 0x21, 0x8A, 0x43, 0x1A, 0x80, 0x30, 0x88, 0x31, 0x88, -+0x33, 0x88, 0x80, 0x0B, 0x01, 0x22, 0x10, 0x40, 0x80, 0x03, 0xC9, 0x0A, 0x0A, 0x40, 0xD2, 0x02, 0x10, 0x43, 0x05, 0x43, -+0x58, 0x05, 0x40, 0x0F, 0x00, 0x02, 0x05, 0x43, 0x25, 0x43, 0xAD, 0xB2, 0x35, 0x80, 0x0B, 0xB0, 0x3C, 0xBC, 0x90, 0x46, -+0x99, 0x46, 0xA2, 0x46, 0xAB, 0x46, 0xF0, 0xBD, 0x32, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, -+0xE7, 0xE6, 0xB3, 0x78, 0x99, 0x46, 0xF3, 0x78, 0x98, 0x46, 0x33, 0x79, 0x00, 0x93, 0x72, 0x79, 0x02, 0x92, 0x00, 0x2B, -+0x10, 0xD1, 0x9D, 0x23, 0x00, 0x22, 0xFA, 0x54, 0x32, 0x78, 0x01, 0x3B, 0xFA, 0x54, 0xF2, 0x88, 0x96, 0x23, 0xFA, 0x52, -+0x73, 0x78, 0x07, 0x2B, 0x00, 0xD9, 0x3D, 0xE1, 0x9B, 0x00, 0x3E, 0x49, 0xCB, 0x58, 0x9F, 0x46, 0x31, 0x78, 0x9D, 0x23, -+0xF9, 0x54, 0x3C, 0x48, 0x78, 0xF7, 0x9C, 0xFC, 0x9C, 0x23, 0x00, 0x22, 0xFA, 0x54, 0xEA, 0xE7, 0x39, 0x4B, 0x1A, 0x68, -+0x39, 0x49, 0x0A, 0x40, 0x1A, 0x60, 0x1A, 0x68, 0x30, 0x49, 0x11, 0x40, 0x80, 0x22, 0x52, 0x01, 0x0A, 0x43, 0x1A, 0x60, -+0x35, 0x4B, 0x1B, 0x78, 0x00, 0x2B, 0x76, 0xD0, 0x31, 0x49, 0x0B, 0x68, 0x2D, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0x1B, 0x02, -+0x13, 0x43, 0x0B, 0x60, 0x6D, 0xE0, 0x2D, 0x4B, 0x1A, 0x68, 0x2D, 0x49, 0x11, 0x40, 0x80, 0x22, 0x92, 0x01, 0x0A, 0x43, -+0x1A, 0x60, 0x1A, 0x68, 0x22, 0x49, 0x11, 0x40, 0x80, 0x22, 0x52, 0x01, 0x0A, 0x43, 0x1A, 0x60, 0x27, 0x4B, 0x1B, 0x78, -+0x00, 0x2B, 0x5A, 0xD0, 0x23, 0x49, 0x0B, 0x68, 0x1F, 0x4A, 0x1A, 0x40, 0x80, 0x23, 0x1B, 0x02, 0x13, 0x43, 0x0B, 0x60, -+0x51, 0xE0, 0xC0, 0x46, 0x38, 0xE6, 0x10, 0x00, 0x18, 0xD5, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, 0xF8, 0x64, 0x61, 0x40, -+0xFE, 0x64, 0x61, 0x40, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0x0C, 0x65, 0x61, 0x40, 0x60, 0x92, 0x16, 0x00, -+0x0E, 0x65, 0x61, 0x40, 0x56, 0x65, 0x61, 0x40, 0x10, 0x65, 0x61, 0x40, 0xFA, 0x64, 0x61, 0x40, 0xFC, 0x64, 0x61, 0x40, -+0x1E, 0x65, 0x61, 0x40, 0xC8, 0x69, 0x00, 0x00, 0x12, 0x65, 0x61, 0x40, 0x0A, 0x65, 0x61, 0x40, 0x40, 0xFF, 0x00, 0x00, -+0x00, 0x65, 0x61, 0x40, 0x02, 0x65, 0x61, 0x40, 0x04, 0x65, 0x61, 0x40, 0x06, 0x65, 0x61, 0x40, 0x08, 0x65, 0x61, 0x40, -+0x00, 0x04, 0x60, 0x40, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x28, 0x04, 0x60, 0x40, 0xFF, 0x7F, 0xFF, 0xFF, -+0x48, 0xD5, 0x10, 0x00, 0x30, 0xD5, 0x10, 0x00, 0xD0, 0x04, 0x60, 0x40, 0xFF, 0xDF, 0xFF, 0xFF, 0xDC, 0xE5, 0x10, 0x00, -+0x94, 0x23, 0xF8, 0x5A, 0x8E, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0xF0, 0x21, 0x74, 0xF7, 0x96, 0xFB, 0x8C, 0x4A, 0x13, 0x68, -+0x8C, 0x49, 0x0B, 0x40, 0x13, 0x60, 0x9E, 0x23, 0xFA, 0x5C, 0x52, 0x00, 0x10, 0x33, 0xFB, 0x5C, 0xD2, 0x18, 0xD2, 0xB2, -+0x62, 0x23, 0x6B, 0x43, 0x87, 0x49, 0x8C, 0x46, 0x63, 0x44, 0x03, 0x93, 0x02, 0x20, 0x07, 0x23, 0x9A, 0x46, 0x04, 0x95, -+0x05, 0x96, 0x91, 0x00, 0x89, 0x18, 0x49, 0x00, 0x82, 0x4B, 0xCC, 0x18, 0x23, 0x88, 0x78, 0x25, 0xAB, 0x43, 0x70, 0x3D, -+0x2B, 0x43, 0x9B, 0xB2, 0x23, 0x80, 0x03, 0x9B, 0x1B, 0x88, 0x25, 0x88, 0xAB, 0x46, 0x1B, 0x0A, 0x55, 0x46, 0x2B, 0x40, -+0x5D, 0x46, 0x56, 0x46, 0xB5, 0x43, 0x2B, 0x43, 0x23, 0x80, 0x79, 0x4B, 0x9C, 0x46, 0x8C, 0x44, 0x63, 0x46, 0x1B, 0x88, -+0x77, 0x4C, 0x23, 0x40, 0x64, 0x46, 0x23, 0x80, 0x76, 0x4B, 0xCB, 0x18, 0x00, 0x24, 0x1C, 0x80, 0x75, 0x4B, 0x9C, 0x46, -+0x61, 0x44, 0x9E, 0x23, 0xFB, 0x5C, 0x5B, 0x00, 0x01, 0x34, 0x54, 0x40, 0xE4, 0xB2, 0xA4, 0x46, 0x63, 0x44, 0x9C, 0x00, -+0xA4, 0x46, 0x63, 0x44, 0x5B, 0x00, 0x6F, 0x4C, 0xA4, 0x46, 0x63, 0x44, 0x6E, 0x4C, 0x23, 0x43, 0x9B, 0xB2, 0x0B, 0x80, -+0x0B, 0x88, 0x5B, 0x04, 0x5B, 0x0C, 0x0B, 0x80, 0x53, 0x42, 0x5A, 0x41, 0xD2, 0xB2, 0x01, 0x38, 0xC0, 0xB2, 0x00, 0x28, -+0xB9, 0xD1, 0x04, 0x9D, 0x05, 0x9E, 0x31, 0x00, 0x08, 0x31, 0x06, 0x22, 0x06, 0xA8, 0xCD, 0xF7, 0xA5, 0xF9, 0x00, 0x21, -+0x02, 0x26, 0xF2, 0xE5, 0x94, 0x23, 0xF8, 0x5A, 0x56, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0xAA, 0x21, 0x74, 0xF7, 0x26, 0xFB, -+0x54, 0x4A, 0x13, 0x68, 0x54, 0x49, 0x0B, 0x40, 0x13, 0x60, 0x8E, 0xE7, 0x94, 0x23, 0xF8, 0x5A, 0x4F, 0x4B, 0x9C, 0x46, -+0x60, 0x44, 0xFF, 0x21, 0x74, 0xF7, 0x18, 0xFB, 0x4D, 0x4A, 0x13, 0x68, 0x4D, 0x49, 0x0B, 0x40, 0x13, 0x60, 0x80, 0xE7, -+0x94, 0x23, 0xF8, 0x5A, 0x48, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0x00, 0x21, 0x74, 0xF7, 0x0A, 0xFB, 0x46, 0x4A, 0x13, 0x68, -+0x46, 0x49, 0x0B, 0x40, 0x13, 0x60, 0x72, 0xE7, 0x94, 0x23, 0xF8, 0x5A, 0x41, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0x0F, 0x21, -+0x74, 0xF7, 0xFC, 0xFA, 0x3F, 0x4A, 0x13, 0x68, 0x3F, 0x49, 0x0B, 0x40, 0x13, 0x60, 0x64, 0xE7, 0x94, 0x23, 0xF8, 0x5A, -+0x3A, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0x55, 0x21, 0x74, 0xF7, 0xEE, 0xFA, 0x38, 0x4A, 0x13, 0x68, 0x38, 0x49, 0x0B, 0x40, -+0x13, 0x60, 0x56, 0xE7, 0x94, 0x23, 0xF8, 0x5A, 0x33, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0x00, 0x21, 0x74, 0xF7, 0xE0, 0xFA, -+0x31, 0x4A, 0x13, 0x68, 0x31, 0x49, 0x0B, 0x40, 0x13, 0x60, 0x48, 0xE7, 0xB3, 0x78, 0x98, 0x46, 0xF3, 0x78, 0x00, 0x93, -+0xB4, 0x79, 0xF1, 0x1D, 0x06, 0x22, 0x06, 0xA8, 0xCD, 0xF7, 0x44, 0xF9, 0x00, 0x22, 0x33, 0x4B, 0x99, 0x46, 0xD5, 0x23, -+0x5B, 0x00, 0x9C, 0x46, 0x03, 0x26, 0x17, 0x3B, 0xFF, 0x3B, 0x9B, 0x46, 0x0A, 0xE0, 0x2F, 0x49, 0x8A, 0x46, 0x53, 0x44, -+0x19, 0x88, 0x49, 0x04, 0x49, 0x0C, 0x19, 0x80, 0x01, 0x32, 0xD2, 0xB2, 0x04, 0x2A, 0x11, 0xD0, 0x4B, 0x46, 0x61, 0x46, -+0x5B, 0x5C, 0xD3, 0x18, 0x33, 0x40, 0xD9, 0x00, 0xCB, 0x1A, 0x5B, 0x00, 0x26, 0x49, 0x58, 0x18, 0x01, 0x88, 0x89, 0xB2, -+0x00, 0x29, 0xE6, 0xD1, 0x59, 0x46, 0x79, 0x5A, 0x01, 0x80, 0xE2, 0xE7, 0x02, 0x94, 0x00, 0x23, 0x99, 0x46, 0x21, 0x49, -+0x03, 0x26, 0x66, 0xE5, 0x20, 0x4B, 0xFA, 0x18, 0x13, 0x88, 0x5B, 0x04, 0x5B, 0x0C, 0x13, 0x80, 0x43, 0x46, 0xDB, 0x07, -+0x0F, 0xD4, 0x11, 0x88, 0x43, 0x46, 0x5B, 0x08, 0x1B, 0x02, 0x1B, 0x48, 0x01, 0x40, 0x0B, 0x43, 0x13, 0x80, 0x43, 0x46, -+0x5B, 0x08, 0x28, 0x33, 0x19, 0x00, 0x18, 0x48, 0x78, 0xF7, 0x0A, 0xFB, 0x10, 0xE6, 0x10, 0x88, 0x43, 0x46, 0x5B, 0x08, -+0x28, 0x33, 0x1B, 0x02, 0x12, 0x49, 0x01, 0x40, 0x0B, 0x43, 0x9B, 0xB2, 0x13, 0x80, 0xEC, 0xE7, 0x00, 0x00, 0x61, 0x40, -+0xD0, 0x04, 0x60, 0x40, 0xFF, 0xEF, 0xFF, 0xFF, 0xFE, 0x64, 0x61, 0x40, 0xCA, 0x69, 0x61, 0x40, 0xCC, 0x69, 0x61, 0x40, -+0x07, 0xE0, 0xFF, 0xFF, 0xCE, 0x69, 0x61, 0x40, 0xC8, 0x69, 0x61, 0x40, 0xC8, 0x69, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, -+0x20, 0xA3, 0x16, 0x00, 0x90, 0x69, 0x61, 0x40, 0x9A, 0x69, 0x61, 0x40, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x65, 0x61, 0x40, -+0xFF, 0x80, 0xFF, 0xFF, 0x3C, 0xD5, 0x10, 0x00, 0x10, 0xB5, 0x07, 0x4B, 0x1C, 0x68, 0xA3, 0x78, 0x00, 0x2B, 0x00, 0xD1, -+0x10, 0xBD, 0x00, 0x23, 0x0A, 0x00, 0xE1, 0x68, 0xFF, 0xF7, 0xE2, 0xFC, 0x00, 0x23, 0xA3, 0x70, 0xF6, 0xE7, 0xC0, 0x46, -+0xD8, 0xE5, 0x10, 0x00, 0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x05, 0x00, 0x82, 0x00, 0x52, 0x4B, 0xD4, 0x58, 0x00, 0x2C, -+0x00, 0xD1, 0x98, 0xE0, 0xA9, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x05, 0xD1, 0x4E, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, -+0x00, 0x20, 0x98, 0x47, 0xA9, 0x22, 0xA3, 0x5C, 0x01, 0x3B, 0xDB, 0xB2, 0xA3, 0x54, 0x09, 0x3A, 0xA2, 0x5C, 0x02, 0x3A, -+0x01, 0x2A, 0x01, 0xD8, 0x00, 0x2B, 0x14, 0xD0, 0x9F, 0xF7, 0xD2, 0xFD, 0x06, 0x00, 0x01, 0x00, 0x28, 0x00, 0xFF, 0xF7, -+0xA9, 0xFB, 0xA9, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x00, 0xD1, 0x68, 0xE0, 0x3F, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, -+0x00, 0x20, 0x98, 0x47, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0x01, 0x21, 0x20, 0x00, 0xCA, 0xF7, 0xEF, 0xFD, 0xA0, 0x23, -+0x02, 0x22, 0xE2, 0x54, 0xFF, 0xF7, 0xF4, 0xFB, 0x37, 0x4A, 0xD5, 0x23, 0x5B, 0x00, 0xD2, 0x5C, 0xD3, 0x00, 0x9B, 0x1A, -+0x5B, 0x00, 0x35, 0x4A, 0x9A, 0x18, 0x12, 0x88, 0xD2, 0x0B, 0xE7, 0xD0, 0x33, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1A, 0x88, -+0xD2, 0x0A, 0xAA, 0x42, 0x07, 0xD0, 0x19, 0x88, 0xC9, 0x0A, 0x2C, 0x4B, 0xDC, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x28, 0x00, -+0xA0, 0x47, 0x2A, 0x4C, 0xD5, 0x20, 0x40, 0x00, 0x22, 0x5C, 0xD3, 0x00, 0x9B, 0x1A, 0x5B, 0x00, 0x27, 0x4A, 0x94, 0x46, -+0x63, 0x44, 0x1A, 0x88, 0x52, 0x04, 0x52, 0x0C, 0x1A, 0x80, 0x21, 0x5C, 0x01, 0x31, 0x03, 0x23, 0x19, 0x40, 0x21, 0x54, -+0x23, 0x4B, 0x1A, 0x68, 0xCB, 0x00, 0x5B, 0x1A, 0x5B, 0x00, 0x22, 0x49, 0x8C, 0x46, 0x63, 0x44, 0x52, 0x04, 0x52, 0x0C, -+0x93, 0x42, 0x05, 0xD0, 0x19, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x18, 0x4E, 0x00, 0x24, -+0xD5, 0x23, 0x5B, 0x00, 0x98, 0x46, 0x14, 0x4F, 0x03, 0xE0, 0x01, 0x34, 0x0E, 0x36, 0x04, 0x2C, 0xA8, 0xD0, 0x33, 0x88, -+0xDB, 0x0B, 0xF8, 0xD0, 0x10, 0x4B, 0x42, 0x46, 0x98, 0x5C, 0x00, 0x23, 0x00, 0x22, 0x21, 0x00, 0xFD, 0x6E, 0xA8, 0x47, -+0xEF, 0xE7, 0x01, 0x21, 0x20, 0x00, 0xCA, 0xF7, 0x8F, 0xFD, 0x02, 0x36, 0x66, 0x60, 0x00, 0x21, 0x28, 0x00, 0xFF, 0xF7, -+0x4F, 0xFF, 0x20, 0x00, 0xF4, 0xF7, 0xA6, 0xFA, 0x8E, 0xE7, 0x04, 0x4B, 0xDC, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x00, 0x21, -+0xA0, 0x47, 0x87, 0xE7, 0x38, 0xE6, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, 0x20, 0xA3, 0x16, 0x00, 0x90, 0x69, 0x61, 0x40, -+0x92, 0x69, 0x61, 0x40, 0x2C, 0x04, 0x60, 0x40, 0x90, 0x69, 0x00, 0x00, 0xF0, 0xB5, 0x83, 0xB0, 0x01, 0x90, 0x0D, 0x00, -+0x14, 0x00, 0xCF, 0xB2, 0x06, 0x2F, 0x07, 0xD9, 0xFF, 0x20, 0x08, 0x40, 0x0B, 0x4B, 0xDE, 0x6E, 0x00, 0x23, 0x00, 0x22, -+0x21, 0x00, 0xB0, 0x47, 0x00, 0x2C, 0x09, 0xD0, 0xFF, 0x20, 0x28, 0x40, 0x06, 0x4B, 0xDD, 0x6E, 0x00, 0x23, 0x00, 0x22, -+0x21, 0x00, 0xA8, 0x47, 0x03, 0xB0, 0xF0, 0xBD, 0x01, 0x99, 0x38, 0x00, 0xFF, 0xF7, 0x28, 0xFF, 0xF8, 0xE7, 0xC0, 0x46, -+0x28, 0x19, 0x16, 0x00, 0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x96, 0xB0, 0x2F, 0x4B, 0x1B, 0x68, 0xD9, 0x68, 0xEF, 0xF3, -+0x10, 0x83, 0xDB, 0x07, 0x51, 0xD4, 0x72, 0xB6, 0x10, 0x31, 0x24, 0x22, 0x0D, 0xA8, 0xCC, 0xF7, 0xCF, 0xFF, 0x62, 0xB6, -+0x0D, 0x9C, 0x00, 0x26, 0x00, 0x2C, 0x07, 0xD0, 0x0E, 0x9B, 0xE3, 0x1A, 0x64, 0x20, 0x58, 0x43, 0x21, 0x00, 0xCC, 0xF7, -+0x75, 0xFB, 0x06, 0x00, 0x13, 0x9D, 0x00, 0x20, 0x00, 0x2D, 0x05, 0xD0, 0x21, 0x48, 0x14, 0x9B, 0x58, 0x43, 0x29, 0x00, -+0xCC, 0xF7, 0x6A, 0xFB, 0x11, 0x9A, 0x12, 0x9F, 0x15, 0x99, 0x13, 0x00, 0x3B, 0x43, 0x0B, 0x43, 0x1B, 0xD0, 0x0F, 0x9B, -+0x98, 0x46, 0x0E, 0x9B, 0x9C, 0x46, 0x00, 0x23, 0x09, 0x93, 0x08, 0x90, 0x07, 0x93, 0x06, 0x96, 0x14, 0x9B, 0x0B, 0x93, -+0x05, 0x93, 0x04, 0x95, 0x03, 0x91, 0x02, 0x97, 0x01, 0x92, 0x10, 0x9B, 0x00, 0x93, 0x43, 0x46, 0x22, 0x00, 0x61, 0x46, -+0x11, 0x48, 0x78, 0xF7, 0xA5, 0xF9, 0x16, 0xB0, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0x0F, 0x9B, 0x0E, 0x99, 0x00, 0x22, -+0x06, 0x92, 0x05, 0x90, 0x04, 0x92, 0x03, 0x96, 0x14, 0x9A, 0x0B, 0x92, 0x02, 0x92, 0x01, 0x95, 0x10, 0x9A, 0x00, 0x92, -+0x22, 0x00, 0x08, 0x48, 0x78, 0xF7, 0x90, 0xF9, 0xE9, 0xE7, 0x10, 0x31, 0x24, 0x22, 0x0D, 0xA8, 0xCC, 0xF7, 0x7E, 0xFF, -+0xAE, 0xE7, 0xC0, 0x46, 0xD8, 0xE5, 0x10, 0x00, 0x10, 0x27, 0x00, 0x00, 0x68, 0xD5, 0x10, 0x00, 0xC8, 0xD5, 0x10, 0x00, -+0x70, 0x47, 0x00, 0x00, 0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x05, 0x00, 0x0F, 0x00, 0x16, 0x00, 0x1C, 0x00, 0x4B, 0x4B, -+0x1B, 0x68, 0x00, 0x2B, 0x05, 0xD0, 0x4A, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x00, 0x21, -+0x10, 0x20, 0x76, 0xF7, 0x37, 0xF9, 0x44, 0x4B, 0x18, 0x60, 0x00, 0x28, 0x10, 0xD0, 0x42, 0x4B, 0x18, 0x68, 0x10, 0x22, -+0x00, 0x21, 0x74, 0xF7, 0xDF, 0xF8, 0x00, 0x2D, 0x0E, 0xD0, 0x01, 0x2D, 0x2C, 0xD0, 0x3E, 0x4B, 0x9B, 0x6E, 0x00, 0x22, -+0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x1B, 0xE0, 0x3A, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x98, 0x47, 0xE8, 0xE7, -+0x36, 0x4C, 0x25, 0x68, 0x00, 0x21, 0x0E, 0x20, 0x76, 0xF7, 0x16, 0xF9, 0xE8, 0x60, 0x23, 0x68, 0xDB, 0x68, 0x00, 0x2B, -+0x0D, 0xD0, 0x31, 0x4C, 0x23, 0x68, 0xD8, 0x68, 0x0E, 0x22, 0x00, 0x21, 0x74, 0xF7, 0xBC, 0xF8, 0x23, 0x68, 0x00, 0x22, -+0x5A, 0x70, 0xDE, 0x70, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0x2B, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, -+0x98, 0x47, 0xEA, 0xE7, 0x26, 0x4D, 0x2B, 0x68, 0x98, 0x46, 0x00, 0x21, 0x38, 0x20, 0x76, 0xF7, 0xF5, 0xF8, 0x43, 0x46, -+0xD8, 0x60, 0x2B, 0x68, 0xDB, 0x68, 0x00, 0x2B, 0x31, 0xD0, 0x20, 0x4D, 0x2B, 0x68, 0xD8, 0x68, 0x38, 0x22, 0x00, 0x21, -+0x74, 0xF7, 0x9A, 0xF8, 0x2B, 0x68, 0x98, 0x46, 0x00, 0x21, 0x28, 0x20, 0x76, 0xF7, 0xE2, 0xF8, 0x43, 0x46, 0x98, 0x60, -+0x2B, 0x68, 0x9B, 0x68, 0x00, 0x2B, 0x25, 0xD0, 0x16, 0x4D, 0x2B, 0x68, 0x98, 0x68, 0x28, 0x22, 0x00, 0x21, 0x74, 0xF7, -+0x87, 0xF8, 0x2B, 0x68, 0xD8, 0x68, 0x0E, 0x22, 0x39, 0x00, 0xCC, 0xF7, 0xF5, 0xFE, 0x2B, 0x68, 0x01, 0x22, 0x5A, 0x70, -+0xC8, 0x22, 0x52, 0x01, 0x5A, 0x60, 0xDE, 0x70, 0x0E, 0x48, 0x0F, 0x4A, 0x82, 0x60, 0x5B, 0x68, 0xE4, 0x18, 0x24, 0x01, -+0x24, 0x09, 0x44, 0x60, 0xCA, 0xF7, 0xA0, 0xFF, 0xB6, 0xE7, 0x08, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, -+0x98, 0x47, 0xC6, 0xE7, 0x04, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xD2, 0xE7, 0xC0, 0x46, -+0xD8, 0xE5, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, 0xFC, 0xE6, 0x10, 0x00, 0xD5, 0x01, 0x10, 0x00, 0xF8, 0xB5, 0x04, 0x00, -+0x4E, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x04, 0xD0, 0xFF, 0xF7, 0xB8, 0xFA, 0x05, 0x00, 0x28, 0x00, 0xF8, 0xBD, 0x4B, 0x48, -+0x78, 0xF7, 0xCA, 0xF8, 0x4A, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x07, 0xD0, 0x49, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, -+0x00, 0x20, 0x98, 0x47, 0x12, 0x25, 0xEE, 0xE7, 0x00, 0x21, 0xF8, 0x20, 0x76, 0xF7, 0x88, 0xF8, 0x42, 0x4B, 0x18, 0x60, -+0x00, 0x28, 0x75, 0xD0, 0x9F, 0xF7, 0xE0, 0xFB, 0x07, 0x00, 0x84, 0xF7, 0x81, 0xF9, 0x40, 0x4A, 0x13, 0x88, 0x40, 0x49, -+0x0B, 0x40, 0x00, 0x02, 0x03, 0x43, 0x9B, 0xB2, 0x13, 0x80, 0x3A, 0x4B, 0x1E, 0x68, 0xF8, 0x22, 0x00, 0x21, 0x30, 0x00, -+0x74, 0xF7, 0x22, 0xF8, 0x00, 0x23, 0x73, 0x62, 0x39, 0x4A, 0xF2, 0x61, 0x39, 0x4A, 0x32, 0x62, 0x03, 0x22, 0x32, 0x76, -+0x38, 0x4A, 0x12, 0x78, 0xB2, 0x75, 0x38, 0x4A, 0x32, 0x61, 0x05, 0x22, 0xF2, 0x75, 0x99, 0x32, 0xB3, 0x54, 0x01, 0x32, -+0xB3, 0x54, 0x02, 0x32, 0xB3, 0x54, 0x03, 0x32, 0x28, 0x21, 0xB1, 0x52, 0x1C, 0x3A, 0xB3, 0x52, 0x80, 0xF7, 0x72, 0xF8, -+0x05, 0x1E, 0x05, 0xD1, 0x28, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x94, 0x23, 0xF5, 0x52, -+0x93, 0x3B, 0x00, 0x22, 0x21, 0x00, 0x00, 0x20, 0xFF, 0xF7, 0x8A, 0xFA, 0x28, 0x4A, 0x13, 0x88, 0x1F, 0x21, 0x0B, 0x40, -+0x13, 0x80, 0x77, 0x60, 0x00, 0x23, 0x82, 0x22, 0xB3, 0x52, 0xB3, 0x60, 0x00, 0x22, 0xA6, 0x33, 0xF2, 0x54, 0x20, 0x3B, -+0xFA, 0x22, 0xD2, 0x01, 0xF2, 0x52, 0x37, 0x67, 0x20, 0x4B, 0xB3, 0x82, 0xFA, 0x23, 0x1B, 0x02, 0xFB, 0x18, 0x1B, 0x01, -+0x1B, 0x09, 0xF3, 0x60, 0x30, 0x00, 0xCA, 0xF7, 0x15, 0xFA, 0x05, 0x1E, 0x07, 0xD0, 0x12, 0x4B, 0x9B, 0x6E, 0x00, 0x22, -+0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x12, 0x25, 0x7F, 0xE7, 0xA0, 0x23, 0x00, 0x22, 0xF2, 0x54, 0x01, 0x32, 0x00, 0x21, -+0x00, 0x20, 0x9F, 0xF7, 0xF3, 0xF8, 0x3B, 0x00, 0x00, 0x22, 0x21, 0x00, 0x00, 0x20, 0xFF, 0xF7, 0xC3, 0xFE, 0x70, 0xE7, -+0x06, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x12, 0x25, 0x68, 0xE7, 0xD8, 0xE5, 0x10, 0x00, -+0x10, 0xD6, 0x10, 0x00, 0x38, 0xE6, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, 0xFE, 0x64, 0x61, 0x40, 0xFF, 0xF8, 0xFF, 0xFF, -+0xF1, 0x02, 0x10, 0x00, 0xD1, 0x01, 0x10, 0x00, 0x7C, 0x91, 0x0D, 0x00, 0x6A, 0x04, 0x00, 0x00, 0xF8, 0x64, 0x61, 0x40, -+0x00, 0x80, 0xFF, 0xFF, 0x10, 0xB5, 0x00, 0x29, 0x12, 0xD1, 0x03, 0x78, 0xFF, 0x2B, 0x0A, 0xD1, 0x43, 0x78, 0xC1, 0x2B, -+0x2F, 0xD1, 0x83, 0x78, 0xFB, 0x2B, 0x2E, 0xD1, 0xC1, 0x78, 0xE8, 0x39, 0x4B, 0x42, 0x59, 0x41, 0x03, 0x31, 0x04, 0x39, -+0x48, 0x42, 0x48, 0x41, 0xC0, 0xB2, 0x10, 0xBD, 0x03, 0x29, 0x0C, 0xD0, 0x12, 0x4B, 0x5C, 0x5C, 0x00, 0x23, 0xD9, 0xB2, -+0xC2, 0x5C, 0xA2, 0x42, 0xF1, 0xD1, 0x01, 0x31, 0xC9, 0xB2, 0x01, 0x33, 0x04, 0x2B, 0xF6, 0xD1, 0xEB, 0xE7, 0x03, 0x78, -+0xFF, 0x2B, 0x0A, 0xD1, 0x43, 0x78, 0xC1, 0x2B, 0x09, 0xD1, 0x83, 0x78, 0xFB, 0x2B, 0x08, 0xD1, 0xC3, 0x78, 0xE8, 0x2B, -+0xDF, 0xD1, 0x04, 0x21, 0xDD, 0xE7, 0x00, 0x21, 0xDB, 0xE7, 0x01, 0x21, 0xD9, 0xE7, 0x02, 0x21, 0xD7, 0xE7, 0x01, 0x21, -+0xD5, 0xE7, 0x02, 0x21, 0xD3, 0xE7, 0xC0, 0x46, 0x1C, 0xE0, 0x10, 0x00, 0xF8, 0xB5, 0x23, 0x4B, 0x1B, 0x68, 0x00, 0x2B, -+0x3A, 0xD0, 0xDA, 0x68, 0x53, 0x78, 0x00, 0x2B, 0x10, 0xD1, 0x95, 0x88, 0x00, 0x2D, 0x0C, 0xD0, 0x1E, 0x4F, 0x1F, 0x4E, -+0xF1, 0x5C, 0xC4, 0x5C, 0x61, 0x40, 0x79, 0x5C, 0xD4, 0x6A, 0xA4, 0x46, 0x61, 0x44, 0xD1, 0x62, 0x01, 0x33, 0xAB, 0x42, -+0xF4, 0xD3, 0xF8, 0xBD, 0x03, 0x2B, 0x11, 0xD0, 0x18, 0x49, 0xCD, 0x5C, 0x94, 0x88, 0x00, 0x2C, 0xF7, 0xD0, 0x00, 0x23, -+0x13, 0x4E, 0xC1, 0x5C, 0x69, 0x40, 0x71, 0x5C, 0xD7, 0x6A, 0xBC, 0x46, 0x61, 0x44, 0xD1, 0x62, 0x01, 0x33, 0xA3, 0x42, -+0xF5, 0xD3, 0xEA, 0xE7, 0x95, 0x88, 0x00, 0x2D, 0xE7, 0xD0, 0x00, 0x23, 0x0B, 0x4F, 0x0E, 0x4E, 0xF1, 0x5C, 0xC4, 0x5C, -+0x61, 0x40, 0x79, 0x5C, 0xD4, 0x6A, 0xA4, 0x46, 0x61, 0x44, 0xD1, 0x62, 0x01, 0x33, 0xAB, 0x42, 0xF4, 0xD3, 0xD8, 0xE7, -+0x08, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xD1, 0xE7, 0xC0, 0x46, 0xD8, 0xE5, 0x10, 0x00, -+0xBC, 0xDE, 0x10, 0x00, 0xBC, 0xDA, 0x10, 0x00, 0x1C, 0xE0, 0x10, 0x00, 0xBC, 0xD6, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, -+0xF0, 0xB5, 0xD6, 0x46, 0x4F, 0x46, 0x46, 0x46, 0xC0, 0xB5, 0x82, 0xB0, 0x06, 0x00, 0x74, 0x4B, 0x1B, 0x68, 0xDD, 0x68, -+0x54, 0x1E, 0xE4, 0xB2, 0x00, 0x2A, 0x00, 0xD1, 0xDA, 0xE0, 0x71, 0x4F, 0xAB, 0xE0, 0x04, 0x21, 0x08, 0x00, 0x10, 0x40, -+0x11, 0x42, 0x2F, 0xD0, 0xE9, 0x69, 0x01, 0x31, 0xE9, 0x61, 0xDB, 0x04, 0x9B, 0x0D, 0x99, 0x46, 0xB8, 0x23, 0x13, 0x42, -+0x5B, 0xD1, 0xAB, 0x88, 0xDB, 0x00, 0xAA, 0x6A, 0x94, 0x46, 0x63, 0x44, 0xAB, 0x62, 0xD5, 0x23, 0x5B, 0x00, 0x65, 0x4A, -+0xD2, 0x5C, 0xD3, 0x00, 0x9B, 0x1A, 0x5B, 0x00, 0x63, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x18, 0x88, 0x83, 0xB2, 0x9A, 0x46, -+0x00, 0x2B, 0x06, 0xD1, 0x60, 0x4B, 0x9B, 0x6E, 0x01, 0x93, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x4B, 0x46, -+0x00, 0x2B, 0x53, 0xD0, 0x43, 0x46, 0x59, 0x06, 0x09, 0x0F, 0x5B, 0x48, 0x50, 0x44, 0xFF, 0xF7, 0x67, 0xFF, 0x4B, 0xE0, -+0x69, 0x69, 0x01, 0x31, 0x69, 0x61, 0xDB, 0x04, 0x9B, 0x0D, 0x99, 0x46, 0xB8, 0x23, 0x13, 0x42, 0x00, 0xD0, 0x95, 0xE0, -+0x00, 0x28, 0xCC, 0xD1, 0xAB, 0x88, 0x4B, 0x45, 0x2B, 0xD0, 0x6B, 0x6A, 0x01, 0x33, 0x6B, 0x62, 0x4C, 0x4A, 0xD5, 0x23, -+0x5B, 0x00, 0xD2, 0x5C, 0xD3, 0x00, 0x9B, 0x1A, 0x5B, 0x00, 0x4A, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x18, 0x88, 0x83, 0xB2, -+0x98, 0x46, 0x00, 0x2B, 0x05, 0xD1, 0x47, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x4B, 0x46, -+0x00, 0x2B, 0x21, 0xD0, 0x69, 0x78, 0x43, 0x48, 0x40, 0x44, 0xFF, 0xF7, 0xF7, 0xFE, 0x00, 0x28, 0x1A, 0xD1, 0x2B, 0x6B, -+0x01, 0x33, 0x2B, 0x63, 0x16, 0xE0, 0x2B, 0x6A, 0x01, 0x33, 0x2B, 0x62, 0x00, 0x28, 0x11, 0xD1, 0xD0, 0xE7, 0xDB, 0x00, -+0xAA, 0x6A, 0x94, 0x46, 0x63, 0x44, 0xAB, 0x62, 0xD0, 0xE7, 0x35, 0x23, 0xEB, 0x5C, 0x01, 0x33, 0xDB, 0xB2, 0x64, 0x2B, -+0x54, 0xD8, 0x35, 0x22, 0xAB, 0x54, 0x34, 0x23, 0x00, 0x22, 0xEA, 0x54, 0x2F, 0x4A, 0xD5, 0x23, 0x5B, 0x00, 0xD2, 0x5C, -+0xD3, 0x00, 0x9B, 0x1A, 0x5B, 0x00, 0x2D, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1B, 0x88, 0x9B, 0xB2, 0x00, 0x2B, 0x05, 0xD1, -+0x2A, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x25, 0x48, 0xD5, 0x21, 0x49, 0x00, 0x42, 0x5C, -+0xD3, 0x00, 0x9B, 0x1A, 0x5B, 0x00, 0x26, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1A, 0x88, 0x52, 0x04, 0x52, 0x0C, 0x1A, 0x80, -+0x42, 0x5C, 0x01, 0x32, 0x03, 0x23, 0x13, 0x40, 0x43, 0x54, 0x01, 0x3C, 0xE4, 0xB2, 0xFF, 0x2C, 0x2C, 0xD0, 0x30, 0x00, -+0x9E, 0xF7, 0x5A, 0xFF, 0x00, 0x28, 0x27, 0xD0, 0xD5, 0x23, 0x5B, 0x00, 0xFA, 0x5C, 0xD3, 0x00, 0x9B, 0x1A, 0x5B, 0x00, -+0x19, 0x4A, 0x9A, 0x18, 0x10, 0x88, 0x82, 0xB2, 0x18, 0x49, 0x59, 0x18, 0x09, 0x88, 0x89, 0xB2, 0x88, 0x46, 0x17, 0x49, -+0x8C, 0x46, 0x63, 0x44, 0x1B, 0x88, 0x9B, 0xB2, 0xC1, 0x07, 0xAE, 0xD4, 0x29, 0x69, 0x01, 0x31, 0x29, 0x61, 0x91, 0x07, -+0x00, 0xD4, 0x32, 0xE7, 0xAB, 0x69, 0x01, 0x33, 0xAB, 0x61, 0xAF, 0xE7, 0x35, 0x23, 0x64, 0x22, 0xEA, 0x54, 0xA8, 0xE7, -+0x2B, 0x6A, 0x01, 0x33, 0x2B, 0x62, 0x67, 0xE7, 0x02, 0xB0, 0x1C, 0xBC, 0x90, 0x46, 0x99, 0x46, 0xA2, 0x46, 0xF0, 0xBD, -+0xD8, 0xE5, 0x10, 0x00, 0x20, 0xA3, 0x16, 0x00, 0x9A, 0x69, 0x61, 0x40, 0x28, 0x19, 0x16, 0x00, 0x00, 0x00, 0x61, 0x40, -+0x90, 0x69, 0x61, 0x40, 0x92, 0x69, 0x61, 0x40, 0x94, 0x69, 0x61, 0x40, 0x96, 0x69, 0x61, 0x40, 0xF0, 0xB5, 0xD6, 0x46, -+0x4F, 0x46, 0x46, 0x46, 0xC0, 0xB5, 0x89, 0x46, 0x82, 0x00, 0x41, 0x4B, 0xD5, 0x58, 0xA6, 0x23, 0xEF, 0x5C, 0x2E, 0x6D, -+0x44, 0x3B, 0x58, 0x43, 0x3E, 0x4B, 0xC3, 0x18, 0x1B, 0x88, 0x3E, 0x4A, 0x82, 0x18, 0x14, 0x88, 0x1B, 0x04, 0x1C, 0x43, -+0xA2, 0x46, 0x3C, 0x4B, 0xC3, 0x18, 0x1B, 0x88, 0x9B, 0x05, 0x9B, 0x0D, 0x98, 0x46, 0x3A, 0x4B, 0xC3, 0x18, 0x1C, 0x88, -+0x39, 0x4B, 0x9C, 0x46, 0x60, 0x44, 0x01, 0x88, 0x24, 0x04, 0x0C, 0x19, 0x37, 0x4B, 0x9E, 0x42, 0x1C, 0xD8, 0x53, 0x46, -+0x4A, 0x46, 0x9B, 0x1A, 0x19, 0x01, 0x09, 0x09, 0x80, 0x22, 0x12, 0x05, 0x91, 0x42, 0x40, 0xD9, 0x4B, 0x46, 0x52, 0x46, -+0x9B, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x5B, 0x42, 0xA1, 0x22, 0xAA, 0x5C, 0x00, 0x2A, 0x3D, 0xD0, 0x00, 0x2B, 0x07, 0xDB, -+0x89, 0x08, 0x00, 0x29, 0x04, 0xDD, 0x89, 0x00, 0x49, 0x44, 0x09, 0x01, 0x0B, 0x09, 0x99, 0x46, 0x53, 0x46, 0xE1, 0x1A, -+0x49, 0x44, 0x09, 0x01, 0x09, 0x09, 0xF4, 0x23, 0x5B, 0x00, 0x42, 0x46, 0x9B, 0x1A, 0x32, 0xD4, 0xA9, 0x67, 0x82, 0x22, -+0xAB, 0x52, 0x4A, 0x42, 0x03, 0x20, 0x10, 0x40, 0xA6, 0x22, 0xA8, 0x54, 0x72, 0x3A, 0x2A, 0x65, 0xAB, 0x60, 0x34, 0x2E, -+0x09, 0xD9, 0xEA, 0x7D, 0x00, 0x2A, 0x06, 0xD0, 0xC8, 0x22, 0x52, 0x00, 0x9A, 0x42, 0x92, 0x41, 0x52, 0x42, 0x05, 0x32, -+0xEA, 0x75, 0x69, 0x67, 0x84, 0x22, 0xAB, 0x52, 0xC0, 0x1B, 0x43, 0x1E, 0x98, 0x41, 0xC0, 0xB2, 0x1C, 0xBC, 0x90, 0x46, -+0x99, 0x46, 0xA2, 0x46, 0xF0, 0xBD, 0x1B, 0x01, 0x1B, 0x09, 0xA1, 0x22, 0xAA, 0x5C, 0x00, 0x2A, 0xC4, 0xD0, 0xC1, 0xE7, -+0x00, 0x2B, 0xC1, 0xDA, 0x0D, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xC2, 0xE7, 0x0B, 0x4B, -+0x9B, 0x1A, 0x01, 0x31, 0x09, 0x01, 0x09, 0x09, 0xC6, 0xE7, 0xC0, 0x46, 0x38, 0xE6, 0x10, 0x00, 0x4C, 0x65, 0x61, 0x40, -+0x4A, 0x65, 0x61, 0x40, 0x4E, 0x65, 0x61, 0x40, 0xFC, 0x64, 0x61, 0x40, 0xFA, 0x64, 0x61, 0x40, 0xE1, 0x04, 0x00, 0x00, -+0x28, 0x19, 0x16, 0x00, 0x59, 0x04, 0x00, 0x00, 0xF8, 0xB5, 0x80, 0x00, 0x25, 0x4B, 0xC5, 0x58, 0xA6, 0x23, 0xEE, 0x5C, -+0x6C, 0x6F, 0xEB, 0x6E, 0xC8, 0x1A, 0x00, 0x01, 0x00, 0x09, 0x22, 0x49, 0x48, 0x43, 0x22, 0x49, 0xCB, 0xF7, 0x84, 0xFF, -+0x1A, 0x30, 0x40, 0x00, 0x02, 0x00, 0x34, 0x3A, 0x52, 0x08, 0x84, 0x23, 0xEB, 0x5A, 0x9B, 0x1A, 0x19, 0xB2, 0x1B, 0x04, -+0x27, 0xD5, 0x00, 0x23, 0x1B, 0x4A, 0x8A, 0x18, 0x11, 0xB2, 0x01, 0x34, 0x24, 0x01, 0x24, 0x09, 0x1F, 0x00, 0x01, 0x33, -+0xDB, 0xB2, 0x12, 0x04, 0xF4, 0xD4, 0xAC, 0x67, 0x82, 0x22, 0xA9, 0x52, 0x64, 0x42, 0x7F, 0x3A, 0x14, 0x40, 0xA3, 0x32, -+0xAC, 0x54, 0x28, 0x65, 0xA9, 0x60, 0x00, 0x2B, 0x0A, 0xD0, 0xEB, 0x7D, 0x00, 0x2B, 0x07, 0xD0, 0xC8, 0x23, 0x5B, 0x00, -+0x8B, 0x42, 0x9B, 0x41, 0x5B, 0x42, 0x06, 0x37, 0xDF, 0x19, 0xEF, 0x75, 0x34, 0x1B, 0x66, 0x1E, 0xB4, 0x41, 0xE0, 0xB2, -+0xF8, 0xBD, 0xAC, 0x67, 0x82, 0x23, 0xE9, 0x52, 0x64, 0x42, 0x7F, 0x3B, 0x1C, 0x40, 0xA3, 0x33, 0xEC, 0x54, 0x28, 0x65, -+0xA9, 0x60, 0xEF, 0xE7, 0x38, 0xE6, 0x10, 0x00, 0xA8, 0x61, 0x00, 0x00, 0x40, 0x42, 0x0F, 0x00, 0x71, 0x02, 0x00, 0x00, -+0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x8A, 0xB0, 0x0E, 0x00, 0x8A, 0x00, 0x52, 0x4B, 0xD5, 0x58, 0x00, 0x2D, 0x00, 0xD1, -+0x9B, 0xE0, 0xA6, 0x23, 0x98, 0x46, 0xEB, 0x5C, 0x01, 0x33, 0x03, 0x24, 0x23, 0x40, 0x1F, 0x00, 0x9F, 0xF7, 0xB0, 0xF8, -+0x00, 0x90, 0x03, 0x00, 0xA3, 0x43, 0x3B, 0x43, 0x42, 0x46, 0xAA, 0x5C, 0xD2, 0x1A, 0x14, 0x40, 0x04, 0x3B, 0xE4, 0x18, -+0x24, 0x01, 0x24, 0x09, 0x23, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x80, 0x22, 0x12, 0x05, 0x93, 0x42, 0x02, 0xD9, 0x03, 0x1B, -+0x1B, 0x01, 0x59, 0xD1, 0x00, 0x23, 0x01, 0x93, 0x01, 0xA9, 0x68, 0x46, 0x9F, 0xF7, 0x9C, 0xF8, 0x01, 0x9B, 0x1A, 0x00, -+0x0F, 0x32, 0xFF, 0x32, 0x9C, 0x21, 0x89, 0x00, 0x8A, 0x42, 0x57, 0xD8, 0x01, 0x92, 0x00, 0x9A, 0x13, 0x1B, 0x1B, 0x01, -+0x1B, 0x09, 0x38, 0x49, 0x8B, 0x42, 0x05, 0xD8, 0xA2, 0x42, 0x61, 0xD1, 0xAB, 0x68, 0x01, 0x9A, 0x93, 0x42, 0x5D, 0xD9, -+0x02, 0xA8, 0x34, 0x4B, 0x02, 0x93, 0x44, 0x60, 0xAB, 0x68, 0x83, 0x60, 0x06, 0x76, 0x06, 0x61, 0x31, 0x4B, 0xC3, 0x60, -+0xAB, 0x7D, 0x03, 0x75, 0x01, 0x33, 0x43, 0x75, 0x00, 0x23, 0x83, 0x75, 0xB0, 0x22, 0xAA, 0x5C, 0xC2, 0x75, 0x83, 0x76, -+0xC3, 0x76, 0x01, 0x33, 0x43, 0x76, 0xCA, 0xF7, 0xD7, 0xFE, 0xA9, 0x22, 0xAB, 0x5C, 0x01, 0x33, 0xAB, 0x54, 0xAA, 0x23, -+0xEB, 0x5C, 0x00, 0x2B, 0x31, 0xD1, 0x9F, 0x23, 0xEB, 0x5C, 0x01, 0x2B, 0x3B, 0xD1, 0xAB, 0x6F, 0x9B, 0xB2, 0x62, 0x21, -+0x4E, 0x43, 0x22, 0x4A, 0xB2, 0x18, 0x13, 0x80, 0xAB, 0x6F, 0x1B, 0x0C, 0x20, 0x4A, 0xB2, 0x18, 0x13, 0x80, 0x20, 0x4B, -+0x9C, 0x46, 0x66, 0x44, 0x2B, 0x6D, 0x01, 0x33, 0x5B, 0x08, 0x01, 0x33, 0x5B, 0x08, 0x1D, 0x4A, 0x13, 0x43, 0x9B, 0xB2, -+0x33, 0x80, 0x22, 0xE0, 0x04, 0x34, 0x24, 0x01, 0x24, 0x09, 0x23, 0x1A, 0x1B, 0x01, 0x1B, 0x09, 0x93, 0x42, 0x9D, 0xD9, -+0x03, 0x1B, 0x1B, 0x01, 0x9A, 0xD0, 0xF3, 0xE7, 0x64, 0x3B, 0xFF, 0x3B, 0x01, 0x93, 0x00, 0x9B, 0x01, 0x33, 0x1B, 0x01, -+0x1B, 0x09, 0x00, 0x93, 0x9F, 0xE7, 0x9E, 0x23, 0xE8, 0x5C, 0xCB, 0xF7, 0x21, 0xF8, 0x0F, 0x4B, 0x01, 0x22, 0x1A, 0x60, -+0xAA, 0x23, 0x00, 0x22, 0xEA, 0x54, 0xC2, 0xE7, 0x0C, 0x48, 0x77, 0xF7, 0xF1, 0xFC, 0x0A, 0xB0, 0x04, 0xBC, 0x90, 0x46, -+0xF0, 0xBD, 0xC0, 0x46, 0x38, 0xE6, 0x10, 0x00, 0xFE, 0xFF, 0xFF, 0x07, 0x39, 0xCB, 0x10, 0x00, 0xDE, 0x05, 0x00, 0x00, -+0xFA, 0x64, 0x61, 0x40, 0xFC, 0x64, 0x61, 0x40, 0x10, 0x65, 0x61, 0x40, 0x00, 0x80, 0xFF, 0xFF, 0x18, 0x00, 0x60, 0x40, -+0x28, 0xD6, 0x10, 0x00, 0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x82, 0xB0, 0x05, 0x00, 0x0E, 0x00, 0x82, 0x00, 0x9D, 0x4B, -+0xD4, 0x58, 0x00, 0x2C, 0x00, 0xD1, 0x2B, 0xE1, 0x9B, 0x4B, 0x1B, 0x68, 0xDF, 0x68, 0xA9, 0x23, 0xE3, 0x5C, 0x00, 0x2B, -+0x05, 0xD1, 0x99, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xA9, 0x22, 0xA3, 0x5C, 0x01, 0x3B, -+0xDB, 0xB2, 0xA3, 0x54, 0x09, 0x3A, 0xA2, 0x5C, 0x02, 0x2A, 0x01, 0xD1, 0x00, 0x2B, 0x51, 0xD0, 0x9E, 0xF7, 0xDE, 0xFF, -+0x01, 0x90, 0x01, 0x22, 0x31, 0x00, 0x28, 0x00, 0xFF, 0xF7, 0x20, 0xFD, 0x62, 0x23, 0x6B, 0x43, 0x8C, 0x4A, 0x94, 0x46, -+0x63, 0x44, 0x1B, 0x88, 0xDB, 0x0B, 0x00, 0xD1, 0xAC, 0xE0, 0x31, 0x00, 0x28, 0x00, 0xFF, 0xF7, 0x15, 0xFE, 0xB4, 0x23, -+0xE0, 0x54, 0xA0, 0x23, 0xE3, 0x5C, 0x02, 0x2B, 0x00, 0xD1, 0xEA, 0xE0, 0x01, 0x21, 0x28, 0x00, 0xFF, 0xF7, 0xBA, 0xF9, -+0x82, 0x23, 0xE3, 0x5E, 0xA3, 0x60, 0x81, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x0C, 0xD0, 0x34, 0x23, 0xFB, 0x5C, 0x00, 0x2B, -+0x00, 0xD1, 0x9D, 0xE0, 0xA9, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x00, 0xD1, 0x93, 0xE0, 0x7A, 0x4B, 0x00, 0x22, 0x1A, 0x60, -+0x34, 0x23, 0xFB, 0x5C, 0x00, 0x2B, 0x00, 0xD1, 0x90, 0xE0, 0xB4, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x00, 0xD0, 0xBE, 0xE0, -+0xAA, 0x33, 0xE3, 0x5C, 0x00, 0x2B, 0x00, 0xD0, 0xD6, 0xE0, 0xA6, 0x33, 0xE2, 0x5C, 0x01, 0x32, 0xA3, 0x3B, 0x13, 0x40, -+0x9E, 0x22, 0xA1, 0x5C, 0x9C, 0x3A, 0x6E, 0x48, 0xCA, 0xF7, 0x56, 0xFF, 0xAA, 0x23, 0x01, 0x22, 0xE2, 0x54, 0xC7, 0xE0, -+0x01, 0x21, 0x20, 0x00, 0xC9, 0xF7, 0xBE, 0xFF, 0xA0, 0x23, 0x02, 0x22, 0xE2, 0x54, 0x0A, 0x33, 0xE3, 0x5C, 0x00, 0x2B, -+0x49, 0xD1, 0xFE, 0xF7, 0xBF, 0xFD, 0x65, 0x4A, 0xD5, 0x23, 0x5B, 0x00, 0xD2, 0x5C, 0xD3, 0x00, 0x9B, 0x1A, 0x5B, 0x00, -+0x62, 0x4A, 0x9A, 0x18, 0x12, 0x88, 0xD2, 0x0B, 0x00, 0xD1, 0xAD, 0xE0, 0x60, 0x4A, 0x94, 0x46, 0x63, 0x44, 0x1A, 0x88, -+0xD2, 0x0A, 0xAA, 0x42, 0x07, 0xD0, 0x19, 0x88, 0xC9, 0x0A, 0x56, 0x4B, 0xDC, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x28, 0x00, -+0xA0, 0x47, 0x57, 0x4C, 0xD5, 0x20, 0x40, 0x00, 0x22, 0x5C, 0xD3, 0x00, 0x9B, 0x1A, 0x5B, 0x00, 0x54, 0x4A, 0x94, 0x46, -+0x63, 0x44, 0x1A, 0x88, 0x52, 0x04, 0x52, 0x0C, 0x1A, 0x80, 0x21, 0x5C, 0x01, 0x31, 0x03, 0x23, 0x19, 0x40, 0x21, 0x54, -+0x50, 0x4B, 0x1A, 0x68, 0xCB, 0x00, 0x5B, 0x1A, 0x5B, 0x00, 0x4F, 0x49, 0x8C, 0x46, 0x63, 0x44, 0x52, 0x04, 0x52, 0x0C, -+0x93, 0x42, 0x05, 0xD0, 0x43, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x45, 0x4E, 0x00, 0x24, -+0xD5, 0x23, 0x5B, 0x00, 0x98, 0x46, 0x3E, 0x4F, 0x0A, 0xE0, 0x28, 0x00, 0xCA, 0xF7, 0x30, 0xFF, 0xAA, 0x23, 0x00, 0x22, -+0xE2, 0x54, 0xAE, 0xE7, 0x01, 0x34, 0x0E, 0x36, 0x04, 0x2C, 0x67, 0xD0, 0x33, 0x88, 0xDB, 0x0B, 0xF8, 0xD0, 0x3A, 0x4B, -+0x42, 0x46, 0x98, 0x5C, 0x00, 0x23, 0x00, 0x22, 0x21, 0x00, 0xFD, 0x6E, 0xA8, 0x47, 0xEF, 0xE7, 0x31, 0x00, 0x28, 0x00, -+0xFF, 0xF7, 0x04, 0xFE, 0xB4, 0x23, 0xE0, 0x54, 0x51, 0xE7, 0x29, 0x00, 0x01, 0x98, 0xFF, 0xF7, 0x53, 0xFE, 0x66, 0xE7, -+0xB4, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x2E, 0xD1, 0xAA, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x47, 0xD1, 0xA9, 0x33, 0xE3, 0x5C, -+0x00, 0x2B, 0x43, 0xD1, 0x01, 0x21, 0x20, 0x00, 0xC9, 0xF7, 0x3A, 0xFF, 0x01, 0x99, 0x61, 0x60, 0x86, 0x23, 0xFA, 0x22, -+0xD2, 0x01, 0xE2, 0x52, 0x21, 0x67, 0x20, 0x33, 0xE3, 0x5C, 0xDB, 0x02, 0xE0, 0x22, 0x92, 0x01, 0x13, 0x40, 0x26, 0x4A, -+0x13, 0x43, 0xA3, 0x82, 0xFA, 0x23, 0x1B, 0x02, 0x9C, 0x46, 0x61, 0x44, 0x0F, 0x01, 0x3F, 0x09, 0xE7, 0x60, 0x20, 0x00, -+0xC9, 0xF7, 0x7C, 0xFD, 0x00, 0x28, 0x23, 0xD0, 0x15, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, -+0x1C, 0xE0, 0x9E, 0x23, 0xE0, 0x5C, 0xCA, 0xF7, 0xD9, 0xFE, 0x00, 0x23, 0xAA, 0x22, 0xA3, 0x54, 0x75, 0x3A, 0xBB, 0x54, -+0xC6, 0xE7, 0x9E, 0x23, 0xE0, 0x5C, 0xCA, 0xF7, 0xCF, 0xFE, 0xAA, 0x23, 0x00, 0x22, 0xE2, 0x54, 0x01, 0x3B, 0xE1, 0x5C, -+0x12, 0x48, 0x77, 0xF7, 0xA1, 0xFB, 0x05, 0xE0, 0x06, 0x4B, 0xDC, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x00, 0x21, 0xA0, 0x47, -+0x02, 0xB0, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, 0x38, 0xE6, 0x10, 0x00, 0xD8, 0xE5, 0x10, 0x00, 0x28, 0x19, 0x16, 0x00, -+0x4E, 0x65, 0x61, 0x40, 0xC8, 0xE6, 0x10, 0x00, 0x7D, 0x03, 0x10, 0x00, 0x20, 0xA3, 0x16, 0x00, 0x90, 0x69, 0x61, 0x40, -+0x92, 0x69, 0x61, 0x40, 0x2C, 0x04, 0x60, 0x40, 0x90, 0x69, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x34, 0xD6, 0x10, 0x00, -+0x10, 0xB5, 0x82, 0x00, 0x0C, 0x4B, 0xD4, 0x58, 0x00, 0x2C, 0x0E, 0xD0, 0xA9, 0x23, 0xE3, 0x5C, 0x00, 0x2B, 0x05, 0xD1, -+0x09, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xA9, 0x22, 0xA3, 0x5C, 0x01, 0x3B, 0xA3, 0x54, -+0x10, 0xBD, 0x04, 0x4B, 0xDC, 0x6E, 0x00, 0x23, 0x00, 0x22, 0x00, 0x21, 0xA0, 0x47, 0xF7, 0xE7, 0x38, 0xE6, 0x10, 0x00, -+0x28, 0x19, 0x16, 0x00, 0xF0, 0xB5, 0xC6, 0x46, 0x00, 0xB5, 0x06, 0x00, 0x0D, 0x00, 0x14, 0x00, 0xCF, 0xB2, 0x06, 0x2F, -+0x08, 0xD9, 0xFF, 0x20, 0x08, 0x40, 0x10, 0x4B, 0xDB, 0x6E, 0x98, 0x46, 0x00, 0x23, 0x00, 0x22, 0x21, 0x00, 0xC0, 0x47, -+0x00, 0x2C, 0x0A, 0xD0, 0x04, 0x2C, 0x0F, 0xD0, 0xFF, 0x20, 0x28, 0x40, 0x09, 0x4B, 0xDD, 0x6E, 0x00, 0x23, 0x00, 0x22, -+0x21, 0x00, 0xA8, 0x47, 0x03, 0xE0, 0x31, 0x00, 0x38, 0x00, 0xFF, 0xF7, 0x61, 0xFE, 0x04, 0xBC, 0x90, 0x46, 0xF0, 0xBD, -+0x31, 0x00, 0x38, 0x00, 0xFF, 0xF7, 0xB6, 0xFF, 0xF7, 0xE7, 0xC0, 0x46, 0x28, 0x19, 0x16, 0x00, 0xF8, 0xB5, 0x05, 0x00, -+0x51, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x02, 0xD0, 0xFE, 0xF7, 0x0E, 0xFD, 0xF8, 0xBD, 0x4F, 0x48, 0x77, 0xF7, 0x22, 0xFB, -+0x4E, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x07, 0xD0, 0x4D, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, -+0x12, 0x20, 0xEF, 0xE7, 0x00, 0x21, 0xF8, 0x20, 0x75, 0xF7, 0xE0, 0xFA, 0x46, 0x4B, 0x18, 0x60, 0x00, 0x28, 0x00, 0xD1, -+0x7C, 0xE0, 0x9E, 0xF7, 0x37, 0xFE, 0x06, 0x00, 0x83, 0xF7, 0xD8, 0xFB, 0x43, 0x4A, 0x13, 0x88, 0x43, 0x49, 0x0B, 0x40, -+0x00, 0x02, 0x03, 0x43, 0x9B, 0xB2, 0x13, 0x80, 0x3D, 0x4B, 0x1C, 0x68, 0xF8, 0x22, 0x00, 0x21, 0x20, 0x00, 0x73, 0xF7, -+0x79, 0xFA, 0x00, 0x23, 0x63, 0x62, 0x3D, 0x4A, 0xE2, 0x61, 0x3D, 0x4A, 0x22, 0x62, 0x03, 0x22, 0x22, 0x76, 0x3C, 0x4A, -+0x12, 0x78, 0xA2, 0x75, 0x3B, 0x4A, 0x22, 0x61, 0x05, 0x22, 0xE2, 0x75, 0x99, 0x32, 0xA3, 0x54, 0x01, 0x32, 0x01, 0x21, -+0xA1, 0x54, 0x6B, 0x3A, 0x22, 0x65, 0x6D, 0x32, 0xA3, 0x54, 0x7F, 0xF7, 0xA9, 0xFA, 0x07, 0x1E, 0x3D, 0xD0, 0x3A, 0x89, -+0x94, 0x23, 0xE2, 0x52, 0x93, 0x3B, 0x01, 0x22, 0x29, 0x00, 0x00, 0x20, 0xFE, 0xF7, 0xE8, 0xFC, 0x33, 0x00, 0x00, 0x22, -+0x29, 0x00, 0x01, 0x20, 0xFF, 0xF7, 0x50, 0xF9, 0x9E, 0xF7, 0xF8, 0xFD, 0x60, 0x60, 0x00, 0x23, 0x82, 0x22, 0xA3, 0x52, -+0xA3, 0x60, 0x04, 0x32, 0xFA, 0x21, 0xC9, 0x01, 0xA1, 0x52, 0xE6, 0x66, 0x26, 0x67, 0x63, 0x67, 0xA3, 0x67, 0x00, 0x22, -+0xA6, 0x33, 0xE2, 0x54, 0x23, 0x4B, 0xA3, 0x82, 0xFA, 0x23, 0x1B, 0x02, 0x9C, 0x46, 0x66, 0x44, 0x36, 0x01, 0x36, 0x09, -+0xE6, 0x60, 0x20, 0x00, 0xC9, 0xF7, 0x6C, 0xFC, 0x00, 0x28, 0x15, 0xD1, 0xA0, 0x23, 0x00, 0x22, 0xE2, 0x54, 0x1C, 0x49, -+0xA1, 0x32, 0xFF, 0x32, 0x8B, 0x5A, 0x01, 0x24, 0x23, 0x43, 0x8B, 0x52, 0xA0, 0x3A, 0xFF, 0x3A, 0x18, 0x4B, 0x1A, 0x60, -+0x78, 0xE7, 0x0E, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0xBA, 0xE7, 0x0A, 0x4B, 0x9B, 0x6E, -+0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x98, 0x47, 0x12, 0x20, 0x69, 0xE7, 0x06, 0x4B, 0x9B, 0x6E, 0x00, 0x22, 0x00, 0x21, -+0x00, 0x20, 0x98, 0x47, 0x12, 0x20, 0x61, 0xE7, 0xD8, 0xE5, 0x10, 0x00, 0x4C, 0xD6, 0x10, 0x00, 0x38, 0xE6, 0x10, 0x00, -+0x28, 0x19, 0x16, 0x00, 0xFE, 0x64, 0x61, 0x40, 0xFF, 0xF8, 0xFF, 0xFF, 0xA1, 0x04, 0x10, 0x00, 0xD3, 0x01, 0x10, 0x00, -+0x7C, 0x91, 0x0D, 0x00, 0x6A, 0x04, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x20, 0xA3, 0x16, 0x00, 0xC8, 0xE6, 0x10, 0x00, -+0x70, 0xB5, 0x04, 0x00, 0x0D, 0x00, 0x0A, 0x48, 0x77, 0xF7, 0x68, 0xFA, 0xA1, 0x78, 0x4A, 0x10, 0x01, 0x23, 0x1A, 0x40, -+0x07, 0x48, 0x02, 0x70, 0x0B, 0x40, 0xA3, 0x70, 0x20, 0x00, 0xFF, 0xF7, 0x85, 0xF9, 0x01, 0x00, 0x28, 0x00, 0xFA, 0xF7, -+0x8B, 0xF9, 0x00, 0x20, 0x70, 0xBD, 0xC0, 0x46, 0x60, 0xD6, 0x10, 0x00, 0xDC, 0xE5, 0x10, 0x00, 0x70, 0xB5, 0x05, 0x00, -+0x0C, 0x00, 0x06, 0x48, 0x77, 0xF7, 0x4C, 0xFA, 0x28, 0x00, 0xFF, 0xF7, 0x1B, 0xFF, 0x01, 0x00, 0x20, 0x00, 0xFA, 0xF7, -+0x77, 0xF9, 0x00, 0x20, 0x70, 0xBD, 0xC0, 0x46, 0x68, 0xD6, 0x10, 0x00, 0x10, 0xB5, 0xFF, 0xF7, 0x51, 0xF8, 0x00, 0x20, -+0x10, 0xBD, 0x00, 0x00, 0x10, 0xB5, 0x0E, 0x4B, 0x1B, 0x68, 0x00, 0x2B, 0x17, 0xD0, 0xDC, 0x68, 0x18, 0x23, 0x0D, 0x22, -+0x00, 0x21, 0x0B, 0x48, 0x75, 0xF7, 0x2A, 0xF9, 0xFF, 0x23, 0x03, 0x70, 0xA3, 0x88, 0x43, 0x80, 0x00, 0x23, 0x03, 0x71, -+0x43, 0x71, 0x23, 0x69, 0x83, 0x60, 0x63, 0x69, 0xC3, 0x60, 0xE3, 0x69, 0x03, 0x61, 0xE3, 0x6A, 0x43, 0x61, 0xC6, 0xF7, -+0x79, 0xFF, 0x10, 0xBD, 0xD8, 0xE5, 0x10, 0x00, 0x03, 0x11, 0x00, 0x00, 0x70, 0xB5, 0x04, 0x00, 0x0D, 0x00, 0x01, 0x78, -+0x0A, 0x48, 0x77, 0xF7, 0x11, 0xFA, 0x23, 0x78, 0x00, 0x2B, 0x07, 0xD0, 0x01, 0x2B, 0x08, 0xD0, 0x00, 0x21, 0x28, 0x00, -+0xFA, 0xF7, 0x3A, 0xF9, 0x00, 0x20, 0x70, 0xBD, 0xFE, 0xF7, 0x6E, 0xFB, 0xF6, 0xE7, 0xFF, 0xF7, 0xC7, 0xFF, 0xFE, 0xF7, -+0x69, 0xFB, 0xF1, 0xE7, 0x70, 0xD6, 0x10, 0x00, 0x45, 0x54, 0x45, 0x52, 0x52, 0x3A, 0x0A, 0x00, 0x77, 0x61, 0x6B, 0x65, -+0x75, 0x70, 0x5F, 0x68, 0x6F, 0x73, 0x74, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x70, 0x6F, 0x77, 0x65, 0x72, 0x5F, 0x75, 0x70, -+0x5F, 0x68, 0x6F, 0x73, 0x74, 0x0A, 0x00, 0x00, 0x75, 0x61, 0x72, 0x74, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x0A, 0x00, 0x00, -+0x70, 0x5F, 0x73, 0x5F, 0x70, 0x00, 0x00, 0x00, 0x77, 0x69, 0x66, 0x69, 0x5F, 0x63, 0x68, 0x5F, 0x75, 0x70, 0x64, 0x61, -+0x74, 0x65, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, -+0xE6, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xF6, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0x1A, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0x42, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0x66, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0x8E, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xBA, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xE6, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0x0C, 0x1C, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0x32, 0x1C, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0x5C, 0x1C, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0x82, 0x1C, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA2, 0x1C, 0x10, 0x00, 0xC4, 0x1C, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0x16, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0x3E, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0x62, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0x8A, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0xB6, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0xE2, 0x1B, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0x08, 0x1C, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0x2E, 0x1C, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0x58, 0x1C, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0x7E, 0x1C, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0x9E, 0x1C, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, 0xA8, 0x1A, 0x10, 0x00, -+0xA8, 0x1A, 0x10, 0x00, 0xC0, 0x1C, 0x10, 0x00, 0x30, 0x78, 0x34, 0x30, 0x33, 0x34, 0x33, 0x30, 0x30, 0x34, 0x3A, 0x25, -+0x78, 0x2C, 0x25, 0x78, 0x00, 0x00, 0x00, 0x00, 0x43, 0x54, 0x53, 0x3A, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x20, 0x0A, 0x00, -+0xE2, 0x1D, 0x10, 0x00, 0x78, 0x1D, 0x10, 0x00, 0x78, 0x1D, 0x10, 0x00, 0x78, 0x1D, 0x10, 0x00, 0x78, 0x1D, 0x10, 0x00, -+0x78, 0x1D, 0x10, 0x00, 0x52, 0x1E, 0x10, 0x00, 0xE4, 0x1D, 0x10, 0x00, 0x78, 0x1D, 0x10, 0x00, 0x78, 0x1D, 0x10, 0x00, -+0xE2, 0x1D, 0x10, 0x00, 0x78, 0x1D, 0x10, 0x00, 0x78, 0x1D, 0x10, 0x00, 0x6D, 0x64, 0x6C, 0x6C, 0x5F, 0x72, 0x65, 0x63, -+0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x62, 0x64, 0x5F, 0x61, 0x64, 0x64, 0x72, 0x3A, 0x25, 0x78, 0x2C, 0x25, -+0x78, 0x0A, 0x00, 0x00, 0x77, 0x69, 0x66, 0x69, 0x6D, 0x61, 0x63, 0x5F, 0x61, 0x64, 0x64, 0x72, 0x3A, 0x25, 0x78, 0x2C, -+0x25, 0x78, 0x0A, 0x00, 0x66, 0x6C, 0x61, 0x73, 0x68, 0x6D, 0x61, 0x63, 0x5F, 0x61, 0x64, 0x64, 0x72, 0x3A, 0x25, 0x78, -+0x2C, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x43, 0x52, 0x5F, 0x50, 0x57, 0x52, 0x5F, 0x52, 0x45, 0x51, -+0x0A, 0x00, 0x00, 0x00, 0x50, 0x57, 0x52, 0x5F, 0x43, 0x54, 0x52, 0x4C, 0x5F, 0x52, 0x45, 0x51, 0x0A, 0x00, 0x00, 0x00, -+0x72, 0x65, 0x6D, 0x6F, 0x74, 0x65, 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x70, 0x77, 0x72, 0x0A, 0x00, 0x61, 0x66, 0x68, 0x74, -+0x6F, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x74, 0x78, 0x5F, 0x61, 0x62, 0x6F, 0x72, 0x74, 0x0A, 0x00, 0x00, 0x00, -+0x72, 0x3A, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x72, 0x73, 0x73, 0x69, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, -+0x73, 0x6D, 0x75, 0x74, 0x65, 0x0A, 0x00, 0x00, 0x72, 0x78, 0x5F, 0x69, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x3A, 0x25, -+0x78, 0x2C, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x3A, 0x25, 0x78, 0x0A, 0x00, -+0x64, 0x75, 0x20, 0x65, 0x6E, 0x6F, 0x75, 0x67, 0x68, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x77, 0x69, 0x66, 0x69, 0x20, 0x63, -+0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x69, 0x6F, 0x6E, 0x0A, 0x00, 0x00, 0x00, 0x75, 0x6D, 0x72, 0x65, 0x0A, 0x00, 0x00, 0x00, -+0x55, 0x4E, 0x44, 0x45, 0x46, 0x20, 0x56, 0x45, 0x4E, 0x44, 0x4F, 0x52, 0x5F, 0x49, 0x4E, 0x46, 0x4F, 0x0A, 0x00, 0x00, -+0x55, 0x4E, 0x4B, 0x4E, 0x4F, 0x57, 0x20, 0x56, 0x45, 0x4E, 0x44, 0x4F, 0x52, 0x5F, 0x49, 0x4E, 0x46, 0x4F, 0x3A, 0x25, -+0x78, 0x0A, 0x00, 0x00, 0x69, 0x6E, 0x69, 0x74, 0x3A, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x2C, 0x25, 0x78, -+0x2C, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x38, 0x5C, 0x10, 0x00, 0x70, 0x5C, 0x10, 0x00, 0x78, 0x5C, 0x10, 0x00, -+0x38, 0x5C, 0x10, 0x00, 0x70, 0x5C, 0x10, 0x00, 0x76, 0x65, 0x72, 0x3A, 0x25, 0x73, 0x0A, 0x00, 0x6C, 0x6D, 0x74, 0x3A, -+0x25, 0x78, 0x2C, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x72, 0x65, 0x6A, 0x65, 0x63, 0x74, 0x3A, 0x25, 0x78, 0x00, 0x00, 0x00, -+0x76, 0x73, 0x5F, 0x61, 0x70, 0x63, 0x66, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x72, 0x65, 0x6A, 0x65, 0x63, 0x74, 0x32, 0x3A, -+0x25, 0x78, 0x00, 0x00, 0x92, 0x73, 0x10, 0x00, 0xC6, 0x72, 0x10, 0x00, 0x86, 0x73, 0x10, 0x00, 0xC6, 0x72, 0x10, 0x00, -+0x92, 0x73, 0x10, 0x00, 0xC6, 0x72, 0x10, 0x00, 0xC6, 0x72, 0x10, 0x00, 0x8C, 0x73, 0x10, 0x00, 0xC0, 0x72, 0x10, 0x00, -+0x6E, 0x6F, 0x61, 0x6C, 0x63, 0x62, 0x75, 0x66, 0x0A, 0x00, 0x00, 0x00, 0x62, 0x62, 0x5F, 0x74, 0x78, 0x5F, 0x74, 0x6F, -+0x6E, 0x65, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x6F, 0x70, 0x6D, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x6D, 0x73, 0x73, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x6D, 0x73, 0x73, 0x65, 0x72, 0x72, 0x0A, 0x00, 0x46, 0x4C, 0x55, 0x53, 0x48, 0x3A, 0x25, 0x78, -+0x0A, 0x00, 0x00, 0x00, 0x4C, 0x54, 0x4B, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x25, 0x78, 0x20, 0x00, 0x6F, 0x70, 0x63, 0x3A, -+0x25, 0x78, 0x0A, 0x00, 0x69, 0x20, 0x3D, 0x20, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x69, 0x3A, 0x25, 0x78, -+0x0A, 0x00, 0x00, 0x00, 0x6F, 0x70, 0x6C, 0x6C, 0x6D, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x1E, 0x8A, 0x10, 0x00, -+0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xBE, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, -+0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, -+0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, -+0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xDA, 0x89, 0x10, 0x00, 0xDA, 0x89, 0x10, 0x00, -+0xFC, 0x89, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, -+0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, -+0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, -+0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, -+0xDA, 0x89, 0x10, 0x00, 0xDA, 0x89, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, -+0xF4, 0x8A, 0x10, 0x00, 0x4C, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xE8, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, -+0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, 0xF4, 0x8A, 0x10, 0x00, -+0xF4, 0x8A, 0x10, 0x00, 0x62, 0x8A, 0x10, 0x00, 0x55, 0x50, 0x3A, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x2C, -+0x25, 0x78, 0x0A, 0x00, 0x6F, 0x70, 0x6C, 0x6C, 0x63, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0x63, 0x72, -+0x78, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0x63, 0x74, 0x6D, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, -+0x61, 0x70, 0x63, 0x66, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x61, 0x74, 0x65, 0x6E, 0x63, 0x79, 0x0A, -+0x00, 0x00, 0x00, 0x00, 0x72, 0x66, 0x5F, 0x72, 0x65, 0x73, 0x65, 0x74, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0x45, 0x52, 0x52, 0x3A, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x2C, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x41, 0x53, 0x53, 0x45, -+0x52, 0x54, 0x5F, 0x57, 0x41, 0x52, 0x4E, 0x49, 0x4E, 0x47, 0x28, 0x25, 0x73, 0x29, 0x2C, 0x20, 0x69, 0x6E, 0x20, 0x25, -+0x78, 0x20, 0x61, 0x74, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x41, 0x53, 0x53, 0x45, -+0x52, 0x54, 0x5F, 0x45, 0x52, 0x52, 0x7A, 0x28, 0x25, 0x73, 0x29, 0x2C, 0x20, 0x69, 0x6E, 0x20, 0x25, 0x78, 0x20, 0x61, -+0x74, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x5F, 0x50, -+0x41, 0x52, 0x41, 0x4D, 0x7A, 0x28, 0x30, 0x78, 0x25, 0x58, 0x2C, 0x20, 0x30, 0x78, 0x25, 0x58, 0x29, 0x2C, 0x20, 0x69, -+0x6E, 0x20, 0x25, 0x78, 0x20, 0x61, 0x74, 0x20, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, -+0x70, 0x61, 0x67, 0x65, 0x5F, 0x73, 0x74, 0x61, 0x72, 0x74, 0x0A, 0x00, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x25, -+0x78, 0x0D, 0x0A, 0x00, 0x64, 0x65, 0x6C, 0x20, 0x6B, 0x65, 0x79, 0x20, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0x6F, 0x70, 0x3A, 0x30, 0x78, 0x25, 0x78, 0x20, 0x30, 0x78, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6E, -+0x5F, 0x65, 0x6E, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x63, 0x68, 0x65, 0x72, 0x72, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, -+0x74, 0x65, 0x73, 0x74, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x5F, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3A, 0x25, 0x78, 0x0A, 0x00, -+0x74, 0x65, 0x73, 0x74, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x5F, 0x65, 0x78, 0x69, 0x74, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, -+0x74, 0x73, 0x74, 0x5F, 0x65, 0x6E, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x5F, 0x62, 0x62, 0x5F, 0x74, 0x73, -+0x74, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x65, 0x64, 0x72, 0x5F, -+0x70, 0x6B, 0x74, 0x3D, 0x25, 0x78, 0x00, 0x00, 0x66, 0x72, 0x65, 0x71, 0x25, 0x78, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0xC0, 0xB8, 0x10, 0x00, 0xB4, 0xB9, 0x10, 0x00, 0x94, 0xBA, 0x10, 0x00, 0xF2, 0xB8, 0x10, 0x00, 0xB0, 0xBA, 0x10, 0x00, -+0xCC, 0xBA, 0x10, 0x00, 0xE8, 0xBA, 0x10, 0x00, 0x04, 0xBB, 0x10, 0x00, 0x70, 0x6F, 0x3A, 0x25, 0x34, 0x64, 0x2C, 0x20, -+0x73, 0x6F, 0x3A, 0x25, 0x34, 0x64, 0x2C, 0x20, 0x68, 0x65, 0x3A, 0x25, 0x34, 0x64, 0x2C, 0x20, 0x63, 0x65, 0x3A, 0x25, -+0x34, 0x64, 0x2C, 0x20, 0x6F, 0x65, 0x3A, 0x25, 0x34, 0x64, 0x2C, 0x20, 0x63, 0x6F, 0x6C, 0x65, 0x3A, 0x25, 0x34, 0x64, -+0x2C, 0x20, 0x70, 0x6E, 0x3A, 0x25, 0x34, 0x64, 0x20, 0x62, 0x63, 0x3A, 0x25, 0x37, 0x64, 0x2C, 0x20, 0x62, 0x65, 0x3A, -+0x25, 0x37, 0x64, 0x2C, 0x20, 0x70, 0x65, 0x72, 0x3A, 0x25, 0x64, 0x2E, 0x25, 0x64, 0x2C, 0x20, 0x62, 0x65, 0x72, 0x3A, -+0x25, 0x64, 0x2E, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x70, 0x6F, 0x3A, 0x25, 0x34, 0x64, 0x2C, 0x20, 0x73, 0x6F, 0x3A, 0x25, -+0x34, 0x64, 0x2C, 0x20, 0x68, 0x65, 0x3A, 0x25, 0x34, 0x64, 0x2C, 0x20, 0x63, 0x65, 0x3A, 0x25, 0x34, 0x64, 0x2C, 0x20, -+0x62, 0x63, 0x3A, 0x25, 0x37, 0x64, 0x2C, 0x20, 0x62, 0x65, 0x3A, 0x25, 0x37, 0x64, 0x2C, 0x20, 0x70, 0x65, 0x72, 0x3A, -+0x25, 0x64, 0x2E, 0x25, 0x64, 0x2C, 0x20, 0x62, 0x65, 0x72, 0x3A, 0x25, 0x64, 0x2E, 0x25, 0x64, 0x0D, 0x0A, 0x00, 0x00, -+0x6C, 0x64, 0x5F, 0x62, 0x62, 0x5F, 0x62, 0x75, 0x72, 0x73, 0x74, 0x5F, 0x74, 0x78, 0x5F, 0x73, 0x74, 0x61, 0x72, 0x74, -+0x0A, 0x00, 0x00, 0x00, 0x72, 0x78, 0x61, 0x62, 0x6F, 0x72, 0x74, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x73, 0x63, 0x68, 0x5F, -+0x70, 0x72, 0x6F, 0x67, 0x5F, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, -+0x6C, 0x64, 0x5F, 0x62, 0x62, 0x5F, 0x72, 0x78, 0x5F, 0x74, 0x73, 0x74, 0x5F, 0x73, 0x74, 0x61, 0x72, 0x74, 0x0A, 0x00, -+0x74, 0x78, 0x5F, 0x74, 0x73, 0x74, 0x0A, 0x00, 0x72, 0x78, 0x5F, 0x74, 0x73, 0x74, 0x0A, 0x00, 0x62, 0x62, 0x5F, 0x74, -+0x73, 0x74, 0x5F, 0x73, 0x74, 0x6F, 0x70, 0x3A, 0x25, 0x78, 0x0A, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -+0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -+0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x02, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0x03, 0x00, 0x00, 0xFF, 0xC1, 0xFB, 0xE8, 0x4C, 0x90, 0x72, 0x8B, -+0xE7, 0xB3, 0x51, 0x89, 0x63, 0xAB, 0x23, 0x23, 0x02, 0x84, 0x18, 0x72, 0xAA, 0x61, 0x2F, 0x3B, 0x51, 0xA8, 0xE5, 0x37, -+0x49, 0xFB, 0xC9, 0xCA, 0x0C, 0x18, 0x53, 0x2C, 0xFD, 0x45, 0xE3, 0x9A, 0xE6, 0xF1, 0x5D, 0xB0, 0xB6, 0x1B, 0xB4, 0xBE, -+0x2A, 0x50, 0xEA, 0xE9, 0x0E, 0x9C, 0x4B, 0x5E, 0x57, 0x24, 0xCC, 0xA1, 0xB7, 0x59, 0xB8, 0x87, 0xFF, 0xE0, 0x7D, 0x74, -+0x26, 0x48, 0xB9, 0xC5, 0xF3, 0xD9, 0xA8, 0xC4, 0xB1, 0xD5, 0x91, 0x11, 0x01, 0x42, 0x0C, 0x39, 0xD5, 0xB0, 0x97, 0x9D, -+0x28, 0xD4, 0xF2, 0x9B, 0xA4, 0xFD, 0x64, 0x65, 0x06, 0x8C, 0x29, 0x96, 0xFE, 0xA2, 0x71, 0x4D, 0xF3, 0xF8, 0x2E, 0x58, -+0xDB, 0x0D, 0x5A, 0x5F, 0x15, 0x28, 0xF5, 0x74, 0x07, 0xCE, 0x25, 0xAF, 0x2B, 0x12, 0xE6, 0xD0, 0xDB, 0x2C, 0xDC, 0xC3, -+0x7F, 0xF0, 0x3E, 0x3A, 0x13, 0xA4, 0xDC, 0xE2, 0xF9, 0x6C, 0x54, 0xE2, 0xD8, 0xEA, 0xC8, 0x88, 0x00, 0x21, 0x86, 0x9C, -+0x6A, 0xD8, 0xCB, 0x4E, 0x14, 0x6A, 0xF9, 0x4D, 0xD2, 0x7E, 0xB2, 0x32, 0x03, 0xC6, 0x14, 0x4B, 0x7F, 0xD1, 0xB8, 0xA6, -+0x79, 0x7C, 0x17, 0xAC, 0xED, 0x06, 0xAD, 0xAF, 0x0A, 0x94, 0x7A, 0xBA, 0x03, 0xE7, 0x92, 0xD7, 0x15, 0x09, 0x73, 0xE8, -+0x6D, 0x16, 0xEE, 0xE1, 0x3F, 0x78, 0x1F, 0x9D, 0x09, 0x52, 0x6E, 0xF1, 0x7C, 0x36, 0x2A, 0x71, 0x6C, 0x75, 0x64, 0x44, -+0x80, 0x10, 0x43, 0x4E, 0x35, 0xEC, 0x65, 0x27, 0x0A, 0xB5, 0xFC, 0x26, 0x69, 0x3F, 0x59, 0x99, 0x01, 0x63, 0x8A, 0xA5, -+0xBF, 0x68, 0x5C, 0xD3, 0x3C, 0xBE, 0x0B, 0xD6, 0x76, 0x83, 0xD6, 0x57, 0x05, 0x4A, 0x3D, 0xDD, 0x81, 0x73, 0xC9, 0xEB, -+0x8A, 0x84, 0x39, 0xF4, 0x36, 0x0B, 0xF7, 0xF0, 0x1F, 0xBC, 0x8F, 0xCE, 0x04, 0x29, 0xB7, 0x78, 0x3E, 0x1B, 0x95, 0x38, -+0xB6, 0x3A, 0x32, 0x22, 0x40, 0x88, 0x21, 0xA7, 0x1A, 0xF6, 0xB2, 0x13, 0x85, 0x5A, 0x7E, 0x93, 0xB4, 0x9F, 0xAC, 0xCC, -+0x80, 0x31, 0xC5, 0xD2, 0x5F, 0x34, 0xAE, 0x69, 0x1E, 0xDF, 0x05, 0x6B, 0xBB, 0x41, 0xEB, 0xAB, 0x02, 0xA5, 0x9E, 0xEE, -+0xC0, 0xB9, 0xE4, 0x75, 0x45, 0xC2, 0x1C, 0x7A, 0x9B, 0x85, 0x7B, 0xF8, 0x0F, 0xDE, 0x47, 0x67, 0x82, 0x94, 0x5B, 0x3C, -+0x9F, 0x8D, 0x4A, 0x1C, 0x5B, 0x1D, 0x19, 0x11, 0x20, 0xC4, 0x90, 0x53, 0x0D, 0x7B, 0xD9, 0x89, 0x42, 0x2D, 0xBF, 0x49, -+0xDA, 0x4F, 0x56, 0x66, 0xC0, 0x98, 0x62, 0xE9, 0x2F, 0x1A, 0xD7, 0x34, 0x8F, 0xEF, 0x82, 0xB5, 0xDD, 0xA0, 0xF5, 0x55, -+0x81, 0x52, 0x4F, 0x77, 0xE0, 0x5C, 0xF2, 0xBA, 0x22, 0x61, 0x0E, 0xBD, 0xCD, 0xC2, 0x3D, 0xFC, 0x07, 0xEF, 0xA3, 0x33, -+0x41, 0xCA, 0x2D, 0x9E, 0xCF, 0x46, 0x25, 0x8E, 0xAD, 0x8E, 0x8C, 0x08, 0x10, 0x62, 0xC8, 0xA9, 0x86, 0xBD, 0xEC, 0x44, -+0xA1, 0x96, 0xDF, 0x24, 0xED, 0x27, 0x2B, 0x33, 0x60, 0x4C, 0xB1, 0xF4, 0x17, 0x8D, 0x6B, 0x9A, 0xC7, 0x77, 0xC1, 0xDA, -+0x6E, 0xD0, 0xFA, 0xAA, 0x40, 0xA9, 0xA7, 0x3B, 0x70, 0x2E, 0x79, 0x5D, 0x91, 0x30, 0x87, 0xDE, 0x66, 0xE1, 0x1E, 0xFE, -+0x83, 0xF7, 0xD1, 0x99, 0x20, 0xE5, 0x16, 0xCF, 0x67, 0xA3, 0x12, 0xC7, 0x56, 0x47, 0x46, 0x04, 0x08, 0x31, 0xE4, 0x54, -+0xC3, 0x5E, 0x76, 0xA2, 0x50, 0xCB, 0x6F, 0x92, 0xF6, 0x93, 0x95, 0x19, 0x30, 0xA6, 0x58, 0xFA, 0x8B, 0xC6, 0x35, 0xCD, -+0xE3, 0xBB, 0x60, 0x6D, 0x37, 0x68, 0x7D, 0x55, 0xA0, 0xD4, 0xD3, 0x1D, 0x38, 0x97, 0xBC, 0xAE, 0x48, 0x98, 0x43, 0x6F, -+0xB3, 0x70, 0x0F, 0xFF, 0xC1, 0xFB, 0xE8, 0x4C, 0x90, 0x72, 0x8B, 0xE7, 0xB3, 0x51, 0x89, 0x63, 0xAB, 0x23, 0x23, 0x02, -+0x84, 0x18, 0x72, 0xAA, 0x61, 0x2F, 0x3B, 0x51, 0xA8, 0xE5, 0x37, 0x49, 0xFB, 0xC9, 0xCA, 0x0C, 0x18, 0x53, 0x2C, 0xFD, -+0x45, 0xE3, 0x9A, 0xE6, 0xF1, 0x5D, 0xB0, 0xB6, 0x1B, 0xB4, 0xBE, 0x2A, 0x50, 0xEA, 0xE9, 0x0E, 0x9C, 0x4B, 0x5E, 0x57, -+0x24, 0xCC, 0xA1, 0xB7, 0x59, 0xB8, 0x87, 0xFF, 0xE0, 0x7D, 0x74, 0x26, 0x48, 0xB9, 0xC5, 0xF3, 0xD9, 0xA8, 0xC4, 0xB1, -+0xD5, 0x91, 0x11, 0x01, 0x42, 0x0C, 0x39, 0xD5, 0xB0, 0x97, 0x9D, 0x28, 0xD4, 0xF2, 0x9B, 0xA4, 0xFD, 0x64, 0x65, 0x06, -+0x8C, 0x29, 0x96, 0xFE, 0xA2, 0x71, 0x4D, 0xF3, 0xF8, 0x2E, 0x58, 0xDB, 0x0D, 0x5A, 0x5F, 0x15, 0x28, 0xF5, 0x74, 0x07, -+0xCE, 0x25, 0xAF, 0x2B, 0x12, 0xE6, 0xD0, 0xDB, 0x2C, 0xDC, 0xC3, 0x7F, 0xF0, 0x3E, 0x3A, 0x13, 0xA4, 0xDC, 0xE2, 0xF9, -+0x6C, 0x54, 0xE2, 0xD8, 0xEA, 0xC8, 0x88, 0x00, 0x21, 0x86, 0x9C, 0x6A, 0xD8, 0xCB, 0x4E, 0x14, 0x6A, 0xF9, 0x4D, 0xD2, -+0x7E, 0xB2, 0x32, 0x03, 0xC6, 0x14, 0x4B, 0x7F, 0xD1, 0xB8, 0xA6, 0x79, 0x7C, 0x17, 0xAC, 0xED, 0x06, 0xAD, 0xAF, 0x0A, -+0x94, 0x7A, 0xBA, 0x03, 0xE7, 0x92, 0xD7, 0x15, 0x09, 0x73, 0xE8, 0x6D, 0x16, 0xEE, 0xE1, 0x3F, 0x78, 0x1F, 0x9D, 0x09, -+0x52, 0x6E, 0xF1, 0x7C, 0x36, 0x2A, 0x71, 0x6C, 0x75, 0x64, 0x44, 0x80, 0x10, 0x43, 0x4E, 0x35, 0xEC, 0x65, 0x27, 0x0A, -+0xB5, 0xFC, 0x26, 0x69, 0x3F, 0x59, 0x99, 0x01, 0x63, 0x8A, 0xA5, 0xBF, 0x68, 0x5C, 0xD3, 0x3C, 0xBE, 0x0B, 0xD6, 0x76, -+0x83, 0xD6, 0x57, 0x05, 0x4A, 0x3D, 0xDD, 0x81, 0x73, 0xC9, 0xEB, 0x8A, 0x84, 0x39, 0xF4, 0x36, 0x0B, 0xF7, 0xF0, 0x1F, -+0xBC, 0x8F, 0xCE, 0x04, 0x29, 0xB7, 0x78, 0x3E, 0x1B, 0x95, 0x38, 0xB6, 0x3A, 0x32, 0x22, 0x40, 0x88, 0x21, 0xA7, 0x1A, -+0xF6, 0xB2, 0x13, 0x85, 0x5A, 0x7E, 0x93, 0xB4, 0x9F, 0xAC, 0xCC, 0x80, 0x31, 0xC5, 0xD2, 0x5F, 0x34, 0xAE, 0x69, 0x1E, -+0xDF, 0x05, 0x6B, 0xBB, 0x41, 0xEB, 0xAB, 0x02, 0xA5, 0x9E, 0xEE, 0xC0, 0xB9, 0xE4, 0x75, 0x45, 0xC2, 0x1C, 0x7A, 0x9B, -+0x85, 0x7B, 0xF8, 0x0F, 0xDE, 0x47, 0x67, 0x82, 0x94, 0x5B, 0x3C, 0x9F, 0x8D, 0x4A, 0x1C, 0x5B, 0x1D, 0x19, 0x11, 0x20, -+0xC4, 0x90, 0x53, 0x0D, 0x7B, 0xD9, 0x89, 0x42, 0x2D, 0xBF, 0x49, 0xDA, 0x4F, 0x56, 0x66, 0xC0, 0x98, 0x62, 0xE9, 0x2F, -+0x1A, 0xD7, 0x34, 0x8F, 0xEF, 0x82, 0xB5, 0xDD, 0xA0, 0xF5, 0x55, 0x81, 0x52, 0x4F, 0x77, 0xE0, 0x5C, 0xF2, 0xBA, 0x22, -+0x61, 0x0E, 0xBD, 0xCD, 0xC2, 0x3D, 0xFC, 0x07, 0xEF, 0xA3, 0x33, 0x41, 0xCA, 0x2D, 0x9E, 0xCF, 0x46, 0x25, 0x8E, 0xAD, -+0x8E, 0x8C, 0x08, 0x10, 0x62, 0xC8, 0xA9, 0x86, 0xBD, 0xEC, 0x44, 0xA1, 0x96, 0xDF, 0x24, 0xED, 0x27, 0x2B, 0x33, 0x60, -+0x4C, 0xB1, 0xF4, 0x17, 0x8D, 0x6B, 0x9A, 0xC7, 0x77, 0xC1, 0xDA, 0x6E, 0xD0, 0xFA, 0xAA, 0x40, 0xA9, 0xA7, 0x3B, 0x70, -+0x2E, 0x79, 0x5D, 0x91, 0x30, 0x87, 0xDE, 0x66, 0xE1, 0x1E, 0xFE, 0x83, 0xF7, 0xD1, 0x99, 0x20, 0xE5, 0x16, 0xCF, 0x67, -+0xA3, 0x12, 0xC7, 0x56, 0x47, 0x46, 0x04, 0x08, 0x31, 0xE4, 0x54, 0xC3, 0x5E, 0x76, 0xA2, 0x50, 0xCB, 0x6F, 0x92, 0xF6, -+0x93, 0x95, 0x19, 0x30, 0xA6, 0x58, 0xFA, 0x8B, 0xC6, 0x35, 0xCD, 0xE3, 0xBB, 0x60, 0x6D, 0x37, 0x68, 0x7D, 0x55, 0xA0, -+0xD4, 0xD3, 0x1D, 0x38, 0x97, 0xBC, 0xAE, 0x48, 0x98, 0x43, 0x6F, 0xB3, 0x70, 0x0F, 0xFF, 0xC1, 0xFF, 0xC1, 0xFB, 0xE8, -+0x4C, 0x90, 0x72, 0x8B, 0xE7, 0xB3, 0x51, 0x89, 0x63, 0xAB, 0x23, 0x23, 0x02, 0x84, 0x18, 0x72, 0xAA, 0x61, 0x2F, 0x3B, -+0x51, 0xA8, 0xE5, 0x37, 0x49, 0xFB, 0xC9, 0xCA, 0x0C, 0x18, 0x53, 0x2C, 0xFD, 0x45, 0xE3, 0x9A, 0xE6, 0xF1, 0x5D, 0xB0, -+0xB6, 0x1B, 0xB4, 0xBE, 0x2A, 0x50, 0xEA, 0xE9, 0x0E, 0x9C, 0x4B, 0x5E, 0x57, 0x24, 0xCC, 0xA1, 0xB7, 0x59, 0xB8, 0x87, -+0xFF, 0xE0, 0x7D, 0x74, 0x26, 0x48, 0xB9, 0xC5, 0xF3, 0xD9, 0xA8, 0xC4, 0xB1, 0xD5, 0x91, 0x11, 0x01, 0x42, 0x0C, 0x39, -+0xD5, 0xB0, 0x97, 0x9D, 0x28, 0xD4, 0xF2, 0x9B, 0xA4, 0xFD, 0x64, 0x65, 0x06, 0x8C, 0x29, 0x96, 0xFE, 0xA2, 0x71, 0x4D, -+0xF3, 0xF8, 0x2E, 0x58, 0xDB, 0x0D, 0x5A, 0x5F, 0x15, 0x28, 0xF5, 0x74, 0x07, 0xCE, 0x25, 0xAF, 0x2B, 0x12, 0xE6, 0xD0, -+0xDB, 0x2C, 0xDC, 0xC3, 0x7F, 0xF0, 0x3E, 0x3A, 0x13, 0xA4, 0xDC, 0xE2, 0xF9, 0x6C, 0x54, 0xE2, 0xD8, 0xEA, 0xC8, 0x88, -+0x00, 0x21, 0x86, 0x9C, 0x6A, 0xD8, 0xCB, 0x4E, 0x14, 0x6A, 0xF9, 0x4D, 0xD2, 0x7E, 0xB2, 0x32, 0x03, 0xC6, 0x14, 0x4B, -+0x7F, 0xD1, 0xB8, 0xA6, 0x79, 0x7C, 0x17, 0xAC, 0xED, 0x06, 0xAD, 0xAF, 0x0A, 0x94, 0x7A, 0xBA, 0x03, 0xE7, 0x92, 0xD7, -+0x15, 0x09, 0x73, 0xE8, 0x6D, 0x16, 0xEE, 0xE1, 0x3F, 0x78, 0x1F, 0x9D, 0x09, 0x52, 0x6E, 0xF1, 0x7C, 0x36, 0x2A, 0x71, -+0x6C, 0x75, 0x64, 0x44, 0x80, 0x10, 0x43, 0x4E, 0x35, 0xEC, 0x65, 0x27, 0x0A, 0xB5, 0xFC, 0x26, 0x69, 0x3F, 0x59, 0x99, -+0x01, 0x63, 0x8A, 0xA5, 0xBF, 0x68, 0x5C, 0xD3, 0x3C, 0xBE, 0x0B, 0xD6, 0x76, 0x83, 0xD6, 0x57, 0x05, 0x4A, 0x3D, 0xDD, -+0x81, 0x73, 0xC9, 0xEB, 0x8A, 0x84, 0x39, 0xF4, 0x36, 0x0B, 0xF7, 0xF0, 0x1F, 0xBC, 0x8F, 0xCE, 0x04, 0x29, 0xB7, 0x78, -+0x3E, 0x1B, 0x95, 0x38, 0xB6, 0x3A, 0x32, 0x22, 0x40, 0x88, 0x21, 0xA7, 0x1A, 0xF6, 0xB2, 0x13, 0x85, 0x5A, 0x7E, 0x93, -+0xB4, 0x9F, 0xAC, 0xCC, 0x80, 0x31, 0xC5, 0xD2, 0x5F, 0x34, 0xAE, 0x69, 0x1E, 0xDF, 0x05, 0x6B, 0xBB, 0x41, 0xEB, 0xAB, -+0x02, 0xA5, 0x9E, 0xEE, 0xC0, 0xB9, 0xE4, 0x75, 0x45, 0xC2, 0x1C, 0x7A, 0x9B, 0x85, 0x7B, 0xF8, 0x0F, 0xDE, 0x47, 0x67, -+0x82, 0x94, 0x5B, 0x3C, 0x9F, 0x8D, 0x4A, 0x1C, 0x5B, 0x1D, 0x19, 0x11, 0x20, 0xC4, 0x90, 0x53, 0x0D, 0x7B, 0xD9, 0x89, -+0x42, 0x2D, 0xBF, 0x49, 0xDA, 0x4F, 0x56, 0x66, 0xC0, 0x98, 0x62, 0xE9, 0x2F, 0x1A, 0xD7, 0x34, 0x8F, 0xEF, 0x82, 0xB5, -+0xDD, 0xA0, 0xF5, 0x55, 0x81, 0x52, 0x4F, 0x77, 0xE0, 0x5C, 0xF2, 0xBA, 0x22, 0x61, 0x0E, 0xBD, 0xCD, 0xC2, 0x3D, 0xFC, -+0x07, 0xEF, 0xA3, 0x33, 0x41, 0xCA, 0x2D, 0x9E, 0xCF, 0x46, 0x25, 0x8E, 0xAD, 0x8E, 0x8C, 0x08, 0x10, 0x62, 0xC8, 0xA9, -+0x86, 0xBD, 0xEC, 0x44, 0xA1, 0x96, 0xDF, 0x24, 0xED, 0x27, 0x2B, 0x33, 0x60, 0x4C, 0xB1, 0xF4, 0x17, 0x8D, 0x6B, 0x9A, -+0xC7, 0x77, 0xC1, 0xDA, 0x6E, 0xD0, 0xFA, 0xAA, 0x40, 0xA9, 0xA7, 0x3B, 0x70, 0x2E, 0x79, 0x5D, 0x91, 0x30, 0x87, 0xDE, -+0x66, 0xE1, 0x1E, 0xFE, 0x83, 0xF7, 0xD1, 0x99, 0x20, 0xE5, 0x16, 0xCF, 0x67, 0xA3, 0x12, 0xC7, 0x56, 0x47, 0x46, 0x04, -+0x08, 0x31, 0xE4, 0x54, 0xC3, 0x5E, 0x76, 0xA2, 0x50, 0xCB, 0x6F, 0x92, 0xF6, 0x93, 0x95, 0x19, 0x30, 0xA6, 0x58, 0xFA, -+0x8B, 0xC6, 0x35, 0xCD, 0xE3, 0xBB, 0x60, 0x6D, 0x37, 0x68, 0x7D, 0x55, 0xA0, 0xD4, 0xD3, 0x1D, 0x38, 0x97, 0xBC, 0xAE, -+0x48, 0x98, 0x43, 0x6F, 0xB3, 0x70, 0x0F, 0xFF, 0xC1, 0xFB, 0xE8, 0x4C, 0x90, 0x72, 0x8B, 0xE7, 0xB3, 0x51, 0x89, 0x63, -+0xAB, 0x23, 0x23, 0x02, 0x84, 0x18, 0x72, 0xAA, 0x61, 0x2F, 0x3B, 0x51, 0xA8, 0xE5, 0x37, 0x49, 0xFB, 0xC9, 0xCA, 0x0C, -+0x18, 0x53, 0x2C, 0xFD, 0x45, 0xE3, 0x9A, 0xE6, 0xF1, 0x5D, 0xB0, 0xB6, 0x1B, 0xB4, 0xBE, 0x2A, 0x50, 0xEA, 0xE9, 0x0E, -+0x9C, 0x4B, 0x5E, 0x57, 0x24, 0xCC, 0xA1, 0xB7, 0x59, 0xB8, 0x87, 0xFF, 0xE0, 0x7D, 0x74, 0x26, 0x48, 0xB9, 0xC5, 0xF3, -+0xD9, 0xA8, 0xC4, 0xB1, 0xD5, 0x91, 0x11, 0x01, 0x42, 0x0C, 0x39, 0xD5, 0xB0, 0x97, 0x9D, 0x28, 0xD4, 0xF2, 0x9B, 0xA4, -+0xFD, 0x64, 0x65, 0x06, 0x8C, 0x29, 0x96, 0xFE, 0xA2, 0x71, 0x4D, 0xF3, 0xF8, 0x2E, 0x58, 0xDB, 0x0D, 0x5A, 0x5F, 0x15, -+0x28, 0xF5, 0x74, 0x07, 0xCE, 0x25, 0xAF, 0x2B, 0x12, 0xE6, 0xD0, 0xDB, 0x2C, 0xDC, 0xC3, 0x7F, 0xF0, 0x3E, 0x3A, 0x13, -+0xA4, 0xDC, 0xE2, 0xF9, 0x6C, 0x54, 0xE2, 0xD8, 0xEA, 0xC8, 0x88, 0x00, 0x21, 0x86, 0x9C, 0x6A, 0xD8, 0xCB, 0x4E, 0x14, -+0x6A, 0xF9, 0x4D, 0xD2, 0x7E, 0xB2, 0x32, 0x03, 0xC6, 0x14, 0x4B, 0x7F, 0xD1, 0xB8, 0xA6, 0x79, 0x7C, 0x17, 0xAC, 0xED, -+0x06, 0xAD, 0xAF, 0x0A, 0x94, 0x7A, 0xBA, 0x03, 0xE7, 0x92, 0xD7, 0x15, 0x09, 0x73, 0xE8, 0x6D, 0x16, 0xEE, 0xE1, 0x3F, -+0x78, 0x1F, 0x9D, 0x09, 0x52, 0x6E, 0xF1, 0x7C, 0x36, 0x2A, 0x71, 0x6C, 0x75, 0x64, 0x44, 0x80, 0x10, 0x43, 0x4E, 0x35, -+0xEC, 0x65, 0x27, 0x0A, 0xB5, 0xFC, 0x26, 0x69, 0x3F, 0x59, 0x99, 0x01, 0x63, 0x8A, 0xA5, 0xBF, 0x68, 0x5C, 0xD3, 0x3C, -+0xBE, 0x0B, 0xD6, 0x76, 0x83, 0xD6, 0x57, 0x05, 0x4A, 0x3D, 0xDD, 0x81, 0x73, 0xC9, 0xEB, 0x8A, 0x84, 0x39, 0xF4, 0x36, -+0x0B, 0xF7, 0xF0, 0x1F, 0xBC, 0x8F, 0xCE, 0x04, 0x29, 0xB7, 0x78, 0x3E, 0x1B, 0x95, 0x38, 0xB6, 0x3A, 0x32, 0x22, 0x40, -+0x88, 0x21, 0xA7, 0x1A, 0xF6, 0xB2, 0x13, 0x85, 0x5A, 0x7E, 0x93, 0xB4, 0x9F, 0xAC, 0xCC, 0x80, 0x31, 0xC5, 0xD2, 0x5F, -+0x34, 0xAE, 0x69, 0x1E, 0xDF, 0x05, 0x6B, 0xBB, 0x41, 0xEB, 0xAB, 0x02, 0xA5, 0x9E, 0xEE, 0xC0, 0xB9, 0xE4, 0x75, 0x45, -+0xC2, 0x1C, 0x7A, 0x9B, 0x85, 0x7B, 0xF8, 0x0F, 0xDE, 0x47, 0x67, 0x82, 0x94, 0x5B, 0x3C, 0x9F, 0x8D, 0x4A, 0x1C, 0x5B, -+0x1D, 0x19, 0x11, 0x20, 0xC4, 0x90, 0x53, 0x0D, 0x7B, 0xD9, 0x89, 0x42, 0x2D, 0xBF, 0x49, 0xDA, 0x4F, 0x56, 0x66, 0xC0, -+0x98, 0x62, 0xE9, 0x2F, 0x1A, 0xD7, 0x34, 0x8F, 0xEF, 0x82, 0xB5, 0xDD, 0xA0, 0xF5, 0x55, 0x81, 0x52, 0x4F, 0x77, 0xE0, -+0x5C, 0xF2, 0xBA, 0x22, 0x61, 0x0E, 0xBD, 0xCD, 0xC2, 0x3D, 0xFC, 0x07, 0xEF, 0xA3, 0x33, 0x41, 0xCA, 0x2D, 0x9E, 0xCF, -+0x46, 0x25, 0x8E, 0xAD, 0x8E, 0x8C, 0x08, 0x10, 0x62, 0xC8, 0xA9, 0x86, 0xBD, 0xEC, 0x44, 0xA1, 0x96, 0xDF, 0x24, 0xED, -+0x27, 0x2B, 0x33, 0x60, 0x4C, 0xB1, 0xF4, 0x17, 0x8D, 0x6B, 0x9A, 0xC7, 0x77, 0xC1, 0xDA, 0x6E, 0xD0, 0xFA, 0xAA, 0x40, -+0xA9, 0xA7, 0x3B, 0x70, 0x2E, 0x79, 0x5D, 0x91, 0x30, 0x87, 0xDE, 0x66, 0xE1, 0x1E, 0xFE, 0x83, 0xF7, 0xD1, 0x99, 0x20, -+0xE5, 0x16, 0xCF, 0x67, 0xA3, 0x12, 0xC7, 0x56, 0x47, 0x46, 0x04, 0x08, 0x31, 0xE4, 0x54, 0xC3, 0x5E, 0x76, 0xA2, 0x50, -+0xCB, 0x6F, 0x92, 0xF6, 0x93, 0x95, 0x19, 0x30, 0xA6, 0x58, 0xFA, 0x8B, 0xC6, 0x35, 0xCD, 0xE3, 0xBB, 0x60, 0x6D, 0x37, -+0x68, 0x7D, 0x55, 0xA0, 0xD4, 0xD3, 0x1D, 0x38, 0x97, 0xBC, 0xAE, 0x48, 0x98, 0x43, 0x6F, 0xB3, 0x70, 0x0F, 0xFF, 0xC1, -+0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x01, 0x02, 0x02, 0x03, -+0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, -+0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, -+0x04, 0x05, 0x05, 0x06, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, -+0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x02, 0x03, 0x03, 0x04, -+0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, -+0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, -+0x03, 0x04, 0x04, 0x05, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, -+0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x03, 0x04, 0x04, 0x05, -+0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, -+0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, -+0x05, 0x06, 0x06, 0x07, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, -+0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x05, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x08, 0x00, 0x10, 0x20, 0x30, -+0x40, 0x50, 0x60, 0x70, 0x00, 0x00, 0x01, 0x50, 0x00, 0x03, 0x04, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x50, -+0x00, 0x02, 0x07, 0x03, 0x0C, 0x04, 0x0D, 0x05, 0x26, 0x06, 0x37, 0x07, 0x2C, 0x08, 0x3D, 0x09, 0x00, 0x00, 0x02, 0x01, -+0x05, 0x00, 0x01, 0x07, 0x00, 0x01, 0x00, 0x00, 0x01, 0x07, 0x00, 0x01, 0x0C, 0x00, 0x03, 0x0D, 0x00, 0x03, 0x06, 0x01, -+0x01, 0x07, 0x01, 0x01, 0x0C, 0x01, 0x03, 0x0D, 0x01, 0x03, 0x00, 0x00, 0x00, 0x27, 0x35, 0x00, 0x2B, 0x00, 0x31, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x22, 0x10, 0x00, 0xFF, 0xF0, 0xAA, 0xFF, 0xFF, 0x00, 0x0F, 0x55, -+0x80, 0x01, 0x00, 0x00, 0xF6, 0xFC, 0xFE, 0x00, 0x03, 0x06, 0x09, 0x0A, 0xF9, 0xFC, 0xFF, 0x02, 0x05, 0x07, 0x09, 0x0C, -+0x0F, 0x11, 0x15, 0x17, 0x50, 0x00, 0x00, 0x00, 0xE4, 0x57, 0x00, 0x00, 0x50, 0xC3, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, -+0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x24, 0x10, 0x04, 0x00, 0x0C, 0x21, 0x04, 0x25, -+0x00, 0x80, 0xDE, 0xA9, 0x91, 0x06, 0x7B, 0x00, 0x04, 0x10, 0x04, 0x00, 0x04, 0x00, 0x00, 0x26, 0x00, 0x80, 0xDE, 0xA9, -+0x65, 0x06, 0x7C, 0x00, 0x04, 0xF0, 0x03, 0x00, 0x3C, 0xE7, 0x1C, 0x24, 0x09, 0x80, 0xDE, 0xA9, 0x69, 0x06, 0x7C, 0x48, -+0x04, 0x10, 0x04, 0x00, 0xF8, 0xFF, 0x7F, 0x24, 0x17, 0x42, 0x40, 0x40, 0x8D, 0x08, 0x7B, 0xB0, 0x14, 0x10, 0x04, 0x00, -+0x0C, 0x21, 0x84, 0x27, 0x00, 0x80, 0xDE, 0xA9, 0x91, 0x46, 0x7B, 0x03, 0x04, 0x10, 0x04, 0x00, 0x0C, 0x21, 0x04, 0x26, -+0x00, 0x80, 0xDE, 0xA9, 0x81, 0x06, 0x7B, 0x03, 0x04, 0xF0, 0x03, 0x00, 0x3C, 0xE7, 0x1C, 0x24, 0x09, 0x80, 0xDE, 0xA9, -+0x69, 0x06, 0x7C, 0x4B, 0x04, 0x10, 0x04, 0x00, 0xF8, 0xFF, 0xFF, 0x27, 0x17, 0x42, 0x40, 0x40, 0xFD, 0x08, 0x7A, 0xB0, -+0x14, 0x10, 0x04, 0x00, 0x0C, 0x21, 0x84, 0x27, 0x00, 0x80, 0xDE, 0xA9, 0x91, 0x46, 0x7B, 0x03, 0x04, 0x10, 0x04, 0x00, -+0x0C, 0x21, 0x04, 0x26, 0x00, 0x80, 0xDE, 0xA9, 0x81, 0x06, 0x7B, 0x03, 0x04, 0xF0, 0x03, 0x00, 0x3C, 0xE7, 0x1C, 0x24, -+0x09, 0x80, 0xDE, 0xA9, 0x69, 0x06, 0x7C, 0x4B, 0x04, 0x10, 0x04, 0x00, 0xF8, 0xFF, 0xFF, 0x27, 0x17, 0x42, 0x40, 0x40, -+0xFD, 0x08, 0x7A, 0xB0, 0x14, 0x10, 0x04, 0x00, 0x0C, 0x21, 0x84, 0x27, 0x00, 0x80, 0xDE, 0xA9, 0x91, 0x46, 0x7B, 0x03, -+0x04, 0x10, 0x04, 0x00, 0x0C, 0x21, 0x04, 0x26, 0x00, 0x80, 0xDE, 0xA9, 0x81, 0x06, 0x7B, 0x03, 0x04, 0xF0, 0x03, 0x00, -+0x3C, 0xE7, 0x1C, 0x24, 0x09, 0x80, 0xDE, 0xA9, 0x69, 0x06, 0x7C, 0x4B, 0x04, 0x10, 0x04, 0x00, 0xF8, 0xFF, 0xFF, 0x27, -+0x17, 0x42, 0x40, 0x40, 0xFD, 0x08, 0x7A, 0xB0, 0xD0, 0x9E, 0x21, 0x00, 0x1C, 0x1C, 0xFB, 0x41, 0xD4, 0x9E, 0x21, 0x00, -+0x1C, 0x1C, 0xFB, 0x41, 0xD4, 0x9E, 0x21, 0x00, 0x70, 0x70, 0xFB, 0x41, 0xD4, 0x9E, 0x21, 0x00, 0x70, 0x70, 0xFB, 0x61, -+0xD6, 0x9E, 0x21, 0x00, 0x70, 0x70, 0xFB, 0x65, 0xD7, 0x9E, 0x21, 0x00, 0x70, 0x70, 0xFB, 0x75, 0xD7, 0x9E, 0x21, 0x00, -+0x70, 0x70, 0xFB, 0xFD, 0xD7, 0x9E, 0x21, 0x00, 0xF0, 0xF0, 0xFB, 0xFD, 0xD7, 0x9D, 0x21, 0x00, 0xF0, 0xF0, 0x87, 0xFD, -+0xD7, 0x9D, 0x21, 0x00, 0xF0, 0xF0, 0x87, 0xFD, 0xD7, 0x9D, 0x21, 0x00, 0xF0, 0xF0, 0x87, 0xFD, 0xD7, 0x9D, 0x21, 0x00, -+0xF0, 0xF0, 0x87, 0xFD, 0xD7, 0x9D, 0x21, 0x00, 0xF0, 0xF0, 0x87, 0xFD, 0xD7, 0x9D, 0x21, 0x00, 0xF0, 0xF0, 0x87, 0xFD, -+0xD7, 0x9D, 0x21, 0x00, 0xF0, 0xF0, 0x87, 0xFD, 0xD7, 0x9D, 0x21, 0x00, 0xF0, 0xF0, 0x87, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, -+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0B, 0x00, 0x00, 0x04, 0x00, 0x00, 0xB8, 0x0B, 0x00, 0x00, 0xFF, 0xF9, 0x01, 0x08, -+0x00, 0x00, 0x00, 0x00, 0xAC, 0x2B, 0x16, 0x00, 0x04, 0x00, 0x00, 0x00, 0x28, 0x21, 0x16, 0x00, 0xA8, 0x61, 0x00, 0x00, -+0xB8, 0x88, 0x00, 0x00, 0x74, 0x40, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, -+0x80, 0x80, 0x80, 0x80, 0x22, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x1B, 0x60, 0x07, 0xED, 0x79, 0x80, 0x80, 0x80, 0x80, -+0x34, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x5B, 0x60, 0x07, 0xCD, 0x79, 0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x55, 0x00, -+0x6C, 0x00, 0x0F, 0x5B, 0x60, 0x07, 0xAD, 0x79, 0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x5B, -+0x60, 0x07, 0x8D, 0x79, 0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x5B, 0x60, 0x07, 0x0D, 0x79, -+0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x5B, 0x60, 0x07, 0x8D, 0x78, 0x80, 0x80, 0x80, 0x80, -+0x6B, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x1B, 0x60, 0x07, 0x8D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x58, 0x3E, 0x55, 0x00, -+0x6C, 0x00, 0x0F, 0xDB, 0x60, 0x07, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x22, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x1B, -+0x60, 0xD7, 0x0C, 0x78, 0x80, 0x80, 0x80, 0x80, 0x22, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x1B, 0x60, 0x1F, 0x0D, 0x78, -+0x80, 0x80, 0x80, 0x80, 0x22, 0x3E, 0x55, 0x00, 0x6D, 0x0C, 0x2F, 0x1B, 0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, -+0x58, 0x3E, 0x55, 0x00, 0x6D, 0x0C, 0x2F, 0xDB, 0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0xD8, 0x3E, 0x55, 0x00, -+0x6D, 0x0C, 0x2F, 0xDB, 0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0xEB, 0x3E, 0x55, 0x00, 0x6D, 0x0C, 0x2F, 0x1B, -+0x60, 0x9F, 0x0D, 0x68, 0x80, 0x80, 0x80, 0x80, 0x6B, 0x3F, 0x55, 0x00, 0x6D, 0x0C, 0x2F, 0x1B, 0x60, 0x9F, 0x0D, 0x68, -+0x80, 0x80, 0x80, 0x80, 0xEB, 0x3F, 0x55, 0x00, 0x6D, 0x0C, 0x2F, 0x1B, 0x60, 0x9F, 0x0D, 0x68, 0x80, 0x80, 0x80, 0x80, -+0x22, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x1B, 0x60, 0x07, 0xED, 0x79, 0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x55, 0x00, -+0x6C, 0x00, 0x0F, 0x5B, 0x60, 0x07, 0xCD, 0x79, 0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x5B, -+0x60, 0x07, 0xAD, 0x79, 0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x5B, 0x60, 0x07, 0x8D, 0x79, -+0x80, 0x80, 0x80, 0x80, 0x34, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x5B, 0x60, 0x07, 0x0D, 0x79, 0x80, 0x80, 0x80, 0x80, -+0x34, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x5B, 0x60, 0x07, 0x8D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x6B, 0x3E, 0x55, 0x00, -+0x6C, 0x00, 0x0F, 0x1B, 0x60, 0x07, 0x8D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x58, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0xDB, -+0x60, 0x07, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x22, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x1B, 0x60, 0xD7, 0x0C, 0x78, -+0x80, 0x80, 0x80, 0x80, 0x22, 0x3E, 0x55, 0x00, 0x6C, 0x00, 0x0F, 0x1B, 0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, -+0x22, 0x3E, 0x55, 0x00, 0x6D, 0x0C, 0x2F, 0x1B, 0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x58, 0x3E, 0x55, 0x00, -+0x6D, 0x0C, 0x2F, 0xDB, 0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0xD8, 0x3E, 0x55, 0x00, 0x6D, 0x0C, 0x2F, 0xDB, -+0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0xEB, 0x3E, 0x55, 0x00, 0x6D, 0x0C, 0x2F, 0x1B, 0x60, 0x9F, 0x0D, 0x68, -+0x80, 0x80, 0x80, 0x80, 0x6B, 0x3F, 0x55, 0x00, 0x6D, 0x0C, 0x2F, 0x1B, 0x60, 0x9F, 0x0D, 0x68, 0x80, 0x80, 0x80, 0x80, -+0xEB, 0x3F, 0x55, 0x00, 0x6D, 0x0C, 0x2F, 0x1B, 0x60, 0x9F, 0x0D, 0x68, 0x80, 0x80, 0x80, 0x80, 0x00, 0x94, 0x7F, 0x00, -+0x6C, 0x00, 0x00, 0x03, 0x60, 0x07, 0xAC, 0xE9, 0x80, 0x80, 0x80, 0x80, 0x00, 0x94, 0x7F, 0x00, 0x6C, 0x00, 0x00, 0x03, -+0x60, 0x07, 0x0C, 0xE8, 0x80, 0x80, 0x80, 0x80, 0x00, 0x94, 0x7F, 0x00, 0x6C, 0x00, 0x20, 0x03, 0x60, 0xD7, 0x0C, 0xE8, -+0x80, 0x80, 0x80, 0x80, 0x00, 0x94, 0x7F, 0x00, 0x6C, 0x00, 0xE0, 0x03, 0x60, 0x9F, 0x0D, 0xE8, 0x80, 0x80, 0x80, 0x80, -+0x00, 0xBE, 0x7F, 0x00, 0x6C, 0x00, 0x0F, 0x1B, 0x60, 0xE7, 0x8C, 0x69, 0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, -+0xFC, 0x00, 0x6F, 0x1B, 0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x12, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0xEF, 0x5B, -+0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x6D, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0xEF, 0x9B, 0x60, 0x9F, 0x0D, 0x68, -+0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0x2F, 0x1B, 0x60, 0x87, 0xEC, 0x79, 0x80, 0x80, 0x80, 0x80, -+0x00, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0x6F, 0x1B, 0x60, 0x87, 0xEC, 0x79, 0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, -+0xFC, 0x00, 0x6F, 0x1B, 0x60, 0x07, 0xAD, 0x79, 0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0x6F, 0x1B, -+0x60, 0x07, 0x0D, 0x79, 0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0x6F, 0x1B, 0x60, 0x07, 0x0D, 0x78, -+0x80, 0x80, 0x80, 0x80, 0x00, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0x6F, 0x1B, 0x60, 0x17, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, -+0x12, 0x3E, 0x55, 0x00, 0xFC, 0x00, 0xEF, 0x5B, 0x60, 0x1F, 0x0D, 0x78, 0x80, 0x80, 0x80, 0x80, 0x6D, 0x3E, 0x55, 0x00, -+0xFC, 0x00, 0xEF, 0x9B, 0x60, 0x9F, 0x0D, 0x68, 0x03, 0xC7, 0x8E, 0x00, 0x07, 0xC7, 0x8E, 0x00, 0x0B, 0xC7, 0x8E, 0x00, -+0x0F, 0xC7, 0x8E, 0x00, 0x13, 0xC7, 0x8E, 0x00, 0x17, 0xC7, 0x8E, 0x00, 0x1B, 0xC7, 0x8E, 0x00, 0x1F, 0xC7, 0x8E, 0x00, -+0x23, 0xC7, 0x8E, 0x00, 0x27, 0xC7, 0x8E, 0x00, 0x2B, 0xC7, 0x8E, 0x00, 0x2F, 0xC7, 0x8E, 0x00, 0x33, 0xC7, 0x8E, 0x00, -+0x37, 0xC7, 0x8E, 0x00, 0x3B, 0xC7, 0x8E, 0x00, 0x3F, 0xC7, 0x8E, 0x00, 0x06, 0x81, 0x88, 0x00, 0x0A, 0x81, 0x88, 0x00, -+0x0C, 0xC1, 0x88, 0x00, 0x14, 0xC1, 0x90, 0x00, 0x14, 0x41, 0x91, 0x00, 0x15, 0xC1, 0x91, 0x00, 0x23, 0xC1, 0x91, 0x00, -+0x3F, 0xC1, 0x91, 0x00, 0x3F, 0xC1, 0x92, 0x00, 0x3F, 0x01, 0x94, 0x00, 0x3F, 0xC1, 0x96, 0x00, 0x3F, 0xC1, 0x96, 0x00, -+0x3F, 0xC1, 0x96, 0x00, 0x3F, 0xC1, 0x96, 0x00, 0x3F, 0xC1, 0x96, 0x00, 0x3F, 0xC1, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x2D, 0x20, 0x53, 0x65, 0x70, 0x20, 0x31, 0x33, 0x20, 0x32, 0x30, 0x32, 0x32, 0x20, 0x31, 0x30, 0x3A, 0x33, 0x38, 0x3A, -+0x33, 0x39, 0x20, 0x2D, 0x20, 0x67, 0x69, 0x74, 0x20, 0x30, 0x61, 0x61, 0x62, 0x66, 0x62, 0x66, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+0x00, 0x00, 0x00, 0x00, -+}; -+ -+struct firmware_info{ -+ char fw_name[30]; -+ char* fw_array; -+ int fw_size; -+}; -+ -+struct firmware_info firmware[]={ -+ {"fmacfw.bin", fmacfw, sizeof(fmacfw)}, -+ {"fw_adid_u03.bin", fw_adid_u03, sizeof(fw_adid_u03)}, -+ {"fw_patch_table_u03.bin", fw_patch_table_u03, sizeof(fw_patch_table_u03)}, -+ {"fw_patch_u03.bin", fw_patch_u03, sizeof(fw_patch_u03)} -+}; -+ -+int aicwf_get_firmware_array(char* fw_name, u32 **fw_buf){ -+ int firmware_number = 0; -+ int index = 0; -+ int fw_size = 0; -+ -+ firmware_number = sizeof(firmware)/sizeof(struct firmware_info); -+ printk("%s search:%s \r\n", __func__ , fw_name); -+ -+ for(index = 0; index < firmware_number; index++){ -+ if(!strcmp(firmware[index].fw_name, fw_name)){ -+ fw_size = firmware[index].fw_size; -+ printk("%s find %s len:%d\r\n", __func__, fw_name, fw_size); -+ *fw_buf = (u32*)firmware[index].fw_array; -+ return fw_size; -+ } -+ } -+ -+ printk("%s %s not found \r\n", __func__, fw_name); -+ -+ return 0; -+} -\ No newline at end of file -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_firmware_array.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_firmware_array.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_firmware_array.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_firmware_array.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,3 @@ -+int aicwf_get_firmware_array(char* fw_name, u32 **fw_buf); -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_txq_prealloc.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_txq_prealloc.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_txq_prealloc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_txq_prealloc.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,62 @@ -+#include -+#include "aicsdio_txrxif.h" -+#include "aic_bsp_driver.h" -+ -+struct prealloc_txq{ -+ int prealloced; -+ void *txq; -+ size_t size; -+}; -+ -+struct prealloc_txq prealloc_txq; -+#define MAX_TXQ_SIZE 100 * 1024 -+ -+void *aicwf_prealloc_txq_alloc(size_t size) -+{ -+ -+ BUG_ON(size > MAX_TXQ_SIZE); -+ -+ //check prealloc_txq.size -+ if((int)prealloc_txq.size != (int)size) -+ { -+ AICWFDBG(LOGINFO, "%s size is diff will to be kzalloc \r\n", __func__); -+ -+ if(prealloc_txq.txq != NULL) -+ { -+ AICWFDBG(LOGINFO, "%s txq to kfree \r\n", __func__); -+ kfree(prealloc_txq.txq); -+ prealloc_txq.txq = NULL; -+ } -+ -+ prealloc_txq.size = size; -+ prealloc_txq.prealloced = 0; -+ } -+ -+ //check prealloc or not -+ if(!prealloc_txq.prealloced) -+ { -+ prealloc_txq.txq = kzalloc(size, GFP_KERNEL); -+ if(!prealloc_txq.txq){ -+ AICWFDBG(LOGERROR, "%s txq kzalloc fail \r\n", __func__); -+ }else{ -+ AICWFDBG(LOGINFO, "%s txq kzalloc successful \r\n", __func__); -+ prealloc_txq.prealloced = 1; -+ } -+ }else{ -+ AICWFDBG(LOGINFO, "%s txq not need to kzalloc \r\n", __func__); -+ } -+ -+ return prealloc_txq.txq; -+} -+void aicwf_prealloc_txq_free(void) -+{ -+ if(prealloc_txq.txq != NULL) -+ { -+ AICWFDBG(LOGINFO, "%s txq to kfree \r\n", __func__); -+ kfree(prealloc_txq.txq); -+ prealloc_txq.txq = NULL; -+ } -+} -+ -+EXPORT_SYMBOL(aicwf_prealloc_txq_alloc); -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_txq_prealloc.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_txq_prealloc.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_txq_prealloc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aicwf_txq_prealloc.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,4 @@ -+ -+ -+void aicwf_prealloc_txq_free(void); -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/.gitignore linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/.gitignore ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/.gitignore 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/.gitignore 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,10 @@ -+*.o -+*.ko -+*.order -+*.symvers -+*.o.d -+*.o.cmd -+*.ko.cmd -+*.mod -+*.mod.c -+*.mod.cmd -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/Makefile linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/Makefile ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/Makefile 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,136 @@ -+CONFIG_SDIO_SUPPORT := y -+CONFIG_SDIO_PWRCTRL := y -+CONFIG_AIC_FW_PATH = "/vendor/etc/firmware" -+#CONFIG_AIC_FW_PATH = "/lib/firmware/aic8800" -+export CONFIG_AIC_FW_PATH -+ccflags-y += -DCONFIG_AIC_FW_PATH=\"$(CONFIG_AIC_FW_PATH)\" -+ -+MODULE_NAME := aic8800_bsp -+ifeq ($(CONFIG_SDIO_SUPPORT), y) -+ccflags-y += -DAICWF_SDIO_SUPPORT -+ccflags-$(CONFIG_SDIO_PWRCTRL) += -DCONFIG_SDIO_PWRCTRL -+endif -+ -+CONFIG_GPIO_WAKEUP ?= n -+CONFIG_M2D_OTA_AUTO_SUPPORT = n -+CONFIG_M2D_OTA_LZMA_SUPPORT = n -+CONFIG_LINK_DET_5G = y -+CONFIG_MCU_MESSAGE = n -+CONFIG_FIRMWARE_ARRAY = n -+# Need to set fw path in BOARD_KERNEL_CMDLINE -+CONFIG_USE_FW_REQUEST ?= n -+CONFIG_FDRV_NO_REG_SDIO = n -+CONFIG_VRF_DCDC_MODE = y -+CONFIG_OOB ?= n -+CONFIG_PREALLOC_TXQ = y -+CONFIG_DPD = y -+CONFIG_FORCE_DPD_CALIB = y -+CONFIG_RESV_MEM_SUPPORT ?= y -+CONFIG_AMSDU_RX = n -+CONFIG_IRQ_FALL ?= n -+CONFIG_SDIO_BT = n -+ -+ccflags-$(CONFIG_GPIO_WAKEUP) += -DCONFIG_GPIO_WAKEUP -+ccflags-$(CONFIG_M2D_OTA_AUTO_SUPPORT) += -DCONFIG_M2D_OTA_AUTO_SUPPORT -+ccflags-$(CONFIG_M2D_OTA_LZMA_SUPPORT) += -DCONFIG_M2D_OTA_LZMA_SUPPORT -+ccflags-$(CONFIG_LINK_DET_5G) += -DCONFIG_LINK_DET_5G -+ccflags-$(CONFIG_MCU_MESSAGE) += -DCONFIG_MCU_MESSAGE -+ccflags-$(CONFIG_FIRMWARE_ARRAY) += -DCONFIG_FIRMWARE_ARRAY -+ccflags-$(CONFIG_USE_FW_REQUEST) += -DCONFIG_USE_FW_REQUEST -+ccflags-$(CONFIG_FDRV_NO_REG_SDIO) += -DCONFIG_FDRV_NO_REG_SDIO -+ccflags-$(CONFIG_VRF_DCDC_MODE) += -DCONFIG_VRF_DCDC_MODE -+ccflags-$(CONFIG_OOB) += -DCONFIG_OOB -+ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ -+ccflags-$(CONFIG_DPD) += -DCONFIG_DPD -+ccflags-$(CONFIG_FORCE_DPD_CALIB) += -DCONFIG_FORCE_DPD_CALIB -DCONFIG_DPD -+ccflags-$(CONFIG_RESV_MEM_SUPPORT) += -DCONFIG_RESV_MEM_SUPPORT -+ccflags-$(CONFIG_AMSDU_RX) += -DCONFIG_AMSDU_RX -+ccflags-$(CONFIG_IRQ_FALL) += -DCONFIG_IRQ_FALL -+ccflags-$(CONFIG_SDIO_BT) += -DCONFIG_SDIO_BT -+ -+obj-m := $(MODULE_NAME).o -+$(MODULE_NAME)-y := \ -+ aic8800dc_compat.o \ -+ aic8800d80_compat.o \ -+ aic_bsp_main.o \ -+ aic_bsp_driver.o \ -+ aicsdio.o \ -+ aicsdio_txrxif.o \ -+ md5.o -+ -+$(MODULE_NAME)-$(CONFIG_PREALLOC_TXQ) += aicwf_txq_prealloc.o -+ -+ifeq ($(CONFIG_FIRMWARE_ARRAY),y) -+$(MODULE_NAME)-y += aicwf_firmware_array.o -+endif -+ -+########## Platform support list ########## -+CONFIG_PLATFORM_ROCKCHIP ?= n -+CONFIG_PLATFORM_ROCKCHIP2 ?= n -+CONFIG_PLATFORM_ALLWINNER ?=n -+CONFIG_PLATFORM_INGENIC_T20 ?= n -+CONFIG_PLATFORM_AMLOGIC ?= n -+CONFIG_PLATFORM_UBUNTU ?= y -+ -+ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y) -+ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP -+KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel -+ARCH ?= arm64 -+CROSS_COMPILE ?= /home/yaya/E/Rockchip/3566/Android11/rk3566_rk3568_android11_oranth/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -+endif -+ -+ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y) -+ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2 -+ARCH ?= arm64 -+KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel -+CROSS_COMPILE ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -+endif -+ -+ifeq ($(CONFIG_PLATFORM_ALLWINNER), y) -+ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER -+KDIR ?= /home/yaya/E/Allwinner/r818/Android10/lichee/kernel/linux-4.9/ -+ARCH ?= arm64 -+CROSS_COMPILE ?= /home/yaya/E/Allwinner/r818/Android10/android/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android- -+ -+endif -+ -+ifeq ($(CONFIG_PLATFORM_INGENIC_T20), y) -+KDIR ?= /home/yaya/E/T40/kernel -+ARCH ?= mips -+CROSS_COMPILE ?= /home/yaya/E/T40/mips-linux-gnu-ingenic-gcc7.2.0-glibc2.29-fp64/bin/mips-linux-gnu- -+endif -+ -+ifeq ($(CONFIG_PLATFORM_AMLOGIC), y) -+ccflags-$(CONFIG_PLATFORM_AMLOGIC) += -DCONFIG_PLATFORM_AMLOGIC -+KDIR ?= /home/aiden/D1/SDK/Amlogic/905x3_a9/android9.0/out/target/product/u202/obj/KERNEL_OBJ/ -+ARCH ?= arm -+CROSS_COMPILE ?= /home/aiden/D1/SDK/Amlogic/905x3_a9/android9.0/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi- -+endif -+ -+ifeq ($(CONFIG_PLATFORM_UBUNTU), y) -+ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU -+KDIR ?= /lib/modules/$(shell uname -r)/build -+PWD ?= $(shell pwd) -+KVER ?= $(shell uname -r) -+MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/ -+ARCH ?= x86_64 -+CROSS_COMPILE ?= -+endif -+########################################### -+ -+all: modules -+modules: -+ make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules -+ -+install: -+ mkdir -p $(MODDESTDIR) -+ install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR) -+ /sbin/depmod -a ${KVER} -+ -+uninstall: -+ rm -rfv $(MODDESTDIR)/$(MODULE_NAME).ko -+ /sbin/depmod -a ${KVER} -+ -+clean: -+ rm -rf *.o *.ko *.o.* *.mod.* modules.* Module.* .a* .o* .*.o.* *.mod .tmp* .cache.mk built-in.a -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/md5.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/md5.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/md5.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/md5.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,161 @@ -+#include -+#include "md5.h" -+ -+unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -+ -+void MD5Init(MD5_CTX *context) -+{ -+ context->count[0] = 0; -+ context->count[1] = 0; -+ context->state[0] = 0x67452301; -+ context->state[1] = 0xEFCDAB89; -+ context->state[2] = 0x98BADCFE; -+ context->state[3] = 0x10325476; -+} -+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen) -+{ -+ unsigned int i = 0,index = 0,partlen = 0; -+ index = (context->count[0] >> 3) & 0x3F; -+ partlen = 64 - index; -+ context->count[0] += inputlen << 3; -+ if(context->count[0] < (inputlen << 3)) -+ context->count[1]++; -+ context->count[1] += inputlen >> 29; -+ -+ if(inputlen >= partlen) -+ { -+ memcpy(&context->buffer[index],input,partlen); -+ MD5Transform(context->state,context->buffer); -+ for(i = partlen;i+64 <= inputlen;i+=64) -+ MD5Transform(context->state,&input[i]); -+ index = 0; -+ } -+ else -+ { -+ i = 0; -+ } -+ memcpy(&context->buffer[index],&input[i],inputlen-i); -+} -+void MD5Final(MD5_CTX *context,unsigned char digest[16]) -+{ -+ unsigned int index = 0,padlen = 0; -+ unsigned char bits[8]; -+ index = (context->count[0] >> 3) & 0x3F; -+ padlen = (index < 56)?(56-index):(120-index); -+ MD5Encode(bits,context->count,8); -+ MD5Update(context,PADDING,padlen); -+ MD5Update(context,bits,8); -+ MD5Encode(digest,context->state,16); -+} -+void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len) -+{ -+ unsigned int i = 0,j = 0; -+ while(j < len) -+ { -+ output[j] = input[i] & 0xFF; -+ output[j+1] = (input[i] >> 8) & 0xFF; -+ output[j+2] = (input[i] >> 16) & 0xFF; -+ output[j+3] = (input[i] >> 24) & 0xFF; -+ i++; -+ j+=4; -+ } -+} -+void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len) -+{ -+ unsigned int i = 0,j = 0; -+ while(j < len) -+ { -+ output[i] = (input[j]) | -+ (input[j+1] << 8) | -+ (input[j+2] << 16) | -+ (input[j+3] << 24); -+ i++; -+ j+=4; -+ } -+} -+void MD5Transform(unsigned int state[4],unsigned char block[64]) -+{ -+ unsigned int a = state[0]; -+ unsigned int b = state[1]; -+ unsigned int c = state[2]; -+ unsigned int d = state[3]; -+ unsigned int x[64]; -+ MD5Decode(x,block,64); -+ FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */ -+ FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */ -+ FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */ -+ FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */ -+ FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */ -+ FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */ -+ FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */ -+ FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */ -+ FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */ -+ FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */ -+ FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */ -+ FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */ -+ FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */ -+ FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */ -+ FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */ -+ FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */ -+ -+ /* Round 2 */ -+ GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */ -+ GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */ -+ GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */ -+ GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */ -+ GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */ -+ GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */ -+ GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */ -+ GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */ -+ GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */ -+ GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */ -+ GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */ -+ GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */ -+ GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */ -+ GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */ -+ GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */ -+ GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */ -+ -+ /* Round 3 */ -+ HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */ -+ HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */ -+ HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */ -+ HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */ -+ HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */ -+ HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */ -+ HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */ -+ HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */ -+ HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */ -+ HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */ -+ HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */ -+ HH(b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */ -+ HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */ -+ HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */ -+ HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */ -+ HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */ -+ -+ /* Round 4 */ -+ II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */ -+ II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */ -+ II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */ -+ II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */ -+ II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */ -+ II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */ -+ II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */ -+ II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */ -+ II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */ -+ II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */ -+ II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */ -+ II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */ -+ II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */ -+ II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */ -+ II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */ -+ II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */ -+ state[0] += a; -+ state[1] += b; -+ state[2] += c; -+ state[3] += d; -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/md5.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/md5.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/md5.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/md5.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,48 @@ -+#ifndef MD5_H -+#define MD5_H -+ -+typedef struct -+{ -+ unsigned int count[2]; -+ unsigned int state[4]; -+ unsigned char buffer[64]; -+}MD5_CTX; -+ -+ -+#define F(x,y,z) ((x & y) | (~x & z)) -+#define G(x,y,z) ((x & z) | (y & ~z)) -+#define H(x,y,z) (x^y^z) -+#define I(x,y,z) (y ^ (x | ~z)) -+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n))) -+#define FF(a,b,c,d,x,s,ac) \ -+ { \ -+ a += F(b,c,d) + x + ac; \ -+ a = ROTATE_LEFT(a,s); \ -+ a += b; \ -+ } -+#define GG(a,b,c,d,x,s,ac) \ -+ { \ -+ a += G(b,c,d) + x + ac; \ -+ a = ROTATE_LEFT(a,s); \ -+ a += b; \ -+ } -+#define HH(a,b,c,d,x,s,ac) \ -+ { \ -+ a += H(b,c,d) + x + ac; \ -+ a = ROTATE_LEFT(a,s); \ -+ a += b; \ -+ } -+#define II(a,b,c,d,x,s,ac) \ -+ { \ -+ a += I(b,c,d) + x + ac; \ -+ a = ROTATE_LEFT(a,s); \ -+ a += b; \ -+ } -+void MD5Init(MD5_CTX *context); -+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen); -+void MD5Final(MD5_CTX *context,unsigned char digest[16]); -+void MD5Transform(unsigned int state[4],unsigned char block[64]); -+void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len); -+void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len); -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/rwnx_version_gen.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/rwnx_version_gen.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/rwnx_version_gen.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_bsp/rwnx_version_gen.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,4 @@ -+#define RWNX_VERS_REV "241c091M (master)" -+#define RWNX_VERS_MOD "6.4.3.0" -+#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - - 241c091M (master)" -+#define RELEASE_DATE "2024_0327_3561b08f" -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic8800_btlpm.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic8800_btlpm.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic8800_btlpm.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic8800_btlpm.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,1167 @@ -+/* -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ */ -+ -+#define DEBUG -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+#include -+#endif -+ -+#include "aic_bsp_export.h" -+ -+/* -+ * #define BT_SLEEP_DBG -+ */ -+#define BT_SLEEP_DBG -+#undef BT_DBG -+#undef BT_ERR -+#ifdef BT_SLEEP_DBG -+#define BT_DBG(fmt, arg...) pr_debug("[BT_LPM] %s: " fmt "\n",\ -+ __func__, ## arg) -+#else -+#define BT_DBG(fmt, arg...) -+#endif -+#define BT_ERR(fmt, arg...) pr_debug("[BT_LPM] %s: " fmt "\n",\ -+ __func__, ## arg) -+ -+/* -+ * Defines -+ */ -+ -+#define VERSION "1.3.3" -+#define PROC_DIR "bluetooth/sleep" -+ -+#define DEFAULT_UART_INDEX 1 -+#define BT_BLUEDROID_SUPPORT 1 -+static int bluesleep_start(void); -+static void bluesleep_stop(void); -+ -+struct bluesleep_info { -+ unsigned int wakeup_enable; -+ unsigned host_wake; -+ unsigned ext_wake; -+ unsigned host_wake_irq; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ struct wakeup_source *ws; -+#else -+ struct wake_lock wake_lock; -+#endif -+ struct uart_port *uport; -+ unsigned host_wake_assert:1; -+ unsigned ext_wake_assert:1; -+ struct platform_device *pdev; -+}; -+ -+/* work function */ -+static void bluesleep_sleep_work(struct work_struct *work); -+static void bluesleep_tx_allow_sleep(void); -+ -+/* work queue */ -+DECLARE_DELAYED_WORK(sleep_workqueue, bluesleep_sleep_work); -+ -+/* Macros for handling sleep work */ -+#define bluesleep_rx_busy() schedule_delayed_work(&sleep_workqueue, 0) -+#define bluesleep_tx_busy() schedule_delayed_work(&sleep_workqueue, 0) -+#define bluesleep_rx_idle() schedule_delayed_work(&sleep_workqueue, 0) -+#define bluesleep_tx_idle() schedule_delayed_work(&sleep_workqueue, 0) -+ -+/* 1 second timeout */ -+#define RX_TIMER_INTERVAL 1 -+ -+/* state variable names and bit positions */ -+#define BT_PROTO 0x01 -+#define BT_TXDATA 0x02 -+#define BT_ASLEEP 0x04 -+#define BT_TXIDLE 0x08 -+#define BT_PAUSE 0x09 -+#define BT_RXTIMER 0x0a -+ -+#if BT_BLUEDROID_SUPPORT -+static bool has_lpm_enabled; -+#else -+/* global pointer to a single hci device. */ -+static struct hci_dev *bluesleep_hdev; -+#endif -+ -+#if BT_BLUEDROID_SUPPORT -+static struct platform_device *bluesleep_uart_dev; -+#endif -+static struct bluesleep_info *bsi; -+ -+/* module usage */ -+static atomic_t open_count = ATOMIC_INIT(1); -+ -+/* -+ * Local function prototypes -+ */ -+ -+#if !BT_BLUEDROID_SUPPORT -+static int bluesleep_hci_event(struct notifier_block *this, -+ unsigned long event, void *data); -+#endif -+ -+/* -+ * Global variables -+ */ -+ -+/** Global state flags */ -+static unsigned long flags; -+ -+/** Tasklet to respond to change in hostwake line */ -+static struct tasklet_struct hostwake_task; -+ -+/** Reception timer */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+static void bluesleep_rx_timer_expire(struct timer_list *t); -+#else -+static void bluesleep_rx_timer_expire(unsigned long data); -+#endif -+static struct timer_list rx_timer; -+ -+/** Lock for state transitions */ -+static spinlock_t rw_lock; -+ -+#if !BT_BLUEDROID_SUPPORT -+/** Notifier block for HCI events */ -+struct notifier_block hci_event_nblock = { -+ .notifier_call = bluesleep_hci_event, -+}; -+#endif -+ -+struct proc_dir_entry *bluetooth_dir, *sleep_dir; -+ -+/* -+ * Local functions -+ */ -+ -+/* -+ * bt go to sleep will call this function tell uart stop data interactive -+ */ -+static void hsuart_power(int on) -+{ -+ if (bsi->uport != NULL) { -+ if (on) -+ bsi->uport->ops->set_mctrl(bsi->uport, TIOCM_RTS); -+ else -+ bsi->uport->ops->set_mctrl(bsi->uport, 0); -+ } else { -+ BT_ERR("bsi->uport = NULL, has_lpm_enabled = %d", has_lpm_enabled); -+ } -+} -+ -+/** -+ * @return 1 if the Host can go to sleep, 0 otherwise. -+ */ -+static inline int bluesleep_can_sleep(void) -+{ -+ /* check if HOST_WAKE_BT_GPIO and BT_WAKE_HOST_GPIO -+ * are both deasserted -+ */ -+ return (gpio_get_value(bsi->ext_wake) != bsi->ext_wake_assert) && -+ (gpio_get_value(bsi->host_wake) != bsi->host_wake_assert) && -+ (!test_bit(BT_RXTIMER, &flags)) && (bsi->uport != NULL); -+} -+ -+/** -+ * @brief@ main sleep work handling function which update the flags -+ * and activate and deactivate UART ,check FIFO. -+ */ -+static void bluesleep_sleep_work(struct work_struct *work) -+{ -+ if (!has_lpm_enabled) -+ return; -+ -+ if (bluesleep_can_sleep()) { -+ /* already asleep, this is an error case */ -+ if (test_bit(BT_ASLEEP, &flags)) { -+ BT_DBG("already asleep"); -+ return; -+ } -+ if (bsi->uport->ops->tx_empty(bsi->uport)) { -+ BT_DBG("going to sleep..."); -+ set_bit(BT_ASLEEP, &flags); -+ /*Deactivating UART */ -+ hsuart_power(0); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ __pm_wakeup_event(bsi->ws, HZ / 2); -+#else -+ wake_lock_timeout(&bsi->wake_lock, HZ / 2); -+#endif -+ } else { -+ BT_DBG("This should never happen.\n"); -+ return; -+ } -+ } else if (test_bit(BT_ASLEEP, &flags)) { -+ BT_DBG("hold wake locks for rx_task."); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ __pm_stay_awake(bsi->ws); -+#else -+ wake_lock(&bsi->wake_lock); -+#endif -+ clear_bit(BT_ASLEEP, &flags); -+ -+ /* Add a timer to make sure that UART -+ * would not be turned on&off very frequentently -+ */ -+ mod_timer(&rx_timer, jiffies + (RX_TIMER_INTERVAL * HZ)); -+ -+ set_bit(BT_RXTIMER, &flags); -+ hsuart_power(1); -+ } else { -+ mod_timer(&rx_timer, jiffies + (RX_TIMER_INTERVAL * HZ)); -+ set_bit(BT_RXTIMER, &flags); -+ -+ if(test_bit(BT_PAUSE, &flags)){ -+ BT_DBG("rx wake du BT_PAUSE:%lx", flags); -+ ///enable bt sleep immediately -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+ } else if (gpio_get_value(bsi->ext_wake) != bsi->ext_wake_assert -+ && !test_bit(BT_TXIDLE, &flags)) { -+ BT_DBG("force retrigger bt wake:%lx", flags); -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ msleep(20); -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+ } -+ } -+} -+ -+/** -+ * A tasklet function that runs in tasklet context and reads the value -+ * of the HOST_WAKE GPIO pin and further defer the work. -+ * @param data Not used. -+ */ -+static void bluesleep_hostwake_task(unsigned long data) -+{ -+ BT_DBG("hostwake line change"); -+ spin_lock(&rw_lock); -+ -+ if (gpio_get_value(bsi->host_wake) == bsi->host_wake_assert) -+ bluesleep_rx_busy(); -+ else -+ bluesleep_rx_idle(); -+ -+ spin_unlock(&rw_lock); -+} -+ -+/** -+ * Handles proper timer action when outgoing data is delivered to the -+ * HCI line discipline. Sets BT_TXDATA. -+ */ -+static void bluesleep_outgoing_data(void) -+{ -+ unsigned long irq_flags; -+ int power_on_uart = 0; -+ -+ spin_lock_irqsave(&rw_lock, irq_flags); -+ -+ /* if the tx side is sleeping... */ -+ if (gpio_get_value(bsi->ext_wake) != bsi->ext_wake_assert) { -+ BT_DBG("tx was sleeping, wakeup it"); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ __pm_stay_awake(bsi->ws); -+#else -+ wake_lock(&bsi->wake_lock); -+#endif -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ clear_bit(BT_ASLEEP, &flags); -+ clear_bit(BT_TXIDLE, &flags); -+ power_on_uart = 1; -+ } -+ -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+ if (power_on_uart == 1) -+ hsuart_power(1); -+} -+ -+#if BT_BLUEDROID_SUPPORT -+static struct uart_port *bluesleep_get_uart_port(void) -+{ -+ struct uart_port *uport = NULL; -+ -+ if (bluesleep_uart_dev) { -+ uport = platform_get_drvdata(bluesleep_uart_dev); -+ if (uport) -+ BT_DBG( -+ "%s get uart_port from blusleep_uart_dev: %s, port irq: %d", -+ __func__, bluesleep_uart_dev->name, uport->irq); -+ } -+ return uport; -+} -+ -+static int bluesleep_lpm_proc_show(struct seq_file *m, void *v) -+{ -+ seq_printf(m, "lpm enable: %d\n", has_lpm_enabled); -+ return 0; -+} -+ -+static int bluesleep_lpm_proc_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, bluesleep_lpm_proc_show, NULL); -+} -+ -+static ssize_t bluesleep_write_proc_lpm(struct file *file, -+ const char __user *buffer, -+ size_t count, loff_t *pos) -+{ -+ char b; -+ -+ if (count < 1) -+ return -EINVAL; -+ -+ if (copy_from_user(&b, buffer, 1)) -+ return -EFAULT; -+ -+ if (b == '0') { -+#if 1 -+ set_bit(BT_PAUSE, &flags); -+ set_bit(BT_TXIDLE, &flags); -+ clear_bit(BT_TXDATA, &flags); -+ /* deassert BT_WAKE */ -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+#else -+ /* HCI_DEV_UNREG */ -+ bluesleep_stop(); -+ has_lpm_enabled = false; -+ bsi->uport = NULL; -+#endif -+ } else { -+ clear_bit(BT_PAUSE, &flags); -+ /* HCI_DEV_REG */ -+ if (!has_lpm_enabled) { -+ has_lpm_enabled = true; -+ if (bluesleep_uart_dev) -+ bsi->uport = bluesleep_get_uart_port(); -+ -+ /* if bluetooth started, start bluesleep*/ -+ bluesleep_start(); -+ } -+ } -+ -+ return count; -+} -+ -+static int bluesleep_btwrite_proc_show(struct seq_file *m, void *v) -+{ -+ seq_puts(m, "it's not support\n"); -+ return 0; -+} -+ -+static int bluesleep_btwrite_proc_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, bluesleep_btwrite_proc_show, NULL); -+} -+ -+static ssize_t bluesleep_write_proc_btwrite(struct file *file, -+ const char __user *buffer, -+ size_t count, loff_t *pos) -+{ -+ char b; -+ -+ if (count < 1) -+ return -EINVAL; -+ -+ if (copy_from_user(&b, buffer, 1)) -+ return -EFAULT; -+ -+ /* HCI_DEV_WRITE */ -+ if (b != '0') -+ bluesleep_outgoing_data(); -+ else -+ bluesleep_tx_allow_sleep(); -+ -+ return count; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) -+static const struct proc_ops lpm_fops = { -+ .proc_open = bluesleep_lpm_proc_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_release = single_release, -+ .proc_write = bluesleep_write_proc_lpm, -+}; -+static const struct proc_ops btwrite_fops = { -+ .proc_open = bluesleep_btwrite_proc_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_release = single_release, -+ .proc_write = bluesleep_write_proc_btwrite, -+}; -+ -+#else -+ -+static const struct file_operations lpm_fops = { -+ .owner = THIS_MODULE, -+ .open = bluesleep_lpm_proc_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+ .write = bluesleep_write_proc_lpm, -+}; -+static const struct file_operations btwrite_fops = { -+ .owner = THIS_MODULE, -+ .open = bluesleep_btwrite_proc_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+ .write = bluesleep_write_proc_btwrite, -+}; -+#endif -+ -+#else -+/** -+ * Handles HCI device events. -+ * @param this Not used. -+ * @param event The event that occurred. -+ * @param data The HCI device associated with the event. -+ * @return NOTIFY_DONE. -+ */ -+static int bluesleep_hci_event(struct notifier_block *this, -+ unsigned long event, void *data) -+{ -+ struct hci_dev *hdev = (struct hci_dev *) data; -+ struct hci_uart *hu; -+ struct uart_state *state; -+ -+ if (!hdev) -+ return NOTIFY_DONE; -+ -+ switch (event) { -+ case HCI_DEV_REG: -+ if (!bluesleep_hdev) { -+ bluesleep_hdev = hdev; -+ hu = (struct hci_uart *) hdev->driver_data; -+ state = (struct uart_state *) hu->tty->driver_data; -+ bsi->uport = state->uart_port; -+ } -+ break; -+ case HCI_DEV_UNREG: -+ bluesleep_hdev = NULL; -+ bsi->uport = NULL; -+ break; -+ case HCI_DEV_WRITE: -+ bluesleep_outgoing_data(); -+ break; -+ } -+ -+ return NOTIFY_DONE; -+} -+#endif -+ -+/** -+ * Function to check wheather bluetooth can sleep when btwrite was deasserted -+ * by bluedroid. -+ */ -+static void bluesleep_tx_allow_sleep(void) -+{ -+ unsigned long irq_flags; -+ BT_DBG("Tx has been idle\n"); -+ spin_lock_irqsave(&rw_lock, irq_flags); -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+ set_bit(BT_TXIDLE, &flags); -+ clear_bit(BT_TXDATA, &flags); -+ bluesleep_tx_idle(); -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+} -+ -+ -+/* Handles reception timer expiration. -+ * Clear BT_RXTIMER. -+ * @param data Not used. -+ */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+static void bluesleep_rx_timer_expire(struct timer_list *t) -+#else -+static void bluesleep_rx_timer_expire(unsigned long data) -+#endif -+{ -+ BT_DBG("bluesleep_rx_timer_expire"); -+ clear_bit(BT_RXTIMER, &flags); -+ bluesleep_rx_idle(); -+} -+ -+/** -+ * Schedules a tasklet to run when receiving an interrupt on the -+ * HOST_WAKE GPIO pin. -+ * @param irq Not used. -+ * @param dev_id Not used. -+ */ -+static irqreturn_t bluesleep_hostwake_isr(int irq, void *dev_id) -+{ -+ /* schedule a tasklet to handle the change in the host wake line */ -+ tasklet_schedule(&hostwake_task); -+ return IRQ_HANDLED; -+} -+ -+/** -+ * Starts the Sleep-Mode Protocol on the Host. -+ * @return On success, 0. On error, -1, and errno is set -+ * appropriately. -+ */ -+static int bluesleep_start(void) -+{ -+ int retval; -+ unsigned long irq_flags; -+ -+ spin_lock_irqsave(&rw_lock, irq_flags); -+ -+ if (test_bit(BT_PROTO, &flags)) { -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+ return 0; -+ } -+ -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+ -+ if (!atomic_dec_and_test(&open_count)) { -+ atomic_inc(&open_count); -+ return -EBUSY; -+ } -+ -+ /* start the timer */ -+ mod_timer(&rx_timer, jiffies + (RX_TIMER_INTERVAL*HZ)); -+ /*deassert BT_WAKE first*/ -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+ msleep(20); -+ -+ /* assert BT_WAKE */ -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ retval = request_irq(bsi->host_wake_irq, bluesleep_hostwake_isr, -+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, -+ "bluetooth hostwake", &bsi->pdev->dev); -+ if (retval < 0) { -+ BT_ERR("Couldn't acquire BT_HOST_WAKE IRQ"); -+ goto fail; -+ } -+ -+ set_bit(BT_PROTO, &flags); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ __pm_stay_awake(bsi->ws); -+#else -+ wake_lock(&bsi->wake_lock); -+#endif -+ -+ return 0; -+fail: -+ del_timer(&rx_timer); -+ atomic_inc(&open_count); -+ -+ return retval; -+} -+ -+/** -+ * Stops the Sleep-Mode Protocol on the Host. -+ */ -+static void bluesleep_stop(void) -+{ -+ unsigned long irq_flags; -+ -+ spin_lock_irqsave(&rw_lock, irq_flags); -+ -+ if (!test_bit(BT_PROTO, &flags)) { -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+ return; -+ } -+ -+ /* assert BT_WAKE */ -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ -+ del_timer(&rx_timer); -+ clear_bit(BT_PROTO, &flags); -+ -+ if (test_bit(BT_ASLEEP, &flags)) { -+ clear_bit(BT_ASLEEP, &flags); -+ hsuart_power(1); -+ } -+ -+ atomic_inc(&open_count); -+ -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+ free_irq(bsi->host_wake_irq, &bsi->pdev->dev); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ __pm_wakeup_event(bsi->ws, HZ / 2); -+#else -+ wake_lock_timeout(&bsi->wake_lock, HZ / 2); -+#endif -+} -+#if 0 -+/** -+ * Read the BT_WAKE GPIO pin value via the proc interface. -+ * When this function returns, page will contain a 1 if the -+ * pin is high, 0 otherwise. -+ * @param page Buffer for writing data. -+ * @param start Not used. -+ * @param offset Not used. -+ * @param count Not used. -+ * @param eof Whether or not there is more data to be read. -+ * @param data Not used. -+ * @return The number of bytes written. -+ */ -+static int bluepower_read_proc_btwake(char *page, char **start, off_t offset, -+ int count, int *eof, void *data) -+{ -+ *eof = 1; -+ return sprintf(page, "btwake:%u\n", -+ (gpio_get_value(bsi->ext_wake) == bsi->ext_wake_assert)); -+} -+ -+/** -+ * Write the BT_WAKE GPIO pin value via the proc interface. -+ * @param file Not used. -+ * @param buffer The buffer to read from. -+ * @param count The number of bytes to be written. -+ * @param data Not used. -+ * @return On success, the number of bytes written. On error, -1, and -+ * errno is set appropriately. -+ */ -+static int bluepower_write_proc_btwake(struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ char *buf; -+ -+ if (count < 1) -+ return -EINVAL; -+ -+ buf = kmalloc(count, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ if (copy_from_user(buf, buffer, count)) { -+ kfree(buf); -+ return -EFAULT; -+ } -+ -+ if (buf[0] == '0') { -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+ } else if (buf[0] == '1') { -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ } else { -+ kfree(buf); -+ return -EINVAL; -+ } -+ -+ kfree(buf); -+ return count; -+} -+ -+/** -+ * Read the BT_HOST_WAKE GPIO pin value via the proc interface. -+ * When this function returns, page will contain a 1 if the pin -+ * is high, 0 otherwise. -+ * @param page Buffer for writing data. -+ * @param start Not used. -+ * @param offset Not used. -+ * @param count Not used. -+ * @param eof Whether or not there is more data to be read. -+ * @param data Not used. -+ * @return The number of bytes written. -+ */ -+static int bluepower_read_proc_hostwake(char *page, char **start, off_t offset, -+ int count, int *eof, void *data) -+{ -+ *eof = 1; -+ return sprintf(page, "hostwake: %u\n", -+ (gpio_get_value(bsi->host_wake) == bsi->host_wake_assert)); -+} -+ -+ -+/** -+ * Read the low-power status of the Host via the proc interface. -+ * When this function returns, page contains a 1 if the Host -+ * is asleep, 0 otherwise. -+ * @param page Buffer for writing data. -+ * @param start Not used. -+ * @param offset Not used. -+ * @param count Not used. -+ * @param eof Whether or not there is more data to be read. -+ * @param data Not used. -+ * @return The number of bytes written. -+ */ -+static int bluesleep_read_proc_asleep(char *page, char **start, off_t offset, -+ int count, int *eof, void *data) -+{ -+ unsigned int asleep; -+ -+ asleep = test_bit(BT_ASLEEP, &flags) ? 1 : 0; -+ *eof = 1; -+ return sprintf(page, "asleep: %u\n", asleep); -+} -+ -+/** -+ * Read the low-power protocol being used by the Host via the proc interface. -+ * When this function returns, page will contain a 1 if the Host -+ * is using the Sleep Mode Protocol, 0 otherwise. -+ * @param page Buffer for writing data. -+ * @param start Not used. -+ * @param offset Not used. -+ * @param count Not used. -+ * @param eof Whether or not there is more data to be read. -+ * @param data Not used. -+ * @return The number of bytes written. -+ */ -+static int bluesleep_read_proc_proto(char *page, char **start, off_t offset, -+ int count, int *eof, void *data) -+{ -+ unsigned int proto; -+ -+ proto = test_bit(BT_PROTO, &flags) ? 1 : 0; -+ *eof = 1; -+ return sprintf(page, "proto: %u\n", proto); -+} -+ -+/** -+ * Modify the low-power protocol used by the Host via the proc interface. -+ * @param file Not used. -+ * @param buffer The buffer to read from. -+ * @param count The number of bytes to be written. -+ * @param data Not used. -+ * @return On success, the number of bytes written. On error, -1, and -+ * errno is set appropriately. -+ */ -+static int bluesleep_write_proc_proto(struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ char proto; -+ -+ if (count < 1) -+ return -EINVAL; -+ -+ if (copy_from_user(&proto, buffer, 1)) -+ return -EFAULT; -+ -+ if (proto == '0') -+ bluesleep_stop(); -+ else -+ bluesleep_start(); -+ -+ /* claim that we wrote everything */ -+ return count; -+} -+#endif -+ -+static int assert_level = -1; -+module_param(assert_level, int, S_IRUGO); -+MODULE_PARM_DESC(assert_level, "BT_LPM hostwake/btwake assert level"); -+ -+static struct platform_device *sw_uart_get_pdev(int id) -+{ -+ struct device_node *np; -+ char match[20]; -+ sprintf(match, "uart%d", id); -+ np = of_find_node_by_type(NULL, match); -+ return of_find_device_by_node(np); -+} -+ -+static int __init bluesleep_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct device *dev = &pdev->dev; -+ enum of_gpio_flags config; -+ int ret, uart_index; -+ u32 val; -+ struct aicbsp_feature_t bsp_feature_lpm; -+ -+ bsi = devm_kzalloc(&pdev->dev, sizeof(struct bluesleep_info), -+ GFP_KERNEL); -+ if (!bsi) -+ return -ENOMEM; -+ -+ bsi->host_wake = of_get_named_gpio_flags(np, "bt_hostwake", 0, &config); -+ if (!gpio_is_valid(bsi->host_wake)) { -+ BT_ERR("get gpio bt_hostwake failed\n"); -+ ret = -EINVAL; -+ goto err0; -+ } -+ -+ /* set host_wake_assert */ -+ aicbsp_get_feature(&bsp_feature_lpm); -+ if (bsp_feature_lpm.irqf == 0) -+ bsi->host_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 0 : 1; -+ else -+ bsi->host_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 1 : 0; -+ -+ BT_DBG("bt_hostwake gpio=%d assert=%d\n", bsi->host_wake, bsi->host_wake_assert); -+ -+ if (assert_level != -1) { -+ bsi->host_wake_assert = (assert_level & 0x02) > 0; -+ BT_DBG("override host_wake assert to %d", bsi->host_wake_assert); -+ } -+ -+ ret = devm_gpio_request(dev, bsi->host_wake, "bt_hostwake"); -+ if (ret < 0) { -+ BT_ERR("can't request bt_hostwake gpio %d\n", -+ bsi->host_wake); -+ goto err0; -+ } -+ ret = gpio_direction_input(bsi->host_wake); -+ if (ret < 0) { -+ BT_ERR("can't request input direction bt_wake gpio %d\n", -+ bsi->host_wake); -+ goto err1; -+ } -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ if (!of_property_read_bool(np, "wakeup-source")) { -+#else -+ if (!of_property_read_u32(np, "wakeup-source", &bsi->wakeup_enable) && -+ (bsi->wakeup_enable == 0)) { -+#endif -+ BT_DBG("wakeup source is disabled!\n"); -+ } else { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+ ret = device_init_wakeup(dev, true); -+ if (ret < 0) { -+ BT_ERR("device init wakeup failed!\n"); -+ goto err1; -+ } -+ ret = dev_pm_set_wake_irq(dev, gpio_to_irq(bsi->host_wake)); -+ if (ret < 0) { -+ BT_ERR("can't enable wakeup src for bt_hostwake %d\n", -+ bsi->host_wake); -+ goto err2; -+ } -+ bsi->wakeup_enable = 1; -+#else -+ BT_ERR("%s kernel unsupport this feature!\r\n", __func__); -+#endif -+ } -+ -+ bsi->ext_wake = of_get_named_gpio_flags(np, "bt_wake", 0, &config); -+ if (!gpio_is_valid(bsi->ext_wake)) { -+ BT_ERR("get gpio bt_wake failed\n"); -+ ret = -EINVAL; -+ goto err2; -+ } -+ -+ ret = devm_gpio_request(dev, bsi->ext_wake, "bt_wake"); -+ if (ret < 0) { -+ BT_ERR("can't request bt_wake gpio %d\n", -+ bsi->ext_wake); -+ goto err2; -+ } -+ -+ /* set ext_wake_assert */ -+ bsi->ext_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 0 : 1; -+ BT_DBG("bt_wake gpio=%d assert=%d\n", bsi->ext_wake, bsi->ext_wake_assert); -+ -+ if (assert_level != -1) { -+ bsi->ext_wake_assert = (assert_level & 0x01) > 0; -+ BT_DBG("override ext_wake assert to %d", bsi->ext_wake_assert); -+ } -+ -+ /* 1.set bt_wake as output and the level is assert, assert bt wake */ -+ ret = gpio_direction_output(bsi->ext_wake, bsi->ext_wake_assert); -+ if (ret < 0) { -+ BT_ERR("can't request output direction bt_wake gpio %d\n", -+ bsi->ext_wake); -+ goto err3; -+ } -+ /*set ext_wake deassert as default*/ -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+ -+ /* 2.get bt_host_wake gpio irq */ -+ bsi->host_wake_irq = gpio_to_irq(bsi->host_wake); -+ if (bsi->host_wake_irq < 0) { -+ BT_ERR("map gpio [%d] to virq failed, errno = %d\n", -+ bsi->host_wake, bsi->host_wake_irq); -+ ret = -ENODEV; -+ goto err3; -+ } -+ -+ uart_index = DEFAULT_UART_INDEX; -+ if (!of_property_read_u32(np, "uart_index", &val)) { -+ switch (val) { -+ case 0: -+ case 1: -+ case 2: -+ uart_index = val; -+ break; -+ default: -+ BT_ERR("unsupported uart_index (%u)\n", val); -+ } -+ } -+ BT_DBG("uart_index (%u)\n", uart_index); -+ bluesleep_uart_dev = sw_uart_get_pdev(uart_index); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ bsi->ws = wakeup_source_register(dev, "bluesleep"); -+#else -+ wake_lock_init(&bsi->wake_lock, WAKE_LOCK_SUSPEND, "bluesleep"); -+#endif -+ bsi->pdev = pdev; -+ -+ return 0; -+ -+err3: -+ devm_gpio_free(dev, bsi->ext_wake); -+err2: -+ device_init_wakeup(dev, false); -+err1: -+ devm_gpio_free(dev, bsi->host_wake); -+err0: -+ devm_kfree(dev, bsi); -+ -+ BT_ERR("probe fail, err: %d", ret); -+ return ret; -+} -+ -+static int bluesleep_remove(struct platform_device *pdev) -+{ -+ /* assert bt wake */ -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ if (test_bit(BT_PROTO, &flags)) { -+ if (disable_irq_wake(bsi->host_wake_irq)) -+ BT_ERR("Couldn't disable hostwake IRQ wakeup mode\n"); -+ free_irq(bsi->host_wake_irq, &bsi->pdev->dev); -+ del_timer(&rx_timer); -+ if (test_bit(BT_ASLEEP, &flags)) -+ hsuart_power(1); -+ } -+ gpio_free(bsi->host_wake); -+ gpio_free(bsi->ext_wake); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ wakeup_source_unregister(bsi->ws); -+#else -+ wake_lock_destroy(&bsi->wake_lock); -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+ if (bsi->wakeup_enable) { -+ BT_DBG("Deinit wakeup source"); -+ device_init_wakeup(&pdev->dev, false); -+ dev_pm_clear_wake_irq(&pdev->dev); -+ } -+#else -+ BT_ERR("%s kernel unsupport this feature!\r\n", __func__); -+#endif -+ return 0; -+} -+ -+#ifdef CONFIG_AUTO_PM -+static int bluesleep_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ printk("%s\n", __func__); -+ -+ bluesleep_tx_allow_sleep(); -+ return 0; -+} -+ -+static int bluesleep_resume(struct platform_device *pdev) -+{ -+ printk("%s\n", __func__); -+ -+ bluesleep_outgoing_data(); -+ return 0; -+} -+#endif -+ -+static const struct of_device_id sunxi_btlpm_ids[] = { -+ { .compatible = "allwinner,sunxi-btlpm" }, -+ { /* Sentinel */ } -+}; -+ -+static struct platform_driver bluesleep_driver = { -+ .remove = bluesleep_remove, -+#ifdef CONFIG_AUTO_PM -+ .suspend = bluesleep_suspend, -+ .resume = bluesleep_resume, -+#endif -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "sunxi-btlpm", -+ .of_match_table = sunxi_btlpm_ids, -+ }, -+}; -+ -+/** -+ * Initializes the module. -+ * @return On success, 0. On error, -1, and errno is set -+ * appropriately. -+ */ -+static int __init bluesleep_init(void) -+{ -+ int retval; -+ struct proc_dir_entry *ent; -+ -+ BT_DBG("BlueSleep Mode Driver Ver %s", VERSION); -+ -+ retval = platform_driver_probe(&bluesleep_driver, bluesleep_probe); -+ if (retval) -+ return retval; -+ -+#if !BT_BLUEDROID_SUPPORT -+ bluesleep_hdev = NULL; -+#endif -+ -+ bluetooth_dir = proc_mkdir("bluetooth", NULL); -+ if (bluetooth_dir == NULL) { -+ BT_ERR("Unable to create /proc/bluetooth directory"); -+ return -ENOMEM; -+ } -+ -+ sleep_dir = proc_mkdir("sleep", bluetooth_dir); -+ if (sleep_dir == NULL) { -+ BT_ERR("Unable to create /proc/%s directory", PROC_DIR); -+ return -ENOMEM; -+ } -+#if 0 -+ /* Creating read/write "btwake" entry */ -+ ent = create_proc_entry("btwake", 0, sleep_dir); -+ if (ent == NULL) { -+ BT_ERR("Unable to create /proc/%s/btwake entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+ ent->read_proc = bluepower_read_proc_btwake; -+ ent->write_proc = bluepower_write_proc_btwake; -+ -+ /* read only proc entries */ -+ if (create_proc_read_entry("hostwake", 0, sleep_dir, -+ bluepower_read_proc_hostwake, NULL) == NULL) { -+ BT_ERR("Unable to create /proc/%s/hostwake entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+ -+ /* read/write proc entries */ -+ ent = create_proc_entry("proto", 0666, sleep_dir); -+ if (ent == NULL) { -+ BT_ERR("Unable to create /proc/%s/proto entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+ ent->read_proc = bluesleep_read_proc_proto; -+ ent->write_proc = bluesleep_write_proc_proto; -+ -+ /* read only proc entries */ -+ if (create_proc_read_entry("asleep", 0, -+ sleep_dir, bluesleep_read_proc_asleep, NULL) == NULL) { -+ BT_ERR("Unable to create /proc/%s/asleep entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+#endif -+#if BT_BLUEDROID_SUPPORT -+ /* read/write proc entries */ -+ ent = proc_create("lpm", 0660, sleep_dir, &lpm_fops); -+ if (ent == NULL) { -+ BT_ERR("Unable to create /proc/%s/lpm entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+ -+ ent = proc_create("btwrite", 0660, sleep_dir, &btwrite_fops); -+ if (ent == NULL) { -+ BT_ERR("Unable to create /proc/%s/btwrite entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+#endif -+ -+ flags = 0; /* clear all status bits */ -+ -+ /* Initialize spinlock. */ -+ spin_lock_init(&rw_lock); -+ -+ /* Initialize timer */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ timer_setup(&rx_timer, bluesleep_rx_timer_expire, 0); -+#else -+ init_timer(&rx_timer); -+ rx_timer.function = bluesleep_rx_timer_expire; -+ rx_timer.data = 0; -+#endif -+ -+ /* initialize host wake tasklet */ -+ tasklet_init(&hostwake_task, bluesleep_hostwake_task, 0); -+ -+#if !BT_BLUEDROID_SUPPORT -+ hci_register_notifier(&hci_event_nblock); -+#endif -+ -+ return 0; -+ -+fail: -+#if BT_BLUEDROID_SUPPORT -+ remove_proc_entry("btwrite", sleep_dir); -+ remove_proc_entry("lpm", sleep_dir); -+#endif -+#if 0 -+ remove_proc_entry("asleep", sleep_dir); -+ remove_proc_entry("proto", sleep_dir); -+ remove_proc_entry("hostwake", sleep_dir); -+ remove_proc_entry("btwake", sleep_dir); -+#endif -+ remove_proc_entry("sleep", bluetooth_dir); -+ remove_proc_entry("bluetooth", 0); -+ return retval; -+} -+ -+/** -+ * Cleans up the module. -+ */ -+static void __exit bluesleep_exit(void) -+{ -+#if !BT_BLUEDROID_SUPPORT -+ hci_unregister_notifier(&hci_event_nblock); -+#endif -+ platform_driver_unregister(&bluesleep_driver); -+ -+#if BT_BLUEDROID_SUPPORT -+ remove_proc_entry("btwrite", sleep_dir); -+ remove_proc_entry("lpm", sleep_dir); -+#endif -+#if 0 -+ remove_proc_entry("asleep", sleep_dir); -+ remove_proc_entry("proto", sleep_dir); -+ remove_proc_entry("hostwake", sleep_dir); -+ remove_proc_entry("btwake", sleep_dir); -+#endif -+ remove_proc_entry("sleep", bluetooth_dir); -+ remove_proc_entry("bluetooth", 0); -+} -+ -+module_init(bluesleep_init); -+module_exit(bluesleep_exit); -+ -+MODULE_DESCRIPTION("Bluetooth Sleep Mode Driver ver %s " VERSION); -+#ifdef MODULE_LICENSE -+MODULE_LICENSE("GPL"); -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic_bluetooth_main.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic_bluetooth_main.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic_bluetooth_main.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic_bluetooth_main.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,88 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "lpm.h" -+#include "rfkill.h" -+ -+#define DRV_CONFIG_FW_NAME "fw.bin" -+#define DRV_DESCRIPTION "AIC BLUETOOTH" -+#define DRV_COPYRIGHT "Copyright(c) 2015-2020 AICSemi" -+#define DRV_AUTHOR "AICSemi" -+#define DRV_VERS_MOD "1.0" -+ -+static struct platform_device *aicbt_pdev; -+ -+static struct platform_driver aicbt_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "aic_bt", -+ }, -+ //.probe = aicbt_probe, -+ //.remove = aicbt_remove, -+}; -+ -+static int __init aic_bluetooth_mod_init(void) -+{ -+ int ret; -+ printk("%s\n", __func__); -+ ret = platform_driver_register(&aicbt_driver); -+ if (ret) { -+ pr_err("register platform driver failed: %d\n", ret); -+ return ret; -+ } -+ -+ aicbt_pdev = platform_device_alloc("aic-bt", -1); -+ ret = platform_device_add(aicbt_pdev); -+ if (ret) { -+ pr_err("register platform device failed: %d\n", ret); -+ goto err0; -+ } -+ -+ ret = rfkill_bluetooth_init(aicbt_pdev); -+ if (ret) { -+ pr_err("rfkill init fail\n"); -+ goto err1; -+ } -+#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2) -+ ret = bluesleep_init(aicbt_pdev); -+ if (ret) { -+ pr_err("bluesleep init fail\n"); -+ goto err2; -+ } -+#endif -+ -+ return 0; -+ -+#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2) -+err2: -+#endif -+ rfkill_bluetooth_remove(aicbt_pdev); -+err1: -+ platform_device_del(aicbt_pdev); -+err0: -+ platform_driver_unregister(&aicbt_driver); -+ return ret; -+} -+ -+static void __exit aic_bluetooth_mod_exit(void) -+{ -+ printk("%s\n", __func__); -+#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2) -+ bluesleep_exit(aicbt_pdev); -+#endif -+ rfkill_bluetooth_remove(aicbt_pdev); -+ platform_device_del(aicbt_pdev); -+ platform_driver_unregister(&aicbt_driver); -+} -+ -+module_init(aic_bluetooth_mod_init); -+module_exit(aic_bluetooth_mod_exit); -+ -+MODULE_DESCRIPTION(DRV_DESCRIPTION); -+MODULE_VERSION(DRV_VERS_MOD); -+MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); -+MODULE_LICENSE("GPL"); -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic_bsp_export.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic_bsp_export.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic_bsp_export.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/aic_bsp_export.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,19 @@ -+#ifndef __AIC_BSP_EXPORT_H -+#define __AIC_BSP_EXPORT_H -+ -+#define AIC_BLUETOOTH 0 -+#define AIC_WIFI 1 -+#define AIC_PWR_OFF 0 -+#define AIC_PWR_ON 1 -+ -+struct aicbsp_feature_t { -+ bool band_5g_support; -+ uint32_t sdio_clock; -+ uint8_t sdio_phase; -+ uint8_t irqf; -+}; -+ -+int aicbsp_set_subsys(int, int); -+int aicbsp_get_feature(struct aicbsp_feature_t *feature); -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/.gitignore linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/.gitignore ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/.gitignore 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/.gitignore 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,10 @@ -+*.o -+*.ko -+*.order -+*.symvers -+*.o.d -+*.o.cmd -+*.ko.cmd -+*.mod -+*.mod.c -+*.mod.cmd -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/Kconfig linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/Kconfig ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/Kconfig 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,5 @@ -+config AIC8800_BTLPM_SUPPORT -+ tristate "AIC8800 bluetooth Support" -+ help -+ This is support for aic bluetooh driver. -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,1111 @@ -+/* -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ */ -+ -+#define DEBUG -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+#include -+#endif -+#include -+#include -+#include -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+#include -+#endif -+ -+/* -+ * #define BT_SLEEP_DBG -+ */ -+#define BT_SLEEP_DBG -+#undef BT_DBG -+#undef BT_ERR -+#ifdef BT_SLEEP_DBG -+#define BT_DBG(fmt, arg...) pr_debug("[BT_LPM] %s: " fmt "\n",\ -+ __func__, ## arg) -+#else -+#define BT_DBG(fmt, arg...) -+#endif -+#define BT_ERR(fmt, arg...) pr_debug("[BT_LPM] %s: " fmt "\n",\ -+ __func__, ## arg) -+ -+/* -+ * Defines -+ */ -+ -+#define VERSION "1.3.3" -+#define PROC_DIR "bluetooth/sleep" -+ -+#define DEFAULT_UART_INDEX 1 -+#define BT_BLUEDROID_SUPPORT 1 -+static int bluesleep_start(void); -+static void bluesleep_stop(void); -+ -+struct bluesleep_info { -+ unsigned int wakeup_enable; -+ unsigned host_wake; -+ unsigned ext_wake; -+ unsigned host_wake_irq; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ struct wakeup_source *ws; -+#else -+ struct wake_lock wake_lock; -+#endif -+ struct uart_port *uport; -+ unsigned host_wake_assert:1; -+ unsigned ext_wake_assert:1; -+ struct platform_device *pdev; -+}; -+ -+/* work function */ -+static void bluesleep_sleep_work(struct work_struct *work); -+static void bluesleep_tx_allow_sleep(void); -+ -+/* work queue */ -+DECLARE_DELAYED_WORK(sleep_workqueue, bluesleep_sleep_work); -+ -+/* Macros for handling sleep work */ -+#define bluesleep_rx_busy() schedule_delayed_work(&sleep_workqueue, 0) -+#define bluesleep_tx_busy() schedule_delayed_work(&sleep_workqueue, 0) -+#define bluesleep_rx_idle() schedule_delayed_work(&sleep_workqueue, 0) -+#define bluesleep_tx_idle() schedule_delayed_work(&sleep_workqueue, 0) -+ -+/* 1 second timeout */ -+#define RX_TIMER_INTERVAL 1 -+ -+/* state variable names and bit positions */ -+#define BT_PROTO 0x01 -+#define BT_TXDATA 0x02 -+#define BT_ASLEEP 0x04 -+#define BT_RXTIMER 0x20 -+#define BT_TXIDLE 0x08 -+ -+#if BT_BLUEDROID_SUPPORT -+static bool has_lpm_enabled; -+#else -+/* global pointer to a single hci device. */ -+static struct hci_dev *bluesleep_hdev; -+#endif -+ -+#if BT_BLUEDROID_SUPPORT -+static struct platform_device *bluesleep_uart_dev; -+#endif -+static struct bluesleep_info *bsi; -+ -+/* module usage */ -+static atomic_t open_count = ATOMIC_INIT(1); -+ -+/* -+ * Local function prototypes -+ */ -+ -+#if !BT_BLUEDROID_SUPPORT -+static int bluesleep_hci_event(struct notifier_block *this, -+ unsigned long event, void *data); -+#endif -+ -+/* -+ * Global variables -+ */ -+ -+/** Global state flags */ -+static unsigned long flags; -+ -+/** Tasklet to respond to change in hostwake line */ -+static struct tasklet_struct hostwake_task; -+ -+/** Reception timer */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+static void bluesleep_rx_timer_expire(struct timer_list *t); -+#else -+static void bluesleep_rx_timer_expire(unsigned long data); -+#endif -+static struct timer_list rx_timer; -+ -+/** Lock for state transitions */ -+static spinlock_t rw_lock; -+ -+#if !BT_BLUEDROID_SUPPORT -+/** Notifier block for HCI events */ -+struct notifier_block hci_event_nblock = { -+ .notifier_call = bluesleep_hci_event, -+}; -+#endif -+ -+struct proc_dir_entry *bluetooth_dir, *sleep_dir; -+ -+/* -+ * Local functions -+ */ -+ -+/* -+ * bt go to sleep will call this function tell uart stop data interactive -+ */ -+static void hsuart_power(int on) -+{ -+ if (bsi->uport != NULL) { -+ if (on) -+ bsi->uport->ops->set_mctrl(bsi->uport, TIOCM_RTS); -+ else -+ bsi->uport->ops->set_mctrl(bsi->uport, 0); -+ } else { -+ BT_ERR("bsi->uport = NULL, has_lpm_enabled = %d", has_lpm_enabled); -+ } -+} -+ -+/** -+ * @return 1 if the Host can go to sleep, 0 otherwise. -+ */ -+static inline int bluesleep_can_sleep(void) -+{ -+ /* check if HOST_WAKE_BT_GPIO and BT_WAKE_HOST_GPIO -+ * are both deasserted -+ */ -+ return (gpio_get_value(bsi->ext_wake) != bsi->ext_wake_assert) && -+ (gpio_get_value(bsi->host_wake) != bsi->host_wake_assert) && -+ (!test_bit(BT_RXTIMER, &flags)) && (bsi->uport != NULL); -+} -+ -+/** -+ * @brief@ main sleep work handling function which update the flags -+ * and activate and deactivate UART ,check FIFO. -+ */ -+static void bluesleep_sleep_work(struct work_struct *work) -+{ -+ if (!has_lpm_enabled) -+ return; -+ -+ if (bluesleep_can_sleep()) { -+ /* already asleep, this is an error case */ -+ if (test_bit(BT_ASLEEP, &flags)) { -+ BT_DBG("already asleep"); -+ return; -+ } -+ if (bsi->uport->ops->tx_empty(bsi->uport)) { -+ BT_DBG("going to sleep..."); -+ set_bit(BT_ASLEEP, &flags); -+ /*Deactivating UART */ -+ hsuart_power(0); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ __pm_wakeup_event(bsi->ws, HZ / 2); -+#else -+ wake_lock_timeout(&bsi->wake_lock, HZ / 2); -+#endif -+ } else { -+ BT_DBG("This should never happen.\n"); -+ return; -+ } -+ } else if (test_bit(BT_ASLEEP, &flags)) { -+ BT_DBG("hold wake locks for rx_task."); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ __pm_stay_awake(bsi->ws); -+#else -+ wake_lock(&bsi->wake_lock); -+#endif -+ clear_bit(BT_ASLEEP, &flags); -+ -+ /* Add a timer to make sure that UART -+ * would not be turned on&off very frequentently -+ */ -+ mod_timer(&rx_timer, jiffies + (RX_TIMER_INTERVAL * HZ)); -+ -+ set_bit(BT_RXTIMER, &flags); -+ hsuart_power(1); -+ } else { -+ mod_timer(&rx_timer, jiffies + (RX_TIMER_INTERVAL * HZ)); -+ if (gpio_get_value(bsi->ext_wake) != bsi->ext_wake_assert -+ && !test_bit(BT_TXIDLE, &flags)) { -+ BT_DBG("force retrigger bt wake:%lx", flags); -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ msleep(20); -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+ } -+ } -+} -+ -+/** -+ * A tasklet function that runs in tasklet context and reads the value -+ * of the HOST_WAKE GPIO pin and further defer the work. -+ * @param data Not used. -+ */ -+static void bluesleep_hostwake_task(unsigned long data) -+{ -+ BT_DBG("hostwake line change"); -+ spin_lock(&rw_lock); -+ -+ if (gpio_get_value(bsi->host_wake) == bsi->host_wake_assert) -+ bluesleep_rx_busy(); -+ else -+ bluesleep_rx_idle(); -+ -+ spin_unlock(&rw_lock); -+} -+ -+/** -+ * Handles proper timer action when outgoing data is delivered to the -+ * HCI line discipline. Sets BT_TXDATA. -+ */ -+static void bluesleep_outgoing_data(void) -+{ -+ unsigned long irq_flags; -+ int power_on_uart = 0; -+ -+ spin_lock_irqsave(&rw_lock, irq_flags); -+ -+ /* if the tx side is sleeping... */ -+ if (gpio_get_value(bsi->ext_wake) != bsi->ext_wake_assert) { -+ BT_DBG("tx was sleeping, wakeup it"); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ __pm_stay_awake(bsi->ws); -+#else -+ wake_lock(&bsi->wake_lock); -+#endif -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ clear_bit(BT_ASLEEP, &flags); -+ clear_bit(BT_TXIDLE, &flags); -+ power_on_uart = 1; -+ } -+ -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+ if (power_on_uart == 1) -+ hsuart_power(1); -+} -+ -+#if BT_BLUEDROID_SUPPORT -+static struct uart_port *bluesleep_get_uart_port(void) -+{ -+ struct uart_port *uport = NULL; -+ -+ if (bluesleep_uart_dev) { -+ uport = platform_get_drvdata(bluesleep_uart_dev); -+ if (uport) -+ BT_DBG( -+ "%s get uart_port from blusleep_uart_dev: %s, port irq: %d", -+ __func__, bluesleep_uart_dev->name, uport->irq); -+ } -+ return uport; -+} -+ -+static int bluesleep_lpm_proc_show(struct seq_file *m, void *v) -+{ -+ seq_printf(m, "lpm enable: %d\n", has_lpm_enabled); -+ return 0; -+} -+ -+static int bluesleep_lpm_proc_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, bluesleep_lpm_proc_show, NULL); -+} -+ -+static ssize_t bluesleep_write_proc_lpm(struct file *file, -+ const char __user *buffer, -+ size_t count, loff_t *pos) -+{ -+ char b; -+ -+ if (count < 1) -+ return -EINVAL; -+ -+ if (copy_from_user(&b, buffer, 1)) -+ return -EFAULT; -+ -+ if (b == '0') { -+ /* HCI_DEV_UNREG */ -+ bluesleep_stop(); -+ has_lpm_enabled = false; -+ bsi->uport = NULL; -+ } else { -+ /* HCI_DEV_REG */ -+ if (!has_lpm_enabled) { -+ has_lpm_enabled = true; -+ if (bluesleep_uart_dev) -+ bsi->uport = bluesleep_get_uart_port(); -+ -+ /* if bluetooth started, start bluesleep*/ -+ bluesleep_start(); -+ } -+ } -+ -+ return count; -+} -+ -+static int bluesleep_btwrite_proc_show(struct seq_file *m, void *v) -+{ -+ seq_puts(m, "it's not support\n"); -+ return 0; -+} -+ -+static int bluesleep_btwrite_proc_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, bluesleep_btwrite_proc_show, NULL); -+} -+ -+static ssize_t bluesleep_write_proc_btwrite(struct file *file, -+ const char __user *buffer, -+ size_t count, loff_t *pos) -+{ -+ char b; -+ -+ if (count < 1) -+ return -EINVAL; -+ -+ if (copy_from_user(&b, buffer, 1)) -+ return -EFAULT; -+ -+ /* HCI_DEV_WRITE */ -+ if (b != '0') -+ bluesleep_outgoing_data(); -+ else -+ bluesleep_tx_allow_sleep(); -+ -+ return count; -+} -+ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 10, 0) -+static const struct proc_ops lpm_fops = { -+ .proc_open = bluesleep_lpm_proc_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_release = single_release, -+ .proc_write = bluesleep_write_proc_lpm, -+}; -+static const struct proc_ops btwrite_fops = { -+ .proc_open = bluesleep_btwrite_proc_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_release = single_release, -+ .proc_write = bluesleep_write_proc_btwrite, -+}; -+#else -+static const struct file_operations lpm_fops = { -+ .owner = THIS_MODULE, -+ .open = bluesleep_lpm_proc_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+ .write = bluesleep_write_proc_lpm, -+}; -+static const struct file_operations btwrite_fops = { -+ .owner = THIS_MODULE, -+ .open = bluesleep_btwrite_proc_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+ .write = bluesleep_write_proc_btwrite, -+}; -+#endif -+#else -+/** -+ * Handles HCI device events. -+ * @param this Not used. -+ * @param event The event that occurred. -+ * @param data The HCI device associated with the event. -+ * @return NOTIFY_DONE. -+ */ -+static int bluesleep_hci_event(struct notifier_block *this, -+ unsigned long event, void *data) -+{ -+ struct hci_dev *hdev = (struct hci_dev *) data; -+ struct hci_uart *hu; -+ struct uart_state *state; -+ -+ if (!hdev) -+ return NOTIFY_DONE; -+ -+ switch (event) { -+ case HCI_DEV_REG: -+ if (!bluesleep_hdev) { -+ bluesleep_hdev = hdev; -+ hu = (struct hci_uart *) hdev->driver_data; -+ state = (struct uart_state *) hu->tty->driver_data; -+ bsi->uport = state->uart_port; -+ } -+ break; -+ case HCI_DEV_UNREG: -+ bluesleep_hdev = NULL; -+ bsi->uport = NULL; -+ break; -+ case HCI_DEV_WRITE: -+ bluesleep_outgoing_data(); -+ break; -+ } -+ -+ return NOTIFY_DONE; -+} -+#endif -+ -+/** -+ * Function to check wheather bluetooth can sleep when btwrite was deasserted -+ * by bluedroid. -+ */ -+static void bluesleep_tx_allow_sleep(void) -+{ -+ unsigned long irq_flags; -+ BT_DBG("Tx has been idle\n"); -+ spin_lock_irqsave(&rw_lock, irq_flags); -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+ set_bit(BT_TXIDLE, &flags); -+ bluesleep_tx_idle(); -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+} -+ -+ -+/* Handles reception timer expiration. -+ * Clear BT_RXTIMER. -+ * @param data Not used. -+ */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+static void bluesleep_rx_timer_expire(struct timer_list *t) -+#else -+static void bluesleep_rx_timer_expire(unsigned long data) -+#endif -+{ -+ BT_DBG("bluesleep_rx_timer_expire"); -+ clear_bit(BT_RXTIMER, &flags); -+ bluesleep_rx_idle(); -+} -+ -+/** -+ * Schedules a tasklet to run when receiving an interrupt on the -+ * HOST_WAKE GPIO pin. -+ * @param irq Not used. -+ * @param dev_id Not used. -+ */ -+static irqreturn_t bluesleep_hostwake_isr(int irq, void *dev_id) -+{ -+ /* schedule a tasklet to handle the change in the host wake line */ -+ tasklet_schedule(&hostwake_task); -+ return IRQ_HANDLED; -+} -+ -+/** -+ * Starts the Sleep-Mode Protocol on the Host. -+ * @return On success, 0. On error, -1, and errno is set -+ * appropriately. -+ */ -+static int bluesleep_start(void) -+{ -+ int retval; -+ unsigned long irq_flags; -+ -+ spin_lock_irqsave(&rw_lock, irq_flags); -+ -+ if (test_bit(BT_PROTO, &flags)) { -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+ return 0; -+ } -+ -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+ -+ if (!atomic_dec_and_test(&open_count)) { -+ atomic_inc(&open_count); -+ return -EBUSY; -+ } -+ -+ /* start the timer */ -+ mod_timer(&rx_timer, jiffies + (RX_TIMER_INTERVAL*HZ)); -+ /*deassert BT_WAKE first*/ -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+ msleep(20); -+ -+ /* assert BT_WAKE */ -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ retval = request_irq(bsi->host_wake_irq, bluesleep_hostwake_isr, -+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, -+ "bluetooth hostwake", &bsi->pdev->dev); -+ if (retval < 0) { -+ BT_ERR("Couldn't acquire BT_HOST_WAKE IRQ"); -+ goto fail; -+ } -+ -+ set_bit(BT_PROTO, &flags); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ __pm_stay_awake(bsi->ws); -+#else -+ wake_lock(&bsi->wake_lock); -+#endif -+ -+ return 0; -+fail: -+ del_timer(&rx_timer); -+ atomic_inc(&open_count); -+ -+ return retval; -+} -+ -+/** -+ * Stops the Sleep-Mode Protocol on the Host. -+ */ -+static void bluesleep_stop(void) -+{ -+ unsigned long irq_flags; -+ -+ spin_lock_irqsave(&rw_lock, irq_flags); -+ -+ if (!test_bit(BT_PROTO, &flags)) { -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+ return; -+ } -+ -+ /* assert BT_WAKE */ -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ -+ del_timer(&rx_timer); -+ clear_bit(BT_PROTO, &flags); -+ -+ if (test_bit(BT_ASLEEP, &flags)) { -+ clear_bit(BT_ASLEEP, &flags); -+ hsuart_power(1); -+ } -+ -+ atomic_inc(&open_count); -+ -+ spin_unlock_irqrestore(&rw_lock, irq_flags); -+ free_irq(bsi->host_wake_irq, &bsi->pdev->dev); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ __pm_wakeup_event(bsi->ws, HZ / 2); -+#else -+ wake_lock_timeout(&bsi->wake_lock, HZ / 2); -+#endif -+} -+#if 0 -+/** -+ * Read the BT_WAKE GPIO pin value via the proc interface. -+ * When this function returns, page will contain a 1 if the -+ * pin is high, 0 otherwise. -+ * @param page Buffer for writing data. -+ * @param start Not used. -+ * @param offset Not used. -+ * @param count Not used. -+ * @param eof Whether or not there is more data to be read. -+ * @param data Not used. -+ * @return The number of bytes written. -+ */ -+static int bluepower_read_proc_btwake(char *page, char **start, off_t offset, -+ int count, int *eof, void *data) -+{ -+ *eof = 1; -+ return sprintf(page, "btwake:%u\n", -+ (gpio_get_value(bsi->ext_wake) == bsi->ext_wake_assert)); -+} -+ -+/** -+ * Write the BT_WAKE GPIO pin value via the proc interface. -+ * @param file Not used. -+ * @param buffer The buffer to read from. -+ * @param count The number of bytes to be written. -+ * @param data Not used. -+ * @return On success, the number of bytes written. On error, -1, and -+ * errno is set appropriately. -+ */ -+static int bluepower_write_proc_btwake(struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ char *buf; -+ -+ if (count < 1) -+ return -EINVAL; -+ -+ buf = kmalloc(count, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ if (copy_from_user(buf, buffer, count)) { -+ kfree(buf); -+ return -EFAULT; -+ } -+ -+ if (buf[0] == '0') { -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+ } else if (buf[0] == '1') { -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ } else { -+ kfree(buf); -+ return -EINVAL; -+ } -+ -+ kfree(buf); -+ return count; -+} -+ -+/** -+ * Read the BT_HOST_WAKE GPIO pin value via the proc interface. -+ * When this function returns, page will contain a 1 if the pin -+ * is high, 0 otherwise. -+ * @param page Buffer for writing data. -+ * @param start Not used. -+ * @param offset Not used. -+ * @param count Not used. -+ * @param eof Whether or not there is more data to be read. -+ * @param data Not used. -+ * @return The number of bytes written. -+ */ -+static int bluepower_read_proc_hostwake(char *page, char **start, off_t offset, -+ int count, int *eof, void *data) -+{ -+ *eof = 1; -+ return sprintf(page, "hostwake: %u\n", -+ (gpio_get_value(bsi->host_wake) == bsi->host_wake_assert)); -+} -+ -+ -+/** -+ * Read the low-power status of the Host via the proc interface. -+ * When this function returns, page contains a 1 if the Host -+ * is asleep, 0 otherwise. -+ * @param page Buffer for writing data. -+ * @param start Not used. -+ * @param offset Not used. -+ * @param count Not used. -+ * @param eof Whether or not there is more data to be read. -+ * @param data Not used. -+ * @return The number of bytes written. -+ */ -+static int bluesleep_read_proc_asleep(char *page, char **start, off_t offset, -+ int count, int *eof, void *data) -+{ -+ unsigned int asleep; -+ -+ asleep = test_bit(BT_ASLEEP, &flags) ? 1 : 0; -+ *eof = 1; -+ return sprintf(page, "asleep: %u\n", asleep); -+} -+ -+/** -+ * Read the low-power protocol being used by the Host via the proc interface. -+ * When this function returns, page will contain a 1 if the Host -+ * is using the Sleep Mode Protocol, 0 otherwise. -+ * @param page Buffer for writing data. -+ * @param start Not used. -+ * @param offset Not used. -+ * @param count Not used. -+ * @param eof Whether or not there is more data to be read. -+ * @param data Not used. -+ * @return The number of bytes written. -+ */ -+static int bluesleep_read_proc_proto(char *page, char **start, off_t offset, -+ int count, int *eof, void *data) -+{ -+ unsigned int proto; -+ -+ proto = test_bit(BT_PROTO, &flags) ? 1 : 0; -+ *eof = 1; -+ return sprintf(page, "proto: %u\n", proto); -+} -+ -+/** -+ * Modify the low-power protocol used by the Host via the proc interface. -+ * @param file Not used. -+ * @param buffer The buffer to read from. -+ * @param count The number of bytes to be written. -+ * @param data Not used. -+ * @return On success, the number of bytes written. On error, -1, and -+ * errno is set appropriately. -+ */ -+static int bluesleep_write_proc_proto(struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ char proto; -+ -+ if (count < 1) -+ return -EINVAL; -+ -+ if (copy_from_user(&proto, buffer, 1)) -+ return -EFAULT; -+ -+ if (proto == '0') -+ bluesleep_stop(); -+ else -+ bluesleep_start(); -+ -+ /* claim that we wrote everything */ -+ return count; -+} -+#endif -+ -+static int assert_level = -1; -+module_param(assert_level, int, S_IRUGO); -+MODULE_PARM_DESC(assert_level, "BT_LPM hostwake/btwake assert level"); -+ -+#if 1 -+static struct platform_device *sw_uart_get_pdev(int id) -+{ -+ struct device_node *np; -+ char match[20]; -+ sprintf(match, "uart%d", id); -+ np = of_find_node_by_type(NULL, match); -+ return of_find_device_by_node(np); -+} -+#endif -+ -+static int bluesleep_probe(struct platform_device *pdev) -+{ -+#if 1 -+ struct device_node *np = of_find_compatible_node(NULL, NULL, "allwinner,sunxi-btlpm"); -+ struct device *dev = &pdev->dev; -+ enum of_gpio_flags config; -+ int ret, uart_index; -+ u32 val; -+ -+ bsi = devm_kzalloc(&pdev->dev, sizeof(struct bluesleep_info), -+ GFP_KERNEL); -+ if (!bsi) -+ return -ENOMEM; -+ -+ bsi->host_wake = of_get_named_gpio_flags(np, "bt_hostwake", 0, &config); -+ if (!gpio_is_valid(bsi->host_wake)) { -+ BT_ERR("get gpio bt_hostwake failed\n"); -+ ret = -EINVAL; -+ goto err0; -+ } -+ -+ /* set host_wake_assert */ -+ bsi->host_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 0 : 1; -+ BT_DBG("bt_hostwake gpio=%d assert=%d\n", bsi->host_wake, bsi->host_wake_assert); -+ -+ if (assert_level != -1) { -+ bsi->host_wake_assert = (assert_level & 0x02) > 0; -+ BT_DBG("override host_wake assert to %d", bsi->host_wake_assert); -+ } -+ -+ ret = devm_gpio_request(dev, bsi->host_wake, "bt_hostwake"); -+ if (ret < 0) { -+ BT_ERR("can't request bt_hostwake gpio %d\n", -+ bsi->host_wake); -+ goto err0; -+ } -+ ret = gpio_direction_input(bsi->host_wake); -+ if (ret < 0) { -+ BT_ERR("can't request input direction bt_wake gpio %d\n", -+ bsi->host_wake); -+ goto err1; -+ } -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ if (!of_property_read_bool(np, "wakeup-source")) { -+#else -+ if (!of_property_read_u32(np, "wakeup-source", &bsi->wakeup_enable) && -+ (bsi->wakeup_enable == 0)) { -+#endif -+ BT_DBG("wakeup source is disabled!\n"); -+ } else { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+ ret = device_init_wakeup(dev, true); -+ if (ret < 0) { -+ BT_ERR("device init wakeup failed!\n"); -+ goto err1; -+ } -+ ret = dev_pm_set_wake_irq(dev, gpio_to_irq(bsi->host_wake)); -+ if (ret < 0) { -+ BT_ERR("can't enable wakeup src for bt_hostwake %d\n", -+ bsi->host_wake); -+ goto err2; -+ } -+ bsi->wakeup_enable = 1; -+#else -+ BT_ERR("%s kernel unsupport this feature!\r\n", __func__); -+#endif -+ } -+ -+ bsi->ext_wake = of_get_named_gpio_flags(np, "bt_wake", 0, &config); -+ if (!gpio_is_valid(bsi->ext_wake)) { -+ BT_ERR("get gpio bt_wake failed\n"); -+ ret = -EINVAL; -+ goto err2; -+ } -+ -+ ret = devm_gpio_request(dev, bsi->ext_wake, "bt_wake"); -+ if (ret < 0) { -+ BT_ERR("can't request bt_wake gpio %d\n", -+ bsi->ext_wake); -+ goto err2; -+ } -+ -+ /* set ext_wake_assert */ -+ bsi->ext_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 0 : 1; -+ BT_DBG("bt_wake gpio=%d assert=%d\n", bsi->ext_wake, bsi->ext_wake_assert); -+ -+ if (assert_level != -1) { -+ bsi->ext_wake_assert = (assert_level & 0x01) > 0; -+ BT_DBG("override ext_wake assert to %d", bsi->ext_wake_assert); -+ } -+ -+ /* 1.set bt_wake as output and the level is assert, assert bt wake */ -+ ret = gpio_direction_output(bsi->ext_wake, bsi->ext_wake_assert); -+ if (ret < 0) { -+ BT_ERR("can't request output direction bt_wake gpio %d\n", -+ bsi->ext_wake); -+ goto err3; -+ } -+ /*set ext_wake deassert as default*/ -+ gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert); -+ -+ /* 2.get bt_host_wake gpio irq */ -+ bsi->host_wake_irq = gpio_to_irq(bsi->host_wake); -+ if (bsi->host_wake_irq < 0) { -+ BT_ERR("map gpio [%d] to virq failed, errno = %d\n", -+ bsi->host_wake, bsi->host_wake_irq); -+ ret = -ENODEV; -+ goto err3; -+ } -+ -+ uart_index = DEFAULT_UART_INDEX; -+ if (!of_property_read_u32(np, "uart_index", &val)) { -+ switch (val) { -+ case 0: -+ case 1: -+ case 2: -+ uart_index = val; -+ break; -+ default: -+ BT_ERR("unsupported uart_index (%u)\n", val); -+ } -+ } -+ BT_DBG("uart_index (%u)\n", uart_index); -+ bluesleep_uart_dev = sw_uart_get_pdev(uart_index); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) -+ bsi->ws = wakeup_source_register(dev, "bluesleep"); -+#else -+ bsi->ws = wakeup_source_register("bluesleep"); -+#endif -+ -+#else -+ wake_lock_init(&bsi->wake_lock, WAKE_LOCK_SUSPEND, "bluesleep"); -+#endif -+ bsi->pdev = pdev; -+ -+ return 0; -+ -+err3: -+ devm_gpio_free(dev, bsi->ext_wake); -+err2: -+ device_init_wakeup(dev, false); -+err1: -+ devm_gpio_free(dev, bsi->host_wake); -+err0: -+ devm_kfree(dev, bsi); -+ -+ BT_ERR("probe fail, err: %d", ret); -+ return ret; -+#endif -+ return 0; -+} -+ -+static int bluesleep_remove(struct platform_device *pdev) -+{ -+ /* assert bt wake */ -+ gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert); -+ if (test_bit(BT_PROTO, &flags)) { -+ if (disable_irq_wake(bsi->host_wake_irq)) -+ BT_ERR("Couldn't disable hostwake IRQ wakeup mode\n"); -+ free_irq(bsi->host_wake_irq, &bsi->pdev->dev); -+ del_timer(&rx_timer); -+ if (test_bit(BT_ASLEEP, &flags)) -+ hsuart_power(1); -+ } -+ gpio_free(bsi->host_wake); -+ gpio_free(bsi->ext_wake); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ wakeup_source_unregister(bsi->ws); -+#else -+ wake_lock_destroy(&bsi->wake_lock); -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+ if (bsi->wakeup_enable) { -+ BT_DBG("Deinit wakeup source"); -+ device_init_wakeup(&pdev->dev, false); -+ dev_pm_clear_wake_irq(&pdev->dev); -+ } -+#else -+ BT_ERR("%s kernel unsupport this feature!\r\n", __func__); -+#endif -+ return 0; -+} -+ -+/** -+ * Initializes the module. -+ * @return On success, 0. On error, -1, and errno is set -+ * appropriately. -+ */ -+int bluesleep_init(struct platform_device *pdev) -+{ -+ int retval; -+ struct proc_dir_entry *ent; -+ -+ BT_DBG("BlueSleep Mode Driver Ver %s", VERSION); -+ -+#if 1 -+ retval = bluesleep_probe(pdev); -+ if (retval) -+ return retval; -+#endif -+ -+#if !BT_BLUEDROID_SUPPORT -+ bluesleep_hdev = NULL; -+#endif -+ -+ bluetooth_dir = proc_mkdir("bluetooth", NULL); -+ if (bluetooth_dir == NULL) { -+ BT_ERR("Unable to create /proc/bluetooth directory"); -+ return -ENOMEM; -+ } -+ -+ sleep_dir = proc_mkdir("sleep", bluetooth_dir); -+ if (sleep_dir == NULL) { -+ BT_ERR("Unable to create /proc/%s directory", PROC_DIR); -+ return -ENOMEM; -+ } -+#if 0 -+ /* Creating read/write "btwake" entry */ -+ ent = create_proc_entry("btwake", 0, sleep_dir); -+ if (ent == NULL) { -+ BT_ERR("Unable to create /proc/%s/btwake entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+ ent->read_proc = bluepower_read_proc_btwake; -+ ent->write_proc = bluepower_write_proc_btwake; -+ -+ /* read only proc entries */ -+ if (create_proc_read_entry("hostwake", 0, sleep_dir, -+ bluepower_read_proc_hostwake, NULL) == NULL) { -+ BT_ERR("Unable to create /proc/%s/hostwake entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+ -+ /* read/write proc entries */ -+ ent = create_proc_entry("proto", 0666, sleep_dir); -+ if (ent == NULL) { -+ BT_ERR("Unable to create /proc/%s/proto entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+ ent->read_proc = bluesleep_read_proc_proto; -+ ent->write_proc = bluesleep_write_proc_proto; -+ -+ /* read only proc entries */ -+ if (create_proc_read_entry("asleep", 0, -+ sleep_dir, bluesleep_read_proc_asleep, NULL) == NULL) { -+ BT_ERR("Unable to create /proc/%s/asleep entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+#endif -+#if BT_BLUEDROID_SUPPORT -+ /* read/write proc entries */ -+ ent = proc_create("lpm", 0660, sleep_dir, &lpm_fops); -+ if (ent == NULL) { -+ BT_ERR("Unable to create /proc/%s/lpm entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+ -+ ent = proc_create("btwrite", 0660, sleep_dir, &btwrite_fops); -+ if (ent == NULL) { -+ BT_ERR("Unable to create /proc/%s/btwrite entry", PROC_DIR); -+ retval = -ENOMEM; -+ goto fail; -+ } -+#endif -+ -+ flags = 0; /* clear all status bits */ -+ -+ /* Initialize spinlock. */ -+ spin_lock_init(&rw_lock); -+ -+ /* Initialize timer */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ timer_setup(&rx_timer, bluesleep_rx_timer_expire, 0); -+#else -+ init_timer(&rx_timer); -+ rx_timer.function = bluesleep_rx_timer_expire; -+ rx_timer.data = 0; -+#endif -+ -+ /* initialize host wake tasklet */ -+ tasklet_init(&hostwake_task, bluesleep_hostwake_task, 0); -+ -+#if !BT_BLUEDROID_SUPPORT -+ hci_register_notifier(&hci_event_nblock); -+#endif -+ -+ return 0; -+ -+fail: -+#if BT_BLUEDROID_SUPPORT -+ remove_proc_entry("btwrite", sleep_dir); -+ remove_proc_entry("lpm", sleep_dir); -+#endif -+#if 0 -+ remove_proc_entry("asleep", sleep_dir); -+ remove_proc_entry("proto", sleep_dir); -+ remove_proc_entry("hostwake", sleep_dir); -+ remove_proc_entry("btwake", sleep_dir); -+#endif -+ remove_proc_entry("sleep", bluetooth_dir); -+ remove_proc_entry("bluetooth", 0); -+ return retval; -+} -+ -+/** -+ * Cleans up the module. -+ */ -+int bluesleep_exit(struct platform_device *dev) -+{ -+#if !BT_BLUEDROID_SUPPORT -+ hci_unregister_notifier(&hci_event_nblock); -+#endif -+ -+#if BT_BLUEDROID_SUPPORT -+ remove_proc_entry("btwrite", sleep_dir); -+ remove_proc_entry("lpm", sleep_dir); -+#endif -+#if 0 -+ remove_proc_entry("asleep", sleep_dir); -+ remove_proc_entry("proto", sleep_dir); -+ remove_proc_entry("hostwake", sleep_dir); -+ remove_proc_entry("btwake", sleep_dir); -+#endif -+ remove_proc_entry("sleep", bluetooth_dir); -+ remove_proc_entry("bluetooth", 0); -+ bluesleep_remove(dev); -+ return 0; -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,21 @@ -+/* -+ * Copyright (C) 2015 Spreadtrum Communications Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __LPM_H -+#define __LPM_H -+ -+int bluesleep_init(struct platform_device *pdev); -+int bluesleep_exit(struct platform_device *dev); -+ -+#endif -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/Makefile linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/Makefile ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/Makefile 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,83 @@ -+CONFIG_AIC8800_BTLPM_SUPPORT = m -+ -+obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) := aic8800_btlpm.o -+ -+ccflags-y += -I$(srctree)/$(src)/../aic8800_bsp -+ -+# Platform support list -+CONFIG_PLATFORM_ROCKCHIP ?= n -+CONFIG_PLATFORM_ROCKCHIP2 ?= n -+CONFIG_PLATFORM_ALLWINNER ?= n -+CONFIG_PLATFORM_AMLOGIC ?= n -+CONFIG_PLATFORM_UBUNTU ?= y -+ -+ -+CONFIG_SUPPORT_LPM ?= n -+CONFIG_AUTO_PM ?= n -+ -+aic8800_btlpm-y := \ -+ aic_bluetooth_main.o \ -+ rfkill.o \ -+ -+aic8800_btlpm-$(CONFIG_SUPPORT_LPM) += lpm.o -+ -+ccflags-y += -DAIC_TRACE_INCLUDE_PATH=$(src) -+ -+ccflags-$(CONFIG_AUTO_PM) += -DCONFIG_AUTO_PM -+ -+ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y) -+ARCH = arm64 -+KDIR = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel -+CROSS_COMPILE = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -+ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP -+ccflags-y += -DANDROID_PLATFORM -+endif -+ -+ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y) -+ARCH = arm64 -+KDIR = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel -+CROSS_COMPILE = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -+ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2 -+ccflags-y += -DANDROID_PLATFORM -+endif -+ -+ifeq ($(CONFIG_PLATFORM_ALLWINNER), y) -+ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER -+KDIR ?= /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/kernel/linux-4.9/ -+ARCH ?= arm64 -+CROSS_COMPILE ?= /home/yaya/E/Allwinner/R818/R818/AndroidQ/android/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android- -+ccflags-y += -DANDROID_PLATFORM -+endif -+ -+ifeq ($(CONFIG_PLATFORM_AMLOGIC), y) -+ccflags-$(CONFIG_PLATFORM_NANOPI) += -DCONFIG_PLATFORM_NANOPI -+ccflags-y += -DANDROID_PLATFORM -+endif -+ -+ifeq ($(CONFIG_PLATFORM_UBUNTU), y) -+KDIR ?= /lib/modules/$(shell uname -r)/build -+PWD ?= $(shell pwd) -+KVER ?= $(shell uname -r) -+MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/ -+ARCH ?= x86_64 -+CROSS_COMPILE ?= -+endif -+ -+ -+all: modules -+modules: -+ make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules -+ -+install: -+ mkdir -p $(MODDESTDIR) -+ install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR) -+ /sbin/depmod -a ${KVER} -+ -+uninstall: -+ rm -rfv $(MODDESTDIR)/$(MODULE_NAME).ko -+ /sbin/depmod -a ${KVER} -+ -+clean: -+ rm -rf *.o *.ko *.o.* *.mod.* modules.* Module.* .a* .o* .*.o.* *.mod .tmp* .cache.mk -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/rfkill.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/rfkill.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/rfkill.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/rfkill.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,81 @@ -+/* -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "aic_bsp_export.h" -+ -+static struct rfkill *bt_rfk; -+static const char bt_name[] = "bluetooth"; -+ -+static int bluetooth_set_power(void *data, bool blocked) -+{ -+ pr_info("%s: start_block=%d\n", __func__, blocked); -+ if (!blocked) { -+ aicbsp_set_subsys(AIC_BLUETOOTH, AIC_PWR_ON); -+ } else { -+ aicbsp_set_subsys(AIC_BLUETOOTH, AIC_PWR_OFF); -+ } -+ -+ pr_info("%s: end_block=%d\n", __func__, blocked); -+ return 0; -+} -+ -+static struct rfkill_ops rfkill_bluetooth_ops = { -+ .set_block = bluetooth_set_power, -+}; -+ -+int rfkill_bluetooth_init(struct platform_device *pdev) -+{ -+ -+ int rc = 0; -+ -+ pr_info("-->%s\n", __func__); -+ bt_rfk = rfkill_alloc(bt_name, &pdev->dev, RFKILL_TYPE_BLUETOOTH, -+ &rfkill_bluetooth_ops, NULL); -+ if (!bt_rfk) { -+ rc = -ENOMEM; -+ goto err_rfkill_alloc; -+ } -+ /* userspace cannot take exclusive control */ -+ rfkill_init_sw_state(bt_rfk, true); -+ rc = rfkill_register(bt_rfk); -+ if (rc) -+ goto err_rfkill_reg; -+ -+ pr_info("<--%s\n", __func__); -+ -+ return 0; -+ -+err_rfkill_reg: -+ rfkill_destroy(bt_rfk); -+err_rfkill_alloc: -+ return rc; -+} -+ -+int rfkill_bluetooth_remove(struct platform_device *dev) -+{ -+ pr_info("-->%s\n", __func__); -+ rfkill_unregister(bt_rfk); -+ rfkill_destroy(bt_rfk); -+ pr_info("<--%s\n", __func__); -+ return 0; -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/rfkill.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/rfkill.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/rfkill.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/rfkill.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,17 @@ -+/* -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#ifndef __RFKILL_H__ -+#define __RFKILL_H__ -+ -+int rfkill_bluetooth_init(struct platform_device *pdev); -+int rfkill_bluetooth_remove(struct platform_device *pdev); -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_br_ext.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_br_ext.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_br_ext.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_br_ext.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,1569 @@ -+/****************************************************************************** -+ * -+ * Copyright(c) 2007 - 2017 Realtek Corporation. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of version 2 of the GNU General Public License as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ *****************************************************************************/ -+#define _AIC_BR_EXT_C_ -+ -+#ifdef __KERNEL__ -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include "rwnx_defs.h" -+#endif -+ -+#ifdef CL_IPV6_PASS -+ #ifdef __KERNEL__ -+ #include -+ #include -+ #include -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) -+ #include -+ #else -+ #include -+ #endif -+ #endif -+#endif -+ -+#ifdef CONFIG_BR_SUPPORT -+ -+/* #define BR_SUPPORT_DEBUG */ -+ -+#define NAT25_IPV4 01 -+#define NAT25_IPV6 02 -+#define NAT25_IPX 03 -+#define NAT25_APPLE 04 -+#define NAT25_PPPOE 05 -+ -+#define RTL_RELAY_TAG_LEN (ETH_ALEN) -+#define TAG_HDR_LEN 4 -+ -+#define MAGIC_CODE 0x8186 -+#define MAGIC_CODE_LEN 2 -+#define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */ -+ -+/*----------------------------------------------------------------- -+ How database records network address: -+ 0 1 2 3 4 5 6 7 8 9 10 -+ |----|----|----|----|----|----|----|----|----|----|----| -+ IPv4 |type| | IP addr | -+ IPX |type| Net addr | Node addr | -+ IPX |type| Net addr |Sckt addr| -+ Apple |type| Network |node| -+ PPPoE |type| SID | AC MAC | -+-----------------------------------------------------------------*/ -+ -+ -+/* Find a tag in pppoe frame and return the pointer */ -+static __inline__ unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type) -+{ -+ unsigned char *cur_ptr, *start_ptr; -+ unsigned short tagLen, tagType; -+ -+ start_ptr = cur_ptr = (unsigned char *)ph->tag; -+ while ((cur_ptr - start_ptr) < ntohs(ph->length)) { -+ /* prevent un-alignment access */ -+ tagType = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]); -+ tagLen = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]); -+ if (tagType == type) -+ return cur_ptr; -+ cur_ptr = cur_ptr + TAG_HDR_LEN + tagLen; -+ } -+ return 0; -+} -+ -+ -+static __inline__ int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag) -+{ -+ struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); -+ int data_len; -+ -+ data_len = tag->tag_len + TAG_HDR_LEN; -+ if (skb_tailroom(skb) < data_len) { -+ printk("skb_tailroom() failed in add SID tag!\n"); -+ return -1; -+ } -+ -+ skb_put(skb, data_len); -+ /* have a room for new tag */ -+ memmove(((unsigned char *)ph->tag + data_len), (unsigned char *)ph->tag, ntohs(ph->length)); -+ ph->length = htons(ntohs(ph->length) + data_len); -+ memcpy((unsigned char *)ph->tag, tag, data_len); -+ return data_len; -+} -+ -+static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len) -+{ -+ int tail_len; -+ unsigned long end, tail; -+ -+ if ((src + len) > skb_tail_pointer(skb) || skb->len < len) -+ return -1; -+ -+ tail = (unsigned long)skb_tail_pointer(skb); -+ end = (unsigned long)src + len; -+ if (tail < end) -+ return -1; -+ -+ tail_len = (int)(tail - end); -+ if (tail_len > 0) -+ memmove(src, src + len, tail_len); -+ -+ skb_trim(skb, skb->len - len); -+ return 0; -+} -+ -+static __inline__ unsigned long __nat25_timeout(struct rwnx_vif *vif) -+{ -+ unsigned long timeout; -+ -+ timeout = jiffies - NAT25_AGEING_TIME * HZ; -+ -+ return timeout; -+} -+ -+ -+static __inline__ int __nat25_has_expired(struct rwnx_vif *vif, -+ struct nat25_network_db_entry *fdb) -+{ -+ if (time_before_eq(fdb->ageing_timer, __nat25_timeout(vif))) -+ return 1; -+ -+ return 0; -+} -+ -+ -+static __inline__ void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr, -+ unsigned int *ipAddr) -+{ -+ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); -+ -+ networkAddr[0] = NAT25_IPV4; -+ memcpy(networkAddr + 7, (unsigned char *)ipAddr, 4); -+} -+ -+ -+static __inline__ void __nat25_generate_ipx_network_addr_with_node(unsigned char *networkAddr, -+ unsigned int *ipxNetAddr, unsigned char *ipxNodeAddr) -+{ -+ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); -+ -+ networkAddr[0] = NAT25_IPX; -+ memcpy(networkAddr + 1, (unsigned char *)ipxNetAddr, 4); -+ memcpy(networkAddr + 5, ipxNodeAddr, 6); -+} -+ -+ -+static __inline__ void __nat25_generate_ipx_network_addr_with_socket(unsigned char *networkAddr, -+ unsigned int *ipxNetAddr, unsigned short *ipxSocketAddr) -+{ -+ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); -+ -+ networkAddr[0] = NAT25_IPX; -+ memcpy(networkAddr + 1, (unsigned char *)ipxNetAddr, 4); -+ memcpy(networkAddr + 5, (unsigned char *)ipxSocketAddr, 2); -+} -+ -+ -+static __inline__ void __nat25_generate_apple_network_addr(unsigned char *networkAddr, -+ unsigned short *network, unsigned char *node) -+{ -+ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); -+ -+ networkAddr[0] = NAT25_APPLE; -+ memcpy(networkAddr + 1, (unsigned char *)network, 2); -+ networkAddr[3] = *node; -+} -+ -+ -+static __inline__ void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr, -+ unsigned char *ac_mac, unsigned short *sid) -+{ -+ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); -+ -+ networkAddr[0] = NAT25_PPPOE; -+ memcpy(networkAddr + 1, (unsigned char *)sid, 2); -+ memcpy(networkAddr + 3, (unsigned char *)ac_mac, 6); -+} -+ -+ -+#ifdef CL_IPV6_PASS -+static void __nat25_generate_ipv6_network_addr(unsigned char *networkAddr, -+ unsigned int *ipAddr) -+{ -+ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); -+ -+ networkAddr[0] = NAT25_IPV6; -+ memcpy(networkAddr + 1, (unsigned char *)ipAddr, 16); -+} -+ -+ -+static unsigned char *scan_tlv(unsigned char *data, int len, unsigned char tag, unsigned char len8b) -+{ -+ while (len > 0) { -+ if (*data == tag && *(data + 1) == len8b && len >= len8b * 8) -+ return data + 2; -+ -+ len -= (*(data + 1)) * 8; -+ data += (*(data + 1)) * 8; -+ } -+ return NULL; -+} -+ -+ -+static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char *replace_mac) -+{ -+ struct icmp6hdr *icmphdr = (struct icmp6hdr *)data; -+ unsigned char *mac; -+ -+ if (icmphdr->icmp6_type == NDISC_ROUTER_SOLICITATION) { -+ if (len >= 8) { -+ mac = scan_tlv(&data[8], len - 8, 1, 1); -+ if (mac) { -+ printk("Router Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], -+ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); -+ memcpy(mac, replace_mac, 6); -+ return 1; -+ } -+ } -+ } else if (icmphdr->icmp6_type == NDISC_ROUTER_ADVERTISEMENT) { -+ if (len >= 16) { -+ mac = scan_tlv(&data[16], len - 16, 1, 1); -+ if (mac) { -+ printk("Router Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], -+ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); -+ memcpy(mac, replace_mac, 6); -+ return 1; -+ } -+ } -+ } else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) { -+ if (len >= 24) { -+ mac = scan_tlv(&data[24], len - 24, 1, 1); -+ if (mac) { -+ printk("Neighbor Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], -+ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); -+ memcpy(mac, replace_mac, 6); -+ return 1; -+ } -+ } -+ } else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) { -+ if (len >= 24) { -+ mac = scan_tlv(&data[24], len - 24, 2, 1); -+ if (mac) { -+ printk("Neighbor Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], -+ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); -+ memcpy(mac, replace_mac, 6); -+ return 1; -+ } -+ } -+ } else if (icmphdr->icmp6_type == NDISC_REDIRECT) { -+ if (len >= 40) { -+ mac = scan_tlv(&data[40], len - 40, 2, 1); -+ if (mac) { -+ printk("Redirect, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], -+ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); -+ memcpy(mac, replace_mac, 6); -+ return 1; -+ } -+ } -+ } -+ return 0; -+} -+ -+#ifdef SUPPORT_RX_UNI2MCAST -+static void convert_ipv6_mac_to_mc(struct sk_buff *skb) -+{ -+ struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN); -+ unsigned char *dst_mac = skb->data; -+ -+ /* dst_mac[0] = 0xff; */ -+ /* dst_mac[1] = 0xff; */ -+ /*modified by qinjunjie,ipv6 multicast address ix 0x33-33-xx-xx-xx-xx*/ -+ dst_mac[0] = 0x33; -+ dst_mac[1] = 0x33; -+ memcpy(&dst_mac[2], &iph->daddr.s6_addr32[3], 4); -+#if defined(__LINUX_2_6__) -+ /*modified by qinjunjie,warning:should not remove next line*/ -+ skb->pkt_type = PACKET_MULTICAST; -+#endif -+} -+#endif /* CL_IPV6_PASS */ -+#endif /* SUPPORT_RX_UNI2MCAST */ -+ -+ -+static __inline__ int __nat25_network_hash(unsigned char *networkAddr) -+{ -+ if (networkAddr[0] == NAT25_IPV4) { -+ unsigned long x; -+ -+ x = networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; -+ -+ return x & (NAT25_HASH_SIZE - 1); -+ } else if (networkAddr[0] == NAT25_IPX) { -+ unsigned long x; -+ -+ x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ -+ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; -+ -+ return x & (NAT25_HASH_SIZE - 1); -+ } else if (networkAddr[0] == NAT25_APPLE) { -+ unsigned long x; -+ -+ x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3]; -+ -+ return x & (NAT25_HASH_SIZE - 1); -+ } else if (networkAddr[0] == NAT25_PPPOE) { -+ unsigned long x; -+ -+ x = networkAddr[0] ^ networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8]; -+ -+ return x & (NAT25_HASH_SIZE - 1); -+ } -+#ifdef CL_IPV6_PASS -+ else if (networkAddr[0] == NAT25_IPV6) { -+ unsigned long x; -+ -+ x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ -+ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10] ^ -+ networkAddr[11] ^ networkAddr[12] ^ networkAddr[13] ^ networkAddr[14] ^ networkAddr[15] ^ -+ networkAddr[16]; -+ -+ return x & (NAT25_HASH_SIZE - 1); -+ } -+#endif -+ else { -+ unsigned long x = 0; -+ int i; -+ -+ for (i = 0; i < MAX_NETWORK_ADDR_LEN; i++) -+ x ^= networkAddr[i]; -+ -+ return x & (NAT25_HASH_SIZE - 1); -+ } -+} -+ -+ -+static __inline__ void __network_hash_link(struct rwnx_vif *vif, -+ struct nat25_network_db_entry *ent, int hash) -+{ -+ /* Caller must _enter_critical_bh already! */ -+ /* _irqL irqL; */ -+ /* _enter_critical_bh(&priv->br_ext_lock, &irqL); */ -+ -+ ent->next_hash = vif->nethash[hash]; -+ if (ent->next_hash != NULL) -+ ent->next_hash->pprev_hash = &ent->next_hash; -+ vif->nethash[hash] = ent; -+ ent->pprev_hash = &vif->nethash[hash]; -+ -+ /* _exit_critical_bh(&priv->br_ext_lock, &irqL); */ -+} -+ -+ -+static __inline__ void __network_hash_unlink(struct nat25_network_db_entry *ent) -+{ -+ /* Caller must _enter_critical_bh already! */ -+ /* _irqL irqL; */ -+ /* _enter_critical_bh(&priv->br_ext_lock, &irqL); */ -+ -+ *(ent->pprev_hash) = ent->next_hash; -+ if (ent->next_hash != NULL) -+ ent->next_hash->pprev_hash = ent->pprev_hash; -+ ent->next_hash = NULL; -+ ent->pprev_hash = NULL; -+ -+ /* _exit_critical_bh(&priv->br_ext_lock, &irqL); */ -+} -+ -+ -+static int __nat25_db_network_lookup_and_replace(struct rwnx_vif *vif, -+ struct sk_buff *skb, unsigned char *networkAddr) -+{ -+ struct nat25_network_db_entry *db; -+ spin_lock_bh(&vif->br_ext_lock); -+ -+ db = vif->nethash[__nat25_network_hash(networkAddr)]; -+ while (db != NULL) { -+ if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { -+ if (!__nat25_has_expired(vif, db)) { -+ /* replace the destination mac address */ -+ memcpy(skb->data, db->macAddr, ETH_ALEN); -+ atomic_inc(&db->use_count); -+ -+#ifdef CL_IPV6_PASS -+ printk("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" -+ "%02x%02x%02x%02x%02x%02x\n", -+ db->macAddr[0], -+ db->macAddr[1], -+ db->macAddr[2], -+ db->macAddr[3], -+ db->macAddr[4], -+ db->macAddr[5], -+ db->networkAddr[0], -+ db->networkAddr[1], -+ db->networkAddr[2], -+ db->networkAddr[3], -+ db->networkAddr[4], -+ db->networkAddr[5], -+ db->networkAddr[6], -+ db->networkAddr[7], -+ db->networkAddr[8], -+ db->networkAddr[9], -+ db->networkAddr[10], -+ db->networkAddr[11], -+ db->networkAddr[12], -+ db->networkAddr[13], -+ db->networkAddr[14], -+ db->networkAddr[15], -+ db->networkAddr[16]); -+#else -+ printk("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", -+ db->macAddr[0], -+ db->macAddr[1], -+ db->macAddr[2], -+ db->macAddr[3], -+ db->macAddr[4], -+ db->macAddr[5], -+ db->networkAddr[0], -+ db->networkAddr[1], -+ db->networkAddr[2], -+ db->networkAddr[3], -+ db->networkAddr[4], -+ db->networkAddr[5], -+ db->networkAddr[6], -+ db->networkAddr[7], -+ db->networkAddr[8], -+ db->networkAddr[9], -+ db->networkAddr[10]); -+#endif -+ } -+ spin_unlock_bh(&vif->br_ext_lock); -+ return 1; -+ } -+ -+ db = db->next_hash; -+ } -+ -+ spin_unlock_bh(&vif->br_ext_lock); -+ return 0; -+} -+ -+ -+static void __nat25_db_network_insert(struct rwnx_vif *vif, -+ unsigned char *macAddr, unsigned char *networkAddr) -+{ -+ struct nat25_network_db_entry *db; -+ int hash; -+ spin_lock_bh(&vif->br_ext_lock); -+ -+ hash = __nat25_network_hash(networkAddr); -+ db = vif->nethash[hash]; -+ -+ while (db != NULL) { -+ if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { -+ memcpy(db->macAddr, macAddr, ETH_ALEN); -+ db->ageing_timer = jiffies; -+ spin_unlock_bh(&vif->br_ext_lock); -+ return; -+ } -+ -+ db = db->next_hash; -+ } -+ -+ db = (struct nat25_network_db_entry *)kmalloc(sizeof(*db), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); -+ if (db == NULL) { -+ spin_unlock_bh(&vif->br_ext_lock); -+ return; -+ } -+ -+ memcpy(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN); -+ memcpy(db->macAddr, macAddr, ETH_ALEN); -+ atomic_set(&db->use_count, 1); -+ db->ageing_timer = jiffies; -+ -+ __network_hash_link(vif, db, hash); -+ -+ spin_unlock_bh(&vif->br_ext_lock); -+} -+ -+ -+static void __nat25_db_print(struct rwnx_vif *vif) -+{ -+ spin_lock_bh(&vif->br_ext_lock); -+ -+#ifdef BR_SUPPORT_DEBUG -+ static int counter = 0; -+ int i, j; -+ struct nat25_network_db_entry *db; -+ -+ counter++; -+ if ((counter % 16) != 0) -+ return; -+ -+ for (i = 0, j = 0; i < NAT25_HASH_SIZE; i++) { -+ db = vif->nethash[i]; -+ -+ while (db != NULL) { -+#ifdef CL_IPV6_PASS -+ printk("NAT25: DB(%d) H(%02d) C(%d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" -+ "%02x%02x%02x%02x%02x%02x\n", -+ j, -+ i, -+ atomic_read(&db->use_count), -+ db->macAddr[0], -+ db->macAddr[1], -+ db->macAddr[2], -+ db->macAddr[3], -+ db->macAddr[4], -+ db->macAddr[5], -+ db->networkAddr[0], -+ db->networkAddr[1], -+ db->networkAddr[2], -+ db->networkAddr[3], -+ db->networkAddr[4], -+ db->networkAddr[5], -+ db->networkAddr[6], -+ db->networkAddr[7], -+ db->networkAddr[8], -+ db->networkAddr[9], -+ db->networkAddr[10], -+ db->networkAddr[11], -+ db->networkAddr[12], -+ db->networkAddr[13], -+ db->networkAddr[14], -+ db->networkAddr[15], -+ db->networkAddr[16]); -+#else -+ printk("NAT25: DB(%d) H(%02d) C(%d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", -+ j, -+ i, -+ atomic_read(&db->use_count), -+ db->macAddr[0], -+ db->macAddr[1], -+ db->macAddr[2], -+ db->macAddr[3], -+ db->macAddr[4], -+ db->macAddr[5], -+ db->networkAddr[0], -+ db->networkAddr[1], -+ db->networkAddr[2], -+ db->networkAddr[3], -+ db->networkAddr[4], -+ db->networkAddr[5], -+ db->networkAddr[6], -+ db->networkAddr[7], -+ db->networkAddr[8], -+ db->networkAddr[9], -+ db->networkAddr[10]); -+#endif -+ j++; -+ -+ db = db->next_hash; -+ } -+ } -+#endif -+ -+ spin_unlock_bh(&vif->br_ext_lock); -+} -+ -+ -+ -+ -+/* -+ * NAT2.5 interface -+ */ -+ -+void nat25_db_cleanup(struct rwnx_vif *vif) -+{ -+ int i; -+ spin_lock_bh(&vif->br_ext_lock); -+ -+ for (i = 0; i < NAT25_HASH_SIZE; i++) { -+ struct nat25_network_db_entry *f; -+ f = vif->nethash[i]; -+ while (f != NULL) { -+ struct nat25_network_db_entry *g; -+ -+ g = f->next_hash; -+ if (vif->scdb_entry == f) { -+ memset(vif->scdb_mac, 0, ETH_ALEN); -+ memset(vif->scdb_ip, 0, 4); -+ vif->scdb_entry = NULL; -+ } -+ __network_hash_unlink(f); -+ kfree(f); -+ -+ f = g; -+ } -+ } -+ -+ spin_unlock_bh(&vif->br_ext_lock); -+} -+ -+ -+void nat25_db_expire(struct rwnx_vif *vif) -+{ -+ int i; -+ spin_lock_bh(&vif->br_ext_lock); -+ -+ /* if(!priv->ethBrExtInfo.nat25_disable) */ -+ { -+ for (i = 0; i < NAT25_HASH_SIZE; i++) { -+ struct nat25_network_db_entry *f; -+ f = vif->nethash[i]; -+ -+ while (f != NULL) { -+ struct nat25_network_db_entry *g; -+ g = f->next_hash; -+ -+ if (__nat25_has_expired(vif, f)) { -+ if (atomic_dec_and_test(&f->use_count)) { -+#ifdef BR_SUPPORT_DEBUG -+#ifdef CL_IPV6_PASS -+ panic_printk("NAT25 Expire H(%02d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" -+ "%02x%02x%02x%02x%02x%02x\n", -+ i, -+ f->macAddr[0], -+ f->macAddr[1], -+ f->macAddr[2], -+ f->macAddr[3], -+ f->macAddr[4], -+ f->macAddr[5], -+ f->networkAddr[0], -+ f->networkAddr[1], -+ f->networkAddr[2], -+ f->networkAddr[3], -+ f->networkAddr[4], -+ f->networkAddr[5], -+ f->networkAddr[6], -+ f->networkAddr[7], -+ f->networkAddr[8], -+ f->networkAddr[9], -+ f->networkAddr[10], -+ f->networkAddr[11], -+ f->networkAddr[12], -+ f->networkAddr[13], -+ f->networkAddr[14], -+ f->networkAddr[15], -+ f->networkAddr[16]); -+#else -+ -+ panic_printk("NAT25 Expire H(%02d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", -+ i, -+ f->macAddr[0], -+ f->macAddr[1], -+ f->macAddr[2], -+ f->macAddr[3], -+ f->macAddr[4], -+ f->macAddr[5], -+ f->networkAddr[0], -+ f->networkAddr[1], -+ f->networkAddr[2], -+ f->networkAddr[3], -+ f->networkAddr[4], -+ f->networkAddr[5], -+ f->networkAddr[6], -+ f->networkAddr[7], -+ f->networkAddr[8], -+ f->networkAddr[9], -+ f->networkAddr[10]); -+#endif -+#endif -+ if (vif->scdb_entry == f) { -+ memset(vif->scdb_mac, 0, ETH_ALEN); -+ memset(vif->scdb_ip, 0, 4); -+ vif->scdb_entry = NULL; -+ } -+ __network_hash_unlink(f); -+ kfree(f); -+ } -+ } -+ -+ f = g; -+ } -+ } -+ } -+ -+ spin_unlock_bh(&vif->br_ext_lock); -+} -+ -+ -+#ifdef SUPPORT_TX_MCAST2UNI -+static int checkIPMcAndReplace(struct rwnx_vif *vif, struct sk_buff *skb, unsigned int *dst_ip) -+{ -+ struct stat_info *pstat; -+ struct list_head *phead, *plist; -+ int i; -+ -+ phead = &vif->asoc_list; -+ plist = phead->next; -+ -+ while (plist != phead) { -+ pstat = list_entry(plist, struct stat_info, asoc_list); -+ plist = plist->next; -+ -+ if (pstat->ipmc_num == 0) -+ continue; -+ -+ for (i = 0; i < MAX_IP_MC_ENTRY; i++) { -+ if (pstat->ipmc[i].used && !memcmp(&pstat->ipmc[i].mcmac[3], ((unsigned char *)dst_ip) + 1, 3)) { -+ memcpy(skb->data, pstat->ipmc[i].mcmac, ETH_ALEN); -+ return 1; -+ } -+ } -+ } -+ return 0; -+} -+#endif -+ -+int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method) -+{ -+ unsigned short protocol; -+ unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; -+ -+ if (skb == NULL) -+ return -1; -+ -+ if ((method <= NAT25_MIN) || (method >= NAT25_MAX)) -+ return -1; -+ -+ protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN)); -+ -+ /*---------------------------------------------------*/ -+ /* Handle IP frame */ -+ /*---------------------------------------------------*/ -+ if (protocol == __constant_htons(ETH_P_IP)) { -+ struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN); -+ -+ if (((unsigned char *)(iph) + (iph->ihl << 2)) >= (skb->data + ETH_HLEN + skb->len)) { -+ printk("NAT25: malformed IP packet !\n"); -+ return -1; -+ } -+ -+ switch (method) { -+ case NAT25_CHECK: -+ return -1; -+ -+ case NAT25_INSERT: { -+ /* some muticast with source IP is all zero, maybe other case is illegal */ -+ /* in class A, B, C, host address is all zero or all one is illegal */ -+ if (iph->saddr == 0) -+ return 0; -+ printk("NAT25: Insert IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr); -+ __nat25_generate_ipv4_network_addr(networkAddr, &iph->saddr); -+ /* record source IP address and , source mac address into db */ -+ __nat25_db_network_insert(vif, skb->data + ETH_ALEN, networkAddr); -+ -+ __nat25_db_print(vif); -+ } -+ return 0; -+ -+ case NAT25_LOOKUP: { -+ printk("NAT25: Lookup IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr); -+#ifdef SUPPORT_TX_MCAST2UNI -+ if (vif->pshare->rf_ft_var.mc2u_disable || -+ ((((OPMODE & (WIFI_STATION_STATE | WIFI_ASOC_STATE)) -+ == (WIFI_STATION_STATE | WIFI_ASOC_STATE)) && -+ !checkIPMcAndReplace(vif, skb, &iph->daddr)) || -+ (OPMODE & WIFI_ADHOC_STATE))) -+#endif -+ { -+ __nat25_generate_ipv4_network_addr(networkAddr, &iph->daddr); -+ -+ if (!__nat25_db_network_lookup_and_replace(vif, skb, networkAddr)) { -+ if (*((unsigned char *)&iph->daddr + 3) == 0xff) { -+ /* L2 is unicast but L3 is broadcast, make L2 bacome broadcast */ -+ printk("NAT25: Set DA as boardcast\n"); -+ memset(skb->data, 0xff, ETH_ALEN); -+ } else { -+ /* forward unknow IP packet to upper TCP/IP */ -+ printk("NAT25: Replace DA with BR's MAC\n"); -+ if ((*(u32 *)vif->br_mac) == 0 && (*(u16 *)(vif->br_mac + 4)) == 0) { -+ void netdev_br_init(struct net_device *netdev); -+ printk("Re-init netdev_br_init() due to br_mac==0!\n"); -+ netdev_br_init(vif->ndev); -+ } -+ memcpy(skb->data, vif->br_mac, ETH_ALEN); -+ } -+ } -+ } -+ } -+ return 0; -+ -+ default: -+ return -1; -+ } -+ } -+ -+ /*---------------------------------------------------*/ -+ /* Handle ARP frame */ -+ /*---------------------------------------------------*/ -+ else if (protocol == __constant_htons(ETH_P_ARP)) { -+ struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN); -+ unsigned char *arp_ptr = (unsigned char *)(arp + 1); -+ unsigned int *sender, *target; -+ -+ if (arp->ar_pro != __constant_htons(ETH_P_IP)) { -+ printk("NAT25: arp protocol unknown (%4x)!\n", htons(arp->ar_pro)); -+ return -1; -+ } -+ -+ switch (method) { -+ case NAT25_CHECK: -+ return 0; /* skb_copy for all ARP frame */ -+ -+ case NAT25_INSERT: { -+ printk("NAT25: Insert ARP, MAC=%02x%02x%02x%02x%02x%02x\n", arp_ptr[0], -+ arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4], arp_ptr[5]); -+ -+ /* change to ARP sender mac address to wlan STA address */ -+ memcpy(arp_ptr, vif->ndev->dev_addr, ETH_ALEN); -+ -+ arp_ptr += arp->ar_hln; -+ sender = (unsigned int *)arp_ptr; -+ -+ __nat25_generate_ipv4_network_addr(networkAddr, sender); -+ -+ __nat25_db_network_insert(vif, skb->data + ETH_ALEN, networkAddr); -+ -+ __nat25_db_print(vif); -+ } -+ return 0; -+ -+ case NAT25_LOOKUP: { -+ printk("NAT25: Lookup ARP\n"); -+ -+ arp_ptr += arp->ar_hln; -+ sender = (unsigned int *)arp_ptr; -+ arp_ptr += (arp->ar_hln + arp->ar_pln); -+ target = (unsigned int *)arp_ptr; -+ -+ __nat25_generate_ipv4_network_addr(networkAddr, target); -+ -+ __nat25_db_network_lookup_and_replace(vif, skb, networkAddr); -+ -+ /* change to ARP target mac address to Lookup result */ -+ arp_ptr = (unsigned char *)(arp + 1); -+ arp_ptr += (arp->ar_hln + arp->ar_pln); -+ memcpy(arp_ptr, skb->data, ETH_ALEN); -+ } -+ return 0; -+ -+ default: -+ return -1; -+ } -+ } -+ -+ /*---------------------------------------------------*/ -+ /* Handle IPX and Apple Talk frame */ -+ /*---------------------------------------------------*/ -+ else if ((protocol == __constant_htons(ETH_P_IPX)) || -+ (protocol == __constant_htons(ETH_P_ATALK)) || -+ (protocol == __constant_htons(ETH_P_AARP))) { -+ unsigned char ipx_header[2] = {0xFF, 0xFF}; -+ struct ipxhdr *ipx = NULL; -+ struct elapaarp *ea = NULL; -+ struct ddpehdr *ddp = NULL; -+ unsigned char *framePtr = skb->data + ETH_HLEN; -+ -+ if (protocol == __constant_htons(ETH_P_IPX)) { -+ printk("NAT25: Protocol=IPX (Ethernet II)\n"); -+ ipx = (struct ipxhdr *)framePtr; -+ } else { /* if(protocol <= __constant_htons(ETH_FRAME_LEN)) */ -+ if (!memcmp(ipx_header, framePtr, 2)) { -+ printk("NAT25: Protocol=IPX (Ethernet 802.3)\n"); -+ ipx = (struct ipxhdr *)framePtr; -+ } else { -+ unsigned char ipx_8022_type = 0xE0; -+ unsigned char snap_8022_type = 0xAA; -+ -+ if (*framePtr == snap_8022_type) { -+ unsigned char ipx_snap_id[5] = {0x0, 0x0, 0x0, 0x81, 0x37}; /* IPX SNAP ID */ -+ unsigned char aarp_snap_id[5] = {0x00, 0x00, 0x00, 0x80, 0xF3}; /* Apple Talk AARP SNAP ID */ -+ unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; /* Apple Talk DDP SNAP ID */ -+ -+ framePtr += 3; /* eliminate the 802.2 header */ -+ -+ if (!memcmp(ipx_snap_id, framePtr, 5)) { -+ framePtr += 5; /* eliminate the SNAP header */ -+ -+ printk("NAT25: Protocol=IPX (Ethernet SNAP)\n"); -+ ipx = (struct ipxhdr *)framePtr; -+ } else if (!memcmp(aarp_snap_id, framePtr, 5)) { -+ framePtr += 5; /* eliminate the SNAP header */ -+ -+ ea = (struct elapaarp *)framePtr; -+ } else if (!memcmp(ddp_snap_id, framePtr, 5)) { -+ framePtr += 5; /* eliminate the SNAP header */ -+ -+ ddp = (struct ddpehdr *)framePtr; -+ } else { -+ printk("NAT25: Protocol=Ethernet SNAP %02x%02x%02x%02x%02x\n", framePtr[0], -+ framePtr[1], framePtr[2], framePtr[3], framePtr[4]); -+ return -1; -+ } -+ } else if (*framePtr == ipx_8022_type) { -+ framePtr += 3; /* eliminate the 802.2 header */ -+ -+ if (!memcmp(ipx_header, framePtr, 2)) { -+ printk("NAT25: Protocol=IPX (Ethernet 802.2)\n"); -+ ipx = (struct ipxhdr *)framePtr; -+ } else -+ return -1; -+ } -+ } -+ } -+ -+ /* IPX */ -+ if (ipx != NULL) { -+ switch (method) { -+ case NAT25_CHECK: -+ if (!memcmp(skb->data + ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) { -+ printk("NAT25: Check IPX skb_copy\n"); -+ return 0; -+ } -+ return -1; -+ -+ case NAT25_INSERT: { -+ printk("NAT25: Insert IPX, Dest=%08x,%02x%02x%02x%02x%02x%02x,%04x Source=%08x,%02x%02x%02x%02x%02x%02x,%04x\n", -+ ipx->ipx_dest.net, -+ ipx->ipx_dest.node[0], -+ ipx->ipx_dest.node[1], -+ ipx->ipx_dest.node[2], -+ ipx->ipx_dest.node[3], -+ ipx->ipx_dest.node[4], -+ ipx->ipx_dest.node[5], -+ ipx->ipx_dest.sock, -+ ipx->ipx_source.net, -+ ipx->ipx_source.node[0], -+ ipx->ipx_source.node[1], -+ ipx->ipx_source.node[2], -+ ipx->ipx_source.node[3], -+ ipx->ipx_source.node[4], -+ ipx->ipx_source.node[5], -+ ipx->ipx_source.sock); -+ -+ if (!memcmp(skb->data + ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) { -+ printk("NAT25: Use IPX Net, and Socket as network addr\n"); -+ -+ __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_source.net, &ipx->ipx_source.sock); -+ -+ /* change IPX source node addr to wlan STA address */ -+ memcpy(ipx->ipx_source.node, vif->ndev->dev_addr, ETH_ALEN); -+ } else -+ __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_source.net, ipx->ipx_source.node); -+ -+ __nat25_db_network_insert(vif, skb->data + ETH_ALEN, networkAddr); -+ -+ __nat25_db_print(vif); -+ } -+ return 0; -+ -+ case NAT25_LOOKUP: { -+ if (!memcmp(vif->ndev->dev_addr, ipx->ipx_dest.node, ETH_ALEN)) { -+ printk("NAT25: Lookup IPX, Modify Destination IPX Node addr\n"); -+ -+ __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_dest.net, &ipx->ipx_dest.sock); -+ -+ __nat25_db_network_lookup_and_replace(vif, skb, networkAddr); -+ -+ /* replace IPX destination node addr with Lookup destination MAC addr */ -+ memcpy(ipx->ipx_dest.node, skb->data, ETH_ALEN); -+ } else { -+ __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_dest.net, ipx->ipx_dest.node); -+ -+ __nat25_db_network_lookup_and_replace(vif, skb, networkAddr); -+ } -+ } -+ return 0; -+ -+ default: -+ return -1; -+ } -+ } -+ -+ /* AARP */ -+ else if (ea != NULL) { -+ /* Sanity check fields. */ -+ if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) { -+ printk("NAT25: Appletalk AARP Sanity check fail!\n"); -+ return -1; -+ } -+ -+ switch (method) { -+ case NAT25_CHECK: -+ return 0; -+ -+ case NAT25_INSERT: { -+ /* change to AARP source mac address to wlan STA address */ -+ memcpy(ea->hw_src, vif->ndev->dev_addr, ETH_ALEN); -+ -+ printk("NAT25: Insert AARP, Source=%d,%d Destination=%d,%d\n", -+ ea->pa_src_net, -+ ea->pa_src_node, -+ ea->pa_dst_net, -+ ea->pa_dst_node); -+ -+ __nat25_generate_apple_network_addr(networkAddr, &ea->pa_src_net, &ea->pa_src_node); -+ -+ __nat25_db_network_insert(vif, skb->data + ETH_ALEN, networkAddr); -+ -+ __nat25_db_print(vif); -+ } -+ return 0; -+ -+ case NAT25_LOOKUP: { -+ printk("NAT25: Lookup AARP, Source=%d,%d Destination=%d,%d\n", -+ ea->pa_src_net, -+ ea->pa_src_node, -+ ea->pa_dst_net, -+ ea->pa_dst_node); -+ -+ __nat25_generate_apple_network_addr(networkAddr, &ea->pa_dst_net, &ea->pa_dst_node); -+ -+ __nat25_db_network_lookup_and_replace(vif, skb, networkAddr); -+ -+ /* change to AARP destination mac address to Lookup result */ -+ memcpy(ea->hw_dst, skb->data, ETH_ALEN); -+ } -+ return 0; -+ -+ default: -+ return -1; -+ } -+ } -+ -+ /* DDP */ -+ else if (ddp != NULL) { -+ switch (method) { -+ case NAT25_CHECK: -+ return -1; -+ -+ case NAT25_INSERT: { -+ printk("NAT25: Insert DDP, Source=%d,%d Destination=%d,%d\n", -+ ddp->deh_snet, -+ ddp->deh_snode, -+ ddp->deh_dnet, -+ ddp->deh_dnode); -+ -+ __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_snet, &ddp->deh_snode); -+ -+ __nat25_db_network_insert(vif, skb->data + ETH_ALEN, networkAddr); -+ -+ __nat25_db_print(vif); -+ } -+ return 0; -+ -+ case NAT25_LOOKUP: { -+ printk("NAT25: Lookup DDP, Source=%d,%d Destination=%d,%d\n", -+ ddp->deh_snet, -+ ddp->deh_snode, -+ ddp->deh_dnet, -+ ddp->deh_dnode); -+ -+ __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_dnet, &ddp->deh_dnode); -+ -+ __nat25_db_network_lookup_and_replace(vif, skb, networkAddr); -+ } -+ return 0; -+ -+ default: -+ return -1; -+ } -+ } -+ -+ return -1; -+ } -+ -+ /*---------------------------------------------------*/ -+ /* Handle PPPoE frame */ -+ /*---------------------------------------------------*/ -+ else if ((protocol == __constant_htons(ETH_P_PPP_DISC)) || -+ (protocol == __constant_htons(ETH_P_PPP_SES))) { -+ struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); -+ unsigned short *pMagic; -+ -+ switch (method) { -+ case NAT25_CHECK: -+ if (ph->sid == 0) -+ return 0; -+ return 1; -+ -+ case NAT25_INSERT: -+ if (ph->sid == 0) { /* Discovery phase according to tag */ -+ if (ph->code == PADI_CODE || ph->code == PADR_CODE) { -+ if (vif->ethBrExtInfo.addPPPoETag) { -+ struct pppoe_tag *tag, *pOldTag; -+ unsigned char tag_buf[40]; -+ int old_tag_len = 0; -+ -+ tag = (struct pppoe_tag *)tag_buf; -+ pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID)); -+ if (pOldTag) { /* if SID existed, copy old value and delete it */ -+ old_tag_len = ntohs(pOldTag->tag_len); -+ if (old_tag_len + TAG_HDR_LEN + MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN > sizeof(tag_buf)) { -+ printk("SID tag length too long!\n"); -+ return -1; -+ } -+ -+ memcpy(tag->tag_data + MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN, -+ pOldTag->tag_data, old_tag_len); -+ -+ if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN + old_tag_len) < 0) { -+ printk("call skb_pull_and_merge() failed in PADI/R packet!\n"); -+ return -1; -+ } -+ ph->length = htons(ntohs(ph->length) - TAG_HDR_LEN - old_tag_len); -+ } -+ -+ tag->tag_type = PTT_RELAY_SID; -+ tag->tag_len = htons(MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN + old_tag_len); -+ -+ /* insert the magic_code+client mac in relay tag */ -+ pMagic = (unsigned short *)tag->tag_data; -+ *pMagic = htons(MAGIC_CODE); -+ memcpy(tag->tag_data + MAGIC_CODE_LEN, skb->data + ETH_ALEN, ETH_ALEN); -+ -+ /* Add relay tag */ -+ if (__nat25_add_pppoe_tag(skb, tag) < 0) -+ return -1; -+ -+ printk("NAT25: Insert PPPoE, forward %s packet\n", -+ (ph->code == PADI_CODE ? "PADI" : "PADR")); -+ } else { /* not add relay tag */ -+ if (vif->pppoe_connection_in_progress && -+ memcmp(skb->data + ETH_ALEN, vif->pppoe_addr, ETH_ALEN)) { -+ printk("Discard PPPoE packet due to another PPPoE connection is in progress!\n"); -+ return -2; -+ } -+ -+ if (vif->pppoe_connection_in_progress == 0) -+ memcpy(vif->pppoe_addr, skb->data + ETH_ALEN, ETH_ALEN); -+ -+ vif->pppoe_connection_in_progress = WAIT_TIME_PPPOE; -+ } -+ } else -+ return -1; -+ } else { /* session phase */ -+ printk("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name); -+ -+ __nat25_generate_pppoe_network_addr(networkAddr, skb->data, &(ph->sid)); -+ -+ __nat25_db_network_insert(vif, skb->data + ETH_ALEN, networkAddr); -+ -+ __nat25_db_print(vif); -+ -+ if (!vif->ethBrExtInfo.addPPPoETag && -+ vif->pppoe_connection_in_progress && -+ !memcmp(skb->data + ETH_ALEN, vif->pppoe_addr, ETH_ALEN)) -+ vif->pppoe_connection_in_progress = 0; -+ } -+ return 0; -+ -+ case NAT25_LOOKUP: -+ if (ph->code == PADO_CODE || ph->code == PADS_CODE) { -+ if (vif->ethBrExtInfo.addPPPoETag) { -+ struct pppoe_tag *tag; -+ unsigned char *ptr; -+ unsigned short tagType, tagLen; -+ int offset = 0; -+ -+ ptr = __nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID)); -+ if (ptr == 0) { -+ printk("Fail to find PTT_RELAY_SID in FADO!\n"); -+ return -1; -+ } -+ -+ tag = (struct pppoe_tag *)ptr; -+ tagType = (unsigned short)((ptr[0] << 8) + ptr[1]); -+ tagLen = (unsigned short)((ptr[2] << 8) + ptr[3]); -+ -+ if ((tagType != ntohs(PTT_RELAY_SID)) || (tagLen < (MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN))) { -+ printk("Invalid PTT_RELAY_SID tag length [%d]!\n", tagLen); -+ return -1; -+ } -+ -+ pMagic = (unsigned short *)tag->tag_data; -+ if (ntohs(*pMagic) != MAGIC_CODE) { -+ printk("Can't find MAGIC_CODE in %s packet!\n", -+ (ph->code == PADO_CODE ? "PADO" : "PADS")); -+ return -1; -+ } -+ -+ memcpy(skb->data, tag->tag_data + MAGIC_CODE_LEN, ETH_ALEN); -+ -+ if (tagLen > MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN) -+ offset = TAG_HDR_LEN; -+ -+ if (skb_pull_and_merge(skb, ptr + offset, TAG_HDR_LEN + MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN - offset) < 0) { -+ printk("call skb_pull_and_merge() failed in PADO packet!\n"); -+ return -1; -+ } -+ ph->length = htons(ntohs(ph->length) - (TAG_HDR_LEN + MAGIC_CODE_LEN + RTL_RELAY_TAG_LEN - offset)); -+ if (offset > 0) -+ tag->tag_len = htons(tagLen - MAGIC_CODE_LEN - RTL_RELAY_TAG_LEN); -+ -+ printk("NAT25: Lookup PPPoE, forward %s Packet from %s\n", -+ (ph->code == PADO_CODE ? "PADO" : "PADS"), skb->dev->name); -+ } else { /* not add relay tag */ -+ if (!vif->pppoe_connection_in_progress) { -+ printk("Discard PPPoE packet due to no connection in progresss!\n"); -+ return -1; -+ } -+ memcpy(skb->data, vif->pppoe_addr, ETH_ALEN); -+ vif->pppoe_connection_in_progress = WAIT_TIME_PPPOE; -+ } -+ } else { -+ if (ph->sid != 0) { -+ printk("NAT25: Lookup PPPoE, lookup session packet from %s\n", skb->dev->name); -+ __nat25_generate_pppoe_network_addr(networkAddr, skb->data + ETH_ALEN, &(ph->sid)); -+ -+ __nat25_db_network_lookup_and_replace(vif, skb, networkAddr); -+ -+ __nat25_db_print(vif); -+ } else -+ return -1; -+ -+ } -+ return 0; -+ -+ default: -+ return -1; -+ } -+ } -+ -+ /*---------------------------------------------------*/ -+ /* Handle EAP frame */ -+ /*---------------------------------------------------*/ -+ else if (protocol == __constant_htons(0x888e)) { -+ switch (method) { -+ case NAT25_CHECK: -+ return -1; -+ -+ case NAT25_INSERT: -+ return 0; -+ -+ case NAT25_LOOKUP: -+ return 0; -+ -+ default: -+ return -1; -+ } -+ } -+ -+ /*---------------------------------------------------*/ -+ /* Handle C-Media proprietary frame */ -+ /*---------------------------------------------------*/ -+ else if ((protocol == __constant_htons(0xe2ae)) || -+ (protocol == __constant_htons(0xe2af))) { -+ switch (method) { -+ case NAT25_CHECK: -+ return -1; -+ -+ case NAT25_INSERT: -+ return 0; -+ -+ case NAT25_LOOKUP: -+ return 0; -+ -+ default: -+ return -1; -+ } -+ } -+ -+ /*---------------------------------------------------*/ -+ /* Handle IPV6 frame */ -+ /*---------------------------------------------------*/ -+#ifdef CL_IPV6_PASS -+ else if (protocol == __constant_htons(ETH_P_IPV6)) { -+ struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN); -+ -+ if (sizeof(*iph) >= (skb->len - ETH_HLEN)) { -+ printk("NAT25: malformed IPv6 packet !\n"); -+ return -1; -+ } -+ -+ switch (method) { -+ case NAT25_CHECK: -+ if (skb->data[0] & 1) -+ return 0; -+ return -1; -+ -+ case NAT25_INSERT: { -+ printk("NAT25: Insert IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," -+ " DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", -+ iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3], -+ iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7], -+ iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3], -+ iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]); -+ -+ if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) { -+ __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr); -+ __nat25_db_network_insert(vif, skb->data + ETH_ALEN, networkAddr); -+ __nat25_db_print(vif); -+ -+ if (iph->nexthdr == IPPROTO_ICMPV6 && -+ skb->len > (ETH_HLEN + sizeof(*iph) + 4)) { -+ if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph), -+ skb->len - ETH_HLEN - sizeof(*iph), vif->ndev->dev_addr)) { -+ struct icmp6hdr *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph)); -+ hdr->icmp6_cksum = 0; -+ hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr, -+ iph->payload_len, -+ IPPROTO_ICMPV6, -+ csum_partial((__u8 *)hdr, iph->payload_len, 0)); -+ } -+ } -+ } -+ } -+ return 0; -+ -+ case NAT25_LOOKUP: -+ printk("NAT25: Lookup IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," -+ " DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", -+ iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3], -+ iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7], -+ iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3], -+ iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]); -+ -+ -+ __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->daddr); -+ if (!__nat25_db_network_lookup_and_replace(vif, skb, networkAddr)) { -+#ifdef SUPPORT_RX_UNI2MCAST -+ if (iph->daddr.s6_addr[0] == 0xff) -+ convert_ipv6_mac_to_mc(skb); -+#endif -+ } -+ return 0; -+ -+ default: -+ return -1; -+ } -+ } -+#endif /* CL_IPV6_PASS */ -+ -+ return -1; -+} -+ -+ -+int nat25_handle_frame(struct rwnx_vif *vif, struct sk_buff *skb) -+{ -+ //printk("%s : vif_type=%d \n",__func__,RWNX_VIF_TYPE(vif)); -+#ifdef BR_SUPPORT_DEBUG -+ if ((!vif->ethBrExtInfo.nat25_disable) && (!(skb->data[0] & 1))) { -+ printk("NAT25: Input Frame: DA=%02x%02x%02x%02x%02x%02x SA=%02x%02x%02x%02x%02x%02x\n", -+ skb->data[0], -+ skb->data[1], -+ skb->data[2], -+ skb->data[3], -+ skb->data[4], -+ skb->data[5], -+ skb->data[6], -+ skb->data[7], -+ skb->data[8], -+ skb->data[9], -+ skb->data[10], -+ skb->data[11]); -+ } -+#endif -+ -+ if (!(skb->data[0] & 1)) { -+ int is_vlan_tag = 0, i, retval = 0; -+ unsigned short vlan_hdr = 0; -+ -+ if (*((unsigned short *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_8021Q)) { -+ is_vlan_tag = 1; -+ vlan_hdr = *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)); -+ for (i = 0; i < 6; i++) -+ *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + ETH_ALEN * 2 - 2 - i * 2)); -+ skb_pull(skb, 4); -+ } -+ -+ if (!vif->ethBrExtInfo.nat25_disable) { -+ unsigned long irqL; -+ spin_lock_bh(&vif->br_ext_lock); -+ /* -+ * This function look up the destination network address from -+ * the NAT2.5 database. Return value = -1 means that the -+ * corresponding network protocol is NOT support. -+ */ -+ if (!vif->ethBrExtInfo.nat25sc_disable && -+ (*((unsigned short *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_IP)) && -+ !memcmp(vif->scdb_ip, skb->data + ETH_HLEN + 16, 4)) { -+ memcpy(skb->data, vif->scdb_mac, ETH_ALEN); -+ -+ spin_unlock_bh(&vif->br_ext_lock); -+ } else { -+ spin_unlock_bh(&vif->br_ext_lock); -+ -+ retval = nat25_db_handle(vif, skb, NAT25_LOOKUP); -+ } -+ } else { -+ if (((*((unsigned short *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_IP)) && -+ !memcmp(vif->br_ip, skb->data + ETH_HLEN + 16, 4)) || -+ ((*((unsigned short *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_ARP)) && -+ !memcmp(vif->br_ip, skb->data + ETH_HLEN + 24, 4))) { -+ /* for traffic to upper TCP/IP */ -+ retval = nat25_db_handle(vif, skb, NAT25_LOOKUP); -+ } -+ } -+ -+ if (is_vlan_tag) { -+ skb_push(skb, 4); -+ for (i = 0; i < 6; i++) -+ *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2)); -+ *((unsigned short *)(skb->data + ETH_ALEN * 2)) = __constant_htons(ETH_P_8021Q); -+ *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)) = vlan_hdr; -+ } -+ -+ if (retval == -1) { -+ /* DEBUG_ERR("NAT25: Lookup fail!\n"); */ -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+#if 0 -+void mac_clone(_adapter *priv, unsigned char *addr) -+{ -+ struct sockaddr sa; -+ -+ memcpy(sa.sa_data, addr, ETH_ALEN); -+ RTW_INFO("MAC Clone: Addr=%02x%02x%02x%02x%02x%02x\n", -+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); -+ rtl8192cd_set_hwaddr(priv->dev, &sa); -+} -+ -+ -+int mac_clone_handle_frame(_adapter *priv, struct sk_buff *skb) -+{ -+ if (priv->ethBrExtInfo.macclone_enable && !priv->macclone_completed) { -+ if (!(skb->data[ETH_ALEN] & 1)) { /* check any other particular MAC add */ -+ if (memcmp(skb->data + ETH_ALEN, GET_MY_HWADDR(priv), ETH_ALEN) && -+ ((priv->dev->br_port) && -+ memcmp(skb->data + ETH_ALEN, priv->br_mac, ETH_ALEN))) { -+ mac_clone(priv, skb->data + ETH_ALEN); -+ priv->macclone_completed = 1; -+ } -+ } -+ } -+ -+ return 0; -+} -+#endif /* 0 */ -+ -+#define SERVER_PORT 67 -+#define CLIENT_PORT 68 -+#define DHCP_MAGIC 0x63825363 -+#define BROADCAST_FLAG 0x8000 -+ -+struct dhcpMessage { -+ u_int8_t op; -+ u_int8_t htype; -+ u_int8_t hlen; -+ u_int8_t hops; -+ u_int32_t xid; -+ u_int16_t secs; -+ u_int16_t flags; -+ u_int32_t ciaddr; -+ u_int32_t yiaddr; -+ u_int32_t siaddr; -+ u_int32_t giaddr; -+ u_int8_t chaddr[16]; -+ u_int8_t sname[64]; -+ u_int8_t file[128]; -+ u_int32_t cookie; -+ u_int8_t options[308]; /* 312 - cookie */ -+}; -+ -+void dhcp_flag_bcast(struct rwnx_vif *vif, struct sk_buff *skb) -+{ -+ if (skb == NULL) -+ return; -+ //print_hex_dump(KERN_ERR, "SKB DUMP: SKB->DATA== ", DUMP_PREFIX_NONE, 32, 1, skb->data, 64,false); -+ if (!vif->ethBrExtInfo.dhcp_bcst_disable) { -+ unsigned short protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN)); -+ printk("%s protocol: %04x\n", __func__, protocol); -+ -+ if (protocol == __constant_htons(ETH_P_IP)) { /* IP */ -+ struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN); -+ -+ if (iph->protocol == IPPROTO_UDP) { /* UDP */ -+ struct udphdr *udph = (struct udphdr *)((u8 *)iph + (iph->ihl << 2)); -+ -+ if ((udph->source == __constant_htons(CLIENT_PORT)) -+ && (udph->dest == __constant_htons(SERVER_PORT))) { /* DHCP request */ -+ struct dhcpMessage *dhcph = -+ (struct dhcpMessage *)((u8 *)udph + sizeof(struct udphdr)); -+ -+ if (dhcph->cookie == __constant_htonl(DHCP_MAGIC)) { /* match magic word */ -+ if (!(dhcph->flags & htons(BROADCAST_FLAG))) { /* if not broadcast */ -+ register int sum = 0; -+ -+ printk("DHCP: change flag of DHCP request to broadcast.\n"); -+ -+ #if 1 -+ /* or BROADCAST flag */ -+ dhcph->flags |= htons(BROADCAST_FLAG); -+ /* recalculate checksum */ -+ sum = ~(udph->check) & 0xffff; -+ sum += dhcph->flags; -+ while (sum >> 16) -+ sum = (sum & 0xffff) + (sum >> 16); -+ udph->check = ~sum; -+ #endif -+ } -+ } -+ } -+ } -+ } -+ } -+} -+ -+ -+void *scdb_findEntry(struct rwnx_vif *vif, unsigned char *macAddr, -+ unsigned char *ipAddr) -+{ -+ printk("%s()\n",__func__); -+ unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; -+ struct nat25_network_db_entry *db; -+ int hash; -+ /* _irqL irqL; */ -+ /* _enter_critical_bh(&priv->br_ext_lock, &irqL); */ -+ -+ __nat25_generate_ipv4_network_addr(networkAddr, (unsigned int *)ipAddr); -+ hash = __nat25_network_hash(networkAddr); -+ db = vif->nethash[hash]; -+ while (db != NULL) { -+ if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { -+ /* _exit_critical_bh(&priv->br_ext_lock, &irqL); */ -+ return (void *)db; -+ } -+ -+ db = db->next_hash; -+ } -+ -+ /* _exit_critical_bh(&priv->br_ext_lock, &irqL); */ -+ return NULL; -+} -+ -+#endif /* CONFIG_BR_SUPPORT */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_br_ext.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_br_ext.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_br_ext.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_br_ext.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,73 @@ -+/****************************************************************************** -+ * -+ * Copyright(c) 2007 - 2017 Realtek Corporation. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of version 2 of the GNU General Public License as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ *****************************************************************************/ -+#ifndef _AIC_BR_EXT_H_ -+#define _AIC_BR_EXT_H_ -+ -+#define CL_IPV6_PASS 1 -+#define MACADDRLEN 6 -+#define WLAN_ETHHDR_LEN 14 -+ -+#define NAT25_HASH_BITS 4 -+#define NAT25_HASH_SIZE (1 << NAT25_HASH_BITS) -+#define NAT25_AGEING_TIME 300 -+ -+#define NDEV_FMT "%s" -+#define NDEV_ARG(ndev) ndev->name -+#define ADPT_FMT "%s" -+//#define ADPT_ARG(adapter) (adapter->pnetdev ? adapter->pnetdev->name : NULL) -+#define FUNC_NDEV_FMT "%s(%s)" -+#define FUNC_NDEV_ARG(ndev) __func__, ndev->name -+#define FUNC_ADPT_FMT "%s(%s)" -+//#define FUNC_ADPT_ARG(adapter) __func__, (adapter->pnetdev ? adapter->pnetdev->name : NULL) -+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -+#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5] -+ -+ -+#ifdef CL_IPV6_PASS -+ #define MAX_NETWORK_ADDR_LEN 17 -+#else -+ #define MAX_NETWORK_ADDR_LEN 11 -+#endif -+ -+struct nat25_network_db_entry { -+ struct nat25_network_db_entry *next_hash; -+ struct nat25_network_db_entry **pprev_hash; -+ atomic_t use_count; -+ unsigned char macAddr[6]; -+ unsigned long ageing_timer; -+ unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; -+}; -+ -+enum NAT25_METHOD { -+ NAT25_MIN, -+ NAT25_CHECK, -+ NAT25_INSERT, -+ NAT25_LOOKUP, -+ NAT25_PARSE, -+ NAT25_MAX -+}; -+ -+struct br_ext_info { -+ unsigned int nat25_disable; -+ unsigned int macclone_enable; -+ unsigned int dhcp_bcst_disable; -+ int addPPPoETag; /* 1: Add PPPoE relay-SID, 0: disable */ -+ unsigned char nat25_dmzMac[MACADDRLEN]; -+ unsigned int nat25sc_disable; -+}; -+ -+void nat25_db_cleanup(struct rwnx_vif *vif); -+ -+#endif /* _AIC_BR_EXT_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_bsp_export.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_bsp_export.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_bsp_export.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_bsp_export.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,58 @@ -+#ifndef __AIC_BSP_EXPORT_H -+#define __AIC_BSP_EXPORT_H -+ -+enum aicbsp_subsys { -+ AIC_BLUETOOTH, -+ AIC_WIFI, -+}; -+ -+enum aicbsp_pwr_state { -+ AIC_PWR_OFF, -+ AIC_PWR_ON, -+}; -+ -+struct aicbsp_feature_t { -+ int hwinfo; -+ uint32_t sdio_clock; -+ uint8_t sdio_phase; -+ int fwlog_en; -+ uint8_t irqf; -+}; -+ -+enum skb_buff_id { -+ AIC_RESV_MEM_TXDATA, -+}; -+ -+#ifdef CONFIG_DPD -+typedef struct { -+ uint32_t bit_mask[3]; -+ uint32_t reserved; -+ uint32_t dpd_high[96]; -+ uint32_t dpd_11b[96]; -+ uint32_t dpd_low[96]; -+ uint32_t idac_11b[48]; -+ uint32_t idac_high[48]; -+ uint32_t idac_low[48]; -+ uint32_t loft_res[18]; -+ uint32_t rx_iqim_res[16]; -+} rf_misc_ram_t; -+ -+typedef struct { -+ uint32_t bit_mask[4]; -+ uint32_t dpd_high[96]; -+ uint32_t loft_res[18]; -+} rf_misc_ram_lite_t; -+ -+#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -+#define DPD_RESULT_SIZE_8800DC sizeof(rf_misc_ram_lite_t) -+ -+extern rf_misc_ram_lite_t dpd_res; -+#endif -+ -+int aicbsp_set_subsys(int, int); -+int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path); -+bool aicbsp_get_load_fw_in_fdrv(void); -+struct sk_buff *aicbsp_resv_mem_alloc_skb(unsigned int length, uint32_t id); -+void aicbsp_resv_mem_kfree_skb(struct sk_buff *skb, uint32_t id); -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_btsdio.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_btsdio.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_btsdio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_btsdio.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,1310 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "aic_btsdio.h" -+#include "rwnx_msg_tx.h" -+ -+static spinlock_t queue_lock; -+ -+static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how) -+{ -+ struct sk_buff *skb; -+ -+ if ((skb = alloc_skb(len + BT_SKB_RESERVE, how))) { -+ skb_reserve(skb, BT_SKB_RESERVE); -+ bt_cb(skb)->incoming = 0; -+ } -+ return skb; -+} -+ -+static spinlock_t queue_lock; -+static spinlock_t dlfw_lock; -+static volatile uint16_t dlfw_dis_state = 0; -+ -+/* Global parameters for bt usb char driver */ -+#define BT_CHAR_DEVICE_NAME "aicbt_dev" -+struct mutex btchr_mutex; -+static struct sk_buff_head btchr_readq; -+static wait_queue_head_t btchr_read_wait; -+static wait_queue_head_t bt_dlfw_wait; -+static int bt_char_dev_registered; -+static dev_t bt_devid; /* bt char device number */ -+static struct cdev bt_char_dev; /* bt character device structure */ -+static struct class *bt_char_class; /* device class for usb char driver */ -+static int bt_reset = 0; -+//int aic_queue_cnt(void); -+/* HCI device & lock */ -+DEFINE_RWLOCK(hci_dev_lock); -+ -+struct hci_dev *ghdev = NULL; -+ -+static struct sk_buff *aic_skb_queue[QUEUE_SIZE]; -+static int aic_skb_queue_front = 0; -+static int aic_skb_queue_rear = 0; -+ -+static inline int check_set_dlfw_state_value(uint16_t change_value) -+{ -+ spin_lock(&dlfw_lock); -+ if(!dlfw_dis_state) { -+ dlfw_dis_state = change_value; -+ } -+ spin_unlock(&dlfw_lock); -+ return dlfw_dis_state; -+} -+ -+static inline void set_dlfw_state_value(uint16_t change_value) -+{ -+ spin_lock(&dlfw_lock); -+ dlfw_dis_state = change_value; -+ spin_unlock(&dlfw_lock); -+} -+ -+static void print_acl(struct sk_buff *skb, int direction) -+{ -+#if PRINT_ACL_DATA -+ //uint wlength = skb->len; -+ u16 *handle = (u16 *)(skb->data); -+ u16 len = *(handle+1); -+ //u8 *acl_data = (u8 *)(skb->data); -+ -+ AICBT_INFO("aic %s: direction %d, handle %04x, len %d", -+ __func__, direction, *handle, len); -+#endif -+} -+ -+static void print_sco(struct sk_buff *skb, int direction) -+{ -+#if PRINT_SCO_DATA -+ uint wlength = skb->len; -+ u16 *handle = (u16 *)(skb->data); -+ u8 len = *(u8 *)(handle+1); -+ //u8 *sco_data =(u8 *)(skb->data); -+ -+ AICBT_INFO("aic %s: direction %d, handle %04x, len %d,wlength %d", -+ __func__, direction, *handle, len,wlength); -+#endif -+} -+ -+int bt_bypass_event(struct sk_buff *skb) -+{ -+ int ret = 0; -+ u8 *opcode = (u8*)(skb->data); -+ //u8 len = *(opcode+1); -+ //printk("bypass_event %x,%x,%x,%x,%x\r\n",opcode[0],opcode[1],opcode[2],opcode[3],opcode[4]); -+ -+ switch(opcode[1]) { -+ case HCI_EV_LE_Meta: -+ { -+ u8 subevent_code; -+ subevent_code = opcode[3]; -+ switch(subevent_code){ -+ case HCI_BLE_ADV_PKT_RPT_EVT: -+ case HCI_LE_EXTENDED_ADVERTISING_REPORT_EVT: -+ { -+ if(aic_queue_cnt() > (QUEUE_SIZE-490)){ -+ printk("more adv report bypass\r\n"); -+ ret = 1; -+ } -+ } -+ break; -+ } -+ } -+ break; -+ default: -+ break; -+ } -+ return ret; -+} -+ -+int bt_sdio_recv(u8 *data,u32 data_len) -+{ -+ struct sk_buff *skb; -+ int type= data[0]; -+ struct hci_dev *hdev; -+ u32 len = data_len; -+ //int ret=0; -+ hdev = hci_dev_get(0); -+ if (!hdev) { -+ AICWFDBG(LOGERROR,"%s: Failed to get hci dev[NULL]", __func__); -+ return -ENODEV; -+ } -+ -+ //printk("%s type %x len %d \n",__func__,type,len); -+ //bt_data_dump("bt_recv", ind->bt_data, 64); -+ -+ /*#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(3, 18, 0)) -+ if (hci_recv_fragment(hdev, type, -+ ind->bt_data[0], -+ ind->data_len) < 0) { -+ AICWFDBG(LOGERROR,"%s: Corrupted event packet", __func__); -+ hdev->stat.err_rx++; -+ } -+ #endif*/ -+ skb = alloc_skb(len,GFP_ATOMIC); -+ if(!skb){ -+ AICWFDBG(LOGERROR, "alloc skb fail %s \n",__func__); -+ } -+ memcpy(skb_put(skb,len) ,data, len); -+ if(bt_bypass_event(skb)){ -+ kfree_skb(skb); -+ return 0; -+ } -+ //bt_data_dump("bt_skb", skb, skb->len); -+ -+ if(aic_enqueue(skb)<0){ -+ kfree_skb(skb); -+ }else{ -+ //printk("wake up \n"); -+ wake_up_interruptible(&btchr_read_wait); -+ } -+ return 0; -+} -+ -+ -+static int bypass_event(struct sk_buff *skb) -+{ -+ int ret = 0; -+ u8 *opcode = (u8*)(skb->data); -+ //u8 len = *(opcode+1); -+ //printk("bypass_event %x,%x,%x,%x,%x\r\n",opcode[0],opcode[1],opcode[2],opcode[3],opcode[4]); -+ -+ switch(*opcode) { -+#ifdef CONFIG_SUPPORT_VENDOR_APCF -+ case HCI_EV_CMD_COMPLETE: -+ { -+ u16 sub_opcpde; -+ sub_opcpde = ((u16)opcode[3]|(u16)(opcode[4])<<8); -+ if(sub_opcpde == 0xfd57){ -+ if(vendor_apcf_sent_done){ -+ vendor_apcf_sent_done--; -+ printk("apcf bypass\r\n"); -+ ret = 1; -+ } -+ } -+ } -+ break; -+#endif//CONFIG_SUPPORT_VENDOR_APCF -+ case HCI_EV_LE_Meta: -+ { -+ u8 subevent_code; -+ subevent_code = opcode[2]; -+ switch(subevent_code){ -+ case HCI_BLE_ADV_PKT_RPT_EVT: -+ case HCI_LE_EXTENDED_ADVERTISING_REPORT_EVT: -+ { -+ if(aic_queue_cnt() > (QUEUE_SIZE-100)){ -+ printk("more adv report bypass\r\n"); -+ ret = 1; -+ } -+ } -+ break; -+ } -+ } -+ break; -+ default: -+ break; -+ } -+ return ret; -+} -+static void print_event(struct sk_buff *skb) -+{ -+#if PRINT_CMD_EVENT -+ //uint wlength = skb->len; -+ //uint icount = 0; -+ u8 *opcode = (u8*)(skb->data); -+ //u8 len = *(opcode+1); -+ -+ printk("aic %s ", __func__); -+ switch (*opcode) { -+ case HCI_EV_INQUIRY_COMPLETE: -+ printk("HCI_EV_INQUIRY_COMPLETE"); -+ break; -+ case HCI_EV_INQUIRY_RESULT: -+ printk("HCI_EV_INQUIRY_RESULT"); -+ break; -+ case HCI_EV_CONN_COMPLETE: -+ printk("HCI_EV_CONN_COMPLETE"); -+ break; -+ case HCI_EV_CONN_REQUEST: -+ printk("HCI_EV_CONN_REQUEST"); -+ break; -+ case HCI_EV_DISCONN_COMPLETE: -+ printk("HCI_EV_DISCONN_COMPLETE"); -+ break; -+ case HCI_EV_AUTH_COMPLETE: -+ printk("HCI_EV_AUTH_COMPLETE"); -+ break; -+ case HCI_EV_REMOTE_NAME: -+ printk("HCI_EV_REMOTE_NAME"); -+ break; -+ case HCI_EV_ENCRYPT_CHANGE: -+ printk("HCI_EV_ENCRYPT_CHANGE"); -+ break; -+ case HCI_EV_CHANGE_LINK_KEY_COMPLETE: -+ printk("HCI_EV_CHANGE_LINK_KEY_COMPLETE"); -+ break; -+ case HCI_EV_REMOTE_FEATURES: -+ printk("HCI_EV_REMOTE_FEATURES"); -+ break; -+ case HCI_EV_REMOTE_VERSION: -+ printk("HCI_EV_REMOTE_VERSION"); -+ break; -+ case HCI_EV_QOS_SETUP_COMPLETE: -+ printk("HCI_EV_QOS_SETUP_COMPLETE"); -+ break; -+ case HCI_EV_CMD_COMPLETE: -+ printk("HCI_EV_CMD_COMPLETE"); -+ break; -+ case HCI_EV_CMD_STATUS: -+ printk("HCI_EV_CMD_STATUS"); -+ break; -+ case HCI_EV_ROLE_CHANGE: -+ printk("HCI_EV_ROLE_CHANGE"); -+ break; -+ case HCI_EV_NUM_COMP_PKTS: -+ printk("HCI_EV_NUM_COMP_PKTS"); -+ break; -+ case HCI_EV_MODE_CHANGE: -+ printk("HCI_EV_MODE_CHANGE"); -+ break; -+ case HCI_EV_PIN_CODE_REQ: -+ printk("HCI_EV_PIN_CODE_REQ"); -+ break; -+ case HCI_EV_LINK_KEY_REQ: -+ printk("HCI_EV_LINK_KEY_REQ"); -+ break; -+ case HCI_EV_LINK_KEY_NOTIFY: -+ printk("HCI_EV_LINK_KEY_NOTIFY"); -+ break; -+ case HCI_EV_CLOCK_OFFSET: -+ printk("HCI_EV_CLOCK_OFFSET"); -+ break; -+ case HCI_EV_PKT_TYPE_CHANGE: -+ printk("HCI_EV_PKT_TYPE_CHANGE"); -+ break; -+ case HCI_EV_PSCAN_REP_MODE: -+ printk("HCI_EV_PSCAN_REP_MODE"); -+ break; -+ case HCI_EV_INQUIRY_RESULT_WITH_RSSI: -+ printk("HCI_EV_INQUIRY_RESULT_WITH_RSSI"); -+ break; -+ case HCI_EV_REMOTE_EXT_FEATURES: -+ printk("HCI_EV_REMOTE_EXT_FEATURES"); -+ break; -+ case HCI_EV_SYNC_CONN_COMPLETE: -+ printk("HCI_EV_SYNC_CONN_COMPLETE"); -+ break; -+ case HCI_EV_SYNC_CONN_CHANGED: -+ printk("HCI_EV_SYNC_CONN_CHANGED"); -+ break; -+ case HCI_EV_SNIFF_SUBRATE: -+ printk("HCI_EV_SNIFF_SUBRATE"); -+ break; -+ case HCI_EV_EXTENDED_INQUIRY_RESULT: -+ printk("HCI_EV_EXTENDED_INQUIRY_RESULT"); -+ break; -+ case HCI_EV_IO_CAPA_REQUEST: -+ printk("HCI_EV_IO_CAPA_REQUEST"); -+ break; -+ case HCI_EV_SIMPLE_PAIR_COMPLETE: -+ printk("HCI_EV_SIMPLE_PAIR_COMPLETE"); -+ break; -+ case HCI_EV_REMOTE_HOST_FEATURES: -+ printk("HCI_EV_REMOTE_HOST_FEATURES"); -+ break; -+ default: -+ printk("unknow event"); -+ break; -+ } -+ printk("\n"); -+#if 0 -+ printk("%02x,len:%d,", *opcode,len); -+ for (icount = 2; (icount < wlength) && (icount < 24); icount++) -+ printk("%02x ", *(opcode+icount)); -+ printk("\n"); -+#endif -+#endif -+} -+ -+ -+static inline ssize_t sdio_put_user(struct sk_buff *skb, -+ char __user *buf, int count) -+{ -+ char __user *ptr = buf; -+ int len = min_t(unsigned int, skb->len, count); -+ -+ if (copy_to_user(ptr, skb->data, len)) -+ return -EFAULT; -+ -+ return len; -+} -+ -+int aic_enqueue(struct sk_buff *skb) -+{ -+ unsigned long flags = 0; -+ int ret = 0; -+ spin_lock_irqsave(&queue_lock, flags); -+ if (aic_skb_queue_front == (aic_skb_queue_rear + 1) % QUEUE_SIZE) { -+ /* -+ * If queue is full, current solution is to drop -+ * the following entries. -+ */ -+ AICBT_WARN("%s: Queue is full, entry will be dropped", __func__); -+ ret = -1; -+ } else { -+ aic_skb_queue[aic_skb_queue_rear] = skb; -+ -+ aic_skb_queue_rear++; -+ aic_skb_queue_rear %= QUEUE_SIZE; -+ -+ } -+ spin_unlock_irqrestore(&queue_lock, flags); -+ return ret; -+} -+ -+static struct sk_buff *aic_dequeue_try(unsigned int deq_len) -+{ -+ struct sk_buff *skb; -+ struct sk_buff *skb_copy; -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&queue_lock, flags); -+ if (aic_skb_queue_front == aic_skb_queue_rear) { -+ AICBT_WARN("%s: Queue is empty", __func__); -+ spin_unlock_irqrestore(&queue_lock, flags); -+ return NULL; -+ } -+ -+ skb = aic_skb_queue[aic_skb_queue_front]; -+ if (deq_len >= skb->len) { -+ -+ aic_skb_queue_front++; -+ aic_skb_queue_front %= QUEUE_SIZE; -+ -+ /* -+ * Return skb addr to be dequeued, and the caller -+ * should free the skb eventually. -+ */ -+ spin_unlock_irqrestore(&queue_lock, flags); -+ return skb; -+ } else { -+ skb_copy = pskb_copy(skb, GFP_ATOMIC); -+ skb_pull(skb, deq_len); -+ /* Return its copy to be freed */ -+ spin_unlock_irqrestore(&queue_lock, flags); -+ return skb_copy; -+ } -+} -+ -+static inline int is_queue_empty(void) -+{ -+ return (aic_skb_queue_front == aic_skb_queue_rear) ? 1 : 0; -+} -+ -+void aic_clear_queue(void) -+{ -+ struct sk_buff *skb; -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&queue_lock, flags); -+ while(!is_queue_empty()) { -+ skb = aic_skb_queue[aic_skb_queue_front]; -+ aic_skb_queue[aic_skb_queue_front] = NULL; -+ aic_skb_queue_front++; -+ aic_skb_queue_front %= QUEUE_SIZE; -+ if (skb) { -+ kfree_skb(skb); -+ } -+ } -+ spin_unlock_irqrestore(&queue_lock, flags); -+} -+ -+int aic_queue_cnt(void) -+{ -+ int ret_cnt = 0; -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&queue_lock, flags); -+ if(is_queue_empty()) { -+ ret_cnt = 0; -+ }else{ -+ if(aic_skb_queue_rear > aic_skb_queue_front){ -+ ret_cnt = aic_skb_queue_rear-aic_skb_queue_front; -+ }else{ -+ ret_cnt = aic_skb_queue_rear+QUEUE_SIZE-aic_skb_queue_front; -+ } -+ } -+ spin_unlock_irqrestore(&queue_lock, flags); -+ return ret_cnt; -+} -+ -+/* -+ * AicSemi - Integrate from hci_core.c -+ */ -+ -+/* Get HCI device by index. -+ * Device is held on return. */ -+struct hci_dev *hci_dev_get(int index) -+{ -+ if (index != 0) -+ return NULL; -+ -+ return ghdev; -+} -+ -+/* ---- HCI ioctl helpers ---- */ -+static int hci_dev_open(__u16 dev) -+{ -+ struct hci_dev *hdev; -+ int ret = 0; -+ -+ AICBT_DBG("%s: dev %d", __func__, dev); -+ -+ hdev = hci_dev_get(dev); -+ if (!hdev) { -+ AICBT_ERR("%s: Failed to get hci dev[Null]", __func__); -+ return -ENODEV; -+ } -+ -+ /*if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { -+ ret = -ENODEV; -+ goto done; -+ } -+ -+ if (test_bit(HCI_UP, &hdev->flags)) { -+ ret = -EALREADY; -+ goto done; -+ }*/ -+ -+done: -+ return ret; -+} -+ -+static int hci_dev_do_close(struct hci_dev *hdev) -+{ -+ //if (hdev->flush) -+ // hdev->flush(hdev); -+ /* After this point our queues are empty -+ * and no tasks are scheduled. */ -+ //hdev->close(hdev); -+ /* Clear flags */ -+ hdev->flags = 0; -+ return 0; -+} -+ -+static int hci_dev_close(__u16 dev) -+{ -+ struct hci_dev *hdev; -+ int err; -+ hdev = hci_dev_get(dev); -+ if (!hdev) { -+ AICBT_ERR("%s: failed to get hci dev[Null]", __func__); -+ return -ENODEV; -+ } -+ -+ err = hci_dev_do_close(hdev); -+ -+ return err; -+} -+ -+#if CONFIG_BLUEDROID -+static struct hci_dev *hci_alloc_dev(void) -+{ -+ struct hci_dev *hdev; -+ -+ hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); -+ if (!hdev) -+ return NULL; -+ -+ return hdev; -+} -+ -+/* Free HCI device */ -+static void hci_free_dev(struct hci_dev *hdev) -+{ -+ kfree(hdev); -+} -+ -+/* Register HCI device */ -+static int hci_register_dev(struct hci_dev *hdev) -+{ -+ int i, id; -+ -+ AICBT_DBG("%s: %p name %s bus %d", __func__, hdev, hdev->name, hdev->bus); -+ /* Do not allow HCI_AMP devices to register at index 0, -+ * so the index can be used as the AMP controller ID. -+ */ -+ id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; -+ -+ write_lock(&hci_dev_lock); -+ -+ sprintf(hdev->name, "hci%d", id); -+ hdev->id = id; -+ hdev->flags = 0; -+ hdev->dev_flags = 0; -+ mutex_init(&hdev->lock); -+ -+ AICBT_DBG("%s: id %d, name %s", __func__, hdev->id, hdev->name); -+ -+ -+ for (i = 0; i < NUM_REASSEMBLY; i++) -+ hdev->reassembly[i] = NULL; -+ -+ memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); -+ atomic_set(&hdev->promisc, 0); -+ -+ if (ghdev) { -+ write_unlock(&hci_dev_lock); -+ AICBT_ERR("%s: Hci device has been registered already", __func__); -+ return -1; -+ } else -+ ghdev = hdev; -+ -+ write_unlock(&hci_dev_lock); -+ -+ return id; -+} -+ -+/* Unregister HCI device */ -+static void hci_unregister_dev(struct hci_dev *hdev) -+{ -+ int i; -+ -+ AICBT_DBG("%s: hdev %p name %s bus %d", __func__, hdev, hdev->name, hdev->bus); -+ set_bit(HCI_UNREGISTER, &hdev->dev_flags); -+ -+ write_lock(&hci_dev_lock); -+ ghdev = NULL; -+ write_unlock(&hci_dev_lock); -+ -+ hci_dev_do_close(hdev); -+ for (i = 0; i < NUM_REASSEMBLY; i++) -+ kfree_skb(hdev->reassembly[i]); -+} -+ -+static void hci_send_to_stack(struct hci_dev *hdev, struct sk_buff *skb) -+{ -+ struct sk_buff *aic_skb_copy = NULL; -+ -+ //AICBT_DBG("%s", __func__); -+ -+ if (!hdev) { -+ AICBT_ERR("%s: Frame for unknown HCI device", __func__); -+ return; -+ } -+ -+ if (!test_bit(HCI_RUNNING, &hdev->flags)) { -+ AICBT_ERR("%s: HCI not running", __func__); -+ return; -+ } -+ -+ aic_skb_copy = pskb_copy(skb, GFP_ATOMIC); -+ if (!aic_skb_copy) { -+ AICBT_ERR("%s: Copy skb error", __func__); -+ return; -+ } -+ -+ memcpy(skb_push(aic_skb_copy, 1), &bt_cb(skb)->pkt_type, 1); -+ aic_enqueue(aic_skb_copy); -+ -+ /* Make sure bt char device existing before wakeup read queue */ -+ hdev = hci_dev_get(0); -+ if (hdev) { -+ //AICBT_DBG("%s: Try to wakeup read queue", __func__); -+ AICBT_DBG("%s", __func__); -+ wake_up_interruptible(&btchr_read_wait); -+ } -+ -+ -+ return; -+} -+ -+/* Receive frame from HCI drivers */ -+static int hci_recv_frame(struct sk_buff *skb) -+{ -+ struct hci_dev *hdev = (struct hci_dev *) skb->dev; -+ -+ if (!hdev || -+ (!test_bit(HCI_UP, &hdev->flags) && !test_bit(HCI_INIT, &hdev->flags))) { -+ kfree_skb(skb); -+ return -ENXIO; -+ } -+ -+ /* Incomming skb */ -+ bt_cb(skb)->incoming = 1; -+ -+ /* Time stamp */ -+ __net_timestamp(skb); -+ -+ if (atomic_read(&hdev->promisc)) { -+#ifdef CONFIG_SCO_OVER_HCI -+ if(bt_cb(skb)->pkt_type == HCI_SCODATA_PKT){ -+ hci_send_to_alsa_ringbuffer(hdev, skb); -+ }else{ -+ if(bt_cb(skb)->pkt_type == HCI_EVENT_PKT){ -+ if(bypass_event(skb)){ -+ kfree_skb(skb); -+ return 0; -+ } -+ } -+ hci_send_to_stack(hdev, skb); -+ } -+#else -+ if(bt_cb(skb)->pkt_type == HCI_EVENT_PKT){ -+ if(bypass_event(skb)){ -+ kfree_skb(skb); -+ return 0; -+ } -+ } -+ /* Send copy to the sockets */ -+ hci_send_to_stack(hdev, skb); -+#endif -+ -+ } -+ -+ kfree_skb(skb); -+ return 0; -+} -+ -+ -+ -+static int hci_reassembly(struct hci_dev *hdev, int type, void *data, -+ int count, __u8 index) -+{ -+ int len = 0; -+ int hlen = 0; -+ int remain = count; -+ struct sk_buff *skb; -+ struct bt_skb_cb *scb; -+ -+ //AICBT_DBG("%s", __func__); -+ -+ if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || -+ index >= NUM_REASSEMBLY) -+ return -EILSEQ; -+ -+ skb = hdev->reassembly[index]; -+ -+ if (!skb) { -+ switch (type) { -+ case HCI_ACLDATA_PKT: -+ len = HCI_MAX_FRAME_SIZE; -+ hlen = HCI_ACL_HDR_SIZE; -+ break; -+ case HCI_EVENT_PKT: -+ len = HCI_MAX_EVENT_SIZE; -+ hlen = HCI_EVENT_HDR_SIZE; -+ break; -+ case HCI_SCODATA_PKT: -+ len = HCI_MAX_SCO_SIZE; -+ hlen = HCI_SCO_HDR_SIZE; -+ break; -+ } -+ -+ skb = bt_skb_alloc(len, GFP_ATOMIC); -+ if (!skb) -+ return -ENOMEM; -+ -+ scb = (void *) skb->cb; -+ scb->expect = hlen; -+ scb->pkt_type = type; -+ -+ skb->dev = (void *) hdev; -+ hdev->reassembly[index] = skb; -+ } -+ -+ while (count) { -+ scb = (void *) skb->cb; -+ len = min_t(uint, scb->expect, count); -+ -+ memcpy(skb_put(skb, len), data, len); -+ -+ count -= len; -+ data += len; -+ scb->expect -= len; -+ remain = count; -+ -+ switch (type) { -+ case HCI_EVENT_PKT: -+ if (skb->len == HCI_EVENT_HDR_SIZE) { -+ struct hci_event_hdr *h = hci_event_hdr(skb); -+ scb->expect = h->plen; -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ hdev->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ break; -+ -+ case HCI_ACLDATA_PKT: -+ if (skb->len == HCI_ACL_HDR_SIZE) { -+ struct hci_acl_hdr *h = hci_acl_hdr(skb); -+ scb->expect = __le16_to_cpu(h->dlen); -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ hdev->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ break; -+ -+ case HCI_SCODATA_PKT: -+ if (skb->len == HCI_SCO_HDR_SIZE) { -+ struct hci_sco_hdr *h = hci_sco_hdr(skb); -+ scb->expect = h->dlen; -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ hdev->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ break; -+ } -+ -+ if (scb->expect == 0) { -+ /* Complete frame */ -+ if(HCI_ACLDATA_PKT == type) -+ print_acl(skb,0); -+ if(HCI_SCODATA_PKT == type) -+ print_sco(skb,0); -+ if(HCI_EVENT_PKT == type) -+ print_event(skb); -+ -+ bt_cb(skb)->pkt_type = type; -+ hci_recv_frame(skb); -+ -+ hdev->reassembly[index] = NULL; -+ return remain; -+ } -+ } -+ -+ return remain; -+} -+ -+int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) -+{ -+ int rem = 0; -+ -+ if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) -+ return -EILSEQ; -+ -+ while (count) { -+ rem = hci_reassembly(hdev, type, data, count, type - 1); -+ if (rem < 0) -+ return rem; -+ -+ data += (count - rem); -+ count = rem; -+ } -+ -+ return rem; -+} -+#endif //CONFIG_BLUEDROID -+ -+static int btchr_open(struct inode *inode_p, struct file *file_p) -+{ -+ struct btusb_data *data; -+ struct hci_dev *hdev; -+ -+ AICBT_DBG("%s: BT sdio char device is opening", __func__); -+ /* Not open unless wanna tracing log */ -+ /* trace_printk("%s: open....\n", __func__); */ -+ -+ hdev = hci_dev_get(0); -+ if (!hdev) { -+ AICBT_DBG("%s: Failed to get hci dev[NULL]", __func__); -+ return -ENODEV; -+ } -+ data = GET_DRV_DATA(hdev); -+ -+ atomic_inc(&hdev->promisc); -+ /* -+ * As bt device is not re-opened when hotplugged out, we cannot -+ * trust on file's private data(may be null) when other file ops -+ * are invoked. -+ */ -+ file_p->private_data = data; -+ -+ mutex_lock(&btchr_mutex); -+ hci_dev_open(0); -+ mutex_unlock(&btchr_mutex); -+ -+ aic_clear_queue(); -+ return nonseekable_open(inode_p, file_p); -+} -+ -+static int btchr_close(struct inode *inode_p, struct file *file_p) -+{ -+ struct btusb_data *data; -+ struct hci_dev *hdev; -+ -+ AICBT_INFO("%s: BT sdio char device is closing", __func__); -+ /* Not open unless wanna tracing log */ -+ /* trace_printk("%s: close....\n", __func__); */ -+ -+ data = file_p->private_data; -+ file_p->private_data = NULL; -+ -+#if CONFIG_BLUEDROID -+ /* -+ * If the upper layer closes bt char interfaces, no reset -+ * action required even bt device hotplugged out. -+ */ -+ bt_reset = 0; -+#endif -+ -+ hdev = hci_dev_get(0); -+ if (hdev) { -+ atomic_set(&hdev->promisc, 0); -+ mutex_lock(&btchr_mutex); -+ hci_dev_close(0); -+ mutex_unlock(&btchr_mutex); -+ } -+ -+ return 0; -+} -+ -+void bt_data_dump(char* tag, void* data, unsigned long len){ -+ unsigned long i = 0; -+ uint8_t* data_ = (uint8_t* )data; -+ -+ printk("%s %s len:(%lu)\r\n", __func__, tag, len); -+ -+ for (i = 0; i < len; i += 16){ -+ printk("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n", -+ data_[0 + i], -+ data_[1 + i], -+ data_[2 + i], -+ data_[3 + i], -+ data_[4 + i], -+ data_[5 + i], -+ data_[6 + i], -+ data_[7 + i], -+ data_[8 + i], -+ data_[9 + i], -+ data_[10 + i], -+ data_[11 + i], -+ data_[12 + i], -+ data_[13 + i], -+ data_[14 + i], -+ data_[15 + i]); -+ } -+ -+} -+ -+static ssize_t btchr_read(struct file *file_p, -+ char __user *buf_p, -+ size_t count, -+ loff_t *pos_p) -+{ -+ struct hci_dev *hdev; -+ struct sk_buff *skb; -+ ssize_t ret = 0; -+ -+ while (count) { -+#if 1 -+ hdev = hci_dev_get(0); -+ if (!hdev) { -+ /* -+ * Note: Only when BT device hotplugged out, we wil get -+ * into such situation. In order to keep the upper layer -+ * stack alive (blocking the read), we should never return -+ * EFAULT or break the loop. -+ */ -+ AICBT_ERR("%s: Failed to get hci dev[Null]", __func__); -+ } -+#endif -+ ret = wait_event_interruptible(btchr_read_wait, !is_queue_empty()); -+ if (ret < 0) { -+ AICBT_ERR("%s: wait event is signaled %d", __func__, (int)ret); -+ break; -+ } -+ -+ skb = aic_dequeue_try(count); -+ //bt_data_dump("btchr_read", skb->data, skb->len); -+ //printk("btchr_read \n"); -+ if (skb) { -+ ret = sdio_put_user(skb, buf_p, count); -+ if (ret < 0) -+ AICBT_ERR("%s: Failed to put data to user space", __func__); -+ kfree_skb(skb); -+ break; -+ } -+ } -+ -+ return ret; -+} -+ -+#ifdef CONFIG_SUPPORT_VENDOR_APCF -+void btchr_external_write(char* buff, int len){ -+ struct hci_dev *hdev; -+ struct sk_buff *skb; -+ int i; -+ struct btusb_data *data; -+ -+ AICBT_INFO("%s \r\n", __func__); -+ for(i=0;idev = (void *)hdev; -+ memcpy((__u8 *)skb->data,(__u8 *)buff,len); -+ skb_put(skb, len); -+ bt_cb(skb)->pkt_type = *((__u8 *)skb->data); -+ skb_pull(skb, 1); -+ data->hdev->send(skb); -+} -+ -+EXPORT_SYMBOL(btchr_external_write); -+#endif //CONFIG_SUPPORT_VENDOR_APCF -+ -+//extern struct rwnx_plat *g_rwnx_plat; -+static ssize_t btchr_write(struct file *file_p, -+ const char __user *buf_p, -+ size_t count, -+ loff_t *pos_p) -+{ -+ struct btusb_data *data = file_p->private_data; -+ struct hci_dev *hdev; -+ struct sk_buff *skb; -+ int err=0; -+ -+ AICBT_DBG("%s", __func__); -+ -+ hdev = hci_dev_get(0); -+ if (!hdev) { -+ AICBT_WARN("%s: Failed to get hci dev[Null]", __func__); -+ /* -+ * Note: we bypass the data from the upper layer if bt device -+ * is hotplugged out. Fortunatelly, H4 or H5 HCI stack does -+ * NOT check btchr_write's return value. However, returning -+ * count instead of EFAULT is preferable. -+ */ -+ /* return -EFAULT; */ -+ return count; -+ } -+ -+#if 0 -+ /* Never trust on btusb_data, as bt device may be hotplugged out */ -+ data = GET_DRV_DATA(hdev); -+ if (!data) { -+ AICBT_WARN("%s: Failed to get bt usb driver data[Null]", __func__); -+ return count; -+ } -+#endif -+ -+ if (count > HCI_MAX_FRAME_SIZE) -+ return -EINVAL; -+ -+ skb = bt_skb_alloc(count, GFP_ATOMIC); -+ if (!skb) -+ return -ENOMEM; -+ skb_reserve(skb, -1); // Add this line -+ -+ if (copy_from_user(skb_put(skb, count), buf_p, count)) { -+ AICBT_ERR("%s: Failed to get data from user space", __func__); -+ kfree_skb(skb); -+ return -EFAULT; -+ } -+ -+ skb->dev = (void *)hdev; -+ bt_cb(skb)->pkt_type = *((__u8 *)skb->data); -+ //skb_pull(skb, 1); -+ //data->hdev->send(skb); -+ -+ //bt_data_dump("btwrite", skb->data, skb->len); -+ err = rwnx_sdio_bt_send_req(g_rwnx_plat->sdiodev->rwnx_hw, skb->len, skb); -+ if(err<0){ -+ printk("%s rwnx_sdio_bt_send_req error %d",__func__,err); -+ } -+ -+ kfree_skb(skb); -+ return count; -+} -+ -+static unsigned int btchr_poll(struct file *file_p, poll_table *wait) -+{ -+ struct btusb_data *data = file_p->private_data; -+ struct hci_dev *hdev; -+ -+ //AICBT_DBG("%s: BT sdio char device is polling", __func__); -+ -+ /*if(!bt_char_dev_registered) { -+ AICBT_ERR("%s: char device has not registered!", __func__); -+ return POLLERR | POLLHUP; -+ }*/ -+ //printk("poll wait\n"); -+ poll_wait(file_p, &btchr_read_wait, wait); -+ //printk("poll out\n"); -+ -+ hdev = hci_dev_get(0); -+ if (!hdev) { -+ AICBT_ERR("%s: Failed to get hci dev[Null]", __func__); -+ //mdelay(URB_CANCELING_DELAY_MS); -+ return POLLERR | POLLHUP; -+ return POLLOUT | POLLWRNORM; -+ } -+ -+#if 0 -+ /* Never trust on btusb_data, as bt device may be hotplugged out */ -+ data = GET_DRV_DATA(hdev); -+ if (!data) { -+ /* -+ * When bt device is hotplugged out, btusb_data will -+ * be freed in disconnect. -+ */ -+ AICBT_ERR("%s: Failed to get bt sdio driver data[Null]", __func__); -+ mdelay(URB_CANCELING_DELAY_MS); -+ return POLLOUT | POLLWRNORM; -+ } -+#endif -+ -+ if (!is_queue_empty()) -+ return POLLIN | POLLRDNORM; -+ -+ return POLLOUT | POLLWRNORM; -+} -+static long btchr_ioctl(struct file *file_p,unsigned int cmd, unsigned long arg) -+{ -+ int ret = 0; -+ struct hci_dev *hdev; -+ struct btusb_data *data; -+ //firmware_info *fw_info; -+ -+ /*if(!bt_char_dev_registered) { -+ return -ENODEV; -+ }*/ -+ -+ printk("%s cmd support %d \n",__func__,cmd); -+ -+#if 1 -+ if(check_set_dlfw_state_value(1) != 1) { -+ AICBT_ERR("%s bt controller is disconnecting!", __func__); -+ return 0; -+ } -+ -+ hdev = hci_dev_get(0); -+ if(!hdev) { -+ AICBT_ERR("%s device is NULL!", __func__); -+ set_dlfw_state_value(0); -+ return 0; -+ } -+ //data = GET_DRV_DATA(hdev); -+ //fw_info = data->fw_info; -+ -+ AICBT_INFO(" btchr_ioctl DOWN_FW_CFG with Cmd:%d",cmd); -+ switch (cmd) { -+ case DOWN_FW_CFG: -+ AICBT_INFO(" btchr_ioctl DOWN_FW_CFG"); -+ /*ret = usb_autopm_get_interface(data->intf); -+ if (ret < 0){ -+ goto failed; -+ }*/ -+ -+ //ret = download_patch(fw_info,1); -+ /*usb_autopm_put_interface(data->intf); -+ if(ret < 0){ -+ AICBT_ERR("%s:Failed in download_patch with ret:%d",__func__,ret); -+ goto failed; -+ } -+ -+ ret = hdev->open(hdev); -+ if(ret < 0){ -+ AICBT_ERR("%s:Failed in hdev->open(hdev):%d",__func__,ret); -+ goto failed; -+ }*/ -+ set_bit(HCI_UP, &hdev->flags); -+ set_dlfw_state_value(0); -+ wake_up_interruptible(&bt_dlfw_wait); -+ return 1; -+ case DWFW_CMPLT: -+ AICBT_INFO(" btchr_ioctl DWFW_CMPLT"); -+#if 1 -+ case SET_ISO_CFG: -+ AICBT_INFO("btchr_ioctl SET_ISO_CFG"); -+ if(copy_from_user(&(hdev->voice_setting), (__u16*)arg, sizeof(__u16))){ -+ AICBT_INFO(" voice settings err"); -+ } -+ //hdev->voice_setting = *(uint16_t*)arg; -+ AICBT_INFO(" voice settings = %d", hdev->voice_setting); -+ //return 1; -+#endif -+ case GET_USB_INFO: -+ //ret = download_patch(fw_info,1); -+ AICBT_INFO(" btchr_ioctl GET_USB_INFO"); -+ /*ret = hdev->open(hdev); -+ if(ret < 0){ -+ AICBT_ERR("%s:Failed in hdev->open(hdev):%d",__func__,ret); -+ //goto done; -+ }*/ -+ set_bit(HCI_UP, &hdev->flags); -+ set_dlfw_state_value(0); -+ wake_up_interruptible(&bt_dlfw_wait); -+ return 1; -+ case RESET_CONTROLLER: -+ AICBT_INFO(" btchr_ioctl RESET_CONTROLLER"); -+ //reset_controller(fw_info); -+ return 1; -+ default: -+ AICBT_ERR("%s:Failed with wrong Cmd:%d",__func__,cmd); -+ goto failed; -+ } -+ failed: -+ set_dlfw_state_value(0); -+ wake_up_interruptible(&bt_dlfw_wait); -+ return ret; -+#endif -+} -+ -+#ifdef CONFIG_PLATFORM_UBUNTU//AIDEN -+typedef u32 compat_uptr_t; -+static inline void __user *compat_ptr(compat_uptr_t uptr) -+{ -+ return (void __user *)(unsigned long)uptr; -+} -+#endif -+ -+#ifdef CONFIG_COMPAT -+static long compat_btchr_ioctl (struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ AICBT_DBG("%s: enter",__func__); -+ return btchr_ioctl(filp, cmd, (unsigned long) compat_ptr(arg)); -+} -+#endif -+static struct file_operations bt_chrdev_ops = { -+ open : btchr_open, -+ release : btchr_close, -+ read : btchr_read, -+ write : btchr_write, -+ poll : btchr_poll, -+ unlocked_ioctl : btchr_ioctl, -+#ifdef CONFIG_COMPAT -+ compat_ioctl : compat_btchr_ioctl, -+#endif -+}; -+ -+int btchr_init() -+{ -+ int res = 0; -+ struct device *dev; -+ -+ AICBT_INFO("Register sdio char device interface for BT driver"); -+ /* -+ * btchr mutex is used to sync between -+ * 1) downloading patch and opening bt char driver -+ * 2) the file operations of bt char driver -+ */ -+ mutex_init(&btchr_mutex); -+ -+ skb_queue_head_init(&btchr_readq); -+ init_waitqueue_head(&btchr_read_wait); -+ init_waitqueue_head(&bt_dlfw_wait); -+ -+ bt_char_class = class_create(THIS_MODULE, BT_CHAR_DEVICE_NAME); -+ if (IS_ERR(bt_char_class)) { -+ AICBT_ERR("Failed to create bt char class"); -+ return PTR_ERR(bt_char_class); -+ } -+ -+ res = alloc_chrdev_region(&bt_devid, 0, 1, BT_CHAR_DEVICE_NAME); -+ if (res < 0) { -+ AICBT_ERR("Failed to allocate bt char device"); -+ goto err_alloc; -+ } -+ -+ dev = device_create(bt_char_class, NULL, bt_devid, NULL, BT_CHAR_DEVICE_NAME); -+ if (IS_ERR(dev)) { -+ AICBT_ERR("Failed to create bt char device"); -+ res = PTR_ERR(dev); -+ goto err_create; -+ } -+ -+ cdev_init(&bt_char_dev, &bt_chrdev_ops); -+ res = cdev_add(&bt_char_dev, bt_devid, 1); -+ if (res < 0) { -+ AICBT_ERR("Failed to add bt char device"); -+ goto err_add; -+ } -+ -+ return 0; -+ -+err_add: -+ device_destroy(bt_char_class, bt_devid); -+err_create: -+ unregister_chrdev_region(bt_devid, 1); -+err_alloc: -+ class_destroy(bt_char_class); -+ return res; -+} -+ -+void btchr_exit(void) -+{ -+ AICBT_INFO("Unregister sdio char device interface for BT driver"); -+ -+ device_destroy(bt_char_class, bt_devid); -+ cdev_del(&bt_char_dev); -+ unregister_chrdev_region(bt_devid, 1); -+ class_destroy(bt_char_class); -+ -+ return; -+} -+ -+int hdev_init(void) -+{ -+ struct hci_dev *hdev; -+ int err=0; -+ hdev = hci_alloc_dev(); -+ -+ err = hci_register_dev(hdev); -+ if (err < 0) { -+ hci_free_dev(hdev); -+ hdev = NULL; -+ return err; -+ } -+ -+ spin_lock_init(&queue_lock); -+ -+ return 0; -+} -+ -+void hdev_exit(void) -+{ -+ struct hci_dev *hdev; -+ hdev = ghdev; -+ hci_unregister_dev(hdev); -+ hci_free_dev(hdev); -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_btsdio.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_btsdio.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_btsdio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_btsdio.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,549 @@ -+#ifndef _AICWF_SDIO_BT_H_ -+#define _AICWF_SDIO_BT_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+ -+#ifdef CONFIG_PLATFORM_UBUNTU -+#define CONFIG_BLUEDROID 1 /* bleuz 0, bluedroid 1 */ -+#else -+#define CONFIG_BLUEDROID 1 /* bleuz 0, bluedroid 1 */ -+#endif -+/* #define HCI_VERSION_CODE KERNEL_VERSION(3, 14, 41) */ -+#define HCI_VERSION_CODE LINUX_VERSION_CODE -+ -+ -+#define PRINT_CMD_EVENT 1 -+#define PRINT_ACL_DATA 1 -+#define PRINT_SCO_DATA 1 -+ -+#define AICBT_DBG_FLAG 1 -+ -+#if AICBT_DBG_FLAG -+#define AICBT_DBG(fmt, arg...) printk( "aic_btsdio: " fmt "\n" , ## arg) -+#else -+#define AICBT_DBG(fmt, arg...) -+#endif -+ -+#define AICBT_INFO(fmt, arg...) printk("aic_btsdio: " fmt "\n" , ## arg) -+#define AICBT_WARN(fmt, arg...) printk("aic_btsdio: " fmt "\n" , ## arg) -+#define AICBT_ERR(fmt, arg...) printk("aic_btsdio: " fmt "\n" , ## arg) -+ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 0) -+#define GET_DRV_DATA(x) hci_get_drvdata(x) -+#else -+#define GET_DRV_DATA(x) x->driver_data -+#endif -+ -+struct btusb_data { -+ struct hci_dev *hdev; -+ //struct usb_device *udev; -+ //struct usb_interface *intf; -+ //struct usb_interface *isoc; -+ -+ spinlock_t lock; -+ -+ unsigned long flags; -+ -+ struct work_struct work; -+ struct work_struct waker; -+ -+ /*struct usb_anchor tx_anchor; -+ struct usb_anchor intr_anchor; -+ struct usb_anchor bulk_anchor; -+ struct usb_anchor isoc_anchor; -+ struct usb_anchor deferred;*/ -+ int tx_in_flight; -+ spinlock_t txlock; -+ -+#if (CONFIG_BLUEDROID == 0) -+#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) -+ spinlock_t rxlock; -+ struct sk_buff *evt_skb; -+ struct sk_buff *acl_skb; -+ struct sk_buff *sco_skb; -+#endif -+#endif -+ -+ /*struct usb_endpoint_descriptor *intr_ep; -+ struct usb_endpoint_descriptor *bulk_tx_ep; -+ struct usb_endpoint_descriptor *bulk_rx_ep; -+ struct usb_endpoint_descriptor *isoc_tx_ep; -+ struct usb_endpoint_descriptor *isoc_rx_ep;*/ -+ -+ __u8 cmdreq_type; -+ -+ unsigned int sco_num; -+ int isoc_altsetting; -+ int suspend_count; -+ uint16_t sco_handle; -+ -+#if (CONFIG_BLUEDROID == 0) -+#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) -+ int (*recv_bulk) (struct btusb_data * data, void *buffer, int count); -+#endif -+#endif -+ -+//#ifdef CONFIG_HAS_EARLYSUSPEND -+#if 0 -+ struct early_suspend early_suspend; -+#else -+ struct notifier_block pm_notifier; -+ struct notifier_block reboot_notifier; -+#endif -+ //firmware_info *fw_info; -+ -+#ifdef CONFIG_SCO_OVER_HCI -+ AIC_sco_card_t *pSCOSnd; -+#endif -+}; -+ -+ -+ -+#define QUEUE_SIZE 500 -+ -+/*************************************** -+** AicSemi - Integrate from bluetooth.h ** -+*****************************************/ -+/* Reserv for core and drivers use */ -+#define BT_SKB_RESERVE 8 -+ -+/* BD Address */ -+typedef struct { -+ __u8 b[6]; -+} __packed bdaddr_t; -+ -+/* Skb helpers */ -+struct bt_skb_cb { -+ __u8 pkt_type; -+ __u8 incoming; -+ __u16 expect; -+ __u16 tx_seq; -+ __u8 retries; -+ __u8 sar; -+ __u8 force_active; -+}; -+ -+#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) -+ -+ -+/*********************************** -+** AicSemi - Integrate from hci.h ** -+***********************************/ -+#define HCI_MAX_ACL_SIZE 1024 -+#define HCI_MAX_SCO_SIZE 255 -+#define HCI_MAX_EVENT_SIZE 260 -+#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) -+ -+/* HCI bus types */ -+#define HCI_VIRTUAL 0 -+#define HCI_USB 1 -+#define HCI_PCCARD 2 -+#define HCI_UART 3 -+#define HCI_RS232 4 -+#define HCI_PCI 5 -+#define HCI_SDIO 6 -+ -+/* HCI controller types */ -+#define HCI_BREDR 0x00 -+#define HCI_AMP 0x01 -+ -+/* HCI device flags */ -+enum { -+ HCI_UP, -+ HCI_INIT, -+ HCI_RUNNING, -+ -+ HCI_PSCAN, -+ HCI_ISCAN, -+ HCI_AUTH, -+ HCI_ENCRYPT, -+ HCI_INQUIRY, -+ -+ HCI_RAW, -+ -+ HCI_RESET, -+}; -+ -+/* -+ * BR/EDR and/or LE controller flags: the flags defined here should represent -+ * states from the controller. -+ */ -+enum { -+ HCI_SETUP, -+ HCI_AUTO_OFF, -+ HCI_MGMT, -+ HCI_PAIRABLE, -+ HCI_SERVICE_CACHE, -+ HCI_LINK_KEYS, -+ HCI_DEBUG_KEYS, -+ HCI_UNREGISTER, -+ -+ HCI_LE_SCAN, -+ HCI_SSP_ENABLED, -+ HCI_HS_ENABLED, -+ HCI_LE_ENABLED, -+ HCI_CONNECTABLE, -+ HCI_DISCOVERABLE, -+ HCI_LINK_SECURITY, -+ HCI_PENDING_CLASS, -+}; -+ -+/* HCI data types */ -+#define HCI_COMMAND_PKT 0x01 -+#define HCI_ACLDATA_PKT 0x02 -+#define HCI_SCODATA_PKT 0x03 -+#define HCI_EVENT_PKT 0x04 -+#define HCI_VENDOR_PKT 0xff -+ -+#define HCI_MAX_NAME_LENGTH 248 -+#define HCI_MAX_EIR_LENGTH 240 -+ -+#define HCI_OP_READ_LOCAL_VERSION 0x1001 -+struct hci_rp_read_local_version { -+ __u8 status; -+ __u8 hci_ver; -+ __le16 hci_rev; -+ __u8 lmp_ver; -+ __le16 manufacturer; -+ __le16 lmp_subver; -+} __packed; -+ -+#define HCI_EV_CMD_COMPLETE 0x0e -+struct hci_ev_cmd_complete { -+ __u8 ncmd; -+ __le16 opcode; -+} __packed; -+ -+/* ---- HCI Packet structures ---- */ -+#define HCI_COMMAND_HDR_SIZE 3 -+#define HCI_EVENT_HDR_SIZE 2 -+#define HCI_ACL_HDR_SIZE 4 -+#define HCI_SCO_HDR_SIZE 3 -+ -+struct hci_command_hdr { -+ __le16 opcode; /* OCF & OGF */ -+ __u8 plen; -+} __packed; -+ -+struct hci_event_hdr { -+ __u8 evt; -+ __u8 plen; -+} __packed; -+ -+struct hci_acl_hdr { -+ __le16 handle; /* Handle & Flags(PB, BC) */ -+ __le16 dlen; -+} __packed; -+ -+struct hci_sco_hdr { -+ __le16 handle; -+ __u8 dlen; -+} __packed; -+ -+static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb) -+{ -+ return (struct hci_event_hdr *) skb->data; -+} -+ -+static inline struct hci_acl_hdr *hci_acl_hdr(const struct sk_buff *skb) -+{ -+ return (struct hci_acl_hdr *) skb->data; -+} -+ -+static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb) -+{ -+ return (struct hci_sco_hdr *) skb->data; -+} -+ -+/* ---- HCI Ioctl requests structures ---- */ -+struct hci_dev_stats { -+ __u32 err_rx; -+ __u32 err_tx; -+ __u32 cmd_tx; -+ __u32 evt_rx; -+ __u32 acl_tx; -+ __u32 acl_rx; -+ __u32 sco_tx; -+ __u32 sco_rx; -+ __u32 byte_rx; -+ __u32 byte_tx; -+}; -+/* AicSemi - Integrate from hci.h end */ -+ -+/***************************************** -+** AicSemi - Integrate from hci_core.h ** -+*****************************************/ -+struct hci_conn_hash { -+ struct list_head list; -+ unsigned int acl_num; -+ unsigned int sco_num; -+ unsigned int le_num; -+}; -+ -+#define HCI_MAX_SHORT_NAME_LENGTH 10 -+ -+#define NUM_REASSEMBLY 4 -+struct hci_dev { -+ struct mutex lock; -+ -+ char name[8]; -+ unsigned long flags; -+ __u16 id; -+ __u8 bus; -+ __u8 dev_type; -+ -+ struct sk_buff *reassembly[NUM_REASSEMBLY]; -+ -+ struct hci_conn_hash conn_hash; -+ -+ struct hci_dev_stats stat; -+ -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0) -+ atomic_t refcnt; -+ struct module *owner; -+ void *driver_data; -+#endif -+ -+ atomic_t promisc; -+ -+ struct device *parent; -+ struct device dev; -+ -+ unsigned long dev_flags; -+ -+ int (*open)(struct hci_dev *hdev); -+ int (*close)(struct hci_dev *hdev); -+ int (*flush)(struct hci_dev *hdev); -+ int (*send)(struct sk_buff *skb); -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0) -+ void (*destruct)(struct hci_dev *hdev); -+#endif -+#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 1) -+ __u16 voice_setting; -+#endif -+ void (*notify)(struct hci_dev *hdev, unsigned int evt); -+ int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); -+ u8 *align_data; -+}; -+ -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0) -+static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d) -+{ -+ atomic_inc(&d->refcnt); -+ return d; -+} -+ -+static inline void __hci_dev_put(struct hci_dev *d) -+{ -+ if (atomic_dec_and_test(&d->refcnt)) -+ d->destruct(d); -+} -+#endif -+ -+static inline void *hci_get_drvdata(struct hci_dev *hdev) -+{ -+ return dev_get_drvdata(&hdev->dev); -+} -+ -+static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) -+{ -+ dev_set_drvdata(&hdev->dev, data); -+} -+ -+#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev)) -+ -+ -+/* ---- HCI Packet structures ---- */ -+#define HCI_COMMAND_HDR_SIZE 3 -+#define HCI_EVENT_HDR_SIZE 2 -+#define HCI_ACL_HDR_SIZE 4 -+#define HCI_SCO_HDR_SIZE 3 -+ -+/* ----- HCI Commands ---- */ -+#define HCI_OP_INQUIRY 0x0401 -+#define HCI_OP_INQUIRY_CANCEL 0x0402 -+#define HCI_OP_EXIT_PERIODIC_INQ 0x0404 -+#define HCI_OP_CREATE_CONN 0x0405 -+#define HCI_OP_DISCONNECT 0x0406 -+#define HCI_OP_ADD_SCO 0x0407 -+#define HCI_OP_CREATE_CONN_CANCEL 0x0408 -+#define HCI_OP_ACCEPT_CONN_REQ 0x0409 -+#define HCI_OP_REJECT_CONN_REQ 0x040a -+#define HCI_OP_LINK_KEY_REPLY 0x040b -+#define HCI_OP_LINK_KEY_NEG_REPLY 0x040c -+#define HCI_OP_PIN_CODE_REPLY 0x040d -+#define HCI_OP_PIN_CODE_NEG_REPLY 0x040e -+#define HCI_OP_CHANGE_CONN_PTYPE 0x040f -+#define HCI_OP_AUTH_REQUESTED 0x0411 -+#define HCI_OP_SET_CONN_ENCRYPT 0x0413 -+#define HCI_OP_CHANGE_CONN_LINK_KEY 0x0415 -+#define HCI_OP_REMOTE_NAME_REQ 0x0419 -+#define HCI_OP_REMOTE_NAME_REQ_CANCEL 0x041a -+#define HCI_OP_READ_REMOTE_FEATURES 0x041b -+#define HCI_OP_READ_REMOTE_EXT_FEATURES 0x041c -+#define HCI_OP_READ_REMOTE_VERSION 0x041d -+#define HCI_OP_SETUP_SYNC_CONN 0x0428 -+#define HCI_OP_ACCEPT_SYNC_CONN_REQ 0x0429 -+#define HCI_OP_REJECT_SYNC_CONN_REQ 0x042a -+#define HCI_OP_SNIFF_MODE 0x0803 -+#define HCI_OP_EXIT_SNIFF_MODE 0x0804 -+#define HCI_OP_ROLE_DISCOVERY 0x0809 -+#define HCI_OP_SWITCH_ROLE 0x080b -+#define HCI_OP_READ_LINK_POLICY 0x080c -+#define HCI_OP_WRITE_LINK_POLICY 0x080d -+#define HCI_OP_READ_DEF_LINK_POLICY 0x080e -+#define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f -+#define HCI_OP_SNIFF_SUBRATE 0x0811 -+#define HCI_OP_Write_Link_Policy_Settings 0x080d -+#define HCI_OP_SET_EVENT_MASK 0x0c01 -+#define HCI_OP_RESET 0x0c03 -+#define HCI_OP_SET_EVENT_FLT 0x0c05 -+#define HCI_OP_Write_Extended_Inquiry_Response 0x0c52 -+#define HCI_OP_Write_Simple_Pairing_Mode 0x0c56 -+#define HCI_OP_Read_Buffer_Size 0x1005 -+#define HCI_OP_Host_Buffer_Size 0x0c33 -+#define HCI_OP_Read_Local_Version_Information 0x1001 -+#define HCI_OP_Read_BD_ADDR 0x1009 -+#define HCI_OP_Read_Local_Supported_Commands 0x1002 -+#define HCI_OP_Write_Scan_Enable 0x0c1a -+#define HCI_OP_Write_Current_IAC_LAP 0x0c3a -+#define HCI_OP_Write_Inquiry_Scan_Activity 0x0c1e -+#define HCI_OP_Write_Class_of_Device 0x0c24 -+#define HCI_OP_LE_Rand 0x2018 -+#define HCI_OP_LE_Set_Random_Address 0x2005 -+#define HCI_OP_LE_Set_Extended_Scan_Enable 0x2042 -+#define HCI_OP_LE_Set_Extended_Scan_Parameters 0x2041 -+#define HCI_OP_Set_Event_Filter 0x0c05 -+#define HCI_OP_Write_Voice_Setting 0x0c26 -+#define HCI_OP_Change_Local_Name 0x0c13 -+#define HCI_OP_Read_Local_Name 0x0c14 -+#define HCI_OP_Wirte_Page_Timeout 0x0c18 -+#define HCI_OP_LE_Clear_Resolving_List 0x0c29 -+#define HCI_OP_LE_Set_Addres_Resolution_Enable_Command 0x0c2e -+#define HCI_OP_Write_Inquiry_mode 0x0c45 -+#define HCI_OP_Write_Page_Scan_Type 0x0c47 -+#define HCI_OP_Write_Inquiry_Scan_Type 0x0c43 -+ -+#define HCI_OP_Delete_Stored_Link_Key 0x0c12 -+#define HCI_OP_LE_Read_Local_Resolvable_Address 0x202d -+#define HCI_OP_LE_Extended_Create_Connection 0x2043 -+#define HCI_OP_Read_Remote_Version_Information 0x041d -+#define HCI_OP_LE_Start_Encryption 0x2019 -+#define HCI_OP_LE_Add_Device_to_Resolving_List 0x2027 -+#define HCI_OP_LE_Set_Privacy_Mode 0x204e -+#define HCI_OP_LE_Connection_Update 0x2013 -+ -+/* ----- HCI events---- */ -+#define HCI_OP_DISCONNECT 0x0406 -+#define HCI_EV_INQUIRY_COMPLETE 0x01 -+#define HCI_EV_INQUIRY_RESULT 0x02 -+#define HCI_EV_CONN_COMPLETE 0x03 -+#define HCI_EV_CONN_REQUEST 0x04 -+#define HCI_EV_DISCONN_COMPLETE 0x05 -+#define HCI_EV_AUTH_COMPLETE 0x06 -+#define HCI_EV_REMOTE_NAME 0x07 -+#define HCI_EV_ENCRYPT_CHANGE 0x08 -+#define HCI_EV_CHANGE_LINK_KEY_COMPLETE 0x09 -+ -+#define HCI_EV_REMOTE_FEATURES 0x0b -+#define HCI_EV_REMOTE_VERSION 0x0c -+#define HCI_EV_QOS_SETUP_COMPLETE 0x0d -+#define HCI_EV_CMD_COMPLETE 0x0e -+#define HCI_EV_CMD_STATUS 0x0f -+ -+#define HCI_EV_ROLE_CHANGE 0x12 -+#define HCI_EV_NUM_COMP_PKTS 0x13 -+#define HCI_EV_MODE_CHANGE 0x14 -+#define HCI_EV_PIN_CODE_REQ 0x16 -+#define HCI_EV_LINK_KEY_REQ 0x17 -+#define HCI_EV_LINK_KEY_NOTIFY 0x18 -+#define HCI_EV_CLOCK_OFFSET 0x1c -+#define HCI_EV_PKT_TYPE_CHANGE 0x1d -+#define HCI_EV_PSCAN_REP_MODE 0x20 -+ -+#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22 -+#define HCI_EV_REMOTE_EXT_FEATURES 0x23 -+#define HCI_EV_SYNC_CONN_COMPLETE 0x2c -+#define HCI_EV_SYNC_CONN_CHANGED 0x2d -+#define HCI_EV_SNIFF_SUBRATE 0x2e -+#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2f -+#define HCI_EV_IO_CAPA_REQUEST 0x31 -+#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 -+#define HCI_EV_REMOTE_HOST_FEATURES 0x3d -+#define HCI_EV_LE_Meta 0x3e -+ -+/* ULP Event sub code */ -+#define HCI_BLE_CONN_COMPLETE_EVT 0x01 -+#define HCI_BLE_ADV_PKT_RPT_EVT 0x02 -+#define HCI_BLE_LL_CONN_PARAM_UPD_EVT 0x03 -+#define HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT 0x04 -+#define HCI_BLE_LTK_REQ_EVT 0x05 -+#define HCI_BLE_RC_PARAM_REQ_EVT 0x06 -+#define HCI_BLE_DATA_LENGTH_CHANGE_EVT 0x07 -+#define HCI_BLE_ENHANCED_CONN_COMPLETE_EVT 0x0a -+#define HCI_BLE_DIRECT_ADV_EVT 0x0b -+#define HCI_BLE_PHY_UPDATE_COMPLETE_EVT 0x0c -+#define HCI_LE_EXTENDED_ADVERTISING_REPORT_EVT 0x0D -+#define HCI_BLE_PERIODIC_ADV_SYNC_EST_EVT 0x0E -+#define HCI_BLE_PERIODIC_ADV_REPORT_EVT 0x0F -+#define HCI_BLE_PERIODIC_ADV_SYNC_LOST_EVT 0x10 -+#define HCI_BLE_SCAN_TIMEOUT_EVT 0x11 -+#define HCI_LE_ADVERTISING_SET_TERMINATED_EVT 0x12 -+#define HCI_BLE_SCAN_REQ_RX_EVT 0x13 -+#define HCI_BLE_CIS_EST_EVT 0x19 -+#define HCI_BLE_CIS_REQ_EVT 0x1a -+#define HCI_BLE_CREATE_BIG_CPL_EVT 0x1b -+#define HCI_BLE_TERM_BIG_CPL_EVT 0x1c -+#define HCI_BLE_BIG_SYNC_EST_EVT 0x1d -+#define HCI_BLE_BIG_SYNC_LOST_EVT 0x1e -+#define HCI_BLE_REQ_PEER_SCA_CPL_EVT 0x1f -+ -+#define HCI_VENDOR_SPECIFIC_EVT 0xFF /* Vendor specific events */ -+ -+#define CONFIG_MAC_OFFSET_GEN_1_2 (0x3C) //MAC's OFFSET in config/efuse for aic generation 1~2 bluetooth chip -+#define CONFIG_MAC_OFFSET_GEN_3PLUS (0x44) //MAC's OFFSET in config/efuse for aic generation 3+ bluetooth chip -+ -+//Define ioctl cmd the same as HCIDEVUP in the kernel -+#define DOWN_FW_CFG _IOW('E', 176, int) -+//#ifdef CONFIG_SCO_OVER_HCI -+//#define SET_ISO_CFG _IOW('H', 202, int) -+//#else -+#define SET_ISO_CFG _IOW('E', 177, int) -+//#endif -+#define RESET_CONTROLLER _IOW('E', 178, int) -+#define DWFW_CMPLT _IOW('E', 179, int) -+ -+#define GET_USB_INFO _IOR('E', 180, int) -+ -+void bt_data_dump(char* tag, void* data, unsigned long len); -+int aic_enqueue(struct sk_buff *skb); -+int aic_queue_cnt(void); -+int bt_sdio_recv(u8 *data,u32 data_len); -+ -+ -+int btchr_init(void); -+void btchr_exit(void); -+int hdev_init(void); -+void hdev_exit(void); -+ -+ -+struct hci_dev *hci_dev_get(int index); -+int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); -+ -+#endif//_AICWF_SDIO_BT_H_ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_vendor.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_vendor.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_vendor.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_vendor.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,909 @@ -+#include "aic_vendor.h" -+#include "rwnx_defs.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "rwnx_version_gen.h" -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ -+static struct wifi_ring_buffer_status ring_buffer[] = { -+ { -+ .name = "aicwf_ring_buffer0", -+ .flags = 0, -+ .ring_id = 0, -+ .verbose_level = 0, -+ .written_bytes = 0, -+ .read_bytes = 0, -+ .written_records = 0, -+ }, -+}; -+ -+static struct wlan_driver_wake_reason_cnt_t wake_reason_cnt = { -+ .total_cmd_event_wake = 10, -+}; -+#endif -+ -+int aic_dev_start_mkeep_alive(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ u8 mkeep_alive_id, u8 *ip_pkt, u16 ip_pkt_len, u8 *src_mac, u8 *dst_mac, u32 period_msec) -+{ -+ u8 *data, *pos; -+ -+ data = kzalloc(ip_pkt_len + 14, GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ pos = data; -+ memcpy(pos, dst_mac, 6); -+ pos += 6; -+ memcpy(pos, src_mac, 6); -+ pos += 6; -+ /* Mapping Ethernet type (ETHERTYPE_IP: 0x0800) */ -+ *(pos++) = 0x08; -+ *(pos++) = 0x00; -+ -+ /* Mapping IP pkt */ -+ memcpy(pos, ip_pkt, ip_pkt_len); -+ pos += ip_pkt_len; -+ -+ //add send 802.3 pkt(raw data) -+ kfree(data); -+ -+ return 0; -+} -+ -+int aic_dev_stop_mkeep_alive(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, u8 mkeep_alive_id) -+{ -+ int res = -1; -+ -+ /* -+ * The mkeep_alive packet is for STA interface only; if the bss is configured as AP, -+ * dongle shall reject a mkeep_alive request. -+ */ -+ if (rwnx_vif->wdev.iftype != NL80211_IFTYPE_STATION) -+ return res; -+ -+ printk("%s execution\n", __func__); -+ -+ //add send stop keep alive -+ res = 0; -+ return res; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+static int aicwf_vendor_start_mkeep_alive(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ /* max size of IP packet for keep alive */ -+ const int MKEEP_ALIVE_IP_PKT_MAX = 256; -+ -+ int ret = 0, rem, type; -+ u8 mkeep_alive_id = 0; -+ u8 *ip_pkt = NULL; -+ u16 ip_pkt_len = 0; -+ u8 src_mac[6]; -+ u8 dst_mac[6]; -+ u32 period_msec = 0; -+ const struct nlattr *iter; -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = container_of(wdev, struct rwnx_vif, wdev); -+ gfp_t kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; -+ printk("%s\n", __func__); -+ -+ nla_for_each_attr(iter, data, len, rem) { -+ type = nla_type(iter); -+ switch (type) { -+ case MKEEP_ALIVE_ATTRIBUTE_ID: -+ mkeep_alive_id = nla_get_u8(iter); -+ break; -+ case MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN: -+ ip_pkt_len = nla_get_u16(iter); -+ if (ip_pkt_len > MKEEP_ALIVE_IP_PKT_MAX) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ break; -+ case MKEEP_ALIVE_ATTRIBUTE_IP_PKT: -+ if (!ip_pkt_len) { -+ ret = -EINVAL; -+ printk("ip packet length is 0\n"); -+ goto exit; -+ } -+ ip_pkt = (u8 *)kzalloc(ip_pkt_len, kflags); -+ if (ip_pkt == NULL) { -+ ret = -ENOMEM; -+ printk("Failed to allocate mem for ip packet\n"); -+ goto exit; -+ } -+ memcpy(ip_pkt, (u8 *)nla_data(iter), ip_pkt_len); -+ break; -+ case MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR: -+ memcpy(src_mac, nla_data(iter), 6); -+ break; -+ case MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR: -+ memcpy(dst_mac, nla_data(iter), 6); -+ break; -+ case MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC: -+ period_msec = nla_get_u32(iter); -+ break; -+ default: -+ pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type); -+ ret = -EINVAL; -+ goto exit; -+ } -+ } -+ -+ if (ip_pkt == NULL) { -+ ret = -EINVAL; -+ printk("ip packet is NULL\n"); -+ goto exit; -+ } -+ -+ ret = aic_dev_start_mkeep_alive(rwnx_hw, rwnx_vif, mkeep_alive_id, ip_pkt, ip_pkt_len, src_mac, -+ dst_mac, period_msec); -+ if (ret < 0) { -+ printk("start_mkeep_alive is failed ret: %d\n", ret); -+ } -+ -+exit: -+ if (ip_pkt) { -+ kfree(ip_pkt); -+ } -+ -+ return ret; -+} -+ -+static int aicwf_vendor_stop_mkeep_alive(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ int ret = 0, rem, type; -+ u8 mkeep_alive_id = 0; -+ const struct nlattr *iter; -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = container_of(wdev, struct rwnx_vif, wdev); -+ -+ printk("%s\n", __func__); -+ nla_for_each_attr(iter, data, len, rem) { -+ type = nla_type(iter); -+ switch (type) { -+ case MKEEP_ALIVE_ATTRIBUTE_ID: -+ mkeep_alive_id = nla_get_u8(iter); -+ break; -+ default: -+ pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ -+ ret = aic_dev_stop_mkeep_alive(rwnx_hw, rwnx_vif, mkeep_alive_id); -+ if (ret < 0) { -+ printk("stop_mkeep_alive is failed ret: %d\n", ret); -+ } -+ -+ return ret; -+} -+ -+static int aicwf_vendor_get_ver(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ int ret = 0, rem, type; -+ const struct nlattr *iter; -+ int payload = 0; -+ char version[128]; -+ int attr = -1; -+ struct sk_buff *reply; -+ -+ nla_for_each_attr(iter, data, len, rem) { -+ type = nla_type(iter); -+ switch (type) { -+ case LOGGER_ATTRIBUTE_DRIVER_VER: -+ memcpy(version, RWNX_VERS_BANNER, sizeof(RWNX_VERS_BANNER)); -+ payload = strlen(version); -+ attr = LOGGER_ATTRIBUTE_DRIVER_VER; -+ break; -+ case LOGGER_ATTRIBUTE_FW_VER: -+ memcpy(version, wiphy->fw_version, sizeof(wiphy->fw_version)); -+ payload = strlen(version); -+ attr = LOGGER_ATTRIBUTE_FW_VER; -+ break; -+ default: -+ AICWFDBG(LOGERROR, "%s(%d), Unknown type: %d\n", __func__, __LINE__, type); -+ return -EINVAL; -+ } -+ } -+ -+ if (attr < 0) -+ return -EINVAL; -+ -+ reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload); -+ -+ if (!reply) -+ return -ENOMEM; -+ -+ if (nla_put(reply, attr, -+ payload, version)) { -+ wiphy_err(wiphy, "%s put version error\n", __func__); -+ goto out_put_fail; -+ } -+ -+ ret = cfg80211_vendor_cmd_reply(reply); -+ if (ret) -+ wiphy_err(wiphy, "%s reply cmd error\n", __func__); -+ return ret; -+ -+out_put_fail: -+ kfree_skb(reply); -+ return -EMSGSIZE; -+} -+ -+static int aicwf_vendor_subcmd_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ int ret = 0, rem, type; -+ const struct nlattr *iter; -+ struct sk_buff *reply; -+ int num_channels = 0; -+ int *channel_list = NULL; -+ int payload; -+ int i = 0; -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct ieee80211_supported_band *rwnx_band_2GHz = rwnx_hw->wiphy->bands[NL80211_BAND_2GHZ]; -+ struct ieee80211_supported_band *rwnx_band_5GHz = rwnx_hw->wiphy->bands[NL80211_BAND_5GHZ]; -+ -+ num_channels += rwnx_band_2GHz->n_channels; -+ num_channels += (rwnx_hw->band_5g_support) ? rwnx_band_5GHz->n_channels : 0; -+ -+ channel_list = (int *)kzalloc(sizeof(int) * num_channels, GFP_KERNEL); -+ if (!channel_list) -+ return -ENOMEM; -+ -+ for (i = 0; i < rwnx_band_2GHz->n_channels; i++) -+ channel_list[i] = rwnx_band_2GHz->channels[i].center_freq; -+ -+ for (; rwnx_hw->band_5g_support && i < num_channels; i++) -+ channel_list[i] = rwnx_band_5GHz->channels[i].center_freq; -+ -+ payload = sizeof(num_channels) + sizeof(int) * num_channels + 4; -+ -+ nla_for_each_attr(iter, data, len, rem) { -+ type = nla_type(iter); -+ switch (type) { -+ case GSCAN_ATTRIBUTE_BAND: -+ reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload); -+ -+ if (!reply) -+ return -ENOMEM; -+ -+ if (nla_put_u32(reply, GSCAN_ATTRIBUTE_NUM_CHANNELS, num_channels)) -+ goto out_put_fail; -+ -+ if (nla_put(reply, GSCAN_ATTRIBUTE_CHANNEL_LIST, sizeof(int) * num_channels, channel_list)) -+ goto out_put_fail; -+ -+ ret = cfg80211_vendor_cmd_reply(reply); -+ if (ret) -+ wiphy_err(wiphy, "%s reply cmd error\n", __func__); -+ break; -+ default: -+ pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type); -+ return -EINVAL; -+ } -+ } -+ -+ kfree(channel_list); -+ return ret; -+ -+out_put_fail: -+ kfree(channel_list); -+ kfree_skb(reply); -+ return -EMSGSIZE; -+} -+ -+static int aicwf_vendor_subcmd_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ int ret = 0, rem, type; -+ const struct nlattr *iter; -+ -+ nla_for_each_attr(iter, data, len, rem) { -+ type = nla_type(iter); -+ switch (type) { -+ case ANDR_WIFI_ATTRIBUTE_COUNTRY: -+ printk("%s(%d), ANDR_WIFI_ATTRIBUTE_COUNTRY: %s\n", __func__, __LINE__, (char *)nla_data(iter)); -+ break; -+ default: -+ pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type); -+ return -EINVAL; -+ } -+ } -+ -+ /* TODO -+ * Add handle in the future! -+ */ -+ -+ return ret; -+} -+ -+static int aicwf_vendor_logger_trigger_memory_dump(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ /* TODO -+ * Add handle in the future! -+ */ -+ return 0; -+} -+ -+static int aicwf_vendor_subcmd_get_feature_set(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ int ret; -+ struct sk_buff *reply; -+ uint32_t feature = 0, payload; -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ -+ payload = sizeof(feature); -+ reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload); -+ -+ if (!reply) -+ return -ENOMEM; -+ -+ /* TODO -+ * Add handle in the future! -+ */ -+ /*bit 1:Basic infrastructure mode*/ -+ if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) -+ feature |= WIFI_FEATURE_INFRA; -+ -+ /*bit 2:Support for 5 GHz Band*/ -+ if (rwnx_hw->band_5g_support) -+ feature |= WIFI_FEATURE_INFRA_5G; -+ -+ /*bit3:HOTSPOT is a supplicant feature, enable it by default*/ -+ feature |= WIFI_FEATURE_HOTSPOT; -+ -+ /*bit 4:P2P*/ -+ if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) && -+ (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) -+ feature |= WIFI_FEATURE_P2P; -+ -+ /*bit 5:soft AP feature supported*/ -+ if (wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) -+ feature |= WIFI_FEATURE_SOFT_AP; -+ -+ /*bit 18:WiFi Logger*/ -+ feature |= WIFI_FEATURE_LOGGER; -+ -+ /*bit 21:WiFi mkeep_alive*/ -+ feature |= WIFI_FEATURE_MKEEP_ALIVE; -+ -+ if (nla_put_u32(reply, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, feature)) { -+ wiphy_err(wiphy, "%s put u32 error\n", __func__); -+ goto out_put_fail; -+ } -+ -+ ret = cfg80211_vendor_cmd_reply(reply); -+ if (ret) -+ wiphy_err(wiphy, "%s reply cmd error\n", __func__); -+ -+ return ret; -+ -+out_put_fail: -+ kfree_skb(reply); -+ return -EMSGSIZE; -+} -+ -+static int aicwf_vendor_logger_get_feature(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ int ret; -+ struct sk_buff *reply; -+ uint32_t feature = 0, payload; -+ -+ payload = sizeof(feature); -+ reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload); -+ -+ if (!reply) -+ return -ENOMEM; -+ -+ feature |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED; -+ feature |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED; -+ -+ /*vts will test wake reason state function*/ -+ feature |= WIFI_LOGGER_WAKE_LOCK_SUPPORTED; -+ -+ if (nla_put_u32(reply, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, feature)) { -+ wiphy_err(wiphy, "put skb u32 failed\n"); -+ goto out_put_fail; -+ } -+ -+ ret = cfg80211_vendor_cmd_reply(reply); -+ if (ret) -+ wiphy_err(wiphy, "reply cmd error\n"); -+ -+ return ret; -+ -+out_put_fail: -+ kfree_skb(reply); -+ return -EMSGSIZE; -+} -+ -+static int aicwf_vendor_logger_get_ring_status(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ int ret; -+ struct sk_buff *reply; -+ uint32_t payload; -+ uint32_t ring_buffer_nums = sizeof(ring_buffer) / sizeof(ring_buffer[0]); -+ -+ payload = sizeof(ring_buffer_nums) + sizeof(ring_buffer); -+ reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload); -+ -+ if (!reply) -+ return -ENOMEM; -+ -+ if (nla_put_u32(reply, LOGGER_ATTRIBUTE_RING_NUM, ring_buffer_nums)) { -+ wiphy_err(wiphy, "put skb u32 failed\n"); -+ goto out_put_fail; -+ } -+ -+ if (nla_put(reply, LOGGER_ATTRIBUTE_RING_STATUS, sizeof(ring_buffer), ring_buffer)) { -+ wiphy_err(wiphy, "put skb failed\n"); -+ goto out_put_fail; -+ } -+ -+ ret = cfg80211_vendor_cmd_reply(reply); -+ if (ret) -+ wiphy_err(wiphy, "reply cmd error\n"); -+ -+ return ret; -+ -+out_put_fail: -+ kfree_skb(reply); -+ return -EMSGSIZE; -+} -+ -+static int aicwf_vendor_logger_start_logging(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ int ret = 0, rem, type, intval, size, i; -+ const struct nlattr *iter; -+ struct wifi_ring_buffer_status rb; -+ -+ nla_for_each_attr(iter, data, len, rem) { -+ type = nla_type(iter); -+ switch (type) { -+ case LOGGER_ATTRIBUTE_LOG_LEVEL: -+ rb.verbose_level = nla_get_u32(iter); -+ break; -+ case LOGGER_ATTRIBUTE_RING_FLAGS: -+ rb.flags = nla_get_u32(iter); -+ break; -+ case LOGGER_ATTRIBUTE_LOG_TIME_INTVAL: -+ intval = nla_get_u32(iter); -+ break; -+ case LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE: -+ size = nla_get_u32(iter); -+ break; -+ case LOGGER_ATTRIBUTE_RING_NAME: -+ strcpy(rb.name, nla_data(iter)); -+ break; -+ default: -+ AICWFDBG(LOGERROR, "%s(%d), Unknown type: %d\n", __func__, __LINE__, type); -+ return -EINVAL; -+ } -+ } -+ -+ ret = -EINVAL; -+ for (i = 0; i < sizeof(ring_buffer) / sizeof(ring_buffer[0]); i++) { -+ if (strcmp(rb.name, ring_buffer[i].name) == 0) { -+ ret = 0; -+ break; -+ } -+ } -+ -+ /* TODO -+ * Add handle in the future -+ */ -+ -+ return ret; -+} -+ -+static int aicwf_vendor_logger_get_ring_data(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ int ret = 0, rem, type, i; -+ const struct nlattr *iter; -+ struct wifi_ring_buffer_status rb; -+ -+ nla_for_each_attr(iter, data, len, rem) { -+ type = nla_type(iter); -+ switch (type) { -+ case LOGGER_ATTRIBUTE_RING_NAME: -+ strcpy(rb.name, nla_data(iter)); -+ break; -+ default: -+ pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type); -+ return -EINVAL; -+ } -+ } -+ -+ ret = -EINVAL; -+ for (i = 0; i < sizeof(ring_buffer) / sizeof(ring_buffer[0]); i++) { -+ if (strcmp(rb.name, ring_buffer[i].name) == 0) { -+ ret = 0; -+ break; -+ } -+ } -+ -+ /* TODO -+ * Add handle in the future -+ */ -+ -+ return ret; -+} -+ -+static int aicwf_vendor_logger_get_wake_reason_stats(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ int ret; -+ struct sk_buff *reply; -+ uint32_t payload; -+ -+ payload = sizeof(wake_reason_cnt.total_cmd_event_wake); -+ reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload); -+ -+ if (!reply) -+ return -ENOMEM; -+ -+ /* TODO -+ * Add handle in the future -+ */ -+ if (nla_put_u32(reply, WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT, wake_reason_cnt.total_cmd_event_wake)) -+ goto out_put_fail; -+ -+ ret = cfg80211_vendor_cmd_reply(reply); -+ if (ret) -+ wiphy_err(wiphy, "reply cmd error\n"); -+ -+ return ret; -+ -+out_put_fail: -+ kfree_skb(reply); -+ return -EMSGSIZE; -+} -+ -+static int aicwf_vendor_apf_subcmd_get_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ /* TODO -+ * Add handle in the future -+ */ -+ return 0; -+} -+ -+static int aicwf_vendor_sub_cmd_set_mac(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int len) -+{ -+ int ret = 0, rem, type; -+ const struct nlattr *iter; -+ u8 mac[ETH_ALEN]; -+ -+ nla_for_each_attr(iter, data, len, rem) { -+ type = nla_type(iter); -+ switch (type) { -+ case WIFI_VENDOR_ATTR_DRIVER_MAC_ADDR: -+ memcpy(mac, nla_data(iter), ETH_ALEN); -+ printk("%s, %02X:%02X:%02X:%02X:%02X:%02X\n", __func__, -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -+ break; -+ default: -+ pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type); -+ return -EINVAL; -+ } -+ } -+ -+ /* TODO -+ * Add handle in the future -+ */ -+ -+ return ret; -+} -+#endif -+ -+static const struct nla_policy -+aicwf_cfg80211_mkeep_alive_policy[MKEEP_ALIVE_ATTRIBUTE_MAX+1] = { -+ [0] = {.type = NLA_UNSPEC }, -+ [MKEEP_ALIVE_ATTRIBUTE_ID] = { .type = NLA_U8 }, -+ [MKEEP_ALIVE_ATTRIBUTE_IP_PKT] = { .type = NLA_MSECS }, -+ [MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN] = { .type = NLA_U16 }, -+ [MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR] = { .type = NLA_MSECS, -+ .len = ETH_ALEN }, -+ [MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR] = { .type = NLA_MSECS, -+ .len = ETH_ALEN }, -+ [MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC] = { .type = NLA_U32 }, -+}; -+ -+static const struct nla_policy -+aicwf_cfg80211_logger_policy[LOGGER_ATTRIBUTE_MAX + 1] = { -+ [0] = {.type = NLA_UNSPEC }, -+ [LOGGER_ATTRIBUTE_DRIVER_VER] = { .type = NLA_BINARY }, -+ [LOGGER_ATTRIBUTE_FW_VER] = { .type = NLA_BINARY }, -+ [LOGGER_ATTRIBUTE_LOG_LEVEL] = { .type = NLA_U32 }, -+ [LOGGER_ATTRIBUTE_RING_FLAGS] = { .type = NLA_U32 }, -+ [LOGGER_ATTRIBUTE_LOG_TIME_INTVAL] = { .type = NLA_U32 }, -+ [LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE] = { .type = NLA_U32 }, -+ [LOGGER_ATTRIBUTE_RING_NAME] = { .type = NLA_STRING }, -+}; -+ -+static const struct nla_policy -+aicwf_cfg80211_subcmd_policy[GSCAN_ATTRIBUTE_MAX + 1] = { -+ [0] = {.type = NLA_UNSPEC }, -+ [GSCAN_ATTRIBUTE_BAND] = { .type = NLA_U32 }, -+}; -+ -+static const struct nla_policy -+aicwf_cfg80211_andr_wifi_policy[ANDR_WIFI_ATTRIBUTE_MAX + 1] = { -+ [0] = {.type = NLA_UNSPEC }, -+ [ANDR_WIFI_ATTRIBUTE_COUNTRY] = { .type = NLA_STRING }, -+}; -+ -+static const struct nla_policy -+aicwf_cfg80211_subcmd_set_mac_policy[WIFI_VENDOR_ATTR_DRIVER_MAX + 1] = { -+ [0] = {.type = NLA_UNSPEC }, -+ [WIFI_VENDOR_ATTR_DRIVER_MAC_ADDR] = { .type = NLA_MSECS, .len = ETH_ALEN }, -+}; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+static int aicwf_dump_interface(struct wiphy *wiphy, -+ struct wireless_dev *wdev, struct sk_buff *skb, -+ const void *data, int data_len, -+ unsigned long *storage) -+{ -+ return 0; -+} -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+const struct wiphy_vendor_command aicwf_vendor_cmd[] = { -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_start_mkeep_alive, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = aicwf_cfg80211_mkeep_alive_policy, -+ .maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_stop_mkeep_alive, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = aicwf_cfg80211_mkeep_alive_policy, -+ .maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = LOGGER_GET_VER -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_get_ver, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = aicwf_cfg80211_logger_policy, -+ .maxattr = LOGGER_ATTRIBUTE_MAX -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_GET_CHANNEL_LIST -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_subcmd_get_channel_list, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = aicwf_cfg80211_subcmd_policy, -+ .maxattr = GSCAN_ATTRIBUTE_MAX -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_subcmd_set_country_code, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = aicwf_cfg80211_andr_wifi_policy, -+ .maxattr = ANDR_WIFI_ATTRIBUTE_MAX -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = LOGGER_TRIGGER_MEM_DUMP -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_logger_trigger_memory_dump, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = VENDOR_CMD_RAW_DATA, -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_GET_FEATURE_SET -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_subcmd_get_feature_set, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = VENDOR_CMD_RAW_DATA, -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = LOGGER_GET_FEATURE -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_logger_get_feature, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = VENDOR_CMD_RAW_DATA, -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = LOGGER_GET_RING_STATUS -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_logger_get_ring_status, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = VENDOR_CMD_RAW_DATA, -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = LOGGER_START_LOGGING -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_logger_start_logging, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = aicwf_cfg80211_logger_policy, -+ .maxattr = LOGGER_ATTRIBUTE_MAX -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = LOGGER_GET_RING_DATA -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_logger_get_ring_data, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = aicwf_cfg80211_logger_policy, -+ .maxattr = LOGGER_ATTRIBUTE_MAX -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = LOGGER_GET_WAKE_REASON_STATS -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_logger_get_wake_reason_stats, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = VENDOR_CMD_RAW_DATA, -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = APF_SUBCMD_GET_CAPABILITIES -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = aicwf_vendor_apf_subcmd_get_capabilities, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = VENDOR_CMD_RAW_DATA, -+#endif -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = VENDOR_NL80211_SUBCMD_SET_MAC -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_RUNNING, -+ .doit = aicwf_vendor_sub_cmd_set_mac, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = aicwf_cfg80211_subcmd_set_mac_policy, -+ .maxattr = WIFI_VENDOR_ATTR_DRIVER_MAX, -+#endif -+ }, -+ { -+ { -+ .vendor_id = BRCM_OUI, -+ .subcmd = VENDOR_NL80211_SUBCMD_SET_MAC -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_RUNNING, -+ .doit = aicwf_vendor_sub_cmd_set_mac, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -+ .dumpit = aicwf_dump_interface, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) -+ .policy = aicwf_cfg80211_subcmd_set_mac_policy, -+ .maxattr = WIFI_VENDOR_ATTR_DRIVER_MAX, -+#endif -+ }, -+}; -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+static const struct nl80211_vendor_cmd_info aicwf_vendor_events[] = { -+}; -+#endif -+ -+int aicwf_vendor_init(struct wiphy *wiphy) -+{ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ wiphy->vendor_commands = aicwf_vendor_cmd; -+ wiphy->n_vendor_commands = ARRAY_SIZE(aicwf_vendor_cmd); -+ wiphy->vendor_events = aicwf_vendor_events; -+ wiphy->n_vendor_events = ARRAY_SIZE(aicwf_vendor_events); -+#endif -+ return 0; -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_vendor.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_vendor.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_vendor.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aic_vendor.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,346 @@ -+#ifndef _AIC_VENDOR_H -+#define _AIC_VENDOR_H -+ -+#include -+ -+#define GOOGLE_OUI 0x001A11 -+#define BRCM_OUI 0x001018 -+ -+typedef enum { -+ START_MKEEP_ALIVE, -+ STOP_MKEEP_ALIVE, -+} GetCmdType; -+ -+typedef enum { -+ /* don't use 0 as a valid subcommand */ -+ VENDOR_NL80211_SUBCMD_UNSPECIFIED, -+ -+ /* define all vendor startup commands between 0x0 and 0x0FFF */ -+ VENDOR_NL80211_SUBCMD_RANGE_START = 0x0001, -+ VENDOR_NL80211_SUBCMD_RANGE_END = 0x0FFF, -+ -+ /* define all GScan related commands between 0x1000 and 0x10FF */ -+ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000, -+ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF, -+ -+ /* define all NearbyDiscovery related commands between 0x1100 and 0x11FF */ -+ ANDROID_NL80211_SUBCMD_NBD_RANGE_START = 0x1100, -+ ANDROID_NL80211_SUBCMD_NBD_RANGE_END = 0x11FF, -+ -+ /* define all RTT related commands between 0x1100 and 0x11FF */ -+ ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100, -+ ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF, -+ -+ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200, -+ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF, -+ -+ /* define all Logger related commands between 0x1400 and 0x14FF */ -+ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400, -+ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF, -+ -+ /* define all wifi offload related commands between 0x1600 and 0x16FF */ -+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600, -+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF, -+ -+ /* define all NAN related commands between 0x1700 and 0x17FF */ -+ ANDROID_NL80211_SUBCMD_NAN_RANGE_START = 0x1700, -+ ANDROID_NL80211_SUBCMD_NAN_RANGE_END = 0x17FF, -+ -+ /* define all Android Packet Filter related commands between 0x1800 and 0x18FF */ -+ ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START = 0x1800, -+ ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_END = 0x18FF, -+ -+ /* This is reserved for future usage */ -+ -+} ANDROID_VENDOR_SUB_COMMAND; -+ -+typedef enum { -+ WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START, -+ WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE, -+} WIFI_OFFLOAD_SUB_COMMAND; -+ -+ -+enum mkeep_alive_attributes { -+ MKEEP_ALIVE_ATTRIBUTE_ID = 0x1, -+ MKEEP_ALIVE_ATTRIBUTE_IP_PKT, -+ MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, -+ MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, -+ MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, -+ MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC, -+ MKEEP_ALIVE_ATTRIBUTE_AFTER_LAST, -+ MKEEP_ALIVE_ATTRIBUTE_MAX = MKEEP_ALIVE_ATTRIBUTE_AFTER_LAST - 1 -+}; -+ -+enum debug_sub_command { -+ LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START, -+ LOGGER_TRIGGER_MEM_DUMP, -+ LOGGER_GET_MEM_DUMP, -+ LOGGER_GET_VER, -+ LOGGER_GET_RING_STATUS, -+ LOGGER_GET_RING_DATA, -+ LOGGER_GET_FEATURE, -+ LOGGER_RESET_LOGGING, -+ LOGGER_TRIGGER_DRIVER_MEM_DUMP, -+ LOGGER_GET_DRIVER_MEM_DUMP, -+ LOGGER_START_PKT_FATE_MONITORING, -+ LOGGER_GET_TX_PKT_FATES, -+ LOGGER_GET_RX_PKT_FATES, -+ LOGGER_GET_WAKE_REASON_STATS, -+ LOGGER_DEBUG_GET_DUMP, -+ LOGGER_FILE_DUMP_DONE_IND, -+ LOGGER_SET_HAL_START, -+ LOGGER_HAL_STOP, -+ LOGGER_SET_HAL_PID, -+}; -+ -+enum logger_attributes { -+ LOGGER_ATTRIBUTE_INVALID = 0, -+ LOGGER_ATTRIBUTE_DRIVER_VER, -+ LOGGER_ATTRIBUTE_FW_VER, -+ LOGGER_ATTRIBUTE_RING_ID, -+ LOGGER_ATTRIBUTE_RING_NAME, -+ LOGGER_ATTRIBUTE_RING_FLAGS, -+ LOGGER_ATTRIBUTE_LOG_LEVEL, -+ LOGGER_ATTRIBUTE_LOG_TIME_INTVAL, -+ LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE, -+ LOGGER_ATTRIBUTE_FW_DUMP_LEN, -+ LOGGER_ATTRIBUTE_FW_DUMP_DATA, -+ // LOGGER_ATTRIBUTE_FW_ERR_CODE, -+ LOGGER_ATTRIBUTE_RING_DATA, -+ LOGGER_ATTRIBUTE_RING_STATUS, -+ LOGGER_ATTRIBUTE_RING_NUM, -+ LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN, -+ LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA, -+ LOGGER_ATTRIBUTE_PKT_FATE_NUM, -+ LOGGER_ATTRIBUTE_PKT_FATE_DATA, -+ LOGGER_ATTRIBUTE_AFTER_LAST, -+ LOGGER_ATTRIBUTE_MAX = LOGGER_ATTRIBUTE_AFTER_LAST - 1, -+}; -+ -+enum wifi_sub_command { -+ GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START, -+ GSCAN_SUBCMD_SET_CONFIG, /* 0x1001 */ -+ GSCAN_SUBCMD_SET_SCAN_CONFIG, /* 0x1002 */ -+ GSCAN_SUBCMD_ENABLE_GSCAN, /* 0x1003 */ -+ GSCAN_SUBCMD_GET_SCAN_RESULTS, /* 0x1004 */ -+ GSCAN_SUBCMD_SCAN_RESULTS, /* 0x1005 */ -+ GSCAN_SUBCMD_SET_HOTLIST, /* 0x1006 */ -+ GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, /* 0x1007 */ -+ GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, /* 0x1008 */ -+ GSCAN_SUBCMD_GET_CHANNEL_LIST, /* 0x1009 */ -+ WIFI_SUBCMD_GET_FEATURE_SET, /* 0x100A */ -+ WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, /* 0x100B */ -+ WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, /* 0x100C */ -+ WIFI_SUBCMD_NODFS_SET, /* 0x100D */ -+ WIFI_SUBCMD_SET_COUNTRY_CODE, /* 0x100E */ -+ /* Add more sub commands here */ -+ GSCAN_SUBCMD_SET_EPNO_SSID, /* 0x100F */ -+ WIFI_SUBCMD_SET_SSID_WHITE_LIST, /* 0x1010 */ -+ WIFI_SUBCMD_SET_ROAM_PARAMS, /* 0x1011 */ -+ WIFI_SUBCMD_ENABLE_LAZY_ROAM, /* 0x1012 */ -+ WIFI_SUBCMD_SET_BSSID_PREF, /* 0x1013 */ -+ WIFI_SUBCMD_SET_BSSID_BLACKLIST, /* 0x1014 */ -+ GSCAN_SUBCMD_ANQPO_CONFIG, /* 0x1015 */ -+ WIFI_SUBCMD_SET_RSSI_MONITOR, /* 0x1016 */ -+ WIFI_SUBCMD_CONFIG_ND_OFFLOAD, /* 0x1017 */ -+ /* Add more sub commands here */ -+ GSCAN_SUBCMD_MAX, -+ APF_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START, -+ APF_SUBCMD_SET_FILTER, -+}; -+ -+enum gscan_attributes { -+ GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, -+ GSCAN_ATTRIBUTE_BASE_PERIOD, -+ GSCAN_ATTRIBUTE_BUCKETS_BAND, -+ GSCAN_ATTRIBUTE_BUCKET_ID, -+ GSCAN_ATTRIBUTE_BUCKET_PERIOD, -+ GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, -+ GSCAN_ATTRIBUTE_BUCKET_CHANNELS, -+ GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, -+ GSCAN_ATTRIBUTE_REPORT_THRESHOLD, -+ GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, -+ GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND, -+ -+ GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, -+ GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates no more results */ -+ GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */ -+ GSCAN_ENABLE_FULL_SCAN_RESULTS, -+ GSCAN_ATTRIBUTE_REPORT_EVENTS, -+ -+ /* remaining reserved for additional attributes */ -+ GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, -+ GSCAN_ATTRIBUTE_FLUSH_RESULTS, -+ GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ -+ GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ -+ GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ -+ GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ -+ GSCAN_ATTRIBUTE_NUM_CHANNELS, -+ GSCAN_ATTRIBUTE_CHANNEL_LIST, -+ GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK, -+ -+ GSCAN_ATTRIBUTE_AFTER_LAST, -+ GSCAN_ATTRIBUTE_MAX = GSCAN_ATTRIBUTE_AFTER_LAST - 1, -+}; -+ -+enum andr_wifi_attributes { -+ ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, -+ ANDR_WIFI_ATTRIBUTE_FEATURE_SET, -+ ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, -+ ANDR_WIFI_ATTRIBUTE_NODFS_SET, -+ ANDR_WIFI_ATTRIBUTE_COUNTRY, -+ ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE, -+ // Add more attribute here -+ ANDR_WIFI_ATTRIBUTE_AFTER_LAST, -+ ANDR_WIFI_ATTRIBUTE_MAX = ANDR_WIFI_ATTRIBUTE_AFTER_LAST - 1, -+}; -+ -+enum wifi_support_feature { -+ /* Feature enums */ -+ WIFI_FEATURE_INFRA = 0x0001, /* Basic infrastructure mode */ -+ WIFI_FEATURE_INFRA_5G = 0x0002, /* Support for 5, GHz Band */ -+ WIFI_FEATURE_HOTSPOT = 0x0004, /* Support for GAS/ANQP */ -+ WIFI_FEATURE_P2P = 0x0008, /* Wifi-Direct */ -+ WIFI_FEATURE_SOFT_AP = 0x0010, /* Soft AP */ -+ WIFI_FEATURE_GSCAN = 0x0020, /* Google-Scan APIs */ -+ WIFI_FEATURE_NAN = 0x0040, /* Neighbor Awareness Networking */ -+ WIFI_FEATURE_D2D_RTT = 0x0080, /* Device-to-device RTT */ -+ WIFI_FEATURE_D2AP_RTT = 0x0100, /* Device-to-AP RTT */ -+ WIFI_FEATURE_BATCH_SCAN = 0x0200, /* Batched Scan (legacy) */ -+ WIFI_FEATURE_PNO = 0x0400, /* Preferred network offload */ -+ WIFI_FEATURE_ADDITIONAL_STA = 0x0800, /* Support for two STAs */ -+ WIFI_FEATURE_TDLS = 0x1000, /* Tunnel directed link setup */ -+ WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000, /* Support for TDLS off channel */ -+ WIFI_FEATURE_EPR = 0x4000, /* Enhanced power reporting */ -+ WIFI_FEATURE_AP_STA = 0x8000, /* Support for AP STA Concurrency */ -+ WIFI_FEATURE_LINK_LAYER_STATS = 0x10000, /* Support for Linkstats */ -+ WIFI_FEATURE_LOGGER = 0x20000, /* WiFi Logger */ -+ WIFI_FEATURE_HAL_EPNO = 0x40000, /* WiFi PNO enhanced */ -+ WIFI_FEATURE_RSSI_MONITOR = 0x80000, /* RSSI Monitor */ -+ WIFI_FEATURE_MKEEP_ALIVE = 0x100000, /* WiFi mkeep_alive */ -+ WIFI_FEATURE_CONFIG_NDO = 0x200000, /* ND offload configure */ -+ WIFI_FEATURE_TX_TRANSMIT_POWER = 0x400000, /* Capture Tx transmit power levels */ -+ WIFI_FEATURE_CONTROL_ROAMING = 0x800000, /* Enable/Disable firmware roaming */ -+ WIFI_FEATURE_IE_WHITELIST = 0x1000000, /* Support Probe IE white listing */ -+ WIFI_FEATURE_SCAN_RAND = 0x2000000, /* Support MAC & Probe Sequence Number randomization */ -+ WIFI_FEATURE_INVALID = 0xFFFFFFFF, /* Invalid Feature */ -+}; -+ -+enum wifi_logger_feature { -+ WIFI_LOGGER_MEMORY_DUMP_SUPPORTED = (1 << (0)), // Memory dump of FW -+ WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED = (1 << (1)), // PKT status -+ WIFI_LOGGER_CONNECT_EVENT_SUPPORTED = (1 << (2)), // Connectivity event -+ WIFI_LOGGER_POWER_EVENT_SUPPORTED = (1 << (3)), // POWER of Driver -+ WIFI_LOGGER_WAKE_LOCK_SUPPORTED = (1 << (4)), // WAKE LOCK of Driver -+ WIFI_LOGGER_VERBOSE_SUPPORTED = (1 << (5)), // verbose log of FW -+ WIFI_LOGGER_WATCHDOG_TIMER_SUPPORTED = (1 << (6)), // monitor the health of FW -+ WIFI_LOGGER_DRIVER_DUMP_SUPPORTED = (1 << (7)), // dumps driver state -+ WIFI_LOGGER_PACKET_FATE_SUPPORTED = (1 << (8)), // tracks connection packets' fate -+}; -+ -+enum wake_stats_attributes { -+ WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT, -+ WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE, -+ WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT, -+ WAKE_STAT_ATTRIBUTE_CMD_COUNT_USED, -+ WAKE_STAT_ATTRIBUTE_TOTAL_DRIVER_FW, -+ WAKE_STAT_ATTRIBUTE_DRIVER_FW_WAKE, -+ WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT, -+ WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT_USED, -+ WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE, -+ WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT, -+ WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT, -+ WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT, -+ WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT, -+ WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT, -+ WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA, -+ WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA, -+ WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS, -+ WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT, -+ WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT, -+ WAKE_STAT_ATTRIBUTE_OTHER__RX_MULTICAST_ADD_CNT, -+ WAKE_STAT_ATTRIBUTE_RX_MULTICAST_PKT_INFO, -+ WAKE_STAT_ATTRIBUTE_AFTER_LAST, -+ WAKE_STAT_ATTRIBUTE_MAX = WAKE_STAT_ATTRIBUTE_AFTER_LAST - 1, -+}; -+ -+enum vendor_nl80211_subcmd { -+ /* copied from wpa_supplicant brcm definations */ -+ VENDOR_NL80211_SUBCMD_UNSPEC = 0, -+ VENDOR_NL80211_SUBCMD_SET_PMK = 4, -+ VENDOR_NL80211_SUBCMD_SET_MAC = 6, -+ VENDOR_NL80211_SCMD_ACS = 9, -+ VENDOR_NL80211_SCMD_MAX = 10, -+}; -+ -+enum nl80211_vendor_subcmd_attributes { -+ WIFI_VENDOR_ATTR_DRIVER_CMD = 0, -+ WIFI_VENDOR_ATTR_DRIVER_KEY_PMK = 1, -+ WIFI_VENDOR_ATTR_DRIVER_MAC_ADDR = 3, -+ WIFI_VENDOR_ATTR_DRIVER_AFTER_LAST = 5, -+ WIFI_VENDOR_ATTR_DRIVER_MAX = -+ WIFI_VENDOR_ATTR_DRIVER_AFTER_LAST - 1, -+}; -+ -+typedef int wifi_ring_buffer_id; -+ -+struct wifi_ring_buffer_status { -+ u8 name[32]; -+ u32 flags; -+ wifi_ring_buffer_id ring_id; -+ u32 ring_buffer_byte_size; -+ u32 verbose_level; -+ u32 written_bytes; -+ u32 read_bytes; -+ u32 written_records; -+}; -+ -+struct rx_data_cnt_details_t { -+ int rx_unicast_cnt; /*Total rx unicast packet which woke up host */ -+ int rx_multicast_cnt; /*Total rx multicast packet which woke up host */ -+ int rx_broadcast_cnt; /*Total rx broadcast packet which woke up host */ -+}; -+ -+struct rx_wake_pkt_type_classification_t { -+ int icmp_pkt; /*wake icmp packet count */ -+ int icmp6_pkt; /*wake icmp6 packet count */ -+ int icmp6_ra; /*wake icmp6 RA packet count */ -+ int icmp6_na; /*wake icmp6 NA packet count */ -+ int icmp6_ns; /*wake icmp6 NS packet count */ -+ //ToDo: Any more interesting classification to add? -+}; -+ -+struct rx_multicast_cnt_t{ -+ int ipv4_rx_multicast_addr_cnt; /*Rx wake packet was ipv4 multicast */ -+ int ipv6_rx_multicast_addr_cnt; /*Rx wake packet was ipv6 multicast */ -+ int other_rx_multicast_addr_cnt;/*Rx wake packet was non-ipv4 and non-ipv6*/ -+}; -+ -+struct wlan_driver_wake_reason_cnt_t { -+ int total_cmd_event_wake; /* Total count of cmd event wakes */ -+ int *cmd_event_wake_cnt; /* Individual wake count array, each index a reason */ -+ int cmd_event_wake_cnt_sz; /* Max number of cmd event wake reasons */ -+ int cmd_event_wake_cnt_used; /* Number of cmd event wake reasons specific to the driver */ -+ -+ int total_driver_fw_local_wake; /* Total count of drive/fw wakes, for local reasons */ -+ int *driver_fw_local_wake_cnt; /* Individual wake count array, each index a reason */ -+ int driver_fw_local_wake_cnt_sz; /* Max number of local driver/fw wake reasons */ -+ int driver_fw_local_wake_cnt_used; /* Number of local driver/fw wake reasons specific to the driver */ -+ -+ int total_rx_data_wake; /* total data rx packets, that woke up host */ -+ struct rx_data_cnt_details_t rx_wake_details; -+ struct rx_wake_pkt_type_classification_t rx_wake_pkt_classification_info; -+ struct rx_multicast_cnt_t rx_multicast_wake_pkt_info; -+}; -+ -+typedef struct wl_mkeep_alive_pkt { -+ u16 version; /* Version for mkeep_alive */ -+ u16 length; /* length of fixed parameters in the structure */ -+ u32 period_msec; /* high bit on means immediate send */ -+ u16 len_bytes; -+ u8 keep_alive_id; /* 0 - 3 for N = 4 */ -+ u8 data[1]; -+} wl_mkeep_alive_pkt_t; -+ -+#endif /* _AIC_VENDOR_H */ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800d80.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800d80.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800d80.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800d80.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,66 @@ -+#include "rwnx_main.h" -+#include "rwnx_msg_tx.h" -+#include "reg_access.h" -+#include "aicwf_compat_8800d80.h" -+ -+#define FW_USERCONFIG_NAME_8800D80 "aic_userconfig_8800d80.txt" -+ -+int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw, -+ u32** buffer, const char *filename); -+void rwnx_plat_userconfig_parsing2(char *buffer, int size); -+void rwnx_plat_userconfig_parsing3(char *buffer, int size); -+ -+void rwnx_release_firmware_common(u32** buffer); -+ -+int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm) -+{ -+ int ret = 0; -+ -+ if ((ret = rwnx_send_txpwr_lvl_v3_req(rwnx_hw))) { -+ return -1; -+ } -+ -+ if ((ret = rwnx_send_txpwr_lvl_adj_req(rwnx_hw))) { -+ return -1; -+ } -+ -+ if ((ret = rwnx_send_txpwr_ofst2x_req(rwnx_hw))) { -+ return -1; -+ } -+ -+ if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) { -+ return -1; -+ } -+ -+ return 0 ; -+} -+ -+int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw) -+{ -+ int size; -+ u32 *dst=NULL; -+ char *filename = FW_USERCONFIG_NAME_8800D80; -+ -+ AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); -+ -+ /* load file */ -+ size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); -+ if (size <= 0) { -+ AICWFDBG(LOGERROR, "wrong size of firmware file\n"); -+ dst = NULL; -+ return 0; -+ } -+ -+ /* Copy the file on the Embedded side */ -+ AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); -+ -+ rwnx_plat_userconfig_parsing3((char *)dst, size); -+ -+ rwnx_release_firmware_common(&dst); -+ -+ AICWFDBG(LOGINFO, "userconfig download complete\n\n"); -+ return 0; -+ -+} -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800d80.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800d80.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800d80.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800d80.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,9 @@ -+#ifndef _AICWF_COMPAT_8800D80_H_ -+#define _AICWF_COMPAT_8800D80_H_ -+#include -+ -+int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm); -+int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw); -+ -+#endif -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800dc.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800dc.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800dc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800dc.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,542 @@ -+#include "rwnx_main.h" -+#include "rwnx_msg_tx.h" -+#include "reg_access.h" -+#include "aic_bsp_export.h" -+ -+#define RWNX_MAC_RF_PATCH_BASE_NAME_8800DC "fmacfw_rf_patch_8800dc" -+#define RWNX_MAC_RF_PATCH_NAME_8800DC RWNX_MAC_RF_PATCH_BASE_NAME_8800DC".bin" -+#define FW_USERCONFIG_NAME_8800DC "aic_userconfig_8800dc.txt" -+#define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt" -+ -+int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr, -+ char *filename); -+int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw, -+ u32** buffer, const char *filename); -+void rwnx_plat_userconfig_parsing2(char *buffer, int size); -+ -+void rwnx_release_firmware_common(u32** buffer); -+ -+u32 wifi_txgain_table_24g_8800dcdw[32] = -+{ -+ 0xA4B22189, //index 0 -+ 0x00007825, -+ 0xA4B2214B, //index 1 -+ 0x00007825, -+ 0xA4B2214F, //index 2 -+ 0x00007825, -+ 0xA4B221D5, //index 3 -+ 0x00007825, -+ 0xA4B221DC, //index 4 -+ 0x00007825, -+ 0xA4B221E5, //index 5 -+ 0x00007825, -+ 0xAC9221E5, //index 6 -+ 0x00006825, -+ 0xAC9221EF, //index 7 -+ 0x00006825, -+ 0xBC9221EE, //index 8 -+ 0x00006825, -+ 0xBC9221FF, //index 9 -+ 0x00006825, -+ 0xBC9221FF, //index 10 -+ 0x00004025, -+ 0xB792203F, //index 11 -+ 0x00004026, -+ 0xDC92203F, //index 12 -+ 0x00004025, -+ 0xE692203F, //index 13 -+ 0x00004025, -+ 0xFF92203F, //index 14 -+ 0x00004035, -+ 0xFFFE203F, //index 15 -+ 0x00004832 -+}; -+ -+u32 wifi_txgain_table_24g_1_8800dcdw[32] = -+{ -+ 0x096E2011, //index 0 -+ 0x00004001, -+ 0x096E2015, //index 1 -+ 0x00004001, -+ 0x096E201B, //index 2 -+ 0x00004001, -+ 0x116E2018, //index 3 -+ 0x00004001, -+ 0x116E201E, //index 4 -+ 0x00004001, -+ 0x116E2023, //index 5 -+ 0x00004001, -+ 0x196E2021, //index 6 -+ 0x00004001, -+ 0x196E202B, //index 7 -+ 0x00004001, -+ 0x216E202B, //index 8 -+ 0x00004001, -+ 0x236E2027, //index 9 -+ 0x00004001, -+ 0x236E2031, //index 10 -+ 0x00004001, -+ 0x246E2039, //index 11 -+ 0x00004001, -+ 0x26922039, //index 12 -+ 0x00004001, -+ 0x2E92203F, //index 13 -+ 0x00004001, -+ 0x3692203F, //index 14 -+ 0x00004001, -+ 0x3FF2203F, //index 15 -+ 0x00004001, -+}; -+ -+u32 wifi_txgain_table_24g_8800dcdw_h[32] = -+{ -+ 0xA55629C9, //index 0 -+ 0x00005825, -+ 0xAE5629C9, //index 1 -+ 0x00005825, -+ 0xAD5629CD, //index 2 -+ 0x00005825, -+ 0xAD5629D1, //index 3 -+ 0x00005825, -+ 0xAD5629D7, //index 4 -+ 0x00005825, -+ 0xAD5629DE, //index 5 -+ 0x00005825, -+ 0xAD5629E6, //index 6 -+ 0x00005825, -+ 0xBD5629E6, //index 7 -+ 0x00005825, -+ 0xBD5629F0, //index 8 -+ 0x00005825, -+ 0xCD5629F0, //index 9 -+ 0x00005825, -+ 0xE55629F0, //index 10 -+ 0x00005825, -+ 0xE55629FF, //index 11 -+ 0x00005825, -+ 0xE55629FF, //index 12 -+ 0x00002825, -+ 0xE75629FF, //index 13 -+ 0x00002825, -+ 0xFF5629FF, //index 14 -+ 0x00001825, -+ 0xFF5628FF, //index 15 -+ 0x00001025, -+}; -+ -+u32 wifi_txgain_table_24g_1_8800dcdw_h[32] = -+{ -+ 0x941A2048, //index 0 -+ 0x00001825, -+ 0x961A2048, //index 1 -+ 0x00001825, -+ 0x9D1A2048, //index 2 -+ 0x00001825, -+ 0x9A1A204F, //index 3 -+ 0x00001825, -+ 0x961A204F, //index 4 -+ 0x00001825, -+ 0x9A1A2057, //index 5 -+ 0x00001825, -+ 0x9C1A2057, //index 6 -+ 0x00001825, -+ 0xA31A205B, //index 7 -+ 0x00001825, -+ 0xAB1A205B, //index 8 -+ 0x00001825, -+ 0xAD1A205B, //index 9 -+ 0x00001825, -+ 0xA71A2064, //index 10 -+ 0x00001825, -+ 0xAD1A2070, //index 11 -+ 0x00001825, -+ 0xAD72207F, //index 12 -+ 0x00001825, -+ 0xBCAE207F, //index 13 -+ 0x00001825, -+ 0xBFB2207F, //index 14 -+ 0x00001825, -+ 0xD73A207F, //index 15 -+ 0x00001825, -+}; -+ -+u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = { -+ 0x82f282d1,//index 0 -+ 0x9591a324, -+ 0x80808419, -+ 0x000000f0, -+ 0x42f282d1,//index 1 -+ 0x95923524, -+ 0x80808419, -+ 0x000000f0, -+ 0x22f282d1,//index 2 -+ 0x9592c724, -+ 0x80808419, -+ 0x000000f0, -+ 0x02f282d1,//index 3 -+ 0x9591a324, -+ 0x80808419, -+ 0x000000f0, -+ 0x06f282d1,//index 4 -+ 0x9591a324, -+ 0x80808419, -+ 0x000000f0, -+ 0x0ef29ad1,//index 5 -+ 0x9591a324, -+ 0x80808419, -+ 0x000000f0, -+ 0x0ef29ad3,//index 6 -+ 0x95923524, -+ 0x80808419, -+ 0x000000f0, -+ 0x0ef29ad7,//index 7 -+ 0x9595a324, -+ 0x80808419, -+ 0x000000f0, -+ 0x02f282d2,//index 8 -+ 0x95951124, -+ 0x80808419, -+ 0x000000f0, -+ 0x02f282f4,//index 9 -+ 0x95951124, -+ 0x80808419, -+ 0x000000f0, -+ 0x02f282e6,//index 10 -+ 0x9595a324, -+ 0x80808419, -+ 0x000000f0, -+ 0x02f282e6,//index 11 -+ 0x9599a324, -+ 0x80808419, -+ 0x000000f0, -+ 0x02f282e6,//index 12 -+ 0x959da324, -+ 0x80808419, -+ 0x000000f0, -+ 0x02f282e6,//index 13 -+ 0x959f5924, -+ 0x80808419, -+ 0x000000f0, -+ 0x06f282e6,//index 14 -+ 0x959f5924, -+ 0x80808419, -+ 0x000000f0, -+ 0x0ef29ae6,//index 15 -+ 0x959f5924, //loft [35:34]=3 -+ 0x80808419, -+ 0x000000f0 -+}; -+ -+u32 wifi_rxgain_table_24g_40m_8800dcdw[64] = { -+ 0x83428151,//index 0 -+ 0x9631a328, -+ 0x80808419, -+ 0x000000f0, -+ 0x43428151,//index 1 -+ 0x96323528, -+ 0x80808419, -+ 0x000000f0, -+ 0x23428151,//index 2 -+ 0x9632c728, -+ 0x80808419, -+ 0x000000f0, -+ 0x03428151,//index 3 -+ 0x9631a328, -+ 0x80808419, -+ 0x000000f0, -+ 0x07429951,//index 4 -+ 0x9631a328, -+ 0x80808419, -+ 0x000000f0, -+ 0x0f42d151,//index 5 -+ 0x9631a328, -+ 0x80808419, -+ 0x000000f0, -+ 0x0f42d153,//index 6 -+ 0x96323528, -+ 0x80808419, -+ 0x000000f0, -+ 0x0f42d157,//index 7 -+ 0x9635a328, -+ 0x80808419, -+ 0x000000f0, -+ 0x03428152,//index 8 -+ 0x96351128, -+ 0x80808419, -+ 0x000000f0, -+ 0x03428174,//index 9 -+ 0x96351128, -+ 0x80808419, -+ 0x000000f0, -+ 0x03428166,//index 10 -+ 0x9635a328, -+ 0x80808419, -+ 0x000000f0, -+ 0x03428166,//index 11 -+ 0x9639a328, -+ 0x80808419, -+ 0x000000f0, -+ 0x03428166,//index 12 -+ 0x963da328, -+ 0x80808419, -+ 0x000000f0, -+ 0x03428166,//index 13 -+ 0x963f5928, -+ 0x80808419, -+ 0x000000f0, -+ 0x07429966,//index 14 -+ 0x963f5928, -+ 0x80808419, -+ 0x000000f0, -+ 0x0f42d166,//index 15 -+ 0x963f5928, -+ 0x80808419, -+ 0x000000f0 -+}; -+ -+#define RAM_LMAC_FW_ADDR 0x00150000 -+#ifdef CONFIG_DPD -+#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB)) -+extern int is_file_exist(char* name); -+#endif -+extern rf_misc_ram_lite_t dpd_res; -+ -+int aicwf_fdrv_dpd_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res) -+{ -+ int ret = 0; -+ uint32_t cfg_base = 0x10164; -+ struct dbg_mem_read_cfm cfm; -+ uint32_t misc_ram_addr; -+ uint32_t ram_base_addr, ram_byte_cnt; -+ AICWFDBG(LOGINFO, "bit_mask[1]=%x\n", dpd_res->bit_mask[1]); -+ if (dpd_res->bit_mask[1] == 0) { -+ AICWFDBG(LOGERROR, "void dpd_res, bypass it.\n"); -+ return 0; -+ } -+ if (testmode == 1) { -+ cfg_base = RAM_LMAC_FW_ADDR + 0x0164; -+ } -+ if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) { -+ AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); -+ return ret; -+ } -+ misc_ram_addr = cfm.memdata; -+ AICWFDBG(LOGINFO, "misc_ram_addr: %x\n", misc_ram_addr); -+ /* Copy dpd_res on the Embedded side */ -+ // bit_mask -+ AICWFDBG(LOGINFO, "bit_mask[0]=%x\n", dpd_res->bit_mask[0]); -+ ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask); -+ ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved); -+ ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->bit_mask[0]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "bit_mask wr fail: %x, ret:%d\r\n", ram_base_addr, ret); -+ return ret; -+ } -+ // dpd_high -+ AICWFDBG(LOGINFO, "dpd_high[0]=%x\n", dpd_res->dpd_high[0]); -+ ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high); -+ ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high); -+ ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->dpd_high[0]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "dpd_high wr fail: %x, ret:%d\r\n", ram_base_addr, ret); -+ return ret; -+ } -+ // loft_res -+ AICWFDBG(LOGINFO, "loft_res[0]=%x\n", dpd_res->loft_res[0]); -+ ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res); -+ ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res); -+ ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->loft_res[0]); -+ if (ret) { -+ AICWFDBG(LOGERROR, "loft_res wr fail: %x, ret:%d\r\n", ram_base_addr, ret); -+ return ret; -+ } -+ return ret; -+} -+ -+#ifndef CONFIG_FORCE_DPD_CALIB -+int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res) -+{ -+ int ret = 0; -+ int size; -+ u32 *dst=NULL; -+ char *filename = FW_DPDRESULT_NAME_8800DC; -+ AICWFDBG(LOGINFO, "dpd_res file path:%s \r\n", filename); -+ /* load file */ -+ size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); -+ if (size <= 0) { -+ AICWFDBG(LOGERROR, "wrong size of dpd_res file\n"); -+ dst = NULL; -+ return -1; -+ } -+ AICWFDBG(LOGINFO, "### Load file done: %s, size=%d, dst[0]=%x\n", filename, size, dst[0]); -+ memcpy((u8 *)dpd_res, (u8 *)dst, sizeof(rf_misc_ram_lite_t)); -+ if (dst) { -+ rwnx_release_firmware_common(&dst); -+ } -+ return ret; -+} -+#endif -+#endif -+ -+int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw) -+{ -+ int ret = 0; -+ uint32_t cfg_base = 0x10164; -+ struct dbg_mem_read_cfm cfm; -+ uint32_t misc_ram_addr; -+ uint32_t misc_ram_size = 12; -+ int i; -+ -+ if (testmode == 1) { -+ cfg_base = RAM_LMAC_FW_ADDR + 0x0164; -+ } -+ // init misc ram -+ printk("%s\n", __func__); -+ ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); -+ return ret; -+ } -+ misc_ram_addr = cfm.memdata; -+ AICWFDBG(LOGERROR, "misc_ram_addr=%x\n", misc_ram_addr); -+ for (i = 0; i < (misc_ram_size / 4); i++) { -+ ret = rwnx_send_dbg_mem_write_req(rwnx_hw, misc_ram_addr + i * 4, 0); -+ if (ret) { -+ AICWFDBG(LOGERROR, "rf misc ram[0x%x] wr fail: %d\n", misc_ram_addr + i * 4, ret); -+ return ret; -+ } -+ } -+ return ret; -+} -+ -+ -+int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm){ -+ int ret = 0; -+ -+ if ((ret = rwnx_send_txpwr_lvl_req(rwnx_hw))) { -+ return -1; -+ } -+ -+ if ((ret = rwnx_send_txpwr_ofst_req(rwnx_hw))) { -+ return -1; -+ } -+ -+ -+ if (testmode == 0) { -+ if (IS_CHIP_ID_H()) { -+ if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0, 1, (u8_l *)wifi_txgain_table_24g_8800dcdw_h, 128))) -+ return -1; -+ -+ if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw_h, 128))) -+ return -1; -+ } else { -+ if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0, 1, (u8_l *)wifi_txgain_table_24g_8800dcdw, 128))) -+ return -1; -+ -+ if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw, 128))) -+ return -1; -+ } -+ -+ if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0, 0, (u8_l *)wifi_rxgain_table_24g_20m_8800dcdw, 256))) -+ return -1; -+ -+ if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32, 0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256))) -+ return -1; -+ -+ if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) { -+ return -1; -+ } -+ } else if (testmode == 1) { -+ if (chip_sub_id >= 1) { -+ #ifdef CONFIG_DPD -+ #ifndef CONFIG_FORCE_DPD_CALIB -+ if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) { -+ AICWFDBG(LOGINFO, "%s load dpd bin\n", __func__); -+ ret = aicwf_fdrv_dpd_result_load_8800dc(rwnx_hw, &dpd_res); -+ if (ret) { -+ AICWFDBG(LOGINFO, "load dpd bin fail: %d\n", ret); -+ return ret; -+ } -+ } -+ #endif -+ if (dpd_res.bit_mask[1]) { -+ ret = aicwf_fdrv_dpd_result_apply_8800dc(rwnx_hw, &dpd_res); -+ if (ret) { -+ AICWFDBG(LOGINFO, "apply dpd bin fail: %d\n", ret); -+ return ret; -+ } -+ } -+ #else -+ { -+ ret = aicwf_fdrv_misc_ram_init_8800dc(rwnx_hw); -+ if (ret) { -+ AICWFDBG(LOGINFO, "misc ram init fail: %d\n", ret); -+ return ret; -+ } -+ } -+ #endif -+ ret = rwnx_send_rf_calib_req(rwnx_hw, cfm); -+ if (ret) { -+ AICWFDBG(LOGINFO, "rf calib req fail: %d\n", ret); -+ return ret; -+ } -+ } -+ } -+ -+ return 0 ; -+} -+ -+int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw){ -+ int size; -+ u32 *dst=NULL; -+ char *filename = FW_USERCONFIG_NAME_8800DC; -+ -+ AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); -+ -+ /* load file */ -+ size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); -+ if (size <= 0) { -+ AICWFDBG(LOGERROR, "wrong size of firmware file\n"); -+ dst = NULL; -+ return 0; -+ } -+ -+ /* Copy the file on the Embedded side */ -+ AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); -+ -+ rwnx_plat_userconfig_parsing2((char *)dst, size); -+ -+ rwnx_release_firmware_common(&dst); -+ -+ AICWFDBG(LOGINFO, "userconfig download complete\n\n"); -+ return 0; -+ -+} -+ -+int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){ -+ int size; -+ u32 *dst=NULL; -+ char *filename = FW_USERCONFIG_NAME_8800DC; -+ -+ AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); -+ -+ /* load file */ -+ size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); -+ if (size <= 0) { -+ AICWFDBG(LOGERROR, "wrong size of firmware file\n"); -+ dst = NULL; -+ return 0; -+ } -+ -+ /* Copy the file on the Embedded side */ -+ AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); -+ -+ rwnx_plat_userconfig_parsing2((char *)dst, size); -+ -+ rwnx_release_firmware_common(&dst); -+ -+ AICWFDBG(LOGINFO, "userconfig download complete\n\n"); -+ return 0; -+ -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800dc.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800dc.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800dc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_compat_8800dc.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,15 @@ -+#include -+#include "aic_bsp_export.h" -+ -+#ifdef CONFIG_DPD -+int aicwf_fdrv_dpd_result_apply_8800dc(struct rwnx_hw * rwnx_hw, rf_misc_ram_lite_t * dpd_res); -+#ifndef CONFIG_FORCE_DPD_CALIB -+int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res); -+#endif -+#endif -+int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw); -+int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm); -+int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw); -+int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw); -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_debug.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_debug.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_debug.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_debug.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,56 @@ -+ -+ -+#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__ -+ -+ -+ -+/* message levels */ -+#define LOGERROR 0x0001 -+#define LOGINFO 0x0002 -+#define LOGTRACE 0x0004 -+#define LOGDEBUG 0x0008 -+#define LOGDATA 0x0010 -+#define LOGIRQ 0x0020 -+#define LOGSDPWRC 0x0040 -+#define LOGWAKELOCK 0x0080 -+#define LOGRXPOLL 0x0100 -+ -+extern int aicwf_dbg_level; -+void rwnx_data_dump(char* tag, void* data, unsigned long len); -+ -+#define AICWF_LOG "AICWFDBG(" -+ -+#define AICWFDBG(level, args, arg...) \ -+do { \ -+ if (aicwf_dbg_level & level) { \ -+ printk(AICWF_LOG#level")\t" args, ##arg); \ -+ } \ -+} while (0) -+ -+#define RWNX_DBG(fmt, ...) \ -+do { \ -+ if (aicwf_dbg_level & LOGTRACE) { \ -+ printk(AICWF_LOG"LOGTRACE)\t"fmt , ##__VA_ARGS__); \ -+ } \ -+} while (0) -+ -+ -+ -+#if 0 -+#define RWNX_DBG(fmt, ...) \ -+ do { \ -+ if (aicwf_dbg_level & LOGTRACE) { \ -+ printk(AICWF_LOG"LOGTRACE"")\t" fmt, ##__VA_ARGS__); \ -+ } \ -+ } while (0) -+#define AICWFDBG(args, level) \ -+do { \ -+ if (aicwf_dbg_level & level) { \ -+ printk(AICWF_LOG"(%s)\t" ,#level); \ -+ printf args; \ -+ } \ -+} while (0) -+#endif -+ -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_rx_prealloc.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_rx_prealloc.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_rx_prealloc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_rx_prealloc.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,97 @@ -+#include -+#include -+#include -+#include -+#include -+#include "aicwf_rx_prealloc.h" -+ -+#ifdef CONFIG_PREALLOC_RX_SKB -+struct aicwf_rx_buff_list aic_rx_buff_list; -+ -+int aic_rxbuff_num_max = 30; -+ -+int aic_rxbuff_size = (64 * 512); -+ -+struct rx_buff *aicwf_prealloc_rxbuff_alloc(spinlock_t *lock) -+{ -+ unsigned long flags; -+ struct rx_buff *rxbuff = NULL; -+ -+ spin_lock_irqsave(lock, flags); -+ if (list_empty(&aic_rx_buff_list.rxbuff_list)) { -+ spin_unlock_irqrestore(lock, flags); -+ printk("%s %d, rxbuff list is empty\n", __func__, __LINE__); -+ return NULL; -+ } else { -+ rxbuff = list_first_entry(&aic_rx_buff_list.rxbuff_list, -+ struct rx_buff, queue); -+ list_del_init(&rxbuff->queue); -+ atomic_dec(&aic_rx_buff_list.rxbuff_list_len); -+ } -+ spin_unlock_irqrestore(lock, flags); -+ //printk("len:%d\n", aic_rx_buff_list.rxbuff_list_len); -+ memset(rxbuff->data, 0, aic_rxbuff_size); -+ rxbuff->len = 0; -+ rxbuff->start = NULL; -+ rxbuff->read = NULL; -+ rxbuff->end = NULL; -+ -+ return rxbuff; -+} -+ -+void aicwf_prealloc_rxbuff_free(struct rx_buff *rxbuff, spinlock_t *lock) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(lock, flags); -+ list_add_tail(&rxbuff->queue, &aic_rx_buff_list.rxbuff_list); -+ atomic_inc(&aic_rx_buff_list.rxbuff_list_len); -+ spin_unlock_irqrestore(lock, flags); -+} -+ -+int aicwf_prealloc_init() -+{ -+ struct rx_buff *rxbuff; -+ int i = 0; -+ -+ printk("%s enter\n", __func__); -+ INIT_LIST_HEAD(&aic_rx_buff_list.rxbuff_list); -+ -+ for (i = 0 ; i < aic_rxbuff_num_max ; i++) { -+ rxbuff = kzalloc(sizeof(struct rx_buff), GFP_KERNEL); -+ if (rxbuff) { -+ rxbuff->data = kzalloc(aic_rxbuff_size, GFP_KERNEL); -+ if (rxbuff->data == NULL) { -+ printk("failed to alloc rxbuff data\n"); -+ kfree(rxbuff); -+ continue; -+ } -+ rxbuff->len = 0; -+ rxbuff->start = NULL; -+ rxbuff->read = NULL; -+ rxbuff->end = NULL; -+ list_add_tail(&rxbuff->queue, &aic_rx_buff_list.rxbuff_list); -+ atomic_inc(&aic_rx_buff_list.rxbuff_list_len); -+ } -+ } -+ -+ printk("pre alloc rxbuff list len: %d\n", (int)atomic_read(&aic_rx_buff_list.rxbuff_list_len)); -+ return 0; -+} -+ -+void aicwf_prealloc_exit() -+{ -+ struct rx_buff *rxbuff; -+ struct rx_buff *pos; -+ -+ printk("%s enter\n", __func__); -+ -+ printk("free pre alloc rxbuff list %d\n", (int)atomic_read(&aic_rx_buff_list.rxbuff_list_len)); -+ list_for_each_entry_safe(rxbuff, pos, &aic_rx_buff_list.rxbuff_list, queue) { -+ list_del_init(&rxbuff->queue); -+ kfree(rxbuff->data); -+ kfree(rxbuff); -+ } -+} -+#endif -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_rx_prealloc.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_rx_prealloc.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_rx_prealloc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_rx_prealloc.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,24 @@ -+#ifndef _AICWF_RX_PREALLOC_H_ -+#define _AICWF_RX_PREALLOC_H_ -+ -+#ifdef CONFIG_PREALLOC_RX_SKB -+struct rx_buff { -+ struct list_head queue; -+ unsigned char *data; -+ u32 len; -+ uint8_t *start; -+ uint8_t *end; -+ uint8_t *read; -+}; -+ -+struct aicwf_rx_buff_list { -+ struct list_head rxbuff_list; -+ atomic_t rxbuff_list_len; -+}; -+ -+struct rx_buff *aicwf_prealloc_rxbuff_alloc(spinlock_t *lock); -+void aicwf_prealloc_rxbuff_free(struct rx_buff *rxbuff, spinlock_t *lock); -+int aicwf_prealloc_init(void); -+void aicwf_prealloc_exit(void); -+#endif -+#endif /* _AICWF_RX_PREALLOC_H_ */ -\ No newline at end of file -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,2591 @@ -+/** -+ * aicwf_sdmmc.c -+ * -+ * SDIO function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "aicwf_txrxif.h" -+#include "aicwf_sdio.h" -+#include "sdio_host.h" -+#include "rwnx_defs.h" -+#include "rwnx_platform.h" -+#include "aicwf_rx_prealloc.h" -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+#include -+#else -+#include -+#endif -+#include "rwnx_wakelock.h" -+ -+#ifdef CONFIG_INGENIC_T20 -+#include "mach/jzmmc.h" -+#endif /* CONFIG_INGENIC_T20 */ -+#ifdef CONFIG_PLATFORM_ROCKCHIP -+#include -+#endif -+#ifdef CONFIG_PLATFORM_ROCKCHIP2 -+#include -+#endif -+ -+#include "aic_bsp_export.h" -+extern uint8_t scanning; -+ -+#ifdef CONFIG_GPIO_WAKEUP -+extern int rwnx_send_me_set_lp_level(struct rwnx_hw *rwnx_hw, u8 lp_level); -+ -+#ifdef CONFIG_WIFI_SUSPEND_FOR_LINUX -+#include -+void rwnx_init_wifi_suspend_node(void); -+void rwnx_deinit_wifi_suspend_node(void); -+void rwnx_set_wifi_suspend(char onoff); -+struct proc_dir_entry *wifi_suspend_node; -+#endif//CONFIG_WIFI_SUSPEND_FOR_LINUX -+ -+#endif//CONFIG_GPIO_WAKEUP -+ -+int tx_aggr_counter = 32; -+module_param_named(tx_aggr_counter, tx_aggr_counter, int, 0644); -+ -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+int tx_fc_low_water = AICWF_SDIO_TX_LOW_WATER; -+module_param_named(tx_fc_low_water, tx_fc_low_water, int, 0644); -+ -+int tx_fc_high_water = AICWF_SDIO_TX_HIGH_WATER; -+module_param_named(tx_fc_high_water, tx_fc_high_water, int, 0644); -+#endif -+ -+int aicwf_sdio_readb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 *val) -+{ -+ int ret; -+ sdio_claim_host(sdiodev->func); -+ *val = sdio_readb(sdiodev->func, regaddr, &ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+} -+ -+int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val) -+{ -+ int ret; -+ sdio_claim_host(sdiodev->func); -+ sdio_writeb(sdiodev->func, val, regaddr, &ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+} -+ -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+void aicwf_sdio_tx_netif_flowctrl(struct rwnx_hw *rwnx_hw, bool state) -+{ -+ struct rwnx_vif *rwnx_vif; -+ list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) { -+ if (! rwnx_vif->up) -+ continue; -+ if (state) -+ netif_tx_stop_all_queues(rwnx_vif->ndev);//netif_stop_queue(rwnx_vif->ndev); -+ else -+ netif_tx_wake_all_queues(rwnx_vif->ndev);//netif_wake_queue(rwnx_vif->ndev); -+ } -+} -+#endif -+ -+int aicwf_sdio_flow_ctrl_msg(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = -1; -+ u8 fc_reg = 0; -+ u32 count = 0; -+ -+ while (true) { -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.flow_ctrl_reg, &fc_reg); -+ if (ret) { -+ return -1; -+ } -+ -+ if (sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ fc_reg = fc_reg & SDIOWIFI_FLOWCTRL_MASK_REG; -+ } -+ -+ if (fc_reg != 0) { -+ ret = fc_reg; -+ if(ret > tx_aggr_counter){ -+ ret = tx_aggr_counter; -+ } -+ return ret; -+ } else { -+ if (count >= FLOW_CTRL_RETRY_COUNT) { -+ ret = -fc_reg; -+ break; -+ } -+ count++; -+ if (count < 30) -+ udelay(200); -+ else if(count < 40) -+ msleep(2); -+ else -+ msleep(10); -+ } -+ } -+ -+ return ret; -+} -+ -+ -+int aicwf_sdio_flow_ctrl(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = -1; -+ u8 fc_reg = 0; -+ u32 count = 0; -+ -+ while (true) { -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.flow_ctrl_reg, &fc_reg); -+ if (ret) { -+ return -1; -+ } -+ -+ if (sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ fc_reg = fc_reg & SDIOWIFI_FLOWCTRL_MASK_REG; -+ } -+ -+ if (fc_reg > DATA_FLOW_CTRL_THRESH) { -+ ret = fc_reg; -+ if(ret > tx_aggr_counter){ -+ ret = tx_aggr_counter; -+ } -+ return ret; -+ } else { -+ if (count >= FLOW_CTRL_RETRY_COUNT) { -+ ret = -fc_reg; -+ break; -+ } -+ count++; -+ if (count < 30) -+ udelay(200); -+ else if(count < 40) -+ msleep(2); -+ else -+ msleep(10); -+ } -+ } -+ -+ return ret; -+} -+ -+ -+int aicwf_sdio_send_pkt(struct aic_sdio_dev *sdiodev, u8 *buf, uint count) -+{ -+ int ret = 0; -+ -+ sdio_claim_host(sdiodev->func); -+ ret = sdio_writesb(sdiodev->func, sdiodev->sdio_reg.wr_fifo_addr, buf, count); -+ sdio_release_host(sdiodev->func); -+ -+ return ret; -+} -+ -+#ifdef CONFIG_PREALLOC_RX_SKB -+int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct rx_buff *rxbuff, -+ u32 size) -+{ -+ int ret; -+ -+ if ((!rxbuff->data) || (!size)) { -+ return -EINVAL;; -+ } -+ -+ sdio_claim_host(sdiodev->func); -+ ret = sdio_readsb(sdiodev->func, rxbuff->data, sdiodev->sdio_reg.rd_fifo_addr, size); -+ sdio_release_host(sdiodev->func); -+ -+ if (ret < 0) { -+ return ret; -+ } -+ rxbuff->len = size; -+ -+ return ret; -+} -+#else -+int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct sk_buff *skbbuf, -+ u32 size) -+{ -+ int ret; -+ -+ if ((!skbbuf) || (!size)) { -+ return -EINVAL;; -+ } -+ -+ sdio_claim_host(sdiodev->func); -+ ret = sdio_readsb(sdiodev->func, skbbuf->data, sdiodev->sdio_reg.rd_fifo_addr, size); -+ sdio_release_host(sdiodev->func); -+ -+ if (ret < 0) { -+ return ret; -+ } -+ skbbuf->len = size; -+ -+ return ret; -+} -+#endif -+ -+ -+#ifdef CONFIG_GPIO_WAKEUP -+static int wakeup_enable; -+static u32 hostwake_irq_num; -+#endif//CONFIG_GPIO_WAKEUP -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)//LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) -+//static struct wakeup_source *ws_rx_sdio; -+//static struct wakeup_source *ws_sdio_pwrctrl; -+//static struct wakeup_source *ws_tx_sdio; -+#ifdef CONFIG_GPIO_WAKEUP -+//static struct wakeup_source *ws; -+#endif -+#else -+#ifdef ANDROID_PLATFORM -+#ifdef CONFIG_GPIO_WAKEUP -+#include -+static struct wake_lock irq_wakelock; -+//struct wake_lock irq_wakelock; -+#endif//CONFIG_GPIO_WAKEUP -+#endif//ANDROID_PLATFORM -+#endif -+ -+#ifdef CONFIG_PLATFORM_ALLWINNER -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) -+extern int sunxi_wlan_get_oob_irq(int *, int *); -+#else -+extern int sunxi_wlan_get_oob_irq(void); -+extern int sunxi_wlan_get_oob_irq_flags(void); -+#endif -+#endif// CONFIG_PLATFORM_ALLWINNER -+ -+#if 0 -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+static struct wakeup_source *ws; -+#else -+#ifdef ANDROID_PLATFORM -+#ifdef CONFIG_GPIO_WAKEUP -+#include -+static struct wake_lock irq_wakelock; -+#endif//CONFIG_GPIO_WAKEUP -+#endif//ANDROID_PLATFORM -+#endif -+#endif -+ -+#if 0 -+void rwnx_pm_stay_awake(struct aic_sdio_dev *sdiodev){ -+ -+#ifdef CONFIG_GPIO_WAKEUP -+ spin_lock_bh(&sdiodev->wslock); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ if(ws != NULL){ -+ __pm_stay_awake(ws); -+ AICWFDBG(LOGWAKELOCK, "%s active_count:%d relax_count:%d\r\n", __func__, (int)ws->active_count, (int)ws->relax_count); -+ } -+#else -+#ifdef ANDROID_PLATFORM -+#ifdef CONFIG_GPIO_WAKEUP -+ wake_lock(&irq_wakelock); -+#endif //CONFIG_GPIO_WAKEUP -+#endif //ANDROID_PLATFORM -+#endif -+ -+ spin_unlock_bh(&sdiodev->wslock); -+#endif -+} -+ -+void rwnx_pm_relax(struct aic_sdio_dev *sdiodev){ -+ -+#ifdef CONFIG_GPIO_WAKEUP -+ spin_lock_bh(&sdiodev->wslock); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ if(ws != NULL){ -+ __pm_relax(ws); -+ AICWFDBG(LOGWAKELOCK, "%s active_count:%d relax_count:%d\r\n", __func__, (int)ws->active_count, (int)ws->relax_count); -+ } -+#else -+#ifdef ANDROID_PLATFORM -+#ifdef CONFIG_GPIO_WAKEUP -+ wake_unlock(&irq_wakelock); -+#endif //CONFIG_GPIO_WAKEUP -+#endif //ANDROID_PLATFORM -+#endif -+ spin_unlock_bh(&sdiodev->wslock); -+#endif -+ -+} -+#endif -+ -+ -+#ifdef CONFIG_GPIO_WAKEUP -+ -+void rwnx_set_wifi_suspend(char onoff); -+ -+ -+static irqreturn_t rwnx_hostwake_irq_handler(int irq, void *para) -+{ -+ static int wake_cnt; -+ wake_cnt++; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ rwnx_wakeup_lock_timeout(g_rwnx_plat->sdiodev->rwnx_hw->ws_rx, 1000); -+#else -+#ifdef ANDROID_PLATFORM -+ wake_lock_timeout(&irq_wakelock, HZ); -+#endif //ANDROID_PLATFORM -+#endif -+ -+ AICWFDBG(LOGIRQ, "%s(%d): wake_irq_cnt = %d\n", __func__, __LINE__, wake_cnt); -+ -+#ifdef CONFIG_OOB -+#if 0//old oob feature -+ complete(&g_rwnx_plat->sdiodev->bus_if->busrx_trgg); -+#else//new oob feature -+ if(g_rwnx_plat->sdiodev->oob_enable){ -+ complete(&g_rwnx_plat->sdiodev->bus_if->busirq_trgg); -+ } -+#endif//old oob feature -+#endif -+ -+ return IRQ_HANDLED; -+} -+#endif//CONFIG_GPIO_WAKEUP -+ -+#ifdef CONFIG_GPIO_WAKEUP -+static int rwnx_disable_hostwake_irq(void); -+static int rwnx_enable_hostwake_irq(void); -+#endif -+ -+static int rwnx_register_hostwake_irq(struct device *dev) -+{ -+ int ret = 0;//-1; -+#ifdef CONFIG_GPIO_WAKEUP -+ unsigned long flag_edge; -+ struct aicbsp_feature_t aicwf_feature; -+ int irq_flags; -+//TODO hostwake_irq_num hostwake_irq_num and wakeup_enable -+ -+ aicbsp_get_feature(&aicwf_feature, NULL); -+ if (aicwf_feature.irqf == 0) -+ flag_edge = IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND; -+ else -+ flag_edge = IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND; -+ -+ -+#ifdef CONFIG_PLATFORM_ALLWINNER -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) -+ hostwake_irq_num = sunxi_wlan_get_oob_irq(&irq_flags, &wakeup_enable); -+#else -+ hostwake_irq_num = sunxi_wlan_get_oob_irq(); -+ irq_flags = sunxi_wlan_get_oob_irq_flags(); -+ wakeup_enable = 1; -+#endif -+#endif //CONFIG_PLATFORM_ALLWINNER -+ -+//For Rockchip -+#ifdef CONFIG_PLATFORM_ROCKCHIP -+ hostwake_irq_num = rockchip_wifi_get_oob_irq(); -+ printk("%s hostwake_irq_num:%d \r\n", __func__, hostwake_irq_num); -+ irq_flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE) & IRQF_TRIGGER_MASK; -+ printk("%s irq_flags:%d \r\n", __func__, irq_flags); -+ wakeup_enable = 1; -+#endif //CONFIG_PLATFORM_ROCKCHIP -+ //For Rockchip -+#ifdef CONFIG_PLATFORM_ROCKCHIP2 -+ hostwake_irq_num = rockchip_wifi_get_oob_irq(); -+ printk("%s hostwake_irq_num:%d \r\n", __func__, hostwake_irq_num); -+ irq_flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE) & IRQF_TRIGGER_MASK; -+ printk("%s irq_flags:%d \r\n", __func__, irq_flags); -+ wakeup_enable = 1; -+#endif //CONFIG_PLATFORM_ROCKCHIP -+ -+ -+ -+ if (wakeup_enable) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ //ws = wakeup_source_register(dev, "wifisleep"); -+ //ws_tx_sdio = wakeup_source_register(dev, "wifi_tx_sleep"); -+ //ws_rx_sdio = wakeup_source_register(dev, "wifi_rx_sleep"); -+ //ws_sdio_pwrctrl = wakeup_source_register(dev, "sdio_pwrctrl_sleep"); -+#else -+#ifdef ANDROID_PLATFORM -+ wake_lock_init(&irq_wakelock, WAKE_LOCK_SUSPEND, "wifisleep"); -+#endif -+#endif -+ ret = device_init_wakeup(dev, true); -+ if (ret < 0) { -+ pr_err("%s(%d): device init wakeup failed!\n", __func__, __LINE__); -+ return ret; -+ } -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+ ret = dev_pm_set_wake_irq(dev, hostwake_irq_num); -+#endif -+ if (ret < 0) { -+ pr_err("%s(%d): can't enable wakeup src!\n", __func__, __LINE__); -+ goto fail1; -+ } -+ -+ ret = request_irq(hostwake_irq_num, rwnx_hostwake_irq_handler, flag_edge, "rwnx_hostwake_irq", NULL); -+ -+ if (ret < 0) { -+ pr_err("%s(%d): request_irq fail! ret = %d\n", __func__, __LINE__, ret); -+ goto fail2; -+ } -+ } -+ //disable_irq(hostwake_irq_num); -+ rwnx_disable_hostwake_irq(); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+ dev_pm_clear_wake_irq(dev); -+#endif -+ rwnx_enable_hostwake_irq(); -+ AICWFDBG(LOGINFO, "%s(%d)\n", __func__, __LINE__); -+ return ret; -+ -+fail2: -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+ dev_pm_clear_wake_irq(dev); -+#endif -+fail1: -+ device_init_wakeup(dev, false); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ //wakeup_source_unregister(ws); -+ //wakeup_source_unregister(ws_tx_sdio); -+ //wakeup_source_unregister(ws_rx_sdio); -+ //wakeup_source_unregister(ws_sdio_pwrctrl); -+#else -+#ifdef ANDROID_PLATFORM -+ wake_lock_destroy(&irq_wakelock); -+#endif -+#endif -+#endif//CONFIG_GPIO_WAKEUP -+ return ret; -+} -+ -+static int rwnx_unregister_hostwake_irq(struct device *dev) -+{ -+#ifdef CONFIG_GPIO_WAKEUP -+ rwnx_disable_hostwake_irq(); -+ if (wakeup_enable) { -+ device_init_wakeup(dev, false); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+ dev_pm_clear_wake_irq(dev); -+#else -+ AICWFDBG(LOGERROR, "%s kernel unsupport this feature!\r\n", __func__); -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ //wakeup_source_unregister(ws); -+ //wakeup_source_unregister(ws_tx_sdio); -+ //wakeup_source_unregister(ws_rx_sdio); -+ //wakeup_source_unregister(ws_sdio_pwrctrl); -+#else -+#ifdef ANDROID_PLATFORM -+ wake_lock_destroy(&irq_wakelock); -+#endif //ANDROID_PLATFORM -+#endif -+ } -+ free_irq(hostwake_irq_num, NULL); -+#endif//CONFIG_GPIO_WAKEUP -+ AICWFDBG(LOGINFO, "%s(%d)\n", __func__, __LINE__); -+ return 0; -+} -+ -+#ifdef CONFIG_GPIO_WAKEUP -+static int rwnx_enable_hostwake_irq(void) -+{ -+#ifdef CONFIG_GPIO_WAKEUP -+ enable_irq(hostwake_irq_num); -+ enable_irq_wake(hostwake_irq_num); -+#endif//CONFIG_GPIO_WAKEUP -+ AICWFDBG(LOGINFO, "%s(%d)\n", __func__, __LINE__); -+ return 0; -+} -+ -+static int rwnx_disable_hostwake_irq(void) -+{ -+ AICWFDBG(LOGINFO, "%s(%d)\n", __func__, __LINE__); -+#ifdef CONFIG_GPIO_WAKEUP -+ disable_irq_nosync(hostwake_irq_num); -+ //disable_irq_wake(hostwake_irq_num); -+ //disable_irq(hostwake_irq_num); -+#endif//CONFIG_GPIO_WAKEUP -+ return 0; -+} -+#endif -+ -+static int aicwf_sdio_chipmatch(struct aic_sdio_dev *sdio_dev, u16_l vid, u16_l did){ -+ -+ if(vid == SDIO_VENDOR_ID_AIC8801 && did == SDIO_DEVICE_ID_AIC8801){ -+ sdio_dev->chipid = PRODUCT_ID_AIC8801; -+ AICWFDBG(LOGINFO, "%s USE AIC8801\r\n", __func__); -+ return 0; -+ }else if(vid == SDIO_VENDOR_ID_AIC8800DC && did == SDIO_DEVICE_ID_AIC8800DC){ -+ sdio_dev->chipid = PRODUCT_ID_AIC8800DC; -+ AICWFDBG(LOGINFO, "%s USE AIC8800DC\r\n", __func__); -+ return 0; -+ }else if(vid == SDIO_VENDOR_ID_AIC8800D80 && did == SDIO_DEVICE_ID_AIC8800D80){ -+ sdio_dev->chipid = PRODUCT_ID_AIC8800D80; -+ AICWFDBG(LOGINFO, "%s USE AIC8800D80\r\n", __func__); -+ return 0; -+ }else{ -+ return -1; -+ } -+} -+ -+ -+extern int rwnx_send_me_set_lp_level(struct rwnx_hw *rwnx_hw, u8 lp_level); -+ -+static int aicwf_sdio_probe(struct sdio_func *func, -+ const struct sdio_device_id *id) -+{ -+ struct mmc_host *host; -+ struct aic_sdio_dev *sdiodev; -+ struct aicwf_bus *bus_if; -+ int err = -ENODEV; -+ -+ AICWFDBG(LOGDEBUG, "%s:%d\n", __func__, func->num); -+ AICWFDBG(LOGDEBUG, "Class=%x\n", func->class); -+ AICWFDBG(LOGDEBUG, "sdio vendor ID: 0x%04x\n", func->vendor); -+ AICWFDBG(LOGDEBUG, "sdio device ID: 0x%04x\n", func->device); -+ AICWFDBG(LOGDEBUG, "Function#: %d\n", func->num); -+ -+ host = func->card->host; -+ if (func->num != 1) { -+ return err; -+ } -+ -+ bus_if = kzalloc(sizeof(struct aicwf_bus), GFP_KERNEL); -+ if (!bus_if) { -+ sdio_err("alloc bus fail\n"); -+ return -ENOMEM; -+ } -+ -+ sdiodev = kzalloc(sizeof(struct aic_sdio_dev), GFP_KERNEL); -+ if (!sdiodev) { -+ sdio_err("alloc sdiodev fail\n"); -+ kfree(bus_if); -+ return -ENOMEM; -+ } -+ -+ -+ err = aicwf_sdio_chipmatch(sdiodev, func->vendor, func->device); -+ -+ sdiodev->func = func; -+ sdiodev->bus_if = bus_if; -+ -+#ifdef CONFIG_OOB -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801){ -+ AICWFDBG(LOGERROR, "%s ERROR!!! 8801 not support OOB \r\n", __func__); -+ sdiodev->oob_enable = false; -+ }else{ -+ sdiodev->oob_enable = true; -+ } -+#else -+ sdiodev->oob_enable = false; -+#endif -+ -+ atomic_set(&sdiodev->is_bus_suspend, 0); -+ bus_if->bus_priv.sdio = sdiodev; -+ -+ dev_set_drvdata(&func->dev, bus_if); -+ sdiodev->dev = &func->dev; -+ -+ //sdio func init start -+ if (sdiodev->chipid != PRODUCT_ID_AIC8800D80) { -+ err = aicwf_sdio_func_init(sdiodev); -+ } else { -+ err = aicwf_sdiov3_func_init(sdiodev); -+ } -+ if (err < 0) { -+ sdio_err("sdio func init fail\n"); -+ goto fail; -+ } -+ //sdio func init end -+ -+ if (aicwf_sdio_bus_init(sdiodev) == NULL) { -+ sdio_err("sdio bus init fail\n"); -+ err = -1; -+ goto fail; -+ } -+ -+ host->caps |= MMC_CAP_NONREMOVABLE; -+ aicwf_rwnx_sdio_platform_init(sdiodev); -+ aicwf_hostif_ready(); -+ err = rwnx_register_hostwake_irq(sdiodev->dev); -+ if (err != 0) -+ return err; -+ -+#ifdef CONFIG_GPIO_WAKEUP -+#ifdef CONFIG_OOB -+ if(sdiodev->oob_enable){ -+ AICWFDBG(LOGINFO, "%s SDIOWIFI_INTR_CONFIG_REG Disable\n", __func__); -+ sdio_claim_host(sdiodev->func); -+ //disable sdio interrupt -+ err = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x0); -+ if (err < 0) { -+ sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG); -+ } -+ sdio_release_irq(sdiodev->func); -+ sdio_release_host(sdiodev->func); -+#if 0 -+#if 0//old oob feature -+ sdiodev->oob_enable = true; -+#else//new oob feature -+ sdiodev->oob_enable = true; -+#endif//old oob feature -+#endif -+ } -+#endif -+ -+#ifdef CONFIG_WIFI_SUSPEND_FOR_LINUX -+ rwnx_init_wifi_suspend_node(); -+#endif//CONFIG_WIFI_SUSPEND_FOR_LINUX -+#endif//CONFIG_GPIO_WAKEUP -+ device_disable_async_suspend(sdiodev->dev); -+ -+ return 0; -+fail: -+ aicwf_sdio_func_deinit(sdiodev); -+ dev_set_drvdata(&func->dev, NULL); -+ kfree(sdiodev); -+ kfree(bus_if); -+ aicwf_hostif_fail(); -+ return err; -+} -+ -+void aicwf_sdio_probe_(struct sdio_func *func, -+ const struct sdio_device_id *id){ -+ aicwf_sdio_probe(func, NULL); -+} -+ -+ -+static void aicwf_sdio_remove(struct sdio_func *func) -+{ -+ struct mmc_host *host; -+ struct aicwf_bus *bus_if = NULL; -+ struct aic_sdio_dev *sdiodev = NULL; -+ -+ AICWFDBG(LOGINFO, "%s Enter\n", __func__); -+ host = func->card->host; -+ host->caps &= ~MMC_CAP_NONREMOVABLE; -+ bus_if = dev_get_drvdata(&func->dev); -+ if (!bus_if) { -+ return; -+ } -+ -+ sdiodev = bus_if->bus_priv.sdio; -+ if (!sdiodev) { -+ return; -+ } -+ -+ sdiodev->bus_if->state = BUS_DOWN_ST; -+ aicwf_sdio_release(sdiodev); -+ aicwf_sdio_func_deinit(sdiodev); -+ rwnx_unregister_hostwake_irq(sdiodev->dev); -+ dev_set_drvdata(&sdiodev->func->dev, NULL); -+ kfree(sdiodev); -+ kfree(bus_if); -+#ifdef CONFIG_WIFI_SUSPEND_FOR_LINUX -+ rwnx_deinit_wifi_suspend_node(); -+#endif//CONFIG_WIFI_SUSPEND_FOR_LINUX -+ AICWFDBG(LOGINFO, "%s done\n", __func__); -+} -+ -+void aicwf_sdio_remove_(struct sdio_func *func){ -+ aicwf_sdio_remove(func); -+} -+ -+static int aicwf_sdio_suspend(struct device *dev) -+{ -+ int ret = 0; -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ mmc_pm_flag_t sdio_flags; -+ struct rwnx_vif *rwnx_vif, *tmp; -+ -+ sdio_dbg("%s enter\n", __func__); -+ -+ list_for_each_entry_safe(rwnx_vif, tmp, &sdiodev->rwnx_hw->vifs, list) { -+ if (rwnx_vif->ndev) -+ netif_device_detach(rwnx_vif->ndev); -+ } -+ -+ sdio_flags = sdio_get_host_pm_caps(sdiodev->func); -+ if (!(sdio_flags & MMC_PM_KEEP_POWER)) { -+ return -EINVAL; -+ } -+ ret = sdio_set_host_pm_flags(sdiodev->func, MMC_PM_KEEP_POWER); -+ if (ret) { -+ return ret; -+ } -+ -+ -+ while (sdiodev->state == SDIO_ACTIVE_ST) { -+ if (down_interruptible(&sdiodev->tx_priv->txctl_sema)) -+ continue; -+ #if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwr_stctl(sdiodev, SDIO_SLEEP_ST); -+ #endif -+ up(&sdiodev->tx_priv->txctl_sema); -+ break; -+ } -+#ifdef CONFIG_GPIO_WAKEUP -+// rwnx_enable_hostwake_irq(); -+#endif -+ -+ -+#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2) -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801){ -+ sdio_dbg("%s SDIOWIFI_INTR_CONFIG_REG Disable\n", __func__); -+ sdio_claim_host(sdiodev->func); -+ //disable sdio interrupt -+ ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x0); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG); -+ } -+ sdio_release_irq(sdiodev->func); -+ sdio_release_host(sdiodev->func); -+ } -+#endif -+ atomic_set(&sdiodev->is_bus_suspend, 1); -+// smp_mb(); -+ -+ sdio_dbg("%s exit\n", __func__); -+ -+ return 0; -+} -+ -+static int aicwf_sdio_resume(struct device *dev) -+{ -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ struct rwnx_vif *rwnx_vif, *tmp; -+#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2) -+ int ret; -+#endif -+ -+ sdio_dbg("%s enter \n", __func__); -+//#ifdef CONFIG_GPIO_WAKEUP -+// rwnx_disable_hostwake_irq(); -+//#endif -+ //dev_pm_clear_wake_irq(dev); -+ list_for_each_entry_safe(rwnx_vif, tmp, &sdiodev->rwnx_hw->vifs, list) { -+ if (rwnx_vif->ndev) -+ netif_device_attach(rwnx_vif->ndev); -+ } -+ -+ #if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwr_stctl(sdiodev, SDIO_ACTIVE_ST); -+ #endif -+ -+// aicwf_sdio_hal_irqhandler(sdiodev->func); -+ -+#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2) -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801){ -+ sdio_dbg("%s SDIOWIFI_INTR_CONFIG_REG Enable\n", __func__); -+ sdio_claim_host(sdiodev->func); -+ sdio_claim_irq(sdiodev->func, aicwf_sdio_hal_irqhandler); -+ -+ //enable sdio interrupt -+ ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x07); -+ if (ret != 0) -+ sdio_err("intr register failed:%d\n", ret); -+ sdio_release_host(sdiodev->func); -+ } -+#endif -+ atomic_set(&sdiodev->is_bus_suspend, 0); -+// smp_mb(); -+ #ifdef CONFIG_WIFI_SUSPEND_FOR_LINUX -+ rwnx_set_wifi_suspend('0'); -+ #endif//CONFIG_WIFI_SUSPEND_FOR_LINUX -+ -+ -+ sdio_dbg("%s exit\n", __func__); -+ return 0; -+} -+ -+static const struct sdio_device_id aicwf_sdmmc_ids[] = { -+ {SDIO_DEVICE(SDIO_VENDOR_ID_AIC8801, SDIO_DEVICE_ID_AIC8801)}, -+ {SDIO_DEVICE(SDIO_VENDOR_ID_AIC8800DC, SDIO_DEVICE_ID_AIC8800DC)}, -+ {SDIO_DEVICE(SDIO_VENDOR_ID_AIC8800D80, SDIO_DEVICE_ID_AIC8800D80)}, -+ { }, -+}; -+ -+MODULE_DEVICE_TABLE(sdio, aicwf_sdmmc_ids); -+ -+static const struct dev_pm_ops aicwf_sdio_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(aicwf_sdio_suspend, aicwf_sdio_resume) -+}; -+ -+#ifndef CONFIG_FDRV_NO_REG_SDIO -+static struct sdio_driver aicwf_sdio_driver = { -+ .probe = aicwf_sdio_probe, -+ .remove = aicwf_sdio_remove, -+ .name = AICWF_SDIO_NAME, -+ .id_table = aicwf_sdmmc_ids, -+ .drv = { -+ .pm = &aicwf_sdio_pm_ops, -+ }, -+}; -+#endif -+ -+#if 0 -+#ifdef CONFIG_NANOPI_M4 -+extern int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq); -+extern unsigned aic_max_freqs; -+extern struct mmc_host *aic_host_drv; -+extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort); -+extern void mmc_release_host(struct mmc_host *host); -+#endif -+#endif -+ -+#ifdef CONFIG_FDRV_NO_REG_SDIO -+extern struct sdio_func *get_sdio_func(void); -+void aicwf_sdio_probe_(struct sdio_func *func, const struct sdio_device_id *id); -+void aicwf_sdio_remove_(struct sdio_func *func); -+#endif -+ -+void aicwf_sdio_register(void) -+{ -+#if 0 -+#ifdef CONFIG_PLATFORM_NANOPI -+ extern_wifi_set_enable(0); -+ mdelay(200); -+ extern_wifi_set_enable(1); -+ mdelay(200); -+ sdio_reinit(); -+#endif /*CONFIG_PLATFORM_NANOPI*/ -+ -+#ifdef CONFIG_PLATFORM_ROCKCHIP -+ rockchip_wifi_power(0); -+ mdelay(200); -+ rockchip_wifi_power(1); -+ mdelay(200); -+ rockchip_wifi_set_carddetect(1); -+#endif /*CONFIG_PLATFORM_ROCKCHIP*/ -+ -+#ifdef CONFIG_INGENIC_T20 -+ jzmmc_manual_detect(1, 1); -+#endif /* CONFIG_INGENIC_T20 */ -+ -+ -+#ifdef CONFIG_NANOPI_M4 -+ if (aic_host_drv->card == NULL) { -+ __mmc_claim_host(aic_host_drv, NULL); -+ printk("aic: >>>mmc_rescan_try_freq\n"); -+ mmc_rescan_try_freq(aic_host_drv, aic_max_freqs); -+ mmc_release_host(aic_host_drv); -+ } -+#endif -+#endif -+ -+ -+#ifndef CONFIG_FDRV_NO_REG_SDIO -+ if (sdio_register_driver(&aicwf_sdio_driver)) { -+ -+ } else { -+ //may add mmc_rescan here -+ } -+#else -+ aicwf_sdio_probe_(get_sdio_func(), NULL); -+#endif -+} -+ -+void aicwf_sdio_exit(void) -+{ -+ if (g_rwnx_plat && g_rwnx_plat->enabled){ -+ rwnx_platform_deinit(g_rwnx_plat->sdiodev->rwnx_hw); -+ }else{ -+ AICWFDBG(LOGERROR, "%s g_rwnx_plat is not ready \r\n", __func__); -+ } -+ -+ udelay(500); -+ -+#ifndef CONFIG_FDRV_NO_REG_SDIO -+ sdio_unregister_driver(&aicwf_sdio_driver); -+#else -+ aicwf_sdio_remove_(get_sdio_func()); -+#endif -+ -+#if 0 -+#ifdef CONFIG_PLATFORM_AMLOGIC -+ extern_wifi_set_enable(0); -+#endif /*CONFIG_PLATFORM_AMLOGIC*/ -+#endif -+ -+#if 0 -+#ifdef CONFIG_PLATFORM_ROCKCHIP -+ rockchip_wifi_set_carddetect(0); -+ mdelay(200); -+ rockchip_wifi_power(0); -+ mdelay(200); -+#endif /*CONFIG_PLATFORM_ROCKCHIP*/ -+#endif -+ -+ if(g_rwnx_plat){ -+ kfree(g_rwnx_plat); -+ } -+} -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+int aicwf_sdio_wakeup(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ int read_retry; -+ int write_retry = 20; -+ int wakeup_reg_val = 0; -+ -+ if (sdiodev->chipid == PRODUCT_ID_AIC8801 || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ wakeup_reg_val = 1; -+ } else if (sdiodev->chipid == PRODUCT_ID_AIC8800D80) { -+ wakeup_reg_val = 0x11; -+ } -+ -+ if (sdiodev->state == SDIO_SLEEP_ST) { -+ AICWFDBG(LOGSDPWRC, "%s w\n", __func__); -+ -+ //rwnx_pm_stay_awake(sdiodev); -+ -+ while (write_retry) { -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.wakeup_reg, wakeup_reg_val); -+ if (ret) { -+ txrx_err("sdio wakeup fail\n"); -+ ret = -1; -+ } else { -+ read_retry = 10; -+ while (read_retry) { -+ u8 val; -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.sleep_reg, &val); -+ if (ret < 0) -+ txrx_err("sdio wakeup read fail\n"); -+ else if (val & 0x10) { -+ break; -+ } -+ read_retry--; -+ udelay(200); -+ } -+ if (read_retry != 0) -+ break; -+ } -+ sdio_dbg("write retry: %d \n", write_retry); -+ write_retry--; -+ udelay(100); -+ } -+ -+ sdiodev->state = SDIO_ACTIVE_ST; -+ aicwf_sdio_pwrctl_timer(sdiodev, sdiodev->active_duration); -+ } -+ return ret; -+} -+ -+int aicwf_sdio_sleep_allow(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ struct aicwf_bus *bus_if = sdiodev->bus_if; -+ struct rwnx_hw *rwnx_hw = sdiodev->rwnx_hw; -+ -+ if (bus_if->state == BUS_DOWN_ST) { -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.sleep_reg, 0x10); -+ if (ret) { -+ sdio_err("Write sleep fail!\n"); -+ } -+ aicwf_sdio_pwrctl_timer(sdiodev, 0); -+ return ret; -+ } -+ -+ sdio_info("sleep: %d, %d\n", sdiodev->state, scanning); -+ if (sdiodev->state == SDIO_ACTIVE_ST && !scanning && !rwnx_hw->is_p2p_alive \ -+ && !rwnx_hw->is_p2p_connected) { -+ AICWFDBG(LOGSDPWRC, "%s s\n", __func__); -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.sleep_reg, 0x10); -+ if (ret) -+ sdio_err("Write sleep fail!\n"); -+ sdiodev->state = SDIO_SLEEP_ST; -+ aicwf_sdio_pwrctl_timer(sdiodev, 0); -+ //rwnx_pm_relax(sdiodev); -+ } else { -+ aicwf_sdio_pwrctl_timer(sdiodev, sdiodev->active_duration); -+ } -+ -+ return ret; -+} -+ -+int aicwf_sdio_pwr_stctl(struct aic_sdio_dev *sdiodev, uint target) -+{ -+ int ret = 0; -+ -+ if (sdiodev->bus_if->state == BUS_DOWN_ST) { -+ return -1; -+ } -+ -+ down(&sdiodev->pwrctl_wakeup_sema); -+ -+ if (sdiodev->state == target) { -+ if (target == SDIO_ACTIVE_ST) { -+ aicwf_sdio_pwrctl_timer(sdiodev, sdiodev->active_duration); -+ } -+ up(&sdiodev->pwrctl_wakeup_sema); -+ return ret; -+ } -+ -+ switch (target) { -+ case SDIO_ACTIVE_ST: -+ aicwf_sdio_wakeup(sdiodev); -+ break; -+ case SDIO_SLEEP_ST: -+ aicwf_sdio_sleep_allow(sdiodev); -+ break; -+ } -+ -+ up(&sdiodev->pwrctl_wakeup_sema); -+ return ret; -+} -+#endif -+ -+#if 0 -+int align_param = 16; -+module_param(align_param, int, 0660); -+#endif -+ -+int aicwf_sdio_txpkt(struct aic_sdio_dev *sdiodev, struct sk_buff *pkt) -+{ -+ int ret = 0; -+ u8 *frame; -+ u32 len = 0; -+ struct aicwf_bus *bus_if = dev_get_drvdata(sdiodev->dev); -+#if 0 -+ int align = 0; -+#endif -+ if (bus_if->state == BUS_DOWN_ST) { -+ sdio_dbg("tx bus is down!\n"); -+ return -EINVAL; -+ } -+ -+#if 0 -+ len = pkt->len; -+ len = (len + SDIOWIFI_FUNC_BLOCKSIZE - 1) / SDIOWIFI_FUNC_BLOCKSIZE * SDIOWIFI_FUNC_BLOCKSIZE; -+ -+ frame = (u8*)kmalloc(sizeof(u8) * len + align_param, GFP_ATOMIC); -+ align = ((unsigned long)(frame)) & (align_param - 1); -+ memcpy(frame + (align_param - align), (u8 *) (pkt->data), len); -+ -+ ret = aicwf_sdio_send_pkt(sdiodev, frame + (align_param - align), len); -+ if (ret) -+ sdio_err("aicwf_sdio_send_pkt fail%d\n", ret); -+ -+ kfree(frame); -+#endif -+#if 1 -+ frame = (u8 *) (pkt->data); -+ len = pkt->len; -+ len = (len + SDIOWIFI_FUNC_BLOCKSIZE - 1) / SDIOWIFI_FUNC_BLOCKSIZE * SDIOWIFI_FUNC_BLOCKSIZE; -+ -+ ret = aicwf_sdio_send_pkt(sdiodev, pkt->data, len); -+ if (ret) -+ sdio_err("aicwf_sdio_send_pkt fail%d\n", ret); -+#endif -+ return ret; -+} -+ -+static int aicwf_sdio_intr_get_len_bytemode(struct aic_sdio_dev *sdiodev, u8 *byte_len) -+{ -+ int ret = 0; -+ -+ if (!byte_len) -+ return -EBADE; -+ -+ if (sdiodev->bus_if->state == BUS_DOWN_ST) { -+ *byte_len = 0; -+ } else { -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.bytemode_len_reg, byte_len); -+ sdiodev->rx_priv->data_len = (*byte_len)*4; -+ } -+ -+ return ret; -+} -+ -+static void aicwf_sdio_bus_stop(struct device *dev) -+{ -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ int ret = 0; -+ -+ #if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwrctl_timer(sdiodev, 0); -+ #endif -+ AICWFDBG(LOGINFO, "%s Enter\n", __func__); -+ -+ bus_if->state = BUS_DOWN_ST; -+ if (sdiodev->tx_priv) { -+ ret = down_interruptible(&sdiodev->tx_priv->txctl_sema); -+ if (ret) -+ AICWFDBG(LOGERROR, "down txctl_sema fail\n"); -+ } -+ -+ #if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwr_stctl(sdiodev, SDIO_SLEEP_ST); -+ #endif -+ -+ if (sdiodev->tx_priv) { -+ if (!ret) -+ up(&sdiodev->tx_priv->txctl_sema); -+ aicwf_frame_queue_flush(&sdiodev->tx_priv->txq); -+ } -+ AICWFDBG(LOGINFO, "%s Exit \n", __func__); -+} -+ -+#ifdef CONFIG_PREALLOC_RX_SKB -+struct rx_buff *aicwf_sdio_readframes(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ u32 size = 0; -+ struct aicwf_bus *bus_if = dev_get_drvdata(sdiodev->dev); -+ struct rx_buff* rxbuff; -+ -+ if (bus_if->state == BUS_DOWN_ST) { -+ sdio_dbg("bus down\n"); -+ return NULL; -+ } -+ -+ size = sdiodev->rx_priv->data_len; -+ rxbuff = aicwf_prealloc_rxbuff_alloc(&sdiodev->rx_priv->rxbuff_lock); -+ if (rxbuff == NULL) { -+ printk("failed to alloc rxbuff\n"); -+ return NULL; -+ } -+ rxbuff->len = 0; -+ rxbuff->start = rxbuff->data; -+ rxbuff->read = rxbuff->start; -+ rxbuff->end = rxbuff->data + size; -+ -+ ret = aicwf_sdio_recv_pkt(sdiodev, rxbuff, size); -+ if (ret) { -+ printk("%s %d, sdio recv pkt fail\n", __func__, __LINE__); -+ aicwf_prealloc_rxbuff_free(rxbuff, &sdiodev->rx_priv->rxbuff_lock); -+ return NULL; -+ } -+ -+ return rxbuff; -+} -+#else -+struct sk_buff *aicwf_sdio_readframes(struct aic_sdio_dev *sdiodev) -+{ -+ int ret = 0; -+ u32 size = 0; -+ struct sk_buff *skb = NULL; -+ struct aicwf_bus *bus_if = dev_get_drvdata(sdiodev->dev); -+ -+ if (bus_if->state == BUS_DOWN_ST) { -+ sdio_dbg("bus down\n"); -+ return NULL; -+ } -+ -+ size = sdiodev->rx_priv->data_len; -+ skb = __dev_alloc_skb(size, GFP_KERNEL); -+ if (!skb) { -+ return NULL; -+ } -+ -+ ret = aicwf_sdio_recv_pkt(sdiodev, skb, size); -+ if (ret) { -+ dev_kfree_skb(skb); -+ skb = NULL; -+ } -+ -+ return skb; -+} -+#endif -+ -+static int aicwf_sdio_tx_msg(struct aic_sdio_dev *sdiodev) -+{ -+ int err = 0; -+ u16 len; -+ u8 *payload = sdiodev->tx_priv->cmd_buf; -+ u16 payload_len = sdiodev->tx_priv->cmd_len; -+ u8 adjust_str[4] = {0, 0, 0, 0}; -+ int adjust_len = 0; -+ int buffer_cnt = 0; -+ u8 retry = 0; -+ -+ len = payload_len; -+ if ((len % TX_ALIGNMENT) != 0) { -+ adjust_len = roundup(len, TX_ALIGNMENT); -+ memcpy(payload+payload_len, adjust_str, (adjust_len - len)); -+ payload_len += (adjust_len - len); -+ } -+ len = payload_len; -+ -+ //link tail is necessary -+ if ((len % SDIOWIFI_FUNC_BLOCKSIZE) != 0) { -+ memset(payload+payload_len, 0, TAIL_LEN); -+ payload_len += TAIL_LEN; -+ len = (payload_len/SDIOWIFI_FUNC_BLOCKSIZE + 1) * SDIOWIFI_FUNC_BLOCKSIZE; -+ } else -+ len = payload_len; -+ -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ buffer_cnt = aicwf_sdio_flow_ctrl_msg(sdiodev); -+ while ((buffer_cnt <= 0 || (buffer_cnt > 0 && len > (buffer_cnt * BUFFER_SIZE))) && retry < 10) { -+ retry++; -+ buffer_cnt = aicwf_sdio_flow_ctrl_msg(sdiodev); -+ printk("buffer_cnt = %d\n", buffer_cnt); -+ } -+ } -+ down(&sdiodev->tx_priv->cmd_txsema); -+ -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ if (buffer_cnt > 0 && len < (buffer_cnt * BUFFER_SIZE)) { -+ err = aicwf_sdio_send_pkt(sdiodev, payload, len); -+ if (err) { -+ sdio_err("aicwf_sdio_send_pkt fail%d\n", err); -+ } -+ } else { -+ sdio_err("tx msg fc retry fail:%d, %d\n", buffer_cnt, len); -+ up(&sdiodev->tx_priv->cmd_txsema); -+ return -1; -+ } -+ }else if(sdiodev->chipid == PRODUCT_ID_AIC8800DC){ -+ err = aicwf_sdio_send_pkt(sdiodev, payload, len); -+ if (err) { -+ sdio_err("aicwf_sdio_send_pkt fail%d\n", err); -+ } -+ } else { -+ sdio_err("tx msg fc retry fail:%d, %d\n", buffer_cnt, len); -+ up(&sdiodev->tx_priv->cmd_txsema); -+ return -1; -+ } -+ -+ sdiodev->tx_priv->cmd_txstate = false; -+ if (!err) -+ sdiodev->tx_priv->cmd_tx_succ = true; -+ else -+ sdiodev->tx_priv->cmd_tx_succ = false; -+ -+ up(&sdiodev->tx_priv->cmd_txsema); -+ -+ return err; -+ -+} -+ -+static void aicwf_sdio_tx_process(struct aic_sdio_dev *sdiodev) -+{ -+ int err = 0; -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+ unsigned long flags; -+#endif -+ -+ if (sdiodev->bus_if->state == BUS_DOWN_ST) { -+ sdio_err("Bus is down\n"); -+ return; -+ } -+ -+ #if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwr_stctl(sdiodev, SDIO_ACTIVE_ST); -+ #endif -+ -+ //config -+ sdio_info("send cmd\n"); -+ if (sdiodev->tx_priv->cmd_txstate) { -+ if (down_interruptible(&sdiodev->tx_priv->txctl_sema)) { -+ txrx_err("txctl down bus->txctl_sema fail\n"); -+ return; -+ } -+ if (sdiodev->state != SDIO_ACTIVE_ST) { -+ txrx_err("state err\n"); -+ up(&sdiodev->tx_priv->txctl_sema); -+ txrx_err("txctl up bus->txctl_sema fail\n"); -+ return; -+ } -+ -+ err = aicwf_sdio_tx_msg(sdiodev); -+ up(&sdiodev->tx_priv->txctl_sema); -+ if (waitqueue_active(&sdiodev->tx_priv->cmd_txdone_wait)) -+ wake_up(&sdiodev->tx_priv->cmd_txdone_wait); -+ } -+ -+ //data -+ sdio_info("send data\n"); -+ if (down_interruptible(&sdiodev->tx_priv->txctl_sema)) { -+ txrx_err("txdata down bus->txctl_sema\n"); -+ return; -+ } -+ -+ if (sdiodev->state != SDIO_ACTIVE_ST) { -+ txrx_err("sdio state err\n"); -+ up(&sdiodev->tx_priv->txctl_sema); -+ return; -+ } -+ -+ if (!aicwf_is_framequeue_empty(&sdiodev->tx_priv->txq)){ -+ sdiodev->tx_priv->fw_avail_bufcnt = aicwf_sdio_flow_ctrl(sdiodev); -+ } -+ while (!aicwf_is_framequeue_empty(&sdiodev->tx_priv->txq)) { -+ if(sdiodev->bus_if->state == BUS_DOWN_ST) { -+ break; -+ } -+ if (sdiodev->tx_priv->fw_avail_bufcnt <= DATA_FLOW_CTRL_THRESH) { -+ if (sdiodev->tx_priv->cmd_txstate) -+ break; -+ sdiodev->tx_priv->fw_avail_bufcnt = aicwf_sdio_flow_ctrl(sdiodev); -+ } else { -+ if (sdiodev->tx_priv->cmd_txstate) { -+ aicwf_sdio_send(sdiodev->tx_priv, 1); -+ break; -+ } else { -+ aicwf_sdio_send(sdiodev->tx_priv, 0); -+ } -+ } -+ } -+ -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+ spin_lock_irqsave(&sdiodev->tx_flow_lock, flags); -+ if (atomic_read(&sdiodev->tx_priv->tx_pktcnt) < tx_fc_low_water) { -+ //printk("sdiodev->tx_priv->tx_pktcnt < tx_fc_low_water:%d %d\r\n", -+ // atomic_read(&sdiodev->tx_priv->tx_pktcnt), tx_fc_low_water); -+ if (sdiodev->flowctrl) { -+ sdiodev->flowctrl = 0; -+ aicwf_sdio_tx_netif_flowctrl(sdiodev->rwnx_hw, false); -+ } -+ } -+ spin_unlock_irqrestore(&sdiodev->tx_flow_lock, flags); -+#endif -+ -+ up(&sdiodev->tx_priv->txctl_sema); -+} -+ -+static int aicwf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) -+{ -+ uint prio; -+ int ret = -EBADE; -+ struct rwnx_txhdr *txhdr = NULL; -+ int headroom = 0; -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+ unsigned long flags; -+#endif -+ -+ if (bus_if->state == BUS_DOWN_ST) { -+ sdio_err("bus_if stopped\n"); -+ txhdr = (struct rwnx_txhdr *)pkt->data; -+ headroom = txhdr->sw_hdr->headroom; -+ kmem_cache_free(txhdr->sw_hdr->rwnx_vif->rwnx_hw->sw_txhdr_cache, txhdr->sw_hdr); -+ skb_pull(pkt, headroom); -+ consume_skb(pkt); -+ return -1; -+ } -+ -+ prio = (pkt->priority & 0x7); -+ spin_lock_bh(&sdiodev->tx_priv->txqlock); -+ if (!aicwf_frame_enq(sdiodev->dev, &sdiodev->tx_priv->txq, pkt, prio)) { -+ txhdr = (struct rwnx_txhdr *)pkt->data; -+ headroom = txhdr->sw_hdr->headroom; -+ kmem_cache_free(txhdr->sw_hdr->rwnx_vif->rwnx_hw->sw_txhdr_cache, txhdr->sw_hdr); -+ skb_pull(pkt, headroom); -+ consume_skb(pkt); -+ spin_unlock_bh(&sdiodev->tx_priv->txqlock); -+ return -ENOSR; -+ goto flowctrl; -+ } else { -+ ret = 0; -+ } -+ -+ atomic_inc(&sdiodev->tx_priv->tx_pktcnt); -+ spin_unlock_bh(&sdiodev->tx_priv->txqlock); -+ complete(&bus_if->bustx_trgg); -+ -+ flowctrl: -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+ spin_lock_irqsave(&sdiodev->tx_flow_lock, flags); -+ if (atomic_read(&sdiodev->tx_priv->tx_pktcnt) >= tx_fc_high_water) { -+ //printk("sdiodev->tx_priv->tx_pktcnt >= tx_fc_high_water:%d %d\r\n", -+ // atomic_read(&sdiodev->tx_priv->tx_pktcnt), tx_fc_high_water); -+ if (!sdiodev->flowctrl) { -+ sdiodev->flowctrl = 1; -+ aicwf_sdio_tx_netif_flowctrl(sdiodev->rwnx_hw, true); -+ } -+ } -+ spin_unlock_irqrestore(&sdiodev->tx_flow_lock, flags); -+#endif -+ -+ return ret; -+} -+ -+static int aicwf_sdio_bus_txmsg(struct device *dev, u8 *msg, uint msglen) -+{ -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ -+ down(&sdiodev->tx_priv->cmd_txsema); -+ sdiodev->tx_priv->cmd_txstate = true; -+ sdiodev->tx_priv->cmd_tx_succ = false; -+ sdiodev->tx_priv->cmd_buf = msg; -+ sdiodev->tx_priv->cmd_len = msglen; -+ up(&sdiodev->tx_priv->cmd_txsema); -+ -+ if (bus_if->state != BUS_UP_ST) { -+ sdio_err("bus has stop\n"); -+ return -1; -+ } -+ -+ complete(&bus_if->bustx_trgg); -+#if 0 -+ if (sdiodev->tx_priv->cmd_txstate) { -+ int timeout = msecs_to_jiffies(CMD_TX_TIMEOUT); -+ ret = wait_event_interruptible_timeout(sdiodev->tx_priv->cmd_txdone_wait, \ -+ !(sdiodev->tx_priv->cmd_txstate), timeout); -+ } -+ -+ if (!sdiodev->tx_priv->cmd_txstate && sdiodev->tx_priv->cmd_tx_succ) { -+ ret = 0; -+ } else { -+ sdio_err("send faild:%d, %d,%x\n", sdiodev->tx_priv->cmd_txstate, sdiodev->tx_priv->cmd_tx_succ, ret); -+ ret = -EIO; -+ } -+#endif -+ return 0; -+} -+ -+ -+int aicwf_sdio_send(struct aicwf_tx_priv *tx_priv, u8 txnow) -+{ -+ struct sk_buff *pkt; -+ struct aic_sdio_dev *sdiodev = tx_priv->sdiodev; -+ u32 aggr_len = 0; -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+ unsigned long flags; -+#endif -+ -+ aggr_len = (tx_priv->tail - tx_priv->head); -+ if (((atomic_read(&tx_priv->aggr_count) == 0) && (aggr_len != 0)) -+ || ((atomic_read(&tx_priv->aggr_count) != 0) && (aggr_len == 0))) { -+ if (aggr_len > 0) -+ aicwf_sdio_aggrbuf_reset(tx_priv); -+ goto done; -+ } -+ -+ if (atomic_read(&tx_priv->aggr_count) == (tx_priv->fw_avail_bufcnt - DATA_FLOW_CTRL_THRESH)) { -+ if (atomic_read(&tx_priv->aggr_count) > 0) { -+ tx_priv->fw_avail_bufcnt -= atomic_read(&tx_priv->aggr_count); -+ aicwf_sdio_aggr_send(tx_priv); //send and check the next pkt; -+ } -+ } else { -+ spin_lock_bh(&sdiodev->tx_priv->txqlock); -+ pkt = aicwf_frame_dequeue(&sdiodev->tx_priv->txq); -+ if (pkt == NULL) { -+ sdio_err("txq no pkt\n"); -+ spin_unlock_bh(&sdiodev->tx_priv->txqlock); -+ goto done; -+ } -+ atomic_dec(&sdiodev->tx_priv->tx_pktcnt); -+ spin_unlock_bh(&sdiodev->tx_priv->txqlock); -+ -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+ spin_lock_irqsave(&sdiodev->tx_flow_lock, flags); -+ if (atomic_read(&sdiodev->tx_priv->tx_pktcnt) < tx_fc_low_water) { -+ //printk("sdiodev->tx_priv->tx_pktcnt < tx_fc_low_water:%d %d\r\n", -+ // atomic_read(&sdiodev->tx_priv->tx_pktcnt), tx_fc_low_water); -+ if (sdiodev->flowctrl) { -+ sdiodev->flowctrl = 0; -+ aicwf_sdio_tx_netif_flowctrl(sdiodev->rwnx_hw, false); -+ } -+ } -+ spin_unlock_irqrestore(&sdiodev->tx_flow_lock, flags); -+#endif -+ -+ if (tx_priv == NULL || tx_priv->tail == NULL || pkt == NULL) -+ txrx_err("null error\n"); -+ if (aicwf_sdio_aggr(tx_priv, pkt)) { -+ aicwf_sdio_aggrbuf_reset(tx_priv); -+ sdio_err("add aggr pkts failed!\n"); -+ goto done; -+ } -+ -+ //when aggr finish or there is cmd to send, just send this aggr pkt to fw -+ if ((int)atomic_read(&sdiodev->tx_priv->tx_pktcnt) == 0 || txnow || (atomic_read(&tx_priv->aggr_count) == (tx_priv->fw_avail_bufcnt - DATA_FLOW_CTRL_THRESH))) { -+ tx_priv->fw_avail_bufcnt -= atomic_read(&tx_priv->aggr_count); -+ aicwf_sdio_aggr_send(tx_priv); -+ } else -+ goto done; -+ } -+ -+done: -+ return 0; -+} -+ -+int aicwf_sdio_aggr(struct aicwf_tx_priv *tx_priv, struct sk_buff *pkt) -+{ -+ struct rwnx_txhdr *txhdr = (struct rwnx_txhdr *)pkt->data; -+ u8 *start_ptr = tx_priv->tail; -+ u8 sdio_header[4]; -+ u8 adjust_str[4] = {0, 0, 0, 0}; -+ u32 curr_len = 0; -+ int allign_len = 0; -+ int headroom; -+ -+ sdio_header[0] = ((pkt->len - txhdr->sw_hdr->headroom + sizeof(struct txdesc_api)) & 0xff); -+ sdio_header[1] = (((pkt->len - txhdr->sw_hdr->headroom + sizeof(struct txdesc_api)) >> 8)&0x0f); -+ sdio_header[2] = 0x01; //data -+ if (tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8801 || -+ tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8800DW) -+ sdio_header[3] = 0; //reserved -+ else if (tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8800D80) -+ sdio_header[3] = crc8_ponl_107(&sdio_header[0], 3); // crc8 -+ -+ memcpy(tx_priv->tail, (u8 *)&sdio_header, sizeof(sdio_header)); -+ tx_priv->tail += sizeof(sdio_header); -+ //payload -+ memcpy(tx_priv->tail, (u8 *)(long)&txhdr->sw_hdr->desc, sizeof(struct txdesc_api)); -+ tx_priv->tail += sizeof(struct txdesc_api); //hostdesc -+ memcpy(tx_priv->tail, (u8 *)((u8 *)txhdr + txhdr->sw_hdr->headroom), pkt->len-txhdr->sw_hdr->headroom); -+ tx_priv->tail += (pkt->len - txhdr->sw_hdr->headroom); -+ -+ //word alignment -+ curr_len = tx_priv->tail - tx_priv->head; -+ if (curr_len & (TX_ALIGNMENT - 1)) { -+ allign_len = roundup(curr_len, TX_ALIGNMENT)-curr_len; -+ memcpy(tx_priv->tail, adjust_str, allign_len); -+ tx_priv->tail += allign_len; -+ } -+ -+ if (tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8801 || tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ tx_priv->sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ start_ptr[0] = ((tx_priv->tail - start_ptr - 4) & 0xff); -+ start_ptr[1] = (((tx_priv->tail - start_ptr - 4)>>8) & 0x0f); -+ } -+ tx_priv->aggr_buf->dev = pkt->dev; -+ -+ if (!txhdr->sw_hdr->need_cfm) { -+ headroom = txhdr->sw_hdr->headroom; -+ kmem_cache_free(txhdr->sw_hdr->rwnx_vif->rwnx_hw->sw_txhdr_cache, txhdr->sw_hdr); -+ skb_pull(pkt, headroom); -+ consume_skb(pkt); -+ } -+ -+ atomic_inc(&tx_priv->aggr_count); -+ return 0; -+} -+ -+void aicwf_sdio_aggr_send(struct aicwf_tx_priv *tx_priv) -+{ -+ struct sk_buff *tx_buf = tx_priv->aggr_buf; -+ int ret = 0; -+ int curr_len = 0; -+ -+ //link tail is necessary -+ curr_len = tx_priv->tail - tx_priv->head; -+ if ((curr_len % TXPKT_BLOCKSIZE) != 0) { -+ memset(tx_priv->tail, 0, TAIL_LEN); -+ tx_priv->tail += TAIL_LEN; -+ } -+ -+ tx_buf->len = tx_priv->tail - tx_priv->head; -+ ret = aicwf_sdio_txpkt(tx_priv->sdiodev, tx_buf); -+ if (ret < 0) { -+ sdio_err("fail to send aggr pkt!\n"); -+ } -+ -+ aicwf_sdio_aggrbuf_reset(tx_priv); -+} -+ -+void aicwf_sdio_aggrbuf_reset(struct aicwf_tx_priv *tx_priv) -+{ -+ struct sk_buff *aggr_buf = tx_priv->aggr_buf; -+ -+ tx_priv->tail = tx_priv->head; -+ aggr_buf->len = 0; -+ atomic_set(&tx_priv->aggr_count, 0); -+} -+ -+extern void set_irq_handler(void *fn); -+ -+static int aicwf_sdio_bus_start(struct device *dev) -+{ -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ int ret = 0; -+ -+ -+ sdio_claim_host(sdiodev->func); -+#ifndef CONFIG_FDRV_NO_REG_SDIO -+ sdio_claim_irq(sdiodev->func, aicwf_sdio_hal_irqhandler); -+#else -+ set_irq_handler(aicwf_sdio_hal_irqhandler); -+#endif -+ if(sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ sdio_f0_writeb(sdiodev->func, 0x07, 0x04, &ret); -+ if (ret) { -+ sdio_err("set func0 int en fail %d\n", ret); -+ } -+ } -+ sdio_release_host(sdiodev->func); -+ -+ -+ //enable sdio interrupt -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x07); -+ if (ret != 0) -+ sdio_err("intr register failed:%d\n", ret); -+ -+ bus_if->state = BUS_UP_ST; -+ -+ return ret; -+} -+ -+#ifdef CONFIG_TXRX_THREAD_PRIO -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) -+#include "uapi/linux/sched/types.h" -+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) -+#include "linux/sched/types.h" -+#else -+#include "linux/sched/rt.h" -+#endif -+ -+int bustx_thread_prio = 1; -+module_param_named(bustx_thread_prio, bustx_thread_prio, int, 0644); -+//module_param(bustx_thread_prio, int, 0); -+int busrx_thread_prio = 1; -+module_param_named(busrx_thread_prio, busrx_thread_prio, int, 0644); -+//module_param(busrx_thread_prio, int, 0); -+#endif -+ -+#ifdef CONFIG_OOB -+int rx_thread_wait_to = 1000; -+module_param_named(rx_thread_wait_to, rx_thread_wait_to, int, 0644); -+ -+//new oob feature -+int sdio_busirq_thread(void *data){ -+ struct aicwf_rx_priv *rx_priv = (struct aicwf_rx_priv *)data; -+ struct aicwf_bus *bus_if = rx_priv->sdiodev->bus_if; -+#if 0 -+#ifdef CONFIG_THREAD_INFO_IN_TASK -+ int set_cpu_ret = 0; -+ -+ AICWFDBG(LOGINFO, "%s the cpu is:%d\n", __func__, current->cpu); -+ set_cpu_ret = set_cpus_allowed_ptr(current, cpumask_of(0)); -+ AICWFDBG(LOGINFO, "%s set_cpu_ret is:%d\n", __func__, set_cpu_ret); -+ AICWFDBG(LOGINFO, "%s change cpu to:%d\n", __func__, current->cpu); -+#endif -+#endif -+ -+#ifdef CONFIG_TXRX_THREAD_PRIO -+ if (busrx_thread_prio > 0) { -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) -+ sched_set_fifo_low(current); -+#else -+ struct sched_param param; -+ param.sched_priority = (busrx_thread_prio - 1 < MAX_RT_PRIO)?busrx_thread_prio:(MAX_RT_PRIO-1); -+ sched_setscheduler(current, SCHED_FIFO, ¶m); -+#endif -+ } -+#endif -+ -+ AICWFDBG(LOGINFO, "%s the policy of current thread is:%d\n", __func__, current->policy); -+ AICWFDBG(LOGINFO, "%s the rt_priority of current thread is:%d\n", __func__, current->rt_priority); -+ AICWFDBG(LOGINFO, "%s the current pid is:%d\n", __func__, current->pid); -+ -+ -+ while (1) { -+ if (kthread_should_stop()) { -+ AICWFDBG(LOGERROR, "sdio busirq thread stop\n"); -+ break; -+ } -+ -+ if(!wait_for_completion_timeout(&bus_if->busirq_trgg, msecs_to_jiffies(rx_thread_wait_to))){ -+ AICWFDBG(LOGRXPOLL, "%s wait for completion timout \r\n", __func__); -+ } -+ -+ if (bus_if->state == BUS_DOWN_ST) -+ continue; -+#if 1 -+#ifdef CONFIG_SDIO_PWRCTRL -+ while(atomic_read(&bus_if->bus_priv.sdio->is_bus_suspend) == 1){ -+ AICWFDBG(LOGDEBUG, "%s waiting for sdio bus resume \r\n", __func__); -+ msleep(100); -+ } -+ aicwf_sdio_pwr_stctl(bus_if->bus_priv.sdio, SDIO_ACTIVE_ST); -+#endif//CONFIG_SDIO_PWRCTRL -+#endif -+ aicwf_sdio_hal_irqhandler(bus_if->bus_priv.sdio->func); -+ } -+ -+ return 0; -+} -+ -+#endif//CONFIG_OOB -+ -+#if 0 -+#include -+#endif -+int sdio_bustx_thread(void *data) -+{ -+ struct aicwf_bus *bus = (struct aicwf_bus *) data; -+ struct aic_sdio_dev *sdiodev = bus->bus_priv.sdio; -+#if 0 -+#ifdef CONFIG_THREAD_INFO_IN_TASK -+ int set_cpu_ret = 0; -+ -+ AICWFDBG(LOGINFO, "%s the cpu is:%d\n", __func__, current->cpu); -+ set_cpu_ret = set_cpus_allowed_ptr(current, cpumask_of(1)); -+ AICWFDBG(LOGINFO, "%s set_cpu_ret is:%d\n", __func__, set_cpu_ret); -+ AICWFDBG(LOGINFO, "%s change cpu to:%d\n", __func__, current->cpu); -+#endif -+#endif -+ -+#if 0 -+ struct cpumask cpumask; -+ cpumask_clear(&cpumask); -+ cpumask_set_cpu(1, &cpumask); -+ cpumask_set_cpu(2, &cpumask); -+ cpumask_set_cpu(3, &cpumask); -+ sched_setaffinity(0, &cpumask);//need to add EXPORT_SYMBOL_GPL(sched_setaffinity) in kernel/sched/core.c -+#endif -+#ifdef CONFIG_TXRX_THREAD_PRIO -+ if (bustx_thread_prio > 0) { -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) -+ sched_set_fifo_low(current); -+#else -+ struct sched_param param; -+ param.sched_priority = (bustx_thread_prio < MAX_RT_PRIO)?bustx_thread_prio:(MAX_RT_PRIO-1); -+ sched_setscheduler(current, SCHED_FIFO, ¶m); -+#endif -+ } -+#endif -+ -+ AICWFDBG(LOGINFO, "%s the policy of current thread is:%d\n", __func__, current->policy); -+ AICWFDBG(LOGINFO, "%s the rt_priority of current thread is:%d\n", __func__, current->rt_priority); -+ AICWFDBG(LOGINFO, "%s the current pid is:%d\n", __func__, current->pid); -+ -+ while (1) { -+ if (kthread_should_stop()) { -+ AICWFDBG(LOGERROR, "sdio bustx thread stop\n"); -+ break; -+ } -+ -+ if (!wait_for_completion_interruptible(&bus->bustx_trgg)) { -+ if (sdiodev->bus_if->state == BUS_DOWN_ST) -+ continue; -+ -+ rwnx_wakeup_lock(sdiodev->rwnx_hw->ws_tx); -+ if ((int)(atomic_read(&sdiodev->tx_priv->tx_pktcnt) > 0) || (sdiodev->tx_priv->cmd_txstate == true)){ -+ aicwf_sdio_tx_process(sdiodev); -+ } -+ rwnx_wakeup_unlock(sdiodev->rwnx_hw->ws_tx); -+ } -+ } -+ -+ return 0; -+} -+ -+#if 0//old oob feature -+int sdio_busrx_thread(void *data) -+{ -+ struct aicwf_rx_priv *rx_priv = (struct aicwf_rx_priv *)data; -+ struct aicwf_bus *bus_if = rx_priv->sdiodev->bus_if; -+#if 0 -+ struct cpumask cpumask; -+ cpumask_clear(&cpumask); -+ cpumask_set_cpu(1, &cpumask); -+ cpumask_set_cpu(2, &cpumask); -+ cpumask_set_cpu(3, &cpumask); -+ sched_setaffinity(0, &cpumask); -+#endif -+#ifdef CONFIG_TXRX_THREAD_PRIO -+ if (busrx_thread_prio > 0) { -+ struct sched_param param; -+ param.sched_priority = (busrx_thread_prio < MAX_RT_PRIO)?busrx_thread_prio:(MAX_RT_PRIO-1); -+ sched_setscheduler(current, SCHED_FIFO, ¶m); -+ } -+#endif -+ -+ AICWFDBG(LOGINFO, "%s the policy of current thread is:%d\n", __func__, current->policy); -+ AICWFDBG(LOGINFO, "%s the rt_priority of current thread is:%d\n", __func__, current->rt_priority); -+ AICWFDBG(LOGINFO, "%s the current pid is:%d\n", __func__, current->pid); -+ -+while (1) { -+ if (kthread_should_stop()) { -+ AICWFDBG(LOGERROR, "sdio busrx thread stop\n"); -+ break; -+ } -+#ifndef CONFIG_OOB -+ if (!wait_for_completion_interruptible(&bus_if->busrx_trgg)) { -+#else -+ if(!wait_for_completion_timeout(&bus_if->busrx_trgg, msecs_to_jiffies(rx_thread_wait_to))){ -+ AICWFDBG(LOGDEBUG, "%s wait for completion timout \r\n", __func__); -+ } -+#endif -+ if (bus_if->state == BUS_DOWN_ST) -+ continue; -+#ifdef CONFIG_OOB -+#ifdef CONFIG_SDIO_PWRCTRL -+ while(atomic_read(&bus_if->bus_priv.sdio->is_bus_suspend) == 1){ -+ AICWFDBG(LOGDEBUG, "%s waiting for sdio bus resume \r\n", __func__); -+ msleep(100); -+ } -+ aicwf_sdio_pwr_stctl(bus_if->bus_priv.sdio, SDIO_ACTIVE_ST); -+#endif//CONFIG_SDIO_PWRCTRL -+ aicwf_sdio_hal_irqhandler(bus_if->bus_priv.sdio->func); -+#endif//CONFIG_OOB -+ rwnx_wakeup_lock(rx_priv->sdiodev->rwnx_hw->ws_rx); -+ aicwf_process_rxframes(rx_priv); -+ rwnx_wakeup_unlock(rx_priv->sdiodev->rwnx_hw->ws_rx); -+#ifndef CONFIG_OOB -+ } -+#endif -+ } -+ -+ return 0; -+ -+} -+#else//new oob feature -+int sdio_busrx_thread(void *data) -+{ -+ struct aicwf_rx_priv *rx_priv = (struct aicwf_rx_priv *)data; -+ struct aicwf_bus *bus_if = rx_priv->sdiodev->bus_if; -+ -+ -+#if 0 -+ struct cpumask cpumask; -+ cpumask_clear(&cpumask); -+ cpumask_set_cpu(1, &cpumask); -+ cpumask_set_cpu(2, &cpumask); -+ cpumask_set_cpu(3, &cpumask); -+ sched_setaffinity(0, &cpumask); -+#endif -+#if 0 -+#ifdef CONFIG_THREAD_INFO_IN_TASK -+ int set_cpu_ret = 0; -+ -+ AICWFDBG(LOGINFO, "%s the cpu is:%d\n", __func__, current->cpu); -+ set_cpu_ret = set_cpus_allowed_ptr(current, cpumask_of(2)); -+ AICWFDBG(LOGINFO, "%s set_cpu_ret is:%d\n", __func__, set_cpu_ret); -+ AICWFDBG(LOGINFO, "%s change cpu to:%d\n", __func__, current->cpu); -+#endif -+#endif -+#ifdef CONFIG_TXRX_THREAD_PRIO -+ if (busrx_thread_prio > 0) { -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) -+ sched_set_fifo_low(current); -+#else -+ struct sched_param param; -+ param.sched_priority = (busrx_thread_prio < MAX_RT_PRIO)?busrx_thread_prio:(MAX_RT_PRIO-1); -+ sched_setscheduler(current, SCHED_FIFO, ¶m); -+#endif -+ } -+#endif -+ -+ AICWFDBG(LOGINFO, "%s the policy of current thread is:%d\n", __func__, current->policy); -+ AICWFDBG(LOGINFO, "%s the rt_priority of current thread is:%d\n", __func__, current->rt_priority); -+ AICWFDBG(LOGINFO, "%s the current pid is:%d\n", __func__, current->pid); -+ -+ while (1) { -+ if (kthread_should_stop()) { -+ AICWFDBG(LOGERROR, "sdio busrx thread stop\n"); -+ break; -+ } -+ if (!wait_for_completion_interruptible(&bus_if->busrx_trgg)) { -+ -+ if (bus_if->state == BUS_DOWN_ST) -+ continue; -+ rwnx_wakeup_lock(rx_priv->sdiodev->rwnx_hw->ws_rx); -+ aicwf_process_rxframes(rx_priv); -+ rwnx_wakeup_unlock(rx_priv->sdiodev->rwnx_hw->ws_rx); -+ } -+ } -+ return 0; -+ -+} -+ -+#endif//old oob feature -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+static int aicwf_sdio_pwrctl_thread(void *data) -+{ -+ struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data; -+ -+ while (1) { -+ if (kthread_should_stop()) { -+ sdio_err("sdio pwrctl thread stop\n"); -+ break; -+ } -+ if (!wait_for_completion_interruptible(&sdiodev->pwrctrl_trgg)) { -+ //printk("%s working\r\n", __func__); -+ -+ if (sdiodev->bus_if->state == BUS_DOWN_ST) -+ continue; -+ -+ rwnx_wakeup_lock(sdiodev->rwnx_hw->ws_pwrctrl); -+ -+ if ((int)(atomic_read(&sdiodev->tx_priv->tx_pktcnt) <= 0) && (sdiodev->tx_priv->cmd_txstate == false) && \ -+ atomic_read(&sdiodev->rx_priv->rx_cnt) == 0) -+ aicwf_sdio_pwr_stctl(sdiodev, SDIO_SLEEP_ST); -+ else -+ aicwf_sdio_pwrctl_timer(sdiodev, sdiodev->active_duration); -+ -+ rwnx_wakeup_unlock(sdiodev->rwnx_hw->ws_pwrctrl); -+ } -+ } -+ -+ return 0; -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+static void aicwf_sdio_bus_pwrctl(ulong data) -+#else -+static void aicwf_sdio_bus_pwrctl(struct timer_list *t) -+#endif -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+ struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data; -+#else -+ struct aic_sdio_dev *sdiodev = from_timer(sdiodev, t, timer); -+#endif -+ -+ if (sdiodev->bus_if->state == BUS_DOWN_ST) { -+ sdio_err("bus down\n"); -+ return; -+ } -+ -+ if (sdiodev->pwrctl_tsk) { -+ complete(&sdiodev->pwrctrl_trgg); -+ } -+} -+#endif -+ -+#ifdef CONFIG_PREALLOC_RX_SKB -+static void aicwf_sdio_enq_rxpkt(struct aic_sdio_dev *sdiodev, struct rx_buff *pkt) -+#else -+static void aicwf_sdio_enq_rxpkt(struct aic_sdio_dev *sdiodev, struct sk_buff *pkt) -+#endif -+{ -+ struct aicwf_rx_priv *rx_priv = sdiodev->rx_priv; -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&rx_priv->rxqlock, flags); -+ #ifdef CONFIG_PREALLOC_RX_SKB -+ if (!aicwf_rxbuff_enqueue(sdiodev->dev, &rx_priv->rxq, pkt)) { -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ printk("%s %d, enqueue rxq fail\n", __func__, __LINE__); -+ aicwf_prealloc_rxbuff_free(pkt, &rx_priv->rxbuff_lock); -+ return; -+ } -+ #else -+ if (!aicwf_rxframe_enqueue(sdiodev->dev, &rx_priv->rxq, pkt)) { -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ aicwf_dev_skb_free(pkt); -+ return; -+ } -+ #endif -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ -+ atomic_inc(&rx_priv->rx_cnt); -+} -+ -+ -+#define SDIO_OTHER_INTERRUPT (0x1ul << 7) -+ -+void aicwf_sdio_hal_irqhandler(struct sdio_func *func) -+{ -+ struct aicwf_bus *bus_if = dev_get_drvdata(&func->dev); -+ struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; -+ u8 intstatus = 0; -+ u8 byte_len = 0; -+ #ifdef CONFIG_PREALLOC_RX_SKB -+ struct rx_buff *pkt = NULL; -+ #else -+ struct sk_buff *pkt = NULL; -+ #endif -+ int ret; -+ -+ //AICWFDBG(LOGDEBUG, "fdrv %s enter \r\n", __func__); -+ rwnx_wakeup_lock(sdiodev->rwnx_hw->ws_irqrx); -+ -+ -+ if (!bus_if || bus_if->state == BUS_DOWN_ST) { -+ sdio_err("bus err\n"); -+ rwnx_wakeup_unlock(sdiodev->rwnx_hw->ws_irqrx); -+ return; -+ } -+ -+#ifdef CONFIG_PREALLOC_RX_SKB -+ if (list_empty(&aic_rx_buff_list.rxbuff_list)) { -+ printk("%s %d, rxbuff list is empty\n", __func__, __LINE__); -+ rwnx_wakeup_unlock(sdiodev->rwnx_hw->ws_irqrx); -+ return; -+ } -+#endif -+ -+ if (sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.block_cnt_reg, &intstatus); -+ while (ret || (intstatus & SDIO_OTHER_INTERRUPT)) { -+ sdio_err("ret=%d, intstatus=%x\r\n", ret, intstatus); -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.block_cnt_reg, &intstatus); -+ } -+ sdiodev->rx_priv->data_len = intstatus * SDIOWIFI_FUNC_BLOCKSIZE; -+ -+ if (intstatus > 0) { -+ if (intstatus < 64) { -+ pkt = aicwf_sdio_readframes(sdiodev); -+ } else { -+ aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len);//byte_len must<= 128 -+ sdio_info("byte mode len=%d\r\n", byte_len); -+ pkt = aicwf_sdio_readframes(sdiodev); -+ } -+ } else { -+ #ifndef CONFIG_PLATFORM_ALLWINNER -+ // sdio_err("Interrupt but no data\n"); -+ #endif -+ } -+ -+ if (pkt) -+ aicwf_sdio_enq_rxpkt(sdiodev, pkt); -+ -+ if(atomic_read(&sdiodev->rx_priv->rx_cnt) == 1){ -+ complete(&bus_if->busrx_trgg); -+ } -+ -+ }else if (sdiodev->chipid == PRODUCT_ID_AIC8800D80) { -+ do { -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.misc_int_status_reg, &intstatus); -+ if (!ret) { -+ break; -+ } -+ sdio_err("ret=%d, intstatus=%x\r\n",ret, intstatus); -+ } while (1); -+ if (intstatus & SDIO_OTHER_INTERRUPT) { -+ u8 int_pending; -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.sleep_reg, &int_pending); -+ if (ret < 0) { -+ sdio_err("reg:%d read failed!\n", sdiodev->sdio_reg.sleep_reg); -+ } -+ int_pending &= ~0x01; // dev to host soft irq -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.sleep_reg, int_pending); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!\n", sdiodev->sdio_reg.sleep_reg); -+ } -+ } -+ -+ if (intstatus > 0) { -+ uint8_t intmaskf2 = intstatus | (0x1UL << 3); -+ if (intmaskf2 > 120U) { // func2 -+ if (intmaskf2 == 127U) { // byte mode -+ //aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len, 1);//byte_len must<= 128 -+ aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len);//byte_len must<= 128 -+ sdio_info("byte mode len=%d\r\n", byte_len); -+ //pkt = aicwf_sdio_readframes(sdiodev, 1); -+ pkt = aicwf_sdio_readframes(sdiodev); -+ } else { // block mode -+ sdiodev->rx_priv->data_len = (intstatus & 0x7U) * SDIOWIFI_FUNC_BLOCKSIZE; -+ //pkt = aicwf_sdio_readframes(sdiodev, 1); -+ pkt = aicwf_sdio_readframes(sdiodev); -+ } -+ } else { // func1 -+ if (intstatus == 120U) { // byte mode -+ //aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len, 0);//byte_len must<= 128 -+ aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len);//byte_len must<= 128 -+ sdio_info("byte mode len=%d\r\n", byte_len); -+ //pkt = aicwf_sdio_readframes(sdiodev, 0); -+ pkt = aicwf_sdio_readframes(sdiodev); -+ } else { // block mode -+ sdiodev->rx_priv->data_len = (intstatus & 0x7FU) * SDIOWIFI_FUNC_BLOCKSIZE; -+ //pkt = aicwf_sdio_readframes(sdiodev, 0); -+ pkt = aicwf_sdio_readframes(sdiodev); -+ } -+ } -+ } else { -+ #ifndef CONFIG_PLATFORM_ALLWINNER -+ //sdio_err("Interrupt but no data\n"); -+ #endif -+ } -+ -+ if (pkt) -+ aicwf_sdio_enq_rxpkt(sdiodev, pkt); -+ -+ if(atomic_read(&sdiodev->rx_priv->rx_cnt) == 1){ -+ complete(&bus_if->busrx_trgg); -+ } -+ } -+ -+ rwnx_wakeup_unlock(sdiodev->rwnx_hw->ws_irqrx); -+} -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration) -+{ -+ uint timeout; -+ -+ //printk("%s duration:%d\r\n", __func__, duration); -+ if (sdiodev->bus_if->state == BUS_DOWN_ST && duration) -+ return; -+ -+ spin_lock_bh(&sdiodev->pwrctl_lock); -+ if (!duration) { -+ if (timer_pending(&sdiodev->timer)) -+ del_timer_sync(&sdiodev->timer); -+ } else { -+ sdiodev->active_duration = duration; -+ timeout = msecs_to_jiffies(sdiodev->active_duration); -+ mod_timer(&sdiodev->timer, jiffies + timeout); -+ } -+ spin_unlock_bh(&sdiodev->pwrctl_lock); -+} -+#endif -+ -+static struct aicwf_bus_ops aicwf_sdio_bus_ops = { -+ .stop = aicwf_sdio_bus_stop, -+ .start = aicwf_sdio_bus_start, -+ .txdata = aicwf_sdio_bus_txdata, -+ .txmsg = aicwf_sdio_bus_txmsg, -+}; -+ -+void aicwf_sdio_release(struct aic_sdio_dev *sdiodev) -+{ -+ struct aicwf_bus *bus_if; -+#ifdef CONFIG_OOB -+ int ret; -+#endif -+ AICWFDBG(LOGINFO, "%s Enter\n", __func__); -+ -+ bus_if = dev_get_drvdata(sdiodev->dev); -+ bus_if->state = BUS_DOWN_ST; -+#ifdef CONFIG_OOB -+ if(sdiodev->oob_enable){ -+ sdio_claim_host(sdiodev->func); -+ //disable sdio interrupt -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x0); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.intr_config_reg); -+ } -+ sdio_release_irq(sdiodev->func); -+ sdio_release_host(sdiodev->func); -+ } -+#endif -+ if (sdiodev->dev) -+ aicwf_bus_deinit(sdiodev->dev); -+ -+ if (sdiodev->tx_priv) -+ aicwf_tx_deinit(sdiodev->tx_priv); -+ -+ if (sdiodev->rx_priv) -+ aicwf_rx_deinit(sdiodev->rx_priv); -+ -+ #if defined(CONFIG_SDIO_PWRCTRL) -+ if (sdiodev->pwrctl_tsk) { -+ complete_all(&sdiodev->pwrctrl_trgg); -+ kthread_stop(sdiodev->pwrctl_tsk); -+ sdiodev->pwrctl_tsk = NULL; -+ } -+ -+ AICWFDBG(LOGINFO, "%s:pwrctl stopped\n", __func__); -+ #endif -+ -+ if (sdiodev->cmd_mgr.state == RWNX_CMD_MGR_STATE_INITED) -+ rwnx_cmd_mgr_deinit(&sdiodev->cmd_mgr); -+ AICWFDBG(LOGINFO, "%s Exit\n", __func__); -+} -+ -+void aicwf_sdio_reg_init(struct aic_sdio_dev *sdiodev) -+{ -+ sdio_dbg("%s\n", __func__); -+ -+ if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ sdiodev->sdio_reg.bytemode_len_reg = SDIOWIFI_BYTEMODE_LEN_REG; -+ sdiodev->sdio_reg.intr_config_reg = SDIOWIFI_INTR_CONFIG_REG; -+ sdiodev->sdio_reg.sleep_reg = SDIOWIFI_SLEEP_REG; -+ sdiodev->sdio_reg.wakeup_reg = SDIOWIFI_WAKEUP_REG; -+ sdiodev->sdio_reg.flow_ctrl_reg = SDIOWIFI_FLOW_CTRL_REG; -+ sdiodev->sdio_reg.register_block = SDIOWIFI_REGISTER_BLOCK; -+ sdiodev->sdio_reg.bytemode_enable_reg = SDIOWIFI_BYTEMODE_ENABLE_REG; -+ sdiodev->sdio_reg.block_cnt_reg = SDIOWIFI_BLOCK_CNT_REG; -+ sdiodev->sdio_reg.rd_fifo_addr = SDIOWIFI_RD_FIFO_ADDR; -+ sdiodev->sdio_reg.wr_fifo_addr = SDIOWIFI_WR_FIFO_ADDR; -+ } else if (sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ sdiodev->sdio_reg.bytemode_len_reg = SDIOWIFI_BYTEMODE_LEN_REG_V3; -+ sdiodev->sdio_reg.intr_config_reg = SDIOWIFI_INTR_ENABLE_REG_V3; -+ sdiodev->sdio_reg.sleep_reg = SDIOWIFI_INTR_PENDING_REG_V3; -+ sdiodev->sdio_reg.wakeup_reg = SDIOWIFI_INTR_TO_DEVICE_REG_V3; -+ sdiodev->sdio_reg.flow_ctrl_reg = SDIOWIFI_FLOW_CTRL_Q1_REG_V3; -+ sdiodev->sdio_reg.bytemode_enable_reg = SDIOWIFI_BYTEMODE_ENABLE_REG_V3; -+ sdiodev->sdio_reg.misc_int_status_reg = SDIOWIFI_MISC_INT_STATUS_REG_V3; -+ sdiodev->sdio_reg.rd_fifo_addr = SDIOWIFI_RD_FIFO_ADDR_V3; -+ sdiodev->sdio_reg.wr_fifo_addr = SDIOWIFI_WR_FIFO_ADDR_V3; -+ } -+} -+ -+int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev) -+{ -+ struct mmc_host *host; -+ u8 block_bit0 = 0x1; -+ u8 byte_mode_disable = 0x1;//1: no byte mode -+ int ret = 0; -+ struct aicbsp_feature_t feature; -+ u8 val = 0; -+ -+ aicbsp_get_feature(&feature, NULL); -+ aicwf_sdio_reg_init(sdiodev); -+ -+ host = sdiodev->func->card->host; -+ -+ sdio_claim_host(sdiodev->func); -+#if 0//SDIO PHASE SETTING -+ sdiodev->func->card->quirks |= MMC_QUIRK_LENIENT_FN0; -+ sdio_f0_writeb(sdiodev->func, feature.sdio_phase, 0x13, &ret); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "write func0 fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+#endif -+ ret = sdio_set_block_size(sdiodev->func, SDIOWIFI_FUNC_BLOCKSIZE); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "set blocksize fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ ret = sdio_enable_func(sdiodev->func); -+ if (ret < 0) { -+ sdio_release_host(sdiodev->func); -+ AICWFDBG(LOGERROR, "enable func fail %d.\n", ret); -+ return ret; -+ } -+ -+#if 1//SDIO CLOCK SETTING -+ if (feature.sdio_clock > 0) { -+ host->ios.clock = feature.sdio_clock; -+ host->ops->set_ios(host, &host->ios); -+ AICWFDBG(LOGINFO, "Set SDIO Clock %d MHz\n", host->ios.clock/1000000); -+ } -+#endif -+ -+ sdio_release_host(sdiodev->func); -+ -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.register_block, block_bit0); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.register_block); -+ return ret; -+ } -+ -+ //1: no byte mode -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.bytemode_enable_reg, byte_mode_disable); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.bytemode_enable_reg); -+ return ret; -+ } -+ -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.wakeup_reg, 1); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.wakeup_reg); -+ return ret; -+ } -+ -+#if 1 -+ mdelay(5); -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.sleep_reg, &val); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "reg:%d read failed!\n", sdiodev->sdio_reg.sleep_reg); -+ return ret; -+ } -+ -+ if(!(val & 0x10)){ -+ AICWFDBG(LOGERROR, "wakeup fail\n"); -+ }else{ -+ AICWFDBG(LOGINFO, "sdio ready\n"); -+ } -+#endif -+ return ret; -+} -+ -+int aicwf_sdiov3_func_init(struct aic_sdio_dev *sdiodev) -+{ -+ struct mmc_host *host; -+ u8 byte_mode_disable = 0x1;//1: no byte mode -+ int ret = 0; -+ struct aicbsp_feature_t feature; -+ //u8 val = 0; -+ u8 val1 = 0; -+ -+ aicbsp_get_feature(&feature, NULL); -+ aicwf_sdio_reg_init(sdiodev); -+ -+ host = sdiodev->func->card->host; -+ -+ sdio_claim_host(sdiodev->func); -+ sdiodev->func->card->quirks |= MMC_QUIRK_LENIENT_FN0; -+ -+ ret = sdio_set_block_size(sdiodev->func, SDIOWIFI_FUNC_BLOCKSIZE); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "set blocksize fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ ret = sdio_enable_func(sdiodev->func); -+ if (ret < 0) { -+ sdio_release_host(sdiodev->func); -+ AICWFDBG(LOGERROR, "enable func fail %d.\n", ret); -+ return ret; -+ } -+ -+ sdio_f0_writeb(sdiodev->func, 0x7F, 0xF2, &ret); -+ if (ret) { -+ sdio_err("set fn0 0xF2 fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+#if 0 -+ if (host->ios.timing == MMC_TIMING_UHS_DDR50) { -+ val = 0x21;//0x1D;//0x5; -+ } else { -+ val = 0x01;//0x19;//0x1; -+ } -+ val |= SDIOCLK_FREE_RUNNING_BIT; -+ sdio_f0_writeb(sdiodev->func, val, 0xF0, &ret); -+ if (ret) { -+ sdio_err("set iopad ctrl fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ sdio_f0_writeb(sdiodev->func, 0x0, 0xF8, &ret); -+ if (ret) { -+ sdio_err("set iopad delay2 fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ sdio_f0_writeb(sdiodev->func, 0x20, 0xF1, &ret); -+ if (ret) { -+ sdio_err("set iopad delay1 fail %d\n", ret); -+ sdio_release_host(sdiodev->func); -+ return ret; -+ } -+ msleep(1); -+#if 1//SDIO CLOCK SETTING -+ if ((feature.sdio_clock > 0) && (host->ios.timing != MMC_TIMING_UHS_DDR50)) { -+ host->ios.clock = feature.sdio_clock; -+ host->ops->set_ios(host, &host->ios); -+ AICWFDBG(LOGINFO, "Set SDIO Clock %d MHz\n", host->ios.clock/1000000); -+ } -+#endif -+#endif -+ sdio_release_host(sdiodev->func); -+ -+ //1: no byte mode -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.bytemode_enable_reg, byte_mode_disable); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.bytemode_enable_reg); -+ return ret; -+ } -+ -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.wakeup_reg, 0x11); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.wakeup_reg); -+ return ret; -+ } -+ -+#if 1 -+ mdelay(5); -+ ret = aicwf_sdio_readb(sdiodev, sdiodev->sdio_reg.sleep_reg, &val1); -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "reg:%d read failed!\n", sdiodev->sdio_reg.sleep_reg); -+ return ret; -+ } -+ -+ if(!(val1 & 0x10)){ -+ AICWFDBG(LOGERROR, "wakeup fail\n"); -+ }else{ -+ AICWFDBG(LOGINFO, "sdio ready\n"); -+ } -+#endif -+ return ret; -+} -+ -+void aicwf_sdio_func_deinit(struct aic_sdio_dev *sdiodev) -+{ -+ sdio_claim_host(sdiodev->func); -+ sdio_disable_func(sdiodev->func); -+ sdio_release_host(sdiodev->func); -+} -+ -+void *aicwf_sdio_bus_init(struct aic_sdio_dev *sdiodev) -+{ -+ int ret; -+ struct aicwf_bus *bus_if; -+ struct aicwf_rx_priv *rx_priv; -+ struct aicwf_tx_priv *tx_priv; -+ -+ #if defined(CONFIG_SDIO_PWRCTRL) -+ spin_lock_init(&sdiodev->pwrctl_lock); -+ sema_init(&sdiodev->pwrctl_wakeup_sema, 1); -+ #endif -+ -+ bus_if = sdiodev->bus_if; -+ bus_if->dev = sdiodev->dev; -+ bus_if->ops = &aicwf_sdio_bus_ops; -+ bus_if->state = BUS_DOWN_ST; -+ #if defined(CONFIG_SDIO_PWRCTRL) -+ sdiodev->state = SDIO_SLEEP_ST; -+ sdiodev->active_duration = SDIOWIFI_PWR_CTRL_INTERVAL; -+ #else -+ sdiodev->state = SDIO_ACTIVE_ST; -+ #endif -+ -+ rx_priv = aicwf_rx_init(sdiodev); -+ if (!rx_priv) { -+ sdio_err("rx init fail\n"); -+ goto fail; -+ } -+ sdiodev->rx_priv = rx_priv; -+ -+ tx_priv = aicwf_tx_init(sdiodev); -+ if (!tx_priv) { -+ sdio_err("tx init fail\n"); -+ goto fail; -+ } -+ sdiodev->tx_priv = tx_priv; -+ aicwf_frame_queue_init(&tx_priv->txq, 8, TXQLEN); -+ spin_lock_init(&tx_priv->txqlock); -+ sema_init(&tx_priv->txctl_sema, 1); -+ sema_init(&tx_priv->cmd_txsema, 1); -+ init_waitqueue_head(&tx_priv->cmd_txdone_wait); -+ atomic_set(&tx_priv->tx_pktcnt, 0); -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+ init_timer(&sdiodev->timer); -+ sdiodev->timer.data = (ulong) sdiodev; -+ sdiodev->timer.function = aicwf_sdio_bus_pwrctl; -+#else -+ timer_setup(&sdiodev->timer, aicwf_sdio_bus_pwrctl, 0); -+#endif -+ init_completion(&sdiodev->pwrctrl_trgg); -+#ifdef AICWF_SDIO_SUPPORT -+ sdiodev->pwrctl_tsk = kthread_run(aicwf_sdio_pwrctl_thread, sdiodev, "aicwf_pwrctl"); -+#endif -+ if (IS_ERR(sdiodev->pwrctl_tsk)) { -+ sdiodev->pwrctl_tsk = NULL; -+ } -+#endif -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+ sdiodev->flowctrl = 0; -+ spin_lock_init(&sdiodev->tx_flow_lock); -+#endif -+ -+ ret = aicwf_bus_init(0, sdiodev->dev); -+ if (ret < 0) { -+ sdio_err("bus init fail\n"); -+ goto fail; -+ } -+ -+ ret = aicwf_bus_start(bus_if); -+ if (ret != 0) { -+ sdio_err("bus start fail\n"); -+ goto fail; -+ } -+ -+ return sdiodev; -+ -+fail: -+ aicwf_sdio_release(sdiodev); -+ return NULL; -+} -+ -+uint8_t crc8_ponl_107(uint8_t *p_buffer, uint16_t cal_size) -+{ -+ uint8_t i; -+ uint8_t crc = 0; -+ if (cal_size==0) { -+ return crc; -+ } -+ while (cal_size--) { -+ for (i = 0x80; i > 0; i /= 2) { -+ if (crc & 0x80) { -+ crc *= 2; -+ crc ^= 0x07; //polynomial X8 + X2 + X + 1,(0x107) -+ } else { -+ crc *= 2; -+ } -+ if ((*p_buffer) & i) { -+ crc ^= 0x07; -+ } -+ } -+ p_buffer++; -+ } -+ -+ return crc; -+} -+ -+#ifdef CONFIG_WIFI_SUSPEND_FOR_LINUX -+void rwnx_set_wifi_suspend(char onoff){ -+ int ret = 0; -+ if (onoff == '0') { -+ printk("%s resume \r\n", __func__); -+ rwnx_send_me_set_lp_level(g_rwnx_plat->sdiodev->rwnx_hw, 0); -+ }else{ -+ printk("%s suspend \r\n", __func__); -+ ret = rwnx_send_me_set_lp_level(g_rwnx_plat->sdiodev->rwnx_hw, 1); -+ if (!ret) { -+ aicwf_sdio_pwr_stctl(g_rwnx_plat->sdiodev, SDIO_SLEEP_ST); -+ ret = aicwf_sdio_writeb(g_rwnx_plat->sdiodev, SDIOWIFI_WAKEUP_REG, 2); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!\n", SDIOWIFI_WAKEUP_REG); -+ } -+ } -+ } -+} -+ -+static ssize_t rwnx_wifi_suspend_write_proc(struct file *file, -+ const char __user *buffer, -+ size_t count, loff_t *pos){ -+ char onoff; -+ -+ if (count < 1) -+ return -EINVAL; -+ -+ if (copy_from_user(&onoff, buffer, 1)) -+ return -EFAULT; -+ -+ rwnx_set_wifi_suspend(onoff); -+ -+ return count; -+} -+ -+static const struct file_operations wifi_suspend_fops = { -+ .owner = THIS_MODULE, -+ .write = rwnx_wifi_suspend_write_proc, -+}; -+ -+void rwnx_init_wifi_suspend_node(void){ -+ struct proc_dir_entry *ent; -+ -+ wifi_suspend_node = proc_mkdir("wifi_suspend", NULL); -+ if (wifi_suspend_node == NULL) { -+ printk("Unable to create /proc/wifi_suspend directory"); -+ } -+ -+ ent = proc_create("suspend", 0660, wifi_suspend_node, &wifi_suspend_fops); -+ if (ent == NULL) { -+ printk("Unable to create /proc/wifi_suspend/suspend"); -+ } -+} -+ -+void rwnx_deinit_wifi_suspend_node(void){ -+ remove_proc_entry("suspend", wifi_suspend_node); -+ remove_proc_entry("wifi_suspend", 0); -+} -+#endif//CONFIG_WIFI_SUSPEND_FOR_LINUX -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,186 @@ -+/** -+ * aicwf_sdio.h -+ * -+ * SDIO function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+#ifndef _AICWF_SDMMC_H_ -+#define _AICWF_SDMMC_H_ -+ -+#ifdef AICWF_SDIO_SUPPORT -+#include -+#include -+#include -+#include -+#include "rwnx_cmds.h" -+#include "aicwf_rx_prealloc.h" -+#define AICWF_SDIO_NAME "aicwf_sdio" -+#define SDIOWIFI_FUNC_BLOCKSIZE 512 -+ -+#define SDIOWIFI_BYTEMODE_LEN_REG 0x02 -+#define SDIOWIFI_INTR_CONFIG_REG 0x04 -+#define SDIOWIFI_SLEEP_REG 0x05 -+#define SDIOWIFI_WAKEUP_REG 0x09 -+#define SDIOWIFI_FLOW_CTRL_REG 0x0A -+#define SDIOWIFI_REGISTER_BLOCK 0x0B -+#define SDIOWIFI_BYTEMODE_ENABLE_REG 0x11 -+#define SDIOWIFI_BLOCK_CNT_REG 0x12 -+#define SDIOWIFI_FLOWCTRL_MASK_REG 0x7F -+#define SDIOWIFI_WR_FIFO_ADDR 0x07 -+#define SDIOWIFI_RD_FIFO_ADDR 0x08 -+ -+#define SDIOWIFI_INTR_ENABLE_REG_V3 0x00 -+#define SDIOWIFI_INTR_PENDING_REG_V3 0x01 -+#define SDIOWIFI_INTR_TO_DEVICE_REG_V3 0x02 -+#define SDIOWIFI_FLOW_CTRL_Q1_REG_V3 0x03 -+#define SDIOWIFI_MISC_INT_STATUS_REG_V3 0x04 -+#define SDIOWIFI_BYTEMODE_LEN_REG_V3 0x05 -+#define SDIOWIFI_BYTEMODE_LEN_MSB_REG_V3 0x06 -+#define SDIOWIFI_BYTEMODE_ENABLE_REG_V3 0x07 -+#define SDIOWIFI_MISC_CTRL_REG_V3 0x08 -+#define SDIOWIFI_FLOW_CTRL_Q2_REG_V3 0x09 -+#define SDIOWIFI_CLK_TEST_RESULT_REG_V3 0x0A -+#define SDIOWIFI_RD_FIFO_ADDR_V3 0x0F -+#define SDIOWIFI_WR_FIFO_ADDR_V3 0x10 -+ -+#define SDIOCLK_FREE_RUNNING_BIT (1 << 6) -+ -+#define SDIOWIFI_PWR_CTRL_INTERVAL 30 -+#define FLOW_CTRL_RETRY_COUNT 50 -+#define BUFFER_SIZE 1536 -+#define TAIL_LEN 4 -+#define TXQLEN (2048*4) -+ -+#define SDIO_SLEEP_ST 0 -+#define SDIO_ACTIVE_ST 1 -+ -+#define DATA_FLOW_CTRL_THRESH 2 -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+#define AICWF_SDIO_TX_LOW_WATER 100 -+#define AICWF_SDIO_TX_HIGH_WATER 500 -+#endif -+ -+typedef enum { -+ SDIO_TYPE_DATA = 0X00, -+ SDIO_TYPE_CFG = 0X10, -+ SDIO_TYPE_CFG_CMD_RSP = 0X11, -+ SDIO_TYPE_CFG_DATA_CFM = 0X12, -+ SDIO_TYPE_CFG_PRINT = 0X13 -+} sdio_type; -+ -+/* SDIO Device ID */ -+#define SDIO_VENDOR_ID_AIC8801 0x5449 -+#define SDIO_VENDOR_ID_AIC8800DC 0xc8a1 -+#define SDIO_VENDOR_ID_AIC8800D80 0xc8a1 -+ -+#define SDIO_DEVICE_ID_AIC8801 0x0145 -+#define SDIO_DEVICE_ID_AIC8800DC 0xc08d -+#define SDIO_DEVICE_ID_AIC8800D80 0x0082 -+ -+enum AICWF_IC{ -+ PRODUCT_ID_AIC8801 = 0, -+ PRODUCT_ID_AIC8800DC, -+ PRODUCT_ID_AIC8800DW, -+ PRODUCT_ID_AIC8800D80 -+}; -+ -+ -+struct rwnx_hw; -+ -+struct aic_sdio_reg { -+ u8 bytemode_len_reg; -+ u8 intr_config_reg; -+ u8 sleep_reg; -+ u8 wakeup_reg; -+ u8 flow_ctrl_reg; -+ u8 flowctrl_mask_reg; -+ u8 register_block; -+ u8 bytemode_enable_reg; -+ u8 block_cnt_reg; -+ u8 misc_int_status_reg; -+ u8 rd_fifo_addr; -+ u8 wr_fifo_addr; -+}; -+ -+struct aic_sdio_dev { -+ struct rwnx_hw *rwnx_hw; -+ struct sdio_func *func; -+ struct device *dev; -+ struct aicwf_bus *bus_if; -+ struct rwnx_cmd_mgr cmd_mgr; -+ -+ struct aicwf_rx_priv *rx_priv; -+ struct aicwf_tx_priv *tx_priv; -+ u32 state; -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+ u8 flowctrl; -+ spinlock_t tx_flow_lock; -+#endif -+ -+ #if defined(CONFIG_SDIO_PWRCTRL) -+ //for sdio pwr ctrl -+ struct timer_list timer; -+ uint active_duration; -+ struct completion pwrctrl_trgg; -+ struct task_struct *pwrctl_tsk; -+ spinlock_t pwrctl_lock; -+ struct semaphore pwrctl_wakeup_sema; -+ #endif -+ u16 chipid; -+ struct aic_sdio_reg sdio_reg; -+ -+ spinlock_t wslock;//AIDEN test -+ bool oob_enable; -+ atomic_t is_bus_suspend; -+}; -+extern struct aicwf_rx_buff_list aic_rx_buff_list; -+int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val); -+void aicwf_sdio_hal_irqhandler(struct sdio_func *func); -+ -+#if defined(CONFIG_SDIO_PWRCTRL) -+void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration); -+int aicwf_sdio_pwr_stctl(struct aic_sdio_dev *sdiodev, uint target); -+#endif -+void aicwf_sdio_reg_init(struct aic_sdio_dev *sdiodev); -+int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev); -+int aicwf_sdiov3_func_init(struct aic_sdio_dev *sdiodev); -+void aicwf_sdio_func_deinit(struct aic_sdio_dev *sdiodev); -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+void aicwf_sdio_tx_netif_flowctrl(struct rwnx_hw *rwnx_hw, bool state); -+#endif -+int aicwf_sdio_flow_ctrl(struct aic_sdio_dev *sdiodev); -+int aicwf_sdio_flow_ctrl_msg(struct aic_sdio_dev *sdiodev); -+#ifdef CONFIG_PREALLOC_RX_SKB -+int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct rx_buff *rxbbuf, u32 size); -+#else -+int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct sk_buff *skbbuf, u32 size); -+#endif -+int aicwf_sdio_send_pkt(struct aic_sdio_dev *sdiodev, u8 *buf, uint count); -+void *aicwf_sdio_bus_init(struct aic_sdio_dev *sdiodev); -+void aicwf_sdio_release(struct aic_sdio_dev *sdiodev); -+void aicwf_sdio_exit(void); -+void aicwf_sdio_register(void); -+int aicwf_sdio_txpkt(struct aic_sdio_dev *sdiodev, struct sk_buff *pkt); -+int sdio_bustx_thread(void *data); -+int sdio_busrx_thread(void *data); -+#ifdef CONFIG_OOB -+//new oob feature -+int sdio_busirq_thread(void *data); -+#endif //CONFIG_OOB -+int aicwf_sdio_aggr(struct aicwf_tx_priv *tx_priv, struct sk_buff *pkt); -+int aicwf_sdio_send(struct aicwf_tx_priv *tx_priv, u8 txnow); -+void aicwf_sdio_aggr_send(struct aicwf_tx_priv *tx_priv); -+void aicwf_sdio_aggrbuf_reset(struct aicwf_tx_priv *tx_priv); -+extern void aicwf_hostif_ready(void); -+extern void aicwf_hostif_fail(void); -+#ifdef CONFIG_PLATFORM_AMLOGIC -+extern void extern_wifi_set_enable(int is_on); -+extern void sdio_reinit(void); -+#endif /*CONFIG_PLATFORM_AMLOGIC*/ -+uint8_t crc8_ponl_107(uint8_t *p_buffer, uint16_t cal_size); -+ -+#endif /* AICWF_SDIO_SUPPORT */ -+ -+#endif /*_AICWF_SDMMC_H_*/ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_tcp_ack.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_tcp_ack.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_tcp_ack.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_tcp_ack.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,633 @@ -+#include"aicwf_tcp_ack.h" -+//#include"rwnx_tx.h" -+//#include "aicwf_tcp_ack.h" -+#include"rwnx_defs.h" -+extern int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg); -+struct msg_buf *intf_tcp_alloc_msg(struct msg_buf *msg) -+{ -+ //printk("%s \n",__func__); -+ int len=sizeof(struct msg_buf) ; -+ msg = kzalloc(len , /*GFP_KERNEL*/GFP_ATOMIC); -+ if(!msg) -+ printk("%s: alloc failed \n", __func__); -+ memset(msg,0,len); -+ return msg; -+} -+ -+void intf_tcp_drop_msg(struct rwnx_hw *priv, -+ struct msg_buf *msg) -+{ -+ //printk("%s \n",__func__); -+ if (msg->skb) -+ dev_kfree_skb_any(msg->skb); -+ -+ kfree(msg); -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+void tcp_ack_timeout(unsigned long data) -+#else -+void tcp_ack_timeout(struct timer_list *t) -+#endif -+{ -+ //printk("%s \n",__func__); -+ struct tcp_ack_info *ack_info; -+ struct msg_buf *msg; -+ struct tcp_ack_manage *ack_m = NULL; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+ ack_info = (struct tcp_ack_info *)data; -+#else -+ ack_info = container_of(t,struct tcp_ack_info,timer); -+#endif -+ -+ ack_m = container_of(ack_info, struct tcp_ack_manage, -+ ack_info[ack_info->ack_info_num]); -+ -+ write_seqlock_bh(&ack_info->seqlock); -+ msg = ack_info->msgbuf; -+ if (ack_info->busy && msg && !ack_info->in_send_msg) { -+ ack_info->msgbuf = NULL; -+ ack_info->drop_cnt = 0; -+ ack_info->in_send_msg = msg; -+ write_sequnlock_bh(&ack_info->seqlock); -+ intf_tx(ack_m->priv, msg);//send skb -+ //ack_info->in_send_msg = NULL;//add by dwx -+ //write_sequnlock_bh(&ack_info->seqlock); -+ //intf_tx(ack_m->priv, msg); -+ return; -+ } -+ write_sequnlock_bh(&ack_info->seqlock); -+} -+ -+void tcp_ack_init(struct rwnx_hw *priv) -+{ -+ int i; -+ struct tcp_ack_info *ack_info; -+ struct tcp_ack_manage *ack_m = &priv->ack_m; -+ -+ printk("%s \n",__func__); -+ memset(ack_m, 0, sizeof(struct tcp_ack_manage)); -+ ack_m->priv = priv; -+ spin_lock_init(&ack_m->lock); -+ atomic_set(&ack_m->max_drop_cnt, TCP_ACK_DROP_CNT); -+ ack_m->last_time = jiffies; -+ ack_m->timeout = msecs_to_jiffies(ACK_OLD_TIME); -+ -+ for (i = 0; i < TCP_ACK_NUM; i++) { -+ ack_info = &ack_m->ack_info[i]; -+ ack_info->ack_info_num = i; -+ seqlock_init(&ack_info->seqlock); -+ ack_info->last_time = jiffies; -+ ack_info->timeout = msecs_to_jiffies(ACK_OLD_TIME); -+ -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+ setup_timer(&ack_info->timer, tcp_ack_timeout, -+ (unsigned long)ack_info); -+ #else -+ timer_setup(&ack_info->timer,tcp_ack_timeout,0); -+ #endif -+ } -+ -+ atomic_set(&ack_m->enable, 1); -+ ack_m->ack_winsize = MIN_WIN; -+} -+ -+void tcp_ack_deinit(struct rwnx_hw *priv) -+{ -+ int i; -+ struct tcp_ack_manage *ack_m = &priv->ack_m; -+ struct msg_buf *drop_msg = NULL; -+ -+ printk("%s \n",__func__); -+ atomic_set(&ack_m->enable, 0); -+ -+ for (i = 0; i < TCP_ACK_NUM; i++) { -+ drop_msg = NULL; -+ -+ write_seqlock_bh(&ack_m->ack_info[i].seqlock); -+ del_timer(&ack_m->ack_info[i].timer); -+ drop_msg = ack_m->ack_info[i].msgbuf; -+ ack_m->ack_info[i].msgbuf = NULL; -+ write_sequnlock_bh(&ack_m->ack_info[i].seqlock); -+ -+ if (drop_msg) -+ intf_tcp_drop_msg(priv, drop_msg);//drop skb -+ } -+} -+ -+int tcp_check_quick_ack(unsigned char *buf, -+ struct tcp_ack_msg *msg) -+{ -+ int ip_hdr_len; -+ unsigned char *temp; -+ struct ethhdr *ethhdr; -+ struct iphdr *iphdr; -+ struct tcphdr *tcphdr; -+ -+ ethhdr = (struct ethhdr *)buf; -+ if (ethhdr->h_proto != htons(ETH_P_IP)) -+ return 0; -+ iphdr = (struct iphdr *)(ethhdr + 1); -+ if (iphdr->version != 4 || iphdr->protocol != IPPROTO_TCP) -+ return 0; -+ ip_hdr_len = iphdr->ihl * 4; -+ temp = (unsigned char *)(iphdr) + ip_hdr_len; -+ tcphdr = (struct tcphdr *)temp; -+ /* TCP_FLAG_ACK */ -+ if (!(temp[13] & 0x10)) -+ return 0; -+ -+ if (temp[13] & 0x8) { -+ msg->saddr = iphdr->daddr; -+ msg->daddr = iphdr->saddr; -+ msg->source = tcphdr->dest; -+ msg->dest = tcphdr->source; -+ msg->seq = ntohl(tcphdr->seq); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len, -+ unsigned short *win_scale) -+{ -+ //printk("%s \n",__func__); -+ int drop = 1; -+ int len = tcphdr->doff * 4; -+ unsigned char *ptr; -+ -+ if(tcp_tot_len > len) { -+ drop = 0; -+ } else { -+ len -= sizeof(struct tcphdr); -+ ptr = (unsigned char *)(tcphdr + 1); -+ -+ while ((len > 0) && drop) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ break; -+ case TCPOPT_NOP: -+ len--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) -+ break; -+ if (opsize > len) -+ break; -+ -+ switch (opcode) { -+ /* TODO: Add other ignore opt */ -+ case TCPOPT_TIMESTAMP: -+ break; -+ case TCPOPT_WINDOW: -+ if (*ptr < 15) -+ *win_scale = (1 << (*ptr)); -+ printk("%d\n",*win_scale); -+ break; -+ default: -+ drop = 2; -+ } -+ -+ ptr += opsize - 2; -+ len -= opsize; -+ } -+ } -+ } -+ -+ return drop; -+} -+ -+ -+/* flag:0 for not tcp ack -+ * 1 for ack which can be drop -+ * 2 for other ack whith more info -+ */ -+ -+int tcp_check_ack(unsigned char *buf, -+ struct tcp_ack_msg *msg, -+ unsigned short *win_scale) -+{ -+ int ret; -+ int ip_hdr_len; -+ int tcp_tot_len; -+ unsigned char *temp; -+ struct ethhdr *ethhdr; -+ struct iphdr *iphdr; -+ struct tcphdr *tcphdr; -+ -+ ethhdr =(struct ethhdr *)buf; -+ if (ethhdr->h_proto != htons(ETH_P_IP)) -+ return 0; -+ -+ iphdr = (struct iphdr *)(ethhdr + 1); -+ if (iphdr->version != 4 || iphdr->protocol != IPPROTO_TCP) -+ return 0; -+ -+ ip_hdr_len = iphdr->ihl * 4; -+ temp = (unsigned char *)(iphdr) + ip_hdr_len; -+ tcphdr = (struct tcphdr *)temp; -+ /* TCP_FLAG_ACK */ -+ if (!(temp[13] & 0x10)) -+ return 0; -+ -+ tcp_tot_len = ntohs(iphdr->tot_len) - ip_hdr_len;// tcp total len -+ ret = is_drop_tcp_ack(tcphdr, tcp_tot_len, win_scale); -+ //printk("is drop:%d \n",ret); -+ -+ if (ret > 0) { -+ msg->saddr = iphdr->saddr; -+ msg->daddr = iphdr->daddr; -+ msg->source = tcphdr->source; -+ msg->dest = tcphdr->dest; -+ msg->seq = ntohl(tcphdr->ack_seq); -+ msg->win = ntohs(tcphdr->window); -+ } -+ -+ return ret; -+} -+ -+/* return val: -1 for not match, others for match */ -+int tcp_ack_match(struct tcp_ack_manage *ack_m, -+ struct tcp_ack_msg *ack_msg) -+{ -+ int i, ret = -1; -+ unsigned start; -+ struct tcp_ack_info *ack_info; -+ struct tcp_ack_msg *ack; -+ -+ for (i = 0; ((ret < 0) && (i < TCP_ACK_NUM)); i++) { -+ ack_info = &ack_m->ack_info[i]; -+ do { -+ start = read_seqbegin(&ack_info->seqlock); -+ ret = -1; -+ -+ ack = &ack_info->ack_msg; -+ if (ack_info->busy && -+ ack->dest == ack_msg->dest && -+ ack->source == ack_msg->source && -+ ack->saddr == ack_msg->saddr && -+ ack->daddr == ack_msg->daddr) -+ ret = i; -+ } while(read_seqretry(&ack_info->seqlock, start)); -+ } -+ -+ return ret; -+} -+ -+ -+void tcp_ack_update(struct tcp_ack_manage *ack_m) -+{ -+ int i; -+ struct tcp_ack_info *ack_info; -+ -+ if (time_after(jiffies, ack_m->last_time + ack_m->timeout)) { -+ spin_lock_bh(&ack_m->lock); -+ ack_m->last_time = jiffies; -+ for (i = TCP_ACK_NUM - 1; i >= 0; i--) { -+ ack_info = &ack_m->ack_info[i]; -+ write_seqlock_bh(&ack_info->seqlock); -+ if (ack_info->busy && -+ time_after(jiffies, ack_info->last_time + -+ ack_info->timeout)) { -+ ack_m->free_index = i; -+ ack_m->max_num--; -+ ack_info->busy = 0; -+ } -+ write_sequnlock_bh(&ack_info->seqlock); -+ } -+ spin_unlock_bh(&ack_m->lock); -+ } -+} -+ -+/* return val: -1 for no index, others for index */ -+int tcp_ack_alloc_index(struct tcp_ack_manage *ack_m) -+{ -+ int i, ret = -1; -+ struct tcp_ack_info *ack_info; -+ unsigned start; -+ -+ spin_lock_bh(&ack_m->lock); -+ if (ack_m->max_num == TCP_ACK_NUM) { -+ spin_unlock_bh(&ack_m->lock); -+ return -1; -+ } -+ -+ if (ack_m->free_index >= 0) { -+ i = ack_m->free_index; -+ ack_m->free_index = -1; -+ ack_m->max_num++; -+ spin_unlock_bh(&ack_m->lock); -+ return i; -+ } -+ -+ for (i = 0; ((ret < 0) && (i < TCP_ACK_NUM)); i++) { -+ ack_info = &ack_m->ack_info[i]; -+ do { -+ start = read_seqbegin(&ack_info->seqlock); -+ ret = -1; -+ if (!ack_info->busy) { -+ ack_m->free_index = -1; -+ ack_m->max_num++; -+ ret = i; -+ } -+ } while(read_seqretry(&ack_info->seqlock, start)); -+ } -+ spin_unlock_bh(&ack_m->lock); -+ -+ return ret; -+} -+ -+ -+/* return val: 0 for not handle tx, 1 for handle tx */ -+int tcp_ack_handle(struct msg_buf *new_msgbuf, -+ struct tcp_ack_manage *ack_m, -+ struct tcp_ack_info *ack_info, -+ struct tcp_ack_msg *ack_msg, -+ int type) -+{ -+ int quick_ack = 0; -+ struct tcp_ack_msg *ack; -+ int ret = 0; -+ struct msg_buf *drop_msg = NULL; -+ -+ //printk("%s %d",__func__,type); -+ write_seqlock_bh(&ack_info->seqlock); -+ -+ ack_info->last_time = jiffies; -+ ack = &ack_info->ack_msg; -+ -+ if (type == 2) { -+ if (U32_BEFORE(ack->seq, ack_msg->seq)) { -+ ack->seq = ack_msg->seq; -+ if (ack_info->psh_flag && -+ !U32_BEFORE(ack_msg->seq, -+ ack_info->psh_seq)) { -+ ack_info->psh_flag = 0; -+ } -+ -+ if (ack_info->msgbuf) { -+ //printk("%lx \n",ack_info->msgbuf); -+ drop_msg = ack_info->msgbuf; -+ ack_info->msgbuf = NULL; -+ del_timer(&ack_info->timer); -+ }else{ -+ //printk("msgbuf is NULL \n"); -+ } -+ -+ ack_info->in_send_msg = NULL; -+ ack_info->drop_cnt = atomic_read(&ack_m->max_drop_cnt); -+ } else { -+ printk("%s before abnormal ack: %d, %d\n", -+ __func__, ack->seq, ack_msg->seq); -+ drop_msg = new_msgbuf; -+ ret = 1; -+ } -+ } else if (U32_BEFORE(ack->seq, ack_msg->seq)) { -+ if (ack_info->msgbuf) { -+ drop_msg = ack_info->msgbuf; -+ ack_info->msgbuf = NULL; -+ } -+ -+ if (ack_info->psh_flag && -+ !U32_BEFORE(ack_msg->seq, ack_info->psh_seq)) { -+ ack_info->psh_flag = 0; -+ quick_ack = 1; -+ } else { -+ ack_info->drop_cnt++; -+ } -+ -+ ack->seq = ack_msg->seq; -+ -+ if (quick_ack || (!ack_info->in_send_msg && -+ (ack_info->drop_cnt >= -+ atomic_read(&ack_m->max_drop_cnt)))) { -+ ack_info->drop_cnt = 0; -+ ack_info->in_send_msg = new_msgbuf; -+ del_timer(&ack_info->timer); -+ } else { -+ ret = 1; -+ ack_info->msgbuf = new_msgbuf; -+ if (!timer_pending(&ack_info->timer)) -+ mod_timer(&ack_info->timer, -+ (jiffies + msecs_to_jiffies(5))); -+ } -+ } else { -+ printk("%s before ack: %d, %d\n", -+ __func__, ack->seq, ack_msg->seq); -+ drop_msg = new_msgbuf; -+ ret = 1; -+ } -+ -+ write_sequnlock_bh(&ack_info->seqlock); -+ -+ if (drop_msg) -+ intf_tcp_drop_msg(ack_m->priv, drop_msg);// drop skb -+ -+ return ret; -+} -+ -+int tcp_ack_handle_new(struct msg_buf *new_msgbuf, -+ struct tcp_ack_manage *ack_m, -+ struct tcp_ack_info *ack_info, -+ struct tcp_ack_msg *ack_msg, -+ int type) -+{ -+ int quick_ack = 0; -+ struct tcp_ack_msg *ack; -+ int ret = 0; -+ struct msg_buf *drop_msg = NULL; -+ struct msg_buf * send_msg = NULL; -+ //printk("",); -+ write_seqlock_bh(&ack_info->seqlock); -+ -+ ack_info->last_time = jiffies; -+ ack = &ack_info->ack_msg; -+ -+ if(U32_BEFORE(ack->seq, ack_msg->seq)){ -+ if (ack_info->msgbuf) { -+ drop_msg = ack_info->msgbuf; -+ ack_info->msgbuf = NULL; -+ //ack_info->drop_cnt++; -+ } -+ -+ if (ack_info->psh_flag && -+ !U32_BEFORE(ack_msg->seq, ack_info->psh_seq)) { -+ ack_info->psh_flag = 0; -+ quick_ack = 1; -+ } else { -+ ack_info->drop_cnt++; -+ } -+ -+ ack->seq = ack_msg->seq; -+ -+ if(quick_ack || (!ack_info->in_send_msg && -+ (ack_info->drop_cnt >= -+ atomic_read(&ack_m->max_drop_cnt)))){ -+ ack_info->drop_cnt = 0; -+ send_msg = new_msgbuf; -+ ack_info->in_send_msg = send_msg; -+ del_timer(&ack_info->timer); -+ }else{ -+ ret = 1; -+ ack_info->msgbuf = new_msgbuf; -+ if (!timer_pending(&ack_info->timer)) -+ mod_timer(&ack_info->timer, -+ (jiffies + msecs_to_jiffies(5))); -+ } -+ -+ //ret = 1; -+ }else { -+ printk("%s before ack: %d, %d\n", -+ __func__, ack->seq, ack_msg->seq); -+ drop_msg = new_msgbuf; -+ ret = 1; -+ } -+ -+ /*if(send_msg){ -+ intf_tx(ack_m->priv,send_msg); -+ ack_info->in_send_msg=NULL; -+ }*/ -+ -+ //ack_info->in_send_msg=NULL; -+ -+ write_sequnlock_bh(&ack_info->seqlock); -+ -+ /*if(send_msg){ -+ intf_tx(ack_m->priv,send_msg); -+ //ack_info->in_send_msg=NULL; -+ }*/ -+ -+ if (drop_msg) -+ intf_tcp_drop_msg(ack_m->priv, drop_msg);// drop skb -+ -+ return ret; -+ -+} -+ -+void filter_rx_tcp_ack(struct rwnx_hw *priv, -+ unsigned char *buf, unsigned plen) -+{ -+ int index; -+ struct tcp_ack_msg ack_msg; -+ struct tcp_ack_info *ack_info; -+ struct tcp_ack_manage *ack_m = &priv->ack_m; -+ -+ if (!atomic_read(&ack_m->enable)) -+ return; -+ -+ if ((plen > MAX_TCP_ACK) || -+ !tcp_check_quick_ack(buf, &ack_msg)) -+ return; -+ -+ index = tcp_ack_match(ack_m, &ack_msg); -+ if (index >= 0) { -+ ack_info = ack_m->ack_info + index; -+ write_seqlock_bh(&ack_info->seqlock); -+ ack_info->psh_flag = 1; -+ ack_info->psh_seq = ack_msg.seq; -+ write_sequnlock_bh(&ack_info->seqlock); -+ } -+} -+ -+/* return val: 0 for not filter, 1 for filter */ -+int filter_send_tcp_ack(struct rwnx_hw *priv, -+ struct msg_buf *msgbuf, -+ unsigned char *buf, unsigned int plen) -+{ -+ //printk("%s \n",__func__); -+ int ret = 0; -+ int index, drop; -+ unsigned short win_scale = 0; -+ unsigned int win = 0; -+ struct tcp_ack_msg ack_msg; -+ struct tcp_ack_msg *ack; -+ struct tcp_ack_info *ack_info; -+ struct tcp_ack_manage *ack_m = &priv->ack_m; -+ -+ if (plen > MAX_TCP_ACK) -+ return 0; -+ -+ tcp_ack_update(ack_m); -+ drop = tcp_check_ack(buf, &ack_msg, &win_scale); -+ //printk("drop:%d win_scale:%d",drop,win_scale); -+ if (!drop && (0 == win_scale)) -+ return 0; -+ -+ index = tcp_ack_match(ack_m, &ack_msg); -+ if (index >= 0) { -+ ack_info = ack_m->ack_info + index; -+ if ((0 != win_scale) && -+ (ack_info->win_scale != win_scale)) { -+ write_seqlock_bh(&ack_info->seqlock); -+ ack_info->win_scale = win_scale; -+ write_sequnlock_bh(&ack_info->seqlock); -+ } -+ -+ if (drop > 0 && atomic_read(&ack_m->enable)) { -+ win = ack_info->win_scale * ack_msg.win; -+ if ((win_scale!=0) && (win < (ack_m->ack_winsize * SIZE_KB))) -+ { -+ drop = 2; -+ printk("%d %d %d",win_scale,win,(ack_m->ack_winsize * SIZE_KB)); -+ } -+ ret = tcp_ack_handle_new(msgbuf, ack_m, ack_info, -+ &ack_msg, drop); -+ } -+ -+ goto out; -+ } -+ -+ index = tcp_ack_alloc_index(ack_m); -+ if (index >= 0) { -+ write_seqlock_bh(&ack_m->ack_info[index].seqlock); -+ ack_m->ack_info[index].busy = 1; -+ ack_m->ack_info[index].psh_flag = 0; -+ ack_m->ack_info[index].last_time = jiffies; -+ ack_m->ack_info[index].drop_cnt = -+ atomic_read(&ack_m->max_drop_cnt); -+ ack_m->ack_info[index].win_scale = -+ (win_scale != 0) ? win_scale : 1; -+ -+ //ack_m->ack_info[index].msgbuf = NULL; -+ //ack_m->ack_info[index].in_send_msg = NULL; -+ ack = &ack_m->ack_info[index].ack_msg; -+ ack->dest = ack_msg.dest; -+ ack->source = ack_msg.source; -+ ack->saddr = ack_msg.saddr; -+ ack->daddr = ack_msg.daddr; -+ ack->seq = ack_msg.seq; -+ write_sequnlock_bh(&ack_m->ack_info[index].seqlock); -+ } -+ -+out: -+ return ret; -+} -+ -+void move_tcpack_msg(struct rwnx_hw *priv, -+ struct msg_buf *msg) -+{ -+ struct tcp_ack_info *ack_info; -+ struct tcp_ack_manage *ack_m = &priv->ack_m; -+ int i = 0; -+ -+ if (!atomic_read(&ack_m->enable)) -+ return; -+ -+ //if (msg->len > MAX_TCP_ACK) -+ // return; -+ -+ for (i = 0; i < TCP_ACK_NUM; i++) { -+ ack_info = &ack_m->ack_info[i]; -+ write_seqlock_bh(&ack_info->seqlock); -+ if (ack_info->busy && (ack_info->in_send_msg == msg)) -+ ack_info->in_send_msg = NULL; -+ write_sequnlock_bh(&ack_info->seqlock); -+ } -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_tcp_ack.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_tcp_ack.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_tcp_ack.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_tcp_ack.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,111 @@ -+#ifndef _AICWF_TCP_ACK_H_ -+#define _AICWF_TCP_ACK_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#define TCP_ACK_NUM 32 -+#define TCP_ACK_EXIT_VAL 0x800 -+#define TCP_ACK_DROP_CNT 10 -+ -+#define ACK_OLD_TIME 4000 -+#define U32_BEFORE(a, b) ((__s32)((__u32)a - (__u32)b) <= 0) -+ -+#define MAX_TCP_ACK 200 -+/*min window size in KB, it's 256KB*/ -+#define MIN_WIN 256 -+#define SIZE_KB 1024 -+ -+ -+struct msg_buf { -+ //struct list_head list; -+ struct sk_buff *skb; -+ struct rwnx_vif *rwnx_vif; -+ -+ /* data just tx cmd use,not include the head */ -+ /*void *data; -+ void *tran_data; -+ unsigned long pcie_addr; -+ u8 type; -+ u8 mode; -+ u16 len; -+ unsigned long timeout;*/ -+ -+ /*unsigned int fifo_id; -+ struct sprdwl_msg_list *msglist;*/ -+ -+ /*unsigned char buffer_type; -+ struct sprdwl_xmit_msg_list *xmit_msg_list; -+ unsigned char msg_type; -+ -+ unsigned long last_time; -+ u8 ctxt_id;*/ -+ -+}; -+ -+struct tcp_ack_msg { -+ u16 source; -+ u16 dest; -+ s32 saddr; -+ s32 daddr; -+ u32 seq; -+ u16 win; -+}; -+ -+ -+struct tcp_ack_info { -+ int ack_info_num; -+ int busy; -+ int drop_cnt; -+ int psh_flag; -+ u32 psh_seq; -+ u16 win_scale; -+ /* seqlock for ack info */ -+ seqlock_t seqlock; -+ unsigned long last_time; -+ unsigned long timeout; -+ struct timer_list timer; -+ struct msg_buf *msgbuf; -+ struct msg_buf *in_send_msg; -+ struct tcp_ack_msg ack_msg; -+}; -+ -+struct tcp_ack_manage { -+ /* 1 filter */ -+ atomic_t enable; -+ int max_num; -+ int free_index; -+ unsigned long last_time; -+ unsigned long timeout; -+ atomic_t max_drop_cnt; -+ /* lock for tcp ack alloc and free */ -+ spinlock_t lock; -+ struct rwnx_hw *priv; -+ struct tcp_ack_info ack_info[TCP_ACK_NUM]; -+ /*size in KB*/ -+ unsigned int ack_winsize; -+}; -+ -+struct msg_buf *intf_tcp_alloc_msg(struct msg_buf *msg); -+ -+void tcp_ack_init(struct rwnx_hw *priv); -+ -+void tcp_ack_deinit(struct rwnx_hw *priv); -+ -+ -+int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len, unsigned short *win_scale); -+ -+int is_tcp_ack(struct sk_buff *skb, unsigned short *win_scale); -+ -+int filter_send_tcp_ack(struct rwnx_hw *priv, struct msg_buf *msgbuf,unsigned char *buf, unsigned int plen); -+ -+void filter_rx_tcp_ack(struct rwnx_hw *priv,unsigned char *buf, unsigned plen); -+ -+void move_tcpack_msg(struct rwnx_hw *priv, struct msg_buf * msg); -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_txrxif.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_txrxif.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_txrxif.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_txrxif.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,885 @@ -+/** -+ * aicwf_bus.c -+ * -+ * bus function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "lmac_msg.h" -+#include "aicwf_txrxif.h" -+#include "rwnx_platform.h" -+#include "rwnx_defs.h" -+#include "rwnx_msg_rx.h" -+#include "rwnx_rx.h" -+#include "aicwf_rx_prealloc.h" -+#ifdef AICWF_SDIO_SUPPORT -+#include "sdio_host.h" -+#endif -+#include "aic_bsp_export.h" -+ -+#ifdef CONFIG_PREALLOC_RX_SKB -+void aicwf_rxframe_queue_init_2(struct rx_frame_queue *pq, int max_len) -+{ -+ //int prio; -+ -+ memset(pq, 0, offsetof(struct rx_frame_queue, queuelist) + (sizeof(struct list_head))); -+ pq->qmax = (u16)max_len; -+ INIT_LIST_HEAD(&pq->queuelist); -+#if 0 -+ memset(pq, 0, offsetof(struct rx_frame_queue, queuelist) + (sizeof(struct list_head) * num_prio)); -+ pq->num_prio = (u16)num_prio; -+ pq->qmax = (u16)max_len; -+ -+ for (prio = 0; prio < num_prio; prio++) { -+ INIT_LIST_HEAD(&pq->queuelist[prio]); -+ } -+#endif -+} -+ -+//extern struct aic_sdio_dev *g_sdiodev; -+void rxbuff_queue_flush(struct aicwf_rx_priv* rx_priv) -+{ -+ -+ //int prio; -+ struct rx_frame_queue *pq = &rx_priv->rxq; -+ struct list_head *pos; -+ struct list_head *n; -+ struct list_head *head; -+ struct rx_buff *tempbuf = NULL; -+ -+ head = &pq->queuelist; -+ list_for_each_safe(pos, n, head) { -+ tempbuf = list_entry(pos, struct rx_buff, queue); -+ list_del_init(&tempbuf->queue); -+#if 0 -+ rxbuff_free(tempbuf); -+#else -+ aicwf_prealloc_rxbuff_free(tempbuf, &rx_priv->rxbuff_lock); -+#endif -+ pq->qcnt--; -+ } -+} -+#endif -+ -+int aicwf_bus_init(uint bus_hdrlen, struct device *dev) -+{ -+ int ret = 0; -+ struct aicwf_bus *bus_if; -+ -+ if (!dev) { -+ txrx_err("device not found\n"); -+ return -1; -+ } -+ bus_if = dev_get_drvdata(dev); -+ bus_if->cmd_buf = kzalloc(CMD_BUF_MAX, GFP_KERNEL); -+ if (!bus_if->cmd_buf) { -+ ret = -ENOMEM; -+ txrx_err("proto_attach failed\n"); -+ goto fail; -+ } -+ memset(bus_if->cmd_buf, '\0', CMD_BUF_MAX); -+ -+ init_completion(&bus_if->bustx_trgg); -+ init_completion(&bus_if->busrx_trgg); -+ //new oob feature -+ init_completion(&bus_if->busirq_trgg); -+#ifdef AICWF_SDIO_SUPPORT -+ spin_lock_init(&bus_if->bus_priv.sdio->wslock);//AIDEN test -+ bus_if->bustx_thread = kthread_run(sdio_bustx_thread, (void *)bus_if, "aicwf_bustx_thread"); -+ bus_if->busrx_thread = kthread_run(sdio_busrx_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busrx_thread"); -+ //new oob feature -+#ifdef CONFIG_OOB -+ if(bus_if->bus_priv.sdio->oob_enable){ -+ bus_if->busirq_thread = kthread_run(sdio_busirq_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busirq_thread"); -+ } -+#endif //CONFIG_OOB -+#endif -+#ifdef AICWF_USB_SUPPORT -+ bus_if->bustx_thread = kthread_run(usb_bustx_thread, (void *)bus_if, "aicwf_bustx_thread"); -+ bus_if->busrx_thread = kthread_run(usb_busrx_thread, (void *)bus_if->bus_priv.usb->rx_priv, "aicwf_busrx_thread"); -+#endif -+ -+ if (IS_ERR(bus_if->bustx_thread)) { -+ bus_if->bustx_thread = NULL; -+ txrx_err("aicwf_bustx_thread run fail\n"); -+ goto fail; -+ } -+ -+ if (IS_ERR(bus_if->busrx_thread)) { -+ bus_if->busrx_thread = NULL; -+ txrx_err("aicwf_bustx_thread run fail\n"); -+ goto fail; -+ } -+ -+ return ret; -+fail: -+ aicwf_bus_deinit(dev); -+ -+ return ret; -+} -+ -+void aicwf_bus_deinit(struct device *dev) -+{ -+ struct aicwf_bus *bus_if; -+#ifdef AICWF_USB_SUPPORT -+ struct aic_usb_dev *usb; -+#endif -+#ifdef AICWF_SDIO_SUPPORT -+ struct aic_sdio_dev *sdiodev; -+#endif -+ -+ if (!dev) { -+ txrx_err("device not found\n"); -+ return; -+ } -+ AICWFDBG(LOGINFO, "%s Enter\r\n", __func__); -+ bus_if = dev_get_drvdata(dev); -+ aicwf_bus_stop(bus_if); -+ -+#ifdef AICWF_USB_SUPPORT -+ usb = bus_if->bus_priv.usb; -+ if (g_rwnx_plat->enabled) -+ rwnx_platform_deinit(usb->rwnx_hw); -+#endif -+#ifdef AICWF_SDIO_SUPPORT -+ sdiodev = bus_if->bus_priv.sdio; -+ if (g_rwnx_plat && g_rwnx_plat->enabled) { -+ rwnx_platform_deinit(sdiodev->rwnx_hw); -+ } -+#endif -+ -+ if (bus_if->cmd_buf) { -+ kfree(bus_if->cmd_buf); -+ bus_if->cmd_buf = NULL; -+ } -+ -+ if (bus_if->bustx_thread) { -+ complete_all(&bus_if->bustx_trgg); -+ kthread_stop(bus_if->bustx_thread); -+ bus_if->bustx_thread = NULL; -+ } -+ AICWFDBG(LOGINFO, "%s Exit\r\n", __func__); -+} -+ -+void aicwf_frame_tx(void *dev, struct sk_buff *skb) -+{ -+#ifdef AICWF_SDIO_SUPPORT -+ struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev; -+ aicwf_bus_txdata(sdiodev->bus_if, skb); -+#else -+ struct aic_usb_dev *usbdev = (struct aic_usb_dev *)dev; -+ -+ if (!usbdev->state) { -+ txrx_err("down\n"); -+ aicwf_usb_tx_flowctrl(usbdev->rwnx_hw, true); -+ dev_kfree_skb(skb); -+ return; -+ } -+ aicwf_bus_txdata(usbdev->bus_if, skb); -+#endif -+} -+ -+struct aicwf_tx_priv *aicwf_tx_init(void *arg) -+{ -+ struct aicwf_tx_priv *tx_priv; -+ -+ tx_priv = kzalloc(sizeof(struct aicwf_tx_priv), GFP_KERNEL); -+ if (!tx_priv) -+ return NULL; -+ -+#ifdef AICWF_SDIO_SUPPORT -+ tx_priv->sdiodev = (struct aic_sdio_dev *)arg; -+#else -+ tx_priv->usbdev = (struct aic_usb_dev *)arg; -+#endif -+ -+ atomic_set(&tx_priv->aggr_count, 0); -+#ifdef CONFIG_RESV_MEM_SUPPORT -+ tx_priv->aggr_buf = aicbsp_resv_mem_alloc_skb(MAX_AGGR_TXPKT_LEN, AIC_RESV_MEM_TXDATA); -+#else -+ tx_priv->aggr_buf = dev_alloc_skb(MAX_AGGR_TXPKT_LEN); -+#endif -+ if (!tx_priv->aggr_buf) { -+ txrx_err("Alloc bus->txdata_buf failed!\n"); -+ kfree(tx_priv); -+ return NULL; -+ } -+ tx_priv->head = tx_priv->aggr_buf->data; -+ tx_priv->tail = tx_priv->aggr_buf->data; -+ -+ return tx_priv; -+} -+ -+void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv) -+{ -+ if (tx_priv && tx_priv->aggr_buf) { -+#ifdef CONFIG_RESV_MEM_SUPPORT -+ aicbsp_resv_mem_kfree_skb(tx_priv->aggr_buf, AIC_RESV_MEM_TXDATA); -+#else -+ dev_kfree_skb(tx_priv->aggr_buf); -+#endif -+ kfree(tx_priv); -+ } -+} -+ -+#ifdef AICWF_SDIO_SUPPORT -+#ifdef CONFIG_PREALLOC_RX_SKB -+static bool aicwf_another_ptk_1(struct rx_buff *buffer) -+{ -+ u8 *read = buffer->read; -+ u16 aggr_len = 0; -+ -+ BUG_ON((read - buffer->start)%4 != 0); -+ -+ if(read == NULL || read >= buffer->end) { -+ return false; -+ } -+ -+ aggr_len = (*read | (*(read + 1) << 8)); -+ if(aggr_len == 0) { -+ return false; -+ } -+ -+ return true; -+} -+#else -+static bool aicwf_another_ptk(struct sk_buff *skb) -+{ -+ u8 *data; -+ u16 aggr_len = 0; -+ -+ if (skb->data == NULL || skb->len == 0) { -+ return false; -+ } -+ data = skb->data; -+ aggr_len = (*skb->data | (*(skb->data + 1) << 8)); -+ if (aggr_len == 0) { -+ return false; -+ } -+ -+ return true; -+} -+#endif -+#endif -+ -+int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv) -+{ -+#ifdef AICWF_SDIO_SUPPORT -+ int ret = 0; -+ unsigned long flags = 0; -+#ifndef CONFIG_PREALLOC_RX_SKB -+ struct sk_buff *skb = NULL; -+#endif -+ u16 pkt_len = 0; -+ struct sk_buff *skb_inblock = NULL; -+ u16 aggr_len = 0, adjust_len = 0; -+ u8 *data = NULL; -+ u8_l *msg = NULL; -+ #ifdef CONFIG_PREALLOC_RX_SKB -+ struct rx_buff *buffer = NULL; -+ -+ while (1) { -+ spin_lock_irqsave(&rx_priv->rxqlock, flags); -+ if (!rx_priv->rxq.qcnt) { -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ break; -+ } -+ buffer = rxbuff_dequeue(&rx_priv->rxq); -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ if (buffer == NULL) { -+ txrx_err("skb_error\r\n"); -+ break; -+ } -+ while (aicwf_another_ptk_1(buffer)) { -+ data = buffer->read; -+ pkt_len = (*data | (*(data + 1) << 8)); -+ -+ if ((data[2] & SDIO_TYPE_CFG) != SDIO_TYPE_CFG) { // type : data -+ aggr_len = pkt_len + RX_HWHRD_LEN; -+ -+ if (aggr_len & (RX_ALIGNMENT - 1)) -+ adjust_len = roundup(aggr_len, RX_ALIGNMENT); -+ else -+ adjust_len = aggr_len; -+ -+ skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL); -+ if (skb_inblock == NULL) { -+ txrx_err("no more space! skip\n"); -+ buffer->read = buffer->read + adjust_len; -+ continue; -+ } -+ -+ skb_put(skb_inblock, aggr_len); -+ memcpy(skb_inblock->data, data, aggr_len); -+ rwnx_rxdataind_aicwf(rx_priv->sdiodev->rwnx_hw, skb_inblock, (void *)rx_priv); -+ buffer->read = buffer->read + adjust_len; -+ } else { -+ // type : config -+ aggr_len = pkt_len; -+ -+ if (aggr_len & (RX_ALIGNMENT - 1)) -+ adjust_len = roundup(aggr_len, RX_ALIGNMENT); -+ else -+ adjust_len = aggr_len; -+ -+ msg = kmalloc(aggr_len+4, GFP_KERNEL); -+ if (msg == NULL) { -+ txrx_err("no more space for msg!\n"); -+ aicwf_prealloc_rxbuff_free(buffer, &rx_priv->rxbuff_lock); -+ return -EBADE; -+ } -+ -+ memcpy(msg, data, aggr_len + 4); -+ if (((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_CMD_RSP) && (rx_priv->sdiodev->bus_if->state != BUS_DOWN_ST)) -+ rwnx_rx_handle_msg(rx_priv->sdiodev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4)); -+ -+ if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_DATA_CFM) -+ aicwf_sdio_host_tx_cfm_handler(&(rx_priv->sdiodev->rwnx_hw->sdio_env), (u32 *)(msg + 4)); -+ -+ if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_PRINT) -+ rwnx_rx_handle_print(rx_priv->sdiodev->rwnx_hw, msg + 4, aggr_len); -+ -+ buffer->read = buffer->read + (adjust_len + 4); -+ kfree(msg); -+ } -+ } -+ -+ aicwf_prealloc_rxbuff_free(buffer, &rx_priv->rxbuff_lock); -+ -+ atomic_dec(&rx_priv->rx_cnt); -+ } -+ -+ #else -+ -+ while (1) { -+ spin_lock_irqsave(&rx_priv->rxqlock, flags); -+ if (aicwf_is_framequeue_empty(&rx_priv->rxq)) { -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ break; -+ } -+ skb = aicwf_frame_dequeue(&rx_priv->rxq); -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ if (skb == NULL) { -+ txrx_err("skb_error\r\n"); -+ break; -+ } -+ while (aicwf_another_ptk(skb)) { -+ data = skb->data; -+ pkt_len = (*skb->data | (*(skb->data + 1) << 8)); -+ -+ if ((skb->data[2] & SDIO_TYPE_CFG) != SDIO_TYPE_CFG) { // type : data -+ aggr_len = pkt_len + RX_HWHRD_LEN; -+ -+ if (aggr_len & (RX_ALIGNMENT - 1)) -+ adjust_len = roundup(aggr_len, RX_ALIGNMENT); -+ else -+ adjust_len = aggr_len; -+ -+ skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL); -+ if (skb_inblock == NULL) { -+ txrx_err("no more space! skip\n"); -+ skb_pull(skb, adjust_len); -+ continue; -+ } -+ -+ skb_put(skb_inblock, aggr_len); -+ memcpy(skb_inblock->data, data, aggr_len); -+ rwnx_rxdataind_aicwf(rx_priv->sdiodev->rwnx_hw, skb_inblock, (void *)rx_priv); -+ skb_pull(skb, adjust_len); -+ } else { -+ // type : config -+ aggr_len = pkt_len; -+ -+ if (aggr_len & (RX_ALIGNMENT - 1)) -+ adjust_len = roundup(aggr_len, RX_ALIGNMENT); -+ else -+ adjust_len = aggr_len; -+ -+ msg = kmalloc(aggr_len+4, GFP_KERNEL); -+ if (msg == NULL) { -+ txrx_err("no more space for msg!\n"); -+ aicwf_dev_skb_free(skb); -+ return -EBADE; -+ } -+ -+ memcpy(msg, data, aggr_len + 4); -+ if (((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_CMD_RSP) && (rx_priv->sdiodev->bus_if->state != BUS_DOWN_ST)) -+ rwnx_rx_handle_msg(rx_priv->sdiodev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4)); -+ -+ if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_DATA_CFM) -+ aicwf_sdio_host_tx_cfm_handler(&(rx_priv->sdiodev->rwnx_hw->sdio_env), (u32 *)(msg + 4)); -+ -+ if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_PRINT) -+ rwnx_rx_handle_print(rx_priv->sdiodev->rwnx_hw, msg + 4, aggr_len); -+ -+ skb_pull(skb, adjust_len+4); -+ kfree(msg); -+ } -+ } -+ -+ dev_kfree_skb(skb); -+ atomic_dec(&rx_priv->rx_cnt); -+ } -+ #endif -+ -+ #if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwr_stctl(rx_priv->sdiodev, SDIO_ACTIVE_ST); -+ #endif -+ -+ return ret; -+#else //AICWF_USB_SUPPORT -+ int ret = 0; -+ unsigned long flags = 0; -+ struct sk_buff *skb = NULL; /* Packet for event or data frames */ -+ u16 pkt_len = 0; -+ struct sk_buff *skb_inblock = NULL; -+ u16 aggr_len = 0, adjust_len = 0; -+ u8 *data = NULL; -+ u8_l *msg = NULL; -+ -+ while (1) { -+ spin_lock_irqsave(&rx_priv->rxqlock, flags); -+ if (aicwf_is_framequeue_empty(&rx_priv->rxq)) { -+ usb_info("no more rxdata\n"); -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ break; -+ } -+ skb = aicwf_frame_dequeue(&rx_priv->rxq); -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ if (skb == NULL) { -+ txrx_err("skb_error\r\n"); -+ break; -+ } -+ data = skb->data; -+ pkt_len = (*skb->data | (*(skb->data + 1) << 8)); -+ //printk("p:%d, s:%d , %x\n", pkt_len, skb->len, data[2]); -+ if (pkt_len > 1600) { -+ dev_kfree_skb(skb); -+ atomic_dec(&rx_priv->rx_cnt); -+ continue; -+ } -+ -+ if ((skb->data[2] & USB_TYPE_CFG) != USB_TYPE_CFG) { // type : data -+ aggr_len = pkt_len + RX_HWHRD_LEN; -+ if (aggr_len & (RX_ALIGNMENT - 1)) -+ adjust_len = roundup(aggr_len, RX_ALIGNMENT); -+ else -+ adjust_len = aggr_len; -+ -+ skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL);//8 is for ccmp mic or wep icv -+ if (skb_inblock == NULL) { -+ txrx_err("no more space! skip!\n"); -+ skb_pull(skb, adjust_len); -+ continue; -+ } -+ -+ skb_put(skb_inblock, aggr_len); -+ memcpy(skb_inblock->data, data, aggr_len); -+ rwnx_rxdataind_aicwf(rx_priv->usbdev->rwnx_hw, skb_inblock, (void *)rx_priv); -+ ///TODO: here need to add rx data process -+ -+ skb_pull(skb, adjust_len); -+ } else { // type : config -+ aggr_len = pkt_len; -+ if (aggr_len & (RX_ALIGNMENT - 1)) -+ adjust_len = roundup(aggr_len, RX_ALIGNMENT); -+ else -+ adjust_len = aggr_len; -+ -+ msg = kmalloc(aggr_len+4, GFP_KERNEL); -+ if (msg == NULL) { -+ txrx_err("no more space for msg!\n"); -+ aicwf_dev_skb_free(skb); -+ return -EBADE; -+ } -+ memcpy(msg, data, aggr_len + 4); -+ if ((*(msg + 2) & 0x7f) == USB_TYPE_CFG_CMD_RSP) -+ rwnx_rx_handle_msg(rx_priv->usbdev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4)); -+ -+ if ((*(msg + 2) & 0x7f) == USB_TYPE_CFG_DATA_CFM) -+ aicwf_usb_host_tx_cfm_handler(&(rx_priv->usbdev->rwnx_hw->usb_env), (u32 *)(msg + 4)); -+ skb_pull(skb, adjust_len + 4); -+ kfree(msg); -+ } -+ -+ dev_kfree_skb(skb); -+ atomic_dec(&rx_priv->rx_cnt); -+ } -+ -+ return ret; -+#endif //AICWF_SDIO_SUPPORT -+} -+ -+static struct recv_msdu *aicwf_rxframe_queue_init(struct list_head *q, int qsize) -+{ -+ int i; -+ struct recv_msdu *req, *reqs; -+ -+ reqs = vmalloc(qsize*sizeof(struct recv_msdu)); -+ if (reqs == NULL) -+ return NULL; -+ -+ req = reqs; -+ for (i = 0; i < qsize; i++) { -+ INIT_LIST_HEAD(&req->rxframe_list); -+ list_add(&req->rxframe_list, q); -+ req++; -+ } -+ -+ return reqs; -+} -+ -+struct aicwf_rx_priv *aicwf_rx_init(void *arg) -+{ -+ struct aicwf_rx_priv *rx_priv; -+ rx_priv = kzalloc(sizeof(struct aicwf_rx_priv), GFP_KERNEL); -+ if (!rx_priv) -+ return NULL; -+ -+#ifdef AICWF_SDIO_SUPPORT -+ rx_priv->sdiodev = (struct aic_sdio_dev *)arg; -+#else -+ rx_priv->usbdev = (struct aic_usb_dev *)arg; -+#endif -+ -+ #ifdef CONFIG_PREALLOC_RX_SKB -+ aicwf_rxframe_queue_init_2(&rx_priv->rxq, MAX_RXQLEN); -+ #else -+ aicwf_frame_queue_init(&rx_priv->rxq, 1, MAX_RXQLEN); -+ #endif -+ spin_lock_init(&rx_priv->rxqlock); -+ #ifdef CONFIG_PREALLOC_RX_SKB -+ spin_lock_init(&rx_priv->rxbuff_lock); -+ aicwf_prealloc_init(); -+ #endif -+ atomic_set(&rx_priv->rx_cnt, 0); -+ -+#ifdef AICWF_RX_REORDER -+ INIT_LIST_HEAD(&rx_priv->rxframes_freequeue); -+ spin_lock_init(&rx_priv->freeq_lock); -+ rx_priv->recv_frames = aicwf_rxframe_queue_init(&rx_priv->rxframes_freequeue, MAX_REORD_RXFRAME); -+ if (!rx_priv->recv_frames) { -+ txrx_err("no enough buffer for free recv frame queue!\n"); -+ kfree(rx_priv); -+ return NULL; -+ } -+ spin_lock_init(&rx_priv->stas_reord_lock); -+ INIT_LIST_HEAD(&rx_priv->stas_reord_list); -+#endif -+ -+ return rx_priv; -+} -+ -+ -+static void aicwf_recvframe_queue_deinit(struct list_head *q) -+{ -+ struct recv_msdu *req, *next; -+ -+ list_for_each_entry_safe(req, next, q, rxframe_list) { -+ list_del_init(&req->rxframe_list); -+ } -+} -+ -+void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv) -+{ -+#ifdef AICWF_RX_REORDER -+ struct reord_ctrl_info *reord_info, *tmp; -+ -+ AICWFDBG(LOGINFO, "%s\n", __func__); -+ -+ spin_lock_bh(&rx_priv->stas_reord_lock); -+ list_for_each_entry_safe(reord_info, tmp, -+ &rx_priv->stas_reord_list, list) { -+ reord_deinit_sta(rx_priv, reord_info); -+ } -+ spin_unlock_bh(&rx_priv->stas_reord_lock); -+#endif -+ -+#ifdef AICWF_SDIO_SUPPORT -+ AICWFDBG(LOGINFO, "sdio rx thread\n"); -+ if (rx_priv->sdiodev->bus_if->busrx_thread) { -+ complete_all(&rx_priv->sdiodev->bus_if->busrx_trgg); -+ kthread_stop(rx_priv->sdiodev->bus_if->busrx_thread); -+ rx_priv->sdiodev->bus_if->busrx_thread = NULL; -+ } -+#ifdef CONFIG_OOB -+ if(rx_priv->sdiodev->oob_enable){ -+ //new oob feature -+ if (rx_priv->sdiodev->bus_if->busirq_thread) { -+ complete_all(&rx_priv->sdiodev->bus_if->busirq_trgg); -+ kthread_stop(rx_priv->sdiodev->bus_if->busirq_thread); -+ rx_priv->sdiodev->bus_if->busirq_thread = NULL; -+ } -+ } -+#endif //CONFIG_OOB -+#endif -+#ifdef AICWF_USB_SUPPORT -+ if (rx_priv->usbdev->bus_if->busrx_thread) { -+ complete_all(&rx_priv->usbdev->bus_if->busrx_trgg); -+ kthread_stop(rx_priv->usbdev->bus_if->busrx_thread); -+ rx_priv->usbdev->bus_if->busrx_thread = NULL; -+ } -+#endif -+ -+ #ifdef CONFIG_PREALLOC_RX_SKB -+ rxbuff_queue_flush(rx_priv); -+ #else -+ aicwf_frame_queue_flush(&rx_priv->rxq); -+ #endif -+ -+#ifdef AICWF_RX_REORDER -+ aicwf_recvframe_queue_deinit(&rx_priv->rxframes_freequeue); -+ if (rx_priv->recv_frames) -+ vfree(rx_priv->recv_frames); -+#endif -+ -+ #ifdef CONFIG_PREALLOC_RX_SKB -+ aicwf_prealloc_exit(); -+ #endif -+ kfree(rx_priv); -+ -+ AICWFDBG(LOGINFO, "%s exit \n", __func__); -+} -+ -+bool aicwf_rxframe_enqueue(struct device *dev, struct frame_queue *q, struct sk_buff *pkt) -+{ -+ return aicwf_frame_enq(dev, q, pkt, 0); -+} -+ -+ -+void aicwf_dev_skb_free(struct sk_buff *skb) -+{ -+ if (!skb) -+ return; -+ -+ dev_kfree_skb_any(skb); -+} -+ -+static struct sk_buff *aicwf_frame_queue_penq(struct frame_queue *pq, int prio, struct sk_buff *p) -+{ -+ struct sk_buff_head *q; -+ -+ if (pq->queuelist[prio].qlen >= pq->qmax) -+ return NULL; -+ -+ q = &pq->queuelist[prio]; -+ __skb_queue_tail(q, p); -+ pq->qcnt++; -+ if (pq->hi_prio < prio) -+ pq->hi_prio = (u16)prio; -+ -+ return p; -+} -+ -+void aicwf_frame_queue_flush(struct frame_queue *pq) -+{ -+ int prio; -+ struct sk_buff_head *q; -+ struct sk_buff *p, *next; -+ -+ for (prio = 0; prio < pq->num_prio; prio++) { -+ q = &pq->queuelist[prio]; -+ skb_queue_walk_safe(q, p, next) { -+ skb_unlink(p, q); -+ aicwf_dev_skb_free(p); -+ pq->qcnt--; -+ } -+ } -+} -+ -+void aicwf_frame_queue_init(struct frame_queue *pq, int num_prio, int max_len) -+{ -+ int prio; -+ -+ memset(pq, 0, offsetof(struct frame_queue, queuelist) + (sizeof(struct sk_buff_head) * num_prio)); -+ pq->num_prio = (u16)num_prio; -+ pq->qmax = (u16)max_len; -+ -+ for (prio = 0; prio < num_prio; prio++) { -+ skb_queue_head_init(&pq->queuelist[prio]); -+ } -+} -+ -+struct sk_buff *aicwf_frame_queue_peek_tail(struct frame_queue *pq, int *prio_out) -+{ -+ int prio; -+ -+ if (pq->qcnt == 0) -+ return NULL; -+ -+ for (prio = 0; prio < pq->hi_prio; prio++) -+ if (!skb_queue_empty(&pq->queuelist[prio])) -+ break; -+ -+ if (prio_out) -+ *prio_out = prio; -+ -+ return skb_peek_tail(&pq->queuelist[prio]); -+} -+ -+bool aicwf_is_framequeue_empty(struct frame_queue *pq) -+{ -+ int prio, len = 0; -+ -+ for (prio = 0; prio <= pq->hi_prio; prio++) -+ len += pq->queuelist[prio].qlen; -+ -+ if (len > 0) -+ return false; -+ else -+ return true; -+} -+ -+struct sk_buff *aicwf_frame_dequeue(struct frame_queue *pq) -+{ -+ struct sk_buff_head *q; -+ struct sk_buff *p; -+ int prio; -+ -+ if (pq->qcnt == 0) -+ return NULL; -+ -+ while ((prio = pq->hi_prio) > 0 && skb_queue_empty(&pq->queuelist[prio])) -+ pq->hi_prio--; -+ -+ q = &pq->queuelist[prio]; -+ p = __skb_dequeue(q); -+ if (p == NULL) -+ return NULL; -+ -+ pq->qcnt--; -+ -+ return p; -+} -+#if 0 -+static struct sk_buff *aicwf_skb_dequeue_tail(struct frame_queue *pq, int prio) -+{ -+ struct sk_buff_head *q = &pq->queuelist[prio]; -+ struct sk_buff *p = skb_dequeue_tail(q); -+ -+ if (!p) -+ return NULL; -+ -+ pq->qcnt--; -+ return p; -+} -+#endif -+ -+bool aicwf_frame_enq(struct device *dev, struct frame_queue *q, struct sk_buff *pkt, int prio) -+{ -+ #if 0 -+ struct sk_buff *p = NULL; -+ int prio_modified = -1; -+ -+ if (q->queuelist[prio].qlen < q->qmax && q->qcnt < q->qmax) { -+ aicwf_frame_queue_penq(q, prio, pkt); -+ return true; -+ } -+ if (q->queuelist[prio].qlen >= q->qmax) { -+ prio_modified = prio; -+ } else if (q->qcnt >= q->qmax) { -+ p = aicwf_frame_queue_peek_tail(q, &prio_modified); -+ if (prio_modified > prio) -+ return false; -+ } -+ -+ if (prio_modified >= 0) { -+ if (prio_modified == prio) -+ return false; -+ -+ p = aicwf_skb_dequeue_tail(q, prio_modified); -+ aicwf_dev_skb_free(p); -+ -+ p = aicwf_frame_queue_penq(q, prio_modified, pkt); -+ if (p == NULL) -+ txrx_err("failed\n"); -+ } -+ -+ return p != NULL; -+ #else -+ if (q->queuelist[prio].qlen < q->qmax && q->qcnt < q->qmax) { -+ aicwf_frame_queue_penq(q, prio, pkt); -+ return true; -+ } else -+ return false; -+ #endif -+} -+ -+#ifdef CONFIG_PREALLOC_RX_SKB -+void rxbuff_free(struct rx_buff *rxbuff) -+{ -+ kfree(rxbuff->data); -+ kfree(rxbuff); -+} -+ -+struct rx_buff *rxbuff_queue_penq(struct rx_frame_queue *pq, struct rx_buff *p) -+{ -+ -+ struct list_head *q; -+ if (pq->qcnt >= pq->qmax) -+ return NULL; -+ -+ q = &pq->queuelist; -+ list_add_tail(&p->queue,q); -+ -+ pq->qcnt++; -+ -+ return p; -+} -+ -+struct rx_buff *rxbuff_dequeue(struct rx_frame_queue *pq) -+{ -+ struct rx_buff *p = NULL; -+ -+ if (pq->qcnt == 0) { -+ printk("%s %d, rxq is empty\n", __func__, __LINE__); -+ return NULL; -+ } -+ -+ if(list_empty(&pq->queuelist)) { -+ printk("%s %d, rxq is empty\n", __func__, __LINE__); -+ return NULL; -+ } else { -+ p = list_first_entry(&pq->queuelist, struct rx_buff, queue); -+ list_del_init(&p->queue); -+ pq->qcnt--; -+ } -+ -+ return p; -+} -+ -+bool aicwf_rxbuff_enqueue(struct device *dev, struct rx_frame_queue *rxq, struct rx_buff *pkt) -+{ -+// struct rx_buff *p = NULL; -+ -+ if ((rxq == NULL) || (pkt == NULL)) { -+ printk("%s %d, rxq or pkt is NULL\n", __func__, __LINE__); -+ return false; -+ } -+ -+ if (rxq->qcnt < rxq->qmax) { -+ if (rxbuff_queue_penq(rxq, pkt)) { -+ return true; -+ } else { -+ printk("%s %d, rxbuff enqueue fail\n", __func__, __LINE__); -+ return false; -+ } -+ } else { -+ printk("%s %d, rxq or pkt is full\n", __func__, __LINE__); -+ return false; -+ } -+} -+#endif -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_txrxif.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_txrxif.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_txrxif.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_txrxif.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,262 @@ -+/** -+ * aicwf_txrxif.h -+ * -+ * bus function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+#ifndef _AICWF_TXRXIF_H_ -+#define _AICWF_TXRXIF_H_ -+ -+#include -+#include -+#include "ipc_shared.h" -+#include "aicwf_rx_prealloc.h" -+#ifdef AICWF_SDIO_SUPPORT -+#include "aicwf_sdio.h" -+#else -+#include "aicwf_usb.h" -+#endif -+ -+#define CMD_BUF_MAX 1536 -+#define TXPKT_BLOCKSIZE 512 -+#define MAX_AGGR_TXPKT_LEN (1536*64) -+#define CMD_TX_TIMEOUT 5000 -+#define TX_ALIGNMENT 4 -+ -+#define RX_HWHRD_LEN 60 //58->60 word allined -+#define CCMP_OR_WEP_INFO 8 -+#define MAX_RXQLEN 2000 -+#define RX_ALIGNMENT 4 -+ -+#define DEBUG_ERROR_LEVEL 0 -+#define DEBUG_DEBUG_LEVEL 1 -+#define DEBUG_INFO_LEVEL 2 -+ -+#define DBG_LEVEL DEBUG_DEBUG_LEVEL -+ -+#define txrx_err(fmt, ...) pr_err("txrx_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__) -+#define sdio_err(fmt, ...) pr_err("sdio_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__) -+#define usb_err(fmt, ...) pr_err("usb_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__) -+#if DBG_LEVEL >= DEBUG_DEBUG_LEVEL -+#define txrx_dbg(fmt, ...) printk("txrx: " fmt, ##__VA_ARGS__) -+#define sdio_dbg(fmt, ...) printk("aicsdio: " fmt, ##__VA_ARGS__) -+#define usb_dbg(fmt, ...) printk("aicusb: " fmt, ##__VA_ARGS__) -+#else -+#define txrx_dbg(fmt, ...) -+#define sdio_dbg(fmt, ...) -+#define usb_dbg(fmt, ...) -+#endif -+#if DBG_LEVEL >= DEBUG_INFO_LEVEL -+#define txrx_info(fmt, ...) printk("aicsdio: " fmt, ##__VA_ARGS__) -+#define sdio_info(fmt, ...) printk("aicsdio: " fmt, ##__VA_ARGS__) -+#define usb_info(fmt, ...) printk("aicusb: " fmt, ##__VA_ARGS__) -+#else -+#define txrx_info(fmt, ...) -+#define sdio_info(fmt, ...) -+#define usb_info(fmt, ...) -+#endif -+ -+enum aicwf_bus_state { -+ BUS_DOWN_ST, -+ BUS_UP_ST -+}; -+ -+struct aicwf_bus_ops { -+ int (*start) (struct device *dev); -+ void (*stop) (struct device *dev); -+ int (*txdata) (struct device *dev, struct sk_buff *skb); -+ int (*txmsg) (struct device *dev, u8 *msg, uint len); -+}; -+ -+struct frame_queue { -+ u16 num_prio; -+ u16 hi_prio; -+ u16 qmax; /* max number of queued frames */ -+ u16 qcnt; -+ struct sk_buff_head queuelist[8]; -+}; -+ -+#ifdef CONFIG_PREALLOC_RX_SKB -+struct rx_frame_queue { -+ u16 qmax; /* max number of queued frames */ -+ u16 qcnt; -+ struct list_head queuelist; -+}; -+#endif -+ -+struct aicwf_bus { -+ union { -+ struct aic_sdio_dev *sdio; -+ struct aic_usb_dev *usb; -+ } bus_priv; -+ struct device *dev; -+ struct aicwf_bus_ops *ops; -+ enum aicwf_bus_state state; -+ u8 *cmd_buf; -+ struct completion bustx_trgg; -+ struct completion busrx_trgg; -+ struct completion busirq_trgg;//new oob feature -+ struct task_struct *bustx_thread; -+ struct task_struct *busrx_thread; -+ struct task_struct *busirq_thread;//new oob feature -+}; -+ -+struct aicwf_tx_priv { -+#ifdef AICWF_SDIO_SUPPORT -+ struct aic_sdio_dev *sdiodev; -+ int fw_avail_bufcnt; -+ //for cmd tx -+ u8 *cmd_buf; -+ uint cmd_len; -+ bool cmd_txstate; -+ bool cmd_tx_succ; -+ struct semaphore cmd_txsema; -+ wait_queue_head_t cmd_txdone_wait; -+ //for data tx -+ atomic_t tx_pktcnt; -+ -+ struct frame_queue txq; -+ spinlock_t txqlock; -+ struct semaphore txctl_sema; -+#endif -+#ifdef AICWF_USB_SUPPORT -+ struct aic_usb_dev *usbdev; -+#endif -+ struct sk_buff *aggr_buf; -+ atomic_t aggr_count; -+ u8 *head; -+ u8 *tail; -+}; -+ -+ -+#define DEFRAG_MAX_WAIT 40 //100 -+#ifdef AICWF_RX_REORDER -+#define MAX_REORD_RXFRAME 250 -+#define REORDER_UPDATE_TIME 50 -+#define AICWF_REORDER_WINSIZE 64 -+#define SN_LESS(a, b) (((a-b)&0x800) != 0) -+#define SN_EQUAL(a, b) (a == b) -+ -+struct reord_ctrl { -+ struct aicwf_rx_priv *rx_priv; -+ u8 enable; -+ u16 ind_sn; -+ u8 wsize_b; -+ spinlock_t reord_list_lock; -+ struct list_head reord_list; -+ struct timer_list reord_timer; -+ struct work_struct reord_timer_work; -+}; -+ -+struct reord_ctrl_info { -+ u8 mac_addr[6]; -+ struct reord_ctrl preorder_ctrl[8]; -+ struct list_head list; -+}; -+ -+struct recv_msdu { -+ struct sk_buff *pkt; -+ u8 tid; -+ u16 seq_num; -+ u8 forward; -+ //uint len; -+ u32 is_amsdu; -+ u8 *rx_data; -+ //for pending rx reorder list -+ struct list_head reord_pending_list; -+ //for total frame list, when rxframe from busif, dequeue, when submit frame to net, enqueue -+ struct list_head rxframe_list; -+ struct reord_ctrl *preorder_ctrl; -+}; -+#endif -+ -+struct aicwf_rx_priv { -+#ifdef AICWF_SDIO_SUPPORT -+ struct aic_sdio_dev *sdiodev; -+#endif -+#ifdef AICWF_USB_SUPPORT -+ struct aic_usb_dev *usbdev; -+#endif -+ -+ void *rwnx_vif; -+ atomic_t rx_cnt; -+ u32 data_len; -+ spinlock_t rxqlock; -+ #ifdef CONFIG_PREALLOC_RX_SKB -+ struct rx_frame_queue rxq; -+ #else -+ struct frame_queue rxq; -+ #endif -+ -+#ifdef AICWF_RX_REORDER -+ spinlock_t freeq_lock; -+ struct list_head rxframes_freequeue; -+ struct list_head stas_reord_list; -+ spinlock_t stas_reord_lock; -+ struct recv_msdu *recv_frames; -+#endif -+#ifdef CONFIG_PREALLOC_RX_SKB -+ spinlock_t rxbuff_lock; -+#endif -+}; -+ -+static inline int aicwf_bus_start(struct aicwf_bus *bus) -+{ -+ return bus->ops->start(bus->dev); -+} -+ -+static inline void aicwf_bus_stop(struct aicwf_bus *bus) -+{ -+ bus->ops->stop(bus->dev); -+} -+ -+static inline int aicwf_bus_txdata(struct aicwf_bus *bus, struct sk_buff *skb) -+{ -+ return bus->ops->txdata(bus->dev, skb); -+} -+ -+static inline int aicwf_bus_txmsg(struct aicwf_bus *bus, u8 *msg, uint len) -+{ -+ return bus->ops->txmsg(bus->dev, msg, len); -+} -+ -+static inline void aicwf_sched_timeout(u32 millisec) -+{ -+ ulong timeout = 0, expires = 0; -+ expires = jiffies + msecs_to_jiffies(millisec); -+ timeout = millisec; -+ -+ while (timeout) { -+ timeout = schedule_timeout(timeout); -+ if (time_after(jiffies, expires)) -+ break; -+ } -+} -+ -+int aicwf_bus_init(uint bus_hdrlen, struct device *dev); -+void aicwf_bus_deinit(struct device *dev); -+void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv); -+void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv); -+struct aicwf_tx_priv *aicwf_tx_init(void *arg); -+struct aicwf_rx_priv *aicwf_rx_init(void *arg); -+void aicwf_frame_queue_init(struct frame_queue *pq, int num_prio, int max_len); -+void aicwf_frame_queue_flush(struct frame_queue *pq); -+bool aicwf_frame_enq(struct device *dev, struct frame_queue *q, struct sk_buff *pkt, int prio); -+bool aicwf_rxframe_enqueue(struct device *dev, struct frame_queue *q, struct sk_buff *pkt); -+bool aicwf_is_framequeue_empty(struct frame_queue *pq); -+void aicwf_frame_tx(void *dev, struct sk_buff *skb); -+void aicwf_dev_skb_free(struct sk_buff *skb); -+struct sk_buff *aicwf_frame_dequeue(struct frame_queue *pq); -+struct sk_buff *aicwf_frame_queue_peek_tail(struct frame_queue *pq, int *prio_out); -+#ifdef CONFIG_PREALLOC_RX_SKB -+void rxbuff_queue_flush(struct aicwf_rx_priv* rx_priv); -+void aicwf_rxframe_queue_init_2(struct rx_frame_queue *pq, int max_len); -+void rxbuff_free(struct rx_buff *rxbuff); -+struct rx_buff *rxbuff_dequeue(struct rx_frame_queue *pq); -+bool aicwf_rxbuff_enqueue(struct device *dev, struct rx_frame_queue *rxq, struct rx_buff *pkt); -+extern struct aicwf_rx_buff_list aic_rx_buff_list; -+#endif -+ -+#endif /* _AICWF_TXRXIF_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_usb.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_usb.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_usb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_usb.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,957 @@ -+/** -+ * aicwf_usb.c -+ * -+ * USB function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+#include -+#include -+#include "aicwf_txrxif.h" -+#include "aicwf_usb.h" -+#include "rwnx_tx.h" -+#include "rwnx_defs.h" -+#include "usb_host.h" -+#include "rwnx_platform.h" -+ -+void aicwf_usb_tx_flowctrl(struct rwnx_hw *rwnx_hw, bool state) -+{ -+ struct rwnx_vif *rwnx_vif; -+ list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) { -+ if (!rwnx_vif->up) -+ continue; -+ if (!rwnx_vif->ndev) -+ continue; -+ if (state) -+ netif_stop_queue(rwnx_vif->ndev); -+ else -+ netif_wake_queue(rwnx_vif->ndev); -+ } -+} -+ -+static struct aicwf_usb_buf *aicwf_usb_tx_dequeue(struct aic_usb_dev *usb_dev, -+ struct list_head *q, int *counter, spinlock_t *qlock) -+{ -+ unsigned long flags; -+ struct aicwf_usb_buf *usb_buf; -+ -+ spin_lock_irqsave(qlock, flags); -+ if (list_empty(q)) { -+ usb_buf = NULL; -+ } else { -+ usb_buf = list_first_entry(q, struct aicwf_usb_buf, list); -+ list_del_init(&usb_buf->list); -+ if (counter) -+ (*counter)--; -+ } -+ spin_unlock_irqrestore(qlock, flags); -+ return usb_buf; -+} -+ -+static void aicwf_usb_tx_queue(struct aic_usb_dev *usb_dev, -+ struct list_head *q, struct aicwf_usb_buf *usb_buf, int *counter, -+ spinlock_t *qlock) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(qlock, flags); -+ list_add_tail(&usb_buf->list, q); -+ (*counter)++; -+ spin_unlock_irqrestore(qlock, flags); -+} -+ -+static struct aicwf_usb_buf *aicwf_usb_rx_buf_get(struct aic_usb_dev *usb_dev) -+{ -+ unsigned long flags; -+ struct aicwf_usb_buf *usb_buf; -+ -+ spin_lock_irqsave(&usb_dev->rx_free_lock, flags); -+ if (list_empty(&usb_dev->rx_free_list)) { -+ usb_buf = NULL; -+ } else { -+ usb_buf = list_first_entry(&usb_dev->rx_free_list, struct aicwf_usb_buf, list); -+ list_del_init(&usb_buf->list); -+ } -+ spin_unlock_irqrestore(&usb_dev->rx_free_lock, flags); -+ return usb_buf; -+} -+ -+static void aicwf_usb_rx_buf_put(struct aic_usb_dev *usb_dev, struct aicwf_usb_buf *usb_buf) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&usb_dev->rx_free_lock, flags); -+ list_add_tail(&usb_buf->list, &usb_dev->rx_free_list); -+ spin_unlock_irqrestore(&usb_dev->rx_free_lock, flags); -+} -+ -+static void aicwf_usb_tx_complete(struct urb *urb) -+{ -+ unsigned long flags; -+ struct aicwf_usb_buf *usb_buf = (struct aicwf_usb_buf *) urb->context; -+ struct aic_usb_dev *usb_dev = usb_buf->usbdev; -+ struct sk_buff *skb; -+ u8 *buf; -+ -+ if (usb_buf->cfm == false) { -+ skb = usb_buf->skb; -+ } else { -+ buf = (u8 *)usb_buf->skb; -+ } -+ -+ if (usb_buf->cfm == false) { -+ dev_kfree_skb_any(skb); -+ } else { -+ kfree(buf); -+ } -+ usb_buf->skb = NULL; -+ -+ aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf, -+ &usb_dev->tx_free_count, &usb_dev->tx_free_lock); -+ -+ spin_lock_irqsave(&usb_dev->tx_flow_lock, flags); -+ if (usb_dev->tx_free_count > AICWF_USB_TX_HIGH_WATER) { -+ if (usb_dev->tbusy) { -+ usb_dev->tbusy = false; -+ aicwf_usb_tx_flowctrl(usb_dev->rwnx_hw, false); -+ } -+ } -+ spin_unlock_irqrestore(&usb_dev->tx_flow_lock, flags); -+ } -+ -+static void aicwf_usb_rx_complete(struct urb *urb) -+{ -+ struct aicwf_usb_buf *usb_buf = (struct aicwf_usb_buf *) urb->context; -+ struct aic_usb_dev *usb_dev = usb_buf->usbdev; -+ struct aicwf_rx_priv *rx_priv = usb_dev->rx_priv; -+ struct sk_buff *skb = NULL; -+ unsigned long flags = 0; -+ -+ skb = usb_buf->skb; -+ usb_buf->skb = NULL; -+ -+ if (urb->actual_length > urb->transfer_buffer_length) { -+ aicwf_dev_skb_free(skb); -+ aicwf_usb_rx_buf_put(usb_dev, usb_buf); -+ schedule_work(&usb_dev->rx_urb_work); -+ return; -+ } -+ -+ if (urb->status != 0 || !urb->actual_length) { -+ aicwf_dev_skb_free(skb); -+ aicwf_usb_rx_buf_put(usb_dev, usb_buf); -+ schedule_work(&usb_dev->rx_urb_work); -+ return; -+ } -+ -+ if (usb_dev->state == USB_UP_ST) { -+ skb_put(skb, urb->actual_length); -+ -+ spin_lock_irqsave(&rx_priv->rxqlock, flags); -+ if (!aicwf_rxframe_enqueue(usb_dev->dev, &rx_priv->rxq, skb)) { -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ usb_err("rx_priv->rxq is over flow!!!\n"); -+ aicwf_dev_skb_free(skb); -+ aicwf_usb_rx_buf_put(usb_dev, usb_buf); -+ return; -+ } -+ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); -+ atomic_inc(&rx_priv->rx_cnt); -+ complete(&rx_priv->usbdev->bus_if->busrx_trgg); -+ aicwf_usb_rx_buf_put(usb_dev, usb_buf); -+ -+ schedule_work(&usb_dev->rx_urb_work); -+ } else { -+ aicwf_dev_skb_free(skb); -+ aicwf_usb_rx_buf_put(usb_dev, usb_buf); -+ } -+} -+ -+static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev, -+ struct aicwf_usb_buf *usb_buf) -+{ -+ struct sk_buff *skb; -+ int ret; -+ -+ if (!usb_buf || !usb_dev) -+ return -1; -+ -+ if (usb_dev->state != USB_UP_ST) { -+ usb_err("usb state is not up!\n"); -+ aicwf_usb_rx_buf_put(usb_dev, usb_buf); -+ return -1; -+ } -+ -+ skb = __dev_alloc_skb(AICWF_USB_MAX_PKT_SIZE, GFP_KERNEL); -+ if (!skb) { -+ aicwf_usb_rx_buf_put(usb_dev, usb_buf); -+ return -1; -+ } -+ -+ usb_buf->skb = skb; -+ -+ usb_fill_bulk_urb(usb_buf->urb, -+ usb_dev->udev, -+ usb_dev->bulk_in_pipe, -+ skb->data, skb_tailroom(skb), aicwf_usb_rx_complete, usb_buf); -+ -+ usb_buf->usbdev = usb_dev; -+ -+ usb_anchor_urb(usb_buf->urb, &usb_dev->rx_submitted); -+ ret = usb_submit_urb(usb_buf->urb, GFP_ATOMIC); -+ if (ret) { -+ usb_err("usb submit rx urb fail:%d\n", ret); -+ usb_unanchor_urb(usb_buf->urb); -+ aicwf_dev_skb_free(usb_buf->skb); -+ usb_buf->skb = NULL; -+ aicwf_usb_rx_buf_put(usb_dev, usb_buf); -+ -+ msleep(100); -+ } -+ return 0; -+} -+ -+static void aicwf_usb_rx_submit_all_urb(struct aic_usb_dev *usb_dev) -+{ -+ struct aicwf_usb_buf *usb_buf; -+ -+ if (usb_dev->state != USB_UP_ST) { -+ usb_err("bus is not up=%d\n", usb_dev->state); -+ return; -+ } -+ -+ while ((usb_buf = aicwf_usb_rx_buf_get(usb_dev)) != NULL) { -+ if (aicwf_usb_submit_rx_urb(usb_dev, usb_buf)) { -+ usb_err("usb rx refill fail\n"); -+ if (usb_dev->state != USB_UP_ST) -+ return; -+ } -+ } -+} -+ -+static void aicwf_usb_rx_prepare(struct aic_usb_dev *usb_dev) -+{ -+ aicwf_usb_rx_submit_all_urb(usb_dev); -+} -+ -+static void aicwf_usb_tx_prepare(struct aic_usb_dev *usb_dev) -+{ -+ struct aicwf_usb_buf *usb_buf; -+ -+ while (!list_empty(&usb_dev->tx_post_list)) { -+ usb_buf = aicwf_usb_tx_dequeue(usb_dev, &usb_dev->tx_post_list, -+ &usb_dev->tx_post_count, &usb_dev->tx_post_lock); -+ if (usb_buf->skb) { -+ dev_kfree_skb(usb_buf->skb); -+ usb_buf->skb = NULL; -+ } -+ aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf, -+ &usb_dev->tx_free_count, &usb_dev->tx_free_lock); -+ } -+} -+static void aicwf_usb_tx_process(struct aic_usb_dev *usb_dev) -+{ -+ struct aicwf_usb_buf *usb_buf; -+ int ret = 0; -+ u8 *data = NULL; -+ -+ while (!list_empty(&usb_dev->tx_post_list)) { -+ if (usb_dev->state != USB_UP_ST) { -+ usb_err("usb state is not up!\n"); -+ return; -+ } -+ -+ usb_buf = aicwf_usb_tx_dequeue(usb_dev, &usb_dev->tx_post_list, -+ &usb_dev->tx_post_count, &usb_dev->tx_post_lock); -+ if (!usb_buf) { -+ usb_err("can not get usb_buf from tx_post_list!\n"); -+ return; -+ } -+ data = usb_buf->skb->data; -+ -+ ret = usb_submit_urb(usb_buf->urb, GFP_ATOMIC); -+ if (ret) { -+ usb_err("aicwf_usb_bus_tx usb_submit_urb FAILED\n"); -+ goto fail; -+ } -+ -+ continue; -+fail: -+ dev_kfree_skb(usb_buf->skb); -+ usb_buf->skb = NULL; -+ aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf, -+ &usb_dev->tx_free_count, &usb_dev->tx_free_lock); -+ } -+} -+ -+int usb_bustx_thread(void *data) -+{ -+ struct aicwf_bus *bus = (struct aicwf_bus *)data; -+ struct aic_usb_dev *usbdev = bus->bus_priv.usb; -+ -+ while (1) { -+ if (kthread_should_stop()) { -+ usb_err("usb bustx thread stop\n"); -+ break; -+ } -+ if (!wait_for_completion_interruptible(&bus->bustx_trgg)) { -+ if (usbdev->bus_if->state == BUS_DOWN_ST) -+ continue; -+ if (usbdev->tx_post_count > 0) -+ aicwf_usb_tx_process(usbdev); -+ } -+ } -+ -+ return 0; -+} -+ -+int usb_busrx_thread(void *data) -+{ -+ struct aicwf_rx_priv *rx_priv = (struct aicwf_rx_priv *)data; -+ struct aicwf_bus *bus_if = rx_priv->usbdev->bus_if; -+ -+ while (1) { -+ if (kthread_should_stop()) { -+ usb_err("usb busrx thread stop\n"); -+ break; -+ } -+ if (!wait_for_completion_interruptible(&bus_if->busrx_trgg)) { -+ if (bus_if->state == BUS_DOWN_ST) -+ continue; -+ aicwf_process_rxframes(rx_priv); -+ } -+ } -+ -+ return 0; -+} -+ -+static void aicwf_usb_send_msg_complete(struct urb *urb) -+{ -+ struct aic_usb_dev *usb_dev = (struct aic_usb_dev *) urb->context; -+ -+ usb_dev->msg_finished = true; -+ if (waitqueue_active(&usb_dev->msg_wait)) -+ wake_up(&usb_dev->msg_wait); -+} -+ -+static int aicwf_usb_bus_txmsg(struct device *dev, u8 *buf, u32 len) -+{ -+ int ret = 0; -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_usb_dev *usb_dev = bus_if->bus_priv.usb; -+ -+ if (usb_dev->state != USB_UP_ST) -+ return -EIO; -+ -+ if (buf == NULL || len == 0 || usb_dev->msg_out_urb == NULL) -+ return -EINVAL; -+ -+ if (test_and_set_bit(0, &usb_dev->msg_busy)) { -+ usb_err("In a control frame option, can't tx!\n"); -+ return -EIO; -+ } -+ -+ usb_dev->msg_finished = false; -+ -+ usb_fill_bulk_urb(usb_dev->msg_out_urb, -+ usb_dev->udev, -+ usb_dev->bulk_out_pipe, -+ buf, len, (usb_complete_t) aicwf_usb_send_msg_complete, usb_dev); -+ usb_dev->msg_out_urb->transfer_flags |= URB_ZERO_PACKET; -+ -+ ret = usb_submit_urb(usb_dev->msg_out_urb, GFP_ATOMIC); -+ if (ret) { -+ usb_err("usb_submit_urb failed %d\n", ret); -+ goto exit; -+ } -+ -+ ret = wait_event_timeout(usb_dev->msg_wait, -+ usb_dev->msg_finished, msecs_to_jiffies(CMD_TX_TIMEOUT)); -+ if (!ret) { -+ if (usb_dev->msg_out_urb) -+ usb_kill_urb(usb_dev->msg_out_urb); -+ usb_err("Txmsg wait timed out\n"); -+ ret = -EIO; -+ goto exit; -+ } -+ -+ if (usb_dev->msg_finished == false) { -+ usb_err("Txmsg timed out\n"); -+ ret = -ETIMEDOUT; -+ goto exit; -+ } -+exit: -+ clear_bit(0, &usb_dev->msg_busy); -+ return ret; -+} -+ -+ -+static void aicwf_usb_free_urb(struct list_head *q, spinlock_t *qlock) -+{ -+ struct aicwf_usb_buf *usb_buf, *tmp; -+ unsigned long flags; -+ -+ spin_lock_irqsave(qlock, flags); -+ list_for_each_entry_safe(usb_buf, tmp, q, list) { -+ spin_unlock_irqrestore(qlock, flags); -+ if (!usb_buf->urb) { -+ usb_err("bad usb_buf\n"); -+ spin_lock_irqsave(qlock, flags); -+ break; -+ } -+ usb_free_urb(usb_buf->urb); -+ list_del_init(&usb_buf->list); -+ spin_lock_irqsave(qlock, flags); -+ } -+ spin_unlock_irqrestore(qlock, flags); -+} -+ -+static int aicwf_usb_alloc_rx_urb(struct aic_usb_dev *usb_dev) -+{ -+ int i; -+ -+ for (i = 0; i < AICWF_USB_RX_URBS; i++) { -+ struct aicwf_usb_buf *usb_buf = &usb_dev->usb_rx_buf[i]; -+ -+ usb_buf->usbdev = usb_dev; -+ usb_buf->urb = usb_alloc_urb(0, GFP_KERNEL); -+ if (!usb_buf->urb) { -+ usb_err("could not allocate rx data urb\n"); -+ goto err; -+ } -+ list_add_tail(&usb_buf->list, &usb_dev->rx_free_list); -+ } -+ return 0; -+ -+err: -+ aicwf_usb_free_urb(&usb_dev->rx_free_list, &usb_dev->rx_free_lock); -+ return -ENOMEM; -+} -+ -+static int aicwf_usb_alloc_tx_urb(struct aic_usb_dev *usb_dev) -+{ -+ int i; -+ -+ for (i = 0; i < AICWF_USB_TX_URBS; i++) { -+ struct aicwf_usb_buf *usb_buf = &usb_dev->usb_tx_buf[i]; -+ -+ usb_buf->usbdev = usb_dev; -+ usb_buf->urb = usb_alloc_urb(0, GFP_KERNEL); -+ if (!usb_buf->urb) { -+ usb_err("could not allocate tx data urb\n"); -+ goto err; -+ } -+ list_add_tail(&usb_buf->list, &usb_dev->tx_free_list); -+ (usb_dev->tx_free_count)++; -+ } -+ return 0; -+ -+err: -+ aicwf_usb_free_urb(&usb_dev->tx_free_list, &usb_dev->tx_free_lock); -+ return -ENOMEM; -+} -+ -+ -+static void aicwf_usb_state_change(struct aic_usb_dev *usb_dev, int state) -+{ -+ int old_state; -+ -+ if (usb_dev->state == state) -+ return; -+ -+ old_state = usb_dev->state; -+ usb_dev->state = state; -+ -+ if (state == USB_DOWN_ST) { -+ usb_dev->bus_if->state = BUS_DOWN_ST; -+ } -+ if (state == USB_UP_ST) { -+ usb_dev->bus_if->state = BUS_UP_ST; -+ } -+} -+ -+static int aicwf_usb_bus_txdata(struct device *dev, struct sk_buff *skb) -+{ -+ u8 *buf; -+ u16 buf_len = 0; -+ u16 adjust_len = 0; -+ struct aicwf_usb_buf *usb_buf; -+ int ret = 0; -+ unsigned long flags; -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_usb_dev *usb_dev = bus_if->bus_priv.usb; -+ struct rwnx_txhdr *txhdr = (struct rwnx_txhdr *)skb->data; -+ struct rwnx_hw *rwnx_hw = usb_dev->rwnx_hw; -+ u8 usb_header[4]; -+ u8 adj_buf[4] = {0}; -+ u16 index = 0; -+ bool need_cfm = false; -+ -+ if (usb_dev->state != USB_UP_ST) { -+ usb_err("usb state is not up!\n"); -+ kmem_cache_free(rwnx_hw->sw_txhdr_cache, txhdr->sw_hdr); -+ dev_kfree_skb_any(skb); -+ return -EIO; -+ } -+ -+ usb_buf = aicwf_usb_tx_dequeue(usb_dev, &usb_dev->tx_free_list, -+ &usb_dev->tx_free_count, &usb_dev->tx_free_lock); -+ if (!usb_buf) { -+ usb_err("free:%d, post:%d\n", usb_dev->tx_free_count, usb_dev->tx_post_count); -+ kmem_cache_free(rwnx_hw->sw_txhdr_cache, txhdr->sw_hdr); -+ dev_kfree_skb_any(skb); -+ ret = -ENOMEM; -+ goto flow_ctrl; -+ } -+ -+ if (txhdr->sw_hdr->need_cfm) { -+ need_cfm = true; -+ buf = kmalloc(skb->len, GFP_KERNEL); -+ index += sizeof(usb_header); -+ memcpy(&buf[index], (u8 *)(long)&txhdr->sw_hdr->desc, sizeof(struct txdesc_api)); -+ index += sizeof(struct txdesc_api); -+ memcpy(&buf[index], &skb->data[txhdr->sw_hdr->headroom], skb->len - txhdr->sw_hdr->headroom); -+ index += skb->len - txhdr->sw_hdr->headroom; -+ buf_len = index; -+ if (buf_len & (TX_ALIGNMENT - 1)) { -+ adjust_len = roundup(buf_len, TX_ALIGNMENT)-buf_len; -+ memcpy(&buf[buf_len], adj_buf, adjust_len); -+ buf_len += adjust_len; -+ } -+ usb_header[0] = ((buf_len) & 0xff); -+ usb_header[1] = (((buf_len) >> 8)&0x0f); -+ usb_header[2] = 0x01; //data -+ usb_header[3] = 0; //reserved -+ memcpy(&buf[0], usb_header, sizeof(usb_header)); -+ usb_buf->skb = (struct sk_buff *)buf; -+ } else { -+ skb_pull(skb, txhdr->sw_hdr->headroom); -+ skb_push(skb, sizeof(struct txdesc_api)); -+ memcpy(&skb->data[0], (u8 *)(long)&txhdr->sw_hdr->desc, sizeof(struct txdesc_api)); -+ kmem_cache_free(rwnx_hw->sw_txhdr_cache, txhdr->sw_hdr); -+ -+ skb_push(skb, sizeof(usb_header)); -+ usb_header[0] = ((skb->len) & 0xff); -+ usb_header[1] = (((skb->len) >> 8)&0x0f); -+ usb_header[2] = 0x01; //data -+ usb_header[3] = 0; //reserved -+ memcpy(&skb->data[0], usb_header, sizeof(usb_header)); -+ -+ buf = skb->data; -+ buf_len = skb->len; -+ -+ usb_buf->skb = skb; -+ } -+ usb_buf->usbdev = usb_dev; -+ if (need_cfm) -+ usb_buf->cfm = true; -+ else -+ usb_buf->cfm = false; -+ usb_fill_bulk_urb(usb_buf->urb, usb_dev->udev, usb_dev->bulk_out_pipe, -+ buf, buf_len, aicwf_usb_tx_complete, usb_buf); -+ usb_buf->urb->transfer_flags |= URB_ZERO_PACKET; -+ -+ aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_post_list, usb_buf, -+ &usb_dev->tx_post_count, &usb_dev->tx_post_lock); -+ complete(&bus_if->bustx_trgg); -+ ret = 0; -+ -+ flow_ctrl: -+ spin_lock_irqsave(&usb_dev->tx_flow_lock, flags); -+ if (usb_dev->tx_free_count < AICWF_USB_TX_LOW_WATER) { -+ usb_dev->tbusy = true; -+ aicwf_usb_tx_flowctrl(usb_dev->rwnx_hw, true); -+ } -+ spin_unlock_irqrestore(&usb_dev->tx_flow_lock, flags); -+ -+ return ret; -+} -+ -+static int aicwf_usb_bus_start(struct device *dev) -+{ -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_usb_dev *usb_dev = bus_if->bus_priv.usb; -+ -+ if (usb_dev->state == USB_UP_ST) -+ return 0; -+ -+ aicwf_usb_state_change(usb_dev, USB_UP_ST); -+ aicwf_usb_rx_prepare(usb_dev); -+ aicwf_usb_tx_prepare(usb_dev); -+ return 0; -+} -+ -+static void aicwf_usb_cancel_all_urbs(struct aic_usb_dev *usb_dev) -+{ -+ struct aicwf_usb_buf *usb_buf, *tmp; -+ unsigned long flags; -+ -+ if (usb_dev->msg_out_urb) -+ usb_kill_urb(usb_dev->msg_out_urb); -+ -+ spin_lock_irqsave(&usb_dev->tx_post_lock, flags); -+ list_for_each_entry_safe(usb_buf, tmp, &usb_dev->tx_post_list, list) { -+ spin_unlock_irqrestore(&usb_dev->tx_post_lock, flags); -+ if (!usb_buf->urb) { -+ usb_err("bad usb_buf\n"); -+ spin_lock_irqsave(&usb_dev->tx_post_lock, flags); -+ break; -+ } -+ usb_kill_urb(usb_buf->urb); -+ spin_lock_irqsave(&usb_dev->tx_post_lock, flags); -+ } -+ spin_unlock_irqrestore(&usb_dev->tx_post_lock, flags); -+ -+ usb_kill_anchored_urbs(&usb_dev->rx_submitted); -+} -+ -+static void aicwf_usb_bus_stop(struct device *dev) -+{ -+ struct aicwf_bus *bus_if = dev_get_drvdata(dev); -+ struct aic_usb_dev *usb_dev = bus_if->bus_priv.usb; -+ -+ usb_dbg("%s\r\n", __func__); -+ if (usb_dev == NULL) -+ return; -+ -+ if (usb_dev->state == USB_DOWN_ST) -+ return; -+ -+ aicwf_usb_state_change(usb_dev, USB_DOWN_ST); -+ aicwf_usb_cancel_all_urbs(usb_dev); -+} -+ -+static void aicwf_usb_deinit(struct aic_usb_dev *usbdev) -+{ -+ cancel_work_sync(&usbdev->rx_urb_work); -+ aicwf_usb_free_urb(&usbdev->rx_free_list, &usbdev->rx_free_lock); -+ aicwf_usb_free_urb(&usbdev->tx_free_list, &usbdev->tx_free_lock); -+ usb_free_urb(usbdev->msg_out_urb); -+} -+ -+static void aicwf_usb_rx_urb_work(struct work_struct *work) -+{ -+ struct aic_usb_dev *usb_dev = container_of(work, struct aic_usb_dev, rx_urb_work); -+ -+ aicwf_usb_rx_submit_all_urb(usb_dev); -+} -+ -+static int aicwf_usb_init(struct aic_usb_dev *usb_dev) -+{ -+ int ret = 0; -+ -+ usb_dev->tbusy = false; -+ usb_dev->state = USB_DOWN_ST; -+ -+ init_waitqueue_head(&usb_dev->msg_wait); -+ init_usb_anchor(&usb_dev->rx_submitted); -+ -+ spin_lock_init(&usb_dev->tx_free_lock); -+ spin_lock_init(&usb_dev->tx_post_lock); -+ spin_lock_init(&usb_dev->rx_free_lock); -+ spin_lock_init(&usb_dev->tx_flow_lock); -+ -+ INIT_LIST_HEAD(&usb_dev->rx_free_list); -+ INIT_LIST_HEAD(&usb_dev->tx_free_list); -+ INIT_LIST_HEAD(&usb_dev->tx_post_list); -+ -+ usb_dev->tx_free_count = 0; -+ usb_dev->tx_post_count = 0; -+ -+ ret = aicwf_usb_alloc_rx_urb(usb_dev); -+ if (ret) { -+ goto error; -+ } -+ ret = aicwf_usb_alloc_tx_urb(usb_dev); -+ if (ret) { -+ goto error; -+ } -+ -+ -+ usb_dev->msg_out_urb = usb_alloc_urb(0, GFP_ATOMIC); -+ if (!usb_dev->msg_out_urb) { -+ usb_err("usb_alloc_urb (msg out) failed\n"); -+ ret = ENOMEM; -+ goto error; -+ } -+ -+ INIT_WORK(&usb_dev->rx_urb_work, aicwf_usb_rx_urb_work); -+ -+ return ret; -+ error: -+ usb_err("failed!\n"); -+ aicwf_usb_deinit(usb_dev); -+ return ret; -+} -+ -+ -+static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *interface) -+{ -+ struct usb_interface_descriptor *interface_desc; -+ struct usb_host_interface *host_interface; -+ struct usb_endpoint_descriptor *endpoint; -+ struct usb_device *usb = usb_dev->udev; -+ int i, endpoints; -+ u8 endpoint_num; -+ int ret = 0; -+ -+ usb_dev->bulk_in_pipe = 0; -+ usb_dev->bulk_out_pipe = 0; -+ -+ host_interface = &interface->altsetting[0]; -+ interface_desc = &host_interface->desc; -+ endpoints = interface_desc->bNumEndpoints; -+ -+ /* Check device configuration */ -+ if (usb->descriptor.bNumConfigurations != 1) { -+ usb_err("Number of configurations: %d not supported\n", -+ usb->descriptor.bNumConfigurations); -+ ret = -ENODEV; -+ goto exit; -+ } -+ -+ /* Check deviceclass */ -+#ifndef CONFIG_USB_BT -+ if (usb->descriptor.bDeviceClass != 0x00) { -+ usb_err("DeviceClass %d not supported\n", -+ usb->descriptor.bDeviceClass); -+ ret = -ENODEV; -+ goto exit; -+ } -+#endif -+ -+ /* Check interface number */ -+#ifdef CONFIG_USB_BT -+ if (usb->actconfig->desc.bNumInterfaces != 3) { -+#else -+ if (usb->actconfig->desc.bNumInterfaces != 1) { -+#endif -+ usb_err("Number of interfaces: %d not supported\n", -+ usb->actconfig->desc.bNumInterfaces); -+ ret = -ENODEV; -+ goto exit; -+ } -+ -+ if ((interface_desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || -+ (interface_desc->bInterfaceSubClass != 0xff) || -+ (interface_desc->bInterfaceProtocol != 0xff)) { -+ usb_err("non WLAN interface %d: 0x%x:0x%x:0x%x\n", -+ interface_desc->bInterfaceNumber, interface_desc->bInterfaceClass, -+ interface_desc->bInterfaceSubClass, interface_desc->bInterfaceProtocol); -+ ret = -ENODEV; -+ goto exit; -+ } -+ -+ for (i = 0; i < endpoints; i++) { -+ endpoint = &host_interface->endpoint[i].desc; -+ endpoint_num = usb_endpoint_num(endpoint); -+ -+ if (usb_endpoint_dir_in(endpoint) && -+ usb_endpoint_xfer_bulk(endpoint)) { -+ if (!usb_dev->bulk_in_pipe) { -+ usb_dev->bulk_in_pipe = usb_rcvbulkpipe(usb, endpoint_num); -+ } -+ } -+ -+ if (usb_endpoint_dir_out(endpoint) && -+ usb_endpoint_xfer_bulk(endpoint)) { -+ if (!usb_dev->bulk_out_pipe) { -+ usb_dev->bulk_out_pipe = usb_sndbulkpipe(usb, endpoint_num); -+ } -+ } -+ } -+ -+ if (usb_dev->bulk_in_pipe == 0) { -+ usb_err("No RX (in) Bulk EP found\n"); -+ ret = -ENODEV; -+ goto exit; -+ } -+ if (usb_dev->bulk_out_pipe == 0) { -+ usb_err("No TX (out) Bulk EP found\n"); -+ ret = -ENODEV; -+ goto exit; -+ } -+ -+ if (usb->speed == USB_SPEED_HIGH) -+ printk("Aic high speed USB device detected\n"); -+ else -+ printk("Aic full speed USB device detected\n"); -+ -+ exit: -+ return ret; -+} -+ -+ -+ -+static struct aicwf_bus_ops aicwf_usb_bus_ops = { -+ .start = aicwf_usb_bus_start, -+ .stop = aicwf_usb_bus_stop, -+ .txdata = aicwf_usb_bus_txdata, -+ .txmsg = aicwf_usb_bus_txmsg, -+}; -+ -+static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) -+{ -+ int ret = 0; -+ struct usb_device *usb = interface_to_usbdev(intf); -+ struct aicwf_bus *bus_if ; -+ struct device *dev = NULL; -+ struct aicwf_rx_priv *rx_priv = NULL; -+ struct aic_usb_dev *usb_dev = NULL; -+ -+ usb_dev = kzalloc(sizeof(struct aic_usb_dev), GFP_ATOMIC); -+ if (!usb_dev) { -+ return -ENOMEM; -+ } -+ -+ usb_dev->udev = usb; -+ usb_dev->dev = &usb->dev; -+ usb_set_intfdata(intf, usb_dev); -+ -+ ret = aicwf_parse_usb(usb_dev, intf); -+ if (ret) { -+ usb_err("aicwf_parse_usb err %d\n", ret); -+ goto out_free; -+ } -+ -+ ret = aicwf_usb_init(usb_dev); -+ if (ret) { -+ usb_err("aicwf_usb_init err %d\n", ret); -+ goto out_free; -+ } -+ -+ bus_if = kzalloc(sizeof(struct aicwf_bus), GFP_ATOMIC); -+ if (!bus_if) { -+ ret = -ENOMEM; -+ goto out_free_usb; -+ } -+ -+ dev = usb_dev->dev; -+ bus_if->dev = dev; -+ usb_dev->bus_if = bus_if; -+ bus_if->bus_priv.usb = usb_dev; -+ dev_set_drvdata(dev, bus_if); -+ -+ bus_if->ops = &aicwf_usb_bus_ops; -+ -+ rx_priv = aicwf_rx_init(usb_dev); -+ if (!rx_priv) { -+ txrx_err("rx init failed\n"); -+ ret = -1; -+ goto out_free_bus; -+ } -+ usb_dev->rx_priv = rx_priv; -+ -+ ret = aicwf_bus_init(0, dev); -+ if (ret < 0) { -+ usb_err("aicwf_bus_init err %d\n", ret); -+ goto out_free_bus; -+ } -+ -+ ret = aicwf_bus_start(bus_if); -+ if (ret < 0) { -+ usb_err("aicwf_bus_start err %d\n", ret); -+ goto out_free_bus; -+ } -+ -+ aicwf_rwnx_usb_platform_init(usb_dev); -+ aicwf_hostif_ready(); -+ return 0; -+ -+out_free_bus: -+ aicwf_bus_deinit(dev); -+ kfree(bus_if); -+out_free_usb: -+ aicwf_usb_deinit(usb_dev); -+out_free: -+ usb_err("failed with errno %d\n", ret); -+ kfree(usb_dev); -+ usb_set_intfdata(intf, NULL); -+ return ret; -+} -+ -+static void aicwf_usb_disconnect(struct usb_interface *intf) -+{ -+ struct aic_usb_dev *usb_dev = -+ (struct aic_usb_dev *) usb_get_intfdata(intf); -+ -+ if (!usb_dev) -+ return; -+ -+ aicwf_bus_deinit(usb_dev->dev); -+ aicwf_usb_deinit(usb_dev); -+ rwnx_cmd_mgr_deinit(&usb_dev->cmd_mgr); -+ -+ if (usb_dev->rx_priv) -+ aicwf_rx_deinit(usb_dev->rx_priv); -+ kfree(usb_dev->bus_if); -+ kfree(usb_dev); -+} -+ -+static int aicwf_usb_suspend(struct usb_interface *intf, pm_message_t state) -+{ -+ struct aic_usb_dev *usb_dev = -+ (struct aic_usb_dev *) usb_get_intfdata(intf); -+ -+ aicwf_usb_state_change(usb_dev, USB_SLEEP_ST); -+ aicwf_bus_stop(usb_dev->bus_if); -+ return 0; -+} -+ -+static int aicwf_usb_resume(struct usb_interface *intf) -+{ -+ struct aic_usb_dev *usb_dev = -+ (struct aic_usb_dev *) usb_get_intfdata(intf); -+ -+ if (usb_dev->state == USB_UP_ST) -+ return 0; -+ -+ aicwf_bus_start(usb_dev->bus_if); -+ return 0; -+} -+ -+static int aicwf_usb_reset_resume(struct usb_interface *intf) -+{ -+ return aicwf_usb_resume(intf); -+} -+ -+static struct usb_device_id aicwf_usb_id_table[] = { -+#ifndef CONFIG_USB_BT -+ {USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC)}, -+#else -+ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC, 0xff, 0xff, 0xff)}, -+#endif -+ {} -+}; -+ -+MODULE_DEVICE_TABLE(usb, aicwf_usb_id_table); -+ -+static struct usb_driver aicwf_usbdrvr = { -+ .name = KBUILD_MODNAME, -+ .probe = aicwf_usb_probe, -+ .disconnect = aicwf_usb_disconnect, -+ .id_table = aicwf_usb_id_table, -+ .suspend = aicwf_usb_suspend, -+ .resume = aicwf_usb_resume, -+ .reset_resume = aicwf_usb_reset_resume, -+ .supports_autosuspend = 1, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) -+ .disable_hub_initiated_lpm = 1, -+#endif -+}; -+ -+void aicwf_usb_register(void) -+{ -+ if (usb_register(&aicwf_usbdrvr) < 0) { -+ usb_err("usb_register failed\n"); -+ } -+} -+ -+void aicwf_usb_exit(void) -+{ -+ if (g_rwnx_plat && g_rwnx_plat->enabled) -+ rwnx_platform_deinit(g_rwnx_plat->usbdev->rwnx_hw); -+ usb_deregister(&aicwf_usbdrvr); -+ kfree(g_rwnx_plat); -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_usb.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_usb.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_usb.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_usb.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,99 @@ -+/** -+ * aicwf_usb.h -+ * -+ * USB function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+#ifndef _AICWF_USB_H_ -+#define _AICWF_USB_H_ -+ -+#include -+#include "rwnx_cmds.h" -+ -+#ifdef AICWF_USB_SUPPORT -+ -+/* USB Device ID */ -+#define USB_VENDOR_ID_AIC 0xA69C -+ -+#ifndef CONFIG_USB_BT -+#define USB_PRODUCT_ID_AIC 0x8800 -+#else -+#define USB_PRODUCT_ID_AIC 0x8801 -+#endif -+ -+#define AICWF_USB_RX_URBS (200) -+#define AICWF_USB_TX_URBS (100) -+#define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4) -+#define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3) -+#define AICWF_USB_MAX_PKT_SIZE (2048) -+ -+typedef enum { -+ USB_TYPE_DATA = 0X00, -+ USB_TYPE_CFG = 0X10, -+ USB_TYPE_CFG_CMD_RSP = 0X11, -+ USB_TYPE_CFG_DATA_CFM = 0X12 -+} usb_type; -+ -+enum aicwf_usb_state { -+ USB_DOWN_ST, -+ USB_UP_ST, -+ USB_SLEEP_ST -+}; -+ -+struct aicwf_usb_buf { -+ struct list_head list; -+ struct aic_usb_dev *usbdev; -+ struct urb *urb; -+ struct sk_buff *skb; -+ bool cfm; -+}; -+ -+struct aic_usb_dev { -+ struct rwnx_hw *rwnx_hw; -+ struct aicwf_bus *bus_if; -+ struct usb_device *udev; -+ struct device *dev; -+ struct aicwf_rx_priv *rx_priv; -+ enum aicwf_usb_state state; -+ struct rwnx_cmd_mgr cmd_mgr; -+ -+ struct usb_anchor rx_submitted; -+ struct work_struct rx_urb_work; -+ -+ spinlock_t rx_free_lock; -+ spinlock_t tx_free_lock; -+ spinlock_t tx_post_lock; -+ spinlock_t tx_flow_lock; -+ -+ struct list_head rx_free_list; -+ struct list_head tx_free_list; -+ struct list_head tx_post_list; -+ -+ uint bulk_in_pipe; -+ uint bulk_out_pipe; -+ -+ int tx_free_count; -+ int tx_post_count; -+ -+ struct aicwf_usb_buf usb_tx_buf[AICWF_USB_TX_URBS]; -+ struct aicwf_usb_buf usb_rx_buf[AICWF_USB_RX_URBS]; -+ -+ int msg_finished; -+ wait_queue_head_t msg_wait; -+ ulong msg_busy; -+ struct urb *msg_out_urb; -+ -+ bool tbusy; -+}; -+ -+extern void aicwf_usb_exit(void); -+extern void aicwf_usb_register(void); -+extern void aicwf_usb_tx_flowctrl(struct rwnx_hw *rwnx_hw, bool state); -+int usb_bustx_thread(void *data); -+int usb_busrx_thread(void *data); -+extern void aicwf_hostif_ready(void); -+ -+#endif /* AICWF_USB_SUPPORT */ -+#endif /* _AICWF_USB_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/.gitignore linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/.gitignore ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/.gitignore 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/.gitignore 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,10 @@ -+*.o -+*.ko -+*.order -+*.symvers -+*.o.d -+*.o.cmd -+*.ko.cmd -+*.mod -+*.mod.c -+*.mod.cmd -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/hal_desc.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/hal_desc.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/hal_desc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/hal_desc.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,353 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file hal_desc.h -+ * -+ * @brief File containing the definition of HW descriptors. -+ * -+ * Contains the definition and structures used by HW -+ * -+ * Copyright (C) RivieraWaves 2011-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _HAL_DESC_H_ -+#define _HAL_DESC_H_ -+ -+#include "lmac_types.h" -+ -+/* Rate and policy table */ -+ -+#define N_CCK 8 -+#define N_OFDM 8 -+#define N_HT (8 * 2 * 2 * 4) -+#define N_VHT (10 * 4 * 2 * 8) -+#define N_HE_SU (12 * 4 * 3 * 8) -+#define N_HE_MU (12 * 6 * 3 * 8) -+#define N_HE_ER (3 * 3 + 3) //RU242 + RU106 -+ -+/* conversion table from NL80211 to MACHW enum */ -+extern const int chnl2bw[]; -+ -+/* conversion table from MACHW to NL80211 enum */ -+extern const int bw2chnl[]; -+ -+/* Values for formatModTx */ -+#define FORMATMOD_NON_HT 0 -+#define FORMATMOD_NON_HT_DUP_OFDM 1 -+#define FORMATMOD_HT_MF 2 -+#define FORMATMOD_HT_GF 3 -+#define FORMATMOD_VHT 4 -+#define FORMATMOD_HE_SU 5 -+#define FORMATMOD_HE_MU 6 -+#define FORMATMOD_HE_ER 7 -+#define FORMATMOD_HE_TB 8 -+ -+/* Values for navProtFrmEx */ -+#define NAV_PROT_NO_PROT_BIT 0 -+#define NAV_PROT_SELF_CTS_BIT 1 -+#define NAV_PROT_RTS_CTS_BIT 2 -+#define NAV_PROT_RTS_CTS_WITH_QAP_BIT 3 -+#define NAV_PROT_STBC_BIT 4 -+ -+/* THD MACCTRLINFO2 fields, used in struct umacdesc umac.flags */ -+/// WhichDescriptor definition - contains aMPDU bit and position value -+/// Offset of WhichDescriptor field in the MAC CONTROL INFO 2 word -+#define WHICHDESC_OFT 19 -+/// Mask of the WhichDescriptor field -+#define WHICHDESC_MSK (0x07 << WHICHDESC_OFT) -+/// Only 1 THD possible, describing an unfragmented MSDU -+#define WHICHDESC_UNFRAGMENTED_MSDU (0x00 << WHICHDESC_OFT) -+/// THD describing the first MPDU of a fragmented MSDU -+#define WHICHDESC_FRAGMENTED_MSDU_FIRST (0x01 << WHICHDESC_OFT) -+/// THD describing intermediate MPDUs of a fragmented MSDU -+#define WHICHDESC_FRAGMENTED_MSDU_INT (0x02 << WHICHDESC_OFT) -+/// THD describing the last MPDU of a fragmented MSDU -+#define WHICHDESC_FRAGMENTED_MSDU_LAST (0x03 << WHICHDESC_OFT) -+/// THD for extra descriptor starting an AMPDU -+#define WHICHDESC_AMPDU_EXTRA (0x04 << WHICHDESC_OFT) -+/// THD describing the first MPDU of an A-MPDU -+#define WHICHDESC_AMPDU_FIRST (0x05 << WHICHDESC_OFT) -+/// THD describing intermediate MPDUs of an A-MPDU -+#define WHICHDESC_AMPDU_INT (0x06 << WHICHDESC_OFT) -+/// THD describing the last MPDU of an A-MPDU -+#define WHICHDESC_AMPDU_LAST (0x07 << WHICHDESC_OFT) -+ -+/// aMPDU bit offset -+#define AMPDU_OFT 21 -+/// aMPDU bit -+#define AMPDU_BIT CO_BIT(AMPDU_OFT) -+ -+union rwnx_mcs_index { -+ struct { -+ u32 mcs : 3; -+ u32 nss : 2; -+ } ht; -+ struct { -+ u32 mcs : 4; -+ u32 nss : 3; -+ } vht; -+ struct { -+ u32 mcs : 4; -+ u32 nss : 3; -+ } he; -+ u32 legacy : 7; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+union rwnx_rate_ctrl_info { -+ struct { -+ u32 mcsIndexTx : 7; -+ u32 bwTx : 2; -+ u32 giAndPreTypeTx : 2; -+ u32 formatModTx : 3; -+ u32 navProtFrmEx : 3; -+ u32 mcsIndexProtTx : 7; -+ u32 bwProtTx : 2; -+ u32 formatModProtTx : 3; -+ u32 nRetry : 3; -+ }; -+ u32 value; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+struct rwnx_power_ctrl_info { -+ u32 txPwrLevelPT : 8; -+ u32 txPwrLevelProtPT : 8; -+ u32 reserved :16; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+union rwnx_pol_phy_ctrl_info_1 { -+ struct { -+ u32 rsvd1 : 3; -+ u32 bfFrmEx : 1; -+ u32 numExtnSS : 2; -+ u32 fecCoding : 1; -+ u32 stbc : 2; -+ u32 rsvd2 : 5; -+ u32 nTx : 3; -+ u32 nTxProt : 3; -+ }; -+ u32 value; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+union rwnx_pol_phy_ctrl_info_2 { -+ struct { -+ u32 antennaSet : 8; -+ u32 smmIndex : 8; -+ u32 beamFormed : 1; -+ }; -+ u32 value; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+union rwnx_pol_mac_ctrl_info_1 { -+ struct { -+ u32 keySRamIndex : 10; -+ u32 keySRamIndexRA : 10; -+ }; -+ u32 value; -+}; -+ -+/* c.f RW-WLAN-nX-MAC-HW-UM */ -+union rwnx_pol_mac_ctrl_info_2 { -+ struct { -+ u32 longRetryLimit : 8; -+ u32 shortRetryLimit : 8; -+ u32 rtsThreshold : 12; -+ }; -+ u32 value; -+}; -+ -+#define POLICY_TABLE_PATTERN 0xBADCAB1E -+ -+struct tx_policy_tbl { -+ /* Unique Pattern at the start of Policy Table */ -+ u32 upatterntx; -+ /* PHY Control 1 Information used by MAC HW */ -+ union rwnx_pol_phy_ctrl_info_1 phyctrlinfo_1; -+ /* PHY Control 2 Information used by MAC HW */ -+ union rwnx_pol_phy_ctrl_info_2 phyctrlinfo_2; -+ /* MAC Control 1 Information used by MAC HW */ -+ union rwnx_pol_mac_ctrl_info_1 macctrlinfo_1; -+ /* MAC Control 2 Information used by MAC HW */ -+ union rwnx_pol_mac_ctrl_info_2 macctrlinfo_2; -+ -+ union rwnx_rate_ctrl_info ratectrlinfos[NX_TX_MAX_RATES]; -+ struct rwnx_power_ctrl_info powerctrlinfos[NX_TX_MAX_RATES]; -+}; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+/** -+ * struct rwnx_hw_txstatus - Bitfield of confirmation status -+ * -+ * @tx_done: packet has been processed by the firmware. -+ * @retry_required: packet has been transmitted but not acknoledged. -+ * Driver must repush it. -+ * @sw_retry_required: packet has not been transmitted (FW wasn't able to push -+ * it when it received it: not active channel ...). Driver must repush it. -+ * @acknowledged: packet has been acknowledged by peer -+ */ -+union rwnx_hw_txstatus { -+ struct { -+ u32 tx_done : 1; -+ u32 retry_required : 1; -+ u32 sw_retry_required : 1; -+ u32 acknowledged : 1; -+ u32 reserved :28; -+ }; -+ u32 value; -+}; -+ -+/** -+ * struct tx_cfm_tag - Structure indicating the status and other -+ * information about the transmission -+ * -+ * @pn: PN that was used for the transmission -+ * @sn: Sequence number of the packet -+ * @timestamp: Timestamp of first transmission of this MPDU -+ * @credits: Number of credits to be reallocated for the txq that push this -+ * buffer (can be 0 or 1) -+ * @ampdu_size: Size of the ampdu in which the frame has been transmitted if -+ * this was the last frame of the a-mpdu, and 0 if the frame is not the last -+ * frame on a a-mdpu. -+ * 1 means that the frame has been transmitted as a singleton. -+ * @amsdu_size: Size, in bytes, allowed to create a-msdu. -+ * @status: transmission status -+ */ -+struct tx_cfm_tag { -+/* -+ u16_l pn[4]; -+ u16_l sn; -+ u16_l timestamp; -+*/ -+ s8_l credits; -+ u8_l ampdu_size; -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ u16_l amsdu_size; -+#endif -+ union rwnx_hw_txstatus status; -+ u32_l hostid; -+}; -+ -+/** -+ * struct rwnx_hw_txhdr - Hardware part of tx header -+ * -+ * @cfm: Information updated by fw/hardware after sending a frame -+ */ -+struct rwnx_hw_txhdr { -+ struct tx_cfm_tag cfm; -+}; -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+/* Modem */ -+ -+#define MDM_PHY_CONFIG_TRIDENT 0 -+#define MDM_PHY_CONFIG_ELMA 1 -+#define MDM_PHY_CONFIG_KARST 2 -+ -+// MODEM features (from reg_mdm_stat.h) -+/// MUMIMOTX field bit -+#define MDM_MUMIMOTX_BIT ((u32)0x80000000) -+/// MUMIMOTX field position -+#define MDM_MUMIMOTX_POS 31 -+/// MUMIMORX field bit -+#define MDM_MUMIMORX_BIT ((u32)0x40000000) -+/// MUMIMORX field position -+#define MDM_MUMIMORX_POS 30 -+/// BFMER field bit -+#define MDM_BFMER_BIT ((u32)0x20000000) -+/// BFMER field position -+#define MDM_BFMER_POS 29 -+/// BFMEE field bit -+#define MDM_BFMEE_BIT ((u32)0x10000000) -+/// BFMEE field position -+#define MDM_BFMEE_POS 28 -+/// LDPCDEC field bit -+#define MDM_LDPCDEC_BIT ((u32)0x08000000) -+/// LDPCDEC field position -+#define MDM_LDPCDEC_POS 27 -+/// LDPCENC field bit -+#define MDM_LDPCENC_BIT ((u32)0x04000000) -+/// LDPCENC field position -+#define MDM_LDPCENC_POS 26 -+/// CHBW field mask -+#define MDM_CHBW_MASK ((u32)0x03000000) -+/// CHBW field LSB position -+#define MDM_CHBW_LSB 24 -+/// CHBW field width -+#define MDM_CHBW_WIDTH ((u32)0x00000002) -+/// DSSSCCK field bit -+#define MDM_DSSSCCK_BIT ((u32)0x00800000) -+/// DSSSCCK field position -+#define MDM_DSSSCCK_POS 23 -+/// VHT field bit -+#define MDM_VHT_BIT ((u32)0x00400000) -+/// VHT field position -+#define MDM_VHT_POS 22 -+/// HE field bit -+#define MDM_HE_BIT ((u32)0x00200000) -+/// HE field position -+#define MDM_HE_POS 21 -+/// ESS field bit -+#define MDM_ESS_BIT ((u32)0x00100000) -+/// ESS field position -+#define MDM_ESS_POS 20 -+/// RFMODE field mask -+#define MDM_RFMODE_MASK ((u32)0x000F0000) -+/// RFMODE field LSB position -+#define MDM_RFMODE_LSB 16 -+/// RFMODE field width -+#define MDM_RFMODE_WIDTH ((u32)0x00000004) -+/// NSTS field mask -+#define MDM_NSTS_MASK ((u32)0x0000F000) -+/// NSTS field LSB position -+#define MDM_NSTS_LSB 12 -+/// NSTS field width -+#define MDM_NSTS_WIDTH ((u32)0x00000004) -+/// NSS field mask -+#define MDM_NSS_MASK ((u32)0x00000F00) -+/// NSS field LSB position -+#define MDM_NSS_LSB 8 -+/// NSS field width -+#define MDM_NSS_WIDTH ((u32)0x00000004) -+/// NTX field mask -+#define MDM_NTX_MASK ((u32)0x000000F0) -+/// NTX field LSB position -+#define MDM_NTX_LSB 4 -+/// NTX field width -+#define MDM_NTX_WIDTH ((u32)0x00000004) -+/// NRX field mask -+#define MDM_NRX_MASK ((u32)0x0000000F) -+/// NRX field LSB position -+#define MDM_NRX_LSB 0 -+/// NRX field width -+#define MDM_NRX_WIDTH ((u32)0x00000004) -+ -+#define __MDM_PHYCFG_FROM_VERS(v) (((v) & MDM_RFMODE_MASK) >> MDM_RFMODE_LSB) -+ -+#define RIU_FCU_PRESENT_MASK ((u32)0xFF000000) -+#define RIU_FCU_PRESENT_LSB 24 -+ -+#define __RIU_FCU_PRESENT(v) (((v) & RIU_FCU_PRESENT_MASK) >> RIU_FCU_PRESENT_LSB == 5) -+ -+/// AGC load version field mask -+#define RIU_AGC_LOAD_MASK ((u32)0x00C00000) -+/// AGC load version field LSB position -+#define RIU_AGC_LOAD_LSB 22 -+ -+#define __RIU_AGCLOAD_FROM_VERS(v) (((v) & RIU_AGC_LOAD_MASK) >> RIU_AGC_LOAD_LSB) -+ -+#define __FPGA_TYPE(v) (((v) & 0xFFFF0000) >> 16) -+ -+#define __MDM_MAJOR_VERSION(v) (((v) & 0xFF000000) >> 24) -+#define __MDM_MINOR_VERSION(v) (((v) & 0x00FF0000) >> 16) -+#define __MDM_VERSION(v) ((__MDM_MAJOR_VERSION(v) + 2) * 10 + __MDM_MINOR_VERSION(v)) -+ -+ -+#endif // _HAL_DESC_H_ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_compat.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_compat.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_compat.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_compat.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,25 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file ipc_compat.h -+ * -+ * Copyright (C) RivieraWaves 2011-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _IPC_H_ -+#define _IPC_H_ -+ -+#define __INLINE inline -+ -+#define __ALIGN4 __aligned(4) -+ -+#define ASSERT_ERR(condition) \ -+ do { \ -+ if (unlikely(!(condition))) { \ -+ printk(KERN_ERR "%s:%d:ASSERT_ERR(" #condition ")\n", __FILE__, __LINE__); \ -+ } \ -+ } while (0) -+ -+#endif /* _IPC_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_host.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_host.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_host.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_host.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,52 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file ipc_host.c -+ * -+ * @brief IPC module. -+ * -+ * Copyright (C) RivieraWaves 2011-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+/* -+ * INCLUDE FILES -+ ****************************************************************************** -+ */ -+#ifndef __KERNEL__ -+#include -+#else -+#include -+#include "rwnx_defs.h" -+#include "rwnx_prof.h" -+#endif -+ -+#include "ipc_host.h" -+ -+/* -+ * TYPES DEFINITION -+ ****************************************************************************** -+ */ -+ -+const int nx_txdesc_cnt[] = { -+ NX_TXDESC_CNT0, -+ NX_TXDESC_CNT1, -+ NX_TXDESC_CNT2, -+ NX_TXDESC_CNT3, -+ #if NX_TXQ_CNT == 5 -+ NX_TXDESC_CNT4, -+ #endif -+}; -+ -+const int nx_txuser_cnt[] = { -+ CONFIG_USER_MAX, -+ CONFIG_USER_MAX, -+ CONFIG_USER_MAX, -+ CONFIG_USER_MAX, -+ #if NX_TXQ_CNT == 5 -+ 1, -+ #endif -+}; -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_host.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_host.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_host.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_host.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,168 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file ipc_host.h -+ * -+ * @brief IPC module. -+ * -+ * Copyright (C) RivieraWaves 2011-2019 -+ * -+ ****************************************************************************** -+ */ -+#ifndef _IPC_HOST_H_ -+#define _IPC_HOST_H_ -+ -+/* -+ * INCLUDE FILES -+ ****************************************************************************** -+ */ -+#include "ipc_shared.h" -+#ifndef __KERNEL__ -+#include "arch.h" -+#else -+#include "ipc_compat.h" -+#endif -+ -+/** -+ ****************************************************************************** -+ * @brief This structure is used to initialize the MAC SW -+ * -+ * The WLAN device driver provides functions call-back with this structure -+ ****************************************************************************** -+ */ -+struct ipc_host_cb_tag { -+ /// WLAN driver call-back function: send_data_cfm -+ int (*send_data_cfm)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: recv_data_ind -+ uint8_t (*recv_data_ind)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: recv_radar_ind -+ uint8_t (*recv_radar_ind)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: recv_unsup_rx_vec_ind -+ uint8_t (*recv_unsup_rx_vec_ind)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: recv_msg_ind -+ uint8_t (*recv_msg_ind)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: recv_msgack_ind -+ uint8_t (*recv_msgack_ind)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: recv_dbg_ind -+ uint8_t (*recv_dbg_ind)(void *pthis, void *host_id); -+ -+ /// WLAN driver call-back function: prim_tbtt_ind -+ void (*prim_tbtt_ind)(void *pthis); -+ -+ /// WLAN driver call-back function: sec_tbtt_ind -+ void (*sec_tbtt_ind)(void *pthis); -+ -+}; -+ -+/* -+ * Struct used to store information about host buffers (DMA Address and local pointer) -+ */ -+struct ipc_hostbuf { -+ void *hostid; ///< ptr to hostbuf client (ipc_host client) structure -+ uint32_t dma_addr; ///< ptr to real hostbuf dma address -+}; -+ -+/// Definition of the IPC Host environment structure. -+struct ipc_host_env_tag { -+ /// Structure containing the callback pointers -+ struct ipc_host_cb_tag cb; -+ -+ /// Pointer to the shared environment -+ struct ipc_shared_env_tag *shared; -+ -+ #ifdef CONFIG_RWNX_FULLMAC -+ // Array used to store the descriptor addresses -+ struct ipc_hostbuf ipc_host_rxdesc_array[IPC_RXDESC_CNT]; -+ // Index of the host RX descriptor array (ipc_shared environment) -+ uint8_t ipc_host_rxdesc_idx; -+ /// Store the number of RX Descriptors -+ uint8_t rxdesc_nb; -+ #endif //(CONFIG_RWNX_FULLMAC) -+ -+ /// Fields for Data Rx handling -+ // Index used for ipc_host_rxbuf_array to point to current buffer -+ uint8_t ipc_host_rxbuf_idx; -+ // Store the number of Rx Data buffers -+ uint32_t rx_bufnb; -+ // Store the size of the Rx Data buffers -+ uint32_t rx_bufsz; -+ -+ /// Fields for Radar events handling -+ // Global array used to store the hostid and hostbuf addresses -+ struct ipc_hostbuf ipc_host_radarbuf_array[IPC_RADARBUF_CNT]; -+ // Index used for ipc_host_rxbuf_array to point to current buffer -+ uint8_t ipc_host_radarbuf_idx; -+ // Store the number of radar event buffers -+ uint32_t radar_bufnb; -+ // Store the size of the radar event buffers -+ uint32_t radar_bufsz; -+ -+ ///Fields for Unsupported frame handling -+ // Global array used to store the hostid and hostbuf addresses -+ struct ipc_hostbuf ipc_host_unsuprxvecbuf_array[IPC_UNSUPRXVECBUF_CNT]; -+ // Index used for ipc_host_unsuprxvecbuf_array to point to current buffer -+ uint8_t ipc_host_unsuprxvecbuf_idx; -+ // Store the number of unsupported rx vector buffers -+ uint32_t unsuprxvec_bufnb; -+ // Store the size of unsupported rx vector buffers -+ uint32_t unsuprxvec_bufsz; -+ -+ // Index used that points to the first free TX desc -+ uint32_t txdesc_free_idx[IPC_TXQUEUE_CNT][CONFIG_USER_MAX]; -+ // Index used that points to the first used TX desc -+ uint32_t txdesc_used_idx[IPC_TXQUEUE_CNT][CONFIG_USER_MAX]; -+ // Array storing the currently pushed host ids for the BK queue -+ void *tx_host_id0[CONFIG_USER_MAX][NX_TXDESC_CNT0]; -+ // Array storing the currently pushed host ids for the BE queue -+ void *tx_host_id1[CONFIG_USER_MAX][NX_TXDESC_CNT1]; -+ // Array storing the currently pushed host ids for the VI queue -+ void *tx_host_id2[CONFIG_USER_MAX][NX_TXDESC_CNT2]; -+ // Array storing the currently pushed host ids for the VO queue -+ void *tx_host_id3[CONFIG_USER_MAX][NX_TXDESC_CNT3]; -+ #if NX_TXQ_CNT == 5 -+ // Array storing the currently pushed host ids for the BCN queue -+ void *tx_host_id4[1][NX_TXDESC_CNT4]; -+ #endif -+ // Pointer to the different host ids arrays, per IPC queue -+ void **tx_host_id[IPC_TXQUEUE_CNT][CONFIG_USER_MAX]; -+ // Pointer to the different TX descriptor arrays, per IPC queue -+ volatile struct txdesc_host *txdesc[IPC_TXQUEUE_CNT][CONFIG_USER_MAX]; -+ -+ /// Fields for Emb->App MSGs handling -+ // Global array used to store the hostid and hostbuf addresses for msg/ind -+ struct ipc_hostbuf ipc_host_msgbuf_array[IPC_MSGE2A_BUF_CNT]; -+ // Index of the MSG E2A buffers array to point to current buffer -+ uint8_t ipc_host_msge2a_idx; -+ // Store the number of E2A MSG buffers -+ uint32_t ipc_e2amsg_bufnb; -+ // Store the size of the E2A MSG buffers -+ uint32_t ipc_e2amsg_bufsz; -+ -+ /// E2A ACKs of A2E MSGs -+ uint8_t msga2e_cnt; -+ void *msga2e_hostid; -+ -+ /// Fields for Debug MSGs handling -+ // Global array used to store the hostid and hostbuf addresses for Debug messages -+ struct ipc_hostbuf ipc_host_dbgbuf_array[IPC_DBGBUF_CNT]; -+ // Index of the Debug messages buffers array to point to current buffer -+ uint8_t ipc_host_dbg_idx; -+ // Store the number of Debug messages buffers -+ uint32_t ipc_dbg_bufnb; -+ // Store the size of the Debug messages buffers -+ uint32_t ipc_dbg_bufsz; -+ -+ /// Pointer to the attached object (used in callbacks and register accesses) -+ void *pthis; -+}; -+ -+extern const int nx_txdesc_cnt[]; -+extern const int nx_txuser_cnt[]; -+ -+#endif // _IPC_HOST_H_ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_shared.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_shared.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_shared.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/ipc_shared.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,785 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file ipc_shared.h -+ * -+ * @brief Shared data between both IPC modules. -+ * -+ * Copyright (C) RivieraWaves 2011-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _IPC_SHARED_H_ -+#define _IPC_SHARED_H_ -+ -+/* -+ * INCLUDE FILES -+ **************************************************************************************** -+ */ -+#include "ipc_compat.h" -+#include "lmac_mac.h" -+ -+/* -+ * DEFINES AND MACROS -+ **************************************************************************************** -+ */ -+#define CO_BIT(pos) (1U<<(pos)) -+ -+#define IPC_TXQUEUE_CNT NX_TXQ_CNT -+#define NX_TXDESC_CNT0 8 -+#define NX_TXDESC_CNT1 64 -+#define NX_TXDESC_CNT2 64 -+#define NX_TXDESC_CNT3 32 -+#if NX_TXQ_CNT == 5 -+#define NX_TXDESC_CNT4 8 -+#endif -+ -+/* -+ * Number of Host buffers available for Data Rx handling (through DMA) -+ */ -+#define IPC_RXBUF_CNT 128 -+ -+/* -+ * Number of shared descriptors available for Data RX handling -+ */ -+#define IPC_RXDESC_CNT 128 -+ -+/* -+ * Number of Host buffers available for Radar events handling (through DMA) -+ */ -+#define IPC_RADARBUF_CNT 16 -+ -+/* -+ * Number of Host buffers available for unsupported Rx vectors handling (through DMA) -+ */ -+#define IPC_UNSUPRXVECBUF_CNT 8 -+ -+/* -+ * Size of RxVector -+ */ -+#define IPC_RXVEC_SIZE 16 -+ -+/* -+ * Number of Host buffers available for Emb->App MSGs sending (through DMA) -+ */ -+#ifdef CONFIG_RWNX_FULLMAC -+#define IPC_MSGE2A_BUF_CNT 64 -+#endif -+/* -+ * Number of Host buffers available for Debug Messages sending (through DMA) -+ */ -+#define IPC_DBGBUF_CNT 32 -+ -+/* -+ * Length used in MSGs structures -+ */ -+#define IPC_A2E_MSG_BUF_SIZE 127 // size in 4-byte words -+#ifdef CONFIG_RWNX_FULLMAC -+#define IPC_E2A_MSG_SIZE_BASE 256 // size in 4-byte words -+#endif -+ -+#ifdef CONFIG_RWNX_TL4 -+#define IPC_E2A_MSG_PARAM_SIZE (IPC_E2A_MSG_SIZE_BASE + (IPC_E2A_MSG_SIZE_BASE / 2)) -+#else -+#define IPC_E2A_MSG_PARAM_SIZE IPC_E2A_MSG_SIZE_BASE -+#endif -+ -+/* -+ * Debug messages buffers size (in bytes) -+ */ -+#define IPC_DBG_PARAM_SIZE 256 -+ -+/* -+ * Define used for Rx hostbuf validity. -+ * This value should appear only when hostbuf was used for a Reception. -+ */ -+#define RX_DMA_OVER_PATTERN 0xAAAAAA00 -+ -+/* -+ * Define used for MSG buffers validity. -+ * This value will be written only when a MSG buffer is used for sending from Emb to App. -+ */ -+#define IPC_MSGE2A_VALID_PATTERN 0xADDEDE2A -+ -+/* -+ * Define used for Debug messages buffers validity. -+ * This value will be written only when a DBG buffer is used for sending from Emb to App. -+ */ -+#define IPC_DBG_VALID_PATTERN 0x000CACA0 -+ -+/* -+ * Length of the receive vectors, in bytes -+ */ -+#define DMA_HDR_PHYVECT_LEN 36 -+ -+/* -+ * Maximum number of payload addresses and lengths present in the descriptor -+ */ -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+#define NX_TX_PAYLOAD_MAX 6 -+#else -+#define NX_TX_PAYLOAD_MAX 1 -+#endif -+ -+/* -+ * Message struct/ID API version -+ */ -+#define MSG_API_VER 33 -+ -+/* -+ **************************************************************************************** -+ */ -+// c.f LMAC/src/tx/tx_swdesc.h -+/// Descriptor filled by the Host -+struct hostdesc { -+ /// Pointer to packet payload -+ //u32_l packet_addr; -+ /// Size of the payload -+ u16_l packet_len; -+ u16_l flags_ext; -+ -+ u32_l hostid; -+#ifdef CONFIG_RWNX_FULLMAC -+ /// Address of the status descriptor in host memory (used for confirmation upload) -+ //u32_l status_desc_addr; -+ /// Destination Address -+ struct mac_addr eth_dest_addr; -+ /// Source Address -+ struct mac_addr eth_src_addr; -+ /// Ethernet Type -+ u16_l ethertype; -+#else /* ! CONFIG_RWNX_FULLMAC */ -+#ifdef CONFIG_RWNX_AGG_TX -+ ///Sequence Number for AMPDU MPDUs - for quick check if it's allowed within window -+ u16_l sn; -+#endif /* CONFIG_RWNX_AGG_TX */ -+ /// Padding between the buffer control structure and the MPDU in host memory -+ u8_l padding; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ u8_l ac; -+ /// Packet TID (0xFF if not a QoS frame) -+ u8_l tid; -+ /// Interface Id -+ u8_l vif_idx; -+ /// Station Id (0xFF if station is unknown) -+ u8_l staid; -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ /// MU-MIMO information (GroupId and User Position in the group) - The GroupId -+ /// is located on bits 0-5 and the User Position on bits 6-7. The GroupId value is set -+ /// to 63 if MU-MIMO shall not be used -+ u8_l mumimo_info; -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+#ifdef CONFIG_RWNX_FULLMAC -+ /// TX flags -+ u16_l flags; -+#endif /* CONFIG_RWNX_FULLMAC */ -+}; -+ -+/// Descriptor filled by the UMAC -+struct umacdesc { -+#ifdef CONFIG_RWNX_AGG_TX -+ ///First Sequence Number of the BlockAck window -+ u16_l sn_win; -+ /// Flags from UMAC (match tx_hd.macctrlinfo2 format) -+ u32_l flags; -+ /// PHY related flags field - rate, GI type, BW type - filled by driver -+ u32_l phy_flags; -+#endif //(CONFIG_RWNX_AGG_TX) -+}; -+ -+struct txdesc_api { -+ /// Information provided by Host -+ struct hostdesc host; -+}; -+ -+ -+struct txdesc_host { -+ u32_l ready; -+ -+ /// API of the embedded part -+ struct txdesc_api api; -+}; -+ -+/// Comes from ipc_dma.h -+/// Element in the pool of TX DMA bridge descriptors. -+struct dma_desc { -+ /** Application subsystem address which is used as source address for DMA payload -+ * transfer*/ -+ u32_l src; -+ /** Points to the start of the embedded data buffer associated with this descriptor. -+ * This address acts as the destination address for the DMA payload transfer*/ -+ u32_l dest; -+ /// Complete length of the buffer in memory -+ u16_l length; -+ /// Control word for the DMA engine (e.g. for interrupt generation) -+ u16_l ctrl; -+ /// Pointer to the next element of the chained list -+ u32_l next; -+}; -+ -+// Comes from la.h -+/// Length of the configuration data of a logic analyzer -+#define LA_CONF_LEN 10 -+ -+/// Structure containing the configuration data of a logic analyzer -+struct la_conf_tag { -+ u32_l conf[LA_CONF_LEN]; -+ u32_l trace_len; -+ u32_l diag_conf; -+}; -+ -+/// Size of a logic analyzer memory -+#define LA_MEM_LEN (1024 * 1024) -+ -+/// Type of errors -+enum { -+ /// Recoverable error, not requiring any action from Upper MAC -+ DBG_ERROR_RECOVERABLE = 0, -+ /// Fatal error, requiring Upper MAC to reset Lower MAC and HW and restart operation -+ DBG_ERROR_FATAL -+}; -+ -+/// Maximum length of the SW diag trace -+#define DBG_SW_DIAG_MAX_LEN 1024 -+ -+/// Maximum length of the error trace -+#define DBG_ERROR_TRACE_SIZE 256 -+ -+/// Number of MAC diagnostic port banks -+#define DBG_DIAGS_MAC_MAX 48 -+ -+/// Number of PHY diagnostic port banks -+#define DBG_DIAGS_PHY_MAX 32 -+ -+/// Maximum size of the RX header descriptor information in the debug dump -+#define DBG_RHD_MEM_LEN (5 * 1024) -+ -+/// Maximum size of the RX buffer descriptor information in the debug dump -+#define DBG_RBD_MEM_LEN (5 * 1024) -+ -+/// Maximum size of the TX header descriptor information in the debug dump -+#define DBG_THD_MEM_LEN (10 * 1024) -+ -+/// Structure containing the information about the PHY channel that is used -+struct phy_channel_info { -+ /// PHY channel information 1 -+ u32_l info1; -+ /// PHY channel information 2 -+ u32_l info2; -+}; -+ -+/// Debug information forwarded to host when an error occurs -+struct dbg_debug_info_tag { -+ /// Type of error (0: recoverable, 1: fatal) -+ u32_l error_type; -+ /// Pointer to the first RX Header Descriptor chained to the MAC HW -+ u32_l rhd; -+ /// Size of the RX header descriptor buffer -+ u32_l rhd_len; -+ /// Pointer to the first RX Buffer Descriptor chained to the MAC HW -+ u32_l rbd; -+ /// Size of the RX buffer descriptor buffer -+ u32_l rbd_len; -+ /// Pointer to the first TX Header Descriptors chained to the MAC HW -+ u32_l thd[NX_TXQ_CNT]; -+ /// Size of the TX header descriptor buffer -+ u32_l thd_len[NX_TXQ_CNT]; -+ /// MAC HW diag configuration -+ u32_l hw_diag; -+ /// Error message -+ u32_l error[DBG_ERROR_TRACE_SIZE/4]; -+ /// SW diag configuration length -+ u32_l sw_diag_len; -+ /// SW diag configuration -+ u32_l sw_diag[DBG_SW_DIAG_MAX_LEN/4]; -+ /// PHY channel information -+ struct phy_channel_info chan_info; -+ /// Embedded LA configuration -+ struct la_conf_tag la_conf; -+ /// MAC diagnostic port state -+ u16_l diags_mac[DBG_DIAGS_MAC_MAX]; -+ /// PHY diagnostic port state -+ u16_l diags_phy[DBG_DIAGS_PHY_MAX]; -+ /// MAC HW RX Header descriptor pointer -+ u32_l rhd_hw_ptr; -+ /// MAC HW RX Buffer descriptor pointer -+ u32_l rbd_hw_ptr; -+}; -+ -+/// Full debug dump that is forwarded to host in case of error -+struct dbg_debug_dump_tag { -+ /// Debug information -+ struct dbg_debug_info_tag dbg_info; -+ -+ /// RX header descriptor memory -+ u32_l rhd_mem[DBG_RHD_MEM_LEN/4]; -+ -+ /// RX buffer descriptor memory -+ u32_l rbd_mem[DBG_RBD_MEM_LEN/4]; -+ -+ /// TX header descriptor memory -+ u32_l thd_mem[NX_TXQ_CNT][DBG_THD_MEM_LEN/4]; -+ -+ /// Logic analyzer memory -+ u32_l la_mem[LA_MEM_LEN/4]; -+}; -+ -+ -+/// Number of pulses in a radar event structure -+#define RADAR_PULSE_MAX 4 -+ -+/// Definition of an array of radar pulses -+struct radar_pulse_array_desc { -+ /// Buffer containing the radar pulses -+ u32_l pulse[RADAR_PULSE_MAX]; -+ /// Index of the radar detection chain that detected those pulses -+ u32_l idx; -+ /// Number of valid pulses in the buffer -+ u32_l cnt; -+}; -+ -+/// Bit mapping inside a radar pulse element -+struct radar_pulse { -+ s32_l freq:6; /** Freq (resolution is 2Mhz range is [-Fadc/4 .. Fadc/4]) */ -+ u32_l fom:4; /** Figure of Merit */ -+ u32_l len:6; /** Length of the current radar pulse (resolution is 2us) */ -+ u32_l rep:16; /** Time interval between the previous radar event -+ and the current one (in us) */ -+}; -+ -+/// Definition of a RX vector descriptor -+struct rx_vector_desc { -+ /// PHY channel information -+ struct phy_channel_info phy_info; -+ -+ /// RX vector 1 -+ u32_l rx_vect1[IPC_RXVEC_SIZE/4]; -+ -+ /// Used to print a valid rx vector -+ u32_l pattern; -+}; -+ -+/// -+struct rxdesc_tag { -+ /// Host Buffer Address -+ u32_l host_id; -+ /// Length -+ u32_l frame_len; -+ /// Status -+ u16_l status; -+}; -+ -+/** -+ **************************************************************************************** -+ * @defgroup IPC IPC -+ * @ingroup NXMAC -+ * @brief Inter Processor Communication module. -+ * -+ * The IPC module implements the protocol to communicate between the Host CPU -+ * and the Embedded CPU. -+ * -+ * @see http://en.wikipedia.org/wiki/Circular_buffer -+ * For more information about the ring buffer typical use and difficulties. -+ **************************************************************************************** -+ */ -+ -+ -+/** -+ **************************************************************************************** -+ * @addtogroup IPC_TX IPC Tx path -+ * @ingroup IPC -+ * @brief IPC Tx path structures and functions -+ * -+ * A typical use case of the IPC Tx path API: -+ * @msc -+ * hscale = "2"; -+ * -+ * a [label=Driver], -+ * b [label="IPC host"], -+ * c [label="IPC emb"], -+ * d [label=Firmware]; -+ * -+ * --- [label="Tx descriptor queue example"]; -+ * a=>a [label="Driver receives a Tx packet from OS"]; -+ * a=>b [label="ipc_host_txdesc_get()"]; -+ * a<a [label="Driver fill the descriptor"]; -+ * a=>b [label="ipc_host_txdesc_push()"]; -+ * ... [label="(several Tx desc can be pushed)"]; -+ * b:>c [label="Tx desc queue filled IRQ"]; -+ * c=>>d [label="EDCA sub-scheduler callback"]; -+ * c<>d [label="UMAC Tx desc callback"]; -+ * ... [label="(several Tx desc can be popped)"]; -+ * d=>d [label="Packets are sent or discarded"]; -+ * --- [label="Tx confirm queue example"]; -+ * c<=d [label="ipc_emb_txcfm_push()"]; -+ * c>>d [label="Request accepted"]; -+ * ... [label="(several Tx cfm can be pushed)"]; -+ * b<:c [label="Tx cfm queue filled IRQ"]; -+ * a<<=b [label="Driver's Tx Confirm callback"]; -+ * a=>b [label="ipc_host_txcfm_pop()"]; -+ * a<c [label="ipc_host_rxbuf_push()"]; -+ * d=>c [label="ipc_host_rxbuf_push()"]; -+ * d=>c [label="ipc_host_rxbuf_push()"]; -+ * ... [label="(several Rx buffer are pushed)"]; -+ * a=>a [label=" Frame is received\n from the medium"]; -+ * a<a [label=" Firmware fill the buffer\n with received frame"]; -+ * a<c [label="Rx desc queue filled IRQ"]; -+ * c=>>d [label="Driver Rx packet callback"]; -+ * c<=d [label="ipc_host_rxdesc_pop()"]; -+ * d=>d [label="Rx packet is handed \nover to the OS "]; -+ * ... [label="(several Rx desc can be poped)"]; -+ * --- [label="Rx buffer request exemple"]; -+ * b:>c [label="Low Rx buffer count IRQ"]; -+ * a<>d [label="Driver Rx buffer callback"]; -+ * d=>c [label="ipc_host_rxbuf_push()"]; -+ * d=>c [label="ipc_host_rxbuf_push()"]; -+ * d=>c [label="ipc_host_rxbuf_push()"]; -+ * ... [label="(several Rx buffer are pushed)"]; -+ * @endmsc -+ * -+ * @addtogroup IPC_RX -+ * @{ -+ **************************************************************************************** -+ */ -+ -+/// @} IPC_RX -+ -+ -+ -+/** -+ **************************************************************************************** -+ * @defgroup IPC_MISC IPC Misc -+ * @ingroup IPC -+ * @brief IPC miscellaneous functions -+ **************************************************************************************** -+ */ -+/** IPC header structure. This structure is stored at the beginning of every IPC message. -+ * @warning This structure's size must NOT exceed 4 bytes in length. -+ */ -+struct ipc_header { -+ /// IPC message type. -+ u16_l type; -+ /// IPC message size in number of bytes. -+ u16_l size; -+}; -+ -+struct ipc_msg_elt { -+ /// Message header (alignment forced on word size, see allocation in shared env). -+ struct ipc_header header __ALIGN4; -+}; -+ -+/// Message structure for MSGs from Emb to App -+struct ipc_e2a_msg { -+ u16_l id; ///< Message id. -+ u16_l dummy_dest_id; -+ u16_l dummy_src_id; -+ u16_l param_len; ///< Parameter embedded struct length. -+ u32_l pattern; ///< Used to stamp a valid MSG buffer -+ u32_l param[IPC_E2A_MSG_PARAM_SIZE]; ///< Parameter embedded struct. Must be word-aligned. -+}; -+ -+/// Message structure for Debug messages from Emb to App -+struct ipc_dbg_msg { -+ u32_l string[IPC_DBG_PARAM_SIZE/4]; ///< Debug string -+ u32_l pattern; ///< Used to stamp a valid buffer -+}; -+ -+/// Message structure for MSGs from App to Emb. -+/// Actually a sub-structure will be used when filling the messages. -+struct ipc_a2e_msg { -+ u32_l dummy_word; // used to cope with kernel message structure -+ u32_l msg[IPC_A2E_MSG_BUF_SIZE]; // body of the msg -+}; -+ -+struct ipc_shared_rx_buf { -+ /// < ptr to hostbuf client (ipc_host client) structure -+ u32_l hostid; -+ /// < ptr to real hostbuf dma address -+ u32_l dma_addr; -+}; -+ -+struct ipc_shared_rx_desc { -+ /// DMA Address -+ u32_l dma_addr; -+}; -+ -+/// Structure containing FW characteristics for compatibility checking -+struct compatibility_tag { -+ /// Size of IPC shared memory -+ u16_l ipc_shared_size; -+ /// Message struct/ID API version -+ u16_l msg_api; -+ /// Version of IPC shared -+ u8_l ipc_shared_version; -+ /// Number of host buffers available for Emb->App MSGs sending -+ u8_l msge2a_buf_cnt; -+ /// Number of host buffers available for Debug Messages sending -+ u8_l dbgbuf_cnt; -+ /// Number of host buffers available for Radar events handling -+ u8_l radarbuf_cnt; -+ /// Number of host buffers available for unsupported Rx vectors handling -+ u8_l unsuprxvecbuf_cnt; -+ /// Number of shared descriptors available for Data RX handling -+ u8_l rxdesc_cnt; -+ /// Number of host buffers available for Data Rx handling -+ u8_l rxbuf_cnt; -+ /// Number of descriptors in BK TX queue (power of 2, min 4, max 64) -+ u8_l bk_txq; -+ /// Number of descriptors in BE TX queue (power of 2, min 4, max 64) -+ u8_l be_txq; -+ /// Number of descriptors in VI TX queue (power of 2, min 4, max 64) -+ u8_l vi_txq; -+ /// Number of descriptors in VO TX queue (power of 2, min 4, max 64) -+ u8_l vo_txq; -+ /// Number of descriptors in BCN TX queue (power of 2, min 4, max 64) -+ u8_l bcn_txq; -+}; -+ -+/* -+ * TYPE and STRUCT DEFINITIONS -+ **************************************************************************************** -+ */ -+ -+ -+// Indexes are defined in the MIB shared structure -+struct ipc_shared_env_tag { -+ volatile struct compatibility_tag comp_info; //FW characteristics -+ -+ volatile struct ipc_a2e_msg msg_a2e_buf; // room for MSG to be sent from App to Emb -+ -+ // Fields for MSGs sending from Emb to App -+ volatile struct ipc_e2a_msg msg_e2a_buf; // room to build the MSG to be DMA Xferred -+ volatile struct dma_desc msg_dma_desc; // DMA descriptor for Emb->App MSGs Xfers -+ volatile u32_l msg_e2a_hostbuf_addr[IPC_MSGE2A_BUF_CNT]; // buffers @ for DMA Xfers -+ -+ // Fields for Debug MSGs sending from Emb to App -+ volatile struct ipc_dbg_msg dbg_buf; // room to build the MSG to be DMA Xferred -+ volatile struct dma_desc dbg_dma_desc; // DMA descriptor for Emb->App MSGs Xfers -+ volatile u32_l dbg_hostbuf_addr[IPC_DBGBUF_CNT]; // buffers @ for MSGs DMA Xfers -+ volatile u32_l la_dbginfo_addr; // Host buffer address for the debug information -+ volatile u32_l pattern_addr; -+ volatile u32_l radarbuf_hostbuf[IPC_RADARBUF_CNT]; // buffers @ for Radar Events -+ volatile u32_l unsuprxvecbuf_hostbuf[IPC_UNSUPRXVECBUF_CNT]; // buffers @ for unsupported Rx vectors -+ volatile struct txdesc_host txdesc0[CONFIG_USER_MAX][NX_TXDESC_CNT0]; -+ volatile struct txdesc_host txdesc1[CONFIG_USER_MAX][NX_TXDESC_CNT1]; -+ volatile struct txdesc_host txdesc2[CONFIG_USER_MAX][NX_TXDESC_CNT2]; -+ volatile struct txdesc_host txdesc3[CONFIG_USER_MAX][NX_TXDESC_CNT3]; -+ #if NX_TXQ_CNT == 5 -+ volatile struct txdesc_host txdesc4[1][NX_TXDESC_CNT4]; -+ #endif -+ #ifdef CONFIG_RWNX_FULLMAC -+ // RX Descriptors Array -+ volatile struct ipc_shared_rx_desc host_rxdesc[IPC_RXDESC_CNT]; -+ // RX Buffers Array -+ volatile struct ipc_shared_rx_buf host_rxbuf[IPC_RXBUF_CNT]; -+ #else -+ // buffers @ for Data Rx -+ volatile u32_l host_rxbuf[IPC_RXBUF_CNT]; -+ #endif /* CONFIG_RWNX_FULLMAC */ -+ -+ u32_l buffered[NX_REMOTE_STA_MAX][TID_MAX]; -+ -+ volatile uint16_t trace_pattern; -+ volatile uint32_t trace_start; -+ volatile uint32_t trace_end; -+ volatile uint32_t trace_size; -+ volatile uint32_t trace_offset; -+ volatile uint32_t trace_nb_compo; -+ volatile uint32_t trace_offset_compo; -+}; -+ -+extern struct ipc_shared_env_tag ipc_shared_env; -+ -+ -+/* -+ * TYPE and STRUCT DEFINITIONS -+ **************************************************************************************** -+ */ -+ -+// IRQs from app to emb -+/// Interrupts bits used for the TX descriptors of the AC queues -+#ifdef CONFIG_RWNX_MUMIMO_TX -+#ifdef CONFIG_RWNX_OLD_IPC -+#error "MU-MIMO cannot be compiled for old IPC" -+#endif -+/// Interrupts bits used -+#if CONFIG_USER_MAX > 3 -+#define IPC_IRQ_A2E_USER_MSK 0xF -+#elif CONFIG_USER_MAX > 2 -+#define IPC_IRQ_A2E_USER_MSK 0x7 -+#else -+#define IPC_IRQ_A2E_USER_MSK 0x3 -+#endif -+ -+/// Offset of the interrupts for AC0 -+#define IPC_IRQ_A2E_AC0_OFT 8 -+/// Mask of the interrupts for AC0 -+#define IPC_IRQ_A2E_AC0_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC0_OFT) -+/// Offset of the interrupts for AC1 -+#define IPC_IRQ_A2E_AC1_OFT (IPC_IRQ_A2E_AC0_OFT + CONFIG_USER_MAX) -+/// Mask of the interrupts for AC1 -+#define IPC_IRQ_A2E_AC1_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC1_OFT) -+/// Offset of the interrupts for AC2 -+#define IPC_IRQ_A2E_AC2_OFT (IPC_IRQ_A2E_AC1_OFT + CONFIG_USER_MAX) -+/// Mask of the interrupts for AC2 -+#define IPC_IRQ_A2E_AC2_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC2_OFT) -+/// Offset of the interrupts for AC3 -+#define IPC_IRQ_A2E_AC3_OFT (IPC_IRQ_A2E_AC2_OFT + CONFIG_USER_MAX) -+/// Mask of the interrupts for AC3 -+#define IPC_IRQ_A2E_AC3_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC3_OFT) -+/// Offset of the interrupts for BCN -+#define IPC_IRQ_A2E_BCN_OFT (IPC_IRQ_A2E_AC3_OFT + CONFIG_USER_MAX) -+/// Mask of the interrupts for BCN -+#define IPC_IRQ_A2E_BCN_MSK CO_BIT(IPC_IRQ_A2E_BCN_OFT) -+ -+#define IPC_IRQ_A2E_AC_TXDESC (IPC_IRQ_A2E_AC0_MSK | IPC_IRQ_A2E_AC1_MSK | \ -+ IPC_IRQ_A2E_AC2_MSK | IPC_IRQ_A2E_AC3_MSK) -+ -+/// Interrupts bits used for the TX descriptors of the BCN queue -+#if NX_TXQ_CNT < 5 -+#define IPC_IRQ_A2E_BCN_TXDESC 0 -+#else -+#define IPC_IRQ_A2E_BCN_TXDESC (0x01 << IPC_IRQ_A2E_BCN_OFT) -+#endif -+ -+/// IPC TX descriptor interrupt mask -+#define IPC_IRQ_A2E_TXDESC (IPC_IRQ_A2E_AC_TXDESC | IPC_IRQ_A2E_BCN_TXDESC) -+#else -+/// IPC TX descriptor interrupt mask -+#define IPC_IRQ_A2E_TXDESC 0xFF00 -+#endif -+ -+#define IPC_IRQ_A2E_TXDESC_FIRSTBIT (8) -+#define IPC_IRQ_A2E_RXBUF_BACK CO_BIT(5) -+#define IPC_IRQ_A2E_RXDESC_BACK CO_BIT(4) -+ -+#define IPC_IRQ_A2E_MSG CO_BIT(1) -+#define IPC_IRQ_A2E_DBG CO_BIT(0) -+ -+#define IPC_IRQ_A2E_ALL (IPC_IRQ_A2E_TXDESC|IPC_IRQ_A2E_MSG|IPC_IRQ_A2E_DBG) -+ -+// IRQs from emb to app -+#define IPC_IRQ_E2A_TXCFM_POS 7 -+ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+#ifdef CONFIG_RWNX_OLD_IPC -+#error "MU-MIMO cannot be compiled for old IPC" -+#endif -+/// Interrupts bits used -+#if CONFIG_USER_MAX > 3 -+#define IPC_IRQ_E2A_USER_MSK 0xF -+#elif CONFIG_USER_MAX > 2 -+#define IPC_IRQ_E2A_USER_MSK 0x7 -+#else -+#define IPC_IRQ_E2A_USER_MSK 0x3 -+#endif -+ -+/// Offset of the interrupts for AC0 -+#define IPC_IRQ_E2A_AC0_OFT IPC_IRQ_E2A_TXCFM_POS -+/// Mask of the interrupts for AC0 -+#define IPC_IRQ_E2A_AC0_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC0_OFT) -+/// Offset of the interrupts for AC1 -+#define IPC_IRQ_E2A_AC1_OFT (IPC_IRQ_E2A_AC0_OFT + CONFIG_USER_MAX) -+/// Mask of the interrupts for AC1 -+#define IPC_IRQ_E2A_AC1_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC1_OFT) -+/// Offset of the interrupts for AC2 -+#define IPC_IRQ_E2A_AC2_OFT (IPC_IRQ_E2A_AC1_OFT + CONFIG_USER_MAX) -+/// Mask of the interrupts for AC2 -+#define IPC_IRQ_E2A_AC2_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC2_OFT) -+/// Offset of the interrupts for AC3 -+#define IPC_IRQ_E2A_AC3_OFT (IPC_IRQ_E2A_AC2_OFT + CONFIG_USER_MAX) -+/// Mask of the interrupts for AC3 -+#define IPC_IRQ_E2A_AC3_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC3_OFT) -+/// Offset of the interrupts for BCN -+#define IPC_IRQ_E2A_BCN_OFT (IPC_IRQ_E2A_AC3_OFT + CONFIG_USER_MAX) -+/// Mask of the interrupts for BCN -+#define IPC_IRQ_E2A_BCN_MSK CO_BIT(IPC_IRQ_E2A_BCN_OFT) -+ -+#define IPC_IRQ_E2A_AC_TXCFM (IPC_IRQ_E2A_AC0_MSK | IPC_IRQ_E2A_AC1_MSK | \ -+ IPC_IRQ_E2A_AC2_MSK | IPC_IRQ_E2A_AC3_MSK) -+ -+/// Interrupts bits used for the TX descriptors of the BCN queue -+#if NX_TXQ_CNT < 5 -+#define IPC_IRQ_E2A_BCN_TXCFM 0 -+#else -+#define IPC_IRQ_E2A_BCN_TXCFM (0x01 << IPC_IRQ_E2A_BCN_OFT) -+#endif -+ -+/// IPC TX descriptor interrupt mask -+#define IPC_IRQ_E2A_TXCFM (IPC_IRQ_E2A_AC_TXCFM | IPC_IRQ_E2A_BCN_TXCFM) -+ -+#else -+ -+#define IPC_IRQ_E2A_TXCFM (((1 << NX_TXQ_CNT) - 1) << IPC_IRQ_E2A_TXCFM_POS) -+ -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+ -+#define IPC_IRQ_E2A_UNSUP_RX_VEC CO_BIT(7) -+#define IPC_IRQ_E2A_RADAR CO_BIT(6) -+#define IPC_IRQ_E2A_TBTT_SEC CO_BIT(5) -+#define IPC_IRQ_E2A_TBTT_PRIM CO_BIT(4) -+#define IPC_IRQ_E2A_RXDESC CO_BIT(3) -+#define IPC_IRQ_E2A_MSG_ACK CO_BIT(2) -+#define IPC_IRQ_E2A_MSG CO_BIT(1) -+#define IPC_IRQ_E2A_DBG CO_BIT(0) -+ -+#define IPC_IRQ_E2A_ALL (IPC_IRQ_E2A_TXCFM \ -+ | IPC_IRQ_E2A_RXDESC \ -+ | IPC_IRQ_E2A_MSG_ACK \ -+ | IPC_IRQ_E2A_MSG \ -+ | IPC_IRQ_E2A_DBG \ -+ | IPC_IRQ_E2A_TBTT_PRIM \ -+ | IPC_IRQ_E2A_TBTT_SEC \ -+ | IPC_IRQ_E2A_RADAR \ -+ | IPC_IRQ_E2A_UNSUP_RX_VEC) -+ -+// FLAGS for RX desc -+#define IPC_RX_FORWARD CO_BIT(1) -+#define IPC_RX_INTRABSS CO_BIT(0) -+ -+ -+// IPC message TYPE -+enum { -+ IPC_MSG_NONE = 0, -+ IPC_MSG_WRAP, -+ IPC_MSG_KMSG, -+ -+ IPC_DBG_STRING, -+ -+}; -+ -+#endif // _IPC_SHARED_H_ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Kconfig linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Kconfig ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Kconfig 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,5 @@ -+config AIC8800_WLAN_SUPPORT -+ tristate "AIC8800 wlan Support" -+ help -+ This is support for aic wifi driver. -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_mac.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_mac.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_mac.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_mac.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,564 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file lmac_mac_types.h -+ * -+ * @brief MAC related definitions. -+ * -+ * Adapted from mac_types.h to used lmac_types.h instead of standard types -+ * eg: perl -pi -e '$_ =~ s/uint(\d{1,2})_t/u$1_l/g; \ -+ * $_ =~ s/int(\d{1,2})_t/s$1_l/g; \ -+ * $_ =~ s/CO_BIT/BIT/g;' lmac_mac.h -+ * -+ * Copyright (C) RivieraWaves 2011-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef LMAC_MAC_H_ -+#define LMAC_MAC_H_ -+ -+#include "lmac_types.h" -+ -+/// Interface types -+enum mac_vif_type { -+ /// ESS STA interface -+ VIF_STA, -+ /// IBSS STA interface -+ VIF_IBSS, -+ /// AP interface -+ VIF_AP, -+ /// Mesh Point interface -+ VIF_MESH_POINT, -+ /// Monitor interface -+ VIF_MONITOR, -+ /// Unknown type -+ VIF_UNKNOWN -+}; -+ -+/// MAC address length in bytes. -+#define MAC_ADDR_LEN 6 -+ -+/// MAC address structure. -+struct mac_addr { -+ /// Array of 16-bit words that make up the MAC address. -+ u16_l array[MAC_ADDR_LEN/2]; -+}; -+ -+/// SSID maximum length. -+#define MAC_SSID_LEN 32 -+ -+/// SSID. -+struct mac_ssid { -+ /// Actual length of the SSID. -+ u8_l length; -+ /// Array containing the SSID name. -+ u8_l array[MAC_SSID_LEN]; -+}; -+ -+/// BSS type -+enum mac_bss_type { -+ INFRASTRUCTURE_MODE = 1, -+ INDEPENDENT_BSS_MODE, -+ ANY_BSS_MODE -+}; -+ -+/// Channel Band -+enum mac_chan_band { -+ /// 2.4GHz Band -+ PHY_BAND_2G4, -+ /// 5GHz band -+ PHY_BAND_5G, -+ /// Number of bands -+ PHY_BAND_MAX, -+}; -+ -+/// Operating Channel Bandwidth -+enum mac_chan_bandwidth { -+ /// 20MHz BW -+ PHY_CHNL_BW_20, -+ /// 40MHz BW -+ PHY_CHNL_BW_40, -+ /// 80MHz BW -+ PHY_CHNL_BW_80, -+ /// 160MHz BW -+ PHY_CHNL_BW_160, -+ /// 80+80MHz BW -+ PHY_CHNL_BW_80P80, -+ /// Reserved BW -+ PHY_CHNL_BW_OTHER, -+}; -+ -+/// max number of channels in the 2.4 GHZ band -+#define MAC_DOMAINCHANNEL_24G_MAX 14 -+ -+/// max number of channels in the 5 GHZ band -+#define MAC_DOMAINCHANNEL_5G_MAX 28 -+ -+/// Channel Flag -+enum mac_chan_flags { -+ /// Cannot initiate radiation on this channel -+ CHAN_NO_IR = BIT(0), -+ /// Channel is not allowed -+ CHAN_DISABLED = BIT(1), -+ /// Radar detection required on this channel -+ CHAN_RADAR = BIT(2), -+}; -+ -+/// Primary Channel definition -+struct mac_chan_def { -+ /// Frequency of the channel (in MHz) -+ u16_l freq; -+ /// RF band (@ref mac_chan_band) -+ u8_l band; -+ /// Additional information (@ref mac_chan_flags) -+ u8_l flags; -+ /// Max transmit power allowed on this channel (dBm) -+ s8_l tx_power; -+}; -+ -+/// Operating Channel -+struct mac_chan_op { -+ /// Band (@ref mac_chan_band) -+ u8_l band; -+ /// Channel type (@ref mac_chan_bandwidth) -+ u8_l type; -+ /// Frequency for Primary 20MHz channel (in MHz) -+ u16_l prim20_freq; -+ /// Frequency center of the contiguous channel or center of Primary 80+80 (in MHz) -+ u16_l center1_freq; -+ /// Frequency center of the non-contiguous secondary 80+80 (in MHz) -+ u16_l center2_freq; -+ /// Max transmit power allowed on this channel (dBm) -+ s8_l tx_power; -+ /// Additional information (@ref mac_chan_flags) -+ u8_l flags; -+}; -+ -+/// Cipher suites (order is important as it is used by MACHW) -+enum mac_cipher_suite { -+ /// 00-0F-AC 1 -+ MAC_CIPHER_WEP40 = 0, -+ /// 00-0F-AC 2 -+ MAC_CIPHER_TKIP = 1, -+ /// 00-0F-AC 4 -+ MAC_CIPHER_CCMP = 2, -+ /// 00-0F-AC 5 -+ MAC_CIPHER_WEP104 = 3, -+ /// 00-14-72 1 -+ MAC_CIPHER_WPI_SMS4 = 4, -+ /// 00-0F-AC 6 (aka AES_CMAC) -+ MAC_CIPHER_BIP_CMAC_128 = 5, -+ -+ // following cipher are not supported by MACHW -+ /// 00-0F-AC 08 -+ MAC_CIPHER_GCMP_128, -+ /// 00-0F-AC 09 -+ MAC_CIPHER_GCMP_256, -+ /// 00-0F-AC 10 -+ MAC_CIPHER_CCMP_256, -+ /// 00-0F-AC 11 -+ MAC_CIPHER_BIP_GMAC_128, -+ /// 00-0F-AC 12 -+ MAC_CIPHER_BIP_GMAC_256, -+ /// 00-0F-AC 13 -+ MAC_CIPHER_BIP_CMAC_256, -+ -+ MAC_CIPHER_INVALID = 0xFF -+}; -+ -+/// Authentication and Key Management suite -+enum mac_akm_suite { -+ /// No security -+ MAC_AKM_NONE, -+ /// Pre RSN (WEP or WPA) -+ MAC_AKM_PRE_RSN, -+ /// 00-0F-AC 1 -+ MAC_AKM_8021X, -+ /// 00-0F-AC 2 -+ MAC_AKM_PSK, -+ /// 00-0F-AC 3 -+ MAC_AKM_FT_8021X, -+ /// 00-0F-AC 4 -+ MAC_AKM_FT_PSK, -+ /// 00-0F-AC 5 -+ MAC_AKM_8021X_SHA256, -+ /// 00-0F-AC 6 -+ MAC_AKM_PSK_SHA256, -+ /// 00-0F-AC 7 -+ MAC_AKM_TDLS, -+ /// 00-0F-AC 8 -+ MAC_AKM_SAE, -+ /// 00-0F-AC 9 -+ MAC_AKM_FT_OVER_SAE, -+ /// 00-0F-AC 11 -+ MAC_AKM_8021X_SUITE_B, -+ /// 00-0F-AC 12 -+ MAC_AKM_8021X_SUITE_B_192, -+ /// 00-0F-AC 14 -+ MAC_AKM_FILS_SHA256, -+ /// 00-0F-AC 15 -+ MAC_AKM_FILS_SHA384, -+ /// 00-0F-AC 16 -+ MAC_AKM_FT_FILS_SHA256, -+ /// 00-0F-AC 17 -+ MAC_AKM_FT_FILS_SHA384, -+ /// 00-0F-AC 18 -+ MAC_AKM_OWE, -+ -+ /// 00-14-72 1 -+ MAC_AKM_WAPI_CERT, -+ /// 00-14-72 2 -+ MAC_AKM_WAPI_PSK, -+}; -+ -+/// Scan result element, parsed from beacon or probe response frames. -+struct mac_scan_result { -+ /// Scan result is valid -+ bool valid_flag; -+ /// Network BSSID. -+ struct mac_addr bssid; -+ /// Network name. -+ struct mac_ssid ssid; -+ /// Network type (@ref mac_bss_type). -+ u16_l bsstype; -+ /// Network channel. -+ struct mac_chan_def *chan; -+ /// Network beacon period (in TU). -+ u16_l beacon_period; -+ /// Capability information -+ u16_l cap_info; -+ /// Supported AKM (bit-field of @ref mac_akm_suite) -+ u32_l akm; -+ /// Group cipher (bit-field of @ref mac_cipher_suite) -+ u16_l group_cipher; -+ /// Group cipher (bit-field of @ref mac_cipher_suite) -+ u16_l pairwise_cipher; -+ /// RSSI of the scanned BSS (in dBm) -+ s8_l rssi; -+}; -+ -+/// Legacy rate 802.11 definitions -+enum mac_legacy_rates { -+ /// DSSS/CCK 1Mbps -+ MAC_RATE_1MBPS = 2, -+ /// DSSS/CCK 2Mbps -+ MAC_RATE_2MBPS = 4, -+ /// DSSS/CCK 5.5Mbps -+ MAC_RATE_5_5MBPS = 11, -+ /// OFDM 6Mbps -+ MAC_RATE_6MBPS = 12, -+ /// OFDM 9Mbps -+ MAC_RATE_9MBPS = 18, -+ /// DSSS/CCK 11Mbps -+ MAC_RATE_11MBPS = 22, -+ /// OFDM 12Mbps -+ MAC_RATE_12MBPS = 24, -+ /// OFDM 18Mbps -+ MAC_RATE_18MBPS = 36, -+ /// OFDM 24Mbps -+ MAC_RATE_24MBPS = 48, -+ /// OFDM 36Mbps -+ MAC_RATE_36MBPS = 72, -+ /// OFDM 48Mbps -+ MAC_RATE_48MBPS = 96, -+ /// OFDM 54Mbps -+ MAC_RATE_54MBPS = 108 -+}; -+ -+/// BSS Membership Selector definitions -+enum mac_bss_membership { -+ /// HT PHY -+ MAC_BSS_MEMBERSHIP_HT_PHY = 127, -+ /// VHT PHY -+ MAC_BSS_MEMBERSHIP_VHT_PHY = 126, -+}; -+ -+/// MAC rateset maximum length -+#define MAC_RATESET_LEN 12 -+ -+/// Structure containing the legacy rateset of a station -+struct mac_rateset { -+ /// Number of legacy rates supported -+ u8_l length; -+ /// Array of legacy rates -+ u8_l array[MAC_RATESET_LEN]; -+}; -+ -+/// MAC Security Key maximum length -+#define MAC_SEC_KEY_LEN 32 // TKIP keys 256 bits (max length) with MIC keys -+ -+/// Structure defining a security key -+struct mac_sec_key { -+ /// Key material length -+ u8_l length; -+ /// Key material -+ u32_l array[MAC_SEC_KEY_LEN/4]; -+}; -+ -+/// Access Category enumeration -+enum mac_ac { -+ /// Background -+ AC_BK = 0, -+ /// Best-effort -+ AC_BE, -+ /// Video -+ AC_VI, -+ /// Voice -+ AC_VO, -+ /// Number of access categories -+ AC_MAX -+}; -+ -+/// Traffic ID enumeration -+enum mac_tid { -+ /// TID_0. Mapped to @ref AC_BE as per 802.11 standard. -+ TID_0, -+ /// TID_1. Mapped to @ref AC_BK as per 802.11 standard. -+ TID_1, -+ /// TID_2. Mapped to @ref AC_BK as per 802.11 standard. -+ TID_2, -+ /// TID_3. Mapped to @ref AC_BE as per 802.11 standard. -+ TID_3, -+ /// TID_4. Mapped to @ref AC_VI as per 802.11 standard. -+ TID_4, -+ /// TID_5. Mapped to @ref AC_VI as per 802.11 standard. -+ TID_5, -+ /// TID_6. Mapped to @ref AC_VO as per 802.11 standard. -+ TID_6, -+ /// TID_7. Mapped to @ref AC_VO as per 802.11 standard. -+ TID_7, -+ /// Non standard Management TID used internally -+ TID_MGT, -+ /// Number of TID supported -+ TID_MAX -+}; -+ -+/// MCS bitfield maximum size (in bytes) -+#define MAX_MCS_LEN 16 // 16 * 8 = 128 -+ -+/// MAC HT capability information element -+struct mac_htcapability { -+ /// HT capability information -+ u16_l ht_capa_info; -+ /// A-MPDU parameters -+ u8_l a_mpdu_param; -+ /// Supported MCS -+ u8_l mcs_rate[MAX_MCS_LEN]; -+ /// HT extended capability information -+ u16_l ht_extended_capa; -+ /// Beamforming capability information -+ u32_l tx_beamforming_capa; -+ /// Antenna selection capability information -+ u8_l asel_capa; -+}; -+ -+/// MAC VHT capability information element -+struct mac_vhtcapability { -+ /// VHT capability information -+ u32_l vht_capa_info; -+ /// RX MCS map -+ u16_l rx_mcs_map; -+ /// RX highest data rate -+ u16_l rx_highest; -+ /// TX MCS map -+ u16_l tx_mcs_map; -+ /// TX highest data rate -+ u16_l tx_highest; -+}; -+ -+/// Length (in bytes) of the MAC HE capability field -+#define MAC_HE_MAC_CAPA_LEN 6 -+/// Length (in bytes) of the PHY HE capability field -+#define MAC_HE_PHY_CAPA_LEN 11 -+/// Maximum length (in bytes) of the PPE threshold data -+#define MAC_HE_PPE_THRES_MAX_LEN 25 -+ -+/// Structure listing the per-NSS, per-BW supported MCS combinations -+struct mac_he_mcs_nss_supp { -+ /// per-NSS supported MCS in RX, for BW <= 80MHz -+ u16_l rx_mcs_80; -+ /// per-NSS supported MCS in TX, for BW <= 80MHz -+ u16_l tx_mcs_80; -+ /// per-NSS supported MCS in RX, for BW = 160MHz -+ u16_l rx_mcs_160; -+ /// per-NSS supported MCS in TX, for BW = 160MHz -+ u16_l tx_mcs_160; -+ /// per-NSS supported MCS in RX, for BW = 80+80MHz -+ u16_l rx_mcs_80p80; -+ /// per-NSS supported MCS in TX, for BW = 80+80MHz -+ u16_l tx_mcs_80p80; -+}; -+ -+/// MAC HE capability information element -+struct mac_hecapability { -+ /// MAC HE capabilities -+ u8_l mac_cap_info[MAC_HE_MAC_CAPA_LEN]; -+ /// PHY HE capabilities -+ u8_l phy_cap_info[MAC_HE_PHY_CAPA_LEN]; -+ /// Supported MCS combinations -+ struct mac_he_mcs_nss_supp mcs_supp; -+ /// PPE Thresholds data -+ u8_l ppe_thres[MAC_HE_PPE_THRES_MAX_LEN]; -+}; -+ -+/// Station flags -+enum mac_sta_flags { -+ /// Bit indicating that a STA has QoS (WMM) capability -+ STA_QOS_CAPA = BIT(0), -+ /// Bit indicating that a STA has HT capability -+ STA_HT_CAPA = BIT(1), -+ /// Bit indicating that a STA has VHT capability -+ STA_VHT_CAPA = BIT(2), -+ /// Bit indicating that a STA has MFP capability -+ STA_MFP_CAPA = BIT(3), -+ /// Bit indicating that the STA included the Operation Notification IE -+ STA_OPMOD_NOTIF = BIT(4), -+ /// Bit indicating that a STA has HE capability -+ STA_HE_CAPA = BIT(5), -+}; -+ -+/// Connection flags -+enum mac_connection_flags { -+ /// Flag indicating whether the control port is controlled by host or not -+ CONTROL_PORT_HOST = BIT(0), -+ /// Flag indicating whether the control port frame shall be sent unencrypted -+ CONTROL_PORT_NO_ENC = BIT(1), -+ /// Flag indicating whether HT and VHT shall be disabled or not -+ DISABLE_HT = BIT(2), -+ /// Flag indicating whether WPA or WPA2 authentication is in use -+ WPA_WPA2_IN_USE = BIT(3), -+ /// Flag indicating whether MFP is in use -+ MFP_IN_USE = BIT(4), -+ // Flag indicating Roam -+ REASSOCIATION = BIT(5), -+}; -+ -+#ifdef CONFIG_HE_FOR_OLD_KERNEL -+#define IEEE80211_HE_MAC_CAP2_ALL_ACK 0x02 -+#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G 0x02 -+#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G 0x04 -+#define IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD 0x20 -+#define IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US 0x40 -+#define IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS 0x80 -+#define IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS 0x01 -+#define IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US 0x02 -+#define IEEE80211_HE_PHY_CAP2_DOPPLER_RX 0x20 -+#define IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ 0x08 -+#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM 0x18 -+#define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 0x00 -+#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40 -+#define IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE 0x01 -+#define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 0x0c -+#define IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK 0x40 -+#define IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK 0x80 -+#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU 0x01 -+#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU 0x02 -+#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB 0x04 -+#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB 0x08 -+#define IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT 0x80 -+#define IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO 0x40 -+#define IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI 0x04 -+#define IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G 0x02 -+#define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB 0x10 -+#define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB 0x20 -+ -+#define IEEE80211_HE_PPE_THRES_MAX_LEN 25 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) -+#define WLAN_EID_EXTENSION 255 -+/* Element ID Extensions for Element ID 255 */ -+ -+enum ieee80211_eid_ext { -+ WLAN_EID_EXT_ASSOC_DELAY_INFO = 1, -+ WLAN_EID_EXT_FILS_REQ_PARAMS = 2, -+ WLAN_EID_EXT_FILS_KEY_CONFIRM = 3, -+ WLAN_EID_EXT_FILS_SESSION = 4, -+ WLAN_EID_EXT_FILS_HLP_CONTAINER = 5, -+ WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN = 6, -+ WLAN_EID_EXT_KEY_DELIVERY = 7, -+ WLAN_EID_EXT_FILS_WRAPPED_DATA = 8, -+ WLAN_EID_EXT_FILS_PUBLIC_KEY = 12, -+ WLAN_EID_EXT_FILS_NONCE = 13, -+ WLAN_EID_EXT_FUTURE_CHAN_GUIDANCE = 14, -+ -+}; -+ -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) -+#define WLAN_EID_EXT_HE_CAPABILITY 35 -+#define WLAN_EID_EXT_HE_OPERATION 36 -+#define WLAN_EID_EXT_UORA 37 -+#define WLAN_EID_EXT_HE_MU_EDCA 38 -+#define WLAN_EID_EXT_HE_SPR 39 -+#define WLAN_EID_EXT_NDP_FEEDBACK_REPORT_PARAMSET 41 -+#define WLAN_EID_EXT_BSS_COLOR_CHG_ANN 42 -+#define WLAN_EID_EXT_QUIET_TIME_PERIOD_SETUP 43 -+#define WLAN_EID_EXT_ESS_REPORT 45 -+#define WLAN_EID_EXT_OPS 46 -+#define WLAN_EID_EXT_HE_BSS_LOAD 47 -+#define WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME 52 -+#define WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION 55 -+#define WLAN_EID_EXT_NON_INHERITANCE 56 -+#define WLAN_EID_EXT_KNOWN_BSSID 57 -+#define WLAN_EID_EXT_SHORT_SSID_LIST 58 -+#define WLAN_EID_EXT_HE_6GHZ_CAPA 59 -+#define WLAN_EID_EXT_UL_MU_POWER_CAPA 60 -+#define WLAN_EID_EXT_EHT_OPERATION 106 -+#define WLAN_EID_EXT_EHT_MULTI_LINK 107 -+#define WLAN_EID_EXT_EHT_CAPABILITY 108 -+#endif -+ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+#include -+#else -+struct ieee80211_he_cap_elem { -+ u8 mac_cap_info[6]; -+ u8 phy_cap_info[11]; -+} __packed; -+ -+struct ieee80211_he_mcs_nss_supp { -+ __le16 rx_mcs_80; -+ __le16 tx_mcs_80; -+ __le16 rx_mcs_160; -+ __le16 tx_mcs_160; -+ __le16 rx_mcs_80p80; -+ __le16 tx_mcs_80p80; -+} __packed; -+ -+struct ieee80211_sta_he_cap { -+ bool has_he; -+ struct ieee80211_he_cap_elem he_cap_elem; -+ struct ieee80211_he_mcs_nss_supp he_mcs_nss_supp; -+ u8 ppe_thres[IEEE80211_HE_PPE_THRES_MAX_LEN]; -+}; -+ -+struct ieee80211_sband_iftype_data { -+ u16 types_mask; -+ struct ieee80211_sta_he_cap he_cap; -+}; -+#endif -+#endif -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) -+struct ieee80211_vht_mcs_info { -+ __le16 rx_mcs_map; -+ __le16 rx_highest; -+ __le16 tx_mcs_map; -+ __le16 tx_highest; -+} __packed; -+ -+struct ieee80211_vht_cap { -+ __le32 vht_cap_info; -+ struct ieee80211_vht_mcs_info supp_mcs; -+}; -+#define WLAN_EID_VHT_CAPABILITY 191 -+ -+struct ieee80211_sta_vht_cap { -+ bool vht_supported; -+ u32 cap; /* use IEEE80211_VHT_CAP_ */ -+ struct ieee80211_vht_mcs_info vht_mcs; -+}; -+#endif -+#endif // LMAC_MAC_H_ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_msg.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_msg.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_msg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_msg.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,3082 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file lmac_msg.h -+ * -+ * @brief Main definitions for message exchanges with LMAC -+ * -+ * Copyright (C) RivieraWaves 2011-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef LMAC_MSG_H_ -+#define LMAC_MSG_H_ -+ -+/* -+ * INCLUDE FILES -+ **************************************************************************************** -+ */ -+// for MAC related elements (mac_addr, mac_ssid...) -+#include "lmac_mac.h" -+ -+/* -+ **************************************************************************************** -+ */ -+///////////////////////////////////////////////////////////////////////////////// -+// COMMUNICATION WITH LMAC LAYER -+///////////////////////////////////////////////////////////////////////////////// -+/* Task identifiers for communication between LMAC and DRIVER */ -+enum { -+ TASK_NONE = (u8_l) -1, -+ -+ // MAC Management task. -+ TASK_MM = 0, -+ // DEBUG task -+ TASK_DBG, -+ /// SCAN task -+ TASK_SCAN, -+ /// TDLS task -+ TASK_TDLS, -+ /// SCANU task -+ TASK_SCANU, -+ /// ME task -+ TASK_ME, -+ /// SM task -+ TASK_SM, -+ /// APM task -+ TASK_APM, -+ /// BAM task -+ TASK_BAM, -+ /// MESH task -+ TASK_MESH, -+ /// RXU task -+ TASK_RXU, -+ /// RM_task -+ TASK_RM, -+ /// TWT task -+ TASK_TWT, -+#if defined CONFIG_RWNX_FULLMAC || defined CONFIG_RWNX_FHOST -+ // This is used to define the last task that is running on the EMB processor -+ TASK_LAST_EMB = TASK_TWT, -+#else -+#error "Need to define SOFTMAC or FULLMAC" -+#endif -+ // nX API task -+ TASK_API, -+ TASK_MAX, -+}; -+ -+ -+/// For MAC HW States copied from "hal_machw.h" -+enum { -+ /// MAC HW IDLE State. -+ HW_IDLE = 0, -+ /// MAC HW RESERVED State. -+ HW_RESERVED, -+ /// MAC HW DOZE State. -+ HW_DOZE, -+ /// MAC HW ACTIVE State. -+ HW_ACTIVE -+}; -+ -+/// Power Save mode setting -+enum mm_ps_mode_state { -+ MM_PS_MODE_OFF, -+ MM_PS_MODE_ON, -+ MM_PS_MODE_ON_DYN, -+}; -+ -+/// Status/error codes used in the MAC software. -+enum { -+ CO_OK, -+ CO_FAIL, -+ CO_EMPTY, -+ CO_FULL, -+ CO_BAD_PARAM, -+ CO_NOT_FOUND, -+ CO_NO_MORE_ELT_AVAILABLE, -+ CO_NO_ELT_IN_USE, -+ CO_BUSY, -+ CO_OP_IN_PROGRESS, -+}; -+ -+/// Remain on channel operation codes -+enum mm_remain_on_channel_op { -+ MM_ROC_OP_START = 0, -+ MM_ROC_OP_CANCEL, -+}; -+ -+#define DRV_TASK_ID 100 -+ -+/// Message Identifier. The number of messages is limited to 0xFFFF. -+/// The message ID is divided in two parts: -+/// - bits[15..10] : task index (no more than 64 tasks supported). -+/// - bits[9..0] : message index (no more that 1024 messages per task). -+typedef u16 lmac_msg_id_t; -+ -+typedef u16 lmac_task_id_t; -+ -+/// Build the first message ID of a task. -+#define LMAC_FIRST_MSG(task) ((lmac_msg_id_t)((task) << 10)) -+ -+#define MSG_T(msg) ((lmac_task_id_t)((msg) >> 10)) -+#define MSG_I(msg) ((msg) & ((1<<10)-1)) -+ -+/// Message structure. -+struct lmac_msg { -+ lmac_msg_id_t id; ///< Message id. -+ lmac_task_id_t dest_id; ///< Destination kernel identifier. -+ lmac_task_id_t src_id; ///< Source kernel identifier. -+ u16 param_len; ///< Parameter embedded struct length. -+ u32 param[]; ///< Parameter embedded struct. Must be word-aligned. -+}; -+ -+/// List of messages related to the task. -+enum mm_msg_tag { -+ /// RESET Request. -+ MM_RESET_REQ = LMAC_FIRST_MSG(TASK_MM), -+ /// RESET Confirmation. -+ MM_RESET_CFM, -+ /// START Request. -+ MM_START_REQ, -+ /// START Confirmation. -+ MM_START_CFM, -+ /// Read Version Request. -+ MM_VERSION_REQ, -+ /// Read Version Confirmation. -+ MM_VERSION_CFM, -+ /// ADD INTERFACE Request. -+ MM_ADD_IF_REQ, -+ /// ADD INTERFACE Confirmation. -+ MM_ADD_IF_CFM, -+ /// REMOVE INTERFACE Request. -+ MM_REMOVE_IF_REQ, -+ /// REMOVE INTERFACE Confirmation. -+ MM_REMOVE_IF_CFM, -+ /// STA ADD Request. -+ MM_STA_ADD_REQ, -+ /// STA ADD Confirm. -+ MM_STA_ADD_CFM, -+ /// STA DEL Request. -+ MM_STA_DEL_REQ, -+ /// STA DEL Confirm. -+ MM_STA_DEL_CFM, -+ /// RX FILTER CONFIGURATION Request. -+ MM_SET_FILTER_REQ, -+ /// RX FILTER CONFIGURATION Confirmation. -+ MM_SET_FILTER_CFM, -+ /// CHANNEL CONFIGURATION Request. -+ MM_SET_CHANNEL_REQ, -+ /// CHANNEL CONFIGURATION Confirmation. -+ MM_SET_CHANNEL_CFM, -+ /// DTIM PERIOD CONFIGURATION Request. -+ MM_SET_DTIM_REQ, -+ /// DTIM PERIOD CONFIGURATION Confirmation. -+ MM_SET_DTIM_CFM, -+ /// BEACON INTERVAL CONFIGURATION Request. -+ MM_SET_BEACON_INT_REQ, -+ /// BEACON INTERVAL CONFIGURATION Confirmation. -+ MM_SET_BEACON_INT_CFM, -+ /// BASIC RATES CONFIGURATION Request. -+ MM_SET_BASIC_RATES_REQ, -+ /// BASIC RATES CONFIGURATION Confirmation. -+ MM_SET_BASIC_RATES_CFM, -+ /// BSSID CONFIGURATION Request. -+ MM_SET_BSSID_REQ, -+ /// BSSID CONFIGURATION Confirmation. -+ MM_SET_BSSID_CFM, -+ /// EDCA PARAMETERS CONFIGURATION Request. -+ MM_SET_EDCA_REQ, -+ /// EDCA PARAMETERS CONFIGURATION Confirmation. -+ MM_SET_EDCA_CFM, -+ /// ABGN MODE CONFIGURATION Request. -+ MM_SET_MODE_REQ, -+ /// ABGN MODE CONFIGURATION Confirmation. -+ MM_SET_MODE_CFM, -+ /// Request setting the VIF active state (i.e associated or AP started) -+ MM_SET_VIF_STATE_REQ, -+ /// Confirmation of the @ref MM_SET_VIF_STATE_REQ message. -+ MM_SET_VIF_STATE_CFM, -+ /// SLOT TIME PARAMETERS CONFIGURATION Request. -+ MM_SET_SLOTTIME_REQ, -+ /// SLOT TIME PARAMETERS CONFIGURATION Confirmation. -+ MM_SET_SLOTTIME_CFM, -+ /// Power Mode Change Request. -+ MM_SET_IDLE_REQ, -+ /// Power Mode Change Confirm. -+ MM_SET_IDLE_CFM, -+ /// KEY ADD Request. -+ MM_KEY_ADD_REQ, -+ /// KEY ADD Confirm. -+ MM_KEY_ADD_CFM, -+ /// KEY DEL Request. -+ MM_KEY_DEL_REQ, -+ /// KEY DEL Confirm. -+ MM_KEY_DEL_CFM, -+ /// Block Ack agreement info addition -+ MM_BA_ADD_REQ, -+ /// Block Ack agreement info addition confirmation -+ MM_BA_ADD_CFM, -+ /// Block Ack agreement info deletion -+ MM_BA_DEL_REQ, -+ /// Block Ack agreement info deletion confirmation -+ MM_BA_DEL_CFM, -+ /// Indication of the primary TBTT to the upper MAC. Upon the reception of this -+ // message the upper MAC has to push the beacon(s) to the beacon transmission queue. -+ MM_PRIMARY_TBTT_IND, -+ /// Indication of the secondary TBTT to the upper MAC. Upon the reception of this -+ // message the upper MAC has to push the beacon(s) to the beacon transmission queue. -+ MM_SECONDARY_TBTT_IND, -+ /// Request for changing the TX power -+ MM_SET_POWER_REQ, -+ /// Confirmation of the TX power change -+ MM_SET_POWER_CFM, -+ /// Request to the LMAC to trigger the embedded logic analyzer and forward the debug -+ /// dump. -+ MM_DBG_TRIGGER_REQ, -+ /// Set Power Save mode -+ MM_SET_PS_MODE_REQ, -+ /// Set Power Save mode confirmation -+ MM_SET_PS_MODE_CFM, -+ /// Request to add a channel context -+ MM_CHAN_CTXT_ADD_REQ, -+ /// Confirmation of the channel context addition -+ MM_CHAN_CTXT_ADD_CFM, -+ /// Request to delete a channel context -+ MM_CHAN_CTXT_DEL_REQ, -+ /// Confirmation of the channel context deletion -+ MM_CHAN_CTXT_DEL_CFM, -+ /// Request to link a channel context to a VIF -+ MM_CHAN_CTXT_LINK_REQ, -+ /// Confirmation of the channel context link -+ MM_CHAN_CTXT_LINK_CFM, -+ /// Request to unlink a channel context from a VIF -+ MM_CHAN_CTXT_UNLINK_REQ, -+ /// Confirmation of the channel context unlink -+ MM_CHAN_CTXT_UNLINK_CFM, -+ /// Request to update a channel context -+ MM_CHAN_CTXT_UPDATE_REQ, -+ /// Confirmation of the channel context update -+ MM_CHAN_CTXT_UPDATE_CFM, -+ /// Request to schedule a channel context -+ MM_CHAN_CTXT_SCHED_REQ, -+ /// Confirmation of the channel context scheduling -+ MM_CHAN_CTXT_SCHED_CFM, -+ /// Request to change the beacon template in LMAC -+ MM_BCN_CHANGE_REQ, -+ /// Confirmation of the beacon change -+ MM_BCN_CHANGE_CFM, -+ /// Request to update the TIM in the beacon (i.e to indicate traffic bufferized at AP) -+ MM_TIM_UPDATE_REQ, -+ /// Confirmation of the TIM update -+ MM_TIM_UPDATE_CFM, -+ /// Connection loss indication -+ MM_CONNECTION_LOSS_IND, -+ /// Channel context switch indication to the upper layers -+ MM_CHANNEL_SWITCH_IND, -+ /// Channel context pre-switch indication to the upper layers -+ MM_CHANNEL_PRE_SWITCH_IND, -+ /// Request to remain on channel or cancel remain on channel -+ MM_REMAIN_ON_CHANNEL_REQ, -+ /// Confirmation of the (cancel) remain on channel request -+ MM_REMAIN_ON_CHANNEL_CFM, -+ /// Remain on channel expired indication -+ MM_REMAIN_ON_CHANNEL_EXP_IND, -+ /// Indication of a PS state change of a peer device -+ MM_PS_CHANGE_IND, -+ /// Indication that some buffered traffic should be sent to the peer device -+ MM_TRAFFIC_REQ_IND, -+ /// Request to modify the STA Power-save mode options -+ MM_SET_PS_OPTIONS_REQ, -+ /// Confirmation of the PS options setting -+ MM_SET_PS_OPTIONS_CFM, -+ /// Indication of PS state change for a P2P VIF -+ MM_P2P_VIF_PS_CHANGE_IND, -+ /// Indication that CSA counter has been updated -+ MM_CSA_COUNTER_IND, -+ /// Channel occupation report indication -+ MM_CHANNEL_SURVEY_IND, -+ /// Message containing Beamformer Information -+ MM_BFMER_ENABLE_REQ, -+ /// Request to Start/Stop/Update NOA - GO Only -+ MM_SET_P2P_NOA_REQ, -+ /// Request to Start/Stop/Update Opportunistic PS - GO Only -+ MM_SET_P2P_OPPPS_REQ, -+ /// Start/Stop/Update NOA Confirmation -+ MM_SET_P2P_NOA_CFM, -+ /// Start/Stop/Update Opportunistic PS Confirmation -+ MM_SET_P2P_OPPPS_CFM, -+ /// P2P NoA Update Indication - GO Only -+ MM_P2P_NOA_UPD_IND, -+ /// Request to set RSSI threshold and RSSI hysteresis -+ MM_CFG_RSSI_REQ, -+ /// Indication that RSSI level is below or above the threshold -+ MM_RSSI_STATUS_IND, -+ /// Indication that CSA is done -+ MM_CSA_FINISH_IND, -+ /// Indication that CSA is in prorgess (resp. done) and traffic must be stopped (resp. restarted) -+ MM_CSA_TRAFFIC_IND, -+ /// Request to update the group information of a station -+ MM_MU_GROUP_UPDATE_REQ, -+ /// Confirmation of the @ref MM_MU_GROUP_UPDATE_REQ message -+ MM_MU_GROUP_UPDATE_CFM, -+ /// Request to initialize the antenna diversity algorithm -+ MM_ANT_DIV_INIT_REQ, -+ /// Request to stop the antenna diversity algorithm -+ MM_ANT_DIV_STOP_REQ, -+ /// Request to update the antenna switch status -+ MM_ANT_DIV_UPDATE_REQ, -+ /// Request to switch the antenna connected to path_0 -+ MM_SWITCH_ANTENNA_REQ, -+ /// Indication that a packet loss has occurred -+ MM_PKTLOSS_IND, -+ -+ MM_SET_ARPOFFLOAD_REQ, -+ MM_SET_ARPOFFLOAD_CFM, -+ MM_SET_AGG_DISABLE_REQ, -+ MM_SET_AGG_DISABLE_CFM, -+ MM_SET_COEX_REQ, -+ MM_SET_COEX_CFM, -+ MM_SET_RF_CONFIG_REQ, -+ MM_SET_RF_CONFIG_CFM, -+ MM_SET_RF_CALIB_REQ, -+ MM_SET_RF_CALIB_CFM, -+ -+ /// MU EDCA PARAMETERS Configuration Request. -+ MM_SET_MU_EDCA_REQ, -+ /// MU EDCA PARAMETERS Configuration Confirmation. -+ MM_SET_MU_EDCA_CFM, -+ /// UORA PARAMETERS Configuration Request. -+ MM_SET_UORA_REQ, -+ /// UORA PARAMETERS Configuration Confirmation. -+ MM_SET_UORA_CFM, -+ /// TXOP RTS THRESHOLD Configuration Request. -+ MM_SET_TXOP_RTS_THRES_REQ, -+ /// TXOP RTS THRESHOLD Configuration Confirmation. -+ MM_SET_TXOP_RTS_THRES_CFM, -+ /// HE BSS Color Configuration Request. -+ MM_SET_BSS_COLOR_REQ, -+ /// HE BSS Color Configuration Confirmation. -+ MM_SET_BSS_COLOR_CFM, -+ -+ MM_GET_MAC_ADDR_REQ, -+ MM_GET_MAC_ADDR_CFM, -+ -+ MM_GET_STA_INFO_REQ, -+ MM_GET_STA_INFO_CFM, -+ -+ MM_SET_TXPWR_IDX_LVL_REQ, -+ MM_SET_TXPWR_IDX_LVL_CFM, -+ -+ MM_SET_TXPWR_OFST_REQ, -+ MM_SET_TXPWR_OFST_CFM, -+ -+ MM_SET_STACK_START_REQ, -+ MM_SET_STACK_START_CFM, -+ -+ MM_APM_STALOSS_IND, -+ -+ MM_SET_VENDOR_HWCONFIG_REQ, -+ MM_SET_VENDOR_HWCONFIG_CFM, -+ -+ MM_GET_FW_VERSION_REQ, -+ MM_GET_FW_VERSION_CFM, -+ -+ MM_SET_RESUME_RESTORE_REQ, -+ MM_SET_RESUME_RESTORE_CFM, -+ -+ MM_GET_WIFI_DISABLE_REQ, -+ MM_GET_WIFI_DISABLE_CFM, -+ -+ MM_CFG_RSSI_CFM, -+ -+ MM_SET_VENDOR_SWCONFIG_REQ, -+ MM_SET_VENDOR_SWCONFIG_CFM, -+ -+ MM_SET_TXPWR_LVL_ADJ_REQ, -+ MM_SET_TXPWR_LVL_ADJ_CFM, -+ -+ /// MAX number of messages -+ MM_MAX, -+}; -+ -+/// Interface types -+enum { -+ /// ESS STA interface -+ MM_STA, -+ /// IBSS STA interface -+ MM_IBSS, -+ /// AP interface -+ MM_AP, -+ // Mesh Point interface -+ MM_MESH_POINT, -+ // Monitor interface -+ MM_MONITOR, -+}; -+ -+///BA agreement types -+enum { -+ ///BlockAck agreement for TX -+ BA_AGMT_TX, -+ ///BlockAck agreement for RX -+ BA_AGMT_RX, -+}; -+ -+///BA agreement related status -+enum { -+ ///Correct BA agreement establishment -+ BA_AGMT_ESTABLISHED, -+ ///BA agreement already exists for STA+TID requested, cannot override it (should have been deleted first) -+ BA_AGMT_ALREADY_EXISTS, -+ ///Correct BA agreement deletion -+ BA_AGMT_DELETED, -+ ///BA agreement for the (STA, TID) doesn't exist so nothing to delete -+ BA_AGMT_DOESNT_EXIST, -+}; -+ -+/// Features supported by LMAC - Positions -+enum mm_features { -+ /// Beaconing -+ MM_FEAT_BCN_BIT = 0, -+/* -+ /// Autonomous Beacon Transmission -+ MM_FEAT_AUTOBCN_BIT, -+ /// Scan in LMAC -+ MM_FEAT_HWSCAN_BIT, -+ /// Connection Monitoring -+ MM_FEAT_CMON_BIT, -+ /// Multi Role -+ MM_FEAT_MROLE_BIT, -+*/ -+ /// Radar Detection -+ MM_FEAT_RADAR_BIT, -+ /// Power Save -+ MM_FEAT_PS_BIT, -+ /// UAPSD -+ MM_FEAT_UAPSD_BIT, -+ /// DPSM -+// MM_FEAT_DPSM_BIT, -+ /// A-MPDU -+ MM_FEAT_AMPDU_BIT, -+ /// A-MSDU -+ MM_FEAT_AMSDU_BIT, -+ /// Channel Context -+// MM_FEAT_CHNL_CTXT_BIT, -+ /// Packet reordering -+// MM_FEAT_REORD_BIT, -+ /// P2P -+ MM_FEAT_P2P_BIT, -+ /// P2P Go -+ MM_FEAT_P2P_GO_BIT, -+ /// UMAC Present -+ MM_FEAT_UMAC_BIT, -+ /// VHT support -+ MM_FEAT_VHT_BIT, -+ /// Beamformee -+ MM_FEAT_BFMEE_BIT, -+ /// Beamformer -+ MM_FEAT_BFMER_BIT, -+ /// WAPI -+ MM_FEAT_WAPI_BIT, -+ /// MFP -+ MM_FEAT_MFP_BIT, -+ /// Mu-MIMO RX support -+ MM_FEAT_MU_MIMO_RX_BIT, -+ /// Mu-MIMO TX support -+ MM_FEAT_MU_MIMO_TX_BIT, -+ /// Wireless Mesh Networking -+ MM_FEAT_MESH_BIT, -+ /// TDLS support -+ MM_FEAT_TDLS_BIT, -+ /// Antenna Diversity support -+ MM_FEAT_ANT_DIV_BIT, -+ /// UF support -+ MM_FEAT_UF_BIT, -+ /// A-MSDU maximum size (bit0) -+ MM_AMSDU_MAX_SIZE_BIT0, -+ /// A-MSDU maximum size (bit1) -+ MM_AMSDU_MAX_SIZE_BIT1, -+ /// MON_DATA support -+ MM_FEAT_MON_DATA_BIT, -+ /// HE (802.11ax) support -+ MM_FEAT_HE_BIT, -+ /// TWT support -+ MM_FEAT_TWT_BIT, -+}; -+ -+/// Maximum number of words in the configuration buffer -+#define PHY_CFG_BUF_SIZE 16 -+ -+/// Structure containing the parameters of the PHY configuration -+struct phy_cfg_tag { -+ /// Buffer containing the parameters specific for the PHY used -+ u32_l parameters[PHY_CFG_BUF_SIZE]; -+}; -+ -+/// Structure containing the parameters of the Trident PHY configuration -+struct phy_trd_cfg_tag { -+ /// MDM type(nxm)(upper nibble) and MDM2RF path mapping(lower nibble) -+ u8_l path_mapping; -+ /// TX DC offset compensation -+ u32_l tx_dc_off_comp; -+}; -+ -+/// Structure containing the parameters of the Karst PHY configuration -+struct phy_karst_cfg_tag { -+ /// TX IQ mismatch compensation in 2.4GHz -+ u32_l tx_iq_comp_2_4G[2]; -+ /// RX IQ mismatch compensation in 2.4GHz -+ u32_l rx_iq_comp_2_4G[2]; -+ /// TX IQ mismatch compensation in 5GHz -+ u32_l tx_iq_comp_5G[2]; -+ /// RX IQ mismatch compensation in 5GHz -+ u32_l rx_iq_comp_5G[2]; -+ /// RF path used by default (0 or 1) -+ u8_l path_used; -+}; -+ -+/// Structure containing the parameters of the @ref MM_START_REQ message -+struct mm_start_req { -+ /// PHY configuration -+ struct phy_cfg_tag phy_cfg; -+ /// UAPSD timeout -+ u32_l uapsd_timeout; -+ /// Local LP clock accuracy (in ppm) -+ u16_l lp_clk_accuracy; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_CHANNEL_REQ message -+struct mm_set_channel_req { -+ /// Channel information -+ struct mac_chan_op chan; -+ /// Index of the RF for which the channel has to be set (0: operating (primary), 1: secondary -+ /// RF (used for additional radar detection). This parameter is reserved if no secondary RF -+ /// is available in the system -+ u8_l index; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_CHANNEL_CFM message -+struct mm_set_channel_cfm { -+ /// Radio index to be used in policy table -+ u8_l radio_idx; -+ /// TX power configured (in dBm) -+ s8_l power; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_DTIM_REQ message -+struct mm_set_dtim_req { -+ /// DTIM period -+ u8_l dtim_period; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_POWER_REQ message -+struct mm_set_power_req { -+ /// Index of the interface for which the parameter is configured -+ u8_l inst_nbr; -+ /// TX power (in dBm) -+ s8_l power; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_POWER_CFM message -+struct mm_set_power_cfm { -+ /// Radio index to be used in policy table -+ u8_l radio_idx; -+ /// TX power configured (in dBm) -+ s8_l power; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_BEACON_INT_REQ message -+struct mm_set_beacon_int_req { -+ /// Beacon interval -+ u16_l beacon_int; -+ /// Index of the interface for which the parameter is configured -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_BASIC_RATES_REQ message -+struct mm_set_basic_rates_req { -+ /// Basic rate set (as expected by bssBasicRateSet field of Rates MAC HW register) -+ u32_l rates; -+ /// Index of the interface for which the parameter is configured -+ u8_l inst_nbr; -+ /// Band on which the interface will operate -+ u8_l band; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_BSSID_REQ message -+struct mm_set_bssid_req { -+ /// BSSID to be configured in HW -+ struct mac_addr bssid; -+ /// Index of the interface for which the parameter is configured -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_FILTER_REQ message -+struct mm_set_filter_req { -+ /// RX filter to be put into rxCntrlReg HW register -+ u32_l filter; -+}; -+ -+/// Structure containing the parameters of the @ref MM_ADD_IF_REQ message. -+struct mm_add_if_req { -+ /// Type of the interface (AP, STA, ADHOC, ...) -+ u8_l type; -+ /// MAC ADDR of the interface to start -+ struct mac_addr addr; -+ /// P2P Interface -+ bool_l p2p; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_EDCA_REQ message -+struct mm_set_edca_req { -+ /// EDCA parameters of the queue (as expected by edcaACxReg HW register) -+ u32_l ac_param; -+ /// Flag indicating if UAPSD can be used on this queue -+ bool_l uapsd; -+ /// HW queue for which the parameters are configured -+ u8_l hw_queue; -+ /// Index of the interface for which the parameters are configured -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_MU_EDCA_REQ message -+struct mm_set_mu_edca_req { -+ /// MU EDCA parameters of the different HE queues -+ u32_l param[AC_MAX]; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_UORA_REQ message -+struct mm_set_uora_req { -+ /// Minimum exponent of OFDMA Contention Window. -+ u8_l eocw_min; -+ /// Maximum exponent of OFDMA Contention Window. -+ u8_l eocw_max; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_TXOP_RTS_THRES_REQ message -+struct mm_set_txop_rts_thres_req { -+ /// TXOP RTS threshold -+ u16_l txop_dur_rts_thres; -+ /// Index of the interface for which the parameter is configured -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_BSS_COLOR_REQ message -+struct mm_set_bss_color_req { -+ /// HE BSS color, formatted as per BSS_COLOR MAC HW register -+ u32_l bss_color; -+}; -+ -+struct mm_set_idle_req { -+ u8_l hw_idle; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_SLOTTIME_REQ message -+struct mm_set_slottime_req { -+ /// Slot time expressed in us -+ u8_l slottime; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_MODE_REQ message -+struct mm_set_mode_req { -+ /// abgnMode field of macCntrl1Reg register -+ u8_l abgnmode; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_VIF_STATE_REQ message -+struct mm_set_vif_state_req { -+ /// Association Id received from the AP (valid only if the VIF is of STA type) -+ u16_l aid; -+ /// Flag indicating if the VIF is active or not -+ bool_l active; -+ /// Interface index -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_ADD_IF_CFM message. -+struct mm_add_if_cfm { -+ /// Status of operation (different from 0 if unsuccessful) -+ u8_l status; -+ /// Interface index assigned by the LMAC -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_REMOVE_IF_REQ message. -+struct mm_remove_if_req { -+ /// Interface index assigned by the LMAC -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_VERSION_CFM message. -+struct mm_version_cfm { -+ /// Version of the LMAC FW -+ u32_l version_lmac; -+ /// Version1 of the MAC HW (as encoded in version1Reg MAC HW register) -+ u32_l version_machw_1; -+ /// Version2 of the MAC HW (as encoded in version2Reg MAC HW register) -+ u32_l version_machw_2; -+ /// Version1 of the PHY (depends on actual PHY) -+ u32_l version_phy_1; -+ /// Version2 of the PHY (depends on actual PHY) -+ u32_l version_phy_2; -+ /// Supported Features -+ u32_l features; -+ /// Maximum number of supported stations -+ u16_l max_sta_nb; -+ /// Maximum number of supported virtual interfaces -+ u8_l max_vif_nb; -+}; -+ -+/// Structure containing the parameters of the @ref MM_STA_ADD_REQ message. -+struct mm_sta_add_req { -+ /// Bitfield showing some capabilities of the STA (@ref enum mac_sta_flags) -+ u32_l capa_flags; -+ /// Maximum A-MPDU size, in bytes, for HE frames -+ u32_l ampdu_size_max_he; -+ /// Maximum A-MPDU size, in bytes, for VHT frames -+ u32_l ampdu_size_max_vht; -+ /// PAID/GID -+ u32_l paid_gid; -+ /// Maximum A-MPDU size, in bytes, for HT frames -+ u16_l ampdu_size_max_ht; -+ /// MAC address of the station to be added -+ struct mac_addr mac_addr; -+ /// A-MPDU spacing, in us -+ u8_l ampdu_spacing_min; -+ /// Interface index -+ u8_l inst_nbr; -+ /// TDLS station -+ bool_l tdls_sta; -+ /// Indicate if the station is TDLS link initiator station -+ bool_l tdls_sta_initiator; -+ /// Indicate if the TDLS Channel Switch is allowed -+ bool_l tdls_chsw_allowed; -+ /// nonTransmitted BSSID index, set to the BSSID index in case the STA added is an AP -+ /// that is a nonTransmitted BSSID. Should be set to 0 otherwise -+ u8_l bssid_index; -+ /// Maximum BSSID indicator, valid if the STA added is an AP that is a nonTransmitted -+ /// BSSID -+ u8_l max_bssid_ind; -+}; -+ -+/// Structure containing the parameters of the @ref MM_STA_ADD_CFM message. -+struct mm_sta_add_cfm { -+ /// Status of the operation (different from 0 if unsuccessful) -+ u8_l status; -+ /// Index assigned by the LMAC to the newly added station -+ u8_l sta_idx; -+ /// MAC HW index of the newly added station -+ u8_l hw_sta_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MM_STA_DEL_REQ message. -+struct mm_sta_del_req { -+ /// Index of the station to be deleted -+ u8_l sta_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MM_STA_DEL_CFM message. -+struct mm_sta_del_cfm { -+ /// Status of the operation (different from 0 if unsuccessful) -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the SET_POWER_MODE REQ message. -+struct mm_setpowermode_req { -+ u8_l mode; -+ u8_l sta_idx; -+}; -+ -+/// Structure containing the parameters of the SET_POWER_MODE CFM message. -+struct mm_setpowermode_cfm { -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref MM_KEY_ADD REQ message. -+struct mm_key_add_req { -+ /// Key index (valid only for default keys) -+ u8_l key_idx; -+ /// STA index (valid only for pairwise or mesh group keys) -+ u8_l sta_idx; -+ /// Key material -+ struct mac_sec_key key; -+ /// Cipher suite (WEP64, WEP128, TKIP, CCMP) -+ u8_l cipher_suite; -+ /// Index of the interface for which the key is set (valid only for default keys or mesh group keys) -+ u8_l inst_nbr; -+ /// A-MSDU SPP parameter -+ u8_l spp; -+ /// Indicate if provided key is a pairwise key or not -+ bool_l pairwise; -+}; -+ -+/// Structure containing the parameters of the @ref MM_KEY_ADD_CFM message. -+struct mm_key_add_cfm { -+ /// Status of the operation (different from 0 if unsuccessful) -+ u8_l status; -+ /// HW index of the key just added -+ u8_l hw_key_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MM_KEY_DEL_REQ message. -+struct mm_key_del_req { -+ /// HW index of the key to be deleted -+ u8_l hw_key_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BA_ADD_REQ message. -+struct mm_ba_add_req { -+ ///Type of agreement (0: TX, 1: RX) -+ u8_l type; -+ ///Index of peer station with which the agreement is made -+ u8_l sta_idx; -+ ///TID for which the agreement is made with peer station -+ u8_l tid; -+ ///Buffer size - number of MPDUs that can be held in its buffer per TID -+ u8_l bufsz; -+ /// Start sequence number negotiated during BA setup - the one in first aggregated MPDU counts more -+ u16_l ssn; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BA_ADD_CFM message. -+struct mm_ba_add_cfm { -+ ///Index of peer station for which the agreement is being confirmed -+ u8_l sta_idx; -+ ///TID for which the agreement is being confirmed -+ u8_l tid; -+ /// Status of ba establishment -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BA_DEL_REQ message. -+struct mm_ba_del_req { -+ ///Type of agreement (0: TX, 1: RX) -+ u8_l type; -+ ///Index of peer station for which the agreement is being deleted -+ u8_l sta_idx; -+ ///TID for which the agreement is being deleted -+ u8_l tid; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BA_DEL_CFM message. -+struct mm_ba_del_cfm { -+ ///Index of peer station for which the agreement deletion is being confirmed -+ u8_l sta_idx; -+ ///TID for which the agreement deletion is being confirmed -+ u8_l tid; -+ /// Status of ba deletion -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_ADD_REQ message -+struct mm_chan_ctxt_add_req { -+ /// Operating channel -+ struct mac_chan_op chan; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_ADD_REQ message -+struct mm_chan_ctxt_add_cfm { -+ /// Status of the addition -+ u8_l status; -+ /// Index of the new channel context -+ u8_l index; -+}; -+ -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_DEL_REQ message -+struct mm_chan_ctxt_del_req { -+ /// Index of the new channel context to be deleted -+ u8_l index; -+}; -+ -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_LINK_REQ message -+struct mm_chan_ctxt_link_req { -+ /// VIF index -+ u8_l vif_index; -+ /// Channel context index -+ u8_l chan_index; -+ /// Indicate if this is a channel switch (unlink current ctx first if true) -+ u8_l chan_switch; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_UNLINK_REQ message -+struct mm_chan_ctxt_unlink_req { -+ /// VIF index -+ u8_l vif_index; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_UPDATE_REQ message -+struct mm_chan_ctxt_update_req { -+ /// Channel context index -+ u8_l chan_index; -+ /// New channel information -+ struct mac_chan_op chan; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHAN_CTXT_SCHED_REQ message -+struct mm_chan_ctxt_sched_req { -+ /// VIF index -+ u8_l vif_index; -+ /// Channel context index -+ u8_l chan_index; -+ /// Type of the scheduling request (0: normal scheduling, 1: derogatory -+ /// scheduling) -+ u8_l type; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHANNEL_SWITCH_IND message -+struct mm_channel_switch_ind { -+ /// Index of the channel context we will switch to -+ u8_l chan_index; -+ /// Indicate if the switch has been triggered by a Remain on channel request -+ bool_l roc; -+ /// VIF on which remain on channel operation has been started (if roc == 1) -+ u8_l vif_index; -+ /// Indicate if the switch has been triggered by a TDLS Remain on channel request -+ bool_l roc_tdls; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHANNEL_PRE_SWITCH_IND message -+struct mm_channel_pre_switch_ind { -+ /// Index of the channel context we will switch to -+ u8_l chan_index; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CONNECTION_LOSS_IND message. -+struct mm_connection_loss_ind { -+ /// VIF instance number -+ u8_l inst_nbr; -+}; -+ -+ -+/// Structure containing the parameters of the @ref MM_DBG_TRIGGER_REQ message. -+struct mm_dbg_trigger_req { -+ /// Error trace to be reported by the LMAC -+ char error[64]; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_PS_MODE_REQ message. -+struct mm_set_ps_mode_req { -+ /// Power Save is activated or deactivated -+ u8_l new_state; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BCN_CHANGE_REQ message. -+#define BCN_MAX_CSA_CPT 2 -+struct mm_bcn_change_req { -+ /// Pointer, in host memory, to the new beacon template -+ u32_l bcn_ptr; -+ /// Length of the beacon template -+ u16_l bcn_len; -+ /// Offset of the TIM IE in the beacon -+ u16_l tim_oft; -+ /// Length of the TIM IE -+ u8_l tim_len; -+ /// Index of the VIF for which the beacon is updated -+ u8_l inst_nbr; -+ /// Offset of CSA (channel switch announcement) counters (0 means no counter) -+ u8_l csa_oft[BCN_MAX_CSA_CPT]; -+}; -+ -+ -+/// Structure containing the parameters of the @ref MM_TIM_UPDATE_REQ message. -+struct mm_tim_update_req { -+ /// Association ID of the STA the bit of which has to be updated (0 for BC/MC traffic) -+ u16_l aid; -+ /// Flag indicating the availability of data packets for the given STA -+ u8_l tx_avail; -+ /// Index of the VIF for which the TIM is updated -+ u8_l inst_nbr; -+}; -+ -+/// Structure containing the parameters of the @ref MM_REMAIN_ON_CHANNEL_REQ message. -+struct mm_remain_on_channel_req { -+ /// Operation Code -+ u8_l op_code; -+ /// VIF Index -+ u8_l vif_index; -+ /// Band (2.4GHz or 5GHz) -+ u8_l band; -+ /// Channel type: 20,40,80,160 or 80+80 MHz -+ u8_l type; -+ /// Frequency for Primary 20MHz channel (in MHz) -+ u16_l prim20_freq; -+ /// Frequency for Center of the contiguous channel or center of Primary 80+80 -+ u16_l center1_freq; -+ /// Frequency for Center of the non-contiguous secondary 80+80 -+ u16_l center2_freq; -+ /// Duration (in ms) -+ u32_l duration_ms; -+ /// TX power (in dBm) -+ s8_l tx_power; -+}; -+ -+/// Structure containing the parameters of the @ref MM_REMAIN_ON_CHANNEL_CFM message -+struct mm_remain_on_channel_cfm { -+ /// Operation Code -+ u8_l op_code; -+ /// Status of the operation -+ u8_l status; -+ /// Channel Context index -+ u8_l chan_ctxt_index; -+}; -+ -+/// Structure containing the parameters of the @ref MM_REMAIN_ON_CHANNEL_EXP_IND message -+struct mm_remain_on_channel_exp_ind { -+ /// VIF Index -+ u8_l vif_index; -+ /// Channel Context index -+ u8_l chan_ctxt_index; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_UAPSD_TMR_REQ message. -+struct mm_set_uapsd_tmr_req { -+ /// action: Start or Stop the timer -+ u8_l action; -+ /// timeout value, in milliseconds -+ u32_l timeout; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_UAPSD_TMR_CFM message. -+struct mm_set_uapsd_tmr_cfm { -+ /// Status of the operation (different from 0 if unsuccessful) -+ u8_l status; -+}; -+ -+ -+/// Structure containing the parameters of the @ref MM_PS_CHANGE_IND message -+struct mm_ps_change_ind { -+ /// Index of the peer device that is switching its PS state -+ u8_l sta_idx; -+ /// New PS state of the peer device (0: active, 1: sleeping) -+ u8_l ps_state; -+}; -+ -+/// Structure containing the parameters of the @ref MM_P2P_VIF_PS_CHANGE_IND message -+struct mm_p2p_vif_ps_change_ind { -+ /// Index of the P2P VIF that is switching its PS state -+ u8_l vif_index; -+ /// New PS state of the P2P VIF interface (0: active, 1: sleeping) -+ u8_l ps_state; -+}; -+ -+/// Structure containing the parameters of the @ref MM_TRAFFIC_REQ_IND message -+struct mm_traffic_req_ind { -+ /// Index of the peer device that needs traffic -+ u8_l sta_idx; -+ /// Number of packets that need to be sent (if 0, all buffered traffic shall be sent and -+ /// if set to @ref PS_SP_INTERRUPTED, it means that current service period has been interrupted) -+ u8_l pkt_cnt; -+ /// Flag indicating if the traffic request concerns U-APSD queues or not -+ bool_l uapsd; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_PS_OPTIONS_REQ message. -+struct mm_set_ps_options_req { -+ /// VIF Index -+ u8_l vif_index; -+ /// Listen interval (0 if wake up shall be based on DTIM period) -+ u16_l listen_interval; -+ /// Flag indicating if we shall listen the BC/MC traffic or not -+ bool_l dont_listen_bc_mc; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CSA_COUNTER_IND message -+struct mm_csa_counter_ind { -+ /// Index of the VIF -+ u8_l vif_index; -+ /// Updated CSA counter value -+ u8_l csa_count; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CHANNEL_SURVEY_IND message -+struct mm_channel_survey_ind { -+ /// Frequency of the channel -+ u16_l freq; -+ /// Noise in dbm -+ s8_l noise_dbm; -+ /// Amount of time spent of the channel (in ms) -+ u32_l chan_time_ms; -+ /// Amount of time the primary channel was sensed busy -+ u32_l chan_time_busy_ms; -+}; -+ -+/// Structure containing the parameters of the @ref MM_BFMER_ENABLE_REQ message. -+struct mm_bfmer_enable_req { -+ /** -+ * Address of the beamforming report space allocated in host memory -+ * (Valid only if vht_su_bfmee is true) -+ */ -+ u32_l host_bfr_addr; -+ /** -+ * Size of the beamforming report space allocated in host memory. This space should -+ * be twice the maximum size of the expected beamforming reports as the FW will -+ * divide it in two in order to be able to upload a new report while another one is -+ * used in transmission -+ */ -+ u16_l host_bfr_size; -+ /// AID -+ u16_l aid; -+ /// Station Index -+ u8_l sta_idx; -+ /// Maximum number of spatial streams the station can receive -+ u8_l rx_nss; -+ /** -+ * Indicate if peer STA is MU Beamformee (VHT) capable -+ * (Valid only if vht_su_bfmee is true) -+ */ -+ bool_l vht_mu_bfmee; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_P2P_NOA_REQ message. -+struct mm_set_p2p_noa_req { -+ /// VIF Index -+ u8_l vif_index; -+ /// Allocated NOA Instance Number - Valid only if count = 0 -+ u8_l noa_inst_nb; -+ /// Count -+ u8_l count; -+ /// Indicate if NoA can be paused for traffic reason -+ bool_l dyn_noa; -+ /// Duration (in us) -+ u32_l duration_us; -+ /// Interval (in us) -+ u32_l interval_us; -+ /// Start Time offset from next TBTT (in us) -+ u32_l start_offset; -+}; -+ -+#ifdef AICWF_ARP_OFFLOAD -+struct mm_set_arpoffload_en_req { -+ u32_l ipaddr; -+ u8_l enable; -+ u8_l vif_idx; -+}; -+ -+struct mm_set_arpoffload_en_cfm { -+ u8_l status; -+}; -+#endif -+ -+struct mm_set_agg_disable_req { -+ u8_l disable; -+ u8_l staidx; -+ u8_l disable_rx; -+}; -+ -+struct mm_set_coex_req { -+ u8_l bt_on; -+ u8_l disable_coexnull; -+ u8_l enable_nullcts; -+ u8_l enable_periodic_timer; -+ u8_l coex_timeslot_set; -+ u32_l coex_timeslot[2]; -+}; -+#if 0 -+struct mm_set_rf_config_req { -+ u8_l def_band; -+ u8_l config_type; -+ u16_l offset; -+ u16_l len; -+ u16_l set; -+ u32_l rx_gain_24g[48][4]; -+ u32_l rx_gain_5g[32][4]; -+ u32_l tx_gain[32]; -+}; -+#endif -+struct mm_set_rf_config_req -+{ -+ u8_l table_sel; -+ u8_l table_ofst; -+ u8_l table_num; -+ u8_l deft_page; -+ u32_l data[64]; -+}; -+ -+struct mm_set_rf_calib_req { -+ u32_l cal_cfg_24g; -+ u32_l cal_cfg_5g; -+ u32_l param_alpha; -+ u32_l bt_calib_en; -+ u32_l bt_calib_param; -+ u8_l xtal_cap; -+ u8_l xtal_cap_fine; -+}; -+ -+struct mm_set_rf_calib_cfm { -+ u32_l rxgain_24g_addr; -+ u32_l rxgain_5g_addr; -+ u32_l txgain_24g_addr; -+ u32_l txgain_5g_addr; -+}; -+ -+struct mm_get_mac_addr_req { -+ u32_l get; -+}; -+ -+struct mm_get_mac_addr_cfm { -+ u8_l mac_addr[6]; -+}; -+ -+struct mm_get_sta_info_req { -+ u8_l sta_idx; -+}; -+ -+struct mm_get_sta_info_cfm { -+ u32_l rate_info; -+ u32_l txfailed; -+ u8 rssi; -+}; -+ -+typedef struct -+{ -+ u8_l enable; -+ u8_l dsss; -+ u8_l ofdmlowrate_2g4; -+ u8_l ofdm64qam_2g4; -+ u8_l ofdm256qam_2g4; -+ u8_l ofdm1024qam_2g4; -+ u8_l ofdmlowrate_5g; -+ u8_l ofdm64qam_5g; -+ u8_l ofdm256qam_5g; -+ u8_l ofdm1024qam_5g; -+} txpwr_lvl_conf_t; -+ -+typedef struct -+{ -+ u8_l enable; -+ s8_l pwrlvl_11b_11ag_2g4[12]; -+ s8_l pwrlvl_11n_11ac_2g4[10]; -+ s8_l pwrlvl_11ax_2g4[12]; -+} txpwr_lvl_conf_v2_t; -+ -+typedef struct -+{ -+ u8_l enable; -+ s8_l pwrlvl_11b_11ag_2g4[12]; -+ s8_l pwrlvl_11n_11ac_2g4[10]; -+ s8_l pwrlvl_11ax_2g4[12]; -+ s8_l pwrlvl_11a_5g[12]; -+ s8_l pwrlvl_11n_11ac_5g[10]; -+ s8_l pwrlvl_11ax_5g[12]; -+} txpwr_lvl_conf_v3_t; -+ -+typedef struct -+{ -+ u8_l enable; -+ s8_l pwrlvl_adj_tbl_2g4[3]; -+ s8_l pwrlvl_adj_tbl_5g[6]; -+} txpwr_lvl_adj_conf_t; -+ -+typedef struct -+{ -+ u8_l loss_enable; -+ u8_l loss_value; -+} txpwr_loss_conf_t; -+ -+struct mm_set_txpwr_lvl_req -+{ -+ union { -+ txpwr_lvl_conf_t txpwr_lvl; -+ txpwr_lvl_conf_v2_t txpwr_lvl_v2; -+ txpwr_lvl_conf_v3_t txpwr_lvl_v3; -+ }; -+}; -+ -+struct mm_set_txpwr_lvl_adj_req -+{ -+ txpwr_lvl_adj_conf_t txpwr_lvl_adj; -+}; -+ -+typedef struct { -+ u8_l enable; -+ u8_l dsss; -+ u8_l ofdmlowrate_2g4; -+ u8_l ofdm64qam_2g4; -+ u8_l ofdm256qam_2g4; -+ u8_l ofdm1024qam_2g4; -+ u8_l ofdmlowrate_5g; -+ u8_l ofdm64qam_5g; -+ u8_l ofdm256qam_5g; -+ u8_l ofdm1024qam_5g; -+} txpwr_idx_conf_t; -+ -+struct mm_set_txpwr_idx_req { -+ txpwr_idx_conf_t txpwr_idx; -+}; -+ -+typedef struct { -+ u8_l enable; -+ s8_l chan_1_4; -+ s8_l chan_5_9; -+ s8_l chan_10_13; -+ s8_l chan_36_64; -+ s8_l chan_100_120; -+ s8_l chan_122_140; -+ s8_l chan_142_165; -+} txpwr_ofst_conf_t; -+ -+/* -+ * pwrofst2x_tbl_2g4[3][3]: -+ * +---------------+----------+----------+----------+ -+ * | RateTyp\ChGrp | CH_1_4 | CH_5_9 | CH_10_13 | -+ * +---------------+----------+----------+----------+ -+ * | DSSS | [0][0] | [0][1] | [0][2] | -+ * +---------------+----------+----------+----------+ -+ * | OFDM_HIGHRATE | [1][0] | [1][1] | [1][2] | -+ * +---------------+----------+----------+----------+ -+ * | OFDM_LOWRATE | [2][0] | [2][1] | [2][2] | -+ * +---------------+----------+----------+----------+ -+ * pwrofst2x_tbl_5g[3][6]: -+ * +---------------+--------------+--------------+----------------+----------------+----------------+----------------+ -+ * | RateTyp\ChGrp | CH_42(36~50) | CH_58(51~64) | CH_106(98~114) | CH_122(115~130)| CH_138(131~146)| CH_155(147~166)| -+ * +---------------+--------------+--------------+----------------+----------------+----------------+----------------+ -+ * | OFDM_LOWRATE | [0][0] | [0][1] | [0][2] | [0][3] | [0][4] | [0][5] | -+ * +---------------+--------------+--------------+----------------+----------------+----------------+----------------+ -+ * | OFDM_HIGHRATE | [1][0] | [1][1] | [1][2] | [1][3] | [1][4] | [1][5] | -+ * +---------------+--------------+--------------+----------------+----------------+----------------+----------------+ -+ * | OFDM_MIDRATE | [2][0] | [2][1] | [2][2] | [2][3] | [2][4] | [2][5] | -+ * +---------------+--------------+--------------+----------------+----------------+----------------+----------------+ -+ */ -+ -+typedef struct -+{ -+ int8_t enable; -+ int8_t pwrofst2x_tbl_2g4[3][3]; -+ int8_t pwrofst2x_tbl_5g[3][6]; -+} txpwr_ofst2x_conf_t; -+ -+typedef struct -+{ -+ u8_l enable; -+ u8_l xtal_cap; -+ u8_l xtal_cap_fine; -+} xtal_cap_conf_t; -+ -+ -+struct mm_set_txpwr_ofst_req { -+ union { -+ txpwr_ofst_conf_t txpwr_ofst; -+ txpwr_ofst2x_conf_t txpwr_ofst2x; -+ }; -+}; -+ -+struct mm_set_stack_start_req { -+ u8_l is_stack_start; -+ u8_l efuse_valid; -+ u8_l set_vendor_info; -+ u8_l fwtrace_redir; -+}; -+ -+struct mm_set_stack_start_cfm { -+ u8_l is_5g_support; -+ u8_l vendor_info; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_P2P_OPPPS_REQ message. -+struct mm_set_p2p_oppps_req { -+ /// VIF Index -+ u8_l vif_index; -+ /// CTWindow -+ u8_l ctwindow; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_P2P_NOA_CFM message. -+struct mm_set_p2p_noa_cfm { -+ /// Request status -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref MM_SET_P2P_OPPPS_CFM message. -+struct mm_set_p2p_oppps_cfm { -+ /// Request status -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref MM_P2P_NOA_UPD_IND message. -+struct mm_p2p_noa_upd_ind { -+ /// VIF Index -+ u8_l vif_index; -+ /// NOA Instance Number -+ u8_l noa_inst_nb; -+ /// NoA Type -+ u8_l noa_type; -+ /// Count -+ u8_l count; -+ /// Duration (in us) -+ u32_l duration_us; -+ /// Interval (in us) -+ u32_l interval_us; -+ /// Start Time -+ u32_l start_time; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CFG_RSSI_REQ message -+struct mm_cfg_rssi_req { -+ /// Index of the VIF -+ u8_l vif_index; -+ /// RSSI threshold -+ s8_l rssi_thold; -+ /// RSSI hysteresis -+ u8_l rssi_hyst; -+}; -+ -+/// Structure containing the parameters of the @ref MM_RSSI_STATUS_IND message -+struct mm_rssi_status_ind { -+ /// Index of the VIF -+ u8_l vif_index; -+ /// Status of the RSSI -+ bool_l rssi_status; -+ /// Current RSSI -+ s8_l rssi; -+}; -+ -+/// Structure containing the parameters of the @ref MM_PKTLOSS_IND message -+struct mm_pktloss_ind { -+ /// Index of the VIF -+ u8_l vif_index; -+ /// Address of the STA for which there is a packet loss -+ struct mac_addr mac_addr; -+ /// Number of packets lost -+ u32 num_packets; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CSA_FINISH_IND message -+struct mm_csa_finish_ind { -+ /// Index of the VIF -+ u8_l vif_index; -+ /// Status of the operation -+ u8_l status; -+ /// New channel ctx index -+ u8_l chan_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MM_CSA_TRAFFIC_IND message -+struct mm_csa_traffic_ind { -+ /// Index of the VIF -+ u8_l vif_index; -+ /// Is tx traffic enable or disable -+ bool_l enable; -+}; -+ -+/// Structure containing the parameters of the @ref MM_MU_GROUP_UPDATE_REQ message. -+/// Size allocated for the structure depends of the number of group -+struct mm_mu_group_update_req { -+ /// Station index -+ u8_l sta_idx; -+ /// Number of groups the STA belongs to -+ u8_l group_cnt; -+ /// Group information -+ struct { -+ /// Group Id -+ u8_l group_id; -+ /// User position -+ u8_l user_pos; -+ } groups[0]; -+}; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For Scan messages -+/////////////////////////////////////////////////////////////////////////////// -+enum scan_msg_tag { -+ /// Scanning start Request. -+ SCAN_START_REQ = LMAC_FIRST_MSG(TASK_SCAN), -+ /// Scanning start Confirmation. -+ SCAN_START_CFM, -+ /// End of scanning indication. -+ SCAN_DONE_IND, -+ /// Cancel scan request -+ SCAN_CANCEL_REQ, -+ /// Cancel scan confirmation -+ SCAN_CANCEL_CFM, -+ -+ /// MAX number of messages -+ SCAN_MAX, -+}; -+ -+/// Maximum number of SSIDs in a scan request -+#define SCAN_SSID_MAX 3 -+ -+/// Maximum number of channels in a scan request -+#define SCAN_CHANNEL_MAX (MAC_DOMAINCHANNEL_24G_MAX + MAC_DOMAINCHANNEL_5G_MAX) -+ -+/// Maximum length of the ProbeReq IEs (SoftMAC mode) -+#define SCAN_MAX_IE_LEN 300 -+ -+/// Maximum number of PHY bands supported -+#define SCAN_BAND_MAX 2 -+ -+/// Structure containing the parameters of the @ref SCAN_START_REQ message -+struct scan_start_req { -+ /// List of channel to be scanned -+ struct mac_chan_def chan[SCAN_CHANNEL_MAX]; -+ /// List of SSIDs to be scanned -+ struct mac_ssid ssid[SCAN_SSID_MAX]; -+ /// BSSID to be scanned -+ struct mac_addr bssid; -+ /// Pointer (in host memory) to the additional IEs that need to be added to the ProbeReq -+ /// (following the SSID element) -+ u32_l add_ies; -+ /// Length of the additional IEs -+ u16_l add_ie_len; -+ /// Index of the VIF that is scanning -+ u8_l vif_idx; -+ /// Number of channels to scan -+ u8_l chan_cnt; -+ /// Number of SSIDs to scan for -+ u8_l ssid_cnt; -+ /// no CCK - For P2P frames not being sent at CCK rate in 2GHz band. -+ bool no_cck; -+ /// Scan duration, in us -+ u32_l duration; -+}; -+ -+/// Structure containing the parameters of the @ref SCAN_START_CFM message -+struct scan_start_cfm { -+ /// Status of the request -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref SCAN_CANCEL_REQ message -+struct scan_cancel_req { -+}; -+ -+/// Structure containing the parameters of the @ref SCAN_START_CFM message -+struct scan_cancel_cfm { -+ /// Status of the request -+ u8_l status; -+}; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For Scanu messages -+/////////////////////////////////////////////////////////////////////////////// -+/// Messages that are logically related to the task. -+enum { -+ /// Scan request from host. -+ SCANU_START_REQ = LMAC_FIRST_MSG(TASK_SCANU), -+ /// Scanning start Confirmation. -+ SCANU_START_CFM, -+ /// Join request -+ SCANU_JOIN_REQ, -+ /// Join confirmation. -+ SCANU_JOIN_CFM, -+ /// Scan result indication. -+ SCANU_RESULT_IND, -+ /// Fast scan request from any other module. -+ SCANU_FAST_REQ, -+ /// Confirmation of fast scan request. -+ SCANU_FAST_CFM, -+ -+ SCANU_VENDOR_IE_REQ, -+ SCANU_VENDOR_IE_CFM, -+ SCANU_START_CFM_ADDTIONAL, -+ SCANU_CANCEL_REQ, -+ SCANU_CANCEL_CFM, -+ -+ /// MAX number of messages -+ SCANU_MAX, -+}; -+ -+/// Maximum length of the additional ProbeReq IEs (FullMAC mode) -+#define SCANU_MAX_IE_LEN 200 -+ -+/// Structure containing the parameters of the @ref SCANU_START_REQ message -+struct scanu_start_req { -+ /// List of channel to be scanned -+ struct mac_chan_def chan[SCAN_CHANNEL_MAX]; -+ /// List of SSIDs to be scanned -+ struct mac_ssid ssid[SCAN_SSID_MAX]; -+ /// BSSID to be scanned (or WILDCARD BSSID if no BSSID is searched in particular) -+ struct mac_addr bssid; -+ /// Address (in host memory) of the additional IEs that need to be added to the ProbeReq -+ /// (following the SSID element) -+ u32_l add_ies; -+ /// Length of the additional IEs -+ u16_l add_ie_len; -+ /// Index of the VIF that is scanning -+ u8_l vif_idx; -+ /// Number of channels to scan -+ u8_l chan_cnt; -+ /// Number of SSIDs to scan for -+ u8_l ssid_cnt; -+ /// no CCK - For P2P frames not being sent at CCK rate in 2GHz band. -+ bool no_cck; -+ /// Scan duration, in us -+ u32_l duration; -+}; -+ -+struct scanu_vendor_ie_req { -+ u16_l add_ie_len; -+ u8_l vif_idx; -+ u8_l ie[256]; -+}; -+ -+/// Structure containing the parameters of the @ref SCANU_START_CFM message -+struct scanu_start_cfm { -+ /// Index of the VIF that was scanning -+ u8_l vif_idx; -+ /// Status of the request -+ u8_l status; -+ /// Number of scan results available -+ u8_l result_cnt; -+}; -+ -+/// Parameters of the @SCANU_RESULT_IND message -+struct scanu_result_ind { -+ /// Length of the frame -+ u16_l length; -+ /// Frame control field of the frame. -+ u16_l framectrl; -+ /// Center frequency on which we received the packet -+ u16_l center_freq; -+ /// PHY band -+ u8_l band; -+ /// Index of the station that sent the frame. 0xFF if unknown. -+ u8_l sta_idx; -+ /// Index of the VIF that received the frame. 0xFF if unknown. -+ u8_l inst_nbr; -+ /// RSSI of the received frame. -+ s8_l rssi; -+ /// Frame payload. -+ u32_l payload[]; -+}; -+ -+/// Structure containing the parameters of the message. -+struct scanu_fast_req { -+ /// The SSID to scan in the channel. -+ struct mac_ssid ssid; -+ /// BSSID. -+ struct mac_addr bssid; -+ /// Probe delay. -+ u16_l probe_delay; -+ /// Minimum channel time. -+ u16_l minch_time; -+ /// Maximum channel time. -+ u16_l maxch_time; -+ /// The channel number to scan. -+ u16_l ch_nbr; -+}; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For ME messages -+/////////////////////////////////////////////////////////////////////////////// -+/// Messages that are logically related to the task. -+enum { -+ /// Configuration request from host. -+ ME_CONFIG_REQ = LMAC_FIRST_MSG(TASK_ME), -+ /// Configuration confirmation. -+ ME_CONFIG_CFM, -+ /// Configuration request from host. -+ ME_CHAN_CONFIG_REQ, -+ /// Configuration confirmation. -+ ME_CHAN_CONFIG_CFM, -+ /// Set control port state for a station. -+ ME_SET_CONTROL_PORT_REQ, -+ /// Control port setting confirmation. -+ ME_SET_CONTROL_PORT_CFM, -+ /// TKIP MIC failure indication. -+ ME_TKIP_MIC_FAILURE_IND, -+ /// Add a station to the FW (AP mode) -+ ME_STA_ADD_REQ, -+ /// Confirmation of the STA addition -+ ME_STA_ADD_CFM, -+ /// Delete a station from the FW (AP mode) -+ ME_STA_DEL_REQ, -+ /// Confirmation of the STA deletion -+ ME_STA_DEL_CFM, -+ /// Indication of a TX RA/TID queue credit update -+ ME_TX_CREDITS_UPDATE_IND, -+ /// Request indicating to the FW that there is traffic buffered on host -+ ME_TRAFFIC_IND_REQ, -+ /// Confirmation that the @ref ME_TRAFFIC_IND_REQ has been executed -+ ME_TRAFFIC_IND_CFM, -+ /// Request of RC statistics to a station -+ ME_RC_STATS_REQ, -+ /// RC statistics confirmation -+ ME_RC_STATS_CFM, -+ /// RC fixed rate request -+ ME_RC_SET_RATE_REQ, -+ /// Configure monitor interface -+ ME_CONFIG_MONITOR_REQ, -+ /// Configure monitor interface response -+ ME_CONFIG_MONITOR_CFM, -+ /// Setting power Save mode request from host -+ ME_SET_PS_MODE_REQ, -+ /// Set power Save mode confirmation -+ ME_SET_PS_MODE_CFM, -+ /// Setting Low Power level request from host -+ ME_SET_LP_LEVEL_REQ, -+ /// Set Low Power level confirmation -+ ME_SET_LP_LEVEL_CFM, -+ /// MAX number of messages -+ ME_MAX, -+}; -+ -+/// Structure containing the parameters of the @ref ME_START_REQ message -+struct me_config_req { -+ /// HT Capabilities -+ struct mac_htcapability ht_cap; -+ /// VHT Capabilities -+ struct mac_vhtcapability vht_cap; -+ /// HE capabilities -+ struct mac_hecapability he_cap; -+ /// Lifetime of packets sent under a BlockAck agreement (expressed in TUs) -+ u16_l tx_lft; -+ /// Maximum supported BW -+ u8_l phy_bw_max; -+ /// Boolean indicating if HT is supported or not -+ bool_l ht_supp; -+ /// Boolean indicating if VHT is supported or not -+ bool_l vht_supp; -+ /// Boolean indicating if HE is supported or not -+ bool_l he_supp; -+ /// Boolean indicating if HE OFDMA UL is enabled or not -+ bool_l he_ul_on; -+ /// Boolean indicating if PS mode shall be enabled or not -+ bool_l ps_on; -+ /// Boolean indicating if Antenna Diversity shall be enabled or not -+ bool_l ant_div_on; -+ /// Boolean indicating if Dynamic PS mode shall be used or not -+ bool_l dpsm; -+}; -+ -+/// Structure containing the parameters of the @ref ME_CHAN_CONFIG_REQ message -+struct me_chan_config_req { -+ /// List of 2.4GHz supported channels -+ struct mac_chan_def chan2G4[MAC_DOMAINCHANNEL_24G_MAX]; -+ /// List of 5GHz supported channels -+ struct mac_chan_def chan5G[MAC_DOMAINCHANNEL_5G_MAX]; -+ /// Number of 2.4GHz channels in the list -+ u8_l chan2G4_cnt; -+ /// Number of 5GHz channels in the list -+ u8_l chan5G_cnt; -+}; -+ -+/// Structure containing the parameters of the @ref ME_SET_CONTROL_PORT_REQ message -+struct me_set_control_port_req { -+ /// Index of the station for which the control port is opened -+ u8_l sta_idx; -+ /// Control port state -+ bool_l control_port_open; -+}; -+ -+/// Structure containing the parameters of the @ref ME_TKIP_MIC_FAILURE_IND message -+struct me_tkip_mic_failure_ind { -+ /// Address of the sending STA -+ struct mac_addr addr; -+ /// TSC value -+ u64_l tsc; -+ /// Boolean indicating if the packet was a group or unicast one (true if group) -+ bool_l ga; -+ /// Key Id -+ u8_l keyid; -+ /// VIF index -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of the @ref ME_STA_ADD_REQ message -+struct me_sta_add_req { -+ /// MAC address of the station to be added -+ struct mac_addr mac_addr; -+ /// Supported legacy rates -+ struct mac_rateset rate_set; -+ /// HT Capabilities -+ struct mac_htcapability ht_cap; -+ /// VHT Capabilities -+ struct mac_vhtcapability vht_cap; -+ /// HE capabilities -+ struct mac_hecapability he_cap; -+ /// Flags giving additional information about the station (@ref mac_sta_flags) -+ u32_l flags; -+ /// Association ID of the station -+ u16_l aid; -+ /// Bit field indicating which queues have U-APSD enabled -+ u8_l uapsd_queues; -+ /// Maximum size, in frames, of a APSD service period -+ u8_l max_sp_len; -+ /// Operation mode information (valid if bit @ref STA_OPMOD_NOTIF is -+ /// set in the flags) -+ u8_l opmode; -+ /// Index of the VIF the station is attached to -+ u8_l vif_idx; -+ /// Whether the the station is TDLS station -+ bool_l tdls_sta; -+ /// Indicate if the station is TDLS link initiator station -+ bool_l tdls_sta_initiator; -+ /// Indicate if the TDLS Channel Switch is allowed -+ bool_l tdls_chsw_allowed; -+}; -+ -+/// Structure containing the parameters of the @ref ME_STA_ADD_CFM message -+struct me_sta_add_cfm { -+ /// Station index -+ u8_l sta_idx; -+ /// Status of the station addition -+ u8_l status; -+ /// PM state of the station -+ u8_l pm_state; -+}; -+ -+/// Structure containing the parameters of the @ref ME_STA_DEL_REQ message. -+struct me_sta_del_req { -+ /// Index of the station to be deleted -+ u8_l sta_idx; -+ /// Whether the the station is TDLS station -+ bool_l tdls_sta; -+}; -+ -+/// Structure containing the parameters of the @ref ME_TX_CREDITS_UPDATE_IND message. -+struct me_tx_credits_update_ind { -+ /// Index of the station for which the credits are updated -+ u8_l sta_idx; -+ /// TID for which the credits are updated -+ u8_l tid; -+ /// Offset to be applied on the credit count -+ s8_l credits; -+}; -+ -+/// Structure containing the parameters of the @ref ME_TRAFFIC_IND_REQ message. -+struct me_traffic_ind_req { -+ /// Index of the station for which UAPSD traffic is available on host -+ u8_l sta_idx; -+ /// Flag indicating the availability of UAPSD packets for the given STA -+ u8_l tx_avail; -+ /// Indicate if traffic is on uapsd-enabled queues -+ bool_l uapsd; -+}; -+ -+struct mm_apm_staloss_ind -+{ -+ u8_l sta_idx; -+ u8_l vif_idx; -+ u8_l mac_addr[6]; -+}; -+ -+#ifdef CONFIG_SDIO_BT -+struct mm_bt_recv_ind -+{ -+ u32_l data_len; -+ u8_l bt_data[1024]; -+}; -+#endif -+ -+enum vendor_hwconfig_tag{ -+ ACS_TXOP_REQ = 0, -+ CHANNEL_ACCESS_REQ, -+ MAC_TIMESCALE_REQ, -+ CCA_THRESHOLD_REQ, -+ BWMODE_REQ, -+ CHIP_TEMP_GET_REQ, -+}; -+ -+enum { -+ BWMODE20M = 0, -+ BWMODE10M, -+ BWMODE5M, -+}; -+ -+struct mm_set_acs_txop_req -+{ -+ u32_l hwconfig_id; -+ u16_l txop_bk; -+ u16_l txop_be; -+ u16_l txop_vi; -+ u16_l txop_vo; -+}; -+ -+struct mm_set_channel_access_req -+{ -+ u32_l hwconfig_id; -+ u32_l edca[4]; -+ u8_l vif_idx; -+ u8_l retry_cnt; -+ u8_l rts_en; -+ u8_l long_nav_en; -+ u8_l cfe_en; -+ u8_l rc_retry_cnt[3]; -+ s8_l ccademod_th; -+}; -+ -+struct mm_set_mac_timescale_req -+{ -+ u32_l hwconfig_id; -+ u8_l sifsA_time; -+ u8_l sifsB_time; -+ u8_l slot_time; -+ u8_l rx_startdelay_ofdm; -+ u8_l rx_startdelay_long; -+ u8_l rx_startdelay_short; -+}; -+ -+struct mm_set_cca_threshold_req -+{ -+ u32_l hwconfig_id; -+ u8_l auto_cca_en; -+ s8_l cca20p_rise_th; -+ s8_l cca20s_rise_th; -+ s8_l cca20p_fall_th; -+ s8_l cca20s_fall_th; -+ -+}; -+ -+struct mm_set_bwmode_req -+{ -+ u32_l hwconfig_id; -+ u8_l bwmode; -+}; -+ -+struct mm_get_chip_temp_req -+{ -+ u32_l hwconfig_id; -+}; -+ -+struct mm_get_chip_temp_cfm -+{ -+ /// Temp degree val -+ s8_l degree; -+}; -+ -+struct mm_set_vendor_hwconfig_cfm -+{ -+ u32_l hwconfig_id; -+ union { -+ struct mm_get_chip_temp_cfm chip_temp_cfm; -+ }; -+}; -+ -+struct mm_set_txop_req -+{ -+ u16_l txop_bk; -+ u16_l txop_be; -+ u16_l txop_vi; -+ u16_l txop_vo; -+ u8_l long_nav_en; -+ u8_l cfe_en; -+}; -+ -+struct mm_get_fw_version_cfm -+{ -+ u8_l fw_version_len; -+ u8_l fw_version[63]; -+}; -+ -+struct mm_get_wifi_disable_cfm -+{ -+ u8_l wifi_disable; -+}; -+ -+enum vendor_swconfig_tag -+{ -+ BCN_CFG_REQ = 0, -+ TEMP_COMP_SET_REQ, -+ TEMP_COMP_GET_REQ, -+ EXT_FLAGS_SET_REQ, -+ EXT_FLAGS_GET_REQ, -+ EXT_FLAGS_MASK_SET_REQ, -+}; -+ -+struct mm_set_bcn_cfg_req -+{ -+ /// Ignore or not bcn tim bcmc bit -+ bool_l tim_bcmc_ignored_enable; -+}; -+ -+struct mm_set_bcn_cfg_cfm -+{ -+ /// Request status -+ bool_l tim_bcmc_ignored_status; -+}; -+ -+struct mm_set_temp_comp_req -+{ -+ /// Enable or not temp comp -+ u8_l enable; -+ u8_l reserved[3]; -+ u32_l tmr_period_ms; -+}; -+ -+struct mm_set_temp_comp_cfm -+{ -+ /// Request status -+ u8_l status; -+}; -+ -+struct mm_get_temp_comp_cfm -+{ -+ /// Request status -+ u8_l status; -+ /// Temp degree val -+ s8_l degree; -+}; -+ -+struct mm_set_ext_flags_req -+{ -+ u32_l user_flags; -+}; -+ -+struct mm_set_ext_flags_cfm -+{ -+ u32_l user_flags; -+}; -+ -+struct mm_get_ext_flags_cfm -+{ -+ u32_l user_flags; -+}; -+ -+struct mm_mask_set_ext_flags_req -+{ -+ u32_l user_flags_mask; -+ u32_l user_flags_val; -+}; -+ -+struct mm_mask_set_ext_flags_cfm -+{ -+ u32_l user_flags; -+}; -+ -+struct mm_set_vendor_swconfig_req -+{ -+ u32_l swconfig_id; -+ union { -+ struct mm_set_bcn_cfg_req bcn_cfg_req; -+ struct mm_set_temp_comp_req temp_comp_set_req; -+ struct mm_set_ext_flags_req ext_flags_set_req; -+ struct mm_mask_set_ext_flags_req ext_flags_mask_set_req; -+ }; -+}; -+ -+struct mm_set_vendor_swconfig_cfm -+{ -+ u32_l swconfig_id; -+ union { -+ struct mm_set_bcn_cfg_cfm bcn_cfg_cfm; -+ struct mm_set_temp_comp_cfm temp_comp_set_cfm; -+ struct mm_get_temp_comp_cfm temp_comp_get_cfm; -+ struct mm_set_ext_flags_cfm ext_flags_set_cfm; -+ struct mm_get_ext_flags_cfm ext_flags_get_cfm; -+ struct mm_mask_set_ext_flags_cfm ext_flags_mask_set_cfm; -+ }; -+}; -+ -+#ifdef CONFIG_SDIO_BT -+struct mm_bt_send_req -+{ -+ u32_l data_len; -+ u8_l bt_data[1024]; -+}; -+ -+struct mm_bt_send_cfm -+{ -+ u8_l status; -+}; -+#endif -+ -+/// Structure containing the parameters of the @ref ME_RC_STATS_REQ message. -+struct me_rc_stats_req { -+ /// Index of the station for which the RC statistics are requested -+ u8_l sta_idx; -+}; -+ -+/// Structure containing the rate control statistics -+struct rc_rate_stats { -+ /// Number of attempts (per sampling interval) -+ u16_l attempts; -+ /// Number of success (per sampling interval) -+ u16_l success; -+ /// Estimated probability of success (EWMA) -+ u16_l probability; -+ /// Rate configuration of the sample -+ u16_l rate_config; -+ union { -+ struct { -+ /// Number of times the sample has been skipped (per sampling interval) -+ u8_l sample_skipped; -+ /// Whether the old probability is available -+ bool_l old_prob_available; -+ /// Whether the rate can be used in the retry chain -+ bool_l rate_allowed; -+ }; -+ struct { -+ /// RU size and UL length received in the latest HE trigger frame -+ u16_l ru_and_length; -+ }; -+ }; -+}; -+ -+/// Number of RC samples -+#define RC_MAX_N_SAMPLE 10 -+/// Index of the HE statistics element in the table -+#define RC_HE_STATS_IDX RC_MAX_N_SAMPLE -+ -+/// Structure containing the parameters of the @ref ME_RC_STATS_CFM message. -+struct me_rc_stats_cfm { -+ /// Index of the station for which the RC statistics are provided -+ u8_l sta_idx; -+ /// Number of samples used in the RC algorithm -+ u16_l no_samples; -+ /// Number of MPDUs transmitted (per sampling interval) -+ u16_l ampdu_len; -+ /// Number of AMPDUs transmitted (per sampling interval) -+ u16_l ampdu_packets; -+ /// Average number of MPDUs in each AMPDU frame (EWMA) -+ u32_l avg_ampdu_len; -+ // Current step 0 of the retry chain -+ u8_l sw_retry_step; -+ /// Trial transmission period -+ u8_l sample_wait; -+ /// Retry chain steps -+ u16_l retry_step_idx[4]; -+ /// RC statistics - Max number of RC samples, plus one for the HE TB statistics -+ struct rc_rate_stats rate_stats[RC_MAX_N_SAMPLE + 1]; -+ /// Throughput - Max number of RC samples, plus one for the HE TB statistics -+ u32_l tp[RC_MAX_N_SAMPLE + 1]; -+}; -+ -+/// Structure containing the parameters of the @ref ME_RC_SET_RATE_REQ message. -+struct me_rc_set_rate_req { -+ /// Index of the station for which the fixed rate is set -+ u8_l sta_idx; -+ /// Rate configuration to be set -+ u16_l fixed_rate_cfg; -+}; -+ -+/// Structure containing the parameters of the @ref ME_CONFIG_MONITOR_REQ message. -+struct me_config_monitor_req { -+ /// Channel to configure -+ struct mac_chan_op chan; -+ /// Is channel data valid -+ bool_l chan_set; -+ /// Enable report of unsupported HT frames -+ bool_l uf; -+ /// Enable auto-reply as the mac_addr matches -+ bool_l auto_reply; -+}; -+ -+/// Structure containing the parameters of the @ref ME_CONFIG_MONITOR_CFM message. -+struct me_config_monitor_cfm { -+ /// Channel context index -+ u8_l chan_index; -+ /// Channel parameters -+ struct mac_chan_op chan; -+}; -+ -+/// Structure containing the parameters of the @ref ME_SET_PS_MODE_REQ message. -+struct me_set_ps_mode_req { -+ /// Power Save is activated or deactivated -+ u8_l ps_state; -+}; -+ -+/// Structure containing the parameters of the @ref ME_SET_LP_LEVEL_REQ message. -+struct me_set_lp_level_req { -+ /// Low Power level -+ u8_l lp_level; -+}; -+ -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For SM messages -+/////////////////////////////////////////////////////////////////////////////// -+/// Message API of the SM task -+enum sm_msg_tag { -+ /// Request to connect to an AP -+ SM_CONNECT_REQ = LMAC_FIRST_MSG(TASK_SM), -+ /// Confirmation of connection -+ SM_CONNECT_CFM, -+ /// Indicates that the SM associated to the AP -+ SM_CONNECT_IND, -+ /// Request to disconnect -+ SM_DISCONNECT_REQ, -+ /// Confirmation of disconnection -+ SM_DISCONNECT_CFM, -+ /// Indicates that the SM disassociated the AP -+ SM_DISCONNECT_IND, -+ /// Request to start external authentication -+ SM_EXTERNAL_AUTH_REQUIRED_IND, -+ /// Response to external authentication request -+ SM_EXTERNAL_AUTH_REQUIRED_RSP, -+ /// Request to update assoc elements after FT over the air authentication -+ SM_FT_AUTH_IND, -+ /// Response to FT authentication with updated assoc elements -+ SM_FT_AUTH_RSP, -+ -+ SM_RSP_TIMEOUT_IND, -+ -+ SM_COEX_TS_TIMEOUT_IND, -+ -+ SM_EXTERNAL_AUTH_REQUIRED_RSP_CFM, -+ /// MAX number of messages -+ SM_MAX, -+}; -+ -+/// Structure containing the parameters of @ref SM_CONNECT_REQ message. -+struct sm_connect_req { -+ /// SSID to connect to -+ struct mac_ssid ssid; -+ /// BSSID to connect to (if not specified, set this field to WILDCARD BSSID) -+ struct mac_addr bssid; -+ /// Channel on which we have to connect (if not specified, set -1 in the chan.freq field) -+ struct mac_chan_def chan; -+ /// Connection flags (see @ref mac_connection_flags) -+ u32_l flags; -+ /// Control port Ethertype (in network endianness) -+ u16_l ctrl_port_ethertype; -+ /// Length of the association request IEs -+ u16_l ie_len; -+ /// Listen interval to be used for this connection -+ u16_l listen_interval; -+ /// Flag indicating if the we have to wait for the BC/MC traffic after beacon or not -+ bool_l dont_wait_bcmc; -+ /// Authentication type -+ u8_l auth_type; -+ /// UAPSD queues (bit0: VO, bit1: VI, bit2: BE, bit3: BK) -+ u8_l uapsd_queues; -+ /// VIF index -+ u8_l vif_idx; -+ /// Buffer containing the additional information elements to be put in the -+ /// association request -+ u32_l ie_buf[64]; -+}; -+ -+/// Structure containing the parameters of the @ref SM_CONNECT_CFM message. -+struct sm_connect_cfm { -+ /// Status. If 0, it means that the connection procedure will be performed and that -+ /// a subsequent @ref SM_CONNECT_IND message will be forwarded once the procedure is -+ /// completed -+ u8_l status; -+}; -+ -+#define SM_ASSOC_IE_LEN 800 -+/// Structure containing the parameters of the @ref SM_CONNECT_IND message. -+struct sm_connect_ind { -+ /// Status code of the connection procedure -+ u16_l status_code; -+ /// BSSID -+ struct mac_addr bssid; -+ /// Flag indicating if the indication refers to an internal roaming or from a host request -+ bool_l roamed; -+ /// Index of the VIF for which the association process is complete -+ u8_l vif_idx; -+ /// Index of the STA entry allocated for the AP -+ u8_l ap_idx; -+ /// Index of the LMAC channel context the connection is attached to -+ u8_l ch_idx; -+ /// Flag indicating if the AP is supporting QoS -+ bool_l qos; -+ /// ACM bits set in the AP WMM parameter element -+ u8_l acm; -+ /// Length of the AssocReq IEs -+ u16_l assoc_req_ie_len; -+ /// Length of the AssocRsp IEs -+ u16_l assoc_rsp_ie_len; -+ /// IE buffer -+ u32_l assoc_ie_buf[SM_ASSOC_IE_LEN/4]; -+ -+ u16_l aid; -+ u8_l band; -+ u16_l center_freq; -+ u8_l width; -+ u32_l center_freq1; -+ u32_l center_freq2; -+ -+ /// EDCA parameters -+ u32_l ac_param[AC_MAX]; -+}; -+ -+/// Structure containing the parameters of the @ref SM_DISCONNECT_REQ message. -+struct sm_disconnect_req { -+ /// Reason of the deauthentication. -+ u16_l reason_code; -+ /// Index of the VIF. -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of SM_ASSOCIATION_IND the message -+struct sm_association_ind { -+ // MAC ADDR of the STA -+ struct mac_addr me_mac_addr; -+}; -+ -+ -+/// Structure containing the parameters of the @ref SM_DISCONNECT_IND message. -+struct sm_disconnect_ind { -+ /// Reason of the disconnection. -+ u16_l reason_code; -+ /// Index of the VIF. -+ u8_l vif_idx; -+ /// FT over DS is ongoing -+ bool_l ft_over_ds; -+ u8_l reassoc; -+}; -+ -+/// Structure containing the parameters of the @ref SM_EXTERNAL_AUTH_REQUIRED_IND -+struct sm_external_auth_required_ind { -+ /// Index of the VIF. -+ u8_l vif_idx; -+ /// SSID to authenticate to -+ struct mac_ssid ssid; -+ /// BSSID to authenticate to -+ struct mac_addr bssid; -+ /// AKM suite of the respective authentication -+ u32_l akm; -+}; -+ -+/// Structure containing the parameters of the @ref SM_EXTERNAL_AUTH_REQUIRED_RSP -+struct sm_external_auth_required_rsp { -+ /// Index of the VIF. -+ u8_l vif_idx; -+ /// Authentication status -+ u16_l status; -+}; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For APM messages -+/////////////////////////////////////////////////////////////////////////////// -+/// Message API of the APM task -+enum apm_msg_tag { -+ /// Request to start the AP. -+ APM_START_REQ = LMAC_FIRST_MSG(TASK_APM), -+ /// Confirmation of the AP start. -+ APM_START_CFM, -+ /// Request to stop the AP. -+ APM_STOP_REQ, -+ /// Confirmation of the AP stop. -+ APM_STOP_CFM, -+ /// Request to start CAC -+ APM_START_CAC_REQ, -+ /// Confirmation of the CAC start -+ APM_START_CAC_CFM, -+ /// Request to stop CAC -+ APM_STOP_CAC_REQ, -+ /// Confirmation of the CAC stop -+ APM_STOP_CAC_CFM, -+ -+ APM_SET_BEACON_IE_REQ, -+ APM_SET_BEACON_IE_CFM, -+ -+ /// MAX number of messages -+ APM_MAX, -+}; -+ -+/// Structure containing the parameters of the @ref APM_START_REQ message. -+struct apm_start_req { -+ /// Basic rate set -+ struct mac_rateset basic_rates; -+ /// Control channel on which we have to enable the AP -+ struct mac_chan_def chan; -+ /// Center frequency of the first segment -+ u32_l center_freq1; -+ /// Center frequency of the second segment (only in 80+80 configuration) -+ u32_l center_freq2; -+ /// Width of channel -+ u8_l ch_width; -+ /// Address, in host memory, to the beacon template -+ u32_l bcn_addr; -+ /// Length of the beacon template -+ u16_l bcn_len; -+ /// Offset of the TIM IE in the beacon -+ u16_l tim_oft; -+ /// Beacon interval -+ u16_l bcn_int; -+ /// Flags (@ref mac_connection_flags) -+ u32_l flags; -+ /// Control port Ethertype -+ u16_l ctrl_port_ethertype; -+ /// Length of the TIM IE -+ u8_l tim_len; -+ /// Index of the VIF for which the AP is started -+ u8_l vif_idx; -+}; -+ -+struct apm_set_bcn_ie_req { -+ u8_l vif_idx; -+ u16_l bcn_ie_len; -+ u8_l bcn_ie[512]; -+}; -+ -+/// Structure containing the parameters of the @ref APM_START_CFM message. -+struct apm_start_cfm { -+ /// Status of the AP starting procedure -+ u8_l status; -+ /// Index of the VIF for which the AP is started -+ u8_l vif_idx; -+ /// Index of the channel context attached to the VIF -+ u8_l ch_idx; -+ /// Index of the STA used for BC/MC traffic -+ u8_l bcmc_idx; -+}; -+ -+/// Structure containing the parameters of the @ref APM_STOP_REQ message. -+struct apm_stop_req { -+ /// Index of the VIF for which the AP has to be stopped -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of the @ref APM_START_CAC_REQ message. -+struct apm_start_cac_req { -+ /// Control channel on which we have to start the CAC -+ struct mac_chan_def chan; -+ /// Center frequency of the first segment -+ u32_l center_freq1; -+ /// Center frequency of the second segment (only in 80+80 configuration) -+ u32_l center_freq2; -+ /// Width of channel -+ u8_l ch_width; -+ /// Index of the VIF for which the CAC is started -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of the @ref APM_START_CAC_CFM message. -+struct apm_start_cac_cfm { -+ /// Status of the CAC starting procedure -+ u8_l status; -+ /// Index of the channel context attached to the VIF for CAC -+ u8_l ch_idx; -+}; -+ -+/// Structure containing the parameters of the @ref APM_STOP_CAC_REQ message. -+struct apm_stop_cac_req { -+ /// Index of the VIF for which the CAC has to be stopped -+ u8_l vif_idx; -+}; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For MESH messages -+/////////////////////////////////////////////////////////////////////////////// -+ -+/// Maximum length of the Mesh ID -+#define MESH_MESHID_MAX_LEN (32) -+ -+/// Message API of the MESH task -+enum mesh_msg_tag -+{ -+ /// Request to start the MP -+ MESH_START_REQ = LMAC_FIRST_MSG(TASK_MESH), -+ /// Confirmation of the MP start. -+ MESH_START_CFM, -+ -+ /// Request to stop the MP. -+ MESH_STOP_REQ, -+ /// Confirmation of the MP stop. -+ MESH_STOP_CFM, -+ -+ // Request to update the MP -+ MESH_UPDATE_REQ, -+ /// Confirmation of the MP update -+ MESH_UPDATE_CFM, -+ -+ /// Request information about a given link -+ MESH_PEER_INFO_REQ, -+ /// Response to the MESH_PEER_INFO_REQ message -+ MESH_PEER_INFO_CFM, -+ -+ /// Request automatic establishment of a path with a given mesh STA -+ MESH_PATH_CREATE_REQ, -+ /// Confirmation to the MESH_PATH_CREATE_REQ message -+ MESH_PATH_CREATE_CFM, -+ -+ /// Request a path update (delete path, modify next hop mesh STA) -+ MESH_PATH_UPDATE_REQ, -+ /// Confirmation to the MESH_PATH_UPDATE_REQ message -+ MESH_PATH_UPDATE_CFM, -+ -+ /// Indication from Host that the indicated Mesh Interface is a proxy for an external STA -+ MESH_PROXY_ADD_REQ, -+ -+ /// Indicate that a connection has been established or lost -+ MESH_PEER_UPDATE_IND, -+ /// Notification that a connection has been established or lost (when MPM handled by userspace) -+ MESH_PEER_UPDATE_NTF = MESH_PEER_UPDATE_IND, -+ -+ /// Indicate that a path is now active or inactive -+ MESH_PATH_UPDATE_IND, -+ /// Indicate that proxy information have been updated -+ MESH_PROXY_UPDATE_IND, -+ -+ /// MAX number of messages -+ MESH_MAX, -+}; -+ -+ -+/// Structure containing the parameters of the @ref MESH_START_REQ message. -+struct mesh_start_req { -+ /// Basic rate set -+ struct mac_rateset basic_rates; -+ /// Control channel on which we have to enable the AP -+ struct mac_chan_def chan; -+ /// Center frequency of the first segment -+ u32_l center_freq1; -+ /// Center frequency of the second segment (only in 80+80 configuration) -+ u32_l center_freq2; -+ /// Width of channel -+ u8_l ch_width; -+ /// DTIM Period -+ u8_l dtim_period; -+ /// Beacon Interval -+ u16_l bcn_int; -+ /// Index of the VIF for which the MP is started -+ u8_l vif_index; -+ /// Length of the Mesh ID -+ u8_l mesh_id_len; -+ /// Mesh ID -+ u8_l mesh_id[MESH_MESHID_MAX_LEN]; -+ /// Address of the IEs to download -+ u32_l ie_addr; -+ /// Length of the provided IEs -+ u8_l ie_len; -+ /// Indicate if Mesh Peering Management (MPM) protocol is handled in userspace -+ bool_l user_mpm; -+ /// Indicate if Mesh Point is using authentication -+ bool_l is_auth; -+ /// Indicate which authentication method is used -+ u8_l auth_id; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_START_CFM message. -+struct mesh_start_cfm { -+ /// Status of the MP starting procedure -+ u8_l status; -+ /// Index of the VIF for which the MP is started -+ u8_l vif_idx; -+ /// Index of the channel context attached to the VIF -+ u8_l ch_idx; -+ /// Index of the STA used for BC/MC traffic -+ u8_l bcmc_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_STOP_REQ message. -+struct mesh_stop_req { -+ /// Index of the VIF for which the MP has to be stopped -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_STOP_CFM message. -+struct mesh_stop_cfm { -+ /// Index of the VIF for which the MP has to be stopped -+ u8_l vif_idx; -+ /// Status -+ u8_l status; -+}; -+ -+/// Bit fields for mesh_update_req message's flags value -+enum mesh_update_flags_bit { -+ /// Root Mode -+ MESH_UPDATE_FLAGS_ROOT_MODE_BIT = 0, -+ /// Gate Mode -+ MESH_UPDATE_FLAGS_GATE_MODE_BIT, -+ /// Mesh Forwarding -+ MESH_UPDATE_FLAGS_MESH_FWD_BIT, -+ /// Local Power Save Mode -+ MESH_UPDATE_FLAGS_LOCAL_PSM_BIT, -+}; -+ -+/// Structure containing the parameters of the @ref MESH_UPDATE_REQ message. -+struct mesh_update_req { -+ /// Flags, indicate fields which have been updated -+ u8_l flags; -+ /// VIF Index -+ u8_l vif_idx; -+ /// Root Mode -+ u8_l root_mode; -+ /// Gate Announcement -+ bool_l gate_announ; -+ /// Mesh Forwarding -+ bool_l mesh_forward; -+ /// Local PS Mode -+ u8_l local_ps_mode; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_UPDATE_CFM message. -+struct mesh_update_cfm { -+ /// Status -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_PEER_INFO_REQ message. -+struct mesh_peer_info_req { -+ ///Index of the station allocated for the peer -+ u8_l sta_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_PEER_INFO_CFM message. -+struct mesh_peer_info_cfm { -+ /// Response status -+ u8_l status; -+ /// Index of the station allocated for the peer -+ u8_l sta_idx; -+ /// Local Link ID -+ u16_l local_link_id; -+ /// Peer Link ID -+ u16_l peer_link_id; -+ /// Local PS Mode -+ u8_l local_ps_mode; -+ /// Peer PS Mode -+ u8_l peer_ps_mode; -+ /// Non-peer PS Mode -+ u8_l non_peer_ps_mode; -+ /// Link State -+ u8_l link_state; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_PATH_CREATE_REQ message. -+struct mesh_path_create_req { -+ /// Index of the interface on which path has to be created -+ u8_l vif_idx; -+ /// Indicate if originator MAC Address is provided -+ bool_l has_orig_addr; -+ /// Path Target MAC Address -+ struct mac_addr tgt_mac_addr; -+ /// Originator MAC Address -+ struct mac_addr orig_mac_addr; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_PATH_CREATE_CFM message. -+struct mesh_path_create_cfm { -+ /// Confirmation status -+ u8_l status; -+ /// VIF Index -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_PATH_UPDATE_REQ message. -+struct mesh_path_update_req { -+ /// Indicate if path must be deleted -+ bool_l delete; -+ /// Index of the interface on which path has to be created -+ u8_l vif_idx; -+ /// Path Target MAC Address -+ struct mac_addr tgt_mac_addr; -+ /// Next Hop MAC Address -+ struct mac_addr nhop_mac_addr; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_PATH_UPDATE_CFM message. -+struct mesh_path_update_cfm { -+ /// Confirmation status -+ u8_l status; -+ /// VIF Index -+ u8_l vif_idx; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_PROXY_ADD_REQ message. -+struct mesh_proxy_add_req { -+ /// VIF Index -+ u8_l vif_idx; -+ /// MAC Address of the External STA -+ struct mac_addr ext_sta_addr; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_PROXY_UPDATE_IND -+struct mesh_proxy_update_ind { -+ /// Indicate if proxy information has been added or deleted -+ bool_l delete; -+ /// Indicate if we are a proxy for the external STA -+ bool_l local; -+ /// VIF Index -+ u8_l vif_idx; -+ /// MAC Address of the External STA -+ struct mac_addr ext_sta_addr; -+ /// MAC Address of the proxy (only valid if local is false) -+ struct mac_addr proxy_mac_addr; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_PEER_UPDATE_IND message. -+struct mesh_peer_update_ind { -+ /// Indicate if connection has been established or lost -+ bool_l estab; -+ /// VIF Index -+ u8_l vif_idx; -+ /// STA Index -+ u8_l sta_idx; -+ /// Peer MAC Address -+ struct mac_addr peer_addr; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_PEER_UPDATE_NTF message. -+struct mesh_peer_update_ntf { -+ /// VIF Index -+ u8_l vif_idx; -+ /// STA Index -+ u8_l sta_idx; -+ /// Mesh Link State -+ u8_l state; -+}; -+ -+/// Structure containing the parameters of the @ref MESH_PATH_UPDATE_IND message. -+struct mesh_path_update_ind { -+ /// Indicate if path is deleted or not -+ bool_l delete; -+ /// Indicate if path is towards an external STA (not part of MBSS) -+ bool_l ext_sta; -+ /// VIF Index -+ u8_l vif_idx; -+ /// Path Index -+ u8_l path_idx; -+ /// Target MAC Address -+ struct mac_addr tgt_mac_addr; -+ /// External STA MAC Address (only if ext_sta is true) -+ struct mac_addr ext_sta_mac_addr; -+ /// Next Hop STA Index -+ u8_l nhop_sta_idx; -+}; -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For Debug messages -+/////////////////////////////////////////////////////////////////////////////// -+ -+/// Messages related to Debug Task -+enum dbg_msg_tag { -+ /// Memory read request -+ DBG_MEM_READ_REQ = LMAC_FIRST_MSG(TASK_DBG), -+ /// Memory read confirm -+ DBG_MEM_READ_CFM, -+ /// Memory write request -+ DBG_MEM_WRITE_REQ, -+ /// Memory write confirm -+ DBG_MEM_WRITE_CFM, -+ /// Module filter request -+ DBG_SET_MOD_FILTER_REQ, -+ /// Module filter confirm -+ DBG_SET_MOD_FILTER_CFM, -+ /// Severity filter request -+ DBG_SET_SEV_FILTER_REQ, -+ /// Severity filter confirm -+ DBG_SET_SEV_FILTER_CFM, -+ /// LMAC/MAC HW fatal error indication -+ DBG_ERROR_IND, -+ /// Request to get system statistics -+ DBG_GET_SYS_STAT_REQ, -+ /// COnfirmation of system statistics -+ DBG_GET_SYS_STAT_CFM, -+ /// Memory block write request -+ DBG_MEM_BLOCK_WRITE_REQ, -+ /// Memory block write confirm -+ DBG_MEM_BLOCK_WRITE_CFM, -+ /// Start app request -+ DBG_START_APP_REQ, -+ /// Start app confirm -+ DBG_START_APP_CFM, -+ /// Start npc request -+ DBG_START_NPC_REQ, -+ /// Start npc confirm -+ DBG_START_NPC_CFM, -+ /// Memory mask write request -+ DBG_MEM_MASK_WRITE_REQ, -+ /// Memory mask write confirm -+ DBG_MEM_MASK_WRITE_CFM, -+ -+ DBG_RFTEST_CMD_REQ, -+ DBG_RFTEST_CMD_CFM, -+ DBG_BINDING_REQ, -+ DBG_BINDING_CFM, -+ DBG_BINDING_IND, -+ -+ DBG_CUSTOM_MSG_REQ, -+ DBG_CUSTOM_MSG_CFM, -+ DBG_CUSTOM_MSG_IND, -+ -+ DBG_GPIO_WRITE_REQ, -+ DBG_GPIO_WRITE_CFM, -+ DBG_GPIO_READ_REQ, -+ DBG_GPIO_READ_CFM, -+ DBG_GPIO_INIT_REQ, -+ DBG_GPIO_INIT_CFM, -+ -+ /// EF usrdata read request -+ DBG_EF_USRDATA_READ_REQ, -+ /// EF usrdata read confirm -+ DBG_EF_USRDATA_READ_CFM, -+ /// Memory block read request -+ DBG_MEM_BLOCK_READ_REQ, -+ /// Memory block read confirm -+ DBG_MEM_BLOCK_READ_CFM, -+ -+ DBG_PWM_INIT_REQ, -+ DBG_PWM_INIT_CFM, -+ DBG_PWM_DEINIT_REQ, -+ DBG_PWM_DEINIT_CFM, -+ -+ /// Max number of Debug messages -+ DBG_MAX, -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_READ_REQ message. -+struct dbg_mem_read_req { -+ u32_l memaddr; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_READ_CFM message. -+struct dbg_mem_read_cfm { -+ u32_l memaddr; -+ u32_l memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_WRITE_REQ message. -+struct dbg_mem_write_req { -+ u32_l memaddr; -+ u32_l memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_WRITE_CFM message. -+struct dbg_mem_write_cfm { -+ u32_l memaddr; -+ u32_l memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_MASK_WRITE_REQ message. -+struct dbg_mem_mask_write_req { -+ u32_l memaddr; -+ u32_l memmask; -+ u32_l memdata; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_MASK_WRITE_CFM message. -+struct dbg_mem_mask_write_cfm { -+ u32_l memaddr; -+ u32_l memdata; -+}; -+ -+struct dbg_rftest_cmd_req { -+ u32_l cmd; -+ u32_l argc; -+ u8_l argv[10]; -+}; -+ -+struct dbg_rftest_cmd_cfm { -+ u32_l rftest_result[18]; -+}; -+ -+struct dbg_gpio_write_req { -+ uint8_t gpio_idx; -+ uint8_t gpio_val; -+}; -+ -+struct dbg_gpio_read_req { -+ uint8_t gpio_idx; -+}; -+ -+struct dbg_gpio_read_cfm { -+ uint8_t gpio_idx; -+ uint8_t gpio_val; -+}; -+ -+struct dbg_gpio_init_req { -+ uint8_t gpio_idx; -+ uint8_t gpio_dir; //1 output, 0 input; -+ uint8_t gpio_val; //for output, 1 high, 0 low; -+}; -+ -+#ifdef CONFIG_MCU_MESSAGE -+/// Structure containing the parameters of the @ref DBG_CUSTOM_MSG_REQ message. -+struct dbg_custom_msg_req -+{ -+ u32_l cmd; -+ u32_l len; -+ u32_l flags; -+ u32_l buf[1]; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_CUSTOM_MSG_CFM message. -+struct dbg_custom_msg_cfm -+{ -+ u32_l cmd; -+ u32_l len; -+ u32_l status; -+ u32_l buf[1]; -+}; -+ -+typedef struct dbg_custom_msg_cfm dbg_custom_msg_ind_t; -+#endif -+ -+/// Structure containing the parameters of the @ref DBG_SET_MOD_FILTER_REQ message. -+struct dbg_set_mod_filter_req { -+ /// Bit field indicating for each module if the traces are enabled or not -+ u32_l mod_filter; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_SEV_MOD_FILTER_REQ message. -+struct dbg_set_sev_filter_req { -+ /// Bit field indicating the severity threshold for the traces -+ u32_l sev_filter; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_GET_SYS_STAT_CFM message. -+struct dbg_get_sys_stat_cfm { -+ /// Time spent in CPU sleep since last reset of the system statistics -+ u32_l cpu_sleep_time; -+ /// Time spent in DOZE since last reset of the system statistics -+ u32_l doze_time; -+ /// Total time spent since last reset of the system statistics -+ u32_l stats_time; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_BLOCK_WRITE_REQ message. -+struct dbg_mem_block_write_req { -+ u32_l memaddr; -+ u32_l memsize; -+ u32_l memdata[1024 / sizeof(u32_l)]; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_MEM_BLOCK_WRITE_CFM message. -+struct dbg_mem_block_write_cfm { -+ u32_l wstatus; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_START_APP_REQ message. -+struct dbg_start_app_req { -+ u32_l bootaddr; -+ u32_l boottype; -+}; -+ -+/// Structure containing the parameters of the @ref DBG_START_APP_CFM message. -+struct dbg_start_app_cfm { -+ u32_l bootstatus; -+}; -+ -+enum { -+ HOST_START_APP_AUTO = 1, -+ HOST_START_APP_CUSTOM, -+ HOST_START_APP_FNCALL = 4, -+ HOST_START_APP_DUMMY = 5, -+}; -+ -+ -+/////////////////////////////////////////////////////////////////////////////// -+/////////// For TDLS messages -+/////////////////////////////////////////////////////////////////////////////// -+ -+/// List of messages related to the task. -+enum tdls_msg_tag { -+ /// TDLS channel Switch Request. -+ TDLS_CHAN_SWITCH_REQ = LMAC_FIRST_MSG(TASK_TDLS), -+ /// TDLS channel switch confirmation. -+ TDLS_CHAN_SWITCH_CFM, -+ /// TDLS channel switch indication. -+ TDLS_CHAN_SWITCH_IND, -+ /// TDLS channel switch to base channel indication. -+ TDLS_CHAN_SWITCH_BASE_IND, -+ /// TDLS cancel channel switch request. -+ TDLS_CANCEL_CHAN_SWITCH_REQ, -+ /// TDLS cancel channel switch confirmation. -+ TDLS_CANCEL_CHAN_SWITCH_CFM, -+ /// TDLS peer power save indication. -+ TDLS_PEER_PS_IND, -+ /// TDLS peer traffic indication request. -+ TDLS_PEER_TRAFFIC_IND_REQ, -+ /// TDLS peer traffic indication confirmation. -+ TDLS_PEER_TRAFFIC_IND_CFM, -+ -+#ifdef CONFIG_SDIO_BT -+ TDLS_SDIO_BT_SEND_REQ = LMAC_FIRST_MSG(TASK_TDLS)+16, -+ TDLS_SDIO_BT_SEND_CFM, -+ TDLS_SDIO_BT_RECV_IND, -+#endif -+ /// MAX number of messages -+ TDLS_MAX -+}; -+ -+/// Structure containing the parameters of the @ref TDLS_CHAN_SWITCH_REQ message -+struct tdls_chan_switch_req { -+ /// Index of the VIF -+ u8_l vif_index; -+ /// STA Index -+ u8_l sta_idx; -+ /// MAC address of the TDLS station -+ struct mac_addr peer_mac_addr; -+ bool_l initiator; -+ /// Band (2.4GHz or 5GHz) -+ u8_l band; -+ /// Channel type: 20,40,80,160 or 80+80 MHz -+ u8_l type; -+ /// Frequency for Primary 20MHz channel (in MHz) -+ u16_l prim20_freq; -+ /// Frequency for Center of the contiguous channel or center of Primary 80+80 -+ u16_l center1_freq; -+ /// Frequency for Center of the non-contiguous secondary 80+80 -+ u16_l center2_freq; -+ /// TX power (in dBm) -+ s8_l tx_power; -+ /// Operating class -+ u8_l op_class; -+}; -+ -+/// Structure containing the parameters of the @ref TDLS_CANCEL_CHAN_SWITCH_REQ message -+struct tdls_cancel_chan_switch_req { -+ /// Index of the VIF -+ u8_l vif_index; -+ /// STA Index -+ u8_l sta_idx; -+ /// MAC address of the TDLS station -+ struct mac_addr peer_mac_addr; -+}; -+ -+ -+/// Structure containing the parameters of the @ref TDLS_CHAN_SWITCH_CFM message -+struct tdls_chan_switch_cfm { -+ /// Status of the operation -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref TDLS_CANCEL_CHAN_SWITCH_CFM message -+struct tdls_cancel_chan_switch_cfm { -+ /// Status of the operation -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref TDLS_CHAN_SWITCH_IND message -+struct tdls_chan_switch_ind { -+ /// VIF Index -+ u8_l vif_index; -+ /// Channel Context Index -+ u8_l chan_ctxt_index; -+ /// Status of the operation -+ u8_l status; -+}; -+ -+/// Structure containing the parameters of the @ref TDLS_CHAN_SWITCH_BASE_IND message -+struct tdls_chan_switch_base_ind { -+ /// VIF Index -+ u8_l vif_index; -+ /// Channel Context index -+ u8_l chan_ctxt_index; -+}; -+ -+/// Structure containing the parameters of the @ref TDLS_PEER_PS_IND message -+struct tdls_peer_ps_ind { -+ /// VIF Index -+ u8_l vif_index; -+ /// STA Index -+ u8_l sta_idx; -+ /// MAC ADDR of the TDLS STA -+ struct mac_addr peer_mac_addr; -+ /// Flag to indicate if the TDLS peer is going to sleep -+ bool ps_on; -+}; -+ -+/// Structure containing the parameters of the @ref TDLS_PEER_TRAFFIC_IND_REQ message -+struct tdls_peer_traffic_ind_req { -+ /// VIF Index -+ u8_l vif_index; -+ /// STA Index -+ u8_l sta_idx; -+ // MAC ADDR of the TDLS STA -+ struct mac_addr peer_mac_addr; -+ /// Dialog token -+ u8_l dialog_token; -+ /// TID of the latest MPDU transmitted over the TDLS direct link to the TDLS STA -+ u8_l last_tid; -+ /// Sequence number of the latest MPDU transmitted over the TDLS direct link -+ /// to the TDLS STA -+ u16_l last_sn; -+}; -+ -+/// Structure containing the parameters of the @ref TDLS_PEER_TRAFFIC_IND_CFM message -+struct tdls_peer_traffic_ind_cfm { -+ /// Status of the operation -+ u8_l status; -+}; -+ -+ -+#endif // LMAC_MSG_H_ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_types.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_types.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_types.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/lmac_types.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,62 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file co_types.h -+ * -+ * @brief This file replaces the need to include stdint or stdbool typical headers, -+ * which may not be available in all toolchains, and adds new types -+ * -+ * Copyright (C) RivieraWaves 2009-2019 -+ * -+ * $Rev: $ -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _LMAC_INT_H_ -+#define _LMAC_INT_H_ -+ -+ -+/** -+ **************************************************************************************** -+ * @addtogroup CO_INT -+ * @ingroup COMMON -+ * @brief Common integer standard types (removes use of stdint) -+ * -+ * @{ -+ **************************************************************************************** -+ */ -+ -+ -+/* -+ * DEFINES -+ **************************************************************************************** -+ */ -+ -+#include -+#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+#include -+#else -+#include -+#endif -+ -+#ifdef CONFIG_RWNX_TL4 -+typedef uint16_t u8_l; -+typedef int16_t s8_l; -+typedef uint16_t bool_l; -+#else -+typedef uint8_t u8_l; -+typedef int8_t s8_l; -+typedef bool bool_l; -+#endif -+typedef uint16_t u16_l; -+typedef int16_t s16_l; -+typedef uint32_t u32_l; -+typedef int32_t s32_l; -+typedef uint64_t u64_l; -+ -+ -+ -+/// @} CO_INT -+#endif // _LMAC_INT_H_ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Makefile linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Makefile ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Makefile 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,380 @@ -+EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS) -+EXTRA_CFLAGS += -Wno-implicit-fallthrough -+#EXTRA_CFLAGS += -Wno-unused-function -+#EXTRA_CFLAGS += -Wno-maybe-uninitialized -+#EXTRA_CFLAGS += -Wno-unused-variable -+ -+RWNX_VERS_NUM := 6.4.3.0 -+ -+CONFIG_COUNTRY_CODE = "00" -+ -+MODULE_NAME = aic8800_fdrv -+CONFIG_AIC8800_WLAN_SUPPORT = m -+ -+# Support of bootrom start -+CONFIG_START_FROM_BOOTROM = y -+ -+# Support of pmic setting, new version bootrom avaliable -+CONFIG_PMIC_SETTING ?=y -+ -+# Select 8800DC/DW DCDC_VRF mode, check your board -+CONFIG_VRF_DCDC_MODE = y -+ -+ -+# ROM patch enabled option -+CONFIG_ROM_PATCH_EN ?=y -+# Support chip with mcu -+CONFIG_MCU_INTEGRATED ?= n -+CONFIG_MCU_MESSAGE ?= n -+ifeq ($(CONFIG_MCU_INTEGRATED), y) -+CONFIG_PMIC_SETTING = n -+else -+CONFIG_MCU_MESSAGE ?= n -+endif -+ -+# -+# WAITING FOR KCONFIG { -+# -+CONFIG_RWNX_FULLMAC ?= y -+CONFIG_RWNX_FHOST ?= n -+ -+# -+# DEBUG OPTIONS -+CONFIG_RWNX_UM_HELPER_DFLT ?= "/dini/dini_bin/rwnx_umh.sh" -+ -+# -+# FW ARCH: -+CONFIG_RWNX_SDM ?= n -+CONFIG_RWNX_TL4 ?= n -+ -+# IPC version -+CONFIG_RWNX_OLD_IPC ?= n -+ -+# Support of P2P DebugFS for enabling/disabling NoA and OppPS -+CONFIG_RWNX_P2P_DEBUGFS := n -+# -+# } // WAITING FOR KCONFIG -+# -+ -+# Enable A-MSDU support (need FW support) -+## Select this if FW is compiled with AMSDU support -+CONFIG_RWNX_SPLIT_TX_BUF ?= n -+## Select this TO send AMSDU -+CONFIG_RWNX_AMSDUS_TX ?= n -+ -+# Enable BFMER support (need FW support) -+CONFIG_RWNX_BFMER ?= n -+ -+CONFIG_SDIO_SUPPORT =y -+CONFIG_USB_SUPPORT =n -+CONFIG_RX_REORDER ?=y -+CONFIG_ARP_OFFLOAD =y -+CONFIG_RADAR_OR_IR_DETECT =n -+CONFIG_DOWNLOAD_FW =n -+CONFIG_RFTEST=y -+CONFIG_USB_BT =y -+CONFIG_SDIO_BT=n -+CONFIG_USE_5G ?= y -+CONFIG_SDIO_PWRCTRL ?= y -+CONFIG_CREATE_TRACE_POINTS = n -+CONFIG_TXRX_THREAD_PRIO = y -+# CONFIG_COEX = n for BT_ONLY, CONFIG_COEX =y for combo and sw -+CONFIG_COEX = y -+CONFIG_RX_NETIF_RECV_SKB = y -+CONFIG_GPIO_WAKEUP ?= n -+CONFIG_SET_VENDOR_EXTENSION_IE = n -+CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y -+CONFIG_WPA3_FOR_OLD_KERNEL ?= n -+CONFIG_VHT_FOR_OLD_KERNEL ?= n -+CONFIG_HE_FOR_OLD_KERNEL ?= n -+CONFIG_PREALLOC_RX_SKB = n -+CONFIG_WIFI_SUSPEND_FOR_LINUX = n -+# Need to set fw path in BOARD_KERNEL_CMDLINE -+CONFIG_USE_FW_REQUEST = n -+CONFIG_USE_P2P0=n -+CONFIG_TX_NETIF_FLOWCTRL = n -+CONFIG_ONE_TXQ = n -+CONFIG_BR_SUPPORT =n -+BR_NAME = br0 -+CONFIG_FDRV_NO_REG_SDIO=n -+CONFIG_SCHED_SCAN = n -+CONFIG_OOB ?= n -+CONFIG_USE_CUSTOMER_MAC = n -+CONFIG_PREALLOC_TXQ ?= y -+CONFIG_DPD = y -+CONFIG_FORCE_DPD_CALIB = y -+CONFIG_FILTER_TCP_ACK =n -+CONFIG_RESV_MEM_SUPPORT ?= y -+CONFIG_GKI = n -+CONFIG_TEMP_COMP = n -+# CONFIG_MCC = n for sta and p2p concurrent in same channel. -+CONFIG_MCC = y -+ -+ifneq ($(CONFIG_WIRELESS_EXT), y) -+CONFIG_USE_WIRELESS_EXT = n -+endif -+ -+# Support of MU-MIMO transmission (need FW support) -+ifeq ($(CONFIG_RWNX_BFMER), y) -+CONFIG_RWNX_MUMIMO_TX ?= n -+else -+CONFIG_RWNX_MUMIMO_TX = n -+endif -+ -+# Enable handling of radar event -+CONFIG_RWNX_RADAR ?= y -+ -+# Enable HW queue for Broadcast/Multicast traffic (need FW support) -+CONFIG_RWNX_BCMC ?= y -+ -+# Enable Monitor+Data interface support (need FW support) -+CONFIG_RWNX_MON_DATA =y -+ -+# extra DEBUG config -+CONFIG_RWNX_SW_PROFILING ?= n -+CONFIG_RWNX_DBG ?= y -+CONFIG_DEBUG_FS ?= n -+ -+obj-$(CONFIG_AIC8800_WLAN_SUPPORT) := $(MODULE_NAME).o -+$(MODULE_NAME)-y := \ -+ rwnx_msg_tx.o \ -+ rwnx_msg_rx.o \ -+ rwnx_utils.o \ -+ rwnx_cmds.o \ -+ rwnx_irqs.o \ -+ rwnx_cfgfile.o \ -+ rwnx_strs.o \ -+ rwnx_rx.o \ -+ rwnx_tx.o \ -+ rwnx_txq.o \ -+ rwnx_main.o \ -+ rwnx_mod_params.o \ -+ rwnx_mesh.o \ -+ rwnx_platform.o \ -+ rwnx_pci.o \ -+ rwnx_dini.o \ -+ rwnx_v7.o \ -+ ipc_host.o \ -+ rwnx_tdls.o \ -+ aic_vendor.o \ -+ md5.o \ -+ aicwf_compat_8800dc.o \ -+ aicwf_compat_8800d80.o \ -+ rwnx_wakelock.o \ -+ regdb.o \ -+ aicwf_rx_prealloc.o -+ -+$(MODULE_NAME)-$(CONFIG_BR_SUPPORT) += aic_br_ext.o -+$(MODULE_NAME)-$(CONFIG_RWNX_RADAR) += rwnx_radar.o -+$(MODULE_NAME)-$(CONFIG_DEBUG_FS) += rwnx_debugfs.o -+$(MODULE_NAME)-$(CONFIG_DEBUG_FS) += rwnx_fw_trace.o -+$(MODULE_NAME)-$(CONFIG_NL80211_TESTMODE) += rwnx_testmode.o -+$(MODULE_NAME)-$(CONFIG_RWNX_BFMER) += rwnx_bfmer.o -+$(MODULE_NAME)-$(CONFIG_RWNX_MUMIMO_TX) += rwnx_mu_group.o -+$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += sdio_host.o -+$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += aicwf_txrxif.o -+$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += aicwf_sdio.o -+$(MODULE_NAME)-$(CONFIG_FILTER_TCP_ACK) += aicwf_tcp_ack.o -+$(MODULE_NAME)-$(CONFIG_SDIO_BT) += aic_btsdio.o -+ -+$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += usb_host.o -+$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += aicwf_txrxif.o -+$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += aicwf_usb.o -+$(MODULE_NAME)-$(CONFIG_GKI) += rwnx_gki.o -+ -+ -+ -+ccflags-$(CONFIG_DEBUG_FS) += -DCONFIG_RWNX_DEBUGFS -+ccflags-$(CONFIG_DEBUG_FS) += -DCONFIG_RWNX_UM_HELPER_DFLT=\"$(CONFIG_RWNX_UM_HELPER_DFLT)\" -+ccflags-$(CONFIG_RWNX_P2P_DEBUGFS) += -DCONFIG_RWNX_P2P_DEBUGFS -+ -+# FW VARS -+ccflags-y += -DNX_VIRT_DEV_MAX=4 -+ -+#for 8800D and DCDW u01 -+#ccflags-y += -DNX_REMOTE_STA_MAX=10 -+ -+#for 8800DCDW u02 -+ccflags-y += -DNX_REMOTE_STA_MAX_FOR_OLD_IC=10 -+ccflags-y += -DNX_REMOTE_STA_MAX=32 -+ -+ccflags-y += -DNX_MU_GROUP_MAX=62 -+ccflags-y += -DNX_TXDESC_CNT=64 -+ccflags-y += -DNX_TX_MAX_RATES=4 -+ccflags-y += -DNX_CHAN_CTXT_CNT=3 -+ -+# FW ARCH: -+ccflags-$(CONFIG_RWNX_SDM) += -DCONFIG_RWNX_SDM -+ccflags-$(CONFIG_RWNX_TL4) += -DCONFIG_RWNX_TL4 -+ccflags-$(CONFIG_RWNX_OLD_IPC) += -DCONFIG_RWNX_OLD_IPC -+ccflags-$(CONFIG_PLATFORM_NANOPI_M4) += -DCONFIG_NANOPI_M4 -+ccflags-$(CONFIG_PLATFORM_INGENIC_T20) += -DCONFIG_INGENIC_T20 -+ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER -+ccflags-$(CONFIG_START_FROM_BOOTROM) += -DCONFIG_START_FROM_BOOTROM -+ccflags-$(CONFIG_PMIC_SETTING) += -DCONFIG_PMIC_SETTING -+ccflags-$(CONFIG_VRF_DCDC_MODE) += -DCONFIG_VRF_DCDC_MODE -+ccflags-$(CONFIG_ROM_PATCH_EN) += -DCONFIG_ROM_PATCH_EN -+ccflags-$(CONFIG_HE_FOR_OLD_KERNEL) += -DCONFIG_HE_FOR_OLD_KERNEL -+ccflags-$(CONFIG_MCU_INTEGRATED) += -DCONFIG_MCU_INTEGRATED -+ccflags-$(CONFIG_MCU_MESSAGE) += -DCONFIG_MCU_MESSAGE -+ccflags-$(CONFIG_COEX) += -DCONFIG_COEX -+ -+ccflags-y += -DCONFIG_RWNX_FULLMAC -+ccflags-y += -I$(srctree) -+ccflags-y += -I$(srctree)/$(src) -+ccflags-y += -I$(srctree)/$(src)/../aic8800_bsp -+ccflags-y += -DCONFIG_AIC_FW_PATH=\"$(CONFIG_AIC_FW_PATH)\" -+ccflags-$(CONFIG_RWNX_RADAR) += -DCONFIG_RWNX_RADAR -+ccflags-$(CONFIG_RWNX_MON_DATA) += -DCONFIG_RWNX_MON_DATA -+ccflags-$(CONFIG_RWNX_BFMER) += -DCONFIG_RWNX_BFMER -+ccflags-$(CONFIG_RWNX_SPLIT_TX_BUF) += -DCONFIG_RWNX_SPLIT_TX_BUF -+ifeq ($(CONFIG_RWNX_SPLIT_TX_BUF), y) -+ccflags-$(CONFIG_RWNX_AMSDUS_TX) += -DCONFIG_RWNX_AMSDUS_TX -+endif -+ccflags-$(CONFIG_RWNX_DBG) += -DCONFIG_RWNX_DBG -+ccflags-$(CONFIG_RWNX_SW_PROFILING) += -DCONFIG_RWNX_SW_PROFILING -+ccflags-$(CONFIG_RWNX_MUMIMO_TX) += -DCONFIG_RWNX_MUMIMO_TX -+ccflags-$(CONFIG_RFTEST) += -DCONFIG_RFTEST -+ccflags-y += -DDEFAULT_COUNTRY_CODE=""\$(CONFIG_COUNTRY_CODE)"\" -+ccflags-$(CONFIG_USE_5G) += -DUSE_5G -+ccflags-$(CONFIG_CREATE_TRACE_POINTS) += -DCREATE_TRACE_POINTS -+ccflags-$(CONFIG_TXRX_THREAD_PRIO) += -DCONFIG_TXRX_THREAD_PRIO -+ccflags-$(CONFIG_GPIO_WAKEUP) += -DCONFIG_GPIO_WAKEUP -+ccflags-$(CONFIG_SET_VENDOR_EXTENSION_IE) += -DCONFIG_SET_VENDOR_EXTENSION_IE -+ccflags-$(CONFIG_SUPPORT_REALTIME_CHANGE_MAC) += -DCONFIG_SUPPORT_REALTIME_CHANGE_MAC -+ccflags-$(CONFIG_WPA3_FOR_OLD_KERNEL) += -DCONFIG_WPA3_FOR_OLD_KERNEL -+ccflags-$(CONFIG_VHT_FOR_OLD_KERNEL) += -DCONFIG_VHT_FOR_OLD_KERNEL -+ccflags-$(CONFIG_PREALLOC_RX_SKB) += -DCONFIG_PREALLOC_RX_SKB -+ccflags-$(CONFIG_WIFI_SUSPEND_FOR_LINUX) += -DCONFIG_WIFI_SUSPEND_FOR_LINUX -+ccflags-$(CONFIG_USE_FW_REQUEST) += -DCONFIG_USE_FW_REQUEST -+ccflags-$(CONFIG_USE_P2P0) += -DCONFIG_USE_P2P0 -+ccflags-$(CONFIG_FDRV_NO_REG_SDIO) += -DCONFIG_FDRV_NO_REG_SDIO -+ccflags-$(CONFIG_SCHED_SCAN) += -DCONFIG_SCHED_SCAN -+ccflags-$(CONFIG_OOB) += -DCONFIG_OOB -+ccflags-$(CONFIG_USE_CUSTOMER_MAC) += -DCONFIG_USE_CUSTOMER_MAC -+ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ -+ccflags-$(CONFIG_DPD) += -DCONFIG_DPD -+ccflags-$(CONFIG_FORCE_DPD_CALIB) += -DCONFIG_FORCE_DPD_CALIB -DCONFIG_DPD -+ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK -+ccflags-$(CONFIG_SDIO_BT) += -DCONFIG_SDIO_BT -+ccflags-$(CONFIG_RESV_MEM_SUPPORT) += -DCONFIG_RESV_MEM_SUPPORT -+ccflags-$(CONFIG_GKI) += -DCONFIG_GKI -+ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP -+ccflags-$(CONFIG_MCC) += -DCONFIG_MCC -+ -+ -+ifeq ($(CONFIG_SDIO_SUPPORT), y) -+ccflags-y += -DAICWF_SDIO_SUPPORT -+ccflags-$(CONFIG_SDIO_PWRCTRL) += -DCONFIG_SDIO_PWRCTRL -+endif -+ -+ifeq ($(CONFIG_USB_SUPPORT), y) -+ccflags-y += -DAICWF_USB_SUPPORT -+endif -+ -+ifeq ($(CONFIG_BR_SUPPORT), y) -+ccflags-y += -DCONFIG_BR_SUPPORT -+ccflags-y += '-DCONFIG_BR_SUPPORT_BRNAME="'$(BR_NAME)'"' -+endif -+ -+ifeq ($(CONFIG_RWNX_MUMIMO_TX), y) -+ccflags-y += -DCONFIG_USER_MAX=2 -+else -+ccflags-y += -DCONFIG_USER_MAX=1 -+endif -+ -+ifeq ($(CONFIG_RWNX_BCMC), y) -+ccflags-y += -DNX_TXQ_CNT=5 -+else -+ccflags-y += -DNX_TXQ_CNT=4 -+endif -+ -+# For old kernel (<=3.19) -+ifeq ($(shell test $(VERSION) -lt 4 -a "$(CONFIG_VENDOR_RWNX)" = y ; echo $$?),0) -+ccflags-y += -DCONFIG_VENDOR_RWNX_VHT_NO80 -+endif -+ -+ccflags-$(CONFIG_RX_REORDER) += -DAICWF_RX_REORDER -+ccflags-$(CONFIG_ARP_OFFLOAD) += -DAICWF_ARP_OFFLOAD -+ccflags-$(CONFIG_RADAR_DETECT) += -DRADAR_OR_IR_DETECT -+ccflags-$(CONFIG_DOWNLOAD_FW) += -DCONFIG_DOWNLOAD_FW -+ccflags-$(CONFIG_RX_NETIF_RECV_SKB) += -DCONFIG_RX_NETIF_RECV_SKB -+ccflags-$(CONFIG_ONE_TXQ) += -DCONFIG_ONE_TXQ -+ccflags-$(CONFIG_TX_NETIF_FLOWCTRL) += -DCONFIG_TX_NETIF_FLOWCTRL -+ -+ccflags-y += -DAIC_TRACE_INCLUDE_PATH=$(src) -+MAKEFLAGS +=-j$(shell nproc) -+ -+########## Platform support list ########## -+CONFIG_PLATFORM_ROCKCHIP ?= n -+CONFIG_PLATFORM_ROCKCHIP2 ?= n -+CONFIG_PLATFORM_ALLWINNER ?= n -+CONFIG_PLATFORM_INGENIC_T20 ?= n -+CONFIG_PLATFORM_AMLOGIC ?= n -+CONFIG_PLATFORM_UBUNTU ?= y -+ -+ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y) -+ARCH := arm64 -+KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel -+CROSS_COMPILE := /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -+ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP -+ccflags-y += -DANDROID_PLATFORM -+endif -+ -+ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y) -+ARCH := arm64 -+KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel -+CROSS_COMPILE := /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -+ -+ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2 -+ccflags-y += -DANDROID_PLATFORM -+endif -+ -+ -+ifeq ($(CONFIG_PLATFORM_ALLWINNER), y) -+ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER -+ccflags-y += -DANDROID_PLATFORM -+KDIR ?= /home/yaya/E/Allwinner/r818/Android10/lichee/kernel/linux-4.9/ -+ARCH ?= arm64 -+CROSS_COMPILE ?= /home/yaya/E/Allwinner/r818/Android10/android/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android- -+endif -+ -+ifeq ($(CONFIG_PLATFORM_INGENIC_T20), y) -+KDIR ?= /home/yaya/E/T40/kernel -+ARCH ?= mips -+CROSS_COMPILE ?= /home/yaya/E/T40/mips-linux-gnu-ingenic-gcc7.2.0-glibc2.29-fp64/bin/mips-linux-gnu- -+endif -+ -+ifeq ($(CONFIG_PLATFORM_AMLOGIC), y) -+ccflags-$(CONFIG_PLATFORM_AMLOGIC) += -DCONFIG_PLATFORM_AMLOGIC -+ccflags-y += -DANDROID_PLATFORM -+endif -+ -+ifeq ($(CONFIG_PLATFORM_UBUNTU), y) -+KDIR ?= /lib/modules/$(shell uname -r)/build -+PWD ?= $(shell pwd) -+KVER ?= $(shell uname -r) -+MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/ -+ARCH ?= x86_64 -+CROSS_COMPILE ?= -+endif -+########################################### -+ -+ -+all: modules -+modules: -+ make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules -+ -+install: -+ mkdir -p $(MODDESTDIR) -+ install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR) -+ /sbin/depmod -a ${KVER} -+ -+uninstall: -+ rm -rfv $(MODDESTDIR)/$(MODULE_NAME).ko -+ /sbin/depmod -a ${KVER} -+ -+clean: -+ rm -rf *.o *.ko *.o.* *.mod.* modules.* Module.* .a* .o* .*.o.* *.mod .tmp* .cache.mk -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/md5.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/md5.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/md5.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/md5.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,161 @@ -+#include -+#include "md5.h" -+ -+unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -+ -+void MD5Init(MD5_CTX *context) -+{ -+ context->count[0] = 0; -+ context->count[1] = 0; -+ context->state[0] = 0x67452301; -+ context->state[1] = 0xEFCDAB89; -+ context->state[2] = 0x98BADCFE; -+ context->state[3] = 0x10325476; -+} -+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen) -+{ -+ unsigned int i = 0,index = 0,partlen = 0; -+ index = (context->count[0] >> 3) & 0x3F; -+ partlen = 64 - index; -+ context->count[0] += inputlen << 3; -+ if(context->count[0] < (inputlen << 3)) -+ context->count[1]++; -+ context->count[1] += inputlen >> 29; -+ -+ if(inputlen >= partlen) -+ { -+ memcpy(&context->buffer[index],input,partlen); -+ MD5Transform(context->state,context->buffer); -+ for(i = partlen;i+64 <= inputlen;i+=64) -+ MD5Transform(context->state,&input[i]); -+ index = 0; -+ } -+ else -+ { -+ i = 0; -+ } -+ memcpy(&context->buffer[index],&input[i],inputlen-i); -+} -+void MD5Final(MD5_CTX *context,unsigned char digest[16]) -+{ -+ unsigned int index = 0,padlen = 0; -+ unsigned char bits[8]; -+ index = (context->count[0] >> 3) & 0x3F; -+ padlen = (index < 56)?(56-index):(120-index); -+ MD5Encode(bits,context->count,8); -+ MD5Update(context,PADDING,padlen); -+ MD5Update(context,bits,8); -+ MD5Encode(digest,context->state,16); -+} -+void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len) -+{ -+ unsigned int i = 0,j = 0; -+ while(j < len) -+ { -+ output[j] = input[i] & 0xFF; -+ output[j+1] = (input[i] >> 8) & 0xFF; -+ output[j+2] = (input[i] >> 16) & 0xFF; -+ output[j+3] = (input[i] >> 24) & 0xFF; -+ i++; -+ j+=4; -+ } -+} -+void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len) -+{ -+ unsigned int i = 0,j = 0; -+ while(j < len) -+ { -+ output[i] = (input[j]) | -+ (input[j+1] << 8) | -+ (input[j+2] << 16) | -+ (input[j+3] << 24); -+ i++; -+ j+=4; -+ } -+} -+void MD5Transform(unsigned int state[4],unsigned char block[64]) -+{ -+ unsigned int a = state[0]; -+ unsigned int b = state[1]; -+ unsigned int c = state[2]; -+ unsigned int d = state[3]; -+ unsigned int x[64]; -+ MD5Decode(x,block,64); -+ FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */ -+ FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */ -+ FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */ -+ FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */ -+ FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */ -+ FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */ -+ FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */ -+ FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */ -+ FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */ -+ FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */ -+ FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */ -+ FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */ -+ FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */ -+ FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */ -+ FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */ -+ FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */ -+ -+ /* Round 2 */ -+ GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */ -+ GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */ -+ GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */ -+ GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */ -+ GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */ -+ GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */ -+ GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */ -+ GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */ -+ GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */ -+ GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */ -+ GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */ -+ GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */ -+ GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */ -+ GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */ -+ GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */ -+ GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */ -+ -+ /* Round 3 */ -+ HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */ -+ HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */ -+ HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */ -+ HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */ -+ HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */ -+ HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */ -+ HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */ -+ HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */ -+ HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */ -+ HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */ -+ HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */ -+ HH(b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */ -+ HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */ -+ HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */ -+ HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */ -+ HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */ -+ -+ /* Round 4 */ -+ II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */ -+ II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */ -+ II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */ -+ II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */ -+ II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */ -+ II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */ -+ II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */ -+ II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */ -+ II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */ -+ II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */ -+ II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */ -+ II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */ -+ II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */ -+ II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */ -+ II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */ -+ II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */ -+ state[0] += a; -+ state[1] += b; -+ state[2] += c; -+ state[3] += d; -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/md5.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/md5.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/md5.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/md5.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,48 @@ -+#ifndef MD5_H -+#define MD5_H -+ -+typedef struct -+{ -+ unsigned int count[2]; -+ unsigned int state[4]; -+ unsigned char buffer[64]; -+}MD5_CTX; -+ -+ -+#define F(x,y,z) ((x & y) | (~x & z)) -+#define G(x,y,z) ((x & z) | (y & ~z)) -+#define H(x,y,z) (x^y^z) -+#define I(x,y,z) (y ^ (x | ~z)) -+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n))) -+#define FF(a,b,c,d,x,s,ac) \ -+ { \ -+ a += F(b,c,d) + x + ac; \ -+ a = ROTATE_LEFT(a,s); \ -+ a += b; \ -+ } -+#define GG(a,b,c,d,x,s,ac) \ -+ { \ -+ a += G(b,c,d) + x + ac; \ -+ a = ROTATE_LEFT(a,s); \ -+ a += b; \ -+ } -+#define HH(a,b,c,d,x,s,ac) \ -+ { \ -+ a += H(b,c,d) + x + ac; \ -+ a = ROTATE_LEFT(a,s); \ -+ a += b; \ -+ } -+#define II(a,b,c,d,x,s,ac) \ -+ { \ -+ a += I(b,c,d) + x + ac; \ -+ a = ROTATE_LEFT(a,s); \ -+ a += b; \ -+ } -+void MD5Init(MD5_CTX *context); -+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen); -+void MD5Final(MD5_CTX *context,unsigned char digest[16]); -+void MD5Transform(unsigned int state[4],unsigned char block[64]); -+void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len); -+void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len); -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/reg_access.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/reg_access.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/reg_access.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/reg_access.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,148 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file reg_access.h -+ * -+ * @brief Definitions and macros for MAC HW and platform register accesses -+ * -+ * Copyright (C) RivieraWaves 2011-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef REG_ACCESS_H_ -+#define REG_ACCESS_H_ -+ -+/***************************************************************************** -+ * Addresses within RWNX_ADDR_SYSTEM -+ *****************************************************************************/ -+/* Shard RAM */ -+#define SHARED_RAM_START_ADDR 0x00000000 -+ -+/* IPC registers */ -+#define IPC_REG_BASE_ADDR 0x00800000 -+ -+/* System Controller Registers */ -+#define SYSCTRL_SIGNATURE_ADDR 0x00900000 -+// old diag register name -+#define SYSCTRL_DIAG_CONF_ADDR 0x00900068 -+#define SYSCTRL_PHYDIAG_CONF_ADDR 0x00900074 -+#define SYSCTRL_RIUDIAG_CONF_ADDR 0x00900078 -+// new diag register name -+#define SYSCTRL_DIAG_CONF0 0x00900064 -+#define SYSCTRL_DIAG_CONF1 0x00900068 -+#define SYSCTRL_DIAG_CONF2 0x00900074 -+#define SYSCTRL_DIAG_CONF3 0x00900078 -+#define SYSCTRL_MISC_CNTL_ADDR 0x009000E0 -+#define BOOTROM_ENABLE BIT(4) -+#define FPGA_B_RESET BIT(1) -+#define SOFT_RESET BIT(0) -+ -+/* MAC platform */ -+#define NXMAC_VERSION_1_ADDR 0x00B00004 -+#define NXMAC_MU_MIMO_TX_BIT BIT(19) -+#define NXMAC_BFMER_BIT BIT(18) -+#define NXMAC_BFMEE_BIT BIT(17) -+#define NXMAC_MAC_80211MH_FORMAT_BIT BIT(16) -+#define NXMAC_COEX_BIT BIT(14) -+#define NXMAC_WAPI_BIT BIT(13) -+#define NXMAC_TPC_BIT BIT(12) -+#define NXMAC_VHT_BIT BIT(11) -+#define NXMAC_HT_BIT BIT(10) -+#define NXMAC_RCE_BIT BIT(8) -+#define NXMAC_CCMP_BIT BIT(7) -+#define NXMAC_TKIP_BIT BIT(6) -+#define NXMAC_WEP_BIT BIT(5) -+#define NXMAC_SECURITY_BIT BIT(4) -+#define NXMAC_SME_BIT BIT(3) -+#define NXMAC_HCCA_BIT BIT(2) -+#define NXMAC_EDCA_BIT BIT(1) -+#define NXMAC_QOS_BIT BIT(0) -+ -+#define NXMAC_RX_CNTRL_ADDR 0x00B00060 -+#define NXMAC_EN_DUPLICATE_DETECTION_BIT BIT(31) -+#define NXMAC_ACCEPT_UNKNOWN_BIT BIT(30) -+#define NXMAC_ACCEPT_OTHER_DATA_FRAMES_BIT BIT(29) -+#define NXMAC_ACCEPT_QO_S_NULL_BIT BIT(28) -+#define NXMAC_ACCEPT_QCFWO_DATA_BIT BIT(27) -+#define NXMAC_ACCEPT_Q_DATA_BIT BIT(26) -+#define NXMAC_ACCEPT_CFWO_DATA_BIT BIT(25) -+#define NXMAC_ACCEPT_DATA_BIT BIT(24) -+#define NXMAC_ACCEPT_OTHER_CNTRL_FRAMES_BIT BIT(23) -+#define NXMAC_ACCEPT_CF_END_BIT BIT(22) -+#define NXMAC_ACCEPT_ACK_BIT BIT(21) -+#define NXMAC_ACCEPT_CTS_BIT BIT(20) -+#define NXMAC_ACCEPT_RTS_BIT BIT(19) -+#define NXMAC_ACCEPT_PS_POLL_BIT BIT(18) -+#define NXMAC_ACCEPT_BA_BIT BIT(17) -+#define NXMAC_ACCEPT_BAR_BIT BIT(16) -+#define NXMAC_ACCEPT_OTHER_MGMT_FRAMES_BIT BIT(15) -+#define NXMAC_ACCEPT_BFMEE_FRAMES_BIT BIT(14) -+#define NXMAC_ACCEPT_ALL_BEACON_BIT BIT(13) -+#define NXMAC_ACCEPT_NOT_EXPECTED_BA_BIT BIT(12) -+#define NXMAC_ACCEPT_DECRYPT_ERROR_FRAMES_BIT BIT(11) -+#define NXMAC_ACCEPT_BEACON_BIT BIT(10) -+#define NXMAC_ACCEPT_PROBE_RESP_BIT BIT(9) -+#define NXMAC_ACCEPT_PROBE_REQ_BIT BIT(8) -+#define NXMAC_ACCEPT_MY_UNICAST_BIT BIT(7) -+#define NXMAC_ACCEPT_UNICAST_BIT BIT(6) -+#define NXMAC_ACCEPT_ERROR_FRAMES_BIT BIT(5) -+#define NXMAC_ACCEPT_OTHER_BSSID_BIT BIT(4) -+#define NXMAC_ACCEPT_BROADCAST_BIT BIT(3) -+#define NXMAC_ACCEPT_MULTICAST_BIT BIT(2) -+#define NXMAC_DONT_DECRYPT_BIT BIT(1) -+#define NXMAC_EXC_UNENCRYPTED_BIT BIT(0) -+ -+#define NXMAC_DEBUG_PORT_SEL_ADDR 0x00B00510 -+#define NXMAC_SW_SET_PROFILING_ADDR 0x00B08564 -+#define NXMAC_SW_CLEAR_PROFILING_ADDR 0x00B08568 -+ -+/* Modem Status */ -+#define MDM_HDMCONFIG_ADDR 0x00C00000 -+ -+/* Clock gating configuration */ -+#define MDM_MEMCLKCTRL0_ADDR 0x00C00848 -+#define MDM_CLKGATEFCTRL0_ADDR 0x00C00874 -+#define CRM_CLKGATEFCTRL0_ADDR 0x00940010 -+ -+/* AGC (trident) */ -+#define AGC_RWNXAGCCNTL_ADDR 0x00C02060 -+ -+/* LDPC RAM*/ -+#define PHY_LDPC_RAM_ADDR 0x00C09000 -+ -+/* FCU (elma )*/ -+#define FCU_RWNXFCAGCCNTL_ADDR 0x00C09034 -+ -+/* AGC RAM */ -+#define PHY_AGC_UCODE_ADDR 0x00C0A000 -+ -+/* RIU */ -+#define RIU_RWNXVERSION_ADDR 0x00C0B000 -+#define RIU_RWNXDYNAMICCONFIG_ADDR 0x00C0B008 -+#define RIU_AGCMEMBISTSTAT_ADDR 0x00C0B238 -+#define RIU_AGCMEMSIGNATURESTAT_ADDR 0x00C0B23C -+#define RIU_RWNXAGCCNTL_ADDR 0x00C0B390 -+ -+/* FCU RAM */ -+#define PHY_FCU_UCODE_ADDR 0x00C0E000 -+ -+/* RF ITF */ -+#define FPGAB_MPIF_SEL_ADDR 0x00C10030 -+#define RF_V6_DIAGPORT_CONF1_ADDR 0x00C10010 -+#define RF_v6_PHYDIAG_CONF1_ADDR 0x00C10018 -+ -+#define RF_V7_DIAGPORT_CONF1_ADDR 0x00F10010 -+#define RF_v7_PHYDIAG_CONF1_ADDR 0x00F10018 -+ -+/***************************************************************************** -+ * Macros for generated register files -+ *****************************************************************************/ -+/* Macros for IPC registers access (used in reg_ipc_app.h) */ -+#define REG_IPC_APP_RD(env, INDEX) \ -+ (*(volatile u32 *)((u8 *)env + IPC_REG_BASE_ADDR + 4 * (INDEX))) -+ -+#define REG_IPC_APP_WR(env, INDEX, value) \ -+ (*(volatile u32 *)((u8 *)env + IPC_REG_BASE_ADDR + 4 * (INDEX)) = value) -+ -+#endif /* REG_ACCESS_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/regdb.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/regdb.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/regdb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/regdb.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,2898 @@ -+#include -+#include -+#include -+ -+//#include "regdb.h" -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0) -+#define REG_RULE_EXT(start, end, bw, gain, eirp, dfs_cac, reg_flags) \ -+{ \ -+ .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \ -+ .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \ -+ .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \ -+ .power_rule.max_antenna_gain = DBI_TO_MBI(gain),\ -+ .power_rule.max_eirp = DBM_TO_MBM(eirp), \ -+ .flags = reg_flags, \ -+} -+#define NL80211_RRF_AUTO_BW 0 -+#endif -+ -+static const struct ieee80211_regdomain regdom_00 = { -+ .n_reg_rules = 2, -+ .alpha2 = "00", -+ .reg_rules = { -+ // 1...14 -+ REG_RULE(2390 - 10, 2510 + 10, 40, 0, 20, 0), -+ // 36...165 -+ REG_RULE(5150 - 10, 5970 + 10, 80, 0, 20, 0), -+ } -+ -+#if 0 -+ .alpha2 = "00", -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 20, 0, 0), -+ //REG_RULE_EXT(2457, 2482, 40, 0, 20, 0, -+ // NL80211_RRF_NO_IR | 0), -+ REG_RULE_EXT(2474, 2494, 20, 0, 20, 0, -+ NL80211_RRF_NO_IR | -+ NL80211_RRF_NO_OFDM | 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_NO_IR | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_NO_IR | -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 20, 0, -+ NL80211_RRF_NO_IR | -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, -+ NL80211_RRF_NO_IR | 0), -+ }, -+ .n_reg_rules = 6 -+#endif -+}; -+ -+static const struct ieee80211_regdomain regdom_AD = { -+ .alpha2 = "AD", -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5490, 5710, 80, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_AE = { -+ .alpha2 = "AE", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ //REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_AF = { -+ .alpha2 = "AF", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_AI = { -+ .alpha2 = "AI", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_AL = { -+ .alpha2 = "AL", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_AM = { -+ .alpha2 = "AM", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 18, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 18, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 3 -+}; -+ -+static const struct ieee80211_regdomain regdom_AN = { -+ .alpha2 = "AN", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_AR = { -+ .alpha2 = "AR", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ //REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ // NL80211_RRF_AUTO_BW | 0), -+ //REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ // NL80211_RRF_DFS | -+ // NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5270, 5330, 40, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ //REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ // NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5815, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 3 -+}; -+ -+static const struct ieee80211_regdomain regdom_AS = { -+ .alpha2 = "AS", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_AT = { -+ .alpha2 = "AT", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_AU = { -+ .alpha2 = "AU", -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_AW = { -+ .alpha2 = "AW", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_AZ = { -+ .alpha2 = "AZ", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 18, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 18, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ }, -+ .n_reg_rules = 3 -+}; -+ -+static const struct ieee80211_regdomain regdom_BA = { -+ .alpha2 = "BA", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_BB = { -+ .alpha2 = "BB", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_BD = { -+ .alpha2 = "BD", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 2 -+}; -+ -+static const struct ieee80211_regdomain regdom_BE = { -+ .alpha2 = "BE", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_BF = { -+ .alpha2 = "BF", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_BG = { -+ .alpha2 = "BG", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_BH = { -+ .alpha2 = "BH", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_BL = { -+ .alpha2 = "BL", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_BM = { -+ .alpha2 = "BM", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_BN = { -+ .alpha2 = "BN", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_BO = { -+ .alpha2 = "BO", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 30, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 3 -+}; -+ -+static const struct ieee80211_regdomain regdom_BR = { -+ .alpha2 = "BR", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_BS = { -+ .alpha2 = "BS", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_BT = { -+ .alpha2 = "BT", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_BY = { -+ .alpha2 = "BY", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_BZ = { -+ .alpha2 = "BZ", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 2 -+}; -+ -+static const struct ieee80211_regdomain regdom_CA = { -+ .alpha2 = "CA", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_CF = { -+ .alpha2 = "CF", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 40, 0, 17, 0, 0), -+ REG_RULE_EXT(5250, 5330, 40, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5490, 5730, 40, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 40, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_CH = { -+ .alpha2 = "CH", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_CI = { -+ .alpha2 = "CI", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_CL = { -+ .alpha2 = "CL", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_CN = { -+ .alpha2 = "CN", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ REG_RULE_EXT(57240, 59400, 2160, 0, 28, 0, 0), -+ REG_RULE_EXT(59400, 63720, 2160, 0, 44, 0, 0), -+ REG_RULE_EXT(63720, 65880, 2160, 0, 28, 0, 0), -+ }, -+ .n_reg_rules = 7 -+}; -+ -+static const struct ieee80211_regdomain regdom_CO = { -+ .alpha2 = "CO", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_CR = { -+ .alpha2 = "CR", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5490, 5730, 80, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_CX = { -+ .alpha2 = "CX", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_CY = { -+ .alpha2 = "CY", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_CZ = { -+ .alpha2 = "CZ", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, -+ NL80211_RRF_NO_OUTDOOR | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, -+ NL80211_RRF_NO_OUTDOOR | -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_DE = { -+ .alpha2 = "DE", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5150, 5250, 80, 0, 20, 0, -+ NL80211_RRF_NO_OUTDOOR | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, -+ NL80211_RRF_NO_OUTDOOR | -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5470, 5695, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ /*REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0),*/ -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_DK = { -+ .alpha2 = "DK", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_DM = { -+ .alpha2 = "DM", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_DO = { -+ .alpha2 = "DO", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_DZ = { -+ .alpha2 = "DZ", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5670, 160, 0, 23, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_EC = { -+ .alpha2 = "EC", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5490, 5730, 80, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_EE = { -+ .alpha2 = "EE", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_EG = { -+ .alpha2 = "EG", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 3 -+}; -+ -+static const struct ieee80211_regdomain regdom_ES = { -+ .alpha2 = "ES", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, -+ NL80211_RRF_NO_OUTDOOR | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, -+ NL80211_RRF_NO_OUTDOOR | -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_ET = { -+ .alpha2 = "ET", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_FI = { -+ .alpha2 = "FI", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_FM = { -+ .alpha2 = "FM", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_FR = { -+ .alpha2 = "FR", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5695, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_GB = { -+ .alpha2 = "GB", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_GD = { -+ .alpha2 = "GD", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_GE = { -+ .alpha2 = "GE", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 18, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 18, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_GF = { -+ .alpha2 = "GF", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_GH = { -+ .alpha2 = "GH", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_GL = { -+ .alpha2 = "GL", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5490, 5710, 80, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_GP = { -+ .alpha2 = "GP", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_GR = { -+ .alpha2 = "GR", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_GT = { -+ .alpha2 = "GT", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_GU = { -+ .alpha2 = "GU", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5490, 5730, 80, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_GY = { -+ .alpha2 = "GY", -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 2 -+}; -+ -+static const struct ieee80211_regdomain regdom_HK = { -+ .alpha2 = "HK", -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_HN = { -+ .alpha2 = "HN", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_HR = { -+ .alpha2 = "HR", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_HT = { -+ .alpha2 = "HT", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_HU = { -+ .alpha2 = "HU", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_ID = { -+ .alpha2 = "ID", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5735, 5815, 80, 0, 23, 0, 0), -+ }, -+ .n_reg_rules = 2 -+}; -+ -+static const struct ieee80211_regdomain regdom_IE = { -+ .alpha2 = "IE", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_IL = { -+ .alpha2 = "IL", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, -+ NL80211_RRF_NO_OUTDOOR | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, -+ NL80211_RRF_NO_OUTDOOR | -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ }, -+ .n_reg_rules = 3 -+}; -+ -+static const struct ieee80211_regdomain regdom_IN = { -+ .alpha2 = "IN", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_IR = { -+ .alpha2 = "IR", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 2 -+}; -+ -+static const struct ieee80211_regdomain regdom_IS = { -+ .alpha2 = "IS", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_IT = { -+ .alpha2 = "IT", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_JM = { -+ .alpha2 = "JM", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_JO = { -+ .alpha2 = "JO", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 23, 0, 0), -+ }, -+ .n_reg_rules = 3 -+}; -+ -+static const struct ieee80211_regdomain regdom_JP = { -+ .alpha2 = "JP", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(2474, 2494, 20, 0, 20, 0, -+ NL80211_RRF_NO_OFDM | 0), -+ REG_RULE_EXT(4910, 4990, 40, 0, 23, 0, 0), -+ REG_RULE_EXT(5030, 5090, 40, 0, 23, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 23, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 7 -+}; -+ -+static const struct ieee80211_regdomain regdom_KE = { -+ .alpha2 = "KE", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, 0), -+ REG_RULE_EXT(5490, 5570, 80, 0, 30, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5775, 40, 0, 23, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_KH = { -+ .alpha2 = "KH", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_KN = { -+ .alpha2 = "KN", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 30, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5815, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_KP = { -+ .alpha2 = "KP", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5630, 80, 0, 30, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5815, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_KR = { -+ .alpha2 = "KR", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 30, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_KW = { -+ .alpha2 = "KW", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ }, -+ .n_reg_rules = 3 -+}; -+ -+static const struct ieee80211_regdomain regdom_KY = { -+ .alpha2 = "KY", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_KZ = { -+ .alpha2 = "KZ", -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ }, -+ .n_reg_rules = 1 -+}; -+ -+static const struct ieee80211_regdomain regdom_LB = { -+ .alpha2 = "LB", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_LC = { -+ .alpha2 = "LC", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 30, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5815, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_LI = { -+ .alpha2 = "LI", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_LK = { -+ .alpha2 = "LK", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5490, 5730, 80, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_LS = { -+ .alpha2 = "LS", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_LT = { -+ .alpha2 = "LT", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_LU = { -+ .alpha2 = "LU", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_LV = { -+ .alpha2 = "LV", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_MA = { -+ .alpha2 = "MA", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ }, -+ .n_reg_rules = 3 -+}; -+ -+static const struct ieee80211_regdomain regdom_MC = { -+ .alpha2 = "MC", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_MD = { -+ .alpha2 = "MD", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_ME = { -+ .alpha2 = "ME", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_MF = { -+ .alpha2 = "MF", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_MH = { -+ .alpha2 = "MH", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_MK = { -+ .alpha2 = "MK", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_MN = { -+ .alpha2 = "MN", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_MO = { -+ .alpha2 = "MO", -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 40, 0, 23, 0, 0), -+ REG_RULE_EXT(5250, 5330, 40, 0, 23, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 40, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_MP = { -+ .alpha2 = "MP", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_MQ = { -+ .alpha2 = "MQ", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_MR = { -+ .alpha2 = "MR", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_MT = { -+ .alpha2 = "MT", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_MU = { -+ .alpha2 = "MU", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_MW = { -+ .alpha2 = "MW", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_MX = { -+ .alpha2 = "MX", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_MY = { -+ .alpha2 = "MY", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_NI = { -+ .alpha2 = "NI", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_NL = { -+ .alpha2 = "NL", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_NO_OUTDOOR | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_NO_OUTDOOR | -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_NO = { -+ .alpha2 = "NO", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5470, 5795, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5815, 5850, 35, 0, 33, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(17100, 17300, 200, 0, 20, 0, 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 7 -+}; -+ -+static const struct ieee80211_regdomain regdom_NP = { -+ .alpha2 = "NP", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_NZ = { -+ .alpha2 = "NZ", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_OM = { -+ .alpha2 = "OM", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_PA = { -+ .alpha2 = "PA", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_PE = { -+ .alpha2 = "PE", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_PF = { -+ .alpha2 = "PF", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_PG = { -+ .alpha2 = "PG", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_PH = { -+ .alpha2 = "PH", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_PK = { -+ .alpha2 = "PK", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 2 -+}; -+ -+static const struct ieee80211_regdomain regdom_PL = { -+ .alpha2 = "PL", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_PM = { -+ .alpha2 = "PM", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_PR = { -+ .alpha2 = "PR", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_PT = { -+ .alpha2 = "PT", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_PW = { -+ .alpha2 = "PW", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_PY = { -+ .alpha2 = "PY", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_QA = { -+ .alpha2 = "QA", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 2 -+}; -+ -+static const struct ieee80211_regdomain regdom_RE = { -+ .alpha2 = "RE", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_RO = { -+ .alpha2 = "RO", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_RS = { -+ .alpha2 = "RS", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5150, 5350, 40, 0, 23, 0, -+ NL80211_RRF_NO_OUTDOOR | 0), -+ REG_RULE_EXT(5470, 5725, 20, 0, 30, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_RU = { -+ .alpha2 = "RU", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5650, 5730, 80, 0, 30, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_RW = { -+ .alpha2 = "RW", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_SA = { -+ .alpha2 = "SA", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_SE = { -+ .alpha2 = "SE", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_SG = { -+ .alpha2 = "SG", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_SI = { -+ .alpha2 = "SI", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_SK = { -+ .alpha2 = "SK", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_SN = { -+ .alpha2 = "SN", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_SR = { -+ .alpha2 = "SR", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_SV = { -+ .alpha2 = "SV", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_SY = { -+ .alpha2 = "SY", -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ }, -+ .n_reg_rules = 1 -+}; -+ -+static const struct ieee80211_regdomain regdom_TC = { -+ .alpha2 = "TC", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_TD = { -+ .alpha2 = "TD", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_TG = { -+ .alpha2 = "TG", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5250, 5330, 40, 0, 20, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5490, 5710, 40, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_TH = { -+ .alpha2 = "TH", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_TN = { -+ .alpha2 = "TN", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ }, -+ .n_reg_rules = 3 -+}; -+ -+static const struct ieee80211_regdomain regdom_TR = { -+ .alpha2 = "TR", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_TT = { -+ .alpha2 = "TT", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_TW = { -+ .alpha2 = "TW", -+ .dfs_region = NL80211_DFS_JP, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5270, 5330, 40, 0, 17, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5490, 5590, 80, 0, 30, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5650, 5710, 40, 0, 30, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_UA = { -+ .alpha2 = "UA", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, -+ NL80211_RRF_NO_OUTDOOR | 0), -+ REG_RULE_EXT(5150, 5350, 40, 0, 20, 0, -+ NL80211_RRF_NO_OUTDOOR | 0), -+ REG_RULE_EXT(5490, 5670, 80, 0, 20, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), -+ REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_UG = { -+ .alpha2 = "UG", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_US = { -+ .alpha2 = "US", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ // 1...13 -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ // 36 40 44 48 -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ // 52 56 60 64 -+ REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ // 100 104 108 112 116 120 124 -+ REG_RULE_EXT(5490, 5650, 80, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ // 128 132 136 140 -+ REG_RULE_EXT(5650, 5710, 40, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ // 149 153 157 161 165 -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ REG_RULE_EXT(57240, 63720, 2160, 0, 40, 0, 0), -+ }, -+ .n_reg_rules = 7 -+}; -+ -+static const struct ieee80211_regdomain regdom_UY = { -+ .alpha2 = "UY", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_UZ = { -+ .alpha2 = "UZ", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ }, -+ .n_reg_rules = 3 -+}; -+ -+static const struct ieee80211_regdomain regdom_VC = { -+ .alpha2 = "VC", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_VE = { -+ .alpha2 = "VE", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_VI = { -+ .alpha2 = "VI", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_VN = { -+ .alpha2 = "VN", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5490, 5730, 80, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_VU = { -+ .alpha2 = "VU", -+ .dfs_region = NL80211_DFS_FCC, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, -+ NL80211_RRF_DFS | 0), -+ REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), -+ }, -+ .n_reg_rules = 5 -+}; -+ -+static const struct ieee80211_regdomain regdom_WF = { -+ .alpha2 = "WF", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_YE = { -+ .alpha2 = "YE", -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ }, -+ .n_reg_rules = 1 -+}; -+ -+static const struct ieee80211_regdomain regdom_YT = { -+ .alpha2 = "YT", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_ZA = { -+ .alpha2 = "ZA", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5695, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ /*REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0),*/ -+ }, -+ .n_reg_rules = 4 -+}; -+ -+static const struct ieee80211_regdomain regdom_ZW = { -+ .alpha2 = "ZW", -+ .dfs_region = NL80211_DFS_ETSI, -+ .reg_rules = { -+ REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), -+ REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, -+ NL80211_RRF_DFS | -+ NL80211_RRF_AUTO_BW | 0), -+ REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, -+ NL80211_RRF_DFS | 0), -+ }, -+ .n_reg_rules = 4 -+}; -+ -+const struct ieee80211_regdomain *reg_regdb[] = { -+ ®dom_00, -+ ®dom_AD, -+ ®dom_AE, -+ ®dom_AF, -+ ®dom_AI, -+ ®dom_AL, -+ ®dom_AM, -+ ®dom_AN, -+ ®dom_AR, -+ ®dom_AS, -+ ®dom_AT, -+ ®dom_AU, -+ ®dom_AW, -+ ®dom_AZ, -+ ®dom_BA, -+ ®dom_BB, -+ ®dom_BD, -+ ®dom_BE, -+ ®dom_BF, -+ ®dom_BG, -+ ®dom_BH, -+ ®dom_BL, -+ ®dom_BM, -+ ®dom_BN, -+ ®dom_BO, -+ ®dom_BR, -+ ®dom_BS, -+ ®dom_BT, -+ ®dom_BY, -+ ®dom_BZ, -+ ®dom_CA, -+ ®dom_CF, -+ ®dom_CH, -+ ®dom_CI, -+ ®dom_CL, -+ ®dom_CN, -+ ®dom_CO, -+ ®dom_CR, -+ ®dom_CX, -+ ®dom_CY, -+ ®dom_CZ, -+ ®dom_DE, -+ ®dom_DK, -+ ®dom_DM, -+ ®dom_DO, -+ ®dom_DZ, -+ ®dom_EC, -+ ®dom_EE, -+ ®dom_EG, -+ ®dom_ES, -+ ®dom_ET, -+ ®dom_FI, -+ ®dom_FM, -+ ®dom_FR, -+ ®dom_GB, -+ ®dom_GD, -+ ®dom_GE, -+ ®dom_GF, -+ ®dom_GH, -+ ®dom_GL, -+ ®dom_GP, -+ ®dom_GR, -+ ®dom_GT, -+ ®dom_GU, -+ ®dom_GY, -+ ®dom_HK, -+ ®dom_HN, -+ ®dom_HR, -+ ®dom_HT, -+ ®dom_HU, -+ ®dom_ID, -+ ®dom_IE, -+ ®dom_IL, -+ ®dom_IN, -+ ®dom_IR, -+ ®dom_IS, -+ ®dom_IT, -+ ®dom_JM, -+ ®dom_JO, -+ ®dom_JP, -+ ®dom_KE, -+ ®dom_KH, -+ ®dom_KN, -+ ®dom_KP, -+ ®dom_KR, -+ ®dom_KW, -+ ®dom_KY, -+ ®dom_KZ, -+ ®dom_LB, -+ ®dom_LC, -+ ®dom_LI, -+ ®dom_LK, -+ ®dom_LS, -+ ®dom_LT, -+ ®dom_LU, -+ ®dom_LV, -+ ®dom_MA, -+ ®dom_MC, -+ ®dom_MD, -+ ®dom_ME, -+ ®dom_MF, -+ ®dom_MH, -+ ®dom_MK, -+ ®dom_MN, -+ ®dom_MO, -+ ®dom_MP, -+ ®dom_MQ, -+ ®dom_MR, -+ ®dom_MT, -+ ®dom_MU, -+ ®dom_MW, -+ ®dom_MX, -+ ®dom_MY, -+ ®dom_NI, -+ ®dom_NL, -+ ®dom_NO, -+ ®dom_NP, -+ ®dom_NZ, -+ ®dom_OM, -+ ®dom_PA, -+ ®dom_PE, -+ ®dom_PF, -+ ®dom_PG, -+ ®dom_PH, -+ ®dom_PK, -+ ®dom_PL, -+ ®dom_PM, -+ ®dom_PR, -+ ®dom_PT, -+ ®dom_PW, -+ ®dom_PY, -+ ®dom_QA, -+ ®dom_RE, -+ ®dom_RO, -+ ®dom_RS, -+ ®dom_RU, -+ ®dom_RW, -+ ®dom_SA, -+ ®dom_SE, -+ ®dom_SG, -+ ®dom_SI, -+ ®dom_SK, -+ ®dom_SN, -+ ®dom_SR, -+ ®dom_SV, -+ ®dom_SY, -+ ®dom_TC, -+ ®dom_TD, -+ ®dom_TG, -+ ®dom_TH, -+ ®dom_TN, -+ ®dom_TR, -+ ®dom_TT, -+ ®dom_TW, -+ ®dom_UA, -+ ®dom_UG, -+ ®dom_US, -+ ®dom_UY, -+ ®dom_UZ, -+ ®dom_VC, -+ ®dom_VE, -+ ®dom_VI, -+ ®dom_VN, -+ ®dom_VU, -+ ®dom_WF, -+ ®dom_YE, -+ ®dom_YT, -+ ®dom_ZA, -+ ®dom_ZW, -+}; -+ -+int reg_regdb_size = ARRAY_SIZE(reg_regdb); -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_bfmer.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_bfmer.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_bfmer.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_bfmer.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,105 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_bfmer.c -+ * -+ * @brief VHT Beamformer function definitions -+ * -+ * Copyright (C) RivieraWaves 2016-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+/** -+ * INCLUDE FILES -+ ****************************************************************************** -+ */ -+ -+#include -+#include "rwnx_bfmer.h" -+ -+/** -+ * FUNCTION DEFINITIONS -+ ****************************************************************************** -+ */ -+ -+int rwnx_bfmer_report_add(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta, -+ unsigned int length) -+{ -+ gfp_t flags; -+ struct rwnx_bfmer_report *bfm_report ; -+ -+ if (in_softirq()) -+ flags = GFP_ATOMIC; -+ else -+ flags = GFP_KERNEL; -+ -+ /* Allocate a structure that will contain the beamforming report */ -+ bfm_report = kmalloc(sizeof(*bfm_report) + length, flags); -+ -+ -+ /* Check report allocation */ -+ if (!bfm_report) { -+ /* Do not use beamforming */ -+ return -1; -+ } -+ -+ /* Store report length */ -+ bfm_report->length = length; -+ -+ /* -+ * Need to provide a Virtual Address to the MAC so that it can -+ * upload the received Beamforming Report in driver memory -+ */ -+ bfm_report->dma_addr = dma_map_single(rwnx_hw->dev, &bfm_report->report[0], -+ length, DMA_FROM_DEVICE); -+ -+ /* Check DMA mapping result */ -+ if (dma_mapping_error(rwnx_hw->dev, bfm_report->dma_addr)) { -+ /* Free allocated report */ -+ kfree(bfm_report); -+ /* And leave */ -+ return -1; -+ } -+ -+ /* Store report structure */ -+ rwnx_sta->bfm_report = bfm_report; -+ -+ return 0; -+} -+ -+void rwnx_bfmer_report_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta) -+{ -+ /* Verify if a report has been allocated */ -+ if (rwnx_sta->bfm_report) { -+ struct rwnx_bfmer_report *bfm_report = rwnx_sta->bfm_report; -+ -+ /* Unmap DMA region */ -+ dma_unmap_single(rwnx_hw->dev, bfm_report->dma_addr, -+ bfm_report->length, DMA_BIDIRECTIONAL); -+ -+ /* Free allocated report structure and clean the pointer */ -+ kfree(bfm_report); -+ rwnx_sta->bfm_report = NULL; -+ } -+} -+ -+#ifdef CONFIG_RWNX_FULLMAC -+u8 rwnx_bfmer_get_rx_nss(const struct ieee80211_vht_cap *vht_capa) -+{ -+ int i; -+ u8 rx_nss = 0; -+ u16 rx_mcs_map = le16_to_cpu(vht_capa->supp_mcs.rx_mcs_map); -+ -+ for (i = 7; i >= 0; i--) { -+ u8 mcs = (rx_mcs_map >> (2 * i)) & 3; -+ -+ if (mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED) { -+ rx_nss = i + 1; -+ break; -+ } -+ } -+ -+ return rx_nss; -+} -+#endif /* CONFIG_RWNX_FULLMAC */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_bfmer.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_bfmer.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_bfmer.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_bfmer.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,100 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_bfmer.h -+ * -+ * @brief VHT Beamformer function declarations -+ * -+ * Copyright (C) RivieraWaves 2016-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _RWNX_BFMER_H_ -+#define _RWNX_BFMER_H_ -+ -+/** -+ * INCLUDE FILES -+ ****************************************************************************** -+ */ -+ -+#include "rwnx_defs.h" -+ -+/** -+ * DEFINES -+ ****************************************************************************** -+ */ -+ -+/// Maximal supported report length (in bytes) -+#define RWNX_BFMER_REPORT_MAX_LEN 2048 -+ -+/// Size of the allocated report space (twice the maximum report length) -+#define RWNX_BFMER_REPORT_SPACE_SIZE (RWNX_BFMER_REPORT_MAX_LEN * 2) -+ -+/** -+ * TYPE DEFINITIONS -+ ****************************************************************************** -+ */ -+ -+/* -+ * Structure used to store a beamforming report. -+ */ -+struct rwnx_bfmer_report { -+ dma_addr_t dma_addr; /* Virtual address provided to MAC for -+ DMA transfer of the Beamforming Report */ -+ unsigned int length; /* Report Length */ -+ u8 report[1]; /* Report to be used for VHT TX Beamforming */ -+}; -+ -+/** -+ * FUNCTION DECLARATIONS -+ ****************************************************************************** -+ */ -+ -+/** -+ ****************************************************************************** -+ * @brief Allocate memory aiming to contains the Beamforming Report received -+ * from a Beamformee capable capable. -+ * The providing length shall be large enough to contain the VHT Compressed -+ * Beaforming Report and the MU Exclusive part. -+ * It also perform a DMA Mapping providing an address to be provided to the HW -+ * responsible for the DMA transfer of the report. -+ * If successful a struct rwnx_bfmer_report object is allocated, it's address -+ * is stored in rwnx_sta->bfm_report. -+ * -+ * @param[in] rwnx_hw PHY Information -+ * @param[in] rwnx_sta Peer STA Information -+ * @param[in] length Memory size to be allocated -+ * -+ * @return 0 if operation is successful, else -1. -+ ****************************************************************************** -+ */ -+int rwnx_bfmer_report_add(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta, -+ unsigned int length); -+ -+/** -+ ****************************************************************************** -+ * @brief Free a previously allocated memory intended to be used for -+ * Beamforming Reports. -+ * -+ * @param[in] rwnx_hw PHY Information -+ * @param[in] rwnx_sta Peer STA Information -+ * -+ ****************************************************************************** -+ */ -+void rwnx_bfmer_report_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+/** -+ ****************************************************************************** -+ * @brief Parse a Rx VHT-MCS map in order to deduce the maximum number of -+ * Spatial Streams supported by a beamformee. -+ * -+ * @param[in] vht_capa Received VHT Capability field. -+ * -+ ****************************************************************************** -+ */ -+u8 rwnx_bfmer_get_rx_nss(const struct ieee80211_vht_cap *vht_capa); -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+#endif /* _RWNX_BFMER_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cfgfile.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cfgfile.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cfgfile.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cfgfile.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,239 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_configparse.c -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ **************************************************************************************** -+ */ -+#include -+#include -+ -+#include "rwnx_defs.h" -+#include "rwnx_cfgfile.h" -+ -+/** -+ * -+ */ -+static const char *rwnx_find_tag(const u8 *file_data, unsigned int file_size, -+ const char *tag_name, unsigned int tag_len) -+{ -+ unsigned int curr, line_start = 0, line_size; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Walk through all the lines of the configuration file */ -+ while (line_start < file_size) { -+ /* Search the end of the current line (or the end of the file) */ -+ for (curr = line_start; curr < file_size; curr++) -+ if (file_data[curr] == '\n') -+ break; -+ -+ /* Compute the line size */ -+ line_size = curr - line_start; -+ -+ /* Check if this line contains the expected tag */ -+ if ((line_size == (strlen(tag_name) + tag_len)) && -+ (!strncmp(&file_data[line_start], tag_name, strlen(tag_name)))) -+ return &file_data[line_start + strlen(tag_name)]; -+ -+ /* Move to next line */ -+ line_start = curr + 1; -+ } -+ -+ /* Tag not found */ -+ return NULL; -+} -+ -+/** -+ * Parse the Config file used at init time -+ */ -+int rwnx_parse_configfile(struct rwnx_hw *rwnx_hw, const char *filename, -+ struct rwnx_conf_file *config) -+{ -+ const struct firmware *config_fw; -+ u8 dflt_mac[ETH_ALEN] = { 0, 111, 111, 111, 111, 0 }; -+ int ret; -+ const u8 *tag_ptr; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ ret = request_firmware(&config_fw, filename, rwnx_hw->dev); -+ if (ret) { -+ printk(KERN_CRIT "%s: Failed to get %s (%d)\n", __func__, filename, ret); -+ return ret; -+ } -+ -+ /* Get MAC Address */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "MAC_ADDR=", strlen("00:00:00:00:00:00")); -+ if (tag_ptr != NULL) { -+ u8 *addr = config->mac_addr; -+ if (sscanf(tag_ptr, -+ "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", -+ addr + 0, addr + 1, addr + 2, -+ addr + 3, addr + 4, addr + 5) != ETH_ALEN) -+ memcpy(config->mac_addr, dflt_mac, ETH_ALEN); -+ } else -+ memcpy(config->mac_addr, dflt_mac, ETH_ALEN); -+ -+ RWNX_DBG("MAC Address is:\n%pM\n", config->mac_addr); -+ -+ /* Release the configuration file */ -+ release_firmware(config_fw); -+ -+ return 0; -+} -+ -+/** -+ * Parse the Config file used at init time -+ */ -+int rwnx_parse_phy_configfile(struct rwnx_hw *rwnx_hw, const char *filename, -+ struct rwnx_phy_conf_file *config, int path) -+{ -+ const struct firmware *config_fw; -+ int ret; -+ const u8 *tag_ptr; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ ret = request_firmware(&config_fw, filename, rwnx_hw->dev); -+ if (ret) { -+ printk(KERN_CRIT "%s: Failed to get %s (%d)\n", __func__, filename, ret); -+ return ret; -+ } -+ -+ /* Get Trident path mapping */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "TRD_PATH_MAPPING=", strlen("00")); -+ if (tag_ptr != NULL) { -+ u8 val; -+ if (sscanf(tag_ptr, "%hhx", &val) == 1) -+ config->trd.path_mapping = val; -+ else -+ config->trd.path_mapping = path; -+ } else -+ config->trd.path_mapping = path; -+ -+ RWNX_DBG("Trident path mapping is: %d\n", config->trd.path_mapping); -+ -+ /* Get DC offset compensation */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "TX_DC_OFF_COMP=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->trd.tx_dc_off_comp) != 1) -+ config->trd.tx_dc_off_comp = 0; -+ } else -+ config->trd.tx_dc_off_comp = 0; -+ -+ RWNX_DBG("TX DC offset compensation is: %08X\n", config->trd.tx_dc_off_comp); -+ -+ /* Get Karst TX IQ compensation value for path0 on 2.4GHz */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "KARST_TX_IQ_COMP_2_4G_PATH_0=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[0]) != 1) -+ config->karst.tx_iq_comp_2_4G[0] = 0x01000000; -+ } else -+ config->karst.tx_iq_comp_2_4G[0] = 0x01000000; -+ -+ RWNX_DBG("Karst TX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[0]); -+ -+ /* Get Karst TX IQ compensation value for path1 on 2.4GHz */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "KARST_TX_IQ_COMP_2_4G_PATH_1=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[1]) != 1) -+ config->karst.tx_iq_comp_2_4G[1] = 0x01000000; -+ } else -+ config->karst.tx_iq_comp_2_4G[1] = 0x01000000; -+ -+ RWNX_DBG("Karst TX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[1]); -+ -+ /* Get Karst RX IQ compensation value for path0 on 2.4GHz */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "KARST_RX_IQ_COMP_2_4G_PATH_0=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[0]) != 1) -+ config->karst.rx_iq_comp_2_4G[0] = 0x01000000; -+ } else -+ config->karst.rx_iq_comp_2_4G[0] = 0x01000000; -+ -+ RWNX_DBG("Karst RX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[0]); -+ -+ /* Get Karst RX IQ compensation value for path1 on 2.4GHz */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "KARST_RX_IQ_COMP_2_4G_PATH_1=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[1]) != 1) -+ config->karst.rx_iq_comp_2_4G[1] = 0x01000000; -+ } else -+ config->karst.rx_iq_comp_2_4G[1] = 0x01000000; -+ -+ RWNX_DBG("Karst RX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[1]); -+ -+ /* Get Karst TX IQ compensation value for path0 on 5GHz */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "KARST_TX_IQ_COMP_5G_PATH_0=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[0]) != 1) -+ config->karst.tx_iq_comp_5G[0] = 0x01000000; -+ } else -+ config->karst.tx_iq_comp_5G[0] = 0x01000000; -+ -+ RWNX_DBG("Karst TX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[0]); -+ -+ /* Get Karst TX IQ compensation value for path1 on 5GHz */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "KARST_TX_IQ_COMP_5G_PATH_1=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[1]) != 1) -+ config->karst.tx_iq_comp_5G[1] = 0x01000000; -+ } else -+ config->karst.tx_iq_comp_5G[1] = 0x01000000; -+ -+ RWNX_DBG("Karst TX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[1]); -+ -+ /* Get Karst RX IQ compensation value for path0 on 5GHz */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "KARST_RX_IQ_COMP_5G_PATH_0=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[0]) != 1) -+ config->karst.rx_iq_comp_5G[0] = 0x01000000; -+ } else -+ config->karst.rx_iq_comp_5G[0] = 0x01000000; -+ -+ RWNX_DBG("Karst RX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[0]); -+ -+ /* Get Karst RX IQ compensation value for path1 on 5GHz */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "KARST_RX_IQ_COMP_5G_PATH_1=", strlen("00000000")); -+ if (tag_ptr != NULL) { -+ if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[1]) != 1) -+ config->karst.rx_iq_comp_5G[1] = 0x01000000; -+ } else -+ config->karst.rx_iq_comp_5G[1] = 0x01000000; -+ -+ RWNX_DBG("Karst RX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[1]); -+ -+ /* Get Karst default path */ -+ tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size, -+ "KARST_DEFAULT_PATH=", strlen("00")); -+ if (tag_ptr != NULL) { -+ u8 val; -+ if (sscanf(tag_ptr, "%hhx", &val) == 1) -+ config->karst.path_used = val; -+ else -+ config->karst.path_used = path; -+ } else -+ config->karst.path_used = path; -+ -+ RWNX_DBG("Karst default path is: %d\n", config->karst.path_used); -+ -+ /* Release the configuration file */ -+ release_firmware(config_fw); -+ -+ return 0; -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cfgfile.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cfgfile.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cfgfile.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cfgfile.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,35 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_cfgfile.h -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _RWNX_CFGFILE_H_ -+#define _RWNX_CFGFILE_H_ -+ -+/* -+ * Structure used to retrieve information from the Config file used at Initialization time -+ */ -+struct rwnx_conf_file { -+ u8 mac_addr[ETH_ALEN]; -+}; -+ -+/* -+ * Structure used to retrieve information from the PHY Config file used at Initialization time -+ */ -+struct rwnx_phy_conf_file { -+ struct phy_trd_cfg_tag trd; -+ struct phy_karst_cfg_tag karst; -+}; -+ -+int rwnx_parse_configfile(struct rwnx_hw *rwnx_hw, const char *filename, -+ struct rwnx_conf_file *config); -+ -+int rwnx_parse_phy_configfile(struct rwnx_hw *rwnx_hw, const char *filename, -+ struct rwnx_phy_conf_file *config, int path); -+ -+#endif /* _RWNX_CFGFILE_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cmds.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cmds.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cmds.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cmds.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,539 @@ -+/** -+ ****************************************************************************** -+ * -+ * rwnx_cmds.c -+ * -+ * Handles queueing (push to IPC, ack/cfm from IPC) of commands issued to -+ * LMAC FW -+ * -+ * Copyright (C) RivieraWaves 2014-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#include -+ -+#include "rwnx_cmds.h" -+#include "rwnx_defs.h" -+#include "rwnx_strs.h" -+//#define CREATE_TRACE_POINTS -+#include "rwnx_events.h" -+#include "aicwf_txrxif.h" -+#ifdef AICWF_SDIO_SUPPORT -+#include "aicwf_sdio.h" -+#else -+#include "aicwf_usb.h" -+#endif -+/** -+ * -+ */ -+extern int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val); -+ -+void rwnx_cmd_free(struct rwnx_cmd *cmd); -+ -+static void cmd_dump(const struct rwnx_cmd *cmd) -+{ -+ printk(KERN_CRIT "tkn[%d] flags:%04x result:%3d cmd:%4d-%-24s - reqcfm(%4d-%-s)\n", -+ cmd->tkn, cmd->flags, cmd->result, cmd->id, RWNX_ID2STR(cmd->id), -+ cmd->reqid, cmd->reqid != (lmac_msg_id_t)-1 ? RWNX_ID2STR(cmd->reqid) : "none"); -+} -+ -+/** -+ * -+ */ -+static void cmd_complete(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) -+{ -+ //RWNX_DBG(RWNX_FN_ENTRY_STR); -+ lockdep_assert_held(&cmd_mgr->lock); -+ -+ list_del(&cmd->list); -+ cmd_mgr->queue_sz--; -+ -+ cmd->flags |= RWNX_CMD_FLAG_DONE; -+ if (cmd->flags & RWNX_CMD_FLAG_NONBLOCK) { -+ rwnx_cmd_free(cmd);//kfree(cmd); -+ } else { -+ if (RWNX_CMD_WAIT_COMPLETE(cmd->flags)) { -+ cmd->result = 0; -+ complete(&cmd->complete); -+ } -+ } -+} -+ -+int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) -+{ -+ bool defer_push = false; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+#ifdef CREATE_TRACE_POINTS -+ trace_msg_send(cmd->id); -+#endif -+ spin_lock_bh(&cmd_mgr->lock); -+ -+ if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) { -+ printk(KERN_CRIT"cmd queue crashed\n"); -+ cmd->result = -EPIPE; -+ spin_unlock_bh(&cmd_mgr->lock); -+ return -EPIPE; -+ } -+ -+ #ifndef CONFIG_RWNX_FHOST -+ if (!list_empty(&cmd_mgr->cmds)) { -+ if (cmd_mgr->queue_sz == cmd_mgr->max_queue_sz) { -+ printk(KERN_CRIT"Too many cmds (%d) already queued\n", -+ cmd_mgr->max_queue_sz); -+ cmd->result = -ENOMEM; -+ spin_unlock_bh(&cmd_mgr->lock); -+ return -ENOMEM; -+ } -+ } -+ #endif -+ -+ cmd->flags |= RWNX_CMD_FLAG_WAIT_PUSH; -+ defer_push = true; -+ -+ if (cmd->flags & RWNX_CMD_FLAG_REQ_CFM) -+ cmd->flags |= RWNX_CMD_FLAG_WAIT_CFM; -+ -+ cmd->tkn = cmd_mgr->next_tkn++; -+ cmd->result = -EINTR; -+ -+ if (!(cmd->flags & RWNX_CMD_FLAG_NONBLOCK)) -+ init_completion(&cmd->complete); -+ -+ list_add_tail(&cmd->list, &cmd_mgr->cmds); -+ cmd_mgr->queue_sz++; -+ spin_unlock_bh(&cmd_mgr->lock); -+ -+ WAKE_CMD_WORK(cmd_mgr); -+ return 0; -+} -+ -+static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) -+{ -+#ifdef AICWF_SDIO_SUPPORT -+ int ret; -+ struct aic_sdio_dev *sdiodev = container_of(cmd_mgr, struct aic_sdio_dev, cmd_mgr); -+#endif -+#ifdef AICWF_USB_SUPPORT -+ struct aic_usb_dev *usbdev = container_of(cmd_mgr, struct aic_usb_dev, cmd_mgr); -+#endif -+ bool defer_push = false; -+ -+ //RWNX_DBG(RWNX_FN_ENTRY_STR); -+#ifdef CREATE_TRACE_POINTS -+ trace_msg_send(cmd->id); -+#endif -+ spin_lock_bh(&cmd_mgr->lock); -+ -+ if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) { -+ printk(KERN_CRIT"cmd queue crashed\n"); -+ cmd->result = -EPIPE; -+ spin_unlock_bh(&cmd_mgr->lock); -+ return -EPIPE; -+ } -+ -+ #ifndef CONFIG_RWNX_FHOST -+ if (!list_empty(&cmd_mgr->cmds)) { -+ struct rwnx_cmd *last; -+ -+ if (cmd_mgr->queue_sz == cmd_mgr->max_queue_sz) { -+ printk(KERN_CRIT"Too many cmds (%d) already queued\n", -+ cmd_mgr->max_queue_sz); -+ cmd->result = -ENOMEM; -+ spin_unlock_bh(&cmd_mgr->lock); -+ return -ENOMEM; -+ } -+ last = list_entry(cmd_mgr->cmds.prev, struct rwnx_cmd, list); -+ if (last->flags & (RWNX_CMD_FLAG_WAIT_ACK | RWNX_CMD_FLAG_WAIT_PUSH | RWNX_CMD_FLAG_WAIT_CFM)) { -+#if 0 // queue even NONBLOCK command. -+ if (cmd->flags & RWNX_CMD_FLAG_NONBLOCK) { -+ printk(KERN_CRIT"cmd queue busy\n"); -+ cmd->result = -EBUSY; -+ spin_unlock_bh(&cmd_mgr->lock); -+ return -EBUSY; -+ } -+#endif -+ cmd->flags |= RWNX_CMD_FLAG_WAIT_PUSH; -+ defer_push = true; -+ } -+ } -+ #endif -+ -+#if 0 -+ cmd->flags |= RWNX_CMD_FLAG_WAIT_ACK; -+#endif -+ if (cmd->flags & RWNX_CMD_FLAG_REQ_CFM) -+ cmd->flags |= RWNX_CMD_FLAG_WAIT_CFM; -+ -+ cmd->tkn = cmd_mgr->next_tkn++; -+ cmd->result = -EINTR; -+ -+ if (!(cmd->flags & RWNX_CMD_FLAG_NONBLOCK)) -+ init_completion(&cmd->complete); -+ -+ list_add_tail(&cmd->list, &cmd_mgr->cmds); -+ cmd_mgr->queue_sz++; -+ -+ if (cmd->a2e_msg->id == ME_TRAFFIC_IND_REQ -+ #ifdef AICWF_ARP_OFFLOAD -+ || cmd->a2e_msg->id == MM_SET_ARPOFFLOAD_REQ -+ #endif -+ ) { -+ defer_push = true; -+ cmd->flags |= RWNX_CMD_FLAG_WAIT_PUSH; -+ //printk("defer push: tkn=%d\r\n", cmd->tkn); -+ } -+ -+ spin_unlock_bh(&cmd_mgr->lock); -+ if (!defer_push) { -+ //printk("queue:id=%x, param_len=%u\n",cmd->a2e_msg->id, cmd->a2e_msg->param_len); -+ #ifdef AICWF_SDIO_SUPPORT -+ aicwf_set_cmd_tx((void *)(sdiodev), cmd->a2e_msg, sizeof(struct lmac_msg) + cmd->a2e_msg->param_len); -+ #else -+ aicwf_set_cmd_tx((void *)(usbdev), cmd->a2e_msg, sizeof(struct lmac_msg) + cmd->a2e_msg->param_len); -+ #endif -+ //rwnx_ipc_msg_push(rwnx_hw, cmd, RWNX_CMD_A2EMSG_LEN(cmd->a2e_msg)); -+ -+ kfree(cmd->a2e_msg); -+ } else { -+ if(cmd_mgr->queue_sz <= 1){ -+ WAKE_CMD_WORK(cmd_mgr); -+ } -+ return 0; -+ } -+ -+ if (!(cmd->flags & RWNX_CMD_FLAG_NONBLOCK)) { -+ #ifdef CONFIG_RWNX_FHOST -+ if (wait_for_completion_killable(&cmd->complete)) { -+ cmd->result = -EINTR; -+ spin_lock_bh(&cmd_mgr->lock); -+ cmd_complete(cmd_mgr, cmd); -+ spin_unlock_bh(&cmd_mgr->lock); -+ /* TODO: kill the cmd at fw level */ -+ } -+ #else -+ unsigned long tout = msecs_to_jiffies(RWNX_80211_CMD_TIMEOUT_MS * cmd_mgr->queue_sz); -+ if (!wait_for_completion_timeout(&cmd->complete, tout)) { -+ printk(KERN_CRIT"cmd timed-out\n"); -+ #ifdef AICWF_SDIO_SUPPORT -+ ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.wakeup_reg, 2); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!\n", sdiodev->sdio_reg.wakeup_reg); -+ } -+ #endif -+ -+ cmd_dump(cmd); -+ spin_lock_bh(&cmd_mgr->lock); -+ cmd_mgr->state = RWNX_CMD_MGR_STATE_CRASHED; -+ if (!(cmd->flags & RWNX_CMD_FLAG_DONE)) { -+ cmd->result = -ETIMEDOUT; -+ cmd_complete(cmd_mgr, cmd); -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+ } else { -+ rwnx_cmd_free(cmd);//kfree(cmd); -+ if (!list_empty(&cmd_mgr->cmds)) -+ WAKE_CMD_WORK(cmd_mgr); -+ } -+ #endif -+ } else { -+ cmd->result = 0; -+ } -+ -+ return 0; -+} -+ -+/** -+ * -+ */ -+static int cmd_mgr_llind(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) -+{ -+ struct rwnx_cmd *cur, *acked = NULL, *next = NULL; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ spin_lock_bh(&cmd_mgr->lock); -+ list_for_each_entry(cur, &cmd_mgr->cmds, list) { -+ if (!acked) { -+ if (cur->tkn == cmd->tkn) { -+ if (WARN_ON_ONCE(cur != cmd)) { -+ cmd_dump(cmd); -+ } -+ acked = cur; -+ continue; -+ } -+ } -+ if (cur->flags & RWNX_CMD_FLAG_WAIT_PUSH) { -+ next = cur; -+ break; -+ } -+ } -+ if (!acked) { -+ printk(KERN_CRIT "Error: acked cmd not found\n"); -+ } else { -+ cmd->flags &= ~RWNX_CMD_FLAG_WAIT_ACK; -+ if (RWNX_CMD_WAIT_COMPLETE(cmd->flags)) -+ cmd_complete(cmd_mgr, cmd); -+ } -+ -+ if (next) { -+ #if 0 //there is no ack -+ struct rwnx_hw *rwnx_hw = container_of(cmd_mgr, struct rwnx_hw, cmd_mgr); -+ next->flags &= ~RWNX_CMD_FLAG_WAIT_PUSH; -+ rwnx_ipc_msg_push(rwnx_hw, next, RWNX_CMD_A2EMSG_LEN(next->a2e_msg)); -+ kfree(next->a2e_msg); -+ #endif -+ } -+ spin_unlock(&cmd_mgr->lock); -+ -+ return 0; -+} -+ -+void cmd_mgr_task_process(struct work_struct *work) -+{ -+ struct rwnx_cmd_mgr *cmd_mgr = container_of(work, struct rwnx_cmd_mgr, cmdWork); -+ struct rwnx_cmd *cur, *next = NULL; -+ unsigned long tout; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ while (1) { -+ next = NULL; -+ spin_lock_bh(&cmd_mgr->lock); -+ -+ list_for_each_entry(cur, &cmd_mgr->cmds, list) { -+ if (cur->flags & RWNX_CMD_FLAG_WAIT_PUSH) { //just judge the first -+ next = cur; -+ } -+ break; -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+ -+ if (next == NULL) -+ break; -+ -+ if (next) { -+#ifdef AICWF_SDIO_SUPPORT -+ struct aic_sdio_dev *sdiodev = container_of(cmd_mgr, struct aic_sdio_dev, cmd_mgr); -+#endif -+#ifdef AICWF_USB_SUPPORT -+ struct aic_usb_dev *usbdev = container_of(cmd_mgr, struct aic_usb_dev, cmd_mgr); -+#endif -+ next->flags &= ~RWNX_CMD_FLAG_WAIT_PUSH; -+ -+ //printk("cmd_process, cmd->id=%d, tkn=%d\r\n",next->reqid, next->tkn); -+ //rwnx_ipc_msg_push(rwnx_hw, next, RWNX_CMD_A2EMSG_LEN(next->a2e_msg)); -+#ifdef AICWF_SDIO_SUPPORT -+ aicwf_set_cmd_tx((void *)(sdiodev), next->a2e_msg, sizeof(struct lmac_msg) + next->a2e_msg->param_len); -+#else -+ aicwf_set_cmd_tx((void *)(usbdev), next->a2e_msg, sizeof(struct lmac_msg) + next->a2e_msg->param_len); -+#endif -+ kfree(next->a2e_msg); -+ -+ tout = msecs_to_jiffies(RWNX_80211_CMD_TIMEOUT_MS * cmd_mgr->queue_sz); -+ if (!wait_for_completion_timeout(&next->complete, tout)) { -+ printk(KERN_CRIT"cmd timed-out\n"); -+#ifdef AICWF_SDIO_SUPPORT -+ if (aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.wakeup_reg, 2) < 0) { -+ sdio_err("reg:%d write failed!\n", sdiodev->sdio_reg.wakeup_reg); -+ } -+#endif -+ cmd_dump(next); -+ spin_lock_bh(&cmd_mgr->lock); -+ cmd_mgr->state = RWNX_CMD_MGR_STATE_CRASHED; -+ if (!(next->flags & RWNX_CMD_FLAG_DONE)) { -+ next->result = -ETIMEDOUT; -+ cmd_complete(cmd_mgr, next); -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+ } else -+ rwnx_cmd_free(next);//kfree(next); -+ } -+ } -+ -+} -+ -+ -+static int cmd_mgr_run_callback(struct rwnx_hw *rwnx_hw, struct rwnx_cmd *cmd, -+ struct rwnx_cmd_e2amsg *msg, msg_cb_fct cb) -+{ -+ int res; -+ -+ if (!cb) { -+ return 0; -+ } -+ //RWNX_DBG(RWNX_FN_ENTRY_STR); -+ //spin_lock_bh(&rwnx_hw->cb_lock); -+ res = cb(rwnx_hw, cmd, msg); -+ //spin_unlock_bh(&rwnx_hw->cb_lock); -+ -+ return res; -+} -+ -+/** -+ * -+ -+ */ -+static int cmd_mgr_msgind(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd_e2amsg *msg, -+ msg_cb_fct cb) -+{ -+#ifdef AICWF_SDIO_SUPPORT -+ struct aic_sdio_dev *sdiodev = container_of(cmd_mgr, struct aic_sdio_dev, cmd_mgr); -+ struct rwnx_hw *rwnx_hw = sdiodev->rwnx_hw; -+#endif -+#ifdef AICWF_USB_SUPPORT -+ struct aic_usb_dev *usbdev = container_of(cmd_mgr, struct aic_usb_dev, cmd_mgr); -+ struct rwnx_hw *rwnx_hw = usbdev->rwnx_hw; -+#endif -+ struct rwnx_cmd *cmd, *pos; -+ bool found = false; -+ -+ // RWNX_DBG(RWNX_FN_ENTRY_STR); -+#ifdef CREATE_TRACE_POINTS -+ trace_msg_recv(msg->id); -+#endif -+ //printk("cmd->id=%x\n", msg->id); -+ spin_lock_bh(&cmd_mgr->lock); -+ list_for_each_entry_safe(cmd, pos, &cmd_mgr->cmds, list) { -+ if (cmd->reqid == msg->id && -+ (cmd->flags & RWNX_CMD_FLAG_WAIT_CFM)) { -+ -+ if (!cmd_mgr_run_callback(rwnx_hw, cmd, msg, cb)) { -+ found = true; -+ cmd->flags &= ~RWNX_CMD_FLAG_WAIT_CFM; -+ -+ if (WARN((msg->param_len > RWNX_CMD_E2AMSG_LEN_MAX), -+ "Unexpect E2A msg len %d > %d\n", msg->param_len, -+ RWNX_CMD_E2AMSG_LEN_MAX)) { -+ msg->param_len = RWNX_CMD_E2AMSG_LEN_MAX; -+ } -+ -+ if (cmd->e2a_msg && msg->param_len) -+ memcpy(cmd->e2a_msg, &msg->param, msg->param_len); -+ -+ if (RWNX_CMD_WAIT_COMPLETE(cmd->flags)) -+ cmd_complete(cmd_mgr, cmd); -+ -+ break; -+ } -+ } -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+ -+ if (!found) -+ cmd_mgr_run_callback(rwnx_hw, NULL, msg, cb); -+ -+ return 0; -+} -+ -+/** -+ * -+ */ -+static void cmd_mgr_print(struct rwnx_cmd_mgr *cmd_mgr) -+{ -+ struct rwnx_cmd *cur; -+ -+ spin_lock_bh(&cmd_mgr->lock); -+ RWNX_DBG("q_sz/max: %2d / %2d - next tkn: %d\n", -+ cmd_mgr->queue_sz, cmd_mgr->max_queue_sz, -+ cmd_mgr->next_tkn); -+ list_for_each_entry(cur, &cmd_mgr->cmds, list) { -+ cmd_dump(cur); -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+} -+ -+static void cmd_mgr_drain(struct rwnx_cmd_mgr *cmd_mgr) -+{ -+ struct rwnx_cmd *cur, *nxt; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ spin_lock_bh(&cmd_mgr->lock); -+ list_for_each_entry_safe(cur, nxt, &cmd_mgr->cmds, list) { -+ list_del(&cur->list); -+ cmd_mgr->queue_sz--; -+ if (!(cur->flags & RWNX_CMD_FLAG_NONBLOCK)) -+ complete(&cur->complete); -+ } -+ spin_unlock_bh(&cmd_mgr->lock); -+} -+ -+void rwnx_cmd_mgr_init(struct rwnx_cmd_mgr *cmd_mgr) -+{ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ INIT_LIST_HEAD(&cmd_mgr->cmds); -+ cmd_mgr->state = RWNX_CMD_MGR_STATE_INITED; -+ spin_lock_init(&cmd_mgr->lock); -+ cmd_mgr->max_queue_sz = RWNX_CMD_MAX_QUEUED; -+ cmd_mgr->queue = &cmd_mgr_queue; -+ cmd_mgr->print = &cmd_mgr_print; -+ cmd_mgr->drain = &cmd_mgr_drain; -+ cmd_mgr->llind = &cmd_mgr_llind; -+ cmd_mgr->msgind = &cmd_mgr_msgind; -+ -+ INIT_WORK(&cmd_mgr->cmdWork, cmd_mgr_task_process); -+ cmd_mgr->cmd_wq = create_singlethread_workqueue("cmd_wq"); -+ if (!cmd_mgr->cmd_wq) { -+ txrx_err("insufficient memory to create cmd workqueue.\n"); -+ return; -+ } -+} -+ -+void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr) -+{ -+ cmd_mgr->print(cmd_mgr); -+ cmd_mgr->drain(cmd_mgr); -+ cmd_mgr->print(cmd_mgr); -+ flush_workqueue(cmd_mgr->cmd_wq); -+ destroy_workqueue(cmd_mgr->cmd_wq); -+ memset(cmd_mgr, 0, sizeof(*cmd_mgr)); -+} -+ -+void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len) -+{ -+ u8 *buffer = NULL; -+ u16 index = 0; -+#ifdef AICWF_SDIO_SUPPORT -+ struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev; -+ struct aicwf_bus *bus = sdiodev->bus_if; -+#else -+ struct aic_usb_dev *usbdev = (struct aic_usb_dev *)dev; -+ struct aicwf_bus *bus = NULL; -+ if (!usbdev->state) { -+ printk("down msg \n"); -+ return; -+ } -+ bus = usbdev->bus_if; -+#endif -+ buffer = bus->cmd_buf; -+ -+ memset(buffer, 0, CMD_BUF_MAX); -+ buffer[0] = (len+4) & 0x00ff; -+ buffer[1] = ((len+4) >> 8) &0x0f; -+ buffer[2] = 0x11; -+ if (sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ sdiodev->chipid == PRODUCT_ID_AIC8800DW) -+ buffer[3] = 0x0; -+ else if (sdiodev->chipid == PRODUCT_ID_AIC8800D80) -+ buffer[3] = crc8_ponl_107(&buffer[0], 3); // crc8 -+ index += 4; -+ //there is a dummy word -+ index += 4; -+ -+ //make sure little endian -+ put_u16(&buffer[index], msg->id); -+ index += 2; -+ put_u16(&buffer[index], msg->dest_id); -+ index += 2; -+ put_u16(&buffer[index], msg->src_id); -+ index += 2; -+ put_u16(&buffer[index], msg->param_len); -+ index += 2; -+ memcpy(&buffer[index], (u8 *)msg->param, msg->param_len); -+ -+ aicwf_bus_txmsg(bus, buffer, len + 8); -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cmds.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cmds.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cmds.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_cmds.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,124 @@ -+/** -+ ****************************************************************************** -+ * -+ * rwnx_cmds.h -+ * -+ * Copyright (C) RivieraWaves 2014-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _RWNX_CMDS_H_ -+#define _RWNX_CMDS_H_ -+ -+#include -+#include -+#include -+#include "lmac_msg.h" -+ -+#ifdef CONFIG_RWNX_SDM -+#define RWNX_80211_CMD_TIMEOUT_MS (20 * 300) -+#elif defined(CONFIG_RWNX_FHOST) -+#define RWNX_80211_CMD_TIMEOUT_MS (10000) -+#else -+#ifdef AICWF_USB_SUPPORT -+#define RWNX_80211_CMD_TIMEOUT_MS 2000//300 -+#else -+#define RWNX_80211_CMD_TIMEOUT_MS 3000//500//300 -+#endif -+#endif -+ -+#define RWNX_CMD_FLAG_NONBLOCK BIT(0) -+#define RWNX_CMD_FLAG_REQ_CFM BIT(1) -+#define RWNX_CMD_FLAG_WAIT_PUSH BIT(2) -+#define RWNX_CMD_FLAG_WAIT_ACK BIT(3) -+#define RWNX_CMD_FLAG_WAIT_CFM BIT(4) -+#define RWNX_CMD_FLAG_DONE BIT(5) -+/* ATM IPC design makes it possible to get the CFM before the ACK, -+ * otherwise this could have simply been a state enum */ -+#define RWNX_CMD_WAIT_COMPLETE(flags) \ -+ (!(flags & (RWNX_CMD_FLAG_WAIT_ACK | RWNX_CMD_FLAG_WAIT_CFM))) -+ -+#define RWNX_CMD_MAX_QUEUED 16 -+ -+#ifdef CONFIG_RWNX_FHOST -+#include "ipc_fhost.h" -+#define rwnx_cmd_e2amsg ipc_fhost_msg -+#define rwnx_cmd_a2emsg ipc_fhost_msg -+#define RWNX_CMD_A2EMSG_LEN(m) (m->param_len) -+#define RWNX_CMD_E2AMSG_LEN_MAX IPC_FHOST_MSG_BUF_SIZE -+struct rwnx_term_stream; -+ -+#else /* !CONFIG_RWNX_FHOST*/ -+#include "ipc_shared.h" -+#define rwnx_cmd_e2amsg ipc_e2a_msg -+#define rwnx_cmd_a2emsg lmac_msg -+#define RWNX_CMD_A2EMSG_LEN(m) (sizeof(struct lmac_msg) + m->param_len) -+#define RWNX_CMD_E2AMSG_LEN_MAX (IPC_E2A_MSG_PARAM_SIZE * 4) -+ -+#endif /* CONFIG_RWNX_FHOST*/ -+ -+struct rwnx_hw; -+struct rwnx_cmd; -+typedef int (*msg_cb_fct)(struct rwnx_hw *rwnx_hw, struct rwnx_cmd *cmd, -+ struct rwnx_cmd_e2amsg *msg); -+static inline void put_u16(u8 *buf, u16 data) -+{ -+ buf[0] = (u8)(data&0x00ff); -+ buf[1] = (u8)((data >> 8)&0x00ff); -+} -+ -+enum rwnx_cmd_mgr_state { -+ RWNX_CMD_MGR_STATE_DEINIT, -+ RWNX_CMD_MGR_STATE_INITED, -+ RWNX_CMD_MGR_STATE_CRASHED, -+}; -+ -+struct rwnx_cmd { -+ struct list_head list; -+ lmac_msg_id_t id; -+ lmac_msg_id_t reqid; -+ struct rwnx_cmd_a2emsg *a2e_msg; -+ char *e2a_msg; -+ u32 tkn; -+ u16 flags; -+ -+ struct completion complete; -+ u32 result; -+ u8 used; -+ int array_id; -+ #ifdef CONFIG_RWNX_FHOST -+ struct rwnx_term_stream *stream; -+ #endif -+}; -+ -+struct rwnx_cmd_mgr { -+ enum rwnx_cmd_mgr_state state; -+ spinlock_t lock; -+ u32 next_tkn; -+ u32 queue_sz; -+ u32 max_queue_sz; -+ -+ struct list_head cmds; -+ -+ int (*queue)(struct rwnx_cmd_mgr *, struct rwnx_cmd *); -+ int (*llind)(struct rwnx_cmd_mgr *, struct rwnx_cmd *); -+ int (*msgind)(struct rwnx_cmd_mgr *, struct rwnx_cmd_e2amsg *, msg_cb_fct); -+ void (*print)(struct rwnx_cmd_mgr *); -+ void (*drain)(struct rwnx_cmd_mgr *); -+ -+ struct work_struct cmdWork; -+ struct workqueue_struct *cmd_wq; -+}; -+ -+#define WAKE_CMD_WORK(cmd_mgr) \ -+ do { \ -+ queue_work((cmd_mgr)->cmd_wq, &cmd_mgr->cmdWork); \ -+ } while (0) -+ -+void rwnx_cmd_mgr_init(struct rwnx_cmd_mgr *cmd_mgr); -+void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr); -+int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd); -+void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len); -+ -+#endif /* _RWNX_CMDS_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_compat.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_compat.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_compat.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_compat.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,446 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_compat.h -+ * -+ * Ensure driver compilation for linux 3.16 to 3.19 -+ * -+ * To avoid too many #if LINUX_VERSION_CODE if the code, when prototype change -+ * between different kernel version: -+ * - For external function, define a macro whose name is the function name with -+ * _compat suffix and prototype (actually the number of parameter) of the -+ * latest version. Then latest version this macro simply call the function -+ * and for older kernel version it call the function adapting the api. -+ * - For internal function (e.g. cfg80211_ops) do the same but the macro name -+ * doesn't need to have the _compat suffix when the function is not used -+ * directly by the driver -+ * -+ * Copyright (C) RivieraWaves 2018 -+ * -+ ****************************************************************************** -+ */ -+#ifndef _RWNX_COMPAT_H_ -+#define _RWNX_COMPAT_H_ -+#include -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) -+#error "Minimum kernel version supported is 3.10" -+#endif -+ -+/* Generic */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) -+#define __bf_shf(x) (__builtin_ffsll(x) - 1) -+#define FIELD_PREP(_mask, _val) \ -+ (((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)) -+#else -+#include -+#endif -+ -+/* CFG80211 */ -+ -+//because android kernel 5.15 uses kernel 6.0 or 6.1 kernel api -+#ifdef ANDROID_PLATFORM -+#define HIGH_KERNEL_VERSION KERNEL_VERSION(5, 15, 41) -+#define HIGH_KERNEL_VERSION2 KERNEL_VERSION(5, 15, 41) -+#define HIGH_KERNEL_VERSION3 KERNEL_VERSION(5, 15, 104) -+#define HIGH_KERNEL_VERSION4 KERNEL_VERSION(6, 1, 0) -+#else -+#define HIGH_KERNEL_VERSION KERNEL_VERSION(6, 0, 0) -+#define HIGH_KERNEL_VERSION2 KERNEL_VERSION(6, 1, 0) -+#define HIGH_KERNEL_VERSION3 KERNEL_VERSION(6, 3, 0) -+#define HIGH_KERNEL_VERSION4 KERNEL_VERSION(6, 3, 0) -+#endif -+ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 60) -+#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE -+#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB -+#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB -+#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU -+#endif -+ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) -+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) -+#define IEEE80211_RADIOTAP_HE 23 -+#define IEEE80211_RADIOTAP_HE_MU 24 -+ -+struct ieee80211_radiotap_he { -+ __le16 data1, data2, data3, data4, data5, data6; -+}; -+ -+enum ieee80211_radiotap_he_bits { -+ IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MASK = 3, -+ IEEE80211_RADIOTAP_HE_DATA1_FORMAT_SU = 0, -+ IEEE80211_RADIOTAP_HE_DATA1_FORMAT_EXT_SU = 1, -+ IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MU = 2, -+ IEEE80211_RADIOTAP_HE_DATA1_FORMAT_TRIG = 3, -+ -+ IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN = 0x0004, -+ IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN = 0x0008, -+ IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN = 0x0010, -+ IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN = 0x0020, -+ IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN = 0x0040, -+ IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN = 0x0080, -+ IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN = 0x0100, -+ IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN = 0x0200, -+ IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN = 0x0400, -+ IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN = 0x0800, -+ IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN = 0x1000, -+ IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN = 0x2000, -+ IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN = 0x4000, -+ IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN = 0x8000, -+ -+ IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN = 0x0001, -+ IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN = 0x0002, -+ IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN = 0x0004, -+ IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN = 0x0008, -+ IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN = 0x0010, -+ IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN = 0x0020, -+ IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN = 0x0040, -+ IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN = 0x0080, -+ IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET = 0x3f00, -+ IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET_KNOWN = 0x4000, -+ IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC = 0x8000, -+ -+ IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR = 0x003f, -+ IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE = 0x0040, -+ IEEE80211_RADIOTAP_HE_DATA3_UL_DL = 0x0080, -+ IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS = 0x0f00, -+ IEEE80211_RADIOTAP_HE_DATA3_DATA_DCM = 0x1000, -+ IEEE80211_RADIOTAP_HE_DATA3_CODING = 0x2000, -+ IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG = 0x4000, -+ IEEE80211_RADIOTAP_HE_DATA3_STBC = 0x8000, -+ -+ IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE = 0x000f, -+ IEEE80211_RADIOTAP_HE_DATA4_MU_STA_ID = 0x7ff0, -+ IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1 = 0x000f, -+ IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2 = 0x00f0, -+ IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3 = 0x0f00, -+ IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4 = 0xf000, -+ -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC = 0x000f, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_20MHZ = 0, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_40MHZ = 1, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_80MHZ = 2, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_160MHZ = 3, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_26T = 4, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_52T = 5, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_106T = 6, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_242T = 7, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_484T = 8, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_996T = 9, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_2x996T = 10, -+ -+ IEEE80211_RADIOTAP_HE_DATA5_GI = 0x0030, -+ IEEE80211_RADIOTAP_HE_DATA5_GI_0_8 = 0, -+ IEEE80211_RADIOTAP_HE_DATA5_GI_1_6 = 1, -+ IEEE80211_RADIOTAP_HE_DATA5_GI_3_2 = 2, -+ -+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE = 0x00c0, -+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_UNKNOWN = 0, -+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_1X = 1, -+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_2X = 2, -+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X = 3, -+ IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS = 0x0700, -+ IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD = 0x3000, -+ IEEE80211_RADIOTAP_HE_DATA5_TXBF = 0x4000, -+ IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG = 0x8000, -+ -+ IEEE80211_RADIOTAP_HE_DATA6_NSTS = 0x000f, -+ IEEE80211_RADIOTAP_HE_DATA6_DOPPLER = 0x0010, -+ IEEE80211_RADIOTAP_HE_DATA6_TXOP = 0x7f00, -+ IEEE80211_RADIOTAP_HE_DATA6_MIDAMBLE_PDCTY = 0x8000, -+}; -+ -+struct ieee80211_radiotap_he_mu { -+ __le16 flags1, flags2; -+ u8 ru_ch1[4]; -+ u8 ru_ch2[4]; -+}; -+ -+enum ieee80211_radiotap_he_mu_bits { -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS = 0x000f, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN = 0x0010, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM = 0x0020, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN = 0x0040, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN = 0x0080, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN = 0x0100, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN = 0x0200, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU_KNOWN = 0x1000, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU = 0x2000, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN = 0x4000, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN = 0x8000, -+ -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW = 0x0003, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_20MHZ = 0x0000, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_40MHZ = 0x0001, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_80MHZ = 0x0002, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_160MHZ = 0x0003, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN = 0x0004, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP = 0x0008, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS = 0x00f0, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW = 0x0300, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN = 0x0400, -+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_CH2_CTR_26T_RU = 0x0800, -+}; -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0) -+#define rwnx_cfg80211_add_iface(wiphy, name, name_assign_type, type, params) \ -+ rwnx_cfg80211_add_iface(wiphy, name, type, u32 *flags, params) -+#else -+#define rwnx_cfg80211_add_iface(wiphy, name, name_assign_type, type, params) \ -+ rwnx_cfg80211_add_iface(wiphy, name, name_assign_type, type, u32 *flags, params) -+#endif -+ -+#define rwnx_cfg80211_change_iface(wiphy, dev, type, params) \ -+ rwnx_cfg80211_change_iface(wiphy, dev, type, u32 *flags, params) -+ -+#define CCFS0(vht) vht->center_freq_seg1_idx -+#define CCFS1(vht) vht->center_freq_seg2_idx -+ -+#else -+#define CCFS0(vht) vht->center_freq_seg0_idx -+#define CCFS1(vht) vht->center_freq_seg1_idx -+ -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) -+#define cfg80211_cqm_rssi_notify(dev, event, level, gfp) \ -+ cfg80211_cqm_rssi_notify(dev, event, gfp) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) -+#define ieee80211_amsdu_to_8023s(skb, list, addr, iftype, extra_headroom, check_da, check_sa) \ -+ ieee80211_amsdu_to_8023s(skb, list, addr, iftype, extra_headroom, false) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0) -+#define NUM_NL80211_BANDS IEEE80211_NUM_BANDS -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) -+#define cfg80211_disconnected(dev, reason, ie, len, local, gfp) \ -+ cfg80211_disconnected(dev, reason, ie, len, gfp) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !(defined CONFIG_VENDOR_RWNX) -+#define ieee80211_chandef_to_operating_class(chan_def, op_class) 0 -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) -+#define SURVEY_INFO_TIME SURVEY_INFO_CHANNEL_TIME -+#define SURVEY_INFO_TIME_BUSY SURVEY_INFO_CHANNEL_TIME_BUSY -+#define SURVEY_INFO_TIME_EXT_BUSY SURVEY_INFO_CHANNEL_TIME_EXT_BUSY -+#define SURVEY_INFO_TIME_RX SURVEY_INFO_CHANNEL_TIME_RX -+#define SURVEY_INFO_TIME_TX SURVEY_INFO_CHANNEL_TIME_TX -+ -+#define SURVEY_TIME(s) s->channel_time -+#define SURVEY_TIME_BUSY(s) s->channel_time_busy -+#else -+#define SURVEY_TIME(s) s->time -+#define SURVEY_TIME_BUSY(s) s->time_busy -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) -+#define cfg80211_ch_switch_started_notify(dev, chandef, count) -+ -+#define WLAN_BSS_COEX_INFORMATION_REQUEST BIT(0) -+#define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING BIT(2) -+#define WLAN_EXT_CAPA4_TDLS_BUFFER_STA BIT(4) -+#define WLAN_EXT_CAPA4_TDLS_PEER_PSM BIT(5) -+#define WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH BIT(6) -+#define WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED BIT(7) -+#define NL80211_FEATURE_TDLS_CHANNEL_SWITCH 0 -+ -+#define STA_TDLS_INITIATOR(sta) 0 -+ -+#define REGULATORY_IGNORE_STALE_KICKOFF 0 -+#else -+#define STA_TDLS_INITIATOR(sta) sta->tdls_initiator -+#endif -+ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) -+#define cfg80211_rx_mgmt(wdev, freq, rssi, buf, len, flags) \ -+ cfg80211_rx_mgmt(wdev, freq, rssi, buf, len, flags, GFP_ATOMIC) -+#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) -+#define cfg80211_rx_mgmt(wdev, freq, rssi, buf, len, flags) \ -+ cfg80211_rx_mgmt(wdev, freq, rssi, buf, len, GFP_ATOMIC) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+#if 0 -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0) -+#define rwnx_cfg80211_tdls_mgmt(wiphy, dev, peer, act, tok, status, peer_capability, initiator, buf, len) \ -+ rwnx_cfg80211_tdls_mgmt(wiphy, dev, peer, act, tok, status, peer_capability, buf, len) -+#else -+#define rwnx_cfg80211_tdls_mgmt(wiphy, dev, peer, act, tok, status, peer_capability, initiator, buf, len) \ -+ rwnx_cfg80211_tdls_mgmt(wiphy, dev, peer, act, tok, status, buf, len) -+#endif -+#endif -+ -+#include -+ -+struct ieee80211_wmm_ac_param { -+ u8 aci_aifsn; /* AIFSN, ACM, ACI */ -+ u8 cw; /* ECWmin, ECWmax (CW = 2^ECW - 1) */ -+ __le16 txop_limit; -+} __packed; -+ -+struct ieee80211_wmm_param_ie { -+ u8 element_id; /* Element ID: 221 (0xdd); */ -+ u8 len; /* Length: 24 */ -+ /* required fields for WMM version 1 */ -+ u8 oui[3]; /* 00:50:f2 */ -+ u8 oui_type; /* 2 */ -+ u8 oui_subtype; /* 1 */ -+ u8 version; /* 1 for WMM version 1.0 */ -+ u8 qos_info; /* AP/STA specific QoS info */ -+ u8 reserved; /* 0 */ -+ /* AC_BE, AC_BK, AC_VI, AC_VO */ -+ struct ieee80211_wmm_ac_param ac[4]; -+} __packed; -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) -+enum { -+ IEEE80211_HE_MCS_SUPPORT_0_7 = 0, -+ IEEE80211_HE_MCS_SUPPORT_0_9 = 1, -+ IEEE80211_HE_MCS_SUPPORT_0_11 = 2, -+ IEEE80211_HE_MCS_NOT_SUPPORTED = 3, -+}; -+#endif -+ -+/* MAC80211 */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0) -+#define rwnx_ops_mgd_prepare_tx(hw, vif, duration) \ -+ rwnx_ops_mgd_prepare_tx(hw, vif) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) -+ -+#define RX_ENC_HT(s) (s->flag |= RX_FLAG_HT) -+#define RX_ENC_HT_GF(s) (s->flag |= (RX_FLAG_HT | RX_FLAG_HT_GF)) -+#define RX_ENC_VHT(s) (s->flag |= RX_FLAG_HT) -+#define RX_ENC_HE(s) (s->flag |= RX_FLAG_HT) -+#define RX_ENC_FLAG_SHORT_GI(s) (s->flag |= RX_FLAG_SHORT_GI) -+#define RX_ENC_FLAG_SHORT_PRE(s) (s->flag |= RX_FLAG_SHORTPRE) -+#define RX_ENC_FLAG_LDPC(s) (s->flag |= RX_FLAG_LDPC) -+#define RX_BW_40MHZ(s) (s->flag |= RX_FLAG_40MHZ) -+#define RX_BW_80MHZ(s) (s->vht_flag |= RX_VHT_FLAG_80MHZ) -+#define RX_BW_160MHZ(s) (s->vht_flag |= RX_VHT_FLAG_160MHZ) -+#define RX_NSS(s) s->vht_nss -+ -+#else -+#define RX_ENC_HT(s) (s->encoding = RX_ENC_HT) -+#define RX_ENC_HT_GF(s) { s->encoding = RX_ENC_HT; \ -+ s->enc_flags |= RX_ENC_FLAG_HT_GF; } -+#define RX_ENC_VHT(s) (s->encoding = RX_ENC_VHT) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) -+#define RX_ENC_HE(s) (s->encoding = RX_ENC_VHT) -+#else -+#define RX_ENC_HE(s) (s->encoding = RX_ENC_HE) -+#endif -+#define RX_ENC_FLAG_SHORT_GI(s) (s->enc_flags |= RX_ENC_FLAG_SHORT_GI) -+#define RX_ENC_FLAG_SHORT_PRE(s) (s->enc_flags |= RX_ENC_FLAG_SHORTPRE) -+#define RX_ENC_FLAG_LDPC(s) (s->enc_flags |= RX_ENC_FLAG_LDPC) -+#define RX_BW_40MHZ(s) (s->bw = RATE_INFO_BW_40) -+#define RX_BW_80MHZ(s) (s->bw = RATE_INFO_BW_80) -+#define RX_BW_160MHZ(s) (s->bw = RATE_INFO_BW_160) -+#define RX_NSS(s) s->nss -+ -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) -+#define ieee80211_cqm_rssi_notify(vif, event, level, gfp) \ -+ ieee80211_cqm_rssi_notify(vif, event, gfp) -+#endif -+ -+#ifndef CONFIG_VENDOR_RWNX_AMSDUS_TX -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) -+#define rwnx_ops_ampdu_action(hw, vif, params) \ -+ rwnx_ops_ampdu_action(hw, vif, enum ieee80211_ampdu_mlme_action action, \ -+ struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size) -+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) -+#define rwnx_ops_ampdu_action(hw, vif, params) \ -+ rwnx_ops_ampdu_action(hw, vif, enum ieee80211_ampdu_mlme_action action, \ -+ struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size, \ -+ bool amsdu) -+#endif -+#endif /* CONFIG_VENDOR_RWNX_AMSDUS_TX */ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) -+#define IEEE80211_HW_SUPPORT_FAST_XMIT 0 -+#define ieee80211_hw_check(hw, feat) (hw->flags & IEEE80211_HW_##feat) -+#define ieee80211_hw_set(hw, feat) {hw->flags |= IEEE80211_HW_##feat; } -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) -+#define rwnx_ops_sw_scan_start(hw, vif, mac_addr) \ -+ rwnx_ops_sw_scan_start(hw) -+#define rwnx_ops_sw_scan_complete(hw, vif) \ -+ rwnx_ops_sw_scan_complete(hw) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+#define rwnx_ops_hw_scan(hw, vif, hw_req) \ -+ rwnx_ops_hw_scan(hw, vif, struct cfg80211_scan_request *req) -+#endif -+ -+/* NET */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) -+#define rwnx_select_queue(dev, skb, sb_dev) \ -+ rwnx_select_queue(dev, skb) -+#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) -+#define rwnx_select_queue(dev, skb, sb_dev) \ -+ rwnx_select_queue(dev, skb, void *accel_priv, select_queue_fallback_t fallback) -+#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -+#define rwnx_select_queue(dev, skb, sb_dev) \ -+ rwnx_select_queue(dev, skb, sb_dev, select_queue_fallback_t fallback) -+#else -+#define rwnx_select_queue(dev, skb, sb_dev) \ -+ rwnx_select_queue(dev, skb, sb_dev) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)) && !(defined CONFIG_VENDOR_RWNX) -+#define sk_pacing_shift_update(sk, shift) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+#define alloc_netdev_mqs(size, name, assign, setup, txqs, rxqs) \ -+ alloc_netdev_mqs(size, name, setup, txqs, rxqs) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+#define NET_NAME_UNKNOWN 0 -+#endif -+ -+/* TRACE */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) -+#define trace_print_symbols_seq ftrace_print_symbols_seq -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+#define trace_seq_buffer_ptr(p) (p->buffer + p->len) -+#endif -+ -+/* TIME */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) -+#define time64_to_tm(t, o, tm) time_to_tm((time_t)t, o, tm) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) -+#define ktime_get_real_seconds get_seconds -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+typedef __s64 time64_t; -+#endif -+ -+#endif /* _RWNX_COMPAT_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_debugfs.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_debugfs.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_debugfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_debugfs.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,2455 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_debugfs.c -+ * -+ * @brief Definition of debugfs entries -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "rwnx_debugfs.h" -+#include "rwnx_msg_tx.h" -+#include "rwnx_radar.h" -+#include "rwnx_tx.h" -+ -+#ifdef CONFIG_DEBUG_FS -+#ifdef CONFIG_RWNX_FULLMAC -+static ssize_t rwnx_dbgfs_stats_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char *buf; -+ int ret; -+ int i, skipped; -+ ssize_t read; -+ int bufsz = (NX_TXQ_CNT) * 20 + (ARRAY_SIZE(priv->stats.amsdus_rx) + 1) * 40 -+ + (ARRAY_SIZE(priv->stats.ampdus_tx) * 30); -+ -+ if (*ppos) -+ return 0; -+ -+ buf = kmalloc(bufsz, GFP_ATOMIC); -+ if (buf == NULL) -+ return 0; -+ -+ ret = scnprintf(buf, bufsz, "TXQs CFM balances "); -+ for (i = 0; i < NX_TXQ_CNT; i++) -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " [%1d]:%3d", i, -+ priv->stats.cfm_balance[i]); -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, "\n"); -+ -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ "\nAMSDU[len] done failed received\n"); -+ for (i = skipped = 0; i < NX_TX_PAYLOAD_MAX; i++) { -+ if (priv->stats.amsdus[i].done) { -+ per = DIV_ROUND_UP((priv->stats.amsdus[i].failed) * -+ 100, priv->stats.amsdus[i].done); -+ } else if (priv->stats.amsdus_rx[i]) { -+ per = 0; -+ } else { -+ per = 0; -+ skipped = 1; -+ continue; -+ } -+ if (skipped) { -+ ret += scnprintf(&buf[ret], bufsz - ret, " ...\n"); -+ skipped = 0; -+ } -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " [%2d] %10d %8d(%3d%%) %10d\n", i ? i + 1 : i, -+ priv->stats.amsdus[i].done, -+ priv->stats.amsdus[i].failed, per, -+ priv->stats.amsdus_rx[i]); -+ } -+ -+ for (; i < ARRAY_SIZE(priv->stats.amsdus_rx); i++) { -+ if (!priv->stats.amsdus_rx[i]) { -+ skipped = 1; -+ continue; -+ } -+ if (skipped) { -+ ret += scnprintf(&buf[ret], bufsz - ret, " ...\n"); -+ skipped = 0; -+ } -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " [%2d] %10d\n", -+ i + 1, priv->stats.amsdus_rx[i]); -+ } -+#else -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ "\nAMSDU[len] received\n"); -+ for (i = skipped = 0; i < ARRAY_SIZE(priv->stats.amsdus_rx); i++) { -+ if (!priv->stats.amsdus_rx[i]) { -+ skipped = 1; -+ continue; -+ } -+ if (skipped) { -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " ...\n"); -+ skipped = 0; -+ } -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " [%2d] %10d\n", -+ i + 1, priv->stats.amsdus_rx[i]); -+ } -+ -+#endif /* CONFIG_RWNX_SPLIT_TX_BUF */ -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ "\nAMPDU[len] done received\n"); -+ for (i = skipped = 0; i < ARRAY_SIZE(priv->stats.ampdus_tx); i++) { -+ if (!priv->stats.ampdus_tx[i] && !priv->stats.ampdus_rx[i]) { -+ skipped = 1; -+ continue; -+ } -+ if (skipped) { -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " ...\n"); -+ skipped = 0; -+ } -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ " [%2d] %9d %9d\n", i ? i + 1 : i, -+ priv->stats.ampdus_tx[i], priv->stats.ampdus_rx[i]); -+ } -+ -+ ret += scnprintf(&buf[ret], bufsz - ret, -+ "#mpdu missed %9d\n", -+ priv->stats.ampdus_rx_miss); -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+ -+ kfree(buf); -+ -+ return read; -+} -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+static ssize_t rwnx_dbgfs_stats_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ -+ /* Prevent from interrupt preemption as these statistics are updated under -+ * interrupt */ -+ spin_lock_bh(&priv->tx_lock); -+ -+ memset(&priv->stats, 0, sizeof(priv->stats)); -+ -+ spin_unlock_bh(&priv->tx_lock); -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(stats); -+ -+#define TXQ_STA_PREF "tid|" -+#define TXQ_STA_PREF_FMT "%3d|" -+ -+#ifdef CONFIG_RWNX_FULLMAC -+#define TXQ_VIF_PREF "type|" -+#define TXQ_VIF_PREF_FMT "%4s|" -+#else -+#define TXQ_VIF_PREF "AC|" -+#define TXQ_VIF_PREF_FMT "%2s|" -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+#define TXQ_HDR "idx| status|credit|ready|retry" -+#define TXQ_HDR_FMT "%3d|%s%s%s%s%s%s%s|%6d|%5d|%5d" -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+#ifdef CONFIG_RWNX_FULLMAC -+#define TXQ_HDR_SUFF "|amsdu" -+#define TXQ_HDR_SUFF_FMT "|%5d" -+#else -+#define TXQ_HDR_SUFF "|amsdu-ht|amdsu-vht" -+#define TXQ_HDR_SUFF_FMT "|%8d|%9d" -+#endif /* CONFIG_RWNX_FULLMAC */ -+#else -+#define TXQ_HDR_SUFF "" -+#define TXQ_HDR_SUF_FMT "" -+#endif /* CONFIG_RWNX_AMSDUS_TX */ -+ -+#define TXQ_HDR_MAX_LEN (sizeof(TXQ_STA_PREF) + sizeof(TXQ_HDR) + sizeof(TXQ_HDR_SUFF) + 1) -+ -+#ifdef CONFIG_RWNX_FULLMAC -+#define PS_HDR "Legacy PS: ready=%d, sp=%d / UAPSD: ready=%d, sp=%d" -+#define PS_HDR_LEGACY "Legacy PS: ready=%d, sp=%d" -+#define PS_HDR_UAPSD "UAPSD: ready=%d, sp=%d" -+#define PS_HDR_MAX_LEN sizeof("Legacy PS: ready=xxx, sp=xxx / UAPSD: ready=xxx, sp=xxx\n") -+#else -+#define PS_HDR "" -+#define PS_HDR_MAX_LEN 0 -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+#define STA_HDR "** STA %d (%pM)\n" -+#define STA_HDR_MAX_LEN (sizeof("- STA xx (xx:xx:xx:xx:xx:xx)\n") + PS_HDR_MAX_LEN) -+ -+#ifdef CONFIG_RWNX_FULLMAC -+#define VIF_HDR "* VIF [%d] %s\n" -+#define VIF_HDR_MAX_LEN (sizeof(VIF_HDR) + IFNAMSIZ) -+#else -+#define VIF_HDR "* VIF [%d]\n" -+#define VIF_HDR_MAX_LEN sizeof(VIF_HDR) -+#endif -+ -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ -+#ifdef CONFIG_RWNX_FULLMAC -+#define VIF_SEP "---------------------------------------\n" -+#else -+#define VIF_SEP "----------------------------------------------------\n" -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+#else /* ! CONFIG_RWNX_AMSDUS_TX */ -+#define VIF_SEP "---------------------------------\n" -+#endif /* CONFIG_RWNX_AMSDUS_TX*/ -+ -+#define VIF_SEP_LEN sizeof(VIF_SEP) -+ -+#define CAPTION "status: L=in hwq list, F=stop full, P=stop sta PS, V=stop vif PS, C=stop channel, S=stop CSA, M=stop MU" -+#define CAPTION_LEN sizeof(CAPTION) -+ -+#define STA_TXQ 0 -+#define VIF_TXQ 1 -+ -+static int rwnx_dbgfs_txq(char *buf, size_t size, struct rwnx_txq *txq, int type, int tid, char *name) -+{ -+ int res, idx = 0; -+ -+ if (type == STA_TXQ) { -+ res = scnprintf(&buf[idx], size, TXQ_STA_PREF_FMT, tid); -+ idx += res; -+ size -= res; -+ } else { -+ res = scnprintf(&buf[idx], size, TXQ_VIF_PREF_FMT, name); -+ idx += res; -+ size -= res; -+ } -+ -+ res = scnprintf(&buf[idx], size, TXQ_HDR_FMT, txq->idx, -+ (txq->status & RWNX_TXQ_IN_HWQ_LIST) ? "L" : " ", -+ (txq->status & RWNX_TXQ_STOP_FULL) ? "F" : " ", -+ (txq->status & RWNX_TXQ_STOP_STA_PS) ? "P" : " ", -+ (txq->status & RWNX_TXQ_STOP_VIF_PS) ? "V" : " ", -+ (txq->status & RWNX_TXQ_STOP_CHAN) ? "C" : " ", -+ (txq->status & RWNX_TXQ_STOP_CSA) ? "S" : " ", -+ (txq->status & RWNX_TXQ_STOP_MU_POS) ? "M" : " ", -+ txq->credits, skb_queue_len(&txq->sk_list), -+ txq->nb_retry); -+ idx += res; -+ size -= res; -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ if (type == STA_TXQ) { -+ res = scnprintf(&buf[idx], size, TXQ_HDR_SUFF_FMT, -+#ifdef CONFIG_RWNX_FULLMAC -+ txq->amsdu_len -+#else -+ txq->amsdu_ht_len_cap, txq->amsdu_vht_len_cap -+#endif /* CONFIG_RWNX_FULLMAC */ -+ ); -+ idx += res; -+ size -= res; -+ } -+#endif -+ -+ res = scnprintf(&buf[idx], size, "\n"); -+ idx += res; -+ size -= res; -+ -+ return idx; -+} -+ -+static int rwnx_dbgfs_txq_sta(char *buf, size_t size, struct rwnx_sta *rwnx_sta, -+ struct rwnx_hw *rwnx_hw) -+{ -+ int tid, res, idx = 0; -+ struct rwnx_txq *txq; -+ -+ res = scnprintf(&buf[idx], size, "\n" STA_HDR, -+ rwnx_sta->sta_idx, -+#ifdef CONFIG_RWNX_FULLMAC -+ rwnx_sta->mac_addr -+#endif /* CONFIG_RWNX_FULLMAC */ -+ ); -+ idx += res; -+ size -= res; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ if (rwnx_sta->ps.active) { -+ if (rwnx_sta->uapsd_tids && -+ (rwnx_sta->uapsd_tids == ((1 << NX_NB_TXQ_PER_STA) - 1))) -+ res = scnprintf(&buf[idx], size, PS_HDR_UAPSD "\n", -+ rwnx_sta->ps.pkt_ready[UAPSD_ID], -+ rwnx_sta->ps.sp_cnt[UAPSD_ID]); -+ else if (rwnx_sta->uapsd_tids) -+ res = scnprintf(&buf[idx], size, PS_HDR "\n", -+ rwnx_sta->ps.pkt_ready[LEGACY_PS_ID], -+ rwnx_sta->ps.sp_cnt[LEGACY_PS_ID], -+ rwnx_sta->ps.pkt_ready[UAPSD_ID], -+ rwnx_sta->ps.sp_cnt[UAPSD_ID]); -+ else -+ res = scnprintf(&buf[idx], size, PS_HDR_LEGACY "\n", -+ rwnx_sta->ps.pkt_ready[LEGACY_PS_ID], -+ rwnx_sta->ps.sp_cnt[LEGACY_PS_ID]); -+ idx += res; -+ size -= res; -+ } else { -+ res = scnprintf(&buf[idx], size, "\n"); -+ idx += res; -+ size -= res; -+ } -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ -+ res = scnprintf(&buf[idx], size, TXQ_STA_PREF TXQ_HDR TXQ_HDR_SUFF "\n"); -+ idx += res; -+ size -= res; -+ -+ -+ foreach_sta_txq(rwnx_sta, txq, tid, rwnx_hw) { -+ res = rwnx_dbgfs_txq(&buf[idx], size, txq, STA_TXQ, tid, NULL); -+ idx += res; -+ size -= res; -+ } -+ -+ return idx; -+} -+ -+static int rwnx_dbgfs_txq_vif(char *buf, size_t size, struct rwnx_vif *rwnx_vif, -+ struct rwnx_hw *rwnx_hw) -+{ -+ int res, idx = 0; -+ struct rwnx_txq *txq; -+ struct rwnx_sta *rwnx_sta; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ res = scnprintf(&buf[idx], size, VIF_HDR, rwnx_vif->vif_index, rwnx_vif->ndev->name); -+ idx += res; -+ size -= res; -+ if (!rwnx_vif->up || rwnx_vif->ndev == NULL) -+ return idx; -+ -+#else -+ int ac; -+ char ac_name[2] = {'0', '\0'}; -+ -+ res = scnprintf(&buf[idx], size, VIF_HDR, rwnx_vif->vif_index); -+ idx += res; -+ size -= res; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP || -+ RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_GO || -+ RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_MESH_POINT) { -+ res = scnprintf(&buf[idx], size, TXQ_VIF_PREF TXQ_HDR "\n"); -+ idx += res; -+ size -= res; -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_UNK_TXQ_TYPE); -+ res = rwnx_dbgfs_txq(&buf[idx], size, txq, VIF_TXQ, 0, "UNK"); -+ idx += res; -+ size -= res; -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_BCMC_TXQ_TYPE); -+ res = rwnx_dbgfs_txq(&buf[idx], size, txq, VIF_TXQ, 0, "BCMC"); -+ idx += res; -+ size -= res; -+ rwnx_sta = &rwnx_hw->sta_table[rwnx_vif->ap.bcmc_index]; -+ if (rwnx_sta->ps.active) { -+ res = scnprintf(&buf[idx], size, PS_HDR_LEGACY "\n", -+ rwnx_sta->ps.sp_cnt[LEGACY_PS_ID], -+ rwnx_sta->ps.sp_cnt[LEGACY_PS_ID]); -+ idx += res; -+ size -= res; -+ } else { -+ res = scnprintf(&buf[idx], size, "\n"); -+ idx += res; -+ size -= res; -+ } -+ -+ list_for_each_entry(rwnx_sta, &rwnx_vif->ap.sta_list, list) { -+ res = rwnx_dbgfs_txq_sta(&buf[idx], size, rwnx_sta, rwnx_hw); -+ idx += res; -+ size -= res; -+ } -+ } else if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || -+ RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) { -+ if (rwnx_vif->sta.ap) { -+ res = rwnx_dbgfs_txq_sta(&buf[idx], size, rwnx_vif->sta.ap, rwnx_hw); -+ idx += res; -+ size -= res; -+ } -+ } -+ -+#else -+ res = scnprintf(&buf[idx], size, TXQ_VIF_PREF TXQ_HDR "\n"); -+ idx += res; -+ size -= res; -+ -+ foreach_vif_txq(rwnx_vif, txq, ac) { -+ ac_name[0]++; -+ res = rwnx_dbgfs_txq(&buf[idx], size, txq, VIF_TXQ, 0, ac_name); -+ idx += res; -+ size -= res; -+ } -+ -+ list_for_each_entry(rwnx_sta, &rwnx_vif->stations, list) { -+ res = rwnx_dbgfs_txq_sta(&buf[idx], size, rwnx_sta, rwnx_hw); -+ idx += res; -+ size -= res; -+ } -+#endif /* CONFIG_RWNX_FULLMAC */ -+ return idx; -+} -+ -+static ssize_t rwnx_dbgfs_txq_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *rwnx_hw = file->private_data; -+ struct rwnx_vif *vif; -+ char *buf; -+ int idx, res; -+ ssize_t read; -+ size_t bufsz = ((NX_VIRT_DEV_MAX * (VIF_HDR_MAX_LEN + 2 * VIF_SEP_LEN)) + -+ (NX_REMOTE_STA_MAX * STA_HDR_MAX_LEN) + -+ ((NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX + NX_NB_TXQ) * -+ TXQ_HDR_MAX_LEN) + CAPTION_LEN); -+ -+ /* everything is read in one go */ -+ if (*ppos) -+ return 0; -+ -+ bufsz = min_t(size_t, bufsz, count); -+ buf = kmalloc(bufsz, GFP_ATOMIC); -+ if (buf == NULL) -+ return 0; -+ -+ bufsz--; -+ idx = 0; -+ -+ res = scnprintf(&buf[idx], bufsz, CAPTION); -+ idx += res; -+ bufsz -= res; -+ -+ //spin_lock_bh(&rwnx_hw->tx_lock); -+ list_for_each_entry(vif, &rwnx_hw->vifs, list) { -+ res = scnprintf(&buf[idx], bufsz, "\n"VIF_SEP); -+ idx += res; -+ bufsz -= res; -+ res = rwnx_dbgfs_txq_vif(&buf[idx], bufsz, vif, rwnx_hw); -+ idx += res; -+ bufsz -= res; -+ res = scnprintf(&buf[idx], bufsz, VIF_SEP); -+ idx += res; -+ bufsz -= res; -+ } -+ //spin_unlock_bh(&rwnx_hw->tx_lock); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, idx); -+ kfree(buf); -+ -+ return read; -+} -+DEBUGFS_READ_FILE_OPS(txq); -+ -+static ssize_t rwnx_dbgfs_acsinfo_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+#ifdef CONFIG_RWNX_FULLMAC -+ struct wiphy *wiphy = priv->wiphy; -+#endif //CONFIG_RWNX_FULLMAC -+ int survey_cnt = 0; -+ int len = 0; -+ int band, chan_cnt; -+ int band_max = NL80211_BAND_5GHZ; -+ char *buf = (char *)vmalloc((SCAN_CHANNEL_MAX + 1) * 43); -+ ssize_t size; -+ -+ if (!buf) -+ return 0; -+ -+ if (priv->band_5g_support) -+ band_max = NL80211_BAND_5GHZ + 1; -+ -+ mutex_lock(&priv->dbgdump_elem.mutex); -+ -+ len += scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "FREQ TIME(ms) BUSY(ms) NOISE(dBm)\n"); -+ -+ for (band = NL80211_BAND_2GHZ; band < band_max; band++) { -+ for (chan_cnt = 0; chan_cnt < wiphy->bands[band]->n_channels; chan_cnt++) { -+ struct rwnx_survey_info *p_survey_info = &priv->survey[survey_cnt]; -+ struct ieee80211_channel *p_chan = &wiphy->bands[band]->channels[chan_cnt]; -+ -+ if (p_survey_info->filled) { -+ len += scnprintf(&buf[len], min_t(size_t, sizeof(buf) - len - 1, count), -+ "%d %03d %03d %d\n", -+ p_chan->center_freq, -+ p_survey_info->chan_time_ms, -+ p_survey_info->chan_time_busy_ms, -+ p_survey_info->noise_dbm); -+ } else { -+ len += scnprintf(&buf[len], min_t(size_t, sizeof(buf) -len -1, count), -+ "%d NOT AVAILABLE\n", -+ p_chan->center_freq); -+ } -+ -+ survey_cnt++; -+ } -+ } -+ -+ mutex_unlock(&priv->dbgdump_elem.mutex); -+ -+ size = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ vfree(buf); -+ -+ return size; -+} -+ -+DEBUGFS_READ_FILE_OPS(acsinfo); -+ -+static ssize_t rwnx_dbgfs_fw_dbg_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ char help[] = "usage: [MOD:]* " -+ "[DBG:]\n"; -+ -+ return simple_read_from_buffer(user_buf, count, ppos, help, sizeof(help)); -+} -+ -+ -+static ssize_t rwnx_dbgfs_fw_dbg_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int idx = 0; -+ u32 mod = 0; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ buf[len] = '\0'; -+ -+#define RWNX_MOD_TOKEN(str, val) \ -+ do { \ -+ if (strncmp(&buf[idx], str, sizeof(str) - 1) == 0) { \ -+ idx += sizeof(str) - 1; \ -+ mod |= val; \ -+ continue; \ -+ } \ -+ } while (0) -+ -+#define RWNX_DBG_TOKEN(str, val) \ -+ do { \ -+ if (strncmp(&buf[idx], str, sizeof(str) - 1) == 0) { \ -+ idx += sizeof(str) - 1; \ -+ dbg = val; \ -+ goto dbg_done; \ -+ } \ -+ } while (0) -+ -+ while ((idx + 4) < len) { -+ if (strncmp(&buf[idx], "MOD:", 4) == 0) { -+ idx += 4; -+ RWNX_MOD_TOKEN("ALL", 0xffffffff); -+ RWNX_MOD_TOKEN("KE", BIT(0)); -+ RWNX_MOD_TOKEN("DBG", BIT(1)); -+ RWNX_MOD_TOKEN("IPC", BIT(2)); -+ RWNX_MOD_TOKEN("DMA", BIT(3)); -+ RWNX_MOD_TOKEN("MM", BIT(4)); -+ RWNX_MOD_TOKEN("TX", BIT(5)); -+ RWNX_MOD_TOKEN("RX", BIT(6)); -+ RWNX_MOD_TOKEN("PHY", BIT(7)); -+ idx++; -+ } else if (strncmp(&buf[idx], "DBG:", 4) == 0) { -+ u32 dbg = 0; -+ idx += 4; -+ RWNX_DBG_TOKEN("NONE", 0); -+ RWNX_DBG_TOKEN("CRT", 1); -+ RWNX_DBG_TOKEN("ERR", 2); -+ RWNX_DBG_TOKEN("WRN", 3); -+ RWNX_DBG_TOKEN("INF", 4); -+ RWNX_DBG_TOKEN("VRB", 5); -+ idx++; -+ continue; -+ dbg_done: -+ rwnx_send_dbg_set_sev_filter_req(priv, dbg); -+ } else { -+ idx++; -+ } -+ } -+ -+ if (mod) { -+ rwnx_send_dbg_set_mod_filter_req(priv, mod); -+ } -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg); -+ -+static ssize_t rwnx_dbgfs_sys_stats_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[3*64]; -+ int len = 0; -+ ssize_t read; -+ int error = 0; -+ struct dbg_get_sys_stat_cfm cfm; -+ u32 sleep_int, sleep_frac, doze_int, doze_frac; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Get the information from the FW */ -+ error = rwnx_send_dbg_get_sys_stat_req(priv, &cfm); -+ if (error) -+ return error; -+ -+ if (cfm.stats_time == 0) -+ return 0; -+ -+ sleep_int = ((cfm.cpu_sleep_time * 100) / cfm.stats_time); -+ sleep_frac = (((cfm.cpu_sleep_time * 100) % cfm.stats_time) * 10) / cfm.stats_time; -+ doze_int = ((cfm.doze_time * 100) / cfm.stats_time); -+ doze_frac = (((cfm.doze_time * 100) % cfm.stats_time) * 10) / cfm.stats_time; -+ -+ len += scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "\nSystem statistics:\n"); -+ len += scnprintf(&buf[len], min_t(size_t, sizeof(buf) - 1, count), -+ " CPU sleep [%%]: %d.%d\n", sleep_int, sleep_frac); -+ len += scnprintf(&buf[len], min_t(size_t, sizeof(buf) - 1, count), -+ " Doze [%%]: %d.%d\n", doze_int, doze_frac); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(sys_stats); -+ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+static ssize_t rwnx_dbgfs_mu_group_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *rwnx_hw = file->private_data; -+ struct rwnx_mu_info *mu = &rwnx_hw->mu; -+ struct rwnx_mu_group *group; -+ size_t bufsz = NX_MU_GROUP_MAX * sizeof("xx = (xx - xx - xx - xx)\n") + 50; -+ char *buf; -+ int j, res, idx = 0; -+ -+ if (*ppos) -+ return 0; -+ -+ buf = kmalloc(bufsz, GFP_ATOMIC); -+ if (buf == NULL) -+ return 0; -+ -+ res = scnprintf(&buf[idx], bufsz, "MU Group list (%d groups, %d users max)\n", -+ NX_MU_GROUP_MAX, CONFIG_USER_MAX); -+ idx += res; -+ bufsz -= res; -+ -+ list_for_each_entry(group, &mu->active_groups, list) { -+ if (group->user_cnt) { -+ res = scnprintf(&buf[idx], bufsz, "%2d = (", group->group_id); -+ idx += res; -+ bufsz -= res; -+ for (j = 0; j < (CONFIG_USER_MAX - 1) ; j++) { -+ if (group->users[j]) -+ res = scnprintf(&buf[idx], bufsz, "%2d - ", -+ group->users[j]->sta_idx); -+ else -+ res = scnprintf(&buf[idx], bufsz, ".. - "); -+ -+ idx += res; -+ bufsz -= res; -+ } -+ -+ if (group->users[j]) -+ res = scnprintf(&buf[idx], bufsz, "%2d)\n", -+ group->users[j]->sta_idx); -+ else -+ res = scnprintf(&buf[idx], bufsz, "..)\n"); -+ -+ idx += res; -+ bufsz -= res; -+ } -+ } -+ -+ res = simple_read_from_buffer(user_buf, count, ppos, buf, idx); -+ kfree(buf); -+ -+ return res; -+} -+ -+DEBUGFS_READ_FILE_OPS(mu_group); -+#endif -+ -+#ifdef CONFIG_RWNX_P2P_DEBUGFS -+static ssize_t rwnx_dbgfs_oppps_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *rw_hw = file->private_data; -+ struct rwnx_vif *rw_vif; -+ char buf[32]; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ int ctw; -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ buf[len] = '\0'; -+ -+ /* Read the written CT Window (provided in ms) value */ -+ if (sscanf(buf, "ctw=%d", &ctw) > 0) { -+ /* Check if at least one VIF is configured as P2P GO */ -+ list_for_each_entry(rw_vif, &rw_hw->vifs, list) { -+#ifdef CONFIG_RWNX_FULLMAC -+ if (RWNX_VIF_TYPE(rw_vif) == NL80211_IFTYPE_P2P_GO) { -+#endif /* CONFIG_RWNX_FULLMAC */ -+ struct mm_set_p2p_oppps_cfm cfm; -+ -+ /* Forward request to the embedded and wait for confirmation */ -+ rwnx_send_p2p_oppps_req(rw_hw, rw_vif, (u8)ctw, &cfm); -+ -+ break; -+ } -+ } -+ } -+ -+ return count; -+} -+ -+DEBUGFS_WRITE_FILE_OPS(oppps); -+ -+static ssize_t rwnx_dbgfs_noa_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *rw_hw = file->private_data; -+ struct rwnx_vif *rw_vif; -+ char buf[64]; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ int noa_count, interval, duration, dyn_noa; -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ buf[len] = '\0'; -+ -+ /* Read the written NOA information */ -+ if (sscanf(buf, "count=%d interval=%d duration=%d dyn=%d", -+ &noa_count, &interval, &duration, &dyn_noa) > 0) { -+ /* Check if at least one VIF is configured as P2P GO */ -+ list_for_each_entry(rw_vif, &rw_hw->vifs, list) { -+#ifdef CONFIG_RWNX_FULLMAC -+ if (RWNX_VIF_TYPE(rw_vif) == NL80211_IFTYPE_P2P_GO) { -+#endif /* CONFIG_RWNX_FULLMAC */ -+ struct mm_set_p2p_noa_cfm cfm; -+ -+ /* Forward request to the embedded and wait for confirmation */ -+ rwnx_send_p2p_noa_req(rw_hw, rw_vif, noa_count, interval, -+ duration, (dyn_noa > 0), &cfm); -+ -+ break; -+ } -+ } -+ } -+ -+ return count; -+} -+ -+DEBUGFS_WRITE_FILE_OPS(noa); -+#endif /* CONFIG_RWNX_P2P_DEBUGFS */ -+ -+static char fw_log_buffer[FW_LOG_SIZE]; -+ -+static ssize_t rwnx_dbgfs_fw_log_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ size_t not_cpy; -+ size_t nb_cpy; -+ char *log = fw_log_buffer; -+ -+ printk("%s, %d, %p, %p\n", __func__, priv->debugfs.fw_log.buf.size, priv->debugfs.fw_log.buf.start, priv->debugfs.fw_log.buf.dataend); -+ //spin_lock_bh(&priv->debugfs.fw_log.lock); -+ -+ if ((priv->debugfs.fw_log.buf.start + priv->debugfs.fw_log.buf.size) >= priv->debugfs.fw_log.buf.dataend) { -+ memcpy(log, priv->debugfs.fw_log.buf.start, priv->debugfs.fw_log.buf.dataend - priv->debugfs.fw_log.buf.start); -+ not_cpy = copy_to_user(user_buf, log, priv->debugfs.fw_log.buf.dataend - priv->debugfs.fw_log.buf.start); -+ nb_cpy = priv->debugfs.fw_log.buf.dataend - priv->debugfs.fw_log.buf.start - not_cpy; -+ priv->debugfs.fw_log.buf.start = priv->debugfs.fw_log.buf.data; -+ } else { -+ memcpy(log, priv->debugfs.fw_log.buf.start, priv->debugfs.fw_log.buf.size); -+ not_cpy = copy_to_user(user_buf, log, priv->debugfs.fw_log.buf.size); -+ nb_cpy = priv->debugfs.fw_log.buf.size - not_cpy; -+ priv->debugfs.fw_log.buf.start = priv->debugfs.fw_log.buf.start + priv->debugfs.fw_log.buf.size - not_cpy; -+ } -+ -+ priv->debugfs.fw_log.buf.size -= nb_cpy; -+ //spin_unlock_bh(&priv->debugfs.fw_log.lock); -+ -+ printk("nb_cpy=%lu, not_cpy=%lu, start=%p, end=%p\n", (long unsigned int)nb_cpy, (long unsigned int)not_cpy, priv->debugfs.fw_log.buf.start, priv->debugfs.fw_log.buf.end); -+ return nb_cpy; -+} -+ -+static ssize_t rwnx_dbgfs_fw_log_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ //struct rwnx_hw *priv = file->private_data; -+ -+ printk("%s\n", __func__); -+ return count; -+} -+DEBUGFS_READ_WRITE_FILE_OPS(fw_log); -+ -+#ifdef CONFIG_RWNX_RADAR -+static ssize_t rwnx_dbgfs_pulses_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos, -+ int rd_idx) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char *buf; -+ int len = 0; -+ int bufsz; -+ int i; -+ int index; -+ struct rwnx_radar_pulses *p = &priv->radar.pulses[rd_idx]; -+ ssize_t read; -+ -+ if (*ppos != 0) -+ return 0; -+ -+ /* Prevent from interrupt preemption */ -+ spin_lock_bh(&priv->radar.lock); -+ bufsz = p->count * 34 + 51; -+ bufsz += rwnx_radar_dump_pattern_detector(NULL, 0, &priv->radar, rd_idx); -+ buf = kmalloc(bufsz, GFP_ATOMIC); -+ if (buf == NULL) { -+ spin_unlock_bh(&priv->radar.lock); -+ return 0; -+ } -+ -+ if (p->count) { -+ len += scnprintf(&buf[len], bufsz - len, -+ " PRI WIDTH FOM FREQ\n"); -+ index = p->index; -+ for (i = 0; i < p->count; i++) { -+ struct radar_pulse *pulse; -+ -+ if (index > 0) -+ index--; -+ else -+ index = RWNX_RADAR_PULSE_MAX - 1; -+ -+ pulse = (struct radar_pulse *) &p->buffer[index]; -+ -+ len += scnprintf(&buf[len], bufsz - len, -+ "%05dus %03dus %2d%% %+3dMHz\n", pulse->rep, -+ 2 * pulse->len, 6 * pulse->fom, 2*pulse->freq); -+ } -+ } -+ -+ len += rwnx_radar_dump_pattern_detector(&buf[len], bufsz - len, -+ &priv->radar, rd_idx); -+ -+ spin_unlock_bh(&priv->radar.lock); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+ kfree(buf); -+ -+ return read; -+} -+ -+static ssize_t rwnx_dbgfs_pulses_prim_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return rwnx_dbgfs_pulses_read(file, user_buf, count, ppos, 0); -+} -+ -+DEBUGFS_READ_FILE_OPS(pulses_prim); -+ -+static ssize_t rwnx_dbgfs_pulses_sec_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return rwnx_dbgfs_pulses_read(file, user_buf, count, ppos, 1); -+} -+ -+DEBUGFS_READ_FILE_OPS(pulses_sec); -+ -+static ssize_t rwnx_dbgfs_detected_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char *buf; -+ int bufsz, len = 0; -+ ssize_t read; -+ -+ if (*ppos != 0) -+ return 0; -+ -+ bufsz = 5; // RIU:\n -+ bufsz += rwnx_radar_dump_radar_detected(NULL, 0, &priv->radar, -+ RWNX_RADAR_RIU); -+ -+ if (priv->phy.cnt > 1) { -+ bufsz += 5; // FCU:\n -+ bufsz += rwnx_radar_dump_radar_detected(NULL, 0, &priv->radar, -+ RWNX_RADAR_FCU); -+ } -+ -+ buf = kmalloc(bufsz, GFP_KERNEL); -+ if (buf == NULL) { -+ return 0; -+ } -+ -+ len = scnprintf(&buf[len], bufsz, "RIU:\n"); -+ len += rwnx_radar_dump_radar_detected(&buf[len], bufsz - len, &priv->radar, -+ RWNX_RADAR_RIU); -+ -+ if (priv->phy.cnt > 1) { -+ len += scnprintf(&buf[len], bufsz - len, "FCU:\n"); -+ len += rwnx_radar_dump_radar_detected(&buf[len], bufsz - len, -+ &priv->radar, RWNX_RADAR_FCU); -+ } -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+ kfree(buf); -+ -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(detected); -+ -+static ssize_t rwnx_dbgfs_enable_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int ret; -+ ssize_t read; -+ -+ ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "RIU=%d FCU=%d\n", priv->radar.dpd[RWNX_RADAR_RIU]->enabled, -+ priv->radar.dpd[RWNX_RADAR_FCU]->enabled); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+ -+ return read; -+} -+ -+static ssize_t rwnx_dbgfs_enable_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int val; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ -+ if (sscanf(buf, "RIU=%d", &val) > 0) -+ rwnx_radar_detection_enable(&priv->radar, val, RWNX_RADAR_RIU); -+ -+ if (sscanf(buf, "FCU=%d", &val) > 0) -+ rwnx_radar_detection_enable(&priv->radar, val, RWNX_RADAR_FCU); -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(enable); -+ -+static ssize_t rwnx_dbgfs_band_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int ret; -+ ssize_t read; -+ -+ ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "BAND=%d\n", priv->phy.sec_chan.band); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+ -+ return read; -+} -+ -+static ssize_t rwnx_dbgfs_band_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int val; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ int band_max = NL80211_BAND_5GHZ; -+ -+ if (priv->band_5g_support) -+ band_max = NL80211_BAND_5GHZ + 1; -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ -+ if ((sscanf(buf, "%d", &val) > 0) && (val >= 0) && (val < band_max)) -+ priv->phy.sec_chan.band = val; -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(band); -+ -+static ssize_t rwnx_dbgfs_type_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int ret; -+ ssize_t read; -+ -+ ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "TYPE=%d\n", priv->phy.sec_chan.type); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+ -+ return read; -+} -+ -+static ssize_t rwnx_dbgfs_type_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int val; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ -+ if ((sscanf(buf, "%d", &val) > 0) && (val >= PHY_CHNL_BW_20) && -+ (val <= PHY_CHNL_BW_80P80)) -+ priv->phy.sec_chan.type = val; -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(type); -+ -+static ssize_t rwnx_dbgfs_prim20_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int ret; -+ ssize_t read; -+ -+ ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "PRIM20=%dMHz\n", priv->phy.sec_chan.prim20_freq); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+ -+ return read; -+} -+ -+static ssize_t rwnx_dbgfs_prim20_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int val; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ -+ if (sscanf(buf, "%d", &val) > 0) -+ priv->phy.sec_chan.prim20_freq = val; -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(prim20); -+ -+static ssize_t rwnx_dbgfs_center1_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int ret; -+ ssize_t read; -+ -+ ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "CENTER1=%dMHz\n", priv->phy.sec_chan.center_freq1); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+ -+ return read; -+} -+ -+static ssize_t rwnx_dbgfs_center1_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int val; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ -+ if (sscanf(buf, "%d", &val) > 0) -+ priv->phy.sec_chan.center_freq1 = val; -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(center1); -+ -+static ssize_t rwnx_dbgfs_center2_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int ret; -+ ssize_t read; -+ -+ ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count), -+ "CENTER2=%dMHz\n", priv->phy.sec_chan.center_freq2); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, ret); -+ -+ return read; -+} -+ -+static ssize_t rwnx_dbgfs_center2_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ int val; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ -+ if (sscanf(buf, "%d", &val) > 0) -+ priv->phy.sec_chan.center_freq2 = val; -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(center2); -+ -+ -+static ssize_t rwnx_dbgfs_set_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ return 0; -+} -+ -+static ssize_t rwnx_dbgfs_set_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ -+ rwnx_send_set_channel(priv, 1, NULL); -+ rwnx_radar_detection_enable(&priv->radar, RWNX_RADAR_DETECT_ENABLE, -+ RWNX_RADAR_FCU); -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(set); -+#endif /* CONFIG_RWNX_RADAR */ -+ -+static ssize_t rwnx_dbgfs_regdbg_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[32]; -+ u32 addr,val, oper; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ struct dbg_mem_read_cfm mem_read_cfm; -+ int ret; -+ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ -+ if (sscanf(buf, "%x %x %x" , &oper, &addr, &val ) > 0) -+ printk("addr=%x, val=%x,oper=%d\n", addr, val, oper); -+ -+ if(oper== 0) { -+ ret = rwnx_send_dbg_mem_read_req(priv, addr, &mem_read_cfm); -+ printk("[0x%x] = [0x%x]\n", mem_read_cfm.memaddr, mem_read_cfm.memdata); -+ } -+ -+ return count; -+} -+ -+DEBUGFS_WRITE_FILE_OPS(regdbg); -+ -+static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[64]; -+ int32_t addr[13]; -+ int32_t addr_out[12]; -+ u32_l hwconfig_id; -+ size_t len = min_t(size_t,count,sizeof(buf)-1); -+ int ret; -+ printk("%s\n",__func__); -+ //choose the type of write info by struct -+ //struct mm_set_vendor_trx_param_req trx_param; -+ -+ if(copy_from_user(buf,user_buf,len)) { -+ return -EFAULT; -+ } -+ -+ buf[len] = '\0'; -+ ret = sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x", -+ &hwconfig_id, &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]); -+ if(ret > 14) { -+ printk("param error > 14\n"); -+ } else { -+ switch(hwconfig_id) -+ { -+ case 0: -+ if(ret != 5) { -+ printk("param error != 5\n"); -+ break;} -+ ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL); -+ printk("ACS_TXOP_REQ bk:0x%x be:0x%x vi:0x%x vo:0x%x\n",addr[0], addr[1], addr[2], addr[3]); -+ break; -+ case 1: -+ if(ret != 14) { -+ printk("param error != 14\n"); -+ break;} -+ addr[12] = ~addr[12] + 1; -+ ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL); -+ printk("CHANNEL_ACCESS_REQ edca:%x,%x,%x,%x, vif:%x, retry_cnt:%x, rts:%x, long_nav:%x, cfe:%x, rc_retry_cnt:%x:%x:%x ccademod_th %x\n", -+ 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]); -+ break; -+ case 2: -+ if(ret != 7) { -+ printk("param error != 7\n"); -+ break;} -+ ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL); -+ printk("MAC_TIMESCALE_REQ sifsA:%x,sifsB:%x,slot:%x,ofdm_delay:%x,long_delay:%x,short_delay:%x\n", -+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); -+ break; -+ case 3: -+ if(ret != 6) { -+ printk("param error != 6\n"); -+ break;} -+ addr[1] = ~addr[1] + 1; -+ addr[2] = ~addr[2] + 1; -+ addr[3] = ~addr[3] + 1; -+ addr[4] = ~addr[4] + 1; -+ ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL); -+ printk("CCA_THRESHOLD_REQ auto_cca:%d, cca20p_rise:%d cca20s_rise:%d cca20p_fail:%d cca20s_fail:%d\n", -+ addr[0], addr[1], addr[2], addr[3], addr[4]); -+ break; -+ case 4: // BWMODE_REQ -+ if (ret != 2) { -+ printk("param error != 2\n"); -+ } else { -+ ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL); -+ printk("BWMODE_REQ md=%d\n", addr[0]); -+ } -+ break; -+ case 5: // CHIP_TEMP_GET_REQ -+ if (ret != 1) { -+ printk("param error != 1\n"); -+ } else { -+ ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, addr_out); -+ printk("CHIP_TEMP_GET_REQ degree=%d\n", addr_out[0]); -+ } -+ break; -+ default: -+ printk("param error\n"); -+ break; -+ } -+ if(ret) { -+ printk("rwnx_send_vendor_hwconfig_req fail: %x\n", ret); -+ } -+ } -+ -+ return count; -+} -+ -+DEBUGFS_WRITE_FILE_OPS(vendor_hwconfig); -+ -+static ssize_t rwnx_dbgfs_vendor_swconfig_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[64]; -+ int32_t addr[12]; -+ int32_t addr_out[12]; -+ u32_l swconfig_id; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ int ret; -+ printk("%s\n", __func__); -+ -+ if (copy_from_user(buf, user_buf, len)) { -+ return -EFAULT; -+ } -+ -+ buf[len] = '\0'; -+ ret = sscanf(buf, "%x %x %x", &swconfig_id, &addr[0], &addr[1]); -+ if (ret > 3) { -+ printk("param error > 3\n"); -+ } else { -+ switch (swconfig_id) -+ { -+ case 0: // BCN_CFG_REQ -+ if (ret != 2) { -+ printk("param error != 2\n"); -+ } else { -+ ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out); -+ printk("BCN_CFG_REQ set_en=%d, get_en=%d\n", addr[0], addr_out[0]); -+ } -+ break; -+ -+ case 1: // TEMP_COMP_SET_REQ -+ if (ret != 3) { -+ printk("param error != 3\n"); -+ } else { -+ ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out); -+ printk("TEMP_COMP_SET_REQ set_en=%d, tmr=%dms, get_st=%d\n", -+ addr[0], addr[1], addr_out[0]); -+ } -+ break; -+ -+ case 2: // TEMP_COMP_GET_REQ -+ if (ret != 1) { -+ printk("param error != 1\n"); -+ } else { -+ ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out); -+ printk("TEMP_COMP_GET_REQ get_st=%d, degree=%d\n", addr_out[0], addr_out[1]); -+ } -+ break; -+ -+ case 3: // EXT_FLAGS_SET_REQ -+ if (ret != 2) { -+ printk("param error != 2\n"); -+ } else { -+ ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out); -+ printk("EXT_FLAGS_SET_REQ set ext_flags=0x%x, get ext_flags=0x%x\n", -+ addr[0], addr_out[0]); -+ } -+ break; -+ -+ case 4: // EXT_FLAGS_GET_REQ -+ if (ret != 1) { -+ printk("param error != 1\n"); -+ } else { -+ ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out); -+ printk("EXT_FLAGS_GET_REQ get ext_flags=0x%x\n", addr_out[0]); -+ } -+ break; -+ -+ case 5: // EXT_FLAGS_MASK_SET_REQ -+ if (ret != 3) { -+ printk("param error != 3\n"); -+ } else { -+ ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out); -+ printk("EXT_FLAGS_MASK_SET_REQ set ext_flags mask=0x%x, val=0x%x, get ext_flags=0x%x\n", -+ addr[0], addr[1], addr_out[0]); -+ } -+ break; -+ -+ default: -+ printk("param error\n"); -+ break; -+ } -+ -+ if (ret) { -+ printk("rwnx_send_vendor_swconfig_req fail: %x\n", ret); -+ } -+ } -+ -+ return count; -+} -+ -+DEBUGFS_WRITE_FILE_OPS(vendor_swconfig); -+ -+static ssize_t rwnx_dbgfs_agg_disable_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ char buf[64]; -+ int agg_disable, agg_disable_rx, sta_idx; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ int ret; -+ printk("%s\n", __func__); -+ -+ if (copy_from_user(buf, user_buf, len)) { -+ return -EFAULT; -+ } -+ -+ buf[len] = '\0'; -+ ret = sscanf(buf, "%d %d %d", &agg_disable, &agg_disable_rx, &sta_idx); -+ if ((ret > 3) || (ret < 2)) { -+ printk("param error: cnt=%d\n", ret); -+ } else { -+ if (ret < 3) { -+ sta_idx = RWNX_INVALID_STA; -+ } -+ printk("disable_agg: T=%d, R=%d, staidx=%d\n", agg_disable, agg_disable_rx, sta_idx); -+ ret = rwnx_send_disable_agg_req(priv, (u8_l)agg_disable, (u8_l)agg_disable_rx, (u8_l)sta_idx); -+ if (ret) { -+ printk("rwnx_send_disable_agg_req fail: %d\n", ret); -+ } -+ } -+ -+ return count; -+} -+ -+DEBUGFS_WRITE_FILE_OPS(agg_disable); -+ -+static ssize_t rwnx_dbgfs_set_roc_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_hw *priv = file->private_data; -+ struct rwnx_vif *vif = NULL; -+ char buf[64]; -+ int roc_start, chan_freq, duration; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ int ret; -+ int if_type = NL80211_IFTYPE_STATION; -+ printk("%s\n", __func__); -+ -+ if (copy_from_user(buf, user_buf, len)) { -+ return -EFAULT; -+ } -+ -+ buf[len] = '\0'; -+ ret = sscanf(buf, "%d %d %d", &roc_start, &chan_freq, &duration); -+ -+ list_for_each_entry(vif, &priv->vifs, list) { -+ if (RWNX_VIF_TYPE(vif) == if_type) { -+ break; -+ } -+ } -+ if ((ret > 3) || (ret < 1)) { -+ printk("param error: cnt=%d\n", ret); -+ } else if (vif) { -+ struct ieee80211_channel chan_entry = {0,}; -+ struct ieee80211_channel *chan = &chan_entry; -+ struct mm_remain_on_channel_cfm roc_cfm; -+ if (ret < 3) { -+ duration = 2000; -+ if (ret < 2) { -+ chan_freq = 2412; -+ } -+ } -+ printk("set_roc: start=%d, freq=%d\n", roc_start, chan_freq); -+ if (roc_start) { -+ if (chan_freq <= 2484) { -+ chan->band = NL80211_BAND_2GHZ; -+ } else { -+ chan->band = NL80211_BAND_5GHZ; -+ } -+ chan->center_freq = chan_freq; -+ chan->max_power = 18; -+ ret = rwnx_send_roc(priv, vif, chan, duration, &roc_cfm); -+ if (ret) { -+ printk("rwnx_send_roc fail: %d\n", ret); -+ } else { -+ printk("roc_cfm: opcode=%x, st=%d, idx=%d\n", roc_cfm.op_code, roc_cfm.status, roc_cfm.chan_ctxt_index); -+ } -+ } else { -+ ret = rwnx_send_cancel_roc(priv); -+ if (ret) { -+ printk("rwnx_send_cancel_roc fail: %d\n", ret); -+ } -+ } -+ } -+ -+ return count; -+} -+ -+DEBUGFS_WRITE_FILE_OPS(set_roc); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+#define LINE_MAX_SZ 150 -+ -+struct st { -+ char line[LINE_MAX_SZ + 1]; -+ unsigned int r_idx; -+}; -+ -+static int compare_idx(const void *st1, const void *st2) -+{ -+ int index1 = ((struct st *)st1)->r_idx; -+ int index2 = ((struct st *)st2)->r_idx; -+ -+ if (index1 > index2) -+ return 1; -+ if (index1 < index2) -+ return -1; -+ -+ return 0; -+} -+ -+static const int ru_size[] = { -+ 26, -+ 52, -+ 106, -+ 242, -+ 484, -+ 996 -+}; -+ -+static int print_rate(char *buf, int size, int format, int nss, int mcs, int bw, -+ int sgi, int pre, int *r_idx) -+{ -+ int res = 0; -+ int bitrates_cck[4] = { 10, 20, 55, 110 }; -+ int bitrates_ofdm[8] = { 6, 9, 12, 18, 24, 36, 48, 54}; -+ char he_gi[3][4] = {"0.8", "1.6", "3.2"}; -+ -+ if (format < FORMATMOD_HT_MF) { -+ if (mcs < 4) { -+ if (r_idx) { -+ *r_idx = (mcs * 2) + pre; -+ res = scnprintf(buf, size - res, "%3d ", *r_idx); -+ } -+ res += scnprintf(&buf[res], size - res, "L-CCK/%cP %2u.%1uM ", -+ pre > 0 ? 'L' : 'S', -+ bitrates_cck[mcs] / 10, -+ bitrates_cck[mcs] % 10); -+ } else { -+ mcs -= 4; -+ if (r_idx) { -+ *r_idx = N_CCK + mcs; -+ res = scnprintf(buf, size - res, "%3d ", *r_idx); -+ } -+ res += scnprintf(&buf[res], size - res, "L-OFDM %2u.0M ", -+ bitrates_ofdm[mcs]); -+ } -+ } else if (format < FORMATMOD_VHT) { -+ if (r_idx) { -+ *r_idx = N_CCK + N_OFDM + nss * 32 + mcs * 4 + bw * 2 + sgi; -+ res = scnprintf(buf, size - res, "%3d ", *r_idx); -+ } -+ mcs += nss * 8; -+ res += scnprintf(&buf[res], size - res, "HT%d/%cGI MCS%-2d ", -+ 20 * (1 << bw), sgi ? 'S' : 'L', mcs); -+ } else if (format == FORMATMOD_VHT) { -+ if (r_idx) { -+ *r_idx = N_CCK + N_OFDM + N_HT + nss * 80 + mcs * 8 + bw * 2 + sgi; -+ res = scnprintf(buf, size - res, "%3d ", *r_idx); -+ } -+ res += scnprintf(&buf[res], size - res, "VHT%d/%cGI%*cMCS%d/%1d ", -+ 20 * (1 << bw), sgi ? 'S' : 'L', bw > 2 ? 5 : 6, ' ', -+ mcs, nss + 1); -+ } else if (format == FORMATMOD_HE_SU) { -+ if (r_idx) { -+ *r_idx = N_CCK + N_OFDM + N_HT + N_VHT + nss * 144 + mcs * 12 + bw * 3 + sgi; -+ res = scnprintf(buf, size - res, "%3d ", *r_idx); -+ } -+ res += scnprintf(&buf[res], size - res, "HE%d/GI%s%*cMCS%d/%1d%*c", -+ 20 * (1 << bw), he_gi[sgi], bw > 2 ? 4 : 5, ' ', -+ mcs, nss + 1, mcs > 9 ? 1 : 2, ' '); -+ } else { -+ if (r_idx) { -+ *r_idx = N_CCK + N_OFDM + N_HT + N_VHT + N_HE_SU + nss * 216 + mcs * 18 + bw * 3 + sgi; -+ res = scnprintf(buf, size - res, "%3d ", *r_idx); -+ } -+ res += scnprintf(&buf[res], size - res, "HEMU-%d/GI%s%*cMCS%d/%1d%*c", -+ ru_size[bw], he_gi[sgi], bw > 1 ? 1 : 2, ' ', -+ mcs, nss + 1, mcs > 9 ? 1 : 2, ' '); -+ -+ } -+ -+ return res; -+} -+ -+static int print_rate_from_cfg(char *buf, int size, u32 rate_config, int *r_idx, int ru_size) -+{ -+ union rwnx_rate_ctrl_info *r_cfg = (union rwnx_rate_ctrl_info *)&rate_config; -+ union rwnx_mcs_index *mcs_index = (union rwnx_mcs_index *)&rate_config; -+ unsigned int ft, pre, gi, bw, nss, mcs, len; -+ -+ ft = r_cfg->formatModTx; -+ pre = r_cfg->giAndPreTypeTx >> 1; -+ gi = r_cfg->giAndPreTypeTx; -+ bw = r_cfg->bwTx; -+ if (ft == FORMATMOD_HE_MU) { -+ mcs = mcs_index->he.mcs; -+ nss = mcs_index->he.nss; -+ bw = ru_size; -+ } else if (ft == FORMATMOD_HE_SU) { -+ mcs = mcs_index->he.mcs; -+ nss = mcs_index->he.nss; -+ } else if (ft == FORMATMOD_VHT) { -+ mcs = mcs_index->vht.mcs; -+ nss = mcs_index->vht.nss; -+ } else if (ft >= FORMATMOD_HT_MF) { -+ mcs = mcs_index->ht.mcs; -+ nss = mcs_index->ht.nss; -+ } else { -+ mcs = mcs_index->legacy; -+ nss = 0; -+ } -+ -+ len = print_rate(buf, size, ft, nss, mcs, bw, gi, pre, r_idx); -+ return len; -+} -+ -+static void idx_to_rate_cfg(int idx, union rwnx_rate_ctrl_info *r_cfg, int *ru_size) -+{ -+ r_cfg->value = 0; -+ if (idx < N_CCK) { -+ r_cfg->formatModTx = FORMATMOD_NON_HT; -+ r_cfg->giAndPreTypeTx = (idx & 1) << 1; -+ r_cfg->mcsIndexTx = idx / 2; -+ } else if (idx < (N_CCK + N_OFDM)) { -+ r_cfg->formatModTx = FORMATMOD_NON_HT; -+ r_cfg->mcsIndexTx = idx - N_CCK + 4; -+ } else if (idx < (N_CCK + N_OFDM + N_HT)) { -+ union rwnx_mcs_index *r = (union rwnx_mcs_index *)r_cfg; -+ -+ idx -= (N_CCK + N_OFDM); -+ r_cfg->formatModTx = FORMATMOD_HT_MF; -+ r->ht.nss = idx / (8*2*2); -+ r->ht.mcs = (idx % (8*2*2)) / (2*2); -+ r_cfg->bwTx = ((idx % (8*2*2)) % (2*2)) / 2; -+ r_cfg->giAndPreTypeTx = idx & 1; -+ } else if (idx < (N_CCK + N_OFDM + N_HT + N_VHT)) { -+ union rwnx_mcs_index *r = (union rwnx_mcs_index *)r_cfg; -+ -+ idx -= (N_CCK + N_OFDM + N_HT); -+ r_cfg->formatModTx = FORMATMOD_VHT; -+ r->vht.nss = idx / (10*4*2); -+ r->vht.mcs = (idx % (10*4*2)) / (4*2); -+ r_cfg->bwTx = ((idx % (10*4*2)) % (4*2)) / 2; -+ r_cfg->giAndPreTypeTx = idx & 1; -+ } else if (idx < (N_CCK + N_OFDM + N_HT + N_VHT + N_HE_SU)) { -+ union rwnx_mcs_index *r = (union rwnx_mcs_index *)r_cfg; -+ -+ idx -= (N_CCK + N_OFDM + N_HT + N_VHT); -+ r_cfg->formatModTx = FORMATMOD_HE_SU; -+ r->vht.nss = idx / (12*4*3); -+ r->vht.mcs = (idx % (12*4*3)) / (4*3); -+ r_cfg->bwTx = ((idx % (12*4*3)) % (4*3)) / 3; -+ r_cfg->giAndPreTypeTx = idx % 3; -+ } else { -+ union rwnx_mcs_index *r = (union rwnx_mcs_index *)r_cfg; -+ -+ BUG_ON(ru_size == NULL); -+ -+ idx -= (N_CCK + N_OFDM + N_HT + N_VHT + N_HE_SU); -+ r_cfg->formatModTx = FORMATMOD_HE_MU; -+ r->vht.nss = idx / (12*6*3); -+ r->vht.mcs = (idx % (12*6*3)) / (6*3); -+ *ru_size = ((idx % (12*6*3)) % (6*3)) / 3; -+ r_cfg->giAndPreTypeTx = idx % 3; -+ r_cfg->bwTx = 0; -+ } -+} -+ -+static void idx_to_rate_cfg1(unsigned int formatmod, -+ unsigned int mcs,unsigned int nss, -+ unsigned int bwTx,unsigned int gi, -+ union rwnx_rate_ctrl_info *r_cfg, int *ru_size) -+{ -+ r_cfg->value = 0; -+ -+ switch(formatmod){ -+ case FORMATMOD_NON_HT: -+ { -+ r_cfg->formatModTx = formatmod; -+ r_cfg->giAndPreTypeTx = 1; -+ r_cfg->mcsIndexTx = mcs; -+ break; -+ } -+ case FORMATMOD_NON_HT_DUP_OFDM: -+ { -+ r_cfg->formatModTx = formatmod; -+ r_cfg->giAndPreTypeTx = gi; -+ r_cfg->mcsIndexTx = mcs; -+ break; -+ } -+ case FORMATMOD_HT_MF: -+ { -+ union rwnx_mcs_index *r = (union rwnx_mcs_index *)r_cfg; -+ -+ r_cfg->formatModTx = formatmod; -+ r->ht.nss = nss; -+ r->ht.mcs = mcs; -+ r_cfg->bwTx = bwTx; -+ r_cfg->giAndPreTypeTx = gi; -+ break; -+ } -+ case FORMATMOD_VHT: -+ case FORMATMOD_HE_SU: -+ { -+ union rwnx_mcs_index *r = (union rwnx_mcs_index *)r_cfg; -+ -+ r_cfg->formatModTx = formatmod; -+ r->vht.nss = nss; -+ r->vht.mcs = mcs; -+ r_cfg->bwTx = bwTx; -+ r_cfg->giAndPreTypeTx = gi; -+ break; -+ } -+ case FORMATMOD_HE_MU: -+ { -+ union rwnx_mcs_index *r = (union rwnx_mcs_index *)r_cfg; -+ -+ r_cfg->formatModTx = formatmod; -+ r->he.nss = nss; -+ r->he.mcs = mcs; -+ r_cfg->bwTx = 0; -+ r_cfg->giAndPreTypeTx = gi; -+ break; -+ } -+ default: -+ printk("Don't have the formatmod"); -+ } -+} -+ -+static ssize_t rwnx_dbgfs_rc_stats_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_sta *sta = NULL; -+ struct rwnx_hw *priv = file->private_data; -+ char *buf; -+ int bufsz, len = 0; -+ ssize_t read; -+ int i = 0; -+ int error = 0; -+ struct me_rc_stats_cfm me_rc_stats_cfm; -+ unsigned int no_samples; -+ struct st *st; -+ u8 mac[6]; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* everything should fit in one call */ -+ if (*ppos) -+ return 0; -+ -+ /* Get the station index from MAC address */ -+ sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+ //if (mac == NULL) -+ // return 0; -+ sta = rwnx_get_sta(priv, mac); -+ if (sta == NULL) -+ return 0; -+ -+ /* Forward the information to the LMAC */ -+ error = rwnx_send_me_rc_stats(priv, sta->sta_idx, &me_rc_stats_cfm); -+ if (error) -+ return error; -+ -+ no_samples = me_rc_stats_cfm.no_samples; -+ if (no_samples == 0) -+ return 0; -+ -+ bufsz = no_samples * LINE_MAX_SZ + 500; -+ -+ buf = kmalloc(bufsz + 1, GFP_ATOMIC); -+ if (buf == NULL) -+ return 0; -+ -+ st = kmalloc(sizeof(struct st) * no_samples, GFP_ATOMIC); -+ if (st == NULL) { -+ kfree(buf); -+ return 0; -+ } -+ -+ for (i = 0; i < no_samples; i++) { -+ unsigned int tp, eprob; -+ len = print_rate_from_cfg(st[i].line, LINE_MAX_SZ, -+ me_rc_stats_cfm.rate_stats[i].rate_config, -+ &st[i].r_idx, 0); -+ -+ if (me_rc_stats_cfm.sw_retry_step != 0) { -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, "%c", -+ me_rc_stats_cfm.retry_step_idx[me_rc_stats_cfm.sw_retry_step] == i ? '*' : ' '); -+ } else { -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, " "); -+ } -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, "%c", -+ me_rc_stats_cfm.retry_step_idx[0] == i ? 'T' : ' '); -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, "%c", -+ me_rc_stats_cfm.retry_step_idx[1] == i ? 't' : ' '); -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, "%c ", -+ me_rc_stats_cfm.retry_step_idx[2] == i ? 'P' : ' '); -+ -+ tp = me_rc_stats_cfm.tp[i] / 10; -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, " %4u.%1u", -+ tp / 10, tp % 10); -+ -+ eprob = ((me_rc_stats_cfm.rate_stats[i].probability * 1000) >> 16) + 1; -+ len += scnprintf(&st[i].line[len], LINE_MAX_SZ - len, -+ " %4u.%1u %5u(%6u) %6u", -+ eprob / 10, eprob % 10, -+ me_rc_stats_cfm.rate_stats[i].success, -+ me_rc_stats_cfm.rate_stats[i].attempts, -+ me_rc_stats_cfm.rate_stats[i].sample_skipped); -+ } -+ len = scnprintf(buf, bufsz, -+ "\nTX rate info for %02X:%02X:%02X:%02X:%02X:%02X:\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -+ -+ len += scnprintf(&buf[len], bufsz - len, -+ " # type rate tpt eprob ok( tot) skipped\n"); -+ -+ // add sorted statistics to the buffer -+ sort(st, no_samples, sizeof(st[0]), compare_idx, NULL); -+ for (i = 0; i < no_samples; i++) { -+ len += scnprintf(&buf[len], bufsz - len, "%s\n", st[i].line); -+ } -+ -+ // display HE TB statistics if any -+ if (me_rc_stats_cfm.rate_stats[RC_HE_STATS_IDX].rate_config != 0) { -+ unsigned int tp, eprob; -+ struct rc_rate_stats *rate_stats = &me_rc_stats_cfm.rate_stats[RC_HE_STATS_IDX]; -+ int ru_index = rate_stats->ru_and_length & 0x07; -+ int ul_length = rate_stats->ru_and_length >> 3; -+ -+ len += scnprintf(&buf[len], bufsz - len, -+ "\nHE TB rate info:\n"); -+ -+ len += scnprintf(&buf[len], bufsz - len, -+ " type rate tpt eprob ok( tot) ul_length\n "); -+ len += print_rate_from_cfg(&buf[len], bufsz - len, rate_stats->rate_config, -+ NULL, ru_index); -+ -+ tp = me_rc_stats_cfm.tp[RC_HE_STATS_IDX] / 10; -+ len += scnprintf(&buf[len], bufsz - len, " %4u.%1u", -+ tp / 10, tp % 10); -+ -+ eprob = ((rate_stats->probability * 1000) >> 16) + 1; -+ len += scnprintf(&buf[len], bufsz - len, -+ " %4u.%1u %5u(%6u) %6u\n", -+ eprob / 10, eprob % 10, -+ rate_stats->success, -+ rate_stats->attempts, -+ ul_length); -+ } -+ -+ len += scnprintf(&buf[len], bufsz - len, "\n MPDUs AMPDUs AvLen trialP"); -+ len += scnprintf(&buf[len], bufsz - len, "\n%6u %6u %3d.%1d %6u\n", -+ me_rc_stats_cfm.ampdu_len, -+ me_rc_stats_cfm.ampdu_packets, -+ me_rc_stats_cfm.avg_ampdu_len >> 16, -+ ((me_rc_stats_cfm.avg_ampdu_len * 10) >> 16) % 10, -+ me_rc_stats_cfm.sample_wait); -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+ kfree(buf); -+ kfree(st); -+ -+ return read; -+} -+ -+DEBUGFS_READ_FILE_OPS(rc_stats); -+ -+static ssize_t rwnx_dbgfs_rc_fixed_rate_idx_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_sta *sta = NULL; -+ struct rwnx_hw *priv = file->private_data; -+ u8 mac[6]; -+ char buf[20]; -+ int fixed_rate_idx = 1; -+ unsigned int formatmod, mcs, nss, bwTx, gi; -+ union rwnx_rate_ctrl_info rate_config; -+ union rwnx_rate_ctrl_info *r_cfg=&rate_config; -+ int error = 0; -+ size_t len = min_t(size_t, count, sizeof(buf) - 1); -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Get the station index from MAC address */ -+ sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+ //if (mac == NULL) -+ // return 0; -+ sta = rwnx_get_sta(priv, mac); -+ if (sta == NULL) -+ return 0; -+ -+ /* Get the content of the file */ -+ if (copy_from_user(buf, user_buf, len)) -+ return -EFAULT; -+ buf[len] = '\0'; -+ //sscanf(buf, "%i\n", &fixed_rate_idx); -+ sscanf(buf, "%u %u %u %u %u",&formatmod, &mcs, &nss, &bwTx, &gi); -+ printk("%u %u %u %u %u\n",formatmod, mcs, nss, bwTx, gi); -+ -+ if((formatmod > 6) || (mcs > 11) || (nss > 8) || (bwTx > 6) || (gi > 3)){ -+ printk("error parameter"); -+ return len; -+ } -+ -+ /* Convert rate index into rate configuration */ -+ if ((fixed_rate_idx < 0) || (fixed_rate_idx >= (N_CCK + N_OFDM + N_HT + N_VHT + N_HE_SU))) -+ { -+ // disable fixed rate -+ rate_config.value = (u32)-1; -+ } -+ else -+ { -+ //idx_to_rate_cfg(fixed_rate_idx, &rate_config, NULL); -+ idx_to_rate_cfg1(formatmod, mcs, nss, bwTx, gi, &rate_config, NULL); -+ } -+ -+ printk("formatModTx=%u mcsIndexTx=%u bwTx=%u giAndPreTypeTx=%u\n",r_cfg->formatModTx,r_cfg->mcsIndexTx,r_cfg->bwTx,r_cfg->giAndPreTypeTx); -+ // Forward the request to the LMAC -+ if ((error = rwnx_send_me_rc_set_rate(priv, sta->sta_idx, -+ (u16)rate_config.value)) != 0) -+ { -+ return error; -+ } -+ -+ printk("send success \n"); -+ priv->debugfs.rc_config[sta->sta_idx] = (int)rate_config.value; -+ return len; -+ -+} -+ -+DEBUGFS_WRITE_FILE_OPS(rc_fixed_rate_idx); -+ -+static ssize_t rwnx_dbgfs_last_rx_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_sta *sta = NULL; -+ struct rwnx_hw *priv = file->private_data; -+ struct rwnx_rx_rate_stats *rate_stats; -+ char *buf; -+ int bufsz, i, len = 0; -+ ssize_t read; -+ unsigned int fmt, pre, bw, nss, mcs, gi; -+ u8 mac[6]; -+ struct rx_vector_1 *last_rx; -+ char hist[] = "##################################################"; -+ int hist_len = sizeof(hist) - 1; -+ u8 nrx; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* everything should fit in one call */ -+ if (*ppos) -+ return 0; -+ -+ /* Get the station index from MAC address */ -+ sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+// if (mac == NULL) -+// return 0; -+ sta = rwnx_get_sta(priv, mac); -+ if (sta == NULL) -+ return 0; -+ -+ rate_stats = &sta->stats.rx_rate; -+ bufsz = (rate_stats->rate_cnt * (50 + hist_len) + 200); -+ buf = kmalloc(bufsz + 1, GFP_ATOMIC); -+ if (buf == NULL) -+ return 0; -+ -+ // Get number of RX paths -+ nrx = (priv->version_cfm.version_phy_1 & MDM_NRX_MASK) >> MDM_NRX_LSB; -+ -+ len += scnprintf(buf, bufsz, -+ "\nRX rate info for %02X:%02X:%02X:%02X:%02X:%02X:\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -+ -+ // Display Statistics -+ for (i = 0; i < rate_stats->size; i++) { -+ if (rate_stats->table[i]) { -+ union rwnx_rate_ctrl_info rate_config; -+ int percent = (rate_stats->table[i] * 1000) / rate_stats->cpt; -+ int p = 0; -+ int ru_size = 0; -+ -+ idx_to_rate_cfg(i, &rate_config, &ru_size); -+ len += print_rate_from_cfg(&buf[len], bufsz - len, -+ rate_config.value, NULL, ru_size); -+ p = (percent * hist_len) / 1000; -+ len += scnprintf(&buf[len], bufsz - len, ": %6d(%3d.%1d%%)%.*s\n", -+ rate_stats->table[i], -+ percent / 10, percent % 10, p, hist); -+ } -+ } -+ -+ // Display detailed info of the last received rate -+ last_rx = &sta->stats.last_rx.rx_vect1; -+ -+ len += scnprintf(&buf[len], bufsz - len, "\nLast received rate\n" -+ " type rate LDPC STBC BEAMFM DCM DOPPLER %s\n", -+ (nrx > 1) ? "rssi1(dBm) rssi2(dBm)" : "rssi(dBm)"); -+ -+ fmt = last_rx->format_mod; -+ bw = last_rx->ch_bw; -+ pre = last_rx->pre_type; -+ if (fmt >= FORMATMOD_HE_SU) { -+ mcs = last_rx->he.mcs; -+ nss = last_rx->he.nss; -+ gi = last_rx->he.gi_type; -+ if (fmt == FORMATMOD_HE_MU) -+ bw = last_rx->he.ru_size; -+ } else if (fmt == FORMATMOD_VHT) { -+ mcs = last_rx->vht.mcs; -+ nss = last_rx->vht.nss; -+ gi = last_rx->vht.short_gi; -+ } else if (fmt >= FORMATMOD_HT_MF) { -+ mcs = last_rx->ht.mcs % 8; -+ nss = last_rx->ht.mcs / 8;; -+ gi = last_rx->ht.short_gi; -+ } else { -+ BUG_ON((mcs = legrates_lut[last_rx->leg_rate]) == -1); -+ nss = 0; -+ gi = 0; -+ } -+ -+ len += print_rate(&buf[len], bufsz - len, fmt, nss, mcs, bw, gi, pre, NULL); -+ -+ /* flags for HT/VHT/HE */ -+ if (fmt >= FORMATMOD_HE_SU) { -+ len += scnprintf(&buf[len], bufsz - len, " %c %c %c %c %c", -+ last_rx->he.fec ? 'L' : ' ', -+ last_rx->he.stbc ? 'S' : ' ', -+ last_rx->he.beamformed ? 'B' : ' ', -+ last_rx->he.dcm ? 'D' : ' ', -+ last_rx->he.doppler ? 'D' : ' '); -+ } else if (fmt == FORMATMOD_VHT) { -+ len += scnprintf(&buf[len], bufsz - len, " %c %c %c ", -+ last_rx->vht.fec ? 'L' : ' ', -+ last_rx->vht.stbc ? 'S' : ' ', -+ last_rx->vht.beamformed ? 'B' : ' '); -+ } else if (fmt >= FORMATMOD_HT_MF) { -+ len += scnprintf(&buf[len], bufsz - len, " %c %c ", -+ last_rx->ht.fec ? 'L' : ' ', -+ last_rx->ht.stbc ? 'S' : ' '); -+ } else { -+ len += scnprintf(&buf[len], bufsz - len, " "); -+ } -+ if (nrx > 1) { -+ len += scnprintf(&buf[len], bufsz - len, " %-4d %d\n", -+ last_rx->rssi1, last_rx->rssi1); -+ } else { -+ len += scnprintf(&buf[len], bufsz - len, " %d\n", last_rx->rssi1); -+ } -+ -+ read = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+ kfree(buf); -+ return read; -+} -+ -+static ssize_t rwnx_dbgfs_last_rx_write(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rwnx_sta *sta = NULL; -+ struct rwnx_hw *priv = file->private_data; -+ u8 mac[6]; -+ -+ /* Get the station index from MAC address */ -+ sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+// if (mac == NULL) -+// return 0; -+ sta = rwnx_get_sta(priv, mac); -+ if (sta == NULL) -+ return 0; -+ -+ /* Prevent from interrupt preemption as these statistics are updated under -+ * interrupt */ -+ spin_lock_bh(&priv->tx_lock); -+ memset(sta->stats.rx_rate.table, 0, -+ sta->stats.rx_rate.size * sizeof(sta->stats.rx_rate.table[0])); -+ sta->stats.rx_rate.cpt = 0; -+ sta->stats.rx_rate.rate_cnt = 0; -+ spin_unlock_bh(&priv->tx_lock); -+ -+ return count; -+} -+ -+DEBUGFS_READ_WRITE_FILE_OPS(last_rx); -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+#ifdef CONFIG_RWNX_FULLMAC -+static void rwnx_rc_stat_work(struct work_struct *ws) -+{ -+ struct rwnx_debugfs *rwnx_debugfs = container_of(ws, struct rwnx_debugfs, -+ rc_stat_work); -+ struct rwnx_hw *rwnx_hw = container_of(rwnx_debugfs, struct rwnx_hw, -+ debugfs); -+ struct rwnx_sta *sta; -+ uint8_t ridx, sta_idx; -+ -+ ridx = rwnx_debugfs->rc_read; -+ sta_idx = rwnx_debugfs->rc_sta[ridx]; -+ if (sta_idx > (NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX)) { -+ WARN(1, "Invalid sta index %d", sta_idx); -+ return; -+ } -+ -+ rwnx_debugfs->rc_sta[ridx] = 0xFF; -+ ridx = (ridx + 1) % ARRAY_SIZE(rwnx_debugfs->rc_sta); -+ rwnx_debugfs->rc_read = ridx; -+ sta = &rwnx_hw->sta_table[sta_idx]; -+ if (!sta) { -+ WARN(1, "Invalid sta %d", sta_idx); -+ return; -+ } -+ -+ if (rwnx_debugfs->dir_sta[sta_idx] == NULL) { -+ /* register the sta */ -+ struct dentry *dir_rc = rwnx_debugfs->dir_rc; -+ struct dentry *dir_sta; -+ struct dentry *file; -+ char sta_name[18]; -+ struct rwnx_rx_rate_stats *rate_stats = &sta->stats.rx_rate; -+ int nb_rx_rate = N_CCK + N_OFDM; -+ struct rwnx_rc_config_save *rc_cfg, *next; -+ -+ if (sta->sta_idx >= NX_REMOTE_STA_MAX) { -+ scnprintf(sta_name, sizeof(sta_name), "bc_mc"); -+ } else { -+ scnprintf(sta_name, sizeof(sta_name), "%pM", sta->mac_addr); -+ } -+ -+ dir_sta = debugfs_create_dir(sta_name, dir_rc); -+ if (!dir_sta) -+ goto error; -+ -+ rwnx_debugfs->dir_sta[sta->sta_idx] = dir_sta; -+ -+ file = debugfs_create_file("stats", S_IRUSR, dir_sta, rwnx_hw, -+ &rwnx_dbgfs_rc_stats_ops); -+ if (IS_ERR_OR_NULL(file)) -+ goto error_after_dir; -+ -+ file = debugfs_create_file("fixed_rate_idx", S_IWUSR, dir_sta, rwnx_hw, -+ &rwnx_dbgfs_rc_fixed_rate_idx_ops); -+ if (IS_ERR_OR_NULL(file)) -+ goto error_after_dir; -+ -+ file = debugfs_create_file("rx_rate", S_IRUSR | S_IWUSR, dir_sta, rwnx_hw, -+ &rwnx_dbgfs_last_rx_ops); -+ if (IS_ERR_OR_NULL(file)) -+ goto error_after_dir; -+ -+ if (rwnx_hw->mod_params->ht_on) -+ nb_rx_rate += N_HT; -+ -+ if (rwnx_hw->mod_params->vht_on) -+ nb_rx_rate += N_VHT; -+ -+ if (rwnx_hw->mod_params->he_on) -+ nb_rx_rate += N_HE_SU + N_HE_MU; -+ -+ rate_stats->table = kzalloc(nb_rx_rate * sizeof(rate_stats->table[0]), -+ GFP_KERNEL); -+ if (!rate_stats->table) -+ goto error_after_dir; -+ -+ rate_stats->size = nb_rx_rate; -+ rate_stats->cpt = 0; -+ rate_stats->rate_cnt = 0; -+ -+ /* By default enable rate contoller */ -+ rwnx_debugfs->rc_config[sta_idx] = -1; -+ -+ /* Unless we already fix the rate for this station */ -+ list_for_each_entry_safe(rc_cfg, next, &rwnx_debugfs->rc_config_save, list) { -+ if (jiffies_to_msecs(jiffies - rc_cfg->timestamp) > RC_CONFIG_DUR) { -+ list_del(&rc_cfg->list); -+ kfree(rc_cfg); -+ } else if (!memcmp(rc_cfg->mac_addr, sta->mac_addr, ETH_ALEN)) { -+ rwnx_debugfs->rc_config[sta_idx] = rc_cfg->rate; -+ list_del(&rc_cfg->list); -+ kfree(rc_cfg); -+ break; -+ } -+ } -+ -+ if ((rwnx_debugfs->rc_config[sta_idx] >= 0) && -+ rwnx_send_me_rc_set_rate(rwnx_hw, sta_idx, -+ (u16)rwnx_debugfs->rc_config[sta_idx])) -+ rwnx_debugfs->rc_config[sta_idx] = -1; -+ -+ } else { -+ /* unregister the sta */ -+ if (sta->stats.rx_rate.table) { -+ kfree(sta->stats.rx_rate.table); -+ sta->stats.rx_rate.table = NULL; -+ } -+ sta->stats.rx_rate.size = 0; -+ sta->stats.rx_rate.cpt = 0; -+ sta->stats.rx_rate.rate_cnt = 0; -+ -+ /* If fix rate was set for this station, save the configuration in case -+ we reconnect to this station within RC_CONFIG_DUR msec */ -+ if (rwnx_debugfs->rc_config[sta_idx] >= 0) { -+ struct rwnx_rc_config_save *rc_cfg; -+ rc_cfg = kmalloc(sizeof(*rc_cfg), GFP_KERNEL); -+ if (rc_cfg) { -+ rc_cfg->rate = rwnx_debugfs->rc_config[sta_idx]; -+ rc_cfg->timestamp = jiffies; -+ memcpy(rc_cfg->mac_addr, sta->mac_addr, ETH_ALEN); -+ list_add_tail(&rc_cfg->list, &rwnx_debugfs->rc_config_save); -+ } -+ } -+ -+ debugfs_remove_recursive(rwnx_debugfs->dir_sta[sta_idx]); -+ rwnx_debugfs->dir_sta[sta->sta_idx] = NULL; -+ } -+ -+ return; -+ -+error_after_dir: -+ debugfs_remove_recursive(rwnx_debugfs->dir_sta[sta_idx]); -+ rwnx_debugfs->dir_sta[sta->sta_idx] = NULL; -+error: -+ dev_err(rwnx_hw->dev, -+ "Error while (un)registering debug entry for sta %d\n", sta_idx); -+} -+ -+void _rwnx_dbgfs_rc_stat_write(struct rwnx_debugfs *rwnx_debugfs, uint8_t sta_idx) -+{ -+ uint8_t widx = rwnx_debugfs->rc_write; -+ if (rwnx_debugfs->rc_sta[widx] != 0XFF) { -+ WARN(1, "Overlap in debugfs rc_sta table\n"); -+ } -+ -+ if (rwnx_debugfs->unregistering) -+ return; -+ -+ rwnx_debugfs->rc_sta[widx] = sta_idx; -+ widx = (widx + 1) % ARRAY_SIZE(rwnx_debugfs->rc_sta); -+ rwnx_debugfs->rc_write = widx; -+ -+ schedule_work(&rwnx_debugfs->rc_stat_work); -+} -+ -+void rwnx_dbgfs_register_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) -+{ -+ _rwnx_dbgfs_rc_stat_write(&rwnx_hw->debugfs, sta->sta_idx); -+} -+ -+void rwnx_dbgfs_unregister_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) -+{ -+ _rwnx_dbgfs_rc_stat_write(&rwnx_hw->debugfs, sta->sta_idx); -+} -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+int rwnx_dbgfs_register(struct rwnx_hw *rwnx_hw, const char *name) -+{ -+#ifdef CONFIG_RWNX_FULLMAC -+ struct dentry *phyd = rwnx_hw->wiphy->debugfsdir; -+ struct dentry *dir_rc; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ struct rwnx_debugfs *rwnx_debugfs = &rwnx_hw->debugfs; -+ struct dentry *dir_drv, *dir_diags; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ dir_drv = debugfs_create_dir(name, phyd); -+ if (!dir_drv) -+ return -ENOMEM; -+ -+ rwnx_debugfs->dir = dir_drv; -+ rwnx_debugfs->unregistering = false; -+ -+ dir_diags = debugfs_create_dir("diags", dir_drv); -+ if (!dir_diags) -+ goto err; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ dir_rc = debugfs_create_dir("rc", dir_drv); -+ if (!dir_rc) -+ goto err; -+ rwnx_debugfs->dir_rc = dir_rc; -+ INIT_WORK(&rwnx_debugfs->rc_stat_work, rwnx_rc_stat_work); -+ INIT_LIST_HEAD(&rwnx_debugfs->rc_config_save); -+ rwnx_debugfs->rc_write = rwnx_debugfs->rc_read = 0; -+ memset(rwnx_debugfs->rc_sta, 0xFF, sizeof(rwnx_debugfs->rc_sta)); -+#endif -+ -+ DEBUGFS_ADD_U32(tcp_pacing_shift, dir_drv, &rwnx_hw->tcp_pacing_shift, -+ S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(stats, dir_drv, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(sys_stats, dir_drv, S_IRUSR); -+ DEBUGFS_ADD_FILE(txq, dir_drv, S_IRUSR); -+ DEBUGFS_ADD_FILE(acsinfo, dir_drv, S_IRUSR); -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ DEBUGFS_ADD_FILE(mu_group, dir_drv, S_IRUSR); -+#endif -+ DEBUGFS_ADD_FILE(regdbg, dir_drv, S_IWUSR); -+ DEBUGFS_ADD_FILE(vendor_hwconfig, dir_drv,S_IWUSR); -+ DEBUGFS_ADD_FILE(vendor_swconfig, dir_drv,S_IWUSR); -+ DEBUGFS_ADD_FILE(agg_disable, dir_drv,S_IWUSR); -+ DEBUGFS_ADD_FILE(set_roc, dir_drv,S_IWUSR); -+ -+#ifdef CONFIG_RWNX_P2P_DEBUGFS -+ { -+ /* Create a p2p directory */ -+ struct dentry *dir_p2p; -+ dir_p2p = debugfs_create_dir("p2p", dir_drv); -+ if (!dir_p2p) -+ goto err; -+ -+ /* Add file allowing to control Opportunistic PS */ -+ DEBUGFS_ADD_FILE(oppps, dir_p2p, S_IRUSR); -+ /* Add file allowing to control Notice of Absence */ -+ DEBUGFS_ADD_FILE(noa, dir_p2p, S_IRUSR); -+ } -+#endif /* CONFIG_RWNX_P2P_DEBUGFS */ -+ -+ if (rwnx_hw->fwlog_en) { -+ rwnx_fw_log_init(&rwnx_hw->debugfs.fw_log); -+ DEBUGFS_ADD_FILE(fw_log, dir_drv, S_IWUSR | S_IRUSR); -+ } -+#ifdef CONFIG_RWNX_RADAR -+ { -+ struct dentry *dir_radar, *dir_sec; -+ dir_radar = debugfs_create_dir("radar", dir_drv); -+ if (!dir_radar) -+ goto err; -+ -+ DEBUGFS_ADD_FILE(pulses_prim, dir_radar, S_IRUSR); -+ DEBUGFS_ADD_FILE(detected, dir_radar, S_IRUSR); -+ DEBUGFS_ADD_FILE(enable, dir_radar, S_IRUSR); -+ -+ if (rwnx_hw->phy.cnt == 2) { -+ DEBUGFS_ADD_FILE(pulses_sec, dir_radar, S_IRUSR); -+ -+ dir_sec = debugfs_create_dir("sec", dir_radar); -+ if (!dir_sec) -+ goto err; -+ -+ DEBUGFS_ADD_FILE(band, dir_sec, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(type, dir_sec, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(prim20, dir_sec, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(center1, dir_sec, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(center2, dir_sec, S_IWUSR | S_IRUSR); -+ DEBUGFS_ADD_FILE(set, dir_sec, S_IWUSR | S_IRUSR); -+ } -+ } -+#endif /* CONFIG_RWNX_RADAR */ -+ return 0; -+ -+err: -+ rwnx_dbgfs_unregister(rwnx_hw); -+ return -ENOMEM; -+} -+ -+void rwnx_dbgfs_unregister(struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_debugfs *rwnx_debugfs = &rwnx_hw->debugfs; -+#ifdef CONFIG_RWNX_FULLMAC -+ struct rwnx_rc_config_save *cfg, *next; -+#endif -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ list_for_each_entry_safe(cfg, next, &rwnx_debugfs->rc_config_save, list) { -+ list_del(&cfg->list); -+ kfree(cfg); -+ } -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ if (rwnx_hw->fwlog_en) -+ rwnx_fw_log_deinit(&rwnx_hw->debugfs.fw_log); -+ -+ if (!rwnx_hw->debugfs.dir) -+ return; -+ -+ rwnx_debugfs->unregistering = true; -+#ifdef CONFIG_RWNX_FULLMAC -+ flush_work(&rwnx_debugfs->rc_stat_work); -+#endif -+ debugfs_remove_recursive(rwnx_hw->debugfs.dir); -+ rwnx_hw->debugfs.dir = NULL; -+} -+ -+#endif /* CONFIG_DEBUG_FS */ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_debugfs.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_debugfs.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_debugfs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_debugfs.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,202 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_debugfs.h -+ * -+ * @brief Miscellaneous utility function definitions -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+ -+#ifndef _RWNX_DEBUGFS_H_ -+#define _RWNX_DEBUGFS_H_ -+#include -+ -+#include -+#include -+#include "rwnx_fw_trace.h" -+ -+struct rwnx_hw; -+struct rwnx_sta; -+ -+/* some macros taken from iwlwifi */ -+/* TODO: replace with generic read and fill read buffer in open to avoid double -+ * reads */ -+#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ -+ if (!debugfs_create_file(#name, mode, parent, rwnx_hw, \ -+ &rwnx_dbgfs_##name##_ops)) \ -+ goto err; \ -+} while (0) -+ -+#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ -+ struct dentry *__tmp; \ -+ __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ -+ parent, ptr); \ -+ if (IS_ERR(__tmp) || !__tmp) \ -+ goto err; \ -+} while (0) -+ -+#define DEBUGFS_ADD_X64(name, parent, ptr) do { \ -+ struct dentry *__tmp; \ -+ __tmp = debugfs_create_x64(#name, S_IWUSR | S_IRUSR, \ -+ parent, ptr); \ -+ if (IS_ERR(__tmp) || !__tmp) \ -+ goto err; \ -+} while (0) -+ -+#define DEBUGFS_ADD_U64(name, parent, ptr, mode) do { \ -+ struct dentry *__tmp; \ -+ __tmp = debugfs_create_u64(#name, mode, \ -+ parent, ptr); \ -+ if (IS_ERR(__tmp) || !__tmp) \ -+ goto err; \ -+} while (0) -+ -+#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ -+ struct dentry *__tmp; \ -+ __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \ -+ parent, ptr); \ -+ if (IS_ERR(__tmp) || !__tmp) \ -+ goto err; \ -+} while (0) -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) -+#define DEBUGFS_ADD_U32(name, parent, ptr, mode) do { \ -+ debugfs_create_u32(#name, mode, \ -+ parent, ptr); \ -+} while (0) -+#else -+#define DEBUGFS_ADD_U32(name, parent, ptr, mode) do { \ -+ struct dentry *__tmp; \ -+ __tmp = debugfs_create_u32(#name, mode, \ -+ parent, ptr); \ -+ if (IS_ERR(__tmp) || !__tmp) \ -+ goto err; \ -+ } while (0) -+#endif -+ -+ -+ -+/* file operation */ -+#define DEBUGFS_READ_FUNC(name) \ -+ static ssize_t rwnx_dbgfs_##name##_read(struct file *file, \ -+ char __user *user_buf, \ -+ size_t count, loff_t *ppos); -+ -+#define DEBUGFS_WRITE_FUNC(name) \ -+ static ssize_t rwnx_dbgfs_##name##_write(struct file *file, \ -+ const char __user *user_buf,\ -+ size_t count, loff_t *ppos); -+ -+#define DEBUGFS_OPEN_FUNC(name) \ -+ static int rwnx_dbgfs_##name##_open(struct inode *inode, \ -+ struct file *file); -+ -+#define DEBUGFS_RELEASE_FUNC(name) \ -+ static int rwnx_dbgfs_##name##_release(struct inode *inode, \ -+ struct file *file); -+ -+#define DEBUGFS_READ_FILE_OPS(name) \ -+ DEBUGFS_READ_FUNC(name); \ -+static const struct file_operations rwnx_dbgfs_##name##_ops = { \ -+ .read = rwnx_dbgfs_##name##_read, \ -+ .open = simple_open, \ -+ .llseek = generic_file_llseek, \ -+}; -+ -+#define DEBUGFS_WRITE_FILE_OPS(name) \ -+ DEBUGFS_WRITE_FUNC(name); \ -+static const struct file_operations rwnx_dbgfs_##name##_ops = { \ -+ .write = rwnx_dbgfs_##name##_write, \ -+ .open = simple_open, \ -+ .llseek = generic_file_llseek, \ -+}; -+ -+#define DEBUGFS_READ_WRITE_FILE_OPS(name) \ -+ DEBUGFS_READ_FUNC(name); \ -+ DEBUGFS_WRITE_FUNC(name); \ -+static const struct file_operations rwnx_dbgfs_##name##_ops = { \ -+ .write = rwnx_dbgfs_##name##_write, \ -+ .read = rwnx_dbgfs_##name##_read, \ -+ .open = simple_open, \ -+ .llseek = generic_file_llseek, \ -+}; -+ -+#define DEBUGFS_READ_WRITE_OPEN_RELEASE_FILE_OPS(name) \ -+ DEBUGFS_READ_FUNC(name); \ -+ DEBUGFS_WRITE_FUNC(name); \ -+ DEBUGFS_OPEN_FUNC(name); \ -+ DEBUGFS_RELEASE_FUNC(name); \ -+static const struct file_operations rwnx_dbgfs_##name##_ops = { \ -+ .write = rwnx_dbgfs_##name##_write, \ -+ .read = rwnx_dbgfs_##name##_read, \ -+ .open = rwnx_dbgfs_##name##_open, \ -+ .release = rwnx_dbgfs_##name##_release, \ -+ .llseek = generic_file_llseek, \ -+}; -+ -+ -+#ifdef CONFIG_RWNX_DEBUGFS -+ -+struct rwnx_debugfs { -+ unsigned long long rateidx; -+ struct dentry *dir; -+ bool trace_prst; -+ -+ char helper_cmd[64]; -+ //struct work_struct helper_work; -+ bool helper_scheduled; -+ spinlock_t umh_lock; -+ bool unregistering; -+ -+#ifndef CONFIG_RWNX_FHOST -+ struct rwnx_fw_log fw_log; -+#endif /* CONFIG_RWNX_FHOST */ -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ struct work_struct rc_stat_work; -+ uint8_t rc_sta[NX_REMOTE_STA_MAX]; -+ uint8_t rc_write; -+ uint8_t rc_read; -+ struct dentry *dir_rc; -+ struct dentry *dir_sta[NX_REMOTE_STA_MAX]; -+ int rc_config[NX_REMOTE_STA_MAX]; -+ struct list_head rc_config_save; -+#endif -+}; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+// Max duration in msecs to save rate config for a sta after disconnection -+#define RC_CONFIG_DUR 600000 -+ -+struct rwnx_rc_config_save { -+ struct list_head list; -+ unsigned long timestamp; -+ int rate; -+ u8 mac_addr[ETH_ALEN]; -+}; -+#endif -+ -+int rwnx_dbgfs_register(struct rwnx_hw *rwnx_hw, const char *name); -+void rwnx_dbgfs_unregister(struct rwnx_hw *rwnx_hw); -+#ifdef CONFIG_RWNX_FULLMAC -+void rwnx_dbgfs_register_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta); -+void rwnx_dbgfs_unregister_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta); -+#endif -+#else -+struct rwnx_debugfs { -+}; -+static inline int rwnx_dbgfs_register(struct rwnx_hw *rwnx_hw, const char *name) { return 0; } -+static inline void rwnx_dbgfs_unregister(struct rwnx_hw *rwnx_hw) {} -+#ifdef CONFIG_RWNX_FULLMAC -+static inline void rwnx_dbgfs_register_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) {} -+static inline void rwnx_dbgfs_unregister_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) {} -+#endif -+#endif /* CONFIG_RWNX_DEBUGFS */ -+ -+ -+#endif /* _RWNX_DEBUGFS_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_defs.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_defs.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_defs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_defs.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,746 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_defs.h -+ * -+ * @brief Main driver structure declarations for fullmac driver -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _RWNX_DEFS_H_ -+#define _RWNX_DEFS_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "rwnx_mod_params.h" -+#include "rwnx_debugfs.h" -+#include "rwnx_tx.h" -+#include "rwnx_rx.h" -+#include "rwnx_radar.h" -+#include "rwnx_utils.h" -+#include "rwnx_mu_group.h" -+#include "rwnx_platform.h" -+#include "rwnx_cmds.h" -+#ifdef CONFIG_GKI -+#include "rwnx_gki.h" -+#endif -+#include "rwnx_compat.h" -+#ifdef CONFIG_FILTER_TCP_ACK -+#include "aicwf_tcp_ack.h" -+#endif -+ -+#ifdef AICWF_SDIO_SUPPORT -+#include "aicwf_sdio.h" -+#include "sdio_host.h" -+#endif -+ -+#ifdef AICWF_USB_SUPPORT -+#include "usb_host.h" -+#endif -+ -+#ifdef CONFIG_BR_SUPPORT -+#include "aic_br_ext.h" -+#endif /* CONFIG_BR_SUPPORT */ -+ -+#define WPI_HDR_LEN 18 -+#define WPI_PN_LEN 16 -+#define WPI_PN_OFST 2 -+#define WPI_MIC_LEN 16 -+#define WPI_KEY_LEN 32 -+#define WPI_SUBKEY_LEN 16 // WPI key is actually two 16bytes key -+ -+#define LEGACY_PS_ID 0 -+#define UAPSD_ID 1 -+ -+#define PS_SP_INTERRUPTED 255 -+#define MAC_ADDR_LEN 6 -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) -+enum nl80211_ac { -+ NL80211_AC_VO, -+ NL80211_AC_VI, -+ NL80211_AC_BE, -+ NL80211_AC_BK, -+ NL80211_NUM_ACS -+}; -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) -+struct ieee80211_vht_operation { -+ u8 vht_op_info_chwidth; -+ u8 vht_op_info_chan_center_freq_seg1_idx; -+ u8 vht_op_info_chan_center_freq_seg2_idx; -+ __le16 vht_basic_mcs_set; -+} __packed; -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) -+#define IEEE80211_RADIOTAP_VHT 21 -+#define IEEE80211_RADIOTAP_VHT_KNOWN_GI 0x0004 -+#define IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH 0x0040 -+ -+#define IEEE80211_RADIOTAP_VHT_FLAG_STBC 0x01 -+#define IEEE80211_RADIOTAP_VHT_FLAG_SGI 0x04 -+ -+#define NL80211_FEATURE_CELL_BASE_REG_HINTS 1 << 3 -+#define NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL 1 << 4 -+#define NL80211_FEATURE_SAE 1 << 5 -+#define NL80211_FEATURE_LOW_PRIORITY_SCAN 1 << 6 -+#define NL80211_FEATURE_SCAN_FLUSH 1 << 7 -+#define NL80211_FEATURE_AP_SCAN 1 << 8 -+#define NL80211_FEATURE_VIF_TXPOWER 1 << 9 -+#define NL80211_FEATURE_NEED_OBSS_SCAN 1 << 10 -+#define NL80211_FEATURE_P2P_GO_CTWIN 1 << 11 -+#define NL80211_FEATURE_P2P_GO_OPPPS 1 << 12 -+ -+/* 802.11ac VHT Capabilities */ -+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x00000000 -+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 0x00000001 -+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 0x00000002 -+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ 0x00000004 -+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ 0x00000008 -+#define IEEE80211_VHT_CAP_RXLDPC 0x00000010 -+#define IEEE80211_VHT_CAP_SHORT_GI_80 0x00000020 -+#define IEEE80211_VHT_CAP_SHORT_GI_160 0x00000040 -+#define IEEE80211_VHT_CAP_TXSTBC 0x00000080 -+#define IEEE80211_VHT_CAP_RXSTBC_1 0x00000100 -+#define IEEE80211_VHT_CAP_RXSTBC_2 0x00000200 -+#define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300 -+#define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400 -+#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 -+#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 -+#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000 -+#define IEEE80211_VHT_CAP_SOUNDING_DIMENTION_MAX 0x00030000 -+#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000 -+#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000 -+#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000 -+#define IEEE80211_VHT_CAP_HTC_VHT 0x00400000 -+#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT 23 -+#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \ -+ (7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT) -+#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB 0x08000000 -+#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB 0x0c000000 -+#define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN 0x10000000 -+#define IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN 0x20000000 -+ -+enum ieee80211_vht_mcs_support { -+ IEEE80211_VHT_MCS_SUPPORT_0_7 = 0, -+ IEEE80211_VHT_MCS_SUPPORT_0_8 = 1, -+ IEEE80211_VHT_MCS_SUPPORT_0_9 = 2, -+ IEEE80211_VHT_MCS_NOT_SUPPORTED = 3, -+}; -+ -+enum nl80211_chan_width { -+ NL80211_CHAN_WIDTH_20_NOHT, -+ NL80211_CHAN_WIDTH_20, -+ NL80211_CHAN_WIDTH_40, -+ NL80211_CHAN_WIDTH_80, -+ NL80211_CHAN_WIDTH_80P80, -+ NL80211_CHAN_WIDTH_160, -+}; -+ -+struct cfg80211_chan_def { -+ struct ieee80211_channel *chan; -+ enum nl80211_chan_width width; -+ u32 center_freq1; -+ u32 center_freq2; -+}; -+ -+enum nl80211_mesh_power_mode { -+ NL80211_MESH_POWER_UNKNOWN, -+ NL80211_MESH_POWER_ACTIVE, -+ NL80211_MESH_POWER_LIGHT_SLEEP, -+ NL80211_MESH_POWER_DEEP_SLEEP, -+ __NL80211_MESH_POWER_AFTER_LAST, -+ NL80211_MESH_POWER_MAX = __NL80211_MESH_POWER_AFTER_LAST - 1 -+}; -+#endif -+ -+/** -+ * struct rwnx_bcn - Information of the beacon in used (AP mode) -+ * -+ * @head: head portion of beacon (before TIM IE) -+ * @tail: tail portion of beacon (after TIM IE) -+ * @ies: extra IEs (not used ?) -+ * @head_len: length of head data -+ * @tail_len: length of tail data -+ * @ies_len: length of extra IEs data -+ * @tim_len: length of TIM IE -+ * @len: Total beacon len (head + tim + tail + extra) -+ * @dtim: dtim period -+ */ -+struct rwnx_bcn { -+ u8 *head; -+ u8 *tail; -+ u8 *ies; -+ size_t head_len; -+ size_t tail_len; -+ size_t ies_len; -+ size_t tim_len; -+ size_t len; -+ u8 dtim; -+}; -+ -+/** -+ * struct rwnx_key - Key information -+ * -+ * @hw_idx: Idx of the key from hardware point of view -+ */ -+struct rwnx_key { -+ u8 hw_idx; -+}; -+ -+/** -+ * Structure containing information about a Mesh Path -+ */ -+struct rwnx_mesh_path { -+ struct list_head list; /* For rwnx_vif.mesh_paths */ -+ u8 path_idx; /* Path Index */ -+ struct mac_addr tgt_mac_addr; /* Target MAC Address */ -+ struct rwnx_sta *p_nhop_sta; /* Pointer to the Next Hop STA */ -+}; -+ -+struct rwnx_mesh_proxy { -+ struct list_head list; /* For rwnx_vif.mesh_proxy */ -+ struct mac_addr ext_sta_addr; /* Address of the External STA */ -+ struct mac_addr proxy_addr; /* Proxy MAC Address */ -+ bool local; /* Indicate if interface is a proxy for the device */ -+}; -+ -+/** -+ * struct rwnx_csa - Information for CSA (Channel Switch Announcement) -+ * -+ * @vif: Pointer to the vif doing the CSA -+ * @bcn: Beacon to use after CSA -+ * @elem: IPC buffer to send the new beacon to the fw -+ * @chandef: defines the channel to use after the switch -+ * @count: Current csa counter -+ * @status: Status of the CSA at fw level -+ * @ch_idx: Index of the new channel context -+ * @work: work scheduled at the end of CSA -+ */ -+struct rwnx_csa { -+ struct rwnx_vif *vif; -+ struct rwnx_bcn bcn; -+ struct rwnx_ipc_elem_var elem; -+ struct cfg80211_chan_def chandef; -+ int count; -+ int status; -+ int ch_idx; -+ struct work_struct work; -+}; -+ -+struct apm_probe_sta { -+ u8 sta_mac_addr[6]; -+ u8 vif_idx; -+ u64 probe_id; -+ struct work_struct apmprobestaWork; -+ struct workqueue_struct *apmprobesta_wq; -+}; -+/// Possible States of the TDLS link. -+enum tdls_status_tag { -+ /// TDLS link is not active (no TDLS peer connected) -+ TDLS_LINK_IDLE, -+ /// TDLS Setup Request transmitted -+ TDLS_SETUP_REQ_TX, -+ /// TDLS Setup Response transmitted -+ TDLS_SETUP_RSP_TX, -+ /// TDLS link is active (TDLS peer connected) -+ TDLS_LINK_ACTIVE, -+ /// TDLS Max Number of states. -+ TDLS_STATE_MAX -+}; -+ -+/* -+ * Structure used to save information relative to the TDLS peer. -+ * This is also linked within the rwnx_hw vifs list. -+ * -+ */ -+struct rwnx_tdls { -+ bool active; /* Indicate if TDLS link is active */ -+ bool initiator; /* Indicate if TDLS peer is the TDLS initiator */ -+ bool chsw_en; /* Indicate if channel switch is enabled */ -+ u8 last_tid; /* TID of the latest MPDU transmitted over the -+ TDLS direct link to the TDLS STA */ -+ u16 last_sn; /* Sequence number of the latest MPDU transmitted -+ over the TDLS direct link to the TDLS STA */ -+ bool ps_on; /* Indicate if the power save is enabled on the -+ TDLS STA */ -+ bool chsw_allowed; /* Indicate if TDLS channel switch is allowed */ -+}; -+ -+ -+/** -+ * enum rwnx_ap_flags - AP flags -+ * -+ * @RWNX_AP_ISOLATE Isolate clients (i.e. Don't brige packets transmitted by -+ * one client for another one) -+ */ -+enum rwnx_ap_flags { -+ RWNX_AP_ISOLATE = BIT(0), -+}; -+ -+/* -+ * Structure used to save information relative to the managed interfaces. -+ * This is also linked within the rwnx_hw vifs list. -+ * -+ */ -+struct rwnx_vif { -+ struct list_head list; -+ struct rwnx_hw *rwnx_hw; -+ struct wireless_dev wdev; -+ struct net_device *ndev; -+ struct net_device_stats net_stats; -+ struct rwnx_key key[6]; -+ unsigned long drv_flags; -+ atomic_t drv_conn_state; -+ u8 drv_vif_index; /* Identifier of the VIF in driver */ -+ u8 vif_index; /* Identifier of the station in FW */ -+ u8 ch_index; /* Channel context identifier */ -+ bool up; /* Indicate if associated netdev is up -+ (i.e. Interface is created at fw level) */ -+ bool use_4addr; /* Should we use 4addresses mode */ -+ bool is_resending; /* Indicate if a frame is being resent on this interface */ -+ bool user_mpm; /* In case of Mesh Point VIF, indicate if MPM is handled by userspace */ -+ bool roc_tdls; /* Indicate if the ROC has been called by a -+ TDLS station */ -+ u8 tdls_status; /* Status of the TDLS link */ -+ bool tdls_chsw_prohibited; /* Indicate if TDLS Channel Switch is prohibited */ -+ bool wep_enabled; /* 1 if WEP is enabled */ -+ bool wep_auth_err; /* 1 if auth status code is not supported auth alg when WEP enabled */ -+ enum nl80211_auth_type last_auth_type; /* Authentication type (algorithm) sent in the last connection -+ when WEP enabled */ -+ union { -+ struct { -+ struct rwnx_sta *ap; /* Pointer to the peer STA entry allocated for -+ the AP */ -+ struct rwnx_sta *tdls_sta; /* Pointer to the TDLS station */ -+ bool external_auth; /* Indicate if external authentication is in progress */ -+ u32 group_cipher_type; -+ u32 paired_cipher_type; -+ //connected network info start -+ char ssid[33];//ssid max is 32, but this has one spare for '\0' -+ int ssid_len; -+ u8 bssid[ETH_ALEN]; -+ u32 conn_owner_nlportid; -+ bool is_roam; -+ //connected network info end -+ } sta; -+ struct { -+ u16 flags; /* see rwnx_ap_flags */ -+ struct list_head sta_list; /* List of STA connected to the AP */ -+ struct rwnx_bcn bcn; /* beacon */ -+ u8 bcmc_index; /* Index of the BCMC sta to use */ -+#if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL) -+ u8 aic_index; -+#endif -+ struct rwnx_csa *csa; -+ -+ struct list_head mpath_list; /* List of Mesh Paths used on this interface */ -+ struct list_head proxy_list; /* List of Proxies Information used on this interface */ -+ bool create_path; /* Indicate if we are waiting for a MESH_CREATE_PATH_CFM -+ message */ -+ int generation; /* Increased each time the list of Mesh Paths is updated */ -+ enum nl80211_mesh_power_mode mesh_pm; /* mesh power save mode currently set in firmware */ -+ enum nl80211_mesh_power_mode next_mesh_pm; /* mesh power save mode for next peer */ -+ } ap; -+ struct { -+ struct rwnx_vif *master; /* pointer on master interface */ -+ struct rwnx_sta *sta_4a; -+ } ap_vlan; -+ }; -+ -+ u8_l key_has_add; -+ u8_l is_p2p_vif; -+ struct apm_probe_sta sta_probe; -+ -+ #ifdef CONFIG_BR_SUPPORT -+ spinlock_t br_ext_lock; -+ /* unsigned int macclone_completed; */ -+ struct nat25_network_db_entry *nethash[NAT25_HASH_SIZE]; -+ int pppoe_connection_in_progress; -+ unsigned char pppoe_addr[MACADDRLEN]; -+ unsigned char scdb_mac[MACADDRLEN]; -+ unsigned char scdb_ip[4]; -+ struct nat25_network_db_entry *scdb_entry; -+ unsigned char br_mac[MACADDRLEN]; -+ unsigned char br_ip[4]; -+ -+ struct br_ext_info ethBrExtInfo; -+ #endif /* CONFIG_BR_SUPPORT */ -+}; -+ -+#define RWNX_VIF_TYPE(rwnx_vif) (rwnx_vif->wdev.iftype) -+ -+/** -+ * Structure used to store information relative to PS mode. -+ * -+ * @active: True when the sta is in PS mode. -+ * If false, other values should be ignored -+ * @pkt_ready: Number of packets buffered for the sta in drv's txq -+ * (1 counter for Legacy PS and 1 for U-APSD) -+ * @sp_cnt: Number of packets that remain to be pushed in the service period. -+ * 0 means that no service period is in progress -+ * (1 counter for Legacy PS and 1 for U-APSD) -+ */ -+struct rwnx_sta_ps { -+ bool active; -+ u16 pkt_ready[2]; -+ u16 sp_cnt[2]; -+}; -+ -+/** -+ * struct rwnx_rx_rate_stats - Store statistics for RX rates -+ * -+ * @table: Table indicating how many frame has been receive which each -+ * rate index. Rate index is the same as the one used by RC algo for TX -+ * @size: Size of the table array -+ * @cpt: number of frames received -+ */ -+struct rwnx_rx_rate_stats { -+ int *table; -+ int size; -+ int cpt; -+ int rate_cnt; -+}; -+ -+/** -+ * struct rwnx_sta_stats - Structure Used to store statistics specific to a STA -+ * -+ * @last_rx: Hardware vector of the last received frame -+ * @rx_rate: Statistics of the received rates -+ */ -+struct rwnx_sta_stats { -+ struct hw_vect last_rx; -+ struct rwnx_rx_rate_stats rx_rate; -+}; -+ -+#if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL) -+struct aic_sta { -+ u8 sta_idx; /* Identifier of the station */ -+ bool he; /* Flag indicating if the station supports HE */ -+ bool vht; /* Flag indicating if the station supports VHT */ -+}; -+#endif -+ -+/* -+ * Structure used to save information relative to the managed stations. -+ */ -+struct rwnx_sta { -+ struct list_head list; -+ u16 aid; /* association ID */ -+ u8 sta_idx; /* Identifier of the station */ -+ u8 vif_idx; /* Identifier of the VIF (fw id) the station -+ belongs to */ -+ u8 vlan_idx; /* Identifier of the VLAN VIF (fw id) the station -+ belongs to (= vif_idx if no vlan in used) */ -+ enum nl80211_band band; /* Band */ -+ enum nl80211_chan_width width; /* Channel width */ -+ u16 center_freq; /* Center frequency */ -+ u32 center_freq1; /* Center frequency 1 */ -+ u32 center_freq2; /* Center frequency 2 */ -+ u8 ch_idx; /* Identifier of the channel -+ context the station belongs to */ -+ bool qos; /* Flag indicating if the station -+ supports QoS */ -+ u8 acm; /* Bitfield indicating which queues -+ have AC mandatory */ -+ u16 uapsd_tids; /* Bitfield indicating which tids are subject to -+ UAPSD */ -+ u8 mac_addr[ETH_ALEN]; /* MAC address of the station */ -+ struct rwnx_key key; -+ bool valid; /* Flag indicating if the entry is valid */ -+ struct rwnx_sta_ps ps; /* Information when STA is in PS (AP only) */ -+#ifdef CONFIG_RWNX_BFMER -+ struct rwnx_bfmer_report *bfm_report; /* Beamforming report to be used for -+ VHT TX Beamforming */ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ struct rwnx_sta_group_info group_info; /* MU grouping information for the STA */ -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+#endif /* CONFIG_RWNX_BFMER */ -+ -+ bool ht; /* Flag indicating if the station -+ supports HT */ -+ bool vht; /* Flag indicating if the station -+ supports VHT */ -+ u32 ac_param[AC_MAX]; /* EDCA parameters */ -+ struct rwnx_tdls tdls; /* TDLS station information */ -+ struct rwnx_sta_stats stats; -+ enum nl80211_mesh_power_mode mesh_pm; /* link-specific mesh power save mode */ -+}; -+ -+static inline const u8 *rwnx_sta_addr(struct rwnx_sta *rwnx_sta) -+{ -+ return rwnx_sta->mac_addr; -+} -+ -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+struct rwnx_amsdu_stats { -+ int done; -+ int failed; -+}; -+#endif -+ -+struct rwnx_stats { -+ int cfm_balance[NX_TXQ_CNT]; -+ unsigned long last_rx, last_tx; /* jiffies */ -+ int ampdus_tx[IEEE80211_MAX_AMPDU_BUF]; -+ int ampdus_rx[IEEE80211_MAX_AMPDU_BUF]; -+ int ampdus_rx_map[4]; -+ int ampdus_rx_miss; -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ struct rwnx_amsdu_stats amsdus[NX_TX_PAYLOAD_MAX]; -+#endif -+ int amsdus_rx[64]; -+}; -+ -+struct rwnx_sec_phy_chan { -+ u16 prim20_freq; -+ u16 center_freq1; -+ u16 center_freq2; -+ enum nl80211_band band; -+ u8 type; -+}; -+ -+/* Structure that will contains all RoC information received from cfg80211 */ -+struct rwnx_roc_elem { -+ struct wireless_dev *wdev; -+ struct ieee80211_channel *chan; -+ unsigned int duration; -+ /* Used to avoid call of CFG80211 callback upon expiration of RoC */ -+ bool mgmt_roc; -+ /* Indicate if we have switch on the RoC channel */ -+ bool on_chan; -+}; -+ -+/* Structure containing channel survey information received from MAC */ -+struct rwnx_survey_info { -+ // Filled -+ u32 filled; -+ // Amount of time in ms the radio spent on the channel -+ u32 chan_time_ms; -+ // Amount of time the primary channel was sensed busy -+ u32 chan_time_busy_ms; -+ // Noise in dbm -+ s8 noise_dbm; -+}; -+ -+#define RWNX_CH_NOT_SET 0xFF -+#define RWNX_INVALID_VIF 0xFF -+#define RWNX_INVALID_STA 0xFF -+ -+/* Structure containing channel context information */ -+struct rwnx_chanctx { -+ struct cfg80211_chan_def chan_def; /* channel description */ -+ u8 count; /* number of vif using this ctxt */ -+}; -+ -+/** -+ * rwnx_phy_info - Phy information -+ * -+ * @phy_cnt: Number of phy interface -+ * @cfg: Configuration send to firmware -+ * @sec_chan: Channel configuration of the second phy interface (if phy_cnt > 1) -+ * @limit_bw: Set to true to limit BW on requested channel. Only set to use -+ * VHT with old radio that don't support 80MHz (deprecated) -+ */ -+struct rwnx_phy_info { -+ u8 cnt; -+ struct phy_cfg_tag cfg; -+ struct rwnx_sec_phy_chan sec_chan; -+ bool limit_bw; -+}; -+ -+ -+struct defrag_ctrl_info { -+ struct list_head list; -+ u8 sta_idx; -+ u8 tid; -+ u16 sn; -+ u8 next_fn; -+ u16 frm_len; -+ struct sk_buff *skb; -+ struct timer_list defrag_timer; -+ struct rwnx_hw *rwnx_hw; -+}; -+ -+struct amsdu_subframe_hdr { -+ u8 da[6]; -+ u8 sa[6]; -+ u16 sublen; -+}; -+ -+ -+/* rwnx driver status */ -+ -+enum rwnx_drv_connect_status { -+ RWNX_DRV_STATUS_DISCONNECTED = 0, -+ RWNX_DRV_STATUS_DISCONNECTING, -+ RWNX_DRV_STATUS_CONNECTING, -+ RWNX_DRV_STATUS_CONNECTED, -+}; -+ -+ -+struct rwnx_hw { -+ struct rwnx_mod_params *mod_params; -+ struct device *dev; -+#ifdef AICWF_SDIO_SUPPORT -+ struct aic_sdio_dev *sdiodev; -+#endif -+#ifdef AICWF_USB_SUPPORT -+ struct aic_usb_dev *usbdev; -+#endif -+ struct wiphy *wiphy; -+ struct list_head vifs; -+ struct rwnx_vif *vif_table[NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX]; /* indexed with fw id */ -+ struct rwnx_sta sta_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX]; -+#if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL) -+ struct aic_sta aic_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX]; -+#endif -+ struct rwnx_survey_info survey[SCAN_CHANNEL_MAX]; -+ struct cfg80211_scan_request *scan_request; -+#ifdef CONFIG_SCHED_SCAN -+ struct cfg80211_sched_scan_request *sched_scan_req; -+#endif -+ struct rwnx_chanctx chanctx_table[NX_CHAN_CTXT_CNT]; -+ u8 cur_chanctx; -+ -+ u8 monitor_vif; /* FW id of the monitor interface, RWNX_INVALID_VIF if no monitor vif at fw level */ -+ -+#ifdef CONFIG_FILTER_TCP_ACK -+ /* tcp ack management */ -+ struct tcp_ack_manage ack_m; -+#endif -+ -+ /* RoC Management */ -+ struct rwnx_roc_elem *roc_elem; /* Information provided by cfg80211 in its remain on channel request */ -+ u32 roc_cookie_cnt; /* Counter used to identify RoC request sent by cfg80211 */ -+ -+ struct rwnx_cmd_mgr *cmd_mgr; -+ -+ struct rwnx_plat *plat; -+ -+ spinlock_t tx_lock; -+ spinlock_t cb_lock; -+ struct mutex mutex; /* per-device perimeter lock */ -+ -+ struct tasklet_struct task; -+ struct mm_version_cfm version_cfm; /* Lower layers versions - obtained via MM_VERSION_REQ */ -+ -+ u32 tcp_pacing_shift; -+ -+ /* IPC */ -+ struct ipc_host_env_tag *ipc_env; -+#ifdef AICWF_SDIO_SUPPORT -+ struct sdio_host_env_tag sdio_env; -+#endif -+#ifdef AICWF_USB_SUPPORT -+ struct usb_host_env_tag usb_env; -+#endif -+ -+ struct rwnx_ipc_elem_pool e2amsgs_pool; -+ struct rwnx_ipc_elem_pool dbgmsgs_pool; -+ struct rwnx_ipc_elem_pool e2aradars_pool; -+ struct rwnx_ipc_elem_var pattern_elem; -+ struct rwnx_ipc_dbgdump_elem dbgdump_elem; -+ struct rwnx_ipc_elem_pool e2arxdesc_pool; -+ struct rwnx_ipc_skb_elem *e2aunsuprxvec_elems; -+ //struct rwnx_ipc_rxbuf_elems rxbuf_elems; -+ struct rwnx_ipc_elem_var scan_ie; -+ -+ struct kmem_cache *sw_txhdr_cache; -+ -+ struct rwnx_debugfs debugfs; -+ struct rwnx_stats stats; -+ -+#ifdef CONFIG_PREALLOC_TXQ -+ struct rwnx_txq *txq; -+#else -+ struct rwnx_txq txq[NX_NB_TXQ]; -+#endif -+ -+ struct rwnx_hwq hwq[NX_TXQ_CNT]; -+ -+ u64 avail_idx_map; -+ u8 vif_started; -+ bool adding_sta; -+ struct rwnx_phy_info phy; -+ -+ struct rwnx_radar radar; -+ -+ /* extended capabilities supported */ -+ u8 ext_capa[8]; -+ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ struct rwnx_mu_info mu; -+#endif -+ u8 is_p2p_alive; -+ u8 is_p2p_connected; -+ struct timer_list p2p_alive_timer; -+ struct rwnx_vif *p2p_dev_vif; -+ atomic_t p2p_alive_timer_count; -+ bool band_5g_support; -+ u8_l vendor_info; -+ bool fwlog_en; -+ -+ struct list_head defrag_list; -+ spinlock_t defrag_lock; -+ -+ struct work_struct apmStalossWork; -+ struct workqueue_struct *apmStaloss_wq; -+ u8 apm_vif_idx; -+ u8 sta_mac_addr[6]; -+ -+ struct wakeup_source *ws_rx; -+ struct wakeup_source *ws_irqrx; -+ struct wakeup_source *ws_tx; -+ struct wakeup_source *ws_pwrctrl; -+ -+#ifdef CONFIG_SCHED_SCAN -+ bool is_sched_scan; -+#endif//CONFIG_SCHED_SCAN -+}; -+ -+u8 *rwnx_build_bcn(struct rwnx_bcn *bcn, struct cfg80211_beacon_data *new); -+ -+void rwnx_chanctx_link(struct rwnx_vif *vif, u8 idx, -+ struct cfg80211_chan_def *chandef); -+void rwnx_chanctx_unlink(struct rwnx_vif *vif); -+int rwnx_chanctx_valid(struct rwnx_hw *rwnx_hw, u8 idx); -+ -+extern u8 chip_id; -+ -+static inline bool is_multicast_sta(int sta_idx) -+{ -+ if((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) || -+ ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC || g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)) -+ { -+ return (sta_idx >= NX_REMOTE_STA_MAX_FOR_OLD_IC); -+ }else{ -+ return (sta_idx >= NX_REMOTE_STA_MAX); -+ } -+ -+} -+struct rwnx_sta *rwnx_get_sta(struct rwnx_hw *rwnx_hw, const u8 *mac_addr); -+ -+static inline uint8_t master_vif_idx(struct rwnx_vif *vif) -+{ -+ if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_AP_VLAN)) { -+ return vif->ap_vlan.master->vif_index; -+ } else { -+ return vif->vif_index; -+ } -+} -+ -+void rwnx_external_auth_enable(struct rwnx_vif *vif); -+void rwnx_external_auth_disable(struct rwnx_vif *vif); -+ -+#endif /* _RWNX_DEFS_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_dini.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_dini.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_dini.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_dini.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,297 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_dini.c - Add support for dini platform -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#include "rwnx_dini.h" -+#include "rwnx_defs.h" -+#include "rwnx_irqs.h" -+#include "reg_access.h" -+ -+/* Config FPGA is accessed via bar0 */ -+#define CFPGA_DMA0_CTRL_REG 0x02C -+#define CFPGA_DMA1_CTRL_REG 0x04C -+#define CFPGA_DMA2_CTRL_REG 0x06C -+#define CFPGA_UINTR_SRC_REG 0x0E8 -+#define CFPGA_UINTR_MASK_REG 0x0EC -+#define CFPGA_BAR4_HIADDR_REG 0x100 -+#define CFPGA_BAR4_LOADDR_REG 0x104 -+#define CFPGA_BAR4_LOADDR_MASK_REG 0x110 -+#define CFPGA_BAR_TOUT 0x120 -+ -+#define CFPGA_DMA_CTRL_ENABLE 0x00001400 -+#define CFPGA_DMA_CTRL_DISABLE 0x00001000 -+#define CFPGA_DMA_CTRL_CLEAR 0x00001800 -+#define CFPGA_DMA_CTRL_REREAD_TIME_MASK (BIT(10) - 1) -+ -+#define CFPGA_BAR4_LOADDR_MASK_MAX 0xFF000000 -+ -+#define CFPGA_PCIEX_IT 0x00000001 -+#define CFPGA_ALL_ITS 0x0000000F -+ -+/* Programmable BAR4 Window start address */ -+#define CPU_RAM_WINDOW_HIGH 0x00000000 -+#define CPU_RAM_WINDOW_LOW 0x00000000 -+#define AHB_BRIDGE_WINDOW_HIGH 0x00000000 -+#define AHB_BRIDGE_WINDOW_LOW 0x60000000 -+ -+struct rwnx_dini { -+ u8 *pci_bar0_vaddr; -+ u8 *pci_bar4_vaddr; -+}; -+ -+static const u32 mv_cfg_fpga_dma_ctrl_regs[] = { -+ CFPGA_DMA0_CTRL_REG, -+ CFPGA_DMA1_CTRL_REG, -+ CFPGA_DMA2_CTRL_REG -+}; -+ -+/* This also clears running transactions */ -+static void dini_dma_on(struct rwnx_dini *rwnx_dini) -+{ -+ int i; -+ u32 reread_time; -+ volatile void *reg; -+ -+ for (i = 0; i < ARRAY_SIZE(mv_cfg_fpga_dma_ctrl_regs); i++) { -+ reg = rwnx_dini->pci_bar0_vaddr + mv_cfg_fpga_dma_ctrl_regs[i]; -+ reread_time = readl(reg) & CFPGA_DMA_CTRL_REREAD_TIME_MASK; -+ -+ writel(CFPGA_DMA_CTRL_CLEAR | reread_time, reg); -+ writel(CFPGA_DMA_CTRL_ENABLE | reread_time, reg); -+ } -+} -+ -+/* This also clears running transactions */ -+static void dini_dma_off(struct rwnx_dini *rwnx_dini) -+{ -+ int i; -+ u32 reread_time; -+ volatile void *reg; -+ -+ for (i = 0; i < ARRAY_SIZE(mv_cfg_fpga_dma_ctrl_regs); i++) { -+ reg = rwnx_dini->pci_bar0_vaddr + mv_cfg_fpga_dma_ctrl_regs[i]; -+ reread_time = readl(reg) & CFPGA_DMA_CTRL_REREAD_TIME_MASK; -+ -+ writel(CFPGA_DMA_CTRL_DISABLE | reread_time, reg); -+ writel(CFPGA_DMA_CTRL_CLEAR | reread_time, reg); -+ } -+} -+ -+ -+/* Configure address range for BAR4. -+ * By default BAR4_LOADDR_MASK value is 0xFF000000, then there is no need to -+ * change it because the addresses we need to access are covered by this mask -+ */ -+static void dini_set_bar4_win(u32 low, u32 high, struct rwnx_dini *rwnx_dini) -+{ -+ writel(low, rwnx_dini->pci_bar0_vaddr + CFPGA_BAR4_LOADDR_REG); -+ writel(high, rwnx_dini->pci_bar0_vaddr + CFPGA_BAR4_HIADDR_REG); -+ writel(CFPGA_BAR4_LOADDR_MASK_MAX, -+ rwnx_dini->pci_bar0_vaddr + CFPGA_BAR4_LOADDR_MASK_REG); -+} -+ -+ -+/** -+ * Enable User Interrupts of CFPGA that trigger PCIe IRQs on PCIE_10 -+ * and request the corresponding IRQ line -+ */ -+int rwnx_cfpga_irq_enable(struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_plat *rwnx_plat = rwnx_hw->plat; -+ struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv; -+ unsigned int cfpga_uintr_mask; -+ volatile void *reg; -+ int ret; -+ -+ /* sched_setscheduler on ONESHOT threaded irq handler for BCNs ? */ -+ ret = request_irq(rwnx_hw->plat->pci_dev->irq, rwnx_irq_hdlr, 0, "rwnx", rwnx_hw); -+ if (ret) -+ return ret; -+ -+ reg = rwnx_dini->pci_bar0_vaddr + CFPGA_UINTR_MASK_REG; -+ cfpga_uintr_mask = readl(reg); -+ writel(cfpga_uintr_mask | CFPGA_PCIEX_IT, reg); -+ -+ return ret; -+} -+ -+/** -+ * Disable User Interrupts of CFPGA that trigger PCIe IRQs on PCIE_10 -+ * and free the corresponding IRQ line -+ */ -+int rwnx_cfpga_irq_disable(struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_plat *rwnx_plat = rwnx_hw->plat; -+ struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv; -+ unsigned int cfpga_uintr_mask; -+ volatile void *reg; -+ -+ reg = rwnx_dini->pci_bar0_vaddr + CFPGA_UINTR_MASK_REG; -+ cfpga_uintr_mask = readl(reg); -+ writel(cfpga_uintr_mask & ~CFPGA_PCIEX_IT, reg); -+ -+ free_irq(rwnx_hw->plat->pci_dev->irq, rwnx_hw); -+ -+ return 0; -+} -+ -+static int rwnx_dini_platform_enable(struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_plat *rwnx_plat = rwnx_hw->plat; -+ struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv; -+ -+#ifdef CONFIG_RWNX_SDM -+ writel(0x0000FFFF, rwnx_dini->pci_bar0_vaddr + CFPGA_BAR_TOUT); -+#endif -+ -+ dini_dma_on(rwnx_dini); -+ return rwnx_cfpga_irq_enable(rwnx_hw); -+} -+ -+static int rwnx_dini_platform_disable(struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_plat *rwnx_plat = rwnx_hw->plat; -+ struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv; -+ int ret; -+ -+ ret = rwnx_cfpga_irq_disable(rwnx_hw); -+ dini_dma_off(rwnx_dini); -+ return ret; -+} -+ -+static void rwnx_dini_platform_deinit(struct rwnx_plat *rwnx_plat) -+{ -+ struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv; -+ -+ pci_disable_device(rwnx_plat->pci_dev); -+ iounmap(rwnx_dini->pci_bar0_vaddr); -+ iounmap(rwnx_dini->pci_bar4_vaddr); -+ pci_release_regions(rwnx_plat->pci_dev); -+ -+ kfree(rwnx_plat); -+} -+ -+static u8 *rwnx_dini_get_address(struct rwnx_plat *rwnx_plat, int addr_name, -+ unsigned int offset) -+{ -+ struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv; -+ -+ if (WARN(addr_name >= RWNX_ADDR_MAX, "Invalid address %d", addr_name)) -+ return NULL; -+ -+ if (addr_name == RWNX_ADDR_CPU) -+ dini_set_bar4_win(CPU_RAM_WINDOW_LOW, CPU_RAM_WINDOW_HIGH, rwnx_dini); -+ else -+ dini_set_bar4_win(AHB_BRIDGE_WINDOW_LOW, AHB_BRIDGE_WINDOW_HIGH, rwnx_dini); -+ -+ return rwnx_dini->pci_bar4_vaddr + offset; -+} -+ -+static void rwnx_dini_ack_irq(struct rwnx_plat *rwnx_plat) -+{ -+ struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv; -+ -+ writel(CFPGA_ALL_ITS, rwnx_dini->pci_bar0_vaddr + CFPGA_UINTR_SRC_REG); -+} -+ -+static const u32 rwnx_dini_config_reg[] = { -+ NXMAC_DEBUG_PORT_SEL_ADDR, -+ SYSCTRL_DIAG_CONF_ADDR, -+ RF_V6_DIAGPORT_CONF1_ADDR, -+ RF_v6_PHYDIAG_CONF1_ADDR, -+}; -+ -+static int rwnx_dini_get_config_reg(struct rwnx_plat *rwnx_plat, const u32 **list) -+{ -+ if (!list) -+ return 0; -+ -+ *list = rwnx_dini_config_reg; -+ return ARRAY_SIZE(rwnx_dini_config_reg); -+} -+ -+/** -+ * rwnx_dini_platform_init - Initialize the DINI platform -+ * -+ * @pci_dev PCI device -+ * @rwnx_plat Pointer on struct rwnx_stat * to be populated -+ * -+ * @return 0 on success, < 0 otherwise -+ * -+ * Allocate and initialize a rwnx_plat structure for the dini platform. -+ */ -+int rwnx_dini_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_plat) -+{ -+ struct rwnx_dini *rwnx_dini; -+ u16 pci_cmd; -+ int ret = 0; -+ -+ *rwnx_plat = kzalloc(sizeof(struct rwnx_plat) + sizeof(struct rwnx_dini), -+ GFP_KERNEL); -+ if (!*rwnx_plat) -+ return -ENOMEM; -+ -+ rwnx_dini = (struct rwnx_dini *)(*rwnx_plat)->priv; -+ -+ /* Hotplug fixups */ -+ pci_read_config_word(pci_dev, PCI_COMMAND, &pci_cmd); -+ pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR; -+ pci_write_config_word(pci_dev, PCI_COMMAND, pci_cmd); -+ //pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2); -+ -+ ret = pci_enable_device(pci_dev); -+ if (ret) { -+ dev_err(&(pci_dev->dev), "pci_enable_device failed\n"); -+ goto out_enable; -+ } -+ -+ pci_set_master(pci_dev); -+#if 0 -+ ret = pci_request_regions(pci_dev, KBUILD_MODNAME); -+ if (ret) { -+ dev_err(&(pci_dev->dev), "pci_request_regions failed\n"); -+ goto out_request; -+ } -+#endif -+ rwnx_dini->pci_bar0_vaddr = (u8 *)pci_ioremap_bar(pci_dev, 0); -+ if (!rwnx_dini->pci_bar0_vaddr) { -+ dev_err(&(pci_dev->dev), "pci_ioremap_bar(%d) failed\n", 0); -+ ret = -ENOMEM; -+ goto out_bar0; -+ } -+ rwnx_dini->pci_bar4_vaddr = (u8 *)pci_ioremap_bar(pci_dev, 4); -+ if (!rwnx_dini->pci_bar4_vaddr) { -+ dev_err(&(pci_dev->dev), "pci_ioremap_bar(%d) failed\n", 4); -+ ret = -ENOMEM; -+ goto out_bar4; -+ } -+ -+ (*rwnx_plat)->enable = rwnx_dini_platform_enable; -+ (*rwnx_plat)->disable = rwnx_dini_platform_disable; -+ (*rwnx_plat)->deinit = rwnx_dini_platform_deinit; -+ (*rwnx_plat)->get_address = rwnx_dini_get_address; -+ (*rwnx_plat)->ack_irq = rwnx_dini_ack_irq; -+ (*rwnx_plat)->get_config_reg = rwnx_dini_get_config_reg; -+ -+#ifdef CONFIG_RWNX_SDM -+ writel(0x0000FFFF, rwnx_dini->pci_bar0_vaddr + CFPGA_BAR_TOUT); -+#endif -+ -+ return 0; -+ -+out_bar4: -+ iounmap(rwnx_dini->pci_bar0_vaddr); -+out_bar0: -+ pci_release_regions(pci_dev); -+//out_request: -+ pci_disable_device(pci_dev); -+out_enable: -+ kfree(*rwnx_plat); -+ return ret; -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_dini.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_dini.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_dini.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_dini.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,20 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_dini.h -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _RWNX_DINI_H_ -+#define _RWNX_DINI_H_ -+ -+#include -+#include "rwnx_platform.h" -+ -+int rwnx_dini_platform_init(struct pci_dev *pci_dev, -+ struct rwnx_plat **rwnx_plat); -+ -+#endif /* _RWNX_DINI_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_events.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_events.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_events.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_events.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,1326 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_events.h -+ * -+ * @brief Trace events definition -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM rwnx -+ -+#if !defined(_RWNX_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _RWNX_EVENTS_H -+ -+#include -+#ifndef CONFIG_RWNX_FHOST -+#include "rwnx_tx.h" -+#endif -+#include "rwnx_compat.h" -+ -+/***************************************************************************** -+ * TRACE function for MGMT TX (FULLMAC) -+ ****************************************************************************/ -+#ifdef CONFIG_RWNX_FULLMAC -+#include "linux/ieee80211.h" -+#if defined(CONFIG_TRACEPOINTS) && defined(CREATE_TRACE_POINTS) -+#include -+ -+/* P2P Public Action Frames Definitions (see WiFi P2P Technical Specification, section 4.2.8) */ -+/* IEEE 802.11 Public Action Usage Category - Define P2P public action frames */ -+#define MGMT_ACTION_PUBLIC_CAT (0x04) -+/* Offset of OUI Subtype field in P2P Action Frame format */ -+#define MGMT_ACTION_OUI_SUBTYPE_OFFSET (6) -+/* P2P Public Action Frame Types */ -+enum p2p_action_type { -+ P2P_ACTION_GO_NEG_REQ = 0, /* GO Negociation Request */ -+ P2P_ACTION_GO_NEG_RSP, /* GO Negociation Response */ -+ P2P_ACTION_GO_NEG_CFM, /* GO Negociation Confirmation */ -+ P2P_ACTION_INVIT_REQ, /* P2P Invitation Request */ -+ P2P_ACTION_INVIT_RSP, /* P2P Invitation Response */ -+ P2P_ACTION_DEV_DISC_REQ, /* Device Discoverability Request */ -+ P2P_ACTION_DEV_DISC_RSP, /* Device Discoverability Response */ -+ P2P_ACTION_PROV_DISC_REQ, /* Provision Discovery Request */ -+ P2P_ACTION_PROV_DISC_RSP, /* Provision Discovery Response */ -+}; -+ -+const char *ftrace_print_mgmt_info(struct trace_seq *p, u16 frame_control, u8 cat, u8 type, u8 p2p) -+{ -+ const char *ret = trace_seq_buffer_ptr(p); -+ -+ switch (frame_control & IEEE80211_FCTL_STYPE) { -+ case (IEEE80211_STYPE_ASSOC_REQ): -+ trace_seq_printf(p, "Association Request"); -+ break; -+ case (IEEE80211_STYPE_ASSOC_RESP): -+ trace_seq_printf(p, "Association Response"); -+ break; -+ case (IEEE80211_STYPE_REASSOC_REQ): -+ trace_seq_printf(p, "Reassociation Request"); -+ break; -+ case (IEEE80211_STYPE_REASSOC_RESP): -+ trace_seq_printf(p, "Reassociation Response"); -+ break; -+ case (IEEE80211_STYPE_PROBE_REQ): -+ trace_seq_printf(p, "Probe Request"); -+ break; -+ case (IEEE80211_STYPE_PROBE_RESP): -+ trace_seq_printf(p, "Probe Response"); -+ break; -+ case (IEEE80211_STYPE_BEACON): -+ trace_seq_printf(p, "Beacon"); -+ break; -+ case (IEEE80211_STYPE_ATIM): -+ trace_seq_printf(p, "ATIM"); -+ break; -+ case (IEEE80211_STYPE_DISASSOC): -+ trace_seq_printf(p, "Disassociation"); -+ break; -+ case (IEEE80211_STYPE_AUTH): -+ trace_seq_printf(p, "Authentication"); -+ break; -+ case (IEEE80211_STYPE_DEAUTH): -+ trace_seq_printf(p, "Deauthentication"); -+ break; -+ case (IEEE80211_STYPE_ACTION): -+ trace_seq_printf(p, "Action"); -+ if (cat == MGMT_ACTION_PUBLIC_CAT && type == 0x9) { -+ switch (p2p) { -+ case (P2P_ACTION_GO_NEG_REQ): -+ trace_seq_printf(p, ": GO Negociation Request"); -+ break; -+ case (P2P_ACTION_GO_NEG_RSP): -+ trace_seq_printf(p, ": GO Negociation Response"); -+ break; -+ case (P2P_ACTION_GO_NEG_CFM): -+ trace_seq_printf(p, ": GO Negociation Confirmation"); -+ break; -+ case (P2P_ACTION_INVIT_REQ): -+ trace_seq_printf(p, ": P2P Invitation Request"); -+ break; -+ case (P2P_ACTION_INVIT_RSP): -+ trace_seq_printf(p, ": P2P Invitation Response"); -+ break; -+ case (P2P_ACTION_DEV_DISC_REQ): -+ trace_seq_printf(p, ": Device Discoverability Request"); -+ break; -+ case (P2P_ACTION_DEV_DISC_RSP): -+ trace_seq_printf(p, ": Device Discoverability Response"); -+ break; -+ case (P2P_ACTION_PROV_DISC_REQ): -+ trace_seq_printf(p, ": Provision Discovery Request"); -+ break; -+ case (P2P_ACTION_PROV_DISC_RSP): -+ trace_seq_printf(p, ": Provision Discovery Response"); -+ break; -+ default: -+ trace_seq_printf(p, "Unknown p2p %d", p2p); -+ break; -+ } -+ } else { -+ switch (cat) { -+ case 0: -+ trace_seq_printf(p, ":Spectrum %d", type); -+ break; -+ case 1: -+ trace_seq_printf(p, ":QOS %d", type); break; -+ case 2: -+ trace_seq_printf(p, ":DLS %d", type); -+ break; -+ case 3: -+ trace_seq_printf(p, ":BA %d", type); -+ break; -+ case 4: -+ trace_seq_printf(p, ":Public %d", type); -+ break; -+ case 5: -+ trace_seq_printf(p, ":Radio Measure %d", type); -+ break; -+ case 6: -+ trace_seq_printf(p, ":Fast BSS %d", type); -+ break; -+ case 7: -+ trace_seq_printf(p, ":HT Action %d", type); -+ break; -+ case 8: -+ trace_seq_printf(p, ":SA Query %d", type); -+ break; -+ case 9: -+ trace_seq_printf(p, ":Protected Public %d", type); -+ break; -+ case 10: -+ trace_seq_printf(p, ":WNM %d", type); -+ break; -+ case 11: -+ trace_seq_printf(p, ":Unprotected WNM %d", type); -+ break; -+ case 12: -+ trace_seq_printf(p, ":TDLS %d", type); -+ break; -+ case 13: -+ trace_seq_printf(p, ":Mesh %d", type); -+ break; -+ case 14: -+ trace_seq_printf(p, ":MultiHop %d", type); -+ break; -+ case 15: -+ trace_seq_printf(p, ":Self Protected %d", type); -+ break; -+ case 126: -+ trace_seq_printf(p, ":Vendor protected"); -+ break; -+ case 127: -+ trace_seq_printf(p, ":Vendor"); -+ break; -+ default: -+ trace_seq_printf(p, ":Unknown category %d", cat); -+ break; -+ } -+ } -+ break; -+ default: -+ trace_seq_printf(p, "Unknown subtype %d", frame_control & IEEE80211_FCTL_STYPE); -+ break; -+ } -+ -+ trace_seq_putc(p, 0); -+ -+ return ret; -+} -+#endif /* defined(CONFIG_TRACEPOINTS) && defined(CREATE_TRACE_POINTS) */ -+ -+#undef __print_mgmt_info -+#define __print_mgmt_info(frame_control, cat, type, p2p) ftrace_print_mgmt_info(p, frame_control, cat, type, p2p) -+ -+TRACE_EVENT( -+ roc, -+ TP_PROTO(u8 vif_idx, u16 freq, unsigned int duration), -+ TP_ARGS(vif_idx, freq, duration), -+ TP_STRUCT__entry( -+ __field(u8, vif_idx) -+ __field(u16, freq) -+ __field(unsigned int, duration) -+ ), -+ TP_fast_assign( -+ __entry->vif_idx = vif_idx; -+ __entry->freq = freq; -+ __entry->duration = duration; -+ ), -+ TP_printk("f=%d vif=%d dur=%d", -+ __entry->freq, __entry->vif_idx, __entry->duration) -+); -+ -+TRACE_EVENT( -+ cancel_roc, -+ TP_PROTO(u8 vif_idx), -+ TP_ARGS(vif_idx), -+ TP_STRUCT__entry( -+ __field(u8, vif_idx) -+ ), -+ TP_fast_assign( -+ __entry->vif_idx = vif_idx; -+ ), -+ TP_printk("vif=%d", __entry->vif_idx) -+); -+ -+TRACE_EVENT( -+ roc_exp, -+ TP_PROTO(u8 vif_idx), -+ TP_ARGS(vif_idx), -+ TP_STRUCT__entry( -+ __field(u8, vif_idx) -+ ), -+ TP_fast_assign( -+ __entry->vif_idx = vif_idx; -+ ), -+ TP_printk("vif=%d", __entry->vif_idx) -+); -+ -+TRACE_EVENT( -+ switch_roc, -+ TP_PROTO(u8 vif_idx), -+ TP_ARGS(vif_idx), -+ TP_STRUCT__entry( -+ __field(u8, vif_idx) -+ ), -+ TP_fast_assign( -+ __entry->vif_idx = vif_idx; -+ ), -+ TP_printk("vif=%d", __entry->vif_idx) -+); -+ -+DECLARE_EVENT_CLASS( -+ mgmt_template, -+ TP_PROTO(u16 freq, u8 vif_idx, u8 sta_idx, struct ieee80211_mgmt *mgmt), -+ TP_ARGS(freq, vif_idx, sta_idx, mgmt), -+ TP_STRUCT__entry( -+ __field(u16, freq) -+ __field(u8, vif_idx) -+ __field(u8, sta_idx) -+ __field(u16, frame_control) -+ __field(u8, action_cat) -+ __field(u8, action_type) -+ __field(u8, action_p2p) -+ ), -+ TP_fast_assign( -+ __entry->freq = freq; -+ __entry->vif_idx = vif_idx; -+ __entry->sta_idx = sta_idx; -+ __entry->frame_control = mgmt->frame_control; -+ __entry->action_cat = mgmt->u.action.category; -+ __entry->action_type = mgmt->u.action.u.wme_action.action_code; -+ __entry->action_p2p = *((u8 *)&mgmt->u.action.category -+ + MGMT_ACTION_OUI_SUBTYPE_OFFSET); -+ ), -+ TP_printk("f=%d vif=%d sta=%d -> %s", -+ __entry->freq, __entry->vif_idx, __entry->sta_idx, -+ __print_mgmt_info(__entry->frame_control, __entry->action_cat, -+ __entry->action_type, __entry->action_p2p)) -+); -+ -+DEFINE_EVENT(mgmt_template, mgmt_tx, -+ TP_PROTO(u16 freq, u8 vif_idx, u8 sta_idx, struct ieee80211_mgmt *mgmt), -+ TP_ARGS(freq, vif_idx, sta_idx, mgmt)); -+ -+DEFINE_EVENT(mgmt_template, mgmt_rx, -+ TP_PROTO(u16 freq, u8 vif_idx, u8 sta_idx, struct ieee80211_mgmt *mgmt), -+ TP_ARGS(freq, vif_idx, sta_idx, mgmt)); -+ -+TRACE_EVENT( -+ mgmt_cfm, -+ TP_PROTO(u8 vif_idx, u8 sta_idx, bool acked), -+ TP_ARGS(vif_idx, sta_idx, acked), -+ TP_STRUCT__entry( -+ __field(u8, vif_idx) -+ __field(u8, sta_idx) -+ __field(bool, acked) -+ ), -+ TP_fast_assign( -+ __entry->vif_idx = vif_idx; -+ __entry->sta_idx = sta_idx; -+ __entry->acked = acked; -+ ), -+ TP_printk("vif=%d sta=%d ack=%d", -+ __entry->vif_idx, __entry->sta_idx, __entry->acked) -+); -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+/***************************************************************************** -+ * TRACE function for TXQ -+ ****************************************************************************/ -+#ifndef CONFIG_RWNX_FHOST -+#if defined(CONFIG_TRACEPOINTS) && defined(CREATE_TRACE_POINTS) -+ -+#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+#include -+#else -+#include -+#endif -+ -+const char * -+ftrace_print_txq(struct trace_seq *p, int txq_idx) -+{ -+ const char *ret = trace_seq_buffer_ptr(p); -+ -+ if (txq_idx == TXQ_INACTIVE) { -+ trace_seq_printf(p, "[INACTIVE]"); -+ } else if (txq_idx < NX_FIRST_VIF_TXQ_IDX) { -+ trace_seq_printf(p, "[STA %d/%d]", -+ txq_idx / NX_NB_TXQ_PER_STA, -+ txq_idx % NX_NB_TXQ_PER_STA); -+#ifdef CONFIG_RWNX_FULLMAC -+ } else if (txq_idx < NX_FIRST_UNK_TXQ_IDX) { -+ trace_seq_printf(p, "[BC/MC %d]", -+ txq_idx - NX_FIRST_BCMC_TXQ_IDX); -+ } else if (txq_idx < NX_OFF_CHAN_TXQ_IDX) { -+ trace_seq_printf(p, "[UNKNOWN %d]", -+ txq_idx - NX_FIRST_UNK_TXQ_IDX); -+ } else if (txq_idx == NX_OFF_CHAN_TXQ_IDX) { -+ trace_seq_printf(p, "[OFFCHAN]"); -+#else -+ } else if (txq_idx < NX_NB_TXQ) { -+ txq_idx -= NX_FIRST_VIF_TXQ_IDX; -+ trace_seq_printf(p, "[VIF %d/%d]", -+ txq_idx / NX_NB_TXQ_PER_VIF, -+ txq_idx % NX_NB_TXQ_PER_VIF); -+#endif -+ } else { -+ trace_seq_printf(p, "[ERROR %d]", txq_idx); -+ } -+ -+ trace_seq_putc(p, 0); -+ -+ return ret; -+} -+ -+const char * -+ftrace_print_sta(struct trace_seq *p, int sta_idx) -+{ -+ const char *ret = trace_seq_buffer_ptr(p); -+ -+ if (sta_idx < NX_REMOTE_STA_MAX) { -+ trace_seq_printf(p, "[STA %d]", sta_idx); -+ } else { -+ trace_seq_printf(p, "[BC/MC %d]", sta_idx - NX_REMOTE_STA_MAX); -+ } -+ -+ trace_seq_putc(p, 0); -+ -+ return ret; -+} -+ -+const char * -+ftrace_print_hwq(struct trace_seq *p, int hwq_idx) -+{ -+ -+ static const struct trace_print_flags symbols[] = { -+ {RWNX_HWQ_BK, "BK"}, -+ {RWNX_HWQ_BE, "BE"}, -+ {RWNX_HWQ_VI, "VI"}, -+ {RWNX_HWQ_VO, "VO"}, -+#ifdef CONFIG_RWNX_FULLMAC -+ {RWNX_HWQ_BCMC, "BCMC"}, -+#else -+ {RWNX_HWQ_BCN, "BCN"}, -+#endif -+ { -1, NULL } }; -+ return trace_print_symbols_seq(p, hwq_idx, symbols); -+} -+ -+const char * -+ftrace_print_hwq_cred(struct trace_seq *p, u8 *cred) -+{ -+ const char *ret = trace_seq_buffer_ptr(p); -+ -+#if CONFIG_USER_MAX == 1 -+ trace_seq_printf(p, "%d", cred[0]); -+#else -+ int i; -+ -+ for (i = 0; i < CONFIG_USER_MAX - 1; i++) -+ trace_seq_printf(p, "%d-", cred[i]); -+ trace_seq_printf(p, "%d", cred[i]); -+#endif -+ -+ trace_seq_putc(p, 0); -+ return ret; -+} -+ -+const char * -+ftrace_print_mu_info(struct trace_seq *p, u8 mu_info) -+{ -+ const char *ret = trace_seq_buffer_ptr(p); -+ -+ if (mu_info) -+ trace_seq_printf(p, "MU: %d-%d", (mu_info & 0x3f), (mu_info >> 6)); -+ -+ trace_seq_putc(p, 0); -+ return ret; -+} -+ -+const char * -+ftrace_print_mu_group(struct trace_seq *p, int nb_user, u8 *users) -+{ -+ const char *ret = trace_seq_buffer_ptr(p); -+ int i; -+ -+ if (users[0] != 0xff) -+ trace_seq_printf(p, "(%d", users[0]); -+ else -+ trace_seq_printf(p, "(-"); -+ for (i = 1; i < CONFIG_USER_MAX ; i++) { -+ if (users[i] != 0xff) -+ trace_seq_printf(p, ",%d", users[i]); -+ else -+ trace_seq_printf(p, ",-"); -+ } -+ -+ trace_seq_printf(p, ")"); -+ trace_seq_putc(p, 0); -+ return ret; -+} -+ -+const char * -+ftrace_print_amsdu(struct trace_seq *p, u16 nb_pkt) -+{ -+ const char *ret = trace_seq_buffer_ptr(p); -+ -+ if (nb_pkt > 1) -+ trace_seq_printf(p, "(AMSDU %d)", nb_pkt); -+ -+ trace_seq_putc(p, 0); -+ return ret; -+} -+#endif /* defined(CONFIG_TRACEPOINTS) && defined(CREATE_TRACE_POINTS) */ -+ -+#undef __print_txq -+#define __print_txq(txq_idx) ftrace_print_txq(p, txq_idx) -+ -+#undef __print_sta -+#define __print_sta(sta_idx) ftrace_print_sta(p, sta_idx) -+ -+#undef __print_hwq -+#define __print_hwq(hwq) ftrace_print_hwq(p, hwq) -+ -+#undef __print_hwq_cred -+#define __print_hwq_cred(cred) ftrace_print_hwq_cred(p, cred) -+ -+#undef __print_mu_info -+#define __print_mu_info(mu_info) ftrace_print_mu_info(p, mu_info) -+ -+#undef __print_mu_group -+#define __print_mu_group(nb, users) ftrace_print_mu_group(p, nb, users) -+ -+#undef __print_amsdu -+#define __print_amsdu(nb_pkt) ftrace_print_amsdu(p, nb_pkt) -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+TRACE_EVENT( -+ txq_select, -+ TP_PROTO(int txq_idx, u16 pkt_ready_up, struct sk_buff *skb), -+ TP_ARGS(txq_idx, pkt_ready_up, skb), -+ TP_STRUCT__entry( -+ __field(u16, txq_idx) -+ __field(u16, pkt_ready) -+ __field(struct sk_buff *, skb) -+ ), -+ TP_fast_assign( -+ __entry->txq_idx = txq_idx; -+ __entry->pkt_ready = pkt_ready_up; -+ __entry->skb = skb; -+ ), -+ TP_printk("%s pkt_ready_up=%d skb=%p", __print_txq(__entry->txq_idx), -+ __entry->pkt_ready, __entry->skb) -+); -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+DECLARE_EVENT_CLASS( -+ hwq_template, -+ TP_PROTO(u8 hwq_idx), -+ TP_ARGS(hwq_idx), -+ TP_STRUCT__entry( -+ __field(u8, hwq_idx) -+ ), -+ TP_fast_assign( -+ __entry->hwq_idx = hwq_idx; -+ ), -+ TP_printk("%s", __print_hwq(__entry->hwq_idx)) -+); -+ -+DEFINE_EVENT(hwq_template, hwq_flowctrl_stop, -+ TP_PROTO(u8 hwq_idx), -+ TP_ARGS(hwq_idx)); -+ -+DEFINE_EVENT(hwq_template, hwq_flowctrl_start, -+ TP_PROTO(u8 hwq_idx), -+ TP_ARGS(hwq_idx)); -+ -+ -+DECLARE_EVENT_CLASS( -+ txq_template, -+ TP_PROTO(struct rwnx_txq *txq), -+ TP_ARGS(txq), -+ TP_STRUCT__entry( -+ __field(u16, txq_idx) -+ ), -+ TP_fast_assign( -+ __entry->txq_idx = txq->idx; -+ ), -+ TP_printk("%s", __print_txq(__entry->txq_idx)) -+); -+ -+DEFINE_EVENT(txq_template, txq_add_to_hw, -+ TP_PROTO(struct rwnx_txq *txq), -+ TP_ARGS(txq)); -+ -+DEFINE_EVENT(txq_template, txq_del_from_hw, -+ TP_PROTO(struct rwnx_txq *txq), -+ TP_ARGS(txq)); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+DEFINE_EVENT(txq_template, txq_flowctrl_stop, -+ TP_PROTO(struct rwnx_txq *txq), -+ TP_ARGS(txq)); -+ -+DEFINE_EVENT(txq_template, txq_flowctrl_restart, -+ TP_PROTO(struct rwnx_txq *txq), -+ TP_ARGS(txq)); -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+TRACE_EVENT( -+ process_txq, -+ TP_PROTO(struct rwnx_txq *txq), -+ TP_ARGS(txq), -+ TP_STRUCT__entry( -+ __field(u16, txq_idx) -+ __field(u16, len) -+ __field(u16, len_retry) -+ __field(s8, credit) -+ #ifdef CONFIG_RWNX_FULLMAC -+ __field(u16, limit) -+ #endif /* CONFIG_RWNX_FULLMAC*/ -+ ), -+ TP_fast_assign( -+ __entry->txq_idx = txq->idx; -+ __entry->len = skb_queue_len(&txq->sk_list); -+ #ifdef CONFIG_MAC80211_TXQ -+ __entry->len += txq->nb_ready_mac80211; -+ #endif -+ __entry->len_retry = txq->nb_retry; -+ __entry->credit = txq->credits; -+ #ifdef CONFIG_RWNX_FULLMAC -+ __entry->limit = txq->push_limit; -+ #endif /* CONFIG_RWNX_FULLMAC*/ -+ ), -+ -+ #ifdef CONFIG_RWNX_FULLMAC -+ TP_printk("%s txq_credits=%d, len=%d, retry_len=%d, push_limit=%d", -+ __print_txq(__entry->txq_idx), __entry->credit, -+ __entry->len, __entry->len_retry, __entry->limit) -+ #else -+ TP_printk("%s txq_credits=%d, len=%d, retry_len=%d", -+ __print_txq(__entry->txq_idx), __entry->credit, -+ __entry->len, __entry->len_retry) -+ #endif /* CONFIG_RWNX_FULLMAC*/ -+); -+ -+DECLARE_EVENT_CLASS( -+ txq_reason_template, -+ TP_PROTO(struct rwnx_txq *txq, u16 reason), -+ TP_ARGS(txq, reason), -+ TP_STRUCT__entry( -+ __field(u16, txq_idx) -+ __field(u16, reason) -+ __field(u16, status) -+ ), -+ TP_fast_assign( -+ __entry->txq_idx = txq->idx; -+ __entry->reason = reason; -+ __entry->status = txq->status; -+ ), -+ TP_printk("%s reason=%s status=%s", -+ __print_txq(__entry->txq_idx), -+ __print_symbolic(__entry->reason, -+ {RWNX_TXQ_STOP_FULL, "FULL"}, -+ {RWNX_TXQ_STOP_CSA, "CSA"}, -+ {RWNX_TXQ_STOP_STA_PS, "PS"}, -+ {RWNX_TXQ_STOP_VIF_PS, "VPS"}, -+ {RWNX_TXQ_STOP_CHAN, "CHAN"}, -+ {RWNX_TXQ_STOP_MU_POS, "MU"}), -+ __print_flags(__entry->status, "|", -+ {RWNX_TXQ_IN_HWQ_LIST, "IN LIST"}, -+ {RWNX_TXQ_STOP_FULL, "FULL"}, -+ {RWNX_TXQ_STOP_CSA, "CSA"}, -+ {RWNX_TXQ_STOP_STA_PS, "PS"}, -+ {RWNX_TXQ_STOP_VIF_PS, "VPS"}, -+ {RWNX_TXQ_STOP_CHAN, "CHAN"}, -+ {RWNX_TXQ_STOP_MU_POS, "MU"}, -+ {RWNX_TXQ_NDEV_FLOW_CTRL, "FLW_CTRL"})) -+); -+ -+DEFINE_EVENT(txq_reason_template, txq_start, -+ TP_PROTO(struct rwnx_txq *txq, u16 reason), -+ TP_ARGS(txq, reason)); -+ -+DEFINE_EVENT(txq_reason_template, txq_stop, -+ TP_PROTO(struct rwnx_txq *txq, u16 reason), -+ TP_ARGS(txq, reason)); -+ -+ -+TRACE_EVENT( -+ push_desc, -+ TP_PROTO(struct sk_buff *skb, struct rwnx_sw_txhdr *sw_txhdr, int push_flags), -+ -+ TP_ARGS(skb, sw_txhdr, push_flags), -+ -+ TP_STRUCT__entry( -+ __field(struct sk_buff *, skb) -+ __field(unsigned int, len) -+ __field(u16, tx_queue) -+ __field(u8, hw_queue) -+ __field(u8, push_flag) -+ __field(u32, flag) -+ __field(s8, txq_cred) -+ __field(u8, hwq_cred) -+ __field(u16, pkt_cnt) -+ __field(u8, mu_info) -+ ), -+ TP_fast_assign( -+ __entry->skb = skb; -+ __entry->tx_queue = sw_txhdr->txq->idx; -+ __entry->push_flag = push_flags; -+ __entry->hw_queue = sw_txhdr->txq->hwq->id; -+ __entry->txq_cred = sw_txhdr->txq->credits; -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ __entry->pkt_cnt = sw_txhdr->desc.host.packet_cnt; -+#endif -+#ifdef CONFIG_RWNX_FULLMAC -+ __entry->flag = sw_txhdr->desc.host.flags; -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ if (sw_txhdr->amsdu.len) -+ __entry->len = sw_txhdr->amsdu.len; -+ else -+#endif /* CONFIG_RWNX_AMSDUS_TX */ -+ __entry->len = sw_txhdr->desc.host.packet_len[0]; -+#else -+ __entry->len = sw_txhdr->desc.host.packet_len; -+#endif /* CONFIG_RWNX_SPLIT_TX_BUF */ -+ -+#else /* !CONFIG_RWNX_FULLMAC */ -+ __entry->flag = sw_txhdr->desc.umac.flags; -+ __entry->len = sw_txhdr->frame_len; -+ __entry->sn = sw_txhdr->sn; -+#endif /* CONFIG_RWNX_FULLMAC */ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ __entry->mu_info = sw_txhdr->desc.host.mumimo_info; -+#else -+ __entry->mu_info = 0; -+#endif -+ ), -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ TP_printk("%s skb=%p (len=%d) hw_queue=%s cred_txq=%d cred_hwq=%d %s flag=%s %s%s%s", -+ __print_txq(__entry->tx_queue), __entry->skb, __entry->len, -+ __print_hwq(__entry->hw_queue), -+ __entry->txq_cred, __entry->hwq_cred, -+ __print_mu_info(__entry->mu_info), -+ __print_flags(__entry->flag, "|", -+ {TXU_CNTRL_RETRY, "RETRY"}, -+ {TXU_CNTRL_MORE_DATA, "MOREDATA"}, -+ {TXU_CNTRL_MGMT, "MGMT"}, -+ {TXU_CNTRL_MGMT_NO_CCK, "NO_CCK"}, -+ {TXU_CNTRL_MGMT_ROBUST, "ROBUST"}, -+ {TXU_CNTRL_AMSDU, "AMSDU"}, -+ {TXU_CNTRL_USE_4ADDR, "4ADDR"}, -+ {TXU_CNTRL_EOSP, "EOSP"}, -+ {TXU_CNTRL_MESH_FWD, "MESH_FWD"}, -+ {TXU_CNTRL_TDLS, "TDLS"}), -+ (__entry->push_flag & RWNX_PUSH_IMMEDIATE) ? "(IMMEDIATE)" : "", -+ (!(__entry->flag & TXU_CNTRL_RETRY) && -+ (__entry->push_flag & RWNX_PUSH_RETRY)) ? "(SW_RETRY)" : "", -+ __print_amsdu(__entry->pkt_cnt)) -+#else -+ TP_printk("%s skb=%p (len=%d) hw_queue=%s cred_txq=%d cred_hwq=%d %s flag=%x (%s) sn=%d %s", -+ __print_txq(__entry->tx_queue), __entry->skb, __entry->len, -+ __print_hwq(__entry->hw_queue), __entry->txq_cred, __entry->hwq_cred, -+ __print_mu_info(__entry->mu_info), -+ __entry->flag, -+ __print_flags(__entry->push_flag, "|", -+ {RWNX_PUSH_RETRY, "RETRY"}, -+ {RWNX_PUSH_IMMEDIATE, "IMMEDIATE"}), -+ __entry->sn, __print_amsdu(__entry->pkt_cnt)) -+#endif /* CONFIG_RWNX_FULLMAC */ -+); -+ -+ -+TRACE_EVENT( -+ txq_queue_skb, -+ TP_PROTO(struct sk_buff *skb, struct rwnx_txq *txq, bool retry), -+ TP_ARGS(skb, txq, retry), -+ TP_STRUCT__entry( -+ __field(struct sk_buff *, skb) -+ __field(u16, txq_idx) -+ __field(s8, credit) -+ __field(u16, q_len) -+ __field(u16, q_len_retry) -+ __field(bool, retry) -+ ), -+ TP_fast_assign( -+ __entry->skb = skb; -+ __entry->txq_idx = txq->idx; -+ __entry->credit = txq->credits; -+ __entry->q_len = skb_queue_len(&txq->sk_list); -+ __entry->q_len_retry = txq->nb_retry; -+ __entry->retry = retry; -+ ), -+ -+ TP_printk("%s skb=%p retry=%d txq_credits=%d queue_len=%d (retry = %d)", -+ __print_txq(__entry->txq_idx), __entry->skb, __entry->retry, -+ __entry->credit, __entry->q_len, __entry->q_len_retry) -+); -+ -+#ifdef CONFIG_MAC80211_TXQ -+TRACE_EVENT( -+ txq_wake, -+ TP_PROTO(struct rwnx_txq *txq), -+ TP_ARGS(txq), -+ TP_STRUCT__entry( -+ __field(u16, txq_idx) -+ __field(u16, q_len) -+ ), -+ TP_fast_assign( -+ __entry->txq_idx = txq->idx; -+ __entry->q_len = txq->nb_ready_mac80211; -+ ), -+ -+ TP_printk("%s mac80211_queue_len=%d", __print_txq(__entry->txq_idx), __entry->q_len) -+); -+ -+TRACE_EVENT( -+ txq_drop, -+ TP_PROTO(struct rwnx_txq *txq, unsigned long nb_drop), -+ TP_ARGS(txq, nb_drop), -+ TP_STRUCT__entry( -+ __field(u16, txq_idx) -+ __field(u16, nb_drop) -+ ), -+ TP_fast_assign( -+ __entry->txq_idx = txq->idx; -+ __entry->nb_drop = nb_drop; -+ ), -+ -+ TP_printk("%s %u pkt have been dropped by codel in mac80211 txq", -+ __print_txq(__entry->txq_idx), __entry->nb_drop) -+); -+ -+#endif -+ -+ -+DECLARE_EVENT_CLASS( -+ idx_template, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx), -+ TP_STRUCT__entry( -+ __field(u16, idx) -+ ), -+ TP_fast_assign( -+ __entry->idx = idx; -+ ), -+ TP_printk("idx=%d", __entry->idx) -+); -+ -+ -+DEFINE_EVENT(idx_template, txq_vif_start, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx)); -+ -+DEFINE_EVENT(idx_template, txq_vif_stop, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx)); -+ -+TRACE_EVENT( -+ process_hw_queue, -+ TP_PROTO(struct rwnx_hwq *hwq), -+ TP_ARGS(hwq), -+ TP_STRUCT__entry( -+ __field(u16, hwq) -+ __array(u8, credits, CONFIG_USER_MAX) -+ ), -+ TP_fast_assign( -+ __entry->hwq = hwq->id; -+ ), -+ TP_printk("hw_queue=%s hw_credits=%s", -+ __print_hwq(__entry->hwq), __print_hwq_cred(__entry->credits)) -+); -+ -+DECLARE_EVENT_CLASS( -+ sta_idx_template, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx), -+ TP_STRUCT__entry( -+ __field(u16, idx) -+ ), -+ TP_fast_assign( -+ __entry->idx = idx; -+ ), -+ TP_printk("%s", __print_sta(__entry->idx)) -+); -+ -+DEFINE_EVENT(sta_idx_template, txq_sta_start, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx)); -+ -+DEFINE_EVENT(sta_idx_template, txq_sta_stop, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx)); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+DEFINE_EVENT(sta_idx_template, ps_disable, -+ TP_PROTO(u16 idx), -+ TP_ARGS(idx)); -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+TRACE_EVENT( -+ skb_confirm, -+ TP_PROTO(struct sk_buff *skb, struct rwnx_txq *txq, struct rwnx_hwq *hwq, -+#ifdef CONFIG_RWNX_FULLMAC -+ struct tx_cfm_tag *cfm -+#else -+ u8 cfm -+#endif -+ ), -+ -+ TP_ARGS(skb, txq, hwq, cfm), -+ -+ TP_STRUCT__entry( -+ __field(struct sk_buff *, skb) -+ __field(u16, txq_idx) -+ __field(u8, hw_queue) -+ __array(u8, hw_credit, CONFIG_USER_MAX) -+ __field(s8, sw_credit) -+ __field(s8, sw_credit_up) -+#ifdef CONFIG_RWNX_FULLMAC -+ __field(u8, ampdu_size) -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ __field(u16, amsdu) -+#endif /* CONFIG_RWNX_SPLIT_TX_BUF */ -+ __field(u16, sn) -+#endif /* CONFIG_RWNX_FULLMAC*/ -+ ), -+ -+ TP_fast_assign( -+ __entry->skb = skb; -+ __entry->txq_idx = txq->idx; -+ __entry->hw_queue = hwq->id; -+ __entry->sw_credit = txq->credits; -+#if defined CONFIG_RWNX_FULLMAC -+ __entry->sw_credit_up = cfm->credits; -+ __entry->ampdu_size = cfm->ampdu_size; -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ __entry->amsdu = cfm->amsdu_size; -+ __entry->sn = cfm->sn; -+#endif -+#else -+ __entry->sw_credit_up = cfm -+#endif /* CONFIG_RWNX_FULLMAC */ -+ ), -+ -+ TP_printk("%s skb=%p hw_queue=%s, hw_credits=%s, txq_credits=%d (+%d)" -+#ifdef CONFIG_RWNX_FULLMAC -+ " sn=%u ampdu=%d" -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ " amsdu=%u" -+#endif -+#endif -+ , __print_txq(__entry->txq_idx), __entry->skb, -+ __print_hwq(__entry->hw_queue), -+ __print_hwq_cred(__entry->hw_credit), -+ __entry->sw_credit, __entry->sw_credit_up -+#ifdef CONFIG_RWNX_FULLMAC -+ , __entry->sn, __entry->ampdu_size -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ , __entry->amsdu -+#endif -+#endif -+ ) -+); -+ -+TRACE_EVENT( -+ credit_update, -+ TP_PROTO(struct rwnx_txq *txq, s8_l cred_up), -+ -+ TP_ARGS(txq, cred_up), -+ -+ TP_STRUCT__entry( -+ __field(struct sk_buff *, skb) -+ __field(u16, txq_idx) -+ __field(s8, sw_credit) -+ __field(s8, sw_credit_up) -+ ), -+ -+ TP_fast_assign( -+ __entry->txq_idx = txq->idx; -+ __entry->sw_credit = txq->credits; -+ __entry->sw_credit_up = cred_up; -+ ), -+ -+ TP_printk("%s txq_credits=%d (%+d)", __print_txq(__entry->txq_idx), -+ __entry->sw_credit, __entry->sw_credit_up) -+) -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+DECLARE_EVENT_CLASS( -+ ps_template, -+ TP_PROTO(struct rwnx_sta *sta), -+ TP_ARGS(sta), -+ TP_STRUCT__entry( -+ __field(u16, idx) -+ __field(u16, ready_ps) -+ __field(u16, sp_ps) -+ __field(u16, ready_uapsd) -+ __field(u16, sp_uapsd) -+ ), -+ TP_fast_assign( -+ __entry->idx = sta->sta_idx; -+ __entry->ready_ps = sta->ps.pkt_ready[LEGACY_PS_ID]; -+ __entry->sp_ps = sta->ps.sp_cnt[LEGACY_PS_ID]; -+ __entry->ready_uapsd = sta->ps.pkt_ready[UAPSD_ID]; -+ __entry->sp_uapsd = sta->ps.sp_cnt[UAPSD_ID]; -+ ), -+ -+ TP_printk("%s [PS] ready=%d sp=%d [UAPSD] ready=%d sp=%d", -+ __print_sta(__entry->idx), __entry->ready_ps, __entry->sp_ps, -+ __entry->ready_uapsd, __entry->sp_uapsd) -+); -+ -+DEFINE_EVENT(ps_template, ps_queue, -+ TP_PROTO(struct rwnx_sta *sta), -+ TP_ARGS(sta)); -+ -+DEFINE_EVENT(ps_template, ps_push, -+ TP_PROTO(struct rwnx_sta *sta), -+ TP_ARGS(sta)); -+ -+DEFINE_EVENT(ps_template, ps_enable, -+ TP_PROTO(struct rwnx_sta *sta), -+ TP_ARGS(sta)); -+ -+TRACE_EVENT( -+ ps_traffic_update, -+ TP_PROTO(u16 sta_idx, u8 traffic, bool uapsd), -+ -+ TP_ARGS(sta_idx, traffic, uapsd), -+ -+ TP_STRUCT__entry( -+ __field(u16, sta_idx) -+ __field(u8, traffic) -+ __field(bool, uapsd) -+ ), -+ -+ TP_fast_assign( -+ __entry->sta_idx = sta_idx; -+ __entry->traffic = traffic; -+ __entry->uapsd = uapsd; -+ ), -+ -+ TP_printk("%s %s%s traffic available ", __print_sta(__entry->sta_idx), -+ __entry->traffic ? "" : "no more ", -+ __entry->uapsd ? "U-APSD" : "legacy PS") -+); -+ -+TRACE_EVENT( -+ ps_traffic_req, -+ TP_PROTO(struct rwnx_sta *sta, u16 pkt_req, u8 ps_id), -+ TP_ARGS(sta, pkt_req, ps_id), -+ TP_STRUCT__entry( -+ __field(u16, idx) -+ __field(u16, pkt_req) -+ __field(u8, ps_id) -+ __field(u16, ready) -+ __field(u16, sp) -+ ), -+ TP_fast_assign( -+ __entry->idx = sta->sta_idx; -+ __entry->pkt_req = pkt_req; -+ __entry->ps_id = ps_id; -+ __entry->ready = sta->ps.pkt_ready[ps_id]; -+ __entry->sp = sta->ps.sp_cnt[ps_id]; -+ ), -+ -+ TP_printk("%s %s traffic request %d pkt (ready=%d, sp=%d)", -+ __print_sta(__entry->idx), -+ __entry->ps_id == UAPSD_ID ? "U-APSD" : "legacy PS", -+ __entry->pkt_req, __entry->ready, __entry->sp) -+); -+ -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+TRACE_EVENT( -+ amsdu_subframe, -+ TP_PROTO(struct rwnx_sw_txhdr *sw_txhdr), -+ TP_ARGS(sw_txhdr), -+ TP_STRUCT__entry( -+ __field(struct sk_buff *, skb) -+ __field(u16, txq_idx) -+ __field(u8, nb) -+ __field(u32, len) -+ ), -+ TP_fast_assign( -+ __entry->skb = sw_txhdr->skb; -+ __entry->nb = sw_txhdr->amsdu.nb; -+ __entry->len = sw_txhdr->amsdu.len; -+ __entry->txq_idx = sw_txhdr->txq->idx; -+ ), -+ -+ TP_printk("%s skb=%p %s nb_subframe=%d, len=%u", -+ __print_txq(__entry->txq_idx), __entry->skb, -+ (__entry->nb == 2) ? "Start new AMSDU" : "Add subframe", -+ __entry->nb, __entry->len) -+); -+#endif -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+TRACE_EVENT( -+ mu_group_update, -+ TP_PROTO(struct rwnx_mu_group *group), -+ TP_ARGS(group), -+ TP_STRUCT__entry( -+ __field(u8, nb_user) -+ __field(u8, group_id) -+ __array(u8, users, CONFIG_USER_MAX) -+ ), -+ TP_fast_assign( -+ int i; -+ __entry->nb_user = group->user_cnt; -+ for (i = 0; i < CONFIG_USER_MAX ; i++) { -+ if (group->users[i]) { -+ __entry->users[i] = group->users[i]->sta_idx; -+ } else { -+ __entry->users[i] = 0xff; -+ } -+ } -+ -+ __entry->group_id = group->group_id; -+ ), -+ -+ TP_printk("Group-id = %d, Users = %s", -+ __entry->group_id, -+ __print_mu_group(__entry->nb_user, __entry->users)) -+); -+ -+TRACE_EVENT( -+ mu_group_delete, -+ TP_PROTO(int group_id), -+ TP_ARGS(group_id), -+ TP_STRUCT__entry( -+ __field(u8, group_id) -+ ), -+ TP_fast_assign( -+ __entry->group_id = group_id; -+ ), -+ -+ TP_printk("Group-id = %d", __entry->group_id) -+); -+ -+TRACE_EVENT( -+ mu_group_selection, -+ TP_PROTO(struct rwnx_sta *sta, int group_id), -+ TP_ARGS(sta, group_id), -+ TP_STRUCT__entry( -+ __field(u8, sta_idx) -+ __field(u8, group_id) -+ ), -+ TP_fast_assign( -+ __entry->sta_idx = sta->sta_idx; -+ __entry->group_id = group_id; -+ ), -+ -+ TP_printk("[Sta %d] Group-id = %d", __entry->sta_idx, __entry->group_id) -+); -+ -+TRACE_EVENT( -+ txq_select_mu_group, -+ TP_PROTO(struct rwnx_txq *txq, int group_id, int pos), -+ -+ TP_ARGS(txq, group_id, pos), -+ -+ TP_STRUCT__entry( -+ __field(u16, txq_idx) -+ __field(u8, group_id) -+ __field(u8, pos) -+ ), -+ TP_fast_assign( -+ __entry->txq_idx = txq->idx; -+ __entry->group_id = group_id; -+ __entry->pos = pos; -+ ), -+ -+ TP_printk("%s: group=%d pos=%d", __print_txq(__entry->txq_idx), -+ __entry->group_id, __entry->pos) -+); -+ -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+#endif /* ! CONFIG_RWNX_FHOST */ -+ -+/***************************************************************************** -+ * TRACE functions for MESH -+ ****************************************************************************/ -+#ifdef CONFIG_RWNX_FULLMAC -+DECLARE_EVENT_CLASS( -+ mesh_path_template, -+ TP_PROTO(struct rwnx_mesh_path *mesh_path), -+ TP_ARGS(mesh_path), -+ TP_STRUCT__entry( -+ __field(u8, idx) -+ __field(u8, next_hop_sta) -+ __array(u8, tgt_mac, ETH_ALEN) -+ ), -+ -+ TP_fast_assign( -+ __entry->idx = mesh_path->path_idx; -+ memcpy(__entry->tgt_mac, &mesh_path->tgt_mac_addr, ETH_ALEN); -+ if (mesh_path->p_nhop_sta) -+ __entry->next_hop_sta = mesh_path->p_nhop_sta->sta_idx; -+ else -+ __entry->next_hop_sta = 0xff; -+ ), -+ -+ TP_printk("Mpath(%d): target=%pM next_hop=STA-%d", -+ __entry->idx, __entry->tgt_mac, __entry->next_hop_sta) -+); -+ -+DEFINE_EVENT(mesh_path_template, mesh_create_path, -+ TP_PROTO(struct rwnx_mesh_path *mesh_path), -+ TP_ARGS(mesh_path)); -+ -+DEFINE_EVENT(mesh_path_template, mesh_delete_path, -+ TP_PROTO(struct rwnx_mesh_path *mesh_path), -+ TP_ARGS(mesh_path)); -+ -+DEFINE_EVENT(mesh_path_template, mesh_update_path, -+ TP_PROTO(struct rwnx_mesh_path *mesh_path), -+ TP_ARGS(mesh_path)); -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+/***************************************************************************** -+ * TRACE functions for RADAR -+ ****************************************************************************/ -+#ifdef CONFIG_RWNX_RADAR -+TRACE_EVENT( -+ radar_pulse, -+ TP_PROTO(u8 chain, struct radar_pulse *pulse), -+ TP_ARGS(chain, pulse), -+ TP_STRUCT__entry( -+ __field(u8, chain) -+ __field(s16, freq) -+ __field(u16, pri) -+ __field(u8, len) -+ __field(u8, fom) -+ ), -+ TP_fast_assign( -+ __entry->freq = pulse->freq * 2; -+ __entry->len = pulse->len * 2; -+ __entry->fom = pulse->fom * 6; -+ __entry->pri = pulse->rep; -+ __entry->chain = chain; -+ ), -+ -+ TP_printk("%s: PRI=%.5d LEN=%.3d FOM=%.2d%% freq=%dMHz ", -+ __print_symbolic(__entry->chain, -+ {RWNX_RADAR_RIU, "RIU"}, -+ {RWNX_RADAR_FCU, "FCU"}), -+ __entry->pri, __entry->len, __entry->fom, __entry->freq) -+ ); -+ -+TRACE_EVENT( -+ radar_detected, -+ TP_PROTO(u8 chain, u8 region, s16 freq, u8 type, u16 pri), -+ TP_ARGS(chain, region, freq, type, pri), -+ TP_STRUCT__entry( -+ __field(u8, chain) -+ __field(u8, region) -+ __field(s16, freq) -+ __field(u8, type) -+ __field(u16, pri) -+ ), -+ TP_fast_assign( -+ __entry->chain = chain; -+ __entry->region = region; -+ __entry->freq = freq; -+ __entry->type = type; -+ __entry->pri = pri; -+ ), -+ TP_printk("%s: region=%s type=%d freq=%dMHz (pri=%dus)", -+ __print_symbolic(__entry->chain, -+ {RWNX_RADAR_RIU, "RIU"}, -+ {RWNX_RADAR_FCU, "FCU"}), -+ __print_symbolic(__entry->region, -+ {NL80211_DFS_UNSET, "UNSET"}, -+ {NL80211_DFS_FCC, "FCC"}, -+ {NL80211_DFS_ETSI, "ETSI"}, -+ {NL80211_DFS_JP, "JP"}), -+ __entry->type, __entry->freq, __entry->pri) -+); -+ -+TRACE_EVENT( -+ radar_set_region, -+ TP_PROTO(u8 region), -+ TP_ARGS(region), -+ TP_STRUCT__entry( -+ __field(u8, region) -+ ), -+ TP_fast_assign( -+ __entry->region = region; -+ ), -+ TP_printk("region=%s", -+ __print_symbolic(__entry->region, -+ {NL80211_DFS_UNSET, "UNSET"}, -+ {NL80211_DFS_FCC, "FCC"}, -+ {NL80211_DFS_ETSI, "ETSI"}, -+ {NL80211_DFS_JP, "JP"})) -+); -+ -+TRACE_EVENT( -+ radar_enable_detection, -+ TP_PROTO(u8 region, u8 enable, u8 chain), -+ TP_ARGS(region, enable, chain), -+ TP_STRUCT__entry( -+ __field(u8, region) -+ __field(u8, chain) -+ __field(u8, enable) -+ ), -+ TP_fast_assign( -+ __entry->chain = chain; -+ __entry->enable = enable; -+ __entry->region = region; -+ ), -+ TP_printk("%s: %s radar detection %s", -+ __print_symbolic(__entry->chain, -+ {RWNX_RADAR_RIU, "RIU"}, -+ {RWNX_RADAR_FCU, "FCU"}), -+ __print_symbolic(__entry->enable, -+ {RWNX_RADAR_DETECT_DISABLE, "Disable"}, -+ {RWNX_RADAR_DETECT_ENABLE, "Enable (no report)"}, -+ {RWNX_RADAR_DETECT_REPORT, "Enable"}), -+ __entry->enable == RWNX_RADAR_DETECT_DISABLE ? "" : -+ __print_symbolic(__entry->region, -+ {NL80211_DFS_UNSET, "UNSET"}, -+ {NL80211_DFS_FCC, "FCC"}, -+ {NL80211_DFS_ETSI, "ETSI"}, -+ {NL80211_DFS_JP, "JP"})) -+); -+#endif /* CONFIG_RWNX_RADAR */ -+ -+/***************************************************************************** -+ * TRACE functions for IPC message -+ ****************************************************************************/ -+#include "rwnx_strs.h" -+ -+DECLARE_EVENT_CLASS( -+ ipc_msg_template, -+ TP_PROTO(u16 id), -+ TP_ARGS(id), -+ TP_STRUCT__entry( -+ __field(u16, id) -+ ), -+ TP_fast_assign( -+ __entry->id = id; -+ ), -+ -+ TP_printk("%s (%d - %d)", RWNX_ID2STR(__entry->id), -+ MSG_T(__entry->id), MSG_I(__entry->id)) -+); -+ -+DEFINE_EVENT(ipc_msg_template, msg_send, -+ TP_PROTO(u16 id), -+ TP_ARGS(id)); -+ -+DEFINE_EVENT(ipc_msg_template, msg_recv, -+ TP_PROTO(u16 id), -+ TP_ARGS(id)); -+ -+ -+ -+#endif /* !defined(_RWNX_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ) */ -+ -+#undef TRACE_INCLUDE_PATH -+#undef TRACE_INCLUDE_FILE -+//#define TRACE_INCLUDE_PATH . -+#define TRACE_INCLUDE_PATH AIC_TRACE_INCLUDE_PATH -+#define TRACE_INCLUDE_FILE rwnx_events -+#include -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_fw_trace.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_fw_trace.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_fw_trace.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_fw_trace.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,48 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_fw_trace.c -+ * -+ * Copyright (C) RivieraWaves 2017-2019 -+ * -+ ****************************************************************************** -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "rwnx_fw_trace.h" -+#include "aicwf_debug.h" -+ -+int rwnx_fw_log_init(struct rwnx_fw_log *fw_log) -+{ -+ u8 *buf = kmalloc(FW_LOG_SIZE, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ fw_log->buf.data = buf; -+ fw_log->buf.start = fw_log->buf.data; -+ fw_log->buf.size = 0; -+ fw_log->buf.end = fw_log->buf.data; -+ fw_log->buf.dataend = fw_log->buf.data + FW_LOG_SIZE; -+ spin_lock_init(&fw_log->lock); -+ -+ AICWFDBG(LOGINFO, "fw_log_init: %lx, %lx\n", (unsigned long)fw_log->buf.start, (unsigned long)(fw_log->buf.dataend)); -+ return 0; -+} -+ -+void rwnx_fw_log_deinit(struct rwnx_fw_log *fw_log) -+{ -+ if (!fw_log) -+ return; -+ -+ if (fw_log->buf.data) -+ kfree(fw_log->buf.data); -+ fw_log->buf.start = NULL; -+ fw_log->buf.end = NULL; -+ fw_log->buf.size = 0; -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_fw_trace.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_fw_trace.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_fw_trace.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_fw_trace.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,35 @@ -+/** -+ ****************************************************************************** -+ * -+ * rwnx_fw_trace.h -+ * -+ * Copyright (C) RivieraWaves 2017-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _RWNX_FW_TRACE_H_ -+#define _RWNX_FW_TRACE_H_ -+ -+#include -+#include -+#include -+ -+#define FW_LOG_SIZE (10240) -+ -+struct rwnx_fw_log_buf { -+ uint8_t *data; -+ uint8_t *start; -+ uint8_t *end; -+ uint8_t *dataend; -+ uint32_t size; -+}; -+ -+struct rwnx_fw_log { -+ struct rwnx_fw_log_buf buf; -+ spinlock_t lock; -+}; -+ -+int rwnx_fw_log_init(struct rwnx_fw_log *fw_log); -+void rwnx_fw_log_deinit(struct rwnx_fw_log *fw_log); -+#endif /* _RWNX_FW_TRACE_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_gki.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_gki.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_gki.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_gki.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,408 @@ -+#include -+#ifdef ANDROID_PLATFORM -+#include "net/wireless/core.h" -+#endif -+#include -+ -+#undef NL80211_MCGRP_MLME -+#define NL80211_MCGRP_MLME 3 -+//#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) -+ -+static struct genl_family rwnx_nl80211_fam; -+ -+static bool __rwnx_cfg80211_unexpected_frame(struct net_device *dev, u8 cmd, -+ const u8 *addr, gfp_t gfp) -+{ -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); -+ struct sk_buff *msg; -+ void *hdr; -+ u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid); -+ -+ if (!nlportid) -+ return false; -+ -+ msg = nlmsg_new(100, gfp); -+ if (!msg) -+ return true; -+ -+ hdr = genlmsg_put(msg, 0, 0, &rwnx_nl80211_fam, 0, cmd); -+ if (!hdr) { -+ nlmsg_free(msg); -+ return true; -+ } -+ -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || -+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || -+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); -+ return true; -+ -+ nla_put_failure: -+ nlmsg_free(msg); -+ return true; -+} -+ -+bool rwnx_cfg80211_rx_spurious_frame(struct net_device *dev, -+ const u8 *addr, gfp_t gfp) -+{ -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ bool ret; -+ -+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && -+ wdev->iftype != NL80211_IFTYPE_P2P_GO)) { -+ return false; -+ } -+ ret = __rwnx_cfg80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME, -+ addr, gfp); -+ return ret; -+} -+ -+bool rwnx_cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, -+ const u8 *addr, gfp_t gfp) -+{ -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ bool ret; -+ -+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && -+ wdev->iftype != NL80211_IFTYPE_P2P_GO && -+ wdev->iftype != NL80211_IFTYPE_AP_VLAN)) { -+ return false; -+ } -+ ret = __rwnx_cfg80211_unexpected_frame(dev, -+ NL80211_CMD_UNEXPECTED_4ADDR_FRAME, -+ addr, gfp); -+ return ret; -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) -+void rwnx_cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr, -+ const u8 *ie, u8 ie_len, -+ int sig_dbm, gfp_t gfp) -+{ -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); -+ struct sk_buff *msg; -+ void *hdr; -+ -+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) -+ return; -+ -+ msg = nlmsg_new(100 + ie_len, gfp); -+ if (!msg) -+ return; -+ -+ hdr = genlmsg_put(msg, 0, 0, &rwnx_nl80211_fam, 0, NL80211_CMD_NEW_PEER_CANDIDATE); -+ if (!hdr) { -+ nlmsg_free(msg); -+ return; -+ } -+ -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || -+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || -+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) || -+ (ie_len && ie && -+ nla_put(msg, NL80211_ATTR_IE, ie_len, ie)) || -+ (sig_dbm && -+ nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm))) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ -+#define NL80211_MCGRP_MLME 3 -+ genlmsg_multicast_netns(&rwnx_nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, -+ NL80211_MCGRP_MLME, gfp); -+ return; -+ -+ nla_put_failure: -+ nlmsg_free(msg); -+} -+#endif -+ -+void rwnx_cfg80211_report_obss_beacon(struct wiphy *wiphy, -+ const u8 *frame, size_t len, -+ int freq, int sig_dbm) -+{ -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -+ struct sk_buff *msg; -+ void *hdr; -+ struct cfg80211_beacon_registration *reg; -+ -+ spin_lock_bh(&rdev->beacon_registrations_lock); -+ list_for_each_entry(reg, &rdev->beacon_registrations, list) { -+ msg = nlmsg_new(len + 100, GFP_ATOMIC); -+ if (!msg) { -+ spin_unlock_bh(&rdev->beacon_registrations_lock); -+ return; -+ } -+ -+ hdr = genlmsg_put(msg, 0, 0, &rwnx_nl80211_fam, 0, NL80211_CMD_FRAME); -+ if (!hdr) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || -+ (freq && -+ nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) || -+ (sig_dbm && -+ nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || -+ nla_put(msg, NL80211_ATTR_FRAME, len, frame)) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ -+ genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid); -+ } -+ spin_unlock_bh(&rdev->beacon_registrations_lock); -+ return; -+ -+ nla_put_failure: -+ spin_unlock_bh(&rdev->beacon_registrations_lock); -+ nlmsg_free(msg); -+} -+ -+static int rwnx_nl80211_send_chandef(struct sk_buff *msg, -+ const struct cfg80211_chan_def *chandef) -+{ -+ if (WARN_ON(!cfg80211_chandef_valid(chandef))) -+ return -EINVAL; -+ -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, -+ chandef->chan->center_freq)) -+ return -ENOBUFS; -+ switch (chandef->width) { -+ case NL80211_CHAN_WIDTH_20_NOHT: -+ case NL80211_CHAN_WIDTH_20: -+ case NL80211_CHAN_WIDTH_40: -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, -+ cfg80211_get_chandef_type(chandef))) -+ return -ENOBUFS; -+ break; -+ default: -+ break; -+ } -+ if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width)) -+ return -ENOBUFS; -+ if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1)) -+ return -ENOBUFS; -+ if (chandef->center_freq2 && -+ nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2)) -+ return -ENOBUFS; -+ return 0; -+} -+ -+void rwnx_cfg80211_ch_switch_notify(struct cfg80211_registered_device *rdev, -+ struct net_device *netdev, -+ struct cfg80211_chan_def *chandef, -+ gfp_t gfp, -+ enum nl80211_commands notif, -+ u8 count) -+{ -+ struct sk_buff *msg; -+ void *hdr; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); -+ if (!msg) -+ return; -+ -+ hdr = genlmsg_put(msg, 0, 0, &rwnx_nl80211_fam, 0, notif); -+ if (!hdr) { -+ nlmsg_free(msg); -+ return; -+ } -+ -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ -+ if (rwnx_nl80211_send_chandef(msg, chandef)) -+ goto nla_put_failure; -+ -+ if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) && -+ (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count))) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ -+ genlmsg_multicast_netns(&rwnx_nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, -+ NL80211_MCGRP_MLME, gfp); -+ return; -+ -+ nla_put_failure: -+ nlmsg_free(msg); -+} -+ -+void rwnx_cfg80211_ch_switch_started_notify(struct net_device *dev, -+ struct cfg80211_chan_def *chandef, -+ u8 count -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) -+ , bool quiet -+ #endif -+ ) -+{ -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ struct wiphy *wiphy = wdev->wiphy; -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -+ -+ rwnx_cfg80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL, -+ NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count); -+} -+ -+int rwnx_regulatory_set_wiphy_regd_sync_rtnl(struct wiphy *wiphy, -+ struct ieee80211_regdomain *rd) -+{ -+ wiphy_apply_custom_regulatory(wiphy, rd); -+ return 0; -+} -+ -+void rwnx_skb_append(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list) -+{ -+ unsigned long flags; -+ struct sk_buff *prev = old; -+ struct sk_buff *next = prev->next; -+ spin_lock_irqsave(&list->lock, flags); -+ WRITE_ONCE(newsk->next, next); -+ WRITE_ONCE(newsk->prev, prev); -+ WRITE_ONCE(next->prev, newsk); -+ WRITE_ONCE(prev->next, newsk); -+ list->qlen++; -+ spin_unlock_irqrestore(&list->lock, flags); -+} -+ -+bool rwnx_ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef, -+ u8 *op_class) -+{ -+ u8 vht_opclass; -+ u32 freq = chandef->center_freq1; -+ -+ if (freq >= 2412 && freq <= 2472) { -+ if (chandef->width > NL80211_CHAN_WIDTH_40) -+ return false; -+ -+ /* 2.407 GHz, channels 1..13 */ -+ if (chandef->width == NL80211_CHAN_WIDTH_40) { -+ if (freq > chandef->chan->center_freq) -+ *op_class = 83; /* HT40+ */ -+ else -+ *op_class = 84; /* HT40- */ -+ } else { -+ *op_class = 81; -+ } -+ -+ return true; -+ } -+ -+ if (freq == 2484) { -+ /* channel 14 is only for IEEE 802.11b */ -+ if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT) -+ return false; -+ -+ *op_class = 82; /* channel 14 */ -+ return true; -+ } -+ -+ switch (chandef->width) { -+ case NL80211_CHAN_WIDTH_80: -+ vht_opclass = 128; -+ break; -+ case NL80211_CHAN_WIDTH_160: -+ vht_opclass = 129; -+ break; -+ case NL80211_CHAN_WIDTH_80P80: -+ vht_opclass = 130; -+ break; -+ case NL80211_CHAN_WIDTH_10: -+ case NL80211_CHAN_WIDTH_5: -+ return false; /* unsupported for now */ -+ default: -+ vht_opclass = 0; -+ break; -+ } -+ -+ /* 5 GHz, channels 36..48 */ -+ if (freq >= 5180 && freq <= 5240) { -+ if (vht_opclass) { -+ *op_class = vht_opclass; -+ } else if (chandef->width == NL80211_CHAN_WIDTH_40) { -+ if (freq > chandef->chan->center_freq) -+ *op_class = 116; -+ else -+ *op_class = 117; -+ } else { -+ *op_class = 115; -+ } -+ -+ return true; -+ } -+ -+ /* 5 GHz, channels 52..64 */ -+ if (freq >= 5260 && freq <= 5320) { -+ if (vht_opclass) { -+ *op_class = vht_opclass; -+ } else if (chandef->width == NL80211_CHAN_WIDTH_40) { -+ if (freq > chandef->chan->center_freq) -+ *op_class = 119; -+ else -+ *op_class = 120; -+ } else { -+ *op_class = 118; -+ } -+ -+ return true; -+ } -+ -+ /* 5 GHz, channels 100..144 */ -+ if (freq >= 5500 && freq <= 5720) { -+ if (vht_opclass) { -+ *op_class = vht_opclass; -+ } else if (chandef->width == NL80211_CHAN_WIDTH_40) { -+ if (freq > chandef->chan->center_freq) -+ *op_class = 122; -+ else -+ *op_class = 123; -+ } else { -+ *op_class = 121; -+ } -+ -+ return true; -+ } -+ -+ /* 5 GHz, channels 149..169 */ -+ if (freq >= 5745 && freq <= 5845) { -+ if (vht_opclass) { -+ *op_class = vht_opclass; -+ } else if (chandef->width == NL80211_CHAN_WIDTH_40) { -+ if (freq > chandef->chan->center_freq) -+ *op_class = 126; -+ else -+ *op_class = 127; -+ } else if (freq <= 5805) { -+ *op_class = 124; -+ } else { -+ *op_class = 125; -+ } -+ -+ return true; -+ } -+ -+ /* 56.16 GHz, channel 1..4 */ -+ if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 6) { -+ if (chandef->width >= NL80211_CHAN_WIDTH_40) -+ return false; -+ -+ *op_class = 180; -+ return true; -+ } -+ -+ /* not supported yet */ -+ return false; -+} -+ -+int rwnx_call_usermodehelper(const char *path, char **argv, char **envp, int wait) -+{ -+ return -1; -+} -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_gki.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_gki.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_gki.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_gki.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,72 @@ -+#ifndef __RWNX_GKI_H -+#define __RWNX_GKI_H -+ -+#ifdef ANDROID_PLATFORM -+#include "net/wireless/core.h" -+#endif -+ -+//#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) -+ -+ -+bool rwnx_cfg80211_rx_spurious_frame(struct net_device *dev, -+ const u8 *addr, gfp_t gfp); -+ -+bool rwnx_cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, -+ const u8 *addr, gfp_t gfp); -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) -+void rwnx_cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr, -+ const u8 *ie, u8 ie_len, -+ int sig_dbm, gfp_t gfp); -+#endif -+ -+void rwnx_cfg80211_report_obss_beacon(struct wiphy *wiphy, -+ const u8 *frame, size_t len, -+ int freq, int sig_dbm); -+ -+void rwnx_cfg80211_ch_switch_notify(struct cfg80211_registered_device *rdev, -+ struct net_device *netdev, -+ struct cfg80211_chan_def *chandef, -+ gfp_t gfp, -+ enum nl80211_commands notif, -+ u8 count); -+ -+void rwnx_cfg80211_ch_switch_started_notify(struct net_device *dev, -+ struct cfg80211_chan_def *chandef, -+ u8 count -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) -+ , bool quiet -+ #endif -+ ); -+ -+int rwnx_regulatory_set_wiphy_regd_sync_rtnl(struct wiphy *wiphy, -+ struct ieee80211_regdomain *rd); -+ -+void rwnx_skb_append(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list); -+ -+bool rwnx_ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef, -+ u8 *op_class); -+ -+int rwnx_call_usermodehelper(const char *path, char **argv, char **envp, int wait); -+ -+#else -+ -+#define rwnx_cfg80211_rx_spurious_frame cfg80211_rx_spurious_frame -+#define rwnx_cfg80211_rx_unexpected_4addr_frame cfg80211_rx_unexpected_4addr_frame -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) -+#define rwnx_cfg80211_notify_new_peer_candidate cfg80211_notify_new_peer_candidate -+#endif -+ -+#define rwnx_cfg80211_report_obss_beacon cfg80211_report_obss_beacon -+#define rwnx_cfg80211_ch_switch_notify cfg80211_ch_switch_notify -+#define rwnx_cfg80211_ch_switch_started_notify cfg80211_ch_switch_started_notify -+#define rwnx_regulatory_set_wiphy_regd_sync_rtnl regulatory_set_wiphy_regd_sync_rtnl -+#define rwnx_skb_append skb_append -+#define rwnx_ieee80211_chandef_to_operating_class ieee80211_chandef_to_operating_class -+#define rwnx_call_usermodehelper call_usermodehelper -+ -+#endif -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_irqs.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_irqs.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_irqs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_irqs.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,65 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_irqs.c -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+#include -+ -+#include "rwnx_defs.h" -+#include "ipc_host.h" -+#include "rwnx_prof.h" -+ -+/** -+ * rwnx_irq_hdlr - IRQ handler -+ * -+ * Handler registerd by the platform driver -+ */ -+irqreturn_t rwnx_irq_hdlr(int irq, void *dev_id) -+{ -+ struct rwnx_hw *rwnx_hw = (struct rwnx_hw *)dev_id; -+ disable_irq_nosync(irq); -+ tasklet_schedule(&rwnx_hw->task); -+ return IRQ_HANDLED; -+} -+ -+/** -+ * rwnx_task - Bottom half for IRQ handler -+ * -+ * Read irq status and process accordingly -+ */ -+void rwnx_task(unsigned long data) -+{ -+ struct rwnx_hw *rwnx_hw = (struct rwnx_hw *)data; -+ -+#if 0 -+ struct rwnx_plat *rwnx_plat = rwnx_hw->plat; -+ u32 status, statuses = 0; -+ -+ /* Ack unconditionnally in case ipc_host_get_status does not see the irq */ -+ rwnx_plat->ack_irq(rwnx_plat); -+ -+ while ((status = ipc_host_get_status(rwnx_hw->ipc_env))) { -+ statuses |= status; -+ /* All kinds of IRQs will be handled in one shot (RX, MSG, DBG, ...) -+ * this will ack IPC irqs not the cfpga irqs */ -+ ipc_host_irq(rwnx_hw->ipc_env, status); -+ -+ rwnx_plat->ack_irq(rwnx_plat); -+ } -+#endif -+ //if (statuses & IPC_IRQ_E2A_RXDESC) -+ // rwnx_hw->stats.last_rx = now; -+ //if (statuses & IPC_IRQ_E2A_TXCFM) -+ // rwnx_hw->stats.last_tx = now; -+ -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ rwnx_hwq_process_all(rwnx_hw); -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+#if 0 -+ enable_irq(rwnx_platform_get_irq(rwnx_plat)); -+#endif -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_irqs.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_irqs.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_irqs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_irqs.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,20 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_irqs.h -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+#ifndef _RWNX_IRQS_H_ -+#define _RWNX_IRQS_H_ -+ -+#include -+ -+/* IRQ handler to be registered by platform driver */ -+irqreturn_t rwnx_irq_hdlr(int irq, void *dev_id); -+ -+void rwnx_task(unsigned long data); -+ -+#endif /* _RWNX_IRQS_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,7391 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_main.c -+ * -+ * @brief Entry point of the RWNX driver -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "rwnx_defs.h" -+#include "rwnx_dini.h" -+#include "rwnx_msg_tx.h" -+#include "reg_access.h" -+#include "hal_desc.h" -+#include "rwnx_debugfs.h" -+#include "rwnx_cfgfile.h" -+#include "rwnx_irqs.h" -+#include "rwnx_radar.h" -+#include "rwnx_version.h" -+#ifdef CONFIG_RWNX_BFMER -+#include "rwnx_bfmer.h" -+#endif //(CONFIG_RWNX_BFMER) -+#include "rwnx_tdls.h" -+#include "rwnx_events.h" -+#include "rwnx_compat.h" -+#include "rwnx_version.h" -+#include "rwnx_main.h" -+#include "aicwf_txrxif.h" -+#ifdef AICWF_SDIO_SUPPORT -+#include "aicwf_sdio.h" -+#endif -+#ifdef AICWF_USB_SUPPORT -+#include "aicwf_usb.h" -+#endif -+#include "aic_bsp_export.h" -+#include "aicwf_compat_8800dc.h" -+#include "aicwf_compat_8800d80.h" -+#include "rwnx_wakelock.h" -+#ifdef CONFIG_SDIO_BT -+#include "aic_btsdio.h" -+#endif -+ -+ -+#define RW_DRV_DESCRIPTION "RivieraWaves 11nac driver for Linux cfg80211" -+#define RW_DRV_COPYRIGHT "Copyright(c) 2015-2017 RivieraWaves" -+#define RW_DRV_AUTHOR "RivieraWaves S.A.S" -+ -+#define RWNX_PRINT_CFM_ERR(req) \ -+ printk(KERN_CRIT "%s: Status Error(%d)\n", #req, (&req##_cfm)->status) -+ -+#define RWNX_HT_CAPABILITIES \ -+{ \ -+ .ht_supported = true, \ -+ .cap = 0, \ -+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ -+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, \ -+ .mcs = { \ -+ .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \ -+ .rx_highest = cpu_to_le16(65), \ -+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ -+ }, \ -+} -+ -+#define RWNX_VHT_CAPABILITIES \ -+{ \ -+ .vht_supported = false, \ -+ .cap = \ -+ (7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT),\ -+ .vht_mcs = { \ -+ .rx_mcs_map = cpu_to_le16( \ -+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 14), \ -+ .tx_mcs_map = cpu_to_le16( \ -+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | \ -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << 14), \ -+ } \ -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) || defined(CONFIG_HE_FOR_OLD_KERNEL) -+#define RWNX_HE_CAPABILITIES \ -+{ \ -+ .has_he = false, \ -+ .he_cap_elem = { \ -+ .mac_cap_info[0] = 0, \ -+ .mac_cap_info[1] = 0, \ -+ .mac_cap_info[2] = 0, \ -+ .mac_cap_info[3] = 0, \ -+ .mac_cap_info[4] = 0, \ -+ .mac_cap_info[5] = 0, \ -+ .phy_cap_info[0] = 0, \ -+ .phy_cap_info[1] = 0, \ -+ .phy_cap_info[2] = 0, \ -+ .phy_cap_info[3] = 0, \ -+ .phy_cap_info[4] = 0, \ -+ .phy_cap_info[5] = 0, \ -+ .phy_cap_info[6] = 0, \ -+ .phy_cap_info[7] = 0, \ -+ .phy_cap_info[8] = 0, \ -+ .phy_cap_info[9] = 0, \ -+ .phy_cap_info[10] = 0, \ -+ }, \ -+ .he_mcs_nss_supp = { \ -+ .rx_mcs_80 = cpu_to_le16(0xfffa), \ -+ .tx_mcs_80 = cpu_to_le16(0xfffa), \ -+ .rx_mcs_160 = cpu_to_le16(0xffff), \ -+ .tx_mcs_160 = cpu_to_le16(0xffff), \ -+ .rx_mcs_80p80 = cpu_to_le16(0xffff), \ -+ .tx_mcs_80p80 = cpu_to_le16(0xffff), \ -+ }, \ -+ .ppe_thres = {0x08, 0x1c, 0x07}, \ -+} -+#else -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+#define RWNX_HE_CAPABILITIES \ -+{ \ -+ .has_he = false, \ -+ .he_cap_elem = { \ -+ .mac_cap_info[0] = 0, \ -+ .mac_cap_info[1] = 0, \ -+ .mac_cap_info[2] = 0, \ -+ .mac_cap_info[3] = 0, \ -+ .mac_cap_info[4] = 0, \ -+ .phy_cap_info[0] = 0, \ -+ .phy_cap_info[1] = 0, \ -+ .phy_cap_info[2] = 0, \ -+ .phy_cap_info[3] = 0, \ -+ .phy_cap_info[4] = 0, \ -+ .phy_cap_info[5] = 0, \ -+ .phy_cap_info[6] = 0, \ -+ .phy_cap_info[7] = 0, \ -+ .phy_cap_info[8] = 0, \ -+ }, \ -+ .he_mcs_nss_supp = { \ -+ .rx_mcs_80 = cpu_to_le16(0xfffa), \ -+ .tx_mcs_80 = cpu_to_le16(0xfffa), \ -+ .rx_mcs_160 = cpu_to_le16(0xffff), \ -+ .tx_mcs_160 = cpu_to_le16(0xffff), \ -+ .rx_mcs_80p80 = cpu_to_le16(0xffff), \ -+ .tx_mcs_80p80 = cpu_to_le16(0xffff), \ -+ }, \ -+ .ppe_thres = {0x08, 0x1c, 0x07}, \ -+} -+#endif -+#endif -+ -+#define RATE(_bitrate, _hw_rate, _flags) { \ -+ .bitrate = (_bitrate), \ -+ .flags = (_flags), \ -+ .hw_value = (_hw_rate), \ -+} -+ -+#define CHAN(_freq) { \ -+ .center_freq = (_freq), \ -+ .max_power = 30, /* FIXME */ \ -+} -+ -+static struct ieee80211_rate rwnx_ratetable[] = { -+ RATE(10, 0x00, 0), -+ RATE(20, 0x01, IEEE80211_RATE_SHORT_PREAMBLE), -+ RATE(55, 0x02, IEEE80211_RATE_SHORT_PREAMBLE), -+ RATE(110, 0x03, IEEE80211_RATE_SHORT_PREAMBLE), -+ RATE(60, 0x04, 0), -+ RATE(90, 0x05, 0), -+ RATE(120, 0x06, 0), -+ RATE(180, 0x07, 0), -+ RATE(240, 0x08, 0), -+ RATE(360, 0x09, 0), -+ RATE(480, 0x0A, 0), -+ RATE(540, 0x0B, 0), -+}; -+ -+/* The channels indexes here are not used anymore */ -+static struct ieee80211_channel rwnx_2ghz_channels[] = { -+ CHAN(2412), -+ CHAN(2417), -+ CHAN(2422), -+ CHAN(2427), -+ CHAN(2432), -+ CHAN(2437), -+ CHAN(2442), -+ CHAN(2447), -+ CHAN(2452), -+ CHAN(2457), -+ CHAN(2462), -+ CHAN(2467), -+ CHAN(2472), -+ CHAN(2484), -+ // Extra channels defined only to be used for PHY measures. -+ // Enabled only if custregd and custchan parameters are set -+ CHAN(2390), -+ CHAN(2400), -+ CHAN(2410), -+ CHAN(2420), -+ CHAN(2430), -+ CHAN(2440), -+ CHAN(2450), -+ CHAN(2460), -+ CHAN(2470), -+ CHAN(2480), -+ CHAN(2490), -+ CHAN(2500), -+ CHAN(2510), -+}; -+ -+static struct ieee80211_channel rwnx_5ghz_channels[] = { -+ CHAN(5180), // 36 - 20MHz -+ CHAN(5200), // 40 - 20MHz -+ CHAN(5220), // 44 - 20MHz -+ CHAN(5240), // 48 - 20MHz -+ CHAN(5260), // 52 - 20MHz -+ CHAN(5280), // 56 - 20MHz -+ CHAN(5300), // 60 - 20MHz -+ CHAN(5320), // 64 - 20MHz -+ CHAN(5500), // 100 - 20MHz -+ CHAN(5520), // 104 - 20MHz -+ CHAN(5540), // 108 - 20MHz -+ CHAN(5560), // 112 - 20MHz -+ CHAN(5580), // 116 - 20MHz -+ CHAN(5600), // 120 - 20MHz -+ CHAN(5620), // 124 - 20MHz -+ CHAN(5640), // 128 - 20MHz -+ CHAN(5660), // 132 - 20MHz -+ CHAN(5680), // 136 - 20MHz -+ CHAN(5700), // 140 - 20MHz -+ CHAN(5720), // 144 - 20MHz -+ CHAN(5745), // 149 - 20MHz -+ CHAN(5765), // 153 - 20MHz -+ CHAN(5785), // 157 - 20MHz -+ CHAN(5805), // 161 - 20MHz -+ CHAN(5825), // 165 - 20MHz -+ // Extra channels defined only to be used for PHY measures. -+ // Enabled only if custregd and custchan parameters are set -+ CHAN(5190), -+ CHAN(5210), -+ CHAN(5230), -+ CHAN(5250), -+ CHAN(5270), -+ CHAN(5290), -+ CHAN(5310), -+ CHAN(5330), -+ CHAN(5340), -+ CHAN(5350), -+ CHAN(5360), -+ CHAN(5370), -+ CHAN(5380), -+ CHAN(5390), -+ CHAN(5400), -+ CHAN(5410), -+ CHAN(5420), -+ CHAN(5430), -+ CHAN(5440), -+ CHAN(5450), -+ CHAN(5460), -+ CHAN(5470), -+ CHAN(5480), -+ CHAN(5490), -+ CHAN(5510), -+ CHAN(5530), -+ CHAN(5550), -+ CHAN(5570), -+ CHAN(5590), -+ CHAN(5610), -+ CHAN(5630), -+ CHAN(5650), -+ CHAN(5670), -+ CHAN(5690), -+ CHAN(5710), -+ CHAN(5730), -+ CHAN(5750), -+ CHAN(5760), -+ CHAN(5770), -+ CHAN(5780), -+ CHAN(5790), -+ CHAN(5800), -+ CHAN(5810), -+ CHAN(5820), -+ CHAN(5830), -+ CHAN(5840), -+ CHAN(5850), -+ CHAN(5860), -+ CHAN(5870), -+ CHAN(5880), -+ CHAN(5890), -+ CHAN(5900), -+ CHAN(5910), -+ CHAN(5920), -+ CHAN(5930), -+ CHAN(5940), -+ CHAN(5950), -+ CHAN(5960), -+ CHAN(5970), -+}; -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) || defined(CONFIG_HE_FOR_OLD_KERNEL) -+struct ieee80211_sband_iftype_data rwnx_he_capa = { -+ .types_mask = BIT(NL80211_IFTYPE_STATION)|BIT(NL80211_IFTYPE_AP), -+ .he_cap = RWNX_HE_CAPABILITIES, -+}; -+#endif -+ -+static struct ieee80211_supported_band rwnx_band_2GHz = { -+ .channels = rwnx_2ghz_channels, -+ .n_channels = ARRAY_SIZE(rwnx_2ghz_channels) - 13, // -13 to exclude extra channels -+ .bitrates = rwnx_ratetable, -+ .n_bitrates = ARRAY_SIZE(rwnx_ratetable), -+ .ht_cap = RWNX_HT_CAPABILITIES, -+ .vht_cap = RWNX_VHT_CAPABILITIES, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ .iftype_data = &rwnx_he_capa, -+ .n_iftype_data = 1, -+#endif -+}; -+ -+static struct ieee80211_supported_band rwnx_band_5GHz = { -+ .channels = rwnx_5ghz_channels, -+ .n_channels = ARRAY_SIZE(rwnx_5ghz_channels) - 59, // -59 to exclude extra channels -+ .bitrates = &rwnx_ratetable[4], -+ .n_bitrates = ARRAY_SIZE(rwnx_ratetable) - 4, -+ .ht_cap = RWNX_HT_CAPABILITIES, -+ .vht_cap = RWNX_VHT_CAPABILITIES, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ .iftype_data = &rwnx_he_capa, -+ .n_iftype_data = 1, -+#endif -+}; -+ -+static struct ieee80211_iface_limit rwnx_limits[] = { -+ { .max = 1, -+ .types = BIT(NL80211_IFTYPE_STATION)}, -+ { .max = 1, -+ .types = BIT(NL80211_IFTYPE_AP)}, -+#ifdef CONFIG_USE_P2P0 -+ { .max = 2, -+#else -+ { .max = 1, -+#endif -+ .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO)}, -+#ifndef CONFIG_USE_P2P0 -+ { .max = 1, -+ .types = BIT(NL80211_IFTYPE_P2P_DEVICE), -+ } -+#endif -+}; -+ -+static struct ieee80211_iface_limit rwnx_limits_dfs[] = { -+ { .max = NX_VIRT_DEV_MAX, .types = BIT(NL80211_IFTYPE_AP)} -+}; -+ -+static const struct ieee80211_iface_combination rwnx_combinations[] = { -+ { -+ .limits = rwnx_limits, -+ .n_limits = ARRAY_SIZE(rwnx_limits), -+#ifdef CONFIG_MCC -+ .num_different_channels = NX_CHAN_CTXT_CNT, -+#else -+ .num_different_channels = 1, -+#endif -+ .max_interfaces = NX_VIRT_DEV_MAX, -+ }, -+ /* Keep this combination as the last one */ -+ { -+ .limits = rwnx_limits_dfs, -+ .n_limits = ARRAY_SIZE(rwnx_limits_dfs), -+ .num_different_channels = 1, -+ .max_interfaces = NX_VIRT_DEV_MAX, -+ .radar_detect_widths = (BIT(NL80211_CHAN_WIDTH_20_NOHT) | -+ BIT(NL80211_CHAN_WIDTH_20) | -+ BIT(NL80211_CHAN_WIDTH_40) | -+ BIT(NL80211_CHAN_WIDTH_80)), -+ } -+}; -+ -+/* There isn't a lot of sense in it, but you can transmit anything you like */ -+static struct ieee80211_txrx_stypes -+rwnx_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { -+ [NL80211_IFTYPE_STATION] = { -+ .tx = 0xffff, -+ .rx = (BIT(IEEE80211_STYPE_ACTION >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4)), -+ }, -+ [NL80211_IFTYPE_AP] = { -+ .tx = 0xffff, -+ .rx = (BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | -+ BIT(IEEE80211_STYPE_ACTION >> 4)), -+ }, -+ [NL80211_IFTYPE_AP_VLAN] = { -+ /* copy AP */ -+ .tx = 0xffff, -+ .rx = (BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | -+ BIT(IEEE80211_STYPE_ACTION >> 4)), -+ }, -+ [NL80211_IFTYPE_P2P_CLIENT] = { -+ .tx = 0xffff, -+ .rx = (BIT(IEEE80211_STYPE_ACTION >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)), -+ }, -+ [NL80211_IFTYPE_P2P_GO] = { -+ .tx = 0xffff, -+ .rx = (BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | -+ BIT(IEEE80211_STYPE_ACTION >> 4)), -+ }, -+ [NL80211_IFTYPE_P2P_DEVICE] = { -+ .tx = 0xffff, -+ .rx = (BIT(IEEE80211_STYPE_ACTION >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)), -+ }, -+ [NL80211_IFTYPE_MESH_POINT] = { -+ .tx = 0xffff, -+ .rx = (BIT(IEEE80211_STYPE_ACTION >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4)), -+ }, -+}; -+ -+ -+static u32 cipher_suites[] = { -+ WLAN_CIPHER_SUITE_WEP40, -+ WLAN_CIPHER_SUITE_WEP104, -+ WLAN_CIPHER_SUITE_TKIP, -+ WLAN_CIPHER_SUITE_CCMP, -+ WLAN_CIPHER_SUITE_AES_CMAC, // reserved entries to enable AES-CMAC and/or SMS4 -+ WLAN_CIPHER_SUITE_SMS4, -+ 0, -+}; -+#define NB_RESERVED_CIPHER 1; -+ -+static const int rwnx_ac2hwq[1][NL80211_NUM_ACS] = { -+ { -+ [NL80211_TXQ_Q_VO] = RWNX_HWQ_VO, -+ [NL80211_TXQ_Q_VI] = RWNX_HWQ_VI, -+ [NL80211_TXQ_Q_BE] = RWNX_HWQ_BE, -+ [NL80211_TXQ_Q_BK] = RWNX_HWQ_BK -+ } -+}; -+ -+const int rwnx_tid2hwq[IEEE80211_NUM_TIDS] = { -+ RWNX_HWQ_BE, -+ RWNX_HWQ_BK, -+ RWNX_HWQ_BK, -+ RWNX_HWQ_BE, -+ RWNX_HWQ_VI, -+ RWNX_HWQ_VI, -+ RWNX_HWQ_VO, -+ RWNX_HWQ_VO, -+ /* TID_8 is used for management frames */ -+ RWNX_HWQ_VO, -+ /* At the moment, all others TID are mapped to BE */ -+ RWNX_HWQ_BE, -+ RWNX_HWQ_BE, -+ RWNX_HWQ_BE, -+ RWNX_HWQ_BE, -+ RWNX_HWQ_BE, -+ RWNX_HWQ_BE, -+ RWNX_HWQ_BE, -+}; -+ -+static const int rwnx_hwq2uapsd[NL80211_NUM_ACS] = { -+ [RWNX_HWQ_VO] = IEEE80211_WMM_IE_STA_QOSINFO_AC_VO, -+ [RWNX_HWQ_VI] = IEEE80211_WMM_IE_STA_QOSINFO_AC_VI, -+ [RWNX_HWQ_BE] = IEEE80211_WMM_IE_STA_QOSINFO_AC_BE, -+ [RWNX_HWQ_BK] = IEEE80211_WMM_IE_STA_QOSINFO_AC_BK, -+}; -+ -+#define P2P_ALIVE_TIME_MS (1*1000) -+#define P2P_ALIVE_TIME_COUNT 200 -+ -+ -+extern uint8_t scanning; -+int aicwf_dbg_level = LOGERROR|LOGINFO|LOGDEBUG|LOGTRACE; -+module_param(aicwf_dbg_level, int, 0660); -+int testmode = 0; -+char aic_fw_path[200]; -+u8 chip_sub_id = 0; -+u8 chip_mcu_id = 0; -+u8 chip_id = 0; -+ -+int rwnx_init_cmd_array(void); -+void rwnx_free_cmd_array(void); -+ -+ -+/********************************************************************* -+ * helper -+ *********************************************************************/ -+struct rwnx_sta *rwnx_get_sta(struct rwnx_hw *rwnx_hw, const u8 *mac_addr) -+{ -+ int i; -+ -+ for (i = 0; i < NX_REMOTE_STA_MAX; i++) { -+ struct rwnx_sta *sta = &rwnx_hw->sta_table[i]; -+ if (sta->valid && (memcmp(mac_addr, &sta->mac_addr, 6) == 0)) -+ return sta; -+ } -+ -+ return NULL; -+} -+ -+void rwnx_enable_wapi(struct rwnx_hw *rwnx_hw) -+{ -+ //cipher_suites[rwnx_hw->wiphy->n_cipher_suites] = WLAN_CIPHER_SUITE_SMS4; -+ rwnx_hw->wiphy->n_cipher_suites++; -+ rwnx_hw->wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; -+} -+ -+void rwnx_enable_mfp(struct rwnx_hw *rwnx_hw) -+{ -+ cipher_suites[rwnx_hw->wiphy->n_cipher_suites] = WLAN_CIPHER_SUITE_AES_CMAC; -+ rwnx_hw->wiphy->n_cipher_suites++; -+} -+ -+u8 *rwnx_build_bcn(struct rwnx_bcn *bcn, struct cfg80211_beacon_data *new) -+{ -+ u8 *buf, *pos; -+ -+ if (new->head) { -+ u8 *head = kmalloc(new->head_len, GFP_KERNEL); -+ -+ if (!head) -+ return NULL; -+ -+ if (bcn->head) -+ kfree(bcn->head); -+ -+ bcn->head = head; -+ bcn->head_len = new->head_len; -+ memcpy(bcn->head, new->head, new->head_len); -+ } -+ if (new->tail) { -+ u8 *tail = kmalloc(new->tail_len, GFP_KERNEL); -+ -+ if (!tail) -+ return NULL; -+ -+ if (bcn->tail) -+ kfree(bcn->tail); -+ -+ bcn->tail = tail; -+ bcn->tail_len = new->tail_len; -+ memcpy(bcn->tail, new->tail, new->tail_len); -+ } -+ -+ if (!bcn->head) -+ return NULL; -+ -+ bcn->tim_len = 6; -+ bcn->len = bcn->head_len + bcn->tail_len + bcn->ies_len + bcn->tim_len; -+ -+ buf = kmalloc(bcn->len, GFP_KERNEL); -+ if (!buf) -+ return NULL; -+ -+ // Build the beacon buffer -+ pos = buf; -+ memcpy(pos, bcn->head, bcn->head_len); -+ pos += bcn->head_len; -+ *pos++ = WLAN_EID_TIM; -+ *pos++ = 4; -+ *pos++ = 0; -+ *pos++ = bcn->dtim; -+ *pos++ = 0; -+ *pos++ = 0; -+ if (bcn->tail) { -+ memcpy(pos, bcn->tail, bcn->tail_len); -+ pos += bcn->tail_len; -+ } -+ if (bcn->ies) { -+ memcpy(pos, bcn->ies, bcn->ies_len); -+ } -+ -+ return buf; -+} -+ -+ -+static void rwnx_del_bcn(struct rwnx_bcn *bcn) -+{ -+ if (bcn->head) { -+ kfree(bcn->head); -+ bcn->head = NULL; -+ } -+ bcn->head_len = 0; -+ -+ if (bcn->tail) { -+ kfree(bcn->tail); -+ bcn->tail = NULL; -+ } -+ bcn->tail_len = 0; -+ -+ if (bcn->ies) { -+ kfree(bcn->ies); -+ bcn->ies = NULL; -+ } -+ bcn->ies_len = 0; -+ bcn->tim_len = 0; -+ bcn->dtim = 0; -+ bcn->len = 0; -+} -+ -+/** -+ * Link channel ctxt to a vif and thus increments count for this context. -+ */ -+void rwnx_chanctx_link(struct rwnx_vif *vif, u8 ch_idx, -+ struct cfg80211_chan_def *chandef) -+{ -+ struct rwnx_chanctx *ctxt; -+ -+ if (ch_idx >= NX_CHAN_CTXT_CNT) { -+ WARN(1, "Invalid channel ctxt id %d", ch_idx); -+ return; -+ } -+ -+ vif->ch_index = ch_idx; -+ ctxt = &vif->rwnx_hw->chanctx_table[ch_idx]; -+ ctxt->count++; -+ -+ // For now chandef is NULL for STATION interface -+ if (chandef) { -+ if (!ctxt->chan_def.chan) -+ ctxt->chan_def = *chandef; -+ else { -+ // TODO. check that chandef is the same as the one already -+ // set for this ctxt -+ } -+ } -+} -+ -+/** -+ * Unlink channel ctxt from a vif and thus decrements count for this context -+ */ -+void rwnx_chanctx_unlink(struct rwnx_vif *vif) -+{ -+ struct rwnx_chanctx *ctxt; -+ -+ if (vif->ch_index == RWNX_CH_NOT_SET) -+ return; -+ -+ ctxt = &vif->rwnx_hw->chanctx_table[vif->ch_index]; -+ -+ if (ctxt->count == 0) { -+ WARN(1, "Chan ctxt ref count is already 0"); -+ } else { -+ ctxt->count--; -+ } -+ -+ if (ctxt->count == 0) { -+ if (vif->ch_index == vif->rwnx_hw->cur_chanctx) { -+ /* If current chan ctxt is no longer linked to a vif -+ disable radar detection (no need to check if it was activated) */ -+ rwnx_radar_detection_enable(&vif->rwnx_hw->radar, -+ RWNX_RADAR_DETECT_DISABLE, -+ RWNX_RADAR_RIU); -+ } -+ /* set chan to null, so that if this ctxt is relinked to a vif that -+ don't have channel information, don't use wrong information */ -+ ctxt->chan_def.chan = NULL; -+ } -+ vif->ch_index = RWNX_CH_NOT_SET; -+} -+ -+int rwnx_chanctx_valid(struct rwnx_hw *rwnx_hw, u8 ch_idx) -+{ -+ if (ch_idx >= NX_CHAN_CTXT_CNT || -+ rwnx_hw->chanctx_table[ch_idx].chan_def.chan == NULL) { -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static void rwnx_del_csa(struct rwnx_vif *vif) -+{ -+ struct rwnx_csa *csa = vif->ap.csa; -+ -+ if (!csa) -+ return; -+ -+ rwnx_del_bcn(&csa->bcn); -+ kfree(csa); -+ vif->ap.csa = NULL; -+} -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+static void rwnx_csa_finish(struct work_struct *ws) -+{ -+ struct rwnx_csa *csa = container_of(ws, struct rwnx_csa, work); -+ struct rwnx_vif *vif = csa->vif; -+ struct rwnx_hw *rwnx_hw = vif->rwnx_hw; -+ int error = csa->status; -+ u8 *buf, *pos; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ buf = kmalloc(csa->bcn.len, GFP_KERNEL); -+ if (!buf) { -+ printk ("%s buf fail\n", __func__); -+ return; -+ } -+ pos = buf; -+ -+ memcpy(pos, csa->bcn.head, csa->bcn.head_len); -+ pos += csa->bcn.head_len; -+ *pos++ = WLAN_EID_TIM; -+ *pos++ = 4; -+ *pos++ = 0; -+ *pos++ = csa->bcn.dtim; -+ *pos++ = 0; -+ *pos++ = 0; -+ if (csa->bcn.tail) { -+ memcpy(pos, csa->bcn.tail, csa->bcn.tail_len); -+ pos += csa->bcn.tail_len; -+ } -+ if (csa->bcn.ies) { -+ memcpy(pos, csa->bcn.ies, csa->bcn.ies_len); -+ } -+ -+ if (!error) { -+ error = rwnx_send_bcn(rwnx_hw, buf, vif->vif_index, csa->bcn.len); -+ if (error) -+ return; -+ error = rwnx_send_bcn_change(rwnx_hw, vif->vif_index, 0, -+ csa->bcn.len, csa->bcn.head_len, -+ csa->bcn.tim_len, NULL); -+ } -+ -+ if (error) { -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) -+ cfg80211_stop_iface(rwnx_hw->wiphy, &vif->wdev, GFP_KERNEL); -+ #else -+ cfg80211_disconnected(vif->ndev, 0, NULL, 0, 0, GFP_KERNEL); -+ #endif -+ } else { -+ mutex_lock(&vif->wdev.mtx); -+ __acquire(&vif->wdev.mtx); -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_chanctx_unlink(vif); -+ rwnx_chanctx_link(vif, csa->ch_idx, &csa->chandef); -+ if (rwnx_hw->cur_chanctx == csa->ch_idx) { -+ rwnx_radar_detection_enable_on_cur_channel(rwnx_hw); -+ rwnx_txq_vif_start(vif, RWNX_TXQ_STOP_CHAN, rwnx_hw); -+ } else -+ rwnx_txq_vif_stop(vif, RWNX_TXQ_STOP_CHAN, rwnx_hw); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION3) -+ cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0, 0); -+#elif (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION) -+ cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0); -+#else -+ cfg80211_ch_switch_notify(vif->ndev, &csa->chandef); -+#endif -+ mutex_unlock(&vif->wdev.mtx); -+ __release(&vif->wdev.mtx); -+ } -+ rwnx_del_csa(vif); -+} -+#endif -+ -+/** -+ * rwnx_external_auth_enable - Enable external authentication on a vif -+ * -+ * @vif: VIF on which external authentication must be enabled -+ * -+ * External authentication requires to start TXQ for unknown STA in -+ * order to send auth frame pusehd by user space. -+ * Note: It is assumed that fw is on the correct channel. -+ */ -+void rwnx_external_auth_enable(struct rwnx_vif *vif) -+{ -+ vif->sta.external_auth = true; -+ rwnx_txq_unk_vif_init(vif); -+ rwnx_txq_start(rwnx_txq_vif_get(vif, NX_UNK_TXQ_TYPE), 0); -+} -+ -+/** -+ * rwnx_external_auth_disable - Disable external authentication on a vif -+ * -+ * @vif: VIF on which external authentication must be disabled -+ */ -+void rwnx_external_auth_disable(struct rwnx_vif *vif) -+{ -+ if (!vif->sta.external_auth) -+ return; -+ -+ vif->sta.external_auth = false; -+ rwnx_txq_unk_vif_deinit(vif); -+} -+ -+/** -+ * rwnx_update_mesh_power_mode - -+ * -+ * @vif: mesh VIF for which power mode is updated -+ * -+ * Does nothing if vif is not a mesh point interface. -+ * Since firmware doesn't support one power save mode per link select the -+ * most "active" power mode among all mesh links. -+ * Indeed as soon as we have to be active on one link we might as well be -+ * active on all links. -+ * -+ * If there is no link then the power mode for next peer is used; -+ */ -+void rwnx_update_mesh_power_mode(struct rwnx_vif *vif) -+{ -+ enum nl80211_mesh_power_mode mesh_pm; -+ struct rwnx_sta *sta; -+ struct mesh_config mesh_conf; -+ struct mesh_update_cfm cfm; -+ u32 mask; -+ -+ if (RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_MESH_POINT) -+ return; -+ -+ if (list_empty(&vif->ap.sta_list)) { -+ mesh_pm = vif->ap.next_mesh_pm; -+ } else { -+ mesh_pm = NL80211_MESH_POWER_DEEP_SLEEP; -+ list_for_each_entry(sta, &vif->ap.sta_list, list) { -+ if (sta->valid && (sta->mesh_pm < mesh_pm)) { -+ mesh_pm = sta->mesh_pm; -+ } -+ } -+ } -+ -+ if (mesh_pm == vif->ap.mesh_pm) -+ return; -+ -+ mask = BIT(NL80211_MESHCONF_POWER_MODE - 1); -+ mesh_conf.power_mode = mesh_pm; -+ if (rwnx_send_mesh_update_req(vif->rwnx_hw, vif, mask, &mesh_conf, &cfm) || -+ cfm.status) -+ return; -+ -+ vif->ap.mesh_pm = mesh_pm; -+} -+ -+#ifdef CONFIG_BR_SUPPORT -+void netdev_br_init(struct net_device *netdev) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(netdev); -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) -+ rcu_read_lock(); -+#endif -+ -+ /* if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) */ -+ { -+ /* struct net_bridge *br = netdev->br_port->br; */ /* ->dev->dev_addr; */ -+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) -+ if (netdev->br_port) -+ #else -+ if (rcu_dereference(rwnx_vif->ndev->rx_handler_data)) -+ #endif -+ { -+ struct net_device *br_netdev; -+ -+ br_netdev = dev_get_by_name(&init_net, CONFIG_BR_SUPPORT_BRNAME); -+ if (br_netdev) { -+ memcpy(rwnx_vif->br_mac, br_netdev->dev_addr, ETH_ALEN); -+ dev_put(br_netdev); -+ printk(FUNC_NDEV_FMT" bind bridge dev "NDEV_FMT"("MAC_FMT")\n" -+ , FUNC_NDEV_ARG(netdev), NDEV_ARG(br_netdev), MAC_ARG(br_netdev->dev_addr)); -+ } else { -+ printk(FUNC_NDEV_FMT" can't get bridge dev by name \"%s\"\n" -+ , FUNC_NDEV_ARG(netdev), CONFIG_BR_SUPPORT_BRNAME); -+ } -+ } -+ -+ rwnx_vif->ethBrExtInfo.addPPPoETag = 1; -+ } -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) -+ rcu_read_unlock(); -+#endif -+} -+#endif /* CONFIG_BR_SUPPORT */ -+ -+ -+/********************************************************************* -+ * netdev callbacks -+ ********************************************************************/ -+/** -+ * int (*ndo_open)(struct net_device *dev); -+ * This function is called when network device transistions to the up -+ * state. -+ * -+ * - Start FW if this is the first interface opened -+ * - Add interface at fw level -+ */ -+static int rwnx_open(struct net_device *dev) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; -+ struct mm_add_if_cfm add_if_cfm; -+ int error = 0; -+ u8 rwnx_rx_gain = 0x0E; -+ int err = 0; -+ int waiting_counter = 10; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ while(test_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags)){ -+ msleep(100); -+ AICWFDBG(LOGDEBUG, "%s waiting for rwnx_close \r\n", __func__); -+ waiting_counter--; -+ if(waiting_counter == 0){ -+ AICWFDBG(LOGERROR, "%s error waiting for close time out \r\n", __func__); -+ break; -+ } -+ } -+ -+#ifdef CONFIG_GPIO_WAKEUP -+//close lp mode -+// rwnx_send_me_set_lp_level(g_rwnx_plat->sdiodev->rwnx_hw, 0); -+#endif//CONFIG_GPIO_WAKEUP -+ -+ // Check if it is the first opened VIF -+ if (rwnx_hw->vif_started == 0) { -+ // Start the FW -+ error = rwnx_send_start(rwnx_hw); -+ if (error) -+ return error; -+ -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC || rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ error = rwnx_send_dbg_mem_mask_write_req(rwnx_hw, 0x4033b300, 0xFF, rwnx_rx_gain); -+ if(error){ -+ return error; -+ } -+ } -+ -+ #ifdef CONFIG_COEX -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801 || -+ ((rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC|| -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW || -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80) && testmode == 0)){ -+ if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) { -+ rwnx_send_coex_req(rwnx_hw, 0, 1); -+ } -+ } -+ #endif -+ -+ /* Device is now started */ -+ } -+ #ifdef CONFIG_COEX -+ else if ((RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_GO)) { -+ rwnx_send_coex_req(rwnx_hw, 1, 0); -+ } -+ #endif -+ -+ set_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags); -+ atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED); -+ AICWFDBG(LOGDEBUG, "%s rwnx_vif->drv_flags:%d\r\n", __func__, (int)rwnx_vif->drv_flags); -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_GO) { -+ if (!rwnx_hw->is_p2p_alive) { -+ if (rwnx_hw->p2p_dev_vif && !rwnx_hw->p2p_dev_vif->up) { -+ err = rwnx_send_add_if (rwnx_hw, rwnx_hw->p2p_dev_vif->wdev.address, -+ RWNX_VIF_TYPE(rwnx_hw->p2p_dev_vif), false, &add_if_cfm); -+ if (err) { -+ return -EIO; -+ } -+ -+ if (add_if_cfm.status != 0) { -+ return -EIO; -+ } -+ -+ /* Save the index retrieved from LMAC */ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_hw->p2p_dev_vif->vif_index = add_if_cfm.inst_nbr; -+ rwnx_hw->p2p_dev_vif->up = true; -+ rwnx_hw->vif_started++; -+ rwnx_hw->vif_table[add_if_cfm.inst_nbr] = rwnx_hw->p2p_dev_vif; -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ } -+ rwnx_hw->is_p2p_alive = 1; -+#ifndef CONFIG_USE_P2P0 -+ mod_timer(&rwnx_hw->p2p_alive_timer, jiffies + msecs_to_jiffies(1000)); -+ atomic_set(&rwnx_hw->p2p_alive_timer_count, 0); -+#endif -+ } -+ } -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP_VLAN) { -+ /* For AP_vlan use same fw and drv indexes. We ensure that this index -+ will not be used by fw for another vif by taking index >= NX_VIRT_DEV_MAX */ -+ add_if_cfm.inst_nbr = rwnx_vif->drv_vif_index; -+ netif_tx_stop_all_queues(dev); -+ -+ /* Save the index retrieved from LMAC */ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_vif->vif_index = add_if_cfm.inst_nbr; -+ rwnx_vif->up = true; -+ rwnx_hw->vif_started++; -+ rwnx_hw->vif_table[add_if_cfm.inst_nbr] = rwnx_vif; -+ AICWFDBG(LOGDEBUG, "%s ap create vif in rwnx_hw->vif_table[%d] \r\n", -+ __func__, rwnx_vif->vif_index); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ } else { -+ /* Forward the information to the LMAC, -+ * p2p value not used in FMAC configuration, iftype is sufficient */ -+ error = rwnx_send_add_if (rwnx_hw, rwnx_vif->wdev.address, RWNX_VIF_TYPE(rwnx_vif), false, &add_if_cfm); -+ if (error) { -+ printk("add if fail\n"); -+ return error; -+ } -+ -+ if (add_if_cfm.status != 0) { -+ RWNX_PRINT_CFM_ERR(add_if); -+ return -EIO; -+ } -+ -+ /* Save the index retrieved from LMAC */ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_vif->vif_index = add_if_cfm.inst_nbr; -+ rwnx_vif->up = true; -+ rwnx_hw->vif_started++; -+ rwnx_hw->vif_table[add_if_cfm.inst_nbr] = rwnx_vif; -+ AICWFDBG(LOGDEBUG, "%s sta create vif in rwnx_hw->vif_table[%d] \r\n", -+ __func__, rwnx_vif->vif_index); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ -+#ifdef CONFIG_USE_P2P0 -+ if(rwnx_vif->is_p2p_vif){ -+ rwnx_hw->p2p_dev_vif = rwnx_vif; -+ rwnx_hw->is_p2p_alive = 1; -+ } -+#endif -+ } -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_MONITOR) { -+ rwnx_hw->monitor_vif = rwnx_vif->vif_index; -+ if (rwnx_vif->ch_index != RWNX_CH_NOT_SET) { -+ //Configure the monitor channel -+ error = rwnx_send_config_monitor_req(rwnx_hw, &rwnx_hw->chanctx_table[rwnx_vif->ch_index].chan_def, NULL); -+ } -+ } -+ -+ #ifdef CONFIG_BR_SUPPORT -+ netdev_br_init(dev); -+ #endif /* CONFIG_BR_SUPPORT */ -+ -+ //netif_carrier_off(dev); -+ netif_start_queue(dev); -+ -+ return error; -+} -+ -+/** -+ * int (*ndo_stop)(struct net_device *dev); -+ * This function is called when network device transistions to the down -+ * state. -+ * -+ * - Remove interface at fw level -+ * - Reset FW if this is the last interface opened -+ */ -+static int rwnx_close(struct net_device *dev) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; -+ int ret; -+#if defined(AICWF_USB_SUPPORT) -+ struct aicwf_bus *bus_if = NULL; -+ struct aic_usb_dev *usbdev = NULL; -+ bus_if = dev_get_drvdata(rwnx_hw->dev); -+ usbdev = bus_if->bus_priv.usb; -+#elif defined(AICWF_SDIO_SUPPORT) -+ struct aicwf_bus *bus_if = NULL; -+ struct aic_sdio_dev *sdiodev = NULL; -+#else -+#endif -+ int waiting_counter = 20; -+ int test_counter = 0; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ test_counter = waiting_counter; -+ while(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING|| -+ atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING){ -+ AICWFDBG(LOGDEBUG, "%s wifi is connecting or disconnecting, waiting 200ms for state to stable\r\n", __func__); -+ msleep(200); -+ test_counter--; -+ if(test_counter == 0){ -+ AICWFDBG(LOGERROR, "%s connecting or disconnecting, not finish\r\n", __func__); -+ WARN_ON(1); -+ break; -+ } -+ } -+ -+#if defined(AICWF_USB_SUPPORT) || defined(AICWF_SDIO_SUPPORT) -+ if (scanning) { -+ scanning = false; -+ } -+#endif -+ -+ netdev_info(dev, "CLOSE"); -+ -+ rwnx_radar_cancel_cac(&rwnx_hw->radar); -+ -+ /* Abort scan request on the vif */ -+ if (rwnx_hw->scan_request && -+ rwnx_hw->scan_request->wdev == &rwnx_vif->wdev) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ cfg80211_scan_done(rwnx_hw->scan_request, &info); -+#else -+ cfg80211_scan_done(rwnx_hw->scan_request, true); -+#endif -+ rwnx_hw->scan_request = NULL; -+ -+ ret = rwnx_send_scanu_cancel_req(rwnx_hw, NULL); -+ mdelay(35);//make sure firmware take affect -+ if (ret) { -+ printk("scanu_cancel fail\n"); -+ return ret; -+ } -+ } -+ -+ if (rwnx_hw->roc_elem && (rwnx_hw->roc_elem->wdev == &rwnx_vif->wdev)) { -+ printk(KERN_CRIT "%s clear roc\n", __func__); -+ /* Initialize RoC element pointer to NULL, indicate that RoC can be started */ -+ kfree(rwnx_hw->roc_elem); -+ rwnx_hw->roc_elem = NULL; -+ } -+ -+ rwnx_vif->up = false; -+ AICWFDBG(LOGDEBUG, "%s rwnx_vif[%d] down \r\n", __func__, rwnx_vif->vif_index); -+ -+ if (netif_carrier_ok(dev)) { -+ if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || -+ RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) { -+ cfg80211_disconnected(dev, WLAN_REASON_DEAUTH_LEAVING, -+ NULL, 0, true, GFP_ATOMIC); -+ netif_tx_stop_all_queues(dev); -+ netif_carrier_off(dev); -+ udelay(1000); -+ } else if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP_VLAN) { -+ netif_carrier_off(dev); -+ } else { -+ netdev_warn(dev, "AP not stopped when disabling interface"); -+ } -+ -+ #ifdef CONFIG_BR_SUPPORT -+ /* if (OPMODE & (WIFI_STATION_STATE | WIFI_ADHOC_STATE)) */ -+ { -+ /* void nat25_db_cleanup(_adapter *priv); */ -+ nat25_db_cleanup(rwnx_vif); -+ } -+ #endif /* CONFIG_BR_SUPPORT */ -+ -+ } -+ -+#if defined(AICWF_USB_SUPPORT) -+ if (usbdev != NULL) { -+ if (usbdev->state != USB_DOWN_ST) -+ rwnx_send_remove_if (rwnx_hw, rwnx_vif->vif_index, false); -+ } -+#endif -+#if defined(AICWF_SDIO_SUPPORT) -+ bus_if = dev_get_drvdata(rwnx_hw->dev); -+ if (bus_if) { -+ sdiodev = bus_if->bus_priv.sdio; -+ } -+ if (sdiodev != NULL) { -+ if (sdiodev->bus_if->state != BUS_DOWN_ST){ -+ if(RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || -+ RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT){ -+ test_counter = waiting_counter; -+ if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED){ -+ atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); -+ rwnx_send_sm_disconnect_req(rwnx_hw, rwnx_vif, 3); -+ while (atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING) { -+ AICWFDBG(LOGDEBUG, "%s wifi is disconnecting, waiting 100ms for state to stable\r\n", __func__); -+ msleep(100); -+ test_counter--; -+ if (test_counter ==0) -+ break; -+ } -+ } -+ } -+#ifdef CONFIG_USE_P2P0 -+ if(!rwnx_vif->is_p2p_vif || ( rwnx_vif->is_p2p_vif && rwnx_hw->is_p2p_alive)){ -+ if (rwnx_vif->is_p2p_vif) -+ rwnx_hw->is_p2p_alive = 0; -+#endif -+ rwnx_send_remove_if (rwnx_hw, rwnx_vif->vif_index, false); -+#ifdef CONFIG_USE_P2P0 -+ } -+#endif -+ } -+ } -+#endif -+ /* Ensure that we won't process disconnect ind */ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ -+ rwnx_hw->vif_table[rwnx_vif->vif_index] = NULL; -+ -+ rwnx_chanctx_unlink(rwnx_vif); -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_MONITOR) -+ rwnx_hw->monitor_vif = RWNX_INVALID_VIF; -+ -+ rwnx_hw->vif_started--; -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ -+ if (rwnx_hw->vif_started == 0) { -+ /* This also lets both ipc sides remain in sync before resetting */ -+#if 0 -+ rwnx_ipc_tx_drain(rwnx_hw); -+#else -+#ifdef AICWF_USB_SUPPORT -+ if (usbdev->bus_if->state != BUS_DOWN_ST) { -+#else -+ if (sdiodev->bus_if->state != BUS_DOWN_ST) { -+#endif -+#ifdef CONFIG_COEX -+ if (testmode == 0) -+ rwnx_send_coex_req(rwnx_hw, 1, 0); -+#endif -+ rwnx_send_reset(rwnx_hw); -+ // Set parameters to firmware -+ if (testmode == 0) { -+ rwnx_send_me_config_req(rwnx_hw); -+ // Set channel parameters to firmware -+ rwnx_send_me_chan_config_req(rwnx_hw); -+ } -+ } -+#endif -+ } -+#ifdef CONFIG_COEX -+ else { -+ if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_GO) -+ rwnx_send_coex_req(rwnx_hw, 0, 1); -+ } -+#endif -+ clear_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags); -+ AICWFDBG(LOGDEBUG, "%s rwnx_vif->drv_flags:%d\r\n", __func__, (int)rwnx_vif->drv_flags); -+ -+#ifdef CONFIG_GPIO_WAKEUP -+ //open lp mode -+ //rwnx_send_me_set_lp_level(g_rwnx_plat->sdiodev->rwnx_hw, 1); -+#if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwr_stctl(g_rwnx_plat->sdiodev, SDIO_SLEEP_ST); -+#endif -+ ret = aicwf_sdio_writeb(g_rwnx_plat->sdiodev, g_rwnx_plat->sdiodev->sdio_reg.wakeup_reg, 2); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!\n", g_rwnx_plat->sdiodev->sdio_reg.wakeup_reg); -+ } -+#endif//CONFIG_GPIO_WAKEUP -+ -+ return 0; -+} -+ -+#ifdef CONFIG_RFTEST -+enum { -+ SET_TX, -+ SET_TXSTOP, -+ SET_TXTONE, -+ SET_RX, -+ GET_RX_RESULT, -+ SET_RXSTOP, -+ SET_RXMETER, -+ SET_POWER, -+ SET_XTAL_CAP, -+ SET_XTAL_CAP_FINE, -+ GET_EFUSE, -+ SET_FREQ_CAL, -+ SET_FREQ_CAL_FINE, -+ GET_FREQ_CAL, -+ SET_MAC_ADDR, -+ GET_MAC_ADDR, -+ SET_BT_MAC_ADDR, -+ GET_BT_MAC_ADDR, -+ SET_VENDOR_INFO, -+ GET_VENDOR_INFO, -+ RDWR_PWRMM, -+ RDWR_PWRIDX, -+ RDWR_PWRLVL = RDWR_PWRIDX, -+ RDWR_PWROFST, -+ RDWR_DRVIBIT, -+ RDWR_EFUSE_PWROFST, -+ RDWR_EFUSE_DRVIBIT, -+ SET_PAPR, -+ SET_CAL_XTAL, -+ GET_CAL_XTAL_RES, -+ SET_COB_CAL, -+ GET_COB_CAL_RES, -+ RDWR_EFUSE_USRDATA, -+ SET_NOTCH, -+ RDWR_PWROFSTFINE, -+ RDWR_EFUSE_PWROFSTFINE, -+ RDWR_EFUSE_SDIOCFG, -+ RDWR_EFUSE_USBVIDPID, -+ SET_SRRC, -+ SET_FSS, -+ RDWR_EFUSE_HE_OFF, -+}; -+ -+typedef struct { -+ u8_l chan; -+ u8_l bw; -+ u8_l mode; -+ u8_l rate; -+ u16_l length; -+ u16_l tx_intv_us; -+} cmd_rf_settx_t; -+ -+typedef struct { -+ u8_l val; -+} cmd_rf_setfreq_t; -+ -+typedef struct { -+ u8_l chan; -+ u8_l bw; -+} cmd_rf_rx_t; -+ -+typedef struct { -+ u8_l block; -+} cmd_rf_getefuse_t; -+typedef struct -+{ -+ u8_l dutid; -+ u8_l chip_num; -+ u8_l dis_xtal; -+}cmd_rf_setcobcal_t; -+typedef struct -+ { -+ u16_l dut_rcv_golden_num; -+ u8_l golden_rcv_dut_num; -+ s8_l rssi_static; -+ s8_l snr_static; -+ s8_l dut_rssi_static; -+ u16_l reserved; -+ }cob_result_ptr_t; -+#endif -+ -+#define CMD_MAXARGS 10 -+ -+#if 0 -+#define isblank(c) ((c) == ' ' || (c) == '\t') -+#define isascii(c) (((unsigned char)(c)) <= 0x7F) -+ -+static int isdigit(unsigned char c) -+{ -+ return ((c >= '0') && (c <= '9')); -+} -+ -+static int isxdigit(unsigned char c) -+{ -+ if ((c >= '0') && (c <= '9')) -+ return 1; -+ if ((c >= 'a') && (c <= 'f')) -+ return 1; -+ if ((c >= 'A') && (c <= 'F')) -+ return 1; -+ return 0; -+} -+ -+static int islower(unsigned char c) -+{ -+ return ((c >= 'a') && (c <= 'z')); -+} -+ -+static unsigned char toupper(unsigned char c) -+{ -+ if (islower(c)) -+ c -= 'a' - 'A'; -+ return c; -+} -+#endif -+ -+ -+static int parse_line (char *line, char *argv[]) -+{ -+ int nargs = 0; -+ -+ while (nargs < CMD_MAXARGS) { -+ /* skip any white space */ -+ while ((*line == ' ') || (*line == '\t')) { -+ ++line; -+ } -+ -+ if (*line == '\0') { /* end of line, no more args */ -+ argv[nargs] = 0; -+ return nargs; -+ } -+ -+ /* Argument include space should be bracketed by quotation mark */ -+ if (*line == '\"') { -+ /* Skip quotation mark */ -+ line++; -+ -+ /* Begin of argument string */ -+ argv[nargs++] = line; -+ -+ /* Until end of argument */ -+ while (*line && (*line != '\"')) { -+ ++line; -+ } -+ } else { -+ argv[nargs++] = line; /* begin of argument string */ -+ -+ /* find end of string */ -+ while (*line && (*line != ' ') && (*line != '\t')) { -+ ++line; -+ } -+ } -+ -+ if (*line == '\0') { /* end of line, no more args */ -+ argv[nargs] = 0; -+ return nargs; -+ } -+ -+ *line++ = '\0'; /* terminate current arg */ -+ } -+ -+ printk("** Too many args (max. %d) **\n", CMD_MAXARGS); -+ -+ return nargs; -+} -+ -+unsigned int command_strtoul(const char *cp, char **endp, unsigned int base) -+{ -+ unsigned int result = 0, value, is_neg = 0; -+ -+ if (*cp == '0') { -+ cp++; -+ if ((*cp == 'x') && isxdigit(cp[1])) { -+ base = 16; -+ cp++; -+ } -+ if (!base) { -+ base = 8; -+ } -+ } -+ if (!base) { -+ base = 10; -+ } -+ if (*cp == '-') { -+ is_neg = 1; -+ cp++; -+ } -+ while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp - '0' : (islower(*cp) ? toupper(*cp) : *cp) - 'A' + 10) < base) { -+ result = result * base + value; -+ cp++; -+ } -+ if (is_neg) -+ result = (unsigned int)((int)result * (-1)); -+ -+ if (endp) -+ *endp = (char *)cp; -+ return result; -+} -+ -+ -+int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len) -+{ -+ int bytes_written = 0; -+ char *para = NULL; -+ char *cmd = NULL; -+ char *argv[CMD_MAXARGS + 1]; -+ int argc; -+#ifdef CONFIG_RFTEST -+ struct dbg_rftest_cmd_cfm cfm; -+ u8_l mac_addr[6]; -+ cmd_rf_settx_t settx_param; -+ cmd_rf_rx_t setrx_param; -+ int freq; -+ cmd_rf_getefuse_t getefuse_param; -+ cmd_rf_setfreq_t cmd_setfreq; -+ cmd_rf_setcobcal_t setcob_cal; -+ u8_l ana_pwr; -+ u8_l dig_pwr; -+ u8_l pwr; -+ u8_l xtal_cap; -+ u8_l xtal_cap_fine; -+ u8_l vendor_info; -+ cob_result_ptr_t *cob_result_ptr; -+ -+#endif -+ -+ u8_l state; -+ -+#ifdef CONFIG_GPIO_WAKEUP -+ u8_l setsusp_mode; -+ int ret = 0; -+#endif -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ argc = parse_line(command, argv); -+ if (argc == 0) { -+ return -1; -+ } -+ -+ do { -+#ifdef CONFIG_RFTEST -+ if (strcasecmp(argv[0], "GET_RX_RESULT") == 0) { -+ AICWFDBG(LOGINFO, "get_rx_result\n"); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, GET_RX_RESULT, 0, NULL, &cfm); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, GET_RX_RESULT, 0, NULL, &cfm); -+ #endif -+ memcpy(command, &cfm.rftest_result[0], 8); -+ bytes_written = 8; -+ } else if (strcasecmp(argv[0], "SET_TX") == 0) { -+ AICWFDBG(LOGINFO, "set_tx\n"); -+ if (argc < 6) { -+ AICWFDBG(LOGERROR, "wrong param\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ settx_param.chan = command_strtoul(argv[1], NULL, 10); -+ settx_param.bw = command_strtoul(argv[2], NULL, 10); -+ settx_param.mode = command_strtoul(argv[3], NULL, 10); -+ settx_param.rate = command_strtoul(argv[4], NULL, 10); -+ settx_param.length = command_strtoul(argv[5], NULL, 10); -+ if (argc > 6) { -+ settx_param.tx_intv_us = command_strtoul(argv[6], NULL, 10); -+ } else { -+ settx_param.tx_intv_us = 10000; // set default val 10ms -+ } -+ AICWFDBG(LOGINFO, "txparam:%d,%d,%d,%d,%d,%d\n", settx_param.chan, settx_param.bw, -+ settx_param.mode, settx_param.rate, settx_param.length, settx_param.tx_intv_us); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_TX, sizeof(cmd_rf_settx_t), (u8_l *)&settx_param, NULL); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_TX, sizeof(cmd_rf_settx_t), (u8_l *)&settx_param, NULL); -+ #endif -+ } else if (strcasecmp(argv[0], "SET_TXSTOP") == 0) { -+ AICWFDBG(LOGINFO, "settx_stop\n"); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_TXSTOP, 0, NULL, NULL); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_TXSTOP, 0, NULL, NULL); -+ #endif -+ } else if (strcasecmp(argv[0], "SET_TXTONE") == 0) { -+ AICWFDBG(LOGINFO, "set_tx_tone,argc:%d\n", argc); -+ if ((argc == 2) || (argc == 3)) { -+ u8_l func, buf[2]; -+ s8_l freq; -+ AICWFDBG(LOGINFO, "argv 1:%s\n", argv[1]); -+ func = (u8_l)command_strtoul(argv[1], NULL, 16); -+ if (argc == 3) { -+ AICWFDBG(LOGINFO, "argv 2:%s\n", argv[2]); -+ freq = (u8_l)command_strtoul(argv[2], NULL, 10); -+ } else { -+ freq = 0; -+ } -+ buf[0] = func; -+ buf[1] = (u8_l)freq; -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_TXTONE, argc - 1, buf, NULL); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_TXTONE, argc - 1, buf, NULL); -+ #endif -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ } -+ } else if (strcasecmp(argv[0], "SET_RX") == 0) { -+ AICWFDBG(LOGINFO, "set_rx\n"); -+ if (argc < 3) { -+ AICWFDBG(LOGERROR, "wrong param\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ setrx_param.chan = command_strtoul(argv[1], NULL, 10); -+ setrx_param.bw = command_strtoul(argv[2], NULL, 10); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_RX, sizeof(cmd_rf_rx_t), (u8_l *)&setrx_param, NULL); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_RX, sizeof(cmd_rf_rx_t), (u8_l *)&setrx_param, NULL); -+ #endif -+ } else if (strcasecmp(argv[0], "SET_RXSTOP") == 0) { -+ AICWFDBG(LOGINFO, "set_rxstop\n"); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_RXSTOP, 0, NULL, NULL); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_RXSTOP, 0, NULL, NULL); -+ #endif -+ } else if (strcasecmp(argv[0], "SET_RX_METER") == 0) { -+ AICWFDBG(LOGINFO, "set_rx_meter\n"); -+ freq = (int)command_strtoul(argv[1], NULL, 10); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_RXMETER, sizeof(freq), (u8_l *)&freq, NULL); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_RXMETER, sizeof(freq), (u8_l *)&freq, NULL); -+ #endif -+ } else if (strcasecmp(argv[0], "SET_FREQ_CAL") == 0) { -+ AICWFDBG(LOGINFO, "set_freq_cal\n"); -+ if (argc < 2) { -+ AICWFDBG(LOGERROR, "wrong param\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ cmd_setfreq.val = command_strtoul(argv[1], NULL, 16); -+ AICWFDBG(LOGINFO, "param:%x\r\n", cmd_setfreq.val); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_FREQ_CAL, sizeof(cmd_rf_setfreq_t), (u8_l *)&cmd_setfreq, &cfm); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_FREQ_CAL, sizeof(cmd_rf_setfreq_t), (u8_l *)&cmd_setfreq, &cfm); -+ #endif -+ memcpy(command, &cfm.rftest_result[0], 4); -+ bytes_written = 4; -+ } else if (strcasecmp(argv[0], "SET_FREQ_CAL_FINE") == 0) { -+ AICWFDBG(LOGINFO, "set_freq_cal_fine\n"); -+ if (argc < 2) { -+ AICWFDBG(LOGERROR, "wrong param\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ cmd_setfreq.val = command_strtoul(argv[1], NULL, 16); -+ AICWFDBG(LOGINFO, "param:%x\r\n", cmd_setfreq.val); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_FREQ_CAL_FINE, sizeof(cmd_rf_setfreq_t), (u8_l *)&cmd_setfreq, &cfm); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_FREQ_CAL_FINE, sizeof(cmd_rf_setfreq_t), (u8_l *)&cmd_setfreq, &cfm); -+ #endif -+ memcpy(command, &cfm.rftest_result[0], 4); -+ bytes_written = 4; -+ } else if (strcasecmp(argv[0], "GET_EFUSE") == 0) { -+ AICWFDBG(LOGINFO, "get_efuse\n"); -+ if (argc < 2) { -+ AICWFDBG(LOGERROR, "wrong param\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ getefuse_param.block = command_strtoul(argv[1], NULL, 10); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, GET_EFUSE, sizeof(cmd_rf_getefuse_t), (u8_l *)&getefuse_param, &cfm); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, GET_EFUSE, sizeof(cmd_rf_getefuse_t), (u8_l *)&getefuse_param, &cfm); -+ #endif -+ AICWFDBG(LOGINFO, "get val=%x\r\n", cfm.rftest_result[0]); -+ memcpy(command, &cfm.rftest_result[0], 4); -+ bytes_written = 4; -+ } else if (strcasecmp(argv[0], "SET_POWER") == 0) { -+ AICWFDBG(LOGINFO, "set_power\n"); -+ if(g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) { -+ ana_pwr = command_strtoul(argv[1], NULL, 16); -+ dig_pwr = command_strtoul(argv[2], NULL, 16); -+ pwr = (ana_pwr << 4 | dig_pwr); -+ if (ana_pwr > 0xf || dig_pwr > 0xf) { -+ AICWFDBG(LOGERROR, "invalid param\r\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else { -+ ana_pwr = command_strtoul(argv[1], NULL, 10); -+ pwr = ana_pwr; -+ if (ana_pwr > 0x1e) { -+ AICWFDBG(LOGERROR, "invalid param\r\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } -+ AICWFDBG(LOGINFO, "pwr =%x\r\n", pwr); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_POWER, sizeof(pwr), (u8_l *)&pwr, NULL); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_POWER, sizeof(pwr), (u8_l *)&pwr, NULL); -+ #endif -+ } else if (strcasecmp(argv[0], "SET_XTAL_CAP") == 0) { -+ AICWFDBG(LOGINFO, "set_xtal_cap\n"); -+ if (argc < 2) { -+ AICWFDBG(LOGERROR, "wrong param\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ xtal_cap = command_strtoul(argv[1], NULL, 10); -+ AICWFDBG(LOGINFO, "xtal_cap =%x\r\n", xtal_cap); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_XTAL_CAP, sizeof(xtal_cap), (u8_l *)&xtal_cap, &cfm); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_XTAL_CAP, sizeof(xtal_cap), (u8_l *)&xtal_cap, &cfm); -+ #endif -+ memcpy(command, &cfm.rftest_result[0], 4); -+ bytes_written = 4; -+ } else if (strcasecmp(argv[0], "SET_XTAL_CAP_FINE") == 0) { -+ AICWFDBG(LOGINFO, "set_xtal_cap_fine\n"); -+ if (argc < 2) { -+ AICWFDBG(LOGERROR, "wrong param\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ xtal_cap_fine = command_strtoul(argv[1], NULL, 10); -+ AICWFDBG(LOGINFO, "xtal_cap_fine =%x\r\n", xtal_cap_fine); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_XTAL_CAP_FINE, sizeof(xtal_cap_fine), (u8_l *)&xtal_cap_fine, &cfm); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_XTAL_CAP_FINE, sizeof(xtal_cap_fine), (u8_l *)&xtal_cap_fine, &cfm); -+ #endif -+ memcpy(command, &cfm.rftest_result[0], 4); -+ bytes_written = 4; -+ } else if (strcasecmp(argv[0], "SET_MAC_ADDR") == 0) { -+ printk("set_mac_addr\n"); -+ if (argc < 7) { -+ AICWFDBG(LOGERROR, "wrong param\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ mac_addr[5] = command_strtoul(argv[1], NULL, 16); -+ mac_addr[4] = command_strtoul(argv[2], NULL, 16); -+ mac_addr[3] = command_strtoul(argv[3], NULL, 16); -+ mac_addr[2] = command_strtoul(argv[4], NULL, 16); -+ mac_addr[1] = command_strtoul(argv[5], NULL, 16); -+ mac_addr[0] = command_strtoul(argv[6], NULL, 16); -+ AICWFDBG(LOGINFO, "set macaddr:%x,%x,%x,%x,%x,%x\n", mac_addr[5], mac_addr[4], mac_addr[3], mac_addr[2], mac_addr[1], mac_addr[0]); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_MAC_ADDR, sizeof(mac_addr), (u8_l *)&mac_addr, NULL); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_MAC_ADDR, sizeof(mac_addr), (u8_l *)&mac_addr, NULL); -+ #endif -+ } else if (strcasecmp(argv[0], "GET_MAC_ADDR") == 0) { -+ u32_l addr0, addr1; -+ AICWFDBG(LOGINFO, "get mac addr\n"); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, GET_MAC_ADDR, 0, NULL, &cfm); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, GET_MAC_ADDR, 0, NULL, &cfm); -+ #endif -+ memcpy(command, &cfm.rftest_result[0], 8); -+ bytes_written = 8; -+ addr0 = cfm.rftest_result[0]; -+ if ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC) || -+ (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW)) { -+ int rem_cnt = (cfm.rftest_result[1] >> 16) & 0x00FF; -+ addr1 = cfm.rftest_result[1] & 0x0000FFFF; -+ AICWFDBG(LOGINFO, "0x%x,0x%x (remain:%x)\n", addr0, addr1, rem_cnt); -+ } else { -+ addr1 = cfm.rftest_result[1]; -+ AICWFDBG(LOGINFO, "0x%x,0x%x\n", addr0, addr1); -+ } -+ } else if (strcasecmp(argv[0], "SET_BT_MAC_ADDR") == 0) { -+ AICWFDBG(LOGINFO, "set_bt_mac_addr\n"); -+ if (argc < 7) { -+ AICWFDBG(LOGERROR, "wrong param\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ mac_addr[5] = command_strtoul(argv[1], NULL, 16); -+ mac_addr[4] = command_strtoul(argv[2], NULL, 16); -+ mac_addr[3] = command_strtoul(argv[3], NULL, 16); -+ mac_addr[2] = command_strtoul(argv[4], NULL, 16); -+ mac_addr[1] = command_strtoul(argv[5], NULL, 16); -+ mac_addr[0] = command_strtoul(argv[6], NULL, 16); -+ AICWFDBG(LOGINFO, "set bt macaddr:%x,%x,%x,%x,%x,%x\n", mac_addr[5], mac_addr[4], mac_addr[3], mac_addr[2], mac_addr[1], mac_addr[0]); -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_BT_MAC_ADDR, sizeof(mac_addr), (u8_l *)&mac_addr, NULL); -+ } else if (strcasecmp(argv[0], "GET_BT_MAC_ADDR")==0) { -+ u32_l addr0, addr1; -+ AICWFDBG(LOGINFO, "get bt mac addr\n"); -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, GET_BT_MAC_ADDR, 0, NULL, &cfm); -+ memcpy(command, &cfm.rftest_result[0], 8); -+ bytes_written = 8; -+ addr0 = cfm.rftest_result[0]; -+ if ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC) || -+ (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW)) { -+ int rem_cnt = (cfm.rftest_result[1] >> 16) & 0x00FF; -+ addr1 = cfm.rftest_result[1] & 0x0000FFFF; -+ AICWFDBG(LOGINFO, "0x%x,0x%x (remain:%x)\n", addr0, addr1, rem_cnt); -+ } else { -+ addr1 = cfm.rftest_result[1]; -+ AICWFDBG(LOGINFO, "0x%x,0x%x\n", addr0, addr1); -+ } -+ } else if (strcasecmp(argv[0], "SET_VENDOR_INFO") == 0) { -+ vendor_info = command_strtoul(argv[1], NULL, 16); -+ AICWFDBG(LOGINFO, "set vendor info:%x\n", vendor_info); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_VENDOR_INFO, 1, &vendor_info, &cfm); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, SET_VENDOR_INFO, 1, &vendor_info, &cfm); -+ #endif -+ if ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC) || -+ (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW)) { -+ memcpy(command, &cfm.rftest_result[0], 2); -+ bytes_written = 2; -+ } else { -+ memcpy(command, &cfm.rftest_result[0], 1); -+ bytes_written = 1; -+ } -+ AICWFDBG(LOGINFO, "0x%x\n", cfm.rftest_result[0]); -+ } else if (strcasecmp(argv[0], "GET_VENDOR_INFO") == 0) { -+ AICWFDBG(LOGINFO, "get vendor info\n"); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, GET_VENDOR_INFO, 0, NULL, &cfm); -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->usbdev->rwnx_hw, GET_VENDOR_INFO, 0, NULL, &cfm); -+ #endif -+ if ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC) || -+ (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW)) { -+ memcpy(command, &cfm.rftest_result[0], 2); -+ bytes_written = 2; -+ } else { -+ memcpy(command, &cfm.rftest_result[0], 1); -+ bytes_written = 1; -+ } -+ AICWFDBG(LOGINFO, "0x%x\n", cfm.rftest_result[0]); -+ } else if (strcasecmp(argv[0], "GET_FREQ_CAL") == 0) { -+ unsigned int val; -+ AICWFDBG(LOGINFO, "get freq cal\n"); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, GET_FREQ_CAL, 0, NULL, &cfm); -+ #endif -+ memcpy(command, &cfm.rftest_result[0], 4); -+ bytes_written = 4; -+ val = cfm.rftest_result[0]; -+ if ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC) || -+ (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW)) { -+ AICWFDBG(LOGINFO, "cap=0x%x (remain:%x), cap_fine=%x (remain:%x)\n", -+ val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff, (val >> 24) & 0xff); -+ } else { -+ AICWFDBG(LOGINFO, "cap=0x%x, cap_fine=0x%x\n", val & 0xff, (val >> 8) & 0xff); -+ } -+ } else if (strcasecmp(argv[0], "RDWR_PWRMM") == 0) { -+ AICWFDBG(LOGINFO, "read/write txpwr manul mode\n"); -+ if (argc <= 1) { // read cur -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_PWRMM, 0, NULL, &cfm); -+ #endif -+ } else { // write -+ u8_l pwrmm = (u8_l)command_strtoul(argv[1], NULL, 16); -+ pwrmm = (pwrmm) ? 1 : 0; -+ AICWFDBG(LOGINFO, "set pwrmm = %x\r\n", pwrmm); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_PWRMM, sizeof(pwrmm), (u8_l *)&pwrmm, &cfm); -+ #endif -+ } -+ memcpy(command, &cfm.rftest_result[0], 4); -+ bytes_written = 4; -+ } else if (strcasecmp(argv[0], "RDWR_PWRIDX") == 0) { -+ u8_l func = 0; -+ #ifdef AICWF_SDIO_SUPPORT -+ if (g_rwnx_plat->sdiodev->chipid != PRODUCT_ID_AIC8801) { -+ AICWFDBG(LOGERROR, "unsupported cmd\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ #endif -+ AICWFDBG(LOGINFO, "read/write txpwr index\n"); -+ if (argc > 1) { -+ func = (u8_l)command_strtoul(argv[1], NULL, 16); -+ } -+ if (func == 0) { // read cur -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_PWRIDX, 0, NULL, &cfm); -+ #endif -+ } else if (func <= 2) { // write 2.4g/5g pwr idx -+ if (argc > 3) { -+ u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16); -+ u8_l pwridx = (u8_l)command_strtoul(argv[3], NULL, 10); -+ u8_l buf[3] = {func, type, pwridx}; -+ AICWFDBG(LOGINFO, "set pwridx:[%x][%x]=%x\r\n", func, type, pwridx); -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_PWRIDX, sizeof(buf), buf, &cfm); -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else { -+ AICWFDBG(LOGERROR, "wrong func: %x\n", func); -+ bytes_written = -EINVAL; -+ break; -+ } -+ memcpy(command, &cfm.rftest_result[0], 9); -+ bytes_written = 9; -+ } else if (strcasecmp(argv[0], "RDWR_PWRLVL") == 0) { -+ u8_l func = 0; -+ #ifdef AICWF_SDIO_SUPPORT -+ if ((g_rwnx_plat->sdiodev->chipid != PRODUCT_ID_AIC8800DC) -+ && (g_rwnx_plat->sdiodev->chipid != PRODUCT_ID_AIC8800DW) -+ && (g_rwnx_plat->sdiodev->chipid != PRODUCT_ID_AIC8800D80)) { -+ AICWFDBG(LOGINFO, "unsupported cmd\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ #endif -+ AICWFDBG(LOGINFO, "read/write txpwr level\n"); -+ if (argc > 1) { -+ func = (u8_l)command_strtoul(argv[1], NULL, 16); -+ } -+ if (func == 0) { // read cur -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_PWRLVL, 0, NULL, &cfm); -+ } else if (func <= 2) { // write 2.4g/5g pwr lvl -+ if (argc > 4) { -+ u8_l grp = (u8_l)command_strtoul(argv[2], NULL, 16); -+ u8_l idx, size; -+ u8_l buf[14] = {func, grp,}; -+ if (argc > 12) { // set all grp -+ AICWFDBG(LOGINFO, "set pwrlvl %s:\n" -+ " [%x] =", (func == 1) ? "2.4g" : "5g", grp); -+ if (grp == 1) { // TXPWR_LVL_GRP_11N_11AC -+ size = 10; -+ } else { -+ size = 12; -+ } -+ for (idx = 0; idx < size; idx++) { -+ s8_l pwrlvl = (s8_l)command_strtoul(argv[3 + idx], NULL, 10); -+ buf[2 + idx] = (u8_l)pwrlvl; -+ if (idx && !(idx & 0x3)) { -+ AICWFDBG(LOGINFO, " "); -+ } -+ AICWFDBG(LOGINFO, " %2d", pwrlvl); -+ } -+ AICWFDBG(LOGINFO, "\n"); -+ size += 2; -+ } else { // set grp[idx] -+ u8_l idx = (u8_l)command_strtoul(argv[3], NULL, 10); -+ s8_l pwrlvl = (s8_l)command_strtoul(argv[4], NULL, 10); -+ buf[2] = idx; -+ buf[3] = (u8_l)pwrlvl; -+ size = 4; -+ AICWFDBG(LOGINFO, "set pwrlvl %s:\n" -+ " [%x][%d] = %d\n", (func == 1) ? "2.4g" : "5g", grp, idx, pwrlvl); -+ } -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_PWRLVL, size, buf, &cfm); -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else { -+ AICWFDBG(LOGERROR, "wrong func: %x\n", func); -+ bytes_written = -EINVAL; -+ break; -+ } -+ if(g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ memcpy(command, &cfm.rftest_result[0], 6 * 12); -+ bytes_written = 6 * 12; -+ } else { -+ memcpy(command, &cfm.rftest_result[0], 3 * 12); -+ bytes_written = 3 * 12; -+ } -+ } else if (strcasecmp(argv[0], "RDWR_PWROFST") == 0) { -+ u8_l func = 0; -+ int res_len = 0; -+ AICWFDBG(LOGINFO, "read/write txpwr offset\n"); -+ if (argc > 1) { -+ func = (u8_l)command_strtoul(argv[1], NULL, 16); -+ } -+ if (func == 0) { // read cur -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_PWROFST, 0, NULL, &cfm); -+ #endif -+ } else if (func <= 2) { // write 2.4g/5g pwr ofst -+ if ((argc > 4) && (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800D80)) { -+ u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16); -+ u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16); -+ s8_l pwrofst = (u8_l)command_strtoul(argv[4], NULL, 10); -+ u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst}; -+ printk("set pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm); -+ #endif -+ } else if ((argc > 3) && (g_rwnx_plat->sdiodev->chipid != PRODUCT_ID_AIC8800D80)) { -+ u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); -+ s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); -+ u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; -+ printk("set pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm); -+ #endif -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else { -+ AICWFDBG(LOGERROR, "wrong func: %x\n", func); -+ bytes_written = -EINVAL; -+ break; -+ } -+ if ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC) || -+ (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW)) { // 3 = 3 (2.4g) -+ res_len = 3; -+ } else if (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800D80) { // 3 * 2 (2.4g) + 3 * 6 (5g) -+ res_len = 3 * 3 + 3 * 6; -+ } else { -+ res_len = 3 + 4; -+ } -+ memcpy(command, &cfm.rftest_result[0], res_len); -+ bytes_written = res_len; -+ } else if (strcasecmp(argv[0], "RDWR_PWROFSTFINE") == 0) { -+ u8_l func = 0; -+ AICWFDBG(LOGINFO, "read/write txpwr offset fine\n"); -+ if (argc > 1) { -+ func = (u8_l)command_strtoul(argv[1], NULL, 16); -+ } -+ if (func == 0) { // read cur -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_PWROFSTFINE, 0, NULL, &cfm); -+ } else if (func <= 2) { // write 2.4g/5g pwr ofst -+ if (argc > 3) { -+ u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); -+ s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); -+ u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; -+ AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst); -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_PWROFSTFINE, sizeof(buf), buf, &cfm); -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else { -+ AICWFDBG(LOGERROR, "wrong func: %x\n", func); -+ bytes_written = -EINVAL; -+ break; -+ } -+ memcpy(command, &cfm.rftest_result[0], 7); -+ bytes_written = 7; -+ } else if (strcasecmp(argv[0], "RDWR_DRVIBIT") == 0) { -+ u8_l func = 0; -+ AICWFDBG(LOGINFO, "read/write pa drv_ibit\n"); -+ if (argc > 1) { -+ func = (u8_l)command_strtoul(argv[1], NULL, 16); -+ } -+ if (func == 0) { // read cur -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_DRVIBIT, 0, NULL, &cfm); -+ #endif -+ } else if (func == 1) { // write 2.4g pa drv_ibit -+ if (argc > 2) { -+ u8_l ibit = (u8_l)command_strtoul(argv[2], NULL, 16); -+ u8_l buf[2] = {func, ibit}; -+ printk("set drvibit:[%x]=%x\r\n", func, ibit); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_DRVIBIT, sizeof(buf), buf, &cfm); -+ #endif -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else { -+ AICWFDBG(LOGERROR, "wrong func: %x\n", func); -+ bytes_written = -EINVAL; -+ break; -+ } -+ memcpy(command, &cfm.rftest_result[0], 16); -+ bytes_written = 16; -+ } else if (strcasecmp(argv[0], "RDWR_EFUSE_PWROFST") == 0) { -+ u8_l func = 0; -+ int res_len = 0; -+ AICWFDBG(LOGINFO, "read/write txpwr offset into efuse\n"); -+ if (argc > 1) { -+ func = (u8_l)command_strtoul(argv[1], NULL, 16); -+ } -+ if (func == 0) { // read cur -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_EFUSE_PWROFST, 0, NULL, &cfm); -+ #endif -+ } else if (func <= 2) { // write 2.4g/5g pwr ofst -+ if ((argc > 4) && (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800D80)) { -+ u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16); -+ u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16); -+ s8_l pwrofst = (u8_l)command_strtoul(argv[4], NULL, 10); -+ u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst}; -+ printk("set efuse pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm); -+ #endif -+ } else if ((argc > 3) && (g_rwnx_plat->sdiodev->chipid != PRODUCT_ID_AIC8800D80)) { -+ u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); -+ s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); -+ u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; -+ printk("set efuse pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm); -+ #endif -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else { -+ AICWFDBG(LOGERROR, "wrong func: %x\n", func); -+ bytes_written = -EINVAL; -+ break; -+ } -+ if ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC) || -+ (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW)) { // 6 = 3 (2.4g) * 2 -+ res_len = 3 * 2; -+ } else if (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800D80) { // 3 * 2 (2.4g) + 3 * 6 (5g) -+ res_len = 3 * 3 + 3 * 6; -+ } else { // 7 = 3(2.4g) + 4(5g) -+ res_len = 3 + 4; -+ } -+ memcpy(command, &cfm.rftest_result[0], res_len); -+ bytes_written = res_len; -+ } else if (strcasecmp(argv[0], "RDWR_EFUSE_DRVIBIT") == 0) { -+ u8_l func = 0; -+ AICWFDBG(LOGINFO, "read/write pa drv_ibit into efuse\n"); -+ if (argc > 1) { -+ func = (u8_l)command_strtoul(argv[1], NULL, 16); -+ } -+ if (func == 0) { // read cur -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_EFUSE_DRVIBIT, 0, NULL, &cfm); -+ #endif -+ } else if (func == 1) { // write 2.4g pa drv_ibit -+ if (argc > 2) { -+ u8_l ibit = (u8_l)command_strtoul(argv[2], NULL, 16); -+ u8_l buf[2] = {func, ibit}; -+ AICWFDBG(LOGINFO, "set efuse drvibit:[%x]=%x\r\n", func, ibit); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_EFUSE_DRVIBIT, sizeof(buf), buf, &cfm); -+ #endif -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else { -+ AICWFDBG(LOGERROR, "wrong func: %x\n", func); -+ bytes_written = -EINVAL; -+ break; -+ } -+ memcpy(command, &cfm.rftest_result[0], 4); -+ bytes_written = 4; -+ } else if (strcasecmp(argv[0], "RDWR_EFUSE_PWROFSTFINE") == 0) { -+ u8_l func = 0; -+ AICWFDBG(LOGINFO, "read/write txpwr offset fine into efuse\n"); -+ if (argc > 1) { -+ func = (u8_l)command_strtoul(argv[1], NULL, 16); -+ } -+ if (func == 0) { // read cur -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_EFUSE_PWROFSTFINE, 0, NULL, &cfm); -+ } else if (func <= 2) { // write 2.4g/5g pwr ofst -+ if (argc > 3) { -+ u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); -+ s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); -+ u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; -+ AICWFDBG(LOGINFO, "set efuse pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst); -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_EFUSE_PWROFSTFINE, sizeof(buf), buf, &cfm); -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else { -+ AICWFDBG(LOGERROR, "wrong func: %x\n", func); -+ bytes_written = -EINVAL; -+ break; -+ } -+ if ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC) || -+ (g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW)) { // 6 = 3 (2.4g) * 2 -+ memcpy(command, &cfm.rftest_result[0], 6); -+ bytes_written = 6; -+ } else { // 7 = 3(2.4g) + 4(5g) -+ memcpy(command, &cfm.rftest_result[0], 7); -+ bytes_written = 7; -+ } -+ } else if (strcasecmp(argv[0], "SET_PAPR") == 0) { -+ AICWFDBG(LOGINFO, "set papr\n"); -+ if (argc > 1) { -+ u8_l func = (u8_l) command_strtoul(argv[1], NULL, 10); -+ AICWFDBG(LOGINFO, "papr %d\r\n", func); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_PAPR, sizeof(func), &func, NULL); -+ #endif -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else if (strcasecmp(argv[0], "SET_NOTCH") == 0) { -+ if (argc > 1) { -+ u8_l func = (u8_l) command_strtoul(argv[1], NULL, 10); -+ AICWFDBG(LOGINFO, "set notch %d\r\n", func); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_NOTCH, sizeof(func), &func, NULL); -+ #endif -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else if (strcasecmp(argv[0], "SET_SRRC") == 0) { -+ if (argc > 1) { -+ u8_l func = (u8_l) command_strtoul(argv[1], NULL, 10); -+ AICWFDBG(LOGINFO, "set srrc %d\r\n", func); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_SRRC, sizeof(func), &func, NULL); -+ #endif -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else if (strcasecmp(argv[0], "SET_FSS") == 0) { -+ if (argc > 1) { -+ u8_l func = (u8_l) command_strtoul(argv[1], NULL, 10); -+ AICWFDBG(LOGINFO, "set fss: %d\r\n", func); -+ #ifdef AICWF_SDIO_SUPPORT -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_FSS, sizeof(func), &func, NULL); -+ #endif -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else if (strcasecmp(argv[0], "RDWR_EFUSE_HE_OFF") == 0) { -+ if (argc > 1) { -+ u8_l func = command_strtoul(argv[1], NULL, 10); -+ AICWFDBG(LOGINFO, "set he off: %d\n", func); -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_EFUSE_HE_OFF, sizeof(func), (u8_l *)&func, &cfm); -+ AICWFDBG(LOGINFO, "he_off cfm: %d\n", cfm.rftest_result[0]); -+ memcpy(command, &cfm.rftest_result[0], 4); -+ bytes_written = 4; -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else if (strcasecmp(argv[0], "SET_COB_CAL") == 0) { -+ AICWFDBG(LOGINFO, "set_cob_cal\n"); -+ if (argc < 3) { -+ AICWFDBG(LOGERROR, "wrong param\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ setcob_cal.dutid = command_strtoul(argv[1], NULL, 10); -+ setcob_cal.chip_num = command_strtoul(argv[2], NULL, 10); -+ setcob_cal.dis_xtal = command_strtoul(argv[3], NULL, 10); -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_COB_CAL, sizeof(cmd_rf_setcobcal_t), (u8_l *)&setcob_cal, NULL); -+ } else if (strcasecmp(argv[0], "GET_COB_CAL_RES")==0) { -+ AICWFDBG(LOGINFO, "get cob cal res\n"); -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, GET_COB_CAL_RES, 0, NULL, &cfm); -+ memcpy(command, &cfm.rftest_result[0], 4); -+ bytes_written = 4; -+ AICWFDBG(LOGINFO, "cap=0x%x, cap_fine=0x%x\n", cfm.rftest_result[0] & 0x0000ffff, (cfm.rftest_result[0] >> 16) & 0x0000ffff); -+ } else if (strcasecmp(argv[0], "DO_COB_TEST") == 0) { -+ AICWFDBG(LOGINFO, "do_cob_test\n"); -+ setcob_cal.dutid = 1; -+ setcob_cal.chip_num = 1; -+ setcob_cal.dis_xtal = 0; -+ if (argc > 1 ) { -+ setcob_cal.dis_xtal = command_strtoul(argv[1], NULL, 10); -+ } -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, SET_COB_CAL, sizeof(cmd_rf_setcobcal_t), (u8_l *)&setcob_cal, NULL); -+ msleep(2000); -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, GET_COB_CAL_RES, 0, NULL, &cfm); -+ state = (cfm.rftest_result[0] >> 16) & 0x000000ff; -+ if (!state){ -+ AICWFDBG(LOGINFO, "cap= 0x%x, cap_fine= 0x%x, freq_ofst= %d Hz\n", -+ cfm.rftest_result[0] & 0x000000ff, (cfm.rftest_result[0] >> 8) & 0x000000ff, cfm.rftest_result[1]); -+ cob_result_ptr = (cob_result_ptr_t *) & (cfm.rftest_result[2]); -+ AICWFDBG(LOGINFO, "golden_rcv_dut= %d , tx_rssi= %d dBm, snr = %d dB\ndut_rcv_godlden= %d , rx_rssi= %d dBm", -+ cob_result_ptr->golden_rcv_dut_num, cob_result_ptr->rssi_static, cob_result_ptr->snr_static, -+ cob_result_ptr->dut_rcv_golden_num, cob_result_ptr->dut_rssi_static); -+ memcpy(command, &cfm.rftest_result, 16); -+ bytes_written = 16; -+ } else { -+ AICWFDBG(LOGERROR, "cob not idle\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else if (strcasecmp(argv[0], "RDWR_EFUSE_SDIOCFG") == 0) { -+ u8_l func = 0; -+ AICWFDBG(LOGINFO, "read/write sdiocfg_bit into efuse\n"); -+ if (argc > 1) { -+ func = (u8_l)command_strtoul(argv[1], NULL, 16); -+ } -+ if (func == 0) { // read cur -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_EFUSE_SDIOCFG, 0, NULL, &cfm); -+ } else if (func == 1) { // write sdiocfg -+ if (argc > 2) { -+ u8_l ibit = (u8_l)command_strtoul(argv[2], NULL, 16); -+ u8_l buf[2] = {func, ibit}; -+ AICWFDBG(LOGINFO, "set efuse sdiocfg:[%x]=%x\r\n", func, ibit); -+ rwnx_send_rftest_req(g_rwnx_plat->sdiodev->rwnx_hw, RDWR_EFUSE_SDIOCFG, sizeof(buf), buf, &cfm); -+ } else { -+ AICWFDBG(LOGERROR, "wrong args\n"); -+ bytes_written = -EINVAL; -+ break; -+ } -+ } else { -+ AICWFDBG(LOGERROR, "wrong func: %x\n", func); -+ bytes_written = -EINVAL; -+ break; -+ } -+ memcpy(command, &cfm.rftest_result[0], 4); -+ bytes_written = 4; -+ } else if (strcasecmp(argv[0], "SETSUSPENDMODE") == 0 && testmode == 0) { -+ #ifdef AICWF_SDIO_SUPPORT -+ #ifdef CONFIG_GPIO_WAKEUP -+ setsusp_mode = command_strtoul(argv[1], NULL, 10); -+ rwnx_send_me_set_lp_level(g_rwnx_plat->sdiodev->rwnx_hw, setsusp_mode); -+ if (setsusp_mode == 1) { -+ #if defined(CONFIG_SDIO_PWRCTRL) -+ aicwf_sdio_pwr_stctl(g_rwnx_plat->sdiodev, SDIO_SLEEP_ST); -+ #endif -+ -+ ret = aicwf_sdio_writeb(g_rwnx_plat->sdiodev, SDIOWIFI_WAKEUP_REG, 2); -+ if (ret < 0) { -+ sdio_err("reg:%d write failed!\n", SDIOWIFI_WAKEUP_REG); -+ } -+ } -+ AICWFDBG(LOGINFO, "set suspend mode %d\n", setsusp_mode); -+ #endif//CONFIG_GPIO_WAKEUP -+ #endif -+ } else { -+ AICWFDBG(LOGERROR, "wrong cmd:%s in %s\n", cmd, __func__); -+ bytes_written = -EINVAL; -+ } -+#endif -+ } while (0); -+ kfree(cmd); -+ kfree(para); -+ return bytes_written; -+} -+ -+//Android private command -+ -+#define RWNX_COUNTRY_CODE_LEN 2 -+#define CMD_SET_COUNTRY "COUNTRY" -+#define CMD_SET_VENDOR_EX_IE "SET_VENDOR_EX_IE" -+#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" -+ -+struct ieee80211_regdomain *getRegdomainFromRwnxDB(struct wiphy *wiphy, char *alpha2); -+struct ieee80211_regdomain *getRegdomainFromRwnxDBIndex(struct wiphy *wiphy, int index); -+extern int reg_regdb_size; -+ -+#ifdef CONFIG_SET_VENDOR_EXTENSION_IE -+extern u8_l vendor_extension_data[256]; -+extern int vendor_extension_len; -+ -+void set_vendor_extension_ie(char *command){ -+ -+ char databyte[3]={0x00, 0x00, 0x00}; -+ int skip = strlen(CMD_SET_VENDOR_EX_IE) + 1; -+ int command_index = skip; -+ int data_index = 0; -+ -+ memset(vendor_extension_data, 0, 256); -+ vendor_extension_len = 0; -+ memcpy(databyte, command + command_index, 2); -+ vendor_extension_len = command_strtoul(databyte, NULL, 16); -+ printk("%s len:%d \r\n", __func__, vendor_extension_len); -+ -+ //parser command and save data in vendor_extension_data -+ for(data_index = 0;data_index < vendor_extension_len; data_index++){ -+ command_index = command_index + 3; -+ memcpy(databyte, command + command_index, 2); -+ vendor_extension_data[data_index] = command_strtoul(databyte, NULL, 16); -+ } -+ -+} -+#endif//CONFIG_SET_VENDOR_EXTENSION_IE -+ -+ -+int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) -+{ -+#define PRIVATE_COMMAND_MAX_LEN 8192 -+#define PRIVATE_COMMAND_DEF_LEN 4096 -+ -+ struct rwnx_vif *vif = netdev_priv(net); -+ int ret = 0; -+ char *command = NULL; -+ int bytes_written = 0; -+ android_wifi_priv_cmd priv_cmd; -+ int buf_size = 0; -+ int skip = 0; -+ char *country = NULL; -+ struct ieee80211_regdomain *regdomain; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ ///todo: add our lock -+ //net_os_wake_lock(net); -+ -+ -+/* if (!capable(CAP_NET_ADMIN)) { -+ ret = -EPERM; -+ goto exit; -+ }*/ -+ if (!ifr->ifr_data) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+#ifdef CONFIG_COMPAT -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)) -+ if (in_compat_syscall()) -+#else -+ if (is_compat_task()) -+#endif -+ { -+ compat_android_wifi_priv_cmd compat_priv_cmd; -+ if (copy_from_user(&compat_priv_cmd, ifr->ifr_data, sizeof(compat_android_wifi_priv_cmd))) { -+ ret = -EFAULT; -+ goto exit; -+ } -+ priv_cmd.buf = compat_ptr(compat_priv_cmd.buf); -+ priv_cmd.used_len = compat_priv_cmd.used_len; -+ priv_cmd.total_len = compat_priv_cmd.total_len; -+ } else -+#endif /* CONFIG_COMPAT */ -+ { -+ if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) { -+ ret = -EFAULT; -+ goto exit; -+ } -+ } -+ if ((priv_cmd.total_len > PRIVATE_COMMAND_MAX_LEN) || (priv_cmd.total_len < 0)) { -+ printk("%s: buf length invalid:%d\n", __FUNCTION__, priv_cmd.total_len); -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ buf_size = max(priv_cmd.total_len, PRIVATE_COMMAND_DEF_LEN); -+ command = kmalloc((buf_size + 1), GFP_KERNEL); -+ -+ if (!command) { -+ printk("%s: failed to allocate memory\n", __FUNCTION__); -+ ret = -ENOMEM; -+ goto exit; -+ } -+ if (copy_from_user(command, priv_cmd.buf, priv_cmd.total_len)) { -+ ret = -EFAULT; -+ goto exit; -+ } -+ command[priv_cmd.total_len] = '\0'; -+ -+ /* outputs */ -+ AICWFDBG(LOGINFO, "%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name); -+ AICWFDBG(LOGINFO, "cmd = %d\n", cmd); -+ AICWFDBG(LOGINFO, "buf_size=%d\n", buf_size); -+ -+#if 1//Handle Android command -+ if(!strncasecmp(command, CMD_SET_COUNTRY, strlen(CMD_SET_COUNTRY))) { -+ skip = strlen(CMD_SET_COUNTRY) + 1; -+ country = command + skip; -+ if (!country || strlen(country) < RWNX_COUNTRY_CODE_LEN) { -+ printk("%s: invalid country code\n", __func__); -+ ret = -EINVAL; -+ goto exit; -+ } -+#if 0 -+ for(index = 0; index < reg_regdb_size; index++){ -+ regdomain = getRegdomainFromRwnxDBIndex(vif->rwnx_hw->wiphy, index); -+ if((ret = regulatory_set_wiphy_regd(vif->rwnx_hw->wiphy, regdomain))){ -+ printk("regulatory_set_wiphy_regd fail \r\n"); -+ }else{ -+ printk("regulatory_set_wiphy_regd ok \r\n"); -+ } -+ } -+#endif -+ AICWFDBG(LOGINFO, "%s country code:%c%c\n", __func__, toupper(country[0]), toupper(country[1])); -+ regdomain = getRegdomainFromRwnxDB(vif->rwnx_hw->wiphy, country); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) -+ if((ret = regulatory_set_wiphy_regd(vif->rwnx_hw->wiphy, regdomain))){ -+ printk("regulatory_set_wiphy_regd fail \r\n"); -+ } -+#else -+ wiphy_apply_custom_regulatory(vif->rwnx_hw->wiphy, regdomain); -+#endif -+ } -+#ifdef CONFIG_SET_VENDOR_EXTENSION_IE -+ else if(!strncasecmp(command, CMD_SET_VENDOR_EX_IE, strlen(CMD_SET_VENDOR_EX_IE))){ -+ set_vendor_extension_ie(command); -+ } -+#endif//CONFIG_SET_VENDOR_EXTENSION_IE -+ else if(!strncasecmp(command, CMD_SET_AP_WPS_P2P_IE, strlen(CMD_SET_AP_WPS_P2P_IE))){ -+ ret = 0; -+ goto exit; -+ } -+#endif//Handle Android command -+ -+ bytes_written = handle_private_cmd(net, command, priv_cmd.total_len); -+ if (bytes_written >= 0) { -+ if ((bytes_written == 0) && (priv_cmd.total_len > 0)) { -+ command[0] = '\0'; -+ } -+ if (bytes_written >= priv_cmd.total_len) { -+ printk("%s: err. bytes_written:%d >= buf_size:%d \n", -+ __FUNCTION__, bytes_written, buf_size); -+ goto exit; -+ } -+ bytes_written++; -+ priv_cmd.used_len = bytes_written; -+ if (copy_to_user(priv_cmd.buf, command, bytes_written)) { -+ printk("%s: failed to copy data to user buffer\n", __FUNCTION__); -+ ret = -EFAULT; -+ } -+ } else { -+ /* Propagate the error */ -+ ret = bytes_written; -+ } -+ -+exit: -+ ///todo: add our unlock -+ //net_os_wake_unlock(net); -+ kfree(command); -+ return ret; -+} -+ -+#ifdef CONFIG_MCU_MESSAGE -+#define CMD_GET_VERSION_STR "GET_VERSION" -+#define CMD_GET_SSID_STR "GET_SSID" -+#define CMD_SET_SSID_STR "SET_SSID" -+#define CMD_GET_PASS_STR "GET_PASS" -+#define CMD_SET_PASS_STR "SET_PASS" -+#define CMD_GET_VAR_STR "GET_VAR" -+#define CMD_SET_VAR_STR "SET_VAR" -+ -+enum custmsg_cmd_tag -+{ -+ CUST_CMD_GET_VERSION = 0, -+ CUST_CMD_GET_SSID, -+ CUST_CMD_SET_SSID, -+ CUST_CMD_GET_PASS, -+ CUST_CMD_SET_PASS, -+ CUST_CMD_GET_VAR, -+ CUST_CMD_SET_VAR, -+ CUST_CMD_MAX -+}; -+ -+int handle_custom_msg(char *command, u32 cmd_len) -+{ -+ int bytes_read = 0, max_bytes_to_read = 0; -+ struct rwnx_hw *p_rwnx_hw = NULL; -+ u32 cmd, len = 0, flags = 0; -+ char *buf = NULL; -+ struct dbg_custom_msg_cfm *cust_msg_cfm; -+ printk("cmd,%s,%ld\n",command,strlen(command)); -+ if (strncasecmp(command, CMD_GET_VERSION_STR, strlen(CMD_GET_VERSION_STR)) == 0) { -+ cmd = CUST_CMD_GET_VERSION; -+ max_bytes_to_read = 32; // max str len for version -+ } else if (strncasecmp(command, CMD_GET_SSID_STR, strlen(CMD_GET_SSID_STR)) == 0) { -+ cmd = CUST_CMD_GET_SSID; -+ max_bytes_to_read = 48; // max str len for ssid -+ } else if (strncasecmp(command, CMD_SET_SSID_STR, strlen(CMD_SET_SSID_STR)) == 0) { -+ cmd = CUST_CMD_SET_SSID; -+ len = cmd_len - (strlen(CMD_SET_SSID_STR) + 1); -+ buf = command + (strlen(CMD_SET_SSID_STR) + 1); -+ max_bytes_to_read = 0; -+ } else if (strncasecmp(command, CMD_GET_PASS_STR, strlen(CMD_GET_PASS_STR)) == 0) { -+ cmd = CUST_CMD_GET_PASS; -+ max_bytes_to_read = 64; // max str len for PASS -+ } else if (strncasecmp(command, CMD_SET_PASS_STR, strlen(CMD_SET_PASS_STR)) == 0) { -+ cmd = CUST_CMD_SET_PASS; -+ len = cmd_len - (strlen(CMD_SET_PASS_STR) + 1); -+ buf = command + (strlen(CMD_SET_PASS_STR) + 1); -+ max_bytes_to_read = 0; -+ } else if (strncasecmp(command, CMD_GET_VAR_STR, strlen(CMD_GET_VAR_STR)) == 0) { -+ cmd = CUST_CMD_GET_VAR; -+ max_bytes_to_read = 64; // max str len for VAR -+ } else if (strncasecmp(command, CMD_SET_VAR_STR, strlen(CMD_SET_VAR_STR)) == 0) { -+ cmd = CUST_CMD_SET_VAR; -+ len = cmd_len - (strlen(CMD_SET_VAR_STR) + 1); -+ buf = command + (strlen(CMD_SET_VAR_STR) + 1); -+ max_bytes_to_read = 0; -+ } else { -+ printk("invalid cmd: %s\r\n", command); -+ return -1; -+ } -+ if (len < 0) { -+ printk("invalid len: %d\r\n", len); -+ return -3; -+ } -+ #ifdef AICWF_SDIO_SUPPORT -+ p_rwnx_hw = g_rwnx_plat->sdiodev->rwnx_hw; -+ #endif -+ #ifdef AICWF_USB_SUPPORT -+ p_rwnx_hw = g_rwnx_plat->usbdev->rwnx_hw; -+ #endif -+ cust_msg_cfm = (struct dbg_custom_msg_cfm *)kmalloc((offsetof(struct dbg_custom_msg_cfm, buf) + max_bytes_to_read), GFP_KERNEL); -+ if (cust_msg_cfm == NULL) { -+ printk("msg cfm alloc fail\r\n"); -+ return -2; -+ } -+ rwnx_send_dbg_custom_msg_req(p_rwnx_hw, cmd, buf, len, flags, cust_msg_cfm); -+ bytes_read = cust_msg_cfm->len; -+ printk("Custom msg cfm: cmd=%d, len=%d, status=%x\n", cust_msg_cfm->cmd, bytes_read, cust_msg_cfm->status); -+ if (bytes_read) { -+ memcpy(command, cust_msg_cfm->buf, bytes_read); -+ command[bytes_read] = '\0'; -+ } else { -+ command[0] = '\0'; -+ } -+ if (cust_msg_cfm->status) { -+ printk("cfm status: %x", cust_msg_cfm->status); -+ } -+ return bytes_read; -+} -+ -+int devipc_cust_msg(struct net_device *net, struct ifreq *ifr, int cmd) -+{ -+#ifdef PRIVATE_COMMAND_MAX_LEN -+#undef PRIVATE_COMMAND_MAX_LEN -+#undef PRIVATE_COMMAND_DEF_LEN -+#define PRIVATE_COMMAND_MAX_LEN 8192 -+#define PRIVATE_COMMAND_DEF_LEN 4096 -+#endif -+ int ret = 0; -+ char *command = NULL; -+ int bytes_written = 0; -+ android_wifi_priv_cmd priv_cmd; -+ int buf_size = 0; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ ///todo: add our lock -+ //net_os_wake_lock(net); -+ -+ -+/* if (!capable(CAP_NET_ADMIN)) { -+ ret = -EPERM; -+ goto exit; -+ }*/ -+ if (!ifr->ifr_data) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+#ifdef CONFIG_COMPAT -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)) -+ if (in_compat_syscall()) -+#else -+ if (is_compat_task()) -+#endif -+ { -+ compat_android_wifi_priv_cmd compat_priv_cmd; -+ if (copy_from_user(&compat_priv_cmd, ifr->ifr_data, sizeof(compat_android_wifi_priv_cmd))) { -+ ret = -EFAULT; -+ goto exit; -+ } -+ priv_cmd.buf = compat_ptr(compat_priv_cmd.buf); -+ priv_cmd.used_len = compat_priv_cmd.used_len; -+ priv_cmd.total_len = compat_priv_cmd.total_len; -+ } else -+#endif /* CONFIG_COMPAT */ -+ { -+ if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) { -+ ret = -EFAULT; -+ goto exit; -+ } -+ } -+ if ((priv_cmd.total_len > PRIVATE_COMMAND_MAX_LEN) || (priv_cmd.total_len < 0)) { -+ printk("%s: buf length invalid:%d\n", __FUNCTION__, priv_cmd.total_len); -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ buf_size = max(priv_cmd.total_len, PRIVATE_COMMAND_DEF_LEN); -+ command = kmalloc((buf_size + 1), GFP_KERNEL); -+ -+ if (!command) -+ { -+ printk("%s: failed to allocate memory\n", __FUNCTION__); -+ ret = -ENOMEM; -+ goto exit; -+ } -+ if (copy_from_user(command, priv_cmd.buf, priv_cmd.used_len)) { -+ ret = -EFAULT; -+ goto exit; -+ } -+ command[priv_cmd.used_len] = '\0'; -+ -+ /* outputs */ -+ printk("%s: Devipc custom msg \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name); -+ printk("cmd = %x\n", cmd); -+ printk("buf_size=%d\n", buf_size); -+ -+ -+ bytes_written = handle_custom_msg(command, priv_cmd.used_len); -+ if (bytes_written >= 0) { -+ if ((bytes_written == 0) && (priv_cmd.total_len > 0)) { -+ command[0] = '\0'; -+ } -+ if (bytes_written >= priv_cmd.total_len) { -+ printk("%s: err. bytes_written:%d >= buf_size:%d \n", -+ __FUNCTION__, bytes_written, buf_size); -+ goto exit; -+ } -+ bytes_written++; -+ priv_cmd.used_len = bytes_written; -+ if (copy_to_user(priv_cmd.buf, command, bytes_written)) { -+ printk("%s: failed to copy data to user buffer\n", __FUNCTION__); -+ ret = -EFAULT; -+ } -+ } -+ else { -+ /* Propagate the error */ -+ ret = bytes_written; -+ } -+ -+exit: -+ ///todo: add our unlock -+ //net_os_wake_unlock(net); -+ kfree(command); -+ return ret; -+} -+#endif -+ -+ -+#define IOCTL_HOSTAPD (SIOCIWFIRSTPRIV+28) -+#define IOCTL_WPAS (SIOCIWFIRSTPRIV+30) -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) -+static int rwnx_do_ioctl(struct net_device *net, struct ifreq *req, int cmd) -+#else -+static int rwnx_do_ioctl(struct net_device *net, struct ifreq *req, void __user *data, int cmd) -+#endif -+{ -+ int ret = 0; -+ ///TODO: add ioctl command handler later -+ switch (cmd) { -+ case IOCTL_HOSTAPD: -+ printk("IOCTL_HOSTAPD\n"); -+ break; -+ case IOCTL_WPAS: -+ AICWFDBG(LOGINFO, "IOCTL_WPAS\n"); -+ break; -+ case SIOCDEVPRIVATE: -+ AICWFDBG(LOGINFO, "IOCTL SIOCDEVPRIVATE\n"); -+ break; -+ case (SIOCDEVPRIVATE+1): -+ AICWFDBG(LOGINFO, "IOCTL PRIVATE\n"); -+ ret = android_priv_cmd(net, req, cmd); -+ break; -+ case (SIOCDEVPRIVATE+2): -+ AICWFDBG(LOGINFO, "IOCTL PRIVATE+2\n"); -+ #ifdef CONFIG_MCU_MESSAGE -+ devipc_cust_msg(net, req, cmd); -+ #endif -+ break; -+ default: -+ ret = -EOPNOTSUPP; -+ } -+ return ret; -+} -+ -+/** -+ * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); -+ * Called when a user wants to get the network device usage -+ * statistics. Drivers must do one of the following: -+ * 1. Define @ndo_get_stats64 to fill in a zero-initialised -+ * rtnl_link_stats64 structure passed by the caller. -+ * 2. Define @ndo_get_stats to update a net_device_stats structure -+ * (which should normally be dev->stats) and return a pointer to -+ * it. The structure may be changed asynchronously only if each -+ * field is written atomically. -+ * 3. Update dev->stats asynchronously and atomically, and define -+ * neither operation. -+ */ -+static struct net_device_stats *rwnx_get_stats(struct net_device *dev) -+{ -+ struct rwnx_vif *vif = netdev_priv(dev); -+ -+ return &vif->net_stats; -+} -+ -+/** -+ * u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb, -+ * struct net_device *sb_dev); -+ * Called to decide which queue to when device supports multiple -+ * transmit queues. -+ */ -+u16 rwnx_select_queue(struct net_device *dev, struct sk_buff *skb, -+ struct net_device *sb_dev) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ return rwnx_select_txq(rwnx_vif, skb); -+} -+ -+/** -+ * int (*ndo_set_mac_address)(struct net_device *dev, void *addr); -+ * This function is called when the Media Access Control address -+ * needs to be changed. If this interface is not defined, the -+ * mac address can not be changed. -+ */ -+static int rwnx_set_mac_address(struct net_device *dev, void *addr) -+{ -+ struct sockaddr *sa = addr; -+ int ret = 0; -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ AICWFDBG(LOGTRACE, "%s enter \r\n", __func__); -+ -+ ret = eth_mac_addr(dev, sa); -+ AICWFDBG(LOGINFO, "%s set %02X:%02X:%02X:%02X:%02X:%02X\r\n", __func__, -+ dev->dev_addr[0],dev->dev_addr[1],dev->dev_addr[2], -+ dev->dev_addr[3],dev->dev_addr[4],dev->dev_addr[5]); -+ memcpy(rwnx_vif->wdev.address, dev->dev_addr, 6); -+ -+ return ret; -+} -+ -+static const struct net_device_ops rwnx_netdev_ops = { -+ .ndo_open = rwnx_open, -+ .ndo_stop = rwnx_close, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) -+ .ndo_do_ioctl = rwnx_do_ioctl, -+#else -+ .ndo_siocdevprivate = rwnx_do_ioctl, -+#endif -+ .ndo_start_xmit = rwnx_start_xmit, -+ .ndo_get_stats = rwnx_get_stats, -+#ifndef CONFIG_ONE_TXQ -+ .ndo_select_queue = rwnx_select_queue, -+#endif -+#ifdef CONFIG_SUPPORT_REALTIME_CHANGE_MAC -+ .ndo_set_mac_address = rwnx_set_mac_address -+#endif -+// .ndo_set_features = rwnx_set_features, -+// .ndo_set_rx_mode = rwnx_set_multicast_list, -+}; -+ -+static const struct net_device_ops rwnx_netdev_monitor_ops = { -+ .ndo_open = rwnx_open, -+ .ndo_stop = rwnx_close, -+ .ndo_get_stats = rwnx_get_stats, -+ .ndo_set_mac_address = rwnx_set_mac_address, -+}; -+ -+static void rwnx_netdev_setup(struct net_device *dev) -+{ -+ ether_setup(dev); -+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; -+ dev->netdev_ops = &rwnx_netdev_ops; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) -+ dev->destructor = free_netdev; -+#else -+ dev->needs_free_netdev = true; -+#endif -+ dev->watchdog_timeo = RWNX_TX_LIFETIME_MS; -+ -+ dev->needed_headroom = sizeof(struct rwnx_txhdr) + RWNX_SWTXHDR_ALIGN_SZ; -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ dev->needed_headroom = max(dev->needed_headroom, -+ (unsigned short)(sizeof(struct rwnx_amsdu_txhdr) -+ + sizeof(struct ethhdr) + 4 -+ + sizeof(rfc1042_header) + 2)); -+#endif /* CONFIG_RWNX_AMSDUS_TX */ -+ -+ dev->hw_features = 0; -+} -+ -+/********************************************************************* -+ * Cfg80211 callbacks (and helper) -+ *********************************************************************/ -+static struct rwnx_vif *rwnx_interface_add(struct rwnx_hw *rwnx_hw, -+ const char *name, -+ unsigned char name_assign_type, -+ enum nl80211_iftype type, -+ struct vif_params *params) -+{ -+ struct net_device *ndev; -+ struct rwnx_vif *vif; -+ int min_idx, max_idx; -+ int vif_idx = -1; -+ int i; -+ int nx_nb_ndev_txq = NX_NB_NDEV_TXQ; -+ -+ if((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) || -+ ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ -+ nx_nb_ndev_txq = NX_NB_NDEV_TXQ_FOR_OLD_IC; -+ } -+ -+ AICWFDBG(LOGINFO, "rwnx_interface_add: %s, %d, %d\r\n", name, type, NL80211_IFTYPE_P2P_DEVICE); -+ // Look for an available VIF -+ if (type == NL80211_IFTYPE_AP_VLAN) { -+ min_idx = NX_VIRT_DEV_MAX; -+ max_idx = NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX; -+ } else { -+ min_idx = 0; -+ max_idx = NX_VIRT_DEV_MAX; -+ } -+ -+ for (i = min_idx; i < max_idx; i++) { -+ if ((rwnx_hw->avail_idx_map) & BIT(i)) { -+ vif_idx = i; -+ break; -+ } -+ } -+ if (vif_idx < 0) -+ return NULL; -+ -+ #ifndef CONFIG_RWNX_MON_DATA -+ list_for_each_entry(vif, &rwnx_hw->vifs, list) { -+ // Check if monitor interface already exists or type is monitor -+ if ((RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_MONITOR) || -+ (type == NL80211_IFTYPE_MONITOR)) { -+ wiphy_err(rwnx_hw->wiphy, -+ "Monitor+Data interface support (MON_DATA) disabled\n"); -+ return NULL; -+ } -+ } -+ #endif -+ -+#ifndef CONFIG_ONE_TXQ -+ ndev = alloc_netdev_mqs(sizeof(*vif), name, name_assign_type, -+ rwnx_netdev_setup, nx_nb_ndev_txq, 1); -+#else -+ ndev = alloc_netdev_mqs(sizeof(*vif), name, name_assign_type, -+ rwnx_netdev_setup, 1, 1); -+#endif -+ -+ if (!ndev) -+ return NULL; -+ -+ vif = netdev_priv(ndev); -+ vif->key_has_add = 0; -+ ndev->ieee80211_ptr = &vif->wdev; -+ vif->wdev.wiphy = rwnx_hw->wiphy; -+ vif->rwnx_hw = rwnx_hw; -+ vif->ndev = ndev; -+ vif->drv_vif_index = vif_idx; -+ SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy)); -+ vif->wdev.netdev = ndev; -+ vif->wdev.iftype = type; -+ vif->up = false; -+ vif->ch_index = RWNX_CH_NOT_SET; -+ memset(&vif->net_stats, 0, sizeof(vif->net_stats)); -+ vif->is_p2p_vif = 0; -+ -+ #ifdef CONFIG_BR_SUPPORT -+ spin_lock_init(&vif->br_ext_lock); -+ #endif /* CONFIG_BR_SUPPORT */ -+ -+ -+ switch (type) { -+ case NL80211_IFTYPE_STATION: -+ vif->sta.ap = NULL; -+ vif->sta.tdls_sta = NULL; -+ vif->sta.external_auth = false; -+ break; -+ case NL80211_IFTYPE_P2P_CLIENT: -+ vif->sta.ap = NULL; -+ vif->sta.tdls_sta = NULL; -+ vif->sta.external_auth = false; -+ vif->is_p2p_vif = 1; -+ break; -+ case NL80211_IFTYPE_MESH_POINT: -+ INIT_LIST_HEAD(&vif->ap.mpath_list); -+ INIT_LIST_HEAD(&vif->ap.proxy_list); -+ vif->ap.create_path = false; -+ vif->ap.generation = 0; -+ vif->ap.mesh_pm = NL80211_MESH_POWER_ACTIVE; -+ vif->ap.next_mesh_pm = NL80211_MESH_POWER_ACTIVE; -+ // no break -+ case NL80211_IFTYPE_AP: -+ INIT_LIST_HEAD(&vif->ap.sta_list); -+ memset(&vif->ap.bcn, 0, sizeof(vif->ap.bcn)); -+ break; -+ case NL80211_IFTYPE_P2P_GO: -+ INIT_LIST_HEAD(&vif->ap.sta_list); -+ memset(&vif->ap.bcn, 0, sizeof(vif->ap.bcn)); -+ vif->is_p2p_vif = 1; -+ break; -+ case NL80211_IFTYPE_AP_VLAN: -+ { -+ struct rwnx_vif *master_vif; -+ bool found = false; -+ list_for_each_entry(master_vif, &rwnx_hw->vifs, list) { -+ if ((RWNX_VIF_TYPE(master_vif) == NL80211_IFTYPE_AP) && -+ !(!memcmp(master_vif->ndev->dev_addr, params->macaddr, -+ ETH_ALEN))) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ goto err; -+ -+ vif->ap_vlan.master = master_vif; -+ vif->ap_vlan.sta_4a = NULL; -+ break; -+ } -+ case NL80211_IFTYPE_MONITOR: -+ ndev->type = ARPHRD_IEEE80211_RADIOTAP; -+ ndev->netdev_ops = &rwnx_netdev_monitor_ops; -+ break; -+ default: -+ break; -+ } -+ -+ if (type == NL80211_IFTYPE_AP_VLAN) { -+ memcpy((void *)ndev->dev_addr, (const void *)params->macaddr, ETH_ALEN); -+ memcpy((void *)vif->wdev.address, (const void *)params->macaddr, ETH_ALEN); -+ } else { -+#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 17, 0) -+ unsigned char mac_addr[6]; -+ memcpy(mac_addr, rwnx_hw->wiphy->perm_addr, ETH_ALEN); -+ mac_addr[5] ^= vif_idx; -+ //memcpy(ndev->dev_addr, mac_addr, ETH_ALEN); -+ eth_hw_addr_set(ndev, mac_addr); -+ memcpy(vif->wdev.address, mac_addr, ETH_ALEN); -+#else -+ memcpy(ndev->dev_addr, rwnx_hw->wiphy->perm_addr, ETH_ALEN); -+ ndev->dev_addr[5] ^= vif_idx; -+ memcpy(vif->wdev.address, ndev->dev_addr, ETH_ALEN); -+#endif -+ -+ } -+ -+ AICWFDBG(LOGINFO, "interface add:%x %x %x %x %x %x\n", vif->wdev.address[0], vif->wdev.address[1], \ -+ vif->wdev.address[2], vif->wdev.address[3], vif->wdev.address[4], vif->wdev.address[5]); -+ -+ if (params) { -+ vif->use_4addr = params->use_4addr; -+ ndev->ieee80211_ptr->use_4addr = params->use_4addr; -+ } else -+ vif->use_4addr = false; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) -+ if (cfg80211_register_netdevice(ndev)) -+#else -+ if (register_netdevice(ndev)) -+#endif -+ goto err; -+ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ list_add_tail(&vif->list, &rwnx_hw->vifs); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ rwnx_hw->avail_idx_map &= ~BIT(vif_idx); -+ -+ return vif; -+ -+err: -+ free_netdev(ndev); -+ return NULL; -+} -+ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) -+void aicwf_p2p_alive_timeout(ulong data) -+#else -+void aicwf_p2p_alive_timeout(struct timer_list *t) -+#endif -+{ -+ struct rwnx_hw *rwnx_hw; -+ struct rwnx_vif *rwnx_vif; -+ struct rwnx_vif *rwnx_vif1, *tmp; -+ u8_l p2p = 0; -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) -+ rwnx_vif = (struct rwnx_vif *)data; -+ rwnx_hw = rwnx_vif->rwnx_hw; -+ #else -+ rwnx_hw = from_timer(rwnx_hw, t, p2p_alive_timer); -+ rwnx_vif = rwnx_hw->p2p_dev_vif; -+ #endif -+ -+ list_for_each_entry_safe(rwnx_vif1, tmp, &rwnx_hw->vifs, list) { -+ if ((rwnx_hw->avail_idx_map & BIT(rwnx_vif1->drv_vif_index)) == 0) { -+ switch (RWNX_VIF_TYPE(rwnx_vif1)) { -+ case NL80211_IFTYPE_P2P_CLIENT: -+ case NL80211_IFTYPE_P2P_GO: -+ rwnx_hw->is_p2p_alive = 1; -+ p2p = 1; -+ break; -+ default: -+ break; -+ } -+ } -+ } -+ -+ if (p2p) -+ atomic_set(&rwnx_hw->p2p_alive_timer_count, 0); -+ else -+ atomic_inc(&rwnx_hw->p2p_alive_timer_count); -+ -+ if (atomic_read(&rwnx_hw->p2p_alive_timer_count) < P2P_ALIVE_TIME_COUNT) { -+ mod_timer(&rwnx_hw->p2p_alive_timer, -+ jiffies + msecs_to_jiffies(P2P_ALIVE_TIME_MS)); -+ return; -+ } else -+ atomic_set(&rwnx_hw->p2p_alive_timer_count, 0); -+ -+ rwnx_hw->is_p2p_alive = 0; -+ if (rwnx_vif->up) { -+ rwnx_send_remove_if (rwnx_hw, rwnx_vif->vif_index, true); -+ -+ /* Ensure that we won't process disconnect ind */ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ -+ rwnx_vif->up = false; -+ rwnx_hw->vif_table[rwnx_vif->vif_index] = NULL; -+ AICWFDBG(LOGDEBUG, "%s rwnx_vif[%d] down \r\n", __func__, rwnx_vif->vif_index); -+ rwnx_hw->vif_started--; -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ } -+} -+ -+ -+/********************************************************************* -+ * Cfg80211 callbacks (and helper) -+ *********************************************************************/ -+static struct wireless_dev *rwnx_virtual_interface_add(struct rwnx_hw *rwnx_hw, -+ const char *name, -+ unsigned char name_assign_type, -+ enum nl80211_iftype type, -+ struct vif_params *params) -+{ -+ struct wireless_dev *wdev = NULL; -+ struct rwnx_vif *vif; -+ int min_idx, max_idx; -+ int vif_idx = -1; -+ int i; -+ -+ printk("rwnx_virtual_interface_add: %d, %s\n", type, name); -+ -+ if (type == NL80211_IFTYPE_AP_VLAN) { -+ min_idx = NX_VIRT_DEV_MAX; -+ max_idx = NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX; -+ } else { -+ min_idx = 0; -+ max_idx = NX_VIRT_DEV_MAX; -+ } -+ -+ for (i = min_idx; i < max_idx; i++) { -+ if ((rwnx_hw->avail_idx_map) & BIT(i)) { -+ vif_idx = i; -+ break; -+ } -+ } -+ -+ if (vif_idx < 0) { -+ printk("virtual_interface_add %s fail\n", name); -+ return NULL; -+ } -+ -+ vif = kzalloc(sizeof(struct rwnx_vif), GFP_KERNEL); -+ if (unlikely(!vif)) { -+ printk("Could not allocate wireless device\n"); -+ return NULL; -+ } -+ wdev = &vif->wdev; -+ wdev->wiphy = rwnx_hw->wiphy; -+ wdev->iftype = type; -+ -+ printk("rwnx_virtual_interface_add, ifname=%s, wdev=%p, vif_idx=%d\n", name, wdev, vif_idx); -+ -+ #ifndef CONFIG_USE_P2P0 -+ vif->is_p2p_vif = 1; -+ vif->rwnx_hw = rwnx_hw; -+ vif->vif_index = vif_idx; -+ vif->wdev.wiphy = rwnx_hw->wiphy; -+ vif->drv_vif_index = vif_idx; -+ vif->up = false; -+ vif->ch_index = RWNX_CH_NOT_SET; -+ memset(&vif->net_stats, 0, sizeof(vif->net_stats)); -+ vif->use_4addr = false; -+ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ list_add_tail(&vif->list, &rwnx_hw->vifs); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ -+ if (rwnx_hw->is_p2p_alive == 0) { -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) -+ init_timer(&rwnx_hw->p2p_alive_timer); -+ rwnx_hw->p2p_alive_timer.data = (unsigned long)vif; -+ rwnx_hw->p2p_alive_timer.function = aicwf_p2p_alive_timeout; -+ #else -+ timer_setup(&rwnx_hw->p2p_alive_timer, aicwf_p2p_alive_timeout, 0); -+ #endif -+ rwnx_hw->is_p2p_alive = 0; -+ rwnx_hw->is_p2p_connected = 0; -+ rwnx_hw->p2p_dev_vif = vif; -+ atomic_set(&rwnx_hw->p2p_alive_timer_count, 0); -+ } -+ #endif -+ rwnx_hw->avail_idx_map &= ~BIT(vif_idx); -+ -+ memcpy(vif->wdev.address, rwnx_hw->wiphy->perm_addr, ETH_ALEN); -+ vif->wdev.address[5] ^= vif_idx; -+ printk("p2p dev addr=%x %x %x %x %x %x\n", vif->wdev.address[0], vif->wdev.address[1], \ -+ vif->wdev.address[2], vif->wdev.address[3], vif->wdev.address[4], vif->wdev.address[5]); -+ -+ return wdev; -+} -+ -+/* -+ * @brief Retrieve the rwnx_sta object allocated for a given MAC address -+ * and a given role. -+ */ -+static struct rwnx_sta *rwnx_retrieve_sta(struct rwnx_hw *rwnx_hw, -+ struct rwnx_vif *rwnx_vif, u8 *addr, -+ __le16 fc, bool ap) -+{ -+ if (ap) { -+ /* only deauth, disassoc and action are bufferable MMPDUs */ -+ bool bufferable = ieee80211_is_deauth(fc) || -+ ieee80211_is_disassoc(fc) || -+ ieee80211_is_action(fc); -+ -+ /* Check if the packet is bufferable or not */ -+ if (bufferable) { -+ /* Check if address is a broadcast or a multicast address */ -+ if (is_broadcast_ether_addr(addr) || is_multicast_ether_addr(addr)) { -+ /* Returned STA pointer */ -+ struct rwnx_sta *rwnx_sta = &rwnx_hw->sta_table[rwnx_vif->ap.bcmc_index]; -+ -+ if (rwnx_sta->valid) -+ return rwnx_sta; -+ } else { -+ /* Returned STA pointer */ -+ struct rwnx_sta *rwnx_sta; -+ -+ /* Go through list of STAs linked with the provided VIF */ -+ spin_lock_bh(&rwnx_vif->rwnx_hw->cb_lock); -+ list_for_each_entry(rwnx_sta, &rwnx_vif->ap.sta_list, list) { -+ if (rwnx_sta->valid && -+ ether_addr_equal(rwnx_sta->mac_addr, addr)) { -+ /* Return the found STA */ -+ spin_unlock_bh(&rwnx_vif->rwnx_hw->cb_lock); -+ return rwnx_sta; -+ } -+ } -+ spin_unlock_bh(&rwnx_vif->rwnx_hw->cb_lock); -+ } -+ } -+ } else { -+ return rwnx_vif->sta.ap; -+ } -+ -+ return NULL; -+} -+ -+/** -+ * @add_virtual_intf: create a new virtual interface with the given name, -+ * must set the struct wireless_dev's iftype. Beware: You must create -+ * the new netdev in the wiphy's network namespace! Returns the struct -+ * wireless_dev, or an ERR_PTR. For P2P device wdevs, the driver must -+ * also set the address member in the wdev. -+ */ -+static struct wireless_dev *rwnx_cfg80211_add_iface(struct wiphy *wiphy, -+ const char *name, -+ unsigned char name_assign_type, -+ enum nl80211_iftype type, -+ struct vif_params *params) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct wireless_dev *wdev; -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) -+ unsigned char name_assign_type = NET_NAME_UNKNOWN; -+#endif -+ -+ if (type != NL80211_IFTYPE_P2P_DEVICE) { -+ struct rwnx_vif *vif = rwnx_interface_add(rwnx_hw, name, name_assign_type, type, params); -+ if (!vif) -+ return ERR_PTR(-EINVAL); -+ return &vif->wdev; -+ -+ } else { -+ wdev = rwnx_virtual_interface_add(rwnx_hw, name, name_assign_type, type, params); -+ if (!wdev) -+ return ERR_PTR(-EINVAL); -+ return wdev; -+ } -+} -+ -+/** -+ * @del_virtual_intf: remove the virtual interface -+ */ -+static int rwnx_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) -+{ -+ struct net_device *dev = wdev->netdev; -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = container_of(wdev, struct rwnx_vif, wdev); -+ -+ AICWFDBG(LOGINFO, "del_iface: %p, %x\n", wdev, wdev->address[5]); -+ -+ if (!dev || !rwnx_vif->ndev) { -+ cfg80211_unregister_wdev(wdev); -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ list_del(&rwnx_vif->list); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ rwnx_hw->avail_idx_map |= BIT(rwnx_vif->drv_vif_index); -+ rwnx_vif->ndev = NULL; -+ kfree(rwnx_vif); -+ return 0; -+ } -+ -+ netdev_info(dev, "Remove Interface"); -+ -+ if (dev->reg_state == NETREG_REGISTERED) { -+ /* Will call rwnx_close if interface is UP */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) -+ cfg80211_unregister_netdevice(dev); -+#else -+ unregister_netdevice(dev); -+#endif -+ -+ } -+ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ list_del(&rwnx_vif->list); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ rwnx_hw->avail_idx_map |= BIT(rwnx_vif->drv_vif_index); -+ rwnx_vif->ndev = NULL; -+ -+ /* Clear the priv in adapter */ -+ dev->ieee80211_ptr = NULL; -+ -+ return 0; -+} -+ -+/** -+ * @change_virtual_intf: change type/configuration of virtual interface, -+ * keep the struct wireless_dev's iftype updated. -+ */ -+static int rwnx_cfg80211_change_iface(struct wiphy *wiphy, -+ struct net_device *dev, -+ enum nl80211_iftype type, -+ struct vif_params *params) -+{ -+#ifndef CONFIG_RWNX_MON_DATA -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+#endif -+ struct rwnx_vif *vif = netdev_priv(dev); -+ struct mm_add_if_cfm add_if_cfm; -+ bool_l p2p = false; -+ int ret; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ printk("change_if: %d to %d, %d, %d", vif->wdev.iftype, type, NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_STATION); -+ -+#ifdef CONFIG_COEX -+ if (type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_P2P_GO) -+ rwnx_send_coex_req(vif->rwnx_hw, 1, 0); -+ if (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_AP || RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_P2P_GO) -+ rwnx_send_coex_req(vif->rwnx_hw, 0, 1); -+#endif -+#ifndef CONFIG_RWNX_MON_DATA -+ if ((type == NL80211_IFTYPE_MONITOR) && -+ (RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_MONITOR)) { -+ struct rwnx_vif *vif_el; -+ list_for_each_entry(vif_el, &rwnx_hw->vifs, list) { -+ // Check if data interface already exists -+ if ((vif_el != vif) && -+ (RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_MONITOR)) { -+ wiphy_err(rwnx_hw->wiphy, -+ "Monitor+Data interface support (MON_DATA) disabled\n"); -+ return -EIO; -+ } -+ } -+ } -+#endif -+ -+ // Reset to default case (i.e. not monitor) -+ dev->type = ARPHRD_ETHER; -+ dev->netdev_ops = &rwnx_netdev_ops; -+ -+ switch (type) { -+ case NL80211_IFTYPE_STATION: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ vif->sta.ap = NULL; -+ vif->sta.tdls_sta = NULL; -+ vif->sta.external_auth = false; -+ break; -+ case NL80211_IFTYPE_MESH_POINT: -+ INIT_LIST_HEAD(&vif->ap.mpath_list); -+ INIT_LIST_HEAD(&vif->ap.proxy_list); -+ vif->ap.create_path = false; -+ vif->ap.generation = 0; -+ // no break -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+ INIT_LIST_HEAD(&vif->ap.sta_list); -+ memset(&vif->ap.bcn, 0, sizeof(vif->ap.bcn)); -+ break; -+ case NL80211_IFTYPE_AP_VLAN: -+ return -EPERM; -+ case NL80211_IFTYPE_MONITOR: -+ dev->type = ARPHRD_IEEE80211_RADIOTAP; -+ dev->netdev_ops = &rwnx_netdev_monitor_ops; -+ break; -+ default: -+ break; -+ } -+ -+ vif->wdev.iftype = type; -+ if (params->use_4addr != -1) -+ vif->use_4addr = params->use_4addr; -+ if (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO) -+ p2p = true; -+ -+ if (vif->up) { -+ /* Abort scan request on the vif */ -+ if (vif->rwnx_hw->scan_request && -+ vif->rwnx_hw->scan_request->wdev == &vif->wdev) { -+#if 0 -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ cfg80211_scan_done(vif->rwnx_hw->scan_request, &info); -+#else -+ cfg80211_scan_done(vif->rwnx_hw->scan_request, true); -+#endif -+ ret = rwnx_send_scanu_cancel_req(vif->rwnx_hw, NULL); -+ if (ret) { -+ printk("scanu_cancel fail\n"); -+ return ret; -+ } -+ vif->rwnx_hw->scan_request = NULL; -+#else -+ if ((ret = rwnx_send_scanu_cancel_req(vif->rwnx_hw, NULL))) { -+ AICWFDBG(LOGERROR, "scanu_cancel fail\n"); -+ return ret; -+ } -+#endif -+ } -+ ret = rwnx_send_remove_if(vif->rwnx_hw, vif->vif_index, false); -+ if (ret) { -+ printk("remove_if fail\n"); -+ return ret; -+ } -+ vif->rwnx_hw->vif_table[vif->vif_index] = NULL; -+ printk("change_if from %d \n", vif->vif_index); -+ ret = rwnx_send_add_if(vif->rwnx_hw, vif->wdev.address, RWNX_VIF_TYPE(vif), p2p, &add_if_cfm); -+ if (ret) { -+ printk("add if fail\n"); -+ return ret; -+ } -+ if (add_if_cfm.status != 0) { -+ printk("add if status fail\n"); -+ return -EIO; -+ } -+ -+ printk("change_if to %d \n", add_if_cfm.inst_nbr); -+ /* Save the index retrieved from LMAC */ -+ spin_lock_bh(&vif->rwnx_hw->cb_lock); -+ vif->vif_index = add_if_cfm.inst_nbr; -+ vif->rwnx_hw->vif_table[add_if_cfm.inst_nbr] = vif; -+ spin_unlock_bh(&vif->rwnx_hw->cb_lock); -+ } -+ -+ return 0; -+} -+ -+static int rwnx_cfgp2p_start_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev) -+{ -+ int ret = 0; -+ -+ //do nothing -+ printk("P2P interface started\n"); -+ -+ return ret; -+} -+ -+static void rwnx_cfgp2p_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev) -+{ -+ int ret = 0; -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = container_of(wdev, struct rwnx_vif, wdev); -+ /* Abort scan request on the vif */ -+ if (rwnx_hw->scan_request && -+ rwnx_hw->scan_request->wdev == &rwnx_vif->wdev) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ cfg80211_scan_done(rwnx_hw->scan_request, &info); -+#else -+ cfg80211_scan_done(rwnx_hw->scan_request, true); -+#endif -+ rwnx_hw->scan_request = NULL; -+ ret = rwnx_send_scanu_cancel_req(rwnx_hw, NULL); -+ if (ret) -+ printk("scanu_cancel fail\n"); -+ } -+ -+ if (rwnx_vif == rwnx_hw->p2p_dev_vif) { -+ rwnx_hw->is_p2p_alive = 0; -+ if (timer_pending(&rwnx_hw->p2p_alive_timer)) { -+ del_timer_sync(&rwnx_hw->p2p_alive_timer); -+ } -+ -+ if (rwnx_vif->up) { -+ rwnx_send_remove_if(rwnx_hw, rwnx_vif->vif_index, true); -+ /* Ensure that we won't process disconnect ind */ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_vif->up = false; -+ rwnx_hw->vif_table[rwnx_vif->vif_index] = NULL; -+ AICWFDBG(LOGDEBUG, "%s rwnx_vif[%d] down \r\n", __func__, rwnx_vif->vif_index); -+ rwnx_hw->vif_started--; -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ } -+ -+ } -+ -+ printk("Exit. P2P interface stopped\n"); -+ -+ return; -+} -+ -+ -+/** -+ * @scan: Request to do a scan. If returning zero, the scan request is given -+ * the driver, and will be valid until passed to cfg80211_scan_done(). -+ * For scan results, call cfg80211_inform_bss(); you can call this outside -+ * the scan/scan_done bracket too. -+ */ -+static int rwnx_cfg80211_scan(struct wiphy *wiphy, -+ struct cfg80211_scan_request *request) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = container_of(request->wdev, struct rwnx_vif, wdev); -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if(testmode){ -+ return -EBUSY; -+ } -+ -+ if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING){ -+ AICWFDBG(LOGERROR, "%s wifi is connecting, return it\r\n", __func__); -+ return -EBUSY; -+ } -+ -+ if (scanning) { -+ AICWFDBG(LOGERROR, "%s is scanning, abort\n", __func__); -+ #if 0 -+ error = rwnx_send_scanu_cancel_req(rwnx_hw, NULL); -+ if (error) -+ return error; -+ msleep(150); -+ #endif -+ return -EBUSY; -+ } -+ -+ if ((RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || -+ RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) && -+ rwnx_vif->sta.external_auth) { -+ AICWFDBG(LOGERROR, "scan about: external auth\r\n"); -+ return -EBUSY; -+ } -+ -+ rwnx_hw->scan_request = request; -+ error = rwnx_send_scanu_req(rwnx_hw, rwnx_vif, request); -+ if (error) -+ return error; -+ -+ return 0; -+} -+ -+bool key_flag = false; -+/** -+ * @add_key: add a key with the given parameters. @mac_addr will be %NULL -+ * when adding a group key. -+ */ -+ static int rwnx_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, -+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2) -+ int link_id, -+#endif -+ u8 key_index, bool pairwise, const u8 *mac_addr, -+ struct key_params *params) -+ -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *vif = netdev_priv(netdev); -+ int i, error = 0; -+ struct mm_key_add_cfm key_add_cfm; -+ u8_l cipher = 0; -+ struct rwnx_sta *sta = NULL; -+ struct rwnx_key *rwnx_key; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (mac_addr) { -+ sta = rwnx_get_sta(rwnx_hw, mac_addr); -+ if (!sta) -+ return -EINVAL; -+ rwnx_key = &sta->key; -+ if (vif->wdev.iftype == NL80211_IFTYPE_STATION || vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) -+ vif->sta.paired_cipher_type = params->cipher; -+ } else { -+ rwnx_key = &vif->key[key_index]; -+ vif->key_has_add = 1; -+ if (vif->wdev.iftype == NL80211_IFTYPE_STATION || vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) -+ vif->sta.group_cipher_type = params->cipher; -+ } -+ -+ /* Retrieve the cipher suite selector */ -+ switch (params->cipher) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ cipher = MAC_CIPHER_WEP40; -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ cipher = MAC_CIPHER_WEP104; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ cipher = MAC_CIPHER_TKIP; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ cipher = MAC_CIPHER_CCMP; -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ cipher = MAC_CIPHER_BIP_CMAC_128; -+ break; -+ case WLAN_CIPHER_SUITE_SMS4: -+ { -+ // Need to reverse key order -+ u8 tmp, *key = (u8 *)params->key; -+ cipher = MAC_CIPHER_WPI_SMS4; -+ for (i = 0; i < WPI_SUBKEY_LEN/2; i++) { -+ tmp = key[i]; -+ key[i] = key[WPI_SUBKEY_LEN - 1 - i]; -+ key[WPI_SUBKEY_LEN - 1 - i] = tmp; -+ } -+ for (i = 0; i < WPI_SUBKEY_LEN/2; i++) { -+ tmp = key[i + WPI_SUBKEY_LEN]; -+ key[i + WPI_SUBKEY_LEN] = key[WPI_KEY_LEN - 1 - i]; -+ key[WPI_KEY_LEN - 1 - i] = tmp; -+ } -+ break; -+ } -+ default: -+ return -EINVAL; -+ } -+ -+ key_flag = false; -+ error = rwnx_send_key_add(rwnx_hw, vif->vif_index, -+ (sta ? sta->sta_idx : 0xFF), pairwise, -+ (u8 *)params->key, params->key_len, -+ key_index, cipher, &key_add_cfm); -+ if (error) -+ return error; -+ -+ if (key_add_cfm.status != 0) { -+ RWNX_PRINT_CFM_ERR(key_add); -+ return -EIO; -+ } -+ -+ /* Save the index retrieved from LMAC */ -+ rwnx_key->hw_idx = key_add_cfm.hw_key_idx; -+ -+ return 0; -+} -+ -+/** -+ * @get_key: get information about the key with the given parameters. -+ * @mac_addr will be %NULL when requesting information for a group -+ * key. All pointers given to the @callback function need not be valid -+ * after it returns. This function should return an error if it is -+ * not possible to retrieve the key, -ENOENT if it doesn't exist. -+ * -+ */ -+static int rwnx_cfg80211_get_key(struct wiphy *wiphy, struct net_device *netdev, -+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2) -+ int link_id, -+#endif -+ u8 key_index, bool pairwise, const u8 *mac_addr, -+ void *cookie, -+ void (*callback)(void *cookie, struct key_params*)) -+{ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ return -1; -+} -+ -+ -+/** -+ * @del_key: remove a key given the @mac_addr (%NULL for a group key) -+ * and @key_index, return -ENOENT if the key doesn't exist. -+ */ -+static int rwnx_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, -+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2) -+ int link_id, -+#endif -+ u8 key_index, bool pairwise, const u8 *mac_addr) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *vif = netdev_priv(netdev); -+ int error; -+ struct rwnx_sta *sta = NULL; -+ struct rwnx_key *rwnx_key; -+ if (!key_flag && vif->wdev.iftype == NL80211_IFTYPE_STATION) -+ return 0; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ if (mac_addr) { -+ sta = rwnx_get_sta(rwnx_hw, mac_addr); -+ if (!sta) -+ return -EINVAL; -+ rwnx_key = &sta->key; -+ if (vif->wdev.iftype == NL80211_IFTYPE_STATION || vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) -+ vif->sta.paired_cipher_type = 0xff; -+ } else { -+ rwnx_key = &vif->key[key_index]; -+ vif->key_has_add = 0; -+ if (vif->wdev.iftype == NL80211_IFTYPE_STATION || vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) -+ vif->sta.group_cipher_type = 0xff; -+ } -+ -+ error = rwnx_send_key_del(rwnx_hw, rwnx_key->hw_idx); -+ -+ rwnx_key->hw_idx = 0; -+ return error; -+} -+ -+/** -+ * @set_default_key: set the default key on an interface -+ */ -+static int rwnx_cfg80211_set_default_key(struct wiphy *wiphy, -+ struct net_device *netdev, -+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2) -+ int link_id, -+#endif -+ u8 key_index, bool unicast, bool multicast) -+{ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ return 0; -+} -+ -+/** -+ * @set_default_mgmt_key: set the default management frame key on an interface -+ */ -+static int rwnx_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, -+ struct net_device *netdev, -+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2) -+ int link_id, -+#endif -+ u8 key_index) -+{ -+ return 0; -+} -+ -+/** -+ * @connect: Connect to the ESS with the specified parameters. When connected, -+ * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. -+ * If the connection fails for some reason, call cfg80211_connect_result() -+ * with the status from the AP. -+ * (invoked with the wireless_dev mutex held) -+ */ -+static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_connect_params *sme) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct sm_connect_cfm sm_connect_cfm; -+ int error = 0; -+ int is_wep = ((sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) || -+ (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) || -+ (sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP40) || -+ (sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP104)); -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+#if 1 -+#if 0 -+ if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED){ -+ AICWFDBG(LOGERROR, "%s driver was connected return it \r\n", __func__); -+ return -EALREADY; -+ } -+#endif -+ if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED) { -+ AICWFDBG(LOGDEBUG, "%s this connection is roam \r\n", __func__); -+ rwnx_vif->sta.is_roam = true; -+ }else{ -+ rwnx_vif->sta.is_roam = false; -+ } -+ -+ if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING|| -+ (int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING) { -+ AICWFDBG(LOGERROR, "%s driver is disconnecting or connecting ,return it \r\n", __func__); -+ return -EALREADY; -+ } -+#endif -+ -+ atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTING); -+ -+ if (is_wep) { -+ if(sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) { -+ if(rwnx_vif->wep_enabled && rwnx_vif->wep_auth_err) { -+ if(rwnx_vif->last_auth_type == NL80211_AUTHTYPE_SHARED_KEY) -+ sme->auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; -+ else -+ sme->auth_type = NL80211_AUTHTYPE_SHARED_KEY; -+ } else { -+ if((rwnx_vif->wep_enabled && !rwnx_vif->wep_auth_err)) -+ sme->auth_type = rwnx_vif->last_auth_type; -+ else -+ sme->auth_type = NL80211_AUTHTYPE_SHARED_KEY; -+ } -+ printk("auto: use sme->auth_type = %d\r\n", sme->auth_type); -+ } else { -+ if (rwnx_vif->wep_enabled && rwnx_vif->wep_auth_err && (sme->auth_type == rwnx_vif->last_auth_type)) { -+ if(sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) { -+ sme->auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; -+ printk("start connect, auth_type changed, shared --> open\n"); -+ } else if(sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) { -+ sme->auth_type = NL80211_AUTHTYPE_SHARED_KEY; -+ printk("start connect, auth_type changed, open --> shared\n"); -+ } -+ } -+ } -+ } -+ -+ /* For SHARED-KEY authentication, must install key first */ -+ if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY && sme->key) { -+ struct key_params key_params; -+ key_params.key = (u8*)sme->key; -+ key_params.seq = NULL; -+ key_params.key_len = sme->key_len; -+ key_params.seq_len = 0; -+ key_params.cipher = sme->crypto.cipher_group; -+ rwnx_cfg80211_add_key(wiphy, dev, -+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2) -+ 0, -+#endif -+ sme->key_idx, false, NULL, &key_params); -+ } -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL) -+ else if ((sme->auth_type == NL80211_AUTHTYPE_SAE) && -+ !(sme->flags & CONNECT_REQ_EXTERNAL_AUTH_SUPPORT)) { -+ netdev_err(dev, "Doesn't support SAE without external authentication\n"); -+ return -EINVAL; -+ } -+#endif -+ -+ if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) { -+ rwnx_hw->is_p2p_connected = 1; -+ } -+ -+ if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION || rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) { -+ rwnx_vif->sta.paired_cipher_type = 0xff; -+ rwnx_vif->sta.group_cipher_type = 0xff; -+ } -+ -+ /* Forward the information to the LMAC */ -+ error = rwnx_send_sm_connect_req(rwnx_hw, rwnx_vif, sme, &sm_connect_cfm); -+ if (error) -+ return error; -+ -+ // Check the status -+ switch (sm_connect_cfm.status) { -+ case CO_OK: -+ error = 0; -+ break; -+ case CO_BUSY: -+ error = -EINPROGRESS; -+ break; -+ case CO_OP_IN_PROGRESS: -+ error = -EALREADY; -+ break; -+ default: -+ error = -EIO; -+ break; -+ } -+ -+ return error; -+} -+ -+/** -+ * @disconnect: Disconnect from the BSS/ESS. -+ * (invoked with the wireless_dev mutex held) -+ */ -+static int rwnx_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, -+ u16 reason_code) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ AICWFDBG(LOGINFO, "%s drv_vif_index:%d disconnect reason:%d \r\n", -+ __func__, rwnx_vif->drv_vif_index, reason_code); -+ -+#if 0 -+ while(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTING){ -+ AICWFDBG(LOGERROR, "%s driver connecting waiting 100ms \r\n", __func__); -+ msleep(100); -+ -+ if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTED){ -+ atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); -+ } -+#endif -+ if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTING){ -+ AICWFDBG(LOGINFO, "%s call cfg80211_connect_result reason:%d \r\n", -+ __func__, reason_code); -+ msleep(500); -+ } -+ -+ if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_DISCONNECTING) { -+ AICWFDBG(LOGERROR, "%s wifi is disconnecting, return it:%d \r\n", -+ __func__, reason_code); -+ return -EBUSY; -+ } -+ -+ if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTED){ -+ atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); -+ key_flag = true; -+ return(rwnx_send_sm_disconnect_req(rwnx_hw, rwnx_vif, reason_code)); -+ }else{ -+ cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0, -+ reason_code?reason_code:WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC); -+ atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED); -+ rwnx_external_auth_disable(rwnx_vif); -+ return 0; -+ } -+ -+} -+ -+#ifdef CONFIG_SCHED_SCAN -+ -+static int rwnx_cfg80211_sched_scan_stop(struct wiphy *wiphy, -+ struct net_device *ndev -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) -+ ,u64 reqid) -+#else -+ ) -+#endif -+{ -+ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ //struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ AICWFDBG(LOGINFO, "%s enter wiphy:%p\r\n", __func__, wiphy); -+ -+ if(rwnx_hw->scan_request){ -+ AICWFDBG(LOGINFO, "%s rwnx_send_scanu_cancel_req\r\n", __func__); -+ return rwnx_send_scanu_cancel_req(rwnx_hw, NULL); -+ }else{ -+ return 0; -+ } -+} -+ -+ -+static int rwnx_cfg80211_sched_scan_start(struct wiphy *wiphy, -+ struct net_device *dev, -+ struct cfg80211_sched_scan_request *request) -+ -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct cfg80211_scan_request *scan_request = NULL; -+ -+ int ret = 0; -+ int index = 0; -+ -+ AICWFDBG(LOGINFO, "%s enter wiphy:%p\r\n", __func__, wiphy); -+ -+ if(rwnx_hw->is_sched_scan || scanning){ -+ AICWFDBG(LOGERROR, "%s is_sched_scanning and scanning, busy", __func__); -+ return -EBUSY; -+ } -+ -+ scan_request = (struct cfg80211_scan_request *)kmalloc(sizeof(struct cfg80211_scan_request), GFP_KERNEL); -+ -+ scan_request->ssids = request->ssids; -+ scan_request->n_channels = request->n_channels; -+ scan_request->n_ssids = request->n_match_sets; -+ scan_request->no_cck = false; -+ scan_request->ie = request->ie; -+ scan_request->ie_len = request->ie_len; -+ scan_request->flags = request->flags; -+ -+ scan_request->wiphy = wiphy; -+ scan_request->scan_start = request->scan_start; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0) -+ memcpy(scan_request->mac_addr, request->mac_addr, ETH_ALEN); -+ memcpy(scan_request->mac_addr_mask, request->mac_addr_mask, ETH_ALEN); -+#endif -+ rwnx_hw->sched_scan_req = request; -+ scan_request->wdev = &rwnx_vif->wdev; -+ AICWFDBG(LOGDEBUG, "%s scan_request->n_channels:%d \r\n", __func__, scan_request->n_channels); -+ AICWFDBG(LOGDEBUG, "%s scan_request->n_ssids:%d \r\n", __func__, scan_request->n_ssids); -+ -+ for(index = 0; index < scan_request->n_ssids; index++){ -+ memset(scan_request->ssids[index].ssid, 0, IEEE80211_MAX_SSID_LEN); -+ -+ memcpy(scan_request->ssids[index].ssid, -+ request->match_sets[index].ssid.ssid, -+ IEEE80211_MAX_SSID_LEN); -+ -+ scan_request->ssids[index].ssid_len = request->match_sets[index].ssid.ssid_len; -+ -+ AICWFDBG(LOGDEBUG, "%s request ssid:%s len:%d \r\n", __func__, -+ scan_request->ssids[index].ssid, scan_request->ssids[index].ssid_len); -+ } -+ -+ for(index = 0;index < scan_request->n_channels; index++){ -+ scan_request->channels[index] = request->channels[index]; -+ -+ AICWFDBG(LOGDEBUG, "%s scan_request->channels[%d]:%d \r\n", __func__, index, -+ scan_request->channels[index]->center_freq); -+ -+ if(scan_request->channels[index] == NULL){ -+ AICWFDBG(LOGERROR, "%s ERROR!!! channels is NULL", __func__); -+ continue; -+ } -+ } -+ -+ rwnx_hw->is_sched_scan = true; -+ -+ if(scanning){ -+ AICWFDBG(LOGERROR, "%s scanning, about it", __func__); -+ kfree(scan_request); -+ return -EBUSY; -+ }else{ -+ ret = rwnx_cfg80211_scan(wiphy, scan_request); -+ } -+ -+ return ret; -+} -+#endif //CONFIG_SCHED_SCAN -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL) -+/** -+ * @external_auth: indicates result of offloaded authentication processing from -+ * user space -+ */ -+static int rwnx_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_external_auth_params *params) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ -+ if (!rwnx_vif->sta.external_auth) -+ return -EINVAL; -+ -+ rwnx_external_auth_disable(rwnx_vif); -+ return rwnx_send_sm_external_auth_required_rsp(rwnx_hw, rwnx_vif, -+ params->status); -+} -+#endif -+ -+/** -+ * @add_station: Add a new station. -+ */ -+static int rwnx_cfg80211_add_station(struct wiphy *wiphy, -+ struct net_device *dev, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) -+ u8 *mac, -+#else -+ const u8 *mac, -+#endif -+ struct station_parameters *params) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct me_sta_add_cfm me_sta_add_cfm; -+ int error = 0; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ WARN_ON(RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP_VLAN); -+ -+ /* Do not add TDLS station */ -+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) -+ return 0; -+ -+ /* Indicate we are in a STA addition process - This will allow handling -+ * potential PS mode change indications correctly -+ */ -+ rwnx_hw->adding_sta = true; -+ -+ /* Forward the information to the LMAC */ -+ error = rwnx_send_me_sta_add(rwnx_hw, params, mac, rwnx_vif->vif_index, &me_sta_add_cfm); -+ if (error) -+ return error; -+ -+ // Check the status -+ switch (me_sta_add_cfm.status) { -+ case CO_OK: -+ { -+ struct rwnx_sta *sta = &rwnx_hw->sta_table[me_sta_add_cfm.sta_idx]; -+ int tid; -+ sta->aid = params->aid; -+ -+ sta->sta_idx = me_sta_add_cfm.sta_idx; -+ sta->ch_idx = rwnx_vif->ch_index; -+ sta->vif_idx = rwnx_vif->vif_index; -+ sta->vlan_idx = sta->vif_idx; -+ sta->qos = (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) != 0; -+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION -+ sta->ht = params->link_sta_params.ht_capa ? 1 : 0; -+ sta->vht = params->link_sta_params.vht_capa ? 1 : 0; -+#else -+ sta->ht = params->ht_capa ? 1 : 0; -+ sta->vht = params->vht_capa ? 1 : 0; -+#endif -+ sta->acm = 0; -+ sta->key.hw_idx = 0; -+ -+ if (params->local_pm != NL80211_MESH_POWER_UNKNOWN) -+ sta->mesh_pm = params->local_pm; -+ else -+ sta->mesh_pm = rwnx_vif->ap.next_mesh_pm; -+ rwnx_update_mesh_power_mode(rwnx_vif); -+ -+ for (tid = 0; tid < NX_NB_TXQ_PER_STA; tid++) { -+ int uapsd_bit = rwnx_hwq2uapsd[rwnx_tid2hwq[tid]]; -+ if (params->uapsd_queues & uapsd_bit) -+ sta->uapsd_tids |= 1 << tid; -+ else -+ sta->uapsd_tids &= ~(1 << tid); -+ } -+ memcpy(sta->mac_addr, mac, ETH_ALEN); -+#ifdef CONFIG_DEBUG_FS -+ rwnx_dbgfs_register_rc_stat(rwnx_hw, sta); -+#endif -+ -+ /* Ensure that we won't process PS change or channel switch ind*/ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_txq_sta_init(rwnx_hw, sta, rwnx_txq_vif_get_status(rwnx_vif)); -+ list_add_tail(&sta->list, &rwnx_vif->ap.sta_list); -+ sta->valid = true; -+ rwnx_ps_bh_enable(rwnx_hw, sta, sta->ps.active || me_sta_add_cfm.pm_state); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ -+ error = 0; -+ -+ if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP || rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) { -+ struct station_info sinfo; -+ memset(&sinfo, 0, sizeof(struct station_info)); -+ sinfo.assoc_req_ies = NULL; -+ sinfo.assoc_req_ies_len = 0; -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) -+ sinfo.filled |= STATION_INFO_ASSOC_REQ_IES; -+ #endif -+ cfg80211_new_sta(rwnx_vif->ndev, sta->mac_addr, &sinfo, GFP_KERNEL); -+ } -+#ifdef CONFIG_RWNX_BFMER -+ if (rwnx_hw->mod_params->bfmer) -+ rwnx_send_bfmer_enable(rwnx_hw, sta, params->vht_capa); -+ -+ rwnx_mu_group_sta_init(sta, params->vht_capa); -+#endif /* CONFIG_RWNX_BFMER */ -+ -+ #define PRINT_STA_FLAG(f) \ -+ (params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "") -+ -+ netdev_info(dev, "Add sta %d (%pM) flags=%s%s%s%s%s%s%s", -+ sta->sta_idx, mac, -+ PRINT_STA_FLAG(AUTHORIZED), -+ PRINT_STA_FLAG(SHORT_PREAMBLE), -+ PRINT_STA_FLAG(WME), -+ PRINT_STA_FLAG(MFP), -+ PRINT_STA_FLAG(AUTHENTICATED), -+ PRINT_STA_FLAG(TDLS_PEER), -+ PRINT_STA_FLAG(ASSOCIATED)); -+ #undef PRINT_STA_FLAG -+ break; -+ } -+ default: -+ error = -EBUSY; -+ break; -+ } -+ -+ rwnx_hw->adding_sta = false; -+ -+ return error; -+} -+ -+/** -+ * @del_station: Remove a station -+ */ -+static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy, -+ struct net_device *dev, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) -+ u8 *mac -+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)) -+ const u8 *mac -+#else -+ struct station_del_parameters *params -+#endif -+ -+) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_sta *cur, *tmp; -+ int error = 0, found = 0; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) -+ const u8 *mac = NULL; -+#endif -+#ifdef AICWF_RX_REORDER -+ struct reord_ctrl_info *reord_info, *reord_tmp; -+ u8 *macaddr; -+ struct aicwf_rx_priv *rx_priv; -+#endif -+ -+ //RWNX_DBG(RWNX_FN_ENTRY_STR); -+ printk("%s: %pM\n", __func__, mac); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) -+ if (params) -+ mac = params->mac; -+#endif -+ -+ do { -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ if(list_empty(&rwnx_vif->ap.sta_list)) { -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ break; -+ } -+ -+ list_for_each_entry_safe(cur, tmp, &rwnx_vif->ap.sta_list, list) { -+ if ((!mac) || (!memcmp(cur->mac_addr, mac, ETH_ALEN))) { -+ found = 1; -+ break; -+ } -+ } -+ -+ if(found) { -+ cur->ps.active = false; -+ cur->valid = false; -+ list_del(&cur->list); -+ } -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ -+ if(found) { -+ netdev_info(dev, "Del sta %d (%pM)", cur->sta_idx, cur->mac_addr); -+ if (cur->vif_idx != cur->vlan_idx) { -+ struct rwnx_vif *vlan_vif; -+ vlan_vif = rwnx_hw->vif_table[cur->vlan_idx]; -+ if (vlan_vif->up) { -+ if ((RWNX_VIF_TYPE(vlan_vif) == NL80211_IFTYPE_AP_VLAN) && -+ (vlan_vif->use_4addr)) { -+ vlan_vif->ap_vlan.sta_4a = NULL; -+ } else { -+ WARN(1, "Deleting sta belonging to VLAN other than AP_VLAN 4A"); -+ } -+ } -+ } -+ if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP || rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) { -+ cfg80211_del_sta(rwnx_vif->ndev, cur->mac_addr, GFP_KERNEL); -+ } -+ -+#ifdef AICWF_RX_REORDER -+#ifdef AICWF_SDIO_SUPPORT -+ rx_priv = rwnx_hw->sdiodev->rx_priv; -+#else -+ rx_priv = rwnx_hw->usbdev->rx_priv; -+#endif -+ if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) { -+ BUG();//should be other function -+ } -+ else if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)){ -+ macaddr = cur->mac_addr; -+ printk("deinit:macaddr:%x,%x,%x,%x,%x,%x\r\n", macaddr[0],macaddr[1],macaddr[2], \ -+ macaddr[3],macaddr[4],macaddr[5]); -+ spin_lock_bh(&rx_priv->stas_reord_lock); -+ list_for_each_entry_safe(reord_info, reord_tmp, -+ &rx_priv->stas_reord_list, list) { -+ printk("reord_mac:%x,%x,%x,%x,%x,%x\r\n", reord_info->mac_addr[0],reord_info->mac_addr[1],reord_info->mac_addr[2], \ -+ reord_info->mac_addr[3],reord_info->mac_addr[4],reord_info->mac_addr[5]); -+ if (!memcmp(reord_info->mac_addr, macaddr, 6)) { -+ reord_deinit_sta(rx_priv, reord_info); -+ break; -+ } -+ } -+ spin_unlock_bh(&rx_priv->stas_reord_lock); -+ } -+#endif -+ -+ rwnx_txq_sta_deinit(rwnx_hw, cur); -+ error = rwnx_send_me_sta_del(rwnx_hw, cur->sta_idx, false); -+ if ((error != 0) && (error != -EPIPE)) -+ return error; -+ -+#ifdef CONFIG_RWNX_BFMER -+ // Disable Beamformer if supported -+ rwnx_bfmer_report_del(rwnx_hw, cur); -+ rwnx_mu_group_sta_del(rwnx_hw, cur); -+#endif /* CONFIG_RWNX_BFMER */ -+ -+#ifdef CONFIG_DEBUG_FS_AIC -+ rwnx_dbgfs_unregister_rc_stat(rwnx_hw, cur); -+#endif -+ } -+ -+ if(mac) -+ break; -+ } while (1); -+ -+ rwnx_update_mesh_power_mode(rwnx_vif); -+ -+ if(!found && mac != NULL) -+ return -ENOENT; -+ else -+ return 0; -+} -+ -+ -+void apm_staloss_work_process(struct work_struct *work) -+{ -+ struct rwnx_hw *rwnx_hw = container_of(work, struct rwnx_hw, apmStalossWork); -+ struct rwnx_sta *cur, *tmp; -+ int error = 0; -+ -+#ifdef AICWF_RX_REORDER -+ struct reord_ctrl_info *reord_info, *reord_tmp; -+ u8 *macaddr; -+ struct aicwf_rx_priv *rx_priv; -+#endif -+ struct rwnx_vif *rwnx_vif; -+ bool_l found = false; -+ const u8 *mac = rwnx_hw->sta_mac_addr; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ // Look for VIF entry -+ list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) { -+ if (rwnx_vif->vif_index == rwnx_hw->apm_vif_idx) { -+ found = true; -+ break; -+ } -+ } -+ -+ printk("apm vif idx=%d, found=%d, mac addr=%pM\n", rwnx_hw->apm_vif_idx, found, mac); -+ if (!found || !rwnx_vif || (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_AP && RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_P2P_GO)) -+ { -+ return; -+ } -+ -+ found = false; -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ list_for_each_entry_safe(cur, tmp, &rwnx_vif->ap.sta_list, list) { -+ if ((mac) && (!memcmp(cur->mac_addr, mac, ETH_ALEN))) { -+ found = true; -+ break; -+ } -+ } -+ if(found) { -+ cur->ps.active = false; -+ cur->valid = false; -+ list_del(&cur->list); -+ } -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ -+ if(found) { -+ netdev_info(rwnx_vif->ndev, "Del sta %d (%pM)", cur->sta_idx, cur->mac_addr); -+ if (cur->vif_idx != cur->vlan_idx) { -+ struct rwnx_vif *vlan_vif; -+ vlan_vif = rwnx_hw->vif_table[cur->vlan_idx]; -+ if (vlan_vif->up) { -+ if ((RWNX_VIF_TYPE(vlan_vif) == NL80211_IFTYPE_AP_VLAN) && -+ (vlan_vif->use_4addr)) { -+ vlan_vif->ap_vlan.sta_4a = NULL; -+ } else { -+ WARN(1, "Deleting sta belonging to VLAN other than AP_VLAN 4A"); -+ } -+ } -+ } -+ -+#ifdef AICWF_RX_REORDER -+#ifdef AICWF_SDIO_SUPPORT -+ rx_priv = rwnx_hw->sdiodev->rx_priv; -+#else -+ rx_priv = rwnx_hw->usbdev->rx_priv; -+#endif -+ if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) { -+ BUG();//should be other function -+ } else if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) { -+ macaddr = cur->mac_addr; -+ printk("deinit:macaddr:%x,%x,%x,%x,%x,%x\r\n", macaddr[0], macaddr[1], macaddr[2], \ -+ macaddr[3], macaddr[4], macaddr[5]); -+ spin_lock_bh(&rx_priv->stas_reord_lock); -+ list_for_each_entry_safe(reord_info, reord_tmp, -+ &rx_priv->stas_reord_list, list) { -+ printk("reord_mac:%x,%x,%x,%x,%x,%x\r\n", reord_info->mac_addr[0], reord_info->mac_addr[1], reord_info->mac_addr[2], \ -+ reord_info->mac_addr[3], reord_info->mac_addr[4], reord_info->mac_addr[5]); -+ if (!memcmp(reord_info->mac_addr, macaddr, 6)) { -+ reord_deinit_sta(rx_priv, reord_info); -+ break; -+ } -+ } -+ spin_unlock_bh(&rx_priv->stas_reord_lock); -+ } -+#endif -+ -+ rwnx_txq_sta_deinit(rwnx_hw, cur); -+ error = rwnx_send_me_sta_del(rwnx_hw, cur->sta_idx, false); -+ if ((error != 0) && (error != -EPIPE)) -+ return; -+ -+#ifdef CONFIG_RWNX_BFMER -+ // Disable Beamformer if supported -+ rwnx_bfmer_report_del(rwnx_hw, cur); -+ rwnx_mu_group_sta_del(rwnx_hw, cur); -+#endif /* CONFIG_RWNX_BFMER */ -+ -+#ifdef CONFIG_DEBUG_FS_AIC -+ rwnx_dbgfs_unregister_rc_stat(rwnx_hw, cur); -+#endif -+ }else { -+ printk("sta not found: %pM\n", mac); -+ return; -+ } -+ -+ rwnx_update_mesh_power_mode(rwnx_vif); -+} -+ -+ -+void apm_probe_sta_work_process(struct work_struct *work) -+{ -+ struct apm_probe_sta *probe_sta = container_of(work, struct apm_probe_sta, apmprobestaWork); -+ struct rwnx_vif *rwnx_vif = container_of(probe_sta, struct rwnx_vif, sta_probe); -+ bool found = false; -+ struct rwnx_sta *cur, *tmp; -+ -+ u8 *mac = rwnx_vif->sta_probe.sta_mac_addr; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ spin_lock_bh(&rwnx_vif->rwnx_hw->cb_lock); -+ list_for_each_entry_safe(cur, tmp, &rwnx_vif->ap.sta_list, list) { -+ if (!memcmp(cur->mac_addr, mac, ETH_ALEN)) { -+ found = true; -+ break; -+ } -+ } -+ spin_unlock_bh(&rwnx_vif->rwnx_hw->cb_lock); -+ -+ printk("sta %pM found = %d\n", mac, found); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) -+ if(found) -+ cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.probe_id, 1, 0, false, GFP_ATOMIC); -+ else -+ cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.probe_id, 0, 0, false, GFP_ATOMIC); -+#else -+ if(found) -+ cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.probe_id, 1, GFP_ATOMIC); -+ else -+ cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.probe_id, 0, GFP_ATOMIC); -+ -+#endif -+ rwnx_vif->sta_probe.probe_id ++; -+} -+/** -+ * @change_station: Modify a given station. Note that flags changes are not much -+ * validated in cfg80211, in particular the auth/assoc/authorized flags -+ * might come to the driver in invalid combinations -- make sure to check -+ * them, also against the existing state! Drivers must call -+ * cfg80211_check_station_change() to validate the information. -+ */ -+static int rwnx_cfg80211_change_station(struct wiphy *wiphy, -+ struct net_device *dev, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) -+ u8 *mac, -+#else -+ const u8 *mac, -+#endif -+ struct station_parameters *params) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *vif = netdev_priv(dev); -+ struct rwnx_sta *sta; -+ -+ sta = rwnx_get_sta(rwnx_hw, mac); -+ if (!sta) { -+ /* Add the TDLS station */ -+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) { -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct me_sta_add_cfm me_sta_add_cfm; -+ int error = 0; -+ -+ /* Indicate we are in a STA addition process - This will allow handling -+ * potential PS mode change indications correctly -+ */ -+ rwnx_hw->adding_sta = true; -+ -+ /* Forward the information to the LMAC */ -+ error = rwnx_send_me_sta_add(rwnx_hw, params, mac, rwnx_vif->vif_index, &me_sta_add_cfm); -+ if (error) -+ return error; -+ -+ // Check the status -+ switch (me_sta_add_cfm.status) { -+ case CO_OK: -+ { -+ int tid; -+ sta = &rwnx_hw->sta_table[me_sta_add_cfm.sta_idx]; -+ sta->aid = params->aid; -+ sta->sta_idx = me_sta_add_cfm.sta_idx; -+ sta->ch_idx = rwnx_vif->ch_index; -+ sta->vif_idx = rwnx_vif->vif_index; -+ sta->vlan_idx = sta->vif_idx; -+ sta->qos = (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) != 0; -+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION -+ sta->ht = params->link_sta_params.ht_capa ? 1 : 0; -+ sta->vht = params->link_sta_params.vht_capa ? 1 : 0; -+#else -+ sta->ht = params->ht_capa ? 1 : 0; -+ sta->vht = params->vht_capa ? 1 : 0; -+#endif -+ sta->acm = 0; -+ for (tid = 0; tid < NX_NB_TXQ_PER_STA; tid++) { -+ int uapsd_bit = rwnx_hwq2uapsd[rwnx_tid2hwq[tid]]; -+ if (params->uapsd_queues & uapsd_bit) -+ sta->uapsd_tids |= 1 << tid; -+ else -+ sta->uapsd_tids &= ~(1 << tid); -+ } -+ memcpy(sta->mac_addr, mac, ETH_ALEN); -+#ifdef CONFIG_DEBUG_FS -+ rwnx_dbgfs_register_rc_stat(rwnx_hw, sta); -+#endif -+ /* Ensure that we won't process PS change or channel switch ind*/ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_txq_sta_init(rwnx_hw, sta, rwnx_txq_vif_get_status(rwnx_vif)); -+ if (rwnx_vif->tdls_status == TDLS_SETUP_RSP_TX) { -+ rwnx_vif->tdls_status = TDLS_LINK_ACTIVE; -+ sta->tdls.initiator = true; -+ sta->tdls.active = true; -+ } -+ /* Set TDLS channel switch capability */ -+ if ((params->ext_capab[3] & WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) && -+ !rwnx_vif->tdls_chsw_prohibited) -+ sta->tdls.chsw_allowed = true; -+ rwnx_vif->sta.tdls_sta = sta; -+ sta->valid = true; -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+#ifdef CONFIG_RWNX_BFMER -+ if (rwnx_hw->mod_params->bfmer) -+ rwnx_send_bfmer_enable(rwnx_hw, sta, params->vht_capa); -+ -+ rwnx_mu_group_sta_init(sta, NULL); -+#endif /* CONFIG_RWNX_BFMER */ -+ -+ #define PRINT_STA_FLAG(f) \ -+ (params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "") -+ -+ netdev_info(dev, "Add %s TDLS sta %d (%pM) flags=%s%s%s%s%s%s%s", -+ sta->tdls.initiator ? "initiator" : "responder", -+ sta->sta_idx, mac, -+ PRINT_STA_FLAG(AUTHORIZED), -+ PRINT_STA_FLAG(SHORT_PREAMBLE), -+ PRINT_STA_FLAG(WME), -+ PRINT_STA_FLAG(MFP), -+ PRINT_STA_FLAG(AUTHENTICATED), -+ PRINT_STA_FLAG(TDLS_PEER), -+ PRINT_STA_FLAG(ASSOCIATED)); -+ #undef PRINT_STA_FLAG -+ -+ break; -+ } -+ default: -+ error = -EBUSY; -+ break; -+ } -+ -+ rwnx_hw->adding_sta = false; -+ } else { -+ return -EINVAL; -+ } -+ } -+ -+ if (params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) -+ rwnx_send_me_set_control_port_req(rwnx_hw, -+ (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED)) != 0, -+ sta->sta_idx); -+ -+ if (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_MESH_POINT) { -+ if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) { -+ if (params->plink_state < NUM_NL80211_PLINK_STATES) { -+ rwnx_send_mesh_peer_update_ntf(rwnx_hw, vif, sta->sta_idx, params->plink_state); -+ } -+ } -+ -+ if (params->local_pm != NL80211_MESH_POWER_UNKNOWN) { -+ sta->mesh_pm = params->local_pm; -+ rwnx_update_mesh_power_mode(vif); -+ } -+ } -+ -+ if (params->vlan) { -+ uint8_t vlan_idx; -+ -+ vif = netdev_priv(params->vlan); -+ vlan_idx = vif->vif_index; -+ -+ if (sta->vlan_idx != vlan_idx) { -+ struct rwnx_vif *old_vif; -+ old_vif = rwnx_hw->vif_table[sta->vlan_idx]; -+ rwnx_txq_sta_switch_vif(sta, old_vif, vif); -+ sta->vlan_idx = vlan_idx; -+ -+ if ((RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_AP_VLAN) && -+ (vif->use_4addr)) { -+ WARN((vif->ap_vlan.sta_4a), -+ "4A AP_VLAN interface with more than one sta"); -+ vif->ap_vlan.sta_4a = sta; -+ } -+ -+ if ((RWNX_VIF_TYPE(old_vif) == NL80211_IFTYPE_AP_VLAN) && -+ (old_vif->use_4addr)) { -+ old_vif->ap_vlan.sta_4a = NULL; -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+/** -+ * @start_ap: Start acting in AP mode defined by the parameters. -+ */ -+static int rwnx_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_ap_settings *settings) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct apm_start_cfm apm_start_cfm; -+ struct rwnx_ipc_elem_var elem; -+ struct rwnx_sta *sta; -+ int error = 0; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ INIT_WORK(&rwnx_vif->sta_probe.apmprobestaWork, apm_probe_sta_work_process); -+ rwnx_vif->sta_probe.apmprobesta_wq = create_singlethread_workqueue("apmprobe_wq"); -+ if (!rwnx_vif->sta_probe.apmprobesta_wq) { -+ txrx_err("insufficient memory to create apmprobe_wq.\n"); -+ return -ENOBUFS; -+ } -+ -+ if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) -+ rwnx_hw->is_p2p_connected = 1; -+ /* Forward the information to the LMAC */ -+ error = rwnx_send_apm_start_req(rwnx_hw, rwnx_vif, settings, &apm_start_cfm, &elem); -+ if (error) -+ goto end; -+ -+ // Check the status -+ switch (apm_start_cfm.status) { -+ case CO_OK: -+ { -+ u8 txq_status = 0; -+ rwnx_vif->ap.bcmc_index = apm_start_cfm.bcmc_idx; -+ rwnx_vif->ap.flags = 0; -+#if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL) -+ rwnx_vif->ap.aic_index = 0; -+#endif -+ sta = &rwnx_hw->sta_table[apm_start_cfm.bcmc_idx]; -+ sta->valid = true; -+ sta->aid = 0; -+ sta->sta_idx = apm_start_cfm.bcmc_idx; -+ sta->ch_idx = apm_start_cfm.ch_idx; -+ sta->vif_idx = rwnx_vif->vif_index; -+ sta->qos = false; -+ sta->acm = 0; -+ sta->ps.active = false; -+ rwnx_mu_group_sta_init(sta, NULL); -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_chanctx_link(rwnx_vif, apm_start_cfm.ch_idx, -+ &settings->chandef); -+ if (rwnx_hw->cur_chanctx != apm_start_cfm.ch_idx) { -+ txq_status = RWNX_TXQ_STOP_CHAN; -+ } -+ rwnx_txq_vif_init(rwnx_hw, rwnx_vif, txq_status); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ -+ netif_tx_start_all_queues(dev); -+ netif_carrier_on(dev); -+ error = 0; -+ /* If the AP channel is already the active, we probably skip radar -+ activation on MM_CHANNEL_SWITCH_IND (unless another vif use this -+ ctxt). In anycase retest if radar detection must be activated -+ */ -+ if (txq_status == 0) { -+ rwnx_radar_detection_enable_on_cur_channel(rwnx_hw); -+ } -+ break; -+ } -+ case CO_BUSY: -+ error = -EINPROGRESS; -+ break; -+ case CO_OP_IN_PROGRESS: -+ error = -EALREADY; -+ break; -+ default: -+ error = -EIO; -+ break; -+ } -+ -+ if (error) { -+ netdev_info(dev, "Failed to start AP (%d)", error); -+ } else { -+ netdev_info(dev, "AP started: ch=%d, bcmc_idx=%d channel=%d bw=%d", -+ rwnx_vif->ch_index, rwnx_vif->ap.bcmc_index, -+ ((settings->chandef).chan)->center_freq, -+ ((settings->chandef).width)); -+ } -+ -+end: -+ //rwnx_ipc_elem_var_deallocs(rwnx_hw, &elem); -+ -+ return error; -+} -+ -+ -+/** -+ * @change_beacon: Change the beacon parameters for an access point mode -+ * interface. This should reject the call when AP mode wasn't started. -+ */ -+static int rwnx_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_beacon_data *info) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *vif = netdev_priv(dev); -+ struct rwnx_bcn *bcn = &vif->ap.bcn; -+ struct rwnx_ipc_elem_var elem; -+ u8 *buf; -+ int error = 0; -+ elem.dma_addr = 0; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ // Build the beacon -+ buf = rwnx_build_bcn(bcn, info); -+ if (!buf) -+ return -ENOMEM; -+ -+ rwnx_send_bcn(rwnx_hw, buf, vif->vif_index, bcn->len); -+ -+ // Forward the information to the LMAC -+ error = rwnx_send_bcn_change(rwnx_hw, vif->vif_index, 0, -+ bcn->len, bcn->head_len, bcn->tim_len, NULL); -+ -+ return error; -+} -+ -+/** -+ * * @stop_ap: Stop being an AP, including stopping beaconing. -+ */ -+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION) -+static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev, unsigned int link_id) -+#else -+static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) -+#endif -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_sta *sta; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ netif_tx_stop_all_queues(dev); -+ netif_carrier_off(dev); -+ -+ if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) -+ rwnx_hw->is_p2p_connected = 0; -+ rwnx_radar_cancel_cac(&rwnx_hw->radar); -+ rwnx_send_apm_stop_req(rwnx_hw, rwnx_vif); -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_chanctx_unlink(rwnx_vif); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ -+ /* delete any remaining STA*/ -+ while (!list_empty(&rwnx_vif->ap.sta_list)) { -+ rwnx_cfg80211_del_station_compat(wiphy, dev, NULL); -+ } -+ -+ /* delete BC/MC STA */ -+ sta = &rwnx_hw->sta_table[rwnx_vif->ap.bcmc_index]; -+ rwnx_txq_vif_deinit(rwnx_hw, rwnx_vif); -+ rwnx_del_bcn(&rwnx_vif->ap.bcn); -+ rwnx_del_csa(rwnx_vif); -+ -+ flush_workqueue(rwnx_vif->sta_probe.apmprobesta_wq); -+ destroy_workqueue(rwnx_vif->sta_probe.apmprobesta_wq); -+ -+ netdev_info(dev, "AP Stopped"); -+ -+ return 0; -+} -+ -+/** -+ * @set_monitor_channel: Set the monitor mode channel for the device. If other -+ * interfaces are active this callback should reject the configuration. -+ * If no interfaces are active or the device is down, the channel should -+ * be stored for when a monitor interface becomes active. -+ * -+ * Also called internaly with chandef set to NULL simply to retrieve the channel -+ * configured at firmware level. -+ */ -+static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif; -+ struct me_config_monitor_cfm cfm; -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (rwnx_hw->monitor_vif == RWNX_INVALID_VIF) -+ return -EINVAL; -+ -+ rwnx_vif = rwnx_hw->vif_table[rwnx_hw->monitor_vif]; -+ -+ // Do nothing if monitor interface is already configured with the requested channel -+ if (rwnx_chanctx_valid(rwnx_hw, rwnx_vif->ch_index)) { -+ struct rwnx_chanctx *ctxt; -+ ctxt = &rwnx_vif->rwnx_hw->chanctx_table[rwnx_vif->ch_index]; -+ if (chandef && cfg80211_chandef_identical(&ctxt->chan_def, chandef)) -+ return 0; -+ } -+ -+ // Always send command to firmware. It allows to retrieve channel context index -+ // and its configuration. -+ if (rwnx_send_config_monitor_req(rwnx_hw, chandef, &cfm)) -+ return -EIO; -+ -+ // Always re-set channel context info -+ rwnx_chanctx_unlink(rwnx_vif); -+ -+ -+ -+ // If there is also a STA interface not yet connected then monitor interface -+ // will only have a channel context after the connection of the STA interface. -+ if (cfm.chan_index != RWNX_CH_NOT_SET) { -+ struct cfg80211_chan_def mon_chandef; -+ -+ if (rwnx_hw->vif_started > 1) { -+ // In this case we just want to update the channel context index not -+ // the channel configuration -+ rwnx_chanctx_link(rwnx_vif, cfm.chan_index, NULL); -+ return -EBUSY; -+ } -+ -+ mon_chandef.chan = ieee80211_get_channel(wiphy, cfm.chan.prim20_freq); -+ mon_chandef.center_freq1 = cfm.chan.center1_freq; -+ mon_chandef.center_freq2 = cfm.chan.center2_freq; -+ mon_chandef.width = chnl2bw[cfm.chan.type]; -+ rwnx_chanctx_link(rwnx_vif, cfm.chan_index, &mon_chandef); -+ } -+ -+ return 0; -+} -+ -+/** -+ * @probe_client: probe an associated client, must return a cookie that it -+ * later passes to cfg80211_probe_status(). -+ */ -+int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, u64 *cookie) -+{ -+// struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *vif = netdev_priv(dev); -+ struct rwnx_sta *sta = NULL; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if((RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_AP) && (RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_P2P_GO) && -+ (RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_AP_VLAN)) -+ return -EINVAL; -+ spin_lock_bh(&vif->rwnx_hw->cb_lock); -+ list_for_each_entry(sta, &vif->ap.sta_list, list){ -+ if (sta->valid && ether_addr_equal(sta->mac_addr, peer)) -+ break; -+ } -+ spin_unlock_bh(&vif->rwnx_hw->cb_lock); -+ -+ if (!sta) -+ return -ENOENT; -+ -+ -+ memcpy(vif->sta_probe.sta_mac_addr, peer, 6); -+ queue_work(vif->sta_probe.apmprobesta_wq, &vif->sta_probe.apmprobestaWork); -+ -+ *cookie = vif->sta_probe.probe_id; -+ -+ return 0; -+ -+} -+ -+/** -+ * @mgmt_frame_register: Notify driver that a management frame type was -+ * registered. Note that this callback may not sleep, and cannot run -+ * concurrently with itself. -+ */ -+void rwnx_cfg80211_mgmt_frame_register(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u16 frame_type, bool reg) -+{ -+} -+ -+/** -+ * @set_wiphy_params: Notify that wiphy parameters have changed; -+ * @changed bitfield (see &enum wiphy_params_flags) describes which values -+ * have changed. The actual parameter values are available in -+ * struct wiphy. If returning an error, no value should be changed. -+ */ -+static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) -+{ -+ return 0; -+} -+ -+ -+/** -+ * @set_tx_power: set the transmit power according to the parameters, -+ * the power passed is in mBm, to get dBm use MBM_TO_DBM(). The -+ * wdev may be %NULL if power was set for the wiphy, and will -+ * always be %NULL unless the driver supports per-vif TX power -+ * (as advertised by the nl80211 feature flag.) -+ */ -+static int rwnx_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, -+ enum nl80211_tx_power_setting type, int mbm) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *vif; -+ s8 pwr; -+ int res = 0; -+ -+ if (type == NL80211_TX_POWER_AUTOMATIC) { -+ pwr = 0x7f; -+ } else { -+ pwr = MBM_TO_DBM(mbm); -+ } -+ -+ if (wdev) { -+ vif = container_of(wdev, struct rwnx_vif, wdev); -+ res = rwnx_send_set_power(rwnx_hw, vif->vif_index, pwr, NULL); -+ } else { -+ list_for_each_entry(vif, &rwnx_hw->vifs, list) { -+ res = rwnx_send_set_power(rwnx_hw, vif->vif_index, pwr, NULL); -+ if (res) -+ break; -+ } -+ } -+ -+ return res; -+} -+ -+/** -+ * @set_power_mgmt: set the power save to one of those two modes: -+ * Power-save off -+ * Power-save on - Dynamic mode -+ */ -+static int rwnx_cfg80211_set_power_mgmt(struct wiphy *wiphy, -+ struct net_device *dev, -+ bool enabled, int timeout) -+{ -+#if 0 -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ u8 ps_mode; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ if (timeout >= 0) -+ netdev_info(dev, "Ignore timeout value %d", timeout); -+ -+ if (!(rwnx_hw->version_cfm.features & BIT(MM_FEAT_PS_BIT))) -+ enabled = false; -+ -+ if (enabled) { -+ /* Switch to Dynamic Power Save */ -+ ps_mode = MM_PS_MODE_ON_DYN; -+ } else { -+ /* Exit Power Save */ -+ ps_mode = MM_PS_MODE_OFF; -+ } -+ -+ return rwnx_send_me_set_ps_mode(rwnx_hw, ps_mode); -+#else -+ /* TODO -+ * Add handle in the feature! -+ */ -+ return 0; -+#endif -+} -+ -+static int rwnx_cfg80211_set_txq_params(struct wiphy *wiphy, struct net_device *dev, -+ struct ieee80211_txq_params *params) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ u8 hw_queue, aifs, cwmin, cwmax; -+ u32 param; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ hw_queue = rwnx_ac2hwq[0][params->ac]; -+ -+ aifs = params->aifs; -+ cwmin = fls(params->cwmin); -+ cwmax = fls(params->cwmax); -+ -+ /* Store queue information in general structure */ -+ param = (u32) (aifs << 0); -+ param |= (u32) (cwmin << 4); -+ param |= (u32) (cwmax << 8); -+ param |= (u32) (params->txop) << 12; -+ -+ /* Send the MM_SET_EDCA_REQ message to the FW */ -+ return rwnx_send_set_edca(rwnx_hw, hw_queue, param, false, rwnx_vif->vif_index); -+} -+ -+ -+/** -+ * @remain_on_channel: Request the driver to remain awake on the specified -+ * channel for the specified duration to complete an off-channel -+ * operation (e.g., public action frame exchange). When the driver is -+ * ready on the requested channel, it must indicate this with an event -+ * notification by calling cfg80211_ready_on_channel(). -+ */ -+static int -+rwnx_cfg80211_remain_on_channel_(struct wiphy *wiphy, struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie, bool mgmt_roc_flag) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ //struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev); -+ struct rwnx_vif *rwnx_vif = container_of(wdev, struct rwnx_vif, wdev); -+ struct rwnx_roc_elem *roc_elem; -+ struct mm_add_if_cfm add_if_cfm; -+ struct mm_remain_on_channel_cfm roc_cfm; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* For debug purpose (use ftrace kernel option) */ -+#ifdef CREATE_TRACE_POINTS -+ trace_roc(rwnx_vif->vif_index, chan->center_freq, duration); -+#endif -+ /* Check that no other RoC procedure has been launched */ -+ if (rwnx_hw->roc_elem) { -+ msleep(2); -+ if (rwnx_hw->roc_elem) { -+ printk("remain_on_channel fail\n"); -+ return -EBUSY; -+ } -+ } -+ -+ printk("remain:%d,%d,%d\n", rwnx_vif->vif_index, rwnx_vif->is_p2p_vif, rwnx_hw->is_p2p_alive); -+#ifdef CONFIG_USE_P2P0 -+ if (rwnx_vif->is_p2p_vif) { -+#else -+ if (rwnx_vif == rwnx_hw->p2p_dev_vif && !rwnx_vif->up) { -+#endif -+ if (!rwnx_hw->is_p2p_alive) { -+ error = rwnx_send_add_if (rwnx_hw, rwnx_vif->wdev.address, //wdev->netdev->dev_addr, -+ RWNX_VIF_TYPE(rwnx_vif), false, &add_if_cfm); -+ if (error) -+ return -EIO; -+ -+ if (add_if_cfm.status != 0) { -+ return -EIO; -+ } -+ -+ /* Save the index retrieved from LMAC */ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_vif->vif_index = add_if_cfm.inst_nbr; -+ rwnx_vif->up = true; -+ rwnx_hw->vif_started++; -+ rwnx_hw->vif_table[add_if_cfm.inst_nbr] = rwnx_vif; -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ rwnx_hw->is_p2p_alive = 1; -+#ifndef CONFIG_USE_P2P0 -+ mod_timer(&rwnx_hw->p2p_alive_timer, jiffies + msecs_to_jiffies(1000)); -+ atomic_set(&rwnx_hw->p2p_alive_timer_count, 0); -+#endif -+ } else { -+#ifndef CONFIG_USE_P2P0 -+ mod_timer(&rwnx_hw->p2p_alive_timer, jiffies + msecs_to_jiffies(1000)); -+ atomic_set(&rwnx_hw->p2p_alive_timer_count, 0); -+#endif -+ } -+ } -+ -+ /* Allocate a temporary RoC element */ -+ roc_elem = kmalloc(sizeof(struct rwnx_roc_elem), GFP_KERNEL); -+ -+ /* Verify that element has well been allocated */ -+ if (!roc_elem) { -+ return -ENOMEM; -+ } -+ -+ /* Initialize the RoC information element */ -+ roc_elem->wdev = wdev; -+ roc_elem->chan = chan; -+ roc_elem->duration = duration; -+ roc_elem->mgmt_roc = mgmt_roc_flag; -+ roc_elem->on_chan = false; -+ -+ /* Initialize the OFFCHAN TX queue to allow off-channel transmissions */ -+ rwnx_txq_offchan_init(rwnx_vif); -+ -+ /* Forward the information to the FMAC */ -+ rwnx_hw->roc_elem = roc_elem; -+ error = rwnx_send_roc(rwnx_hw, rwnx_vif, chan, duration, &roc_cfm); -+ -+ /* If no error, keep all the information for handling of end of procedure */ -+ if (error == 0) { -+ /* Set the cookie value */ -+ *cookie = (u64)(rwnx_hw->roc_cookie_cnt); -+ if (roc_cfm.status) { -+ // failed to roc -+ rwnx_hw->roc_elem = NULL; -+ kfree(roc_elem); -+ rwnx_txq_offchan_deinit(rwnx_vif); -+ return -EBUSY; -+ } -+ } else { -+ /* Free the allocated element */ -+ rwnx_hw->roc_elem = NULL; -+ kfree(roc_elem); -+ rwnx_txq_offchan_deinit(rwnx_vif); -+ } -+ -+ return error; -+} -+ -+ -+static int -+rwnx_cfg80211_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie) -+{ -+ return rwnx_cfg80211_remain_on_channel_(wiphy, wdev, chan, duration, cookie, false); -+} -+ -+/** -+ * @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation. -+ * This allows the operation to be terminated prior to timeout based on -+ * the duration value. -+ */ -+static int rwnx_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u64 cookie) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+#ifdef CREATE_TRACE_POINTS -+ struct rwnx_vif *rwnx_vif = container_of(wdev, struct rwnx_vif, wdev);//netdev_priv(wdev->netdev); -+#endif -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* For debug purpose (use ftrace kernel option) */ -+#ifdef CREATE_TRACE_POINTS -+ trace_cancel_roc(rwnx_vif->vif_index); -+#endif -+ /* Check if a RoC procedure is pending */ -+ if (!rwnx_hw->roc_elem) { -+ return 0; -+ } -+ -+ /* Forward the information to the FMAC */ -+ return rwnx_send_cancel_roc(rwnx_hw); -+} -+ -+#define IS_2P4GHZ(n) (n >= 2412 && n <= 2484) -+#define IS_5GHZ(n) (n >= 4000 && n <= 5895) -+#define DEFAULT_NOISE_FLOOR_2GHZ (-89) -+#define DEFAULT_NOISE_FLOOR_5GHZ (-92) -+ -+/** -+ * @dump_survey: get site survey information. -+ */ -+static int rwnx_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *netdev, -+ int idx, struct survey_info *info) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct ieee80211_supported_band *sband; -+ struct rwnx_survey_info *rwnx_survey; -+ -+ //RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (idx >= ARRAY_SIZE(rwnx_hw->survey)) -+ return -ENOENT; -+ -+ rwnx_survey = &rwnx_hw->survey[idx]; -+ -+ // Check if provided index matches with a supported 2.4GHz channel -+ sband = wiphy->bands[NL80211_BAND_2GHZ]; -+ if (sband && idx >= sband->n_channels) { -+ idx -= sband->n_channels; -+ sband = NULL; -+ } -+ -+ if (rwnx_hw->band_5g_support) { -+ if (!sband) { -+ // Check if provided index matches with a supported 5GHz channel -+ sband = wiphy->bands[NL80211_BAND_5GHZ]; -+ -+ if (!sband || idx >= sband->n_channels) -+ return -ENOENT; -+ } -+ } else { -+ if (!sband || idx >= sband->n_channels) -+ return -ENOENT; -+ } -+ -+ // Fill the survey -+ info->channel = &sband->channels[idx]; -+ info->filled = rwnx_survey->filled; -+ -+ if (rwnx_survey->filled != 0) { -+ SURVEY_TIME(info) = (u64)rwnx_survey->chan_time_ms; -+ SURVEY_TIME_BUSY(info) = (u64)rwnx_survey->chan_time_busy_ms; -+ //info->noise = rwnx_survey->noise_dbm; -+ info->noise = ((IS_2P4GHZ(info->channel->center_freq)) ? DEFAULT_NOISE_FLOOR_2GHZ : -+ (IS_5GHZ(info->channel->center_freq)) ? DEFAULT_NOISE_FLOOR_5GHZ : DEFAULT_NOISE_FLOOR_5GHZ); -+ -+ // Set the survey report as not used -+ if(info->noise == 0){ -+ rwnx_survey->filled = 0; -+ }else{ -+ rwnx_survey->filled |= SURVEY_INFO_NOISE_DBM; -+ } -+ -+ } -+ -+ return 0; -+} -+ -+/** -+ * @get_channel: Get the current operating channel for the virtual interface. -+ * For monitor interfaces, it should return %NULL unless there's a single -+ * current monitoring channel. -+ */ -+static int rwnx_cfg80211_get_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION -+ unsigned int link_id, -+#endif -+ struct cfg80211_chan_def *chandef) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = container_of(wdev, struct rwnx_vif, wdev); -+ struct rwnx_chanctx *ctxt; -+ -+ if (!rwnx_vif->up) { -+ return -ENODATA; -+ } -+ -+ if (rwnx_vif->vif_index == rwnx_hw->monitor_vif) { -+ //retrieve channel from firmware -+ rwnx_cfg80211_set_monitor_channel(wiphy, NULL); -+ } -+ -+ //Check if channel context is valid -+ if (!rwnx_chanctx_valid(rwnx_hw, rwnx_vif->ch_index)) { -+ return -ENODATA; -+ } -+ -+ ctxt = &rwnx_hw->chanctx_table[rwnx_vif->ch_index]; -+ *chandef = ctxt->chan_def; -+ -+ return 0; -+} -+ -+/** -+ * @mgmt_tx: Transmit a management frame. -+ */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie) -+#else -+static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, -+ struct ieee80211_channel *channel, bool offchan, -+ unsigned int wait, const u8 *buf, size_t len, -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) -+ bool no_cck, -+ #endif -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) -+ bool dont_wait_for_ack, -+ #endif -+ u64 *cookie) -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = container_of(wdev, struct rwnx_vif, wdev);//netdev_priv(wdev->netdev); -+ struct rwnx_sta *rwnx_sta; -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+ struct ieee80211_channel *channel = params->chan; -+ const u8 *buf = params->buf; -+ //size_t len = params->len; -+ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ -+ struct ieee80211_mgmt *mgmt = (void *)buf; -+ bool ap = false; -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+ bool offchan = false; -+ #endif -+ -+ /* Check if provided VIF is an AP or a STA one */ -+ switch (RWNX_VIF_TYPE(rwnx_vif)) { -+ case NL80211_IFTYPE_AP_VLAN: -+ rwnx_vif = rwnx_vif->ap_vlan.master; -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+ case NL80211_IFTYPE_MESH_POINT: -+ ap = true; -+ break; -+ case NL80211_IFTYPE_STATION: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ default: -+ break; -+ } -+ -+ /* Get STA on which management frame has to be sent */ -+ rwnx_sta = rwnx_retrieve_sta(rwnx_hw, rwnx_vif, mgmt->da, -+ mgmt->frame_control, ap); -+#ifdef CREATE_TRACE_POINTS -+ trace_mgmt_tx((channel) ? channel->center_freq : 0, -+ rwnx_vif->vif_index, (rwnx_sta) ? rwnx_sta->sta_idx : 0xFF, -+ mgmt); -+#endif -+ if (ap || rwnx_sta) -+ goto send_frame; -+ -+ /* Not an AP interface sending frame to unknown STA: -+ * This is allowed for external authetication */ -+ if (rwnx_vif->sta.external_auth && ieee80211_is_auth(mgmt->frame_control)) -+ goto send_frame; -+ -+ /* Otherwise ROC is needed */ -+ if (!channel) { -+ printk("mgmt_tx fail since channel\n"); -+ return -EINVAL; -+ } -+ -+ /* Check that a RoC is already pending */ -+ if (rwnx_hw->roc_elem) { -+ /* Get VIF used for current ROC */ -+ struct rwnx_vif *rwnx_roc_vif = container_of(rwnx_hw->roc_elem->wdev, struct rwnx_vif, wdev);//netdev_priv(rwnx_hw->roc_elem->wdev->netdev); -+ -+ /* Check if RoC channel is the same than the required one */ -+ if ((rwnx_hw->roc_elem->chan->center_freq != channel->center_freq) -+ || (rwnx_vif->vif_index != rwnx_roc_vif->vif_index)) { -+ printk("mgmt rx chan invalid: %d, %d", rwnx_hw->roc_elem->chan->center_freq, channel->center_freq); -+ return -EINVAL; -+ } -+ } else { -+ u64 cookie; -+ int error; -+ -+ printk("mgmt rx remain on chan\n"); -+ -+ /* Start a ROC procedure for 30ms */ -+ error = rwnx_cfg80211_remain_on_channel_(wiphy, wdev, channel, -+ 30, &cookie, true); -+ if (error) { -+ printk("mgmt rx chan err\n"); -+ return error; -+ } -+ /* Need to keep in mind that RoC has been launched internally in order to -+ * avoid to call the cfg80211 callback once expired */ -+ //rwnx_hw->roc_elem->mgmt_roc = true; -+ } -+ -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+ offchan = true; -+ #endif -+ -+send_frame: -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+ return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, params, offchan, cookie); -+ #else -+ return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, channel, offchan, wait, buf, len, no_cck, dont_wait_for_ack, cookie); -+ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ -+} -+ -+/** -+ * @start_radar_detection: Start radar detection in the driver. -+ */ -+static -+int rwnx_cfg80211_start_radar_detection(struct wiphy *wiphy, -+ struct net_device *dev, -+ struct cfg80211_chan_def *chandef -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) -+ , u32 cac_time_ms -+ #endif -+ ) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct apm_start_cac_cfm cfm; -+ -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) -+ rwnx_radar_start_cac(&rwnx_hw->radar, cac_time_ms, rwnx_vif); -+ #endif -+ rwnx_send_apm_start_cac_req(rwnx_hw, rwnx_vif, chandef, &cfm); -+ -+ if (cfm.status == CO_OK) { -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_chanctx_link(rwnx_vif, cfm.ch_idx, chandef); -+ if (rwnx_hw->cur_chanctx == rwnx_vif->ch_index) -+ rwnx_radar_detection_enable(&rwnx_hw->radar, -+ RWNX_RADAR_DETECT_REPORT, -+ RWNX_RADAR_RIU); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ } else { -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+/** -+ * @update_ft_ies: Provide updated Fast BSS Transition information to the -+ * driver. If the SME is in the driver/firmware, this information can be -+ * used in building Authentication and Reassociation Request frames. -+ */ -+static -+int rwnx_cfg80211_update_ft_ies(struct wiphy *wiphy, -+ struct net_device *dev, -+ struct cfg80211_update_ft_ies_params *ftie) -+{ -+ printk("%s\n", __func__); -+ return 0; -+} -+ -+/** -+ * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. -+ */ -+static -+int rwnx_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, -+ struct net_device *dev, -+ int32_t rssi_thold, uint32_t rssi_hyst) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ -+ return rwnx_send_cfg_rssi_req(rwnx_hw, rwnx_vif->vif_index, rssi_thold, rssi_hyst); -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+/** -+ * -+ * @channel_switch: initiate channel-switch procedure (with CSA). Driver is -+ * responsible for veryfing if the switch is possible. Since this is -+ * inherently tricky driver may decide to disconnect an interface later -+ * with cfg80211_stop_iface(). This doesn't mean driver can accept -+ * everything. It should do it's best to verify requests and reject them -+ * as soon as possible. -+ */ -+int rwnx_cfg80211_channel_switch (struct wiphy *wiphy, -+ struct net_device *dev, -+ struct cfg80211_csa_settings *params) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *vif = netdev_priv(dev); -+ struct rwnx_bcn *bcn, *bcn_after; -+ struct rwnx_csa *csa; -+ u16 csa_oft[BCN_MAX_CSA_CPT]; -+ u8 *buf; -+ int i, error = 0; -+ -+ -+ if (vif->ap.csa) -+ return -EBUSY; -+ -+ if (params->n_counter_offsets_beacon > BCN_MAX_CSA_CPT) -+ return -EINVAL; -+ -+ /* Build the new beacon with CSA IE */ -+ bcn = &vif->ap.bcn; -+ buf = rwnx_build_bcn(bcn, ¶ms->beacon_csa); -+ if (!buf) -+ return -ENOMEM; -+ -+ memset(csa_oft, 0, sizeof(csa_oft)); -+ for (i = 0; i < params->n_counter_offsets_beacon; i++) { -+ csa_oft[i] = params->counter_offsets_beacon[i] + bcn->head_len + -+ bcn->tim_len; -+ } -+ -+ /* If count is set to 0 (i.e anytime after this beacon) force it to 2 */ -+ if (params->count == 0) { -+ params->count = 2; -+ for (i = 0; i < params->n_counter_offsets_beacon; i++) { -+ buf[csa_oft[i]] = 2; -+ } -+ } -+ -+ error = rwnx_send_bcn(rwnx_hw, buf, vif->vif_index, bcn->len); -+ if (error) { -+ goto end; -+ } -+ -+ /* Build the beacon to use after CSA. It will only be sent to fw once -+ CSA is over, but do it before sending the beacon as it must be ready -+ when CSA is finished. */ -+ csa = kzalloc(sizeof(struct rwnx_csa), GFP_KERNEL); -+ if (!csa) { -+ error = -ENOMEM; -+ goto end; -+ } -+ -+ bcn_after = &csa->bcn; -+ buf = rwnx_build_bcn(bcn_after, ¶ms->beacon_after); -+ if (!buf) { -+ error = -ENOMEM; -+ rwnx_del_csa(vif); -+ goto end; -+ } -+ -+ error = rwnx_send_bcn(rwnx_hw, buf, vif->vif_index, bcn_after->len); -+ if (error) { -+ goto end; -+ } -+ -+ vif->ap.csa = csa; -+ csa->vif = vif; -+ csa->chandef = params->chandef; -+ -+ /* Send new Beacon. FW will extract channel and count from the beacon */ -+ error = rwnx_send_bcn_change(rwnx_hw, vif->vif_index, 0, -+ bcn->len, bcn->head_len, bcn->tim_len, csa_oft); -+ -+ if (error) { -+ rwnx_del_csa(vif); -+ goto end; -+ } else { -+ INIT_WORK(&csa->work, rwnx_csa_finish); -+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION4 -+ cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false, 0); -+#elif LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2 -+ cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false); -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) -+ cfg80211_ch_switch_started_notify(dev, &csa->chandef, params->count, params->block_tx); -+#else -+ cfg80211_ch_switch_started_notify(dev, &csa->chandef, params->count); -+#endif -+ -+ } -+ -+end: -+ return error; -+} -+#endif -+ -+ -+/* -+ * @tdls_mgmt: prepare TDLS action frame packets and forward them to FW -+ */ -+static int -+rwnx_cfg80211_tdls_mgmt(struct wiphy *wiphy, -+ struct net_device *dev, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+ const u8 *peer, -+#else -+ u8 *peer, -+#endif -+ u8 action_code, -+ u8 dialog_token, -+ u16 status_code, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0) -+ u32 peer_capability, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) -+ bool initiator, -+#endif -+ const u8 *buf, -+ size_t len) -+ -+{ -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0) -+ u32 peer_capability = 0; -+ #endif -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+ bool initiator = false; -+ #endif -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ int ret = 0; -+ -+ /* make sure we support TDLS */ -+ if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) -+ return -ENOTSUPP; -+ -+ /* make sure we are in station mode (and connected) */ -+ if ((RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_STATION) || -+ (!rwnx_vif->up) || (!rwnx_vif->sta.ap)) -+ return -ENOTSUPP; -+ -+ /* only one TDLS link is supported */ -+ if ((action_code == WLAN_TDLS_SETUP_REQUEST) && -+ (rwnx_vif->sta.tdls_sta) && -+ (rwnx_vif->tdls_status == TDLS_LINK_ACTIVE)) { -+ printk("%s: only one TDLS link is supported!\n", __func__); -+ return -ENOTSUPP; -+ } -+ -+ if ((action_code == WLAN_TDLS_DISCOVERY_REQUEST) && -+ (rwnx_hw->mod_params->ps_on)) { -+ printk("%s: discovery request is not supported when " -+ "power-save is enabled!\n", __func__); -+ return -ENOTSUPP; -+ } -+ -+ switch (action_code) { -+ case WLAN_TDLS_SETUP_RESPONSE: -+ /* only one TDLS link is supported */ -+ if ((status_code == 0) && -+ (rwnx_vif->sta.tdls_sta) && -+ (rwnx_vif->tdls_status == TDLS_LINK_ACTIVE)) { -+ printk("%s: only one TDLS link is supported!\n", __func__); -+ status_code = WLAN_STATUS_REQUEST_DECLINED; -+ } -+ /* fall-through */ -+ case WLAN_TDLS_SETUP_REQUEST: -+ case WLAN_TDLS_TEARDOWN: -+ case WLAN_TDLS_DISCOVERY_REQUEST: -+ case WLAN_TDLS_SETUP_CONFIRM: -+ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: -+ ret = rwnx_tdls_send_mgmt_packet_data(rwnx_hw, rwnx_vif, peer, action_code, -+ dialog_token, status_code, peer_capability, initiator, buf, len, 0, NULL); -+ break; -+ -+ default: -+ printk("%s: Unknown TDLS mgmt/action frame %pM\n", -+ __func__, peer); -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ -+ if (action_code == WLAN_TDLS_SETUP_REQUEST) { -+ rwnx_vif->tdls_status = TDLS_SETUP_REQ_TX; -+ } else if (action_code == WLAN_TDLS_SETUP_RESPONSE) { -+ rwnx_vif->tdls_status = TDLS_SETUP_RSP_TX; -+ } else if ((action_code == WLAN_TDLS_SETUP_CONFIRM) && (ret == CO_OK)) { -+ rwnx_vif->tdls_status = TDLS_LINK_ACTIVE; -+ /* Set TDLS active */ -+ rwnx_vif->sta.tdls_sta->tdls.active = true; -+ } -+ -+ return ret; -+} -+ -+/* -+ * @tdls_oper: execute TDLS operation -+ */ -+static int -+rwnx_cfg80211_tdls_oper(struct wiphy *wiphy, -+ struct net_device *dev, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+ const u8 *peer, -+#else -+ u8 *peer, -+#endif -+ enum nl80211_tdls_operation oper) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ int error; -+ -+ if (oper != NL80211_TDLS_DISABLE_LINK) -+ return 0; -+ -+ if (!rwnx_vif->sta.tdls_sta) { -+ printk("%s: TDLS station %pM does not exist\n", __func__, peer); -+ return -ENOLINK; -+ } -+ -+ if (memcmp(rwnx_vif->sta.tdls_sta->mac_addr, peer, ETH_ALEN) == 0) { -+ /* Disable Channel Switch */ -+ if (!rwnx_send_tdls_cancel_chan_switch_req(rwnx_hw, rwnx_vif, -+ rwnx_vif->sta.tdls_sta, -+ NULL)) -+ rwnx_vif->sta.tdls_sta->tdls.chsw_en = false; -+ -+ netdev_info(dev, "Del TDLS sta %d (%pM)", -+ rwnx_vif->sta.tdls_sta->sta_idx, -+ rwnx_vif->sta.tdls_sta->mac_addr); -+ /* Ensure that we won't process PS change ind */ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_vif->sta.tdls_sta->ps.active = false; -+ rwnx_vif->sta.tdls_sta->valid = false; -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ rwnx_txq_sta_deinit(rwnx_hw, rwnx_vif->sta.tdls_sta); -+ error = rwnx_send_me_sta_del(rwnx_hw, rwnx_vif->sta.tdls_sta->sta_idx, true); -+ if ((error != 0) && (error != -EPIPE)) -+ return error; -+ -+#ifdef CONFIG_RWNX_BFMER -+ // Disable Beamformer if supported -+ rwnx_bfmer_report_del(rwnx_hw, rwnx_vif->sta.tdls_sta); -+ rwnx_mu_group_sta_del(rwnx_hw, rwnx_vif->sta.tdls_sta); -+#endif /* CONFIG_RWNX_BFMER */ -+ -+ /* Set TDLS not active */ -+ rwnx_vif->sta.tdls_sta->tdls.active = false; -+#ifdef CONFIG_DEBUG_FS -+ rwnx_dbgfs_unregister_rc_stat(rwnx_hw, rwnx_vif->sta.tdls_sta); -+#endif -+ // Remove TDLS station -+ rwnx_vif->tdls_status = TDLS_LINK_IDLE; -+ rwnx_vif->sta.tdls_sta = NULL; -+ } -+ -+ return 0; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) -+/* -+ * @tdls_channel_switch: enable TDLS channel switch -+ */ -+static int -+rwnx_cfg80211_tdls_channel_switch (struct wiphy *wiphy, -+ struct net_device *dev, -+ const u8 *addr, u8 oper_class, -+ struct cfg80211_chan_def *chandef) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_sta *rwnx_sta = rwnx_vif->sta.tdls_sta; -+ struct tdls_chan_switch_cfm cfm; -+ int error; -+ -+ if ((!rwnx_sta) || (memcmp(addr, rwnx_sta->mac_addr, ETH_ALEN))) { -+ printk("%s: TDLS station %pM doesn't exist\n", __func__, addr); -+ return -ENOLINK; -+ } -+ -+ if (!rwnx_sta->tdls.chsw_allowed) { -+ printk("%s: TDLS station %pM does not support TDLS channel switch\n", __func__, addr); -+ return -ENOTSUPP; -+ } -+ -+ error = rwnx_send_tdls_chan_switch_req(rwnx_hw, rwnx_vif, rwnx_sta, -+ rwnx_sta->tdls.initiator, -+ oper_class, chandef, &cfm); -+ if (error) -+ return error; -+ -+ if (!cfm.status) { -+ rwnx_sta->tdls.chsw_en = true; -+ return 0; -+ } else { -+ printk("%s: TDLS channel switch already enabled and only one is supported\n", __func__); -+ return -EALREADY; -+ } -+} -+ -+/* -+ * @tdls_cancel_channel_switch: disable TDLS channel switch -+ */ -+static void -+rwnx_cfg80211_tdls_cancel_channel_switch (struct wiphy *wiphy, -+ struct net_device *dev, -+ const u8 *addr) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_sta *rwnx_sta = rwnx_vif->sta.tdls_sta; -+ struct tdls_cancel_chan_switch_cfm cfm; -+ -+ if (!rwnx_sta) -+ return; -+ -+ if (!rwnx_send_tdls_cancel_chan_switch_req(rwnx_hw, rwnx_vif, -+ rwnx_sta, &cfm)) -+ rwnx_sta->tdls.chsw_en = false; -+} -+#endif /* version >= 3.19 */ -+ -+/** -+ * @change_bss: Modify parameters for a given BSS (mainly for AP mode). -+ */ -+int rwnx_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, -+ struct bss_parameters *params) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ int res = -EOPNOTSUPP; -+ -+ if (((RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP) || -+ (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_GO)) && -+ (params->ap_isolate > -1)) { -+ -+ if (params->ap_isolate) -+ rwnx_vif->ap.flags |= RWNX_AP_ISOLATE; -+ else -+ rwnx_vif->ap.flags &= ~RWNX_AP_ISOLATE; -+ -+ res = 0; -+ } -+ -+ return res; -+} -+ -+static int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif, -+ struct station_info *sinfo) -+{ -+ struct rwnx_sta_stats *stats = &sta->stats; -+ struct rx_vector_1 *rx_vect1 = &stats->last_rx.rx_vect1; -+ union rwnx_rate_ctrl_info *rate_info; -+ struct mm_get_sta_info_cfm cfm; -+ -+ rwnx_send_get_sta_info_req(vif->rwnx_hw, sta->sta_idx, &cfm); -+ sinfo->tx_failed = cfm.txfailed; -+ rate_info = (union rwnx_rate_ctrl_info *)&cfm.rate_info; -+ -+ AICWFDBG(LOGDEBUG, "%s ModTx:%d TxIndex:%d ModRx:%d RxHTIndex:%d RxVHTIndex:%d RxHEIndex:%d RSSI:%d \r\n", __func__, -+ rate_info->formatModTx, rate_info->mcsIndexTx, rx_vect1->format_mod, -+ rx_vect1->ht.mcs, -+ rx_vect1->vht.mcs, -+ rx_vect1->he.mcs, -+ (s8)cfm.rssi); -+ -+ -+ switch (rate_info->formatModTx) { -+ case FORMATMOD_NON_HT: -+ case FORMATMOD_NON_HT_DUP_OFDM: -+ sinfo->txrate.flags = 0; -+ sinfo->txrate.legacy = tx_legrates_lut_rate[rate_info->mcsIndexTx]; -+ break; -+ case FORMATMOD_HT_MF: -+ case FORMATMOD_HT_GF: -+ sinfo->txrate.flags = RATE_INFO_FLAGS_MCS; -+ sinfo->txrate.mcs = rate_info->mcsIndexTx; -+ break; -+ case FORMATMOD_VHT: -+ sinfo->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; -+ sinfo->txrate.mcs = rate_info->mcsIndexTx; -+ break; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ case FORMATMOD_HE_MU: -+ case FORMATMOD_HE_SU: -+ case FORMATMOD_HE_ER: -+ sinfo->txrate.flags = RATE_INFO_FLAGS_HE_MCS; -+ sinfo->txrate.mcs = rate_info->mcsIndexTx; -+ break; -+#else -+ case FORMATMOD_HE_MU: -+ case FORMATMOD_HE_SU: -+ case FORMATMOD_HE_ER: -+ sinfo->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; -+ if(rate_info->mcsIndexTx > 9){ -+ sinfo->txrate.mcs = 9; -+ }else{ -+ sinfo->txrate.mcs = rate_info->mcsIndexTx; -+ } -+ break; -+#endif -+ default: -+ return -EINVAL; -+ } -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) -+ switch (rate_info->bwTx) { -+ case PHY_CHNL_BW_20: -+ sinfo->txrate.bw = RATE_INFO_BW_20; -+ break; -+ case PHY_CHNL_BW_40: -+ sinfo->txrate.bw = RATE_INFO_BW_40; -+ break; -+ case PHY_CHNL_BW_80: -+ sinfo->txrate.bw = RATE_INFO_BW_80; -+ break; -+ case PHY_CHNL_BW_160: -+ sinfo->txrate.bw = RATE_INFO_BW_160; -+ break; -+ default: -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ sinfo->txrate.bw = RATE_INFO_BW_HE_RU; -+#else -+ sinfo->txrate.bw = RATE_INFO_BW_20; -+#endif -+ break; -+ } -+#endif -+ -+ sinfo->txrate.nss = 1; -+ sinfo->filled |= (BIT(NL80211_STA_INFO_TX_BITRATE) | BIT(NL80211_STA_INFO_TX_FAILED)); -+ -+ sinfo->inactive_time = jiffies_to_msecs(jiffies - vif->rwnx_hw->stats.last_tx); -+ sinfo->rx_bytes = vif->net_stats.rx_bytes; -+ sinfo->tx_bytes = vif->net_stats.tx_bytes; -+ sinfo->tx_packets = vif->net_stats.tx_packets; -+ sinfo->rx_packets = vif->net_stats.rx_packets; -+ sinfo->signal = (s8)cfm.rssi; -+ sinfo->rxrate.nss = 1; -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) -+ switch (rx_vect1->ch_bw) { -+ case PHY_CHNL_BW_20: -+ sinfo->rxrate.bw = RATE_INFO_BW_20; -+ break; -+ case PHY_CHNL_BW_40: -+ sinfo->rxrate.bw = RATE_INFO_BW_40; -+ break; -+ case PHY_CHNL_BW_80: -+ sinfo->rxrate.bw = RATE_INFO_BW_80; -+ break; -+ case PHY_CHNL_BW_160: -+ sinfo->rxrate.bw = RATE_INFO_BW_160; -+ break; -+ default: -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ sinfo->rxrate.bw = RATE_INFO_BW_HE_RU; -+ #else -+ sinfo->rxrate.bw = RATE_INFO_BW_20; -+ #endif -+ break; -+ } -+ #endif -+ -+ switch (rx_vect1->format_mod) { -+ case FORMATMOD_NON_HT: -+ case FORMATMOD_NON_HT_DUP_OFDM: -+ sinfo->rxrate.flags = 0; -+ sinfo->rxrate.legacy = legrates_lut_rate[legrates_lut[rx_vect1->leg_rate]]; -+ break; -+ case FORMATMOD_HT_MF: -+ case FORMATMOD_HT_GF: -+ sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS; -+ if (rx_vect1->ht.short_gi) -+ sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; -+ sinfo->rxrate.mcs = rx_vect1->ht.mcs; -+ break; -+ case FORMATMOD_VHT: -+ sinfo->rxrate.flags = RATE_INFO_FLAGS_VHT_MCS; -+ if (rx_vect1->vht.short_gi) -+ sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; -+ sinfo->rxrate.mcs = rx_vect1->vht.mcs; -+ break; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ case FORMATMOD_HE_MU: -+ sinfo->rxrate.he_ru_alloc = rx_vect1->he.ru_size; -+ case FORMATMOD_HE_SU: -+ case FORMATMOD_HE_ER: -+ sinfo->rxrate.flags = RATE_INFO_FLAGS_HE_MCS; -+ sinfo->rxrate.mcs = rx_vect1->he.mcs; -+ sinfo->rxrate.he_gi = rx_vect1->he.gi_type; -+ sinfo->rxrate.he_dcm = rx_vect1->he.dcm; -+ break; -+#else -+ //kernel not support he -+ case FORMATMOD_HE_MU: -+ case FORMATMOD_HE_SU: -+ case FORMATMOD_HE_ER: -+ sinfo->rxrate.flags = RATE_INFO_FLAGS_VHT_MCS; -+ if(rx_vect1->he.mcs > 9){ -+ sinfo->rxrate.mcs = 9; -+ }else{ -+ sinfo->rxrate.mcs = rx_vect1->he.mcs; -+ } -+ break; -+#endif -+ default: -+ return -EINVAL; -+ } -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) -+ sinfo->filled |= (STATION_INFO_INACTIVE_TIME | -+ STATION_INFO_RX_BYTES64 | -+ STATION_INFO_TX_BYTES64 | -+ STATION_INFO_RX_PACKETS | -+ STATION_INFO_TX_PACKETS | -+ STATION_INFO_SIGNAL | -+ STATION_INFO_RX_BITRATE); -+#else -+ sinfo->filled |= (BIT(NL80211_STA_INFO_INACTIVE_TIME) | -+ BIT(NL80211_STA_INFO_RX_BYTES64) | -+ BIT(NL80211_STA_INFO_TX_BYTES64) | -+ BIT(NL80211_STA_INFO_RX_PACKETS) | -+ BIT(NL80211_STA_INFO_TX_PACKETS) | -+ BIT(NL80211_STA_INFO_SIGNAL) | -+ BIT(NL80211_STA_INFO_RX_BITRATE)); -+#endif -+ -+ return 0; -+} -+ -+ -+/** -+ * @get_station: get station information for the station identified by @mac -+ */ -+static int rwnx_cfg80211_get_station(struct wiphy *wiphy, -+ struct net_device *dev, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) -+ u8 *mac, -+#else -+ const u8 *mac, -+#endif -+ struct station_info *sinfo) -+{ -+ struct rwnx_vif *vif = netdev_priv(dev); -+ struct rwnx_sta *sta = NULL; -+ -+ if (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_MONITOR) -+ return -EINVAL; -+ else if ((RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_STATION) || -+ (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_P2P_CLIENT)) { -+ if (vif->sta.ap && ether_addr_equal(vif->sta.ap->mac_addr, mac)) -+ sta = vif->sta.ap; -+ } else { -+ struct rwnx_sta *sta_iter; -+ spin_lock_bh(&vif->rwnx_hw->cb_lock); -+ list_for_each_entry(sta_iter, &vif->ap.sta_list, list) { -+ if (sta_iter->valid && ether_addr_equal(sta_iter->mac_addr, mac)) { -+ sta = sta_iter; -+ break; -+ } -+ } -+ spin_unlock_bh(&vif->rwnx_hw->cb_lock); -+ } -+ -+ if (sta) -+ return rwnx_fill_station_info(sta, vif, sinfo); -+ -+ return -ENOENT; -+} -+ -+ -+/** -+ * @dump_station: dump station callback -- resume dump at index @idx -+ */ -+static int rwnx_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev, -+ int idx, u8 *mac, struct station_info *sinfo) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_sta *sta_iter, *sta = NULL; -+ struct mesh_peer_info_cfm peer_info_cfm; -+ int i = 0; -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) -+ return -ENOTSUPP; -+ -+ list_for_each_entry(sta_iter, &rwnx_vif->ap.sta_list, list) { -+ if (i < idx) { -+ i++; -+ continue; -+ } -+ -+ sta = sta_iter; -+ break; -+ } -+ -+ if (sta == NULL) -+ return -ENOENT; -+ -+ /* Forward the information to the UMAC */ -+ if (rwnx_send_mesh_peer_info_req(rwnx_hw, rwnx_vif, sta->sta_idx, -+ &peer_info_cfm)) -+ return -ENOMEM; -+ -+ /* Copy peer MAC address */ -+ memcpy(mac, &sta->mac_addr, ETH_ALEN); -+ -+ /* Fill station information */ -+ sinfo->llid = peer_info_cfm.local_link_id; -+ sinfo->plid = peer_info_cfm.peer_link_id; -+ sinfo->plink_state = peer_info_cfm.link_state; -+ sinfo->local_pm = peer_info_cfm.local_ps_mode; -+ sinfo->peer_pm = peer_info_cfm.peer_ps_mode; -+ sinfo->nonpeer_pm = peer_info_cfm.non_peer_ps_mode; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) -+ sinfo->filled = (STATION_INFO_LLID | -+ STATION_INFO_PLID | -+ STATION_INFO_PLINK_STATE | -+ STATION_INFO_LOCAL_PM | -+ STATION_INFO_PEER_PM | -+ STATION_INFO_NONPEER_PM); -+#else -+ sinfo->filled = (BIT(NL80211_STA_INFO_LLID) | -+ BIT(NL80211_STA_INFO_PLID) | -+ BIT(NL80211_STA_INFO_PLINK_STATE) | -+ BIT(NL80211_STA_INFO_LOCAL_PM) | -+ BIT(NL80211_STA_INFO_PEER_PM) | -+ BIT(NL80211_STA_INFO_NONPEER_PM)); -+#endif -+ -+ return 0; -+} -+ -+/** -+ * @add_mpath: add a fixed mesh path -+ */ -+static int rwnx_cfg80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) -+ u8 *dst, -+ u8 *next_hop -+#else -+ const u8 *dst, -+ const u8 *next_hop -+#endif -+) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct mesh_path_update_cfm cfm; -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) -+ return -ENOTSUPP; -+ -+ return rwnx_send_mesh_path_update_req(rwnx_hw, rwnx_vif, dst, next_hop, &cfm); -+} -+ -+/** -+ * @del_mpath: delete a given mesh path -+ */ -+static int rwnx_cfg80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) -+ u8 *dst -+#else -+ const u8 *dst -+#endif -+) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct mesh_path_update_cfm cfm; -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) -+ return -ENOTSUPP; -+ -+ return rwnx_send_mesh_path_update_req(rwnx_hw, rwnx_vif, dst, NULL, &cfm); -+} -+ -+/** -+ * @change_mpath: change a given mesh path -+ */ -+static int rwnx_cfg80211_change_mpath(struct wiphy *wiphy, struct net_device *dev, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) -+ u8 *dst, -+ u8 *next_hop -+#else -+ const u8 *dst, -+ const u8 *next_hop -+#endif -+) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct mesh_path_update_cfm cfm; -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) -+ return -ENOTSUPP; -+ -+ return rwnx_send_mesh_path_update_req(rwnx_hw, rwnx_vif, dst, next_hop, &cfm); -+} -+ -+/** -+ * @get_mpath: get a mesh path for the given parameters -+ */ -+static int rwnx_cfg80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, -+ u8 *dst, u8 *next_hop, struct mpath_info *pinfo) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_mesh_path *mesh_path = NULL; -+ struct rwnx_mesh_path *cur; -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) -+ return -ENOTSUPP; -+ -+ list_for_each_entry(cur, &rwnx_vif->ap.mpath_list, list) { -+ /* Compare the path target address and the provided destination address */ -+ if (memcmp(dst, &cur->tgt_mac_addr, ETH_ALEN)) { -+ continue; -+ } -+ -+ mesh_path = cur; -+ break; -+ } -+ -+ if (mesh_path == NULL) -+ return -ENOENT; -+ -+ /* Copy next HOP MAC address */ -+ if (mesh_path->p_nhop_sta) -+ memcpy(next_hop, &mesh_path->p_nhop_sta->mac_addr, ETH_ALEN); -+ -+ /* Fill path information */ -+ pinfo->filled = 0; -+ pinfo->generation = rwnx_vif->ap.generation; -+ -+ return 0; -+} -+ -+/** -+ * @dump_mpath: dump mesh path callback -- resume dump at index @idx -+ */ -+static int rwnx_cfg80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, -+ int idx, u8 *dst, u8 *next_hop, -+ struct mpath_info *pinfo) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_mesh_path *mesh_path = NULL; -+ struct rwnx_mesh_path *cur; -+ int i = 0; -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) -+ return -ENOTSUPP; -+ -+ list_for_each_entry(cur, &rwnx_vif->ap.mpath_list, list) { -+ if (i < idx) { -+ i++; -+ continue; -+ } -+ -+ mesh_path = cur; -+ break; -+ } -+ -+ if (mesh_path == NULL) -+ return -ENOENT; -+ -+ /* Copy target and next hop MAC address */ -+ memcpy(dst, &mesh_path->tgt_mac_addr, ETH_ALEN); -+ if (mesh_path->p_nhop_sta) -+ memcpy(next_hop, &mesh_path->p_nhop_sta->mac_addr, ETH_ALEN); -+ -+ /* Fill path information */ -+ pinfo->filled = 0; -+ pinfo->generation = rwnx_vif->ap.generation; -+ -+ return 0; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) -+/** -+ * @get_mpp: get a mesh proxy path for the given parameters -+ */ -+static int rwnx_cfg80211_get_mpp(struct wiphy *wiphy, struct net_device *dev, -+ u8 *dst, u8 *mpp, struct mpath_info *pinfo) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_mesh_proxy *mesh_proxy = NULL; -+ struct rwnx_mesh_proxy *cur; -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) -+ return -ENOTSUPP; -+ -+ list_for_each_entry(cur, &rwnx_vif->ap.proxy_list, list) { -+ if (cur->local) { -+ continue; -+ } -+ -+ /* Compare the path target address and the provided destination address */ -+ if (memcmp(dst, &cur->ext_sta_addr, ETH_ALEN)) { -+ continue; -+ } -+ -+ mesh_proxy = cur; -+ break; -+ } -+ -+ if (mesh_proxy == NULL) -+ return -ENOENT; -+ -+ memcpy(mpp, &mesh_proxy->proxy_addr, ETH_ALEN); -+ -+ /* Fill path information */ -+ pinfo->filled = 0; -+ pinfo->generation = rwnx_vif->ap.generation; -+ -+ return 0; -+} -+ -+/** -+ * @dump_mpp: dump mesh proxy path callback -- resume dump at index @idx -+ */ -+static int rwnx_cfg80211_dump_mpp(struct wiphy *wiphy, struct net_device *dev, -+ int idx, u8 *dst, u8 *mpp, struct mpath_info *pinfo) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_mesh_proxy *mesh_proxy = NULL; -+ struct rwnx_mesh_proxy *cur; -+ int i = 0; -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) -+ return -ENOTSUPP; -+ -+ list_for_each_entry(cur, &rwnx_vif->ap.proxy_list, list) { -+ if (cur->local) { -+ continue; -+ } -+ -+ if (i < idx) { -+ i++; -+ continue; -+ } -+ -+ mesh_proxy = cur; -+ break; -+ } -+ -+ if (mesh_proxy == NULL) -+ return -ENOENT; -+ -+ /* Copy target MAC address */ -+ memcpy(dst, &mesh_proxy->ext_sta_addr, ETH_ALEN); -+ memcpy(mpp, &mesh_proxy->proxy_addr, ETH_ALEN); -+ -+ /* Fill path information */ -+ pinfo->filled = 0; -+ pinfo->generation = rwnx_vif->ap.generation; -+ -+ return 0; -+} -+#endif /* version >= 3.19 */ -+ -+/** -+ * @get_mesh_config: Get the current mesh configuration -+ */ -+static int rwnx_cfg80211_get_mesh_config(struct wiphy *wiphy, struct net_device *dev, -+ struct mesh_config *conf) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) -+ return -ENOTSUPP; -+ -+ return 0; -+} -+ -+/** -+ * @update_mesh_config: Update mesh parameters on a running mesh. -+ */ -+static int rwnx_cfg80211_update_mesh_config(struct wiphy *wiphy, struct net_device *dev, -+ u32 mask, const struct mesh_config *nconf) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct mesh_update_cfm cfm; -+ int status; -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) -+ return -ENOTSUPP; -+ -+ if (mask & CO_BIT(NL80211_MESHCONF_POWER_MODE - 1)) { -+ rwnx_vif->ap.next_mesh_pm = nconf->power_mode; -+ -+ if (!list_empty(&rwnx_vif->ap.sta_list)) { -+ // If there are mesh links we don't want to update the power mode -+ // It will be updated with rwnx_update_mesh_power_mode() when the -+ // ps mode of a link is updated or when a new link is added/removed -+ mask &= ~BIT(NL80211_MESHCONF_POWER_MODE - 1); -+ -+ if (!mask) -+ return 0; -+ } -+ } -+ -+ status = rwnx_send_mesh_update_req(rwnx_hw, rwnx_vif, mask, nconf, &cfm); -+ -+ if (!status && (cfm.status != 0)) -+ status = -EINVAL; -+ -+ return status; -+} -+ -+/** -+ * @join_mesh: join the mesh network with the specified parameters -+ * (invoked with the wireless_dev mutex held) -+ */ -+static int rwnx_cfg80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, -+ const struct mesh_config *conf, const struct mesh_setup *setup) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct mesh_start_cfm mesh_start_cfm; -+ int error = 0; -+ u8 txq_status = 0; -+ /* STA for BC/MC traffic */ -+ struct rwnx_sta *sta; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) -+ return -ENOTSUPP; -+ -+ /* Forward the information to the UMAC */ -+ error = rwnx_send_mesh_start_req(rwnx_hw, rwnx_vif, conf, setup, &mesh_start_cfm); -+ if (error) { -+ return error; -+ } -+ -+ /* Check the status */ -+ switch (mesh_start_cfm.status) { -+ case CO_OK: -+ rwnx_vif->ap.bcmc_index = mesh_start_cfm.bcmc_idx; -+ rwnx_vif->ap.flags = 0; -+ rwnx_vif->use_4addr = true; -+ rwnx_vif->user_mpm = setup->user_mpm; -+ -+ sta = &rwnx_hw->sta_table[mesh_start_cfm.bcmc_idx]; -+ sta->valid = true; -+ sta->aid = 0; -+ sta->sta_idx = mesh_start_cfm.bcmc_idx; -+ sta->ch_idx = mesh_start_cfm.ch_idx; -+ sta->vif_idx = rwnx_vif->vif_index; -+ sta->qos = true; -+ sta->acm = 0; -+ sta->ps.active = false; -+ rwnx_mu_group_sta_init(sta, NULL); -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_chanctx_link(rwnx_vif, mesh_start_cfm.ch_idx, -+ (struct cfg80211_chan_def *)(&setup->chandef)); -+ if (rwnx_hw->cur_chanctx != mesh_start_cfm.ch_idx) { -+ txq_status = RWNX_TXQ_STOP_CHAN; -+ } -+ rwnx_txq_vif_init(rwnx_hw, rwnx_vif, txq_status); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ -+ netif_tx_start_all_queues(dev); -+ netif_carrier_on(dev); -+ -+ /* If the AP channel is already the active, we probably skip radar -+ activation on MM_CHANNEL_SWITCH_IND (unless another vif use this -+ ctxt). In anycase retest if radar detection must be activated -+ */ -+ if (rwnx_hw->cur_chanctx == mesh_start_cfm.ch_idx) { -+ rwnx_radar_detection_enable_on_cur_channel(rwnx_hw); -+ } -+ break; -+ -+ case CO_BUSY: -+ error = -EINPROGRESS; -+ break; -+ -+ default: -+ error = -EIO; -+ break; -+ } -+ -+ /* Print information about the operation */ -+ if (error) { -+ netdev_info(dev, "Failed to start MP (%d)", error); -+ } else { -+ netdev_info(dev, "MP started: ch=%d, bcmc_idx=%d", -+ rwnx_vif->ch_index, rwnx_vif->ap.bcmc_index); -+ } -+ -+ return error; -+} -+ -+/** -+ * @leave_mesh: leave the current mesh network -+ * (invoked with the wireless_dev mutex held) -+ */ -+static int rwnx_cfg80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct mesh_stop_cfm mesh_stop_cfm; -+ int error = 0; -+ -+ error = rwnx_send_mesh_stop_req(rwnx_hw, rwnx_vif, &mesh_stop_cfm); -+ -+ if (error == 0) { -+ /* Check the status */ -+ switch (mesh_stop_cfm.status) { -+ case CO_OK: -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_chanctx_unlink(rwnx_vif); -+ rwnx_radar_cancel_cac(&rwnx_hw->radar); -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ /* delete BC/MC STA */ -+ rwnx_txq_vif_deinit(rwnx_hw, rwnx_vif); -+ rwnx_del_bcn(&rwnx_vif->ap.bcn); -+ -+ netif_tx_stop_all_queues(dev); -+ netif_carrier_off(dev); -+ -+ break; -+ -+ default: -+ error = -EIO; -+ break; -+ } -+ } -+ -+ if (error) { -+ netdev_info(dev, "Failed to stop MP"); -+ } else { -+ netdev_info(dev, "MP Stopped"); -+ } -+ -+ return 0; -+} -+ -+static struct cfg80211_ops rwnx_cfg80211_ops = { -+ .add_virtual_intf = rwnx_cfg80211_add_iface, -+ .del_virtual_intf = rwnx_cfg80211_del_iface, -+ .change_virtual_intf = rwnx_cfg80211_change_iface, -+ .start_p2p_device = rwnx_cfgp2p_start_p2p_device, -+ .stop_p2p_device = rwnx_cfgp2p_stop_p2p_device, -+ .scan = rwnx_cfg80211_scan, -+ .connect = rwnx_cfg80211_connect, -+ .disconnect = rwnx_cfg80211_disconnect, -+ .add_key = rwnx_cfg80211_add_key, -+ .get_key = rwnx_cfg80211_get_key, -+ .del_key = rwnx_cfg80211_del_key, -+ .set_default_key = rwnx_cfg80211_set_default_key, -+ .set_default_mgmt_key = rwnx_cfg80211_set_default_mgmt_key, -+ .add_station = rwnx_cfg80211_add_station, -+ .del_station = rwnx_cfg80211_del_station_compat, -+ .change_station = rwnx_cfg80211_change_station, -+ .mgmt_tx = rwnx_cfg80211_mgmt_tx, -+ .start_ap = rwnx_cfg80211_start_ap, -+ .change_beacon = rwnx_cfg80211_change_beacon, -+ .stop_ap = rwnx_cfg80211_stop_ap, -+ .set_monitor_channel = rwnx_cfg80211_set_monitor_channel, -+ .probe_client = rwnx_cfg80211_probe_client, -+// .mgmt_frame_register = rwnx_cfg80211_mgmt_frame_register, -+ .set_wiphy_params = rwnx_cfg80211_set_wiphy_params, -+ .set_txq_params = rwnx_cfg80211_set_txq_params, -+ .set_tx_power = rwnx_cfg80211_set_tx_power, -+// .get_tx_power = rwnx_cfg80211_get_tx_power, -+ .set_power_mgmt = rwnx_cfg80211_set_power_mgmt, -+ .get_station = rwnx_cfg80211_get_station, -+ .remain_on_channel = rwnx_cfg80211_remain_on_channel, -+ .cancel_remain_on_channel = rwnx_cfg80211_cancel_remain_on_channel, -+ .dump_survey = rwnx_cfg80211_dump_survey, -+ .get_channel = rwnx_cfg80211_get_channel, -+ .start_radar_detection = rwnx_cfg80211_start_radar_detection, -+ .update_ft_ies = rwnx_cfg80211_update_ft_ies, -+ .set_cqm_rssi_config = rwnx_cfg80211_set_cqm_rssi_config, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+ .channel_switch = rwnx_cfg80211_channel_switch, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) -+ .tdls_channel_switch = rwnx_cfg80211_tdls_channel_switch, -+ .tdls_cancel_channel_switch = rwnx_cfg80211_tdls_cancel_channel_switch, -+#endif -+ .tdls_mgmt = rwnx_cfg80211_tdls_mgmt, -+ .tdls_oper = rwnx_cfg80211_tdls_oper, -+ .change_bss = rwnx_cfg80211_change_bss, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL) -+ .external_auth = rwnx_cfg80211_external_auth, -+#endif -+#ifdef CONFIG_SCHED_SCAN -+ .sched_scan_start = rwnx_cfg80211_sched_scan_start, -+ .sched_scan_stop = rwnx_cfg80211_sched_scan_stop, -+#endif -+}; -+ -+ -+/********************************************************************* -+ * Init/Exit functions -+ *********************************************************************/ -+static void rwnx_wdev_unregister(struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_vif *rwnx_vif, *tmp; -+ -+ rtnl_lock(); -+ list_for_each_entry_safe(rwnx_vif, tmp, &rwnx_hw->vifs, list) { -+ rwnx_cfg80211_del_iface(rwnx_hw->wiphy, &rwnx_vif->wdev); -+ } -+ rtnl_unlock(); -+} -+ -+static void rwnx_set_vers(struct rwnx_hw *rwnx_hw) -+{ -+ u32 vers = rwnx_hw->version_cfm.version_lmac; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ snprintf(rwnx_hw->wiphy->fw_version, -+ sizeof(rwnx_hw->wiphy->fw_version), "%d.%d.%d.%d", -+ (vers & (0xff << 24)) >> 24, (vers & (0xff << 16)) >> 16, -+ (vers & (0xff << 8)) >> 8, (vers & (0xff << 0)) >> 0); -+} -+ -+static void rwnx_reg_notifier(struct wiphy *wiphy, -+ struct regulatory_request *request) -+{ -+ struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); -+ -+ // For now trust all initiator -+ rwnx_radar_set_domain(&rwnx_hw->radar, request->dfs_region); -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801 || -+ ((rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC|| -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW || -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80) && testmode == 0)){ -+ rwnx_send_me_chan_config_req(rwnx_hw); -+ } -+} -+ -+static void rwnx_enable_mesh(struct rwnx_hw *rwnx_hw) -+{ -+ struct wiphy *wiphy = rwnx_hw->wiphy; -+ -+ if (!rwnx_mod_params.mesh) -+ return; -+ -+ rwnx_cfg80211_ops.get_station = rwnx_cfg80211_get_station; -+ rwnx_cfg80211_ops.dump_station = rwnx_cfg80211_dump_station; -+ rwnx_cfg80211_ops.add_mpath = rwnx_cfg80211_add_mpath; -+ rwnx_cfg80211_ops.del_mpath = rwnx_cfg80211_del_mpath; -+ rwnx_cfg80211_ops.change_mpath = rwnx_cfg80211_change_mpath; -+ rwnx_cfg80211_ops.get_mpath = rwnx_cfg80211_get_mpath; -+ rwnx_cfg80211_ops.dump_mpath = rwnx_cfg80211_dump_mpath; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) -+ rwnx_cfg80211_ops.get_mpp = rwnx_cfg80211_get_mpp; -+ rwnx_cfg80211_ops.dump_mpp = rwnx_cfg80211_dump_mpp; -+#endif -+ rwnx_cfg80211_ops.get_mesh_config = rwnx_cfg80211_get_mesh_config; -+ rwnx_cfg80211_ops.update_mesh_config = rwnx_cfg80211_update_mesh_config; -+ rwnx_cfg80211_ops.join_mesh = rwnx_cfg80211_join_mesh; -+ rwnx_cfg80211_ops.leave_mesh = rwnx_cfg80211_leave_mesh; -+ -+ wiphy->flags |= (WIPHY_FLAG_MESH_AUTH | WIPHY_FLAG_IBSS_RSN); -+ wiphy->features |= NL80211_FEATURE_USERSPACE_MPM; -+ wiphy->interface_modes |= BIT(NL80211_IFTYPE_MESH_POINT); -+ -+ rwnx_limits[0].types |= BIT(NL80211_IFTYPE_MESH_POINT); -+ rwnx_limits_dfs[0].types |= BIT(NL80211_IFTYPE_MESH_POINT); -+} -+ -+extern int rwnx_init_aic(struct rwnx_hw *rwnx_hw); -+ -+#if IS_ENABLED(CONFIG_SUNXI_ADDR_MGT) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) -+extern int get_custom_mac_address(int fmt, char *name, char *addr); -+#else -+extern int get_wifi_custom_mac_address(char *addr_str); -+#endif -+#endif -+#if IS_ENABLED(CONFIG_PM) -+static const struct wiphy_wowlan_support aic_wowlan_support = { -+ .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_MAGIC_PKT, -+}; -+#endif -+/** -+ * -+ */ -+extern int aicwf_vendor_init(struct wiphy *wiphy); -+extern txpwr_idx_conf_t nvram_txpwr_idx; -+ -+ -+int rwnx_ic_system_init(struct rwnx_hw *rwnx_hw){ -+ u32 mem_addr; -+ struct dbg_mem_read_cfm rd_mem_addr_cfm; -+ -+ mem_addr = 0x40500000; -+ -+// if(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+// rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ if (rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm)){ -+ return -1; -+ } -+ -+ chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16); -+ -+ if (rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm)) { -+ AICWFDBG(LOGERROR, "[0x00000020] rd fail\n"); -+ return -1; -+ } -+ chip_sub_id = (u8)(rd_mem_addr_cfm.memdata); -+ -+ AICWFDBG(LOGINFO, "FDRV chip_id=%x, chip_sub_id=%x!!\n", chip_id, chip_sub_id); -+ -+#ifdef CONFIG_OOB -+ if(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80) { -+ u32 memdata_temp = 0x00000006; -+ int ret; -+ ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, 0x40504084, 4, &memdata_temp); -+ if (ret) { -+ AICWFDBG(LOGERROR, "[0x40504084] write fail: %d\n", ret); -+ return -1; -+ } -+ -+ ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x40504084, &rd_mem_addr_cfm); -+ if (ret) { -+ AICWFDBG(LOGERROR, "[0x40504084] rd fail\n"); -+ return -1; -+ } -+ AICWFDBG(LOGINFO, "rd [0x40504084] = %x\n", rd_mem_addr_cfm.memdata); -+ } -+#endif -+ -+ if (rwnx_platform_on(rwnx_hw, NULL)) -+ return -1; -+#if defined(CONFIG_START_FROM_BOOTROM) -+ //if (start_from_bootrom(rwnx_hw)) -+ // return -1; -+#endif -+// } -+ return 0; -+} -+ -+int rwnx_ic_rf_init(struct rwnx_hw *rwnx_hw){ -+ struct mm_set_rf_calib_cfm cfm; -+ int ret = 0; -+ -+ if(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801){ -+ if ((ret = rwnx_send_txpwr_idx_req(rwnx_hw))) { -+ return -1; -+ } -+ -+ if ((ret = rwnx_send_txpwr_ofst_req(rwnx_hw))) { -+ return -1; -+ } -+ -+ if (testmode == 0) { -+ if ((ret = rwnx_send_rf_calib_req(rwnx_hw, &cfm))) -+ return -1; -+ } -+ -+ }else if(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ -+ if ((ret = aicwf_set_rf_config_8800dc(rwnx_hw, &cfm))) -+ return -1; -+ -+ -+ }else if(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ if ((ret = aicwf_set_rf_config_8800d80(rwnx_hw, &cfm))) -+ return -1; -+ } -+ return 0; -+} -+ -+ -+#ifdef CONFIG_PLATFORM_ALLWINNER -+#ifdef CONFIG_USE_CUSTOMER_MAC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) -+extern int get_custom_mac_address(int fmt, char *name, char *addr); -+#else -+extern int get_wifi_custom_mac_address(char *addr_str); -+#endif -+#endif//CONFIG_USE_CUSTOMER_MAC -+#endif//CONFIG_PLATFORM_ALLWINNER -+ -+#ifdef CONFIG_PLATFORM_ROCKCHIP -+#include -+#endif -+#ifdef CONFIG_PLATFORM_ROCKCHIP2 -+#include -+#endif -+ -+#ifdef CONFIG_USE_CUSTOMER_MAC -+int rwnx_get_custom_mac_addr(u8_l *mac_addr_efuse){ -+ int ret = 0; -+ -+#ifdef CONFIG_PLATFORM_ALLWINNER -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) -+ ret = get_custom_mac_address(1, "wifi", mac_addr_efuse); -+#else -+ ret = get_wifi_custom_mac_address(addr_str); -+ if (ret >= 0) { -+ sscanf(addr_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", -+ &mac_addr_efuse[0], &mac_addr_efuse[1], &mac_addr_efuse[2], -+ &mac_addr_efuse[3], &mac_addr_efuse[4], &mac_addr_efuse[5]); -+ } -+#endif -+ -+#endif//CONFIG_PLATFORM_ALLWINNER -+ -+#ifdef CONFIG_PLATFORM_ROCKCHIP -+ ret = rockchip_wifi_mac_addr(mac_addr_efuse); -+#endif//CONFIG_PLATFORM_ROCKCHIP -+#ifdef CONFIG_PLATFORM_ROCKCHIP2 -+ ret = rockchip_wifi_mac_addr(mac_addr_efuse); -+#endif//CONFIG_PLATFORM_ROCKCHIP -+ -+ if(ret == 0){ -+ AICWFDBG(LOGINFO, "%s %02x:%02x:%02x:%02x:%02x:%02x", __func__, -+ mac_addr_efuse[0], mac_addr_efuse[1], mac_addr_efuse[2], -+ mac_addr_efuse[3], mac_addr_efuse[4], mac_addr_efuse[5]); -+ } -+ -+ return ret; -+} -+#endif -+ -+extern void *aicwf_prealloc_txq_alloc(size_t size); -+int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data) -+{ -+ struct rwnx_hw *rwnx_hw; -+ struct rwnx_conf_file init_conf; -+ int ret = 0; -+ struct wiphy *wiphy; -+ struct rwnx_vif *vif; -+ int i; -+ u8 dflt_mac[ETH_ALEN] = { 0x88, 0x00, 0x33, 0x77, 0x10, 0x99}; -+ u8 addr_str[20]; -+ //struct mm_set_rf_calib_cfm cfm; -+ struct mm_get_fw_version_cfm fw_version; -+ u8_l mac_addr_efuse[ETH_ALEN]; -+ struct aicbsp_feature_t feature; -+ struct mm_set_stack_start_cfm set_start_cfm; -+#ifdef CONFIG_TEMP_COMP -+ struct mm_set_vendor_swconfig_cfm swconfig_cfm; -+#endif -+ char fw_path[200]; -+ (void)addr_str; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ memset(fw_path, 0, 200); -+ aicbsp_get_feature(&feature, fw_path); -+ -+ get_random_bytes(&dflt_mac[4], 2); -+ -+ /* create a new wiphy for use with cfg80211 */ -+ AICWFDBG(LOGINFO, "%s sizeof(struct rwnx_hw):%d \r\n", __func__, (int)sizeof(struct rwnx_hw)); -+ wiphy = wiphy_new(&rwnx_cfg80211_ops, sizeof(struct rwnx_hw)); -+ -+ if (!wiphy) { -+ dev_err(rwnx_platform_get_dev(rwnx_plat), "Failed to create new wiphy\n"); -+ ret = -ENOMEM; -+ goto err_out; -+ } -+ -+ rwnx_hw = wiphy_priv(wiphy); -+ rwnx_hw->wiphy = wiphy; -+ rwnx_hw->plat = rwnx_plat; -+ rwnx_hw->dev = rwnx_platform_get_dev(rwnx_plat); -+#ifdef AICWF_SDIO_SUPPORT -+ rwnx_hw->sdiodev = rwnx_plat->sdiodev; -+ rwnx_plat->sdiodev->rwnx_hw = rwnx_hw; -+ rwnx_hw->cmd_mgr = &rwnx_plat->sdiodev->cmd_mgr; -+#else -+ rwnx_hw->usbdev = rwnx_plat->usbdev; -+ rwnx_plat->usbdev->rwnx_hw = rwnx_hw; -+ rwnx_hw->cmd_mgr = &rwnx_plat->usbdev->cmd_mgr; -+#endif -+ rwnx_hw->mod_params = &rwnx_mod_params; -+ rwnx_hw->tcp_pacing_shift = 7; -+ -+#ifdef CONFIG_SCHED_SCAN -+ rwnx_hw->is_sched_scan = false; -+#endif//CONFIG_SCHED_SCAN -+ -+ aicwf_wakeup_lock_init(rwnx_hw); -+ rwnx_init_aic(rwnx_hw); -+ /* set device pointer for wiphy */ -+ set_wiphy_dev(wiphy, rwnx_hw->dev); -+ -+ /* Create cache to allocate sw_txhdr */ -+ rwnx_hw->sw_txhdr_cache = KMEM_CACHE(rwnx_sw_txhdr, 0); -+ if (!rwnx_hw->sw_txhdr_cache) { -+ wiphy_err(wiphy, "Cannot allocate cache for sw TX header\n"); -+ ret = -ENOMEM; -+ goto err_cache; -+ } -+ -+#ifdef CONFIG_FILTER_TCP_ACK -+ tcp_ack_init(rwnx_hw); -+#endif -+ -+#if 0 -+ ret = rwnx_parse_configfile(rwnx_hw, RWNX_CONFIG_FW_NAME, &init_conf); -+ if (ret) { -+ wiphy_err(wiphy, "rwnx_parse_configfile failed\n"); -+ goto err_config; -+ } -+#else -+ memcpy(init_conf.mac_addr, dflt_mac, ETH_ALEN); -+#endif -+ -+ rwnx_hw->vif_started = 0; -+ rwnx_hw->monitor_vif = RWNX_INVALID_VIF; -+ rwnx_hw->adding_sta = false; -+ -+ rwnx_hw->scan_ie.addr = NULL; -+ -+ for (i = 0; i < NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX; i++) -+ rwnx_hw->avail_idx_map |= BIT(i); -+ -+ rwnx_hwq_init(rwnx_hw); -+ -+#ifdef CONFIG_PREALLOC_TXQ -+ rwnx_hw->txq = (struct rwnx_txq*)aicwf_prealloc_txq_alloc(sizeof(struct rwnx_txq)*NX_NB_TXQ); -+#endif -+ -+ for (i = 0; i < NX_NB_TXQ; i++) { -+ rwnx_hw->txq[i].idx = TXQ_INACTIVE; -+ } -+ -+ rwnx_mu_group_init(rwnx_hw); -+ -+ /* Initialize RoC element pointer to NULL, indicate that RoC can be started */ -+ rwnx_hw->roc_elem = NULL; -+ /* Cookie can not be 0 */ -+ rwnx_hw->roc_cookie_cnt = 1; -+ -+ INIT_LIST_HEAD(&rwnx_hw->vifs); -+ INIT_LIST_HEAD(&rwnx_hw->defrag_list); -+ spin_lock_init(&rwnx_hw->defrag_lock); -+ mutex_init(&rwnx_hw->mutex); -+ mutex_init(&rwnx_hw->dbgdump_elem.mutex); -+ spin_lock_init(&rwnx_hw->tx_lock); -+ spin_lock_init(&rwnx_hw->cb_lock); -+ -+ INIT_WORK(&rwnx_hw->apmStalossWork, apm_staloss_work_process); -+ rwnx_hw->apmStaloss_wq = create_singlethread_workqueue("apmStaloss_wq"); -+ if (!rwnx_hw->apmStaloss_wq) { -+ txrx_err("insufficient memory to create apmStaloss workqueue.\n"); -+ goto err_cache; -+ } -+ -+ wiphy->mgmt_stypes = rwnx_default_mgmt_stypes; -+ rwnx_hw->fwlog_en = feature.fwlog_en; -+ -+ -+ //init ic system -+ if((ret = rwnx_ic_system_init(rwnx_hw))){ -+ goto err_lmac_reqs; -+ } -+ -+ //ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, feature.hwinfo < 0, feature.hwinfo, 0, &set_start_cfm); -+#ifdef USE_5G -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801) { -+ ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, 0, CO_BIT(5), 0, &set_start_cfm); -+ } -+#else -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801) { -+ ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, 0, 0, 0, &set_start_cfm); -+ } -+#endif -+ else if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, 0, 0, 0, &set_start_cfm); -+ set_start_cfm.is_5g_support = false; -+ } else { -+ ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, 0, CO_BIT(5), 0, &set_start_cfm); -+ } -+ -+ if (ret) -+ goto err_lmac_reqs; -+ -+ AICWFDBG(LOGINFO, "is 5g support = %d, vendor_info = 0x%02X\n", set_start_cfm.is_5g_support, set_start_cfm.vendor_info); -+ rwnx_hw->band_5g_support = set_start_cfm.is_5g_support; -+ rwnx_hw->vendor_info = (feature.hwinfo < 0) ? set_start_cfm.vendor_info : feature.hwinfo; -+ -+ ret = rwnx_send_get_fw_version_req(rwnx_hw, &fw_version); -+ memcpy(wiphy->fw_version, fw_version.fw_version, fw_version.fw_version_len>32? 32 : fw_version.fw_version_len); -+ AICWFDBG(LOGINFO, "Firmware Version: %s\r\n", fw_version.fw_version); -+ -+ wiphy->bands[NL80211_BAND_2GHZ] = &rwnx_band_2GHz; -+ if (rwnx_hw->band_5g_support) -+ wiphy->bands[NL80211_BAND_5GHZ] = &rwnx_band_5GHz; -+ -+ wiphy->interface_modes = -+ BIT(NL80211_IFTYPE_STATION) | -+ BIT(NL80211_IFTYPE_AP) | -+ BIT(NL80211_IFTYPE_AP_VLAN) | -+ BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO) | -+#ifndef CONFIG_USE_P2P0 -+ BIT(NL80211_IFTYPE_P2P_DEVICE) | -+#endif -+ BIT(NL80211_IFTYPE_MONITOR); -+ -+#if IS_ENABLED(CONFIG_PM) -+ /* Set WoWLAN flags */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) -+ wiphy->wowlan = &aic_wowlan_support; -+#else -+ wiphy->wowlan.flags = aic_wowlan_support.flags; -+#endif -+#endif -+ wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) -+ WIPHY_FLAG_HAS_CHANNEL_SWITCH | -+ #endif -+ WIPHY_FLAG_4ADDR_STATION | -+ WIPHY_FLAG_4ADDR_AP; -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+ wiphy->max_num_csa_counters = BCN_MAX_CSA_CPT; -+ #endif -+ -+ wiphy->max_remain_on_channel_duration = rwnx_hw->mod_params->roc_dur_max; -+ -+ wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN | -+ NL80211_FEATURE_SK_TX_STATUS | -+ NL80211_FEATURE_VIF_TXPOWER | -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) -+ NL80211_FEATURE_ACTIVE_MONITOR | -+ #endif -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+ NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE | -+ #endif -+ 0; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL) -+ wiphy->features |= NL80211_FEATURE_SAE; -+#endif -+ -+ if (rwnx_mod_params.tdls) -+ /* TDLS support */ -+ wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH; -+ -+ wiphy->iface_combinations = rwnx_combinations; -+ /* -1 not to include combination with radar detection, will be re-added in -+ rwnx_handle_dynparams if supported */ -+ wiphy->n_iface_combinations = ARRAY_SIZE(rwnx_combinations) - 1; -+ wiphy->reg_notifier = rwnx_reg_notifier; -+ -+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; -+ -+ rwnx_enable_wapi(rwnx_hw); -+ -+ wiphy->cipher_suites = cipher_suites; -+ wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites) - NB_RESERVED_CIPHER; -+ -+ rwnx_hw->ext_capa[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING; -+ rwnx_hw->ext_capa[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF; -+ -+ wiphy->extended_capabilities = rwnx_hw->ext_capa; -+ wiphy->extended_capabilities_mask = rwnx_hw->ext_capa; -+ wiphy->extended_capabilities_len = ARRAY_SIZE(rwnx_hw->ext_capa); -+ -+#ifdef CONFIG_SCHED_SCAN -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) -+ wiphy->max_sched_scan_reqs = 1; -+#endif -+ wiphy->max_sched_scan_ssids = SCAN_SSID_MAX;//16; -+ wiphy->max_match_sets = SCAN_SSID_MAX;//16; -+ wiphy->max_sched_scan_ie_len = 2048; -+#endif//CONFIG_SCHED_SCAN -+ -+ tasklet_init(&rwnx_hw->task, rwnx_task, (unsigned long)rwnx_hw); -+ -+ //init ic rf -+ if((ret = rwnx_ic_rf_init(rwnx_hw))){ -+ goto err_lmac_reqs; -+ } -+ -+ -+#ifdef CONFIG_USE_CUSTOMER_MAC -+ ret = rwnx_get_custom_mac_addr(mac_addr_efuse); -+ if (ret){ -+ AICWFDBG(LOGERROR, "%s read mac fail use default mac\r\n", __func__); -+ memcpy(init_conf.mac_addr, dflt_mac, ETH_ALEN); -+ } -+#else -+ ret = rwnx_send_get_macaddr_req(rwnx_hw, (struct mm_get_mac_addr_cfm *)mac_addr_efuse); -+ if (ret) -+ goto err_lmac_reqs; -+#endif -+ -+ if (mac_addr_efuse[0] | mac_addr_efuse[1] | mac_addr_efuse[2] | mac_addr_efuse[3]) { -+ memcpy(init_conf.mac_addr, mac_addr_efuse, ETH_ALEN); -+ }else{ -+ memcpy(init_conf.mac_addr, dflt_mac, ETH_ALEN); -+ } -+ -+ -+ AICWFDBG(LOGINFO, "get macaddr: %02x:%02x:%02x:%02x:%02x:%02x\r\n", -+ mac_addr_efuse[0], mac_addr_efuse[1], mac_addr_efuse[2], -+ mac_addr_efuse[3], mac_addr_efuse[4], mac_addr_efuse[5]); -+ memcpy(wiphy->perm_addr, init_conf.mac_addr, ETH_ALEN); -+ -+ /* Reset FW */ -+ ret = rwnx_send_reset(rwnx_hw); -+ if (ret) -+ goto err_lmac_reqs; -+ -+#ifdef CONFIG_TEMP_COMP -+ rwnx_send_set_temp_comp_req(rwnx_hw, &swconfig_cfm); -+#endif -+ -+ ret = rwnx_send_version_req(rwnx_hw, &rwnx_hw->version_cfm); -+ if (ret) -+ goto err_lmac_reqs; -+ rwnx_set_vers(rwnx_hw); -+ -+ ret = rwnx_handle_dynparams(rwnx_hw, rwnx_hw->wiphy); -+ if (ret) -+ goto err_lmac_reqs; -+ -+ rwnx_enable_mesh(rwnx_hw); -+ rwnx_radar_detection_init(&rwnx_hw->radar); -+ -+ /* Set parameters to firmware */ -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801 || -+ ((rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC|| -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW || -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80) && testmode == 0)){ -+ rwnx_send_me_config_req(rwnx_hw); -+ } -+ -+ /* Only monitor mode supported when custom channels are enabled */ -+ if (rwnx_mod_params.custchan) { -+ rwnx_limits[0].types = BIT(NL80211_IFTYPE_MONITOR); -+ rwnx_limits_dfs[0].types = BIT(NL80211_IFTYPE_MONITOR); -+ } -+ -+ aicwf_vendor_init(wiphy); -+ -+ ret = wiphy_register(wiphy); -+ if (ret) { -+ wiphy_err(wiphy, "Could not register wiphy device\n"); -+ goto err_register_wiphy; -+ } -+ -+ /* Update regulatory (if needed) and set channel parameters to firmware -+ (must be done after WiPHY registration) */ -+ rwnx_custregd(rwnx_hw, wiphy); -+ -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801 || -+ ((rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW || -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80) && testmode == 0)) { -+ rwnx_send_me_chan_config_req(rwnx_hw); -+ } -+ -+ *platform_data = rwnx_hw; -+ -+#ifdef CONFIG_DEBUG_FS -+ ret = rwnx_dbgfs_register(rwnx_hw, "rwnx"); -+ if (ret) { -+ wiphy_err(wiphy, "Failed to register debugfs entries"); -+ goto err_debugfs; -+ } -+#endif -+ rtnl_lock(); -+ -+ /* Add an initial station interface */ -+ vif = rwnx_interface_add(rwnx_hw, "wlan%d", NET_NAME_UNKNOWN, -+ NL80211_IFTYPE_STATION, NULL); -+ -+ rtnl_unlock(); -+ -+ if (!vif) { -+ wiphy_err(wiphy, "Failed to instantiate a network device\n"); -+ ret = -ENOMEM; -+ goto err_add_interface; -+ } -+ -+ //wiphy_info(wiphy, "New interface create %s", vif->ndev->name); -+ AICWFDBG(LOGINFO, "New interface create %s \r\n", vif->ndev->name); -+ -+#ifdef CONFIG_SDIO_BT -+ btchr_init(); -+ hdev_init(); -+#endif -+ -+#ifdef CONFIG_USE_P2P0 -+ -+ rtnl_lock(); -+ /* Add an initial p2p0 interface */ -+ vif = rwnx_interface_add(rwnx_hw, "p2p%d", NET_NAME_UNKNOWN, -+ NL80211_IFTYPE_STATION, NULL); -+ vif->is_p2p_vif = 1; -+ rtnl_unlock(); -+ -+ if (!vif) { -+ wiphy_err(wiphy, "Failed to instantiate a network device\n"); -+ ret = -ENOMEM; -+ goto err_add_interface; -+ } -+ -+ //wiphy_info(wiphy, "New interface create %s", vif->ndev->name); -+ AICWFDBG(LOGINFO, "New interface create %s \r\n", vif->ndev->name); -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) -+ init_timer(&rwnx_hw->p2p_alive_timer); -+ rwnx_hw->p2p_alive_timer.data = (unsigned long)vif; -+ rwnx_hw->p2p_alive_timer.function = aicwf_p2p_alive_timeout; -+#else -+ timer_setup(&rwnx_hw->p2p_alive_timer, aicwf_p2p_alive_timeout, 0); -+#endif -+ rwnx_hw->is_p2p_alive = 0; -+ rwnx_hw->is_p2p_connected = 0; -+ atomic_set(&rwnx_hw->p2p_alive_timer_count, 0); -+#endif -+ -+ -+ return 0; -+ -+err_add_interface: -+#ifdef CONFIG_DEBUG_FS -+ rwnx_dbgfs_unregister(rwnx_hw); -+err_debugfs: -+#endif -+ wiphy_unregister(rwnx_hw->wiphy); -+err_register_wiphy: -+err_lmac_reqs: -+ printk("err_lmac_reqs\n"); -+ rwnx_platform_off(rwnx_hw, NULL); -+//err_platon: -+//err_config: -+ kmem_cache_destroy(rwnx_hw->sw_txhdr_cache); -+err_cache: -+ aicwf_wakeup_lock_deinit(rwnx_hw); -+ wiphy_free(wiphy); -+err_out: -+ return ret; -+} -+ -+/** -+ * -+ */ -+void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw) -+{ -+ struct mm_set_stack_start_cfm set_start_cfm; -+ struct defrag_ctrl_info *defrag_ctrl = NULL; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+#ifdef AICWF_USB_SUPPORT -+ if (rwnx_hw->usbdev->bus_if->state != BUS_DOWN_ST) -+#else -+ if (rwnx_hw->sdiodev->bus_if->state != BUS_DOWN_ST) -+#endif -+ rwnx_send_set_stack_start_req(rwnx_hw, 0, 0, 0, 0, &set_start_cfm); -+ -+ rwnx_hw->fwlog_en = 0; -+ spin_lock_bh(&rwnx_hw->defrag_lock); -+ if (!list_empty(&rwnx_hw->defrag_list)) { -+ list_for_each_entry(defrag_ctrl, &rwnx_hw->defrag_list, list) { -+ list_del_init(&defrag_ctrl->list); -+ if (timer_pending(&defrag_ctrl->defrag_timer)) -+ del_timer_sync(&defrag_ctrl->defrag_timer); -+ dev_kfree_skb(defrag_ctrl->skb); -+ kfree(defrag_ctrl); -+ } -+ } -+ spin_unlock_bh(&rwnx_hw->defrag_lock); -+#ifdef CONFIG_DEBUG_FS -+ rwnx_dbgfs_unregister(rwnx_hw); -+#endif -+ -+#ifdef CONFIG_SDIO_BT -+ btchr_exit(); -+ hdev_exit(); -+#endif -+ -+ flush_workqueue(rwnx_hw->apmStaloss_wq); -+ destroy_workqueue(rwnx_hw->apmStaloss_wq); -+ -+ rwnx_wdev_unregister(rwnx_hw); -+ wiphy_unregister(rwnx_hw->wiphy); -+ rwnx_radar_detection_deinit(&rwnx_hw->radar); -+ rwnx_platform_off(rwnx_hw, NULL); -+ kmem_cache_destroy(rwnx_hw->sw_txhdr_cache); -+#ifdef CONFIG_FILTER_TCP_ACK -+ tcp_ack_deinit(rwnx_hw); -+#endif -+ aicwf_wakeup_lock_deinit(rwnx_hw); -+ wiphy_free(rwnx_hw->wiphy); -+} -+ -+static void aicsmac_driver_register(void) -+{ -+#ifdef AICWF_SDIO_SUPPORT -+ aicwf_sdio_register(); -+#endif -+#ifdef AICWF_USB_SUPPORT -+ aicwf_usb_register(); -+#endif -+#ifdef AICWF_PCIE_SUPPORT -+ aicwf_pcie_register(); -+#endif -+} -+ -+//static DECLARE_WORK(aicsmac_driver_work, aicsmac_driver_register); -+ -+struct completion hostif_register_done; -+static int rwnx_driver_err = -1; -+ -+#define REGISTRATION_TIMEOUT 9000 -+ -+void aicwf_hostif_ready(void) -+{ -+ rwnx_driver_err = 0; -+ g_rwnx_plat->enabled = true; -+ complete(&hostif_register_done); -+} -+ -+void aicwf_hostif_fail(void) -+{ -+ rwnx_driver_err = 1; -+ complete(&hostif_register_done); -+} -+ -+static int __init rwnx_mod_init(void) -+{ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ rwnx_print_version(); -+ rwnx_init_cmd_array(); -+ -+//#ifndef CONFIG_PLATFORM_ROCKCHIP -+ if (aicbsp_set_subsys(AIC_WIFI, AIC_PWR_ON) < 0) { -+ AICWFDBG(LOGERROR, "%s, set power on fail!\n", __func__); -+ if(!aicbsp_get_load_fw_in_fdrv()){ -+ return -ENODEV; -+ } -+ } -+//#endif -+ -+ init_completion(&hostif_register_done); -+ aicsmac_driver_register(); -+ -+ if ((wait_for_completion_timeout(&hostif_register_done, msecs_to_jiffies(REGISTRATION_TIMEOUT)) == 0) || rwnx_driver_err) { -+ AICWFDBG(LOGERROR, "register_driver timeout or error\n"); -+#ifdef AICWF_SDIO_SUPPORT -+ aicwf_sdio_exit(); -+#endif /* AICWF_SDIO_SUPPORT */ -+#ifdef AICWF_USB_SUPPORT -+ aicwf_usb_exit(); -+#endif /*AICWF_USB_SUPPORT */ -+ aicbsp_set_subsys(AIC_WIFI, AIC_PWR_OFF); -+ return -ENODEV; -+ } -+ -+#ifdef AICWF_PCIE_SUPPORT -+ return rwnx_platform_register_drv(); -+#else -+ return 0; -+#endif -+} -+ -+/** -+ * -+ */ -+static void __exit rwnx_mod_exit(void) -+{ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+#ifdef AICWF_PCIE_SUPPORT -+ rwnx_platform_unregister_drv(); -+#endif -+ -+#ifdef AICWF_SDIO_SUPPORT -+ aicwf_sdio_exit(); -+#endif -+ -+#ifdef AICWF_USB_SUPPORT -+ aicwf_usb_exit(); -+#endif -+//#ifndef CONFIG_PLATFORM_ROCKCHIP -+ aicbsp_set_subsys(AIC_WIFI, AIC_PWR_OFF); -+//#endif -+ rwnx_free_cmd_array(); -+ -+} -+ -+ -+#if MODULE_IMPORT_NS -+MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); -+#endif -+ -+module_init(rwnx_mod_init); -+module_exit(rwnx_mod_exit); -+ -+MODULE_FIRMWARE(RWNX_CONFIG_FW_NAME); -+ -+MODULE_DESCRIPTION(RW_DRV_DESCRIPTION); -+MODULE_VERSION(RWNX_VERS_MOD); -+MODULE_AUTHOR(RW_DRV_COPYRIGHT " " RW_DRV_AUTHOR); -+MODULE_LICENSE("GPL"); -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,40 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_main.h -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _RWNX_MAIN_H_ -+#define _RWNX_MAIN_H_ -+ -+#include "rwnx_defs.h" -+ -+typedef struct _android_wifi_priv_cmd { -+ char *buf; -+ int used_len; -+ int total_len; -+} android_wifi_priv_cmd; -+ -+#ifdef CONFIG_COMPAT -+typedef struct _compat_android_wifi_priv_cmd { -+ compat_caddr_t buf; -+ int used_len; -+ int total_len; -+} compat_android_wifi_priv_cmd; -+#endif /* CONFIG_COMPAT */ -+ -+int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data); -+void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw); -+extern int testmode; -+extern u8 chip_sub_id; -+extern u8 chip_mcu_id; -+extern u8 chip_id; -+ -+#define CHIP_ID_H_MASK 0xC0 -+#define IS_CHIP_ID_H() ((chip_id & CHIP_ID_H_MASK) == CHIP_ID_H_MASK) -+ -+#endif /* _RWNX_MAIN_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mesh.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mesh.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mesh.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mesh.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,42 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_mesh.c -+ * -+ * Copyright (C) RivieraWaves 2016-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+/** -+ * INCLUDE FILES -+ **************************************************************************************** -+ */ -+ -+#include "rwnx_mesh.h" -+ -+/** -+ * FUNCTION DEFINITIONS -+ **************************************************************************************** -+ */ -+ -+struct rwnx_mesh_proxy *rwnx_get_mesh_proxy_info(struct rwnx_vif *p_rwnx_vif, u8 *p_sta_addr, bool local) -+{ -+ struct rwnx_mesh_proxy *p_mesh_proxy = NULL; -+ struct rwnx_mesh_proxy *p_cur_proxy; -+ -+ /* Look for proxied devices with provided address */ -+ list_for_each_entry(p_cur_proxy, &p_rwnx_vif->ap.proxy_list, list) { -+ if (p_cur_proxy->local != local) { -+ continue; -+ } -+ -+ if (!memcmp(&p_cur_proxy->ext_sta_addr, p_sta_addr, ETH_ALEN)) { -+ p_mesh_proxy = p_cur_proxy; -+ break; -+ } -+ } -+ -+ /* Return the found information */ -+ return p_mesh_proxy; -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mesh.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mesh.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mesh.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mesh.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,45 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_mesh.h -+ * -+ * @brief VHT Beamformer function declarations -+ * -+ * Copyright (C) RivieraWaves 2016-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _RWNX_MESH_H_ -+#define _RWNX_MESH_H_ -+ -+/** -+ * INCLUDE FILES -+ **************************************************************************************** -+ */ -+ -+#include "rwnx_defs.h" -+ -+/** -+ * DEFINES -+ **************************************************************************************** -+ */ -+ -+/** -+ * TYPE DEFINITIONS -+ **************************************************************************************** -+ */ -+ -+/** -+ * FUNCTION DECLARATIONS -+ **************************************************************************************** -+ */ -+ -+/** -+ **************************************************************************************** -+ * @brief TODO [LT] -+ **************************************************************************************** -+ */ -+struct rwnx_mesh_proxy *rwnx_get_mesh_proxy_info(struct rwnx_vif *p_rwnx_vif, u8 *p_sta_addr, bool local); -+ -+#endif /* _RWNX_MESH_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,1754 @@ -+/** -+****************************************************************************** -+* -+* @file rwnx_mod_params.c -+* -+* @brief Set configuration according to modules parameters -+* -+* Copyright (C) RivieraWaves 2012-2019 -+* -+****************************************************************************** -+*/ -+#include -+#include -+ -+#include "rwnx_defs.h" -+#include "rwnx_tx.h" -+#include "hal_desc.h" -+#include "rwnx_cfgfile.h" -+#include "rwnx_dini.h" -+#include "reg_access.h" -+#include "rwnx_compat.h" -+ -+#ifdef CONFIG_RWNX_FULLMAC -+#define COMMON_PARAM(name, default_softmac, default_fullmac) \ -+ .name = default_fullmac, -+#define SOFTMAC_PARAM(name, default) -+#define FULLMAC_PARAM(name, default) .name = default, -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+struct rwnx_mod_params rwnx_mod_params = { -+ /* common parameters */ -+ COMMON_PARAM(ht_on, true, true) -+ COMMON_PARAM(vht_on, true, true) -+ COMMON_PARAM(he_on, true, true) -+ COMMON_PARAM(mcs_map, IEEE80211_VHT_MCS_SUPPORT_0_9, IEEE80211_VHT_MCS_SUPPORT_0_9) -+ COMMON_PARAM(he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_11, IEEE80211_HE_MCS_SUPPORT_0_11) -+ COMMON_PARAM(he_ul_on, false, false) -+ COMMON_PARAM(ldpc_on, true, true) -+ COMMON_PARAM(stbc_on, true, true) -+ COMMON_PARAM(gf_rx_on, false, false) -+ COMMON_PARAM(phy_cfg, 2, 2) -+ COMMON_PARAM(uapsd_timeout, 300, 300) -+ COMMON_PARAM(ap_uapsd_on, true, true) -+ COMMON_PARAM(sgi, true, true) -+ COMMON_PARAM(sgi80, false, false) -+ COMMON_PARAM(use_2040, 1, 1) -+ COMMON_PARAM(nss, 1, 1) -+ COMMON_PARAM(amsdu_rx_max, 2, 2) -+ COMMON_PARAM(bfmee, true, true) -+ COMMON_PARAM(bfmer, false, false) -+ COMMON_PARAM(mesh, true, true) -+ COMMON_PARAM(murx, true, true) -+ COMMON_PARAM(mutx, true, true) -+ COMMON_PARAM(mutx_on, true, true) -+ COMMON_PARAM(use_80, false, false) -+ COMMON_PARAM(custregd, true, true) -+ COMMON_PARAM(custchan, false, false) -+ COMMON_PARAM(roc_dur_max, 500, 500) -+ COMMON_PARAM(listen_itv, 0, 0) -+ COMMON_PARAM(listen_bcmc, true, true) -+ COMMON_PARAM(lp_clk_ppm, 20, 20) -+ COMMON_PARAM(ps_on, true, true) -+ COMMON_PARAM(tx_lft, RWNX_TX_LIFETIME_MS, RWNX_TX_LIFETIME_MS) -+ COMMON_PARAM(amsdu_maxnb, NX_TX_PAYLOAD_MAX, NX_TX_PAYLOAD_MAX) -+ // By default, only enable UAPSD for Voice queue (see IEEE80211_DEFAULT_UAPSD_QUEUE comment) -+ COMMON_PARAM(uapsd_queues, IEEE80211_WMM_IE_STA_QOSINFO_AC_VO, IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) -+ COMMON_PARAM(tdls, false, false) -+ COMMON_PARAM(uf, false, false) -+ COMMON_PARAM(auto_reply, false, false) -+ COMMON_PARAM(ftl, "", "") -+ COMMON_PARAM(dpsm, false, false) -+ -+ /* SOFTMAC only parameters */ -+ SOFTMAC_PARAM(mfp_on, false) -+ SOFTMAC_PARAM(gf_on, false) -+ SOFTMAC_PARAM(bwsig_on, true) -+ SOFTMAC_PARAM(dynbw_on, true) -+ SOFTMAC_PARAM(agg_tx, true) -+ SOFTMAC_PARAM(amsdu_force, 2) -+ SOFTMAC_PARAM(rc_probes_on, false) -+ SOFTMAC_PARAM(cmon, true) -+ SOFTMAC_PARAM(hwscan, true) -+ SOFTMAC_PARAM(autobcn, true) -+ SOFTMAC_PARAM(dpsm, true) -+ -+ /* FULLMAC only parameters */ -+ FULLMAC_PARAM(ant_div, true) -+}; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+/* FULLMAC specific parameters*/ -+module_param_named(ant_div, rwnx_mod_params.ant_div, bool, S_IRUGO); -+MODULE_PARM_DESC(ant_div, "Enable Antenna Diversity (Default: 1)"); -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+module_param_named(ht_on, rwnx_mod_params.ht_on, bool, S_IRUGO); -+MODULE_PARM_DESC(ht_on, "Enable HT (Default: 1)"); -+ -+module_param_named(vht_on, rwnx_mod_params.vht_on, bool, S_IRUGO); -+MODULE_PARM_DESC(vht_on, "Enable VHT (Default: 1)"); -+ -+module_param_named(he_on, rwnx_mod_params.he_on, bool, S_IRUGO); -+MODULE_PARM_DESC(he_on, "Enable HE (Default: 1)"); -+ -+module_param_named(mcs_map, rwnx_mod_params.mcs_map, int, S_IRUGO); -+MODULE_PARM_DESC(mcs_map, "VHT MCS map value 0: MCS0_7, 1: MCS0_8, 2: MCS0_9" -+ " (Default: 2)"); -+ -+module_param_named(he_mcs_map, rwnx_mod_params.he_mcs_map, int, S_IRUGO); -+MODULE_PARM_DESC(he_mcs_map, "HE MCS map value 0: MCS0_7, 1: MCS0_9, 2: MCS0_11" -+ " (Default: 2)"); -+ -+module_param_named(he_ul_on, rwnx_mod_params.he_ul_on, bool, S_IRUGO); -+MODULE_PARM_DESC(he_ul_on, "Enable HE OFDMA UL (Default: 0)"); -+ -+module_param_named(amsdu_maxnb, rwnx_mod_params.amsdu_maxnb, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(amsdu_maxnb, "Maximum number of MSDUs inside an A-MSDU in TX: (Default: NX_TX_PAYLOAD_MAX)"); -+ -+module_param_named(ps_on, rwnx_mod_params.ps_on, bool, S_IRUGO); -+MODULE_PARM_DESC(ps_on, "Enable PowerSaving (Default: 1-Enabled)"); -+ -+module_param_named(tx_lft, rwnx_mod_params.tx_lft, int, 0644); -+MODULE_PARM_DESC(tx_lft, "Tx lifetime (ms) - setting it to 0 disables retries " -+ "(Default: "__stringify(RWNX_TX_LIFETIME_MS)")"); -+ -+module_param_named(ldpc_on, rwnx_mod_params.ldpc_on, bool, S_IRUGO); -+MODULE_PARM_DESC(ldpc_on, "Enable LDPC (Default: 1)"); -+ -+module_param_named(stbc_on, rwnx_mod_params.stbc_on, bool, S_IRUGO); -+MODULE_PARM_DESC(stbc_on, "Enable STBC in RX (Default: 1)"); -+ -+module_param_named(gf_rx_on, rwnx_mod_params.gf_rx_on, bool, S_IRUGO); -+MODULE_PARM_DESC(gf_rx_on, "Enable HT greenfield in reception (Default: 1)"); -+ -+module_param_named(phycfg, rwnx_mod_params.phy_cfg, int, S_IRUGO); -+MODULE_PARM_DESC(phycfg, -+ "0 <= phycfg <= 5 : RF Channel Conf (Default: 2(C0-A1-B2))"); -+ -+module_param_named(uapsd_timeout, rwnx_mod_params.uapsd_timeout, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(uapsd_timeout, -+ "UAPSD Timer timeout, in ms (Default: 300). If 0, UAPSD is disabled"); -+ -+module_param_named(uapsd_queues, rwnx_mod_params.uapsd_queues, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(uapsd_queues, "UAPSD Queues, integer value, must be seen as a bitfield\n" -+ " Bit 0 = VO\n" -+ " Bit 1 = VI\n" -+ " Bit 2 = BK\n" -+ " Bit 3 = BE\n" -+ " -> uapsd_queues=7 will enable uapsd for VO, VI and BK queues"); -+ -+module_param_named(ap_uapsd_on, rwnx_mod_params.ap_uapsd_on, bool, S_IRUGO); -+MODULE_PARM_DESC(ap_uapsd_on, "Enable UAPSD in AP mode (Default: 1)"); -+ -+module_param_named(sgi, rwnx_mod_params.sgi, bool, S_IRUGO); -+MODULE_PARM_DESC(sgi, "Advertise Short Guard Interval support (Default: 1)"); -+ -+module_param_named(sgi80, rwnx_mod_params.sgi80, bool, S_IRUGO); -+MODULE_PARM_DESC(sgi80, "Advertise Short Guard Interval support for 80MHz (Default: 1)"); -+ -+module_param_named(use_2040, rwnx_mod_params.use_2040, bool, S_IRUGO); -+MODULE_PARM_DESC(use_2040, "Use tweaked 20-40MHz mode (Default: 1)"); -+ -+module_param_named(use_80, rwnx_mod_params.use_80, bool, S_IRUGO); -+MODULE_PARM_DESC(use_80, "Enable 80MHz (Default: 1)"); -+ -+module_param_named(custregd, rwnx_mod_params.custregd, bool, S_IRUGO); -+MODULE_PARM_DESC(custregd, -+ "Use permissive custom regulatory rules (for testing ONLY) (Default: 0)"); -+ -+module_param_named(custchan, rwnx_mod_params.custchan, bool, S_IRUGO); -+MODULE_PARM_DESC(custchan, -+ "Extend channel set to non-standard channels (for testing ONLY) (Default: 0)"); -+ -+module_param_named(nss, rwnx_mod_params.nss, int, S_IRUGO); -+MODULE_PARM_DESC(nss, "1 <= nss <= 2 : Supported number of Spatial Streams (Default: 1)"); -+ -+module_param_named(amsdu_rx_max, rwnx_mod_params.amsdu_rx_max, int, S_IRUGO); -+MODULE_PARM_DESC(amsdu_rx_max, "0 <= amsdu_rx_max <= 2 : Maximum A-MSDU size supported in RX\n" -+ " 0: 3895 bytes\n" -+ " 1: 7991 bytes\n" -+ " 2: 11454 bytes\n" -+ " This value might be reduced according to the FW capabilities.\n" -+ " Default: 2"); -+ -+module_param_named(bfmee, rwnx_mod_params.bfmee, bool, S_IRUGO); -+MODULE_PARM_DESC(bfmee, "Enable Beamformee Capability (Default: 1-Enabled)"); -+ -+module_param_named(bfmer, rwnx_mod_params.bfmer, bool, S_IRUGO); -+MODULE_PARM_DESC(bfmer, "Enable Beamformer Capability (Default: 0-Disabled)"); -+ -+module_param_named(mesh, rwnx_mod_params.mesh, bool, S_IRUGO); -+MODULE_PARM_DESC(mesh, "Enable Meshing Capability (Default: 1-Enabled)"); -+ -+module_param_named(murx, rwnx_mod_params.murx, bool, S_IRUGO); -+MODULE_PARM_DESC(murx, "Enable MU-MIMO RX Capability (Default: 1-Enabled)"); -+ -+module_param_named(mutx, rwnx_mod_params.mutx, bool, S_IRUGO); -+MODULE_PARM_DESC(mutx, "Enable MU-MIMO TX Capability (Default: 1-Enabled)"); -+ -+module_param_named(mutx_on, rwnx_mod_params.mutx_on, bool, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(mutx_on, "Enable MU-MIMO transmissions (Default: 1-Enabled)"); -+ -+module_param_named(roc_dur_max, rwnx_mod_params.roc_dur_max, int, S_IRUGO); -+MODULE_PARM_DESC(roc_dur_max, "Maximum Remain on Channel duration"); -+ -+module_param_named(listen_itv, rwnx_mod_params.listen_itv, int, S_IRUGO); -+MODULE_PARM_DESC(listen_itv, "Maximum listen interval"); -+ -+module_param_named(listen_bcmc, rwnx_mod_params.listen_bcmc, bool, S_IRUGO); -+MODULE_PARM_DESC(listen_bcmc, "Wait for BC/MC traffic following DTIM beacon"); -+ -+module_param_named(lp_clk_ppm, rwnx_mod_params.lp_clk_ppm, int, S_IRUGO); -+MODULE_PARM_DESC(lp_clk_ppm, "Low Power Clock accuracy of the local device"); -+ -+module_param_named(tdls, rwnx_mod_params.tdls, bool, S_IRUGO); -+MODULE_PARM_DESC(tdls, "Enable TDLS (Default: 1-Enabled)"); -+ -+module_param_named(uf, rwnx_mod_params.uf, bool, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(uf, "Enable Unsupported HT Frame Logging (Default: 0-Disabled)"); -+ -+module_param_named(auto_reply, rwnx_mod_params.auto_reply, bool, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(auto_reply, "Enable Monitor MacAddr Auto-Reply (Default: 0-Disabled)"); -+ -+module_param_named(ftl, rwnx_mod_params.ftl, charp, S_IRUGO); -+MODULE_PARM_DESC(ftl, "Firmware trace level (Default: \"\")"); -+ -+module_param_named(dpsm, rwnx_mod_params.dpsm, bool, S_IRUGO); -+MODULE_PARM_DESC(dpsm, "Enable Dynamic PowerSaving (Default: 1-Enabled)"); -+ -+ -+#ifdef DEFAULT_COUNTRY_CODE -+char default_ccode[4] = DEFAULT_COUNTRY_CODE; -+#else -+char default_ccode[4] = "00"; -+#endif -+ -+char country_code[4]; -+module_param_string(country_code, country_code, 4, 0600); -+ -+#if 0 -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+/* Regulatory rules */ -+static struct ieee80211_regdomain rwnx_regdom = { -+ .n_reg_rules = 2, -+ .alpha2 = "99", -+ .reg_rules = { -+ REG_RULE(2390 - 10, 2510 + 10, 40, 0, 1000, 0), -+ REG_RULE(5150 - 10, 5970 + 10, 80, 0, 1000, 0), -+ } -+}; -+#endif -+#endif -+ -+static const int mcs_map_to_rate[4][3] = { -+ [PHY_CHNL_BW_20][IEEE80211_VHT_MCS_SUPPORT_0_7] = 65, -+ [PHY_CHNL_BW_20][IEEE80211_VHT_MCS_SUPPORT_0_8] = 78, -+ [PHY_CHNL_BW_20][IEEE80211_VHT_MCS_SUPPORT_0_9] = 78, -+ [PHY_CHNL_BW_40][IEEE80211_VHT_MCS_SUPPORT_0_7] = 135, -+ [PHY_CHNL_BW_40][IEEE80211_VHT_MCS_SUPPORT_0_8] = 162, -+ [PHY_CHNL_BW_40][IEEE80211_VHT_MCS_SUPPORT_0_9] = 180, -+ [PHY_CHNL_BW_80][IEEE80211_VHT_MCS_SUPPORT_0_7] = 292, -+ [PHY_CHNL_BW_80][IEEE80211_VHT_MCS_SUPPORT_0_8] = 351, -+ [PHY_CHNL_BW_80][IEEE80211_VHT_MCS_SUPPORT_0_9] = 390, -+ [PHY_CHNL_BW_160][IEEE80211_VHT_MCS_SUPPORT_0_7] = 585, -+ [PHY_CHNL_BW_160][IEEE80211_VHT_MCS_SUPPORT_0_8] = 702, -+ [PHY_CHNL_BW_160][IEEE80211_VHT_MCS_SUPPORT_0_9] = 780, -+}; -+ -+#define MAX_VHT_RATE(map, nss, bw) (mcs_map_to_rate[bw][map] * (nss)) -+ -+extern struct ieee80211_regdomain *reg_regdb[]; -+ -+char ccode_channels[200]; -+int index_for_channel_list = 0; -+module_param_string(ccode_channels, ccode_channels, 200, 0600); -+ -+void rwnx_get_countrycode_channels(struct wiphy *wiphy, -+ struct ieee80211_regdomain *regdomain){ -+ enum nl80211_band band; -+ struct ieee80211_supported_band *sband; -+ int channel_index; -+ int rule_index; -+ int band_num = 0; -+ int rule_num = regdomain->n_reg_rules; -+ int start_freq = 0; -+ int end_freq = 0; -+ int center_freq = 0; -+ char channel[4]; -+ -+ band_num = NUM_NL80211_BANDS; -+ -+ memset(ccode_channels, 0, 200); -+ index_for_channel_list = 0; -+ -+ for (band = 0; band < band_num; band++) { -+ sband = wiphy->bands[band];// bands: 0:2.4G 1:5G 2:60G -+ if (!sband) -+ continue; -+ -+ for (channel_index = 0; channel_index < sband->n_channels; channel_index++) { -+ for(rule_index = 0; rule_index < rule_num; rule_index++){ -+ start_freq = regdomain->reg_rules[rule_index].freq_range.start_freq_khz/1000; -+ end_freq = regdomain->reg_rules[rule_index].freq_range.end_freq_khz/1000; -+ center_freq = sband->channels[channel_index].center_freq; -+ if((center_freq - 10) >= start_freq && (center_freq + 10) <= end_freq){ -+ sprintf(channel, "%d",ieee80211_frequency_to_channel(center_freq)); -+ memcpy(ccode_channels + index_for_channel_list, channel, strlen(channel)); -+ index_for_channel_list += strlen(channel); -+ memcpy(ccode_channels + index_for_channel_list, " ", 1); -+ index_for_channel_list += 1; -+ break; -+ } -+ } -+ } -+ } -+ AICWFDBG(LOGINFO, "%s support channel:%s\r\n", __func__, ccode_channels); -+} -+ -+ -+struct ieee80211_regdomain *getRegdomainFromRwnxDBIndex(struct wiphy *wiphy, -+ int index) -+{ -+ u8 idx; -+ -+ idx = index; -+ -+ memset(country_code, 0, 4); -+ country_code[0] = reg_regdb[idx]->alpha2[0]; -+ country_code[1] = reg_regdb[idx]->alpha2[1]; -+ -+ printk("%s set ccode:%s \r\n", __func__, country_code); -+ -+ rwnx_get_countrycode_channels(wiphy, reg_regdb[idx]); -+ -+ return reg_regdb[idx]; -+} -+ -+ -+struct ieee80211_regdomain *getRegdomainFromRwnxDB(struct wiphy *wiphy, -+ char *alpha2) -+{ -+ u8 idx; -+ -+ memset(country_code, 0, 4); -+ -+ AICWFDBG(LOGINFO, "%s set ccode:%s \r\n", __func__, alpha2); -+ idx = 0; -+ -+ while (reg_regdb[idx]){ -+ if((reg_regdb[idx]->alpha2[0] == alpha2[0]) && -+ (reg_regdb[idx]->alpha2[1] == alpha2[1])){ -+ memcpy(country_code, alpha2, 2); -+ rwnx_get_countrycode_channels(wiphy, reg_regdb[idx]); -+ return reg_regdb[idx]; -+ } -+ idx++; -+ } -+ -+ AICWFDBG(LOGERROR, "%s(): Error, wrong country = %s\n", -+ __func__, alpha2); -+ AICWFDBG(LOGINFO, "Set as default 00\n"); -+ memcpy(country_code, default_ccode, sizeof(default_ccode)); -+ rwnx_get_countrycode_channels(wiphy, reg_regdb[0]); -+ -+ return reg_regdb[0]; -+} -+ -+ -+ -+/** -+ * Do some sanity check -+ * -+ */ -+#if 0 -+static int rwnx_check_fw_hw_feature(struct rwnx_hw *rwnx_hw, -+ struct wiphy *wiphy) -+{ -+ u32_l sys_feat = rwnx_hw->version_cfm.features; -+ u32_l mac_feat = rwnx_hw->version_cfm.version_machw_1; -+ u32_l phy_feat = rwnx_hw->version_cfm.version_phy_1; -+ u32_l phy_vers = rwnx_hw->version_cfm.version_phy_2; -+ u16_l max_sta_nb = rwnx_hw->version_cfm.max_sta_nb; -+ u8_l max_vif_nb = rwnx_hw->version_cfm.max_vif_nb; -+ int bw, res = 0; -+ int amsdu_rx; -+ -+ if (!rwnx_hw->mod_params->custregd) -+ rwnx_hw->mod_params->custchan = false; -+ -+ if (rwnx_hw->mod_params->custchan) { -+ rwnx_hw->mod_params->mesh = false; -+ rwnx_hw->mod_params->tdls = false; -+ } -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+ if (!(sys_feat & BIT(MM_FEAT_UMAC_BIT))) { -+ wiphy_err(wiphy, -+ "Loading softmac firmware with fullmac driver\n"); -+ res = -1; -+ } -+ -+ if (!(sys_feat & BIT(MM_FEAT_ANT_DIV_BIT))) { -+ rwnx_hw->mod_params->ant_div = false; -+ } -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ if (!(sys_feat & BIT(MM_FEAT_VHT_BIT))) { -+ rwnx_hw->mod_params->vht_on = false; -+ } -+ -+ // Check if HE is supported -+ if (!(sys_feat & BIT(MM_FEAT_HE_BIT))) { -+ rwnx_hw->mod_params->he_on = false; -+ rwnx_hw->mod_params->he_ul_on = false; -+ } -+ -+ if (!(sys_feat & BIT(MM_FEAT_PS_BIT))) { -+ rwnx_hw->mod_params->ps_on = false; -+ } -+ -+ /* AMSDU (non)support implies different shared structure definition -+ so insure that fw and drv have consistent compilation option */ -+ if (sys_feat & BIT(MM_FEAT_AMSDU_BIT)) { -+#ifndef CONFIG_RWNX_SPLIT_TX_BUF -+ wiphy_err(wiphy, -+ "AMSDU enabled in firmware but support not compiled in driver\n"); -+ res = -1; -+#else -+ if (rwnx_hw->mod_params->amsdu_maxnb > NX_TX_PAYLOAD_MAX) -+ rwnx_hw->mod_params->amsdu_maxnb = NX_TX_PAYLOAD_MAX; -+#endif /* CONFIG_RWNX_SPLIT_TX_BUF */ -+ } else { -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ wiphy_err(wiphy, -+ "AMSDU disabled in firmware but support compiled in driver\n"); -+ res = -1; -+#endif /* CONFIG_RWNX_SPLIT_TX_BUF */ -+ } -+ -+ if (!(sys_feat & BIT(MM_FEAT_UAPSD_BIT))) { -+ rwnx_hw->mod_params->uapsd_timeout = 0; -+ } -+ -+ if (!(sys_feat & BIT(MM_FEAT_BFMEE_BIT))) { -+ rwnx_hw->mod_params->bfmee = false; -+ } -+ -+ if ((sys_feat & BIT(MM_FEAT_BFMER_BIT))) { -+#ifndef CONFIG_RWNX_BFMER -+ wiphy_err(wiphy, -+ "BFMER enabled in firmware but support not compiled in driver\n"); -+ res = -1; -+#endif /* CONFIG_RWNX_BFMER */ -+ // Check PHY and MAC HW BFMER support and update parameter accordingly -+ if (!(phy_feat & MDM_BFMER_BIT) || !(mac_feat & NXMAC_BFMER_BIT)) { -+ rwnx_hw->mod_params->bfmer = false; -+ // Disable the feature in the bitfield so that it won't be displayed -+ sys_feat &= ~BIT(MM_FEAT_BFMER_BIT); -+ } -+ } else { -+#ifdef CONFIG_RWNX_BFMER -+ wiphy_err(wiphy, -+ "BFMER disabled in firmware but support compiled in driver\n"); -+ res = -1; -+#else -+ rwnx_hw->mod_params->bfmer = false; -+#endif /* CONFIG_RWNX_BFMER */ -+ } -+ -+ if (!(sys_feat & BIT(MM_FEAT_MESH_BIT))) { -+ rwnx_hw->mod_params->mesh = false; -+ } -+ -+ if (!(sys_feat & BIT(MM_FEAT_TDLS_BIT))) { -+ rwnx_hw->mod_params->tdls = false; -+ } -+ -+ if (!(sys_feat & BIT(MM_FEAT_UF_BIT))) { -+ rwnx_hw->mod_params->uf = false; -+ } -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ if ((sys_feat & BIT(MM_FEAT_MON_DATA_BIT))) { -+#ifndef CONFIG_RWNX_MON_DATA -+ wiphy_err(wiphy, -+ "Monitor+Data interface support (MON_DATA) is enabled in firmware but support not compiled in driver\n"); -+ res = -1; -+#endif /* CONFIG_RWNX_MON_DATA */ -+ } else { -+#ifdef CONFIG_RWNX_MON_DATA -+ wiphy_err(wiphy, -+ "Monitor+Data interface support (MON_DATA) disabled in firmware but support compiled in driver\n"); -+ res = -1; -+#endif /* CONFIG_RWNX_MON_DATA */ -+ } -+#endif -+ -+ // Check supported AMSDU RX size -+ amsdu_rx = (sys_feat >> MM_AMSDU_MAX_SIZE_BIT0) & 0x03; -+ if (amsdu_rx < rwnx_hw->mod_params->amsdu_rx_max) { -+ rwnx_hw->mod_params->amsdu_rx_max = amsdu_rx; -+ } -+ -+ // Check supported BW -+ bw = (phy_feat & MDM_CHBW_MASK) >> MDM_CHBW_LSB; -+ // Check if 80MHz BW is supported -+ if (bw < 2) { -+ rwnx_hw->mod_params->use_80 = false; -+ } -+ // Check if 40MHz BW is supported -+ if (bw < 1) -+ rwnx_hw->mod_params->use_2040 = false; -+ -+ // 80MHz BW shall be disabled if 40MHz is not enabled -+ if (!rwnx_hw->mod_params->use_2040) -+ rwnx_hw->mod_params->use_80 = false; -+ -+ // Check if HT is supposed to be supported. If not, disable VHT/HE too -+ if (!rwnx_hw->mod_params->ht_on) { -+ rwnx_hw->mod_params->vht_on = false; -+ rwnx_hw->mod_params->he_on = false; -+ rwnx_hw->mod_params->he_ul_on = false; -+ rwnx_hw->mod_params->use_80 = false; -+ rwnx_hw->mod_params->use_2040 = false; -+ } -+ -+ // LDPC is mandatory for HE40 and above, so if LDPC is not supported, then disable -+ // HE to use HT/VHT only -+ if (rwnx_hw->mod_params->use_2040 && !rwnx_hw->mod_params->ldpc_on) { -+ rwnx_hw->mod_params->he_on = false; -+ rwnx_hw->mod_params->he_ul_on = false; -+ } -+ -+ // HT greenfield is not supported in modem >= 3.0 -+ if (__MDM_MAJOR_VERSION(phy_vers) > 0) { -+ rwnx_hw->mod_params->gf_rx_on = false; -+ } -+ -+ if (!(sys_feat & BIT(MM_FEAT_MU_MIMO_RX_BIT)) || -+ !rwnx_hw->mod_params->bfmee) { -+ rwnx_hw->mod_params->murx = false; -+ } -+ -+ if ((sys_feat & BIT(MM_FEAT_MU_MIMO_TX_BIT))) { -+#ifndef CONFIG_RWNX_MUMIMO_TX -+ wiphy_err(wiphy, -+ "MU-MIMO TX enabled in firmware but support not compiled in driver\n"); -+ res = -1; -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+ if (!rwnx_hw->mod_params->bfmer) -+ rwnx_hw->mod_params->mutx = false; -+ // Check PHY and MAC HW MU-MIMO TX support and update parameter accordingly -+ else if (!(phy_feat & MDM_MUMIMOTX_BIT) || !(mac_feat & NXMAC_MU_MIMO_TX_BIT)) { -+ rwnx_hw->mod_params->mutx = false; -+ // Disable the feature in the bitfield so that it won't be displayed -+ sys_feat &= ~BIT(MM_FEAT_MU_MIMO_TX_BIT); -+ } -+ } else { -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ wiphy_err(wiphy, -+ "MU-MIMO TX disabled in firmware but support compiled in driver\n"); -+ res = -1; -+#else -+ rwnx_hw->mod_params->mutx = false; -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+ } -+ -+ if (sys_feat & BIT(MM_FEAT_WAPI_BIT)) { -+ rwnx_enable_wapi(rwnx_hw); -+ } -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ if (sys_feat & BIT(MM_FEAT_MFP_BIT)) { -+ rwnx_enable_mfp(rwnx_hw); -+ } -+#endif -+ -+#ifdef CONFIG_RWNX_FULLMAC -+#define QUEUE_NAME "Broadcast/Multicast queue " -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ if (sys_feat & BIT(MM_FEAT_BCN_BIT)) { -+#if NX_TXQ_CNT == 4 -+ wiphy_err(wiphy, QUEUE_NAME -+ "enabled in firmware but support not compiled in driver\n"); -+ res = -1; -+#endif /* NX_TXQ_CNT == 4 */ -+ } else { -+#if NX_TXQ_CNT == 5 -+ wiphy_err(wiphy, QUEUE_NAME -+ "disabled in firmware but support compiled in driver\n"); -+ res = -1; -+#endif /* NX_TXQ_CNT == 5 */ -+ } -+#undef QUEUE_NAME -+ -+#ifdef CONFIG_RWNX_RADAR -+ if (sys_feat & BIT(MM_FEAT_RADAR_BIT)) { -+ /* Enable combination with radar detection */ -+ wiphy->n_iface_combinations++; -+ } -+#endif /* CONFIG_RWNX_RADAR */ -+ -+#ifndef CONFIG_RWNX_SDM -+ switch (__MDM_PHYCFG_FROM_VERS(phy_feat)) { -+ case MDM_PHY_CONFIG_TRIDENT: -+ case MDM_PHY_CONFIG_ELMA: -+ rwnx_hw->mod_params->nss = 1; -+ break; -+ case MDM_PHY_CONFIG_KARST: -+ { -+ int nss_supp = (phy_feat & MDM_NSS_MASK) >> MDM_NSS_LSB; -+ if (rwnx_hw->mod_params->nss > nss_supp) -+ rwnx_hw->mod_params->nss = nss_supp; -+ } -+ break; -+ default: -+ WARN_ON(1); -+ break; -+ } -+#endif /* CONFIG_RWNX_SDM */ -+ -+ if (rwnx_hw->mod_params->nss < 1 || rwnx_hw->mod_params->nss > 2) -+ rwnx_hw->mod_params->nss = 1; -+ -+ if (rwnx_hw->mod_params->phy_cfg < 0 || rwnx_hw->mod_params->phy_cfg > 5) -+ rwnx_hw->mod_params->phy_cfg = 2; -+ -+ if (rwnx_hw->mod_params->mcs_map < 0 || rwnx_hw->mod_params->mcs_map > 2) -+ rwnx_hw->mod_params->mcs_map = 0; -+ -+ wiphy_info(wiphy, "PHY features: [NSS=%d][CHBW=%d]%s%s\n", -+ rwnx_hw->mod_params->nss, -+ 20 * (1 << ((phy_feat & MDM_CHBW_MASK) >> MDM_CHBW_LSB)), -+ rwnx_hw->mod_params->ldpc_on ? "[LDPC]" : "", -+ rwnx_hw->mod_params->he_on ? "[HE]" : ""); -+ -+#define PRINT_RWNX_FEAT(feat) \ -+ (sys_feat & BIT(MM_FEAT_##feat##_BIT) ? "["#feat"]" : "") -+ -+ wiphy_info(wiphy, "FW features: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", -+ PRINT_RWNX_FEAT(BCN), -+ PRINT_RWNX_FEAT(AUTOBCN), -+ PRINT_RWNX_FEAT(HWSCAN), -+ PRINT_RWNX_FEAT(CMON), -+ PRINT_RWNX_FEAT(MROLE), -+ PRINT_RWNX_FEAT(RADAR), -+ PRINT_RWNX_FEAT(PS), -+ PRINT_RWNX_FEAT(UAPSD), -+ PRINT_RWNX_FEAT(DPSM), -+ PRINT_RWNX_FEAT(AMPDU), -+ PRINT_RWNX_FEAT(AMSDU), -+ PRINT_RWNX_FEAT(CHNL_CTXT), -+ PRINT_RWNX_FEAT(REORD), -+ PRINT_RWNX_FEAT(P2P), -+ PRINT_RWNX_FEAT(P2P_GO), -+ PRINT_RWNX_FEAT(UMAC), -+ PRINT_RWNX_FEAT(VHT), -+ PRINT_RWNX_FEAT(HE), -+ PRINT_RWNX_FEAT(BFMEE), -+ PRINT_RWNX_FEAT(BFMER), -+ PRINT_RWNX_FEAT(WAPI), -+ PRINT_RWNX_FEAT(MFP), -+ PRINT_RWNX_FEAT(MU_MIMO_RX), -+ PRINT_RWNX_FEAT(MU_MIMO_TX), -+ PRINT_RWNX_FEAT(MESH), -+ PRINT_RWNX_FEAT(TDLS), -+ PRINT_RWNX_FEAT(ANT_DIV)); -+#undef PRINT_RWNX_FEAT -+ -+ if (max_sta_nb != NX_REMOTE_STA_MAX) { -+ wiphy_err(wiphy, "Different number of supported stations between driver and FW (%d != %d)\n", -+ NX_REMOTE_STA_MAX, max_sta_nb); -+ res = -1; -+ } -+ -+ if (max_vif_nb != NX_VIRT_DEV_MAX) { -+ wiphy_err(wiphy, "Different number of supported virtual interfaces between driver and FW (%d != %d)\n", -+ NX_VIRT_DEV_MAX, max_vif_nb); -+ res = -1; -+ } -+ -+ return res; -+} -+#endif -+ -+ -+static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) -+{ -+#ifdef CONFIG_VHT_FOR_OLD_KERNEL -+ #ifdef USE_5G -+ struct ieee80211_supported_band *band_5GHz = wiphy->bands[NL80211_BAND_5GHZ]; -+ #endif -+ struct ieee80211_supported_band *band_2GHz = wiphy->bands[NL80211_BAND_2GHZ]; -+ -+ int i; -+ int nss = rwnx_hw->mod_params->nss; -+ int mcs_map; -+ int mcs_map_max; -+ int bw_max; -+ -+ if (!rwnx_hw->mod_params->vht_on) { -+ return; -+ } -+ -+ rwnx_hw->vht_cap_2G.vht_supported = true; -+ if (rwnx_hw->mod_params->sgi80) -+ rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_SHORT_GI_80; -+ if (rwnx_hw->mod_params->stbc_on) -+ rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_RXSTBC_1; -+ if (rwnx_hw->mod_params->ldpc_on) -+ rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_RXLDPC; -+ if (rwnx_hw->mod_params->bfmee) { -+ rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ rwnx_hw->vht_cap_2G.cap |= 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; -+ #else -+ rwnx_hw->vht_cap_2G.cap |= 3 << 13; -+ #endif -+ } -+ if (nss > 1) -+ rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_TXSTBC; -+ -+ // Update the AMSDU max RX size (not shifted as located at offset 0 of the VHT cap) -+ rwnx_hw->vht_cap_2G.cap |= rwnx_hw->mod_params->amsdu_rx_max; -+ -+ if (rwnx_hw->mod_params->bfmer) { -+ rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; -+ /* Set number of sounding dimensions */ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ rwnx_hw->vht_cap_2G.cap |= (nss - 1) << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; -+ #else -+ rwnx_hw->vht_cap_2G.cap |= (nss - 1) << 16; -+ #endif -+ } -+ if (rwnx_hw->mod_params->murx) -+ rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; -+ if (rwnx_hw->mod_params->mutx) -+ rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; -+ -+ /* -+ * MCS map: -+ * This capabilities are filled according to the mcs_map module parameter. -+ * However currently we have some limitations due to FPGA clock constraints -+ * that prevent always using the range of MCS that is defined by the -+ * parameter: -+ * - in RX, 2SS, we support up to MCS7 -+ * - in TX, 2SS, we support up to MCS8 -+ */ -+ // Get max supported BW -+ if (rwnx_hw->mod_params->use_80) -+ bw_max = PHY_CHNL_BW_80; -+ else if (rwnx_hw->mod_params->use_2040) -+ bw_max = PHY_CHNL_BW_40; -+ else -+ bw_max = PHY_CHNL_BW_20; -+ -+ // Check if MCS map should be limited to MCS0_8 due to the standard. Indeed in BW20, -+ // MCS9 is not supported in 1 and 2 SS -+ if (rwnx_hw->mod_params->use_2040) -+ mcs_map_max = IEEE80211_VHT_MCS_SUPPORT_0_9; -+ else -+ mcs_map_max = IEEE80211_VHT_MCS_SUPPORT_0_8; -+ -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, mcs_map_max); -+ rwnx_hw->vht_cap_2G.vht_mcs.rx_mcs_map = cpu_to_le16(0); -+ for (i = 0; i < nss; i++) { -+ rwnx_hw->vht_cap_2G.vht_mcs.rx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); -+ rwnx_hw->vht_cap_2G.vht_mcs.rx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); -+ mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_7; -+ } -+ for (; i < 8; i++) { -+ rwnx_hw->vht_cap_2G.vht_mcs.rx_mcs_map |= cpu_to_le16( -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); -+ } -+ -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, mcs_map_max); -+ rwnx_hw->vht_cap_2G.vht_mcs.tx_mcs_map = cpu_to_le16(0); -+ for (i = 0; i < nss; i++) { -+ rwnx_hw->vht_cap_2G.vht_mcs.tx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); -+ rwnx_hw->vht_cap_2G.vht_mcs.tx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, -+ IEEE80211_VHT_MCS_SUPPORT_0_8); -+ } -+ for (; i < 8; i++) { -+ rwnx_hw->vht_cap_2G.vht_mcs.tx_mcs_map |= cpu_to_le16( -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); -+ } -+ -+ if (!rwnx_hw->mod_params->use_80) { -+#ifdef CONFIG_VENDOR_RWNX_VHT_NO80 -+ rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_NOT_SUP_WIDTH_80; -+#endif//CONFIG_VENDOR_RWNX_VHT_NO80 -+ rwnx_hw->vht_cap_2G.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_80; -+ } -+ -+ rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK; -+ printk("%s, vht_capa_info=0x%x\n", __func__, rwnx_hw->vht_cap_2G.cap); -+#ifdef USE_5G -+ if (rwnx_hw->band_5g_support) { -+ rwnx_hw->vht_cap_5G.vht_supported = true; -+ if (rwnx_hw->mod_params->sgi80) -+ rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_SHORT_GI_80; -+ if (rwnx_hw->mod_params->stbc_on) -+ rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_RXSTBC_1; -+ if (rwnx_hw->mod_params->ldpc_on) -+ rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_RXLDPC; -+ if (rwnx_hw->mod_params->bfmee) { -+ rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ rwnx_hw->vht_cap_5G.cap |= 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; -+ #else -+ rwnx_hw->vht_cap_5G.cap |= 3 << 13; -+ #endif -+ } -+ if (nss > 1) -+ rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_TXSTBC; -+ -+ // Update the AMSDU max RX size (not shifted as located at offset 0 of the VHT cap) -+ rwnx_hw->vht_cap_5G.cap |= rwnx_hw->mod_params->amsdu_rx_max; -+ -+ if (rwnx_hw->mod_params->bfmer) { -+ rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; -+ /* Set number of sounding dimensions */ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ rwnx_hw->vht_cap_5G.cap |= (nss - 1) << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; -+ #else -+ rwnx_hw->vht_cap_5G.cap |= (nss - 1) << 16; -+ #endif -+ } -+ if (rwnx_hw->mod_params->murx) -+ rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; -+ if (rwnx_hw->mod_params->mutx) -+ rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; -+ -+ /* -+ * MCS map: -+ * This capabilities are filled according to the mcs_map module parameter. -+ * However currently we have some limitations due to FPGA clock constraints -+ * that prevent always using the range of MCS that is defined by the -+ * parameter: -+ * - in RX, 2SS, we support up to MCS7 -+ * - in TX, 2SS, we support up to MCS8 -+ */ -+ // Get max supported BW -+ if (rwnx_hw->mod_params->use_80) -+ bw_max = PHY_CHNL_BW_80; -+ else if (rwnx_hw->mod_params->use_2040) -+ bw_max = PHY_CHNL_BW_40; -+ else -+ bw_max = PHY_CHNL_BW_20; -+ -+ // Check if MCS map should be limited to MCS0_8 due to the standard. Indeed in BW20, -+ // MCS9 is not supported in 1 and 2 SS -+ if (rwnx_hw->mod_params->use_2040) -+ mcs_map_max = IEEE80211_VHT_MCS_SUPPORT_0_9; -+ else -+ mcs_map_max = IEEE80211_VHT_MCS_SUPPORT_0_8; -+ -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, mcs_map_max); -+ rwnx_hw->vht_cap_5G.vht_mcs.rx_mcs_map = cpu_to_le16(0); -+ for (i = 0; i < nss; i++) { -+ rwnx_hw->vht_cap_5G.vht_mcs.rx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); -+ rwnx_hw->vht_cap_5G.vht_mcs.rx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); -+ mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_7; -+ } -+ for (; i < 8; i++) { -+ rwnx_hw->vht_cap_5G.vht_mcs.rx_mcs_map |= cpu_to_le16( -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); -+ } -+ -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, mcs_map_max); -+ rwnx_hw->vht_cap_5G.vht_mcs.tx_mcs_map = cpu_to_le16(0); -+ for (i = 0; i < nss; i++) { -+ rwnx_hw->vht_cap_5G.vht_mcs.tx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); -+ rwnx_hw->vht_cap_5G.vht_mcs.tx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, -+ IEEE80211_VHT_MCS_SUPPORT_0_8); -+ } -+ for (; i < 8; i++) { -+ rwnx_hw->vht_cap_5G.vht_mcs.tx_mcs_map |= cpu_to_le16( -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); -+ } -+ -+ if (!rwnx_hw->mod_params->use_80) { -+#ifdef CONFIG_VENDOR_RWNX_VHT_NO80 -+ rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_NOT_SUP_WIDTH_80; -+#endif//CONFIG_VENDOR_RWNX_VHT_NO80 -+ rwnx_hw->vht_cap_5G.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_80; -+ } -+ -+ } -+#endif//USE_5G -+ return; -+#else -+ struct ieee80211_supported_band *band_5GHz = wiphy->bands[NL80211_BAND_5GHZ]; -+ struct ieee80211_supported_band *band_2GHz = wiphy->bands[NL80211_BAND_2GHZ]; -+ -+ int i; -+ int nss = rwnx_hw->mod_params->nss; -+ int mcs_map; -+ int mcs_map_max; -+ int bw_max; -+#endif//CONFIG_VHT_FOR_OLD_KERNEL -+ -+ if (!rwnx_hw->mod_params->vht_on) { -+ return; -+ } -+ -+ -+ band_2GHz->vht_cap.vht_supported = true; -+ if (rwnx_hw->mod_params->sgi80) -+ band_2GHz->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80; -+ if (rwnx_hw->mod_params->stbc_on) -+ band_2GHz->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1; -+ if (rwnx_hw->mod_params->ldpc_on) -+ band_2GHz->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; -+ if (rwnx_hw->mod_params->bfmee) { -+ band_2GHz->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ band_2GHz->vht_cap.cap |= 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; -+ #else -+ band_2GHz->vht_cap.cap |= 3 << 13; -+ #endif -+ } -+ if (nss > 1) -+ band_2GHz->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC; -+ -+ // Update the AMSDU max RX size (not shifted as located at offset 0 of the VHT cap) -+ band_2GHz->vht_cap.cap |= rwnx_hw->mod_params->amsdu_rx_max; -+ -+ if (rwnx_hw->mod_params->bfmer) { -+ band_2GHz->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; -+ /* Set number of sounding dimensions */ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ band_2GHz->vht_cap.cap |= (nss - 1) << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; -+ #else -+ band_2GHz->vht_cap.cap |= (nss - 1) << 16; -+ #endif -+ } -+ if (rwnx_hw->mod_params->murx) -+ band_2GHz->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; -+ if (rwnx_hw->mod_params->mutx) -+ band_2GHz->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; -+ -+ /* -+ * MCS map: -+ * This capabilities are filled according to the mcs_map module parameter. -+ * However currently we have some limitations due to FPGA clock constraints -+ * that prevent always using the range of MCS that is defined by the -+ * parameter: -+ * - in RX, 2SS, we support up to MCS7 -+ * - in TX, 2SS, we support up to MCS8 -+ */ -+ // Get max supported BW -+ if (rwnx_hw->mod_params->use_80) -+ bw_max = PHY_CHNL_BW_80; -+ else if (rwnx_hw->mod_params->use_2040) -+ bw_max = PHY_CHNL_BW_40; -+ else -+ bw_max = PHY_CHNL_BW_20; -+ -+ // Check if MCS map should be limited to MCS0_8 due to the standard. Indeed in BW20, -+ // MCS9 is not supported in 1 and 2 SS -+ if (rwnx_hw->mod_params->use_2040) -+ mcs_map_max = IEEE80211_VHT_MCS_SUPPORT_0_9; -+ else -+ mcs_map_max = IEEE80211_VHT_MCS_SUPPORT_0_8; -+ -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, mcs_map_max); -+ band_2GHz->vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(0); -+ for (i = 0; i < nss; i++) { -+ band_2GHz->vht_cap.vht_mcs.rx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); -+ band_2GHz->vht_cap.vht_mcs.rx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); -+ mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_7; -+ } -+ for (; i < 8; i++) { -+ band_2GHz->vht_cap.vht_mcs.rx_mcs_map |= cpu_to_le16( -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); -+ } -+ -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, mcs_map_max); -+ band_2GHz->vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(0); -+ for (i = 0; i < nss; i++) { -+ band_2GHz->vht_cap.vht_mcs.tx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); -+ band_2GHz->vht_cap.vht_mcs.tx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, -+ IEEE80211_VHT_MCS_SUPPORT_0_8); -+ } -+ for (; i < 8; i++) { -+ band_2GHz->vht_cap.vht_mcs.tx_mcs_map |= cpu_to_le16( -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); -+ } -+ -+ if (!rwnx_hw->mod_params->use_80) { -+#ifdef CONFIG_VENDOR_RWNX_VHT_NO80 -+ band_2GHz->vht_cap.cap |= IEEE80211_VHT_CAP_NOT_SUP_WIDTH_80; -+#endif -+ band_2GHz->vht_cap.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_80; -+ } -+ -+ if (rwnx_hw->band_5g_support) { -+ band_5GHz->vht_cap.vht_supported = true; -+ if (rwnx_hw->mod_params->sgi80) -+ band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80; -+ if (rwnx_hw->mod_params->stbc_on) -+ band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1; -+ if (rwnx_hw->mod_params->ldpc_on) -+ band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; -+ if (rwnx_hw->mod_params->bfmee) { -+ band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ band_5GHz->vht_cap.cap |= 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; -+ #else -+ band_5GHz->vht_cap.cap |= 3 << 13; -+ #endif -+ } -+ if (nss > 1) -+ band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC; -+ -+ // Update the AMSDU max RX size (not shifted as located at offset 0 of the VHT cap) -+ band_5GHz->vht_cap.cap |= rwnx_hw->mod_params->amsdu_rx_max; -+ -+ if (rwnx_hw->mod_params->bfmer) { -+ band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; -+ /* Set number of sounding dimensions */ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ band_5GHz->vht_cap.cap |= (nss - 1) << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; -+ #else -+ band_5GHz->vht_cap.cap |= (nss - 1) << 16; -+ #endif -+ } -+ if (rwnx_hw->mod_params->murx) -+ band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; -+ if (rwnx_hw->mod_params->mutx) -+ band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; -+ -+ /* -+ * MCS map: -+ * This capabilities are filled according to the mcs_map module parameter. -+ * However currently we have some limitations due to FPGA clock constraints -+ * that prevent always using the range of MCS that is defined by the -+ * parameter: -+ * - in RX, 2SS, we support up to MCS7 -+ * - in TX, 2SS, we support up to MCS8 -+ */ -+ // Get max supported BW -+ if (rwnx_hw->mod_params->use_80) -+ bw_max = PHY_CHNL_BW_80; -+ else if (rwnx_hw->mod_params->use_2040) -+ bw_max = PHY_CHNL_BW_40; -+ else -+ bw_max = PHY_CHNL_BW_20; -+ -+ // Check if MCS map should be limited to MCS0_8 due to the standard. Indeed in BW20, -+ // MCS9 is not supported in 1 and 2 SS -+ if (rwnx_hw->mod_params->use_2040) -+ mcs_map_max = IEEE80211_VHT_MCS_SUPPORT_0_9; -+ else -+ mcs_map_max = IEEE80211_VHT_MCS_SUPPORT_0_8; -+ -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, mcs_map_max); -+ band_5GHz->vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(0); -+ for (i = 0; i < nss; i++) { -+ band_5GHz->vht_cap.vht_mcs.rx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); -+ band_5GHz->vht_cap.vht_mcs.rx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); -+ mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_7; -+ } -+ for (; i < 8; i++) { -+ band_5GHz->vht_cap.vht_mcs.rx_mcs_map |= cpu_to_le16( -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); -+ } -+ -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, mcs_map_max); -+ band_5GHz->vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(0); -+ for (i = 0; i < nss; i++) { -+ band_5GHz->vht_cap.vht_mcs.tx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); -+ band_5GHz->vht_cap.vht_mcs.tx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); -+ mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, -+ IEEE80211_VHT_MCS_SUPPORT_0_8); -+ } -+ for (; i < 8; i++) { -+ band_5GHz->vht_cap.vht_mcs.tx_mcs_map |= cpu_to_le16( -+ IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); -+ } -+ -+ if (!rwnx_hw->mod_params->use_80) { -+#ifdef CONFIG_VENDOR_RWNX_VHT_NO80 -+ band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_NOT_SUP_WIDTH_80; -+#endif -+ band_5GHz->vht_cap.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_80; -+ } -+ } -+} -+ -+static void rwnx_set_ht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) -+{ -+ struct ieee80211_supported_band *band_5GHz = wiphy->bands[NL80211_BAND_5GHZ]; -+ struct ieee80211_supported_band *band_2GHz = wiphy->bands[NL80211_BAND_2GHZ]; -+ int i; -+ int nss = rwnx_hw->mod_params->nss; -+ -+ if (!rwnx_hw->mod_params->ht_on) { -+ band_2GHz->ht_cap.ht_supported = false; -+ if (rwnx_hw->band_5g_support) -+ band_5GHz->ht_cap.ht_supported = false; -+ return; -+ } -+ -+ if (rwnx_hw->mod_params->stbc_on) -+ band_2GHz->ht_cap.cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; -+ if (rwnx_hw->mod_params->ldpc_on) -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; -+ if (rwnx_hw->mod_params->use_2040) { -+ band_2GHz->ht_cap.mcs.rx_mask[4] = 0x1; /* MCS32 */ -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; -+ band_2GHz->ht_cap.mcs.rx_highest = cpu_to_le16(135 * nss); -+ } else { -+ band_2GHz->ht_cap.mcs.rx_highest = cpu_to_le16(65 * nss); -+ } -+ if (nss > 1) -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; -+ -+ // Update the AMSDU max RX size -+ if (rwnx_hw->mod_params->amsdu_rx_max) -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU; -+ -+ if (rwnx_hw->mod_params->sgi) { -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; -+ if (rwnx_hw->mod_params->use_2040) { -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; -+ band_2GHz->ht_cap.mcs.rx_highest = cpu_to_le16(150 * nss); -+ } else -+ band_2GHz->ht_cap.mcs.rx_highest = cpu_to_le16(72 * nss); -+ } -+ if (rwnx_hw->mod_params->gf_rx_on) -+ band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD; -+ -+ for (i = 0; i < nss; i++) { -+ band_2GHz->ht_cap.mcs.rx_mask[i] = 0xFF; -+ } -+ -+ if (rwnx_hw->band_5g_support) -+ band_5GHz->ht_cap = band_2GHz->ht_cap; -+} -+ -+#ifdef CONFIG_HE_FOR_OLD_KERNEL -+extern struct ieee80211_sband_iftype_data rwnx_he_capa; -+#endif -+static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) -+{ -+#ifdef CONFIG_HE_FOR_OLD_KERNEL -+ struct ieee80211_sta_he_cap *he_cap; -+ int i; -+ int nss = rwnx_hw->mod_params->nss; -+ int mcs_map; -+ -+ he_cap = (struct ieee80211_sta_he_cap *) &rwnx_he_capa.he_cap; -+ he_cap->has_he = true; -+ he_cap->he_cap_elem.mac_cap_info[2] |= IEEE80211_HE_MAC_CAP2_ALL_ACK; -+ if (rwnx_hw->mod_params->use_2040) { -+ he_cap->he_cap_elem.phy_cap_info[0] |= -+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; -+ he_cap->ppe_thres[0] |= 0x10; -+ } -+ if (rwnx_hw->mod_params->use_80) { -+ he_cap->ppe_thres[0] |= 0x20; -+ he_cap->ppe_thres[2] |= 0xc0; -+ he_cap->ppe_thres[3] |= 0x07; -+ } -+ //if (rwnx_hw->mod_params->use_80) -+ { -+ he_cap->he_cap_elem.phy_cap_info[0] |= -+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; -+ } -+ if (rwnx_hw->mod_params->ldpc_on) { -+ he_cap->he_cap_elem.phy_cap_info[1] |= IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; -+ } else { -+ // If no LDPC is supported, we have to limit to MCS0_9, as LDPC is mandatory -+ // for MCS 10 and 11 -+ rwnx_hw->mod_params->he_mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, -+ IEEE80211_HE_MCS_SUPPORT_0_9); -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) -+ he_cap->he_cap_elem.phy_cap_info[1] |= IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US -+ | IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS; -+ -+ he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS | -+ IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | -+ IEEE80211_HE_PHY_CAP2_DOPPLER_RX; -+ #else -+ he_cap->he_cap_elem.phy_cap_info[1] |= IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US; -+ he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | -+ IEEE80211_HE_PHY_CAP2_DOPPLER_RX; -+ #endif -+ if (rwnx_hw->mod_params->stbc_on) -+ he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ; -+ he_cap->he_cap_elem.phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM | -+ IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 | -+ IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA; -+ if (rwnx_hw->mod_params->bfmee) { -+ he_cap->he_cap_elem.phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE; -+ he_cap->he_cap_elem.phy_cap_info[4] |= -+ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4; -+ } -+ he_cap->he_cap_elem.phy_cap_info[5] |= IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK | -+ IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK; -+ he_cap->he_cap_elem.phy_cap_info[6] |= IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | -+ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | -+ IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB | -+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB | -+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT | -+ IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO; -+ he_cap->he_cap_elem.phy_cap_info[7] |= IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; -+ he_cap->he_cap_elem.phy_cap_info[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G; -+ he_cap->he_cap_elem.phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | -+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB; -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80) -+ mcs_map = rwnx_hw->mod_params->he_mcs_map; -+ else if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801 || rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW) -+ mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_9); -+ memset(&he_cap->he_mcs_nss_supp, 0, sizeof(he_cap->he_mcs_nss_supp)); -+ for (i = 0; i < nss; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.rx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); -+ he_cap->he_mcs_nss_supp.rx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.rx_mcs_80p80 |= unsup_for_ss; -+ mcs_map = IEEE80211_HE_MCS_SUPPORT_0_7; -+ } -+ for (; i < 8; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.rx_mcs_80 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.rx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.rx_mcs_80p80 |= unsup_for_ss; -+ } -+ mcs_map = rwnx_hw->mod_params->he_mcs_map; -+ for (i = 0; i < nss; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.tx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); -+ he_cap->he_mcs_nss_supp.tx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.tx_mcs_80p80 |= unsup_for_ss; -+ mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, -+ IEEE80211_HE_MCS_SUPPORT_0_7); -+ } -+ for (; i < 8; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.tx_mcs_80 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.tx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.tx_mcs_80p80 |= unsup_for_ss; -+ } -+ -+ return ; -+ #endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ struct ieee80211_supported_band *band_5GHz = wiphy->bands[NL80211_BAND_5GHZ]; -+ struct ieee80211_supported_band *band_2GHz = wiphy->bands[NL80211_BAND_2GHZ]; -+ int i; -+ int nss = rwnx_hw->mod_params->nss; -+ struct ieee80211_sta_he_cap *he_cap; -+ int mcs_map; -+ if (!rwnx_hw->mod_params->he_on) { -+ band_2GHz->iftype_data = NULL; -+ band_2GHz->n_iftype_data = 0; -+ if (rwnx_hw->band_5g_support) { -+ band_5GHz->iftype_data = NULL; -+ band_5GHz->n_iftype_data = 0; -+ } -+ return; -+ } -+ he_cap = (struct ieee80211_sta_he_cap *) &band_2GHz->iftype_data->he_cap; -+ he_cap->has_he = true; -+ he_cap->he_cap_elem.mac_cap_info[2] |= IEEE80211_HE_MAC_CAP2_ALL_ACK; -+ if (rwnx_hw->mod_params->use_2040) { -+ he_cap->he_cap_elem.phy_cap_info[0] |= -+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; -+ he_cap->ppe_thres[0] |= 0x10; -+ } -+ if (rwnx_hw->mod_params->use_80) { -+ he_cap->ppe_thres[0] |= 0x20; -+ he_cap->ppe_thres[2] |= 0xc0; -+ he_cap->ppe_thres[3] |= 0x07; -+ } -+ //if (rwnx_hw->mod_params->use_80) -+ { -+ he_cap->he_cap_elem.phy_cap_info[0] |= -+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; -+ } -+ if (rwnx_hw->mod_params->ldpc_on) { -+ he_cap->he_cap_elem.phy_cap_info[1] |= IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; -+ } else { -+ // If no LDPC is supported, we have to limit to MCS0_9, as LDPC is mandatory -+ // for MCS 10 and 11 -+ rwnx_hw->mod_params->he_mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, -+ IEEE80211_HE_MCS_SUPPORT_0_9); -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) -+ he_cap->he_cap_elem.phy_cap_info[1] |= IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US -+ | IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS; -+ -+ he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS | -+ IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | -+ IEEE80211_HE_PHY_CAP2_DOPPLER_RX; -+ #else -+ he_cap->he_cap_elem.phy_cap_info[1] |= IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US; -+ he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | -+ IEEE80211_HE_PHY_CAP2_DOPPLER_RX; -+ #endif -+ if (rwnx_hw->mod_params->stbc_on) -+ he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ; -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) -+ he_cap->he_cap_elem.phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM | -+ IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 | -+ IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU; -+ #else -+ he_cap->he_cap_elem.phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM | -+ IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 | -+ IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA; -+ #endif -+ -+ -+ if (rwnx_hw->mod_params->bfmee) { -+ he_cap->he_cap_elem.phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE; -+ he_cap->he_cap_elem.phy_cap_info[4] |= -+ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4; -+ } -+ he_cap->he_cap_elem.phy_cap_info[5] |= IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK | -+ IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) -+ he_cap->he_cap_elem.phy_cap_info[6] |= IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | -+ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | -+ IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | -+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB | -+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT | -+ IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO; -+ #else -+ he_cap->he_cap_elem.phy_cap_info[6] |= IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | -+ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | -+ IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB | -+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB | -+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT | -+ IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO; -+ #endif -+ -+ he_cap->he_cap_elem.phy_cap_info[7] |= IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; -+ he_cap->he_cap_elem.phy_cap_info[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) -+ he_cap->he_cap_elem.phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | -+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB; -+ #endif -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ mcs_map = rwnx_hw->mod_params->he_mcs_map; -+ } -+ else if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801 || rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_9); -+ } -+ memset(&he_cap->he_mcs_nss_supp, 0, sizeof(he_cap->he_mcs_nss_supp)); -+ for (i = 0; i < nss; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.rx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); -+ he_cap->he_mcs_nss_supp.rx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.rx_mcs_80p80 |= unsup_for_ss; -+ mcs_map = IEEE80211_HE_MCS_SUPPORT_0_7; -+ } -+ for (; i < 8; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.rx_mcs_80 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.rx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.rx_mcs_80p80 |= unsup_for_ss; -+ } -+ mcs_map = rwnx_hw->mod_params->he_mcs_map; -+ for (i = 0; i < nss; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.tx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); -+ he_cap->he_mcs_nss_supp.tx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.tx_mcs_80p80 |= unsup_for_ss; -+ mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, -+ IEEE80211_HE_MCS_SUPPORT_0_7); -+ } -+ for (; i < 8; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.tx_mcs_80 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.tx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.tx_mcs_80p80 |= unsup_for_ss; -+ } -+ -+ if (rwnx_hw->band_5g_support) { -+ he_cap = (struct ieee80211_sta_he_cap *) &band_5GHz->iftype_data->he_cap; -+ he_cap->has_he = true; -+ he_cap->he_cap_elem.mac_cap_info[2] |= IEEE80211_HE_MAC_CAP2_ALL_ACK; -+ if (rwnx_hw->mod_params->use_2040) { -+ he_cap->he_cap_elem.phy_cap_info[0] |= -+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; -+ he_cap->ppe_thres[0] |= 0x10; -+ } -+ if (rwnx_hw->mod_params->use_80) { -+ he_cap->ppe_thres[0] |= 0x20; -+ he_cap->ppe_thres[2] |= 0xc0; -+ he_cap->ppe_thres[3] |= 0x07; -+ } -+ //if (rwnx_hw->mod_params->use_80) -+ { -+ he_cap->he_cap_elem.phy_cap_info[0] |= -+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; -+ } -+ if (rwnx_hw->mod_params->ldpc_on) { -+ he_cap->he_cap_elem.phy_cap_info[1] |= IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; -+ } else { -+ // If no LDPC is supported, we have to limit to MCS0_9, as LDPC is mandatory -+ // for MCS 10 and 11 -+ rwnx_hw->mod_params->he_mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, -+ IEEE80211_HE_MCS_SUPPORT_0_9); -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) -+ he_cap->he_cap_elem.phy_cap_info[1] |= IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US | -+ IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS; -+ he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS | -+ IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | -+ IEEE80211_HE_PHY_CAP2_DOPPLER_RX; -+ #else -+ he_cap->he_cap_elem.phy_cap_info[1] |= IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US; -+ he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | -+ IEEE80211_HE_PHY_CAP2_DOPPLER_RX; -+ #endif -+ if (rwnx_hw->mod_params->stbc_on) -+ he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) -+ he_cap->he_cap_elem.phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM | -+ IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 | -+ IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU; -+ #else -+ he_cap->he_cap_elem.phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM | -+ IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 | -+ IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA; -+ #endif -+ -+ if (rwnx_hw->mod_params->bfmee) { -+ he_cap->he_cap_elem.phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE; -+ he_cap->he_cap_elem.phy_cap_info[4] |= -+ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4; -+ } -+ he_cap->he_cap_elem.phy_cap_info[5] |= IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK | -+ IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) -+ he_cap->he_cap_elem.phy_cap_info[6] |= IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | -+ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | -+ IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | -+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB | -+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT | -+ IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO; -+ #else -+ he_cap->he_cap_elem.phy_cap_info[6] |= IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | -+ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | -+ IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB | -+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB | -+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT | -+ IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO; -+ #endif -+ -+ he_cap->he_cap_elem.phy_cap_info[7] |= IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; -+ he_cap->he_cap_elem.phy_cap_info[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) -+ he_cap->he_cap_elem.phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | -+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB; -+ #endif -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80) -+ mcs_map = rwnx_hw->mod_params->he_mcs_map; -+ else if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801 || rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW) -+ mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_9); -+ memset(&he_cap->he_mcs_nss_supp, 0, sizeof(he_cap->he_mcs_nss_supp)); -+ for (i = 0; i < nss; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.rx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); -+ he_cap->he_mcs_nss_supp.rx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.rx_mcs_80p80 |= unsup_for_ss; -+ mcs_map = IEEE80211_HE_MCS_SUPPORT_0_7; -+ } -+ for (; i < 8; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.rx_mcs_80 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.rx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.rx_mcs_80p80 |= unsup_for_ss; -+ } -+ mcs_map = rwnx_hw->mod_params->he_mcs_map; -+ for (i = 0; i < nss; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.tx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); -+ he_cap->he_mcs_nss_supp.tx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.tx_mcs_80p80 |= unsup_for_ss; -+ mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, -+ IEEE80211_HE_MCS_SUPPORT_0_7); -+ } -+ for (; i < 8; i++) { -+ __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); -+ he_cap->he_mcs_nss_supp.tx_mcs_80 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.tx_mcs_160 |= unsup_for_ss; -+ he_cap->he_mcs_nss_supp.tx_mcs_80p80 |= unsup_for_ss; -+ } -+ } -+#endif -+} -+ -+static void rwnx_set_wiphy_params(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) -+{ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) -+ struct ieee80211_regdomain *regdomain; -+#endif -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ /* FULLMAC specific parameters */ -+ wiphy->flags |= WIPHY_FLAG_REPORTS_OBSS; -+ wiphy->max_scan_ssids = SCAN_SSID_MAX; -+ wiphy->max_scan_ie_len = SCANU_MAX_IE_LEN; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ if (rwnx_hw->mod_params->tdls) { -+ /* TDLS support */ -+ wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; -+#ifdef CONFIG_RWNX_FULLMAC -+ /* TDLS external setup support */ -+ wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; -+#endif -+ } -+ -+ if (rwnx_hw->mod_params->ap_uapsd_on) -+ wiphy->flags |= WIPHY_FLAG_AP_UAPSD; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ if (rwnx_hw->mod_params->ps_on) -+ wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; -+ else -+ wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; -+#endif -+ -+if (rwnx_hw->mod_params->custregd) { -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+ // Apply custom regulatory. Note that for recent kernel versions we use instead the -+ // REGULATORY_WIPHY_SELF_MANAGED flag, along with the regulatory_set_wiphy_regd() -+ // function, that needs to be called after wiphy registration -+ memcpy(country_code, default_ccode, sizeof(default_ccode)); -+ regdomain = getRegdomainFromRwnxDB(wiphy, default_ccode); -+ printk(KERN_CRIT -+ "\n\n%s: CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES\n\n", -+ __func__); -+ wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; -+ wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; -+ wiphy_apply_custom_regulatory(wiphy, regdomain); -+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) -+ memcpy(country_code, default_ccode, sizeof(default_ccode)); -+ regdomain = getRegdomainFromRwnxDB(wiphy, default_ccode); -+ printk(KERN_CRIT"%s: Registering custom regulatory\n", __func__); -+ wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; -+ wiphy_apply_custom_regulatory(wiphy, regdomain); -+#endif -+ // Check if custom channel set shall be enabled. In such case only monitor mode is -+ // supported -+ if (rwnx_hw->mod_params->custchan) { -+ wiphy->interface_modes = BIT(NL80211_IFTYPE_MONITOR); -+ -+ // Enable "extra" channels -+ wiphy->bands[NL80211_BAND_2GHZ]->n_channels += 13; -+ //#ifdef USE_5G -+ if(rwnx_hw->band_5g_support){ -+ wiphy->bands[NL80211_BAND_5GHZ]->n_channels += 59; -+ } -+ //#endif -+ } -+ } -+ -+#if 0 -+ if (rwnx_hw->mod_params->custregd) { -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+ // Apply custom regulatory. Note that for recent kernel versions we use instead the -+ // REGULATORY_WIPHY_SELF_MANAGED flag, along with the regulatory_set_wiphy_regd() -+ // function, that needs to be called after wiphy registration -+ printk(KERN_CRIT -+ "\n\n%s: CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES\n\n", -+ __func__); -+ wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; -+ wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; -+ wiphy_apply_custom_regulatory(wiphy, &rwnx_regdom); -+#endif -+ // Check if custom channel set shall be enabled. In such case only monitor mode is -+ // supported -+ if (rwnx_hw->mod_params->custchan) { -+ wiphy->interface_modes = BIT(NL80211_IFTYPE_MONITOR); -+ -+ // Enable "extra" channels -+ wiphy->bands[NL80211_BAND_2GHZ]->n_channels += 13; -+ if (rwnx_hw->band_5g_support) -+ wiphy->bands[NL80211_BAND_5GHZ]->n_channels += 59; -+ } -+ } -+#endif -+} -+ -+#if 0 -+static void rwnx_set_rf_params(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) -+{ -+#ifndef CONFIG_RWNX_SDM -+ struct ieee80211_supported_band *band_5GHz = wiphy->bands[NL80211_BAND_5GHZ]; -+ struct ieee80211_supported_band *band_2GHz = wiphy->bands[NL80211_BAND_2GHZ]; -+ u32 mdm_phy_cfg = __MDM_PHYCFG_FROM_VERS(rwnx_hw->version_cfm.version_phy_1); -+ -+ /* -+ * Get configuration file depending on the RF -+ */ -+ if (mdm_phy_cfg == MDM_PHY_CONFIG_TRIDENT) { -+ struct rwnx_phy_conf_file phy_conf; -+ // Retrieve the Trident configuration -+ rwnx_parse_phy_configfile(rwnx_hw, RWNX_PHY_CONFIG_TRD_NAME, -+ &phy_conf, rwnx_hw->mod_params->phy_cfg); -+ memcpy(&rwnx_hw->phy.cfg, &phy_conf.trd, sizeof(phy_conf.trd)); -+ } else if (mdm_phy_cfg == MDM_PHY_CONFIG_ELMA) { -+ } else if (mdm_phy_cfg == MDM_PHY_CONFIG_KARST) { -+ struct rwnx_phy_conf_file phy_conf; -+ // We use the NSS parameter as is -+ // Retrieve the Karst configuration -+ rwnx_parse_phy_configfile(rwnx_hw, RWNX_PHY_CONFIG_KARST_NAME, -+ &phy_conf, rwnx_hw->mod_params->phy_cfg); -+ -+ memcpy(&rwnx_hw->phy.cfg, &phy_conf.karst, sizeof(phy_conf.karst)); -+ } else { -+ WARN_ON(1); -+ } -+ -+ /* -+ * adjust caps depending on the RF -+ */ -+ switch (mdm_phy_cfg) { -+ case MDM_PHY_CONFIG_TRIDENT: -+ { -+ wiphy_dbg(wiphy, "found Trident phy .. limit BW to 40MHz\n"); -+ rwnx_hw->phy.limit_bw = true; -+ if (rwnx_hw->band_5g_support) { -+#ifdef CONFIG_VENDOR_RWNX_VHT_NO80 -+ band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_NOT_SUP_WIDTH_80; -+#endif -+ band_5GHz->vht_cap.cap &= ~(IEEE80211_VHT_CAP_SHORT_GI_80 | -+ IEEE80211_VHT_CAP_RXSTBC_MASK); -+ } -+ break; -+ } -+ case MDM_PHY_CONFIG_ELMA: -+ wiphy_dbg(wiphy, "found ELMA phy .. disabling 2.4GHz and greenfield rx\n"); -+ wiphy->bands[NL80211_BAND_2GHZ] = NULL; -+ band_2GHz->ht_cap.cap &= ~IEEE80211_HT_CAP_GRN_FLD; -+ if (rwnx_hw->band_5g_support) { -+ band_5GHz->ht_cap.cap &= ~IEEE80211_HT_CAP_GRN_FLD; -+ band_5GHz->vht_cap.cap &= ~IEEE80211_VHT_CAP_RXSTBC_MASK; -+ } -+ break; -+ case MDM_PHY_CONFIG_KARST: -+ { -+ wiphy_dbg(wiphy, "found KARST phy\n"); -+ break; -+ } -+ default: -+ WARN_ON(1); -+ break; -+ } -+#endif /* CONFIG_RWNX_SDM */ -+} -+#endif -+ -+int rwnx_handle_dynparams(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) -+{ -+#if 0 -+ /* Check compatibility between requested parameters and HW/SW features */ -+ int ret; -+ -+ ret = rwnx_check_fw_hw_feature(rwnx_hw, wiphy); -+ if (ret) -+ return ret; -+ -+ /* Allocate the RX buffers according to the maximum AMSDU RX size */ -+ ret = rwnx_ipc_rxbuf_init(rwnx_hw, -+ (4 * (rwnx_hw->mod_params->amsdu_rx_max + 1) + 1) * 1024); -+ if (ret) { -+ wiphy_err(wiphy, "Cannot allocate the RX buffers\n"); -+ return ret; -+ } -+#endif -+ -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80) { -+ rwnx_hw->mod_params->sgi80 = true; -+ rwnx_hw->mod_params->use_80 = true; -+ } -+ -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80) { -+ rwnx_hw->mod_params->use_80 = true; -+ } -+ -+ if (rwnx_hw->sdiodev->chipid != PRODUCT_ID_AIC8800D80 && -+ rwnx_hw->mod_params->he_mcs_map == IEEE80211_HE_MCS_SUPPORT_0_11) { -+ AICWFDBG(LOGINFO,"%s unsupport mcs11 change to mcs9", __func__); -+ rwnx_hw->mod_params->he_mcs_map = IEEE80211_HE_MCS_SUPPORT_0_9; -+ } -+ -+ /* Set wiphy parameters */ -+ rwnx_set_wiphy_params(rwnx_hw, wiphy); -+ /* Set VHT capabilities */ -+ rwnx_set_vht_capa(rwnx_hw, wiphy); -+ /* Set HE capabilities */ -+ rwnx_set_he_capa(rwnx_hw, wiphy); -+ /* Set HT capabilities */ -+ rwnx_set_ht_capa(rwnx_hw, wiphy); -+ /* Set RF specific parameters (shall be done last as it might change some -+ capabilities previously set) */ -+#if 0 -+ rwnx_set_rf_params(rwnx_hw, wiphy); -+#endif -+ return 0; -+} -+ -+void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) -+{ -+// For older kernel version, the custom regulatory is applied before the wiphy -+// registration (in rwnx_set_wiphy_params()), so nothing has to be done here -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) -+ if (!rwnx_hw->mod_params->custregd) -+ return; -+ -+ wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; -+ wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED; -+ -+ rtnl_lock(); -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) -+ if (regulatory_set_wiphy_regd_sync(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){ -+ wiphy_err(wiphy, "Failed to set custom regdomain\n"); -+ } -+ #else -+ if (regulatory_set_wiphy_regd_sync_rtnl(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){ -+ wiphy_err(wiphy, "Failed to set custom regdomain\n"); -+ } -+ #endif -+ -+ else{ -+ wiphy_err(wiphy,"\n" -+ "*******************************************************\n" -+ "** CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES **\n" -+ "*******************************************************\n"); -+ } -+ rtnl_unlock(); -+#endif -+ -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,70 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_mod_params.h -+ * -+ * @brief Declaration of module parameters -+ * -+ * Copyright (C) RivieraWaves 2012-2021 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _RWNX_MOD_PARAM_H_ -+#define _RWNX_MOD_PARAM_H_ -+ -+struct rwnx_mod_params { -+ bool ht_on; -+ bool vht_on; -+ bool he_on; -+ int mcs_map; -+ int he_mcs_map; -+ bool he_ul_on; -+ bool ldpc_on; -+ bool stbc_on; -+ bool gf_rx_on; -+ int phy_cfg; -+ int uapsd_timeout; -+ bool ap_uapsd_on; -+ bool sgi; -+ bool sgi80; -+ bool use_2040; -+ bool use_80; -+ bool custregd; -+ bool custchan; -+ int nss; -+ int amsdu_rx_max; -+ bool bfmee; -+ bool bfmer; -+ bool mesh; -+ bool murx; -+ bool mutx; -+ bool mutx_on; -+ unsigned int roc_dur_max; -+ int listen_itv; -+ bool listen_bcmc; -+ int lp_clk_ppm; -+ bool ps_on; -+ int tx_lft; -+ int amsdu_maxnb; -+ int uapsd_queues; -+ bool tdls; -+ bool uf; -+ bool auto_reply; -+ char *ftl; -+ bool dpsm; -+#ifdef CONFIG_RWNX_FULLMAC -+ bool ant_div; -+#endif /* CONFIG_RWNX_FULLMAC */ -+}; -+ -+extern struct rwnx_mod_params rwnx_mod_params; -+ -+struct rwnx_hw; -+struct wiphy; -+int rwnx_handle_dynparams(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy); -+void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy); -+void rwnx_enable_wapi(struct rwnx_hw *rwnx_hw); -+void rwnx_enable_mfp(struct rwnx_hw *rwnx_hw); -+ -+#endif /* _RWNX_MOD_PARAM_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_rx.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_rx.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_rx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_rx.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,1567 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_msg_rx.c -+ * -+ * @brief RX function definitions -+ * -+ * Copyright (C) RivieraWaves 2012-2021 -+ * -+ **************************************************************************************** -+ */ -+#include -+#include "rwnx_defs.h" -+#include "rwnx_prof.h" -+#include "rwnx_tx.h" -+#ifdef CONFIG_RWNX_BFMER -+#include "rwnx_bfmer.h" -+#endif //(CONFIG_RWNX_BFMER) -+#ifdef CONFIG_RWNX_FULLMAC -+#include "rwnx_debugfs.h" -+#include "rwnx_msg_tx.h" -+#include "rwnx_tdls.h" -+#endif /* CONFIG_RWNX_FULLMAC */ -+#include "rwnx_events.h" -+#include "rwnx_compat.h" -+#include "aicwf_txrxif.h" -+#include "rwnx_msg_rx.h" -+#ifdef CONFIG_SDIO_BT -+#include "aic_btsdio.h" -+#endif -+void rwnx_cfg80211_unlink_bss(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif); -+ -+static int rwnx_freq_to_idx(struct rwnx_hw *rwnx_hw, int freq) -+{ -+ struct ieee80211_supported_band *sband = NULL; -+ int band, ch, idx = 0; -+ -+ for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { -+#ifdef CONFIG_RWNX_FULLMAC -+ sband = rwnx_hw->wiphy->bands[band]; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ if (!sband) { -+ continue; -+ } -+ -+ for (ch = 0; ch < sband->n_channels; ch++, idx++) { -+ if (sband->channels[ch].center_freq == freq) { -+ goto exit; -+ } -+ } -+ } -+ -+ BUG_ON(1); -+ -+exit: -+ // Channel has been found, return the index -+ return idx; -+} -+ -+/*************************************************************************** -+ * Messages from MM task -+ **************************************************************************/ -+static inline int rwnx_rx_chan_pre_switch_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct rwnx_vif *rwnx_vif; -+ int chan_idx = ((struct mm_channel_pre_switch_ind *)msg->param)->chan_index; -+ -+ REG_SW_SET_PROFILING_CHAN(rwnx_hw, SW_PROF_CHAN_CTXT_PSWTCH_BIT); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) { -+ if (rwnx_vif->up && rwnx_vif->ch_index == chan_idx) { -+ rwnx_txq_vif_stop(rwnx_vif, RWNX_TXQ_STOP_CHAN, rwnx_hw); -+ } -+ } -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ REG_SW_CLEAR_PROFILING_CHAN(rwnx_hw, SW_PROF_CHAN_CTXT_PSWTCH_BIT); -+ -+ return 0; -+} -+ -+static inline int rwnx_rx_chan_switch_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct rwnx_vif *rwnx_vif; -+ int chan_idx = ((struct mm_channel_switch_ind *)msg->param)->chan_index; -+ bool roc = ((struct mm_channel_switch_ind *)msg->param)->roc; -+ bool roc_tdls = ((struct mm_channel_switch_ind *)msg->param)->roc_tdls; -+ -+ REG_SW_SET_PROFILING_CHAN(rwnx_hw, SW_PROF_CHAN_CTXT_SWTCH_BIT); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ if (roc_tdls) { -+ u8 vif_index = ((struct mm_channel_switch_ind *)msg->param)->vif_index; -+ list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) { -+ if (rwnx_vif->vif_index == vif_index) { -+ rwnx_vif->roc_tdls = true; -+ rwnx_txq_tdls_sta_start(rwnx_vif, RWNX_TXQ_STOP_CHAN, rwnx_hw); -+ } -+ } -+ } else if (!roc) { -+ list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) { -+ if (rwnx_vif->up && rwnx_vif->ch_index == chan_idx) { -+ rwnx_txq_vif_start(rwnx_vif, RWNX_TXQ_STOP_CHAN, rwnx_hw); -+ } -+ } -+ } else { -+ /* Retrieve the allocated RoC element */ -+ struct rwnx_roc_elem *roc_elem = rwnx_hw->roc_elem; -+ /* Get VIF on which RoC has been started */ -+ //rwnx_vif = netdev_priv(roc_elem->wdev->netdev); -+ -+ /* For debug purpose (use ftrace kernel option) */ -+ //trace_switch_roc(rwnx_vif->vif_index); -+ -+ if(roc_elem) { -+ /* If mgmt_roc is true, remain on channel has been started by ourself */ -+ if (!roc_elem->mgmt_roc) { -+ /* Inform the host that we have switch on the indicated off-channel */ -+ cfg80211_ready_on_channel(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt), -+ roc_elem->chan, roc_elem->duration, GFP_ATOMIC); -+ } -+ -+ /* Keep in mind that we have switched on the channel */ -+ roc_elem->on_chan = true; -+ } else { -+ printk("roc_elem == null\n"); -+ } -+ // Enable traffic on OFF channel queue -+ rwnx_txq_offchan_start(rwnx_hw); -+ } -+ -+ tasklet_schedule(&rwnx_hw->task); -+ -+ rwnx_hw->cur_chanctx = chan_idx; -+ rwnx_radar_detection_enable_on_cur_channel(rwnx_hw); -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ REG_SW_CLEAR_PROFILING_CHAN(rwnx_hw, SW_PROF_CHAN_CTXT_SWTCH_BIT); -+ -+ return 0; -+} -+ -+static inline int rwnx_rx_tdls_chan_switch_cfm(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ return 0; -+} -+ -+static inline int rwnx_rx_tdls_chan_switch_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+#ifdef CONFIG_RWNX_FULLMAC -+ // Enable traffic on OFF channel queue -+ rwnx_txq_offchan_start(rwnx_hw); -+ -+ return 0; -+#endif -+} -+ -+static inline int rwnx_rx_tdls_chan_switch_base_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct rwnx_vif *rwnx_vif; -+ u8 vif_index = ((struct tdls_chan_switch_base_ind *)msg->param)->vif_index; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) { -+ if (rwnx_vif->vif_index == vif_index) { -+ rwnx_vif->roc_tdls = false; -+ rwnx_txq_tdls_sta_stop(rwnx_vif, RWNX_TXQ_STOP_CHAN, rwnx_hw); -+ } -+ } -+ return 0; -+#endif -+} -+ -+static inline int rwnx_rx_tdls_peer_ps_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct rwnx_vif *rwnx_vif; -+ u8 vif_index = ((struct tdls_peer_ps_ind *)msg->param)->vif_index; -+ bool ps_on = ((struct tdls_peer_ps_ind *)msg->param)->ps_on; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) { -+ if (rwnx_vif->vif_index == vif_index) { -+ rwnx_vif->sta.tdls_sta->tdls.ps_on = ps_on; -+ // Update PS status for the TDLS station -+ rwnx_ps_bh_enable(rwnx_hw, rwnx_vif->sta.tdls_sta, ps_on); -+ } -+ } -+ -+ return 0; -+#endif -+} -+ -+static inline int rwnx_rx_remain_on_channel_exp_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+#ifdef CONFIG_RWNX_FULLMAC -+ /* Retrieve the allocated RoC element */ -+ struct rwnx_roc_elem *roc_elem = rwnx_hw->roc_elem; -+ /* Get VIF on which RoC has been started */ -+ struct rwnx_vif *rwnx_vif; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (!roc_elem) -+ return 0; -+ -+ rwnx_vif = container_of(roc_elem->wdev, struct rwnx_vif, wdev); -+ /* For debug purpose (use ftrace kernel option) */ -+#ifdef CREATE_TRACE_POINTS -+ trace_roc_exp(rwnx_vif->vif_index); -+#endif -+ /* If mgmt_roc is true, remain on channel has been started by ourself */ -+ /* If RoC has been cancelled before we switched on channel, do not call cfg80211 */ -+ if (!roc_elem->mgmt_roc && roc_elem->on_chan) { -+ /* Inform the host that off-channel period has expired */ -+ cfg80211_remain_on_channel_expired(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt), -+ roc_elem->chan, GFP_ATOMIC); -+ } -+ -+ /* De-init offchannel TX queue */ -+ rwnx_txq_offchan_deinit(rwnx_vif); -+ -+ /* Increase the cookie counter cannot be zero */ -+ rwnx_hw->roc_cookie_cnt++; -+ -+ if (rwnx_hw->roc_cookie_cnt == 0) { -+ rwnx_hw->roc_cookie_cnt = 1; -+ } -+ -+ /* Free the allocated RoC element */ -+ kfree(roc_elem); -+ rwnx_hw->roc_elem = NULL; -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ return 0; -+} -+ -+static inline int rwnx_rx_p2p_vif_ps_change_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ int vif_idx = ((struct mm_p2p_vif_ps_change_ind *)msg->param)->vif_index; -+ int ps_state = ((struct mm_p2p_vif_ps_change_ind *)msg->param)->ps_state; -+ struct rwnx_vif *vif_entry; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ vif_entry = rwnx_hw->vif_table[vif_idx]; -+ -+ if (vif_entry) { -+ goto found_vif; -+ } -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ goto exit; -+ -+found_vif: -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ if (ps_state == MM_PS_MODE_OFF) { -+ // Start TX queues for provided VIF -+ rwnx_txq_vif_start(vif_entry, RWNX_TXQ_STOP_VIF_PS, rwnx_hw); -+ } else { -+ // Stop TX queues for provided VIF -+ rwnx_txq_vif_stop(vif_entry, RWNX_TXQ_STOP_VIF_PS, rwnx_hw); -+ } -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+exit: -+ return 0; -+} -+ -+static inline int rwnx_rx_channel_survey_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_channel_survey_ind *ind = (struct mm_channel_survey_ind *)msg->param; -+ // Get the channel index -+ int idx = rwnx_freq_to_idx(rwnx_hw, ind->freq); -+ // Get the survey -+ struct rwnx_survey_info *rwnx_survey; -+ -+ if (idx > ARRAY_SIZE(rwnx_hw->survey)) -+ return 0; -+ -+ rwnx_survey = &rwnx_hw->survey[idx]; -+ -+ // Store the received parameters -+ rwnx_survey->chan_time_ms = ind->chan_time_ms; -+ rwnx_survey->chan_time_busy_ms = ind->chan_time_busy_ms; -+ rwnx_survey->noise_dbm = ind->noise_dbm; -+ rwnx_survey->filled = (SURVEY_INFO_TIME | -+ SURVEY_INFO_TIME_BUSY); -+ -+ if (ind->noise_dbm != 0) { -+ rwnx_survey->filled |= SURVEY_INFO_NOISE_DBM; -+ } -+ -+ return 0; -+} -+ -+static inline int rwnx_rx_p2p_noa_upd_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ return 0; -+} -+ -+static inline int rwnx_rx_rssi_status_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_rssi_status_ind *ind = (struct mm_rssi_status_ind *)msg->param; -+ int vif_idx = ind->vif_index; -+ bool rssi_status = ind->rssi_status; -+ -+ struct rwnx_vif *vif_entry; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+vif_entry = rwnx_hw->vif_table[vif_idx]; -+ if (vif_entry) { -+ cfg80211_cqm_rssi_notify(vif_entry->ndev, -+ rssi_status ? NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW : -+ NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, -+ ind->rssi, GFP_ATOMIC); -+ } -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ return 0; -+} -+ -+static inline int rwnx_rx_pktloss_notify_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+#ifdef CONFIG_RWNX_FULLMAC -+ struct mm_pktloss_ind *ind = (struct mm_pktloss_ind *)msg->param; -+ struct rwnx_vif *vif_entry; -+ int vif_idx = ind->vif_index; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ vif_entry = rwnx_hw->vif_table[vif_idx]; -+ if (vif_entry) { -+ cfg80211_cqm_pktloss_notify(vif_entry->ndev, (const u8 *)ind->mac_addr.array, -+ ind->num_packets, GFP_ATOMIC); -+ } -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ return 0; -+} -+ -+static inline int rwnx_apm_staloss_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_apm_staloss_ind *ind = (struct mm_apm_staloss_ind *)msg->param; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ memcpy(rwnx_hw->sta_mac_addr, ind->mac_addr, 6); -+ rwnx_hw->apm_vif_idx = ind->vif_idx; -+ -+ queue_work(rwnx_hw->apmStaloss_wq, &rwnx_hw->apmStalossWork); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SDIO_BT -+static inline int rwnx_bt_recv_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_bt_recv_ind *ind = (struct mm_bt_recv_ind *)msg->param; -+ -+ bt_sdio_recv(ind->bt_data,ind->data_len); -+ return 0; -+} -+#endif -+ -+static inline int rwnx_rx_csa_counter_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_csa_counter_ind *ind = (struct mm_csa_counter_ind *)msg->param; -+ struct rwnx_vif *vif; -+ bool found = false; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ // Look for VIF entry -+ list_for_each_entry(vif, &rwnx_hw->vifs, list) { -+ if (vif->vif_index == ind->vif_index) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (found) { -+#ifdef CONFIG_RWNX_FULLMAC -+ if (vif->ap.csa) -+ vif->ap.csa->count = ind->csa_count; -+ else -+ netdev_err(vif->ndev, "CSA counter update but no active CSA"); -+ -+#endif -+ } -+ -+ return 0; -+} -+ -+#ifdef CONFIG_RWNX_FULLMAC -+static inline int rwnx_rx_csa_finish_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_csa_finish_ind *ind = (struct mm_csa_finish_ind *)msg->param; -+ struct rwnx_vif *vif; -+ bool found = false; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ // Look for VIF entry -+ list_for_each_entry(vif, &rwnx_hw->vifs, list) { -+ if (vif->vif_index == ind->vif_index) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (found) { -+ if (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_AP || -+ RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_P2P_GO) { -+ if (vif->ap.csa) { -+ vif->ap.csa->status = ind->status; -+ vif->ap.csa->ch_idx = ind->chan_idx; -+ schedule_work(&vif->ap.csa->work); -+ } else -+ netdev_err(vif->ndev, "CSA finish indication but no active CSA"); -+ } else { -+ if (ind->status == 0) { -+ rwnx_chanctx_unlink(vif); -+ rwnx_chanctx_link(vif, ind->chan_idx, NULL); -+ if (rwnx_hw->cur_chanctx == ind->chan_idx) { -+ rwnx_radar_detection_enable_on_cur_channel(rwnx_hw); -+ rwnx_txq_vif_start(vif, RWNX_TXQ_STOP_CHAN, rwnx_hw); -+ } else -+ rwnx_txq_vif_stop(vif, RWNX_TXQ_STOP_CHAN, rwnx_hw); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static inline int rwnx_rx_csa_traffic_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_csa_traffic_ind *ind = (struct mm_csa_traffic_ind *)msg->param; -+ struct rwnx_vif *vif; -+ bool found = false; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ // Look for VIF entry -+ list_for_each_entry(vif, &rwnx_hw->vifs, list) { -+ if (vif->vif_index == ind->vif_index) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (found) { -+ if (ind->enable) -+ rwnx_txq_vif_start(vif, RWNX_TXQ_STOP_CSA, rwnx_hw); -+ else -+ rwnx_txq_vif_stop(vif, RWNX_TXQ_STOP_CSA, rwnx_hw); -+ } -+ -+ return 0; -+} -+ -+static inline int rwnx_rx_ps_change_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_ps_change_ind *ind = (struct mm_ps_change_ind *)msg->param; -+ struct rwnx_sta *sta = &rwnx_hw->sta_table[ind->sta_idx]; -+ -+ if (ind->sta_idx >= (NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX)) { -+ wiphy_err(rwnx_hw->wiphy, "Invalid sta index reported by fw %d\n", -+ ind->sta_idx); -+ return 1; -+ } -+ -+ netdev_dbg(rwnx_hw->vif_table[sta->vif_idx]->ndev, -+ "Sta %d, change PS mode to %s", sta->sta_idx, -+ ind->ps_state ? "ON" : "OFF"); -+ -+ if (sta->valid) { -+ rwnx_ps_bh_enable(rwnx_hw, sta, ind->ps_state); -+ } else if (rwnx_hw->adding_sta) { -+ sta->ps.active = ind->ps_state ? true : false; -+ } else { -+ if (rwnx_hw->vif_table[sta->vif_idx] && rwnx_hw->vif_table[sta->vif_idx]->ndev) -+ netdev_err(rwnx_hw->vif_table[sta->vif_idx]->ndev, -+ "Ignore PS mode change on invalid sta\n"); -+ } -+ -+ return 0; -+} -+ -+ -+static inline int rwnx_rx_traffic_req_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mm_traffic_req_ind *ind = (struct mm_traffic_req_ind *)msg->param; -+ struct rwnx_sta *sta = &rwnx_hw->sta_table[ind->sta_idx]; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ netdev_dbg(rwnx_hw->vif_table[sta->vif_idx]->ndev, -+ "Sta %d, asked for %d pkt", sta->sta_idx, ind->pkt_cnt); -+ -+ rwnx_ps_bh_traffic_req(rwnx_hw, sta, ind->pkt_cnt, -+ ind->uapsd ? UAPSD_ID : LEGACY_PS_ID); -+ -+ return 0; -+} -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+/*************************************************************************** -+ * Messages from SCAN task -+ **************************************************************************/ -+#if 0 -+static inline int rwnx_rx_scan_done_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) -+ struct cfg80211_scan_info info = { -+ .aborted = false, -+ }; -+#endif -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ rwnx_ipc_elem_var_deallocs(rwnx_hw, &rwnx_hw->scan_ie); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) -+ ieee80211_scan_completed(rwnx_hw->hw, &info); -+#else -+ ieee80211_scan_completed(rwnx_hw->hw, false); -+#endif -+ -+ return 0; -+} -+#endif -+ -+/*************************************************************************** -+ * Messages from SCANU task -+ **************************************************************************/ -+#ifdef CONFIG_RWNX_FULLMAC -+extern uint8_t scanning; -+static inline int rwnx_rx_scanu_start_cfm(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (rwnx_hw->scan_request -+#ifdef CONFIG_SCHED_SCAN -+ && !rwnx_hw->is_sched_scan -+#endif//CONFIG_SCHED_SCAN -+ ) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) -+ struct cfg80211_scan_info info = { -+ .aborted = false, -+ }; -+ -+ cfg80211_scan_done(rwnx_hw->scan_request, &info); -+#else -+ cfg80211_scan_done(rwnx_hw->scan_request, false); -+#endif -+ } -+ -+#ifdef CONFIG_SCHED_SCAN -+ if(rwnx_hw->is_sched_scan){ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) -+ AICWFDBG(LOGINFO, "%s cfg80211_sched_scan_results \r\n", __func__); -+ cfg80211_sched_scan_results(rwnx_hw->scan_request->wiphy, -+ rwnx_hw->sched_scan_req->reqid); -+#else -+ cfg80211_sched_scan_results(rwnx_hw->sched_scan_req->wiphy); -+#endif -+ kfree(rwnx_hw->scan_request); -+ rwnx_hw->is_sched_scan = false; -+ } -+#endif//CONFIG_SCHED_SCAN -+ -+ rwnx_hw->scan_request = NULL; -+ scanning = 0; -+ -+ return 0; -+} -+ -+static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct cfg80211_bss *bss = NULL; -+ struct ieee80211_channel *chan; -+ struct scanu_result_ind *ind = (struct scanu_result_ind *)msg->param; -+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)ind->payload; -+ u64 tsf; -+ u8 *ie; -+ size_t ielen; -+ u16 capability, beacon_interval; -+ u16 len = ind->length; -+ -+ chan = ieee80211_get_channel(rwnx_hw->wiphy, ind->center_freq); -+ -+ if (chan != NULL) { -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+ struct timespec ts; -+ get_monotonic_boottime(&ts); -+ tsf = (u64)ts.tv_sec * 1000000 + div_u64(ts.tv_nsec, 1000); -+ mgmt->u.probe_resp.timestamp = ((u64)ts.tv_sec*1000000) + ts.tv_nsec/1000; -+#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) -+ struct timespec ts; -+ ts = ktime_to_timespec(ktime_get_boottime()); -+ tsf = (u64)ts.tv_sec * 1000000 + div_u64(ts.tv_nsec, 1000); -+ mgmt->u.probe_resp.timestamp = tsf; -+#else -+ struct timespec64 ts; -+ ts = ktime_to_timespec64(ktime_get_boottime()); -+ tsf = (u64)ts.tv_sec * 1000000 + div_u64(ts.tv_nsec, 1000); -+ mgmt->u.probe_resp.timestamp = tsf; -+#endif -+ ie = mgmt->u.probe_resp.variable; -+ ielen = len - offsetof(struct ieee80211_mgmt, u.probe_resp.variable); -+ beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); -+ capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); -+ /* framework use system bootup time */ -+ bss = cfg80211_inform_bss(rwnx_hw->wiphy, chan, -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) -+ CFG80211_BSS_FTYPE_UNKNOWN, -+#endif -+ mgmt->bssid, tsf, capability, beacon_interval, -+ ie, ielen, ind->rssi * 100, GFP_ATOMIC); -+ } -+ -+ if (bss != NULL) -+ cfg80211_put_bss(rwnx_hw->wiphy, bss); -+ -+ return 0; -+} -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+/*************************************************************************** -+ * Messages from ME task -+ **************************************************************************/ -+#ifdef CONFIG_RWNX_FULLMAC -+static inline int rwnx_rx_me_tkip_mic_failure_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct me_tkip_mic_failure_ind *ind = (struct me_tkip_mic_failure_ind *)msg->param; -+ struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[ind->vif_idx]; -+ struct net_device *dev = rwnx_vif->ndev; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ cfg80211_michael_mic_failure(dev, (u8 *)&ind->addr, (ind->ga ? NL80211_KEYTYPE_GROUP : -+ NL80211_KEYTYPE_PAIRWISE), ind->keyid, -+ (u8 *)&ind->tsc, GFP_ATOMIC); -+ -+ return 0; -+} -+ -+static inline int rwnx_rx_me_tx_credits_update_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct me_tx_credits_update_ind *ind = (struct me_tx_credits_update_ind *)msg->param; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ rwnx_txq_credit_update(rwnx_hw, ind->sta_idx, ind->tid, ind->credits); -+ -+ return 0; -+} -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+/*************************************************************************** -+ * Messages from SM task -+ **************************************************************************/ -+#ifdef CONFIG_RWNX_FULLMAC -+static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct sm_connect_ind *ind = (struct sm_connect_ind *)msg->param; -+ struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[ind->vif_idx]; -+ struct net_device *dev = rwnx_vif->ndev; -+ const u8 *req_ie, *rsp_ie; -+ const u8 *extcap_ie; -+ const struct ieee_types_extcap *extcap; -+ struct ieee80211_channel *chan; -+ struct cfg80211_bss *bss = NULL; -+ struct wireless_dev *wdev = NULL; -+ int retry_counter = 10; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ wdev = dev->ieee80211_ptr; -+ -+ /* Retrieve IE addresses and lengths */ -+ req_ie = (const u8 *)ind->assoc_ie_buf; -+ rsp_ie = req_ie + ind->assoc_req_ie_len; -+ -+ // Fill-in the AP information -+ AICWFDBG(LOGINFO, "%s ind->status_code:%d \r\n", __func__, ind->status_code); -+ -+ if (ind->status_code == 0) { -+ struct rwnx_sta *sta = &rwnx_hw->sta_table[ind->ap_idx]; -+ u8 txq_status; -+ struct cfg80211_chan_def chandef; -+ -+ sta->valid = true; -+ sta->sta_idx = ind->ap_idx; -+ sta->ch_idx = ind->ch_idx; -+ sta->vif_idx = ind->vif_idx; -+ sta->vlan_idx = sta->vif_idx; -+ sta->qos = ind->qos; -+ sta->acm = ind->acm; -+ sta->ps.active = false; -+ sta->aid = ind->aid; -+ sta->band = ind->band;//ind->chan.band; -+ sta->width = ind->width;//ind->chan.type; -+ sta->center_freq = ind->center_freq;//ind->chan.prim20_freq; -+ sta->center_freq1 = ind->center_freq1;//ind->chan.center1_freq; -+ sta->center_freq2 = ind->center_freq2;//ind->chan.center2_freq; -+ rwnx_vif->sta.ap = sta; -+ chan = ieee80211_get_channel(rwnx_hw->wiphy, ind->center_freq);//ind->chan.prim20_freq); -+ cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT); -+ if (!rwnx_hw->mod_params->ht_on) -+ chandef.width = NL80211_CHAN_WIDTH_20_NOHT; -+ else -+ chandef.width = chnl2bw[ind->width];//[ind->chan.type]; -+ chandef.center_freq1 = ind->center_freq1;//ind->chan.center1_freq; -+ chandef.center_freq2 = ind->center_freq2;//ind->chan.center2_freq; -+ rwnx_chanctx_link(rwnx_vif, ind->ch_idx, &chandef); -+ memcpy(sta->mac_addr, ind->bssid.array, ETH_ALEN); -+ if (ind->ch_idx == rwnx_hw->cur_chanctx) { -+ txq_status = 0; -+ } else { -+ txq_status = RWNX_TXQ_STOP_CHAN; -+ } -+ memcpy(sta->ac_param, ind->ac_param, sizeof(sta->ac_param)); -+ rwnx_txq_sta_init(rwnx_hw, sta, txq_status); -+ rwnx_txq_tdls_vif_init(rwnx_vif); -+#ifdef CONFIG_DEBUG_FS -+ rwnx_dbgfs_register_rc_stat(rwnx_hw, sta); -+#endif -+ rwnx_mu_group_sta_init(sta, NULL); -+ /* Look for TDLS Channel Switch Prohibited flag in the Extended Capability -+ * Information Element*/ -+ extcap_ie = cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY, rsp_ie, ind->assoc_rsp_ie_len); -+ if (extcap_ie && extcap_ie[1] >= 5) { -+ extcap = (void *)(extcap_ie); -+ rwnx_vif->tdls_chsw_prohibited = extcap->ext_capab[4] & WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED; -+ } -+ -+ if (rwnx_vif->wep_enabled) -+ rwnx_vif->wep_auth_err = false; -+ -+#ifdef CONFIG_RWNX_BFMER -+ /* If Beamformer feature is activated, check if features can be used -+ * with the new peer device -+ */ -+ if (rwnx_hw->mod_params->bfmer) { -+ const u8 *vht_capa_ie; -+ const struct ieee80211_vht_cap *vht_cap; -+ -+ do { -+ /* Look for VHT Capability Information Element */ -+ vht_capa_ie = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, rsp_ie, -+ ind->assoc_rsp_ie_len); -+ -+ /* Stop here if peer device does not support VHT */ -+ if (!vht_capa_ie) { -+ break; -+ } -+ -+ vht_cap = (const struct ieee80211_vht_cap *)(vht_capa_ie + 2); -+ -+ /* Send MM_BFMER_ENABLE_REQ message if needed */ -+ rwnx_send_bfmer_enable(rwnx_hw, sta, vht_cap); -+ } while (0); -+ } -+#endif //(CONFIG_RWNX_BFMER) -+ -+#ifdef CONFIG_RWNX_MON_DATA -+ // If there are 1 sta and 1 monitor interface active at the same time then -+ // monitor interface channel context is always the same as the STA interface. -+ // This doesn't work with 2 STA interfaces but we don't want to support it. -+ if (rwnx_hw->monitor_vif != RWNX_INVALID_VIF) { -+ struct rwnx_vif *rwnx_mon_vif = rwnx_hw->vif_table[rwnx_hw->monitor_vif]; -+ rwnx_chanctx_unlink(rwnx_mon_vif); -+ rwnx_chanctx_link(rwnx_mon_vif, ind->ch_idx, NULL); -+ } -+#endif -+ //atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); -+ } else if (ind->status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { -+ if (rwnx_vif->wep_enabled) { -+ rwnx_vif->wep_auth_err = true; -+ AICWFDBG(LOGINFO, "con ind wep_auth_err %d\n", rwnx_vif->wep_auth_err); -+ } -+ atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); -+ }else{ -+ atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); -+ } -+ -+ AICWFDBG(LOGINFO, "%s ind->roamed:%d ind->status_code:%d rwnx_vif->drv_conn_state:%d\r\n", -+ __func__, -+ ind->roamed, -+ ind->status_code, -+ (int)atomic_read(&rwnx_vif->drv_conn_state)); -+ -+ do { -+ bss = cfg80211_get_bss(wdev->wiphy, NULL, rwnx_vif->sta.bssid, -+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION -+ wdev->u.client.ssid, wdev->u.client.ssid_len, -+#else -+ wdev->ssid, wdev->ssid_len, -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) -+ wdev->conn_bss_type, -+ IEEE80211_PRIVACY_ANY); -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) -+ IEEE80211_BSS_TYPE_ESS, -+ IEEE80211_PRIVACY_ANY); -+#else -+ WLAN_CAPABILITY_ESS, -+ WLAN_CAPABILITY_PRIVACY); -+#endif -+ -+ -+ if (!bss) { -+ printk("%s bss is NULL \r\n", __func__); -+ -+ printk("%s bss ssid(%d):%s conn_bss_type:%d bss2 ssid(%d):%s conn_bss_type:%d\r\n", -+ __func__, -+ (int)rwnx_vif->sta.ssid_len, -+ rwnx_vif->sta.ssid, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) -+ IEEE80211_BSS_TYPE_ESS, -+#else -+ WLAN_CAPABILITY_ESS, -+#endif -+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION -+ (int)wdev->u.client.ssid_len, -+ wdev->u.client.ssid, -+#else -+ (int)wdev->ssid_len, -+ wdev->ssid, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) -+ wdev->conn_bss_type -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) -+ IEEE80211_BSS_TYPE_ESS -+#else -+ WLAN_CAPABILITY_ESS -+#endif -+ ); -+ -+ -+ printk("%s rwnx_vif->sta.bssid %02x %02x %02x %02x %02x %02x \r\n", __func__, -+ rwnx_vif->sta.bssid[0], rwnx_vif->sta.bssid[1], rwnx_vif->sta.bssid[2], -+ rwnx_vif->sta.bssid[3], rwnx_vif->sta.bssid[4], rwnx_vif->sta.bssid[5]); -+ -+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION -+ wdev->u.client.ssid_len = (int)rwnx_vif->sta.ssid_len; -+ memcpy(wdev->u.client.ssid, rwnx_vif->sta.ssid, wdev->u.client.ssid_len); -+#else -+ wdev->ssid_len = (int)rwnx_vif->sta.ssid_len; -+ memcpy(wdev->ssid, rwnx_vif->sta.ssid, wdev->ssid_len); -+#endif -+ msleep(100); -+ retry_counter--; -+ if(retry_counter == 0){ -+ printk("%s bss recover fail \r\n", __func__); -+ break; -+ } -+ } -+ } while (!bss); -+ -+ if (!ind->roamed){//not roaming -+ cfg80211_connect_result(dev, (const u8 *)ind->bssid.array, req_ie, -+ ind->assoc_req_ie_len, rsp_ie, -+ ind->assoc_rsp_ie_len, ind->status_code, -+ GFP_ATOMIC); -+ if (ind->status_code == 0) { -+ atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); -+ } else { -+ atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); -+ rwnx_external_auth_disable(rwnx_vif); -+ } -+ AICWFDBG(LOGINFO, "%s cfg80211_connect_result pass, rwnx_vif->drv_conn_state:%d\r\n", -+ __func__, -+ (int)atomic_read(&rwnx_vif->drv_conn_state)); -+ }else {//roaming -+ if(ind->status_code != 0){ -+ AICWFDBG(LOGINFO, "%s roaming fail to notify disconnect \r\n", __func__); -+ cfg80211_disconnected(dev, 0, NULL, 0,1, GFP_ATOMIC); -+ atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); -+ rwnx_external_auth_disable(rwnx_vif); -+ }else{ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) -+ struct cfg80211_roam_info info; -+ memset(&info, 0, sizeof(info)); -+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION -+ if (rwnx_vif->ch_index < NX_CHAN_CTXT_CNT) -+ info.links[0].channel = rwnx_hw->chanctx_table[rwnx_vif->ch_index].chan_def.chan; -+ info.links[0].bssid = (const u8 *)ind->bssid.array; -+#else -+ if (rwnx_vif->ch_index < NX_CHAN_CTXT_CNT) -+ info.channel = rwnx_hw->chanctx_table[rwnx_vif->ch_index].chan_def.chan; -+ info.bssid = (const u8 *)ind->bssid.array; -+#endif -+ info.req_ie = req_ie; -+ info.req_ie_len = ind->assoc_req_ie_len; -+ info.resp_ie = rsp_ie; -+ info.resp_ie_len = ind->assoc_rsp_ie_len; -+ cfg80211_roamed(dev, &info, GFP_ATOMIC); -+ atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); -+#else -+ chan = ieee80211_get_channel(rwnx_hw->wiphy, ind->center_freq); -+ cfg80211_roamed(dev -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE) -+ , chan -+#endif -+ , (const u8 *)ind->bssid.array -+ , req_ie -+ , ind->assoc_req_ie_len -+ , rsp_ie -+ , ind->assoc_rsp_ie_len -+ , GFP_ATOMIC); -+#endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)*/ -+ atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); -+ } -+ } -+ netif_tx_start_all_queues(dev); -+ netif_carrier_on(dev); -+ -+ return 0; -+} -+ -+void rwnx_cfg80211_unlink_bss(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif){ -+ struct wiphy *wiphy = rwnx_hw->wiphy; -+ struct cfg80211_bss *bss = NULL; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/, -+ rwnx_vif->sta.bssid, rwnx_vif->sta.ssid, -+ rwnx_vif->sta.ssid_len, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) -+ IEEE80211_BSS_TYPE_ESS, -+ IEEE80211_PRIVACY(true));//temp set true -+#else -+ WLAN_CAPABILITY_ESS, -+ WLAN_CAPABILITY_ESS); -+#endif -+ -+ if (bss) { -+ cfg80211_unlink_bss(wiphy, bss); -+ AICWFDBG(LOGINFO, "%s(): cfg80211_unlink %s!!\n", __func__, rwnx_vif->sta.ssid); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) -+ cfg80211_put_bss(wiphy, bss); -+#else -+ cfg80211_put_bss(bss); -+#endif -+ }else{ -+ AICWFDBG(LOGINFO, "%s(): cfg80211_unlink error %s!!\n", __func__, rwnx_vif->sta.ssid); -+ } -+} -+ -+extern u8 dhcped; -+static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct sm_disconnect_ind *ind = (struct sm_disconnect_ind *)msg->param; -+ struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[ind->vif_idx]; -+ struct net_device *dev; -+#ifdef AICWF_RX_REORDER -+ struct reord_ctrl_info *reord_info, *tmp; -+ u8 *macaddr; -+ struct aicwf_rx_priv *rx_priv; -+#endif -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTED){ -+ AICWFDBG(LOGINFO, "%s, is already disconnected, drop disconnect ind", __func__); -+ return 0; -+ } -+ -+ dhcped = 0; -+ -+ if(!rwnx_vif) -+ return 0; -+ dev = rwnx_vif->ndev; -+ -+ if (rwnx_vif->sta.is_roam == false) { -+ rwnx_cfg80211_unlink_bss(rwnx_hw, rwnx_vif); -+ } else { -+ AICWFDBG(LOGINFO, "%s roaming no rwnx_cfg80211_unlink_bss \r\n", __func__); -+ } -+ -+ #ifdef CONFIG_BR_SUPPORT -+ struct rwnx_vif *vif = netdev_priv(dev); -+ /* clear bridge database */ -+ nat25_db_cleanup(rwnx_vif); -+ #endif /* CONFIG_BR_SUPPORT */ -+ -+ if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) -+ rwnx_hw->is_p2p_connected = 0; -+ /* if vif is not up, rwnx_close has already been called */ -+ if (rwnx_vif->up) { -+ if (!ind->ft_over_ds && !ind->reassoc) { -+ cfg80211_disconnected(dev, ind->reason_code, NULL, 0, -+ (ind->reason_code < 1), GFP_ATOMIC); -+ } -+ netif_tx_stop_all_queues(dev); -+ netif_carrier_off(dev); -+ } -+ -+#ifdef CONFIG_RWNX_BFMER -+ /* Disable Beamformer if supported */ -+ rwnx_bfmer_report_del(rwnx_hw, rwnx_vif->sta.ap); -+#endif //(CONFIG_RWNX_BFMER) -+ -+#ifdef AICWF_RX_REORDER -+#ifdef AICWF_SDIO_SUPPORT -+ rx_priv = rwnx_hw->sdiodev->rx_priv; -+#else -+ rx_priv = rwnx_hw->usbdev->rx_priv; -+#endif -+ if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) { -+ macaddr = (u8*)rwnx_vif->ndev->dev_addr; -+ printk("deinit:macaddr:%x,%x,%x,%x,%x,%x\r\n", macaddr[0], macaddr[1], macaddr[2], \ -+ macaddr[3], macaddr[4], macaddr[5]); -+ -+ //spin_lock_bh(&rx_priv->stas_reord_lock); -+ list_for_each_entry_safe(reord_info, tmp, &rx_priv->stas_reord_list, list) { -+ macaddr = (u8*)rwnx_vif->ndev->dev_addr; -+ printk("reord_mac:%x,%x,%x,%x,%x,%x\r\n", reord_info->mac_addr[0], reord_info->mac_addr[1], reord_info->mac_addr[2], \ -+ reord_info->mac_addr[3], reord_info->mac_addr[4], reord_info->mac_addr[5]); -+ if (!memcmp(reord_info->mac_addr, macaddr, 6)) { -+ reord_deinit_sta(rx_priv, reord_info); -+ break; -+ } -+ } -+ //spin_unlock_bh(&rx_priv->stas_reord_lock); -+ } else if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) { -+ BUG();//should be not here: del_sta function -+ } -+#endif -+ -+ rwnx_txq_sta_deinit(rwnx_hw, rwnx_vif->sta.ap); -+ rwnx_txq_tdls_vif_deinit(rwnx_vif); -+ #if 0 -+ rwnx_dbgfs_unregister_rc_stat(rwnx_hw, rwnx_vif->sta.ap); -+ #endif -+ rwnx_vif->sta.ap->valid = false; -+ rwnx_vif->sta.ap = NULL; -+ rwnx_external_auth_disable(rwnx_vif); -+ rwnx_chanctx_unlink(rwnx_vif); -+ -+ //msleep(200); -+ atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); -+ return 0; -+} -+ -+static inline int rwnx_rx_sm_external_auth_required_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct sm_external_auth_required_ind *ind = -+ (struct sm_external_auth_required_ind *)msg->param; -+ struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[ind->vif_idx]; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL) -+ struct net_device *dev = rwnx_vif->ndev; -+ struct cfg80211_external_auth_params params; -+ int ret = 0; -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ int retry_counter = 10; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ params.action = NL80211_EXTERNAL_AUTH_START; -+ memcpy(params.bssid, ind->bssid.array, ETH_ALEN); -+ params.ssid.ssid_len = ind->ssid.length; -+ memcpy(params.ssid.ssid, ind->ssid.array, -+ min_t(size_t, ind->ssid.length, sizeof(params.ssid.ssid))); -+ params.key_mgmt_suite = ind->akm; -+ -+ while (wdev->conn_owner_nlportid == 0) { -+ AICWFDBG(LOGINFO, "%s WARNING conn_owner_nlportid = 0, msleep 100ms.\r\n", __func__); -+ msleep(100); -+ retry_counter--; -+ if (retry_counter == 0) { -+ break; -+ } -+ } -+ AICWFDBG(LOGINFO, "%s wdev->conn_owner_nlportid:%d \r\n", __func__, (int)wdev->conn_owner_nlportid); -+ -+ if (wdev->conn_owner_nlportid != 0) { -+ rwnx_vif->sta.conn_owner_nlportid = wdev->conn_owner_nlportid; -+ } else { -+ AICWFDBG(LOGINFO, "%s try to recover conn_owner_nlportid\r\n", __func__); -+ wdev->conn_owner_nlportid = rwnx_vif->sta.conn_owner_nlportid; -+ } -+ -+ if ((ind->vif_idx > NX_VIRT_DEV_MAX) || !rwnx_vif->up || -+ (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_STATION) || -+ (ret = cfg80211_external_auth_request(dev, ¶ms, GFP_ATOMIC))) { -+ wiphy_err(rwnx_hw->wiphy, "Failed to start external auth on vif %d, rwnx_vif->up %d, iftype:%d, ret %d", -+ ind->vif_idx, rwnx_vif->up, RWNX_VIF_TYPE(rwnx_vif), ret); -+ rwnx_send_sm_external_auth_required_rsp(rwnx_hw, rwnx_vif, -+ WLAN_STATUS_UNSPECIFIED_FAILURE); -+ return 0; -+ } -+ -+ rwnx_external_auth_enable(rwnx_vif); -+#else -+ rwnx_send_sm_external_auth_required_rsp(rwnx_hw, rwnx_vif, -+ WLAN_STATUS_UNSPECIFIED_FAILURE); -+#endif -+ return 0; -+} -+ -+ -+static inline int rwnx_rx_mesh_path_create_cfm(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mesh_path_create_cfm *cfm = (struct mesh_path_create_cfm *)msg->param; -+ struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[cfm->vif_idx]; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Check we well have a Mesh Point Interface */ -+ if (rwnx_vif && (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_MESH_POINT)) { -+ rwnx_vif->ap.create_path = false; -+ } -+ -+ return 0; -+} -+ -+static inline int rwnx_rx_mesh_peer_update_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mesh_peer_update_ind *ind = (struct mesh_peer_update_ind *)msg->param; -+ struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[ind->vif_idx]; -+ struct rwnx_sta *rwnx_sta = &rwnx_hw->sta_table[ind->sta_idx]; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if ((ind->vif_idx >= (NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX)) || -+ (rwnx_vif && (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT)) || -+ (ind->sta_idx >= NX_REMOTE_STA_MAX)) -+ return 1; -+ -+ /* Check we well have a Mesh Point Interface */ -+ if (!rwnx_vif->user_mpm) { -+ /* Check if peer link has been established or lost */ -+ if (ind->estab) { -+ if (!rwnx_sta->valid) { -+ u8 txq_status; -+ -+ rwnx_sta->valid = true; -+ rwnx_sta->sta_idx = ind->sta_idx; -+ rwnx_sta->ch_idx = rwnx_vif->ch_index; -+ rwnx_sta->vif_idx = ind->vif_idx; -+ rwnx_sta->vlan_idx = rwnx_sta->vif_idx; -+ rwnx_sta->ps.active = false; -+ rwnx_sta->qos = true; -+ rwnx_sta->aid = ind->sta_idx + 1; -+ //rwnx_sta->acm = ind->acm; -+ memcpy(rwnx_sta->mac_addr, ind->peer_addr.array, ETH_ALEN); -+ -+ rwnx_chanctx_link(rwnx_vif, rwnx_sta->ch_idx, NULL); -+ -+ /* Add the station in the list of VIF's stations */ -+ INIT_LIST_HEAD(&rwnx_sta->list); -+ list_add_tail(&rwnx_sta->list, &rwnx_vif->ap.sta_list); -+ -+ /* Initialize the TX queues */ -+ if (rwnx_sta->ch_idx == rwnx_hw->cur_chanctx) { -+ txq_status = 0; -+ } else { -+ txq_status = RWNX_TXQ_STOP_CHAN; -+ } -+ -+ rwnx_txq_sta_init(rwnx_hw, rwnx_sta, txq_status); -+#ifdef CONFIG_DEBUG_FS -+ rwnx_dbgfs_register_rc_stat(rwnx_hw, rwnx_sta); -+#endif -+#ifdef CONFIG_RWNX_BFMER -+ // TODO: update indication to contains vht capabilties -+ if (rwnx_hw->mod_params->bfmer) -+ rwnx_send_bfmer_enable(rwnx_hw, rwnx_sta, NULL); -+ -+ rwnx_mu_group_sta_init(rwnx_sta, NULL); -+#endif /* CONFIG_RWNX_BFMER */ -+ -+ } else { -+ WARN_ON(0); -+ } -+ } else { -+ if (rwnx_sta->valid) { -+ rwnx_sta->ps.active = false; -+ rwnx_sta->valid = false; -+ -+ /* Remove the station from the list of VIF's station */ -+ list_del_init(&rwnx_sta->list); -+ -+ rwnx_txq_sta_deinit(rwnx_hw, rwnx_sta); -+#ifdef CONFIG_DEBUG_FS -+ rwnx_dbgfs_unregister_rc_stat(rwnx_hw, rwnx_sta); -+#endif -+ } else { -+ WARN_ON(0); -+ } -+ } -+ } else { -+ if (!ind->estab && rwnx_sta->valid) { -+ /* There is no way to inform upper layer for lost of peer, still -+ clean everything in the driver */ -+ rwnx_sta->ps.active = false; -+ rwnx_sta->valid = false; -+ -+ /* Remove the station from the list of VIF's station */ -+ list_del_init(&rwnx_sta->list); -+ -+ rwnx_txq_sta_deinit(rwnx_hw, rwnx_sta); -+#ifdef CONFIG_DEBUG_FS -+ rwnx_dbgfs_unregister_rc_stat(rwnx_hw, rwnx_sta); -+#endif -+ } else { -+ WARN_ON(0); -+ } -+ } -+ -+ return 0; -+} -+ -+static inline int rwnx_rx_mesh_path_update_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mesh_path_update_ind *ind = (struct mesh_path_update_ind *)msg->param; -+ struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[ind->vif_idx]; -+ struct rwnx_mesh_path *mesh_path; -+ bool found = false; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (ind->vif_idx >= (NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX)) -+ return 1; -+ -+ if (!rwnx_vif || (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT)) -+ return 0; -+ -+ /* Look for path with provided target address */ -+ list_for_each_entry(mesh_path, &rwnx_vif->ap.mpath_list, list) { -+ if (mesh_path->path_idx == ind->path_idx) { -+ found = true; -+ break; -+ } -+ } -+ -+ /* Check if element has been deleted */ -+ if (ind->delete) { -+ if (found) { -+#ifdef CREATE_TRACE_POINTS -+ trace_mesh_delete_path(mesh_path); -+#endif -+ /* Remove element from list */ -+ list_del_init(&mesh_path->list); -+ /* Free the element */ -+ kfree(mesh_path); -+ } -+ } else { -+ if (found) { -+ // Update the Next Hop STA -+ mesh_path->p_nhop_sta = &rwnx_hw->sta_table[ind->nhop_sta_idx]; -+#ifdef CREATE_TRACE_POINTS -+ trace_mesh_update_path(mesh_path); -+#endif -+ } else { -+ // Allocate a Mesh Path structure -+ mesh_path = (struct rwnx_mesh_path *)kmalloc(sizeof(struct rwnx_mesh_path), GFP_ATOMIC); -+ -+ if (mesh_path) { -+ INIT_LIST_HEAD(&mesh_path->list); -+ -+ mesh_path->path_idx = ind->path_idx; -+ mesh_path->p_nhop_sta = &rwnx_hw->sta_table[ind->nhop_sta_idx]; -+ memcpy(&mesh_path->tgt_mac_addr, &ind->tgt_mac_addr, MAC_ADDR_LEN); -+ -+ // Insert the path in the list of path -+ list_add_tail(&mesh_path->list, &rwnx_vif->ap.mpath_list); -+#ifdef CREATE_TRACE_POINTS -+ trace_mesh_create_path(mesh_path); -+#endif -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static inline int rwnx_rx_mesh_proxy_update_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ struct mesh_proxy_update_ind *ind = (struct mesh_proxy_update_ind *)msg->param; -+ struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[ind->vif_idx]; -+ struct rwnx_mesh_proxy *mesh_proxy; -+ bool found = false; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (ind->vif_idx >= (NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX)) -+ return 1; -+ -+ if (!rwnx_vif || (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT)) -+ return 0; -+ -+ /* Look for path with provided external STA address */ -+ list_for_each_entry(mesh_proxy, &rwnx_vif->ap.proxy_list, list) { -+ if (!memcmp(&ind->ext_sta_addr, &mesh_proxy->ext_sta_addr, ETH_ALEN)) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (ind->delete && found) { -+ /* Delete mesh path */ -+ list_del_init(&mesh_proxy->list); -+ kfree(mesh_proxy); -+ } else if (!ind->delete && !found) { -+ /* Allocate a Mesh Path structure */ -+ mesh_proxy = (struct rwnx_mesh_proxy *)kmalloc(sizeof(*mesh_proxy), -+ GFP_ATOMIC); -+ -+ if (mesh_proxy) { -+ INIT_LIST_HEAD(&mesh_proxy->list); -+ -+ memcpy(&mesh_proxy->ext_sta_addr, &ind->ext_sta_addr, MAC_ADDR_LEN); -+ mesh_proxy->local = ind->local; -+ -+ if (!ind->local) { -+ memcpy(&mesh_proxy->proxy_addr, &ind->proxy_mac_addr, MAC_ADDR_LEN); -+ } -+ -+ /* Insert the path in the list of path */ -+ list_add_tail(&mesh_proxy->list, &rwnx_vif->ap.proxy_list); -+ } -+ } -+ -+ return 0; -+} -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+/*************************************************************************** -+ * Messages from APM task -+ **************************************************************************/ -+ -+ -+/*************************************************************************** -+ * Messages from DEBUG task -+ **************************************************************************/ -+static inline int rwnx_rx_dbg_error_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_MCU_MESSAGE -+static inline int rwnx_rx_dbg_custmsg_ind(struct rwnx_hw *rwnx_hw, -+ struct rwnx_cmd *cmd, -+ struct ipc_e2a_msg *msg) -+{ -+ dbg_custom_msg_ind_t * ind; -+ char str_msg[32 + 1]; -+ int str_len; -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ ind = (dbg_custom_msg_ind_t *)msg->param; -+ str_len = (ind->len < 32) ? ind->len : 32; -+ memcpy(str_msg, (char *)ind->buf, str_len); -+ str_msg[str_len] = '\0'; -+ printk("CustMsgInd: cmd=0x%x, len=%d, str=%s\r\n", ind->cmd, ind->len, str_msg); -+ -+ return 0; -+} -+#endif -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = { -+ [MSG_I(MM_CHANNEL_SWITCH_IND)] = rwnx_rx_chan_switch_ind, -+ [MSG_I(MM_CHANNEL_PRE_SWITCH_IND)] = rwnx_rx_chan_pre_switch_ind, -+ [MSG_I(MM_REMAIN_ON_CHANNEL_EXP_IND)] = rwnx_rx_remain_on_channel_exp_ind, -+ [MSG_I(MM_PS_CHANGE_IND)] = rwnx_rx_ps_change_ind, -+ [MSG_I(MM_TRAFFIC_REQ_IND)] = rwnx_rx_traffic_req_ind, -+ [MSG_I(MM_P2P_VIF_PS_CHANGE_IND)] = rwnx_rx_p2p_vif_ps_change_ind, -+ [MSG_I(MM_CSA_COUNTER_IND)] = rwnx_rx_csa_counter_ind, -+ [MSG_I(MM_CSA_FINISH_IND)] = rwnx_rx_csa_finish_ind, -+ [MSG_I(MM_CSA_TRAFFIC_IND)] = rwnx_rx_csa_traffic_ind, -+ [MSG_I(MM_CHANNEL_SURVEY_IND)] = rwnx_rx_channel_survey_ind, -+ [MSG_I(MM_P2P_NOA_UPD_IND)] = rwnx_rx_p2p_noa_upd_ind, -+ [MSG_I(MM_RSSI_STATUS_IND)] = rwnx_rx_rssi_status_ind, -+ [MSG_I(MM_PKTLOSS_IND)] = rwnx_rx_pktloss_notify_ind, -+ [MSG_I(MM_APM_STALOSS_IND)] = rwnx_apm_staloss_ind, -+}; -+ -+static msg_cb_fct scan_hdlrs[MSG_I(SCANU_MAX)] = { -+ [MSG_I(SCANU_START_CFM)] = rwnx_rx_scanu_start_cfm, -+ [MSG_I(SCANU_RESULT_IND)] = rwnx_rx_scanu_result_ind, -+}; -+ -+static msg_cb_fct me_hdlrs[MSG_I(ME_MAX)] = { -+ [MSG_I(ME_TKIP_MIC_FAILURE_IND)] = rwnx_rx_me_tkip_mic_failure_ind, -+ [MSG_I(ME_TX_CREDITS_UPDATE_IND)] = rwnx_rx_me_tx_credits_update_ind, -+}; -+ -+static msg_cb_fct sm_hdlrs[MSG_I(SM_MAX)] = { -+ [MSG_I(SM_CONNECT_IND)] = rwnx_rx_sm_connect_ind, -+ [MSG_I(SM_DISCONNECT_IND)] = rwnx_rx_sm_disconnect_ind, -+ [MSG_I(SM_EXTERNAL_AUTH_REQUIRED_IND)] = rwnx_rx_sm_external_auth_required_ind, -+}; -+ -+static msg_cb_fct apm_hdlrs[MSG_I(APM_MAX)] = { -+}; -+ -+static msg_cb_fct mesh_hdlrs[MSG_I(MESH_MAX)] = { -+ [MSG_I(MESH_PATH_CREATE_CFM)] = rwnx_rx_mesh_path_create_cfm, -+ [MSG_I(MESH_PEER_UPDATE_IND)] = rwnx_rx_mesh_peer_update_ind, -+ [MSG_I(MESH_PATH_UPDATE_IND)] = rwnx_rx_mesh_path_update_ind, -+ [MSG_I(MESH_PROXY_UPDATE_IND)] = rwnx_rx_mesh_proxy_update_ind, -+}; -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+static msg_cb_fct dbg_hdlrs[MSG_I(DBG_MAX)] = { -+ [MSG_I(DBG_ERROR_IND)] = rwnx_rx_dbg_error_ind, -+#ifdef CONFIG_MCU_MESSAGE -+ [MSG_I(DBG_CUSTOM_MSG_IND)] = rwnx_rx_dbg_custmsg_ind, -+#endif -+}; -+ -+static msg_cb_fct tdls_hdlrs[MSG_I(TDLS_MAX)] = { -+ [MSG_I(TDLS_CHAN_SWITCH_CFM)] = rwnx_rx_tdls_chan_switch_cfm, -+ [MSG_I(TDLS_CHAN_SWITCH_IND)] = rwnx_rx_tdls_chan_switch_ind, -+ [MSG_I(TDLS_CHAN_SWITCH_BASE_IND)] = rwnx_rx_tdls_chan_switch_base_ind, -+ [MSG_I(TDLS_PEER_PS_IND)] = rwnx_rx_tdls_peer_ps_ind, -+#ifdef CONFIG_SDIO_BT -+ [MSG_I(TDLS_SDIO_BT_RECV_IND)] = rwnx_bt_recv_ind, -+#endif -+}; -+ -+static msg_cb_fct *msg_hdlrs[] = { -+ [TASK_MM] = mm_hdlrs, -+ [TASK_DBG] = dbg_hdlrs, -+#ifdef CONFIG_RWNX_FULLMAC -+ [TASK_TDLS] = tdls_hdlrs, -+ [TASK_SCANU] = scan_hdlrs, -+ [TASK_ME] = me_hdlrs, -+ [TASK_SM] = sm_hdlrs, -+ [TASK_APM] = apm_hdlrs, -+ [TASK_MESH] = mesh_hdlrs, -+#endif /* CONFIG_RWNX_FULLMAC */ -+}; -+ -+/** -+ * -+ */ -+void rwnx_rx_handle_msg(struct rwnx_hw *rwnx_hw, struct ipc_e2a_msg *msg) -+{ -+ AICWFDBG(LOGDEBUG, "%s msg->id:0x%x \r\n", __func__, msg->id); -+ -+ rwnx_hw->cmd_mgr->msgind(rwnx_hw->cmd_mgr, msg, -+ msg_hdlrs[MSG_T(msg->id)][MSG_I(msg->id)]); -+} -+ -+void rwnx_rx_handle_print(struct rwnx_hw *rwnx_hw, u8 *msg, u32 len) -+{ -+ u8 *data_end = NULL; -+ (void)data_end; -+ -+ if (!rwnx_hw || !rwnx_hw->fwlog_en) { -+ pr_err("FWLOG-OVFL: %s", msg); -+ return; -+ } -+ -+ printk("FWLOG: %s", msg); -+ -+#ifdef CONFIG_RWNX_DEBUGFS -+ data_end = rwnx_hw->debugfs.fw_log.buf.dataend; -+ -+ if (!rwnx_hw->debugfs.fw_log.buf.data) -+ return ; -+ -+ //printk("end=%lx, len=%d\n", (unsigned long)rwnx_hw->debugfs.fw_log.buf.end, len); -+ -+ spin_lock_bh(&rwnx_hw->debugfs.fw_log.lock); -+ -+ if (rwnx_hw->debugfs.fw_log.buf.end + len > data_end) { -+ int rem = data_end - rwnx_hw->debugfs.fw_log.buf.end; -+ memcpy(rwnx_hw->debugfs.fw_log.buf.end, msg, rem); -+ memcpy(rwnx_hw->debugfs.fw_log.buf.data, &msg[rem], len - rem); -+ rwnx_hw->debugfs.fw_log.buf.end = rwnx_hw->debugfs.fw_log.buf.data + (len - rem); -+ } else { -+ memcpy(rwnx_hw->debugfs.fw_log.buf.end, msg, len); -+ rwnx_hw->debugfs.fw_log.buf.end += len; -+ } -+ -+ rwnx_hw->debugfs.fw_log.buf.size += len; -+ if (rwnx_hw->debugfs.fw_log.buf.size > FW_LOG_SIZE) -+ rwnx_hw->debugfs.fw_log.buf.size = FW_LOG_SIZE; -+ -+ spin_unlock_bh(&rwnx_hw->debugfs.fw_log.lock); -+#endif -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_rx.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_rx.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_rx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_rx.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,19 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_msg_rx.h -+ * -+ * @brief RX function declarations -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _RWNX_MSG_RX_H_ -+#define _RWNX_MSG_RX_H_ -+ -+void rwnx_rx_handle_msg(struct rwnx_hw *rwnx_hw, struct ipc_e2a_msg *msg); -+void rwnx_rx_handle_print(struct rwnx_hw *rwnx_hw, u8 *msg, u32 len); -+ -+#endif /* _RWNX_MSG_RX_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_tx.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_tx.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_tx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_tx.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,3677 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_msg_tx.c -+ * -+ * @brief TX function definitions -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#include "rwnx_msg_tx.h" -+#include "rwnx_mod_params.h" -+#include "reg_access.h" -+#ifdef CONFIG_RWNX_BFMER -+#include "rwnx_bfmer.h" -+#endif //(CONFIG_RWNX_BFMER) -+#include "rwnx_compat.h" -+#include "rwnx_cmds.h" -+#include "aicwf_txrxif.h" -+#include "rwnx_strs.h" -+#include "rwnx_main.h" -+#include "rwnx_wakelock.h" -+ -+const struct mac_addr mac_addr_bcst = {{0xFFFF, 0xFFFF, 0xFFFF}}; -+ -+/* Default MAC Rx filters that can be changed by mac80211 -+ * (via the configure_filter() callback) */ -+#define RWNX_MAC80211_CHANGEABLE ( \ -+ NXMAC_ACCEPT_BA_BIT | \ -+ NXMAC_ACCEPT_BAR_BIT | \ -+ NXMAC_ACCEPT_OTHER_DATA_FRAMES_BIT | \ -+ NXMAC_ACCEPT_PROBE_REQ_BIT | \ -+ NXMAC_ACCEPT_PS_POLL_BIT \ -+ ) -+ -+/* Default MAC Rx filters that cannot be changed by mac80211 */ -+#define RWNX_MAC80211_NOT_CHANGEABLE ( \ -+ NXMAC_ACCEPT_QO_S_NULL_BIT | \ -+ NXMAC_ACCEPT_Q_DATA_BIT | \ -+ NXMAC_ACCEPT_DATA_BIT | \ -+ NXMAC_ACCEPT_OTHER_MGMT_FRAMES_BIT | \ -+ NXMAC_ACCEPT_MY_UNICAST_BIT | \ -+ NXMAC_ACCEPT_BROADCAST_BIT | \ -+ NXMAC_ACCEPT_BEACON_BIT | \ -+ NXMAC_ACCEPT_PROBE_RESP_BIT \ -+ ) -+ -+/* Default MAC Rx filter */ -+#define RWNX_DEFAULT_RX_FILTER (RWNX_MAC80211_CHANGEABLE | RWNX_MAC80211_NOT_CHANGEABLE) -+ -+const int bw2chnl[] = { -+ [NL80211_CHAN_WIDTH_20_NOHT] = PHY_CHNL_BW_20, -+ [NL80211_CHAN_WIDTH_20] = PHY_CHNL_BW_20, -+ [NL80211_CHAN_WIDTH_40] = PHY_CHNL_BW_40, -+ [NL80211_CHAN_WIDTH_80] = PHY_CHNL_BW_80, -+ [NL80211_CHAN_WIDTH_160] = PHY_CHNL_BW_160, -+ [NL80211_CHAN_WIDTH_80P80] = PHY_CHNL_BW_80P80, -+}; -+ -+const int chnl2bw[] = { -+ [PHY_CHNL_BW_20] = NL80211_CHAN_WIDTH_20, -+ [PHY_CHNL_BW_40] = NL80211_CHAN_WIDTH_40, -+ [PHY_CHNL_BW_80] = NL80211_CHAN_WIDTH_80, -+ [PHY_CHNL_BW_160] = NL80211_CHAN_WIDTH_160, -+ [PHY_CHNL_BW_80P80] = NL80211_CHAN_WIDTH_80P80, -+}; -+ -+#define RWNX_CMD_ARRAY_SIZE 20 -+#define RWNX_CMD_HIGH_WATER_SIZE RWNX_CMD_ARRAY_SIZE/2 -+ -+struct rwnx_cmd cmd_array[RWNX_CMD_ARRAY_SIZE]; -+static spinlock_t cmd_array_lock; -+int cmd_array_index = 0; -+ -+ -+ -+/*****************************************************************************/ -+/* -+ * Parse the ampdu density to retrieve the value in usec, according to the -+ * values defined in ieee80211.h -+ */ -+static inline u8 rwnx_ampdudensity2usec(u8 ampdudensity) -+{ -+ switch (ampdudensity) { -+ case IEEE80211_HT_MPDU_DENSITY_NONE: -+ return 0; -+ /* 1 microsecond is our granularity */ -+ case IEEE80211_HT_MPDU_DENSITY_0_25: -+ case IEEE80211_HT_MPDU_DENSITY_0_5: -+ case IEEE80211_HT_MPDU_DENSITY_1: -+ return 1; -+ case IEEE80211_HT_MPDU_DENSITY_2: -+ return 2; -+ case IEEE80211_HT_MPDU_DENSITY_4: -+ return 4; -+ case IEEE80211_HT_MPDU_DENSITY_8: -+ return 8; -+ case IEEE80211_HT_MPDU_DENSITY_16: -+ return 16; -+ default: -+ return 0; -+ } -+} -+ -+static inline bool use_pairwise_key(struct cfg80211_crypto_settings *crypto) -+{ -+ if ((crypto->cipher_group == WLAN_CIPHER_SUITE_WEP40) || -+ (crypto->cipher_group == WLAN_CIPHER_SUITE_WEP104)) -+ return false; -+ -+ return true; -+} -+ -+static inline bool is_non_blocking_msg(int id) -+{ -+ return ((id == MM_TIM_UPDATE_REQ) || (id == ME_RC_SET_RATE_REQ) || -+ (id == MM_BFMER_ENABLE_REQ) || (id == ME_TRAFFIC_IND_REQ) || -+ (id == TDLS_PEER_TRAFFIC_IND_REQ) || -+ (id == MESH_PATH_CREATE_REQ) || (id == MESH_PROXY_ADD_REQ) || -+ (id == SM_EXTERNAL_AUTH_REQUIRED_RSP)); -+} -+ -+static inline u8_l get_chan_flags(uint32_t flags) -+{ -+ u8_l chan_flags = 0; -+#ifdef RADAR_OR_IR_DETECT -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) -+ if (flags & IEEE80211_CHAN_PASSIVE_SCAN) -+ #else -+ if (flags & IEEE80211_CHAN_NO_IR) -+ #endif -+ chan_flags |= CHAN_NO_IR; -+ if (flags & IEEE80211_CHAN_RADAR) -+ chan_flags |= CHAN_RADAR; -+#endif -+ return chan_flags; -+} -+ -+static inline s8_l chan_to_fw_pwr(int power) -+{ -+ return power > 127 ? 127 : (s8_l)power; -+} -+ -+static inline void limit_chan_bw(u8_l *bw, u16_l primary, u16_l *center1) -+{ -+ int oft, new_oft = 10; -+ -+ if (*bw <= PHY_CHNL_BW_40) -+ return; -+ -+ oft = *center1 - primary; -+ *bw = PHY_CHNL_BW_40; -+ -+ if (oft < 0) -+ new_oft = new_oft * -1; -+ if (abs(oft) == 10 || abs(oft) == 50) -+ new_oft = new_oft * -1; -+ -+ *center1 = primary + new_oft; -+} -+ -+struct rwnx_cmd *rwnx_cmd_malloc(void){ -+ struct rwnx_cmd *cmd = NULL; -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&cmd_array_lock, flags); -+ -+ for(cmd_array_index = 0; cmd_array_index < RWNX_CMD_ARRAY_SIZE; cmd_array_index++){ -+ if(cmd_array[cmd_array_index].used == 0){ -+ AICWFDBG(LOGTRACE, "%s get cmd_array[%d]:%p \r\n", __func__, cmd_array_index,&cmd_array[cmd_array_index]); -+ cmd = &cmd_array[cmd_array_index]; -+ cmd_array[cmd_array_index].used = 1; -+ break; -+ } -+ } -+ -+ if(cmd_array_index >= RWNX_CMD_HIGH_WATER_SIZE){ -+ AICWFDBG(LOGERROR, "%s cmd(%d) was pending...\r\n", __func__, cmd_array_index); -+ mdelay(100); -+ } -+ -+ if(!cmd){ -+ AICWFDBG(LOGERROR, "%s array is empty...\r\n", __func__); -+ } -+ -+ spin_unlock_irqrestore(&cmd_array_lock, flags); -+ -+ return cmd; -+} -+ -+void rwnx_cmd_free(struct rwnx_cmd *cmd){ -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&cmd_array_lock, flags); -+ cmd->used = 0; -+ AICWFDBG(LOGTRACE, "%s cmd_array[%d]:%p \r\n", __func__, cmd->array_id, cmd); -+ spin_unlock_irqrestore(&cmd_array_lock, flags); -+} -+ -+ -+int rwnx_init_cmd_array(void){ -+ -+ AICWFDBG(LOGTRACE, "%s Enter \r\n", __func__); -+ spin_lock_init(&cmd_array_lock); -+ -+ for(cmd_array_index = 0; cmd_array_index < RWNX_CMD_ARRAY_SIZE; cmd_array_index++){ -+ AICWFDBG(LOGTRACE, "%s cmd_queue[%d]:%p \r\n", __func__, cmd_array_index, &cmd_array[cmd_array_index]); -+ cmd_array[cmd_array_index].used = 0; -+ cmd_array[cmd_array_index].array_id = cmd_array_index; -+ } -+ AICWFDBG(LOGTRACE, "%s Exit \r\n", __func__); -+ -+ return 0; -+} -+ -+void rwnx_free_cmd_array(void){ -+ -+ AICWFDBG(LOGTRACE, "%s Enter \r\n", __func__); -+ -+ for(cmd_array_index = 0; cmd_array_index < RWNX_CMD_ARRAY_SIZE; cmd_array_index++){ -+ cmd_array[cmd_array_index].used = 0; -+ } -+ -+ AICWFDBG(LOGTRACE, "%s Exit \r\n", __func__); -+} -+ -+ -+/** -+ ****************************************************************************** -+ * @brief Allocate memory for a message -+ * -+ * This primitive allocates memory for a message that has to be sent. The memory -+ * is allocated dynamically on the heap and the length of the variable parameter -+ * structure has to be provided in order to allocate the correct size. -+ * -+ * Several additional parameters are provided which will be preset in the message -+ * and which may be used internally to choose the kind of memory to allocate. -+ * -+ * The memory allocated will be automatically freed by the kernel, after the -+ * pointer has been sent to ke_msg_send(). If the message is not sent, it must -+ * be freed explicitly with ke_msg_free(). -+ * -+ * Allocation failure is considered critical and should not happen. -+ * -+ * @param[in] id Message identifier -+ * @param[in] dest_id Destination Task Identifier -+ * @param[in] src_id Source Task Identifier -+ * @param[in] param_len Size of the message parameters to be allocated -+ * -+ * @return Pointer to the parameter member of the ke_msg. If the parameter -+ * structure is empty, the pointer will point to the end of the message -+ * and should not be used (except to retrieve the message pointer or to -+ * send the message) -+ ****************************************************************************** -+ */ -+static inline void *rwnx_msg_zalloc(lmac_msg_id_t const id, -+ lmac_task_id_t const dest_id, -+ lmac_task_id_t const src_id, -+ uint16_t const param_len) -+{ -+ struct lmac_msg *msg; -+ gfp_t flags; -+ -+// if (is_non_blocking_msg(id) && (in_softirq()||in_atomic())) -+ flags = GFP_ATOMIC; -+// else -+// flags = GFP_KERNEL; -+ -+ msg = (struct lmac_msg *)kzalloc(sizeof(struct lmac_msg) + param_len, -+ flags); -+ if (msg == NULL) { -+ AICWFDBG(LOGERROR, "%s: msg allocation failed\n", __func__); -+ return NULL; -+ } -+ msg->id = id; -+ msg->dest_id = dest_id; -+ msg->src_id = src_id; -+ msg->param_len = param_len; -+ //printk("rwnx_msg_zalloc size=%d id=%d\n",msg->param_len,msg->id); -+ -+ return msg->param; -+} -+ -+static void rwnx_msg_free(struct rwnx_hw *rwnx_hw, const void *msg_params) -+{ -+ struct lmac_msg *msg = container_of((void *)msg_params, -+ struct lmac_msg, param); -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Free the message */ -+ kfree(msg); -+} -+ -+//void rwnx_pm_relax(struct aic_sdio_dev *sdiodev); -+//void rwnx_pm_stay_awake(struct aic_sdio_dev *sdiodev); -+ -+static int rwnx_send_msg(struct rwnx_hw *rwnx_hw, const void *msg_params, -+ int reqcfm, lmac_msg_id_t reqid, void *cfm) -+{ -+ struct lmac_msg *msg; -+ struct rwnx_cmd *cmd; -+ bool nonblock; -+ int ret = 0; -+ u8_l empty = 0; -+ -+ //RWNX_DBG(RWNX_FN_ENTRY_STR); -+ AICWFDBG(LOGTRACE, "%s (%d)%s reqcfm:%d in_irq:%d in_softirq:%d in_atomic:%d\r\n", -+ __func__, reqid, RWNX_ID2STR(reqid), reqcfm, (int)in_irq(), (int)in_softirq(), (int)in_atomic()); -+ -+ -+#ifdef AICWF_USB_SUPPORT -+ if (rwnx_hw->usbdev->state == USB_DOWN_ST) { -+ rwnx_msg_free(rwnx_hw, msg_params); -+ usb_err("bus is down\n"); -+ return 0; -+ } -+#endif -+#ifdef AICWF_SDIO_SUPPORT -+ rwnx_wakeup_lock(rwnx_hw->ws_tx); -+ if (rwnx_hw->sdiodev->bus_if->state == BUS_DOWN_ST) { -+ rwnx_msg_free(rwnx_hw, msg_params); -+ sdio_err("bus is down\n"); -+ rwnx_wakeup_unlock(rwnx_hw->ws_tx); -+ return 0; -+ } -+#endif -+ -+ msg = container_of((void *)msg_params, struct lmac_msg, param); -+ -+ #if 0 -+ if (!test_bit(RWNX_DEV_STARTED, &rwnx_hw->drv_flags) && -+ reqid != DBG_MEM_READ_CFM && reqid != DBG_MEM_WRITE_CFM && -+ reqid != DBG_MEM_BLOCK_WRITE_CFM && reqid != DBG_START_APP_CFM && -+ reqid != MM_SET_RF_CALIB_CFM && reqid != MM_SET_RF_CONFIG_CFM && -+ reqid != MM_RESET_CFM && reqid != MM_VERSION_CFM && -+ reqid != MM_START_CFM && reqid != MM_SET_IDLE_CFM && -+ reqid != ME_CONFIG_CFM && reqid != MM_SET_PS_MODE_CFM && -+ reqid != ME_CHAN_CONFIG_CFM) { -+ printk(KERN_CRIT "%s: bypassing (RWNX_DEV_RESTARTING set) 0x%02x\n", -+ __func__, reqid); -+ kfree(msg); -+ return -EBUSY; -+ } -+ #endif -+#if 0 -+ else if (!rwnx_hw->ipc_env) { -+ printk(KERN_CRIT "%s: bypassing (restart must have failed)\n", __func__); -+ kfree(msg); -+ return -EBUSY; -+ } -+#endif -+ -+ //nonblock = is_non_blocking_msg(msg->id); -+ nonblock = 0; -+ cmd = rwnx_cmd_malloc();//kzalloc(sizeof(struct rwnx_cmd), nonblock ? GFP_ATOMIC : GFP_KERNEL); -+ cmd->result = -EINTR; -+ cmd->id = msg->id; -+ cmd->reqid = reqid; -+ cmd->a2e_msg = msg; -+ cmd->e2a_msg = cfm; -+ if (nonblock) -+ cmd->flags = RWNX_CMD_FLAG_NONBLOCK; -+ if (reqcfm) -+ cmd->flags |= RWNX_CMD_FLAG_REQ_CFM; -+ -+ if (cfm != NULL) { -+ do { -+ if(rwnx_hw->cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) -+ break; -+ spin_lock_bh(&rwnx_hw->cmd_mgr->lock); -+ empty = list_empty(&rwnx_hw->cmd_mgr->cmds); -+ spin_unlock_bh(&rwnx_hw->cmd_mgr->lock); -+ if(!empty) { -+ if(in_softirq()) { -+ printk("in_softirq:check cmdqueue empty\n"); -+ mdelay(10); -+ } -+ else { -+ printk("check cmdqueue empty\n"); -+ msleep(50); -+ } -+ } -+ } while (!empty);//wait for cmd queue empty -+ } -+ -+ if (reqcfm) { -+ cmd->flags &= ~RWNX_CMD_FLAG_WAIT_ACK; // we don't need ack any more -+ ret = rwnx_hw->cmd_mgr->queue(rwnx_hw->cmd_mgr, cmd); -+ } else { -+#ifdef AICWF_SDIO_SUPPORT -+ aicwf_set_cmd_tx((void *)(rwnx_hw->sdiodev), cmd->a2e_msg, sizeof(struct lmac_msg) + cmd->a2e_msg->param_len); -+#else -+ aicwf_set_cmd_tx((void *)(rwnx_hw->usbdev), cmd->a2e_msg, sizeof(struct lmac_msg) + cmd->a2e_msg->param_len); -+#endif -+ } -+ -+ if (!reqcfm || ret) -+ rwnx_cmd_free(cmd);//kfree(cmd); -+ -+ rwnx_wakeup_unlock(rwnx_hw->ws_tx); -+ return 0; -+} -+ -+ -+static int rwnx_send_msg1(struct rwnx_hw *rwnx_hw, const void *msg_params, -+ int reqcfm, lmac_msg_id_t reqid, void *cfm, bool defer) -+{ -+ struct lmac_msg *msg; -+ struct rwnx_cmd *cmd; -+ bool nonblock; -+ int ret = 0; -+ -+// RWNX_DBG(RWNX_FN_ENTRY_STR); -+ printk("%s (%d)%s reqcfm:%d in_irq:%d in_softirq:%d in_atomic:%d\r\n", -+ __func__, reqid, RWNX_ID2STR(reqid), reqcfm, (int)in_irq(), (int)in_softirq(), (int)in_atomic()); -+ -+ rwnx_wakeup_lock(rwnx_hw->ws_tx); -+ msg = container_of((void *)msg_params, struct lmac_msg, param); -+ -+ //nonblock = is_non_blocking_msg(msg->id); -+ nonblock = 0; -+ cmd = rwnx_cmd_malloc();//kzalloc(sizeof(struct rwnx_cmd), nonblock ? GFP_ATOMIC : GFP_KERNEL); -+ cmd->result = -EINTR; -+ cmd->id = msg->id; -+ cmd->reqid = reqid; -+ cmd->a2e_msg = msg; -+ cmd->e2a_msg = cfm; -+ if (nonblock) -+ cmd->flags = RWNX_CMD_FLAG_NONBLOCK; -+ if (reqcfm) -+ cmd->flags |= RWNX_CMD_FLAG_REQ_CFM; -+ -+ if (reqcfm) { -+ cmd->flags &= ~RWNX_CMD_FLAG_WAIT_ACK; // we don't need ack any more -+ if (!defer) -+ ret = rwnx_hw->cmd_mgr->queue(rwnx_hw->cmd_mgr, cmd); -+ else -+ ret = cmd_mgr_queue_force_defer(rwnx_hw->cmd_mgr, cmd); -+ } -+ -+ if (!reqcfm || ret) -+ rwnx_cmd_free(cmd);//kfree(cmd); -+ -+ if (!ret) -+ ret = cmd->result; -+ -+ rwnx_wakeup_unlock(rwnx_hw->ws_tx); -+ //return ret; -+ return 0; -+} -+ -+/****************************************************************************** -+ * Control messages handling functions (FULLMAC) -+ *****************************************************************************/ -+int rwnx_send_reset(struct rwnx_hw *rwnx_hw) -+{ -+ void *void_param; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* RESET REQ has no parameter */ -+ void_param = rwnx_msg_zalloc(MM_RESET_REQ, TASK_MM, DRV_TASK_ID, 0); -+ if (!void_param) -+ return -ENOMEM; -+ -+ return rwnx_send_msg(rwnx_hw, void_param, 1, MM_RESET_CFM, NULL); -+} -+ -+int rwnx_send_start(struct rwnx_hw *rwnx_hw) -+{ -+ struct mm_start_req *start_req_param; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the START REQ message */ -+ start_req_param = rwnx_msg_zalloc(MM_START_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_start_req)); -+ if (!start_req_param) -+ return -ENOMEM; -+ -+ /* Set parameters for the START message */ -+ memcpy(&start_req_param->phy_cfg, &rwnx_hw->phy.cfg, sizeof(rwnx_hw->phy.cfg)); -+ start_req_param->uapsd_timeout = (u32_l)rwnx_hw->mod_params->uapsd_timeout; -+ start_req_param->lp_clk_accuracy = (u16_l)rwnx_hw->mod_params->lp_clk_ppm; -+ -+ /* Send the START REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, start_req_param, 1, MM_START_CFM, NULL); -+} -+ -+int rwnx_send_version_req(struct rwnx_hw *rwnx_hw, struct mm_version_cfm *cfm) -+{ -+ void *void_param; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* VERSION REQ has no parameter */ -+ void_param = rwnx_msg_zalloc(MM_VERSION_REQ, TASK_MM, DRV_TASK_ID, 0); -+ if (!void_param) -+ return -ENOMEM; -+ -+ return rwnx_send_msg(rwnx_hw, void_param, 1, MM_VERSION_CFM, cfm); -+} -+ -+int rwnx_send_add_if (struct rwnx_hw *rwnx_hw, const unsigned char *mac, -+ enum nl80211_iftype iftype, bool p2p, struct mm_add_if_cfm *cfm) -+{ -+ struct mm_add_if_req *add_if_req_param; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the ADD_IF_REQ message */ -+ add_if_req_param = rwnx_msg_zalloc(MM_ADD_IF_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_add_if_req)); -+ if (!add_if_req_param) -+ return -ENOMEM; -+ -+ /* Set parameters for the ADD_IF_REQ message */ -+ memcpy(&(add_if_req_param->addr.array[0]), mac, ETH_ALEN); -+ switch (iftype) { -+ #ifdef CONFIG_RWNX_FULLMAC -+ //case NL80211_IFTYPE_P2P_DEVICE: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ add_if_req_param->p2p = true; -+ // no break -+ #endif /* CONFIG_RWNX_FULLMAC */ -+ case NL80211_IFTYPE_STATION: -+ add_if_req_param->type = MM_STA; -+ break; -+ -+ case NL80211_IFTYPE_ADHOC: -+ add_if_req_param->type = MM_IBSS; -+ break; -+ -+ #ifdef CONFIG_RWNX_FULLMAC -+ case NL80211_IFTYPE_P2P_GO: -+ add_if_req_param->p2p = true; -+ // no break -+ #endif /* CONFIG_RWNX_FULLMAC */ -+ case NL80211_IFTYPE_AP: -+ add_if_req_param->type = MM_AP; -+ break; -+ case NL80211_IFTYPE_MESH_POINT: -+ add_if_req_param->type = MM_MESH_POINT; -+ break; -+ case NL80211_IFTYPE_AP_VLAN: -+ return -1; -+ case NL80211_IFTYPE_MONITOR: -+ add_if_req_param->type = MM_MONITOR; -+ break; -+ default: -+ add_if_req_param->type = MM_STA; -+ break; -+ } -+ -+ -+ /* Send the ADD_IF_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, add_if_req_param, 1, MM_ADD_IF_CFM, cfm); -+} -+ -+int rwnx_send_remove_if (struct rwnx_hw *rwnx_hw, u8 vif_index, bool defer) -+{ -+ struct mm_remove_if_req *remove_if_req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_REMOVE_IF_REQ message */ -+ remove_if_req = rwnx_msg_zalloc(MM_REMOVE_IF_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_remove_if_req)); -+ if (!remove_if_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_REMOVE_IF_REQ message */ -+ remove_if_req->inst_nbr = vif_index; -+ -+ /* Send the MM_REMOVE_IF_REQ message to LMAC FW */ -+ return rwnx_send_msg1(rwnx_hw, remove_if_req, 1, MM_REMOVE_IF_CFM, NULL, defer); -+} -+ -+int rwnx_send_set_channel(struct rwnx_hw *rwnx_hw, int phy_idx, -+ struct mm_set_channel_cfm *cfm) -+{ -+ struct mm_set_channel_req *req; -+ enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT; -+ u16 center_freq = 2412, center_freq1 = 2412, center_freq2 = 2412; -+ s8 tx_power = 0; -+ u8 flags = 0; -+ enum nl80211_band band = NL80211_BAND_2GHZ; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (phy_idx >= rwnx_hw->phy.cnt) -+ return -ENOTSUPP; -+ -+ req = rwnx_msg_zalloc(MM_SET_CHANNEL_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_channel_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ if (phy_idx == 0) { -+#ifdef CONFIG_RWNX_FULLMAC -+ /* On FULLMAC only setting channel of secondary chain */ -+ wiphy_err(rwnx_hw->wiphy, "Trying to set channel of primary chain"); -+ return 0; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ } else { -+ struct rwnx_sec_phy_chan *chan = &rwnx_hw->phy.sec_chan; -+ width = chnl2bw[chan->type]; -+ band = chan->band; -+ center_freq = chan->prim20_freq; -+ center_freq1 = chan->center_freq1; -+ center_freq2 = chan->center_freq2; -+ flags = 0; -+ } -+ -+ req->chan.band = band; -+ req->chan.type = bw2chnl[width]; -+ req->chan.prim20_freq = center_freq; -+ req->chan.center1_freq = center_freq1; -+ req->chan.center2_freq = center_freq2; -+ req->chan.tx_power = tx_power; -+ req->chan.flags = flags; -+ req->index = phy_idx; -+ -+ if (rwnx_hw->phy.limit_bw) -+ limit_chan_bw(&req->chan.type, req->chan.prim20_freq, &req->chan.center1_freq); -+ -+ RWNX_DBG("mac80211: freq=%d(c1:%d - c2:%d)/width=%d - band=%d\n" -+ " hw(%d): prim20=%d(c1:%d - c2:%d)/ type=%d - band=%d\n", -+ center_freq, center_freq1, center_freq2, width, band, -+ phy_idx, req->chan.prim20_freq, req->chan.center1_freq, -+ req->chan.center2_freq, req->chan.type, req->chan.band); -+ -+ /* Send the MM_SET_CHANNEL_REQ REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, MM_SET_CHANNEL_CFM, cfm); -+} -+ -+int rwnx_send_key_add(struct rwnx_hw *rwnx_hw, u8 vif_idx, u8 sta_idx, bool pairwise, -+ u8 *key, u8 key_len, u8 key_idx, u8 cipher_suite, -+ struct mm_key_add_cfm *cfm) -+{ -+ struct mm_key_add_req *key_add_req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_KEY_ADD_REQ message */ -+ key_add_req = rwnx_msg_zalloc(MM_KEY_ADD_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_key_add_req)); -+ if (!key_add_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_KEY_ADD_REQ message */ -+ if (sta_idx != 0xFF) { -+ /* Pairwise key */ -+ key_add_req->sta_idx = sta_idx; -+ } else { -+ /* Default key */ -+ key_add_req->sta_idx = sta_idx; -+ key_add_req->key_idx = (u8_l)key_idx; /* only useful for default keys */ -+ } -+ key_add_req->pairwise = pairwise; -+ key_add_req->inst_nbr = vif_idx; -+ key_add_req->key.length = key_len; -+ memcpy(&(key_add_req->key.array[0]), key, key_len); -+ -+ key_add_req->cipher_suite = cipher_suite; -+ -+ RWNX_DBG("%s: sta_idx:%d key_idx:%d inst_nbr:%d cipher:%d key_len:%d\n", __func__, -+ key_add_req->sta_idx, key_add_req->key_idx, key_add_req->inst_nbr, -+ key_add_req->cipher_suite, key_add_req->key.length); -+#if defined(CONFIG_RWNX_DBG) || defined(CONFIG_DYNAMIC_DEBUG) -+ print_hex_dump_bytes("key: ", DUMP_PREFIX_OFFSET, key_add_req->key.array, key_add_req->key.length); -+#endif -+ -+ /* Send the MM_KEY_ADD_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, key_add_req, 1, MM_KEY_ADD_CFM, cfm); -+} -+ -+int rwnx_send_key_del(struct rwnx_hw *rwnx_hw, uint8_t hw_key_idx) -+{ -+ struct mm_key_del_req *key_del_req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_KEY_DEL_REQ message */ -+ key_del_req = rwnx_msg_zalloc(MM_KEY_DEL_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_key_del_req)); -+ if (!key_del_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_KEY_DEL_REQ message */ -+ key_del_req->hw_key_idx = hw_key_idx; -+ -+ /* Send the MM_KEY_DEL_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, key_del_req, 1, MM_KEY_DEL_CFM, NULL); -+} -+ -+int rwnx_send_bcn(struct rwnx_hw *rwnx_hw, u8 *buf, u8 vif_idx, u16 bcn_len) -+{ -+ struct apm_set_bcn_ie_req *bcn_ie_req; -+ bcn_ie_req = rwnx_msg_zalloc(APM_SET_BEACON_IE_REQ, TASK_APM, DRV_TASK_ID, -+ sizeof(struct apm_set_bcn_ie_req)); -+ if (!bcn_ie_req) -+ return -ENOMEM; -+ -+ bcn_ie_req->vif_idx = vif_idx; -+ bcn_ie_req->bcn_ie_len = bcn_len; -+ memcpy(bcn_ie_req->bcn_ie, (u8 *)buf, bcn_len); -+ kfree(buf); -+ -+ return rwnx_send_msg(rwnx_hw, bcn_ie_req, 1, APM_SET_BEACON_IE_CFM, NULL); -+} -+ -+int rwnx_send_bcn_change(struct rwnx_hw *rwnx_hw, u8 vif_idx, u32 bcn_addr, -+ u16 bcn_len, u16 tim_oft, u16 tim_len, u16 *csa_oft) -+{ -+ struct mm_bcn_change_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_BCN_CHANGE_REQ message */ -+ req = rwnx_msg_zalloc(MM_BCN_CHANGE_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_bcn_change_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_BCN_CHANGE_REQ message */ -+ req->bcn_ptr = bcn_addr; -+ req->bcn_len = bcn_len; -+ req->tim_oft = tim_oft; -+ req->tim_len = tim_len; -+ req->inst_nbr = vif_idx; -+ -+ if (csa_oft) { -+ int i; -+ for (i = 0; i < BCN_MAX_CSA_CPT; i++) { -+ req->csa_oft[i] = csa_oft[i]; -+ } -+ } -+ -+ /* Send the MM_BCN_CHANGE_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, MM_BCN_CHANGE_CFM, NULL); -+} -+ -+int rwnx_send_roc(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ struct ieee80211_channel *chan, unsigned int duration, -+ struct mm_remain_on_channel_cfm *roc_cfm) -+{ -+ struct mm_remain_on_channel_req *req; -+ struct cfg80211_chan_def chandef; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Create channel definition structure */ -+ cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT); -+ -+ /* Build the MM_REMAIN_ON_CHANNEL_REQ message */ -+ req = rwnx_msg_zalloc(MM_REMAIN_ON_CHANNEL_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_remain_on_channel_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_REMAIN_ON_CHANNEL_REQ message */ -+ req->op_code = MM_ROC_OP_START; -+ req->vif_index = vif->vif_index; -+ req->duration_ms = duration; -+ req->band = chan->band; -+ req->type = bw2chnl[chandef.width]; -+ req->prim20_freq = chan->center_freq; -+ req->center1_freq = chandef.center_freq1; -+ req->center2_freq = chandef.center_freq2; -+ req->tx_power = chan_to_fw_pwr(chan->max_power); -+ -+ /* Send the MM_REMAIN_ON_CHANNEL_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, MM_REMAIN_ON_CHANNEL_CFM, roc_cfm); -+} -+ -+int rwnx_send_cancel_roc(struct rwnx_hw *rwnx_hw) -+{ -+ struct mm_remain_on_channel_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_REMAIN_ON_CHANNEL_REQ message */ -+ req = rwnx_msg_zalloc(MM_REMAIN_ON_CHANNEL_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_remain_on_channel_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_REMAIN_ON_CHANNEL_REQ message */ -+ req->op_code = MM_ROC_OP_CANCEL; -+ -+ /* Send the MM_REMAIN_ON_CHANNEL_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, MM_REMAIN_ON_CHANNEL_CFM, NULL); -+} -+ -+int rwnx_send_set_power(struct rwnx_hw *rwnx_hw, u8 vif_idx, s8 pwr, -+ struct mm_set_power_cfm *cfm) -+{ -+ struct mm_set_power_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_POWER_REQ message */ -+ req = rwnx_msg_zalloc(MM_SET_POWER_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_power_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_SET_POWER_REQ message */ -+ req->inst_nbr = vif_idx; -+ req->power = pwr; -+ -+ /* Send the MM_SET_POWER_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, MM_SET_POWER_CFM, cfm); -+} -+ -+int rwnx_send_set_edca(struct rwnx_hw *rwnx_hw, u8 hw_queue, u32 param, -+ bool uapsd, u8 inst_nbr) -+{ -+ struct mm_set_edca_req *set_edca_req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_EDCA_REQ message */ -+ set_edca_req = rwnx_msg_zalloc(MM_SET_EDCA_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_edca_req)); -+ if (!set_edca_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_SET_EDCA_REQ message */ -+ set_edca_req->ac_param = param; -+ set_edca_req->uapsd = uapsd; -+ set_edca_req->hw_queue = hw_queue; -+ set_edca_req->inst_nbr = inst_nbr; -+ -+ /* Send the MM_SET_EDCA_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, set_edca_req, 1, MM_SET_EDCA_CFM, NULL); -+} -+ -+#ifdef CONFIG_RWNX_P2P_DEBUGFS -+int rwnx_send_p2p_oppps_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ u8 ctw, struct mm_set_p2p_oppps_cfm *cfm) -+{ -+ struct mm_set_p2p_oppps_req *p2p_oppps_req; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_P2P_OPPPS_REQ message */ -+ p2p_oppps_req = rwnx_msg_zalloc(MM_SET_P2P_OPPPS_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_p2p_oppps_req)); -+ -+ if (!p2p_oppps_req) { -+ return -ENOMEM; -+ } -+ -+ /* Fill the message parameters */ -+ p2p_oppps_req->vif_index = rwnx_vif->vif_index; -+ p2p_oppps_req->ctwindow = ctw; -+ -+ /* Send the MM_P2P_OPPPS_REQ message to LMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, p2p_oppps_req, 1, MM_SET_P2P_OPPPS_CFM, cfm); -+ -+ return error; -+} -+ -+int rwnx_send_p2p_noa_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ int count, int interval, int duration, bool dyn_noa, -+ struct mm_set_p2p_noa_cfm *cfm) -+{ -+ struct mm_set_p2p_noa_req *p2p_noa_req; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Param check */ -+ if (count > 255) -+ count = 255; -+ -+ if (duration >= interval) { -+ dev_err(rwnx_hw->dev, "Invalid p2p NOA config: interval=%d <= duration=%d\n", -+ interval, duration); -+ return -EINVAL; -+ } -+ -+ /* Build the MM_SET_P2P_NOA_REQ message */ -+ p2p_noa_req = rwnx_msg_zalloc(MM_SET_P2P_NOA_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_p2p_noa_req)); -+ -+ if (!p2p_noa_req) { -+ return -ENOMEM; -+ } -+ -+ /* Fill the message parameters */ -+ p2p_noa_req->vif_index = rwnx_vif->vif_index; -+ p2p_noa_req->noa_inst_nb = 0; -+ p2p_noa_req->count = count; -+ -+ if (count) { -+ p2p_noa_req->duration_us = duration * 1024; -+ p2p_noa_req->interval_us = interval * 1024; -+ p2p_noa_req->start_offset = (interval - duration - 10) * 1024; -+ p2p_noa_req->dyn_noa = dyn_noa; -+ } -+ -+ /* Send the MM_SET_2P_NOA_REQ message to LMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, p2p_noa_req, 1, MM_SET_P2P_NOA_CFM, cfm); -+ -+ return error; -+} -+#endif /* CONFIG_RWNX_P2P_DEBUGFS */ -+ -+#ifdef AICWF_ARP_OFFLOAD -+int rwnx_send_arpoffload_en_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ u32_l ipaddr, u8_l enable) -+{ -+ struct mm_set_arpoffload_en_req *arp_offload_req; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_P2P_NOA_REQ message */ -+ arp_offload_req = rwnx_msg_zalloc(MM_SET_ARPOFFLOAD_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_arpoffload_en_req)); -+ -+ if (!arp_offload_req) { -+ return -ENOMEM; -+ } -+ -+ /* Fill the message parameters */ -+ arp_offload_req->enable = enable; -+ arp_offload_req->vif_idx = rwnx_vif->vif_index; -+ arp_offload_req->ipaddr = ipaddr; -+ -+ /* Send the MM_ARPOFFLOAD_EN_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, arp_offload_req, 1, MM_SET_ARPOFFLOAD_CFM, NULL); -+ -+ return error; -+} -+#endif -+ -+int rwnx_send_disable_agg_req(struct rwnx_hw *rwnx_hw, u8_l agg_disable, u8_l agg_disable_rx, u8_l sta_idx) -+{ -+ struct mm_set_agg_disable_req *req; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_AGG_DISABLE_REQ message */ -+ req = rwnx_msg_zalloc(MM_SET_AGG_DISABLE_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_agg_disable_req)); -+ -+ if (!req) { -+ return -ENOMEM; -+ } -+ -+ req->disable = agg_disable; -+ req->staidx = sta_idx; -+ req->disable_rx = agg_disable_rx; -+ -+ /* Send the MM_SET_AGG_DISABLE_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_AGG_DISABLE_CFM, NULL); -+ -+ return (error); -+}; -+ -+int rwnx_send_coex_req(struct rwnx_hw *rwnx_hw, u8_l disable_coexnull, u8_l enable_nullcts) -+{ -+ struct mm_set_coex_req *coex_req; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_COEX_REQ message */ -+ coex_req = rwnx_msg_zalloc(MM_SET_COEX_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_coex_req)); -+ -+ if (!coex_req) { -+ return -ENOMEM; -+ } -+ -+ coex_req->bt_on = 1; -+ coex_req->disable_coexnull = disable_coexnull; -+ coex_req->enable_nullcts = enable_nullcts; -+ coex_req->enable_periodic_timer = 0; -+ coex_req->coex_timeslot_set = 0; -+ -+ /* Send the MM_SET_COEX_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, coex_req, 1, MM_SET_COEX_CFM, NULL); -+ -+ return error; -+}; -+ -+ -+int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l *tbl, u16_l len) -+{ -+ struct mm_set_rf_config_req *rf_config_req; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_RF_CONFIG_REQ message */ -+ rf_config_req = rwnx_msg_zalloc(MM_SET_RF_CONFIG_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_rf_config_req)); -+ -+ if (!rf_config_req) { -+ return -ENOMEM; -+ } -+ -+ rf_config_req->table_sel = sel; -+ rf_config_req->table_ofst = ofst; -+ rf_config_req->table_num = 16; -+ rf_config_req->deft_page = 0; -+ -+ memcpy(rf_config_req->data, tbl, len); -+ -+ /* Send the MM_SET_RF_CONFIG_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, rf_config_req, 1, MM_SET_RF_CONFIG_CFM, NULL); -+ -+ return (error); -+ -+} -+ -+int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm) -+{ -+ struct mm_set_rf_calib_req *rf_calib_req; -+ xtal_cap_conf_t xtal_cap = {0,}; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_P2P_NOA_REQ message */ -+ rf_calib_req = rwnx_msg_zalloc(MM_SET_RF_CALIB_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_rf_calib_req)); -+ -+ if (!rf_calib_req) { -+ return -ENOMEM; -+ } -+ -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801){ -+ rf_calib_req->cal_cfg_24g = 0xbf; -+ rf_calib_req->cal_cfg_5g = 0x3f; -+ } else if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC || rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW) { -+ rf_calib_req->cal_cfg_24g = 0x0f8f; -+ rf_calib_req->cal_cfg_5g = 0; -+ } else if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80) { -+ rf_calib_req->cal_cfg_24g = 0x0f8f; -+ rf_calib_req->cal_cfg_5g = 0x0f0f; -+ } -+ -+ rf_calib_req->param_alpha = 0x0c34c008; -+ rf_calib_req->bt_calib_en = 0; -+ rf_calib_req->bt_calib_param = 0x264203; -+ -+ get_userconfig_xtal_cap(&xtal_cap); -+ -+ if (xtal_cap.enable) { -+ printk("user xtal cap: %d, cap_fine: %d\n", xtal_cap.xtal_cap, xtal_cap.xtal_cap_fine); -+ rf_calib_req->xtal_cap = xtal_cap.xtal_cap; -+ rf_calib_req->xtal_cap_fine = xtal_cap.xtal_cap_fine; -+ } else { -+ rf_calib_req->xtal_cap = 0; -+ rf_calib_req->xtal_cap_fine = 0; -+ } -+ -+ -+ /* Send the MM_SET_RF_CALIB_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, rf_calib_req, 1, MM_SET_RF_CALIB_CFM, cfm); -+ -+ return error; -+}; -+ -+int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cfm *cfm) -+{ -+ struct mm_get_mac_addr_req *get_macaddr_req; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_GET_MAC_ADDR_REQ message */ -+ get_macaddr_req = rwnx_msg_zalloc(MM_GET_MAC_ADDR_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_get_mac_addr_req)); -+ -+ if (!get_macaddr_req) { -+ return -ENOMEM; -+ } -+ -+ get_macaddr_req->get = 1; -+ -+ /* Send the MM_GET_MAC_ADDR_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, get_macaddr_req, 1, MM_GET_MAC_ADDR_CFM, cfm); -+ -+ return error; -+}; -+ -+int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_get_sta_info_cfm *cfm) -+{ -+ struct mm_get_sta_info_req *get_info_req; -+ int error; -+ -+ -+ /* Build the MM_GET_STA_INFO_REQ message */ -+ get_info_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_get_sta_info_req)); -+ -+ if (!get_info_req) { -+ return -ENOMEM; -+ } -+ -+ get_info_req->sta_idx = sta_idx; -+ -+ /* Send the MM_GET_STA_INFO_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, get_info_req, 1, MM_GET_STA_INFO_CFM, cfm); -+ -+ return error; -+}; -+ -+int rwnx_send_set_stack_start_req(struct rwnx_hw *rwnx_hw, u8_l on, u8_l efuse_valid, u8_l set_vendor_info, -+ u8_l fwtrace_redir_en, struct mm_set_stack_start_cfm *cfm) -+{ -+ struct mm_set_stack_start_req *req; -+ int error; -+ -+ /* Build the MM_SET_STACK_START_REQ message */ -+ req = rwnx_msg_zalloc(MM_SET_STACK_START_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_stack_start_req)); -+ -+ if (!req) { -+ return -ENOMEM; -+ } -+ -+ req->is_stack_start = on; -+ req->efuse_valid = efuse_valid; -+ req->set_vendor_info = set_vendor_info; -+ req->fwtrace_redir = fwtrace_redir_en; -+ /* Send the MM_SET_STACK_START_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_STACK_START_CFM, cfm); -+ -+ return error; -+} -+ -+int rwnx_send_set_temp_comp_req(struct rwnx_hw *rwnx_hw, struct mm_set_vendor_swconfig_cfm *cfm) -+{ -+ struct mm_set_vendor_swconfig_req *req; -+ int ret; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ /* Build the TEMP_COMP_SET_REQ message */ -+ req = rwnx_msg_zalloc(MM_SET_VENDOR_SWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_vendor_swconfig_req)); -+ if (!req) { -+ printk("%s msg_alloc fail\n", __func__); -+ return -ENOMEM; -+ } -+ req->swconfig_id = TEMP_COMP_SET_REQ; -+ req->temp_comp_set_req.enable = 1; -+ req->temp_comp_set_req.tmr_period_ms = 15 * 1000; -+ -+ ret = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, cfm); -+ if (!ret) -+ printk("temp_comp status: %d\n", cfm->temp_comp_set_cfm.status); -+ else { -+ printk("%s msg_fail\n", __func__); -+ return ret; -+ } -+ return ret; -+} -+ -+int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param, int32_t *param_out) -+{ -+ struct mm_set_acs_txop_req *req0; -+ struct mm_set_channel_access_req *req1; -+ struct mm_set_mac_timescale_req *req2; -+ struct mm_set_cca_threshold_req *req3; -+ struct mm_set_bwmode_req *req4; -+ -+ int error = 0; -+ -+ switch (hwconfig_id) -+ { -+ case ACS_TXOP_REQ: -+ /* Build the ACS_TXOP_REQ message */ -+ req0= rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_acs_txop_req) ); -+ if (!req0) -+ return -ENOMEM; -+ req0->hwconfig_id = hwconfig_id; -+ req0->txop_be = param[0]; -+ req0->txop_bk = param[1]; -+ req0->txop_vi = param[2]; -+ req0->txop_vo = param[3]; -+ printk("set_acs_txop_req: be: %x,bk: %x,vi: %x,vo: %x\n", -+ req0->txop_be, req0->txop_bk, req0->txop_vi, req0->txop_vo); -+ /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req0, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); -+ break; -+ -+ case CHANNEL_ACCESS_REQ: -+ /* Build the CHANNEL_ACCESS_REQ message */ -+ req1 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_channel_access_req)); -+ if (!req1) -+ return -ENOMEM; -+ req1->hwconfig_id = hwconfig_id; -+ req1->edca[0] = param[0]; -+ req1->edca[1] = param[1]; -+ req1->edca[2] = param[2]; -+ req1->edca[3] = param[3]; -+ req1->vif_idx = param[4]; -+ req1->retry_cnt = param[5]; -+ req1->rts_en = param[6]; -+ req1->long_nav_en = param[7]; -+ req1->cfe_en = param[8]; -+ req1->rc_retry_cnt[0] = param[9]; -+ req1->rc_retry_cnt[1] = param[10]; -+ req1->rc_retry_cnt[2] = param[11]; -+ req1->ccademod_th = param[12]; -+ printk("set_channel_access_req:edca[]= %x %x %x %x\nvif_idx: %x, retry_cnt: %x, rts_en: %x, long_nav_en: %x, cfe_en: %x, rc_retry_cnt: %x:%x:%x, ccademod_th = %d\n", -+ req1->edca[0], req1->edca[1], req1->edca[2], req1->edca[3], req1->vif_idx, req1->retry_cnt, req1->rts_en, req1->long_nav_en, req1->cfe_en, req1->rc_retry_cnt[0],req1->rc_retry_cnt[1], req1->rc_retry_cnt[2], req1->ccademod_th); -+ /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req1, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); -+ break; -+ -+ case MAC_TIMESCALE_REQ: -+ /* Build the MAC_TIMESCALE_REQ message */ -+ req2 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_mac_timescale_req)); -+ if (!req2) -+ return -ENOMEM; -+ req2->hwconfig_id = hwconfig_id; -+ req2->sifsA_time = param[0]; -+ req2->sifsB_time = param[1]; -+ req2->slot_time = param[2]; -+ req2->rx_startdelay_ofdm = param[3]; -+ req2->rx_startdelay_long = param[4]; -+ req2->rx_startdelay_short = param[5]; -+ printk("set_mac_timescale_req:sifsA_time: %x, sifsB_time: %x, slot_time: %x, rx_startdelay ofdm:%x long %x short %x\n", -+ req2->sifsA_time, req2->sifsB_time, req2->slot_time, req2->rx_startdelay_ofdm, req2->rx_startdelay_long, req2->rx_startdelay_short); -+ /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req2, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); -+ break; -+ -+ case CCA_THRESHOLD_REQ: -+ /* Build the CCA_THRESHOLD_REQ message */ -+ req3 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_cca_threshold_req)); -+ if (!req3) -+ return -ENOMEM; -+ req3->hwconfig_id = hwconfig_id; -+ req3->auto_cca_en = param[0]; -+ req3->cca20p_rise_th = param[1]; -+ req3->cca20s_rise_th = param[2]; -+ req3->cca20p_fall_th = param[3]; -+ req3->cca20s_fall_th = param[4]; -+ printk("cca_threshold_req: auto_cca_en:%d\ncca20p_rise_th = %d\ncca20s_rise_th = %d\ncca20p_fall_th = %d\ncca20s_fall_th = %d\n", -+ req3->auto_cca_en, req3->cca20p_rise_th, req3->cca20s_rise_th, req3->cca20p_fall_th, req3->cca20s_fall_th); -+ /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req3, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); -+ break; -+ case BWMODE_REQ: -+ /* Build the SET_BWMODE_REQ message */ -+ req4 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_bwmode_req)); -+ if (!req4) -+ return -ENOMEM; -+ req4->hwconfig_id = hwconfig_id; -+ req4->bwmode = param[0]; -+ printk("bwmode :%d\n", req4->bwmode); -+ /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req4, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); -+ break; -+ case CHIP_TEMP_GET_REQ: -+ if ((rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC) || -+ (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW)) -+ { -+ struct mm_get_chip_temp_req *req; -+ struct mm_set_vendor_hwconfig_cfm cfm = {0,}; -+ /* Build the CHIP_TEMP_GET_REQ message */ -+ req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_get_chip_temp_req)); -+ if (!req) -+ return -ENOMEM; -+ req->hwconfig_id = hwconfig_id; -+ /* Send the MM_SET_VENDOR_HWCONFIG_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, &cfm); -+ if (!error) { -+ if (param_out) { -+ param_out[0] = (int32_t)cfm.chip_temp_cfm.degree; -+ } -+ printk("get_chip_temp degree=%d\n", cfm.chip_temp_cfm.degree); -+ } else { -+ printk("get_chip_temp err=%d\n", error); -+ } -+ } -+ break; -+ default: -+ return -ENOMEM; -+ } -+ return error; -+} -+ -+int rwnx_send_vendor_swconfig_req(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, int32_t *param_in, int32_t *param_out) -+{ -+ struct mm_set_vendor_swconfig_req *req; -+ struct mm_set_vendor_swconfig_cfm cfm = {0,}; -+ int error; -+ -+ req = rwnx_msg_zalloc(MM_SET_VENDOR_SWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_vendor_swconfig_req)); -+ if (!req) { -+ return -ENOMEM; -+ } -+ req->swconfig_id = swconfig_id; -+ -+ switch (swconfig_id) -+ { -+ case BCN_CFG_REQ: -+ /* Build the BCN_CFG_REQ message */ -+ req->bcn_cfg_req.tim_bcmc_ignored_enable = (bool_l)param_in[0]; -+ printk("bcn_cfg_req: tim_bcmc_ignd=%d\n", req->bcn_cfg_req.tim_bcmc_ignored_enable); -+ /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); -+ if (!error) { -+ param_out[0] = (int32_t)cfm.bcn_cfg_cfm.tim_bcmc_ignored_status; -+ printk("status=%d\n", cfm.bcn_cfg_cfm.tim_bcmc_ignored_status); -+ } -+ break; -+ -+ case TEMP_COMP_SET_REQ: -+ /* Build the TEMP_COMP_SET_REQ message */ -+ req->temp_comp_set_req.enable = (u8_l)param_in[0]; -+ req->temp_comp_set_req.tmr_period_ms = (u32_l)param_in[1]; -+ printk("temp_comp_set_req: en=%d, tmr=%x\n", -+ req->temp_comp_set_req.enable, req->temp_comp_set_req.tmr_period_ms); -+ /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); -+ if (!error) { -+ param_out[0] = (int32_t)cfm.temp_comp_set_cfm.status; -+ printk("status=%d\n", cfm.temp_comp_set_cfm.status); -+ } -+ break; -+ -+ case TEMP_COMP_GET_REQ: -+ printk("temp_comp_get_req\n"); -+ /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); -+ if (!error) { -+ param_out[0] = (int32_t)cfm.temp_comp_get_cfm.status; -+ param_out[1] = (int32_t)cfm.temp_comp_get_cfm.degree; -+ printk("status=%d, degree=%d\n", -+ cfm.temp_comp_get_cfm.status, cfm.temp_comp_get_cfm.degree); -+ } -+ break; -+ -+ case EXT_FLAGS_SET_REQ: -+ /* Build the EXT_FLAGS_SET_REQ message */ -+ req->ext_flags_set_req.user_flags = (u32_l)param_in[0]; -+ printk("ext_flags_set_req: flags=%x\n", -+ req->ext_flags_set_req.user_flags); -+ /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); -+ if (!error) { -+ param_out[0] = (uint32_t)cfm.ext_flags_set_cfm.user_flags; -+ printk("cfm flags=%x\n", cfm.ext_flags_set_cfm.user_flags); -+ } -+ break; -+ -+ case EXT_FLAGS_GET_REQ: -+ /* Build the EXT_FLAGS_GET_REQ message */ -+ printk("ext_flags_get_req\n"); -+ /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); -+ if (!error) { -+ param_out[0] = (uint32_t)cfm.ext_flags_get_cfm.user_flags; -+ printk("cfm flags=%x\n", cfm.ext_flags_get_cfm.user_flags); -+ } -+ break; -+ -+ case EXT_FLAGS_MASK_SET_REQ: -+ /* Build the EXT_FLAGS_MASK_SET_REQ message */ -+ req->ext_flags_mask_set_req.user_flags_mask = (u32_l)param_in[0]; -+ req->ext_flags_mask_set_req.user_flags_val = (u32_l)param_in[1]; -+ printk("ext_flags_mask_set_req: flags mask=0x%x, val=0x%x\n", -+ req->ext_flags_mask_set_req.user_flags_mask, req->ext_flags_mask_set_req.user_flags_val); -+ /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); -+ if (!error) { -+ param_out[0] = (uint32_t)cfm.ext_flags_mask_set_cfm.user_flags; -+ printk("cfm flags=%x\n", cfm.ext_flags_mask_set_cfm.user_flags); -+ } -+ break; -+ -+ default: -+ error = -ENOMEM; -+ break; -+ } -+ -+ return error; -+} -+ -+int rwnx_send_mask_set_ext_flags_req(struct rwnx_hw *rwnx_hw, uint32_t flags_mask, uint32_t flags_val, struct mm_set_vendor_swconfig_cfm *cfm) -+{ -+ struct mm_set_vendor_swconfig_req *req; -+ int ret; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ /* Build the REQ message */ -+ req = rwnx_msg_zalloc(MM_SET_VENDOR_SWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_vendor_swconfig_req)); -+ if (!req) { -+ AICWFDBG(LOGERROR, "%s msg_alloc fail\n", __func__); -+ return -ENOMEM; -+ } -+ req->swconfig_id = EXT_FLAGS_MASK_SET_REQ; -+ req->ext_flags_mask_set_req.user_flags_mask = (u32_l)flags_mask; -+ req->ext_flags_mask_set_req.user_flags_val = (u32_l)flags_val; -+ -+ ret = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, cfm); -+ if (!ret) { -+ AICWFDBG(LOGINFO, "curr ext_flags=%x\n", cfm->ext_flags_mask_set_cfm.user_flags); -+ } else { -+ AICWFDBG(LOGERROR, "%s send_msg_fail\n", __func__); -+ return ret; -+ } -+ return ret; -+} -+ -+#ifdef CONFIG_SDIO_BT -+int rwnx_sdio_bt_send_req(struct rwnx_hw *rwnx_hw,uint32_t len, struct sk_buff *skb) -+{ -+ struct mm_bt_send_req *req; -+ struct mm_bt_send_cfm cfm; -+ int error; -+ -+ cfm.status = 0; -+ req = rwnx_msg_zalloc(TDLS_SDIO_BT_SEND_REQ, TASK_TDLS, DRV_TASK_ID, sizeof(struct mm_bt_send_req)); -+ -+ if (!req) { -+ return -ENOMEM; -+ } -+ -+ req->data_len = len; -+ memcpy(req->bt_data,skb->data,len); -+ -+ error = rwnx_send_msg(rwnx_hw, req, 1, TDLS_SDIO_BT_SEND_CFM, &cfm); -+ if(!cfm.status){ -+ printk("bt send no cfm"); -+ } -+ -+ return error; -+} -+#endif -+ -+int rwnx_send_get_fw_version_req(struct rwnx_hw *rwnx_hw, struct mm_get_fw_version_cfm *cfm) -+{ -+ void *req; -+ int error; -+ -+ /* Build the MM_GET_FW_VERSION_REQ message */ -+ req = rwnx_msg_zalloc(MM_GET_FW_VERSION_REQ, TASK_MM, DRV_TASK_ID, sizeof(u8)); -+ -+ if (!req) { -+ return -ENOMEM; -+ } -+ -+ /* Send the MM_GET_FW_VERSION_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, req, 1, MM_GET_FW_VERSION_CFM, cfm); -+ -+ return error; -+} -+ -+int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw) -+{ -+ struct mm_set_txpwr_lvl_req *txpwr_lvl_req; -+ txpwr_lvl_conf_v2_t txpwr_lvl_v2_tmp; -+ txpwr_lvl_conf_v2_t *txpwr_lvl_v2; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_TXPWR_LVL_REQ message */ -+ txpwr_lvl_req = rwnx_msg_zalloc(MM_SET_TXPWR_IDX_LVL_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_txpwr_lvl_req)); -+ -+ if (!txpwr_lvl_req) { -+ return -ENOMEM; -+ } -+ -+ txpwr_lvl_v2 = &txpwr_lvl_v2_tmp; -+ -+ get_userconfig_txpwr_lvl_v2_in_fdrv(txpwr_lvl_v2); -+ -+ if (txpwr_lvl_v2->enable == 0) { -+ rwnx_msg_free(rwnx_hw, txpwr_lvl_req); -+ return 0; -+ } else { -+ AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_v2->enable); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_1m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_2m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_5m5_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_11m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_6m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_9m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_12m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_18m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_24m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_36m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_48m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_54m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[11]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs0_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs1_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs2_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs3_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs4_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs5_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs6_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs7_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs8_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs9_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs0_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs1_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs2_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs3_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs4_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs5_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs6_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs7_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs8_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs9_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs10_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[11]); -+ -+ if ((testmode == 0) && (chip_sub_id == 0)) { -+ txpwr_lvl_req->txpwr_lvl.enable = txpwr_lvl_v2->enable; -+ txpwr_lvl_req->txpwr_lvl.dsss = txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]; // 11M -+ txpwr_lvl_req->txpwr_lvl.ofdmlowrate_2g4= txpwr_lvl_v2->pwrlvl_11ax_2g4[4]; // MCS4 -+ txpwr_lvl_req->txpwr_lvl.ofdm64qam_2g4 = txpwr_lvl_v2->pwrlvl_11ax_2g4[7]; // MCS7 -+ txpwr_lvl_req->txpwr_lvl.ofdm256qam_2g4 = txpwr_lvl_v2->pwrlvl_11ax_2g4[9]; // MCS9 -+ txpwr_lvl_req->txpwr_lvl.ofdm1024qam_2g4= txpwr_lvl_v2->pwrlvl_11ax_2g4[11]; // MCS11 -+ txpwr_lvl_req->txpwr_lvl.ofdmlowrate_5g = 13; // unused -+ txpwr_lvl_req->txpwr_lvl.ofdm64qam_5g = 13; // unused -+ txpwr_lvl_req->txpwr_lvl.ofdm256qam_5g = 13; // unused -+ txpwr_lvl_req->txpwr_lvl.ofdm1024qam_5g = 13; // unused -+ } else { -+ txpwr_lvl_req->txpwr_lvl_v2 = *txpwr_lvl_v2; -+ } -+ -+ /* Send the MM_SET_TXPWR_LVL_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, txpwr_lvl_req, 1, MM_SET_TXPWR_IDX_LVL_CFM, NULL); -+ -+ return (error); -+ } -+} -+ -+int rwnx_send_txpwr_lvl_v3_req(struct rwnx_hw *rwnx_hw) -+{ -+ struct mm_set_txpwr_lvl_req *txpwr_lvl_req; -+ txpwr_lvl_conf_v3_t txpwr_lvl_v3_tmp; -+ txpwr_lvl_conf_v3_t *txpwr_lvl_v3; -+ txpwr_loss_conf_t txpwr_loss_tmp; -+ txpwr_loss_conf_t *txpwr_loss; -+ int error; -+ int i; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_TXPWR_LVL_REQ message */ -+ txpwr_lvl_req = rwnx_msg_zalloc(MM_SET_TXPWR_IDX_LVL_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_txpwr_lvl_req)); -+ -+ if (!txpwr_lvl_req) { -+ return -ENOMEM; -+ } -+ -+ txpwr_lvl_v3 = &txpwr_lvl_v3_tmp; -+ txpwr_loss = &txpwr_loss_tmp; -+ txpwr_loss->loss_enable = 0; -+ -+ get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_v3); -+ get_userconfig_txpwr_loss(txpwr_loss); -+ -+ if (txpwr_loss->loss_enable == 1) { -+ AICWFDBG(LOGINFO, "%s:loss_value:%d\r\n", __func__, txpwr_loss->loss_value); -+ -+ for (i = 0; i <= 11; i++) -+ txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[i] += txpwr_loss->loss_value; -+ for (i = 0; i <= 9; i++) -+ txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[i] += txpwr_loss->loss_value; -+ for (i = 0; i <= 11; i++) -+ txpwr_lvl_v3->pwrlvl_11ax_2g4[i] += txpwr_loss->loss_value; -+ -+ for (i = 0; i <= 11; i++) -+ txpwr_lvl_v3->pwrlvl_11a_5g[i] += txpwr_loss->loss_value; -+ for (i = 0; i <= 9; i++) -+ txpwr_lvl_v3->pwrlvl_11n_11ac_5g[i] += txpwr_loss->loss_value; -+ for (i = 0; i <= 11; i++) -+ txpwr_lvl_v3->pwrlvl_11ax_5g[i] += txpwr_loss->loss_value; -+ } -+ -+ if (txpwr_lvl_v3->enable == 0) { -+ rwnx_msg_free(rwnx_hw, txpwr_lvl_req); -+ return 0; -+ } else { -+ AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_v3->enable); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_1m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_2m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_5m5_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_11m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_6m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_9m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_12m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_18m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_24m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_36m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_48m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_54m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[11]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs0_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs1_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs2_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs3_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs4_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs5_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs6_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs7_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs8_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs9_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs0_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs1_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs2_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs3_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs4_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs5_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs6_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs7_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs8_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs9_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs10_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[11]); -+ -+ AICWFDBG(LOGINFO, "%s:lvl_11a_1m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_2m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_5m5_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_11m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_6m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_9m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_12m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_18m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_24m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_36m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_48m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_54m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[11]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs0_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs1_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs2_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs3_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs4_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs5_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs6_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs7_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs8_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs9_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs0_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs1_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs2_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs3_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs4_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs5_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs6_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs7_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs8_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs9_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs10_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[11]); -+ -+ txpwr_lvl_req->txpwr_lvl_v3 = *txpwr_lvl_v3; -+ -+ /* Send the MM_SET_TXPWR_LVL_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, txpwr_lvl_req, 1, MM_SET_TXPWR_IDX_LVL_CFM, NULL); -+ -+ return (error); -+ } -+} -+ -+int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw) -+{ -+ struct mm_set_txpwr_lvl_adj_req *txpwr_lvl_adj_req; -+ txpwr_lvl_adj_conf_t txpwr_lvl_adj_tmp; -+ txpwr_lvl_adj_conf_t *txpwr_lvl_adj; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_TXPWR_LVL_REQ message */ -+ txpwr_lvl_adj_req = rwnx_msg_zalloc(MM_SET_TXPWR_LVL_ADJ_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_txpwr_lvl_adj_req)); -+ -+ if (!txpwr_lvl_adj_req) { -+ return -ENOMEM; -+ } -+ -+ txpwr_lvl_adj = &txpwr_lvl_adj_tmp; -+ -+ get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj); -+ -+ if (txpwr_lvl_adj->enable == 0) { -+ rwnx_msg_free(rwnx_hw, txpwr_lvl_adj_req); -+ return 0; -+ } else { -+ AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_adj->enable); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_1_4:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_5_9:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_10_13:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_2g4[2]); -+ -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_42:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_58:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_106:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_122:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_138:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_155:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[5]); -+ -+ txpwr_lvl_adj_req->txpwr_lvl_adj = *txpwr_lvl_adj; -+ -+ /* Send the MM_SET_TXPWR_LVL_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, txpwr_lvl_adj_req, 1, MM_SET_TXPWR_LVL_ADJ_CFM, NULL); -+ -+ return (error); -+ } -+} -+ -+int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw) -+{ -+ struct mm_set_txpwr_idx_req *txpwr_idx_req; -+ txpwr_idx_conf_t *txpwr_idx; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_TXPWR_IDX_LVL_REQ message */ -+ txpwr_idx_req = rwnx_msg_zalloc(MM_SET_TXPWR_IDX_LVL_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_txpwr_idx_req)); -+ -+ if (!txpwr_idx_req) { -+ return -ENOMEM; -+ } -+ -+ txpwr_idx = &txpwr_idx_req->txpwr_idx; -+ txpwr_idx->enable = 1; -+ txpwr_idx->dsss = 9; -+ txpwr_idx->ofdmlowrate_2g4 = 8; -+ txpwr_idx->ofdm64qam_2g4 = 8; -+ txpwr_idx->ofdm256qam_2g4 = 8; -+ txpwr_idx->ofdm1024qam_2g4 = 8; -+ txpwr_idx->ofdmlowrate_5g = 11; -+ txpwr_idx->ofdm64qam_5g = 10; -+ txpwr_idx->ofdm256qam_5g = 9; -+ txpwr_idx->ofdm1024qam_5g = 9; -+ -+ get_userconfig_txpwr_idx(txpwr_idx); -+ -+ if (txpwr_idx->enable == 0) { -+ rwnx_msg_free(rwnx_hw, txpwr_idx_req); -+ return 0; -+ } else { -+ /* Send the MM_SET_TXPWR_IDX_LVL_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, txpwr_idx_req, 1, MM_SET_TXPWR_IDX_LVL_CFM, NULL); -+ -+ return error; -+ } -+}; -+ -+int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw) -+{ -+ struct mm_set_txpwr_ofst_req *txpwr_ofst_req; -+ txpwr_ofst_conf_t *txpwr_ofst; -+ int error; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_TXPWR_OFST_REQ message */ -+ txpwr_ofst_req = rwnx_msg_zalloc(MM_SET_TXPWR_OFST_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_txpwr_ofst_req)); -+ -+ if (!txpwr_ofst_req) { -+ return -ENOMEM; -+ } -+ -+ txpwr_ofst = &txpwr_ofst_req->txpwr_ofst; -+ txpwr_ofst->enable = 1; -+ txpwr_ofst->chan_1_4 = 0; -+ txpwr_ofst->chan_5_9 = 0; -+ txpwr_ofst->chan_10_13 = 0; -+ txpwr_ofst->chan_36_64 = 0; -+ txpwr_ofst->chan_100_120 = 0; -+ txpwr_ofst->chan_122_140 = 0; -+ txpwr_ofst->chan_142_165 = 0; -+ -+ if(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801){ -+ get_userconfig_txpwr_ofst(txpwr_ofst); -+ }else if(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst); -+ } -+ -+ if (txpwr_ofst->enable == 0) { -+ rwnx_msg_free(rwnx_hw, txpwr_ofst_req); -+ return 0; -+ } else { -+ /* Send the MM_SET_TXPWR_OFST_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, txpwr_ofst_req, 1, MM_SET_TXPWR_OFST_CFM, NULL); -+ -+ return error; -+ } -+}; -+ -+int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw) -+{ -+ struct mm_set_txpwr_ofst_req *txpwr_ofst_req; -+ txpwr_ofst2x_conf_t *txpwr_ofst2x; -+ int error = 0; -+ int type, ch_grp; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_SET_TXPWR_OFST_REQ message */ -+ txpwr_ofst_req = rwnx_msg_zalloc(MM_SET_TXPWR_OFST_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_set_txpwr_ofst_req)); -+ -+ if (!txpwr_ofst_req) { -+ return -ENOMEM; -+ } -+ -+ txpwr_ofst2x = &txpwr_ofst_req->txpwr_ofst2x; -+ txpwr_ofst2x->enable = 0; -+ for (type = 0; type < 3; type++) { -+ for (ch_grp = 0; ch_grp < 6; ch_grp++) { -+ if (ch_grp < 3) { -+ txpwr_ofst2x->pwrofst2x_tbl_2g4[type][ch_grp] = 0; -+ } -+ txpwr_ofst2x->pwrofst2x_tbl_5g[type][ch_grp] = 0; -+ } -+ } -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x); -+ } -+ if (txpwr_ofst2x->enable){ -+ AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_ofst2x->enable); -+ AICWFDBG(LOGINFO, "pwrofst2x 2.4g: [0]:11b, [1]:ofdm_highrate, [2]:ofdm_lowrate\n" -+ " chan=" "\t1-4" "\t5-9" "\t10-13"); -+ for (type = 0; type < 3; type++) { -+ AICWFDBG(LOGINFO, "\n [%d] =", type); -+ for (ch_grp = 0; ch_grp < 3; ch_grp++) { -+ AICWFDBG(LOGINFO, "\t%d", txpwr_ofst2x->pwrofst2x_tbl_2g4[type][ch_grp]); -+ } -+ } -+ AICWFDBG(LOGINFO, "\npwrofst2x 5g: [0]:ofdm_lowrate, [1]:ofdm_highrate, [2]:ofdm_midrate\n" -+ " chan=" "\t36-50" "\t51-64" "\t98-114" "\t115-130" "\t131-146" "\t147-166"); -+ for (type = 0; type < 3; type++) { -+ AICWFDBG(LOGINFO, "\n [%d] =", type); -+ for (ch_grp = 0; ch_grp < 6; ch_grp++) { -+ AICWFDBG(LOGINFO, "\t%d", txpwr_ofst2x->pwrofst2x_tbl_5g[type][ch_grp]); -+ } -+ } -+ AICWFDBG(LOGINFO, "\n"); -+ -+ /* Send the MM_SET_TXPWR_OFST_REQ message to UMAC FW */ -+ error = rwnx_send_msg(rwnx_hw, txpwr_ofst_req, 1, MM_SET_TXPWR_OFST_CFM, NULL); -+ }else{ -+ AICWFDBG(LOGINFO, "%s:Do not use txpwr_ofst2x\r\n", __func__); -+ rwnx_msg_free(rwnx_hw, txpwr_ofst_req); -+ } -+ -+ return (error); -+} -+ -+/****************************************************************************** -+ * Control messages handling functions (FULLMAC only) -+ *****************************************************************************/ -+#ifdef CONFIG_RWNX_FULLMAC -+#ifdef CONFIG_HE_FOR_OLD_KERNEL -+extern struct ieee80211_sband_iftype_data rwnx_he_capa; -+#endif -+#ifdef CONFIG_VHT_FOR_OLD_KERNEL -+static struct ieee80211_sta_vht_cap* rwnx_vht_capa; -+#endif -+int rwnx_send_me_config_req(struct rwnx_hw *rwnx_hw) -+{ -+ struct me_config_req *req; -+ struct wiphy *wiphy = rwnx_hw->wiphy; -+ -+ struct ieee80211_sta_ht_cap *ht_cap; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) -+ struct ieee80211_sta_vht_cap *vht_cap; -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ struct ieee80211_sta_he_cap const *he_cap = NULL; -+#else -+ #ifdef CONFIG_HE_FOR_OLD_KERNEL -+ struct ieee80211_sta_he_cap const *he_cap; -+ #endif -+#endif -+ uint8_t *ht_mcs; -+ int i; -+ -+ if (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80) { -+ rwnx_hw->mod_params->use_80 = true; -+ } -+ -+ if (rwnx_hw->band_5g_support) { -+ ht_cap = &wiphy->bands[NL80211_BAND_5GHZ]->ht_cap; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) -+ vht_cap = &wiphy->bands[NL80211_BAND_5GHZ]->vht_cap; -+ #endif -+ } else { -+ ht_cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) -+ vht_cap = &wiphy->bands[NL80211_BAND_2GHZ]->vht_cap; -+ #endif -+ } -+ #ifdef CONFIG_VHT_FOR_OLD_KERNEL -+ rwnx_vht_capa = vht_cap; -+ #endif -+ -+ ht_mcs = (uint8_t *)&ht_cap->mcs; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the ME_CONFIG_REQ message */ -+ req = rwnx_msg_zalloc(ME_CONFIG_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_config_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_CONFIG_REQ message */ -+ req->ht_supp = ht_cap->ht_supported; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) -+ req->vht_supp = vht_cap->vht_supported; -+ #endif -+ req->ht_cap.ht_capa_info = cpu_to_le16(ht_cap->cap | IEEE80211_HT_CAP_LDPC_CODING); -+ req->ht_cap.a_mpdu_param = ht_cap->ampdu_factor | -+ (ht_cap->ampdu_density << -+ IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); -+ for (i = 0; i < sizeof(ht_cap->mcs); i++) -+ req->ht_cap.mcs_rate[i] = ht_mcs[i]; -+ req->ht_cap.ht_extended_capa = 0; -+ req->ht_cap.tx_beamforming_capa = 0; -+ req->ht_cap.asel_capa = 0; -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) -+ if (req->vht_supp) { -+ req->vht_cap.vht_capa_info = cpu_to_le32(vht_cap->cap); -+ req->vht_cap.rx_highest = cpu_to_le16(vht_cap->vht_mcs.rx_highest); -+ req->vht_cap.rx_mcs_map = cpu_to_le16(vht_cap->vht_mcs.rx_mcs_map); -+ req->vht_cap.tx_highest = cpu_to_le16(vht_cap->vht_mcs.tx_highest); -+ req->vht_cap.tx_mcs_map = cpu_to_le16(vht_cap->vht_mcs.tx_mcs_map); -+ } -+ #endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) || defined(CONFIG_HE_FOR_OLD_KERNEL) -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ if (wiphy->bands[NL80211_BAND_2GHZ]->iftype_data != NULL) { -+ he_cap = &wiphy->bands[NL80211_BAND_2GHZ]->iftype_data->he_cap; -+ //} -+ #endif -+ #if defined(CONFIG_HE_FOR_OLD_KERNEL) -+ if (1) { -+ he_cap = &rwnx_he_capa.he_cap; -+ #endif -+ req->he_supp = he_cap->has_he; -+ for (i = 0; i < ARRAY_SIZE(he_cap->he_cap_elem.mac_cap_info); i++) { -+ req->he_cap.mac_cap_info[i] = he_cap->he_cap_elem.mac_cap_info[i]; -+ } -+ for (i = 0; i < ARRAY_SIZE(he_cap->he_cap_elem.phy_cap_info); i++) { -+ req->he_cap.phy_cap_info[i] = he_cap->he_cap_elem.phy_cap_info[i]; -+ } -+ req->he_cap.mcs_supp.rx_mcs_80 = cpu_to_le16(he_cap->he_mcs_nss_supp.rx_mcs_80); -+ req->he_cap.mcs_supp.tx_mcs_80 = cpu_to_le16(he_cap->he_mcs_nss_supp.tx_mcs_80); -+ req->he_cap.mcs_supp.rx_mcs_160 = cpu_to_le16(he_cap->he_mcs_nss_supp.rx_mcs_160); -+ req->he_cap.mcs_supp.tx_mcs_160 = cpu_to_le16(he_cap->he_mcs_nss_supp.tx_mcs_160); -+ req->he_cap.mcs_supp.rx_mcs_80p80 = cpu_to_le16(he_cap->he_mcs_nss_supp.rx_mcs_80p80); -+ req->he_cap.mcs_supp.tx_mcs_80p80 = cpu_to_le16(he_cap->he_mcs_nss_supp.tx_mcs_80p80); -+ for (i = 0; i < MAC_HE_PPE_THRES_MAX_LEN; i++) { -+ req->he_cap.ppe_thres[i] = he_cap->ppe_thres[i]; -+ } -+ req->he_ul_on = rwnx_hw->mod_params->he_ul_on; -+ } -+#else -+ req->he_supp = false; -+ req->he_ul_on = false; -+#endif -+ req->ps_on = rwnx_hw->mod_params->ps_on; -+ req->dpsm = rwnx_hw->mod_params->dpsm; -+ req->tx_lft = rwnx_hw->mod_params->tx_lft; -+ req->ant_div_on = rwnx_hw->mod_params->ant_div; -+ if (rwnx_hw->mod_params->use_80) -+ req->phy_bw_max = PHY_CHNL_BW_80; -+ else if (rwnx_hw->mod_params->use_2040) -+ req->phy_bw_max = PHY_CHNL_BW_40; -+ else -+ req->phy_bw_max = PHY_CHNL_BW_20; -+ -+ wiphy_info(wiphy, "HT supp %d, VHT supp %d, HE supp %d\n", req->ht_supp, -+ req->vht_supp, -+ req->he_supp); -+ /* Send the ME_CONFIG_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, ME_CONFIG_CFM, NULL); -+} -+ -+int rwnx_send_me_chan_config_req(struct rwnx_hw *rwnx_hw) -+{ -+ struct me_chan_config_req *req; -+ struct wiphy *wiphy = rwnx_hw->wiphy; -+ int i; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the ME_CHAN_CONFIG_REQ message */ -+ req = rwnx_msg_zalloc(ME_CHAN_CONFIG_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_chan_config_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ req->chan2G4_cnt = 0; -+ if (wiphy->bands[NL80211_BAND_2GHZ] != NULL) { -+ struct ieee80211_supported_band *b = wiphy->bands[NL80211_BAND_2GHZ]; -+ for (i = 0; i < b->n_channels; i++) { -+ req->chan2G4[req->chan2G4_cnt].flags = 0; -+ if (b->channels[i].flags & IEEE80211_CHAN_DISABLED) -+ req->chan2G4[req->chan2G4_cnt].flags |= CHAN_DISABLED; -+ req->chan2G4[req->chan2G4_cnt].flags |= get_chan_flags(b->channels[i].flags); -+ req->chan2G4[req->chan2G4_cnt].band = NL80211_BAND_2GHZ; -+ req->chan2G4[req->chan2G4_cnt].freq = b->channels[i].center_freq; -+ req->chan2G4[req->chan2G4_cnt].tx_power = chan_to_fw_pwr(b->channels[i].max_power); -+ req->chan2G4_cnt++; -+ if (req->chan2G4_cnt == MAC_DOMAINCHANNEL_24G_MAX) -+ break; -+ } -+ } -+ -+ req->chan5G_cnt = 0; -+ if (wiphy->bands[NL80211_BAND_5GHZ] != NULL) { -+ struct ieee80211_supported_band *b = wiphy->bands[NL80211_BAND_5GHZ]; -+ for (i = 0; i < b->n_channels; i++) { -+ req->chan5G[req->chan5G_cnt].flags = 0; -+ if (b->channels[i].flags & IEEE80211_CHAN_DISABLED) -+ req->chan5G[req->chan5G_cnt].flags |= CHAN_DISABLED; -+ req->chan5G[req->chan5G_cnt].flags |= get_chan_flags(b->channels[i].flags); -+ req->chan5G[req->chan5G_cnt].band = NL80211_BAND_5GHZ; -+ req->chan5G[req->chan5G_cnt].freq = b->channels[i].center_freq; -+ req->chan5G[req->chan5G_cnt].tx_power = chan_to_fw_pwr(b->channels[i].max_power); -+ req->chan5G_cnt++; -+ if (req->chan5G_cnt == MAC_DOMAINCHANNEL_5G_MAX) -+ break; -+ } -+ } -+ -+ /* Send the ME_CHAN_CONFIG_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, ME_CHAN_CONFIG_CFM, NULL); -+} -+ -+int rwnx_send_me_set_control_port_req(struct rwnx_hw *rwnx_hw, bool opened, u8 sta_idx) -+{ -+ struct me_set_control_port_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the ME_SET_CONTROL_PORT_REQ message */ -+ req = rwnx_msg_zalloc(ME_SET_CONTROL_PORT_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_set_control_port_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_SET_CONTROL_PORT_REQ message */ -+ req->sta_idx = sta_idx; -+ req->control_port_open = opened; -+ -+ /* Send the ME_SET_CONTROL_PORT_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, ME_SET_CONTROL_PORT_CFM, NULL); -+} -+ -+int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *params, -+ const u8 *mac, u8 inst_nbr, struct me_sta_add_cfm *cfm) -+{ -+ struct me_sta_add_req *req; -+ -+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION -+ struct link_station_parameters *link_sta_params = ¶ms->link_sta_params; -+#else -+ struct station_parameters *link_sta_params = params; -+#endif -+ u8 *ht_mcs = (u8 *)&link_sta_params->ht_capa->mcs; -+ -+ int i; -+ struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[inst_nbr]; -+ #if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL) -+ struct aic_sta *sta = &rwnx_hw->aic_table[rwnx_vif->ap.aic_index]; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ printk("assoc_req idx %d, he: %d, vht: %d\n ", rwnx_vif->ap.aic_index, sta->he, sta->vht); -+ if (rwnx_vif->ap.aic_index < NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX) -+ rwnx_vif->ap.aic_index++; -+ else -+ rwnx_vif->ap.aic_index = 0; -+ #endif -+ -+ /* Build the MM_STA_ADD_REQ message */ -+ req = rwnx_msg_zalloc(ME_STA_ADD_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_sta_add_req)); -+ if (!req){ -+ return -ENOMEM; -+ } -+ -+ /* Set parameters for the MM_STA_ADD_REQ message */ -+ memcpy(&(req->mac_addr.array[0]), mac, ETH_ALEN); -+ -+ req->rate_set.length = link_sta_params->supported_rates_len; -+ for (i = 0; i < link_sta_params->supported_rates_len; i++) -+ req->rate_set.array[i] = link_sta_params->supported_rates[i]; -+ -+ req->flags = 0; -+ if (link_sta_params->ht_capa) { -+ const struct ieee80211_ht_cap *ht_capa = link_sta_params->ht_capa; -+ -+ req->flags |= STA_HT_CAPA; -+ req->ht_cap.ht_capa_info = cpu_to_le16(ht_capa->cap_info); -+ req->ht_cap.a_mpdu_param = ht_capa->ampdu_params_info; -+ for (i = 0; i < sizeof(ht_capa->mcs); i++) -+ req->ht_cap.mcs_rate[i] = ht_mcs[i]; -+ req->ht_cap.ht_extended_capa = cpu_to_le16(ht_capa->extended_ht_cap_info); -+ req->ht_cap.tx_beamforming_capa = cpu_to_le32(ht_capa->tx_BF_cap_info); -+ req->ht_cap.asel_capa = ht_capa->antenna_selection_info; -+ } -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) -+ if (link_sta_params->vht_capa) { -+ const struct ieee80211_vht_cap *vht_capa = link_sta_params->vht_capa; -+ -+ req->flags |= STA_VHT_CAPA; -+ req->vht_cap.vht_capa_info = cpu_to_le32(vht_capa->vht_cap_info); -+ req->vht_cap.rx_highest = cpu_to_le16(vht_capa->supp_mcs.rx_highest); -+ req->vht_cap.rx_mcs_map = cpu_to_le16(vht_capa->supp_mcs.rx_mcs_map); -+ req->vht_cap.tx_highest = cpu_to_le16(vht_capa->supp_mcs.tx_highest); -+ req->vht_cap.tx_mcs_map = cpu_to_le16(vht_capa->supp_mcs.tx_mcs_map); -+ } -+#elif defined(CONFIG_VHT_FOR_OLD_KERNEL) -+ if (sta->vht) { -+ const struct ieee80211_vht_cap *vht_capa = rwnx_vht_capa; -+ -+ req->flags |= STA_VHT_CAPA; -+ req->vht_cap.vht_capa_info = cpu_to_le32(vht_capa->vht_cap_info); -+ req->vht_cap.rx_highest = cpu_to_le16(vht_capa->supp_mcs.rx_highest); -+ req->vht_cap.rx_mcs_map = cpu_to_le16(vht_capa->supp_mcs.rx_mcs_map); -+ req->vht_cap.tx_highest = cpu_to_le16(vht_capa->supp_mcs.tx_highest); -+ req->vht_cap.tx_mcs_map = cpu_to_le16(vht_capa->supp_mcs.tx_mcs_map); -+ } -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) -+ if (link_sta_params->he_capa) { -+ const struct ieee80211_he_cap_elem *he_capa = link_sta_params->he_capa; -+ struct ieee80211_he_mcs_nss_supp *mcs_nss_supp = -+ (struct ieee80211_he_mcs_nss_supp *)(he_capa + 1); -+ -+ req->flags |= STA_HE_CAPA; -+ for (i = 0; i < ARRAY_SIZE(he_capa->mac_cap_info); i++) { -+ req->he_cap.mac_cap_info[i] = he_capa->mac_cap_info[i]; -+ } -+ for (i = 0; i < ARRAY_SIZE(he_capa->phy_cap_info); i++) { -+ req->he_cap.phy_cap_info[i] = he_capa->phy_cap_info[i]; -+ } -+ req->he_cap.mcs_supp.rx_mcs_80 = mcs_nss_supp->rx_mcs_80; -+ req->he_cap.mcs_supp.tx_mcs_80 = mcs_nss_supp->tx_mcs_80; -+ req->he_cap.mcs_supp.rx_mcs_160 = mcs_nss_supp->rx_mcs_160; -+ req->he_cap.mcs_supp.tx_mcs_160 = mcs_nss_supp->tx_mcs_160; -+ req->he_cap.mcs_supp.rx_mcs_80p80 = mcs_nss_supp->rx_mcs_80p80; -+ req->he_cap.mcs_supp.tx_mcs_80p80 = mcs_nss_supp->tx_mcs_80p80; -+ } -+#else -+ #ifdef CONFIG_HE_FOR_OLD_KERNEL -+ if (sta->he) { -+ const struct ieee80211_he_cap_elem *he_capa = &rwnx_he_capa.he_cap.he_cap_elem; -+ struct ieee80211_he_mcs_nss_supp *mcs_nss_supp = -+ (struct ieee80211_he_mcs_nss_supp *)(he_capa + 1); -+ req->flags |= STA_HE_CAPA; -+ for (i = 0; i < ARRAY_SIZE(he_capa->mac_cap_info); i++) { -+ req->he_cap.mac_cap_info[i] = he_capa->mac_cap_info[i]; -+ } -+ for (i = 0; i < ARRAY_SIZE(he_capa->phy_cap_info); i++) { -+ req->he_cap.phy_cap_info[i] = he_capa->phy_cap_info[i]; -+ } -+ req->he_cap.mcs_supp.rx_mcs_80 = mcs_nss_supp->rx_mcs_80; -+ req->he_cap.mcs_supp.tx_mcs_80 = mcs_nss_supp->tx_mcs_80; -+ req->he_cap.mcs_supp.rx_mcs_160 = mcs_nss_supp->rx_mcs_160; -+ req->he_cap.mcs_supp.tx_mcs_160 = mcs_nss_supp->tx_mcs_160; -+ req->he_cap.mcs_supp.rx_mcs_80p80 = mcs_nss_supp->rx_mcs_80p80; -+ req->he_cap.mcs_supp.tx_mcs_80p80 = mcs_nss_supp->tx_mcs_80p80; -+ } -+ #endif -+#endif -+ -+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) -+ req->flags |= STA_QOS_CAPA; -+ -+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_MFP)) -+ req->flags |= STA_MFP_CAPA; -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ if (link_sta_params->opmode_notif_used) { -+ req->flags |= STA_OPMOD_NOTIF; -+ req->opmode = link_sta_params->opmode_notif_used; -+ } -+ #endif -+ -+ req->aid = cpu_to_le16(params->aid); -+ req->uapsd_queues = params->uapsd_queues; -+ req->max_sp_len = params->max_sp * 2; -+ req->vif_idx = inst_nbr; -+ -+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) { -+ //struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[inst_nbr]; -+ req->tdls_sta = true; -+ if ((params->ext_capab[3] & WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) && -+ !rwnx_vif->tdls_chsw_prohibited) -+ req->tdls_chsw_allowed = true; -+ if (rwnx_vif->tdls_status == TDLS_SETUP_RSP_TX) -+ req->tdls_sta_initiator = true; -+ } -+ -+ /* Send the ME_STA_ADD_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, ME_STA_ADD_CFM, cfm); -+} -+ -+int rwnx_send_me_sta_del(struct rwnx_hw *rwnx_hw, u8 sta_idx, bool tdls_sta) -+{ -+ struct me_sta_del_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_STA_DEL_REQ message */ -+ req = rwnx_msg_zalloc(ME_STA_DEL_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_sta_del_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_STA_DEL_REQ message */ -+ req->sta_idx = sta_idx; -+ req->tdls_sta = tdls_sta; -+ -+ /* Send the ME_STA_DEL_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, ME_STA_DEL_CFM, NULL); -+} -+ -+int rwnx_send_me_traffic_ind(struct rwnx_hw *rwnx_hw, u8 sta_idx, bool uapsd, u8 tx_status) -+{ -+ struct me_traffic_ind_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the ME_UTRAFFIC_IND_REQ message */ -+ req = rwnx_msg_zalloc(ME_TRAFFIC_IND_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_traffic_ind_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_TRAFFIC_IND_REQ message */ -+ req->sta_idx = sta_idx; -+ req->tx_avail = tx_status; -+ req->uapsd = uapsd; -+ -+ /* Send the ME_TRAFFIC_IND_REQ to UMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, ME_TRAFFIC_IND_CFM, NULL); -+} -+ -+int rwnx_send_me_rc_stats(struct rwnx_hw *rwnx_hw, -+ u8 sta_idx, -+ struct me_rc_stats_cfm *cfm) -+{ -+ struct me_rc_stats_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the ME_RC_STATS_REQ message */ -+ req = rwnx_msg_zalloc(ME_RC_STATS_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_rc_stats_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_RC_STATS_REQ message */ -+ req->sta_idx = sta_idx; -+ -+ /* Send the ME_RC_STATS_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, ME_RC_STATS_CFM, cfm); -+} -+ -+int rwnx_send_me_rc_set_rate(struct rwnx_hw *rwnx_hw, -+ u8 sta_idx, -+ u16 rate_cfg) -+{ -+ struct me_rc_set_rate_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the ME_RC_SET_RATE_REQ message */ -+ req = rwnx_msg_zalloc(ME_RC_SET_RATE_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_rc_set_rate_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_RC_SET_RATE_REQ message */ -+ req->sta_idx = sta_idx; -+ req->fixed_rate_cfg = rate_cfg; -+ -+ /* Send the ME_RC_SET_RATE_REQ message to FW */ -+ return rwnx_send_msg(rwnx_hw, req, 0, 0, NULL); -+} -+ -+int rwnx_send_me_set_ps_mode(struct rwnx_hw *rwnx_hw, u8 ps_mode) -+{ -+ struct me_set_ps_mode_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the ME_SET_PS_MODE_REQ message */ -+ req = rwnx_msg_zalloc(ME_SET_PS_MODE_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_set_ps_mode_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_SET_PS_MODE_REQ message */ -+ req->ps_state = ps_mode; -+ -+ /* Send the ME_SET_PS_MODE_REQ message to FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, ME_SET_PS_MODE_CFM, NULL); -+} -+ -+int rwnx_send_me_set_lp_level(struct rwnx_hw *rwnx_hw, u8 lp_level) -+{ -+ struct me_set_lp_level_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the ME_SET_LP_LEVEL_REQ message */ -+ req = rwnx_msg_zalloc(ME_SET_LP_LEVEL_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_set_lp_level_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the ME_SET_LP_LEVEL_REQ message */ -+ req->lp_level = lp_level; -+ -+ /* Send the ME_SET_LP_LEVEL_REQ message to FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, ME_SET_LP_LEVEL_CFM, NULL); -+} -+ -+int rwnx_send_sm_connect_req(struct rwnx_hw *rwnx_hw, -+ struct rwnx_vif *rwnx_vif, -+ struct cfg80211_connect_params *sme, -+ struct sm_connect_cfm *cfm) -+{ -+ struct sm_connect_req *req; -+ int i; -+ u32_l flags = 0; -+ bool gval = false; -+ bool pval = false; -+ rwnx_vif->wep_enabled = false; -+ rwnx_vif->wep_auth_err = false; -+ rwnx_vif->last_auth_type = 0; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the SM_CONNECT_REQ message */ -+ req = rwnx_msg_zalloc(SM_CONNECT_REQ, TASK_SM, DRV_TASK_ID, -+ sizeof(struct sm_connect_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ if ((sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) || -+ (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104)) { -+ gval = true; -+ } -+ -+ if (sme->crypto.n_ciphers_pairwise && -+ ((sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP40) || -+ (sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP104))) { -+ pval = true; -+ } -+ -+ /* Set parameters for the SM_CONNECT_REQ message */ -+ if (sme->crypto.n_ciphers_pairwise && -+ ((sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP40) || -+ (sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_TKIP) || -+ (sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP104))) -+ flags |= DISABLE_HT; -+ -+ if (sme->crypto.control_port) -+ flags |= CONTROL_PORT_HOST; -+ -+ if (sme->crypto.control_port_no_encrypt) -+ flags |= CONTROL_PORT_NO_ENC; -+ -+ if (use_pairwise_key(&sme->crypto)) -+ flags |= WPA_WPA2_IN_USE; -+ -+ if (sme->mfp == NL80211_MFP_REQUIRED) -+ flags |= MFP_IN_USE; -+ -+ if (rwnx_vif->sta.ap) -+ flags |= REASSOCIATION; -+ -+ req->ctrl_port_ethertype = sme->crypto.control_port_ethertype; -+ -+ if (sme->bssid) -+ memcpy(&req->bssid, sme->bssid, ETH_ALEN); -+ else -+ req->bssid = mac_addr_bcst; -+ req->vif_idx = rwnx_vif->vif_index; -+ if (sme->channel) { -+ req->chan.band = sme->channel->band; -+ req->chan.freq = sme->channel->center_freq; -+ req->chan.flags = get_chan_flags(sme->channel->flags); -+ } else { -+ req->chan.freq = (u16_l)-1; -+ } -+ for (i = 0; i < sme->ssid_len; i++) -+ req->ssid.array[i] = sme->ssid[i]; -+ req->ssid.length = sme->ssid_len; -+ req->flags = flags; -+ if (WARN_ON(sme->ie_len > sizeof(req->ie_buf))) -+ goto invalid_param; -+ if (sme->ie_len) -+ memcpy(req->ie_buf, sme->ie, sme->ie_len); -+ req->ie_len = sme->ie_len; -+ req->listen_interval = rwnx_mod_params.listen_itv; -+ req->dont_wait_bcmc = !rwnx_mod_params.listen_bcmc; -+ -+ /* Set auth_type */ -+ if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) -+ req->auth_type = WLAN_AUTH_OPEN; -+ else if (sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) -+ req->auth_type = WLAN_AUTH_OPEN; -+ else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) -+ req->auth_type = WLAN_AUTH_SHARED_KEY; -+ else if (sme->auth_type == NL80211_AUTHTYPE_FT) { -+ req->auth_type = WLAN_AUTH_FT; -+ } else if (sme->auth_type == NL80211_AUTHTYPE_SAE) -+ req->auth_type = WLAN_AUTH_SAE; -+ else -+ goto invalid_param; -+ -+ /* Set UAPSD queues */ -+ req->uapsd_queues = rwnx_mod_params.uapsd_queues; -+ -+ rwnx_vif->wep_enabled = pval & gval; -+ -+ if (rwnx_vif->wep_enabled) { -+ rwnx_vif->last_auth_type = sme->auth_type; -+ } -+ -+ rwnx_vif->sta.ssid_len = (int)sme->ssid_len; -+ memset(rwnx_vif->sta.ssid, 0, rwnx_vif->sta.ssid_len + 1); -+ memcpy(rwnx_vif->sta.ssid, sme->ssid, rwnx_vif->sta.ssid_len); -+ if (sme->bssid) -+ memcpy(rwnx_vif->sta.bssid, sme->bssid, ETH_ALEN); -+ -+ printk("%s drv_vif_index:%d connect to %s(%d) channel:%d auth_type:%d\r\n", -+ __func__, -+ rwnx_vif->drv_vif_index, -+ rwnx_vif->sta.ssid, -+ rwnx_vif->sta.ssid_len, -+ req->chan.freq, -+ req->auth_type); -+ -+ /* Send the SM_CONNECT_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, SM_CONNECT_CFM, cfm); -+ -+invalid_param: -+ rwnx_msg_free(rwnx_hw, req); -+ return -EINVAL; -+} -+ -+int rwnx_send_sm_disconnect_req(struct rwnx_hw *rwnx_hw, -+ struct rwnx_vif *rwnx_vif, -+ u16 reason) -+{ -+ struct sm_disconnect_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the SM_DISCONNECT_REQ message */ -+ req = rwnx_msg_zalloc(SM_DISCONNECT_REQ, TASK_SM, DRV_TASK_ID, -+ sizeof(struct sm_disconnect_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the SM_DISCONNECT_REQ message */ -+ req->reason_code = reason; -+ req->vif_idx = rwnx_vif->vif_index; -+ -+ /* Send the SM_DISCONNECT_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, SM_DISCONNECT_CFM, NULL); -+} -+ -+int rwnx_send_sm_external_auth_required_rsp(struct rwnx_hw *rwnx_hw, -+ struct rwnx_vif *rwnx_vif, -+ u16 status) -+{ -+ struct sm_external_auth_required_rsp *rsp; -+ -+ /* Build the SM_EXTERNAL_AUTH_CFM message */ -+ rsp = rwnx_msg_zalloc(SM_EXTERNAL_AUTH_REQUIRED_RSP, TASK_SM, DRV_TASK_ID, -+ sizeof(struct sm_external_auth_required_rsp)); -+ if (!rsp) -+ return -ENOMEM; -+ -+ rsp->status = status; -+ rsp->vif_idx = rwnx_vif->vif_index; -+ -+ /* send the SM_EXTERNAL_AUTH_REQUIRED_RSP message UMAC FW */ -+ return rwnx_send_msg(rwnx_hw, rsp, 1, SM_EXTERNAL_AUTH_REQUIRED_RSP_CFM, NULL); -+} -+ -+int rwnx_send_apm_start_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ struct cfg80211_ap_settings *settings, -+ struct apm_start_cfm *cfm, -+ struct rwnx_ipc_elem_var *elem) -+{ -+ struct apm_start_req *req; -+ struct rwnx_bcn *bcn = &vif->ap.bcn; -+ u8 *buf; -+ u32 flags = 0; -+ const u8 *rate_ie; -+ u8 rate_len = 0; -+ int var_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); -+ const u8 *var_pos; -+ int len, i; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the APM_START_REQ message */ -+ req = rwnx_msg_zalloc(APM_START_REQ, TASK_APM, DRV_TASK_ID, -+ sizeof(struct apm_start_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ // Build the beacon -+ bcn->dtim = (u8)settings->dtim_period; -+ buf = rwnx_build_bcn(bcn, &settings->beacon); -+ if (!buf) { -+ rwnx_msg_free(rwnx_hw, req); -+ return -ENOMEM; -+ } -+ -+ // Retrieve the basic rate set from the beacon buffer -+ len = bcn->len - var_offset; -+ var_pos = buf + var_offset; -+ -+// Assume that rate higher that 54 Mbps are BSS membership -+#define IS_BASIC_RATE(r) ((r & 0x80) && ((r & ~0x80) <= (54 * 2))) -+ -+ rate_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len); -+ if (rate_ie) { -+ const u8 *rates = rate_ie + 2; -+ for (i = 0; (i < rate_ie[1]) && (rate_len < MAC_RATESET_LEN); i++) { -+ if (IS_BASIC_RATE(rates[i])) -+ req->basic_rates.array[rate_len++] = rates[i]; -+ } -+ } -+ rate_ie = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, var_pos, len); -+ if (rate_ie) { -+ const u8 *rates = rate_ie + 2; -+ for (i = 0; (i < rate_ie[1]) && (rate_len < MAC_RATESET_LEN); i++) { -+ if (IS_BASIC_RATE(rates[i])) -+ req->basic_rates.array[rate_len++] = rates[i]; -+ } -+ } -+ req->basic_rates.length = rate_len; -+#undef IS_BASIC_RATE -+ -+#if 0 -+ // Sync buffer for FW -+ error = rwnx_ipc_elem_var_allocs(rwnx_hw, elem, bcn->len, DMA_TO_DEVICE, buf, NULL, NULL); -+ if (error) { -+ return error; -+ } -+#else -+ rwnx_send_bcn(rwnx_hw, buf, vif->vif_index, bcn->len); -+#endif -+ -+ /* Set parameters for the APM_START_REQ message */ -+ req->vif_idx = vif->vif_index; -+ req->bcn_addr = elem->dma_addr; -+ req->bcn_len = bcn->len; -+ req->tim_oft = bcn->head_len; -+ req->tim_len = bcn->tim_len; -+ req->chan.band = settings->chandef.chan->band; -+ req->chan.freq = settings->chandef.chan->center_freq; -+ req->chan.flags = 0; -+ req->chan.tx_power = chan_to_fw_pwr(settings->chandef.chan->max_power); -+ req->center_freq1 = settings->chandef.center_freq1; -+ req->center_freq2 = settings->chandef.center_freq2; -+ req->ch_width = bw2chnl[settings->chandef.width]; -+ req->bcn_int = settings->beacon_interval; -+ if (settings->crypto.control_port) -+ flags |= CONTROL_PORT_HOST; -+ -+ if (settings->crypto.control_port_no_encrypt) -+ flags |= CONTROL_PORT_NO_ENC; -+ -+ if (use_pairwise_key(&settings->crypto)) -+ flags |= WPA_WPA2_IN_USE; -+ -+ if (settings->crypto.control_port_ethertype) -+ req->ctrl_port_ethertype = settings->crypto.control_port_ethertype; -+ else -+ req->ctrl_port_ethertype = ETH_P_PAE; -+ req->flags = flags; -+ -+ /* Send the APM_START_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, APM_START_CFM, cfm); -+} -+ -+int rwnx_send_apm_stop_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif) -+{ -+ struct apm_stop_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the APM_STOP_REQ message */ -+ req = rwnx_msg_zalloc(APM_STOP_REQ, TASK_APM, DRV_TASK_ID, -+ sizeof(struct apm_stop_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the APM_STOP_REQ message */ -+ req->vif_idx = vif->vif_index; -+ -+ /* Send the APM_STOP_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, APM_STOP_CFM, NULL); -+} -+ -+uint8_t scanning;// = 0; -+ -+#define P2P_WILDCARD_SSID "DIRECT-" -+#define P2P_WILDCARD_SSID_LEN (sizeof(P2P_WILDCARD_SSID) - 1) -+ -+#ifdef CONFIG_SET_VENDOR_EXTENSION_IE -+u8_l vendor_extension_data[256]; -+u8_l vendor_extension_len = 0; -+#if 0 -+u8_l vendor_extension_data[]={ -+ 0x10,0x49,0x00,0x17,0x00,0x01,0x37,0x10, -+ 0x06,0x00,0x10,0xc5,0xc9,0x91,0xeb,0x1f, -+ 0xce,0x4d,0x00,0xa1,0x2a,0xdf,0xa1,0xe9, -+ 0xc3,0x44,0xe6,0x10,0x49,0x00,0x21,0x00, -+ 0x01,0x37,0x20,0x01,0x00,0x01,0x05,0x20, -+ 0x02,0x00,0x04,0x43,0x56,0x54,0x45,0x20, -+ 0x05,0x00,0x0d,0x31,0x39,0x32,0x2e,0x31, -+ 0x36,0x38,0x2e,0x31,0x35,0x34,0x2e,0x31}; -+#endif -+ -+void rwnx_insert_vendor_extension_data(struct scanu_vendor_ie_req *ie_req){ -+ u8_l temp_ie[256]; -+ u8_l vendor_extension_subelement[3] = {0x00,0x37,0x2A}; -+ u8_l vendor_extension_id[2] = {0x10,0x49}; -+ int index = 0; -+ int vendor_extension_subelement_len = 0; -+ -+ memset(temp_ie, 0, 256); -+ -+ //find vendor_extension_subelement -+ for(index = 0; index < ie_req->add_ie_len; index++){ -+ if(ie_req->ie[index] == vendor_extension_id[0]){ -+ index++; -+ if(index == ie_req->add_ie_len){ -+ return; -+ } -+ if(ie_req->ie[index] == vendor_extension_id[1] && -+ ie_req->ie[index + 3] == vendor_extension_subelement[0]&& -+ ie_req->ie[index + 4] == vendor_extension_subelement[1]&& -+ ie_req->ie[index + 5] == vendor_extension_subelement[2]){ -+ index = index + 2; -+ vendor_extension_subelement_len = ie_req->ie[index]; -+ printk("%s find vendor_extension_subelement,index:%d len:%d\r\n", __func__, index, ie_req->ie[index]); -+ break; -+ } -+ } -+ } -+ index = index + vendor_extension_subelement_len; -+ -+ //insert vendor extension -+ memcpy(&temp_ie[0], ie_req->ie, index + 1); -+ memcpy(&temp_ie[index + 1], vendor_extension_data, vendor_extension_len/*sizeof(vendor_extension_data)*/);//insert vendor extension data -+ memcpy(&temp_ie[index + 1 + vendor_extension_len/*sizeof(vendor_extension_data)*/], &ie_req->ie[index + 1], ie_req->add_ie_len - index); -+ -+ memcpy(ie_req->ie, temp_ie, ie_req->add_ie_len + vendor_extension_len/*sizeof(vendor_extension_data)*/); -+ ie_req->add_ie_len = ie_req->add_ie_len + vendor_extension_len/*sizeof(vendor_extension_data)*/; -+ ie_req->ie[1] = ie_req->ie[1] + vendor_extension_len/*sizeof(vendor_extension_data)*/; -+ -+ //rwnx_data_dump((char*)__func__, (void*)ie_req->ie, ie_req->add_ie_len); -+} -+#endif//CONFIG_SET_VENDOR_EXTENSION_IE -+ -+ -+int rwnx_send_scanu_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct cfg80211_scan_request *param) -+{ -+ struct scanu_start_req *req = NULL; -+ struct scanu_vendor_ie_req *ie_req = NULL; -+ struct mm_add_if_cfm add_if_cfm; -+ int i; -+ uint8_t chan_flags = 0; -+ int err; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the SCANU_START_REQ message */ -+ req = rwnx_msg_zalloc(SCANU_START_REQ, TASK_SCANU, DRV_TASK_ID, -+ sizeof(struct scanu_start_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ scanning = 1; -+ /* Set parameters */ -+ req->vif_idx = rwnx_vif->vif_index; -+ req->chan_cnt = (u8)min_t(int, SCAN_CHANNEL_MAX, param->n_channels); -+ req->ssid_cnt = (u8)min_t(int, SCAN_SSID_MAX, param->n_ssids); -+ req->bssid = mac_addr_bcst; -+ req->no_cck = param->no_cck; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) -+ if (param->duration_mandatory) -+ //req->duration = ieee80211_tu_to_usec(param->duration); -+ req->duration = 0; -+#endif -+ -+#ifdef RADAR_OR_IR_DETECT -+ if (req->ssid_cnt == 0) -+ chan_flags |= CHAN_NO_IR; -+#endif -+ for (i = 0; i < req->ssid_cnt; i++) { -+ int j; -+ for (j = 0; j < param->ssids[i].ssid_len; j++) -+ req->ssid[i].array[j] = param->ssids[i].ssid[j]; -+ req->ssid[i].length = param->ssids[i].ssid_len; -+ -+ if (!memcmp(P2P_WILDCARD_SSID, param->ssids[i].ssid, -+ P2P_WILDCARD_SSID_LEN)) { -+ AICWFDBG(LOGINFO, "p2p scanu:%d,%d,%d\n", rwnx_vif->vif_index, rwnx_vif->is_p2p_vif, rwnx_hw->is_p2p_alive); -+#ifdef CONFIG_USE_P2P0 -+ if (rwnx_vif->is_p2p_vif && !rwnx_hw->is_p2p_alive) { -+#else -+ if (rwnx_vif == rwnx_hw->p2p_dev_vif && !rwnx_vif->up) { -+#endif -+ err = rwnx_send_add_if (rwnx_hw, rwnx_vif->wdev.address, -+ RWNX_VIF_TYPE(rwnx_vif), false, &add_if_cfm); -+ if (err) -+ goto error; -+ -+ if (add_if_cfm.status != 0) { -+ return -EIO; -+ } -+ -+ /* Save the index retrieved from LMAC */ -+ spin_lock_bh(&rwnx_hw->cb_lock); -+ rwnx_vif->vif_index = add_if_cfm.inst_nbr; -+ rwnx_vif->up = true; -+ rwnx_hw->vif_started++; -+ rwnx_hw->vif_table[add_if_cfm.inst_nbr] = rwnx_vif; -+ spin_unlock_bh(&rwnx_hw->cb_lock); -+ } -+ rwnx_hw->is_p2p_alive = 1; -+#ifndef CONFIG_USE_P2P0 -+ mod_timer(&rwnx_hw->p2p_alive_timer, jiffies + msecs_to_jiffies(1000)); -+ atomic_set(&rwnx_hw->p2p_alive_timer_count, 0); -+#endif -+ AICWFDBG(LOGINFO, "p2p scan start\n"); -+ } -+ } -+ -+#if 1 -+ if (param->ie) { -+ #if 0 -+ if (rwnx_ipc_elem_var_allocs(rwnx_hw, &rwnx_hw->scan_ie, -+ param->ie_len, DMA_TO_DEVICE, -+ NULL, param->ie, NULL)) -+ goto error; -+ -+ req->add_ie_len = param->ie_len; -+ req->add_ies = rwnx_hw->scan_ie.dma_addr; -+ #else -+ ie_req = rwnx_msg_zalloc(SCANU_VENDOR_IE_REQ, TASK_SCANU, DRV_TASK_ID, -+ sizeof(struct scanu_vendor_ie_req)); -+ if (!ie_req) -+ return -ENOMEM; -+ -+ ie_req->add_ie_len = param->ie_len; -+ ie_req->vif_idx = rwnx_vif->vif_index; -+ memcpy(ie_req->ie, param->ie, param->ie_len); -+#ifdef CONFIG_SET_VENDOR_EXTENSION_IE -+ rwnx_insert_vendor_extension_data(ie_req); -+#endif //CONFIG_SET_VENDOR_EXTENSION_IE -+ req->add_ie_len = 0; -+ req->add_ies = 0; -+ -+ err = rwnx_send_msg(rwnx_hw, ie_req, 1, SCANU_VENDOR_IE_CFM, NULL); -+ if (err) -+ goto error; -+ #endif -+ } -+ else { -+ req->add_ie_len = 0; -+ req->add_ies = 0; -+ } -+#else -+ req->add_ie_len = 0; -+ req->add_ies = 0; -+#endif -+ -+ for (i = 0; i < req->chan_cnt; i++) { -+ struct ieee80211_channel *chan = param->channels[i]; -+ AICWFDBG(LOGDEBUG, "scan channel:%d(%d) \r\n", ieee80211_frequency_to_channel(chan->center_freq), chan->center_freq); -+ req->chan[i].band = chan->band; -+ req->chan[i].freq = chan->center_freq; -+ req->chan[i].flags = chan_flags | get_chan_flags(chan->flags); -+ req->chan[i].tx_power = chan_to_fw_pwr(chan->max_reg_power); -+ } -+ -+ /* Send the SCANU_START_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, SCANU_START_CFM_ADDTIONAL, NULL); -+error: -+ if (req != NULL) -+ rwnx_msg_free(rwnx_hw, req); -+ if (ie_req != NULL) -+ rwnx_msg_free(rwnx_hw, ie_req); -+ return -ENOMEM; -+} -+ -+int rwnx_send_scanu_cancel_req(struct rwnx_hw *rwnx_hw, struct scan_cancel_cfm *cfm) -+{ -+ struct scan_cancel_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the SCAN_CANCEL_REQ message */ -+ req = rwnx_msg_zalloc(SCANU_CANCEL_REQ, TASK_SCANU, DRV_TASK_ID, -+ sizeof(struct scan_cancel_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Send the SCAN_CANCEL_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, SCANU_CANCEL_CFM, cfm); -+} -+ -+int rwnx_send_apm_start_cac_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ struct cfg80211_chan_def *chandef, -+ struct apm_start_cac_cfm *cfm) -+{ -+ struct apm_start_cac_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the APM_START_CAC_REQ message */ -+ req = rwnx_msg_zalloc(APM_START_CAC_REQ, TASK_APM, DRV_TASK_ID, -+ sizeof(struct apm_start_cac_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the APM_START_CAC_REQ message */ -+ req->vif_idx = vif->vif_index; -+ req->chan.band = chandef->chan->band; -+ req->chan.freq = chandef->chan->center_freq; -+ req->chan.flags = 0; -+ req->center_freq1 = chandef->center_freq1; -+ req->center_freq2 = chandef->center_freq2; -+ req->ch_width = bw2chnl[chandef->width]; -+ -+ /* Send the APM_START_CAC_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, APM_START_CAC_CFM, cfm); -+} -+ -+int rwnx_send_apm_stop_cac_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif) -+{ -+ struct apm_stop_cac_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the APM_STOP_CAC_REQ message */ -+ req = rwnx_msg_zalloc(APM_STOP_CAC_REQ, TASK_APM, DRV_TASK_ID, -+ sizeof(struct apm_stop_cac_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the APM_STOP_CAC_REQ message */ -+ req->vif_idx = vif->vif_index; -+ -+ /* Send the APM_STOP_CAC_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, APM_STOP_CAC_CFM, NULL); -+} -+ -+int rwnx_send_mesh_start_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ const struct mesh_config *conf, const struct mesh_setup *setup, -+ struct mesh_start_cfm *cfm) -+{ -+ // Message to send -+ struct mesh_start_req *req; -+ // Supported basic rates -+ struct ieee80211_supported_band *band_2GHz = rwnx_hw->wiphy->bands[NL80211_BAND_2GHZ]; -+ /* Counter */ -+ int i; -+ /* Return status */ -+ int status; -+ /* DMA Address to be unmapped after confirmation reception */ -+ u32 dma_addr = 0; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MESH_START_REQ message */ -+ req = rwnx_msg_zalloc(MESH_START_REQ, TASK_MESH, DRV_TASK_ID, -+ sizeof(struct mesh_start_req)); -+ if (!req) { -+ return -ENOMEM; -+ } -+ -+ req->vif_index = vif->vif_index; -+ req->bcn_int = setup->beacon_interval; -+ req->dtim_period = setup->dtim_period; -+ req->mesh_id_len = setup->mesh_id_len; -+ -+ for (i = 0; i < setup->mesh_id_len; i++) { -+ req->mesh_id[i] = *(setup->mesh_id + i); -+ } -+ -+ req->user_mpm = setup->user_mpm; -+ req->is_auth = setup->is_authenticated; -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) -+ req->auth_id = setup->auth_id; -+ #endif -+ req->ie_len = setup->ie_len; -+ -+ if (setup->ie_len) { -+ /* -+ * Need to provide a Virtual Address to the MAC so that it can download the -+ * additional information elements. -+ */ -+ req->ie_addr = dma_map_single(rwnx_hw->dev, (void *)setup->ie, -+ setup->ie_len, DMA_FROM_DEVICE); -+ -+ /* Check DMA mapping result */ -+ if (dma_mapping_error(rwnx_hw->dev, req->ie_addr)) { -+ printk(KERN_CRIT "%s - DMA Mapping error on additional IEs\n", __func__); -+ -+ /* Consider there is no Additional IEs */ -+ req->ie_len = 0; -+ } else { -+ /* Store DMA Address so that we can unmap the memory section once MESH_START_CFM is received */ -+ dma_addr = req->ie_addr; -+ } -+ } -+ -+ /* Provide rate information */ -+ req->basic_rates.length = 0; -+ for (i = 0; i < band_2GHz->n_bitrates; i++) { -+ u16 rate = band_2GHz->bitrates[i].bitrate; -+ -+ /* Read value is in in units of 100 Kbps, provided value is in units -+ * of 1Mbps, and multiplied by 2 so that 5.5 becomes 11 */ -+ rate = (rate << 1) / 10; -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) // TODO: check basic rates -+ if (setup->basic_rates & CO_BIT(i)) { -+ rate |= 0x80; -+ } -+ #endif -+ -+ req->basic_rates.array[i] = (u8)rate; -+ req->basic_rates.length++; -+ } -+ -+ /* Provide channel information */ -+ req->chan.band = setup->chandef.chan->band; -+ req->chan.freq = setup->chandef.chan->center_freq; -+ req->chan.flags = 0; -+ req->chan.tx_power = chan_to_fw_pwr(setup->chandef.chan->max_power); -+ req->center_freq1 = setup->chandef.center_freq1; -+ req->center_freq2 = setup->chandef.center_freq2; -+ req->ch_width = bw2chnl[setup->chandef.width]; -+ -+ /* Send the MESH_START_REQ message to UMAC FW */ -+ status = rwnx_send_msg(rwnx_hw, req, 1, MESH_START_CFM, cfm); -+ -+ /* Unmap DMA area */ -+ if (setup->ie_len) { -+ dma_unmap_single(rwnx_hw->dev, dma_addr, setup->ie_len, DMA_TO_DEVICE); -+ } -+ -+ /* Return the status */ -+ return status; -+} -+ -+int rwnx_send_mesh_stop_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ struct mesh_stop_cfm *cfm) -+{ -+ // Message to send -+ struct mesh_stop_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MESH_STOP_REQ message */ -+ req = rwnx_msg_zalloc(MESH_STOP_REQ, TASK_MESH, DRV_TASK_ID, -+ sizeof(struct mesh_stop_req)); -+ if (!req) { -+ return -ENOMEM; -+ } -+ -+ req->vif_idx = vif->vif_index; -+ -+ /* Send the MESH_STOP_REQ message to UMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, MESH_STOP_CFM, cfm); -+} -+ -+int rwnx_send_mesh_update_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ u32 mask, const struct mesh_config *p_mconf, struct mesh_update_cfm *cfm) -+{ -+ // Message to send -+ struct mesh_update_req *req; -+ // Keep only bit for fields which can be updated -+ u32 supp_mask = (mask << 1) & (CO_BIT(NL80211_MESHCONF_GATE_ANNOUNCEMENTS) -+ | CO_BIT(NL80211_MESHCONF_HWMP_ROOTMODE) -+ | CO_BIT(NL80211_MESHCONF_FORWARDING) -+ | CO_BIT(NL80211_MESHCONF_POWER_MODE)); -+ -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (!supp_mask) { -+ return -ENOENT; -+ } -+ -+ /* Build the MESH_UPDATE_REQ message */ -+ req = rwnx_msg_zalloc(MESH_UPDATE_REQ, TASK_MESH, DRV_TASK_ID, -+ sizeof(struct mesh_update_req)); -+ -+ if (!req) { -+ return -ENOMEM; -+ } -+ -+ req->vif_idx = vif->vif_index; -+ -+ if (supp_mask & CO_BIT(NL80211_MESHCONF_GATE_ANNOUNCEMENTS)) { -+ req->flags |= CO_BIT(MESH_UPDATE_FLAGS_GATE_MODE_BIT); -+ req->gate_announ = p_mconf->dot11MeshGateAnnouncementProtocol; -+ } -+ -+ if (supp_mask & CO_BIT(NL80211_MESHCONF_HWMP_ROOTMODE)) { -+ req->flags |= CO_BIT(MESH_UPDATE_FLAGS_ROOT_MODE_BIT); -+ req->root_mode = p_mconf->dot11MeshHWMPRootMode; -+ } -+ -+ if (supp_mask & CO_BIT(NL80211_MESHCONF_FORWARDING)) { -+ req->flags |= CO_BIT(MESH_UPDATE_FLAGS_MESH_FWD_BIT); -+ req->mesh_forward = p_mconf->dot11MeshForwarding; -+ } -+ -+ if (supp_mask & CO_BIT(NL80211_MESHCONF_POWER_MODE)) { -+ req->flags |= CO_BIT(MESH_UPDATE_FLAGS_LOCAL_PSM_BIT); -+ req->local_ps_mode = p_mconf->power_mode; -+ } -+ -+ /* Send the MESH_UPDATE_REQ message to UMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, MESH_UPDATE_CFM, cfm); -+} -+ -+int rwnx_send_mesh_peer_info_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ u8 sta_idx, struct mesh_peer_info_cfm *cfm) -+{ -+ // Message to send -+ struct mesh_peer_info_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MESH_PEER_INFO_REQ message */ -+ req = rwnx_msg_zalloc(MESH_PEER_INFO_REQ, TASK_MESH, DRV_TASK_ID, -+ sizeof(struct mesh_peer_info_req)); -+ if (!req) { -+ return -ENOMEM; -+ } -+ -+ req->sta_idx = sta_idx; -+ -+ /* Send the MESH_PEER_INFO_REQ message to UMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, MESH_PEER_INFO_CFM, cfm); -+} -+ -+void rwnx_send_mesh_peer_update_ntf(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ u8 sta_idx, u8 mlink_state) -+{ -+ // Message to send -+ struct mesh_peer_update_ntf *ntf; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MESH_PEER_UPDATE_NTF message */ -+ ntf = rwnx_msg_zalloc(MESH_PEER_UPDATE_NTF, TASK_MESH, DRV_TASK_ID, -+ sizeof(struct mesh_peer_update_ntf)); -+ -+ if (ntf) { -+ ntf->vif_idx = vif->vif_index; -+ ntf->sta_idx = sta_idx; -+ ntf->state = mlink_state; -+ -+ /* Send the MESH_PEER_INFO_REQ message to UMAC FW */ -+ rwnx_send_msg(rwnx_hw, ntf, 0, 0, NULL); -+ } -+} -+ -+void rwnx_send_mesh_path_create_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, u8 *tgt_addr) -+{ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Check if we are already waiting for a confirmation */ -+ if (!vif->ap.create_path) { -+ // Message to send -+ struct mesh_path_create_req *req; -+ -+ /* Build the MESH_PATH_CREATE_REQ message */ -+ req = rwnx_msg_zalloc(MESH_PATH_CREATE_REQ, TASK_MESH, DRV_TASK_ID, -+ sizeof(struct mesh_path_create_req)); -+ -+ if (req) { -+ req->vif_idx = vif->vif_index; -+ memcpy(&req->tgt_mac_addr, tgt_addr, ETH_ALEN); -+ -+ vif->ap.create_path = true; -+ -+ /* Send the MESH_PATH_CREATE_REQ message to UMAC FW */ -+ rwnx_send_msg(rwnx_hw, req, 0, 0, NULL); -+ } -+ } -+} -+ -+int rwnx_send_mesh_path_update_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, const u8 *tgt_addr, -+ const u8 *p_nhop_addr, struct mesh_path_update_cfm *cfm) -+{ -+ // Message to send -+ struct mesh_path_update_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MESH_PATH_UPDATE_REQ message */ -+ req = rwnx_msg_zalloc(MESH_PATH_UPDATE_REQ, TASK_MESH, DRV_TASK_ID, -+ sizeof(struct mesh_path_update_req)); -+ if (!req) { -+ return -ENOMEM; -+ } -+ -+ req->delete = (p_nhop_addr == NULL); -+ req->vif_idx = vif->vif_index; -+ memcpy(&req->tgt_mac_addr, tgt_addr, ETH_ALEN); -+ -+ if (p_nhop_addr) { -+ memcpy(&req->nhop_mac_addr, p_nhop_addr, ETH_ALEN); -+ } -+ -+ /* Send the MESH_PATH_UPDATE_REQ message to UMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, MESH_PATH_UPDATE_CFM, cfm); -+} -+ -+void rwnx_send_mesh_proxy_add_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, u8 *ext_addr) -+{ -+ // Message to send -+ struct mesh_proxy_add_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MESH_PROXY_ADD_REQ message */ -+ req = rwnx_msg_zalloc(MESH_PROXY_ADD_REQ, TASK_MESH, DRV_TASK_ID, -+ sizeof(struct mesh_proxy_add_req)); -+ -+ if (req) { -+ req->vif_idx = vif->vif_index; -+ memcpy(&req->ext_sta_addr, ext_addr, ETH_ALEN); -+ -+ /* Send the MESH_PROXY_ADD_REQ message to UMAC FW */ -+ rwnx_send_msg(rwnx_hw, req, 0, 0, NULL); -+ } -+} -+ -+int rwnx_send_tdls_peer_traffic_ind_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif) -+{ -+ struct tdls_peer_traffic_ind_req *tdls_peer_traffic_ind_req; -+ -+ if (!rwnx_vif->sta.tdls_sta) -+ return -ENOLINK; -+ -+ /* Build the TDLS_PEER_TRAFFIC_IND_REQ message */ -+ tdls_peer_traffic_ind_req = rwnx_msg_zalloc(TDLS_PEER_TRAFFIC_IND_REQ, TASK_TDLS, DRV_TASK_ID, -+ sizeof(struct tdls_peer_traffic_ind_req)); -+ -+ if (!tdls_peer_traffic_ind_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the TDLS_PEER_TRAFFIC_IND_REQ message */ -+ tdls_peer_traffic_ind_req->vif_index = rwnx_vif->vif_index; -+ tdls_peer_traffic_ind_req->sta_idx = rwnx_vif->sta.tdls_sta->sta_idx; -+ memcpy(&(tdls_peer_traffic_ind_req->peer_mac_addr.array[0]), -+ rwnx_vif->sta.tdls_sta->mac_addr, ETH_ALEN); -+ tdls_peer_traffic_ind_req->dialog_token = 0; // check dialog token value -+ tdls_peer_traffic_ind_req->last_tid = rwnx_vif->sta.tdls_sta->tdls.last_tid; -+ tdls_peer_traffic_ind_req->last_sn = rwnx_vif->sta.tdls_sta->tdls.last_sn; -+ -+ /* Send the TDLS_PEER_TRAFFIC_IND_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, tdls_peer_traffic_ind_req, 0, 0, NULL); -+} -+ -+int rwnx_send_config_monitor_req(struct rwnx_hw *rwnx_hw, -+ struct cfg80211_chan_def *chandef, -+ struct me_config_monitor_cfm *cfm) -+{ -+ struct me_config_monitor_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the ME_CONFIG_MONITOR_REQ message */ -+ req = rwnx_msg_zalloc(ME_CONFIG_MONITOR_REQ, TASK_ME, DRV_TASK_ID, -+ sizeof(struct me_config_monitor_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ if (chandef) { -+ req->chan_set = true; -+ -+ req->chan.band = chandef->chan->band; -+ req->chan.type = bw2chnl[chandef->width]; -+ req->chan.prim20_freq = chandef->chan->center_freq; -+ req->chan.center1_freq = chandef->center_freq1; -+ req->chan.center2_freq = chandef->center_freq2; -+ req->chan.tx_power = chan_to_fw_pwr(chandef->chan->max_power); -+ -+ if (rwnx_hw->phy.limit_bw) -+ limit_chan_bw(&req->chan.type, req->chan.prim20_freq, &req->chan.center1_freq); -+ } else { -+ req->chan_set = false; -+ } -+ -+ req->uf = rwnx_hw->mod_params->uf; -+ req->auto_reply = rwnx_hw->mod_params->auto_reply; -+ -+ /* Send the ME_CONFIG_MONITOR_REQ message to FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, ME_CONFIG_MONITOR_CFM, cfm); -+} -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+int rwnx_send_tdls_chan_switch_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct rwnx_sta *rwnx_sta, bool sta_initiator, -+ u8 oper_class, struct cfg80211_chan_def *chandef, -+ struct tdls_chan_switch_cfm *cfm) -+{ -+ struct tdls_chan_switch_req *tdls_chan_switch_req; -+ -+ -+ /* Build the TDLS_CHAN_SWITCH_REQ message */ -+ tdls_chan_switch_req = rwnx_msg_zalloc(TDLS_CHAN_SWITCH_REQ, TASK_TDLS, DRV_TASK_ID, -+ sizeof(struct tdls_chan_switch_req)); -+ -+ if (!tdls_chan_switch_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the TDLS_CHAN_SWITCH_REQ message */ -+ tdls_chan_switch_req->vif_index = rwnx_vif->vif_index; -+ tdls_chan_switch_req->sta_idx = rwnx_sta->sta_idx; -+ memcpy(&(tdls_chan_switch_req->peer_mac_addr.array[0]), -+ rwnx_sta_addr(rwnx_sta), ETH_ALEN); -+ tdls_chan_switch_req->initiator = sta_initiator; -+ tdls_chan_switch_req->band = chandef->chan->band; -+ tdls_chan_switch_req->type = bw2chnl[chandef->width]; -+ tdls_chan_switch_req->prim20_freq = chandef->chan->center_freq; -+ tdls_chan_switch_req->center1_freq = chandef->center_freq1; -+ tdls_chan_switch_req->center2_freq = chandef->center_freq2; -+ tdls_chan_switch_req->tx_power = chan_to_fw_pwr(chandef->chan->max_power); -+ tdls_chan_switch_req->op_class = oper_class; -+ -+ /* Send the TDLS_CHAN_SWITCH_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, tdls_chan_switch_req, 1, TDLS_CHAN_SWITCH_CFM, cfm); -+} -+ -+int rwnx_send_tdls_cancel_chan_switch_req(struct rwnx_hw *rwnx_hw, -+ struct rwnx_vif *rwnx_vif, -+ struct rwnx_sta *rwnx_sta, -+ struct tdls_cancel_chan_switch_cfm *cfm) -+{ -+ struct tdls_cancel_chan_switch_req *tdls_cancel_chan_switch_req; -+ -+ /* Build the TDLS_CHAN_SWITCH_REQ message */ -+ tdls_cancel_chan_switch_req = rwnx_msg_zalloc(TDLS_CANCEL_CHAN_SWITCH_REQ, TASK_TDLS, DRV_TASK_ID, -+ sizeof(struct tdls_cancel_chan_switch_req)); -+ if (!tdls_cancel_chan_switch_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the TDLS_CHAN_SWITCH_REQ message */ -+ tdls_cancel_chan_switch_req->vif_index = rwnx_vif->vif_index; -+ tdls_cancel_chan_switch_req->sta_idx = rwnx_sta->sta_idx; -+ memcpy(&(tdls_cancel_chan_switch_req->peer_mac_addr.array[0]), -+ rwnx_sta_addr(rwnx_sta), ETH_ALEN); -+ -+ /* Send the TDLS_CHAN_SWITCH_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, tdls_cancel_chan_switch_req, 1, TDLS_CANCEL_CHAN_SWITCH_CFM, cfm); -+} -+ -+#ifdef CONFIG_RWNX_BFMER -+#ifdef CONFIG_RWNX_FULLMAC -+void rwnx_send_bfmer_enable(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta, -+ const struct ieee80211_vht_cap *vht_cap) -+#endif /* CONFIG_RWNX_FULLMAC*/ -+{ -+ struct mm_bfmer_enable_req *bfmer_en_req; -+#ifdef CONFIG_RWNX_FULLMAC -+ __le32 vht_capability; -+ u8 rx_nss = 0; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ if (!vht_cap) { -+#endif /* CONFIG_RWNX_FULLMAC */ -+ goto end; -+ } -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ vht_capability = vht_cap->vht_cap_info; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ if (!(vht_capability & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) { -+ goto end; -+ } -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ rx_nss = rwnx_bfmer_get_rx_nss(vht_cap); -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ /* Allocate a structure that will contain the beamforming report */ -+ if (rwnx_bfmer_report_add(rwnx_hw, rwnx_sta, RWNX_BFMER_REPORT_SPACE_SIZE)) { -+ goto end; -+ } -+ -+ /* Build the MM_BFMER_ENABLE_REQ message */ -+ bfmer_en_req = rwnx_msg_zalloc(MM_BFMER_ENABLE_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_bfmer_enable_req)); -+ -+ /* Check message allocation */ -+ if (!bfmer_en_req) { -+ /* Free memory allocated for the report */ -+ rwnx_bfmer_report_del(rwnx_hw, rwnx_sta); -+ -+ /* Do not use beamforming */ -+ goto end; -+ } -+ -+ /* Provide DMA address to the MAC */ -+ bfmer_en_req->host_bfr_addr = rwnx_sta->bfm_report->dma_addr; -+ bfmer_en_req->host_bfr_size = RWNX_BFMER_REPORT_SPACE_SIZE; -+ bfmer_en_req->sta_idx = rwnx_sta->sta_idx; -+#ifdef CONFIG_RWNX_FULLMAC -+ bfmer_en_req->aid = rwnx_sta->aid; -+ bfmer_en_req->rx_nss = rx_nss; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ if (vht_capability & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) { -+ bfmer_en_req->vht_mu_bfmee = true; -+ } else { -+ bfmer_en_req->vht_mu_bfmee = false; -+ } -+ -+ /* Send the MM_BFMER_EN_REQ message to LMAC FW */ -+ rwnx_send_msg(rwnx_hw, bfmer_en_req, 0, 0, NULL); -+ -+end: -+ return; -+} -+ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+int rwnx_send_mu_group_update_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta) -+{ -+ struct mm_mu_group_update_req *req; -+ int group_id, i = 0; -+ u64 map; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_MU_GROUP_UPDATE_REQ message */ -+ req = rwnx_msg_zalloc(MM_MU_GROUP_UPDATE_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_mu_group_update_req) + -+ rwnx_sta->group_info.cnt * sizeof(req->groups[0])); -+ -+ /* Check message allocation */ -+ if (!req) -+ return -ENOMEM; -+ -+ /* Go through the groups the STA belongs to */ -+ group_sta_for_each(rwnx_sta, group_id, map) { -+ int user_pos = rwnx_mu_group_sta_get_pos(rwnx_hw, rwnx_sta, group_id); -+ -+ if (WARN((i >= rwnx_sta->group_info.cnt), -+ "STA%d: Too much group (%d)\n", -+ rwnx_sta->sta_idx, i + 1)) -+ break; -+ -+ req->groups[i].group_id = group_id; -+ req->groups[i].user_pos = user_pos; -+ -+ i++; -+ } -+ -+ req->group_cnt = rwnx_sta->group_info.cnt; -+ req->sta_idx = rwnx_sta->sta_idx; -+ -+ /* Send the MM_MU_GROUP_UPDATE_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, MM_MU_GROUP_UPDATE_CFM, NULL); -+} -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+#endif /* CONFIG_RWNX_BFMER */ -+ -+/********************************************************************** -+ * Debug Messages -+ *********************************************************************/ -+int rwnx_send_dbg_trigger_req(struct rwnx_hw *rwnx_hw, char *msg) -+{ -+ struct mm_dbg_trigger_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_DBG_TRIGGER_REQ message */ -+ req = rwnx_msg_zalloc(MM_DBG_TRIGGER_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_dbg_trigger_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Set parameters for the MM_DBG_TRIGGER_REQ message */ -+ strncpy(req->error, msg, sizeof(req->error)); -+ -+ /* Send the MM_DBG_TRIGGER_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 0, -1, NULL); -+} -+ -+int rwnx_send_dbg_mem_read_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, -+ struct dbg_mem_read_cfm *cfm) -+{ -+ struct dbg_mem_read_req *mem_read_req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the DBG_MEM_READ_REQ message */ -+ mem_read_req = rwnx_msg_zalloc(DBG_MEM_READ_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_mem_read_req)); -+ if (!mem_read_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_MEM_READ_REQ message */ -+ mem_read_req->memaddr = mem_addr; -+ -+ /* Send the DBG_MEM_READ_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, mem_read_req, 1, DBG_MEM_READ_CFM, cfm); -+} -+ -+int rwnx_send_dbg_mem_write_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, -+ u32 mem_data) -+{ -+ struct dbg_mem_write_req *mem_write_req; -+ -+ //RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the DBG_MEM_WRITE_REQ message */ -+ mem_write_req = rwnx_msg_zalloc(DBG_MEM_WRITE_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_mem_write_req)); -+ if (!mem_write_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_MEM_WRITE_REQ message */ -+ mem_write_req->memaddr = mem_addr; -+ mem_write_req->memdata = mem_data; -+ -+ /* Send the DBG_MEM_WRITE_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, mem_write_req, 1, DBG_MEM_WRITE_CFM, NULL); -+} -+ -+int rwnx_send_dbg_mem_mask_write_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, -+ u32 mem_mask, u32 mem_data) -+{ -+ struct dbg_mem_mask_write_req *mem_mask_write_req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the DBG_MEM_MASK_WRITE_REQ message */ -+ mem_mask_write_req = rwnx_msg_zalloc(DBG_MEM_MASK_WRITE_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_mem_mask_write_req)); -+ if (!mem_mask_write_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_MEM_MASK_WRITE_REQ message */ -+ mem_mask_write_req->memaddr = mem_addr; -+ mem_mask_write_req->memmask = mem_mask; -+ mem_mask_write_req->memdata = mem_data; -+ -+ /* Send the DBG_MEM_MASK_WRITE_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, mem_mask_write_req, 1, DBG_MEM_MASK_WRITE_CFM, NULL); -+} -+ -+#ifdef CONFIG_RFTEST -+int rwnx_send_rftest_req(struct rwnx_hw *rwnx_hw, u32_l cmd, u32_l argc, u8_l *argv, struct dbg_rftest_cmd_cfm *cfm) -+{ -+ struct dbg_rftest_cmd_req *mem_rftest_cmd_req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the DBG_RFTEST_CMD_REQ message */ -+ mem_rftest_cmd_req = rwnx_msg_zalloc(DBG_RFTEST_CMD_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_rftest_cmd_req)); -+ if (!mem_rftest_cmd_req) -+ return -ENOMEM; -+ -+ if (argc > 10) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_MEM_MASK_WRITE_REQ message */ -+ mem_rftest_cmd_req->cmd = cmd; -+ mem_rftest_cmd_req->argc = argc; -+ if (argc != 0) -+ memcpy(mem_rftest_cmd_req->argv, argv, argc); -+ -+ /* Send the DBG_RFTEST_CMD_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, mem_rftest_cmd_req, 1, DBG_RFTEST_CMD_CFM, cfm); -+} -+#endif -+ -+#ifdef CONFIG_MCU_MESSAGE -+int rwnx_send_dbg_custom_msg_req(struct rwnx_hw *rwnx_hw, -+ u32 cmd, void *buf, u32 len, u32 action, -+ struct dbg_custom_msg_cfm *cfm) -+{ -+ struct dbg_custom_msg_req *cust_msg_req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the DBG_CUSTOM_MSG_REQ message */ -+ cust_msg_req = -+ rwnx_msg_zalloc(DBG_CUSTOM_MSG_REQ, TASK_DBG, DRV_TASK_ID, -+ offsetof(struct dbg_custom_msg_req, buf) + len); -+ if (!cust_msg_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_CUSTOM_MSG_REQ message */ -+ cust_msg_req->cmd = cmd; -+ cust_msg_req->len = len; -+ cust_msg_req->flags = action; -+ if (buf) { -+ memcpy(cust_msg_req->buf, buf, len); -+ } -+ -+ /* Send the DBG_CUSTOM_MSG_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, cust_msg_req, 1, DBG_CUSTOM_MSG_CFM, cfm); -+} -+#endif -+ -+int rwnx_send_dbg_set_mod_filter_req(struct rwnx_hw *rwnx_hw, u32 filter) -+{ -+ struct dbg_set_mod_filter_req *set_mod_filter_req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the DBG_SET_MOD_FILTER_REQ message */ -+ set_mod_filter_req = -+ rwnx_msg_zalloc(DBG_SET_MOD_FILTER_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_set_mod_filter_req)); -+ if (!set_mod_filter_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_SET_MOD_FILTER_REQ message */ -+ set_mod_filter_req->mod_filter = filter; -+ -+ /* Send the DBG_SET_MOD_FILTER_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, set_mod_filter_req, 1, DBG_SET_MOD_FILTER_CFM, NULL); -+} -+ -+int rwnx_send_dbg_set_sev_filter_req(struct rwnx_hw *rwnx_hw, u32 filter) -+{ -+ struct dbg_set_sev_filter_req *set_sev_filter_req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the DBG_SET_SEV_FILTER_REQ message */ -+ set_sev_filter_req = -+ rwnx_msg_zalloc(DBG_SET_SEV_FILTER_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_set_sev_filter_req)); -+ if (!set_sev_filter_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_SET_SEV_FILTER_REQ message */ -+ set_sev_filter_req->sev_filter = filter; -+ -+ /* Send the DBG_SET_SEV_FILTER_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, set_sev_filter_req, 1, DBG_SET_SEV_FILTER_CFM, NULL); -+} -+ -+int rwnx_send_dbg_get_sys_stat_req(struct rwnx_hw *rwnx_hw, -+ struct dbg_get_sys_stat_cfm *cfm) -+{ -+ void *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Allocate the message */ -+ req = rwnx_msg_zalloc(DBG_GET_SYS_STAT_REQ, TASK_DBG, DRV_TASK_ID, 0); -+ if (!req) -+ return -ENOMEM; -+ -+ /* Send the DBG_MEM_READ_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, DBG_GET_SYS_STAT_CFM, cfm); -+} -+ -+int rwnx_send_dbg_mem_block_write_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, -+ u32 mem_size, u32 *mem_data) -+{ -+ struct dbg_mem_block_write_req *mem_blk_write_req; -+ -+ //RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the DBG_MEM_BLOCK_WRITE_REQ message */ -+ mem_blk_write_req = rwnx_msg_zalloc(DBG_MEM_BLOCK_WRITE_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_mem_block_write_req)); -+ if (!mem_blk_write_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_MEM_BLOCK_WRITE_REQ message */ -+ mem_blk_write_req->memaddr = mem_addr; -+ mem_blk_write_req->memsize = mem_size; -+ memcpy(mem_blk_write_req->memdata, mem_data, mem_size); -+ -+ /* Send the DBG_MEM_BLOCK_WRITE_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, mem_blk_write_req, 1, DBG_MEM_BLOCK_WRITE_CFM, NULL); -+} -+ -+int rwnx_send_dbg_start_app_req(struct rwnx_hw *rwnx_hw, u32 boot_addr, -+ u32 boot_type) -+{ -+ struct dbg_start_app_req *start_app_req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the DBG_START_APP_REQ message */ -+ start_app_req = rwnx_msg_zalloc(DBG_START_APP_REQ, TASK_DBG, DRV_TASK_ID, -+ sizeof(struct dbg_start_app_req)); -+ if (!start_app_req) -+ return -ENOMEM; -+ -+ /* Set parameters for the DBG_START_APP_REQ message */ -+ start_app_req->bootaddr = boot_addr; -+ start_app_req->boottype = boot_type; -+ -+ /* Send the DBG_START_APP_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, start_app_req, 1, DBG_START_APP_CFM, NULL); -+} -+ -+int rwnx_send_cfg_rssi_req(struct rwnx_hw *rwnx_hw, u8 vif_index, int rssi_thold, u32 rssi_hyst) -+{ -+ struct mm_cfg_rssi_req *req; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ /* Build the MM_CFG_RSSI_REQ message */ -+ req = rwnx_msg_zalloc(MM_CFG_RSSI_REQ, TASK_MM, DRV_TASK_ID, -+ sizeof(struct mm_cfg_rssi_req)); -+ if (!req) -+ return -ENOMEM; -+ -+ if (rwnx_hw->vif_table[vif_index] == NULL) -+ return 0; -+ -+ /* Set parameters for the MM_CFG_RSSI_REQ message */ -+ req->vif_index = vif_index; -+ req->rssi_thold = (s8)rssi_thold; -+ req->rssi_hyst = (u8)rssi_hyst; -+ -+ /* Send the MM_CFG_RSSI_REQ message to LMAC FW */ -+ return rwnx_send_msg(rwnx_hw, req, 1, MM_CFG_RSSI_CFM, NULL); -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_tx.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_tx.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_tx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_msg_tx.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,186 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_msg_tx.h -+ * -+ * @brief TX function declarations -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _RWNX_MSG_TX_H_ -+#define _RWNX_MSG_TX_H_ -+ -+#include "rwnx_defs.h" -+ -+int rwnx_send_reset(struct rwnx_hw *rwnx_hw); -+int rwnx_send_start(struct rwnx_hw *rwnx_hw); -+int rwnx_send_version_req(struct rwnx_hw *rwnx_hw, struct mm_version_cfm *cfm); -+int rwnx_send_add_if (struct rwnx_hw *rwnx_hw, const unsigned char *mac, -+ enum nl80211_iftype iftype, bool p2p, struct mm_add_if_cfm *cfm); -+int rwnx_send_remove_if (struct rwnx_hw *rwnx_hw, u8 vif_index, bool defer); -+int rwnx_send_set_channel(struct rwnx_hw *rwnx_hw, int phy_idx, -+ struct mm_set_channel_cfm *cfm); -+int rwnx_send_key_add(struct rwnx_hw *rwnx_hw, u8 vif_idx, u8 sta_idx, bool pairwise, -+ u8 *key, u8 key_len, u8 key_idx, u8 cipher_suite, -+ struct mm_key_add_cfm *cfm); -+int rwnx_send_key_del(struct rwnx_hw *rwnx_hw, uint8_t hw_key_idx); -+int rwnx_send_bcn(struct rwnx_hw *rwnx_hw, u8 *buf, u8 vif_idx, u16 bcn_len); -+ -+int rwnx_send_bcn_change(struct rwnx_hw *rwnx_hw, u8 vif_idx, u32 bcn_addr, -+ u16 bcn_len, u16 tim_oft, u16 tim_len, u16 *csa_oft); -+int rwnx_send_tim_update(struct rwnx_hw *rwnx_hw, u8 vif_idx, u16 aid, -+ u8 tx_status); -+int rwnx_send_roc(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ struct ieee80211_channel *chan, unsigned int duration, struct mm_remain_on_channel_cfm *roc_cfm); -+int rwnx_send_cancel_roc(struct rwnx_hw *rwnx_hw); -+int rwnx_send_set_power(struct rwnx_hw *rwnx_hw, u8 vif_idx, s8 pwr, -+ struct mm_set_power_cfm *cfm); -+int rwnx_send_set_edca(struct rwnx_hw *rwnx_hw, u8 hw_queue, u32 param, -+ bool uapsd, u8 inst_nbr); -+int rwnx_send_tdls_chan_switch_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct rwnx_sta *rwnx_sta, bool sta_initiator, -+ u8 oper_class, struct cfg80211_chan_def *chandef, -+ struct tdls_chan_switch_cfm *cfm); -+int rwnx_send_tdls_cancel_chan_switch_req(struct rwnx_hw *rwnx_hw, -+ struct rwnx_vif *rwnx_vif, -+ struct rwnx_sta *rwnx_sta, -+ struct tdls_cancel_chan_switch_cfm *cfm); -+ -+#ifdef CONFIG_RWNX_P2P_DEBUGFS -+int rwnx_send_p2p_oppps_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ u8 ctw, struct mm_set_p2p_oppps_cfm *cfm); -+int rwnx_send_p2p_noa_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ int count, int interval, int duration, -+ bool dyn_noa, struct mm_set_p2p_noa_cfm *cfm); -+#endif /* CONFIG_RWNX_P2P_DEBUGFS */ -+ -+#ifdef AICWF_ARP_OFFLOAD -+int rwnx_send_arpoffload_en_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ u32_l ipaddr, u8_l enable); -+#endif -+int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l *tbl, u16_l len); -+int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm); -+int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cfm *cfm); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+int rwnx_send_me_config_req(struct rwnx_hw *rwnx_hw); -+int rwnx_send_me_chan_config_req(struct rwnx_hw *rwnx_hw); -+int rwnx_send_me_set_control_port_req(struct rwnx_hw *rwnx_hw, bool opened, -+ u8 sta_idx); -+int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *params, -+ const u8 *mac, u8 inst_nbr, struct me_sta_add_cfm *cfm); -+int rwnx_send_me_sta_del(struct rwnx_hw *rwnx_hw, u8 sta_idx, bool tdls_sta); -+int rwnx_send_me_traffic_ind(struct rwnx_hw *rwnx_hw, u8 sta_idx, bool uapsd, u8 tx_status); -+int rwnx_send_me_rc_stats(struct rwnx_hw *rwnx_hw, u8 sta_idx, -+ struct me_rc_stats_cfm *cfm); -+int rwnx_send_me_rc_set_rate(struct rwnx_hw *rwnx_hw, -+ u8 sta_idx, -+ u16 rate_idx); -+int rwnx_send_me_set_ps_mode(struct rwnx_hw *rwnx_hw, u8 ps_mode); -+int rwnx_send_me_set_lp_level(struct rwnx_hw *rwnx_hw, u8 lp_level); -+int rwnx_send_sm_connect_req(struct rwnx_hw *rwnx_hw, -+ struct rwnx_vif *rwnx_vif, -+ struct cfg80211_connect_params *sme, -+ struct sm_connect_cfm *cfm); -+int rwnx_send_sm_disconnect_req(struct rwnx_hw *rwnx_hw, -+ struct rwnx_vif *rwnx_vif, -+ u16 reason); -+int rwnx_send_sm_external_auth_required_rsp(struct rwnx_hw *rwnx_hw, -+ struct rwnx_vif *rwnx_vif, -+ u16 status); -+int rwnx_send_apm_start_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ struct cfg80211_ap_settings *settings, -+ struct apm_start_cfm *cfm, -+ struct rwnx_ipc_elem_var *elem); -+int rwnx_send_apm_stop_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif); -+int rwnx_send_scanu_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct cfg80211_scan_request *param); -+int rwnx_send_scanu_cancel_req(struct rwnx_hw *rwnx_hw, -+ struct scan_cancel_cfm *cfm); -+ -+int rwnx_send_apm_start_cac_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ struct cfg80211_chan_def *chandef, -+ struct apm_start_cac_cfm *cfm); -+int rwnx_send_apm_stop_cac_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif); -+int rwnx_send_tdls_peer_traffic_ind_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif); -+int rwnx_send_config_monitor_req(struct rwnx_hw *rwnx_hw, -+ struct cfg80211_chan_def *chandef, -+ struct me_config_monitor_cfm *cfm); -+int rwnx_send_mesh_start_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ const struct mesh_config *conf, const struct mesh_setup *setup, -+ struct mesh_start_cfm *cfm); -+int rwnx_send_mesh_stop_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ struct mesh_stop_cfm *cfm); -+int rwnx_send_mesh_update_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ u32 mask, const struct mesh_config *p_mconf, struct mesh_update_cfm *cfm); -+int rwnx_send_mesh_peer_info_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ u8 sta_idx, struct mesh_peer_info_cfm *cfm); -+void rwnx_send_mesh_peer_update_ntf(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ u8 sta_idx, u8 mlink_state); -+void rwnx_send_mesh_path_create_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, u8 *tgt_addr); -+int rwnx_send_mesh_path_update_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, const u8 *tgt_addr, -+ const u8 *p_nhop_addr, struct mesh_path_update_cfm *cfm); -+void rwnx_send_mesh_proxy_add_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, u8 *ext_addr); -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+#ifdef CONFIG_RWNX_BFMER -+#ifdef CONFIG_RWNX_FULLMAC -+void rwnx_send_bfmer_enable(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta, -+ const struct ieee80211_vht_cap *vht_cap); -+#endif /* CONFIG_RWNX_FULLMAC */ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+int rwnx_send_mu_group_update_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta); -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+#endif /* CONFIG_RWNX_BFMER */ -+ -+/* Debug messages */ -+int rwnx_send_dbg_trigger_req(struct rwnx_hw *rwnx_hw, char *msg); -+int rwnx_send_dbg_mem_read_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, -+ struct dbg_mem_read_cfm *cfm); -+int rwnx_send_dbg_mem_write_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, -+ u32 mem_data); -+int rwnx_send_dbg_mem_mask_write_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, -+ u32 mem_mask, u32 mem_data); -+int rwnx_send_dbg_set_mod_filter_req(struct rwnx_hw *rwnx_hw, u32 filter); -+#ifdef CONFIG_RFTEST -+int rwnx_send_rftest_req(struct rwnx_hw *rwnx_hw, u32_l cmd, u32_l argc, u8_l *argv, struct dbg_rftest_cmd_cfm *cfm); -+#endif -+#ifdef CONFIG_MCU_MESSAGE -+int rwnx_send_dbg_custom_msg_req(struct rwnx_hw *rwnx_hw, -+ u32 cmd, void *buf, u32 len, u32 action, -+ struct dbg_custom_msg_cfm *cfm); -+#endif -+int rwnx_send_dbg_set_sev_filter_req(struct rwnx_hw *rwnx_hw, u32 filter); -+int rwnx_send_dbg_get_sys_stat_req(struct rwnx_hw *rwnx_hw, -+ struct dbg_get_sys_stat_cfm *cfm); -+int rwnx_send_dbg_mem_block_write_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, -+ u32 mem_size, u32 *mem_data); -+int rwnx_send_dbg_start_app_req(struct rwnx_hw *rwnx_hw, u32 boot_addr, -+ u32 boot_type); -+int rwnx_send_cfg_rssi_req(struct rwnx_hw *rwnx_hw, u8 vif_index, int rssi_thold, u32 rssi_hyst); -+int rwnx_send_disable_agg_req(struct rwnx_hw *rwnx_hw, u8_l agg_disable, u8_l agg_disable_rx, u8_l sta_idx); -+int rwnx_send_coex_req(struct rwnx_hw *rwnx_hw, u8_l disable_coexnull, u8_l enable_nullcts); -+int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_get_sta_info_cfm *cfm); -+int rwnx_send_set_stack_start_req(struct rwnx_hw *rwnx_hw, u8_l on, u8_l efuse_valid, u8_l set_vendor_info, -+ u8_l fwtrace_redir_en, struct mm_set_stack_start_cfm *cfm); -+int rwnx_send_txop_req(struct rwnx_hw *rwnx_hw, uint16_t *txop, u8_l long_nav_en, u8_l cfe_en); -+int rwnx_send_set_temp_comp_req(struct rwnx_hw *rwnx_hw, struct mm_set_vendor_swconfig_cfm *cfm); -+int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param, int32_t *param_out); -+int rwnx_send_vendor_swconfig_req(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, int32_t *param_in, int32_t *param_out); -+int rwnx_send_mask_set_ext_flags_req(struct rwnx_hw *rwnx_hw, uint32_t flags_mask, uint32_t flags_val, struct mm_set_vendor_swconfig_cfm *cfm); -+int rwnx_send_get_fw_version_req(struct rwnx_hw *rwnx_hw, struct mm_get_fw_version_cfm *cfm); -+int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw); -+int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw); -+int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw); -+int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw); -+int rwnx_send_txpwr_lvl_v3_req(struct rwnx_hw *rwnx_hw); -+int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw); -+ -+#ifdef CONFIG_SDIO_BT -+int rwnx_sdio_bt_send_req(struct rwnx_hw *rwnx_hw,uint32_t len, struct sk_buff *skb); -+#endif -+ -+#endif /* _RWNX_MSG_TX_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mu_group.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mu_group.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mu_group.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mu_group.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,659 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_mu_group.c -+ * -+ * Copyright (C) RivieraWaves 2016-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#include "rwnx_defs.h" -+#include "rwnx_msg_tx.h" -+#include "rwnx_events.h" -+ -+ -+/** -+ * rwnx_mu_group_sta_init - Initialize group information for a STA -+ * -+ * @sta: Sta to initialize -+ */ -+void rwnx_mu_group_sta_init(struct rwnx_sta *sta, -+ const struct ieee80211_vht_cap *vht_cap) -+{ -+ sta->group_info.map = 0; -+ sta->group_info.cnt = 0; -+ sta->group_info.active.next = LIST_POISON1; -+ sta->group_info.update.next = LIST_POISON1; -+ sta->group_info.last_update = 0; -+ sta->group_info.traffic = 0; -+ sta->group_info.group = 0; -+ -+ if (!vht_cap || -+ !(vht_cap->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) { -+ sta->group_info.map = RWNX_SU_GROUP; -+ } -+} -+ -+/** -+ * rwnx_mu_group_sta_del - Remove a sta from all MU group -+ * -+ * @rwnx_hw: main driver data -+ * @sta: STA to remove -+ * -+ * Remove one sta from all the MU groups it belongs to. -+ */ -+void rwnx_mu_group_sta_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) -+{ -+ struct rwnx_mu_info *mu = &rwnx_hw->mu; -+ int i, j, group_id; -+ bool lock_taken; -+ u64 map; -+ -+ lock_taken = (down_interruptible(&mu->lock) == 0); -+ -+ group_sta_for_each(sta, group_id, map) { -+ struct rwnx_mu_group *group = rwnx_mu_group_from_id(mu, group_id); -+ -+ for (i = 0; i < CONFIG_USER_MAX; i++) { -+ if (group->users[i] == sta) { -+ group->users[i] = NULL; -+ group->user_cnt--; -+ /* Don't keep group with only one user */ -+ if (group->user_cnt == 1) { -+ for (j = 0; j < CONFIG_USER_MAX; j++) { -+ if (group->users[j]) { -+ group->users[j]->group_info.cnt--; -+ group->users[j]->group_info.map &= ~BIT_ULL(group->group_id); -+ if (group->users[j]->group_info.group == group_id) -+ group->users[j]->group_info.group = 0; -+ group->user_cnt--; -+ break; -+ } -+ } -+ mu->group_cnt--; -+ trace_mu_group_delete(group->group_id); -+ } else { -+ trace_mu_group_update(group); -+ } -+ break; -+ } -+ } -+ -+ WARN((i == CONFIG_USER_MAX), "sta %d doesn't belongs to group %d", -+ sta->sta_idx, group_id); -+ } -+ -+ sta->group_info.map = 0; -+ sta->group_info.cnt = 0; -+ sta->group_info.traffic = 0; -+ -+ if (sta->group_info.active.next != LIST_POISON1) -+ list_del(&sta->group_info.active); -+ -+ if (sta->group_info.update.next != LIST_POISON1) -+ list_del(&sta->group_info.update); -+ -+ if (lock_taken) -+ up(&mu->lock); -+} -+ -+/** -+ * rwnx_mu_group_sta_get_map - Get the list of group a STA belongs to -+ * -+ * @sta: pointer to the sta -+ * -+ * @return the list of group a STA belongs to as a bitfield -+ */ -+u64 rwnx_mu_group_sta_get_map(struct rwnx_sta *sta) -+{ -+ if (sta) -+ return sta->group_info.map; -+ return 0; -+} -+ -+/** -+ * rwnx_mu_group_sta_get_pos - Get sta position in a group -+ * -+ * @rwnx_hw: main driver data -+ * @sta: pointer to the sta -+ * @group_id: Group id -+ * -+ * @return the positon of @sta in group @group_id or -1 if the sta -+ * doesn't belongs to the group (or group id is invalid) -+ */ -+int rwnx_mu_group_sta_get_pos(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, -+ int group_id) -+{ -+ struct rwnx_mu_group *group; -+ int i; -+ -+ group = rwnx_mu_group_from_id(&rwnx_hw->mu, group_id); -+ if (!group) -+ return -1; -+ -+ for (i = 0; i < CONFIG_USER_MAX; i++) { -+ if (group->users[i] == sta) -+ return i; -+ } -+ -+ WARN(1, "sta %d doesn't belongs to group %d", -+ sta->sta_idx, group_id); -+ return -1; -+} -+ -+/** -+ * rwnx_mu_group_move_head - Move (or add) one element at the top of a list -+ * -+ * @list: list pointer -+ * @elem: element to move (or add) at the top of @list -+ * -+ */ -+static inline -+void rwnx_mu_group_move_head(struct list_head *list, struct list_head *elem) -+{ -+ if (elem->next != LIST_POISON1) { -+ __list_del_entry(elem); -+ } -+ list_add(elem, list); -+} -+ -+/** -+ * rwnx_mu_group_remove_users - Remove all the users of a group -+ * -+ * @mu: pointer on MU info -+ * @group: pointer on group to remove users from -+ * -+ * Loop over all users one one group and remove this group from their -+ * map (and count). -+ * Each users is also added to the update_sta list, so that group info -+ * will be resent to fw for this user. -+ */ -+static inline -+void rwnx_mu_group_remove_users(struct rwnx_mu_info *mu, -+ struct rwnx_mu_group *group) -+{ -+ struct rwnx_sta *sta; -+ int i, group_id = group->group_id; -+ -+ for (i = 0; i < CONFIG_USER_MAX; i++) { -+ if (group->users[i]) { -+ sta = group->users[i]; -+ group->users[i] = NULL; -+ sta->group_info.cnt--; -+ sta->group_info.map &= ~BIT_ULL(group_id); -+ rwnx_mu_group_move_head(&mu->update_sta, -+ &sta->group_info.update); -+ } -+ } -+ -+ if (group->user_cnt) -+ mu->group_cnt--; -+ group->user_cnt = 0; -+ trace_mu_group_delete(group_id); -+} -+ -+/** -+ * rwnx_mu_group_add_users - Add users to a group -+ * -+ * @mu: pointer on MU info -+ * @group: pointer on group to add users in -+ * @nb_user: number of users to ad -+ * @users: table of user to add -+ * -+ * Add @nb_users to @group (which may already have users) -+ * Each new users is added to the first free position. -+ * It is assume that @group has at least @nb_user free position. If it is not -+ * case it only add the number of users needed to complete the group. -+ * Each users (effectively added to @group) is also added to the update_sta -+ * list, so that group info will be resent to fw for this user. -+ */ -+static inline -+void rwnx_mu_group_add_users(struct rwnx_mu_info *mu, -+ struct rwnx_mu_group *group, -+ int nb_user, struct rwnx_sta **users) -+{ -+ int i, j, group_id = group->group_id; -+ -+ if (!group->user_cnt) -+ mu->group_cnt++; -+ -+ j = 0; -+ for (i = 0; i < nb_user ; i++) { -+ for (; j < CONFIG_USER_MAX ; j++) { -+ if (group->users[j] == NULL) { -+ group->users[j] = users[i]; -+ users[i]->group_info.cnt++; -+ users[i]->group_info.map |= BIT_ULL(group_id); -+ -+ rwnx_mu_group_move_head(&(mu->update_sta), -+ &(users[i]->group_info.update)); -+ group->user_cnt++; -+ j++; -+ break; -+ } -+ -+ WARN(j == (CONFIG_USER_MAX - 1), -+ "Too many user for group %d (nb_user=%d)", -+ group_id, group->user_cnt + nb_user - i); -+ } -+ } -+ -+ trace_mu_group_update(group); -+} -+ -+ -+/** -+ * rwnx_mu_group_create_one - create on group with a specific group of user -+ * -+ * @mu: pointer on MU info -+ * @nb_user: number of user to include in the group (<= CONFIG_USER_MAX) -+ * @users: table of users -+ * -+ * Try to create a new group with a specific group of users. -+ * 1- First it checks if a group containing all this users already exists. -+ * -+ * 2- Then it checks if it is possible to complete a group which already -+ * contains at least one user. -+ * -+ * 3- Finally it create a new group. To do so, it take take the last group of -+ * the active_groups list, remove all its current users and add the new ones -+ * -+ * In all cases, the group selected is moved at the top of the active_groups -+ * list -+ * -+ * @return 1 if a new group has been created and 0 otherwise -+ */ -+static -+int rwnx_mu_group_create_one(struct rwnx_mu_info *mu, int nb_user, -+ struct rwnx_sta **users, int *nb_group_left) -+{ -+ int i, group_id; -+ struct rwnx_mu_group *group; -+ u64 group_match; -+ u64 group_avail; -+ -+ group_match = users[0]->group_info.map; -+ group_avail = users[0]->group_info.map; -+ for (i = 1; i < nb_user ; i++) { -+ group_match &= users[i]->group_info.map; -+ group_avail |= users[i]->group_info.map; -+ -+ } -+ -+ if (group_match) { -+ /* a group (or more) with all the users already exist */ -+ group_id = RWNX_GET_FIRST_GROUP_ID(group_match); -+ group = rwnx_mu_group_from_id(mu, group_id); -+ rwnx_mu_group_move_head(&mu->active_groups, &group->list); -+ return 0; -+ } -+ -+#if CONFIG_USER_MAX > 2 -+ if (group_avail) { -+ /* check if we can complete a group */ -+ struct rwnx_sta *users2[CONFIG_USER_MAX]; -+ int nb_user2; -+ -+ group_for_each(group_id, group_avail) { -+ group = rwnx_mu_group_from_id(mu, group_id); -+ if (group->user_cnt == CONFIG_USER_MAX) -+ continue; -+ -+ nb_user2 = 0; -+ for (i = 0; i < nb_user ; i++) { -+ if (!(users[i]->group_info.map & BIT_ULL(group_id))) { -+ users2[nb_user2] = users[i]; -+ nb_user2++; -+ } -+ } -+ -+ if ((group->user_cnt + nb_user2) <= CONFIG_USER_MAX) { -+ rwnx_mu_group_add_users(mu, group, nb_user2, users2); -+ rwnx_mu_group_move_head(&mu->active_groups, &group->list); -+ return 0; -+ } -+ } -+ } -+#endif /* CONFIG_USER_MAX > 2*/ -+ -+ /* create a new group */ -+ group = list_last_entry(&mu->active_groups, struct rwnx_mu_group, list); -+ rwnx_mu_group_remove_users(mu, group); -+ rwnx_mu_group_add_users(mu, group, nb_user, users); -+ rwnx_mu_group_move_head(&mu->active_groups, &group->list); -+ (*nb_group_left)--; -+ -+ return 1; -+} -+ -+/** -+ * rwnx_mu_group_create - Create new groups containing one specific sta -+ * -+ * @mu: pointer on MU info -+ * @sta: sta to add in each group -+ * @nb_group_left: maximum number to new group allowed. (updated on exit) -+ * -+ * This will try to create "all the possible" group with a specific sta being -+ * a member of all these group. -+ * The function simply loops over the @active_sta list (starting from @sta). -+ * When it has (CONFIG_USER_MAX - 1) users it try to create a new group with -+ * these users (plus @sta). -+ * Loops end when there is no more users, or no more new group is allowed -+ * -+ */ -+static -+void rwnx_mu_group_create(struct rwnx_mu_info *mu, struct rwnx_sta *sta, -+ int *nb_group_left) -+{ -+ struct rwnx_sta *user_sta = sta; -+ struct rwnx_sta *users[CONFIG_USER_MAX]; -+ int nb_user = 1; -+ -+ users[0] = sta; -+ while (*nb_group_left) { -+ -+ list_for_each_entry_continue(user_sta, &mu->active_sta, group_info.active) { -+ users[nb_user] = user_sta; -+ if (++nb_user == CONFIG_USER_MAX) { -+ break; -+ } -+ } -+ -+ if (nb_user > 1) { -+ if (rwnx_mu_group_create_one(mu, nb_user, users, nb_group_left)) -+ (*nb_group_left)--; -+ -+ if (nb_user < CONFIG_USER_MAX) -+ break; -+ else -+ nb_user = 1; -+ } else -+ break; -+ } -+} -+ -+/** -+ * rwnx_mu_group_work - process function of the "group_work" -+ * -+ * The work is scheduled when several sta (MU beamformee capable) are active. -+ * When called, the @active_sta contains the list of the active sta (starting -+ * from the most recent one), and @active_groups is the list of all possible -+ * groups ordered so that the first one is the most recently used. -+ * -+ * This function will create new groups, starting from group containing the -+ * most "active" sta. -+ * For example if the list of sta is : -+ * sta8 -> sta3 -> sta4 -> sta7 -> sta1 -+ * and the number of user per group is 3, it will create grooups : -+ * - sta8 / sta3 / sta4 -+ * - sta8 / sta7 / sta1 -+ * - sta3 / sta4 / sta7 -+ * - sta3 / sta1 -+ * - sta4 / sta7 / sta1 -+ * - sta7 / sta1 -+ * -+ * To create new group, the least used group are first selected. -+ * It is only allowed to create NX_MU_GROUP_MAX per iteration. -+ * -+ * Once groups have been updated, mu group information is update to the fw. -+ * To do so it use the @update_sta list to know which sta has been affected. -+ * As it is necessary to wait for fw confirmation before using this new group -+ * MU is temporarily disabled during group update -+ * -+ * Work is then rescheduled. -+ * -+ * At the end of the function, both @active_sta and @update_sta list are empty. -+ * -+ * Note: -+ * - This is still a WIP, and will require more tuning -+ * - not all combinations are created, to avoid to much processing. -+ * - reschedule delay should be adaptative -+ */ -+void rwnx_mu_group_work(struct work_struct *ws) -+{ -+ struct delayed_work *dw = container_of(ws, struct delayed_work, work); -+ struct rwnx_mu_info *mu = container_of(dw, struct rwnx_mu_info, group_work); -+ struct rwnx_hw *rwnx_hw = container_of(mu, struct rwnx_hw, mu); -+ struct rwnx_sta *sta, *next; -+ int nb_group_left = NX_MU_GROUP_MAX; -+ -+ if (WARN(!rwnx_hw->mod_params->mutx, -+ "In group formation work, but mutx disabled")) -+ return; -+ -+ if (down_interruptible(&mu->lock) != 0) -+ return; -+ -+ mu->update_count++; -+ if (!mu->update_count) -+ mu->update_count++; -+ -+ list_for_each_entry_safe(sta, next, &mu->active_sta, group_info.active) { -+ if (nb_group_left) -+ rwnx_mu_group_create(mu, sta, &nb_group_left); -+ -+ sta->group_info.last_update = mu->update_count; -+ list_del(&sta->group_info.active); -+ } -+ -+ if (!list_empty(&mu->update_sta)) { -+ list_for_each_entry_safe(sta, next, &mu->update_sta, group_info.update) { -+ rwnx_send_mu_group_update_req(rwnx_hw, sta); -+ list_del(&sta->group_info.update); -+ } -+ } -+ -+ mu->next_group_select = jiffies; -+ rwnx_mu_group_sta_select(rwnx_hw); -+ up(&mu->lock); -+ -+ return; -+} -+ -+/** -+ * rwnx_mu_group_init - Initialize MU groups -+ * -+ * @rwnx_hw: main driver data -+ * -+ * Initialize all MU group -+ */ -+void rwnx_mu_group_init(struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_mu_info *mu = &rwnx_hw->mu; -+ int i; -+ -+ INIT_LIST_HEAD(&mu->active_groups); -+ INIT_LIST_HEAD(&mu->active_sta); -+ INIT_LIST_HEAD(&mu->update_sta); -+ -+ for (i = 0; i < NX_MU_GROUP_MAX; i++) { -+ int j; -+ mu->groups[i].user_cnt = 0; -+ mu->groups[i].group_id = i + 1; -+ for (j = 0; j < CONFIG_USER_MAX; j++) { -+ mu->groups[i].users[j] = NULL; -+ } -+ list_add(&mu->groups[i].list, &mu->active_groups); -+ } -+ -+ mu->update_count = 1; -+ mu->group_cnt = 0; -+ mu->next_group_select = jiffies; -+ INIT_DELAYED_WORK(&mu->group_work, rwnx_mu_group_work); -+ sema_init(&mu->lock, 1); -+} -+ -+/** -+ * rwnx_mu_set_active_sta - mark a STA as active -+ * -+ * @rwnx_hw: main driver data -+ * @sta: pointer to the sta -+ * @traffic: Number of buffers to add in the sta's traffic counter -+ * -+ * If @sta is MU beamformee capable (and MU-MIMO tx is enabled) move the -+ * sta at the top of the @active_sta list. -+ * It also schedule the group_work if not already scheduled and the list -+ * contains more than one sta. -+ * -+ * If a STA was already in the list during the last group update -+ * (i.e. sta->group_info.last_update == mu->update_count) it is not added -+ * back to the list until a sta that wasn't active during the last update is -+ * added. This is to avoid scheduling group update with a list of sta that -+ * were all already in the list during previous update. -+ * -+ * It is called with mu->lock taken. -+ */ -+void rwnx_mu_set_active_sta(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, -+ int traffic) -+{ -+ struct rwnx_mu_info *mu = &rwnx_hw->mu; -+ -+ if (!sta || (sta->group_info.map & RWNX_SU_GROUP)) -+ return; -+ -+ sta->group_info.traffic += traffic; -+ -+ if ((sta->group_info.last_update != mu->update_count) || -+ !list_empty(&mu->active_sta)) { -+ -+ rwnx_mu_group_move_head(&mu->active_sta, &sta->group_info.active); -+ -+ if (!delayed_work_pending(&mu->group_work) && -+ !list_is_singular(&mu->active_sta)) { -+ schedule_delayed_work(&mu->group_work, -+ msecs_to_jiffies(RWNX_MU_GROUP_INTERVAL)); -+ } -+ } -+} -+ -+/** -+ * rwnx_mu_set_active_group - mark a MU group as active -+ * -+ * @rwnx_hw: main driver data -+ * @group_id: Group id -+ * -+ * move a group at the top of the @active_groups list -+ */ -+void rwnx_mu_set_active_group(struct rwnx_hw *rwnx_hw, int group_id) -+{ -+ struct rwnx_mu_info *mu = &rwnx_hw->mu; -+ struct rwnx_mu_group *group = rwnx_mu_group_from_id(mu, group_id); -+ -+ rwnx_mu_group_move_head(&mu->active_groups, &group->list); -+} -+ -+ -+/** -+ * rwnx_mu_group_sta_select - Select the best group for MU stas -+ * -+ * @rwnx_hw: main driver data -+ * -+ * For each MU capable client of AP interfaces this function tries to select -+ * the best group to use. -+ * -+ * In first pass, gather information from all stations to form statistics -+ * for each group for the previous @RWNX_MU_GROUP_SELECT_INTERVAL interval: -+ * - number of buffers transmitted -+ * - number of user -+ * -+ * Then groups with more than 2 active users, are assigned after being ordered -+ * by traffic : -+ * - group with highest traffic is selected: set this group for all its users -+ * - update nb_users for all others group (as one sta may be in several groups) -+ * - select the next group that have still mor than 2 users and assign it. -+ * - continue until all group are processed -+ * -+ */ -+void rwnx_mu_group_sta_select(struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_mu_info *mu = &rwnx_hw->mu; -+ int nb_users[NX_MU_GROUP_MAX + 1]; -+ int traffic[NX_MU_GROUP_MAX + 1]; -+ int order[NX_MU_GROUP_MAX + 1]; -+ struct rwnx_sta *sta; -+ struct rwnx_vif *vif; -+ struct list_head *head; -+ u64 map; -+ int i, j, update, group_id, tmp, cnt = 0; -+ -+ if (!mu->group_cnt || time_before(jiffies, mu->next_group_select)) -+ return; -+ -+ list_for_each_entry(vif, &rwnx_hw->vifs, list) { -+ -+ if (RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_AP) -+ continue; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ head = &vif->ap.sta_list; -+#else -+ head = &vif->stations; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ memset(nb_users, 0, sizeof(nb_users)); -+ memset(traffic, 0, sizeof(traffic)); -+ list_for_each_entry(sta, head, list) { -+ int sta_traffic = sta->group_info.traffic; -+ -+ /* reset statistics for next selection */ -+ sta->group_info.traffic = 0; -+ if (sta->group_info.group) -+ trace_mu_group_selection(sta, 0); -+ sta->group_info.group = 0; -+ -+ if (sta->group_info.cnt == 0 || -+ sta_traffic < RWNX_MU_GROUP_MIN_TRAFFIC) -+ continue; -+ -+ group_sta_for_each(sta, group_id, map) { -+ nb_users[group_id]++; -+ traffic[group_id] += sta_traffic; -+ -+ /* list group with 2 users or more */ -+ if (nb_users[group_id] == 2) -+ order[cnt++] = group_id; -+ } -+ } -+ -+ /* reorder list of group with more that 2 users */ -+ update = 1; -+ while (update) { -+ update = 0; -+ for (i = 0; i < cnt - 1; i++) { -+ if (traffic[order[i]] < traffic[order[i + 1]]) { -+ tmp = order[i]; -+ order[i] = order[i + 1]; -+ order[i + 1] = tmp; -+ update = 1; -+ } -+ } -+ } -+ -+ /* now assign group in traffic order */ -+ for (i = 0; i < cnt; i++) { -+ struct rwnx_mu_group *group; -+ group_id = order[i]; -+ -+ if (nb_users[group_id] < 2) -+ continue; -+ -+ group = rwnx_mu_group_from_id(mu, group_id); -+ for (j = 0; j < CONFIG_USER_MAX; j++) { -+ if (group->users[j]) { -+ trace_mu_group_selection(group->users[j], group_id); -+ group->users[j]->group_info.group = group_id; -+ -+ group_sta_for_each(group->users[j], tmp, map) { -+ if (group_id != tmp) -+ nb_users[tmp]--; -+ } -+ } -+ } -+ } -+ } -+ -+ mu->next_group_select = jiffies + -+ msecs_to_jiffies(RWNX_MU_GROUP_SELECT_INTERVAL); -+ mu->next_group_select |= 1; -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mu_group.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mu_group.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mu_group.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mu_group.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,181 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_mu_group.h -+ * -+ * Copyright (C) RivieraWaves 2016-2019 -+ * -+ ****************************************************************************** -+ */ -+#ifndef _RWNX_MU_GROUP_H_ -+#define _RWNX_MU_GROUP_H_ -+ -+#include -+#include -+ -+struct rwnx_hw; -+struct rwnx_sta; -+ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ -+/** -+ * struct rwnx_sta_group_info - Group Information for a STA -+ * -+ * @active: node for @mu->active_sta list -+ * @update: node for @mu->update_sta list -+ * @cnt: Number of groups the STA belongs to -+ * @map: Bitfield of groups the sta belongs to -+ * @traffic: Number of buffers sent since previous group selection -+ * @group: Id of the group selected by previous group selection -+ * (cf @rwnx_mu_group_sta_select) -+ */ -+struct rwnx_sta_group_info { -+ struct list_head active; -+ struct list_head update; -+ u16 last_update; -+ int cnt; -+ u64 map; -+ int traffic; -+ u8 group; -+}; -+ -+/** -+ * struct mu_group_info - Information about the users of a group -+ * -+ * @list: node for mu->active_groups -+ * @group_id: Group identifier -+ * @user_cnt: Number of the users in the group -+ * @users: Pointer to the sta, ordered by user position -+ */ -+struct rwnx_mu_group { -+ struct list_head list; -+ int group_id; -+ int user_cnt; -+ struct rwnx_sta *users[CONFIG_USER_MAX]; -+}; -+ -+/** -+ * struct rwnx_mu_info - Information about all MU group -+ * -+ * @active_groups: List of all possible groups. Ordered from the most recently -+ * used one to the least one (and possibly never used) -+ * @active_sta: List of MU beamformee sta that have been active (since previous -+ * group update). Ordered from the most recently active. -+ * @update_sta: List of sta whose group information has changed and need to be -+ * updated at fw level -+ * @groups: Table of all groups -+ * @group_work: Work item used to schedule group update -+ * @update_count: Counter used to identify the last group formation update. -+ * (cf rwnx_sta_group_info.last_update) -+ * @lock: Lock taken during group update. If tx happens lock is taken, then tx -+ * will not used MU. -+ * @next_group_assign: Next time the group selection should be run -+ * (ref @rwnx_mu_group_sta_select) -+ * @group_cnt: Number of group created -+ */ -+struct rwnx_mu_info { -+ struct list_head active_groups; -+ struct list_head active_sta; -+ struct list_head update_sta; -+ struct rwnx_mu_group groups[NX_MU_GROUP_MAX]; -+ struct delayed_work group_work; -+ u16 update_count; -+ struct semaphore lock; -+ unsigned long next_group_select; -+ u8 group_cnt; -+}; -+ -+#define RWNX_SU_GROUP BIT_ULL(0) -+#define RWNX_MU_GROUP_MASK 0x7ffffffffffffffeULL -+#define RWNX_MU_GROUP_INTERVAL 200 /* in ms */ -+#define RWNX_MU_GROUP_SELECT_INTERVAL 100 /* in ms */ -+// minimum traffic in a RWNX_MU_GROUP_SELECT_INTERVAL to consider the sta -+#define RWNX_MU_GROUP_MIN_TRAFFIC 50 /* in number of packet */ -+ -+ -+#define RWNX_GET_FIRST_GROUP_ID(map) (fls64(map) - 1) -+ -+#define group_sta_for_each(sta, id, map) \ -+ do { \ -+ map = sta->group_info.map & RWNX_MU_GROUP_MASK; \ -+ for (id = (fls64(map) - 1) ; id > 0 ; \ -+ map &= ~(u64)BIT_ULL(id), id = (fls64(map) - 1)) \ -+ } while (0) -+ -+#define group_for_each(id, map) \ -+ for (id = (fls64(map) - 1) ; id > 0 ; \ -+ map &= ~(u64)BIT_ULL(id), id = (fls64(map) - 1)) -+ -+#define RWNX_MUMIMO_INFO_POS_ID(info) (((info) >> 6) & 0x3) -+#define RWNX_MUMIMO_INFO_GROUP_ID(info) ((info) & 0x3f) -+ -+static inline -+struct rwnx_mu_group *rwnx_mu_group_from_id(struct rwnx_mu_info *mu, int id) -+{ -+ if (id > NX_MU_GROUP_MAX) -+ return NULL; -+ -+ return &mu->groups[id - 1]; -+} -+ -+ -+void rwnx_mu_group_sta_init(struct rwnx_sta *sta, -+ const struct ieee80211_vht_cap *vht_cap); -+void rwnx_mu_group_sta_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta); -+u64 rwnx_mu_group_sta_get_map(struct rwnx_sta *sta); -+int rwnx_mu_group_sta_get_pos(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, -+ int group_id); -+ -+void rwnx_mu_group_init(struct rwnx_hw *rwnx_hw); -+ -+void rwnx_mu_set_active_sta(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, -+ int traffic); -+void rwnx_mu_set_active_group(struct rwnx_hw *rwnx_hw, int group_id); -+void rwnx_mu_group_sta_select(struct rwnx_hw *rwnx_hw); -+ -+ -+#else /* ! CONFIG_RWNX_MUMIMO_TX */ -+ -+static inline -+void rwnx_mu_group_sta_init(struct rwnx_sta *sta, -+ const struct ieee80211_vht_cap *vht_cap) -+{} -+ -+static inline -+void rwnx_mu_group_sta_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) -+{} -+ -+static inline -+u64 rwnx_mu_group_sta_get_map(struct rwnx_sta *sta) -+{ -+ return 0; -+} -+ -+static inline -+int rwnx_mu_group_sta_get_pos(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, -+ int group_id) -+{ -+ return 0; -+} -+ -+static inline -+void rwnx_mu_group_init(struct rwnx_hw *rwnx_hw) -+{} -+ -+static inline -+void rwnx_mu_set_active_sta(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, -+ int traffic) -+{} -+ -+static inline -+void rwnx_mu_set_active_group(struct rwnx_hw *rwnx_hw, int group_id) -+{} -+ -+static inline -+void rwnx_mu_group_sta_select(struct rwnx_hw *rwnx_hw) -+{} -+ -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+ -+#endif /* _RWNX_MU_GROUP_H_ */ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_pci.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_pci.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_pci.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,94 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_pci.c -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+#include -+#include -+ -+#include "rwnx_defs.h" -+#include "rwnx_dini.h" -+#include "rwnx_v7.h" -+ -+#define PCI_VENDOR_ID_DINIGROUP 0x17DF -+#define PCI_DEVICE_ID_DINIGROUP_DNV6_F2PCIE 0x1907 -+ -+#define PCI_DEVICE_ID_XILINX_CEVA_VIRTEX7 0x7011 -+ -+static const struct pci_device_id rwnx_pci_ids[] = { -+ {PCI_DEVICE(PCI_VENDOR_ID_DINIGROUP, PCI_DEVICE_ID_DINIGROUP_DNV6_F2PCIE)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_XILINX_CEVA_VIRTEX7)}, -+ {0,} -+}; -+ -+ -+/* Uncomment this for depmod to create module alias */ -+/* We don't want this on development platform */ -+//MODULE_DEVICE_TABLE(pci, rwnx_pci_ids); -+ -+static int rwnx_pci_probe(struct pci_dev *pci_dev, -+ const struct pci_device_id *pci_id) -+{ -+ struct rwnx_plat *rwnx_plat = NULL; -+ void *drvdata; -+ int ret = -ENODEV; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (pci_id->vendor == PCI_VENDOR_ID_DINIGROUP) { -+ ret = rwnx_dini_platform_init(pci_dev, &rwnx_plat); -+ } else if (pci_id->vendor == PCI_VENDOR_ID_XILINX) { -+ ret = rwnx_v7_platform_init(pci_dev, &rwnx_plat); -+ } -+ -+ if (ret) -+ return ret; -+ -+ rwnx_plat->pci_dev = pci_dev; -+ -+ ret = rwnx_platform_init(rwnx_plat, &drvdata); -+ pci_set_drvdata(pci_dev, drvdata); -+ -+ if (ret) -+ rwnx_plat->deinit(rwnx_plat); -+ -+ return ret; -+} -+ -+static void rwnx_pci_remove(struct pci_dev *pci_dev) -+{ -+ struct rwnx_hw *rwnx_hw; -+ struct rwnx_plat *rwnx_plat; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ rwnx_hw = pci_get_drvdata(pci_dev); -+ rwnx_plat = rwnx_hw->plat; -+ -+ rwnx_platform_deinit(rwnx_hw); -+ rwnx_plat->deinit(rwnx_plat); -+ -+ pci_set_drvdata(pci_dev, NULL); -+} -+ -+static struct pci_driver rwnx_pci_drv = { -+ .name = KBUILD_MODNAME, -+ .id_table = rwnx_pci_ids, -+ .probe = rwnx_pci_probe, -+ .remove = rwnx_pci_remove -+}; -+ -+int rwnx_pci_register_drv(void) -+{ -+ return pci_register_driver(&rwnx_pci_drv); -+} -+ -+void rwnx_pci_unregister_drv(void) -+{ -+ pci_unregister_driver(&rwnx_pci_drv); -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_pci.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_pci.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_pci.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,17 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_pci.h -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _RWNX_PCI_H_ -+#define _RWNX_PCI_H_ -+ -+int rwnx_pci_register_drv(void); -+void rwnx_pci_unregister_drv(void); -+ -+#endif /* _RWNX_PCI_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,2108 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_platform.c -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "rwnx_platform.h" -+#include "reg_access.h" -+#include "hal_desc.h" -+#include "rwnx_main.h" -+#include "rwnx_pci.h" -+#ifndef CONFIG_RWNX_FHOST -+#include "ipc_host.h" -+#endif /* !CONFIG_RWNX_FHOST */ -+#include "rwnx_msg_tx.h" -+ -+#ifdef AICWF_SDIO_SUPPORT -+#include "aicwf_sdio.h" -+#endif -+ -+#ifdef AICWF_USB_SUPPORT -+#include "aicwf_usb.h" -+#endif -+#include "md5.h" -+#include "aicwf_compat_8800dc.h" -+#include "aicwf_compat_8800d80.h" -+ -+#ifdef CONFIG_USE_FW_REQUEST -+#include -+#endif -+ -+#define FW_PATH_MAX_LEN 200 -+extern char aic_fw_path[FW_PATH_MAX_LEN]; -+ -+//Parser state -+#define INIT 0 -+#define CMD 1 -+#define PRINT 2 -+#define GET_VALUE 3 -+ -+ -+struct rwnx_plat *g_rwnx_plat; -+ -+typedef struct -+{ -+ txpwr_lvl_conf_t txpwr_lvl; -+ txpwr_lvl_conf_v2_t txpwr_lvl_v2; -+ txpwr_lvl_conf_v3_t txpwr_lvl_v3; -+ txpwr_lvl_adj_conf_t txpwr_lvl_adj; -+ txpwr_loss_conf_t txpwr_loss; -+ txpwr_ofst_conf_t txpwr_ofst; -+ txpwr_ofst2x_conf_t txpwr_ofst2x; -+ xtal_cap_conf_t xtal_cap; -+} userconfig_info_t; -+ -+userconfig_info_t userconfig_info = { -+ .txpwr_lvl = { -+ .enable = 1, -+ .dsss = 9, -+ .ofdmlowrate_2g4 = 8, -+ .ofdm64qam_2g4 = 8, -+ .ofdm256qam_2g4 = 8, -+ .ofdm1024qam_2g4 = 8, -+ .ofdmlowrate_5g = 11, -+ .ofdm64qam_5g = 10, -+ .ofdm256qam_5g = 9, -+ .ofdm1024qam_5g = 9 -+ }, -+ .txpwr_lvl_v2 = { -+ .enable = 1, -+ .pwrlvl_11b_11ag_2g4 = -+ //1M, 2M, 5M5, 11M, 6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M -+ { 20, 20, 20, 20, 20, 20, 20, 20, 18, 18, 16, 16}, -+ .pwrlvl_11n_11ac_2g4 = -+ //MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9 -+ { 20, 20, 20, 20, 18, 18, 16, 16, 16, 16}, -+ .pwrlvl_11ax_2g4 = -+ //MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9, MCS10,MCS11 -+ { 20, 20, 20, 20, 18, 18, 16, 16, 16, 16, 15, 15}, -+ }, -+ .txpwr_lvl_v3 = { -+ .enable = 1, -+ .pwrlvl_11b_11ag_2g4 = -+ //1M, 2M, 5M5, 11M, 6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M -+ { 20, 20, 20, 20, 20, 20, 20, 20, 18, 18, 16, 16}, -+ .pwrlvl_11n_11ac_2g4 = -+ //MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9 -+ { 20, 20, 20, 20, 18, 18, 16, 16, 16, 16}, -+ .pwrlvl_11ax_2g4 = -+ //MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9, MCS10,MCS11 -+ { 20, 20, 20, 20, 18, 18, 16, 16, 16, 16, 15, 15}, -+ .pwrlvl_11a_5g = -+ //NA, NA, NA, NA, 6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M -+ { 0x80, 0x80, 0x80, 0x80, 20, 20, 20, 20, 18, 18, 16, 16}, -+ .pwrlvl_11n_11ac_5g = -+ //MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9 -+ { 20, 20, 20, 20, 18, 18, 16, 16, 16, 15}, -+ .pwrlvl_11ax_5g = -+ //MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9, MCS10,MCS11 -+ { 20, 20, 20, 20, 18, 18, 16, 16, 16, 15, 14, 14}, -+ }, -+ .txpwr_loss = { -+ .loss_enable = 1, -+ .loss_value = 0, -+ }, -+ .txpwr_ofst = { -+ .enable = 1, -+ .chan_1_4 = 0, -+ .chan_5_9 = 0, -+ .chan_10_13 = 0, -+ .chan_36_64 = 0, -+ .chan_100_120 = 0, -+ .chan_122_140 = 0, -+ .chan_142_165 = 0, -+ }, -+ .txpwr_ofst2x = { -+ .enable = 0, -+ .pwrofst2x_tbl_2g4 = -+ { // ch1-4, ch5-9, ch10-13 -+ { 0, 0, 0 }, // 11b -+ { 0, 0, 0 }, // ofdm_highrate -+ { 0, 0, 0 }, // ofdm_lowrate -+ }, -+ .pwrofst2x_tbl_5g = -+ { // ch42, ch58, ch106,ch122,ch138,ch155 -+ { 0, 0, 0, 0, 0, 0 }, // ofdm_lowrate -+ { 0, 0, 0, 0, 0, 0 }, // ofdm_highrate -+ { 0, 0, 0, 0, 0, 0 }, // ofdm_midrate -+ }, -+ }, -+ .xtal_cap = { -+ .enable = 0, -+ .xtal_cap = 24, -+ .xtal_cap_fine = 31, -+ }, -+}; -+ -+ -+#ifdef CONFIG_RWNX_TL4 -+/** -+ * rwnx_plat_tl4_fw_upload() - Load the requested FW into embedded side. -+ * -+ * @rwnx_plat: pointer to platform structure -+ * @fw_addr: Virtual address where the fw must be loaded -+ * @filename: Name of the fw. -+ * -+ * Load a fw, stored as a hex file, into the specified address -+ */ -+static int rwnx_plat_tl4_fw_upload(struct rwnx_plat *rwnx_plat, u8 *fw_addr, -+ char *filename) -+{ -+ struct device *dev = rwnx_platform_get_dev(rwnx_plat); -+ const struct firmware *fw; -+ int err = 0; -+ u32 *dst; -+ u8 const *file_data; -+ char typ0, typ1; -+ u32 addr0, addr1; -+ u32 dat0, dat1; -+ int remain; -+ -+ err = request_firmware(&fw, filename, dev); -+ if (err) { -+ return err; -+ } -+ file_data = fw->data; -+ remain = fw->size; -+ -+ /* Copy the file on the Embedded side */ -+ dev_dbg(dev, "\n### Now copy %s firmware, @ = %p\n", filename, fw_addr); -+ -+ /* Walk through all the lines of the configuration file */ -+ while (remain >= 16) { -+ u32 data, offset; -+ -+ if (sscanf(file_data, "%c:%08X %04X", &typ0, &addr0, &dat0) != 3) -+ break; -+ if ((addr0 & 0x01) != 0) { -+ addr0 = addr0 - 1; -+ dat0 = 0; -+ } else { -+ file_data += 16; -+ remain -= 16; -+ } -+ if ((remain < 16) || -+ (sscanf(file_data, "%c:%08X %04X", &typ1, &addr1, &dat1) != 3) || -+ (typ1 != typ0) || (addr1 != (addr0 + 1))) { -+ typ1 = typ0; -+ addr1 = addr0 + 1; -+ dat1 = 0; -+ } else { -+ file_data += 16; -+ remain -= 16; -+ } -+ -+ if (typ0 == 'C') { -+ offset = 0x00200000; -+ if ((addr1 % 4) == 3) -+ offset += 2*(addr1 - 3); -+ else -+ offset += 2*(addr1 + 1); -+ -+ data = dat1 | (dat0 << 16); -+ } else { -+ offset = 2*(addr1 - 1); -+ data = dat0 | (dat1 << 16); -+ } -+ dst = (u32 *)(fw_addr + offset); -+ *dst = data; -+ } -+ -+ release_firmware(fw); -+ -+ return err; -+} -+#endif -+ -+#if MODULE_IMPORT_NS -+MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); -+#endif -+ -+#if 0 -+/** -+ * rwnx_plat_bin_fw_upload() - Load the requested binary FW into embedded side. -+ * -+ * @rwnx_plat: pointer to platform structure -+ * @fw_addr: Virtual address where the fw must be loaded -+ * @filename: Name of the fw. -+ * -+ * Load a fw, stored as a binary file, into the specified address -+ */ -+static int rwnx_plat_bin_fw_upload(struct rwnx_plat *rwnx_plat, u8 *fw_addr, -+ char *filename) -+{ -+ const struct firmware *fw; -+ struct device *dev = rwnx_platform_get_dev(rwnx_plat); -+ int err = 0; -+ unsigned int i, size; -+ u32 *src, *dst; -+ -+ err = request_firmware(&fw, filename, dev); -+ if (err) { -+ return err; -+ } -+ -+ /* Copy the file on the Embedded side */ -+ dev_dbg(dev, "\n### Now copy %s firmware, @ = %p\n", filename, fw_addr); -+ -+ src = (u32 *)fw->data; -+ dst = (u32 *)fw_addr; -+ size = (unsigned int)fw->size; -+ -+ /* check potential platform bug on multiple stores vs memcpy */ -+ for (i = 0; i < size; i += 4) { -+ *dst++ = *src++; -+ } -+ -+ release_firmware(fw); -+ -+ return err; -+} -+#endif -+ -+#define MD5(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15] -+#define MD5PINRT "file md5:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\r\n" -+ -+static int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *device) -+{ -+#ifdef CONFIG_USE_FW_REQUEST -+ const struct firmware *fw = NULL; -+ u32 *dst = NULL; -+ void *buffer=NULL; -+ MD5_CTX md5; -+ unsigned char decrypt[16]; -+ int size = 0; -+ int ret = 0; -+ -+ printk("%s: request firmware = %s \n", __func__ ,name); -+ -+ ret = request_firmware(&fw, name, NULL); -+ -+ if (ret < 0) { -+ printk("Load %s fail\n", name); -+ release_firmware(fw); -+ return -1; -+ } -+ -+ size = fw->size; -+ dst = (u32 *)fw->data; -+ -+ if (size <= 0) { -+ printk("wrong size of firmware file\n"); -+ release_firmware(fw); -+ return -1; -+ } -+ -+ -+ buffer = vmalloc(size); -+ memset(buffer, 0, size); -+ memcpy(buffer, dst, size); -+ -+ *fw_buf = buffer; -+ -+ MD5Init(&md5); -+ MD5Update(&md5, (unsigned char *)buffer, size); -+ MD5Final(&md5, decrypt); -+ printk(MD5PINRT, MD5(decrypt)); -+ -+ release_firmware(fw); -+ -+ return size; -+#else -+ void *buffer = NULL; -+ char *path = NULL; -+ struct file *fp = NULL; -+ int size = 0, len = 0;// i = 0; -+ ssize_t rdlen = 0; -+ //u32 *src = NULL, *dst = NULL; -+ MD5_CTX md5; -+ unsigned char decrypt[16]; -+ -+ /* get the firmware path */ -+ path = __getname(); -+ if (!path) { -+ *fw_buf = NULL; -+ return -1; -+ } -+ -+ len = snprintf(path, FW_PATH_MAX_LEN, "%s/%s", aic_fw_path, name); -+ -+ //len = snprintf(path, FW_PATH_MAX_LEN, "%s", name); -+ if (len >= FW_PATH_MAX_LEN) { -+ AICWFDBG(LOGERROR, "%s: %s file's path too long\n", __func__, name); -+ *fw_buf = NULL; -+ __putname(path); -+ return -1; -+ } -+ -+ AICWFDBG(LOGINFO, "%s :firmware path = %s \n", __func__, path); -+ -+ /* open the firmware file */ -+ fp = filp_open(path, O_RDONLY, 0); -+ if (IS_ERR_OR_NULL(fp)) { -+ AICWFDBG(LOGERROR, "%s: %s file failed to open\n", __func__, name); -+ *fw_buf = NULL; -+ __putname(path); -+ fp = NULL; -+ return -1; -+ } -+ -+ size = i_size_read(file_inode(fp)); -+ if (size <= 0) { -+ AICWFDBG(LOGERROR, "%s: %s file size invalid %d\n", __func__, name, size); -+ *fw_buf = NULL; -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ return -1; -+ } -+ -+ /* start to read from firmware file */ -+ buffer = kzalloc(size, GFP_KERNEL); -+ if (!buffer) { -+ *fw_buf = NULL; -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ return -1; -+ } -+ -+ #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 13, 16) -+ rdlen = kernel_read(fp, buffer, size, &fp->f_pos); -+ #else -+ rdlen = kernel_read(fp, fp->f_pos, buffer, size); -+ #endif -+ -+ if (size != rdlen) { -+ AICWFDBG(LOGERROR, "%s: %s file rdlen invalid %d\n", __func__, name, (int)rdlen); -+ *fw_buf = NULL; -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ kfree(buffer); -+ buffer = NULL; -+ return -1; -+ } -+ if (rdlen > 0) { -+ fp->f_pos += rdlen; -+ } -+ -+#if 0 -+ /*start to transform the data format*/ -+ src = (u32 *)buffer; -+ dst = (u32 *)kzalloc(size, GFP_KERNEL); -+ -+ if (!dst) { -+ *fw_buf = NULL; -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ kfree(buffer); -+ buffer = NULL; -+ return -1; -+ } -+ -+ for (i = 0; i < (size/4); i++) { -+ dst[i] = src[i]; -+ } -+#endif -+ -+ __putname(path); -+ filp_close(fp, NULL); -+ fp = NULL; -+ //kfree(buffer); -+ //buffer = NULL; -+ *fw_buf = (u32*)buffer; -+ -+ MD5Init(&md5); -+ MD5Update(&md5, (unsigned char *)buffer, size); -+ MD5Final(&md5, decrypt); -+ -+ AICWFDBG(LOGINFO, MD5PINRT, MD5(decrypt)); -+ -+ return size; -+#endif -+} -+ -+ -+ -+/* buffer is allocated by kzalloc */ -+int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw, u32** buffer, const char *filename) -+{ -+ int size; -+ -+ AICWFDBG(LOGINFO, "### Load file %s\n", filename); -+ -+ size = rwnx_load_firmware(buffer, filename, NULL); -+ -+ return size; -+} -+ -+static void rwnx_restore_firmware(u32 **fw_buf) -+{ -+#ifdef CONFIG_USE_FW_REQUEST -+ vfree(*fw_buf); -+#else -+ kfree(*fw_buf); -+#endif -+ *fw_buf = NULL; -+} -+ -+ -+void rwnx_release_firmware_common(u32** buffer) -+{ -+ rwnx_restore_firmware(buffer); -+} -+ -+ -+/** -+ * rwnx_plat_bin_fw_upload_2() - Load the requested binary FW into embedded side. -+ * -+ * @rwnx_hw: Main driver data -+ * @fw_addr: Address where the fw must be loaded -+ * @filename: Name of the fw. -+ * -+ * Load a fw, stored as a binary file, into the specified address -+ */ -+int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr, -+ char *filename) -+{ -+ int err = 0; -+ unsigned int i = 0, size; -+// u32 *src; -+ u32 *dst=NULL; -+ -+ /* Copy the file on the Embedded side */ -+ AICWFDBG(LOGINFO, "### Upload %s firmware, @ = %x\n", filename, fw_addr); -+ -+ size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); -+ if (!dst) { -+ AICWFDBG(LOGERROR, "No such file or directory\n"); -+ return -1; -+ } -+ if (size <= 0) { -+ AICWFDBG(LOGERROR, "wrong size of firmware file\n"); -+ dst = NULL; -+ err = -1; -+ } -+ -+ AICWFDBG(LOGINFO, "size=%d, dst[0]=%x\n", size, dst[0]); -+ if (size > 512) { -+ for (; i < (size - 512); i += 512) { -+ //printk("wr blk 0: %p -> %x\r\n", dst + i / 4, fw_addr + i); -+ err = rwnx_send_dbg_mem_block_write_req(rwnx_hw, fw_addr + i, 512, dst + i / 4); -+ if (err) { -+ AICWFDBG(LOGERROR, "bin upload fail: %x, err:%d\r\n", fw_addr + i, err); -+ break; -+ } -+ } -+ } -+ if (!err && (i < size)) { -+ //printk("wr blk 1: %p -> %x\r\n", dst + i / 4, fw_addr + i); -+ err = rwnx_send_dbg_mem_block_write_req(rwnx_hw, fw_addr + i, size - i, dst + i / 4); -+ if (err) { -+ AICWFDBG(LOGERROR, "bin upload fail: %x, err:%d\r\n", fw_addr + i, err); -+ } -+ } -+ -+ if (dst) { -+ rwnx_release_firmware_common(&dst); -+ } -+ -+ return err; -+} -+ -+ -+ -+typedef struct { -+ txpwr_idx_conf_t txpwr_idx; -+ txpwr_ofst_conf_t txpwr_ofst; -+ xtal_cap_conf_t xtal_cap; -+} nvram_info_t; -+ -+nvram_info_t nvram_info = { -+ .txpwr_idx = { -+ .enable = 1, -+ .dsss = 9, -+ .ofdmlowrate_2g4 = 8, -+ .ofdm64qam_2g4 = 8, -+ .ofdm256qam_2g4 = 8, -+ .ofdm1024qam_2g4 = 8, -+ .ofdmlowrate_5g = 11, -+ .ofdm64qam_5g = 10, -+ .ofdm256qam_5g = 9, -+ .ofdm1024qam_5g = 9 -+ }, -+ .txpwr_ofst = { -+ .enable = 1, -+ .chan_1_4 = 0, -+ .chan_5_9 = 0, -+ .chan_10_13 = 0, -+ .chan_36_64 = 0, -+ .chan_100_120 = 0, -+ .chan_122_140 = 0, -+ .chan_142_165 = 0, -+ }, -+ .xtal_cap = { -+ .enable = 0, -+ .xtal_cap = 24, -+ .xtal_cap_fine = 31, -+ }, -+}; -+ -+void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst) -+{ -+ txpwr_ofst->enable = userconfig_info.txpwr_ofst.enable; -+ txpwr_ofst->chan_1_4 = userconfig_info.txpwr_ofst.chan_1_4; -+ txpwr_ofst->chan_5_9 = userconfig_info.txpwr_ofst.chan_5_9; -+ txpwr_ofst->chan_10_13 = userconfig_info.txpwr_ofst.chan_10_13; -+ txpwr_ofst->chan_36_64 = userconfig_info.txpwr_ofst.chan_36_64; -+ txpwr_ofst->chan_100_120 = userconfig_info.txpwr_ofst.chan_100_120; -+ txpwr_ofst->chan_122_140 = userconfig_info.txpwr_ofst.chan_122_140; -+ txpwr_ofst->chan_142_165 = userconfig_info.txpwr_ofst.chan_142_165; -+ -+ AICWFDBG(LOGINFO, "%s:enable :%d\r\n", __func__, txpwr_ofst->enable); -+ AICWFDBG(LOGINFO, "%s:chan_1_4 :%d\r\n", __func__, txpwr_ofst->chan_1_4); -+ AICWFDBG(LOGINFO, "%s:chan_5_9 :%d\r\n", __func__, txpwr_ofst->chan_5_9); -+ AICWFDBG(LOGINFO, "%s:chan_10_13 :%d\r\n", __func__, txpwr_ofst->chan_10_13); -+ AICWFDBG(LOGINFO, "%s:chan_36_64 :%d\r\n", __func__, txpwr_ofst->chan_36_64); -+ AICWFDBG(LOGINFO, "%s:chan_100_120:%d\r\n", __func__, txpwr_ofst->chan_100_120); -+ AICWFDBG(LOGINFO, "%s:chan_122_140:%d\r\n", __func__, txpwr_ofst->chan_122_140); -+ AICWFDBG(LOGINFO, "%s:chan_142_165:%d\r\n", __func__, txpwr_ofst->chan_142_165); -+} -+ -+void get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x_conf_t *txpwr_ofst2x) -+{ -+ int type, ch_grp; -+ *txpwr_ofst2x = userconfig_info.txpwr_ofst2x; -+ AICWFDBG(LOGINFO, "%s:enable :%d\r\n", __func__, txpwr_ofst2x->enable); -+ AICWFDBG(LOGINFO, "pwrofst2x 2.4g: [0]:11b, [1]:ofdm_highrate, [2]:ofdm_lowrate\n" -+ " chan=" "\t1-4" "\t5-9" "\t10-13"); -+ for (type = 0; type < 3; type++) { -+ AICWFDBG(LOGINFO, "\n [%d] =", type); -+ for (ch_grp = 0; ch_grp < 3; ch_grp++) { -+ AICWFDBG(LOGINFO, "\t%d", txpwr_ofst2x->pwrofst2x_tbl_2g4[type][ch_grp]); -+ } -+ } -+ AICWFDBG(LOGINFO, "\npwrofst2x 5g: [0]:ofdm_lowrate, [1]:ofdm_highrate, [2]:ofdm_midrate\n" -+ " chan=" "\t36-50" "\t51-64" "\t98-114" "\t115-130" "\t131-146" "\t147-166"); -+ for (type = 0; type < 3; type++) { -+ AICWFDBG(LOGINFO, "\n [%d] =", type); -+ for (ch_grp = 0; ch_grp < 6; ch_grp++) { -+ AICWFDBG(LOGINFO, "\t%d", txpwr_ofst2x->pwrofst2x_tbl_5g[type][ch_grp]); -+ } -+ } -+ AICWFDBG(LOGINFO, "\n"); -+} -+ -+void get_userconfig_txpwr_idx(txpwr_idx_conf_t *txpwr_idx) -+{ -+ memcpy(txpwr_idx, &(nvram_info.txpwr_idx), sizeof(txpwr_idx_conf_t)); -+} -+ -+void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst) -+{ -+ memcpy(txpwr_ofst, &(nvram_info.txpwr_ofst), sizeof(txpwr_ofst_conf_t)); -+} -+ -+void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap) -+{ -+ if(nvram_info.xtal_cap.enable){ -+ *xtal_cap = nvram_info.xtal_cap; -+ } -+ -+ if(userconfig_info.xtal_cap.enable){ -+ *xtal_cap = userconfig_info.xtal_cap; -+ } -+ -+ AICWFDBG(LOGINFO, "%s:enable :%d\r\n", __func__, xtal_cap->enable); -+ AICWFDBG(LOGINFO, "%s:xtal_cap :%d\r\n", __func__, xtal_cap->xtal_cap); -+ AICWFDBG(LOGINFO, "%s:xtal_cap_fine:%d\r\n", __func__, xtal_cap->xtal_cap_fine); -+} -+ -+ -+#define MATCH_NODE(type, node, cfg_key) {cfg_key, offsetof(type, node)} -+ -+struct parse_match_t { -+ char keyname[64]; -+ int offset; -+}; -+ -+static const char *parse_key_prefix[] = { -+ [0x01] = "module0_", -+ [0x21] = "module1_", -+}; -+ -+static const struct parse_match_t parse_match_tab[] = { -+ MATCH_NODE(nvram_info_t, txpwr_idx.enable, "enable"), -+ MATCH_NODE(nvram_info_t, txpwr_idx.dsss, "dsss"), -+ MATCH_NODE(nvram_info_t, txpwr_idx.ofdmlowrate_2g4, "ofdmlowrate_2g4"), -+ MATCH_NODE(nvram_info_t, txpwr_idx.ofdm64qam_2g4, "ofdm64qam_2g4"), -+ MATCH_NODE(nvram_info_t, txpwr_idx.ofdm256qam_2g4, "ofdm256qam_2g4"), -+ MATCH_NODE(nvram_info_t, txpwr_idx.ofdm1024qam_2g4, "ofdm1024qam_2g4"), -+ MATCH_NODE(nvram_info_t, txpwr_idx.ofdmlowrate_5g, "ofdmlowrate_5g"), -+ MATCH_NODE(nvram_info_t, txpwr_idx.ofdm64qam_5g, "ofdm64qam_5g"), -+ MATCH_NODE(nvram_info_t, txpwr_idx.ofdm256qam_5g, "ofdm256qam_5g"), -+ MATCH_NODE(nvram_info_t, txpwr_idx.ofdm1024qam_5g, "ofdm1024qam_5g"), -+ -+ MATCH_NODE(nvram_info_t, txpwr_ofst.enable, "ofst_enable"), -+ MATCH_NODE(nvram_info_t, txpwr_ofst.chan_1_4, "ofst_chan_1_4"), -+ MATCH_NODE(nvram_info_t, txpwr_ofst.chan_5_9, "ofst_chan_5_9"), -+ MATCH_NODE(nvram_info_t, txpwr_ofst.chan_10_13, "ofst_chan_10_13"), -+ MATCH_NODE(nvram_info_t, txpwr_ofst.chan_36_64, "ofst_chan_36_64"), -+ MATCH_NODE(nvram_info_t, txpwr_ofst.chan_100_120, "ofst_chan_100_120"), -+ MATCH_NODE(nvram_info_t, txpwr_ofst.chan_122_140, "ofst_chan_122_140"), -+ MATCH_NODE(nvram_info_t, txpwr_ofst.chan_142_165, "ofst_chan_142_165"), -+ -+ MATCH_NODE(nvram_info_t, xtal_cap.enable, "xtal_enable"), -+ MATCH_NODE(nvram_info_t, xtal_cap.xtal_cap, "xtal_cap"), -+ MATCH_NODE(nvram_info_t, xtal_cap.xtal_cap_fine, "xtal_cap_fine"), -+}; -+ -+static int parse_key_val(const char *str, const char *key, char *val) -+{ -+ const char *p = NULL; -+ const char *dst = NULL; -+ int keysize = 0; -+ int bufsize = 0; -+ -+ if (str == NULL || key == NULL || val == NULL) -+ return -1; -+ -+ keysize = strlen(key); -+ bufsize = strlen(str); -+ if (bufsize <= keysize) -+ return -1; -+ -+ p = str; -+ while (*p != 0 && *p == ' ') -+ p++; -+ -+ if (*p == '#') -+ return -1; -+ -+ if (str + bufsize - p <= keysize) -+ return -1; -+ -+ if (strncmp(p, key, keysize) != 0) -+ return -1; -+ -+ p += keysize; -+ -+ while (*p != 0 && *p == ' ') -+ p++; -+ -+ if (*p != '=') -+ return -1; -+ -+ p++; -+ while (*p != 0 && *p == ' ') -+ p++; -+ -+ if (*p == '"') -+ p++; -+ -+ dst = p; -+ while (*p != 0) -+ p++; -+ -+ p--; -+ while (*p == ' ') -+ p--; -+ -+ if (*p == '"') -+ p--; -+ -+ while (*p == '\r' || *p == '\n') -+ p--; -+ -+ p++; -+ strncpy(val, dst, p -dst); -+ val[p - dst] = 0; -+ return 0; -+} -+ -+ -+int rwnx_atoi(char *value) -+{ -+ int len = 0; -+ int i = 0; -+ int result = 0; -+ int flag = 1; -+ -+ if (value[0] == '-') { -+ flag = -1; -+ value++; -+ } -+ len = strlen(value); -+ -+ for (i = 0;i < len ;i++) { -+ result = result * 10; -+ if (value[i] >= 48 && value[i] <= 57) { -+ result += value[i] - 48; -+ } else { -+ result = 0; -+ break; -+ } -+ } -+ -+ return result * flag; -+} -+ -+ -+void rwnx_plat_nvram_set_value(char *command, char *value) -+{ -+ //TODO send command -+ AICWFDBG(LOGINFO, "%s:command=%s value=%s\n", __func__, command, value); -+ if (!strcmp(command, "enable")) { -+ userconfig_info.txpwr_lvl.enable = rwnx_atoi(value); -+ userconfig_info.txpwr_lvl_v2.enable = rwnx_atoi(value); -+ } else if (!strcmp(command, "dsss")) { -+ userconfig_info.txpwr_lvl.dsss = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdmlowrate_2g4")) { -+ userconfig_info.txpwr_lvl.ofdmlowrate_2g4 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm64qam_2g4")) { -+ userconfig_info.txpwr_lvl.ofdm64qam_2g4 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm256qam_2g4")) { -+ userconfig_info.txpwr_lvl.ofdm256qam_2g4 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm1024qam_2g4")) { -+ userconfig_info.txpwr_lvl.ofdm1024qam_2g4 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdmlowrate_5g")) { -+ userconfig_info.txpwr_lvl.ofdmlowrate_5g = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm64qam_5g")) { -+ userconfig_info.txpwr_lvl.ofdm64qam_5g = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm256qam_5g")) { -+ userconfig_info.txpwr_lvl.ofdm256qam_5g = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm1024qam_5g")) { -+ userconfig_info.txpwr_lvl.ofdm1024qam_5g = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_1m_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_2m_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_5m5_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_11m_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_6m_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_9m_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_12m_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[6] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_18m_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[7] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_24m_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[8] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_36m_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[9] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_48m_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[10] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_54m_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[11] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs0_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs1_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs2_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs3_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs4_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs5_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs6_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[6] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs7_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[7] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs8_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[8] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs9_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[9] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs0_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs1_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs2_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs3_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs4_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs5_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs6_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[6] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs7_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[7] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs8_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[8] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs9_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[9] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs10_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[10] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs11_2g4")) { -+ userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[11] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_enable")) { -+ userconfig_info.txpwr_ofst.enable = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_1_4")) { -+ userconfig_info.txpwr_ofst.chan_1_4 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_5_9")) { -+ userconfig_info.txpwr_ofst.chan_5_9 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_10_13")) { -+ userconfig_info.txpwr_ofst.chan_10_13 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_36_64")) { -+ userconfig_info.txpwr_ofst.chan_36_64 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_100_120")) { -+ userconfig_info.txpwr_ofst.chan_100_120 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_122_140")) { -+ userconfig_info.txpwr_ofst.chan_122_140 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_142_165")) { -+ userconfig_info.txpwr_ofst.chan_142_165 = rwnx_atoi(value); -+ } else if (!strcmp(command, "xtal_enable")) { -+ userconfig_info.xtal_cap.enable = rwnx_atoi(value); -+ } else if (!strcmp(command, "xtal_cap")) { -+ userconfig_info.xtal_cap.xtal_cap = rwnx_atoi(value); -+ } else if (!strcmp(command, "xtal_cap_fine")) { -+ userconfig_info.xtal_cap.xtal_cap_fine = rwnx_atoi(value); -+ } else { -+ AICWFDBG(LOGERROR, "invalid cmd: %s\n", command); -+ } -+} -+ -+void rwnx_plat_nvram_set_value_v3(char *command, char *value) -+{ -+ //TODO send command -+ AICWFDBG(LOGINFO, "%s:command=%s value=%s\n", __func__, command, value); -+ if (!strcmp(command, "enable")) { -+ userconfig_info.txpwr_lvl.enable = rwnx_atoi(value); -+ userconfig_info.txpwr_lvl_v3.enable = rwnx_atoi(value); -+ } else if (!strcmp(command, "dsss")) { -+ userconfig_info.txpwr_lvl.dsss = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdmlowrate_2g4")) { -+ userconfig_info.txpwr_lvl.ofdmlowrate_2g4 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm64qam_2g4")) { -+ userconfig_info.txpwr_lvl.ofdm64qam_2g4 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm256qam_2g4")) { -+ userconfig_info.txpwr_lvl.ofdm256qam_2g4 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm1024qam_2g4")) { -+ userconfig_info.txpwr_lvl.ofdm1024qam_2g4 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdmlowrate_5g")) { -+ userconfig_info.txpwr_lvl.ofdmlowrate_5g = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm64qam_5g")) { -+ userconfig_info.txpwr_lvl.ofdm64qam_5g = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm256qam_5g")) { -+ userconfig_info.txpwr_lvl.ofdm256qam_5g = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofdm1024qam_5g")) { -+ userconfig_info.txpwr_lvl.ofdm1024qam_5g = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_1m_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_2m_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_5m5_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_11m_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_6m_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_9m_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_12m_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[6] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_18m_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[7] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_24m_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[8] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_36m_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[9] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_48m_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[10] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11b_11ag_54m_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[11] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs0_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs1_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs2_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs3_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs4_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs5_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs6_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[6] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs7_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[7] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs8_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[8] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs9_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[9] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs0_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs1_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs2_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs3_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs4_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs5_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs6_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[6] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs7_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[7] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs8_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[8] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs9_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[9] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs10_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[10] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs11_2g4")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[11] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_1m_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_2m_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_5m5_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_11m_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_6m_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_9m_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_12m_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[6] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_18m_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[7] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_24m_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[8] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_36m_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[9] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_48m_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[10] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11a_54m_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[11] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs0_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs1_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs2_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs3_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs4_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs5_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs6_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[6] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs7_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[7] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs8_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[8] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11n_11ac_mcs9_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[9] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs0_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs1_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs2_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs3_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs4_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs5_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs6_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[6] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs7_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[7] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs8_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[8] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs9_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[9] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs10_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[10] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_11ax_mcs11_5g")) { -+ userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[11] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_adj_enable")) { -+ userconfig_info.txpwr_lvl_adj.enable = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_adj_2g4_chan_1_4")) { -+ userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_2g4[0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_adj_2g4_chan_5_9")) { -+ userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_2g4[1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "lvl_adj_2g4_chan_10_13")) { -+ userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_2g4[2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_42")) { -+ userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_58")) { -+ userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_106")) { -+ userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_122")) { -+ userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_138")) { -+ userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_155")) { -+ userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "loss_enable")) { -+ userconfig_info.txpwr_loss.loss_enable = rwnx_atoi(value); -+ } else if (!strcmp(command, "loss_value")) { -+ userconfig_info.txpwr_loss.loss_value = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_enable")) { -+ userconfig_info.txpwr_ofst.enable = rwnx_atoi(value); -+ userconfig_info.txpwr_ofst2x.enable = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_1_4")) { -+ userconfig_info.txpwr_ofst.chan_1_4 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_5_9")) { -+ userconfig_info.txpwr_ofst.chan_5_9 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_10_13")) { -+ userconfig_info.txpwr_ofst.chan_10_13 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_36_64")) { -+ userconfig_info.txpwr_ofst.chan_36_64 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_100_120")) { -+ userconfig_info.txpwr_ofst.chan_100_120 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_122_140")) { -+ userconfig_info.txpwr_ofst.chan_122_140 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_chan_142_165")) { -+ userconfig_info.txpwr_ofst.chan_142_165 = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_2g4_11b_chan_1_4")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[0][0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_2g4_11b_chan_5_9")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[0][1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_2g4_11b_chan_10_13")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[0][2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_2g4_ofdm_highrate_chan_1_4")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[1][0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_2g4_ofdm_highrate_chan_5_9")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[1][1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_2g4_ofdm_highrate_chan_10_13")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[1][2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_2g4_ofdm_lowrate_chan_1_4")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[2][0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_2g4_ofdm_lowrate_chan_5_9")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[2][1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_2g4_ofdm_lowrate_chan_10_13")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[2][0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_lowrate_chan_42")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[0][0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_lowrate_chan_58")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[0][1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_lowrate_chan_106")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[0][2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_lowrate_chan_122")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[0][3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_lowrate_chan_138")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[0][4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_lowrate_chan_155")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[0][5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_42")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[1][0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_58")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[1][1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_106")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[1][2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_122")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[1][3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_138")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[1][4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_highrate_chan_155")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[1][5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_midrate_chan_42")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[2][0] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_midrate_chan_58")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[2][1] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_midrate_chan_106")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[2][2] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_midrate_chan_122")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[2][3] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_midrate_chan_138")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[2][4] = rwnx_atoi(value); -+ } else if (!strcmp(command, "ofst_5g_ofdm_midrate_chan_155")) { -+ userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[2][5] = rwnx_atoi(value); -+ } else if (!strcmp(command, "xtal_enable")) { -+ userconfig_info.xtal_cap.enable = rwnx_atoi(value); -+ } else if (!strcmp(command, "xtal_cap")) { -+ userconfig_info.xtal_cap.xtal_cap = rwnx_atoi(value); -+ } else if (!strcmp(command, "xtal_cap_fine")) { -+ userconfig_info.xtal_cap.xtal_cap_fine = rwnx_atoi(value); -+ } else { -+ AICWFDBG(LOGERROR, "invalid cmd: %s\n", command); -+ } -+} -+ -+void rwnx_plat_userconfig_parsing2(char *buffer, int size) -+{ -+ int i = 0; -+ int parse_state = 0; -+ char command[30]; -+ char value[100]; -+ int char_counter = 0; -+ -+ memset(command, 0, 30); -+ memset(value, 0, 100); -+ -+ for (i = 0; i < size; i++) { -+ //Send command or print nvram log when char is \r or \n -+ if (buffer[i] == 0x0a || buffer[i] == 0x0d) { -+ if (command[0] != 0 && value[0] != 0) { -+ if (parse_state == PRINT) { -+ AICWFDBG(LOGINFO, "%s:%s\r\n", __func__, value); -+ } else if (parse_state == GET_VALUE) { -+ rwnx_plat_nvram_set_value(command, value); -+ } -+ } -+ //Reset command value and char_counter -+ memset(command, 0, 30); -+ memset(value, 0, 100); -+ char_counter = 0; -+ parse_state = INIT; -+ continue; -+ } -+ -+ //Switch parser state -+ if (parse_state == INIT) { -+ if (buffer[i] == '#') { -+ parse_state = PRINT; -+ continue; -+ } else if (buffer[i] == 0x0a || buffer[i] == 0x0d) { -+ parse_state = INIT; -+ continue; -+ } else { -+ parse_state = CMD; -+ } -+ } -+ -+ //Fill data to command and value -+ if (parse_state == PRINT) { -+ command[0] = 0x01; -+ value[char_counter] = buffer[i]; -+ char_counter++; -+ } else if (parse_state == CMD) { -+ if (command[0] != 0 && buffer[i] == '=') { -+ parse_state = GET_VALUE; -+ char_counter = 0; -+ continue; -+ } -+ command[char_counter] = buffer[i]; -+ char_counter++; -+ } else if (parse_state == GET_VALUE) { -+ value[char_counter] = buffer[i]; -+ char_counter++; -+ } -+ } -+} -+ -+void rwnx_plat_userconfig_parsing3(char *buffer, int size) -+{ -+ int i = 0; -+ int parse_state = 0; -+ char command[64]; -+ char value[100]; -+ int char_counter = 0; -+ -+ memset(command, 0, 64); -+ memset(value, 0, 100); -+ -+ for (i = 0; i < size; i++) { -+ //Send command or print nvram log when char is \r or \n -+ if (buffer[i] == 0x0a || buffer[i] == 0x0d) { -+ if (command[0] != 0 && value[0] != 0) { -+ if (parse_state == PRINT) { -+ AICWFDBG(LOGINFO, "%s:%s\r\n", __func__, value); -+ } else if (parse_state == GET_VALUE) { -+ rwnx_plat_nvram_set_value_v3(command, value); -+ } -+ } -+ //Reset command value and char_counter -+ memset(command, 0, 64); -+ memset(value, 0, 100); -+ char_counter = 0; -+ parse_state = INIT; -+ continue; -+ } -+ -+ //Switch parser state -+ if (parse_state == INIT) { -+ if (buffer[i] == '#') { -+ parse_state = PRINT; -+ continue; -+ } else if (buffer[i] == 0x0a || buffer[i] == 0x0d) { -+ parse_state = INIT; -+ continue; -+ } else { -+ parse_state = CMD; -+ } -+ } -+ -+ //Fill data to command and value -+ if (parse_state == PRINT) { -+ command[0] = 0x01; -+ value[char_counter] = buffer[i]; -+ char_counter++; -+ } else if (parse_state == CMD) { -+ if (command[0] != 0 && buffer[i] == '=') { -+ parse_state = GET_VALUE; -+ char_counter = 0; -+ continue; -+ } -+ command[char_counter] = buffer[i]; -+ char_counter++; -+ } else if (parse_state == GET_VALUE) { -+ if(buffer[i] != 0x2D && (buffer[i] < 0x30 || buffer[i] > 0x39)) { -+ continue; -+ } -+ value[char_counter] = buffer[i]; -+ char_counter++; -+ } -+ } -+} -+ -+void rwnx_plat_userconfig_parsing(struct rwnx_hw *rwnx_hw, char *buffer, int size) -+{ -+ char conf[100], keyname[64]; -+ char *line; -+ char *data; -+ int i = 0, err, len = 0; -+ long val; -+ -+ if (size <= 0) { -+ pr_err("Config buffer size %d error\n", size); -+ return; -+ } -+ -+ printk("%s rwnx_hw->vendor_info:0x%02X \r\n", __func__, rwnx_hw->vendor_info); -+ if (rwnx_hw->vendor_info == 0x00 || -+ (rwnx_hw->vendor_info > (sizeof(parse_key_prefix) / sizeof(parse_key_prefix[0]) - 1))) { -+ printk("Unsuppor vendor info config\n"); -+ printk("Using module0 config\n"); -+ rwnx_hw->vendor_info = 0x01; -+ //return; -+ } -+ -+ data = vmalloc(size + 1); -+ if (!data) { -+ pr_err("vmalloc fail\n"); -+ return; -+ } -+ -+ memcpy(data, buffer, size); -+ buffer = data; -+ -+ while (1) { -+ line = buffer; -+ if (*line == 0) -+ break; -+ -+ while (*buffer != '\r' && *buffer != '\n' && *buffer != 0 && len++ < size) -+ buffer++; -+ -+ while ((*buffer == '\r' || *buffer == '\n') && len++ < size) -+ *buffer++ = 0; -+ -+ if (len >= size) -+ *buffer = 0; -+ -+ // store value to data struct -+ for (i = 0; i < sizeof(parse_match_tab) / sizeof(parse_match_tab[0]); i++) { -+ sprintf(&keyname[0], "%s%s", parse_key_prefix[rwnx_hw->vendor_info], parse_match_tab[i].keyname); -+ if (parse_key_val(line, keyname, conf) == 0) { -+ err = kstrtol(conf, 0, &val); -+ *(unsigned long *)((unsigned long)&nvram_info + parse_match_tab[i].offset) = val; -+ printk("%s, %s = %ld\n", __func__, parse_match_tab[i].keyname, val); -+ break; -+ } -+ } -+ -+ } -+ vfree(data); -+} -+ -+static int aic_load_firmware(u32 ** fw_buf, char *fw_path,const char *name, struct device *device) -+{ -+#ifdef CONFIG_USE_FW_REQUEST -+ const struct firmware *fw = NULL; -+ u32 *dst = NULL; -+ void *buffer=NULL; -+ MD5_CTX md5; -+ unsigned char decrypt[16]; -+ int size = 0; -+ int ret = 0; -+ -+ AICWFDBG(LOGINFO, "%s: request firmware = %s \n", __func__ ,name); -+ -+ ret = request_firmware(&fw, name, NULL); -+ -+ if (ret < 0) { -+ AICWFDBG(LOGERROR, "Load %s fail\n", name); -+ release_firmware(fw); -+ return -1; -+ } -+ -+ size = fw->size; -+ dst = (u32 *)fw->data; -+ -+ if (size <= 0) { -+ AICWFDBG(LOGERROR, "wrong size of firmware file\n"); -+ release_firmware(fw); -+ return -1; -+ } -+ -+ buffer = vmalloc(size); -+ memset(buffer, 0, size); -+ memcpy(buffer, dst, size); -+ -+ *fw_buf = buffer; -+ -+ MD5Init(&md5); -+ MD5Update(&md5, (unsigned char *)buffer, size); -+ MD5Final(&md5, decrypt); -+ AICWFDBG(LOGINFO, MD5PINRT, MD5(decrypt)); -+ -+ release_firmware(fw); -+ -+ return size; -+#else -+ void *buffer=NULL; -+ char *path=NULL; -+ struct file *fp=NULL; -+ int size = 0, len=0;//, i=0; -+ ssize_t rdlen=0; -+ //u32 *src=NULL, *dst = NULL; -+ -+ /* get the firmware path */ -+ path = __getname(); -+ if (!path){ -+ *fw_buf=NULL; -+ return -1; -+ } -+ -+ len = sprintf(path, "%s/%s",fw_path, name); -+ -+ AICWFDBG(LOGINFO, "%s :firmware path = %s \n", __func__ ,path); -+ -+ -+ /* open the firmware file */ -+ fp=filp_open(path, O_RDONLY, 0); -+ if(IS_ERR(fp) || (!fp)){ -+ printk("%s: %s file failed to open\n", __func__, name); -+ if(IS_ERR(fp)){ -+ printk("is_Err\n"); -+ } -+ if((!fp)){ -+ printk("null\n"); -+ } -+ *fw_buf=NULL; -+ __putname(path); -+ fp=NULL; -+ return -1; -+ } -+ -+ size = i_size_read(file_inode(fp)); -+ if(size<=0){ -+ printk("%s: %s file size invalid %d\n", __func__, name, size); -+ *fw_buf=NULL; -+ __putname(path); -+ filp_close(fp,NULL); -+ fp=NULL; -+ return -1; -+ } -+ -+ /* start to read from firmware file */ -+ buffer = vmalloc(size); -+ memset(buffer, 0, size); -+ if(!buffer){ -+ *fw_buf=NULL; -+ __putname(path); -+ filp_close(fp,NULL); -+ fp=NULL; -+ return -1; -+ } -+ -+ -+ #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 13, 16) -+ rdlen = kernel_read(fp, buffer, size, &fp->f_pos); -+ #else -+ rdlen = kernel_read(fp, fp->f_pos, buffer, size); -+ #endif -+ -+ if(size != rdlen){ -+ printk("%s: %s file rdlen invalid %d %d\n", __func__, name, (int)rdlen, size); -+ *fw_buf=NULL; -+ __putname(path); -+ filp_close(fp,NULL); -+ fp=NULL; -+ vfree(buffer); -+ buffer=NULL; -+ return -1; -+ } -+ if(rdlen > 0){ -+ fp->f_pos += rdlen; -+ //printk("f_pos=%d\n", (int)fp->f_pos); -+ } -+ -+#if 0 -+ /*start to transform the data format*/ -+ src = (u32*)buffer; -+ //printk("malloc dst\n"); -+ dst = (u32*)vmalloc(size); -+ memset(dst, 0, size); -+ -+ if(!dst){ -+ *fw_buf=NULL; -+ __putname(path); -+ filp_close(fp,NULL); -+ fp=NULL; -+ vfree(buffer); -+ buffer=NULL; -+ return -1; -+ } -+ -+ for(i=0;i<(size/4);i++){ -+ dst[i] = src[i]; -+ } -+#endif -+ -+ __putname(path); -+ filp_close(fp,NULL); -+ fp=NULL; -+ //vfree(buffer); -+ //buffer=NULL; -+ *fw_buf = (u32 *)buffer; -+ -+ return size; -+#endif -+} -+ -+ -+ -+#define FW_USERCONFIG_NAME "aic_userconfig.txt" -+ -+int rwnx_plat_userconfig_upload_android(struct rwnx_hw *rwnx_hw, char *fw_path, char *filename) -+{ -+ int size; -+ u32 *dst=NULL; -+ -+ printk("userconfig file path:%s \r\n", filename); -+ -+ /* load aic firmware */ -+ size = aic_load_firmware(&dst, fw_path ,filename, NULL); -+ if(size <= 0){ -+ printk("wrong size of firmware file\n"); -+ vfree(dst); -+ dst = NULL; -+ return 0; -+ } -+ -+ /* Copy the file on the Embedded side */ -+ printk("### Upload %s userconfig, size=%d\n", filename, size); -+ -+ rwnx_plat_userconfig_parsing(rwnx_hw, (char *)dst, size); -+ -+ if (dst) { -+ vfree(dst); -+ dst = NULL; -+ } -+ -+ printk("userconfig download complete\n\n"); -+ -+ return 0; -+ -+} -+ -+/** -+ * rwnx_plat_fmac_load() - Load FW code -+ * -+ * @rwnx_hw: Main driver data -+ */ -+ #if 0 -+static int rwnx_plat_fmac_load(struct rwnx_hw *rwnx_hw, char *fw_path) -+{ -+ int ret = 0; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ ret = rwnx_plat_userconfig_upload_android(rwnx_hw, fw_path, FW_USERCONFIG_NAME); -+ return ret; -+} -+ #endif -+ -+/** -+ * rwnx_platform_reset() - Reset the platform -+ * -+ * @rwnx_plat: platform data -+ */ -+static int rwnx_platform_reset(struct rwnx_plat *rwnx_plat) -+{ -+ u32 regval; -+ -+#if defined(AICWF_USB_SUPPORT) || defined(AICWF_SDIO_SUPPORT) -+ return 0; -+#endif -+ -+ /* the doc states that SOFT implies FPGA_B_RESET -+ * adding FPGA_B_RESET is clearer */ -+ RWNX_REG_WRITE(SOFT_RESET | FPGA_B_RESET, rwnx_plat, -+ RWNX_ADDR_SYSTEM, SYSCTRL_MISC_CNTL_ADDR); -+ msleep(100); -+ -+ regval = RWNX_REG_READ(rwnx_plat, RWNX_ADDR_SYSTEM, SYSCTRL_MISC_CNTL_ADDR); -+ -+ if (regval & SOFT_RESET) { -+ dev_err(rwnx_platform_get_dev(rwnx_plat), "reset: failed\n"); -+ return -EIO; -+ } -+ -+ RWNX_REG_WRITE(regval & ~FPGA_B_RESET, rwnx_plat, -+ RWNX_ADDR_SYSTEM, SYSCTRL_MISC_CNTL_ADDR); -+ msleep(100); -+ return 0; -+} -+ -+/** -+ * rwmx_platform_save_config() - Save hardware config before reload -+ * -+ * @rwnx_plat: Pointer to platform data -+ * -+ * Return configuration registers values. -+ */ -+static void *rwnx_term_save_config(struct rwnx_plat *rwnx_plat) -+{ -+ const u32 *reg_list; -+ u32 *reg_value, *res; -+ int i, size = 0; -+ -+ if (rwnx_plat->get_config_reg) { -+ size = rwnx_plat->get_config_reg(rwnx_plat, ®_list); -+ } -+ -+ if (size <= 0) -+ return NULL; -+ -+ res = kmalloc(sizeof(u32) * size, GFP_KERNEL); -+ if (!res) -+ return NULL; -+ -+ reg_value = res; -+ for (i = 0; i < size; i++) { -+ *reg_value++ = RWNX_REG_READ(rwnx_plat, RWNX_ADDR_SYSTEM, -+ *reg_list++); -+ } -+ -+ return res; -+} -+ -+#if 0 -+/** -+ * rwmx_platform_restore_config() - Restore hardware config after reload -+ * -+ * @rwnx_plat: Pointer to platform data -+ * @reg_value: Pointer of value to restore -+ * (obtained with rwmx_platform_save_config()) -+ * -+ * Restore configuration registers value. -+ */ -+static void rwnx_term_restore_config(struct rwnx_plat *rwnx_plat, -+ u32 *reg_value) -+{ -+ const u32 *reg_list; -+ int i, size = 0; -+ -+ if (!reg_value || !rwnx_plat->get_config_reg) -+ return; -+ -+ size = rwnx_plat->get_config_reg(rwnx_plat, ®_list); -+ -+ for (i = 0; i < size; i++) { -+ RWNX_REG_WRITE(*reg_value++, rwnx_plat, RWNX_ADDR_SYSTEM, -+ *reg_list++); -+ } -+} -+#endif -+ -+#ifndef CONFIG_RWNX_FHOST -+#if 0 -+static int rwnx_check_fw_compatibility(struct rwnx_hw *rwnx_hw) -+{ -+ struct ipc_shared_env_tag *shared = rwnx_hw->ipc_env->shared; -+ #ifdef CONFIG_RWNX_FULLMAC -+ struct wiphy *wiphy = rwnx_hw->wiphy; -+ #endif //CONFIG_RWNX_FULLMAC -+ #ifdef CONFIG_RWNX_OLD_IPC -+ int ipc_shared_version = 10; -+ #else //CONFIG_RWNX_OLD_IPC -+ int ipc_shared_version = 11; -+ #endif //CONFIG_RWNX_OLD_IPC -+ int res = 0; -+ -+ if (shared->comp_info.ipc_shared_version != ipc_shared_version) { -+ wiphy_err(wiphy, "Different versions of IPC shared version between driver and FW (%d != %d)\n ", -+ ipc_shared_version, shared->comp_info.ipc_shared_version); -+ res = -1; -+ } -+ -+ if (shared->comp_info.radarbuf_cnt != IPC_RADARBUF_CNT) { -+ wiphy_err(wiphy, "Different number of host buffers available for Radar events handling "\ -+ "between driver and FW (%d != %d)\n", IPC_RADARBUF_CNT, -+ shared->comp_info.radarbuf_cnt); -+ res = -1; -+ } -+ -+ if (shared->comp_info.unsuprxvecbuf_cnt != IPC_UNSUPRXVECBUF_CNT) { -+ wiphy_err(wiphy, "Different number of host buffers available for unsupported Rx vectors "\ -+ "handling between driver and FW (%d != %d)\n", IPC_UNSUPRXVECBUF_CNT, -+ shared->comp_info.unsuprxvecbuf_cnt); -+ res = -1; -+ } -+ -+ #ifdef CONFIG_RWNX_FULLMAC -+ if (shared->comp_info.rxdesc_cnt != IPC_RXDESC_CNT) { -+ wiphy_err(wiphy, "Different number of shared descriptors available for Data RX handling "\ -+ "between driver and FW (%d != %d)\n", IPC_RXDESC_CNT, -+ shared->comp_info.rxdesc_cnt); -+ res = -1; -+ } -+ #endif /* CONFIG_RWNX_FULLMAC */ -+ -+ if (shared->comp_info.rxbuf_cnt != IPC_RXBUF_CNT) { -+ wiphy_err(wiphy, "Different number of host buffers available for Data Rx handling "\ -+ "between driver and FW (%d != %d)\n", IPC_RXBUF_CNT, -+ shared->comp_info.rxbuf_cnt); -+ res = -1; -+ } -+ -+ if (shared->comp_info.msge2a_buf_cnt != IPC_MSGE2A_BUF_CNT) { -+ wiphy_err(wiphy, "Different number of host buffers available for Emb->App MSGs "\ -+ "sending between driver and FW (%d != %d)\n", IPC_MSGE2A_BUF_CNT, -+ shared->comp_info.msge2a_buf_cnt); -+ res = -1; -+ } -+ -+ if (shared->comp_info.dbgbuf_cnt != IPC_DBGBUF_CNT) { -+ wiphy_err(wiphy, "Different number of host buffers available for debug messages "\ -+ "sending between driver and FW (%d != %d)\n", IPC_DBGBUF_CNT, -+ shared->comp_info.dbgbuf_cnt); -+ res = -1; -+ } -+ -+ if (shared->comp_info.bk_txq != NX_TXDESC_CNT0) { -+ wiphy_err(wiphy, "Driver and FW have different sizes of BK TX queue (%d != %d)\n", -+ NX_TXDESC_CNT0, shared->comp_info.bk_txq); -+ res = -1; -+ } -+ -+ if (shared->comp_info.be_txq != NX_TXDESC_CNT1) { -+ wiphy_err(wiphy, "Driver and FW have different sizes of BE TX queue (%d != %d)\n", -+ NX_TXDESC_CNT1, shared->comp_info.be_txq); -+ res = -1; -+ } -+ -+ if (shared->comp_info.vi_txq != NX_TXDESC_CNT2) { -+ wiphy_err(wiphy, "Driver and FW have different sizes of VI TX queue (%d != %d)\n", -+ NX_TXDESC_CNT2, shared->comp_info.vi_txq); -+ res = -1; -+ } -+ -+ if (shared->comp_info.vo_txq != NX_TXDESC_CNT3) { -+ wiphy_err(wiphy, "Driver and FW have different sizes of VO TX queue (%d != %d)\n", -+ NX_TXDESC_CNT3, shared->comp_info.vo_txq); -+ res = -1; -+ } -+ -+ #if NX_TXQ_CNT == 5 -+ if (shared->comp_info.bcn_txq != NX_TXDESC_CNT4) { -+ wiphy_err(wiphy, "Driver and FW have different sizes of BCN TX queue (%d != %d)\n", -+ NX_TXDESC_CNT4, shared->comp_info.bcn_txq); -+ res = -1; -+ } -+ #else -+ if (shared->comp_info.bcn_txq > 0) { -+ wiphy_err(wiphy, "BCMC enabled in firmware but disabled in driver\n"); -+ res = -1; -+ } -+ #endif /* NX_TXQ_CNT == 5 */ -+ -+ if (shared->comp_info.ipc_shared_size != sizeof(ipc_shared_env)) { -+ wiphy_err(wiphy, "Different sizes of IPC shared between driver and FW (%zd != %d)\n", -+ sizeof(ipc_shared_env), shared->comp_info.ipc_shared_size); -+ res = -1; -+ } -+ -+ if (shared->comp_info.msg_api != MSG_API_VER) { -+ wiphy_warn(wiphy, "WARNING: Different supported message API versions between "\ -+ "driver and FW (%d != %d)\n", MSG_API_VER, shared->comp_info.msg_api); -+ } -+ -+ return res; -+} -+#endif -+#endif /* !CONFIG_RWNX_FHOST */ -+ -+ -+void get_userconfig_txpwr_lvl_in_fdrv(txpwr_lvl_conf_t *txpwr_lvl) -+{ -+ txpwr_lvl->enable = userconfig_info.txpwr_lvl.enable; -+ txpwr_lvl->dsss = userconfig_info.txpwr_lvl.dsss; -+ txpwr_lvl->ofdmlowrate_2g4 = userconfig_info.txpwr_lvl.ofdmlowrate_2g4; -+ txpwr_lvl->ofdm64qam_2g4 = userconfig_info.txpwr_lvl.ofdm64qam_2g4; -+ txpwr_lvl->ofdm256qam_2g4 = userconfig_info.txpwr_lvl.ofdm256qam_2g4; -+ txpwr_lvl->ofdm1024qam_2g4 = userconfig_info.txpwr_lvl.ofdm1024qam_2g4; -+ txpwr_lvl->ofdmlowrate_5g = userconfig_info.txpwr_lvl.ofdmlowrate_5g; -+ txpwr_lvl->ofdm64qam_5g = userconfig_info.txpwr_lvl.ofdm64qam_5g; -+ txpwr_lvl->ofdm256qam_5g = userconfig_info.txpwr_lvl.ofdm256qam_5g; -+ txpwr_lvl->ofdm1024qam_5g = userconfig_info.txpwr_lvl.ofdm1024qam_5g; -+ -+ AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl->enable); -+ AICWFDBG(LOGINFO, "%s:dsss:%d\r\n", __func__, txpwr_lvl->dsss); -+ AICWFDBG(LOGINFO, "%s:ofdmlowrate_2g4:%d\r\n", __func__, txpwr_lvl->ofdmlowrate_2g4); -+ AICWFDBG(LOGINFO, "%s:ofdm64qam_2g4:%d\r\n", __func__, txpwr_lvl->ofdm64qam_2g4); -+ AICWFDBG(LOGINFO, "%s:ofdm256qam_2g4:%d\r\n", __func__, txpwr_lvl->ofdm256qam_2g4); -+ AICWFDBG(LOGINFO, "%s:ofdm1024qam_2g4:%d\r\n", __func__, txpwr_lvl->ofdm1024qam_2g4); -+ AICWFDBG(LOGINFO, "%s:ofdmlowrate_5g:%d\r\n", __func__, txpwr_lvl->ofdmlowrate_5g); -+ AICWFDBG(LOGINFO, "%s:ofdm64qam_5g:%d\r\n", __func__, txpwr_lvl->ofdm64qam_5g); -+ AICWFDBG(LOGINFO, "%s:ofdm256qam_5g:%d\r\n", __func__, txpwr_lvl->ofdm256qam_5g); -+ AICWFDBG(LOGINFO, "%s:ofdm1024qam_5g:%d\r\n", __func__, txpwr_lvl->ofdm1024qam_5g); -+} -+ -+void get_userconfig_txpwr_lvl_v2_in_fdrv(txpwr_lvl_conf_v2_t *txpwr_lvl_v2) -+{ -+ *txpwr_lvl_v2 = userconfig_info.txpwr_lvl_v2; -+ -+ AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_v2->enable); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_1m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_2m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_5m5_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_11m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_6m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_9m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_12m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_18m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_24m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_36m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_48m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_54m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[11]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs0_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs1_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs2_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs3_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs4_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs5_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs6_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs7_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs8_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs9_2g4:%d\r\n",__func__, txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs0_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs1_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs2_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs3_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs4_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs5_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs6_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs7_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs8_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs9_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs10_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[11]); -+} -+ -+void get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_conf_v3_t *txpwr_lvl_v3) -+{ -+ *txpwr_lvl_v3 = userconfig_info.txpwr_lvl_v3; -+ -+ AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_v3->enable); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_1m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_2m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_5m5_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_11m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_6m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_9m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_12m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_18m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_24m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_36m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_48m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_54m_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[11]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs0_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs1_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs2_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs3_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs4_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs5_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs6_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs7_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs8_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs9_2g4:%d\r\n",__func__, txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs0_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs1_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs2_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs3_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs4_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs5_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs6_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs7_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs8_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs9_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs10_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_2g4:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_2g4[11]); -+ -+ AICWFDBG(LOGINFO, "%s:lvl_11a_1m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_2m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_5m5_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_11m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_6m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_9m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_12m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_18m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_24m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_36m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_48m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11a_54m_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11a_5g[11]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs0_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs1_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs2_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs3_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs4_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs5_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs6_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs7_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs8_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs9_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11n_11ac_5g[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs0_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs1_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs2_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs3_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs4_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs5_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[5]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs6_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[6]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs7_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[7]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs8_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[8]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs9_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[9]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs10_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[10]); -+ AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[11]); -+} -+ -+void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj) -+{ -+ *txpwr_lvl_adj = userconfig_info.txpwr_lvl_adj; -+ -+ AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_adj->enable); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_1_4:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_2g4[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_5_9:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_2g4[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_10_13:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_2g4[2]); -+ -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_42:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[0]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_58:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[1]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_106:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[2]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_122:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[3]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_138:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[4]); -+ AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_155:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[5]); -+} -+ -+/** -+ * rwnx_plat_userconfig_load ---Load aic_userconfig.txt -+ *@filename name of config -+*/ -+static int rwnx_plat_userconfig_load(struct rwnx_hw *rwnx_hw) { -+ -+ if(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8801){ -+ -+ rwnx_plat_userconfig_upload_android(rwnx_hw, aic_fw_path, FW_USERCONFIG_NAME); -+ }else if(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC){ -+ rwnx_plat_userconfig_load_8800dc(rwnx_hw); -+ }else if(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW){ -+ rwnx_plat_userconfig_load_8800dw(rwnx_hw); -+ }else if(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800D80){ -+ rwnx_plat_userconfig_load_8800d80(rwnx_hw); -+ } -+ return 0; -+} -+ -+void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss) -+{ -+ txpwr_loss->loss_enable = userconfig_info.txpwr_loss.loss_enable; -+ txpwr_loss->loss_value = userconfig_info.txpwr_loss.loss_value; -+ -+ AICWFDBG(LOGINFO, "%s:loss_enable:%d\r\n", __func__, txpwr_loss->loss_enable); -+ AICWFDBG(LOGINFO, "%s:loss_value:%d\r\n", __func__, txpwr_loss->loss_value); -+} -+ -+/** -+ * rwnx_platform_on() - Start the platform -+ * -+ * @rwnx_hw: Main driver data -+ * @config: Config to restore (NULL if nothing to restore) -+ * -+ * It starts the platform : -+ * - load fw and ucodes -+ * - initialize IPC -+ * - boot the fw -+ * - enable link communication/IRQ -+ * -+ * Called by 802.11 part -+ */ -+int rwnx_platform_on(struct rwnx_hw *rwnx_hw, void *config) -+{ -+ int ret; -+ struct rwnx_plat *rwnx_plat = rwnx_hw->plat; -+ (void)ret; -+ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ if (rwnx_plat->enabled) -+ return 0; -+ -+ #ifndef CONFIG_ROM_PATCH_EN -+ #ifdef CONFIG_DOWNLOAD_FW -+ ret = rwnx_plat_fmac_load(rwnx_hw, (char*)config); -+ if (ret) -+ return ret; -+ #endif /* !CONFIG_ROM_PATCH_EN */ -+ #endif -+ -+#if 0 -+ ret = rwnx_plat_patch_load(rwnx_hw); -+ if (ret) { -+ return ret; -+ } -+#endif -+ -+ -+ rwnx_plat_userconfig_load(rwnx_hw); -+ -+ //rwnx_plat->enabled = true; -+ -+ return 0; -+} -+ -+/** -+ * rwnx_platform_off() - Stop the platform -+ * -+ * @rwnx_hw: Main driver data -+ * @config: Updated with pointer to config, to be able to restore it with -+ * rwnx_platform_on(). It's up to the caller to free the config. Set to NULL -+ * if configuration is not needed. -+ * -+ * Called by 802.11 part -+ */ -+void rwnx_platform_off(struct rwnx_hw *rwnx_hw, void **config) -+{ -+#if defined(AICWF_USB_SUPPORT) || defined(AICWF_SDIO_SUPPORT) -+ tasklet_kill(&rwnx_hw->task); -+ rwnx_hw->plat->enabled = false; -+ return ; -+#endif -+ -+ if (!rwnx_hw->plat->enabled) { -+ if (config) -+ *config = NULL; -+ return; -+ } -+ -+ if (config) -+ *config = rwnx_term_save_config(rwnx_hw->plat); -+ -+ rwnx_hw->plat->disable(rwnx_hw); -+ -+ tasklet_kill(&rwnx_hw->task); -+ rwnx_platform_reset(rwnx_hw->plat); -+ -+ rwnx_hw->plat->enabled = false; -+} -+ -+/** -+ * rwnx_platform_init() - Initialize the platform -+ * -+ * @rwnx_plat: platform data (already updated by platform driver) -+ * @platform_data: Pointer to store the main driver data pointer (aka rwnx_hw) -+ * That will be set as driver data for the platform driver -+ * Return: 0 on success, < 0 otherwise -+ * -+ * Called by the platform driver after it has been probed -+ */ -+int rwnx_platform_init(struct rwnx_plat *rwnx_plat, void **platform_data) -+{ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+ rwnx_plat->enabled = false; -+ g_rwnx_plat = rwnx_plat; -+ -+#if defined CONFIG_RWNX_FULLMAC -+ return rwnx_cfg80211_init(rwnx_plat, platform_data); -+#elif defined CONFIG_RWNX_FHOST -+ return rwnx_fhost_init(rwnx_plat, platform_data); -+#endif -+} -+ -+/** -+ * rwnx_platform_deinit() - Deinitialize the platform -+ * -+ * @rwnx_hw: main driver data -+ * -+ * Called by the platform driver after it is removed -+ */ -+void rwnx_platform_deinit(struct rwnx_hw *rwnx_hw) -+{ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+ -+#if defined CONFIG_RWNX_FULLMAC -+ rwnx_cfg80211_deinit(rwnx_hw); -+#elif defined CONFIG_RWNX_FHOST -+ rwnx_fhost_deinit(rwnx_hw); -+#endif -+} -+ -+/** -+ * rwnx_platform_register_drv() - Register all possible platform drivers -+ */ -+int rwnx_platform_register_drv(void) -+{ -+ return rwnx_pci_register_drv(); -+} -+ -+ -+/** -+ * rwnx_platform_unregister_drv() - Unegister all platform drivers -+ */ -+void rwnx_platform_unregister_drv(void) -+{ -+ return rwnx_pci_unregister_drv(); -+} -+ -+struct device *rwnx_platform_get_dev(struct rwnx_plat *rwnx_plat) -+{ -+#ifdef AICWF_SDIO_SUPPORT -+ return rwnx_plat->sdiodev->dev; -+#endif -+#ifdef AICWF_USB_SUPPORT -+ return rwnx_plat->usbdev->dev; -+#endif -+ return &(rwnx_plat->pci_dev->dev); -+} -+ -+ -+#ifndef CONFIG_RWNX_SDM -+MODULE_FIRMWARE(RWNX_AGC_FW_NAME); -+MODULE_FIRMWARE(RWNX_FCU_FW_NAME); -+MODULE_FIRMWARE(RWNX_LDPC_RAM_NAME); -+#endif -+MODULE_FIRMWARE(RWNX_MAC_FW_NAME); -+#ifndef CONFIG_RWNX_TL4 -+MODULE_FIRMWARE(RWNX_MAC_FW_NAME2); -+#endif -+ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,136 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_platorm.h -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _RWNX_PLATFORM_H_ -+#define _RWNX_PLATFORM_H_ -+ -+#include -+#include "lmac_msg.h" -+ -+#define RWNX_CONFIG_FW_NAME "rwnx_settings.ini" -+#define RWNX_PHY_CONFIG_TRD_NAME "rwnx_trident.ini" -+#define RWNX_PHY_CONFIG_KARST_NAME "rwnx_karst.ini" -+#define RWNX_AGC_FW_NAME "agcram.bin" -+#define RWNX_LDPC_RAM_NAME "ldpcram.bin" -+#ifdef CONFIG_RWNX_FULLMAC -+#define RWNX_MAC_FW_BASE_NAME "fmacfw" -+#elif defined CONFIG_RWNX_FHOST -+#define RWNX_MAC_FW_BASE_NAME "fhostfw" -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+#ifdef CONFIG_RWNX_TL4 -+#define RWNX_MAC_FW_NAME RWNX_MAC_FW_BASE_NAME".hex" -+#else -+#define RWNX_MAC_FW_NAME RWNX_MAC_FW_BASE_NAME".ihex" -+#define RWNX_MAC_FW_NAME2 RWNX_MAC_FW_BASE_NAME".bin" -+#endif -+ -+#define RWNX_FCU_FW_NAME "fcuram.bin" -+#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB)) -+#define FW_DPDRESULT_NAME_8800DC "aic_dpdresult_lite_8800dc.bin" -+#endif -+ -+/** -+ * Type of memory to access (cf rwnx_plat.get_address) -+ * -+ * @RWNX_ADDR_CPU To access memory of the embedded CPU -+ * @RWNX_ADDR_SYSTEM To access memory/registers of one subsystem of the -+ * embedded system -+ * -+ */ -+enum rwnx_platform_addr { -+ RWNX_ADDR_CPU, -+ RWNX_ADDR_SYSTEM, -+ RWNX_ADDR_MAX, -+}; -+ -+struct rwnx_hw; -+ -+/** -+ * struct rwnx_plat - Operation pointers for RWNX PCI platform -+ * -+ * @pci_dev: pointer to pci dev -+ * @enabled: Set if embedded platform has been enabled (i.e. fw loaded and -+ * ipc started) -+ * @enable: Configure communication with the fw (i.e. configure the transfers -+ * enable and register interrupt) -+ * @disable: Stop communication with the fw -+ * @deinit: Free all ressources allocated for the embedded platform -+ * @get_address: Return the virtual address to access the requested address on -+ * the platform. -+ * @ack_irq: Acknowledge the irq at link level. -+ * @get_config_reg: Return the list (size + pointer) of registers to restore in -+ * order to reload the platform while keeping the current configuration. -+ * -+ * @priv Private data for the link driver -+ */ -+struct rwnx_plat { -+ struct pci_dev *pci_dev; -+ -+#ifdef AICWF_SDIO_SUPPORT -+ struct aic_sdio_dev *sdiodev; -+#endif -+ -+#ifdef AICWF_USB_SUPPORT -+ struct aic_usb_dev *usbdev; -+#endif -+ bool enabled; -+ -+ int (*enable)(struct rwnx_hw *rwnx_hw); -+ int (*disable)(struct rwnx_hw *rwnx_hw); -+ void (*deinit)(struct rwnx_plat *rwnx_plat); -+ u8* (*get_address)(struct rwnx_plat *rwnx_plat, int addr_name, -+ unsigned int offset); -+ void (*ack_irq)(struct rwnx_plat *rwnx_plat); -+ int (*get_config_reg)(struct rwnx_plat *rwnx_plat, const u32 **list); -+ -+ u8 priv[0] __aligned(sizeof(void *)); -+}; -+ -+#define RWNX_ADDR(plat, base, offset) \ -+ plat->get_address(plat, base, offset) -+ -+#define RWNX_REG_READ(plat, base, offset) \ -+ readl(plat->get_address(plat, base, offset)) -+ -+#define RWNX_REG_WRITE(val, plat, base, offset) \ -+ writel(val, plat->get_address(plat, base, offset)) -+ -+extern struct rwnx_plat *g_rwnx_plat; -+ -+int rwnx_platform_init(struct rwnx_plat *rwnx_plat, void **platform_data); -+void rwnx_platform_deinit(struct rwnx_hw *rwnx_hw); -+ -+int rwnx_platform_on(struct rwnx_hw *rwnx_hw, void *config); -+void rwnx_platform_off(struct rwnx_hw *rwnx_hw, void **config); -+ -+int rwnx_platform_register_drv(void); -+void rwnx_platform_unregister_drv(void); -+ -+void get_userconfig_txpwr_idx(txpwr_idx_conf_t *txpwr_idx); -+void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst); -+void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap); -+ -+void get_userconfig_txpwr_lvl_in_fdrv(txpwr_lvl_conf_t *txpwr_lvl); -+void get_userconfig_txpwr_lvl_v2_in_fdrv(txpwr_lvl_conf_v2_t *txpwr_lvl_v2); -+void get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_conf_v3_t *txpwr_lvl_v3); -+void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj); -+ -+void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst); -+void get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x_conf_t *txpwr_ofst2x); -+void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss); -+extern struct device *rwnx_platform_get_dev(struct rwnx_plat *rwnx_plat); -+ -+static inline unsigned int rwnx_platform_get_irq(struct rwnx_plat *rwnx_plat) -+{ -+ return rwnx_plat->pci_dev->irq; -+} -+ -+#endif /* _RWNX_PLATFORM_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_prof.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_prof.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_prof.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_prof.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,133 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_prof.h -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _RWNX_PROF_H_ -+#define _RWNX_PROF_H_ -+ -+#include "reg_access.h" -+#include "rwnx_platform.h" -+ -+static inline void rwnx_prof_set(struct rwnx_hw *rwnx_hw, int val) -+{ -+ struct rwnx_plat *rwnx_plat = rwnx_hw->plat; -+ RWNX_REG_WRITE(val, rwnx_plat, RWNX_ADDR_SYSTEM, NXMAC_SW_SET_PROFILING_ADDR); -+} -+ -+static inline void rwnx_prof_clear(struct rwnx_hw *rwnx_hw, int val) -+{ -+ struct rwnx_plat *rwnx_plat = rwnx_hw->plat; -+ RWNX_REG_WRITE(val, rwnx_plat, RWNX_ADDR_SYSTEM, NXMAC_SW_CLEAR_PROFILING_ADDR); -+} -+ -+#if 0 -+/* Defines for SW Profiling registers values */ -+enum { -+ TX_IPC_IRQ, -+ TX_IPC_EVT, -+ TX_PREP_EVT, -+ TX_DMA_IRQ, -+ TX_MAC_IRQ, -+ TX_PAYL_HDL, -+ TX_CFM_EVT, -+ TX_IPC_CFM, -+ RX_MAC_IRQ, // 8 -+ RX_TRIGGER_EVT, -+ RX_DMA_IRQ, -+ RX_DMA_EVT, -+ RX_IPC_IND, -+ RX_MPDU_XFER, -+ DBG_PROF_MAX -+}; -+#endif -+ -+enum { -+ SW_PROF_HOSTBUF_IDX = 12, -+ /****** IPC IRQs related signals ******/ -+ /* E2A direction */ -+ SW_PROF_IRQ_E2A_RXDESC = 16, // to make sure we let 16 bits available for LMAC FW -+ SW_PROF_IRQ_E2A_TXCFM, -+ SW_PROF_IRQ_E2A_DBG, -+ SW_PROF_IRQ_E2A_MSG, -+ SW_PROF_IPC_MSGPUSH, -+ SW_PROF_MSGALLOC, -+ SW_PROF_MSGIND, -+ SW_PROF_DBGIND, -+ -+ /* A2E direction */ -+ SW_PROF_IRQ_A2E_TXCFM_BACK, -+ -+ /****** Driver functions related signals ******/ -+ SW_PROF_WAIT_QUEUE_STOP, -+ SW_PROF_WAIT_QUEUE_WAKEUP, -+ SW_PROF_RWNXDATAIND, -+ SW_PROF_RWNX_IPC_IRQ_HDLR, -+ SW_PROF_RWNX_IPC_THR_IRQ_HDLR, -+ SW_PROF_IEEE80211RX, -+ SW_PROF_RWNX_PATTERN, -+ SW_PROF_MAX -+}; -+ -+// [LT]For debug purpose only -+#if (0) -+#define SW_PROF_CHAN_CTXT_CFM_HDL_BIT (21) -+#define SW_PROF_CHAN_CTXT_CFM_BIT (22) -+#define SW_PROF_CHAN_CTXT_CFM_SWDONE_BIT (23) -+#define SW_PROF_CHAN_CTXT_PUSH_BIT (24) -+#define SW_PROF_CHAN_CTXT_QUEUE_BIT (25) -+#define SW_PROF_CHAN_CTXT_TX_BIT (26) -+#define SW_PROF_CHAN_CTXT_TX_PAUSE_BIT (27) -+#define SW_PROF_CHAN_CTXT_PSWTCH_BIT (28) -+#define SW_PROF_CHAN_CTXT_SWTCH_BIT (29) -+ -+// TO DO: update this -+ -+#define REG_SW_SET_PROFILING_CHAN(env, bit) \ -+ rwnx_prof_set((struct rwnx_hw *)env, BIT(bit)) -+ -+#define REG_SW_CLEAR_PROFILING_CHAN(env, bit) \ -+ rwnx_prof_clear((struct rwnx_hw *)env, BIT(bit)) -+ -+#else -+#define SW_PROF_CHAN_CTXT_CFM_HDL_BIT (0) -+#define SW_PROF_CHAN_CTXT_CFM_BIT (0) -+#define SW_PROF_CHAN_CTXT_CFM_SWDONE_BIT (0) -+#define SW_PROF_CHAN_CTXT_PUSH_BIT (0) -+#define SW_PROF_CHAN_CTXT_QUEUE_BIT (0) -+#define SW_PROF_CHAN_CTXT_TX_BIT (0) -+#define SW_PROF_CHAN_CTXT_TX_PAUSE_BIT (0) -+#define SW_PROF_CHAN_CTXT_PSWTCH_BIT (0) -+#define SW_PROF_CHAN_CTXT_SWTCH_BIT (0) -+ -+#define REG_SW_SET_PROFILING_CHAN(env, bit) do {} while (0) -+#define REG_SW_CLEAR_PROFILING_CHAN(env, bit) do {} while (0) -+#endif -+ -+#ifdef CONFIG_RWNX_SW_PROFILING -+/* Macros for SW PRofiling registers access */ -+#define REG_SW_SET_PROFILING(env, bit) \ -+ rwnx_prof_set((struct rwnx_hw *)env, BIT(bit)) -+ -+#define REG_SW_SET_HOSTBUF_IDX_PROFILING(env, val) \ -+ rwnx_prof_set((struct rwnx_hw *)env, val << (SW_PROF_HOSTBUF_IDX)) -+ -+#define REG_SW_CLEAR_PROFILING(env, bit) \ -+ rwnx_prof_clear((struct rwnx_hw *)env, BIT(bit)) -+ -+#define REG_SW_CLEAR_HOSTBUF_IDX_PROFILING(env) \ -+ rwnx_prof_clear((struct rwnx_hw *)env, 0x0F << (SW_PROF_HOSTBUF_IDX)) -+ -+#else -+#define REG_SW_SET_PROFILING(env, value) do {} while (0) -+#define REG_SW_CLEAR_PROFILING(env, value) do {} while (0) -+#define REG_SW_SET_HOSTBUF_IDX_PROFILING(env, val) do {} while (0) -+#define REG_SW_CLEAR_HOSTBUF_IDX_PROFILING(env) do {} while (0) -+#endif -+ -+#endif /* _RWNX_PROF_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,1644 @@ -+/** -+****************************************************************************** -+ * -+ * @file rwnx_radar.c -+ * -+ * @brief Functions to handle radar detection -+ * Radar detection is copied (and adapted) from ath driver source code. -+ * -+ * Copyright (c) 2012 Neratec Solutions AG -+ * Copyright (C) RivieraWaves 2015-2019 -+ * -+ ****************************************************************************** -+ */ -+#include -+#include -+#include -+#include -+ -+#include "rwnx_radar.h" -+#include "rwnx_defs.h" -+#include "rwnx_msg_tx.h" -+#include "rwnx_events.h" -+#include "rwnx_compat.h" -+ -+/* -+ * tolerated deviation of radar time stamp in usecs on both sides -+ * TODO: this might need to be HW-dependent -+ */ -+#define PRI_TOLERANCE 16 -+ -+/** -+ * struct radar_types - contains array of patterns defined for one DFS domain -+ * @domain: DFS regulatory domain -+ * @num_radar_types: number of radar types to follow -+ * @radar_types: radar types array -+ */ -+struct radar_types { -+ enum nl80211_dfs_regions region; -+ u32 num_radar_types; -+ const struct radar_detector_specs *spec_riu; -+ const struct radar_detector_specs *spec_fcu; -+}; -+ -+/** -+ * Type of radar waveform: -+ * RADAR_WAVEFORM_SHORT : waveform defined by -+ * - pulse width -+ * - pulse interval in a burst (pri) -+ * - number of pulses in a burst (ppb) -+ * -+ * RADAR_WAVEFORM_WEATHER : -+ * same than SHORT except that ppb is dependent of pri -+ * -+ * RADAR_WAVEFORM_INTERLEAVED : -+ * same than SHORT except there are several value of pri (interleaved) -+ * -+ * RADAR_WAVEFORM_LONG : -+ * -+ */ -+enum radar_waveform_type { -+ RADAR_WAVEFORM_SHORT, -+ RADAR_WAVEFORM_WEATHER, -+ RADAR_WAVEFORM_INTERLEAVED, -+ RADAR_WAVEFORM_LONG -+}; -+ -+/** -+ * struct radar_detector_specs - detector specs for a radar pattern type -+ * @type_id: pattern type, as defined by regulatory -+ * @width_min: minimum radar pulse width in [us] -+ * @width_max: maximum radar pulse width in [us] -+ * @pri_min: minimum pulse repetition interval in [us] (including tolerance) -+ * @pri_max: minimum pri in [us] (including tolerance) -+ * @num_pri: maximum number of different pri for this type -+ * @ppb: pulses per bursts for this type -+ * @ppb_thresh: number of pulses required to trigger detection -+ * @max_pri_tolerance: pulse time stamp tolerance on both sides [us] -+ * @type: Type of radar waveform -+ */ -+struct radar_detector_specs { -+ u8 type_id; -+ u8 width_min; -+ u8 width_max; -+ u16 pri_min; -+ u16 pri_max; -+ u8 num_pri; -+ u8 ppb; -+ u8 ppb_thresh; -+ u8 max_pri_tolerance; -+ enum radar_waveform_type type; -+}; -+ -+ -+/* percentage on ppb threshold to trigger detection */ -+#define MIN_PPB_THRESH 50 -+#define PPB_THRESH(PPB) ((PPB * MIN_PPB_THRESH + 50) / 100) -+#define PRF2PRI(PRF) ((1000000 + PRF / 2) / PRF) -+ -+/* width tolerance */ -+#define WIDTH_TOLERANCE 2 -+#define WIDTH_LOWER(X) (X) -+#define WIDTH_UPPER(X) (X) -+ -+#define ETSI_PATTERN_SHORT(ID, WMIN, WMAX, PMIN, PMAX, PPB) \ -+ { \ -+ ID, WIDTH_LOWER(WMIN), WIDTH_UPPER(WMAX), \ -+ (PRF2PRI(PMAX) - PRI_TOLERANCE), \ -+ (PRF2PRI(PMIN) + PRI_TOLERANCE), 1, PPB, \ -+ PPB_THRESH(PPB), PRI_TOLERANCE, RADAR_WAVEFORM_SHORT \ -+ } -+ -+#define ETSI_PATTERN_INTERLEAVED(ID, WMIN, WMAX, PMIN, PMAX, PRFMIN, PRFMAX, PPB) \ -+ { \ -+ ID, WIDTH_LOWER(WMIN), WIDTH_UPPER(WMAX), \ -+ (PRF2PRI(PMAX) * PRFMIN- PRI_TOLERANCE), \ -+ (PRF2PRI(PMIN) * PRFMAX + PRI_TOLERANCE), \ -+ PRFMAX, PPB * PRFMAX, \ -+ PPB_THRESH(PPB), PRI_TOLERANCE, RADAR_WAVEFORM_INTERLEAVED \ -+ } -+ -+/* radar types as defined by ETSI EN-301-893 v1.7.1 */ -+static const struct radar_detector_specs etsi_radar_ref_types_v17_riu[] = { -+ ETSI_PATTERN_SHORT(0, 0, 8, 700, 700, 18), -+ ETSI_PATTERN_SHORT(1, 0, 10, 200, 1000, 10), -+ ETSI_PATTERN_SHORT(2, 0, 22, 200, 1600, 15), -+ ETSI_PATTERN_SHORT(3, 0, 22, 2300, 4000, 25), -+ ETSI_PATTERN_SHORT(4, 20, 38, 2000, 4000, 20), -+ ETSI_PATTERN_INTERLEAVED(5, 0, 8, 300, 400, 2, 3, 10), -+ ETSI_PATTERN_INTERLEAVED(6, 0, 8, 400, 1200, 2, 3, 15), -+}; -+ -+static const struct radar_detector_specs etsi_radar_ref_types_v17_fcu[] = { -+ ETSI_PATTERN_SHORT(0, 0, 8, 700, 700, 18), -+ ETSI_PATTERN_SHORT(1, 0, 8, 200, 1000, 10), -+ ETSI_PATTERN_SHORT(2, 0, 16, 200, 1600, 15), -+ ETSI_PATTERN_SHORT(3, 0, 16, 2300, 4000, 25), -+ ETSI_PATTERN_SHORT(4, 20, 34, 2000, 4000, 20), -+ ETSI_PATTERN_INTERLEAVED(5, 0, 8, 300, 400, 2, 3, 10), -+ ETSI_PATTERN_INTERLEAVED(6, 0, 8, 400, 1200, 2, 3, 15), -+}; -+ -+static const struct radar_types etsi_radar_types_v17 = { -+ .region = NL80211_DFS_ETSI, -+ .num_radar_types = ARRAY_SIZE(etsi_radar_ref_types_v17_riu), -+ .spec_riu = etsi_radar_ref_types_v17_riu, -+ .spec_fcu = etsi_radar_ref_types_v17_fcu, -+}; -+ -+#define FCC_PATTERN(ID, WMIN, WMAX, PMIN, PMAX, PRF, PPB, TYPE) \ -+ { \ -+ ID, WIDTH_LOWER(WMIN), WIDTH_UPPER(WMAX), \ -+ PMIN - PRI_TOLERANCE, \ -+ PMAX * PRF + PRI_TOLERANCE, PRF, PPB * PRF, \ -+ PPB_THRESH(PPB), PRI_TOLERANCE, TYPE \ -+ } -+ -+static const struct radar_detector_specs fcc_radar_ref_types_riu[] = { -+ FCC_PATTERN(0, 0, 8, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT), -+ FCC_PATTERN(1, 0, 8, 518, 3066, 1, 102, RADAR_WAVEFORM_WEATHER), -+ FCC_PATTERN(2, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT), -+ FCC_PATTERN(3, 6, 20, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT), -+ FCC_PATTERN(4, 10, 28, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT), -+ FCC_PATTERN(5, 50, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG), -+ FCC_PATTERN(6, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT), -+}; -+ -+static const struct radar_detector_specs fcc_radar_ref_types_fcu[] = { -+ FCC_PATTERN(0, 0, 8, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT), -+ FCC_PATTERN(1, 0, 8, 518, 3066, 1, 102, RADAR_WAVEFORM_WEATHER), -+ FCC_PATTERN(2, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT), -+ FCC_PATTERN(3, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT), -+ FCC_PATTERN(4, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT), -+ FCC_PATTERN(5, 50, 104, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG), -+ FCC_PATTERN(6, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT), -+}; -+ -+static const struct radar_types fcc_radar_types = { -+ .region = NL80211_DFS_FCC, -+ .num_radar_types = ARRAY_SIZE(fcc_radar_ref_types_riu), -+ .spec_riu = fcc_radar_ref_types_riu, -+ .spec_fcu = fcc_radar_ref_types_fcu, -+}; -+ -+#define JP_PATTERN FCC_PATTERN -+static const struct radar_detector_specs jp_radar_ref_types_riu[] = { -+ JP_PATTERN(0, 0, 8, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(1, 2, 8, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(2, 0, 8, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(3, 0, 8, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(4, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(5, 6, 20, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(6, 10, 28, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(7, 50, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG), -+ JP_PATTERN(8, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT), -+}; -+ -+static const struct radar_detector_specs jp_radar_ref_types_fcu[] = { -+ JP_PATTERN(0, 0, 8, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(1, 2, 6, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(2, 0, 8, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(3, 2, 2, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(4, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(5, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(6, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT), -+ JP_PATTERN(7, 50, 104, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG), -+ JP_PATTERN(8, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT), -+}; -+ -+static const struct radar_types jp_radar_types = { -+ .region = NL80211_DFS_JP, -+ .num_radar_types = ARRAY_SIZE(jp_radar_ref_types_riu), -+ .spec_riu = jp_radar_ref_types_riu, -+ .spec_fcu = jp_radar_ref_types_fcu, -+}; -+ -+static const struct radar_types *dfs_domains[] = { -+ &etsi_radar_types_v17, -+ &fcc_radar_types, -+ &jp_radar_types, -+}; -+ -+ -+/** -+ * struct pri_sequence - sequence of pulses matching one PRI -+ * @head: list_head -+ * @pri: pulse repetition interval (PRI) in usecs -+ * @dur: duration of sequence in usecs -+ * @count: number of pulses in this sequence -+ * @count_falses: number of not matching pulses in this sequence -+ * @first_ts: time stamp of first pulse in usecs -+ * @last_ts: time stamp of last pulse in usecs -+ * @deadline_ts: deadline when this sequence becomes invalid (first_ts + dur) -+ * @ppb_thresh: Number of pulses to validate detection -+ * (need for weather radar whose value depends of pri) -+ */ -+struct pri_sequence { -+ struct list_head head; -+ u32 pri; -+ u32 dur; -+ u32 count; -+ u32 count_falses; -+ u64 first_ts; -+ u64 last_ts; -+ u64 deadline_ts; -+ u8 ppb_thresh; -+}; -+ -+ -+/** -+ * struct pulse_elem - elements in pulse queue -+ * @ts: time stamp in usecs -+ */ -+struct pulse_elem { -+ struct list_head head; -+ u64 ts; -+}; -+ -+/** -+ * struct pri_detector - PRI detector element for a dedicated radar type -+ * @head: -+ * @rs: detector specs for this detector element -+ * @last_ts: last pulse time stamp considered for this element in usecs -+ * @sequences: list_head holding potential pulse sequences -+ * @pulses: list connecting pulse_elem objects -+ * @count: number of pulses in queue -+ * @max_count: maximum number of pulses to be queued -+ * @window_size: window size back from newest pulse time stamp in usecs -+ * @freq: -+ */ -+struct pri_detector { -+ struct list_head head; -+ const struct radar_detector_specs *rs; -+ u64 last_ts; -+ struct list_head sequences; -+ struct list_head pulses; -+ u32 count; -+ u32 max_count; -+ u32 window_size; -+ struct pri_detector_ops *ops; -+ u16 freq; -+}; -+ -+/** -+ * struct pri_detector_ops - PRI detector ops (dependent of waveform type) -+ * @init : Initialize pri_detector structure -+ * @add_pulse : Add a pulse to the pri-detector -+ * @reset_on_pri_overflow : Should the pri_detector be resetted when pri overflow -+ */ -+struct pri_detector_ops { -+ void (*init)(struct pri_detector *pde); -+ struct pri_sequence * (*add_pulse)(struct pri_detector *pde, u16 len, u64 ts, u16 pri); -+ int reset_on_pri_overflow; -+}; -+ -+ -+/****************************************************************************** -+ * PRI (pulse repetition interval) sequence detection -+ *****************************************************************************/ -+/** -+ * Singleton Pulse and Sequence Pools -+ * -+ * Instances of pri_sequence and pulse_elem are kept in singleton pools to -+ * reduce the number of dynamic allocations. They are shared between all -+ * instances and grow up to the peak number of simultaneously used objects. -+ * -+ * Memory is freed after all references to the pools are released. -+ */ -+static u32 singleton_pool_references; -+static LIST_HEAD(pulse_pool); -+static LIST_HEAD(pseq_pool); -+static DEFINE_SPINLOCK(pool_lock); -+ -+static void pool_register_ref(void) -+{ -+ spin_lock_bh(&pool_lock); -+ singleton_pool_references++; -+ spin_unlock_bh(&pool_lock); -+} -+ -+static void pool_deregister_ref(void) -+{ -+ spin_lock_bh(&pool_lock); -+ singleton_pool_references--; -+ if (singleton_pool_references == 0) { -+ /* free singleton pools with no references left */ -+ struct pri_sequence *ps, *ps0; -+ struct pulse_elem *p, *p0; -+ -+ list_for_each_entry_safe(p, p0, &pulse_pool, head) { -+ list_del(&p->head); -+ kfree(p); -+ } -+ list_for_each_entry_safe(ps, ps0, &pseq_pool, head) { -+ list_del(&ps->head); -+ kfree(ps); -+ } -+ } -+ spin_unlock_bh(&pool_lock); -+} -+ -+static void pool_put_pulse_elem(struct pulse_elem *pe) -+{ -+ spin_lock_bh(&pool_lock); -+ list_add(&pe->head, &pulse_pool); -+ spin_unlock_bh(&pool_lock); -+} -+ -+static void pool_put_pseq_elem(struct pri_sequence *pse) -+{ -+ spin_lock_bh(&pool_lock); -+ list_add(&pse->head, &pseq_pool); -+ spin_unlock_bh(&pool_lock); -+} -+ -+static struct pri_sequence *pool_get_pseq_elem(void) -+{ -+ struct pri_sequence *pse = NULL; -+ spin_lock_bh(&pool_lock); -+ if (!list_empty(&pseq_pool)) { -+ pse = list_first_entry(&pseq_pool, struct pri_sequence, head); -+ list_del(&pse->head); -+ } -+ spin_unlock_bh(&pool_lock); -+ -+ if (pse == NULL) { -+ pse = kmalloc(sizeof(*pse), GFP_ATOMIC); -+ } -+ -+ return pse; -+} -+ -+static struct pulse_elem *pool_get_pulse_elem(void) -+{ -+ struct pulse_elem *pe = NULL; -+ spin_lock_bh(&pool_lock); -+ if (!list_empty(&pulse_pool)) { -+ pe = list_first_entry(&pulse_pool, struct pulse_elem, head); -+ list_del(&pe->head); -+ } -+ spin_unlock_bh(&pool_lock); -+ return pe; -+} -+ -+static struct pulse_elem *pulse_queue_get_tail(struct pri_detector *pde) -+{ -+ struct list_head *l = &pde->pulses; -+ if (list_empty(l)) -+ return NULL; -+ return list_entry(l->prev, struct pulse_elem, head); -+} -+ -+static bool pulse_queue_dequeue(struct pri_detector *pde) -+{ -+ struct pulse_elem *p = pulse_queue_get_tail(pde); -+ if (p != NULL) { -+ list_del_init(&p->head); -+ pde->count--; -+ /* give it back to pool */ -+ pool_put_pulse_elem(p); -+ } -+ return (pde->count > 0); -+} -+ -+/** -+ * pulse_queue_check_window - remove pulses older than window -+ * @pde: pointer on pri_detector -+ * -+ * dequeue pulse that are too old. -+ */ -+static -+void pulse_queue_check_window(struct pri_detector *pde) -+{ -+ u64 min_valid_ts; -+ struct pulse_elem *p; -+ -+ /* there is no delta time with less than 2 pulses */ -+ if (pde->count < 2) -+ return; -+ -+ if (pde->last_ts <= pde->window_size) -+ return; -+ -+ min_valid_ts = pde->last_ts - pde->window_size; -+ while ((p = pulse_queue_get_tail(pde)) != NULL) { -+ if (p->ts >= min_valid_ts) -+ return; -+ pulse_queue_dequeue(pde); -+ } -+} -+ -+/** -+ * pulse_queue_enqueue - Queue one pulse -+ * @pde: pointer on pri_detector -+ * -+ * Add one pulse to the list. If the maximum number of pulses -+ * if reached, remove oldest one. -+ */ -+static -+bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts) -+{ -+ struct pulse_elem *p = pool_get_pulse_elem(); -+ if (p == NULL) { -+ p = kmalloc(sizeof(*p), GFP_ATOMIC); -+ if (p == NULL) { -+ return false; -+ } -+ } -+ INIT_LIST_HEAD(&p->head); -+ p->ts = ts; -+ list_add(&p->head, &pde->pulses); -+ pde->count++; -+ pde->last_ts = ts; -+ pulse_queue_check_window(pde); -+ if (pde->count >= pde->max_count) -+ pulse_queue_dequeue(pde); -+ -+ return true; -+} -+ -+ -+/*************************************************************************** -+ * Short waveform -+ **************************************************************************/ -+/** -+ * pde_get_multiple() - get number of multiples considering a given tolerance -+ * @return factor if abs(val - factor*fraction) <= tolerance, 0 otherwise -+ */ -+static -+u32 pde_get_multiple(u32 val, u32 fraction, u32 tolerance) -+{ -+ u32 remainder; -+ u32 factor; -+ u32 delta; -+ -+ if (fraction == 0) -+ return 0; -+ -+ delta = (val < fraction) ? (fraction - val) : (val - fraction); -+ -+ if (delta <= tolerance) -+ /* val and fraction are within tolerance */ -+ return 1; -+ -+ factor = val / fraction; -+ remainder = val % fraction; -+ if (remainder > tolerance) { -+ /* no exact match */ -+ if ((fraction - remainder) <= tolerance) -+ /* remainder is within tolerance */ -+ factor++; -+ else -+ factor = 0; -+ } -+ return factor; -+} -+ -+/** -+ * pde_short_create_sequences - create_sequences function for -+ * SHORT/WEATHER/INTERLEAVED radar waveform -+ * @pde: pointer on pri_detector -+ * @ts: timestamp of the pulse -+ * @min_count: Minimum number of pulse to be present in the sequence. -+ * (With this pulse there is already a sequence with @min_count -+ * pulse, so if we can't create a sequence with more pulse don't -+ * create it) -+ * @return: false if an error occured (memory allocation) true otherwise -+ * -+ * For each pulses queued check if we can create a sequence with -+ * pri = (ts - pulse_queued.ts) which contains more than @min_count pulses. -+ * -+ */ -+static -+bool pde_short_create_sequences(struct pri_detector *pde, -+ u64 ts, u32 min_count) -+{ -+ struct pulse_elem *p; -+ u16 pulse_idx = 0; -+ -+ list_for_each_entry(p, &pde->pulses, head) { -+ struct pri_sequence ps, *new_ps; -+ struct pulse_elem *p2; -+ u32 tmp_false_count; -+ u64 min_valid_ts; -+ u32 delta_ts = ts - p->ts; -+ pulse_idx++; -+ -+ if (delta_ts < pde->rs->pri_min) -+ /* ignore too small pri */ -+ continue; -+ -+ if (delta_ts > pde->rs->pri_max) -+ /* stop on too large pri (sorted list) */ -+ break; -+ -+ /* build a new sequence with new potential pri */ -+ ps.count = 2; -+ ps.count_falses = pulse_idx - 1; -+ ps.first_ts = p->ts; -+ ps.last_ts = ts; -+ ps.pri = ts - p->ts; -+ ps.dur = ps.pri * (pde->rs->ppb - 1) -+ + 2 * pde->rs->max_pri_tolerance; -+ -+ p2 = p; -+ tmp_false_count = 0; -+ if (ps.dur > ts) -+ min_valid_ts = 0; -+ else -+ min_valid_ts = ts - ps.dur; -+ /* check which past pulses are candidates for new sequence */ -+ list_for_each_entry_continue(p2, &pde->pulses, head) { -+ u32 factor; -+ if (p2->ts < min_valid_ts) -+ /* stop on crossing window border */ -+ break; -+ /* check if pulse match (multi)PRI */ -+ factor = pde_get_multiple(ps.last_ts - p2->ts, ps.pri, -+ pde->rs->max_pri_tolerance); -+ if (factor > 0) { -+ ps.count++; -+ ps.first_ts = p2->ts; -+ /* -+ * on match, add the intermediate falses -+ * and reset counter -+ */ -+ ps.count_falses += tmp_false_count; -+ tmp_false_count = 0; -+ } else { -+ /* this is a potential false one */ -+ tmp_false_count++; -+ } -+ } -+ if (ps.count <= min_count) { -+ /* did not reach minimum count, drop sequence */ -+ continue; -+ } -+ /* this is a valid one, add it */ -+ ps.deadline_ts = ps.first_ts + ps.dur; -+ if (pde->rs->type == RADAR_WAVEFORM_WEATHER) { -+ ps.ppb_thresh = 19000000 / (360 * ps.pri); -+ ps.ppb_thresh = PPB_THRESH(ps.ppb_thresh); -+ } else { -+ ps.ppb_thresh = pde->rs->ppb_thresh; -+ } -+ -+ new_ps = pool_get_pseq_elem(); -+ if (new_ps == NULL) { -+ return false; -+ } -+ memcpy(new_ps, &ps, sizeof(ps)); -+ INIT_LIST_HEAD(&new_ps->head); -+ list_add(&new_ps->head, &pde->sequences); -+ } -+ return true; -+} -+ -+/** -+ * pde_short_add_to_existing_seqs - add_to_existing_seqs function for -+ * SHORT/WEATHER/INTERLEAVED radar waveform -+ * @pde: pointer on pri_detector -+ * @ts: timestamp of the pulse -+ * -+ * Check all sequemces created for this pde. -+ * - If the sequence is too old delete it. -+ * - Else if the delta with the previous pulse match the pri of the sequence -+ * add the pulse to this sequence. If the pulse cannot be added it is added -+ * to the false pulses for this sequence -+ * -+ * @return the length of the longest sequence in which the pulse has been added -+ */ -+static -+u32 pde_short_add_to_existing_seqs(struct pri_detector *pde, u64 ts) -+{ -+ u32 max_count = 0; -+ struct pri_sequence *ps, *ps2; -+ list_for_each_entry_safe(ps, ps2, &pde->sequences, head) { -+ u32 delta_ts; -+ u32 factor; -+ -+ /* first ensure that sequence is within window */ -+ if (ts > ps->deadline_ts) { -+ list_del_init(&ps->head); -+ pool_put_pseq_elem(ps); -+ continue; -+ } -+ -+ delta_ts = ts - ps->last_ts; -+ factor = pde_get_multiple(delta_ts, ps->pri, -+ pde->rs->max_pri_tolerance); -+ -+ if (factor > 0) { -+ ps->last_ts = ts; -+ ps->count++; -+ -+ if (max_count < ps->count) -+ max_count = ps->count; -+ } else { -+ ps->count_falses++; -+ } -+ } -+ return max_count; -+} -+ -+ -+/** -+ * pde_short_check_detection - check_detection function for -+ * SHORT/WEATHER/INTERLEAVED radar waveform -+ * @pde: pointer on pri_detector -+ * -+ * Check all sequemces created for this pde. -+ * - If a sequence contains more pulses than the threshold and more matching -+ * that false pulses. -+ * -+ * @return The first complete sequence, and NULL if no sequence is complete. -+ */ -+static -+struct pri_sequence *pde_short_check_detection(struct pri_detector *pde) -+{ -+ struct pri_sequence *ps; -+ -+ if (list_empty(&pde->sequences)) -+ return NULL; -+ -+ list_for_each_entry(ps, &pde->sequences, head) { -+ /* -+ * we assume to have enough matching confidence if we -+ * 1) have enough pulses -+ * 2) have more matching than false pulses -+ */ -+ if ((ps->count >= ps->ppb_thresh) && -+ (ps->count * pde->rs->num_pri > ps->count_falses)) { -+ return ps; -+ } -+ } -+ return NULL; -+} -+ -+/** -+ * pde_short_init - init function for -+ * SHORT/WEATHER/INTERLEAVED radar waveform -+ * @pde: pointer on pri_detector -+ * -+ * Initialize pri_detector window size to the maximun size of one burst -+ * for the radar specification associated. -+ */ -+static -+void pde_short_init(struct pri_detector *pde) -+{ -+ pde->window_size = pde->rs->pri_max * pde->rs->ppb * pde->rs->num_pri; -+ pde->max_count = pde->rs->ppb * 2; -+} -+ -+static void pri_detector_reset(struct pri_detector *pde, u64 ts); -+/** -+ * pde_short_add_pulse - Add pulse to a pri_detector for -+ * SHORT/WEATHER/INTERLEAVED radar waveform -+ * -+ * @pde : pointer on pri_detector -+ * @len : width of the pulse -+ * @ts : timestamp of the pulse received -+ * @pri : Delta in us with the previous pulse. -+ * (0 means that delta in bigger than 65535 us) -+ * -+ * Process on pulse within this pri_detector -+ * - First try to add it to existing sequence -+ * - Then try to create a new and longest sequence -+ * - Check if this pulse complete a sequence -+ * - If not save this pulse in the list -+ */ -+static -+struct pri_sequence *pde_short_add_pulse(struct pri_detector *pde, -+ u16 len, u64 ts, u16 pri) -+{ -+ u32 max_updated_seq; -+ struct pri_sequence *ps; -+ const struct radar_detector_specs *rs = pde->rs; -+ -+ if (pde->count == 0) { -+ /* This is the first pulse after reset, no need to check sequences */ -+ pulse_queue_enqueue(pde, ts); -+ return NULL; -+ } -+ -+ if ((ts - pde->last_ts) < rs->max_pri_tolerance) { -+ /* if delta to last pulse is too short, don't use this pulse */ -+ return NULL; -+ } -+ -+ max_updated_seq = pde_short_add_to_existing_seqs(pde, ts); -+ -+ if (!pde_short_create_sequences(pde, ts, max_updated_seq)) { -+ pri_detector_reset(pde, ts); -+ return NULL; -+ } -+ -+ ps = pde_short_check_detection(pde); -+ -+ if (ps == NULL) -+ pulse_queue_enqueue(pde, ts); -+ -+ return ps; -+} -+ -+ -+ -+/** -+ * pri detector ops to detect short radar waveform -+ * A Short waveform is defined by : -+ * The width of pulses. -+ * The interval between two pulses inside a burst (called pri) -+ * (some waveform may have or 2/3 interleaved pri) -+ * The number of pulses per burst (ppb) -+ */ -+static struct pri_detector_ops pri_detector_short = { -+ .init = pde_short_init, -+ .add_pulse = pde_short_add_pulse, -+ .reset_on_pri_overflow = 1, -+}; -+ -+ -+/*************************************************************************** -+ * Long waveform -+ **************************************************************************/ -+#define LONG_RADAR_DURATION 12000000 -+#define LONG_RADAR_BURST_MIN_DURATION (12000000 / 20) -+#define LONG_RADAR_MAX_BURST 20 -+ -+/** -+ * pde_long_init - init function for LONG radar waveform -+ * @pde: pointer on pri_detector -+ * -+ * Initialize pri_detector window size to the long waveform radar -+ * waveform (ie. 12s) and max_count -+ */ -+static -+void pde_long_init(struct pri_detector *pde) -+{ -+ pde->window_size = LONG_RADAR_DURATION; -+ pde->max_count = LONG_RADAR_MAX_BURST; /* only count burst not pulses */ -+} -+ -+ -+/** -+ * pde_long_add_pulse - Add pulse to a pri_detector for -+ * LONG radar waveform -+ * -+ * @pde : pointer on pri_detector -+ * @len : width of the pulse -+ * @ts : timestamp of the pulse received -+ * @pri : Delta in us with the previous pulse. -+ * -+ * -+ * For long pulse we only handle one sequence. Since each burst -+ * have a different set of parameters (number of pulse, pri) than -+ * the previous one we only use pulse width to add the pulse in the -+ * sequence. -+ * We only queue one pulse per burst and valid the radar when enough burst -+ * has been detected. -+ */ -+static -+struct pri_sequence *pde_long_add_pulse(struct pri_detector *pde, -+ u16 len, u64 ts, u16 pri) -+{ -+ struct pri_sequence *ps; -+ const struct radar_detector_specs *rs = pde->rs; -+ -+ if (list_empty(&pde->sequences)) { -+ /* First pulse, create a new sequence */ -+ ps = pool_get_pseq_elem(); -+ if (ps == NULL) { -+ return NULL; -+ } -+ -+ /*For long waveform, "count" represents the number of burst detected */ -+ ps->count = 1; -+ /*"count_false" represents the number of pulse in the current burst */ -+ ps->count_falses = 1; -+ ps->first_ts = ts; -+ ps->last_ts = ts; -+ ps->deadline_ts = ts + pde->window_size; -+ ps->pri = 0; -+ INIT_LIST_HEAD(&ps->head); -+ list_add(&ps->head, &pde->sequences); -+ pulse_queue_enqueue(pde, ts); -+ } else { -+ u32 delta_ts; -+ -+ ps = (struct pri_sequence *)pde->sequences.next; -+ -+ delta_ts = ts - ps->last_ts; -+ ps->last_ts = ts; -+ -+ if (delta_ts < rs->pri_max) { -+ /* ignore pulse too close from previous one */ -+ } else if ((delta_ts >= rs->pri_min) && -+ (delta_ts <= rs->pri_max)) { -+ /* this is a new pulse in the current burst, ignore it -+ (i.e don't queue it) */ -+ ps->count_falses++; -+ } else if ((ps->count > 2) && -+ (ps->dur + delta_ts) < LONG_RADAR_BURST_MIN_DURATION) { -+ /* not enough time between burst, ignore pulse */ -+ } else { -+ /* a new burst */ -+ ps->count++; -+ ps->count_falses = 1; -+ -+ /* reset the start of the sequence if deadline reached */ -+ if (ts > ps->deadline_ts) { -+ struct pulse_elem *p; -+ u64 min_valid_ts; -+ -+ min_valid_ts = ts - pde->window_size; -+ while ((p = pulse_queue_get_tail(pde)) != NULL) { -+ if (p->ts >= min_valid_ts) { -+ ps->first_ts = p->ts; -+ ps->deadline_ts = p->ts + pde->window_size; -+ break; -+ } -+ pulse_queue_dequeue(pde); -+ ps->count--; -+ } -+ } -+ -+ /* valid radar if enough burst detected and delta with first burst -+ is at least duration/2 */ -+ if (ps->count > pde->rs->ppb_thresh && -+ (ts - ps->first_ts) > (pde->window_size / 2)) { -+ return ps; -+ } else { -+ pulse_queue_enqueue(pde, ts); -+ ps->dur = delta_ts; -+ } -+ } -+ } -+ -+ return NULL; -+} -+ -+/** -+ * pri detector ops to detect long radar waveform -+ */ -+static struct pri_detector_ops pri_detector_long = { -+ .init = pde_long_init, -+ .add_pulse = pde_long_add_pulse, -+ .reset_on_pri_overflow = 0, -+}; -+ -+ -+/*************************************************************************** -+ * PRI detector init/reset/exit/get -+ **************************************************************************/ -+/** -+ * pri_detector_init- Create a new pri_detector -+ * -+ * @dpd: dfs_pattern_detector instance pointer -+ * @radar_type: index of radar pattern -+ * @freq: Frequency of the pri detector -+ */ -+struct pri_detector *pri_detector_init(struct dfs_pattern_detector *dpd, -+ u16 radar_type, u16 freq) -+{ -+ struct pri_detector *pde; -+ -+ pde = kzalloc(sizeof(*pde), GFP_ATOMIC); -+ if (pde == NULL) -+ return NULL; -+ -+ INIT_LIST_HEAD(&pde->sequences); -+ INIT_LIST_HEAD(&pde->pulses); -+ INIT_LIST_HEAD(&pde->head); -+ list_add(&pde->head, &dpd->detectors[radar_type]); -+ -+ pde->rs = &dpd->radar_spec[radar_type]; -+ pde->freq = freq; -+ -+ if (pde->rs->type == RADAR_WAVEFORM_LONG) { -+ /* for LONG WAVEFORM */ -+ pde->ops = &pri_detector_long; -+ } else { -+ /* for SHORT, WEATHER and INTERLEAVED */ -+ pde->ops = &pri_detector_short; -+ } -+ -+ /* Init dependent of specs */ -+ pde->ops->init(pde); -+ -+ pool_register_ref(); -+ return pde; -+} -+ -+/** -+ * pri_detector_reset - Reset pri_detector -+ * -+ * @pde: pointer on pri_detector -+ * @ts: New ts reference for the pri_detector -+ * -+ * free pulse queue and sequences list and give objects back to pools -+ */ -+static -+void pri_detector_reset(struct pri_detector *pde, u64 ts) -+{ -+ struct pri_sequence *ps, *ps0; -+ struct pulse_elem *p, *p0; -+ list_for_each_entry_safe(ps, ps0, &pde->sequences, head) { -+ list_del_init(&ps->head); -+ pool_put_pseq_elem(ps); -+ } -+ list_for_each_entry_safe(p, p0, &pde->pulses, head) { -+ list_del_init(&p->head); -+ pool_put_pulse_elem(p); -+ } -+ pde->count = 0; -+ pde->last_ts = ts; -+} -+ -+/** -+ * pri_detector_exit - Delete pri_detector -+ * -+ * @pde: pointer on pri_detector -+ */ -+static -+void pri_detector_exit(struct pri_detector *pde) -+{ -+ pri_detector_reset(pde, 0); -+ pool_deregister_ref(); -+ list_del(&pde->head); -+ kfree(pde); -+} -+ -+/** -+ * pri_detector_get() - get pri detector for a given frequency and type -+ * @dpd: dfs_pattern_detector instance pointer -+ * @freq: frequency in MHz -+ * @radar_type: index of radar pattern -+ * @return pointer to pri detector on success, NULL otherwise -+ * -+ * Return existing pri detector for the given frequency or return a -+ * newly create one. -+ * Pri detector are "merged" by frequency so that if a pri detector for a freq -+ * of +/- 2Mhz already exists don't create a new one. -+ * -+ * Maybe will need to adapt frequency merge for pattern with chirp. -+ */ -+static struct pri_detector * -+pri_detector_get(struct dfs_pattern_detector *dpd, u16 freq, u16 radar_type) -+{ -+ struct pri_detector *pde, *cur = NULL; -+ list_for_each_entry(pde, &dpd->detectors[radar_type], head) { -+ if (pde->freq == freq) { -+ if (pde->count) -+ return pde; -+ else -+ cur = pde; -+ } else if (pde->freq - 2 == freq && pde->count) { -+ return pde; -+ } else if (pde->freq + 2 == freq && pde->count) { -+ return pde; -+ } -+ } -+ -+ if (cur) -+ return cur; -+ else -+ return pri_detector_init(dpd, radar_type, freq); -+} -+ -+ -+/****************************************************************************** -+ * DFS Pattern Detector -+ *****************************************************************************/ -+/** -+ * dfs_pattern_detector_reset() - reset all channel detectors -+ * -+ * @dpd: dfs_pattern_detector -+ */ -+static void dfs_pattern_detector_reset(struct dfs_pattern_detector *dpd) -+{ -+ struct pri_detector *pde; -+ int i; -+ -+ for (i = 0; i < dpd->num_radar_types; i++) { -+ if (!list_empty(&dpd->detectors[i])) -+ list_for_each_entry(pde, &dpd->detectors[i], head) -+ pri_detector_reset(pde, dpd->last_pulse_ts); -+ } -+ -+ dpd->last_pulse_ts = 0; -+ dpd->prev_jiffies = jiffies; -+} -+ -+/** -+ * dfs_pattern_detector_reset() - delete all channel detectors -+ * -+ * @dpd: dfs_pattern_detector -+ */ -+static void dfs_pattern_detector_exit(struct dfs_pattern_detector *dpd) -+{ -+ struct pri_detector *pde, *pde0; -+ int i; -+ -+ for (i = 0; i < dpd->num_radar_types; i++) { -+ if (!list_empty(&dpd->detectors[i])) -+ list_for_each_entry_safe(pde, pde0, &dpd->detectors[i], head) -+ pri_detector_exit(pde); -+ } -+ -+ kfree(dpd); -+} -+ -+/** -+ * dfs_pattern_detector_pri_overflow - reset all channel detectors on pri -+ * overflow -+ * @dpd: dfs_pattern_detector -+ */ -+static void dfs_pattern_detector_pri_overflow(struct dfs_pattern_detector *dpd) -+{ -+ struct pri_detector *pde; -+ int i; -+ -+ for (i = 0; i < dpd->num_radar_types; i++) { -+ if (!list_empty(&dpd->detectors[i])) -+ list_for_each_entry(pde, &dpd->detectors[i], head) -+ if (pde->ops->reset_on_pri_overflow) -+ pri_detector_reset(pde, dpd->last_pulse_ts); -+ } -+} -+ -+/** -+ * dfs_pattern_detector_add_pulse - Process one pulse -+ * -+ * @dpd: dfs_pattern_detector -+ * @chain: Chain that correspond to this pattern_detector (only for debug) -+ * @freq: frequency of the pulse -+ * @pri: Delta with previous pulse. (0 if delta is too big for u16) -+ * @len: width of the pulse -+ * @now: jiffies value when pulse was received -+ * -+ * Get (or create) the channel_detector for this frequency. Then add the pulse -+ * in each pri_detector created in this channel_detector. -+ * -+ * -+ * @return True is the pulse complete a radar pattern, false otherwise -+ */ -+static bool dfs_pattern_detector_add_pulse(struct dfs_pattern_detector *dpd, -+ enum rwnx_radar_chain chain, -+ u16 freq, u16 pri, u16 len, u32 now) -+{ -+ u32 i; -+ -+ /* -+ * pulses received for a non-supported or un-initialized -+ * domain are treated as detected radars for fail-safety -+ */ -+ if (dpd->region == NL80211_DFS_UNSET) -+ return true; -+ -+ /* Compute pulse time stamp */ -+ if (pri == 0) { -+ u32 delta_jiffie; -+ if (unlikely(now < dpd->prev_jiffies)) { -+ delta_jiffie = 0xffffffff - dpd->prev_jiffies + now; -+ } else { -+ delta_jiffie = now - dpd->prev_jiffies; -+ } -+ dpd->last_pulse_ts += jiffies_to_usecs(delta_jiffie); -+ dpd->prev_jiffies = now; -+ dfs_pattern_detector_pri_overflow(dpd); -+ } else { -+ dpd->last_pulse_ts += pri; -+ } -+ -+ for (i = 0; i < dpd->num_radar_types; i++) { -+ struct pri_sequence *ps; -+ struct pri_detector *pde; -+ const struct radar_detector_specs *rs = &dpd->radar_spec[i]; -+ -+ /* no need to look up for pde if len is not within range */ -+ if ((rs->width_min > len) || -+ (rs->width_max < len)) { -+ continue; -+ } -+ -+ pde = pri_detector_get(dpd, freq, i); -+ ps = pde->ops->add_pulse(pde, len, dpd->last_pulse_ts, pri); -+ -+ if (ps != NULL) { -+#ifdef CREATE_TRACE_POINTS -+ trace_radar_detected(chain, dpd->region, pde->freq, i, ps->pri); -+#endif -+ // reset everything instead of just the channel detector -+ dfs_pattern_detector_reset(dpd); -+ return true; -+ } -+ } -+ -+ return false; -+} -+ -+/** -+ * get_dfs_domain_radar_types() - get radar types for a given DFS domain -+ * @param domain DFS domain -+ * @return radar_types ptr on success, NULL if DFS domain is not supported -+ */ -+static const struct radar_types * -+get_dfs_domain_radar_types(enum nl80211_dfs_regions region) -+{ -+ u32 i; -+ for (i = 0; i < ARRAY_SIZE(dfs_domains); i++) { -+ if (dfs_domains[i]->region == region) -+ return dfs_domains[i]; -+ } -+ return NULL; -+} -+ -+/** -+ * get_dfs_max_radar_types() - get maximum radar types for all supported domain -+ * @return the maximum number of radar pattern supported by on region -+ */ -+static u16 get_dfs_max_radar_types(void) -+{ -+ u32 i; -+ u16 max = 0; -+ for (i = 0; i < ARRAY_SIZE(dfs_domains); i++) { -+ if (dfs_domains[i]->num_radar_types > max) -+ max = dfs_domains[i]->num_radar_types; -+ } -+ return max; -+} -+ -+/** -+ * dfs_pattern_detector_set_domain - set DFS domain -+ * -+ * @dpd: dfs_pattern_detector -+ * @region: DFS region -+ * -+ * set DFS domain, resets detector lines upon domain changes -+ */ -+static -+bool dfs_pattern_detector_set_domain(struct dfs_pattern_detector *dpd, -+ enum nl80211_dfs_regions region, u8 chain) -+{ -+ const struct radar_types *rt; -+ struct pri_detector *pde, *pde0; -+ int i; -+ -+ if (dpd->region == region) -+ return true; -+ -+ dpd->region = NL80211_DFS_UNSET; -+ -+ rt = get_dfs_domain_radar_types(region); -+ if (rt == NULL) -+ return false; -+ -+ /* delete all pri detectors for previous DFS domain */ -+ for (i = 0; i < dpd->num_radar_types; i++) { -+ if (!list_empty(&dpd->detectors[i])) -+ list_for_each_entry_safe(pde, pde0, &dpd->detectors[i], head) -+ pri_detector_exit(pde); -+ } -+ -+ if (chain == RWNX_RADAR_RIU) -+ dpd->radar_spec = rt->spec_riu; -+ else -+ dpd->radar_spec = rt->spec_fcu; -+ dpd->num_radar_types = rt->num_radar_types; -+ -+ dpd->region = region; -+ return true; -+} -+ -+/** -+ * dfs_pattern_detector_init - Initialize dfs_pattern_detector -+ * -+ * @region: DFS region -+ * @return: pointer on dfs_pattern_detector -+ * -+ */ -+static struct dfs_pattern_detector * -+dfs_pattern_detector_init(enum nl80211_dfs_regions region, u8 chain) -+{ -+ struct dfs_pattern_detector *dpd; -+ u16 i, max_radar_type = get_dfs_max_radar_types(); -+ -+ dpd = kmalloc(sizeof(*dpd) + max_radar_type * sizeof(dpd->detectors[0]), -+ GFP_KERNEL); -+ if (dpd == NULL) -+ return NULL; -+ -+ dpd->region = NL80211_DFS_UNSET; -+ dpd->enabled = RWNX_RADAR_DETECT_DISABLE; -+ dpd->last_pulse_ts = 0; -+ dpd->prev_jiffies = jiffies; -+ dpd->num_radar_types = 0; -+ for (i = 0; i < max_radar_type; i++) -+ INIT_LIST_HEAD(&dpd->detectors[i]); -+ -+ if (dfs_pattern_detector_set_domain(dpd, region, chain)) -+ return dpd; -+ -+ kfree(dpd); -+ return NULL; -+} -+ -+ -+/****************************************************************************** -+ * driver interface -+ *****************************************************************************/ -+static u16 rwnx_radar_get_center_freq(struct rwnx_hw *rwnx_hw, u8 chain) -+{ -+ if (chain == RWNX_RADAR_FCU) -+ return rwnx_hw->phy.sec_chan.center_freq1; -+ -+ if (chain == RWNX_RADAR_RIU) { -+#ifdef CONFIG_RWNX_FULLMAC -+ if (!rwnx_chanctx_valid(rwnx_hw, rwnx_hw->cur_chanctx)) { -+ WARN(1, "Radar pulse without channel information"); -+ } else -+ return rwnx_hw->chanctx_table[rwnx_hw->cur_chanctx].chan_def.center_freq1; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ } -+ -+ return 0; -+} -+ -+static void rwnx_radar_detected(struct rwnx_hw *rwnx_hw) -+{ -+#ifdef CONFIG_RWNX_FULLMAC -+ struct cfg80211_chan_def chan_def; -+ -+ if (!rwnx_chanctx_valid(rwnx_hw, rwnx_hw->cur_chanctx)) { -+ WARN(1, "Radar detected without channel information"); -+ return; -+ } -+ -+ /* -+ recopy chan_def in local variable because rwnx_radar_cancel_cac may -+ clean the variable (if in CAC and it's the only vif using this context) -+ and CAC should be aborted before reporting the radar. -+ */ -+ chan_def = rwnx_hw->chanctx_table[rwnx_hw->cur_chanctx].chan_def; -+ -+ rwnx_radar_cancel_cac(&rwnx_hw->radar); -+ cfg80211_radar_event(rwnx_hw->wiphy, &chan_def, GFP_KERNEL); -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+} -+ -+static void rwnx_radar_process_pulse(struct work_struct *ws) -+{ -+ struct rwnx_radar *radar = container_of(ws, struct rwnx_radar, -+ detection_work); -+ struct rwnx_hw *rwnx_hw = container_of(radar, struct rwnx_hw, radar); -+ int chain; -+ u32 pulses[RWNX_RADAR_LAST][RWNX_RADAR_PULSE_MAX]; -+ u16 pulses_count[RWNX_RADAR_LAST]; -+ u32 now = jiffies; /* would be better to store jiffies value in IT handler */ -+ -+ /* recopy pulses locally to avoid too long spin_lock */ -+ spin_lock_bh(&radar->lock); -+ for (chain = RWNX_RADAR_RIU; chain < RWNX_RADAR_LAST; chain++) { -+ int start, count; -+ -+ count = radar->pulses[chain].count; -+ start = radar->pulses[chain].index - count; -+ if (start < 0) -+ start += RWNX_RADAR_PULSE_MAX; -+ -+ pulses_count[chain] = count; -+ if (count == 0) -+ continue; -+ -+ if ((start + count) > RWNX_RADAR_PULSE_MAX) { -+ u16 count1 = (RWNX_RADAR_PULSE_MAX - start); -+ memcpy(&(pulses[chain][0]), -+ &(radar->pulses[chain].buffer[start]), -+ count1 * sizeof(struct radar_pulse)); -+ memcpy(&(pulses[chain][count1]), -+ &(radar->pulses[chain].buffer[0]), -+ (count - count1) * sizeof(struct radar_pulse)); -+ } else { -+ memcpy(&(pulses[chain][0]), -+ &(radar->pulses[chain].buffer[start]), -+ count * sizeof(struct radar_pulse)); -+ } -+ radar->pulses[chain].count = 0; -+ } -+ spin_unlock_bh(&radar->lock); -+ -+ -+ /* now process pulses */ -+ for (chain = RWNX_RADAR_RIU; chain < RWNX_RADAR_LAST; chain++) { -+ int i; -+ u16 freq; -+ -+ if (pulses_count[chain] == 0) -+ continue; -+ -+ freq = rwnx_radar_get_center_freq(rwnx_hw, chain); -+ -+ for (i = 0; i < pulses_count[chain] ; i++) { -+ struct radar_pulse *p = (struct radar_pulse *)&pulses[chain][i]; -+#ifdef CREATE_TRACE_POINTS -+ trace_radar_pulse(chain, p); -+#endif -+ if (dfs_pattern_detector_add_pulse(radar->dpd[chain], chain, -+ (s16)freq + (2 * p->freq), -+ p->rep, (p->len * 2), now)) { -+ u16 idx = radar->detected[chain].index; -+ -+ if (chain == RWNX_RADAR_RIU) { -+ /* operating chain, inform upper layer to change channel */ -+ if (radar->dpd[chain]->enabled == RWNX_RADAR_DETECT_REPORT) { -+ rwnx_radar_detected(rwnx_hw); -+ /* no need to report new radar until upper layer set a -+ new channel. This prevent warning if a new radar is -+ detected while mac80211 is changing channel */ -+ rwnx_radar_detection_enable(radar, -+ RWNX_RADAR_DETECT_DISABLE, -+ chain); -+ /* purge any event received since the beginning of the -+ function (we are sure not to interfer with tasklet -+ as we disable detection just before) */ -+ radar->pulses[chain].count = 0; -+ } -+ } else { -+ /* secondary radar detection chain, simply report info in -+ debugfs for now */ -+ } -+ -+ radar->detected[chain].freq[idx] = (s16)freq + (2 * p->freq); -+ radar->detected[chain].time[idx] = ktime_get_real_seconds(); -+ radar->detected[chain].index = ((idx + 1) % -+ NX_NB_RADAR_DETECTED); -+ radar->detected[chain].count++; -+ /* no need to process next pulses for this chain */ -+ break; -+ } -+ } -+ } -+} -+ -+#ifdef CONFIG_RWNX_FULLMAC -+static void rwnx_radar_cac_work(struct work_struct *ws) -+{ -+ struct delayed_work *dw = container_of(ws, struct delayed_work, work); -+ struct rwnx_radar *radar = container_of(dw, struct rwnx_radar, cac_work); -+ struct rwnx_hw *rwnx_hw = container_of(radar, struct rwnx_hw, radar); -+ struct rwnx_chanctx *ctxt; -+ -+ if (radar->cac_vif == NULL) { -+ WARN(1, "CAC finished but no vif set"); -+ return; -+ } -+ -+ ctxt = &rwnx_hw->chanctx_table[radar->cac_vif->ch_index]; -+ cfg80211_cac_event(radar->cac_vif->ndev, -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ &ctxt->chan_def, -+ #endif -+ NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); -+ rwnx_send_apm_stop_cac_req(rwnx_hw, radar->cac_vif); -+ rwnx_chanctx_unlink(radar->cac_vif); -+ -+ radar->cac_vif = NULL; -+} -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+bool rwnx_radar_detection_init(struct rwnx_radar *radar) -+{ -+ spin_lock_init(&radar->lock); -+ -+ radar->dpd[RWNX_RADAR_RIU] = dfs_pattern_detector_init(NL80211_DFS_UNSET, -+ RWNX_RADAR_RIU); -+ if (radar->dpd[RWNX_RADAR_RIU] == NULL) -+ return false; -+ -+ radar->dpd[RWNX_RADAR_FCU] = dfs_pattern_detector_init(NL80211_DFS_UNSET, -+ RWNX_RADAR_FCU); -+ if (radar->dpd[RWNX_RADAR_FCU] == NULL) { -+ rwnx_radar_detection_deinit(radar); -+ return false; -+ } -+ -+ INIT_WORK(&radar->detection_work, rwnx_radar_process_pulse); -+#ifdef CONFIG_RWNX_FULLMAC -+ INIT_DELAYED_WORK(&radar->cac_work, rwnx_radar_cac_work); -+ radar->cac_vif = NULL; -+#endif /* CONFIG_RWNX_FULLMAC */ -+ return true; -+} -+ -+void rwnx_radar_detection_deinit(struct rwnx_radar *radar) -+{ -+ if (radar->dpd[RWNX_RADAR_RIU]) { -+ dfs_pattern_detector_exit(radar->dpd[RWNX_RADAR_RIU]); -+ radar->dpd[RWNX_RADAR_RIU] = NULL; -+ } -+ if (radar->dpd[RWNX_RADAR_FCU]) { -+ dfs_pattern_detector_exit(radar->dpd[RWNX_RADAR_FCU]); -+ radar->dpd[RWNX_RADAR_FCU] = NULL; -+ } -+} -+ -+bool rwnx_radar_set_domain(struct rwnx_radar *radar, -+ enum nl80211_dfs_regions region) -+{ -+ if (radar->dpd[0] == NULL) -+ return false; -+#ifdef CREATE_TRACE_POINTS -+ trace_radar_set_region(region); -+#endif -+ return (dfs_pattern_detector_set_domain(radar->dpd[RWNX_RADAR_RIU], -+ region, RWNX_RADAR_RIU) && -+ dfs_pattern_detector_set_domain(radar->dpd[RWNX_RADAR_FCU], -+ region, RWNX_RADAR_FCU)); -+} -+ -+void rwnx_radar_detection_enable(struct rwnx_radar *radar, u8 enable, u8 chain) -+{ -+ if (chain < RWNX_RADAR_LAST) { -+#ifdef CREATE_TRACE_POINTS -+ trace_radar_enable_detection(radar->dpd[chain]->region, enable, chain); -+#endif -+ spin_lock_bh(&radar->lock); -+ radar->dpd[chain]->enabled = enable; -+ spin_unlock_bh(&radar->lock); -+ } -+} -+ -+bool rwnx_radar_detection_is_enable(struct rwnx_radar *radar, u8 chain) -+{ -+ return radar->dpd[chain]->enabled != RWNX_RADAR_DETECT_DISABLE; -+} -+ -+#ifdef CONFIG_RWNX_FULLMAC -+void rwnx_radar_start_cac(struct rwnx_radar *radar, u32 cac_time_ms, -+ struct rwnx_vif *vif) -+{ -+ WARN(radar->cac_vif != NULL, "CAC already in progress"); -+ radar->cac_vif = vif; -+ schedule_delayed_work(&radar->cac_work, msecs_to_jiffies(cac_time_ms)); -+} -+ -+void rwnx_radar_cancel_cac(struct rwnx_radar *radar) -+{ -+ struct rwnx_hw *rwnx_hw = container_of(radar, struct rwnx_hw, radar); -+ -+ if (radar->cac_vif == NULL) { -+ return; -+ } -+ -+ if (cancel_delayed_work(&radar->cac_work)) { -+ struct rwnx_chanctx *ctxt; -+ ctxt = &rwnx_hw->chanctx_table[radar->cac_vif->ch_index]; -+ rwnx_send_apm_stop_cac_req(rwnx_hw, radar->cac_vif); -+ cfg80211_cac_event(radar->cac_vif->ndev, -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) -+ &ctxt->chan_def, -+ #endif -+ NL80211_RADAR_CAC_ABORTED, GFP_KERNEL); -+ rwnx_chanctx_unlink(radar->cac_vif); -+ } -+ -+ radar->cac_vif = NULL; -+} -+ -+void rwnx_radar_detection_enable_on_cur_channel(struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_chanctx *ctxt; -+ -+ /* If no information on current channel do nothing */ -+ if (!rwnx_chanctx_valid(rwnx_hw, rwnx_hw->cur_chanctx)) -+ return; -+ -+ ctxt = &rwnx_hw->chanctx_table[rwnx_hw->cur_chanctx]; -+ if (ctxt->chan_def.chan->flags & IEEE80211_CHAN_RADAR) { -+ rwnx_radar_detection_enable(&rwnx_hw->radar, -+ RWNX_RADAR_DETECT_REPORT, -+ RWNX_RADAR_RIU); -+ } else { -+ rwnx_radar_detection_enable(&rwnx_hw->radar, -+ RWNX_RADAR_DETECT_DISABLE, -+ RWNX_RADAR_RIU); -+ } -+} -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+/***************************************************************************** -+ * Debug functions -+ *****************************************************************************/ -+static -+int rwnx_radar_dump_pri_detector(char *buf, size_t len, -+ struct pri_detector *pde) -+{ -+ char freq_info[] = "Freq = %3.dMhz\n"; -+ char seq_info[] = " pri | count | false \n"; -+ struct pri_sequence *seq; -+ int res, write = 0; -+ -+ if (list_empty(&pde->sequences)) { -+ return 0; -+ } -+ -+ if (buf == NULL) { -+ int nb_seq = 1; -+ list_for_each_entry(seq, &pde->sequences, head) { -+ nb_seq++; -+ } -+ -+ return (sizeof(freq_info) + nb_seq * sizeof(seq_info)); -+ } -+ -+ res = scnprintf(buf, len, freq_info, pde->freq); -+ write += res; -+ len -= res; -+ -+ res = scnprintf(&buf[write], len, "%s", seq_info); -+ write += res; -+ len -= res; -+ -+ list_for_each_entry(seq, &pde->sequences, head) { -+ res = scnprintf(&buf[write], len, " %6.d | %2.d | %.2d \n", -+ seq->pri, seq->count, seq->count_falses); -+ write += res; -+ len -= res; -+ } -+ -+ return write; -+} -+ -+int rwnx_radar_dump_pattern_detector(char *buf, size_t len, -+ struct rwnx_radar *radar, u8 chain) -+{ -+ struct dfs_pattern_detector *dpd = radar->dpd[chain]; -+ char info[] = "Type = %3.d\n"; -+ struct pri_detector *pde; -+ int i, res, write = 0; -+ -+ /* if buf is NULL return size needed for dump */ -+ if (buf == NULL) { -+ int size_needed = 0; -+ -+ for (i = 0; i < dpd->num_radar_types; i++) { -+ list_for_each_entry(pde, &dpd->detectors[i], head) { -+ size_needed += rwnx_radar_dump_pri_detector(NULL, 0, pde); -+ } -+ size_needed += sizeof(info); -+ -+ return size_needed; -+ } -+ } -+ -+ /* */ -+ for (i = 0; i < dpd->num_radar_types; i++) { -+ res = scnprintf(&buf[write], len, info, i); -+ -+ write += res; -+ len -= res; -+ list_for_each_entry(pde, &dpd->detectors[i], head) { -+ res = rwnx_radar_dump_pri_detector(&buf[write], len, pde); -+ write += res; -+ len -= res; -+ } -+ } -+ -+ return write; -+} -+ -+ -+int rwnx_radar_dump_radar_detected(char *buf, size_t len, -+ struct rwnx_radar *radar, u8 chain) -+{ -+ struct rwnx_radar_detected *detect = &(radar->detected[chain]); -+ char info[] = "2001/02/02 - 02:20 5126MHz\n"; -+ int idx, i, res, write = 0; -+ int count = detect->count; -+ -+ if (count > NX_NB_RADAR_DETECTED) -+ count = NX_NB_RADAR_DETECTED; -+ -+ if (buf == NULL) { -+ return (count * sizeof(info)) + 1; -+ } -+ -+ idx = (detect->index - detect->count) % NX_NB_RADAR_DETECTED; -+ -+ for (i = 0; i < count; i++) { -+ struct tm tm; -+ time64_to_tm(detect->time[idx], 0, &tm); -+ -+ res = scnprintf(&buf[write], len, -+ "%.4d/%.2d/%.2d - %.2d:%.2d %4.4dMHz\n", -+ (int)tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, -+ tm.tm_hour, tm.tm_min, detect->freq[idx]); -+ write += res; -+ len -= res; -+ -+ idx = (idx + 1) % NX_NB_RADAR_DETECTED; -+ } -+ -+ return write; -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,160 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_radar.h -+ * -+ * @brief Functions to handle radar detection -+ * -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+#ifndef _RWNX_RADAR_H_ -+#define _RWNX_RADAR_H_ -+ -+#include -+ -+struct rwnx_vif; -+struct rwnx_hw; -+ -+enum rwnx_radar_chain { -+ RWNX_RADAR_RIU = 0, -+ RWNX_RADAR_FCU, -+ RWNX_RADAR_LAST -+}; -+ -+enum rwnx_radar_detector { -+ RWNX_RADAR_DETECT_DISABLE = 0, /* Ignore radar pulses */ -+ RWNX_RADAR_DETECT_ENABLE = 1, /* Process pattern detection but do not -+ report radar to upper layer (for test) */ -+ RWNX_RADAR_DETECT_REPORT = 2 /* Process pattern detection and report -+ radar to upper layer. */ -+}; -+ -+#ifdef CONFIG_RWNX_RADAR -+#include -+#include -+ -+#define RWNX_RADAR_PULSE_MAX 32 -+ -+/** -+ * struct rwnx_radar_pulses - List of pulses reported by HW -+ * @index: write index -+ * @count: number of valid pulses -+ * @buffer: buffer of pulses -+ */ -+struct rwnx_radar_pulses { -+ /* Last radar pulses received */ -+ int index; -+ int count; -+ u32 buffer[RWNX_RADAR_PULSE_MAX]; -+}; -+ -+/** -+ * struct dfs_pattern_detector - DFS pattern detector -+ * @region: active DFS region, NL80211_DFS_UNSET until set -+ * @num_radar_types: number of different radar types -+ * @last_pulse_ts: time stamp of last valid pulse in usecs -+ * @prev_jiffies: -+ * @radar_detector_specs: array of radar detection specs -+ * @channel_detectors: list connecting channel_detector elements -+ */ -+struct dfs_pattern_detector { -+ u8 enabled; -+ enum nl80211_dfs_regions region; -+ u8 num_radar_types; -+ u64 last_pulse_ts; -+ u32 prev_jiffies; -+ const struct radar_detector_specs *radar_spec; -+ struct list_head detectors[]; -+}; -+ -+#define NX_NB_RADAR_DETECTED 4 -+ -+/** -+ * struct rwnx_radar_detected - List of radar detected -+ */ -+struct rwnx_radar_detected { -+ u16 index; -+ u16 count; -+ s64 time[NX_NB_RADAR_DETECTED]; -+ s16 freq[NX_NB_RADAR_DETECTED]; -+}; -+ -+ -+struct rwnx_radar { -+ struct rwnx_radar_pulses pulses[RWNX_RADAR_LAST]; -+ struct dfs_pattern_detector *dpd[RWNX_RADAR_LAST]; -+ struct rwnx_radar_detected detected[RWNX_RADAR_LAST]; -+ struct work_struct detection_work; /* Work used to process radar pulses */ -+ spinlock_t lock; /* lock for pulses processing */ -+ -+ /* In softmac cac is handled by mac80211 */ -+#ifdef CONFIG_RWNX_FULLMAC -+ struct delayed_work cac_work; /* Work used to handle CAC */ -+ struct rwnx_vif *cac_vif; /* vif on which we started CAC */ -+#endif -+}; -+ -+bool rwnx_radar_detection_init(struct rwnx_radar *radar); -+void rwnx_radar_detection_deinit(struct rwnx_radar *radar); -+bool rwnx_radar_set_domain(struct rwnx_radar *radar, -+ enum nl80211_dfs_regions region); -+void rwnx_radar_detection_enable(struct rwnx_radar *radar, u8 enable, u8 chain); -+bool rwnx_radar_detection_is_enable(struct rwnx_radar *radar, u8 chain); -+void rwnx_radar_start_cac(struct rwnx_radar *radar, u32 cac_time_ms, -+ struct rwnx_vif *vif); -+void rwnx_radar_cancel_cac(struct rwnx_radar *radar); -+void rwnx_radar_detection_enable_on_cur_channel(struct rwnx_hw *rwnx_hw); -+int rwnx_radar_dump_pattern_detector(char *buf, size_t len, -+ struct rwnx_radar *radar, u8 chain); -+int rwnx_radar_dump_radar_detected(char *buf, size_t len, -+ struct rwnx_radar *radar, u8 chain); -+ -+#else -+ -+struct rwnx_radar { -+}; -+ -+static inline bool rwnx_radar_detection_init(struct rwnx_radar *radar) -+{return true; } -+ -+static inline void rwnx_radar_detection_deinit(struct rwnx_radar *radar) -+{} -+ -+static inline bool rwnx_radar_set_domain(struct rwnx_radar *radar, -+ enum nl80211_dfs_regions region) -+{return true; } -+ -+static inline void rwnx_radar_detection_enable(struct rwnx_radar *radar, -+ u8 enable, u8 chain) -+{} -+ -+static inline bool rwnx_radar_detection_is_enable(struct rwnx_radar *radar, -+ u8 chain) -+{return false; } -+ -+static inline void rwnx_radar_start_cac(struct rwnx_radar *radar, -+ u32 cac_time_ms, struct rwnx_vif *vif) -+{} -+ -+static inline void rwnx_radar_cancel_cac(struct rwnx_radar *radar) -+{} -+ -+static inline void rwnx_radar_detection_enable_on_cur_channel(struct rwnx_hw *rwnx_hw) -+{} -+ -+static inline int rwnx_radar_dump_pattern_detector(char *buf, size_t len, -+ struct rwnx_radar *radar, -+ u8 chain) -+{return 0; } -+ -+static inline int rwnx_radar_dump_radar_detected(char *buf, size_t len, -+ struct rwnx_radar *radar, -+ u8 chain) -+{return 0; } -+ -+#endif /* CONFIG_RWNX_RADAR */ -+ -+#endif // _RWNX_RADAR_H_ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_rx.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_rx.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_rx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_rx.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,2501 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_rx.c -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+#include -+#include -+#include -+#include -+ -+#include "rwnx_defs.h" -+#include "rwnx_rx.h" -+#include "rwnx_tx.h" -+#include "rwnx_prof.h" -+#include "ipc_host.h" -+#include "rwnx_events.h" -+#include "rwnx_compat.h" -+#include "aicwf_txrxif.h" -+#ifdef AICWF_ARP_OFFLOAD -+#include -+#include -+#include "rwnx_msg_tx.h" -+#endif -+ -+#ifndef IEEE80211_MAX_CHAINS -+#define IEEE80211_MAX_CHAINS 4 -+#endif -+ -+u8 dhcped; // = 0; -+ -+u16 tx_legrates_lut_rate[] = { -+ 10, -+ 20, -+ 55, -+ 110, -+ 60, -+ 90, -+ 120, -+ 180, -+ 240, -+ 360, -+ 480, -+ 540 -+}; -+ -+ -+u16 legrates_lut_rate[] = { -+ 10, -+ 20, -+ 55, -+ 110, -+ 0, -+ 0, -+ 0, -+ 0, -+ 480, -+ 240, -+ 120, -+ 60, -+ 540, -+ 360, -+ 180, -+ 90 -+}; -+ -+ -+const u8 legrates_lut[] = { -+ 0, /* 0 */ -+ 1, /* 1 */ -+ 2, /* 2 */ -+ 3, /* 3 */ -+ -1, /* 4 */ -+ -1, /* 5 */ -+ -1, /* 6 */ -+ -1, /* 7 */ -+ 10, /* 8 */ -+ 8, /* 9 */ -+ 6, /* 10 */ -+ 4, /* 11 */ -+ 11, /* 12 */ -+ 9, /* 13 */ -+ 7, /* 14 */ -+ 5 /* 15 */ -+}; -+ -+struct vendor_radiotap_hdr { -+ u8 oui[3]; -+ u8 subns; -+ u16 len; -+ u8 data[]; -+}; -+ -+/** -+ * rwnx_rx_get_vif - Return pointer to the destination vif -+ * -+ * @rwnx_hw: main driver data -+ * @vif_idx: vif index present in rx descriptor -+ * -+ * Select the vif that should receive this frame. Returns NULL if the destination -+ * vif is not active or vif is not specified in the descriptor. -+ */ -+static inline -+struct rwnx_vif *rwnx_rx_get_vif(struct rwnx_hw *rwnx_hw, int vif_idx) -+{ -+ struct rwnx_vif *rwnx_vif = NULL; -+ -+ if (vif_idx < NX_VIRT_DEV_MAX) { -+ rwnx_vif = rwnx_hw->vif_table[vif_idx]; -+ -+ if(!rwnx_vif){ -+ AICWFDBG(LOGERROR, "%s rwnx_hw->vif_table[%d] NULL\r\n", __func__, vif_idx); -+ return NULL; -+ }else if(!rwnx_vif->up){ -+ AICWFDBG(LOGERROR, "%s rwnx_hw->vif_table[%d] is down\r\n", __func__, vif_idx); -+ return NULL; -+ } -+ } -+ -+ return rwnx_vif; -+} -+ -+/** -+ * rwnx_rx_vector_convert - Convert a legacy RX vector into a new RX vector format -+ * -+ * @rwnx_hw: main driver data. -+ * @rx_vect1: Rx vector 1 descriptor of the received frame. -+ * @rx_vect2: Rx vector 2 descriptor of the received frame. -+ */ -+static void rwnx_rx_vector_convert(struct rwnx_hw *rwnx_hw, -+ struct rx_vector_1 *rx_vect1, -+ struct rx_vector_2 *rx_vect2) -+{ -+ struct rx_vector_1_old rx_vect1_leg; -+ struct rx_vector_2_old rx_vect2_leg; -+ u32_l phy_vers = rwnx_hw->version_cfm.version_phy_2; -+ -+ // Check if we need to do the conversion. Only if old modem is used -+ if (__MDM_MAJOR_VERSION(phy_vers) > 0) { -+ rx_vect1->rssi1 = rx_vect1->rssi_leg; -+ return; -+ } -+ -+ // Copy the received vector locally -+ memcpy(&rx_vect1_leg, rx_vect1, sizeof(struct rx_vector_1_old)); -+ -+ // Reset it -+ memset(rx_vect1, 0, sizeof(struct rx_vector_1)); -+ -+ // Perform the conversion -+ rx_vect1->format_mod = rx_vect1_leg.format_mod; -+ rx_vect1->ch_bw = rx_vect1_leg.ch_bw; -+ rx_vect1->antenna_set = rx_vect1_leg.antenna_set; -+ rx_vect1->leg_length = rx_vect1_leg.leg_length; -+ rx_vect1->leg_rate = rx_vect1_leg.leg_rate; -+ rx_vect1->rssi1 = rx_vect1_leg.rssi1; -+ -+ switch (rx_vect1->format_mod) { -+ case FORMATMOD_NON_HT: -+ case FORMATMOD_NON_HT_DUP_OFDM: -+ rx_vect1->leg.lsig_valid = rx_vect1_leg.lsig_valid; -+ rx_vect1->leg.chn_bw_in_non_ht = rx_vect1_leg.num_extn_ss; -+ rx_vect1->leg.dyn_bw_in_non_ht = rx_vect1_leg.dyn_bw; -+ break; -+ case FORMATMOD_HT_MF: -+ case FORMATMOD_HT_GF: -+ rx_vect1->ht.aggregation = rx_vect1_leg.aggregation; -+ rx_vect1->ht.fec = rx_vect1_leg.fec_coding; -+ rx_vect1->ht.lsig_valid = rx_vect1_leg.lsig_valid; -+ rx_vect1->ht.length = rx_vect1_leg.ht_length; -+ rx_vect1->ht.mcs = rx_vect1_leg.mcs; -+ rx_vect1->ht.num_extn_ss = rx_vect1_leg.num_extn_ss; -+ rx_vect1->ht.short_gi = rx_vect1_leg.short_gi; -+ rx_vect1->ht.smoothing = rx_vect1_leg.smoothing; -+ rx_vect1->ht.sounding = rx_vect1_leg.sounding; -+ rx_vect1->ht.stbc = rx_vect1_leg.stbc; -+ break; -+ case FORMATMOD_VHT: -+ rx_vect1->vht.beamformed = !rx_vect1_leg.smoothing; -+ rx_vect1->vht.fec = rx_vect1_leg.fec_coding; -+ rx_vect1->vht.length = rx_vect1_leg.ht_length | rx_vect1_leg._ht_length << 8; -+ rx_vect1->vht.mcs = rx_vect1_leg.mcs & 0x0F; -+ rx_vect1->vht.nss = rx_vect1_leg.stbc ? rx_vect1_leg.n_sts/2 : rx_vect1_leg.n_sts; -+ rx_vect1->vht.doze_not_allowed = rx_vect1_leg.doze_not_allowed; -+ rx_vect1->vht.short_gi = rx_vect1_leg.short_gi; -+ rx_vect1->vht.sounding = rx_vect1_leg.sounding; -+ rx_vect1->vht.stbc = rx_vect1_leg.stbc; -+ rx_vect1->vht.group_id = rx_vect1_leg.group_id; -+ rx_vect1->vht.partial_aid = rx_vect1_leg.partial_aid; -+ rx_vect1->vht.first_user = rx_vect1_leg.first_user; -+ break; -+ } -+ -+ if (!rx_vect2) -+ return; -+ -+ // Copy the received vector 2 locally -+ memcpy(&rx_vect2_leg, rx_vect2, sizeof(struct rx_vector_2_old)); -+ -+ // Reset it -+ memset(rx_vect2, 0, sizeof(struct rx_vector_2)); -+ -+ rx_vect2->rcpi1 = rx_vect2_leg.rcpi; -+ rx_vect2->rcpi2 = rx_vect2_leg.rcpi; -+ rx_vect2->rcpi3 = rx_vect2_leg.rcpi; -+ rx_vect2->rcpi4 = rx_vect2_leg.rcpi; -+ -+ rx_vect2->evm1 = rx_vect2_leg.evm1; -+ rx_vect2->evm2 = rx_vect2_leg.evm2; -+ rx_vect2->evm3 = rx_vect2_leg.evm3; -+ rx_vect2->evm4 = rx_vect2_leg.evm4; -+} -+ -+/** -+ * rwnx_rx_statistic - save some statistics about received frames -+ * -+ * @rwnx_hw: main driver data. -+ * @hw_rxhdr: Rx Hardware descriptor of the received frame. -+ * @sta: STA that sent the frame. -+ */ -+static void rwnx_rx_statistic(struct rwnx_hw *rwnx_hw, struct hw_rxhdr *hw_rxhdr, -+ struct rwnx_sta *sta) -+{ -+#if 1//def CONFIG_RWNX_DEBUGFS -+ struct rwnx_stats *stats = &rwnx_hw->stats; -+ struct rwnx_rx_rate_stats *rate_stats = &sta->stats.rx_rate; -+ struct rx_vector_1 *rxvect = &hw_rxhdr->hwvect.rx_vect1; -+ int mpdu, ampdu, mpdu_prev, rate_idx; -+ -+ /* save complete hwvect */ -+ sta->stats.last_rx = hw_rxhdr->hwvect; -+ -+ /* update ampdu rx stats */ -+ mpdu = hw_rxhdr->hwvect.mpdu_cnt; -+ ampdu = hw_rxhdr->hwvect.ampdu_cnt; -+ mpdu_prev = stats->ampdus_rx_map[ampdu]; -+ -+ if (mpdu_prev < mpdu) { -+ stats->ampdus_rx_miss += mpdu - mpdu_prev - 1; -+ } else { -+ stats->ampdus_rx[mpdu_prev]++; -+ } -+ stats->ampdus_rx_map[ampdu] = mpdu; -+ -+ /* update rx rate statistic */ -+ if (!rate_stats->size) -+ return; -+ -+ if (rxvect->format_mod > FORMATMOD_NON_HT_DUP_OFDM) { -+ int mcs; -+ int bw = rxvect->ch_bw; -+ int sgi; -+ int nss; -+ switch (rxvect->format_mod) { -+ case FORMATMOD_HT_MF: -+ case FORMATMOD_HT_GF: -+ mcs = rxvect->ht.mcs % 8; -+ nss = rxvect->ht.mcs / 8; -+ sgi = rxvect->ht.short_gi; -+ rate_idx = N_CCK + N_OFDM + nss * 32 + mcs * 4 + bw * 2 + sgi; -+ break; -+ case FORMATMOD_VHT: -+ mcs = rxvect->vht.mcs; -+ nss = rxvect->vht.nss; -+ sgi = rxvect->vht.short_gi; -+ rate_idx = N_CCK + N_OFDM + N_HT + nss * 80 + mcs * 8 + bw * 2 + sgi; -+ break; -+ case FORMATMOD_HE_SU: -+ mcs = rxvect->he.mcs; -+ nss = rxvect->he.nss; -+ sgi = rxvect->he.gi_type; -+ rate_idx = N_CCK + N_OFDM + N_HT + N_VHT + nss * 144 + mcs * 12 + bw * 3 + sgi; -+ break; -+ default: -+ mcs = rxvect->he.mcs; -+ nss = rxvect->he.nss; -+ sgi = rxvect->he.gi_type; -+ rate_idx = N_CCK + N_OFDM + N_HT + N_VHT + N_HE_SU -+ + nss * 216 + mcs * 18 + rxvect->he.ru_size * 3 + sgi; -+ break; -+ } -+ } else { -+ int idx = legrates_lut[rxvect->leg_rate]; -+ if (idx < 4) { -+ rate_idx = idx * 2 + rxvect->pre_type; -+ } else { -+ rate_idx = N_CCK + idx - 4; -+ } -+ } -+ if (rate_idx < rate_stats->size) { -+ if (!rate_stats->table[rate_idx]) -+ rate_stats->rate_cnt++; -+ rate_stats->table[rate_idx]++; -+ rate_stats->cpt++; -+ } else { -+ wiphy_err(rwnx_hw->wiphy, "RX: Invalid index conversion => %d/%d\n", -+ rate_idx, rate_stats->size); -+ } -+#endif -+} -+ -+/** -+ * rwnx_rx_data_skb - Process one data frame -+ * -+ * @rwnx_hw: main driver data -+ * @rwnx_vif: vif that received the buffer -+ * @skb: skb received -+ * @rxhdr: HW rx descriptor -+ * @return: true if buffer has been forwarded to upper layer -+ * -+ * If buffer is amsdu , it is first split into a list of skb. -+ * Then each skb may be: -+ * - forwarded to upper layer -+ * - resent on wireless interface -+ * -+ * When vif is a STA interface, every skb is only forwarded to upper layer. -+ * When vif is an AP interface, multicast skb are forwarded and resent, whereas -+ * skb for other BSS's STA are only resent. -+ */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+#define RAISE_RX_SOFTIRQ() \ -+ cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) -+#endif /* LINUX_VERSION_CODE */ -+ -+void rwnx_rx_data_skb_resend(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct sk_buff *skb, struct hw_rxhdr *rxhdr) -+{ -+ struct sk_buff *rx_skb = skb; -+ const struct ethhdr *eth; -+ struct sk_buff *skb_copy; -+ -+ rx_skb->dev = rwnx_vif->ndev; -+ skb_reset_mac_header(rx_skb); -+ eth = eth_hdr(rx_skb); -+ -+ //printk("resend\n"); -+ /* resend pkt on wireless interface */ -+ /* always need to copy buffer when forward=0 to get enough headrom for tsdesc */ -+ skb_copy = skb_copy_expand(rx_skb, sizeof(struct rwnx_txhdr) + -+ RWNX_SWTXHDR_ALIGN_SZ + 3 + 24 + 8, 0, GFP_ATOMIC); -+ -+ if (skb_copy) { -+ int res; -+ skb_copy->protocol = htons(ETH_P_802_3); -+ skb_reset_network_header(skb_copy); -+ skb_reset_mac_header(skb_copy); -+ -+ rwnx_vif->is_resending = true; -+ res = dev_queue_xmit(skb_copy); -+ rwnx_vif->is_resending = false; -+ /* note: buffer is always consummed by dev_queue_xmit */ -+ if (res == NET_XMIT_DROP) { -+ rwnx_vif->net_stats.rx_dropped++; -+ rwnx_vif->net_stats.tx_dropped++; -+ } else if (res != NET_XMIT_SUCCESS) { -+ netdev_err(rwnx_vif->ndev, -+ "Failed to re-send buffer to driver (res=%d)", -+ res); -+ rwnx_vif->net_stats.tx_errors++; -+ } -+ } else { -+ netdev_err(rwnx_vif->ndev, "Failed to copy skb"); -+ } -+} -+ -+static void rwnx_rx_data_skb_forward(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct sk_buff *skb, struct hw_rxhdr *rxhdr) -+{ -+ struct sk_buff *rx_skb; -+ -+ rx_skb = skb; -+ rx_skb->dev = rwnx_vif->ndev; -+ skb_reset_mac_header(rx_skb); -+ -+ #ifdef CONFIG_BR_SUPPORT -+ void *br_port = NULL; -+ -+ if (1) {//(check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { -+ /* Insert NAT2.5 RX here! */ -+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) -+ br_port = rwnx_vif->ndev->br_port; -+ #else -+ rcu_read_lock(); -+ br_port = rcu_dereference(rwnx_vif->ndev->rx_handler_data); -+ rcu_read_unlock(); -+ #endif -+ -+ if (br_port) { -+ int nat25_handle_frame(struct rwnx_vif *vif, struct sk_buff *skb); -+ -+ if (nat25_handle_frame(rwnx_vif, rx_skb) == -1) { -+ /* priv->ext_stats.rx_data_drops++; */ -+ /* DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n"); */ -+ /* return FAIL; */ -+ -+ } -+ } -+ } -+ #endif /* CONFIG_BR_SUPPORT */ -+ -+ /* Update statistics */ -+ rwnx_vif->net_stats.rx_packets++; -+ rwnx_vif->net_stats.rx_bytes += rx_skb->len; -+ -+ //printk("forward\n"); -+ -+ rx_skb->protocol = eth_type_trans(rx_skb, rwnx_vif->ndev); -+ memset(rx_skb->cb, 0, sizeof(rx_skb->cb)); -+ REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_IEEE80211RX); -+ -+ #ifdef CONFIG_FILTER_TCP_ACK -+ filter_rx_tcp_ack(rwnx_hw,rx_skb->data, cpu_to_le16(rx_skb->len)); -+ #endif -+ -+ #ifdef CONFIG_RX_NETIF_RECV_SKB //modify by aic -+ local_bh_disable(); -+ netif_receive_skb(rx_skb); -+ local_bh_enable(); -+ #else -+ if (in_interrupt()) { -+ netif_rx(rx_skb); -+ } else { -+ /* -+ * If the receive is not processed inside an ISR, the softirqd must be woken explicitly to service the NET_RX_SOFTIRQ. -+ * * In 2.6 kernels, this is handledby netif_rx_ni(), but in earlier kernels, we need to do it manually. -+ */ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -+ netif_rx_ni(rx_skb); -+ #else -+ ulong flags; -+ netif_rx(rx_skb); -+ local_irq_save(flags); -+ RAISE_RX_SOFTIRQ(); -+ local_irq_restore(flags); -+ #endif -+ } -+ #endif -+ REG_SW_CLEAR_PROFILING(rwnx_hw, SW_PROF_IEEE80211RX); -+ -+ rwnx_hw->stats.last_rx = jiffies; -+} -+ -+ -+static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct sk_buff *skb, struct hw_rxhdr *rxhdr) -+{ -+ struct sk_buff_head list; -+ struct sk_buff *rx_skb; -+ bool amsdu = rxhdr->flags_is_amsdu; -+ u8 flags_dst_idx = rxhdr->flags_dst_idx; -+ bool resend = false, forward = true; -+ -+ skb->dev = rwnx_vif->ndev; -+ -+ __skb_queue_head_init(&list); -+ -+ if (amsdu) { -+ #if 1 -+ rwnx_rxdata_process_amsdu(rwnx_hw, skb, rxhdr->flags_vif_idx, &list); //rxhdr not used below since skb free! -+ #else -+ int count; -+ ieee80211_amsdu_to_8023s(skb, &list, rwnx_vif->ndev->dev_addr, -+ RWNX_VIF_TYPE(rwnx_vif), 0, NULL, NULL); -+ -+ count = skb_queue_len(&list); -+ if (count > ARRAY_SIZE(rwnx_hw->stats.amsdus_rx)) -+ count = ARRAY_SIZE(rwnx_hw->stats.amsdus_rx); -+ rwnx_hw->stats.amsdus_rx[count - 1]++; -+ #endif -+ } else { -+ rwnx_hw->stats.amsdus_rx[0]++; -+ __skb_queue_head(&list, skb); -+ } -+ -+ if (((RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP) || -+ (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP_VLAN) || -+ (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_GO)) && -+ !(rwnx_vif->ap.flags & RWNX_AP_ISOLATE)) { -+ const struct ethhdr *eth; -+ rx_skb = skb_peek(&list); -+ skb_reset_mac_header(rx_skb); -+ eth = eth_hdr(rx_skb); -+ -+ if (unlikely(is_multicast_ether_addr(eth->h_dest))) { -+ /* broadcast pkt need to be forwared to upper layer and resent -+ on wireless interface */ -+ resend = true; -+ } else { -+ /* unicast pkt for STA inside the BSS, no need to forward to upper -+ layer simply resend on wireless interface */ -+ if (flags_dst_idx != RWNX_INVALID_STA) { -+ struct rwnx_sta *sta = &rwnx_hw->sta_table[flags_dst_idx]; -+ if (sta->valid && (sta->vlan_idx == rwnx_vif->vif_index)) { -+ forward = false; -+ resend = true; -+ } -+ } -+ } -+ } else if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_MESH_POINT) { -+ const struct ethhdr *eth; -+ rx_skb = skb_peek(&list); -+ skb_reset_mac_header(rx_skb); -+ eth = eth_hdr(rx_skb); -+ -+ if (!is_multicast_ether_addr(eth->h_dest)) { -+ /* unicast pkt for STA inside the BSS, no need to forward to upper -+ layer simply resend on wireless interface */ -+ if (flags_dst_idx != RWNX_INVALID_STA) { -+ forward = false; -+ resend = true; -+ } -+ } -+ } -+ -+ while (!skb_queue_empty(&list)) { -+ rx_skb = __skb_dequeue(&list); -+ -+ /* resend pkt on wireless interface */ -+ if (resend) { -+ struct sk_buff *skb_copy; -+ /* always need to copy buffer when forward=0 to get enough headrom for tsdesc */ -+ skb_copy = skb_copy_expand(rx_skb, sizeof(struct rwnx_txhdr) + -+ RWNX_SWTXHDR_ALIGN_SZ + 3 + 24 + 8, 0, GFP_ATOMIC); -+ -+ if (skb_copy) { -+ int res; -+ skb_copy->protocol = htons(ETH_P_802_3); -+ skb_reset_network_header(skb_copy); -+ skb_reset_mac_header(skb_copy); -+ -+ rwnx_vif->is_resending = true; -+ res = dev_queue_xmit(skb_copy); -+ rwnx_vif->is_resending = false; -+ /* note: buffer is always consummed by dev_queue_xmit */ -+ if (res == NET_XMIT_DROP) { -+ rwnx_vif->net_stats.rx_dropped++; -+ rwnx_vif->net_stats.tx_dropped++; -+ } else if (res != NET_XMIT_SUCCESS) { -+ netdev_err(rwnx_vif->ndev, -+ "Failed to re-send buffer to driver (res=%d)", -+ res); -+ rwnx_vif->net_stats.tx_errors++; -+ } -+ } else { -+ netdev_err(rwnx_vif->ndev, "Failed to copy skb"); -+ } -+ } -+ -+ /* forward pkt to upper layer */ -+ if (forward) { -+ #ifdef CONFIG_BR_SUPPORT -+ void *br_port = NULL; -+ -+ if (1) {//(check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { -+ /* Insert NAT2.5 RX here! */ -+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) -+ br_port = rwnx_vif->ndev->br_port; -+ #else -+ rcu_read_lock(); -+ br_port = rcu_dereference(rwnx_vif->ndev->rx_handler_data); -+ rcu_read_unlock(); -+ #endif -+ -+ if (br_port) { -+ int nat25_handle_frame(struct rwnx_vif *vif, struct sk_buff *skb); -+ -+ if (nat25_handle_frame(rwnx_vif, rx_skb) == -1) { -+ /* priv->ext_stats.rx_data_drops++; */ -+ /* DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n"); */ -+ /* return FAIL; */ -+ } -+ } -+ } -+ #endif /* CONFIG_BR_SUPPORT */ -+ -+ /* Update statistics */ -+ rwnx_vif->net_stats.rx_packets++; -+ rwnx_vif->net_stats.rx_bytes += rx_skb->len; -+ -+ rx_skb->protocol = eth_type_trans(rx_skb, rwnx_vif->ndev); -+#ifdef AICWF_ARP_OFFLOAD -+ if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) -+ arpoffload_proc(rx_skb, rwnx_vif); -+#endif -+ memset(rx_skb->cb, 0, sizeof(rx_skb->cb)); -+ REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_IEEE80211RX); -+ -+#ifdef CONFIG_FILTER_TCP_ACK -+ filter_rx_tcp_ack(rwnx_hw,rx_skb->data, cpu_to_le16(rx_skb->len)); -+#endif -+ -+ #ifdef CONFIG_RX_NETIF_RECV_SKB //modify by aic -+ local_bh_disable(); -+ netif_receive_skb(rx_skb); -+ local_bh_enable(); -+ #else -+ if (in_interrupt()) { -+ netif_rx(rx_skb); -+ } else { -+ /* -+ * If the receive is not processed inside an ISR, the softirqd must be woken explicitly to service the NET_RX_SOFTIRQ. -+ * * In 2.6 kernels, this is handledby netif_rx_ni(), but in earlier kernels, we need to do it manually. -+ */ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -+ netif_rx_ni(rx_skb); -+ #else -+ ulong flags; -+ netif_rx(rx_skb); -+ local_irq_save(flags); -+ RAISE_RX_SOFTIRQ(); -+ local_irq_restore(flags); -+ #endif -+ } -+ #endif -+ REG_SW_CLEAR_PROFILING(rwnx_hw, SW_PROF_IEEE80211RX); -+ -+ rwnx_hw->stats.last_rx = jiffies; -+ } -+ } -+ -+ return forward; -+} -+ -+#ifdef CONFIG_HE_FOR_OLD_KERNEL -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) -+const u8 *cfg80211_find_ie_match(u8 eid, const u8 *ies, int len, -+ const u8 *match, int match_len, -+ int match_offset) -+{ -+ const struct element *elem; -+ -+ /* match_offset can't be smaller than 2, unless match_len is -+ * zero, in which case match_offset must be zero as well. -+ */ -+ if (WARN_ON((match_len && match_offset < 2) || -+ (!match_len && match_offset))) -+ return NULL; -+ -+ for_each_element_id(elem, eid, ies, len) { -+ if (elem->datalen >= match_offset - 2 + match_len && -+ !memcmp(elem->data + match_offset - 2, match, match_len)) -+ return (void *)elem; -+ } -+ -+ return NULL; -+} -+#endif -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) -+static inline const u8 *cfg80211_find_ext_ie(u8 ext_eid, const u8* ies, int len) -+{ -+ return cfg80211_find_ie_match(WLAN_EID_EXTENSION, ies, len, -+ &ext_eid, 1, 2); -+} -+#endif -+#endif -+ -+ -+/** -+ * rwnx_rx_mgmt - Process one 802.11 management frame -+ * -+ * @rwnx_hw: main driver data -+ * @rwnx_vif: vif to upload the buffer to -+ * @skb: skb received -+ * @rxhdr: HW rx descriptor -+ * -+ * Forward the management frame to a given interface. -+ */ -+static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct sk_buff *skb, struct hw_rxhdr *hw_rxhdr) -+{ -+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; -+ struct rx_vector_1 *rxvect = &hw_rxhdr->hwvect.rx_vect1; -+ -+ //printk("rwnx_rx_mgmt\n"); -+ -+#if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL) -+ struct aic_sta *sta = &rwnx_hw->aic_table[rwnx_vif->ap.aic_index]; -+ const u8* ie; -+ u32 len; -+ -+ if(skb->data[0]!=0x80) -+ AICWFDBG(LOGDEBUG,"rxmgmt:%x,%x\n", skb->data[0], skb->data[1]); -+ -+ if (ieee80211_is_assoc_req(mgmt->frame_control) && rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) { -+ printk("ASSOC_REQ: sta_idx %d MAC %pM\n", rwnx_vif->ap.aic_index, mgmt->sa); -+ sta->sta_idx = rwnx_vif->ap.aic_index; -+ len = skb->len - (mgmt->u.assoc_req.variable - skb->data); -+ -+ #ifdef CONFIG_HE_FOR_OLD_KERNEL -+ struct ieee80211_he_cap_elem *he; -+ ie = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, mgmt->u.assoc_req.variable, len); -+ if (ie && ie[1] >= sizeof(*he) + 1) { -+ printk("assoc_req: find he\n"); -+ sta->he = true; -+ } -+ else { -+ printk("assoc_req: no find he\n"); -+ sta->he = false; -+ } -+ #endif -+ -+ #ifdef CONFIG_VHT_FOR_OLD_KERNEL -+ struct ieee80211_vht_cap *vht; -+ ie = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, mgmt->u.assoc_req.variable, len); -+ if (ie && ie[1] >= sizeof(*vht)) { -+ printk("assoc_req: find vht\n"); -+ sta->vht = true; -+ } else { -+ printk("assoc_req: no find vht\n"); -+ sta->vht = false; -+ } -+ #endif -+ } -+#endif -+ -+ if (ieee80211_is_mgmt(mgmt->frame_control) && -+ (skb->len <= 24 || skb->len > 768)) { -+ printk("mgmt err\n"); -+ return; -+ } -+ if (ieee80211_is_beacon(mgmt->frame_control)) { -+ if ((RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_MESH_POINT) && -+ hw_rxhdr->flags_new_peer) { -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) -+#ifdef CONFIG_GKI -+ rwnx_cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa, -+ mgmt->u.beacon.variable, -+ skb->len - offsetof(struct ieee80211_mgmt, -+ u.beacon.variable), -+ GFP_ATOMIC); -+#else -+ cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa, -+ mgmt->u.beacon.variable, -+ skb->len - offsetof(struct ieee80211_mgmt, -+ u.beacon.variable), -+ GFP_ATOMIC); -+#endif -+#else -+ -+#ifdef CONFIG_GKI -+ /* TODO: the value of parameter sig_dbm need to be confirmed */ -+ rwnx_cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa, -+ mgmt->u.beacon.variable, -+ skb->len - offsetof(struct ieee80211_mgmt, -+ u.beacon.variable), -+ rxvect->rssi1, GFP_ATOMIC); -+#else -+ /* TODO: the value of parameter sig_dbm need to be confirmed */ -+ cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa, -+ mgmt->u.beacon.variable, -+ skb->len - offsetof(struct ieee80211_mgmt, -+ u.beacon.variable), -+ rxvect->rssi1, GFP_ATOMIC); -+#endif -+ -+#endif -+ } else { -+#ifdef CONFIG_GKI -+ rwnx_cfg80211_report_obss_beacon(rwnx_hw->wiphy, skb->data, skb->len, -+ hw_rxhdr->phy_info.phy_prim20_freq, -+ rxvect->rssi1); -+#else -+ cfg80211_report_obss_beacon(rwnx_hw->wiphy, skb->data, skb->len, -+ hw_rxhdr->phy_info.phy_prim20_freq, -+ rxvect->rssi1); -+#endif -+ } -+ } else if ((ieee80211_is_deauth(mgmt->frame_control) || -+ ieee80211_is_disassoc(mgmt->frame_control)) && -+ (mgmt->u.deauth.reason_code == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA || -+ mgmt->u.deauth.reason_code == WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA)) { -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) // TODO: process unprot mgmt -+ cfg80211_rx_unprot_mlme_mgmt(rwnx_vif->ndev, skb->data, skb->len); -+ #endif -+ } else if ((RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION) && -+ (ieee80211_is_action(mgmt->frame_control) && -+ (mgmt->u.action.category == 6))) { -+ struct cfg80211_ft_event_params ft_event; -+ ft_event.target_ap = (uint8_t *)&mgmt->u.action + ETH_ALEN + 2; -+ ft_event.ies = (uint8_t *)&mgmt->u.action + ETH_ALEN * 2 + 2; -+ ft_event.ies_len = skb->len - (ft_event.ies - (uint8_t *)mgmt); -+ ft_event.ric_ies = NULL; -+ ft_event.ric_ies_len = 0; -+ cfg80211_ft_event(rwnx_vif->ndev, &ft_event); -+ } else { -+ cfg80211_rx_mgmt(&rwnx_vif->wdev, hw_rxhdr->phy_info.phy_prim20_freq, -+ rxvect->rssi1, skb->data, skb->len, 0); -+ } -+} -+ -+/** -+ * rwnx_rx_mgmt_any - Process one 802.11 management frame -+ * -+ * @rwnx_hw: main driver data -+ * @skb: skb received -+ * @rxhdr: HW rx descriptor -+ * -+ * Process the management frame and free the corresponding skb. -+ * If vif is not specified in the rx descriptor, the the frame is uploaded -+ * on all active vifs. -+ */ -+static void rwnx_rx_mgmt_any(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, -+ struct hw_rxhdr *hw_rxhdr) -+{ -+ struct rwnx_vif *rwnx_vif; -+ int vif_idx = hw_rxhdr->flags_vif_idx; -+#ifdef CREATE_TRACE_POINTS -+ trace_mgmt_rx(hw_rxhdr->phy_info.phy_prim20_freq, vif_idx, -+ hw_rxhdr->flags_sta_idx, (struct ieee80211_mgmt *)skb->data); -+#endif -+ if (vif_idx == RWNX_INVALID_VIF) { -+ list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) { -+ if (!rwnx_vif->up) -+ continue; -+ rwnx_rx_mgmt(rwnx_hw, rwnx_vif, skb, hw_rxhdr); -+ } -+ } else { -+ rwnx_vif = rwnx_rx_get_vif(rwnx_hw, vif_idx); -+ if (rwnx_vif) -+ rwnx_rx_mgmt(rwnx_hw, rwnx_vif, skb, hw_rxhdr); -+ } -+ -+ dev_kfree_skb(skb); -+} -+ -+/** -+ * rwnx_rx_rtap_hdrlen - Return radiotap header length -+ * -+ * @rxvect: Rx vector used to fill the radiotap header -+ * @has_vend_rtap: boolean indicating if vendor specific data is present -+ * -+ * Compute the length of the radiotap header based on @rxvect and vendor -+ * specific data (if any). -+ */ -+static u8 rwnx_rx_rtap_hdrlen(struct rx_vector_1 *rxvect, -+ bool has_vend_rtap) -+{ -+ u8 rtap_len; -+ -+ /* Compute radiotap header length */ -+ rtap_len = sizeof(struct ieee80211_radiotap_header) + 8; -+ -+ // Check for multiple antennas -+ if (hweight32(rxvect->antenna_set) > 1) -+ // antenna and antenna signal fields -+ rtap_len += 4 * hweight8(rxvect->antenna_set); -+ -+ // TSFT -+ if (!has_vend_rtap) { -+ rtap_len = ALIGN(rtap_len, 8); -+ rtap_len += 8; -+ } -+ -+ // IEEE80211_HW_SIGNAL_DBM -+ rtap_len++; -+ -+ // Check if single antenna -+ if (hweight32(rxvect->antenna_set) == 1) -+ rtap_len++; //Single antenna -+ -+ // padding for RX FLAGS -+ rtap_len = ALIGN(rtap_len, 2); -+ -+ // Check for HT frames -+ if ((rxvect->format_mod == FORMATMOD_HT_MF) || -+ (rxvect->format_mod == FORMATMOD_HT_GF)) -+ rtap_len += 3; -+ -+ // Check for AMPDU -+ if (!(has_vend_rtap) && ((rxvect->format_mod >= FORMATMOD_VHT) || -+ ((rxvect->format_mod > FORMATMOD_NON_HT_DUP_OFDM) && -+ (rxvect->ht.aggregation)))) { -+ rtap_len = ALIGN(rtap_len, 4); -+ rtap_len += 8; -+ } -+ -+ // Check for VHT frames -+ if (rxvect->format_mod == FORMATMOD_VHT) { -+ rtap_len = ALIGN(rtap_len, 2); -+ rtap_len += 12; -+ } -+ -+ // Check for HE frames -+ if (rxvect->format_mod == FORMATMOD_HE_SU) { -+ rtap_len = ALIGN(rtap_len, 2); -+ rtap_len += sizeof(struct ieee80211_radiotap_he); -+ } -+ -+ // Check for multiple antennas -+ if (hweight32(rxvect->antenna_set) > 1) { -+ // antenna and antenna signal fields -+ rtap_len += 2 * hweight8(rxvect->antenna_set); -+ } -+ -+ // Check for vendor specific data -+ if (has_vend_rtap) { -+ /* vendor presence bitmap */ -+ rtap_len += 4; -+ /* alignment for fixed 6-byte vendor data header */ -+ rtap_len = ALIGN(rtap_len, 2); -+ } -+ -+ return rtap_len; -+} -+ -+/** -+ * rwnx_rx_add_rtap_hdr - Add radiotap header to sk_buff -+ * -+ * @rwnx_hw: main driver data -+ * @skb: skb received (will include the radiotap header) -+ * @rxvect: Rx vector -+ * @phy_info: Information regarding the phy -+ * @hwvect: HW Info (NULL if vendor specific data is available) -+ * @rtap_len: Length of the radiotap header -+ * @vend_rtap_len: radiotap vendor length (0 if not present) -+ * @vend_it_present: radiotap vendor present -+ * -+ * Builds a radiotap header and add it to @skb. -+ */ -+static void rwnx_rx_add_rtap_hdr(struct rwnx_hw *rwnx_hw, -+ struct sk_buff *skb, -+ struct rx_vector_1 *rxvect, -+ struct phy_channel_info_desc *phy_info, -+ struct hw_vect *hwvect, -+ int rtap_len, -+ u8 vend_rtap_len, -+ u32 vend_it_present) -+{ -+ struct ieee80211_radiotap_header *rtap; -+ u8 *pos, rate_idx; -+ __le32 *it_present; -+ u32 it_present_val = 0; -+ bool fec_coding = false; -+ bool short_gi = false; -+ bool stbc = false; -+ bool aggregation = false; -+ -+ rtap = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); -+ memset((u8 *) rtap, 0, rtap_len); -+ -+ rtap->it_version = 0; -+ rtap->it_pad = 0; -+ rtap->it_len = cpu_to_le16(rtap_len + vend_rtap_len); -+ -+ it_present = &rtap->it_present; -+ -+ // Check for multiple antennas -+ if (hweight32(rxvect->antenna_set) > 1) { -+ int chain; -+ unsigned long chains = rxvect->antenna_set; -+ -+ for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) { -+ it_present_val |= -+ BIT(IEEE80211_RADIOTAP_EXT) | -+ BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE); -+ put_unaligned_le32(it_present_val, it_present); -+ it_present++; -+ it_present_val = BIT(IEEE80211_RADIOTAP_ANTENNA) | -+ BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL); -+ } -+ } -+ -+ // Check if vendor specific data is present -+ if (vend_rtap_len) { -+ it_present_val |= BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE) | -+ BIT(IEEE80211_RADIOTAP_EXT); -+ put_unaligned_le32(it_present_val, it_present); -+ it_present++; -+ it_present_val = vend_it_present; -+ } -+ -+ put_unaligned_le32(it_present_val, it_present); -+ pos = (void *)(it_present + 1); -+ -+ // IEEE80211_RADIOTAP_TSFT -+ if (hwvect) { -+ rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); -+ // padding -+ while ((pos - (u8 *)rtap) & 7) -+ *pos++ = 0; -+ put_unaligned_le64((((u64)le32_to_cpu(hwvect->tsf_hi) << 32) + -+ (u64)le32_to_cpu(hwvect->tsf_lo)), pos); -+ pos += 8; -+ } -+ -+ // IEEE80211_RADIOTAP_FLAGS -+ rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_FLAGS); -+ if (hwvect && (!hwvect->frm_successful_rx)) -+ *pos |= IEEE80211_RADIOTAP_F_BADFCS; -+ if (!rxvect->pre_type -+ && (rxvect->format_mod <= FORMATMOD_NON_HT_DUP_OFDM)) -+ *pos |= IEEE80211_RADIOTAP_F_SHORTPRE; -+ pos++; -+ -+ // IEEE80211_RADIOTAP_RATE -+ // check for HT, VHT or HE frames -+ if (rxvect->format_mod >= FORMATMOD_HE_SU) { -+ rate_idx = rxvect->he.mcs; -+ fec_coding = rxvect->he.fec; -+ stbc = rxvect->he.stbc; -+ aggregation = true; -+ *pos = 0; -+ } else if (rxvect->format_mod == FORMATMOD_VHT) { -+ rate_idx = rxvect->vht.mcs; -+ fec_coding = rxvect->vht.fec; -+ short_gi = rxvect->vht.short_gi; -+ stbc = rxvect->vht.stbc; -+ aggregation = true; -+ *pos = 0; -+ } else if (rxvect->format_mod > FORMATMOD_NON_HT_DUP_OFDM) { -+ rate_idx = rxvect->ht.mcs; -+ fec_coding = rxvect->ht.fec; -+ short_gi = rxvect->ht.short_gi; -+ stbc = rxvect->ht.stbc; -+ aggregation = rxvect->ht.aggregation; -+ *pos = 0; -+ } else { -+ struct ieee80211_supported_band *band = -+ rwnx_hw->wiphy->bands[phy_info->phy_band]; -+ rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); -+ BUG_ON((rate_idx = legrates_lut[rxvect->leg_rate]) == -1); -+ if (phy_info->phy_band == NL80211_BAND_5GHZ) -+ rate_idx -= 4; /* rwnx_ratetable_5ghz[0].hw_value == 4 */ -+ *pos = DIV_ROUND_UP(band->bitrates[rate_idx].bitrate, 5); -+ } -+ pos++; -+ -+ // IEEE80211_RADIOTAP_CHANNEL -+ rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_CHANNEL); -+ put_unaligned_le16(phy_info->phy_prim20_freq, pos); -+ pos += 2; -+ -+ if (phy_info->phy_band == NL80211_BAND_5GHZ) -+ put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, pos); -+ else if (rxvect->format_mod > FORMATMOD_NON_HT_DUP_OFDM) -+ put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, pos); -+ else -+ put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, pos); -+ pos += 2; -+ -+ if (hweight32(rxvect->antenna_set) == 1) { -+ // IEEE80211_RADIOTAP_DBM_ANTSIGNAL -+ rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); -+ *pos++ = rxvect->rssi1; -+ -+ // IEEE80211_RADIOTAP_ANTENNA -+ rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_ANTENNA); -+ *pos++ = rxvect->antenna_set; -+ } -+ -+ // IEEE80211_RADIOTAP_LOCK_QUALITY is missing -+ // IEEE80211_RADIOTAP_DB_ANTNOISE is missing -+ -+ // IEEE80211_RADIOTAP_RX_FLAGS -+ rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RX_FLAGS); -+ // 2 byte alignment -+ if ((pos - (u8 *)rtap) & 1) -+ *pos++ = 0; -+ put_unaligned_le16(0, pos); -+ //Right now, we only support fcs error (no RX_FLAG_FAILED_PLCP_CRC) -+ pos += 2; -+ -+ // Check if HT -+ if ((rxvect->format_mod == FORMATMOD_HT_MF) -+ || (rxvect->format_mod == FORMATMOD_HT_GF)) { -+ rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS); -+ *pos++ = IEEE80211_RADIOTAP_MCS_HAVE_MCS | -+ IEEE80211_RADIOTAP_MCS_HAVE_GI | -+ IEEE80211_RADIOTAP_MCS_HAVE_BW; -+ *pos = 0; -+ if (short_gi) -+ *pos |= IEEE80211_RADIOTAP_MCS_SGI; -+ if (rxvect->ch_bw == PHY_CHNL_BW_40) -+ *pos |= IEEE80211_RADIOTAP_MCS_BW_40; -+ if (rxvect->format_mod == FORMATMOD_HT_GF) -+ *pos |= IEEE80211_RADIOTAP_MCS_FMT_GF; -+ if (fec_coding) -+ *pos |= IEEE80211_RADIOTAP_MCS_FEC_LDPC; -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+ *pos++ |= stbc << 5; -+ #else -+ *pos++ |= stbc << IEEE80211_RADIOTAP_MCS_STBC_SHIFT; -+ #endif -+ *pos++ = rate_idx; -+ } -+ -+ // check for HT or VHT frames -+ if (aggregation && hwvect) { -+ // 4 byte alignment -+ while ((pos - (u8 *)rtap) & 3) -+ pos++; -+ rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_AMPDU_STATUS); -+ put_unaligned_le32(hwvect->ampdu_cnt, pos); -+ pos += 4; -+ put_unaligned_le32(0, pos); -+ pos += 4; -+ } -+ -+ // Check for VHT frames -+ if (rxvect->format_mod == FORMATMOD_VHT) { -+ u16 vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | -+ IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; -+ u8 vht_nss = rxvect->vht.nss + 1; -+ -+ rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT); -+ -+ if ((rxvect->ch_bw == PHY_CHNL_BW_160) -+ && phy_info->phy_center2_freq) -+ vht_details &= ~IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; -+ put_unaligned_le16(vht_details, pos); -+ pos += 2; -+ -+ // flags -+ if (short_gi) -+ *pos |= IEEE80211_RADIOTAP_VHT_FLAG_SGI; -+ if (stbc) -+ *pos |= IEEE80211_RADIOTAP_VHT_FLAG_STBC; -+ pos++; -+ -+ // bandwidth -+ if (rxvect->ch_bw == PHY_CHNL_BW_40) -+ *pos++ = 1; -+ if (rxvect->ch_bw == PHY_CHNL_BW_80) -+ *pos++ = 4; -+ else if ((rxvect->ch_bw == PHY_CHNL_BW_160) -+ && phy_info->phy_center2_freq) -+ *pos++ = 0; //80P80 -+ else if (rxvect->ch_bw == PHY_CHNL_BW_160) -+ *pos++ = 11; -+ else // 20 MHz -+ *pos++ = 0; -+ -+ // MCS/NSS -+ *pos = (rate_idx << 4) | vht_nss; -+ pos += 4; -+ if (fec_coding) -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0) -+ *pos |= 0x01; -+ #else -+ *pos |= IEEE80211_RADIOTAP_CODING_LDPC_USER0; -+ #endif -+ pos++; -+ // group ID -+ pos++; -+ // partial_aid -+ pos += 2; -+ } -+ -+ // Check for HE frames -+ if (rxvect->format_mod == FORMATMOD_HE_SU) { -+ struct ieee80211_radiotap_he he; -+ #define HE_PREP(f, val) cpu_to_le16(FIELD_PREP(IEEE80211_RADIOTAP_HE_##f, val)) -+ #define D1_KNOWN(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_##f##_KNOWN) -+ #define D2_KNOWN(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_##f##_KNOWN) -+ -+ he.data1 = D1_KNOWN(DATA_MCS) | D1_KNOWN(BSS_COLOR) | D1_KNOWN(BEAM_CHANGE) | -+ D1_KNOWN(UL_DL) | D1_KNOWN(CODING) | D1_KNOWN(STBC) | -+ D1_KNOWN(BW_RU_ALLOC) | D1_KNOWN(DOPPLER) | D1_KNOWN(DATA_DCM); -+ he.data2 = D2_KNOWN(GI) | D2_KNOWN(TXBF); -+ -+ if (stbc) { -+ he.data6 |= HE_PREP(DATA6_NSTS, 2); -+ he.data3 |= HE_PREP(DATA3_STBC, 1); -+ } else { -+ he.data6 |= HE_PREP(DATA6_NSTS, rxvect->he.nss); -+ } -+ -+ he.data3 |= HE_PREP(DATA3_BSS_COLOR, rxvect->he.bss_color); -+ he.data3 |= HE_PREP(DATA3_BEAM_CHANGE, rxvect->he.beam_change); -+ he.data3 |= HE_PREP(DATA3_UL_DL, rxvect->he.uplink_flag); -+ he.data3 |= HE_PREP(DATA3_BSS_COLOR, rxvect->he.bss_color); -+ he.data3 |= HE_PREP(DATA3_DATA_MCS, rxvect->he.mcs); -+ he.data3 |= HE_PREP(DATA3_DATA_DCM, rxvect->he.dcm); -+ he.data3 |= HE_PREP(DATA3_CODING, rxvect->he.fec); -+ -+ he.data5 |= HE_PREP(DATA5_GI, rxvect->he.gi_type); -+ he.data5 |= HE_PREP(DATA5_TXBF, rxvect->he.beamformed); -+ he.data5 |= HE_PREP(DATA5_LTF_SIZE, rxvect->he.he_ltf_type + 1); -+ -+ switch (rxvect->ch_bw) { -+ case PHY_CHNL_BW_20: -+ he.data5 |= HE_PREP(DATA5_DATA_BW_RU_ALLOC, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_20MHZ); -+ break; -+ case PHY_CHNL_BW_40: -+ he.data5 |= HE_PREP(DATA5_DATA_BW_RU_ALLOC, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_40MHZ); -+ break; -+ case PHY_CHNL_BW_80: -+ he.data5 |= HE_PREP(DATA5_DATA_BW_RU_ALLOC, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_80MHZ); -+ break; -+ case PHY_CHNL_BW_160: -+ he.data5 |= HE_PREP(DATA5_DATA_BW_RU_ALLOC, -+ IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_160MHZ); -+ break; -+ default: -+ WARN_ONCE(1, "Invalid SU BW %d\n", rxvect->ch_bw); -+ } -+ -+ he.data6 |= HE_PREP(DATA6_DOPPLER, rxvect->he.doppler); -+ -+ /* ensure 2 byte alignment */ -+ while ((pos - (u8 *)rtap) & 1) -+ pos++; -+ rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_HE); -+ memcpy(pos, &he, sizeof(he)); -+ pos += sizeof(he); -+ } -+ -+ // Rx Chains -+ if (hweight32(rxvect->antenna_set) > 1) { -+ int chain; -+ unsigned long chains = rxvect->antenna_set; -+ u8 rssis[4] = {rxvect->rssi1, rxvect->rssi1, rxvect->rssi1, rxvect->rssi1}; -+ -+ for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) { -+ *pos++ = rssis[chain]; -+ *pos++ = chain; -+ } -+ } -+} -+ -+/** -+ * rwnx_rx_monitor - Build radiotap header for skb an send it to netdev -+ * -+ * @rwnx_hw: main driver data -+ * @rwnx_vif: vif that received the buffer -+ * @skb: sk_buff received -+ * @hw_rxhdr_ptr: Pointer to HW RX header -+ * @rtap_len: Radiotap Header length -+ * -+ * Add radiotap header to the receved skb and send it to netdev -+ */ -+static int rwnx_rx_monitor(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct sk_buff *skb, struct hw_rxhdr *hw_rxhdr_ptr, -+ u8 rtap_len) -+{ -+ skb->dev = rwnx_vif->ndev; -+ -+ if (rwnx_vif->wdev.iftype != NL80211_IFTYPE_MONITOR) { -+ netdev_err(rwnx_vif->ndev, "not a monitor vif\n"); -+ return -1; -+ } -+ -+ /* Add RadioTap Header */ -+ rwnx_rx_add_rtap_hdr(rwnx_hw, skb, &hw_rxhdr_ptr->hwvect.rx_vect1, -+ &hw_rxhdr_ptr->phy_info, &hw_rxhdr_ptr->hwvect, -+ rtap_len, 0, 0); -+ -+ skb_reset_mac_header(skb); -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ skb->pkt_type = PACKET_OTHERHOST; -+ skb->protocol = htons(ETH_P_802_2); -+ -+#ifdef CONFIG_FILTER_TCP_ACK -+ filter_rx_tcp_ack(rwnx_hw,skb->data, cpu_to_le16(skb->len)); -+#endif -+ -+ local_bh_disable(); -+ netif_receive_skb(skb); -+ local_bh_enable(); -+ -+ return 0; -+} -+ -+#ifdef AICWF_ARP_OFFLOAD -+void arpoffload_proc(struct sk_buff *skb, struct rwnx_vif *rwnx_vif) -+{ -+ struct iphdr *iphead = (struct iphdr *)(skb->data); -+ struct udphdr *udph; -+ struct DHCPInfo *dhcph; -+ -+ if (skb->protocol == htons(ETH_P_IP)) { // IP -+ if (iphead->protocol == IPPROTO_UDP) { // UDP -+ udph = (struct udphdr *)((u8 *)iphead + (iphead->ihl << 2)); -+ if ((udph->source == __constant_htons(SERVER_PORT)) -+ && (udph->dest == __constant_htons(CLIENT_PORT))) { // DHCP offset/ack -+ dhcph = (struct DHCPInfo *)((u8 *)udph + sizeof(struct udphdr)); -+ if (dhcph->cookie == htonl(DHCP_MAGIC) && dhcph->op == 2 && -+ !memcmp(dhcph->chaddr, rwnx_vif->ndev->dev_addr, 6)) { // match magic word -+ u32 length = ntohs(udph->len) - sizeof(struct udphdr) - offsetof(struct DHCPInfo, options); -+ u16 offset = 0; -+ u8 *option = dhcph->options; -+ while (option[offset] != DHCP_OPTION_END && offset < length) { -+ if (option[offset] == DHCP_OPTION_MESSAGE_TYPE) { -+ if (option[offset+2] == DHCP_ACK) { -+ dhcped = 1; -+ AICWFDBG(LOGINFO, "paired=%x, should=%x\n", rwnx_vif->sta.paired_cipher_type, WLAN_CIPHER_SUITE_CCMP); -+ if (rwnx_vif->sta.paired_cipher_type == WLAN_CIPHER_SUITE_CCMP || \ -+ rwnx_vif->sta.paired_cipher_type == WLAN_CIPHER_SUITE_AES_CMAC || \ -+ ((rwnx_vif->sta.group_cipher_type == 0xff) && \ -+ (rwnx_vif->sta.paired_cipher_type == 0xff))) -+ rwnx_send_arpoffload_en_req(rwnx_vif->rwnx_hw, rwnx_vif, dhcph->yiaddr, 1); -+ else -+ rwnx_send_arpoffload_en_req(rwnx_vif->rwnx_hw, rwnx_vif, dhcph->yiaddr, 0); -+ } -+ } -+ offset += 2 + option[offset+1]; -+ } -+ } -+ } -+ } -+ } -+} -+#endif -+ -+#ifdef AICWF_RX_REORDER -+void reord_rxframe_free(spinlock_t *lock, struct list_head *q, struct list_head *list) -+{ -+ spin_lock_bh(lock); -+ list_add(list, q); -+ spin_unlock_bh(lock); -+} -+ -+struct recv_msdu *reord_rxframe_alloc(spinlock_t *lock, struct list_head *q) -+{ -+ struct recv_msdu *rxframe; -+ -+ spin_lock_bh(lock); -+ if (list_empty(q)) { -+ spin_unlock_bh(lock); -+ return NULL; -+ } -+ rxframe = list_entry(q->next, struct recv_msdu, rxframe_list); -+ list_del_init(q->next); -+ spin_unlock_bh(lock); -+ return rxframe; -+} -+ -+struct reord_ctrl_info *reord_init_sta(struct aicwf_rx_priv *rx_priv, const u8 *mac_addr) -+{ -+ u8 i = 0; -+ struct reord_ctrl *preorder_ctrl = NULL; -+ struct reord_ctrl_info *reord_info; -+#ifdef AICWF_SDIO_SUPPORT -+ struct aicwf_bus *bus_if = rx_priv->sdiodev->bus_if; -+#else -+ struct aicwf_bus *bus_if = rx_priv->usbdev->bus_if; -+#endif -+ -+ if (bus_if->state == BUS_DOWN_ST || rx_priv == NULL) { -+ AICWFDBG(LOGERROR, "bad stat!\n"); -+ return NULL; -+ } -+ -+ AICWFDBG(LOGINFO, "reord_init_sta:%pM\n", mac_addr); -+ reord_info = kmalloc(sizeof(struct reord_ctrl_info), GFP_ATOMIC); -+ if (!reord_info) -+ return NULL; -+ -+ memcpy(reord_info->mac_addr, mac_addr, ETH_ALEN); -+ for (i = 0; i < 8; i++) { -+ preorder_ctrl = &reord_info->preorder_ctrl[i]; -+ preorder_ctrl->enable = true; -+ preorder_ctrl->ind_sn = 0xffff; -+ preorder_ctrl->wsize_b = AICWF_REORDER_WINSIZE; -+ preorder_ctrl->rx_priv = rx_priv; -+ INIT_LIST_HEAD(&preorder_ctrl->reord_list); -+ spin_lock_init(&preorder_ctrl->reord_list_lock); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+ init_timer(&preorder_ctrl->reord_timer); -+ preorder_ctrl->reord_timer.data = (ulong) preorder_ctrl; -+ preorder_ctrl->reord_timer.function = reord_timeout_handler; -+#else -+ timer_setup(&preorder_ctrl->reord_timer, reord_timeout_handler, 0); -+#endif -+ INIT_WORK(&preorder_ctrl->reord_timer_work, reord_timeout_worker); -+ } -+ -+ return reord_info; -+} -+ -+int reord_flush_tid(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u8 tid) -+{ -+ struct reord_ctrl_info *reord_info; -+ struct reord_ctrl *preorder_ctrl; -+ struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif; -+ struct ethhdr *eh = (struct ethhdr *)(skb->data); -+ u8 *mac; -+ unsigned long flags; -+ u8 found = 0; -+ struct list_head *phead, *plist; -+ struct recv_msdu *prframe; -+ int ret; -+ -+ if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) -+ mac = eh->h_dest; -+ else if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) -+ mac = eh->h_source; -+ else { -+ AICWFDBG(LOGERROR, "error mode:%d!\n", rwnx_vif->wdev.iftype); -+ dev_kfree_skb(skb); -+ return -1; -+ } -+ -+ spin_lock_bh(&rx_priv->stas_reord_lock); -+ list_for_each_entry(reord_info, &rx_priv->stas_reord_list, list) { -+ if (!memcmp(mac, reord_info->mac_addr, ETH_ALEN)) { -+ found = 1; -+ preorder_ctrl = &reord_info->preorder_ctrl[tid]; -+ break; -+ } -+ } -+ if (!found) { -+ spin_unlock_bh(&rx_priv->stas_reord_lock); -+ return 0; -+ } -+ spin_unlock_bh(&rx_priv->stas_reord_lock); -+ -+ if (preorder_ctrl->enable == false) -+ return 0; -+ spin_lock_irqsave(&preorder_ctrl->reord_list_lock, flags); -+ phead = &preorder_ctrl->reord_list; -+ while (1) { -+ if (list_empty(phead)) { -+ break; -+ } -+ plist = phead->next; -+ prframe = list_entry(plist, struct recv_msdu, reord_pending_list); -+ reord_single_frame_ind(rx_priv, prframe); -+ list_del_init(&(prframe->reord_pending_list)); -+ } -+ -+ AICWFDBG(LOGINFO, "flush:tid=%d", tid); -+ preorder_ctrl->enable = false; -+ spin_unlock_irqrestore(&preorder_ctrl->reord_list_lock, flags); -+ if (timer_pending(&preorder_ctrl->reord_timer)) -+ ret = del_timer_sync(&preorder_ctrl->reord_timer); -+ cancel_work_sync(&preorder_ctrl->reord_timer_work); -+ -+ return 0; -+} -+ -+void reord_deinit_sta(struct aicwf_rx_priv *rx_priv, struct reord_ctrl_info *reord_info) -+{ -+ u8 i = 0; -+ unsigned long flags; -+ struct reord_ctrl *preorder_ctrl = NULL; -+ int ret; -+ -+ if (rx_priv == NULL) { -+ txrx_err("bad rx_priv!\n"); -+ return; -+ } -+ -+ for (i = 0; i < 8; i++) { -+ struct recv_msdu *req, *next; -+ preorder_ctrl = &reord_info->preorder_ctrl[i]; -+ spin_lock_irqsave(&preorder_ctrl->reord_list_lock, flags); -+ list_for_each_entry_safe(req, next, &preorder_ctrl->reord_list, reord_pending_list) { -+ list_del_init(&req->reord_pending_list); -+ if (req->pkt != NULL) -+ dev_kfree_skb(req->pkt); -+ req->pkt = NULL; -+ reord_rxframe_free(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue, &req->rxframe_list); -+ } -+ spin_unlock_irqrestore(&preorder_ctrl->reord_list_lock, flags); -+ if (timer_pending(&preorder_ctrl->reord_timer)) { -+ ret = del_timer_sync(&preorder_ctrl->reord_timer); -+ } -+ cancel_work_sync(&preorder_ctrl->reord_timer_work); -+ } -+ list_del(&reord_info->list); -+ kfree(reord_info); -+} -+ -+int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prframe) -+{ -+ struct list_head *rxframes_freequeue = NULL; -+ struct sk_buff *skb = NULL; -+ struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif; -+ struct sk_buff_head list; -+ struct sk_buff *rx_skb; -+ -+ rxframes_freequeue = &rx_priv->rxframes_freequeue; -+ skb = prframe->pkt; -+ -+ #ifdef CONFIG_BR_SUPPORT -+ void *br_port = NULL; -+ -+ if (1) {//(check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { -+ /* Insert NAT2.5 RX here! */ -+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) -+ br_port = rwnx_vif->ndev->br_port; -+ #else -+ rcu_read_lock(); -+ br_port = rcu_dereference(rwnx_vif->ndev->rx_handler_data); -+ rcu_read_unlock(); -+ #endif -+ -+ if (br_port) { -+ int nat25_handle_frame(struct rwnx_vif *vif, struct sk_buff *skb); -+ -+ if (nat25_handle_frame(rwnx_vif, skb) == -1) { -+ /* priv->ext_stats.rx_data_drops++; */ -+ /* DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n"); */ -+ /* return FAIL; */ -+ } -+ } -+ } -+ #endif /* CONFIG_BR_SUPPORT */ -+ -+ if (skb == NULL) { -+ txrx_err("skb is NULL\n"); -+ return -1; -+ } -+ -+ if(!prframe->forward) { -+ //printk("single: %d not forward: drop\n", prframe->seq_num); -+ dev_kfree_skb(skb); -+ prframe->pkt = NULL; -+ reord_rxframe_free(&rx_priv->freeq_lock, rxframes_freequeue, &prframe->rxframe_list); -+ return 0; -+ } -+ -+ //skb->data = prframe->rx_data; -+ //skb_set_tail_pointer(skb, prframe->len); -+ //skb->len = prframe->len; -+ __skb_queue_head_init(&list); -+ //printk("sg:%d\n", prframe->is_amsdu); -+ if(prframe->is_amsdu) { -+ rwnx_rxdata_process_amsdu(rwnx_vif->rwnx_hw, skb, rwnx_vif->vif_index, &list); //rxhdr not used below since skb free! -+ } else { -+ __skb_queue_head(&list, skb); -+ } -+ -+ -+ while (!skb_queue_empty(&list)) { -+ rx_skb = __skb_dequeue(&list); -+ -+ rwnx_vif->net_stats.rx_packets++; -+ rwnx_vif->net_stats.rx_bytes += rx_skb->len; -+ //printk("netif sn=%d, len=%d\n", precv_frame->attrib.seq_num, skb->len); -+ -+ rx_skb->dev = rwnx_vif->ndev; -+ rx_skb->protocol = eth_type_trans(rx_skb, rwnx_vif->ndev); -+ -+#ifdef AICWF_ARP_OFFLOAD -+ if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) { -+ arpoffload_proc(rx_skb, rwnx_vif); -+ } -+#endif -+ memset(rx_skb->cb, 0, sizeof(rx_skb->cb)); -+ -+#ifdef CONFIG_FILTER_TCP_ACK -+ filter_rx_tcp_ack(rwnx_vif->rwnx_hw,rx_skb->data, cpu_to_le16(skb->len)); -+#endif -+ -+#ifdef CONFIG_RX_NETIF_RECV_SKB//AIDEN test -+ local_bh_disable(); -+ netif_receive_skb(rx_skb); -+ local_bh_enable(); -+#else -+ if (in_interrupt()) { -+ netif_rx(rx_skb); -+ } else { -+ /* -+ * If the receive is not processed inside an ISR, the softirqd must be woken explicitly to service the NET_RX_SOFTIRQ. -+ * * In 2.6 kernels, this is handledby netif_rx_ni(), but in earlier kernels, we need to do it manually. -+ */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -+ netif_rx_ni(rx_skb); -+#else -+ ulong flags; -+ netif_rx(rx_skb); -+ local_irq_save(flags); -+ RAISE_RX_SOFTIRQ(); -+ local_irq_restore(flags); -+#endif -+ } -+#endif /* CONFIG_RX_NETIF_RECV_SKB */ -+ } -+ -+ prframe->pkt = NULL; -+ reord_rxframe_free(&rx_priv->freeq_lock, rxframes_freequeue, &prframe->rxframe_list); -+ -+ return 0; -+} -+ -+bool reord_rxframes_process(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *preorder_ctrl, int bforced) -+{ -+ struct list_head *phead, *plist; -+ struct recv_msdu *prframe; -+ bool bPktInBuf = false; -+ -+ if (bforced == true) { -+ phead = &preorder_ctrl->reord_list; -+ if (list_empty(phead)) { -+ return false; -+ } -+ -+ plist = phead->next; -+ prframe = list_entry(plist, struct recv_msdu, reord_pending_list); -+ preorder_ctrl->ind_sn = prframe->seq_num; -+ } -+ -+ phead = &preorder_ctrl->reord_list; -+ if (list_empty(phead)) { -+ return bPktInBuf; -+ } -+ -+ list_for_each_entry(prframe, phead, reord_pending_list) { -+ if (!SN_LESS(preorder_ctrl->ind_sn, prframe->seq_num)) { -+ if (SN_EQUAL(preorder_ctrl->ind_sn, prframe->seq_num)) { -+ preorder_ctrl->ind_sn = (preorder_ctrl->ind_sn + 1) & 0xFFF; -+ } -+ } else { -+ bPktInBuf = true; -+ break; -+ } -+ } -+ -+ return bPktInBuf; -+} -+ -+void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv, -+ struct reord_ctrl *preorder_ctrl) -+{ -+ struct list_head *phead, *plist; -+ struct recv_msdu *prframe; -+ -+ phead = &preorder_ctrl->reord_list; -+ while (1) { -+ //spin_lock_bh(&preorder_ctrl->reord_list_lock); -+ if (list_empty(phead)) { -+ // spin_unlock_bh(&preorder_ctrl->reord_list_lock); -+ break; -+ } -+ -+ plist = phead->next; -+ prframe = list_entry(plist, struct recv_msdu, reord_pending_list); -+ -+ if (!SN_LESS(preorder_ctrl->ind_sn, prframe->seq_num)) { -+ list_del_init(&(prframe->reord_pending_list)); -+ // spin_unlock_bh(&preorder_ctrl->reord_list_lock); -+ reord_single_frame_ind(rx_priv, prframe); -+ } else { -+ // spin_unlock_bh(&preorder_ctrl->reord_list_lock); -+ break; -+ } -+ } -+} -+ -+int reorder_timeout = REORDER_UPDATE_TIME; -+module_param(reorder_timeout, int, 0660); -+ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+void reord_timeout_handler (ulong data) -+#else -+void reord_timeout_handler (struct timer_list *t) -+#endif -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+ struct reord_ctrl *preorder_ctrl = (struct reord_ctrl *)data; -+#else -+ struct reord_ctrl *preorder_ctrl = from_timer(preorder_ctrl, t, reord_timer); -+#endif -+ -+#if 0 //AIDEN -+ struct aicwf_rx_priv *rx_priv = preorder_ctrl->rx_priv; -+ -+ if (reord_rxframes_process(rx_priv, preorder_ctrl, true) == true) { -+ mod_timer(&preorder_ctrl->reord_timer, jiffies + msecs_to_jiffies(REORDER_UPDATE_TIME)); -+ } -+#endif -+ -+ if (!work_pending(&preorder_ctrl->reord_timer_work)) -+ schedule_work(&preorder_ctrl->reord_timer_work); -+} -+ -+void reord_timeout_worker(struct work_struct *work) -+{ -+ struct reord_ctrl *preorder_ctrl = container_of(work, struct reord_ctrl, reord_timer_work); -+ struct aicwf_rx_priv *rx_priv = preorder_ctrl->rx_priv; -+ -+ spin_lock_bh(&preorder_ctrl->reord_list_lock); -+#if 1//AIDEN -+ if (reord_rxframes_process(rx_priv, preorder_ctrl, true)==true) { -+ mod_timer(&preorder_ctrl->reord_timer, jiffies + msecs_to_jiffies(reorder_timeout/*REORDER_UPDATE_TIME*/)); -+ } -+#endif -+ -+ reord_rxframes_ind(rx_priv, preorder_ctrl); -+ spin_unlock_bh(&preorder_ctrl->reord_list_lock); -+ -+ return ; -+} -+ -+int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 seq_num, u8 tid, u8 forward, u8 is_amsdu) -+{ -+ int ret = 0; -+ u8 *mac; -+ struct recv_msdu *pframe; -+ struct reord_ctrl *preorder_ctrl; -+ struct reord_ctrl_info *reord_info; -+ struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif; -+ struct ethhdr *eh = (struct ethhdr *)(skb->data); -+ u8 *da = eh->h_dest; -+ u8 is_mcast = ((*da) & 0x01) ? 1 : 0; -+ -+ if (rwnx_vif == NULL || skb->len <= 14) { -+ dev_kfree_skb(skb); -+ return -1; -+ } -+ -+ pframe = reord_rxframe_alloc(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue); -+ if (!pframe) { -+ dev_kfree_skb(skb); -+ return -1; -+ } -+ -+ INIT_LIST_HEAD(&pframe->reord_pending_list); -+ pframe->seq_num = seq_num; -+ pframe->tid = tid; -+ pframe->rx_data = skb->data; -+ //pframe->len = skb->len; -+ pframe->pkt = skb; -+ pframe->forward = forward; -+ preorder_ctrl = pframe->preorder_ctrl; -+ pframe->is_amsdu = is_amsdu; -+ -+ if ((ntohs(eh->h_proto) == ETH_P_PAE) || is_mcast) -+ return reord_single_frame_ind(rx_priv, pframe); -+ -+ if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) -+ mac = eh->h_dest; -+ else if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) -+ mac = eh->h_source; -+ else { -+ dev_kfree_skb(skb); -+ return -1; -+ } -+ -+ spin_lock_bh(&rx_priv->stas_reord_lock); -+ list_for_each_entry(reord_info, &rx_priv->stas_reord_list, list) { -+ if (!memcmp(mac, reord_info->mac_addr, ETH_ALEN)) { -+ preorder_ctrl = &reord_info->preorder_ctrl[pframe->tid]; -+ break; -+ } -+ } -+ -+ if (&reord_info->list == &rx_priv->stas_reord_list) { -+ reord_info = reord_init_sta(rx_priv, mac); -+ if (!reord_info) { -+ spin_unlock_bh(&rx_priv->stas_reord_lock); -+ dev_kfree_skb(skb); -+ return -1; -+ } -+ list_add_tail(&reord_info->list, &rx_priv->stas_reord_list); -+ preorder_ctrl = &reord_info->preorder_ctrl[pframe->tid]; -+ } else { -+ if (preorder_ctrl->enable == false) { -+ preorder_ctrl->enable = true; -+ preorder_ctrl->ind_sn = 0xffff; -+ preorder_ctrl->wsize_b = AICWF_REORDER_WINSIZE; -+ preorder_ctrl->rx_priv = rx_priv; -+ } -+ } -+ spin_unlock_bh(&rx_priv->stas_reord_lock); -+ -+ if (preorder_ctrl->enable == false) { -+ spin_lock_bh(&preorder_ctrl->reord_list_lock); -+ preorder_ctrl->ind_sn = pframe->seq_num; -+ reord_single_frame_ind(rx_priv, pframe); -+ preorder_ctrl->ind_sn = (preorder_ctrl->ind_sn + 1)%4096; -+ spin_unlock_bh(&rx_priv->stas_reord_lock); -+ return 0; -+ } -+ -+ spin_lock_bh(&preorder_ctrl->reord_list_lock); -+ if (reord_need_check(preorder_ctrl, pframe->seq_num)) { -+#if 1 -+ if(pframe->rx_data[42] == 0x80){//this is rtp package -+ if(pframe->seq_num == preorder_ctrl->ind_sn){ -+ printk("%s pframe->seq_num1:%d \r\n", __func__, pframe->seq_num); -+ reord_single_frame_ind(rx_priv, pframe);//not need to reorder -+ }else{ -+ printk("%s free pframe->seq_num:%d \r\n", __func__, pframe->seq_num); -+ if (pframe->pkt){ -+ dev_kfree_skb(pframe->pkt); -+ pframe->pkt = NULL; -+ } -+ reord_rxframe_free(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue, &pframe->rxframe_list); -+ } -+ }else{ -+ //printk("%s pframe->seq_num2:%d \r\n", __func__, pframe->seq_num); -+ reord_single_frame_ind(rx_priv, pframe);//not need to reorder -+ } -+#else -+ reord_single_frame_ind(rx_priv, pframe);//not need to reor -+#endif -+ spin_unlock_bh(&preorder_ctrl->reord_list_lock); -+ return 0; -+ } -+ -+ if (reord_rxframe_enqueue(preorder_ctrl, pframe)) { -+ spin_unlock_bh(&preorder_ctrl->reord_list_lock); -+ goto fail; -+ } -+ -+ if (reord_rxframes_process(rx_priv, preorder_ctrl, false) == true) { -+ if (!timer_pending(&preorder_ctrl->reord_timer)) { -+ ret = mod_timer(&preorder_ctrl->reord_timer, jiffies + msecs_to_jiffies(reorder_timeout/*REORDER_UPDATE_TIME*/)); -+ } -+ } else { -+ if (timer_pending(&preorder_ctrl->reord_timer)) { -+ ret = del_timer(&preorder_ctrl->reord_timer); -+ } -+ } -+ -+ reord_rxframes_ind(rx_priv, preorder_ctrl); -+ spin_unlock_bh(&preorder_ctrl->reord_list_lock); -+ -+ return 0; -+ -+fail: -+ if (pframe->pkt) { -+ dev_kfree_skb(pframe->pkt); -+ pframe->pkt = NULL; -+ } -+ reord_rxframe_free(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue, &pframe->rxframe_list); -+ return ret; -+} -+ -+int reord_need_check(struct reord_ctrl *preorder_ctrl, u16 seq_num) -+{ -+ u8 wsize = preorder_ctrl->wsize_b; -+ u16 wend = (preorder_ctrl->ind_sn + wsize -1) & 0xFFF; -+ -+ if (preorder_ctrl->ind_sn == 0xFFFF) { -+ preorder_ctrl->ind_sn = seq_num; -+ } -+ -+ if (SN_LESS(seq_num, preorder_ctrl->ind_sn)) { -+ return -1; -+ } -+ -+ if (SN_EQUAL(seq_num, preorder_ctrl->ind_sn)) { -+ preorder_ctrl->ind_sn = (preorder_ctrl->ind_sn + 1) & 0xFFF; -+ } else if (SN_LESS(wend, seq_num)) { -+ if (seq_num >= (wsize-1)) -+ preorder_ctrl->ind_sn = seq_num-(wsize-1); -+ else -+ preorder_ctrl->ind_sn = 0xFFF - (wsize - (seq_num + 1)) + 1; -+ } -+ -+ return 0; -+} -+ -+int reord_rxframe_enqueue(struct reord_ctrl *preorder_ctrl, struct recv_msdu *prframe) -+{ -+ struct list_head *preord_list = &preorder_ctrl->reord_list; -+ struct list_head *phead, *plist; -+ struct recv_msdu *pnextrframe; -+ -+ phead = preord_list; -+ plist = phead->next; -+ -+ while (phead != plist) { -+ pnextrframe = list_entry(plist, struct recv_msdu, reord_pending_list); -+ if (SN_LESS(pnextrframe->seq_num, prframe->seq_num)) { -+ plist = plist->next; -+ continue; -+ } else if (SN_EQUAL(pnextrframe->seq_num, prframe->seq_num)) { -+ return -1; -+ } else { -+ break; -+ } -+ } -+ list_add_tail(&(prframe->reord_pending_list), plist); -+ -+ return 0; -+} -+#endif /* AICWF_RX_REORDER */ -+ -+void remove_sec_hdr_mgmt_frame(struct hw_rxhdr *hw_rxhdr, struct sk_buff *skb) -+{ -+ u8 hdr_len = 24; -+ u8 mgmt_header[24] = {0}; -+ -+ if (!hw_rxhdr->hwvect.ga_frame) { -+ if (((skb->data[0] & 0x0C) == 0) && (skb->data[1] & 0x40) == 0x40) { //protect management frame -+ printk("frame type %x\n", skb->data[0]); -+ if (hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_CCMP128) { -+ memcpy(mgmt_header, skb->data, hdr_len); -+ skb_pull(skb, 8); -+ memcpy(skb->data, mgmt_header, hdr_len); -+ hw_rxhdr->hwvect.len -= 8; -+ } else { -+ printk("unsupport decr_status:%d\n", hw_rxhdr->hwvect.decr_status); -+ } -+ } -+ } -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) -+void defrag_timeout_cb(ulong data) -+#else -+void defrag_timeout_cb(struct timer_list *t) -+#endif -+{ -+ struct defrag_ctrl_info *defrag_ctrl = NULL; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) -+ defrag_ctrl = (struct defrag_ctrl_info *)data; -+#else -+ defrag_ctrl = from_timer(defrag_ctrl, t, defrag_timer); -+#endif -+ -+ printk("%s:%p\r\n", __func__, defrag_ctrl); -+ spin_lock_bh(&defrag_ctrl->rwnx_hw->defrag_lock); -+ list_del_init(&defrag_ctrl->list); -+ dev_kfree_skb(defrag_ctrl->skb); -+ kfree(defrag_ctrl); -+ spin_unlock_bh(&defrag_ctrl->rwnx_hw->defrag_lock); -+} -+ -+void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx, -+ struct sk_buff_head *list) -+{ -+ u16 len_alligned = 0; -+ u16 sublen = 0; -+ struct sk_buff *sub_skb = NULL; -+ struct rwnx_vif *rwnx_vif; -+ -+ //if (is_amsdu) -+ { -+ //skb_pull(skb, pull_len-8); -+ /* |amsdu sub1 | amsdu sub2 | ... */ -+ len_alligned = 0; -+ sublen = 0; -+ sub_skb = NULL; -+ while (skb->len > 16) { -+ sublen = (skb->data[12]<<8)|(skb->data[13]); -+ if (skb->len > (sublen+14)) -+ len_alligned = roundup(sublen + 14, 4); -+ else if (skb->len == (sublen+14)) -+ len_alligned = sublen+14; -+ else { -+ printk("accroding to amsdu: this will not happen\n"); -+ break; -+ } -+ //printk("sublen = %d, %x, %x, %x, %x\r\n", sublen,skb->data[0], skb->data[1], skb->data[12], skb->data[13]); -+#if 1 -+ sub_skb = __dev_alloc_skb(sublen - 6 + 12, GFP_ATOMIC); -+ if(!sub_skb){ -+ printk("sub_skb alloc fail:%d\n", sublen); -+ break; -+ } -+ skb_put(sub_skb, sublen - 6 + 12); -+ memcpy(sub_skb->data, skb->data, MAC_ADDR_LEN); -+ memcpy(&sub_skb->data[6], &skb->data[6], MAC_ADDR_LEN); -+ memcpy(&sub_skb->data[12], &skb->data[14 + 6], sublen - 6); -+ -+ rwnx_vif = rwnx_rx_get_vif(rwnx_hw, vif_idx); -+ if (!rwnx_vif) { -+ printk("Frame received but no active vif (%d)", vif_idx); -+ //dev_kfree_skb(sub_skb); -+ break; -+ } -+ -+ __skb_queue_tail(list, sub_skb); -+ -+ //printk("a:%p\n", sub_skb); -+ //if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, sub_skb, hw_rxhdr)) -+ // dev_kfree_skb(sub_skb); -+#endif -+ skb_pull(skb, len_alligned); -+ } -+ //printk("af:%p\n", skb); -+ -+ dev_kfree_skb(skb); -+ //return 0; -+ } -+} -+ -+u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv) -+{ -+ struct hw_rxhdr *hw_rxhdr; -+ struct rxdesc_tag *rxdesc = NULL; -+ struct rwnx_vif *rwnx_vif; -+ struct sk_buff *skb = hostid; -+ int msdu_offset = sizeof(struct hw_rxhdr) + 2; -+ u16_l status = 0; -+ struct aicwf_rx_priv *rx_priv_tmp; -+ u8 hdr_len = 24; -+ u8 ra[MAC_ADDR_LEN] = {0}; -+ u8 ta[MAC_ADDR_LEN] = {0}; -+ u8 ether_type[2] = {0}; -+ u8 pull_len = 0; -+ u16 seq_num = 0; -+ u8_l frag_num = 0; -+ u8 tid = 0; -+ u8 is_qos = 0; -+ u8 is_frag = 0; -+ struct defrag_ctrl_info *defrag_info = NULL; -+ struct defrag_ctrl_info *defrag_info_tmp = NULL; -+ struct sk_buff *skb_tmp = NULL; -+ int ret; -+ u8 sta_idx = 0; -+ u16_l frame_ctrl; -+ u8 is_amsdu = 0; -+ bool resend = false, forward = true; -+ const struct ethhdr *eth; -+ -+ hw_rxhdr = (struct hw_rxhdr *)skb->data; -+ -+ if (hw_rxhdr->is_monitor_vif) { -+ status = RX_STAT_MONITOR; -+ printk("monitor rx\n"); -+ } -+ -+ if (hw_rxhdr->flags_upload) -+ status |= RX_STAT_FORWARD; -+ -+ /* Check if we need to delete the buffer */ -+ if (status & RX_STAT_DELETE) { -+ /* Remove the SK buffer from the rxbuf_elems table */ -+ #if 0 -+ rwnx_ipc_rxbuf_elem_pull(rwnx_hw, skb); -+ #endif -+ /* Free the buffer */ -+ dev_kfree_skb(skb); -+ goto end; -+ } -+ -+ /* Check if we need to forward the buffer coming from a monitor interface */ -+ if (status & RX_STAT_MONITOR) { -+ struct sk_buff *skb_monitor; -+ struct hw_rxhdr hw_rxhdr_copy; -+ u8 rtap_len; -+ u16 frm_len; -+ -+ //Check if monitor interface exists and is open -+ rwnx_vif = rwnx_rx_get_vif(rwnx_hw, rwnx_hw->monitor_vif); -+ if (!rwnx_vif) { -+ dev_err(rwnx_hw->dev, "Received monitor frame but there is no monitor interface open\n"); -+ goto check_len_update; -+ } -+ -+ rwnx_rx_vector_convert(rwnx_hw, -+ &hw_rxhdr->hwvect.rx_vect1, -+ &hw_rxhdr->hwvect.rx_vect2); -+ rtap_len = rwnx_rx_rtap_hdrlen(&hw_rxhdr->hwvect.rx_vect1, false); -+ -+ // Move skb->data pointer to MAC Header or Ethernet header -+ skb->data += (msdu_offset + 2); //sdio/usb word allign -+ -+ //Save frame length -+ frm_len = le32_to_cpu(hw_rxhdr->hwvect.len); -+ -+ // Reserve space for frame -+ skb->len = frm_len; -+ -+ if (status == RX_STAT_MONITOR) { -+ /* Remove the SK buffer from the rxbuf_elems table. It will also -+ unmap the buffer and then sync the buffer for the cpu */ -+ //rwnx_ipc_rxbuf_elem_pull(rwnx_hw, skb); -+ -+ //Check if there is enough space to add the radiotap header -+ if (skb_headroom(skb) > rtap_len) { -+ skb_monitor = skb; -+ -+ //Duplicate the HW Rx Header to override with the radiotap header -+ memcpy(&hw_rxhdr_copy, hw_rxhdr, sizeof(hw_rxhdr_copy)); -+ -+ hw_rxhdr = &hw_rxhdr_copy; -+ } else { -+ //Duplicate the skb and extend the headroom -+ skb_monitor = skb_copy_expand(skb, rtap_len, 0, GFP_ATOMIC); -+ -+ //Reset original skb->data pointer -+ skb->data = (void *)hw_rxhdr; -+ } -+ } else { -+ skb->data = (void *)hw_rxhdr; -+ -+ wiphy_err(rwnx_hw->wiphy, "RX status %d is invalid when MON_DATA is disabled\n", status); -+ goto check_len_update; -+ } -+ -+ skb_reset_tail_pointer(skb); -+ skb->len = 0; -+ skb_reset_tail_pointer(skb_monitor); -+ skb_monitor->len = 0; -+ -+ skb_put(skb_monitor, frm_len); -+ if (rwnx_rx_monitor(rwnx_hw, rwnx_vif, skb_monitor, hw_rxhdr, rtap_len)) -+ dev_kfree_skb(skb_monitor); -+ -+ if (status == RX_STAT_MONITOR) { -+ status |= RX_STAT_ALLOC; -+ if (skb_monitor != skb) { -+ dev_kfree_skb(skb); -+ } -+ } -+ } -+ -+check_len_update: -+ /* Check if we need to update the length */ -+ if (status & RX_STAT_LEN_UPDATE) { -+ if (rxdesc) -+ hw_rxhdr->hwvect.len = rxdesc->frame_len; -+ -+ if (status & RX_STAT_ETH_LEN_UPDATE) { -+ /* Update Length Field inside the Ethernet Header */ -+ struct ethhdr *hdr = (struct ethhdr *)((u8 *)hw_rxhdr + msdu_offset); -+ -+ if (rxdesc) -+ hdr->h_proto = htons(rxdesc->frame_len - sizeof(struct ethhdr)); -+ } -+ -+ goto end; -+ } -+ -+ /* Check if it must be discarded after informing upper layer */ -+ if (status & RX_STAT_SPURIOUS) { -+ struct ieee80211_hdr *hdr; -+ -+ hdr = (struct ieee80211_hdr *)(skb->data + msdu_offset); -+ rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx); -+ if (rwnx_vif) { -+#ifdef CONFIG_GKI -+ rwnx_cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC); -+#else -+ cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC); -+#endif -+ } -+ goto end; -+ } -+ -+ /* Check if we need to forward the buffer */ -+ if (status & RX_STAT_FORWARD) { -+ rwnx_rx_vector_convert(rwnx_hw, -+ &hw_rxhdr->hwvect.rx_vect1, -+ &hw_rxhdr->hwvect.rx_vect2); -+ skb_pull(skb, msdu_offset + 2); //+2 since sdio allign 58->60 -+ -+#define MAC_FCTRL_MOREFRAG 0x0400 -+ frame_ctrl = (skb->data[1] << 8) | skb->data[0]; -+ seq_num = ((skb->data[22] & 0xf0) >> 4) | (skb->data[23] << 4); -+ frag_num = (skb->data[22] & 0x0f); -+ is_amsdu = 0; -+ -+ if ((skb->data[0] & 0x0f) == 0x08) { -+ if ((skb->data[0] & 0x80) == 0x80) {//qos data -+ hdr_len = 26; -+ tid = skb->data[24] & 0x0F; -+ is_qos = 1; -+ if (skb->data[24] & 0x80) -+ is_amsdu = 1; -+ } -+ -+ if(skb->data[1] & 0x80)// htc -+ hdr_len += 4; -+ -+ if ((skb->data[1] & 0x3) == 0x1) {// to ds -+ memcpy(ra, &skb->data[16], MAC_ADDR_LEN); -+ memcpy(ta, &skb->data[10], MAC_ADDR_LEN); -+ } else if ((skb->data[1] & 0x3) == 0x2) { //from ds -+ memcpy(ta, &skb->data[16], MAC_ADDR_LEN); -+ memcpy(ra, &skb->data[4], MAC_ADDR_LEN); -+ } -+ -+ pull_len += (hdr_len + 8); -+ -+ switch (hw_rxhdr->hwvect.decr_status) { -+ case RWNX_RX_HD_DECR_CCMP128: -+ pull_len += 8;//ccmp_header -+ //skb_pull(&skb->data[skb->len-8], 8); //ccmp_mic_len -+ memcpy(ether_type, &skb->data[hdr_len + 6 + 8], 2); -+ break; -+ case RWNX_RX_HD_DECR_TKIP: -+ pull_len += 8;//tkip_header -+ memcpy(ether_type, &skb->data[hdr_len + 6 + 8], 2); -+ break; -+ case RWNX_RX_HD_DECR_WEP: -+ pull_len += 4;//wep_header -+ memcpy(ether_type, &skb->data[hdr_len + 6 + 4], 2); -+ break; -+ case RWNX_RX_HD_DECR_WAPI: -+ pull_len += 18;//wapi_header -+ memcpy(ether_type, &skb->data[hdr_len + 6 + 18], 2); -+ break; -+ -+ default: -+ memcpy(ether_type, &skb->data[hdr_len + 6], 2); -+ break; -+ } -+ if(is_amsdu) -+ hw_rxhdr->flags_is_amsdu = 1; -+ else -+ hw_rxhdr->flags_is_amsdu = 0; -+ -+ if (is_amsdu) { -+ #if 1 -+ skb_pull(skb, pull_len-8); -+ #else -+ skb_pull(skb, pull_len-8); -+ /* |amsdu sub1 | amsdu sub2 | ... */ -+ len_alligned = 0; -+ sublen = 0; -+ sub_skb = NULL; -+ //printk("is_len:%d, pull:%d\n", skb->len, pull_len); -+ while (skb->len > 16) { -+ sublen = (skb->data[12]<<8)|(skb->data[13]); -+ if (skb->len > (sublen+14)) -+ len_alligned = roundup(sublen + 14, 4); -+ else if (skb->len == (sublen+14)) -+ len_alligned = sublen+14; -+ else { -+ printk("accroding to amsdu: this will not happen\n"); -+ break; -+ } -+ //printk("sublen = %d, %x, %x, %x, %x\r\n", sublen,skb->data[0], skb->data[1], skb->data[12], skb->data[13]); -+#if 1 -+ sub_skb = __dev_alloc_skb(sublen - 6 + 12, GFP_KERNEL); -+ skb_put(sub_skb, sublen - 6 + 12); -+ memcpy(sub_skb->data, skb->data, MAC_ADDR_LEN); -+ memcpy(&sub_skb->data[6], &skb->data[6], MAC_ADDR_LEN); -+ memcpy(&sub_skb->data[12], &skb->data[14 + 6], sublen - 6); -+ -+ rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx); -+ if (!rwnx_vif) { -+ printk("Frame received but no active vif (%d)", hw_rxhdr->flags_vif_idx); -+ dev_kfree_skb(sub_skb); -+ break; -+ } -+ -+ if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, sub_skb, hw_rxhdr)) -+ dev_kfree_skb(sub_skb); -+#endif -+ skb_pull(skb, len_alligned); -+ } -+ dev_kfree_skb(skb); -+ return 0; -+ #endif -+ } -+ -+ if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA) -+ sta_idx = hw_rxhdr->flags_dst_idx; -+ -+ if (!hw_rxhdr->flags_need_reord && ((frame_ctrl & MAC_FCTRL_MOREFRAG) || frag_num)) { -+ printk("rxfrag:%d,%d,%d,sn=%d,%d\r\n", (frame_ctrl & MAC_FCTRL_MOREFRAG), frag_num, skb->len, seq_num,pull_len); -+ if (frame_ctrl & MAC_FCTRL_MOREFRAG) { -+ spin_lock_bh(&rwnx_hw->defrag_lock); -+ if (!list_empty(&rwnx_hw->defrag_list)) { -+ list_for_each_entry(defrag_info_tmp, &rwnx_hw->defrag_list, list) { -+ if ((defrag_info_tmp->sn == seq_num) && (defrag_info_tmp->tid == tid) && \ -+ defrag_info_tmp->sta_idx == sta_idx) { -+ defrag_info = defrag_info_tmp; -+ break; -+ } -+ } -+ } -+ -+ //printk("rx frag: sn=%d, fn=%d, skb->len=%d\r\n", seq_num, frag_num, skb->len); -+ if (defrag_info) { -+ is_frag = 1; -+ if (defrag_info->next_fn != frag_num) { -+ printk("discard:%d:%d\n", defrag_info->next_fn, frag_num); -+ dev_kfree_skb(skb); -+ spin_unlock_bh(&rwnx_hw->defrag_lock); -+ return 0; -+ } -+ -+ skb_put(defrag_info->skb, skb->len-(pull_len-8)); -+ memcpy(&defrag_info->skb->data[defrag_info->frm_len], \ -+ &skb->data[pull_len-8], skb->len - (pull_len-8)); -+ //printk("middle:%d,%d\n", skb->len-(pull_len-8), skb->len); -+ defrag_info->frm_len += (skb->len - (pull_len - 8)); -+ defrag_info->next_fn++; -+ dev_kfree_skb(skb); -+ spin_unlock_bh(&rwnx_hw->defrag_lock); -+ return 0; -+ } else { -+ defrag_info = kzalloc(sizeof(struct defrag_ctrl_info), GFP_KERNEL); -+ if (defrag_info == NULL) { -+ printk("no defrag_ctrl_info\r\n"); -+ dev_kfree_skb(skb); -+ spin_unlock_bh(&rwnx_hw->defrag_lock); -+ return 0; -+ } -+ defrag_info->skb = __dev_alloc_skb(2000, GFP_KERNEL); -+ if (defrag_info->skb == NULL) { -+ printk("no fragment skb\r\n"); -+ dev_kfree_skb(skb); -+ kfree(defrag_info); -+ spin_unlock_bh(&rwnx_hw->defrag_lock); -+ return 0; -+ } -+ is_frag = 1; -+ skb_pull(skb, pull_len); -+ skb_push(skb, 14); -+ memcpy(skb->data, ra, MAC_ADDR_LEN); -+ memcpy(&skb->data[6], ta, MAC_ADDR_LEN); -+ memcpy(&skb->data[12], ether_type, 2); -+ defrag_info->sn = seq_num; -+ defrag_info->next_fn = 1; -+ defrag_info->tid = tid; -+ defrag_info->sta_idx = sta_idx; -+ -+ skb_put(defrag_info->skb, skb->len); -+ memcpy(defrag_info->skb->data, skb->data, skb->len); -+ defrag_info->frm_len = skb->len; -+ defrag_info->rwnx_hw = rwnx_hw; -+ //printk("first:%p,%p,%p,%p,%p, %d,%d\r\n", defrag_info, defrag_info->skb, defrag_info->skb->head, defrag_info->skb->tail, defrag_info->skb->end, defrag_info->frm_len, skb->len); -+ list_add_tail(&defrag_info->list, &rwnx_hw->defrag_list); -+ spin_unlock_bh(&rwnx_hw->defrag_lock); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) -+ init_timer(&defrag_info->defrag_timer); -+ defrag_info->defrag_timer.data = (unsigned long)defrag_info; -+ defrag_info->defrag_timer.function = defrag_timeout_cb; -+#else -+ timer_setup(&defrag_info->defrag_timer, defrag_timeout_cb, 0); -+#endif -+ ret = mod_timer(&defrag_info->defrag_timer, jiffies + msecs_to_jiffies(DEFRAG_MAX_WAIT)); -+ dev_kfree_skb(skb); -+ return 0; -+ } -+ } else { -+ //check whether the last fragment -+ if (!list_empty(&rwnx_hw->defrag_list)) { -+ spin_lock_bh(&rwnx_hw->defrag_lock); -+ list_for_each_entry(defrag_info_tmp, &rwnx_hw->defrag_list, list) { -+ if (((defrag_info_tmp->sn == seq_num) && (defrag_info_tmp->tid == tid) && \ -+ defrag_info_tmp->sta_idx == sta_idx)) { -+ defrag_info = defrag_info_tmp; -+ break; -+ } -+ } -+ -+ if (!defrag_info) -+ spin_unlock_bh(&rwnx_hw->defrag_lock); -+ else { -+ if (defrag_info->next_fn != frag_num) { -+ printk("discard:%d:%d\n", defrag_info->next_fn, frag_num); -+ dev_kfree_skb(skb); -+ spin_unlock_bh(&rwnx_hw->defrag_lock); -+ return 0; -+ } -+ -+ skb_put(defrag_info->skb, skb->len - (pull_len-8)); -+ memcpy(&defrag_info->skb->data[defrag_info->frm_len], \ -+ &skb->data[pull_len-8], skb->len - (pull_len-8)); -+ defrag_info->frm_len += (skb->len - (pull_len-8)); -+ is_frag = 1; -+ //printk("last: sn=%d, fn=%d, %d, %d\r\n", seq_num, frag_num, defrag_info->frm_len, skb->len); -+ -+ rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx); -+ if (!rwnx_vif) { -+ printk("Frame received but no active vif (%d)", hw_rxhdr->flags_vif_idx); -+ dev_kfree_skb(skb); -+ spin_unlock_bh(&rwnx_hw->defrag_lock); -+ return 0; -+ } -+ dev_kfree_skb(skb); -+ -+ skb_tmp = defrag_info->skb; -+ list_del_init(&defrag_info->list); -+ if (timer_pending(&defrag_info->defrag_timer)) { -+ ret = del_timer(&defrag_info->defrag_timer); -+ } -+ kfree(defrag_info); -+ spin_unlock_bh(&rwnx_hw->defrag_lock); -+ -+ if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb_tmp, hw_rxhdr)) -+ dev_kfree_skb(skb_tmp); -+ -+ return 0; -+ } -+ } -+ } -+ } -+ -+ if (!is_frag && !is_amsdu) { -+ skb_pull(skb, pull_len); -+ skb_push(skb, 14); -+ memcpy(skb->data, ra, MAC_ADDR_LEN); -+ memcpy(&skb->data[6], ta, MAC_ADDR_LEN); -+ memcpy(&skb->data[12], ether_type, 2); -+ } -+ } -+ -+ if (hw_rxhdr->flags_is_80211_mpdu) { -+ remove_sec_hdr_mgmt_frame(hw_rxhdr, skb); -+ rwnx_rx_mgmt_any(rwnx_hw, skb, hw_rxhdr); -+ } else { -+ rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx); -+ -+ if (!rwnx_vif) { -+ dev_err(rwnx_hw->dev, "Frame received but no active vif(%d)", -+ hw_rxhdr->flags_vif_idx); -+ dev_kfree_skb(skb); -+ goto end; -+ } -+ -+ if (hw_rxhdr->flags_sta_idx != RWNX_INVALID_STA) { -+ struct rwnx_sta *sta; -+ -+ sta = &rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx]; -+ rwnx_rx_statistic(rwnx_hw, hw_rxhdr, sta); -+ -+ if (sta->vlan_idx != rwnx_vif->vif_index) { -+ rwnx_vif = rwnx_hw->vif_table[sta->vlan_idx]; -+ if (!rwnx_vif) { -+ dev_kfree_skb(skb); -+ goto end; -+ } -+ } -+ -+ if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) { -+#ifdef CONFIG_GKI -+ rwnx_cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev, -+ sta->mac_addr, GFP_ATOMIC); -+#else -+ cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev, -+ sta->mac_addr, GFP_ATOMIC); -+#endif -+ } -+ } -+ -+ skb->priority = 256 + tid;//hw_rxhdr->flags_user_prio; -+ -+#ifdef AICWF_RX_REORDER -+ rx_priv_tmp = rx_priv; -+ rx_priv_tmp->rwnx_vif = (void *)rwnx_vif; -+ -+ if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) { -+ if (is_qos && hw_rxhdr->flags_need_reord) -+ reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1, hw_rxhdr->flags_is_amsdu); -+ else if (is_qos && !hw_rxhdr->flags_need_reord) { -+ reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid); -+ if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr) && !hw_rxhdr->flags_is_amsdu) -+ dev_kfree_skb(skb); -+ } else { -+ if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr) && !hw_rxhdr->flags_is_amsdu) -+ dev_kfree_skb(skb); -+ } -+ } else if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) { -+#if 1 -+ skb_reset_mac_header(skb); -+ eth = eth_hdr(skb); -+ //printk("da:%pM, %x,%x, len=%d\n", eth->h_dest, skb->data[12], skb->data[13], skb->len); -+ -+ if (unlikely(is_multicast_ether_addr(eth->h_dest))) { -+ /* broadcast pkt need to be forwared to upper layer and resent -+ on wireless interface */ -+ resend = true; -+ } else { -+ /* unicast pkt for STA inside the BSS, no need to forward to upper -+ layer simply resend on wireless interface */ -+ if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA) { -+ struct rwnx_sta *sta = &rwnx_hw->sta_table[hw_rxhdr->flags_dst_idx]; -+ if (sta->valid && (sta->vlan_idx == rwnx_vif->vif_index)) { -+ resend = true; -+ forward = false; -+ } -+ } -+ } -+ -+ if (resend) -+ rwnx_rx_data_skb_resend(rwnx_hw, rwnx_vif, skb, hw_rxhdr); -+ -+ if (forward) { -+ if (is_qos && hw_rxhdr->flags_need_reord) -+ reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1, hw_rxhdr->flags_is_amsdu); -+ else if (is_qos && !hw_rxhdr->flags_need_reord) { -+ reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid); -+ rwnx_rx_data_skb_forward(rwnx_hw, rwnx_vif, skb, hw_rxhdr); -+ } else -+ rwnx_rx_data_skb_forward(rwnx_hw, rwnx_vif, skb, hw_rxhdr); -+ } else if(resend) { -+ if (is_qos && hw_rxhdr->flags_need_reord) -+ reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 0, hw_rxhdr->flags_is_amsdu); -+ else if (is_qos && !hw_rxhdr->flags_need_reord) { -+ reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid); -+ dev_kfree_skb(skb); -+ } -+ }else -+ dev_kfree_skb(skb); -+#else -+ if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr)) -+ dev_kfree_skb(skb); -+#endif -+ } -+#else -+ if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr)) -+ dev_kfree_skb(skb); -+#endif -+ } -+ } -+ -+end: -+ return 0; -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_rx.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_rx.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_rx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_rx.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,392 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_rx.h -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+#ifndef _RWNX_RX_H_ -+#define _RWNX_RX_H_ -+ -+#include "aicwf_txrxif.h" -+ -+#define SERVER_PORT 67 -+#define CLIENT_PORT 68 -+#define DHCP_MAGIC 0x63825363 -+#define DHCP_ACK 5 -+#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */ -+#define DHCP_OPTION_END 255 -+ -+enum rx_status_bits { -+ /// The buffer can be forwarded to the networking stack -+ RX_STAT_FORWARD = 1 << 0, -+ /// A new buffer has to be allocated -+ RX_STAT_ALLOC = 1 << 1, -+ /// The buffer has to be deleted -+ RX_STAT_DELETE = 1 << 2, -+ /// The length of the buffer has to be updated -+ RX_STAT_LEN_UPDATE = 1 << 3, -+ /// The length in the Ethernet header has to be updated -+ RX_STAT_ETH_LEN_UPDATE = 1 << 4, -+ /// Simple copy -+ RX_STAT_COPY = 1 << 5, -+ /// Spurious frame (inform upper layer and discard) -+ RX_STAT_SPURIOUS = 1 << 6, -+ /// packet for monitor interface -+ RX_STAT_MONITOR = 1 << 7, -+}; -+ -+ -+/* -+ * Decryption status subfields. -+ * { -+ */ -+#define RWNX_RX_HD_DECR_UNENC 0 // ENCRYPTION TYPE NONE -+#define RWNX_RX_HD_DECR_WEP 1 // ENCRYPTION TYPE WEP -+#define RWNX_RX_HD_DECR_TKIP 2 // ENCRYPTION TYPE TKIP -+#define RWNX_RX_HD_DECR_CCMP128 3 // ENCRYPTION TYPE CCMP128 -+#define RWNX_RX_HD_DECR_CCMP256 4 // ENCRYPTION TYPE CCMP256 -+#define RWNX_RX_HD_DECR_GCMP128 5 // ENCRYPTION TYPE GCMP128 -+#define RWNX_RX_HD_DECR_GCMP256 6 // ENCRYPTION TYPE GCMP256 -+#define RWNX_RX_HD_DECR_WAPI 7 // ENCRYPTION TYPE WAPI -+// @} -+ -+//#ifdef CONFIG_RWNX_MON_DATA -+#if 0 -+#define RX_MACHDR_BACKUP_LEN 64 -+#endif -+ -+struct rx_vector_1_old { -+ /** Receive Vector 1a */ -+ u32 leg_length :12; -+ u32 leg_rate : 4; -+ u32 ht_length :16; -+ -+ /** Receive Vector 1b */ -+ u32 _ht_length : 4; // FIXME -+ u32 short_gi : 1; -+ u32 stbc : 2; -+ u32 smoothing : 1; -+ u32 mcs : 7; -+ u32 pre_type : 1; -+ u32 format_mod : 3; -+ u32 ch_bw : 2; -+ u32 n_sts : 3; -+ u32 lsig_valid : 1; -+ u32 sounding : 1; -+ u32 num_extn_ss : 2; -+ u32 aggregation : 1; -+ u32 fec_coding : 1; -+ u32 dyn_bw : 1; -+ u32 doze_not_allowed : 1; -+ -+ /** Receive Vector 1c */ -+ u32 antenna_set : 8; -+ u32 partial_aid : 9; -+ u32 group_id : 6; -+ u32 first_user : 1; -+ s32 rssi1 : 8; -+ -+ /** Receive Vector 1d */ -+ s32 rssi2 : 8; -+ s32 rssi3 : 8; -+ s32 rssi4 : 8; -+ u32 reserved_1d : 8; -+}; -+ -+struct rx_leg_vect { -+ u8 dyn_bw_in_non_ht : 1; -+ u8 chn_bw_in_non_ht : 2; -+ u8 rsvd_nht : 4; -+ u8 lsig_valid : 1; -+} __packed; -+ -+struct rx_ht_vect { -+ u16 sounding : 1; -+ u16 smoothing : 1; -+ u16 short_gi : 1; -+ u16 aggregation : 1; -+ u16 stbc : 1; -+ u16 num_extn_ss : 2; -+ u16 lsig_valid : 1; -+ u16 mcs : 7; -+ u16 fec : 1; -+ u16 length :16; -+} __packed; -+ -+struct rx_vht_vect { -+ u8 sounding : 1; -+ u8 beamformed : 1; -+ u8 short_gi : 1; -+ u8 rsvd_vht1 : 1; -+ u8 stbc : 1; -+ u8 doze_not_allowed : 1; -+ u8 first_user : 1; -+ u8 rsvd_vht2 : 1; -+ u16 partial_aid : 9; -+ u16 group_id : 6; -+ u16 rsvd_vht3 : 1; -+ u32 mcs : 4; -+ u32 nss : 3; -+ u32 fec : 1; -+ u32 length :20; -+ u32 rsvd_vht4 : 4; -+} __packed; -+ -+struct rx_he_vect { -+ u8 sounding : 1; -+ u8 beamformed : 1; -+ u8 gi_type : 2; -+ u8 stbc : 1; -+ u8 rsvd_he1 : 3; -+ -+ u8 uplink_flag : 1; -+ u8 beam_change : 1; -+ u8 dcm : 1; -+ u8 he_ltf_type : 2; -+ u8 doppler : 1; -+ u8 rsvd_he2 : 2; -+ -+ u8 bss_color : 6; -+ u8 rsvd_he3 : 2; -+ -+ u8 txop_duration : 7; -+ u8 rsvd_he4 : 1; -+ -+ u8 pe_duration : 4; -+ u8 spatial_reuse : 4; -+ -+ u8 sig_b_comp_mode : 1; -+ u8 dcm_sig_b : 1; -+ u8 mcs_sig_b : 3; -+ u8 ru_size : 3; -+ -+ u32 mcs : 4; -+ u32 nss : 3; -+ u32 fec : 1; -+ u32 length :20; -+ u32 rsvd_he6 : 4; -+} __packed; -+ -+struct rx_vector_1 { -+ u8 format_mod : 4; -+ u8 ch_bw : 3; -+ u8 pre_type : 1; -+ u8 antenna_set : 8; -+ s32 rssi_leg : 8; -+ u32 leg_length :12; -+ u32 leg_rate : 4; -+ s32 rssi1 : 8; -+ -+ union { -+ struct rx_leg_vect leg; -+ struct rx_ht_vect ht; -+ struct rx_vht_vect vht; -+ struct rx_he_vect he; -+ }; -+} __packed; -+ -+struct rx_vector_2_old { -+ /** Receive Vector 2a */ -+ u32 rcpi : 8; -+ u32 evm1 : 8; -+ u32 evm2 : 8; -+ u32 evm3 : 8; -+ -+ /** Receive Vector 2b */ -+ u32 evm4 : 8; -+ u32 reserved2b_1 : 8; -+ u32 reserved2b_2 : 8; -+ u32 reserved2b_3 : 8; -+ -+}; -+ -+struct rx_vector_2 { -+ /** Receive Vector 2a */ -+ u32 rcpi1 : 8; -+ u32 rcpi2 : 8; -+ u32 rcpi3 : 8; -+ u32 rcpi4 : 8; -+ -+ /** Receive Vector 2b */ -+ u32 evm1 : 8; -+ u32 evm2 : 8; -+ u32 evm3 : 8; -+ u32 evm4 : 8; -+}; -+ -+struct phy_channel_info_desc { -+ /** PHY channel information 1 */ -+ u32 phy_band : 8; -+ u32 phy_channel_type : 8; -+ u32 phy_prim20_freq : 16; -+ /** PHY channel information 2 */ -+ u32 phy_center1_freq : 16; -+ u32 phy_center2_freq : 16; -+}; -+ -+struct hw_vect { -+ /** Total length for the MPDU transfer */ -+ u32 len :16; -+ -+ u32 reserved : 8;//data type is included -+ /** AMPDU Status Information */ -+ u32 mpdu_cnt : 6; -+ u32 ampdu_cnt : 2; -+ -+ /** TSF Low */ -+ __le32 tsf_lo; -+ /** TSF High */ -+ __le32 tsf_hi; -+ -+ /** Receive Vector 1 */ -+ struct rx_vector_1 rx_vect1; -+ /** Receive Vector 2 */ -+ struct rx_vector_2 rx_vect2; -+ -+ /** Status **/ -+ u32 rx_vect2_valid : 1; -+ u32 resp_frame : 1; -+ /** Decryption Status */ -+ u32 decr_status : 3; -+ u32 rx_fifo_oflow : 1; -+ -+ /** Frame Unsuccessful */ -+ u32 undef_err : 1; -+ u32 phy_err : 1; -+ u32 fcs_err : 1; -+ u32 addr_mismatch : 1; -+ u32 ga_frame : 1; -+ u32 current_ac : 2; -+ -+ u32 frm_successful_rx : 1; -+ /** Descriptor Done */ -+ u32 desc_done_rx : 1; -+ /** Key Storage RAM Index */ -+ u32 key_sram_index : 10; -+ /** Key Storage RAM Index Valid */ -+ u32 key_sram_v : 1; -+ u32 type : 2; -+ u32 subtype : 4; -+}; -+ -+//#ifdef CONFIG_RWNX_MON_DATA -+#if 0 -+/// MAC header backup descriptor -+struct mon_machdrdesc { -+ /// Length of the buffer -+ u32 buf_len; -+ /// Buffer containing mac header, LLC and SNAP -+ u8 buffer[RX_MACHDR_BACKUP_LEN]; -+}; -+#endif -+ -+struct hw_rxhdr { -+ /** RX vector */ -+ struct hw_vect hwvect; -+ -+ /** PHY channel information */ -+ struct phy_channel_info_desc phy_info; -+ -+ /** RX flags */ -+ u32 flags_is_amsdu : 1; -+ u32 flags_is_80211_mpdu: 1; -+ u32 flags_is_4addr : 1; -+ u32 flags_new_peer : 1; -+#if defined(AICWF_SDIO_SUPPORT) || defined(AICWF_USB_SUPPORT) -+ u32 flags_user_prio : 1; // aic: fw not fill any more -+ u32 flags_need_reord : 1; -+ u32 flags_upload : 1; -+#else -+ u32 flags_user_prio : 3; -+#endif -+#ifndef AICWF_RX_REORDER -+ u32 flags_rsvd0 : 1; -+#else -+ u32 is_monitor_vif : 1; -+#endif -+ u32 flags_vif_idx : 8; // 0xFF if invalid VIF index -+ u32 flags_sta_idx : 8; // 0xFF if invalid STA index -+ u32 flags_dst_idx : 8; // 0xFF if unknown destination STA -+//#ifdef CONFIG_RWNX_MON_DATA -+#if 0 -+ /// MAC header backup descriptor (used only for MSDU when there is a monitor and a data interface) -+ struct mon_machdrdesc mac_hdr_backup; -+#endif -+ /** Pattern indicating if the buffer is available for the driver */ -+ u32 pattern; -+}; -+ -+extern const u8 legrates_lut[]; -+extern u16 legrates_lut_rate[]; -+extern u16 tx_legrates_lut_rate[]; -+ -+struct DHCPInfo { -+ u8 op; -+ u8 htype; -+ u8 hlen; -+ u8 hops; -+ u32 xid; -+ u16 secs; -+ u16 flags; -+ u32 ciaddr; -+ u32 yiaddr; -+ u32 siaddr; -+ u32 giaddr; -+ u8 chaddr[16]; -+ u8 sname[64]; -+ u8 file[128]; -+ u32 cookie; -+ u8 options[308]; /* 312 - cookie */ -+}; -+ -+u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv); -+int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv); -+ -+#ifdef AICWF_ARP_OFFLOAD -+void arpoffload_proc(struct sk_buff *skb, struct rwnx_vif *rwnx_vif); -+#endif -+#ifdef AICWF_RX_REORDER -+struct recv_msdu *reord_rxframe_alloc(spinlock_t *lock, struct list_head *q); -+void reord_rxframe_free(spinlock_t *lock, struct list_head *q, struct list_head *list); -+struct reord_ctrl_info *reord_init_sta(struct aicwf_rx_priv *rx_priv, const u8 *mac_addr); -+void reord_deinit_sta(struct aicwf_rx_priv *rx_priv, struct reord_ctrl_info *reord_info); -+int reord_need_check(struct reord_ctrl *preorder_ctrl, u16 seq_num); -+int reord_rxframe_enqueue(struct reord_ctrl *preorder_ctrl, struct recv_msdu *prframe); -+void reord_timeout_worker(struct work_struct *work); -+int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prframe); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) -+void reord_timeout_handler (ulong data); -+#else -+void reord_timeout_handler (struct timer_list *t); -+#endif -+ -+#endif -+void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx, -+ struct sk_buff_head *list); -+ -+#ifdef CONFIG_HE_FOR_OLD_KERNEL -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 197) -+struct element { -+ u8 id; -+ u8 datalen; -+ u8 data[]; -+}; -+/* element iteration helpers */ -+#define for_each_element(_elem, _data, _datalen) \ -+ for (_elem = (const struct element *)(_data); \ -+ (const u8 *)(_data) + (_datalen) - (const u8 *)_elem >= \ -+ (int)sizeof(*_elem) && \ -+ (const u8 *)(_data) + (_datalen) - (const u8 *)_elem >= \ -+ (int)sizeof(*_elem) + _elem->datalen; \ -+ _elem = (const struct element *)(_elem->data + _elem->datalen)) -+ -+#define for_each_element_id(element, _id, data, datalen) \ -+ for_each_element(element, data, datalen) \ -+ if (element->id == (_id)) -+#endif -+#endif -+ -+#endif /* _RWNX_RX_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_strs.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_strs.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_strs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_strs.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,266 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_strs.c -+ * -+ * @brief Miscellaneous debug strings -+ * -+ * Copyright (C) RivieraWaves 2014-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#include "lmac_msg.h" -+static const char *const rwnx_mmid2str[MSG_I(MM_MAX)] = { -+ [MSG_I(MM_RESET_REQ)] = "MM_RESET_REQ", -+ [MSG_I(MM_RESET_CFM)] = "MM_RESET_CFM", -+ [MSG_I(MM_START_REQ)] = "MM_START_REQ", -+ [MSG_I(MM_START_CFM)] = "MM_START_CFM", -+ [MSG_I(MM_VERSION_REQ)] = "MM_VERSION_REQ", -+ [MSG_I(MM_VERSION_CFM)] = "MM_VERSION_CFM", -+ [MSG_I(MM_ADD_IF_REQ)] = "MM_ADD_IF_REQ", -+ [MSG_I(MM_ADD_IF_CFM)] = "MM_ADD_IF_CFM", -+ [MSG_I(MM_REMOVE_IF_REQ)] = "MM_REMOVE_IF_REQ", -+ [MSG_I(MM_REMOVE_IF_CFM)] = "MM_REMOVE_IF_CFM", -+ [MSG_I(MM_STA_ADD_REQ)] = "MM_STA_ADD_REQ", -+ [MSG_I(MM_STA_ADD_CFM)] = "MM_STA_ADD_CFM", -+ [MSG_I(MM_STA_DEL_REQ)] = "MM_STA_DEL_REQ", -+ [MSG_I(MM_STA_DEL_CFM)] = "MM_STA_DEL_CFM", -+ [MSG_I(MM_SET_FILTER_REQ)] = "MM_SET_FILTER_REQ", -+ [MSG_I(MM_SET_FILTER_CFM)] = "MM_SET_FILTER_CFM", -+ [MSG_I(MM_SET_CHANNEL_REQ)] = "MM_SET_CHANNEL_REQ", -+ [MSG_I(MM_SET_CHANNEL_CFM)] = "MM_SET_CHANNEL_CFM", -+ [MSG_I(MM_SET_DTIM_REQ)] = "MM_SET_DTIM_REQ", -+ [MSG_I(MM_SET_DTIM_CFM)] = "MM_SET_DTIM_CFM", -+ [MSG_I(MM_SET_BEACON_INT_REQ)] = "MM_SET_BEACON_INT_REQ", -+ [MSG_I(MM_SET_BEACON_INT_CFM)] = "MM_SET_BEACON_INT_CFM", -+ [MSG_I(MM_SET_BASIC_RATES_REQ)] = "MM_SET_BASIC_RATES_REQ", -+ [MSG_I(MM_SET_BASIC_RATES_CFM)] = "MM_SET_BASIC_RATES_CFM", -+ [MSG_I(MM_SET_BSSID_REQ)] = "MM_SET_BSSID_REQ", -+ [MSG_I(MM_SET_BSSID_CFM)] = "MM_SET_BSSID_CFM", -+ [MSG_I(MM_SET_EDCA_REQ)] = "MM_SET_EDCA_REQ", -+ [MSG_I(MM_SET_EDCA_CFM)] = "MM_SET_EDCA_CFM", -+ [MSG_I(MM_SET_MODE_REQ)] = "MM_SET_MODE_REQ", -+ [MSG_I(MM_SET_MODE_CFM)] = "MM_SET_MODE_CFM", -+ [MSG_I(MM_SET_VIF_STATE_REQ)] = "MM_SET_VIF_STATE_REQ", -+ [MSG_I(MM_SET_VIF_STATE_CFM)] = "MM_SET_VIF_STATE_CFM", -+ [MSG_I(MM_SET_SLOTTIME_REQ)] = "MM_SET_SLOTTIME_REQ", -+ [MSG_I(MM_SET_SLOTTIME_CFM)] = "MM_SET_SLOTTIME_CFM", -+ [MSG_I(MM_SET_IDLE_REQ)] = "MM_SET_IDLE_REQ", -+ [MSG_I(MM_SET_IDLE_CFM)] = "MM_SET_IDLE_CFM", -+ [MSG_I(MM_KEY_ADD_REQ)] = "MM_KEY_ADD_REQ", -+ [MSG_I(MM_KEY_ADD_CFM)] = "MM_KEY_ADD_CFM", -+ [MSG_I(MM_KEY_DEL_REQ)] = "MM_KEY_DEL_REQ", -+ [MSG_I(MM_KEY_DEL_CFM)] = "MM_KEY_DEL_CFM", -+ [MSG_I(MM_BA_ADD_REQ)] = "MM_BA_ADD_REQ", -+ [MSG_I(MM_BA_ADD_CFM)] = "MM_BA_ADD_CFM", -+ [MSG_I(MM_BA_DEL_REQ)] = "MM_BA_DEL_REQ", -+ [MSG_I(MM_BA_DEL_CFM)] = "MM_BA_DEL_CFM", -+ [MSG_I(MM_PRIMARY_TBTT_IND)] = "MM_PRIMARY_TBTT_IND", -+ [MSG_I(MM_SECONDARY_TBTT_IND)] = "MM_SECONDARY_TBTT_IND", -+ [MSG_I(MM_SET_POWER_REQ)] = "MM_SET_POWER_REQ", -+ [MSG_I(MM_SET_POWER_CFM)] = "MM_SET_POWER_CFM", -+ [MSG_I(MM_DBG_TRIGGER_REQ)] = "MM_DBG_TRIGGER_REQ", -+ [MSG_I(MM_SET_PS_MODE_REQ)] = "MM_SET_PS_MODE_REQ", -+ [MSG_I(MM_SET_PS_MODE_CFM)] = "MM_SET_PS_MODE_CFM", -+ [MSG_I(MM_CHAN_CTXT_ADD_REQ)] = "MM_CHAN_CTXT_ADD_REQ", -+ [MSG_I(MM_CHAN_CTXT_ADD_CFM)] = "MM_CHAN_CTXT_ADD_CFM", -+ [MSG_I(MM_CHAN_CTXT_DEL_REQ)] = "MM_CHAN_CTXT_DEL_REQ", -+ [MSG_I(MM_CHAN_CTXT_DEL_CFM)] = "MM_CHAN_CTXT_DEL_CFM", -+ [MSG_I(MM_CHAN_CTXT_LINK_REQ)] = "MM_CHAN_CTXT_LINK_REQ", -+ [MSG_I(MM_CHAN_CTXT_LINK_CFM)] = "MM_CHAN_CTXT_LINK_CFM", -+ [MSG_I(MM_CHAN_CTXT_UNLINK_REQ)] = "MM_CHAN_CTXT_UNLINK_REQ", -+ [MSG_I(MM_CHAN_CTXT_UNLINK_CFM)] = "MM_CHAN_CTXT_UNLINK_CFM", -+ [MSG_I(MM_CHAN_CTXT_UPDATE_REQ)] = "MM_CHAN_CTXT_UPDATE_REQ", -+ [MSG_I(MM_CHAN_CTXT_UPDATE_CFM)] = "MM_CHAN_CTXT_UPDATE_CFM", -+ [MSG_I(MM_CHAN_CTXT_SCHED_REQ)] = "MM_CHAN_CTXT_SCHED_REQ", -+ [MSG_I(MM_CHAN_CTXT_SCHED_CFM)] = "MM_CHAN_CTXT_SCHED_CFM", -+ [MSG_I(MM_BCN_CHANGE_REQ)] = "MM_BCN_CHANGE_REQ", -+ [MSG_I(MM_BCN_CHANGE_CFM)] = "MM_BCN_CHANGE_CFM", -+ [MSG_I(MM_TIM_UPDATE_REQ)] = "MM_TIM_UPDATE_REQ", -+ [MSG_I(MM_TIM_UPDATE_CFM)] = "MM_TIM_UPDATE_CFM", -+ [MSG_I(MM_CONNECTION_LOSS_IND)] = "MM_CONNECTION_LOSS_IND", -+ [MSG_I(MM_CHANNEL_SWITCH_IND)] = "MM_CHANNEL_SWITCH_IND", -+ [MSG_I(MM_CHANNEL_PRE_SWITCH_IND)] = "MM_CHANNEL_PRE_SWITCH_IND", -+ [MSG_I(MM_REMAIN_ON_CHANNEL_REQ)] = "MM_REMAIN_ON_CHANNEL_REQ", -+ [MSG_I(MM_REMAIN_ON_CHANNEL_CFM)] = "MM_REMAIN_ON_CHANNEL_CFM", -+ [MSG_I(MM_REMAIN_ON_CHANNEL_EXP_IND)] = "MM_REMAIN_ON_CHANNEL_EXP_IND", -+ [MSG_I(MM_PS_CHANGE_IND)] = "MM_PS_CHANGE_IND", -+ [MSG_I(MM_TRAFFIC_REQ_IND)] = "MM_TRAFFIC_REQ_IND", -+ [MSG_I(MM_SET_PS_OPTIONS_REQ)] = "MM_SET_PS_OPTIONS_REQ", -+ [MSG_I(MM_SET_PS_OPTIONS_CFM)] = "MM_SET_PS_OPTIONS_CFM", -+ [MSG_I(MM_P2P_VIF_PS_CHANGE_IND)] = "MM_P2P_VIF_PS_CHANGE_IND", -+ [MSG_I(MM_CSA_COUNTER_IND)] = "MM_CSA_COUNTER_IND", -+ [MSG_I(MM_CHANNEL_SURVEY_IND)] = "MM_CHANNEL_SURVEY_IND", -+ [MSG_I(MM_SET_P2P_NOA_REQ)] = "MM_SET_P2P_NOA_REQ", -+ [MSG_I(MM_SET_P2P_OPPPS_REQ)] = "MM_SET_P2P_OPPPS_REQ", -+ [MSG_I(MM_SET_P2P_NOA_CFM)] = "MM_SET_P2P_NOA_CFM", -+ [MSG_I(MM_SET_P2P_OPPPS_CFM)] = "MM_SET_P2P_OPPPS_CFM", -+ [MSG_I(MM_CFG_RSSI_REQ)] = "MM_CFG_RSSI_REQ", -+ [MSG_I(MM_RSSI_STATUS_IND)] = "MM_RSSI_STATUS_IND", -+ [MSG_I(MM_CSA_FINISH_IND)] = "MM_CSA_FINISH_IND", -+ [MSG_I(MM_CSA_TRAFFIC_IND)] = "MM_CSA_TRAFFIC_IND", -+ [MSG_I(MM_MU_GROUP_UPDATE_REQ)] = "MM_MU_GROUP_UPDATE_REQ", -+ [MSG_I(MM_MU_GROUP_UPDATE_CFM)] = "MM_MU_GROUP_UPDATE_CFM", -+ -+ [MSG_I(MM_SET_ARPOFFLOAD_REQ)] = "MM_SET_ARPOFFLOAD_REQ", -+ [MSG_I(MM_SET_ARPOFFLOAD_CFM)] = "MM_SET_ARPOFFLOAD_CFM", -+ [MSG_I(MM_SET_AGG_DISABLE_REQ)] = "MM_SET_AGG_DISABLE_REQ", -+ [MSG_I(MM_SET_AGG_DISABLE_CFM)] = "MM_SET_AGG_DISABLE_CFM", -+ [MSG_I(MM_SET_COEX_REQ)] = "MM_SET_COEX_REQ", -+ [MSG_I(MM_SET_COEX_CFM)] = "MM_SET_COEX_CFM", -+ [MSG_I(MM_SET_RF_CONFIG_REQ)] = "MM_SET_RF_CONFIG_REQ", -+ [MSG_I(MM_SET_RF_CONFIG_CFM)] = "MM_SET_RF_CONFIG_CFM", -+ [MSG_I(MM_SET_RF_CALIB_REQ)] = "MM_SET_RF_CALIB_REQ", -+ [MSG_I(MM_SET_RF_CALIB_CFM)] = "MM_SET_RF_CALIB_CFM", -+ -+ [MSG_I(MM_GET_MAC_ADDR_REQ)] = "MM_GET_MAC_ADDR_REQ", -+ [MSG_I(MM_GET_MAC_ADDR_CFM)] = "MM_GET_MAC_ADDR_CFM", -+ [MSG_I(MM_GET_STA_INFO_REQ)] = "MM_GET_STA_INFO_REQ", -+ [MSG_I(MM_GET_STA_INFO_CFM)] = "MM_GET_STA_INFO_CFM", -+ [MSG_I(MM_SET_TXPWR_IDX_LVL_REQ)] = "MM_SET_TXPWR_IDX_LVL_REQ", -+ [MSG_I(MM_SET_TXPWR_IDX_LVL_CFM)] = "MM_SET_TXPWR_IDX_LVL_CFM", -+ [MSG_I(MM_SET_TXPWR_OFST_REQ)] = "MM_SET_TXPWR_OFST_REQ", -+ [MSG_I(MM_SET_TXPWR_OFST_CFM)] = "MM_SET_TXPWR_OFST_CFM", -+ [MSG_I(MM_SET_STACK_START_REQ)] = "MM_SET_STACK_START_REQ", -+ [MSG_I(MM_SET_STACK_START_CFM)] = "MM_SET_STACK_START_CFM", -+ [MSG_I(MM_APM_STALOSS_IND)] = "MM_APM_STALOSS_IND", -+ [MSG_I(MM_SET_VENDOR_HWCONFIG_REQ)] = "MM_SET_VENDOR_HWCONFIG_REQ", -+ [MSG_I(MM_SET_VENDOR_HWCONFIG_CFM)] = "MM_SET_VENDOR_HWCONFIG_CFM", -+ [MSG_I(MM_GET_FW_VERSION_REQ)] = "MM_GET_FW_VERSION_REQ", -+ [MSG_I(MM_GET_FW_VERSION_CFM)] = "MM_GET_FW_VERSION_CFM", -+ [MSG_I(MM_SET_RESUME_RESTORE_REQ)] = "MM_SET_RESUME_RESTORE_REQ", -+ [MSG_I(MM_SET_RESUME_RESTORE_CFM)] = "MM_SET_RESUME_RESTORE_CFM", -+ [MSG_I(MM_GET_WIFI_DISABLE_REQ)] = "MM_GET_WIFI_DISABLE_REQ", -+ [MSG_I(MM_GET_WIFI_DISABLE_CFM)] = "MM_GET_WIFI_DISABLE_CFM", -+ [MSG_I(MM_CFG_RSSI_CFM)] = "MM_CFG_RSSI_CFM", -+}; -+ -+static const char *const rwnx_dbgid2str[MSG_I(DBG_MAX)] = { -+ [MSG_I(DBG_MEM_READ_REQ)] = "DBG_MEM_READ_REQ", -+ [MSG_I(DBG_MEM_READ_CFM)] = "DBG_MEM_READ_CFM", -+ [MSG_I(DBG_MEM_WRITE_REQ)] = "DBG_MEM_WRITE_REQ", -+ [MSG_I(DBG_MEM_WRITE_CFM)] = "DBG_MEM_WRITE_CFM", -+ [MSG_I(DBG_SET_MOD_FILTER_REQ)] = "DBG_SET_MOD_FILTER_REQ", -+ [MSG_I(DBG_SET_MOD_FILTER_CFM)] = "DBG_SET_MOD_FILTER_CFM", -+ [MSG_I(DBG_SET_SEV_FILTER_REQ)] = "DBG_SET_SEV_FILTER_REQ", -+ [MSG_I(DBG_SET_SEV_FILTER_CFM)] = "DBG_SET_SEV_FILTER_CFM", -+ [MSG_I(DBG_ERROR_IND)] = "DBG_ERROR_IND", -+ [MSG_I(DBG_GET_SYS_STAT_REQ)] = "DBG_GET_SYS_STAT_REQ", -+ [MSG_I(DBG_GET_SYS_STAT_CFM)] = "DBG_GET_SYS_STAT_CFM", -+}; -+ -+static const char *const rwnx_scanid2str[MSG_I(SCAN_MAX)] = { -+ [MSG_I(SCAN_START_REQ)] = "SCAN_START_REQ", -+ [MSG_I(SCAN_START_CFM)] = "SCAN_START_CFM", -+ [MSG_I(SCAN_DONE_IND)] = "SCAN_DONE_IND", -+}; -+ -+static const char *const rwnx_tdlsid2str[MSG_I(TDLS_MAX)] = { -+ [MSG_I(TDLS_CHAN_SWITCH_CFM)] = "TDLS_CHAN_SWITCH_CFM", -+ [MSG_I(TDLS_CHAN_SWITCH_REQ)] = "TDLS_CHAN_SWITCH_REQ", -+ [MSG_I(TDLS_CHAN_SWITCH_IND)] = "TDLS_CHAN_SWITCH_IND", -+ [MSG_I(TDLS_CHAN_SWITCH_BASE_IND)] = "TDLS_CHAN_SWITCH_BASE_IND", -+ [MSG_I(TDLS_CANCEL_CHAN_SWITCH_REQ)] = "TDLS_CANCEL_CHAN_SWITCH_REQ", -+ [MSG_I(TDLS_CANCEL_CHAN_SWITCH_CFM)] = "TDLS_CANCEL_CHAN_SWITCH_CFM", -+ [MSG_I(TDLS_PEER_PS_IND)] = "TDLS_PEER_PS_IND", -+ [MSG_I(TDLS_PEER_TRAFFIC_IND_REQ)] = "TDLS_PEER_TRAFFIC_IND_REQ", -+ [MSG_I(TDLS_PEER_TRAFFIC_IND_CFM)] = "TDLS_PEER_TRAFFIC_IND_CFM", -+}; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+static const char *const rwnx_scanuid2str[MSG_I(SCANU_MAX)] = { -+ [MSG_I(SCANU_START_REQ)] = "SCANU_START_REQ", -+ [MSG_I(SCANU_START_CFM)] = "SCANU_START_CFM", -+ [MSG_I(SCANU_JOIN_REQ)] = "SCANU_JOIN_REQ", -+ [MSG_I(SCANU_JOIN_CFM)] = "SCANU_JOIN_CFM", -+ [MSG_I(SCANU_RESULT_IND)] = "SCANU_RESULT_IND", -+ [MSG_I(SCANU_FAST_REQ)] = "SCANU_FAST_REQ", -+ [MSG_I(SCANU_FAST_CFM)] = "SCANU_FAST_CFM", -+ [MSG_I(SCANU_VENDOR_IE_REQ)] = "SCANU_VENDOR_IE_REQ", -+ [MSG_I(SCANU_VENDOR_IE_CFM)] = "SCANU_VENDOR_IE_CFM", -+ [MSG_I(SCANU_START_CFM_ADDTIONAL)] = "SCANU_START_CFM_ADDTIONAL", -+ [MSG_I(SCANU_CANCEL_REQ)] = "SCANU_CANCEL_REQ", -+ [MSG_I(SCANU_CANCEL_CFM)] = "SCANU_CANCEL_CFM", -+}; -+ -+static const char *const rwnx_meid2str[MSG_I(ME_MAX)] = { -+ [MSG_I(ME_CONFIG_REQ)] = "ME_CONFIG_REQ", -+ [MSG_I(ME_CONFIG_CFM)] = "ME_CONFIG_CFM", -+ [MSG_I(ME_CHAN_CONFIG_REQ)] = "ME_CHAN_CONFIG_REQ", -+ [MSG_I(ME_CHAN_CONFIG_CFM)] = "ME_CHAN_CONFIG_CFM", -+ [MSG_I(ME_SET_CONTROL_PORT_REQ)] = "ME_SET_CONTROL_PORT_REQ", -+ [MSG_I(ME_SET_CONTROL_PORT_CFM)] = "ME_SET_CONTROL_PORT_CFM", -+ [MSG_I(ME_TKIP_MIC_FAILURE_IND)] = "ME_TKIP_MIC_FAILURE_IND", -+ [MSG_I(ME_STA_ADD_REQ)] = "ME_STA_ADD_REQ", -+ [MSG_I(ME_STA_ADD_CFM)] = "ME_STA_ADD_CFM", -+ [MSG_I(ME_STA_DEL_REQ)] = "ME_STA_DEL_REQ", -+ [MSG_I(ME_STA_DEL_CFM)] = "ME_STA_DEL_CFM", -+ [MSG_I(ME_TX_CREDITS_UPDATE_IND)]= "ME_TX_CREDITS_UPDATE_IND", -+ [MSG_I(ME_RC_STATS_REQ)] = "ME_RC_STATS_REQ", -+ [MSG_I(ME_RC_STATS_CFM)] = "ME_RC_STATS_CFM", -+ [MSG_I(ME_RC_SET_RATE_REQ)] = "ME_RC_SET_RATE_REQ", -+ [MSG_I(ME_TRAFFIC_IND_REQ)] = "ME_TRAFFIC_IND_REQ", -+ [MSG_I(ME_TRAFFIC_IND_CFM)] = "ME_TRAFFIC_IND_CFM", -+ [MSG_I(ME_SET_PS_MODE_REQ)] = "ME_SET_PS_MODE_REQ", -+ [MSG_I(ME_SET_PS_MODE_CFM)] = "ME_SET_PS_MODE_CFM", -+}; -+ -+static const char *const rwnx_smid2str[MSG_I(SM_MAX)] = { -+ [MSG_I(SM_CONNECT_REQ)] = "SM_CONNECT_REQ", -+ [MSG_I(SM_CONNECT_CFM)] = "SM_CONNECT_CFM", -+ [MSG_I(SM_CONNECT_IND)] = "SM_CONNECT_IND", -+ [MSG_I(SM_DISCONNECT_REQ)] = "SM_DISCONNECT_REQ", -+ [MSG_I(SM_DISCONNECT_CFM)] = "SM_DISCONNECT_CFM", -+ [MSG_I(SM_DISCONNECT_IND)] = "SM_DISCONNECT_IND", -+ [MSG_I(SM_EXTERNAL_AUTH_REQUIRED_IND)] = "SM_EXTERNAL_AUTH_REQUIRED_IND", -+ [MSG_I(SM_EXTERNAL_AUTH_REQUIRED_RSP)] = "SM_EXTERNAL_AUTH_REQUIRED_RSP", -+ [MSG_I(SM_EXTERNAL_AUTH_REQUIRED_RSP_CFM)] = "SM_EXTERNAL_AUTH_REQUIRED_RSP_CFM", -+}; -+ -+static const char *const rwnx_apmid2str[MSG_I(APM_MAX)] = { -+ [MSG_I(APM_START_REQ)] = "APM_START_REQ", -+ [MSG_I(APM_START_CFM)] = "APM_START_CFM", -+ [MSG_I(APM_STOP_REQ)] = "APM_STOP_REQ", -+ [MSG_I(APM_STOP_CFM)] = "APM_STOP_CFM", -+ [MSG_I(APM_START_CAC_REQ)] = "APM_START_CAC_REQ", -+ [MSG_I(APM_START_CAC_CFM)] = "APM_START_CAC_CFM", -+ [MSG_I(APM_STOP_CAC_REQ)] = "APM_STOP_CAC_REQ", -+ [MSG_I(APM_STOP_CAC_CFM)] = "APM_STOP_CAC_CFM", -+ [MSG_I(APM_SET_BEACON_IE_REQ)] = "APM_SET_BEACON_IE_REQ", -+ [MSG_I(APM_SET_BEACON_IE_CFM)] = "APM_SET_BEACON_IE_CFM", -+}; -+ -+static const char *const rwnx_meshid2str[MSG_I(MESH_MAX)] = { -+ [MSG_I(MESH_START_REQ)] = "MESH_START_REQ", -+ [MSG_I(MESH_START_CFM)] = "MESH_START_CFM", -+ [MSG_I(MESH_STOP_REQ)] = "MESH_STOP_REQ", -+ [MSG_I(MESH_STOP_CFM)] = "MESH_STOP_CFM", -+ [MSG_I(MESH_UPDATE_REQ)] = "MESH_UPDATE_REQ", -+ [MSG_I(MESH_UPDATE_CFM)] = "MESH_UPDATE_CFM", -+ [MSG_I(MESH_PATH_CREATE_REQ)] = "MESH_PATH_CREATE_REQ", -+ [MSG_I(MESH_PATH_CREATE_CFM)] = "MESH_PATH_CREATE_CFM", -+ [MSG_I(MESH_PATH_UPDATE_REQ)] = "MESH_PATH_UPDATE_REQ", -+ [MSG_I(MESH_PATH_UPDATE_CFM)] = "MESH_PATH_UPDATE_CFM", -+ [MSG_I(MESH_PROXY_ADD_REQ)] = "MESH_PROXY_ADD_REQ", -+ [MSG_I(MESH_PEER_UPDATE_IND)] = "MESH_PEER_UPDATE_IND", -+ [MSG_I(MESH_PATH_UPDATE_IND)] = "MESH_PATH_UPDATE_IND", -+ [MSG_I(MESH_PROXY_UPDATE_IND)] = "MESH_PROXY_UPDATE_IND", -+}; -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+const char *const *rwnx_id2str[TASK_LAST_EMB + 1] = { -+ [TASK_MM] = rwnx_mmid2str, -+ [TASK_DBG] = rwnx_dbgid2str, -+ [TASK_SCAN] = rwnx_scanid2str, -+ [TASK_TDLS] = rwnx_tdlsid2str, -+#ifdef CONFIG_RWNX_FULLMAC -+ [TASK_SCANU] = rwnx_scanuid2str, -+ [TASK_ME] = rwnx_meid2str, -+ [TASK_SM] = rwnx_smid2str, -+ [TASK_APM] = rwnx_apmid2str, -+ [TASK_MESH] = rwnx_meshid2str, -+#endif -+}; -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_strs.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_strs.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_strs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_strs.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,31 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_strs.h -+ * -+ * @brief Miscellaneous debug strings -+ * -+ * Copyright (C) RivieraWaves 2014-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef _RWNX_STRS_H_ -+#define _RWNX_STRS_H_ -+ -+#ifdef CONFIG_RWNX_FHOST -+ -+#define RWNX_ID2STR(tag) "Cmd" -+ -+#else -+#include "lmac_msg.h" -+ -+#define RWNX_ID2STR(tag) (((MSG_T(tag) < ARRAY_SIZE(rwnx_id2str)) && \ -+ (rwnx_id2str[MSG_T(tag)]) && \ -+ ((rwnx_id2str[MSG_T(tag)])[MSG_I(tag)])) ? \ -+ (rwnx_id2str[MSG_T(tag)])[MSG_I(tag)] : "unknown") -+ -+extern const char *const *rwnx_id2str[TASK_LAST_EMB + 1]; -+#endif /* CONFIG_RWNX_FHOST */ -+ -+#endif /* _RWNX_STRS_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tdls.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tdls.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tdls.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tdls.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,785 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_tx.c -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+/** -+ * INCLUDE FILES -+ ****************************************************************************** -+ */ -+ -+#include "rwnx_tdls.h" -+#include "rwnx_compat.h" -+ -+/** -+ * FUNCTION DEFINITIONS -+ ****************************************************************************** -+ */ -+ -+static u16 -+rwnx_get_tdls_sta_capab(struct rwnx_vif *rwnx_vif, u16 status_code) -+{ -+ u16 capab = 0; -+ -+ /* The capability will be 0 when sending a failure code */ -+ if (status_code != 0) -+ return capab; -+ -+ if (rwnx_vif->sta.ap->band != NL80211_BAND_2GHZ) -+ return capab; -+ -+ capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; -+ capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; -+ -+ return capab; -+} -+ -+static int -+rwnx_tdls_prepare_encap_data(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, struct sk_buff *skb) -+{ -+ struct ieee80211_tdls_data *tf; -+ tf = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_data) - sizeof(tf->u)); -+ -+ // set eth header -+ memcpy(tf->da, peer, ETH_ALEN); -+ memcpy(tf->sa, rwnx_hw->wiphy->perm_addr, ETH_ALEN); -+ tf->ether_type = cpu_to_be16(ETH_P_TDLS); -+ -+ // set common TDLS info -+ tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; -+ tf->category = WLAN_CATEGORY_TDLS; -+ tf->action_code = action_code; -+ -+ // set action specific TDLS info -+ switch (action_code) { -+ case WLAN_TDLS_SETUP_REQUEST: -+ skb_put(skb, sizeof(tf->u.setup_req)); -+ tf->u.setup_req.dialog_token = dialog_token; -+ tf->u.setup_req.capability = -+ cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code)); -+ break; -+ -+ case WLAN_TDLS_SETUP_RESPONSE: -+ skb_put(skb, sizeof(tf->u.setup_resp)); -+ tf->u.setup_resp.status_code = cpu_to_le16(status_code); -+ tf->u.setup_resp.dialog_token = dialog_token; -+ tf->u.setup_resp.capability = -+ cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code)); -+ break; -+ -+ case WLAN_TDLS_SETUP_CONFIRM: -+ skb_put(skb, sizeof(tf->u.setup_cfm)); -+ tf->u.setup_cfm.status_code = cpu_to_le16(status_code); -+ tf->u.setup_cfm.dialog_token = dialog_token; -+ break; -+ -+ case WLAN_TDLS_TEARDOWN: -+ skb_put(skb, sizeof(tf->u.teardown)); -+ tf->u.teardown.reason_code = cpu_to_le16(status_code); -+ break; -+ -+ case WLAN_TDLS_DISCOVERY_REQUEST: -+ skb_put(skb, sizeof(tf->u.discover_req)); -+ tf->u.discover_req.dialog_token = dialog_token; -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+rwnx_prep_tdls_direct(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, struct sk_buff *skb) -+{ -+ struct ieee80211_mgmt *mgmt; -+ -+ mgmt = (void *)skb_put(skb, 24); -+ memset(mgmt, 0, 24); -+ memcpy(mgmt->da, peer, ETH_ALEN); -+ memcpy(mgmt->sa, rwnx_hw->wiphy->perm_addr, ETH_ALEN); -+ memcpy(mgmt->bssid, rwnx_vif->sta.ap->mac_addr, ETH_ALEN); -+ -+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | -+ IEEE80211_STYPE_ACTION); -+ -+ switch (action_code) { -+ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: -+ skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp)); -+ mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; -+ mgmt->u.action.u.tdls_discover_resp.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES; -+ mgmt->u.action.u.tdls_discover_resp.dialog_token = dialog_token; -+ mgmt->u.action.u.tdls_discover_resp.capability = -+ cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code)); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+rwnx_add_srates_ie(struct rwnx_hw *rwnx_hw, struct sk_buff *skb) -+{ -+ u8 i, rates, *pos; -+ int rate; -+ struct ieee80211_supported_band *rwnx_band_2GHz = rwnx_hw->wiphy->bands[NL80211_BAND_2GHZ]; -+ -+ rates = 8; -+ -+ if (skb_tailroom(skb) < rates + 2) -+ return -ENOMEM; -+ -+ pos = skb_put(skb, rates + 2); -+ *pos++ = WLAN_EID_SUPP_RATES; -+ *pos++ = rates; -+ for (i = 0; i < rates; i++) { -+ rate = rwnx_band_2GHz->bitrates[i].bitrate; -+ rate = DIV_ROUND_UP(rate, 5); -+ *pos++ = (u8)rate; -+ } -+ -+ return 0; -+} -+ -+static int -+rwnx_add_ext_srates_ie(struct rwnx_hw *rwnx_hw, struct sk_buff *skb) -+{ -+ u8 i, exrates, *pos; -+ int rate; -+ struct ieee80211_supported_band *rwnx_band_2GHz = rwnx_hw->wiphy->bands[NL80211_BAND_2GHZ]; -+ -+ exrates = rwnx_band_2GHz->n_bitrates - 8; -+ -+ if (skb_tailroom(skb) < exrates + 2) -+ return -ENOMEM; -+ -+ pos = skb_put(skb, exrates + 2); -+ *pos++ = WLAN_EID_EXT_SUPP_RATES; -+ *pos++ = exrates; -+ for (i = 8; i < (8+exrates); i++) { -+ rate = rwnx_band_2GHz->bitrates[i].bitrate; -+ rate = DIV_ROUND_UP(rate, 5); -+ *pos++ = (u8)rate; -+ } -+ -+ return 0; -+} -+ -+static void -+rwnx_tdls_add_supp_channels(struct rwnx_hw *rwnx_hw, struct sk_buff *skb) -+{ -+ /* -+ * Add possible channels for TDLS. These are channels that are allowed -+ * to be active. -+ */ -+ u8 subband_cnt = 0; -+ u8 *pos_subband; -+ u8 *pos = skb_put(skb, 2); -+ struct ieee80211_supported_band *rwnx_band_2GHz = rwnx_hw->wiphy->bands[NL80211_BAND_2GHZ]; -+ struct ieee80211_supported_band *rwnx_band_5GHz = rwnx_hw->wiphy->bands[NL80211_BAND_5GHZ]; -+ -+ *pos++ = WLAN_EID_SUPPORTED_CHANNELS; -+ -+ /* -+ * 5GHz and 2GHz channels numbers can overlap. Ignore this for now, as -+ * this doesn't happen in real world scenarios. -+ */ -+ -+ /* 2GHz, with 5MHz spacing */ -+ pos_subband = skb_put(skb, 2); -+ if (rwnx_band_2GHz->n_channels > 0) { -+ *pos_subband++ = ieee80211_frequency_to_channel(rwnx_band_2GHz->channels[0].center_freq); -+ *pos_subband++ = rwnx_band_2GHz->n_channels; -+ subband_cnt++; -+ } -+ -+ /* 5GHz, with 20MHz spacing */ -+ pos_subband = skb_put(skb, 2); -+ if (rwnx_hw->band_5g_support) { -+ if (rwnx_band_5GHz->n_channels > 0) { -+ *pos_subband++ = ieee80211_frequency_to_channel(rwnx_band_5GHz->channels[0].center_freq); -+ *pos_subband++ = rwnx_band_5GHz->n_channels; -+ subband_cnt++; -+ } -+ } -+ /* length */ -+ *pos = 2 * subband_cnt; -+} -+ -+static void -+rwnx_tdls_add_ext_capab(struct rwnx_hw *rwnx_hw, struct sk_buff *skb) -+{ -+ u8 *pos = (void *)skb_put(skb, 7); -+ bool chan_switch = rwnx_hw->wiphy->features & -+ NL80211_FEATURE_TDLS_CHANNEL_SWITCH; -+ -+ *pos++ = WLAN_EID_EXT_CAPABILITY; -+ *pos++ = 5; /* len */ -+ *pos++ = 0x0; -+ *pos++ = 0x0; -+ *pos++ = 0x0; -+ *pos++ = WLAN_EXT_CAPA4_TDLS_BUFFER_STA | -+ (chan_switch ? WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH : 0); -+ *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED; -+} -+ -+static void -+rwnx_add_wmm_info_ie(struct sk_buff *skb, u8 qosinfo) -+{ -+ u8 *pos = (void *)skb_put(skb, 9); -+ -+ *pos++ = WLAN_EID_VENDOR_SPECIFIC; -+ *pos++ = 7; /* len */ -+ *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */ -+ *pos++ = 0x50; -+ *pos++ = 0xf2; -+ *pos++ = 2; /* WME */ -+ *pos++ = 0; /* WME info */ -+ *pos++ = 1; /* WME ver */ -+ *pos++ = qosinfo; /* U-APSD no in use */ -+} -+ -+/* translate numbering in the WMM parameter IE to the mac80211 notation */ -+static u8 rwnx_ac_from_wmm(int ac) -+{ -+ switch (ac) { -+ default: -+ WARN_ON_ONCE(1); -+ case 0: -+ return AC_BE; -+ case 1: -+ return AC_BK; -+ case 2: -+ return AC_VI; -+ case 3: -+ return AC_VO; -+ } -+} -+ -+static void -+rwnx_add_wmm_param_ie(struct sk_buff *skb, u8 acm_bits, u32 *ac_params) -+{ -+ struct ieee80211_wmm_param_ie *wmm; -+ int i, j; -+ u8 cw_min, cw_max; -+ bool acm; -+ -+ wmm = (void *)skb_put(skb, sizeof(struct ieee80211_wmm_param_ie)); -+ memset(wmm, 0, sizeof(*wmm)); -+ -+ wmm->element_id = WLAN_EID_VENDOR_SPECIFIC; -+ wmm->len = sizeof(*wmm) - 2; -+ -+ wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */ -+ wmm->oui[1] = 0x50; -+ wmm->oui[2] = 0xf2; -+ wmm->oui_type = 2; /* WME */ -+ wmm->oui_subtype = 1; /* WME param */ -+ wmm->version = 1; /* WME ver */ -+ wmm->qos_info = 0; /* U-APSD not in use */ -+ -+ /* -+ * Use the EDCA parameters defined for the BSS, or default if the AP -+ * doesn't support it, as mandated by 802.11-2012 section 10.22.4 -+ */ -+ for (i = 0; i < AC_MAX; i++) { -+ j = rwnx_ac_from_wmm(i); -+ cw_min = (ac_params[j] & 0xF0) >> 4; -+ cw_max = (ac_params[j] & 0xF00) >> 8; -+ acm = (acm_bits & (1 << j)) != 0; -+ -+ wmm->ac[i].aci_aifsn = (i << 5) | (acm << 4) | (ac_params[j] & 0xF); -+ wmm->ac[i].cw = (cw_max << 4) | cw_min; -+ wmm->ac[i].txop_limit = (ac_params[j] & 0x0FFFF000) >> 12; -+ } -+} -+ -+static void -+rwnx_tdls_add_oper_classes(struct rwnx_vif *rwnx_vif, struct sk_buff *skb) -+{ -+ u8 *pos; -+ u8 op_class; -+ struct cfg80211_chan_def chan_def; -+ struct ieee80211_channel chan; -+ -+ chan.band = rwnx_vif->sta.ap->band; -+ chan.center_freq = rwnx_vif->sta.ap->center_freq; -+ chan_def.chan = &chan; -+ chan_def.width = rwnx_vif->sta.ap->width; -+ chan_def.center_freq1 = rwnx_vif->sta.ap->center_freq1; -+ chan_def.center_freq2 = rwnx_vif->sta.ap->center_freq2; -+#ifdef CONFIG_GKI -+ if (!rwnx_ieee80211_chandef_to_operating_class(&chan_def, &op_class)) -+#else -+ if (!ieee80211_chandef_to_operating_class(&chan_def, &op_class)) -+#endif -+ return; -+ -+ pos = skb_put(skb, 4); -+ *pos++ = WLAN_EID_SUPPORTED_REGULATORY_CLASSES; -+ *pos++ = 2; /* len */ -+ -+ // current op class -+ *pos++ = op_class; -+ *pos++ = op_class; /* give current operating class as alternate too */ -+ -+ // need to add 5GHz classes? -+} -+ -+static void -+rwnx_ie_build_ht_cap(struct sk_buff *skb, struct ieee80211_sta_ht_cap *ht_cap, -+ u16 cap) -+{ -+ u8 *pos; -+ __le16 tmp; -+ -+ pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); -+ *pos++ = WLAN_EID_HT_CAPABILITY; -+ *pos++ = sizeof(struct ieee80211_ht_cap); -+ memset(pos, 0, sizeof(struct ieee80211_ht_cap)); -+ -+ /* capability flags */ -+ tmp = cpu_to_le16(cap); -+ memcpy(pos, &tmp, sizeof(u16)); -+ pos += sizeof(u16); -+ -+ /* AMPDU parameters */ -+ *pos++ = ht_cap->ampdu_factor | -+ (ht_cap->ampdu_density << -+ IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); -+ -+ /* MCS set */ -+ memcpy(pos, &ht_cap->mcs, sizeof(ht_cap->mcs)); -+ pos += sizeof(ht_cap->mcs); -+ -+ /* extended capabilities */ -+ pos += sizeof(__le16); -+ -+ /* BF capabilities */ -+ pos += sizeof(__le32); -+ -+ /* antenna selection */ -+ pos += sizeof(u8); -+} -+ -+static void -+rwnx_ie_build_vht_cap(struct sk_buff *skb, struct ieee80211_sta_vht_cap *vht_cap, -+ u32 cap) -+{ -+ u8 *pos; -+ __le32 tmp; -+ -+ pos = skb_put(skb, 14); -+ -+ *pos++ = WLAN_EID_VHT_CAPABILITY; -+ *pos++ = sizeof(struct ieee80211_vht_cap); -+ memset(pos, 0, sizeof(struct ieee80211_vht_cap)); -+ -+ /* capability flags */ -+ tmp = cpu_to_le32(cap); -+ memcpy(pos, &tmp, sizeof(u32)); -+ pos += sizeof(u32); -+ -+ /* VHT MCS set */ -+ memcpy(pos, &vht_cap->vht_mcs, sizeof(vht_cap->vht_mcs)); -+ pos += sizeof(vht_cap->vht_mcs); -+} -+ -+static void -+rwnx_tdls_add_bss_coex_ie(struct sk_buff *skb) -+{ -+ u8 *pos = (void *)skb_put(skb, 3); -+ -+ *pos++ = WLAN_EID_BSS_COEX_2040; -+ *pos++ = 1; /* len */ -+ -+ *pos++ = WLAN_BSS_COEX_INFORMATION_REQUEST; -+} -+ -+static void -+rwnx_tdls_add_link_ie(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct sk_buff *skb, const u8 *peer, -+ bool initiator) -+{ -+ struct ieee80211_tdls_lnkie *lnkid; -+ const u8 *init_addr, *rsp_addr; -+ -+ if (initiator) { -+ init_addr = rwnx_hw->wiphy->perm_addr; -+ rsp_addr = peer; -+ } else { -+ init_addr = peer; -+ rsp_addr = rwnx_hw->wiphy->perm_addr; -+ } -+ -+ lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie)); -+ -+ lnkid->ie_type = WLAN_EID_LINK_ID; -+ lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2; -+ -+ memcpy(lnkid->bssid, rwnx_vif->sta.ap->mac_addr, ETH_ALEN); -+ memcpy(lnkid->init_sta, init_addr, ETH_ALEN); -+ memcpy(lnkid->resp_sta, rsp_addr, ETH_ALEN); -+} -+ -+static void -+rwnx_tdls_add_aid_ie(struct rwnx_vif *rwnx_vif, struct sk_buff *skb) -+{ -+ u8 *pos = (void *)skb_put(skb, 4); -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) -+ *pos++ = WLAN_EID_AID; -+ #else -+ *pos++ = 197; -+ #endif -+ *pos++ = 2; /* len */ -+ *pos++ = rwnx_vif->sta.ap->aid; -+} -+ -+static u8 * -+rwnx_ie_build_ht_oper(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, -+ u16 prot_mode) -+{ -+ struct ieee80211_ht_operation *ht_oper; -+ /* Build HT Information */ -+ *pos++ = WLAN_EID_HT_OPERATION; -+ *pos++ = sizeof(struct ieee80211_ht_operation); -+ ht_oper = (struct ieee80211_ht_operation *)pos; -+ ht_oper->primary_chan = ieee80211_frequency_to_channel( -+ rwnx_vif->sta.ap->center_freq); -+ switch (rwnx_vif->sta.ap->width) { -+ case NL80211_CHAN_WIDTH_160: -+ case NL80211_CHAN_WIDTH_80P80: -+ case NL80211_CHAN_WIDTH_80: -+ case NL80211_CHAN_WIDTH_40: -+ if (rwnx_vif->sta.ap->center_freq1 > rwnx_vif->sta.ap->center_freq) -+ ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; -+ else -+ ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW; -+ break; -+ default: -+ ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; -+ break; -+ } -+ if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 && -+ rwnx_vif->sta.ap->width != NL80211_CHAN_WIDTH_20_NOHT && -+ rwnx_vif->sta.ap->width != NL80211_CHAN_WIDTH_20) -+ ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; -+ -+ ht_oper->operation_mode = cpu_to_le16(prot_mode); -+ ht_oper->stbc_param = 0x0000; -+ -+ /* It seems that Basic MCS set and Supported MCS set -+ are identical for the first 10 bytes */ -+ memset(&ht_oper->basic_set, 0, 16); -+ memcpy(&ht_oper->basic_set, &ht_cap->mcs, 10); -+ -+ return pos + sizeof(struct ieee80211_ht_operation); -+} -+ -+static u8 * -+rwnx_ie_build_vht_oper(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, -+ u16 prot_mode) -+{ -+ struct ieee80211_vht_operation *vht_oper; -+ /* Build HT Information */ -+ *pos++ = WLAN_EID_VHT_OPERATION; -+ *pos++ = sizeof(struct ieee80211_vht_operation); -+ vht_oper = (struct ieee80211_vht_operation *)pos; -+ -+ switch (rwnx_vif->sta.ap->width) { -+ case NL80211_CHAN_WIDTH_80: -+ vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ; // Channel Width -+ CCFS0(vht_oper) = -+ ieee80211_frequency_to_channel(rwnx_vif->sta.ap->center_freq); // Channel Center Frequency Segment 0 -+ CCFS1(vht_oper) = 0; // Channel Center Frequency Segment 1 (N.A.) -+ break; -+ case NL80211_CHAN_WIDTH_160: -+ vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ; // Channel Width -+ CCFS0(vht_oper) = -+ ieee80211_frequency_to_channel(rwnx_vif->sta.ap->center_freq); // Channel Center Frequency Segment 0 -+ CCFS1(vht_oper) = 0; // Channel Center Frequency Segment 1 (N.A.) -+ break; -+ case NL80211_CHAN_WIDTH_80P80: -+ vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ; // Channel Width -+ CCFS0(vht_oper) = -+ ieee80211_frequency_to_channel(rwnx_vif->sta.ap->center_freq1); // Channel Center Frequency Segment 0 -+ CCFS1(vht_oper) = -+ ieee80211_frequency_to_channel(rwnx_vif->sta.ap->center_freq2); // Channel Center Frequency Segment 1 -+ break; -+ default: -+ vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT; -+ CCFS0(vht_oper) = 0; -+ CCFS1(vht_oper) = 0; -+ break; -+ } -+ -+ vht_oper->basic_mcs_set = cpu_to_le16(rwnx_hw->mod_params->mcs_map); -+ -+ return pos + sizeof(struct ieee80211_vht_operation); -+ -+} -+ -+static void -+rwnx_tdls_add_setup_start_ies(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct sk_buff *skb, const u8 *peer, -+ u8 action_code, bool initiator, -+ const u8 *extra_ies, size_t extra_ies_len) -+{ -+ enum nl80211_band band = rwnx_vif->sta.ap->band; -+ struct ieee80211_supported_band *sband; -+ struct ieee80211_sta_ht_cap ht_cap; -+ struct ieee80211_sta_vht_cap vht_cap; -+ size_t offset = 0, noffset; -+ u8 *pos; -+ -+ rcu_read_lock(); -+ -+ rwnx_add_srates_ie(rwnx_hw, skb); -+ rwnx_add_ext_srates_ie(rwnx_hw, skb); -+ rwnx_tdls_add_supp_channels(rwnx_hw, skb); -+ rwnx_tdls_add_ext_capab(rwnx_hw, skb); -+ -+ /* add the QoS element if we support it */ -+ if (/*local->hw.queues >= IEEE80211_NUM_ACS &&*/ -+ action_code != WLAN_PUB_ACTION_TDLS_DISCOVER_RES) -+ rwnx_add_wmm_info_ie(skb, 0); /* no U-APSD */ -+ -+ rwnx_tdls_add_oper_classes(rwnx_vif, skb); -+ -+ /* -+ * with TDLS we can switch channels, and HT-caps are not necessarily -+ * the same on all bands. The specification limits the setup to a -+ * single HT-cap, so use the current band for now. -+ */ -+ sband = rwnx_hw->wiphy->bands[band]; -+ memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); -+ if (((action_code == WLAN_TDLS_SETUP_REQUEST) || -+ (action_code == WLAN_TDLS_SETUP_RESPONSE) || -+ (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES)) && -+ ht_cap.ht_supported /* (!sta || sta->sta.ht_cap.ht_supported)*/) { -+ rwnx_ie_build_ht_cap(skb, &ht_cap, ht_cap.cap); -+ } -+ -+ if (ht_cap.ht_supported && -+ (ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) -+ rwnx_tdls_add_bss_coex_ie(skb); -+ -+ rwnx_tdls_add_link_ie(rwnx_hw, rwnx_vif, skb, peer, initiator); -+ -+ memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap)); -+ if (vht_cap.vht_supported) { -+ rwnx_tdls_add_aid_ie(rwnx_vif, skb); -+ rwnx_ie_build_vht_cap(skb, &vht_cap, vht_cap.cap); -+ // Operating mode Notification (optional) -+ } -+ -+ /* add any remaining IEs */ -+ if (extra_ies_len) { -+ noffset = extra_ies_len; -+ pos = skb_put(skb, noffset - offset); -+ memcpy(pos, extra_ies + offset, noffset - offset); -+ } -+ -+ rcu_read_unlock(); -+} -+ -+ -+static void -+rwnx_tdls_add_setup_cfm_ies(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct sk_buff *skb, const u8 *peer, bool initiator, -+ const u8 *extra_ies, size_t extra_ies_len) -+{ -+ struct ieee80211_supported_band *sband; -+ enum nl80211_band band = rwnx_vif->sta.ap->band; -+ struct ieee80211_sta_ht_cap ht_cap; -+ struct ieee80211_sta_vht_cap vht_cap; -+ -+ size_t offset = 0, noffset; -+ struct rwnx_sta *sta, *ap_sta; -+ u8 *pos; -+ -+ rcu_read_lock(); -+ -+ sta = rwnx_get_sta(rwnx_hw, peer); -+ ap_sta = rwnx_vif->sta.ap; -+ if (WARN_ON_ONCE(!sta || !ap_sta)) { -+ rcu_read_unlock(); -+ return; -+ } -+ -+ /* add the QoS param IE if both the peer and we support it */ -+ if (sta->qos) -+ rwnx_add_wmm_param_ie(skb, ap_sta->acm, ap_sta->ac_param); -+ -+ /* if HT support is only added in TDLS, we need an HT-operation IE */ -+ sband = rwnx_hw->wiphy->bands[band]; -+ memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); -+ if (ht_cap.ht_supported && !ap_sta->ht && sta->ht) { -+ pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation)); -+ /* send an empty HT operation IE */ -+ rwnx_ie_build_ht_oper(rwnx_hw, rwnx_vif, pos, &ht_cap, 0); -+ } -+ -+ rwnx_tdls_add_link_ie(rwnx_hw, rwnx_vif, skb, peer, initiator); -+ -+ memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap)); -+ if (vht_cap.vht_supported && !ap_sta->vht && sta->vht) { -+ pos = skb_put(skb, 2 + sizeof(struct ieee80211_vht_operation)); -+ rwnx_ie_build_vht_oper(rwnx_hw, rwnx_vif, pos, &ht_cap, 0); -+ // Operating mode Notification (optional) -+ } -+ -+ /* add any remaining IEs */ -+ if (extra_ies_len) { -+ noffset = extra_ies_len; -+ pos = skb_put(skb, noffset - offset); -+ memcpy(pos, extra_ies + offset, noffset - offset); -+ } -+ -+ rcu_read_unlock(); -+} -+ -+static void -+rwnx_tdls_add_ies(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ struct sk_buff *skb, const u8 *peer, -+ u8 action_code, u16 status_code, -+ bool initiator, const u8 *extra_ies, -+ size_t extra_ies_len, u8 oper_class, -+ struct cfg80211_chan_def *chandef) -+{ -+ switch (action_code) { -+ case WLAN_TDLS_SETUP_REQUEST: -+ case WLAN_TDLS_SETUP_RESPONSE: -+ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: -+ if (status_code == 0) -+ rwnx_tdls_add_setup_start_ies(rwnx_hw, rwnx_vif, skb, peer, action_code, -+ initiator, extra_ies, extra_ies_len); -+ break; -+ case WLAN_TDLS_SETUP_CONFIRM: -+ if (status_code == 0) -+ rwnx_tdls_add_setup_cfm_ies(rwnx_hw, rwnx_vif, skb, peer, initiator, -+ extra_ies, extra_ies_len); -+ break; -+ -+ case WLAN_TDLS_TEARDOWN: -+ case WLAN_TDLS_DISCOVERY_REQUEST: -+ if (extra_ies_len) -+ memcpy(skb_put(skb, extra_ies_len), extra_ies, -+ extra_ies_len); -+ if (status_code == 0 || action_code == WLAN_TDLS_TEARDOWN) -+ rwnx_tdls_add_link_ie(rwnx_hw, rwnx_vif, skb, peer, initiator); -+ break; -+ } -+} -+ -+int -+rwnx_tdls_send_mgmt_packet_data(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, u32 peer_capability, bool initiator, -+ const u8 *extra_ies, size_t extra_ies_len, u8 oper_class, -+ struct cfg80211_chan_def *chandef) -+{ -+ struct sk_buff *skb; -+ int ret = 0; -+ struct ieee80211_supported_band *rwnx_band_2GHz = rwnx_hw->wiphy->bands[NL80211_BAND_2GHZ]; -+ struct ieee80211_supported_band *rwnx_band_5GHz = rwnx_hw->wiphy->bands[NL80211_BAND_5GHZ]; -+ int channels = rwnx_band_2GHz->n_channels; -+ -+ if (rwnx_hw->band_5g_support) -+ channels += rwnx_band_5GHz->n_channels; -+ -+ skb = netdev_alloc_skb(rwnx_vif->ndev, -+ sizeof(struct ieee80211_tdls_data) + // ethhdr + TDLS info -+ 10 + /* supported rates */ -+ 6 + /* extended supported rates */ -+ (2 + channels) + /* supported channels */ -+ sizeof(struct ieee_types_extcap) + -+ sizeof(struct ieee80211_wmm_param_ie) + -+ 4 + /* oper classes */ -+ 28 + //sizeof(struct ieee80211_ht_cap) + -+ sizeof(struct ieee_types_bss_co_2040) + -+ sizeof(struct ieee80211_tdls_lnkie) + -+ (2 + sizeof(struct ieee80211_vht_cap)) + -+ 4 + /*AID*/ -+ (2 + sizeof(struct ieee80211_ht_operation)) + -+ extra_ies_len); -+ -+ if (!skb) -+ return 0; -+ -+ switch (action_code) { -+ case WLAN_TDLS_SETUP_REQUEST: -+ case WLAN_TDLS_SETUP_RESPONSE: -+ case WLAN_TDLS_SETUP_CONFIRM: -+ case WLAN_TDLS_TEARDOWN: -+ case WLAN_TDLS_DISCOVERY_REQUEST: -+ ret = rwnx_tdls_prepare_encap_data(rwnx_hw, rwnx_vif, peer, action_code, -+ dialog_token, status_code, skb); -+ break; -+ -+ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: -+ ret = rwnx_prep_tdls_direct(rwnx_hw, rwnx_vif, peer, action_code, -+ dialog_token, status_code, skb); -+ break; -+ -+ default: -+ ret = -ENOTSUPP; -+ break; -+ } -+ -+ if (ret < 0) -+ goto fail; -+ -+ rwnx_tdls_add_ies(rwnx_hw, rwnx_vif, skb, peer, action_code, status_code, -+ initiator, extra_ies, extra_ies_len, oper_class, chandef); -+ -+ if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) { -+ u64 cookie; -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+ struct cfg80211_mgmt_tx_params params; -+ -+ params.len = skb->len; -+ params.buf = skb->data; -+ ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, ¶ms, false, &cookie); -+ #else -+ ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, NULL, false, 0, skb->data, skb->len, false, false, &cookie); -+ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ -+ -+ return ret; -+ } -+ -+ switch (action_code) { -+ case WLAN_TDLS_SETUP_REQUEST: -+ case WLAN_TDLS_SETUP_RESPONSE: -+ case WLAN_TDLS_SETUP_CONFIRM: -+ skb->priority = 2; -+ break; -+ default: -+ skb->priority = 5; -+ break; -+ } -+ -+ ret = rwnx_select_txq(rwnx_vif, skb); -+ ret = rwnx_start_xmit(skb, rwnx_vif->ndev); -+ -+ return ret; -+ -+fail: -+ dev_kfree_skb(skb); -+ return ret; -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tdls.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tdls.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tdls.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tdls.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,54 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_tdls.h -+ * -+ * @brief TDLS function declarations -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef RWNX_TDLS_H_ -+#define RWNX_TDLS_H_ -+ -+#include "rwnx_defs.h" -+ -+struct ieee_types_header { -+ u8 element_id; -+ u8 len; -+} __packed; -+ -+struct ieee_types_bss_co_2040 { -+ struct ieee_types_header ieee_hdr; -+ u8 bss_2040co; -+} __packed; -+ -+struct ieee_types_extcap { -+ struct ieee_types_header ieee_hdr; -+ u8 ext_capab[8]; -+} __packed; -+ -+struct ieee_types_vht_cap { -+ struct ieee_types_header ieee_hdr; -+ struct ieee80211_vht_cap vhtcap; -+} __packed; -+ -+struct ieee_types_vht_oper { -+ struct ieee_types_header ieee_hdr; -+ struct ieee80211_vht_operation vhtoper; -+} __packed; -+ -+struct ieee_types_aid { -+ struct ieee_types_header ieee_hdr; -+ u16 aid; -+} __packed; -+ -+int rwnx_tdls_send_mgmt_packet_data(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, u32 peer_capability, bool initiator, -+ const u8 *extra_ies, size_t extra_ies_len, u8 oper_class, -+ struct cfg80211_chan_def *chandef); -+ -+#endif /* RWNX_TDLS_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_testmode.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_testmode.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_testmode.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_testmode.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,230 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_testmode.c -+ * -+ * @brief Test mode function definitions -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#include -+#include -+ -+#include "rwnx_testmode.h" -+#include "rwnx_msg_tx.h" -+#include "rwnx_dini.h" -+#include "reg_access.h" -+ -+/* -+ * This function handles the user application commands for register access. -+ * -+ * It retrieves command ID carried with RWNX_TM_ATTR_COMMAND and calls to the -+ * handlers respectively. -+ * -+ * If it's an unknown commdn ID, -ENOSYS is returned; or -ENOMSG if the -+ * mandatory fields(RWNX_TM_ATTR_REG_OFFSET,RWNX_TM_ATTR_REG_VALUE32) -+ * are missing; Otherwise 0 is replied indicating the success of the command execution. -+ * -+ * If RWNX_TM_ATTR_COMMAND is RWNX_TM_CMD_APP2DEV_REG_READ, the register read -+ * value is returned with RWNX_TM_ATTR_REG_VALUE32. -+ * -+ * @hw: ieee80211_hw object that represents the device -+ * @tb: general message fields from the user space -+ */ -+int rwnx_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) -+{ -+ struct rwnx_hw *rwnx_hw = hw->priv; -+ u32 mem_addr, val32; -+ struct sk_buff *skb; -+ int status = 0; -+ -+ /* First check if register address is there */ -+ if (!tb[RWNX_TM_ATTR_REG_OFFSET]) { -+ printk("Error finding register offset\n"); -+ return -ENOMSG; -+ } -+ -+ mem_addr = nla_get_u32(tb[RWNX_TM_ATTR_REG_OFFSET]); -+ -+ switch (nla_get_u32(tb[RWNX_TM_ATTR_COMMAND])) { -+ case RWNX_TM_CMD_APP2DEV_REG_READ: -+ { -+ struct dbg_mem_read_cfm mem_read_cfm; -+ -+ /*** Send the command to the LMAC ***/ -+ status = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &mem_read_cfm); -+ if (status) -+ return status; -+ -+ /* Allocate the answer message */ -+ skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); -+ if (!skb) { -+ printk("Error allocating memory\n"); -+ return -ENOMEM; -+ } -+ -+ val32 = mem_read_cfm.memdata; -+ if (nla_put_u32(skb, RWNX_TM_ATTR_REG_VALUE32, val32)) -+ goto nla_put_failure; -+ -+ /* Send the answer to upper layer */ -+ status = cfg80211_testmode_reply(skb); -+ if (status < 0) -+ printk("Error sending msg : %d\n", status); -+ } -+ break; -+ -+ case RWNX_TM_CMD_APP2DEV_REG_WRITE: -+ { -+ if (!tb[RWNX_TM_ATTR_REG_VALUE32]) { -+ printk("Error finding value to write\n"); -+ return -ENOMSG; -+ } else { -+ val32 = nla_get_u32(tb[RWNX_TM_ATTR_REG_VALUE32]); -+ /* Send the command to the LMAC */ -+ status = rwnx_send_dbg_mem_write_req(rwnx_hw, mem_addr, val32); -+ if (status) -+ return status; -+ } -+ } -+ break; -+ -+ default: -+ printk("Unknown testmode register command ID\n"); -+ return -ENOSYS; -+ } -+ -+ return status; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -EMSGSIZE; -+} -+ -+/* -+ * This function handles the user application commands for Debug filter settings. -+ * -+ * @hw: ieee80211_hw object that represents the device -+ * @tb: general message fields from the user space -+ */ -+int rwnx_testmode_dbg_filter(struct ieee80211_hw *hw, struct nlattr **tb) -+{ -+ struct rwnx_hw *rwnx_hw = hw->priv; -+ u32 filter; -+ int status = 0; -+ -+ /* First check if the filter is there */ -+ if (!tb[RWNX_TM_ATTR_REG_FILTER]) { -+ printk("Error finding filter value\n"); -+ return -ENOMSG; -+ } -+ -+ filter = nla_get_u32(tb[RWNX_TM_ATTR_REG_FILTER]); -+ RWNX_DBG("testmode debug filter, setting: 0x%x\n", filter); -+ -+ switch (nla_get_u32(tb[RWNX_TM_ATTR_COMMAND])) { -+ case RWNX_TM_CMD_APP2DEV_SET_DBGMODFILTER: -+ { -+ /* Send the command to the LMAC */ -+ status = rwnx_send_dbg_set_mod_filter_req(rwnx_hw, filter); -+ if (status) -+ return status; -+ } -+ break; -+ case RWNX_TM_CMD_APP2DEV_SET_DBGSEVFILTER: -+ { -+ /* Send the command to the LMAC */ -+ status = rwnx_send_dbg_set_sev_filter_req(rwnx_hw, filter); -+ if (status) -+ return status; -+ } -+ break; -+ -+ default: -+ printk("Unknown testmode register command ID\n"); -+ return -ENOSYS; -+ } -+ -+ return status; -+} -+ -+/* -+ * This function handles the user application commands for register access without using -+ * the normal LMAC messaging way. -+ * This time register access will be done through direct PCI BAR windows. This can be used -+ * to access registers even when the :AMC FW is stuck. -+ * -+ * @hw: ieee80211_hw object that represents the device -+ * @tb: general message fields from the user space -+ */ -+int rwnx_testmode_reg_dbg(struct ieee80211_hw *hw, struct nlattr **tb) -+{ -+ struct rwnx_hw *rwnx_hw = hw->priv; -+ struct rwnx_plat *rwnx_plat = rwnx_hw->plat; -+ u32 mem_addr; -+ struct sk_buff *skb; -+ int status = 0; -+ volatile unsigned int reg_value = 0; -+ unsigned int offset; -+ -+ /* First check if register address is there */ -+ if (!tb[RWNX_TM_ATTR_REG_OFFSET]) { -+ printk("Error finding register offset\n"); -+ return -ENOMSG; -+ } -+ -+ mem_addr = nla_get_u32(tb[RWNX_TM_ATTR_REG_OFFSET]); -+ offset = mem_addr & 0x00FFFFFF; -+ -+ switch (nla_get_u32(tb[RWNX_TM_ATTR_COMMAND])) { -+ case RWNX_TM_CMD_APP2DEV_REG_READ_DBG: -+ { -+ /*** Send the command to the LMAC ***/ -+ reg_value = RWNX_REG_READ(rwnx_plat, RWNX_ADDR_SYSTEM, offset); -+ -+ /* Allocate the answer message */ -+ skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); -+ if (!skb) { -+ printk("Error allocating memory\n"); -+ return -ENOMEM; -+ } -+ -+ if (nla_put_u32(skb, RWNX_TM_ATTR_REG_VALUE32, reg_value)) -+ goto nla_put_failure; -+ -+ /* Send the answer to upper layer */ -+ status = cfg80211_testmode_reply(skb); -+ if (status < 0) -+ printk("Error sending msg : %d\n", status); -+ } -+ break; -+ -+ case RWNX_TM_CMD_APP2DEV_REG_WRITE_DBG: -+ { -+ if (!tb[RWNX_TM_ATTR_REG_VALUE32]) { -+ printk("Error finding value to write\n"); -+ return -ENOMSG; -+ } else { -+ reg_value = nla_get_u32(tb[RWNX_TM_ATTR_REG_VALUE32]); -+ -+ /* Send the command to the LMAC */ -+ RWNX_REG_WRITE(reg_value, rwnx_plat, RWNX_ADDR_SYSTEM, -+ offset); -+ } -+ } -+ break; -+ -+ default: -+ printk("Unknown testmode register command ID\n"); -+ return -ENOSYS; -+ } -+ -+ return status; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -EMSGSIZE; -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_testmode.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_testmode.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_testmode.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_testmode.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,64 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_testmode.h -+ * -+ * @brief Test mode function declarations -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ **************************************************************************************** -+ */ -+ -+#ifndef RWNX_TESTMODE_H_ -+#define RWNX_TESTMODE_H_ -+ -+#include -+#include -+ -+/* Commands from user space to kernel space(RWNX_TM_CMD_APP2DEV_XX) and -+ * from and kernel space to user space(RWNX_TM_CMD_DEV2APP_XX). -+ * The command ID is carried with RWNX_TM_ATTR_COMMAND. -+ */ -+enum rwnx_tm_cmd_t { -+ /* commands from user application to access register */ -+ RWNX_TM_CMD_APP2DEV_REG_READ = 1, -+ RWNX_TM_CMD_APP2DEV_REG_WRITE, -+ -+ /* commands from user application to select the Debug levels */ -+ RWNX_TM_CMD_APP2DEV_SET_DBGMODFILTER, -+ RWNX_TM_CMD_APP2DEV_SET_DBGSEVFILTER, -+ -+ /* commands to access registers without sending messages to LMAC layer, -+ * this must be used when LMAC FW is stuck. */ -+ RWNX_TM_CMD_APP2DEV_REG_READ_DBG, -+ RWNX_TM_CMD_APP2DEV_REG_WRITE_DBG, -+ -+ RWNX_TM_CMD_MAX, -+}; -+ -+enum rwnx_tm_attr_t { -+ RWNX_TM_ATTR_NOT_APPLICABLE = 0, -+ -+ RWNX_TM_ATTR_COMMAND, -+ -+ /* When RWNX_TM_ATTR_COMMAND is RWNX_TM_CMD_APP2DEV_REG_XXX, -+ * The mandatory fields are: -+ * RWNX_TM_ATTR_REG_OFFSET for the offset of the target register; -+ * RWNX_TM_ATTR_REG_VALUE32 for value */ -+ RWNX_TM_ATTR_REG_OFFSET, -+ RWNX_TM_ATTR_REG_VALUE32, -+ -+ /* When RWNX_TM_ATTR_COMMAND is RWNX_TM_CMD_APP2DEV_SET_DBGXXXFILTER, -+ * The mandatory field is RWNX_TM_ATTR_REG_FILTER. */ -+ RWNX_TM_ATTR_REG_FILTER, -+ -+ RWNX_TM_ATTR_MAX, -+}; -+ -+/***********************************************************************/ -+int rwnx_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb); -+int rwnx_testmode_dbg_filter(struct ieee80211_hw *hw, struct nlattr **tb); -+int rwnx_testmode_reg_dbg(struct ieee80211_hw *hw, struct nlattr **tb); -+ -+#endif /* RWNX_TESTMODE_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tx.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tx.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tx.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,1953 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_tx.c -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+#include -+#include -+#include -+ -+#include "rwnx_defs.h" -+#include "rwnx_tx.h" -+#include "rwnx_msg_tx.h" -+#include "rwnx_mesh.h" -+#include "rwnx_events.h" -+#include "rwnx_compat.h" -+#include "aicwf_txrxif.h" -+ -+/****************************************************************************** -+ * Power Save functions -+ *****************************************************************************/ -+/** -+ * rwnx_set_traffic_status - Inform FW if traffic is available for STA in PS -+ * -+ * @rwnx_hw: Driver main data -+ * @sta: Sta in PS mode -+ * @available: whether traffic is buffered for the STA -+ * @ps_id: type of PS data requested (@LEGACY_PS_ID or @UAPSD_ID) -+ */ -+void rwnx_set_traffic_status(struct rwnx_hw *rwnx_hw, -+ struct rwnx_sta *sta, -+ bool available, -+ u8 ps_id) -+{ -+ if (sta->tdls.active) { -+ rwnx_send_tdls_peer_traffic_ind_req(rwnx_hw, -+ rwnx_hw->vif_table[sta->vif_idx]); -+ } else { -+ bool uapsd = (ps_id != LEGACY_PS_ID); -+ rwnx_send_me_traffic_ind(rwnx_hw, sta->sta_idx, uapsd, available); -+#ifdef CREATE_TRACE_POINTS -+ trace_ps_traffic_update(sta->sta_idx, available, uapsd); -+#endif -+ } -+} -+ -+/** -+ * rwnx_ps_bh_enable - Enable/disable PS mode for one STA -+ * -+ * @rwnx_hw: Driver main data -+ * @sta: Sta which enters/leaves PS mode -+ * @enable: PS mode status -+ * -+ * This function will enable/disable PS mode for one STA. -+ * When enabling PS mode: -+ * - Stop all STA's txq for RWNX_TXQ_STOP_STA_PS reason -+ * - Count how many buffers are already ready for this STA -+ * - For BC/MC sta, update all queued SKB to use hw_queue BCMC -+ * - Update TIM if some packet are ready -+ * -+ * When disabling PS mode: -+ * - Start all STA's txq for RWNX_TXQ_STOP_STA_PS reason -+ * - For BC/MC sta, update all queued SKB to use hw_queue AC_BE -+ * - Update TIM if some packet are ready (otherwise fw will not update TIM -+ * in beacon for this STA) -+ * -+ * All counter/skb updates are protected from TX path by taking tx_lock -+ * -+ * NOTE: _bh_ in function name indicates that this function is called -+ * from a bottom_half tasklet. -+ */ -+void rwnx_ps_bh_enable(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, -+ bool enable) -+{ -+ struct rwnx_txq *txq; -+ -+ if (enable) { -+#ifdef CREATE_TRACE_POINTS -+ trace_ps_enable(sta); -+#endif -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ sta->ps.active = true; -+ sta->ps.sp_cnt[LEGACY_PS_ID] = 0; -+ sta->ps.sp_cnt[UAPSD_ID] = 0; -+ rwnx_txq_sta_stop(sta, RWNX_TXQ_STOP_STA_PS, rwnx_hw); -+ -+ if (is_multicast_sta(sta->sta_idx)) { -+ txq = rwnx_txq_sta_get(sta, 0, rwnx_hw); -+ sta->ps.pkt_ready[LEGACY_PS_ID] = skb_queue_len(&txq->sk_list); -+ sta->ps.pkt_ready[UAPSD_ID] = 0; -+ //txq->hwq = &rwnx_hw->hwq[RWNX_HWQ_BCMC]; -+ } else { -+ int i; -+ sta->ps.pkt_ready[LEGACY_PS_ID] = 0; -+ sta->ps.pkt_ready[UAPSD_ID] = 0; -+ foreach_sta_txq(sta, txq, i, rwnx_hw) { -+ sta->ps.pkt_ready[txq->ps_id] += skb_queue_len(&txq->sk_list); -+ } -+ } -+ -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+ -+ //if (sta->ps.pkt_ready[LEGACY_PS_ID]) -+ // rwnx_set_traffic_status(rwnx_hw, sta, true, LEGACY_PS_ID); -+ -+ //if (sta->ps.pkt_ready[UAPSD_ID]) -+ // rwnx_set_traffic_status(rwnx_hw, sta, true, UAPSD_ID); -+ } else { -+#ifdef CREATE_TRACE_POINTS -+ trace_ps_disable(sta->sta_idx); -+#endif -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ sta->ps.active = false; -+ -+ if (is_multicast_sta(sta->sta_idx)) { -+ txq = rwnx_txq_sta_get(sta, 0, rwnx_hw); -+ txq->hwq = &rwnx_hw->hwq[RWNX_HWQ_BE]; -+ txq->push_limit = 0; -+ } else { -+ int i; -+ foreach_sta_txq(sta, txq, i, rwnx_hw) { -+ txq->push_limit = 0; -+ } -+ } -+ -+ rwnx_txq_sta_start(sta, RWNX_TXQ_STOP_STA_PS, rwnx_hw); -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+ -+ //if (sta->ps.pkt_ready[LEGACY_PS_ID]) -+ // rwnx_set_traffic_status(rwnx_hw, sta, false, LEGACY_PS_ID); -+ -+ //if (sta->ps.pkt_ready[UAPSD_ID]) -+ // rwnx_set_traffic_status(rwnx_hw, sta, false, UAPSD_ID); -+ -+ tasklet_schedule(&rwnx_hw->task); -+ } -+} -+ -+/** -+ * rwnx_ps_bh_traffic_req - Handle traffic request for STA in PS mode -+ * -+ * @rwnx_hw: Driver main data -+ * @sta: Sta which enters/leaves PS mode -+ * @pkt_req: number of pkt to push -+ * @ps_id: type of PS data requested (@LEGACY_PS_ID or @UAPSD_ID) -+ * -+ * This function will make sure that @pkt_req are pushed to fw -+ * whereas the STA is in PS mode. -+ * If request is 0, send all traffic -+ * If request is greater than available pkt, reduce request -+ * Note: request will also be reduce if txq credits are not available -+ * -+ * All counter updates are protected from TX path by taking tx_lock -+ * -+ * NOTE: _bh_ in function name indicates that this function is called -+ * from the bottom_half tasklet. -+ */ -+void rwnx_ps_bh_traffic_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, -+ u16 pkt_req, u8 ps_id) -+{ -+ int pkt_ready_all; -+ struct rwnx_txq *txq; -+ int schedule = 0; -+ -+ //if (WARN(!sta->ps.active, "sta %pM is not in Power Save mode", -+ // sta->mac_addr)) -+ // return; -+ if (!sta->ps.active) { -+ AICWFDBG(LOGTRACE,"sta %pM is not in Power Save mode", sta->mac_addr); -+ return; -+ } -+#ifdef CREATE_TRACE_POINTS -+ trace_ps_traffic_req(sta, pkt_req, ps_id); -+#endif -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ -+ /* Fw may ask to stop a service period with PS_SP_INTERRUPTED. This only -+ happens for p2p-go interface if NOA starts during a service period */ -+ if ((pkt_req == PS_SP_INTERRUPTED) && (ps_id == UAPSD_ID)) { -+ int tid; -+ sta->ps.sp_cnt[ps_id] = 0; -+ foreach_sta_txq(sta, txq, tid, rwnx_hw) { -+ txq->push_limit = 0; -+ } -+ goto done; -+ } -+ -+ pkt_ready_all = (sta->ps.pkt_ready[ps_id] - sta->ps.sp_cnt[ps_id]); -+ -+ /* Don't start SP until previous one is finished or we don't have -+ packet ready (which must not happen for U-APSD) */ -+ if (sta->ps.sp_cnt[ps_id] || pkt_ready_all <= 0) { -+ goto done; -+ } -+ -+ /* Adapt request to what is available. */ -+ if (pkt_req == 0 || pkt_req > pkt_ready_all) { -+ pkt_req = pkt_ready_all; -+ } -+ -+ /* Reset the SP counter */ -+ sta->ps.sp_cnt[ps_id] = 0; -+ schedule = 1; -+ -+ /* "dispatch" the request between txq */ -+ if (is_multicast_sta(sta->sta_idx)) { -+ txq = rwnx_txq_sta_get(sta, 0, rwnx_hw); -+ //if (txq->credits <= 0) -+ // goto done; -+ if (pkt_req > txq->credits) -+ pkt_req = txq->credits; -+ txq->push_limit = pkt_req; -+ sta->ps.sp_cnt[ps_id] = pkt_req; -+ rwnx_txq_add_to_hw_list(txq); -+ } else { -+ int i, tid; -+ -+ foreach_sta_txq_prio(sta, txq, tid, i, rwnx_hw) { -+ u16 txq_len = skb_queue_len(&txq->sk_list); -+ -+ if (txq->ps_id != ps_id) -+ continue; -+ -+ if (txq_len > txq->credits) -+ txq_len = txq->credits; -+ -+ if (txq_len == 0) -+ continue; -+ -+ if (txq_len < pkt_req) { -+ /* Not enough pkt queued in this txq, add this -+ txq to hwq list and process next txq */ -+ pkt_req -= txq_len; -+ txq->push_limit = txq_len; -+ sta->ps.sp_cnt[ps_id] += txq_len; -+ rwnx_txq_add_to_hw_list(txq); -+ } else { -+ /* Enough pkt in this txq to comlete the request -+ add this txq to hwq list and stop processing txq */ -+ txq->push_limit = pkt_req; -+ sta->ps.sp_cnt[ps_id] += pkt_req; -+ rwnx_txq_add_to_hw_list(txq); -+ break; -+ } -+ } -+ } -+ -+done: -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+ if (schedule) -+ tasklet_schedule(&rwnx_hw->task); -+} -+ -+/****************************************************************************** -+ * TX functions -+ *****************************************************************************/ -+#define PRIO_STA_NULL 0xAA -+ -+static const int rwnx_down_hwq2tid[3] = { -+ [RWNX_HWQ_BK] = 2, -+ [RWNX_HWQ_BE] = 3, -+ [RWNX_HWQ_VI] = 5, -+}; -+ -+static void rwnx_downgrade_ac(struct rwnx_sta *sta, struct sk_buff *skb) -+{ -+ int8_t ac = rwnx_tid2hwq[skb->priority]; -+ -+ if (WARN((ac > RWNX_HWQ_VO), -+ "Unexepcted ac %d for skb before downgrade", ac)) -+ ac = RWNX_HWQ_VO; -+ -+ while (sta->acm & BIT(ac)) { -+ if (ac == RWNX_HWQ_BK) { -+ skb->priority = 1; -+ return; -+ } -+ ac--; -+ skb->priority = rwnx_down_hwq2tid[ac]; -+ } -+} -+ -+u16 rwnx_select_txq(struct rwnx_vif *rwnx_vif, struct sk_buff *skb) -+{ -+ struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; -+ struct wireless_dev *wdev = &rwnx_vif->wdev; -+ struct rwnx_sta *sta = NULL; -+ struct rwnx_txq *txq; -+ u16 netdev_queue; -+ bool tdls_mgmgt_frame = false; -+ int nx_bcmc_txq_ndev_idx = NX_BCMC_TXQ_NDEV_IDX; -+ -+ if((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) || -+ ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ -+ nx_bcmc_txq_ndev_idx = NX_BCMC_TXQ_NDEV_IDX_FOR_OLD_IC; -+ } -+ -+ switch (wdev->iftype) { -+ case NL80211_IFTYPE_STATION: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ { -+ struct ethhdr *eth; -+ eth = (struct ethhdr *)skb->data; -+ if (eth->h_proto == cpu_to_be16(ETH_P_TDLS)) { -+ tdls_mgmgt_frame = true; -+ } -+ if ((rwnx_vif->tdls_status == TDLS_LINK_ACTIVE) && -+ (rwnx_vif->sta.tdls_sta != NULL) && -+ (memcmp(eth->h_dest, rwnx_vif->sta.tdls_sta->mac_addr, ETH_ALEN) == 0)) -+ sta = rwnx_vif->sta.tdls_sta; -+ else -+ sta = rwnx_vif->sta.ap; -+ break; -+ } -+ case NL80211_IFTYPE_AP_VLAN: -+ if (rwnx_vif->ap_vlan.sta_4a) { -+ sta = rwnx_vif->ap_vlan.sta_4a; -+ break; -+ } -+ -+ /* AP_VLAN interface is not used for a 4A STA, -+ fallback searching sta amongs all AP's clients */ -+ rwnx_vif = rwnx_vif->ap_vlan.master; -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+ { -+ struct rwnx_sta *cur; -+ struct ethhdr *eth = (struct ethhdr *)skb->data; -+ -+ if (is_multicast_ether_addr(eth->h_dest)) { -+ sta = &rwnx_hw->sta_table[rwnx_vif->ap.bcmc_index]; -+ } else { -+ spin_lock_bh(&rwnx_vif->rwnx_hw->cb_lock); -+ list_for_each_entry(cur, &rwnx_vif->ap.sta_list, list) { -+ if (!memcmp(cur->mac_addr, eth->h_dest, ETH_ALEN)) { -+ sta = cur; -+ break; -+ } -+ } -+ spin_unlock_bh(&rwnx_vif->rwnx_hw->cb_lock); -+ } -+ -+ break; -+ } -+ case NL80211_IFTYPE_MESH_POINT: -+ { -+ struct ethhdr *eth = (struct ethhdr *)skb->data; -+ -+ if (!rwnx_vif->is_resending) { -+ /* -+ * If ethernet source address is not the address of a mesh wireless interface, we are proxy for -+ * this address and have to inform the HW -+ */ -+ if (memcmp(ð->h_source[0], &rwnx_vif->ndev->perm_addr[0], ETH_ALEN)) { -+ /* Check if LMAC is already informed */ -+ if (!rwnx_get_mesh_proxy_info(rwnx_vif, (u8 *)ð->h_source, true)) { -+ rwnx_send_mesh_proxy_add_req(rwnx_hw, rwnx_vif, (u8 *)ð->h_source); -+ } -+ } -+ } -+ -+ if (is_multicast_ether_addr(eth->h_dest)) { -+ sta = &rwnx_hw->sta_table[rwnx_vif->ap.bcmc_index]; -+ } else { -+ /* Path to be used */ -+ struct rwnx_mesh_path *p_mesh_path = NULL; -+ struct rwnx_mesh_path *p_cur_path; -+ /* Check if destination is proxied by a peer Mesh STA */ -+ struct rwnx_mesh_proxy *p_mesh_proxy = rwnx_get_mesh_proxy_info(rwnx_vif, (u8 *)ð->h_dest, false); -+ /* Mesh Target address */ -+ struct mac_addr *p_tgt_mac_addr; -+ -+ if (p_mesh_proxy) { -+ p_tgt_mac_addr = &p_mesh_proxy->proxy_addr; -+ } else { -+ p_tgt_mac_addr = (struct mac_addr *)ð->h_dest; -+ } -+ -+ /* Look for path with provided target address */ -+ list_for_each_entry(p_cur_path, &rwnx_vif->ap.mpath_list, list) { -+ if (!memcmp(&p_cur_path->tgt_mac_addr, p_tgt_mac_addr, ETH_ALEN)) { -+ p_mesh_path = p_cur_path; -+ break; -+ } -+ } -+ -+ if (p_mesh_path) { -+ sta = p_mesh_path->p_nhop_sta; -+ } else { -+ rwnx_send_mesh_path_create_req(rwnx_hw, rwnx_vif, (u8 *)p_tgt_mac_addr); -+ } -+ } -+ -+ break; -+ } -+ default: -+ break; -+ } -+ -+ if (sta && sta->qos) { -+ if (tdls_mgmgt_frame) { -+ skb_set_queue_mapping(skb, NX_STA_NDEV_IDX(skb->priority, sta->sta_idx)); -+ } else { -+ /* use the data classifier to determine what 802.1d tag the -+ * data frame has */ -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) -+ skb->priority = cfg80211_classify8021d(skb) & IEEE80211_QOS_CTL_TAG1D_MASK; -+ #else -+ skb->priority = cfg80211_classify8021d(skb, NULL) & IEEE80211_QOS_CTL_TAG1D_MASK; -+ #endif -+ } -+ if (sta->acm) -+ rwnx_downgrade_ac(sta, skb); -+ -+ txq = rwnx_txq_sta_get(sta, skb->priority, rwnx_hw); -+ netdev_queue = txq->ndev_idx; -+ } else if (sta) { -+ skb->priority = 0xFF; -+ txq = rwnx_txq_sta_get(sta, 0, rwnx_hw); -+ netdev_queue = txq->ndev_idx; -+ } else { -+ /* This packet will be dropped in xmit function, still need to select -+ an active queue for xmit to be called. As it most likely to happen -+ for AP interface, select BCMC queue -+ (TODO: select another queue if BCMC queue is stopped) */ -+ skb->priority = PRIO_STA_NULL; -+ netdev_queue = nx_bcmc_txq_ndev_idx; -+ } -+ -+#ifndef CONFIG_ONE_TXQ -+ BUG_ON(netdev_queue >= NX_NB_NDEV_TXQ); -+#endif -+ -+ return netdev_queue; -+} -+ -+/** -+ * rwnx_set_more_data_flag - Update MORE_DATA flag in tx sw desc -+ * -+ * @rwnx_hw: Driver main data -+ * @sw_txhdr: Header for pkt to be pushed -+ * -+ * If STA is in PS mode -+ * - Set EOSP in case the packet is the last of the UAPSD service period -+ * - Set MORE_DATA flag if more pkt are ready for this sta -+ * - Update TIM if this is the last pkt buffered for this sta -+ * -+ * note: tx_lock already taken. -+ */ -+static inline void rwnx_set_more_data_flag(struct rwnx_hw *rwnx_hw, -+ struct rwnx_sw_txhdr *sw_txhdr) -+{ -+ struct rwnx_sta *sta = sw_txhdr->rwnx_sta; -+ struct rwnx_vif *vif = sw_txhdr->rwnx_vif; -+ struct rwnx_txq *txq = sw_txhdr->txq; -+ -+ if (unlikely(sta->ps.active)) { -+ sta->ps.pkt_ready[txq->ps_id]--; -+ sta->ps.sp_cnt[txq->ps_id]--; -+#ifdef CREATE_TRACE_POINTS -+ trace_ps_push(sta); -+#endif -+ if (((txq->ps_id == UAPSD_ID) || (vif->wdev.iftype == NL80211_IFTYPE_MESH_POINT) || (sta->tdls.active)) -+ && !sta->ps.sp_cnt[txq->ps_id]) { -+ sw_txhdr->desc.host.flags |= TXU_CNTRL_EOSP; -+ } -+ -+ if (sta->ps.pkt_ready[txq->ps_id]) { -+ sw_txhdr->desc.host.flags |= TXU_CNTRL_MORE_DATA; -+ } else { -+ rwnx_set_traffic_status(rwnx_hw, sta, false, txq->ps_id); -+ } -+ } -+} -+ -+/** -+ * rwnx_get_tx_priv - Get STA and tid for one skb -+ * -+ * @rwnx_vif: vif ptr -+ * @skb: skb -+ * @tid: pointer updated with the tid to use for this skb -+ * -+ * @return: pointer on the destination STA (may be NULL) -+ * -+ * skb has already been parsed in rwnx_select_queue function -+ * simply re-read information form skb. -+ */ -+static struct rwnx_sta *rwnx_get_tx_priv(struct rwnx_vif *rwnx_vif, -+ struct sk_buff *skb, -+ u8 *tid) -+{ -+ static struct rwnx_hw *rwnx_hw; -+ struct rwnx_sta *sta; -+ int sta_idx; -+ int nx_remote_sta_max = NX_REMOTE_STA_MAX; -+ int nx_bcmc_txq_ndev_idx = NX_BCMC_TXQ_NDEV_IDX; -+ -+ -+ if((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) || -+ ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ -+ nx_remote_sta_max = NX_REMOTE_STA_MAX_FOR_OLD_IC; -+ nx_bcmc_txq_ndev_idx = NX_BCMC_TXQ_NDEV_IDX_FOR_OLD_IC; -+ } -+ -+ -+ rwnx_hw = rwnx_vif->rwnx_hw; -+ *tid = skb->priority; -+ if (unlikely(skb->priority == PRIO_STA_NULL)) { -+ return NULL; -+ } else { -+ int ndev_idx = skb_get_queue_mapping(skb); -+ -+ if (ndev_idx == nx_bcmc_txq_ndev_idx) -+ sta_idx = nx_remote_sta_max + master_vif_idx(rwnx_vif); -+ else -+ sta_idx = ndev_idx / NX_NB_TID_PER_STA; -+ -+ sta = &rwnx_hw->sta_table[sta_idx]; -+ } -+ -+ return sta; -+} -+ -+/** -+ * rwnx_prep_tx - Prepare buffer for DMA transmission -+ * -+ * @rwnx_hw: Driver main data -+ * @txhdr: Tx descriptor -+ * -+ * Maps hw_txhdr and buffer data for transmission via DMA. -+ * - Data buffer with be downloaded by embebded side. -+ * - hw_txhdr will be uploaded by embedded side when buffer has been -+ * transmitted over the air. -+ */ -+static int rwnx_prep_tx(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr) -+{ -+#if 0 -+ struct rwnx_sw_txhdr *sw_txhdr = txhdr->sw_hdr; -+ struct rwnx_hw_txhdr *hw_txhdr = &txhdr->hw_hdr; -+ dma_addr_t dma_addr; -+ -+ /* MAP (and sync) memory for DMA */ -+ dma_addr = dma_map_single(rwnx_hw->dev, hw_txhdr, -+ sw_txhdr->map_len, DMA_BIDIRECTIONAL); -+ if (WARN_ON(dma_mapping_error(rwnx_hw->dev, dma_addr))) -+ return -1; -+ -+ sw_txhdr->dma_addr = dma_addr; -+#endif -+ return 0; -+} -+ -+/** -+ * rwnx_tx_push - Push one packet to fw -+ * -+ * @rwnx_hw: Driver main data -+ * @txhdr: tx desc of the buffer to push -+ * @flags: push flags (see @rwnx_push_flags) -+ * -+ * Push one packet to fw. Sw desc of the packet has already been updated. -+ * Only MORE_DATA flag will be set if needed. -+ */ -+void rwnx_tx_push(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr, int flags) -+{ -+ struct rwnx_sw_txhdr *sw_txhdr = txhdr->sw_hdr; -+ struct sk_buff *skb = sw_txhdr->skb; -+ struct rwnx_txq *txq = sw_txhdr->txq; -+ u16 hw_queue = txq->hwq->id; -+ int user = 0; -+ -+ lockdep_assert_held(&rwnx_hw->tx_lock); -+ -+ //printk("rwnx_tx_push\n"); -+ /* RETRY flag is not always set so retest here */ -+ if (txq->nb_retry) { -+ flags |= RWNX_PUSH_RETRY; -+ txq->nb_retry--; -+ if (txq->nb_retry == 0) { -+ WARN(skb != txq->last_retry_skb, -+ "last retry buffer is not the expected one"); -+ txq->last_retry_skb = NULL; -+ } -+ } else if (!(flags & RWNX_PUSH_RETRY)) { -+ txq->pkt_sent++; -+ } -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ if (txq->amsdu == sw_txhdr) { -+ WARN((flags & RWNX_PUSH_RETRY), "End A-MSDU on a retry"); -+ rwnx_hw->stats.amsdus[sw_txhdr->amsdu.nb - 1].done++; -+ txq->amsdu = NULL; -+ } else if (!(flags & RWNX_PUSH_RETRY) && -+ !(sw_txhdr->desc.host.flags & TXU_CNTRL_AMSDU)) { -+ rwnx_hw->stats.amsdus[0].done++; -+ } -+#endif /* CONFIG_RWNX_AMSDUS_TX */ -+ -+ /* Wait here to update hw_queue, as for multicast STA hwq may change -+ between queue and push (because of PS) */ -+ sw_txhdr->hw_queue = hw_queue; -+ -+ //sw_txhdr->desc.host.packet_addr = hw_queue; //use packet_addr field for hw_txq -+ sw_txhdr->desc.host.ac = hw_queue; //use ac field for hw_txq -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ /* MU group is only selected during hwq processing */ -+ sw_txhdr->desc.host.mumimo_info = txq->mumimo_info; -+ user = RWNX_TXQ_POS_ID(txq); -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+ -+ if (sw_txhdr->rwnx_sta) { -+ /* only for AP mode */ -+ rwnx_set_more_data_flag(rwnx_hw, sw_txhdr); -+ } -+#ifdef CREATE_TRACE_POINTS -+ trace_push_desc(skb, sw_txhdr, flags); -+#endif -+ #if 0 -+ txq->credits--; -+ #endif -+ txq->pkt_pushed[user]++; -+ //printk("txq->credits=%d\n",txq->credits); -+ #if 0 -+ if (txq->credits <= 0) -+ rwnx_txq_stop(txq, RWNX_TXQ_STOP_FULL); -+ #endif -+ -+ if (txq->push_limit) -+ txq->push_limit--; -+#if 0 -+ rwnx_ipc_txdesc_push(rwnx_hw, &sw_txhdr->desc, skb, hw_queue, user); -+#else -+#ifdef AICWF_SDIO_SUPPORT -+ if (((sw_txhdr->desc.host.flags & TXU_CNTRL_MGMT) && \ -+ ((*(skb->data+sw_txhdr->headroom) == 0xd0) || (*(skb->data+sw_txhdr->headroom) == 0x10) || (*(skb->data+sw_txhdr->headroom) == 0x30))) || \ -+ (sw_txhdr->desc.host.ethertype == 0x8e88) || (sw_txhdr->desc.host.ethertype == 0xb488)) { -+ sw_txhdr->need_cfm = 1; -+ sw_txhdr->desc.host.hostid = ((1<<31) | rwnx_hw->sdio_env.txdesc_free_idx[0]); -+ aicwf_sdio_host_txdesc_push(&(rwnx_hw->sdio_env), 0, (long)skb); -+ AICWFDBG(LOGINFO, "need cfm ethertype:%8x,user_idx=%d, skb=%p\n", sw_txhdr->desc.host.ethertype, rwnx_hw->sdio_env.txdesc_free_idx[0], skb); -+ } else { -+ sw_txhdr->need_cfm = 0; -+ sw_txhdr->desc.host.hostid = 0; -+ -+ sw_txhdr->rwnx_vif->net_stats.tx_packets++; -+ sw_txhdr->rwnx_vif->net_stats.tx_bytes += sw_txhdr->frame_len; -+ rwnx_hw->stats.last_tx = jiffies; -+ } -+ aicwf_frame_tx((void *)(rwnx_hw->sdiodev), skb); -+#endif -+#ifdef AICWF_USB_SUPPORT -+ if (((sw_txhdr->desc.host.flags & TXU_CNTRL_MGMT) && \ -+ ((*(skb->data+sw_txhdr->headroom) == 0xd0) || (*(skb->data+sw_txhdr->headroom) == 0x10) || (*(skb->data+sw_txhdr->headroom) == 0x30))) || \ -+ (sw_txhdr->desc.host.ethertype == 0x8e88)) { -+ printk("push need cfm flags 0x%x\n", sw_txhdr->desc.host.flags); -+ sw_txhdr->need_cfm = 1; -+ sw_txhdr->desc.host.hostid = ((1<<31) | rwnx_hw->usb_env.txdesc_free_idx[0]); -+ aicwf_usb_host_txdesc_push(&(rwnx_hw->usb_env), 0, (long)(skb)); -+ } else { -+ sw_txhdr->need_cfm = 0; -+ sw_txhdr->desc.host.hostid = 0; -+ -+ sw_txhdr->rwnx_vif->net_stats.tx_packets++; -+ sw_txhdr->rwnx_vif->net_stats.tx_bytes += sw_txhdr->frame_len; -+ rwnx_hw->stats.last_tx = jiffies; -+ } -+ aicwf_frame_tx((void *)(rwnx_hw->usbdev), skb); -+#endif -+#endif -+#if 0 -+ txq->hwq->credits[user]--; -+#endif -+ rwnx_hw->stats.cfm_balance[hw_queue]++; -+} -+ -+ -+ -+/** -+ * rwnx_tx_retry - Push an AMPDU pkt that need to be retried -+ * -+ * @rwnx_hw: Driver main data -+ * @skb: pkt to re-push -+ * @txhdr: tx desc of the pkt to re-push -+ * @sw_retry: Indicates if fw decide to retry this buffer -+ * (i.e. it has never been transmitted over the air) -+ * -+ * Called when a packet needs to be repushed to the firmware. -+ * First update sw descriptor and then queue it in the retry list. -+ */ -+static void rwnx_tx_retry(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, -+ struct rwnx_txhdr *txhdr, bool sw_retry) -+{ -+ struct rwnx_sw_txhdr *sw_txhdr = txhdr->sw_hdr; -+ struct tx_cfm_tag *cfm = &txhdr->hw_hdr.cfm; -+ struct rwnx_txq *txq = sw_txhdr->txq; -+ int peek_off = offsetof(struct rwnx_hw_txhdr, cfm); -+ int peek_len = sizeof(((struct rwnx_hw_txhdr *)0)->cfm); -+ -+ if (!sw_retry) { -+ /* update sw desc */ -+ #if 0 -+ sw_txhdr->desc.host.sn = cfm->sn; -+ sw_txhdr->desc.host.pn[0] = cfm->pn[0]; -+ sw_txhdr->desc.host.pn[1] = cfm->pn[1]; -+ sw_txhdr->desc.host.pn[2] = cfm->pn[2]; -+ sw_txhdr->desc.host.pn[3] = cfm->pn[3]; -+ sw_txhdr->desc.host.timestamp = cfm->timestamp; -+ #endif -+ sw_txhdr->desc.host.flags |= TXU_CNTRL_RETRY; -+ -+ #ifdef CONFIG_RWNX_AMSDUS_TX -+ if (sw_txhdr->desc.host.flags & TXU_CNTRL_AMSDU) -+ rwnx_hw->stats.amsdus[sw_txhdr->amsdu.nb - 1].failed++; -+ #endif -+ } -+ -+ /* MORE_DATA will be re-set if needed when pkt will be repushed */ -+ sw_txhdr->desc.host.flags &= ~TXU_CNTRL_MORE_DATA; -+ -+ cfm->status.value = 0; -+ dma_sync_single_for_device(rwnx_hw->dev, sw_txhdr->dma_addr + peek_off, -+ peek_len, DMA_BIDIRECTIONAL); -+ -+ txq->credits++; -+ if (txq->credits > 0) -+ rwnx_txq_start(txq, RWNX_TXQ_STOP_FULL); -+ -+ /* Queue the buffer */ -+ rwnx_txq_queue_skb(skb, txq, rwnx_hw, true); -+} -+ -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+/* return size of subframe (including header) */ -+static inline int rwnx_amsdu_subframe_length(struct ethhdr *eth, int eth_len) -+{ -+ /* ethernet header is replaced with amdsu header that have the same size -+ Only need to check if LLC/SNAP header will be added */ -+ int len = eth_len; -+ -+ if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN) { -+ len += sizeof(rfc1042_header) + 2; -+ } -+ -+ return len; -+} -+ -+static inline bool rwnx_amsdu_is_aggregable(struct sk_buff *skb) -+{ -+ /* need to add some check on buffer to see if it can be aggregated ? */ -+ return true; -+} -+ -+ -+/** -+ * rwnx_amsdu_del_subframe_header - remove AMSDU header -+ * -+ * amsdu_txhdr: amsdu tx descriptor -+ * -+ * Move back the ethernet header at the "beginning" of the data buffer. -+ * (which has been moved in @rwnx_amsdu_add_subframe_header) -+ */ -+static void rwnx_amsdu_del_subframe_header(struct rwnx_amsdu_txhdr *amsdu_txhdr) -+{ -+ struct sk_buff *skb = amsdu_txhdr->skb; -+ struct ethhdr *eth; -+ u8 *pos; -+ -+ pos = skb->data; -+ pos += sizeof(struct rwnx_amsdu_txhdr); -+ eth = (struct ethhdr *)pos; -+ pos += amsdu_txhdr->pad + sizeof(struct ethhdr); -+ -+ if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN) { -+ pos += sizeof(rfc1042_header) + 2; -+ } -+ -+ memmove(pos, eth, sizeof(*eth)); -+ skb_pull(skb, (pos - skb->data)); -+} -+ -+/** -+ * rwnx_amsdu_add_subframe_header - Add AMSDU header and link subframe -+ * -+ * @rwnx_hw Driver main data -+ * @skb Buffer to aggregate -+ * @sw_txhdr Tx descriptor for the first A-MSDU subframe -+ * -+ * return 0 on sucess, -1 otherwise -+ * -+ * This functions Add A-MSDU header and LLC/SNAP header in the buffer -+ * and update sw_txhdr of the first subframe to link this buffer. -+ * If an error happens, the buffer will be queued as a normal buffer. -+ * -+ * -+ * Before After -+ * +-------------+ +-------------+ -+ * | HEADROOM | | HEADROOM | -+ * | | +-------------+ <- data -+ * | | | amsdu_txhdr | -+ * | | | * pad size | -+ * | | +-------------+ -+ * | | | ETH hdr | keep original eth hdr -+ * | | | | to restore it once transmitted -+ * | | +-------------+ <- packet_addr[x] -+ * | | | Pad | -+ * | | +-------------+ -+ * data -> +-------------+ | AMSDU HDR | -+ * | ETH hdr | +-------------+ -+ * | | | LLC/SNAP | -+ * +-------------+ +-------------+ -+ * | DATA | | DATA | -+ * | | | | -+ * +-------------+ +-------------+ -+ * -+ * Called with tx_lock hold -+ */ -+static int rwnx_amsdu_add_subframe_header(struct rwnx_hw *rwnx_hw, -+ struct sk_buff *skb, -+ struct rwnx_sw_txhdr *sw_txhdr) -+{ -+ struct rwnx_amsdu *amsdu = &sw_txhdr->amsdu; -+ struct rwnx_amsdu_txhdr *amsdu_txhdr; -+ struct ethhdr *amsdu_hdr, *eth = (struct ethhdr *)skb->data; -+ int headroom_need, map_len, msdu_len; -+ dma_addr_t dma_addr; -+ u8 *pos, *map_start; -+ -+ msdu_len = skb->len - sizeof(*eth); -+ headroom_need = sizeof(*amsdu_txhdr) + amsdu->pad + -+ sizeof(*amsdu_hdr); -+ if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN) { -+ headroom_need += sizeof(rfc1042_header) + 2; -+ msdu_len += sizeof(rfc1042_header) + 2; -+ } -+ -+ /* we should have enough headroom (checked in xmit) */ -+ if (WARN_ON(skb_headroom(skb) < headroom_need)) { -+ return -1; -+ } -+ -+ /* allocate headroom */ -+ pos = skb_push(skb, headroom_need); -+ amsdu_txhdr = (struct rwnx_amsdu_txhdr *)pos; -+ pos += sizeof(*amsdu_txhdr); -+ -+ /* move eth header */ -+ memmove(pos, eth, sizeof(*eth)); -+ eth = (struct ethhdr *)pos; -+ pos += sizeof(*eth); -+ -+ /* Add padding from previous subframe */ -+ map_start = pos; -+ memset(pos, 0, amsdu->pad); -+ pos += amsdu->pad; -+ -+ /* Add AMSDU hdr */ -+ amsdu_hdr = (struct ethhdr *)pos; -+ memcpy(amsdu_hdr->h_dest, eth->h_dest, ETH_ALEN); -+ memcpy(amsdu_hdr->h_source, eth->h_source, ETH_ALEN); -+ amsdu_hdr->h_proto = htons(msdu_len); -+ pos += sizeof(*amsdu_hdr); -+ -+ if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN) { -+ memcpy(pos, rfc1042_header, sizeof(rfc1042_header)); -+ pos += sizeof(rfc1042_header); -+ } -+ -+ /* MAP (and sync) memory for DMA */ -+ map_len = msdu_len + amsdu->pad + sizeof(*amsdu_hdr); -+ dma_addr = dma_map_single(rwnx_hw->dev, map_start, map_len, -+ DMA_BIDIRECTIONAL); -+ if (WARN_ON(dma_mapping_error(rwnx_hw->dev, dma_addr))) { -+ pos -= sizeof(*eth); -+ memmove(pos, eth, sizeof(*eth)); -+ skb_pull(skb, headroom_need); -+ return -1; -+ } -+ -+ /* update amdsu_txhdr */ -+ amsdu_txhdr->map_len = map_len; -+ amsdu_txhdr->dma_addr = dma_addr; -+ amsdu_txhdr->skb = skb; -+ amsdu_txhdr->pad = amsdu->pad; -+ amsdu_txhdr->msdu_len = msdu_len; -+ -+ /* update rwnx_sw_txhdr (of the first subframe) */ -+ BUG_ON(amsdu->nb != sw_txhdr->desc.host.packet_cnt); -+ sw_txhdr->desc.host.packet_addr[amsdu->nb] = dma_addr; -+ sw_txhdr->desc.host.packet_len[amsdu->nb] = map_len; -+ sw_txhdr->desc.host.packet_cnt++; -+ amsdu->nb++; -+ -+ amsdu->pad = AMSDU_PADDING(map_len - amsdu->pad); -+ list_add_tail(&amsdu_txhdr->list, &amsdu->hdrs); -+ amsdu->len += map_len; -+ -+ trace_amsdu_subframe(sw_txhdr); -+ return 0; -+} -+ -+/** -+ * rwnx_amsdu_add_subframe - Add this buffer as an A-MSDU subframe if possible -+ * -+ * @rwnx_hw Driver main data -+ * @skb Buffer to aggregate if possible -+ * @sta Destination STA -+ * @txq sta's txq used for this buffer -+ * -+ * Tyr to aggregate the buffer in an A-MSDU. If it succeed then the -+ * buffer is added as a new A-MSDU subframe with AMSDU and LLC/SNAP -+ * headers added (so FW won't have to modify this subframe). -+ * -+ * To be added as subframe : -+ * - sta must allow amsdu -+ * - buffer must be aggregable (to be defined) -+ * - at least one other aggregable buffer is pending in the queue -+ * or an a-msdu (with enough free space) is currently in progress -+ * -+ * returns true if buffer has been added as A-MDSP subframe, false otherwise -+ * -+ */ -+static bool rwnx_amsdu_add_subframe(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, -+ struct rwnx_sta *sta, struct rwnx_txq *txq) -+{ -+ bool res = false; -+ struct ethhdr *eth; -+ -+ /* immediately return if amsdu are not allowed for this sta */ -+ if (!txq->amsdu_len || rwnx_hw->mod_params->amsdu_maxnb < 2 || -+ !rwnx_amsdu_is_aggregable(skb) -+ ) -+ return false; -+ -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ if (txq->amsdu) { -+ /* aggreagation already in progress, add this buffer if enough space -+ available, otherwise end the current amsdu */ -+ struct rwnx_sw_txhdr *sw_txhdr = txq->amsdu; -+ eth = (struct ethhdr *)(skb->data); -+ -+ if (((sw_txhdr->amsdu.len + sw_txhdr->amsdu.pad + -+ rwnx_amsdu_subframe_length(eth, skb->len)) > txq->amsdu_len) || -+ rwnx_amsdu_add_subframe_header(rwnx_hw, skb, sw_txhdr)) { -+ txq->amsdu = NULL; -+ goto end; -+ } -+ -+ if (sw_txhdr->amsdu.nb >= rwnx_hw->mod_params->amsdu_maxnb) { -+ rwnx_hw->stats.amsdus[sw_txhdr->amsdu.nb - 1].done++; -+ /* max number of subframes reached */ -+ txq->amsdu = NULL; -+ } -+ } else { -+ /* Check if a new amsdu can be started with the previous buffer -+ (if any) and this one */ -+ struct sk_buff *skb_prev = skb_peek_tail(&txq->sk_list); -+ struct rwnx_txhdr *txhdr; -+ struct rwnx_sw_txhdr *sw_txhdr; -+ int len1, len2; -+ -+ if (!skb_prev || !rwnx_amsdu_is_aggregable(skb_prev)) -+ goto end; -+ -+ txhdr = (struct rwnx_txhdr *)skb_prev->data; -+ sw_txhdr = txhdr->sw_hdr; -+ if ((sw_txhdr->amsdu.len) || -+ (sw_txhdr->desc.host.flags & TXU_CNTRL_RETRY)) -+ /* previous buffer is already a complete amsdu or a retry */ -+ goto end; -+ -+ eth = (struct ethhdr *)(skb_prev->data + sw_txhdr->headroom); -+ len1 = rwnx_amsdu_subframe_length(eth, (sw_txhdr->frame_len + -+ sizeof(struct ethhdr))); -+ -+ eth = (struct ethhdr *)(skb->data); -+ len2 = rwnx_amsdu_subframe_length(eth, skb->len); -+ -+ if (len1 + AMSDU_PADDING(len1) + len2 > txq->amsdu_len) -+ /* not enough space to aggregate those two buffers */ -+ goto end; -+ -+ /* Add subframe header. -+ Note: Fw will take care of adding AMDSU header for the first -+ subframe while generating 802.11 MAC header */ -+ INIT_LIST_HEAD(&sw_txhdr->amsdu.hdrs); -+ sw_txhdr->amsdu.len = len1; -+ sw_txhdr->amsdu.nb = 1; -+ sw_txhdr->amsdu.pad = AMSDU_PADDING(len1); -+ if (rwnx_amsdu_add_subframe_header(rwnx_hw, skb, sw_txhdr)) -+ goto end; -+ -+ sw_txhdr->desc.host.flags |= TXU_CNTRL_AMSDU; -+ -+ if (sw_txhdr->amsdu.nb < rwnx_hw->mod_params->amsdu_maxnb) -+ txq->amsdu = sw_txhdr; -+ else -+ rwnx_hw->stats.amsdus[sw_txhdr->amsdu.nb - 1].done++; -+ } -+ -+ res = true; -+ -+end: -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+ return res; -+} -+#endif /* CONFIG_RWNX_AMSDUS_TX */ -+ -+#ifdef CONFIG_BR_SUPPORT -+int aic_br_client_tx(struct rwnx_vif *vif, struct sk_buff **pskb) -+{ -+ struct sk_buff *skb = *pskb; -+ -+ /* if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) */ -+ { -+ void dhcp_flag_bcast(struct rwnx_vif *vif, struct sk_buff *skb); -+ int res, is_vlan_tag = 0, i, do_nat25 = 1; -+ unsigned short vlan_hdr = 0; -+ void *br_port = NULL; -+ -+ /* mac_clone_handle_frame(priv, skb); */ -+ -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) -+ br_port = vif->ndev->br_port; -+#else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */ -+ rcu_read_lock(); -+ br_port = rcu_dereference(vif->ndev->rx_handler_data); -+ rcu_read_unlock(); -+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */ -+#ifdef BR_SUPPORT_DEBUG -+ printk("SA=%pM, br_mac=%pM, type=0x%x, da[0]=%x, scdb=%pM, vif_type=%d\n", skb->data + MACADDRLEN, vif->br_mac, *((unsigned short *)(skb->data + MACADDRLEN * 2)), -+ skb->data[0], vif->scdb_mac,RWNX_VIF_TYPE(vif)); -+#endif -+ spin_lock_bh(&vif->br_ext_lock); -+ if (!(skb->data[0] & 1) && -+ br_port && -+ memcmp(skb->data + MACADDRLEN, vif->br_mac, MACADDRLEN) && -+ *((unsigned short *)(skb->data + MACADDRLEN * 2)) != __constant_htons(ETH_P_8021Q) && -+ *((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP) && -+ !memcmp(vif->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN) && vif->scdb_entry) { -+ memcpy(skb->data + MACADDRLEN, vif->ndev->dev_addr, MACADDRLEN); -+ vif->scdb_entry->ageing_timer = jiffies; -+ spin_unlock_bh(&vif->br_ext_lock); -+ } else -+ /* if (!priv->pmib->ethBrExtInfo.nat25_disable) */ -+ { -+ /* if (priv->dev->br_port && -+ * !memcmp(skb->data+MACADDRLEN, priv->br_mac, MACADDRLEN)) { */ -+#if 1 -+ if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q)) { -+ is_vlan_tag = 1; -+ vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)); -+ for (i = 0; i < 6; i++) -+ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2)); -+ skb_pull(skb, 4); -+ } -+ /* if SA == br_mac && skb== IP => copy SIP to br_ip ?? why */ -+ if (!memcmp(skb->data + MACADDRLEN, vif->br_mac, MACADDRLEN) && -+ (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP))) -+ memcpy(vif->br_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4); -+ -+ if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP)) { -+ if (memcmp(vif->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN)) { -+ #if 1 -+ void *scdb_findEntry(struct rwnx_vif *vif, unsigned char *macAddr, unsigned char *ipAddr); -+ -+ vif->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(vif, -+ skb->data + MACADDRLEN, skb->data + WLAN_ETHHDR_LEN + 12); -+ if (vif->scdb_entry != NULL) { -+ memcpy(vif->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN); -+ memcpy(vif->scdb_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4); -+ vif->scdb_entry->ageing_timer = jiffies; -+ do_nat25 = 0; -+ } -+ #endif -+ } else { -+ if (vif->scdb_entry) { -+ vif->scdb_entry->ageing_timer = jiffies; -+ do_nat25 = 0; -+ } else { -+ memset(vif->scdb_mac, 0, MACADDRLEN); -+ memset(vif->scdb_ip, 0, 4); -+ } -+ } -+ } -+ spin_unlock_bh(&vif->br_ext_lock); -+#endif /* 1 */ -+ if (do_nat25) { -+ #if 1 -+ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method); -+ if (nat25_db_handle(vif, skb, NAT25_CHECK) == 0) { -+ struct sk_buff *newskb; -+ -+ if (is_vlan_tag) { -+ skb_push(skb, 4); -+ for (i = 0; i < 6; i++) -+ *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2)); -+ *((unsigned short *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q); -+ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr; -+ } -+ -+ newskb = skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); -+ if (newskb == NULL) { -+ /* priv->ext_stats.tx_drops++; */ -+ printk("TX DROP: skb_copy fail!\n"); -+ /* goto stop_proc; */ -+ return -1; -+ } -+ dev_kfree_skb_any(skb); -+ -+ *pskb = skb = newskb; -+ if (is_vlan_tag) { -+ vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)); -+ for (i = 0; i < 6; i++) -+ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2)); -+ skb_pull(skb, 4); -+ } -+ } -+ -+ if (skb_is_nonlinear(skb)) -+ printk("%s(): skb_is_nonlinear!!\n", __FUNCTION__); -+ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) -+ res = skb_linearize(skb, GFP_ATOMIC); -+#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) */ -+ res = skb_linearize(skb); -+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) */ -+ if (res < 0) { -+ printk("TX DROP: skb_linearize fail!\n"); -+ /* goto free_and_stop; */ -+ return -1; -+ } -+ -+ res = nat25_db_handle(vif, skb, NAT25_INSERT); -+ if (res < 0) { -+ if (res == -2) { -+ /* priv->ext_stats.tx_drops++; */ -+ printk("TX DROP: nat25_db_handle fail!\n"); -+ /* goto free_and_stop; */ -+ return -1; -+ -+ } -+ /* we just print warning message and let it go */ -+ /* DEBUG_WARN("%s()-%d: nat25_db_handle INSERT Warning!\n", __FUNCTION__, __LINE__); */ -+ /* return -1; */ /* return -1 will cause system crash on 2011/08/30! */ -+ return 0; -+ } -+ #endif -+ } -+ -+ memcpy(skb->data + MACADDRLEN, vif->ndev->dev_addr, MACADDRLEN); -+ -+ dhcp_flag_bcast(vif, skb); -+ -+ if (is_vlan_tag) { -+ skb_push(skb, 4); -+ for (i = 0; i < 6; i++) -+ *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2)); -+ *((unsigned short *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q); -+ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr; -+ } -+ } -+#if 0 -+ else { -+ if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q)) -+ is_vlan_tag = 1; -+ -+ if (is_vlan_tag) { -+ if (ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A_VALN(skb->data)) -+ memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); -+ } else { -+ if (ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A(skb->data)) -+ memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); -+ } -+ } -+#endif /* 0 */ -+ -+ /* check if SA is equal to our MAC */ -+ if (memcmp(skb->data + MACADDRLEN, vif->ndev->dev_addr, MACADDRLEN)) { -+ /* priv->ext_stats.tx_drops++; */ -+ printk("TX DROP: untransformed frame SA:%02X%02X%02X%02X%02X%02X!\n", -+ skb->data[6], skb->data[7], skb->data[8], skb->data[9], skb->data[10], skb->data[11]); -+ /* goto free_and_stop; */ -+ return -1; -+ } -+ } -+ printk("%s:exit\n",__func__); -+ return 0; -+} -+#endif /* CONFIG_BR_SUPPORT */ -+ -+ -+#ifdef CONFIG_FILTER_TCP_ACK -+/* return: -+ * 0, msg buf freed by the real driver -+ * others, skb need free by the caller,remember not use msg->skb! -+ */ -+ -+int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg) -+{ -+ struct rwnx_vif *rwnx_vif = msg->rwnx_vif; -+ struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; -+ struct rwnx_txhdr *txhdr; -+ struct rwnx_sw_txhdr *sw_txhdr; -+ struct txdesc_api *desc; -+ struct rwnx_sta *sta; -+ struct rwnx_txq *txq; -+ int headroom; -+ //int max_headroom; -+ int hdr_pads; -+ -+ u16 frame_len; -+ u16 frame_oft; -+ u8 tid; -+ struct sk_buff *skb=msg->skb; -+ struct ethhdr eth_t; -+ -+ move_tcpack_msg(rwnx_hw,msg); -+ kfree(msg); -+ -+ memcpy(ð_t, skb->data, sizeof(struct ethhdr)); -+ -+ /* Get the STA id and TID information */ -+ sta = rwnx_get_tx_priv(rwnx_vif, skb, &tid); -+ if (!sta) -+ goto free; -+ -+ txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); -+ if (txq->idx == TXQ_INACTIVE) -+ goto free; -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ if (rwnx_amsdu_add_subframe(rwnx_hw, skb, sta, txq)) -+ return NETDEV_TX_OK; -+#endif -+ -+#ifdef CONFIG_BR_SUPPORT -+ if (1) {//(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { -+ void *br_port = NULL; -+ -+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) -+ br_port = rwnx_vif->ndev->br_port; -+ #else -+ rcu_read_lock(); -+ br_port = rcu_dereference(rwnx_vif->ndev->rx_handler_data); -+ rcu_read_unlock(); -+ #endif -+ -+ if (br_port) { -+ s32 res = aic_br_client_tx(rwnx_vif, &skb); -+ if (res == -1) { -+ goto free; -+ } -+ } -+ } -+#endif /* CONFIG_BR_SUPPORT */ -+ -+ -+ /* Retrieve the pointer to the Ethernet data */ -+ // eth = (struct ethhdr *)skb->data; -+ -+ skb_pull(skb, 14); -+ //hdr_pads = RWNX_SWTXHDR_ALIGN_PADS((long)eth); -+ hdr_pads = RWNX_SWTXHDR_ALIGN_PADS((long)skb->data); -+ headroom = sizeof(struct rwnx_txhdr) + hdr_pads; -+ -+ skb_push(skb, headroom); -+ -+ txhdr = (struct rwnx_txhdr *)skb->data; -+ sw_txhdr = kmem_cache_alloc(rwnx_hw->sw_txhdr_cache, GFP_ATOMIC); -+ if (unlikely(sw_txhdr == NULL)) -+ goto free; -+ txhdr->sw_hdr = sw_txhdr; -+ desc = &sw_txhdr->desc; -+ -+ frame_len = (u16)skb->len - headroom;// - sizeof(*eth); -+ -+ sw_txhdr->txq = txq; -+ sw_txhdr->frame_len = frame_len; -+ sw_txhdr->rwnx_sta = sta; -+ sw_txhdr->rwnx_vif = rwnx_vif; -+ sw_txhdr->skb = skb; -+ sw_txhdr->headroom = headroom; -+ sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr); -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ sw_txhdr->amsdu.len = 0; -+ sw_txhdr->amsdu.nb = 0; -+#endif -+ // Fill-in the descriptor -+ memcpy(&desc->host.eth_dest_addr, eth_t.h_dest, ETH_ALEN); -+ memcpy(&desc->host.eth_src_addr, eth_t.h_source, ETH_ALEN); -+ desc->host.ethertype = eth_t.h_proto; -+ desc->host.staid = sta->sta_idx; -+ desc->host.tid = tid; -+ if (unlikely(rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP_VLAN)) -+ desc->host.vif_idx = rwnx_vif->ap_vlan.master->vif_index; -+ else -+ desc->host.vif_idx = rwnx_vif->vif_index; -+ -+ if (rwnx_vif->use_4addr && (sta->sta_idx < NX_REMOTE_STA_MAX)) -+ desc->host.flags = TXU_CNTRL_USE_4ADDR; -+ else -+ desc->host.flags = 0; -+ -+ if ((rwnx_vif->tdls_status == TDLS_LINK_ACTIVE) && -+ rwnx_vif->sta.tdls_sta && -+ (memcmp(desc->host.eth_dest_addr.array, rwnx_vif->sta.tdls_sta->mac_addr, ETH_ALEN) == 0)) { -+ desc->host.flags |= TXU_CNTRL_TDLS; -+ rwnx_vif->sta.tdls_sta->tdls.last_tid = desc->host.tid; -+ //rwnx_vif->sta.tdls_sta->tdls.last_sn = desc->host.sn; -+ } -+ -+ if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_MESH_POINT) { -+ if (rwnx_vif->is_resending) { -+ desc->host.flags |= TXU_CNTRL_MESH_FWD; -+ } -+ } -+ -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ desc->host.packet_len[0] = frame_len; -+#else -+ desc->host.packet_len = frame_len; -+#endif -+ -+ txhdr->hw_hdr.cfm.status.value = 0; -+ -+ if (unlikely(rwnx_prep_tx(rwnx_hw, txhdr))) { -+ kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr); -+ skb_pull(skb, headroom); -+ dev_kfree_skb_any(skb); -+ return NETDEV_TX_BUSY; -+ } -+ -+ /* Fill-in TX descriptor */ -+ frame_oft = sizeof(struct rwnx_txhdr) - offsetof(struct rwnx_txhdr, hw_hdr) -+ + hdr_pads;// + sizeof(*eth); -+#if 0 -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ desc->host.packet_addr[0] = sw_txhdr->dma_addr + frame_oft; -+ desc->host.packet_cnt = 1; -+#else -+ desc->host.packet_addr = sw_txhdr->dma_addr + frame_oft; -+#endif -+#endif -+ desc->host.hostid = sw_txhdr->dma_addr; -+ -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ if (rwnx_txq_queue_skb(skb, txq, rwnx_hw, false)) -+ rwnx_hwq_process(rwnx_hw, txq->hwq); -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+ -+ return 0;//NETDEV_TX_OK -+ -+free: -+ dev_kfree_skb_any(skb); -+ -+ return 0;//NETDEV_TX_OK -+} -+#endif -+ -+/** -+ * netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, -+ * struct net_device *dev); -+ * Called when a packet needs to be transmitted. -+ * Must return NETDEV_TX_OK , NETDEV_TX_BUSY. -+ * (can also return NETDEV_TX_LOCKED if NETIF_F_LLTX) -+ * -+ * - Initialize the desciptor for this pkt (stored in skb before data) -+ * - Push the pkt in the corresponding Txq -+ * - If possible (i.e. credit available and not in PS) the pkt is pushed -+ * to fw -+ */ -+netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct rwnx_vif *rwnx_vif = netdev_priv(dev); -+ struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; -+ struct rwnx_txhdr *txhdr; -+ struct rwnx_sw_txhdr *sw_txhdr; -+ struct txdesc_api *desc; -+ struct rwnx_sta *sta; -+ struct rwnx_txq *txq; -+ int headroom; -+ int max_headroom; -+ int hdr_pads; -+ -+ u16 frame_len; -+ u16 frame_oft; -+ u8 tid; -+ -+ struct ethhdr eth_t; -+#ifdef CONFIG_FILTER_TCP_ACK -+ struct msg_buf *msgbuf; -+#endif -+ -+#ifdef CONFIG_ONE_TXQ -+ skb->queue_mapping = rwnx_select_txq(rwnx_vif, skb); -+#endif -+ -+ sk_pacing_shift_update(skb->sk, rwnx_hw->tcp_pacing_shift); -+ max_headroom = sizeof(struct rwnx_txhdr); -+ -+ /* check whether the current skb can be used */ -+ if (skb_shared(skb) || (skb_headroom(skb) < max_headroom) || -+ (skb_cloned(skb) && (dev->priv_flags & IFF_BRIDGE_PORT))) { -+ struct sk_buff *newskb = skb_copy_expand(skb, max_headroom, 0, -+ GFP_ATOMIC); -+ if (unlikely(newskb == NULL)) -+ goto free; -+ -+ dev_kfree_skb_any(skb); -+ -+ skb = newskb; -+ } -+ -+ if(skb->priority < 3) -+ skb->priority = 0; -+ -+#ifdef CONFIG_FILTER_TCP_ACK -+ msgbuf=intf_tcp_alloc_msg(msgbuf); -+ msgbuf->rwnx_vif=rwnx_vif; -+ msgbuf->skb=skb; -+ if(filter_send_tcp_ack(rwnx_hw,msgbuf,skb->data,cpu_to_le16(skb->len))){ -+ return NETDEV_TX_OK; -+ }else{ -+ move_tcpack_msg(rwnx_hw,msgbuf); -+ kfree(msgbuf); -+ } -+#endif -+ -+ memcpy(ð_t, skb->data, sizeof(struct ethhdr)); -+ -+ /* Get the STA id and TID information */ -+ sta = rwnx_get_tx_priv(rwnx_vif, skb, &tid); -+ if (!sta) -+ goto free; -+ -+ txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); -+ if (txq->idx == TXQ_INACTIVE) -+ goto free; -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ if (rwnx_amsdu_add_subframe(rwnx_hw, skb, sta, txq)) -+ return NETDEV_TX_OK; -+#endif -+ -+ #ifdef CONFIG_BR_SUPPORT -+ if (1) {//(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { -+ void *br_port = NULL; -+ -+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) -+ br_port = rwnx_vif->ndev->br_port; -+ #else -+ rcu_read_lock(); -+ br_port = rcu_dereference(rwnx_vif->ndev->rx_handler_data); -+ rcu_read_unlock(); -+ #endif -+ -+ if (br_port) { -+ s32 res = aic_br_client_tx(rwnx_vif, &skb); -+ if (res == -1) { -+ goto free; -+ } -+ } -+ } -+ #endif /* CONFIG_BR_SUPPORT */ -+ -+ -+ /* Retrieve the pointer to the Ethernet data */ -+ // eth = (struct ethhdr *)skb->data; -+ -+ skb_pull(skb, 14); -+ //hdr_pads = RWNX_SWTXHDR_ALIGN_PADS((long)eth); -+ hdr_pads = RWNX_SWTXHDR_ALIGN_PADS((long)skb->data); -+ headroom = sizeof(struct rwnx_txhdr) + hdr_pads; -+ -+ skb_push(skb, headroom); -+ -+ txhdr = (struct rwnx_txhdr *)skb->data; -+ sw_txhdr = kmem_cache_alloc(rwnx_hw->sw_txhdr_cache, GFP_ATOMIC); -+ if (unlikely(sw_txhdr == NULL)) -+ goto free; -+ txhdr->sw_hdr = sw_txhdr; -+ desc = &sw_txhdr->desc; -+ -+ frame_len = (u16)skb->len - headroom;// - sizeof(*eth); -+ -+ sw_txhdr->txq = txq; -+ sw_txhdr->frame_len = frame_len; -+ sw_txhdr->rwnx_sta = sta; -+ sw_txhdr->rwnx_vif = rwnx_vif; -+ sw_txhdr->skb = skb; -+ sw_txhdr->headroom = headroom; -+ sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr); -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ sw_txhdr->amsdu.len = 0; -+ sw_txhdr->amsdu.nb = 0; -+#endif -+ // Fill-in the descriptor -+ memcpy(&desc->host.eth_dest_addr, eth_t.h_dest, ETH_ALEN); -+ memcpy(&desc->host.eth_src_addr, eth_t.h_source, ETH_ALEN); -+ desc->host.ethertype = eth_t.h_proto; -+ desc->host.staid = sta->sta_idx; -+ desc->host.tid = tid; -+ if (unlikely(rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP_VLAN)) -+ desc->host.vif_idx = rwnx_vif->ap_vlan.master->vif_index; -+ else -+ desc->host.vif_idx = rwnx_vif->vif_index; -+ -+ if (rwnx_vif->use_4addr && (sta->sta_idx < NX_REMOTE_STA_MAX)) -+ desc->host.flags = TXU_CNTRL_USE_4ADDR; -+ else -+ desc->host.flags = 0; -+ -+ if ((rwnx_vif->tdls_status == TDLS_LINK_ACTIVE) && -+ rwnx_vif->sta.tdls_sta && -+ (memcmp(desc->host.eth_dest_addr.array, rwnx_vif->sta.tdls_sta->mac_addr, ETH_ALEN) == 0)) { -+ desc->host.flags |= TXU_CNTRL_TDLS; -+ rwnx_vif->sta.tdls_sta->tdls.last_tid = desc->host.tid; -+ //rwnx_vif->sta.tdls_sta->tdls.last_sn = desc->host.sn; -+ } -+ -+ if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_MESH_POINT) { -+ if (rwnx_vif->is_resending) { -+ desc->host.flags |= TXU_CNTRL_MESH_FWD; -+ } -+ } -+ -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ desc->host.packet_len[0] = frame_len; -+#else -+ desc->host.packet_len = frame_len; -+#endif -+ -+ txhdr->hw_hdr.cfm.status.value = 0; -+ -+ if (unlikely(rwnx_prep_tx(rwnx_hw, txhdr))) { -+ kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr); -+ skb_pull(skb, headroom); -+ dev_kfree_skb_any(skb); -+ return NETDEV_TX_BUSY; -+ } -+ -+ /* Fill-in TX descriptor */ -+ frame_oft = sizeof(struct rwnx_txhdr) - offsetof(struct rwnx_txhdr, hw_hdr) -+ + hdr_pads;// + sizeof(*eth); -+#if 0 -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ desc->host.packet_addr[0] = sw_txhdr->dma_addr + frame_oft; -+ desc->host.packet_cnt = 1; -+#else -+ desc->host.packet_addr = sw_txhdr->dma_addr + frame_oft; -+#endif -+#endif -+ desc->host.hostid = sw_txhdr->dma_addr; -+ -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ if (rwnx_txq_queue_skb(skb, txq, rwnx_hw, false)) -+ rwnx_hwq_process(rwnx_hw, txq->hwq); -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+ -+ return NETDEV_TX_OK; -+ -+free: -+ dev_kfree_skb_any(skb); -+ -+ return NETDEV_TX_OK; -+} -+ -+/** -+ * rwnx_start_mgmt_xmit - Transmit a management frame -+ * -+ * @vif: Vif that send the frame -+ * @sta: Destination of the frame. May be NULL if the destiantion is unknown -+ * to the AP. -+ * @params: Mgmt frame parameters -+ * @offchan: Indicate whether the frame must be send via the offchan TXQ. -+ * (is is redundant with params->offchan ?) -+ * @cookie: updated with a unique value to identify the frame with upper layer -+ * -+ */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta, -+ struct cfg80211_mgmt_tx_params *params, bool offchan, -+ u64 *cookie) -+#else -+int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta, -+ struct ieee80211_channel *channel, bool offchan, -+ unsigned int wait, const u8 *buf, size_t len, -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) -+ bool no_cck, -+ #endif -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) -+ bool dont_wait_for_ack, -+ #endif -+ u64 *cookie) -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ -+{ -+ struct rwnx_hw *rwnx_hw = vif->rwnx_hw; -+ struct rwnx_txhdr *txhdr; -+ struct rwnx_sw_txhdr *sw_txhdr; -+ struct txdesc_api *desc; -+ struct sk_buff *skb; -+ u16 frame_len, headroom, frame_oft; -+ u8 *data; -+ int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX; -+ struct rwnx_txq *txq; -+ bool robust; -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+ const u8 *buf = params->buf; -+ size_t len = params->len; -+ bool no_cck = params->no_cck; -+ #endif -+ -+ AICWFDBG(LOGDEBUG,"mgmt xmit %x %x ",buf[0],buf[1]); -+ -+ if((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) || -+ ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ -+ nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC; -+ } -+ -+ -+ headroom = sizeof(struct rwnx_txhdr); -+ frame_len = len; -+ -+ //---------------------------------------------------------------------- -+ -+ /* Set TID and Queues indexes */ -+ if (sta) { -+ txq = rwnx_txq_sta_get(sta, 8, rwnx_hw); -+ } else { -+ if (offchan) -+ txq = &rwnx_hw->txq[nx_off_chan_txq_idx]; -+ else -+ txq = rwnx_txq_vif_get(vif, NX_UNK_TXQ_TYPE); -+ } -+ -+ /* Ensure that TXQ is active */ -+ if (txq->idx == TXQ_INACTIVE) { -+ netdev_dbg(vif->ndev, "TXQ inactive\n"); -+ return -EBUSY; -+ } -+ -+ /* -+ * Create a SK Buff object that will contain the provided data -+ */ -+ skb = dev_alloc_skb(headroom + frame_len); -+ -+ if (!skb) { -+ return -ENOMEM; -+ } -+ -+ *cookie = (unsigned long)skb; -+ -+ /* -+ * Move skb->data pointer in order to reserve room for rwnx_txhdr -+ * headroom value will be equal to sizeof(struct rwnx_txhdr) -+ */ -+ skb_reserve(skb, headroom); -+ -+ /* -+ * Extend the buffer data area in order to contain the provided packet -+ * len value (for skb) will be equal to param->len -+ */ -+ data = skb_put(skb, frame_len); -+ /* Copy the provided data */ -+ memcpy(data, buf, frame_len); -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) -+ robust = ieee80211_is_robust_mgmt_frame(skb); -+#else -+ if (skb->len < 25){ -+ robust = false; -+ } -+ robust = ieee80211_is_robust_mgmt_frame((void *)skb->data); -+#endif -+ -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) -+ /* Update CSA counter if present */ -+ if (unlikely(params->n_csa_offsets) && -+ vif->wdev.iftype == NL80211_IFTYPE_AP && -+ vif->ap.csa) { -+ int i; -+ -+ data = skb->data; -+ for (i = 0; i < params->n_csa_offsets ; i++) { -+ data[params->csa_offsets[i]] = vif->ap.csa->count; -+ } -+ } -+ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ -+ -+ /* -+ * Go back to the beginning of the allocated data area -+ * skb->data pointer will move backward -+ */ -+ skb_push(skb, headroom); -+ -+ //---------------------------------------------------------------------- -+ -+ /* Fill the TX Header */ -+ txhdr = (struct rwnx_txhdr *)skb->data; -+ -+ txhdr->hw_hdr.cfm.status.value = 0; -+ -+ //---------------------------------------------------------------------- -+ -+ /* Fill the SW TX Header */ -+ sw_txhdr = kmem_cache_alloc(rwnx_hw->sw_txhdr_cache, GFP_ATOMIC); -+ if (unlikely(sw_txhdr == NULL)) { -+ dev_kfree_skb(skb); -+ return -ENOMEM; -+ } -+ txhdr->sw_hdr = sw_txhdr; -+ -+ sw_txhdr->txq = txq; -+ sw_txhdr->frame_len = frame_len; -+ sw_txhdr->rwnx_sta = sta; -+ sw_txhdr->rwnx_vif = vif; -+ sw_txhdr->skb = skb; -+ sw_txhdr->headroom = headroom; -+ sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr); -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ sw_txhdr->amsdu.len = 0; -+ sw_txhdr->amsdu.nb = 0; -+#endif -+ //---------------------------------------------------------------------- -+ -+ /* Fill the Descriptor to be provided to the MAC SW */ -+ desc = &sw_txhdr->desc; -+ -+ desc->host.ethertype = 0; -+ desc->host.staid = (sta) ? sta->sta_idx : 0xFF; -+ desc->host.vif_idx = vif->vif_index; -+ desc->host.tid = 0xFF; -+ desc->host.flags = TXU_CNTRL_MGMT; -+ if (robust) -+ desc->host.flags |= TXU_CNTRL_MGMT_ROBUST; -+ -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ desc->host.packet_len[0] = frame_len; -+#else -+ desc->host.packet_len = frame_len; -+#endif -+ -+ if (no_cck) { -+ desc->host.flags |= TXU_CNTRL_MGMT_NO_CCK; -+ } -+ -+ /* Get DMA Address */ -+ if (unlikely(rwnx_prep_tx(rwnx_hw, txhdr))) { -+ kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr); -+ dev_kfree_skb(skb); -+ return -EBUSY; -+ } -+ -+ frame_oft = sizeof(struct rwnx_txhdr) - offsetof(struct rwnx_txhdr, hw_hdr); -+#if 0 -+#ifdef CONFIG_RWNX_SPLIT_TX_BUF -+ desc->host.packet_addr[0] = sw_txhdr->dma_addr + frame_oft; -+ desc->host.packet_cnt = 1; -+#else -+ desc->host.packet_addr = sw_txhdr->dma_addr + frame_oft; -+#endif -+#endif -+ desc->host.hostid = sw_txhdr->dma_addr; -+ -+ //---------------------------------------------------------------------- -+ -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ if (rwnx_txq_queue_skb(skb, txq, rwnx_hw, false)) -+ rwnx_hwq_process(rwnx_hw, txq->hwq); -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+ -+ return 0; -+} -+ -+/** -+ * rwnx_txdatacfm - FW callback for TX confirmation -+ * -+ * called with tx_lock hold -+ */ -+int rwnx_txdatacfm(void *pthis, void *host_id) -+{ -+ struct rwnx_hw *rwnx_hw = (struct rwnx_hw *)pthis; -+ struct sk_buff *skb = host_id; -+ struct rwnx_txhdr *txhdr; -+ union rwnx_hw_txstatus rwnx_txst; -+ struct rwnx_sw_txhdr *sw_txhdr; -+ struct rwnx_hwq *hwq; -+ struct rwnx_txq *txq; -+ int headroom; -+ //int peek_off = offsetof(struct rwnx_hw_txhdr, cfm); -+ //int peek_len = sizeof(((struct rwnx_hw_txhdr *)0)->cfm); -+ -+ txhdr = (struct rwnx_txhdr *)skb->data; -+ sw_txhdr = txhdr->sw_hdr; -+ -+ /* Read status in the TX control header */ -+ rwnx_txst = txhdr->hw_hdr.cfm.status; -+ -+ /* Check status in the header. If status is null, it means that the buffer -+ * was not transmitted and we have to return immediately */ -+ if (rwnx_txst.value == 0) { -+ return -1; -+ } -+ -+#ifdef AICWF_USB_SUPPORT -+ if (rwnx_hw->usbdev->state == USB_DOWN_ST) { -+ headroom = sw_txhdr->headroom; -+ kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr); -+ skb_pull(skb, headroom); -+ consume_skb(skb); -+ return 0; -+ } -+#endif -+#ifdef AICWF_SDIO_SUPPORT -+ if(rwnx_hw->sdiodev->bus_if->state == BUS_DOWN_ST) { -+ headroom = sw_txhdr->headroom; -+ kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr); -+ skb_pull(skb, headroom); -+ consume_skb(skb); -+ return 0; -+ } -+#endif -+ -+ txq = sw_txhdr->txq; -+ /* don't use txq->hwq as it may have changed between push and confirm */ -+ hwq = &rwnx_hw->hwq[sw_txhdr->hw_queue]; -+ rwnx_txq_confirm_any(rwnx_hw, txq, hwq, sw_txhdr); -+ -+ /* Update txq and HW queue credits */ -+ if (sw_txhdr->desc.host.flags & TXU_CNTRL_MGMT) { -+ printk("done=%d retry_required=%d sw_retry_required=%d acknowledged=%d\n", -+ rwnx_txst.tx_done, rwnx_txst.retry_required, -+ rwnx_txst.sw_retry_required, rwnx_txst.acknowledged); -+#ifdef CREATE_TRACE_POINTS -+ trace_mgmt_cfm(sw_txhdr->rwnx_vif->vif_index, -+ (sw_txhdr->rwnx_sta) ? sw_txhdr->rwnx_sta->sta_idx : 0xFF, -+ rwnx_txst.acknowledged); -+#endif -+ /* Confirm transmission to CFG80211 */ -+ cfg80211_mgmt_tx_status(&sw_txhdr->rwnx_vif->wdev, -+ (unsigned long)skb, -+ (skb->data + sw_txhdr->headroom), -+ sw_txhdr->frame_len, -+ rwnx_txst.acknowledged, -+ GFP_ATOMIC); -+ } else if ((txq->idx != TXQ_INACTIVE) && -+ (rwnx_txst.retry_required || rwnx_txst.sw_retry_required)) { -+ bool sw_retry = (rwnx_txst.sw_retry_required) ? true : false; -+ -+ /* Reset the status */ -+ txhdr->hw_hdr.cfm.status.value = 0; -+ -+ /* The confirmed packet was part of an AMPDU and not acked -+ * correctly, so reinject it in the TX path to be retried */ -+ rwnx_tx_retry(rwnx_hw, skb, txhdr, sw_retry); -+ return 0; -+ } -+#ifdef CREATE_TRACE_POINTS -+ trace_skb_confirm(skb, txq, hwq, &txhdr->hw_hdr.cfm); -+#endif -+ /* STA may have disconnect (and txq stopped) when buffers were stored -+ in fw. In this case do nothing when they're returned */ -+ if (txq->idx != TXQ_INACTIVE) { -+ #if 0 -+ if (txhdr->hw_hdr.cfm.credits) { -+ txq->credits += txhdr->hw_hdr.cfm.credits; -+ if (txq->credits <= 0) -+ rwnx_txq_stop(txq, RWNX_TXQ_STOP_FULL); -+ else if (txq->credits > 0) -+ rwnx_txq_start(txq, RWNX_TXQ_STOP_FULL); -+ } -+ #endif -+ -+ /* continue service period */ -+ if (unlikely(txq->push_limit && !rwnx_txq_is_full(txq))) { -+ rwnx_txq_add_to_hw_list(txq); -+ } -+ } -+ -+ if (txhdr->hw_hdr.cfm.ampdu_size && -+ txhdr->hw_hdr.cfm.ampdu_size < IEEE80211_MAX_AMPDU_BUF) -+ rwnx_hw->stats.ampdus_tx[txhdr->hw_hdr.cfm.ampdu_size - 1]++; -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ txq->amsdu_len = txhdr->hw_hdr.cfm.amsdu_size; -+#endif -+ -+ /* Update statistics */ -+ sw_txhdr->rwnx_vif->net_stats.tx_packets++; -+ sw_txhdr->rwnx_vif->net_stats.tx_bytes += sw_txhdr->frame_len; -+ -+ /* Release SKBs */ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ if (sw_txhdr->desc.host.flags & TXU_CNTRL_AMSDU) { -+ struct rwnx_amsdu_txhdr *amsdu_txhdr; -+ list_for_each_entry(amsdu_txhdr, &sw_txhdr->amsdu.hdrs, list) { -+ rwnx_amsdu_del_subframe_header(amsdu_txhdr); -+ consume_skb(amsdu_txhdr->skb); -+ } -+ } -+#endif /* CONFIG_RWNX_AMSDUS_TX */ -+ -+ headroom = sw_txhdr->headroom; -+ kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr); -+ skb_pull(skb, headroom); -+ consume_skb(skb); -+ -+ return 0; -+} -+ -+/** -+ * rwnx_txq_credit_update - Update credit for one txq -+ * -+ * @rwnx_hw: Driver main data -+ * @sta_idx: STA idx -+ * @tid: TID -+ * @update: offset to apply in txq credits -+ * -+ * Called when fw send ME_TX_CREDITS_UPDATE_IND message. -+ * Apply @update to txq credits, and stop/start the txq if needed -+ */ -+void rwnx_txq_credit_update(struct rwnx_hw *rwnx_hw, int sta_idx, u8 tid, -+ s8 update) -+{ -+ struct rwnx_sta *sta = &rwnx_hw->sta_table[sta_idx]; -+ struct rwnx_txq *txq; -+ -+ txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); -+ -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ -+ if (txq->idx != TXQ_INACTIVE) { -+ //txq->credits += update; -+#ifdef CREATE_TRACE_POINTS -+ trace_credit_update(txq, update); -+#endif -+ if (txq->credits <= 0) -+ rwnx_txq_stop(txq, RWNX_TXQ_STOP_FULL); -+ else -+ rwnx_txq_start(txq, RWNX_TXQ_STOP_FULL); -+ } -+ -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tx.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tx.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_tx.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,188 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_tx.h -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+#ifndef _RWNX_TX_H_ -+#define _RWNX_TX_H_ -+ -+#include -+#include -+#include -+#include "lmac_types.h" -+#include "ipc_shared.h" -+#include "rwnx_txq.h" -+#include "hal_desc.h" -+ -+#define RWNX_HWQ_BK 0 -+#define RWNX_HWQ_BE 1 -+#define RWNX_HWQ_VI 2 -+#define RWNX_HWQ_VO 3 -+#define RWNX_HWQ_BCMC 4 -+#define RWNX_HWQ_NB NX_TXQ_CNT -+#define RWNX_HWQ_ALL_ACS (RWNX_HWQ_BK | RWNX_HWQ_BE | RWNX_HWQ_VI | RWNX_HWQ_VO) -+#define RWNX_HWQ_ALL_ACS_BIT (BIT(RWNX_HWQ_BK) | BIT(RWNX_HWQ_BE) | \ -+ BIT(RWNX_HWQ_VI) | BIT(RWNX_HWQ_VO)) -+ -+#define RWNX_TX_LIFETIME_MS 1000 -+#define RWNX_TX_MAX_RATES NX_TX_MAX_RATES -+ -+#define RWNX_SWTXHDR_ALIGN_SZ 4 -+#define RWNX_SWTXHDR_ALIGN_MSK (RWNX_SWTXHDR_ALIGN_SZ - 1) -+#define RWNX_SWTXHDR_ALIGN_PADS(x) \ -+ ((RWNX_SWTXHDR_ALIGN_SZ - ((x) & RWNX_SWTXHDR_ALIGN_MSK)) \ -+ & RWNX_SWTXHDR_ALIGN_MSK) -+#if RWNX_SWTXHDR_ALIGN_SZ & RWNX_SWTXHDR_ALIGN_MSK -+#error bad RWNX_SWTXHDR_ALIGN_SZ -+#endif -+ -+#define AMSDU_PADDING(x) ((4 - ((x) & 0x3)) & 0x3) -+ -+#define TXU_CNTRL_RETRY BIT(0) -+#define TXU_CNTRL_MORE_DATA BIT(2) -+#define TXU_CNTRL_MGMT BIT(3) -+#define TXU_CNTRL_MGMT_NO_CCK BIT(4) -+#define TXU_CNTRL_AMSDU BIT(6) -+#define TXU_CNTRL_MGMT_ROBUST BIT(7) -+#define TXU_CNTRL_USE_4ADDR BIT(8) -+#define TXU_CNTRL_EOSP BIT(9) -+#define TXU_CNTRL_MESH_FWD BIT(10) -+#define TXU_CNTRL_TDLS BIT(11) -+ -+extern const int rwnx_tid2hwq[IEEE80211_NUM_TIDS]; -+ -+/** -+ * struct rwnx_amsdu_txhdr - Structure added in skb headroom (instead of -+ * rwnx_txhdr) for amsdu subframe buffer (except for the first subframe -+ * that has a normal rwnx_txhdr) -+ * -+ * @list List of other amsdu subframe (rwnx_sw_txhdr.amsdu.hdrs) -+ * @map_len Length to be downloaded for this subframe -+ * @dma_addr Buffer address form embedded point of view -+ * @skb skb -+ * @pad padding added before this subframe -+ * (only use when amsdu must be dismantled) -+ * @msdu_len Size, in bytes, of the MSDU (without padding nor amsdu header) -+ */ -+struct rwnx_amsdu_txhdr { -+ struct list_head list; -+ size_t map_len; -+ dma_addr_t dma_addr; -+ struct sk_buff *skb; -+ u16 pad; -+ u16 msdu_len; -+}; -+ -+/** -+ * struct rwnx_amsdu - Structure to manage creation of an A-MSDU, updated -+ * only In the first subframe of an A-MSDU -+ * -+ * @hdrs List of subframe of rwnx_amsdu_txhdr -+ * @len Current size for this A-MDSU (doesn't take padding into account) -+ * 0 means that no amsdu is in progress -+ * @nb Number of subframe in the amsdu -+ * @pad Padding to add before adding a new subframe -+ */ -+struct rwnx_amsdu { -+ struct list_head hdrs; -+ u16 len; -+ u8 nb; -+ u8 pad; -+}; -+ -+/** -+ * struct rwnx_sw_txhdr - Software part of tx header -+ * -+ * @rwnx_sta sta to which this buffer is addressed -+ * @rwnx_vif vif that send the buffer -+ * @txq pointer to TXQ used to send the buffer -+ * @hw_queue Index of the HWQ used to push the buffer. -+ * May be different than txq->hwq->id on confirmation. -+ * @frame_len Size of the frame (doesn't not include mac header) -+ * (Only used to update stat, can't we use skb->len instead ?) -+ * @headroom Headroom added in skb to add rwnx_txhdr -+ * (Only used to remove it before freeing skb, is it needed ?) -+ * @amsdu Description of amsdu whose first subframe is this buffer -+ * (amsdu.nb = 0 means this buffer is not part of amsdu) -+ * @skb skb received from transmission -+ * @map_len Length mapped for DMA (only rwnx_hw_txhdr and data are mapped) -+ * @dma_addr DMA address after mapping -+ * @desc Buffer description that will be copied in shared mem for FW -+ */ -+struct rwnx_sw_txhdr { -+ struct rwnx_sta *rwnx_sta; -+ struct rwnx_vif *rwnx_vif; -+ struct rwnx_txq *txq; -+ u8 hw_queue; -+ u16 frame_len; -+ u16 headroom; -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ struct rwnx_amsdu amsdu; -+#endif -+ u32 need_cfm; -+ struct sk_buff *skb; -+ -+ size_t map_len; -+ dma_addr_t dma_addr; -+ struct txdesc_api desc; -+}; -+ -+/** -+ * struct rwnx_txhdr - Stucture to control transimission of packet -+ * (Added in skb headroom) -+ * -+ * @sw_hdr: Information from driver -+ * @cache_guard: -+ * @hw_hdr: Information for/from hardware -+ */ -+struct rwnx_txhdr { -+ struct rwnx_sw_txhdr *sw_hdr; -+ char cache_guard[L1_CACHE_BYTES]; -+ struct rwnx_hw_txhdr hw_hdr; -+}; -+ -+u16 rwnx_select_txq(struct rwnx_vif *rwnx_vif, struct sk_buff *skb); -+netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta, -+ struct cfg80211_mgmt_tx_params *params, bool offchan, -+ u64 *cookie); -+#else -+int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta, -+ struct ieee80211_channel *channel, bool offchan, -+ unsigned int wait, const u8 *buf, size_t len, -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) -+ bool no_cck, -+ #endif -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) -+ bool dont_wait_for_ack, -+ #endif -+ u64 *cookie); -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ -+int rwnx_txdatacfm(void *pthis, void *host_id); -+ -+struct rwnx_hw; -+struct rwnx_sta; -+void rwnx_set_traffic_status(struct rwnx_hw *rwnx_hw, -+ struct rwnx_sta *sta, -+ bool available, -+ u8 ps_id); -+void rwnx_ps_bh_enable(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, -+ bool enable); -+void rwnx_ps_bh_traffic_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, -+ u16 pkt_req, u8 ps_id); -+ -+void rwnx_switch_vif_sta_txq(struct rwnx_sta *sta, struct rwnx_vif *old_vif, -+ struct rwnx_vif *new_vif); -+ -+int rwnx_dbgfs_print_sta(char *buf, size_t size, struct rwnx_sta *sta, -+ struct rwnx_hw *rwnx_hw); -+void rwnx_txq_credit_update(struct rwnx_hw *rwnx_hw, int sta_idx, u8 tid, -+ s8 update); -+void rwnx_tx_push(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr, int flags); -+ -+#endif /* _RWNX_TX_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_txq.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_txq.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_txq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_txq.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,1370 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_txq.c -+ * -+ * Copyright (C) RivieraWaves 2016-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#include "rwnx_defs.h" -+#include "rwnx_tx.h" -+#include "ipc_host.h" -+#include "rwnx_events.h" -+ -+/****************************************************************************** -+ * Utils functions -+ *****************************************************************************/ -+#ifdef CONFIG_RWNX_FULLMAC -+const int nx_tid_prio[NX_NB_TID_PER_STA] = {7, 6, 5, 4, 3, 0, 2, 1}; -+ -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+extern int tx_fc_low_water; -+extern int tx_fc_high_water; -+#endif -+ -+static inline int rwnx_txq_sta_idx(struct rwnx_sta *sta, u8 tid) -+{ -+ if (is_multicast_sta(sta->sta_idx)){ -+ if((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) || -+ ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ -+ return NX_FIRST_VIF_TXQ_IDX_FOR_OLD_IC + sta->vif_idx; -+ }else{ -+ return NX_FIRST_VIF_TXQ_IDX + sta->vif_idx; -+ } -+ }else{ -+ return (sta->sta_idx * NX_NB_TXQ_PER_STA) + tid; -+ } -+} -+ -+static inline int rwnx_txq_vif_idx(struct rwnx_vif *vif, u8 type) -+{ -+ -+ if((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) || -+ ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ -+ return NX_FIRST_VIF_TXQ_IDX_FOR_OLD_IC + master_vif_idx(vif) + (type * NX_VIRT_DEV_MAX); -+ }else{ -+ return NX_FIRST_VIF_TXQ_IDX + master_vif_idx(vif) + (type * NX_VIRT_DEV_MAX); -+ } -+ -+} -+ -+struct rwnx_txq *rwnx_txq_sta_get(struct rwnx_sta *sta, u8 tid, -+ struct rwnx_hw *rwnx_hw) -+{ -+ if (tid >= NX_NB_TXQ_PER_STA) -+ tid = 0; -+ -+ return &rwnx_hw->txq[rwnx_txq_sta_idx(sta, tid)]; -+} -+ -+struct rwnx_txq *rwnx_txq_vif_get(struct rwnx_vif *vif, u8 type) -+{ -+ if (type > NX_UNK_TXQ_TYPE) -+ type = NX_BCMC_TXQ_TYPE; -+ -+ return &vif->rwnx_hw->txq[rwnx_txq_vif_idx(vif, type)]; -+} -+ -+static inline struct rwnx_sta *rwnx_txq_2_sta(struct rwnx_txq *txq) -+{ -+ return txq->sta; -+} -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ -+/****************************************************************************** -+ * Init/Deinit functions -+ *****************************************************************************/ -+/** -+ * rwnx_txq_init - Initialize a TX queue -+ * -+ * @txq: TX queue to be initialized -+ * @idx: TX queue index -+ * @status: TX queue initial status -+ * @hwq: Associated HW queue -+ * @ndev: Net device this queue belongs to -+ * (may be null for non netdev txq) -+ * -+ * Each queue is initialized with the credit of @NX_TXQ_INITIAL_CREDITS. -+ */ -+static void rwnx_txq_init(struct rwnx_txq *txq, int idx, u8 status, -+ struct rwnx_hwq *hwq, int tid, -+#ifdef CONFIG_RWNX_FULLMAC -+ struct rwnx_sta *sta, struct net_device *ndev -+#endif -+ ) -+{ -+ int i; -+ int nx_first_unk_txq_idx = NX_FIRST_UNK_TXQ_IDX; -+ int nx_bcmc_txq_ndev_idx = NX_BCMC_TXQ_NDEV_IDX; -+ int nx_first_vif_txq_idx = NX_FIRST_VIF_TXQ_IDX; -+ -+ if((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) || -+ ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ -+ nx_first_unk_txq_idx = NX_FIRST_UNK_TXQ_IDX_FOR_OLD_IC; -+ nx_bcmc_txq_ndev_idx = NX_BCMC_TXQ_NDEV_IDX_FOR_OLD_IC; -+ nx_first_vif_txq_idx = NX_FIRST_VIF_TXQ_IDX_FOR_OLD_IC; -+ } -+ -+ -+ -+ txq->idx = idx; -+ txq->status = status; -+ txq->credits = NX_TXQ_INITIAL_CREDITS; -+ txq->pkt_sent = 0; -+ skb_queue_head_init(&txq->sk_list); -+ txq->last_retry_skb = NULL; -+ txq->nb_retry = 0; -+ txq->hwq = hwq; -+ txq->sta = sta; -+ for (i = 0; i < CONFIG_USER_MAX ; i++) -+ txq->pkt_pushed[i] = 0; -+ txq->push_limit = 0; -+ txq->tid = tid; -+#ifdef CONFIG_MAC80211_TXQ -+ txq->nb_ready_mac80211 = 0; -+#endif -+#ifdef CONFIG_RWNX_FULLMAC -+ txq->ps_id = LEGACY_PS_ID; -+ if (idx < nx_first_vif_txq_idx) { -+ int sta_idx = sta->sta_idx; -+ int tid = idx - (sta_idx * NX_NB_TXQ_PER_STA); -+ if (tid < NX_NB_TID_PER_STA) -+ txq->ndev_idx = NX_STA_NDEV_IDX(tid, sta_idx); -+ else -+ txq->ndev_idx = NDEV_NO_TXQ; -+ } else if (idx < nx_first_unk_txq_idx) { -+ txq->ndev_idx = nx_bcmc_txq_ndev_idx; -+ } else { -+ txq->ndev_idx = NDEV_NO_TXQ; -+ } -+ txq->ndev = ndev; -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ txq->amsdu = NULL; -+ txq->amsdu_len = 0; -+#endif /* CONFIG_RWNX_AMSDUS_TX */ -+#endif /* CONFIG_RWNX_FULLMAC */ -+} -+ -+/** -+ * rwnx_txq_flush - Flush all buffers queued for a TXQ -+ * -+ * @rwnx_hw: main driver data -+ * @txq: txq to flush -+ */ -+void rwnx_txq_flush(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq) -+{ -+ struct sk_buff *skb; -+ -+ -+ while ((skb = skb_dequeue(&txq->sk_list)) != NULL) { -+ struct rwnx_sw_txhdr *sw_txhdr = ((struct rwnx_txhdr *)skb->data)->sw_hdr; -+ -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ if (sw_txhdr->desc.host.packet_cnt > 1) { -+ struct rwnx_amsdu_txhdr *amsdu_txhdr; -+ list_for_each_entry(amsdu_txhdr, &sw_txhdr->amsdu.hdrs, list) { -+ //dma_unmap_single(rwnx_hw->dev, amsdu_txhdr->dma_addr, -+ // amsdu_txhdr->map_len, DMA_TO_DEVICE); -+ dev_kfree_skb_any(amsdu_txhdr->skb); -+ } -+ } -+#endif -+ kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr); -+ //dma_unmap_single(rwnx_hw->dev, sw_txhdr->dma_addr, sw_txhdr->map_len, -+ // DMA_TO_DEVICE); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ dev_kfree_skb_any(skb); -+#endif /* CONFIG_RWNX_FULLMAC */ -+ } -+} -+ -+/** -+ * rwnx_txq_deinit - De-initialize a TX queue -+ * -+ * @rwnx_hw: Driver main data -+ * @txq: TX queue to be de-initialized -+ * Any buffer stuck in a queue will be freed. -+ */ -+static void rwnx_txq_deinit(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq) -+{ -+ if (txq->idx == TXQ_INACTIVE) -+ return; -+ -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ rwnx_txq_del_from_hw_list(txq); -+ txq->idx = TXQ_INACTIVE; -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+ -+ rwnx_txq_flush(rwnx_hw, txq); -+} -+ -+/** -+ * rwnx_txq_vif_init - Initialize all TXQ linked to a vif -+ * -+ * @rwnx_hw: main driver data -+ * @rwnx_vif: Pointer on VIF -+ * @status: Intial txq status -+ * -+ * Softmac : 1 VIF TXQ per HWQ -+ * -+ * Fullmac : 1 VIF TXQ for BC/MC -+ * 1 VIF TXQ for MGMT to unknown STA -+ */ -+void rwnx_txq_vif_init(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ u8 status) -+{ -+ struct rwnx_txq *txq; -+ int idx; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_BCMC_TXQ_TYPE); -+ idx = rwnx_txq_vif_idx(rwnx_vif, NX_BCMC_TXQ_TYPE); -+ rwnx_txq_init(txq, idx, status, &rwnx_hw->hwq[RWNX_HWQ_BE], 0, -+ &rwnx_hw->sta_table[rwnx_vif->ap.bcmc_index], rwnx_vif->ndev); -+ -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_UNK_TXQ_TYPE); -+ idx = rwnx_txq_vif_idx(rwnx_vif, NX_UNK_TXQ_TYPE); -+ rwnx_txq_init(txq, idx, status, &rwnx_hw->hwq[RWNX_HWQ_VO], TID_MGT, -+ NULL, rwnx_vif->ndev); -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+} -+ -+/** -+ * rwnx_txq_vif_deinit - Deinitialize all TXQ linked to a vif -+ * -+ * @rwnx_hw: main driver data -+ * @rwnx_vif: Pointer on VIF -+ */ -+void rwnx_txq_vif_deinit(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif) -+{ -+ struct rwnx_txq *txq; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_BCMC_TXQ_TYPE); -+ rwnx_txq_deinit(rwnx_hw, txq); -+ -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_UNK_TXQ_TYPE); -+ rwnx_txq_deinit(rwnx_hw, txq); -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+} -+ -+ -+/** -+ * rwnx_txq_sta_init - Initialize TX queues for a STA -+ * -+ * @rwnx_hw: Main driver data -+ * @rwnx_sta: STA for which tx queues need to be initialized -+ * @status: Intial txq status -+ * -+ * This function initialize all the TXQ associated to a STA. -+ * Softmac : 1 TXQ per TID -+ * -+ * Fullmac : 1 TXQ per TID (limited to 8) -+ * 1 TXQ for MGMT -+ */ -+void rwnx_txq_sta_init(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta, -+ u8 status) -+{ -+ struct rwnx_txq *txq; -+ int tid, idx; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[rwnx_sta->vif_idx]; -+ idx = rwnx_txq_sta_idx(rwnx_sta, 0); -+ -+ foreach_sta_txq(rwnx_sta, txq, tid, rwnx_hw) { -+ rwnx_txq_init(txq, idx, status, &rwnx_hw->hwq[rwnx_tid2hwq[tid]], tid, -+ rwnx_sta, rwnx_vif->ndev); -+ txq->ps_id = rwnx_sta->uapsd_tids & (1 << tid) ? UAPSD_ID : LEGACY_PS_ID; -+ idx++; -+ } -+ -+#endif /* CONFIG_RWNX_FULLMAC*/ -+} -+ -+/** -+ * rwnx_txq_sta_deinit - Deinitialize TX queues for a STA -+ * -+ * @rwnx_hw: Main driver data -+ * @rwnx_sta: STA for which tx queues need to be deinitialized -+ */ -+void rwnx_txq_sta_deinit(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta) -+{ -+ struct rwnx_txq *txq; -+ int tid; -+ -+ foreach_sta_txq(rwnx_sta, txq, tid, rwnx_hw) { -+ rwnx_txq_deinit(rwnx_hw, txq); -+ } -+} -+ -+#ifdef CONFIG_RWNX_FULLMAC -+/** -+ * rwnx_txq_unk_vif_init - Initialize TXQ for unknown STA linked to a vif -+ * -+ * @rwnx_vif: Pointer on VIF -+ */ -+void rwnx_txq_unk_vif_init(struct rwnx_vif *rwnx_vif) -+{ -+ struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; -+ struct rwnx_txq *txq; -+ int idx; -+ -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_UNK_TXQ_TYPE); -+ idx = rwnx_txq_vif_idx(rwnx_vif, NX_UNK_TXQ_TYPE); -+ rwnx_txq_init(txq, idx, 0, &rwnx_hw->hwq[RWNX_HWQ_VO], TID_MGT, NULL, rwnx_vif->ndev); -+} -+ -+/** -+ * rwnx_txq_tdls_vif_deinit - Deinitialize TXQ for unknown STA linked to a vif -+ * -+ * @rwnx_vif: Pointer on VIF -+ */ -+void rwnx_txq_unk_vif_deinit(struct rwnx_vif *rwnx_vif) -+{ -+ struct rwnx_txq *txq; -+ -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_UNK_TXQ_TYPE); -+ rwnx_txq_deinit(rwnx_vif->rwnx_hw, txq); -+} -+ -+/** -+ * rwnx_init_unk_txq - Initialize TX queue for the transmission on a offchannel -+ * -+ * @vif: Interface for which the queue has to be initialized -+ * -+ * NOTE: Offchannel txq is only active for the duration of the ROC -+ */ -+void rwnx_txq_offchan_init(struct rwnx_vif *rwnx_vif) -+{ -+ struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; -+ struct rwnx_txq *txq; -+ int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX; -+ -+ if((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) || -+ ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ -+ nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC; -+ } -+ -+ txq = &rwnx_hw->txq[nx_off_chan_txq_idx]; -+ rwnx_txq_init(txq, nx_off_chan_txq_idx, RWNX_TXQ_STOP_CHAN, -+ &rwnx_hw->hwq[RWNX_HWQ_VO], TID_MGT, NULL, rwnx_vif->ndev); -+} -+ -+/** -+ * rwnx_deinit_offchan_txq - Deinitialize TX queue for offchannel -+ * -+ * @vif: Interface that manages the STA -+ * -+ * This function deintialize txq for one STA. -+ * Any buffer stuck in a queue will be freed. -+ */ -+void rwnx_txq_offchan_deinit(struct rwnx_vif *rwnx_vif) -+{ -+ struct rwnx_txq *txq; -+ -+ int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX; -+ -+ if((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) || -+ ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ -+ nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC; -+ } -+ -+ txq = &rwnx_vif->rwnx_hw->txq[nx_off_chan_txq_idx]; -+ rwnx_txq_deinit(rwnx_vif->rwnx_hw, txq); -+} -+ -+ -+/** -+ * rwnx_txq_tdls_vif_init - Initialize TXQ vif for TDLS -+ * -+ * @rwnx_vif: Pointer on VIF -+ */ -+void rwnx_txq_tdls_vif_init(struct rwnx_vif *rwnx_vif) -+{ -+ struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; -+ -+ if (!(rwnx_hw->wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) -+ return; -+ -+ rwnx_txq_unk_vif_init(rwnx_vif); -+} -+ -+/** -+ * rwnx_txq_tdls_vif_deinit - Deinitialize TXQ vif for TDLS -+ * -+ * @rwnx_vif: Pointer on VIF -+ */ -+void rwnx_txq_tdls_vif_deinit(struct rwnx_vif *rwnx_vif) -+{ -+ struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; -+ -+ if (!(rwnx_hw->wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) -+ return; -+ -+ rwnx_txq_unk_vif_deinit(rwnx_vif); -+} -+#endif -+ -+/****************************************************************************** -+ * Start/Stop functions -+ *****************************************************************************/ -+/** -+ * rwnx_txq_add_to_hw_list - Add TX queue to a HW queue schedule list. -+ * -+ * @txq: TX queue to add -+ * -+ * Add the TX queue if not already present in the HW queue list. -+ * To be called with tx_lock hold -+ */ -+void rwnx_txq_add_to_hw_list(struct rwnx_txq *txq) -+{ -+ if (!(txq->status & RWNX_TXQ_IN_HWQ_LIST)) { -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_add_to_hw(txq); -+#endif -+ txq->status |= RWNX_TXQ_IN_HWQ_LIST; -+ list_add_tail(&txq->sched_list, &txq->hwq->list); -+ txq->hwq->need_processing = true; -+ } -+} -+ -+/** -+ * rwnx_txq_del_from_hw_list - Delete TX queue from a HW queue schedule list. -+ * -+ * @txq: TX queue to delete -+ * -+ * Remove the TX queue from the HW queue list if present. -+ * To be called with tx_lock hold -+ */ -+void rwnx_txq_del_from_hw_list(struct rwnx_txq *txq) -+{ -+ if (txq->status & RWNX_TXQ_IN_HWQ_LIST) { -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_del_from_hw(txq); -+#endif -+ txq->status &= ~RWNX_TXQ_IN_HWQ_LIST; -+ list_del(&txq->sched_list); -+ } -+} -+ -+/** -+ * rwnx_txq_skb_ready - Check if skb are available for the txq -+ * -+ * @txq: Pointer on txq -+ * @return True if there are buffer ready to be pushed on this txq, -+ * false otherwise -+ */ -+static inline bool rwnx_txq_skb_ready(struct rwnx_txq *txq) -+{ -+#ifdef CONFIG_MAC80211_TXQ -+ if (txq->nb_ready_mac80211 != NOT_MAC80211_TXQ) -+ return ((txq->nb_ready_mac80211 > 0) || !skb_queue_empty(&txq->sk_list)); -+ else -+#endif -+ return !skb_queue_empty(&txq->sk_list); -+} -+ -+/** -+ * rwnx_txq_start - Try to Start one TX queue -+ * -+ * @txq: TX queue to start -+ * @reason: reason why the TX queue is started (among RWNX_TXQ_STOP_xxx) -+ * -+ * Re-start the TX queue for one reason. -+ * If after this the txq is no longer stopped and some buffers are ready, -+ * the TX queue is also added to HW queue list. -+ * To be called with tx_lock hold -+ */ -+void rwnx_txq_start(struct rwnx_txq *txq, u16 reason) -+{ -+ BUG_ON(txq == NULL); -+ if (txq->idx != TXQ_INACTIVE && (txq->status & reason)) { -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_start(txq, reason); -+#endif -+ txq->status &= ~reason; -+ if (!rwnx_txq_is_stopped(txq) && rwnx_txq_skb_ready(txq)) -+ rwnx_txq_add_to_hw_list(txq); -+ } -+} -+ -+/** -+ * rwnx_txq_stop - Stop one TX queue -+ * -+ * @txq: TX queue to stop -+ * @reason: reason why the TX queue is stopped (among RWNX_TXQ_STOP_xxx) -+ * -+ * Stop the TX queue. It will remove the TX queue from HW queue list -+ * To be called with tx_lock hold -+ */ -+void rwnx_txq_stop(struct rwnx_txq *txq, u16 reason) -+{ -+ BUG_ON(txq == NULL); -+ if (txq->idx != TXQ_INACTIVE) { -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_stop(txq, reason); -+#endif -+ txq->status |= reason; -+ rwnx_txq_del_from_hw_list(txq); -+ } -+} -+ -+ -+/** -+ * rwnx_txq_sta_start - Start all the TX queue linked to a STA -+ * -+ * @sta: STA whose TX queues must be re-started -+ * @reason: Reason why the TX queue are restarted (among RWNX_TXQ_STOP_xxx) -+ * @rwnx_hw: Driver main data -+ * -+ * This function will re-start all the TX queues of the STA for the reason -+ * specified. It can be : -+ * - RWNX_TXQ_STOP_STA_PS: the STA is no longer in power save mode -+ * - RWNX_TXQ_STOP_VIF_PS: the VIF is in power save mode (p2p absence) -+ * - RWNX_TXQ_STOP_CHAN: the STA's VIF is now on the current active channel -+ * -+ * Any TX queue with buffer ready and not Stopped for other reasons, will be -+ * added to the HW queue list -+ * To be called with tx_lock hold -+ */ -+void rwnx_txq_sta_start(struct rwnx_sta *rwnx_sta, u16 reason -+#ifdef CONFIG_RWNX_FULLMAC -+ , struct rwnx_hw *rwnx_hw -+#endif -+ ) -+{ -+ struct rwnx_txq *txq; -+ int tid; -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_sta_start(rwnx_sta->sta_idx); -+#endif -+ foreach_sta_txq(rwnx_sta, txq, tid, rwnx_hw) { -+ rwnx_txq_start(txq, reason); -+ } -+} -+ -+ -+/** -+ * rwnx_stop_sta_txq - Stop all the TX queue linked to a STA -+ * -+ * @sta: STA whose TX queues must be stopped -+ * @reason: Reason why the TX queue are stopped (among RWNX_TX_STOP_xxx) -+ * @rwnx_hw: Driver main data -+ * -+ * This function will stop all the TX queues of the STA for the reason -+ * specified. It can be : -+ * - RWNX_TXQ_STOP_STA_PS: the STA is in power save mode -+ * - RWNX_TXQ_STOP_VIF_PS: the VIF is in power save mode (p2p absence) -+ * - RWNX_TXQ_STOP_CHAN: the STA's VIF is not on the current active channel -+ * -+ * Any TX queue present in a HW queue list will be removed from this list. -+ * To be called with tx_lock hold -+ */ -+void rwnx_txq_sta_stop(struct rwnx_sta *rwnx_sta, u16 reason -+#ifdef CONFIG_RWNX_FULLMAC -+ , struct rwnx_hw *rwnx_hw -+#endif -+ ) -+{ -+ struct rwnx_txq *txq; -+ int tid; -+ -+ if (!rwnx_sta) -+ return; -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_sta_stop(rwnx_sta->sta_idx); -+#endif -+ foreach_sta_txq(rwnx_sta, txq, tid, rwnx_hw) { -+ rwnx_txq_stop(txq, reason); -+ } -+} -+ -+#ifdef CONFIG_RWNX_FULLMAC -+void rwnx_txq_tdls_sta_start(struct rwnx_vif *rwnx_vif, u16 reason, -+ struct rwnx_hw *rwnx_hw) -+{ -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_vif_start(rwnx_vif->vif_index); -+#endif -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ -+ if (rwnx_vif->sta.tdls_sta) -+ rwnx_txq_sta_start(rwnx_vif->sta.tdls_sta, reason, rwnx_hw); -+ -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+} -+#endif -+ -+#ifdef CONFIG_RWNX_FULLMAC -+void rwnx_txq_tdls_sta_stop(struct rwnx_vif *rwnx_vif, u16 reason, -+ struct rwnx_hw *rwnx_hw) -+{ -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_vif_stop(rwnx_vif->vif_index); -+#endif -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ -+ if (rwnx_vif->sta.tdls_sta) -+ rwnx_txq_sta_stop(rwnx_vif->sta.tdls_sta, reason, rwnx_hw); -+ -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+} -+#endif -+ -+#ifdef CONFIG_RWNX_FULLMAC -+static inline void rwnx_txq_vif_for_each_sta(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, -+ void (*f)(struct rwnx_sta *, u16, struct rwnx_hw *), u16 reason) { -+ -+ switch (RWNX_VIF_TYPE(rwnx_vif)) { -+ case NL80211_IFTYPE_STATION: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ { -+ if (rwnx_vif->tdls_status == TDLS_LINK_ACTIVE) -+ f(rwnx_vif->sta.tdls_sta, reason, rwnx_hw); -+ if (!WARN_ON(rwnx_vif->sta.ap == NULL)) -+ f(rwnx_vif->sta.ap, reason, rwnx_hw); -+ break; -+ } -+ case NL80211_IFTYPE_AP_VLAN: -+ rwnx_vif = rwnx_vif->ap_vlan.master; -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_MESH_POINT: -+ case NL80211_IFTYPE_P2P_GO: -+ { -+ struct rwnx_sta *sta; -+ list_for_each_entry(sta, &rwnx_vif->ap.sta_list, list) { -+ f(sta, reason, rwnx_hw); -+ } -+ break; -+ } -+ default: -+ BUG(); -+ break; -+ } -+} -+#endif -+ -+/** -+ * rwnx_txq_vif_start - START TX queues of all STA associated to the vif -+ * and vif's TXQ -+ * -+ * @vif: Interface to start -+ * @reason: Start reason (RWNX_TXQ_STOP_CHAN or RWNX_TXQ_STOP_VIF_PS) -+ * @rwnx_hw: Driver main data -+ * -+ * Iterate over all the STA associated to the vif and re-start them for the -+ * reason @reason -+ * Take tx_lock -+ */ -+void rwnx_txq_vif_start(struct rwnx_vif *rwnx_vif, u16 reason, -+ struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_txq *txq; -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_vif_start(rwnx_vif->vif_index); -+#endif -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ //Reject if monitor interface -+ if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_MONITOR) -+ goto end; -+ -+ if (rwnx_vif->roc_tdls && rwnx_vif->sta.tdls_sta && rwnx_vif->sta.tdls_sta->tdls.chsw_en) { -+ rwnx_txq_sta_start(rwnx_vif->sta.tdls_sta, reason, rwnx_hw); -+ } -+ if (!rwnx_vif->roc_tdls) { -+ rwnx_txq_vif_for_each_sta(rwnx_hw, rwnx_vif, rwnx_txq_sta_start, reason); -+ } -+ -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_BCMC_TXQ_TYPE); -+ rwnx_txq_start(txq, reason); -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_UNK_TXQ_TYPE); -+ rwnx_txq_start(txq, reason); -+ -+end: -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+} -+ -+ -+/** -+ * rwnx_txq_vif_stop - STOP TX queues of all STA associated to the vif -+ * -+ * @vif: Interface to stop -+ * @arg: Stop reason (RWNX_TXQ_STOP_CHAN or RWNX_TXQ_STOP_VIF_PS) -+ * @rwnx_hw: Driver main data -+ * -+ * Iterate over all the STA associated to the vif and stop them for the -+ * reason RWNX_TXQ_STOP_CHAN or RWNX_TXQ_STOP_VIF_PS -+ * Take tx_lock -+ */ -+void rwnx_txq_vif_stop(struct rwnx_vif *rwnx_vif, u16 reason, -+ struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_txq *txq; -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_vif_stop(rwnx_vif->vif_index); -+#endif -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ //Reject if monitor interface -+ if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_MONITOR) -+ goto end; -+ -+ rwnx_txq_vif_for_each_sta(rwnx_hw, rwnx_vif, rwnx_txq_sta_stop, reason); -+ -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_BCMC_TXQ_TYPE); -+ rwnx_txq_stop(txq, reason); -+ txq = rwnx_txq_vif_get(rwnx_vif, NX_UNK_TXQ_TYPE); -+ rwnx_txq_stop(txq, reason); -+ -+end: -+#endif /* CONFIG_RWNX_FULLMAC*/ -+ -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+} -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+/** -+ * rwnx_start_offchan_txq - START TX queue for offchannel frame -+ * -+ * @rwnx_hw: Driver main data -+ */ -+void rwnx_txq_offchan_start(struct rwnx_hw *rwnx_hw) -+{ -+ struct rwnx_txq *txq; -+ int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX; -+ -+ if((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8801) || -+ ((g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DC || -+ g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ -+ nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC; -+ } -+ -+ -+ txq = &rwnx_hw->txq[nx_off_chan_txq_idx]; -+ spin_lock_bh(&rwnx_hw->tx_lock); -+ rwnx_txq_start(txq, RWNX_TXQ_STOP_CHAN); -+ spin_unlock_bh(&rwnx_hw->tx_lock); -+} -+ -+/** -+ * rwnx_switch_vif_sta_txq - Associate TXQ linked to a STA to a new vif -+ * -+ * @sta: STA whose txq must be switched -+ * @old_vif: Vif currently associated to the STA (may no longer be active) -+ * @new_vif: vif which should be associated to the STA for now on -+ * -+ * This function will switch the vif (i.e. the netdev) associated to all STA's -+ * TXQ. This is used when AP_VLAN interface are created. -+ * If one STA is associated to an AP_vlan vif, it will be moved from the master -+ * AP vif to the AP_vlan vif. -+ * If an AP_vlan vif is removed, then STA will be moved back to mastert AP vif. -+ * -+ */ -+void rwnx_txq_sta_switch_vif(struct rwnx_sta *sta, struct rwnx_vif *old_vif, -+ struct rwnx_vif *new_vif) -+{ -+ struct rwnx_hw *rwnx_hw = new_vif->rwnx_hw; -+ struct rwnx_txq *txq; -+ int i; -+ -+ /* start TXQ on the new interface, and update ndev field in txq */ -+ if (!netif_carrier_ok(new_vif->ndev)) -+ netif_carrier_on(new_vif->ndev); -+ txq = rwnx_txq_sta_get(sta, 0, rwnx_hw); -+ for (i = 0; i < NX_NB_TID_PER_STA; i++, txq++) { -+ txq->ndev = new_vif->ndev; -+ netif_wake_subqueue(txq->ndev, txq->ndev_idx); -+ } -+} -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+/****************************************************************************** -+ * TXQ queue/schedule functions -+ *****************************************************************************/ -+/** -+ * rwnx_txq_queue_skb - Queue a buffer in a TX queue -+ * -+ * @skb: Buffer to queue -+ * @txq: TX Queue in which the buffer must be added -+ * @rwnx_hw: Driver main data -+ * @retry: Should it be queued in the retry list -+ * -+ * @return: Retrun 1 if txq has been added to hwq list, 0 otherwise -+ * -+ * Add a buffer in the buffer list of the TX queue -+ * and add this TX queue in the HW queue list if the txq is not stopped. -+ * If this is a retry packet it is added after the last retry packet or at the -+ * beginning if there is no retry packet queued. -+ * -+ * If the STA is in PS mode and this is the first packet queued for this txq -+ * update TIM. -+ * -+ * To be called with tx_lock hold -+ */ -+int rwnx_txq_queue_skb(struct sk_buff *skb, struct rwnx_txq *txq, -+ struct rwnx_hw *rwnx_hw, bool retry) -+{ -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ if (unlikely(txq->sta && txq->sta->ps.active)) { -+ txq->sta->ps.pkt_ready[txq->ps_id]++; -+#ifdef CREATE_TRACE_POINTS -+ trace_ps_queue(txq->sta); -+#endif -+ if (txq->sta->ps.pkt_ready[txq->ps_id] == 1) { -+ rwnx_set_traffic_status(rwnx_hw, txq->sta, true, txq->ps_id); -+ } -+ } -+#endif -+ -+ if (!retry) { -+ /* add buffer in the sk_list */ -+ skb_queue_tail(&txq->sk_list, skb); -+ } else { -+ if (txq->last_retry_skb) -+#ifdef CONFIG_GKI -+ rwnx_skb_append(txq->last_retry_skb, skb, &txq->sk_list); -+#else -+ skb_append(txq->last_retry_skb, skb, &txq->sk_list); -+#endif -+ else -+ skb_queue_head(&txq->sk_list, skb); -+ -+ txq->last_retry_skb = skb; -+ txq->nb_retry++; -+ } -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_queue_skb(skb, txq, retry); -+#endif -+ /* Flowctrl corresponding netdev queue if needed */ -+#ifdef CONFIG_RWNX_FULLMAC -+#ifndef CONFIG_ONE_TXQ -+ -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+ if ((txq->ndev_idx != NDEV_NO_TXQ) && ((skb_queue_len(&txq->sk_list) > RWNX_NDEV_FLOW_CTRL_STOP) && -+ !rwnx_hw->sdiodev->flowctrl)) { -+// (atomic_read(&rwnx_hw->sdiodev->tx_priv->tx_pktcnt) >= tx_fc_high_water))) { -+#else -+ /* If too many buffer are queued for this TXQ stop netdev queue */ -+ if ((txq->ndev_idx != NDEV_NO_TXQ) && -+ (skb_queue_len(&txq->sk_list) > RWNX_NDEV_FLOW_CTRL_STOP)) { -+#endif -+ -+ txq->status |= RWNX_TXQ_NDEV_FLOW_CTRL; -+ netif_stop_subqueue(txq->ndev, txq->ndev_idx); -+#ifdef CREATE_TRACE_POINT -+ trace_txq_flowctrl_stop(txq); -+#endif -+ } -+#endif /* CONFIG_ONE_TXQ */ -+#else /* ! CONFIG_RWNX_FULLMAC */ -+ -+ if (!retry && ++txq->hwq->len == txq->hwq->len_stop) { -+ trace_hwq_flowctrl_stop(txq->hwq->id); -+ ieee80211_stop_queue(rwnx_hw->hw, txq->hwq->id); -+ rwnx_hw->stats.queues_stops++; -+ } -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+ /* add it in the hwq list if not stopped and not yet present */ -+ if (!rwnx_txq_is_stopped(txq)) { -+ rwnx_txq_add_to_hw_list(txq); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/** -+ * rwnx_txq_confirm_any - Process buffer confirmed by fw -+ * -+ * @rwnx_hw: Driver main data -+ * @txq: TX Queue -+ * @hwq: HW Queue -+ * @sw_txhdr: software descriptor of the confirmed packet -+ * -+ * Process a buffer returned by the fw. It doesn't check buffer status -+ * and only does systematic counter update: -+ * - hw credit -+ * - buffer pushed to fw -+ * -+ * To be called with tx_lock hold -+ */ -+void rwnx_txq_confirm_any(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq, -+ struct rwnx_hwq *hwq, struct rwnx_sw_txhdr *sw_txhdr) -+{ -+ int user = 0; -+ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ int group_id; -+ -+ user = RWNX_MUMIMO_INFO_POS_ID(sw_txhdr->desc.host.mumimo_info); -+ group_id = RWNX_MUMIMO_INFO_GROUP_ID(sw_txhdr->desc.host.mumimo_info); -+ -+ if ((txq->idx != TXQ_INACTIVE) && -+ (txq->pkt_pushed[user] == 1) && -+ (txq->status & RWNX_TXQ_STOP_MU_POS)) -+ rwnx_txq_start(txq, RWNX_TXQ_STOP_MU_POS); -+ -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+ -+ if (txq->pkt_pushed[user]) -+ txq->pkt_pushed[user]--; -+ -+ hwq->need_processing = true; -+ rwnx_hw->stats.cfm_balance[hwq->id]--; -+} -+ -+/****************************************************************************** -+ * HWQ processing -+ *****************************************************************************/ -+static inline -+bool rwnx_txq_take_mu_lock(struct rwnx_hw *rwnx_hw) -+{ -+ bool res = false; -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ if (rwnx_hw->mod_params->mutx) -+ res = (down_trylock(&rwnx_hw->mu.lock) == 0); -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+ return res; -+} -+ -+static inline -+void rwnx_txq_release_mu_lock(struct rwnx_hw *rwnx_hw) -+{ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ up(&rwnx_hw->mu.lock); -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+} -+ -+static inline -+void rwnx_txq_set_mu_info(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq, -+ int group_id, int pos) -+{ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ trace_txq_select_mu_group(txq, group_id, pos); -+ if (group_id) { -+ txq->mumimo_info = group_id | (pos << 6); -+ rwnx_mu_set_active_group(rwnx_hw, group_id); -+ } else -+ txq->mumimo_info = 0; -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+} -+ -+static inline -+s8 rwnx_txq_get_credits(struct rwnx_txq *txq) -+{ -+ s8 cred = txq->credits; -+ /* if destination is in PS mode, push_limit indicates the maximum -+ number of packet that can be pushed on this txq. */ -+ if (txq->push_limit && (cred > txq->push_limit)) { -+ cred = txq->push_limit; -+ } -+ return cred; -+} -+ -+/** -+ * skb_queue_extract - Extract buffer from skb list -+ * -+ * @list: List of skb to extract from -+ * @head: List of skb to append to -+ * @nb_elt: Number of skb to extract -+ * -+ * extract the first @nb_elt of @list and append them to @head -+ * It is assume that: -+ * - @list contains more that @nb_elt -+ * - There is no need to take @list nor @head lock to modify them -+ */ -+static inline void skb_queue_extract(struct sk_buff_head *list, -+ struct sk_buff_head *head, int nb_elt) -+{ -+ int i; -+ struct sk_buff *first, *last, *ptr; -+ -+ first = ptr = list->next; -+ for (i = 0; i < nb_elt; i++) { -+ ptr = ptr->next; -+ } -+ last = ptr->prev; -+ -+ /* unlink nb_elt in list */ -+ list->qlen -= nb_elt; -+ list->next = ptr; -+ ptr->prev = (struct sk_buff *)list; -+ -+ /* append nb_elt at end of head */ -+ head->qlen += nb_elt; -+ last->next = (struct sk_buff *)head; -+ head->prev->next = first; -+ first->prev = head->prev; -+ head->prev = last; -+} -+ -+ -+#ifdef CONFIG_MAC80211_TXQ -+/** -+ * rwnx_txq_mac80211_dequeue - Dequeue buffer from mac80211 txq and -+ * add them to push list -+ * -+ * @rwnx_hw: Main driver data -+ * @sk_list: List of buffer to push (initialized without lock) -+ * @txq: TXQ to dequeue buffers from -+ * @max: Max number of buffer to dequeue -+ * -+ * Dequeue buffer from mac80211 txq, prepare them for transmission and chain them -+ * to the list of buffer to push. -+ * -+ * @return true if no more buffer are queued in mac80211 txq and false otherwise. -+ */ -+static bool rwnx_txq_mac80211_dequeue(struct rwnx_hw *rwnx_hw, -+ struct sk_buff_head *sk_list, -+ struct rwnx_txq *txq, int max) -+{ -+ struct ieee80211_txq *mac_txq; -+ struct sk_buff *skb; -+ unsigned long mac_txq_len; -+ -+ if (txq->nb_ready_mac80211 == NOT_MAC80211_TXQ) -+ return true; -+ -+ mac_txq = container_of((void *)txq, struct ieee80211_txq, drv_priv); -+ -+ for (; max > 0; max--) { -+ skb = rwnx_tx_dequeue_prep(rwnx_hw, mac_txq); -+ if (skb == NULL) -+ return true; -+ -+ __skb_queue_tail(sk_list, skb); -+ } -+ -+ /* re-read mac80211 txq current length. -+ It is mainly for debug purpose to trace dropped packet. There is no -+ problems to have nb_ready_mac80211 != actual mac80211 txq length */ -+ ieee80211_txq_get_depth(mac_txq, &mac_txq_len, NULL); -+ if (txq->nb_ready_mac80211 > mac_txq_len) -+ trace_txq_drop(txq, txq->nb_ready_mac80211 - mac_txq_len); -+ txq->nb_ready_mac80211 = mac_txq_len; -+ -+ return (txq->nb_ready_mac80211 == 0); -+} -+#endif -+ -+/** -+ * rwnx_txq_get_skb_to_push - Get list of buffer to push for one txq -+ * -+ * @rwnx_hw: main driver data -+ * @hwq: HWQ on wich buffers will be pushed -+ * @txq: TXQ to get buffers from -+ * @user: user postion to use -+ * @sk_list_push: list to update -+ * -+ * -+ * This function will returned a list of buffer to push for one txq. -+ * It will take into account the number of credit of the HWQ for this user -+ * position and TXQ (and push_limit). -+ * This allow to get a list that can be pushed without having to test for -+ * hwq/txq status after each push -+ * -+ * If a MU group has been selected for this txq, it will also update the -+ * counter for the group -+ * -+ * @return true if txq no longer have buffer ready after the ones returned. -+ * false otherwise -+ */ -+static -+bool rwnx_txq_get_skb_to_push(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq, -+ struct rwnx_txq *txq, int user, -+ struct sk_buff_head *sk_list_push) -+{ -+ int nb_ready = skb_queue_len(&txq->sk_list); -+ int credits = rwnx_txq_get_credits(txq); -+ bool res = false; -+ -+ __skb_queue_head_init(sk_list_push); -+ -+ if (credits >= nb_ready) { -+ skb_queue_splice_init(&txq->sk_list, sk_list_push); -+#ifdef CONFIG_MAC80211_TXQ -+ res = rwnx_txq_mac80211_dequeue(rwnx_hw, sk_list_push, txq, credits - nb_ready); -+ credits = skb_queue_len(sk_list_push); -+#else -+ res = true; -+ credits = nb_ready; -+#endif -+ } else { -+ skb_queue_extract(&txq->sk_list, sk_list_push, credits); -+ -+ /* When processing PS service period (i.e. push_limit != 0), no longer -+ process this txq if the buffers extracted will complete the SP for -+ this txq */ -+ if (txq->push_limit && (credits == txq->push_limit)) -+ res = true; -+ } -+ -+ rwnx_mu_set_active_sta(rwnx_hw, rwnx_txq_2_sta(txq), credits); -+ -+ return res; -+} -+ -+/** -+ * rwnx_txq_select_user - Select User queue for a txq -+ * -+ * @rwnx_hw: main driver data -+ * @mu_lock: true is MU lock is taken -+ * @txq: TXQ to select MU group for -+ * @hwq: HWQ for the TXQ -+ * @user: Updated with user position selected -+ * -+ * @return false if it is no possible to process this txq. -+ * true otherwise -+ * -+ * This function selects the MU group to use for a TXQ. -+ * The selection is done as follow: -+ * -+ * - return immediately for STA that don't belongs to any group and select -+ * group 0 / user 0 -+ * -+ * - If MU tx is disabled (by user mutx_on, or because mu group are being -+ * updated !mu_lock), select group 0 / user 0 -+ * -+ * - Use the best group selected by @rwnx_mu_group_sta_select. -+ * -+ * Each time a group is selected (except for the first case where sta -+ * doesn't belongs to a MU group), the function checks that no buffer is -+ * pending for this txq on another user position. If this is the case stop -+ * the txq (RWNX_TXQ_STOP_MU_POS) and return false. -+ * -+ */ -+static -+bool rwnx_txq_select_user(struct rwnx_hw *rwnx_hw, bool mu_lock, -+ struct rwnx_txq *txq, struct rwnx_hwq *hwq, int *user) -+{ -+ int pos = 0; -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ int id, group_id = 0; -+ struct rwnx_sta *sta = rwnx_txq_2_sta(txq); -+ -+ /* for sta that belong to no group return immediately */ -+ if (!sta || !sta->group_info.cnt) -+ goto end; -+ -+ /* If MU is disabled, need to check user */ -+ if (!rwnx_hw->mod_params->mutx_on || !mu_lock) -+ goto check_user; -+ -+ /* Use the "best" group selected */ -+ group_id = sta->group_info.group; -+ -+ if (group_id > 0) -+ pos = rwnx_mu_group_sta_get_pos(rwnx_hw, sta, group_id); -+ -+check_user: -+ /* check that we can push on this user position */ -+#if CONFIG_USER_MAX == 2 -+ id = (pos + 1) & 0x1; -+ if (txq->pkt_pushed[id]) { -+ rwnx_txq_stop(txq, RWNX_TXQ_STOP_MU_POS); -+ return false; -+ } -+ -+#else -+ for (id = 0 ; id < CONFIG_USER_MAX ; id++) { -+ if (id != pos && txq->pkt_pushed[id]) { -+ rwnx_txq_stop(txq, RWNX_TXQ_STOP_MU_POS); -+ return false; -+ } -+ } -+#endif -+ -+end: -+ rwnx_txq_set_mu_info(rwnx_hw, txq, group_id, pos); -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+ -+ *user = pos; -+ return true; -+} -+ -+ -+/** -+ * rwnx_hwq_process - Process one HW queue list -+ * -+ * @rwnx_hw: Driver main data -+ * @hw_queue: HW queue index to process -+ * -+ * The function will iterate over all the TX queues linked in this HW queue -+ * list. For each TX queue, push as many buffers as possible in the HW queue. -+ * (NB: TX queue have at least 1 buffer, otherwise it wouldn't be in the list) -+ * - If TX queue no longer have buffer, remove it from the list and check next -+ * TX queue -+ * - If TX queue no longer have credits or has a push_limit (PS mode) and it -+ * is reached , remove it from the list and check next TX queue -+ * - If HW queue is full, update list head to start with the next TX queue on -+ * next call if current TX queue already pushed "too many" pkt in a row, and -+ * return -+ * -+ * To be called when HW queue list is modified: -+ * - when a buffer is pushed on a TX queue -+ * - when new credits are received -+ * - when a STA returns from Power Save mode or receives traffic request. -+ * - when Channel context change -+ * -+ * To be called with tx_lock hold -+ */ -+#define ALL_HWQ_MASK ((1 << CONFIG_USER_MAX) - 1) -+ -+void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq) -+{ -+ struct rwnx_txq *txq, *next; -+ int user, credit_map = 0; -+ bool mu_enable; -+#ifdef CREATE_TRACE_POINTS -+ trace_process_hw_queue(hwq); -+#endif -+ hwq->need_processing = false; -+ -+ mu_enable = rwnx_txq_take_mu_lock(rwnx_hw); -+ if (!mu_enable) -+ credit_map = ALL_HWQ_MASK - 1; -+ -+ list_for_each_entry_safe(txq, next, &hwq->list, sched_list) { -+ struct rwnx_txhdr *txhdr = NULL; -+ struct sk_buff_head sk_list_push; -+ struct sk_buff *skb; -+ bool txq_empty; -+#ifdef CREATE_TRACE_POINTS -+ trace_process_txq(txq); -+#endif -+ /* sanity check for debug */ -+ BUG_ON(!(txq->status & RWNX_TXQ_IN_HWQ_LIST)); -+ if(txq->idx == TXQ_INACTIVE){ -+ printk("%s txq->idx == TXQ_INACTIVE \r\n", __func__); -+ rwnx_txq_del_from_hw_list(txq); -+ rwnx_txq_flush(rwnx_hw, txq); -+ continue; -+ } -+ BUG_ON(txq->idx == TXQ_INACTIVE); -+ BUG_ON(txq->credits <= 0); -+ BUG_ON(!rwnx_txq_skb_ready(txq)); -+ -+ if (!rwnx_txq_select_user(rwnx_hw, mu_enable, txq, hwq, &user)) { -+ printk("select user:%d\n", user); -+ continue; -+ } -+ -+ txq_empty = rwnx_txq_get_skb_to_push(rwnx_hw, hwq, txq, user, -+ &sk_list_push); -+ while ((skb = __skb_dequeue(&sk_list_push)) != NULL) { -+ txhdr = (struct rwnx_txhdr *)skb->data; -+ rwnx_tx_push(rwnx_hw, txhdr, 0); -+ } -+ -+ if (txq_empty) { -+ rwnx_txq_del_from_hw_list(txq); -+ txq->pkt_sent = 0; -+ } else if (rwnx_txq_is_scheduled(txq)) { -+ /* txq not empty, -+ - To avoid starving need to process other txq in the list -+ - For better aggregation, need to send "as many consecutive -+ pkt as possible" for he same txq -+ ==> Add counter to trigger txq switch -+ */ -+ if (txq->pkt_sent > hwq->size) { -+ txq->pkt_sent = 0; -+ list_rotate_left(&hwq->list); -+ } -+ } -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ /* Unable to complete PS traffic request because of hwq credit */ -+ if (txq->push_limit && txq->sta) { -+ if (txq->ps_id == LEGACY_PS_ID) { -+ /* for legacy PS abort SP and wait next ps-poll */ -+ txq->sta->ps.sp_cnt[txq->ps_id] -= txq->push_limit; -+ txq->push_limit = 0; -+ } -+ /* for u-apsd need to complete the SP to send EOSP frame */ -+ } -+#ifndef CONFIG_ONE_TXQ -+ /* restart netdev queue if number of queued buffer is below threshold */ -+#ifdef CONFIG_TX_NETIF_FLOWCTRL -+ if (unlikely(txq->status & RWNX_TXQ_NDEV_FLOW_CTRL) && -+ (skb_queue_len(&txq->sk_list) < RWNX_NDEV_FLOW_CTRL_RESTART)) { -+#else -+ if (unlikely(txq->status & RWNX_TXQ_NDEV_FLOW_CTRL) && -+ skb_queue_len(&txq->sk_list) < RWNX_NDEV_FLOW_CTRL_RESTART) { -+#endif -+ -+ txq->status &= ~RWNX_TXQ_NDEV_FLOW_CTRL; -+ netif_wake_subqueue(txq->ndev, txq->ndev_idx); -+#ifdef CREATE_TRACE_POINTS -+ trace_txq_flowctrl_restart(txq); -+#endif -+ } -+#endif /* CONFIG_ONE_TXQ */ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ } -+ -+ -+ if (mu_enable) -+ rwnx_txq_release_mu_lock(rwnx_hw); -+} -+ -+/** -+ * rwnx_hwq_process_all - Process all HW queue list -+ * -+ * @rwnx_hw: Driver main data -+ * -+ * Loop over all HWQ, and process them if needed -+ * To be called with tx_lock hold -+ */ -+void rwnx_hwq_process_all(struct rwnx_hw *rwnx_hw) -+{ -+ int id; -+ -+ rwnx_mu_group_sta_select(rwnx_hw); -+ -+ for (id = ARRAY_SIZE(rwnx_hw->hwq) - 1; id >= 0 ; id--) { -+ if (rwnx_hw->hwq[id].need_processing) { -+ rwnx_hwq_process(rwnx_hw, &rwnx_hw->hwq[id]); -+ } -+ } -+} -+ -+/** -+ * rwnx_hwq_init - Initialize all hwq structures -+ * -+ * @rwnx_hw: Driver main data -+ * -+ */ -+void rwnx_hwq_init(struct rwnx_hw *rwnx_hw) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(rwnx_hw->hwq); i++) { -+ struct rwnx_hwq *hwq = &rwnx_hw->hwq[i]; -+ -+ hwq->id = i; -+ hwq->size = nx_txdesc_cnt[i]; -+ INIT_LIST_HEAD(&hwq->list); -+ -+ } -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_txq.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_txq.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_txq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_txq.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,402 @@ -+/** -+ **************************************************************************************** -+ * -+ * @file rwnx_txq.h -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ **************************************************************************************** -+ */ -+#ifndef _RWNX_TXQ_H_ -+#define _RWNX_TXQ_H_ -+ -+#include -+#include -+#include -+ -+#ifdef CONFIG_RWNX_FULLMAC -+/** -+ * Fullmac TXQ configuration: -+ * - STA: 1 TXQ per TID (limited to 8) -+ * 1 TXQ for bufferable MGT frames -+ * - VIF: 1 TXQ for Multi/Broadcast + -+ * 1 TXQ for MGT for unknown STAs or non-bufferable MGT frames -+ * - 1 TXQ for offchannel transmissions -+ * -+ * -+ * Txq mapping looks like -+ * for NX_REMOTE_STA_MAX=10 and NX_VIRT_DEV_MAX=4 -+ * -+ * | TXQ | NDEV_ID | VIF | STA | TID | HWQ | -+ * |-----+---------+-----+-------+------+-----|- -+ * | 0 | 0 | | 0 | 0 | 1 | 9 TXQ per STA -+ * | 1 | 1 | | 0 | 1 | 0 | (8 data + 1 mgmt) -+ * | 2 | 2 | | 0 | 2 | 0 | -+ * | 3 | 3 | | 0 | 3 | 1 | -+ * | 4 | 4 | | 0 | 4 | 2 | -+ * | 5 | 5 | | 0 | 5 | 2 | -+ * | 6 | 6 | | 0 | 6 | 3 | -+ * | 7 | 7 | | 0 | 7 | 3 | -+ * | 8 | N/A | | 0 | MGMT | 3 | -+ * |-----+---------+-----+-------+------+-----|- -+ * | ... | | | | | | Same for all STAs -+ * |-----+---------+-----+-------+------+-----|- -+ * | 90 | 80 | 0 | BC/MC | 0 | 1/4 | 1 TXQ for BC/MC per VIF -+ * | ... | | | | | | -+ * | 93 | 80 | 3 | BC/MC | 0 | 1/4 | -+ * |-----+---------+-----+-------+------+-----|- -+ * | 94 | N/A | 0 | N/A | MGMT | 3 | 1 TXQ for unknown STA per VIF -+ * | ... | | | | | | -+ * | 97 | N/A | 3 | N/A | MGMT | 3 | -+ * |-----+---------+-----+-------+------+-----|- -+ * | 98 | N/A | | N/A | MGMT | 3 | 1 TXQ for offchannel frame -+ */ -+#define NX_NB_TID_PER_STA 8 -+#define NX_NB_TXQ_PER_STA (NX_NB_TID_PER_STA + 1) -+#define NX_NB_TXQ_PER_VIF 2 -+#define NX_NB_TXQ ((NX_NB_TXQ_PER_STA * NX_REMOTE_STA_MAX) + \ -+ (NX_NB_TXQ_PER_VIF * NX_VIRT_DEV_MAX) + 1) -+ -+#define NX_FIRST_VIF_TXQ_IDX (NX_REMOTE_STA_MAX * NX_NB_TXQ_PER_STA) -+#define NX_FIRST_BCMC_TXQ_IDX NX_FIRST_VIF_TXQ_IDX -+#define NX_FIRST_UNK_TXQ_IDX (NX_FIRST_BCMC_TXQ_IDX + NX_VIRT_DEV_MAX) -+ -+#define NX_OFF_CHAN_TXQ_IDX (NX_FIRST_VIF_TXQ_IDX + \ -+ (NX_VIRT_DEV_MAX * NX_NB_TXQ_PER_VIF)) -+ -+#define NX_FIRST_VIF_TXQ_IDX_FOR_OLD_IC (NX_REMOTE_STA_MAX_FOR_OLD_IC * NX_NB_TXQ_PER_STA) -+#define NX_FIRST_BCMC_TXQ_IDX_FOR_OLD_IC NX_FIRST_VIF_TXQ_IDX_FOR_OLD_IC -+#define NX_FIRST_UNK_TXQ_IDX_FOR_OLD_IC (NX_FIRST_BCMC_TXQ_IDX_FOR_OLD_IC + NX_VIRT_DEV_MAX) -+ -+#define NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC (NX_FIRST_VIF_TXQ_IDX_FOR_OLD_IC + \ -+ (NX_VIRT_DEV_MAX * NX_NB_TXQ_PER_VIF)) -+ -+ -+#define NX_BCMC_TXQ_TYPE 0 -+#define NX_UNK_TXQ_TYPE 1 -+ -+/** -+ * Each data TXQ is a netdev queue. TXQ to send MGT are not data TXQ as -+ * they did not recieved buffer from netdev interface. -+ * Need to allocate the maximum case. -+ * AP : all STAs + 1 BC/MC -+ */ -+#define NX_NB_NDEV_TXQ ((NX_NB_TID_PER_STA * NX_REMOTE_STA_MAX) + 1) -+#define NX_NB_NDEV_TXQ_FOR_OLD_IC ((NX_NB_TID_PER_STA * NX_REMOTE_STA_MAX_FOR_OLD_IC) + 1) -+ -+#define NX_BCMC_TXQ_NDEV_IDX (NX_NB_TID_PER_STA * NX_REMOTE_STA_MAX) -+#define NX_BCMC_TXQ_NDEV_IDX_FOR_OLD_IC (NX_NB_TID_PER_STA * NX_REMOTE_STA_MAX_FOR_OLD_IC) -+#define NX_STA_NDEV_IDX(tid, sta_idx) ((tid) + (sta_idx) * NX_NB_TID_PER_STA) -+#define NDEV_NO_TXQ 0xffff -+#if (NX_NB_NDEV_TXQ >= NDEV_NO_TXQ) -+#error("Need to increase struct rwnx_txq->ndev_idx size") -+#endif -+ -+/* stop netdev queue when number of queued buffers if greater than this */ -+#define RWNX_NDEV_FLOW_CTRL_STOP 64 -+/* restart netdev queue when number of queued buffers is lower than this */ -+#define RWNX_NDEV_FLOW_CTRL_RESTART 64 -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+#define TXQ_INACTIVE 0xffff -+#if (NX_NB_TXQ >= TXQ_INACTIVE) -+#error("Need to increase struct rwnx_txq->idx size") -+#endif -+ -+#define NX_TXQ_INITIAL_CREDITS 64 -+ -+/** -+ * TXQ tid sorted by decreasing priority -+ */ -+extern const int nx_tid_prio[NX_NB_TID_PER_STA]; -+ -+/** -+ * struct rwnx_hwq - Structure used to save information relative to -+ * an AC TX queue (aka HW queue) -+ * @list: List of TXQ, that have buffers ready for this HWQ -+ * @credits: available credit for the queue (i.e. nb of buffers that -+ * can be pushed to FW ) -+ * @id Id of the HWQ among RWNX_HWQ_.... -+ * @size size of the queue -+ * @need_processing Indicate if hwq should be processed -+ * @len number of packet ready to be pushed to fw for this HW queue -+ * @len_stop threshold to stop mac80211(i.e. netdev) queues. Stop queue when -+ * driver has more than @len_stop packets ready. -+ * @len_start threshold to wake mac8011 queues. Wake queue when driver has -+ * less than @len_start packets ready. -+ */ -+struct rwnx_hwq { -+ struct list_head list; -+ u8 size; -+ u8 id; -+ bool need_processing; -+}; -+ -+/** -+ * enum rwnx_push_flags - Flags of pushed buffer -+ * -+ * @RWNX_PUSH_RETRY Pushing a buffer for retry -+ * @RWNX_PUSH_IMMEDIATE Pushing a buffer without queuing it first -+ */ -+enum rwnx_push_flags { -+ RWNX_PUSH_RETRY = BIT(0), -+ RWNX_PUSH_IMMEDIATE = BIT(1), -+}; -+ -+/** -+ * enum rwnx_txq_flags - TXQ status flag -+ * -+ * @RWNX_TXQ_IN_HWQ_LIST: The queue is scheduled for transmission -+ * @RWNX_TXQ_STOP_FULL: No more credits for the queue -+ * @RWNX_TXQ_STOP_CSA: CSA is in progress -+ * @RWNX_TXQ_STOP_STA_PS: Destiniation sta is currently in power save mode -+ * @RWNX_TXQ_STOP_VIF_PS: Vif owning this queue is currently in power save mode -+ * @RWNX_TXQ_STOP_CHAN: Channel of this queue is not the current active channel -+ * @RWNX_TXQ_STOP_MU_POS: TXQ is stopped waiting for all the buffers pushed to -+ * fw to be confirmed -+ * @RWNX_TXQ_STOP: All possible reason to have a txq stopped -+ * @RWNX_TXQ_NDEV_FLOW_CTRL: associated netdev queue is currently stopped. -+ * Note: when a TXQ is flowctrl it is NOT stopped -+ */ -+enum rwnx_txq_flags { -+ RWNX_TXQ_IN_HWQ_LIST = BIT(0), -+ RWNX_TXQ_STOP_FULL = BIT(1), -+ RWNX_TXQ_STOP_CSA = BIT(2), -+ RWNX_TXQ_STOP_STA_PS = BIT(3), -+ RWNX_TXQ_STOP_VIF_PS = BIT(4), -+ RWNX_TXQ_STOP_CHAN = BIT(5), -+ RWNX_TXQ_STOP_MU_POS = BIT(6), -+ RWNX_TXQ_STOP = (RWNX_TXQ_STOP_FULL | RWNX_TXQ_STOP_CSA | -+ RWNX_TXQ_STOP_STA_PS | RWNX_TXQ_STOP_VIF_PS | -+ RWNX_TXQ_STOP_CHAN), -+ RWNX_TXQ_NDEV_FLOW_CTRL = BIT(7), -+}; -+ -+ -+/** -+ * struct rwnx_txq - Structure used to save information relative to -+ * a RA/TID TX queue -+ * -+ * @idx: Unique txq idx. Set to TXQ_INACTIVE if txq is not used. -+ * @status: bitfield of @rwnx_txq_flags. -+ * @credits: available credit for the queue (i.e. nb of buffers that -+ * can be pushed to FW). -+ * @pkt_sent: number of consecutive pkt sent without leaving HW queue list -+ * @pkt_pushed: number of pkt currently pending for transmission confirmation -+ * @sched_list: list node for HW queue schedule list (rwnx_hwq.list) -+ * @sk_list: list of buffers to push to fw -+ * @last_retry_skb: pointer on the last skb in @sk_list that is a retry. -+ * (retry skb are stored at the beginning of the list) -+ * NULL if no retry skb is queued in @sk_list -+ * @nb_retry: Number of retry packet queued. -+ * @hwq: Pointer on the associated HW queue. -+ * @push_limit: number of packet to push before removing the txq from hwq list. -+ * (we always have push_limit < skb_queue_len(sk_list)) -+ * @tid: TID -+ * -+ * SOFTMAC specific: -+ * @baw: Block Ack window information -+ * @amsdu_anchor: pointer to rwnx_sw_txhdr of the first subframe of the A-MSDU. -+ * NULL if no A-MSDU frame is in construction -+ * @amsdu_ht_len_cap: -+ * @amsdu_vht_len_cap: -+ * @nb_ready_mac80211: Number of buffer ready in mac80211 txq -+ * -+ * FULLMAC specific -+ * @ps_id: Index to use for Power save mode (LEGACY or UAPSD) -+ * @ndev_idx: txq idx from netdev point of view (0xFF for non netdev queue) -+ * @ndev: pointer to ndev of the corresponding vif -+ * @amsdu: pointer to rwnx_sw_txhdr of the first subframe of the A-MSDU. -+ * NULL if no A-MSDU frame is in construction -+ * @amsdu_len: Maximum size allowed for an A-MSDU. 0 means A-MSDU not allowed -+ */ -+struct rwnx_txq { -+ u16 idx; -+ u8 status; -+ s8 credits; -+ u8 pkt_sent; -+ u8 pkt_pushed[CONFIG_USER_MAX]; -+ struct list_head sched_list; -+ struct sk_buff_head sk_list; -+ struct sk_buff *last_retry_skb; -+ struct rwnx_hwq *hwq; -+ int nb_retry; -+ u8 push_limit; -+ u8 tid; -+#ifdef CONFIG_MAC80211_TXQ -+ unsigned long nb_ready_mac80211; -+#endif -+#ifdef CONFIG_RWNX_FULLMAC -+ struct rwnx_sta *sta; -+ u8 ps_id; -+ u16 ndev_idx; -+ struct net_device *ndev; -+#ifdef CONFIG_RWNX_AMSDUS_TX -+ struct rwnx_sw_txhdr *amsdu; -+ u16 amsdu_len; -+#endif /* CONFIG_RWNX_AMSDUS_TX */ -+#endif /* CONFIG_RWNX_FULLMAC */ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+ u8 mumimo_info; -+#endif -+}; -+ -+struct rwnx_sta; -+struct rwnx_vif; -+struct rwnx_hw; -+struct rwnx_sw_txhdr; -+ -+#ifdef CONFIG_RWNX_MUMIMO_TX -+#define RWNX_TXQ_GROUP_ID(txq) ((txq)->mumimo_info & 0x3f) -+#define RWNX_TXQ_POS_ID(txq) (((txq)->mumimo_info >> 6) & 0x3) -+#else -+#define RWNX_TXQ_GROUP_ID(txq) 0 -+#define RWNX_TXQ_POS_ID(txq) 0 -+#endif /* CONFIG_RWNX_MUMIMO_TX */ -+ -+static inline bool rwnx_txq_is_stopped(struct rwnx_txq *txq) -+{ -+ return (txq->status & RWNX_TXQ_STOP); -+} -+ -+static inline bool rwnx_txq_is_full(struct rwnx_txq *txq) -+{ -+ return (txq->status & RWNX_TXQ_STOP_FULL); -+} -+ -+static inline bool rwnx_txq_is_scheduled(struct rwnx_txq *txq) -+{ -+ return (txq->status & RWNX_TXQ_IN_HWQ_LIST); -+} -+ -+/** -+ * foreach_sta_txq - Macro to iterate over all TXQ of a STA in increasing -+ * TID order -+ * -+ * @sta: pointer to rwnx_sta -+ * @txq: pointer to rwnx_txq updated with the next TXQ at each iteration -+ * @tid: int updated with the TXQ tid at each iteration -+ * @rwnx_hw: main driver data -+ */ -+#ifdef CONFIG_MAC80211_TXQ -+#define foreach_sta_txq(sta, txq, tid, rwnx_hw) \ -+ for (tid = 0, txq = rwnx_txq_sta_get(sta, 0); \ -+ tid < NX_NB_TXQ_PER_STA; \ -+ tid++, txq = rwnx_txq_sta_get(sta, tid)) -+ -+#elif defined(CONFIG_RWNX_FULLMAC) /* CONFIG_RWNX_FULLMAC */ -+#define foreach_sta_txq(sta, txq, tid, rwnx_hw) \ -+ for (tid = 0, txq = rwnx_txq_sta_get(sta, 0, rwnx_hw); \ -+ tid < (is_multicast_sta(sta->sta_idx) ? 1 : NX_NB_TXQ_PER_STA); \ -+ tid++, txq++) -+ -+#endif -+ -+/** -+ * foreach_sta_txq_prio - Macro to iterate over all TXQ of a STA in -+ * decreasing priority order -+ * -+ * @sta: pointer to rwnx_sta -+ * @txq: pointer to rwnx_txq updated with the next TXQ at each iteration -+ * @tid: int updated with the TXQ tid at each iteration -+ * @i: int updated with ieration count -+ * @rwnx_hw: main driver data -+ * -+ * Note: For fullmac txq for mgmt frame is skipped -+ */ -+#ifdef CONFIG_RWNX_FULLMAC -+#define foreach_sta_txq_prio(sta, txq, tid, i, rwnx_hw) \ -+ for (i = 0, tid = nx_tid_prio[0], txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); \ -+ i < NX_NB_TID_PER_STA; \ -+ i++, tid = nx_tid_prio[i], txq = rwnx_txq_sta_get(sta, tid, rwnx_hw)) -+#endif -+ -+/** -+ * foreach_vif_txq - Macro to iterate over all TXQ of a VIF (in AC order) -+ * -+ * @vif: pointer to rwnx_vif -+ * @txq: pointer to rwnx_txq updated with the next TXQ at each iteration -+ * @ac: int updated with the TXQ ac at each iteration -+ */ -+#ifdef CONFIG_MAC80211_TXQ -+#define foreach_vif_txq(vif, txq, ac) \ -+ for (ac = RWNX_HWQ_BK, txq = rwnx_txq_vif_get(vif, ac); \ -+ ac < NX_NB_TXQ_PER_VIF; \ -+ ac++, txq = rwnx_txq_vif_get(vif, ac)) -+ -+#else -+#define foreach_vif_txq(vif, txq, ac) \ -+ for (ac = RWNX_HWQ_BK, txq = &vif->txqs[0]; \ -+ ac < NX_NB_TXQ_PER_VIF; \ -+ ac++, txq++) -+#endif -+ -+#ifdef CONFIG_RWNX_FULLMAC -+struct rwnx_txq *rwnx_txq_sta_get(struct rwnx_sta *sta, u8 tid, -+ struct rwnx_hw *rwnx_hw); -+struct rwnx_txq *rwnx_txq_vif_get(struct rwnx_vif *vif, u8 type); -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+/** -+ * rwnx_txq_vif_get_status - return status bits related to the vif -+ * -+ * @rwnx_vif: Pointer to vif structure -+ */ -+static inline u8 rwnx_txq_vif_get_status(struct rwnx_vif *rwnx_vif) -+{ -+ struct rwnx_txq *txq = rwnx_txq_vif_get(rwnx_vif, 0); -+ return (txq->status & (RWNX_TXQ_STOP_CHAN | RWNX_TXQ_STOP_VIF_PS)); -+} -+ -+void rwnx_txq_vif_init(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, -+ u8 status); -+void rwnx_txq_vif_deinit(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif); -+void rwnx_txq_sta_init(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta, -+ u8 status); -+void rwnx_txq_sta_deinit(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta); -+#ifdef CONFIG_RWNX_FULLMAC -+void rwnx_txq_unk_vif_init(struct rwnx_vif *rwnx_vif); -+void rwnx_txq_unk_vif_deinit(struct rwnx_vif *vif); -+void rwnx_txq_offchan_init(struct rwnx_vif *rwnx_vif); -+void rwnx_txq_offchan_deinit(struct rwnx_vif *rwnx_vif); -+void rwnx_txq_tdls_vif_init(struct rwnx_vif *rwnx_vif); -+void rwnx_txq_tdls_vif_deinit(struct rwnx_vif *vif); -+void rwnx_txq_tdls_sta_start(struct rwnx_vif *rwnx_vif, u16 reason, -+ struct rwnx_hw *rwnx_hw); -+void rwnx_txq_tdls_sta_stop(struct rwnx_vif *rwnx_vif, u16 reason, -+ struct rwnx_hw *rwnx_hw); -+#endif -+ -+ -+void rwnx_txq_add_to_hw_list(struct rwnx_txq *txq); -+void rwnx_txq_del_from_hw_list(struct rwnx_txq *txq); -+void rwnx_txq_stop(struct rwnx_txq *txq, u16 reason); -+void rwnx_txq_start(struct rwnx_txq *txq, u16 reason); -+void rwnx_txq_vif_start(struct rwnx_vif *vif, u16 reason, -+ struct rwnx_hw *rwnx_hw); -+void rwnx_txq_vif_stop(struct rwnx_vif *vif, u16 reason, -+ struct rwnx_hw *rwnx_hw); -+ -+#ifdef CONFIG_RWNX_FULLMAC -+void rwnx_txq_sta_start(struct rwnx_sta *sta, u16 reason, -+ struct rwnx_hw *rwnx_hw); -+void rwnx_txq_sta_stop(struct rwnx_sta *sta, u16 reason, -+ struct rwnx_hw *rwnx_hw); -+void rwnx_txq_offchan_start(struct rwnx_hw *rwnx_hw); -+void rwnx_txq_sta_switch_vif(struct rwnx_sta *sta, struct rwnx_vif *old_vif, -+ struct rwnx_vif *new_vif); -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+ -+int rwnx_txq_queue_skb(struct sk_buff *skb, struct rwnx_txq *txq, -+ struct rwnx_hw *rwnx_hw, bool retry); -+void rwnx_txq_confirm_any(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq, -+ struct rwnx_hwq *hwq, struct rwnx_sw_txhdr *sw_txhdr); -+ -+ -+void rwnx_hwq_init(struct rwnx_hw *rwnx_hw); -+void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq); -+void rwnx_hwq_process_all(struct rwnx_hw *rwnx_hw); -+ -+#endif /* _RWNX_TXQ_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_utils.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_utils.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_utils.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_utils.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,39 @@ -+/** -+ * rwnx_utils.c -+ * -+ * IPC utility function definitions -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ */ -+#include "rwnx_utils.h" -+#include "rwnx_defs.h" -+#include "rwnx_rx.h" -+#include "rwnx_tx.h" -+#include "rwnx_msg_rx.h" -+#include "rwnx_debugfs.h" -+#include "rwnx_prof.h" -+#include "ipc_host.h" -+ -+extern int get_testmode(void); -+extern void get_fw_path(char* fw_path); -+extern int testmode; -+extern char aic_fw_path[200]; -+ -+ -+int rwnx_init_aic(struct rwnx_hw *rwnx_hw) -+{ -+ RWNX_DBG(RWNX_FN_ENTRY_STR); -+#ifdef AICWF_SDIO_SUPPORT -+ aicwf_sdio_host_init(&(rwnx_hw->sdio_env), NULL, NULL, rwnx_hw); -+#else -+ aicwf_usb_host_init(&(rwnx_hw->usb_env), NULL, NULL, rwnx_hw); -+#endif -+ rwnx_cmd_mgr_init(rwnx_hw->cmd_mgr); -+ -+ testmode = get_testmode(); -+ memset(aic_fw_path, 0, 200); -+ get_fw_path(aic_fw_path); -+ -+ return 0; -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_utils.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_utils.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_utils.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_utils.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,133 @@ -+/** -+ * rwnx_ipc_utils.h -+ * -+ * IPC utility function declarations -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ */ -+#ifndef _RWNX_IPC_UTILS_H_ -+#define _RWNX_IPC_UTILS_H_ -+ -+#include -+#include -+#include -+#include "aicwf_debug.h" -+ -+ -+#include "lmac_msg.h" -+#if 0 -+#ifdef CONFIG_RWNX_DBG -+/* #define RWNX_DBG(format, arg...) pr_warn(format, ## arg) */ -+#define RWNX_DBG printk -+#else -+#define RWNX_DBG(a...) do {} while (0) -+#endif -+ -+#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__ -+#endif -+enum rwnx_dev_flag { -+ RWNX_DEV_RESTARTING, -+ RWNX_DEV_STACK_RESTARTING, -+ RWNX_DEV_STARTED, -+}; -+ -+struct rwnx_hw; -+struct rwnx_sta; -+ -+/** -+ * struct rwnx_ipc_elem - Generic IPC buffer of fixed size -+ * -+ * @addr: Host address of the buffer. -+ * @dma_addr: DMA address of the buffer. -+ */ -+struct rwnx_ipc_elem { -+ void *addr; -+ dma_addr_t dma_addr; -+}; -+ -+/** -+ * struct rwnx_ipc_elem_pool - Generic pool of IPC buffers of fixed size -+ * -+ * @nb: Number of buffers currenlty allocated in the pool -+ * @buf: Array of buffers (size of array is @nb) -+ * @pool: DMA pool in which buffers have been allocated -+ */ -+struct rwnx_ipc_elem_pool { -+ int nb; -+ struct rwnx_ipc_elem *buf; -+ struct dma_pool *pool; -+}; -+ -+/** -+ * struct rwnx_ipc_elem - Generic IPC buffer of variable size -+ * -+ * @addr: Host address of the buffer. -+ * @dma_addr: DMA address of the buffer. -+ * @size: Size, in bytes, of the buffer -+ */ -+struct rwnx_ipc_elem_var { -+ void *addr; -+ dma_addr_t dma_addr; -+ size_t size; -+}; -+ -+/** -+ * struct rwnx_ipc_dbgdump_elem - IPC buffer for debug dump -+ * -+ * @mutex: Mutex to protect access to debug dump -+ * @buf: IPC buffer -+ */ -+struct rwnx_ipc_dbgdump_elem { -+ struct mutex mutex; -+ struct rwnx_ipc_elem_var buf; -+}; -+ -+static const u32 rwnx_rxbuff_pattern = 0xCAFEFADE; -+ -+/* -+ * Maximum Length of Radiotap header vendor specific data(in bytes) -+ */ -+#define RADIOTAP_HDR_VEND_MAX_LEN 16 -+ -+/* -+ * Maximum Radiotap Header Length without vendor specific data (in bytes) -+ */ -+#define RADIOTAP_HDR_MAX_LEN 80 -+ -+/* -+ * Unsupported HT Frame data length (in bytes) -+ */ -+#define UNSUP_RX_VEC_DATA_LEN 2 -+ -+/** -+ * struct rwnx_ipc_skb_elem - IPC buffer for SKB element -+ * -+ * @skb: Pointer to the skb buffer allocated -+ * @dma_addr: DMA address of the data buffer fo skb -+ * -+ */ -+struct rwnx_ipc_skb_elem { -+ struct sk_buff *skb; -+ dma_addr_t dma_addr; -+}; -+ -+#ifdef CONFIG_RWNX_FULLMAC -+ -+/* Maximum number of rx buffer the fw may use at the same time */ -+#define RWNX_RXBUFF_MAX (64 * NX_REMOTE_STA_MAX) -+ -+/** -+ * struct rwnx_ipc_rxbuf_elems - IPC buffers for RX -+ * -+ * @skb: Array of buffer push to FW. -+ * @idx: Index of the last pushed skb.(Use to find the next free entry quicker) -+ * -+ * Note: contrary to softmac version, dma_addr are stored inside skb->cb. -+ */ -+struct rwnx_ipc_rxbuf_elems { -+ struct sk_buff *skb[RWNX_RXBUFF_MAX]; -+ int idx; -+}; -+ -+#endif /* CONFIG_RWNX_FULLMAC */ -+#endif /* _RWNX_IPC_UTILS_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_v7.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_v7.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_v7.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_v7.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,195 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_v7.c - Support for v7 platform -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#include "rwnx_v7.h" -+#include "rwnx_defs.h" -+#include "rwnx_irqs.h" -+#include "reg_access.h" -+#include "hal_desc.h" -+ -+struct rwnx_v7 { -+ u8 *pci_bar0_vaddr; -+ u8 *pci_bar1_vaddr; -+}; -+ -+static int rwnx_v7_platform_enable(struct rwnx_hw *rwnx_hw) -+{ -+ int ret; -+ -+ /* sched_setscheduler on ONESHOT threaded irq handler for BCNs ? */ -+ ret = request_irq(rwnx_hw->plat->pci_dev->irq, rwnx_irq_hdlr, 0, -+ "rwnx", rwnx_hw); -+ return ret; -+} -+ -+static int rwnx_v7_platform_disable(struct rwnx_hw *rwnx_hw) -+{ -+ free_irq(rwnx_hw->plat->pci_dev->irq, rwnx_hw); -+ return 0; -+} -+ -+static void rwnx_v7_platform_deinit(struct rwnx_plat *rwnx_plat) -+{ -+ #ifdef CONFIG_PCI -+ struct rwnx_v7 *rwnx_v7 = (struct rwnx_v7 *)rwnx_plat->priv; -+ -+ pci_disable_device(rwnx_plat->pci_dev); -+ iounmap(rwnx_v7->pci_bar0_vaddr); -+ iounmap(rwnx_v7->pci_bar1_vaddr); -+ pci_release_regions(rwnx_plat->pci_dev); -+ pci_clear_master(rwnx_plat->pci_dev); -+ pci_disable_msi(rwnx_plat->pci_dev); -+ #endif -+ kfree(rwnx_plat); -+} -+ -+static u8 *rwnx_v7_get_address(struct rwnx_plat *rwnx_plat, int addr_name, -+ unsigned int offset) -+{ -+ struct rwnx_v7 *rwnx_v7 = (struct rwnx_v7 *)rwnx_plat->priv; -+ -+ if (WARN(addr_name >= RWNX_ADDR_MAX, "Invalid address %d", addr_name)) -+ return NULL; -+ -+ if (addr_name == RWNX_ADDR_CPU) -+ return rwnx_v7->pci_bar0_vaddr + offset; -+ else -+ return rwnx_v7->pci_bar1_vaddr + offset; -+} -+ -+static void rwnx_v7_ack_irq(struct rwnx_plat *rwnx_plat) -+{ -+ -+} -+ -+static const u32 rwnx_v7_config_reg[] = { -+ NXMAC_DEBUG_PORT_SEL_ADDR, -+ SYSCTRL_DIAG_CONF_ADDR, -+ SYSCTRL_PHYDIAG_CONF_ADDR, -+ SYSCTRL_RIUDIAG_CONF_ADDR, -+ RF_V7_DIAGPORT_CONF1_ADDR, -+}; -+ -+static const u32 rwnx_v7_he_config_reg[] = { -+ SYSCTRL_DIAG_CONF0, -+ SYSCTRL_DIAG_CONF1, -+ SYSCTRL_DIAG_CONF2, -+ SYSCTRL_DIAG_CONF3, -+}; -+ -+static int rwnx_v7_get_config_reg(struct rwnx_plat *rwnx_plat, const u32 **list) -+{ -+ u32 fpga_sign; -+ -+ if (!list) -+ return 0; -+ -+ fpga_sign = RWNX_REG_READ(rwnx_plat, RWNX_ADDR_SYSTEM, SYSCTRL_SIGNATURE_ADDR); -+ if (__FPGA_TYPE(fpga_sign) == 0xc0ca) { -+ *list = rwnx_v7_he_config_reg; -+ return ARRAY_SIZE(rwnx_v7_he_config_reg); -+ } else { -+ *list = rwnx_v7_config_reg; -+ return ARRAY_SIZE(rwnx_v7_config_reg); -+ } -+} -+ -+ -+/** -+ * rwnx_v7_platform_init - Initialize the DINI platform -+ * -+ * @pci_dev PCI device -+ * @rwnx_plat Pointer on struct rwnx_stat * to be populated -+ * -+ * @return 0 on success, < 0 otherwise -+ * -+ * Allocate and initialize a rwnx_plat structure for the dini platform. -+ */ -+int rwnx_v7_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_plat) -+{ -+ struct rwnx_v7 *rwnx_v7; -+ u16 pci_cmd; -+ int ret = 0; -+ -+ *rwnx_plat = kzalloc(sizeof(struct rwnx_plat) + sizeof(struct rwnx_v7), -+ GFP_KERNEL); -+ if (!*rwnx_plat) -+ return -ENOMEM; -+ -+ rwnx_v7 = (struct rwnx_v7 *)(*rwnx_plat)->priv; -+ -+ /* Hotplug fixups */ -+ pci_read_config_word(pci_dev, PCI_COMMAND, &pci_cmd); -+ pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR; -+ pci_write_config_word(pci_dev, PCI_COMMAND, pci_cmd); -+ //pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2); -+ -+ ret = pci_enable_device(pci_dev); -+ if (ret) { -+ dev_err(&(pci_dev->dev), "pci_enable_device failed\n"); -+ goto out_enable; -+ } -+ -+ pci_set_master(pci_dev); -+ -+#if 0 -+ ret = pci_request_regions(pci_dev, KBUILD_MODNAME); -+ if (ret) { -+ dev_err(&(pci_dev->dev), "pci_request_regions failed\n"); -+ goto out_request; -+ } -+#endif -+ #ifdef CONFIG_PCI -+ if (pci_enable_msi(pci_dev)) { -+ dev_err(&(pci_dev->dev), "pci_enable_msi failed\n"); -+ goto out_msi; -+ -+ } -+ #endif -+ -+ rwnx_v7->pci_bar0_vaddr = (u8 *)pci_ioremap_bar(pci_dev, 0); -+ if (!rwnx_v7->pci_bar0_vaddr) { -+ dev_err(&(pci_dev->dev), "pci_ioremap_bar(%d) failed\n", 0); -+ ret = -ENOMEM; -+ goto out_bar0; -+ } -+ rwnx_v7->pci_bar1_vaddr = (u8 *)pci_ioremap_bar(pci_dev, 1); -+ if (!rwnx_v7->pci_bar1_vaddr) { -+ dev_err(&(pci_dev->dev), "pci_ioremap_bar(%d) failed\n", 1); -+ ret = -ENOMEM; -+ goto out_bar1; -+ } -+ -+ (*rwnx_plat)->enable = rwnx_v7_platform_enable; -+ (*rwnx_plat)->disable = rwnx_v7_platform_disable; -+ (*rwnx_plat)->deinit = rwnx_v7_platform_deinit; -+ (*rwnx_plat)->get_address = rwnx_v7_get_address; -+ (*rwnx_plat)->ack_irq = rwnx_v7_ack_irq; -+ (*rwnx_plat)->get_config_reg = rwnx_v7_get_config_reg; -+ -+ return 0; -+ -+out_bar1: -+ iounmap(rwnx_v7->pci_bar0_vaddr); -+out_bar0: -+#ifdef CONFIG_PCI -+ pci_disable_msi(pci_dev); -+out_msi: -+#endif -+ pci_release_regions(pci_dev); -+//out_request: -+#ifdef CONFIG_PCI -+ pci_clear_master(pci_dev); -+#endif -+ pci_disable_device(pci_dev); -+out_enable: -+ kfree(*rwnx_plat); -+ return ret; -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_v7.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_v7.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_v7.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_v7.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,20 @@ -+/** -+ ****************************************************************************** -+ * -+ * @file rwnx_v7.h -+ * -+ * Copyright (C) RivieraWaves 2012-2019 -+ * -+ ****************************************************************************** -+ */ -+ -+#ifndef _RWNX_V7_H_ -+#define _RWNX_V7_H_ -+ -+#include -+#include "rwnx_platform.h" -+ -+int rwnx_v7_platform_init(struct pci_dev *pci_dev, -+ struct rwnx_plat **rwnx_plat); -+ -+#endif /* _RWNX_V7_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version_gen.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version_gen.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version_gen.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version_gen.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,4 @@ -+#define RWNX_VERS_REV "241c091M (master)" -+#define RWNX_VERS_MOD "6.4.3.0" -+#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - - 241c091M (master)" -+#define RELEASE_DATE "2024_0327_3561b08f" -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,12 @@ -+#ifndef _RWNX_VERSION_H_ -+#define _RWNX_VERSION_H_ -+ -+#include "rwnx_version_gen.h" -+ -+static inline void rwnx_print_version(void) -+{ -+ AICWFDBG(LOGINFO, RWNX_VERS_BANNER"\n"); -+ AICWFDBG(LOGINFO, "RELEASE_DATE:%s \r\n", RELEASE_DATE); -+} -+ -+#endif /* _RWNX_VERSION_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_wakelock.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_wakelock.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_wakelock.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_wakelock.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,86 @@ -+#include -+#include -+#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -+#include -+#else -+#include -+#endif -+#include "rwnx_defs.h" -+#include "rwnx_wakelock.h" -+ -+struct wakeup_source *rwnx_wakeup_init(const char *name) -+{ -+ struct wakeup_source *ws; -+ ws = wakeup_source_create(name); -+ wakeup_source_add(ws); -+ return ws; -+} -+ -+void rwnx_wakeup_deinit(struct wakeup_source *ws) -+{ -+ if (ws && ws->active) -+ __pm_relax(ws); -+ wakeup_source_remove(ws); -+ wakeup_source_destroy(ws); -+} -+ -+struct wakeup_source *rwnx_wakeup_register(struct device *dev, const char *name) -+{ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) -+ return wakeup_source_register(dev, name); -+#else -+ -+#if defined(CONFIG_PLATFORM_ROCKCHIP2) || defined(CONFIG_PLATFORM_ROCKCHIP) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) -+ return wakeup_source_register(dev, name); -+#else -+ return wakeup_source_register(name); -+#endif -+ -+#else -+ return wakeup_source_register(name); -+#endif//#if defined(CONFIG_PLATFORM_ROCKCHIP2) || defined(CONFIG_PLATFORM_ROCKCHIP) -+ -+#endif//LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) -+} -+ -+void rwnx_wakeup_unregister(struct wakeup_source *ws) -+{ -+ if (ws && ws->active) -+ __pm_relax(ws); -+ wakeup_source_unregister(ws); -+} -+ -+void rwnx_wakeup_lock(struct wakeup_source *ws) -+{ -+ __pm_stay_awake(ws); -+} -+ -+void rwnx_wakeup_unlock(struct wakeup_source *ws) -+{ -+ __pm_relax(ws); -+} -+ -+void rwnx_wakeup_lock_timeout(struct wakeup_source *ws, unsigned int msec) -+{ -+ __pm_wakeup_event(ws, msec); -+} -+ -+void aicwf_wakeup_lock_init(struct rwnx_hw *rwnx_hw) -+{ -+ rwnx_hw->ws_tx = rwnx_wakeup_init("rwnx_tx_wakelock"); -+ rwnx_hw->ws_rx = rwnx_wakeup_init("rwnx_rx_wakelock"); -+ rwnx_hw->ws_irqrx = rwnx_wakeup_init("rwnx_irqrx_wakelock"); -+ rwnx_hw->ws_pwrctrl = rwnx_wakeup_init("rwnx_pwrcrl_wakelock"); -+} -+ -+void aicwf_wakeup_lock_deinit(struct rwnx_hw *rwnx_hw) -+{ -+ rwnx_wakeup_deinit(rwnx_hw->ws_tx); -+ rwnx_wakeup_deinit(rwnx_hw->ws_rx); -+ rwnx_wakeup_deinit(rwnx_hw->ws_irqrx); -+ rwnx_wakeup_deinit(rwnx_hw->ws_pwrctrl); -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_wakelock.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_wakelock.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_wakelock.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_wakelock.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,21 @@ -+#ifndef __RWNX_WAKELOCK_H -+#define __RWNX_WAKELOCK_H -+ -+#include -+#include -+#include -+ -+struct wakeup_source *rwnx_wakeup_init(const char *name); -+void rwnx_wakeup_deinit(struct wakeup_source *ws); -+ -+struct wakeup_source *rwnx_wakeup_register(struct device *dev, const char *name); -+void rwnx_wakeup_unregister(struct wakeup_source *ws); -+ -+void rwnx_wakeup_lock(struct wakeup_source *ws); -+void rwnx_wakeup_unlock(struct wakeup_source *ws); -+void rwnx_wakeup_lock_timeout(struct wakeup_source *ws, unsigned int msec); -+ -+void aicwf_wakeup_lock_init(struct rwnx_hw *rwnx_hw); -+void aicwf_wakeup_lock_deinit(struct rwnx_hw *rwnx_hw); -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/sdio_host.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/sdio_host.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/sdio_host.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/sdio_host.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,137 @@ -+/** -+ * sdio_host.c -+ * -+ * SDIO host function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+ -+#include "sdio_host.h" -+//#include "ipc_compat.h" -+#include "rwnx_tx.h" -+#include "rwnx_platform.h" -+#include "aicwf_debug.h" -+ -+/** -+ **************************************************************************************** -+ */ -+void aicwf_sdio_host_init(struct sdio_host_env_tag *env, -+ void *cb, -+ void *shared_env_ptr, -+ void *pthis) -+{ -+ // Reset the environments -+ -+ // Reset the Host environment -+ memset(env, 0, sizeof(struct sdio_host_env_tag)); -+ // Save the pointer to the register base -+ env->pthis = pthis; -+} -+ -+/** -+ **************************************************************************************** -+ */ -+volatile struct txdesc_host *aicwf_sdio_host_txdesc_get(struct sdio_host_env_tag *env, const int queue_idx) -+{ -+ // struct ipc_shared_env_tag *shared_env_ptr = env->shared; -+ volatile struct txdesc_host *txdesc_free = NULL; -+ uint32_t used_idx = env->txdesc_used_idx[queue_idx]; -+ uint32_t free_idx = env->txdesc_free_idx[queue_idx]; -+ -+ // ASSERT_ERR(queue_idx < SDIO_TXQUEUE_CNT); -+ // ASSERT_ERR((free_idx - used_idx) <= SDIO_TXDESC_CNT); -+ -+ // Check if a free descriptor is available -+ if (free_idx != (used_idx + SDIO_TXDESC_CNT)) { -+ // Get the pointer to the first free descriptor -+ // txdesc_free = shared_env_ptr->txdesc[queue_idx] + (free_idx % IPC_TXDESC_CNT); -+ } else { -+ txdesc_free = NULL; -+ } -+ -+ return txdesc_free; -+} -+ -+/** -+ **************************************************************************************** -+ */ -+void aicwf_sdio_host_txdesc_push(struct sdio_host_env_tag *env, const int queue_idx, const uint64_t host_id) -+{ -+ //printk("push, %d, %d, 0x%llx \r\n", queue_idx, env->txdesc_free_idx[queue_idx], host_id); -+ // Save the host id in the environment -+ env->tx_host_id[queue_idx][env->txdesc_free_idx[queue_idx] % SDIO_TXDESC_CNT] = host_id; -+ -+ // Increment the index -+ env->txdesc_free_idx[queue_idx]++; -+ if (env->txdesc_free_idx[queue_idx] == 0x80000000) -+ env->txdesc_free_idx[queue_idx] = 0; -+} -+ -+/** -+ **************************************************************************************** -+ */ -+void aicwf_sdio_host_tx_cfm_handler(struct sdio_host_env_tag *env, u32 *data) -+{ -+ u32 queue_idx = 0;// data[0]; -+ //struct rwnx_hw *rwnx_hw = (struct rwnx_hw *)env->pthis; -+ struct sk_buff *skb = NULL; -+ struct rwnx_txhdr *txhdr; -+ -+ // TX confirmation descriptors have been received -+ // REG_SW_SET_PROFILING(env->pthis, SW_PROF_IRQ_E2A_TXCFM); -+ //while (1) -+ { -+ // Get the used index and increase it. We do the increase before knowing if the -+ // current buffer is confirmed because the callback function may call the -+ // ipc_host_txdesc_get() in case flow control was enabled and the index has to be -+ // already at the good value to ensure that the test of FIFO full is correct -+ //uint32_t used_idx = env->txdesc_used_idx[queue_idx]++; -+ uint32_t used_idx = data[1]; -+ unsigned long host_id = env->tx_host_id[queue_idx][used_idx % SDIO_TXDESC_CNT]; -+ -+ // Reset the host id in the array -+ env->tx_host_id[queue_idx][used_idx % SDIO_TXDESC_CNT] = 0; -+ -+ // call the external function to indicate that a TX packet is freed -+ if (host_id == 0) { -+ // No more confirmations, so put back the used index at its initial value -+ env->txdesc_used_idx[queue_idx] = used_idx; -+ AICWFDBG(LOGERROR, "ERROR:No more confirmations\r\n"); -+ //break; -+ } -+ // set the cfm status -+ skb = (struct sk_buff *)host_id; -+ txhdr = (struct rwnx_txhdr *)skb->data; -+ txhdr->hw_hdr.cfm.status = (union rwnx_hw_txstatus)data[0]; -+ AICWFDBG(LOGINFO, "sdio_host_tx_cfm_handler:used_idx=%d, 0x%p, status=%x\r\n", used_idx, env->pthis, txhdr->hw_hdr.cfm.status.value); -+ //if (env->cb.send_data_cfm(env->pthis, host_id) != 0) -+ if (rwnx_txdatacfm(env->pthis, (void *)host_id) != 0) { -+ // No more confirmations, so put back the used index at its initial value -+ env->txdesc_used_idx[queue_idx] = used_idx; -+ env->tx_host_id[queue_idx][used_idx % SDIO_TXDESC_CNT] = host_id; -+ // and exit the loop -+ AICWFDBG(LOGERROR, "ERROR:rwnx_txdatacfm,\r\n"); -+ // break; -+ } -+ } -+} -+ -+int aicwf_rwnx_sdio_platform_init(struct aic_sdio_dev *sdiodev) -+{ -+ struct rwnx_plat *rwnx_plat = NULL; -+ void *drvdata; -+ int ret = -ENODEV; -+ -+ rwnx_plat = kzalloc(sizeof(struct rwnx_plat), GFP_KERNEL); -+ -+ if (!rwnx_plat) { -+ return -ENOMEM; -+ } -+ -+ rwnx_plat->sdiodev = sdiodev; -+ ret = rwnx_platform_init(rwnx_plat, &drvdata); -+ -+ return ret; -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/sdio_host.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/sdio_host.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/sdio_host.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/sdio_host.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,41 @@ -+/** -+ * sdio_host.h -+ * -+ * SDIO host function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+ -+#ifndef _SDIO_HOST_H_ -+#define _SDIO_HOST_H_ -+ -+#include "lmac_types.h" -+#include "aicwf_sdio.h" -+ -+#define SDIO_TXQUEUE_CNT NX_TXQ_CNT -+#define SDIO_TXDESC_CNT NX_TXDESC_CNT -+ -+ -+/// Definition of the IPC Host environment structure. -+struct sdio_host_env_tag { -+ // Index used that points to the first free TX desc -+ uint32_t txdesc_free_idx[SDIO_TXQUEUE_CNT]; -+ // Index used that points to the first used TX desc -+ uint32_t txdesc_used_idx[SDIO_TXQUEUE_CNT]; -+ // Array storing the currently pushed host ids, per IPC queue -+ uint64_t tx_host_id[SDIO_TXQUEUE_CNT][SDIO_TXDESC_CNT]; -+ -+ /// Pointer to the attached object (used in callbacks and register accesses) -+ void *pthis; -+}; -+ -+extern void aicwf_sdio_host_init(struct sdio_host_env_tag *env, -+ void *cb, void *shared_env_ptr, void *pthis); -+ -+extern void aicwf_sdio_host_txdesc_push(struct sdio_host_env_tag *env, const int queue_idx, const uint64_t host_id); -+ -+extern void aicwf_sdio_host_tx_cfm_handler(struct sdio_host_env_tag *env, u32 *data); -+extern int aicwf_rwnx_sdio_platform_init(struct aic_sdio_dev *sdiodev); -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/usb_host.c linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/usb_host.c ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/usb_host.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/usb_host.c 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,146 @@ -+/** -+ * usb_host.c -+ * -+ * USB host function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+ -+#include "usb_host.h" -+//#include "ipc_compat.h" -+#include "rwnx_tx.h" -+#include "rwnx_platform.h" -+ -+/** -+ **************************************************************************************** -+ */ -+void aicwf_usb_host_init(struct usb_host_env_tag *env, -+ void *cb, -+ void *shared_env_ptr, -+ void *pthis) -+{ -+ // Reset the environments -+ -+ // Reset the Host environment -+ memset(env, 0, sizeof(struct usb_host_env_tag)); -+ //printk("[Gaofx]rwnx_init_aic pthis %p !\n", pthis); -+ // Save the pointer to the register base -+ env->pthis = pthis; -+} -+ -+/** -+ **************************************************************************************** -+ */ -+volatile struct txdesc_host *aicwf_usb_host_txdesc_get(struct usb_host_env_tag *env, const int queue_idx) -+{ -+ // struct ipc_shared_env_tag *shared_env_ptr = env->shared; -+ volatile struct txdesc_host *txdesc_free = NULL; -+ uint32_t used_idx = env->txdesc_used_idx[queue_idx]; -+ uint32_t free_idx = env->txdesc_free_idx[queue_idx]; -+ -+ // ASSERT_ERR(queue_idx < SDIO_TXQUEUE_CNT); -+ // ASSERT_ERR((free_idx - used_idx) <= USB_TXDESC_CNT); -+ -+ // Check if a free descriptor is available -+ if (free_idx != (used_idx + USB_TXDESC_CNT)) { -+ // Get the pointer to the first free descriptor -+ // txdesc_free = shared_env_ptr->txdesc[queue_idx] + (free_idx % IPC_TXDESC_CNT); -+ } else { -+ txdesc_free = NULL; -+ } -+ -+ return txdesc_free; -+} -+ -+/** -+ **************************************************************************************** -+ */ -+void aicwf_usb_host_txdesc_push(struct usb_host_env_tag *env, const int queue_idx, const uint64_t host_id) -+{ -+ //printk("push, %d, %d, 0x%llx \r\n", queue_idx, env->txdesc_free_idx[queue_idx], host_id); -+ // Save the host id in the environment -+ env->tx_host_id[queue_idx][env->txdesc_free_idx[queue_idx] % USB_TXDESC_CNT] = host_id; -+ -+ // Increment the index -+ env->txdesc_free_idx[queue_idx]++; -+ if (env->txdesc_free_idx[queue_idx] == 0x80000000) -+ env->txdesc_free_idx[queue_idx] = 0; -+} -+ -+/** -+ **************************************************************************************** -+ */ -+void aicwf_usb_host_tx_cfm_handler(struct usb_host_env_tag *env, u32 *data) -+{ -+ u32 queue_idx = 0;//data[0]; -+ //struct rwnx_hw *rwnx_hw = (struct rwnx_hw *)env->pthis; -+ struct sk_buff *skb = NULL; -+ struct rwnx_txhdr *txhdr; -+ printk("%s enter \n", __func__); -+ //printk("sdio_host_tx_cfm_handler, %d, 0x%08x\r\n", queue_idx, data[1]); -+ // TX confirmation descriptors have been received -+ // REG_SW_SET_PROFILING(env->pthis, SW_PROF_IRQ_E2A_TXCFM); -+ //while (1) -+ { -+ // Get the used index and increase it. We do the increase before knowing if the -+ // current buffer is confirmed because the callback function may call the -+ // ipc_host_txdesc_get() in case flow control was enabled and the index has to be -+ // already at the good value to ensure that the test of FIFO full is correct -+ //uint32_t used_idx = env->txdesc_used_idx[queue_idx]++; -+ uint32_t used_idx = data[1]; -+ uint64_t host_id = env->tx_host_id[queue_idx][used_idx % USB_TXDESC_CNT]; -+ -+ // Reset the host id in the array -+ env->tx_host_id[queue_idx][used_idx % USB_TXDESC_CNT] = 0; -+ -+ // call the external function to indicate that a TX packet is freed -+ if (host_id == 0) { -+ // No more confirmations, so put back the used index at its initial value -+ env->txdesc_used_idx[queue_idx] = used_idx; -+ printk("ERROR:No more confirmations\r\n"); -+ return; -+ //break; -+ } -+ // set the cfm status -+ skb = (struct sk_buff *)(uint64_t)host_id; -+ txhdr = (struct rwnx_txhdr *)skb->data; -+ txhdr->hw_hdr.cfm.status = (union rwnx_hw_txstatus)data[0]; -+ //txhdr->hw_hdr.status = data[1]; -+ //printk("sdio_host_tx_cfm_handler, 0x%p\r\n", env->pthis); -+ //if (env->cb.send_data_cfm(env->pthis, host_id) != 0) -+ if (rwnx_txdatacfm(env->pthis, (void *)host_id) != 0) { -+ // No more confirmations, so put back the used index at its initial value -+ env->txdesc_used_idx[queue_idx] = used_idx; -+ env->tx_host_id[queue_idx][used_idx % USB_TXDESC_CNT] = host_id; -+ // and exit the loop -+ printk("ERROR:rwnx_txdatacfm,\r\n"); -+ // break; -+ } -+ } -+} -+ -+int aicwf_rwnx_usb_platform_init(struct aic_usb_dev *usbdev) -+{ -+ struct rwnx_plat *rwnx_plat = NULL; -+ void *drvdata; -+ int ret = -ENODEV; -+ -+ rwnx_plat = kzalloc(sizeof(struct rwnx_plat), GFP_KERNEL); -+ -+ if (!rwnx_plat) -+ return -ENOMEM; -+ -+// rwnx_plat->pci_dev = pci_dev; -+ rwnx_plat->usbdev = usbdev; -+ -+ ret = rwnx_platform_init(rwnx_plat, &drvdata); -+#if 0 -+ pci_set_drvdata(pci_dev, drvdata); -+ -+ if (ret) -+ rwnx_plat->deinit(rwnx_plat); -+#endif -+ return ret; -+} -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/usb_host.h linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/usb_host.h ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/usb_host.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/usb_host.h 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,41 @@ -+/** -+ * usb_host.h -+ * -+ * USB host function declarations -+ * -+ * Copyright (C) AICSemi 2018-2020 -+ */ -+ -+ -+#ifndef _USB_HOST_H_ -+#define _USB_HOST_H_ -+ -+#include "lmac_types.h" -+#include "aicwf_usb.h" -+ -+#define USB_TXQUEUE_CNT NX_TXQ_CNT -+#define USB_TXDESC_CNT NX_TXDESC_CNT -+ -+ -+/// Definition of the IPC Host environment structure. -+struct usb_host_env_tag { -+ // Index used that points to the first free TX desc -+ uint32_t txdesc_free_idx[USB_TXQUEUE_CNT]; -+ // Index used that points to the first used TX desc -+ uint32_t txdesc_used_idx[USB_TXQUEUE_CNT]; -+ // Array storing the currently pushed host ids, per IPC queue -+ uint64_t tx_host_id[USB_TXQUEUE_CNT][USB_TXDESC_CNT]; -+ -+ /// Pointer to the attached object (used in callbacks and register accesses) -+ void *pthis; -+}; -+ -+extern void aicwf_usb_host_init(struct usb_host_env_tag *env, -+ void *cb, void *shared_env_ptr, void *pthis); -+ -+extern void aicwf_usb_host_txdesc_push(struct usb_host_env_tag *env, const int queue_idx, const uint64_t host_id); -+ -+extern void aicwf_usb_host_tx_cfm_handler(struct usb_host_env_tag *env, u32 *data); -+extern int aicwf_rwnx_usb_platform_init(struct aic_usb_dev *usbdev); -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/.gitignore linux-6.9.4/drivers/net/wireless/aic8800_sdio/.gitignore ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/.gitignore 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/.gitignore 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,5 @@ -+*.symvers -+*.order -+*.symvers.cmd -+*.order.cmd -+.tmp_versions/ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/Kconfig linux-6.9.4/drivers/net/wireless/aic8800_sdio/Kconfig ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/Kconfig 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,18 @@ -+config AIC_WLAN_SUPPORT -+ bool "AIC wireless Support" -+ default n -+ help -+ This is support for aic wireless chip. -+ -+config AIC_FW_PATH -+ depends on AIC_WLAN_SUPPORT -+ string "Firmware & config file path" -+ default "/vendor/etc/firmware" -+ #default "/lib/firmware/aic8800_sdio" -+ help -+ Path to the firmware & config file. -+ -+if AIC_WLAN_SUPPORT -+source "drivers/net/wireless/aic8800/aic8800_fdrv/Kconfig" -+source "drivers/net/wireless/aic8800/aic8800_btlpm/Kconfig" -+endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/aic8800_sdio/Makefile linux-6.9.4/drivers/net/wireless/aic8800_sdio/Makefile ---- linux-6.9.4/drivers/net/wireless/aic8800_sdio/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.9.4/drivers/net/wireless/aic8800_sdio/Makefile 2024-06-14 03:58:38.000000000 +0200 -@@ -0,0 +1,91 @@ -+CONFIG_AIC8800_BTLPM_SUPPORT := m -+CONFIG_AIC8800_WLAN_SUPPORT := m -+CONFIG_AIC_WLAN_SUPPORT := m -+ -+obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) += aic8800_btlpm/ -+obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/ -+obj-$(CONFIG_AIC_WLAN_SUPPORT) += aic8800_bsp/ -+ -+MAKEFLAGS +=-j$(shell nproc) -+ -+########## config option ########## -+export CONFIG_USE_FW_REQUEST = n -+export CONFIG_PREALLOC_RX_SKB = n -+export CONFIG_PREALLOC_TXQ = y -+export CONFIG_OOB = n -+export CONFIG_GPIO_WAKEUP = n -+export CONFIG_RESV_MEM_SUPPORT = y -+################################### -+ -+########## Platform support list ########## -+export CONFIG_PLATFORM_ROCKCHIP = n -+export CONFIG_PLATFORM_ROCKCHIP2 = n -+export CONFIG_PLATFORM_ALLWINNER = n -+export CONFIG_PLATFORM_AMLOGIC = n -+export CONFIG_PLATFORM_UBUNTU = y -+ -+ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y) -+ARCH = arm64 -+KDIR = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel -+CROSS_COMPILE = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -+ccflags-y += -DANDROID_PLATFORM -+ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP -+endif -+ -+ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y) -+KDIR := /home/yaya/E/Rockchip/3126/Android6/kernel -+ARCH ?= arm -+CROSS_COMPILE ?= /home/yaya/E/Rockchip/3288/Android5/rk3288_JHY/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- -+ccflags-y += -DANDROID_PLATFORM -+ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP2 -+endif -+ -+ifeq ($(CONFIG_PLATFORM_ALLWINNER), y) -+KDIR = /home/yaya/E/Allwinner/A133/Android10/linux-4.9 -+ARCH = arm64 -+CROSS_COMPILE = /home/yaya/E/Allwinner/r818/Android10/lichee/out/gcc-linaro-5.3.1-2016.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -+export CONFIG_SUPPORT_LPM = y -+ccflags-y += -DANDROID_PLATFORM -+endif -+ -+ifeq ($(CONFIG_PLATFORM_AMLOGIC), y) -+ARCH = arm -+CROSS_COMPILE = /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androidkernel- -+KDIR = /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/out/target/product/u202/obj/KERNEL_OBJ/ -+ccflags-y += -DANDROID_PLATFORM -+export CONFIG_SUPPORT_LPM = y -+endif -+ -+ifeq ($(CONFIG_PLATFORM_UBUNTU), y) -+KDIR = /lib/modules/$(shell uname -r)/build -+PWD = $(shell pwd) -+KVER = $(shell uname -r) -+MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800 -+ARCH = x86_64 -+CROSS_COMPILE ?= -+endif -+########################################### -+ -+all: modules -+modules: -+ make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules -+ -+install: -+ mkdir -p $(MODDESTDIR) -+ install -p -m 644 aic8800_bsp/aic8800_bsp.ko $(MODDESTDIR)/ -+ install -p -m 644 aic8800_fdrv/aic8800_fdrv.ko $(MODDESTDIR)/ -+ install -p -m 644 aic8800_btlpm/aic8800_btlpm.ko $(MODDESTDIR)/ -+ /sbin/depmod -a ${KVER} -+ -+uninstall: -+ rm -rfv $(MODDESTDIR)/aic8800_bsp.ko -+ rm -rfv $(MODDESTDIR)/aic8800_fdrv.ko -+ rm -rfv $(MODDESTDIR)/aic8800_btlpm.ko -+ /sbin/depmod -a ${KVER} -+ -+clean: -+ cd aic8800_bsp/;make clean;cd .. -+ cd aic8800_fdrv/;make clean;cd .. -+ cd aic8800_btlpm/;make clean;cd .. -+ rm -rf modules.order Module.symvers .modules.order.cmd .Module.symvers.cmd .tmp_versions/ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/Kconfig linux-6.9.4/drivers/net/wireless/Kconfig ---- linux-6.9.4/drivers/net/wireless/Kconfig 2024-06-14 17:05:16.121340851 +0200 -+++ linux-6.9.4/drivers/net/wireless/Kconfig 2024-06-14 17:02:21.148011271 +0200 -@@ -37,6 +37,7 @@ - source "drivers/net/wireless/ti/Kconfig" - source "drivers/net/wireless/zydas/Kconfig" - source "drivers/net/wireless/quantenna/Kconfig" -+source "drivers/net/wireless/aic8800_sdio/Kconfig" - - source "drivers/net/wireless/virtual/Kconfig" - -diff --speed-large-files --no-dereference --minimal -Naur linux-6.9.4/drivers/net/wireless/Makefile linux-6.9.4/drivers/net/wireless/Makefile ---- linux-6.9.4/drivers/net/wireless/Makefile 2024-06-14 17:05:16.121340851 +0200 -+++ linux-6.9.4/drivers/net/wireless/Makefile 2024-06-14 17:02:21.148011271 +0200 -@@ -22,5 +22,6 @@ - obj-$(CONFIG_WLAN_VENDOR_ST) += st/ - obj-$(CONFIG_WLAN_VENDOR_TI) += ti/ - obj-$(CONFIG_WLAN_VENDOR_ZYDAS) += zydas/ -+obj-$(CONFIG_AIC_SDIO_WLAN_SUPPORT) += aic8800_sdio/ - - obj-$(CONFIG_WLAN) += virtual/ diff --git a/patch/kernel/archive/sunxi-dev-6.14/0802-net-wireless-mm2-fixes-aic8800-sdio-v2024_0327_3561b08f.patch b/patch/kernel/archive/sunxi-dev-6.14/0802-net-wireless-mm2-fixes-aic8800-sdio-v2024_0327_3561b08f.patch deleted file mode 100644 index 50bc0aa79..000000000 --- a/patch/kernel/archive/sunxi-dev-6.14/0802-net-wireless-mm2-fixes-aic8800-sdio-v2024_0327_3561b08f.patch +++ /dev/null @@ -1,388 +0,0 @@ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.c linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.c ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.c 2024-11-03 17:06:15.410016386 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_driver.c 2024-11-03 17:04:11.540015950 +0100 -@@ -472,7 +472,7 @@ - #endif - - #define MD5(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15] --#define MD5PINRT "file md5:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\r\n" -+#define MD5PINRT "file md5:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" - - int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *device) - { -@@ -1489,15 +1489,15 @@ - *(data + 15) = aicbt_info[sdiodev->chipid].lpm_enable; - *(data + 17) = aicbt_info[sdiodev->chipid].txpwr_lvl; - -- printk("%s bt btmode[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].btmode); -- printk("%s bt uart_baud[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].uart_baud); -- printk("%s bt uart_flowctrl[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].uart_flowctrl); -- printk("%s bt lpm_enable[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].lpm_enable); -- printk("%s bt tx_pwr[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].txpwr_lvl); -+ printk("%s bt btmode[%d]:%d", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].btmode); -+ printk("%s bt uart_baud[%d]:%d", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].uart_baud); -+ printk("%s bt uart_flowctrl[%d]:%d", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].uart_flowctrl); -+ printk("%s bt lpm_enable[%d]:%d", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].lpm_enable); -+ printk("%s bt tx_pwr[%d]:%d", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].txpwr_lvl); - } - - if (AICBT_PT_VER == p->type) { -- printk("aicbsp: bt patch version: %s\n", (char *)p->data); -+ printk("aicbsp: bt patch version: %s", (char *)p->data); - continue; - } - -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_main.c linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_main.c ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_main.c 2024-11-03 17:06:15.410016386 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_bsp/aic_bsp_main.c 2024-11-03 17:04:11.540015950 +0100 -@@ -15,7 +15,8 @@ - #define DRV_AUTHOR "AICSemi" - #define DRV_VERS_MOD "1.0" - --int aicwf_dbg_level_bsp = LOGERROR|LOGINFO|LOGDEBUG|LOGTRACE; -+//int aicwf_dbg_level_bsp = LOGERROR|LOGINFO|LOGDEBUG|LOGTRACE; -+int aicwf_dbg_level_bsp = LOGERROR; - - static struct platform_device *aicbsp_pdev; - -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.c linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.c ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.c 2024-11-03 17:06:15.420016386 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_btlpm/lpm.c 2024-11-03 17:04:11.540015950 +0100 -@@ -769,6 +769,16 @@ - } - #endif - -+enum of_gpio_flags { -+ OF_GPIO_ACTIVE_LOW = 0x1, -+ OF_GPIO_SINGLE_ENDED = 0x2, -+ OF_GPIO_OPEN_DRAIN = 0x4, -+ OF_GPIO_TRANSITORY = 0x8, -+ OF_GPIO_PULL_UP = 0x10, -+ OF_GPIO_PULL_DOWN = 0x20, -+ OF_GPIO_PULL_DISABLE = 0x40, -+}; -+ - static int bluesleep_probe(struct platform_device *pdev) - { - #if 1 -@@ -783,7 +793,7 @@ - if (!bsi) - return -ENOMEM; - -- bsi->host_wake = of_get_named_gpio_flags(np, "bt_hostwake", 0, &config); -+ bsi->host_wake = of_get_named_gpio(np, "bt_hostwake", 0); - if (!gpio_is_valid(bsi->host_wake)) { - BT_ERR("get gpio bt_hostwake failed\n"); - ret = -EINVAL; -@@ -791,7 +801,7 @@ - } - - /* set host_wake_assert */ -- bsi->host_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 0 : 1; -+ bsi->host_wake_assert = (config == GPIOF_ACTIVE_LOW) ? 0 : 1; - BT_DBG("bt_hostwake gpio=%d assert=%d\n", bsi->host_wake, bsi->host_wake_assert); - - if (assert_level != -1) { -@@ -838,7 +848,7 @@ - #endif - } - -- bsi->ext_wake = of_get_named_gpio_flags(np, "bt_wake", 0, &config); -+ bsi->ext_wake = of_get_named_gpio(np, "bt_wake", 0); - if (!gpio_is_valid(bsi->ext_wake)) { - BT_ERR("get gpio bt_wake failed\n"); - ret = -EINVAL; -@@ -911,11 +921,11 @@ - return 0; - - err3: -- devm_gpio_free(dev, bsi->ext_wake); -+ //todo devm_gpio_free(dev, bsi->ext_wake); - err2: - device_init_wakeup(dev, false); - err1: -- devm_gpio_free(dev, bsi->host_wake); -+ //todo devm_gpio_free(dev, bsi->host_wake); - err0: - devm_kfree(dev, bsi); - -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.c linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.c ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.c 2024-11-03 17:06:15.423349720 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/aicwf_sdio.c 2024-11-03 17:04:11.540015950 +0100 -@@ -529,15 +529,15 @@ - - if(vid == SDIO_VENDOR_ID_AIC8801 && did == SDIO_DEVICE_ID_AIC8801){ - sdio_dev->chipid = PRODUCT_ID_AIC8801; -- AICWFDBG(LOGINFO, "%s USE AIC8801\r\n", __func__); -+ AICWFDBG(LOGINFO, "%s USE AIC8801\r", __func__); - return 0; - }else if(vid == SDIO_VENDOR_ID_AIC8800DC && did == SDIO_DEVICE_ID_AIC8800DC){ - sdio_dev->chipid = PRODUCT_ID_AIC8800DC; -- AICWFDBG(LOGINFO, "%s USE AIC8800DC\r\n", __func__); -+ AICWFDBG(LOGINFO, "%s USE AIC8800DC\r", __func__); - return 0; - }else if(vid == SDIO_VENDOR_ID_AIC8800D80 && did == SDIO_DEVICE_ID_AIC8800D80){ - sdio_dev->chipid = PRODUCT_ID_AIC8800D80; -- AICWFDBG(LOGINFO, "%s USE AIC8800D80\r\n", __func__); -+ AICWFDBG(LOGINFO, "%s USE AIC8800D80\r", __func__); - return 0; - }else{ - return -1; -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Makefile linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Makefile ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Makefile 2024-11-03 17:06:15.423349720 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Makefile 2024-11-03 17:04:11.540015950 +0100 -@@ -132,7 +132,7 @@ - - # extra DEBUG config - CONFIG_RWNX_SW_PROFILING ?= n --CONFIG_RWNX_DBG ?= y -+CONFIG_RWNX_DBG ?= n - CONFIG_DEBUG_FS ?= n - - obj-$(CONFIG_AIC8800_WLAN_SUPPORT) := $(MODULE_NAME).o -@@ -203,6 +203,8 @@ - ccflags-y += -DNX_TX_MAX_RATES=4 - ccflags-y += -DNX_CHAN_CTXT_CNT=3 - -+ccflags-y += -Wno-incompatible-pointer-types -+ - # FW ARCH: - ccflags-$(CONFIG_RWNX_SDM) += -DCONFIG_RWNX_SDM - ccflags-$(CONFIG_RWNX_TL4) += -DCONFIG_RWNX_TL4 -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.c linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.c ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.c 2024-11-03 17:06:15.426683053 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_main.c 2024-11-03 17:04:11.540015950 +0100 -@@ -510,7 +510,8 @@ - - - extern uint8_t scanning; --int aicwf_dbg_level = LOGERROR|LOGINFO|LOGDEBUG|LOGTRACE; -+//int aicwf_dbg_level = LOGERROR|LOGINFO|LOGDEBUG|LOGTRACE; -+int aicwf_dbg_level = LOGERROR; - module_param(aicwf_dbg_level, int, 0660); - int testmode = 0; - char aic_fw_path[200]; -@@ -770,7 +771,11 @@ - cfg80211_disconnected(vif->ndev, 0, NULL, 0, 0, GFP_KERNEL); - #endif - } else { -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)) -+ wiphy_lock(vif->wdev.wiphy); -+#else - mutex_lock(&vif->wdev.mtx); -+#endif - __acquire(&vif->wdev.mtx); - spin_lock_bh(&rwnx_hw->cb_lock); - rwnx_chanctx_unlink(vif); -@@ -782,13 +787,17 @@ - rwnx_txq_vif_stop(vif, RWNX_TXQ_STOP_CHAN, rwnx_hw); - spin_unlock_bh(&rwnx_hw->cb_lock); - #if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION3) -- cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0, 0); -+ cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0); - #elif (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION) - cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0); - #else - cfg80211_ch_switch_notify(vif->ndev, &csa->chandef); - #endif -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)) -+ wiphy_lock(vif->wdev.wiphy); -+#else - mutex_unlock(&vif->wdev.mtx); -+#endif - __release(&vif->wdev.mtx); - } - rwnx_del_csa(vif); -@@ -3013,10 +3022,11 @@ - bool found = false; - list_for_each_entry(master_vif, &rwnx_hw->vifs, list) { - if ((RWNX_VIF_TYPE(master_vif) == NL80211_IFTYPE_AP) && -- !(!memcmp(master_vif->ndev->dev_addr, params->macaddr, -- ETH_ALEN))) { -- found = true; -- break; -+ !(!memcmp(master_vif->ndev->dev_addr, params->macaddr, ETH_ALEN))) -+ { -+ memcmp(master_vif->ndev->dev_addr_shadow, params->macaddr, ETH_ALEN); -+ found = true; -+ break; - } - } - -@@ -5561,7 +5571,7 @@ - } else { - INIT_WORK(&csa->work, rwnx_csa_finish); - #if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION4 -- cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false, 0); -+ cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false); - #elif LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2 - cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false); - #elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) -@@ -6565,8 +6575,8 @@ - .tdls_channel_switch = rwnx_cfg80211_tdls_channel_switch, - .tdls_cancel_channel_switch = rwnx_cfg80211_tdls_cancel_channel_switch, - #endif -- .tdls_mgmt = rwnx_cfg80211_tdls_mgmt, -- .tdls_oper = rwnx_cfg80211_tdls_oper, -+ //todo .tdls_mgmt = rwnx_cfg80211_tdls_mgmt, -+ //todo .tdls_oper = rwnx_cfg80211_tdls_oper, - .change_bss = rwnx_cfg80211_change_bss, - #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL) - .external_auth = rwnx_cfg80211_external_auth, -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.c linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.c ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.c 2024-11-03 17:06:15.430016386 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_mod_params.c 2024-11-03 17:04:11.540015950 +0100 -@@ -1546,9 +1546,6 @@ - // function, that needs to be called after wiphy registration - memcpy(country_code, default_ccode, sizeof(default_ccode)); - regdomain = getRegdomainFromRwnxDB(wiphy, default_ccode); -- printk(KERN_CRIT -- "\n\n%s: CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES\n\n", -- __func__); - wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; - wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; - wiphy_apply_custom_regulatory(wiphy, regdomain); -@@ -1580,9 +1577,6 @@ - // Apply custom regulatory. Note that for recent kernel versions we use instead the - // REGULATORY_WIPHY_SELF_MANAGED flag, along with the regulatory_set_wiphy_regd() - // function, that needs to be called after wiphy registration -- printk(KERN_CRIT -- "\n\n%s: CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES\n\n", -- __func__); - wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; - wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; - wiphy_apply_custom_regulatory(wiphy, &rwnx_regdom); -@@ -1725,11 +1719,15 @@ - // For older kernel version, the custom regulatory is applied before the wiphy - // registration (in rwnx_set_wiphy_params()), so nothing has to be done here - #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) -- if (!rwnx_hw->mod_params->custregd) -- return; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) -+ // nop -+#else -+ wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; -+#endif -+ wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED; - -- wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; -- wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED; -+ if (!rwnx_hw->mod_params->custregd) -+ return; - - rtnl_lock(); - #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) -@@ -1743,10 +1741,7 @@ - #endif - - else{ -- wiphy_err(wiphy,"\n" -- "*******************************************************\n" -- "** CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES **\n" -- "*******************************************************\n"); -+ // - } - rtnl_unlock(); - #endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.c linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.c ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.c 2024-11-03 17:06:15.430016386 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_platform.c 2024-11-03 17:04:11.540015950 +0100 -@@ -271,7 +271,7 @@ - #endif - - #define MD5(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15] --#define MD5PINRT "file md5:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\r\n" -+#define MD5PINRT "file md5:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" - - static int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *device) - { -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.c linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.c ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.c 2024-11-03 17:06:15.430016386 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_radar.c 2024-11-03 16:42:50.616678220 +0100 -@@ -1399,7 +1399,7 @@ - #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) - &ctxt->chan_def, - #endif -- NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); -+ NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0); - rwnx_send_apm_stop_cac_req(rwnx_hw, radar->cac_vif); - rwnx_chanctx_unlink(radar->cac_vif); - -@@ -1499,7 +1499,7 @@ - #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) - &ctxt->chan_def, - #endif -- NL80211_RADAR_CAC_ABORTED, GFP_KERNEL); -+ NL80211_RADAR_CAC_ABORTED, GFP_KERNEL, 0); - rwnx_chanctx_unlink(radar->cac_vif); - } - -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version.h linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version.h ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version.h 2024-11-03 17:06:15.433349720 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/aic8800_fdrv/rwnx_version.h 2024-11-03 17:04:11.540015950 +0100 -@@ -6,7 +6,7 @@ - static inline void rwnx_print_version(void) - { - AICWFDBG(LOGINFO, RWNX_VERS_BANNER"\n"); -- AICWFDBG(LOGINFO, "RELEASE_DATE:%s \r\n", RELEASE_DATE); -+ AICWFDBG(LOGINFO, "RELEASE_DATE:%s \r", RELEASE_DATE); - } - - #endif /* _RWNX_VERSION_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/.gitignore linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/.gitignore ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/.gitignore 2024-11-03 17:06:15.433349720 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/.gitignore 1970-01-01 01:00:00.000000000 +0100 -@@ -1,5 +0,0 @@ --*.symvers --*.order --*.symvers.cmd --*.order.cmd --.tmp_versions/ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/Kconfig linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/Kconfig ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/Kconfig 2024-11-03 17:06:15.433349720 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/Kconfig 2024-11-03 17:04:11.540015950 +0100 -@@ -1,18 +1,17 @@ --config AIC_WLAN_SUPPORT -- bool "AIC wireless Support" -+config AIC_SDIO_WLAN_SUPPORT -+ bool "AIC 8800 SDIO wireless Support" - default n - help -- This is support for aic wireless chip. -+ This is support for aic 8800 wireless chip with SDIO interface. - - config AIC_FW_PATH -- depends on AIC_WLAN_SUPPORT -+ depends on AIC_SDIO_WLAN_SUPPORT - string "Firmware & config file path" -- default "/vendor/etc/firmware" -- #default "/lib/firmware/aic8800_sdio" -+ default "/lib/firmware/aic8800_sdio" - help - Path to the firmware & config file. - --if AIC_WLAN_SUPPORT --source "drivers/net/wireless/aic8800/aic8800_fdrv/Kconfig" --source "drivers/net/wireless/aic8800/aic8800_btlpm/Kconfig" -+if AIC_SDIO_WLAN_SUPPORT -+source "drivers/net/wireless/aic8800_sdio/aic8800_fdrv/Kconfig" -+source "drivers/net/wireless/aic8800_sdio/aic8800_btlpm/Kconfig" - endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/Makefile linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/Makefile ---- linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/Makefile 2024-11-03 17:06:15.433349720 +0100 -+++ linux-6.12-rc5/drivers/net/wireless/aic8800_sdio/Makefile 2024-11-03 17:04:11.543349283 +0100 -@@ -1,12 +1,10 @@ - CONFIG_AIC8800_BTLPM_SUPPORT := m - CONFIG_AIC8800_WLAN_SUPPORT := m --CONFIG_AIC_WLAN_SUPPORT := m -+CONFIG_AIC_SDIO_WLAN_SUPPORT := m - - obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) += aic8800_btlpm/ - obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/ --obj-$(CONFIG_AIC_WLAN_SUPPORT) += aic8800_bsp/ -- --MAKEFLAGS +=-j$(shell nproc) -+obj-$(CONFIG_AIC_SDIO_WLAN_SUPPORT) += aic8800_bsp/ - - ########## config option ########## - export CONFIG_USE_FW_REQUEST = n diff --git a/patch/kernel/archive/sunxi-dev-6.14/1103-mfd-axp20x-Allow-multiple-regulators.patch b/patch/kernel/archive/sunxi-dev-6.14/1103-mfd-axp20x-Allow-multiple-regulators.patch deleted file mode 100644 index 7fd333498..000000000 --- a/patch/kernel/archive/sunxi-dev-6.14/1103-mfd-axp20x-Allow-multiple-regulators.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 12045a9ab272974528afea72781f5308c662a1d0 Mon Sep 17 00:00:00 2001 -From: Andre Przywara -Date: Tue, 1 Oct 2024 22:28:41 +0100 -Subject: [PATCH 03/37] mfd: axp20x: Allow multiple regulators - -At the moment trying to register a second AXP chip makes the probe fail, -as some sysfs registration fails due to a duplicate name: - -... -[ 3.688215] axp20x-i2c 0-0035: AXP20X driver loaded -[ 3.695610] axp20x-i2c 0-0036: AXP20x variant AXP323 found -[ 3.706151] sysfs: cannot create duplicate filename '/bus/platform/devices/axp20x-regulator' -[ 3.714718] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.12.0-rc1-00026-g50bf2e2c079d-dirty #192 -[ 3.724020] Hardware name: Avaota A1 (DT) -[ 3.728029] Call trace: -[ 3.730477] dump_backtrace+0x94/0xec -[ 3.734146] show_stack+0x18/0x24 -[ 3.737462] dump_stack_lvl+0x80/0xf4 -[ 3.741128] dump_stack+0x18/0x24 -[ 3.744444] sysfs_warn_dup+0x64/0x80 -[ 3.748109] sysfs_do_create_link_sd+0xf0/0xf8 -[ 3.752553] sysfs_create_link+0x20/0x40 -[ 3.756476] bus_add_device+0x64/0x104 -[ 3.760229] device_add+0x310/0x760 -[ 3.763717] platform_device_add+0x10c/0x238 -[ 3.767990] mfd_add_device+0x4ec/0x5c8 -[ 3.771829] mfd_add_devices+0x88/0x11c -[ 3.775666] axp20x_device_probe+0x70/0x184 -[ 3.779851] axp20x_i2c_probe+0x9c/0xd8 -... - -This is because we use PLATFORM_DEVID_NONE for the mfd_add_devices() -call, which would number the child devices in the same 0-based way, even -for the second (or any other) instance. - -Use PLATFORM_DEVID_AUTO instead, which automatically assigns -non-conflicting device numbers. - -Signed-off-by: Andre Przywara -Reviewed-by: Chen-Yu Tsai ---- - drivers/mfd/axp20x.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c -index 5ceea359289..bc08ae43326 100644 ---- a/drivers/mfd/axp20x.c -+++ b/drivers/mfd/axp20x.c -@@ -1419,7 +1419,7 @@ int axp20x_device_probe(struct axp20x_dev *axp20x) - } - } - -- ret = mfd_add_devices(axp20x->dev, PLATFORM_DEVID_NONE, axp20x->cells, -+ ret = mfd_add_devices(axp20x->dev, PLATFORM_DEVID_AUTO, axp20x->cells, - axp20x->nr_cells, NULL, 0, NULL); - - if (ret) { --- -2.46.0 - diff --git a/patch/kernel/archive/sunxi-dev-6.14/1137-net-phy-add-Maxio-MAE0621A-phy-driver.patch b/patch/kernel/archive/sunxi-dev-6.14/1137-net-phy-add-Maxio-MAE0621A-phy-driver.patch deleted file mode 100644 index cda59311d..000000000 --- a/patch/kernel/archive/sunxi-dev-6.14/1137-net-phy-add-Maxio-MAE0621A-phy-driver.patch +++ /dev/null @@ -1,368 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: John Doe -Date: Sat, 15 Mar 2025 00:57:55 -0300 -Subject: [PATCH] Add Maxio MAE0621A PHY driver - -Signed-off-by: John Doe ---- - drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 + - drivers/net/phy/Kconfig | 5 + - drivers/net/phy/Makefile | 1 + - drivers/net/phy/maxio.c | 254 ++++++++++ - drivers/net/phy/phy_device.c | 9 + - 5 files changed, 274 insertions(+) - -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index d04543e5697b..c8cf84fa4091 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -7826,10 +7826,11 @@ int stmmac_suspend(struct device *dev) - - priv->speed = SPEED_UNKNOWN; - return 0; - } - EXPORT_SYMBOL_GPL(stmmac_suspend); -+#define MAXIO_PHY_MAE0621A_ID 0x7b744411 - - static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue) - { - struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - -@@ -7922,10 +7923,14 @@ int stmmac_resume(struct device *dev) - - stmmac_reset_queues_param(priv); - - stmmac_free_tx_skbufs(priv); - stmmac_clear_descriptors(priv, &priv->dma_conf); -+ if (ndev->phydev->drv->config_init) { -+ if (ndev->phydev->phy_id == MAXIO_PHY_MAE0621A_ID) -+ ndev->phydev->drv->config_init(ndev->phydev); -+ } - - stmmac_hw_setup(ndev, false); - stmmac_init_coalesce(priv); - stmmac_set_rx_mode(ndev); - -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index 41c15a2c2037..6a5de0ce5723 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -360,10 +360,15 @@ config RENESAS_PHY - config ROCKCHIP_PHY - tristate "Rockchip Ethernet PHYs" - help - Currently supports the integrated Ethernet PHY. - -+config MAXIO_PHY -+ tristate "Maxio PHYs" -+ help -+ Supports the Maxio MAExxxx PHY. -+ - config SMSC_PHY - tristate "SMSC PHYs" - select CRC16 - help - Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index c8dac6e92278..2bdde53a3885 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -94,10 +94,11 @@ obj-$(CONFIG_NXP_C45_TJA11XX_PHY) += nxp-c45-tja.o - obj-$(CONFIG_NXP_CBTX_PHY) += nxp-cbtx.o - obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o - obj-y += qcom/ - obj-$(CONFIG_QSEMI_PHY) += qsemi.o - obj-$(CONFIG_REALTEK_PHY) += realtek/ -+obj-$(CONFIG_MAXIO_PHY) += maxio.o - obj-$(CONFIG_RENESAS_PHY) += uPD60620.o - obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o - obj-$(CONFIG_SMSC_PHY) += smsc.o - obj-$(CONFIG_STE10XP) += ste10Xp.o - obj-$(CONFIG_TERANETICS_PHY) += teranetics.o -diff --git a/drivers/net/phy/maxio.c b/drivers/net/phy/maxio.c -new file mode 100644 -index 000000000000..fd227e86794f ---- /dev/null -+++ b/drivers/net/phy/maxio.c -@@ -0,0 +1,254 @@ -+/* -+ * drivers/net/phy/maxio.c -+ * -+ * Driver for maxio PHYs -+ * -+ * Author: zhao yang -+ * -+ * Copyright (c) 2004 maxio technology, Inc. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAXIO_PAGE_SELECT 0x1f -+#define MAXIO_MAE0621A_INER 0x12 -+#define MAXIO_MAE0621A_INER_LINK_STATUS BIT(4) -+#define MAXIO_MAE0621A_INSR 0x1d -+#define MAXIO_MAE0621A_TX_DELAY (BIT(6)|BIT(7)) -+#define MAXIO_MAE0621A_RX_DELAY (BIT(4)|BIT(5)) -+#define MAXIO_MAE0621A_CLK_MODE_REG 0x02 -+#define MAXIO_MAE0621A_WORK_STATUS_REG 0x1d -+ -+ -+static int maxio_read_paged(struct phy_device *phydev, int page, u32 regnum) -+{ -+ int ret = 0, oldpage; -+ -+ oldpage = phy_read(phydev, MAXIO_PAGE_SELECT); -+ if (oldpage >= 0) { -+ phy_write(phydev, MAXIO_PAGE_SELECT, page); -+ ret = phy_read(phydev, regnum); -+ } -+ phy_write(phydev, MAXIO_PAGE_SELECT, oldpage); -+ -+ return ret; -+} -+ -+static int maxio_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val) -+{ -+ int ret = 0, oldpage; -+ -+ oldpage = phy_read(phydev, MAXIO_PAGE_SELECT); -+ if (oldpage >= 0) { -+ phy_write(phydev, MAXIO_PAGE_SELECT, page); -+ ret = phy_write(phydev, regnum, val); -+ } -+ phy_write(phydev, MAXIO_PAGE_SELECT, oldpage); -+ -+ return ret; -+} -+ -+static int maxio_mae0621a_clk_init(struct phy_device *phydev) -+{ -+ u32 workmode,clkmode,oldpage; -+ -+ oldpage = phy_read(phydev, MAXIO_PAGE_SELECT); -+ if (oldpage == 0xFFFF) { -+ oldpage = phy_read(phydev, MAXIO_PAGE_SELECT); -+ } -+ -+ //soft reset -+ phy_write(phydev, MAXIO_PAGE_SELECT, 0x0); -+ phy_write(phydev, MII_BMCR, BMCR_RESET | phy_read(phydev, MII_BMCR)); -+ -+ //get workmode -+ phy_write(phydev, MAXIO_PAGE_SELECT, 0xa43); -+ workmode = phy_read(phydev, MAXIO_MAE0621A_WORK_STATUS_REG); -+ -+ //get clkmode -+ phy_write( phydev, MAXIO_PAGE_SELECT, 0xd92 ); -+ clkmode = phy_read( phydev, MAXIO_MAE0621A_CLK_MODE_REG ); -+ -+ //abnormal -+ if (0 == (workmode&BIT(5))) { -+ if (0 == (clkmode&BIT(8))) { -+ //oscillator -+ phy_write(phydev, 0x02, clkmode | BIT(8)); -+ printk("****maxio_mae0621a_clk_init**clkmode**0x210a: 0x%x\n", phydev->phy_id); -+ } else { -+ //crystal -+ printk("****maxio_mae0621a_clk_init**clkmode**0x200a: 0x%x\n", phydev->phy_id); -+ phy_write(phydev, 0x02, clkmode &(~ BIT(8))); -+ } -+ } -+ phy_write(phydev, MAXIO_PAGE_SELECT, 0x0); -+ -+ phy_write(phydev, MAXIO_PAGE_SELECT, oldpage); -+ -+ return 0; -+} -+ -+static int maxio_read_mmd(struct phy_device *phydev, int devnum, u16 regnum) -+{ -+ int ret = 0, oldpage; -+ oldpage = phy_read(phydev, MAXIO_PAGE_SELECT); -+ -+ if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {// eee info -+ phy_write(phydev, MAXIO_PAGE_SELECT ,0); -+ phy_write(phydev, 0xd, MDIO_MMD_AN); -+ phy_write(phydev, 0xe, MDIO_AN_EEE_ADV); -+ phy_write(phydev, 0xd, 0x4000 | MDIO_MMD_AN); -+ ret = phy_read(phydev, 0x0e); -+ } else { -+ ret = -EOPNOTSUPP; -+ } -+ phy_write(phydev, MAXIO_PAGE_SELECT, oldpage); -+ -+ return ret; -+} -+ -+static int maxio_write_mmd(struct phy_device *phydev, int devnum, u16 regnum, u16 val) -+{ -+ int ret = 0, oldpage; -+ oldpage = phy_read(phydev, MAXIO_PAGE_SELECT); -+ -+ if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) { // eee info -+ phy_write(phydev, MAXIO_PAGE_SELECT ,0); -+ ret |= phy_write(phydev, 0xd, MDIO_MMD_AN); -+ ret |= phy_write(phydev, 0xe, MDIO_AN_EEE_ADV); -+ ret |= phy_write(phydev, 0xd, 0x4000 | MDIO_MMD_AN); -+ ret |= phy_write(phydev, 0xe, val); -+ msleep(100); -+ ret |= genphy_restart_aneg(phydev); -+ } else { -+ ret = -EOPNOTSUPP; -+ } -+ phy_write(phydev, MAXIO_PAGE_SELECT, oldpage); -+ -+ return ret; -+} -+ -+static int maxio_mae0621a_config_aneg(struct phy_device *phydev) -+{ -+ return genphy_config_aneg(phydev); -+} -+ -+ -+static int maxio_mae0621a_config_init(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ u16 val; -+ int ret; -+ u32 broken = 0; -+ -+ maxio_mae0621a_clk_init(phydev); -+ -+ //disable eee -+ printk("eee value: 0x%x \n",maxio_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV)); -+ maxio_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0); -+ printk("eee value: 0x%x \n",maxio_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV)); -+ broken |= MDIO_EEE_100TX; -+ broken |= MDIO_EEE_1000T; -+ memcpy(phydev->eee_broken_modes, broken, sizeof(phydev->eee_broken_modes)); -+ -+ //enable auto_speed_down -+ ret = maxio_write_paged(phydev, 0xd8f, 0x0, 0x300 ); -+ -+ //adjust TX/RX delay -+ switch (phydev->interface) { -+ case PHY_INTERFACE_MODE_RGMII: -+ val = 0x0; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ val = MAXIO_MAE0621A_TX_DELAY | MAXIO_MAE0621A_RX_DELAY; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ val = MAXIO_MAE0621A_RX_DELAY; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ val = MAXIO_MAE0621A_TX_DELAY; -+ break; -+ default: /* the rest of the modes imply leaving delays as is. */ -+ goto delay_skip; -+ } -+ -+ ret = maxio_read_paged(phydev, 0xd96, 0x0); -+ if (ret < 0) { -+ dev_err(dev, "Failed to update the TX delay register\n"); -+ return ret; -+ } -+ -+ ret =maxio_write_paged(phydev, 0xd96, 0x0, val|ret ); -+ if (ret < 0) { -+ dev_err(dev, "Failed to update the TX delay register\n"); -+ return ret; -+ } else if (ret == 0) { -+ dev_dbg(dev, -+ "2ns delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n", -+ val ? "enabled" : "disabled"); -+ } -+delay_skip: -+ -+ phy_write(phydev, MII_BMCR, BMCR_RESET | phy_read(phydev, MII_BMCR)); -+ msleep(1); -+ phy_write(phydev, MAXIO_PAGE_SELECT, 0x0); -+ -+ return 0; -+} -+ -+ -+static int maxio_mae0621a_resume(struct phy_device *phydev) -+{ -+ int ret = genphy_resume(phydev); -+ -+ ret |= phy_write(phydev, MII_BMCR, BMCR_RESET | phy_read(phydev, MII_BMCR)); -+ -+ msleep(20); -+ -+ return ret; -+} -+ -+int maxio_mae0621a_suspend(struct phy_device *phydev) -+{ -+ genphy_suspend(phydev); -+ phy_write(phydev, MAXIO_PAGE_SELECT ,0); -+ -+ return 0; -+} -+ -+static int maxio_mae0621a_status(struct phy_device *phydev) -+{ -+ return genphy_read_status(phydev); -+} -+ -+static int maxio_mae0621a_probe(struct phy_device *phydev) -+{ -+ int ret = maxio_mae0621a_clk_init(phydev); -+ mdelay(100); -+ return ret; -+} -+ -+static struct phy_driver maxio_nc_drvs[] = { -+ { -+ .phy_id = 0x7b744411, -+ .phy_id_mask = 0x7fffffff, -+ .name = "MAE0621A Gigabit Ethernet", -+ .features = PHY_GBIT_FEATURES, -+ .probe = maxio_mae0621a_probe, -+ .config_init = maxio_mae0621a_config_init, -+ .config_aneg = maxio_mae0621a_config_aneg, -+ .read_status = maxio_mae0621a_status, -+ .suspend = maxio_mae0621a_suspend, -+ .resume = maxio_mae0621a_resume, -+ }, -+}; -+module_phy_driver(maxio_nc_drvs); -+ -+MODULE_DESCRIPTION("Maxio PHY driver"); -+MODULE_AUTHOR("Zhao Yang"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c -index 46713d27412b..1a9514360673 100644 ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -858,10 +858,19 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, - */ - static int get_phy_c22_id(struct mii_bus *bus, int addr, u32 *phy_id) - { - int phy_reg; - -+#ifdef CONFIG_MAXIO_PHY -+ /* -+ *An MDIO connects to multiple PHYs requiring write before read. -+ *This operation does not affect one MDIO connected to a single PHY -+ *MII_PHYSID2 is a read-only register and writine to it has no effect -+ */ -+ mdiobus_write(bus,addr,MII_PHYSID2,0); -+#endif -+ - /* Grab the bits from PHYIR1, and put them in the upper half */ - phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); - if (phy_reg < 0) { - /* returning -ENODEV doesn't stop bus scanning */ - return (phy_reg == -EIO || phy_reg == -ENODEV) ? -ENODEV : -EIO; --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/archive/sunxi-dev-6.14/1139-net-ethernet-allwinner-add-gmac200-support.patch b/patch/kernel/archive/sunxi-dev-6.14/1139-net-ethernet-allwinner-add-gmac200-support.patch deleted file mode 100644 index 99f67bc5e..000000000 --- a/patch/kernel/archive/sunxi-dev-6.14/1139-net-ethernet-allwinner-add-gmac200-support.patch +++ /dev/null @@ -1,3238 +0,0 @@ - -Code is backport from BSP kernel - -Signed-off-by: Piotr Oniszczuk - -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi.c linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi.c ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi.c 2025-01-21 15:58:05.577494134 +0100 -@@ -0,0 +1,829 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* Copyright(c) 2020 - 2023 Allwinner Technology Co.,Ltd. All rights reserved. */ -+/* -+* Allwinner DWMAC driver. -+* -+* Copyright(c) 2022-2027 Allwinnertech Co., Ltd. -+* -+* 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. -+*/ -+#define SUNXI_MODNAME "stmmac" -+#include "sunxi-log.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "stmmac/stmmac.h" -+#include "stmmac/stmmac_platform.h" -+ -+#include "dwmac-sunxi.h" -+ -+#define DWMAC_MODULE_VERSION "0.3.0" -+ -+#define MAC_ADDR_LEN 18 -+#define SUNXI_DWMAC_MAC_ADDRESS "80:3f:5d:09:8b:26" -+#define MAC_IRQ_NAME 8 -+ -+static char mac_str[MAC_ADDR_LEN] = SUNXI_DWMAC_MAC_ADDRESS; -+module_param_string(mac_str, mac_str, MAC_ADDR_LEN, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(mac_str, "MAC Address String.(xx:xx:xx:xx:xx:xx)"); -+ -+//todo #ifdef MODULE -+//extern int get_custom_mac_address(int fmt, char *name, char *addr); -+//#endif -+ -+static int sunxi_dwmac200_set_syscon(struct sunxi_dwmac *chip) -+{ -+ u32 reg_val = 0; -+ -+ /* Clear interface mode bits */ -+ reg_val &= ~(SUNXI_DWMAC200_SYSCON_ETCS | SUNXI_DWMAC200_SYSCON_EPIT); -+ if (chip->variant->interface & PHY_INTERFACE_MODE_RMII) -+ reg_val &= ~SUNXI_DWMAC200_SYSCON_RMII_EN; -+ -+ switch (chip->interface) { -+ case PHY_INTERFACE_MODE_MII: -+ /* default */ -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ reg_val |= SUNXI_DWMAC200_SYSCON_EPIT; -+ reg_val |= FIELD_PREP(SUNXI_DWMAC200_SYSCON_ETCS, -+ chip->rgmii_clk_ext ? SUNXI_DWMAC_ETCS_EXT_GMII : SUNXI_DWMAC_ETCS_INT_GMII); -+ if (chip->rgmii_clk_ext) -+ sunxi_info(chip->dev, "RGMII use external transmit clock\n"); -+ else -+ sunxi_info(chip->dev, "RGMII use internal transmit clock\n"); -+ break; -+ case PHY_INTERFACE_MODE_RMII: -+ reg_val |= SUNXI_DWMAC200_SYSCON_RMII_EN; -+ reg_val &= ~SUNXI_DWMAC200_SYSCON_ETCS; -+ break; -+ default: -+ sunxi_err(chip->dev, "Unsupported interface mode: %s", phy_modes(chip->interface)); -+ return -EINVAL; -+ } -+ -+ writel(reg_val, chip->syscfg_base + SUNXI_DWMAC200_SYSCON_REG); -+ return 0; -+} -+ -+static int sunxi_dwmac200_set_delaychain(struct sunxi_dwmac *chip, enum sunxi_dwmac_delaychain_dir dir, u32 delay) -+{ -+ u32 reg_val = readl(chip->syscfg_base + SUNXI_DWMAC200_SYSCON_REG); -+ int ret = -EINVAL; -+ -+ switch (dir) { -+ case SUNXI_DWMAC_DELAYCHAIN_TX: -+ if (delay <= chip->variant->tx_delay_max) { -+ reg_val &= ~SUNXI_DWMAC200_SYSCON_ETXDC; -+ reg_val |= FIELD_PREP(SUNXI_DWMAC200_SYSCON_ETXDC, delay); -+ ret = 0; -+ } -+ break; -+ case SUNXI_DWMAC_DELAYCHAIN_RX: -+ if (delay <= chip->variant->rx_delay_max) { -+ reg_val &= ~SUNXI_DWMAC200_SYSCON_ERXDC; -+ reg_val |= FIELD_PREP(SUNXI_DWMAC200_SYSCON_ERXDC, delay); -+ ret = 0; -+ } -+ break; -+ } -+ -+ if (!ret) -+ writel(reg_val, chip->syscfg_base + SUNXI_DWMAC200_SYSCON_REG); -+ -+ return ret; -+} -+ -+static u32 sunxi_dwmac200_get_delaychain(struct sunxi_dwmac *chip, enum sunxi_dwmac_delaychain_dir dir) -+{ -+ u32 delay = 0; -+ u32 reg_val = readl(chip->syscfg_base + SUNXI_DWMAC200_SYSCON_REG); -+ -+ switch (dir) { -+ case SUNXI_DWMAC_DELAYCHAIN_TX: -+ delay = FIELD_GET(SUNXI_DWMAC200_SYSCON_ETXDC, reg_val); -+ break; -+ case SUNXI_DWMAC_DELAYCHAIN_RX: -+ delay = FIELD_GET(SUNXI_DWMAC200_SYSCON_ERXDC, reg_val); -+ break; -+ default: -+ sunxi_err(chip->dev, "Unknow delaychain dir %d\n", dir); -+ } -+ -+ return delay; -+} -+ -+static int sunxi_dwmac210_set_delaychain(struct sunxi_dwmac *chip, enum sunxi_dwmac_delaychain_dir dir, u32 delay) -+{ -+ u32 reg_val = readl(chip->syscfg_base + SUNXI_DWMAC210_CFG_REG); -+ int ret = -EINVAL; -+ -+ switch (dir) { -+ case SUNXI_DWMAC_DELAYCHAIN_TX: -+ if (delay <= chip->variant->tx_delay_max) { -+ reg_val &= ~(SUNXI_DWMAC210_CFG_ETXDC_H | SUNXI_DWMAC210_CFG_ETXDC_L); -+ reg_val |= FIELD_PREP(SUNXI_DWMAC210_CFG_ETXDC_H, delay >> 3); -+ reg_val |= FIELD_PREP(SUNXI_DWMAC210_CFG_ETXDC_L, delay); -+ ret = 0; -+ } -+ break; -+ case SUNXI_DWMAC_DELAYCHAIN_RX: -+ if (delay <= chip->variant->rx_delay_max) { -+ reg_val &= ~SUNXI_DWMAC210_CFG_ERXDC; -+ reg_val |= FIELD_PREP(SUNXI_DWMAC210_CFG_ERXDC, delay); -+ ret = 0; -+ } -+ break; -+ } -+ -+ if (!ret) -+ writel(reg_val, chip->syscfg_base + SUNXI_DWMAC210_CFG_REG); -+ -+ return ret; -+} -+ -+static u32 sunxi_dwmac210_get_delaychain(struct sunxi_dwmac *chip, enum sunxi_dwmac_delaychain_dir dir) -+{ -+ u32 delay = 0; -+ u32 tx_l, tx_h; -+ u32 reg_val = readl(chip->syscfg_base + SUNXI_DWMAC210_CFG_REG); -+ -+ switch (dir) { -+ case SUNXI_DWMAC_DELAYCHAIN_TX: -+ tx_h = FIELD_GET(SUNXI_DWMAC210_CFG_ETXDC_H, reg_val); -+ tx_l = FIELD_GET(SUNXI_DWMAC210_CFG_ETXDC_L, reg_val); -+ delay = (tx_h << 3 | tx_l); -+ break; -+ case SUNXI_DWMAC_DELAYCHAIN_RX: -+ delay = FIELD_GET(SUNXI_DWMAC210_CFG_ERXDC, reg_val); -+ break; -+ } -+ -+ return delay; -+} -+ -+static int sunxi_dwmac110_get_version(struct sunxi_dwmac *chip, u16 *ip_tag, u16 *ip_vrm) -+{ -+ u32 reg_val; -+ -+ if (!ip_tag || !ip_vrm) -+ return -EINVAL; -+ -+ reg_val = readl(chip->syscfg_base + SUNXI_DWMAC110_VERSION_REG); -+ *ip_tag = FIELD_GET(SUNXI_DWMAC110_VERSION_IP_TAG, reg_val); -+ *ip_vrm = FIELD_GET(SUNXI_DWMAC110_VERSION_IP_VRM, reg_val); -+ return 0; -+} -+ -+static int sunxi_dwmac_power_on(struct sunxi_dwmac *chip) -+{ -+ int ret; -+ -+ /* set dwmac pin bank voltage to 3.3v */ -+ if (!IS_ERR(chip->dwmac3v3_supply)) { -+ ret = regulator_set_voltage(chip->dwmac3v3_supply, 3300000, 3300000); -+ if (ret) { -+ sunxi_err(chip->dev, "Set dwmac3v3-supply voltage 3300000 failed %d\n", ret); -+ goto err_dwmac3v3; -+ } -+ -+ ret = regulator_enable(chip->dwmac3v3_supply); -+ if (ret) { -+ sunxi_err(chip->dev, "Enable dwmac3v3-supply failed %d\n", ret); -+ goto err_dwmac3v3; -+ } -+ } -+ -+ /* set phy voltage to 3.3v */ -+ if (!IS_ERR(chip->phy3v3_supply)) { -+ ret = regulator_set_voltage(chip->phy3v3_supply, 3300000, 3300000); -+ if (ret) { -+ sunxi_err(chip->dev, "Set phy3v3-supply voltage 3300000 failed %d\n", ret); -+ goto err_phy3v3; -+ } -+ -+ ret = regulator_enable(chip->phy3v3_supply); -+ if (ret) { -+ sunxi_err(chip->dev, "Enable phy3v3-supply failed\n"); -+ goto err_phy3v3; -+ } -+ } -+ -+ return 0; -+ -+err_phy3v3: -+ regulator_disable(chip->dwmac3v3_supply); -+err_dwmac3v3: -+ return ret; -+} -+ -+static void sunxi_dwmac_power_off(struct sunxi_dwmac *chip) -+{ -+ if (!IS_ERR(chip->phy3v3_supply)) -+ regulator_disable(chip->phy3v3_supply); -+ if (!IS_ERR(chip->dwmac3v3_supply)) -+ regulator_disable(chip->dwmac3v3_supply); -+} -+ -+static int sunxi_dwmac_clk_init(struct sunxi_dwmac *chip) -+{ -+ int ret; -+ -+ if (chip->variant->flags & SUNXI_DWMAC_HSI_CLK_GATE) -+ reset_control_deassert(chip->hsi_rst); -+ reset_control_deassert(chip->ahb_rst); -+ -+ if (chip->variant->flags & SUNXI_DWMAC_HSI_CLK_GATE) { -+ ret = clk_prepare_enable(chip->hsi_ahb); -+ if (ret) { -+ sunxi_err(chip->dev, "enable hsi_ahb failed\n"); -+ goto err_ahb; -+ } -+ ret = clk_prepare_enable(chip->hsi_axi); -+ if (ret) { -+ sunxi_err(chip->dev, "enable hsi_axi failed\n"); -+ goto err_axi; -+ } -+ } -+ -+ if (chip->variant->flags & SUNXI_DWMAC_NSI_CLK_GATE) { -+ ret = clk_prepare_enable(chip->nsi_clk); -+ if (ret) { -+ sunxi_err(chip->dev, "enable nsi clk failed\n"); -+ goto err_nsi; -+ } -+ } -+ -+ if (chip->soc_phy_clk_en) { -+ ret = clk_prepare_enable(chip->phy_clk); -+ if (ret) { -+ sunxi_err(chip->dev, "Enable phy clk failed\n"); -+ goto err_phy; -+ } -+ } -+ -+ return 0; -+ -+err_phy: -+ if (chip->variant->flags & SUNXI_DWMAC_NSI_CLK_GATE) -+ clk_disable_unprepare(chip->nsi_clk); -+err_nsi: -+ if (chip->variant->flags & SUNXI_DWMAC_HSI_CLK_GATE) { -+ clk_disable_unprepare(chip->hsi_axi); -+err_axi: -+ clk_disable_unprepare(chip->hsi_ahb); -+ } -+err_ahb: -+ reset_control_assert(chip->ahb_rst); -+ if (chip->variant->flags & SUNXI_DWMAC_HSI_CLK_GATE) -+ reset_control_assert(chip->hsi_rst); -+ return ret; -+} -+ -+static void sunxi_dwmac_clk_exit(struct sunxi_dwmac *chip) -+{ -+ if (chip->soc_phy_clk_en) -+ clk_disable_unprepare(chip->phy_clk); -+ if (chip->variant->flags & SUNXI_DWMAC_NSI_CLK_GATE) -+ clk_disable_unprepare(chip->nsi_clk); -+ if (chip->variant->flags & SUNXI_DWMAC_HSI_CLK_GATE) { -+ clk_disable_unprepare(chip->hsi_axi); -+ clk_disable_unprepare(chip->hsi_ahb); -+ } -+ reset_control_assert(chip->ahb_rst); -+ if (chip->variant->flags & SUNXI_DWMAC_HSI_CLK_GATE) -+ reset_control_assert(chip->hsi_rst); -+} -+ -+static int sunxi_dwmac_hw_init(struct sunxi_dwmac *chip) -+{ -+ int ret; -+ -+ ret = chip->variant->set_syscon(chip); -+ if (ret < 0) { -+ sunxi_err(chip->dev, "Set syscon failed\n"); -+ goto err; -+ } -+ -+ ret = chip->variant->set_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_TX, chip->tx_delay); -+ if (ret < 0) { -+ sunxi_err(chip->dev, "Invalid TX clock delay: %d\n", chip->tx_delay); -+ goto err; -+ } -+ -+ ret = chip->variant->set_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_RX, chip->rx_delay); -+ if (ret < 0) { -+ sunxi_err(chip->dev, "Invalid RX clock delay: %d\n", chip->rx_delay); -+ goto err; -+ } -+ -+err: -+ return ret; -+} -+ -+static void sunxi_dwmac_hw_exit(struct sunxi_dwmac *chip) -+{ -+ writel(0, chip->syscfg_base); -+} -+ -+static int sunxi_dwmac_ecc_init(struct sunxi_dwmac *chip) -+{ -+ struct net_device *ndev = dev_get_drvdata(chip->dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct plat_stmmacenet_data *plat_dat = priv->plat; -+ -+ plat_dat->safety_feat_cfg = devm_kzalloc(chip->dev, sizeof(*plat_dat->safety_feat_cfg), GFP_KERNEL); -+ if (!plat_dat->safety_feat_cfg) -+ return -ENOMEM; -+ -+ plat_dat->safety_feat_cfg->tsoee = 0; /* TSO memory ECC Disabled */ -+ plat_dat->safety_feat_cfg->mrxpee = 0; /* MTL Rx Parser ECC Disabled */ -+ plat_dat->safety_feat_cfg->mestee = 0; /* MTL EST ECC Disabled */ -+ plat_dat->safety_feat_cfg->mrxee = 1; /* MTL Rx FIFO ECC Enable */ -+ plat_dat->safety_feat_cfg->mtxee = 1; /* MTL Tx FIFO ECC Enable */ -+ plat_dat->safety_feat_cfg->epsi = 0; /* Not Enable Parity on Slave Interface port */ -+ plat_dat->safety_feat_cfg->edpp = 1; /* Enable Data path Parity Protection */ -+ plat_dat->safety_feat_cfg->prtyen = 1; /* Enable FSM parity feature */ -+ plat_dat->safety_feat_cfg->tmouten = 1; /* Enable FSM timeout feature */ -+ -+ return 0; -+} -+ -+static int sunxi_dwmac_init(struct platform_device *pdev, void *priv) -+{ -+ struct sunxi_dwmac *chip = priv; -+ int ret; -+ -+ ret = sunxi_dwmac_power_on(chip); -+ if (ret) { -+ sunxi_err(&pdev->dev, "Power on dwmac failed\n"); -+ return ret; -+ } -+ -+ ret = sunxi_dwmac_clk_init(chip); -+ if (ret) { -+ sunxi_err(&pdev->dev, "Clk init dwmac failed\n"); -+ goto err_clk; -+ } -+ -+ ret = sunxi_dwmac_hw_init(chip); -+ if (ret) -+ sunxi_warn(&pdev->dev, "Hw init dwmac failed\n"); -+ -+ return 0; -+ -+err_clk: -+ sunxi_dwmac_power_off(chip); -+ return ret; -+} -+ -+static void sunxi_dwmac_exit(struct platform_device *pdev, void *priv) -+{ -+ struct sunxi_dwmac *chip = priv; -+ -+ sunxi_dwmac_hw_exit(chip); -+ sunxi_dwmac_clk_exit(chip); -+ sunxi_dwmac_power_off(chip); -+} -+ -+static void sunxi_dwmac_parse_delay_maps(struct sunxi_dwmac *chip) -+{ -+ struct platform_device *pdev = to_platform_device(chip->dev); -+ struct device_node *np = pdev->dev.of_node; -+ int ret, maps_cnt; -+ u32 *maps; -+ -+ maps_cnt = of_property_count_elems_of_size(np, "delay-maps", sizeof(u32)); -+ if (maps_cnt <= 0) { -+ sunxi_info(&pdev->dev, "Not found delay-maps in dts\n"); -+ return; -+ } -+ -+ maps = devm_kcalloc(&pdev->dev, maps_cnt, sizeof(u32), GFP_KERNEL); -+ if (!maps) -+ return; -+ -+ ret = of_property_read_u32_array(np, "delay-maps", maps, maps_cnt); -+ if (ret) { -+ sunxi_err(&pdev->dev, "Failed to parse delay-maps\n"); -+ goto err_parse_maps; -+ } -+/* todo -+ int i; -+ const u8 array_size = 3; -+ u16 soc_ver; -+ -+ soc_ver = (u16)sunxi_get_soc_ver(); -+ for (i = 0; i < (maps_cnt / array_size); i++) { -+ if (soc_ver == maps[i * array_size]) { -+ chip->rx_delay = maps[i * array_size + 1]; -+ chip->tx_delay = maps[i * array_size + 2]; -+ sunxi_info(&pdev->dev, "Overwrite delay-maps parameters, rx-delay:%d, tx-delay:%d\n", -+ chip->rx_delay, chip->tx_delay); -+ } -+ } -+*/ -+err_parse_maps: -+ devm_kfree(&pdev->dev, maps); -+} -+ -+static void sunxi_dwmac_request_mtl_irq(struct platform_device *pdev, struct sunxi_dwmac *chip, -+ struct plat_stmmacenet_data *plat_dat) -+{ -+ u32 queues; -+ char int_name[MAC_IRQ_NAME]; -+ -+ for (queues = 0; queues < plat_dat->tx_queues_to_use; queues++) { -+ sprintf(int_name, "%s%d_%s", "tx", queues, "irq"); -+ chip->res->tx_irq[queues] = platform_get_irq_byname_optional(pdev, int_name); -+ if (chip->res->tx_irq[queues] < 0) -+ chip->res->tx_irq[queues] = 0; -+ } -+ -+ for (queues = 0; queues < plat_dat->rx_queues_to_use; queues++) { -+ sprintf(int_name, "%s%d_%s", "rx", queues, "irq"); -+ chip->res->rx_irq[queues] = platform_get_irq_byname_optional(pdev, int_name); -+ if (chip->res->rx_irq[queues] < 0) -+ chip->res->rx_irq[queues] = 0; -+ } -+} -+ -+static int sunxi_dwmac_resource_get(struct platform_device *pdev, struct sunxi_dwmac *chip, -+ struct plat_stmmacenet_data *plat_dat) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct device *dev = &pdev->dev; -+ struct resource *res; -+ int ret; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (!res) { -+ sunxi_err(dev, "Get phy memory failed\n"); -+ return -ENODEV; -+ } -+ -+ chip->syscfg_base = devm_ioremap_resource(dev, res); -+ if (!chip->syscfg_base) { -+ sunxi_err(dev, "Phy memory mapping failed\n"); -+ return -ENOMEM; -+ } -+ -+ chip->rgmii_clk_ext = of_property_read_bool(np, "aw,rgmii-clk-ext"); -+ chip->soc_phy_clk_en = of_property_read_bool(np, "aw,soc-phy-clk-en") || -+ of_property_read_bool(np, "aw,soc-phy25m"); -+ if (chip->soc_phy_clk_en) { -+ chip->phy_clk = devm_clk_get(dev, "phy"); -+ if (IS_ERR(chip->phy_clk)) { -+ chip->phy_clk = devm_clk_get(dev, "phy25m"); -+ if (IS_ERR(chip->phy_clk)) { -+ sunxi_err(dev, "Get phy25m clk failed\n"); -+ return -EINVAL; -+ } -+ } -+ sunxi_info(dev, "Phy use soc fanout\n"); -+ } else -+ sunxi_info(dev, "Phy use ext osc\n"); -+ -+ if (chip->variant->flags & SUNXI_DWMAC_HSI_CLK_GATE) { -+ chip->hsi_ahb = devm_clk_get(dev, "hsi_ahb"); -+ if (IS_ERR(chip->hsi_ahb)) { -+ sunxi_err(dev, "Get hsi_ahb clk failed\n"); -+ return -EINVAL; -+ } -+ chip->hsi_axi = devm_clk_get(dev, "hsi_axi"); -+ if (IS_ERR(chip->hsi_axi)) { -+ sunxi_err(dev, "Get hsi_axi clk failed\n"); -+ return -EINVAL; -+ } -+ } -+ -+ if (chip->variant->flags & SUNXI_DWMAC_NSI_CLK_GATE) { -+ chip->nsi_clk = devm_clk_get(dev, "nsi"); -+ if (IS_ERR(chip->nsi_clk)) { -+ sunxi_err(dev, "Get nsi clk failed\n"); -+ return -EINVAL; -+ } -+ } -+ -+ if (chip->variant->flags & SUNXI_DWMAC_MEM_ECC) { -+ sunxi_info(dev, "Support mem ecc\n"); -+ chip->res->sfty_ce_irq = platform_get_irq_byname_optional(pdev, "mac_eccirq"); -+ if (chip->res->sfty_ce_irq < 0) { -+ sunxi_err(&pdev->dev, "Get ecc irq failed\n"); -+ return -EINVAL; -+ } -+ } -+ -+ if (chip->variant->flags & SUNXI_DWMAC_HSI_CLK_GATE) { -+ chip->hsi_rst = devm_reset_control_get_shared(chip->dev, "hsi"); -+ if (IS_ERR(chip->hsi_rst)) { -+ sunxi_err(dev, "Get hsi reset failed\n"); -+ return -EINVAL; -+ } -+ } -+ -+ chip->ahb_rst = devm_reset_control_get_optional_shared(chip->dev, "ahb"); -+ if (IS_ERR(chip->ahb_rst)) { -+ sunxi_err(dev, "Get mac reset failed\n"); -+ return -EINVAL; -+ } -+ -+ chip->dwmac3v3_supply = devm_regulator_get_optional(&pdev->dev, "dwmac3v3"); -+ if (IS_ERR(chip->dwmac3v3_supply)) -+ sunxi_warn(dev, "Not found dwmac3v3-supply\n"); -+ -+ chip->phy3v3_supply = devm_regulator_get_optional(&pdev->dev, "phy3v3"); -+ if (IS_ERR(chip->phy3v3_supply)) -+ sunxi_warn(dev, "Not found phy3v3-supply\n"); -+ -+ ret = of_property_read_u32(np, "tx-delay", &chip->tx_delay); -+ if (ret) { -+ sunxi_warn(dev, "Get gmac tx-delay failed, use default 0\n"); -+ chip->tx_delay = 0; -+ } -+ -+ ret = of_property_read_u32(np, "rx-delay", &chip->rx_delay); -+ if (ret) { -+ sunxi_warn(dev, "Get gmac rx-delay failed, use default 0\n"); -+ chip->rx_delay = 0; -+ } -+ -+ sunxi_dwmac_parse_delay_maps(chip); -+ -+ if (chip->variant->flags & SUNXI_DWMAC_MULTI_MSI) -+ sunxi_dwmac_request_mtl_irq(pdev, chip, plat_dat); -+ -+ return 0; -+} -+ -+#ifndef MODULE -+static void sunxi_dwmac_set_mac(u8 *dst, u8 *src) -+{ -+ int i; -+ char *p = src; -+ -+ for (i = 0; i < ETH_ALEN; i++, p++) -+ dst[i] = simple_strtoul(p, &p, 16); -+} -+#endif -+ -+static int sunxi_dwmac_probe(struct platform_device *pdev) -+{ -+ struct plat_stmmacenet_data *plat_dat; -+ struct stmmac_resources stmmac_res; -+ struct sunxi_dwmac *chip; -+ struct device *dev = &pdev->dev; -+ int ret; -+ -+ ret = stmmac_get_platform_resources(pdev, &stmmac_res); -+ if (ret) -+ return ret; -+ -+ chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); -+ if (!chip) { -+ sunxi_err(&pdev->dev, "Alloc sunxi dwmac err\n"); -+ return -ENOMEM; -+ } -+ -+ chip->variant = of_device_get_match_data(&pdev->dev); -+ if (!chip->variant) { -+ sunxi_err(&pdev->dev, "Missing dwmac-sunxi variant\n"); -+ return -EINVAL; -+ } -+ -+ chip->dev = dev; -+ chip->res = &stmmac_res; -+ -+ plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac); -+ -+ if (IS_ERR(plat_dat)) -+ return PTR_ERR(plat_dat); -+ -+ ret = sunxi_dwmac_resource_get(pdev, chip, plat_dat); -+ if (ret < 0) -+ return -EINVAL; -+ -+#ifdef MODULE -+//todo get_custom_mac_address(1, "eth", stmmac_res.mac); -+#else -+//todo sunxi_dwmac_set_mac(stmmac_res.mac, mac_str); -+#endif -+ -+ -+ plat_dat->bsp_priv = chip; -+ plat_dat->init = sunxi_dwmac_init; -+ plat_dat->exit = sunxi_dwmac_exit; -+ /* must use 0~4G space */ -+ plat_dat->host_dma_width = 32; -+ -+ /* Disable Split Header (SPH) feature for sunxi platfrom as default -+ * The same issue also detect on intel platfrom, see 41eebbf90dfbcc8ad16d4755fe2cdb8328f5d4a7. -+ */ -+ if (chip->variant->flags & SUNXI_DWMAC_SPH_DISABLE) -+ plat_dat->flags |= STMMAC_FLAG_SPH_DISABLE; -+ if (chip->variant->flags & SUNXI_DWMAC_MULTI_MSI) -+ plat_dat->flags |= STMMAC_FLAG_MULTI_MSI_EN; -+ chip->interface = plat_dat->mac_interface; -+ -+ plat_dat->clk_csr = 4; /* MDC = AHB(200M)/102 = 2M */ -+ -+ ret = sunxi_dwmac_init(pdev, plat_dat->bsp_priv); -+ if (ret) -+ goto err_init; -+ -+ ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); -+ if (ret) -+ goto err_dvr_probe; -+ -+ if (chip->variant->flags & SUNXI_DWMAC_MEM_ECC) { -+ ret = sunxi_dwmac_ecc_init(chip); -+ if (ret < 0) { -+ sunxi_err(chip->dev, "Init ecc failed\n"); -+ goto err_cfg; -+ } -+ } -+ -+ sunxi_dwmac_sysfs_init(&pdev->dev); -+ -+ sunxi_info(&pdev->dev, "probe success (Version %s)\n", DWMAC_MODULE_VERSION); -+ -+ return 0; -+ -+err_cfg: -+ stmmac_dvr_remove(&pdev->dev); -+err_dvr_probe: -+ sunxi_dwmac_exit(pdev, chip); -+err_init: -+ //stmmac_remove_config_dt(pdev, plat_dat); -+ return ret; -+} -+ -+static void sunxi_dwmac_remove(struct platform_device *pdev) -+{ -+ sunxi_dwmac_sysfs_exit(&pdev->dev); -+ stmmac_pltfr_remove(pdev); -+} -+ -+static void sunxi_dwmac_shutdown(struct platform_device *pdev) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ -+ sunxi_dwmac_exit(pdev, chip); -+} -+ -+static int __maybe_unused sunxi_dwmac_suspend(struct device *dev) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct platform_device *pdev = to_platform_device(dev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ int ret; -+ -+ /* suspend error workaround */ -+ if (ndev && ndev->phydev) { -+ chip->uevent_suppress = dev_get_uevent_suppress(&ndev->phydev->mdio.dev); -+ dev_set_uevent_suppress(&ndev->phydev->mdio.dev, true); -+ } -+ -+ ret = stmmac_suspend(dev); -+ sunxi_dwmac_exit(pdev, chip); -+ stmmac_bus_clks_config(priv, false); -+ -+ return ret; -+} -+ -+static int __maybe_unused sunxi_dwmac_resume(struct device *dev) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct platform_device *pdev = to_platform_device(dev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ int ret; -+ -+ stmmac_bus_clks_config(priv, true); -+ sunxi_dwmac_init(pdev, chip); -+ ret = stmmac_resume(dev); -+ -+ if (ndev && ndev->phydev) { -+ /* State machine change phy state too early before mdio bus resume. -+ * WARN_ON would print in mdio_bus_phy_resume if state not equal to PHY_HALTED/PHY_READY/PHY_UP. -+ * Workaround is change the state back to PHY_UP and modify the state machine work so the judgment can be passed. -+ */ -+ rtnl_lock(); -+ mutex_lock(&ndev->phydev->lock); -+ if (ndev->phydev->state == PHY_UP || ndev->phydev->state == PHY_NOLINK) { -+ if (ndev->phydev->state == PHY_NOLINK) -+ ndev->phydev->state = PHY_UP; -+ phy_queue_state_machine(ndev->phydev, HZ); -+ } -+ mutex_unlock(&ndev->phydev->lock); -+ rtnl_unlock(); -+ -+ /* suspend error workaround */ -+ dev_set_uevent_suppress(&ndev->phydev->mdio.dev, chip->uevent_suppress); -+ } -+ -+ return ret; -+} -+ -+static SIMPLE_DEV_PM_OPS(sunxi_dwmac_pm_ops, sunxi_dwmac_suspend, sunxi_dwmac_resume); -+ -+static const struct sunxi_dwmac_variant dwmac200_variant = { -+ .interface = PHY_INTERFACE_MODE_RMII | PHY_INTERFACE_MODE_RGMII, -+ .flags = SUNXI_DWMAC_SPH_DISABLE, -+ .rx_delay_max = 31, -+ .tx_delay_max = 7, -+ .set_syscon = sunxi_dwmac200_set_syscon, -+ .set_delaychain = sunxi_dwmac200_set_delaychain, -+ .get_delaychain = sunxi_dwmac200_get_delaychain, -+}; -+ -+static const struct sunxi_dwmac_variant dwmac210_variant = { -+ .interface = PHY_INTERFACE_MODE_RMII | PHY_INTERFACE_MODE_RGMII, -+ .flags = SUNXI_DWMAC_SPH_DISABLE | SUNXI_DWMAC_MULTI_MSI, -+ .rx_delay_max = 31, -+ .tx_delay_max = 31, -+ .set_syscon = sunxi_dwmac200_set_syscon, -+ .set_delaychain = sunxi_dwmac210_set_delaychain, -+ .get_delaychain = sunxi_dwmac210_get_delaychain, -+}; -+ -+static const struct sunxi_dwmac_variant dwmac220_variant = { -+ .interface = PHY_INTERFACE_MODE_RMII | PHY_INTERFACE_MODE_RGMII, -+ .flags = SUNXI_DWMAC_SPH_DISABLE | SUNXI_DWMAC_NSI_CLK_GATE | SUNXI_DWMAC_MULTI_MSI | SUNXI_DWMAC_MEM_ECC, -+ .rx_delay_max = 31, -+ .tx_delay_max = 31, -+ .set_syscon = sunxi_dwmac200_set_syscon, -+ .set_delaychain = sunxi_dwmac210_set_delaychain, -+ .get_delaychain = sunxi_dwmac210_get_delaychain, -+}; -+ -+static const struct sunxi_dwmac_variant dwmac110_variant = { -+ .interface = PHY_INTERFACE_MODE_RMII | PHY_INTERFACE_MODE_RGMII, -+ .flags = SUNXI_DWMAC_SPH_DISABLE | SUNXI_DWMAC_NSI_CLK_GATE | SUNXI_DWMAC_HSI_CLK_GATE | SUNXI_DWMAC_MULTI_MSI, -+ .rx_delay_max = 31, -+ .tx_delay_max = 31, -+ .set_syscon = sunxi_dwmac200_set_syscon, -+ .set_delaychain = sunxi_dwmac210_set_delaychain, -+ .get_delaychain = sunxi_dwmac210_get_delaychain, -+ .get_version = sunxi_dwmac110_get_version, -+}; -+ -+static const struct of_device_id sunxi_dwmac_match[] = { -+ { .compatible = "allwinner,sunxi-gmac-200", .data = &dwmac200_variant }, -+ { .compatible = "allwinner,sunxi-gmac-210", .data = &dwmac210_variant }, -+ { .compatible = "allwinner,sunxi-gmac-220", .data = &dwmac220_variant }, -+ { .compatible = "allwinner,sunxi-gmac-110", .data = &dwmac110_variant }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, sunxi_dwmac_match); -+ -+static struct platform_driver sunxi_dwmac_driver = { -+ .probe = sunxi_dwmac_probe, -+ .remove = sunxi_dwmac_remove, -+ .shutdown = sunxi_dwmac_shutdown, -+ .driver = { -+ .name = "dwmac-sunxi", -+ .pm = &sunxi_dwmac_pm_ops, -+ .of_match_table = sunxi_dwmac_match, -+ }, -+}; -+module_platform_driver(sunxi_dwmac_driver); -+ -+#ifndef MODULE -+static int __init sunxi_dwmac_set_mac_addr(char *str) -+{ -+ char *p = str; -+ -+ if (str && strlen(str)) -+ memcpy(mac_str, p, MAC_ADDR_LEN); -+ -+ return 0; -+} -+__setup("mac_addr=", sunxi_dwmac_set_mac_addr); -+#endif /* MODULE */ -+ -+MODULE_DESCRIPTION("Allwinner DWMAC driver"); -+MODULE_AUTHOR("wujiayi "); -+MODULE_AUTHOR("xuminghui "); -+MODULE_AUTHOR("Piotr Oniszczuk "); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_VERSION(DWMAC_MODULE_VERSION); -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi.h linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi.h ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi.h 2025-01-21 15:58:05.577494134 +0100 -@@ -0,0 +1,176 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* Copyright(c) 2020 - 2023 Allwinner Technology Co.,Ltd. All rights reserved. */ -+/* -+* Allwinner DWMAC driver header. -+* -+* Copyright(c) 2022-2027 Allwinnertech Co., Ltd. -+* -+* 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. -+*/ -+ -+#ifndef _DWMAC_SUNXI_H_ -+#define _DWMAC_SUNXI_H_ -+ -+#include -+#include -+ -+/* DWCMAC5 ECC Debug Register -+ * These macro do not defined in mainline code dwmac5.h -+ */ -+#define MTL_DBG_CTL 0x00000c08 -+#define EIEC BIT(18) -+#define EIAEE BIT(17) -+#define EIEE BIT(16) -+#define FIFOSEL GENMASK(13, 12) -+#define FIFOWREN BIT(11) -+#define FIFORDEN BIT(10) -+#define RSTSEL BIT(9) -+#define RSTALL BIT(8) -+#define DBGMOD BIT(1) -+#define FDBGEN BIT(0) -+#define MTL_DBG_STS 0x00000c0c -+#define FIFOBUSY BIT(0) -+#define MTL_FIFO_DEBUG_DATA 0x00000c10 -+#define MTL_ECC_ERR_STS_RCTL 0x00000cd0 -+#define CUES BIT(5) -+#define CCES BIT(4) -+#define EMS GENMASK(3, 1) -+#define EESRE BIT(0) -+#define MTL_ECC_ERR_ADDR_STATUS 0x00000cd4 -+#define EUEAS GENMASK(31, 16) -+#define ECEAS GENMASK(15, 0) -+#define MTL_ECC_ERR_CNTR_STATUS 0x00000cd8 -+#define EUECS GENMASK(19, 16) -+#define ECECS GENMASK(7, 0) -+#define MTL_DPP_ECC_EIC 0x00000ce4 -+#define EIM BIT(16) -+#define BLEI GENMASK(7, 0) -+ -+/* GMAC-200 Register */ -+#define SUNXI_DWMAC200_SYSCON_REG (0x00) -+ #define SUNXI_DWMAC200_SYSCON_BPS_EFUSE GENMASK(31, 28) -+ #define SUNXI_DWMAC200_SYSCON_XMII_SEL BIT(27) -+ #define SUNXI_DWMAC200_SYSCON_EPHY_MODE GENMASK(26, 25) -+ #define SUNXI_DWMAC200_SYSCON_PHY_ADDR GENMASK(24, 20) -+ #define SUNXI_DWMAC200_SYSCON_BIST_CLK_EN BIT(19) -+ #define SUNXI_DWMAC200_SYSCON_CLK_SEL BIT(18) -+ #define SUNXI_DWMAC200_SYSCON_LED_POL BIT(17) -+ #define SUNXI_DWMAC200_SYSCON_SHUTDOWN BIT(16) -+ #define SUNXI_DWMAC200_SYSCON_PHY_SEL BIT(15) -+ #define SUNXI_DWMAC200_SYSCON_ENDIAN_MODE BIT(14) -+ #define SUNXI_DWMAC200_SYSCON_RMII_EN BIT(13) -+ #define SUNXI_DWMAC200_SYSCON_ETXDC GENMASK(12, 10) -+ #define SUNXI_DWMAC200_SYSCON_ERXDC GENMASK(9, 5) -+ #define SUNXI_DWMAC200_SYSCON_ERXIE BIT(4) -+ #define SUNXI_DWMAC200_SYSCON_ETXIE BIT(3) -+ #define SUNXI_DWMAC200_SYSCON_EPIT BIT(2) -+ #define SUNXI_DWMAC200_SYSCON_ETCS GENMASK(1, 0) -+ -+/* GMAC-210 Register */ -+#define SUNXI_DWMAC210_CFG_REG (0x00) -+ #define SUNXI_DWMAC210_CFG_ETXDC_H GENMASK(17, 16) -+ #define SUNXI_DWMAC210_CFG_PHY_SEL BIT(15) -+ #define SUNXI_DWMAC210_CFG_ENDIAN_MODE BIT(14) -+ #define SUNXI_DWMAC210_CFG_RMII_EN BIT(13) -+ #define SUNXI_DWMAC210_CFG_ETXDC_L GENMASK(12, 10) -+ #define SUNXI_DWMAC210_CFG_ERXDC GENMASK(9, 5) -+ #define SUNXI_DWMAC210_CFG_ERXIE BIT(4) -+ #define SUNXI_DWMAC210_CFG_ETXIE BIT(3) -+ #define SUNXI_DWMAC210_CFG_EPIT BIT(2) -+ #define SUNXI_DWMAC210_CFG_ETCS GENMASK(1, 0) -+#define SUNXI_DWMAC210_PTP_TIMESTAMP_L_REG (0x40) -+#define SUNXI_DWMAC210_PTP_TIMESTAMP_H_REG (0x48) -+#define SUNXI_DWMAC210_STAT_INT_REG (0x4C) -+ #define SUNXI_DWMAC210_STAT_PWR_DOWN_ACK BIT(4) -+ #define SUNXI_DWMAC210_STAT_SBD_TX_CLK_GATE BIT(3) -+ #define SUNXI_DWMAC210_STAT_LPI_INT BIT(1) -+ #define SUNXI_DWMAC210_STAT_PMT_INT BIT(0) -+#define SUNXI_DWMAC210_CLK_GATE_CFG_REG (0x80) -+ #define SUNXI_DWMAC210_CLK_GATE_CFG_RX BIT(7) -+ #define SUNXI_DWMAC210_CLK_GATE_CFG_PTP_REF BIT(6) -+ #define SUNXI_DWMAC210_CLK_GATE_CFG_CSR BIT(5) -+ #define SUNXI_DWMAC210_CLK_GATE_CFG_TX BIT(4) -+ #define SUNXI_DWMAC210_CLK_GATE_CFG_APP BIT(3) -+ -+/* GMAC-110 Register */ -+#define SUNXI_DWMAC110_CFG_REG SUNXI_DWMAC210_CFG_REG -+ /* SUNXI_DWMAC110_CFG_REG is same with SUNXI_DWMAC210_CFG_REG */ -+#define SUNXI_DWMAC110_CLK_GATE_CFG_REG (0x04) -+ #define SUNXI_DWMAC110_CLK_GATE_CFG_RX BIT(3) -+ #define SUNXI_DWMAC110_CLK_GATE_CFG_TX BIT(2) -+ #define SUNXI_DWMAC110_CLK_GATE_CFG_APP BIT(1) -+ #define SUNXI_DWMAC110_CLK_GATE_CFG_CSR BIT(0) -+#define SUNXI_DWMAC110_VERSION_REG (0xfc) -+ #define SUNXI_DWMAC110_VERSION_IP_TAG GENMASK(31, 16) -+ #define SUNXI_DWMAC110_VERSION_IP_VRM GENMASK(15, 0) -+ -+#define SUNXI_DWMAC_ETCS_MII 0x0 -+#define SUNXI_DWMAC_ETCS_EXT_GMII 0x1 -+#define SUNXI_DWMAC_ETCS_INT_GMII 0x2 -+ -+/* MAC flags defined */ -+#define SUNXI_DWMAC_SPH_DISABLE BIT(0) -+#define SUNXI_DWMAC_NSI_CLK_GATE BIT(1) -+#define SUNXI_DWMAC_MULTI_MSI BIT(2) -+#define SUNXI_DWMAC_MEM_ECC BIT(3) -+#define SUNXI_DWMAC_HSI_CLK_GATE BIT(4) -+ -+struct sunxi_dwmac; -+ -+enum sunxi_dwmac_delaychain_dir { -+ SUNXI_DWMAC_DELAYCHAIN_TX, -+ SUNXI_DWMAC_DELAYCHAIN_RX, -+}; -+ -+enum sunxi_dwmac_ecc_fifo_type { -+ SUNXI_DWMAC_ECC_FIFO_TX, -+ SUNXI_DWMAC_ECC_FIFO_RX, -+}; -+ -+struct sunxi_dwmac_variant { -+ u32 flags; -+ u32 interface; -+ u32 rx_delay_max; -+ u32 tx_delay_max; -+ int (*set_syscon)(struct sunxi_dwmac *chip); -+ int (*set_delaychain)(struct sunxi_dwmac *chip, enum sunxi_dwmac_delaychain_dir dir, u32 delay); -+ u32 (*get_delaychain)(struct sunxi_dwmac *chip, enum sunxi_dwmac_delaychain_dir dir); -+ int (*get_version)(struct sunxi_dwmac *chip, u16 *ip_tag, u16 *ip_vrm); -+}; -+ -+struct sunxi_dwmac_mii_reg { -+ u32 addr; -+ u16 reg; -+ u16 value; -+}; -+ -+struct sunxi_dwmac { -+ const struct sunxi_dwmac_variant *variant; -+ struct sunxi_dwmac_mii_reg mii_reg; -+ struct clk *phy_clk; -+ struct clk *nsi_clk; -+ struct clk *hsi_ahb; -+ struct clk *hsi_axi; -+ struct reset_control *ahb_rst; -+ struct reset_control *hsi_rst; -+ struct device *dev; -+ void __iomem *syscfg_base; -+ struct regulator *dwmac3v3_supply; -+ struct regulator *phy3v3_supply; -+ -+ u32 tx_delay; /* adjust transmit clock delay */ -+ u32 rx_delay; /* adjust receive clock delay */ -+ -+ bool rgmii_clk_ext; -+ bool soc_phy_clk_en; -+ int interface; -+ unsigned int uevent_suppress; /* suspend error workaround: control kobject_uevent_env */ -+ -+ struct stmmac_resources *res; -+}; -+ -+#include "dwmac-sunxi-sysfs.h" -+ -+#endif /* _DWMAC_SUNXI_H_ */ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi-sysfs.c linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi-sysfs.c ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi-sysfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi-sysfs.c 2025-01-21 15:58:05.577494134 +0100 -@@ -0,0 +1,927 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* Copyright(c) 2020 - 2023 Allwinner Technology Co.,Ltd. All rights reserved. */ -+/* -+* Allwinner DWMAC driver sysfs. -+* -+* Copyright(c) 2022-2027 Allwinnertech Co., Ltd. -+* -+*/ -+ -+#include "sunxi-log.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "stmmac/stmmac.h" -+ -+#include "dwmac-sunxi-sysfs.h" -+ -+struct sunxi_dwmac_hdr { -+ __be32 version; -+ __be64 magic; -+ u8 id; -+ u32 tx; -+ u32 rx; -+} __packed; -+ -+#define SUNXI_DWMAC_PKT_SIZE (sizeof(struct ethhdr) + sizeof(struct iphdr) + \ -+ sizeof(struct sunxi_dwmac_hdr)) -+#define SUNXI_DWMAC_PKT_MAGIC 0xdeadcafecafedeadULL -+#define SUNXI_DWMAC_TIMEOUT msecs_to_jiffies(2) -+ -+struct sunxi_dwmac_packet_attr { -+ u32 tx; -+ u32 rx; -+ unsigned char *src; -+ unsigned char *dst; -+ u32 ip_src; -+ u32 ip_dst; -+ int tcp; -+ int sport; -+ int dport; -+ int dont_wait; -+ int timeout; -+ int size; -+ int max_size; -+ u8 id; -+ u16 queue_mapping; -+ u64 timestamp; -+}; -+ -+struct sunxi_dwmac_loop_priv { -+ struct sunxi_dwmac_packet_attr *packet; -+ struct packet_type pt; -+ struct completion comp; -+ int ok; -+}; -+ -+struct sunxi_dwmac_calibrate { -+ u8 id; -+ u32 tx_delay; -+ u32 rx_delay; -+ u32 window_tx; -+ u32 window_rx; -+}; -+ -+/** -+ * sunxi_dwmac_parse_read_str - parse the input string for write attri. -+ * @str: string to be parsed, eg: "0x00 0x01". -+ * @addr: store the phy addr. eg: 0x00. -+ * @reg: store the reg addr. eg: 0x01. -+ * -+ * return 0 if success, otherwise failed. -+ */ -+static int sunxi_dwmac_parse_read_str(char *str, u16 *addr, u16 *reg) -+{ -+ char *ptr = str; -+ char *tstr = NULL; -+ int ret; -+ -+ /** -+ * Skip the leading whitespace, find the true split symbol. -+ * And it must be 'address value'. -+ */ -+ tstr = strim(str); -+ ptr = strchr(tstr, ' '); -+ if (!ptr) -+ return -EINVAL; -+ -+ /** -+ * Replaced split symbol with a %NUL-terminator temporary. -+ * Will be fixed at end. -+ */ -+ *ptr = '\0'; -+ ret = kstrtos16(tstr, 16, addr); -+ if (ret) -+ goto out; -+ -+ ret = kstrtos16(skip_spaces(ptr + 1), 16, reg); -+ -+out: -+ return ret; -+} -+ -+/** -+ * sunxi_dwmac_parse_write_str - parse the input string for compare attri. -+ * @str: string to be parsed, eg: "0x00 0x11 0x11". -+ * @addr: store the phy addr. eg: 0x00. -+ * @reg: store the reg addr. eg: 0x11. -+ * @val: store the value. eg: 0x11. -+ * -+ * return 0 if success, otherwise failed. -+ */ -+static int sunxi_dwmac_parse_write_str(char *str, u16 *addr, -+ u16 *reg, u16 *val) -+{ -+ u16 result_addr[3] = { 0 }; -+ char *ptr = str; -+ char *ptr2 = NULL; -+ int i, ret; -+ -+ for (i = 0; i < ARRAY_SIZE(result_addr); i++) { -+ ptr = skip_spaces(ptr); -+ ptr2 = strchr(ptr, ' '); -+ if (ptr2) -+ *ptr2 = '\0'; -+ -+ ret = kstrtou16(ptr, 16, &result_addr[i]); -+ -+ if (!ptr2 || ret) -+ break; -+ -+ ptr = ptr2 + 1; -+ } -+ -+ *addr = result_addr[0]; -+ *reg = result_addr[1]; -+ *val = result_addr[2]; -+ -+ return ret; -+} -+ -+static struct sk_buff *sunxi_dwmac_get_skb(struct stmmac_priv *priv, -+ struct sunxi_dwmac_packet_attr *attr) -+{ -+ struct sk_buff *skb = NULL; -+ struct udphdr *uhdr = NULL; -+ struct tcphdr *thdr = NULL; -+ struct sunxi_dwmac_hdr *shdr; -+ struct ethhdr *ehdr; -+ struct iphdr *ihdr; -+ int iplen, size; -+ -+ size = attr->size + SUNXI_DWMAC_PKT_SIZE; -+ -+ if (attr->tcp) -+ size += sizeof(*thdr); -+ else -+ size += sizeof(*uhdr); -+ -+ if (attr->max_size && (attr->max_size > size)) -+ size = attr->max_size; -+ -+ skb = netdev_alloc_skb(priv->dev, size); -+ if (!skb) -+ return NULL; -+ -+ prefetchw(skb->data); -+ -+ ehdr = skb_push(skb, ETH_HLEN); -+ skb_reset_mac_header(skb); -+ -+ skb_set_network_header(skb, skb->len); -+ ihdr = skb_put(skb, sizeof(*ihdr)); -+ -+ skb_set_transport_header(skb, skb->len); -+ if (attr->tcp) -+ thdr = skb_put(skb, sizeof(*thdr)); -+ else -+ uhdr = skb_put(skb, sizeof(*uhdr)); -+ -+ eth_zero_addr(ehdr->h_source); -+ eth_zero_addr(ehdr->h_dest); -+ if (attr->src) -+ ether_addr_copy(ehdr->h_source, attr->src); -+ if (attr->dst) -+ ether_addr_copy(ehdr->h_dest, attr->dst); -+ -+ ehdr->h_proto = htons(ETH_P_IP); -+ -+ if (attr->tcp) { -+ thdr->source = htons(attr->sport); -+ thdr->dest = htons(attr->dport); -+ thdr->doff = sizeof(*thdr) / 4; -+ thdr->check = 0; -+ } else { -+ uhdr->source = htons(attr->sport); -+ uhdr->dest = htons(attr->dport); -+ uhdr->len = htons(sizeof(*shdr) + sizeof(*uhdr) + attr->size); -+ if (attr->max_size) -+ uhdr->len = htons(attr->max_size - -+ (sizeof(*ihdr) + sizeof(*ehdr))); -+ uhdr->check = 0; -+ } -+ -+ ihdr->ihl = 5; -+ ihdr->ttl = 32; -+ ihdr->version = 4; -+ if (attr->tcp) -+ ihdr->protocol = IPPROTO_TCP; -+ else -+ ihdr->protocol = IPPROTO_UDP; -+ iplen = sizeof(*ihdr) + sizeof(*shdr) + attr->size; -+ if (attr->tcp) -+ iplen += sizeof(*thdr); -+ else -+ iplen += sizeof(*uhdr); -+ -+ if (attr->max_size) -+ iplen = attr->max_size - sizeof(*ehdr); -+ -+ ihdr->tot_len = htons(iplen); -+ ihdr->frag_off = 0; -+ ihdr->saddr = htonl(attr->ip_src); -+ ihdr->daddr = htonl(attr->ip_dst); -+ ihdr->tos = 0; -+ ihdr->id = 0; -+ ip_send_check(ihdr); -+ -+ shdr = skb_put(skb, sizeof(*shdr)); -+ shdr->version = 0; -+ shdr->magic = cpu_to_be64(SUNXI_DWMAC_PKT_MAGIC); -+ shdr->id = attr->id; -+ shdr->tx = attr->tx; -+ shdr->rx = attr->rx; -+ -+ if (attr->size) -+ skb_put(skb, attr->size); -+ if (attr->max_size && (attr->max_size > skb->len)) -+ skb_put(skb, attr->max_size - skb->len); -+ -+ skb->csum = 0; -+ skb->ip_summed = CHECKSUM_PARTIAL; -+ if (attr->tcp) { -+ thdr->check = ~tcp_v4_check(skb->len, ihdr->saddr, ihdr->daddr, 0); -+ skb->csum_start = skb_transport_header(skb) - skb->head; -+ skb->csum_offset = offsetof(struct tcphdr, check); -+ } else { -+ udp4_hwcsum(skb, ihdr->saddr, ihdr->daddr); -+ } -+ -+ skb->protocol = htons(ETH_P_IP); -+ skb->pkt_type = PACKET_HOST; -+ skb->dev = priv->dev; -+ -+ if (attr->timestamp) -+ skb->tstamp = ns_to_ktime(attr->timestamp); -+ -+ return skb; -+} -+ -+static int sunxi_dwmac_loopback_validate(struct sk_buff *skb, -+ struct net_device *ndev, -+ struct packet_type *pt, -+ struct net_device *orig_ndev) -+{ -+ struct sunxi_dwmac_loop_priv *tpriv = pt->af_packet_priv; -+ unsigned char *src = tpriv->packet->src; -+ unsigned char *dst = tpriv->packet->dst; -+ struct sunxi_dwmac_hdr *shdr; -+ struct ethhdr *ehdr; -+ struct udphdr *uhdr; -+ struct tcphdr *thdr; -+ struct iphdr *ihdr; -+ -+ skb = skb_unshare(skb, GFP_ATOMIC); -+ if (!skb) -+ goto out; -+ -+ if (skb_linearize(skb)) -+ goto out; -+ if (skb_headlen(skb) < (SUNXI_DWMAC_PKT_SIZE - ETH_HLEN)) -+ goto out; -+ -+ ehdr = (struct ethhdr *)skb_mac_header(skb); -+ if (dst) { -+ if (!ether_addr_equal_unaligned(ehdr->h_dest, dst)) -+ goto out; -+ } -+ if (src) { -+ if (!ether_addr_equal_unaligned(ehdr->h_source, src)) -+ goto out; -+ } -+ -+ ihdr = ip_hdr(skb); -+ -+ if (tpriv->packet->tcp) { -+ if (ihdr->protocol != IPPROTO_TCP) -+ goto out; -+ -+ thdr = (struct tcphdr *)((u8 *)ihdr + 4 * ihdr->ihl); -+ if (thdr->dest != htons(tpriv->packet->dport)) -+ goto out; -+ -+ shdr = (struct sunxi_dwmac_hdr *)((u8 *)thdr + sizeof(*thdr)); -+ } else { -+ if (ihdr->protocol != IPPROTO_UDP) -+ goto out; -+ -+ uhdr = (struct udphdr *)((u8 *)ihdr + 4 * ihdr->ihl); -+ if (uhdr->dest != htons(tpriv->packet->dport)) -+ goto out; -+ -+ shdr = (struct sunxi_dwmac_hdr *)((u8 *)uhdr + sizeof(*uhdr)); -+ } -+ -+ if (shdr->magic != cpu_to_be64(SUNXI_DWMAC_PKT_MAGIC)) -+ goto out; -+ if (tpriv->packet->id != shdr->id) -+ goto out; -+ if (tpriv->packet->tx != shdr->tx || tpriv->packet->rx != shdr->rx) -+ goto out; -+ -+ tpriv->ok = true; -+ complete(&tpriv->comp); -+out: -+ kfree_skb(skb); -+ return 0; -+} -+ -+static int sunxi_dwmac_loopback_run(struct stmmac_priv *priv, -+ struct sunxi_dwmac_packet_attr *attr) -+{ -+ struct sunxi_dwmac_loop_priv *tpriv; -+ struct sk_buff *skb = NULL; -+ int ret = 0; -+ -+ tpriv = kzalloc(sizeof(*tpriv), GFP_KERNEL); -+ if (!tpriv) -+ return -ENOMEM; -+ -+ tpriv->ok = false; -+ init_completion(&tpriv->comp); -+ -+ tpriv->pt.type = htons(ETH_P_IP); -+ tpriv->pt.func = sunxi_dwmac_loopback_validate; -+ tpriv->pt.dev = priv->dev; -+ tpriv->pt.af_packet_priv = tpriv; -+ tpriv->packet = attr; -+ -+ if (!attr->dont_wait) -+ dev_add_pack(&tpriv->pt); -+ -+ skb = sunxi_dwmac_get_skb(priv, attr); -+ if (!skb) { -+ ret = -ENOMEM; -+ goto cleanup; -+ } -+ -+ ret = dev_direct_xmit(skb, attr->queue_mapping); -+ if (ret) -+ goto cleanup; -+ -+ if (attr->dont_wait) -+ goto cleanup; -+ -+ if (!attr->timeout) -+ attr->timeout = SUNXI_DWMAC_TIMEOUT; -+ -+ wait_for_completion_timeout(&tpriv->comp, attr->timeout); -+ ret = tpriv->ok ? 0 : -ETIMEDOUT; -+ -+cleanup: -+ if (!attr->dont_wait) -+ dev_remove_pack(&tpriv->pt); -+ kfree(tpriv); -+ return ret; -+} -+ -+static int sunxi_dwmac_test_delaychain(struct sunxi_dwmac *chip, struct sunxi_dwmac_calibrate *cali) -+{ -+ struct net_device *ndev = dev_get_drvdata(chip->dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ unsigned char src[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -+ unsigned char dst[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -+ struct sunxi_dwmac_packet_attr attr = { }; -+ -+ chip->variant->set_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_TX, cali->tx_delay); -+ chip->variant->set_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_RX, cali->rx_delay); -+ -+ attr.src = src; -+ attr.dst = dst; -+ attr.tcp = true; -+ attr.queue_mapping = 0; -+ stmmac_get_systime(priv, priv->ptpaddr, &attr.timestamp); -+ attr.id = cali->id; -+ attr.tx = cali->tx_delay; -+ attr.rx = cali->rx_delay; -+ -+ return sunxi_dwmac_loopback_run(priv, &attr); -+} -+ -+static int sunxi_dwmac_calibrate_scan_window(struct sunxi_dwmac *chip, struct sunxi_dwmac_calibrate *cali) -+{ -+ struct net_device *ndev = dev_get_drvdata(chip->dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ char *buf, *ptr; -+ int tx_sum, rx_sum, count; -+ u32 tx, rx; -+ int ret = 0; -+ -+ buf = devm_kzalloc(chip->dev, PAGE_SIZE, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ netif_testing_on(ndev); -+ -+ ret = phy_loopback(priv->dev->phydev, true); -+ if (ret) -+ goto err; -+ -+ tx_sum = rx_sum = count = 0; -+ -+ for (tx = 0; tx < cali->window_tx; tx++) { -+ ptr = buf; -+ ptr += scnprintf(ptr, PAGE_SIZE - (ptr - buf), "TX(0x%02x): ", tx); -+ for (rx = 0; rx < cali->window_rx; rx++) { -+ cali->id++; -+ cali->tx_delay = tx; -+ cali->rx_delay = rx; -+ if (sunxi_dwmac_test_delaychain(chip, cali) < 0) { -+ ptr += scnprintf(ptr, PAGE_SIZE - (ptr - buf), "X"); -+ } else { -+ tx_sum += tx; -+ rx_sum += rx; -+ count++; -+ ptr += scnprintf(ptr, PAGE_SIZE - (ptr - buf), "-"); -+ } -+ } -+ ptr += scnprintf(ptr, PAGE_SIZE - (ptr - buf), "\n"); -+ printk(buf); -+ } -+ -+ if (tx_sum && rx_sum && count) { -+ cali->tx_delay = tx_sum / count; -+ cali->rx_delay = rx_sum / count; -+ } else { -+ cali->tx_delay = cali->rx_delay = 0; -+ } -+ -+ phy_loopback(priv->dev->phydev, false); -+ -+err: -+ netif_testing_off(ndev); -+ devm_kfree(chip->dev, buf); -+ return ret; -+} -+ -+static ssize_t sunxi_dwmac_calibrate_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ struct phy_device *phydev = priv->dev->phydev; -+ struct sunxi_dwmac_calibrate *cali; -+ u32 old_tx, old_rx; -+ int ret; -+ -+ if (!ndev || !phydev) { -+ sunxi_err(chip->dev, "Not found netdevice or phy\n"); -+ return -EINVAL; -+ } -+ -+ if (!netif_carrier_ok(ndev) || !phydev->link) { -+ sunxi_err(chip->dev, "Netdevice or phy not link\n"); -+ return -EINVAL; -+ } -+ -+ if (phydev->speed < SPEED_1000) { -+ sunxi_err(chip->dev, "Speed %s no need calibrate\n", phy_speed_to_str(phydev->speed)); -+ return -EINVAL; -+ } -+ -+ cali = devm_kzalloc(dev, sizeof(*cali), GFP_KERNEL); -+ if (!cali) -+ return -ENOMEM; -+ -+ old_tx = chip->variant->get_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_TX); -+ old_rx = chip->variant->get_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_RX); -+ -+ cali->window_tx = chip->variant->tx_delay_max + 1; -+ cali->window_rx = chip->variant->rx_delay_max + 1; -+ -+ ret = sunxi_dwmac_calibrate_scan_window(chip, cali); -+ if (ret) { -+ sunxi_err(dev, "Calibrate scan window tx:%d rx:%d failed\n", cali->window_tx, cali->window_rx); -+ goto err; -+ } -+ -+ if (cali->tx_delay && cali->rx_delay) { -+ chip->variant->set_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_TX, cali->tx_delay); -+ chip->variant->set_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_RX, cali->rx_delay); -+ sunxi_info(chip->dev, "Calibrate suitable delay tx:%d rx:%d\n", cali->tx_delay, cali->rx_delay); -+ } else { -+ chip->variant->set_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_TX, old_tx); -+ chip->variant->set_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_RX, old_rx); -+ sunxi_warn(chip->dev, "Calibrate cannot find suitable delay\n"); -+ } -+ -+err: -+ devm_kfree(dev, cali); -+ return count; -+} -+ -+static int sunxi_dwmac_test_ecc_inject(struct stmmac_priv *priv, enum sunxi_dwmac_ecc_fifo_type type, u8 bit) -+{ -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ static const u32 wdata[2] = {0x55555555, 0x55555555}; -+ u32 rdata[ARRAY_SIZE(wdata)]; -+ u32 mtl_dbg_ctl, mtl_dpp_ecc_eic; -+ u32 val; -+ int i, ret = 0; -+ -+ mtl_dbg_ctl = readl(priv->ioaddr + MTL_DBG_CTL); -+ mtl_dpp_ecc_eic = readl(priv->ioaddr + MTL_DPP_ECC_EIC); -+ -+ mtl_dbg_ctl &= ~EIAEE; /* disable ecc error injection on address */ -+ mtl_dbg_ctl |= DBGMOD | FDBGEN; /* ecc debug mode enable */ -+ mtl_dpp_ecc_eic &= ~EIM; /* indicate error injection on data */ -+ mtl_dpp_ecc_eic |= FIELD_PREP(BLEI, 36); /* inject bit location is bit0 and bit36 */ -+ -+ /* ecc select inject bit */ -+ switch (bit) { -+ case 0: -+ mtl_dbg_ctl &= ~EIEE; /* ecc inject error disable */ -+ break; -+ case 1: -+ mtl_dbg_ctl &= ~EIEC; /* ecc inject insert 1-bit error */ -+ mtl_dbg_ctl |= EIEE; /* ecc inject error enable */ -+ break; -+ case 2: -+ mtl_dbg_ctl |= EIEC; /* ecc inject insert 2-bit error */ -+ mtl_dbg_ctl |= EIEE; /* ecc inject error enable */ -+ break; -+ default: -+ ret = -EINVAL; -+ sunxi_err(chip->dev, "test unsupport ecc inject bit %d\n", bit); -+ goto err; -+ } -+ -+ /* ecc select fifo */ -+ mtl_dbg_ctl &= ~FIFOSEL; -+ switch (type) { -+ case SUNXI_DWMAC_ECC_FIFO_TX: -+ mtl_dbg_ctl |= FIELD_PREP(FIFOSEL, 0x0); -+ break; -+ case SUNXI_DWMAC_ECC_FIFO_RX: -+ mtl_dbg_ctl |= FIELD_PREP(FIFOSEL, 0x3); -+ break; -+ default: -+ ret = -EINVAL; -+ sunxi_err(chip->dev, "test unsupport ecc inject fifo type %d\n", type); -+ goto err; -+ } -+ -+ writel(mtl_dpp_ecc_eic, priv->ioaddr + MTL_DPP_ECC_EIC); -+ writel(mtl_dbg_ctl, priv->ioaddr + MTL_DBG_CTL); -+ -+ /* write fifo debug data */ -+ mtl_dbg_ctl &= ~FIFORDEN; -+ mtl_dbg_ctl |= FIFOWREN; -+ for (i = 0; i < ARRAY_SIZE(wdata); i++) { -+ writel(wdata[i], priv->ioaddr + MTL_FIFO_DEBUG_DATA); -+ writel(mtl_dbg_ctl, priv->ioaddr + MTL_DBG_CTL); -+ ret = readl_poll_timeout_atomic(priv->ioaddr + MTL_DBG_STS, val, !(val & FIFOBUSY), 10, 200000); -+ if (ret) { -+ sunxi_err(chip->dev, "timeout with ecc debug fifo write busy (%#x)\n", val); -+ goto err; -+ } -+ } -+ -+ /* read fifo debug data */ -+ mtl_dbg_ctl &= ~FIFOWREN; -+ mtl_dbg_ctl |= FIFORDEN; -+ for (i = 0; i < ARRAY_SIZE(wdata); i++) { -+ writel(mtl_dbg_ctl, priv->ioaddr + MTL_DBG_CTL); -+ ret = readl_poll_timeout_atomic(priv->ioaddr + MTL_DBG_STS, val, !(val & FIFOBUSY), 10, 200000); -+ if (ret) { -+ sunxi_err(chip->dev, "test timeout with ecc debug fifo read busy (%#x)\n", val); -+ goto err; -+ } -+ rdata[i] = readl(priv->ioaddr + MTL_FIFO_DEBUG_DATA); -+ } -+ -+ /* compare data */ -+ switch (bit) { -+ case 0: -+ case 1: -+ /* for ecc error inject 0/1 bit, read should be same with write */ -+ for (i = 0; i < ARRAY_SIZE(wdata); i++) { -+ if (rdata[i] != wdata[i]) { -+ ret = -EINVAL; -+ break; -+ } -+ } -+ break; -+ case 2: -+ /* for ecc error inject 2 bit, read should be different with write */ -+ for (i = 0; i < ARRAY_SIZE(wdata); i++) { -+ if (rdata[i] == wdata[i]) { -+ ret = -EINVAL; -+ break; -+ } -+ } -+ break; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(wdata); i++) -+ sunxi_info(chip->dev, "fifo %d write [%#x] -> read [%#x]\n", i, wdata[i], rdata[i]); -+ -+err: -+ /* ecc debug mode disable */ -+ mtl_dbg_ctl &= ~(EIEE | EIEC | FIFOWREN | FIFORDEN); -+ writel(mtl_dbg_ctl, priv->ioaddr + MTL_DBG_CTL); -+ -+ return ret; -+} -+ -+static ssize_t sunxi_dwmac_ecc_inject_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ return scnprintf(buf, PAGE_SIZE, -+ "Usage:\n" -+ "echo \"[dir] [inject_bit]\" > ecc_inject\n\n" -+ "[dir] : 0(tx) 1(rx)\n" -+ "[inject_bit] : 0/1/2\n"); -+} -+ -+static ssize_t sunxi_dwmac_ecc_inject_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ struct phy_device *phydev = priv->dev->phydev; -+ static const char *dir_str[] = {"tx", "rx"}; -+ u16 dir, inject_bit; -+ u64 ret; -+ -+ if (!ndev || !phydev) { -+ sunxi_err(chip->dev, "netdevice or phy not found\n"); -+ return -EINVAL; -+ } -+ -+ if (!netif_running(ndev)) { -+ sunxi_err(chip->dev, "netdevice is not running\n"); -+ return -EINVAL; -+ } -+ -+ if (!(chip->variant->flags & SUNXI_DWMAC_MEM_ECC)) { -+ sunxi_err(chip->dev, "ecc not support or enabled\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ ret = sunxi_dwmac_parse_read_str((char *)buf, &dir, &inject_bit); -+ if (ret) -+ return ret; -+ -+ switch (dir) { -+ case 0: -+ dir = SUNXI_DWMAC_ECC_FIFO_TX; -+ break; -+ case 1: -+ dir = SUNXI_DWMAC_ECC_FIFO_RX; -+ break; -+ default: -+ sunxi_err(chip->dev, "test unsupport ecc dir %d\n", dir); -+ return -EINVAL; -+ } -+ -+ netif_testing_on(ndev); -+ -+ /* ecc inject test */ -+ ret = sunxi_dwmac_test_ecc_inject(priv, dir, inject_bit); -+ if (ret) -+ sunxi_info(chip->dev, "test ecc %s inject %d bit : FAILED\n", dir_str[dir], inject_bit); -+ else -+ sunxi_info(chip->dev, "test ecc %s inject %d bit : PASS\n", dir_str[dir], inject_bit); -+ -+ netif_testing_off(ndev); -+ -+ return count; -+} -+ -+static ssize_t sunxi_dwmac_tx_delay_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ u32 delay = chip->variant->get_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_TX); -+ -+ return scnprintf(buf, PAGE_SIZE, -+ "Usage:\n" -+ "echo [0~%d] > tx_delay\n\n" -+ "now tx_delay: %d\n", -+ chip->variant->tx_delay_max, delay); -+} -+ -+static ssize_t sunxi_dwmac_tx_delay_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ int ret; -+ u32 delay; -+ -+ if (!netif_running(ndev)) { -+ sunxi_err(dev, "Eth is not running\n"); -+ return count; -+ } -+ -+ ret = kstrtou32(buf, 0, &delay); -+ if (ret) -+ return ret; -+ -+ if (delay > chip->variant->tx_delay_max) { -+ sunxi_err(dev, "Tx_delay exceed max %d\n", chip->variant->tx_delay_max); -+ return -EINVAL; -+ } -+ -+ chip->variant->set_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_TX, delay); -+ -+ return count; -+} -+ -+static ssize_t sunxi_dwmac_rx_delay_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ u32 delay = chip->variant->get_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_RX); -+ -+ return scnprintf(buf, PAGE_SIZE, -+ "Usage:\n" -+ "echo [0~%d] > rx_delay\n\n" -+ "now rx_delay: %d\n", -+ chip->variant->rx_delay_max, delay); -+} -+ -+static ssize_t sunxi_dwmac_rx_delay_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ int ret; -+ u32 delay; -+ -+ if (!netif_running(ndev)) { -+ sunxi_err(dev, "Eth is not running\n"); -+ return count; -+ } -+ -+ ret = kstrtou32(buf, 0, &delay); -+ if (ret) -+ return ret; -+ -+ if (delay > chip->variant->rx_delay_max) { -+ sunxi_err(dev, "Rx_delay exceed max %d\n", chip->variant->rx_delay_max); -+ return -EINVAL; -+ } -+ -+ chip->variant->set_delaychain(chip, SUNXI_DWMAC_DELAYCHAIN_RX, delay); -+ -+ return count; -+} -+ -+static ssize_t sunxi_dwmac_mii_read_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ -+ if (!netif_running(ndev)) { -+ sunxi_err(dev, "Eth is not running\n"); -+ return 0; -+ } -+ -+ chip->mii_reg.value = mdiobus_read(priv->mii, chip->mii_reg.addr, chip->mii_reg.reg); -+ return sprintf(buf, "ADDR[0x%02x]:REG[0x%02x] = 0x%04x\n", -+ chip->mii_reg.addr, chip->mii_reg.reg, chip->mii_reg.value); -+} -+ -+static ssize_t sunxi_dwmac_mii_read_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ int ret; -+ u16 reg, addr; -+ char *ptr; -+ -+ ptr = (char *)buf; -+ -+ if (!netif_running(ndev)) { -+ sunxi_err(dev, "Eth is not running\n"); -+ return count; -+ } -+ -+ ret = sunxi_dwmac_parse_read_str(ptr, &addr, ®); -+ if (ret) -+ return ret; -+ -+ chip->mii_reg.addr = addr; -+ chip->mii_reg.reg = reg; -+ -+ return count; -+} -+ -+static ssize_t sunxi_dwmac_mii_write_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ u16 bef_val, aft_val; -+ -+ if (!netif_running(ndev)) { -+ sunxi_err(dev, "Eth is not running\n"); -+ return 0; -+ } -+ -+ bef_val = mdiobus_read(priv->mii, chip->mii_reg.addr, chip->mii_reg.reg); -+ mdiobus_write(priv->mii, chip->mii_reg.addr, chip->mii_reg.reg, chip->mii_reg.value); -+ aft_val = mdiobus_read(priv->mii, chip->mii_reg.addr, chip->mii_reg.reg); -+ return sprintf(buf, "before ADDR[0x%02x]:REG[0x%02x] = 0x%04x\n" -+ "after ADDR[0x%02x]:REG[0x%02x] = 0x%04x\n", -+ chip->mii_reg.addr, chip->mii_reg.reg, bef_val, -+ chip->mii_reg.addr, chip->mii_reg.reg, aft_val); -+} -+ -+static ssize_t sunxi_dwmac_mii_write_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ int ret; -+ u16 reg, addr, val; -+ char *ptr; -+ -+ ptr = (char *)buf; -+ -+ if (!netif_running(ndev)) { -+ sunxi_err(dev, "Eth is not running\n"); -+ return count; -+ } -+ -+ ret = sunxi_dwmac_parse_write_str(ptr, &addr, ®, &val); -+ if (ret) -+ return ret; -+ -+ chip->mii_reg.reg = reg; -+ chip->mii_reg.addr = addr; -+ chip->mii_reg.value = val; -+ -+ return count; -+} -+ -+static ssize_t sunxi_dwmac_version_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct stmmac_priv *priv = netdev_priv(ndev); -+ struct sunxi_dwmac *chip = priv->plat->bsp_priv; -+ u16 ip_tag, ip_vrm; -+ ssize_t count = 0; -+ -+ if (chip->variant->get_version) { -+ chip->variant->get_version(chip, &ip_tag, &ip_vrm); -+ count = sprintf(buf, "IP TAG: %x\nIP VRM: %x\n", ip_tag, ip_vrm); -+ } -+ -+ return count; -+} -+ -+static struct device_attribute sunxi_dwmac_tool_attr[] = { -+ __ATTR(calibrate, 0220, NULL, sunxi_dwmac_calibrate_store), -+ __ATTR(rx_delay, 0664, sunxi_dwmac_rx_delay_show, sunxi_dwmac_rx_delay_store), -+ __ATTR(tx_delay, 0664, sunxi_dwmac_tx_delay_show, sunxi_dwmac_tx_delay_store), -+ __ATTR(mii_read, 0664, sunxi_dwmac_mii_read_show, sunxi_dwmac_mii_read_store), -+ __ATTR(mii_write, 0664, sunxi_dwmac_mii_write_show, sunxi_dwmac_mii_write_store), -+ __ATTR(ecc_inject, 0664, sunxi_dwmac_ecc_inject_show, sunxi_dwmac_ecc_inject_store), -+ __ATTR(version, 0444, sunxi_dwmac_version_show, NULL), -+}; -+ -+void sunxi_dwmac_sysfs_init(struct device *dev) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(sunxi_dwmac_tool_attr); i++) -+ device_create_file(dev, &sunxi_dwmac_tool_attr[i]); -+} -+ -+void sunxi_dwmac_sysfs_exit(struct device *dev) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(sunxi_dwmac_tool_attr); i++) -+ device_remove_file(dev, &sunxi_dwmac_tool_attr[i]); -+} -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi-sysfs.h linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi-sysfs.h ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi-sysfs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/dwmac-sunxi-sysfs.h 2025-01-21 15:58:05.577494134 +0100 -@@ -0,0 +1,20 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* Copyright(c) 2020 - 2023 Allwinner Technology Co.,Ltd. All rights reserved. */ -+/* -+* -+* Allwinner DWMAC driver sysfs haeder. -+* -+* Copyright(c) 2022-2027 Allwinnertech Co., Ltd. -+* -+*/ -+ -+#ifndef _DWMAC_SUNXI_SYSFS_H_ -+#define _DWMAC_SUNXI_SYSFS_H_ -+ -+#include "dwmac-sunxi.h" -+ -+void sunxi_dwmac_sysfs_init(struct device *dev); -+void sunxi_dwmac_sysfs_exit(struct device *dev); -+ -+#endif /* _DWMAC_SUNXI_SYSFS_H_ */ -+ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/Kconfig linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/Kconfig ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/Kconfig 2025-01-23 10:54:36.827432742 +0100 -@@ -0,0 +1,34 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+menu "Stmmac Drivers" -+ -+config SUNXI55I_GMAC200 -+ tristate "Allwinner A523 GMAC-200 driver" -+ depends on OF && (ARCH_SUNXI || COMPILE_TEST) -+ select STMMAC_ETH -+ select STMMAC_PLATFORM -+ select SUNXI55I_STMMAC -+ -+ help -+ Support for Allwinner A523 GMAC-200/GMAC-300 ethernet controllers. -+ -+ This selects Allwinner A523 SoC glue layer support for the -+ stmmac device driver. This driver is used for -+ GMAC-200/GMAC-300 ethernet controller. -+ -+if SUNXI55I_GMAC200 -+config SUNXI55I_STMMAC -+ tristate "Allwinner A523 GMAC-200 STMMAC support" -+ depends on OF && (ARCH_SUNXI || COMPILE_TEST) -+ help -+ Support stmmac device driver for Allwinner A523 GMAC-200/GMAC-300. -+ -+config SUNXI55I_STMMAC_UIO -+ tristate "Allwinner A523 GMAC-200 UIO ethernet controller" -+ default n -+ select UIO -+ help -+ Say M here if you want to use the sunxi-uio.ko for DPDK on A523. -+ -+endif -+ -+endmenu -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/Makefile linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/Makefile ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/Makefile 2025-01-23 10:41:37.537411780 +0100 -@@ -0,0 +1,8 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+ccflags-y += -I $(srctree)/include/linux/ -+ccflags-y += -I $(srctree)/drivers/net/ethernet/stmicro/ -+ccflags-y += -DDYNAMIC_DEBUG_MODULE -+ -+obj-$(CONFIG_SUNXI55I_STMMAC) += sunxi-stmmac.o -+sunxi-stmmac-objs += dwmac-sunxi.o dwmac-sunxi-sysfs.o -+obj-$(CONFIG_SUNXI55I_STMMAC_UIO) += sunxi-uio.o -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/sunxi-log.h linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/sunxi-log.h ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/sunxi-log.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/sunxi-log.h 2025-01-21 15:58:05.577494134 +0100 -@@ -0,0 +1,174 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* Copyright(c) 2020 - 2023 Allwinner Technology Co.,Ltd. All rights reserved. */ -+/* -+ * Allwinner's log functions -+ * -+ * Copyright (c) 2023, lvda -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the 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. -+ * -+ */ -+ -+#ifndef __SUNXI_LOG_H__ -+#define __SUNXI_LOG_H__ -+ -+#define SUNXI_LOG_VERSION "V0.7" -+/* Allow user to define their own MODNAME with `SUNXI_MODNAME` */ -+#ifndef SUNXI_MODNAME -+#define SUNXI_MODNAME KBUILD_MODNAME -+#endif -+ -+#ifdef pr_fmt -+#undef pr_fmt -+#endif -+ -+#ifdef dev_fmt -+#undef dev_fmt -+#endif -+ -+#define pr_fmt(fmt) "sunxi:" SUNXI_MODNAME fmt -+#define dev_fmt pr_fmt -+ -+#include -+#include -+ -+/* -+ * Copy from dev_name(). Someone like to use "dev_name" as local variable, -+ * which will case compile error. -+ */ -+static inline const char *sunxi_log_dev_name(const struct device *dev) -+{ -+ /* Use the init name until the kobject becomes available */ -+ if (dev->init_name) -+ return dev->init_name; -+ -+ return kobject_name(&dev->kobj); -+} -+ -+/* -+ * Parameter Description: -+ * 1. dev: Optional parameter. If the context cannot obtain dev, fill in NULL -+ * 2. fmt: Format specifier -+ * 3. err_code: Error code. Only used in sunxi_err_std() -+ * 4. ...: Variable arguments -+ */ -+ -+#if IS_ENABLED(CONFIG_AW_LOG_VERBOSE) -+ -+/* void sunxi_err(struct device *dev, char *fmt, ...); */ -+#define sunxi_err(dev, fmt, ...) \ -+ do { if (dev) \ -+ pr_err("-%s:[ERR]:%s +%d %s(): "fmt, sunxi_log_dev_name(dev), __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ else \ -+ pr_err(":[ERR]:%s +%d %s(): "fmt, __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ } while (0) -+ -+/* void sunxi_err_std(struct device *dev, int err_code, char *fmt, ...); */ -+#define sunxi_err_std(dev, err_code, fmt, ...) \ -+ do { if (dev) \ -+ pr_err("-%s:[ERR%d]:%s +%d %s(): "fmt, sunxi_log_dev_name(dev), err_code, __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ else \ -+ pr_err(":[ERR%d]:%s +%d %s(): "fmt, err_code, __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ } while (0) -+ -+/* void sunxi_warn(struct device *dev, char *fmt, ...); */ -+#define sunxi_warn(dev, fmt, ...) \ -+ do { if (dev) \ -+ pr_warn("-%s:[WARN]:%s +%d %s(): "fmt, sunxi_log_dev_name(dev), __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ else \ -+ pr_warn(":[WARN]:%s +%d %s(): "fmt, __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ } while (0) -+ -+/* void sunxi_info(struct device *dev, char *fmt, ...); */ -+#define sunxi_info(dev, fmt, ...) \ -+ do { if (dev) \ -+ pr_info("-%s:[INFO]:%s +%d %s(): "fmt, sunxi_log_dev_name(dev), __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ else \ -+ pr_info(":[INFO]:%s +%d %s(): "fmt, __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ } while (0) -+ -+/* void sunxi_debug(struct device *dev, char *fmt, ...); */ -+#define sunxi_debug(dev, fmt, ...) \ -+ do { if (dev) \ -+ pr_debug("-%s:[DEBUG]:%s +%d %s(): "fmt, sunxi_log_dev_name(dev), __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ else \ -+ pr_debug(":[DEBUG]:%s +%d %s(): "fmt, __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ } while (0) -+ -+#else /* !CONFIG_AW_LOG_VERBOSE */ -+ -+/* void sunxi_err(struct device *dev, char *fmt, ...); */ -+#define sunxi_err(dev, fmt, ...) \ -+ do { if (dev) \ -+ pr_err("-%s:[ERR]: "fmt, sunxi_log_dev_name(dev), ## __VA_ARGS__); \ -+ else \ -+ pr_err(":[ERR]: "fmt, ## __VA_ARGS__); \ -+ } while (0) -+ -+/* void sunxi_err_std(struct device *dev, int err_code, char *fmt, ...); */ -+#define sunxi_err_std(dev, err_code, fmt, ...) \ -+ do { if (dev) \ -+ pr_err("-%s:[ERR%d]: "fmt, sunxi_log_dev_name(dev), err_code, ## __VA_ARGS__); \ -+ else \ -+ pr_err(":[ERR%d]: "fmt, err_code, ## __VA_ARGS__); \ -+ } while (0) -+ -+/* void sunxi_warn(struct device *dev, char *fmt, ...); */ -+#define sunxi_warn(dev, fmt, ...) \ -+ do { if (dev) \ -+ pr_warn("-%s:[WARN]: "fmt, sunxi_log_dev_name(dev), ## __VA_ARGS__); \ -+ else \ -+ pr_warn(":[WARN]: "fmt, ## __VA_ARGS__); \ -+ } while (0) -+ -+/* void sunxi_info(struct device *dev, char *fmt, ...); */ -+#define sunxi_info(dev, fmt, ...) \ -+ do { if (dev) \ -+ pr_info("-%s:[INFO]: "fmt, sunxi_log_dev_name(dev), ## __VA_ARGS__); \ -+ else \ -+ pr_info(":[INFO]: "fmt, ## __VA_ARGS__); \ -+ } while (0) -+ -+/* void sunxi_debug(struct device *dev, char *fmt, ...); */ -+#define sunxi_debug(dev, fmt, ...) \ -+ do { if (dev) \ -+ pr_debug("-%s:[DEBUG]: "fmt, sunxi_log_dev_name(dev), ## __VA_ARGS__); \ -+ else \ -+ pr_debug(":[DEBUG]: "fmt, ## __VA_ARGS__); \ -+ } while (0) -+ -+#endif /* CONFIG_AW_LOG_VERBOSE */ -+ -+/* void sunxi_debug_verbose(struct device *dev, char *fmt, ...); */ -+#define sunxi_debug_verbose(dev, fmt, ...) \ -+ do { if (dev) \ -+ pr_debug("-%s:[DEBUG]:%s +%d %s(): "fmt, sunxi_log_dev_name(dev), __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ else \ -+ pr_debug(":[DEBUG]:%s +%d %s(): "fmt, __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ -+ } while (0) -+ -+/* void sunxi_debug_line(struct device *dev); */ -+#define sunxi_debug_line(dev) \ -+ do { if (dev) \ -+ pr_debug("-%s:[DEBUG]:%s +%d %s()\n", sunxi_log_dev_name(dev), __FILE__, __LINE__, __func__); \ -+ else \ -+ pr_debug(":[DEBUG]:%s +%d %s()\n", __FILE__, __LINE__, __func__); \ -+ } while (0) -+ -+/* -+ * TODO: -+ * print_hex_dump_debug -+ * print_hex_dump_bytes -+ * trace_printk -+ * printk_ratelimited -+*/ -+ -+#endif -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/sunxi-uio.c linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/sunxi-uio.c ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/sunxi-uio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac-200/sunxi-uio.c 2025-01-21 15:58:05.577494134 +0100 -@@ -0,0 +1,1015 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/** -+ * Copyright 2023 Allwinnertech -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "stmmac/stmmac_ptp.h" -+#include "stmmac/stmmac.h" -+#include "hwif.h" -+ -+#define DRIVER_NAME "sunxi_uio" -+#define DRIVER_VERSION "0.0.1" -+ -+#define TC_DEFAULT 64 -+static int tc = TC_DEFAULT; -+ -+#define DEFAULT_BUFSIZE 1536 -+static int buf_sz = DEFAULT_BUFSIZE; -+ -+#define STMMAC_RX_COPYBREAK 256 -+ -+/** -+ * sunxi_uio -+ * local information for uio module driver -+ * -+ * @dev: device pointer -+ * @ndev: network device pointer -+ * @name: uio name -+ * @uio: uio information -+ * @map_num: number of uio memory regions -+ */ -+struct sunxi_uio { -+ struct device *dev; -+ struct net_device *ndev; -+ char name[16]; -+ struct uio_info uio; -+ int map_num; -+}; -+ -+static int sunxi_uio_open(struct uio_info *info, struct inode *inode) -+{ -+ return 0; -+} -+ -+static int sunxi_uio_release(struct uio_info *info, -+ struct inode *inode) -+{ -+ return 0; -+} -+ -+static int sunxi_uio_mmap(struct uio_info *info, -+ struct vm_area_struct *vma) -+{ -+ u32 ret, pfn; -+ -+ pfn = (info->mem[vma->vm_pgoff].addr) >> PAGE_SHIFT; -+ -+ if (vma->vm_pgoff) -+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -+ else -+ vma->vm_page_prot = pgprot_device(vma->vm_page_prot); -+ -+ ret = remap_pfn_range(vma, vma->vm_start, pfn, -+ vma->vm_end - vma->vm_start, vma->vm_page_prot); -+ if (ret) { -+ /* Error Handle */ -+ pr_err("remap_pfn_range failed"); -+ } -+ return ret; -+} -+ -+/** -+ * sunxi_uio_free_dma_rx_desc_resources - free RX dma desc resources -+ * @priv: private structure -+ */ -+static void sunxi_uio_free_dma_rx_desc_resources(struct stmmac_priv *priv) -+{ -+ u32 queue, rx_count = priv->plat->rx_queues_to_use; -+ -+ /* Free RX queue resources */ -+ for (queue = 0; queue < rx_count; queue++) { -+ struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ -+ /* Free DMA regions of consistent memory previously allocated */ -+ if (!priv->extend_desc) -+ dma_free_coherent(priv->device, priv->dma_rx_size * -+ sizeof(struct dma_desc), -+ rx_q->dma_rx, rx_q->dma_rx_phy); -+ else -+ dma_free_coherent(priv->device, priv->dma_rx_size * -+ sizeof(struct dma_extended_desc), -+ rx_q->dma_erx, rx_q->dma_rx_phy); -+ } -+} -+ -+/** -+ * sunxi_uio_free_dma_tx_desc_resources - free TX dma desc resources -+ * @priv: private structure -+ */ -+static void sunxi_uio_free_dma_tx_desc_resources(struct stmmac_priv *priv) -+{ -+ u32 queue, tx_count = priv->plat->tx_queues_to_use; -+ -+ /* Free TX queue resources */ -+ for (queue = 0; queue < tx_count; queue++) { -+ struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ size_t size; -+ void *addr; -+ -+ if (priv->extend_desc) { -+ size = sizeof(struct dma_extended_desc); -+ addr = tx_q->dma_etx; -+ } else if (tx_q->tbs & STMMAC_TBS_AVAIL) { -+ size = sizeof(struct dma_edesc); -+ addr = tx_q->dma_entx; -+ } else { -+ size = sizeof(struct dma_desc); -+ addr = tx_q->dma_tx; -+ } -+ -+ size *= priv->dma_tx_size; -+ -+ dma_free_coherent(priv->device, size, addr, tx_q->dma_tx_phy); -+ } -+} -+ -+/** -+ * sunxi_uio_alloc_dma_rx_desc_resources - alloc RX resources. -+ * @priv: private structure -+ * Description: according to which descriptor can be used (extend or basic) -+ * this function allocates the resources for TX and RX paths. In case of -+ * reception, for example, it pre-allocated the RX socket buffer in order to -+ * allow zero-copy mechanism. -+ */ -+static int sunxi_uio_alloc_dma_rx_desc_resources(struct stmmac_priv *priv) -+{ -+ u32 queue, rx_count = priv->plat->rx_queues_to_use; -+ int ret = -ENOMEM; -+ -+ /* RX queues buffers and DMA */ -+ for (queue = 0; queue < rx_count; queue++) { -+ struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ -+ if (priv->extend_desc) { -+ rx_q->dma_erx = dma_alloc_coherent(priv->device, -+ priv->dma_rx_size * -+ sizeof(struct dma_extended_desc), -+ &rx_q->dma_rx_phy, -+ GFP_KERNEL); -+ if (!rx_q->dma_erx) -+ goto err_dma; -+ } else { -+ rx_q->dma_rx = dma_alloc_coherent(priv->device, -+ priv->dma_rx_size * -+ sizeof(struct dma_desc), -+ &rx_q->dma_rx_phy, -+ GFP_KERNEL); -+ if (!rx_q->dma_rx) -+ goto err_dma; -+ } -+ } -+ -+ return 0; -+ -+err_dma: -+ sunxi_uio_free_dma_rx_desc_resources(priv); -+ -+ return ret; -+} -+ -+/** -+ * sunxi_uio_alloc_dma_tx_desc_resources - alloc TX resources. -+ * @priv: private structure -+ * Description: according to which descriptor can be used (extend or basic) -+ * this function allocates the resources for TX and RX paths. In case of -+ * reception, for example, it pre-allocated the RX socket buffer in order to -+ * allow zero-copy mechanism. -+ */ -+static int sunxi_uio_alloc_dma_tx_desc_resources(struct stmmac_priv *priv) -+{ -+ u32 queue, tx_count = priv->plat->tx_queues_to_use; -+ int ret = -ENOMEM; -+ -+ /* TX queues buffers and DMA */ -+ for (queue = 0; queue < tx_count; queue++) { -+ struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ size_t size; -+ void *addr; -+ -+ tx_q->queue_index = queue; -+ tx_q->priv_data = priv; -+ -+ if (priv->extend_desc) -+ size = sizeof(struct dma_extended_desc); -+ else if (tx_q->tbs & STMMAC_TBS_AVAIL) -+ size = sizeof(struct dma_edesc); -+ else -+ size = sizeof(struct dma_desc); -+ -+ size *= priv->dma_tx_size; -+ -+ addr = dma_alloc_coherent(priv->device, size, -+ &tx_q->dma_tx_phy, GFP_KERNEL); -+ if (!addr) -+ goto err_dma; -+ -+ if (priv->extend_desc) -+ tx_q->dma_etx = addr; -+ else if (tx_q->tbs & STMMAC_TBS_AVAIL) -+ tx_q->dma_entx = addr; -+ else -+ tx_q->dma_tx = addr; -+ } -+ -+ return 0; -+ -+err_dma: -+ sunxi_uio_free_dma_tx_desc_resources(priv); -+ return ret; -+} -+ -+/** -+ * sunxi_uio_alloc_dma_desc_resources - alloc TX/RX resources. -+ * @priv: private structure -+ * Description: according to which descriptor can be used (extend or basic) -+ * this function allocates the resources for TX and RX paths. In case of -+ * reception, for example, it pre-allocated the RX socket buffer in order to -+ * allow zero-copy mechanism. -+ */ -+static int sunxi_uio_alloc_dma_desc_resources(struct stmmac_priv *priv) -+{ -+ /* RX Allocation */ -+ int ret = sunxi_uio_alloc_dma_rx_desc_resources(priv); -+ -+ if (ret) -+ return ret; -+ -+ ret = sunxi_uio_alloc_dma_tx_desc_resources(priv); -+ -+ return ret; -+} -+ -+/** -+ * sunxi_uio_free_dma_desc_resources - free dma desc resources -+ * @priv: private structure -+ */ -+static void sunxi_uio_free_dma_desc_resources(struct stmmac_priv *priv) -+{ -+ /* Release the DMA RX socket buffers */ -+ sunxi_uio_free_dma_rx_desc_resources(priv); -+ -+ /* Release the DMA TX socket buffers */ -+ sunxi_uio_free_dma_tx_desc_resources(priv); -+} -+ -+/** -+ * sunxi_uio_init_phy - PHY initialization -+ * @dev: net device structure -+ * Description: it initializes the driver's PHY state, and attaches the PHY -+ * to the mac driver. -+ * Return value: -+ * 0 on success -+ */ -+static int sunxi_uio_init_phy(struct net_device *dev) -+{ -+ struct stmmac_priv *priv = netdev_priv(dev); -+ struct device_node *node; -+ int ret; -+ -+ node = priv->plat->phylink_node; -+ -+ if (node) -+ ret = phylink_of_phy_connect(priv->phylink, node, 0); -+ -+ /* Some DT bindings do not set-up the PHY handle. Let's try to -+ * manually parse it -+ */ -+ if (!node || ret) { -+ int addr = priv->plat->phy_addr; -+ struct phy_device *phydev; -+ -+ phydev = mdiobus_get_phy(priv->mii, addr); -+ if (!phydev) { -+ netdev_err(priv->dev, "no phy at addr %d\n", addr); -+ return -ENODEV; -+ } -+ -+ ret = phylink_connect_phy(priv->phylink, phydev); -+ } -+ -+ if (!priv->plat->pmt) { -+ struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; -+ -+ phylink_ethtool_get_wol(priv->phylink, &wol); -+ device_set_wakeup_capable(priv->device, !!wol.supported); -+ } -+ -+ return ret; -+} -+ -+/** -+ * sunxi_uio_init_dma_engine - DMA init. -+ * @priv: driver private structure -+ * Description: -+ * It inits the DMA invoking the specific MAC/GMAC callback. -+ * Some DMA parameters can be passed from the platform; -+ * in case of these are not passed a default is kept for the MAC or GMAC. -+ */ -+static int sunxi_uio_init_dma_engine(struct stmmac_priv *priv) -+{ -+ u32 rx_channels_count = priv->plat->rx_queues_to_use; -+ u32 tx_channels_count = priv->plat->tx_queues_to_use; -+ u32 dma_csr_ch = max(rx_channels_count, tx_channels_count); -+ struct stmmac_rx_queue *rx_q; -+ struct stmmac_tx_queue *tx_q; -+ u32 chan = 0; -+ int atds = 0, ret = 0; -+ -+ if (!priv->plat->dma_cfg || !priv->plat->dma_cfg->pbl) { -+ dev_err(priv->device, "Invalid DMA configuration\n"); -+ return -EINVAL; -+ } -+ -+ if (priv->extend_desc && priv->mode == STMMAC_RING_MODE) -+ atds = 1; -+ -+ ret = stmmac_reset(priv, priv->ioaddr); -+ if (ret) { -+ dev_err(priv->device, "Failed to reset the dma\n"); -+ return ret; -+ } -+ -+ /* DMA Configuration */ -+ stmmac_dma_init(priv, priv->ioaddr, priv->plat->dma_cfg, atds); -+ -+ if (priv->plat->axi) -+ stmmac_axi(priv, priv->ioaddr, priv->plat->axi); -+ -+ /* DMA CSR Channel configuration */ -+ for (chan = 0; chan < dma_csr_ch; chan++) -+ stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan); -+ -+ /* DMA RX Channel Configuration */ -+ for (chan = 0; chan < rx_channels_count; chan++) { -+ rx_q = &priv->rx_queue[chan]; -+ -+ stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, -+ rx_q->dma_rx_phy, chan); -+ -+ rx_q->rx_tail_addr = rx_q->dma_rx_phy + -+ (priv->dma_rx_size * -+ sizeof(struct dma_desc)); -+ stmmac_set_rx_tail_ptr(priv, priv->ioaddr, -+ rx_q->rx_tail_addr, chan); -+ } -+ -+ /* DMA TX Channel Configuration */ -+ for (chan = 0; chan < tx_channels_count; chan++) { -+ tx_q = &priv->tx_queue[chan]; -+ -+ stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, -+ tx_q->dma_tx_phy, chan); -+ -+ tx_q->tx_tail_addr = tx_q->dma_tx_phy; -+ stmmac_set_tx_tail_ptr(priv, priv->ioaddr, -+ tx_q->tx_tail_addr, chan); -+ } -+ -+ return ret; -+} -+ -+static void sunxi_uio_set_rings_length(struct stmmac_priv *priv) -+{ -+ u32 rx_channels_count = priv->plat->rx_queues_to_use; -+ u32 tx_channels_count = priv->plat->tx_queues_to_use; -+ u32 chan; -+ -+ /* set TX ring length */ -+ for (chan = 0; chan < tx_channels_count; chan++) -+ stmmac_set_tx_ring_len(priv, priv->ioaddr, -+ (priv->dma_tx_size - 1), chan); -+ -+ /* set RX ring length */ -+ for (chan = 0; chan < rx_channels_count; chan++) -+ stmmac_set_rx_ring_len(priv, priv->ioaddr, -+ (priv->dma_rx_size - 1), chan); -+} -+ -+/** -+ * sunxi_uio_set_tx_queue_weight - Set TX queue weight -+ * @priv: driver private structure -+ * Description: It is used for setting TX queues weight -+ */ -+static void sunxi_uio_set_tx_queue_weight(struct stmmac_priv *priv) -+{ -+ u32 tx_queues_count = priv->plat->tx_queues_to_use; -+ u32 weight, queue; -+ -+ for (queue = 0; queue < tx_queues_count; queue++) { -+ weight = priv->plat->tx_queues_cfg[queue].weight; -+ stmmac_set_mtl_tx_queue_weight(priv, priv->hw, weight, queue); -+ } -+} -+ -+/** -+ * sunxi_uio_configure_cbs - Configure CBS in TX queue -+ * @priv: driver private structure -+ * Description: It is used for configuring CBS in AVB TX queues -+ */ -+static void sunxi_uio_configure_cbs(struct stmmac_priv *priv) -+{ -+ u32 tx_queues_count = priv->plat->tx_queues_to_use; -+ u32 mode_to_use, queue; -+ -+ /* queue 0 is reserved for legacy traffic */ -+ for (queue = 1; queue < tx_queues_count; queue++) { -+ mode_to_use = priv->plat->tx_queues_cfg[queue].mode_to_use; -+ if (mode_to_use == MTL_QUEUE_DCB) -+ continue; -+ -+ stmmac_config_cbs(priv, priv->hw, -+ priv->plat->tx_queues_cfg[queue].send_slope, -+ priv->plat->tx_queues_cfg[queue].idle_slope, -+ priv->plat->tx_queues_cfg[queue].high_credit, -+ priv->plat->tx_queues_cfg[queue].low_credit, -+ queue); -+ } -+} -+ -+/** -+ * sunxi_uio_rx_queue_dma_chan_map - Map RX queue to RX dma channel -+ * @priv: driver private structure -+ * Description: It is used for mapping RX queues to RX dma channels -+ */ -+static void sunxi_uio_rx_queue_dma_chan_map(struct stmmac_priv *priv) -+{ -+ u32 rx_queues_count = priv->plat->rx_queues_to_use; -+ u32 queue, chan; -+ -+ for (queue = 0; queue < rx_queues_count; queue++) { -+ chan = priv->plat->rx_queues_cfg[queue].chan; -+ stmmac_map_mtl_to_dma(priv, priv->hw, queue, chan); -+ } -+} -+ -+/** -+ * sunxi_uio_mac_config_rx_queues_prio - Configure RX Queue priority -+ * @priv: driver private structure -+ * Description: It is used for configuring the RX Queue Priority -+ */ -+static void sunxi_uio_mac_config_rx_queues_prio(struct stmmac_priv *priv) -+{ -+ u32 rx_queues_count = priv->plat->rx_queues_to_use; -+ u32 queue, prio; -+ -+ for (queue = 0; queue < rx_queues_count; queue++) { -+ if (!priv->plat->rx_queues_cfg[queue].use_prio) -+ continue; -+ -+ prio = priv->plat->rx_queues_cfg[queue].prio; -+ stmmac_rx_queue_prio(priv, priv->hw, prio, queue); -+ } -+} -+ -+/** -+ * sunxi_uio_mac_config_tx_queues_prio - Configure TX Queue priority -+ * @priv: driver private structure -+ * Description: It is used for configuring the TX Queue Priority -+ */ -+static void sunxi_uio_mac_config_tx_queues_prio(struct stmmac_priv *priv) -+{ -+ u32 tx_queues_count = priv->plat->tx_queues_to_use; -+ u32 queue, prio; -+ -+ for (queue = 0; queue < tx_queues_count; queue++) { -+ if (!priv->plat->tx_queues_cfg[queue].use_prio) -+ continue; -+ -+ prio = priv->plat->tx_queues_cfg[queue].prio; -+ stmmac_tx_queue_prio(priv, priv->hw, prio, queue); -+ } -+} -+ -+/** -+ * sunxi_uio_mac_config_rx_queues_routing - Configure RX Queue Routing -+ * @priv: driver private structure -+ * Description: It is used for configuring the RX queue routing -+ */ -+static void sunxi_uio_mac_config_rx_queues_routing(struct stmmac_priv *priv) -+{ -+ u32 rx_queues_count = priv->plat->rx_queues_to_use; -+ u32 queue; -+ u8 packet; -+ -+ for (queue = 0; queue < rx_queues_count; queue++) { -+ /* no specific packet type routing specified for the queue */ -+ if (priv->plat->rx_queues_cfg[queue].pkt_route == 0x0) -+ continue; -+ -+ packet = priv->plat->rx_queues_cfg[queue].pkt_route; -+ stmmac_rx_queue_routing(priv, priv->hw, packet, queue); -+ } -+} -+ -+static void sunxi_uio_mac_config_rss(struct stmmac_priv *priv) -+{ -+ if (!priv->dma_cap.rssen || !priv->plat->rss_en) { -+ priv->rss.enable = false; -+ return; -+ } -+ -+ if (priv->dev->features & NETIF_F_RXHASH) -+ priv->rss.enable = true; -+ else -+ priv->rss.enable = false; -+ -+ stmmac_rss_configure(priv, priv->hw, &priv->rss, -+ priv->plat->rx_queues_to_use); -+} -+ -+/** -+ * sunxi_uio_mac_enable_rx_queues - Enable MAC rx queues -+ * @priv: driver private structure -+ * Description: It is used for enabling the rx queues in the MAC -+ */ -+static void sunxi_uio_mac_enable_rx_queues(struct stmmac_priv *priv) -+{ -+ u32 rx_queues_count = priv->plat->rx_queues_to_use; -+ int queue; -+ u8 mode; -+ -+ for (queue = 0; queue < rx_queues_count; queue++) { -+ mode = priv->plat->rx_queues_cfg[queue].mode_to_use; -+ stmmac_rx_queue_enable(priv, priv->hw, mode, queue); -+ } -+} -+ -+/** -+ * sunxi_uio_mtl_configuration - Configure MTL -+ * @priv: driver private structure -+ * Description: It is used for configuring MTL -+ */ -+static void sunxi_uio_mtl_configuration(struct stmmac_priv *priv) -+{ -+ u32 rx_queues_count = priv->plat->rx_queues_to_use; -+ u32 tx_queues_count = priv->plat->tx_queues_to_use; -+ -+ if (tx_queues_count > 1) -+ sunxi_uio_set_tx_queue_weight(priv); -+ -+ /* Configure MTL RX algorithms */ -+ if (rx_queues_count > 1) -+ stmmac_prog_mtl_rx_algorithms(priv, priv->hw, -+ priv->plat->rx_sched_algorithm); -+ -+ /* Configure MTL TX algorithms */ -+ if (tx_queues_count > 1) -+ stmmac_prog_mtl_tx_algorithms(priv, priv->hw, -+ priv->plat->tx_sched_algorithm); -+ -+ /* Configure CBS in AVB TX queues */ -+ if (tx_queues_count > 1) -+ sunxi_uio_configure_cbs(priv); -+ -+ /* Map RX MTL to DMA channels */ -+ sunxi_uio_rx_queue_dma_chan_map(priv); -+ -+ /* Enable MAC RX Queues */ -+ sunxi_uio_mac_enable_rx_queues(priv); -+ -+ /* Set RX priorities */ -+ if (rx_queues_count > 1) -+ sunxi_uio_mac_config_rx_queues_prio(priv); -+ -+ /* Set TX priorities */ -+ if (tx_queues_count > 1) -+ sunxi_uio_mac_config_tx_queues_prio(priv); -+ -+ /* Set RX routing */ -+ if (rx_queues_count > 1) -+ sunxi_uio_mac_config_rx_queues_routing(priv); -+ -+ /* Receive Side Scaling */ -+ if (rx_queues_count > 1) -+ sunxi_uio_mac_config_rss(priv); -+} -+ -+static void sunxi_uio_safety_feat_configuration(struct stmmac_priv *priv) -+{ -+ if (priv->dma_cap.asp) { -+ netdev_info(priv->dev, "Enabling Safety Features\n"); -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) -+ stmmac_safety_feat_config(priv, priv->ioaddr, priv->dma_cap.asp); -+#else -+ stmmac_safety_feat_config(priv, priv->ioaddr, priv->dma_cap.asp, -+ priv->plat->safety_feat_cfg); -+#endif -+ } else { -+ netdev_info(priv->dev, "No Safety Features support found\n"); -+ } -+} -+ -+/** -+ * sunxi_uio_dma_operation_mode - HW DMA operation mode -+ * @priv: driver private structure -+ * Description: it is used for configuring the DMA operation mode register in -+ * order to program the tx/rx DMA thresholds or Store-And-Forward mode. -+ */ -+static void sunxi_uio_dma_operation_mode(struct stmmac_priv *priv) -+{ -+ u32 rx_channels_count = priv->plat->rx_queues_to_use; -+ u32 tx_channels_count = priv->plat->tx_queues_to_use; -+ int rxfifosz = priv->plat->rx_fifo_size; -+ int txfifosz = priv->plat->tx_fifo_size; -+ u32 txmode = 0, rxmode = 0, chan = 0; -+ u8 qmode = 0; -+ -+ if (rxfifosz == 0) -+ rxfifosz = priv->dma_cap.rx_fifo_size; -+ if (txfifosz == 0) -+ txfifosz = priv->dma_cap.tx_fifo_size; -+ -+ /* Adjust for real per queue fifo size */ -+ rxfifosz /= rx_channels_count; -+ txfifosz /= tx_channels_count; -+ -+ if (priv->plat->force_thresh_dma_mode) { -+ txmode = tc; -+ rxmode = tc; -+ } else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) { -+ /* In case of GMAC, SF mode can be enabled -+ * to perform the TX COE in HW. This depends on: -+ * 1) TX COE if actually supported -+ * 2) There is no bugged Jumbo frame support -+ * that needs to not insert csum in the TDES. -+ */ -+ txmode = SF_DMA_MODE; -+ rxmode = SF_DMA_MODE; -+ priv->xstats.threshold = SF_DMA_MODE; -+ } else { -+ txmode = tc; -+ rxmode = SF_DMA_MODE; -+ } -+ -+ /* configure all channels */ -+ for (chan = 0; chan < rx_channels_count; chan++) { -+ qmode = priv->plat->rx_queues_cfg[chan].mode_to_use; -+ -+ stmmac_dma_rx_mode(priv, priv->ioaddr, rxmode, chan, -+ rxfifosz, qmode); -+ stmmac_set_dma_bfsize(priv, priv->ioaddr, priv->dma_buf_sz, -+ chan); -+ } -+ -+ for (chan = 0; chan < tx_channels_count; chan++) { -+ qmode = priv->plat->tx_queues_cfg[chan].mode_to_use; -+ -+ stmmac_dma_tx_mode(priv, priv->ioaddr, txmode, chan, -+ txfifosz, qmode); -+ } -+} -+ -+/** -+ * sunxi_uio_hw_setup - setup mac in a usable state. -+ * @dev : pointer to the device structure. -+ * @init_ptp: initialize PTP if set -+ * Description: -+ * this is the main function to setup the HW in a usable state because the -+ * dma engine is reset, the core registers are configured (e.g. AXI, -+ * Checksum features, timers). The DMA is ready to start receiving and -+ * transmitting. -+ * Return value: -+ * 0 on success and an appropriate (-)ve integer as defined in errno.h -+ * file on failure. -+ */ -+static int sunxi_uio_hw_setup(struct net_device *dev, bool init_ptp) -+{ -+ struct stmmac_priv *priv = netdev_priv(dev); -+ int ret; -+ -+ /* DMA initialization and SW reset */ -+ ret = sunxi_uio_init_dma_engine(priv); -+ if (ret < 0) { -+ netdev_err(priv->dev, "%s: DMA engine initialization failed\n", -+ __func__); -+ return ret; -+ } -+ -+ /* Copy the MAC addr into the HW */ -+ stmmac_set_umac_addr(priv, priv->hw, dev->dev_addr, 0); -+ -+ /* PS and related bits will be programmed according to the speed */ -+ if (priv->hw->pcs) { -+ int speed = priv->plat->mac_port_sel_speed; -+ -+ if (speed == SPEED_10 || speed == SPEED_100 || -+ speed == SPEED_1000) { -+ priv->hw->ps = speed; -+ } else { -+ dev_warn(priv->device, "invalid port speed\n"); -+ priv->hw->ps = 0; -+ } -+ } -+ -+ /* Initialize the MAC Core */ -+ stmmac_core_init(priv, priv->hw, dev); -+ -+ /* Initialize MTL*/ -+ sunxi_uio_mtl_configuration(priv); -+ -+ /* Initialize Safety Features */ -+ sunxi_uio_safety_feat_configuration(priv); -+ -+ ret = stmmac_rx_ipc(priv, priv->hw); -+ if (!ret) { -+ netdev_warn(priv->dev, "RX IPC Checksum Offload disabled\n"); -+ priv->plat->rx_coe = STMMAC_RX_COE_NONE; -+ priv->hw->rx_csum = 0; -+ } -+ -+ /* Enable the MAC Rx/Tx */ -+ stmmac_mac_set(priv, priv->ioaddr, true); -+ -+ /* Set the HW DMA mode and the COE */ -+ sunxi_uio_dma_operation_mode(priv); -+ -+ if (priv->hw->pcs) -+ stmmac_pcs_ctrl_ane(priv, priv->hw, 1, priv->hw->ps, 0); -+ -+ /* set TX and RX rings length */ -+ sunxi_uio_set_rings_length(priv); -+ -+ return 0; -+} -+ -+static int sunxi_uio_set_bfsize(int mtu, int bufsize) -+{ -+ int ret = bufsize; -+ -+ if (mtu >= BUF_SIZE_8KiB) -+ ret = BUF_SIZE_16KiB; -+ else if (mtu >= BUF_SIZE_4KiB) -+ ret = BUF_SIZE_8KiB; -+ else if (mtu >= BUF_SIZE_2KiB) -+ ret = BUF_SIZE_4KiB; -+ else if (mtu > DEFAULT_BUFSIZE) -+ ret = BUF_SIZE_2KiB; -+ else -+ ret = DEFAULT_BUFSIZE; -+ -+ return ret; -+} -+ -+/** -+ * sunxi_uio_init - open entry point of the driver -+ * @dev : pointer to the device structure. -+ * Description: -+ * This function is the open entry point of the driver. -+ * Return value: -+ * 0 on success and an appropriate (-)ve integer as defined in errno.h -+ * file on failure. -+ */ -+static int sunxi_uio_init(struct net_device *dev) -+{ -+ struct stmmac_priv *priv = netdev_priv(dev); -+ int ret, bfsize = 0; -+ -+ if (priv->hw->pcs != STMMAC_PCS_TBI && -+ priv->hw->pcs != STMMAC_PCS_RTBI && -+ !priv->hw->xpcs) { -+ ret = sunxi_uio_init_phy(dev); -+ if (ret) { -+ netdev_err(priv->dev, -+ "%s: Cannot attach to PHY (error: %d)\n", -+ __func__, ret); -+ return ret; -+ } -+ } -+ -+ /* Extra statistics */ -+ priv->xstats.threshold = tc; -+ -+ bfsize = stmmac_set_16kib_bfsize(priv, dev->mtu); -+ if (bfsize < 0) -+ bfsize = 0; -+ -+ if (bfsize < BUF_SIZE_16KiB) -+ bfsize = sunxi_uio_set_bfsize(dev->mtu, priv->dma_buf_sz); -+ -+ priv->dma_buf_sz = bfsize; -+ buf_sz = bfsize; -+ -+ priv->rx_copybreak = STMMAC_RX_COPYBREAK; -+ -+ if (!priv->dma_tx_size) -+ priv->dma_tx_size = DMA_DEFAULT_TX_SIZE; -+ if (!priv->dma_rx_size) -+ priv->dma_rx_size = DMA_DEFAULT_RX_SIZE; -+ -+ ret = sunxi_uio_alloc_dma_desc_resources(priv); -+ if (ret < 0) { -+ netdev_err(priv->dev, "%s: DMA descriptors allocation failed\n", -+ __func__); -+ goto dma_desc_error; -+ } -+ -+ ret = sunxi_uio_hw_setup(dev, true); -+ if (ret < 0) { -+ netdev_err(priv->dev, "%s: Hw setup failed\n", __func__); -+ goto init_error; -+ } -+ -+ phylink_start(priv->phylink); -+ /* We may have called phylink_speed_down before */ -+ phylink_speed_up(priv->phylink); -+ -+ return 0; -+ -+init_error: -+ sunxi_uio_free_dma_desc_resources(priv); -+dma_desc_error: -+ phylink_disconnect_phy(priv->phylink); -+ return ret; -+} -+ -+/** -+ * sunxi_uio_exit - close entry point of the driver -+ * @dev : device pointer. -+ * Description: -+ * This is the stop entry point of the driver. -+ */ -+static int sunxi_uio_exit(struct net_device *dev) -+{ -+ struct stmmac_priv *priv = netdev_priv(dev); -+ -+ /* Stop and disconnect the PHY */ -+ if (dev->phydev) { -+ phy_stop(dev->phydev); -+ phy_disconnect(dev->phydev); -+ } -+ -+ /* Release and free the Rx/Tx resources */ -+ sunxi_uio_free_dma_desc_resources(priv); -+ -+ /* Disable the MAC Rx/Tx */ -+ stmmac_mac_set(priv, priv->ioaddr, false); -+ -+ netif_carrier_off(dev); -+ -+ return 0; -+} -+ -+/** -+ * sunxi_uio_probe() platform driver probe routine -+ * - register uio devices filled with memory maps retrieved -+ * from device tree -+ */ -+static int sunxi_uio_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node, *mac_node; -+ struct sunxi_uio *chip; -+ struct net_device *netdev; -+ struct stmmac_priv *priv; -+ struct uio_info *uio; -+ struct resource *res; -+ int err = 0; -+ -+ chip = devm_kzalloc(dev, sizeof(struct sunxi_uio), -+ GFP_KERNEL); -+ if (!chip) -+ return -ENOMEM; -+ -+ uio = &chip->uio; -+ chip->dev = dev; -+ mac_node = of_parse_phandle(np, "sunxi,ethernet", 0); -+ if (!mac_node) -+ return -ENODEV; -+ -+ if (of_device_is_available(mac_node)) { -+ netdev = of_find_net_device_by_node(mac_node); -+ of_node_put(mac_node); -+ if (!netdev) -+ return -ENODEV; -+ } else { -+ of_node_put(mac_node); -+ return -EINVAL; -+ } -+ -+ chip->ndev = netdev; -+ rtnl_lock(); -+ dev_close(netdev); -+ rtnl_unlock(); -+ -+ rtnl_lock(); -+ err = sunxi_uio_init(netdev); -+ if (err) { -+ rtnl_unlock(); -+ dev_err(dev, "Failed to open stmmac resource: %d\n", err); -+ return err; -+ } -+ rtnl_unlock(); -+ -+ priv = netdev_priv(netdev); -+ snprintf(chip->name, sizeof(chip->name), "uio_%s", -+ netdev->name); -+ uio->name = chip->name; -+ uio->version = DRIVER_VERSION; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -ENODEV; -+ -+ uio->mem[0].name = "eth_regs"; -+ uio->mem[0].addr = res->start & PAGE_MASK; -+ uio->mem[0].size = PAGE_ALIGN(resource_size(res)); -+ uio->mem[0].memtype = UIO_MEM_PHYS; -+ -+ uio->mem[1].name = "eth_rx_bd"; -+ uio->mem[1].addr = priv->rx_queue[0].dma_rx_phy; -+ uio->mem[1].size = priv->dma_rx_size * sizeof(struct dma_desc); -+ uio->mem[1].memtype = UIO_MEM_PHYS; -+ -+ uio->mem[2].name = "eth_tx_bd"; -+ uio->mem[2].addr = priv->tx_queue[0].dma_tx_phy; -+ uio->mem[2].size = priv->dma_tx_size * sizeof(struct dma_desc); -+ uio->mem[2].memtype = UIO_MEM_PHYS; -+ -+ uio->open = sunxi_uio_open; -+ uio->release = sunxi_uio_release; -+ /* Custom mmap function. */ -+ uio->mmap = sunxi_uio_mmap; -+ uio->priv = chip; -+ -+ err = uio_register_device(dev, uio); -+ if (err) { -+ dev_err(dev, "Failed to register uio device: %d\n", err); -+ return err; -+ } -+ -+ chip->map_num = 3; -+ -+ dev_info(dev, "Registered %s uio devices, %d register maps attached\n", -+ chip->name, chip->map_num); -+ -+ platform_set_drvdata(pdev, chip); -+ -+ return 0; -+} -+ -+/** -+ * sunxi_uio_remove() - UIO platform driver release -+ * routine - unregister uio devices -+ */ -+static int sunxi_uio_remove(struct platform_device *pdev) -+{ -+ struct sunxi_uio *chip = platform_get_drvdata(pdev); -+ struct net_device *netdev; -+ -+ if (!chip) -+ return -EINVAL; -+ -+ netdev = chip->ndev; -+ -+ uio_unregister_device(&chip->uio); -+ -+ if (netdev) { -+ rtnl_lock(); -+ sunxi_uio_exit(netdev); -+ rtnl_unlock(); -+ } -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ if (netdev) { -+ rtnl_lock(); -+ dev_open(netdev, NULL); -+ rtnl_unlock(); -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id sunxi_uio_of_match[] = { -+ { .compatible = "allwinner,sunxi-uio", }, -+ { } -+}; -+ -+static struct platform_driver sunxi_uio_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = DRIVER_NAME, -+ .of_match_table = sunxi_uio_of_match, -+ }, -+ .probe = sunxi_uio_probe, -+ .remove = sunxi_uio_remove, -+}; -+module_platform_driver(sunxi_uio_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("xuminghui "); -+MODULE_VERSION(DRIVER_VERSION); -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/Kconfig linux-6.12.10/drivers/net/ethernet/allwinner/Kconfig ---- linux-6.12.10/drivers/net/ethernet/allwinner/Kconfig 2025-01-17 13:41:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/Kconfig 2025-01-23 10:53:24.284097476 +0100 -@@ -34,4 +34,6 @@ - To compile this driver as a module, choose M here. The module - will be called sun4i-emac. - -+source "drivers/net/ethernet/allwinner/gmac-200/Kconfig" -+ - endif # NET_VENDOR_ALLWINNER -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/Makefile linux-6.12.10/drivers/net/ethernet/allwinner/Makefile ---- linux-6.12.10/drivers/net/ethernet/allwinner/Makefile 2025-01-17 13:41:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/Makefile 2025-01-23 10:53:31.710764338 +0100 -@@ -4,3 +4,4 @@ - # - - obj-$(CONFIG_SUN4I_EMAC) += sun4i-emac.o -+obj-$(CONFIG_NET_VENDOR_ALLWINNER) += gmac-200/ diff --git a/patch/kernel/archive/sunxi-dev-6.14/1140-net-ethernet-allwinner-add-gmac-support.patch b/patch/kernel/archive/sunxi-dev-6.14/1140-net-ethernet-allwinner-add-gmac-support.patch deleted file mode 100644 index 27e806e8e..000000000 --- a/patch/kernel/archive/sunxi-dev-6.14/1140-net-ethernet-allwinner-add-gmac-support.patch +++ /dev/null @@ -1,4470 +0,0 @@ - -Code is backport from BSP kernel - -Signed-off-by: Piotr Oniszczuk - -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac/Kconfig linux-6.12.10/drivers/net/ethernet/allwinner/gmac/Kconfig ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac/Kconfig 2025-01-23 10:14:54.944035323 +0100 -@@ -0,0 +1,37 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+menu "Gmac Drivers" -+ -+config SUNXI55I_GMAC -+ tristate "Allwinner A523 GMAC support" -+ depends on OF -+ select SUNXI55I_GMAC_MDIO -+ select CRC32 -+ help -+ Support for Allwinner A523 GMAC ethernet driver. -+ -+ To compile this driver as a module, choose M here. The module -+ will be called sunxi-gmac.ko. -+ -+config SUNXI55I_GMAC_MDIO -+ tristate "Allwinner A523 GMAC MDIO support" -+ select MDIO_BUS -+ select MDIO_DEVICE -+ select PHYLIB -+ select MII -+ help -+ This driver supports the A523 GMAC MDIO interface in the network -+ -+config SUNXI55I_GMAC_METADATA -+ bool "Allwinner A523 GMAC metadata support" -+ depends on SUNXI55I_GMAC -+ help -+ Support Allwinner A523 GMAC to transmit and receive metadata -+ -+# todo (not backported from bsp yet) -+#config SUNXI55I_EPHY -+# tristate "Drivers for A523 Allwinner EPHY" -+# depends on SUNXI55I_GMAC -+# help -+# Support Allwinner A523 EPHY -+ -+endmenu -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac/Makefile linux-6.12.10/drivers/net/ethernet/allwinner/gmac/Makefile ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac/Makefile 2025-01-23 10:14:29.307367960 +0100 -@@ -0,0 +1,7 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+ -+ccflags-y += -I $(srctree)/drivers/net/ethernet/allwinner/gmac -+ -+obj-$(CONFIG_SUNXI55I_GMAC) += sunxi-gmac.o -+obj-$(CONFIG_SUNXI55I_GMAC_MDIO) += sunxi-mdio.o -+obj-$(CONFIG_SUNXI55I_EPHY) += sunxi-ephy.o -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-ephy.c linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-ephy.c ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-ephy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-ephy.c 2024-12-11 14:45:52.380098296 +0100 -@@ -0,0 +1,315 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+* Allwinner ephy driver. -+* -+* Copyright(c) 2022-2027 Allwinnertech Co., Ltd. -+* -+* 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. -+*/ -+ -+/* #define DEBUG */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+//#include -+#include -+#include -+ -+#define AC300_EPHY "ac300-ephy" -+#define AC300_DEV "ac300" -+ -+#define EPHY_CALI_BASE 0 -+#define EPHY_CALI_BIT BIT(29) -+#define EPHY_BGS_MASK 0x0f000000 -+#define EPHY_BGS_OFFSET 24 -+/* -+ * Ephy diagram test -+ * This macro will cause all cpu stuck -+ * Use it carefully -+ */ -+/* #define EPHY_100M_ED_TEST */ -+ -+struct ephy_res { -+ struct phy_device *ac300; -+ spinlock_t lock; -+ atomic_t ephy_en; -+}; -+ -+static struct ephy_res ac300_ephy; -+ -+static int sunxi_ephy_read_sid(u32 *buf) -+{ -+ int ret; -+ -+ if (!buf) -+ return -EINVAL; -+ -+ //todo ret = sunxi_efuse_readn(EFUSE_FTCP_NAME, buf, 4); -+ //if (ret) -+ // return ret; -+ -+ return 0; -+} -+ -+void sunxi_ephy_config_new_init(struct phy_device *phydev) -+{ -+ phy_write(phydev, 0x1f, 0x0100); /* switch to Page 1 */ -+ phy_write(phydev, 0x12, 0x4824); /* Disable APS */ -+ -+ phy_write(phydev, 0x1f, 0x0200); /* switch to Page 2 */ -+ phy_write(phydev, 0x18, 0x0000); /* PHYAFE TRX optimization */ -+ -+ phy_write(phydev, 0x1f, 0x0600); /* switch to Page 6 */ -+ phy_write(phydev, 0x14, 0x7809); /* PHYAFE TX optimization */ -+ phy_write(phydev, 0x13, 0xf000); /* PHYAFE RX optimization */ -+ phy_write(phydev, 0x10, 0x5523); -+ phy_write(phydev, 0x15, 0x3533); -+ -+ phy_write(phydev, 0x1f, 0x0800); /* switch to Page 8 */ -+ phy_write(phydev, 0x1d, 0x0844); /* disable auto offset */ -+ phy_write(phydev, 0x18, 0x00bc); /* PHYAFE TRX optimization */ -+ -+ phy_write(phydev, 0x1f, 0x0000); /* switch to Page 0 */ -+} -+ -+void sunxi_ephy_config_old_init(struct phy_device *phydev) -+{ -+ phy_write(phydev, 0x1f, 0x0100); /* switch to Page 1 */ -+ phy_write(phydev, 0x12, 0x4824); /* Disable APS */ -+ -+ phy_write(phydev, 0x1f, 0x0200); /* switch to Page 2 */ -+ phy_write(phydev, 0x18, 0x0000); /* PHYAFE TRX optimization */ -+ -+ phy_write(phydev, 0x1f, 0x0600); /* switch to Page 6 */ -+ phy_write(phydev, 0x14, 0x780b); /* PHYAFE TX optimization */ -+ phy_write(phydev, 0x13, 0xf000); /* PHYAFE RX optimization */ -+ phy_write(phydev, 0x15, 0x1530); -+ phy_write(phydev, 0x1f, 0x0800); /* switch to Page 8 */ -+ phy_write(phydev, 0x18, 0x00bc); /* PHYAFE TRX optimization */ -+ -+ phy_write(phydev, 0x1f, 0x0000); /* switch to Page 0 */ -+} -+ -+void sunxi_ephy_config_cali(struct phy_device *phydev, u32 ephy_cali) -+{ -+ int value, bgs_adjust; -+ -+ /* Adjust BGS value of 0x06 reg */ -+ value = phy_read(phydev, 0x06); -+ value &= ~(0x0F << 12); -+ bgs_adjust = (ephy_cali & EPHY_BGS_MASK) >> EPHY_BGS_OFFSET; -+ value |= (0xF & (EPHY_CALI_BASE + bgs_adjust)) << 12; -+ phy_write(phydev, 0x06, value); -+} -+ -+void sunxi_ephy_disable_intelligent_ieee(struct phy_device *phydev) -+{ -+ unsigned int value; -+ -+ phy_write(phydev, 0x1f, 0x0100); /* switch to page 1 */ -+ value = phy_read(phydev, 0x17); /* read address 0 0x17 register */ -+ value &= ~(1 << 3); /* reg 0x17 bit 3, set 0 to disable IEEE */ -+ phy_write(phydev, 0x17, value); -+ phy_write(phydev, 0x1f, 0x0000); /* switch to page 0 */ -+} -+ -+void sunxi_ephy_disable_802_3az_ieee(struct phy_device *phydev) -+{ -+ unsigned int value; -+ -+ phy_write(phydev, 0xd, 0x7); -+ phy_write(phydev, 0xe, 0x3c); -+ phy_write(phydev, 0xd, 0x1 << 14 | 0x7); -+ value = phy_read(phydev, 0xe); -+ value &= ~(0x1 << 1); -+ phy_write(phydev, 0xd, 0x7); -+ phy_write(phydev, 0xe, 0x3c); -+ phy_write(phydev, 0xd, 0x1 << 14 | 0x7); -+ phy_write(phydev, 0xe, value); -+ -+ phy_write(phydev, 0x1f, 0x0200); /* switch to page 2 */ -+ phy_write(phydev, 0x18, 0x0000); -+} -+ -+#ifdef EPHY_100M_ED_TEST -+static void ephy_debug_test(void *info) -+{ -+ while (1) -+ ; -+} -+#endif -+ -+static int ephy_config_init(struct phy_device *phydev) -+{ -+ int value; -+ int ret; -+ u32 ephy_cali = 0; -+ -+ ret = sunxi_ephy_read_sid(&ephy_cali); -+ if (ret) { -+ pr_err("ephy cali efuse read fail, use default 0\n"); -+ } -+ -+ sunxi_ephy_config_cali(ac300_ephy.ac300, ephy_cali); -+ -+ /* -+ * EPHY_CALI_BIT: the flag of calibration value -+ * 0: Normal -+ * 1: Low level of calibration value -+ */ -+ if (ephy_cali & EPHY_CALI_BIT) { -+ pr_debug("Low level ephy, use new init\n"); -+ sunxi_ephy_config_new_init(phydev); -+ } else { -+ pr_debug("Normal ephy, use old init\n"); -+ sunxi_ephy_config_old_init(phydev); -+ } -+ -+ sunxi_ephy_disable_intelligent_ieee(phydev); /* Disable Intelligent IEEE */ -+ sunxi_ephy_disable_802_3az_ieee(phydev); /* Disable 802.3az IEEE */ -+ phy_write(phydev, 0x1f, 0x0000); /* Switch to Page 0 */ -+ -+#ifdef EPHY_100M_ED_TEST -+ phy_write(phydev, 0x1f, 0x0000); /* Switch to Page 0 */ -+ phy_write(phydev, 0x00, 0x2100); /* Force 100M Mode */ -+ phy_write(phydev, 0x1f, 0x0000); /* Switch to Page 0 */ -+ phy_write(phydev, 0x13, 0x0100); /* Force TX output@TXP/TXN */ -+ on_each_cpu(ephy_debug_test, NULL, 1); /* Stuck all cpu for ephy eye diagram test */ -+#endif -+ -+ value = phy_read(ac300_ephy.ac300, 0x06); -+ if (phydev->interface == PHY_INTERFACE_MODE_RMII) -+ value |= (1 << 11); -+ else -+ value &= (~(1 << 11)); -+ -+ phy_write(ac300_ephy.ac300, 0x06, value); -+ -+ return 0; -+} -+ -+static int ephy_probe(struct phy_device *phydev) -+{ -+ return 0; -+} -+ -+static int ephy_suspend(struct phy_device *phydev) -+{ -+ return genphy_suspend(phydev); -+} -+ -+static int ephy_resume(struct phy_device *phydev) -+{ -+ return genphy_resume(phydev); -+} -+ -+static void ac300_enable(struct phy_device *phydev) -+{ -+ /* release reset */ -+ phy_write(phydev, 0x00, 0x1f40); /* reset ephy */ -+ phy_write(phydev, 0x00, 0x1f43); /* de-reset ephy */ -+ -+ /* clk gating */ -+ phy_write(phydev, 0x00, 0x1fb7); -+ -+ /* io enable */ -+ phy_write(phydev, 0x05, 0xa81f); -+ -+ mdelay(10); -+ phy_write(phydev, 0x06, 0x0811); -+ -+ mdelay(10); -+ phy_write(phydev, 0x06, 0x0810); -+} -+ -+static void ac300_disable(struct phy_device *phydev) -+{ -+ phy_write(phydev, 0x00, 0x1f40); -+ phy_write(phydev, 0x05, 0xa800); -+ -+ phy_write(phydev, 0x06, 0x01); -+} -+ -+static int ac300_suspend(struct phy_device *phydev) -+{ -+ ac300_disable(phydev); -+ return 0; -+} -+ -+static int ac300_resume(struct phy_device *phydev) -+{ -+ return 0; -+} -+ -+static int ac300_probe(struct phy_device *phydev) -+{ -+ ac300_enable(phydev); -+ -+ return 0; -+} -+ -+static int ac300_init(struct phy_device *phydev) -+{ -+ /* save ac300 message */ -+ ac300_ephy.ac300 = phydev; -+ -+ /* ac300 enable */ -+ ac300_enable(phydev); -+ -+ /* FIXME: delay may be required after AC300 reset*/ -+ msleep(50); -+ -+ return 0; -+} -+ -+static struct phy_driver ac300_driver[] = { -+{ -+ .phy_id = 0xc0000000, -+ .name = AC300_DEV, -+ .phy_id_mask = 0xffffffff, -+ .config_init = ac300_init, -+ .suspend = ac300_suspend, -+ .resume = ac300_resume, -+ .probe = ac300_probe, -+}, -+{ .phy_id = 0x00441400, -+ .name = AC300_EPHY, -+ .phy_id_mask = 0x0ffffff0, -+ .config_init = ephy_config_init, -+ .config_aneg = &genphy_config_aneg, -+ .read_status = &genphy_read_status, -+ .suspend = ephy_suspend, -+ .resume = ephy_resume, -+ .probe = ephy_probe, -+ -+} }; -+ -+module_phy_driver(ac300_driver); -+ -+static struct mdio_device_id __maybe_unused ac300_tbl[] = { -+ { 0xc0000000, 0x0fffffff }, -+ { 0x00441400, 0x0ffffff0 }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(mdio, ac300_tbl); -+MODULE_DESCRIPTION("Allwinner phy drivers"); -+MODULE_AUTHOR("xuminghui "); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION("1.1.1"); -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-gmac.c linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-gmac.c ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-gmac.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-gmac.c 2025-01-23 10:25:09.037385167 +0100 -@@ -0,0 +1,3634 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* Copyright(c) 2020 - 2023 Allwinner Technology Co.,Ltd. All rights reserved. */ -+/* -+* Allwinner GMAC driver. -+* -+* Copyright(c) 2022-2027 Allwinnertech Co., Ltd. -+* -+* 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. -+*/ -+ -+/* #define DEBUG */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+//todo #include -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+#include -+#endif /* CONFIG_SUNXI55I_EPHY */ -+#if IS_ENABLED(CONFIG_SUNXI55I_GMAC_METADATA) -+#include -+#endif /* CONFIG_SUNXI55I_GMAC_METADATA */ -+#include -+ -+/* All sunxi-gmac tracepoints are defined by the include below, which -+ * must be included exactly once across the whole kernel with -+ * CREATE_TRACE_POINTS defined -+ */ -+//#define CREATE_TRACE_POINTS -+//#include "sunxi-gmac-trace.h" -+ -+#define SUNXI_GMAC_MODULE_VERSION "2.4.3" -+ -+#define SUNXI_GMAC_DMA_DESC_RX 256 -+#define SUNXI_GMAC_DMA_DESC_TX 256 -+#define SUNXI_GMAC_BUDGET (sunxi_gmac_dma_desc_rx / 4) -+#define SUNXI_GMAC_TX_THRESH (sunxi_gmac_dma_desc_tx / 4) -+ -+#define SUNXI_GMAC_HASH_TABLE_SIZE 64 -+#define SUNXI_GMAC_MAX_BUF_SZ (SZ_2K - 1) -+/* Under the premise that each descriptor currently transmits 2k data, jumbo frame max is 8100 */ -+#define SUNXI_GMAC_MAX_MTU_SZ 8100 -+ -+/* SUNXI_GMAC_FRAME_FILTER register value */ -+#define SUNXI_GMAC_FRAME_FILTER_PR 0x80000000 /* Promiscuous Mode */ -+#define SUNXI_GMAC_FRAME_FILTER_HUC 0x00000100 /* Hash Unicast */ -+#define SUNXI_GMAC_FRAME_FILTER_HMC 0x00000200 /* Hash Multicast */ -+#define SUNXI_GMAC_FRAME_FILTER_DAIF 0x00000010 /* DA Inverse Filtering */ -+#define SUNXI_GMAC_FRAME_FILTER_PM 0x00010000 /* Pass all multicast */ -+#define SUNXI_GMAC_FRAME_FILTER_DBF 0x00020000 /* Disable Broadcast frames */ -+#define SUNXI_GMAC_FRAME_FILTER_SAIF 0x00000020 /* Inverse Filtering */ -+#define SUNXI_GMAC_FRAME_FILTER_SAF 0x00000040 /* Source Address Filter */ -+#define SUNXI_GMAC_FRAME_FILTER_RA 0x00000001 /* Receive all mode */ -+ -+/* Default tx descriptor */ -+#define SUNXI_GMAC_TX_SINGLE_DESC0 0x80000000 -+#define SUNXI_GMAC_TX_SINGLE_DESC1 0x63000000 -+ -+/* Default rx descriptor */ -+#define SUNXI_GMAC_RX_SINGLE_DESC0 0x80000000 -+#define SUNXI_GMAC_RX_SINGLE_DESC1 0x83000000 -+ -+/****************************************************************************** -+ * sunxi gmac reg offset -+ *****************************************************************************/ -+#define SUNXI_GMAC_BASIC_CTL0 0x00 -+#define SUNXI_GMAC_BASIC_CTL1 0x04 -+#define SUNXI_GMAC_INT_STA 0x08 -+#define SUNXI_GMAC_INT_EN 0x0C -+#define SUNXI_GMAC_TX_CTL0 0x10 -+#define SUNXI_GMAC_TX_CTL1 0x14 -+#define SUNXI_GMAC_TX_FLOW_CTL 0x1C -+#define SUNXI_GMAC_TX_DESC_LIST 0x20 -+#define SUNXI_GMAC_RX_CTL0 0x24 -+#define SUNXI_GMAC_RX_CTL1 0x28 -+#define SUNXI_GMAC_RX_DESC_LIST 0x34 -+#define SUNXI_GMAC_RX_FRM_FLT 0x38 -+#define SUNXI_GMAC_RX_HASH0 0x40 -+#define SUNXI_GMAC_RX_HASH1 0x44 -+#define SUNXI_GMAC_MDIO_ADDR 0x48 -+#define SUNXI_GMAC_MDIO_DATA 0x4C -+#define SUNXI_GMAC_ADDR_HI(reg) (0x50 + ((reg) << 3)) -+#define SUNXI_GMAC_ADDR_LO(reg) (0x54 + ((reg) << 3)) -+#define SUNXI_GMAC_TX_DMA_STA 0xB0 -+#define SUNXI_GMAC_TX_CUR_DESC 0xB4 -+#define SUNXI_GMAC_TX_CUR_BUF 0xB8 -+#define SUNXI_GMAC_RX_DMA_STA 0xC0 -+#define SUNXI_GMAC_RX_CUR_DESC 0xC4 -+#define SUNXI_GMAC_RX_CUR_BUF 0xC8 -+#define SUNXI_GMAC_RGMII_STA 0xD0 -+ -+#define SUNXI_GMAC_RGMII_IRQ 0x00000001 -+ -+#define SUNXI_GMAC_CTL0_LM 0x02 -+#define SUNXI_GMAC_CTL0_DM 0x01 -+#define SUNXI_GMAC_CTL0_SPEED 0x04 -+ -+#define SUNXI_GMAC_BURST_LEN 0x3F000000 -+#define SUNXI_GMAC_RX_TX_PRI 0x02 -+#define SUNXI_GMAC_SOFT_RST 0x01 -+ -+#define SUNXI_GMAC_TX_FLUSH 0x01 -+#define SUNXI_GMAC_TX_MD 0x02 -+#define SUNXI_GMAC_TX_NEXT_FRM 0x04 -+#define SUNXI_GMAC_TX_TH 0x0700 -+#define SUNXI_GMAC_TX_FLOW_CTL_BIT 0x01 -+ -+#define SUNXI_GMAC_RX_FLUSH 0x01 -+#define SUNXI_GMAC_RX_MD 0x02 -+#define SUNXI_GMAC_RX_RUNT_FRM 0x04 -+#define SUNXI_GMAC_RX_ERR_FRM 0x08 -+#define SUNXI_GMAC_RX_TH 0x0030 -+#define SUNXI_GMAC_RX_FLOW_CTL 0x1000000 -+ -+#define SUNXI_GMAC_TX_INT 0x00001 -+#define SUNXI_GMAC_TX_STOP_INT 0x00002 -+#define SUNXI_GMAC_TX_UA_INT 0x00004 -+#define SUNXI_GMAC_TX_TOUT_INT 0x00008 -+#define SUNXI_GMAC_TX_UNF_INT 0x00010 -+#define SUNXI_GMAC_TX_EARLY_INT 0x00020 -+#define SUNXI_GMAC_RX_INT 0x00100 -+#define SUNXI_GMAC_RX_UA_INT 0x00200 -+#define SUNXI_GMAC_RX_STOP_INT 0x00400 -+#define SUNXI_GMAC_RX_TOUT_INT 0x00800 -+#define SUNXI_GMAC_RX_OVF_INT 0x01000 -+#define SUNXI_GMAC_RX_EARLY_INT 0x02000 -+#define SUNXI_GMAC_LINK_STA_INT 0x10000 -+ -+#define SUNXI_GMAC_CHAIN_MODE_OFFSET 24 -+#define SUNXI_GMAC_LOOPBACK_OFFSET 2 -+#define SUNXI_GMAC_LOOPBACK 0x00000002 -+#define SUNXI_GMAC_CLEAR_SPEED 0x03 -+#define SUNXI_GMAC_1000M_SPEED ~0x0c -+#define SUNXI_GMAC_100M_SPEED 0x0c -+#define SUNXI_GMAC_10M_SPEED 0x08 -+#define SUNXI_GMAC_RX_FLOW_EN 0x10000 -+#define SUNXI_GMAC_TX_FLOW_EN 0x00001 -+#define SUNXI_GMAC_PAUSE_OFFSET 4 -+#define SUNXI_GMAC_INT_OFFSET 0x3fff -+#define SUNXI_GMAC_RX_DMA_EN 0x40000000 -+#define SUNXI_GMAC_TX_DMA_EN 0x40000000 -+#define SUNXI_GMAC_BURST_VALUE 8 -+#define SUNXI_GMAC_BURST_OFFSET 24 -+#define SUNXI_GMAC_SF_DMA_MODE 1 -+#define SUNXI_GMAC_TX_FRM_LEN_OFFSET 30 -+#define SUNXI_GMAC_CRC_OFFSET 27 -+#define SUNXI_GMAC_STRIP_FCS_OFFSET 28 -+#define SUNXI_GMAC_JUMBO_EN_OFFSET 29 -+#define SUNXI_GMAC_MDC_DIV_RATIO_M 0x03 -+#define SUNXI_GMAC_MDC_DIV_OFFSET 20 -+#define SUNXI_GMAC_TX_DMA_TH64 64 -+#define SUNXI_GMAC_TX_DMA_TH128 128 -+#define SUNXI_GMAC_TX_DMA_TH192 192 -+#define SUNXI_GMAC_TX_DMA_TH256 256 -+#define SUNXI_GMAC_TX_DMA_TH64_VAL 0x00000000 -+#define SUNXI_GMAC_TX_DMA_TH128_VAL 0X00000100 -+#define SUNXI_GMAC_TX_DMA_TH192_VAL 0x00000200 -+#define SUNXI_GMAC_TX_DMA_TH256_VAL 0x00000300 -+#define SUNXI_GMAC_RX_DMA_TH32 32 -+#define SUNXI_GMAC_RX_DMA_TH64 64 -+#define SUNXI_GMAC_RX_DMA_TH96 96 -+#define SUNXI_GMAC_RX_DMA_TH128 128 -+#define SUNXI_GMAC_RX_DMA_TH32_VAL 0x10 -+#define SUNXI_GMAC_RX_DMA_TH64_VAL 0x00 -+#define SUNXI_GMAC_RX_DMA_TH96_VAL 0x20 -+#define SUNXI_GMAC_RX_DMA_TH128_VAL 0x30 -+#define SUNXI_GMAC_TX_DMA_START 31 -+#define SUNXI_GMAC_RX_DMA_START 31 -+#define SUNXI_GMAC_DMA_DESC_BUFSIZE 11 -+#define SUNXI_GMAC_LOOPBACK_OFF 0 -+#define SUNXI_GMAC_MAC_LOOPBACK_ON 1 -+#define SUNXI_GMAC_PHY_LOOPBACK_ON 2 -+#define SUNXI_GMAC_OWN_DMA 0x80000000 -+#define SUNXI_GMAC_GPHY_TEST_OFFSET 13 -+#define SUNXI_GMAC_GPHY_TEST_MASK 0x07 -+#define SUNXI_GMAC_PHY_RGMII_MASK 0x00000004 -+#define SUNXI_GMAC_ETCS_RMII_MASK 0x00002003 -+#define SUNXI_GMAC_RGMII_INTCLK_MASK 0x00000002 -+#define SUNXI_GMAC_RMII_MASK 0x00002000 -+#define SUNXI_GMAC_TX_DELAY_MASK 0x07 -+#define SUNXI_GMAC_TX_DELAY_OFFSET 10 -+#define SUNXI_GMAC_RX_DELAY_MASK 0x1F -+#define SUNXI_GMAC_RX_DELAY_OFFSET 5 -+/* Flow Control defines */ -+#define SUNXI_GMAC_FLOW_OFF 0 -+#define SUNXI_GMAC_FLOW_RX 1 -+#define SUNXI_GMAC_FLOW_TX 2 -+#define SUNXI_GMAC_FLOW_AUTO (SUNXI_GMAC_FLOW_TX | SUNXI_GMAC_FLOW_RX) -+ -+/* Ring buffer caculate method */ -+#define circ_cnt(head, tail, size) (((head) > (tail)) ? \ -+ ((head) - (tail)) : \ -+ ((head) - (tail)) & ((size) - 1)) -+ -+#define circ_space(head, tail, size) circ_cnt((tail), ((head) + 1), (size)) -+ -+#define circ_inc(n, s) (((n) + 1) % (s)) -+ -+#define MAC_ADDR_LEN 18 -+#define SUNXI_GMAC_MAC_ADDRESS "80:3f:5d:09:8b:26" -+ -+/* loopback test */ -+#define LOOPBACK_PKT_CNT 64 -+#define LOOPBACK_PKT_LEN 1514 -+#define LOOPBACK_DEFAULT_TIME 5 -+enum self_test_index { -+ INTERNAL_LOOPBACK_TEST = 0, -+ EXTERNAL_LOOPBACK_TEST = 1, -+ SELF_TEST_MAX = 2, -+}; -+ -+static char sunxi_gmac_test_strings[][ETH_GSTRING_LEN] = { -+ "Internal lb test (mac loopback)", -+ "External lb test (phy loopback)", -+}; -+ -+//todo #ifdef MODULE -+//extern int get_custom_mac_address(int fmt, char *name, char *addr); -+//#endif -+ -+static char mac_str[MAC_ADDR_LEN] = SUNXI_GMAC_MAC_ADDRESS; -+module_param_string(mac_str, mac_str, MAC_ADDR_LEN, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(mac_str, "MAC Address String.(xx:xx:xx:xx:xx:xx)"); -+ -+static int rxmode = 1; -+module_param(rxmode, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(rxmode, "DMA threshold control value"); -+ -+static int txmode = 1; -+module_param(txmode, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(txmode, "DMA threshold control value"); -+ -+static int pause = 0x400; -+module_param(pause, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(pause, "Flow Control Pause Time"); -+ -+#define TX_TIMEO 5000 -+static int watchdog = TX_TIMEO; -+module_param(watchdog, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds"); -+ -+static int sunxi_gmac_dma_desc_rx = SUNXI_GMAC_DMA_DESC_RX; -+module_param(sunxi_gmac_dma_desc_rx, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(sunxi_gmac_dma_desc_rx, "The number of receive's descriptors"); -+ -+static int sunxi_gmac_dma_desc_tx = SUNXI_GMAC_DMA_DESC_TX; -+module_param(sunxi_gmac_dma_desc_tx, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(sunxi_gmac_dma_desc_tx, "The number of transmit's descriptors"); -+ -+static int user_tx_delay = -1; -+module_param(user_tx_delay, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(user_tx_delay, "RGMII tx-delay parameter"); -+ -+static int user_rx_delay = -1; -+module_param(user_rx_delay, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(user_rx_delay, "RGMII rx-delay parameter"); -+ -+/* - 0: Flow Off -+ * - 1: Rx Flow -+ * - 2: Tx Flow -+ * - 3: Rx & Tx Flow -+ */ -+static int flow_ctrl; -+module_param(flow_ctrl, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(flow_ctrl, "Flow control [0: off, 1: rx, 2: tx, 3: both]"); -+ -+typedef union { -+ struct { -+ /* TDES0 */ -+ unsigned int deferred:1; /* Deferred bit (only half-duplex) */ -+ unsigned int under_err:1; /* Underflow error */ -+ unsigned int ex_deferral:1; /* Excessive deferral */ -+ unsigned int coll_cnt:4; /* Collision count */ -+ unsigned int vlan_tag:1; /* VLAN Frame */ -+ unsigned int ex_coll:1; /* Excessive collision */ -+ unsigned int late_coll:1; /* Late collision */ -+ unsigned int no_carr:1; /* No carrier */ -+ unsigned int loss_carr:1; /* Loss of collision */ -+ unsigned int ipdat_err:1; /* IP payload error */ -+ unsigned int frm_flu:1; /* Frame flushed */ -+ unsigned int jab_timeout:1; /* Jabber timeout */ -+ unsigned int err_sum:1; /* Error summary */ -+ unsigned int iphead_err:1; /* IP header error */ -+ unsigned int ttss:1; /* Transmit time stamp status */ -+ unsigned int reserved0:13; -+ unsigned int own:1; /* Own bit. CPU:0, DMA:1 */ -+ } tx; -+ -+ /* bits 5 7 0 | Frame status -+ * ---------------------------------------------------------- -+ * 0 0 0 | IEEE 802.3 Type frame (length < 1536 octects) -+ * 1 0 0 | IPv4/6 No CSUM errorS. -+ * 1 0 1 | IPv4/6 CSUM PAYLOAD error -+ * 1 1 0 | IPv4/6 CSUM IP HR error -+ * 1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS -+ * 0 0 1 | IPv4/6 unsupported IP PAYLOAD -+ * 0 1 1 | COE bypassed.. no IPv4/6 frame -+ * 0 1 0 | Reserved. -+ */ -+ struct { -+ /* RDES0 */ -+ unsigned int chsum_err:1; /* Payload checksum error */ -+ unsigned int crc_err:1; /* CRC error */ -+ unsigned int dribbling:1; /* Dribble bit error */ -+ unsigned int mii_err:1; /* Received error (bit3) */ -+ unsigned int recv_wt:1; /* Received watchdog timeout */ -+ unsigned int frm_type:1; /* Frame type */ -+ unsigned int late_coll:1; /* Late Collision */ -+ unsigned int ipch_err:1; /* IPv header checksum error (bit7) */ -+ unsigned int last_desc:1; /* Laset descriptor */ -+ unsigned int first_desc:1; /* First descriptor */ -+ unsigned int vlan_tag:1; /* VLAN Tag */ -+ unsigned int over_err:1; /* Overflow error (bit11) */ -+ unsigned int len_err:1; /* Length error */ -+ unsigned int sou_filter:1; /* Source address filter fail */ -+ unsigned int desc_err:1; /* Descriptor error */ -+ unsigned int err_sum:1; /* Error summary (bit15) */ -+ unsigned int frm_len:14; /* Frame length */ -+ unsigned int des_filter:1; /* Destination address filter fail */ -+ unsigned int own:1; /* Own bit. CPU:0, DMA:1 */ -+ #define RX_PKT_OK 0x7FFFB77C -+ #define RX_LEN 0x3FFF0000 -+ } rx; -+ -+ unsigned int all; -+} sunxi_gmac_desc0_u; -+ -+typedef union { -+ struct { -+ /* TDES1 */ -+ unsigned int buf1_size:11; /* Transmit buffer1 size */ -+ unsigned int buf2_size:11; /* Transmit buffer2 size */ -+ unsigned int ttse:1; /* Transmit time stamp enable */ -+ unsigned int dis_pad:1; /* Disable pad (bit23) */ -+ unsigned int adr_chain:1; /* Second address chained */ -+ unsigned int end_ring:1; /* Transmit end of ring */ -+ unsigned int crc_dis:1; /* Disable CRC */ -+ unsigned int cic:2; /* Checksum insertion control (bit27:28) */ -+ unsigned int first_sg:1; /* First Segment */ -+ unsigned int last_seg:1; /* Last Segment */ -+ unsigned int interrupt:1; /* Interrupt on completion */ -+ } tx; -+ -+ struct { -+ /* RDES1 */ -+ unsigned int buf1_size:11; /* Received buffer1 size */ -+ unsigned int buf2_size:11; /* Received buffer2 size */ -+ unsigned int reserved1:2; -+ unsigned int adr_chain:1; /* Second address chained */ -+ unsigned int end_ring:1; /* Received end of ring */ -+ unsigned int reserved2:5; -+ unsigned int dis_ic:1; /* Disable interrupt on completion */ -+ } rx; -+ -+ unsigned int all; -+} sunxi_gmac_desc1_u; -+ -+typedef struct sunxi_gmac_dma_desc { -+ sunxi_gmac_desc0_u desc0; -+ sunxi_gmac_desc1_u desc1; -+ /* The address of buffers */ -+ unsigned int desc2; -+ /* Next desc's address */ -+ unsigned int desc3; -+} __attribute__((packed)) sunxi_gmac_dma_desc_t; -+ -+enum rx_frame_status { /* IPC status */ -+ good_frame = 0, -+ discard_frame = 1, -+ csum_none = 2, -+ incomplete_frame = 3, /* use for jumbo frame */ -+ llc_snap = 4, -+}; -+ -+enum tx_dma_irq_status { -+ tx_hard_error = 1, -+ tx_hard_error_bump_tc = 2, -+ handle_tx_rx = 3, -+}; -+ -+struct sunxi_gmac_extra_stats { -+ /* Transmit errors */ -+ unsigned long tx_underflow; -+ unsigned long tx_carrier; -+ unsigned long tx_losscarrier; -+ unsigned long vlan_tag; -+ unsigned long tx_deferred; -+ unsigned long tx_vlan; -+ unsigned long tx_jabber; -+ unsigned long tx_frame_flushed; -+ unsigned long tx_payload_error; -+ unsigned long tx_ip_header_error; -+ -+ /* Receive errors */ -+ unsigned long rx_desc; -+ unsigned long sa_filter_fail; -+ unsigned long overflow_error; -+ unsigned long ipc_csum_error; -+ unsigned long rx_collision; -+ unsigned long rx_crc; -+ unsigned long dribbling_bit; -+ unsigned long rx_length; -+ unsigned long rx_mii; -+ unsigned long rx_multicast; -+ unsigned long rx_gmac_overflow; -+ unsigned long rx_watchdog; -+ unsigned long da_rx_filter_fail; -+ unsigned long sa_rx_filter_fail; -+ unsigned long rx_missed_cntr; -+ unsigned long rx_overflow_cntr; -+ unsigned long rx_vlan; -+ -+ /* Tx/Rx IRQ errors */ -+ unsigned long tx_undeflow_irq; -+ unsigned long tx_process_stopped_irq; -+ unsigned long tx_jabber_irq; -+ unsigned long rx_overflow_irq; -+ unsigned long rx_buf_unav_irq; -+ unsigned long rx_process_stopped_irq; -+ unsigned long rx_watchdog_irq; -+ unsigned long tx_early_irq; -+ unsigned long fatal_bus_error_irq; -+ -+ /* Extra info */ -+ unsigned long threshold; -+ unsigned long tx_pkt_n; -+ unsigned long rx_pkt_n; -+ unsigned long poll_n; -+ unsigned long sched_timer_n; -+ unsigned long normal_irq_n; -+}; -+ -+struct sunxi_gmac; -+ -+struct sunxi_gmac_ephy_ops { -+ int (*resource_get)(struct platform_device *pdev); -+ void (*resource_put)(struct platform_device *pdev); -+ int (*hardware_init)(struct sunxi_gmac *chip); -+ void (*hardware_deinit)(struct sunxi_gmac *chip); -+}; -+ -+struct sunxi_gmac { -+ struct sunxi_gmac_dma_desc *dma_tx; /* Tx dma descriptor */ -+ struct sk_buff **tx_skb; /* Tx socket buffer array */ -+ unsigned int tx_clean; /* Tx ring buffer data consumer */ -+ unsigned int tx_dirty; /* Tx ring buffer data provider */ -+ dma_addr_t dma_tx_phy; /* Tx dma physical address */ -+ -+ unsigned long buf_sz; /* Size of buffer specified by current descriptor */ -+ -+ struct sunxi_gmac_dma_desc *dma_rx; /* Rx dma descriptor */ -+ struct sk_buff **rx_skb; /* Rx socket buffer array */ -+ unsigned int rx_clean; /* Rx ring buffer data consumer */ -+ unsigned int rx_dirty; /* Rx ring buffer data provider */ -+ dma_addr_t dma_rx_phy; /* Rx dma physical address */ -+ -+ struct net_device *ndev; -+ struct device *dev; -+ struct napi_struct napi; -+ -+ struct sunxi_gmac_extra_stats xstats; /* Additional network statistics */ -+ -+ bool link; /* Phy link status */ -+ int speed; /* NIC network speed */ -+ int duplex; /* NIC network duplex capability */ -+ -+ /* suspend error workaround */ -+ unsigned int gmac_uevent_suppress; /* control kobject_uevent_env */ -+ -+#define SUNXI_EXTERNAL_PHY 1 -+#define SUNXI_INTERNAL_PHY 0 -+ u32 phy_type; /* 1: External phy, 0: Internal phy */ -+ -+#define SUNXI_PHY_USE_CLK25M 0 /* External phy use phy25m clk provided by Soc */ -+#define SUNXI_PHY_USE_EXT_OSC 1 /* External phy use extern osc 25m */ -+ u32 phy_clk_type; -+ -+ phy_interface_t phy_interface; -+ void __iomem *base; -+ void __iomem *syscfg_base; -+ struct clk *gmac_clk; -+ struct clk *phy25m_clk; -+ struct reset_control *reset; -+ struct pinctrl *pinctrl; -+ struct regulator *gmac_supply; -+ -+ /* definition spinlock */ -+ spinlock_t universal_lock; /* universal spinlock */ -+ spinlock_t tx_lock; /* tx tramsmit spinlock */ -+ -+ /* adjust transmit clock delay, value: 0~7 */ -+ /* adjust receive clock delay, value: 0~31 */ -+ u32 tx_delay; -+ u32 rx_delay; -+ -+ struct device_node *phy_node; -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+ struct device_node *ac300_np; -+ struct phy_device *ac300_dev; -+ struct pwm_device *ac300_pwm; -+ u32 pwm_channel; -+#define PWM_DUTY_NS 205 -+#define PWM_PERIOD_NS 410 -+ struct sunxi_gmac_ephy_ops *ephy_ops; -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ -+ /* loopback test */ -+ int loopback_pkt_len; -+ int loopback_test_rx_idx; -+ bool is_loopback_test; -+ u8 *loopback_test_rx_buf; -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_GMAC_METADATA) -+ u8 *metadata_buff; -+ struct miscdevice mdev; -+ struct completion metadata_done; -+ u32 metadata_len; -+#endif -+ -+ struct sk_buff *skb; /* for jumbo frame */ -+ -+ u32 irq_affinity; -+}; -+ -+/** -+ * sunxi_gmac_desc_init_chain - GMAC dma descriptor chain table initialization -+ * -+ * @desc: Dma descriptor -+ * @addr: Dma descriptor physical address -+ * @size: Dma descriptor numsa -+ * -+ * Called when the NIC is up. We init Tx/Rx dma descriptor table. -+ */ -+static void sunxi_gmac_desc_init_chain(struct sunxi_gmac_dma_desc *desc, unsigned long addr, unsigned int size) -+{ -+ /* In chained mode the desc3 points to the next element in the ring. -+ * The latest element has to point to the head. -+ */ -+ int i; -+ struct sunxi_gmac_dma_desc *p = desc; -+ unsigned long dma_phy = addr; -+ -+ for (i = 0; i < (size - 1); i++) { -+ dma_phy += sizeof(*p); -+ p->desc3 = (unsigned int)dma_phy; -+ /* Chain mode */ -+ p->desc1.all |= (1 << SUNXI_GMAC_CHAIN_MODE_OFFSET); -+ p++; -+ } -+ p->desc1.all |= (1 << SUNXI_GMAC_CHAIN_MODE_OFFSET); -+ p->desc3 = (unsigned int)addr; -+} -+ -+/** -+ * sunxi_gmac_set_link_mode - GMAC speed/duplex set func -+ * -+ * @iobase: Gmac membase -+ * @duplex: Duplex capability:half/full -+ * @speed: Speed:10M/100M/1000M -+ * -+ * Updates phy status and takes action for network queue if required -+ * based upon link status. -+ */ -+static void sunxi_gmac_set_link_mode(void *iobase, int duplex, int speed) -+{ -+ unsigned int ctrl = readl(iobase + SUNXI_GMAC_BASIC_CTL0); -+ -+ if (!duplex) -+ ctrl &= ~SUNXI_GMAC_CTL0_DM; -+ else -+ ctrl |= SUNXI_GMAC_CTL0_DM; -+ -+ /* clear ctrl speed */ -+ ctrl &= SUNXI_GMAC_CLEAR_SPEED; -+ -+ switch (speed) { -+ case 1000: -+ ctrl &= SUNXI_GMAC_1000M_SPEED; -+ break; -+ case 100: -+ ctrl |= SUNXI_GMAC_100M_SPEED; -+ break; -+ case 10: -+ ctrl |= SUNXI_GMAC_10M_SPEED; -+ break; -+ default: -+ break; -+ } -+ -+ writel(ctrl, iobase + SUNXI_GMAC_BASIC_CTL0); -+} -+ -+/** -+ * sunxi_gmac_loop - GMAC loopback mode set func -+ * -+ * @iobase: Gmac membase -+ * @loopback_enable: Loopback status -+ */ -+static void sunxi_gmac_loopback(void *iobase, int loopback_enable) -+{ -+ int reg; -+ -+ reg = readl(iobase + SUNXI_GMAC_BASIC_CTL0); -+ if (loopback_enable) -+ reg |= SUNXI_GMAC_LOOPBACK_OFFSET; -+ else -+ reg &= ~SUNXI_GMAC_LOOPBACK_OFFSET; -+ writel(reg, iobase + SUNXI_GMAC_BASIC_CTL0); -+} -+ -+static void sunxi_gmac_crc(void *iobase, bool enable) -+{ -+ int reg; -+ -+ reg = readl(iobase + SUNXI_GMAC_RX_CTL0); -+ if (enable) -+ reg |= (1 << SUNXI_GMAC_CRC_OFFSET); -+ else -+ reg &= ~(1 << SUNXI_GMAC_CRC_OFFSET); -+ -+ writel(reg, iobase + SUNXI_GMAC_RX_CTL0); -+} -+ -+/** -+ * sunxi_gmac_flow_ctrl - GMAC flow ctrl set func -+ * -+ * @iobase: Gmac membase -+ * @duolex: Duplex capability -+ * @fc: Flow control option -+ * @pause: Flow control pause time -+ */ -+static void sunxi_gmac_flow_ctrl(void *iobase, int duplex, int fc, int pause) -+{ -+ unsigned int flow; -+ -+ if (fc & SUNXI_GMAC_FLOW_RX) { -+ flow = readl(iobase + SUNXI_GMAC_RX_CTL0); -+ flow |= SUNXI_GMAC_RX_FLOW_EN; -+ writel(flow, iobase + SUNXI_GMAC_RX_CTL0); -+ } -+ -+ if (fc & SUNXI_GMAC_FLOW_TX) { -+ flow = readl(iobase + SUNXI_GMAC_TX_FLOW_CTL); -+ flow |= SUNXI_GMAC_TX_FLOW_EN; -+ writel(flow, iobase + SUNXI_GMAC_TX_FLOW_CTL); -+ } -+ -+ if (duplex) { -+ flow = readl(iobase + SUNXI_GMAC_TX_FLOW_CTL); -+ flow |= (pause << SUNXI_GMAC_PAUSE_OFFSET); -+ writel(flow, iobase + SUNXI_GMAC_TX_FLOW_CTL); -+ } -+} -+ -+/** -+ * sunxi_gmac_int_status - GMAC get int status func -+ * -+ * @iobase: Gmac membase -+ * @x: Extra statistics -+ */ -+static int sunxi_gmac_int_status(void *iobase, struct sunxi_gmac_extra_stats *x) -+{ -+ int ret; -+ /* read the status register (CSR5) */ -+ unsigned int intr_status; -+ -+ intr_status = readl(iobase + SUNXI_GMAC_RGMII_STA); -+ if (intr_status & SUNXI_GMAC_RGMII_IRQ) -+ readl(iobase + SUNXI_GMAC_RGMII_STA); -+ -+ intr_status = readl(iobase + SUNXI_GMAC_INT_STA); -+ -+ /* ABNORMAL interrupts */ -+ if (intr_status & SUNXI_GMAC_TX_UNF_INT) { -+ ret = tx_hard_error_bump_tc; -+ x->tx_undeflow_irq++; -+ } -+ if (intr_status & SUNXI_GMAC_TX_TOUT_INT) -+ x->tx_jabber_irq++; -+ -+ if (intr_status & SUNXI_GMAC_RX_OVF_INT) -+ x->rx_overflow_irq++; -+ -+ if (intr_status & SUNXI_GMAC_RX_UA_INT) -+ x->rx_buf_unav_irq++; -+ -+ if (intr_status & SUNXI_GMAC_RX_STOP_INT) -+ x->rx_process_stopped_irq++; -+ -+ if (intr_status & SUNXI_GMAC_RX_TOUT_INT) -+ x->rx_watchdog_irq++; -+ -+ if (intr_status & SUNXI_GMAC_TX_EARLY_INT) -+ x->tx_early_irq++; -+ -+ if (intr_status & SUNXI_GMAC_TX_STOP_INT) { -+ x->tx_process_stopped_irq++; -+ ret = tx_hard_error; -+ } -+ -+ /* TX/RX NORMAL interrupts */ -+ if (intr_status & (SUNXI_GMAC_TX_INT | SUNXI_GMAC_RX_INT | SUNXI_GMAC_RX_EARLY_INT | SUNXI_GMAC_TX_UA_INT)) { -+ x->normal_irq_n++; -+ if (intr_status & (SUNXI_GMAC_TX_INT | SUNXI_GMAC_RX_INT)) -+ ret = handle_tx_rx; -+ } -+ /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */ -+ writel(intr_status & SUNXI_GMAC_INT_OFFSET, iobase + SUNXI_GMAC_INT_STA); -+ -+ return ret; -+} -+ -+/** -+ * sunxi_gmac_enable_rx - enable gmac rx dma -+ * -+ * @iobase: Gmac membase -+ * @rxbase: Base address of Rx descriptor -+ */ -+static void sunxi_gmac_enable_rx(void *iobase, unsigned long rxbase) -+{ -+ unsigned int value; -+ -+ /* Write the base address of Rx descriptor lists into registers */ -+ writel(rxbase, iobase + SUNXI_GMAC_RX_DESC_LIST); -+ -+ value = readl(iobase + SUNXI_GMAC_RX_CTL1); -+ value |= SUNXI_GMAC_RX_DMA_EN; -+ writel(value, iobase + SUNXI_GMAC_RX_CTL1); -+} -+ -+static int sunxi_gmac_read_rx_flowctl(void *iobase) -+{ -+ unsigned int value; -+ -+ value = readl(iobase + SUNXI_GMAC_RX_CTL1); -+ -+ return value & SUNXI_GMAC_RX_FLOW_CTL; -+} -+ -+static int sunxi_gmac_read_tx_flowctl(void *iobase) -+{ -+ unsigned int value; -+ -+ value = readl(iobase + SUNXI_GMAC_TX_FLOW_CTL); -+ -+ return value & SUNXI_GMAC_TX_FLOW_CTL_BIT; -+} -+ -+static void sunxi_gmac_write_rx_flowctl(void *iobase, bool flag) -+{ -+ unsigned int value; -+ -+ value = readl(iobase + SUNXI_GMAC_RX_CTL1); -+ -+ if (flag) -+ value |= SUNXI_GMAC_RX_FLOW_CTL; -+ else -+ value &= ~SUNXI_GMAC_RX_FLOW_CTL; -+ -+ writel(value, iobase + SUNXI_GMAC_RX_CTL1); -+} -+ -+static void sunxi_gmac_write_tx_flowctl(void *iobase, bool flag) -+{ -+ unsigned int value; -+ -+ value = readl(iobase + SUNXI_GMAC_TX_FLOW_CTL); -+ -+ if (flag) -+ value |= SUNXI_GMAC_TX_FLOW_CTL_BIT; -+ else -+ value &= ~SUNXI_GMAC_TX_FLOW_CTL_BIT; -+ -+ writel(value, iobase + SUNXI_GMAC_TX_FLOW_CTL); -+} -+ -+/** -+ * sunxi_gmac_enable_tx - enable gmac tx dma -+ * -+ * @iobase: Gmac membase -+ * @rxbase: Base address of Tx descriptor -+ */ -+static void sunxi_gmac_enable_tx(void *iobase, unsigned long txbase) -+{ -+ unsigned int value; -+ -+ /* Write the base address of Tx descriptor lists into registers */ -+ writel(txbase, iobase + SUNXI_GMAC_TX_DESC_LIST); -+ -+ value = readl(iobase + SUNXI_GMAC_TX_CTL1); -+ value |= SUNXI_GMAC_TX_DMA_EN; -+ writel(value, iobase + SUNXI_GMAC_TX_CTL1); -+} -+ -+/** -+ * sunxi_gmac_disable_tx - disable gmac tx dma -+ * -+ * @iobase: Gmac membase -+ * @rxbase: Base address of Tx descriptor -+ */ -+static void sunxi_gmac_disable_tx(void *iobase) -+{ -+ unsigned int value = readl(iobase + SUNXI_GMAC_TX_CTL1); -+ -+ value &= ~SUNXI_GMAC_TX_DMA_EN; -+ writel(value, iobase + SUNXI_GMAC_TX_CTL1); -+} -+ -+static int sunxi_gmac_dma_init(void *iobase) -+{ -+ unsigned int value; -+ -+ /* Burst should be 8 */ -+ value = (SUNXI_GMAC_BURST_VALUE << SUNXI_GMAC_BURST_OFFSET); -+ -+#ifdef CONFIG_SUNXI_GMAC_DA -+ value |= SUNXI_GMAC_RX_TX_PRI; /* Rx has priority over tx */ -+#endif -+ writel(value, iobase + SUNXI_GMAC_BASIC_CTL1); -+ -+ /* Mask interrupts by writing to CSR7 */ -+ writel(SUNXI_GMAC_RX_INT | SUNXI_GMAC_TX_UNF_INT, iobase + SUNXI_GMAC_INT_EN); -+ -+ return 0; -+} -+ -+/** -+ * sunxi_gmac_init - init gmac config -+ * -+ * @iobase: Gmac membase -+ * @txmode: tx flow control mode -+ * @rxmode: rx flow control mode -+ */ -+static int sunxi_gmac_init(void *iobase, int txmode, int rxmode) -+{ -+ unsigned int value; -+ -+ sunxi_gmac_dma_init(iobase); -+ -+ /* Initialize the core component */ -+ value = readl(iobase + SUNXI_GMAC_TX_CTL0); -+ value |= (1 << SUNXI_GMAC_TX_FRM_LEN_OFFSET); -+ writel(value, iobase + SUNXI_GMAC_TX_CTL0); -+ -+ value = readl(iobase + SUNXI_GMAC_RX_CTL0); -+ value |= (1 << SUNXI_GMAC_CRC_OFFSET); /* Enable CRC & IPv4 Header Checksum */ -+ value |= (1 << SUNXI_GMAC_STRIP_FCS_OFFSET); /* Automatic Pad/CRC Stripping */ -+ value |= (1 << SUNXI_GMAC_JUMBO_EN_OFFSET); /* Jumbo Frame Enable */ -+ writel(value, iobase + SUNXI_GMAC_RX_CTL0); -+ -+ writel((SUNXI_GMAC_MDC_DIV_RATIO_M << SUNXI_GMAC_MDC_DIV_OFFSET), -+ iobase + SUNXI_GMAC_MDIO_ADDR); /* MDC_DIV_RATIO */ -+ -+ /* Set the Rx&Tx mode */ -+ value = readl(iobase + SUNXI_GMAC_TX_CTL1); -+ if (txmode == SUNXI_GMAC_SF_DMA_MODE) { -+ /* Transmit COE type 2 cannot be done in cut-through mode. */ -+ value |= SUNXI_GMAC_TX_MD; -+ /* Operating on second frame increase the performance -+ * especially when transmit store-and-forward is used. -+ */ -+ value |= SUNXI_GMAC_TX_NEXT_FRM; -+ } else { -+ value &= ~SUNXI_GMAC_TX_MD; -+ value &= ~SUNXI_GMAC_TX_TH; -+ /* Set the transmit threshold */ -+ if (txmode <= SUNXI_GMAC_TX_DMA_TH64) -+ value |= SUNXI_GMAC_TX_DMA_TH64_VAL; -+ else if (txmode <= SUNXI_GMAC_TX_DMA_TH128) -+ value |= SUNXI_GMAC_TX_DMA_TH128_VAL; -+ else if (txmode <= SUNXI_GMAC_TX_DMA_TH192) -+ value |= SUNXI_GMAC_TX_DMA_TH192_VAL; -+ else -+ value |= SUNXI_GMAC_TX_DMA_TH256_VAL; -+ } -+ writel(value, iobase + SUNXI_GMAC_TX_CTL1); -+ -+ value = readl(iobase + SUNXI_GMAC_RX_CTL1); -+ if (rxmode == SUNXI_GMAC_SF_DMA_MODE) { -+ value |= SUNXI_GMAC_RX_MD; -+ } else { -+ value &= ~SUNXI_GMAC_RX_MD; -+ value &= ~SUNXI_GMAC_RX_TH; -+ if (rxmode <= SUNXI_GMAC_RX_DMA_TH32) -+ value |= SUNXI_GMAC_RX_DMA_TH32_VAL; -+ else if (rxmode <= SUNXI_GMAC_RX_DMA_TH64) -+ value |= SUNXI_GMAC_RX_DMA_TH64_VAL; -+ else if (rxmode <= SUNXI_GMAC_RX_DMA_TH96) -+ value |= SUNXI_GMAC_RX_DMA_TH96_VAL; -+ else -+ value |= SUNXI_GMAC_RX_DMA_TH128_VAL; -+ } -+ -+ /* Forward frames with error and undersized good frame. */ -+ value |= (SUNXI_GMAC_RX_ERR_FRM | SUNXI_GMAC_RX_RUNT_FRM); -+ -+ writel(value, iobase + SUNXI_GMAC_RX_CTL1); -+ -+ return 0; -+} -+ -+static void sunxi_gmac_hash_filter(void *iobase, unsigned long low, unsigned long high) -+{ -+ writel(high, iobase + SUNXI_GMAC_RX_HASH0); -+ writel(low, iobase + SUNXI_GMAC_RX_HASH1); -+} -+ -+/* write macaddr into MAC register */ -+static void sunxi_gmac_set_mac_addr_to_reg(void *iobase, unsigned char *addr, int index) -+{ -+ unsigned long data; -+ -+ /* one char is 8bit, so splice mac address in steps of 8 */ -+ data = (addr[5] << 8) | addr[4]; -+ writel(data, iobase + SUNXI_GMAC_ADDR_HI(index)); -+ data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; -+ writel(data, iobase + SUNXI_GMAC_ADDR_LO(index)); -+} -+ -+static void sunxi_gmac_dma_start(void *iobase) -+{ -+ unsigned long value; -+ -+ value = readl(iobase + SUNXI_GMAC_TX_CTL0); -+ value |= (1 << SUNXI_GMAC_TX_DMA_START); -+ writel(value, iobase + SUNXI_GMAC_TX_CTL0); -+ -+ value = readl(iobase + SUNXI_GMAC_RX_CTL0); -+ value |= (1 << SUNXI_GMAC_RX_DMA_START); -+ writel(value, iobase + SUNXI_GMAC_RX_CTL0); -+} -+ -+static void sunxi_gmac_dma_stop(void *iobase) -+{ -+ unsigned long value; -+ -+ value = readl(iobase + SUNXI_GMAC_TX_CTL0); -+ value &= ~(1 << SUNXI_GMAC_TX_DMA_START); -+ writel(value, iobase + SUNXI_GMAC_TX_CTL0); -+ -+ value = readl(iobase + SUNXI_GMAC_RX_CTL0); -+ value &= ~(1 << SUNXI_GMAC_RX_DMA_START); -+ writel(value, iobase + SUNXI_GMAC_RX_CTL0); -+} -+ -+static void sunxi_gmac_tx_poll(void *iobase) -+{ -+ unsigned int value; -+ -+ value = readl(iobase + SUNXI_GMAC_TX_CTL1); -+ writel(value | (1 << SUNXI_GMAC_TX_DMA_START), iobase + SUNXI_GMAC_TX_CTL1); -+} -+ -+static void sunxi_gmac_irq_enable(void *iobase) -+{ -+ writel(SUNXI_GMAC_RX_INT | SUNXI_GMAC_TX_UNF_INT, iobase + SUNXI_GMAC_INT_EN); -+} -+ -+static void sunxi_gmac_irq_disable(void *iobase) -+{ -+ writel(0, iobase + SUNXI_GMAC_INT_EN); -+} -+ -+static void sunxi_gmac_desc_buf_set(struct sunxi_gmac_dma_desc *desc, unsigned long paddr, int size) -+{ -+ desc->desc1.all &= (~((1 << SUNXI_GMAC_DMA_DESC_BUFSIZE) - 1)); -+ desc->desc1.all |= (size & ((1 << SUNXI_GMAC_DMA_DESC_BUFSIZE) - 1)); -+ desc->desc2 = paddr; -+} -+ -+static void sunxi_gmac_desc_set_own(struct sunxi_gmac_dma_desc *desc) -+{ -+ desc->desc0.all |= SUNXI_GMAC_OWN_DMA; -+} -+ -+static void sunxi_gmac_desc_tx_close(struct sunxi_gmac_dma_desc *first, struct sunxi_gmac_dma_desc *end, int csum_insert) -+{ -+ struct sunxi_gmac_dma_desc *desc = first; -+ -+ first->desc1.tx.first_sg = 1; -+ end->desc1.tx.last_seg = 1; -+ end->desc1.tx.interrupt = 1; -+ -+ if (csum_insert) -+ do { -+ desc->desc1.tx.cic = 3; -+ desc++; -+ } while (desc <= end); -+} -+ -+static void sunxi_gmac_desc_init(struct sunxi_gmac_dma_desc *desc) -+{ -+ desc->desc1.all = 0; -+ desc->desc2 = 0; -+ desc->desc1.all |= (1 << SUNXI_GMAC_CHAIN_MODE_OFFSET); -+} -+ -+static int sunxi_gmac_desc_get_tx_status(struct sunxi_gmac_dma_desc *desc, struct sunxi_gmac_extra_stats *x) -+{ -+ int ret = 0; -+ -+ if (desc->desc0.tx.under_err) { -+ x->tx_underflow++; -+ ret = -EIO; -+ } -+ -+ if (desc->desc0.tx.no_carr) { -+ x->tx_carrier++; -+ ret = -EIO; -+ } -+ -+ if (desc->desc0.tx.loss_carr) { -+ x->tx_losscarrier++; -+ ret = -EIO; -+ } -+ -+ if (desc->desc0.tx.deferred) { -+ x->tx_deferred++; -+ ret = -EIO; -+ } -+ -+ return ret; -+} -+ -+static int sunxi_gmac_desc_buf_get_len(struct sunxi_gmac_dma_desc *desc) -+{ -+ return (desc->desc1.all & ((1 << SUNXI_GMAC_DMA_DESC_BUFSIZE) - 1)); -+} -+ -+static int sunxi_gmac_desc_buf_get_addr(struct sunxi_gmac_dma_desc *desc) -+{ -+ return desc->desc2; -+} -+ -+static int sunxi_gmac_desc_rx_frame_len(struct sunxi_gmac_dma_desc *desc) -+{ -+ return desc->desc0.rx.frm_len; -+} -+ -+static int sunxi_gmac_desc_llc_snap(struct sunxi_gmac_dma_desc *desc) -+{ -+ /* Splice flags as follow: -+ * bits 5 7 0 | Frame status -+ * ---------------------------------------------------------- -+ * 0 0 0 | IEEE 802.3 Type frame (length < 1536 octects) -+ * 1 0 0 | IPv4/6 No CSUM errorS. -+ * 1 0 1 | IPv4/6 CSUM PAYLOAD error -+ * 1 1 0 | IPv4/6 CSUM IP HR error -+ * 1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS -+ * 0 0 1 | IPv4/6 unsupported IP PAYLOAD -+ * 0 1 1 | COE bypassed.. no IPv4/6 frame -+ * 0 1 0 | Reserved. -+ */ -+ return ((desc->desc0.rx.frm_type << 2 | -+ desc->desc0.rx.ipch_err << 1 | -+ desc->desc0.rx.chsum_err) & 0x7); -+} -+ -+static int sunxi_gmac_desc_get_rx_status(struct sunxi_gmac_dma_desc *desc, struct sunxi_gmac_extra_stats *x) -+{ -+ int ret = good_frame; -+ -+ if (desc->desc0.rx.last_desc == 0) -+ return incomplete_frame; -+ -+ if (desc->desc0.rx.err_sum) { -+ if (desc->desc0.rx.desc_err) -+ x->rx_desc++; -+ -+ if (desc->desc0.rx.sou_filter) -+ x->sa_filter_fail++; -+ -+ if (desc->desc0.rx.over_err) -+ x->overflow_error++; -+ -+ if (desc->desc0.rx.ipch_err) -+ x->ipc_csum_error++; -+ -+ if (desc->desc0.rx.late_coll) -+ x->rx_collision++; -+ -+ if (desc->desc0.rx.crc_err) -+ x->rx_crc++; -+ -+ ret = discard_frame; -+ } -+ -+ if (desc->desc0.rx.len_err) -+ ret = discard_frame; -+ -+ if (desc->desc0.rx.mii_err) -+ ret = discard_frame; -+ -+ if (ret == good_frame) { -+ if (sunxi_gmac_desc_llc_snap(desc) == 0) -+ ret = llc_snap; -+ } -+ -+ return ret; -+} -+ -+static int sunxi_gmac_desc_get_own(struct sunxi_gmac_dma_desc *desc) -+{ -+ return desc->desc0.all & SUNXI_GMAC_OWN_DMA; -+} -+ -+static int sunxi_gmac_desc_get_tx_last_seg(struct sunxi_gmac_dma_desc *desc) -+{ -+ return desc->desc1.tx.last_seg; -+} -+ -+static int sunxi_gmac_reset(void *iobase, int n) -+{ -+ unsigned int value; -+ -+ /* gmac software reset */ -+ value = readl(iobase + SUNXI_GMAC_BASIC_CTL1); -+ value |= SUNXI_GMAC_SOFT_RST; -+ writel(value, iobase + SUNXI_GMAC_BASIC_CTL1); -+ -+ udelay(n); -+ -+ return !!(readl(iobase + SUNXI_GMAC_BASIC_CTL1) & SUNXI_GMAC_SOFT_RST); -+} -+ -+static int sunxi_gmac_stop(struct net_device *ndev); -+ -+static void sunxi_gmac_dump_dma_desc(struct sunxi_gmac_dma_desc *desc, int size) -+{ -+#ifdef DEBUG -+ int i; -+ -+ for (i = 0; i < size; i++) { -+ u32 *x = (u32 *)(desc + i); -+ -+ pr_info("\t%d [0x%08lx]: %08x %08x %08x %08x\n", -+ i, (unsigned long)(&desc[i]), -+ x[0], x[1], x[2], x[3]); -+ } -+ pr_info("\n"); -+#endif -+} -+ -+static ssize_t sunxi_gmac_extra_tx_stats_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ return sprintf(buf, "tx_underflow: %lu\ntx_carrier: %lu\n" -+ "tx_losscarrier: %lu\nvlan_tag: %lu\n" -+ "tx_deferred: %lu\ntx_vlan: %lu\n" -+ "tx_jabber: %lu\ntx_frame_flushed: %lu\n" -+ "tx_payload_error: %lu\ntx_ip_header_error: %lu\n\n", -+ chip->xstats.tx_underflow, chip->xstats.tx_carrier, -+ chip->xstats.tx_losscarrier, chip->xstats.vlan_tag, -+ chip->xstats.tx_deferred, chip->xstats.tx_vlan, -+ chip->xstats.tx_jabber, chip->xstats.tx_frame_flushed, -+ chip->xstats.tx_payload_error, chip->xstats.tx_ip_header_error); -+} -+/* eg: cat extra_tx_stats */ -+static DEVICE_ATTR(extra_tx_stats, 0444, sunxi_gmac_extra_tx_stats_show, NULL); -+ -+static ssize_t sunxi_gmac_extra_rx_stats_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ return sprintf(buf, "rx_desc: %lu\nsa_filter_fail: %lu\n" -+ "overflow_error: %lu\nipc_csum_error: %lu\n" -+ "rx_collision: %lu\nrx_crc: %lu\n" -+ "dribbling_bit: %lu\nrx_length: %lu\n" -+ "rx_mii: %lu\nrx_multicast: %lu\n" -+ "rx_gmac_overflow: %lu\nrx_watchdog: %lu\n" -+ "da_rx_filter_fail: %lu\nsa_rx_filter_fail: %lu\n" -+ "rx_missed_cntr: %lu\nrx_overflow_cntr: %lu\n" -+ "rx_vlan: %lu\n\n", -+ chip->xstats.rx_desc, chip->xstats.sa_filter_fail, -+ chip->xstats.overflow_error, chip->xstats.ipc_csum_error, -+ chip->xstats.rx_collision, chip->xstats.rx_crc, -+ chip->xstats.dribbling_bit, chip->xstats.rx_length, -+ chip->xstats.rx_mii, chip->xstats.rx_multicast, -+ chip->xstats.rx_gmac_overflow, chip->xstats.rx_length, -+ chip->xstats.da_rx_filter_fail, chip->xstats.sa_rx_filter_fail, -+ chip->xstats.rx_missed_cntr, chip->xstats.rx_overflow_cntr, -+ chip->xstats.rx_vlan); -+} -+/* eg: cat extra_rx_stats */ -+static DEVICE_ATTR(extra_rx_stats, 0444, sunxi_gmac_extra_rx_stats_show, NULL); -+ -+static ssize_t sunxi_gmac_gphy_test_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "Usage:\necho [0/1/2/3/4] > gphy_test\n" -+ "0 - Normal Mode\n" -+ "1 - Transmit Jitter Test\n" -+ "2 - Transmit Jitter Test(MASTER mode)\n" -+ "3 - Transmit Jitter Test(SLAVE mode)\n" -+ "4 - Transmit Distortion Test\n\n"); -+} -+ -+static ssize_t sunxi_gmac_gphy_test_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ u16 value, phyreg_val; -+ int ret; -+ -+ phyreg_val = phy_read(ndev->phydev, MII_CTRL1000); -+ -+ ret = kstrtou16(buf, 0, &value); -+ if (ret) -+ return ret; -+ -+ if (value >= 0 && value <= 4) { -+ phyreg_val &= ~(SUNXI_GMAC_GPHY_TEST_MASK << -+ SUNXI_GMAC_GPHY_TEST_OFFSET); -+ phyreg_val |= value << SUNXI_GMAC_GPHY_TEST_OFFSET; -+ phy_write(ndev->phydev, MII_CTRL1000, phyreg_val); -+ netdev_info(ndev, "Set MII_CTRL1000(0x09) Reg: 0x%x\n", phyreg_val); -+ } else { -+ netdev_err(ndev, "Error: Unknown value (%d)\n", value); -+ } -+ -+ return count; -+} -+/* eg: echo 0 > gphy_test */ -+static DEVICE_ATTR(gphy_test, 0664, sunxi_gmac_gphy_test_show, sunxi_gmac_gphy_test_store); -+ -+static ssize_t sunxi_gmac_mii_read_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "Usage:\necho PHYREG > mii_read\n"); -+} -+ -+static ssize_t sunxi_gmac_mii_read_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ u16 phyreg, phyreg_val; -+ int ret; -+ -+ if (!netif_running(ndev)) { -+ netdev_err(ndev, "Error: Nic is down\n"); -+ return count; -+ } -+ -+ ret = kstrtou16(buf, 0, &phyreg); -+ if (ret) -+ return ret; -+ -+ phyreg_val = phy_read(ndev->phydev, phyreg); -+ netdev_info(ndev, "PHYREG[0x%02x] = 0x%04x\n", phyreg, phyreg_val); -+ return count; -+} -+/* eg: echo 0x00 > mii_read; cat mii_read */ -+static DEVICE_ATTR(mii_read, 0664, sunxi_gmac_mii_read_show, sunxi_gmac_mii_read_store); -+ -+static ssize_t sunxi_gmac_mii_write_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "Usage:\necho PHYREG PHYVAL > mii_write\n"); -+} -+ -+static ssize_t sunxi_gmac_mii_write_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ u16 phyreg_val_before, phyreg_val_after; -+ int i, ret; -+ /* userspace_cmd[0]: phyreg -+ * userspace_cmd[1]: phyval -+ */ -+ u16 userspace_cmd[2] = {0}; -+ char *ptr1 = (char *)buf; -+ char *ptr2; -+ -+ if (!netif_running(ndev)) { -+ netdev_err(ndev, "Error: Nic is down\n"); -+ return count; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(userspace_cmd); i++) { -+ ptr1 = skip_spaces(ptr1); -+ ptr2 = strchr(ptr1, ' '); -+ if (ptr2) -+ *ptr2 = '\0'; -+ -+ ret = kstrtou16(ptr1, 16, &userspace_cmd[i]); -+ if (!ptr2 || ret) -+ break; -+ -+ ptr1 = ptr2 + 1; -+ } -+ -+ phyreg_val_before = phy_read(ndev->phydev, userspace_cmd[0]); -+ phy_write(ndev->phydev, userspace_cmd[0], userspace_cmd[1]); -+ phyreg_val_after = phy_read(ndev->phydev, userspace_cmd[0]); -+ netdev_info(ndev, "before PHYREG[0x%02x] = 0x%04x, after PHYREG[0x%02x] = 0x%04x\n", -+ userspace_cmd[0], phyreg_val_before, userspace_cmd[0], phyreg_val_after); -+ -+ return count; -+} -+/* eg: echo 0x00 0x1234 > mii_write; cat mii_write */ -+static DEVICE_ATTR(mii_write, 0664, sunxi_gmac_mii_write_show, sunxi_gmac_mii_write_store); -+ -+static ssize_t sunxi_gmac_loopback_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ int macreg_val; -+ u16 phyreg_val; -+ -+ phyreg_val = phy_read(ndev->phydev, MII_BMCR); -+ if (phyreg_val & BMCR_LOOPBACK) -+ netdev_dbg(ndev, "Phy loopback enabled\n"); -+ else -+ netdev_dbg(ndev, "Phy loopback disabled\n"); -+ -+ macreg_val = readl(chip->base); -+ if (macreg_val & SUNXI_GMAC_LOOPBACK) -+ netdev_dbg(ndev, "Mac loopback enabled\n"); -+ else -+ netdev_dbg(ndev, "Mac loopback disabled\n"); -+ -+ return sprintf(buf, "Usage:\necho [0/1/2] > loopback\n" -+ "0 - Loopback off\n" -+ "1 - Mac loopback mode\n" -+ "2 - Phy loopback mode\n"); -+} -+ -+static ssize_t sunxi_gmac_loopback_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ int phyreg_val, ret; -+ u16 mode; -+ -+ if (!netif_running(ndev)) { -+ netdev_err(ndev, "Error: eth is down\n"); -+ return count; -+ } -+ -+ ret = kstrtou16(buf, 0, &mode); -+ if (ret) -+ return ret; -+ -+ switch (mode) { -+ case SUNXI_GMAC_LOOPBACK_OFF: -+ sunxi_gmac_loopback(chip->base, 0); -+ phyreg_val = phy_read(ndev->phydev, MII_BMCR); -+ phy_write(ndev->phydev, MII_BMCR, phyreg_val & ~BMCR_LOOPBACK); -+ break; -+ case SUNXI_GMAC_MAC_LOOPBACK_ON: -+ phyreg_val = phy_read(ndev->phydev, MII_BMCR); -+ phy_write(ndev->phydev, MII_BMCR, phyreg_val & ~BMCR_LOOPBACK); -+ sunxi_gmac_loopback(chip->base, 1); -+ break; -+ case SUNXI_GMAC_PHY_LOOPBACK_ON: -+ sunxi_gmac_loopback(chip->base, 0); -+ phyreg_val = phy_read(ndev->phydev, MII_BMCR); -+ phy_write(ndev->phydev, MII_BMCR, phyreg_val | BMCR_LOOPBACK); -+ break; -+ default: -+ netdev_err(ndev, "Error: Please echo right value\n"); -+ break; -+ } -+ -+ return count; -+} -+/* eg: echo 1 > loopback */ -+static DEVICE_ATTR(loopback, 0664, sunxi_gmac_loopback_show, sunxi_gmac_loopback_store); -+ -+static ssize_t sunxi_gmac_tx_delay_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ u32 reg_val; -+ u16 tx_delay; -+ -+ reg_val = readl(chip->syscfg_base); -+ tx_delay = (reg_val >> SUNXI_GMAC_TX_DELAY_OFFSET) & SUNXI_GMAC_TX_DELAY_MASK; -+ -+ return sprintf(buf, "Usage:\necho [0~7] > tx_delay\n" -+ "\nnow tx_delay: %d\n", tx_delay); -+} -+ -+static ssize_t sunxi_gmac_tx_delay_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ int ret; -+ u32 reg_val; -+ u16 tx_delay; -+ -+ if (!netif_running(ndev)) { -+ netdev_err(ndev, "Error: eth is down\n"); -+ return count; -+ } -+ -+ ret = kstrtou16(buf, 0, &tx_delay); -+ if (ret) -+ return ret; -+ -+ if (tx_delay > 7) -+ return -EINVAL; -+ -+ reg_val = readl(chip->syscfg_base); -+ reg_val &= ~(SUNXI_GMAC_TX_DELAY_MASK << SUNXI_GMAC_TX_DELAY_OFFSET); -+ reg_val |= ((tx_delay & SUNXI_GMAC_TX_DELAY_MASK) << SUNXI_GMAC_TX_DELAY_OFFSET); -+ writel(reg_val, chip->syscfg_base); -+ -+ return count; -+} -+/* eg: echo 1 > tx_delay */ -+static DEVICE_ATTR(tx_delay, 0664, sunxi_gmac_tx_delay_show, sunxi_gmac_tx_delay_store); -+ -+static ssize_t sunxi_gmac_rx_delay_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ u32 reg_val; -+ u16 rx_delay; -+ -+ reg_val = readl(chip->syscfg_base); -+ rx_delay = (reg_val >> SUNXI_GMAC_RX_DELAY_OFFSET) & SUNXI_GMAC_RX_DELAY_MASK; -+ -+ return sprintf(buf, "Usage:\necho [0~31] > rx_delay\n" -+ "\nnow rx_delay: %d\n", rx_delay); -+} -+ -+static ssize_t sunxi_gmac_rx_delay_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ int ret; -+ u32 reg_val; -+ u16 rx_delay; -+ -+ if (!netif_running(ndev)) { -+ netdev_err(ndev, "Error: eth is down\n"); -+ return count; -+ } -+ -+ ret = kstrtou16(buf, 0, &rx_delay); -+ if (ret) -+ return ret; -+ -+ if (rx_delay > 31) -+ return -EINVAL; -+ -+ reg_val = readl(chip->syscfg_base); -+ reg_val &= ~(SUNXI_GMAC_RX_DELAY_MASK << SUNXI_GMAC_RX_DELAY_OFFSET); -+ reg_val |= ((rx_delay & SUNXI_GMAC_RX_DELAY_MASK) << SUNXI_GMAC_RX_DELAY_OFFSET); -+ writel(reg_val, chip->syscfg_base); -+ -+ return count; -+} -+/* eg: echo 1 > rx_delay */ -+static DEVICE_ATTR(rx_delay, 0664, sunxi_gmac_rx_delay_show, sunxi_gmac_rx_delay_store); -+ -+/* In phy state machine, we use this func to change link status */ -+static void sunxi_gmac_adjust_link(struct net_device *ndev) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ struct phy_device *phydev = ndev->phydev; -+ unsigned long flags; -+ int new_state = 0; -+ -+ if (!phydev) -+ return; -+ -+ spin_lock_irqsave(&chip->universal_lock, flags); -+ if (phydev->link) { -+ /* Now we make sure that we can be in full duplex mode. -+ * If not, we operate in half-duplex mode. -+ */ -+ if (phydev->duplex != chip->duplex) { -+ new_state = 1; -+ chip->duplex = phydev->duplex; -+ } -+ /* Flow Control operation */ -+ if (phydev->pause) -+ sunxi_gmac_flow_ctrl(chip->base, phydev->duplex, -+ flow_ctrl, pause); -+ -+ if (phydev->speed != chip->speed) { -+ new_state = 1; -+ chip->speed = phydev->speed; -+ } -+ -+ if (chip->link == 0) { -+ new_state = 1; -+ chip->link = phydev->link; -+ } -+ -+ if (new_state) -+ sunxi_gmac_set_link_mode(chip->base, chip->duplex, chip->speed); -+ -+ } else if (chip->link != phydev->link) { -+ new_state = 1; -+ chip->link = 0; -+ chip->speed = 0; -+ chip->duplex = -1; -+ } -+ spin_unlock_irqrestore(&chip->universal_lock, flags); -+ -+ if (new_state) -+ phy_print_status(phydev); -+} -+ -+static int sunxi_gmac_phy_release(struct net_device *ndev) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ struct phy_device *phydev = ndev->phydev; -+ int value; -+ -+ /* Stop and disconnect the PHY */ -+ if (phydev) -+ phy_stop(phydev); -+ -+ chip->link = PHY_DOWN; -+ chip->speed = 0; -+ chip->duplex = -1; -+ -+ if (phydev) { -+ value = phy_read(phydev, MII_BMCR); -+ phy_write(phydev, MII_BMCR, (value | BMCR_PDOWN)); -+ } -+ -+ if (phydev) { -+ phy_disconnect(phydev); -+ ndev->phydev = NULL; -+ } -+ -+ return 0; -+} -+ -+/* Refill rx dma descriptor after using */ -+static void sunxi_gmac_rx_refill(struct net_device *ndev) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ struct sunxi_gmac_dma_desc *desc; -+ struct sk_buff *skb = NULL; -+ dma_addr_t dma_addr; -+ -+ while (circ_space(chip->rx_clean, chip->rx_dirty, sunxi_gmac_dma_desc_rx) > 0) { -+ int entry = chip->rx_clean; -+ -+ /* Find the dirty's desc and clean it */ -+ desc = chip->dma_rx + entry; -+ -+ if (chip->rx_skb[entry] == NULL) { -+ skb = netdev_alloc_skb_ip_align(ndev, chip->buf_sz); -+ -+ if (unlikely(skb == NULL)) -+ break; -+ -+ chip->rx_skb[entry] = skb; -+ dma_addr = dma_map_single(chip->dev, skb->data, -+ chip->buf_sz, DMA_FROM_DEVICE); -+ -+ sunxi_gmac_desc_buf_set(desc, dma_addr, chip->buf_sz); -+ } -+ -+ dma_wmb(); -+ sunxi_gmac_desc_set_own(desc); -+ chip->rx_clean = circ_inc(chip->rx_clean, sunxi_gmac_dma_desc_rx); -+ } -+} -+ -+/* -+ * sunxi_gmac_dma_desc_init - initialize the RX/TX descriptor list -+ * -+ * @ndev: net device structure -+ * Description: initialize the list for dma. -+ */ -+static int sunxi_gmac_dma_desc_init(struct net_device *ndev) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ struct device *dev = &ndev->dev; -+ -+ chip->rx_skb = devm_kzalloc(dev, sizeof(chip->rx_skb[0]) * sunxi_gmac_dma_desc_rx, -+ GFP_KERNEL); -+ if (!chip->rx_skb) { -+ netdev_err(ndev, "Error: Alloc rx_skb failed\n"); -+ goto rx_skb_err; -+ } -+ chip->tx_skb = devm_kzalloc(dev, sizeof(chip->tx_skb[0]) * sunxi_gmac_dma_desc_tx, -+ GFP_KERNEL); -+ if (!chip->tx_skb) { -+ netdev_err(ndev, "Error: Alloc tx_skb failed\n"); -+ goto tx_skb_err; -+ } -+ -+ chip->dma_tx = dma_alloc_coherent(chip->dev, -+ sunxi_gmac_dma_desc_tx * -+ sizeof(struct sunxi_gmac_dma_desc), -+ &chip->dma_tx_phy, -+ GFP_KERNEL); -+ if (!chip->dma_tx) { -+ netdev_err(ndev, "Error: Alloc dma_tx failed\n"); -+ goto dma_tx_err; -+ } -+ -+ chip->dma_rx = dma_alloc_coherent(chip->dev, -+ sunxi_gmac_dma_desc_rx * -+ sizeof(struct sunxi_gmac_dma_desc), -+ &chip->dma_rx_phy, -+ GFP_KERNEL); -+ if (!chip->dma_rx) { -+ netdev_err(ndev, "Error: Alloc dma_rx failed\n"); -+ goto dma_rx_err; -+ } -+ -+ /* Set the size of buffer depend on the MTU & max buf size */ -+ chip->buf_sz = SUNXI_GMAC_MAX_BUF_SZ; -+ return 0; -+ -+dma_rx_err: -+ dma_free_coherent(chip->dev, sunxi_gmac_dma_desc_rx * sizeof(struct sunxi_gmac_dma_desc), -+ chip->dma_tx, chip->dma_tx_phy); -+dma_tx_err: -+ kfree(chip->tx_skb); -+tx_skb_err: -+ kfree(chip->rx_skb); -+rx_skb_err: -+ return -ENOMEM; -+} -+ -+static void sunxi_gmac_free_rx_skb(struct sunxi_gmac *chip) -+{ -+ int i; -+ -+ for (i = 0; i < sunxi_gmac_dma_desc_rx; i++) { -+ if (chip->rx_skb[i] != NULL) { -+ struct sunxi_gmac_dma_desc *desc = chip->dma_rx + i; -+ -+ dma_unmap_single(chip->dev, (u32)sunxi_gmac_desc_buf_get_addr(desc), -+ sunxi_gmac_desc_buf_get_len(desc), -+ DMA_FROM_DEVICE); -+ dev_kfree_skb_any(chip->rx_skb[i]); -+ chip->rx_skb[i] = NULL; -+ } -+ } -+} -+ -+static void sunxi_gmac_free_tx_skb(struct sunxi_gmac *chip) -+{ -+ int i; -+ -+ for (i = 0; i < sunxi_gmac_dma_desc_tx; i++) { -+ if (chip->tx_skb[i] != NULL) { -+ struct sunxi_gmac_dma_desc *desc = chip->dma_tx + i; -+ -+ if (sunxi_gmac_desc_buf_get_addr(desc)) -+ dma_unmap_single(chip->dev, (u32)sunxi_gmac_desc_buf_get_addr(desc), -+ sunxi_gmac_desc_buf_get_len(desc), -+ DMA_TO_DEVICE); -+ dev_kfree_skb_any(chip->tx_skb[i]); -+ chip->tx_skb[i] = NULL; -+ } -+ } -+} -+ -+static void sunxi_gmac_dma_desc_deinit(struct sunxi_gmac *chip) -+{ -+ /* Free the region of consistent memory previously allocated for the DMA */ -+ dma_free_coherent(chip->dev, sunxi_gmac_dma_desc_tx * sizeof(struct sunxi_gmac_dma_desc), -+ chip->dma_tx, chip->dma_tx_phy); -+ dma_free_coherent(chip->dev, sunxi_gmac_dma_desc_rx * sizeof(struct sunxi_gmac_dma_desc), -+ chip->dma_rx, chip->dma_rx_phy); -+ -+ kfree(chip->rx_skb); -+ kfree(chip->tx_skb); -+} -+ -+static int sunxi_gmac_stop(struct net_device *ndev) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ netif_stop_queue(ndev); -+ napi_disable(&chip->napi); -+ -+ netif_carrier_off(ndev); -+ -+ sunxi_gmac_phy_release(ndev); -+ -+ sunxi_gmac_dma_stop(chip->base); -+ -+ netif_tx_lock_bh(ndev); -+ /* Release the DMA TX/RX socket buffers */ -+ sunxi_gmac_free_rx_skb(chip); -+ sunxi_gmac_free_tx_skb(chip); -+ netif_tx_unlock_bh(ndev); -+ -+ return 0; -+} -+ -+static int sunxi_gmac_power_on(struct sunxi_gmac *chip) -+{ -+ int ret; -+ -+ if (IS_ERR_OR_NULL(chip->gmac_supply)) -+ return 0; -+ -+ ret = regulator_set_voltage(chip->gmac_supply, 3300000, 3300000); -+ if (ret) { -+ dev_err(chip->dev, "gmac-power set voltage error\n"); -+ return -EINVAL; -+ } -+ -+ ret = regulator_enable(chip->gmac_supply); -+ if (ret) { -+ dev_err(chip->dev, "Error: enable gmac-power failed\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static void sunxi_gmac_power_off(struct sunxi_gmac *chip) -+{ -+ if (IS_ERR_OR_NULL(chip->gmac_supply)) -+ return; -+ -+ regulator_disable(chip->gmac_supply); -+} -+ -+/** -+ * sunxi_gmac_open - GMAC device open -+ * @ndev: The Allwinner GMAC network adapter -+ * -+ * Called when system wants to start the interface. We init TX/RX channels -+ * and enable the hardware for packet reception/transmission and start the -+ * network queue. -+ * -+ * Returns 0 for a successful open, or appropriate error code -+ */ -+static int sunxi_gmac_open(struct net_device *ndev) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ int ret; -+ -+ /* -+ * When changing the configuration of GMAC and PHY, -+ * it is necessary to turn off the carrier on the link. -+ */ -+ netif_carrier_off(ndev); -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+ if (chip->ac300_np) { -+ chip->ac300_dev = of_phy_find_device(chip->ac300_np); -+ if (!chip->ac300_dev) { -+ netdev_err(ndev, "Error: Could not find ac300 %s\n", -+ chip->ac300_np->full_name); -+ return -ENODEV; -+ } -+ phy_init_hw(chip->ac300_dev); -+ } -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ -+ if (chip->phy_node) { -+ ndev->phydev = of_phy_connect(ndev, chip->phy_node, -+ &sunxi_gmac_adjust_link, 0, chip->phy_interface); -+ if (!ndev->phydev) { -+ netdev_err(ndev, "Error: Could not connect to phy %s\n", -+ chip->phy_node->full_name); -+ return -ENODEV; -+ } -+ netdev_info(ndev, "%s: Type(%d) PHY ID %08x at %d IRQ %s (%s)\n", -+ ndev->name, ndev->phydev->interface, ndev->phydev->phy_id, -+ ndev->phydev->mdio.addr, "poll", dev_name(&ndev->phydev->mdio.dev)); -+ } -+ ret = sunxi_gmac_reset((void *)chip->base, 1000); -+ if (ret) { -+ netdev_err(ndev, "Error: Mac reset failed, please check phy and mac clk\n"); -+ goto mac_reset_err; -+ } -+ -+ sunxi_gmac_init(chip->base, txmode, rxmode); -+ sunxi_gmac_set_mac_addr_to_reg(chip->base, (unsigned char *)ndev->dev_addr, 0); -+ -+ memset(chip->dma_tx, 0, sunxi_gmac_dma_desc_tx * sizeof(struct sunxi_gmac_dma_desc)); -+ memset(chip->dma_rx, 0, sunxi_gmac_dma_desc_rx * sizeof(struct sunxi_gmac_dma_desc)); -+ -+ sunxi_gmac_desc_init_chain(chip->dma_rx, (unsigned long)chip->dma_rx_phy, sunxi_gmac_dma_desc_rx); -+ sunxi_gmac_desc_init_chain(chip->dma_tx, (unsigned long)chip->dma_tx_phy, sunxi_gmac_dma_desc_tx); -+ -+ chip->rx_clean = 0; -+ chip->rx_dirty = 0; -+ chip->tx_clean = 0; -+ chip->tx_dirty = 0; -+ sunxi_gmac_rx_refill(ndev); -+ -+ /* Extra statistics */ -+ memset(&chip->xstats, 0, sizeof(struct sunxi_gmac_extra_stats)); -+ -+ if (ndev->phydev) -+ phy_start(ndev->phydev); -+ -+ sunxi_gmac_enable_rx(chip->base, (unsigned long)((struct sunxi_gmac_dma_desc *) -+ chip->dma_rx_phy + chip->rx_dirty)); -+ sunxi_gmac_enable_tx(chip->base, (unsigned long)((struct sunxi_gmac_dma_desc *) -+ chip->dma_tx_phy + chip->tx_clean)); -+ -+ napi_enable(&chip->napi); -+ netif_start_queue(ndev); -+ -+ /* Start the Rx/Tx */ -+ sunxi_gmac_dma_start(chip->base); -+ -+ /* Indicate that the MAC is responsible for managing PHY PM */ -+ ndev->phydev->mac_managed_pm = true; -+ -+ return 0; -+ -+mac_reset_err: -+ phy_disconnect(ndev->phydev); -+ return ret; -+} -+ -+static int sunxi_gmac_clk_enable(struct sunxi_gmac *chip); -+static void sunxi_gmac_clk_disable(struct sunxi_gmac *chip); -+ -+#if IS_ENABLED(CONFIG_PM) -+static int sunxi_gmac_select_gpio_state(struct pinctrl *pctrl, char *name) -+{ -+ int ret; -+ struct pinctrl_state *pctrl_state; -+ -+ pctrl_state = pinctrl_lookup_state(pctrl, name); -+ if (IS_ERR(pctrl_state)) { -+ pr_err("gmac pinctrl_lookup_state(%s) failed! return %p\n", -+ name, pctrl_state); -+ return -EINVAL; -+ } -+ -+ ret = pinctrl_select_state(pctrl, pctrl_state); -+ if (ret < 0) -+ pr_err("gmac pinctrl_select_state(%s) failed! return %d\n", -+ name, ret); -+ -+ return ret; -+} -+ -+static int sunxi_gmac_resume(struct device *dev) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ if (!netif_running(ndev)) -+ return 0; -+ -+ sunxi_gmac_power_on(chip); -+ -+ sunxi_gmac_clk_enable(chip); -+ -+ sunxi_gmac_select_gpio_state(chip->pinctrl, PINCTRL_STATE_DEFAULT); -+ -+ netif_device_attach(ndev); -+ -+ sunxi_gmac_open(ndev); -+ -+ /* suspend error workaround */ -+ if (ndev->phydev) -+ dev_set_uevent_suppress(&ndev->phydev->mdio.dev, chip->gmac_uevent_suppress); -+ -+ return 0; -+} -+ -+static int sunxi_gmac_suspend(struct device *dev) -+{ -+ struct net_device *ndev = dev_get_drvdata(dev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ if (!ndev || !netif_running(ndev)) -+ return 0; -+ -+ /* suspend error workaround */ -+ if (ndev->phydev) { -+ chip->gmac_uevent_suppress = dev_get_uevent_suppress(&ndev->phydev->mdio.dev); -+ dev_set_uevent_suppress(&ndev->phydev->mdio.dev, true); -+ } -+ -+ netif_device_detach(ndev); -+ -+ sunxi_gmac_stop(ndev); -+ -+ sunxi_gmac_select_gpio_state(chip->pinctrl, PINCTRL_STATE_SLEEP); -+ -+ sunxi_gmac_power_off(chip); -+ -+ sunxi_gmac_clk_disable(chip); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops sunxi_gmac_pm_ops = { -+ .suspend = sunxi_gmac_suspend, -+ .resume = sunxi_gmac_resume, -+}; -+#else -+static const struct dev_pm_ops sunxi_gmac_pm_ops; -+#endif /* CONFIG_PM */ -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+static void sunxi_gmac_shutdown(struct platform_device *pdev) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ if (chip->ac300_dev) -+ phy_detach(chip->ac300_dev); -+} -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ -+static void sunxi_gmac_check_addr(struct net_device *ndev, unsigned char *mac) -+{ -+ int i; -+ char *p = mac; -+ unsigned char tmp_addr[6]; -+ -+ if (!is_valid_ether_addr(ndev->dev_addr)) { -+ for (i = 0; i < ETH_ALEN; i++, p++) { -+ tmp_addr[i] = simple_strtoul(p, &p, 16); -+ dev_addr_mod(ndev, i, &tmp_addr[i], sizeof(char)); -+ } -+ -+ if (!is_valid_ether_addr(ndev->dev_addr)) { -+ eth_random_addr((u8 *)ndev->dev_addr); -+ netdev_info(ndev, "Info: Use random mac address\n"); -+ } -+ } -+} -+ -+static int sunxi_gmac_clk_enable(struct sunxi_gmac *chip) -+{ -+ struct net_device *ndev = chip->ndev; -+ int ret; -+ u32 clk_value; -+ -+ ret = reset_control_deassert(chip->reset); -+ if (ret) { -+ netdev_err(ndev, "Error: Try to de-assert gmac rst failed\n"); -+ goto gmac_reset_err; -+ } -+ -+ ret = clk_prepare_enable(chip->gmac_clk); -+ if (ret) { -+ netdev_err(ndev, "Error: Try to enable gmac_clk failed\n"); -+ goto gmac_clk_err; -+ } -+ -+ if (chip->phy_clk_type == SUNXI_PHY_USE_CLK25M) { -+ ret = clk_prepare_enable(chip->phy25m_clk); -+ if (ret) { -+ netdev_err(ndev, "Error: Try to enable phy25m_clk failed\n"); -+ goto phy25m_clk_err; -+ } -+ } -+ -+ clk_value = readl(chip->syscfg_base); -+ /* Only support RGMII/RMII/MII */ -+ if (chip->phy_interface == PHY_INTERFACE_MODE_RGMII) -+ clk_value |= SUNXI_GMAC_PHY_RGMII_MASK; -+ else -+ clk_value &= (~SUNXI_GMAC_PHY_RGMII_MASK); -+ -+ clk_value &= (~SUNXI_GMAC_ETCS_RMII_MASK); -+ if (chip->phy_interface == PHY_INTERFACE_MODE_RGMII -+ || chip->phy_interface == PHY_INTERFACE_MODE_GMII) -+ clk_value |= SUNXI_GMAC_RGMII_INTCLK_MASK; -+ else if (chip->phy_interface == PHY_INTERFACE_MODE_RMII) -+ clk_value |= SUNXI_GMAC_RMII_MASK; -+ -+ /* -+ * Adjust Tx/Rx clock delay -+ * Tx clock delay: 0~7 -+ * Rx clock delay: 0~31 -+ */ -+ clk_value &= ~(SUNXI_GMAC_TX_DELAY_MASK << SUNXI_GMAC_TX_DELAY_OFFSET); -+ clk_value |= ((chip->tx_delay & SUNXI_GMAC_TX_DELAY_MASK) << SUNXI_GMAC_TX_DELAY_OFFSET); -+ clk_value &= ~(SUNXI_GMAC_RX_DELAY_MASK << SUNXI_GMAC_RX_DELAY_OFFSET); -+ clk_value |= ((chip->rx_delay & SUNXI_GMAC_RX_DELAY_MASK) << SUNXI_GMAC_RX_DELAY_OFFSET); -+ -+ if (chip->phy_type == SUNXI_EXTERNAL_PHY) -+ clk_value &= ~(1 << 15); -+ else -+ clk_value |= (1 << 15); -+ -+ writel(clk_value, chip->syscfg_base); -+ -+ return 0; -+ -+phy25m_clk_err: -+ clk_disable(chip->gmac_clk); -+gmac_clk_err: -+ reset_control_assert(chip->reset); -+gmac_reset_err: -+ return ret; -+} -+ -+static void sunxi_gmac_clk_disable(struct sunxi_gmac *chip) -+{ -+ writel(0, chip->syscfg_base); -+ -+ if (chip->phy25m_clk) -+ clk_disable_unprepare(chip->phy25m_clk); -+ -+ if (chip->gmac_clk) -+ clk_disable_unprepare(chip->gmac_clk); -+ -+ if (chip->reset) -+ reset_control_assert(chip->reset); -+} -+ -+static void sunxi_gmac_tx_err(struct sunxi_gmac *chip) -+{ -+ netif_stop_queue(chip->ndev); -+ -+ sunxi_gmac_disable_tx(chip->base); -+ -+ sunxi_gmac_free_tx_skb(chip); -+ memset(chip->dma_tx, 0, sunxi_gmac_dma_desc_tx * sizeof(struct sunxi_gmac_dma_desc)); -+ sunxi_gmac_desc_init_chain(chip->dma_tx, (unsigned long)chip->dma_tx_phy, sunxi_gmac_dma_desc_tx); -+ chip->tx_dirty = 0; -+ chip->tx_clean = 0; -+ sunxi_gmac_enable_tx(chip->base, chip->dma_tx_phy); -+ -+ chip->ndev->stats.tx_errors++; -+ netif_wake_queue(chip->ndev); -+} -+ -+static void sunxi_gmac_schedule(struct sunxi_gmac *chip) -+{ -+ if (likely(napi_schedule_prep(&chip->napi))) { -+ sunxi_gmac_irq_disable(chip->base); -+ __napi_schedule(&chip->napi); -+ } -+} -+ -+static irqreturn_t sunxi_gmac_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *ndev = (struct net_device *)dev_id; -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ int status; -+ -+ status = sunxi_gmac_int_status(chip->base, (void *)(&chip->xstats)); -+ -+ if (likely(status == handle_tx_rx)) -+ sunxi_gmac_schedule(chip); -+ else if (unlikely(status == tx_hard_error_bump_tc)) -+ netdev_info(ndev, "Do nothing for bump tc\n"); -+ else if (unlikely(status == tx_hard_error)) -+ sunxi_gmac_tx_err(chip); -+ else -+ netdev_info(ndev, "Do nothing.....\n"); -+ -+ return IRQ_HANDLED; -+} -+ -+static void sunxi_gmac_tx_complete(struct sunxi_gmac *chip) -+{ -+ unsigned int entry = 0; -+ struct sk_buff *skb = NULL; -+ struct sunxi_gmac_dma_desc *desc = NULL; -+ int tx_stat; -+ -+ spin_lock_bh(&chip->tx_lock); -+ while (circ_cnt(chip->tx_dirty, chip->tx_clean, sunxi_gmac_dma_desc_tx) > 0) { -+ entry = chip->tx_clean; -+ desc = chip->dma_tx + entry; -+ -+ /* Check if the descriptor is owned by the DMA. */ -+ if (sunxi_gmac_desc_get_own(desc)) -+ break; -+ -+ /* Verify tx error by looking at the last segment */ -+ if (sunxi_gmac_desc_get_tx_last_seg(desc)) { -+ tx_stat = sunxi_gmac_desc_get_tx_status(desc, (void *)(&chip->xstats)); -+ -+ /* -+ * These stats will be parsed by net framework layer -+ * use ifconfig -a in linux cmdline to view -+ */ -+ if (likely(!tx_stat)) -+ chip->ndev->stats.tx_packets++; -+ else -+ chip->ndev->stats.tx_errors++; -+ } -+ -+ dma_unmap_single(chip->dev, (u32)sunxi_gmac_desc_buf_get_addr(desc), -+ sunxi_gmac_desc_buf_get_len(desc), DMA_TO_DEVICE); -+ -+ skb = chip->tx_skb[entry]; -+ chip->tx_skb[entry] = NULL; -+ sunxi_gmac_desc_init(desc); -+ -+ /* Find next dirty desc */ -+ chip->tx_clean = circ_inc(entry, sunxi_gmac_dma_desc_tx); -+ -+ if (unlikely(skb == NULL)) -+ continue; -+ -+ dev_kfree_skb(skb); -+ } -+ -+ if (unlikely(netif_queue_stopped(chip->ndev)) && -+ circ_space(chip->tx_dirty, chip->tx_clean, sunxi_gmac_dma_desc_tx) > -+ SUNXI_GMAC_TX_THRESH) { -+ netif_wake_queue(chip->ndev); -+ } -+ spin_unlock_bh(&chip->tx_lock); -+} -+ -+static netdev_tx_t sunxi_gmac_xmit(struct sk_buff *skb, struct net_device *ndev) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ struct sunxi_gmac_dma_desc *desc, *first; -+ unsigned int entry, len, tmp_len = 0; -+ unsigned char *data_addr = skb->data; -+ int i, csum_insert; -+ int nfrags = skb_shinfo(skb)->nr_frags; -+ dma_addr_t dma_addr; -+ -+ spin_lock_bh(&chip->tx_lock); -+ if (unlikely(circ_space(chip->tx_dirty, chip->tx_clean, -+ sunxi_gmac_dma_desc_tx) < (nfrags + 1))) { -+ if (!netif_queue_stopped(ndev)) { -+ netdev_err(ndev, "Error: Tx Ring full when queue awake\n"); -+ netif_stop_queue(ndev); -+ } -+ spin_unlock_bh(&chip->tx_lock); -+ -+ return NETDEV_TX_BUSY; -+ } -+ -+ csum_insert = (skb->ip_summed == CHECKSUM_PARTIAL); -+ entry = chip->tx_dirty; -+ first = chip->dma_tx + entry; -+ desc = chip->dma_tx + entry; -+ -+ len = skb_headlen(skb); -+ chip->tx_skb[entry] = skb; -+ -+ /* Every desc max size is 2K */ -+ while (len != 0) { -+ desc = chip->dma_tx + entry; -+ tmp_len = ((len > SUNXI_GMAC_MAX_BUF_SZ) ? SUNXI_GMAC_MAX_BUF_SZ : len); -+ -+ dma_addr = dma_map_single(chip->dev, data_addr, tmp_len, DMA_TO_DEVICE); -+ if (dma_mapping_error(chip->dev, dma_addr)) { -+ ndev->stats.tx_dropped++; -+ dev_kfree_skb(skb); -+ spin_unlock_bh(&chip->tx_lock); -+ return -ENOMEM; -+ } -+ -+ sunxi_gmac_desc_buf_set(desc, dma_addr, tmp_len); -+ /* Don't set the first's own bit, here */ -+ if (first != desc) { -+ chip->tx_skb[entry] = NULL; -+ sunxi_gmac_desc_set_own(desc); -+ } -+ -+ entry = circ_inc(entry, sunxi_gmac_dma_desc_tx); -+ data_addr += tmp_len; -+ len -= tmp_len; -+ } -+ -+ for (i = 0; i < nfrags; i++) { -+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; -+ -+ len = skb_frag_size(frag); -+ desc = chip->dma_tx + entry; -+ dma_addr = skb_frag_dma_map(chip->dev, frag, 0, len, DMA_TO_DEVICE); -+ if (dma_mapping_error(chip->dev, dma_addr)) { -+ ndev->stats.tx_dropped++; -+ dev_kfree_skb(skb); -+ spin_unlock_bh(&chip->tx_lock); -+ return -ENOMEM; -+ } -+ -+ sunxi_gmac_desc_buf_set(desc, dma_addr, len); -+ sunxi_gmac_desc_set_own(desc); -+ chip->tx_skb[entry] = NULL; -+ entry = circ_inc(entry, sunxi_gmac_dma_desc_tx); -+ } -+ -+ ndev->stats.tx_bytes += skb->len; -+ chip->tx_dirty = entry; -+ sunxi_gmac_desc_tx_close(first, desc, csum_insert); -+ -+ /* -+ * When the own bit, for the first frame, has to be set, all -+ * descriptors for the same frame has to be set before, to -+ * avoid race condition. -+ */ -+ dma_wmb(); -+ -+ sunxi_gmac_desc_set_own(first); -+ spin_unlock_bh(&chip->tx_lock); -+ -+ if (circ_space(chip->tx_dirty, chip->tx_clean, sunxi_gmac_dma_desc_tx) <= -+ (MAX_SKB_FRAGS + 1)) { -+ netif_stop_queue(ndev); -+ if (circ_space(chip->tx_dirty, chip->tx_clean, sunxi_gmac_dma_desc_tx) > -+ SUNXI_GMAC_TX_THRESH) -+ netif_wake_queue(ndev); -+ } -+ -+ netdev_dbg(ndev, "TX descripotor DMA: 0x%08x, dirty: %d, clean: %d\n", -+ (unsigned int)chip->dma_tx_phy, chip->tx_dirty, chip->tx_clean); -+ sunxi_gmac_dump_dma_desc(chip->dma_tx, sunxi_gmac_dma_desc_tx); -+ -+ sunxi_gmac_tx_poll(chip->base); -+ sunxi_gmac_tx_complete(chip); -+ -+ return NETDEV_TX_OK; -+} -+ -+static void sunxi_gmac_copy_loopback_data(struct sunxi_gmac *chip, -+ struct sk_buff *skb) -+{ -+ struct net_device *ndev = chip->ndev; -+ int loopback_len = chip->loopback_pkt_len; -+ int pkt_offset, frag_len, i; -+ void *frag_data = NULL; -+ u8 *loopback_buf = chip->loopback_test_rx_buf; -+ -+ if (chip->loopback_test_rx_idx == LOOPBACK_PKT_CNT) { -+ chip->loopback_test_rx_idx = 0; -+ netdev_warn(ndev, "Warning: Loopback test receive too more test pkts\n"); -+ } -+ -+ if (skb->len != chip->loopback_pkt_len) { -+ netdev_warn(ndev, "Warning: Wrong pkt length\n"); -+ chip->loopback_test_rx_idx++; -+ return; -+ } -+ -+ pkt_offset = chip->loopback_test_rx_idx * loopback_len; -+ frag_len = (int)skb_headlen(skb); -+ memcpy(loopback_buf + pkt_offset, skb->data, frag_len); -+ pkt_offset += frag_len; -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { -+ frag_data = skb_frag_address(&skb_shinfo(skb)->frags[i]); -+ frag_len = (int)skb_frag_size(&skb_shinfo(skb)->frags[i]); -+ memcpy((loopback_buf + pkt_offset), frag_data, frag_len); -+ pkt_offset += frag_len; -+ } -+ -+ chip->loopback_test_rx_idx++; -+} -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_GMAC_METADATA) -+static int sunxi_gmac_rx_metadata_cmp(struct sk_buff *skb) -+{ -+ const u8 tmp[4] = {0xAA, 0xAA, 0xAA, 0xAA}; -+ u8 *data = skb->data; -+ -+ data = data + (2 * ETH_ALEN + 2); -+ return memcmp(data, tmp, 4); -+} -+#endif -+ -+static int sunxi_gmac_rx(struct sunxi_gmac *chip, int limit) -+{ -+ unsigned int rxcount = 0, offset = 0; -+ unsigned int entry; -+ struct sunxi_gmac_dma_desc *desc = NULL; -+ int status; -+ u32 frame_len; -+ -+ while (rxcount < limit) { -+ entry = chip->rx_dirty; -+ desc = chip->dma_rx + entry; -+ -+ if (sunxi_gmac_desc_get_own(desc)) -+ break; -+ -+ rxcount++; -+ chip->rx_dirty = circ_inc(chip->rx_dirty, sunxi_gmac_dma_desc_rx); -+ -+ /* Get length & status from hardware */ -+ frame_len = sunxi_gmac_desc_rx_frame_len(desc); -+ status = sunxi_gmac_desc_get_rx_status(desc, (void *)(&chip->xstats)); -+ -+ netdev_dbg(chip->ndev, "Rx frame size %d, status: %d\n", -+ frame_len, status); -+ -+ if (unlikely(!chip->rx_skb[entry])) { -+ netdev_err(chip->ndev, "Skb is null\n"); -+ chip->ndev->stats.rx_dropped++; -+ break; -+ } -+ -+ if (status == discard_frame || frame_len > SUNXI_GMAC_MAX_MTU_SZ) { -+ netdev_err(chip->ndev, "Get error pkt\n"); -+ chip->ndev->stats.rx_errors++; -+ if (chip->rx_skb[entry]) { -+ dev_kfree_skb_any(chip->rx_skb[entry]); -+ chip->rx_skb[entry] = NULL; -+ } -+ -+ if (chip->skb) { -+ dev_kfree_skb_any(chip->skb); -+ chip->skb = NULL; -+ } -+ continue; -+ } -+ -+ dma_unmap_single(chip->dev, (u32)sunxi_gmac_desc_buf_get_addr(desc), -+ sunxi_gmac_desc_buf_get_len(desc), DMA_FROM_DEVICE); -+ -+ /* jumbo frame */ -+ if (status == incomplete_frame) { -+ if (!chip->skb) -+ chip->skb = netdev_alloc_skb_ip_align(chip->ndev, SUNXI_GMAC_MAX_MTU_SZ); -+ -+ if (!chip->skb) { -+ netdev_err(chip->ndev, "Failed to alloc skb\n"); -+ if (chip->rx_skb[entry]) { -+ dev_kfree_skb_any(chip->rx_skb[entry]); -+ chip->rx_skb[entry] = NULL; -+ } -+ continue; -+ } -+ -+ skb_copy_to_linear_data_offset(chip->skb, offset, chip->rx_skb[entry]->data, frame_len - offset); -+ /* after copy, release tmp skb */ -+ dev_kfree_skb_any(chip->rx_skb[entry]); -+ chip->rx_skb[entry] = NULL; -+ offset = frame_len; -+ continue; -+ } else { -+ if (!chip->skb) { -+ /* -+ * no need to copy skb, -+ * pass it to protocol stack, -+ * and protocol stack will release skb -+ */ -+ chip->skb = chip->rx_skb[entry]; -+ chip->rx_skb[entry] = NULL; -+ } else { -+ skb_copy_to_linear_data_offset(chip->skb, offset, chip->rx_skb[entry]->data, frame_len - offset); -+ /* after copy, release tmp skb */ -+ dev_kfree_skb_any(chip->rx_skb[entry]); -+ chip->rx_skb[entry] = NULL; -+ } -+ offset = 0; -+ } -+ -+ if (likely(status != llc_snap)) -+ frame_len -= ETH_FCS_LEN; -+ -+ skb_put(chip->skb, frame_len); -+ -+ if (unlikely(chip->is_loopback_test)) -+ sunxi_gmac_copy_loopback_data(chip, chip->skb); -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_GMAC_METADATA) -+ if (unlikely(sunxi_gmac_rx_metadata_cmp(chip->skb) == 0)) { -+ frame_len = min(frame_len, chip->metadata_len); -+ memcpy(chip->metadata_buff, chip->skb->data + (2 * ETH_ALEN + 6), frame_len); -+ complete(&chip->metadata_done); -+ dev_kfree_skb_any(chip->skb); -+ continue; -+ } -+#endif -+ -+ chip->skb->protocol = eth_type_trans(chip->skb, chip->ndev); -+ chip->skb->ip_summed = CHECKSUM_UNNECESSARY; -+ -+ napi_gro_receive(&chip->napi, chip->skb); -+ -+ chip->ndev->stats.rx_packets++; -+ chip->ndev->stats.rx_bytes += frame_len; -+ chip->skb = NULL; -+ } -+ -+ if (rxcount > 0) { -+ netdev_dbg(chip->ndev, "RX descriptor DMA: 0x%08x, dirty: %d, clean: %d\n", -+ (unsigned int)chip->dma_rx_phy, chip->rx_dirty, chip->rx_clean); -+ sunxi_gmac_dump_dma_desc(chip->dma_rx, sunxi_gmac_dma_desc_rx); -+ } -+ -+ sunxi_gmac_rx_refill(chip->ndev); -+ -+ return rxcount; -+} -+ -+static int sunxi_gmac_poll(struct napi_struct *napi, int budget) -+{ -+ struct sunxi_gmac *chip = container_of(napi, struct sunxi_gmac, napi); -+ int work_done = 0; -+ -+ sunxi_gmac_tx_complete(chip); -+ work_done = sunxi_gmac_rx(chip, budget); -+ -+ if (work_done < budget) { -+ napi_complete(napi); -+ sunxi_gmac_irq_enable(chip->base); -+ } -+ -+ return work_done; -+} -+ -+static int sunxi_gmac_change_mtu(struct net_device *ndev, int new_mtu) -+{ -+ if (netif_running(ndev)) { -+ netdev_err(ndev, "Error: Nic must be stopped to change its MTU\n"); -+ return -EBUSY; -+ } -+ -+ if (new_mtu < 46) { -+ netdev_err(ndev, "Error: Invalid MTU\n"); -+ return -EINVAL; -+ } -+ -+ ndev->mtu = new_mtu; -+ netdev_update_features(ndev); -+ -+ return 0; -+} -+ -+static netdev_features_t sunxi_gmac_fix_features(struct net_device *ndev, -+ netdev_features_t features) -+{ -+ return features; -+} -+ -+static void sunxi_gmac_set_rx_mode(struct net_device *ndev) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ unsigned int value = 0; -+ -+ netdev_dbg(ndev, "%s: # mcasts %d, # unicast %d\n", -+ __func__, netdev_mc_count(ndev), netdev_uc_count(ndev)); -+ -+ spin_lock_bh(&chip->universal_lock); -+ if (ndev->flags & IFF_PROMISC) { -+ value = SUNXI_GMAC_FRAME_FILTER_PR; -+ } else if ((netdev_mc_count(ndev) > SUNXI_GMAC_HASH_TABLE_SIZE) || -+ (ndev->flags & IFF_ALLMULTI)) { -+ value = SUNXI_GMAC_FRAME_FILTER_PM; /* pass all multi */ -+ sunxi_gmac_hash_filter(chip->base, ~0UL, ~0UL); -+ } else if (!netdev_mc_empty(ndev)) { -+ u32 mc_filter[2]; -+ struct netdev_hw_addr *ha; -+ -+ /* Hash filter for multicast */ -+ value = SUNXI_GMAC_FRAME_FILTER_HMC; -+ -+ memset(mc_filter, 0, sizeof(mc_filter)); -+ netdev_for_each_mc_addr(ha, ndev) { -+ /* The upper 6 bits of the calculated CRC are used to -+ * index the contens of the hash table -+ */ -+ int bit_nr = bitrev32(~crc32_le(~0, ha->addr, 6)) >> 26; -+ /* The most significant bit determines the register to -+ * use (H/L) while the other 5 bits determine the bit -+ * within the register. -+ */ -+ mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); -+ } -+ sunxi_gmac_hash_filter(chip->base, mc_filter[0], mc_filter[1]); -+ } -+ -+ /* Handle multiple unicast addresses (perfect filtering)*/ -+ if (netdev_uc_count(ndev) > 16) { -+ /* Switch to promiscuous mode is more than 8 addrs are required */ -+ value |= SUNXI_GMAC_FRAME_FILTER_PR; -+ } else { -+ int reg = 1; -+ struct netdev_hw_addr *ha; -+ -+ netdev_for_each_uc_addr(ha, ndev) { -+ sunxi_gmac_set_mac_addr_to_reg(chip->base, ha->addr, reg); -+ reg++; -+ } -+ } -+ -+#ifdef FRAME_FILTER_DEBUG -+ /* Enable Receive all mode (to debug filtering_fail errors) */ -+ value |= SUNXI_GMAC_FRAME_FILTER_RA; -+#endif -+ writel(value, chip->base + SUNXI_GMAC_RX_FRM_FLT); -+ spin_unlock_bh(&chip->universal_lock); -+} -+ -+static void sunxi_gmac_tx_timeout(struct net_device *ndev, unsigned int txqueue) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ sunxi_gmac_tx_err(chip); -+} -+ -+static int sunxi_gmac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) -+{ -+ if (!netif_running(ndev)) -+ return -EINVAL; -+ -+ if (!ndev->phydev) -+ return -EINVAL; -+ -+ return phy_mii_ioctl(ndev->phydev, rq, cmd); -+} -+ -+/* Configuration changes (passed on by ifconfig) */ -+static int sunxi_gmac_config(struct net_device *ndev, struct ifmap *map) -+{ -+ if (ndev->flags & IFF_UP) /* can't act on a running interface */ -+ return -EBUSY; -+ -+ /* Don't allow changing the I/O address */ -+ if (map->base_addr != ndev->base_addr) { -+ netdev_err(ndev, "Error: Can't change I/O address\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ /* Don't allow changing the IRQ */ -+ if (map->irq != ndev->irq) { -+ netdev_err(ndev, "Error: Can't change IRQ number %d\n", ndev->irq); -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ -+static int sunxi_gmac_set_mac_address(struct net_device *ndev, void *p) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ struct sockaddr *addr = p; -+ -+ if (!is_valid_ether_addr(addr->sa_data)) { -+ netdev_err(ndev, "Error: Set error mac address\n"); -+ return -EADDRNOTAVAIL; -+ } -+ -+ eth_hw_addr_set(ndev, addr->sa_data); -+ sunxi_gmac_set_mac_addr_to_reg(chip->base, (unsigned char *)ndev->dev_addr, 0); -+ -+ return 0; -+} -+ -+static int sunxi_gmac_set_features(struct net_device *ndev, netdev_features_t features) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ if (features & NETIF_F_LOOPBACK && netif_running(ndev)) -+ sunxi_gmac_loopback(chip->base, 1); -+ else -+ sunxi_gmac_loopback(chip->base, 0); -+ -+ return 0; -+} -+ -+#if IS_ENABLED(CONFIG_NET_POLL_CONTROLLER) -+/* Polling receive - used by NETCONSOLE and other diagnostic tools -+ * to allow network I/O with interrupts disabled. -+ */ -+static void sunxi_gmac_poll_controller(struct net_device *dev) -+{ -+ disable_irq(dev->irq); -+ sunxi_gmac_interrupt(dev->irq, dev); -+ enable_irq(dev->irq); -+} -+#endif -+ -+static const struct net_device_ops sunxi_gmac_netdev_ops = { -+ .ndo_init = NULL, -+ .ndo_open = sunxi_gmac_open, -+ .ndo_start_xmit = sunxi_gmac_xmit, -+ .ndo_stop = sunxi_gmac_stop, -+ .ndo_change_mtu = sunxi_gmac_change_mtu, -+ .ndo_fix_features = sunxi_gmac_fix_features, -+ .ndo_set_rx_mode = sunxi_gmac_set_rx_mode, -+ .ndo_tx_timeout = sunxi_gmac_tx_timeout, -+ .ndo_do_ioctl = sunxi_gmac_ioctl, -+ .ndo_set_config = sunxi_gmac_config, -+#if IS_ENABLED(CONFIG_NET_POLL_CONTROLLER) -+ .ndo_poll_controller = sunxi_gmac_poll_controller, -+#endif -+ .ndo_set_mac_address = sunxi_gmac_set_mac_address, -+ .ndo_set_features = sunxi_gmac_set_features, -+}; -+ -+static int sunxi_gmac_check_if_running(struct net_device *ndev) -+{ -+ if (!netif_running(ndev)) -+ return -EBUSY; -+ return 0; -+} -+ -+static int sunxi_gmac_ethtool_get_sset_count(struct net_device *netdev, int sset) -+{ -+ int len; -+ -+ switch (sset) { -+ case ETH_SS_STATS: -+ len = 0; -+ return len; -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+ -+/** -+ * sunxi_gmac_ethtool_getdrvinfo - Get various SUNXI GMAC driver information. -+ * @ndev: Pointer to net_device structure -+ * @ed: Pointer to ethtool_drvinfo structure -+ * -+ * This implements ethtool command for getting the driver information. -+ * Issue "ethtool -i ethX" under linux prompt to execute this function. -+ */ -+static void sunxi_gmac_ethtool_getdrvinfo(struct net_device *ndev, -+ struct ethtool_drvinfo *info) -+{ -+ strscpy(info->driver, "sunxi_gmac", sizeof(info->driver)); -+ -+ strcpy(info->version, SUNXI_GMAC_MODULE_VERSION); -+ info->fw_version[0] = '\0'; -+} -+ -+/** -+ * sunxi_gmac_ethool_get_pauseparam - Get the pause parameter setting for Tx/Rx. -+ * -+ * @ndev: Pointer to net_device structure -+ * @epause: Pointer to ethtool_pauseparam structure -+ * -+ * This implements ethtool command for getting sunxi_gmac ethernet pause frame -+ * setting. Issue "ethtool -a ethx" to execute this function. -+ */ -+static void sunxi_gmac_ethtool_get_pauseparam(struct net_device *ndev, -+ struct ethtool_pauseparam *epause) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ /* TODO: need to support autoneg */ -+ epause->tx_pause = sunxi_gmac_read_tx_flowctl(chip->base); -+ epause->rx_pause = sunxi_gmac_read_rx_flowctl(chip->base); -+} -+ -+/** -+ * sunxi_gmac_ethtool_set_pauseparam - Set device pause paramter(flow contrl) -+ * settings. -+ * @ndev: Pointer to net_device structure -+ * @epause: Pointer to ethtool_pauseparam structure -+ * -+ * This implements ethtool command for enabling flow control on Rx and Tx. -+ * Issue "ethtool -A ethx tx on|off" under linux prompt to execute this -+ * function. -+ * -+ */ -+static int sunxi_gmac_ethtool_set_pauseparam(struct net_device *ndev, -+ struct ethtool_pauseparam *epause) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ sunxi_gmac_write_tx_flowctl(chip->base, !!epause->tx_pause); -+ netdev_info(ndev, "Tx flowctrl %s\n", epause->tx_pause ? "ON" : "OFF"); -+ -+ sunxi_gmac_write_rx_flowctl(chip->base, !!epause->rx_pause); -+ netdev_info(ndev, "Rx flowctrl %s\n", epause->rx_pause ? "ON" : "OFF"); -+ -+ return 0; -+} -+ -+/** -+ * sunxi_gmac_ethtool_get_wol - Get device wake-on-lan settings. -+ * -+ * @ndev: Pointer to net_device structure -+ * @wol: Pointer to ethtool_wolinfo structure -+ * -+ * This implements ethtool command for get wake-on-lan settings. -+ * Issue "ethtool -s ethx wol p|u|m|b|a|g|s|d" under linux prompt to execute -+ * this function. -+ */ -+static void sunxi_gmac_ethtool_get_wol(struct net_device *ndev, -+ struct ethtool_wolinfo *wol) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ spin_lock_irq(&chip->universal_lock); -+ /* TODO: need to support wol */ -+ spin_unlock_irq(&chip->universal_lock); -+ -+ netdev_err(ndev, "Error: wakeup-on-lan func is not supported yet\n"); -+} -+ -+/** -+ * sunxi_gmac_ethtool_set_wol - set device wake-on-lan settings. -+ * -+ * @ndev: Pointer to net_device structure -+ * @wol: Pointer to ethtool_wolinfo structure -+ * -+ * This implements ethtool command for set wake-on-lan settings. -+ * Issue "ethtool -s ethx wol p|u|n|b|a|g|s|d" under linux prompt to execute -+ * this function. -+ */ -+static int sunxi_gmac_ethtool_set_wol(struct net_device *ndev, -+ struct ethtool_wolinfo *wol) -+{ -+ /* -+ * TODO: Wake-on-lane function need to be supported. -+ */ -+ -+ return 0; -+} -+ -+static int __sunxi_gmac_loopback_test(struct net_device *ndev) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ struct sk_buff *skb_tmp = NULL, *skb = NULL; -+ u8 *test_data = NULL; -+ u8 *loopback_test_rx_buf = chip->loopback_test_rx_buf; -+ u32 i, j; -+ -+ skb_tmp = alloc_skb(LOOPBACK_PKT_LEN, GFP_ATOMIC); -+ if (!skb_tmp) -+ return -ENOMEM; -+ -+ test_data = __skb_put(skb_tmp, LOOPBACK_PKT_LEN); -+ -+ memset(test_data, 0xFF, 2 * ETH_ALEN); -+ test_data[ETH_ALEN] = 0xFE; -+ test_data[2 * ETH_ALEN] = 0x08; -+ test_data[2 * ETH_ALEN + 1] = 0x0; -+ -+ for (i = ETH_HLEN; i < LOOPBACK_PKT_LEN; i++) -+ test_data[i] = i & 0xFF; -+ -+ skb_tmp->queue_mapping = 0; -+ skb_tmp->ip_summed = CHECKSUM_COMPLETE; -+ skb_tmp->dev = ndev; -+ -+ for (i = 0; i < LOOPBACK_DEFAULT_TIME; i++) { -+ chip->loopback_test_rx_idx = 0; -+ memset(loopback_test_rx_buf, 0, LOOPBACK_PKT_CNT * LOOPBACK_PKT_LEN); -+ -+ for (j = 0; j < LOOPBACK_PKT_CNT; j++) { -+ skb = pskb_copy(skb_tmp, GFP_ATOMIC); -+ if (!skb) { -+ dev_kfree_skb_any(skb_tmp); -+ netdev_err(ndev, "Error: Copy skb failed for loopback test\n"); -+ return -ENOMEM; -+ } -+ -+ /* mark index for every pkt */ -+ skb->data[LOOPBACK_PKT_LEN - 1] = j; -+ -+ /* xmit loopback skb */ -+ if (sunxi_gmac_xmit(skb, ndev)) { -+ dev_kfree_skb_any(skb); -+ dev_kfree_skb_any(skb_tmp); -+ netdev_err(ndev, "Error: Xmit pkt failed for loopback test\n"); -+ return -EBUSY; -+ } -+ } -+ -+ /* wait till all pkts received to RX buffer */ -+ msleep(200); -+ -+ for (j = 0; j < LOOPBACK_PKT_CNT; j++) { -+ /* compare loopback data */ -+ if (memcmp(loopback_test_rx_buf + j * LOOPBACK_PKT_LEN, -+ skb_tmp->data, LOOPBACK_PKT_LEN - 1) || -+ (*(loopback_test_rx_buf + j * LOOPBACK_PKT_LEN + -+ LOOPBACK_PKT_LEN - 1) != j)) { -+ dev_kfree_skb_any(skb_tmp); -+ netdev_err(ndev, "Error: Compare pkt failed in loopback test (index=0x%02x, data[%d]=0x%02x)\n", -+ j + i * LOOPBACK_PKT_CNT, -+ LOOPBACK_PKT_LEN - 1, -+ *(loopback_test_rx_buf + j * LOOPBACK_PKT_LEN + -+ LOOPBACK_PKT_LEN - 1)); -+ return -EIO; -+ } -+ } -+ } -+ -+ dev_kfree_skb_any(skb_tmp); -+ return 0; -+} -+ -+static int sunxi_gmac_loopback_test(struct net_device *ndev, u32 flags, -+ enum self_test_index *test_index) -+{ -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ u8 *loopback_test_rx_buf = NULL; -+ int err = 0; -+ -+ /* set loopback */ -+ if (!(flags & ETH_TEST_FL_EXTERNAL_LB)) { -+ *test_index = INTERNAL_LOOPBACK_TEST; -+ sunxi_gmac_loopback(chip->base, true); -+ } else { -+ *test_index = EXTERNAL_LOOPBACK_TEST; -+ err |= phy_loopback(ndev->phydev, true); -+ if (err) -+ goto out; -+ } -+ -+ /* only focus data part, so turn off the crc check */ -+ sunxi_gmac_crc(chip->base, false); -+ -+ loopback_test_rx_buf = vmalloc(LOOPBACK_PKT_CNT * LOOPBACK_PKT_LEN); -+ if (!loopback_test_rx_buf) { -+ err |= -ENOMEM; -+ } else { -+ chip->loopback_test_rx_buf = loopback_test_rx_buf; -+ chip->loopback_pkt_len = LOOPBACK_PKT_LEN; -+ chip->is_loopback_test = true; -+ err |= __sunxi_gmac_loopback_test(ndev); -+ chip->is_loopback_test = false; -+ msleep(100); -+ vfree(loopback_test_rx_buf); -+ chip->loopback_test_rx_buf = NULL; -+ } -+ -+ sunxi_gmac_crc(chip->base, true); -+out: -+ if (!(flags & ETH_TEST_FL_EXTERNAL_LB)) -+ sunxi_gmac_loopback(chip->base, false); -+ else -+ err |= phy_loopback(ndev->phydev, false); -+ -+ return err; -+} -+ -+static void sunxi_gmac_self_test(struct net_device *ndev, -+ struct ethtool_test *eth_test, u64 *data) -+{ -+ enum self_test_index test_index = 0; -+ int err; -+ -+ memset(data, 0, SELF_TEST_MAX * sizeof(u64)); -+ -+ if (!netif_running(ndev)) { -+ netdev_err(ndev, "Error: Do not support selftest when ndev is closed\n"); -+ eth_test->flags |= ETH_TEST_FL_FAILED; -+ return; -+ } -+ -+ netif_carrier_off(ndev); -+ netif_tx_disable(ndev); -+ -+ err = sunxi_gmac_loopback_test(ndev, eth_test->flags, &test_index); -+ if (err) { -+ eth_test->flags |= ETH_TEST_FL_FAILED; -+ data[test_index] = 1; /* 0:success, 1:fail */ -+ netdev_err(ndev, "Error: Loopback test failed\n"); -+ } -+ -+ netif_tx_wake_all_queues(ndev); -+ netif_carrier_on(ndev); -+} -+ -+static int sunxi_gmac_get_sset_count(struct net_device *ndev, int sset) -+{ -+ switch (sset) { -+ case ETH_SS_TEST: -+ return ARRAY_SIZE(sunxi_gmac_test_strings); -+ case ETH_SS_STATS: -+ return -EOPNOTSUPP; -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static void sunxi_gmac_get_strings(struct net_device *netdev, -+ u32 stringset, u8 *data) -+{ -+ switch (stringset) { -+ case ETH_SS_TEST: -+ memcpy(data, *sunxi_gmac_test_strings, sizeof(sunxi_gmac_test_strings)); -+ return; -+ case ETH_SS_STATS: -+ return; -+ default: -+ return; -+ } -+} -+ -+static const struct ethtool_ops sunxi_gmac_ethtool_ops = { -+ .begin = sunxi_gmac_check_if_running, -+ .get_link = ethtool_op_get_link, -+ .get_pauseparam = sunxi_gmac_ethtool_get_pauseparam, -+ .set_pauseparam = sunxi_gmac_ethtool_set_pauseparam, -+ .get_wol = sunxi_gmac_ethtool_get_wol, -+ .set_wol = sunxi_gmac_ethtool_set_wol, -+ .get_sset_count = sunxi_gmac_ethtool_get_sset_count, -+ .get_drvinfo = sunxi_gmac_ethtool_getdrvinfo, -+ .get_link_ksettings = phy_ethtool_get_link_ksettings, -+ .set_link_ksettings = phy_ethtool_set_link_ksettings, -+ .get_sset_count = sunxi_gmac_get_sset_count, -+ .get_strings = sunxi_gmac_get_strings, -+ .self_test = sunxi_gmac_self_test, -+}; -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+static int sunxi_gmac_ephy_v1_hardware_init(struct sunxi_gmac *chip) -+{ -+ int ret; -+ -+ ret = pwm_config(chip->ac300_pwm, PWM_DUTY_NS, PWM_PERIOD_NS); -+ if (ret) { -+ netdev_err(chip->ndev, "Error: Config ac300 pwm failed\n"); -+ return ret; -+ } -+ -+ ret = pwm_enable(chip->ac300_pwm); -+ if (ret) { -+ netdev_err(chip->ndev, "Error: Enable ac300 pwm failed\n"); -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ -+static int sunxi_gmac_hardware_init(struct platform_device *pdev) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ int ret; -+ -+ ret = sunxi_gmac_power_on(chip); -+ if (ret) { -+ netdev_err(ndev, "Error: Gmac power on failed\n"); -+ ret = -EINVAL; -+ goto power_on_err; -+ } -+ -+ ret = sunxi_gmac_clk_enable(chip); -+ if (ret) { -+ netdev_err(ndev, "Error: Clk enable is failed\n"); -+ ret = -EINVAL; -+ goto clk_enable_err; -+ } -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+ ret = chip->ephy_ops->hardware_init(chip); -+ if (ret) { -+ netdev_err(ndev, "Error: ephy init failed\n"); -+ ret = -EINVAL; -+ goto ephy_init_err; -+ } -+ -+ return 0; -+ -+ephy_init_err: -+ sunxi_gmac_clk_disable(chip); -+#endif /* CONFIG_SUNXI55I_EPHY */ -+clk_enable_err: -+ sunxi_gmac_power_off(chip); -+power_on_err: -+ return ret; -+} -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+static void sunxi_gmac_ephy_v1_hardware_deinit(struct sunxi_gmac *chip) -+{ -+ pwm_disable(chip->ac300_pwm); -+} -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ -+static void sunxi_gmac_hardware_deinit(struct platform_device *pdev) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ sunxi_gmac_power_off(chip); -+ -+ sunxi_gmac_clk_disable(chip); -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+ chip->ephy_ops->hardware_deinit(chip); -+#endif /* CONFIG_SUNXI55I_EPHY */ -+} -+ -+static void sunxi_gmac_parse_delay_maps(struct sunxi_gmac *chip) -+{ -+ struct platform_device *pdev = to_platform_device(chip->dev); -+ struct device_node *np = pdev->dev.of_node; -+ int ret, maps_cnt; -+ u32 *maps; -+ -+ maps_cnt = of_property_count_elems_of_size(np, "delay-maps", sizeof(u32)); -+ if (maps_cnt <= 0) { -+ dev_info(&pdev->dev, "Info: not found delay-maps in dts\n"); -+ return; -+ } -+ -+ maps = devm_kcalloc(&pdev->dev, maps_cnt, sizeof(u32), GFP_KERNEL); -+ if (!maps) -+ return; -+ -+ ret = of_property_read_u32_array(np, "delay-maps", maps, maps_cnt); -+ if (ret) { -+ dev_err(&pdev->dev, "Error: failed to parse delay-maps\n"); -+ goto err_parse_maps; -+ } -+/* todo -+ const u8 array_size = 3; -+ u16 soc_ver; -+ int i; -+ -+ soc_ver = (u16)sunxi_get_soc_ver(); -+ for (i = 0; i < (maps_cnt / array_size); i++) { -+ if (soc_ver == maps[i * array_size]) { -+ chip->rx_delay = maps[i * array_size + 1]; -+ chip->tx_delay = maps[i * array_size + 2]; -+ dev_info(&pdev->dev, "Info: delay-maps overwrite delay parameters, rx-delay:%d, tx-delay:%d\n", -+ chip->rx_delay, chip->tx_delay); -+ } -+ } -+*/ -+err_parse_maps: -+ devm_kfree(&pdev->dev, maps); -+} -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+static int sunxi_gmac_ephy_v1_resource_get(struct platform_device *pdev) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ struct device_node *np = pdev->dev.of_node; -+ int ret; -+ -+ ret = of_property_read_u32(np, "sunxi,pwm-channel", &chip->pwm_channel); -+ if (ret) { -+ dev_err(&pdev->dev, "Error: Get ac300 pwm failed\n"); -+ return -EINVAL; -+ } -+ -+ chip->ac300_pwm = pwm_request(chip->pwm_channel, NULL); -+ if (IS_ERR_OR_NULL(chip->ac300_pwm)) { -+ dev_err(&pdev->dev, "Error: Get ac300 pwm failed\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ -+static int sunxi_gmac_resource_get(struct platform_device *pdev) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ struct device_node *np = pdev->dev.of_node; -+ struct resource *res; -+ struct cpumask mask; -+ int cpu; -+ phy_interface_t phy_mode; -+ -+ int ret; -+ -+ /* External phy is selected by default */ -+ chip->phy_type = SUNXI_EXTERNAL_PHY; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "Error: Get gmac memory failed\n"); -+ return -ENODEV; -+ } -+ -+ chip->base = devm_ioremap_resource(&pdev->dev, res); -+ if (!chip->base) { -+ dev_err(&pdev->dev, "Error: Gmac memory mapping failed\n"); -+ return -ENOMEM; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (!res) { -+ dev_err(&pdev->dev, "Error: Get phy memory failed\n"); -+ return -ENODEV; -+ } -+ -+ chip->syscfg_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); -+ if (!chip->syscfg_base) { -+ dev_err(&pdev->dev, "Error: Phy memory mapping failed\n"); -+ return -ENOMEM; -+ } -+ -+ ndev->irq = platform_get_irq_byname(pdev, "gmacirq"); -+ if (ndev->irq < 0) { -+ dev_err(&pdev->dev, "Error: Gmac irq not found\n"); -+ return -ENXIO; -+ } -+ -+ ret = devm_request_irq(&pdev->dev, ndev->irq, sunxi_gmac_interrupt, IRQF_SHARED, dev_name(&pdev->dev), ndev); -+ if (ret) { -+ dev_err(&pdev->dev, "Error: Could not request irq %d\n", ndev->irq); -+ return -EINVAL; -+ } -+ -+ ret = of_property_read_u32(np, "irq-affinity", &chip->irq_affinity); -+ if (ret) { -+ dev_dbg(&pdev->dev, "Info: Get irq-affinity failed, use default\n"); -+ } else { -+ for_each_online_cpu(cpu) { -+ if (chip->irq_affinity & BIT(cpu)) -+ cpumask_set_cpu(cpu, &mask); -+ } -+ irq_set_affinity(ndev->irq, &mask); -+ dev_info(&pdev->dev, "Info: Set irq affinity to cpu%d\n", cpumask_first(&mask)); -+ } -+ -+ chip->reset = devm_reset_control_get(&pdev->dev, NULL); -+ if (IS_ERR(chip->reset)) { -+ dev_err(&pdev->dev, "Error: Get gmac rst failed\n"); -+ return -EINVAL; -+ } -+ -+ chip->pinctrl = devm_pinctrl_get(&pdev->dev); -+ if (IS_ERR(chip->pinctrl)) { -+ dev_err(&pdev->dev, "Error: Get Pin failed\n"); -+ return -EIO; -+ } -+ -+ chip->gmac_clk = devm_clk_get(&pdev->dev, "gmac"); -+ if (!chip->gmac_clk) { -+ dev_err(&pdev->dev, "Error: Get gmac clock failed\n"); -+ return -EINVAL; -+ } -+ -+ ret = of_get_phy_mode(np, &phy_mode); -+ if (!ret) { -+ chip->phy_interface = phy_mode; -+ if (chip->phy_interface != PHY_INTERFACE_MODE_RGMII && -+ chip->phy_interface != PHY_INTERFACE_MODE_RMII && -+ chip->phy_interface != PHY_INTERFACE_MODE_MII) { -+ dev_err(&pdev->dev, "Error: Get gmac phy interface failed\n"); -+ return -EINVAL; -+ } -+ } -+ -+ ret = of_property_read_u32(np, "tx-delay", &chip->tx_delay); -+ if (ret) { -+ dev_warn(&pdev->dev, "Warning: Get gmac tx-delay failed, use default 0\n"); -+ chip->tx_delay = 0; -+ } -+ -+ if (user_tx_delay >= 0 && user_tx_delay <= 7) { -+ chip->tx_delay = user_tx_delay; -+ dev_info(&pdev->dev, "Info: user tx-delay: %d\n", chip->tx_delay); -+ } else { -+ dev_info(&pdev->dev, "Info: dts tx-delay: %d\n", chip->tx_delay); -+ } -+ -+ ret = of_property_read_u32(np, "rx-delay", &chip->rx_delay); -+ if (ret) { -+ dev_warn(&pdev->dev, "Warning: Get gmac rx-delay failed, use default 0\n"); -+ chip->rx_delay = 0; -+ } -+ -+ if (user_rx_delay >= 0 && user_rx_delay <= 31) { -+ chip->rx_delay = user_rx_delay; -+ dev_info(&pdev->dev, "Info: user rx-delay: %d\n", chip->rx_delay); -+ } else { -+ dev_info(&pdev->dev, "Info: dts rx-delay: %d\n", chip->rx_delay); -+ } -+ -+ sunxi_gmac_parse_delay_maps(chip); -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+ chip->ac300_np = of_parse_phandle(np, "ac300-phy-handle", 0); -+ if (!chip->ac300_np) { -+ dev_err(&pdev->dev, "Error: Get gmac ac300-phy-handle failed\n"); -+ return -EINVAL; -+ } -+ -+ ret = chip->ephy_ops->resource_get(pdev); -+ if (ret) -+ return -EINVAL; -+ -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ -+ chip->phy_node = of_parse_phandle(np, "phy-handle", 0); -+ if (!chip->phy_node) { -+ dev_err(&pdev->dev, "Error: Get gmac phy-handle failed\n"); -+ return -EINVAL; -+ } -+ -+ ret = of_property_read_u32(np, "sunxi,phy-clk-type", &chip->phy_clk_type); -+ if (ret) { -+ dev_warn(&pdev->dev, "Warning: Get gmac phy-clk-type failed, use default OSC or pwm\n"); -+ chip->phy_clk_type = SUNXI_PHY_USE_EXT_OSC; -+ }; -+ -+ if (chip->phy_clk_type == SUNXI_PHY_USE_CLK25M) { -+ chip->phy25m_clk = devm_clk_get(&pdev->dev, "phy25m"); -+ if (IS_ERR_OR_NULL(chip->phy25m_clk)) { -+ dev_err(&pdev->dev, "Error: Get phy25m clk failed\n"); -+ return -EINVAL; -+ } -+ } -+ -+ chip->gmac_supply = devm_regulator_get_optional(&pdev->dev, "gmac3v3"); -+ if (IS_ERR(chip->gmac_supply)) -+ netdev_err(ndev, "Error: Not found gmac3v3-supply\n"); -+ -+ /* -+ * Read mac-address from dts, -+ * it doesn't matter if it's missing -+ */ -+ of_get_ethdev_address(np, ndev); -+ -+ return 0; -+} -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+static void sunxi_gmac_ephy_v1_resource_put(struct platform_device *pdev) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ pwm_free(chip->ac300_pwm); -+} -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ -+static void sunxi_gmac_resource_put(struct platform_device *pdev) -+{ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+ chip->ephy_ops->resource_put(pdev); -+#endif /* CONFIG_SUNXI55I_EPHY */ -+} -+ -+static void sunxi_gmac_sysfs_create(struct device *dev) -+{ -+ device_create_file(dev, &dev_attr_gphy_test); -+ device_create_file(dev, &dev_attr_mii_read); -+ device_create_file(dev, &dev_attr_mii_write); -+ device_create_file(dev, &dev_attr_loopback); -+ device_create_file(dev, &dev_attr_tx_delay); -+ device_create_file(dev, &dev_attr_rx_delay); -+ device_create_file(dev, &dev_attr_extra_tx_stats); -+ device_create_file(dev, &dev_attr_extra_rx_stats); -+} -+ -+static void sunxi_gmac_sysfs_destroy(struct device *dev) -+{ -+ device_remove_file(dev, &dev_attr_gphy_test); -+ device_remove_file(dev, &dev_attr_mii_read); -+ device_remove_file(dev, &dev_attr_mii_write); -+ device_remove_file(dev, &dev_attr_loopback); -+ device_remove_file(dev, &dev_attr_tx_delay); -+ device_remove_file(dev, &dev_attr_rx_delay); -+ device_remove_file(dev, &dev_attr_extra_tx_stats); -+ device_remove_file(dev, &dev_attr_extra_rx_stats); -+} -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_GMAC_METADATA) -+ -+#define GMAC_WRITE _IOWR('X', 1, unsigned int) -+#define GMAC_READ _IOWR('X', 2, unsigned int) -+ -+static int sunxi_gmac_fops_open(struct inode *inode, struct file *file) -+{ -+ struct miscdevice *mdev = file->private_data; -+ struct sunxi_gmac *chip = container_of(mdev, struct sunxi_gmac, mdev); -+ -+ file->private_data = chip; -+ -+ return 0; -+} -+ -+static int sunxi_gmac_fops_release(struct inode *inode, struct file *file) -+{ -+ return 0; -+} -+ -+static struct sk_buff *sunxi_gmac_skb_compose(struct sunxi_gmac *chip) -+{ -+ struct sk_buff *skb; -+ u8 *skb_data, *data = chip->metadata_buff; -+ u32 len = chip->ndev->mtu; -+ const u8 markbits = 4; -+ -+ skb = alloc_skb(len, GFP_KERNEL); -+ if (!skb) -+ return NULL; -+ -+ skb_data = __skb_put(skb, len); -+ -+ /* -+ * compose broadcast skb -+ * dest mac : FF-FF-FF-FF-FF-FF -+ * src mac : FE-FF-FF-FF-FF-FF -+ * protocal : 08-00 -+ * metadata mark: AA-AA-AA-AA -+ * */ -+ memset(skb_data, 0, len); -+ memset(skb_data, 0xFF, 2 * ETH_ALEN); -+ skb_data[ETH_ALEN] = 0xFE; -+ skb_data[2 * ETH_ALEN] = 0x08; -+ skb_data[2 * ETH_ALEN + 1] = 0x0; -+ skb_data = skb_data + (2 * ETH_ALEN + 2); -+ memset(skb_data, 0xAA, markbits); -+ -+ skb_data = skb_data + markbits; -+ memcpy(skb_data, data, len); -+ -+ skb->queue_mapping = 0; -+ skb->ip_summed = CHECKSUM_NONE; -+ skb->dev = chip->ndev; -+ -+ return skb; -+} -+ -+static long sunxi_gmac_fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ struct sunxi_gmac *chip = file->private_data; -+ struct sk_buff *skb; -+ int ret; -+ -+ memset(chip->metadata_buff, 0, chip->metadata_len); -+ switch (cmd) { -+ case GMAC_WRITE: -+ ret = copy_from_user(chip->metadata_buff, (void __user *)arg, chip->metadata_len); -+ if (ret) { -+ dev_err(chip->dev, "metadata copy from user err\n"); -+ return -EFAULT; -+ } -+ -+ skb = sunxi_gmac_skb_compose(chip); -+ if (!skb) -+ return -ENOMEM; -+ -+ if (sunxi_gmac_xmit(skb, skb->dev)) -+ return -EBUSY; -+ -+ break; -+ case GMAC_READ: -+ wait_for_completion(&chip->metadata_done); -+ -+ ret = copy_to_user((void __user *)arg, chip->metadata_buff, chip->metadata_len); -+ if (ret) { -+ dev_err(chip->dev, "metadata copy to user err\n"); -+ return -EFAULT; -+ } -+ break; -+ default: -+ ret = -EFAULT; -+ dev_err(chip->dev, "Unspported cmd\n"); -+ break; -+ } -+ -+ return ret; -+} -+ -+struct file_operations sunxi_gmac_fops = { -+ .owner = THIS_MODULE, -+ .open = sunxi_gmac_fops_open, -+ .release = sunxi_gmac_fops_release, -+ .unlocked_ioctl = sunxi_gmac_fops_ioctl, -+}; -+ -+static int sunxi_gmac_fops_init(struct sunxi_gmac *chip) -+{ -+ chip->mdev.parent = chip->dev; -+ chip->mdev.minor = MISC_DYNAMIC_MINOR; -+ chip->mdev.name = "gmac"; -+ chip->mdev.fops = &sunxi_gmac_fops; -+ -+ /* MTU includes 4 bytes of mark, so the maximum metadata is MTU - 4 bytes in length */ -+ chip->metadata_len = chip->ndev->mtu - 4; -+ -+ chip->metadata_buff = devm_kzalloc(chip->dev, (sizeof(char) * chip->metadata_len), GFP_KERNEL); -+ if (!chip->metadata_buff) -+ return -ENOMEM; -+ -+ init_completion(&chip->metadata_done); -+ -+ return misc_register(&chip->mdev); -+} -+ -+static void sunxi_gmac_fops_exit(struct sunxi_gmac *chip) -+{ -+ kfree(chip->metadata_buff); -+ misc_deregister(&chip->mdev); -+} -+ -+#endif /* CONFIG_SUNXI55I_GMAC_METADATA */ -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+static struct sunxi_gmac_ephy_ops sunxi_gmac_ephy_ops_v1 = { -+ .resource_get = sunxi_gmac_ephy_v1_resource_get, -+ .resource_put = sunxi_gmac_ephy_v1_resource_put, -+ .hardware_init = sunxi_gmac_ephy_v1_hardware_init, -+ .hardware_deinit = sunxi_gmac_ephy_v1_hardware_deinit, -+}; -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ -+static const struct of_device_id sunxi_gmac_of_match[] = { -+ {.compatible = "allwinner,sunxi-gmac",}, -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+ {.compatible = "allwinner,sunxi-gmac-ephy-v1", .data = &sunxi_gmac_ephy_ops_v1, }, -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, sunxi_gmac_of_match); -+ -+/** -+ * sunxi_gmac_probe - GMAC device probe -+ * @pdev: The SUNXI GMAC device that we are removing -+ * -+ * Called when probing for GMAC device. We get details of instances and -+ * resource information from platform init and register a network device -+ * and allocate resources necessary for driver to perform -+ * -+ */ -+static int sunxi_gmac_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct net_device *ndev; -+ struct sunxi_gmac *chip; -+ const struct of_device_id *match; -+ -+ dev_dbg(&pdev->dev, "%s() BEGIN\n", __func__); -+ -+ match = of_match_device(sunxi_gmac_of_match, &pdev->dev); -+ if (!match) { -+ dev_err(&pdev->dev, "gmac probe match device failed\n"); -+ return -EINVAL; -+ } -+ -+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); -+ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -+ -+ ndev = alloc_etherdev(sizeof(*chip)); -+ if (!ndev) { -+ dev_err(&pdev->dev, "Error: Allocate network device failed\n"); -+ ret = -ENOMEM; -+ goto alloc_etherdev_err; -+ } -+ SET_NETDEV_DEV(ndev, &pdev->dev); -+ -+ chip = netdev_priv(ndev); -+ platform_set_drvdata(pdev, ndev); -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+ chip->ephy_ops = (struct sunxi_gmac_ephy_ops *)match->data; -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ chip->ndev = ndev; -+ chip->dev = &pdev->dev; -+ ret = sunxi_gmac_resource_get(pdev); -+ if (ret) { -+ dev_err(&pdev->dev, "Error: Get gmac hardware resource failed\n"); -+ goto resource_get_err; -+ } -+ -+ ret = sunxi_gmac_hardware_init(pdev); -+ if (ret) { -+ dev_err(&pdev->dev, "Error: Init gmac hardware resource failed\n"); -+ goto hardware_init_err; -+ } -+ -+ /* -+ * setup the netdevice -+ * fillup netdevice base memory and ops -+ * fillup netdevice ethtool ops -+ */ -+ ether_setup(ndev); -+ ndev->netdev_ops = &sunxi_gmac_netdev_ops; -+ netdev_set_default_ethtool_ops(ndev, &sunxi_gmac_ethtool_ops); -+ ndev->base_addr = (unsigned long)chip->base; -+ -+ /* fillup netdevice features and flags */ -+ ndev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | -+ NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_GRO; -+ ndev->features |= ndev->hw_features; -+ ndev->hw_features |= NETIF_F_LOOPBACK; -+ ndev->priv_flags |= IFF_UNICAST_FLT; -+ ndev->watchdog_timeo = msecs_to_jiffies(watchdog); -+ ndev->max_mtu = SUNXI_GMAC_MAX_MTU_SZ; -+ -+ /* add napi poll method */ -+ netif_napi_add(ndev, &chip->napi, sunxi_gmac_poll); -+ -+ spin_lock_init(&chip->universal_lock); -+ spin_lock_init(&chip->tx_lock); -+ -+ ret = register_netdev(ndev); -+ if (ret) { -+ dev_err(&pdev->dev, "Error: Register %s failed\n", ndev->name); -+ goto register_err; -+ } -+ -+//todo #ifdef MODULE -+// get_custom_mac_address(0, "eth", mac_str); -+//#endif -+ /* Before open the device, the mac address should be set */ -+ sunxi_gmac_check_addr(ndev, mac_str); -+ -+ memcpy(ndev->dev_addr_shadow, ndev->dev_addr, 18); -+ -+ ret = sunxi_gmac_dma_desc_init(ndev); -+ if (ret) { -+ dev_err(&pdev->dev, "Error: Init dma descriptor failed\n"); -+ goto init_dma_desc_err; -+ } -+ -+ sunxi_gmac_sysfs_create(&pdev->dev); -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_GMAC_METADATA) -+ ret = sunxi_gmac_fops_init(chip); -+ if (ret) { -+ dev_err(&pdev->dev, "Error: Init gmac class failed\n"); -+ goto fops_init_err; -+ } -+#endif -+ -+ dev_dbg(&pdev->dev, "%s() SUCCESS\n", __func__); -+ -+ return 0; -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_GMAC_METADATA) -+fops_init_err: -+ sunxi_gmac_sysfs_destroy(&pdev->dev); -+#endif -+init_dma_desc_err: -+ unregister_netdev(ndev); -+register_err: -+ netif_napi_del(&chip->napi); -+ sunxi_gmac_hardware_deinit(pdev); -+hardware_init_err: -+ sunxi_gmac_resource_put(pdev); -+resource_get_err: -+ platform_set_drvdata(pdev, NULL); -+ free_netdev(ndev); -+alloc_etherdev_err: -+ return ret; -+} -+ -+static void sunxi_gmac_remove(struct platform_device *pdev) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct sunxi_gmac *chip = netdev_priv(ndev); -+ -+#if IS_ENABLED(CONFIG_SUNXI55I_GMAC_METADATA) -+ sunxi_gmac_fops_exit(chip); -+#endif -+ sunxi_gmac_sysfs_destroy(&pdev->dev); -+ sunxi_gmac_dma_desc_deinit(chip); -+ unregister_netdev(ndev); -+ netif_napi_del(&chip->napi); -+ sunxi_gmac_hardware_deinit(pdev); -+ sunxi_gmac_resource_put(pdev); -+ platform_set_drvdata(pdev, NULL); -+ free_netdev(ndev); -+} -+ -+static struct platform_driver sunxi_gmac_driver = { -+ .probe = sunxi_gmac_probe, -+ .remove = sunxi_gmac_remove, -+#if IS_ENABLED(CONFIG_SUNXI55I_EPHY) -+ .shutdown = sunxi_gmac_shutdown, -+#endif /* CONFIG_SUNXI55I_EPHY */ -+ .driver = { -+ .name = "sunxi-gmac", -+ .owner = THIS_MODULE, -+ .pm = &sunxi_gmac_pm_ops, -+ .of_match_table = sunxi_gmac_of_match, -+ }, -+}; -+module_platform_driver(sunxi_gmac_driver); -+ -+#ifndef MODULE -+static int __init sunxi_gmac_set_mac_addr(char *str) -+{ -+ char *p = str; -+ -+ /** -+ * mac address: xx:xx:xx:xx:xx:xx -+ * The reason why memcpy 18 bytes is -+ * the `/0`. -+ */ -+ if (str && strlen(str)) -+ memcpy(mac_str, p, MAC_ADDR_LEN); -+ -+ return 0; -+} -+/* TODO: When used more than one mac, -+ * parsing the mac address becomes a problem. -+ * Maybe use this way: mac0_addr=, mac1_addr= -+ */ -+__setup("mac0_addr=", sunxi_gmac_set_mac_addr); -+#endif /* MODULE */ -+ -+MODULE_DESCRIPTION("Allwinner GMAC driver"); -+MODULE_AUTHOR("xuminghui "); -+MODULE_AUTHOR("Piotr Oniszczuk "); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_VERSION(SUNXI_GMAC_MODULE_VERSION); -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-mdio.c linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-mdio.c ---- linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-mdio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/gmac/sunxi-mdio.c 2024-12-11 14:37:13.080084379 +0100 -@@ -0,0 +1,434 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* Copyright(c) 2020 - 2023 Allwinner Technology Co.,Ltd. All rights reserved. */ -+/* -+ * Allwinner GMAC MDIO interface driver -+ * -+ * Copyright 2022 Allwinnertech -+ * -+ * 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. -+ */ -+ -+/* #define DEBUG */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define SUNXI_MDIO_CONFIG 0x0 -+#define SUNXI_MDIO_DATA 0x4 -+ -+#define SUNXI_MDIO_BUSY 0x00000001 -+#define SUNXI_MDIO_WRITE 0x00000002 -+#define SUNXI_MDIO_PHY_MASK 0x0000FFC0 -+#define SUNXI_MDIO_CR_MASK 0x0000001 -+#define SUNXI_MDIO_CLK 0x00000008 -+#define SUNXI_MDIO_MDC_DIV 0x3 -+ -+/* bits 4 3 2 | AHB1 Clock | MDC Clock -+ * ------------------------------------------------------- -+ * 0 0 0 | 60 ~ 100 MHz | div-42 -+ * 0 0 1 | 100 ~ 150 MHz | div-62 -+ * 0 1 0 | 20 ~ 35 MHz | div-16 -+ * 0 1 1 | 35 ~ 60 MHz | div-26 -+ * 1 0 0 | 150 ~ 250 MHz | div-102 -+ * 1 0 1 | 250 ~ 300 MHz | div-124 -+ * 1 1 x | Reserved | -+ */ -+#define SUNXI_MDIO_MDC_DIV_RATIO_M 0x07 -+#define SUNXI_MDIO_MDC_DIV_RATIO_M_BIT 20 -+#define SUNXI_MDIO_PHY_ADDR 0x0001F000 -+#define SUNXI_MDIO_PHY_ADDR_OFFSET 12 -+#define SUNXI_MDIO_PHY_REG 0x000007F0 -+#define SUNXI_MDIO_PHY_REG_OFFSET 4 -+#define SUNXI_MDIO_RESET 0x4 -+#define SUNXI_MDIO_RESET_OFFSET 2 -+ -+#define SUNXI_MDIO_WR_TIMEOUT 10 /* ms */ -+ -+struct mii_reg_dump { -+ u32 addr; -+ u16 reg; -+ u16 value; -+}; -+ -+struct sunxi_mdio { -+ struct device *dev; -+ void __iomem *base; -+}; -+ -+struct mii_reg_dump mii_reg; -+/** -+ * sunxi_parse_read_str - parse the input string for write attri. -+ * @str: string to be parsed, eg: "0x00 0x01". -+ * @addr: store the reg address. eg: 0x00. -+ * @reg: store the expect value. eg: 0x01. -+ * -+ * return 0 if success, otherwise failed. -+ */ -+static int sunxi_parse_read_str(char *str, u16 *addr, u16 *reg) -+{ -+ char *ptr = str; -+ char *tstr = NULL; -+ int ret; -+ -+ /* -+ * Skip the leading whitespace, find the true split symbol. -+ * And it must be 'address value'. -+ */ -+ tstr = strim(str); -+ ptr = strchr(tstr, ' '); -+ if (!ptr) -+ return -EINVAL; -+ -+ /* -+ * Replaced split symbol with a %NUL-terminator temporary. -+ * Will be fixed at end. -+ */ -+ *ptr = '\0'; -+ ret = kstrtos16(tstr, 16, addr); -+ if (ret) -+ goto out; -+ -+ ret = kstrtos16(skip_spaces(ptr + 1), 16, reg); -+ -+out: -+ return ret; -+} -+ -+/** -+ * sunxi_parse_write_str - parse the input string for compare attri. -+ * @str: string to be parsed, eg: "0x00 0x11 0x11". -+ * @addr: store the address. eg: 0x00. -+ * @reg: store the reg. eg: 0x11. -+ * @val: store the value. eg: 0x11. -+ * -+ * return 0 if success, otherwise failed. -+ */ -+static int sunxi_parse_write_str(char *str, u16 *addr, -+ u16 *reg, u16 *val) -+{ -+ u16 result_addr[3] = { 0 }; -+ char *ptr = str; -+ char *ptr2 = NULL; -+ int i, ret = 0; -+ -+ for (i = 0; i < ARRAY_SIZE(result_addr); i++) { -+ ptr = skip_spaces(ptr); -+ ptr2 = strchr(ptr, ' '); -+ if (ptr2) -+ *ptr2 = '\0'; -+ -+ ret = kstrtou16(ptr, 16, &result_addr[i]); -+ -+ if (!ptr2 || ret) -+ break; -+ -+ ptr = ptr2 + 1; -+ } -+ -+ *addr = result_addr[0]; -+ *reg = result_addr[1]; -+ *val = result_addr[2]; -+ -+ return ret; -+} -+ -+/* -+ * Wait until any existing MII operation is complete -+ * Read 0 indicate finish in read or write operation -+ * Read 1 indicate busy -+ * */ -+static void sunxi_mdio_busy_wait(struct sunxi_mdio *chip) -+{ -+ unsigned long timeout = jiffies + msecs_to_jiffies(SUNXI_MDIO_WR_TIMEOUT); -+ u32 reg; -+ -+ do { -+ reg = readl(chip->base + SUNXI_MDIO_CONFIG); -+ -+ if ((reg & SUNXI_MDIO_BUSY) != 1) -+ break; -+ -+ } while (time_before(jiffies, timeout)); -+} -+ -+/** -+ * sunxi_mdio_read - GMAC MII bus read func -+ * @bus: mii bus struct -+ * @phyaddr: phy address -+ * @phyreg: phy register -+ * -+ * Called when phy_write is used. -+ * -+ * Returns reg value for specific phy register. -+ */ -+static int sunxi_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) -+{ -+ unsigned int value = 0; -+ struct sunxi_mdio *chip = bus->priv; -+ -+ /* Mask the MDC_DIV_RATIO */ -+ value |= ((SUNXI_MDIO_MDC_DIV & SUNXI_MDIO_MDC_DIV_RATIO_M) << SUNXI_MDIO_MDC_DIV_RATIO_M_BIT); -+ value |= (((phyaddr << SUNXI_MDIO_PHY_ADDR_OFFSET) & (SUNXI_MDIO_PHY_ADDR)) | -+ ((phyreg << SUNXI_MDIO_PHY_REG_OFFSET) & (SUNXI_MDIO_PHY_REG)) | -+ SUNXI_MDIO_BUSY); -+ -+ writel(value, chip->base + SUNXI_MDIO_CONFIG); -+ -+ sunxi_mdio_busy_wait(chip); -+ -+ return (int)readl(chip->base + SUNXI_MDIO_DATA); -+} -+ -+/** -+ * sunxi_mdio_write - GMAC MII bus write func -+ * @bus: mii bus struct -+ * @phyaddr: phy address -+ * @phyreg: phy register -+ * @data: the value to be written to the register -+ * -+ * Called when phy_wirte is used. -+ * -+ * Returns 0 for a successful open, or appropriate error code -+ */ -+static int sunxi_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, unsigned short data) -+{ -+ unsigned int value; -+ struct sunxi_mdio *chip = bus->priv; -+ -+ value = ((SUNXI_MDIO_MDC_DIV_RATIO_M << SUNXI_MDIO_MDC_DIV_RATIO_M_BIT) & readl(chip->base+ SUNXI_MDIO_CONFIG)) | -+ (SUNXI_MDIO_MDC_DIV << SUNXI_MDIO_MDC_DIV_RATIO_M_BIT); -+ value |= (((phyaddr << SUNXI_MDIO_PHY_ADDR_OFFSET) & (SUNXI_MDIO_PHY_ADDR)) | -+ ((phyreg << SUNXI_MDIO_PHY_REG_OFFSET) & (SUNXI_MDIO_PHY_REG))) | -+ SUNXI_MDIO_WRITE | SUNXI_MDIO_BUSY; -+ -+ sunxi_mdio_busy_wait(chip); -+ -+ /* Set the MII address register to write */ -+ writel(data, chip->base + SUNXI_MDIO_DATA); -+ writel(value, chip->base + SUNXI_MDIO_CONFIG); -+ -+ sunxi_mdio_busy_wait(chip); -+ -+ return 0; -+} -+ -+static int sunxi_mdio_reset(struct mii_bus *bus) -+{ -+ struct sunxi_mdio *chip = bus->priv; -+ -+ writel((SUNXI_MDIO_RESET << SUNXI_MDIO_RESET_OFFSET), chip->base + SUNXI_MDIO_CONFIG); -+ -+ sunxi_mdio_busy_wait(chip); -+ return 0; -+} -+ -+static ssize_t sunxi_mdio_read_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct mii_bus *bus = platform_get_drvdata(pdev); -+ -+ mii_reg.value = sunxi_mdio_read(bus, mii_reg.addr, mii_reg.reg); -+ return sprintf(buf, "ADDR[0x%02x]:REG[0x%02x] = 0x%04x\n", -+ mii_reg.addr, mii_reg.reg, mii_reg.value); -+} -+ -+static ssize_t sunxi_mdio_read_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ int ret = 0; -+ u16 reg, addr; -+ char *ptr; -+ -+ ptr = (char *)buf; -+ -+ if (!dev) { -+ pr_err("Argment is invalid\n"); -+ return count; -+ } -+ -+ ret = sunxi_parse_read_str(ptr, &addr, ®); -+ if (ret) -+ return ret; -+ -+ mii_reg.addr = addr; -+ mii_reg.reg = reg; -+ -+ return count; -+} -+ -+static ssize_t sunxi_mdio_write_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct mii_bus *bus = platform_get_drvdata(pdev); -+ u16 bef_val, aft_val; -+ -+ bef_val = sunxi_mdio_read(bus, mii_reg.addr, mii_reg.reg); -+ sunxi_mdio_write(bus, mii_reg.addr, mii_reg.reg, mii_reg.value); -+ aft_val = sunxi_mdio_read(bus, mii_reg.addr, mii_reg.reg); -+ return sprintf(buf, "before ADDR[0x%02x]:REG[0x%02x] = 0x%04x\n" -+ "after ADDR[0x%02x]:REG[0x%02x] = 0x%04x\n", -+ mii_reg.addr, mii_reg.reg, bef_val, -+ mii_reg.addr, mii_reg.reg, aft_val); -+} -+ -+static ssize_t sunxi_mdio_write_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ int ret = 0; -+ u16 reg, addr, val; -+ char *ptr; -+ -+ ptr = (char *)buf; -+ -+ ret = sunxi_parse_write_str(ptr, &addr, ®, &val); -+ if (ret) -+ return ret; -+ -+ mii_reg.reg = reg; -+ mii_reg.addr = addr; -+ mii_reg.value = val; -+ -+ return count; -+} -+ -+static DEVICE_ATTR(mii_read, 0664, sunxi_mdio_read_show, sunxi_mdio_read_store); -+static DEVICE_ATTR(mii_write, 0664, sunxi_mdio_write_show, sunxi_mdio_write_store); -+ -+static void sunxi_mdio_sysfs_create(struct device *dev) -+{ -+ device_create_file(dev, &dev_attr_mii_read); -+ device_create_file(dev, &dev_attr_mii_write); -+} -+ -+static void sunxi_mdio_sysfs_destroy(struct device *dev) -+{ -+ device_remove_file(dev, &dev_attr_mii_read); -+ device_remove_file(dev, &dev_attr_mii_write); -+} -+/** -+ * sunxi_mdio_probe - GMAC MII bus probe func -+ * -+ * sunxi mdio probe must run after sunxi emac probe, -+ * because mdio clk was enabled in emac driver. -+ */ -+static int sunxi_mdio_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct device *dev = &pdev->dev; -+ struct mii_bus *bus; -+ struct sunxi_mdio *chip; -+ int ret; -+#ifdef DEBUG -+ struct phy_device *phy; -+ int addr; -+#endif -+ -+ dev_dbg(dev, "%s() BEGIN\n", __func__); -+ -+ chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); -+ if (!chip) -+ return -ENOMEM; -+ -+ bus = mdiobus_alloc_size(sizeof(*bus)); -+ if (!bus) { -+ dev_err(dev, "Error: alloc mii bus failed\n"); -+ return -ENOMEM; -+ } -+ -+ bus->name = dev_name(dev); -+ bus->read = sunxi_mdio_read; -+ bus->write = sunxi_mdio_write; -+ bus->reset = sunxi_mdio_reset; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(&pdev->dev)); -+ bus->parent = &pdev->dev; -+ bus->priv = chip; -+ -+ chip->dev = dev; -+ chip->base = of_iomap(np, 0); -+ if (IS_ERR(chip->base)) { -+ ret = PTR_ERR(chip->base); -+ goto iomap_err; -+ } -+ -+ ret = of_mdiobus_register(bus, np); -+ if (ret < 0) -+ goto mdio_register_err; -+ -+ platform_set_drvdata(pdev, bus); -+ -+ sunxi_mdio_sysfs_create(dev); -+ -+#ifdef DEBUG -+ /* scan and dump the bus */ -+ for (addr = 0; addr < PHY_MAX_ADDR; addr++) { -+ phy = mdiobus_get_phy(bus, addr); -+ if (phy) -+ dev_info(dev, "PHY ID: 0x%08x, ADDR: 0x%x, DEVICE: %s, DRIVER: %s\n", -+ phy->phy_id, addr, phydev_name(phy), -+ phy->drv ? phy->drv->name : "Generic PHY"); -+ } -+#endif -+ -+ dev_dbg(dev, "%s() SUCCESS\n", __func__); -+ return 0; -+ -+mdio_register_err: -+ iounmap(chip->base); -+iomap_err: -+ mdiobus_free(bus); -+ return ret; -+} -+ -+static void sunxi_mdio_remove(struct platform_device *pdev) -+{ -+ struct mii_bus *bus = platform_get_drvdata(pdev); -+ struct device *dev = &pdev->dev; -+ struct sunxi_mdio *chip = bus->priv; -+ -+ sunxi_mdio_sysfs_destroy(dev); -+ mdiobus_unregister(bus); -+ iounmap(chip->base); -+ mdiobus_free(bus); -+} -+ -+static const struct of_device_id sunxi_mdio_dt_ids[] = { -+ { .compatible = "allwinner,sunxi-mdio" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, sunxi_mdio_dt_ids); -+ -+static struct platform_driver sunxi_mdio_driver = { -+ .probe = sunxi_mdio_probe, -+ .remove = sunxi_mdio_remove, -+ .driver = { -+ .name = "sunxi-mdio", -+ .of_match_table = sunxi_mdio_dt_ids, -+ }, -+}; -+ -+static int __init sunxi_mdio_init(void) -+{ -+ return platform_driver_register(&sunxi_mdio_driver); -+} -+late_initcall(sunxi_mdio_init); -+ -+static void __exit sunxi_mdio_exit(void) -+{ -+ platform_driver_unregister(&sunxi_mdio_driver); -+} -+module_exit(sunxi_mdio_exit); -+ -+MODULE_DESCRIPTION("Allwinner GMAC MDIO interface driver"); -+MODULE_AUTHOR("xuminghui "); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION("1.0.1"); -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/Kconfig linux-6.12.10/drivers/net/ethernet/allwinner/Kconfig ---- linux-6.12.10/drivers/net/ethernet/allwinner/Kconfig 2025-01-23 10:27:54.404056276 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/Kconfig 2025-01-23 09:26:21.877290265 +0100 -@@ -35,5 +35,6 @@ - will be called sun4i-emac. - - source "drivers/net/ethernet/allwinner/gmac-200/Kconfig" -+source "drivers/net/ethernet/allwinner/gmac/Kconfig" - - endif # NET_VENDOR_ALLWINNER -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/drivers/net/ethernet/allwinner/Makefile linux-6.12.10/drivers/net/ethernet/allwinner/Makefile ---- linux-6.12.10/drivers/net/ethernet/allwinner/Makefile 2025-01-23 10:27:54.404056276 +0100 -+++ linux-6.12.10/drivers/net/ethernet/allwinner/Makefile 2025-01-23 09:28:49.753960900 +0100 -@@ -5,3 +5,4 @@ - - obj-$(CONFIG_SUN4I_EMAC) += sun4i-emac.o - obj-$(CONFIG_NET_VENDOR_ALLWINNER) += gmac-200/ -+obj-$(CONFIG_NET_VENDOR_ALLWINNER) += gmac/ diff --git a/patch/kernel/archive/sunxi-dev-6.14/1151-arm64-dtsi-allwinner-add-gmac1-in-A523-dtsi.patch b/patch/kernel/archive/sunxi-dev-6.14/1151-arm64-dtsi-allwinner-add-gmac1-in-A523-dtsi.patch deleted file mode 100644 index 72b2877d9..000000000 --- a/patch/kernel/archive/sunxi-dev-6.14/1151-arm64-dtsi-allwinner-add-gmac1-in-A523-dtsi.patch +++ /dev/null @@ -1,99 +0,0 @@ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.4/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi linux-6.12.4/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi ---- linux-6.12.4/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi 2024-12-17 16:00:39.127051177 +0100 -+++ linux-6.12.4/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi 2024-12-18 12:33:17.756857967 +0100 -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - - / { - interrupt-parent = <&gic>; -@@ -110,6 +112,28 @@ - allwinner,pinmux = <2>; - function = "uart0"; - }; -+ -+ /omit-if-no-ref/ -+ gmac1_pins_default: gmac1@0 { -+ pins = "PJ0", "PJ1", "PJ2", "PJ3", -+ "PJ4", "PJ5", "PJ6", "PJ7", -+ "PJ8", "PJ9", "PJ10", "PJ11", -+ "PJ12","PJ13", "PJ14", "PJ15"; -+ allwinner,pinmux = <5>; -+ function = "gmac1"; -+ drive-strength = <40>; -+ bias-pull-up; -+ }; -+ -+ /omit-if-no-ref/ -+ gmac1_pins_sleep: gmac1@1 { -+ pins = "PJ0", "PJ1", "PJ2", "PJ3", -+ "PJ4", "PJ5", "PJ6", "PJ7", -+ "PJ8", "PJ9", "PJ10", "PJ11", -+ "PJ12","PJ13", "PJ14", "PJ15"; -+ allwinner,pinmux = <0>; -+ function = "gpio_in"; -+ }; - }; - - ccu: clock@2001000 { -@@ -380,5 +404,58 @@ - clock-names = "bus", "hosc", "ahb"; - #clock-cells = <1>; - }; -+ -+ gmac1: ethernet@4510000 { -+ compatible = "allwinner,sunxi-gmac-200", "snps,dwmac-4.20a"; -+ reg = <0x04510000 0x10000>, -+ <0x03000034 0x4>; -+ interrupts = ; -+ interrupt-names = "macirq"; -+ clocks = <&ccu CLK_BUS_EMAC1>, <&ccu CLK_MBUS_EMAC1>, <&ccu CLK_EMAC1_25M>; -+ clock-names = "stmmaceth", "pclk", "phy25m"; -+ resets = <&ccu RST_BUS_EMAC1>; -+ reset-names = "stmmaceth"; -+ phy-handle = <&gmac1_phy0>; -+ //todo power-domains = <&pd1 A523_PCK_VO1>; -+ status = "disabled"; -+ -+ snps,fixed-burst; -+ -+ snps,axi-config = <&gmac1_stmmac_axi_setup>; -+ snps,mtl-rx-config = <&gmac1_mtl_rx_setup>; -+ snps,mtl-tx-config = <&gmac1_mtl_tx_setup>; -+ -+ gmac1_stmmac_axi_setup: stmmac-axi-config { -+ snps,wr_osr_lmt = <0xf>; -+ snps,rd_osr_lmt = <0xf>; -+ snps,blen = <256 128 64 32 16 8 4>; -+ }; -+ -+ gmac1_mtl_rx_setup: rx-queues-config { -+ snps,rx-queues-to-use = <1>; -+ queue0 {}; -+ }; -+ -+ gmac1_mtl_tx_setup: tx_queues-config { -+ snps,tx-queues-to-use = <1>; -+ queue0 {}; -+ }; -+ -+ mdio1: mdio1@1 { -+ compatible = "snps,dwmac-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ gmac1_phy0: ethernet-phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0x1>; -+ max-speed = <1000>; /* Max speed capability */ -+ reset-gpios = <&pio 9 27 GPIO_ACTIVE_LOW>; /* PJ27; 9 is PJ */ -+ /* PHY datasheet rst time */ -+ reset-assert-us = <10000>; -+ reset-deassert-us = <150000>; -+ }; -+ }; -+ }; - }; - }; diff --git a/patch/kernel/archive/sunxi-dev-6.14/1152-arm64-dtsi-allwinner-add-gmac0-in-A523-dtsi.patch b/patch/kernel/archive/sunxi-dev-6.14/1152-arm64-dtsi-allwinner-add-gmac0-in-A523-dtsi.patch deleted file mode 100644 index 48f5b366c..000000000 --- a/patch/kernel/archive/sunxi-dev-6.14/1152-arm64-dtsi-allwinner-add-gmac0-in-A523-dtsi.patch +++ /dev/null @@ -1,69 +0,0 @@ -diff --speed-large-files --no-dereference --minimal -Naur linux-6.12.10/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi linux-6.12.10/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi ---- linux-6.12.10/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi 2025-01-22 15:45:11.961240491 +0100 -+++ linux-6.12.10/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi 2025-01-22 13:16:06.127667018 +0100 -@@ -159,6 +159,28 @@ - allwinner,pinmux = <2>; - function = "uart0"; - }; -+ -+ /omit-if-no-ref/ -+ gmac0_pins_default: gmac0@0 { -+ pins = "PH0", "PH1", "PH2", "PH3", -+ "PH4", "PH5", "PH6", "PH7", -+ "PH9", "PH10","PH13","PH14", -+ "PH15","PH16","PH17","PH18"; -+ allwinner,pinmux = <5>; -+ function = "gmac0"; -+ drive-strength = <40>; -+ bias-pull-up; -+ }; -+ -+ /omit-if-no-ref/ -+ gmac0_pins_sleep: gmac0@1 { -+ pins = "PH0", "PH1", "PH2", "PH3", -+ "PH4", "PH5", "PH6", "PH7", -+ "PH9", "PH10","PH13","PH14", -+ "PH15","PH16","PH17","PH18"; -+ allwinner,pinmux = <0>; -+ function = "gpio_in"; -+ }; - - /omit-if-no-ref/ - gmac1_pins_default: gmac1@0 { -@@ -610,6 +632,36 @@ - #clock-cells = <1>; - }; - -+ mdio0: mdio0@4500048 { -+ compatible = "allwinner,sunxi-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x04500048 0x8>; -+ status = "disabled"; -+ -+ gmac0_phy0: ethernet-phy@1 { -+ reg = <1>; -+ max-speed = <1000>; /* Max speed capability */ -+ reset-gpios = <&pio 7 19 GPIO_ACTIVE_LOW>; /* PH19 */ -+ /* PHY datasheet rst time */ -+ reset-assert-us = <10000>; -+ reset-deassert-us = <150000>; -+ }; -+ }; -+ -+ gmac0: gmac0@4500000 { -+ compatible = "allwinner,sunxi-gmac"; -+ reg = <0x04500000 0x10000>, -+ <0x03000030 0x4>; -+ interrupts = ; -+ interrupt-names = "gmacirq"; -+ clocks = <&ccu CLK_BUS_EMAC0>, <&ccu CLK_EMAC0_25M>; -+ clock-names = "gmac", "phy25m"; -+ resets = <&ccu RST_BUS_EMAC0>; -+ phy-handle = <&gmac0_phy0>; -+ status = "disabled"; -+ }; -+ - gmac1: ethernet@4510000 { - compatible = "allwinner,sunxi-gmac-200", "snps,dwmac-4.20a"; - reg = <0x04510000 0x10000>, diff --git a/patch/kernel/archive/sunxi-dev-6.14/1208-thermal-drivers-sun8i-Add-initial-support-for-A523-T.patch b/patch/kernel/archive/sunxi-dev-6.14/1208-thermal-drivers-sun8i-Add-initial-support-for-A523-T.patch deleted file mode 100644 index 1f16ec907..000000000 --- a/patch/kernel/archive/sunxi-dev-6.14/1208-thermal-drivers-sun8i-Add-initial-support-for-A523-T.patch +++ /dev/null @@ -1,307 +0,0 @@ -From a5476261558ca640f5c414d66f4f7f619796d7b3 Mon Sep 17 00:00:00 2001 -From: iuncuim -Date: Sat, 22 Mar 2025 05:11:02 +0300 -Subject: [PATCH] thermal/drivers/sun8i: Add initial support for A523 THS0/THS1 - controller - -Signed-off-by: Mikhail Kalashnikov ---- - .../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 123 ++++++++++++++++++ - drivers/thermal/sun8i_thermal.c | 51 +++++++- - 2 files changed, 171 insertions(+), 3 deletions(-) - -diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi -index ee485899b..ad3722b5c 100644 ---- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi -@@ -22,6 +22,7 @@ cpu0: cpu@0 { - device_type = "cpu"; - reg = <0x000>; - enable-method = "psci"; -+ #cooling-cells = <2>; - }; - - cpu1: cpu@100 { -@@ -29,6 +30,7 @@ cpu1: cpu@100 { - device_type = "cpu"; - reg = <0x100>; - enable-method = "psci"; -+ #cooling-cells = <2>; - }; - - cpu2: cpu@200 { -@@ -36,6 +38,7 @@ cpu2: cpu@200 { - device_type = "cpu"; - reg = <0x200>; - enable-method = "psci"; -+ #cooling-cells = <2>; - }; - - cpu3: cpu@300 { -@@ -43,6 +46,7 @@ cpu3: cpu@300 { - device_type = "cpu"; - reg = <0x300>; - enable-method = "psci"; -+ #cooling-cells = <2>; - }; - - cpu4: cpu@400 { -@@ -50,6 +54,7 @@ cpu4: cpu@400 { - device_type = "cpu"; - reg = <0x400>; - enable-method = "psci"; -+ #cooling-cells = <2>; - }; - - cpu5: cpu@500 { -@@ -57,6 +62,7 @@ cpu5: cpu@500 { - device_type = "cpu"; - reg = <0x500>; - enable-method = "psci"; -+ #cooling-cells = <2>; - }; - - cpu6: cpu@600 { -@@ -64,6 +70,7 @@ cpu6: cpu@600 { - device_type = "cpu"; - reg = <0x600>; - enable-method = "psci"; -+ #cooling-cells = <2>; - }; - - cpu7: cpu@700 { -@@ -71,6 +78,7 @@ cpu7: cpu@700 { - device_type = "cpu"; - reg = <0x700>; - enable-method = "psci"; -+ #cooling-cells = <2>; - }; - }; - -@@ -171,6 +179,40 @@ ccu: clock-controller@2001000 { - #reset-cells = <1>; - }; - -+ ths1: thermal-sensor@2009400 { -+ compatible = "allwinner,sun55i-a523-ths1"; -+ reg = <0x02009400 0x400>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_GPADC1>; -+ clock-names = "bus", "gpadc"; -+ resets = <&ccu RST_BUS_THS>; -+ nvmem-cells = <&ths_calibration>; -+ nvmem-cell-names = "calibration"; -+ #thermal-sensor-cells = <1>; -+ }; -+ -+ ths0: thermal-sensor@200a000 { -+ compatible = "allwinner,sun55i-a523-ths0"; -+ reg = <0x0200a000 0x400>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_GPADC0>; -+ clock-names = "bus", "gpadc"; -+ nvmem-cells = <&ths_calibration>; -+ nvmem-cell-names = "calibration"; -+ #thermal-sensor-cells = <1>; -+ }; -+ -+ sid: efuse@3006000 { -+ compatible = "allwinner,sun50i-a523-sid", "allwinner,sun50i-a64-sid"; -+ reg = <0x03006000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ /* TODO: we need set proper calibration values */ -+ ths_calibration: thermal-sensor-calibration@38 { -+ reg = <0x38 0x10>; -+ }; -+ }; -+ - mmc0: mmc@4020000 { - compatible = "allwinner,sun55i-a523-mmc", - "allwinner,sun20i-d1-mmc"; -@@ -595,4 +637,85 @@ rtc: rtc@7090000 { - #clock-cells = <1>; - }; - }; -+ -+ thermal-zones { -+ cpu0_thermal: cpu0-thermal { -+ polling-delay-passive = <100>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths1 1>; -+ sustainable-power = <1200>; -+ -+ trips { -+ cpu0_threshold: cpu-trip-0 { -+ temperature = <70000>; -+ type = "passive"; -+ hysteresis = <0>; -+ }; -+ cpu0_target: cpu-trip-1 { -+ temperature = <90000>; -+ type = "passive"; -+ hysteresis = <0>; -+ }; -+ cpu0_critical: cpu-trip-2 { -+ temperature = <110000>; -+ type = "critical"; -+ hysteresis = <0>; -+ }; -+ }; -+ }; -+ -+ cpu4_thermal: cpu4-thermal { -+ polling-delay-passive = <100>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths1 0>; -+ sustainable-power = <1600>; -+ -+ trips { -+ cpu4_threshold: cpu-trip-0 { -+ temperature = <70000>; -+ type = "passive"; -+ hysteresis = <0>; -+ }; -+ cpu4_target: cpu-trip-1 { -+ temperature = <90000>; -+ type = "passive"; -+ hysteresis = <0>; -+ }; -+ cpu4_critical: cpu-trip-2 { -+ temperature = <110000>; -+ type = "critical"; -+ hysteresis = <0>; -+ }; -+ }; -+ }; -+ -+ gpu-thermal { -+ polling-delay-passive = <100>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths1 2>; -+ sustainable-power = <2400>; -+ -+ trips { -+ gpu_temp_critical: gpu-trip-0 { -+ temperature = <110000>; -+ type = "critical"; -+ hysteresis = <0>; -+ }; -+ }; -+ }; -+ -+ ddr-thermal { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&ths0 0>; -+ -+ trips { -+ ddr_temp_critical: ddr-trip-0 { -+ temperature = <110000>; -+ type = "critical"; -+ hysteresis = <0>; -+ }; -+ }; -+ }; -+ }; - }; -diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c -index 226747906..bd4f7d781 100644 ---- a/drivers/thermal/sun8i_thermal.c -+++ b/drivers/thermal/sun8i_thermal.c -@@ -66,8 +66,9 @@ struct tsensor { - }; - - struct ths_thermal_chip { -- bool has_mod_clk; -- bool has_bus_clk_reset; -+ bool has_gpadc_clk; -+ bool has_mod_clk; -+ bool has_bus_clk_reset; - bool needs_sram; - int sensor_num; - int offset; -@@ -89,7 +90,8 @@ struct ths_device { - struct regmap_field *sram_regmap_field; - struct reset_control *reset; - struct clk *bus_clk; -- struct clk *mod_clk; -+ struct clk *mod_clk; -+ struct clk *gpadc_clk; - struct tsensor sensor[MAX_SENSOR_NUM]; - }; - -@@ -114,6 +116,15 @@ static int sun50i_h5_calc_temp(struct ths_device *tmdev, - return -1590 * reg / 10 + 276000; - } - -+static int sun55i_a523_calc_temp(struct ths_device *tmdev, -+ int id, int reg) -+{ -+ if (reg >= 0x7c8) -+ return 74 * (2736 - reg); -+ else -+ return 65 * (2825 - reg); -+} -+ - static int sun8i_ths_get_temp(struct thermal_zone_device *tz, int *temp) - { - struct tsensor *s = thermal_zone_device_priv(tz); -@@ -417,6 +428,16 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev) - if (ret) - return ret; - -+ if (tmdev->chip->has_gpadc_clk) { -+ tmdev->gpadc_clk = devm_clk_get_enabled(&pdev->dev, "gpadc"); -+ if (IS_ERR(tmdev->gpadc_clk)) -+ return PTR_ERR(tmdev->gpadc_clk); -+ } -+ -+ ret = clk_prepare_enable(tmdev->gpadc_clk); -+ if (ret) -+ return ret; -+ - if (tmdev->chip->needs_sram) { - struct regmap *regmap; - -@@ -709,6 +730,28 @@ static const struct ths_thermal_chip sun50i_h616_ths = { - .calc_temp = sun8i_ths_calc_temp, - }; - -+static const struct ths_thermal_chip sun55i_a523_ths0 = { -+ .sensor_num = 1, -+ .has_bus_clk_reset = false, /* TODO: same reset with sun55i_a523_ths1, gives an error */ -+ .has_gpadc_clk = true, -+ .temp_data_base = SUN50I_H6_THS_TEMP_DATA, -+ .calibrate = sun50i_h6_ths_calibrate, /* TODO: calibration function has not yet been added */ -+ .init = sun50i_h6_thermal_init, -+ .irq_ack = sun50i_h6_irq_ack, -+ .calc_temp = sun55i_a523_calc_temp, -+}; -+ -+static const struct ths_thermal_chip sun55i_a523_ths1 = { -+ .sensor_num = 3, -+ .has_bus_clk_reset = true, -+ .has_gpadc_clk = true, -+ .temp_data_base = SUN50I_H6_THS_TEMP_DATA, -+ .calibrate = sun50i_h6_ths_calibrate, /* TODO: calibration function has not yet been added */ -+ .init = sun50i_h6_thermal_init, -+ .irq_ack = sun50i_h6_irq_ack, -+ .calc_temp = sun55i_a523_calc_temp, -+}; -+ - static const struct of_device_id of_ths_match[] = { - { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths }, - { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths }, -@@ -719,6 +762,8 @@ static const struct of_device_id of_ths_match[] = { - { .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths }, - { .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths }, - { .compatible = "allwinner,sun50i-h616-ths", .data = &sun50i_h616_ths }, -+ { .compatible = "allwinner,sun55i-a523-ths0", .data = &sun55i_a523_ths0 }, -+ { .compatible = "allwinner,sun55i-a523-ths1", .data = &sun55i_a523_ths1 }, - { /* sentinel */ }, - }; - MODULE_DEVICE_TABLE(of, of_ths_match); --- -2.49.0 - diff --git a/patch/kernel/archive/sunxi-dev-6.14/update-cubie-a5e-dts.patch b/patch/kernel/archive/sunxi-dev-6.14/update-cubie-a5e-dts.patch deleted file mode 100644 index ba4604bfc..000000000 --- a/patch/kernel/archive/sunxi-dev-6.14/update-cubie-a5e-dts.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: John Doe -Date: Sat, 15 Mar 2025 17:18:05 -0300 -Subject: Patch sun55i-a527-radxa-a5e.dts Add gmac0/1 wifi - -Signed-off-by: John Doe ---- - arch/arm64/boot/dts/allwinner/sun55i-a527-radxa-a5e.dts | 99 ++++++++++ - 1 file changed, 99 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a527-radxa-a5e.dts b/arch/arm64/boot/dts/allwinner/sun55i-a527-radxa-a5e.dts -index 912e1bda974c..8cf16035796e 100644 ---- a/arch/arm64/boot/dts/allwinner/sun55i-a527-radxa-a5e.dts -+++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-radxa-a5e.dts -@@ -11,16 +11,38 @@ / { - model = "Radxa A5E"; - compatible = "radxa,cubie-a5e", "allwinner,sun55i-a527"; - - aliases { - serial0 = &uart0; -+ mmc0 = &mmc0; -+ mmc1 = &mmc1; -+ mmc2 = &mmc2; -+ ethernet0 = &gmac0; -+ ethernet1 = &gmac1; -+ ethernet2 = &wlan; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - -+ leds { -+ compatible = "gpio-leds"; -+ -+ led-0 { -+ label = "radxa:green:power"; -+ gpios = <&r_pio 0 4 GPIO_ACTIVE_LOW>; /* PL4 */ -+ linux,default-trigger = "heartbeat"; -+ }; -+ -+ led-1 { -+ label = "radxa:blue:user"; -+ gpios = <&r_pio 0 5 GPIO_ACTIVE_LOW>; /* PL5 */ -+ linux,default-trigger = "default-on"; -+ }; -+ }; -+ - ext_osc32k: ext-osc32k-clk { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32768>; - clock-output-names = "ext_osc32k"; -@@ -42,10 +64,20 @@ reg_usb_vbus: vbus { - regulator-max-microvolt = <5000000>; - vin-supply = <®_vcc5v>; - gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ - enable-active-high; - }; -+ -+ reg_3v3_wifi: 3v3-wifi { -+ compatible = "regulator-fixed"; -+ regulator-name = "3v3-wifi"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <®_vcc5v>; -+ gpio = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */ -+ enable-active-high; -+ }; - }; - - &ehci0 { - status = "okay"; - }; -@@ -59,10 +91,27 @@ &mmc0 { - cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_DOWN)>; /* PF6 */ - bus-width = <4>; - status = "okay"; - }; - -+&mmc1_pins { -+ drive-strength = <40>; -+}; -+ -+&mmc1 { -+ vmmc-supply = <®_3v3_wifi>; -+ bus-width = <4>; -+ non-removable; -+ // todo: investigate why clock above 40MHz makes data errors -+ max-frequency = <35000000>; -+ status = "okay"; -+ -+ wlan: wifi@1 { -+ reg = <1>; -+ }; -+}; -+ - &ohci0 { - status = "okay"; - }; - - &ohci1 { -@@ -295,5 +344,55 @@ &usb_otg { - &usbphy { - usb0_vbus-supply = <®_vcc5v>; - usb1_vbus-supply = <®_usb_vbus>; - status = "okay"; - }; -+ -+&gmac0 { -+ phy-mode = "rgmii"; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&gmac0_pins_default>; -+ pinctrl-1 = <&gmac0_pins_sleep>; -+ sunxi,phy-clk-type = <0>; -+ tx-delay = <2>; -+ rx-delay = <4>; -+ gmac3v3-supply = <®_cldo3>; -+ status = "okay"; -+}; -+ -+&mdio0 { -+ compatible = "allwinner,sunxi-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x04500048 0x8>; -+ status = "okay"; -+ -+ gmac0_phy0: ethernet-phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0x1>; -+ reset-gpios = <&pio 7 8 GPIO_ACTIVE_LOW>; /* PH8 */ -+ reset-assert-us = <10000>; -+ reset-deassert-us = <150000>; -+ }; -+}; -+ -+&gmac1 { -+ phy-mode = "rgmii"; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&gmac1_pins_default>; -+ pinctrl-1 = <&gmac1_pins_sleep>; -+ aw,soc-phy25m; -+ tx-delay = <3>; -+ rx-delay = <4>; -+ dwmac3v3-supply = <®_cldo3>; -+ status = "okay"; -+ -+ mdio1: mdio1@1 { -+ gmac1_phy0: ethernet-phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0x1>; -+ reset-gpios = <&pio 9 16 GPIO_ACTIVE_LOW>; /* PJ16 */ -+ reset-assert-us = <10000>; -+ reset-deassert-us = <150000>; -+ }; -+ }; -+}; --- -Created with Armbian build tools https://github.com/armbian/build -